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 code = ubik_VL_GetEntryByIDN(cstruct, 0, volid, voltype, entryp);
140 if (newvlserver == vltype_unknown) {
141 if (code == RXGEN_OPCODE) {
142 newvlserver = vltype_old; /* Doesn't support new interface */
145 newvlserver = vltype_new;
152 VLDB_GetEntryByName(char *namep, struct nvldbentry *entryp)
154 struct vldbentry oentry;
157 if (newvlserver == vltype_old) {
159 code = ubik_VL_GetEntryByNameO(cstruct, 0, namep, &oentry);
161 ovlentry_to_nvlentry(&oentry, entryp);
164 code = ubik_VL_GetEntryByNameN(cstruct, 0, namep, entryp);
165 if (newvlserver == vltype_unknown) {
166 if (code == RXGEN_OPCODE) {
167 newvlserver = vltype_old; /* Doesn't support new interface */
170 newvlserver = vltype_new;
177 VLDB_ReplaceEntry(afs_uint32 volid, afs_int32 voltype, struct nvldbentry *entryp, afs_int32 releasetype)
179 struct vldbentry oentry;
182 if (newvlserver == vltype_old) {
184 code = nvlentry_to_ovlentry(entryp, &oentry);
188 ubik_VL_ReplaceEntry(cstruct, 0, volid, voltype, &oentry,
193 ubik_VL_ReplaceEntryN(cstruct, 0, volid, voltype, entryp,
195 if (newvlserver == vltype_unknown) {
196 if (code == RXGEN_OPCODE) {
197 newvlserver = vltype_old; /* Doesn't support new interface */
200 newvlserver = vltype_new;
207 convertBulkToNBulk(bulkentries *bulk, nbulkentries *nbulk) {
210 if (bulk->bulkentries_len == 0)
213 nbulk->nbulkentries_len = bulk->bulkentries_len;
214 nbulk->nbulkentries_val =
215 xdr_alloc(bulk->bulkentries_len * sizeof(struct nvldbentry));
217 for (i = 0; i < bulk->bulkentries_len; i++) {
218 ovlentry_to_nvlentry(&bulk->bulkentries_val[i],
219 &nbulk->nbulkentries_val[i]);
224 VLDB_ListAttributes(VldbListByAttributes *attrp,
226 nbulkentries *blkentriesp)
228 bulkentries arrayEntries;
231 if (newvlserver == vltype_old) {
233 memset(&arrayEntries, 0, sizeof(arrayEntries));
235 ubik_VL_ListAttributes(cstruct, 0, attrp, entriesp,
241 /* Ensure the number of entries claimed matches the no. returned */
244 if (*entriesp > arrayEntries.bulkentries_len)
245 *entriesp = arrayEntries.bulkentries_len;
247 convertBulkToNBulk(&arrayEntries, blkentriesp);
249 xdr_free((xdrproc_t) xdr_bulkentries, &arrayEntries);
253 ubik_VL_ListAttributesN(cstruct, 0, attrp, entriesp, blkentriesp);
254 if (newvlserver == vltype_unknown) {
255 if (code == RXGEN_OPCODE) {
256 newvlserver = vltype_old; /* Doesn't support new interface */
259 newvlserver = vltype_new;
263 /* Ensure the number of entries claimed matches the no. returned */
266 if (*entriesp > blkentriesp->nbulkentries_len)
267 *entriesp = blkentriesp->nbulkentries_len;
273 VLDB_ListAttributesN2(VldbListByAttributes *attrp,
276 afs_int32 *nentriesp,
277 nbulkentries *blkentriesp,
278 afs_int32 *nextindexp)
280 afs_int32 code = RXGEN_OPCODE;
282 if (newvlserver != vltype_old) {
284 ubik_VL_ListAttributesN2(cstruct, 0, attrp, (name ? name : ""),
285 thisindex, nentriesp, blkentriesp, nextindexp);
289 /* Ensure the number of entries claimed matches the no. returned */
292 if (*nentriesp > blkentriesp->nbulkentries_len)
293 *nentriesp = blkentriesp->nbulkentries_len;
301 afs_uint32 addrs[16];
304 * Increase cache size. This avoids high CPU usage by the vlserver
305 * in environments where there are more than 16 fileservers in the
308 #define GETADDRUCACHESIZE 64
309 struct cacheips cacheips[GETADDRUCACHESIZE];
310 int cacheip_index = 0;
313 VLDB_IsSameAddrs(afs_uint32 serv1, afs_uint32 serv2, afs_int32 *errorp)
316 ListAddrByAttributes attrs;
318 afs_uint32 *addrp, j, f1, f2;
319 afs_int32 unique, nentries, i;
321 static int initcache = 0;
327 if (newvlserver == vltype_old || newvlserver == vltype_new) {
331 for (i = 0; i < GETADDRUCACHESIZE; i++) {
332 cacheips[i].server = cacheips[i].count = 0;
337 /* See if it's cached */
338 for (i = 0; i < GETADDRUCACHESIZE; i++) {
340 for (j = 0; j < cacheips[i].count; j++) {
341 if (serv1 == cacheips[i].addrs[j])
343 else if (serv2 == cacheips[i].addrs[j])
351 if (cacheips[i].server == serv1)
355 memset(&attrs, 0, sizeof(attrs));
356 attrs.Mask = VLADDR_IPADDR;
357 attrs.ipaddr = serv1;
358 memset(&addrs, 0, sizeof(addrs));
359 memset(&uuid, 0, sizeof(uuid));
361 ubik_VL_GetAddrsU(cstruct, 0, &attrs, &uuid, &unique, &nentries,
363 if (newvlserver == vltype_unknown) {
364 if (code == RXGEN_OPCODE) {
367 newvlserver = vltype_uuid;
370 if (code == VL_NOENT)
378 if (nentries > GETADDRUCACHESIZE)
379 nentries = GETADDRUCACHESIZE; /* safety check; should not happen */
380 if (++cacheip_index >= GETADDRUCACHESIZE)
382 cacheips[cacheip_index].server = serv1;
383 cacheips[cacheip_index].count = nentries;
384 addrp = addrs.bulkaddrs_val;
385 for (i = 0; i < nentries; i++, addrp++) {
386 cacheips[cacheip_index].addrs[i] = *addrp;
387 if (serv2 == *addrp) {
395 Get the appropriate type of ubik client structure out from the system.
398 vsu_ClientInit(const char *confDir, char *cellName, int secFlags,
399 int (*secproc)(struct rx_securityClass *, afs_int32),
400 struct ubik_client **uclientp)
402 return ugen_ClientInitFlags(confDir, cellName, secFlags, uclientp,
403 secproc, VLDB_MAXSERVERS, AFSCONF_VLDBSERVICE,
407 /*extract the name of volume <name> without readonly or backup suffixes
408 * and return the result as <rname>.
411 vsu_ExtractName(char rname[], char name[])
413 char sname[VOLSER_OLDMAXVOLNAME + 1];
416 strncpy(sname, name, sizeof(sname));
417 sname[sizeof(sname) - 1] = '\0';
418 total = strlen(sname);
419 if (!strcmp(&sname[total - 9], ".readonly")) {
420 /*discard the last 8 chars */
421 sname[total - 9] = '\0';
422 strcpy(rname, sname);
424 } else if (!strcmp(&sname[total - 7], ".backup")) {
425 /*discard last 6 chars */
426 sname[total - 7] = '\0';
427 strcpy(rname, sname);
430 strncpy(rname, name, VOLSER_OLDMAXVOLNAME);
431 rname[VOLSER_OLDMAXVOLNAME] = '\0';
436 /* returns 0 if failed */
438 vsu_GetVolumeID(char *astring, struct ubik_client *acstruct, afs_int32 *errp)
440 char volname[VOLSER_OLDMAXVOLNAME + 1];
441 struct nvldbentry entry;
447 if (isdigit(astring[0])) {
450 result = strtoul(astring, &end, 10);
451 if (result != UINT_MAX && *end == '\0')
455 /* It was not a volume number but something else */
456 total = strlen(astring);
457 vsu_ExtractName(volname, astring);
458 vcode = VLDB_GetEntryByName(volname, &entry);
460 if ((total >= 9) && (!strcmp(&astring[total - 9], ".readonly")))
461 return entry.volumeId[ROVOL];
462 else if ((total >= 7) && (!strcmp(&astring[total - 7], ".backup")))
463 return entry.volumeId[BACKVOL];
465 return (entry.volumeId[RWVOL]);
468 return 0; /* can't find volume */