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>
17 #include <WINNT/afsevent.h>
19 #ifdef HAVE_SYS_FILE_H
24 #include <afs/afsutil.h>
27 #include <rx/rx_globals.h>
29 #include <afs/cellconfig.h>
37 void fill_listattributes_entry(struct VldbListByAttributes *, char **, int);
38 void display_listattributes_entry(struct VldbListByAttributes *,int);
39 void display_entry(struct vldbentry *, int);
40 void display_entryN(struct nvldbentry *, int);
41 void display_update_entry(struct VldbUpdateEntry *, int);
42 void dump_stats(vldstats *, vital_vlheader *);
43 void GetArgs(char *, char **, int *);
44 void print_usage(void);
45 void fill_entry(struct vldbentry *, char **, int);
46 void fill_update_entry(struct VldbUpdateEntry *, char **, int);
48 #define VL_NUMBER_OPCODESX 34
49 static char *opcode_names[VL_NUMBER_OPCODESX] = {
96 struct Vlent *VLa[NVOLS];
97 #define VHash(avol) ((avol)&(NVOLS-1))
98 struct Vlent *VL, *SVL;
100 struct ubik_client *cstruct;
101 struct rx_connection *serverconns[MAXSERVERS];
102 char confdir[AFSDIR_PATH_MAX];
106 GetVolume(int vol, struct vldbentry *entry)
114 for (vl = VLa[i]; vl; vl = vl->next) {
115 if ((vl->rwid == vol && vol != entry->volumeId[0])
116 || (vl->roid == vol && vol != entry->volumeId[1])
117 || (vl->baid == vol && vol != entry->volumeId[2])) {
121 VL->rwid = entry->volumeId[0];
122 VL->roid = entry->volumeId[1];
123 VL->baid = entry->volumeId[2];
124 strcpy(entry->name, VL->name);
127 if (VLcnt++ > ALLOCNT) { /* XXXX FIX XXXXXXXXX */
128 printf("Too many entries (> %d)\n", ALLOCNT);
135 /* Almost identical's to pr_Initialize in vlserver/pruser.c */
137 vl_Initialize(char *confDir, int secFlags, int server, char *cellp)
139 return ugen_ClientInitServer(confDir, cellp, secFlags, &cstruct,
140 MAXSERVERS, AFSCONF_VLDBSERVICE, 90,
141 server, htons(AFSCONF_VLDBPORT));
144 /* return host address in network byte order */
146 GetServer(char *aname)
153 code = sscanf(aname, "%d.%d.%d.%d", &b1, &b2, &b3, &b4);
155 addr = (b1 << 24) | (b2 << 16) | (b3 << 8) | b4;
156 return htonl(addr); /* convert to network order (128 in byte 0) */
158 th = gethostbyname(aname);
161 memcpy(&addr, th->h_addr, sizeof(addr));
167 handleit(struct cmd_syndesc *as, void *arock)
170 afs_int32 code, server = 0, sawserver = 0;
171 afs_int32 id, voltype;
172 struct vldbentry entry;
174 struct VldbUpdateEntry updateentry;
175 struct VldbListByAttributes listbyattributes;
176 int secFlags = AFSCONF_SECOPTS_FALLBACK_NULL;
178 if ((ti = as->parms[0].items)) /* -cellpath <dir> */
179 strcpy(confdir, ti->data);
180 if (as->parms[1].items) /* -server */
181 strcpy(confdir, AFSDIR_SERVER_ETC_DIRPATH);
182 if (as->parms[2].items) /* -noauth */
183 secFlags |= AFSCONF_SECOPTS_NOAUTH;
184 if ((ti = as->parms[3].items)) { /* -host */
185 server = GetServer(ti->data);
187 printf("server '%s' not found in host table\n", ti->data);
192 if (sawserver && !as->parms[2].items && (!(ti = as->parms[4].items))) {
194 ("Must also specify the -cell' option along with -host for authenticated conns\n");
197 if ((ti = as->parms[4].items)) { /* -cell */
200 if ((code = vl_Initialize(confdir, secFlags, server, cellp))) {
201 printf("Couldn't initialize vldb library (code=%d).\n", code);
205 if (as->parms[5].items) { /* -gstats */
207 vital_vlheader vital_header;
208 code = ubik_VL_GetStats(cstruct, 0, &stats, &vital_header);
210 dump_stats(&stats, &vital_header);
216 int nargs, releasetype;
217 memset(&entry, 0, sizeof(entry));
218 memset(&updateentry, 0, sizeof(updateentry));
219 memset(&listbyattributes, 0, sizeof(listbyattributes));
221 if (fgets(line, 499, stdin) == NULL) {
228 GetArgs(line, argp, &nargs);
232 } else if (!strcmp(oper, "cr")) {
233 fill_entry(&entry, argp, nargs);
234 display_entry(&entry, 0);
235 code = ubik_VL_CreateEntry(cstruct, 0, &entry);
236 printf("return code is %d\n", code);
237 } else if (!strcmp(oper, "rm")) {
238 sscanf(&(*argp)[0], "%d", &id);
240 sscanf(&(*argp)[0], "%d", &voltype);
241 code = ubik_VL_DeleteEntry(cstruct, 0, id, voltype);
242 printf("return code is %d\n", code);
243 } else if (!strcmp(oper, "re")) {
244 sscanf(&(*argp)[0], "%d", &id);
246 sscanf(&(*argp)[0], "%d", &voltype);
248 sscanf(&(*argp)[0], "%d", &releasetype);
250 fill_entry(&entry, argp, nargs);
251 display_entry(&entry, 0);
253 ubik_VL_ReplaceEntry(
254 cstruct, 0, id, voltype,
255 &entry, releasetype);
256 printf("return code is %d\n", code);
257 } else if (!strcmp(oper, "up")) {
258 sscanf(&(*argp)[0], "%d", &id);
260 sscanf(&(*argp)[0], "%d", &voltype);
262 sscanf(&(*argp)[0], "%d", &releasetype);
264 fill_update_entry(&updateentry, argp, nargs);
265 display_update_entry(&updateentry, 0);
267 ubik_VL_UpdateEntry(cstruct, 0, id, voltype,
268 &updateentry, releasetype);
269 printf("return code is %d\n", code);
270 } else if (!strcmp(oper, "ls")) {
271 afs_int32 index, count, next_index;
272 for (index = 0; 1; index = next_index) {
273 memset(&entry, 0, sizeof(entry));
275 ubik_VL_ListEntry(cstruct, 0, index, &count,
276 &next_index, &entry);
278 printf("VL_ListEntry returned code = %d\n", code);
283 display_entry(&entry, 0);
285 } else if (!strcmp(oper, "ldups")) {
286 afs_int32 index, count, num = 0, num1 = 0, next_index;
290 (struct Vlent *)malloc(ALLOCNT * sizeof(struct Vlent));
292 printf("Can't allocate memory...\n");
295 printf("Enumerating all entries in vldb...\n");
296 for (index = 0; 1; index = next_index) {
297 memset(&entry, 0, sizeof(entry));
299 ubik_VL_ListEntry(cstruct, 0, index, &count,
300 &next_index, &entry);
302 printf("VL_ListEntry returned code = %d\n", code);
308 if ((vl1 = GetVolume(entry.volumeId[0], &entry))) {
311 ("Duplicate entry is found for RW vol %u: [RW %u, RO %u, BA %u, name=%s]\n",
312 entry.volumeId[0], vl1->rwid, vl1->roid,
313 vl1->baid, vl1->name);
315 if ((vl1 = GetVolume(entry.volumeId[1], &entry))) {
318 ("Duplicate entry is found for RO vol %u: [RW %u, RO %u, BA %u, name=%s]\n",
319 entry.volumeId[1], vl1->rwid, vl1->roid,
320 vl1->baid, vl1->name);
322 if ((vl1 = GetVolume(entry.volumeId[2], &entry))) {
325 ("Duplicate entry is found for BA vol %u: [RW %u, RO %u, BA %u, name=%s]\n",
326 entry.volumeId[2], vl1->rwid, vl1->roid,
327 vl1->baid, vl1->name);
329 /*display_entry(&entry, 0); */
331 printf("(%d vldb entries found - %d duplicates)\n", num,
333 } else if (!strcmp(oper, "checkhash")) {
334 int index, count, num = 0, num1 = 0, num2 = 0, num3 =
335 0, num31 = 0, num4 = 0, num41 = 0, next_index;
336 struct vldbentry tentry;
339 (struct Vlent *)malloc(ALLOCNT * sizeof(struct Vlent));
341 printf("Can't allocate memory...\n");
344 printf("Volumes not found in main hash tables in vldb...\n");
345 for (index = 0; 1; index = next_index) {
346 memset(&entry, 0, sizeof(entry));
348 ubik_VL_ListEntry(cstruct, 0, index, &count,
349 &next_index, &entry);
351 printf("VL_ListEntry returned code = %d\n", code);
358 ubik_VL_GetEntryByNameO(cstruct, 0, entry.name,
360 if (code == VL_NOENT) {
362 printf("\tVolume %s %d (not in namehash)\n",
363 entry.name, entry.volumeId[RWVOL]);
366 ubik_VL_GetEntryByID(cstruct, 0,
367 entry.volumeId[RWVOL], RWVOL, &tentry);
368 if (code == VL_NOENT) {
370 printf("\tVolume %s %d (not in rwid hash)\n",
371 entry.name, entry.volumeId[RWVOL]);
373 if (entry.volumeId[BACKVOL]) {
375 ubik_VL_GetEntryByID(cstruct, 0,
376 entry.volumeId[BACKVOL], BACKVOL,
379 if (code == VL_NOENT) {
381 printf("\tVolume %s %d (not in backup id hash)\n",
382 entry.name, entry.volumeId[BACKVOL]);
385 if (entry.volumeId[ROVOL]) {
387 ubik_VL_GetEntryByID(cstruct, 0,
388 entry.volumeId[ROVOL], ROVOL, &tentry);
390 if (code == VL_NOENT) {
392 printf("\tVolume %s %d (not in RO id hash)\n",
393 entry.name, entry.volumeId[ROVOL]);
398 ("\nTotal vldb entries %d\nTotal volumes %d (%d rw, %d backup, %d ro)\n",
399 num, num + num31 + num41, num, num31, num41);
401 ("\n\t%d didn't hash properly by name\n\t%d didn't hash properly by rw volid\n",
404 ("\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",
405 num3, num31, num4, num41);
406 } else if (!strcmp(oper, "fixhash")) {
407 int index, count, num = 0, num1 = 0, num2 = 0, next_index, x =
409 struct vldbentry tentry;
412 (struct Vlent *)malloc(ALLOCNT * sizeof(struct Vlent));
414 printf("Can't allocate memory...\n");
418 ("Volumes not found in main hash tables in vldb will be fixed...\n");
419 memset(&updateentry, 0, sizeof(updateentry));
420 for (index = 0; 1; index = next_index) {
421 memset(&entry, 0, sizeof(entry));
423 ubik_VL_ListEntry(cstruct, 0, index, &count,
424 &next_index, &entry);
426 printf("VL_ListEntry returned code = %d\n", code);
433 ubik_VL_GetEntryByNameO(cstruct, 0, entry.name,
435 if (code == VL_NOENT) {
437 updateentry.Mask = VLUPDATE_VOLNAMEHASH;
438 printf("\tVolume %s %d (not in namehash)\n",
439 entry.name, entry.volumeId[RWVOL]);
441 ubik_VL_UpdateEntry(cstruct, 0,
442 entry.volumeId[RWVOL], -1, &updateentry,
446 printf("\tFailed to update volume %s (err=%d)\n",
451 ubik_VL_GetEntryByID(cstruct, 0,
452 entry.volumeId[RWVOL], RWVOL, &tentry);
453 if (code == VL_NOENT) {
456 updateentry.Mask = VLUPDATE_RWID;
457 updateentry.spares3 = entry.volumeId[RWVOL];
458 printf("\tVolume %s %d (not in rw id hash)\n",
459 entry.name, entry.volumeId[RWVOL]);
461 ubik_VL_UpdateEntryByName(cstruct, 0,
462 entry.name, &updateentry, 0);
464 printf("\tFailed to update volume %s (err=%d)\n",
470 if (entry.volumeId[BACKVOL]) {
472 ubik_VL_GetEntryByID(cstruct, 0,
473 entry.volumeId[BACKVOL], BACKVOL,
475 if (code == VL_NOENT) {
477 updateentry.Mask = VLUPDATE_BACKUPID;
478 updateentry.BackupId = entry.volumeId[BACKVOL];
479 printf("\tVolume %s %d (not in backup id hash)\n",
480 entry.name, entry.volumeId[BACKVOL]);
482 ubik_VL_UpdateEntry(cstruct, 0,
483 entry.volumeId[RWVOL], -1,
487 ("\tFailed to update volume %s (err=%d)\n",
493 if (entry.volumeId[ROVOL]) {
495 ubik_VL_GetEntryByID(cstruct, 0,
496 entry.volumeId[ROVOL], ROVOL, &tentry);
497 if (code == VL_NOENT) {
499 updateentry.Mask = VLUPDATE_READONLYID;
500 updateentry.ReadOnlyId = entry.volumeId[ROVOL];
501 printf("\tVolume %s %d (not in RO id hash)\n",
502 entry.name, entry.volumeId[ROVOL]);
504 ubik_VL_UpdateEntry(cstruct, 0,
505 entry.volumeId[RWVOL], -1,
509 ("\tFailed to update volume %s (err=%d)\n",
517 ("\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",
519 } else if (!strcmp(oper, "la")) {
522 struct vldbentry *entry;
524 memset(&entries, 0, sizeof(entries));
525 fill_listattributes_entry(&listbyattributes, argp, nargs);
526 display_listattributes_entry(&listbyattributes, 0);
528 ubik_VL_ListAttributes(cstruct, 0,
529 &listbyattributes, &nentries, &entries);
531 printf("VL_ListAttributes returned code = %d\n", code);
534 entry = (struct vldbentry *)entries.bulkentries_val;
535 for (i = 0; i < nentries; i++, entry++)
536 display_entry(entry, 0);
537 if (entries.bulkentries_val)
538 free(entries.bulkentries_val);
539 } else if (!strcmp(oper, "lan2")) {
540 int nentries, i, si, nsi, t = 0;
541 nbulkentries entries;
542 struct nvldbentry *entry;
545 /* The volume name to search for (supports wildcarding) */
547 strcpy(name, argp[0]);
553 fill_listattributes_entry(&listbyattributes, argp, nargs);
554 display_listattributes_entry(&listbyattributes, 0);
555 printf("Wildcard VolName: '%s'\n", name);
557 for (si = 0; si != -1; si = nsi) {
559 memset(&entries, 0, sizeof(entries));
561 ubik_VL_ListAttributesN2(cstruct, 0,
562 &listbyattributes, name, si, &nentries,
565 printf("VL_ListAttributesN2 returned code = %d\n",
571 entry = (struct nvldbentry *)entries.nbulkentries_val;
572 for (i = 0; i < nentries; i++, entry++)
573 display_entryN(entry, 0);
574 if (entries.nbulkentries_val)
575 free(entries.nbulkentries_val);
577 printf("--- %d volumes ---\n", t);
578 } else if (!strcmp(oper, "ln")) {
580 vldb_list linkedvldbs;
581 vldblist vllist, vllist1;
583 fill_listattributes_entry(&listbyattributes, argp, nargs);
584 display_listattributes_entry(&listbyattributes, 0);
585 memset(&linkedvldbs, 0, sizeof(vldb_list));
587 ubik_VL_LinkedList(cstruct, 0, &listbyattributes,
588 &netries, &linkedvldbs);
590 printf("VL_LinkedList returned code = %d\n", code);
593 printf("Found %d entr%s\n", netries,
594 (netries == 1 ? "y" : "ies"));
595 for (vllist = linkedvldbs.node; vllist; vllist = vllist1) {
596 vllist1 = vllist->next_vldb;
597 display_entry((struct vldbentry *) &vllist->VldbEntry, 0);
600 } else if (!strcmp(oper, "lnn")) {
602 nvldb_list linkedvldbs;
603 nvldblist vllist, vllist1;
605 fill_listattributes_entry(&listbyattributes, argp, nargs);
606 display_listattributes_entry(&listbyattributes, 0);
607 memset(&linkedvldbs, 0, sizeof(vldb_list));
609 ubik_VL_LinkedListN(cstruct, 0, &listbyattributes,
610 &netries, &linkedvldbs);
612 printf("VL_LinkedList returned code = %d\n", code);
615 printf("Found %d entr%s\n", netries,
616 (netries == 1 ? "y" : "ies"));
617 for (vllist = linkedvldbs.node; vllist; vllist = vllist1) {
618 vllist1 = vllist->next_vldb;
619 display_entry((struct vldbentry *)&vllist->VldbEntry, 0);
622 } else if (!strcmp(oper, "di")) {
623 sscanf(&(*argp)[0], "%d", &id);
625 sscanf(&(*argp)[0], "%d", &voltype);
627 ubik_VL_GetEntryByID(cstruct, 0, id, voltype,
629 display_entry(&entry, code);
630 printf("return code is %d.\n", code);
631 } else if (!strcmp(oper, "rmnh")) {
632 sscanf(&(*argp)[0], "%d", &id);
634 sscanf(&(*argp)[0], "%d", &voltype);
636 ubik_VL_GetEntryByID(cstruct, 0, id, voltype,
638 display_entry(&entry, code);
639 memset(&updateentry, 0, sizeof(updateentry));
640 updateentry.Mask = VLUPDATE_VOLNAMEHASH;
641 printf("\tRehashing namehash table for %s (%d)\n", entry.name,
642 entry.volumeId[RWVOL]);
644 ubik_VL_UpdateEntry(cstruct, 0,
645 entry.volumeId[RWVOL], -1, &updateentry, 0);
647 printf("\tFailed to update volume %s (err=%d)\n",
650 printf("return code is %d.\n", code);
651 } else if (!strcmp(oper, "undelete")) {
652 afs_int32 index, count, next_index;
654 memset(&updateentry, 0, sizeof(updateentry));
655 sscanf(&(*argp)[0], "%d", &id);
657 sscanf(&(*argp)[0], "%d", &voltype);
658 if (voltype < 0 && voltype > 2) {
659 printf("Illegal voltype; must be 0, 1 or 2\n");
662 printf("Searching vldb for volume %d...\n", id);
663 for (index = 0; 1; index = next_index) {
664 memset(&entry, 0, sizeof(entry));
666 ubik_VL_ListEntry(cstruct, 0, index, &count,
667 &next_index, &entry);
669 printf("VL_ListEntry returned code = %d\n", code);
674 if (entry.volumeId[voltype] == id) {
675 printf("\nThe current contents of the vldb for %d:\n",
677 display_entry(&entry, 0);
679 if (entry.flags & VLDELETED) {
680 updateentry.Mask = VLUPDATE_FLAGS;
681 updateentry.flags = entry.flags;
682 updateentry.flags &= ~VLDELETED;
684 ("\tUndeleting vldb entry for vol %d (%s)\n",
687 ubik_VL_UpdateEntry(cstruct, 0, id, -1,
691 ("\tFailed to update volume %s (err=%d)\n",
695 printf("Entry not deleted; ignored\n");
700 } else if (!strcmp(oper, "dn")) {
703 ubik_VL_GetEntryByNameO(cstruct, 0, vname, &entry);
704 display_entry(&entry, code);
705 printf("return code is %d.\n", code);
706 } else if (!strcmp(oper, "nv")) {
707 unsigned int newvolid;
708 sscanf(&(*argp)[0], "%d", &id);
710 ubik_VL_GetNewVolumeId(cstruct, 0, id, &newvolid);
712 printf("Current Max volid is (in hex):0x%x\n", newvolid);
713 printf("return code is %d\n", code);
714 } else if (!strcmp(oper, "gs")) {
716 vital_vlheader vital_header;
718 ubik_VL_GetStats(cstruct, 0, &stats, &vital_header);
720 dump_stats(&stats, &vital_header);
721 printf("return code is %d.\n", code);
722 } else if (!strcmp(oper, "ga")) {
726 struct VLCallBack vlcb;
728 addrs.bulkaddrs_val = 0;
729 addrs.bulkaddrs_len = 0;
730 code = ubik_VL_GetAddrs(cstruct, 0, 0 /*Handle */ ,
731 0 /*spare2 */ , &vlcb,
734 printf("VL_GetAddrs returned code = %d\n", code);
737 addrp = addrs.bulkaddrs_val;
738 for (i = 0; i < nentries; i++, addrp++) {
739 if ((*addrp & 0xff000000) == 0xff000000)
740 printf("[0x%x %u] (special multi-homed entry)\n",
743 printf("[0x%x %u] %s\n", *addrp, *addrp,
744 hostutil_GetNameByINet(ntohl(*addrp)));
746 free(addrs.bulkaddrs_val);
747 } else if (!strcmp(oper, "gau")) {
751 struct VLCallBack vlcb;
753 addrs.bulkaddrs_val = 0;
754 addrs.bulkaddrs_len = 0;
755 code = ubik_VL_GetAddrs(cstruct, 0, 0 /*Handle */ ,
756 0 /*spare2 */ , &vlcb,
759 printf("VL_GetAddrs returned code = %d\n", code);
762 addrp = addrs.bulkaddrs_val;
763 for (i = 0; i < nentries; i++, addrp++) {
764 if ((*addrp & 0xff000000) == 0xff000000) {
765 int mhnentries, unique;
766 struct in_addr hostAddr;
769 ListAddrByAttributes attrs;
772 printf("[0x%x %u] (special multi-homed entry)\n",
774 attrs.Mask = VLADDR_INDEX;
775 mhaddrs.bulkaddrs_val = 0;
776 mhaddrs.bulkaddrs_len = 0;
777 attrs.index = *addrp & 0x00ffffff;
780 ubik_VL_GetAddrsU(cstruct, 0, &attrs, &uuid,
781 &unique, &mhnentries, &mhaddrs);
783 printf("VL_GetAddrsU returned code = %d\n", code);
787 (" [%d]: uuid[%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x]\n addrunique=%d, ip address(es):\n",
788 attrs.index, uuid.time_low, uuid.time_mid,
789 uuid.time_hi_and_version,
790 uuid.clock_seq_hi_and_reserved,
791 uuid.clock_seq_low, uuid.node[0], uuid.node[1],
792 uuid.node[2], uuid.node[3], uuid.node[4],
793 uuid.node[5], unique);
794 mhaddrp = mhaddrs.bulkaddrs_val;
795 for (j = 0; j < mhnentries; j++) {
796 mhaddrp[j] = ntohl(mhaddrp[j]);
797 hostAddr.s_addr = mhaddrp[j];
798 printf("\t%s (%s)\n", inet_ntoa(hostAddr),
799 hostutil_GetNameByINet(mhaddrp[j]));
801 if (mhaddrs.bulkaddrs_val)
802 free(mhaddrs.bulkaddrs_val);
804 printf("[0x%x %u] %s\n", *addrp, *addrp,
805 hostutil_GetNameByINet(ntohl(*addrp)));
808 free(addrs.bulkaddrs_val);
809 } else if (!strcmp(oper, "mhc")) {
810 afs_uint32 serveraddrs[MAXSERVERID + 1][VL_MAXIPADDRS_PERMH];
811 afs_int32 serveraddrtype[MAXSERVERID + 1];
812 int nentries1, nentries2, i, j, x, y, unique, found;
813 afs_uint32 *addrp1, *addrp2;
814 bulkaddrs addrs1, addrs2;
815 struct VLCallBack vlcb;
816 ListAddrByAttributes attrs;
818 afs_int32 base, index;
820 for (i = 0; i < MAXSERVERID + 1; i++) {
821 serveraddrtype[i] = 0;
822 for (j = 0; j < VL_MAXIPADDRS_PERMH; j++)
823 serveraddrs[i][j] = 0;
826 /* Collect a list of all registered IP addresses */
827 addrs1.bulkaddrs_val = 0;
828 addrs1.bulkaddrs_len = 0;
830 ubik_VL_GetAddrs(cstruct, 0, 0, 0, &vlcb,
831 &nentries1, &addrs1);
833 printf("VL_GetAddrs returned code = %d\n", code);
836 addrp1 = addrs1.bulkaddrs_val;
837 for (i = 0; i < nentries1; i++, addrp1++) {
838 if ((*addrp1 & 0xff000000) != 0xff000000) {
839 serveraddrs[i][0] = ntohl(*addrp1);
840 serveraddrtype[i] = 1;
842 /* It's multihomed. Get all of its addresses */
843 serveraddrtype[i] = 2;
844 base = (*addrp1 >> 16) & 0xff;
845 index = *addrp1 & 0xffff;
847 addrs2.bulkaddrs_val = 0;
848 addrs2.bulkaddrs_len = 0;
849 attrs.Mask = VLADDR_INDEX;
850 attrs.index = (base * VL_MHSRV_PERBLK) + index;
852 ubik_VL_GetAddrsU(cstruct, 0, &attrs, &uuid,
853 &unique, &nentries2, &addrs2);
855 printf("VL_GetAddrsU returned code = %d\n", code);
859 addrp2 = addrs2.bulkaddrs_val;
860 for (j = 0; j < nentries2; j++) {
861 serveraddrs[i][j] = ntohl(addrp2[j]);
863 free(addrs2.bulkaddrs_val);
867 if (serveraddrtype[i] == 1) {
868 printf("%u\n", serveraddrs[i][0]);
871 for (j = 0; j < VL_MAXIPADDRS_PERMH; j++)
872 if (serveraddrs[i][j])
873 printf(" %u", serveraddrs[i][j]);
878 free(addrs1.bulkaddrs_val);
880 /* Look for any duplicates */
881 for (i = 0; i < MAXSERVERID + 1; i++) {
882 if (!serveraddrtype[i])
884 for (j = 0; j < VL_MAXIPADDRS_PERMH; j++) {
885 if (!serveraddrs[i][j])
889 for (x = i + 1; x < MAXSERVERID + 1; x++) {
890 if (!serveraddrtype[x])
892 for (y = 0; y < VL_MAXIPADDRS_PERMH; y++) {
893 if (!serveraddrs[x][y])
895 if (serveraddrs[i][j] == serveraddrs[x][y]) {
896 serveraddrs[x][y] = 0;
903 ("Found %d entries of IP address %u (0x%x)\n",
904 found + 1, serveraddrs[i][j],
910 /*----------------------------------------*/
912 } else if (!strcmp(oper, "regaddr")) {
914 afs_uint32 *addrp, tad;
918 memset(&uuid, 0, sizeof(uuid));
919 sscanf(&(*argp)[0], "%d", &i);
921 memcpy(uuid.node, &i, sizeof(i));
923 if (nargs < 0 || nargs > 16) {
924 printf("Illegal # entries = %d\n", nargs);
927 addrp = (afs_uint32 *) malloc(20 * 4);
928 addrs.bulkaddrs_val = addrp;
929 addrs.bulkaddrs_len = nargs;
931 sscanf(&(*argp)[0], "%d", &tad);
936 ubik_VL_RegisterAddrs(cstruct, 0, &uuid,
937 0 /*spare */ , &addrs);
939 printf("VL_RegisterAddrs returned code = %d\n", code);
942 } else if (!strcmp(oper, "ca")) {
943 struct hostent *h1, *h2;
946 printf("changing %s", *argp);
947 h1 = hostutil_GetHostByName(&(*argp)[0]);
949 printf("cmdebug: can't resolve address for host %s",
953 memcpy(&a1, (afs_int32 *) h1->h_addr, sizeof(afs_uint32));
956 printf(" to %s\n", *argp);
957 h2 = hostutil_GetHostByName(&(*argp)[0]);
959 printf("cmdebug: can't resolve address for host %s",
963 memcpy(&a2, (afs_int32 *) h2->h_addr, sizeof(afs_uint32));
965 printf("changing 0x%x to 0x%x\n", ntohl(a1), ntohl(a2));
967 ubik_VL_ChangeAddr(cstruct, 0, ntohl(a1),
970 printf("VL_ChangeAddr returned code = %d\n", code);
973 } else if (!strcmp(oper, "caid")) {
976 sscanf(&(*argp)[0], "%d", &a1);
977 printf("changing %d (0x%x)", a1, a1);
979 sscanf(&(*argp)[0], "%d", &a2);
980 printf(" to %d (0x%x)\n", a2, a2);
981 code = ubik_VL_ChangeAddr(cstruct, 0, a1, a2);
983 printf("VL_ChangeAddr returned code = %d\n", code);
986 } else if ((!strcmp(oper, "?")) || !strcmp(oper, "h") || !strcmp(oper, "help"))
988 else if ((!strcmp(oper, "q")) || !strcmp(oper, "quit"))
991 printf("Unknown oper (%s)!\n", oper);
999 #include "AFS_component_version_number.c"
1002 main(int argc, char **argv)
1004 struct cmd_syndesc *ts;
1007 strcpy(confdir, AFSDIR_CLIENT_ETC_DIRPATH);
1008 ts = cmd_CreateSyntax("initcmd", handleit, NULL, "initialize the program");
1009 cmd_AddParm(ts, "-cellpath", CMD_LIST, CMD_OPTIONAL,
1010 "Cell configuration directory");
1011 cmd_AddParm(ts, "-server", CMD_LIST, CMD_OPTIONAL,
1012 "Use the cell config in /usr/afs/etc (default /usr/vice/etc)");
1013 cmd_AddParm(ts, "-noauth", CMD_FLAG, CMD_OPTIONAL,
1014 "Run it without authentication");
1015 cmd_AddParm(ts, "-host", CMD_LIST, CMD_OPTIONAL,
1016 "vldb server to talk to");
1017 cmd_AddParm(ts, "-cell", CMD_LIST, CMD_OPTIONAL,
1018 "cellname '-host' belongs to (required for auth conns)");
1019 cmd_AddParm(ts, "-getstats", CMD_FLAG, CMD_OPTIONAL,
1020 "print vldb statistics (non interactive)");
1021 code = cmd_Dispatch(argc, argv);
1027 fill_entry(struct vldbentry *entry, char **argp, int nargs)
1034 sscanf(&(*argp)[0], "%d", &entry->spares3);
1036 sscanf(&(*argp)[0], "%d", &entry->nServers);
1037 strcpy(entry->name, name);
1038 for (i = 0; i < entry->nServers; i++) {
1040 sscanf(&(*argp)[0], "%u", &entry->serverNumber[i]);
1042 for (i = 0; i < entry->nServers; i++) {
1044 sscanf(&(*argp)[0], "%d", &entry->serverPartition[i]);
1046 for (i = 0; i < entry->nServers; i++) {
1048 sscanf(&(*argp)[0], "%d", &entry->serverFlags[i]);
1050 for (i = 0; i < MAXTYPES; i++) {
1052 sscanf(&(*argp)[0], "%u", &entry->volumeId[i]);
1055 sscanf(&(*argp)[0], "%d", &entry->flags);
1057 sscanf(&(*argp)[0], "%u", &entry->cloneId);
1061 fill_update_entry(struct VldbUpdateEntry *entry, char **argp, int nargs)
1068 if (strcmp(name, "null")) {
1069 strcpy(entry->name, name);
1070 entry->Mask |= VLUPDATE_VOLUMENAME;
1073 sscanf(&(*argp)[0], "%d", &entry->flags);
1074 if (entry->flags != -1)
1075 entry->Mask |= VLUPDATE_FLAGS;
1077 sscanf(&(*argp)[0], "%u", &entry->cloneId);
1078 if (entry->flags != -1)
1079 entry->Mask |= VLUPDATE_CLONEID;
1081 sscanf(&(*argp)[0], "%u", &entry->ReadOnlyId);
1082 if (entry->ReadOnlyId != -1)
1083 entry->Mask |= VLUPDATE_READONLYID;
1085 sscanf(&(*argp)[0], "%u", &entry->BackupId);
1086 if (entry->BackupId != -1)
1087 entry->Mask |= VLUPDATE_BACKUPID;
1089 sscanf(&(*argp)[0], "%d", &entry->nModifiedRepsites);
1090 if (entry->nModifiedRepsites != -1)
1091 entry->Mask |= VLUPDATE_REPSITES;
1092 for (i = 0; i < entry->nModifiedRepsites; i++) {
1094 sscanf(&(*argp)[0], "%x", &Mask);
1096 sscanf(&(*argp)[0], "%u", &entry->RepsitesTargetServer[i]);
1098 sscanf(&(*argp)[0], "%d", &entry->RepsitesTargetPart[i]);
1099 if (Mask & VLUPDATE_REPS_DELETE)
1100 entry->RepsitesMask[i] |= VLUPDATE_REPS_DELETE;
1101 if (Mask & VLUPDATE_REPS_MODSERV) {
1103 sscanf(&(*argp)[0], "%u", &entry->RepsitesNewServer[i]);
1104 entry->RepsitesMask[i] |= VLUPDATE_REPS_MODSERV;
1105 } else if (Mask & VLUPDATE_REPS_MODPART) {
1107 sscanf(&(*argp)[0], "%d", &entry->RepsitesNewPart[i]);
1108 entry->RepsitesMask[i] |= VLUPDATE_REPS_MODPART;
1109 } else if (Mask & VLUPDATE_REPS_MODFLAG) {
1111 sscanf(&(*argp)[0], "%d", &entry->RepsitesNewFlags[i]);
1112 entry->RepsitesMask[i] |= VLUPDATE_REPS_MODFLAG;
1113 } else if (Mask & VLUPDATE_REPS_ADD) {
1115 sscanf(&(*argp)[0], "%u", &entry->RepsitesNewServer[i]);
1117 sscanf(&(*argp)[0], "%d", &entry->RepsitesNewPart[i]);
1119 sscanf(&(*argp)[0], "%d", &entry->RepsitesNewFlags[i]);
1120 entry->RepsitesMask[i] |= VLUPDATE_REPS_ADD;
1126 fill_listattributes_entry(struct VldbListByAttributes *entry, char **argp,
1133 entry->server = ntohl(GetServer(argp[0]));
1134 sscanf(&(*argp)[0], "%d", &entry->server);
1135 if (entry->server != 0)
1136 entry->Mask |= VLLIST_SERVER;
1141 sscanf(&(*argp)[0], "%d", &entry->partition);
1142 if (entry->partition != -1)
1143 entry->Mask |= VLLIST_PARTITION;
1148 sscanf(&(*argp)[0], "%d", &entry->volumeid);
1149 if (entry->volumeid != -1)
1150 entry->Mask |= VLLIST_VOLUMEID;
1155 sscanf(&(*argp)[0], "%d", &entry->flag);
1156 if (entry->flag != -1)
1157 entry->Mask |= VLLIST_FLAG;
1161 display_listattributes_entry(struct VldbListByAttributes *entry, int error)
1165 printf("\nList entry values (Mask=%x)\n", entry->Mask);
1166 if (entry->Mask & VLLIST_SERVER)
1167 printf("\tServer: %d.%d.%d.%d\n", (entry->server >> 24) & 0xff,
1168 (entry->server >> 16) & 0xff, (entry->server >> 8) & 0xff,
1169 (entry->server) & 0xff);
1170 if (entry->Mask & VLLIST_PARTITION)
1171 printf("\tPartition: %d\n", entry->partition);
1172 if (entry->Mask & VLLIST_VOLUMEID)
1173 printf("\tVolumeId: %u\n", entry->volumeid);
1174 if (entry->Mask & VLLIST_FLAG)
1175 printf("\tFlag: %x\n", entry->flag);
1179 #define volumetype_string(type) (type == RWVOL? "read/write":type == ROVOL? "readonly":type == BACKVOL? "backup":"unknown")
1182 display_entry(struct vldbentry *entry, int error)
1188 printf("\nEntry for volume name: %s, volid=%u (flags=%X) are:\n",
1189 entry->name, entry->volumeId[RWVOL], entry->flags);
1190 printf("ParentID=%u, ReadOnlyID=%u, backupID=%u, CloneId=%u ",
1191 entry->volumeId[0], entry->volumeId[1], entry->volumeId[2],
1193 printf("nServers=%d\n", entry->nServers);
1194 printf("ServerNumber\tServerPart\tserverFlag\n");
1195 for (i = 0; i < entry->nServers; i++)
1196 printf("%12u\t%10d\t%10x\n", entry->serverNumber[i],
1197 entry->serverPartition[i], entry->serverFlags[i]);
1201 display_entryN(struct nvldbentry *entry, int error)
1207 printf("\nEntry for volume name: %s, volid=%u (flags=%X) are:\n",
1208 entry->name, entry->volumeId[RWVOL], entry->flags);
1209 printf("ParentID=%u, ReadOnlyID=%u, backupID=%u, CloneId=%u ",
1210 entry->volumeId[0], entry->volumeId[1], entry->volumeId[2],
1212 printf("nServers=%d\n", entry->nServers);
1213 printf("ServerNumber\tServerPart\tserverFlag\n");
1214 ei = entry->matchindex & 0xffff;
1215 et = (entry->matchindex >> 16) & 0xffff;
1216 for (i = 0; i < entry->nServers; i++) {
1217 printf("%12u\t%10d\t%10x", entry->serverNumber[i],
1218 entry->serverPartition[i], entry->serverFlags[i]);
1220 printf(" <--- %s", (et == 4) ? "RW" : ((et == 8) ? "BK" : "RO"));
1227 display_update_entry(struct VldbUpdateEntry *entry, int error)
1233 printf("\nUpdate entry values (Mask=%x)\n", entry->Mask);
1234 if (entry->Mask & VLUPDATE_VOLUMENAME)
1235 printf("\tNew name: %s\n", entry->name);
1236 if (entry->Mask & VLUPDATE_FLAGS)
1237 printf("\tNew flags: %X\n", entry->flags);
1238 if (entry->Mask & VLUPDATE_CLONEID)
1239 printf("\tNew CloneId: %X\n", entry->cloneId);
1240 if (entry->Mask & VLUPDATE_READONLYID)
1241 printf("\tNew RO id: %d\n", entry->ReadOnlyId);
1242 if (entry->Mask & VLUPDATE_BACKUPID)
1243 printf("\tNew BACKUP id: %d\n", entry->BackupId);
1244 if (entry->Mask & VLUPDATE_REPSITES) {
1245 printf("\tRepsites info:\n");
1246 printf("\tFlag\tTServer\tTPart\tNServer\tNPart\tNFlag\n");
1247 for (i = 0; i < entry->nModifiedRepsites; i++) {
1248 printf("\t%4x\t%7u\t%5d", entry->RepsitesMask[i],
1249 entry->RepsitesTargetServer[i],
1250 entry->RepsitesTargetPart[i]);
1251 if ((entry->RepsitesMask[i] & VLUPDATE_REPS_ADD)
1252 || (entry->RepsitesMask[i] & VLUPDATE_REPS_MODSERV))
1253 printf("\t%7u", entry->RepsitesNewServer[i]);
1255 printf("\t-------");
1256 if ((entry->RepsitesMask[i] & VLUPDATE_REPS_ADD)
1257 || (entry->RepsitesMask[i] & VLUPDATE_REPS_MODPART))
1258 printf("\t%5d", entry->RepsitesNewPart[i]);
1261 if ((entry->RepsitesMask[i] & VLUPDATE_REPS_ADD)
1262 || (entry->RepsitesMask[i] & VLUPDATE_REPS_MODFLAG))
1263 printf("\t%5x\n", entry->RepsitesNewFlags[i]);
1265 printf("\t-----\n");
1271 dump_stats(vldstats *stats, vital_vlheader *vital_header)
1275 time_t start_time = stats->start_time;
1278 strftime(strg, sizeof(strg), "%a %b %d %H:%M:%S %Y",
1279 localtime_r(&start_time, &tm));
1280 printf("Dynamic statistics stats (starting time: %s):\n", strg);
1281 printf("OpcodeName\t# Requests\t# Aborts\n");
1282 for (i = 0; i < VL_NUMBER_OPCODESX; i++)
1283 printf("%10s\t%10d\t%8d\n", opcode_names[i], stats->requests[i],
1285 printf("\nVldb header stats (version=%d)\n",
1286 ntohl(vital_header->vldbversion));
1287 printf("headersize=%d, allocs=%d, frees=%d, MaxVolid=%X\n",
1288 ntohl(vital_header->headersize), ntohl(vital_header->allocs),
1289 ntohl(vital_header->frees), ntohl(vital_header->MaxVolumeId));
1290 for (i = 0; i < MAXTYPES; i++)
1291 printf("total %s entries=%d\n", volumetype_string(i),
1292 ntohl(vital_header->totalEntries[i]));
1296 GetArgs(char *line, char **args, int *nargs)
1301 while (isspace(*line))
1307 *args++ = line, (*nargs)++;
1308 while (*line && !isspace(*line))
1316 printf("Valid Commands:\n");
1318 printf(" CreateEntry:\n");
1320 ("\tcr <vname> <vtype> <#S> <Saddr1>.<Saddrn> <Spart1>.<Spartn> <Sflag1>.<Sflagn> <Volid1-3> <flag>\n");
1322 printf(" DeleteEntry:\n");
1323 printf("\trm <volid> <voltype>\n");
1325 printf(" ReplaceEntry:\n");
1326 printf("\tre <volid> <voltype> <New vldb entry ala 'cr'>\n");
1328 printf(" UpdateEntry:\n");
1330 ("\tup <volid> <voltype> <vname> <vtype> <#AddSer> [<Saddr1>.<Saddrn> <Spart1>.<Spartn> <Sflag1>.<Sflagn>] <Volid1-3> <flag>\n");
1332 printf(" ListEntry:\n");
1335 printf(" Find duplicate entries of a volume\n");
1336 printf("\tldups\n");
1338 printf(" For each vlentry, find it by name, RW id, BK id, and RO id\n");
1339 printf("\tcheckhash\n");
1342 (" UpdateEntry (update the volname, RW id, BK id, RO id hashes):\n");
1343 printf("\tfixhash\n");
1345 printf(" ListAttributes:\n");
1346 printf("\tla [server] [partition] [volumeid] [flag]\n");
1348 printf(" ListAttributesN2:\n");
1349 printf("\tlan2 [volname] [server] [partition] [volumeid] [flag]\n");
1351 printf(" GetEntryByID:\n");
1352 printf("\tdi <volid> <voltype>\n");
1354 printf(" UpdateEntry (refresh namehash table):\n");
1355 printf("\trmnh <volid> <voltype>\n");
1357 printf(" GetEntryByName:\n");
1358 printf("\tdn <volname> <voltype>\n");
1360 printf(" UpdateEntry (undelete a vol entry):\n");
1361 printf("\tundelete <volid> <voltype>\n");
1363 * printf(" LinkedList\n");
1364 * printf("\t:ln [server] [partition] [volumeid] [flag]\n");
1366 * printf(" LinkedListN\n");
1367 * printf("\t:lnn [server] [partition] [volumeid] [flag]\n");
1369 printf(" GetNewVoumeId:\n");
1370 printf("\tnv <bump-count>\n");
1372 printf(" GetStats:\n");
1375 printf(" ChangeAddr:\n");
1376 printf("\tca <oldmachname> <newmachname>\n");
1379 * printf(" ChangeAddr\n");
1380 * printf("\t:caid <oldaddr> <newaddr>\n");
1382 printf(" GetAddrs:\n");
1385 printf(" GetAddrsU:\n");
1388 printf(" RegisterAddrs:\n");
1389 printf("\tregaddr uuidNumber <ip1 .. ipn>\n");
1391 printf("\tmisc: q, quit, ?, h\n");