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>
40 #include <afs/afsutil.h>
43 #include <rx/rx_globals.h>
46 #include <afs/cellconfig.h>
55 extern int VL_GetAddrsU(), VL_RegisterAddrs();
56 #define VL_NUMBER_OPCODESX 34
57 static char *opcode_names[VL_NUMBER_OPCODESX] = {
102 extern int VL_UpdateEntryByName();
104 #define ALLOCNT 50000
105 struct Vlent *VLa[NVOLS];
106 #define VHash(avol) ((avol)&(NVOLS-1))
107 struct Vlent *VL, *SVL;
109 struct ubik_client *cstruct;
110 struct rx_connection *serverconns[MAXSERVERS];
111 char confdir[AFSDIR_PATH_MAX];
113 extern struct cmd_syndesc *cmd_CreateSyntax();
115 struct Vlent *GetVolume(vol, entry)
116 struct vldbentry *entry;
119 register struct Vlent *vl;
121 if (!vol) return (struct Vlent *)0;
123 for (vl=VLa[i]; vl; vl = vl->next) {
124 if ((vl->rwid == vol && vol != entry->volumeId[0]) ||
125 (vl->roid == vol && vol != entry->volumeId[1]) ||
126 (vl->baid == vol && vol != entry->volumeId[2])) {
130 VL->rwid = entry->volumeId[0];
131 VL->roid = entry->volumeId[1];
132 VL->baid = entry->volumeId[2];
133 strcpy(entry->name, VL->name);
136 if (VLcnt++ > ALLOCNT) { /* XXXX FIX XXXXXXXXX */
137 printf("Too many entries (> %d)\n", ALLOCNT);
141 return (struct Vlent *)0;
144 /* Almost identical's to pr_Initialize in vlserver/pruser.c */
145 afs_int32 vl_Initialize(auth, confDir, server, cellp)
147 char *confDir, *cellp;
149 struct afsconf_dir *tdir;
150 struct ktc_principal sname;
151 struct ktc_token ttoken;
152 afs_int32 scIndex = 0;
153 struct rx_securityClass *sc;
154 struct afsconf_cell info;
159 fprintf(stderr,"vl_Initialize: Could not initialize rx.\n");
163 rx_SetRxDeadTime(50);
165 tdir = afsconf_Open(confDir);
167 fprintf(stderr,"Could not open configuration directory (%s).\n", confDir);
171 if (auth) { /* we don't need tickets for null */
173 code = afsconf_GetLocalCell(tdir, sname.cell, sizeof(sname.cell));
175 fprintf(stderr,"vl_Initialize: Could not get local cell name.\n");
179 strncpy(sname.cell, cellp, sizeof(sname.cell));
180 sname.instance[0] = 0;
181 strcpy(sname.name, "afs");
182 code = ktc_GetToken(&sname,&ttoken, sizeof(ttoken), (char *)0);
184 fprintf(stderr,"vl_Initialize: Could not get afs tokens, running unauthenticated.\n");
187 else if (ttoken.kvno <= 255)
191 "vl_Initialize: funny kvno (%d) in ticket, proceeding\n",
198 sc = (struct rx_securityClass *) rxnull_NewClientSecurityObject();
203 sc = (struct rx_securityClass *) rxkad_NewClientSecurityObject (rxkad_clear,
204 &ttoken.sessionKey, ttoken.kvno, ttoken.ticketLen, ttoken.ticket);
207 code = afsconf_GetCellInfo(tdir,(char *)0, AFSCONF_VLDBSERVICE, &info);
208 if (info.numServers > MAXSERVERS) {
210 "vl_Initialize: info.numServers=%d (> MAXSERVERS=%d)\n",
211 info.numServers, MAXSERVERS);
214 for (i = 0;i<info.numServers;i++)
215 serverconns[i] = rx_NewConnection
216 (info.hostAddr[i].sin_addr.s_addr, info.hostAddr[i].sin_port,
217 USER_SERVICE_ID, sc, scIndex);
219 serverconns[0] = rx_NewConnection(server, htons(AFSCONF_VLDBPORT),
220 USER_SERVICE_ID, sc, scIndex);
222 code = ubik_ClientInit(serverconns, &cstruct);
225 fprintf(stderr,"vl_Initialize: ubik client init failed.\n");
231 /* return host address in network byte order */
232 afs_int32 GetServer(aname)
234 register struct hostent *th;
237 register afs_int32 code;
239 code = sscanf(aname, "%d.%d.%d.%d", &b1, &b2, &b3, &b4);
241 addr = (b1<<24) | (b2<<16) | (b3<<8) | b4;
242 return htonl(addr); /* convert to network order (128 in byte 0) */
244 th = gethostbyname(aname);
246 bcopy(th->h_addr, &addr, sizeof(addr));
252 struct cmd_syndesc *as;
254 register struct cmd_item *ti;
255 register afs_int32 code, server = 0, sawserver=0;
256 afs_int32 i, id, voltype;
257 struct vldbentry entry;
258 char *cmd = 0, *cellp=0;
259 struct VldbUpdateEntry updateentry;
260 struct VldbListByAttributes listbyattributes;
261 int noAuth = 1; /* Default is authenticated connections */
263 if (ti = as->parms[0].items) /* -cellpath <dir> */
264 strcpy(confdir, ti->data);
265 if (as->parms[1].items) /* -server */
266 strcpy(confdir, AFSDIR_SERVER_ETC_DIRPATH);
267 if (as->parms[2].items) /* -noauth */
269 if (ti = as->parms[3].items) { /* -host */
270 server = GetServer(ti->data);
272 printf("server '%s' not found in host table\n", ti->data);
277 if (!sawserver && noAuth && (!(ti = as->parms[4].items))) {
278 printf("Must also specify the -cell' option along with -host for authenticated conns\n");
281 if (ti = as->parms[4].items) { /* -cell */
284 if (code = vl_Initialize(noAuth, confdir, server, cellp)) {
285 printf("Couldn't initialize vldb library (code=%d).\n",code);
289 if (as->parms[5].items) { /* -gstats */
291 vital_vlheader vital_header;
292 code = ubik_Call(VL_GetStats, cstruct, 0, &stats, &vital_header);
293 if (!code) dump_stats(&stats, &vital_header);
299 int nargs, releasetype;
300 bzero(&entry, sizeof(entry));
301 bzero(&updateentry, sizeof(updateentry));
302 bzero(&listbyattributes, sizeof(listbyattributes));
304 if (fgets(line, 499, stdin) == NULL) {
309 register char **argp = args;
310 GetArgs(line, argp, &nargs);
313 if (!strcmp(oper, "cr")) {
314 fill_entry(&entry, argp, nargs);
315 display_entry(&entry, 0);
316 code = ubik_Call(VL_CreateEntry, cstruct,0, &entry);
317 printf("return code is %d\n", code);
318 } else if (!strcmp(oper,"rm")) {
319 sscanf(&(*argp)[0], "%d", &id);
321 sscanf(&(*argp)[0], "%d", &voltype);
322 code = ubik_Call(VL_DeleteEntry, cstruct, 0, id, voltype);
323 printf("return code is %d\n",code);
324 } else if (!strcmp(oper, "re")) {
325 sscanf(&(*argp)[0], "%d", &id);
327 sscanf(&(*argp)[0], "%d", &voltype);
329 sscanf(&(*argp)[0], "%d", &releasetype);
331 fill_entry(&entry, argp, nargs);
332 display_entry(&entry, 0);
333 code = ubik_Call(VL_ReplaceEntry, cstruct, 0, id, voltype, &entry, releasetype);
334 printf("return code is %d\n", code);
335 } else if (!strcmp(oper, "up")) {
336 sscanf(&(*argp)[0], "%d", &id);
338 sscanf(&(*argp)[0], "%d", &voltype);
340 sscanf(&(*argp)[0], "%d", &releasetype);
342 fill_update_entry(&updateentry, argp, nargs);
343 display_update_entry(&updateentry, 0);
344 code = ubik_Call(VL_UpdateEntry, cstruct, 0, id, voltype, &updateentry, releasetype);
345 printf("return code is %d\n", code);
346 } else if (!strcmp(oper,"ls")) {
347 afs_int32 index, count, next_index;
348 for (index = 0; 1; index = next_index) {
349 bzero(&entry, sizeof(entry));
350 code = ubik_Call(VL_ListEntry,cstruct,0,index,&count,&next_index,&entry);
352 printf("VL_ListEntry returned code = %d\n", code);
355 if (!next_index) break;
356 display_entry(&entry, 0);
358 } else if (!strcmp(oper,"ldups")) {
359 afs_int32 index, count, num=0, num1=0, next_index;
362 VL = SVL = (struct Vlent *) malloc(ALLOCNT * sizeof(struct Vlent));
364 printf("Can't allocate memory...\n");
367 printf("Enumerating all entries in vldb...\n");
368 for (index = 0; 1; index = next_index) {
369 bzero(&entry, sizeof(entry));
370 code = ubik_Call(VL_ListEntry,cstruct,0,index,&count,&next_index,&entry);
372 printf("VL_ListEntry returned code = %d\n", code);
375 if (!next_index) break;
377 if (vl1 = GetVolume(entry.volumeId[0], &entry)) {
379 printf("Duplicate entry is found for RW vol %u: [RW %u, RO %u, BA %u, name=%s]\n",
380 entry.volumeId[0], vl1->rwid, vl1->roid, vl1->baid, vl1->name);
382 if (vl1 = GetVolume(entry.volumeId[1], &entry)) {
384 printf("Duplicate entry is found for RO vol %u: [RW %u, RO %u, BA %u, name=%s]\n",
385 entry.volumeId[1], vl1->rwid, vl1->roid, vl1->baid, vl1->name);
387 if (vl1 = GetVolume(entry.volumeId[2], &entry)) {
389 printf("Duplicate entry is found for BA vol %u: [RW %u, RO %u, BA %u, name=%s]\n",
390 entry.volumeId[2], vl1->rwid, vl1->roid, vl1->baid, vl1->name);
392 /*display_entry(&entry, 0);*/
394 printf("(%d vldb entries found - %d duplicates)\n", num, num1);
395 } else if (!strcmp(oper,"checkhash")) {
396 int index, count, num=0, num1=0, num2 = 0, num3=0, num31=0, num4=0, num41=0, next_index;
397 struct vldbentry tentry;
400 VL = SVL = (struct Vlent *) malloc(ALLOCNT * sizeof(struct Vlent));
402 printf("Can't allocate memory...\n");
405 printf("Volumes not found in main hash tables in vldb...\n");
406 for (index = 0; 1; index = next_index) {
407 bzero(&entry, sizeof(entry));
408 code = ubik_Call(VL_ListEntry,cstruct,0,index,&count,&next_index,&entry);
410 printf("VL_ListEntry returned code = %d\n", code);
413 if (!next_index) break;
415 code = ubik_Call(VL_GetEntryByNameO,cstruct,0,entry.name, &tentry);
416 if (code == VL_NOENT) {
418 printf("\tVolume %s %d (not in namehash)\n", entry.name, entry.volumeId[RWVOL]);
420 code = ubik_Call(VL_GetEntryByID,cstruct,0,entry.volumeId[RWVOL], RWVOL, &tentry);
421 if (code == VL_NOENT) {
423 printf("\tVolume %s %d (not in rwid hash)\n", entry.name, entry.volumeId[RWVOL]);
425 if (entry.volumeId[BACKVOL]) {
426 code = ubik_Call(VL_GetEntryByID,cstruct,0,entry.volumeId[BACKVOL], BACKVOL, &tentry);
428 if (code == VL_NOENT) {
430 printf("\tVolume %s %d (not in backup id hash)\n", entry.name, entry.volumeId[BACKVOL]);
433 if (entry.volumeId[ROVOL]) {
434 code = ubik_Call(VL_GetEntryByID,cstruct,0,entry.volumeId[ROVOL], ROVOL, &tentry);
436 if (code == VL_NOENT) {
438 printf("\tVolume %s %d (not in RO id hash)\n", entry.name, entry.volumeId[ROVOL]);
442 printf("\nTotal vldb entries %d\nTotal volumes %d (%d rw, %d backup, %d ro)\n",
443 num, num+num31+num41, num, num31, num41);
444 printf("\n\t%d didn't hash properly by name\n\t%d didn't hash properly by rw volid\n",
446 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",
447 num3, num31, num4, num41);
448 } else if (!strcmp(oper,"fixhash")) {
449 int index, count, num=0, num1=0, num2 = 0, next_index, x=0;
450 struct vldbentry tentry;
453 VL = SVL = (struct Vlent *) malloc(ALLOCNT * sizeof(struct Vlent));
455 printf("Can't allocate memory...\n");
458 printf("Volumes not found in main hash tables in vldb will be fixed...\n");
459 bzero(&updateentry, sizeof(updateentry));
460 for (index = 0; 1; index = next_index) {
461 int n1=0, n2=0, n3=0, n4=0;
462 bzero(&entry, sizeof(entry));
463 code = ubik_Call(VL_ListEntry,cstruct,0,index,&count,&next_index,&entry);
465 printf("VL_ListEntry returned code = %d\n", code);
468 if (!next_index) break;
470 code = ubik_Call(VL_GetEntryByNameO,cstruct,0,entry.name, &tentry);
471 if (code == VL_NOENT) {
474 updateentry.Mask = VLUPDATE_VOLNAMEHASH;
475 printf("\tVolume %s %d (not in namehash)\n", entry.name, entry.volumeId[RWVOL]);
476 code = ubik_Call(VL_UpdateEntry, cstruct, 0, entry.volumeId[RWVOL], -1, &updateentry, 0);
479 printf("\tFailed to update volume %s (err=%d)\n", entry.name, code);
482 code = ubik_Call(VL_GetEntryByID,cstruct,0,entry.volumeId[RWVOL], RWVOL, &tentry);
483 if (code == VL_NOENT) {
486 updateentry.Mask = VLUPDATE_RWID;
487 updateentry.spares3 = entry.volumeId[RWVOL];
488 printf("\tVolume %s %d (not in rw id hash)\n", entry.name, entry.volumeId[RWVOL]);
489 code = ubik_Call(VL_UpdateEntryByName, cstruct, 0, entry.name, &updateentry, 0);
491 printf("\tFailed to update volume %s (err=%d)\n", entry.name, code);
496 if (entry.volumeId[BACKVOL] && !n2) {
497 code = ubik_Call(VL_GetEntryByID,cstruct,0,entry.volumeId[BACKVOL], BACKVOL, &tentry);
498 if (code == VL_NOENT) {
501 updateentry.Mask = VLUPDATE_BACKUPID;
502 updateentry.BackupId = entry.volumeId[BACKVOL];
503 printf("\tVolume %s %d (not in backup id hash)\n", entry.name, entry.volumeId[BACKVOL]);
504 code = ubik_Call(VL_UpdateEntry, cstruct, 0, entry.volumeId[RWVOL], -1, &updateentry, 0);
506 printf("\tFailed to update volume %s (err=%d)\n", entry.name, code);
511 if (entry.volumeId[ROVOL && !n2]) {
512 code = ubik_Call(VL_GetEntryByID,cstruct,0,entry.volumeId[ROVOL], ROVOL, &tentry);
513 if (code == VL_NOENT) {
516 updateentry.Mask = VLUPDATE_READONLYID;
517 updateentry.ReadOnlyId = entry.volumeId[ROVOL];
518 printf("\tVolume %s %d (not in RO id hash)\n", entry.name, entry.volumeId[ROVOL]);
519 code = ubik_Call(VL_UpdateEntry, cstruct, 0, entry.volumeId[RWVOL], -1, &updateentry, 0);
521 printf("\tFailed to update volume %s (err=%d)\n", entry.name, code);
527 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",
529 } else if (!strcmp(oper, "la")) {
532 struct vldbentry *entry;
534 bzero(&entries,sizeof(entries));
535 fill_listattributes_entry(&listbyattributes, argp, nargs);
536 display_listattributes_entry(&listbyattributes, 0);
537 code = ubik_Call(VL_ListAttributes, cstruct, 0, &listbyattributes, &nentries, &entries);
539 printf("VL_ListAttributes returned code = %d\n", code);
542 entry = (struct vldbentry *)entries.bulkentries_val;
543 for (i=0; i < nentries; i++, entry++)
544 display_entry(entry, 0);
545 if (entries.bulkentries_val) free((char *)entries.bulkentries_val);
546 } else if (!strcmp(oper, "lan2")) {
547 int nentries, i, si, nsi, t=0;
548 nbulkentries entries;
549 struct nvldbentry *entry;
552 /* The volume name to search for (supports wildcarding) */
554 strcpy(name,argp[0]);
560 fill_listattributes_entry(&listbyattributes, argp, nargs);
561 display_listattributes_entry(&listbyattributes, 0);
562 printf("Wildcard VolName: '%s'\n", name);
564 for (si=0; si!=-1; si=nsi) {
566 bzero(&entries,sizeof(entries));
567 code = ubik_Call(VL_ListAttributesN2, cstruct, 0,
568 &listbyattributes, name, si,
569 &nentries, &entries, &nsi);
571 printf("VL_ListAttributesN2 returned code = %d\n", code);
576 entry = (struct nvldbentry *)entries.nbulkentries_val;
577 for (i=0; i < nentries; i++, entry++)
578 display_entryN(entry, 0);
579 if (entries.nbulkentries_val) free((char *)entries.nbulkentries_val);
581 printf("--- %d volumes ---\n", t);
582 } else if (!strcmp(oper, "ln")) {
584 vldb_list linkedvldbs;
585 vldblist vllist, vllist1;
587 fill_listattributes_entry(&listbyattributes, argp, nargs);
588 display_listattributes_entry(&listbyattributes, 0);
589 bzero(&linkedvldbs, sizeof(vldb_list));
590 code = ubik_Call(VL_LinkedList, cstruct, 0, &listbyattributes,
591 &netries, &linkedvldbs);
593 printf("VL_LinkedList returned code = %d\n", code);
596 printf("Found %d entr%s\n", netries, (netries==1?"y":"ies"));
597 for (vllist = linkedvldbs.node; vllist; vllist = vllist1) {
598 vllist1 = vllist->next_vldb;
599 display_entry(&vllist->VldbEntry, 0);
600 free((char *)vllist);
602 } else if (!strcmp(oper, "lnn")) {
604 nvldb_list linkedvldbs;
605 nvldblist vllist, vllist1;
607 fill_listattributes_entry(&listbyattributes, argp, nargs);
608 display_listattributes_entry(&listbyattributes, 0);
609 bzero(&linkedvldbs, sizeof(vldb_list));
610 code = ubik_Call(VL_LinkedListN, cstruct, 0, &listbyattributes,
611 &netries, &linkedvldbs);
613 printf("VL_LinkedList returned code = %d\n", code);
616 printf("Found %d entr%s\n", netries, (netries==1?"y":"ies"));
617 for (vllist = linkedvldbs.node; vllist; vllist = vllist1) {
618 vllist1 = vllist->next_vldb;
619 display_entry(&vllist->VldbEntry, 0);
620 free((char *)vllist);
622 } else if (!strcmp(oper,"di")) {
623 sscanf(&(*argp)[0], "%d", &id);
625 sscanf(&(*argp)[0], "%d", &voltype);
626 code = ubik_Call(VL_GetEntryByID, cstruct, 0, id, voltype, &entry);
627 display_entry(&entry, code);
628 printf("return code is %d.\n",code);
629 } else if (!strcmp(oper,"rmnh")) {
630 sscanf(&(*argp)[0], "%d", &id);
632 sscanf(&(*argp)[0], "%d", &voltype);
633 code = ubik_Call(VL_GetEntryByID, cstruct, 0, id, voltype, &entry);
634 display_entry(&entry, code);
635 bzero(&updateentry, sizeof(updateentry));
636 updateentry.Mask = VLUPDATE_VOLNAMEHASH;
637 printf("\tRehashing namehash table for %s (%d)\n", entry.name, entry.volumeId[RWVOL]);
638 code = ubik_Call(VL_UpdateEntry, cstruct, 0, entry.volumeId[RWVOL], -1, &updateentry, 0);
640 printf("\tFailed to update volume %s (err=%d)\n", entry.name, code);
642 printf("return code is %d.\n",code);
643 } else if (!strcmp(oper,"undelete")) {
644 afs_int32 index, count, next_index;
646 bzero(&updateentry, sizeof(updateentry));
647 sscanf(&(*argp)[0], "%d", &id);
649 sscanf(&(*argp)[0], "%d", &voltype);
650 if (voltype < 0 && voltype > 2) {
651 printf("Illegal voltype; must be 0, 1 or 2\n");
654 printf("Searching vldb for volume %d...\n", id);
655 for (index = 0; 1; index = next_index) {
656 bzero(&entry, sizeof(entry));
657 code = ubik_Call(VL_ListEntry,cstruct,0,index,&count,&next_index,&entry);
659 printf("VL_ListEntry returned code = %d\n", code);
662 if (!next_index) break;
663 if (entry.volumeId[voltype] == id) {
664 printf("\nThe current contents of the vldb for %d:\n", id);
665 display_entry(&entry, 0);
667 if (entry.flags & VLDELETED) {
668 updateentry.Mask = VLUPDATE_FLAGS;
669 updateentry.flags = entry.flags;
670 updateentry.flags &= ~VLDELETED;
671 printf("\tUndeleting vldb entry for vol %d (%s)\n", id, entry.name);
672 code = ubik_Call(VL_UpdateEntry, cstruct, 0, id, -1, &updateentry, 0);
674 printf("\tFailed to update volume %s (err=%d)\n", entry.name, code);
677 printf("Entry not deleted; ignored\n");
682 } else if (!strcmp(oper,"dn")) {
684 code = ubik_Call(VL_GetEntryByNameO,cstruct,0,vname, &entry);
685 display_entry(&entry, code);
686 printf("return code is %d.\n",code);
687 } else if (!strcmp(oper, "nv")) {
689 sscanf(&(*argp)[0], "%d", &id);
690 code = ubik_Call(VL_GetNewVolumeId, cstruct, 0, id, &newvolid);
691 if (!code) printf("Current Max volid is (in hex):%X\n", newvolid);
692 printf("return code is %d\n", code);
693 } else if (!strcmp(oper, "gs")) {
695 vital_vlheader vital_header;
696 code = ubik_Call(VL_GetStats, cstruct, 0, &stats, &vital_header);
697 if (!code) dump_stats(&stats, &vital_header);
698 printf("return code is %d.\n", code);
699 } else if (!strcmp(oper, "ga")) {
703 struct vldbentry *entry;
704 struct VLCallBack vlcb;
706 addrs.bulkaddrs_val = 0;
707 addrs.bulkaddrs_len = 0;
708 code = ubik_Call(VL_GetAddrs, cstruct, 0, 0 /*Handle*/, 0 /*spare2*/, &vlcb,
711 printf("VL_GetAddrs returned code = %d\n", code);
714 addrp = addrs.bulkaddrs_val;
715 for (i=0; i < nentries; i++, addrp++) {
716 if ((*addrp & 0xff000000) == 0xff000000)
717 printf ("[0x%x %u] (special multi-homed entry)\n", *addrp, *addrp);
719 printf ("[0x%x %u] %s\n", *addrp, *addrp, hostutil_GetNameByINet(ntohl(*addrp)));
721 free((char *)addrs.bulkaddrs_val);
722 } else if (!strcmp(oper, "gau")) {
726 struct VLCallBack vlcb;
728 addrs.bulkaddrs_val = 0;
729 addrs.bulkaddrs_len = 0;
730 code = ubik_Call(VL_GetAddrs, cstruct, 0, 0 /*Handle*/, 0 /*spare2*/, &vlcb,
733 printf("VL_GetAddrs returned code = %d\n", code);
736 addrp = addrs.bulkaddrs_val;
737 for (i=0; i < nentries; i++, addrp++) {
738 if ((*addrp & 0xff000000) == 0xff000000) {
739 int mhnentries, unique;
740 struct in_addr hostAddr;
743 ListAddrByAttributes attrs;
746 printf ("[0x%x %u] (special multi-homed entry)\n", *addrp, *addrp);
747 attrs.Mask = VLADDR_INDEX;
748 mhaddrs.bulkaddrs_val = 0;
749 mhaddrs.bulkaddrs_len = 0;
750 attrs.index = *addrp & 0x00ffffff;
752 code = ubik_Call(VL_GetAddrsU, cstruct, 0, &attrs, &uuid, &unique, &mhnentries, &mhaddrs);
754 printf("VL_GetAddrsU returned code = %d\n", code);
757 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,
758 uuid.time_mid, uuid.time_hi_and_version, uuid.clock_seq_hi_and_reserved, uuid.clock_seq_low,
759 uuid.node[0], uuid.node[1], uuid.node[2], uuid.node[3], uuid.node[4], uuid.node[5], unique);
760 mhaddrp = mhaddrs.bulkaddrs_val;
761 for (j=0; j<mhnentries; j++) {
762 mhaddrp[j] = ntohl(mhaddrp[j]);
763 hostAddr.s_addr = mhaddrp[j];
764 printf ("\t%s (%s)\n", inet_ntoa(hostAddr), hostutil_GetNameByINet(mhaddrp[j]));
766 if (mhaddrs.bulkaddrs_val) free((char *)mhaddrs.bulkaddrs_val);
768 printf ("[0x%x %u] %s\n", *addrp, *addrp, hostutil_GetNameByINet(ntohl(*addrp)));
771 free((char *)addrs.bulkaddrs_val);
772 } else if (!strcmp(oper, "mhc")) {
773 afs_int32 serveraddrs[MAXSERVERID+1][VL_MAXIPADDRS_PERMH];
774 afs_int32 serveraddrtype[MAXSERVERID+1];
775 int nentries1, nentries2, i, j, x, y, unique, found;
776 afs_uint32 *addrp1, *addrp2;
777 bulkaddrs addrs1, addrs2;
778 struct vldbentry *entry;
779 struct VLCallBack vlcb;
780 ListAddrByAttributes attrs;
782 afs_int32 base, index;
784 for (i=0; i<MAXSERVERID+1; i++) {
785 serveraddrtype[i] = 0;
786 for (j=0; j<VL_MAXIPADDRS_PERMH; j++)
787 serveraddrs[i][j] = 0;
790 /* Collect a list of all registered IP addresses */
791 addrs1.bulkaddrs_val = 0;
792 addrs1.bulkaddrs_len = 0;
793 code = ubik_Call(VL_GetAddrs, cstruct, 0, 0,
794 0, &vlcb, &nentries1, &addrs1);
796 printf("VL_GetAddrs returned code = %d\n", code);
799 addrp1 = addrs1.bulkaddrs_val;
800 for (i=0; i < nentries1; i++, addrp1++) {
801 if ((*addrp1 & 0xff000000) != 0xff000000) {
802 serveraddrs[i][0] = ntohl(*addrp1);
803 serveraddrtype[i] = 1;
805 /* It's multihomed. Get all of its addresses */
806 serveraddrtype[i] = 2;
807 base = (*addrp1 >> 16) & 0xff;
808 index = *addrp1 & 0xffff;
810 addrs2.bulkaddrs_val = 0;
811 addrs2.bulkaddrs_len = 0;
812 attrs.Mask = VLADDR_INDEX;
813 attrs.index = (base * VL_MHSRV_PERBLK) + index;
814 code = ubik_Call(VL_GetAddrsU, cstruct, 0, &attrs,
815 &uuid, &unique, &nentries2, &addrs2);
817 printf("VL_GetAddrsU returned code = %d\n", code);
821 addrp2 = addrs2.bulkaddrs_val;
822 for (j=0; j<nentries2; j++) {
823 serveraddrs[i][j] = ntohl(addrp2[j]);
825 free((char *)addrs2.bulkaddrs_val);
829 if (serveraddrtype[i] == 1) {
830 printf ("%u\n", serveraddrs[i][0]);
833 for (j=0; j<VL_MAXIPADDRS_PERMH; j++)
834 if (serveraddrs[i][j])
835 printf(" %u", serveraddrs[i][j]);
840 free((char *)addrs1.bulkaddrs_val);
842 /* Look for any duplicates */
843 for (i=0; i<MAXSERVERID+1; i++) {
844 if (!serveraddrtype[i]) continue;
845 for (j=0; j<VL_MAXIPADDRS_PERMH; j++) {
846 if (!serveraddrs[i][j]) continue;
849 for (x=i+1; x<MAXSERVERID+1; x++) {
850 if (!serveraddrtype[x]) continue;
851 for (y=0; y<VL_MAXIPADDRS_PERMH; y++) {
852 if (!serveraddrs[x][y]) continue;
853 if (serveraddrs[i][j] == serveraddrs[x][y]) {
854 serveraddrs[x][y] = 0;
860 printf("Found %d entries of IP address %u (0x%x)\n",
862 serveraddrs[i][j], serveraddrs[i][j]);
867 /*----------------------------------------*/
869 } else if (!strcmp(oper, "regaddr")) {
871 afs_uint32 *addrp, tad;
873 struct vldbentry *entry;
876 bzero(&uuid,sizeof(uuid));
877 sscanf(&(*argp)[0], "%d", &i);
879 bcopy(&i, uuid.node, sizeof(i));
881 if (nargs < 0 || nargs > 16) {
882 printf("Illegal # entries = %d\n", nargs);
885 addrp = (afs_uint32 *) malloc(20 * 4);
886 addrs.bulkaddrs_val = addrp;
887 addrs.bulkaddrs_len = nargs;
889 sscanf(&(*argp)[0], "%d", &tad);
893 code = ubik_Call(VL_RegisterAddrs, cstruct, 0, &uuid, 0 /*spare*/, &addrs);
895 printf("VL_RegisterAddrs returned code = %d\n", code);
898 } else if (!strcmp(oper,"ca")) {
899 extern struct hostent *hostutil_GetHostByName();
900 struct hostent *h1, *h2;
902 unsigned char n1[80], n2[80];
904 printf("changing %s", *argp);
905 h1 = hostutil_GetHostByName(&(*argp)[0]);
907 printf("cmdebug: can't resolve address for host %s");
910 bcopy((afs_int32 *)h1->h_addr, &a1, sizeof(afs_uint32));
913 printf(" to %s\n", *argp);
914 h2 = hostutil_GetHostByName(&(*argp)[0]);
916 printf("cmdebug: can't resolve address for host %s", *argp);
919 bcopy((afs_int32 *)h2->h_addr, &a2, sizeof(afs_uint32));
921 printf("changing 0x%x to 0x%x\n", ntohl(a1), ntohl(a2));
922 code = ubik_Call(VL_ChangeAddr, cstruct, 0, ntohl(a1), ntohl(a2));
924 printf("VL_ChangeAddr returned code = %d\n", code);
927 } else if (!strcmp(oper,"caid")) {
929 unsigned char n1[80], n2[80];
931 sscanf(&(*argp)[0], "%d", &a1);
932 printf("changing %d (0x%x)", a1, a1);
934 sscanf(&(*argp)[0], "%d", &a2);
935 printf(" to %d (0x%x)\n", a2, a2);
936 code = ubik_Call(VL_ChangeAddr, cstruct, 0, a1, a2);
938 printf("VL_ChangeAddr returned code = %d\n", code);
941 } else if ((!strcmp(oper,"?")) || !strcmp(oper,"h"))
943 else if ((!strcmp(oper,"q")) || !strcmp(oper, "quit"))
946 printf("Unknown oper!\n");
953 #include "AFS_component_version_number.c"
959 register struct cmd_syndesc *ts;
962 strcpy(confdir, AFSDIR_CLIENT_ETC_DIRPATH);
963 ts = cmd_CreateSyntax("initcmd", handleit, 0, "initialize the program");
964 cmd_AddParm(ts, "-cellpath", CMD_LIST, CMD_OPTIONAL, "Cell configuration directory");
965 cmd_AddParm(ts, "-server", CMD_LIST, CMD_OPTIONAL, "Use the cell config in /usr/afs/etc (default /usr/vice/etc)");
966 cmd_AddParm(ts, "-noauth", CMD_FLAG, CMD_OPTIONAL, "Run it without authentication");
967 cmd_AddParm(ts, "-host", CMD_LIST, CMD_OPTIONAL, "vldb server to talk to");
968 cmd_AddParm(ts, "-cell", CMD_LIST, CMD_OPTIONAL, "cellname '-host' belongs to (required for auth conns)");
969 cmd_AddParm(ts, "-getstats", CMD_FLAG, CMD_OPTIONAL, "print vldb statistics (non interactive)");
970 code = cmd_Dispatch(argc, argv);
975 fill_entry(entry, argp, nargs)
976 struct vldbentry *entry;
985 sscanf(&(*argp)[0], "%d", &entry->spares3);
987 sscanf(&(*argp)[0], "%d", &entry->nServers);
988 strcpy(entry->name, name);
989 for (i=0; i < entry->nServers; i++) {
991 sscanf(&(*argp)[0], "%u", &entry->serverNumber[i]);
993 for (i=0; i < entry->nServers; i++) {
995 sscanf(&(*argp)[0], "%d", &entry->serverPartition[i]);
997 for (i=0; i < entry->nServers; i++) {
999 sscanf(&(*argp)[0], "%d", &entry->serverFlags[i]);
1001 for (i=0; i < MAXTYPES; i++) {
1003 sscanf(&(*argp)[0], "%d", &entry->volumeId[i]);
1006 sscanf(&(*argp)[0], "%d", &entry->flags);
1008 sscanf(&(*argp)[0], "%d", &entry->cloneId);
1012 fill_update_entry(entry, argp, nargs)
1013 struct VldbUpdateEntry *entry;
1022 if (strcmp(name, "null")) {
1023 strcpy(entry->name, name);
1024 entry->Mask |= VLUPDATE_VOLUMENAME;
1027 sscanf(&(*argp)[0], "%d", &entry->flags);
1028 if (entry->flags != -1)
1029 entry->Mask |= VLUPDATE_FLAGS;
1031 sscanf(&(*argp)[0], "%d", &entry->cloneId);
1032 if (entry->flags != -1)
1033 entry->Mask |= VLUPDATE_CLONEID;
1035 sscanf(&(*argp)[0], "%d", &entry->ReadOnlyId);
1036 if (entry->ReadOnlyId != -1)
1037 entry->Mask |= VLUPDATE_READONLYID;
1039 sscanf(&(*argp)[0], "%d", &entry->BackupId);
1040 if (entry->BackupId != -1)
1041 entry->Mask |= VLUPDATE_BACKUPID;
1043 sscanf(&(*argp)[0], "%d", &entry->nModifiedRepsites);
1044 if (entry->nModifiedRepsites != -1)
1045 entry->Mask |= VLUPDATE_REPSITES;
1046 for (i=0; i < entry->nModifiedRepsites; i++) {
1048 sscanf(&(*argp)[0], "%x", &Mask);
1050 sscanf(&(*argp)[0], "%u", &entry->RepsitesTargetServer[i]);
1052 sscanf(&(*argp)[0], "%d", &entry->RepsitesTargetPart[i]);
1053 if (Mask & VLUPDATE_REPS_DELETE)
1054 entry->RepsitesMask[i] |= VLUPDATE_REPS_DELETE;
1055 if (Mask & VLUPDATE_REPS_MODSERV) {
1057 sscanf(&(*argp)[0], "%u", &entry->RepsitesNewServer[i]);
1058 entry->RepsitesMask[i] |= VLUPDATE_REPS_MODSERV;
1059 } else if (Mask & VLUPDATE_REPS_MODPART) {
1061 sscanf(&(*argp)[0], "%d", &entry->RepsitesNewPart[i]);
1062 entry->RepsitesMask[i] |= VLUPDATE_REPS_MODPART;
1063 } else if (Mask & VLUPDATE_REPS_MODFLAG) {
1065 sscanf(&(*argp)[0], "%d", &entry->RepsitesNewFlags[i]);
1066 entry->RepsitesMask[i] |= VLUPDATE_REPS_MODFLAG;
1067 } else if (Mask & VLUPDATE_REPS_ADD) {
1069 sscanf(&(*argp)[0], "%u", &entry->RepsitesNewServer[i]);
1071 sscanf(&(*argp)[0], "%d", &entry->RepsitesNewPart[i]);
1073 sscanf(&(*argp)[0], "%d", &entry->RepsitesNewFlags[i]);
1074 entry->RepsitesMask[i] |= VLUPDATE_REPS_ADD;
1080 fill_listattributes_entry(entry, argp, nargs)
1081 struct VldbListByAttributes *entry;
1087 if (nargs <= 0) return;
1088 entry->server = ntohl(GetServer(argp[0]));
1089 sscanf(&(*argp)[0], "%d", &entry->server);
1090 if (entry->server != 0)
1091 entry->Mask |= VLLIST_SERVER;
1094 if (nargs <= 0) return;
1095 sscanf(&(*argp)[0], "%d", &entry->partition);
1096 if (entry->partition != -1)
1097 entry->Mask |= VLLIST_PARTITION;
1100 if (nargs <= 0) return;
1101 sscanf(&(*argp)[0], "%d", &entry->volumeid);
1102 if (entry->volumeid != -1)
1103 entry->Mask |= VLLIST_VOLUMEID;
1106 if (nargs <= 0) return;
1107 sscanf(&(*argp)[0], "%d", &entry->flag);
1108 if (entry->flag != -1)
1109 entry->Mask |= VLLIST_FLAG;
1112 display_listattributes_entry(entry, error)
1113 struct VldbListByAttributes *entry;
1117 printf("\nList entry values (Mask=%x)\n", entry->Mask);
1118 if (entry->Mask & VLLIST_SERVER)
1119 printf("\tServer: %d.%d.%d.%d\n",
1120 (entry->server>>24) & 0xff, (entry->server>>16) & 0xff,
1121 (entry->server>> 8) & 0xff, (entry->server) & 0xff);
1122 if (entry->Mask & VLLIST_PARTITION)
1123 printf("\tPartition: %d\n", entry->partition);
1124 if (entry->Mask & VLLIST_VOLUMEID)
1125 printf("\tVolumeId: %u\n", entry->volumeid);
1126 if (entry->Mask & VLLIST_FLAG)
1127 printf("\tFlag: %x\n", entry->flag);
1131 #define volumetype_string(type) (type == RWVOL? "read/write":type == ROVOL? "readonly":type == BACKVOL? "backup":"unknown")
1133 display_entry(entry, error)
1134 struct vldbentry *entry;
1140 printf("\nEntry for volume name: %s, volid=%u (flags=%X) are:\n", entry->name, entry->volumeId[RWVOL], entry->flags);
1141 printf("ParentID=%u, ReadOnlyID=%u, backupID=%u, CloneId=%u ", entry->volumeId[0], entry->volumeId[1], entry->volumeId[2], entry->cloneId);
1142 printf("nServers=%d\n", entry->nServers);
1143 printf("ServerNumber\tServerPart\tserverFlag\n");
1144 for (i=0; i < entry->nServers; i++)
1145 printf("%12u\t%10d\t%10x\n", entry->serverNumber[i], entry->serverPartition[i], entry->serverFlags[i]);
1148 display_entryN(entry, error)
1149 struct nvldbentry *entry;
1155 printf("\nEntry for volume name: %s, volid=%u (flags=%X) are:\n",
1156 entry->name, entry->volumeId[RWVOL], entry->flags);
1157 printf("ParentID=%u, ReadOnlyID=%u, backupID=%u, CloneId=%u ",
1158 entry->volumeId[0], entry->volumeId[1],
1159 entry->volumeId[2], entry->cloneId);
1160 printf("nServers=%d\n", entry->nServers);
1161 printf("ServerNumber\tServerPart\tserverFlag\n");
1162 ei = entry->matchindex & 0xffff;
1163 et = (entry->matchindex >> 16) & 0xffff;
1164 for (i=0; i < entry->nServers; i++) {
1165 printf("%12u\t%10d\t%10x",
1166 entry->serverNumber[i], entry->serverPartition[i],
1167 entry->serverFlags[i]);
1169 printf(" <--- %s", (et==4)?"RW":((et==8)?"BK":"RO"));
1176 display_update_entry(entry, error)
1177 struct VldbUpdateEntry *entry;
1183 printf("\nUpdate entry values (Mask=%x)\n", entry->Mask);
1184 if (entry->Mask & VLUPDATE_VOLUMENAME)
1185 printf("\tNew name: %s\n", entry->name);
1186 if (entry->Mask & VLUPDATE_FLAGS)
1187 printf("\tNew flags: %X\n", entry->flags);
1188 if (entry->Mask & VLUPDATE_CLONEID)
1189 printf("\tNew CloneId: %X\n", entry->cloneId);
1190 if (entry->Mask & VLUPDATE_READONLYID)
1191 printf("\tNew RO id: %D\n", entry->ReadOnlyId);
1192 if (entry->Mask & VLUPDATE_BACKUPID)
1193 printf("\tNew BACKUP id: %D\n", entry->BackupId);
1194 if (entry->Mask & VLUPDATE_REPSITES) {
1195 printf("\tRepsites info:\n");
1196 printf("\tFlag\tTServer\tTPart\tNServer\tNPart\tNFlag\n");
1197 for (i=0; i < entry->nModifiedRepsites; i++) {
1198 printf("\t%4x\t%7U\t%5d", entry->RepsitesMask[i], entry->RepsitesTargetServer[i], entry->RepsitesTargetPart[i]);
1199 if ((entry->RepsitesMask[i] & VLUPDATE_REPS_ADD) || (entry->RepsitesMask[i] & VLUPDATE_REPS_MODSERV))
1200 printf("\t%7U", entry->RepsitesNewServer[i]);
1202 printf("\t-------");
1203 if ((entry->RepsitesMask[i] & VLUPDATE_REPS_ADD) || (entry->RepsitesMask[i] & VLUPDATE_REPS_MODPART))
1204 printf("\t%5d", entry->RepsitesNewPart[i]);
1207 if ((entry->RepsitesMask[i] & VLUPDATE_REPS_ADD) || (entry->RepsitesMask[i] & VLUPDATE_REPS_MODFLAG))
1208 printf("\t%5x\n", entry->RepsitesNewFlags[i]);
1210 printf("\t-----\n");
1215 dump_stats(stats, vital_header)
1217 vital_vlheader *vital_header;
1221 strncpy(strg, ctime((time_t *)&stats->start_time), sizeof(strg));
1222 strg[strlen(strg)-1] = 0;
1223 printf("Dynamic statistics stats (starting time: %s):\n", strg);
1224 printf("OpcodeName\t# Requests\t# Aborts\n");
1225 for (i=0; i < VL_NUMBER_OPCODESX; i++)
1226 printf("%10s\t%10d\t%8d\n", opcode_names[i], stats->requests[i], stats->aborts[i]);
1227 printf("\nVldb header stats (version=%d)\n", ntohl(vital_header->vldbversion));
1228 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));
1229 for (i=0; i < MAXTYPES; i++)
1230 printf("total %s entries=%d\n", volumetype_string(i), ntohl(vital_header->totalEntries[i]));
1233 GetArgs(line,args, nargs)
1234 register char *line;
1235 register char **args;
1236 register int *nargs;
1240 register char *last = line;
1241 while (*line == ' ')
1247 *args++ = line, (*nargs)++;
1248 while (*line && *line != ' ')
1255 printf("Valid Commands:\n");
1257 printf(" CreateEntry:\n");
1258 printf("\tcr <vname> <vtype> <#S> <Saddr1>.<Saddrn> <Spart1>.<Spartn> <Sflag1>.<Sflagn> <Volid1-3> <flag>\n");
1260 printf(" DeleteEntry:\n");
1261 printf("\trm <volid> <voltype>\n");
1263 printf(" ReplaceEntry:\n");
1264 printf("\tre <volid> <voltype> <New vldb entry ala 'cr'>\n");
1266 printf(" UpdateEntry:\n");
1267 printf("\tup <volid> <voltype> <vname> <vtype> <#AddSer> [<Saddr1>.<Saddrn> <Spart1>.<Spartn> <Sflag1>.<Sflagn>] <Volid1-3> <flag>\n");
1269 printf(" ListEntry:\n");
1272 printf(" Find duplicate entries of a volume\n");
1273 printf("\tldups\n");
1275 printf(" For each vlentry, find it by name, RW id, BK id, and RO id\n");
1276 printf("\tcheckhash\n");
1278 printf(" UpdateEntry (update the volname, RW id, BK id, RO id hashes):\n");
1279 printf("\tfixhash\n");
1281 printf(" ListAttributes:\n");
1282 printf("\tla [server] [partition] [volumeid] [flag]\n");
1284 printf(" ListAttributesN2:\n");
1285 printf("\tlan2 [volname] [server] [partition] [volumeid] [flag]\n");
1287 printf(" GetEntryByID:\n");
1288 printf("\tdi <volid> <voltype>\n");
1290 printf(" UpdateEntry (refresh namehash table):\n");
1291 printf("\trmnh <volid> <voltype>\n");
1293 printf(" GetEntryByName:\n");
1294 printf("\tdn <volname> <voltype>\n");
1296 printf(" UpdateEntry (undelete a vol entry):\n");
1297 printf("\tundelete <volid> <voltype>\n");
1299 * printf(" LinkedList\n");
1300 * printf("\t:ln [server] [partition] [volumeid] [flag]\n");
1302 * printf(" LinkedListN\n");
1303 * printf("\t:lnn [server] [partition] [volumeid] [flag]\n");
1305 printf(" GetNewVoumeId:\n");
1306 printf("\tnv <bump-count>\n");
1308 printf(" GetStats:\n");
1311 printf(" ChangeAddr:\n");
1312 printf("\tca <oldmachname> <newmachname>\n");
1315 * printf(" ChangeAddr\n");
1316 * printf("\t:caid <oldaddr> <newaddr>\n");
1318 printf(" GetAddrs:\n");
1321 printf(" GetAddrsU:\n");
1324 printf(" RegisterAddrs:\n");
1325 printf("\tregaddr uuidNumber <ip1 .. ipn>\n");
1327 printf("\tmisc: q, quit, ?, h\n");