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;
59 extern int VL_CreateEntry(), VL_CreateEntryN();
60 extern int VL_GetEntryByID(), VL_GetEntryByIDN();
61 extern int VL_GetEntryByNameO(), VL_GetEntryByNameN();
62 extern int VL_ReplaceEntry(), VL_ReplaceEntryN();
63 extern int VL_ListAttributes(), VL_ListAttributesN(), VL_ListAttributesN2();
66 ovlentry_to_nvlentry(oentryp, nentryp)
67 struct vldbentry *oentryp;
68 struct nvldbentry *nentryp;
72 memset(nentryp, 0, sizeof(struct nvldbentry));
73 strncpy(nentryp->name, oentryp->name, sizeof(nentryp->name));
74 for (i = 0; i < oentryp->nServers; i++) {
75 nentryp->serverNumber[i] = oentryp->serverNumber[i];
76 nentryp->serverPartition[i] = oentryp->serverPartition[i];
77 nentryp->serverFlags[i] = oentryp->serverFlags[i];
79 nentryp->nServers = oentryp->nServers;
80 for (i = 0; i < MAXTYPES; i++)
81 nentryp->volumeId[i] = oentryp->volumeId[i];
82 nentryp->cloneId = oentryp->cloneId;
83 nentryp->flags = oentryp->flags;
87 nvlentry_to_ovlentry(nentryp, oentryp)
88 struct nvldbentry *nentryp;
89 struct vldbentry *oentryp;
93 memset(oentryp, 0, sizeof(struct vldbentry));
94 strncpy(oentryp->name, nentryp->name, sizeof(oentryp->name));
95 if (nentryp->nServers > OMAXNSERVERS) {
97 * The alternative is to store OMAXSERVERS but it's always better
98 * to know what's going on...
102 for (i = 0; i < nentryp->nServers; i++) {
103 oentryp->serverNumber[i] = nentryp->serverNumber[i];
104 oentryp->serverPartition[i] = nentryp->serverPartition[i];
105 oentryp->serverFlags[i] = nentryp->serverFlags[i];
107 oentryp->nServers = i;
108 for (i = 0; i < MAXTYPES; i++)
109 oentryp->volumeId[i] = nentryp->volumeId[i];
110 oentryp->cloneId = nentryp->cloneId;
111 oentryp->flags = nentryp->flags;
115 static int newvlserver = 0;
117 VLDB_CreateEntry(entryp)
118 struct nvldbentry *entryp;
120 struct vldbentry oentry;
123 if (newvlserver == 1) {
125 code = nvlentry_to_ovlentry(entryp, &oentry);
128 code = ubik_Call(VL_CreateEntry, cstruct, 0, &oentry);
131 code = ubik_Call(VL_CreateEntryN, cstruct, 0, entryp);
133 if (code == RXGEN_OPCODE) {
134 newvlserver = 1; /* Doesn't support new interface */
143 VLDB_GetEntryByID(volid, voltype, entryp)
144 afs_int32 volid, voltype;
145 struct nvldbentry *entryp;
147 struct vldbentry oentry;
150 if (newvlserver == 1) {
153 ubik_Call(VL_GetEntryByID, cstruct, 0, volid, voltype, &oentry);
155 ovlentry_to_nvlentry(&oentry, entryp);
158 code = ubik_Call(VL_GetEntryByIDN, cstruct, 0, volid, voltype, entryp);
160 if (code == RXGEN_OPCODE) {
161 newvlserver = 1; /* Doesn't support new interface */
170 VLDB_GetEntryByName(namep, entryp)
172 struct nvldbentry *entryp;
174 struct vldbentry oentry;
177 if (newvlserver == 1) {
179 code = ubik_Call(VL_GetEntryByNameO, cstruct, 0, namep, &oentry);
181 ovlentry_to_nvlentry(&oentry, entryp);
184 code = ubik_Call(VL_GetEntryByNameN, cstruct, 0, namep, entryp);
186 if (code == RXGEN_OPCODE) {
187 newvlserver = 1; /* Doesn't support new interface */
196 VLDB_ReplaceEntry(volid, voltype, entryp, releasetype)
197 afs_int32 volid, voltype, releasetype;
198 struct nvldbentry *entryp;
200 struct vldbentry oentry;
203 if (newvlserver == 1) {
205 code = nvlentry_to_ovlentry(entryp, &oentry);
209 ubik_Call(VL_ReplaceEntry, cstruct, 0, volid, voltype, &oentry,
214 ubik_Call(VL_ReplaceEntryN, cstruct, 0, volid, voltype, entryp,
217 if (code == RXGEN_OPCODE) {
218 newvlserver = 1; /* Doesn't support new interface */
229 VLDB_ListAttributes(attrp, entriesp, blkentriesp)
230 VldbListByAttributes *attrp;
232 nbulkentries *blkentriesp;
234 bulkentries arrayEntries;
235 register int code, i;
237 if (newvlserver == 1) {
239 memset(&arrayEntries, 0, sizeof(arrayEntries)); /*initialize to hint the stub to alloc space */
241 ubik_Call(VL_ListAttributes, cstruct, 0, attrp, entriesp,
244 blkentriesp->nbulkentries_val =
245 (nvldbentry *) malloc(*entriesp * sizeof(struct nvldbentry));
246 for (i = 0; i < *entriesp; i++) { /* process each entry */
247 ovlentry_to_nvlentry(&arrayEntries.bulkentries_val[i],
248 &blkentriesp->nbulkentries_val[i]);
251 if (arrayEntries.bulkentries_val)
252 free(arrayEntries.bulkentries_val);
256 ubik_Call(VL_ListAttributesN, cstruct, 0, attrp, entriesp,
259 if (code == RXGEN_OPCODE) {
260 newvlserver = 1; /* Doesn't support new interface */
269 VLDB_ListAttributesN2(attrp, name, thisindex, nentriesp, blkentriesp,
271 VldbListByAttributes *attrp;
274 afs_int32 *nentriesp;
275 nbulkentries *blkentriesp;
276 afs_int32 *nextindexp;
281 ubik_Call(VL_ListAttributesN2, cstruct, 0, attrp, (name ? name : ""),
282 thisindex, nentriesp, blkentriesp, nextindexp);
287 static int vlserverv4 = -1;
291 afs_uint32 addrs[16];
294 * Increase cache size. This avoids high CPU usage by the vlserver
295 * in environments where there are more than 16 fileservers in the
298 #define GETADDRUCACHESIZE 64
299 struct cacheips cacheips[GETADDRUCACHESIZE];
300 int cacheip_index = 0;
301 extern int VL_GetAddrsU();
302 VLDB_IsSameAddrs(serv1, serv2, errorp)
303 afs_int32 serv1, serv2, *errorp;
306 ListAddrByAttributes attrs;
308 afs_uint32 *addrp, nentries, unique, i, j, f1, f2;
310 static int initcache = 0;
316 if (vlserverv4 == 1) {
320 for (i = 0; i < GETADDRUCACHESIZE; i++) {
321 cacheips[i].server = cacheips[i].count = 0;
326 /* See if it's cached */
327 for (i = 0; i < GETADDRUCACHESIZE; i++) {
329 for (j = 0; j < cacheips[i].count; j++) {
330 if (serv1 == cacheips[i].addrs[j])
332 else if (serv2 == cacheips[i].addrs[j])
340 if (cacheips[i].server == serv1)
344 memset(&attrs, 0, sizeof(attrs));
345 attrs.Mask = VLADDR_IPADDR;
346 attrs.ipaddr = serv1;
347 memset(&addrs, 0, sizeof(addrs));
348 memset(&uuid, 0, sizeof(uuid));
350 ubik_Call(VL_GetAddrsU, cstruct, 0, &attrs, &uuid, &unique, &nentries,
352 if (vlserverv4 == -1) {
353 if (code == RXGEN_OPCODE) {
354 vlserverv4 = 1; /* Doesn't support new interface */
360 if (code == VL_NOENT)
368 if (nentries > GETADDRUCACHESIZE)
369 nentries = GETADDRUCACHESIZE; /* safety check; should not happen */
370 if (++cacheip_index >= GETADDRUCACHESIZE)
372 cacheips[cacheip_index].server = serv1;
373 cacheips[cacheip_index].count = nentries;
374 addrp = addrs.bulkaddrs_val;
375 for (i = 0; i < nentries; i++, addrp++) {
376 cacheips[cacheip_index].addrs[i] = *addrp;
377 if (serv2 == *addrp) {
387 subik_Call(aproc, aclient, aflags, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10,
388 p11, p12, p13, p14, p15, p16)
389 register struct ubik_client *aclient;
392 afs_int32 p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14,
395 struct vldbentry vldbentry;
396 register int code, (*nproc) ();
398 if (newvlserver == 1) {
401 ubik_Call(aproc, aclient, aflags, p1, p2, p3, p4, p5, p6, p7, p8, p9,
402 p10, p11, p12, p13, p14, p15, p16);
404 if (code == RXGEN_OPCODE) {
405 newvlserver = 1; /* Doesn't support new interface */
415 Set encryption. If 'cryptflag' is nonzero, encrpytion is turned on
416 for authenticated connections; if zero, encryption is turned off.
417 Calling this function always results in a level of at least rxkad_auth;
418 to get a rxkad_clear connection, simply don't call this.
421 vsu_SetCrypt(cryptflag)
425 vsu_rxkad_level = rxkad_crypt;
427 vsu_rxkad_level = rxkad_auth;
433 Get the appropriate type of ubik client structure out from the system.
436 vsu_ClientInit(noAuthFlag, confDir, cellName, sauth, uclientp, secproc)
440 struct ubik_client **uclientp;
444 afs_int32 code, scIndex, i;
445 struct afsconf_cell info;
446 struct afsconf_dir *tdir;
447 struct ktc_principal sname;
448 struct ktc_token ttoken;
449 struct rx_securityClass *sc;
450 static struct rx_connection *serverconns[VLDB_MAXSERVERS];
456 fprintf(STDERR, "vsu_ClientInit: could not initialize rx.\n");
459 rx_SetRxDeadTime(90);
461 if (sauth) { /* -localauth */
462 tdir = afsconf_Open(AFSDIR_SERVER_ETC_DIRPATH);
465 "vsu_ClientInit: Could not process files in configuration directory (%s).\n",
466 AFSDIR_SERVER_ETC_DIRPATH);
469 code = afsconf_ClientAuth(tdir, &sc, &scIndex); /* sets sc,scIndex */
472 "vsu_ClientInit: Could not get security object for -localAuth\n");
476 afsconf_GetCellInfo(tdir, tdir->cellName, AFSCONF_VLDBSERVICE,
480 "vsu_ClientInit: can't find cell %s's hosts in %s/%s\n",
481 cellName, AFSDIR_SERVER_ETC_DIRPATH,
482 AFSDIR_CELLSERVDB_FILE);
485 } else { /* not -localauth */
486 tdir = afsconf_Open(confDir);
489 "vsu_ClientInit: Could not process files in configuration directory (%s).\n",
495 code = afsconf_GetLocalCell(tdir, cellstr, sizeof(cellstr));
498 "vsu_ClientInit: can't get local cellname, check %s/%s\n",
499 confDir, AFSDIR_THISCELL_FILE);
506 afsconf_GetCellInfo(tdir, cellName, AFSCONF_VLDBSERVICE, &info);
509 "vsu_ClientInit: can't find cell %s's hosts in %s/%s\n",
510 cellName, confDir, AFSDIR_CELLSERVDB_FILE);
513 if (noAuthFlag) /* -noauth */
515 else { /* not -noauth */
516 strcpy(sname.cell, info.name);
517 sname.instance[0] = 0;
518 strcpy(sname.name, "afs");
519 code = ktc_GetToken(&sname, &ttoken, sizeof(ttoken), NULL);
520 if (code) { /* did not get ticket */
522 "vsu_ClientInit: Could not get afs tokens, running unauthenticated.\n");
524 } else { /* got a ticket */
526 if ((ttoken.kvno < 0) || (ttoken.kvno > 255)) {
528 "vsu_ClientInit: funny kvno (%d) in ticket, proceeding\n",
536 sc = rxnull_NewClientSecurityObject();
539 sc = rxkad_NewClientSecurityObject(vsu_rxkad_level,
541 ttoken.kvno, ttoken.ticketLen,
545 fprintf(STDERR, "vsu_ClientInit: unsupported security index %d\n",
554 if (secproc) /* tell UV module about default authentication */
555 (*secproc) (sc, scIndex);
556 if (info.numServers > VLDB_MAXSERVERS) {
558 "vsu_ClientInit: info.numServers=%d (> VLDB_MAXSERVERS=%d)\n",
559 info.numServers, VLDB_MAXSERVERS);
562 for (i = 0; i < info.numServers; i++) {
564 rx_NewConnection(info.hostAddr[i].sin_addr.s_addr,
565 info.hostAddr[i].sin_port, USER_SERVICE_ID, sc,
569 code = ubik_ClientInit(serverconns, uclientp);
571 fprintf(STDERR, "vsu_ClientInit: ubik client init failed.\n");
578 /*extract the name of volume <name> without readonly or backup suffixes
579 * and return the result as <rname>.
581 vsu_ExtractName(rname, name)
582 char rname[], name[];
584 char sname[VOLSER_OLDMAXVOLNAME + 1];
587 strncpy(sname, name, sizeof(sname));
588 sname[sizeof(sname) - 1] = '\0';
589 total = strlen(sname);
590 if (!strcmp(&sname[total - 9], ".readonly")) {
591 /*discard the last 8 chars */
592 sname[total - 9] = '\0';
593 strcpy(rname, sname);
595 } else if (!strcmp(&sname[total - 7], ".backup")) {
596 /*discard last 6 chars */
597 sname[total - 7] = '\0';
598 strcpy(rname, sname);
601 strncpy(rname, name, VOLSER_OLDMAXVOLNAME);
602 rname[VOLSER_OLDMAXVOLNAME] = '\0';
608 /* returns 0 if failed */
610 vsu_GetVolumeID(astring, acstruct, errp)
611 struct ubik_client *acstruct;
615 afs_uint32 tc, value;
617 char *str, *ptr, volname[VOLSER_OLDMAXVOLNAME + 1];
619 struct nvldbentry entry;
624 total = strlen(astring);
628 while ((curval = *str++)) {
629 if (curval < '0' || curval > '9')
634 vsu_ExtractName(volname, astring);
635 vcode = VLDB_GetEntryByName(volname, &entry);
637 if (!strcmp(&astring[total - 9], ".readonly"))
638 return entry.volumeId[ROVOL];
639 else if ((!strcmp(&astring[total - 7], ".backup")))
640 return entry.volumeId[BACKVOL];
642 return (entry.volumeId[RWVOL]);
645 return 0; /* can't find volume */
650 while ((tc = *astring++)) {
653 fprintf(STDERR, "goofed in volid \n");
655 fprintf(STDERR, "Could not get entry from vldb for %s\n",
657 PrintError("", vcode);
662 if (tc < '0' || tc > '9') {
665 "internal error: out of range char in vol ID\n");
667 fprintf(STDERR, "Could not get entry from vldb for %s\n",
669 PrintError("", vcode);