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>
21 #include <sys/types.h>
24 #include <netinet/in.h>
25 #endif /* AFS_NT40_ENV */
28 #include <sys/statfs.h>
35 #include <rx/rx_globals.h>
37 #include <afs/vlserver.h>
38 #include <afs/cellconfig.h>
41 #include <afs/afsint.h>
48 #include "vsutils_prototypes.h"
50 struct ubik_client *cstruct;
51 static rxkad_level vsu_rxkad_level = rxkad_clear;
54 ovlentry_to_nvlentry(struct vldbentry *oentryp,
55 struct nvldbentry *nentryp)
59 memset(nentryp, 0, sizeof(struct nvldbentry));
60 strncpy(nentryp->name, oentryp->name, sizeof(nentryp->name));
61 for (i = 0; i < oentryp->nServers; i++) {
62 nentryp->serverNumber[i] = oentryp->serverNumber[i];
63 nentryp->serverPartition[i] = oentryp->serverPartition[i];
64 nentryp->serverFlags[i] = oentryp->serverFlags[i];
66 nentryp->nServers = oentryp->nServers;
67 for (i = 0; i < MAXTYPES; i++)
68 nentryp->volumeId[i] = oentryp->volumeId[i];
69 nentryp->cloneId = oentryp->cloneId;
70 nentryp->flags = oentryp->flags;
74 nvlentry_to_ovlentry(struct nvldbentry *nentryp,
75 struct vldbentry *oentryp)
79 memset(oentryp, 0, sizeof(struct vldbentry));
80 strncpy(oentryp->name, nentryp->name, sizeof(oentryp->name));
81 if (nentryp->nServers > OMAXNSERVERS) {
83 * The alternative is to store OMAXSERVERS but it's always better
84 * to know what's going on...
88 for (i = 0; i < nentryp->nServers; i++) {
89 oentryp->serverNumber[i] = nentryp->serverNumber[i];
90 oentryp->serverPartition[i] = nentryp->serverPartition[i];
91 oentryp->serverFlags[i] = nentryp->serverFlags[i];
93 oentryp->nServers = i;
94 for (i = 0; i < MAXTYPES; i++)
95 oentryp->volumeId[i] = nentryp->volumeId[i];
96 oentryp->cloneId = nentryp->cloneId;
97 oentryp->flags = nentryp->flags;
101 static int newvlserver = 0;
104 VLDB_CreateEntry(struct nvldbentry *entryp)
106 struct vldbentry oentry;
109 if (newvlserver == 1) {
111 code = nvlentry_to_ovlentry(entryp, &oentry);
114 code = ubik_VL_CreateEntry(cstruct, 0, &oentry);
117 code = ubik_VL_CreateEntryN(cstruct, 0, entryp);
119 if (code == RXGEN_OPCODE) {
120 newvlserver = 1; /* Doesn't support new interface */
130 VLDB_GetEntryByID(afs_uint32 volid, afs_int32 voltype, struct nvldbentry *entryp)
132 struct vldbentry oentry;
135 if (newvlserver == 1) {
138 ubik_VL_GetEntryByID(cstruct, 0, volid, voltype, &oentry);
140 ovlentry_to_nvlentry(&oentry, entryp);
143 code = ubik_VL_GetEntryByIDN(cstruct, 0, volid, voltype, entryp);
145 if (code == RXGEN_OPCODE) {
146 newvlserver = 1; /* Doesn't support new interface */
156 VLDB_GetEntryByName(char *namep, struct nvldbentry *entryp)
158 struct vldbentry oentry;
161 if (newvlserver == 1) {
163 code = ubik_VL_GetEntryByNameO(cstruct, 0, namep, &oentry);
165 ovlentry_to_nvlentry(&oentry, entryp);
168 code = ubik_VL_GetEntryByNameN(cstruct, 0, namep, entryp);
170 if (code == RXGEN_OPCODE) {
171 newvlserver = 1; /* Doesn't support new interface */
181 VLDB_ReplaceEntry(afs_uint32 volid, afs_int32 voltype, struct nvldbentry *entryp, afs_int32 releasetype)
183 struct vldbentry oentry;
186 if (newvlserver == 1) {
188 code = nvlentry_to_ovlentry(entryp, &oentry);
192 ubik_VL_ReplaceEntry(cstruct, 0, volid, voltype, &oentry,
197 ubik_VL_ReplaceEntryN(cstruct, 0, volid, voltype, entryp,
200 if (code == RXGEN_OPCODE) {
201 newvlserver = 1; /* Doesn't support new interface */
212 VLDB_ListAttributes(VldbListByAttributes *attrp,
214 nbulkentries *blkentriesp)
216 bulkentries arrayEntries;
219 if (newvlserver == 1) {
221 memset(&arrayEntries, 0, sizeof(arrayEntries)); /*initialize to hint the stub to alloc space */
223 ubik_VL_ListAttributes(cstruct, 0, attrp, entriesp,
226 blkentriesp->nbulkentries_val =
227 (nvldbentry *) malloc(*entriesp * sizeof(struct nvldbentry));
228 for (i = 0; i < *entriesp; i++) { /* process each entry */
229 ovlentry_to_nvlentry(&arrayEntries.bulkentries_val[i],
230 &blkentriesp->nbulkentries_val[i]);
233 if (arrayEntries.bulkentries_val)
234 free(arrayEntries.bulkentries_val);
238 ubik_VL_ListAttributesN(cstruct, 0, attrp, entriesp,
241 if (code == RXGEN_OPCODE) {
242 newvlserver = 1; /* Doesn't support new interface */
252 VLDB_ListAttributesN2(VldbListByAttributes *attrp,
255 afs_int32 *nentriesp,
256 nbulkentries *blkentriesp,
257 afs_int32 *nextindexp)
262 ubik_VL_ListAttributesN2(cstruct, 0, attrp, (name ? name : ""),
263 thisindex, nentriesp, blkentriesp, nextindexp);
268 static int vlserverv4 = -1;
272 afs_uint32 addrs[16];
275 * Increase cache size. This avoids high CPU usage by the vlserver
276 * in environments where there are more than 16 fileservers in the
279 #define GETADDRUCACHESIZE 64
280 struct cacheips cacheips[GETADDRUCACHESIZE];
281 int cacheip_index = 0;
284 VLDB_IsSameAddrs(afs_uint32 serv1, afs_uint32 serv2, afs_int32 *errorp)
287 ListAddrByAttributes attrs;
289 afs_uint32 *addrp, i, j, f1, f2;
290 afs_int32 unique, nentries;
292 static int initcache = 0;
298 if (vlserverv4 == 1) {
302 for (i = 0; i < GETADDRUCACHESIZE; i++) {
303 cacheips[i].server = cacheips[i].count = 0;
308 /* See if it's cached */
309 for (i = 0; i < GETADDRUCACHESIZE; i++) {
311 for (j = 0; j < cacheips[i].count; j++) {
312 if (serv1 == cacheips[i].addrs[j])
314 else if (serv2 == cacheips[i].addrs[j])
322 if (cacheips[i].server == serv1)
326 memset(&attrs, 0, sizeof(attrs));
327 attrs.Mask = VLADDR_IPADDR;
328 attrs.ipaddr = serv1;
329 memset(&addrs, 0, sizeof(addrs));
330 memset(&uuid, 0, sizeof(uuid));
332 ubik_VL_GetAddrsU(cstruct, 0, &attrs, &uuid, &unique, &nentries,
334 if (vlserverv4 == -1) {
335 if (code == RXGEN_OPCODE) {
336 vlserverv4 = 1; /* Doesn't support new interface */
342 if (code == VL_NOENT)
350 if (nentries > GETADDRUCACHESIZE)
351 nentries = GETADDRUCACHESIZE; /* safety check; should not happen */
352 if (++cacheip_index >= GETADDRUCACHESIZE)
354 cacheips[cacheip_index].server = serv1;
355 cacheips[cacheip_index].count = nentries;
356 addrp = addrs.bulkaddrs_val;
357 for (i = 0; i < nentries; i++, addrp++) {
358 cacheips[cacheip_index].addrs[i] = *addrp;
359 if (serv2 == *addrp) {
368 Set encryption. If 'cryptflag' is nonzero, encrpytion is turned on
369 for authenticated connections; if zero, encryption is turned off.
370 Calling this function always results in a level of at least rxkad_auth;
371 to get a rxkad_clear connection, simply don't call this.
374 vsu_SetCrypt(int cryptflag)
377 vsu_rxkad_level = rxkad_crypt;
379 vsu_rxkad_level = rxkad_auth;
385 Get the appropriate type of ubik client structure out from the system.
388 vsu_ClientInit(int noAuthFlag, const char *confDir, char *cellName, afs_int32 sauth,
389 struct ubik_client **uclientp,
390 int (*secproc)(struct rx_securityClass *, afs_int32))
392 return ugen_ClientInit(noAuthFlag, confDir, cellName, sauth, uclientp,
393 secproc, "vsu_ClientInit", vsu_rxkad_level,
394 VLDB_MAXSERVERS, AFSCONF_VLDBSERVICE, 90,
395 0, 0, USER_SERVICE_ID);
399 /*extract the name of volume <name> without readonly or backup suffixes
400 * and return the result as <rname>.
403 vsu_ExtractName(char rname[], char name[])
405 char sname[VOLSER_OLDMAXVOLNAME + 1];
408 strncpy(sname, name, sizeof(sname));
409 sname[sizeof(sname) - 1] = '\0';
410 total = strlen(sname);
411 if (!strcmp(&sname[total - 9], ".readonly")) {
412 /*discard the last 8 chars */
413 sname[total - 9] = '\0';
414 strcpy(rname, sname);
416 } else if (!strcmp(&sname[total - 7], ".backup")) {
417 /*discard last 6 chars */
418 sname[total - 7] = '\0';
419 strcpy(rname, sname);
422 strncpy(rname, name, VOLSER_OLDMAXVOLNAME);
423 rname[VOLSER_OLDMAXVOLNAME] = '\0';
428 /* returns 0 if failed */
430 vsu_GetVolumeID(char *astring, struct ubik_client *acstruct, afs_int32 *errp)
432 char volname[VOLSER_OLDMAXVOLNAME + 1];
433 struct nvldbentry entry;
439 if (isdigit(astring[0])) {
442 result = strtoul(astring, &end, 10);
443 if (result != UINT_MAX && *end == '\0')
447 /* It was not a volume number but something else */
448 total = strlen(astring);
449 vsu_ExtractName(volname, astring);
450 vcode = VLDB_GetEntryByName(volname, &entry);
452 if ((total >= 9) && (!strcmp(&astring[total - 9], ".readonly")))
453 return entry.volumeId[ROVOL];
454 else if ((total >= 7) && (!strcmp(&astring[total - 7], ".backup")))
455 return entry.volumeId[BACKVOL];
457 return (entry.volumeId[RWVOL]);
460 return 0; /* can't find volume */