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>
43 #include <rx/rx_globals.h>
45 #include <afs/vlserver.h>
47 #include <afs/cellconfig.h>
50 #include <afs/afsint.h>
57 struct ubik_client *cstruct;
58 static rxkad_level vsu_rxkad_level = rxkad_clear;
61 ovlentry_to_nvlentry(oentryp, nentryp)
62 struct vldbentry *oentryp;
63 struct nvldbentry *nentryp;
67 memset(nentryp, 0, sizeof(struct nvldbentry));
68 strncpy(nentryp->name, oentryp->name, sizeof(nentryp->name));
69 for (i = 0; i < oentryp->nServers; i++) {
70 nentryp->serverNumber[i] = oentryp->serverNumber[i];
71 nentryp->serverPartition[i] = oentryp->serverPartition[i];
72 nentryp->serverFlags[i] = oentryp->serverFlags[i];
74 nentryp->nServers = oentryp->nServers;
75 for (i = 0; i < MAXTYPES; i++)
76 nentryp->volumeId[i] = oentryp->volumeId[i];
77 nentryp->cloneId = oentryp->cloneId;
78 nentryp->flags = oentryp->flags;
82 nvlentry_to_ovlentry(nentryp, oentryp)
83 struct nvldbentry *nentryp;
84 struct vldbentry *oentryp;
88 memset(oentryp, 0, sizeof(struct vldbentry));
89 strncpy(oentryp->name, nentryp->name, sizeof(oentryp->name));
90 if (nentryp->nServers > OMAXNSERVERS) {
92 * The alternative is to store OMAXSERVERS but it's always better
93 * to know what's going on...
97 for (i = 0; i < nentryp->nServers; i++) {
98 oentryp->serverNumber[i] = nentryp->serverNumber[i];
99 oentryp->serverPartition[i] = nentryp->serverPartition[i];
100 oentryp->serverFlags[i] = nentryp->serverFlags[i];
102 oentryp->nServers = i;
103 for (i = 0; i < MAXTYPES; i++)
104 oentryp->volumeId[i] = nentryp->volumeId[i];
105 oentryp->cloneId = nentryp->cloneId;
106 oentryp->flags = nentryp->flags;
110 static int newvlserver = 0;
112 VLDB_CreateEntry(entryp)
113 struct nvldbentry *entryp;
115 struct vldbentry oentry;
118 if (newvlserver == 1) {
120 code = nvlentry_to_ovlentry(entryp, &oentry);
123 code = ubik_Call(VL_CreateEntry, cstruct, 0, &oentry);
126 code = ubik_Call(VL_CreateEntryN, cstruct, 0, entryp);
128 if (code == RXGEN_OPCODE) {
129 newvlserver = 1; /* Doesn't support new interface */
138 VLDB_GetEntryByID(volid, voltype, entryp)
139 afs_int32 volid, voltype;
140 struct nvldbentry *entryp;
142 struct vldbentry oentry;
145 if (newvlserver == 1) {
148 ubik_Call(VL_GetEntryByID, cstruct, 0, volid, voltype, &oentry);
150 ovlentry_to_nvlentry(&oentry, entryp);
153 code = ubik_Call(VL_GetEntryByIDN, cstruct, 0, volid, voltype, entryp);
155 if (code == RXGEN_OPCODE) {
156 newvlserver = 1; /* Doesn't support new interface */
165 VLDB_GetEntryByName(namep, entryp)
167 struct nvldbentry *entryp;
169 struct vldbentry oentry;
172 if (newvlserver == 1) {
174 code = ubik_Call(VL_GetEntryByNameO, cstruct, 0, namep, &oentry);
176 ovlentry_to_nvlentry(&oentry, entryp);
179 code = ubik_Call(VL_GetEntryByNameN, cstruct, 0, namep, entryp);
181 if (code == RXGEN_OPCODE) {
182 newvlserver = 1; /* Doesn't support new interface */
191 VLDB_ReplaceEntry(volid, voltype, entryp, releasetype)
192 afs_int32 volid, voltype, releasetype;
193 struct nvldbentry *entryp;
195 struct vldbentry oentry;
198 if (newvlserver == 1) {
200 code = nvlentry_to_ovlentry(entryp, &oentry);
204 ubik_Call(VL_ReplaceEntry, cstruct, 0, volid, voltype, &oentry,
209 ubik_Call(VL_ReplaceEntryN, cstruct, 0, volid, voltype, entryp,
212 if (code == RXGEN_OPCODE) {
213 newvlserver = 1; /* Doesn't support new interface */
224 VLDB_ListAttributes(attrp, entriesp, blkentriesp)
225 VldbListByAttributes *attrp;
227 nbulkentries *blkentriesp;
229 bulkentries arrayEntries;
230 register int code, i;
232 if (newvlserver == 1) {
234 memset(&arrayEntries, 0, sizeof(arrayEntries)); /*initialize to hint the stub to alloc space */
236 ubik_Call(VL_ListAttributes, cstruct, 0, attrp, entriesp,
239 blkentriesp->nbulkentries_val =
240 (nvldbentry *) malloc(*entriesp * sizeof(struct nvldbentry));
241 for (i = 0; i < *entriesp; i++) { /* process each entry */
242 ovlentry_to_nvlentry(&arrayEntries.bulkentries_val[i],
243 &blkentriesp->nbulkentries_val[i]);
246 if (arrayEntries.bulkentries_val)
247 free(arrayEntries.bulkentries_val);
251 ubik_Call(VL_ListAttributesN, cstruct, 0, attrp, entriesp,
254 if (code == RXGEN_OPCODE) {
255 newvlserver = 1; /* Doesn't support new interface */
264 VLDB_ListAttributesN2(attrp, name, thisindex, nentriesp, blkentriesp,
266 VldbListByAttributes *attrp;
269 afs_int32 *nentriesp;
270 nbulkentries *blkentriesp;
271 afs_int32 *nextindexp;
276 ubik_Call(VL_ListAttributesN2, cstruct, 0, attrp, (name ? name : ""),
277 thisindex, nentriesp, blkentriesp, nextindexp);
282 static int vlserverv4 = -1;
286 afs_uint32 addrs[16];
289 * Increase cache size. This avoids high CPU usage by the vlserver
290 * in environments where there are more than 16 fileservers in the
293 #define GETADDRUCACHESIZE 64
294 struct cacheips cacheips[GETADDRUCACHESIZE];
295 int cacheip_index = 0;
297 VLDB_IsSameAddrs(serv1, serv2, errorp)
298 afs_int32 serv1, serv2, *errorp;
301 ListAddrByAttributes attrs;
303 afs_uint32 *addrp, nentries, unique, i, j, f1, f2;
305 static int initcache = 0;
311 if (vlserverv4 == 1) {
315 for (i = 0; i < GETADDRUCACHESIZE; i++) {
316 cacheips[i].server = cacheips[i].count = 0;
321 /* See if it's cached */
322 for (i = 0; i < GETADDRUCACHESIZE; i++) {
324 for (j = 0; j < cacheips[i].count; j++) {
325 if (serv1 == cacheips[i].addrs[j])
327 else if (serv2 == cacheips[i].addrs[j])
335 if (cacheips[i].server == serv1)
339 memset(&attrs, 0, sizeof(attrs));
340 attrs.Mask = VLADDR_IPADDR;
341 attrs.ipaddr = serv1;
342 memset(&addrs, 0, sizeof(addrs));
343 memset(&uuid, 0, sizeof(uuid));
345 ubik_Call(VL_GetAddrsU, cstruct, 0, &attrs, &uuid, &unique, &nentries,
347 if (vlserverv4 == -1) {
348 if (code == RXGEN_OPCODE) {
349 vlserverv4 = 1; /* Doesn't support new interface */
355 if (code == VL_NOENT)
363 if (nentries > GETADDRUCACHESIZE)
364 nentries = GETADDRUCACHESIZE; /* safety check; should not happen */
365 if (++cacheip_index >= GETADDRUCACHESIZE)
367 cacheips[cacheip_index].server = serv1;
368 cacheips[cacheip_index].count = nentries;
369 addrp = addrs.bulkaddrs_val;
370 for (i = 0; i < nentries; i++, addrp++) {
371 cacheips[cacheip_index].addrs[i] = *addrp;
372 if (serv2 == *addrp) {
382 subik_Call(aproc, aclient, aflags, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10,
383 p11, p12, p13, p14, p15, p16)
384 register struct ubik_client *aclient;
387 afs_int32 p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14,
390 struct vldbentry vldbentry;
391 register int code, (*nproc) ();
393 if (newvlserver == 1) {
396 ubik_Call(aproc, aclient, aflags, p1, p2, p3, p4, p5, p6, p7, p8, p9,
397 p10, p11, p12, p13, p14, p15, p16);
399 if (code == RXGEN_OPCODE) {
400 newvlserver = 1; /* Doesn't support new interface */
410 Set encryption. If 'cryptflag' is nonzero, encrpytion is turned on
411 for authenticated connections; if zero, encryption is turned off.
412 Calling this function always results in a level of at least rxkad_auth;
413 to get a rxkad_clear connection, simply don't call this.
416 vsu_SetCrypt(cryptflag)
420 vsu_rxkad_level = rxkad_crypt;
422 vsu_rxkad_level = rxkad_auth;
428 Get the appropriate type of ubik client structure out from the system.
431 vsu_ClientInit(noAuthFlag, confDir, cellName, sauth, uclientp, secproc)
435 struct ubik_client **uclientp;
439 afs_int32 code, scIndex, i;
440 struct afsconf_cell info;
441 struct afsconf_dir *tdir;
442 struct ktc_principal sname;
443 struct ktc_token ttoken;
444 struct rx_securityClass *sc;
445 static struct rx_connection *serverconns[VLDB_MAXSERVERS];
448 return ugen_ClientInit(noAuthFlag, confDir, cellName, sauth, uclientp,
449 secproc, "vsu_ClientInit", vsu_rxkad_level,
450 VLDB_MAXSERVERS, AFSCONF_VLDBSERVICE, 90,
451 0, 0, USER_SERVICE_ID);
455 /*extract the name of volume <name> without readonly or backup suffixes
456 * and return the result as <rname>.
459 vsu_ExtractName(rname, name)
460 char rname[], name[];
462 char sname[VOLSER_OLDMAXVOLNAME + 1];
465 strncpy(sname, name, sizeof(sname));
466 sname[sizeof(sname) - 1] = '\0';
467 total = strlen(sname);
468 if (!strcmp(&sname[total - 9], ".readonly")) {
469 /*discard the last 8 chars */
470 sname[total - 9] = '\0';
471 strcpy(rname, sname);
473 } else if (!strcmp(&sname[total - 7], ".backup")) {
474 /*discard last 6 chars */
475 sname[total - 7] = '\0';
476 strcpy(rname, sname);
479 strncpy(rname, name, VOLSER_OLDMAXVOLNAME);
480 rname[VOLSER_OLDMAXVOLNAME] = '\0';
486 /* returns 0 if failed */
488 vsu_GetVolumeID(astring, acstruct, errp)
489 struct ubik_client *acstruct;
493 afs_uint32 tc, value;
495 char *str, *ptr, volname[VOLSER_OLDMAXVOLNAME + 1];
497 struct nvldbentry entry;
502 total = strlen(astring);
506 while ((curval = *str++)) {
507 if (curval < '0' || curval > '9')
512 vsu_ExtractName(volname, astring);
513 vcode = VLDB_GetEntryByName(volname, &entry);
515 if (!strcmp(&astring[total - 9], ".readonly"))
516 return entry.volumeId[ROVOL];
517 else if ((!strcmp(&astring[total - 7], ".backup")))
518 return entry.volumeId[BACKVOL];
520 return (entry.volumeId[RWVOL]);
523 return 0; /* can't find volume */
528 while ((tc = *astring++)) {
531 fprintf(STDERR, "goofed in volid \n");
533 fprintf(STDERR, "Could not get entry from vldb for %s\n",
535 PrintError("", vcode);
540 if (tc < '0' || tc > '9') {
543 "internal error: out of range char in vol ID\n");
545 fprintf(STDERR, "Could not get entry from vldb for %s\n",
547 PrintError("", vcode);