2 * Copyright 2000, International Business Machines Corporation and others.
5 * This software has been released under the terms of the IBM Public
6 * License. For details, see the LICENSE file in the top-level source
7 * directory or online at http://www.openafs.org/dl/license10.html
10 #include <afsconfig.h>
11 #include <afs/param.h>
16 #include <sys/types.h>
25 #include <netinet/in.h>
26 #include <arpa/inet.h>
30 #include <sys/statfs.h>
46 #include <rx/rx_globals.h>
48 #include <afs/vlserver.h>
50 #include <afs/cellconfig.h>
52 #include <afs/afsutil.h>
54 #include <afs/afsint.h>
64 #include "volser_prototypes.h"
66 #ifdef HAVE_POSIX_REGEX
80 #define COMMONPARMS cmd_Seek(ts, 12);\
81 cmd_AddParm(ts, "-cell", CMD_SINGLE, CMD_OPTIONAL, "cell name");\
82 cmd_AddParm(ts, "-noauth", CMD_FLAG, CMD_OPTIONAL, "don't authenticate");\
83 cmd_AddParm(ts, "-localauth",CMD_FLAG,CMD_OPTIONAL,"use server tickets");\
84 cmd_AddParm(ts, "-verbose", CMD_FLAG, CMD_OPTIONAL, "verbose");\
85 cmd_AddParm(ts, "-encrypt", CMD_FLAG, CMD_OPTIONAL, "encrypt commands");\
87 #define ERROR_EXIT(code) {error=(code); goto error_exit;}
91 struct rx_connection *tconn;
93 extern struct ubik_client *cstruct;
96 static struct tqHead busyHead, notokHead;
99 qInit(struct tqHead *ahead)
101 memset((char *)ahead, 0, sizeof(struct tqHead));
107 qPut(struct tqHead *ahead, afs_int32 volid)
111 elem = (struct tqElem *)malloc(sizeof(struct tqElem));
112 elem->next = ahead->next;
120 qGet(struct tqHead *ahead, afs_int32 *volid)
124 if (ahead->count <= 0)
126 *volid = ahead->next->volid;
128 ahead->next = tmp->next;
134 /* returns 1 if <filename> exists else 0 */
136 FileExists(char *filename)
142 code = usd_Open(filename, USD_OPEN_RDONLY, 0, &ufd);
146 code = USD_IOCTL(ufd, USD_IOCTL_GETSIZE, &size);
154 /* returns 1 if <name> doesnot end in .readonly or .backup, else 0 */
156 VolNameOK(char *name)
161 total = strlen(name);
162 if (!strcmp(&name[total - 9], ".readonly")) {
164 } else if (!strcmp(&name[total - 7], ".backup")) {
171 /* return 1 if name is a number else 0 */
173 IsNumeric(char *name)
181 for (i = 0; i < len; i++) {
182 if (*ptr < '0' || *ptr > '9') {
194 * Parse a server name/address and return the address in HOST BYTE order
197 GetServer(char *aname)
199 register struct hostent *th;
202 register afs_int32 code;
203 char hostname[MAXHOSTCHARS];
205 code = sscanf(aname, "%d.%d.%d.%d", &b1, &b2, &b3, &b4);
207 addr = (b1 << 24) | (b2 << 16) | (b3 << 8) | b4;
208 addr = ntohl(addr); /* convert to host order */
210 th = gethostbyname(aname);
213 memcpy(&addr, th->h_addr, sizeof(addr));
216 if (addr == htonl(0x7f000001)) { /* local host */
217 code = gethostname(hostname, MAXHOSTCHARS);
220 th = gethostbyname(hostname); /* returns host byte order */
223 memcpy(&addr, th->h_addr, sizeof(addr));
230 GetVolumeType(char *aname)
233 if (!strcmp(aname, "ro"))
235 else if (!strcmp(aname, "rw"))
237 else if (!strcmp(aname, "bk"))
244 IsPartValid(afs_int32 partId, afs_int32 server, afs_int32 *code)
246 struct partList dummyPartList;
252 *code = UV_ListPartitions(server, &dummyPartList, &cnt);
255 for (i = 0; i < cnt; i++) {
256 if (dummyPartList.partFlags[i] & PARTVALID)
257 if (dummyPartList.partId[i] == partId)
265 /*sends the contents of file associated with <fd> and <blksize> to Rx Stream
266 * associated with <call> */
268 SendFile(usd_handle_t ufd, register struct rx_call *call, long blksize)
270 char *buffer = (char *)0;
275 buffer = (char *)malloc(blksize);
277 fprintf(STDERR, "malloc failed\n");
281 while (!error && !done) {
282 #ifndef AFS_NT40_ENV /* NT csn't select on non-socket fd's */
285 FD_SET((int)(ufd->handle), &in);
286 /* don't timeout if read blocks */
287 IOMGR_Select(((int)(ufd->handle)) + 1, &in, 0, 0, 0);
289 error = USD_READ(ufd, buffer, blksize, &nbytes);
291 fprintf(STDERR, "File system read failed\n");
298 if (rx_Write(call, buffer, nbytes) != nbytes) {
308 /* function invoked by UV_RestoreVolume, reads the data from rx_trx_stream and
309 * writes it out to the volume. */
311 WriteData(struct rx_call *call, char *rock)
316 afs_int32 error, code;
322 if (!filename || !*filename) {
323 usd_StandardInput(&ufd);
327 code = usd_Open(filename, USD_OPEN_RDONLY, 0, &ufd);
330 code = USD_IOCTL(ufd, USD_IOCTL_GETBLKSIZE, &blksize);
333 fprintf(STDERR, "Could not access file '%s'\n", filename);
338 code = SendFile(ufd, call, blksize);
345 code = USD_CLOSE(ufd);
347 fprintf(STDERR, "Could not close dump file %s\n",
348 (filename && *filename) ? filename : "STDOUT");
356 /* Receive data from <call> stream into file associated
357 * with <fd> <blksize>
360 ReceiveFile(usd_handle_t ufd, struct rx_call *call, long blksize)
364 afs_uint32 bytesleft, w;
367 buffer = (char *)malloc(blksize);
369 fprintf(STDERR, "memory allocation failed\n");
373 while ((bytesread = rx_Read(call, buffer, blksize)) > 0) {
374 for (bytesleft = bytesread; bytesleft; bytesleft -= w) {
375 #ifndef AFS_NT40_ENV /* NT csn't select on non-socket fd's */
378 FD_SET((int)(ufd->handle), &out);
379 /* don't timeout if write blocks */
380 IOMGR_Select(((int)(ufd->handle)) + 1, 0, &out, 0, 0);
383 USD_WRITE(ufd, &buffer[bytesread - bytesleft], bytesleft, &w);
385 fprintf(STDERR, "File system write failed\n");
398 DumpFunction(struct rx_call *call, char *filename)
400 usd_handle_t ufd; /* default is to stdout */
401 afs_int32 error = 0, code;
406 /* Open the output file */
407 if (!filename || !*filename) {
408 usd_StandardOutput(&ufd);
413 usd_Open(filename, USD_OPEN_CREATE | USD_OPEN_RDWR, 0666, &ufd);
417 code = USD_IOCTL(ufd, USD_IOCTL_SETSIZE, &size);
420 code = USD_IOCTL(ufd, USD_IOCTL_GETBLKSIZE, &blksize);
423 fprintf(STDERR, "Could not create file '%s'\n", filename);
424 ERROR_EXIT(VOLSERBADOP);
428 code = ReceiveFile(ufd, call, blksize);
433 /* Close the output file */
435 code = USD_CLOSE(ufd);
437 fprintf(STDERR, "Could not close dump file %s\n",
438 (filename && *filename) ? filename : "STDIN");
448 DisplayFormat(pntr, server, part, totalOK, totalNotOK, totalBusy, fast,
451 afs_int32 server, part;
452 int *totalOK, *totalNotOK, *totalBusy;
453 int fast, longlist, disp;
458 fprintf(STDOUT, "%-10lu\n", (unsigned long)pntr->volid);
459 } else if (longlist) {
460 if (pntr->status == VOK) {
461 fprintf(STDOUT, "%-32s ", pntr->name);
462 fprintf(STDOUT, "%10lu ", (unsigned long)pntr->volid);
464 fprintf(STDOUT, "RW ");
466 fprintf(STDOUT, "RO ");
468 fprintf(STDOUT, "BK ");
469 fprintf(STDOUT, "%10d K ", pntr->size);
470 if (pntr->inUse == 1) {
471 fprintf(STDOUT, "On-line");
474 fprintf(STDOUT, "Off-line");
477 if (pntr->needsSalvaged == 1)
478 fprintf(STDOUT, "**needs salvage**");
479 fprintf(STDOUT, "\n");
480 MapPartIdIntoName(part, pname);
481 fprintf(STDOUT, " %s %s \n", hostutil_GetNameByINet(server),
483 fprintf(STDOUT, " RWrite %10lu ROnly %10lu Backup %10lu \n",
484 (unsigned long)pntr->parentID,
485 (unsigned long)pntr->cloneID,
486 (unsigned long)pntr->backupID);
487 fprintf(STDOUT, " MaxQuota %10d K \n", pntr->maxquota);
488 fprintf(STDOUT, " Creation %s",
489 ctime((time_t *) & pntr->creationDate));
490 #ifdef FULL_LISTVOL_SWITCH
491 fprintf(STDOUT, " Copy %s",
492 ctime((time_t *) & pntr->copyDate));
493 if (!pntr->backupDate)
494 fprintf(STDOUT, " Backup Never\n");
496 fprintf(STDOUT, " Backup %s",
497 ctime((time_t *) & pntr->backupDate));
498 if (pntr->accessDate)
499 fprintf(STDOUT, " Last Access %s",
500 ctime((time_t *) & pntr->accessDate));
502 if (pntr->updateDate < pntr->creationDate)
503 fprintf(STDOUT, " Last Update %s",
504 ctime((time_t *) & pntr->creationDate));
506 fprintf(STDOUT, " Last Update %s",
507 ctime((time_t *) & pntr->updateDate));
509 " %d accesses in the past day (i.e., vnode references)\n",
511 } else if (pntr->status == VBUSY) {
513 qPut(&busyHead, pntr->volid);
515 fprintf(STDOUT, "**** Volume %lu is busy ****\n",
516 (unsigned long)pntr->volid);
519 qPut(¬okHead, pntr->volid);
521 fprintf(STDOUT, "**** Could not attach volume %lu ****\n",
522 (unsigned long)pntr->volid);
524 fprintf(STDOUT, "\n");
525 } else { /* default listing */
526 if (pntr->status == VOK) {
527 fprintf(STDOUT, "%-32s ", pntr->name);
528 fprintf(STDOUT, "%10lu ", (unsigned long)pntr->volid);
530 fprintf(STDOUT, "RW ");
532 fprintf(STDOUT, "RO ");
534 fprintf(STDOUT, "BK ");
535 fprintf(STDOUT, "%10d K ", pntr->size);
536 if (pntr->inUse == 1) {
537 fprintf(STDOUT, "On-line");
540 fprintf(STDOUT, "Off-line");
543 if (pntr->needsSalvaged == 1)
544 fprintf(STDOUT, "**needs salvage**");
545 fprintf(STDOUT, "\n");
546 } else if (pntr->status == VBUSY) {
548 qPut(&busyHead, pntr->volid);
550 fprintf(STDOUT, "**** Volume %lu is busy ****\n",
551 (unsigned long)pntr->volid);
554 qPut(¬okHead, pntr->volid);
556 fprintf(STDOUT, "**** Could not attach volume %lu ****\n",
557 (unsigned long)pntr->volid);
562 /*------------------------------------------------------------------------
563 * PRIVATE XDisplayFormat
566 * Display the contents of one extended volume info structure.
569 * a_xInfoP : Ptr to extended volume info struct to print.
570 * a_servID : Server ID to print.
571 * a_partID : Partition ID to print.
572 * a_totalOKP : Ptr to total-OK counter.
573 * a_totalNotOKP : Ptr to total-screwed counter.
574 * a_totalBusyP : Ptr to total-busy counter.
575 * a_fast : Fast listing?
576 * a_int32 : Int32 listing?
577 * a_showProblems : Show volume problems?
583 * Nothing interesting.
587 *------------------------------------------------------------------------*/
590 XDisplayFormat(a_xInfoP, a_servID, a_partID, a_totalOKP, a_totalNotOKP,
591 a_totalBusyP, a_fast, a_int32, a_showProblems)
592 volintXInfo *a_xInfoP;
602 { /*XDisplayFormat */
610 fprintf(STDOUT, "%-10lu\n", (unsigned long)a_xInfoP->volid);
611 } else if (a_int32) {
613 * Fully-detailed listing.
615 if (a_xInfoP->status == VOK) {
617 * Volume's status is OK - all the fields are valid.
619 fprintf(STDOUT, "%-32s ", a_xInfoP->name);
620 fprintf(STDOUT, "%10lu ", (unsigned long)a_xInfoP->volid);
621 if (a_xInfoP->type == 0)
622 fprintf(STDOUT, "RW ");
623 if (a_xInfoP->type == 1)
624 fprintf(STDOUT, "RO ");
625 if (a_xInfoP->type == 2)
626 fprintf(STDOUT, "BK ");
627 fprintf(STDOUT, "%10d K used ", a_xInfoP->size);
628 fprintf(STDOUT, "%d files ", a_xInfoP->filecount);
629 if (a_xInfoP->inUse == 1) {
630 fprintf(STDOUT, "On-line");
633 fprintf(STDOUT, "Off-line");
636 fprintf(STDOUT, "\n");
637 MapPartIdIntoName(a_partID, pname);
638 fprintf(STDOUT, " %s %s \n", hostutil_GetNameByINet(a_servID),
640 fprintf(STDOUT, " RWrite %10lu ROnly %10lu Backup %10lu \n",
641 (unsigned long)a_xInfoP->parentID,
642 (unsigned long)a_xInfoP->cloneID,
643 (unsigned long)a_xInfoP->backupID);
644 fprintf(STDOUT, " MaxQuota %10d K \n", a_xInfoP->maxquota);
645 fprintf(STDOUT, " Creation %s",
646 ctime((time_t *) & a_xInfoP->creationDate));
647 #ifdef FULL_LISTVOL_SWITCH
648 fprintf(STDOUT, " Copy %s",
649 ctime((time_t *) & a_xInfoP->copyDate));
650 if (!a_xInfoP->backupDate)
651 fprintf(STDOUT, " Backup Never\n");
653 fprintf(STDOUT, " Backup %s",
654 ctime((time_t *) & a_xInfoP->backupDate));
655 if (a_xInfoP->accessDate)
656 fprintf(STDOUT, " Last Access %s",
657 ctime((time_t *) & a_xInfoP->accessDate));
659 if (a_xInfoP->updateDate < a_xInfoP->creationDate)
660 fprintf(STDOUT, " Last Update %s",
661 ctime((time_t *) & a_xInfoP->creationDate));
663 fprintf(STDOUT, " Last Update %s",
664 ctime((time_t *) & a_xInfoP->updateDate));
666 " %d accesses in the past day (i.e., vnode references)\n",
670 * Print all the read/write and authorship stats.
672 fprintf(STDOUT, "\n Raw Read/Write Stats\n");
674 " |-------------------------------------------|\n");
676 " | Same Network | Diff Network |\n");
678 " |----------|----------|----------|----------|\n");
680 " | Total | Auth | Total | Auth |\n");
682 " |----------|----------|----------|----------|\n");
683 fprintf(STDOUT, "Reads | %8d | %8d | %8d | %8d |\n",
684 a_xInfoP->stat_reads[VOLINT_STATS_SAME_NET],
685 a_xInfoP->stat_reads[VOLINT_STATS_SAME_NET_AUTH],
686 a_xInfoP->stat_reads[VOLINT_STATS_DIFF_NET],
687 a_xInfoP->stat_reads[VOLINT_STATS_DIFF_NET_AUTH]);
688 fprintf(STDOUT, "Writes | %8d | %8d | %8d | %8d |\n",
689 a_xInfoP->stat_writes[VOLINT_STATS_SAME_NET],
690 a_xInfoP->stat_writes[VOLINT_STATS_SAME_NET_AUTH],
691 a_xInfoP->stat_writes[VOLINT_STATS_DIFF_NET],
692 a_xInfoP->stat_writes[VOLINT_STATS_DIFF_NET_AUTH]);
694 " |-------------------------------------------|\n\n");
697 " Writes Affecting Authorship\n");
699 " |-------------------------------------------|\n");
701 " | File Authorship | Directory Authorship|\n");
703 " |----------|----------|----------|----------|\n");
705 " | Same | Diff | Same | Diff |\n");
707 " |----------|----------|----------|----------|\n");
708 fprintf(STDOUT, "0-60 sec | %8d | %8d | %8d | %8d |\n",
709 a_xInfoP->stat_fileSameAuthor[VOLINT_STATS_TIME_IDX_0],
710 a_xInfoP->stat_fileDiffAuthor[VOLINT_STATS_TIME_IDX_0],
711 a_xInfoP->stat_dirSameAuthor[VOLINT_STATS_TIME_IDX_0],
712 a_xInfoP->stat_dirDiffAuthor[VOLINT_STATS_TIME_IDX_0]);
713 fprintf(STDOUT, "1-10 min | %8d | %8d | %8d | %8d |\n",
714 a_xInfoP->stat_fileSameAuthor[VOLINT_STATS_TIME_IDX_1],
715 a_xInfoP->stat_fileDiffAuthor[VOLINT_STATS_TIME_IDX_1],
716 a_xInfoP->stat_dirSameAuthor[VOLINT_STATS_TIME_IDX_1],
717 a_xInfoP->stat_dirDiffAuthor[VOLINT_STATS_TIME_IDX_1]);
718 fprintf(STDOUT, "10min-1hr | %8d | %8d | %8d | %8d |\n",
719 a_xInfoP->stat_fileSameAuthor[VOLINT_STATS_TIME_IDX_2],
720 a_xInfoP->stat_fileDiffAuthor[VOLINT_STATS_TIME_IDX_2],
721 a_xInfoP->stat_dirSameAuthor[VOLINT_STATS_TIME_IDX_2],
722 a_xInfoP->stat_dirDiffAuthor[VOLINT_STATS_TIME_IDX_2]);
723 fprintf(STDOUT, "1hr-1day | %8d | %8d | %8d | %8d |\n",
724 a_xInfoP->stat_fileSameAuthor[VOLINT_STATS_TIME_IDX_3],
725 a_xInfoP->stat_fileDiffAuthor[VOLINT_STATS_TIME_IDX_3],
726 a_xInfoP->stat_dirSameAuthor[VOLINT_STATS_TIME_IDX_3],
727 a_xInfoP->stat_dirDiffAuthor[VOLINT_STATS_TIME_IDX_3]);
728 fprintf(STDOUT, "1day-1wk | %8d | %8d | %8d | %8d |\n",
729 a_xInfoP->stat_fileSameAuthor[VOLINT_STATS_TIME_IDX_4],
730 a_xInfoP->stat_fileDiffAuthor[VOLINT_STATS_TIME_IDX_4],
731 a_xInfoP->stat_dirSameAuthor[VOLINT_STATS_TIME_IDX_4],
732 a_xInfoP->stat_dirDiffAuthor[VOLINT_STATS_TIME_IDX_4]);
733 fprintf(STDOUT, "> 1wk | %8d | %8d | %8d | %8d |\n",
734 a_xInfoP->stat_fileSameAuthor[VOLINT_STATS_TIME_IDX_5],
735 a_xInfoP->stat_fileDiffAuthor[VOLINT_STATS_TIME_IDX_5],
736 a_xInfoP->stat_dirSameAuthor[VOLINT_STATS_TIME_IDX_5],
737 a_xInfoP->stat_dirDiffAuthor[VOLINT_STATS_TIME_IDX_5]);
739 " |-------------------------------------------|\n");
740 } /*Volume status OK */
741 else if (a_xInfoP->status == VBUSY) {
743 qPut(&busyHead, a_xInfoP->volid);
745 fprintf(STDOUT, "**** Volume %lu is busy ****\n",
746 (unsigned long)a_xInfoP->volid);
750 qPut(¬okHead, a_xInfoP->volid);
752 fprintf(STDOUT, "**** Could not attach volume %lu ****\n",
753 (unsigned long)a_xInfoP->volid);
754 } /*Screwed volume */
755 fprintf(STDOUT, "\n");
761 if (a_xInfoP->status == VOK) {
762 fprintf(STDOUT, "%-32s ", a_xInfoP->name);
763 fprintf(STDOUT, "%10lu ", (unsigned long)a_xInfoP->volid);
764 if (a_xInfoP->type == 0)
765 fprintf(STDOUT, "RW ");
766 if (a_xInfoP->type == 1)
767 fprintf(STDOUT, "RO ");
768 if (a_xInfoP->type == 2)
769 fprintf(STDOUT, "BK ");
770 fprintf(STDOUT, "%10d K ", a_xInfoP->size);
771 if (a_xInfoP->inUse == 1) {
772 fprintf(STDOUT, "On-line");
775 fprintf(STDOUT, "Off-line");
778 fprintf(STDOUT, "\n");
780 else if (a_xInfoP->status == VBUSY) {
782 qPut(&busyHead, a_xInfoP->volid);
784 fprintf(STDOUT, "**** Volume %lu is busy ****\n",
785 (unsigned long)a_xInfoP->volid);
789 qPut(¬okHead, a_xInfoP->volid);
791 fprintf(STDOUT, "**** Could not attach volume %lu ****\n",
792 (unsigned long)a_xInfoP->volid);
793 } /*Screwed volume */
794 } /*Default listing */
795 } /*XDisplayFormat */
797 #ifdef FULL_LISTVOL_SWITCH
799 DisplayFormat2(server, partition, pntr)
800 long server, partition;
803 static long server_cache = -1, partition_cache = -1;
804 static char hostname[256], address[32], pname[16];
806 if (server != server_cache) {
810 strcpy(hostname, hostutil_GetNameByINet(server));
811 strcpy(address, inet_ntoa(s));
812 server_cache = server;
814 if (partition != partition_cache) {
815 MapPartIdIntoName(partition, pname);
816 partition_cache = partition;
820 fprintf(STDOUT, "name\t\t%s\n", pntr->name);
821 fprintf(STDOUT, "id\t\t%lu\n", pntr->volid);
822 fprintf(STDOUT, "serv\t\t%s\t%s\n", address, hostname);
823 fprintf(STDOUT, "part\t\t%s\n", pname);
824 switch (pntr->status) {
826 fprintf(STDOUT, "status\t\tOK\n");
829 fprintf(STDOUT, "status\t\tBUSY\n");
832 fprintf(STDOUT, "status\t\tUNATTACHABLE\n");
835 fprintf(STDOUT, "backupID\t%lu\n", pntr->backupID);
836 fprintf(STDOUT, "parentID\t%lu\n", pntr->parentID);
837 fprintf(STDOUT, "cloneID\t\t%lu\n", pntr->cloneID);
838 fprintf(STDOUT, "inUse\t\t%s\n", pntr->inUse ? "Y" : "N");
839 fprintf(STDOUT, "needsSalvaged\t%s\n", pntr->needsSalvaged ? "Y" : "N");
840 /* 0xD3 is from afs/volume.h since I had trouble including the file */
841 fprintf(STDOUT, "destroyMe\t%s\n", pntr->destroyMe == 0xD3 ? "Y" : "N");
842 switch (pntr->type) {
844 fprintf(STDOUT, "type\t\tRW\n");
847 fprintf(STDOUT, "type\t\tRO\n");
850 fprintf(STDOUT, "type\t\tBK\n");
853 fprintf(STDOUT, "type\t\t?\n");
856 fprintf(STDOUT, "creationDate\t%-9lu\t%s", pntr->creationDate,
857 ctime(&pntr->creationDate));
858 fprintf(STDOUT, "accessDate\t%-9lu\t%s", pntr->accessDate,
859 ctime(&pntr->accessDate));
860 fprintf(STDOUT, "updateDate\t%-9lu\t%s", pntr->updateDate,
861 ctime(&pntr->updateDate));
862 fprintf(STDOUT, "backupDate\t%-9lu\t%s", pntr->backupDate,
863 ctime(&pntr->backupDate));
864 fprintf(STDOUT, "copyDate\t%-9lu\t%s", pntr->copyDate,
865 ctime(&pntr->copyDate));
866 fprintf(STDOUT, "flags\t\t%#lx\t(Optional)\n", pntr->flags);
867 fprintf(STDOUT, "diskused\t%u\n", pntr->size);
868 fprintf(STDOUT, "maxquota\t%u\n", pntr->maxquota);
869 fprintf(STDOUT, "minquota\t%lu\t(Optional)\n", pntr->spare0);
870 fprintf(STDOUT, "filecount\t%u\n", pntr->filecount);
871 fprintf(STDOUT, "dayUse\t\t%u\n", pntr->dayUse);
872 fprintf(STDOUT, "weekUse\t\t%lu\t(Optional)\n", pntr->spare1);
873 fprintf(STDOUT, "spare2\t\t%lu\t(Optional)\n", pntr->spare2);
874 fprintf(STDOUT, "spare3\t\t%lu\t(Optional)\n", pntr->spare3);
879 DisplayVolumes2(server, partition, pntr, count)
881 long server, partition, count;
885 for (i = 0; i < count; i++) {
886 fprintf(STDOUT, "BEGIN_OF_ENTRY\n");
887 DisplayFormat2(server, partition, pntr);
888 fprintf(STDOUT, "END_OF_ENTRY\n\n");
893 #endif /* FULL_LISTVOL_SWITCH */
896 DisplayVolumes(server, part, pntr, count, longlist, fast, quiet)
897 afs_int32 server, part;
899 afs_int32 count, longlist, fast;
902 int totalOK, totalNotOK, totalBusy, i;
910 for (i = 0; i < count; i++) {
911 DisplayFormat(pntr, server, part, &totalOK, &totalNotOK, &totalBusy,
916 while (busyHead.count) {
917 qGet(&busyHead, &volid);
918 fprintf(STDOUT, "**** Volume %lu is busy ****\n",
919 (unsigned long)volid);
923 while (notokHead.count) {
924 qGet(¬okHead, &volid);
925 fprintf(STDOUT, "**** Could not attach volume %lu ****\n",
926 (unsigned long)volid);
930 fprintf(STDOUT, "\n");
933 "Total volumes onLine %d ; Total volumes offLine %d ; Total busy %d\n\n",
934 totalOK, totalNotOK, totalBusy);
939 /*------------------------------------------------------------------------
940 * PRIVATE XDisplayVolumes
943 * Display extended volume information.
946 * a_servID : Pointer to the Rx call we're performing.
947 * a_partID : Partition for which we want the extended list.
948 * a_xInfoP : Ptr to extended volume info.
949 * a_count : Number of volume records contained above.
950 * a_int32 : Int32 listing generated?
951 * a_fast : Fast listing generated?
952 * a_quiet : Quiet listing generated?
958 * Nothing interesting.
962 *------------------------------------------------------------------------*/
965 XDisplayVolumes(a_servID, a_partID, a_xInfoP, a_count, a_int32, a_fast,
969 volintXInfo *a_xInfoP;
975 { /*XDisplayVolumes */
977 int totalOK; /*Total OK volumes */
978 int totalNotOK; /*Total screwed volumes */
979 int totalBusy; /*Total busy volumes */
980 int i; /*Loop variable */
981 afs_int32 volid; /*Current volume ID */
984 * Initialize counters and (global!!) queues.
993 * Display each volume in the list.
995 for (i = 0; i < a_count; i++) {
996 XDisplayFormat(a_xInfoP, a_servID, a_partID, &totalOK, &totalNotOK,
997 &totalBusy, a_fast, a_int32, 0);
1002 * If any volumes were found to be busy or screwed, display them.
1005 while (busyHead.count) {
1006 qGet(&busyHead, &volid);
1007 fprintf(STDOUT, "**** Volume %lu is busy ****\n",
1008 (unsigned long)volid);
1012 while (notokHead.count) {
1013 qGet(¬okHead, &volid);
1014 fprintf(STDOUT, "**** Could not attach volume %lu ****\n",
1015 (unsigned long)volid);
1020 fprintf(STDOUT, "\n");
1023 "Total volumes: %d on-line, %d off-line, %d busyd\n\n",
1024 totalOK, totalNotOK, totalBusy);
1028 } /*XDisplayVolumes */
1030 /* set <server> and <part> to the correct values depending on
1031 * <voltype> and <entry> */
1033 GetServerAndPart(entry, voltype, server, part, previdx)
1034 struct nvldbentry *entry;
1035 afs_int32 *server, *part;
1039 int i, istart, vtype;
1044 /* Doesn't check for non-existance of backup volume */
1045 if ((voltype == RWVOL) || (voltype == BACKVOL)) {
1047 istart = 0; /* seach the entire entry */
1050 /* Seach from beginning of entry or pick up where we left off */
1051 istart = ((*previdx < 0) ? 0 : *previdx + 1);
1054 for (i = istart; i < entry->nServers; i++) {
1055 if (entry->serverFlags[i] & vtype) {
1056 *server = entry->serverNumber[i];
1057 *part = entry->serverPartition[i];
1063 /* Didn't find any, return -1 */
1069 PostVolumeStats(entry)
1070 struct nvldbentry *entry;
1072 SubEnumerateEntry(entry);
1073 /* Check for VLOP_ALLOPERS */
1074 if (entry->flags & VLOP_ALLOPERS)
1075 fprintf(STDOUT, " Volume is currently LOCKED \n");
1079 /*------------------------------------------------------------------------
1080 * PRIVATE XVolumeStats
1083 * Display extended volume information.
1086 * a_xInfoP : Ptr to extended volume info.
1087 * a_entryP : Ptr to the volume's VLDB entry.
1088 * a_srvID : Server ID.
1089 * a_partID : Partition ID.
1090 * a_volType : Type of volume to print.
1096 * Nothing interesting.
1100 *------------------------------------------------------------------------*/
1103 XVolumeStats(a_xInfoP, a_entryP, a_srvID, a_partID, a_volType)
1104 volintXInfo *a_xInfoP;
1105 struct nvldbentry *a_entryP;
1112 int totalOK, totalNotOK, totalBusy; /*Dummies - we don't really count here */
1114 XDisplayFormat(a_xInfoP, /*Ptr to extended volume info */
1115 a_srvID, /*Server ID to print */
1116 a_partID, /*Partition ID to print */
1117 &totalOK, /*Ptr to total-OK counter */
1118 &totalNotOK, /*Ptr to total-screwed counter */
1119 &totalBusy, /*Ptr to total-busy counter */
1120 0, /*Don't do a fast listing */
1121 1, /*Do a long listing */
1122 1); /*Show volume problems */
1128 VolumeStats(pntr, entry, server, part, voltype)
1130 struct nvldbentry *entry;
1132 afs_int32 server, part;
1134 int totalOK, totalNotOK, totalBusy;
1136 DisplayFormat(pntr, server, part, &totalOK, &totalNotOK, &totalBusy, 0, 1,
1141 /* command to forcibly remove a volume */
1144 register struct cmd_syndesc *as;
1146 register afs_int32 code;
1147 afs_int32 volID, err;
1152 server = GetServer(tp = as->parms[0].items->data);
1154 fprintf(STDERR, "vos: server '%s' not found in host table\n", tp);
1158 partID = volutil_GetPartitionID(tp = as->parms[1].items->data);
1160 fprintf(STDERR, "vos: could not parse '%s' as a partition name", tp);
1164 volID = vsu_GetVolumeID(tp = as->parms[2].items->data, cstruct, &err);
1167 PrintError("", err);
1170 "vos: could not parse '%s' as a numeric volume ID", tp);
1175 "vos: forcibly removing all traces of volume %d, please wait...",
1178 code = UV_NukeVolume(server, partID, volID);
1180 fprintf(STDOUT, "done.\n");
1182 fprintf(STDOUT, "failed with code %d.\n", code);
1187 /*------------------------------------------------------------------------
1188 * PRIVATE ExamineVolume
1191 * Routine used to examine a single volume, contacting the VLDB as
1192 * well as the Volume Server.
1195 * as : Ptr to parsed command line arguments.
1198 * 0 for a successful operation,
1199 * Otherwise, one of the ubik or VolServer error values.
1202 * Nothing interesting.
1206 *------------------------------------------------------------------------
1210 register struct cmd_syndesc *as;
1212 struct nvldbentry entry;
1213 afs_int32 vcode = 0;
1214 volintInfo *pntr = (volintInfo *) 0;
1215 volintXInfo *xInfoP = (volintXInfo *) 0;
1217 afs_int32 code, err, error = 0;
1218 int voltype, foundserv = 0, foundentry = 0;
1219 afs_int32 aserver, apart;
1221 int wantExtendedInfo; /*Do we want extended vol info? */
1223 wantExtendedInfo = (as->parms[1].items ? 1 : 0); /* -extended */
1225 volid = vsu_GetVolumeID(as->parms[0].items->data, cstruct, &err); /* -id */
1228 PrintError("", err);
1230 fprintf(STDERR, "Unknown volume ID or name '%s'\n",
1231 as->parms[0].items->data);
1236 fprintf(STDOUT, "Fetching VLDB entry for %lu .. ",
1237 (unsigned long)volid);
1240 vcode = VLDB_GetEntryByID(volid, -1, &entry);
1243 "Could not fetch the entry for volume number %lu from VLDB \n",
1244 (unsigned long)volid);
1248 fprintf(STDOUT, "done\n");
1249 MapHostToNetwork(&entry);
1251 if (entry.volumeId[RWVOL] == volid)
1253 else if (entry.volumeId[BACKVOL] == volid)
1255 else /* (entry.volumeId[ROVOL] == volid) */
1258 do { /* do {...} while (voltype == ROVOL) */
1259 /* Get the entry for the volume. If its a RW vol, get the RW entry.
1260 * It its a BK vol, get the RW entry (even if VLDB may say the BK doen't exist).
1261 * If its a RO vol, get the next RO entry.
1263 GetServerAndPart(&entry, ((voltype == ROVOL) ? ROVOL : RWVOL),
1264 &aserver, &apart, &previdx);
1265 if (previdx == -1) { /* searched all entries */
1267 fprintf(STDERR, "Volume %s does not exist in VLDB\n\n",
1268 as->parms[0].items->data);
1275 /* Get information about the volume from the server */
1277 fprintf(STDOUT, "Getting volume listing from the server %s .. ",
1278 hostutil_GetNameByINet(aserver));
1281 if (wantExtendedInfo)
1282 code = UV_XListOneVolume(aserver, apart, volid, &xInfoP);
1284 code = UV_ListOneVolume(aserver, apart, volid, &pntr);
1286 fprintf(STDOUT, "done\n");
1290 if (code == ENODEV) {
1291 if ((voltype == BACKVOL) && !(entry.flags & BACK_EXISTS)) {
1292 /* The VLDB says there is no backup volume and its not on disk */
1293 fprintf(STDERR, "Volume %s does not exist\n",
1294 as->parms[0].items->data);
1298 "Volume does not exist on server %s as indicated by the VLDB\n",
1299 hostutil_GetNameByINet(aserver));
1302 PrintDiagnostics("examine", code);
1304 fprintf(STDOUT, "\n");
1307 if (wantExtendedInfo)
1308 XVolumeStats(xInfoP, &entry, aserver, apart, voltype);
1310 #ifdef FULL_LISTVOL_SWITCH
1311 if (as->parms[2].items) {
1312 DisplayFormat2(aserver, apart, pntr);
1313 EnumerateEntry(&entry);
1315 #endif /* FULL_LISTVOL_SWITCH */
1316 VolumeStats(pntr, &entry, aserver, apart, voltype);
1318 if ((voltype == BACKVOL) && !(entry.flags & BACK_EXISTS)) {
1319 /* The VLDB says there is no backup volume yet we found one on disk */
1320 fprintf(STDERR, "Volume %s does not exist in VLDB\n",
1321 as->parms[0].items->data);
1330 } while (voltype == ROVOL);
1333 fprintf(STDERR, "Dump only information from VLDB\n\n");
1334 fprintf(STDOUT, "%s \n", entry.name); /* PostVolumeStats doesn't print name */
1336 PostVolumeStats(&entry);
1341 /*------------------------------------------------------------------------
1345 * Routine used to change the status of a single volume.
1348 * as : Ptr to parsed command line arguments.
1351 * 0 for a successful operation,
1352 * Otherwise, one of the ubik or VolServer error values.
1355 * Nothing interesting.
1359 *------------------------------------------------------------------------
1363 register struct cmd_syndesc *as;
1365 struct nvldbentry entry;
1366 afs_int32 vcode = 0;
1369 afs_int32 code, err;
1370 afs_int32 aserver, apart;
1373 volid = vsu_GetVolumeID(as->parms[0].items->data, cstruct, &err); /* -id */
1376 PrintError("", err);
1378 fprintf(STDERR, "Unknown volume ID or name '%s'\n",
1379 as->parms[0].items->data);
1383 code = VLDB_GetEntryByID(volid, RWVOL, &entry);
1386 "Could not fetch the entry for volume number %lu from VLDB \n",
1387 (unsigned long)volid);
1390 MapHostToNetwork(&entry);
1392 GetServerAndPart(&entry, RWVOL, &aserver, &apart, &previdx);
1393 if (previdx == -1) {
1394 fprintf(STDERR, "Volume %s does not exist in VLDB\n\n",
1395 as->parms[0].items->data);
1399 memset(&info, 0, sizeof(info));
1410 if (as->parms[1].items) {
1412 code = util_GetInt32(as->parms[1].items->data, &info.maxquota);
1414 fprintf(STDERR, "invalid quota value\n");
1418 if (as->parms[2].items) {
1422 code = UV_SetVolumeInfo(aserver, apart, volid, &info);
1425 "Could not update volume info fields for volume number %lu\n",
1426 (unsigned long)volid);
1430 /*------------------------------------------------------------------------
1434 * Brings a volume online.
1437 * as : Ptr to parsed command line arguments.
1440 * 0 for a successful operation,
1443 * Nothing interesting.
1447 *------------------------------------------------------------------------
1451 register struct cmd_syndesc *as;
1453 afs_int32 server, partition, volid;
1454 afs_int32 code, err = 0;
1456 server = GetServer(as->parms[0].items->data);
1458 fprintf(STDERR, "vos: server '%s' not found in host table\n",
1459 as->parms[0].items->data);
1463 partition = volutil_GetPartitionID(as->parms[1].items->data);
1464 if (partition < 0) {
1465 fprintf(STDERR, "vos: could not interpret partition name '%s'\n",
1466 as->parms[1].items->data);
1470 volid = vsu_GetVolumeID(as->parms[2].items->data, cstruct, &err); /* -id */
1473 PrintError("", err);
1475 fprintf(STDERR, "Unknown volume ID or name '%s'\n",
1476 as->parms[0].items->data);
1480 code = UV_SetVolume(server, partition, volid, ITOffline, 0 /*online */ ,
1483 fprintf(STDERR, "Failed to set volume. Code = %d\n", code);
1490 /*------------------------------------------------------------------------
1491 * PRIVATE volOffline
1494 * Brings a volume offline.
1497 * as : Ptr to parsed command line arguments.
1500 * 0 for a successful operation,
1503 * Nothing interesting.
1507 *------------------------------------------------------------------------
1510 volOffline(register struct cmd_syndesc *as)
1512 afs_int32 server, partition, volid;
1513 afs_int32 code, err = 0;
1514 afs_int32 transflag, sleeptime, transdone;
1516 server = GetServer(as->parms[0].items->data);
1518 fprintf(STDERR, "vos: server '%s' not found in host table\n",
1519 as->parms[0].items->data);
1523 partition = volutil_GetPartitionID(as->parms[1].items->data);
1524 if (partition < 0) {
1525 fprintf(STDERR, "vos: could not interpret partition name '%s'\n",
1526 as->parms[1].items->data);
1530 volid = vsu_GetVolumeID(as->parms[2].items->data, cstruct, &err); /* -id */
1533 PrintError("", err);
1535 fprintf(STDERR, "Unknown volume ID or name '%s'\n",
1536 as->parms[0].items->data);
1540 transflag = (as->parms[4].items ? ITBusy : ITOffline);
1541 sleeptime = (as->parms[3].items ? atol(as->parms[3].items->data) : 0);
1542 transdone = (sleeptime ? 0 /*online */ : VTOutOfService);
1543 if (as->parms[4].items && !as->parms[3].items) {
1544 fprintf(STDERR, "-sleep option must be used with -busy flag\n");
1549 UV_SetVolume(server, partition, volid, transflag, transdone,
1552 fprintf(STDERR, "Failed to set volume. Code = %d\n", code);
1560 CreateVolume(register struct cmd_syndesc *as)
1564 afs_int32 volid, code;
1565 struct nvldbentry entry;
1570 tserver = GetServer(as->parms[0].items->data);
1572 fprintf(STDERR, "vos: host '%s' not found in host table\n",
1573 as->parms[0].items->data);
1576 pnum = volutil_GetPartitionID(as->parms[1].items->data);
1578 fprintf(STDERR, "vos: could not interpret partition name '%s'\n",
1579 as->parms[1].items->data);
1582 if (!IsPartValid(pnum, tserver, &code)) { /*check for validity of the partition */
1584 PrintError("", code);
1587 "vos : partition %s does not exist on the server\n",
1588 as->parms[1].items->data);
1591 if (!ISNAMEVALID(as->parms[2].items->data)) {
1593 "vos: the name of the root volume %s exceeds the size limit of %d\n",
1594 as->parms[2].items->data, VOLSER_OLDMAXVOLNAME - 10);
1597 if (!VolNameOK(as->parms[2].items->data)) {
1599 "Illegal volume name %s, should not end in .readonly or .backup\n",
1600 as->parms[2].items->data);
1603 if (IsNumeric(as->parms[2].items->data)) {
1604 fprintf(STDERR, "Illegal volume name %s, should not be a number\n",
1605 as->parms[2].items->data);
1608 vcode = VLDB_GetEntryByName(as->parms[2].items->data, &entry);
1610 fprintf(STDERR, "Volume %s already exists\n",
1611 as->parms[2].items->data);
1612 PrintDiagnostics("create", code);
1616 if (as->parms[3].items) {
1617 if (!IsNumeric(as->parms[3].items->data)) {
1618 fprintf(STDERR, "Initial quota %s should be numeric.\n",
1619 as->parms[3].items->data);
1623 code = util_GetInt32(as->parms[3].items->data, "a);
1625 fprintf(STDERR, "vos: bad integer specified for quota.\n");
1631 UV_CreateVolume2(tserver, pnum, as->parms[2].items->data, quota, 0,
1634 PrintDiagnostics("create", code);
1637 MapPartIdIntoName(pnum, part);
1638 fprintf(STDOUT, "Volume %lu created on partition %s of %s\n",
1639 (unsigned long)volid, part, as->parms[0].items->data);
1646 struct nvldbentry *entry;
1649 afs_int32 error, code, curserver, curpart, volid;
1651 MapHostToNetwork(entry);
1653 for (i = 0; i < entry->nServers; i++) {
1654 curserver = entry->serverNumber[i];
1655 curpart = entry->serverPartition[i];
1656 if (entry->serverFlags[i] & ITSROVOL) {
1657 volid = entry->volumeId[ROVOL];
1659 volid = entry->volumeId[RWVOL];
1661 code = UV_DeleteVolume(curserver, curpart, volid);
1670 struct cmd_syndesc *as;
1672 afs_int32 err, code = 0;
1673 afs_int32 server = 0, partition = -1, volid;
1677 if (as->parms[0].items) {
1678 server = GetServer(as->parms[0].items->data);
1680 fprintf(STDERR, "vos: server '%s' not found in host table\n",
1681 as->parms[0].items->data);
1686 if (as->parms[1].items) {
1687 partition = volutil_GetPartitionID(as->parms[1].items->data);
1688 if (partition < 0) {
1689 fprintf(STDERR, "vos: could not interpret partition name '%s'\n",
1690 as->parms[1].items->data);
1694 /* Check for validity of the partition */
1695 if (!IsPartValid(partition, server, &code)) {
1697 PrintError("", code);
1700 "vos : partition %s does not exist on the server\n",
1701 as->parms[1].items->data);
1707 volid = vsu_GetVolumeID(as->parms[2].items->data, cstruct, &err);
1709 fprintf(STDERR, "Can't find volume name '%s' in VLDB\n",
1710 as->parms[2].items->data);
1712 PrintError("", err);
1716 /* If the server or partition option are not complete, try to fill
1717 * them in from the VLDB entry.
1719 if ((partition == -1) || !server) {
1720 struct nvldbentry entry;
1722 code = VLDB_GetEntryByID(volid, -1, &entry);
1725 "Could not fetch the entry for volume %lu from VLDB\n",
1726 (unsigned long)volid);
1727 PrintError("", code);
1731 if (((volid == entry.volumeId[RWVOL]) && (entry.flags & RW_EXISTS))
1732 || ((volid == entry.volumeId[BACKVOL])
1733 && (entry.flags & BACK_EXISTS))) {
1734 idx = Lp_GetRwIndex(&entry);
1735 if ((idx == -1) || (server && (server != entry.serverNumber[idx]))
1736 || ((partition != -1)
1737 && (partition != entry.serverPartition[idx]))) {
1738 fprintf(STDERR, "VLDB: Volume '%s' no match\n",
1739 as->parms[2].items->data);
1742 } else if ((volid == entry.volumeId[ROVOL])
1743 && (entry.flags & RO_EXISTS)) {
1744 for (idx = -1, j = 0; j < entry.nServers; j++) {
1745 if (entry.serverFlags[j] != ITSROVOL)
1748 if (((server == 0) || (server == entry.serverNumber[j]))
1749 && ((partition == -1)
1750 || (partition == entry.serverPartition[j]))) {
1753 "VLDB: Volume '%s' matches more than one RO\n",
1754 as->parms[2].items->data);
1761 fprintf(STDERR, "VLDB: Volume '%s' no match\n",
1762 as->parms[2].items->data);
1766 fprintf(STDERR, "VLDB: Volume '%s' no match\n",
1767 as->parms[2].items->data);
1771 server = htonl(entry.serverNumber[idx]);
1772 partition = entry.serverPartition[idx];
1776 code = UV_DeleteVolume(server, partition, volid);
1778 PrintDiagnostics("remove", code);
1782 MapPartIdIntoName(partition, pname);
1783 fprintf(STDOUT, "Volume %lu on partition %s server %s deleted\n",
1784 (unsigned long)volid, pname, hostutil_GetNameByINet(server));
1788 #define TESTM 0 /* set for move space tests, clear for production */
1791 register struct cmd_syndesc *as;
1794 afs_int32 volid, fromserver, toserver, frompart, topart;
1795 afs_int32 flags, code, err;
1796 char fromPartName[10], toPartName[10];
1798 struct diskPartition partition; /* for space check */
1801 volid = vsu_GetVolumeID(as->parms[0].items->data, cstruct, &err);
1804 PrintError("", err);
1806 fprintf(STDERR, "vos: can't find volume ID or name '%s'\n",
1807 as->parms[0].items->data);
1810 fromserver = GetServer(as->parms[1].items->data);
1811 if (fromserver == 0) {
1812 fprintf(STDERR, "vos: server '%s' not found in host table\n",
1813 as->parms[1].items->data);
1816 toserver = GetServer(as->parms[3].items->data);
1817 if (toserver == 0) {
1818 fprintf(STDERR, "vos: server '%s' not found in host table\n",
1819 as->parms[3].items->data);
1822 frompart = volutil_GetPartitionID(as->parms[2].items->data);
1824 fprintf(STDERR, "vos: could not interpret partition name '%s'\n",
1825 as->parms[2].items->data);
1828 if (!IsPartValid(frompart, fromserver, &code)) { /*check for validity of the partition */
1830 PrintError("", code);
1833 "vos : partition %s does not exist on the server\n",
1834 as->parms[2].items->data);
1837 topart = volutil_GetPartitionID(as->parms[4].items->data);
1839 fprintf(STDERR, "vos: could not interpret partition name '%s'\n",
1840 as->parms[4].items->data);
1843 if (!IsPartValid(topart, toserver, &code)) { /*check for validity of the partition */
1845 PrintError("", code);
1848 "vos : partition %s does not exist on the server\n",
1849 as->parms[4].items->data);
1854 if (as->parms[5].items) flags |= RV_NOCLONE;
1857 * check source partition for space to clone volume
1860 MapPartIdIntoName(topart, toPartName);
1861 MapPartIdIntoName(frompart, fromPartName);
1864 * check target partition for space to move volume
1867 code = UV_PartitionInfo(toserver, toPartName, &partition);
1869 fprintf(STDERR, "vos: cannot access partition %s\n", toPartName);
1873 fprintf(STDOUT, "target partition %s free space %d\n", toPartName,
1876 p = (volintInfo *) 0;
1877 code = UV_ListOneVolume(fromserver, frompart, volid, &p);
1879 fprintf(STDERR, "vos:cannot access volume %lu\n",
1880 (unsigned long)volid);
1885 fprintf(STDOUT, "volume %lu size %d\n", (unsigned long)volid,
1887 if (partition.free <= p->size) {
1889 "vos: no space on target partition %s to move volume %lu\n",
1890 toPartName, (unsigned long)volid);
1897 fprintf(STDOUT, "size test - don't do move\n");
1901 /* successful move still not guaranteed but shoot for it */
1904 UV_MoveVolume2(volid, fromserver, frompart, toserver, topart, flags);
1906 PrintDiagnostics("move", code);
1909 MapPartIdIntoName(topart, toPartName);
1910 MapPartIdIntoName(frompart, fromPartName);
1911 fprintf(STDOUT, "Volume %lu moved from %s %s to %s %s \n",
1912 (unsigned long)volid, as->parms[1].items->data, fromPartName,
1913 as->parms[3].items->data, toPartName);
1920 register struct cmd_syndesc *as;
1922 afs_int32 volid, fromserver, toserver, frompart, topart, code, err, flags;
1923 char fromPartName[10], toPartName[10], *tovolume;
1924 struct nvldbentry entry;
1925 struct diskPartition partition; /* for space check */
1928 volid = vsu_GetVolumeID(as->parms[0].items->data, cstruct, &err);
1931 PrintError("", err);
1933 fprintf(STDERR, "vos: can't find volume ID or name '%s'\n",
1934 as->parms[0].items->data);
1937 fromserver = GetServer(as->parms[1].items->data);
1938 if (fromserver == 0) {
1939 fprintf(STDERR, "vos: server '%s' not found in host table\n",
1940 as->parms[1].items->data);
1944 toserver = GetServer(as->parms[4].items->data);
1945 if (toserver == 0) {
1946 fprintf(STDERR, "vos: server '%s' not found in host table\n",
1947 as->parms[4].items->data);
1951 tovolume = as->parms[3].items->data;
1952 if (!ISNAMEVALID(tovolume)) {
1954 "vos: the name of the root volume %s exceeds the size limit of %d\n",
1955 tovolume, VOLSER_OLDMAXVOLNAME - 10);
1958 if (!VolNameOK(tovolume)) {
1960 "Illegal volume name %s, should not end in .readonly or .backup\n",
1964 if (IsNumeric(tovolume)) {
1965 fprintf(STDERR, "Illegal volume name %s, should not be a number\n",
1969 code = VLDB_GetEntryByName(tovolume, &entry);
1971 fprintf(STDERR, "Volume %s already exists\n", tovolume);
1972 PrintDiagnostics("copy", code);
1976 frompart = volutil_GetPartitionID(as->parms[2].items->data);
1978 fprintf(STDERR, "vos: could not interpret partition name '%s'\n",
1979 as->parms[2].items->data);
1982 if (!IsPartValid(frompart, fromserver, &code)) { /*check for validity of the partition */
1984 PrintError("", code);
1987 "vos : partition %s does not exist on the server\n",
1988 as->parms[2].items->data);
1992 topart = volutil_GetPartitionID(as->parms[5].items->data);
1994 fprintf(STDERR, "vos: could not interpret partition name '%s'\n",
1995 as->parms[5].items->data);
1998 if (!IsPartValid(topart, toserver, &code)) { /*check for validity of the partition */
2000 PrintError("", code);
2003 "vos : partition %s does not exist on the server\n",
2004 as->parms[5].items->data);
2009 if (as->parms[6].items) flags |= RV_OFFLINE;
2010 if (as->parms[7].items) flags |= RV_RDONLY;
2011 if (as->parms[8].items) flags |= RV_NOCLONE;
2013 MapPartIdIntoName(topart, toPartName);
2014 MapPartIdIntoName(frompart, fromPartName);
2017 * check target partition for space to move volume
2020 code = UV_PartitionInfo(toserver, toPartName, &partition);
2022 fprintf(STDERR, "vos: cannot access partition %s\n", toPartName);
2026 fprintf(STDOUT, "target partition %s free space %d\n", toPartName,
2029 p = (volintInfo *) 0;
2030 code = UV_ListOneVolume(fromserver, frompart, volid, &p);
2032 fprintf(STDERR, "vos:cannot access volume %lu\n",
2033 (unsigned long)volid);
2038 if (partition.free <= p->size) {
2040 "vos: no space on target partition %s to copy volume %lu\n",
2041 toPartName, (unsigned long)volid);
2047 /* successful copy still not guaranteed but shoot for it */
2050 UV_CopyVolume2(volid, fromserver, frompart, tovolume, toserver,
2053 PrintDiagnostics("copy", code);
2056 MapPartIdIntoName(topart, toPartName);
2057 MapPartIdIntoName(frompart, fromPartName);
2058 fprintf(STDOUT, "Volume %lu copied from %s %s to %s on %s %s \n",
2059 (unsigned long)volid, as->parms[1].items->data, fromPartName,
2060 tovolume, as->parms[4].items->data, toPartName);
2068 register struct cmd_syndesc *as;
2070 afs_int32 volid, fromserver, toserver, frompart, topart, tovolid;
2071 afs_int32 code, err, flags;
2072 char fromPartName[10], toPartName[10], toVolName[32], *tovolume;
2073 struct nvldbentry entry;
2074 struct diskPartition partition; /* for space check */
2077 p = (volintInfo *) 0;
2078 q = (volintInfo *) 0;
2080 volid = vsu_GetVolumeID(as->parms[0].items->data, cstruct, &err);
2083 PrintError("", err);
2085 fprintf(STDERR, "vos: can't find volume ID or name '%s'\n",
2086 as->parms[0].items->data);
2089 fromserver = GetServer(as->parms[1].items->data);
2090 if (fromserver == 0) {
2091 fprintf(STDERR, "vos: server '%s' not found in host table\n",
2092 as->parms[1].items->data);
2096 toserver = GetServer(as->parms[3].items->data);
2097 if (toserver == 0) {
2098 fprintf(STDERR, "vos: server '%s' not found in host table\n",
2099 as->parms[3].items->data);
2103 frompart = volutil_GetPartitionID(as->parms[2].items->data);
2105 fprintf(STDERR, "vos: could not interpret partition name '%s'\n",
2106 as->parms[2].items->data);
2109 if (!IsPartValid(frompart, fromserver, &code)) { /*check for validity of the partition */
2111 PrintError("", code);
2114 "vos : partition %s does not exist on the server\n",
2115 as->parms[2].items->data);
2119 topart = volutil_GetPartitionID(as->parms[4].items->data);
2121 fprintf(STDERR, "vos: could not interpret partition name '%s'\n",
2122 as->parms[4].items->data);
2125 if (!IsPartValid(topart, toserver, &code)) { /*check for validity of the partition */
2127 PrintError("", code);
2130 "vos : partition %s does not exist on the server\n",
2131 as->parms[4].items->data);
2135 if (as->parms[5].items) {
2136 tovolume = as->parms[5].items->data;
2137 if (!ISNAMEVALID(tovolume)) {
2139 "vos: the name of the root volume %s exceeds the size limit of %d\n",
2140 tovolume, VOLSER_OLDMAXVOLNAME - 10);
2143 if (!VolNameOK(tovolume)) {
2145 "Illegal volume name %s, should not end in .readonly or .backup\n",
2149 if (IsNumeric(tovolume)) {
2151 "Illegal volume name %s, should not be a number\n",
2156 /* use actual name of source volume */
2157 code = UV_ListOneVolume(fromserver, frompart, volid, &p);
2159 fprintf(STDERR, "vos:cannot access volume %lu\n",
2160 (unsigned long)volid);
2163 strcpy(toVolName, p->name);
2164 tovolume = toVolName;
2165 /* save p for size checks later */
2168 if (as->parms[6].items) {
2169 tovolid = vsu_GetVolumeID(as->parms[6].items->data, cstruct, &err);
2172 PrintError("", err);
2174 fprintf(STDERR, "vos: can't find volume ID or name '%s'\n",
2175 as->parms[6].items->data);
2181 tovolid = vsu_GetVolumeID(tovolume, cstruct, &err);
2184 PrintError("", err);
2186 fprintf(STDERR, "vos: can't find volume ID or name '%s'\n",
2195 if (as->parms[7].items) flags |= RV_OFFLINE;
2196 if (as->parms[8].items) flags |= RV_RDONLY;
2197 if (as->parms[9].items) flags |= RV_NOCLONE;
2198 if (as->parms[10].items) flags |= RV_CPINCR;
2200 MapPartIdIntoName(topart, toPartName);
2201 MapPartIdIntoName(frompart, fromPartName);
2204 * check target partition for space to move volume
2207 code = UV_PartitionInfo(toserver, toPartName, &partition);
2209 fprintf(STDERR, "vos: cannot access partition %s\n", toPartName);
2213 fprintf(STDOUT, "target partition %s free space %d\n", toPartName,
2216 /* Don't do this again if we did it above */
2218 code = UV_ListOneVolume(fromserver, frompart, volid, &p);
2220 fprintf(STDERR, "vos:cannot access volume %lu\n",
2221 (unsigned long)volid);
2226 /* OK if this fails */
2227 code = UV_ListOneVolume(toserver, topart, tovolid, &q);
2229 /* Treat existing volume size as "free" */
2231 p->size = (q->size < p->size) ? p->size - q->size : 0;
2233 if (partition.free <= p->size) {
2235 "vos: no space on target partition %s to copy volume %lu\n",
2236 toPartName, (unsigned long)volid);
2244 /* successful copy still not guaranteed but shoot for it */
2247 UV_CopyVolume2(volid, fromserver, frompart, tovolume, toserver,
2248 topart, tovolid, flags);
2250 PrintDiagnostics("shadow", code);
2253 MapPartIdIntoName(topart, toPartName);
2254 MapPartIdIntoName(frompart, fromPartName);
2255 fprintf(STDOUT, "Volume %lu shadowed from %s %s to %s %s \n",
2256 (unsigned long)volid, as->parms[1].items->data, fromPartName,
2257 as->parms[4].items->data, toPartName);
2265 register struct cmd_syndesc *as;
2267 afs_int32 server, part, volid, cloneid, voltype;
2268 char partName[10], *volname;
2269 afs_int32 code, err, flags;
2270 struct nvldbentry entry;
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);
2282 if (as->parms[1].items || as->parms[2].items) {
2283 if (!as->parms[1].items || !as->parms[2].items) {
2285 "Must specify both -server and -partition options\n");
2288 server = GetServer(as->parms[1].items->data);
2290 fprintf(STDERR, "vos: server '%s' not found in host table\n",
2291 as->parms[1].items->data);
2294 part = volutil_GetPartitionID(as->parms[2].items->data);
2296 fprintf(STDERR, "vos: could not interpret partition name '%s'\n",
2297 as->parms[2].items->data);
2300 if (!IsPartValid(part, server, &code)) { /*check for validity of the partition */
2302 PrintError("", code);
2305 "vos : partition %s does not exist on the server\n",
2306 as->parms[2].items->data);
2310 code = GetVolumeInfo(volid, &server, &part, &voltype, &entry);
2316 if (as->parms[3].items) {
2317 volname = as->parms[3].items->data;
2318 if (strlen(volname) > VOLSER_OLDMAXVOLNAME - 1) {
2320 "vos: the name of the root volume %s exceeds the size limit of %d\n",
2321 volname, VOLSER_OLDMAXVOLNAME - 1);
2324 if (!VolNameOK(volname)) {
2326 "Illegal volume name %s, should not end in .readonly or .backup\n",
2330 if (IsNumeric(volname)) {
2332 "Illegal volume name %s, should not be a number\n",
2339 if (as->parms[4].items) {
2340 cloneid = vsu_GetVolumeID(as->parms[4].items->data, cstruct, &err);
2343 PrintError("", err);
2345 fprintf(STDERR, "vos: can't find volume ID or name '%s'\n",
2346 as->parms[4].items->data);
2352 if (as->parms[5].items) flags |= RV_OFFLINE;
2353 if (as->parms[6].items) flags |= RV_RDONLY;
2357 UV_CloneVolume(server, part, volid, cloneid, volname, flags);
2360 PrintDiagnostics("clone", code);
2363 MapPartIdIntoName(part, partName);
2364 fprintf(STDOUT, "Created clone for volume %lu\n",
2365 as->parms[0].items->data);
2373 register struct cmd_syndesc *as;
2375 afs_int32 avolid, aserver, apart, vtype, code, err;
2376 struct nvldbentry entry;
2378 afs_int32 buvolid, buserver, bupart, butype;
2379 struct nvldbentry buentry;
2381 avolid = vsu_GetVolumeID(as->parms[0].items->data, cstruct, &err);
2384 PrintError("", err);
2386 fprintf(STDERR, "vos: can't find volume ID or name '%s'\n",
2387 as->parms[0].items->data);
2390 code = GetVolumeInfo(avolid, &aserver, &apart, &vtype, &entry);
2394 /* verify this is a readwrite volume */
2396 if (vtype != RWVOL) {
2397 fprintf(STDERR, "%s not RW volume\n", as->parms[0].items->data);
2401 /* is there a backup volume already? */
2403 if (entry.flags & BACK_EXISTS) {
2404 /* yep, where is it? */
2406 buvolid = entry.volumeId[BACKVOL];
2407 code = GetVolumeInfo(buvolid, &buserver, &bupart, &butype, &buentry);
2412 code = VLDB_IsSameAddrs(buserver, aserver, &err);
2415 "Failed to get info about server's %d address(es) from vlserver; aborting call!\n",
2421 "FATAL ERROR: backup volume %lu exists on server %lu\n",
2422 (unsigned long)buvolid, (unsigned long)buserver);
2427 /* nope, carry on */
2429 code = UV_BackupVolume(aserver, apart, avolid);
2432 PrintDiagnostics("backup", code);
2435 fprintf(STDOUT, "Created backup volume for %s \n",
2436 as->parms[0].items->data);
2442 register struct cmd_syndesc *as;
2445 struct nvldbentry entry;
2446 afs_int32 avolid, aserver, apart, vtype, code, err;
2449 if (as->parms[1].items)
2451 avolid = vsu_GetVolumeID(as->parms[0].items->data, cstruct, &err);
2454 PrintError("", err);
2456 fprintf(STDERR, "vos: can't find volume '%s'\n",
2457 as->parms[0].items->data);
2460 code = GetVolumeInfo(avolid, &aserver, &apart, &vtype, &entry);
2464 if (vtype != RWVOL) {
2465 fprintf(STDERR, "%s not a RW volume\n", as->parms[0].items->data);
2469 if (!ISNAMEVALID(entry.name)) {
2471 "Volume name %s is too long, rename before releasing\n",
2476 code = UV_ReleaseVolume(avolid, aserver, apart, force);
2478 PrintDiagnostics("release", code);
2481 fprintf(STDOUT, "Released volume %s successfully\n",
2482 as->parms[0].items->data);
2488 register struct cmd_syndesc *as;
2491 afs_int32 avolid, aserver, apart, voltype, fromdate = 0, code, err, i;
2492 char filename[NameLen];
2493 struct nvldbentry entry;
2495 rx_SetRxDeadTime(60 * 10);
2496 for (i = 0; i < MAXSERVERS; i++) {
2497 struct rx_connection *rxConn = ubik_GetRPCConn(cstruct, i);
2500 rx_SetConnDeadTime(rxConn, rx_connDeadTime);
2501 if (rxConn->service)
2502 rxConn->service->connDeadTime = rx_connDeadTime;
2505 avolid = vsu_GetVolumeID(as->parms[0].items->data, cstruct, &err);
2508 PrintError("", err);
2510 fprintf(STDERR, "vos: can't find volume '%s'\n",
2511 as->parms[0].items->data);
2515 if (as->parms[3].items || as->parms[4].items) {
2516 if (!as->parms[3].items || !as->parms[4].items) {
2518 "Must specify both -server and -partition options\n");
2521 aserver = GetServer(as->parms[3].items->data);
2523 fprintf(STDERR, "Invalid server name\n");
2526 apart = volutil_GetPartitionID(as->parms[4].items->data);
2528 fprintf(STDERR, "Invalid partition name\n");
2532 code = GetVolumeInfo(avolid, &aserver, &apart, &voltype, &entry);
2537 if (as->parms[1].items && strcmp(as->parms[1].items->data, "0")) {
2538 code = ktime_DateToInt32(as->parms[1].items->data, &fromdate);
2540 fprintf(STDERR, "vos: failed to parse date '%s' (error=%d))\n",
2541 as->parms[1].items->data, code);
2545 if (as->parms[2].items) {
2546 strcpy(filename, as->parms[2].items->data);
2548 strcpy(filename, "");
2551 if (as->parms[5].items) {
2553 UV_DumpClonedVolume(avolid, aserver, apart, fromdate,
2554 DumpFunction, filename);
2557 UV_DumpVolume(avolid, aserver, apart, fromdate, DumpFunction,
2561 PrintDiagnostics("dump", code);
2564 if (strcmp(filename, ""))
2565 fprintf(STDERR, "Dumped volume %s in file %s\n",
2566 as->parms[0].items->data, filename);
2568 fprintf(STDERR, "Dumped volume %s in stdout \n",
2569 as->parms[0].items->data);
2580 register struct cmd_syndesc *as;
2583 afs_int32 avolid, aserver, apart, code, vcode, err;
2584 afs_int32 aoverwrite = ASK;
2585 int restoreflags, readonly = 0, offline = 0, voltype = RWVOL;
2587 char afilename[NameLen], avolname[VOLSER_MAXVOLNAME + 1], apartName[10];
2588 char volname[VOLSER_MAXVOLNAME + 1];
2589 struct nvldbentry entry;
2593 if (as->parms[4].items) {
2594 avolid = vsu_GetVolumeID(as->parms[4].items->data, cstruct, &err);
2597 PrintError("", err);
2599 fprintf(STDERR, "vos: can't find volume '%s'\n",
2600 as->parms[4].items->data);
2606 if (as->parms[5].items) {
2607 if ((strcmp(as->parms[5].items->data, "a") == 0)
2608 || (strcmp(as->parms[5].items->data, "abort") == 0)) {
2610 } else if ((strcmp(as->parms[5].items->data, "f") == 0)
2611 || (strcmp(as->parms[5].items->data, "full") == 0)) {
2613 } else if ((strcmp(as->parms[5].items->data, "i") == 0)
2614 || (strcmp(as->parms[5].items->data, "inc") == 0)
2615 || (strcmp(as->parms[5].items->data, "increment") == 0)
2616 || (strcmp(as->parms[5].items->data, "incremental") == 0)) {
2619 fprintf(STDERR, "vos: %s is not a valid argument to -overwrite\n",
2620 as->parms[5].items->data);
2624 if (as->parms[6].items)
2626 if (as->parms[7].items) {
2631 aserver = GetServer(as->parms[0].items->data);
2633 fprintf(STDERR, "vos: server '%s' not found in host table\n",
2634 as->parms[0].items->data);
2637 apart = volutil_GetPartitionID(as->parms[1].items->data);
2639 fprintf(STDERR, "vos: could not interpret partition name '%s'\n",
2640 as->parms[1].items->data);
2643 if (!IsPartValid(apart, aserver, &code)) { /*check for validity of the partition */
2645 PrintError("", code);
2648 "vos : partition %s does not exist on the server\n",
2649 as->parms[1].items->data);
2652 strcpy(avolname, as->parms[2].items->data);
2653 if (!ISNAMEVALID(avolname)) {
2655 "vos: the name of the volume %s exceeds the size limit\n",
2659 if (!VolNameOK(avolname)) {
2661 "Illegal volume name %s, should not end in .readonly or .backup\n",
2665 if (as->parms[3].items) {
2666 strcpy(afilename, as->parms[3].items->data);
2667 if (!FileExists(afilename)) {
2668 fprintf(STDERR, "Can't access file %s\n", afilename);
2672 strcpy(afilename, "");
2675 /* Check if volume exists or not */
2677 vsu_ExtractName(volname, avolname);
2678 vcode = VLDB_GetEntryByName(volname, &entry);
2679 if (vcode) { /* no volume - do a full restore */
2680 restoreflags = RV_FULLRST;
2681 if ((aoverwrite == INC) || (aoverwrite == ABORT))
2683 "Volume does not exist; Will perform a full restore\n");
2686 else if ((!readonly && Lp_GetRwIndex(&entry) == -1) /* RW volume does not exist - do a full */
2687 ||(readonly && !Lp_ROMatch(0, 0, &entry))) { /* RO volume does not exist - do a full */
2688 restoreflags = RV_FULLRST;
2689 if ((aoverwrite == INC) || (aoverwrite == ABORT))
2691 "%s Volume does not exist; Will perform a full restore\n",
2692 readonly ? "RO" : "RW");
2695 avolid = entry.volumeId[voltype];
2696 } else if (entry.volumeId[voltype] != 0
2697 && entry.volumeId[voltype] != avolid) {
2698 avolid = entry.volumeId[voltype];
2702 else { /* volume exists - do we do a full incremental or abort */
2703 int Oserver, Opart, Otype, vol_elsewhere = 0;
2704 struct nvldbentry Oentry;
2708 avolid = entry.volumeId[voltype];
2709 } else if (entry.volumeId[voltype] != 0
2710 && entry.volumeId[voltype] != avolid) {
2711 avolid = entry.volumeId[voltype];
2714 /* A file name was specified - check if volume is on another partition */
2715 vcode = GetVolumeInfo(avolid, &Oserver, &Opart, &Otype, &Oentry);
2719 vcode = VLDB_IsSameAddrs(Oserver, aserver, &err);
2722 "Failed to get info about server's %d address(es) from vlserver (err=%d); aborting call!\n",
2726 if (!vcode || (Opart != apart))
2729 if (aoverwrite == ASK) {
2730 if (strcmp(afilename, "") == 0) { /* The file is from standard in */
2732 "Volume exists and no -overwrite option specified; Aborting restore command\n");
2736 /* Ask what to do */
2737 if (vol_elsewhere) {
2739 "The volume %s %u already exists on a different server/part\n",
2740 volname, entry.volumeId[voltype]);
2742 "Do you want to do a full restore or abort? [fa](a): ");
2745 "The volume %s %u already exists in the VLDB\n",
2746 volname, entry.volumeId[voltype]);
2748 "Do you want to do a full/incremental restore or abort? [fia](a): ");
2751 while (!(dc == EOF || dc == '\n'))
2752 dc = getchar(); /* goto end of line */
2753 if ((c == 'f') || (c == 'F'))
2755 else if ((c == 'i') || (c == 'I'))
2761 if (aoverwrite == ABORT) {
2762 fprintf(STDERR, "Volume exists; Aborting restore command\n");
2764 } else if (aoverwrite == FULL) {
2765 restoreflags = RV_FULLRST;
2767 "Volume exists; Will delete and perform full restore\n");
2768 } else if (aoverwrite == INC) {
2770 if (vol_elsewhere) {
2772 "%s volume %lu already exists on a different server/part; not allowed\n",
2773 readonly ? "RO" : "RW", (unsigned long)avolid);
2779 restoreflags |= RV_OFFLINE;
2781 restoreflags |= RV_RDONLY;
2783 UV_RestoreVolume(aserver, apart, avolid, avolname, restoreflags,
2784 WriteData, afilename);
2786 PrintDiagnostics("restore", code);
2789 MapPartIdIntoName(apart, apartName);
2792 * patch typo here - originally "parms[1]", should be "parms[0]"
2795 fprintf(STDOUT, "Restored volume %s on %s %s\n", avolname,
2796 as->parms[0].items->data, apartName);
2802 register struct cmd_syndesc *as;
2805 afs_int32 avolid, code, err;
2807 avolid = vsu_GetVolumeID(as->parms[0].items->data, cstruct, &err);
2810 PrintError("", err);
2812 fprintf(STDERR, "vos: can't find volume '%s'\n",
2813 as->parms[0].items->data);
2817 code = UV_LockRelease(avolid);
2819 PrintDiagnostics("unlock", code);
2822 fprintf(STDOUT, "Released lock on vldb entry for volume %s\n",
2823 as->parms[0].items->data);
2829 register struct cmd_syndesc *as;
2831 afs_int32 avolid, aserver, apart, code, err;
2832 char apartName[10], avolname[VOLSER_MAXVOLNAME + 1];
2834 vsu_ExtractName(avolname, as->parms[2].items->data);;
2835 avolid = vsu_GetVolumeID(avolname, cstruct, &err);
2838 PrintError("", err);
2840 fprintf(STDERR, "vos: can't find volume '%s'\n",
2841 as->parms[2].items->data);
2844 aserver = GetServer(as->parms[0].items->data);
2846 fprintf(STDERR, "vos: server '%s' not found in host table\n",
2847 as->parms[0].items->data);
2850 apart = volutil_GetPartitionID(as->parms[1].items->data);
2852 fprintf(STDERR, "vos: could not interpret partition name '%s'\n",
2853 as->parms[1].items->data);
2856 if (!IsPartValid(apart, aserver, &code)) { /*check for validity of the partition */
2858 PrintError("", code);
2861 "vos : partition %s does not exist on the server\n",
2862 as->parms[1].items->data);
2865 code = UV_AddSite(aserver, apart, avolid);
2867 PrintDiagnostics("addsite", code);
2870 MapPartIdIntoName(apart, apartName);
2871 fprintf(STDOUT, "Added replication site %s %s for volume %s\n",
2872 as->parms[0].items->data, apartName, as->parms[2].items->data);
2878 register struct cmd_syndesc *as;
2881 afs_int32 avolid, aserver, apart, code, err;
2882 char apartName[10], avolname[VOLSER_MAXVOLNAME + 1];
2884 vsu_ExtractName(avolname, as->parms[2].items->data);
2885 avolid = vsu_GetVolumeID(avolname, cstruct, &err);
2888 PrintError("", err);
2890 fprintf(STDERR, "vos: can't find volume '%s'\n",
2891 as->parms[2].items->data);
2894 aserver = GetServer(as->parms[0].items->data);
2896 fprintf(STDERR, "vos: server '%s' not found in host table\n",
2897 as->parms[0].items->data);
2900 apart = volutil_GetPartitionID(as->parms[1].items->data);
2902 fprintf(STDERR, "vos: could not interpret partition name '%s'\n",
2903 as->parms[1].items->data);
2907 *skip the partition validity check, since it is possible that the partition
2908 *has since been decomissioned.
2911 if (!IsPartValid(apart,aserver,&code)){
2912 if(code) PrintError("",code);
2913 else fprintf(STDERR,"vos : partition %s does not exist on the server\n",as->parms[1].items->data);
2917 code = UV_RemoveSite(aserver, apart, avolid);
2919 PrintDiagnostics("remsite", code);
2922 MapPartIdIntoName(apart, apartName);
2923 fprintf(STDOUT, "Removed replication site %s %s for volume %s\n",
2924 as->parms[0].items->data, apartName, as->parms[2].items->data);
2930 register struct cmd_syndesc *as;
2932 afs_int32 avolid, aserver, apart, code, err;
2935 avolid = vsu_GetVolumeID(as->parms[2].items->data, cstruct, &err);
2938 PrintError("", err);
2940 fprintf(STDERR, "vos: can't find volume '%s'\n",
2941 as->parms[2].items->data);
2944 aserver = GetServer(as->parms[0].items->data);
2946 fprintf(STDERR, "vos: server '%s' not found in host table\n",
2947 as->parms[0].items->data);
2950 apart = volutil_GetPartitionID(as->parms[1].items->data);
2952 fprintf(STDERR, "vos: could not interpret partition name '%s'\n",
2953 as->parms[1].items->data);
2956 if (!IsPartValid(apart, aserver, &code)) { /*check for validity of the partition */
2958 PrintError("", code);
2961 "vos : partition %s does not exist on the server\n",
2962 as->parms[1].items->data);
2965 code = UV_ChangeLocation(aserver, apart, avolid);
2967 PrintDiagnostics("addsite", code);
2970 MapPartIdIntoName(apart, apartName);
2971 fprintf(STDOUT, "Changed location to %s %s for volume %s\n",
2972 as->parms[0].items->data, apartName, as->parms[2].items->data);
2978 register struct cmd_syndesc *as;
2980 afs_int32 aserver, code;
2981 struct partList dummyPartList;
2986 aserver = GetServer(as->parms[0].items->data);
2988 fprintf(STDERR, "vos: server '%s' not found in host table\n",
2989 as->parms[0].items->data);
2994 code = UV_ListPartitions(aserver, &dummyPartList, &cnt);
2996 PrintDiagnostics("listpart", code);
3000 fprintf(STDOUT, "The partitions on the server are:\n");
3001 for (i = 0; i < cnt; i++) {
3002 if (dummyPartList.partFlags[i] & PARTVALID) {
3003 memset(pname, 0, sizeof(pname));
3004 MapPartIdIntoName(dummyPartList.partId[i], pname);
3005 fprintf(STDOUT, " %10s ", pname);
3007 if ((i % 5) == 0 && (i != 0))
3008 fprintf(STDOUT, "\n");
3011 fprintf(STDOUT, "\n");
3012 fprintf(STDOUT, "Total: %d\n", total);
3018 CompareVolName(p1, p2)
3021 volintInfo *arg1, *arg2;
3023 arg1 = (volintInfo *) p1;
3024 arg2 = (volintInfo *) p2;
3025 return (strcmp(arg1->name, arg2->name));
3029 /*------------------------------------------------------------------------
3030 * PRIVATE XCompareVolName
3033 * Comparison routine for volume names coming from an extended
3037 * a_obj1P : Char ptr to first extended vol info object
3038 * a_obj1P : Char ptr to second extended vol info object
3041 * The value of strcmp() on the volume names within the passed
3042 * objects (i,e., -1, 0, or 1).
3045 * Passed to qsort() as the designated comparison routine.
3049 *------------------------------------------------------------------------*/
3052 XCompareVolName(a_obj1P, a_obj2P)
3053 char *a_obj1P, *a_obj2P;
3055 { /*XCompareVolName */
3058 (((struct volintXInfo *)(a_obj1P))->name,
3059 ((struct volintXInfo *)(a_obj2P))->name));
3061 } /*XCompareVolName */
3064 CompareVolID(p1, p2)
3067 volintInfo *arg1, *arg2;
3069 arg1 = (volintInfo *) p1;
3070 arg2 = (volintInfo *) p2;
3071 if (arg1->volid == arg2->volid)
3073 if (arg1->volid > arg2->volid)
3080 /*------------------------------------------------------------------------
3081 * PRIVATE XCompareVolID
3084 * Comparison routine for volume IDs coming from an extended
3088 * a_obj1P : Char ptr to first extended vol info object
3089 * a_obj1P : Char ptr to second extended vol info object
3092 * The value of strcmp() on the volume names within the passed
3093 * objects (i,e., -1, 0, or 1).
3096 * Passed to qsort() as the designated comparison routine.
3100 *------------------------------------------------------------------------*/
3103 XCompareVolID(a_obj1P, a_obj2P)
3104 char *a_obj1P, *a_obj2P;
3106 { /*XCompareVolID */
3108 afs_int32 id1, id2; /*Volume IDs we're comparing */
3110 id1 = ((struct volintXInfo *)(a_obj1P))->volid;
3111 id2 = ((struct volintXInfo *)(a_obj2P))->volid;
3119 } /*XCompareVolID */
3121 /*------------------------------------------------------------------------
3122 * PRIVATE ListVolumes
3125 * Routine used to list volumes, contacting the Volume Server
3126 * directly, bypassing the VLDB.
3129 * as : Ptr to parsed command line arguments.
3132 * 0 Successful operation
3135 * Nothing interesting.
3139 *------------------------------------------------------------------------*/
3143 register struct cmd_syndesc *as;
3145 afs_int32 apart, int32list, fast;
3146 afs_int32 aserver, code;
3147 volintInfo *pntr, *oldpntr;
3151 volintXInfo *xInfoP, *origxInfoP; /*Ptr to current/orig extended vol info */
3152 int wantExtendedInfo; /*Do we want extended vol info? */
3155 struct partList dummyPartList;
3163 if (as->parms[3].items)
3165 if (as->parms[4].items)
3169 if (as->parms[2].items)
3175 if (as->parms[5].items) {
3177 * We can't coexist with the fast flag.
3181 "vos: Can't use the -fast and -extended flags together\n");
3186 * We need to turn on ``long'' listings to get the full effect.
3188 wantExtendedInfo = 1;
3191 wantExtendedInfo = 0;
3192 if (as->parms[1].items) {
3193 apart = volutil_GetPartitionID(as->parms[1].items->data);
3195 fprintf(STDERR, "vos: could not interpret partition name '%s'\n",
3196 as->parms[1].items->data);
3199 dummyPartList.partId[0] = apart;
3200 dummyPartList.partFlags[0] = PARTVALID;
3203 aserver = GetServer(as->parms[0].items->data);
3205 fprintf(STDERR, "vos: server '%s' not found in host table\n",
3206 as->parms[0].items->data);
3211 if (!IsPartValid(apart, aserver, &code)) { /*check for validity of the partition */
3213 PrintError("", code);
3216 "vos : partition %s does not exist on the server\n",
3217 as->parms[1].items->data);
3221 code = UV_ListPartitions(aserver, &dummyPartList, &cnt);
3223 PrintDiagnostics("listvol", code);
3227 for (i = 0; i < cnt; i++) {
3228 if (dummyPartList.partFlags[i] & PARTVALID) {
3229 if (wantExtendedInfo)
3231 UV_XListVolumes(aserver, dummyPartList.partId[i], all,
3235 UV_ListVolumes(aserver, dummyPartList.partId[i], all,
3238 PrintDiagnostics("listvol", code);
3243 if (wantExtendedInfo) {
3244 origxInfoP = xInfoP;
3245 base = (char *)xInfoP;
3248 base = (char *)pntr;
3252 if (wantExtendedInfo)
3253 qsort(base, count, sizeof(volintXInfo), XCompareVolName);
3255 qsort(base, count, sizeof(volintInfo), CompareVolName);
3257 if (wantExtendedInfo)
3258 qsort(base, count, sizeof(volintXInfo), XCompareVolID);
3260 qsort(base, count, sizeof(volintInfo), CompareVolID);
3262 MapPartIdIntoName(dummyPartList.partId[i], pname);
3265 "Total number of volumes on server %s partition %s: %lu \n",
3266 as->parms[0].items->data, pname,
3267 (unsigned long)count);
3268 if (wantExtendedInfo) {
3269 XDisplayVolumes(aserver, dummyPartList.partId[i], origxInfoP,
3270 count, int32list, fast, quiet);
3273 xInfoP = (volintXInfo *) 0;
3275 #ifdef FULL_LISTVOL_SWITCH
3276 if (as->parms[6].items)
3277 DisplayVolumes2(aserver, dummyPartList.partId[i], oldpntr,
3280 #endif /* FULL_LISTVOL_SWITCH */
3281 DisplayVolumes(aserver, dummyPartList.partId[i], oldpntr,
3282 count, int32list, fast, quiet);
3285 pntr = (volintInfo *) 0;
3294 register struct cmd_syndesc *as;
3296 afs_int32 pnum, code; /* part name */
3302 if (as->parms[0].items) {
3303 tserver = GetServer(as->parms[0].items->data);
3305 fprintf(STDERR, "vos: host '%s' not found in host table\n",
3306 as->parms[0].items->data);
3311 if (as->parms[1].items) {
3312 pnum = volutil_GetPartitionID(as->parms[1].items->data);
3314 fprintf(STDERR, "vos: could not interpret partition name '%s'\n",
3315 as->parms[1].items->data);
3318 if (!IsPartValid(pnum, tserver, &code)) { /*check for validity of the partition */
3320 PrintError("", code);
3323 "vos: partition %s does not exist on the server\n",
3324 as->parms[1].items->data);
3331 "The -partition option requires a -server option\n");
3336 if (as->parms[2].items) {
3337 /* Synchronize an individual volume */
3338 volname = as->parms[2].items->data;
3339 code = UV_SyncVolume(tserver, pnum, volname, flags);
3343 "Without a -volume option, the -server option is required\n");
3346 code = UV_SyncVldb(tserver, pnum, flags, 0 /*unused */ );
3350 PrintDiagnostics("syncvldb", code);
3354 /* Print a summary of what we did */
3356 fprintf(STDOUT, "VLDB volume %s synchronized", volname);
3358 fprintf(STDOUT, "VLDB synchronized");
3360 fprintf(STDOUT, " with state of server %s", as->parms[0].items->data);
3363 MapPartIdIntoName(pnum, part);
3364 fprintf(STDOUT, " partition %s\n", part);
3366 fprintf(STDOUT, "\n");
3373 register struct cmd_syndesc *as;
3376 afs_int32 pnum, code; /* part name */
3381 tserver = GetServer(as->parms[0].items->data);
3383 fprintf(STDERR, "vos: host '%s' not found in host table\n",
3384 as->parms[0].items->data);
3387 if (as->parms[1].items) {
3388 pnum = volutil_GetPartitionID(as->parms[1].items->data);
3390 fprintf(STDERR, "vos: could not interpret partition name '%s'\n",
3391 as->parms[1].items->data);
3394 if (!IsPartValid(pnum, tserver, &code)) { /*check for validity of the partition */
3396 PrintError("", code);
3399 "vos : partition %s does not exist on the server\n",
3400 as->parms[1].items->data);
3408 code = UV_SyncServer(tserver, pnum, flags, 0 /*unused */ );
3410 PrintDiagnostics("syncserv", code);
3414 MapPartIdIntoName(pnum, part);
3415 fprintf(STDOUT, "Server %s partition %s synchronized with VLDB\n",
3416 as->parms[0].items->data, part);
3418 fprintf(STDOUT, "Server %s synchronized with VLDB\n",
3419 as->parms[0].items->data);
3428 struct nvldbentry entry;
3431 /* The vlserver will handle names with the .readonly
3432 * and .backup extension as well as volume ids.
3434 vcode = VLDB_GetEntryByName(name, &entry);
3436 PrintError("", vcode);
3439 MapHostToNetwork(&entry);
3440 EnumerateEntry(&entry);
3442 /* Defect #3027: grubby check to handle locked volume.
3443 * If VLOP_ALLOPERS is set, the entry is locked.
3444 * Leave this routine as is, but put in correct check.
3446 if (entry.flags & VLOP_ALLOPERS)
3447 fprintf(STDOUT, " Volume is currently LOCKED \n");
3454 register struct cmd_syndesc *as;
3457 struct nvldbentry entry;
3458 afs_int32 volid, code, server, part, zapbackupid = 0, backupid = 0, err;
3460 if (as->parms[3].items) {
3461 /* force flag is on, use the other version */
3462 return NukeVolume(as);
3465 if (as->parms[4].items) {
3469 volid = vsu_GetVolumeID(as->parms[2].items->data, cstruct, &err);
3472 PrintError("", err);
3474 fprintf(STDERR, "vos: can't find volume '%s'\n",
3475 as->parms[2].items->data);
3478 part = volutil_GetPartitionID(as->parms[1].items->data);
3480 fprintf(STDERR, "vos: could not interpret partition name '%s'\n",
3481 as->parms[1].items->data);
3484 server = GetServer(as->parms[0].items->data);
3486 fprintf(STDERR, "vos: host '%s' not found in host table\n",
3487 as->parms[0].items->data);
3490 if (!IsPartValid(part, server, &code)) { /*check for validity of the partition */
3492 PrintError("", code);
3495 "vos : partition %s does not exist on the server\n",
3496 as->parms[1].items->data);
3499 code = VLDB_GetEntryByID(volid, -1, &entry);
3501 if (volid == entry.volumeId[RWVOL])
3502 backupid = entry.volumeId[BACKVOL];
3504 "Warning: Entry for volume number %lu exists in VLDB (but we're zapping it anyway!)\n",
3505 (unsigned long)volid);
3508 volintInfo *pntr = (volintInfo *) 0;
3511 code = UV_ListOneVolume(server, part, volid, &pntr);
3513 if (volid == pntr->parentID)
3514 backupid = pntr->backupID;
3520 code = UV_VolumeZap(server, part, backupid);
3522 PrintDiagnostics("zap", code);
3525 fprintf(STDOUT, "Backup Volume %lu deleted\n",
3526 (unsigned long)backupid);
3529 code = UV_VolumeZap(server, part, volid);
3531 PrintDiagnostics("zap", code);
3534 fprintf(STDOUT, "Volume %lu deleted\n", (unsigned long)volid);
3541 register struct cmd_syndesc *as;
3544 afs_int32 server, code;
3545 transDebugInfo *pntr, *oldpntr;
3550 server = GetServer(as->parms[0].items->data);
3552 fprintf(STDERR, "vos: host '%s' not found in host table\n",
3553 as->parms[0].items->data);
3556 code = UV_VolserStatus(server, &pntr, &count);
3558 PrintDiagnostics("status", code);
3563 fprintf(STDOUT, "No active transactions on %s\n",
3564 as->parms[0].items->data);
3566 fprintf(STDOUT, "Total transactions: %d\n", count);
3568 for (i = 0; i < count; i++) {
3569 /*print out the relevant info */
3570 fprintf(STDOUT, "--------------------------------------\n");
3571 fprintf(STDOUT, "transaction: %lu created: %s",
3572 (unsigned long)pntr->tid, ctime((time_t *) & pntr->time));
3573 if (pntr->returnCode) {
3574 fprintf(STDOUT, "returnCode: %lu\n",
3575 (unsigned long)pntr->returnCode);
3578 fprintf(STDOUT, "attachFlags: ");
3579 switch (pntr->iflags) {
3581 fprintf(STDOUT, "offline ");
3584 fprintf(STDOUT, "busy ");
3587 fprintf(STDOUT, "readonly ");
3590 fprintf(STDOUT, "create ");
3593 fprintf(STDOUT, "create volid ");
3596 fprintf(STDOUT, "\n");
3599 fprintf(STDOUT, "volumeStatus: ");
3600 switch (pntr->vflags) {
3601 case VTDeleteOnSalvage:
3602 fprintf(STDOUT, "deleteOnSalvage ");
3603 case VTOutOfService:
3604 fprintf(STDOUT, "outOfService ");
3606 fprintf(STDOUT, "deleted ");
3608 fprintf(STDOUT, "\n");
3611 fprintf(STDOUT, "transactionFlags: ");
3612 fprintf(STDOUT, "delete\n");
3614 MapPartIdIntoName(pntr->partition, pname);
3615 fprintf(STDOUT, "volume: %lu partition: %s procedure: %s\n",
3616 (unsigned long)pntr->volid, pname, pntr->lastProcName);
3617 if (pntr->callValid) {
3619 "packetRead: %lu lastReceiveTime: %d packetSend: %lu lastSendTime: %d\n",
3620 (unsigned long)pntr->readNext, pntr->lastReceiveTime,
3621 (unsigned long)pntr->transmitNext, pntr->lastSendTime);
3624 fprintf(STDOUT, "--------------------------------------\n");
3625 fprintf(STDOUT, "\n");
3634 register struct cmd_syndesc *as;
3636 afs_int32 code1, code2, code;
3637 struct nvldbentry entry;
3639 code1 = VLDB_GetEntryByName(as->parms[0].items->data, &entry);
3641 fprintf(STDERR, "vos: Could not find entry for volume %s\n",
3642 as->parms[0].items->data);
3645 code2 = VLDB_GetEntryByName(as->parms[1].items->data, &entry);
3646 if ((!code1) && (!code2)) { /*the newname already exists */
3647 fprintf(STDERR, "vos: volume %s already exists\n",
3648 as->parms[1].items->data);
3652 if (code1 && code2) {
3653 fprintf(STDERR, "vos: Could not find entry for volume %s or %s\n",
3654 as->parms[0].items->data, as->parms[1].items->data);
3657 if (!VolNameOK(as->parms[0].items->data)) {
3659 "Illegal volume name %s, should not end in .readonly or .backup\n",
3660 as->parms[0].items->data);
3663 if (!ISNAMEVALID(as->parms[1].items->data)) {
3665 "vos: the new volume name %s exceeds the size limit of %d\n",
3666 as->parms[1].items->data, VOLSER_OLDMAXVOLNAME - 10);
3669 if (!VolNameOK(as->parms[1].items->data)) {
3671 "Illegal volume name %s, should not end in .readonly or .backup\n",
3672 as->parms[1].items->data);
3675 if (IsNumeric(as->parms[1].items->data)) {
3676 fprintf(STDERR, "Illegal volume name %s, should not be a number\n",
3677 as->parms[1].items->data);
3680 MapHostToNetwork(&entry);
3682 UV_RenameVolume(&entry, as->parms[0].items->data,
3683 as->parms[1].items->data);
3685 PrintDiagnostics("rename", code);
3688 fprintf(STDOUT, "Renamed volume %s to %s\n", as->parms[0].items->data,
3689 as->parms[1].items->data);
3693 GetVolumeInfo(volid, server, part, voltype, rentry)
3694 afs_int32 *server, volid, *part, *voltype;
3695 register struct nvldbentry *rentry;
3700 vcode = VLDB_GetEntryByID(volid, -1, rentry);
3703 "Could not fetch the entry for volume %lu from VLDB \n",
3704 (unsigned long)volid);
3705 PrintError("", vcode);
3708 MapHostToNetwork(rentry);
3709 if (volid == rentry->volumeId[ROVOL]) {
3711 for (i = 0; i < rentry->nServers; i++) {
3712 if ((index == -1) && (rentry->serverFlags[i] & ITSROVOL)
3713 && !(rentry->serverFlags[i] & RO_DONTUSE))
3718 "RO volume is not found in VLDB entry for volume %lu\n",
3719 (unsigned long)volid);
3723 *server = rentry->serverNumber[index];
3724 *part = rentry->serverPartition[index];
3728 index = Lp_GetRwIndex(rentry);
3731 "RW Volume is not found in VLDB entry for volume %lu\n",
3732 (unsigned long)volid);
3735 if (volid == rentry->volumeId[RWVOL]) {
3737 *server = rentry->serverNumber[index];
3738 *part = rentry->serverPartition[index];
3741 if (volid == rentry->volumeId[BACKVOL]) {
3743 *server = rentry->serverNumber[index];
3744 *part = rentry->serverPartition[index];
3748 "unexpected volume type for volume %lu\n",
3749 (unsigned long)volid);
3755 register struct cmd_syndesc *as;
3761 struct VldbListByAttributes attributes;
3762 nbulkentries arrayEntries;
3763 register struct nvldbentry *vllist;
3764 struct cmd_item *itp;
3767 char prefix[VOLSER_MAXVOLNAME + 1];
3769 afs_int32 totalBack = 0, totalFail = 0, err;
3771 if (as->parms[0].items) { /* -id */
3772 if (as->parms[1].items || as->parms[2].items || as->parms[3].items) {
3774 "You cannot use -server, -partition, or -prefix with the -id argument\n");
3777 for (itp = as->parms[0].items; itp; itp = itp->next) {
3778 avolid = vsu_GetVolumeID(itp->data, cstruct, &err);
3781 PrintError("", err);
3783 fprintf(STDERR, "vos: can't find volume '%s'\n",
3787 if (as->parms[4].items) { /* -noexecute */
3788 fprintf(STDOUT, "Would have deleted VLDB entry for %s \n",
3793 vcode = ubik_Call(VL_DeleteEntry, cstruct, 0, avolid, RWVOL);
3795 fprintf(STDERR, "Could not delete entry for volume %s\n",
3798 "You must specify a RW volume name or ID "
3799 "(the entire VLDB entry will be deleted)\n");
3800 PrintError("", vcode);
3806 fprintf(STDOUT, "Deleted %d VLDB entries\n", totalBack);
3810 if (!as->parms[1].items && !as->parms[2].items && !as->parms[3].items) {
3811 fprintf(STDERR, "You must specify an option\n");
3815 /* Zero out search attributes */
3816 memset(&attributes, 0, sizeof(struct VldbListByAttributes));
3818 if (as->parms[1].items) { /* -prefix */
3819 strncpy(prefix, as->parms[1].items->data, VOLSER_MAXVOLNAME);
3821 if (!as->parms[2].items && !as->parms[3].items) { /* a single entry only */
3823 "You must provide -server with the -prefix argument\n");
3828 if (as->parms[2].items) { /* -server */
3830 aserver = GetServer(as->parms[2].items->data);
3832 fprintf(STDERR, "vos: server '%s' not found in host table\n",
3833 as->parms[2].items->data);
3836 attributes.server = ntohl(aserver);
3837 attributes.Mask |= VLLIST_SERVER;
3840 if (as->parms[3].items) { /* -partition */
3841 if (!as->parms[2].items) {
3843 "You must provide -server with the -partition argument\n");
3846 apart = volutil_GetPartitionID(as->parms[3].items->data);
3848 fprintf(STDERR, "vos: could not interpret partition name '%s'\n",
3849 as->parms[3].items->data);
3852 attributes.partition = apart;
3853 attributes.Mask |= VLLIST_PARTITION;
3856 /* Print status line of what we are doing */
3857 fprintf(STDOUT, "Deleting VLDB entries for ");
3858 if (as->parms[2].items) {
3859 fprintf(STDOUT, "server %s ", as->parms[2].items->data);
3861 if (as->parms[3].items) {
3863 MapPartIdIntoName(apart, pname);
3864 fprintf(STDOUT, "partition %s ", pname);
3867 fprintf(STDOUT, "which are prefixed with %s ", prefix);
3869 fprintf(STDOUT, "\n");
3872 /* Get all the VLDB entries on a server and/or partition */
3873 memset(&arrayEntries, 0, sizeof(arrayEntries));
3874 vcode = VLDB_ListAttributes(&attributes, &nentries, &arrayEntries);
3876 fprintf(STDERR, "Could not access the VLDB for attributes\n");
3877 PrintError("", vcode);
3881 /* Process each entry */
3882 for (j = 0; j < nentries; j++) {
3883 vllist = &arrayEntries.nbulkentries_val[j];
3885 /* It only deletes the RW volumes */
3886 if (strncmp(vllist->name, prefix, strlen(prefix))) {
3889 "Omitting to delete %s due to prefix %s mismatch\n",
3890 vllist->name, prefix);
3897 if (as->parms[4].items) { /* -noexecute */
3898 fprintf(STDOUT, "Would have deleted VLDB entry for %s \n",
3904 /* Only matches the RW volume name */
3905 avolid = vllist->volumeId[RWVOL];
3906 vcode = ubik_Call(VL_DeleteEntry, cstruct, 0, avolid, RWVOL);
3908 fprintf(STDOUT, "Could not delete VDLB entry for %s\n",
3911 PrintError("", vcode);
3916 fprintf(STDOUT, "Deleted VLDB entry for %s \n", vllist->name);
3921 fprintf(STDOUT, "----------------------\n");
3923 "Total VLDB entries deleted: %lu; failed to delete: %lu\n",
3924 (unsigned long)totalBack, (unsigned long)totalFail);
3925 if (arrayEntries.nbulkentries_val)
3926 free(arrayEntries.nbulkentries_val);
3932 CompareVldbEntryByName(p1, p2)
3935 struct nvldbentry *arg1, *arg2;
3937 arg1 = (struct nvldbentry *)p1;
3938 arg2 = (struct nvldbentry *)p2;
3939 return (strcmp(arg1->name, arg2->name));
3943 static int CompareVldbEntry(p1,p2)
3946 struct nvldbentry *arg1,*arg2;
3949 char comp1[100],comp2[100];
3950 char temp1[20],temp2[20];
3952 arg1 = (struct nvldbentry *)p1;
3953 arg2 = (struct nvldbentry *)p2;
3957 for(i = 0; i < arg1->nServers; i++)
3958 if(arg1->serverFlags[i] & ITSRWVOL) pos1 = i;
3959 for(i = 0; i < arg2->nServers; i++)
3960 if(arg2->serverFlags[i] & ITSRWVOL) pos2 = i;
3961 if(pos1 == -1 || pos2 == -1){
3965 sprintf(comp1,"%10u",arg1->serverNumber[pos1]);
3966 sprintf(comp2,"%10u",arg2->serverNumber[pos2]);
3967 sprintf(temp1,"%10u",arg1->serverPartition[pos1]);
3968 sprintf(temp2,"%10u",arg2->serverPartition[pos2]);
3969 strcat(comp1,temp1);
3970 strcat(comp2,temp2);
3971 strcat(comp1,arg1->name);
3972 strcat(comp1,arg2->name);
3973 return(strcmp(comp1,comp2));
3980 struct cmd_syndesc *as;
3983 afs_int32 aserver, code;
3985 struct VldbListByAttributes attributes;
3986 nbulkentries arrayEntries;
3987 struct nvldbentry *vllist, *tarray = 0, *ttarray;
3988 afs_int32 centries, nentries = 0, tarraysize, parraysize;
3991 int quiet, sort, lock;
3992 afs_int32 thisindex, nextindex;
3997 attributes.Mask = 0;
3998 lock = (as->parms[3].items ? 1 : 0); /* -lock flag */
3999 quiet = (as->parms[4].items ? 1 : 0); /* -quit flag */
4000 sort = (as->parms[5].items ? 0 : 1); /* -nosort flag */
4002 /* If the volume name is given, Use VolumeInfoCmd to look it up
4003 * and not ListAttributes.
4005 if (as->parms[0].items) {
4008 "vos: illegal use of '-locked' switch, need to specify server and/or partition\n");
4011 code = VolumeInfoCmd(as->parms[0].items->data);
4013 PrintError("", code);
4019 /* Server specified */
4020 if (as->parms[1].items) {
4021 aserver = GetServer(as->parms[1].items->data);
4023 fprintf(STDERR, "vos: server '%s' not found in host table\n",
4024 as->parms[1].items->data);
4027 attributes.server = ntohl(aserver);
4028 attributes.Mask |= VLLIST_SERVER;
4031 /* Partition specified */
4032 if (as->parms[2].items) {
4033 apart = volutil_GetPartitionID(as->parms[2].items->data);
4035 fprintf(STDERR, "vos: could not interpret partition name '%s'\n",
4036 as->parms[2].items->data);
4039 attributes.partition = apart;
4040 attributes.Mask |= VLLIST_PARTITION;
4044 attributes.Mask |= VLLIST_FLAG;
4045 attributes.flag = VLOP_ALLOPERS;
4048 /* Print header information */
4050 MapPartIdIntoName(apart, pname);
4051 fprintf(STDOUT, "VLDB entries for %s %s%s%s %s\n",
4052 (as->parms[1].items ? "server" : "all"),
4053 (as->parms[1].items ? as->parms[1].items->data : "servers"),
4054 (as->parms[2].items ? " partition " : ""),
4055 (as->parms[2].items ? pname : ""),
4056 (lock ? "which are locked:" : ""));
4059 for (thisindex = 0; (thisindex != -1); thisindex = nextindex) {
4060 memset(&arrayEntries, 0, sizeof(arrayEntries));
4065 VLDB_ListAttributesN2(&attributes, 0, thisindex, ¢ries,
4066 &arrayEntries, &nextindex);
4067 if (vcode == RXGEN_OPCODE) {
4068 /* Vlserver not running with ListAttributesN2. Fall back */
4070 VLDB_ListAttributes(&attributes, ¢ries, &arrayEntries);
4074 fprintf(STDERR, "Could not access the VLDB for attributes\n");
4075 PrintError("", vcode);
4078 nentries += centries;
4080 /* We don't sort, so just print the entries now */
4082 for (j = 0; j < centries; j++) { /* process each entry */
4083 vllist = &arrayEntries.nbulkentries_val[j];
4084 MapHostToNetwork(vllist);
4085 EnumerateEntry(vllist);
4087 if (vllist->flags & VLOP_ALLOPERS)
4088 fprintf(STDOUT, " Volume is currently LOCKED \n");
4092 /* So we sort. First we must collect all the entries and keep
4095 else if (centries > 0) {
4097 /* steal away the first bulk entries array */
4098 tarray = (struct nvldbentry *)arrayEntries.nbulkentries_val;
4099 tarraysize = centries * sizeof(struct nvldbentry);
4100 arrayEntries.nbulkentries_val = 0;
4102 /* Grow the tarray to keep the extra entries */
4103 parraysize = (centries * sizeof(struct nvldbentry));
4105 (struct nvldbentry *)realloc(tarray,
4106 tarraysize + parraysize);
4109 "Could not allocate enough space for the VLDB entries\n");
4115 memcpy(((char *)tarray) + tarraysize,
4116 (char *)arrayEntries.nbulkentries_val, parraysize);
4117 tarraysize += parraysize;
4121 /* Free the bulk array */
4122 if (arrayEntries.nbulkentries_val) {
4123 free(arrayEntries.nbulkentries_val);
4124 arrayEntries.nbulkentries_val = 0;
4128 /* Here is where we now sort all the entries and print them */
4129 if (sort && (nentries > 0)) {
4130 qsort((char *)tarray, nentries, sizeof(struct nvldbentry),
4131 CompareVldbEntryByName);
4132 for (vllist = tarray, j = 0; j < nentries; j++, vllist++) {
4133 MapHostToNetwork(vllist);
4134 EnumerateEntry(vllist);
4136 if (vllist->flags & VLOP_ALLOPERS)
4137 fprintf(STDOUT, " Volume is currently LOCKED \n");
4143 fprintf(STDOUT, "\nTotal entries: %lu\n", (unsigned long)nentries);
4151 register struct cmd_syndesc *as;
4153 afs_int32 apart = 0, avolid;
4154 afs_int32 aserver = 0, code, aserver1, apart1;
4156 struct VldbListByAttributes attributes;
4157 nbulkentries arrayEntries;
4158 register struct nvldbentry *vllist;
4162 int seenprefix, seenxprefix, exclude, ex, exp, noaction;
4163 afs_int32 totalBack = 0;
4164 afs_int32 totalFail = 0;
4165 int previdx = -1, error, same;
4167 struct cmd_item *ti;
4171 memset(&attributes, 0, sizeof(struct VldbListByAttributes));
4172 attributes.Mask = 0;
4174 seenprefix = (as->parms[0].items ? 1 : 0);
4175 exclude = (as->parms[3].items ? 1 : 0);
4176 seenxprefix = (as->parms[4].items ? 1 : 0);
4177 noaction = (as->parms[5].items ? 1 : 0);
4179 if (as->parms[1].items) { /* -server */
4180 aserver = GetServer(as->parms[1].items->data);
4182 fprintf(STDERR, "vos: server '%s' not found in host table\n",
4183 as->parms[1].items->data);
4186 attributes.server = ntohl(aserver);
4187 attributes.Mask |= VLLIST_SERVER;
4190 if (as->parms[2].items) { /* -partition */
4191 apart = volutil_GetPartitionID(as->parms[2].items->data);
4193 fprintf(STDERR, "vos: could not interpret partition name '%s'\n",
4194 as->parms[2].items->data);
4197 attributes.partition = apart;
4198 attributes.Mask |= VLLIST_PARTITION;
4201 /* Check to make sure the prefix and xprefix expressions compile ok */
4203 for (ti = as->parms[0].items; ti; ti = ti->next) {
4204 if (strncmp(ti->data, "^", 1) == 0) {
4205 #ifdef HAVE_POSIX_REGEX
4209 code = regcomp(&re, ti->data, REG_NOSUB);
4211 regerror(code, &re, errbuf, sizeof errbuf);
4213 "Unrecognizable -prefix regular expression: '%s': %s\n",
4219 ccode = (char *)re_comp(ti->data);
4222 "Unrecognizable -prefix regular expression: '%s': %s\n",
4231 for (ti = as->parms[4].items; ti; ti = ti->next) {
4232 if (strncmp(ti->data, "^", 1) == 0) {
4233 #ifdef HAVE_POSIX_REGEX
4237 code = regcomp(&re, ti->data, REG_NOSUB);
4239 regerror(code, &re, errbuf, sizeof errbuf);
4241 "Unrecognizable -xprefix regular expression: '%s': %s\n",
4247 ccode = (char *)re_comp(ti->data);
4250 "Unrecognizable -xprefix regular expression: '%s': %s\n",
4259 memset(&arrayEntries, 0, sizeof(arrayEntries)); /* initialize to hint the stub to alloc space */
4260 vcode = VLDB_ListAttributes(&attributes, &nentries, &arrayEntries);
4262 fprintf(STDERR, "Could not access the VLDB for attributes\n");
4263 PrintError("", vcode);
4267 if (as->parms[1].items || as->parms[2].items || verbose) {
4268 fprintf(STDOUT, "%s up volumes",
4269 (noaction ? "Would have backed" : "Backing"));
4271 if (as->parms[1].items) {
4272 fprintf(STDOUT, " on server %s", as->parms[1].items->data);
4273 } else if (as->parms[2].items) {
4274 fprintf(STDOUT, " for all servers");
4277 if (as->parms[2].items) {
4278 MapPartIdIntoName(apart, pname);
4279 fprintf(STDOUT, " partition %s", pname);
4282 if (seenprefix || (!seenprefix && seenxprefix)) {
4283 ti = (seenprefix ? as->parms[0].items : as->parms[4].items);
4284 ex = (seenprefix ? exclude : !exclude);
4285 exp = (strncmp(ti->data, "^", 1) == 0);
4286 fprintf(STDOUT, " which %smatch %s '%s'", (ex ? "do not " : ""),
4287 (exp ? "expression" : "prefix"), ti->data);
4288 for (ti = ti->next; ti; ti = ti->next) {
4289 exp = (strncmp(ti->data, "^", 1) == 0);
4290 printf(" %sor %s '%s'", (ex ? "n" : ""),
4291 (exp ? "expression" : "prefix"), ti->data);
4295 if (seenprefix && seenxprefix) {
4296 ti = as->parms[4].items;
4297 exp = (strncmp(ti->data, "^", 1) == 0);
4298 fprintf(STDOUT, " %swhich match %s '%s'",
4299 (exclude ? "adding those " : "removing those "),
4300 (exp ? "expression" : "prefix"), ti->data);
4301 for (ti = ti->next; ti; ti = ti->next) {
4302 exp = (strncmp(ti->data, "^", 1) == 0);
4303 printf(" or %s '%s'", (exp ? "expression" : "prefix"),
4307 fprintf(STDOUT, " .. ");
4309 fprintf(STDOUT, "\n");
4313 for (j = 0; j < nentries; j++) { /* process each vldb entry */
4314 vllist = &arrayEntries.nbulkentries_val[j];
4317 for (ti = as->parms[0].items; ti; ti = ti->next) {
4318 if (strncmp(ti->data, "^", 1) == 0) {
4319 #ifdef HAVE_POSIX_REGEX
4323 /* XXX -- should just do the compile once! */
4324 code = regcomp(&re, ti->data, REG_NOSUB);
4326 regerror(code, &re, errbuf, sizeof errbuf);
4328 "Error in -prefix regular expression: '%s': %s\n",
4332 match = (regexec(&re, vllist->name, 0, NULL, 0) == 0);
4335 ccode = (char *)re_comp(ti->data);
4338 "Error in -prefix regular expression: '%s': %s\n",
4342 match = (re_exec(vllist->name) == 1);
4346 (strncmp(vllist->name, ti->data, strlen(ti->data)) ==
4356 /* Without the -exclude flag: If it matches the prefix, then
4357 * check if we want to exclude any from xprefix.
4358 * With the -exclude flag: If it matches the prefix, then
4359 * check if we want to add any from xprefix.
4361 if (match && seenxprefix) {
4362 for (ti = as->parms[4].items; ti; ti = ti->next) {
4363 if (strncmp(ti->data, "^", 1) == 0) {
4364 #ifdef HAVE_POSIX_REGEX
4368 /* XXX -- should just do the compile once! */
4369 code = regcomp(&re, ti->data, REG_NOSUB);
4371 regerror(code, &re, errbuf, sizeof errbuf);
4373 "Error in -xprefix regular expression: '%s': %s\n",
4377 if (regexec(&re, vllist->name, 0, NULL, 0) == 0)
4381 ccode = (char *)re_comp(ti->data);
4384 "Error in -xprefix regular expression: '%s': %s\n",
4388 if (re_exec(vllist->name) == 1) {
4394 if (strncmp(vllist->name, ti->data, strlen(ti->data)) ==
4404 match = !match; /* -exclude will reverse the match */
4406 continue; /* Skip if no match */
4408 /* Print list of volumes to backup */
4410 fprintf(STDOUT, " %s\n", vllist->name);
4414 if (!(vllist->flags & RW_EXISTS)) {
4417 "Omitting to backup %s since RW volume does not exist \n",
4419 fprintf(STDOUT, "\n");
4425 avolid = vllist->volumeId[RWVOL];
4426 MapHostToNetwork(vllist);
4427 GetServerAndPart(vllist, RWVOL, &aserver1, &apart1, &previdx);
4428 if (aserver1 == -1 || apart1 == -1) {
4429 fprintf(STDOUT, "could not backup %s, invalid VLDB entry\n",
4435 same = VLDB_IsSameAddrs(aserver, aserver1, &error);
4438 "Failed to get info about server's %d address(es) from vlserver (err=%d); aborting call!\n",
4444 if ((aserver && !same) || (apart && (apart != apart1))) {
4447 "Omitting to backup %s since the RW is in a different location\n",
4453 time_t now = time(0);
4454 fprintf(STDOUT, "Creating backup volume for %s on %s",
4455 vllist->name, ctime(&now));
4459 code = UV_BackupVolume(aserver1, apart1, avolid);
4461 fprintf(STDOUT, "Could not backup %s\n", vllist->name);
4467 fprintf(STDOUT, "\n");
4469 } /* process each vldb entry */
4470 fprintf(STDOUT, "done\n");
4471 fprintf(STDOUT, "Total volumes backed up: %lu; failed to backup: %lu\n",
4472 (unsigned long)totalBack, (unsigned long)totalFail);
4474 if (arrayEntries.nbulkentries_val)
4475 free(arrayEntries.nbulkentries_val);
4481 register struct cmd_syndesc *as;
4484 afs_int32 aserver, code;
4486 struct VldbListByAttributes attributes;
4487 nbulkentries arrayEntries;
4488 register struct nvldbentry *vllist;
4497 attributes.Mask = 0;
4499 if (as->parms[0].items) { /* server specified */
4500 aserver = GetServer(as->parms[0].items->data);
4502 fprintf(STDERR, "vos: server '%s' not found in host table\n",
4503 as->parms[0].items->data);
4506 attributes.server = ntohl(aserver);
4507 attributes.Mask |= VLLIST_SERVER;
4509 if (as->parms[1].items) { /* partition specified */
4510 apart = volutil_GetPartitionID(as->parms[1].items->data);
4512 fprintf(STDERR, "vos: could not interpret partition name '%s'\n",
4513 as->parms[1].items->data);
4516 if (!IsPartValid(apart, aserver, &code)) { /*check for validity of the partition */
4518 PrintError("", code);
4521 "vos : partition %s does not exist on the server\n",
4522 as->parms[1].items->data);
4525 attributes.partition = apart;
4526 attributes.Mask |= VLLIST_PARTITION;
4528 attributes.flag = VLOP_ALLOPERS;
4529 attributes.Mask |= VLLIST_FLAG;
4530 memset(&arrayEntries, 0, sizeof(arrayEntries)); /*initialize to hint the stub to alloc space */
4531 vcode = VLDB_ListAttributes(&attributes, &nentries, &arrayEntries);
4533 fprintf(STDERR, "Could not access the VLDB for attributes\n");
4534 PrintError("", vcode);
4537 for (j = 0; j < nentries; j++) { /* process each entry */
4538 vllist = &arrayEntries.nbulkentries_val[j];
4539 volid = vllist->volumeId[RWVOL];
4541 ubik_Call(VL_ReleaseLock, cstruct, 0, volid, -1,
4542 LOCKREL_OPCODE | LOCKREL_AFSID | LOCKREL_TIMESTAMP);
4544 fprintf(STDERR, "Could not unlock entry for volume %s\n",
4546 PrintError("", vcode);
4551 MapPartIdIntoName(apart, pname);
4554 "Could not lock %lu VLDB entries of %lu locked entries\n",
4555 (unsigned long)totalE, (unsigned long)nentries);
4557 if (as->parms[0].items) {
4559 "Unlocked all the VLDB entries for volumes on server %s ",
4560 as->parms[0].items->data);
4561 if (as->parms[1].items) {
4562 MapPartIdIntoName(apart, pname);
4563 fprintf(STDOUT, "partition %s\n", pname);
4565 fprintf(STDOUT, "\n");
4567 } else if (as->parms[1].items) {
4568 MapPartIdIntoName(apart, pname);
4570 "Unlocked all the VLDB entries for volumes on partition %s on all servers\n",
4575 if (arrayEntries.nbulkentries_val)
4576 free(arrayEntries.nbulkentries_val);
4582 register struct cmd_syndesc *as;
4585 afs_int32 aserver, code;
4587 struct diskPartition partition;
4588 struct partList dummyPartList;
4592 aserver = GetServer(as->parms[0].items->data);
4594 fprintf(STDERR, "vos: server '%s' not found in host table\n",
4595 as->parms[0].items->data);
4598 if (as->parms[1].items) {
4599 apart = volutil_GetPartitionID(as->parms[1].items->data);
4601 fprintf(STDERR, "vos: could not interpret partition name '%s'\n",
4602 as->parms[1].items->data);
4605 dummyPartList.partId[0] = apart;
4606 dummyPartList.partFlags[0] = PARTVALID;
4610 if (!IsPartValid(apart, aserver, &code)) { /*check for validity of the partition */
4612 PrintError("", code);
4615 "vos : partition %s does not exist on the server\n",
4616 as->parms[1].items->data);
4620 code = UV_ListPartitions(aserver, &dummyPartList, &cnt);
4622 PrintDiagnostics("listpart", code);
4626 for (i = 0; i < cnt; i++) {
4627 if (dummyPartList.partFlags[i] & PARTVALID) {
4628 MapPartIdIntoName(dummyPartList.partId[i], pname);
4629 code = UV_PartitionInfo(aserver, pname, &partition);
4631 fprintf(STDERR, "Could not get information on partition %s\n",
4633 PrintError("", code);
4637 "Free space on partition %s: %d K blocks out of total %d\n",
4638 pname, partition.free, partition.minFree);
4646 register struct cmd_syndesc *as;
4649 afs_int32 ip1, ip2, vcode;
4652 ip1 = GetServer(as->parms[0].items->data);
4654 fprintf(STDERR, "vos: invalid host address\n");
4658 if ((as->parms[1].items && as->parms[2].items)
4659 || (!as->parms[1].items && !as->parms[2].items)) {
4661 "vos: Must specify either '-newaddr <addr>' or '-remove' flag\n");
4665 if (as->parms[1].items) {
4666 ip2 = GetServer(as->parms[1].items->data);
4668 fprintf(STDERR, "vos: invalid host address\n");
4672 /* Play a trick here. If we are removing an address, ip1 will be -1
4673 * and ip2 will be the original address. This switch prevents an
4674 * older revision vlserver from removing the IP address.
4681 vcode = ubik_Call_New(VL_ChangeAddr, cstruct, 0, ntohl(ip1), ntohl(ip2));
4684 fprintf(STDERR, "Could not remove server %s from the VLDB\n",
4685 as->parms[0].items->data);
4686 if (vcode == VL_NOENT) {
4688 "vlserver does not support the remove flag or ");
4691 fprintf(STDERR, "Could not change server %s to server %s\n",
4692 as->parms[0].items->data, as->parms[1].items->data);
4694 PrintError("", vcode);
4699 fprintf(STDOUT, "Removed server %s from the VLDB\n",
4700 as->parms[0].items->data);
4702 fprintf(STDOUT, "Changed server %s to server %s\n",
4703 as->parms[0].items->data, as->parms[1].items->data);
4709 print_addrs(const bulkaddrs * addrs, const afsUUID * m_uuid, int nentries,
4710 int print, int noresolve)
4714 struct VLCallBack vlcb;
4717 ListAddrByAttributes m_attrs;
4718 afs_int32 m_nentries, *m_addrp;
4719 afs_int32 base, index;
4723 afsUUID_to_string(m_uuid, buf, sizeof(buf));
4724 printf("UUID: %s\n", buf);
4727 /* print out the list of all the server */
4728 addrp = (afs_int32 *) addrs->bulkaddrs_val;
4729 for (i = 0; i < nentries; i++, addrp++) {
4730 /* If it is a multihomed address, then we will need to
4731 * get the addresses for this multihomed server from
4732 * the vlserver and print them.
4734 if (((*addrp & 0xff000000) == 0xff000000) && ((*addrp) & 0xffff)) {
4735 /* Get the list of multihomed fileservers */
4736 base = (*addrp >> 16) & 0xff;
4737 index = (*addrp) & 0xffff;
4739 if ((base >= 0) && (base <= VL_MAX_ADDREXTBLKS) && (index >= 1)
4740 && (index <= VL_MHSRV_PERBLK)) {
4741 m_attrs.Mask = VLADDR_INDEX;
4742 m_attrs.index = (base * VL_MHSRV_PERBLK) + index;
4744 m_addrs.bulkaddrs_val = 0;
4745 m_addrs.bulkaddrs_len = 0;
4747 ubik_Call(VL_GetAddrsU, cstruct, 0, &m_attrs, &m_uuid,
4748 &vlcb, &m_nentries, &m_addrs);
4751 "vos: could not list the multi-homed server addresses\n");
4752 PrintError("", vcode);
4755 /* Print the list */
4756 m_addrp = (afs_int32 *) m_addrs.bulkaddrs_val;
4757 for (j = 0; j < m_nentries; j++, m_addrp++) {
4758 *m_addrp = htonl(*m_addrp);
4761 printf("%s ", afs_inet_ntoa_r(*m_addrp, hoststr));
4763 printf("%s ", hostutil_GetNameByINet(*m_addrp));
4767 printf("<unknown>\n");
4776 /* Otherwise, it is a non-multihomed entry and contains
4777 * the IP address of the server - print it.
4779 *addrp = htonl(*addrp);
4782 printf("%s\n", afs_inet_ntoa_r(*addrp, hoststr));
4784 printf("%s\n", hostutil_GetNameByINet(*addrp));
4796 register struct cmd_syndesc *as;
4799 afs_int32 i, noresolve = 0, printuuid = 0;
4800 struct VLCallBack vlcb;
4803 ListAddrByAttributes m_attrs;
4804 afsUUID m_uuid, askuuid;
4805 afs_int32 m_nentries;
4807 memset(&m_attrs, 0, sizeof(struct ListAddrByAttributes));
4808 m_attrs.Mask = VLADDR_INDEX;
4810 memset(&m_addrs, 0, sizeof(bulkaddrs));
4811 memset(&askuuid, 0, sizeof(afsUUID));
4812 if (as->parms[0].items) {
4814 afsUUID_from_string(as->parms[0].items->data, &askuuid);
4815 m_attrs.Mask = VLADDR_UUID;
4816 m_attrs.uuid = askuuid;
4818 if (as->parms[1].items) {
4822 he = hostutil_GetHostByName((char *)as->parms[1].items->data);
4824 fprintf(stderr, "Can't get host info for '%s'\n",
4825 as->parms[1].items->data);
4828 memcpy(&saddr, he->h_addr, 4);
4829 m_attrs.Mask = VLADDR_IPADDR;
4830 m_attrs.ipaddr = ntohl(saddr);
4832 if (as->parms[2].items) {
4835 if (as->parms[3].items) {
4839 m_addrs.bulkaddrs_val = 0;
4840 m_addrs.bulkaddrs_len = 0;
4843 ubik_Call_New(VL_GetAddrs, cstruct, 0, 0, 0, &vlcb, &nentries,
4846 fprintf(STDERR, "vos: could not list the server addresses\n");
4847 PrintError("", vcode);
4852 m_addrs.bulkaddrs_val = 0;
4853 m_addrs.bulkaddrs_len = 0;
4859 ubik_Call_New(VL_GetAddrsU, cstruct, 0, &m_attrs, &m_uuid,
4860 &vlcb, &m_nentries, &m_addrs);
4861 if (vcode == VL_NOENT) {
4867 if (vcode == VL_INDEXERANGE) {
4872 fprintf(STDERR, "vos: could not list the server addresses\n");
4873 PrintError("", vcode);
4877 print_addrs(&m_addrs, &m_uuid, m_nentries, printuuid, noresolve);
4880 if ((as->parms[1].items) || (as->parms[0].items) || (i > nentries))
4889 register struct cmd_syndesc *as;
4892 afs_int32 avolid, vcode, err;
4894 avolid = vsu_GetVolumeID(as->parms[0].items->data, cstruct, &err);
4897 PrintError("", err);
4899 fprintf(STDERR, "vos: can't find volume '%s'\n",
4900 as->parms[0].items->data);
4903 vcode = ubik_Call(VL_SetLock, cstruct, 0, avolid, -1, VLOP_DELETE);
4905 fprintf(STDERR, "Could not lock VLDB entry for volume %s\n",
4906 as->parms[0].items->data);
4907 PrintError("", vcode);
4910 fprintf(STDOUT, "Locked VLDB entry for volume %s\n",
4911 as->parms[0].items->data);
4917 register struct cmd_syndesc *as;
4920 afs_int32 partition = -1;
4921 afs_int32 server, volid, code, i, same;
4922 struct nvldbentry entry, storeEntry;
4925 afs_int32 rwserver = 0;
4926 afs_int32 rwpartition;
4928 afs_int32 roserver = 0;
4929 afs_int32 ropartition;
4931 struct rx_connection *aconn;
4934 server = GetServer(as->parms[0].items->data);
4936 fprintf(STDERR, "vos: host '%s' not found in host table\n",
4937 as->parms[0].items->data);
4940 partition = volutil_GetPartitionID(as->parms[1].items->data);
4941 if (partition < 0) {
4942 fprintf(STDERR, "vos: could not interpret partition name '%s'\n",
4943 as->parms[1].items->data);
4946 if (!IsPartValid(partition, server, &code)) {
4948 PrintError("", code);
4951 "vos : partition %s does not exist on the server\n",
4952 as->parms[1].items->data);
4955 volid = vsu_GetVolumeID(as->parms[2].items->data, cstruct, &code);
4958 PrintError("", code);
4960 fprintf(STDERR, "Unknown volume ID or name '%s'\n",
4961 as->parms[0].items->data);
4964 if (as->parms[3].items)
4967 vcode = VLDB_GetEntryByID(volid, -1, &entry);
4970 "Could not fetch the entry for volume %lu from VLDB\n",
4971 (unsigned long)volid);
4972 PrintError("convertROtoRW", code);
4976 /* use RO volid even if user specified RW or BK volid */
4978 if (volid != entry.volumeId[ROVOL])
4979 volid = entry.volumeId[ROVOL];
4981 MapHostToNetwork(&entry);
4982 for (i = 0; i < entry.nServers; i++) {
4983 if (entry.serverFlags[i] & ITSRWVOL) {
4985 rwserver = entry.serverNumber[i];
4986 rwpartition = entry.serverPartition[i];
4988 if (entry.serverFlags[i] & ITSROVOL) {
4989 same = VLDB_IsSameAddrs(server, entry.serverNumber[i], &code);
4992 "Failed to get info about server's %d address(es) from vlserver (err=%d); aborting call!\n",
4998 roserver = entry.serverNumber[i];
4999 ropartition = entry.serverPartition[i];
5005 fprintf(STDERR, "Warning: RO volume didn't exist in vldb!\n");
5007 if (ropartition != partition) {
5009 "Warning: RO volume should be in partition %d instead of %d (vldb)\n",
5010 ropartition, partition);
5015 "VLDB indicates that a RW volume exists already on %s in partition %s.\n",
5016 hostutil_GetNameByINet(rwserver),
5017 volutil_PartitionName(rwpartition));
5019 fprintf(STDERR, "Overwrite this VLDB entry? [y|n] (n)\n");
5021 while (!(dc == EOF || dc == '\n'))
5022 dc = getchar(); /* goto end of line */
5023 if ((c != 'y') && (c != 'Y')) {
5024 fprintf(STDERR, "aborted.\n");
5031 ubik_Call(VL_SetLock, cstruct, 0, entry.volumeId[RWVOL], RWVOL,
5033 aconn = UV_Bind(server, AFSCONF_VOLUMEPORT);
5034 code = AFSVolConvertROtoRWvolume(aconn, partition, volid);
5037 "Converting RO volume %lu to RW volume failed with code %d\n",
5038 (unsigned long)volid, code);
5039 PrintError("convertROtoRW ", code);
5042 entry.serverFlags[roindex] = ITSRWVOL;
5043 entry.flags |= RW_EXISTS;
5044 entry.flags &= ~BACK_EXISTS;
5047 if (rwindex != entry.nServers) {
5048 entry.serverNumber[rwindex] = entry.serverNumber[entry.nServers];
5049 entry.serverPartition[rwindex] =
5050 entry.serverPartition[entry.nServers];
5051 entry.serverFlags[rwindex] = entry.serverFlags[entry.nServers];
5052 entry.serverNumber[entry.nServers] = 0;
5053 entry.serverPartition[entry.nServers] = 0;
5054 entry.serverFlags[entry.nServers] = 0;
5057 entry.flags &= ~RO_EXISTS;
5058 for (i = 0; i < entry.nServers; i++) {
5059 if (entry.serverFlags[i] & ITSROVOL) {
5060 if (!(entry.serverFlags[i] & (RO_DONTUSE | NEW_REPSITE)))
5061 entry.flags |= RO_EXISTS;
5064 MapNetworkToHost(&entry, &storeEntry);
5066 VLDB_ReplaceEntry(entry.volumeId[RWVOL], RWVOL, &storeEntry,
5067 (LOCKREL_OPCODE | LOCKREL_AFSID |
5068 LOCKREL_TIMESTAMP));
5071 "Warning: volume converted, but vldb update failed with code %d!\n",
5074 vcode = UV_LockRelease(entry.volumeId[RWVOL]);
5076 PrintDiagnostics("unlock", vcode);
5083 register struct cmd_syndesc *as;
5085 afs_int32 avolid, aserver, apart, voltype, fromdate = 0, code, err, i;
5086 struct nvldbentry entry;
5087 volintSize vol_size;
5089 rx_SetRxDeadTime(60 * 10);
5090 for (i = 0; i < MAXSERVERS; i++) {
5091 struct rx_connection *rxConn = ubik_GetRPCConn(cstruct, i);
5094 rx_SetConnDeadTime(rxConn, rx_connDeadTime);
5095 if (rxConn->service)
5096 rxConn->service->connDeadTime = rx_connDeadTime;
5099 avolid = vsu_GetVolumeID(as->parms[0].items->data, cstruct, &err);
5102 PrintError("", err);
5104 fprintf(STDERR, "vos: can't find volume '%s'\n",
5105 as->parms[0].items->data);
5109 if (as->parms[1].items || as->parms[2].items) {
5110 if (!as->parms[1].items || !as->parms[2].items) {
5112 "Must specify both -server and -partition options\n");
5115 aserver = GetServer(as->parms[2].items->data);
5117 fprintf(STDERR, "Invalid server name\n");
5120 apart = volutil_GetPartitionID(as->parms[1].items->data);
5122 fprintf(STDERR, "Invalid partition name\n");
5126 code = GetVolumeInfo(avolid, &aserver, &apart, &voltype, &entry);
5133 if (as->parms[4].items && strcmp(as->parms[4].items->data, "0")) {
5134 code = ktime_DateToInt32(as->parms[4].items->data, &fromdate);
5136 fprintf(STDERR, "vos: failed to parse date '%s' (error=%d))\n",
5137 as->parms[1].items->data, code);
5142 fprintf(STDOUT, "Volume: %s\n", as->parms[0].items->data);
5144 if (as->parms[3].items) { /* do the dump estimate */
5145 #ifdef AFS_64BIT_ENV
5146 vol_size.dump_size = 0;
5148 FillInt64(vol_size.dump_size,0, 1);
5150 code = UV_GetSize(avolid, aserver, apart, fromdate, &vol_size);
5152 PrintDiagnostics("size", code);
5155 /* presumably the size info is now gathered in pntr */
5156 /* now we display it */
5158 fprintf(STDOUT, "dump_size: %llu\n", vol_size.dump_size);
5166 PrintDiagnostics(astring, acode)
5170 if (acode == EACCES) {
5172 "You are not authorized to perform the 'vos %s' command (%d)\n",
5175 fprintf(STDERR, "Error in vos %s command.\n", astring);
5176 PrintError("", acode);
5183 MyBeforeProc(as, arock)
5184 struct cmd_syndesc *as;
5187 register char *tcell;
5188 register afs_int32 code;
5189 register afs_int32 sauth;
5191 /* Initialize the ubik_client connection */
5192 rx_SetRxDeadTime(90);
5193 cstruct = (struct ubik_client *)0;
5197 if (as->parms[12].items) /* if -cell specified */
5198 tcell = as->parms[12].items->data;
5199 if (as->parms[14].items) /* -serverauth specified */
5201 if (as->parms[16].items) /* -crypt specified */
5204 vsu_ClientInit((as->parms[13].items != 0), confdir, tcell, sauth,
5205 &cstruct, UV_SetSecurity))) {
5206 fprintf(STDERR, "could not initialize VLDB library (code=%lu) \n",
5207 (unsigned long)code);
5211 if (as->parms[15].items) /* -verbose flag set */
5221 /* this sucks but it works for now.
5226 #include "AFS_component_version_number.c"
5232 register afs_int32 code;
5234 register struct cmd_syndesc *ts;
5236 #ifdef AFS_AIX32_ENV
5238 * The following signal action for AIX is necessary so that in case of a
5239 * crash (i.e. core is generated) we can include the user's data section
5240 * in the core dump. Unfortunately, by default, only a partial core is
5241 * generated which, in many cases, isn't too useful.
5243 struct sigaction nsa;
5245 sigemptyset(&nsa.sa_mask);
5246 nsa.sa_handler = SIG_DFL;
5247 nsa.sa_flags = SA_FULLDUMP;
5248 sigaction(SIGSEGV, &nsa, NULL);
5251 confdir = AFSDIR_CLIENT_ETC_DIRPATH;
5253 cmd_SetBeforeProc(MyBeforeProc, NULL);
5255 ts = cmd_CreateSyntax("create", CreateVolume, 0, "create a new volume");
5256 cmd_AddParm(ts, "-server", CMD_SINGLE, 0, "machine name");
5257 cmd_AddParm(ts, "-partition", CMD_SINGLE, 0, "partition name");
5258 cmd_AddParm(ts, "-name", CMD_SINGLE, 0, "volume name");
5259 cmd_AddParm(ts, "-maxquota", CMD_SINGLE, CMD_OPTIONAL,
5260 "initial quota (KB)");
5262 cmd_AddParm(ts, "-minquota", CMD_SINGLE, CMD_OPTIONAL, "");
5266 ts = cmd_CreateSyntax("remove", DeleteVolume, 0, "delete a volume");
5267 cmd_AddParm(ts, "-server", CMD_SINGLE, CMD_OPTIONAL, "machine name");
5268 cmd_AddParm(ts, "-partition", CMD_SINGLE, CMD_OPTIONAL, "partition name");
5269 cmd_AddParm(ts, "-id", CMD_SINGLE, 0, "volume name or ID");
5273 ts = cmd_CreateSyntax("move", MoveVolume, 0, "move a volume");
5274 cmd_AddParm(ts, "-id", CMD_SINGLE, 0, "volume name or ID");
5275 cmd_AddParm(ts, "-fromserver", CMD_SINGLE, 0, "machine name on source");
5276 cmd_AddParm(ts, "-frompartition", CMD_SINGLE, 0,
5277 "partition name on source");
5278 cmd_AddParm(ts, "-toserver", CMD_SINGLE, 0,
5279 "machine name on destination");
5280 cmd_AddParm(ts, "-topartition", CMD_SINGLE, 0,
5281 "partition name on destination");
5282 cmd_AddParm(ts, "-live", CMD_FLAG, CMD_OPTIONAL,
5283 "copy live volume without cloning");
5286 ts = cmd_CreateSyntax("copy", CopyVolume, 0, "copy a volume");
5287 cmd_AddParm(ts, "-id", CMD_SINGLE, 0, "volume name or ID on source");
5288 cmd_AddParm(ts, "-fromserver", CMD_SINGLE, 0, "machine name on source");
5289 cmd_AddParm(ts, "-frompartition", CMD_SINGLE, 0,
5290 "partition name on source");
5291 cmd_AddParm(ts, "-toname", CMD_SINGLE, 0, "volume name on destination");
5292 cmd_AddParm(ts, "-toserver", CMD_SINGLE, 0,
5293 "machine name on destination");
5294 cmd_AddParm(ts, "-topartition", CMD_SINGLE, 0,
5295 "partition name on destination");
5296 cmd_AddParm(ts, "-offline", CMD_FLAG, CMD_OPTIONAL,
5297 "leave new volume offline");
5298 cmd_AddParm(ts, "-readonly", CMD_FLAG, CMD_OPTIONAL,
5299 "make new volume read-only");
5300 cmd_AddParm(ts, "-live", CMD_FLAG, CMD_OPTIONAL,
5301 "copy live volume without cloning");
5304 ts = cmd_CreateSyntax("shadow", ShadowVolume, 0,
5305 "make or update a shadow volume");
5306 cmd_AddParm(ts, "-id", CMD_SINGLE, 0, "volume name or ID on source");
5307 cmd_AddParm(ts, "-fromserver", CMD_SINGLE, 0, "machine name on source");
5308 cmd_AddParm(ts, "-frompartition", CMD_SINGLE, 0,
5309 "partition name on source");
5310 cmd_AddParm(ts, "-toserver", CMD_SINGLE, 0,
5311 "machine name on destination");
5312 cmd_AddParm(ts, "-topartition", CMD_SINGLE, 0,
5313 "partition name on destination");
5314 cmd_AddParm(ts, "-toname", CMD_SINGLE, CMD_OPTIONAL,
5315 "volume name on destination");
5316 cmd_AddParm(ts, "-toid", CMD_SINGLE, CMD_OPTIONAL,
5317 "volume ID on destination");
5318 cmd_AddParm(ts, "-offline", CMD_FLAG, CMD_OPTIONAL,
5319 "leave shadow volume offline");
5320 cmd_AddParm(ts, "-readonly", CMD_FLAG, CMD_OPTIONAL,
5321 "make shadow volume read-only");
5322 cmd_AddParm(ts, "-live", CMD_FLAG, CMD_OPTIONAL,
5323 "copy live volume without cloning");
5324 cmd_AddParm(ts, "-incremental", CMD_FLAG, CMD_OPTIONAL,
5325 "do incremental update if target exists");
5328 ts = cmd_CreateSyntax("backup", BackupVolume, 0,
5329 "make backup of a volume");
5330 cmd_AddParm(ts, "-id", CMD_SINGLE, 0, "volume name or ID");
5333 ts = cmd_CreateSyntax("clone", CloneVolume, 0,
5334 "make clone of a volume");
5335 cmd_AddParm(ts, "-id", CMD_SINGLE, 0, "volume name or ID");
5336 cmd_AddParm(ts, "-server", CMD_SINGLE, CMD_OPTIONAL, "server");
5337 cmd_AddParm(ts, "-partition", CMD_SINGLE, CMD_OPTIONAL, "partition");
5338 cmd_AddParm(ts, "-toname", CMD_SINGLE, CMD_OPTIONAL,
5339 "volume name on destination");
5340 cmd_AddParm(ts, "-toid", CMD_SINGLE, CMD_OPTIONAL,
5341 "volume ID on destination");
5342 cmd_AddParm(ts, "-offline", CMD_FLAG, CMD_OPTIONAL,
5343 "leave clone volume offline");
5344 cmd_AddParm(ts, "-readonly", CMD_FLAG, CMD_OPTIONAL,
5345 "make clone volume read-only, not readwrite");
5348 ts = cmd_CreateSyntax("release", ReleaseVolume, 0, "release a volume");
5349 cmd_AddParm(ts, "-id", CMD_SINGLE, 0, "volume name or ID");
5350 cmd_AddParm(ts, "-force", CMD_FLAG, CMD_OPTIONAL,
5351 "force a complete release");
5354 ts = cmd_CreateSyntax("dump", DumpVolume, 0, "dump a volume");
5355 cmd_AddParm(ts, "-id", CMD_SINGLE, 0, "volume name or ID");
5356 cmd_AddParm(ts, "-time", CMD_SINGLE, CMD_OPTIONAL, "dump from time");
5357 cmd_AddParm(ts, "-file", CMD_SINGLE, CMD_OPTIONAL, "dump file");
5358 cmd_AddParm(ts, "-server", CMD_SINGLE, CMD_OPTIONAL, "server");
5359 cmd_AddParm(ts, "-partition", CMD_SINGLE, CMD_OPTIONAL, "partition");
5360 cmd_AddParm(ts, "-clone", CMD_FLAG, CMD_OPTIONAL,
5361 "dump a clone of the volume");
5364 ts = cmd_CreateSyntax("restore", RestoreVolume, 0, "restore a volume");
5365 cmd_AddParm(ts, "-server", CMD_SINGLE, 0, "machine name");
5366 cmd_AddParm(ts, "-partition", CMD_SINGLE, 0, "partition name");
5367 cmd_AddParm(ts, "-name", CMD_SINGLE, 0, "name of volume to be restored");
5368 cmd_AddParm(ts, "-file", CMD_SINGLE, CMD_OPTIONAL, "dump file");
5369 cmd_AddParm(ts, "-id", CMD_SINGLE, CMD_OPTIONAL, "volume ID");
5370 cmd_AddParm(ts, "-overwrite", CMD_SINGLE, CMD_OPTIONAL,
5371 "abort | full | incremental");
5372 cmd_AddParm(ts, "-offline", CMD_FLAG, CMD_OPTIONAL,
5373 "leave restored volume offline");
5374 cmd_AddParm(ts, "-readonly", CMD_FLAG, CMD_OPTIONAL,
5375 "make restored volume read-only");
5378 ts = cmd_CreateSyntax("unlock", LockReleaseCmd, 0,
5379 "release lock on VLDB entry for a volume");
5380 cmd_AddParm(ts, "-id", CMD_SINGLE, 0, "volume name or ID");
5383 ts = cmd_CreateSyntax("changeloc", ChangeLocation, 0,
5384 "change an RW volume's location in the VLDB");
5385 cmd_AddParm(ts, "-server", CMD_SINGLE, 0,
5386 "machine name for new location");
5387 cmd_AddParm(ts, "-partition", CMD_SINGLE, 0,
5388 "partition name for new location");
5389 cmd_AddParm(ts, "-id", CMD_SINGLE, 0, "volume name or ID");
5392 ts = cmd_CreateSyntax("addsite", AddSite, 0, "add a replication site");
5393 cmd_AddParm(ts, "-server", CMD_SINGLE, 0, "machine name for new site");
5394 cmd_AddParm(ts, "-partition", CMD_SINGLE, 0,
5395 "partition name for new site");
5396 cmd_AddParm(ts, "-id", CMD_SINGLE, 0, "volume name or ID");
5399 ts = cmd_CreateSyntax("remsite", RemoveSite, 0,
5400 "remove a replication site");
5401 cmd_AddParm(ts, "-server", CMD_SINGLE, 0, "machine name");
5402 cmd_AddParm(ts, "-partition", CMD_SINGLE, 0, "partition name");
5403 cmd_AddParm(ts, "-id", CMD_SINGLE, 0, "volume name or ID");
5406 ts = cmd_CreateSyntax("listpart", ListPartitions, 0, "list partitions");
5407 cmd_AddParm(ts, "-server", CMD_SINGLE, 0, "machine name");
5410 ts = cmd_CreateSyntax("listvol", ListVolumes, 0,
5411 "list volumes on server (bypass VLDB)");
5412 cmd_AddParm(ts, "-server", CMD_SINGLE, 0, "machine name");
5413 cmd_AddParm(ts, "-partition", CMD_SINGLE, CMD_OPTIONAL, "partition name");
5414 cmd_AddParm(ts, "-fast", CMD_FLAG, CMD_OPTIONAL, "minimal listing");
5415 cmd_AddParm(ts, "-long", CMD_FLAG, CMD_OPTIONAL,
5416 "list all normal volume fields");
5417 cmd_AddParm(ts, "-quiet", CMD_FLAG, CMD_OPTIONAL,
5418 "generate minimal information");
5419 cmd_AddParm(ts, "-extended", CMD_FLAG, CMD_OPTIONAL,
5420 "list extended volume fields");
5421 #ifdef FULL_LISTVOL_SWITCH
5422 cmd_AddParm(ts, "-format", CMD_FLAG, CMD_OPTIONAL,
5423 "machine readable format");
5424 #endif /* FULL_LISTVOL_SWITCH */
5427 ts = cmd_CreateSyntax("syncvldb", SyncVldb, 0,
5428 "synchronize VLDB with server");
5429 cmd_AddParm(ts, "-server", CMD_SINGLE, CMD_OPTIONAL, "machine name");
5430 cmd_AddParm(ts, "-partition", CMD_SINGLE, CMD_OPTIONAL, "partition name");
5431 cmd_AddParm(ts, "-volume", CMD_SINGLE, CMD_OPTIONAL, "volume name or ID");
5434 ts = cmd_CreateSyntax("syncserv", SyncServer, 0,
5435 "synchronize server with VLDB");
5436 cmd_AddParm(ts, "-server", CMD_SINGLE, 0, "machine name");
5437 cmd_AddParm(ts, "-partition", CMD_SINGLE, CMD_OPTIONAL, "partition name");
5440 ts = cmd_CreateSyntax("examine", ExamineVolume, 0,
5441 "everything about the volume");
5442 cmd_AddParm(ts, "-id", CMD_SINGLE, 0, "volume name or ID");
5443 cmd_AddParm(ts, "-extended", CMD_FLAG, CMD_OPTIONAL,
5444 "list extended volume fields");
5445 #ifdef FULL_LISTVOL_SWITCH
5446 cmd_AddParm(ts, "-format", CMD_FLAG, CMD_OPTIONAL,
5447 "machine readable format");
5448 #endif /* FULL_LISTVOL_SWITCH */
5450 cmd_CreateAlias(ts, "volinfo");
5452 ts = cmd_CreateSyntax("setfields", SetFields, 0,
5453 "change volume info fields");
5454 cmd_AddParm(ts, "-id", CMD_SINGLE, 0, "volume name or ID");
5455 cmd_AddParm(ts, "-maxquota", CMD_SINGLE, CMD_OPTIONAL, "quota (KB)");
5456 cmd_AddParm(ts, "-clearuse", CMD_FLAG, CMD_OPTIONAL, "clear dayUse");
5459 ts = cmd_CreateSyntax("offline", volOffline, 0, (char *)CMD_HIDDEN);
5460 cmd_AddParm(ts, "-server", CMD_SINGLE, 0, "server name");
5461 cmd_AddParm(ts, "-partition", CMD_SINGLE, 0, "partition name");
5462 cmd_AddParm(ts, "-id", CMD_SINGLE, 0, "volume name or ID");
5463 cmd_AddParm(ts, "-sleep", CMD_SINGLE, CMD_OPTIONAL, "seconds to sleep");
5464 cmd_AddParm(ts, "-busy", CMD_FLAG, CMD_OPTIONAL, "busy volume");
5467 ts = cmd_CreateSyntax("online", volOnline, 0, (char *)CMD_HIDDEN);
5468 cmd_AddParm(ts, "-server", CMD_SINGLE, 0, "server name");
5469 cmd_AddParm(ts, "-partition", CMD_SINGLE, 0, "partition name");
5470 cmd_AddParm(ts, "-id", CMD_SINGLE, 0, "volume name or ID");
5473 ts = cmd_CreateSyntax("zap", VolumeZap, 0,
5474 "delete the volume, don't bother with VLDB");
5475 cmd_AddParm(ts, "-server", CMD_SINGLE, 0, "machine name");
5476 cmd_AddParm(ts, "-partition", CMD_SINGLE, 0, "partition name");
5477 cmd_AddParm(ts, "-id", CMD_SINGLE, 0, "volume ID");
5478 cmd_AddParm(ts, "-force", CMD_FLAG, CMD_OPTIONAL,
5479 "force deletion of bad volumes");
5480 cmd_AddParm(ts, "-backup", CMD_FLAG, CMD_OPTIONAL,
5481 "also delete backup volume if one is found");
5484 ts = cmd_CreateSyntax("status", VolserStatus, 0,
5485 "report on volser status");
5486 cmd_AddParm(ts, "-server", CMD_SINGLE, 0, "machine name");
5489 ts = cmd_CreateSyntax("rename", RenameVolume, 0, "rename a volume");
5490 cmd_AddParm(ts, "-oldname", CMD_SINGLE, 0, "old volume name ");
5491 cmd_AddParm(ts, "-newname", CMD_SINGLE, 0, "new volume name ");
5494 ts = cmd_CreateSyntax("listvldb", ListVLDB, 0,
5495 "list volumes in the VLDB");
5496 cmd_AddParm(ts, "-name", CMD_SINGLE, CMD_OPTIONAL, "volume name or ID");
5497 cmd_AddParm(ts, "-server", CMD_SINGLE, CMD_OPTIONAL, "machine name");
5498 cmd_AddParm(ts, "-partition", CMD_SINGLE, CMD_OPTIONAL, "partition name");
5499 cmd_AddParm(ts, "-locked", CMD_FLAG, CMD_OPTIONAL, "locked volumes only");
5500 cmd_AddParm(ts, "-quiet", CMD_FLAG, CMD_OPTIONAL,
5501 "generate minimal information");
5502 cmd_AddParm(ts, "-nosort", CMD_FLAG, CMD_OPTIONAL,
5503 "do not alphabetically sort the volume names");
5506 ts = cmd_CreateSyntax("backupsys", BackSys, 0, "en masse backups");
5507 cmd_AddParm(ts, "-prefix", CMD_LIST, CMD_OPTIONAL,
5508 "common prefix on volume(s)");
5509 cmd_AddParm(ts, "-server", CMD_SINGLE, CMD_OPTIONAL, "machine name");
5510 cmd_AddParm(ts, "-partition", CMD_SINGLE, CMD_OPTIONAL, "partition name");
5511 cmd_AddParm(ts, "-exclude", CMD_FLAG, CMD_OPTIONAL,
5512 "exclude common prefix volumes");
5513 cmd_AddParm(ts, "-xprefix", CMD_LIST, CMD_OPTIONAL,
5514 "negative prefix on volume(s)");
5515 cmd_AddParm(ts, "-dryrun", CMD_FLAG, CMD_OPTIONAL, "no action");
5518 ts = cmd_CreateSyntax("delentry", DeleteEntry, 0,
5519 "delete VLDB entry for a volume");
5520 cmd_AddParm(ts, "-id", CMD_LIST, CMD_OPTIONAL, "volume name or ID");
5521 cmd_AddParm(ts, "-prefix", CMD_SINGLE, CMD_OPTIONAL,
5522 "prefix of the volume whose VLDB entry is to be deleted");
5523 cmd_AddParm(ts, "-server", CMD_SINGLE, CMD_OPTIONAL, "machine name");
5524 cmd_AddParm(ts, "-partition", CMD_SINGLE, CMD_OPTIONAL, "partition name");
5525 cmd_AddParm(ts, "-noexecute", CMD_FLAG, CMD_OPTIONAL | CMD_HIDE,
5529 ts = cmd_CreateSyntax("partinfo", PartitionInfo, 0,
5530 "list partition information");
5531 cmd_AddParm(ts, "-server", CMD_SINGLE, 0, "machine name");
5532 cmd_AddParm(ts, "-partition", CMD_SINGLE, CMD_OPTIONAL, "partition name");
5535 ts = cmd_CreateSyntax("unlockvldb", UnlockVLDB, 0,
5536 "unlock all the locked entries in the VLDB");
5537 cmd_AddParm(ts, "-server", CMD_SINGLE, CMD_OPTIONAL, "machine name");
5538 cmd_AddParm(ts, "-partition", CMD_SINGLE, CMD_OPTIONAL, "partition name");
5541 ts = cmd_CreateSyntax("lock", LockEntry, 0,
5542 "lock VLDB entry for a volume");
5543 cmd_AddParm(ts, "-id", CMD_SINGLE, 0, "volume name or ID");
5546 ts = cmd_CreateSyntax("changeaddr", ChangeAddr, 0,
5547 "change the IP address of a file server");
5548 cmd_AddParm(ts, "-oldaddr", CMD_SINGLE, 0, "original IP address");
5549 cmd_AddParm(ts, "-newaddr", CMD_SINGLE, CMD_OPTIONAL, "new IP address");
5550 cmd_AddParm(ts, "-remove", CMD_FLAG, CMD_OPTIONAL,
5551 "remove the IP address from the VLDB");
5554 ts = cmd_CreateSyntax("listaddrs", ListAddrs, 0,
5555 "list the IP address of all file servers registered in the VLDB");
5556 cmd_AddParm(ts, "-uuid", CMD_SINGLE, CMD_OPTIONAL, "uuid of server");
5557 cmd_AddParm(ts, "-host", CMD_SINGLE, CMD_OPTIONAL, "address of host");
5558 cmd_AddParm(ts, "-noresolve", CMD_FLAG, CMD_OPTIONAL,
5559 "don't resolve addresses");
5560 cmd_AddParm(ts, "-printuuid", CMD_FLAG, CMD_OPTIONAL,
5561 "print uuid of hosts");
5564 ts = cmd_CreateSyntax("convertROtoRW", ConvertRO, 0,
5565 "convert a RO volume into a RW volume (after loss of old RW volume)");
5566 cmd_AddParm(ts, "-server", CMD_SINGLE, 0, "machine name");
5567 cmd_AddParm(ts, "-partition", CMD_SINGLE, 0, "partition name");
5568 cmd_AddParm(ts, "-id", CMD_SINGLE, 0, "volume name or ID");
5569 cmd_AddParm(ts, "-force", CMD_FLAG, CMD_OPTIONAL, "don't ask");
5572 ts = cmd_CreateSyntax("size", Sizes, 0,
5573 "obtain various sizes of the volume.");
5574 cmd_AddParm(ts, "-id", CMD_SINGLE, 0, "volume name or ID");
5575 cmd_AddParm(ts, "-partition", CMD_SINGLE, CMD_OPTIONAL, "partition name");
5576 cmd_AddParm(ts, "-server", CMD_SINGLE, CMD_OPTIONAL, "machine name");
5577 cmd_AddParm(ts, "-dump", CMD_FLAG, CMD_OPTIONAL,
5578 "Obtain the size of the dump");
5579 cmd_AddParm(ts, "-time", CMD_SINGLE, CMD_OPTIONAL, "dump from time");
5582 code = cmd_Dispatch(argc, argv);
5584 /* Shut down the ubik_client and rx connections */
5586 (void)ubik_ClientDestroy(cstruct);
5592 exit((code ? -1 : 0));