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;
41 static rxkad_level vsu_rxkad_level = rxkad_clear;
44 ovlentry_to_nvlentry(struct vldbentry *oentryp,
45 struct nvldbentry *nentryp)
49 memset(nentryp, 0, sizeof(struct nvldbentry));
50 strncpy(nentryp->name, oentryp->name, sizeof(nentryp->name));
51 for (i = 0; i < oentryp->nServers; i++) {
52 nentryp->serverNumber[i] = oentryp->serverNumber[i];
53 nentryp->serverPartition[i] = oentryp->serverPartition[i];
54 nentryp->serverFlags[i] = oentryp->serverFlags[i];
56 nentryp->nServers = oentryp->nServers;
57 for (i = 0; i < MAXTYPES; i++)
58 nentryp->volumeId[i] = oentryp->volumeId[i];
59 nentryp->cloneId = oentryp->cloneId;
60 nentryp->flags = oentryp->flags;
64 nvlentry_to_ovlentry(struct nvldbentry *nentryp,
65 struct vldbentry *oentryp)
69 memset(oentryp, 0, sizeof(struct vldbentry));
70 strncpy(oentryp->name, nentryp->name, sizeof(oentryp->name));
71 if (nentryp->nServers > OMAXNSERVERS) {
73 * The alternative is to store OMAXSERVERS but it's always better
74 * to know what's going on...
78 for (i = 0; i < nentryp->nServers; i++) {
79 oentryp->serverNumber[i] = nentryp->serverNumber[i];
80 oentryp->serverPartition[i] = nentryp->serverPartition[i];
81 oentryp->serverFlags[i] = nentryp->serverFlags[i];
83 oentryp->nServers = i;
84 for (i = 0; i < MAXTYPES; i++)
85 oentryp->volumeId[i] = nentryp->volumeId[i];
86 oentryp->cloneId = nentryp->cloneId;
87 oentryp->flags = nentryp->flags;
98 static enum _vlserver_type newvlserver = vltype_unknown;
101 VLDB_CreateEntry(struct nvldbentry *entryp)
103 struct vldbentry oentry;
106 if (newvlserver == vltype_old) {
108 code = nvlentry_to_ovlentry(entryp, &oentry);
111 code = ubik_VL_CreateEntry(cstruct, 0, &oentry);
114 code = ubik_VL_CreateEntryN(cstruct, 0, entryp);
115 if (newvlserver == vltype_unknown) {
116 if (code == RXGEN_OPCODE) {
117 newvlserver = vltype_old; /* Doesn't support new interface */
120 newvlserver = vltype_new;
127 VLDB_GetEntryByID(afs_uint32 volid, afs_int32 voltype, struct nvldbentry *entryp)
129 struct vldbentry oentry;
132 if (newvlserver == vltype_old) {
135 ubik_VL_GetEntryByID(cstruct, 0, volid, voltype, &oentry);
137 ovlentry_to_nvlentry(&oentry, entryp);
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 code = ubik_VL_GetEntryByNameN(cstruct, 0, namep, entryp);
166 if (newvlserver == vltype_unknown) {
167 if (code == RXGEN_OPCODE) {
168 newvlserver = vltype_old; /* Doesn't support new interface */
171 newvlserver = vltype_new;
178 VLDB_ReplaceEntry(afs_uint32 volid, afs_int32 voltype, struct nvldbentry *entryp, afs_int32 releasetype)
180 struct vldbentry oentry;
183 if (newvlserver == vltype_old) {
185 code = nvlentry_to_ovlentry(entryp, &oentry);
189 ubik_VL_ReplaceEntry(cstruct, 0, volid, voltype, &oentry,
194 ubik_VL_ReplaceEntryN(cstruct, 0, volid, voltype, entryp,
196 if (newvlserver == vltype_unknown) {
197 if (code == RXGEN_OPCODE) {
198 newvlserver = vltype_old; /* Doesn't support new interface */
201 newvlserver = vltype_new;
208 convertBulkToNBulk(bulkentries *bulk, nbulkentries *nbulk) {
211 if (bulk->bulkentries_len == 0)
214 nbulk->nbulkentries_len = bulk->bulkentries_len;
215 nbulk->nbulkentries_val =
216 xdr_alloc(bulk->bulkentries_len * sizeof(struct nvldbentry));
218 for (i = 0; i < bulk->bulkentries_len; i++) {
219 ovlentry_to_nvlentry(&bulk->bulkentries_val[i],
220 &nbulk->nbulkentries_val[i]);
225 VLDB_ListAttributes(VldbListByAttributes *attrp,
227 nbulkentries *blkentriesp)
229 bulkentries arrayEntries;
232 if (newvlserver == vltype_old) {
234 memset(&arrayEntries, 0, sizeof(arrayEntries));
236 ubik_VL_ListAttributes(cstruct, 0, attrp, entriesp,
242 /* Ensure the number of entries claimed matches the no. returned */
245 if (*entriesp > arrayEntries.bulkentries_len)
246 *entriesp = arrayEntries.bulkentries_len;
248 convertBulkToNBulk(&arrayEntries, blkentriesp);
250 xdr_free((xdrproc_t) xdr_bulkentries, &arrayEntries);
254 ubik_VL_ListAttributesN(cstruct, 0, attrp, entriesp, blkentriesp);
255 if (newvlserver == vltype_unknown) {
256 if (code == RXGEN_OPCODE) {
257 newvlserver = vltype_old; /* Doesn't support new interface */
260 newvlserver = vltype_new;
264 /* Ensure the number of entries claimed matches the no. returned */
267 if (*entriesp > blkentriesp->nbulkentries_len)
268 *entriesp = blkentriesp->nbulkentries_len;
274 VLDB_ListAttributesN2(VldbListByAttributes *attrp,
277 afs_int32 *nentriesp,
278 nbulkentries *blkentriesp,
279 afs_int32 *nextindexp)
281 afs_int32 code = RXGEN_OPCODE;
283 if (newvlserver != vltype_old) {
285 ubik_VL_ListAttributesN2(cstruct, 0, attrp, (name ? name : ""),
286 thisindex, nentriesp, blkentriesp, nextindexp);
290 /* Ensure the number of entries claimed matches the no. returned */
293 if (*nentriesp > blkentriesp->nbulkentries_len)
294 *nentriesp = blkentriesp->nbulkentries_len;
302 afs_uint32 addrs[16];
305 * Increase cache size. This avoids high CPU usage by the vlserver
306 * in environments where there are more than 16 fileservers in the
309 #define GETADDRUCACHESIZE 64
310 struct cacheips cacheips[GETADDRUCACHESIZE];
311 int cacheip_index = 0;
314 VLDB_IsSameAddrs(afs_uint32 serv1, afs_uint32 serv2, afs_int32 *errorp)
317 ListAddrByAttributes attrs;
319 afs_uint32 *addrp, j, f1, f2;
320 afs_int32 unique, nentries, i;
322 static int initcache = 0;
328 if (newvlserver == vltype_old || newvlserver == vltype_new) {
332 for (i = 0; i < GETADDRUCACHESIZE; i++) {
333 cacheips[i].server = cacheips[i].count = 0;
338 /* See if it's cached */
339 for (i = 0; i < GETADDRUCACHESIZE; i++) {
341 for (j = 0; j < cacheips[i].count; j++) {
342 if (serv1 == cacheips[i].addrs[j])
344 else if (serv2 == cacheips[i].addrs[j])
352 if (cacheips[i].server == serv1)
356 memset(&attrs, 0, sizeof(attrs));
357 attrs.Mask = VLADDR_IPADDR;
358 attrs.ipaddr = serv1;
359 memset(&addrs, 0, sizeof(addrs));
360 memset(&uuid, 0, sizeof(uuid));
362 ubik_VL_GetAddrsU(cstruct, 0, &attrs, &uuid, &unique, &nentries,
364 if (newvlserver == vltype_unknown) {
365 if (code == RXGEN_OPCODE) {
368 newvlserver = vltype_uuid;
371 if (code == VL_NOENT)
379 if (nentries > GETADDRUCACHESIZE)
380 nentries = GETADDRUCACHESIZE; /* safety check; should not happen */
381 if (++cacheip_index >= GETADDRUCACHESIZE)
383 cacheips[cacheip_index].server = serv1;
384 cacheips[cacheip_index].count = nentries;
385 addrp = addrs.bulkaddrs_val;
386 for (i = 0; i < nentries; i++, addrp++) {
387 cacheips[cacheip_index].addrs[i] = *addrp;
388 if (serv2 == *addrp) {
397 Set encryption. If 'cryptflag' is nonzero, encrpytion is turned on
398 for authenticated connections; if zero, encryption is turned off.
399 Calling this function always results in a level of at least rxkad_auth;
400 to get a rxkad_clear connection, simply don't call this.
403 vsu_SetCrypt(int cryptflag)
406 vsu_rxkad_level = rxkad_crypt;
408 vsu_rxkad_level = rxkad_auth;
414 Get the appropriate type of ubik client structure out from the system.
417 vsu_ClientInit(int noAuthFlag, const char *confDir, char *cellName, afs_int32 sauth,
418 struct ubik_client **uclientp,
419 int (*secproc)(struct rx_securityClass *, afs_int32))
421 return ugen_ClientInit(noAuthFlag, confDir, cellName, sauth, uclientp,
422 secproc, "vsu_ClientInit", vsu_rxkad_level,
423 VLDB_MAXSERVERS, AFSCONF_VLDBSERVICE, 90,
424 0, 0, USER_SERVICE_ID);
428 /*extract the name of volume <name> without readonly or backup suffixes
429 * and return the result as <rname>.
432 vsu_ExtractName(char rname[], char name[])
434 char sname[VOLSER_OLDMAXVOLNAME + 1];
437 strncpy(sname, name, sizeof(sname));
438 sname[sizeof(sname) - 1] = '\0';
439 total = strlen(sname);
440 if (!strcmp(&sname[total - 9], ".readonly")) {
441 /*discard the last 8 chars */
442 sname[total - 9] = '\0';
443 strcpy(rname, sname);
445 } else if (!strcmp(&sname[total - 7], ".backup")) {
446 /*discard last 6 chars */
447 sname[total - 7] = '\0';
448 strcpy(rname, sname);
451 strncpy(rname, name, VOLSER_OLDMAXVOLNAME);
452 rname[VOLSER_OLDMAXVOLNAME] = '\0';
457 /* returns 0 if failed */
459 vsu_GetVolumeID(char *astring, struct ubik_client *acstruct, afs_int32 *errp)
461 char volname[VOLSER_OLDMAXVOLNAME + 1];
462 struct nvldbentry entry;
468 if (isdigit(astring[0])) {
471 result = strtoul(astring, &end, 10);
472 if (result != UINT_MAX && *end == '\0')
476 /* It was not a volume number but something else */
477 total = strlen(astring);
478 vsu_ExtractName(volname, astring);
479 vcode = VLDB_GetEntryByName(volname, &entry);
481 if ((total >= 9) && (!strcmp(&astring[total - 9], ".readonly")))
482 return entry.volumeId[ROVOL];
483 else if ((total >= 7) && (!strcmp(&astring[total - 7], ".backup")))
484 return entry.volumeId[BACKVOL];
486 return (entry.volumeId[RWVOL]);
489 return 0; /* can't find volume */