Commit | Line | Data |
---|---|---|
805e021f CE |
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 | #include <afs/stds.h> | |
13 | ||
14 | #include <roken.h> | |
15 | ||
16 | #ifdef AFS_NT40_ENV | |
17 | #include <WINNT/afsevent.h> | |
18 | #endif | |
19 | #ifdef HAVE_SYS_FILE_H | |
20 | #include <sys/file.h> | |
21 | #endif | |
22 | #include <ctype.h> | |
23 | ||
24 | #include <afs/afsutil.h> | |
25 | #include <rx/xdr.h> | |
26 | #include <rx/rx.h> | |
27 | #include <rx/rx_globals.h> | |
28 | #include <rx/rxkad.h> | |
29 | #include <afs/cellconfig.h> | |
30 | #include <afs/keys.h> | |
31 | #include <afs/cmd.h> | |
32 | #include <lock.h> | |
33 | #include <ubik.h> | |
34 | ||
35 | #include "vlserver.h" | |
36 | ||
37 | void fill_listattributes_entry(struct VldbListByAttributes *, char **, int); | |
38 | void display_listattributes_entry(struct VldbListByAttributes *,int); | |
39 | void display_entry(struct vldbentry *, int); | |
40 | void display_entryN(struct nvldbentry *, int); | |
41 | void display_update_entry(struct VldbUpdateEntry *, int); | |
42 | void dump_stats(vldstats *, vital_vlheader *); | |
43 | void GetArgs(char *, char **, int *); | |
44 | void print_usage(void); | |
45 | void fill_entry(struct vldbentry *, char **, int); | |
46 | void fill_update_entry(struct VldbUpdateEntry *, char **, int); | |
47 | ||
48 | #define VL_NUMBER_OPCODESX 34 | |
49 | static char *opcode_names[VL_NUMBER_OPCODESX] = { | |
50 | "CreateEntry", | |
51 | "DeleteEntry", | |
52 | "GetEntryByID", | |
53 | "GetEntryByName", | |
54 | "GetNewVolumeId", | |
55 | "ReplaceEntry", | |
56 | "UpdateEntry", | |
57 | "SetLock", | |
58 | "ReleaseLock", | |
59 | "ListEntry", | |
60 | "ListAttributes", | |
61 | "LinkedList", | |
62 | "GetStats", | |
63 | "Probe", /* RPC is ProbeServer */ | |
64 | "GetAddrs", | |
65 | "ChangeAddr", | |
66 | "CreateEntryN", | |
67 | "GetEntryByIDN", | |
68 | "GetEntryByNameN", | |
69 | "ReplaceEntryN", | |
70 | "ListEntryN", | |
71 | "ListAttributesN", | |
72 | "LinkedListN", | |
73 | "UpdateeEntryByName", | |
74 | "CreateEntryU", | |
75 | "GetEntryByIDU", | |
76 | "GetEntryByNameU", | |
77 | "ReplaceEntryU", | |
78 | "ListEntryU", | |
79 | "ListAttributesU", | |
80 | "LinkedListU", | |
81 | "RegisterAddr", | |
82 | "GetAddrsU", | |
83 | "ListAttributesN2" | |
84 | }; | |
85 | ||
86 | struct Vlent { | |
87 | struct Vlent *next; | |
88 | afs_int32 rwid; | |
89 | afs_int32 roid; | |
90 | afs_int32 baid; | |
91 | char name[64]; | |
92 | }; | |
93 | ||
94 | #define NVOLS 1000 | |
95 | #define ALLOCNT 50000 | |
96 | struct Vlent *VLa[NVOLS]; | |
97 | #define VHash(avol) ((avol)&(NVOLS-1)) | |
98 | struct Vlent *VL, *SVL; | |
99 | int VLcnt = 0; | |
100 | struct ubik_client *cstruct; | |
101 | struct rx_connection *serverconns[MAXSERVERS]; | |
102 | char confdir[AFSDIR_PATH_MAX]; | |
103 | char *(args[50]); | |
104 | ||
105 | struct Vlent * | |
106 | GetVolume(int vol, struct vldbentry *entry) | |
107 | { | |
108 | int i; | |
109 | struct Vlent *vl; | |
110 | ||
111 | if (!vol) | |
112 | return NULL; | |
113 | i = VHash(vol); | |
114 | for (vl = VLa[i]; vl; vl = vl->next) { | |
115 | if ((vl->rwid == vol && vol != entry->volumeId[0]) | |
116 | || (vl->roid == vol && vol != entry->volumeId[1]) | |
117 | || (vl->baid == vol && vol != entry->volumeId[2])) { | |
118 | return vl; | |
119 | } | |
120 | } | |
121 | VL->rwid = entry->volumeId[0]; | |
122 | VL->roid = entry->volumeId[1]; | |
123 | VL->baid = entry->volumeId[2]; | |
124 | strcpy(entry->name, VL->name); | |
125 | VL->next = VLa[i]; | |
126 | VLa[i] = VL; | |
127 | if (VLcnt++ > ALLOCNT) { /* XXXX FIX XXXXXXXXX */ | |
128 | printf("Too many entries (> %d)\n", ALLOCNT); | |
129 | exit(1); | |
130 | } | |
131 | VL++; | |
132 | return NULL; | |
133 | } | |
134 | ||
135 | /* Almost identical's to pr_Initialize in vlserver/pruser.c */ | |
136 | afs_int32 | |
137 | vl_Initialize(char *confDir, int secFlags, int server, char *cellp) | |
138 | { | |
139 | return ugen_ClientInitServer(confDir, cellp, secFlags, &cstruct, | |
140 | MAXSERVERS, AFSCONF_VLDBSERVICE, 90, | |
141 | server, htons(AFSCONF_VLDBPORT)); | |
142 | } | |
143 | ||
144 | /* return host address in network byte order */ | |
145 | afs_int32 | |
146 | GetServer(char *aname) | |
147 | { | |
148 | struct hostent *th; | |
149 | afs_uint32 addr; | |
150 | int b1, b2, b3, b4; | |
151 | afs_int32 code; | |
152 | ||
153 | code = sscanf(aname, "%d.%d.%d.%d", &b1, &b2, &b3, &b4); | |
154 | if (code == 4) { | |
155 | addr = (b1 << 24) | (b2 << 16) | (b3 << 8) | b4; | |
156 | return htonl(addr); /* convert to network order (128 in byte 0) */ | |
157 | } | |
158 | th = gethostbyname(aname); | |
159 | if (!th) | |
160 | return 0; | |
161 | memcpy(&addr, th->h_addr, sizeof(addr)); | |
162 | return addr; | |
163 | } | |
164 | ||
165 | ||
166 | static int | |
167 | handleit(struct cmd_syndesc *as, void *arock) | |
168 | { | |
169 | struct cmd_item *ti; | |
170 | afs_int32 code, server = 0, sawserver = 0; | |
171 | afs_int32 id, voltype; | |
172 | struct vldbentry entry; | |
173 | char *cellp = 0; | |
174 | struct VldbUpdateEntry updateentry; | |
175 | struct VldbListByAttributes listbyattributes; | |
176 | int secFlags = AFSCONF_SECOPTS_FALLBACK_NULL; | |
177 | ||
178 | if ((ti = as->parms[0].items)) /* -cellpath <dir> */ | |
179 | strcpy(confdir, ti->data); | |
180 | if (as->parms[1].items) /* -server */ | |
181 | strcpy(confdir, AFSDIR_SERVER_ETC_DIRPATH); | |
182 | if (as->parms[2].items) /* -noauth */ | |
183 | secFlags |= AFSCONF_SECOPTS_NOAUTH; | |
184 | if ((ti = as->parms[3].items)) { /* -host */ | |
185 | server = GetServer(ti->data); | |
186 | if (server == 0) { | |
187 | printf("server '%s' not found in host table\n", ti->data); | |
188 | exit(1); | |
189 | } | |
190 | sawserver = 1; | |
191 | } | |
192 | if (sawserver && !as->parms[2].items && (!(ti = as->parms[4].items))) { | |
193 | printf | |
194 | ("Must also specify the -cell' option along with -host for authenticated conns\n"); | |
195 | exit(1); | |
196 | } | |
197 | if ((ti = as->parms[4].items)) { /* -cell */ | |
198 | cellp = ti->data; | |
199 | } | |
200 | if ((code = vl_Initialize(confdir, secFlags, server, cellp))) { | |
201 | printf("Couldn't initialize vldb library (code=%d).\n", code); | |
202 | exit(1); | |
203 | } | |
204 | ||
205 | if (as->parms[6].items) { /* -probe */ | |
206 | int nconns = 0; | |
207 | int status = 0; | |
208 | int i; | |
209 | char hoststr[16]; | |
210 | afs_uint32 addr; | |
211 | ||
212 | for (i = 0; cstruct->conns[i]; i++, nconns++) { | |
213 | rx_SetConnDeadTime(cstruct->conns[i], 6); | |
214 | addr = rx_HostOf(rx_PeerOf(cstruct->conns[i])); | |
215 | if (!nconns) { | |
216 | printf("probing"); | |
217 | } | |
218 | printf(" %s", afs_inet_ntoa_r(addr, hoststr)); | |
219 | } | |
220 | if (nconns == 0) { | |
221 | printf("no connections\n"); | |
222 | return 255; | |
223 | } | |
224 | printf("\n"); | |
225 | multi_Rx(cstruct->conns, nconns) { | |
226 | multi_VL_ProbeServer(); | |
227 | addr = rx_HostOf(rx_PeerOf(cstruct->conns[multi_i])); | |
228 | if (!multi_error) { | |
229 | printf(" ok: %s\n", afs_inet_ntoa_r(addr, hoststr)); | |
230 | } else { | |
231 | status = 255; | |
232 | printf(" not ok (%d): %s\n", multi_error, | |
233 | afs_inet_ntoa_r(addr, hoststr)); | |
234 | } | |
235 | } | |
236 | multi_End; | |
237 | return status; | |
238 | } | |
239 | ||
240 | if (as->parms[5].items) { /* -getstats */ | |
241 | vldstats stats; | |
242 | vital_vlheader vital_header; | |
243 | code = ubik_VL_GetStats(cstruct, 0, &stats, &vital_header); | |
244 | if (!code) | |
245 | dump_stats(&stats, &vital_header); | |
246 | exit(0); | |
247 | } | |
248 | ||
249 | while (1) { | |
250 | char line[500]; | |
251 | int nargs, releasetype; | |
252 | memset(&entry, 0, sizeof(entry)); | |
253 | memset(&updateentry, 0, sizeof(updateentry)); | |
254 | memset(&listbyattributes, 0, sizeof(listbyattributes)); | |
255 | printf("vl> "); | |
256 | if (fgets(line, 499, stdin) == NULL) { | |
257 | printf("\n"); | |
258 | exit(0); | |
259 | } else { | |
260 | char *oper, *vname; | |
261 | char **argp = args; | |
262 | ||
263 | GetArgs(line, argp, &nargs); | |
264 | oper = &argp[0][0]; | |
265 | ++argp, --nargs; | |
266 | if (!*line) { | |
267 | } else if (!strcmp(oper, "cr")) { | |
268 | fill_entry(&entry, argp, nargs); | |
269 | display_entry(&entry, 0); | |
270 | code = ubik_VL_CreateEntry(cstruct, 0, &entry); | |
271 | printf("return code is %d\n", code); | |
272 | } else if (!strcmp(oper, "rm")) { | |
273 | sscanf(&(*argp)[0], "%d", &id); | |
274 | ++argp, --nargs; | |
275 | sscanf(&(*argp)[0], "%d", &voltype); | |
276 | code = ubik_VL_DeleteEntry(cstruct, 0, id, voltype); | |
277 | printf("return code is %d\n", code); | |
278 | } else if (!strcmp(oper, "re")) { | |
279 | sscanf(&(*argp)[0], "%d", &id); | |
280 | ++argp, --nargs; | |
281 | sscanf(&(*argp)[0], "%d", &voltype); | |
282 | ++argp, --nargs; | |
283 | sscanf(&(*argp)[0], "%d", &releasetype); | |
284 | ++argp, --nargs; | |
285 | fill_entry(&entry, argp, nargs); | |
286 | display_entry(&entry, 0); | |
287 | code = | |
288 | ubik_VL_ReplaceEntry( | |
289 | cstruct, 0, id, voltype, | |
290 | &entry, releasetype); | |
291 | printf("return code is %d\n", code); | |
292 | } else if (!strcmp(oper, "up")) { | |
293 | sscanf(&(*argp)[0], "%d", &id); | |
294 | ++argp, --nargs; | |
295 | sscanf(&(*argp)[0], "%d", &voltype); | |
296 | ++argp, --nargs; | |
297 | sscanf(&(*argp)[0], "%d", &releasetype); | |
298 | ++argp, --nargs; | |
299 | fill_update_entry(&updateentry, argp, nargs); | |
300 | display_update_entry(&updateentry, 0); | |
301 | code = | |
302 | ubik_VL_UpdateEntry(cstruct, 0, id, voltype, | |
303 | &updateentry, releasetype); | |
304 | printf("return code is %d\n", code); | |
305 | } else if (!strcmp(oper, "ls")) { | |
306 | afs_int32 index, count, next_index; | |
307 | for (index = 0; 1; index = next_index) { | |
308 | memset(&entry, 0, sizeof(entry)); | |
309 | code = | |
310 | ubik_VL_ListEntry(cstruct, 0, index, &count, | |
311 | &next_index, &entry); | |
312 | if (code) { | |
313 | printf("VL_ListEntry returned code = %d\n", code); | |
314 | break; | |
315 | } | |
316 | if (!next_index) | |
317 | break; | |
318 | display_entry(&entry, 0); | |
319 | } | |
320 | } else if (!strcmp(oper, "ldups")) { | |
321 | afs_int32 index, count, num = 0, num1 = 0, next_index; | |
322 | struct Vlent *vl1; | |
323 | ||
324 | VL = SVL = malloc(ALLOCNT * sizeof(struct Vlent)); | |
325 | if (VL == NULL) { | |
326 | printf("Can't allocate memory...\n"); | |
327 | exit(1); | |
328 | } | |
329 | printf("Enumerating all entries in vldb...\n"); | |
330 | for (index = 0; 1; index = next_index) { | |
331 | memset(&entry, 0, sizeof(entry)); | |
332 | code = | |
333 | ubik_VL_ListEntry(cstruct, 0, index, &count, | |
334 | &next_index, &entry); | |
335 | if (code) { | |
336 | printf("VL_ListEntry returned code = %d\n", code); | |
337 | break; | |
338 | } | |
339 | if (!next_index) | |
340 | break; | |
341 | num++; | |
342 | if ((vl1 = GetVolume(entry.volumeId[0], &entry))) { | |
343 | num1++; | |
344 | printf | |
345 | ("Duplicate entry is found for RW vol %u: [RW %u, RO %u, BA %u, name=%s]\n", | |
346 | entry.volumeId[0], vl1->rwid, vl1->roid, | |
347 | vl1->baid, vl1->name); | |
348 | } | |
349 | if ((vl1 = GetVolume(entry.volumeId[1], &entry))) { | |
350 | num1++; | |
351 | printf | |
352 | ("Duplicate entry is found for RO vol %u: [RW %u, RO %u, BA %u, name=%s]\n", | |
353 | entry.volumeId[1], vl1->rwid, vl1->roid, | |
354 | vl1->baid, vl1->name); | |
355 | } | |
356 | if ((vl1 = GetVolume(entry.volumeId[2], &entry))) { | |
357 | num1++; | |
358 | printf | |
359 | ("Duplicate entry is found for BA vol %u: [RW %u, RO %u, BA %u, name=%s]\n", | |
360 | entry.volumeId[2], vl1->rwid, vl1->roid, | |
361 | vl1->baid, vl1->name); | |
362 | } | |
363 | /*display_entry(&entry, 0); */ | |
364 | } | |
365 | printf("(%d vldb entries found - %d duplicates)\n", num, | |
366 | num1); | |
367 | } else if (!strcmp(oper, "checkhash")) { | |
368 | int index, count, num = 0, num1 = 0, num2 = 0, num3 = | |
369 | 0, num31 = 0, num4 = 0, num41 = 0, next_index; | |
370 | struct vldbentry tentry; | |
371 | ||
372 | VL = SVL = malloc(ALLOCNT * sizeof(struct Vlent)); | |
373 | if (VL == NULL) { | |
374 | printf("Can't allocate memory...\n"); | |
375 | exit(1); | |
376 | } | |
377 | printf("Volumes not found in main hash tables in vldb...\n"); | |
378 | for (index = 0; 1; index = next_index) { | |
379 | memset(&entry, 0, sizeof(entry)); | |
380 | code = | |
381 | ubik_VL_ListEntry(cstruct, 0, index, &count, | |
382 | &next_index, &entry); | |
383 | if (code) { | |
384 | printf("VL_ListEntry returned code = %d\n", code); | |
385 | break; | |
386 | } | |
387 | if (!next_index) | |
388 | break; | |
389 | num++; | |
390 | code = | |
391 | ubik_VL_GetEntryByNameO(cstruct, 0, entry.name, | |
392 | &tentry); | |
393 | if (code == VL_NOENT) { | |
394 | num1++; | |
395 | printf("\tVolume %s %d (not in namehash)\n", | |
396 | entry.name, entry.volumeId[RWVOL]); | |
397 | } | |
398 | code = | |
399 | ubik_VL_GetEntryByID(cstruct, 0, | |
400 | entry.volumeId[RWVOL], RWVOL, &tentry); | |
401 | if (code == VL_NOENT) { | |
402 | num2++; | |
403 | printf("\tVolume %s %d (not in rwid hash)\n", | |
404 | entry.name, entry.volumeId[RWVOL]); | |
405 | } | |
406 | if (entry.volumeId[BACKVOL]) { | |
407 | code = | |
408 | ubik_VL_GetEntryByID(cstruct, 0, | |
409 | entry.volumeId[BACKVOL], BACKVOL, | |
410 | &tentry); | |
411 | num31++; | |
412 | if (code == VL_NOENT) { | |
413 | num3++; | |
414 | printf("\tVolume %s %d (not in backup id hash)\n", | |
415 | entry.name, entry.volumeId[BACKVOL]); | |
416 | } | |
417 | } | |
418 | if (entry.volumeId[ROVOL]) { | |
419 | code = | |
420 | ubik_VL_GetEntryByID(cstruct, 0, | |
421 | entry.volumeId[ROVOL], ROVOL, &tentry); | |
422 | num41++; | |
423 | if (code == VL_NOENT) { | |
424 | num4++; | |
425 | printf("\tVolume %s %d (not in RO id hash)\n", | |
426 | entry.name, entry.volumeId[ROVOL]); | |
427 | } | |
428 | } | |
429 | } | |
430 | printf | |
431 | ("\nTotal vldb entries %d\nTotal volumes %d (%d rw, %d backup, %d ro)\n", | |
432 | num, num + num31 + num41, num, num31, num41); | |
433 | printf | |
434 | ("\n\t%d didn't hash properly by name\n\t%d didn't hash properly by rw volid\n", | |
435 | num1, num2); | |
436 | printf | |
437 | ("\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", | |
438 | num3, num31, num4, num41); | |
439 | } else if (!strcmp(oper, "fixhash")) { | |
440 | int index, count, num = 0, num1 = 0, num2 = 0, next_index, x = | |
441 | 0; | |
442 | struct vldbentry tentry; | |
443 | ||
444 | VL = SVL = malloc(ALLOCNT * sizeof(struct Vlent)); | |
445 | if (VL == NULL) { | |
446 | printf("Can't allocate memory...\n"); | |
447 | exit(1); | |
448 | } | |
449 | printf | |
450 | ("Volumes not found in main hash tables in vldb will be fixed...\n"); | |
451 | memset(&updateentry, 0, sizeof(updateentry)); | |
452 | for (index = 0; 1; index = next_index) { | |
453 | memset(&entry, 0, sizeof(entry)); | |
454 | code = | |
455 | ubik_VL_ListEntry(cstruct, 0, index, &count, | |
456 | &next_index, &entry); | |
457 | if (code) { | |
458 | printf("VL_ListEntry returned code = %d\n", code); | |
459 | break; | |
460 | } | |
461 | if (!next_index) | |
462 | break; | |
463 | num++; | |
464 | code = | |
465 | ubik_VL_GetEntryByNameO(cstruct, 0, entry.name, | |
466 | &tentry); | |
467 | if (code == VL_NOENT) { | |
468 | num1++; | |
469 | updateentry.Mask = VLUPDATE_VOLNAMEHASH; | |
470 | printf("\tVolume %s %d (not in namehash)\n", | |
471 | entry.name, entry.volumeId[RWVOL]); | |
472 | code = | |
473 | ubik_VL_UpdateEntry(cstruct, 0, | |
474 | entry.volumeId[RWVOL], -1, &updateentry, | |
475 | 0); | |
476 | if (code) { | |
477 | x++; | |
478 | printf("\tFailed to update volume %s (err=%d)\n", | |
479 | entry.name, code); | |
480 | } | |
481 | } | |
482 | code = | |
483 | ubik_VL_GetEntryByID(cstruct, 0, | |
484 | entry.volumeId[RWVOL], RWVOL, &tentry); | |
485 | if (code == VL_NOENT) { | |
486 | num1++; | |
487 | num2++; | |
488 | updateentry.Mask = VLUPDATE_RWID; | |
489 | updateentry.spares3 = entry.volumeId[RWVOL]; | |
490 | printf("\tVolume %s %d (not in rw id hash)\n", | |
491 | entry.name, entry.volumeId[RWVOL]); | |
492 | code = | |
493 | ubik_VL_UpdateEntryByName(cstruct, 0, | |
494 | entry.name, &updateentry, 0); | |
495 | if (code) { | |
496 | printf("\tFailed to update volume %s (err=%d)\n", | |
497 | entry.name, code); | |
498 | x++; | |
499 | } | |
500 | x++; | |
501 | } | |
502 | if (entry.volumeId[BACKVOL]) { | |
503 | code = | |
504 | ubik_VL_GetEntryByID(cstruct, 0, | |
505 | entry.volumeId[BACKVOL], BACKVOL, | |
506 | &tentry); | |
507 | if (code == VL_NOENT) { | |
508 | num1++; | |
509 | updateentry.Mask = VLUPDATE_BACKUPID; | |
510 | updateentry.BackupId = entry.volumeId[BACKVOL]; | |
511 | printf("\tVolume %s %d (not in backup id hash)\n", | |
512 | entry.name, entry.volumeId[BACKVOL]); | |
513 | code = | |
514 | ubik_VL_UpdateEntry(cstruct, 0, | |
515 | entry.volumeId[RWVOL], -1, | |
516 | &updateentry, 0); | |
517 | if (code) { | |
518 | printf | |
519 | ("\tFailed to update volume %s (err=%d)\n", | |
520 | entry.name, code); | |
521 | x++; | |
522 | } | |
523 | } | |
524 | } | |
525 | if (entry.volumeId[ROVOL]) { | |
526 | code = | |
527 | ubik_VL_GetEntryByID(cstruct, 0, | |
528 | entry.volumeId[ROVOL], ROVOL, &tentry); | |
529 | if (code == VL_NOENT) { | |
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_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_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(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_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(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_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((struct vldbentry *) &vllist->VldbEntry, 0); | |
630 | free(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_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((struct vldbentry *)&vllist->VldbEntry, 0); | |
652 | free(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_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_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_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_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_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_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 | unsigned int newvolid; | |
740 | sscanf(&(*argp)[0], "%d", &id); | |
741 | code = | |
742 | ubik_VL_GetNewVolumeId(cstruct, 0, id, &newvolid); | |
743 | if (!code) | |
744 | printf("Current Max volid is (in hex):0x%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_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_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(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_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 | memset(&attrs, 0, sizeof(attrs)); | |
807 | attrs.Mask = VLADDR_INDEX; | |
808 | mhaddrs.bulkaddrs_val = 0; | |
809 | mhaddrs.bulkaddrs_len = 0; | |
810 | attrs.index = *addrp & 0x00ffffff; | |
811 | ||
812 | code = | |
813 | ubik_VL_GetAddrsU(cstruct, 0, &attrs, &uuid, | |
814 | &unique, &mhnentries, &mhaddrs); | |
815 | if (code) { | |
816 | printf("VL_GetAddrsU returned code = %d\n", code); | |
817 | continue; | |
818 | } | |
819 | printf | |
820 | (" [%d]: uuid[%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x]\n addrunique=%d, ip address(es):\n", | |
821 | attrs.index, uuid.time_low, uuid.time_mid, | |
822 | uuid.time_hi_and_version, | |
823 | uuid.clock_seq_hi_and_reserved, | |
824 | uuid.clock_seq_low, uuid.node[0], uuid.node[1], | |
825 | uuid.node[2], uuid.node[3], uuid.node[4], | |
826 | uuid.node[5], unique); | |
827 | mhaddrp = mhaddrs.bulkaddrs_val; | |
828 | for (j = 0; j < mhnentries; j++) { | |
829 | mhaddrp[j] = ntohl(mhaddrp[j]); | |
830 | hostAddr.s_addr = mhaddrp[j]; | |
831 | printf("\t%s (%s)\n", inet_ntoa(hostAddr), | |
832 | hostutil_GetNameByINet(mhaddrp[j])); | |
833 | } | |
834 | if (mhaddrs.bulkaddrs_val) | |
835 | free(mhaddrs.bulkaddrs_val); | |
836 | } else { | |
837 | printf("[0x%x %u] %s\n", *addrp, *addrp, | |
838 | hostutil_GetNameByINet(ntohl(*addrp))); | |
839 | } | |
840 | } | |
841 | free(addrs.bulkaddrs_val); | |
842 | } else if (!strcmp(oper, "mhc")) { | |
843 | afs_uint32 serveraddrs[MAXSERVERID + 1][VL_MAXIPADDRS_PERMH]; | |
844 | afs_int32 serveraddrtype[MAXSERVERID + 1]; | |
845 | int nentries1, nentries2, i, j, x, y, unique, found; | |
846 | afs_uint32 *addrp1, *addrp2; | |
847 | bulkaddrs addrs1, addrs2; | |
848 | struct VLCallBack vlcb; | |
849 | ListAddrByAttributes attrs; | |
850 | afsUUID uuid; | |
851 | afs_int32 base, index; | |
852 | ||
853 | for (i = 0; i < MAXSERVERID + 1; i++) { | |
854 | serveraddrtype[i] = 0; | |
855 | for (j = 0; j < VL_MAXIPADDRS_PERMH; j++) | |
856 | serveraddrs[i][j] = 0; | |
857 | } | |
858 | ||
859 | /* Collect a list of all registered IP addresses */ | |
860 | addrs1.bulkaddrs_val = 0; | |
861 | addrs1.bulkaddrs_len = 0; | |
862 | code = | |
863 | ubik_VL_GetAddrs(cstruct, 0, 0, 0, &vlcb, | |
864 | &nentries1, &addrs1); | |
865 | if (code) { | |
866 | printf("VL_GetAddrs returned code = %d\n", code); | |
867 | continue; | |
868 | } | |
869 | addrp1 = addrs1.bulkaddrs_val; | |
870 | for (i = 0; i < nentries1; i++, addrp1++) { | |
871 | if ((*addrp1 & 0xff000000) != 0xff000000) { | |
872 | serveraddrs[i][0] = ntohl(*addrp1); | |
873 | serveraddrtype[i] = 1; | |
874 | } else { | |
875 | /* It's multihomed. Get all of its addresses */ | |
876 | serveraddrtype[i] = 2; | |
877 | base = (*addrp1 >> 16) & 0xff; | |
878 | index = *addrp1 & 0xffff; | |
879 | ||
880 | addrs2.bulkaddrs_val = 0; | |
881 | addrs2.bulkaddrs_len = 0; | |
882 | memset(&attrs, 0, sizeof(attrs)); | |
883 | attrs.Mask = VLADDR_INDEX; | |
884 | attrs.index = (base * VL_MHSRV_PERBLK) + index; | |
885 | code = | |
886 | ubik_VL_GetAddrsU(cstruct, 0, &attrs, &uuid, | |
887 | &unique, &nentries2, &addrs2); | |
888 | if (code) { | |
889 | printf("VL_GetAddrsU returned code = %d\n", code); | |
890 | break; | |
891 | } | |
892 | ||
893 | addrp2 = addrs2.bulkaddrs_val; | |
894 | for (j = 0; j < nentries2; j++) { | |
895 | serveraddrs[i][j] = ntohl(addrp2[j]); | |
896 | } | |
897 | free(addrs2.bulkaddrs_val); | |
898 | } | |
899 | ||
900 | if (nargs) { | |
901 | if (serveraddrtype[i] == 1) { | |
902 | printf("%u\n", serveraddrs[i][0]); | |
903 | } else { | |
904 | printf("["); | |
905 | for (j = 0; j < VL_MAXIPADDRS_PERMH; j++) | |
906 | if (serveraddrs[i][j]) | |
907 | printf(" %u", serveraddrs[i][j]); | |
908 | printf(" ]\n"); | |
909 | } | |
910 | } | |
911 | } | |
912 | free(addrs1.bulkaddrs_val); | |
913 | ||
914 | /* Look for any duplicates */ | |
915 | for (i = 0; i < MAXSERVERID + 1; i++) { | |
916 | if (!serveraddrtype[i]) | |
917 | continue; | |
918 | for (j = 0; j < VL_MAXIPADDRS_PERMH; j++) { | |
919 | if (!serveraddrs[i][j]) | |
920 | continue; | |
921 | ||
922 | found = 0; | |
923 | for (x = i + 1; x < MAXSERVERID + 1; x++) { | |
924 | if (!serveraddrtype[x]) | |
925 | continue; | |
926 | for (y = 0; y < VL_MAXIPADDRS_PERMH; y++) { | |
927 | if (!serveraddrs[x][y]) | |
928 | continue; | |
929 | if (serveraddrs[i][j] == serveraddrs[x][y]) { | |
930 | serveraddrs[x][y] = 0; | |
931 | found++; | |
932 | } | |
933 | } | |
934 | } | |
935 | if (found) { | |
936 | printf | |
937 | ("Found %d entries of IP address %u (0x%x)\n", | |
938 | found + 1, serveraddrs[i][j], | |
939 | serveraddrs[i][j]); | |
940 | } | |
941 | } | |
942 | } | |
943 | ||
944 | /*----------------------------------------*/ | |
945 | ||
946 | } else if (!strcmp(oper, "regaddr")) { | |
947 | int i; | |
948 | afs_uint32 *addrp, tad; | |
949 | bulkaddrs addrs; | |
950 | afsUUID uuid; | |
951 | ||
952 | memset(&uuid, 0, sizeof(uuid)); | |
953 | sscanf(&(*argp)[0], "%d", &i); | |
954 | ++argp, --nargs; | |
955 | memcpy(uuid.node, &i, sizeof(i)); | |
956 | ||
957 | if (nargs < 0 || nargs > 16) { | |
958 | printf("Illegal # entries = %d\n", nargs); | |
959 | continue; | |
960 | } | |
961 | addrp = malloc(20 * 4); | |
962 | addrs.bulkaddrs_val = addrp; | |
963 | addrs.bulkaddrs_len = nargs; | |
964 | while (nargs > 0) { | |
965 | sscanf(&(*argp)[0], "%d", &tad); | |
966 | *addrp++ = tad; | |
967 | ++argp, --nargs; | |
968 | } | |
969 | code = | |
970 | ubik_VL_RegisterAddrs(cstruct, 0, &uuid, | |
971 | 0 /*spare */ , &addrs); | |
972 | if (code) { | |
973 | printf("VL_RegisterAddrs returned code = %d\n", code); | |
974 | continue; | |
975 | } | |
976 | } else if (!strcmp(oper, "ca")) { | |
977 | struct hostent *h1, *h2; | |
978 | afs_uint32 a1, a2; | |
979 | ||
980 | printf("changing %s", *argp); | |
981 | h1 = hostutil_GetHostByName(&(*argp)[0]); | |
982 | if (!h1) { | |
983 | printf("cmdebug: can't resolve address for host %s", | |
984 | *argp); | |
985 | continue; | |
986 | } | |
987 | memcpy(&a1, (afs_int32 *) h1->h_addr, sizeof(afs_uint32)); | |
988 | ||
989 | ++argp, --nargs; | |
990 | printf(" to %s\n", *argp); | |
991 | h2 = hostutil_GetHostByName(&(*argp)[0]); | |
992 | if (!h2) { | |
993 | printf("cmdebug: can't resolve address for host %s", | |
994 | *argp); | |
995 | continue; | |
996 | } | |
997 | memcpy(&a2, (afs_int32 *) h2->h_addr, sizeof(afs_uint32)); | |
998 | ||
999 | printf("changing 0x%x to 0x%x\n", ntohl(a1), ntohl(a2)); | |
1000 | code = | |
1001 | ubik_VL_ChangeAddr(cstruct, 0, ntohl(a1), | |
1002 | ntohl(a2)); | |
1003 | if (code) { | |
1004 | printf("VL_ChangeAddr returned code = %d\n", code); | |
1005 | continue; | |
1006 | } | |
1007 | } else if (!strcmp(oper, "caid")) { | |
1008 | afs_uint32 a1, a2; | |
1009 | ||
1010 | sscanf(&(*argp)[0], "%d", &a1); | |
1011 | printf("changing %d (0x%x)", a1, a1); | |
1012 | ++argp, --nargs; | |
1013 | sscanf(&(*argp)[0], "%d", &a2); | |
1014 | printf(" to %d (0x%x)\n", a2, a2); | |
1015 | code = ubik_VL_ChangeAddr(cstruct, 0, a1, a2); | |
1016 | if (code) { | |
1017 | printf("VL_ChangeAddr returned code = %d\n", code); | |
1018 | continue; | |
1019 | } | |
1020 | } else if ((!strcmp(oper, "?")) || !strcmp(oper, "h") || !strcmp(oper, "help")) | |
1021 | print_usage(); | |
1022 | else if ((!strcmp(oper, "q")) || !strcmp(oper, "quit")) | |
1023 | exit(0); | |
1024 | else { | |
1025 | printf("Unknown oper (%s)!\n", oper); | |
1026 | print_usage(); | |
1027 | } | |
1028 | } | |
1029 | } | |
1030 | } | |
1031 | ||
1032 | ||
1033 | #include "AFS_component_version_number.c" | |
1034 | ||
1035 | int | |
1036 | main(int argc, char **argv) | |
1037 | { | |
1038 | struct cmd_syndesc *ts; | |
1039 | afs_int32 code; | |
1040 | ||
1041 | strcpy(confdir, AFSDIR_CLIENT_ETC_DIRPATH); | |
1042 | ts = cmd_CreateSyntax("initcmd", handleit, NULL, 0, "initialize the program"); | |
1043 | cmd_AddParm(ts, "-cellpath", CMD_LIST, CMD_OPTIONAL, | |
1044 | "Cell configuration directory"); | |
1045 | cmd_AddParm(ts, "-server", CMD_LIST, CMD_OPTIONAL, | |
1046 | "Use the cell config in /usr/afs/etc (default /usr/vice/etc)"); | |
1047 | cmd_AddParm(ts, "-noauth", CMD_FLAG, CMD_OPTIONAL, | |
1048 | "Run it without authentication"); | |
1049 | cmd_AddParm(ts, "-host", CMD_LIST, CMD_OPTIONAL, | |
1050 | "vldb server to talk to"); | |
1051 | cmd_AddParm(ts, "-cell", CMD_LIST, CMD_OPTIONAL, | |
1052 | "cellname '-host' belongs to (required for auth conns)"); | |
1053 | cmd_AddParm(ts, "-getstats", CMD_FLAG, CMD_OPTIONAL, | |
1054 | "print vldb statistics (non interactive)"); | |
1055 | cmd_AddParm(ts, "-probe", CMD_FLAG, CMD_OPTIONAL, | |
1056 | "probe vldb servers, use with -host to probe only one. (non interactive)"); | |
1057 | code = cmd_Dispatch(argc, argv); | |
1058 | exit(code); | |
1059 | } | |
1060 | ||
1061 | ||
1062 | void | |
1063 | fill_entry(struct vldbentry *entry, char **argp, 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], "%u", &entry->volumeId[i]); | |
1089 | } | |
1090 | ++argp, --nargs; | |
1091 | sscanf(&(*argp)[0], "%d", &entry->flags); | |
1092 | ++argp, --nargs; | |
1093 | sscanf(&(*argp)[0], "%u", &entry->cloneId); | |
1094 | } | |
1095 | ||
1096 | void | |
1097 | fill_update_entry(struct VldbUpdateEntry *entry, char **argp, int nargs) | |
1098 | { | |
1099 | int i, Mask; | |
1100 | char *name; | |
1101 | ||
1102 | entry->Mask = 0; | |
1103 | name = &argp[0][0]; | |
1104 | if (strcmp(name, "null")) { | |
1105 | strcpy(entry->name, name); | |
1106 | entry->Mask |= VLUPDATE_VOLUMENAME; | |
1107 | } | |
1108 | ++argp, --nargs; | |
1109 | sscanf(&(*argp)[0], "%d", &entry->flags); | |
1110 | if (entry->flags != -1) | |
1111 | entry->Mask |= VLUPDATE_FLAGS; | |
1112 | ++argp, --nargs; | |
1113 | sscanf(&(*argp)[0], "%u", &entry->cloneId); | |
1114 | if (entry->flags != -1) | |
1115 | entry->Mask |= VLUPDATE_CLONEID; | |
1116 | ++argp, --nargs; | |
1117 | sscanf(&(*argp)[0], "%u", &entry->ReadOnlyId); | |
1118 | if (entry->ReadOnlyId != -1) | |
1119 | entry->Mask |= VLUPDATE_READONLYID; | |
1120 | ++argp, --nargs; | |
1121 | sscanf(&(*argp)[0], "%u", &entry->BackupId); | |
1122 | if (entry->BackupId != -1) | |
1123 | entry->Mask |= VLUPDATE_BACKUPID; | |
1124 | ++argp, --nargs; | |
1125 | sscanf(&(*argp)[0], "%d", &entry->nModifiedRepsites); | |
1126 | if (entry->nModifiedRepsites != -1) | |
1127 | entry->Mask |= VLUPDATE_REPSITES; | |
1128 | for (i = 0; i < entry->nModifiedRepsites; i++) { | |
1129 | ++argp, --nargs; | |
1130 | sscanf(&(*argp)[0], "%x", &Mask); | |
1131 | ++argp, --nargs; | |
1132 | sscanf(&(*argp)[0], "%u", &entry->RepsitesTargetServer[i]); | |
1133 | ++argp, --nargs; | |
1134 | sscanf(&(*argp)[0], "%d", &entry->RepsitesTargetPart[i]); | |
1135 | if (Mask & VLUPDATE_REPS_DELETE) | |
1136 | entry->RepsitesMask[i] |= VLUPDATE_REPS_DELETE; | |
1137 | if (Mask & VLUPDATE_REPS_MODSERV) { | |
1138 | ++argp, --nargs; | |
1139 | sscanf(&(*argp)[0], "%u", &entry->RepsitesNewServer[i]); | |
1140 | entry->RepsitesMask[i] |= VLUPDATE_REPS_MODSERV; | |
1141 | } else if (Mask & VLUPDATE_REPS_MODPART) { | |
1142 | ++argp, --nargs; | |
1143 | sscanf(&(*argp)[0], "%d", &entry->RepsitesNewPart[i]); | |
1144 | entry->RepsitesMask[i] |= VLUPDATE_REPS_MODPART; | |
1145 | } else if (Mask & VLUPDATE_REPS_MODFLAG) { | |
1146 | ++argp, --nargs; | |
1147 | sscanf(&(*argp)[0], "%d", &entry->RepsitesNewFlags[i]); | |
1148 | entry->RepsitesMask[i] |= VLUPDATE_REPS_MODFLAG; | |
1149 | } else if (Mask & VLUPDATE_REPS_ADD) { | |
1150 | ++argp, --nargs; | |
1151 | sscanf(&(*argp)[0], "%u", &entry->RepsitesNewServer[i]); | |
1152 | ++argp, --nargs; | |
1153 | sscanf(&(*argp)[0], "%d", &entry->RepsitesNewPart[i]); | |
1154 | ++argp, --nargs; | |
1155 | sscanf(&(*argp)[0], "%d", &entry->RepsitesNewFlags[i]); | |
1156 | entry->RepsitesMask[i] |= VLUPDATE_REPS_ADD; | |
1157 | } | |
1158 | } | |
1159 | } | |
1160 | ||
1161 | void | |
1162 | fill_listattributes_entry(struct VldbListByAttributes *entry, char **argp, | |
1163 | int nargs) | |
1164 | { | |
1165 | entry->Mask = 0; | |
1166 | ||
1167 | if (nargs <= 0) | |
1168 | return; | |
1169 | entry->server = ntohl(GetServer(argp[0])); | |
1170 | sscanf(&(*argp)[0], "%d", &entry->server); | |
1171 | if (entry->server != 0) | |
1172 | entry->Mask |= VLLIST_SERVER; | |
1173 | ++argp, --nargs; | |
1174 | ||
1175 | if (nargs <= 0) | |
1176 | return; | |
1177 | sscanf(&(*argp)[0], "%d", &entry->partition); | |
1178 | if (entry->partition != -1) | |
1179 | entry->Mask |= VLLIST_PARTITION; | |
1180 | ++argp, --nargs; | |
1181 | ||
1182 | if (nargs <= 0) | |
1183 | return; | |
1184 | sscanf(&(*argp)[0], "%d", &entry->volumeid); | |
1185 | if (entry->volumeid != -1) | |
1186 | entry->Mask |= VLLIST_VOLUMEID; | |
1187 | ++argp, --nargs; | |
1188 | ||
1189 | if (nargs <= 0) | |
1190 | return; | |
1191 | sscanf(&(*argp)[0], "%d", &entry->flag); | |
1192 | if (entry->flag != -1) | |
1193 | entry->Mask |= VLLIST_FLAG; | |
1194 | } | |
1195 | ||
1196 | void | |
1197 | display_listattributes_entry(struct VldbListByAttributes *entry, int error) | |
1198 | { | |
1199 | if (error) | |
1200 | return; | |
1201 | printf("\nList entry values (Mask=%x)\n", entry->Mask); | |
1202 | if (entry->Mask & VLLIST_SERVER) | |
1203 | printf("\tServer: %d.%d.%d.%d\n", (entry->server >> 24) & 0xff, | |
1204 | (entry->server >> 16) & 0xff, (entry->server >> 8) & 0xff, | |
1205 | (entry->server) & 0xff); | |
1206 | if (entry->Mask & VLLIST_PARTITION) | |
1207 | printf("\tPartition: %d\n", entry->partition); | |
1208 | if (entry->Mask & VLLIST_VOLUMEID) | |
1209 | printf("\tVolumeId: %u\n", entry->volumeid); | |
1210 | if (entry->Mask & VLLIST_FLAG) | |
1211 | printf("\tFlag: %x\n", entry->flag); | |
1212 | } | |
1213 | ||
1214 | ||
1215 | #define volumetype_string(type) (type == RWVOL? "read/write":type == ROVOL? "readonly":type == BACKVOL? "backup":"unknown") | |
1216 | ||
1217 | void | |
1218 | display_entry(struct vldbentry *entry, int error) | |
1219 | { | |
1220 | int i; | |
1221 | ||
1222 | if (error) | |
1223 | return; | |
1224 | printf("\nEntry for volume name: %s, volid=%u (flags=%X) are:\n", | |
1225 | entry->name, entry->volumeId[RWVOL], entry->flags); | |
1226 | printf("ParentID=%u, ReadOnlyID=%u, backupID=%u, CloneId=%u ", | |
1227 | entry->volumeId[0], entry->volumeId[1], entry->volumeId[2], | |
1228 | entry->cloneId); | |
1229 | printf("nServers=%d\n", entry->nServers); | |
1230 | printf("ServerNumber\tServerPart\tserverFlag\n"); | |
1231 | for (i = 0; i < entry->nServers; i++) | |
1232 | printf("%12u\t%10d\t%10x\n", entry->serverNumber[i], | |
1233 | entry->serverPartition[i], entry->serverFlags[i]); | |
1234 | } | |
1235 | ||
1236 | void | |
1237 | display_entryN(struct nvldbentry *entry, int error) | |
1238 | { | |
1239 | int i, et, ei; | |
1240 | ||
1241 | if (error) | |
1242 | return; | |
1243 | printf("\nEntry for volume name: %s, volid=%u (flags=%X) are:\n", | |
1244 | entry->name, entry->volumeId[RWVOL], entry->flags); | |
1245 | printf("ParentID=%u, ReadOnlyID=%u, backupID=%u, CloneId=%u ", | |
1246 | entry->volumeId[0], entry->volumeId[1], entry->volumeId[2], | |
1247 | entry->cloneId); | |
1248 | printf("nServers=%d\n", entry->nServers); | |
1249 | printf("ServerNumber\tServerPart\tserverFlag\n"); | |
1250 | ei = entry->matchindex & 0xffff; | |
1251 | et = (entry->matchindex >> 16) & 0xffff; | |
1252 | for (i = 0; i < entry->nServers; i++) { | |
1253 | printf("%12u\t%10d\t%10x", entry->serverNumber[i], | |
1254 | entry->serverPartition[i], entry->serverFlags[i]); | |
1255 | if (i == ei) { | |
1256 | printf(" <--- %s", (et == 4) ? "RW" : ((et == 8) ? "BK" : "RO")); | |
1257 | } | |
1258 | printf("\n"); | |
1259 | } | |
1260 | } | |
1261 | ||
1262 | void | |
1263 | display_update_entry(struct VldbUpdateEntry *entry, int error) | |
1264 | { | |
1265 | int i; | |
1266 | ||
1267 | if (error) | |
1268 | return; | |
1269 | printf("\nUpdate entry values (Mask=%x)\n", entry->Mask); | |
1270 | if (entry->Mask & VLUPDATE_VOLUMENAME) | |
1271 | printf("\tNew name: %s\n", entry->name); | |
1272 | if (entry->Mask & VLUPDATE_FLAGS) | |
1273 | printf("\tNew flags: %X\n", entry->flags); | |
1274 | if (entry->Mask & VLUPDATE_CLONEID) | |
1275 | printf("\tNew CloneId: %X\n", entry->cloneId); | |
1276 | if (entry->Mask & VLUPDATE_READONLYID) | |
1277 | printf("\tNew RO id: %d\n", entry->ReadOnlyId); | |
1278 | if (entry->Mask & VLUPDATE_BACKUPID) | |
1279 | printf("\tNew BACKUP id: %d\n", entry->BackupId); | |
1280 | if (entry->Mask & VLUPDATE_REPSITES) { | |
1281 | printf("\tRepsites info:\n"); | |
1282 | printf("\tFlag\tTServer\tTPart\tNServer\tNPart\tNFlag\n"); | |
1283 | for (i = 0; i < entry->nModifiedRepsites; i++) { | |
1284 | printf("\t%4x\t%7u\t%5d", entry->RepsitesMask[i], | |
1285 | entry->RepsitesTargetServer[i], | |
1286 | entry->RepsitesTargetPart[i]); | |
1287 | if ((entry->RepsitesMask[i] & VLUPDATE_REPS_ADD) | |
1288 | || (entry->RepsitesMask[i] & VLUPDATE_REPS_MODSERV)) | |
1289 | printf("\t%7u", entry->RepsitesNewServer[i]); | |
1290 | else | |
1291 | printf("\t-------"); | |
1292 | if ((entry->RepsitesMask[i] & VLUPDATE_REPS_ADD) | |
1293 | || (entry->RepsitesMask[i] & VLUPDATE_REPS_MODPART)) | |
1294 | printf("\t%5d", entry->RepsitesNewPart[i]); | |
1295 | else | |
1296 | printf("\t-----"); | |
1297 | if ((entry->RepsitesMask[i] & VLUPDATE_REPS_ADD) | |
1298 | || (entry->RepsitesMask[i] & VLUPDATE_REPS_MODFLAG)) | |
1299 | printf("\t%5x\n", entry->RepsitesNewFlags[i]); | |
1300 | else | |
1301 | printf("\t-----\n"); | |
1302 | } | |
1303 | } | |
1304 | } | |
1305 | ||
1306 | void | |
1307 | dump_stats(vldstats *stats, vital_vlheader *vital_header) | |
1308 | { | |
1309 | int i; | |
1310 | char strg[30]; | |
1311 | time_t start_time = stats->start_time; | |
1312 | struct tm tm; | |
1313 | ||
1314 | strftime(strg, sizeof(strg), "%a %b %d %H:%M:%S %Y", | |
1315 | localtime_r(&start_time, &tm)); | |
1316 | printf("Dynamic statistics stats (starting time: %s):\n", strg); | |
1317 | printf("OpcodeName\t# Requests\t# Aborts\n"); | |
1318 | for (i = 0; i < VL_NUMBER_OPCODESX; i++) | |
1319 | printf("%10s\t%10d\t%8d\n", opcode_names[i], stats->requests[i], | |
1320 | stats->aborts[i]); | |
1321 | printf("\nVldb header stats (version=%d)\n", | |
1322 | ntohl(vital_header->vldbversion)); | |
1323 | printf("headersize=%d, allocs=%d, frees=%d, MaxVolid=%X\n", | |
1324 | ntohl(vital_header->headersize), ntohl(vital_header->allocs), | |
1325 | ntohl(vital_header->frees), ntohl(vital_header->MaxVolumeId)); | |
1326 | for (i = 0; i < MAXTYPES; i++) | |
1327 | printf("total %s entries=%d\n", volumetype_string(i), | |
1328 | ntohl(vital_header->totalEntries[i])); | |
1329 | } | |
1330 | ||
1331 | void | |
1332 | GetArgs(char *line, char **args, int *nargs) | |
1333 | { | |
1334 | *nargs = 0; | |
1335 | while (*line) { | |
1336 | char *last = line; | |
1337 | while (isspace(*line)) | |
1338 | line++; | |
1339 | if (isspace(*last)) | |
1340 | *last = 0; | |
1341 | if (!*line) | |
1342 | break; | |
1343 | *args++ = line, (*nargs)++; | |
1344 | while (*line && !isspace(*line)) | |
1345 | line++; | |
1346 | } | |
1347 | } | |
1348 | ||
1349 | void | |
1350 | print_usage(void) | |
1351 | { | |
1352 | printf("Valid Commands:\n"); | |
1353 | ||
1354 | printf(" CreateEntry:\n"); | |
1355 | printf | |
1356 | ("\tcr <vname> <vtype> <#S> <Saddr1>.<Saddrn> <Spart1>.<Spartn> <Sflag1>.<Sflagn> <Volid1-3> <flag>\n"); | |
1357 | ||
1358 | printf(" DeleteEntry:\n"); | |
1359 | printf("\trm <volid> <voltype>\n"); | |
1360 | ||
1361 | printf(" ReplaceEntry:\n"); | |
1362 | printf("\tre <volid> <voltype> <New vldb entry ala 'cr'>\n"); | |
1363 | ||
1364 | printf(" UpdateEntry:\n"); | |
1365 | printf | |
1366 | ("\tup <volid> <voltype> <vname> <vtype> <#AddSer> [<Saddr1>.<Saddrn> <Spart1>.<Spartn> <Sflag1>.<Sflagn>] <Volid1-3> <flag>\n"); | |
1367 | ||
1368 | printf(" ListEntry:\n"); | |
1369 | printf("\tls\n"); | |
1370 | ||
1371 | printf(" Find duplicate entries of a volume\n"); | |
1372 | printf("\tldups\n"); | |
1373 | ||
1374 | printf(" For each vlentry, find it by name, RW id, BK id, and RO id\n"); | |
1375 | printf("\tcheckhash\n"); | |
1376 | ||
1377 | printf | |
1378 | (" UpdateEntry (update the volname, RW id, BK id, RO id hashes):\n"); | |
1379 | printf("\tfixhash\n"); | |
1380 | ||
1381 | printf(" ListAttributes:\n"); | |
1382 | printf("\tla [server] [partition] [volumeid] [flag]\n"); | |
1383 | ||
1384 | printf(" ListAttributesN2:\n"); | |
1385 | printf("\tlan2 [volname] [server] [partition] [volumeid] [flag]\n"); | |
1386 | ||
1387 | printf(" GetEntryByID:\n"); | |
1388 | printf("\tdi <volid> <voltype>\n"); | |
1389 | ||
1390 | printf(" UpdateEntry (refresh namehash table):\n"); | |
1391 | printf("\trmnh <volid> <voltype>\n"); | |
1392 | ||
1393 | printf(" GetEntryByName:\n"); | |
1394 | printf("\tdn <volname> <voltype>\n"); | |
1395 | ||
1396 | printf(" UpdateEntry (undelete a vol entry):\n"); | |
1397 | printf("\tundelete <volid> <voltype>\n"); | |
1398 | /* | |
1399 | * printf(" LinkedList\n"); | |
1400 | * printf("\t:ln [server] [partition] [volumeid] [flag]\n"); | |
1401 | * | |
1402 | * printf(" LinkedListN\n"); | |
1403 | * printf("\t:lnn [server] [partition] [volumeid] [flag]\n"); | |
1404 | */ | |
1405 | printf(" GetNewVoumeId:\n"); | |
1406 | printf("\tnv <bump-count>\n"); | |
1407 | ||
1408 | printf(" GetStats:\n"); | |
1409 | printf("\tgs\n"); | |
1410 | ||
1411 | printf(" ChangeAddr:\n"); | |
1412 | printf("\tca <oldmachname> <newmachname>\n"); | |
1413 | ||
1414 | /* | |
1415 | * printf(" ChangeAddr\n"); | |
1416 | * printf("\t:caid <oldaddr> <newaddr>\n"); | |
1417 | */ | |
1418 | printf(" GetAddrs:\n"); | |
1419 | printf("\tga\n"); | |
1420 | ||
1421 | printf(" GetAddrsU:\n"); | |
1422 | printf("\tgau\n"); | |
1423 | ||
1424 | printf(" RegisterAddrs:\n"); | |
1425 | printf("\tregaddr uuidNumber <ip1 .. ipn>\n"); | |
1426 | ||
1427 | printf("\tmisc: q, quit, ?, h\n"); | |
1428 | } |