2 * Copyright 2000, International Business Machines Corporation and others.
5 * This software has been released under the terms of the IBM Public
6 * License. For details, see the LICENSE file in the top-level source
7 * directory or online at http://www.openafs.org/dl/license10.html
10 #include <afsconfig.h>
11 #include <afs/param.h>
13 #ifdef IGNORE_SOME_GCC_WARNINGS
14 # pragma GCC diagnostic warning "-Wimplicit-function-declaration"
17 #include <sys/types.h>
27 #include <netinet/in.h>
28 #include <arpa/inet.h>
32 #include <sys/statfs.h>
40 #include <rx/rx_globals.h>
42 #include <afs/vlserver.h>
43 #include <afs/cellconfig.h>
45 #include <afs/afsutil.h>
47 #include <afs/afsint.h>
52 #include <afs/ihandle.h>
53 #include <afs/vnode.h>
54 #include <afs/volume.h>
61 #include "volser_prototypes.h"
62 #include "vsutils_prototypes.h"
63 #include "lockprocs_prototypes.h"
65 #ifdef HAVE_POSIX_REGEX
69 /* Local Prototypes */
70 int PrintDiagnostics(char *astring, afs_int32 acode);
71 int GetVolumeInfo(afs_uint32 volid, afs_int32 *server, afs_int32 *part,
72 afs_int32 *voltype, struct nvldbentry *rentry);
84 #define COMMONPARMS cmd_Seek(ts, 12);\
85 cmd_AddParm(ts, "-cell", CMD_SINGLE, CMD_OPTIONAL, "cell name");\
86 cmd_AddParm(ts, "-noauth", CMD_FLAG, CMD_OPTIONAL, "don't authenticate");\
87 cmd_AddParm(ts, "-localauth",CMD_FLAG,CMD_OPTIONAL,"use server tickets");\
88 cmd_AddParm(ts, "-verbose", CMD_FLAG, CMD_OPTIONAL, "verbose");\
89 cmd_AddParm(ts, "-encrypt", CMD_FLAG, CMD_OPTIONAL, "encrypt commands");\
90 cmd_AddParm(ts, "-noresolve", CMD_FLAG, CMD_OPTIONAL, "don't resolve addresses"); \
92 #define ERROR_EXIT(code) {error=(code); goto error_exit;}
95 struct rx_connection *tconn;
97 extern struct ubik_client *cstruct;
100 static struct tqHead busyHead, notokHead;
103 qInit(struct tqHead *ahead)
105 memset((char *)ahead, 0, sizeof(struct tqHead));
111 qPut(struct tqHead *ahead, afs_uint32 volid)
115 elem = (struct tqElem *)malloc(sizeof(struct tqElem));
116 elem->next = ahead->next;
124 qGet(struct tqHead *ahead, afs_uint32 *volid)
128 if (ahead->count <= 0)
130 *volid = ahead->next->volid;
132 ahead->next = tmp->next;
138 /* returns 1 if <filename> exists else 0 */
140 FileExists(char *filename)
146 code = usd_Open(filename, USD_OPEN_RDONLY, 0, &ufd);
150 code = USD_IOCTL(ufd, USD_IOCTL_GETSIZE, &size);
158 /* returns 1 if <name> doesnot end in .readonly or .backup, else 0 */
160 VolNameOK(char *name)
165 total = strlen(name);
166 if (!strcmp(&name[total - 9], ".readonly")) {
168 } else if (!strcmp(&name[total - 7], ".backup")) {
175 /* return 1 if name is a number else 0 */
177 IsNumeric(char *name)
185 for (i = 0; i < len; i++) {
186 if (*ptr < '0' || *ptr > '9') {
198 * Parse a server name/address and return the address in HOST BYTE order
201 GetServer(char *aname)
203 register struct hostent *th;
206 register afs_int32 code;
207 char hostname[MAXHOSTCHARS];
209 code = sscanf(aname, "%d.%d.%d.%d", &b1, &b2, &b3, &b4);
211 addr = (b1 << 24) | (b2 << 16) | (b3 << 8) | b4;
212 addr = ntohl(addr); /* convert to host order */
214 th = gethostbyname(aname);
217 memcpy(&addr, th->h_addr, sizeof(addr));
220 if (addr == htonl(0x7f000001)) { /* local host */
221 code = gethostname(hostname, MAXHOSTCHARS);
224 th = gethostbyname(hostname); /* returns host byte order */
227 memcpy(&addr, th->h_addr, sizeof(addr));
234 GetVolumeType(char *aname)
237 if (!strcmp(aname, "ro"))
239 else if (!strcmp(aname, "rw"))
241 else if (!strcmp(aname, "bk"))
248 IsPartValid(afs_int32 partId, afs_int32 server, afs_int32 *code)
250 struct partList dummyPartList;
256 *code = UV_ListPartitions(server, &dummyPartList, &cnt);
259 for (i = 0; i < cnt; i++) {
260 if (dummyPartList.partFlags[i] & PARTVALID)
261 if (dummyPartList.partId[i] == partId)
269 /*sends the contents of file associated with <fd> and <blksize> to Rx Stream
270 * associated with <call> */
272 SendFile(usd_handle_t ufd, register struct rx_call *call, long blksize)
274 char *buffer = (char *)0;
279 buffer = (char *)malloc(blksize);
281 fprintf(STDERR, "malloc failed\n");
285 while (!error && !done) {
286 #ifndef AFS_NT40_ENV /* NT csn't select on non-socket fd's */
289 FD_SET((intptr_t)(ufd->handle), &in);
290 /* don't timeout if read blocks */
291 #if defined(AFS_PTHREAD_ENV)
292 select(((int)(ufd->handle)) + 1, &in, 0, 0, 0);
294 IOMGR_Select(((intptr_t)(ufd->handle)) + 1, &in, 0, 0, 0);
297 error = USD_READ(ufd, buffer, blksize, &nbytes);
299 fprintf(STDERR, "File system read failed\n");
306 if (rx_Write(call, buffer, nbytes) != nbytes) {
316 /* function invoked by UV_RestoreVolume, reads the data from rx_trx_stream and
317 * writes it out to the volume. */
319 WriteData(struct rx_call *call, void *rock)
321 char *filename = (char *) rock;
324 afs_int32 error, code;
326 afs_hyper_t filesize, currOffset;
332 if (!filename || !*filename) {
333 usd_StandardInput(&ufd);
337 code = usd_Open(filename, USD_OPEN_RDONLY, 0, &ufd);
340 code = USD_IOCTL(ufd, USD_IOCTL_GETBLKSIZE, &blksize);
343 fprintf(STDERR, "Could not access file '%s'\n", filename);
347 /* test if we have a valid dump */
348 hset64(filesize, 0, 0);
349 USD_SEEK(ufd, filesize, SEEK_END, &currOffset);
350 hset64(filesize, hgethi(currOffset), hgetlo(currOffset)-sizeof(afs_uint32));
351 USD_SEEK(ufd, filesize, SEEK_SET, &currOffset);
352 USD_READ(ufd, (char *)&buffer, sizeof(afs_uint32), &got);
353 if ((got != sizeof(afs_uint32)) || (ntohl(buffer) != DUMPENDMAGIC)) {
354 fprintf(STDERR, "Signature missing from end of file '%s'\n", filename);
358 /* rewind, we are done */
359 hset64(filesize, 0, 0);
360 USD_SEEK(ufd, filesize, SEEK_SET, &currOffset);
362 code = SendFile(ufd, call, blksize);
369 code = USD_CLOSE(ufd);
371 fprintf(STDERR, "Could not close dump file %s\n",
372 (filename && *filename) ? filename : "STDOUT");
380 /* Receive data from <call> stream into file associated
381 * with <fd> <blksize>
384 ReceiveFile(usd_handle_t ufd, struct rx_call *call, long blksize)
388 afs_uint32 bytesleft, w;
391 buffer = (char *)malloc(blksize);
393 fprintf(STDERR, "memory allocation failed\n");
397 while ((bytesread = rx_Read(call, buffer, blksize)) > 0) {
398 for (bytesleft = bytesread; bytesleft; bytesleft -= w) {
399 #ifndef AFS_NT40_ENV /* NT csn't select on non-socket fd's */
402 FD_SET((intptr_t)(ufd->handle), &out);
403 /* don't timeout if write blocks */
404 #if defined(AFS_PTHREAD_ENV)
405 select(((int)(ufd->handle)) + 1, &out, 0, 0, 0);
407 IOMGR_Select(((intptr_t)(ufd->handle)) + 1, 0, &out, 0, 0);
411 USD_WRITE(ufd, &buffer[bytesread - bytesleft], bytesleft, &w);
413 fprintf(STDERR, "File system write failed\n");
426 DumpFunction(struct rx_call *call, void *rock)
428 char *filename = (char *)rock;
429 usd_handle_t ufd; /* default is to stdout */
430 afs_int32 error = 0, code;
435 /* Open the output file */
436 if (!filename || !*filename) {
437 usd_StandardOutput(&ufd);
442 usd_Open(filename, USD_OPEN_CREATE | USD_OPEN_RDWR, 0666, &ufd);
446 code = USD_IOCTL(ufd, USD_IOCTL_SETSIZE, &size);
449 code = USD_IOCTL(ufd, USD_IOCTL_GETBLKSIZE, &blksize);
452 fprintf(STDERR, "Could not create file '%s'\n", filename);
453 ERROR_EXIT(VOLSERBADOP);
457 code = ReceiveFile(ufd, call, blksize);
462 /* Close the output file */
464 code = USD_CLOSE(ufd);
466 fprintf(STDERR, "Could not close dump file %s\n",
467 (filename && *filename) ? filename : "STDIN");
477 DisplayFormat(volintInfo *pntr, afs_int32 server, afs_int32 part,
478 int *totalOK, int *totalNotOK, int *totalBusy, int fast,
479 int longlist, int disp)
485 fprintf(STDOUT, "%-10lu\n", (unsigned long)pntr->volid);
486 } else if (longlist) {
487 if (pntr->status == VOK) {
488 fprintf(STDOUT, "%-32s ", pntr->name);
489 fprintf(STDOUT, "%10lu ", (unsigned long)pntr->volid);
491 fprintf(STDOUT, "RW ");
493 fprintf(STDOUT, "RO ");
495 fprintf(STDOUT, "BK ");
496 fprintf(STDOUT, "%10d K ", pntr->size);
497 if (pntr->inUse == 1) {
498 fprintf(STDOUT, "On-line");
501 fprintf(STDOUT, "Off-line");
504 if (pntr->needsSalvaged == 1)
505 fprintf(STDOUT, "**needs salvage**");
506 fprintf(STDOUT, "\n");
507 MapPartIdIntoName(part, pname);
508 fprintf(STDOUT, " %s %s \n", hostutil_GetNameByINet(server),
510 fprintf(STDOUT, " RWrite %10lu ROnly %10lu Backup %10lu \n",
511 (unsigned long)pntr->parentID,
512 (unsigned long)pntr->cloneID,
513 (unsigned long)pntr->backupID);
514 fprintf(STDOUT, " MaxQuota %10d K \n", pntr->maxquota);
515 t = pntr->creationDate;
516 fprintf(STDOUT, " Creation %s",
518 #ifdef FULL_LISTVOL_SWITCH
520 fprintf(STDOUT, " Copy %s",
523 t = pntr->backupDate;
525 fprintf(STDOUT, " Backup Never\n");
527 fprintf(STDOUT, " Backup %s",
530 t = pntr->accessDate;
532 fprintf(STDOUT, " Last Access %s",
535 t = pntr->updateDate;
537 fprintf(STDOUT, " Last Update Never\n");
539 fprintf(STDOUT, " Last Update %s",
542 " %d accesses in the past day (i.e., vnode references)\n",
544 } else if (pntr->status == VBUSY) {
546 qPut(&busyHead, pntr->volid);
548 fprintf(STDOUT, "**** Volume %lu is busy ****\n",
549 (unsigned long)pntr->volid);
552 qPut(¬okHead, pntr->volid);
554 fprintf(STDOUT, "**** Could not attach volume %lu ****\n",
555 (unsigned long)pntr->volid);
557 fprintf(STDOUT, "\n");
558 } else { /* default listing */
559 if (pntr->status == VOK) {
560 fprintf(STDOUT, "%-32s ", pntr->name);
561 fprintf(STDOUT, "%10lu ", (unsigned long)pntr->volid);
563 fprintf(STDOUT, "RW ");
565 fprintf(STDOUT, "RO ");
567 fprintf(STDOUT, "BK ");
568 fprintf(STDOUT, "%10d K ", pntr->size);
569 if (pntr->inUse == 1) {
570 fprintf(STDOUT, "On-line");
573 fprintf(STDOUT, "Off-line");
576 if (pntr->needsSalvaged == 1)
577 fprintf(STDOUT, "**needs salvage**");
578 fprintf(STDOUT, "\n");
579 } else if (pntr->status == VBUSY) {
581 qPut(&busyHead, pntr->volid);
583 fprintf(STDOUT, "**** Volume %lu is busy ****\n",
584 (unsigned long)pntr->volid);
587 qPut(¬okHead, pntr->volid);
589 fprintf(STDOUT, "**** Could not attach volume %lu ****\n",
590 (unsigned long)pntr->volid);
595 /*------------------------------------------------------------------------
596 * PRIVATE XDisplayFormat
599 * Display the contents of one extended volume info structure.
602 * a_xInfoP : Ptr to extended volume info struct to print.
603 * a_servID : Server ID to print.
604 * a_partID : Partition ID to print.
605 * a_totalOKP : Ptr to total-OK counter.
606 * a_totalNotOKP : Ptr to total-screwed counter.
607 * a_totalBusyP : Ptr to total-busy counter.
608 * a_fast : Fast listing?
609 * a_int32 : Int32 listing?
610 * a_showProblems : Show volume problems?
616 * Nothing interesting.
620 *------------------------------------------------------------------------*/
623 XDisplayFormat(volintXInfo *a_xInfoP, afs_int32 a_servID, afs_int32 a_partID,
624 int *a_totalOKP, int *a_totalNotOKP, int *a_totalBusyP,
625 int a_fast, int a_int32, int a_showProblems)
626 { /*XDisplayFormat */
634 fprintf(STDOUT, "%-10lu\n", (unsigned long)a_xInfoP->volid);
635 } else if (a_int32) {
637 * Fully-detailed listing.
639 if (a_xInfoP->status == VOK) {
641 * Volume's status is OK - all the fields are valid.
643 fprintf(STDOUT, "%-32s ", a_xInfoP->name);
644 fprintf(STDOUT, "%10lu ", (unsigned long)a_xInfoP->volid);
645 if (a_xInfoP->type == 0)
646 fprintf(STDOUT, "RW ");
647 if (a_xInfoP->type == 1)
648 fprintf(STDOUT, "RO ");
649 if (a_xInfoP->type == 2)
650 fprintf(STDOUT, "BK ");
651 fprintf(STDOUT, "%10d K used ", a_xInfoP->size);
652 fprintf(STDOUT, "%d files ", a_xInfoP->filecount);
653 if (a_xInfoP->inUse == 1) {
654 fprintf(STDOUT, "On-line");
657 fprintf(STDOUT, "Off-line");
660 fprintf(STDOUT, "\n");
661 MapPartIdIntoName(a_partID, pname);
662 fprintf(STDOUT, " %s %s \n", hostutil_GetNameByINet(a_servID),
664 fprintf(STDOUT, " RWrite %10lu ROnly %10lu Backup %10lu \n",
665 (unsigned long)a_xInfoP->parentID,
666 (unsigned long)a_xInfoP->cloneID,
667 (unsigned long)a_xInfoP->backupID);
668 fprintf(STDOUT, " MaxQuota %10d K \n", a_xInfoP->maxquota);
670 t = a_xInfoP->creationDate;
671 fprintf(STDOUT, " Creation %s",
673 #ifdef FULL_LISTVOL_SWITCH
674 t = a_xInfoP->copyDate;
675 fprintf(STDOUT, " Copy %s",
678 t = a_xInfoP->backupDate;
680 fprintf(STDOUT, " Backup Never\n");
682 fprintf(STDOUT, " Backup %s",
685 t = a_xInfoP->accessDate;
687 fprintf(STDOUT, " Last Access %s",
690 t = a_xInfoP->updateDate;
692 fprintf(STDOUT, " Last Update Never\n");
694 fprintf(STDOUT, " Last Update %s",
697 " %d accesses in the past day (i.e., vnode references)\n",
701 * Print all the read/write and authorship stats.
703 fprintf(STDOUT, "\n Raw Read/Write Stats\n");
705 " |-------------------------------------------|\n");
707 " | Same Network | Diff Network |\n");
709 " |----------|----------|----------|----------|\n");
711 " | Total | Auth | Total | Auth |\n");
713 " |----------|----------|----------|----------|\n");
714 fprintf(STDOUT, "Reads | %8d | %8d | %8d | %8d |\n",
715 a_xInfoP->stat_reads[VOLINT_STATS_SAME_NET],
716 a_xInfoP->stat_reads[VOLINT_STATS_SAME_NET_AUTH],
717 a_xInfoP->stat_reads[VOLINT_STATS_DIFF_NET],
718 a_xInfoP->stat_reads[VOLINT_STATS_DIFF_NET_AUTH]);
719 fprintf(STDOUT, "Writes | %8d | %8d | %8d | %8d |\n",
720 a_xInfoP->stat_writes[VOLINT_STATS_SAME_NET],
721 a_xInfoP->stat_writes[VOLINT_STATS_SAME_NET_AUTH],
722 a_xInfoP->stat_writes[VOLINT_STATS_DIFF_NET],
723 a_xInfoP->stat_writes[VOLINT_STATS_DIFF_NET_AUTH]);
725 " |-------------------------------------------|\n\n");
728 " Writes Affecting Authorship\n");
730 " |-------------------------------------------|\n");
732 " | File Authorship | Directory Authorship|\n");
734 " |----------|----------|----------|----------|\n");
736 " | Same | Diff | Same | Diff |\n");
738 " |----------|----------|----------|----------|\n");
739 fprintf(STDOUT, "0-60 sec | %8d | %8d | %8d | %8d |\n",
740 a_xInfoP->stat_fileSameAuthor[VOLINT_STATS_TIME_IDX_0],
741 a_xInfoP->stat_fileDiffAuthor[VOLINT_STATS_TIME_IDX_0],
742 a_xInfoP->stat_dirSameAuthor[VOLINT_STATS_TIME_IDX_0],
743 a_xInfoP->stat_dirDiffAuthor[VOLINT_STATS_TIME_IDX_0]);
744 fprintf(STDOUT, "1-10 min | %8d | %8d | %8d | %8d |\n",
745 a_xInfoP->stat_fileSameAuthor[VOLINT_STATS_TIME_IDX_1],
746 a_xInfoP->stat_fileDiffAuthor[VOLINT_STATS_TIME_IDX_1],
747 a_xInfoP->stat_dirSameAuthor[VOLINT_STATS_TIME_IDX_1],
748 a_xInfoP->stat_dirDiffAuthor[VOLINT_STATS_TIME_IDX_1]);
749 fprintf(STDOUT, "10min-1hr | %8d | %8d | %8d | %8d |\n",
750 a_xInfoP->stat_fileSameAuthor[VOLINT_STATS_TIME_IDX_2],
751 a_xInfoP->stat_fileDiffAuthor[VOLINT_STATS_TIME_IDX_2],
752 a_xInfoP->stat_dirSameAuthor[VOLINT_STATS_TIME_IDX_2],
753 a_xInfoP->stat_dirDiffAuthor[VOLINT_STATS_TIME_IDX_2]);
754 fprintf(STDOUT, "1hr-1day | %8d | %8d | %8d | %8d |\n",
755 a_xInfoP->stat_fileSameAuthor[VOLINT_STATS_TIME_IDX_3],
756 a_xInfoP->stat_fileDiffAuthor[VOLINT_STATS_TIME_IDX_3],
757 a_xInfoP->stat_dirSameAuthor[VOLINT_STATS_TIME_IDX_3],
758 a_xInfoP->stat_dirDiffAuthor[VOLINT_STATS_TIME_IDX_3]);
759 fprintf(STDOUT, "1day-1wk | %8d | %8d | %8d | %8d |\n",
760 a_xInfoP->stat_fileSameAuthor[VOLINT_STATS_TIME_IDX_4],
761 a_xInfoP->stat_fileDiffAuthor[VOLINT_STATS_TIME_IDX_4],
762 a_xInfoP->stat_dirSameAuthor[VOLINT_STATS_TIME_IDX_4],
763 a_xInfoP->stat_dirDiffAuthor[VOLINT_STATS_TIME_IDX_4]);
764 fprintf(STDOUT, "> 1wk | %8d | %8d | %8d | %8d |\n",
765 a_xInfoP->stat_fileSameAuthor[VOLINT_STATS_TIME_IDX_5],
766 a_xInfoP->stat_fileDiffAuthor[VOLINT_STATS_TIME_IDX_5],
767 a_xInfoP->stat_dirSameAuthor[VOLINT_STATS_TIME_IDX_5],
768 a_xInfoP->stat_dirDiffAuthor[VOLINT_STATS_TIME_IDX_5]);
770 " |-------------------------------------------|\n");
771 } /*Volume status OK */
772 else if (a_xInfoP->status == VBUSY) {
774 qPut(&busyHead, a_xInfoP->volid);
776 fprintf(STDOUT, "**** Volume %lu is busy ****\n",
777 (unsigned long)a_xInfoP->volid);
781 qPut(¬okHead, a_xInfoP->volid);
783 fprintf(STDOUT, "**** Could not attach volume %lu ****\n",
784 (unsigned long)a_xInfoP->volid);
785 } /*Screwed volume */
786 fprintf(STDOUT, "\n");
792 if (a_xInfoP->status == VOK) {
793 fprintf(STDOUT, "%-32s ", a_xInfoP->name);
794 fprintf(STDOUT, "%10lu ", (unsigned long)a_xInfoP->volid);
795 if (a_xInfoP->type == 0)
796 fprintf(STDOUT, "RW ");
797 if (a_xInfoP->type == 1)
798 fprintf(STDOUT, "RO ");
799 if (a_xInfoP->type == 2)
800 fprintf(STDOUT, "BK ");
801 fprintf(STDOUT, "%10d K ", a_xInfoP->size);
802 if (a_xInfoP->inUse == 1) {
803 fprintf(STDOUT, "On-line");
806 fprintf(STDOUT, "Off-line");
809 fprintf(STDOUT, "\n");
811 else if (a_xInfoP->status == VBUSY) {
813 qPut(&busyHead, a_xInfoP->volid);
815 fprintf(STDOUT, "**** Volume %lu is busy ****\n",
816 (unsigned long)a_xInfoP->volid);
820 qPut(¬okHead, a_xInfoP->volid);
822 fprintf(STDOUT, "**** Could not attach volume %lu ****\n",
823 (unsigned long)a_xInfoP->volid);
824 } /*Screwed volume */
825 } /*Default listing */
826 } /*XDisplayFormat */
828 #ifdef FULL_LISTVOL_SWITCH
829 /*------------------------------------------------------------------------
830 * PRIVATE XDisplayFormat2
833 * Display the formated contents of one extended volume info structure.
836 * a_xInfoP : Ptr to extended volume info struct to print.
837 * a_servID : Server ID to print.
838 * a_partID : Partition ID to print.
839 * a_totalOKP : Ptr to total-OK counter.
840 * a_totalNotOKP : Ptr to total-screwed counter.
841 * a_totalBusyP : Ptr to total-busy counter.
842 * a_fast : Fast listing?
843 * a_int32 : Int32 listing?
844 * a_showProblems : Show volume problems?
850 * Nothing interesting.
854 *------------------------------------------------------------------------*/
857 XDisplayFormat2(volintXInfo *a_xInfoP, afs_int32 a_servID, afs_int32 a_partID,
858 int *a_totalOKP, int *a_totalNotOKP, int *a_totalBusyP,
859 int a_fast, int a_int32, int a_showProblems)
860 { /*XDisplayFormat */
866 fprintf(STDOUT, "vold_id\t%-10lu\n", (unsigned long)a_xInfoP->volid);
867 } else if (a_int32) {
869 * Fully-detailed listing.
871 if (a_xInfoP->status == VOK) {
873 * Volume's status is OK - all the fields are valid.
876 static long server_cache = -1, partition_cache = -1;
877 static char hostname[256], address[32], pname[16];
878 int i,ai[] = {VOLINT_STATS_TIME_IDX_0,VOLINT_STATS_TIME_IDX_1,VOLINT_STATS_TIME_IDX_2,
879 VOLINT_STATS_TIME_IDX_3,VOLINT_STATS_TIME_IDX_4,VOLINT_STATS_TIME_IDX_5};
881 if (a_servID != server_cache) {
885 strcpy(hostname, hostutil_GetNameByINet(a_servID));
886 strcpy(address, inet_ntoa(s));
887 server_cache = a_servID;
889 if (a_partID != partition_cache) {
890 MapPartIdIntoName(a_partID, pname);
891 partition_cache = a_partID;
894 fprintf(STDOUT, "name\t\t%s\n", a_xInfoP->name);
895 fprintf(STDOUT, "id\t\t%lu\n", afs_printable_uint32_lu(a_xInfoP->volid));
896 fprintf(STDOUT, "serv\t\t%s\t%s\n", address, hostname);
897 fprintf(STDOUT, "part\t\t%s\n", pname);
898 fprintf(STDOUT, "status\t\tOK\n");
899 fprintf(STDOUT, "backupID\t%lu\n",
900 afs_printable_uint32_lu(a_xInfoP->backupID));
901 fprintf(STDOUT, "parentID\t%lu\n",
902 afs_printable_uint32_lu(a_xInfoP->parentID));
903 fprintf(STDOUT, "cloneID\t\t%lu\n",
904 afs_printable_uint32_lu(a_xInfoP->cloneID));
905 fprintf(STDOUT, "inUse\t\t%s\n", a_xInfoP->inUse ? "Y" : "N");
906 switch (a_xInfoP->type) {
908 fprintf(STDOUT, "type\t\tRW\n");
911 fprintf(STDOUT, "type\t\tRO\n");
914 fprintf(STDOUT, "type\t\tBK\n");
917 fprintf(STDOUT, "type\t\t?\n");
920 t = a_xInfoP->creationDate;
921 fprintf(STDOUT, "creationDate\t%-9lu\t%s",
922 afs_printable_uint32_lu(a_xInfoP->creationDate),
925 t = a_xInfoP->accessDate;
926 fprintf(STDOUT, "accessDate\t%-9lu\t%s",
927 afs_printable_uint32_lu(a_xInfoP->accessDate),
930 t = a_xInfoP->updateDate;
931 fprintf(STDOUT, "updateDate\t%-9lu\t%s",
932 afs_printable_uint32_lu(a_xInfoP->updateDate),
935 t = a_xInfoP->backupDate;
936 fprintf(STDOUT, "backupDate\t%-9lu\t%s",
937 afs_printable_uint32_lu(a_xInfoP->backupDate),
940 t = a_xInfoP->copyDate;
941 fprintf(STDOUT, "copyDate\t%-9lu\t%s",
942 afs_printable_uint32_lu(a_xInfoP->copyDate),
945 fprintf(STDOUT, "diskused\t%u\n", a_xInfoP->size);
946 fprintf(STDOUT, "maxquota\t%u\n", a_xInfoP->maxquota);
948 fprintf(STDOUT, "filecount\t%u\n", a_xInfoP->filecount);
949 fprintf(STDOUT, "dayUse\t\t%u\n", a_xInfoP->dayUse);
953 fprintf(STDOUT,"reads_same_net\t%8d\n",a_xInfoP->stat_reads[VOLINT_STATS_SAME_NET]);
954 fprintf(STDOUT,"reads_same_net_auth\t%8d\n",a_xInfoP->stat_reads[VOLINT_STATS_SAME_NET_AUTH]);
955 fprintf(STDOUT,"reads_diff_net\t%8d\n",a_xInfoP->stat_reads[VOLINT_STATS_DIFF_NET]);
956 fprintf(STDOUT,"reads_diff_net_auth\t%8d\n",a_xInfoP->stat_reads[VOLINT_STATS_DIFF_NET_AUTH]);
958 fprintf(STDOUT,"writes_same_net\t%8d\n",a_xInfoP->stat_writes[VOLINT_STATS_SAME_NET]);
959 fprintf(STDOUT,"writes_same_net_auth\t%8d\n",a_xInfoP->stat_writes[VOLINT_STATS_SAME_NET_AUTH]);
960 fprintf(STDOUT,"writes_diff_net\t%8d\n",a_xInfoP->stat_writes[VOLINT_STATS_DIFF_NET]);
961 fprintf(STDOUT,"writes_diff_net_auth\t%8d\n",a_xInfoP->stat_writes[VOLINT_STATS_DIFF_NET_AUTH]);
965 fprintf(STDOUT,"file_same_author_idx_%d\t%8d\n",i+1,a_xInfoP->stat_fileSameAuthor[ai[i]]);
966 fprintf(STDOUT,"file_diff_author_idx_%d\t%8d\n",i+1,a_xInfoP->stat_fileDiffAuthor[ai[i]]);
967 fprintf(STDOUT,"dir_same_author_idx_%d\t%8d\n",i+1,a_xInfoP->stat_dirSameAuthor[ai[i]]);
968 fprintf(STDOUT,"dir_dif_author_idx_%d\t%8d\n",i+1,a_xInfoP->stat_dirDiffAuthor[ai[i]]);
971 } /*Volume status OK */
972 else if (a_xInfoP->status == VBUSY) {
974 qPut(&busyHead, a_xInfoP->volid);
976 fprintf(STDOUT, "BUSY_VOL\t%lu\n",
977 (unsigned long)a_xInfoP->volid);
981 qPut(¬okHead, a_xInfoP->volid);
983 fprintf(STDOUT, "COULD_NOT_ATTACH\t%lu\n",
984 (unsigned long)a_xInfoP->volid);
985 } /*Screwed volume */
991 if (a_xInfoP->status == VOK) {
992 fprintf(STDOUT, "name\t%-32s\n", a_xInfoP->name);
993 fprintf(STDOUT, "volID\t%10lu\n", (unsigned long)a_xInfoP->volid);
994 if (a_xInfoP->type == 0)
995 fprintf(STDOUT, "type\tRW\n");
996 if (a_xInfoP->type == 1)
997 fprintf(STDOUT, "type\tRO\n");
998 if (a_xInfoP->type == 2)
999 fprintf(STDOUT, "type\tBK\n");
1000 fprintf(STDOUT, "size\t%10dK\n", a_xInfoP->size);
1002 fprintf(STDOUT, "inUse\t%d\n",a_xInfoP->inUse);
1003 if (a_xInfoP->inUse == 1)
1009 else if (a_xInfoP->status == VBUSY) {
1011 qPut(&busyHead, a_xInfoP->volid);
1013 fprintf(STDOUT, "VOLUME_BUSY\t%lu\n",
1014 (unsigned long)a_xInfoP->volid);
1018 qPut(¬okHead, a_xInfoP->volid);
1020 fprintf(STDOUT, "COULD_NOT_ATTACH_VOLUME\t%lu\n",
1021 (unsigned long)a_xInfoP->volid);
1022 } /*Screwed volume */
1023 } /*Default listing */
1024 } /*XDisplayFormat */
1025 #endif /*FULL_LISTVOL_SWITCH*/
1027 #ifdef FULL_LISTVOL_SWITCH
1029 DisplayFormat2(long server, long partition, volintInfo *pntr)
1031 static long server_cache = -1, partition_cache = -1;
1032 static char hostname[256], address[32], pname[16];
1035 if (server != server_cache) {
1039 strcpy(hostname, hostutil_GetNameByINet(server));
1040 strcpy(address, inet_ntoa(s));
1041 server_cache = server;
1043 if (partition != partition_cache) {
1044 MapPartIdIntoName(partition, pname);
1045 partition_cache = partition;
1048 if (pntr->status == VOK)
1049 fprintf(STDOUT, "name\t\t%s\n", pntr->name);
1051 fprintf(STDOUT, "id\t\t%lu\n",
1052 afs_printable_uint32_lu(pntr->volid));
1053 fprintf(STDOUT, "serv\t\t%s\t%s\n", address, hostname);
1054 fprintf(STDOUT, "part\t\t%s\n", pname);
1055 switch (pntr->status) {
1057 fprintf(STDOUT, "status\t\tOK\n");
1060 fprintf(STDOUT, "status\t\tBUSY\n");
1063 fprintf(STDOUT, "status\t\tUNATTACHABLE\n");
1066 fprintf(STDOUT, "backupID\t%lu\n",
1067 afs_printable_uint32_lu(pntr->backupID));
1068 fprintf(STDOUT, "parentID\t%lu\n",
1069 afs_printable_uint32_lu(pntr->parentID));
1070 fprintf(STDOUT, "cloneID\t\t%lu\n",
1071 afs_printable_uint32_lu(pntr->cloneID));
1072 fprintf(STDOUT, "inUse\t\t%s\n", pntr->inUse ? "Y" : "N");
1073 fprintf(STDOUT, "needsSalvaged\t%s\n", pntr->needsSalvaged ? "Y" : "N");
1074 /* 0xD3 is from afs/volume.h since I had trouble including the file */
1075 fprintf(STDOUT, "destroyMe\t%s\n", pntr->destroyMe == 0xD3 ? "Y" : "N");
1076 switch (pntr->type) {
1078 fprintf(STDOUT, "type\t\tRW\n");
1081 fprintf(STDOUT, "type\t\tRO\n");
1084 fprintf(STDOUT, "type\t\tBK\n");
1087 fprintf(STDOUT, "type\t\t?\n");
1090 t = pntr->creationDate;
1091 fprintf(STDOUT, "creationDate\t%-9lu\t%s",
1092 afs_printable_uint32_lu(pntr->creationDate),
1095 t = pntr->accessDate;
1096 fprintf(STDOUT, "accessDate\t%-9lu\t%s",
1097 afs_printable_uint32_lu(pntr->accessDate),
1100 t = pntr->updateDate;
1101 fprintf(STDOUT, "updateDate\t%-9lu\t%s",
1102 afs_printable_uint32_lu(pntr->updateDate),
1105 t = pntr->backupDate;
1106 fprintf(STDOUT, "backupDate\t%-9lu\t%s",
1107 afs_printable_uint32_lu(pntr->backupDate),
1111 fprintf(STDOUT, "copyDate\t%-9lu\t%s",
1112 afs_printable_uint32_lu(pntr->copyDate),
1115 fprintf(STDOUT, "flags\t\t%#lx\t(Optional)\n",
1116 afs_printable_uint32_lu(pntr->flags));
1117 fprintf(STDOUT, "diskused\t%u\n", pntr->size);
1118 fprintf(STDOUT, "maxquota\t%u\n", pntr->maxquota);
1119 fprintf(STDOUT, "minquota\t%lu\t(Optional)\n",
1120 afs_printable_uint32_lu(pntr->spare0));
1121 fprintf(STDOUT, "filecount\t%u\n", pntr->filecount);
1122 fprintf(STDOUT, "dayUse\t\t%u\n", pntr->dayUse);
1123 fprintf(STDOUT, "weekUse\t\t%lu\t(Optional)\n",
1124 afs_printable_uint32_lu(pntr->spare1));
1125 fprintf(STDOUT, "spare2\t\t%lu\t(Optional)\n",
1126 afs_printable_uint32_lu(pntr->spare2));
1127 fprintf(STDOUT, "spare3\t\t%lu\t(Optional)\n",
1128 afs_printable_uint32_lu(pntr->spare3));
1133 DisplayVolumes2(long server, long partition, volintInfo *pntr, long count)
1137 for (i = 0; i < count; i++) {
1138 fprintf(STDOUT, "BEGIN_OF_ENTRY\n");
1139 DisplayFormat2(server, partition, pntr);
1140 fprintf(STDOUT, "END_OF_ENTRY\n\n");
1145 #endif /* FULL_LISTVOL_SWITCH */
1148 DisplayVolumes(afs_int32 server, afs_int32 part, volintInfo *pntr,
1149 afs_int32 count, afs_int32 longlist, afs_int32 fast,
1152 int totalOK, totalNotOK, totalBusy, i;
1153 afs_uint32 volid = 0;
1160 for (i = 0; i < count; i++) {
1161 DisplayFormat(pntr, server, part, &totalOK, &totalNotOK, &totalBusy,
1166 while (busyHead.count) {
1167 qGet(&busyHead, &volid);
1168 fprintf(STDOUT, "**** Volume %lu is busy ****\n",
1169 (unsigned long)volid);
1173 while (notokHead.count) {
1174 qGet(¬okHead, &volid);
1175 fprintf(STDOUT, "**** Could not attach volume %lu ****\n",
1176 (unsigned long)volid);
1180 fprintf(STDOUT, "\n");
1183 "Total volumes onLine %d ; Total volumes offLine %d ; Total busy %d\n\n",
1184 totalOK, totalNotOK, totalBusy);
1188 /*------------------------------------------------------------------------
1189 * PRIVATE XDisplayVolumes
1192 * Display extended volume information.
1195 * a_servID : Pointer to the Rx call we're performing.
1196 * a_partID : Partition for which we want the extended list.
1197 * a_xInfoP : Ptr to extended volume info.
1198 * a_count : Number of volume records contained above.
1199 * a_int32 : Int32 listing generated?
1200 * a_fast : Fast listing generated?
1201 * a_quiet : Quiet listing generated?
1207 * Nothing interesting.
1211 *------------------------------------------------------------------------*/
1214 XDisplayVolumes(afs_int32 a_servID, afs_int32 a_partID, volintXInfo *a_xInfoP,
1215 afs_int32 a_count, afs_int32 a_int32, afs_int32 a_fast,
1217 { /*XDisplayVolumes */
1219 int totalOK; /*Total OK volumes */
1220 int totalNotOK; /*Total screwed volumes */
1221 int totalBusy; /*Total busy volumes */
1222 int i; /*Loop variable */
1223 afs_uint32 volid = 0; /*Current volume ID */
1226 * Initialize counters and (global!!) queues.
1235 * Display each volume in the list.
1237 for (i = 0; i < a_count; i++) {
1238 XDisplayFormat(a_xInfoP, a_servID, a_partID, &totalOK, &totalNotOK,
1239 &totalBusy, a_fast, a_int32, 0);
1244 * If any volumes were found to be busy or screwed, display them.
1247 while (busyHead.count) {
1248 qGet(&busyHead, &volid);
1249 fprintf(STDOUT, "**** Volume %lu is busy ****\n",
1250 (unsigned long)volid);
1254 while (notokHead.count) {
1255 qGet(¬okHead, &volid);
1256 fprintf(STDOUT, "**** Could not attach volume %lu ****\n",
1257 (unsigned long)volid);
1262 fprintf(STDOUT, "\n");
1265 "Total volumes: %d on-line, %d off-line, %d busyd\n\n",
1266 totalOK, totalNotOK, totalBusy);
1270 } /*XDisplayVolumes */
1271 #ifdef FULL_LISTVOL_SWITCH
1272 /*------------------------------------------------------------------------
1273 * PRIVATE XDisplayVolumes2
1276 * Display extended formated volume information.
1279 * a_servID : Pointer to the Rx call we're performing.
1280 * a_partID : Partition for which we want the extended list.
1281 * a_xInfoP : Ptr to extended volume info.
1282 * a_count : Number of volume records contained above.
1283 * a_int32 : Int32 listing generated?
1284 * a_fast : Fast listing generated?
1285 * a_quiet : Quiet listing generated?
1291 * Nothing interesting.
1295 *------------------------------------------------------------------------*/
1298 XDisplayVolumes2(afs_int32 a_servID, afs_int32 a_partID, volintXInfo *a_xInfoP,
1299 afs_int32 a_count, afs_int32 a_int32, afs_int32 a_fast,
1301 { /*XDisplayVolumes */
1303 int totalOK; /*Total OK volumes */
1304 int totalNotOK; /*Total screwed volumes */
1305 int totalBusy; /*Total busy volumes */
1306 int i; /*Loop variable */
1307 afs_uint32 volid = 0; /*Current volume ID */
1310 * Initialize counters and (global!!) queues.
1319 * Display each volume in the list.
1321 for (i = 0; i < a_count; i++) {
1322 fprintf(STDOUT, "BEGIN_OF_ENTRY\n");
1323 XDisplayFormat2(a_xInfoP, a_servID, a_partID, &totalOK, &totalNotOK,
1324 &totalBusy, a_fast, a_int32, 0);
1325 fprintf(STDOUT, "END_OF_ENTRY\n");
1330 * If any volumes were found to be busy or screwed, display them.
1333 while (busyHead.count) {
1334 qGet(&busyHead, &volid);
1335 fprintf(STDOUT, "BUSY_VOL\t%lu\n",
1336 (unsigned long)volid);
1340 while (notokHead.count) {
1341 qGet(¬okHead, &volid);
1342 fprintf(STDOUT, "COULD_NOT_ATTACH\t%lu\n",
1343 (unsigned long)volid);
1348 fprintf(STDOUT, "\n");
1351 "VOLUMES_ONLINE\t%d\nVOLUMES_OFFLINE\t%d\nVOLUMES_BUSY\t%d\n",
1352 totalOK, totalNotOK, totalBusy);
1356 } /*XDisplayVolumes2 */
1357 #endif /* FULL_LISTVOL_SWITCH */
1360 /* set <server> and <part> to the correct values depending on
1361 * <voltype> and <entry> */
1363 GetServerAndPart(struct nvldbentry *entry, int voltype, afs_int32 *server,
1364 afs_int32 *part, int *previdx)
1366 int i, istart, vtype;
1371 /* Doesn't check for non-existance of backup volume */
1372 if ((voltype == RWVOL) || (voltype == BACKVOL)) {
1374 istart = 0; /* seach the entire entry */
1377 /* Seach from beginning of entry or pick up where we left off */
1378 istart = ((*previdx < 0) ? 0 : *previdx + 1);
1381 for (i = istart; i < entry->nServers; i++) {
1382 if (entry->serverFlags[i] & vtype) {
1383 *server = entry->serverNumber[i];
1384 *part = entry->serverPartition[i];
1390 /* Didn't find any, return -1 */
1396 PostVolumeStats(struct nvldbentry *entry)
1398 SubEnumerateEntry(entry);
1399 /* Check for VLOP_ALLOPERS */
1400 if (entry->flags & VLOP_ALLOPERS)
1401 fprintf(STDOUT, " Volume is currently LOCKED \n");
1405 /*------------------------------------------------------------------------
1406 * PRIVATE XVolumeStats
1409 * Display extended volume information.
1412 * a_xInfoP : Ptr to extended volume info.
1413 * a_entryP : Ptr to the volume's VLDB entry.
1414 * a_srvID : Server ID.
1415 * a_partID : Partition ID.
1416 * a_volType : Type of volume to print.
1422 * Nothing interesting.
1426 *------------------------------------------------------------------------*/
1429 XVolumeStats(volintXInfo *a_xInfoP, struct nvldbentry *a_entryP,
1430 afs_int32 a_srvID, afs_int32 a_partID, int a_volType)
1433 int totalOK, totalNotOK, totalBusy; /*Dummies - we don't really count here */
1435 XDisplayFormat(a_xInfoP, /*Ptr to extended volume info */
1436 a_srvID, /*Server ID to print */
1437 a_partID, /*Partition ID to print */
1438 &totalOK, /*Ptr to total-OK counter */
1439 &totalNotOK, /*Ptr to total-screwed counter */
1440 &totalBusy, /*Ptr to total-busy counter */
1441 0, /*Don't do a fast listing */
1442 1, /*Do a long listing */
1443 1); /*Show volume problems */
1449 VolumeStats_int(volintInfo *pntr, struct nvldbentry *entry, afs_int32 server,
1450 afs_int32 part, int voltype)
1452 int totalOK, totalNotOK, totalBusy;
1454 DisplayFormat(pntr, server, part, &totalOK, &totalNotOK, &totalBusy, 0, 1,
1459 /* command to forcibly remove a volume */
1461 NukeVolume(register struct cmd_syndesc *as)
1463 register afs_int32 code;
1470 server = GetServer(tp = as->parms[0].items->data);
1472 fprintf(STDERR, "vos: server '%s' not found in host table\n", tp);
1476 partID = volutil_GetPartitionID(tp = as->parms[1].items->data);
1478 fprintf(STDERR, "vos: could not parse '%s' as a partition name", tp);
1482 volID = vsu_GetVolumeID(tp = as->parms[2].items->data, cstruct, &err);
1485 PrintError("", err);
1488 "vos: could not parse '%s' as a numeric volume ID", tp);
1493 "vos: forcibly removing all traces of volume %d, please wait...",
1496 code = UV_NukeVolume(server, partID, volID);
1498 fprintf(STDOUT, "done.\n");
1500 fprintf(STDOUT, "failed with code %d.\n", code);
1505 /*------------------------------------------------------------------------
1506 * PRIVATE ExamineVolume
1509 * Routine used to examine a single volume, contacting the VLDB as
1510 * well as the Volume Server.
1513 * as : Ptr to parsed command line arguments.
1516 * 0 for a successful operation,
1517 * Otherwise, one of the ubik or VolServer error values.
1520 * Nothing interesting.
1524 *------------------------------------------------------------------------
1527 ExamineVolume(register struct cmd_syndesc *as, void *arock)
1529 struct nvldbentry entry;
1530 afs_int32 vcode = 0;
1531 volintInfo *pntr = (volintInfo *) 0;
1532 volintXInfo *xInfoP = (volintXInfo *) 0;
1534 afs_int32 code, err, error = 0;
1535 int voltype, foundserv = 0, foundentry = 0;
1536 afs_int32 aserver, apart;
1538 int wantExtendedInfo; /*Do we want extended vol info? */
1540 wantExtendedInfo = (as->parms[1].items ? 1 : 0); /* -extended */
1542 volid = vsu_GetVolumeID(as->parms[0].items->data, cstruct, &err); /* -id */
1545 PrintError("", err);
1547 fprintf(STDERR, "Unknown volume ID or name '%s'\n",
1548 as->parms[0].items->data);
1553 fprintf(STDOUT, "Fetching VLDB entry for %lu .. ",
1554 (unsigned long)volid);
1557 vcode = VLDB_GetEntryByID(volid, -1, &entry);
1560 "Could not fetch the entry for volume number %lu from VLDB \n",
1561 (unsigned long)volid);
1565 fprintf(STDOUT, "done\n");
1566 MapHostToNetwork(&entry);
1568 if (entry.volumeId[RWVOL] == volid)
1570 else if (entry.volumeId[BACKVOL] == volid)
1572 else /* (entry.volumeId[ROVOL] == volid) */
1575 do { /* do {...} while (voltype == ROVOL) */
1576 /* Get the entry for the volume. If its a RW vol, get the RW entry.
1577 * It its a BK vol, get the RW entry (even if VLDB may say the BK doen't exist).
1578 * If its a RO vol, get the next RO entry.
1580 GetServerAndPart(&entry, ((voltype == ROVOL) ? ROVOL : RWVOL),
1581 &aserver, &apart, &previdx);
1582 if (previdx == -1) { /* searched all entries */
1584 fprintf(STDERR, "Volume %s does not exist in VLDB\n\n",
1585 as->parms[0].items->data);
1592 /* Get information about the volume from the server */
1594 fprintf(STDOUT, "Getting volume listing from the server %s .. ",
1595 hostutil_GetNameByINet(aserver));
1598 if (wantExtendedInfo)
1599 code = UV_XListOneVolume(aserver, apart, volid, &xInfoP);
1601 code = UV_ListOneVolume(aserver, apart, volid, &pntr);
1603 fprintf(STDOUT, "done\n");
1607 if (code == ENODEV) {
1608 if ((voltype == BACKVOL) && !(entry.flags & BACK_EXISTS)) {
1609 /* The VLDB says there is no backup volume and its not on disk */
1610 fprintf(STDERR, "Volume %s does not exist\n",
1611 as->parms[0].items->data);
1615 "Volume does not exist on server %s as indicated by the VLDB\n",
1616 hostutil_GetNameByINet(aserver));
1619 PrintDiagnostics("examine", code);
1621 fprintf(STDOUT, "\n");
1624 if (wantExtendedInfo)
1625 XVolumeStats(xInfoP, &entry, aserver, apart, voltype);
1627 #ifdef FULL_LISTVOL_SWITCH
1628 if (as->parms[2].items) {
1629 DisplayFormat2(aserver, apart, pntr);
1630 EnumerateEntry(&entry);
1632 #endif /* FULL_LISTVOL_SWITCH */
1633 VolumeStats_int(pntr, &entry, aserver, apart, voltype);
1635 if ((voltype == BACKVOL) && !(entry.flags & BACK_EXISTS)) {
1636 /* The VLDB says there is no backup volume yet we found one on disk */
1637 fprintf(STDERR, "Volume %s does not exist in VLDB\n",
1638 as->parms[0].items->data);
1647 } while (voltype == ROVOL);
1650 fprintf(STDERR, "Dump only information from VLDB\n\n");
1651 fprintf(STDOUT, "%s \n", entry.name); /* PostVolumeStats doesn't print name */
1653 PostVolumeStats(&entry);
1658 /*------------------------------------------------------------------------
1662 * Routine used to change the status of a single volume.
1665 * as : Ptr to parsed command line arguments.
1668 * 0 for a successful operation,
1669 * Otherwise, one of the ubik or VolServer error values.
1672 * Nothing interesting.
1676 *------------------------------------------------------------------------
1679 SetFields(register struct cmd_syndesc *as, void *arock)
1681 struct nvldbentry entry;
1684 afs_int32 code, err;
1685 afs_int32 aserver, apart;
1688 volid = vsu_GetVolumeID(as->parms[0].items->data, cstruct, &err); /* -id */
1691 PrintError("", err);
1693 fprintf(STDERR, "Unknown volume ID or name '%s'\n",
1694 as->parms[0].items->data);
1698 code = VLDB_GetEntryByID(volid, RWVOL, &entry);
1701 "Could not fetch the entry for volume number %lu from VLDB \n",
1702 (unsigned long)volid);
1705 MapHostToNetwork(&entry);
1707 GetServerAndPart(&entry, RWVOL, &aserver, &apart, &previdx);
1708 if (previdx == -1) {
1709 fprintf(STDERR, "Volume %s does not exist in VLDB\n\n",
1710 as->parms[0].items->data);
1714 init_volintInfo(&info);
1718 if (as->parms[1].items) {
1720 code = util_GetHumanInt32(as->parms[1].items->data, &info.maxquota);
1722 fprintf(STDERR, "invalid quota value\n");
1726 if (as->parms[2].items) {
1730 if (as->parms[3].items) {
1731 /* -clearVolUpCounter */
1734 code = UV_SetVolumeInfo(aserver, apart, volid, &info);
1737 "Could not update volume info fields for volume number %lu\n",
1738 (unsigned long)volid);
1742 /*------------------------------------------------------------------------
1746 * Brings a volume online.
1749 * as : Ptr to parsed command line arguments.
1752 * 0 for a successful operation,
1755 * Nothing interesting.
1759 *------------------------------------------------------------------------
1762 volOnline(register struct cmd_syndesc *as, void *arock)
1764 afs_int32 server, partition;
1766 afs_int32 code, err = 0;
1768 server = GetServer(as->parms[0].items->data);
1770 fprintf(STDERR, "vos: server '%s' not found in host table\n",
1771 as->parms[0].items->data);
1775 partition = volutil_GetPartitionID(as->parms[1].items->data);
1776 if (partition < 0) {
1777 fprintf(STDERR, "vos: could not interpret partition name '%s'\n",
1778 as->parms[1].items->data);
1782 volid = vsu_GetVolumeID(as->parms[2].items->data, cstruct, &err); /* -id */
1785 PrintError("", err);
1787 fprintf(STDERR, "Unknown volume ID or name '%s'\n",
1788 as->parms[0].items->data);
1792 code = UV_SetVolume(server, partition, volid, ITOffline, 0 /*online */ ,
1795 fprintf(STDERR, "Failed to set volume. Code = %d\n", code);
1802 /*------------------------------------------------------------------------
1803 * PRIVATE volOffline
1806 * Brings a volume offline.
1809 * as : Ptr to parsed command line arguments.
1812 * 0 for a successful operation,
1815 * Nothing interesting.
1819 *------------------------------------------------------------------------
1822 volOffline(register struct cmd_syndesc *as, void *arock)
1824 afs_int32 server, partition;
1826 afs_int32 code, err = 0;
1827 afs_int32 transflag, sleeptime, transdone;
1829 server = GetServer(as->parms[0].items->data);
1831 fprintf(STDERR, "vos: server '%s' not found in host table\n",
1832 as->parms[0].items->data);
1836 partition = volutil_GetPartitionID(as->parms[1].items->data);
1837 if (partition < 0) {
1838 fprintf(STDERR, "vos: could not interpret partition name '%s'\n",
1839 as->parms[1].items->data);
1843 volid = vsu_GetVolumeID(as->parms[2].items->data, cstruct, &err); /* -id */
1846 PrintError("", err);
1848 fprintf(STDERR, "Unknown volume ID or name '%s'\n",
1849 as->parms[0].items->data);
1853 transflag = (as->parms[4].items ? ITBusy : ITOffline);
1854 sleeptime = (as->parms[3].items ? atol(as->parms[3].items->data) : 0);
1855 transdone = (sleeptime ? 0 /*online */ : VTOutOfService);
1856 if (as->parms[4].items && !as->parms[3].items) {
1857 fprintf(STDERR, "-sleep option must be used with -busy flag\n");
1862 UV_SetVolume(server, partition, volid, transflag, transdone,
1865 fprintf(STDERR, "Failed to set volume. Code = %d\n", code);
1873 CreateVolume(register struct cmd_syndesc *as, void *arock)
1877 afs_uint32 volid = 0, rovolid = 0, bkvolid = 0;
1878 afs_uint32 *arovolid;
1880 struct nvldbentry entry;
1884 arovolid = &rovolid;
1887 tserver = GetServer(as->parms[0].items->data);
1889 fprintf(STDERR, "vos: host '%s' not found in host table\n",
1890 as->parms[0].items->data);
1893 pnum = volutil_GetPartitionID(as->parms[1].items->data);
1895 fprintf(STDERR, "vos: could not interpret partition name '%s'\n",
1896 as->parms[1].items->data);
1899 if (!IsPartValid(pnum, tserver, &code)) { /*check for validity of the partition */
1901 PrintError("", code);
1904 "vos : partition %s does not exist on the server\n",
1905 as->parms[1].items->data);
1908 if (!ISNAMEVALID(as->parms[2].items->data)) {
1910 "vos: the name of the root volume %s exceeds the size limit of %d\n",
1911 as->parms[2].items->data, VOLSER_OLDMAXVOLNAME - 10);
1914 if (!VolNameOK(as->parms[2].items->data)) {
1916 "Illegal volume name %s, should not end in .readonly or .backup\n",
1917 as->parms[2].items->data);
1920 if (IsNumeric(as->parms[2].items->data)) {
1921 fprintf(STDERR, "Illegal volume name %s, should not be a number\n",
1922 as->parms[2].items->data);
1925 vcode = VLDB_GetEntryByName(as->parms[2].items->data, &entry);
1927 fprintf(STDERR, "Volume %s already exists\n",
1928 as->parms[2].items->data);
1929 PrintDiagnostics("create", code);
1933 if (as->parms[3].items) {
1934 code = util_GetHumanInt32(as->parms[3].items->data, "a);
1936 fprintf(STDERR, "vos: bad integer specified for quota.\n");
1941 if (as->parms[4].items) {
1942 if (!IsNumeric(as->parms[4].items->data)) {
1943 fprintf(STDERR, "vos: Given volume ID %s should be numeric.\n",
1944 as->parms[4].items->data);
1948 code = util_GetUInt32(as->parms[4].items->data, &volid);
1950 fprintf(STDERR, "vos: bad integer specified for volume ID.\n");
1955 if (as->parms[5].items) {
1956 if (!IsNumeric(as->parms[5].items->data)) {
1957 fprintf(STDERR, "vos: Given RO volume ID %s should be numeric.\n",
1958 as->parms[5].items->data);
1962 code = util_GetUInt32(as->parms[5].items->data, &rovolid);
1964 fprintf(STDERR, "vos: bad integer specified for volume ID.\n");
1974 UV_CreateVolume3(tserver, pnum, as->parms[2].items->data, quota, 0,
1975 0, 0, 0, &volid, arovolid, &bkvolid);
1977 PrintDiagnostics("create", code);
1980 MapPartIdIntoName(pnum, part);
1981 fprintf(STDOUT, "Volume %lu created on partition %s of %s\n",
1982 (unsigned long)volid, part, as->parms[0].items->data);
1989 DeleteAll(struct nvldbentry *entry)
1992 afs_int32 error, code, curserver, curpart;
1995 MapHostToNetwork(entry);
1997 for (i = 0; i < entry->nServers; i++) {
1998 curserver = entry->serverNumber[i];
1999 curpart = entry->serverPartition[i];
2000 if (entry->serverFlags[i] & ITSROVOL) {
2001 volid = entry->volumeId[ROVOL];
2003 volid = entry->volumeId[RWVOL];
2005 code = UV_DeleteVolume(curserver, curpart, volid);
2014 DeleteVolume(struct cmd_syndesc *as, void *arock)
2016 afs_int32 err, code = 0;
2017 afs_int32 server = 0, partition = -1;
2022 if (as->parms[0].items) {
2023 server = GetServer(as->parms[0].items->data);
2025 fprintf(STDERR, "vos: server '%s' not found in host table\n",
2026 as->parms[0].items->data);
2031 if (as->parms[1].items) {
2032 partition = volutil_GetPartitionID(as->parms[1].items->data);
2033 if (partition < 0) {
2034 fprintf(STDERR, "vos: could not interpret partition name '%s'\n",
2035 as->parms[1].items->data);
2039 /* Check for validity of the partition */
2040 if (!IsPartValid(partition, server, &code)) {
2042 PrintError("", code);
2045 "vos : partition %s does not exist on the server\n",
2046 as->parms[1].items->data);
2052 volid = vsu_GetVolumeID(as->parms[2].items->data, cstruct, &err);
2054 fprintf(STDERR, "Can't find volume name '%s' in VLDB\n",
2055 as->parms[2].items->data);
2057 PrintError("", err);
2061 /* If the server or partition option are not complete, try to fill
2062 * them in from the VLDB entry.
2064 if ((partition == -1) || !server) {
2065 struct nvldbentry entry;
2067 code = VLDB_GetEntryByID(volid, -1, &entry);
2070 "Could not fetch the entry for volume %lu from VLDB\n",
2071 (unsigned long)volid);
2072 PrintError("", code);
2076 if (((volid == entry.volumeId[RWVOL]) && (entry.flags & RW_EXISTS))
2077 || ((volid == entry.volumeId[BACKVOL])
2078 && (entry.flags & BACK_EXISTS))) {
2079 idx = Lp_GetRwIndex(&entry);
2080 if ((idx == -1) || (server && (server != entry.serverNumber[idx]))
2081 || ((partition != -1)
2082 && (partition != entry.serverPartition[idx]))) {
2083 fprintf(STDERR, "VLDB: Volume '%s' no match\n",
2084 as->parms[2].items->data);
2087 } else if ((volid == entry.volumeId[ROVOL])
2088 && (entry.flags & RO_EXISTS)) {
2089 for (idx = -1, j = 0; j < entry.nServers; j++) {
2090 if (entry.serverFlags[j] != ITSROVOL)
2093 if (((server == 0) || (server == entry.serverNumber[j]))
2094 && ((partition == -1)
2095 || (partition == entry.serverPartition[j]))) {
2098 "VLDB: Volume '%s' matches more than one RO\n",
2099 as->parms[2].items->data);
2106 fprintf(STDERR, "VLDB: Volume '%s' no match\n",
2107 as->parms[2].items->data);
2111 fprintf(STDERR, "VLDB: Volume '%s' no match\n",
2112 as->parms[2].items->data);
2116 server = htonl(entry.serverNumber[idx]);
2117 partition = entry.serverPartition[idx];
2121 code = UV_DeleteVolume(server, partition, volid);
2123 PrintDiagnostics("remove", code);
2127 MapPartIdIntoName(partition, pname);
2128 fprintf(STDOUT, "Volume %lu on partition %s server %s deleted\n",
2129 (unsigned long)volid, pname, hostutil_GetNameByINet(server));
2133 #define TESTM 0 /* set for move space tests, clear for production */
2135 MoveVolume(register struct cmd_syndesc *as, void *arock)
2139 afs_int32 fromserver, toserver, frompart, topart;
2140 afs_int32 flags, code, err;
2141 char fromPartName[10], toPartName[10];
2143 struct diskPartition64 partition; /* for space check */
2146 volid = vsu_GetVolumeID(as->parms[0].items->data, cstruct, &err);
2149 PrintError("", err);
2151 fprintf(STDERR, "vos: can't find volume ID or name '%s'\n",
2152 as->parms[0].items->data);
2155 fromserver = GetServer(as->parms[1].items->data);
2156 if (fromserver == 0) {
2157 fprintf(STDERR, "vos: server '%s' not found in host table\n",
2158 as->parms[1].items->data);
2161 toserver = GetServer(as->parms[3].items->data);
2162 if (toserver == 0) {
2163 fprintf(STDERR, "vos: server '%s' not found in host table\n",
2164 as->parms[3].items->data);
2167 frompart = volutil_GetPartitionID(as->parms[2].items->data);
2169 fprintf(STDERR, "vos: could not interpret partition name '%s'\n",
2170 as->parms[2].items->data);
2173 if (!IsPartValid(frompart, fromserver, &code)) { /*check for validity of the partition */
2175 PrintError("", code);
2178 "vos : partition %s does not exist on the server\n",
2179 as->parms[2].items->data);
2182 topart = volutil_GetPartitionID(as->parms[4].items->data);
2184 fprintf(STDERR, "vos: could not interpret partition name '%s'\n",
2185 as->parms[4].items->data);
2188 if (!IsPartValid(topart, toserver, &code)) { /*check for validity of the partition */
2190 PrintError("", code);
2193 "vos : partition %s does not exist on the server\n",
2194 as->parms[4].items->data);
2199 if (as->parms[5].items) flags |= RV_NOCLONE;
2202 * check source partition for space to clone volume
2205 MapPartIdIntoName(topart, toPartName);
2206 MapPartIdIntoName(frompart, fromPartName);
2209 * check target partition for space to move volume
2212 code = UV_PartitionInfo64(toserver, toPartName, &partition);
2214 fprintf(STDERR, "vos: cannot access partition %s\n", toPartName);
2218 fprintf(STDOUT, "target partition %s free space %" AFS_INT64_FMT "\n", toPartName,
2221 p = (volintInfo *) 0;
2222 code = UV_ListOneVolume(fromserver, frompart, volid, &p);
2224 fprintf(STDERR, "vos:cannot access volume %lu\n",
2225 (unsigned long)volid);
2229 fprintf(STDOUT, "volume %lu size %d\n", (unsigned long)volid,
2231 if (partition.free <= p->size) {
2233 "vos: no space on target partition %s to move volume %lu\n",
2234 toPartName, (unsigned long)volid);
2241 fprintf(STDOUT, "size test - don't do move\n");
2245 /* successful move still not guaranteed but shoot for it */
2248 UV_MoveVolume2(volid, fromserver, frompart, toserver, topart, flags);
2250 PrintDiagnostics("move", code);
2253 MapPartIdIntoName(topart, toPartName);
2254 MapPartIdIntoName(frompart, fromPartName);
2255 fprintf(STDOUT, "Volume %lu moved from %s %s to %s %s \n",
2256 (unsigned long)volid, as->parms[1].items->data, fromPartName,
2257 as->parms[3].items->data, toPartName);
2263 CopyVolume(register struct cmd_syndesc *as, void *arock)
2266 afs_int32 fromserver, toserver, frompart, topart, code, err, flags;
2267 char fromPartName[10], toPartName[10], *tovolume;
2268 struct nvldbentry entry;
2269 struct diskPartition64 partition; /* for space check */
2272 volid = vsu_GetVolumeID(as->parms[0].items->data, cstruct, &err);
2275 PrintError("", err);
2277 fprintf(STDERR, "vos: can't find volume ID or name '%s'\n",
2278 as->parms[0].items->data);
2281 fromserver = GetServer(as->parms[1].items->data);
2282 if (fromserver == 0) {
2283 fprintf(STDERR, "vos: server '%s' not found in host table\n",
2284 as->parms[1].items->data);
2288 toserver = GetServer(as->parms[4].items->data);
2289 if (toserver == 0) {
2290 fprintf(STDERR, "vos: server '%s' not found in host table\n",
2291 as->parms[4].items->data);
2295 tovolume = as->parms[3].items->data;
2296 if (!ISNAMEVALID(tovolume)) {
2298 "vos: the name of the root volume %s exceeds the size limit of %d\n",
2299 tovolume, VOLSER_OLDMAXVOLNAME - 10);
2302 if (!VolNameOK(tovolume)) {
2304 "Illegal volume name %s, should not end in .readonly or .backup\n",
2308 if (IsNumeric(tovolume)) {
2309 fprintf(STDERR, "Illegal volume name %s, should not be a number\n",
2313 code = VLDB_GetEntryByName(tovolume, &entry);
2315 fprintf(STDERR, "Volume %s already exists\n", tovolume);
2316 PrintDiagnostics("copy", code);
2320 frompart = volutil_GetPartitionID(as->parms[2].items->data);
2322 fprintf(STDERR, "vos: could not interpret partition name '%s'\n",
2323 as->parms[2].items->data);
2326 if (!IsPartValid(frompart, fromserver, &code)) { /*check for validity of the partition */
2328 PrintError("", code);
2331 "vos : partition %s does not exist on the server\n",
2332 as->parms[2].items->data);
2336 topart = volutil_GetPartitionID(as->parms[5].items->data);
2338 fprintf(STDERR, "vos: could not interpret partition name '%s'\n",
2339 as->parms[5].items->data);
2342 if (!IsPartValid(topart, toserver, &code)) { /*check for validity of the partition */
2344 PrintError("", code);
2347 "vos : partition %s does not exist on the server\n",
2348 as->parms[5].items->data);
2353 if (as->parms[6].items) flags |= RV_OFFLINE;
2354 if (as->parms[7].items) flags |= RV_RDONLY;
2355 if (as->parms[8].items) flags |= RV_NOCLONE;
2357 MapPartIdIntoName(topart, toPartName);
2358 MapPartIdIntoName(frompart, fromPartName);
2361 * check target partition for space to move volume
2364 code = UV_PartitionInfo64(toserver, toPartName, &partition);
2366 fprintf(STDERR, "vos: cannot access partition %s\n", toPartName);
2370 fprintf(STDOUT, "target partition %s free space %" AFS_INT64_FMT "\n", toPartName,
2373 p = (volintInfo *) 0;
2374 code = UV_ListOneVolume(fromserver, frompart, volid, &p);
2376 fprintf(STDERR, "vos:cannot access volume %lu\n",
2377 (unsigned long)volid);
2381 if (partition.free <= p->size) {
2383 "vos: no space on target partition %s to copy volume %lu\n",
2384 toPartName, (unsigned long)volid);
2390 /* successful copy still not guaranteed but shoot for it */
2393 UV_CopyVolume2(volid, fromserver, frompart, tovolume, toserver,
2396 PrintDiagnostics("copy", code);
2399 MapPartIdIntoName(topart, toPartName);
2400 MapPartIdIntoName(frompart, fromPartName);
2401 fprintf(STDOUT, "Volume %lu copied from %s %s to %s on %s %s \n",
2402 (unsigned long)volid, as->parms[1].items->data, fromPartName,
2403 tovolume, as->parms[4].items->data, toPartName);
2410 ShadowVolume(register struct cmd_syndesc *as, void *arock)
2412 afs_uint32 volid, tovolid;
2413 afs_int32 fromserver, toserver, frompart, topart;
2414 afs_int32 code, err, flags;
2415 char fromPartName[10], toPartName[10], toVolName[32], *tovolume;
2416 struct diskPartition64 partition; /* for space check */
2419 p = (volintInfo *) 0;
2420 q = (volintInfo *) 0;
2422 volid = vsu_GetVolumeID(as->parms[0].items->data, cstruct, &err);
2425 PrintError("", err);
2427 fprintf(STDERR, "vos: can't find volume ID or name '%s'\n",
2428 as->parms[0].items->data);
2431 fromserver = GetServer(as->parms[1].items->data);
2432 if (fromserver == 0) {
2433 fprintf(STDERR, "vos: server '%s' not found in host table\n",
2434 as->parms[1].items->data);
2438 toserver = GetServer(as->parms[3].items->data);
2439 if (toserver == 0) {
2440 fprintf(STDERR, "vos: server '%s' not found in host table\n",
2441 as->parms[3].items->data);
2445 frompart = volutil_GetPartitionID(as->parms[2].items->data);
2447 fprintf(STDERR, "vos: could not interpret partition name '%s'\n",
2448 as->parms[2].items->data);
2451 if (!IsPartValid(frompart, fromserver, &code)) { /*check for validity of the partition */
2453 PrintError("", code);
2456 "vos : partition %s does not exist on the server\n",
2457 as->parms[2].items->data);
2461 topart = volutil_GetPartitionID(as->parms[4].items->data);
2463 fprintf(STDERR, "vos: could not interpret partition name '%s'\n",
2464 as->parms[4].items->data);
2467 if (!IsPartValid(topart, toserver, &code)) { /*check for validity of the partition */
2469 PrintError("", code);
2472 "vos : partition %s does not exist on the server\n",
2473 as->parms[4].items->data);
2477 if (as->parms[5].items) {
2478 tovolume = as->parms[5].items->data;
2479 if (!ISNAMEVALID(tovolume)) {
2481 "vos: the name of the root volume %s exceeds the size limit of %d\n",
2482 tovolume, VOLSER_OLDMAXVOLNAME - 10);
2485 if (!VolNameOK(tovolume)) {
2487 "Illegal volume name %s, should not end in .readonly or .backup\n",
2491 if (IsNumeric(tovolume)) {
2493 "Illegal volume name %s, should not be a number\n",
2498 /* use actual name of source volume */
2499 code = UV_ListOneVolume(fromserver, frompart, volid, &p);
2501 fprintf(STDERR, "vos:cannot access volume %lu\n",
2502 (unsigned long)volid);
2505 strcpy(toVolName, p->name);
2506 tovolume = toVolName;
2507 /* save p for size checks later */
2510 if (as->parms[6].items) {
2511 tovolid = vsu_GetVolumeID(as->parms[6].items->data, cstruct, &err);
2514 PrintError("", err);
2516 fprintf(STDERR, "vos: can't find volume ID or name '%s'\n",
2517 as->parms[6].items->data);
2523 tovolid = vsu_GetVolumeID(tovolume, cstruct, &err);
2526 PrintError("", err);
2528 fprintf(STDERR, "vos: can't find volume ID or name '%s'\n",
2537 if (as->parms[7].items) flags |= RV_OFFLINE;
2538 if (as->parms[8].items) flags |= RV_RDONLY;
2539 if (as->parms[9].items) flags |= RV_NOCLONE;
2540 if (as->parms[10].items) flags |= RV_CPINCR;
2542 MapPartIdIntoName(topart, toPartName);
2543 MapPartIdIntoName(frompart, fromPartName);
2546 * check target partition for space to move volume
2549 code = UV_PartitionInfo64(toserver, toPartName, &partition);
2551 fprintf(STDERR, "vos: cannot access partition %s\n", toPartName);
2555 fprintf(STDOUT, "target partition %s free space %" AFS_INT64_FMT "\n", toPartName,
2558 /* Don't do this again if we did it above */
2560 code = UV_ListOneVolume(fromserver, frompart, volid, &p);
2562 fprintf(STDERR, "vos:cannot access volume %lu\n",
2563 (unsigned long)volid);
2568 /* OK if this fails */
2569 code = UV_ListOneVolume(toserver, topart, tovolid, &q);
2571 /* Treat existing volume size as "free" */
2573 p->size = (q->size < p->size) ? p->size - q->size : 0;
2575 if (partition.free <= p->size) {
2577 "vos: no space on target partition %s to copy volume %lu\n",
2578 toPartName, (unsigned long)volid);
2586 /* successful copy still not guaranteed but shoot for it */
2589 UV_CopyVolume2(volid, fromserver, frompart, tovolume, toserver,
2590 topart, tovolid, flags);
2592 PrintDiagnostics("shadow", code);
2595 MapPartIdIntoName(topart, toPartName);
2596 MapPartIdIntoName(frompart, fromPartName);
2597 fprintf(STDOUT, "Volume %lu shadowed from %s %s to %s %s \n",
2598 (unsigned long)volid, as->parms[1].items->data, fromPartName,
2599 as->parms[3].items->data, toPartName);
2606 CloneVolume(register struct cmd_syndesc *as, void *arock)
2608 afs_uint32 volid, cloneid;
2609 afs_int32 server, part, voltype;
2610 char partName[10], *volname;
2611 afs_int32 code, err, flags;
2612 struct nvldbentry entry;
2614 volid = vsu_GetVolumeID(as->parms[0].items->data, cstruct, &err);
2617 PrintError("", err);
2619 fprintf(STDERR, "vos: can't find volume ID or name '%s'\n",
2620 as->parms[0].items->data);
2624 if (as->parms[1].items || as->parms[2].items) {
2625 if (!as->parms[1].items || !as->parms[2].items) {
2627 "Must specify both -server and -partition options\n");
2630 server = GetServer(as->parms[1].items->data);
2632 fprintf(STDERR, "vos: server '%s' not found in host table\n",
2633 as->parms[1].items->data);
2636 part = volutil_GetPartitionID(as->parms[2].items->data);
2638 fprintf(STDERR, "vos: could not interpret partition name '%s'\n",
2639 as->parms[2].items->data);
2642 if (!IsPartValid(part, server, &code)) { /*check for validity of the partition */
2644 PrintError("", code);
2647 "vos : partition %s does not exist on the server\n",
2648 as->parms[2].items->data);
2652 code = GetVolumeInfo(volid, &server, &part, &voltype, &entry);
2658 if (as->parms[3].items) {
2659 volname = as->parms[3].items->data;
2660 if (strlen(volname) > VOLSER_OLDMAXVOLNAME - 1) {
2662 "vos: the name of the root volume %s exceeds the size limit of %d\n",
2663 volname, VOLSER_OLDMAXVOLNAME - 1);
2668 * In order that you be able to make clones of RO or BK, this
2669 * check must be omitted.
2671 if (!VolNameOK(volname)) {
2673 "Illegal volume name %s, should not end in .readonly or .backup\n",
2678 if (IsNumeric(volname)) {
2680 "Illegal volume name %s, should not be a number\n",
2687 if (as->parms[4].items) {
2688 cloneid = vsu_GetVolumeID(as->parms[4].items->data, cstruct, &err);
2691 PrintError("", err);
2693 fprintf(STDERR, "vos: can't find volume ID or name '%s'\n",
2694 as->parms[4].items->data);
2700 if (as->parms[5].items) flags |= RV_OFFLINE;
2701 if (as->parms[6].items) flags |= RV_RDONLY;
2705 UV_CloneVolume(server, part, volid, cloneid, volname, flags);
2708 PrintDiagnostics("clone", code);
2711 MapPartIdIntoName(part, partName);
2712 fprintf(STDOUT, "Created clone for volume %s\n",
2713 as->parms[0].items->data);
2720 BackupVolume(register struct cmd_syndesc *as, void *arock)
2723 afs_int32 aserver, apart, vtype, code, err;
2724 struct nvldbentry entry;
2727 afs_int32 buserver, bupart, butype;
2728 struct nvldbentry buentry;
2730 avolid = vsu_GetVolumeID(as->parms[0].items->data, cstruct, &err);
2733 PrintError("", err);
2735 fprintf(STDERR, "vos: can't find volume ID or name '%s'\n",
2736 as->parms[0].items->data);
2739 code = GetVolumeInfo(avolid, &aserver, &apart, &vtype, &entry);
2743 /* verify this is a readwrite volume */
2745 if (vtype != RWVOL) {
2746 fprintf(STDERR, "%s not RW volume\n", as->parms[0].items->data);
2750 /* is there a backup volume already? */
2752 if (entry.flags & BACK_EXISTS) {
2753 /* yep, where is it? */
2755 buvolid = entry.volumeId[BACKVOL];
2756 code = GetVolumeInfo(buvolid, &buserver, &bupart, &butype, &buentry);
2761 code = VLDB_IsSameAddrs(buserver, aserver, &err);
2764 "Failed to get info about server's %d address(es) from vlserver; aborting call!\n",
2770 "FATAL ERROR: backup volume %lu exists on server %lu\n",
2771 (unsigned long)buvolid, (unsigned long)buserver);
2776 /* nope, carry on */
2778 code = UV_BackupVolume(aserver, apart, avolid);
2781 PrintDiagnostics("backup", code);
2784 fprintf(STDOUT, "Created backup volume for %s \n",
2785 as->parms[0].items->data);
2790 ReleaseVolume(register struct cmd_syndesc *as, void *arock)
2793 struct nvldbentry entry;
2795 afs_int32 aserver, apart, vtype, code, err;
2798 if (as->parms[1].items)
2800 avolid = vsu_GetVolumeID(as->parms[0].items->data, cstruct, &err);
2803 PrintError("", err);
2805 fprintf(STDERR, "vos: can't find volume '%s'\n",
2806 as->parms[0].items->data);
2809 code = GetVolumeInfo(avolid, &aserver, &apart, &vtype, &entry);
2813 if (vtype != RWVOL) {
2814 fprintf(STDERR, "%s not a RW volume\n", as->parms[0].items->data);
2818 if (!ISNAMEVALID(entry.name)) {
2820 "Volume name %s is too long, rename before releasing\n",
2825 code = UV_ReleaseVolume(avolid, aserver, apart, force);
2827 PrintDiagnostics("release", code);
2830 fprintf(STDOUT, "Released volume %s successfully\n",
2831 as->parms[0].items->data);
2836 DumpVolumeCmd(register struct cmd_syndesc *as, void *arock)
2839 afs_int32 aserver, apart, voltype, fromdate = 0, code, err, i, flags;
2840 char filename[MAXPATHLEN];
2841 struct nvldbentry entry;
2843 rx_SetRxDeadTime(60 * 10);
2844 for (i = 0; i < MAXSERVERS; i++) {
2845 struct rx_connection *rxConn = ubik_GetRPCConn(cstruct, i);
2848 rx_SetConnDeadTime(rxConn, rx_connDeadTime);
2849 if (rxConn->service)
2850 rxConn->service->connDeadTime = rx_connDeadTime;
2853 avolid = vsu_GetVolumeID(as->parms[0].items->data, cstruct, &err);
2856 PrintError("", err);
2858 fprintf(STDERR, "vos: can't find volume '%s'\n",
2859 as->parms[0].items->data);
2863 if (as->parms[3].items || as->parms[4].items) {
2864 if (!as->parms[3].items || !as->parms[4].items) {
2866 "Must specify both -server and -partition options\n");
2869 aserver = GetServer(as->parms[3].items->data);
2871 fprintf(STDERR, "Invalid server name\n");
2874 apart = volutil_GetPartitionID(as->parms[4].items->data);
2876 fprintf(STDERR, "Invalid partition name\n");
2880 code = GetVolumeInfo(avolid, &aserver, &apart, &voltype, &entry);
2885 if (as->parms[1].items && strcmp(as->parms[1].items->data, "0")) {
2886 code = ktime_DateToInt32(as->parms[1].items->data, &fromdate);
2888 fprintf(STDERR, "vos: failed to parse date '%s' (error=%d))\n",
2889 as->parms[1].items->data, code);
2893 if (as->parms[2].items) {
2894 strcpy(filename, as->parms[2].items->data);
2896 strcpy(filename, "");
2899 flags = as->parms[6].items ? VOLDUMPV2_OMITDIRS : 0;
2901 if (as->parms[5].items) {
2903 UV_DumpClonedVolume(avolid, aserver, apart, fromdate,
2904 DumpFunction, filename, flags);
2907 UV_DumpVolume(avolid, aserver, apart, fromdate, DumpFunction,
2910 if ((code == RXGEN_OPCODE) && (as->parms[6].items)) {
2911 flags &= ~VOLDUMPV2_OMITDIRS;
2915 PrintDiagnostics("dump", code);
2918 if (strcmp(filename, ""))
2919 fprintf(STDERR, "Dumped volume %s in file %s\n",
2920 as->parms[0].items->data, filename);
2922 fprintf(STDERR, "Dumped volume %s in stdout \n",
2923 as->parms[0].items->data);
2937 RestoreVolumeCmd(register struct cmd_syndesc *as, void *arock)
2939 afs_uint32 avolid, aparentid;
2940 afs_int32 aserver, apart, code, vcode, err;
2941 afs_int32 aoverwrite = ASK;
2942 afs_int32 acreation = 0, alastupdate = 0;
2943 int restoreflags = 0;
2944 int readonly = 0, offline = 0, voltype = RWVOL;
2946 char afilename[MAXPATHLEN], avolname[VOLSER_MAXVOLNAME + 1], apartName[10];
2947 char volname[VOLSER_MAXVOLNAME + 1];
2948 struct nvldbentry entry;
2953 if (as->parms[4].items) {
2954 avolid = vsu_GetVolumeID(as->parms[4].items->data, cstruct, &err);
2957 PrintError("", err);
2959 fprintf(STDERR, "vos: can't find volume '%s'\n",
2960 as->parms[4].items->data);
2966 if (as->parms[5].items) {
2967 if ((strcmp(as->parms[5].items->data, "a") == 0)
2968 || (strcmp(as->parms[5].items->data, "abort") == 0)) {
2970 } else if ((strcmp(as->parms[5].items->data, "f") == 0)
2971 || (strcmp(as->parms[5].items->data, "full") == 0)) {
2973 } else if ((strcmp(as->parms[5].items->data, "i") == 0)
2974 || (strcmp(as->parms[5].items->data, "inc") == 0)
2975 || (strcmp(as->parms[5].items->data, "increment") == 0)
2976 || (strcmp(as->parms[5].items->data, "incremental") == 0)) {
2979 fprintf(STDERR, "vos: %s is not a valid argument to -overwrite\n",
2980 as->parms[5].items->data);
2984 if (as->parms[6].items)
2986 if (as->parms[7].items) {
2991 if (as->parms[8].items) {
2992 if ((strcmp(as->parms[8].items->data, "d") == 0)
2993 || (strcmp(as->parms[8].items->data, "dump") == 0)) {
2994 acreation = TS_DUMP;
2995 } else if ((strcmp(as->parms[8].items->data, "k") == 0)
2996 || (strcmp(as->parms[8].items->data, "keep") == 0)) {
2997 acreation = TS_KEEP;
2998 } else if ((strcmp(as->parms[8].items->data, "n") == 0)
2999 || (strcmp(as->parms[8].items->data, "new") == 0)) {
3002 fprintf(STDERR, "vos: %s is not a valid argument to -creation\n",
3003 as->parms[8].items->data);
3008 if (as->parms[9].items) {
3009 if ((strcmp(as->parms[9].items->data, "d") == 0)
3010 || (strcmp(as->parms[9].items->data, "dump") == 0)) {
3011 alastupdate = TS_DUMP;
3012 } else if ((strcmp(as->parms[9].items->data, "k") == 0)
3013 || (strcmp(as->parms[9].items->data, "keep") == 0)) {
3014 alastupdate = TS_KEEP;
3015 } else if ((strcmp(as->parms[9].items->data, "n") == 0)
3016 || (strcmp(as->parms[9].items->data, "new") == 0)) {
3017 alastupdate = TS_NEW;
3019 fprintf(STDERR, "vos: %s is not a valid argument to -lastupdate\n",
3020 as->parms[9].items->data);
3025 aserver = GetServer(as->parms[0].items->data);
3027 fprintf(STDERR, "vos: server '%s' not found in host table\n",
3028 as->parms[0].items->data);
3031 apart = volutil_GetPartitionID(as->parms[1].items->data);
3033 fprintf(STDERR, "vos: could not interpret partition name '%s'\n",
3034 as->parms[1].items->data);
3037 if (!IsPartValid(apart, aserver, &code)) { /*check for validity of the partition */
3039 PrintError("", code);
3042 "vos : partition %s does not exist on the server\n",
3043 as->parms[1].items->data);
3046 strcpy(avolname, as->parms[2].items->data);
3047 if (!ISNAMEVALID(avolname)) {
3049 "vos: the name of the volume %s exceeds the size limit\n",
3053 if (!VolNameOK(avolname)) {
3055 "Illegal volume name %s, should not end in .readonly or .backup\n",
3059 if (as->parms[3].items) {
3060 strcpy(afilename, as->parms[3].items->data);
3061 if (!FileExists(afilename)) {
3062 fprintf(STDERR, "Can't access file %s\n", afilename);
3066 strcpy(afilename, "");
3069 /* Check if volume exists or not */
3071 vsu_ExtractName(volname, avolname);
3072 vcode = VLDB_GetEntryByName(volname, &entry);
3073 if (vcode) { /* no volume - do a full restore */
3074 restoreflags = RV_FULLRST;
3075 if ((aoverwrite == INC) || (aoverwrite == ABORT))
3077 "Volume does not exist; Will perform a full restore\n");
3080 else if ((!readonly && Lp_GetRwIndex(&entry) == -1) /* RW volume does not exist - do a full */
3081 ||(readonly && !Lp_ROMatch(0, 0, &entry))) { /* RO volume does not exist - do a full */
3082 restoreflags = RV_FULLRST;
3083 if ((aoverwrite == INC) || (aoverwrite == ABORT))
3085 "%s Volume does not exist; Will perform a full restore\n",
3086 readonly ? "RO" : "RW");
3089 avolid = entry.volumeId[voltype];
3090 } else if (entry.volumeId[voltype] != 0
3091 && entry.volumeId[voltype] != avolid) {
3092 avolid = entry.volumeId[voltype];
3094 aparentid = entry.volumeId[RWVOL];
3097 else { /* volume exists - do we do a full incremental or abort */
3098 int Oserver, Opart, Otype, vol_elsewhere = 0;
3099 struct nvldbentry Oentry;
3103 avolid = entry.volumeId[voltype];
3104 } else if (entry.volumeId[voltype] != 0
3105 && entry.volumeId[voltype] != avolid) {
3106 avolid = entry.volumeId[voltype];
3108 aparentid = entry.volumeId[RWVOL];
3110 /* A file name was specified - check if volume is on another partition */
3111 vcode = GetVolumeInfo(avolid, &Oserver, &Opart, &Otype, &Oentry);
3115 vcode = VLDB_IsSameAddrs(Oserver, aserver, &err);
3118 "Failed to get info about server's %d address(es) from vlserver (err=%d); aborting call!\n",
3122 if (!vcode || (Opart != apart))
3125 if (aoverwrite == ASK) {
3126 if (strcmp(afilename, "") == 0) { /* The file is from standard in */
3128 "Volume exists and no -overwrite option specified; Aborting restore command\n");
3132 /* Ask what to do */
3133 if (vol_elsewhere) {
3135 "The volume %s %u already exists on a different server/part\n",
3136 volname, entry.volumeId[voltype]);
3138 "Do you want to do a full restore or abort? [fa](a): ");
3141 "The volume %s %u already exists in the VLDB\n",
3142 volname, entry.volumeId[voltype]);
3144 "Do you want to do a full/incremental restore or abort? [fia](a): ");
3147 while (!(dc == EOF || dc == '\n'))
3148 dc = getchar(); /* goto end of line */
3149 if ((c == 'f') || (c == 'F'))
3151 else if ((c == 'i') || (c == 'I'))
3157 if (aoverwrite == ABORT) {
3158 fprintf(STDERR, "Volume exists; Aborting restore command\n");
3160 } else if (aoverwrite == FULL) {
3161 restoreflags = RV_FULLRST;
3163 "Volume exists; Will delete and perform full restore\n");
3164 } else if (aoverwrite == INC) {
3166 if (vol_elsewhere) {
3168 "%s volume %lu already exists on a different server/part; not allowed\n",
3169 readonly ? "RO" : "RW", (unsigned long)avolid);
3175 restoreflags |= RV_OFFLINE;
3177 restoreflags |= RV_RDONLY;
3179 switch (acreation) {
3181 restoreflags |= RV_CRDUMP;
3184 restoreflags |= RV_CRKEEP;
3187 restoreflags |= RV_CRNEW;
3190 if (aoverwrite == FULL)
3191 restoreflags |= RV_CRNEW;
3193 restoreflags |= RV_CRKEEP;
3196 switch (alastupdate) {
3198 restoreflags |= RV_LUDUMP;
3201 restoreflags |= RV_LUKEEP;
3204 restoreflags |= RV_LUNEW;
3207 restoreflags |= RV_LUDUMP;
3209 if (as->parms[10].items) {
3210 restoreflags |= RV_NODEL;
3215 UV_RestoreVolume2(aserver, apart, avolid, aparentid,
3216 avolname, restoreflags, WriteData, afilename);
3218 PrintDiagnostics("restore", code);
3221 MapPartIdIntoName(apart, apartName);
3224 * patch typo here - originally "parms[1]", should be "parms[0]"
3227 fprintf(STDOUT, "Restored volume %s on %s %s\n", avolname,
3228 as->parms[0].items->data, apartName);
3233 LockReleaseCmd(register struct cmd_syndesc *as, void *arock)
3236 afs_int32 code, err;
3238 avolid = vsu_GetVolumeID(as->parms[0].items->data, cstruct, &err);
3241 PrintError("", err);
3243 fprintf(STDERR, "vos: can't find volume '%s'\n",
3244 as->parms[0].items->data);
3248 code = UV_LockRelease(avolid);
3250 PrintDiagnostics("unlock", code);
3253 fprintf(STDOUT, "Released lock on vldb entry for volume %s\n",
3254 as->parms[0].items->data);
3259 AddSite(register struct cmd_syndesc *as, void *arock)
3262 afs_int32 aserver, apart, code, err, arovolid, valid = 0;
3263 char apartName[10], avolname[VOLSER_MAXVOLNAME + 1];
3265 vsu_ExtractName(avolname, as->parms[2].items->data);;
3266 avolid = vsu_GetVolumeID(avolname, cstruct, &err);
3269 PrintError("", err);
3271 fprintf(STDERR, "vos: can't find volume '%s'\n",
3272 as->parms[2].items->data);
3276 if (as->parms[3].items) {
3277 vsu_ExtractName(avolname, as->parms[3].items->data);
3278 arovolid = vsu_GetVolumeID(avolname, cstruct, &err);
3280 fprintf(STDERR, "vos: invalid ro volume id '%s'\n",
3281 as->parms[3].items->data);
3285 aserver = GetServer(as->parms[0].items->data);
3287 fprintf(STDERR, "vos: server '%s' not found in host table\n",
3288 as->parms[0].items->data);
3291 apart = volutil_GetPartitionID(as->parms[1].items->data);
3293 fprintf(STDERR, "vos: could not interpret partition name '%s'\n",
3294 as->parms[1].items->data);
3297 if (!IsPartValid(apart, aserver, &code)) { /*check for validity of the partition */
3299 PrintError("", code);
3302 "vos : partition %s does not exist on the server\n",
3303 as->parms[1].items->data);
3306 if (as->parms[4].items) {
3309 code = UV_AddSite2(aserver, apart, avolid, arovolid, valid);
3311 PrintDiagnostics("addsite", code);
3314 MapPartIdIntoName(apart, apartName);
3315 fprintf(STDOUT, "Added replication site %s %s for volume %s\n",
3316 as->parms[0].items->data, apartName, as->parms[2].items->data);
3321 RemoveSite(register struct cmd_syndesc *as, void *arock)
3325 afs_int32 aserver, apart, code, err;
3326 char apartName[10], avolname[VOLSER_MAXVOLNAME + 1];
3328 vsu_ExtractName(avolname, as->parms[2].items->data);
3329 avolid = vsu_GetVolumeID(avolname, cstruct, &err);
3332 PrintError("", err);
3334 fprintf(STDERR, "vos: can't find volume '%s'\n",
3335 as->parms[2].items->data);
3338 aserver = GetServer(as->parms[0].items->data);
3340 fprintf(STDERR, "vos: server '%s' not found in host table\n",
3341 as->parms[0].items->data);
3344 apart = volutil_GetPartitionID(as->parms[1].items->data);
3346 fprintf(STDERR, "vos: could not interpret partition name '%s'\n",
3347 as->parms[1].items->data);
3351 *skip the partition validity check, since it is possible that the partition
3352 *has since been decomissioned.
3355 if (!IsPartValid(apart,aserver,&code)){
3356 if(code) PrintError("",code);
3357 else fprintf(STDERR,"vos : partition %s does not exist on the server\n",as->parms[1].items->data);
3361 code = UV_RemoveSite(aserver, apart, avolid);
3363 PrintDiagnostics("remsite", code);
3366 MapPartIdIntoName(apart, apartName);
3367 fprintf(STDOUT, "Removed replication site %s %s for volume %s\n",
3368 as->parms[0].items->data, apartName, as->parms[2].items->data);
3373 ChangeLocation(register struct cmd_syndesc *as, void *arock)
3376 afs_int32 aserver, apart, code, err;
3379 avolid = vsu_GetVolumeID(as->parms[2].items->data, cstruct, &err);
3382 PrintError("", err);
3384 fprintf(STDERR, "vos: can't find volume '%s'\n",
3385 as->parms[2].items->data);
3388 aserver = GetServer(as->parms[0].items->data);
3390 fprintf(STDERR, "vos: server '%s' not found in host table\n",
3391 as->parms[0].items->data);
3394 apart = volutil_GetPartitionID(as->parms[1].items->data);
3396 fprintf(STDERR, "vos: could not interpret partition name '%s'\n",
3397 as->parms[1].items->data);
3400 if (!IsPartValid(apart, aserver, &code)) { /*check for validity of the partition */
3402 PrintError("", code);
3405 "vos : partition %s does not exist on the server\n",
3406 as->parms[1].items->data);
3409 code = UV_ChangeLocation(aserver, apart, avolid);
3411 PrintDiagnostics("addsite", code);
3414 MapPartIdIntoName(apart, apartName);
3415 fprintf(STDOUT, "Changed location to %s %s for volume %s\n",
3416 as->parms[0].items->data, apartName, as->parms[2].items->data);
3421 ListPartitions(register struct cmd_syndesc *as, void *arock)
3423 afs_int32 aserver, code;
3424 struct partList dummyPartList;
3429 aserver = GetServer(as->parms[0].items->data);
3431 fprintf(STDERR, "vos: server '%s' not found in host table\n",
3432 as->parms[0].items->data);
3437 code = UV_ListPartitions(aserver, &dummyPartList, &cnt);
3439 PrintDiagnostics("listpart", code);
3443 fprintf(STDOUT, "The partitions on the server are:\n");
3444 for (i = 0; i < cnt; i++) {
3445 if (dummyPartList.partFlags[i] & PARTVALID) {
3446 memset(pname, 0, sizeof(pname));
3447 MapPartIdIntoName(dummyPartList.partId[i], pname);
3448 fprintf(STDOUT, " %10s ", pname);
3450 if ((i % 5) == 0 && (i != 0))
3451 fprintf(STDOUT, "\n");
3454 fprintf(STDOUT, "\n");
3455 fprintf(STDOUT, "Total: %d\n", total);
3461 CompareVolName(const void *p1, const void *p2)
3463 volintInfo *arg1, *arg2;
3465 arg1 = (volintInfo *) p1;
3466 arg2 = (volintInfo *) p2;
3467 return (strcmp(arg1->name, arg2->name));
3471 /*------------------------------------------------------------------------
3472 * PRIVATE XCompareVolName
3475 * Comparison routine for volume names coming from an extended
3479 * a_obj1P : Char ptr to first extended vol info object
3480 * a_obj1P : Char ptr to second extended vol info object
3483 * The value of strcmp() on the volume names within the passed
3484 * objects (i,e., -1, 0, or 1).
3487 * Passed to qsort() as the designated comparison routine.
3491 *------------------------------------------------------------------------*/
3494 XCompareVolName(const void *a_obj1P, const void *a_obj2P)
3495 { /*XCompareVolName */
3498 (((struct volintXInfo *)(a_obj1P))->name,
3499 ((struct volintXInfo *)(a_obj2P))->name));
3501 } /*XCompareVolName */
3504 CompareVolID(const void *p1, const void *p2)
3506 volintInfo *arg1, *arg2;
3508 arg1 = (volintInfo *) p1;
3509 arg2 = (volintInfo *) p2;
3510 if (arg1->volid == arg2->volid)
3512 if (arg1->volid > arg2->volid)
3519 /*------------------------------------------------------------------------
3520 * PRIVATE XCompareVolID
3523 * Comparison routine for volume IDs coming from an extended
3527 * a_obj1P : Char ptr to first extended vol info object
3528 * a_obj1P : Char ptr to second extended vol info object
3531 * The value of strcmp() on the volume names within the passed
3532 * objects (i,e., -1, 0, or 1).
3535 * Passed to qsort() as the designated comparison routine.
3539 *------------------------------------------------------------------------*/
3542 XCompareVolID(const void *a_obj1P, const void *a_obj2P)
3543 { /*XCompareVolID */
3545 afs_int32 id1, id2; /*Volume IDs we're comparing */
3547 id1 = ((struct volintXInfo *)(a_obj1P))->volid;
3548 id2 = ((struct volintXInfo *)(a_obj2P))->volid;
3556 } /*XCompareVolID */
3558 /*------------------------------------------------------------------------
3559 * PRIVATE ListVolumes
3562 * Routine used to list volumes, contacting the Volume Server
3563 * directly, bypassing the VLDB.
3566 * as : Ptr to parsed command line arguments.
3569 * 0 Successful operation
3572 * Nothing interesting.
3576 *------------------------------------------------------------------------*/
3579 ListVolumes(register struct cmd_syndesc *as, void *arock)
3581 afs_int32 apart, int32list, fast;
3582 afs_int32 aserver, code;
3584 volintInfo *oldpntr = NULL;
3588 volintXInfo *xInfoP;
3589 volintXInfo *origxInfoP = NULL; /*Ptr to current/orig extended vol info */
3590 int wantExtendedInfo; /*Do we want extended vol info? */
3593 struct partList dummyPartList;
3601 if (as->parms[3].items)
3603 if (as->parms[4].items)
3607 if (as->parms[2].items)
3613 if (as->parms[5].items) {
3615 * We can't coexist with the fast flag.
3619 "vos: Can't use the -fast and -extended flags together\n");
3624 * We need to turn on ``long'' listings to get the full effect.
3626 wantExtendedInfo = 1;
3629 wantExtendedInfo = 0;
3630 if (as->parms[1].items) {
3631 apart = volutil_GetPartitionID(as->parms[1].items->data);
3633 fprintf(STDERR, "vos: could not interpret partition name '%s'\n",
3634 as->parms[1].items->data);
3637 dummyPartList.partId[0] = apart;
3638 dummyPartList.partFlags[0] = PARTVALID;
3641 aserver = GetServer(as->parms[0].items->data);
3643 fprintf(STDERR, "vos: server '%s' not found in host table\n",
3644 as->parms[0].items->data);
3649 if (!IsPartValid(apart, aserver, &code)) { /*check for validity of the partition */
3651 PrintError("", code);
3654 "vos : partition %s does not exist on the server\n",
3655 as->parms[1].items->data);
3659 code = UV_ListPartitions(aserver, &dummyPartList, &cnt);
3661 PrintDiagnostics("listvol", code);
3665 for (i = 0; i < cnt; i++) {
3666 if (dummyPartList.partFlags[i] & PARTVALID) {
3667 if (wantExtendedInfo)
3669 UV_XListVolumes(aserver, dummyPartList.partId[i], all,
3673 UV_ListVolumes(aserver, dummyPartList.partId[i], all,
3676 PrintDiagnostics("listvol", code);
3681 if (wantExtendedInfo) {
3682 origxInfoP = xInfoP;
3683 base = (char *)xInfoP;
3686 base = (char *)pntr;
3690 if (wantExtendedInfo)
3691 qsort(base, count, sizeof(volintXInfo), XCompareVolName);
3693 qsort(base, count, sizeof(volintInfo), CompareVolName);
3695 if (wantExtendedInfo)
3696 qsort(base, count, sizeof(volintXInfo), XCompareVolID);
3698 qsort(base, count, sizeof(volintInfo), CompareVolID);
3700 MapPartIdIntoName(dummyPartList.partId[i], pname);
3703 "Total number of volumes on server %s partition %s: %lu \n",
3704 as->parms[0].items->data, pname,
3705 (unsigned long)count);
3706 if (wantExtendedInfo) {
3707 #ifdef FULL_LISTVOL_SWITCH
3708 if (as->parms[6].items)
3709 XDisplayVolumes2(aserver, dummyPartList.partId[i], origxInfoP,
3710 count, int32list, fast, quiet);
3712 #endif /* FULL_LISTVOL_SWITCH */
3713 XDisplayVolumes(aserver, dummyPartList.partId[i], origxInfoP,
3714 count, int32list, fast, quiet);
3717 xInfoP = (volintXInfo *) 0;
3719 #ifdef FULL_LISTVOL_SWITCH
3720 if (as->parms[6].items)
3721 DisplayVolumes2(aserver, dummyPartList.partId[i], oldpntr,
3724 #endif /* FULL_LISTVOL_SWITCH */
3725 DisplayVolumes(aserver, dummyPartList.partId[i], oldpntr,
3726 count, int32list, fast, quiet);
3729 pntr = (volintInfo *) 0;
3737 SyncVldb(register struct cmd_syndesc *as, void *arock)
3739 afs_int32 pnum = 0, code; /* part name */
3745 if (as->parms[0].items) {
3746 tserver = GetServer(as->parms[0].items->data);
3748 fprintf(STDERR, "vos: host '%s' not found in host table\n",
3749 as->parms[0].items->data);
3754 if (as->parms[1].items) {
3755 pnum = volutil_GetPartitionID(as->parms[1].items->data);
3757 fprintf(STDERR, "vos: could not interpret partition name '%s'\n",
3758 as->parms[1].items->data);
3761 if (!IsPartValid(pnum, tserver, &code)) { /*check for validity of the partition */
3763 PrintError("", code);
3766 "vos: partition %s does not exist on the server\n",
3767 as->parms[1].items->data);
3774 "The -partition option requires a -server option\n");
3779 if (as->parms[3].items) {
3780 flags |= 2; /* don't update */
3783 if (as->parms[2].items) {
3784 /* Synchronize an individual volume */
3785 volname = as->parms[2].items->data;
3786 code = UV_SyncVolume(tserver, pnum, volname, flags);
3790 "Without a -volume option, the -server option is required\n");
3793 code = UV_SyncVldb(tserver, pnum, flags, 0 /*unused */ );
3797 PrintDiagnostics("syncvldb", code);
3801 /* Print a summary of what we did */
3803 fprintf(STDOUT, "VLDB volume %s synchronized", volname);
3805 fprintf(STDOUT, "VLDB synchronized");
3807 fprintf(STDOUT, " with state of server %s", as->parms[0].items->data);
3810 MapPartIdIntoName(pnum, part);
3811 fprintf(STDOUT, " partition %s\n", part);
3813 fprintf(STDOUT, "\n");
3819 SyncServer(register struct cmd_syndesc *as, void *arock)
3821 afs_int32 pnum, code; /* part name */
3826 tserver = GetServer(as->parms[0].items->data);
3828 fprintf(STDERR, "vos: host '%s' not found in host table\n",
3829 as->parms[0].items->data);
3832 if (as->parms[1].items) {
3833 pnum = volutil_GetPartitionID(as->parms[1].items->data);
3835 fprintf(STDERR, "vos: could not interpret partition name '%s'\n",
3836 as->parms[1].items->data);
3839 if (!IsPartValid(pnum, tserver, &code)) { /*check for validity of the partition */
3841 PrintError("", code);
3844 "vos : partition %s does not exist on the server\n",
3845 as->parms[1].items->data);
3853 if (as->parms[2].items) {
3854 flags |= 2; /* don't update */
3856 code = UV_SyncServer(tserver, pnum, flags, 0 /*unused */ );
3858 PrintDiagnostics("syncserv", code);
3862 MapPartIdIntoName(pnum, part);
3863 fprintf(STDOUT, "Server %s partition %s synchronized with VLDB\n",
3864 as->parms[0].items->data, part);
3866 fprintf(STDOUT, "Server %s synchronized with VLDB\n",
3867 as->parms[0].items->data);
3873 VolumeInfoCmd(char *name)
3875 struct nvldbentry entry;
3878 /* The vlserver will handle names with the .readonly
3879 * and .backup extension as well as volume ids.
3881 vcode = VLDB_GetEntryByName(name, &entry);
3883 PrintError("", vcode);
3886 MapHostToNetwork(&entry);
3887 EnumerateEntry(&entry);
3889 /* Defect #3027: grubby check to handle locked volume.
3890 * If VLOP_ALLOPERS is set, the entry is locked.
3891 * Leave this routine as is, but put in correct check.
3893 if (entry.flags & VLOP_ALLOPERS)
3894 fprintf(STDOUT, " Volume is currently LOCKED \n");
3900 VolumeZap(register struct cmd_syndesc *as, void *arock)
3902 struct nvldbentry entry;
3903 afs_uint32 volid, zapbackupid = 0, backupid = 0;
3904 afs_int32 code, server, part, err;
3906 if (as->parms[3].items) {
3907 /* force flag is on, use the other version */
3908 return NukeVolume(as);
3911 if (as->parms[4].items) {
3915 volid = vsu_GetVolumeID(as->parms[2].items->data, cstruct, &err);
3918 PrintError("", err);
3920 fprintf(STDERR, "vos: can't find volume '%s'\n",
3921 as->parms[2].items->data);
3924 part = volutil_GetPartitionID(as->parms[1].items->data);
3926 fprintf(STDERR, "vos: could not interpret partition name '%s'\n",
3927 as->parms[1].items->data);
3930 server = GetServer(as->parms[0].items->data);
3932 fprintf(STDERR, "vos: host '%s' not found in host table\n",
3933 as->parms[0].items->data);
3936 if (!IsPartValid(part, server, &code)) { /*check for validity of the partition */
3938 PrintError("", code);
3941 "vos : partition %s does not exist on the server\n",
3942 as->parms[1].items->data);
3945 code = VLDB_GetEntryByID(volid, -1, &entry);
3947 if (volid == entry.volumeId[RWVOL])
3948 backupid = entry.volumeId[BACKVOL];
3950 "Warning: Entry for volume number %lu exists in VLDB (but we're zapping it anyway!)\n",
3951 (unsigned long)volid);
3954 volintInfo *pntr = (volintInfo *) 0;
3957 code = UV_ListOneVolume(server, part, volid, &pntr);
3959 if (volid == pntr->parentID)
3960 backupid = pntr->backupID;
3966 code = UV_VolumeZap(server, part, backupid);
3968 PrintDiagnostics("zap", code);
3971 fprintf(STDOUT, "Backup Volume %lu deleted\n",
3972 (unsigned long)backupid);
3975 code = UV_VolumeZap(server, part, volid);
3977 PrintDiagnostics("zap", code);
3980 fprintf(STDOUT, "Volume %lu deleted\n", (unsigned long)volid);
3986 VolserStatus(register struct cmd_syndesc *as, void *arock)
3988 afs_int32 server, code;
3989 transDebugInfo *pntr, *oldpntr;
3995 server = GetServer(as->parms[0].items->data);
3997 fprintf(STDERR, "vos: host '%s' not found in host table\n",
3998 as->parms[0].items->data);
4001 code = UV_VolserStatus(server, &pntr, &count);
4003 PrintDiagnostics("status", code);
4008 fprintf(STDOUT, "No active transactions on %s\n",
4009 as->parms[0].items->data);
4011 fprintf(STDOUT, "Total transactions: %d\n", count);
4013 for (i = 0; i < count; i++) {
4014 /*print out the relevant info */
4015 fprintf(STDOUT, "--------------------------------------\n");
4017 fprintf(STDOUT, "transaction: %lu created: %s",
4018 (unsigned long)pntr->tid, ctime(&t));
4019 if (pntr->returnCode) {
4020 fprintf(STDOUT, "returnCode: %lu\n",
4021 (unsigned long)pntr->returnCode);
4024 fprintf(STDOUT, "attachFlags: ");
4025 switch (pntr->iflags) {
4027 fprintf(STDOUT, "offline ");
4030 fprintf(STDOUT, "busy ");
4033 fprintf(STDOUT, "readonly ");
4036 fprintf(STDOUT, "create ");
4039 fprintf(STDOUT, "create volid ");
4042 fprintf(STDOUT, "\n");
4045 fprintf(STDOUT, "volumeStatus: ");
4046 switch (pntr->vflags) {
4047 case VTDeleteOnSalvage:
4048 fprintf(STDOUT, "deleteOnSalvage ");
4049 case VTOutOfService:
4050 fprintf(STDOUT, "outOfService ");
4052 fprintf(STDOUT, "deleted ");
4054 fprintf(STDOUT, "\n");
4057 fprintf(STDOUT, "transactionFlags: ");
4058 fprintf(STDOUT, "delete\n");
4060 MapPartIdIntoName(pntr->partition, pname);
4061 fprintf(STDOUT, "volume: %lu partition: %s procedure: %s\n",
4062 (unsigned long)pntr->volid, pname, pntr->lastProcName);
4063 if (pntr->callValid) {
4065 "packetRead: %lu lastReceiveTime: %d packetSend: %lu lastSendTime: %d\n",
4066 (unsigned long)pntr->readNext, pntr->lastReceiveTime,
4067 (unsigned long)pntr->transmitNext, pntr->lastSendTime);
4070 fprintf(STDOUT, "--------------------------------------\n");
4071 fprintf(STDOUT, "\n");
4079 RenameVolume(register struct cmd_syndesc *as, void *arock)
4081 afs_int32 code1, code2, code;
4082 struct nvldbentry entry;
4084 code1 = VLDB_GetEntryByName(as->parms[0].items->data, &entry);
4086 fprintf(STDERR, "vos: Could not find entry for volume %s\n",
4087 as->parms[0].items->data);
4090 code2 = VLDB_GetEntryByName(as->parms[1].items->data, &entry);
4091 if ((!code1) && (!code2)) { /*the newname already exists */
4092 fprintf(STDERR, "vos: volume %s already exists\n",
4093 as->parms[1].items->data);
4097 if (code1 && code2) {
4098 fprintf(STDERR, "vos: Could not find entry for volume %s or %s\n",
4099 as->parms[0].items->data, as->parms[1].items->data);
4102 if (!VolNameOK(as->parms[0].items->data)) {
4104 "Illegal volume name %s, should not end in .readonly or .backup\n",
4105 as->parms[0].items->data);
4108 if (!ISNAMEVALID(as->parms[1].items->data)) {
4110 "vos: the new volume name %s exceeds the size limit of %d\n",
4111 as->parms[1].items->data, VOLSER_OLDMAXVOLNAME - 10);
4114 if (!VolNameOK(as->parms[1].items->data)) {
4116 "Illegal volume name %s, should not end in .readonly or .backup\n",
4117 as->parms[1].items->data);
4120 if (IsNumeric(as->parms[1].items->data)) {
4121 fprintf(STDERR, "Illegal volume name %s, should not be a number\n",
4122 as->parms[1].items->data);
4125 MapHostToNetwork(&entry);
4127 UV_RenameVolume(&entry, as->parms[0].items->data,
4128 as->parms[1].items->data);
4130 PrintDiagnostics("rename", code);
4133 fprintf(STDOUT, "Renamed volume %s to %s\n", as->parms[0].items->data,
4134 as->parms[1].items->data);
4139 GetVolumeInfo(afs_uint32 volid, afs_int32 *server, afs_int32 *part, afs_int32 *voltype,
4140 struct nvldbentry *rentry)
4145 vcode = VLDB_GetEntryByID(volid, -1, rentry);
4148 "Could not fetch the entry for volume %lu from VLDB \n",
4149 (unsigned long)volid);
4150 PrintError("", vcode);
4153 MapHostToNetwork(rentry);
4154 if (volid == rentry->volumeId[ROVOL]) {
4156 for (i = 0; i < rentry->nServers; i++) {
4157 if ((index == -1) && (rentry->serverFlags[i] & ITSROVOL)
4158 && !(rentry->serverFlags[i] & RO_DONTUSE))
4163 "RO volume is not found in VLDB entry for volume %lu\n",
4164 (unsigned long)volid);
4168 *server = rentry->serverNumber[index];
4169 *part = rentry->serverPartition[index];
4173 index = Lp_GetRwIndex(rentry);
4176 "RW Volume is not found in VLDB entry for volume %lu\n",
4177 (unsigned long)volid);
4180 if (volid == rentry->volumeId[RWVOL]) {
4182 *server = rentry->serverNumber[index];
4183 *part = rentry->serverPartition[index];
4186 if (volid == rentry->volumeId[BACKVOL]) {
4188 *server = rentry->serverNumber[index];
4189 *part = rentry->serverPartition[index];
4193 "unexpected volume type for volume %lu\n",
4194 (unsigned long)volid);
4199 DeleteEntry(register struct cmd_syndesc *as, void *arock)
4201 afs_int32 apart = 0;
4204 struct VldbListByAttributes attributes;
4205 nbulkentries arrayEntries;
4206 register struct nvldbentry *vllist;
4207 struct cmd_item *itp;
4210 char prefix[VOLSER_MAXVOLNAME + 1];
4212 afs_int32 totalBack = 0, totalFail = 0, err;
4214 if (as->parms[0].items) { /* -id */
4215 if (as->parms[1].items || as->parms[2].items || as->parms[3].items) {
4217 "You cannot use -server, -partition, or -prefix with the -id argument\n");
4220 for (itp = as->parms[0].items; itp; itp = itp->next) {
4221 avolid = vsu_GetVolumeID(itp->data, cstruct, &err);
4224 PrintError("", err);
4226 fprintf(STDERR, "vos: can't find volume '%s'\n",
4230 if (as->parms[4].items) { /* -noexecute */
4231 fprintf(STDOUT, "Would have deleted VLDB entry for %s \n",
4236 vcode = ubik_VL_DeleteEntry(cstruct, 0, avolid, RWVOL);
4238 fprintf(STDERR, "Could not delete entry for volume %s\n",
4241 "You must specify a RW volume name or ID "
4242 "(the entire VLDB entry will be deleted)\n");
4243 PrintError("", vcode);
4249 fprintf(STDOUT, "Deleted %d VLDB entries\n", totalBack);
4253 if (!as->parms[1].items && !as->parms[2].items && !as->parms[3].items) {
4254 fprintf(STDERR, "You must specify an option\n");
4258 /* Zero out search attributes */
4259 memset(&attributes, 0, sizeof(struct VldbListByAttributes));
4261 if (as->parms[1].items) { /* -prefix */
4262 strncpy(prefix, as->parms[1].items->data, VOLSER_MAXVOLNAME);
4264 if (!as->parms[2].items && !as->parms[3].items) { /* a single entry only */
4266 "You must provide -server with the -prefix argument\n");
4271 if (as->parms[2].items) { /* -server */
4273 aserver = GetServer(as->parms[2].items->data);
4275 fprintf(STDERR, "vos: server '%s' not found in host table\n",
4276 as->parms[2].items->data);
4279 attributes.server = ntohl(aserver);
4280 attributes.Mask |= VLLIST_SERVER;
4283 if (as->parms[3].items) { /* -partition */
4284 if (!as->parms[2].items) {
4286 "You must provide -server with the -partition argument\n");
4289 apart = volutil_GetPartitionID(as->parms[3].items->data);
4291 fprintf(STDERR, "vos: could not interpret partition name '%s'\n",
4292 as->parms[3].items->data);
4295 attributes.partition = apart;
4296 attributes.Mask |= VLLIST_PARTITION;
4299 /* Print status line of what we are doing */
4300 fprintf(STDOUT, "Deleting VLDB entries for ");
4301 if (as->parms[2].items) {
4302 fprintf(STDOUT, "server %s ", as->parms[2].items->data);
4304 if (as->parms[3].items) {
4306 MapPartIdIntoName(apart, pname);
4307 fprintf(STDOUT, "partition %s ", pname);
4310 fprintf(STDOUT, "which are prefixed with %s ", prefix);
4312 fprintf(STDOUT, "\n");
4315 /* Get all the VLDB entries on a server and/or partition */
4316 memset(&arrayEntries, 0, sizeof(arrayEntries));
4317 vcode = VLDB_ListAttributes(&attributes, &nentries, &arrayEntries);
4319 fprintf(STDERR, "Could not access the VLDB for attributes\n");
4320 PrintError("", vcode);
4324 /* Process each entry */
4325 for (j = 0; j < nentries; j++) {
4326 vllist = &arrayEntries.nbulkentries_val[j];
4328 /* It only deletes the RW volumes */
4329 if (strncmp(vllist->name, prefix, strlen(prefix))) {
4332 "Omitting to delete %s due to prefix %s mismatch\n",
4333 vllist->name, prefix);
4340 if (as->parms[4].items) { /* -noexecute */
4341 fprintf(STDOUT, "Would have deleted VLDB entry for %s \n",
4347 /* Only matches the RW volume name */
4348 avolid = vllist->volumeId[RWVOL];
4349 vcode = ubik_VL_DeleteEntry(cstruct, 0, avolid, RWVOL);
4351 fprintf(STDOUT, "Could not delete VDLB entry for %s\n",
4354 PrintError("", vcode);
4359 fprintf(STDOUT, "Deleted VLDB entry for %s \n", vllist->name);
4364 fprintf(STDOUT, "----------------------\n");
4366 "Total VLDB entries deleted: %lu; failed to delete: %lu\n",
4367 (unsigned long)totalBack, (unsigned long)totalFail);
4368 if (arrayEntries.nbulkentries_val)
4369 free(arrayEntries.nbulkentries_val);
4375 CompareVldbEntryByName(const void *p1, const void *p2)
4377 struct nvldbentry *arg1, *arg2;
4379 arg1 = (struct nvldbentry *)p1;
4380 arg2 = (struct nvldbentry *)p2;
4381 return (strcmp(arg1->name, arg2->name));
4385 static int CompareVldbEntry(char *p1, char *p2)
4387 struct nvldbentry *arg1,*arg2;
4390 char comp1[100],comp2[100];
4391 char temp1[20],temp2[20];
4393 arg1 = (struct nvldbentry *)p1;
4394 arg2 = (struct nvldbentry *)p2;
4398 for(i = 0; i < arg1->nServers; i++)
4399 if(arg1->serverFlags[i] & ITSRWVOL) pos1 = i;
4400 for(i = 0; i < arg2->nServers; i++)
4401 if(arg2->serverFlags[i] & ITSRWVOL) pos2 = i;
4402 if(pos1 == -1 || pos2 == -1){
4406 sprintf(comp1,"%10u",arg1->serverNumber[pos1]);
4407 sprintf(comp2,"%10u",arg2->serverNumber[pos2]);
4408 sprintf(temp1,"%10u",arg1->serverPartition[pos1]);
4409 sprintf(temp2,"%10u",arg2->serverPartition[pos2]);
4410 strcat(comp1,temp1);
4411 strcat(comp2,temp2);
4412 strcat(comp1,arg1->name);
4413 strcat(comp1,arg2->name);
4414 return(strcmp(comp1,comp2));
4420 ListVLDB(struct cmd_syndesc *as, void *arock)
4423 afs_int32 aserver, code;
4425 struct VldbListByAttributes attributes;
4426 nbulkentries arrayEntries;
4427 struct nvldbentry *vllist, *tarray = 0, *ttarray;
4428 afs_int32 centries, nentries = 0;
4429 afs_int32 tarraysize = 0;
4430 afs_int32 parraysize;
4433 int quiet, sort, lock;
4434 afs_int32 thisindex, nextindex;
4439 attributes.Mask = 0;
4440 lock = (as->parms[3].items ? 1 : 0); /* -lock flag */
4441 quiet = (as->parms[4].items ? 1 : 0); /* -quit flag */
4442 sort = (as->parms[5].items ? 0 : 1); /* -nosort flag */
4444 /* If the volume name is given, Use VolumeInfoCmd to look it up
4445 * and not ListAttributes.
4447 if (as->parms[0].items) {
4450 "vos: illegal use of '-locked' switch, need to specify server and/or partition\n");
4453 code = VolumeInfoCmd(as->parms[0].items->data);
4455 PrintError("", code);
4461 /* Server specified */
4462 if (as->parms[1].items) {
4463 aserver = GetServer(as->parms[1].items->data);
4465 fprintf(STDERR, "vos: server '%s' not found in host table\n",
4466 as->parms[1].items->data);
4469 attributes.server = ntohl(aserver);
4470 attributes.Mask |= VLLIST_SERVER;
4473 /* Partition specified */
4474 if (as->parms[2].items) {
4475 apart = volutil_GetPartitionID(as->parms[2].items->data);
4477 fprintf(STDERR, "vos: could not interpret partition name '%s'\n",
4478 as->parms[2].items->data);
4481 attributes.partition = apart;
4482 attributes.Mask |= VLLIST_PARTITION;
4486 attributes.Mask |= VLLIST_FLAG;
4487 attributes.flag = VLOP_ALLOPERS;
4490 /* Print header information */
4492 MapPartIdIntoName(apart, pname);
4493 fprintf(STDOUT, "VLDB entries for %s %s%s%s %s\n",
4494 (as->parms[1].items ? "server" : "all"),
4495 (as->parms[1].items ? as->parms[1].items->data : "servers"),
4496 (as->parms[2].items ? " partition " : ""),
4497 (as->parms[2].items ? pname : ""),
4498 (lock ? "which are locked:" : ""));
4501 for (thisindex = 0; (thisindex != -1); thisindex = nextindex) {
4502 memset(&arrayEntries, 0, sizeof(arrayEntries));
4507 VLDB_ListAttributesN2(&attributes, 0, thisindex, ¢ries,
4508 &arrayEntries, &nextindex);
4509 if (vcode == RXGEN_OPCODE) {
4510 /* Vlserver not running with ListAttributesN2. Fall back */
4512 VLDB_ListAttributes(&attributes, ¢ries, &arrayEntries);
4516 fprintf(STDERR, "Could not access the VLDB for attributes\n");
4517 PrintError("", vcode);
4520 nentries += centries;
4522 /* We don't sort, so just print the entries now */
4524 for (j = 0; j < centries; j++) { /* process each entry */
4525 vllist = &arrayEntries.nbulkentries_val[j];
4526 MapHostToNetwork(vllist);
4527 EnumerateEntry(vllist);
4529 if (vllist->flags & VLOP_ALLOPERS)
4530 fprintf(STDOUT, " Volume is currently LOCKED \n");
4534 /* So we sort. First we must collect all the entries and keep
4537 else if (centries > 0) {
4539 /* steal away the first bulk entries array */
4540 tarray = (struct nvldbentry *)arrayEntries.nbulkentries_val;
4541 tarraysize = centries * sizeof(struct nvldbentry);
4542 arrayEntries.nbulkentries_val = 0;
4544 /* Grow the tarray to keep the extra entries */
4545 parraysize = (centries * sizeof(struct nvldbentry));
4547 (struct nvldbentry *)realloc(tarray,
4548 tarraysize + parraysize);
4551 "Could not allocate enough space for the VLDB entries\n");
4557 memcpy(((char *)tarray) + tarraysize,
4558 (char *)arrayEntries.nbulkentries_val, parraysize);
4559 tarraysize += parraysize;
4563 /* Free the bulk array */
4564 if (arrayEntries.nbulkentries_val) {
4565 free(arrayEntries.nbulkentries_val);
4566 arrayEntries.nbulkentries_val = 0;
4570 /* Here is where we now sort all the entries and print them */
4571 if (sort && (nentries > 0)) {
4572 qsort((char *)tarray, nentries, sizeof(struct nvldbentry),
4573 CompareVldbEntryByName);
4574 for (vllist = tarray, j = 0; j < nentries; j++, vllist++) {
4575 MapHostToNetwork(vllist);
4576 EnumerateEntry(vllist);
4578 if (vllist->flags & VLOP_ALLOPERS)
4579 fprintf(STDOUT, " Volume is currently LOCKED \n");
4585 fprintf(STDOUT, "\nTotal entries: %lu\n", (unsigned long)nentries);
4592 BackSys(register struct cmd_syndesc *as, void *arock)
4595 afs_int32 apart = 0;
4596 afs_int32 aserver = 0, code, aserver1, apart1;
4598 struct VldbListByAttributes attributes;
4599 nbulkentries arrayEntries;
4600 register struct nvldbentry *vllist;
4604 int seenprefix, seenxprefix, exclude, ex, exp, noaction;
4605 afs_int32 totalBack = 0;
4606 afs_int32 totalFail = 0;
4610 struct cmd_item *ti;
4612 #ifndef HAVE_POSIX_REGEX
4616 memset(&attributes, 0, sizeof(struct VldbListByAttributes));
4617 attributes.Mask = 0;
4619 seenprefix = (as->parms[0].items ? 1 : 0);
4620 exclude = (as->parms[3].items ? 1 : 0);
4621 seenxprefix = (as->parms[4].items ? 1 : 0);
4622 noaction = (as->parms[5].items ? 1 : 0);
4624 if (as->parms[1].items) { /* -server */
4625 aserver = GetServer(as->parms[1].items->data);
4627 fprintf(STDERR, "vos: server '%s' not found in host table\n",
4628 as->parms[1].items->data);
4631 attributes.server = ntohl(aserver);
4632 attributes.Mask |= VLLIST_SERVER;
4635 if (as->parms[2].items) { /* -partition */
4636 apart = volutil_GetPartitionID(as->parms[2].items->data);
4638 fprintf(STDERR, "vos: could not interpret partition name '%s'\n",
4639 as->parms[2].items->data);
4642 attributes.partition = apart;
4643 attributes.Mask |= VLLIST_PARTITION;
4646 /* Check to make sure the prefix and xprefix expressions compile ok */
4648 for (ti = as->parms[0].items; ti; ti = ti->next) {
4649 if (strncmp(ti->data, "^", 1) == 0) {
4650 #ifdef HAVE_POSIX_REGEX
4654 code = regcomp(&re, ti->data, REG_NOSUB);
4656 regerror(code, &re, errbuf, sizeof errbuf);
4658 "Unrecognizable -prefix regular expression: '%s': %s\n",
4664 ccode = (char *)re_comp(ti->data);
4667 "Unrecognizable -prefix regular expression: '%s': %s\n",
4676 for (ti = as->parms[4].items; ti; ti = ti->next) {
4677 if (strncmp(ti->data, "^", 1) == 0) {
4678 #ifdef HAVE_POSIX_REGEX
4682 code = regcomp(&re, ti->data, REG_NOSUB);
4684 regerror(code, &re, errbuf, sizeof errbuf);
4686 "Unrecognizable -xprefix regular expression: '%s': %s\n",
4692 ccode = (char *)re_comp(ti->data);
4695 "Unrecognizable -xprefix regular expression: '%s': %s\n",
4704 memset(&arrayEntries, 0, sizeof(arrayEntries)); /* initialize to hint the stub to alloc space */
4705 vcode = VLDB_ListAttributes(&attributes, &nentries, &arrayEntries);
4707 fprintf(STDERR, "Could not access the VLDB for attributes\n");
4708 PrintError("", vcode);
4712 if (as->parms[1].items || as->parms[2].items || verbose) {
4713 fprintf(STDOUT, "%s up volumes",
4714 (noaction ? "Would have backed" : "Backing"));
4716 if (as->parms[1].items) {
4717 fprintf(STDOUT, " on server %s", as->parms[1].items->data);
4718 } else if (as->parms[2].items) {
4719 fprintf(STDOUT, " for all servers");
4722 if (as->parms[2].items) {
4723 MapPartIdIntoName(apart, pname);
4724 fprintf(STDOUT, " partition %s", pname);
4727 if (seenprefix || (!seenprefix && seenxprefix)) {
4728 ti = (seenprefix ? as->parms[0].items : as->parms[4].items);
4729 ex = (seenprefix ? exclude : !exclude);
4730 exp = (strncmp(ti->data, "^", 1) == 0);
4731 fprintf(STDOUT, " which %smatch %s '%s'", (ex ? "do not " : ""),
4732 (exp ? "expression" : "prefix"), ti->data);
4733 for (ti = ti->next; ti; ti = ti->next) {
4734 exp = (strncmp(ti->data, "^", 1) == 0);
4735 printf(" %sor %s '%s'", (ex ? "n" : ""),
4736 (exp ? "expression" : "prefix"), ti->data);
4740 if (seenprefix && seenxprefix) {
4741 ti = as->parms[4].items;
4742 exp = (strncmp(ti->data, "^", 1) == 0);
4743 fprintf(STDOUT, " %swhich match %s '%s'",
4744 (exclude ? "adding those " : "removing those "),
4745 (exp ? "expression" : "prefix"), ti->data);
4746 for (ti = ti->next; ti; ti = ti->next) {
4747 exp = (strncmp(ti->data, "^", 1) == 0);
4748 printf(" or %s '%s'", (exp ? "expression" : "prefix"),
4752 fprintf(STDOUT, " .. ");
4754 fprintf(STDOUT, "\n");
4758 for (j = 0; j < nentries; j++) { /* process each vldb entry */
4759 vllist = &arrayEntries.nbulkentries_val[j];
4762 for (ti = as->parms[0].items; ti; ti = ti->next) {
4763 if (strncmp(ti->data, "^", 1) == 0) {
4764 #ifdef HAVE_POSIX_REGEX
4768 /* XXX -- should just do the compile once! */
4769 code = regcomp(&re, ti->data, REG_NOSUB);
4771 regerror(code, &re, errbuf, sizeof errbuf);
4773 "Error in -prefix regular expression: '%s': %s\n",
4777 match = (regexec(&re, vllist->name, 0, NULL, 0) == 0);
4780 ccode = (char *)re_comp(ti->data);
4783 "Error in -prefix regular expression: '%s': %s\n",
4787 match = (re_exec(vllist->name) == 1);
4791 (strncmp(vllist->name, ti->data, strlen(ti->data)) ==
4801 /* Without the -exclude flag: If it matches the prefix, then
4802 * check if we want to exclude any from xprefix.
4803 * With the -exclude flag: If it matches the prefix, then
4804 * check if we want to add any from xprefix.
4806 if (match && seenxprefix) {
4807 for (ti = as->parms[4].items; ti; ti = ti->next) {
4808 if (strncmp(ti->data, "^", 1) == 0) {
4809 #ifdef HAVE_POSIX_REGEX
4813 /* XXX -- should just do the compile once! */
4814 code = regcomp(&re, ti->data, REG_NOSUB);
4816 regerror(code, &re, errbuf, sizeof errbuf);
4818 "Error in -xprefix regular expression: '%s': %s\n",
4822 if (regexec(&re, vllist->name, 0, NULL, 0) == 0)
4826 ccode = (char *)re_comp(ti->data);
4829 "Error in -xprefix regular expression: '%s': %s\n",
4833 if (re_exec(vllist->name) == 1) {
4839 if (strncmp(vllist->name, ti->data, strlen(ti->data)) ==
4849 match = !match; /* -exclude will reverse the match */
4851 continue; /* Skip if no match */
4853 /* Print list of volumes to backup */
4855 fprintf(STDOUT, " %s\n", vllist->name);
4859 if (!(vllist->flags & RW_EXISTS)) {
4862 "Omitting to backup %s since RW volume does not exist \n",
4864 fprintf(STDOUT, "\n");
4870 avolid = vllist->volumeId[RWVOL];
4871 MapHostToNetwork(vllist);
4872 GetServerAndPart(vllist, RWVOL, &aserver1, &apart1, &previdx);
4873 if (aserver1 == -1 || apart1 == -1) {
4874 fprintf(STDOUT, "could not backup %s, invalid VLDB entry\n",
4880 same = VLDB_IsSameAddrs(aserver, aserver1, &error);
4883 "Failed to get info about server's %d address(es) from vlserver (err=%d); aborting call!\n",
4889 if ((aserver && !same) || (apart && (apart != apart1))) {
4892 "Omitting to backup %s since the RW is in a different location\n",
4898 time_t now = time(0);
4899 fprintf(STDOUT, "Creating backup volume for %s on %s",
4900 vllist->name, ctime(&now));
4904 code = UV_BackupVolume(aserver1, apart1, avolid);
4906 fprintf(STDOUT, "Could not backup %s\n", vllist->name);
4912 fprintf(STDOUT, "\n");
4914 } /* process each vldb entry */
4915 fprintf(STDOUT, "done\n");
4916 fprintf(STDOUT, "Total volumes backed up: %lu; failed to backup: %lu\n",
4917 (unsigned long)totalBack, (unsigned long)totalFail);
4919 if (arrayEntries.nbulkentries_val)
4920 free(arrayEntries.nbulkentries_val);
4925 UnlockVLDB(register struct cmd_syndesc *as, void *arock)
4928 afs_int32 aserver = 0;
4931 struct VldbListByAttributes attributes;
4932 nbulkentries arrayEntries;
4933 register struct nvldbentry *vllist;
4942 attributes.Mask = 0;
4944 if (as->parms[0].items) { /* server specified */
4945 aserver = GetServer(as->parms[0].items->data);
4947 fprintf(STDERR, "vos: server '%s' not found in host table\n",
4948 as->parms[0].items->data);
4951 attributes.server = ntohl(aserver);
4952 attributes.Mask |= VLLIST_SERVER;
4954 if (as->parms[1].items) { /* partition specified */
4955 apart = volutil_GetPartitionID(as->parms[1].items->data);
4957 fprintf(STDERR, "vos: could not interpret partition name '%s'\n",
4958 as->parms[1].items->data);
4961 if (!IsPartValid(apart, aserver, &code)) { /*check for validity of the partition */
4963 PrintError("", code);
4966 "vos : partition %s does not exist on the server\n",
4967 as->parms[1].items->data);
4970 attributes.partition = apart;
4971 attributes.Mask |= VLLIST_PARTITION;
4973 attributes.flag = VLOP_ALLOPERS;
4974 attributes.Mask |= VLLIST_FLAG;
4975 memset(&arrayEntries, 0, sizeof(arrayEntries)); /*initialize to hint the stub to alloc space */
4976 vcode = VLDB_ListAttributes(&attributes, &nentries, &arrayEntries);
4978 fprintf(STDERR, "Could not access the VLDB for attributes\n");
4979 PrintError("", vcode);
4982 for (j = 0; j < nentries; j++) { /* process each entry */
4983 vllist = &arrayEntries.nbulkentries_val[j];
4984 volid = vllist->volumeId[RWVOL];
4986 ubik_VL_ReleaseLock(cstruct, 0, volid, -1,
4987 LOCKREL_OPCODE | LOCKREL_AFSID |
4990 fprintf(STDERR, "Could not unlock entry for volume %s\n",
4992 PrintError("", vcode);
4997 MapPartIdIntoName(apart, pname);
5000 "Could not lock %lu VLDB entries of %lu locked entries\n",
5001 (unsigned long)totalE, (unsigned long)nentries);
5003 if (as->parms[0].items) {
5005 "Unlocked all the VLDB entries for volumes on server %s ",
5006 as->parms[0].items->data);
5007 if (as->parms[1].items) {
5008 MapPartIdIntoName(apart, pname);
5009 fprintf(STDOUT, "partition %s\n", pname);
5011 fprintf(STDOUT, "\n");
5013 } else if (as->parms[1].items) {
5014 MapPartIdIntoName(apart, pname);
5016 "Unlocked all the VLDB entries for volumes on partition %s on all servers\n",
5021 if (arrayEntries.nbulkentries_val)
5022 free(arrayEntries.nbulkentries_val);
5027 PrintInt64Size(afs_uint64 in)
5029 register afs_uint32 hi, lo;
5030 register char * units;
5031 static char output[16];
5033 SplitInt64(in,hi,lo);
5037 } else if (!(hi & 0xFFFFFC00)) {
5039 lo = (hi << 22) | (lo >> 10);
5040 } else if (!(hi & 0xFFF00000)) {
5042 lo = (hi << 12) | (lo >> 20);
5043 } else if (!(hi & 0xC0000000)) {
5045 lo = (hi << 2) | (lo >> 30);
5050 sprintf(output,"%u %s", lo, units);
5055 PartitionInfo(register struct cmd_syndesc *as, void *arock)
5058 afs_int32 aserver, code;
5060 struct diskPartition64 partition;
5061 struct partList dummyPartList;
5063 int printSummary=0, sumPartitions=0;
5064 afs_uint64 sumFree, sumStorage;
5067 ZeroInt64(sumStorage);
5069 aserver = GetServer(as->parms[0].items->data);
5071 fprintf(STDERR, "vos: server '%s' not found in host table\n",
5072 as->parms[0].items->data);
5075 if (as->parms[1].items) {
5076 apart = volutil_GetPartitionID(as->parms[1].items->data);
5078 fprintf(STDERR, "vos: could not interpret partition name '%s'\n",
5079 as->parms[1].items->data);
5082 dummyPartList.partId[0] = apart;
5083 dummyPartList.partFlags[0] = PARTVALID;
5086 if (as->parms[2].items) {
5090 if (!IsPartValid(apart, aserver, &code)) { /*check for validity of the partition */
5092 PrintError("", code);
5095 "vos : partition %s does not exist on the server\n",
5096 as->parms[1].items->data);
5100 code = UV_ListPartitions(aserver, &dummyPartList, &cnt);
5102 PrintDiagnostics("listpart", code);
5106 for (i = 0; i < cnt; i++) {
5107 if (dummyPartList.partFlags[i] & PARTVALID) {
5108 MapPartIdIntoName(dummyPartList.partId[i], pname);
5109 code = UV_PartitionInfo64(aserver, pname, &partition);
5111 fprintf(STDERR, "Could not get information on partition %s\n",
5113 PrintError("", code);
5117 "Free space on partition %s: %" AFS_INT64_FMT " K blocks out of total %" AFS_INT64_FMT "\n",
5118 pname, partition.free, partition.minFree);
5120 AddUInt64(sumFree,partition.free,&sumFree);
5121 AddUInt64(sumStorage,partition.minFree,&sumStorage);
5126 "Summary: %s free out of ",
5127 PrintInt64Size(sumFree));
5129 "%s on %d partitions\n",
5130 PrintInt64Size(sumStorage),
5137 ChangeAddr(register struct cmd_syndesc *as, void *arock)
5139 afs_int32 ip1, ip2, vcode;
5142 ip1 = GetServer(as->parms[0].items->data);
5144 fprintf(STDERR, "vos: invalid host address\n");
5148 if ((as->parms[1].items && as->parms[2].items)
5149 || (!as->parms[1].items && !as->parms[2].items)) {
5151 "vos: Must specify either '-newaddr <addr>' or '-remove' flag\n");
5155 if (as->parms[1].items) {
5156 ip2 = GetServer(as->parms[1].items->data);
5158 fprintf(STDERR, "vos: invalid host address\n");
5162 /* Play a trick here. If we are removing an address, ip1 will be -1
5163 * and ip2 will be the original address. This switch prevents an
5164 * older revision vlserver from removing the IP address.
5171 vcode = ubik_Call_New(VL_ChangeAddr, cstruct, 0, ntohl(ip1), ntohl(ip2));
5174 fprintf(STDERR, "Could not remove server %s from the VLDB\n",
5175 as->parms[0].items->data);
5176 if (vcode == VL_NOENT) {
5178 "vlserver does not support the remove flag or ");
5181 fprintf(STDERR, "Could not change server %s to server %s\n",
5182 as->parms[0].items->data, as->parms[1].items->data);
5184 PrintError("", vcode);
5189 fprintf(STDOUT, "Removed server %s from the VLDB\n",
5190 as->parms[0].items->data);
5192 fprintf(STDOUT, "Changed server %s to server %s\n",
5193 as->parms[0].items->data, as->parms[1].items->data);
5199 print_addrs(const bulkaddrs * addrs, afsUUID * m_uuid, int nentries,
5204 struct VLCallBack vlcb;
5207 ListAddrByAttributes m_attrs;
5208 afs_int32 m_nentries, *m_addrp;
5209 afs_int32 base, index;
5213 afsUUID_to_string(m_uuid, buf, sizeof(buf));
5214 printf("UUID: %s\n", buf);
5217 /* print out the list of all the server */
5218 addrp = (afs_int32 *) addrs->bulkaddrs_val;
5219 for (i = 0; i < nentries; i++, addrp++) {
5220 /* If it is a multihomed address, then we will need to
5221 * get the addresses for this multihomed server from
5222 * the vlserver and print them.
5224 if (((*addrp & 0xff000000) == 0xff000000) && ((*addrp) & 0xffff)) {
5225 /* Get the list of multihomed fileservers */
5226 base = (*addrp >> 16) & 0xff;
5227 index = (*addrp) & 0xffff;
5229 if ((base >= 0) && (base <= VL_MAX_ADDREXTBLKS) && (index >= 1)
5230 && (index <= VL_MHSRV_PERBLK)) {
5231 m_attrs.Mask = VLADDR_INDEX;
5232 m_attrs.index = (base * VL_MHSRV_PERBLK) + index;
5234 m_addrs.bulkaddrs_val = 0;
5235 m_addrs.bulkaddrs_len = 0;
5237 ubik_VL_GetAddrsU(cstruct, 0, &m_attrs, m_uuid,
5238 (afs_int32 *)&vlcb, &m_nentries, &m_addrs);
5241 "vos: could not list the multi-homed server addresses\n");
5242 PrintError("", vcode);
5245 /* Print the list */
5246 m_addrp = (afs_int32 *) m_addrs.bulkaddrs_val;
5247 for (j = 0; j < m_nentries; j++, m_addrp++) {
5248 *m_addrp = htonl(*m_addrp);
5251 printf("%s ", afs_inet_ntoa_r(*m_addrp, hoststr));
5253 printf("%s ", hostutil_GetNameByINet(*m_addrp));
5257 printf("<unknown>\n");
5266 /* Otherwise, it is a non-multihomed entry and contains
5267 * the IP address of the server - print it.
5269 *addrp = htonl(*addrp);
5272 printf("%s\n", afs_inet_ntoa_r(*addrp, hoststr));
5274 printf("%s\n", hostutil_GetNameByINet(*addrp));
5285 ListAddrs(register struct cmd_syndesc *as, void *arock)
5288 afs_int32 i, printuuid = 0;
5289 struct VLCallBack vlcb;
5292 ListAddrByAttributes m_attrs;
5293 afsUUID m_uuid, askuuid;
5294 afs_int32 m_nentries;
5296 memset(&m_attrs, 0, sizeof(struct ListAddrByAttributes));
5297 m_attrs.Mask = VLADDR_INDEX;
5299 memset(&m_addrs, 0, sizeof(bulkaddrs));
5300 memset(&askuuid, 0, sizeof(afsUUID));
5301 if (as->parms[0].items) {
5303 if (afsUUID_from_string(as->parms[0].items->data, &askuuid) < 0) {
5304 fprintf(STDERR, "vos: invalid UUID '%s'\n",
5305 as->parms[0].items->data);
5308 m_attrs.Mask = VLADDR_UUID;
5309 m_attrs.uuid = askuuid;
5311 if (as->parms[1].items) {
5315 he = hostutil_GetHostByName((char *)as->parms[1].items->data);
5317 fprintf(STDERR, "vos: Can't get host info for '%s'\n",
5318 as->parms[1].items->data);
5321 memcpy(&saddr, he->h_addr, 4);
5322 m_attrs.Mask = VLADDR_IPADDR;
5323 m_attrs.ipaddr = ntohl(saddr);
5325 if (as->parms[2].items) {
5329 m_addrs.bulkaddrs_val = 0;
5330 m_addrs.bulkaddrs_len = 0;
5333 ubik_Call_New(VL_GetAddrs, cstruct, 0, 0, 0, &vlcb, &nentries,
5336 fprintf(STDERR, "vos: could not list the server addresses\n");
5337 PrintError("", vcode);
5342 m_addrs.bulkaddrs_val = 0;
5343 m_addrs.bulkaddrs_len = 0;
5349 ubik_Call_New(VL_GetAddrsU, cstruct, 0, &m_attrs, &m_uuid,
5350 &vlcb, &m_nentries, &m_addrs);
5352 if (vcode == VL_NOENT) {
5353 if (m_attrs.Mask == VLADDR_UUID) {
5354 fprintf(STDERR, "vos: no entry for UUID '%s' found in VLDB\n",
5355 as->parms[0].items->data);
5357 } else if (m_attrs.Mask == VLADDR_IPADDR) {
5358 fprintf(STDERR, "vos: no entry for host '%s' [0x%08x] found in VLDB\n",
5359 as->parms[1].items->data, m_attrs.ipaddr);
5368 if (vcode == VL_INDEXERANGE) {
5373 fprintf(STDERR, "vos: could not list the server addresses\n");
5374 PrintError("", vcode);
5378 print_addrs(&m_addrs, &m_uuid, m_nentries, printuuid);
5381 if ((as->parms[1].items) || (as->parms[0].items) || (i > nentries))
5389 LockEntry(register struct cmd_syndesc *as, void *arock)
5392 afs_int32 vcode, err;
5394 avolid = vsu_GetVolumeID(as->parms[0].items->data, cstruct, &err);
5397 PrintError("", err);
5399 fprintf(STDERR, "vos: can't find volume '%s'\n",
5400 as->parms[0].items->data);
5403 vcode = ubik_VL_SetLock(cstruct, 0, avolid, -1, VLOP_DELETE);
5405 fprintf(STDERR, "Could not lock VLDB entry for volume %s\n",
5406 as->parms[0].items->data);
5407 PrintError("", vcode);
5410 fprintf(STDOUT, "Locked VLDB entry for volume %s\n",
5411 as->parms[0].items->data);
5416 ConvertRO(register struct cmd_syndesc *as, void *arock)
5418 afs_int32 partition = -1;
5420 afs_int32 server, code, i, same;
5421 struct nvldbentry entry, storeEntry;
5423 afs_int32 rwindex = 0;
5424 afs_int32 rwserver = 0;
5425 afs_int32 rwpartition = 0;
5426 afs_int32 roindex = 0;
5427 afs_int32 roserver = 0;
5428 afs_int32 ropartition = 0;
5430 struct rx_connection *aconn;
5433 server = GetServer(as->parms[0].items->data);
5435 fprintf(STDERR, "vos: host '%s' not found in host table\n",
5436 as->parms[0].items->data);
5439 partition = volutil_GetPartitionID(as->parms[1].items->data);
5440 if (partition < 0) {
5441 fprintf(STDERR, "vos: could not interpret partition name '%s'\n",
5442 as->parms[1].items->data);
5445 if (!IsPartValid(partition, server, &code)) {
5447 PrintError("", code);
5450 "vos : partition %s does not exist on the server\n",
5451 as->parms[1].items->data);
5454 volid = vsu_GetVolumeID(as->parms[2].items->data, cstruct, &code);
5457 PrintError("", code);
5459 fprintf(STDERR, "Unknown volume ID or name '%s'\n",
5460 as->parms[0].items->data);
5463 if (as->parms[3].items)
5466 vcode = VLDB_GetEntryByID(volid, -1, &entry);
5469 "Could not fetch the entry for volume %lu from VLDB\n",
5470 (unsigned long)volid);
5471 PrintError("convertROtoRW", code);
5475 /* use RO volid even if user specified RW or BK volid */
5477 if (volid != entry.volumeId[ROVOL])
5478 volid = entry.volumeId[ROVOL];
5480 MapHostToNetwork(&entry);
5481 for (i = 0; i < entry.nServers; i++) {
5482 if (entry.serverFlags[i] & ITSRWVOL) {
5484 rwserver = entry.serverNumber[i];
5485 rwpartition = entry.serverPartition[i];
5487 if (entry.serverFlags[i] & ITSROVOL) {
5488 same = VLDB_IsSameAddrs(server, entry.serverNumber[i], &code);
5491 "Failed to get info about server's %d address(es) from vlserver (err=%d); aborting call!\n",
5497 roserver = entry.serverNumber[i];
5498 ropartition = entry.serverPartition[i];
5504 fprintf(STDERR, "Warning: RO volume didn't exist in vldb!\n");
5506 if (ropartition != partition) {
5508 "Warning: RO volume should be in partition %d instead of %d (vldb)\n",
5509 ropartition, partition);
5514 "VLDB indicates that a RW volume exists already on %s in partition %s.\n",
5515 hostutil_GetNameByINet(rwserver),
5516 volutil_PartitionName(rwpartition));
5518 fprintf(STDERR, "Overwrite this VLDB entry? [y|n] (n)\n");
5520 while (!(dc == EOF || dc == '\n'))
5521 dc = getchar(); /* goto end of line */
5522 if ((c != 'y') && (c != 'Y')) {
5523 fprintf(STDERR, "aborted.\n");
5530 ubik_VL_SetLock(cstruct, 0, entry.volumeId[RWVOL], RWVOL,
5532 aconn = UV_Bind(server, AFSCONF_VOLUMEPORT);
5533 code = AFSVolConvertROtoRWvolume(aconn, partition, volid);
5536 "Converting RO volume %lu to RW volume failed with code %d\n",
5537 (unsigned long)volid, code);
5538 PrintError("convertROtoRW ", code);
5541 entry.serverFlags[roindex] = ITSRWVOL;
5542 entry.flags |= RW_EXISTS;
5543 entry.flags &= ~BACK_EXISTS;
5546 if (rwindex != entry.nServers) {
5547 entry.serverNumber[rwindex] = entry.serverNumber[entry.nServers];
5548 entry.serverPartition[rwindex] =
5549 entry.serverPartition[entry.nServers];
5550 entry.serverFlags[rwindex] = entry.serverFlags[entry.nServers];
5551 entry.serverNumber[entry.nServers] = 0;
5552 entry.serverPartition[entry.nServers] = 0;
5553 entry.serverFlags[entry.nServers] = 0;
5556 entry.flags &= ~RO_EXISTS;
5557 for (i = 0; i < entry.nServers; i++) {
5558 if (entry.serverFlags[i] & ITSROVOL) {
5559 if (!(entry.serverFlags[i] & (RO_DONTUSE | NEW_REPSITE)))
5560 entry.flags |= RO_EXISTS;
5563 MapNetworkToHost(&entry, &storeEntry);
5565 VLDB_ReplaceEntry(entry.volumeId[RWVOL], RWVOL, &storeEntry,
5566 (LOCKREL_OPCODE | LOCKREL_AFSID |
5567 LOCKREL_TIMESTAMP));
5570 "Warning: volume converted, but vldb update failed with code %d!\n",
5573 vcode = UV_LockRelease(entry.volumeId[RWVOL]);
5575 PrintDiagnostics("unlock", vcode);
5581 Sizes(register struct cmd_syndesc *as, void *arock)
5584 afs_int32 aserver, apart, voltype, fromdate = 0, code, err, i;
5585 struct nvldbentry entry;
5586 volintSize vol_size;
5588 rx_SetRxDeadTime(60 * 10);
5589 for (i = 0; i < MAXSERVERS; i++) {
5590 struct rx_connection *rxConn = ubik_GetRPCConn(cstruct, i);
5593 rx_SetConnDeadTime(rxConn, rx_connDeadTime);
5594 if (rxConn->service)
5595 rxConn->service->connDeadTime = rx_connDeadTime;
5598 avolid = vsu_GetVolumeID(as->parms[0].items->data, cstruct, &err);
5601 PrintError("", err);
5603 fprintf(STDERR, "vos: can't find volume '%s'\n",
5604 as->parms[0].items->data);
5608 if (as->parms[1].items || as->parms[2].items) {
5609 if (!as->parms[1].items || !as->parms[2].items) {
5611 "Must specify both -server and -partition options\n");
5614 aserver = GetServer(as->parms[2].items->data);
5616 fprintf(STDERR, "Invalid server name\n");
5619 apart = volutil_GetPartitionID(as->parms[1].items->data);
5621 fprintf(STDERR, "Invalid partition name\n");
5625 code = GetVolumeInfo(avolid, &aserver, &apart, &voltype, &entry);
5632 if (as->parms[4].items && strcmp(as->parms[4].items->data, "0")) {
5633 code = ktime_DateToInt32(as->parms[4].items->data, &fromdate);
5635 fprintf(STDERR, "vos: failed to parse date '%s' (error=%d))\n",
5636 as->parms[4].items->data, code);
5641 fprintf(STDOUT, "Volume: %s\n", as->parms[0].items->data);
5643 if (as->parms[3].items) { /* do the dump estimate */
5644 #ifdef AFS_64BIT_ENV
5645 vol_size.dump_size = 0;
5647 FillInt64(vol_size.dump_size,0, 1);
5649 code = UV_GetSize(avolid, aserver, apart, fromdate, &vol_size);
5651 PrintDiagnostics("size", code);
5654 /* presumably the size info is now gathered in pntr */
5655 /* now we display it */
5657 fprintf(STDOUT, "dump_size: %llu\n", vol_size.dump_size);
5666 PrintDiagnostics(char *astring, afs_int32 acode)
5668 if (acode == EACCES) {
5670 "You are not authorized to perform the 'vos %s' command (%d)\n",
5673 fprintf(STDERR, "Error in vos %s command.\n", astring);
5674 PrintError("", acode);
5681 MyBeforeProc(struct cmd_syndesc *as, void *arock)
5683 register char *tcell;
5684 register afs_int32 code;
5685 register afs_int32 sauth;
5687 /* Initialize the ubik_client connection */
5688 rx_SetRxDeadTime(90);
5689 cstruct = (struct ubik_client *)0;
5693 if (as->parms[12].items) /* if -cell specified */
5694 tcell = as->parms[12].items->data;
5695 if (as->parms[14].items) /* -serverauth specified */
5697 if (as->parms[16].items) /* -crypt specified */
5700 vsu_ClientInit((as->parms[13].items != 0), confdir, tcell, sauth,
5701 &cstruct, UV_SetSecurity))) {
5702 fprintf(STDERR, "could not initialize VLDB library (code=%lu) \n",
5703 (unsigned long)code);
5707 if (as->parms[15].items) /* -verbose flag set */
5711 if (as->parms[17].items) /* -noresolve flag set */
5721 /* this sucks but it works for now.
5726 #include "AFS_component_version_number.c"
5729 main(int argc, char **argv)
5731 register afs_int32 code;
5733 register struct cmd_syndesc *ts;
5735 #ifdef AFS_AIX32_ENV
5737 * The following signal action for AIX is necessary so that in case of a
5738 * crash (i.e. core is generated) we can include the user's data section
5739 * in the core dump. Unfortunately, by default, only a partial core is
5740 * generated which, in many cases, isn't too useful.
5742 struct sigaction nsa;
5744 sigemptyset(&nsa.sa_mask);
5745 nsa.sa_handler = SIG_DFL;
5746 nsa.sa_flags = SA_FULLDUMP;
5747 sigaction(SIGSEGV, &nsa, NULL);
5750 confdir = AFSDIR_CLIENT_ETC_DIRPATH;
5752 cmd_SetBeforeProc(MyBeforeProc, NULL);
5754 ts = cmd_CreateSyntax("create", CreateVolume, NULL, "create a new volume");
5755 cmd_AddParm(ts, "-server", CMD_SINGLE, 0, "machine name");
5756 cmd_AddParm(ts, "-partition", CMD_SINGLE, 0, "partition name");
5757 cmd_AddParm(ts, "-name", CMD_SINGLE, 0, "volume name");
5758 cmd_AddParm(ts, "-maxquota", CMD_SINGLE, CMD_OPTIONAL,
5759 "initial quota (KB)");
5760 cmd_AddParm(ts, "-id", CMD_SINGLE, CMD_OPTIONAL, "volume ID");
5761 cmd_AddParm(ts, "-roid", CMD_SINGLE, CMD_OPTIONAL, "readonly volume ID");
5763 cmd_AddParm(ts, "-minquota", CMD_SINGLE, CMD_OPTIONAL, "");
5767 ts = cmd_CreateSyntax("remove", DeleteVolume, NULL, "delete a volume");
5768 cmd_AddParm(ts, "-server", CMD_SINGLE, CMD_OPTIONAL, "machine name");
5769 cmd_AddParm(ts, "-partition", CMD_SINGLE, CMD_OPTIONAL, "partition name");
5770 cmd_AddParm(ts, "-id", CMD_SINGLE, 0, "volume name or ID");
5774 ts = cmd_CreateSyntax("move", MoveVolume, NULL, "move a volume");
5775 cmd_AddParm(ts, "-id", CMD_SINGLE, 0, "volume name or ID");
5776 cmd_AddParm(ts, "-fromserver", CMD_SINGLE, 0, "machine name on source");
5777 cmd_AddParm(ts, "-frompartition", CMD_SINGLE, 0,
5778 "partition name on source");
5779 cmd_AddParm(ts, "-toserver", CMD_SINGLE, 0,
5780 "machine name on destination");
5781 cmd_AddParm(ts, "-topartition", CMD_SINGLE, 0,
5782 "partition name on destination");
5783 cmd_AddParm(ts, "-live", CMD_FLAG, CMD_OPTIONAL,
5784 "copy live volume without cloning");
5787 ts = cmd_CreateSyntax("copy", CopyVolume, NULL, "copy a volume");
5788 cmd_AddParm(ts, "-id", CMD_SINGLE, 0, "volume name or ID on source");
5789 cmd_AddParm(ts, "-fromserver", CMD_SINGLE, 0, "machine name on source");
5790 cmd_AddParm(ts, "-frompartition", CMD_SINGLE, 0,
5791 "partition name on source");
5792 cmd_AddParm(ts, "-toname", CMD_SINGLE, 0, "volume name on destination");
5793 cmd_AddParm(ts, "-toserver", CMD_SINGLE, 0,
5794 "machine name on destination");
5795 cmd_AddParm(ts, "-topartition", CMD_SINGLE, 0,
5796 "partition name on destination");
5797 cmd_AddParm(ts, "-offline", CMD_FLAG, CMD_OPTIONAL,
5798 "leave new volume offline");
5799 cmd_AddParm(ts, "-readonly", CMD_FLAG, CMD_OPTIONAL,
5800 "make new volume read-only");
5801 cmd_AddParm(ts, "-live", CMD_FLAG, CMD_OPTIONAL,
5802 "copy live volume without cloning");
5805 ts = cmd_CreateSyntax("shadow", ShadowVolume, NULL,
5806 "make or update a shadow volume");
5807 cmd_AddParm(ts, "-id", CMD_SINGLE, 0, "volume name or ID on source");
5808 cmd_AddParm(ts, "-fromserver", CMD_SINGLE, 0, "machine name on source");
5809 cmd_AddParm(ts, "-frompartition", CMD_SINGLE, 0,
5810 "partition name on source");
5811 cmd_AddParm(ts, "-toserver", CMD_SINGLE, 0,
5812 "machine name on destination");
5813 cmd_AddParm(ts, "-topartition", CMD_SINGLE, 0,
5814 "partition name on destination");
5815 cmd_AddParm(ts, "-toname", CMD_SINGLE, CMD_OPTIONAL,
5816 "volume name on destination");
5817 cmd_AddParm(ts, "-toid", CMD_SINGLE, CMD_OPTIONAL,
5818 "volume ID on destination");
5819 cmd_AddParm(ts, "-offline", CMD_FLAG, CMD_OPTIONAL,
5820 "leave shadow volume offline");
5821 cmd_AddParm(ts, "-readonly", CMD_FLAG, CMD_OPTIONAL,
5822 "make shadow volume read-only");
5823 cmd_AddParm(ts, "-live", CMD_FLAG, CMD_OPTIONAL,
5824 "copy live volume without cloning");
5825 cmd_AddParm(ts, "-incremental", CMD_FLAG, CMD_OPTIONAL,
5826 "do incremental update if target exists");
5829 ts = cmd_CreateSyntax("backup", BackupVolume, NULL,
5830 "make backup of a volume");
5831 cmd_AddParm(ts, "-id", CMD_SINGLE, 0, "volume name or ID");
5834 ts = cmd_CreateSyntax("clone", CloneVolume, NULL,
5835 "make clone of a volume");
5836 cmd_AddParm(ts, "-id", CMD_SINGLE, 0, "volume name or ID");
5837 cmd_AddParm(ts, "-server", CMD_SINGLE, CMD_OPTIONAL, "server");
5838 cmd_AddParm(ts, "-partition", CMD_SINGLE, CMD_OPTIONAL, "partition");
5839 cmd_AddParm(ts, "-toname", CMD_SINGLE, CMD_OPTIONAL,
5840 "volume name on destination");
5841 cmd_AddParm(ts, "-toid", CMD_SINGLE, CMD_OPTIONAL,
5842 "volume ID on destination");
5843 cmd_AddParm(ts, "-offline", CMD_FLAG, CMD_OPTIONAL,
5844 "leave clone volume offline");
5845 cmd_AddParm(ts, "-readonly", CMD_FLAG, CMD_OPTIONAL,
5846 "make clone volume read-only, not readwrite");
5849 ts = cmd_CreateSyntax("release", ReleaseVolume, NULL, "release a volume");
5850 cmd_AddParm(ts, "-id", CMD_SINGLE, 0, "volume name or ID");
5851 cmd_AddParm(ts, "-force", CMD_FLAG, CMD_OPTIONAL,
5852 "force a complete release");
5855 ts = cmd_CreateSyntax("dump", DumpVolumeCmd, NULL, "dump a volume");
5856 cmd_AddParm(ts, "-id", CMD_SINGLE, 0, "volume name or ID");
5857 cmd_AddParm(ts, "-time", CMD_SINGLE, CMD_OPTIONAL, "dump from time");
5858 cmd_AddParm(ts, "-file", CMD_SINGLE, CMD_OPTIONAL, "dump file");
5859 cmd_AddParm(ts, "-server", CMD_SINGLE, CMD_OPTIONAL, "server");
5860 cmd_AddParm(ts, "-partition", CMD_SINGLE, CMD_OPTIONAL, "partition");
5861 cmd_AddParm(ts, "-clone", CMD_FLAG, CMD_OPTIONAL,
5862 "dump a clone of the volume");
5863 cmd_AddParm(ts, "-omitdirs", CMD_FLAG, CMD_OPTIONAL,
5864 "omit unchanged directories from an incremental dump");
5867 ts = cmd_CreateSyntax("restore", RestoreVolumeCmd, NULL,
5868 "restore a volume");
5869 cmd_AddParm(ts, "-server", CMD_SINGLE, 0, "machine name");
5870 cmd_AddParm(ts, "-partition", CMD_SINGLE, 0, "partition name");
5871 cmd_AddParm(ts, "-name", CMD_SINGLE, 0, "name of volume to be restored");
5872 cmd_AddParm(ts, "-file", CMD_SINGLE, CMD_OPTIONAL, "dump file");
5873 cmd_AddParm(ts, "-id", CMD_SINGLE, CMD_OPTIONAL, "volume ID");
5874 cmd_AddParm(ts, "-overwrite", CMD_SINGLE, CMD_OPTIONAL,
5875 "abort | full | incremental");
5876 cmd_AddParm(ts, "-offline", CMD_FLAG, CMD_OPTIONAL,
5877 "leave restored volume offline");
5878 cmd_AddParm(ts, "-readonly", CMD_FLAG, CMD_OPTIONAL,
5879 "make restored volume read-only");
5880 cmd_AddParm(ts, "-creation", CMD_SINGLE, CMD_OPTIONAL,
5881 "dump | keep | new");
5882 cmd_AddParm(ts, "-lastupdate", CMD_SINGLE, CMD_OPTIONAL,
5883 "dump | keep | new");
5884 cmd_AddParm(ts, "-nodelete", CMD_FLAG, CMD_OPTIONAL,
5885 "do not delete old site when restoring to a new site");
5888 ts = cmd_CreateSyntax("unlock", LockReleaseCmd, NULL,
5889 "release lock on VLDB entry for a volume");
5890 cmd_AddParm(ts, "-id", CMD_SINGLE, 0, "volume name or ID");
5893 ts = cmd_CreateSyntax("changeloc", ChangeLocation, NULL,
5894 "change an RW volume's location in the VLDB");
5895 cmd_AddParm(ts, "-server", CMD_SINGLE, 0,
5896 "machine name for new location");
5897 cmd_AddParm(ts, "-partition", CMD_SINGLE, 0,
5898 "partition name for new location");
5899 cmd_AddParm(ts, "-id", CMD_SINGLE, 0, "volume name or ID");
5902 ts = cmd_CreateSyntax("addsite", AddSite, NULL, "add a replication site");
5903 cmd_AddParm(ts, "-server", CMD_SINGLE, 0, "machine name for new site");
5904 cmd_AddParm(ts, "-partition", CMD_SINGLE, 0,
5905 "partition name for new site");
5906 cmd_AddParm(ts, "-id", CMD_SINGLE, 0, "volume name or ID");
5907 cmd_AddParm(ts, "-roid", CMD_SINGLE, CMD_OPTIONAL, "volume name or ID for RO");
5908 cmd_AddParm(ts, "-valid", CMD_FLAG, CMD_OPTIONAL, "publish as an up-to-date site in VLDB");
5911 ts = cmd_CreateSyntax("remsite", RemoveSite, NULL,
5912 "remove a replication site");
5913 cmd_AddParm(ts, "-server", CMD_SINGLE, 0, "machine name");
5914 cmd_AddParm(ts, "-partition", CMD_SINGLE, 0, "partition name");
5915 cmd_AddParm(ts, "-id", CMD_SINGLE, 0, "volume name or ID");
5918 ts = cmd_CreateSyntax("listpart", ListPartitions, NULL, "list partitions");
5919 cmd_AddParm(ts, "-server", CMD_SINGLE, 0, "machine name");
5922 ts = cmd_CreateSyntax("listvol", ListVolumes, NULL,
5923 "list volumes on server (bypass VLDB)");
5924 cmd_AddParm(ts, "-server", CMD_SINGLE, 0, "machine name");
5925 cmd_AddParm(ts, "-partition", CMD_SINGLE, CMD_OPTIONAL, "partition name");
5926 cmd_AddParm(ts, "-fast", CMD_FLAG, CMD_OPTIONAL, "minimal listing");
5927 cmd_AddParm(ts, "-long", CMD_FLAG, CMD_OPTIONAL,
5928 "list all normal volume fields");
5929 cmd_AddParm(ts, "-quiet", CMD_FLAG, CMD_OPTIONAL,
5930 "generate minimal information");
5931 cmd_AddParm(ts, "-extended", CMD_FLAG, CMD_OPTIONAL,
5932 "list extended volume fields");
5933 #ifdef FULL_LISTVOL_SWITCH
5934 cmd_AddParm(ts, "-format", CMD_FLAG, CMD_OPTIONAL,
5935 "machine readable format");
5936 #endif /* FULL_LISTVOL_SWITCH */
5939 ts = cmd_CreateSyntax("syncvldb", SyncVldb, NULL,
5940 "synchronize VLDB with server");
5941 cmd_AddParm(ts, "-server", CMD_SINGLE, CMD_OPTIONAL, "machine name");
5942 cmd_AddParm(ts, "-partition", CMD_SINGLE, CMD_OPTIONAL, "partition name");
5943 cmd_AddParm(ts, "-volume", CMD_SINGLE, CMD_OPTIONAL, "volume name or ID");
5944 cmd_AddParm(ts, "-dryrun", CMD_FLAG, CMD_OPTIONAL, "report without updating");
5947 ts = cmd_CreateSyntax("syncserv", SyncServer, NULL,
5948 "synchronize server with VLDB");
5949 cmd_AddParm(ts, "-server", CMD_SINGLE, 0, "machine name");
5950 cmd_AddParm(ts, "-partition", CMD_SINGLE, CMD_OPTIONAL, "partition name");
5951 cmd_AddParm(ts, "-dryrun", CMD_FLAG, CMD_OPTIONAL, "report without updating");
5954 ts = cmd_CreateSyntax("examine", ExamineVolume, NULL,
5955 "everything about the volume");
5956 cmd_AddParm(ts, "-id", CMD_SINGLE, 0, "volume name or ID");
5957 cmd_AddParm(ts, "-extended", CMD_FLAG, CMD_OPTIONAL,
5958 "list extended volume fields");
5959 #ifdef FULL_LISTVOL_SWITCH
5960 cmd_AddParm(ts, "-format", CMD_FLAG, CMD_OPTIONAL,
5961 "machine readable format");
5962 #endif /* FULL_LISTVOL_SWITCH */
5964 cmd_CreateAlias(ts, "volinfo");
5966 ts = cmd_CreateSyntax("setfields", SetFields, NULL,
5967 "change volume info fields");
5968 cmd_AddParm(ts, "-id", CMD_SINGLE, 0, "volume name or ID");
5969 cmd_AddParm(ts, "-maxquota", CMD_SINGLE, CMD_OPTIONAL, "quota (KB)");
5970 cmd_AddParm(ts, "-clearuse", CMD_FLAG, CMD_OPTIONAL, "clear dayUse");
5971 cmd_AddParm(ts, "-clearVolUpCounter", CMD_FLAG, CMD_OPTIONAL, "clear volUpdateCounter");
5974 ts = cmd_CreateSyntax("offline", volOffline, NULL, "force the volume status to offline");
5975 cmd_AddParm(ts, "-server", CMD_SINGLE, 0, "server name");
5976 cmd_AddParm(ts, "-partition", CMD_SINGLE, 0, "partition name");
5977 cmd_AddParm(ts, "-id", CMD_SINGLE, 0, "volume name or ID");
5978 cmd_AddParm(ts, "-sleep", CMD_SINGLE, CMD_OPTIONAL, "seconds to sleep");
5979 cmd_AddParm(ts, "-busy", CMD_FLAG, CMD_OPTIONAL, "busy volume");
5982 ts = cmd_CreateSyntax("online", volOnline, NULL, "force the volume status to online");
5983 cmd_AddParm(ts, "-server", CMD_SINGLE, 0, "server name");
5984 cmd_AddParm(ts, "-partition", CMD_SINGLE, 0, "partition name");
5985 cmd_AddParm(ts, "-id", CMD_SINGLE, 0, "volume name or ID");
5988 ts = cmd_CreateSyntax("zap", VolumeZap, NULL,
5989 "delete the volume, don't bother with VLDB");
5990 cmd_AddParm(ts, "-server", CMD_SINGLE, 0, "machine name");
5991 cmd_AddParm(ts, "-partition", CMD_SINGLE, 0, "partition name");
5992 cmd_AddParm(ts, "-id", CMD_SINGLE, 0, "volume ID");
5993 cmd_AddParm(ts, "-force", CMD_FLAG, CMD_OPTIONAL,
5994 "force deletion of bad volumes");
5995 cmd_AddParm(ts, "-backup", CMD_FLAG, CMD_OPTIONAL,
5996 "also delete backup volume if one is found");
5999 ts = cmd_CreateSyntax("status", VolserStatus, NULL,
6000 "report on volser status");
6001 cmd_AddParm(ts, "-server", CMD_SINGLE, 0, "machine name");
6004 ts = cmd_CreateSyntax("rename", RenameVolume, NULL, "rename a volume");
6005 cmd_AddParm(ts, "-oldname", CMD_SINGLE, 0, "old volume name ");
6006 cmd_AddParm(ts, "-newname", CMD_SINGLE, 0, "new volume name ");
6009 ts = cmd_CreateSyntax("listvldb", ListVLDB, NULL,
6010 "list volumes in the VLDB");
6011 cmd_AddParm(ts, "-name", CMD_SINGLE, CMD_OPTIONAL, "volume name or ID");
6012 cmd_AddParm(ts, "-server", CMD_SINGLE, CMD_OPTIONAL, "machine name");
6013 cmd_AddParm(ts, "-partition", CMD_SINGLE, CMD_OPTIONAL, "partition name");
6014 cmd_AddParm(ts, "-locked", CMD_FLAG, CMD_OPTIONAL, "locked volumes only");
6015 cmd_AddParm(ts, "-quiet", CMD_FLAG, CMD_OPTIONAL,
6016 "generate minimal information");
6017 cmd_AddParm(ts, "-nosort", CMD_FLAG, CMD_OPTIONAL,
6018 "do not alphabetically sort the volume names");
6021 ts = cmd_CreateSyntax("backupsys", BackSys, NULL, "en masse backups");
6022 cmd_AddParm(ts, "-prefix", CMD_LIST, CMD_OPTIONAL,
6023 "common prefix on volume(s)");
6024 cmd_AddParm(ts, "-server", CMD_SINGLE, CMD_OPTIONAL, "machine name");
6025 cmd_AddParm(ts, "-partition", CMD_SINGLE, CMD_OPTIONAL, "partition name");
6026 cmd_AddParm(ts, "-exclude", CMD_FLAG, CMD_OPTIONAL,
6027 "exclude common prefix volumes");
6028 cmd_AddParm(ts, "-xprefix", CMD_LIST, CMD_OPTIONAL,
6029 "negative prefix on volume(s)");
6030 cmd_AddParm(ts, "-dryrun", CMD_FLAG, CMD_OPTIONAL, "no action");
6033 ts = cmd_CreateSyntax("delentry", DeleteEntry, NULL,
6034 "delete VLDB entry for a volume");
6035 cmd_AddParm(ts, "-id", CMD_LIST, CMD_OPTIONAL, "volume name or ID");
6036 cmd_AddParm(ts, "-prefix", CMD_SINGLE, CMD_OPTIONAL,
6037 "prefix of the volume whose VLDB entry is to be deleted");
6038 cmd_AddParm(ts, "-server", CMD_SINGLE, CMD_OPTIONAL, "machine name");
6039 cmd_AddParm(ts, "-partition", CMD_SINGLE, CMD_OPTIONAL, "partition name");
6040 cmd_AddParm(ts, "-noexecute", CMD_FLAG, CMD_OPTIONAL,
6044 ts = cmd_CreateSyntax("partinfo", PartitionInfo, NULL,
6045 "list partition information");
6046 cmd_AddParm(ts, "-server", CMD_SINGLE, 0, "machine name");
6047 cmd_AddParm(ts, "-partition", CMD_SINGLE, CMD_OPTIONAL, "partition name");
6048 cmd_AddParm(ts, "-summary", CMD_FLAG, CMD_OPTIONAL,
6049 "print storage summary");
6052 ts = cmd_CreateSyntax("unlockvldb", UnlockVLDB, NULL,
6053 "unlock all the locked entries in the VLDB");
6054 cmd_AddParm(ts, "-server", CMD_SINGLE, CMD_OPTIONAL, "machine name");
6055 cmd_AddParm(ts, "-partition", CMD_SINGLE, CMD_OPTIONAL, "partition name");
6058 ts = cmd_CreateSyntax("lock", LockEntry, NULL,
6059 "lock VLDB entry for a volume");
6060 cmd_AddParm(ts, "-id", CMD_SINGLE, 0, "volume name or ID");
6063 ts = cmd_CreateSyntax("changeaddr", ChangeAddr, NULL,
6064 "change the IP address of a file server");
6065 cmd_AddParm(ts, "-oldaddr", CMD_SINGLE, 0, "original IP address");
6066 cmd_AddParm(ts, "-newaddr", CMD_SINGLE, CMD_OPTIONAL, "new IP address");
6067 cmd_AddParm(ts, "-remove", CMD_FLAG, CMD_OPTIONAL,
6068 "remove the IP address from the VLDB");
6071 ts = cmd_CreateSyntax("listaddrs", ListAddrs, NULL,
6072 "list the IP address of all file servers registered in the VLDB");
6073 cmd_AddParm(ts, "-uuid", CMD_SINGLE, CMD_OPTIONAL, "uuid of server");
6074 cmd_AddParm(ts, "-host", CMD_SINGLE, CMD_OPTIONAL, "address of host");
6075 cmd_AddParm(ts, "-printuuid", CMD_FLAG, CMD_OPTIONAL,
6076 "print uuid of hosts");
6079 ts = cmd_CreateSyntax("convertROtoRW", ConvertRO, NULL,
6080 "convert a RO volume into a RW volume (after loss of old RW volume)");
6081 cmd_AddParm(ts, "-server", CMD_SINGLE, 0, "machine name");
6082 cmd_AddParm(ts, "-partition", CMD_SINGLE, 0, "partition name");
6083 cmd_AddParm(ts, "-id", CMD_SINGLE, 0, "volume name or ID");
6084 cmd_AddParm(ts, "-force", CMD_FLAG, CMD_OPTIONAL, "don't ask");
6087 ts = cmd_CreateSyntax("size", Sizes, NULL,
6088 "obtain various sizes of the volume.");
6089 cmd_AddParm(ts, "-id", CMD_SINGLE, 0, "volume name or ID");
6090 cmd_AddParm(ts, "-partition", CMD_SINGLE, CMD_OPTIONAL, "partition name");
6091 cmd_AddParm(ts, "-server", CMD_SINGLE, CMD_OPTIONAL, "machine name");
6092 cmd_AddParm(ts, "-dump", CMD_FLAG, CMD_OPTIONAL,
6093 "Obtain the size of the dump");
6094 cmd_AddParm(ts, "-time", CMD_SINGLE, CMD_OPTIONAL, "dump from time");
6097 code = cmd_Dispatch(argc, argv);
6099 /* Shut down the ubik_client and rx connections */
6101 (void)ubik_ClientDestroy(cstruct);
6107 exit((code ? -1 : 0));