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>
16 #include <sys/types.h>
25 #include <WINNT/afsevent.h>
27 #ifdef HAVE_SYS_TIME_H
30 #ifdef HAVE_SYS_FILE_H
36 #ifdef HAVE_NETINET_IN_H
37 #include <netinet/in.h>
49 #include <afs/afsutil.h>
52 #include <rx/rx_globals.h>
55 #include <afs/cellconfig.h>
63 void fill_listattributes_entry();
64 void display_listattributes_entry();
66 void display_entryN();
67 void display_update_entry();
72 void fill_update_entry();
74 extern int VL_GetAddrsU(), VL_RegisterAddrs();
75 #define VL_NUMBER_OPCODESX 34
76 static char *opcode_names[VL_NUMBER_OPCODESX] = {
100 "UpdateeEntryByName",
121 extern int VL_UpdateEntryByName();
123 #define ALLOCNT 50000
124 struct Vlent *VLa[NVOLS];
125 #define VHash(avol) ((avol)&(NVOLS-1))
126 struct Vlent *VL, *SVL;
128 struct ubik_client *cstruct;
129 struct rx_connection *serverconns[MAXSERVERS];
130 char confdir[AFSDIR_PATH_MAX];
132 extern struct cmd_syndesc *cmd_CreateSyntax();
134 struct Vlent *GetVolume(vol, entry)
135 struct vldbentry *entry;
138 register struct Vlent *vl;
140 if (!vol) return NULL;
142 for (vl=VLa[i]; vl; vl = vl->next) {
143 if ((vl->rwid == vol && vol != entry->volumeId[0]) ||
144 (vl->roid == vol && vol != entry->volumeId[1]) ||
145 (vl->baid == vol && vol != entry->volumeId[2])) {
149 VL->rwid = entry->volumeId[0];
150 VL->roid = entry->volumeId[1];
151 VL->baid = entry->volumeId[2];
152 strcpy(entry->name, VL->name);
155 if (VLcnt++ > ALLOCNT) { /* XXXX FIX XXXXXXXXX */
156 printf("Too many entries (> %d)\n", ALLOCNT);
163 /* Almost identical's to pr_Initialize in vlserver/pruser.c */
164 afs_int32 vl_Initialize(auth, confDir, server, cellp)
166 char *confDir, *cellp;
168 struct afsconf_dir *tdir;
169 struct ktc_principal sname;
170 struct ktc_token ttoken;
171 afs_int32 scIndex = 0;
172 struct rx_securityClass *sc;
173 struct afsconf_cell info;
178 fprintf(stderr,"vl_Initialize: Could not initialize rx.\n");
182 rx_SetRxDeadTime(50);
184 tdir = afsconf_Open(confDir);
186 fprintf(stderr,"Could not open configuration directory (%s).\n", confDir);
190 if (auth) { /* we don't need tickets for null */
192 code = afsconf_GetLocalCell(tdir, sname.cell, sizeof(sname.cell));
194 fprintf(stderr,"vl_Initialize: Could not get local cell name.\n");
198 strncpy(sname.cell, cellp, sizeof(sname.cell));
199 sname.instance[0] = 0;
200 strcpy(sname.name, "afs");
201 code = ktc_GetToken(&sname,&ttoken, sizeof(ttoken), NULL);
203 fprintf(stderr,"vl_Initialize: Could not get afs tokens, running unauthenticated.\n");
206 else if (ttoken.kvno <= 255)
210 "vl_Initialize: funny kvno (%d) in ticket, proceeding\n",
217 sc = rxnull_NewClientSecurityObject();
222 sc = rxkad_NewClientSecurityObject (rxkad_clear,
223 &ttoken.sessionKey, ttoken.kvno, ttoken.ticketLen, ttoken.ticket);
226 code = afsconf_GetCellInfo(tdir,NULL, AFSCONF_VLDBSERVICE, &info);
227 if (info.numServers > MAXSERVERS) {
229 "vl_Initialize: info.numServers=%d (> MAXSERVERS=%d)\n",
230 info.numServers, MAXSERVERS);
233 for (i = 0;i<info.numServers;i++)
234 serverconns[i] = rx_NewConnection
235 (info.hostAddr[i].sin_addr.s_addr, info.hostAddr[i].sin_port,
236 USER_SERVICE_ID, sc, scIndex);
238 serverconns[0] = rx_NewConnection(server, htons(AFSCONF_VLDBPORT),
239 USER_SERVICE_ID, sc, scIndex);
241 code = ubik_ClientInit(serverconns, &cstruct);
244 fprintf(stderr,"vl_Initialize: ubik client init failed.\n");
250 /* return host address in network byte order */
251 afs_int32 GetServer(aname)
253 register struct hostent *th;
256 register afs_int32 code;
258 code = sscanf(aname, "%d.%d.%d.%d", &b1, &b2, &b3, &b4);
260 addr = (b1<<24) | (b2<<16) | (b3<<8) | b4;
261 return htonl(addr); /* convert to network order (128 in byte 0) */
263 th = gethostbyname(aname);
265 memcpy(&addr, th->h_addr, sizeof(addr));
271 struct cmd_syndesc *as;
273 register struct cmd_item *ti;
274 register afs_int32 code, server = 0, sawserver=0;
275 afs_int32 id, voltype;
276 struct vldbentry entry;
277 char *cmd = 0, *cellp=0;
278 struct VldbUpdateEntry updateentry;
279 struct VldbListByAttributes listbyattributes;
280 int noAuth = 1; /* Default is authenticated connections */
282 if (ti = as->parms[0].items) /* -cellpath <dir> */
283 strcpy(confdir, ti->data);
284 if (as->parms[1].items) /* -server */
285 strcpy(confdir, AFSDIR_SERVER_ETC_DIRPATH);
286 if (as->parms[2].items) /* -noauth */
288 if (ti = as->parms[3].items) { /* -host */
289 server = GetServer(ti->data);
291 printf("server '%s' not found in host table\n", ti->data);
296 if (!sawserver && noAuth && (!(ti = as->parms[4].items))) {
297 printf("Must also specify the -cell' option along with -host for authenticated conns\n");
300 if (ti = as->parms[4].items) { /* -cell */
303 if (code = vl_Initialize(noAuth, confdir, server, cellp)) {
304 printf("Couldn't initialize vldb library (code=%d).\n",code);
308 if (as->parms[5].items) { /* -gstats */
310 vital_vlheader vital_header;
311 code = ubik_Call(VL_GetStats, cstruct, 0, &stats, &vital_header);
312 if (!code) dump_stats(&stats, &vital_header);
318 int nargs, releasetype;
319 memset(&entry, 0, sizeof(entry));
320 memset(&updateentry, 0, sizeof(updateentry));
321 memset(&listbyattributes, 0, sizeof(listbyattributes));
323 if (fgets(line, 499, stdin) == NULL) {
328 register char **argp = args;
329 GetArgs(line, argp, &nargs);
332 if (!strcmp(oper, "cr")) {
333 fill_entry(&entry, argp, nargs);
334 display_entry(&entry, 0);
335 code = ubik_Call(VL_CreateEntry, cstruct,0, &entry);
336 printf("return code is %d\n", code);
337 } else if (!strcmp(oper,"rm")) {
338 sscanf(&(*argp)[0], "%d", &id);
340 sscanf(&(*argp)[0], "%d", &voltype);
341 code = ubik_Call(VL_DeleteEntry, cstruct, 0, id, voltype);
342 printf("return code is %d\n",code);
343 } else if (!strcmp(oper, "re")) {
344 sscanf(&(*argp)[0], "%d", &id);
346 sscanf(&(*argp)[0], "%d", &voltype);
348 sscanf(&(*argp)[0], "%d", &releasetype);
350 fill_entry(&entry, argp, nargs);
351 display_entry(&entry, 0);
352 code = ubik_Call(VL_ReplaceEntry, cstruct, 0, id, voltype, &entry, releasetype);
353 printf("return code is %d\n", code);
354 } else if (!strcmp(oper, "up")) {
355 sscanf(&(*argp)[0], "%d", &id);
357 sscanf(&(*argp)[0], "%d", &voltype);
359 sscanf(&(*argp)[0], "%d", &releasetype);
361 fill_update_entry(&updateentry, argp, nargs);
362 display_update_entry(&updateentry, 0);
363 code = ubik_Call(VL_UpdateEntry, cstruct, 0, id, voltype, &updateentry, releasetype);
364 printf("return code is %d\n", code);
365 } else if (!strcmp(oper,"ls")) {
366 afs_int32 index, count, next_index;
367 for (index = 0; 1; index = next_index) {
368 memset(&entry, 0, sizeof(entry));
369 code = ubik_Call(VL_ListEntry,cstruct,0,index,&count,&next_index,&entry);
371 printf("VL_ListEntry returned code = %d\n", code);
374 if (!next_index) break;
375 display_entry(&entry, 0);
377 } else if (!strcmp(oper,"ldups")) {
378 afs_int32 index, count, num=0, num1=0, next_index;
381 VL = SVL = (struct Vlent *) malloc(ALLOCNT * sizeof(struct Vlent));
383 printf("Can't allocate memory...\n");
386 printf("Enumerating all entries in vldb...\n");
387 for (index = 0; 1; index = next_index) {
388 memset(&entry, 0, sizeof(entry));
389 code = ubik_Call(VL_ListEntry,cstruct,0,index,&count,&next_index,&entry);
391 printf("VL_ListEntry returned code = %d\n", code);
394 if (!next_index) break;
396 if (vl1 = GetVolume(entry.volumeId[0], &entry)) {
398 printf("Duplicate entry is found for RW vol %u: [RW %u, RO %u, BA %u, name=%s]\n",
399 entry.volumeId[0], vl1->rwid, vl1->roid, vl1->baid, vl1->name);
401 if (vl1 = GetVolume(entry.volumeId[1], &entry)) {
403 printf("Duplicate entry is found for RO vol %u: [RW %u, RO %u, BA %u, name=%s]\n",
404 entry.volumeId[1], vl1->rwid, vl1->roid, vl1->baid, vl1->name);
406 if (vl1 = GetVolume(entry.volumeId[2], &entry)) {
408 printf("Duplicate entry is found for BA vol %u: [RW %u, RO %u, BA %u, name=%s]\n",
409 entry.volumeId[2], vl1->rwid, vl1->roid, vl1->baid, vl1->name);
411 /*display_entry(&entry, 0);*/
413 printf("(%d vldb entries found - %d duplicates)\n", num, num1);
414 } else if (!strcmp(oper,"checkhash")) {
415 int index, count, num=0, num1=0, num2 = 0, num3=0, num31=0, num4=0, num41=0, next_index;
416 struct vldbentry tentry;
418 VL = SVL = (struct Vlent *) malloc(ALLOCNT * sizeof(struct Vlent));
420 printf("Can't allocate memory...\n");
423 printf("Volumes not found in main hash tables in vldb...\n");
424 for (index = 0; 1; index = next_index) {
425 memset(&entry, 0, sizeof(entry));
426 code = ubik_Call(VL_ListEntry,cstruct,0,index,&count,&next_index,&entry);
428 printf("VL_ListEntry returned code = %d\n", code);
431 if (!next_index) break;
433 code = ubik_Call(VL_GetEntryByNameO,cstruct,0,entry.name, &tentry);
434 if (code == VL_NOENT) {
436 printf("\tVolume %s %d (not in namehash)\n", entry.name, entry.volumeId[RWVOL]);
438 code = ubik_Call(VL_GetEntryByID,cstruct,0,entry.volumeId[RWVOL], RWVOL, &tentry);
439 if (code == VL_NOENT) {
441 printf("\tVolume %s %d (not in rwid hash)\n", entry.name, entry.volumeId[RWVOL]);
443 if (entry.volumeId[BACKVOL]) {
444 code = ubik_Call(VL_GetEntryByID,cstruct,0,entry.volumeId[BACKVOL], BACKVOL, &tentry);
446 if (code == VL_NOENT) {
448 printf("\tVolume %s %d (not in backup id hash)\n", entry.name, entry.volumeId[BACKVOL]);
451 if (entry.volumeId[ROVOL]) {
452 code = ubik_Call(VL_GetEntryByID,cstruct,0,entry.volumeId[ROVOL], ROVOL, &tentry);
454 if (code == VL_NOENT) {
456 printf("\tVolume %s %d (not in RO id hash)\n", entry.name, entry.volumeId[ROVOL]);
460 printf("\nTotal vldb entries %d\nTotal volumes %d (%d rw, %d backup, %d ro)\n",
461 num, num+num31+num41, num, num31, num41);
462 printf("\n\t%d didn't hash properly by name\n\t%d didn't hash properly by rw volid\n",
464 printf("\t%d didn't hash properly by backup volid (out of %d)\n\t%d didn't hash properly by ro volid (out of %d)\n",
465 num3, num31, num4, num41);
466 } else if (!strcmp(oper,"fixhash")) {
467 int index, count, num=0, num1=0, num2 = 0, next_index, x=0;
468 struct vldbentry tentry;
470 VL = SVL = (struct Vlent *) malloc(ALLOCNT * sizeof(struct Vlent));
472 printf("Can't allocate memory...\n");
475 printf("Volumes not found in main hash tables in vldb will be fixed...\n");
476 memset(&updateentry, 0, sizeof(updateentry));
477 for (index = 0; 1; index = next_index) {
478 int n1=0, n2=0, n3=0, n4=0;
479 memset(&entry, 0, sizeof(entry));
480 code = ubik_Call(VL_ListEntry,cstruct,0,index,&count,&next_index,&entry);
482 printf("VL_ListEntry returned code = %d\n", code);
485 if (!next_index) break;
487 code = ubik_Call(VL_GetEntryByNameO,cstruct,0,entry.name, &tentry);
488 if (code == VL_NOENT) {
491 updateentry.Mask = VLUPDATE_VOLNAMEHASH;
492 printf("\tVolume %s %d (not in namehash)\n", entry.name, entry.volumeId[RWVOL]);
493 code = ubik_Call(VL_UpdateEntry, cstruct, 0, entry.volumeId[RWVOL], -1, &updateentry, 0);
496 printf("\tFailed to update volume %s (err=%d)\n", entry.name, code);
499 code = ubik_Call(VL_GetEntryByID,cstruct,0,entry.volumeId[RWVOL], RWVOL, &tentry);
500 if (code == VL_NOENT) {
503 updateentry.Mask = VLUPDATE_RWID;
504 updateentry.spares3 = entry.volumeId[RWVOL];
505 printf("\tVolume %s %d (not in rw id hash)\n", entry.name, entry.volumeId[RWVOL]);
506 code = ubik_Call(VL_UpdateEntryByName, cstruct, 0, entry.name, &updateentry, 0);
508 printf("\tFailed to update volume %s (err=%d)\n", entry.name, code);
513 if (entry.volumeId[BACKVOL] && !n2) {
514 code = ubik_Call(VL_GetEntryByID,cstruct,0,entry.volumeId[BACKVOL], BACKVOL, &tentry);
515 if (code == VL_NOENT) {
518 updateentry.Mask = VLUPDATE_BACKUPID;
519 updateentry.BackupId = entry.volumeId[BACKVOL];
520 printf("\tVolume %s %d (not in backup id hash)\n", entry.name, entry.volumeId[BACKVOL]);
521 code = ubik_Call(VL_UpdateEntry, cstruct, 0, entry.volumeId[RWVOL], -1, &updateentry, 0);
523 printf("\tFailed to update volume %s (err=%d)\n", entry.name, code);
528 if (entry.volumeId[ROVOL && !n2]) {
529 code = ubik_Call(VL_GetEntryByID,cstruct,0,entry.volumeId[ROVOL], ROVOL, &tentry);
530 if (code == VL_NOENT) {
533 updateentry.Mask = VLUPDATE_READONLYID;
534 updateentry.ReadOnlyId = entry.volumeId[ROVOL];
535 printf("\tVolume %s %d (not in RO id hash)\n", entry.name, entry.volumeId[ROVOL]);
536 code = ubik_Call(VL_UpdateEntry, cstruct, 0, entry.volumeId[RWVOL], -1, &updateentry, 0);
538 printf("\tFailed to update volume %s (err=%d)\n", entry.name, code);
544 printf("\nTotal vldb entries found %d:\n\t%d entries didn't hash properly and are fixed except %d that need to be handled manually\n",
546 } else if (!strcmp(oper, "la")) {
549 struct vldbentry *entry;
551 memset(&entries, 0, sizeof(entries));
552 fill_listattributes_entry(&listbyattributes, argp, nargs);
553 display_listattributes_entry(&listbyattributes, 0);
554 code = ubik_Call(VL_ListAttributes, cstruct, 0, &listbyattributes, &nentries, &entries);
556 printf("VL_ListAttributes returned code = %d\n", code);
559 entry = (struct vldbentry *)entries.bulkentries_val;
560 for (i=0; i < nentries; i++, entry++)
561 display_entry(entry, 0);
562 if (entries.bulkentries_val) free((char *)entries.bulkentries_val);
563 } else if (!strcmp(oper, "lan2")) {
564 int nentries, i, si, nsi, t=0;
565 nbulkentries entries;
566 struct nvldbentry *entry;
569 /* The volume name to search for (supports wildcarding) */
571 strcpy(name,argp[0]);
577 fill_listattributes_entry(&listbyattributes, argp, nargs);
578 display_listattributes_entry(&listbyattributes, 0);
579 printf("Wildcard VolName: '%s'\n", name);
581 for (si=0; si!=-1; si=nsi) {
583 memset(&entries, 0, sizeof(entries));
584 code = ubik_Call(VL_ListAttributesN2, cstruct, 0,
585 &listbyattributes, name, si,
586 &nentries, &entries, &nsi);
588 printf("VL_ListAttributesN2 returned code = %d\n", code);
593 entry = (struct nvldbentry *)entries.nbulkentries_val;
594 for (i=0; i < nentries; i++, entry++)
595 display_entryN(entry, 0);
596 if (entries.nbulkentries_val) free((char *)entries.nbulkentries_val);
598 printf("--- %d volumes ---\n", t);
599 } else if (!strcmp(oper, "ln")) {
601 vldb_list linkedvldbs;
602 vldblist vllist, vllist1;
604 fill_listattributes_entry(&listbyattributes, argp, nargs);
605 display_listattributes_entry(&listbyattributes, 0);
606 memset(&linkedvldbs, 0, sizeof(vldb_list));
607 code = ubik_Call(VL_LinkedList, cstruct, 0, &listbyattributes,
608 &netries, &linkedvldbs);
610 printf("VL_LinkedList returned code = %d\n", code);
613 printf("Found %d entr%s\n", netries, (netries==1?"y":"ies"));
614 for (vllist = linkedvldbs.node; vllist; vllist = vllist1) {
615 vllist1 = vllist->next_vldb;
616 display_entry(&vllist->VldbEntry, 0);
617 free((char *)vllist);
619 } else if (!strcmp(oper, "lnn")) {
621 nvldb_list linkedvldbs;
622 nvldblist vllist, vllist1;
624 fill_listattributes_entry(&listbyattributes, argp, nargs);
625 display_listattributes_entry(&listbyattributes, 0);
626 memset(&linkedvldbs, 0, sizeof(vldb_list));
627 code = ubik_Call(VL_LinkedListN, cstruct, 0, &listbyattributes,
628 &netries, &linkedvldbs);
630 printf("VL_LinkedList returned code = %d\n", code);
633 printf("Found %d entr%s\n", netries, (netries==1?"y":"ies"));
634 for (vllist = linkedvldbs.node; vllist; vllist = vllist1) {
635 vllist1 = vllist->next_vldb;
636 display_entry(&vllist->VldbEntry, 0);
637 free((char *)vllist);
639 } else if (!strcmp(oper,"di")) {
640 sscanf(&(*argp)[0], "%d", &id);
642 sscanf(&(*argp)[0], "%d", &voltype);
643 code = ubik_Call(VL_GetEntryByID, cstruct, 0, id, voltype, &entry);
644 display_entry(&entry, code);
645 printf("return code is %d.\n",code);
646 } else if (!strcmp(oper,"rmnh")) {
647 sscanf(&(*argp)[0], "%d", &id);
649 sscanf(&(*argp)[0], "%d", &voltype);
650 code = ubik_Call(VL_GetEntryByID, cstruct, 0, id, voltype, &entry);
651 display_entry(&entry, code);
652 memset(&updateentry, 0, sizeof(updateentry));
653 updateentry.Mask = VLUPDATE_VOLNAMEHASH;
654 printf("\tRehashing namehash table for %s (%d)\n", entry.name, entry.volumeId[RWVOL]);
655 code = ubik_Call(VL_UpdateEntry, cstruct, 0, entry.volumeId[RWVOL], -1, &updateentry, 0);
657 printf("\tFailed to update volume %s (err=%d)\n", entry.name, code);
659 printf("return code is %d.\n",code);
660 } else if (!strcmp(oper,"undelete")) {
661 afs_int32 index, count, next_index;
663 memset(&updateentry, 0, sizeof(updateentry));
664 sscanf(&(*argp)[0], "%d", &id);
666 sscanf(&(*argp)[0], "%d", &voltype);
667 if (voltype < 0 && voltype > 2) {
668 printf("Illegal voltype; must be 0, 1 or 2\n");
671 printf("Searching vldb for volume %d...\n", id);
672 for (index = 0; 1; index = next_index) {
673 memset(&entry, 0, sizeof(entry));
674 code = ubik_Call(VL_ListEntry,cstruct,0,index,&count,&next_index,&entry);
676 printf("VL_ListEntry returned code = %d\n", code);
679 if (!next_index) break;
680 if (entry.volumeId[voltype] == id) {
681 printf("\nThe current contents of the vldb for %d:\n", id);
682 display_entry(&entry, 0);
684 if (entry.flags & VLDELETED) {
685 updateentry.Mask = VLUPDATE_FLAGS;
686 updateentry.flags = entry.flags;
687 updateentry.flags &= ~VLDELETED;
688 printf("\tUndeleting vldb entry for vol %d (%s)\n", id, entry.name);
689 code = ubik_Call(VL_UpdateEntry, cstruct, 0, id, -1, &updateentry, 0);
691 printf("\tFailed to update volume %s (err=%d)\n", entry.name, code);
694 printf("Entry not deleted; ignored\n");
699 } else if (!strcmp(oper,"dn")) {
701 code = ubik_Call(VL_GetEntryByNameO,cstruct,0,vname, &entry);
702 display_entry(&entry, code);
703 printf("return code is %d.\n",code);
704 } else if (!strcmp(oper, "nv")) {
706 sscanf(&(*argp)[0], "%d", &id);
707 code = ubik_Call(VL_GetNewVolumeId, cstruct, 0, id, &newvolid);
708 if (!code) printf("Current Max volid is (in hex):%X\n", newvolid);
709 printf("return code is %d\n", code);
710 } else if (!strcmp(oper, "gs")) {
712 vital_vlheader vital_header;
713 code = ubik_Call(VL_GetStats, cstruct, 0, &stats, &vital_header);
714 if (!code) dump_stats(&stats, &vital_header);
715 printf("return code is %d.\n", code);
716 } else if (!strcmp(oper, "ga")) {
720 struct VLCallBack vlcb;
722 addrs.bulkaddrs_val = 0;
723 addrs.bulkaddrs_len = 0;
724 code = ubik_Call(VL_GetAddrs, cstruct, 0, 0 /*Handle*/, 0 /*spare2*/, &vlcb,
727 printf("VL_GetAddrs returned code = %d\n", code);
730 addrp = addrs.bulkaddrs_val;
731 for (i=0; i < nentries; i++, addrp++) {
732 if ((*addrp & 0xff000000) == 0xff000000)
733 printf ("[0x%x %u] (special multi-homed entry)\n", *addrp, *addrp);
735 printf ("[0x%x %u] %s\n", *addrp, *addrp, hostutil_GetNameByINet(ntohl(*addrp)));
737 free((char *)addrs.bulkaddrs_val);
738 } else if (!strcmp(oper, "gau")) {
742 struct VLCallBack vlcb;
744 addrs.bulkaddrs_val = 0;
745 addrs.bulkaddrs_len = 0;
746 code = ubik_Call(VL_GetAddrs, cstruct, 0, 0 /*Handle*/, 0 /*spare2*/, &vlcb,
749 printf("VL_GetAddrs returned code = %d\n", code);
752 addrp = addrs.bulkaddrs_val;
753 for (i=0; i < nentries; i++, addrp++) {
754 if ((*addrp & 0xff000000) == 0xff000000) {
755 int mhnentries, unique;
756 struct in_addr hostAddr;
759 ListAddrByAttributes attrs;
762 printf ("[0x%x %u] (special multi-homed entry)\n", *addrp, *addrp);
763 attrs.Mask = VLADDR_INDEX;
764 mhaddrs.bulkaddrs_val = 0;
765 mhaddrs.bulkaddrs_len = 0;
766 attrs.index = *addrp & 0x00ffffff;
768 code = ubik_Call(VL_GetAddrsU, cstruct, 0, &attrs, &uuid, &unique, &mhnentries, &mhaddrs);
770 printf("VL_GetAddrsU returned code = %d\n", code);
773 printf(" [%d]: uuid[%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x]\n addrunique=%d, ip address(es):\n", attrs.index, uuid.time_low,
774 uuid.time_mid, uuid.time_hi_and_version, uuid.clock_seq_hi_and_reserved, uuid.clock_seq_low,
775 uuid.node[0], uuid.node[1], uuid.node[2], uuid.node[3], uuid.node[4], uuid.node[5], unique);
776 mhaddrp = mhaddrs.bulkaddrs_val;
777 for (j=0; j<mhnentries; j++) {
778 mhaddrp[j] = ntohl(mhaddrp[j]);
779 hostAddr.s_addr = mhaddrp[j];
780 printf ("\t%s (%s)\n", inet_ntoa(hostAddr), hostutil_GetNameByINet(mhaddrp[j]));
782 if (mhaddrs.bulkaddrs_val) free((char *)mhaddrs.bulkaddrs_val);
784 printf ("[0x%x %u] %s\n", *addrp, *addrp, hostutil_GetNameByINet(ntohl(*addrp)));
787 free((char *)addrs.bulkaddrs_val);
788 } else if (!strcmp(oper, "mhc")) {
789 afs_int32 serveraddrs[MAXSERVERID+1][VL_MAXIPADDRS_PERMH];
790 afs_int32 serveraddrtype[MAXSERVERID+1];
791 int nentries1, nentries2, i, j, x, y, unique, found;
792 afs_uint32 *addrp1, *addrp2;
793 bulkaddrs addrs1, addrs2;
794 struct VLCallBack vlcb;
795 ListAddrByAttributes attrs;
797 afs_int32 base, index;
799 for (i=0; i<MAXSERVERID+1; i++) {
800 serveraddrtype[i] = 0;
801 for (j=0; j<VL_MAXIPADDRS_PERMH; j++)
802 serveraddrs[i][j] = 0;
805 /* Collect a list of all registered IP addresses */
806 addrs1.bulkaddrs_val = 0;
807 addrs1.bulkaddrs_len = 0;
808 code = ubik_Call(VL_GetAddrs, cstruct, 0, 0,
809 0, &vlcb, &nentries1, &addrs1);
811 printf("VL_GetAddrs returned code = %d\n", code);
814 addrp1 = addrs1.bulkaddrs_val;
815 for (i=0; i < nentries1; i++, addrp1++) {
816 if ((*addrp1 & 0xff000000) != 0xff000000) {
817 serveraddrs[i][0] = ntohl(*addrp1);
818 serveraddrtype[i] = 1;
820 /* It's multihomed. Get all of its addresses */
821 serveraddrtype[i] = 2;
822 base = (*addrp1 >> 16) & 0xff;
823 index = *addrp1 & 0xffff;
825 addrs2.bulkaddrs_val = 0;
826 addrs2.bulkaddrs_len = 0;
827 attrs.Mask = VLADDR_INDEX;
828 attrs.index = (base * VL_MHSRV_PERBLK) + index;
829 code = ubik_Call(VL_GetAddrsU, cstruct, 0, &attrs,
830 &uuid, &unique, &nentries2, &addrs2);
832 printf("VL_GetAddrsU returned code = %d\n", code);
836 addrp2 = addrs2.bulkaddrs_val;
837 for (j=0; j<nentries2; j++) {
838 serveraddrs[i][j] = ntohl(addrp2[j]);
840 free((char *)addrs2.bulkaddrs_val);
844 if (serveraddrtype[i] == 1) {
845 printf ("%u\n", serveraddrs[i][0]);
848 for (j=0; j<VL_MAXIPADDRS_PERMH; j++)
849 if (serveraddrs[i][j])
850 printf(" %u", serveraddrs[i][j]);
855 free((char *)addrs1.bulkaddrs_val);
857 /* Look for any duplicates */
858 for (i=0; i<MAXSERVERID+1; i++) {
859 if (!serveraddrtype[i]) continue;
860 for (j=0; j<VL_MAXIPADDRS_PERMH; j++) {
861 if (!serveraddrs[i][j]) continue;
864 for (x=i+1; x<MAXSERVERID+1; x++) {
865 if (!serveraddrtype[x]) continue;
866 for (y=0; y<VL_MAXIPADDRS_PERMH; y++) {
867 if (!serveraddrs[x][y]) continue;
868 if (serveraddrs[i][j] == serveraddrs[x][y]) {
869 serveraddrs[x][y] = 0;
875 printf("Found %d entries of IP address %u (0x%x)\n",
877 serveraddrs[i][j], serveraddrs[i][j]);
882 /*----------------------------------------*/
884 } else if (!strcmp(oper, "regaddr")) {
886 afs_uint32 *addrp, tad;
890 memset(&uuid, 0, sizeof(uuid));
891 sscanf(&(*argp)[0], "%d", &i);
893 memcpy(uuid.node, &i, sizeof(i));
895 if (nargs < 0 || nargs > 16) {
896 printf("Illegal # entries = %d\n", nargs);
899 addrp = (afs_uint32 *) malloc(20 * 4);
900 addrs.bulkaddrs_val = addrp;
901 addrs.bulkaddrs_len = nargs;
903 sscanf(&(*argp)[0], "%d", &tad);
907 code = ubik_Call(VL_RegisterAddrs, cstruct, 0, &uuid, 0 /*spare*/, &addrs);
909 printf("VL_RegisterAddrs returned code = %d\n", code);
912 } else if (!strcmp(oper,"ca")) {
913 extern struct hostent *hostutil_GetHostByName();
914 struct hostent *h1, *h2;
917 printf("changing %s", *argp);
918 h1 = hostutil_GetHostByName(&(*argp)[0]);
920 printf("cmdebug: can't resolve address for host %s", *argp);
923 memcpy(&a1, (afs_int32 *)h1->h_addr, sizeof(afs_uint32));
926 printf(" to %s\n", *argp);
927 h2 = hostutil_GetHostByName(&(*argp)[0]);
929 printf("cmdebug: can't resolve address for host %s", *argp);
932 memcpy(&a2, (afs_int32 *)h2->h_addr, sizeof(afs_uint32));
934 printf("changing 0x%x to 0x%x\n", ntohl(a1), ntohl(a2));
935 code = ubik_Call(VL_ChangeAddr, cstruct, 0, ntohl(a1), ntohl(a2));
937 printf("VL_ChangeAddr returned code = %d\n", code);
940 } else if (!strcmp(oper,"caid")) {
943 sscanf(&(*argp)[0], "%d", &a1);
944 printf("changing %d (0x%x)", a1, a1);
946 sscanf(&(*argp)[0], "%d", &a2);
947 printf(" to %d (0x%x)\n", a2, a2);
948 code = ubik_Call(VL_ChangeAddr, cstruct, 0, a1, a2);
950 printf("VL_ChangeAddr returned code = %d\n", code);
953 } else if ((!strcmp(oper,"?")) || !strcmp(oper,"h"))
955 else if ((!strcmp(oper,"q")) || !strcmp(oper, "quit"))
958 printf("Unknown oper!\n");
965 #include "AFS_component_version_number.c"
971 register struct cmd_syndesc *ts;
974 strcpy(confdir, AFSDIR_CLIENT_ETC_DIRPATH);
975 ts = cmd_CreateSyntax("initcmd", handleit, 0, "initialize the program");
976 cmd_AddParm(ts, "-cellpath", CMD_LIST, CMD_OPTIONAL, "Cell configuration directory");
977 cmd_AddParm(ts, "-server", CMD_LIST, CMD_OPTIONAL, "Use the cell config in /usr/afs/etc (default /usr/vice/etc)");
978 cmd_AddParm(ts, "-noauth", CMD_FLAG, CMD_OPTIONAL, "Run it without authentication");
979 cmd_AddParm(ts, "-host", CMD_LIST, CMD_OPTIONAL, "vldb server to talk to");
980 cmd_AddParm(ts, "-cell", CMD_LIST, CMD_OPTIONAL, "cellname '-host' belongs to (required for auth conns)");
981 cmd_AddParm(ts, "-getstats", CMD_FLAG, CMD_OPTIONAL, "print vldb statistics (non interactive)");
982 code = cmd_Dispatch(argc, argv);
988 fill_entry(entry, argp, nargs)
989 struct vldbentry *entry;
998 sscanf(&(*argp)[0], "%d", &entry->spares3);
1000 sscanf(&(*argp)[0], "%d", &entry->nServers);
1001 strcpy(entry->name, name);
1002 for (i=0; i < entry->nServers; i++) {
1004 sscanf(&(*argp)[0], "%u", &entry->serverNumber[i]);
1006 for (i=0; i < entry->nServers; i++) {
1008 sscanf(&(*argp)[0], "%d", &entry->serverPartition[i]);
1010 for (i=0; i < entry->nServers; i++) {
1012 sscanf(&(*argp)[0], "%d", &entry->serverFlags[i]);
1014 for (i=0; i < MAXTYPES; i++) {
1016 sscanf(&(*argp)[0], "%d", &entry->volumeId[i]);
1019 sscanf(&(*argp)[0], "%d", &entry->flags);
1021 sscanf(&(*argp)[0], "%d", &entry->cloneId);
1025 fill_update_entry(entry, argp, nargs)
1026 struct VldbUpdateEntry *entry;
1035 if (strcmp(name, "null")) {
1036 strcpy(entry->name, name);
1037 entry->Mask |= VLUPDATE_VOLUMENAME;
1040 sscanf(&(*argp)[0], "%d", &entry->flags);
1041 if (entry->flags != -1)
1042 entry->Mask |= VLUPDATE_FLAGS;
1044 sscanf(&(*argp)[0], "%d", &entry->cloneId);
1045 if (entry->flags != -1)
1046 entry->Mask |= VLUPDATE_CLONEID;
1048 sscanf(&(*argp)[0], "%d", &entry->ReadOnlyId);
1049 if (entry->ReadOnlyId != -1)
1050 entry->Mask |= VLUPDATE_READONLYID;
1052 sscanf(&(*argp)[0], "%d", &entry->BackupId);
1053 if (entry->BackupId != -1)
1054 entry->Mask |= VLUPDATE_BACKUPID;
1056 sscanf(&(*argp)[0], "%d", &entry->nModifiedRepsites);
1057 if (entry->nModifiedRepsites != -1)
1058 entry->Mask |= VLUPDATE_REPSITES;
1059 for (i=0; i < entry->nModifiedRepsites; i++) {
1061 sscanf(&(*argp)[0], "%x", &Mask);
1063 sscanf(&(*argp)[0], "%u", &entry->RepsitesTargetServer[i]);
1065 sscanf(&(*argp)[0], "%d", &entry->RepsitesTargetPart[i]);
1066 if (Mask & VLUPDATE_REPS_DELETE)
1067 entry->RepsitesMask[i] |= VLUPDATE_REPS_DELETE;
1068 if (Mask & VLUPDATE_REPS_MODSERV) {
1070 sscanf(&(*argp)[0], "%u", &entry->RepsitesNewServer[i]);
1071 entry->RepsitesMask[i] |= VLUPDATE_REPS_MODSERV;
1072 } else if (Mask & VLUPDATE_REPS_MODPART) {
1074 sscanf(&(*argp)[0], "%d", &entry->RepsitesNewPart[i]);
1075 entry->RepsitesMask[i] |= VLUPDATE_REPS_MODPART;
1076 } else if (Mask & VLUPDATE_REPS_MODFLAG) {
1078 sscanf(&(*argp)[0], "%d", &entry->RepsitesNewFlags[i]);
1079 entry->RepsitesMask[i] |= VLUPDATE_REPS_MODFLAG;
1080 } else if (Mask & VLUPDATE_REPS_ADD) {
1082 sscanf(&(*argp)[0], "%u", &entry->RepsitesNewServer[i]);
1084 sscanf(&(*argp)[0], "%d", &entry->RepsitesNewPart[i]);
1086 sscanf(&(*argp)[0], "%d", &entry->RepsitesNewFlags[i]);
1087 entry->RepsitesMask[i] |= VLUPDATE_REPS_ADD;
1093 fill_listattributes_entry(entry, argp, nargs)
1094 struct VldbListByAttributes *entry;
1100 if (nargs <= 0) return;
1101 entry->server = ntohl(GetServer(argp[0]));
1102 sscanf(&(*argp)[0], "%d", &entry->server);
1103 if (entry->server != 0)
1104 entry->Mask |= VLLIST_SERVER;
1107 if (nargs <= 0) return;
1108 sscanf(&(*argp)[0], "%d", &entry->partition);
1109 if (entry->partition != -1)
1110 entry->Mask |= VLLIST_PARTITION;
1113 if (nargs <= 0) return;
1114 sscanf(&(*argp)[0], "%d", &entry->volumeid);
1115 if (entry->volumeid != -1)
1116 entry->Mask |= VLLIST_VOLUMEID;
1119 if (nargs <= 0) return;
1120 sscanf(&(*argp)[0], "%d", &entry->flag);
1121 if (entry->flag != -1)
1122 entry->Mask |= VLLIST_FLAG;
1126 display_listattributes_entry(entry, error)
1127 struct VldbListByAttributes *entry;
1131 printf("\nList entry values (Mask=%x)\n", entry->Mask);
1132 if (entry->Mask & VLLIST_SERVER)
1133 printf("\tServer: %d.%d.%d.%d\n",
1134 (entry->server>>24) & 0xff, (entry->server>>16) & 0xff,
1135 (entry->server>> 8) & 0xff, (entry->server) & 0xff);
1136 if (entry->Mask & VLLIST_PARTITION)
1137 printf("\tPartition: %d\n", entry->partition);
1138 if (entry->Mask & VLLIST_VOLUMEID)
1139 printf("\tVolumeId: %u\n", entry->volumeid);
1140 if (entry->Mask & VLLIST_FLAG)
1141 printf("\tFlag: %x\n", entry->flag);
1145 #define volumetype_string(type) (type == RWVOL? "read/write":type == ROVOL? "readonly":type == BACKVOL? "backup":"unknown")
1148 display_entry(entry, error)
1149 struct vldbentry *entry;
1155 printf("\nEntry for volume name: %s, volid=%u (flags=%X) are:\n", entry->name, entry->volumeId[RWVOL], entry->flags);
1156 printf("ParentID=%u, ReadOnlyID=%u, backupID=%u, CloneId=%u ", entry->volumeId[0], entry->volumeId[1], entry->volumeId[2], entry->cloneId);
1157 printf("nServers=%d\n", entry->nServers);
1158 printf("ServerNumber\tServerPart\tserverFlag\n");
1159 for (i=0; i < entry->nServers; i++)
1160 printf("%12u\t%10d\t%10x\n", entry->serverNumber[i], entry->serverPartition[i], entry->serverFlags[i]);
1164 display_entryN(entry, error)
1165 struct nvldbentry *entry;
1171 printf("\nEntry for volume name: %s, volid=%u (flags=%X) are:\n",
1172 entry->name, entry->volumeId[RWVOL], entry->flags);
1173 printf("ParentID=%u, ReadOnlyID=%u, backupID=%u, CloneId=%u ",
1174 entry->volumeId[0], entry->volumeId[1],
1175 entry->volumeId[2], entry->cloneId);
1176 printf("nServers=%d\n", entry->nServers);
1177 printf("ServerNumber\tServerPart\tserverFlag\n");
1178 ei = entry->matchindex & 0xffff;
1179 et = (entry->matchindex >> 16) & 0xffff;
1180 for (i=0; i < entry->nServers; i++) {
1181 printf("%12u\t%10d\t%10x",
1182 entry->serverNumber[i], entry->serverPartition[i],
1183 entry->serverFlags[i]);
1185 printf(" <--- %s", (et==4)?"RW":((et==8)?"BK":"RO"));
1192 display_update_entry(entry, error)
1193 struct VldbUpdateEntry *entry;
1199 printf("\nUpdate entry values (Mask=%x)\n", entry->Mask);
1200 if (entry->Mask & VLUPDATE_VOLUMENAME)
1201 printf("\tNew name: %s\n", entry->name);
1202 if (entry->Mask & VLUPDATE_FLAGS)
1203 printf("\tNew flags: %X\n", entry->flags);
1204 if (entry->Mask & VLUPDATE_CLONEID)
1205 printf("\tNew CloneId: %X\n", entry->cloneId);
1206 if (entry->Mask & VLUPDATE_READONLYID)
1207 printf("\tNew RO id: %D\n", entry->ReadOnlyId);
1208 if (entry->Mask & VLUPDATE_BACKUPID)
1209 printf("\tNew BACKUP id: %D\n", entry->BackupId);
1210 if (entry->Mask & VLUPDATE_REPSITES) {
1211 printf("\tRepsites info:\n");
1212 printf("\tFlag\tTServer\tTPart\tNServer\tNPart\tNFlag\n");
1213 for (i=0; i < entry->nModifiedRepsites; i++) {
1214 printf("\t%4x\t%7U\t%5d", entry->RepsitesMask[i], entry->RepsitesTargetServer[i], entry->RepsitesTargetPart[i]);
1215 if ((entry->RepsitesMask[i] & VLUPDATE_REPS_ADD) || (entry->RepsitesMask[i] & VLUPDATE_REPS_MODSERV))
1216 printf("\t%7U", entry->RepsitesNewServer[i]);
1218 printf("\t-------");
1219 if ((entry->RepsitesMask[i] & VLUPDATE_REPS_ADD) || (entry->RepsitesMask[i] & VLUPDATE_REPS_MODPART))
1220 printf("\t%5d", entry->RepsitesNewPart[i]);
1223 if ((entry->RepsitesMask[i] & VLUPDATE_REPS_ADD) || (entry->RepsitesMask[i] & VLUPDATE_REPS_MODFLAG))
1224 printf("\t%5x\n", entry->RepsitesNewFlags[i]);
1226 printf("\t-----\n");
1232 dump_stats(stats, vital_header)
1234 vital_vlheader *vital_header;
1238 strncpy(strg, ctime((time_t *)&stats->start_time), sizeof(strg));
1239 strg[strlen(strg)-1] = 0;
1240 printf("Dynamic statistics stats (starting time: %s):\n", strg);
1241 printf("OpcodeName\t# Requests\t# Aborts\n");
1242 for (i=0; i < VL_NUMBER_OPCODESX; i++)
1243 printf("%10s\t%10d\t%8d\n", opcode_names[i], stats->requests[i], stats->aborts[i]);
1244 printf("\nVldb header stats (version=%d)\n", ntohl(vital_header->vldbversion));
1245 printf("headersize=%d, allocs=%d, frees=%d, MaxVolid=%X\n", ntohl(vital_header->headersize), ntohl(vital_header->allocs), ntohl(vital_header->frees), ntohl(vital_header->MaxVolumeId));
1246 for (i=0; i < MAXTYPES; i++)
1247 printf("total %s entries=%d\n", volumetype_string(i), ntohl(vital_header->totalEntries[i]));
1251 GetArgs(line,args, nargs)
1252 register char *line;
1253 register char **args;
1254 register int *nargs;
1258 register char *last = line;
1259 while (*line == ' ')
1265 *args++ = line, (*nargs)++;
1266 while (*line && *line != ' ')
1274 printf("Valid Commands:\n");
1276 printf(" CreateEntry:\n");
1277 printf("\tcr <vname> <vtype> <#S> <Saddr1>.<Saddrn> <Spart1>.<Spartn> <Sflag1>.<Sflagn> <Volid1-3> <flag>\n");
1279 printf(" DeleteEntry:\n");
1280 printf("\trm <volid> <voltype>\n");
1282 printf(" ReplaceEntry:\n");
1283 printf("\tre <volid> <voltype> <New vldb entry ala 'cr'>\n");
1285 printf(" UpdateEntry:\n");
1286 printf("\tup <volid> <voltype> <vname> <vtype> <#AddSer> [<Saddr1>.<Saddrn> <Spart1>.<Spartn> <Sflag1>.<Sflagn>] <Volid1-3> <flag>\n");
1288 printf(" ListEntry:\n");
1291 printf(" Find duplicate entries of a volume\n");
1292 printf("\tldups\n");
1294 printf(" For each vlentry, find it by name, RW id, BK id, and RO id\n");
1295 printf("\tcheckhash\n");
1297 printf(" UpdateEntry (update the volname, RW id, BK id, RO id hashes):\n");
1298 printf("\tfixhash\n");
1300 printf(" ListAttributes:\n");
1301 printf("\tla [server] [partition] [volumeid] [flag]\n");
1303 printf(" ListAttributesN2:\n");
1304 printf("\tlan2 [volname] [server] [partition] [volumeid] [flag]\n");
1306 printf(" GetEntryByID:\n");
1307 printf("\tdi <volid> <voltype>\n");
1309 printf(" UpdateEntry (refresh namehash table):\n");
1310 printf("\trmnh <volid> <voltype>\n");
1312 printf(" GetEntryByName:\n");
1313 printf("\tdn <volname> <voltype>\n");
1315 printf(" UpdateEntry (undelete a vol entry):\n");
1316 printf("\tundelete <volid> <voltype>\n");
1318 * printf(" LinkedList\n");
1319 * printf("\t:ln [server] [partition] [volumeid] [flag]\n");
1321 * printf(" LinkedListN\n");
1322 * printf("\t:lnn [server] [partition] [volumeid] [flag]\n");
1324 printf(" GetNewVoumeId:\n");
1325 printf("\tnv <bump-count>\n");
1327 printf(" GetStats:\n");
1330 printf(" ChangeAddr:\n");
1331 printf("\tca <oldmachname> <newmachname>\n");
1334 * printf(" ChangeAddr\n");
1335 * printf("\t:caid <oldaddr> <newaddr>\n");
1337 printf(" GetAddrs:\n");
1340 printf(" GetAddrsU:\n");
1343 printf(" RegisterAddrs:\n");
1344 printf("\tregaddr uuidNumber <ip1 .. ipn>\n");
1346 printf("\tmisc: q, quit, ?, h\n");