2 * Copyright 2000, International Business Machines Corporation and others.
5 * This software has been released under the terms of the IBM Public
6 * License. For details, see the LICENSE file in the top-level source
7 * directory or online at http://www.openafs.org/dl/license10.html
10 #include <afsconfig.h>
11 #include <afs/param.h>
22 #include <sys/types.h>
25 #include <netinet/in.h>
26 #endif /* AFS_NT40_ENV */
29 #include <sys/statfs.h>
36 #include <rx/rx_globals.h>
38 #include <afs/vlserver.h>
39 #include <afs/cellconfig.h>
42 #include <afs/afsint.h>
49 #include "vsutils_prototypes.h"
51 struct ubik_client *cstruct;
52 static rxkad_level vsu_rxkad_level = rxkad_clear;
55 ovlentry_to_nvlentry(struct vldbentry *oentryp,
56 struct nvldbentry *nentryp)
60 memset(nentryp, 0, sizeof(struct nvldbentry));
61 strncpy(nentryp->name, oentryp->name, sizeof(nentryp->name));
62 for (i = 0; i < oentryp->nServers; i++) {
63 nentryp->serverNumber[i] = oentryp->serverNumber[i];
64 nentryp->serverPartition[i] = oentryp->serverPartition[i];
65 nentryp->serverFlags[i] = oentryp->serverFlags[i];
67 nentryp->nServers = oentryp->nServers;
68 for (i = 0; i < MAXTYPES; i++)
69 nentryp->volumeId[i] = oentryp->volumeId[i];
70 nentryp->cloneId = oentryp->cloneId;
71 nentryp->flags = oentryp->flags;
75 nvlentry_to_ovlentry(struct nvldbentry *nentryp,
76 struct vldbentry *oentryp)
80 memset(oentryp, 0, sizeof(struct vldbentry));
81 strncpy(oentryp->name, nentryp->name, sizeof(oentryp->name));
82 if (nentryp->nServers > OMAXNSERVERS) {
84 * The alternative is to store OMAXSERVERS but it's always better
85 * to know what's going on...
89 for (i = 0; i < nentryp->nServers; i++) {
90 oentryp->serverNumber[i] = nentryp->serverNumber[i];
91 oentryp->serverPartition[i] = nentryp->serverPartition[i];
92 oentryp->serverFlags[i] = nentryp->serverFlags[i];
94 oentryp->nServers = i;
95 for (i = 0; i < MAXTYPES; i++)
96 oentryp->volumeId[i] = nentryp->volumeId[i];
97 oentryp->cloneId = nentryp->cloneId;
98 oentryp->flags = nentryp->flags;
102 enum _vlserver_type {
109 static enum _vlserver_type newvlserver = vltype_unknown;
112 VLDB_CreateEntry(struct nvldbentry *entryp)
114 struct vldbentry oentry;
117 if (newvlserver == vltype_old) {
119 code = nvlentry_to_ovlentry(entryp, &oentry);
122 code = ubik_VL_CreateEntry(cstruct, 0, &oentry);
125 code = ubik_VL_CreateEntryN(cstruct, 0, entryp);
126 if (newvlserver == vltype_unknown) {
127 if (code == RXGEN_OPCODE) {
128 newvlserver = vltype_old; /* Doesn't support new interface */
131 newvlserver = vltype_new;
138 VLDB_GetEntryByID(afs_uint32 volid, afs_int32 voltype, struct nvldbentry *entryp)
140 struct vldbentry oentry;
143 if (newvlserver == vltype_old) {
146 ubik_VL_GetEntryByID(cstruct, 0, volid, voltype, &oentry);
148 ovlentry_to_nvlentry(&oentry, entryp);
151 code = ubik_VL_GetEntryByIDN(cstruct, 0, volid, voltype, entryp);
152 if (newvlserver == vltype_unknown) {
153 if (code == RXGEN_OPCODE) {
154 newvlserver = vltype_old; /* Doesn't support new interface */
157 newvlserver = vltype_new;
164 VLDB_GetEntryByName(char *namep, struct nvldbentry *entryp)
166 struct vldbentry oentry;
169 if (newvlserver == vltype_old) {
171 code = ubik_VL_GetEntryByNameO(cstruct, 0, namep, &oentry);
173 ovlentry_to_nvlentry(&oentry, entryp);
176 code = ubik_VL_GetEntryByNameN(cstruct, 0, namep, entryp);
177 if (newvlserver == vltype_unknown) {
178 if (code == RXGEN_OPCODE) {
179 newvlserver = vltype_old; /* Doesn't support new interface */
182 newvlserver = vltype_new;
189 VLDB_ReplaceEntry(afs_uint32 volid, afs_int32 voltype, struct nvldbentry *entryp, afs_int32 releasetype)
191 struct vldbentry oentry;
194 if (newvlserver == vltype_old) {
196 code = nvlentry_to_ovlentry(entryp, &oentry);
200 ubik_VL_ReplaceEntry(cstruct, 0, volid, voltype, &oentry,
205 ubik_VL_ReplaceEntryN(cstruct, 0, volid, voltype, entryp,
207 if (newvlserver == vltype_unknown) {
208 if (code == RXGEN_OPCODE) {
209 newvlserver = vltype_old; /* Doesn't support new interface */
212 newvlserver = vltype_new;
219 convertBulkToNBulk(bulkentries *bulk, nbulkentries *nbulk) {
222 if (bulk->bulkentries_len == 0)
225 nbulk->nbulkentries_len = bulk->bulkentries_len;
226 nbulk->nbulkentries_val =
227 xdr_alloc(bulk->bulkentries_len * sizeof(struct nvldbentry));
229 for (i = 0; i < bulk->bulkentries_len; i++) {
230 ovlentry_to_nvlentry(&bulk->bulkentries_val[i],
231 &nbulk->nbulkentries_val[i]);
236 VLDB_ListAttributes(VldbListByAttributes *attrp,
238 nbulkentries *blkentriesp)
240 bulkentries arrayEntries;
243 if (newvlserver == vltype_old) {
245 memset(&arrayEntries, 0, sizeof(arrayEntries));
247 ubik_VL_ListAttributes(cstruct, 0, attrp, entriesp,
253 /* Ensure the number of entries claimed matches the no. returned */
256 if (*entriesp > arrayEntries.bulkentries_len)
257 *entriesp = arrayEntries.bulkentries_len;
259 convertBulkToNBulk(&arrayEntries, blkentriesp);
261 xdr_free((xdrproc_t) xdr_bulkentries, &arrayEntries);
265 ubik_VL_ListAttributesN(cstruct, 0, attrp, entriesp, blkentriesp);
266 if (newvlserver == vltype_unknown) {
267 if (code == RXGEN_OPCODE) {
268 newvlserver = vltype_old; /* Doesn't support new interface */
271 newvlserver = vltype_new;
275 /* Ensure the number of entries claimed matches the no. returned */
278 if (*entriesp > blkentriesp->nbulkentries_len)
279 *entriesp = blkentriesp->nbulkentries_len;
285 VLDB_ListAttributesN2(VldbListByAttributes *attrp,
288 afs_int32 *nentriesp,
289 nbulkentries *blkentriesp,
290 afs_int32 *nextindexp)
292 afs_int32 code = RXGEN_OPCODE;
294 if (newvlserver != vltype_old) {
296 ubik_VL_ListAttributesN2(cstruct, 0, attrp, (name ? name : ""),
297 thisindex, nentriesp, blkentriesp, nextindexp);
301 /* Ensure the number of entries claimed matches the no. returned */
304 if (*nentriesp > blkentriesp->nbulkentries_len)
305 *nentriesp = blkentriesp->nbulkentries_len;
313 afs_uint32 addrs[16];
316 * Increase cache size. This avoids high CPU usage by the vlserver
317 * in environments where there are more than 16 fileservers in the
320 #define GETADDRUCACHESIZE 64
321 struct cacheips cacheips[GETADDRUCACHESIZE];
322 int cacheip_index = 0;
325 VLDB_IsSameAddrs(afs_uint32 serv1, afs_uint32 serv2, afs_int32 *errorp)
328 ListAddrByAttributes attrs;
330 afs_uint32 *addrp, i, j, f1, f2;
331 afs_int32 unique, nentries;
333 static int initcache = 0;
339 if (newvlserver == vltype_old || newvlserver == vltype_new) {
343 for (i = 0; i < GETADDRUCACHESIZE; i++) {
344 cacheips[i].server = cacheips[i].count = 0;
349 /* See if it's cached */
350 for (i = 0; i < GETADDRUCACHESIZE; i++) {
352 for (j = 0; j < cacheips[i].count; j++) {
353 if (serv1 == cacheips[i].addrs[j])
355 else if (serv2 == cacheips[i].addrs[j])
363 if (cacheips[i].server == serv1)
367 memset(&attrs, 0, sizeof(attrs));
368 attrs.Mask = VLADDR_IPADDR;
369 attrs.ipaddr = serv1;
370 memset(&addrs, 0, sizeof(addrs));
371 memset(&uuid, 0, sizeof(uuid));
373 ubik_VL_GetAddrsU(cstruct, 0, &attrs, &uuid, &unique, &nentries,
375 if (newvlserver == vltype_unknown) {
376 if (code == RXGEN_OPCODE) {
379 newvlserver = vltype_uuid;
382 if (code == VL_NOENT)
390 if (nentries > GETADDRUCACHESIZE)
391 nentries = GETADDRUCACHESIZE; /* safety check; should not happen */
392 if (++cacheip_index >= GETADDRUCACHESIZE)
394 cacheips[cacheip_index].server = serv1;
395 cacheips[cacheip_index].count = nentries;
396 addrp = addrs.bulkaddrs_val;
397 for (i = 0; i < nentries; i++, addrp++) {
398 cacheips[cacheip_index].addrs[i] = *addrp;
399 if (serv2 == *addrp) {
408 Set encryption. If 'cryptflag' is nonzero, encrpytion is turned on
409 for authenticated connections; if zero, encryption is turned off.
410 Calling this function always results in a level of at least rxkad_auth;
411 to get a rxkad_clear connection, simply don't call this.
414 vsu_SetCrypt(int cryptflag)
417 vsu_rxkad_level = rxkad_crypt;
419 vsu_rxkad_level = rxkad_auth;
425 Get the appropriate type of ubik client structure out from the system.
428 vsu_ClientInit(int noAuthFlag, const char *confDir, char *cellName, afs_int32 sauth,
429 struct ubik_client **uclientp,
430 int (*secproc)(struct rx_securityClass *, afs_int32))
432 return ugen_ClientInit(noAuthFlag, confDir, cellName, sauth, uclientp,
433 secproc, "vsu_ClientInit", vsu_rxkad_level,
434 VLDB_MAXSERVERS, AFSCONF_VLDBSERVICE, 90,
435 0, 0, USER_SERVICE_ID);
439 /*extract the name of volume <name> without readonly or backup suffixes
440 * and return the result as <rname>.
443 vsu_ExtractName(char rname[], char name[])
445 char sname[VOLSER_OLDMAXVOLNAME + 1];
448 strncpy(sname, name, sizeof(sname));
449 sname[sizeof(sname) - 1] = '\0';
450 total = strlen(sname);
451 if (!strcmp(&sname[total - 9], ".readonly")) {
452 /*discard the last 8 chars */
453 sname[total - 9] = '\0';
454 strcpy(rname, sname);
456 } else if (!strcmp(&sname[total - 7], ".backup")) {
457 /*discard last 6 chars */
458 sname[total - 7] = '\0';
459 strcpy(rname, sname);
462 strncpy(rname, name, VOLSER_OLDMAXVOLNAME);
463 rname[VOLSER_OLDMAXVOLNAME] = '\0';
468 /* returns 0 if failed */
470 vsu_GetVolumeID(char *astring, struct ubik_client *acstruct, afs_int32 *errp)
472 char volname[VOLSER_OLDMAXVOLNAME + 1];
473 struct nvldbentry entry;
479 if (isdigit(astring[0])) {
482 result = strtoul(astring, &end, 10);
483 if (result != UINT_MAX && *end == '\0')
487 /* It was not a volume number but something else */
488 total = strlen(astring);
489 vsu_ExtractName(volname, astring);
490 vcode = VLDB_GetEntryByName(volname, &entry);
492 if ((total >= 9) && (!strcmp(&astring[total - 9], ".readonly")))
493 return entry.volumeId[ROVOL];
494 else if ((total >= 7) && (!strcmp(&astring[total - 7], ".backup")))
495 return entry.volumeId[BACKVOL];
497 return (entry.volumeId[RWVOL]);
500 return 0; /* can't find volume */