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>
18 #include <sys/statfs.h>
24 #include <rx/rx_globals.h>
26 #include <afs/vlserver.h>
27 #include <afs/cellconfig.h>
30 #include <afs/afsint.h>
38 #include "vsutils_prototypes.h"
40 struct ubik_client *cstruct;
43 ovlentry_to_nvlentry(struct vldbentry *oentryp,
44 struct nvldbentry *nentryp)
48 memset(nentryp, 0, sizeof(struct nvldbentry));
49 strncpy(nentryp->name, oentryp->name, sizeof(nentryp->name));
50 for (i = 0; i < oentryp->nServers; i++) {
51 nentryp->serverNumber[i] = oentryp->serverNumber[i];
52 nentryp->serverPartition[i] = oentryp->serverPartition[i];
53 nentryp->serverFlags[i] = oentryp->serverFlags[i];
55 nentryp->nServers = oentryp->nServers;
56 for (i = 0; i < MAXTYPES; i++)
57 nentryp->volumeId[i] = oentryp->volumeId[i];
58 nentryp->cloneId = oentryp->cloneId;
59 nentryp->flags = oentryp->flags;
63 nvlentry_to_ovlentry(struct nvldbentry *nentryp,
64 struct vldbentry *oentryp)
68 memset(oentryp, 0, sizeof(struct vldbentry));
69 strncpy(oentryp->name, nentryp->name, sizeof(oentryp->name));
70 if (nentryp->nServers > OMAXNSERVERS) {
72 * The alternative is to store OMAXSERVERS but it's always better
73 * to know what's going on...
77 for (i = 0; i < nentryp->nServers; i++) {
78 oentryp->serverNumber[i] = nentryp->serverNumber[i];
79 oentryp->serverPartition[i] = nentryp->serverPartition[i];
80 oentryp->serverFlags[i] = nentryp->serverFlags[i];
82 oentryp->nServers = i;
83 for (i = 0; i < MAXTYPES; i++)
84 oentryp->volumeId[i] = nentryp->volumeId[i];
85 oentryp->cloneId = nentryp->cloneId;
86 oentryp->flags = nentryp->flags;
97 static enum _vlserver_type newvlserver = vltype_unknown;
100 VLDB_CreateEntry(struct nvldbentry *entryp)
102 struct vldbentry oentry;
105 if (newvlserver == vltype_old) {
107 code = nvlentry_to_ovlentry(entryp, &oentry);
110 code = ubik_VL_CreateEntry(cstruct, 0, &oentry);
113 code = ubik_VL_CreateEntryN(cstruct, 0, entryp);
114 if (newvlserver == vltype_unknown) {
115 if (code == RXGEN_OPCODE) {
116 newvlserver = vltype_old; /* Doesn't support new interface */
119 newvlserver = vltype_new;
126 VLDB_GetEntryByID(afs_uint32 volid, afs_int32 voltype, struct nvldbentry *entryp)
128 struct vldbentry oentry;
131 if (newvlserver == vltype_old) {
134 ubik_VL_GetEntryByID(cstruct, 0, volid, voltype, &oentry);
136 ovlentry_to_nvlentry(&oentry, entryp);
139 memset(entryp, 0, sizeof(*entryp)); /* ensure padding is cleared */
140 code = ubik_VL_GetEntryByIDN(cstruct, 0, volid, voltype, entryp);
141 if (newvlserver == vltype_unknown) {
142 if (code == RXGEN_OPCODE) {
143 newvlserver = vltype_old; /* Doesn't support new interface */
146 newvlserver = vltype_new;
153 VLDB_GetEntryByName(char *namep, struct nvldbentry *entryp)
155 struct vldbentry oentry;
158 if (newvlserver == vltype_old) {
160 code = ubik_VL_GetEntryByNameO(cstruct, 0, namep, &oentry);
162 ovlentry_to_nvlentry(&oentry, entryp);
165 memset(entryp, 0, sizeof(*entryp)); /* ensure padding is cleared */
166 code = ubik_VL_GetEntryByNameN(cstruct, 0, namep, entryp);
167 if (newvlserver == vltype_unknown) {
168 if (code == RXGEN_OPCODE) {
169 newvlserver = vltype_old; /* Doesn't support new interface */
172 newvlserver = vltype_new;
179 VLDB_ReplaceEntry(afs_uint32 volid, afs_int32 voltype, struct nvldbentry *entryp, afs_int32 releasetype)
181 struct vldbentry oentry;
184 if (newvlserver == vltype_old) {
186 code = nvlentry_to_ovlentry(entryp, &oentry);
190 ubik_VL_ReplaceEntry(cstruct, 0, volid, voltype, &oentry,
195 ubik_VL_ReplaceEntryN(cstruct, 0, volid, voltype, entryp,
197 if (newvlserver == vltype_unknown) {
198 if (code == RXGEN_OPCODE) {
199 newvlserver = vltype_old; /* Doesn't support new interface */
202 newvlserver = vltype_new;
209 convertBulkToNBulk(bulkentries *bulk, nbulkentries *nbulk) {
212 if (bulk->bulkentries_len == 0)
215 nbulk->nbulkentries_len = bulk->bulkentries_len;
216 nbulk->nbulkentries_val =
217 xdr_alloc(bulk->bulkentries_len * sizeof(struct nvldbentry));
219 for (i = 0; i < bulk->bulkentries_len; i++) {
220 ovlentry_to_nvlentry(&bulk->bulkentries_val[i],
221 &nbulk->nbulkentries_val[i]);
226 VLDB_ListAttributes(VldbListByAttributes *attrp,
228 nbulkentries *blkentriesp)
230 bulkentries arrayEntries;
233 if (newvlserver == vltype_old) {
235 memset(&arrayEntries, 0, sizeof(arrayEntries));
237 ubik_VL_ListAttributes(cstruct, 0, attrp, entriesp,
243 /* Ensure the number of entries claimed matches the no. returned */
246 if (*entriesp > arrayEntries.bulkentries_len)
247 *entriesp = arrayEntries.bulkentries_len;
249 convertBulkToNBulk(&arrayEntries, blkentriesp);
251 xdr_free((xdrproc_t) xdr_bulkentries, &arrayEntries);
255 ubik_VL_ListAttributesN(cstruct, 0, attrp, entriesp, blkentriesp);
256 if (newvlserver == vltype_unknown) {
257 if (code == RXGEN_OPCODE) {
258 newvlserver = vltype_old; /* Doesn't support new interface */
261 newvlserver = vltype_new;
265 /* Ensure the number of entries claimed matches the no. returned */
268 if (*entriesp > blkentriesp->nbulkentries_len)
269 *entriesp = blkentriesp->nbulkentries_len;
275 VLDB_ListAttributesN2(VldbListByAttributes *attrp,
278 afs_int32 *nentriesp,
279 nbulkentries *blkentriesp,
280 afs_int32 *nextindexp)
282 afs_int32 code = RXGEN_OPCODE;
284 if (newvlserver != vltype_old) {
286 ubik_VL_ListAttributesN2(cstruct, 0, attrp, (name ? name : ""),
287 thisindex, nentriesp, blkentriesp, nextindexp);
291 /* Ensure the number of entries claimed matches the no. returned */
294 if (*nentriesp > blkentriesp->nbulkentries_len)
295 *nentriesp = blkentriesp->nbulkentries_len;
303 afs_uint32 addrs[16];
306 * Increase cache size. This avoids high CPU usage by the vlserver
307 * in environments where there are more than 16 fileservers in the
310 #define GETADDRUCACHESIZE 64
311 struct cacheips cacheips[GETADDRUCACHESIZE];
312 int cacheip_index = 0;
315 VLDB_IsSameAddrs(afs_uint32 serv1, afs_uint32 serv2, afs_int32 *errorp)
318 ListAddrByAttributes attrs;
320 afs_uint32 *addrp, j, f1, f2;
321 afs_int32 unique, nentries, i;
323 static int initcache = 0;
329 if (newvlserver == vltype_old || newvlserver == vltype_new) {
333 for (i = 0; i < GETADDRUCACHESIZE; i++) {
334 cacheips[i].server = cacheips[i].count = 0;
339 /* See if it's cached */
340 for (i = 0; i < GETADDRUCACHESIZE; i++) {
342 for (j = 0; j < cacheips[i].count; j++) {
343 if (serv1 == cacheips[i].addrs[j])
345 else if (serv2 == cacheips[i].addrs[j])
353 if (cacheips[i].server == serv1)
357 memset(&attrs, 0, sizeof(attrs));
358 attrs.Mask = VLADDR_IPADDR;
359 attrs.ipaddr = serv1;
360 memset(&addrs, 0, sizeof(addrs));
361 memset(&uuid, 0, sizeof(uuid));
363 ubik_VL_GetAddrsU(cstruct, 0, &attrs, &uuid, &unique, &nentries,
365 if (newvlserver == vltype_unknown) {
366 if (code == RXGEN_OPCODE) {
369 newvlserver = vltype_uuid;
372 if (code == VL_NOENT)
380 if (nentries > GETADDRUCACHESIZE)
381 nentries = GETADDRUCACHESIZE; /* safety check; should not happen */
382 if (++cacheip_index >= GETADDRUCACHESIZE)
384 cacheips[cacheip_index].server = serv1;
385 cacheips[cacheip_index].count = nentries;
386 addrp = addrs.bulkaddrs_val;
387 for (i = 0; i < nentries; i++, addrp++) {
388 cacheips[cacheip_index].addrs[i] = *addrp;
389 if (serv2 == *addrp) {
397 Get the appropriate type of ubik client structure out from the system.
400 vsu_ClientInit(const char *confDir, char *cellName, int secFlags,
401 ugen_secproc_func secproc,
402 struct ubik_client **uclientp)
404 return ugen_ClientInitFlags(confDir, cellName, secFlags, uclientp,
405 secproc, VLDB_MAXSERVERS, AFSCONF_VLDBSERVICE,
409 /*extract the name of volume <name> without readonly or backup suffixes
410 * and return the result as <rname>.
413 vsu_ExtractName(char rname[], char name[])
415 char sname[VOLSER_OLDMAXVOLNAME + 1];
418 strncpy(sname, name, sizeof(sname));
419 sname[sizeof(sname) - 1] = '\0';
420 total = strlen(sname);
421 if (total >= 9 && !strcmp(&sname[total - 9], ".readonly")) {
422 /*discard the last 8 chars */
423 sname[total - 9] = '\0';
424 strcpy(rname, sname);
426 } else if (total >= 7 && !strcmp(&sname[total - 7], ".backup")) {
427 /*discard last 6 chars */
428 sname[total - 7] = '\0';
429 strcpy(rname, sname);
432 strncpy(rname, name, VOLSER_OLDMAXVOLNAME);
433 rname[VOLSER_OLDMAXVOLNAME] = '\0';
438 /* returns 0 if failed */
440 vsu_GetVolumeID(char *astring, struct ubik_client *acstruct, afs_int32 *errp)
442 char volname[VOLSER_OLDMAXVOLNAME + 1];
443 struct nvldbentry entry;
449 if (isdigit(astring[0])) {
452 result = strtoul(astring, &end, 10);
453 if (result != UINT_MAX && *end == '\0')
457 /* It was not a volume number but something else */
458 total = strlen(astring);
459 vsu_ExtractName(volname, astring);
460 vcode = VLDB_GetEntryByName(volname, &entry);
462 if ((total >= 9) && (!strcmp(&astring[total - 9], ".readonly")))
463 return entry.volumeId[ROVOL];
464 else if ((total >= 7) && (!strcmp(&astring[total - 7], ".backup")))
465 return entry.volumeId[BACKVOL];
467 return (entry.volumeId[RWVOL]);
470 return 0; /* can't find volume */