time-t-casting-fixes-20060404
[openafs.git] / src / vlserver / vlclient.c
1 /*
2  * Copyright 2000, International Business Machines Corporation and others.
3  * All Rights Reserved.
4  * 
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
8  */
9
10 #include <afsconfig.h>
11 #include <afs/param.h>
12
13 RCSID
14     ("$Header$");
15
16 #include <afs/stds.h>
17 #include <sys/types.h>
18 #ifdef HAVE_TIME_H
19 #include <time.h>
20 #endif
21 #ifdef HAVE_FCNTL_H
22 #include <fcntl.h>
23 #endif
24 #ifdef AFS_NT40_ENV
25 #include <winsock2.h>
26 #include <WINNT/afsevent.h>
27 #endif
28 #ifdef HAVE_SYS_TIME_H
29 #include <sys/time.h>
30 #endif
31 #ifdef HAVE_SYS_FILE_H
32 #include <sys/file.h>
33 #endif
34 #ifdef HAVE_NETDB_H
35 #include <netdb.h>
36 #endif
37 #ifdef HAVE_NETINET_IN_H
38 #include <netinet/in.h>
39 #endif
40 #include <stdio.h>
41
42 #ifdef HAVE_STRING_H
43 #include <string.h>
44 #else
45 #ifdef HAVE_STRINGS_H
46 #include <strings.h>
47 #endif
48 #endif
49
50 #include <afs/afsutil.h>
51 #include <rx/xdr.h>
52 #include <rx/rx.h>
53 #include <rx/rx_globals.h>
54 #include <rx/rxkad.h>
55 #include <afs/auth.h>
56 #include <afs/cellconfig.h>
57 #include <afs/keys.h>
58 #include <afs/cmd.h>
59 #include <lock.h>
60 #include <ubik.h>
61 #include "vlserver.h"
62 #include "vlclient.h"
63
64 void fill_listattributes_entry();
65 void display_listattributes_entry();
66 void display_entry();
67 void display_entryN();
68 void display_update_entry();
69 void dump_stats();
70 void GetArgs();
71 void print_usage();
72 void fill_entry();
73 void fill_update_entry();
74
75 #define VL_NUMBER_OPCODESX      34
76 static char *opcode_names[VL_NUMBER_OPCODESX] = {
77     "CreateEntry",
78     "DeleteEntry",
79     "GetEntryByID",
80     "GetEntryByName",
81     "GetNewVolumeId",
82     "ReplaceEntry",
83     "UpdateEntry",
84     "SetLock",
85     "ReleaseLock",
86     "ListEntry",
87     "ListAttributes",
88     "LinkedList",
89     "GetStats",
90     "Probe",
91     "GetAddrs",
92     "ChangeAddr",
93     "CreateEntryN",
94     "GetEntryByIDN",
95     "GetEntryByNameN",
96     "ReplaceEntryN",
97     "ListEntryN",
98     "ListAttributesN",
99     "LinkedListN",
100     "UpdateeEntryByName",
101     "CreateEntryU",
102     "GetEntryByIDU",
103     "GetEntryByNameU",
104     "ReplaceEntryU",
105     "ListEntryU",
106     "ListAttributesU",
107     "LinkedListU",
108     "RegisterAddr",
109     "GetAddrsU",
110     "ListAttributesN2"
111 };
112
113 struct Vlent {
114     struct Vlent *next;
115     afs_int32 rwid;
116     afs_int32 roid;
117     afs_int32 baid;
118     char name[64];
119 };
120
121 #define NVOLS   1000
122 #define ALLOCNT 50000
123 struct Vlent *VLa[NVOLS];
124 #define VHash(avol)     ((avol)&(NVOLS-1))
125 struct Vlent *VL, *SVL;
126 int VLcnt = 0;
127 struct ubik_client *cstruct;
128 struct rx_connection *serverconns[MAXSERVERS];
129 char confdir[AFSDIR_PATH_MAX];
130 char *(args[50]);
131
132 struct Vlent *
133 GetVolume(vol, entry)
134      struct vldbentry *entry;
135 {
136     register int i;
137     register struct Vlent *vl;
138
139     if (!vol)
140         return NULL;
141     i = VHash(vol);
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])) {
146             return vl;
147         }
148     }
149     VL->rwid = entry->volumeId[0];
150     VL->roid = entry->volumeId[1];
151     VL->baid = entry->volumeId[2];
152     strcpy(entry->name, VL->name);
153     VL->next = VLa[i];
154     VLa[i] = VL;
155     if (VLcnt++ > ALLOCNT) {    /* XXXX FIX XXXXXXXXX */
156         printf("Too many entries (> %d)\n", ALLOCNT);
157         exit(1);
158     }
159     VL++;
160     return NULL;
161 }
162
163 /* Almost identical's to pr_Initialize in vlserver/pruser.c */
164 afs_int32
165 vl_Initialize(int auth, char *confDir, int server, char *cellp)
166 {
167     return ugen_ClientInit(auth?0:1, confDir, cellp, 0,
168                           &cstruct, NULL, "vl_Initialize", rxkad_clear, 
169                           MAXSERVERS, AFSCONF_VLDBSERVICE, 50, server,
170                           htons(AFSCONF_VLDBPORT), USER_SERVICE_ID);
171 }
172
173 /* return host address in network byte order */
174 afs_int32
175 GetServer(char *aname)
176 {
177     register struct hostent *th;
178     afs_int32 addr;
179     int b1, b2, b3, b4;
180     register afs_int32 code;
181
182     code = sscanf(aname, "%d.%d.%d.%d", &b1, &b2, &b3, &b4);
183     if (code == 4) {
184         addr = (b1 << 24) | (b2 << 16) | (b3 << 8) | b4;
185         return htonl(addr);     /* convert to network order (128 in byte 0) */
186     }
187     th = gethostbyname(aname);
188     if (!th)
189         return 0;
190     memcpy(&addr, th->h_addr, sizeof(addr));
191     return addr;
192 }
193
194
195 static
196 handleit(as)
197      struct cmd_syndesc *as;
198 {
199     register struct cmd_item *ti;
200     register afs_int32 code, server = 0, sawserver = 0;
201     afs_int32 id, voltype;
202     struct vldbentry entry;
203     char *cmd = 0, *cellp = 0;
204     struct VldbUpdateEntry updateentry;
205     struct VldbListByAttributes listbyattributes;
206     int noAuth = 1;             /* Default is authenticated connections */
207
208     if (ti = as->parms[0].items)        /* -cellpath <dir> */
209         strcpy(confdir, ti->data);
210     if (as->parms[1].items)     /* -server */
211         strcpy(confdir, AFSDIR_SERVER_ETC_DIRPATH);
212     if (as->parms[2].items)     /* -noauth */
213         noAuth = 0;
214     if (ti = as->parms[3].items) {      /* -host */
215         server = GetServer(ti->data);
216         if (server == 0) {
217             printf("server '%s' not found in host table\n", ti->data);
218             exit(1);
219         }
220         sawserver = 1;
221     }
222     if (!sawserver && noAuth && (!(ti = as->parms[4].items))) {
223         printf
224             ("Must also specify the -cell' option along with -host for authenticated conns\n");
225         exit(1);
226     }
227     if (ti = as->parms[4].items) {      /* -cell */
228         cellp = ti->data;
229     }
230     if (code = vl_Initialize(noAuth, confdir, server, cellp)) {
231         printf("Couldn't initialize vldb library (code=%d).\n", code);
232         exit(1);
233     }
234
235     if (as->parms[5].items) {   /* -gstats */
236         vldstats stats;
237         vital_vlheader vital_header;
238         code = ubik_Call(VL_GetStats, cstruct, 0, &stats, &vital_header);
239         if (!code)
240             dump_stats(&stats, &vital_header);
241         exit(0);
242     }
243
244     while (1) {
245         char line[500];
246         int nargs, releasetype;
247         memset(&entry, 0, sizeof(entry));
248         memset(&updateentry, 0, sizeof(updateentry));
249         memset(&listbyattributes, 0, sizeof(listbyattributes));
250         printf("vl> ");
251         if (fgets(line, 499, stdin) == NULL) {
252             printf("\n");
253             exit(0);
254         } else {
255             char *oper, *vname;
256             register char **argp = args;
257             GetArgs(line, argp, &nargs);
258             oper = &argp[0][0];
259             ++argp, --nargs;
260             if (!strcmp(oper, "cr")) {
261                 fill_entry(&entry, argp, nargs);
262                 display_entry(&entry, 0);
263                 code = ubik_Call(VL_CreateEntry, cstruct, 0, &entry);
264                 printf("return code is %d\n", code);
265             } else if (!strcmp(oper, "rm")) {
266                 sscanf(&(*argp)[0], "%d", &id);
267                 ++argp, --nargs;
268                 sscanf(&(*argp)[0], "%d", &voltype);
269                 code = ubik_Call(VL_DeleteEntry, cstruct, 0, id, voltype);
270                 printf("return code is %d\n", code);
271             } else if (!strcmp(oper, "re")) {
272                 sscanf(&(*argp)[0], "%d", &id);
273                 ++argp, --nargs;
274                 sscanf(&(*argp)[0], "%d", &voltype);
275                 ++argp, --nargs;
276                 sscanf(&(*argp)[0], "%d", &releasetype);
277                 ++argp, --nargs;
278                 fill_entry(&entry, argp, nargs);
279                 display_entry(&entry, 0);
280                 code =
281                     ubik_Call(VL_ReplaceEntry, cstruct, 0, id, voltype,
282                               &entry, releasetype);
283                 printf("return code is %d\n", code);
284             } else if (!strcmp(oper, "up")) {
285                 sscanf(&(*argp)[0], "%d", &id);
286                 ++argp, --nargs;
287                 sscanf(&(*argp)[0], "%d", &voltype);
288                 ++argp, --nargs;
289                 sscanf(&(*argp)[0], "%d", &releasetype);
290                 ++argp, --nargs;
291                 fill_update_entry(&updateentry, argp, nargs);
292                 display_update_entry(&updateentry, 0);
293                 code =
294                     ubik_Call(VL_UpdateEntry, cstruct, 0, id, voltype,
295                               &updateentry, releasetype);
296                 printf("return code is %d\n", code);
297             } else if (!strcmp(oper, "ls")) {
298                 afs_int32 index, count, next_index;
299                 for (index = 0; 1; index = next_index) {
300                     memset(&entry, 0, sizeof(entry));
301                     code =
302                         ubik_Call(VL_ListEntry, cstruct, 0, index, &count,
303                                   &next_index, &entry);
304                     if (code) {
305                         printf("VL_ListEntry returned code = %d\n", code);
306                         break;
307                     }
308                     if (!next_index)
309                         break;
310                     display_entry(&entry, 0);
311                 }
312             } else if (!strcmp(oper, "ldups")) {
313                 afs_int32 index, count, num = 0, num1 = 0, next_index;
314                 struct Vlent *vl1;
315
316                 VL = SVL =
317                     (struct Vlent *)malloc(ALLOCNT * sizeof(struct Vlent));
318                 if (VL == NULL) {
319                     printf("Can't allocate memory...\n");
320                     exit(1);
321                 }
322                 printf("Enumerating all entries in vldb...\n");
323                 for (index = 0; 1; index = next_index) {
324                     memset(&entry, 0, sizeof(entry));
325                     code =
326                         ubik_Call(VL_ListEntry, cstruct, 0, index, &count,
327                                   &next_index, &entry);
328                     if (code) {
329                         printf("VL_ListEntry returned code = %d\n", code);
330                         break;
331                     }
332                     if (!next_index)
333                         break;
334                     num++;
335                     if (vl1 = GetVolume(entry.volumeId[0], &entry)) {
336                         num1++;
337                         printf
338                             ("Duplicate entry is found for RW vol %u: [RW %u, RO %u, BA %u, name=%s]\n",
339                              entry.volumeId[0], vl1->rwid, vl1->roid,
340                              vl1->baid, vl1->name);
341                     }
342                     if (vl1 = GetVolume(entry.volumeId[1], &entry)) {
343                         num1++;
344                         printf
345                             ("Duplicate entry is found for RO vol %u: [RW %u, RO %u, BA %u, name=%s]\n",
346                              entry.volumeId[1], vl1->rwid, vl1->roid,
347                              vl1->baid, vl1->name);
348                     }
349                     if (vl1 = GetVolume(entry.volumeId[2], &entry)) {
350                         num1++;
351                         printf
352                             ("Duplicate entry is found for BA vol %u: [RW %u, RO %u, BA %u, name=%s]\n",
353                              entry.volumeId[2], vl1->rwid, vl1->roid,
354                              vl1->baid, vl1->name);
355                     }
356                     /*display_entry(&entry, 0); */
357                 }
358                 printf("(%d vldb entries found - %d duplicates)\n", num,
359                        num1);
360             } else if (!strcmp(oper, "checkhash")) {
361                 int index, count, num = 0, num1 = 0, num2 = 0, num3 =
362                     0, num31 = 0, num4 = 0, num41 = 0, next_index;
363                 struct vldbentry tentry;
364
365                 VL = SVL =
366                     (struct Vlent *)malloc(ALLOCNT * sizeof(struct Vlent));
367                 if (VL == NULL) {
368                     printf("Can't allocate memory...\n");
369                     exit(1);
370                 }
371                 printf("Volumes not found in main hash tables in vldb...\n");
372                 for (index = 0; 1; index = next_index) {
373                     memset(&entry, 0, sizeof(entry));
374                     code =
375                         ubik_Call(VL_ListEntry, cstruct, 0, index, &count,
376                                   &next_index, &entry);
377                     if (code) {
378                         printf("VL_ListEntry returned code = %d\n", code);
379                         break;
380                     }
381                     if (!next_index)
382                         break;
383                     num++;
384                     code =
385                         ubik_Call(VL_GetEntryByNameO, cstruct, 0, entry.name,
386                                   &tentry);
387                     if (code == VL_NOENT) {
388                         num1++;
389                         printf("\tVolume %s %d (not in namehash)\n",
390                                entry.name, entry.volumeId[RWVOL]);
391                     }
392                     code =
393                         ubik_Call(VL_GetEntryByID, cstruct, 0,
394                                   entry.volumeId[RWVOL], RWVOL, &tentry);
395                     if (code == VL_NOENT) {
396                         num2++;
397                         printf("\tVolume %s %d (not in rwid hash)\n",
398                                entry.name, entry.volumeId[RWVOL]);
399                     }
400                     if (entry.volumeId[BACKVOL]) {
401                         code =
402                             ubik_Call(VL_GetEntryByID, cstruct, 0,
403                                       entry.volumeId[BACKVOL], BACKVOL,
404                                       &tentry);
405                         num31++;
406                         if (code == VL_NOENT) {
407                             num3++;
408                             printf("\tVolume %s %d (not in backup id hash)\n",
409                                    entry.name, entry.volumeId[BACKVOL]);
410                         }
411                     }
412                     if (entry.volumeId[ROVOL]) {
413                         code =
414                             ubik_Call(VL_GetEntryByID, cstruct, 0,
415                                       entry.volumeId[ROVOL], ROVOL, &tentry);
416                         num41++;
417                         if (code == VL_NOENT) {
418                             num4++;
419                             printf("\tVolume %s %d (not in RO id hash)\n",
420                                    entry.name, entry.volumeId[ROVOL]);
421                         }
422                     }
423                 }
424                 printf
425                     ("\nTotal vldb entries %d\nTotal volumes %d (%d rw, %d backup, %d ro)\n",
426                      num, num + num31 + num41, num, num31, num41);
427                 printf
428                     ("\n\t%d didn't hash properly by name\n\t%d didn't hash properly by rw volid\n",
429                      num1, num2);
430                 printf
431                     ("\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",
432                      num3, num31, num4, num41);
433             } else if (!strcmp(oper, "fixhash")) {
434                 int index, count, num = 0, num1 = 0, num2 = 0, next_index, x =
435                     0;
436                 struct vldbentry tentry;
437
438                 VL = SVL =
439                     (struct Vlent *)malloc(ALLOCNT * sizeof(struct Vlent));
440                 if (VL == NULL) {
441                     printf("Can't allocate memory...\n");
442                     exit(1);
443                 }
444                 printf
445                     ("Volumes not found in main hash tables in vldb will be fixed...\n");
446                 memset(&updateentry, 0, sizeof(updateentry));
447                 for (index = 0; 1; index = next_index) {
448                     /* FIXME: n2 is never changed for some reason */
449                     int n1 = 0, n2 = 0, n3 = 0, n4 = 0;
450                     memset(&entry, 0, sizeof(entry));
451                     code =
452                         ubik_Call(VL_ListEntry, cstruct, 0, index, &count,
453                                   &next_index, &entry);
454                     if (code) {
455                         printf("VL_ListEntry returned code = %d\n", code);
456                         break;
457                     }
458                     if (!next_index)
459                         break;
460                     num++;
461                     code =
462                         ubik_Call(VL_GetEntryByNameO, cstruct, 0, entry.name,
463                                   &tentry);
464                     if (code == VL_NOENT) {
465                         num1++;
466                         n1 = 1;
467                         updateentry.Mask = VLUPDATE_VOLNAMEHASH;
468                         printf("\tVolume %s %d (not in namehash)\n",
469                                entry.name, entry.volumeId[RWVOL]);
470                         code =
471                             ubik_Call(VL_UpdateEntry, cstruct, 0,
472                                       entry.volumeId[RWVOL], -1, &updateentry,
473                                       0);
474                         if (code) {
475                             x++;
476                             printf("\tFailed to update volume %s (err=%d)\n",
477                                    entry.name, code);
478                         }
479                     }
480                     code =
481                         ubik_Call(VL_GetEntryByID, cstruct, 0,
482                                   entry.volumeId[RWVOL], RWVOL, &tentry);
483                     if (code == VL_NOENT) {
484                         num1++;
485                         num2++;
486                         updateentry.Mask = VLUPDATE_RWID;
487                         updateentry.spares3 = entry.volumeId[RWVOL];
488                         printf("\tVolume %s %d (not in rw id hash)\n",
489                                entry.name, entry.volumeId[RWVOL]);
490                         code =
491                             ubik_Call(VL_UpdateEntryByName, cstruct, 0,
492                                       entry.name, &updateentry, 0);
493                         if (code) {
494                             printf("\tFailed to update volume %s (err=%d)\n",
495                                    entry.name, code);
496                             x++;
497                         }
498                         x++;
499                     }
500                     if (entry.volumeId[BACKVOL] && !n2) {
501                         code =
502                             ubik_Call(VL_GetEntryByID, cstruct, 0,
503                                       entry.volumeId[BACKVOL], BACKVOL,
504                                       &tentry);
505                         if (code == VL_NOENT) {
506                             n3 = 1;
507                             num1++;
508                             updateentry.Mask = VLUPDATE_BACKUPID;
509                             updateentry.BackupId = entry.volumeId[BACKVOL];
510                             printf("\tVolume %s %d (not in backup id hash)\n",
511                                    entry.name, entry.volumeId[BACKVOL]);
512                             code =
513                                 ubik_Call(VL_UpdateEntry, cstruct, 0,
514                                           entry.volumeId[RWVOL], -1,
515                                           &updateentry, 0);
516                             if (code) {
517                                 printf
518                                     ("\tFailed to update volume %s (err=%d)\n",
519                                      entry.name, code);
520                                 x++;
521                             }
522                         }
523                     }
524                     if (entry.volumeId[ROVOL && !n2]) {
525                         code =
526                             ubik_Call(VL_GetEntryByID, cstruct, 0,
527                                       entry.volumeId[ROVOL], ROVOL, &tentry);
528                         if (code == VL_NOENT) {
529                             n4 = 1;
530                             num1++;
531                             updateentry.Mask = VLUPDATE_READONLYID;
532                             updateentry.ReadOnlyId = entry.volumeId[ROVOL];
533                             printf("\tVolume %s %d (not in RO id hash)\n",
534                                    entry.name, entry.volumeId[ROVOL]);
535                             code =
536                                 ubik_Call(VL_UpdateEntry, cstruct, 0,
537                                           entry.volumeId[RWVOL], -1,
538                                           &updateentry, 0);
539                             if (code) {
540                                 printf
541                                     ("\tFailed to update volume %s (err=%d)\n",
542                                      entry.name, code);
543                                 x++;
544                             }
545                         }
546                     }
547                 }
548                 printf
549                     ("\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",
550                      num, num1, x);
551             } else if (!strcmp(oper, "la")) {
552                 int nentries = 0, i;
553                 bulkentries entries;
554                 struct vldbentry *entry;
555
556                 memset(&entries, 0, sizeof(entries));
557                 fill_listattributes_entry(&listbyattributes, argp, nargs);
558                 display_listattributes_entry(&listbyattributes, 0);
559                 code =
560                     ubik_Call(VL_ListAttributes, cstruct, 0,
561                               &listbyattributes, &nentries, &entries);
562                 if (code) {
563                     printf("VL_ListAttributes returned code = %d\n", code);
564                     continue;
565                 }
566                 entry = (struct vldbentry *)entries.bulkentries_val;
567                 for (i = 0; i < nentries; i++, entry++)
568                     display_entry(entry, 0);
569                 if (entries.bulkentries_val)
570                     free((char *)entries.bulkentries_val);
571             } else if (!strcmp(oper, "lan2")) {
572                 int nentries, i, si, nsi, t = 0;
573                 nbulkentries entries;
574                 struct nvldbentry *entry;
575                 char name[64];
576
577                 /* The volume name to search for (supports wildcarding) */
578                 if (nargs > 0) {
579                     strcpy(name, argp[0]);
580                     ++argp, --nargs;
581                 } else {
582                     strcpy(name, "");
583                 }
584
585                 fill_listattributes_entry(&listbyattributes, argp, nargs);
586                 display_listattributes_entry(&listbyattributes, 0);
587                 printf("Wildcard VolName: '%s'\n", name);
588
589                 for (si = 0; si != -1; si = nsi) {
590                     nentries = 0;
591                     memset(&entries, 0, sizeof(entries));
592                     code =
593                         ubik_Call(VL_ListAttributesN2, cstruct, 0,
594                                   &listbyattributes, name, si, &nentries,
595                                   &entries, &nsi);
596                     if (code) {
597                         printf("VL_ListAttributesN2 returned code = %d\n",
598                                code);
599                         break;
600                     }
601
602                     t += nentries;
603                     entry = (struct nvldbentry *)entries.nbulkentries_val;
604                     for (i = 0; i < nentries; i++, entry++)
605                         display_entryN(entry, 0);
606                     if (entries.nbulkentries_val)
607                         free((char *)entries.nbulkentries_val);
608                 }
609                 printf("--- %d volumes ---\n", t);
610             } else if (!strcmp(oper, "ln")) {
611                 int netries;
612                 vldb_list linkedvldbs;
613                 vldblist vllist, vllist1;
614
615                 fill_listattributes_entry(&listbyattributes, argp, nargs);
616                 display_listattributes_entry(&listbyattributes, 0);
617                 memset(&linkedvldbs, 0, sizeof(vldb_list));
618                 code =
619                     ubik_Call(VL_LinkedList, cstruct, 0, &listbyattributes,
620                               &netries, &linkedvldbs);
621                 if (code) {
622                     printf("VL_LinkedList returned code = %d\n", code);
623                     continue;
624                 }
625                 printf("Found %d entr%s\n", netries,
626                        (netries == 1 ? "y" : "ies"));
627                 for (vllist = linkedvldbs.node; vllist; vllist = vllist1) {
628                     vllist1 = vllist->next_vldb;
629                     display_entry(&vllist->VldbEntry, 0);
630                     free((char *)vllist);
631                 }
632             } else if (!strcmp(oper, "lnn")) {
633                 int netries;
634                 nvldb_list linkedvldbs;
635                 nvldblist vllist, vllist1;
636
637                 fill_listattributes_entry(&listbyattributes, argp, nargs);
638                 display_listattributes_entry(&listbyattributes, 0);
639                 memset(&linkedvldbs, 0, sizeof(vldb_list));
640                 code =
641                     ubik_Call(VL_LinkedListN, cstruct, 0, &listbyattributes,
642                               &netries, &linkedvldbs);
643                 if (code) {
644                     printf("VL_LinkedList returned code = %d\n", code);
645                     continue;
646                 }
647                 printf("Found %d entr%s\n", netries,
648                        (netries == 1 ? "y" : "ies"));
649                 for (vllist = linkedvldbs.node; vllist; vllist = vllist1) {
650                     vllist1 = vllist->next_vldb;
651                     display_entry(&vllist->VldbEntry, 0);
652                     free((char *)vllist);
653                 }
654             } else if (!strcmp(oper, "di")) {
655                 sscanf(&(*argp)[0], "%d", &id);
656                 ++argp, --nargs;
657                 sscanf(&(*argp)[0], "%d", &voltype);
658                 code =
659                     ubik_Call(VL_GetEntryByID, cstruct, 0, id, voltype,
660                               &entry);
661                 display_entry(&entry, code);
662                 printf("return code is %d.\n", code);
663             } else if (!strcmp(oper, "rmnh")) {
664                 sscanf(&(*argp)[0], "%d", &id);
665                 ++argp, --nargs;
666                 sscanf(&(*argp)[0], "%d", &voltype);
667                 code =
668                     ubik_Call(VL_GetEntryByID, cstruct, 0, id, voltype,
669                               &entry);
670                 display_entry(&entry, code);
671                 memset(&updateentry, 0, sizeof(updateentry));
672                 updateentry.Mask = VLUPDATE_VOLNAMEHASH;
673                 printf("\tRehashing namehash table for %s (%d)\n", entry.name,
674                        entry.volumeId[RWVOL]);
675                 code =
676                     ubik_Call(VL_UpdateEntry, cstruct, 0,
677                               entry.volumeId[RWVOL], -1, &updateentry, 0);
678                 if (code) {
679                     printf("\tFailed to update volume %s (err=%d)\n",
680                            entry.name, code);
681                 }
682                 printf("return code is %d.\n", code);
683             } else if (!strcmp(oper, "undelete")) {
684                 afs_int32 index, count, next_index;
685
686                 memset(&updateentry, 0, sizeof(updateentry));
687                 sscanf(&(*argp)[0], "%d", &id);
688                 ++argp, --nargs;
689                 sscanf(&(*argp)[0], "%d", &voltype);
690                 if (voltype < 0 && voltype > 2) {
691                     printf("Illegal voltype; must be 0, 1 or 2\n");
692                     continue;
693                 }
694                 printf("Searching vldb for volume %d...\n", id);
695                 for (index = 0; 1; index = next_index) {
696                     memset(&entry, 0, sizeof(entry));
697                     code =
698                         ubik_Call(VL_ListEntry, cstruct, 0, index, &count,
699                                   &next_index, &entry);
700                     if (code) {
701                         printf("VL_ListEntry returned code = %d\n", code);
702                         break;
703                     }
704                     if (!next_index)
705                         break;
706                     if (entry.volumeId[voltype] == id) {
707                         printf("\nThe current contents of the vldb for %d:\n",
708                                id);
709                         display_entry(&entry, 0);
710
711                         if (entry.flags & VLDELETED) {
712                             updateentry.Mask = VLUPDATE_FLAGS;
713                             updateentry.flags = entry.flags;
714                             updateentry.flags &= ~VLDELETED;
715                             printf
716                                 ("\tUndeleting vldb entry for vol %d (%s)\n",
717                                  id, entry.name);
718                             code =
719                                 ubik_Call(VL_UpdateEntry, cstruct, 0, id, -1,
720                                           &updateentry, 0);
721                             if (code) {
722                                 printf
723                                     ("\tFailed to update volume %s (err=%d)\n",
724                                      entry.name, code);
725                             }
726                         } else {
727                             printf("Entry not deleted; ignored\n");
728                         }
729                         break;
730                     }
731                 }
732             } else if (!strcmp(oper, "dn")) {
733                 vname = &argp[0][0];
734                 code =
735                     ubik_Call(VL_GetEntryByNameO, cstruct, 0, vname, &entry);
736                 display_entry(&entry, code);
737                 printf("return code is %d.\n", code);
738             } else if (!strcmp(oper, "nv")) {
739                 int newvolid;
740                 sscanf(&(*argp)[0], "%d", &id);
741                 code =
742                     ubik_Call(VL_GetNewVolumeId, cstruct, 0, id, &newvolid);
743                 if (!code)
744                     printf("Current Max volid is (in hex):%X\n", newvolid);
745                 printf("return code is %d\n", code);
746             } else if (!strcmp(oper, "gs")) {
747                 vldstats stats;
748                 vital_vlheader vital_header;
749                 code =
750                     ubik_Call(VL_GetStats, cstruct, 0, &stats, &vital_header);
751                 if (!code)
752                     dump_stats(&stats, &vital_header);
753                 printf("return code is %d.\n", code);
754             } else if (!strcmp(oper, "ga")) {
755                 int nentries, i;
756                 afs_uint32 *addrp;
757                 bulkaddrs addrs;
758                 struct VLCallBack vlcb;
759
760                 addrs.bulkaddrs_val = 0;
761                 addrs.bulkaddrs_len = 0;
762                 code = ubik_Call(VL_GetAddrs, cstruct, 0, 0 /*Handle */ ,
763                                  0 /*spare2 */ , &vlcb,
764                                  &nentries, &addrs);
765                 if (code) {
766                     printf("VL_GetAddrs returned code = %d\n", code);
767                     continue;
768                 }
769                 addrp = addrs.bulkaddrs_val;
770                 for (i = 0; i < nentries; i++, addrp++) {
771                     if ((*addrp & 0xff000000) == 0xff000000)
772                         printf("[0x%x %u] (special multi-homed entry)\n",
773                                *addrp, *addrp);
774                     else
775                         printf("[0x%x %u] %s\n", *addrp, *addrp,
776                                hostutil_GetNameByINet(ntohl(*addrp)));
777                 }
778                 free((char *)addrs.bulkaddrs_val);
779             } else if (!strcmp(oper, "gau")) {
780                 int nentries, i, j;
781                 afs_uint32 *addrp;
782                 bulkaddrs addrs;
783                 struct VLCallBack vlcb;
784
785                 addrs.bulkaddrs_val = 0;
786                 addrs.bulkaddrs_len = 0;
787                 code = ubik_Call(VL_GetAddrs, cstruct, 0, 0 /*Handle */ ,
788                                  0 /*spare2 */ , &vlcb,
789                                  &nentries, &addrs);
790                 if (code) {
791                     printf("VL_GetAddrs returned code = %d\n", code);
792                     continue;
793                 }
794                 addrp = addrs.bulkaddrs_val;
795                 for (i = 0; i < nentries; i++, addrp++) {
796                     if ((*addrp & 0xff000000) == 0xff000000) {
797                         int mhnentries, unique;
798                         struct in_addr hostAddr;
799                         afs_uint32 *mhaddrp;
800                         bulkaddrs mhaddrs;
801                         ListAddrByAttributes attrs;
802                         afsUUID uuid;
803
804                         printf("[0x%x %u] (special multi-homed entry)\n",
805                                *addrp, *addrp);
806                         attrs.Mask = VLADDR_INDEX;
807                         mhaddrs.bulkaddrs_val = 0;
808                         mhaddrs.bulkaddrs_len = 0;
809                         attrs.index = *addrp & 0x00ffffff;
810
811                         code =
812                             ubik_Call(VL_GetAddrsU, cstruct, 0, &attrs, &uuid,
813                                       &unique, &mhnentries, &mhaddrs);
814                         if (code) {
815                             printf("VL_GetAddrsU returned code = %d\n", code);
816                             continue;
817                         }
818                         printf
819                             ("   [%d]: uuid[%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x]\n   addrunique=%d, ip address(es):\n",
820                              attrs.index, uuid.time_low, uuid.time_mid,
821                              uuid.time_hi_and_version,
822                              uuid.clock_seq_hi_and_reserved,
823                              uuid.clock_seq_low, uuid.node[0], uuid.node[1],
824                              uuid.node[2], uuid.node[3], uuid.node[4],
825                              uuid.node[5], unique);
826                         mhaddrp = mhaddrs.bulkaddrs_val;
827                         for (j = 0; j < mhnentries; j++) {
828                             mhaddrp[j] = ntohl(mhaddrp[j]);
829                             hostAddr.s_addr = mhaddrp[j];
830                             printf("\t%s (%s)\n", inet_ntoa(hostAddr),
831                                    hostutil_GetNameByINet(mhaddrp[j]));
832                         }
833                         if (mhaddrs.bulkaddrs_val)
834                             free((char *)mhaddrs.bulkaddrs_val);
835                     } else {
836                         printf("[0x%x %u] %s\n", *addrp, *addrp,
837                                hostutil_GetNameByINet(ntohl(*addrp)));
838                     }
839                 }
840                 free((char *)addrs.bulkaddrs_val);
841             } else if (!strcmp(oper, "mhc")) {
842                 afs_int32 serveraddrs[MAXSERVERID + 1][VL_MAXIPADDRS_PERMH];
843                 afs_int32 serveraddrtype[MAXSERVERID + 1];
844                 int nentries1, nentries2, i, j, x, y, unique, found;
845                 afs_uint32 *addrp1, *addrp2;
846                 bulkaddrs addrs1, addrs2;
847                 struct VLCallBack vlcb;
848                 ListAddrByAttributes attrs;
849                 afsUUID uuid;
850                 afs_int32 base, index;
851
852                 for (i = 0; i < MAXSERVERID + 1; i++) {
853                     serveraddrtype[i] = 0;
854                     for (j = 0; j < VL_MAXIPADDRS_PERMH; j++)
855                         serveraddrs[i][j] = 0;
856                 }
857
858                 /* Collect a list of all registered IP addresses */
859                 addrs1.bulkaddrs_val = 0;
860                 addrs1.bulkaddrs_len = 0;
861                 code =
862                     ubik_Call(VL_GetAddrs, cstruct, 0, 0, 0, &vlcb,
863                               &nentries1, &addrs1);
864                 if (code) {
865                     printf("VL_GetAddrs returned code = %d\n", code);
866                     continue;
867                 }
868                 addrp1 = addrs1.bulkaddrs_val;
869                 for (i = 0; i < nentries1; i++, addrp1++) {
870                     if ((*addrp1 & 0xff000000) != 0xff000000) {
871                         serveraddrs[i][0] = ntohl(*addrp1);
872                         serveraddrtype[i] = 1;
873                     } else {
874                         /* It's multihomed. Get all of its addresses */
875                         serveraddrtype[i] = 2;
876                         base = (*addrp1 >> 16) & 0xff;
877                         index = *addrp1 & 0xffff;
878
879                         addrs2.bulkaddrs_val = 0;
880                         addrs2.bulkaddrs_len = 0;
881                         attrs.Mask = VLADDR_INDEX;
882                         attrs.index = (base * VL_MHSRV_PERBLK) + index;
883                         code =
884                             ubik_Call(VL_GetAddrsU, cstruct, 0, &attrs, &uuid,
885                                       &unique, &nentries2, &addrs2);
886                         if (code) {
887                             printf("VL_GetAddrsU returned code = %d\n", code);
888                             break;
889                         }
890
891                         addrp2 = addrs2.bulkaddrs_val;
892                         for (j = 0; j < nentries2; j++) {
893                             serveraddrs[i][j] = ntohl(addrp2[j]);
894                         }
895                         free((char *)addrs2.bulkaddrs_val);
896                     }
897
898                     if (nargs) {
899                         if (serveraddrtype[i] == 1) {
900                             printf("%u\n", serveraddrs[i][0]);
901                         } else {
902                             printf("[");
903                             for (j = 0; j < VL_MAXIPADDRS_PERMH; j++)
904                                 if (serveraddrs[i][j])
905                                     printf(" %u", serveraddrs[i][j]);
906                             printf(" ]\n");
907                         }
908                     }
909                 }
910                 free((char *)addrs1.bulkaddrs_val);
911
912                 /* Look for any duplicates */
913                 for (i = 0; i < MAXSERVERID + 1; i++) {
914                     if (!serveraddrtype[i])
915                         continue;
916                     for (j = 0; j < VL_MAXIPADDRS_PERMH; j++) {
917                         if (!serveraddrs[i][j])
918                             continue;
919
920                         found = 0;
921                         for (x = i + 1; x < MAXSERVERID + 1; x++) {
922                             if (!serveraddrtype[x])
923                                 continue;
924                             for (y = 0; y < VL_MAXIPADDRS_PERMH; y++) {
925                                 if (!serveraddrs[x][y])
926                                     continue;
927                                 if (serveraddrs[i][j] == serveraddrs[x][y]) {
928                                     serveraddrs[x][y] = 0;
929                                     found++;
930                                 }
931                             }
932                         }
933                         if (found) {
934                             printf
935                                 ("Found %d entries of IP address %u (0x%x)\n",
936                                  found + 1, serveraddrs[i][j],
937                                  serveraddrs[i][j]);
938                         }
939                     }
940                 }
941
942                /*----------------------------------------*/
943
944             } else if (!strcmp(oper, "regaddr")) {
945                 int i;
946                 afs_uint32 *addrp, tad;
947                 bulkaddrs addrs;
948                 afsUUID uuid;
949
950                 memset(&uuid, 0, sizeof(uuid));
951                 sscanf(&(*argp)[0], "%d", &i);
952                 ++argp, --nargs;
953                 memcpy(uuid.node, &i, sizeof(i));
954
955                 if (nargs < 0 || nargs > 16) {
956                     printf("Illegal # entries = %d\n", nargs);
957                     continue;
958                 }
959                 addrp = (afs_uint32 *) malloc(20 * 4);
960                 addrs.bulkaddrs_val = addrp;
961                 addrs.bulkaddrs_len = nargs;
962                 while (nargs > 0) {
963                     sscanf(&(*argp)[0], "%d", &tad);
964                     *addrp++ = tad;
965                     ++argp, --nargs;
966                 }
967                 code =
968                     ubik_Call(VL_RegisterAddrs, cstruct, 0, &uuid,
969                               0 /*spare */ , &addrs);
970                 if (code) {
971                     printf("VL_RegisterAddrs returned code = %d\n", code);
972                     continue;
973                 }
974             } else if (!strcmp(oper, "ca")) {
975                 extern struct hostent *hostutil_GetHostByName();
976                 struct hostent *h1, *h2;
977                 afs_uint32 a1, a2;
978
979                 printf("changing %s", *argp);
980                 h1 = hostutil_GetHostByName(&(*argp)[0]);
981                 if (!h1) {
982                     printf("cmdebug: can't resolve address for host %s",
983                            *argp);
984                     continue;
985                 }
986                 memcpy(&a1, (afs_int32 *) h1->h_addr, sizeof(afs_uint32));
987
988                 ++argp, --nargs;
989                 printf(" to %s\n", *argp);
990                 h2 = hostutil_GetHostByName(&(*argp)[0]);
991                 if (!h2) {
992                     printf("cmdebug: can't resolve address for host %s",
993                            *argp);
994                     continue;
995                 }
996                 memcpy(&a2, (afs_int32 *) h2->h_addr, sizeof(afs_uint32));
997
998                 printf("changing 0x%x to 0x%x\n", ntohl(a1), ntohl(a2));
999                 code =
1000                     ubik_Call(VL_ChangeAddr, cstruct, 0, ntohl(a1),
1001                               ntohl(a2));
1002                 if (code) {
1003                     printf("VL_ChangeAddr returned code = %d\n", code);
1004                     continue;
1005                 }
1006             } else if (!strcmp(oper, "caid")) {
1007                 afs_uint32 a1, a2;
1008
1009                 sscanf(&(*argp)[0], "%d", &a1);
1010                 printf("changing %d (0x%x)", a1, a1);
1011                 ++argp, --nargs;
1012                 sscanf(&(*argp)[0], "%d", &a2);
1013                 printf(" to %d (0x%x)\n", a2, a2);
1014                 code = ubik_Call(VL_ChangeAddr, cstruct, 0, a1, a2);
1015                 if (code) {
1016                     printf("VL_ChangeAddr returned code = %d\n", code);
1017                     continue;
1018                 }
1019             } else if ((!strcmp(oper, "?")) || !strcmp(oper, "h"))
1020                 print_usage();
1021             else if ((!strcmp(oper, "q")) || !strcmp(oper, "quit"))
1022                 exit(0);
1023             else {
1024                 printf("Unknown oper!\n");
1025             }
1026         }
1027     }
1028 }
1029
1030
1031 #include "AFS_component_version_number.c"
1032
1033 main(argc, argv)
1034      int argc;
1035      char **argv;
1036 {
1037     register struct cmd_syndesc *ts;
1038     afs_int32 code;
1039
1040     strcpy(confdir, AFSDIR_CLIENT_ETC_DIRPATH);
1041     ts = cmd_CreateSyntax("initcmd", handleit, 0, "initialize the program");
1042     cmd_AddParm(ts, "-cellpath", CMD_LIST, CMD_OPTIONAL,
1043                 "Cell configuration directory");
1044     cmd_AddParm(ts, "-server", CMD_LIST, CMD_OPTIONAL,
1045                 "Use the cell config in /usr/afs/etc (default /usr/vice/etc)");
1046     cmd_AddParm(ts, "-noauth", CMD_FLAG, CMD_OPTIONAL,
1047                 "Run it without authentication");
1048     cmd_AddParm(ts, "-host", CMD_LIST, CMD_OPTIONAL,
1049                 "vldb server to talk to");
1050     cmd_AddParm(ts, "-cell", CMD_LIST, CMD_OPTIONAL,
1051                 "cellname '-host' belongs to (required for auth conns)");
1052     cmd_AddParm(ts, "-getstats", CMD_FLAG, CMD_OPTIONAL,
1053                 "print vldb statistics (non interactive)");
1054     code = cmd_Dispatch(argc, argv);
1055     exit(code);
1056 }
1057
1058
1059 void
1060 fill_entry(entry, argp, nargs)
1061      struct vldbentry *entry;
1062      char **argp;
1063      int nargs;
1064 {
1065     char *name;
1066     int i;
1067
1068     name = &argp[0][0];
1069     ++argp, --nargs;
1070     sscanf(&(*argp)[0], "%d", &entry->spares3);
1071     ++argp, --nargs;
1072     sscanf(&(*argp)[0], "%d", &entry->nServers);
1073     strcpy(entry->name, name);
1074     for (i = 0; i < entry->nServers; i++) {
1075         ++argp, --nargs;
1076         sscanf(&(*argp)[0], "%u", &entry->serverNumber[i]);
1077     }
1078     for (i = 0; i < entry->nServers; i++) {
1079         ++argp, --nargs;
1080         sscanf(&(*argp)[0], "%d", &entry->serverPartition[i]);
1081     }
1082     for (i = 0; i < entry->nServers; i++) {
1083         ++argp, --nargs;
1084         sscanf(&(*argp)[0], "%d", &entry->serverFlags[i]);
1085     }
1086     for (i = 0; i < MAXTYPES; i++) {
1087         ++argp, --nargs;
1088         sscanf(&(*argp)[0], "%d", &entry->volumeId[i]);
1089     }
1090     ++argp, --nargs;
1091     sscanf(&(*argp)[0], "%d", &entry->flags);
1092     ++argp, --nargs;
1093     sscanf(&(*argp)[0], "%d", &entry->cloneId);
1094 }
1095
1096 void
1097 fill_update_entry(entry, argp, nargs)
1098      struct VldbUpdateEntry *entry;
1099      char **argp;
1100      int nargs;
1101 {
1102     int i, Mask;
1103     char *name;
1104
1105     entry->Mask = 0;
1106     name = &argp[0][0];
1107     if (strcmp(name, "null")) {
1108         strcpy(entry->name, name);
1109         entry->Mask |= VLUPDATE_VOLUMENAME;
1110     }
1111     ++argp, --nargs;
1112     sscanf(&(*argp)[0], "%d", &entry->flags);
1113     if (entry->flags != -1)
1114         entry->Mask |= VLUPDATE_FLAGS;
1115     ++argp, --nargs;
1116     sscanf(&(*argp)[0], "%d", &entry->cloneId);
1117     if (entry->flags != -1)
1118         entry->Mask |= VLUPDATE_CLONEID;
1119     ++argp, --nargs;
1120     sscanf(&(*argp)[0], "%d", &entry->ReadOnlyId);
1121     if (entry->ReadOnlyId != -1)
1122         entry->Mask |= VLUPDATE_READONLYID;
1123     ++argp, --nargs;
1124     sscanf(&(*argp)[0], "%d", &entry->BackupId);
1125     if (entry->BackupId != -1)
1126         entry->Mask |= VLUPDATE_BACKUPID;
1127     ++argp, --nargs;
1128     sscanf(&(*argp)[0], "%d", &entry->nModifiedRepsites);
1129     if (entry->nModifiedRepsites != -1)
1130         entry->Mask |= VLUPDATE_REPSITES;
1131     for (i = 0; i < entry->nModifiedRepsites; i++) {
1132         ++argp, --nargs;
1133         sscanf(&(*argp)[0], "%x", &Mask);
1134         ++argp, --nargs;
1135         sscanf(&(*argp)[0], "%u", &entry->RepsitesTargetServer[i]);
1136         ++argp, --nargs;
1137         sscanf(&(*argp)[0], "%d", &entry->RepsitesTargetPart[i]);
1138         if (Mask & VLUPDATE_REPS_DELETE)
1139             entry->RepsitesMask[i] |= VLUPDATE_REPS_DELETE;
1140         if (Mask & VLUPDATE_REPS_MODSERV) {
1141             ++argp, --nargs;
1142             sscanf(&(*argp)[0], "%u", &entry->RepsitesNewServer[i]);
1143             entry->RepsitesMask[i] |= VLUPDATE_REPS_MODSERV;
1144         } else if (Mask & VLUPDATE_REPS_MODPART) {
1145             ++argp, --nargs;
1146             sscanf(&(*argp)[0], "%d", &entry->RepsitesNewPart[i]);
1147             entry->RepsitesMask[i] |= VLUPDATE_REPS_MODPART;
1148         } else if (Mask & VLUPDATE_REPS_MODFLAG) {
1149             ++argp, --nargs;
1150             sscanf(&(*argp)[0], "%d", &entry->RepsitesNewFlags[i]);
1151             entry->RepsitesMask[i] |= VLUPDATE_REPS_MODFLAG;
1152         } else if (Mask & VLUPDATE_REPS_ADD) {
1153             ++argp, --nargs;
1154             sscanf(&(*argp)[0], "%u", &entry->RepsitesNewServer[i]);
1155             ++argp, --nargs;
1156             sscanf(&(*argp)[0], "%d", &entry->RepsitesNewPart[i]);
1157             ++argp, --nargs;
1158             sscanf(&(*argp)[0], "%d", &entry->RepsitesNewFlags[i]);
1159             entry->RepsitesMask[i] |= VLUPDATE_REPS_ADD;
1160         }
1161     }
1162 }
1163
1164 void
1165 fill_listattributes_entry(entry, argp, nargs)
1166      struct VldbListByAttributes *entry;
1167      char **argp;
1168      int nargs;
1169 {
1170     entry->Mask = 0;
1171
1172     if (nargs <= 0)
1173         return;
1174     entry->server = ntohl(GetServer(argp[0]));
1175     sscanf(&(*argp)[0], "%d", &entry->server);
1176     if (entry->server != 0)
1177         entry->Mask |= VLLIST_SERVER;
1178     ++argp, --nargs;
1179
1180     if (nargs <= 0)
1181         return;
1182     sscanf(&(*argp)[0], "%d", &entry->partition);
1183     if (entry->partition != -1)
1184         entry->Mask |= VLLIST_PARTITION;
1185     ++argp, --nargs;
1186
1187     if (nargs <= 0)
1188         return;
1189     sscanf(&(*argp)[0], "%d", &entry->volumeid);
1190     if (entry->volumeid != -1)
1191         entry->Mask |= VLLIST_VOLUMEID;
1192     ++argp, --nargs;
1193
1194     if (nargs <= 0)
1195         return;
1196     sscanf(&(*argp)[0], "%d", &entry->flag);
1197     if (entry->flag != -1)
1198         entry->Mask |= VLLIST_FLAG;
1199 }
1200
1201 void
1202 display_listattributes_entry(entry, error)
1203      struct VldbListByAttributes *entry;
1204      int error;
1205 {
1206     if (error)
1207         return;
1208     printf("\nList entry values (Mask=%x)\n", entry->Mask);
1209     if (entry->Mask & VLLIST_SERVER)
1210         printf("\tServer: %d.%d.%d.%d\n", (entry->server >> 24) & 0xff,
1211                (entry->server >> 16) & 0xff, (entry->server >> 8) & 0xff,
1212                (entry->server) & 0xff);
1213     if (entry->Mask & VLLIST_PARTITION)
1214         printf("\tPartition: %d\n", entry->partition);
1215     if (entry->Mask & VLLIST_VOLUMEID)
1216         printf("\tVolumeId: %u\n", entry->volumeid);
1217     if (entry->Mask & VLLIST_FLAG)
1218         printf("\tFlag: %x\n", entry->flag);
1219 }
1220
1221
1222 #define volumetype_string(type) (type == RWVOL? "read/write":type == ROVOL? "readonly":type == BACKVOL? "backup":"unknown")
1223
1224 void
1225 display_entry(entry, error)
1226      struct vldbentry *entry;
1227      int error;
1228 {
1229     int i;
1230
1231     if (error)
1232         return;
1233     printf("\nEntry for volume name: %s, volid=%u (flags=%X) are:\n",
1234            entry->name, entry->volumeId[RWVOL], entry->flags);
1235     printf("ParentID=%u, ReadOnlyID=%u, backupID=%u, CloneId=%u ",
1236            entry->volumeId[0], entry->volumeId[1], entry->volumeId[2],
1237            entry->cloneId);
1238     printf("nServers=%d\n", entry->nServers);
1239     printf("ServerNumber\tServerPart\tserverFlag\n");
1240     for (i = 0; i < entry->nServers; i++)
1241         printf("%12u\t%10d\t%10x\n", entry->serverNumber[i],
1242                entry->serverPartition[i], entry->serverFlags[i]);
1243 }
1244
1245 void
1246 display_entryN(entry, error)
1247      struct nvldbentry *entry;
1248      int error;
1249 {
1250     int i, et, ei;
1251
1252     if (error)
1253         return;
1254     printf("\nEntry for volume name: %s, volid=%u (flags=%X) are:\n",
1255            entry->name, entry->volumeId[RWVOL], entry->flags);
1256     printf("ParentID=%u, ReadOnlyID=%u, backupID=%u, CloneId=%u ",
1257            entry->volumeId[0], entry->volumeId[1], entry->volumeId[2],
1258            entry->cloneId);
1259     printf("nServers=%d\n", entry->nServers);
1260     printf("ServerNumber\tServerPart\tserverFlag\n");
1261     ei = entry->matchindex & 0xffff;
1262     et = (entry->matchindex >> 16) & 0xffff;
1263     for (i = 0; i < entry->nServers; i++) {
1264         printf("%12u\t%10d\t%10x", entry->serverNumber[i],
1265                entry->serverPartition[i], entry->serverFlags[i]);
1266         if (i == ei) {
1267             printf(" <--- %s", (et == 4) ? "RW" : ((et == 8) ? "BK" : "RO"));
1268         }
1269         printf("\n");
1270     }
1271 }
1272
1273 void
1274 display_update_entry(entry, error)
1275      struct VldbUpdateEntry *entry;
1276      int error;
1277 {
1278     int i;
1279
1280     if (error)
1281         return;
1282     printf("\nUpdate entry values (Mask=%x)\n", entry->Mask);
1283     if (entry->Mask & VLUPDATE_VOLUMENAME)
1284         printf("\tNew name: %s\n", entry->name);
1285     if (entry->Mask & VLUPDATE_FLAGS)
1286         printf("\tNew flags: %X\n", entry->flags);
1287     if (entry->Mask & VLUPDATE_CLONEID)
1288         printf("\tNew CloneId: %X\n", entry->cloneId);
1289     if (entry->Mask & VLUPDATE_READONLYID)
1290         printf("\tNew RO id: %D\n", entry->ReadOnlyId);
1291     if (entry->Mask & VLUPDATE_BACKUPID)
1292         printf("\tNew BACKUP id: %D\n", entry->BackupId);
1293     if (entry->Mask & VLUPDATE_REPSITES) {
1294         printf("\tRepsites info:\n");
1295         printf("\tFlag\tTServer\tTPart\tNServer\tNPart\tNFlag\n");
1296         for (i = 0; i < entry->nModifiedRepsites; i++) {
1297             printf("\t%4x\t%7U\t%5d", entry->RepsitesMask[i],
1298                    entry->RepsitesTargetServer[i],
1299                    entry->RepsitesTargetPart[i]);
1300             if ((entry->RepsitesMask[i] & VLUPDATE_REPS_ADD)
1301                 || (entry->RepsitesMask[i] & VLUPDATE_REPS_MODSERV))
1302                 printf("\t%7U", entry->RepsitesNewServer[i]);
1303             else
1304                 printf("\t-------");
1305             if ((entry->RepsitesMask[i] & VLUPDATE_REPS_ADD)
1306                 || (entry->RepsitesMask[i] & VLUPDATE_REPS_MODPART))
1307                 printf("\t%5d", entry->RepsitesNewPart[i]);
1308             else
1309                 printf("\t-----");
1310             if ((entry->RepsitesMask[i] & VLUPDATE_REPS_ADD)
1311                 || (entry->RepsitesMask[i] & VLUPDATE_REPS_MODFLAG))
1312                 printf("\t%5x\n", entry->RepsitesNewFlags[i]);
1313             else
1314                 printf("\t-----\n");
1315         }
1316     }
1317 }
1318
1319 void
1320 dump_stats(stats, vital_header)
1321      vldstats *stats;
1322      vital_vlheader *vital_header;
1323 {
1324     int i;
1325     char strg[30];
1326     time_t start_time = stats->start_time;
1327
1328     strncpy(strg, ctime(&start_time), sizeof(strg));
1329     strg[strlen(strg) - 1] = 0;
1330     printf("Dynamic statistics stats (starting time: %s):\n", strg);
1331     printf("OpcodeName\t# Requests\t# Aborts\n");
1332     for (i = 0; i < VL_NUMBER_OPCODESX; i++)
1333         printf("%10s\t%10d\t%8d\n", opcode_names[i], stats->requests[i],
1334                stats->aborts[i]);
1335     printf("\nVldb header stats (version=%d)\n",
1336            ntohl(vital_header->vldbversion));
1337     printf("headersize=%d, allocs=%d, frees=%d, MaxVolid=%X\n",
1338            ntohl(vital_header->headersize), ntohl(vital_header->allocs),
1339            ntohl(vital_header->frees), ntohl(vital_header->MaxVolumeId));
1340     for (i = 0; i < MAXTYPES; i++)
1341         printf("total %s entries=%d\n", volumetype_string(i),
1342                ntohl(vital_header->totalEntries[i]));
1343 }
1344
1345 void
1346 GetArgs(line, args, nargs)
1347      register char *line;
1348      register char **args;
1349      register int *nargs;
1350 {
1351     *nargs = 0;
1352     while (*line) {
1353         register char *last = line;
1354         while (*line == ' ')
1355             line++;
1356         if (*last == ' ')
1357             *last = 0;
1358         if (!*line)
1359             break;
1360         *args++ = line, (*nargs)++;
1361         while (*line && *line != ' ')
1362             line++;
1363     }
1364 }
1365
1366 void
1367 print_usage()
1368 {
1369     printf("Valid Commands:\n");
1370
1371     printf("   CreateEntry:\n");
1372     printf
1373         ("\tcr <vname> <vtype> <#S> <Saddr1>.<Saddrn> <Spart1>.<Spartn> <Sflag1>.<Sflagn> <Volid1-3> <flag>\n");
1374
1375     printf("   DeleteEntry:\n");
1376     printf("\trm <volid> <voltype>\n");
1377
1378     printf("   ReplaceEntry:\n");
1379     printf("\tre <volid> <voltype> <New vldb entry ala 'cr'>\n");
1380
1381     printf("   UpdateEntry:\n");
1382     printf
1383         ("\tup <volid> <voltype> <vname> <vtype> <#AddSer> [<Saddr1>.<Saddrn> <Spart1>.<Spartn> <Sflag1>.<Sflagn>] <Volid1-3> <flag>\n");
1384
1385     printf("   ListEntry:\n");
1386     printf("\tls\n");
1387
1388     printf("   Find duplicate entries of a volume\n");
1389     printf("\tldups\n");
1390
1391     printf("   For each vlentry, find it by name, RW id, BK id, and RO id\n");
1392     printf("\tcheckhash\n");
1393
1394     printf
1395         ("   UpdateEntry (update the volname, RW id, BK id, RO id hashes):\n");
1396     printf("\tfixhash\n");
1397
1398     printf("   ListAttributes:\n");
1399     printf("\tla [server] [partition] [volumeid] [flag]\n");
1400
1401     printf("   ListAttributesN2:\n");
1402     printf("\tlan2 [volname] [server] [partition] [volumeid] [flag]\n");
1403
1404     printf("   GetEntryByID:\n");
1405     printf("\tdi <volid> <voltype>\n");
1406
1407     printf("   UpdateEntry (refresh namehash table):\n");
1408     printf("\trmnh <volid> <voltype>\n");
1409
1410     printf("   GetEntryByName:\n");
1411     printf("\tdn <volname> <voltype>\n");
1412
1413     printf("   UpdateEntry (undelete a vol entry):\n");
1414     printf("\tundelete <volid> <voltype>\n");
1415 /*
1416  *  printf("  LinkedList\n");
1417  *  printf("\t:ln [server] [partition] [volumeid] [flag]\n");
1418  *
1419  *  printf("  LinkedListN\n");
1420  *  printf("\t:lnn [server] [partition] [volumeid] [flag]\n");
1421  */
1422     printf("   GetNewVoumeId:\n");
1423     printf("\tnv <bump-count>\n");
1424
1425     printf("   GetStats:\n");
1426     printf("\tgs\n");
1427
1428     printf("   ChangeAddr:\n");
1429     printf("\tca <oldmachname> <newmachname>\n");
1430
1431 /*
1432  *  printf("   ChangeAddr\n");
1433  *  printf("\t:caid <oldaddr> <newaddr>\n");
1434  */
1435     printf("   GetAddrs:\n");
1436     printf("\tga\n");
1437
1438     printf("   GetAddrsU:\n");
1439     printf("\tgau\n");
1440
1441     printf("   RegisterAddrs:\n");
1442     printf("\tregaddr uuidNumber <ip1 .. ipn>\n");
1443
1444     printf("\tmisc: q, quit, ?, h\n");
1445 }