e37408125c3a887352474a0af026351158cd5da6
[openafs.git] / src / libadmin / test / vos.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 /*
11  * This file implements the vos related funtions for afscp
12  */
13
14 #include <afsconfig.h>
15 #include <afs/param.h>
16 #ifndef AFS_NT40_ENV
17 #include <netdb.h>
18 #include <netinet/in.h>
19 #include <arpa/inet.h>
20 #include <afs/afsutil.h>
21 #endif
22
23 RCSID
24     ("$Header$");
25
26 #include "vos.h"
27
28 /*
29  * Utility functions
30  */
31
32 /*
33  * Generic fuction for converting input string to an integer.  Pass
34  * the error_msg you want displayed if there is an error converting
35  * the string.
36  */
37
38 static unsigned int
39 GetIntFromString(const char *int_str, const char *error_msg)
40 {
41     unsigned int i;
42     char *bad_char = NULL;
43
44     i = strtoul(int_str, &bad_char, 10);
45     if ((bad_char == NULL) || (*bad_char == 0)) {
46         return i;
47     }
48
49     ERR_EXT(error_msg);
50 }
51
52 /*
53  * Generic fuction for converting input string to a volume number
54  * It will accept integer strings as well as volume names.
55  */
56
57 static unsigned int
58 GetVolumeIdFromString(const char *volume)
59 {
60     unsigned int volume_id;
61     char *bad_char = NULL;
62     afs_status_t st = 0;
63     vos_vldbEntry_t entry;
64
65     volume_id = strtoul(volume, &bad_char, 10);
66     if ((bad_char == NULL) || (*bad_char == 0)) {
67         return volume_id;
68     }
69
70     /*
71      * We failed to convert the string to a number, so see if it
72      * is a volume name
73      */
74     if (vos_VLDBGet
75         (cellHandle, 0, (const unsigned int *)0, volume, &entry, &st)) {
76         return entry.volumeId[VOS_READ_WRITE_VOLUME];
77     } else {
78         ERR_EXT("failed to convert specified volume to an id");
79     }
80 }
81
82 /*
83  * Generic fuction for converting input string to a partition number
84  * It will accept integer strings as well as partition names.
85  */
86
87 static unsigned int
88 GetPartitionIdFromString(const char *partition)
89 {
90     unsigned int partition_id;
91     char *bad_char = NULL;
92     afs_status_t st = 0;
93     char pname[20];
94     int pname_len;
95
96     partition_id = strtoul(partition, &bad_char, 10);
97     if ((bad_char == NULL) || (*bad_char == 0)) {
98         return partition_id;
99     }
100
101     /*
102      * We failed to convert the string to a number, so see if it
103      * is a partition name
104      */
105
106     pname_len = strlen(partition);
107
108     sprintf(pname, "%s", "/vicep");
109     if (pname_len <= 2) {
110         strcat(pname, partition);
111     } else if (!strncmp(partition, "/vicep", 6)) {
112         strcat(pname, partition + 6);
113     } else if (!strncmp(partition, "vicep", 5)) {
114         strcat(pname, partition + 5);
115     } else {
116         ERR_EXT("invalid partition");
117     }
118
119     if (!vos_PartitionNameToId((const char *)pname, &partition_id, &st)) {
120         ERR_ST_EXT("invalid partition", st);
121     }
122
123     return partition_id;
124 }
125
126 /*
127  * Generic fuction for converting input string to an address in host order. 
128  * It will accept strings in the form "128.98.12.1"
129  */
130
131 static int
132 GetAddressFromString(const char *addr_str)
133 {
134     int addr = inet_addr(addr_str);
135
136     if (addr == -1) {
137         ERR_EXT("failed to convert specified address");
138     }
139
140     return ntohl(addr);
141 }
142
143 static void
144 PrintMessage(vos_messageType_t type, char *message)
145 {
146     printf("%s\n", message);
147 }
148
149 int
150 DoVosBackupVolumeCreate(struct cmd_syndesc *as, void *arock)
151 {
152     typedef enum { VOLUME } DoVosBackupVolumeCreate_parm_t;
153     afs_status_t st = 0;
154     unsigned int volume_id;
155
156     if (as->parms[VOLUME].items) {
157         const char *volume = as->parms[VOLUME].items->data;
158         volume_id = GetVolumeIdFromString(volume);
159     }
160
161     if (!vos_BackupVolumeCreate(cellHandle, 0, volume_id, &st)) {
162         ERR_ST_EXT("vos_BackupVolumeCreate", st);
163     }
164     return 0;
165 }
166
167 int
168 DoVosBackupVolumeCreateMultiple(struct cmd_syndesc *as, void *arock)
169 {
170     typedef enum { SERVER, PARTITION, PREFIX,
171         EXCLUDE
172     } DoVosBackupVolumeCreate_parm_t;
173     afs_status_t st = 0;
174     void *vos_server = NULL;
175     unsigned int partition_id;
176     const unsigned int *part_ptr = NULL;
177     const char *prefix = NULL;
178     vos_exclude_t exclude = VOS_INCLUDE;
179
180     if (as->parms[SERVER].items) {
181         if (!vos_ServerOpen
182             (cellHandle, as->parms[SERVER].items->data, &vos_server, &st)) {
183             ERR_ST_EXT("vos_ServerOpen", st);
184         }
185     }
186
187     if (as->parms[PARTITION].items) {
188         partition_id =
189             GetPartitionIdFromString(as->parms[PARTITION].items->data);
190         part_ptr = &partition_id;
191     }
192
193     if (as->parms[PREFIX].items) {
194         prefix = as->parms[PREFIX].items->data;
195     }
196
197     if (as->parms[EXCLUDE].items) {
198         exclude = VOS_EXCLUDE;
199     }
200
201     if (!vos_BackupVolumeCreateMultiple
202         (cellHandle, vos_server, (vos_MessageCallBack_t) 0, part_ptr, prefix,
203          exclude, &st)) {
204         ERR_ST_EXT("vos_BackupVolumeCreate", st);
205     }
206     return 0;
207 }
208
209 static void
210 Print_vos_partitionEntry_p(vos_partitionEntry_p part, const char *prefix)
211 {
212     printf("%sInformation for partition %s\n", prefix, part->name);
213     printf("%s\tDevice name: %s\n", prefix, part->deviceName);
214     printf("%s\tlockFileDescriptor: %d\n", prefix, part->lockFileDescriptor);
215     printf("%s\tTotal space: %d\n", prefix, part->totalSpace);
216     printf("%s\tTotal Free space: %d\n", prefix, part->totalFreeSpace);
217 }
218
219 int
220 DoVosPartitionGet(struct cmd_syndesc *as, void *arock)
221 {
222     typedef enum { SERVER, PARTITION } DoVosPartitionGet_parm_t;
223     afs_status_t st = 0;
224     void *vos_server = NULL;
225     unsigned int partition_id;
226     vos_partitionEntry_t entry;
227
228     if (as->parms[SERVER].items) {
229         if (!vos_ServerOpen
230             (cellHandle, as->parms[SERVER].items->data, &vos_server, &st)) {
231             ERR_ST_EXT("vos_ServerOpen", st);
232         }
233     }
234
235     if (as->parms[PARTITION].items) {
236         partition_id =
237             GetPartitionIdFromString(as->parms[PARTITION].items->data);
238     }
239
240     if (!vos_PartitionGet
241         (cellHandle, vos_server, 0, partition_id, &entry, &st)) {
242         ERR_ST_EXT("vos_PartitionGet", st);
243     }
244
245     Print_vos_partitionEntry_p(&entry, "");
246
247     return 0;
248 }
249
250 int
251 DoVosPartitionList(struct cmd_syndesc *as, void *arock)
252 {
253     typedef enum { SERVER } DoVosPartitionGet_parm_t;
254     afs_status_t st = 0;
255     void *vos_server = NULL;
256     void *iter;
257     vos_partitionEntry_t entry;
258
259     if (as->parms[SERVER].items) {
260         if (!vos_ServerOpen
261             (cellHandle, as->parms[SERVER].items->data, &vos_server, &st)) {
262             ERR_ST_EXT("vos_ServerOpen", st);
263         }
264     }
265
266     if (!vos_PartitionGetBegin(cellHandle, vos_server, 0, &iter, &st)) {
267         ERR_ST_EXT("vos_PartitionGetBegin", st);
268     }
269
270     printf("Listing partitions at server %s\n",
271            as->parms[SERVER].items->data);
272     while (vos_PartitionGetNext(iter, &entry, &st)) {
273         Print_vos_partitionEntry_p(&entry, "    ");
274     }
275
276     if (st != ADMITERATORDONE) {
277         ERR_ST_EXT("vos_PartitionGetNext", st);
278     }
279
280     if (!vos_PartitionGetDone(iter, &st)) {
281         ERR_ST_EXT("vos_PartitionGetDone", st);
282     }
283     return 0;
284 }
285
286 int
287 DoVosServerSync(struct cmd_syndesc *as, void *arock)
288 {
289     typedef enum { SERVER, PARTITION } DoVosServerSync_parm_t;
290     afs_status_t st = 0;
291     void *vos_server = NULL;
292     unsigned int partition_id;
293     const unsigned int *part_ptr = NULL;
294
295     if (as->parms[SERVER].items) {
296         if (!vos_ServerOpen
297             (cellHandle, as->parms[SERVER].items->data, &vos_server, &st)) {
298             ERR_ST_EXT("vos_ServerOpen", st);
299         }
300     }
301
302     if (as->parms[PARTITION].items) {
303         partition_id =
304             GetPartitionIdFromString(as->parms[PARTITION].items->data);
305         part_ptr = &partition_id;
306     }
307
308     if (!vos_ServerSync(cellHandle, vos_server, 0, part_ptr, &st)) {
309         ERR_ST_EXT("vos_PartitionGetDone", st);
310     }
311     return 0;
312 }
313
314 int
315 DoVosFileServerAddressChange(struct cmd_syndesc *as, void *arock)
316 {
317     typedef enum { OLDADDRESS,
318         NEWADDRESS
319     } DoVosFileServerAddressChange_parm_t;
320     afs_status_t st = 0;
321     int old_addr, new_addr;
322
323     if (as->parms[OLDADDRESS].items) {
324         const char *addr = as->parms[OLDADDRESS].items->data;
325         old_addr = GetAddressFromString(addr);
326     }
327
328     if (as->parms[NEWADDRESS].items) {
329         const char *addr = as->parms[OLDADDRESS].items->data;
330         new_addr = GetAddressFromString(addr);
331     }
332
333     if (!vos_FileServerAddressChange(cellHandle, 0, old_addr, new_addr, &st)) {
334         ERR_ST_EXT("vos_FileServerAddressChange", st);
335     }
336     return 0;
337 }
338
339 int
340 DoVosFileServerAddressRemove(struct cmd_syndesc *as, void *arock)
341 {
342     typedef enum { ADDRESS } DoVosFileServerAddressRemove_parm_t;
343     afs_status_t st = 0;
344     int address;
345
346     if (as->parms[ADDRESS].items) {
347         const char *addr = as->parms[ADDRESS].items->data;
348         address = GetAddressFromString(addr);
349     }
350
351     if (!vos_FileServerAddressRemove(cellHandle, 0, address, &st)) {
352         ERR_ST_EXT("vos_FileServerAddressRemove", st);
353     }
354     return 0;
355 }
356
357 static void
358 Print_vos_fileServerEntry_p(vos_fileServerEntry_p serv, const char *prefix)
359 {
360     int i;
361
362     for (i = 0; i < serv->count; i++) {
363         printf("%s%x ", prefix, serv->serverAddress[i]);
364     }
365     printf("\n");
366 }
367
368 int
369 DoVosFileServerList(struct cmd_syndesc *as, void *arock)
370 {
371     afs_status_t st = 0;
372     void *iter;
373     vos_fileServerEntry_t entry;
374
375     if (!vos_FileServerGetBegin(cellHandle, 0, &iter, &st)) {
376         ERR_ST_EXT("vos_FileServerGetBegin", st);
377     }
378
379     while (vos_FileServerGetNext(iter, &entry, &st)) {
380         Print_vos_fileServerEntry_p(&entry, "");
381     }
382
383     if (st != ADMITERATORDONE) {
384         ERR_ST_EXT("vos_FileServerGetNext", st);
385     }
386
387     if (!vos_FileServerGetDone(iter, &st)) {
388         ERR_ST_EXT("vos_FileServerGetDone", st);
389     }
390
391     return 0;
392 }
393
394 static void
395 Print_vos_serverTransactionStatus_p(vos_serverTransactionStatus_p tran,
396                                     const char *prefix)
397 {
398     printf("%sTransaction id\t\t\t%d\n", prefix, tran->transactionId);
399     printf("%sLast active time\t\t\t%d\n", prefix, tran->lastActiveTime);
400     printf("%sCreation time\t\t\t%d\n", prefix, tran->creationTime);
401     printf("%sError code\t\t\t%d\n", prefix, tran->errorCode);
402     printf("%sVolume id\t\t\t\t%u\n", prefix, tran->volumeId);
403     printf("%sPartition\t\t\t\t%d\n", prefix, tran->partition);
404     printf("%sLast procedure name\t\t\t%s\n", prefix,
405            tran->lastProcedureName);
406     printf("%sNext receive packet seq num\t\t\t%d\n", prefix,
407            tran->nextReceivePacketSequenceNumber);
408     printf("%sNext send packet seq num\t\t\t%d\n", prefix,
409            tran->nextSendPacketSequenceNumber);
410     printf("%sLast receive time\t\t\t%d\n", prefix, tran->lastReceiveTime);
411     printf("%sLast send time\t\t\t%d\n", prefix, tran->lastSendTime);
412     printf("%sVolume attach mode\t\t\t%d\n", prefix, tran->volumeAttachMode);
413     printf("%sVolume active status\t\t\t%d\n", prefix,
414            tran->volumeActiveStatus);
415     printf("%sVolume tran status\t\t\t%d\n", prefix,
416            tran->volumeTransactionStatus);
417 }
418
419 int
420 DoVosServerTransactionStatusList(struct cmd_syndesc *as, void *arock)
421 {
422     typedef enum { SERVER } DoVosServerTransactionStatusList_parm_t;
423     afs_status_t st = 0;
424     void *vos_server = NULL;
425     void *iter = NULL;
426     vos_serverTransactionStatus_t tran;
427
428
429     if (as->parms[SERVER].items) {
430         if (!vos_ServerOpen
431             (cellHandle, as->parms[SERVER].items->data, &vos_server, &st)) {
432             ERR_ST_EXT("vos_ServerOpen", st);
433         }
434     }
435
436     if (!vos_ServerTransactionStatusGetBegin
437         (cellHandle, vos_server, 0, &iter, &st)) {
438         ERR_ST_EXT("vos_ServerTransactionStatusGetBegin", st);
439     }
440
441     while (vos_ServerTransactionStatusGetNext(iter, &tran, &st)) {
442         Print_vos_serverTransactionStatus_p(&tran, "");
443     }
444
445     if (st != ADMITERATORDONE) {
446         ERR_ST_EXT("vos_ServerTransactionStatusGetNext", st);
447     }
448
449     if (!vos_ServerTransactionStatusGetDone(iter, &st)) {
450         ERR_ST_EXT("vos_ServerTransactionStatusGetDone", st);
451     }
452     return 0;
453 }
454
455 static void
456 Print_vos_vldbEntry_p(vos_vldbEntry_p entry, const char *prefix)
457 {
458     int i;
459
460     printf("%sVolume entry %s\n", prefix, entry->name);
461     printf("%sNumber of servers %d\n", prefix, entry->numServers);
462     printf("%sRead write volume %u\n", prefix,
463            entry->volumeId[VOS_READ_WRITE_VOLUME]);
464     printf("%sRead only volume %u\n", prefix,
465            entry->volumeId[VOS_READ_ONLY_VOLUME]);
466     printf("%sBackup volume %u\n", prefix,
467            entry->volumeId[VOS_BACKUP_VOLUME]);
468     printf("%sClone volume %u\n", prefix, entry->cloneId);
469
470     printf("%sVolume entry status:\n", prefix);
471     if (entry->status & VOS_VLDB_ENTRY_OK) {
472         printf("%s\tVOS_VLDB_ENTRY_OK\n", prefix);
473     }
474     if (entry->status & VOS_VLDB_ENTRY_MOVE) {
475         printf("%s\tVOS_VLDB_ENTRY_MOVE\n", prefix);
476     }
477     if (entry->status & VOS_VLDB_ENTRY_RELEASE) {
478         printf("%s\tVOS_VLDB_ENTRY_RELEASE\n", prefix);
479     }
480     if (entry->status & VOS_VLDB_ENTRY_BACKUP) {
481         printf("%s\tVOS_VLDB_ENTRY_BACKUP\n", prefix);
482     }
483     if (entry->status & VOS_VLDB_ENTRY_DELETE) {
484         printf("%s\tVOS_VLDB_ENTRY_DELETE\n", prefix);
485     }
486     if (entry->status & VOS_VLDB_ENTRY_DUMP) {
487         printf("%s\tVOS_VLDB_ENTRY_DUMP\n", prefix);
488     }
489     if (entry->status & VOS_VLDB_ENTRY_LOCKED) {
490         printf("%s\tVOS_VLDB_ENTRY_LOCKED\n", prefix);
491     }
492     if (entry->status & VOS_VLDB_ENTRY_RWEXISTS) {
493         printf("%s\tVOS_VLDB_ENTRY_RWEXISTS\n", prefix);
494     }
495     if (entry->status & VOS_VLDB_ENTRY_ROEXISTS) {
496         printf("%s\tVOS_VLDB_ENTRY_ROEXISTS\n", prefix);
497     }
498     if (entry->status & VOS_VLDB_ENTRY_BACKEXISTS) {
499         printf("%s\tVOS_VLDB_ENTRY_BACKEXISTS\n", prefix);
500     }
501
502     printf("%sVolume location information for replicas:\n", prefix);
503     for (i = 0; i < entry->numServers; i++) {
504         printf("%s\tServer %x\n", prefix,
505                entry->volumeSites[i].serverAddress);
506         printf("%s\tPartition %x\n", prefix,
507                entry->volumeSites[i].serverPartition);
508         if (entry->volumeSites[i].serverFlags & VOS_VLDB_NEW_REPSITE) {
509             printf("%s\tVOS_VLDB_NEW_REPSITE\n", prefix);
510         }
511         if (entry->volumeSites[i].serverFlags & VOS_VLDB_READ_ONLY) {
512             printf("%s\tVOS_VLDB_READ_ONLY\n", prefix);
513         }
514         if (entry->volumeSites[i].serverFlags & VOS_VLDB_READ_WRITE) {
515             printf("%s\tVOS_VLDB_READ_WRITE\n", prefix);
516         }
517         if (entry->volumeSites[i].serverFlags & VOS_VLDB_BACKUP) {
518             printf("%s\tVOS_VLDB_BACKUP\n", prefix);
519         }
520         if (entry->volumeSites[i].serverFlags & VOS_VLDB_DONT_USE) {
521             printf("%s\tVOS_VLDB_DONT_USE\n", prefix);
522         }
523     }
524     printf("\n");
525 }
526
527 int
528 DoVosVLDBGet(struct cmd_syndesc *as, void *arock)
529 {
530     typedef enum { VOLUME } DoVosVLDBGet_parm_t;
531     afs_status_t st = 0;
532     vos_vldbEntry_t entry;
533     unsigned int volume_id;
534     const char *volume_name = NULL;
535
536     if (as->parms[VOLUME].items) {
537         const char *volume = as->parms[VOLUME].items->data;
538         volume_id = GetVolumeIdFromString(volume);
539     }
540
541
542     if (!vos_VLDBGet(cellHandle, 0, &volume_id, volume_name, &entry, &st)) {
543         ERR_ST_EXT("vos_VLDBGet", st);
544     }
545
546     Print_vos_vldbEntry_p(&entry, "");
547
548     return 0;
549 }
550
551 int
552 DoVosVLDBList(struct cmd_syndesc *as, void *arock)
553 {
554     typedef enum { SERVER, PARTITION } DoVosVLDBList_parm_t;
555     afs_status_t st = 0;
556     void *vos_server = NULL;
557     unsigned int partition_id;
558     unsigned int *part_ptr = NULL;
559     int have_server = 0;
560     vos_vldbEntry_t entry;
561     void *iter = NULL;
562
563     if (as->parms[SERVER].items) {
564         if (!vos_ServerOpen
565             (cellHandle, as->parms[SERVER].items->data, &vos_server, &st)) {
566             ERR_ST_EXT("vos_ServerOpen", st);
567         }
568         have_server = 1;
569     }
570
571     if (as->parms[PARTITION].items) {
572         if (!have_server) {
573             ERR_EXT("must specify server when specifying partition");
574         }
575         partition_id =
576             GetPartitionIdFromString(as->parms[PARTITION].items->data);
577         part_ptr = &partition_id;
578     }
579
580     if (!vos_VLDBGetBegin(cellHandle, vos_server, 0, part_ptr, &iter, &st)) {
581         ERR_ST_EXT("vos_VLDBGetBegin", st);
582     }
583
584     while (vos_VLDBGetNext(iter, &entry, &st)) {
585         Print_vos_vldbEntry_p(&entry, "");
586     }
587
588     if (st != ADMITERATORDONE) {
589         ERR_ST_EXT("vos_VLDBGetNext", st);
590     }
591
592     if (!vos_VLDBGetDone(iter, &st)) {
593         ERR_ST_EXT("vos_VLDBGetDone", st);
594     }
595
596     return 0;
597 }
598
599 int
600 DoVosVLDBEntryRemove(struct cmd_syndesc *as, void *arock)
601 {
602     typedef enum { SERVER, PARTITION, VOLUME } DoVosVLDBEntryRemove_parm_t;
603     afs_status_t st = 0;
604     void *vos_server = NULL;
605     unsigned int partition_id;
606     unsigned int *part_ptr = NULL;
607     int have_server = 0;
608     unsigned int volume_id;
609     unsigned int *vol_ptr = NULL;
610
611     if (as->parms[SERVER].items) {
612         if (!vos_ServerOpen
613             (cellHandle, as->parms[SERVER].items->data, &vos_server, &st)) {
614             ERR_ST_EXT("vos_ServerOpen", st);
615         }
616         have_server = 1;
617     }
618
619     if (as->parms[PARTITION].items) {
620         if (!have_server) {
621             ERR_EXT("must specify server when specifying partition");
622         }
623         partition_id =
624             GetPartitionIdFromString(as->parms[PARTITION].items->data);
625         part_ptr = &partition_id;
626     }
627
628     if (as->parms[VOLUME].items) {
629         const char *volume = as->parms[VOLUME].items->data;
630         volume_id = GetVolumeIdFromString(volume);
631         vol_ptr = &volume_id;
632     }
633
634     if (!vos_VLDBEntryRemove
635         (cellHandle, vos_server, 0, part_ptr, vol_ptr, &st)) {
636         ERR_ST_EXT("vos_VLDBEntryRemove", st);
637     }
638
639     return 0;
640 }
641
642 int
643 DoVosVLDBUnlock(struct cmd_syndesc *as, void *arock)
644 {
645     typedef enum { SERVER, PARTITION } DoVosVLDBUnlock_parm_t;
646     afs_status_t st = 0;
647     void *vos_server = NULL;
648     unsigned int partition_id;
649     unsigned int *part_ptr = NULL;
650     int have_server = 0;
651
652     if (as->parms[SERVER].items) {
653         if (!vos_ServerOpen
654             (cellHandle, as->parms[SERVER].items->data, &vos_server, &st)) {
655             ERR_ST_EXT("vos_ServerOpen", st);
656         }
657         have_server = 1;
658     }
659
660     if (as->parms[PARTITION].items) {
661         if (!have_server) {
662             ERR_EXT("must specify server when specifying partition");
663         }
664         partition_id =
665             GetPartitionIdFromString(as->parms[PARTITION].items->data);
666         part_ptr = &partition_id;
667     }
668
669     if (!vos_VLDBUnlock(cellHandle, vos_server, 0, part_ptr, &st)) {
670         ERR_ST_EXT("vos_VLDBUnlock", st);
671     }
672
673     return 0;
674 }
675
676 int
677 DoVosVLDBEntryLock(struct cmd_syndesc *as, void *arock)
678 {
679     typedef enum { VOLUME } DoVosVLDBEntryLoc_parm_tk;
680     afs_status_t st = 0;
681     unsigned int volume_id;
682
683     if (as->parms[VOLUME].items) {
684         const char *volume = as->parms[VOLUME].items->data;
685         volume_id = GetVolumeIdFromString(volume);
686     }
687
688     if (!vos_VLDBEntryLock(cellHandle, 0, volume_id, &st)) {
689         ERR_ST_EXT("vos_VLDBEntryLock", st);
690     }
691
692     return 0;
693 }
694
695 int
696 DoVosVLDBEntryUnlock(struct cmd_syndesc *as, void *arock)
697 {
698     typedef enum { VOLUME } DoVosVLDBEntryUnlock_parm_t;
699     afs_status_t st = 0;
700     unsigned int volume_id;
701
702     if (as->parms[VOLUME].items) {
703         const char *volume = as->parms[VOLUME].items->data;
704         volume_id = GetVolumeIdFromString(volume);
705     }
706
707     if (!vos_VLDBEntryUnlock(cellHandle, 0, volume_id, &st)) {
708         ERR_ST_EXT("vos_VLDBEntryUnlock", st);
709     }
710
711     return 0;
712 }
713
714 int
715 DoVosVLDBReadOnlySiteCreate(struct cmd_syndesc *as, void *arock)
716 {
717     typedef enum { SERVER, PARTITION,
718         VOLUME
719     } DoVosVLDBReadOnlySiteCreate_parm_t;
720     afs_status_t st = 0;
721     void *vos_server = NULL;
722     unsigned int partition_id;
723     unsigned int volume_id;
724
725     if (as->parms[SERVER].items) {
726         if (!vos_ServerOpen
727             (cellHandle, as->parms[SERVER].items->data, &vos_server, &st)) {
728             ERR_ST_EXT("vos_ServerOpen", st);
729         }
730     }
731
732     if (as->parms[PARTITION].items) {
733         partition_id =
734             GetPartitionIdFromString(as->parms[PARTITION].items->data);
735     }
736
737     if (as->parms[VOLUME].items) {
738         const char *volume = as->parms[VOLUME].items->data;
739         volume_id = GetVolumeIdFromString(volume);
740     }
741
742     if (!vos_VLDBReadOnlySiteCreate
743         (cellHandle, vos_server, 0, partition_id, volume_id, &st)) {
744         ERR_ST_EXT("vos_VLDBReadOnlySiteCreate", st);
745     }
746     return 0;
747 }
748
749 int
750 DoVosVLDBReadOnlySiteDelete(struct cmd_syndesc *as, void *arock)
751 {
752     typedef enum { SERVER, PARTITION,
753         VOLUME
754     } DoVosVLDBReadOnlySiteDelete_parm_t;
755     afs_status_t st = 0;
756     void *vos_server = NULL;
757     unsigned int partition_id;
758     unsigned int volume_id;
759
760     if (as->parms[SERVER].items) {
761         if (!vos_ServerOpen
762             (cellHandle, as->parms[SERVER].items->data, &vos_server, &st)) {
763             ERR_ST_EXT("vos_ServerOpen", st);
764         }
765     }
766
767     if (as->parms[PARTITION].items) {
768         partition_id =
769             GetPartitionIdFromString(as->parms[PARTITION].items->data);
770     }
771
772     if (as->parms[VOLUME].items) {
773         const char *volume = as->parms[VOLUME].items->data;
774         volume_id = GetVolumeIdFromString(volume);
775     }
776
777     if (!vos_VLDBReadOnlySiteDelete
778         (cellHandle, vos_server, 0, partition_id, volume_id, &st)) {
779         ERR_ST_EXT("vos_VLDBReadOnlySiteDelete", st);
780     }
781
782     return 0;
783 }
784
785 int
786 DoVosVLDBSync(struct cmd_syndesc *as, void *arock)
787 {
788     typedef enum { SERVER, PARTITION, FORCE } DoVosVLDBSync_parm_t;
789     afs_status_t st = 0;
790     void *vos_server = NULL;
791     unsigned int partition_id;
792     unsigned int *part_ptr = NULL;
793     int have_server = 0;
794     vos_force_t force = VOS_NORMAL;
795
796     if (as->parms[SERVER].items) {
797         if (!vos_ServerOpen
798             (cellHandle, as->parms[SERVER].items->data, &vos_server, &st)) {
799             ERR_ST_EXT("vos_ServerOpen", st);
800         }
801         have_server = 1;
802     }
803
804     if (as->parms[PARTITION].items) {
805         if (!have_server) {
806             ERR_EXT("must specify server when specifying partition");
807         }
808         partition_id =
809             GetPartitionIdFromString(as->parms[PARTITION].items->data);
810         part_ptr = &partition_id;
811     }
812
813     if (as->parms[FORCE].items) {
814         force = VOS_FORCE;
815     }
816
817     if (!vos_VLDBSync(cellHandle, vos_server, 0, part_ptr, force, &st)) {
818         ERR_ST_EXT("vos_VLDBSync", st);
819     }
820
821     return 0;
822 }
823
824 int
825 DoVosVolumeCreate(struct cmd_syndesc *as, void *arock)
826 {
827     typedef enum { SERVER, PARTITION, VOLUME,
828         QUOTA
829     } DoVosVolumeCreate_parm_t;
830     afs_status_t st = 0;
831     void *vos_server = NULL;
832     unsigned int partition_id;
833     unsigned int volume_id;
834     const char *volume = NULL;
835     unsigned int quota;
836
837     if (as->parms[SERVER].items) {
838         if (!vos_ServerOpen
839             (cellHandle, as->parms[SERVER].items->data, &vos_server, &st)) {
840             ERR_ST_EXT("vos_ServerOpen", st);
841         }
842     }
843
844     if (as->parms[PARTITION].items) {
845         partition_id =
846             GetPartitionIdFromString(as->parms[PARTITION].items->data);
847     }
848
849     if (as->parms[VOLUME].items) {
850         volume = as->parms[VOLUME].items->data;
851     }
852
853     if (as->parms[QUOTA].items) {
854         quota =
855             GetIntFromString(as->parms[QUOTA].items->data, "invalid quota");
856     }
857
858     if (!vos_VolumeCreate
859         (cellHandle, vos_server, 0, partition_id, volume, quota, &volume_id,
860          &st)) {
861         ERR_ST_EXT("vos_VolumeCreate", st);
862     }
863
864     printf("Created volume %u\n", volume_id);
865
866     return 0;
867 }
868
869 int
870 DoVosVolumeDelete(struct cmd_syndesc *as, void *arock)
871 {
872     typedef enum { SERVER, PARTITION, VOLUME } DoVosVolumeDelete_parm_t;
873     afs_status_t st = 0;
874     void *vos_server = NULL;
875     unsigned int partition_id;
876     unsigned int volume_id;
877
878     if (as->parms[SERVER].items) {
879         if (!vos_ServerOpen
880             (cellHandle, as->parms[SERVER].items->data, &vos_server, &st)) {
881             ERR_ST_EXT("vos_ServerOpen", st);
882         }
883     }
884
885     if (as->parms[PARTITION].items) {
886         partition_id =
887             GetPartitionIdFromString(as->parms[PARTITION].items->data);
888     }
889
890     if (as->parms[VOLUME].items) {
891         const char *volume = as->parms[VOLUME].items->data;
892         volume_id = GetVolumeIdFromString(volume);
893     }
894
895     if (!vos_VolumeDelete
896         (cellHandle, vos_server, 0, partition_id, volume_id, &st)) {
897         ERR_ST_EXT("vos_VolumeDelete", st);
898     }
899
900     return 0;
901 }
902
903 int
904 DoVosVolumeRename(struct cmd_syndesc *as, void *arock)
905 {
906     typedef enum { OLDVOLUME, NEWVOLUME } DoVosVolumeRename_parm_t;
907     afs_status_t st = 0;
908     unsigned int old_volume;
909     const char *new_volume;
910
911     if (as->parms[OLDVOLUME].items) {
912         const char *volume = as->parms[OLDVOLUME].items->data;
913         old_volume = GetVolumeIdFromString(volume);
914     }
915
916     if (as->parms[NEWVOLUME].items) {
917         new_volume = as->parms[NEWVOLUME].items->data;
918     }
919
920     if (!vos_VolumeRename(cellHandle, 0, old_volume, new_volume, &st)) {
921         ERR_ST_EXT("vos_VolumeRename", st);
922     }
923
924     return 0;
925 }
926
927 int
928 DoVosVolumeDump(struct cmd_syndesc *as, void *arock)
929 {
930     typedef enum { SERVER, PARTITION, VOLUME, STARTTIME,
931         DUMPFILE
932     } DoVosVolumeDump_parm_t;
933     afs_status_t st = 0;
934     void *vos_server = NULL;
935     unsigned int partition_id;
936     unsigned int *part_ptr = NULL;
937     int have_server = 0;
938     unsigned int volume_id;
939     unsigned int start_time;
940     const char *dumpfile;
941
942     if (as->parms[SERVER].items) {
943         if (!vos_ServerOpen
944             (cellHandle, as->parms[SERVER].items->data, &vos_server, &st)) {
945             ERR_ST_EXT("vos_ServerOpen", st);
946         }
947         have_server = 1;
948     }
949
950     if (as->parms[PARTITION].items) {
951         if (!have_server) {
952             ERR_EXT("must specify server when specifying partition");
953         }
954         partition_id =
955             GetPartitionIdFromString(as->parms[PARTITION].items->data);
956         part_ptr = &partition_id;
957     }
958
959     if (as->parms[VOLUME].items) {
960         const char *volume = as->parms[VOLUME].items->data;
961         volume_id = GetVolumeIdFromString(volume);
962     }
963
964     if (as->parms[STARTTIME].items) {
965         start_time =
966             GetIntFromString(as->parms[STARTTIME].items->data,
967                              "invalid start time");
968     }
969
970     if (as->parms[DUMPFILE].items) {
971         dumpfile = as->parms[DUMPFILE].items->data;
972     }
973
974     if (!vos_VolumeDump
975         (cellHandle, vos_server, 0, part_ptr, volume_id, start_time, dumpfile,
976          &st)) {
977         ERR_ST_EXT("vos_VolumeDump", st);
978     }
979
980     return 0;
981 }
982
983 int
984 DoVosVolumeRestore(struct cmd_syndesc *as, void *arock)
985 {
986     typedef enum { SERVER, PARTITION, ID, VOLUME, DUMPFILE,
987         FULL
988     } DoVosVolumeRestore_parm_t;
989     afs_status_t st = 0;
990     void *vos_server = NULL;
991     unsigned int partition_id;
992     unsigned int volume_id;
993     unsigned int *vol_ptr = NULL;
994     const char *dumpfile;
995     const char *volume_name;
996     vos_volumeRestoreType_t restore = VOS_RESTORE_INCREMENTAL;
997
998     if (as->parms[SERVER].items) {
999         if (!vos_ServerOpen
1000             (cellHandle, as->parms[SERVER].items->data, &vos_server, &st)) {
1001             ERR_ST_EXT("vos_ServerOpen", st);
1002         }
1003     }
1004
1005     if (as->parms[PARTITION].items) {
1006         partition_id =
1007             GetPartitionIdFromString(as->parms[PARTITION].items->data);
1008     }
1009
1010     if (as->parms[VOLUME].items) {
1011         volume_name = as->parms[VOLUME].items->data;
1012     }
1013
1014     if (as->parms[ID].items) {
1015         const char *volume = as->parms[ID].items->data;
1016         volume_id = GetVolumeIdFromString(volume);
1017         vol_ptr = &volume_id;
1018     }
1019
1020     if (as->parms[DUMPFILE].items) {
1021         dumpfile = as->parms[DUMPFILE].items->data;
1022     }
1023
1024     if (as->parms[FULL].items) {
1025         restore = VOS_RESTORE_FULL;
1026     }
1027
1028     if (!vos_VolumeRestore
1029         (cellHandle, vos_server, 0, partition_id, vol_ptr, volume_name,
1030          dumpfile, restore, &st)) {
1031         ERR_ST_EXT("vos_VolumeRestore", st);
1032     }
1033
1034     return 0;
1035 }
1036
1037 int
1038 DoVosVolumeOnline(struct cmd_syndesc *as, void *arock)
1039 {
1040     typedef enum { SERVER, PARTITION, VOLUME, SLEEP,
1041         BUSY
1042     } DoVosVolumeOnline_parm_t;
1043     afs_status_t st = 0;
1044     void *vos_server = NULL;
1045     unsigned int partition_id;
1046     unsigned int volume_id;
1047     unsigned int sleep;
1048     vos_volumeOnlineType_t type = VOS_ONLINE_OFFLINE;
1049
1050     if (as->parms[SERVER].items) {
1051         if (!vos_ServerOpen
1052             (cellHandle, as->parms[SERVER].items->data, &vos_server, &st)) {
1053             ERR_ST_EXT("vos_ServerOpen", st);
1054         }
1055     }
1056
1057     if (as->parms[PARTITION].items) {
1058         partition_id =
1059             GetPartitionIdFromString(as->parms[PARTITION].items->data);
1060     }
1061
1062     if (as->parms[VOLUME].items) {
1063         const char *volume = as->parms[VOLUME].items->data;
1064         volume_id = GetVolumeIdFromString(volume);
1065     }
1066
1067     if (as->parms[SLEEP].items) {
1068         sleep =
1069             GetIntFromString(as->parms[SLEEP].items->data,
1070                              "invalid sleep time");
1071     }
1072
1073     if (as->parms[BUSY].items) {
1074         type = VOS_ONLINE_BUSY;
1075     }
1076
1077     if (!vos_VolumeOnline
1078         (vos_server, 0, partition_id, volume_id, sleep, type, &st)) {
1079         ERR_ST_EXT("vos_VolumeOnline", st);
1080     }
1081
1082     return 0;
1083 }
1084
1085 int
1086 DoVosVolumeOffline(struct cmd_syndesc *as, void *arock)
1087 {
1088     typedef enum { SERVER, PARTITION, VOLUME } DoVosVolumeOffline_parm_t;
1089     afs_status_t st = 0;
1090     void *vos_server = NULL;
1091     unsigned int partition_id;
1092     unsigned int volume_id;
1093
1094     if (as->parms[SERVER].items) {
1095         if (!vos_ServerOpen
1096             (cellHandle, as->parms[SERVER].items->data, &vos_server, &st)) {
1097             ERR_ST_EXT("vos_ServerOpen", st);
1098         }
1099     }
1100
1101     if (as->parms[PARTITION].items) {
1102         partition_id =
1103             GetPartitionIdFromString(as->parms[PARTITION].items->data);
1104     }
1105
1106     if (as->parms[VOLUME].items) {
1107         const char *volume = as->parms[VOLUME].items->data;
1108         volume_id = GetVolumeIdFromString(volume);
1109     }
1110
1111     if (!vos_VolumeOffline(vos_server, 0, partition_id, volume_id, &st)) {
1112         ERR_ST_EXT("vos_VolumeOffline", st);
1113     }
1114
1115     return 0;
1116 }
1117
1118 static void
1119 Print_vos_volumeEntry_p(vos_volumeEntry_p entry, const char *prefix)
1120 {
1121     if (entry->status == VOS_OK) {
1122         printf("%sVolume name %s id %u\n", prefix, entry->name, entry->id);
1123         printf("%sRead write id %u\n", prefix, entry->readWriteId);
1124         printf("%sRead only id %u\n", prefix, entry->readOnlyId);
1125         printf("%sBackup id %u\n", prefix, entry->backupId);
1126         printf("%sCreation date %lu\n", prefix, entry->creationDate);
1127         printf("%sLast access date %lu\n", prefix, entry->lastAccessDate);
1128         printf("%sLast update date %lu\n", prefix, entry->lastUpdateDate);
1129         printf("%sLast backup date %lu\n", prefix, entry->lastBackupDate);
1130         printf("%sLast copy creation date %lu\n", prefix,
1131                entry->copyCreationDate);
1132         printf("%sAccesses since midnight %d\n", prefix,
1133                entry->accessesSinceMidnight);
1134         printf("%sFile count %d\n", prefix, entry->fileCount);
1135         printf("%sMax quota %d\n", prefix, entry->maxQuota);
1136         printf("%sCurrent size %d\n", prefix, entry->currentSize);
1137
1138         printf("%sVolume status: VOS_OK\n", prefix);
1139
1140         printf("%sVolume disposition:\n", prefix);
1141
1142         switch (entry->volumeDisposition) {
1143         case VOS_OK:
1144             printf("%s\tVOS_OK\n", prefix);
1145             break;
1146         case VOS_SALVAGE:
1147             printf("%s\tVOS_SALVAGE\n", prefix);
1148             break;
1149         case VOS_NO_VNODE:
1150             printf("%s\tVOS_NO_VNODE\n", prefix);
1151             break;
1152         case VOS_NO_VOL:
1153             printf("%s\tVOS_NO_VOL\n", prefix);
1154             break;
1155         case VOS_VOL_EXISTS:
1156             printf("%s\tVOS_VOL_EXISTS\n", prefix);
1157             break;
1158         case VOS_NO_SERVICE:
1159             printf("%s\tVOS_NO_SERVICE\n", prefix);
1160             break;
1161         case VOS_OFFLINE:
1162             printf("%s\tVOS_OFFLINE\n", prefix);
1163             break;
1164         case VOS_ONLINE:
1165             printf("%s\tVOS_ONLINE\n", prefix);
1166             break;
1167         case VOS_DISK_FULL:
1168             printf("%s\tVOS_DISK_FULL\n", prefix);
1169             break;
1170         case VOS_OVER_QUOTA:
1171             printf("%s\tVOS_OVER_QUOTA\n", prefix);
1172             break;
1173         case VOS_BUSY:
1174             printf("%s\tVOS_BUSY\n", prefix);
1175             break;
1176         case VOS_MOVED:
1177             printf("%s\tVOS_MOVED\n", prefix);
1178             break;
1179         default:
1180             printf("Unknown volume disposition %d\n",
1181                    entry->volumeDisposition);
1182             break;
1183         }
1184
1185         printf("%sVolume type: ", prefix);
1186
1187         if (entry->type == VOS_READ_WRITE_VOLUME) {
1188             printf("read write\n");
1189         } else if (entry->type == VOS_READ_ONLY_VOLUME) {
1190             printf("read only\n");
1191         } else {
1192             printf("backup\n");
1193         }
1194
1195         printf("\n%s\tSame Network\tSame Network Authenticated"
1196                "\tDifferent Network\tDifferent Network Authenticated\n\n",
1197                prefix);
1198         printf("%sRead\t%d\t%d\t%d\t%d\n", prefix,
1199                entry->readStats[VOS_VOLUME_READ_WRITE_STATS_SAME_NETWORK],
1200                entry->
1201                readStats
1202                [VOS_VOLUME_READ_WRITE_STATS_SAME_NETWORK_AUTHENTICATED],
1203                entry->
1204                readStats[VOS_VOLUME_READ_WRITE_STATS_DIFFERENT_NETWORK],
1205                entry->
1206                readStats
1207                [VOS_VOLUME_READ_WRITE_STATS_DIFFERENT_NETWORK_AUTHENTICATED]);
1208         printf("%sWrite\t%d\t%d\t%d\t%d\n", prefix,
1209                entry->writeStats[VOS_VOLUME_READ_WRITE_STATS_SAME_NETWORK],
1210                entry->
1211                writeStats
1212                [VOS_VOLUME_READ_WRITE_STATS_SAME_NETWORK_AUTHENTICATED],
1213                entry->
1214                writeStats[VOS_VOLUME_READ_WRITE_STATS_DIFFERENT_NETWORK],
1215                entry->
1216                writeStats
1217                [VOS_VOLUME_READ_WRITE_STATS_DIFFERENT_NETWORK_AUTHENTICATED]);
1218
1219         printf
1220             ("\n%s\t0 to 60 secs\t1 to 10 mins\t10 to 60 mins\t1 to 24 hrs\t1 to 7 days\t more than 7 days\n",
1221              prefix);
1222         printf("%sFile Author Write Same Network\t%d\t%d\t%d\t%d\t%d\t%d\n",
1223                prefix,
1224                entry->
1225                fileAuthorWriteSameNetwork
1226                [VOS_VOLUME_TIME_STATS_0_TO_60_SECONDS],
1227                entry->
1228                fileAuthorWriteSameNetwork
1229                [VOS_VOLUME_TIME_STATS_1_TO_10_MINUTES],
1230                entry->
1231                fileAuthorWriteSameNetwork
1232                [VOS_VOLUME_TIME_STATS_10_TO_60_MINUTES],
1233                entry->
1234                fileAuthorWriteSameNetwork
1235                [VOS_VOLUME_TIME_STATS_1_TO_24_HOURS],
1236                entry->
1237                fileAuthorWriteSameNetwork[VOS_VOLUME_TIME_STATS_1_TO_7_DAYS],
1238                entry->
1239                fileAuthorWriteSameNetwork
1240                [VOS_VOLUME_TIME_STATS_GREATER_THAN_7_DAYS]);
1241         printf("%sFile Author Write Diff Network\t%d\t%d\t%d\t%d\t%d\t%d\n",
1242                prefix,
1243                entry->
1244                fileAuthorWriteDifferentNetwork
1245                [VOS_VOLUME_TIME_STATS_0_TO_60_SECONDS],
1246                entry->
1247                fileAuthorWriteDifferentNetwork
1248                [VOS_VOLUME_TIME_STATS_1_TO_10_MINUTES],
1249                entry->
1250                fileAuthorWriteDifferentNetwork
1251                [VOS_VOLUME_TIME_STATS_10_TO_60_MINUTES],
1252                entry->
1253                fileAuthorWriteDifferentNetwork
1254                [VOS_VOLUME_TIME_STATS_1_TO_24_HOURS],
1255                entry->
1256                fileAuthorWriteDifferentNetwork
1257                [VOS_VOLUME_TIME_STATS_1_TO_7_DAYS],
1258                entry->
1259                fileAuthorWriteDifferentNetwork
1260                [VOS_VOLUME_TIME_STATS_GREATER_THAN_7_DAYS]);
1261         printf("%sDir Author Write Same Network\t%d\t%d\t%d\t%d\t%d\t%d\n",
1262                prefix,
1263                entry->
1264                dirAuthorWriteSameNetwork
1265                [VOS_VOLUME_TIME_STATS_0_TO_60_SECONDS],
1266                entry->
1267                dirAuthorWriteSameNetwork
1268                [VOS_VOLUME_TIME_STATS_1_TO_10_MINUTES],
1269                entry->
1270                dirAuthorWriteSameNetwork
1271                [VOS_VOLUME_TIME_STATS_10_TO_60_MINUTES],
1272                entry->
1273                dirAuthorWriteSameNetwork[VOS_VOLUME_TIME_STATS_1_TO_24_HOURS],
1274                entry->
1275                dirAuthorWriteSameNetwork[VOS_VOLUME_TIME_STATS_1_TO_7_DAYS],
1276                entry->
1277                dirAuthorWriteSameNetwork
1278                [VOS_VOLUME_TIME_STATS_GREATER_THAN_7_DAYS]);
1279         printf("%sDir Author Write Diff Network\t%d\t%d\t%d\t%d\t%d\t%d\n",
1280                prefix,
1281                entry->
1282                dirAuthorWriteDifferentNetwork
1283                [VOS_VOLUME_TIME_STATS_0_TO_60_SECONDS],
1284                entry->
1285                dirAuthorWriteDifferentNetwork
1286                [VOS_VOLUME_TIME_STATS_1_TO_10_MINUTES],
1287                entry->
1288                dirAuthorWriteDifferentNetwork
1289                [VOS_VOLUME_TIME_STATS_10_TO_60_MINUTES],
1290                entry->
1291                dirAuthorWriteDifferentNetwork
1292                [VOS_VOLUME_TIME_STATS_1_TO_24_HOURS],
1293                entry->
1294                dirAuthorWriteDifferentNetwork
1295                [VOS_VOLUME_TIME_STATS_1_TO_7_DAYS],
1296                entry->
1297                dirAuthorWriteDifferentNetwork
1298                [VOS_VOLUME_TIME_STATS_GREATER_THAN_7_DAYS]);
1299     } else {
1300         printf("%sUnable to print volume because volume status:\n", prefix);
1301         switch (entry->status) {
1302         case VOS_SALVAGE:
1303             printf("%s\tVOS_SALVAGE\n", prefix);
1304             break;
1305         case VOS_NO_VNODE:
1306             printf("%s\tVOS_NO_VNODE\n", prefix);
1307             break;
1308         case VOS_NO_VOL:
1309             printf("%s\tVOS_NO_VOL\n", prefix);
1310             break;
1311         case VOS_VOL_EXISTS:
1312             printf("%s\tVOS_VOL_EXISTS\n", prefix);
1313             break;
1314         case VOS_NO_SERVICE:
1315             printf("%s\tVOS_NO_SERVICE\n", prefix);
1316             break;
1317         case VOS_OFFLINE:
1318             printf("%s\tVOS_OFFLINE\n", prefix);
1319             break;
1320         case VOS_ONLINE:
1321             printf("%s\tVOS_ONLINE\n", prefix);
1322             break;
1323         case VOS_DISK_FULL:
1324             printf("%s\tVOS_DISK_FULL\n", prefix);
1325             break;
1326         case VOS_OVER_QUOTA:
1327             printf("%s\tVOS_OVER_QUOTA\n", prefix);
1328             break;
1329         case VOS_BUSY:
1330             printf("%s\tVOS_BUSY\n", prefix);
1331             break;
1332         case VOS_MOVED:
1333             printf("%s\tVOS_MOVED\n", prefix);
1334             break;
1335         default:
1336             printf("Unknown volume status %d\n", entry->status);
1337             break;
1338         }
1339     }
1340 }
1341
1342 int
1343 DoVosVolumeGet(struct cmd_syndesc *as, void *arock)
1344 {
1345     typedef enum { SERVER, PARTITION, VOLUME } DoVosVolumeGet_parm_t;
1346     afs_status_t st = 0;
1347     void *vos_server = NULL;
1348     unsigned int partition_id;
1349     unsigned int volume_id;
1350     vos_volumeEntry_t entry;
1351
1352     if (as->parms[SERVER].items) {
1353         if (!vos_ServerOpen
1354             (cellHandle, as->parms[SERVER].items->data, &vos_server, &st)) {
1355             ERR_ST_EXT("vos_ServerOpen", st);
1356         }
1357     }
1358
1359     if (as->parms[PARTITION].items) {
1360         partition_id =
1361             GetPartitionIdFromString(as->parms[PARTITION].items->data);
1362     }
1363
1364     if (as->parms[VOLUME].items) {
1365         const char *volume = as->parms[VOLUME].items->data;
1366         volume_id = GetVolumeIdFromString(volume);
1367     }
1368
1369     if (!vos_VolumeGet
1370         (cellHandle, vos_server, 0, partition_id, volume_id, &entry, &st)) {
1371         ERR_ST_EXT("vos_VolumeGet", st);
1372     }
1373
1374     Print_vos_volumeEntry_p(&entry, "");
1375
1376     return 0;
1377 }
1378
1379 int
1380 DoVosVolumeList(struct cmd_syndesc *as, void *arock)
1381 {
1382     typedef enum { SERVER, PARTITION } DoVosVolumeList_parm_t;
1383     afs_status_t st = 0;
1384     void *vos_server = NULL;
1385     void *iter = NULL;
1386     unsigned int partition_id;
1387     vos_volumeEntry_t entry;
1388
1389     if (as->parms[SERVER].items) {
1390         if (!vos_ServerOpen
1391             (cellHandle, as->parms[SERVER].items->data, &vos_server, &st)) {
1392             ERR_ST_EXT("vos_ServerOpen", st);
1393         }
1394     }
1395
1396     if (as->parms[PARTITION].items) {
1397         partition_id =
1398             GetPartitionIdFromString(as->parms[PARTITION].items->data);
1399     }
1400
1401     if (!vos_VolumeGetBegin
1402         (cellHandle, vos_server, 0, partition_id, &iter, &st)) {
1403         ERR_ST_EXT("vos_VolumeGetBegin", st);
1404     }
1405
1406     printf("Volumes located at %s partition %s\n",
1407            as->parms[SERVER].items->data, as->parms[PARTITION].items->data);
1408
1409     while (vos_VolumeGetNext(iter, &entry, &st)) {
1410         Print_vos_volumeEntry_p(&entry, "    ");
1411         printf("\n");
1412     }
1413
1414     if (st != ADMITERATORDONE) {
1415         ERR_ST_EXT("vos_VolumeGetNext", st);
1416     }
1417
1418     if (!vos_VolumeGetDone(iter, &st)) {
1419         ERR_ST_EXT("vos_VolumeGetDone", st);
1420     }
1421
1422     return 0;
1423 }
1424
1425 int
1426 DoVosVolumeMove(struct cmd_syndesc *as, void *arock)
1427 {
1428     typedef enum { VOLUME, FROMSERVER, FROMPARTITION, TOSERVER,
1429         TOPARTITION
1430     } DoVosVolumeMove_parm_t;
1431     afs_status_t st = 0;
1432     void *from_server = NULL;
1433     void *to_server = NULL;
1434     unsigned int from_partition;
1435     unsigned int to_partition;
1436     unsigned int volume_id;
1437
1438     if (as->parms[FROMSERVER].items) {
1439         if (!vos_ServerOpen
1440             (cellHandle, as->parms[FROMSERVER].items->data, &from_server,
1441              &st)) {
1442             ERR_ST_EXT("vos_ServerOpen", st);
1443         }
1444     }
1445
1446     if (as->parms[TOSERVER].items) {
1447         if (!vos_ServerOpen
1448             (cellHandle, as->parms[TOSERVER].items->data, &to_server, &st)) {
1449             ERR_ST_EXT("vos_ServerOpen", st);
1450         }
1451     }
1452
1453     if (as->parms[FROMPARTITION].items) {
1454         from_partition =
1455             GetPartitionIdFromString(as->parms[FROMPARTITION].items->data);
1456     }
1457
1458     if (as->parms[TOPARTITION].items) {
1459         to_partition =
1460             GetPartitionIdFromString(as->parms[TOPARTITION].items->data);
1461     }
1462
1463     if (as->parms[VOLUME].items) {
1464         const char *volume = as->parms[VOLUME].items->data;
1465         volume_id = GetVolumeIdFromString(volume);
1466     }
1467
1468     if (!vos_VolumeMove
1469         (cellHandle, 0, volume_id, from_server, from_partition, to_server,
1470          to_partition, &st)) {
1471         ERR_ST_EXT("vos_VolumeMove", st);
1472     }
1473
1474     return 0;
1475 }
1476
1477 int
1478 DoVosVolumeRelease(struct cmd_syndesc *as, void *arock)
1479 {
1480     typedef enum { VOLUME, FORCE } DoVosVolumeRelease_parm_t;
1481     afs_status_t st = 0;
1482     unsigned int volume_id;
1483     vos_force_t force = VOS_NORMAL;
1484
1485     if (as->parms[VOLUME].items) {
1486         const char *volume = as->parms[VOLUME].items->data;
1487         volume_id = GetVolumeIdFromString(volume);
1488     }
1489
1490     if (as->parms[FORCE].items) {
1491         force = VOS_FORCE;
1492     }
1493
1494     if (!vos_VolumeRelease(cellHandle, 0, volume_id, force, &st)) {
1495         ERR_ST_EXT("vos_VolumeRelease", st);
1496     }
1497     return 0;
1498 }
1499
1500 int
1501 DoVosVolumeZap(struct cmd_syndesc *as, void *arock)
1502 {
1503     typedef enum { SERVER, PARTITION, VOLUME, FORCE } DoVosVolumeZap_parm_t;
1504     afs_status_t st = 0;
1505     void *vos_server = NULL;
1506     unsigned int partition_id;
1507     unsigned int volume_id;
1508     vos_force_t force = VOS_NORMAL;
1509
1510     if (as->parms[SERVER].items) {
1511         if (!vos_ServerOpen
1512             (cellHandle, as->parms[SERVER].items->data, &vos_server, &st)) {
1513             ERR_ST_EXT("vos_ServerOpen", st);
1514         }
1515     }
1516
1517     if (as->parms[PARTITION].items) {
1518         partition_id =
1519             GetPartitionIdFromString(as->parms[PARTITION].items->data);
1520     }
1521
1522     if (as->parms[VOLUME].items) {
1523         const char *volume = as->parms[VOLUME].items->data;
1524         volume_id = GetVolumeIdFromString(volume);
1525     }
1526
1527     if (as->parms[FORCE].items) {
1528         force = VOS_FORCE;
1529     }
1530
1531     if (!vos_VolumeZap
1532         (cellHandle, vos_server, 0, partition_id, volume_id, force, &st)) {
1533         ERR_ST_EXT("vos_VolumeZap", st);
1534     }
1535
1536     return 0;
1537 }
1538
1539 int
1540 DoVosPartitionNameToId(struct cmd_syndesc *as, void *arock)
1541 {
1542     typedef enum { PARTITION } DoVosPartitionNameToId_parm_t;
1543     afs_status_t st = 0;
1544     unsigned int partition_id;
1545
1546     if (as->parms[PARTITION].items) {
1547         partition_id =
1548             GetPartitionIdFromString(as->parms[PARTITION].items->data);
1549     }
1550
1551     printf("The id for partition %s is %u\n",
1552            as->parms[PARTITION].items->data, partition_id);
1553
1554     return 0;
1555 }
1556
1557 int
1558 DoVosPartitionIdToName(struct cmd_syndesc *as, void *arock)
1559 {
1560     typedef enum { PARTITIONID } DoVosPartitionIdToName_parm_t;
1561     afs_status_t st = 0;
1562     unsigned int partition_id;
1563     char partition[VOS_MAX_PARTITION_NAME_LEN];
1564
1565     if (as->parms[PARTITIONID].items) {
1566         partition_id =
1567             GetIntFromString(as->parms[PARTITIONID].items->data,
1568                              "bad partition id");
1569     }
1570
1571     if (!vos_PartitionIdToName(partition_id, partition, &st)) {
1572         ERR_ST_EXT("bad partition id", st);
1573     }
1574
1575     printf("The partition for id %u is %s\n", partition_id, partition);
1576
1577     return 0;
1578 }
1579
1580 int
1581 DoVosVolumeQuotaChange(struct cmd_syndesc *as, void *arock)
1582 {
1583     typedef enum { SERVER, PARTITION, VOLUME,
1584         QUOTA
1585     } DoVosVolumeQuotaChange_parm_t;
1586     afs_status_t st = 0;
1587     void *vos_server = NULL;
1588     unsigned int partition_id;
1589     unsigned int volume_id;
1590     unsigned int quota;
1591
1592     if (as->parms[SERVER].items) {
1593         if (!vos_ServerOpen
1594             (cellHandle, as->parms[SERVER].items->data, &vos_server, &st)) {
1595             ERR_ST_EXT("vos_ServerOpen", st);
1596         }
1597     }
1598
1599     if (as->parms[PARTITION].items) {
1600         partition_id =
1601             GetPartitionIdFromString(as->parms[PARTITION].items->data);
1602     }
1603
1604     if (as->parms[VOLUME].items) {
1605         const char *volume = as->parms[VOLUME].items->data;
1606         volume_id = GetVolumeIdFromString(volume);
1607     }
1608
1609     if (as->parms[QUOTA].items) {
1610         quota =
1611             GetIntFromString(as->parms[QUOTA].items->data, "invalid quota");
1612     }
1613
1614     if (!vos_VolumeQuotaChange
1615         (cellHandle, vos_server, 0, partition_id, volume_id, quota, &st)) {
1616         ERR_ST_EXT("vos_VolumeQuotaChange", st);
1617     }
1618
1619     return 0;
1620 }
1621
1622 /*
1623  * Parse a server name/address and return the address in HOST BYTE order
1624  */
1625 static afs_uint32
1626 GetServer(char *aname)
1627 {
1628     register struct hostent *th;
1629     afs_uint32 addr;
1630     int b1, b2, b3, b4;
1631     register afs_int32 code;
1632     char hostname[MAXHOSTCHARS];
1633
1634     code = sscanf(aname, "%d.%d.%d.%d", &b1, &b2, &b3, &b4);
1635     if (code == 4) {
1636         addr = (b1 << 24) | (b2 << 16) | (b3 << 8) | b4;
1637         addr = ntohl(addr);     /* convert to host order */
1638     } else {
1639         th = gethostbyname(aname);
1640         if (!th)
1641             return 0;
1642         memcpy(&addr, th->h_addr, sizeof(addr));
1643     }
1644
1645     if (addr == htonl(0x7f000001)) {    /* local host */
1646         code = gethostname(hostname, MAXHOSTCHARS);
1647         if (code)
1648             return 0;
1649         th = gethostbyname(hostname);   /* returns host byte order */
1650         if (!th)
1651             return 0;
1652         memcpy(&addr, th->h_addr, sizeof(addr));
1653     }
1654
1655     return (addr);
1656 }
1657
1658 static void
1659 Print_vos_volintInfo(afs_uint32 server, afs_uint32 partition, volintInfo* pinfo, const char *prefix)
1660 {
1661     static afs_uint32 server_cache;
1662     static int cache_valid = 0;
1663     static char hostname[256], address[32];
1664
1665     if (!cache_valid || server != server_cache) {
1666         struct in_addr s;
1667
1668         s.s_addr = server;
1669         strcpy(hostname, hostutil_GetNameByINet(server));
1670         strcpy(address, inet_ntoa(s));
1671         server_cache = server;
1672         cache_valid = 1;
1673     }
1674     
1675     
1676     printf("%sname\t\t%s\n",prefix, pinfo->name);
1677     printf("%sid\t\t%lu\n",prefix, pinfo->volid);
1678     printf("%sserv\t\t%s\t%s\n",prefix, address,hostname);
1679     printf("%spart\t\t%u\n", prefix,partition);
1680     
1681     switch (pinfo->status) {
1682     case 2: /* VOK */
1683         printf("%sstatus\t\tOK\n",prefix);
1684         break;
1685     case 101: /* VBUSY */
1686         printf("%sstatus\t\tBUSY\n",prefix);
1687         return;
1688     default:
1689         printf("%sstatus\t\tUNATTACHABLE\n",prefix);
1690         return;
1691     }
1692     printf("%sbackupID\t%lu\n",prefix, pinfo->backupID);
1693     printf("%sparentID\t%lu\n",prefix, pinfo->parentID);
1694     printf("%scloneID\t%lu\n",prefix, pinfo->cloneID);
1695     printf("%sinUse\t\t%s\n",prefix, pinfo->inUse ? "Y" : "N");
1696     printf("%sneedsSalvaged\t%s\n",prefix, pinfo->needsSalvaged ? "Y" : "N");
1697     /* 0xD3 is from afs/volume.h since I had trouble including the file */
1698     printf("%sdestroyMe\t%s\n",prefix, pinfo->destroyMe == 0xD3 ? "Y" : "N");
1699     switch (pinfo->type) {
1700     case 0:
1701         printf("%stype\t\tRW\n",prefix);
1702         break;
1703     case 1:
1704         printf("%stype\t\tRO\n",prefix);
1705         break;
1706     case 2:
1707         printf("%stype\t\tBK\n",prefix);
1708         break;
1709     default:
1710         printf("%stype\t\t?\n",prefix);
1711         break;
1712     }
1713     printf("%screationDate\t%-9lu\n", prefix,pinfo->creationDate);
1714     printf("%saccessDate\t%-9lu\n", prefix,pinfo->accessDate);
1715     printf("%supdateDate\t%-9lu\n", prefix,pinfo->updateDate);
1716     printf("%sbackupDate\t%-9lu\n", prefix,pinfo->backupDate);
1717     printf("%scopyDate\t%-9lu\n", prefix,pinfo->copyDate);
1718             
1719     printf("%sflags\t\t%#lx\t(Optional)\n",prefix, pinfo->flags);
1720     printf("%sdiskused\t%u\n",prefix, pinfo->size);
1721     printf("%smaxquota\t%u\n",prefix, pinfo->maxquota);
1722     printf("%sminquota\t%lu\t(Optional)\n",prefix, pinfo->spare0);
1723     printf("%sfilecount\t%u\n",prefix, pinfo->filecount);
1724     printf("%sdayUse\t\t%u\n",prefix, pinfo->dayUse);
1725     printf("%sweekUse\t%lu\t(Optional)\n",prefix, pinfo->spare1);
1726     printf("%svolUpdateCounter\t\t%lu\t(Optional)\n",prefix, pinfo->spare2);
1727     printf("%sspare3\t\t%lu\t(Optional)\n",prefix, pinfo->spare3);
1728 }
1729
1730 int
1731 DoVosVolumeGet2(struct cmd_syndesc *as, void *arock)
1732 {
1733     typedef enum { SERVER, PARTITION, VOLUME } DoVosVolumeGet_parm_t;
1734     afs_status_t st = 0;
1735     void *vos_server = NULL;
1736     afs_uint32 partition_id;
1737     afs_uint32 volume_id;
1738
1739         volintInfo info;
1740         memset(&info, 0, sizeof(struct volintInfo));
1741
1742     if (as->parms[SERVER].items) {
1743         if (!vos_ServerOpen
1744             (cellHandle, as->parms[SERVER].items->data, &vos_server, &st)) {
1745             ERR_ST_EXT("vos_ServerOpen", st);
1746         }
1747     }
1748
1749     if (as->parms[PARTITION].items) {
1750         partition_id =
1751             GetPartitionIdFromString(as->parms[PARTITION].items->data);
1752     }
1753
1754     if (as->parms[VOLUME].items) {
1755         const char *volume = as->parms[VOLUME].items->data;
1756         volume_id = GetVolumeIdFromString(volume);
1757     }
1758     
1759
1760         if (!vos_VolumeGet2
1761         (cellHandle, vos_server, 0, partition_id, volume_id, &info, &st)) {
1762         ERR_ST_EXT("vos_VolumeGet2", st);
1763     }
1764
1765
1766     Print_vos_volintInfo(GetServer(as->parms[SERVER].items->data),partition_id,&info," ");
1767
1768     return 0;
1769 }
1770
1771
1772 int
1773 DoVos_ClearVolUpdateCounter(struct cmd_syndesc *as, void *arock)
1774 {
1775     typedef enum { SERVER, PARTITION, VOLUME } DoVosVolumeGet_parm_t;
1776     afs_status_t st = 0;
1777     void *vos_server = NULL;
1778     unsigned int partition_id;
1779     unsigned int volume_id;
1780
1781     if (as->parms[SERVER].items) {
1782         if (!vos_ServerOpen
1783             (cellHandle, as->parms[SERVER].items->data, &vos_server, &st)) {
1784             ERR_ST_EXT("vos_ServerOpen", st);
1785         }
1786     }
1787
1788     if (as->parms[PARTITION].items) {
1789         partition_id =
1790             GetPartitionIdFromString(as->parms[PARTITION].items->data);
1791     }
1792
1793     if (as->parms[VOLUME].items) {
1794         const char *volume = as->parms[VOLUME].items->data;
1795         volume_id = GetVolumeIdFromString(volume);
1796     }
1797
1798     if (!vos_ClearVolUpdateCounter
1799         (cellHandle, vos_server,partition_id, volume_id, &st)) {
1800         ERR_ST_EXT("vos_ClearVolUpdateCounter", st);
1801     }
1802
1803     return 0;
1804 }
1805
1806 void
1807 SetupVosAdminCmd(void)
1808 {
1809     struct cmd_syndesc *ts;
1810
1811     ts = cmd_CreateSyntax("VosBackupVolumeCreate", DoVosBackupVolumeCreate, NULL,
1812                           "create a backup volume");
1813     cmd_AddParm(ts, "-volume", CMD_SINGLE, CMD_REQUIRED, "volume to back up");
1814     SetupCommonCmdArgs(ts);
1815
1816     ts = cmd_CreateSyntax("VosBackupVolumeCreateMultiple",
1817                           DoVosBackupVolumeCreateMultiple, NULL,
1818                           "create a backup volume");
1819     cmd_AddParm(ts, "-server", CMD_SINGLE, CMD_OPTIONAL,
1820                 "server housing volumes to back up");
1821     cmd_AddParm(ts, "-partition", CMD_SINGLE, CMD_OPTIONAL,
1822                 "partition housing volumes to back up");
1823     cmd_AddParm(ts, "-prefix", CMD_SINGLE, CMD_OPTIONAL,
1824                 "common prefix of volumes to back up");
1825     cmd_AddParm(ts, "-exclude", CMD_FLAG, CMD_OPTIONAL,
1826                 "exclude volumes from backup that match prefix");
1827     SetupCommonCmdArgs(ts);
1828
1829     ts = cmd_CreateSyntax("VosPartitionGet", DoVosPartitionGet, NULL,
1830                           "get information about a partition");
1831     cmd_AddParm(ts, "-server", CMD_SINGLE, CMD_REQUIRED,
1832                 "server housing partition of interest");
1833     cmd_AddParm(ts, "-partition", CMD_SINGLE, CMD_REQUIRED,
1834                 "partition to query");
1835     SetupCommonCmdArgs(ts);
1836
1837     ts = cmd_CreateSyntax("VosPartitionList", DoVosPartitionList, NULL,
1838                           "list information about all partitions at a server");
1839     cmd_AddParm(ts, "-server", CMD_SINGLE, CMD_REQUIRED,
1840                 "server housing partitions of interest");
1841     SetupCommonCmdArgs(ts);
1842
1843     ts = cmd_CreateSyntax("VosServerSync", DoVosServerSync, NULL,
1844                           "sync server with vldb");
1845     cmd_AddParm(ts, "-server", CMD_SINGLE, CMD_REQUIRED, "server to sync");
1846     cmd_AddParm(ts, "-partition", CMD_SINGLE, CMD_OPTIONAL,
1847                 "partition to sync");
1848     SetupCommonCmdArgs(ts);
1849
1850     ts = cmd_CreateSyntax("VosFileServerAddressChange",
1851                           DoVosFileServerAddressChange, NULL,
1852                           "change a server's address in the vldb");
1853     cmd_AddParm(ts, "-oldaddress", CMD_SINGLE, CMD_REQUIRED,
1854                 "old address to change");
1855     cmd_AddParm(ts, "-newaddress", CMD_SINGLE, CMD_REQUIRED, "new address");
1856     SetupCommonCmdArgs(ts);
1857
1858     ts = cmd_CreateSyntax("VosFileServerAddressRemove",
1859                           DoVosFileServerAddressRemove, NULL,
1860                           "remove a server's address from the vldb");
1861     cmd_AddParm(ts, "-address", CMD_SINGLE, CMD_REQUIRED,
1862                 "address to remove");
1863     SetupCommonCmdArgs(ts);
1864
1865     ts = cmd_CreateSyntax("VosFileServerList", DoVosFileServerList, NULL,
1866                           "list the file servers in a cell");
1867     SetupCommonCmdArgs(ts);
1868
1869     ts = cmd_CreateSyntax("VosServerTransactionStatusList",
1870                           DoVosServerTransactionStatusList, NULL,
1871                           "list the active transactions at a server");
1872     cmd_AddParm(ts, "-server", CMD_SINGLE, CMD_REQUIRED, "server to query");
1873     SetupCommonCmdArgs(ts);
1874
1875     ts = cmd_CreateSyntax("VosVLDBGet", DoVosVLDBGet, NULL,
1876                           "get a vldb entry for a volume");
1877     cmd_AddParm(ts, "-volume", CMD_SINGLE, CMD_REQUIRED,
1878                 "volume to retrieve");
1879     SetupCommonCmdArgs(ts);
1880
1881     ts = cmd_CreateSyntax("VosVLDBList", DoVosVLDBList, NULL,
1882                           "list a group of vldb entries");
1883     cmd_AddParm(ts, "-server", CMD_SINGLE, CMD_OPTIONAL,
1884                 "limit entries to a particular server");
1885     cmd_AddParm(ts, "-partition", CMD_SINGLE, CMD_OPTIONAL,
1886                 "limit entries to a particular partition");
1887     SetupCommonCmdArgs(ts);
1888
1889     ts = cmd_CreateSyntax("VosVLDBEntryRemove", DoVosVLDBEntryRemove, NULL,
1890                           "remove vldb entries");
1891     cmd_AddParm(ts, "-server", CMD_SINGLE, CMD_OPTIONAL,
1892                 "limit entries to a particular server");
1893     cmd_AddParm(ts, "-partition", CMD_SINGLE, CMD_OPTIONAL,
1894                 "limit entries to a particular partition");
1895     cmd_AddParm(ts, "-volume", CMD_SINGLE, CMD_OPTIONAL, "volume to remove");
1896     SetupCommonCmdArgs(ts);
1897
1898     ts = cmd_CreateSyntax("VosVLDBUnlock", DoVosVLDBUnlock, NULL,
1899                           "unlock a group of vldb entries");
1900     cmd_AddParm(ts, "-server", CMD_SINGLE, CMD_OPTIONAL,
1901                 "limit entries to a particular server");
1902     cmd_AddParm(ts, "-partition", CMD_SINGLE, CMD_OPTIONAL,
1903                 "limit entries to a particular partition");
1904     SetupCommonCmdArgs(ts);
1905
1906     ts = cmd_CreateSyntax("VosVLDBEntryLock", DoVosVLDBList, NULL,
1907                           "lock a single vldb entry");
1908     cmd_AddParm(ts, "-volume", CMD_SINGLE, CMD_REQUIRED, "volume to lock");
1909     SetupCommonCmdArgs(ts);
1910
1911     ts = cmd_CreateSyntax("VosVLDBEntryUnlock", DoVosVLDBEntryUnlock, NULL,
1912                           "unlock a single vldb entry");
1913     cmd_AddParm(ts, "-volume", CMD_SINGLE, CMD_REQUIRED, "volume to unlock");
1914     SetupCommonCmdArgs(ts);
1915
1916     ts = cmd_CreateSyntax("VosVLDBReadOnlySiteCreate",
1917                           DoVosVLDBReadOnlySiteCreate, NULL,
1918                           "create a read only site");
1919     cmd_AddParm(ts, "-server", CMD_SINGLE, CMD_REQUIRED,
1920                 "server where read only will be created");
1921     cmd_AddParm(ts, "-partition", CMD_SINGLE, CMD_REQUIRED,
1922                 "partition where read only will be created");
1923     cmd_AddParm(ts, "-volume", CMD_SINGLE, CMD_REQUIRED,
1924                 "volume to replicate");
1925     SetupCommonCmdArgs(ts);
1926
1927     ts = cmd_CreateSyntax("VosVLDBReadOnlySiteDelete",
1928                           DoVosVLDBReadOnlySiteDelete, NULL,
1929                           "delete a read only site before initial replication");
1930     cmd_AddParm(ts, "-server", CMD_SINGLE, CMD_OPTIONAL,
1931                 "server where read only will be deleted");
1932     cmd_AddParm(ts, "-partition", CMD_SINGLE, CMD_OPTIONAL,
1933                 "partition where read only will be deleted");
1934     cmd_AddParm(ts, "-volume", CMD_SINGLE, CMD_REQUIRED, "volume to delete");
1935     SetupCommonCmdArgs(ts);
1936
1937     ts = cmd_CreateSyntax("VosVLDBSync", DoVosVLDBSync, NULL,
1938                           "sync vldb with server");
1939     cmd_AddParm(ts, "-server", CMD_SINGLE, CMD_REQUIRED, "server to sync");
1940     cmd_AddParm(ts, "-partition", CMD_SINGLE, CMD_OPTIONAL,
1941                 "limit sync to a particular partition");
1942     cmd_AddParm(ts, "-force", CMD_FLAG, CMD_OPTIONAL, "force sync to occur");
1943     SetupCommonCmdArgs(ts);
1944
1945     ts = cmd_CreateSyntax("VosVolumeCreate", DoVosVolumeCreate, NULL,
1946                           "create a read write volume");
1947     cmd_AddParm(ts, "-server", CMD_SINGLE, CMD_REQUIRED,
1948                 "server where volume will be created");
1949     cmd_AddParm(ts, "-partition", CMD_SINGLE, CMD_REQUIRED,
1950                 "partition where volume will be created");
1951     cmd_AddParm(ts, "-volume", CMD_SINGLE, CMD_REQUIRED,
1952                 "name of new volume");
1953     cmd_AddParm(ts, "-quota", CMD_SINGLE, CMD_REQUIRED,
1954                 "size quota of new volume in 1kb units");
1955     SetupCommonCmdArgs(ts);
1956
1957     ts = cmd_CreateSyntax("VosVolumeDelete", DoVosVolumeDelete, NULL,
1958                           "delete a volume");
1959     cmd_AddParm(ts, "-server", CMD_SINGLE, CMD_REQUIRED,
1960                 "server where volume exists");
1961     cmd_AddParm(ts, "-partition", CMD_SINGLE, CMD_REQUIRED,
1962                 "partition where volume exists");
1963     cmd_AddParm(ts, "-volume", CMD_SINGLE, CMD_REQUIRED, "volume to delete");
1964     SetupCommonCmdArgs(ts);
1965
1966     ts = cmd_CreateSyntax("VosVolumeRename", DoVosVolumeRename, NULL,
1967                           "rename a volume");
1968     cmd_AddParm(ts, "-oldname", CMD_SINGLE, CMD_REQUIRED, "old volume name");
1969     cmd_AddParm(ts, "-newname", CMD_SINGLE, CMD_REQUIRED, "new volume name");
1970     SetupCommonCmdArgs(ts);
1971
1972     ts = cmd_CreateSyntax("VosVolumeDump", DoVosVolumeDump, NULL,
1973                           "dump a volume to a file");
1974     cmd_AddParm(ts, "-server", CMD_SINGLE, CMD_OPTIONAL,
1975                 "dump volume at a particular server");
1976     cmd_AddParm(ts, "-partition", CMD_SINGLE, CMD_OPTIONAL,
1977                 "dump volume at a particular partition");
1978     cmd_AddParm(ts, "-volume", CMD_SINGLE, CMD_REQUIRED, "volume to dump");
1979     cmd_AddParm(ts, "-starttime", CMD_SINGLE, CMD_REQUIRED,
1980                 "files modified after this time will be dumped");
1981     cmd_AddParm(ts, "-dumpfile", CMD_SINGLE, CMD_REQUIRED,
1982                 "file to contain dump results");
1983     SetupCommonCmdArgs(ts);
1984
1985     ts = cmd_CreateSyntax("VosVolumeRestore", DoVosVolumeRestore, NULL,
1986                           "restore a volume from a dumpfile");
1987     cmd_AddParm(ts, "-server", CMD_SINGLE, CMD_REQUIRED,
1988                 "server that houses volume to restore");
1989     cmd_AddParm(ts, "-partition", CMD_SINGLE, CMD_REQUIRED,
1990                 "partition that houses volume to restore");
1991     cmd_AddParm(ts, "-id", CMD_SINGLE, CMD_OPTIONAL, "id of volume restored");
1992     cmd_AddParm(ts, "-volume", CMD_SINGLE, CMD_REQUIRED,
1993                 "name of volume restored");
1994     cmd_AddParm(ts, "-dumpfile", CMD_SINGLE, CMD_REQUIRED,
1995                 "file contained dump of volume");
1996     cmd_AddParm(ts, "-full", CMD_FLAG, CMD_OPTIONAL,
1997                 "does a full restore of volume");
1998     SetupCommonCmdArgs(ts);
1999
2000     ts = cmd_CreateSyntax("VosVolumeOnline", DoVosVolumeOnline, NULL,
2001                           "bring a volume online");
2002     cmd_AddParm(ts, "-server", CMD_SINGLE, CMD_REQUIRED,
2003                 "server that houses volume");
2004     cmd_AddParm(ts, "-partition", CMD_SINGLE, CMD_REQUIRED,
2005                 "partition that houses volume");
2006     cmd_AddParm(ts, "-volume", CMD_SINGLE, CMD_REQUIRED,
2007                 "volume to bring online");
2008     cmd_AddParm(ts, "-sleep", CMD_SINGLE, CMD_REQUIRED, "seconds to sleep");
2009     cmd_AddParm(ts, "-busy", CMD_FLAG, CMD_OPTIONAL, "mark volume busy");
2010     SetupCommonCmdArgs(ts);
2011
2012     ts = cmd_CreateSyntax("VosVolumeOffline", DoVosVolumeOffline, NULL,
2013                           "take a volume offline");
2014     cmd_AddParm(ts, "-server", CMD_SINGLE, CMD_REQUIRED,
2015                 "server that houses volume");
2016     cmd_AddParm(ts, "-partition", CMD_SINGLE, CMD_REQUIRED,
2017                 "partition that houses volume");
2018     cmd_AddParm(ts, "-volume", CMD_SINGLE, CMD_REQUIRED,
2019                 "volume to bring offline");
2020     SetupCommonCmdArgs(ts);
2021
2022     ts = cmd_CreateSyntax("VosVolumeGet", DoVosVolumeGet, NULL,
2023                           "get a volume entry");
2024     cmd_AddParm(ts, "-server", CMD_SINGLE, CMD_REQUIRED,
2025                 "server that houses volume");
2026     cmd_AddParm(ts, "-partition", CMD_SINGLE, CMD_REQUIRED,
2027                 "partition that houses volume");
2028     cmd_AddParm(ts, "-volume", CMD_SINGLE, CMD_REQUIRED,
2029                 "volume to retrieve");
2030     SetupCommonCmdArgs(ts);
2031
2032     ts = cmd_CreateSyntax("VosVolumeList", DoVosVolumeList, NULL,
2033                           "list a group of volumes");
2034     cmd_AddParm(ts, "-server", CMD_SINGLE, CMD_REQUIRED,
2035                 "limit volumes to a particular server");
2036     cmd_AddParm(ts, "-partition", CMD_SINGLE, CMD_REQUIRED,
2037                 "limit volumes to a particular partition");
2038     SetupCommonCmdArgs(ts);
2039
2040     ts = cmd_CreateSyntax("VosVolumeMove", DoVosVolumeMove, NULL,
2041                           "move a volume");
2042     cmd_AddParm(ts, "-volume", CMD_SINGLE, CMD_REQUIRED, "volume to move");
2043     cmd_AddParm(ts, "-fromserver", CMD_SINGLE, CMD_REQUIRED, "source server");
2044     cmd_AddParm(ts, "-frompartition", CMD_SINGLE, CMD_REQUIRED,
2045                 "source partition");
2046     cmd_AddParm(ts, "-toserver", CMD_SINGLE, CMD_REQUIRED,
2047                 "destination server");
2048     cmd_AddParm(ts, "-topartition", CMD_SINGLE, CMD_REQUIRED,
2049                 "destination partition");
2050     SetupCommonCmdArgs(ts);
2051
2052     ts = cmd_CreateSyntax("VosVolumeRelease", DoVosVolumeRelease, NULL,
2053                           "release updates to read only");
2054     cmd_AddParm(ts, "-volume", CMD_SINGLE, CMD_REQUIRED,
2055                 "volume to replicate");
2056     cmd_AddParm(ts, "-force", CMD_FLAG, CMD_OPTIONAL,
2057                 "force release to occur");
2058     SetupCommonCmdArgs(ts);
2059
2060     ts = cmd_CreateSyntax("VosVolumeZap", DoVosVolumeZap, NULL, "zap a volume");
2061     cmd_AddParm(ts, "-server", CMD_SINGLE, CMD_REQUIRED,
2062                 "server that houses the volume to zap");
2063     cmd_AddParm(ts, "-partition", CMD_SINGLE, CMD_REQUIRED,
2064                 "partition that houses the volume to zap");
2065     cmd_AddParm(ts, "-volume", CMD_SINGLE, CMD_REQUIRED, "volume to zap");
2066     cmd_AddParm(ts, "-force", CMD_FLAG, CMD_OPTIONAL, "force zap");
2067     SetupCommonCmdArgs(ts);
2068
2069     ts = cmd_CreateSyntax("VosPartitionNameToId", DoVosPartitionNameToId, NULL,
2070                           "convert a partition name to a number");
2071     cmd_AddParm(ts, "-partition", CMD_SINGLE, CMD_REQUIRED,
2072                 "partition to convert");
2073     SetupCommonCmdArgs(ts);
2074
2075     ts = cmd_CreateSyntax("VosPartitionIdToName", DoVosPartitionIdToName, NULL,
2076                           "convert a number to a partition");
2077     cmd_AddParm(ts, "-id", CMD_SINGLE, CMD_REQUIRED, "number to convert");
2078     SetupCommonCmdArgs(ts);
2079
2080     ts = cmd_CreateSyntax("VosVolumeQuotaChange", DoVosVolumeQuotaChange, NULL,
2081                           "change the quota for a partition");
2082     cmd_AddParm(ts, "-server", CMD_SINGLE, CMD_REQUIRED,
2083                 "server that houses the volume");
2084     cmd_AddParm(ts, "-partition", CMD_SINGLE, CMD_REQUIRED,
2085                 "partition that houses the volume");
2086     cmd_AddParm(ts, "-volume", CMD_SINGLE, CMD_REQUIRED, "volume to change");
2087     cmd_AddParm(ts, "-quota", CMD_SINGLE, CMD_REQUIRED,
2088                 "new quota in 1kb units");
2089     SetupCommonCmdArgs(ts);
2090
2091     ts = cmd_CreateSyntax("VosVolumeGet2", DoVosVolumeGet2, NULL,
2092                           "get a volume entry");
2093     cmd_AddParm(ts, "-server", CMD_SINGLE, CMD_REQUIRED,
2094                 "server that houses volume");
2095     cmd_AddParm(ts, "-partition", CMD_SINGLE, CMD_REQUIRED,
2096                 "partition that houses volume");
2097     cmd_AddParm(ts, "-volume", CMD_SINGLE, CMD_REQUIRED,
2098                 "volume to retrieve");
2099     SetupCommonCmdArgs(ts);
2100     
2101     ts = cmd_CreateSyntax("ClearVolUpdateCounter", DoVos_ClearVolUpdateCounter, NULL,
2102                           "clear volUpdateCounter");
2103     cmd_AddParm(ts, "-server", CMD_SINGLE, CMD_REQUIRED,
2104                 "server that houses volume");
2105     cmd_AddParm(ts, "-partition", CMD_SINGLE, CMD_REQUIRED,
2106                 "partition that houses volume");
2107     cmd_AddParm(ts, "-volume", CMD_SINGLE, CMD_REQUIRED,
2108                 "volume");
2109     SetupCommonCmdArgs(ts);
2110
2111 }
2112