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)
503 fprintf(STDOUT, " Last Update Never\n");
505 fprintf(STDOUT, " Last Update %s",
506 ctime((time_t *) & pntr->updateDate));
508 " %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)
660 fprintf(STDOUT, " Last Update Never\n");
662 fprintf(STDOUT, " Last Update %s",
663 ctime((time_t *) & a_xInfoP->updateDate));
665 " %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
798 /*------------------------------------------------------------------------
799 * PRIVATE XDisplayFormat2
802 * Display the formated contents of one extended volume info structure.
805 * a_xInfoP : Ptr to extended volume info struct to print.
806 * a_servID : Server ID to print.
807 * a_partID : Partition ID to print.
808 * a_totalOKP : Ptr to total-OK counter.
809 * a_totalNotOKP : Ptr to total-screwed counter.
810 * a_totalBusyP : Ptr to total-busy counter.
811 * a_fast : Fast listing?
812 * a_int32 : Int32 listing?
813 * a_showProblems : Show volume problems?
819 * Nothing interesting.
823 *------------------------------------------------------------------------*/
826 XDisplayFormat2(a_xInfoP, a_servID, a_partID, a_totalOKP, a_totalNotOKP,
827 a_totalBusyP, a_fast, a_int32, a_showProblems)
828 volintXInfo *a_xInfoP;
838 { /*XDisplayFormat */
846 fprintf(STDOUT, "vold_id\t%-10lu\n", (unsigned long)a_xInfoP->volid);
847 } else if (a_int32) {
849 * Fully-detailed listing.
851 if (a_xInfoP->status == VOK) {
853 * Volume's status is OK - all the fields are valid.
856 static long server_cache = -1, partition_cache = -1;
857 static char hostname[256], address[32], pname[16];
858 int i,ai[] = {VOLINT_STATS_TIME_IDX_0,VOLINT_STATS_TIME_IDX_1,VOLINT_STATS_TIME_IDX_2,
859 VOLINT_STATS_TIME_IDX_3,VOLINT_STATS_TIME_IDX_4,VOLINT_STATS_TIME_IDX_5};
861 if (a_servID != server_cache) {
865 strcpy(hostname, hostutil_GetNameByINet(a_servID));
866 strcpy(address, inet_ntoa(s));
867 server_cache = a_servID;
869 if (a_partID != partition_cache) {
870 MapPartIdIntoName(a_partID, pname);
871 partition_cache = a_partID;
875 fprintf(STDOUT, "name\t\t%s\n", a_xInfoP->name);
876 fprintf(STDOUT, "id\t\t%lu\n", a_xInfoP->volid);
877 fprintf(STDOUT, "serv\t\t%s\t%s\n", address, hostname);
878 fprintf(STDOUT, "part\t\t%s\n", pname);
879 switch (a_xInfoP->status) {
881 fprintf(STDOUT, "status\t\tOK\n");
884 fprintf(STDOUT, "status\t\tBUSY\n");
887 fprintf(STDOUT, "status\t\tUNATTACHABLE\n");
890 fprintf(STDOUT, "backupID\t%lu\n", a_xInfoP->backupID);
891 fprintf(STDOUT, "parentID\t%lu\n", a_xInfoP->parentID);
892 fprintf(STDOUT, "cloneID\t\t%lu\n", a_xInfoP->cloneID);
893 fprintf(STDOUT, "inUse\t\t%s\n", a_xInfoP->inUse ? "Y" : "N");
894 switch (a_xInfoP->type) {
896 fprintf(STDOUT, "type\t\tRW\n");
899 fprintf(STDOUT, "type\t\tRO\n");
902 fprintf(STDOUT, "type\t\tBK\n");
905 fprintf(STDOUT, "type\t\t?\n");
908 fprintf(STDOUT, "creationDate\t%-9lu\t%s", a_xInfoP->creationDate,
909 ctime(&a_xInfoP->creationDate));
910 fprintf(STDOUT, "accessDate\t%-9lu\t%s", a_xInfoP->accessDate,
911 ctime(&a_xInfoP->accessDate));
912 fprintf(STDOUT, "updateDate\t%-9lu\t%s", a_xInfoP->updateDate,
913 ctime(&a_xInfoP->updateDate));
914 fprintf(STDOUT, "backupDate\t%-9lu\t%s", a_xInfoP->backupDate,
915 ctime(&a_xInfoP->backupDate));
916 fprintf(STDOUT, "copyDate\t%-9lu\t%s", a_xInfoP->copyDate,
917 ctime(&a_xInfoP->copyDate));
919 fprintf(STDOUT, "diskused\t%u\n", a_xInfoP->size);
920 fprintf(STDOUT, "maxquota\t%u\n", a_xInfoP->maxquota);
922 fprintf(STDOUT, "filecount\t%u\n", a_xInfoP->filecount);
923 fprintf(STDOUT, "dayUse\t\t%u\n", a_xInfoP->dayUse);
927 fprintf(STDOUT,"reads_same_net\t%8d\n",a_xInfoP->stat_reads[VOLINT_STATS_SAME_NET]);
928 fprintf(STDOUT,"reads_same_net_auth\t%8d\n",a_xInfoP->stat_reads[VOLINT_STATS_SAME_NET_AUTH]);
929 fprintf(STDOUT,"reads_diff_net\t%8d\n",a_xInfoP->stat_reads[VOLINT_STATS_DIFF_NET]);
930 fprintf(STDOUT,"reads_diff_net_auth\t%8d\n",a_xInfoP->stat_reads[VOLINT_STATS_DIFF_NET_AUTH]);
932 fprintf(STDOUT,"writes_same_net\t%8d\n",a_xInfoP->stat_writes[VOLINT_STATS_SAME_NET]);
933 fprintf(STDOUT,"writes_same_net_auth\t%8d\n",a_xInfoP->stat_writes[VOLINT_STATS_SAME_NET_AUTH]);
934 fprintf(STDOUT,"writes_diff_net\t%8d\n",a_xInfoP->stat_writes[VOLINT_STATS_DIFF_NET]);
935 fprintf(STDOUT,"writes_diff_net_auth\t%8d\n",a_xInfoP->stat_writes[VOLINT_STATS_DIFF_NET_AUTH]);
939 fprintf(STDOUT,"file_same_author_idx_%d\t%8d\n",i+1,a_xInfoP->stat_fileSameAuthor[ai[i]]);
940 fprintf(STDOUT,"file_diff_author_idx_%d\t%8d\n",i+1,a_xInfoP->stat_fileDiffAuthor[ai[i]]);
941 fprintf(STDOUT,"dir_same_author_idx_%d\t%8d\n",i+1,a_xInfoP->stat_dirSameAuthor[ai[i]]);
942 fprintf(STDOUT,"dir_dif_author_idx_%d\t%8d\n",i+1,a_xInfoP->stat_dirDiffAuthor[ai[i]]);
945 } /*Volume status OK */
946 else if (a_xInfoP->status == VBUSY) {
948 qPut(&busyHead, a_xInfoP->volid);
950 fprintf(STDOUT, "BUSY_VOL\t%lu\n",
951 (unsigned long)a_xInfoP->volid);
955 qPut(¬okHead, a_xInfoP->volid);
957 fprintf(STDOUT, "COULD_NOT_ATTACH\t%lu\n",
958 (unsigned long)a_xInfoP->volid);
959 } /*Screwed volume */
965 if (a_xInfoP->status == VOK) {
966 fprintf(STDOUT, "name\t%-32s\n", a_xInfoP->name);
967 fprintf(STDOUT, "volID\t%10lu\n", (unsigned long)a_xInfoP->volid);
968 if (a_xInfoP->type == 0)
969 fprintf(STDOUT, "type\tRW\n");
970 if (a_xInfoP->type == 1)
971 fprintf(STDOUT, "type\tRO\n");
972 if (a_xInfoP->type == 2)
973 fprintf(STDOUT, "type\tBK\n");
974 fprintf(STDOUT, "size\t%10dK\n", a_xInfoP->size);
976 fprintf(STDOUT, "inUse\t%d\n",a_xInfoP->inUse);
977 if (a_xInfoP->inUse == 1)
983 else if (a_xInfoP->status == VBUSY) {
985 qPut(&busyHead, a_xInfoP->volid);
987 fprintf(STDOUT, "VOLUME_BUSY\t%lu\n",
988 (unsigned long)a_xInfoP->volid);
992 qPut(¬okHead, a_xInfoP->volid);
994 fprintf(STDOUT, "COULD_NOT_ATTACH_VOLUME\t%lu\n",
995 (unsigned long)a_xInfoP->volid);
996 } /*Screwed volume */
997 } /*Default listing */
998 } /*XDisplayFormat */
999 #endif /*FULL_LISTVOL_SWITCH*/
1001 #ifdef FULL_LISTVOL_SWITCH
1003 DisplayFormat2(server, partition, pntr)
1004 long server, partition;
1007 static long server_cache = -1, partition_cache = -1;
1008 static char hostname[256], address[32], pname[16];
1010 if (server != server_cache) {
1014 strcpy(hostname, hostutil_GetNameByINet(server));
1015 strcpy(address, inet_ntoa(s));
1016 server_cache = server;
1018 if (partition != partition_cache) {
1019 MapPartIdIntoName(partition, pname);
1020 partition_cache = partition;
1024 fprintf(STDOUT, "name\t\t%s\n", pntr->name);
1025 fprintf(STDOUT, "id\t\t%lu\n", pntr->volid);
1026 fprintf(STDOUT, "serv\t\t%s\t%s\n", address, hostname);
1027 fprintf(STDOUT, "part\t\t%s\n", pname);
1028 switch (pntr->status) {
1030 fprintf(STDOUT, "status\t\tOK\n");
1033 fprintf(STDOUT, "status\t\tBUSY\n");
1036 fprintf(STDOUT, "status\t\tUNATTACHABLE\n");
1039 fprintf(STDOUT, "backupID\t%lu\n", pntr->backupID);
1040 fprintf(STDOUT, "parentID\t%lu\n", pntr->parentID);
1041 fprintf(STDOUT, "cloneID\t\t%lu\n", pntr->cloneID);
1042 fprintf(STDOUT, "inUse\t\t%s\n", pntr->inUse ? "Y" : "N");
1043 fprintf(STDOUT, "needsSalvaged\t%s\n", pntr->needsSalvaged ? "Y" : "N");
1044 /* 0xD3 is from afs/volume.h since I had trouble including the file */
1045 fprintf(STDOUT, "destroyMe\t%s\n", pntr->destroyMe == 0xD3 ? "Y" : "N");
1046 switch (pntr->type) {
1048 fprintf(STDOUT, "type\t\tRW\n");
1051 fprintf(STDOUT, "type\t\tRO\n");
1054 fprintf(STDOUT, "type\t\tBK\n");
1057 fprintf(STDOUT, "type\t\t?\n");
1060 fprintf(STDOUT, "creationDate\t%-9lu\t%s", pntr->creationDate,
1061 ctime(&pntr->creationDate));
1062 fprintf(STDOUT, "accessDate\t%-9lu\t%s", pntr->accessDate,
1063 ctime(&pntr->accessDate));
1064 fprintf(STDOUT, "updateDate\t%-9lu\t%s", pntr->updateDate,
1065 ctime(&pntr->updateDate));
1066 fprintf(STDOUT, "backupDate\t%-9lu\t%s", pntr->backupDate,
1067 ctime(&pntr->backupDate));
1068 fprintf(STDOUT, "copyDate\t%-9lu\t%s", pntr->copyDate,
1069 ctime(&pntr->copyDate));
1070 fprintf(STDOUT, "flags\t\t%#lx\t(Optional)\n", pntr->flags);
1071 fprintf(STDOUT, "diskused\t%u\n", pntr->size);
1072 fprintf(STDOUT, "maxquota\t%u\n", pntr->maxquota);
1073 fprintf(STDOUT, "minquota\t%lu\t(Optional)\n", pntr->spare0);
1074 fprintf(STDOUT, "filecount\t%u\n", pntr->filecount);
1075 fprintf(STDOUT, "dayUse\t\t%u\n", pntr->dayUse);
1076 fprintf(STDOUT, "weekUse\t\t%lu\t(Optional)\n", pntr->spare1);
1077 fprintf(STDOUT, "spare2\t\t%lu\t(Optional)\n", pntr->spare2);
1078 fprintf(STDOUT, "spare3\t\t%lu\t(Optional)\n", pntr->spare3);
1083 DisplayVolumes2(server, partition, pntr, count)
1085 long server, partition, count;
1089 for (i = 0; i < count; i++) {
1090 fprintf(STDOUT, "BEGIN_OF_ENTRY\n");
1091 DisplayFormat2(server, partition, pntr);
1092 fprintf(STDOUT, "END_OF_ENTRY\n\n");
1097 #endif /* FULL_LISTVOL_SWITCH */
1100 DisplayVolumes(server, part, pntr, count, longlist, fast, quiet)
1101 afs_int32 server, part;
1103 afs_int32 count, longlist, fast;
1106 int totalOK, totalNotOK, totalBusy, i;
1114 for (i = 0; i < count; i++) {
1115 DisplayFormat(pntr, server, part, &totalOK, &totalNotOK, &totalBusy,
1120 while (busyHead.count) {
1121 qGet(&busyHead, &volid);
1122 fprintf(STDOUT, "**** Volume %lu is busy ****\n",
1123 (unsigned long)volid);
1127 while (notokHead.count) {
1128 qGet(¬okHead, &volid);
1129 fprintf(STDOUT, "**** Could not attach volume %lu ****\n",
1130 (unsigned long)volid);
1134 fprintf(STDOUT, "\n");
1137 "Total volumes onLine %d ; Total volumes offLine %d ; Total busy %d\n\n",
1138 totalOK, totalNotOK, totalBusy);
1142 /*------------------------------------------------------------------------
1143 * PRIVATE XDisplayVolumes
1146 * Display extended volume information.
1149 * a_servID : Pointer to the Rx call we're performing.
1150 * a_partID : Partition for which we want the extended list.
1151 * a_xInfoP : Ptr to extended volume info.
1152 * a_count : Number of volume records contained above.
1153 * a_int32 : Int32 listing generated?
1154 * a_fast : Fast listing generated?
1155 * a_quiet : Quiet listing generated?
1161 * Nothing interesting.
1165 *------------------------------------------------------------------------*/
1168 XDisplayVolumes(a_servID, a_partID, a_xInfoP, a_count, a_int32, a_fast,
1172 volintXInfo *a_xInfoP;
1178 { /*XDisplayVolumes */
1180 int totalOK; /*Total OK volumes */
1181 int totalNotOK; /*Total screwed volumes */
1182 int totalBusy; /*Total busy volumes */
1183 int i; /*Loop variable */
1184 afs_int32 volid; /*Current volume ID */
1187 * Initialize counters and (global!!) queues.
1196 * Display each volume in the list.
1198 for (i = 0; i < a_count; i++) {
1199 XDisplayFormat(a_xInfoP, a_servID, a_partID, &totalOK, &totalNotOK,
1200 &totalBusy, a_fast, a_int32, 0);
1205 * If any volumes were found to be busy or screwed, display them.
1208 while (busyHead.count) {
1209 qGet(&busyHead, &volid);
1210 fprintf(STDOUT, "**** Volume %lu is busy ****\n",
1211 (unsigned long)volid);
1215 while (notokHead.count) {
1216 qGet(¬okHead, &volid);
1217 fprintf(STDOUT, "**** Could not attach volume %lu ****\n",
1218 (unsigned long)volid);
1223 fprintf(STDOUT, "\n");
1226 "Total volumes: %d on-line, %d off-line, %d busyd\n\n",
1227 totalOK, totalNotOK, totalBusy);
1231 } /*XDisplayVolumes */
1232 #ifdef FULL_LISTVOL_SWITCH
1233 /*------------------------------------------------------------------------
1234 * PRIVATE XDisplayVolumes2
1237 * Display extended formated volume information.
1240 * a_servID : Pointer to the Rx call we're performing.
1241 * a_partID : Partition for which we want the extended list.
1242 * a_xInfoP : Ptr to extended volume info.
1243 * a_count : Number of volume records contained above.
1244 * a_int32 : Int32 listing generated?
1245 * a_fast : Fast listing generated?
1246 * a_quiet : Quiet listing generated?
1252 * Nothing interesting.
1256 *------------------------------------------------------------------------*/
1259 XDisplayVolumes2(a_servID, a_partID, a_xInfoP, a_count, a_int32, a_fast,
1263 volintXInfo *a_xInfoP;
1269 { /*XDisplayVolumes */
1271 int totalOK; /*Total OK volumes */
1272 int totalNotOK; /*Total screwed volumes */
1273 int totalBusy; /*Total busy volumes */
1274 int i; /*Loop variable */
1275 afs_int32 volid; /*Current volume ID */
1278 * Initialize counters and (global!!) queues.
1287 * Display each volume in the list.
1289 for (i = 0; i < a_count; i++) {
1290 fprintf(STDOUT, "BEGIN_OF_ENTRY\n");
1291 XDisplayFormat2(a_xInfoP, a_servID, a_partID, &totalOK, &totalNotOK,
1292 &totalBusy, a_fast, a_int32, 0);
1293 fprintf(STDOUT, "END_OF_ENTRY\n");
1298 * If any volumes were found to be busy or screwed, display them.
1301 while (busyHead.count) {
1302 qGet(&busyHead, &volid);
1303 fprintf(STDOUT, "BUSY_VOL\t%lu\n",
1304 (unsigned long)volid);
1308 while (notokHead.count) {
1309 qGet(¬okHead, &volid);
1310 fprintf(STDOUT, "COULD_NOT_ATTACH\t%lu\n",
1311 (unsigned long)volid);
1316 fprintf(STDOUT, "\n");
1319 "VOLUMES_ONLINE\t%d\nVOLUMES_OFFLINE\t%d\nVOLUMES_BUSY\t%d\n",
1320 totalOK, totalNotOK, totalBusy);
1324 } /*XDisplayVolumes2 */
1325 #endif /* FULL_LISTVOL_SWITCH */
1328 /* set <server> and <part> to the correct values depending on
1329 * <voltype> and <entry> */
1331 GetServerAndPart(entry, voltype, server, part, previdx)
1332 struct nvldbentry *entry;
1333 afs_int32 *server, *part;
1337 int i, istart, vtype;
1342 /* Doesn't check for non-existance of backup volume */
1343 if ((voltype == RWVOL) || (voltype == BACKVOL)) {
1345 istart = 0; /* seach the entire entry */
1348 /* Seach from beginning of entry or pick up where we left off */
1349 istart = ((*previdx < 0) ? 0 : *previdx + 1);
1352 for (i = istart; i < entry->nServers; i++) {
1353 if (entry->serverFlags[i] & vtype) {
1354 *server = entry->serverNumber[i];
1355 *part = entry->serverPartition[i];
1361 /* Didn't find any, return -1 */
1367 PostVolumeStats(entry)
1368 struct nvldbentry *entry;
1370 SubEnumerateEntry(entry);
1371 /* Check for VLOP_ALLOPERS */
1372 if (entry->flags & VLOP_ALLOPERS)
1373 fprintf(STDOUT, " Volume is currently LOCKED \n");
1377 /*------------------------------------------------------------------------
1378 * PRIVATE XVolumeStats
1381 * Display extended volume information.
1384 * a_xInfoP : Ptr to extended volume info.
1385 * a_entryP : Ptr to the volume's VLDB entry.
1386 * a_srvID : Server ID.
1387 * a_partID : Partition ID.
1388 * a_volType : Type of volume to print.
1394 * Nothing interesting.
1398 *------------------------------------------------------------------------*/
1401 XVolumeStats(a_xInfoP, a_entryP, a_srvID, a_partID, a_volType)
1402 volintXInfo *a_xInfoP;
1403 struct nvldbentry *a_entryP;
1410 int totalOK, totalNotOK, totalBusy; /*Dummies - we don't really count here */
1412 XDisplayFormat(a_xInfoP, /*Ptr to extended volume info */
1413 a_srvID, /*Server ID to print */
1414 a_partID, /*Partition ID to print */
1415 &totalOK, /*Ptr to total-OK counter */
1416 &totalNotOK, /*Ptr to total-screwed counter */
1417 &totalBusy, /*Ptr to total-busy counter */
1418 0, /*Don't do a fast listing */
1419 1, /*Do a long listing */
1420 1); /*Show volume problems */
1426 VolumeStats(pntr, entry, server, part, voltype)
1428 struct nvldbentry *entry;
1430 afs_int32 server, part;
1432 int totalOK, totalNotOK, totalBusy;
1434 DisplayFormat(pntr, server, part, &totalOK, &totalNotOK, &totalBusy, 0, 1,
1439 /* command to forcibly remove a volume */
1442 register struct cmd_syndesc *as;
1444 register afs_int32 code;
1445 afs_int32 volID, err;
1450 server = GetServer(tp = as->parms[0].items->data);
1452 fprintf(STDERR, "vos: server '%s' not found in host table\n", tp);
1456 partID = volutil_GetPartitionID(tp = as->parms[1].items->data);
1458 fprintf(STDERR, "vos: could not parse '%s' as a partition name", tp);
1462 volID = vsu_GetVolumeID(tp = as->parms[2].items->data, cstruct, &err);
1465 PrintError("", err);
1468 "vos: could not parse '%s' as a numeric volume ID", tp);
1473 "vos: forcibly removing all traces of volume %d, please wait...",
1476 code = UV_NukeVolume(server, partID, volID);
1478 fprintf(STDOUT, "done.\n");
1480 fprintf(STDOUT, "failed with code %d.\n", code);
1485 /*------------------------------------------------------------------------
1486 * PRIVATE ExamineVolume
1489 * Routine used to examine a single volume, contacting the VLDB as
1490 * well as the Volume Server.
1493 * as : Ptr to parsed command line arguments.
1496 * 0 for a successful operation,
1497 * Otherwise, one of the ubik or VolServer error values.
1500 * Nothing interesting.
1504 *------------------------------------------------------------------------
1508 register struct cmd_syndesc *as;
1510 struct nvldbentry entry;
1511 afs_int32 vcode = 0;
1512 volintInfo *pntr = (volintInfo *) 0;
1513 volintXInfo *xInfoP = (volintXInfo *) 0;
1515 afs_int32 code, err, error = 0;
1516 int voltype, foundserv = 0, foundentry = 0;
1517 afs_int32 aserver, apart;
1519 int wantExtendedInfo; /*Do we want extended vol info? */
1521 wantExtendedInfo = (as->parms[1].items ? 1 : 0); /* -extended */
1523 volid = vsu_GetVolumeID(as->parms[0].items->data, cstruct, &err); /* -id */
1526 PrintError("", err);
1528 fprintf(STDERR, "Unknown volume ID or name '%s'\n",
1529 as->parms[0].items->data);
1534 fprintf(STDOUT, "Fetching VLDB entry for %lu .. ",
1535 (unsigned long)volid);
1538 vcode = VLDB_GetEntryByID(volid, -1, &entry);
1541 "Could not fetch the entry for volume number %lu from VLDB \n",
1542 (unsigned long)volid);
1546 fprintf(STDOUT, "done\n");
1547 MapHostToNetwork(&entry);
1549 if (entry.volumeId[RWVOL] == volid)
1551 else if (entry.volumeId[BACKVOL] == volid)
1553 else /* (entry.volumeId[ROVOL] == volid) */
1556 do { /* do {...} while (voltype == ROVOL) */
1557 /* Get the entry for the volume. If its a RW vol, get the RW entry.
1558 * It its a BK vol, get the RW entry (even if VLDB may say the BK doen't exist).
1559 * If its a RO vol, get the next RO entry.
1561 GetServerAndPart(&entry, ((voltype == ROVOL) ? ROVOL : RWVOL),
1562 &aserver, &apart, &previdx);
1563 if (previdx == -1) { /* searched all entries */
1565 fprintf(STDERR, "Volume %s does not exist in VLDB\n\n",
1566 as->parms[0].items->data);
1573 /* Get information about the volume from the server */
1575 fprintf(STDOUT, "Getting volume listing from the server %s .. ",
1576 hostutil_GetNameByINet(aserver));
1579 if (wantExtendedInfo)
1580 code = UV_XListOneVolume(aserver, apart, volid, &xInfoP);
1582 code = UV_ListOneVolume(aserver, apart, volid, &pntr);
1584 fprintf(STDOUT, "done\n");
1588 if (code == ENODEV) {
1589 if ((voltype == BACKVOL) && !(entry.flags & BACK_EXISTS)) {
1590 /* The VLDB says there is no backup volume and its not on disk */
1591 fprintf(STDERR, "Volume %s does not exist\n",
1592 as->parms[0].items->data);
1596 "Volume does not exist on server %s as indicated by the VLDB\n",
1597 hostutil_GetNameByINet(aserver));
1600 PrintDiagnostics("examine", code);
1602 fprintf(STDOUT, "\n");
1605 if (wantExtendedInfo)
1606 XVolumeStats(xInfoP, &entry, aserver, apart, voltype);
1608 #ifdef FULL_LISTVOL_SWITCH
1609 if (as->parms[2].items) {
1610 DisplayFormat2(aserver, apart, pntr);
1611 EnumerateEntry(&entry);
1613 #endif /* FULL_LISTVOL_SWITCH */
1614 VolumeStats(pntr, &entry, aserver, apart, voltype);
1616 if ((voltype == BACKVOL) && !(entry.flags & BACK_EXISTS)) {
1617 /* The VLDB says there is no backup volume yet we found one on disk */
1618 fprintf(STDERR, "Volume %s does not exist in VLDB\n",
1619 as->parms[0].items->data);
1628 } while (voltype == ROVOL);
1631 fprintf(STDERR, "Dump only information from VLDB\n\n");
1632 fprintf(STDOUT, "%s \n", entry.name); /* PostVolumeStats doesn't print name */
1634 PostVolumeStats(&entry);
1639 /*------------------------------------------------------------------------
1643 * Routine used to change the status of a single volume.
1646 * as : Ptr to parsed command line arguments.
1649 * 0 for a successful operation,
1650 * Otherwise, one of the ubik or VolServer error values.
1653 * Nothing interesting.
1657 *------------------------------------------------------------------------
1661 register struct cmd_syndesc *as;
1663 struct nvldbentry entry;
1664 afs_int32 vcode = 0;
1667 afs_int32 code, err;
1668 afs_int32 aserver, apart;
1671 volid = vsu_GetVolumeID(as->parms[0].items->data, cstruct, &err); /* -id */
1674 PrintError("", err);
1676 fprintf(STDERR, "Unknown volume ID or name '%s'\n",
1677 as->parms[0].items->data);
1681 code = VLDB_GetEntryByID(volid, RWVOL, &entry);
1684 "Could not fetch the entry for volume number %lu from VLDB \n",
1685 (unsigned long)volid);
1688 MapHostToNetwork(&entry);
1690 GetServerAndPart(&entry, RWVOL, &aserver, &apart, &previdx);
1691 if (previdx == -1) {
1692 fprintf(STDERR, "Volume %s does not exist in VLDB\n\n",
1693 as->parms[0].items->data);
1697 init_volintInfo(&info);
1701 if (as->parms[1].items) {
1703 code = util_GetInt32(as->parms[1].items->data, &info.maxquota);
1705 fprintf(STDERR, "invalid quota value\n");
1709 if (as->parms[2].items) {
1713 code = UV_SetVolumeInfo(aserver, apart, volid, &info);
1716 "Could not update volume info fields for volume number %lu\n",
1717 (unsigned long)volid);
1721 /*------------------------------------------------------------------------
1725 * Brings a volume online.
1728 * as : Ptr to parsed command line arguments.
1731 * 0 for a successful operation,
1734 * Nothing interesting.
1738 *------------------------------------------------------------------------
1742 register struct cmd_syndesc *as;
1744 afs_int32 server, partition, volid;
1745 afs_int32 code, err = 0;
1747 server = GetServer(as->parms[0].items->data);
1749 fprintf(STDERR, "vos: server '%s' not found in host table\n",
1750 as->parms[0].items->data);
1754 partition = volutil_GetPartitionID(as->parms[1].items->data);
1755 if (partition < 0) {
1756 fprintf(STDERR, "vos: could not interpret partition name '%s'\n",
1757 as->parms[1].items->data);
1761 volid = vsu_GetVolumeID(as->parms[2].items->data, cstruct, &err); /* -id */
1764 PrintError("", err);
1766 fprintf(STDERR, "Unknown volume ID or name '%s'\n",
1767 as->parms[0].items->data);
1771 code = UV_SetVolume(server, partition, volid, ITOffline, 0 /*online */ ,
1774 fprintf(STDERR, "Failed to set volume. Code = %d\n", code);
1781 /*------------------------------------------------------------------------
1782 * PRIVATE volOffline
1785 * Brings a volume offline.
1788 * as : Ptr to parsed command line arguments.
1791 * 0 for a successful operation,
1794 * Nothing interesting.
1798 *------------------------------------------------------------------------
1801 volOffline(register struct cmd_syndesc *as)
1803 afs_int32 server, partition, volid;
1804 afs_int32 code, err = 0;
1805 afs_int32 transflag, sleeptime, transdone;
1807 server = GetServer(as->parms[0].items->data);
1809 fprintf(STDERR, "vos: server '%s' not found in host table\n",
1810 as->parms[0].items->data);
1814 partition = volutil_GetPartitionID(as->parms[1].items->data);
1815 if (partition < 0) {
1816 fprintf(STDERR, "vos: could not interpret partition name '%s'\n",
1817 as->parms[1].items->data);
1821 volid = vsu_GetVolumeID(as->parms[2].items->data, cstruct, &err); /* -id */
1824 PrintError("", err);
1826 fprintf(STDERR, "Unknown volume ID or name '%s'\n",
1827 as->parms[0].items->data);
1831 transflag = (as->parms[4].items ? ITBusy : ITOffline);
1832 sleeptime = (as->parms[3].items ? atol(as->parms[3].items->data) : 0);
1833 transdone = (sleeptime ? 0 /*online */ : VTOutOfService);
1834 if (as->parms[4].items && !as->parms[3].items) {
1835 fprintf(STDERR, "-sleep option must be used with -busy flag\n");
1840 UV_SetVolume(server, partition, volid, transflag, transdone,
1843 fprintf(STDERR, "Failed to set volume. Code = %d\n", code);
1851 CreateVolume(register struct cmd_syndesc *as)
1855 afs_int32 volid, code;
1856 struct nvldbentry entry;
1861 tserver = GetServer(as->parms[0].items->data);
1863 fprintf(STDERR, "vos: host '%s' not found in host table\n",
1864 as->parms[0].items->data);
1867 pnum = volutil_GetPartitionID(as->parms[1].items->data);
1869 fprintf(STDERR, "vos: could not interpret partition name '%s'\n",
1870 as->parms[1].items->data);
1873 if (!IsPartValid(pnum, tserver, &code)) { /*check for validity of the partition */
1875 PrintError("", code);
1878 "vos : partition %s does not exist on the server\n",
1879 as->parms[1].items->data);
1882 if (!ISNAMEVALID(as->parms[2].items->data)) {
1884 "vos: the name of the root volume %s exceeds the size limit of %d\n",
1885 as->parms[2].items->data, VOLSER_OLDMAXVOLNAME - 10);
1888 if (!VolNameOK(as->parms[2].items->data)) {
1890 "Illegal volume name %s, should not end in .readonly or .backup\n",
1891 as->parms[2].items->data);
1894 if (IsNumeric(as->parms[2].items->data)) {
1895 fprintf(STDERR, "Illegal volume name %s, should not be a number\n",
1896 as->parms[2].items->data);
1899 vcode = VLDB_GetEntryByName(as->parms[2].items->data, &entry);
1901 fprintf(STDERR, "Volume %s already exists\n",
1902 as->parms[2].items->data);
1903 PrintDiagnostics("create", code);
1907 if (as->parms[3].items) {
1908 if (!IsNumeric(as->parms[3].items->data)) {
1909 fprintf(STDERR, "Initial quota %s should be numeric.\n",
1910 as->parms[3].items->data);
1914 code = util_GetInt32(as->parms[3].items->data, "a);
1916 fprintf(STDERR, "vos: bad integer specified for quota.\n");
1922 UV_CreateVolume2(tserver, pnum, as->parms[2].items->data, quota, 0,
1925 PrintDiagnostics("create", code);
1928 MapPartIdIntoName(pnum, part);
1929 fprintf(STDOUT, "Volume %lu created on partition %s of %s\n",
1930 (unsigned long)volid, part, as->parms[0].items->data);
1937 struct nvldbentry *entry;
1940 afs_int32 error, code, curserver, curpart, volid;
1942 MapHostToNetwork(entry);
1944 for (i = 0; i < entry->nServers; i++) {
1945 curserver = entry->serverNumber[i];
1946 curpart = entry->serverPartition[i];
1947 if (entry->serverFlags[i] & ITSROVOL) {
1948 volid = entry->volumeId[ROVOL];
1950 volid = entry->volumeId[RWVOL];
1952 code = UV_DeleteVolume(curserver, curpart, volid);
1961 struct cmd_syndesc *as;
1963 afs_int32 err, code = 0;
1964 afs_int32 server = 0, partition = -1, volid;
1968 if (as->parms[0].items) {
1969 server = GetServer(as->parms[0].items->data);
1971 fprintf(STDERR, "vos: server '%s' not found in host table\n",
1972 as->parms[0].items->data);
1977 if (as->parms[1].items) {
1978 partition = volutil_GetPartitionID(as->parms[1].items->data);
1979 if (partition < 0) {
1980 fprintf(STDERR, "vos: could not interpret partition name '%s'\n",
1981 as->parms[1].items->data);
1985 /* Check for validity of the partition */
1986 if (!IsPartValid(partition, server, &code)) {
1988 PrintError("", code);
1991 "vos : partition %s does not exist on the server\n",
1992 as->parms[1].items->data);
1998 volid = vsu_GetVolumeID(as->parms[2].items->data, cstruct, &err);
2000 fprintf(STDERR, "Can't find volume name '%s' in VLDB\n",
2001 as->parms[2].items->data);
2003 PrintError("", err);
2007 /* If the server or partition option are not complete, try to fill
2008 * them in from the VLDB entry.
2010 if ((partition == -1) || !server) {
2011 struct nvldbentry entry;
2013 code = VLDB_GetEntryByID(volid, -1, &entry);
2016 "Could not fetch the entry for volume %lu from VLDB\n",
2017 (unsigned long)volid);
2018 PrintError("", code);
2022 if (((volid == entry.volumeId[RWVOL]) && (entry.flags & RW_EXISTS))
2023 || ((volid == entry.volumeId[BACKVOL])
2024 && (entry.flags & BACK_EXISTS))) {
2025 idx = Lp_GetRwIndex(&entry);
2026 if ((idx == -1) || (server && (server != entry.serverNumber[idx]))
2027 || ((partition != -1)
2028 && (partition != entry.serverPartition[idx]))) {
2029 fprintf(STDERR, "VLDB: Volume '%s' no match\n",
2030 as->parms[2].items->data);
2033 } else if ((volid == entry.volumeId[ROVOL])
2034 && (entry.flags & RO_EXISTS)) {
2035 for (idx = -1, j = 0; j < entry.nServers; j++) {
2036 if (entry.serverFlags[j] != ITSROVOL)
2039 if (((server == 0) || (server == entry.serverNumber[j]))
2040 && ((partition == -1)
2041 || (partition == entry.serverPartition[j]))) {
2044 "VLDB: Volume '%s' matches more than one RO\n",
2045 as->parms[2].items->data);
2052 fprintf(STDERR, "VLDB: Volume '%s' no match\n",
2053 as->parms[2].items->data);
2057 fprintf(STDERR, "VLDB: Volume '%s' no match\n",
2058 as->parms[2].items->data);
2062 server = htonl(entry.serverNumber[idx]);
2063 partition = entry.serverPartition[idx];
2067 code = UV_DeleteVolume(server, partition, volid);
2069 PrintDiagnostics("remove", code);
2073 MapPartIdIntoName(partition, pname);
2074 fprintf(STDOUT, "Volume %lu on partition %s server %s deleted\n",
2075 (unsigned long)volid, pname, hostutil_GetNameByINet(server));
2079 #define TESTM 0 /* set for move space tests, clear for production */
2082 register struct cmd_syndesc *as;
2085 afs_int32 volid, fromserver, toserver, frompart, topart;
2086 afs_int32 flags, code, err;
2087 char fromPartName[10], toPartName[10];
2089 struct diskPartition partition; /* for space check */
2092 volid = vsu_GetVolumeID(as->parms[0].items->data, cstruct, &err);
2095 PrintError("", err);
2097 fprintf(STDERR, "vos: can't find volume ID or name '%s'\n",
2098 as->parms[0].items->data);
2101 fromserver = GetServer(as->parms[1].items->data);
2102 if (fromserver == 0) {
2103 fprintf(STDERR, "vos: server '%s' not found in host table\n",
2104 as->parms[1].items->data);
2107 toserver = GetServer(as->parms[3].items->data);
2108 if (toserver == 0) {
2109 fprintf(STDERR, "vos: server '%s' not found in host table\n",
2110 as->parms[3].items->data);
2113 frompart = volutil_GetPartitionID(as->parms[2].items->data);
2115 fprintf(STDERR, "vos: could not interpret partition name '%s'\n",
2116 as->parms[2].items->data);
2119 if (!IsPartValid(frompart, fromserver, &code)) { /*check for validity of the partition */
2121 PrintError("", code);
2124 "vos : partition %s does not exist on the server\n",
2125 as->parms[2].items->data);
2128 topart = volutil_GetPartitionID(as->parms[4].items->data);
2130 fprintf(STDERR, "vos: could not interpret partition name '%s'\n",
2131 as->parms[4].items->data);
2134 if (!IsPartValid(topart, toserver, &code)) { /*check for validity of the partition */
2136 PrintError("", code);
2139 "vos : partition %s does not exist on the server\n",
2140 as->parms[4].items->data);
2145 if (as->parms[5].items) flags |= RV_NOCLONE;
2148 * check source partition for space to clone volume
2151 MapPartIdIntoName(topart, toPartName);
2152 MapPartIdIntoName(frompart, fromPartName);
2155 * check target partition for space to move volume
2158 code = UV_PartitionInfo(toserver, toPartName, &partition);
2160 fprintf(STDERR, "vos: cannot access partition %s\n", toPartName);
2164 fprintf(STDOUT, "target partition %s free space %d\n", toPartName,
2167 p = (volintInfo *) 0;
2168 code = UV_ListOneVolume(fromserver, frompart, volid, &p);
2170 fprintf(STDERR, "vos:cannot access volume %lu\n",
2171 (unsigned long)volid);
2176 fprintf(STDOUT, "volume %lu size %d\n", (unsigned long)volid,
2178 if (partition.free <= p->size) {
2180 "vos: no space on target partition %s to move volume %lu\n",
2181 toPartName, (unsigned long)volid);
2188 fprintf(STDOUT, "size test - don't do move\n");
2192 /* successful move still not guaranteed but shoot for it */
2195 UV_MoveVolume2(volid, fromserver, frompart, toserver, topart, flags);
2197 PrintDiagnostics("move", code);
2200 MapPartIdIntoName(topart, toPartName);
2201 MapPartIdIntoName(frompart, fromPartName);
2202 fprintf(STDOUT, "Volume %lu moved from %s %s to %s %s \n",
2203 (unsigned long)volid, as->parms[1].items->data, fromPartName,
2204 as->parms[3].items->data, toPartName);
2211 register struct cmd_syndesc *as;
2213 afs_int32 volid, fromserver, toserver, frompart, topart, code, err, flags;
2214 char fromPartName[10], toPartName[10], *tovolume;
2215 struct nvldbentry entry;
2216 struct diskPartition partition; /* for space check */
2219 volid = vsu_GetVolumeID(as->parms[0].items->data, cstruct, &err);
2222 PrintError("", err);
2224 fprintf(STDERR, "vos: can't find volume ID or name '%s'\n",
2225 as->parms[0].items->data);
2228 fromserver = GetServer(as->parms[1].items->data);
2229 if (fromserver == 0) {
2230 fprintf(STDERR, "vos: server '%s' not found in host table\n",
2231 as->parms[1].items->data);
2235 toserver = GetServer(as->parms[4].items->data);
2236 if (toserver == 0) {
2237 fprintf(STDERR, "vos: server '%s' not found in host table\n",
2238 as->parms[4].items->data);
2242 tovolume = as->parms[3].items->data;
2243 if (!ISNAMEVALID(tovolume)) {
2245 "vos: the name of the root volume %s exceeds the size limit of %d\n",
2246 tovolume, VOLSER_OLDMAXVOLNAME - 10);
2249 if (!VolNameOK(tovolume)) {
2251 "Illegal volume name %s, should not end in .readonly or .backup\n",
2255 if (IsNumeric(tovolume)) {
2256 fprintf(STDERR, "Illegal volume name %s, should not be a number\n",
2260 code = VLDB_GetEntryByName(tovolume, &entry);
2262 fprintf(STDERR, "Volume %s already exists\n", tovolume);
2263 PrintDiagnostics("copy", code);
2267 frompart = volutil_GetPartitionID(as->parms[2].items->data);
2269 fprintf(STDERR, "vos: could not interpret partition name '%s'\n",
2270 as->parms[2].items->data);
2273 if (!IsPartValid(frompart, fromserver, &code)) { /*check for validity of the partition */
2275 PrintError("", code);
2278 "vos : partition %s does not exist on the server\n",
2279 as->parms[2].items->data);
2283 topart = volutil_GetPartitionID(as->parms[5].items->data);
2285 fprintf(STDERR, "vos: could not interpret partition name '%s'\n",
2286 as->parms[5].items->data);
2289 if (!IsPartValid(topart, toserver, &code)) { /*check for validity of the partition */
2291 PrintError("", code);
2294 "vos : partition %s does not exist on the server\n",
2295 as->parms[5].items->data);
2300 if (as->parms[6].items) flags |= RV_OFFLINE;
2301 if (as->parms[7].items) flags |= RV_RDONLY;
2302 if (as->parms[8].items) flags |= RV_NOCLONE;
2304 MapPartIdIntoName(topart, toPartName);
2305 MapPartIdIntoName(frompart, fromPartName);
2308 * check target partition for space to move volume
2311 code = UV_PartitionInfo(toserver, toPartName, &partition);
2313 fprintf(STDERR, "vos: cannot access partition %s\n", toPartName);
2317 fprintf(STDOUT, "target partition %s free space %d\n", toPartName,
2320 p = (volintInfo *) 0;
2321 code = UV_ListOneVolume(fromserver, frompart, volid, &p);
2323 fprintf(STDERR, "vos:cannot access volume %lu\n",
2324 (unsigned long)volid);
2329 if (partition.free <= p->size) {
2331 "vos: no space on target partition %s to copy volume %lu\n",
2332 toPartName, (unsigned long)volid);
2338 /* successful copy still not guaranteed but shoot for it */
2341 UV_CopyVolume2(volid, fromserver, frompart, tovolume, toserver,
2344 PrintDiagnostics("copy", code);
2347 MapPartIdIntoName(topart, toPartName);
2348 MapPartIdIntoName(frompart, fromPartName);
2349 fprintf(STDOUT, "Volume %lu copied from %s %s to %s on %s %s \n",
2350 (unsigned long)volid, as->parms[1].items->data, fromPartName,
2351 tovolume, as->parms[4].items->data, toPartName);
2359 register struct cmd_syndesc *as;
2361 afs_int32 volid, fromserver, toserver, frompart, topart, tovolid;
2362 afs_int32 code, err, flags;
2363 char fromPartName[10], toPartName[10], toVolName[32], *tovolume;
2364 struct nvldbentry entry;
2365 struct diskPartition partition; /* for space check */
2368 p = (volintInfo *) 0;
2369 q = (volintInfo *) 0;
2371 volid = vsu_GetVolumeID(as->parms[0].items->data, cstruct, &err);
2374 PrintError("", err);
2376 fprintf(STDERR, "vos: can't find volume ID or name '%s'\n",
2377 as->parms[0].items->data);
2380 fromserver = GetServer(as->parms[1].items->data);
2381 if (fromserver == 0) {
2382 fprintf(STDERR, "vos: server '%s' not found in host table\n",
2383 as->parms[1].items->data);
2387 toserver = GetServer(as->parms[3].items->data);
2388 if (toserver == 0) {
2389 fprintf(STDERR, "vos: server '%s' not found in host table\n",
2390 as->parms[3].items->data);
2394 frompart = volutil_GetPartitionID(as->parms[2].items->data);
2396 fprintf(STDERR, "vos: could not interpret partition name '%s'\n",
2397 as->parms[2].items->data);
2400 if (!IsPartValid(frompart, fromserver, &code)) { /*check for validity of the partition */
2402 PrintError("", code);
2405 "vos : partition %s does not exist on the server\n",
2406 as->parms[2].items->data);
2410 topart = volutil_GetPartitionID(as->parms[4].items->data);
2412 fprintf(STDERR, "vos: could not interpret partition name '%s'\n",
2413 as->parms[4].items->data);
2416 if (!IsPartValid(topart, toserver, &code)) { /*check for validity of the partition */
2418 PrintError("", code);
2421 "vos : partition %s does not exist on the server\n",
2422 as->parms[4].items->data);
2426 if (as->parms[5].items) {
2427 tovolume = as->parms[5].items->data;
2428 if (!ISNAMEVALID(tovolume)) {
2430 "vos: the name of the root volume %s exceeds the size limit of %d\n",
2431 tovolume, VOLSER_OLDMAXVOLNAME - 10);
2434 if (!VolNameOK(tovolume)) {
2436 "Illegal volume name %s, should not end in .readonly or .backup\n",
2440 if (IsNumeric(tovolume)) {
2442 "Illegal volume name %s, should not be a number\n",
2447 /* use actual name of source volume */
2448 code = UV_ListOneVolume(fromserver, frompart, volid, &p);
2450 fprintf(STDERR, "vos:cannot access volume %lu\n",
2451 (unsigned long)volid);
2454 strcpy(toVolName, p->name);
2455 tovolume = toVolName;
2456 /* save p for size checks later */
2459 if (as->parms[6].items) {
2460 tovolid = vsu_GetVolumeID(as->parms[6].items->data, cstruct, &err);
2463 PrintError("", err);
2465 fprintf(STDERR, "vos: can't find volume ID or name '%s'\n",
2466 as->parms[6].items->data);
2472 tovolid = vsu_GetVolumeID(tovolume, cstruct, &err);
2475 PrintError("", err);
2477 fprintf(STDERR, "vos: can't find volume ID or name '%s'\n",
2486 if (as->parms[7].items) flags |= RV_OFFLINE;
2487 if (as->parms[8].items) flags |= RV_RDONLY;
2488 if (as->parms[9].items) flags |= RV_NOCLONE;
2489 if (as->parms[10].items) flags |= RV_CPINCR;
2491 MapPartIdIntoName(topart, toPartName);
2492 MapPartIdIntoName(frompart, fromPartName);
2495 * check target partition for space to move volume
2498 code = UV_PartitionInfo(toserver, toPartName, &partition);
2500 fprintf(STDERR, "vos: cannot access partition %s\n", toPartName);
2504 fprintf(STDOUT, "target partition %s free space %d\n", toPartName,
2507 /* Don't do this again if we did it above */
2509 code = UV_ListOneVolume(fromserver, frompart, volid, &p);
2511 fprintf(STDERR, "vos:cannot access volume %lu\n",
2512 (unsigned long)volid);
2517 /* OK if this fails */
2518 code = UV_ListOneVolume(toserver, topart, tovolid, &q);
2520 /* Treat existing volume size as "free" */
2522 p->size = (q->size < p->size) ? p->size - q->size : 0;
2524 if (partition.free <= p->size) {
2526 "vos: no space on target partition %s to copy volume %lu\n",
2527 toPartName, (unsigned long)volid);
2535 /* successful copy still not guaranteed but shoot for it */
2538 UV_CopyVolume2(volid, fromserver, frompart, tovolume, toserver,
2539 topart, tovolid, flags);
2541 PrintDiagnostics("shadow", code);
2544 MapPartIdIntoName(topart, toPartName);
2545 MapPartIdIntoName(frompart, fromPartName);
2546 fprintf(STDOUT, "Volume %lu shadowed from %s %s to %s %s \n",
2547 (unsigned long)volid, as->parms[1].items->data, fromPartName,
2548 as->parms[3].items->data, toPartName);
2556 register struct cmd_syndesc *as;
2558 afs_int32 server, part, volid, cloneid, voltype;
2559 char partName[10], *volname;
2560 afs_int32 code, err, flags;
2561 struct nvldbentry entry;
2563 volid = vsu_GetVolumeID(as->parms[0].items->data, cstruct, &err);
2566 PrintError("", err);
2568 fprintf(STDERR, "vos: can't find volume ID or name '%s'\n",
2569 as->parms[0].items->data);
2573 if (as->parms[1].items || as->parms[2].items) {
2574 if (!as->parms[1].items || !as->parms[2].items) {
2576 "Must specify both -server and -partition options\n");
2579 server = GetServer(as->parms[1].items->data);
2581 fprintf(STDERR, "vos: server '%s' not found in host table\n",
2582 as->parms[1].items->data);
2585 part = volutil_GetPartitionID(as->parms[2].items->data);
2587 fprintf(STDERR, "vos: could not interpret partition name '%s'\n",
2588 as->parms[2].items->data);
2591 if (!IsPartValid(part, server, &code)) { /*check for validity of the partition */
2593 PrintError("", code);
2596 "vos : partition %s does not exist on the server\n",
2597 as->parms[2].items->data);
2601 code = GetVolumeInfo(volid, &server, &part, &voltype, &entry);
2607 if (as->parms[3].items) {
2608 volname = as->parms[3].items->data;
2609 if (strlen(volname) > VOLSER_OLDMAXVOLNAME - 1) {
2611 "vos: the name of the root volume %s exceeds the size limit of %d\n",
2612 volname, VOLSER_OLDMAXVOLNAME - 1);
2615 if (!VolNameOK(volname)) {
2617 "Illegal volume name %s, should not end in .readonly or .backup\n",
2621 if (IsNumeric(volname)) {
2623 "Illegal volume name %s, should not be a number\n",
2630 if (as->parms[4].items) {
2631 cloneid = vsu_GetVolumeID(as->parms[4].items->data, cstruct, &err);
2634 PrintError("", err);
2636 fprintf(STDERR, "vos: can't find volume ID or name '%s'\n",
2637 as->parms[4].items->data);
2643 if (as->parms[5].items) flags |= RV_OFFLINE;
2644 if (as->parms[6].items) flags |= RV_RDONLY;
2648 UV_CloneVolume(server, part, volid, cloneid, volname, flags);
2651 PrintDiagnostics("clone", code);
2654 MapPartIdIntoName(part, partName);
2655 fprintf(STDOUT, "Created clone for volume %lu\n",
2656 as->parms[0].items->data);
2664 register struct cmd_syndesc *as;
2666 afs_int32 avolid, aserver, apart, vtype, code, err;
2667 struct nvldbentry entry;
2669 afs_int32 buvolid, buserver, bupart, butype;
2670 struct nvldbentry buentry;
2672 avolid = vsu_GetVolumeID(as->parms[0].items->data, cstruct, &err);
2675 PrintError("", err);
2677 fprintf(STDERR, "vos: can't find volume ID or name '%s'\n",
2678 as->parms[0].items->data);
2681 code = GetVolumeInfo(avolid, &aserver, &apart, &vtype, &entry);
2685 /* verify this is a readwrite volume */
2687 if (vtype != RWVOL) {
2688 fprintf(STDERR, "%s not RW volume\n", as->parms[0].items->data);
2692 /* is there a backup volume already? */
2694 if (entry.flags & BACK_EXISTS) {
2695 /* yep, where is it? */
2697 buvolid = entry.volumeId[BACKVOL];
2698 code = GetVolumeInfo(buvolid, &buserver, &bupart, &butype, &buentry);
2703 code = VLDB_IsSameAddrs(buserver, aserver, &err);
2706 "Failed to get info about server's %d address(es) from vlserver; aborting call!\n",
2712 "FATAL ERROR: backup volume %lu exists on server %lu\n",
2713 (unsigned long)buvolid, (unsigned long)buserver);
2718 /* nope, carry on */
2720 code = UV_BackupVolume(aserver, apart, avolid);
2723 PrintDiagnostics("backup", code);
2726 fprintf(STDOUT, "Created backup volume for %s \n",
2727 as->parms[0].items->data);
2733 register struct cmd_syndesc *as;
2736 struct nvldbentry entry;
2737 afs_int32 avolid, aserver, apart, vtype, code, err;
2740 if (as->parms[1].items)
2742 avolid = vsu_GetVolumeID(as->parms[0].items->data, cstruct, &err);
2745 PrintError("", err);
2747 fprintf(STDERR, "vos: can't find volume '%s'\n",
2748 as->parms[0].items->data);
2751 code = GetVolumeInfo(avolid, &aserver, &apart, &vtype, &entry);
2755 if (vtype != RWVOL) {
2756 fprintf(STDERR, "%s not a RW volume\n", as->parms[0].items->data);
2760 if (!ISNAMEVALID(entry.name)) {
2762 "Volume name %s is too long, rename before releasing\n",
2767 code = UV_ReleaseVolume(avolid, aserver, apart, force);
2769 PrintDiagnostics("release", code);
2772 fprintf(STDOUT, "Released volume %s successfully\n",
2773 as->parms[0].items->data);
2779 register struct cmd_syndesc *as;
2782 afs_int32 avolid, aserver, apart, voltype, fromdate = 0, code, err, i;
2783 char filename[NameLen];
2784 struct nvldbentry entry;
2786 rx_SetRxDeadTime(60 * 10);
2787 for (i = 0; i < MAXSERVERS; i++) {
2788 struct rx_connection *rxConn = ubik_GetRPCConn(cstruct, i);
2791 rx_SetConnDeadTime(rxConn, rx_connDeadTime);
2792 if (rxConn->service)
2793 rxConn->service->connDeadTime = rx_connDeadTime;
2796 avolid = vsu_GetVolumeID(as->parms[0].items->data, cstruct, &err);
2799 PrintError("", err);
2801 fprintf(STDERR, "vos: can't find volume '%s'\n",
2802 as->parms[0].items->data);
2806 if (as->parms[3].items || as->parms[4].items) {
2807 if (!as->parms[3].items || !as->parms[4].items) {
2809 "Must specify both -server and -partition options\n");
2812 aserver = GetServer(as->parms[3].items->data);
2814 fprintf(STDERR, "Invalid server name\n");
2817 apart = volutil_GetPartitionID(as->parms[4].items->data);
2819 fprintf(STDERR, "Invalid partition name\n");
2823 code = GetVolumeInfo(avolid, &aserver, &apart, &voltype, &entry);
2828 if (as->parms[1].items && strcmp(as->parms[1].items->data, "0")) {
2829 code = ktime_DateToInt32(as->parms[1].items->data, &fromdate);
2831 fprintf(STDERR, "vos: failed to parse date '%s' (error=%d))\n",
2832 as->parms[1].items->data, code);
2836 if (as->parms[2].items) {
2837 strcpy(filename, as->parms[2].items->data);
2839 strcpy(filename, "");
2842 if (as->parms[5].items) {
2844 UV_DumpClonedVolume(avolid, aserver, apart, fromdate,
2845 DumpFunction, filename);
2848 UV_DumpVolume(avolid, aserver, apart, fromdate, DumpFunction,
2852 PrintDiagnostics("dump", code);
2855 if (strcmp(filename, ""))
2856 fprintf(STDERR, "Dumped volume %s in file %s\n",
2857 as->parms[0].items->data, filename);
2859 fprintf(STDERR, "Dumped volume %s in stdout \n",
2860 as->parms[0].items->data);
2875 register struct cmd_syndesc *as;
2878 afs_int32 avolid, aserver, apart, code, vcode, err;
2879 afs_int32 aoverwrite = ASK;
2880 afs_int32 acreation = 0, alastupdate = 0;
2881 int restoreflags, readonly = 0, offline = 0, voltype = RWVOL;
2883 char afilename[NameLen], avolname[VOLSER_MAXVOLNAME + 1], apartName[10];
2884 char volname[VOLSER_MAXVOLNAME + 1];
2885 struct nvldbentry entry;
2889 if (as->parms[4].items) {
2890 avolid = vsu_GetVolumeID(as->parms[4].items->data, cstruct, &err);
2893 PrintError("", err);
2895 fprintf(STDERR, "vos: can't find volume '%s'\n",
2896 as->parms[4].items->data);
2902 if (as->parms[5].items) {
2903 if ((strcmp(as->parms[5].items->data, "a") == 0)
2904 || (strcmp(as->parms[5].items->data, "abort") == 0)) {
2906 } else if ((strcmp(as->parms[5].items->data, "f") == 0)
2907 || (strcmp(as->parms[5].items->data, "full") == 0)) {
2909 } else if ((strcmp(as->parms[5].items->data, "i") == 0)
2910 || (strcmp(as->parms[5].items->data, "inc") == 0)
2911 || (strcmp(as->parms[5].items->data, "increment") == 0)
2912 || (strcmp(as->parms[5].items->data, "incremental") == 0)) {
2915 fprintf(STDERR, "vos: %s is not a valid argument to -overwrite\n",
2916 as->parms[5].items->data);
2920 if (as->parms[6].items)
2922 if (as->parms[7].items) {
2927 if (as->parms[8].items) {
2928 if ((strcmp(as->parms[8].items->data, "d") == 0)
2929 || (strcmp(as->parms[8].items->data, "dump") == 0)) {
2930 acreation = TS_DUMP;
2931 } else if ((strcmp(as->parms[8].items->data, "k") == 0)
2932 || (strcmp(as->parms[8].items->data, "keep") == 0)) {
2933 acreation = TS_KEEP;
2934 } else if ((strcmp(as->parms[8].items->data, "n") == 0)
2935 || (strcmp(as->parms[8].items->data, "new") == 0)) {
2938 fprintf(STDERR, "vos: %s is not a valid argument to -creation\n",
2939 as->parms[8].items->data);
2944 if (as->parms[9].items) {
2945 if ((strcmp(as->parms[9].items->data, "d") == 0)
2946 || (strcmp(as->parms[9].items->data, "dump") == 0)) {
2947 alastupdate = TS_DUMP;
2948 } else if ((strcmp(as->parms[9].items->data, "k") == 0)
2949 || (strcmp(as->parms[9].items->data, "keep") == 0)) {
2950 alastupdate = TS_KEEP;
2951 } else if ((strcmp(as->parms[9].items->data, "n") == 0)
2952 || (strcmp(as->parms[9].items->data, "new") == 0)) {
2953 alastupdate = TS_NEW;
2955 fprintf(STDERR, "vos: %s is not a valid argument to -lastupdate\n",
2956 as->parms[9].items->data);
2961 aserver = GetServer(as->parms[0].items->data);
2963 fprintf(STDERR, "vos: server '%s' not found in host table\n",
2964 as->parms[0].items->data);
2967 apart = volutil_GetPartitionID(as->parms[1].items->data);
2969 fprintf(STDERR, "vos: could not interpret partition name '%s'\n",
2970 as->parms[1].items->data);
2973 if (!IsPartValid(apart, aserver, &code)) { /*check for validity of the partition */
2975 PrintError("", code);
2978 "vos : partition %s does not exist on the server\n",
2979 as->parms[1].items->data);
2982 strcpy(avolname, as->parms[2].items->data);
2983 if (!ISNAMEVALID(avolname)) {
2985 "vos: the name of the volume %s exceeds the size limit\n",
2989 if (!VolNameOK(avolname)) {
2991 "Illegal volume name %s, should not end in .readonly or .backup\n",
2995 if (as->parms[3].items) {
2996 strcpy(afilename, as->parms[3].items->data);
2997 if (!FileExists(afilename)) {
2998 fprintf(STDERR, "Can't access file %s\n", afilename);
3002 strcpy(afilename, "");
3005 /* Check if volume exists or not */
3007 vsu_ExtractName(volname, avolname);
3008 vcode = VLDB_GetEntryByName(volname, &entry);
3009 if (vcode) { /* no volume - do a full restore */
3010 restoreflags = RV_FULLRST;
3011 if ((aoverwrite == INC) || (aoverwrite == ABORT))
3013 "Volume does not exist; Will perform a full restore\n");
3016 else if ((!readonly && Lp_GetRwIndex(&entry) == -1) /* RW volume does not exist - do a full */
3017 ||(readonly && !Lp_ROMatch(0, 0, &entry))) { /* RO volume does not exist - do a full */
3018 restoreflags = RV_FULLRST;
3019 if ((aoverwrite == INC) || (aoverwrite == ABORT))
3021 "%s Volume does not exist; Will perform a full restore\n",
3022 readonly ? "RO" : "RW");
3025 avolid = entry.volumeId[voltype];
3026 } else if (entry.volumeId[voltype] != 0
3027 && entry.volumeId[voltype] != avolid) {
3028 avolid = entry.volumeId[voltype];
3032 else { /* volume exists - do we do a full incremental or abort */
3033 int Oserver, Opart, Otype, vol_elsewhere = 0;
3034 struct nvldbentry Oentry;
3038 avolid = entry.volumeId[voltype];
3039 } else if (entry.volumeId[voltype] != 0
3040 && entry.volumeId[voltype] != avolid) {
3041 avolid = entry.volumeId[voltype];
3044 /* A file name was specified - check if volume is on another partition */
3045 vcode = GetVolumeInfo(avolid, &Oserver, &Opart, &Otype, &Oentry);
3049 vcode = VLDB_IsSameAddrs(Oserver, aserver, &err);
3052 "Failed to get info about server's %d address(es) from vlserver (err=%d); aborting call!\n",
3056 if (!vcode || (Opart != apart))
3059 if (aoverwrite == ASK) {
3060 if (strcmp(afilename, "") == 0) { /* The file is from standard in */
3062 "Volume exists and no -overwrite option specified; Aborting restore command\n");
3066 /* Ask what to do */
3067 if (vol_elsewhere) {
3069 "The volume %s %u already exists on a different server/part\n",
3070 volname, entry.volumeId[voltype]);
3072 "Do you want to do a full restore or abort? [fa](a): ");
3075 "The volume %s %u already exists in the VLDB\n",
3076 volname, entry.volumeId[voltype]);
3078 "Do you want to do a full/incremental restore or abort? [fia](a): ");
3081 while (!(dc == EOF || dc == '\n'))
3082 dc = getchar(); /* goto end of line */
3083 if ((c == 'f') || (c == 'F'))
3085 else if ((c == 'i') || (c == 'I'))
3091 if (aoverwrite == ABORT) {
3092 fprintf(STDERR, "Volume exists; Aborting restore command\n");
3094 } else if (aoverwrite == FULL) {
3095 restoreflags = RV_FULLRST;
3097 "Volume exists; Will delete and perform full restore\n");
3098 } else if (aoverwrite == INC) {
3100 if (vol_elsewhere) {
3102 "%s volume %lu already exists on a different server/part; not allowed\n",
3103 readonly ? "RO" : "RW", (unsigned long)avolid);
3109 restoreflags |= RV_OFFLINE;
3111 restoreflags |= RV_RDONLY;
3113 switch (acreation) {
3115 restoreflags |= RV_CRDUMP;
3118 restoreflags |= RV_CRKEEP;
3121 restoreflags |= RV_CRNEW;
3124 if (aoverwrite == FULL)
3125 restoreflags |= RV_CRNEW;
3127 restoreflags |= RV_CRKEEP;
3130 switch (alastupdate) {
3132 restoreflags |= RV_LUDUMP;
3135 restoreflags |= RV_LUKEEP;
3138 restoreflags |= RV_LUNEW;
3141 restoreflags |= RV_LUDUMP;
3145 UV_RestoreVolume(aserver, apart, avolid, avolname, restoreflags,
3146 WriteData, afilename);
3148 PrintDiagnostics("restore", code);
3151 MapPartIdIntoName(apart, apartName);
3154 * patch typo here - originally "parms[1]", should be "parms[0]"
3157 fprintf(STDOUT, "Restored volume %s on %s %s\n", avolname,
3158 as->parms[0].items->data, apartName);
3164 register struct cmd_syndesc *as;
3167 afs_int32 avolid, code, err;
3169 avolid = vsu_GetVolumeID(as->parms[0].items->data, cstruct, &err);
3172 PrintError("", err);
3174 fprintf(STDERR, "vos: can't find volume '%s'\n",
3175 as->parms[0].items->data);
3179 code = UV_LockRelease(avolid);
3181 PrintDiagnostics("unlock", code);
3184 fprintf(STDOUT, "Released lock on vldb entry for volume %s\n",
3185 as->parms[0].items->data);
3191 register struct cmd_syndesc *as;
3193 afs_int32 avolid, aserver, apart, code, err;
3194 char apartName[10], avolname[VOLSER_MAXVOLNAME + 1];
3196 vsu_ExtractName(avolname, as->parms[2].items->data);;
3197 avolid = vsu_GetVolumeID(avolname, cstruct, &err);
3200 PrintError("", err);
3202 fprintf(STDERR, "vos: can't find volume '%s'\n",
3203 as->parms[2].items->data);
3206 aserver = GetServer(as->parms[0].items->data);
3208 fprintf(STDERR, "vos: server '%s' not found in host table\n",
3209 as->parms[0].items->data);
3212 apart = volutil_GetPartitionID(as->parms[1].items->data);
3214 fprintf(STDERR, "vos: could not interpret partition name '%s'\n",
3215 as->parms[1].items->data);
3218 if (!IsPartValid(apart, aserver, &code)) { /*check for validity of the partition */
3220 PrintError("", code);
3223 "vos : partition %s does not exist on the server\n",
3224 as->parms[1].items->data);
3227 code = UV_AddSite(aserver, apart, avolid);
3229 PrintDiagnostics("addsite", code);
3232 MapPartIdIntoName(apart, apartName);
3233 fprintf(STDOUT, "Added replication site %s %s for volume %s\n",
3234 as->parms[0].items->data, apartName, as->parms[2].items->data);
3240 register struct cmd_syndesc *as;
3243 afs_int32 avolid, aserver, apart, code, err;
3244 char apartName[10], avolname[VOLSER_MAXVOLNAME + 1];
3246 vsu_ExtractName(avolname, as->parms[2].items->data);
3247 avolid = vsu_GetVolumeID(avolname, cstruct, &err);
3250 PrintError("", err);
3252 fprintf(STDERR, "vos: can't find volume '%s'\n",
3253 as->parms[2].items->data);
3256 aserver = GetServer(as->parms[0].items->data);
3258 fprintf(STDERR, "vos: server '%s' not found in host table\n",
3259 as->parms[0].items->data);
3262 apart = volutil_GetPartitionID(as->parms[1].items->data);
3264 fprintf(STDERR, "vos: could not interpret partition name '%s'\n",
3265 as->parms[1].items->data);
3269 *skip the partition validity check, since it is possible that the partition
3270 *has since been decomissioned.
3273 if (!IsPartValid(apart,aserver,&code)){
3274 if(code) PrintError("",code);
3275 else fprintf(STDERR,"vos : partition %s does not exist on the server\n",as->parms[1].items->data);
3279 code = UV_RemoveSite(aserver, apart, avolid);
3281 PrintDiagnostics("remsite", code);
3284 MapPartIdIntoName(apart, apartName);
3285 fprintf(STDOUT, "Removed replication site %s %s for volume %s\n",
3286 as->parms[0].items->data, apartName, as->parms[2].items->data);
3292 register struct cmd_syndesc *as;
3294 afs_int32 avolid, aserver, apart, code, err;
3297 avolid = vsu_GetVolumeID(as->parms[2].items->data, cstruct, &err);
3300 PrintError("", err);
3302 fprintf(STDERR, "vos: can't find volume '%s'\n",
3303 as->parms[2].items->data);
3306 aserver = GetServer(as->parms[0].items->data);
3308 fprintf(STDERR, "vos: server '%s' not found in host table\n",
3309 as->parms[0].items->data);
3312 apart = 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(apart, aserver, &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);
3327 code = UV_ChangeLocation(aserver, apart, avolid);
3329 PrintDiagnostics("addsite", code);
3332 MapPartIdIntoName(apart, apartName);
3333 fprintf(STDOUT, "Changed location to %s %s for volume %s\n",
3334 as->parms[0].items->data, apartName, as->parms[2].items->data);
3340 register struct cmd_syndesc *as;
3342 afs_int32 aserver, code;
3343 struct partList dummyPartList;
3348 aserver = GetServer(as->parms[0].items->data);
3350 fprintf(STDERR, "vos: server '%s' not found in host table\n",
3351 as->parms[0].items->data);
3356 code = UV_ListPartitions(aserver, &dummyPartList, &cnt);
3358 PrintDiagnostics("listpart", code);
3362 fprintf(STDOUT, "The partitions on the server are:\n");
3363 for (i = 0; i < cnt; i++) {
3364 if (dummyPartList.partFlags[i] & PARTVALID) {
3365 memset(pname, 0, sizeof(pname));
3366 MapPartIdIntoName(dummyPartList.partId[i], pname);
3367 fprintf(STDOUT, " %10s ", pname);
3369 if ((i % 5) == 0 && (i != 0))
3370 fprintf(STDOUT, "\n");
3373 fprintf(STDOUT, "\n");
3374 fprintf(STDOUT, "Total: %d\n", total);
3380 CompareVolName(p1, p2)
3383 volintInfo *arg1, *arg2;
3385 arg1 = (volintInfo *) p1;
3386 arg2 = (volintInfo *) p2;
3387 return (strcmp(arg1->name, arg2->name));
3391 /*------------------------------------------------------------------------
3392 * PRIVATE XCompareVolName
3395 * Comparison routine for volume names coming from an extended
3399 * a_obj1P : Char ptr to first extended vol info object
3400 * a_obj1P : Char ptr to second extended vol info object
3403 * The value of strcmp() on the volume names within the passed
3404 * objects (i,e., -1, 0, or 1).
3407 * Passed to qsort() as the designated comparison routine.
3411 *------------------------------------------------------------------------*/
3414 XCompareVolName(a_obj1P, a_obj2P)
3415 char *a_obj1P, *a_obj2P;
3417 { /*XCompareVolName */
3420 (((struct volintXInfo *)(a_obj1P))->name,
3421 ((struct volintXInfo *)(a_obj2P))->name));
3423 } /*XCompareVolName */
3426 CompareVolID(p1, p2)
3429 volintInfo *arg1, *arg2;
3431 arg1 = (volintInfo *) p1;
3432 arg2 = (volintInfo *) p2;
3433 if (arg1->volid == arg2->volid)
3435 if (arg1->volid > arg2->volid)
3442 /*------------------------------------------------------------------------
3443 * PRIVATE XCompareVolID
3446 * Comparison routine for volume IDs coming from an extended
3450 * a_obj1P : Char ptr to first extended vol info object
3451 * a_obj1P : Char ptr to second extended vol info object
3454 * The value of strcmp() on the volume names within the passed
3455 * objects (i,e., -1, 0, or 1).
3458 * Passed to qsort() as the designated comparison routine.
3462 *------------------------------------------------------------------------*/
3465 XCompareVolID(a_obj1P, a_obj2P)
3466 char *a_obj1P, *a_obj2P;
3468 { /*XCompareVolID */
3470 afs_int32 id1, id2; /*Volume IDs we're comparing */
3472 id1 = ((struct volintXInfo *)(a_obj1P))->volid;
3473 id2 = ((struct volintXInfo *)(a_obj2P))->volid;
3481 } /*XCompareVolID */
3483 /*------------------------------------------------------------------------
3484 * PRIVATE ListVolumes
3487 * Routine used to list volumes, contacting the Volume Server
3488 * directly, bypassing the VLDB.
3491 * as : Ptr to parsed command line arguments.
3494 * 0 Successful operation
3497 * Nothing interesting.
3501 *------------------------------------------------------------------------*/
3505 register struct cmd_syndesc *as;
3507 afs_int32 apart, int32list, fast;
3508 afs_int32 aserver, code;
3509 volintInfo *pntr, *oldpntr;
3513 volintXInfo *xInfoP, *origxInfoP; /*Ptr to current/orig extended vol info */
3514 int wantExtendedInfo; /*Do we want extended vol info? */
3517 struct partList dummyPartList;
3525 if (as->parms[3].items)
3527 if (as->parms[4].items)
3531 if (as->parms[2].items)
3537 if (as->parms[5].items) {
3539 * We can't coexist with the fast flag.
3543 "vos: Can't use the -fast and -extended flags together\n");
3548 * We need to turn on ``long'' listings to get the full effect.
3550 wantExtendedInfo = 1;
3553 wantExtendedInfo = 0;
3554 if (as->parms[1].items) {
3555 apart = volutil_GetPartitionID(as->parms[1].items->data);
3557 fprintf(STDERR, "vos: could not interpret partition name '%s'\n",
3558 as->parms[1].items->data);
3561 dummyPartList.partId[0] = apart;
3562 dummyPartList.partFlags[0] = PARTVALID;
3565 aserver = GetServer(as->parms[0].items->data);
3567 fprintf(STDERR, "vos: server '%s' not found in host table\n",
3568 as->parms[0].items->data);
3573 if (!IsPartValid(apart, aserver, &code)) { /*check for validity of the partition */
3575 PrintError("", code);
3578 "vos : partition %s does not exist on the server\n",
3579 as->parms[1].items->data);
3583 code = UV_ListPartitions(aserver, &dummyPartList, &cnt);
3585 PrintDiagnostics("listvol", code);
3589 for (i = 0; i < cnt; i++) {
3590 if (dummyPartList.partFlags[i] & PARTVALID) {
3591 if (wantExtendedInfo)
3593 UV_XListVolumes(aserver, dummyPartList.partId[i], all,
3597 UV_ListVolumes(aserver, dummyPartList.partId[i], all,
3600 PrintDiagnostics("listvol", code);
3605 if (wantExtendedInfo) {
3606 origxInfoP = xInfoP;
3607 base = (char *)xInfoP;
3610 base = (char *)pntr;
3614 if (wantExtendedInfo)
3615 qsort(base, count, sizeof(volintXInfo), XCompareVolName);
3617 qsort(base, count, sizeof(volintInfo), CompareVolName);
3619 if (wantExtendedInfo)
3620 qsort(base, count, sizeof(volintXInfo), XCompareVolID);
3622 qsort(base, count, sizeof(volintInfo), CompareVolID);
3624 MapPartIdIntoName(dummyPartList.partId[i], pname);
3627 "Total number of volumes on server %s partition %s: %lu \n",
3628 as->parms[0].items->data, pname,
3629 (unsigned long)count);
3630 if (wantExtendedInfo) {
3631 #ifdef FULL_LISTVOL_SWITCH
3632 if (as->parms[6].items)
3633 XDisplayVolumes2(aserver, dummyPartList.partId[i], origxInfoP,
3634 count, int32list, fast, quiet);
3636 #endif /* FULL_LISTVOL_SWITCH */
3637 XDisplayVolumes(aserver, dummyPartList.partId[i], origxInfoP,
3638 count, int32list, fast, quiet);
3641 xInfoP = (volintXInfo *) 0;
3643 #ifdef FULL_LISTVOL_SWITCH
3644 if (as->parms[6].items)
3645 DisplayVolumes2(aserver, dummyPartList.partId[i], oldpntr,
3648 #endif /* FULL_LISTVOL_SWITCH */
3649 DisplayVolumes(aserver, dummyPartList.partId[i], oldpntr,
3650 count, int32list, fast, quiet);
3653 pntr = (volintInfo *) 0;
3662 register struct cmd_syndesc *as;
3664 afs_int32 pnum = 0, code; /* part name */
3670 if (as->parms[0].items) {
3671 tserver = GetServer(as->parms[0].items->data);
3673 fprintf(STDERR, "vos: host '%s' not found in host table\n",
3674 as->parms[0].items->data);
3679 if (as->parms[1].items) {
3680 pnum = volutil_GetPartitionID(as->parms[1].items->data);
3682 fprintf(STDERR, "vos: could not interpret partition name '%s'\n",
3683 as->parms[1].items->data);
3686 if (!IsPartValid(pnum, tserver, &code)) { /*check for validity of the partition */
3688 PrintError("", code);
3691 "vos: partition %s does not exist on the server\n",
3692 as->parms[1].items->data);
3699 "The -partition option requires a -server option\n");
3704 if (as->parms[2].items) {
3705 /* Synchronize an individual volume */
3706 volname = as->parms[2].items->data;
3707 code = UV_SyncVolume(tserver, pnum, volname, flags);
3711 "Without a -volume option, the -server option is required\n");
3714 code = UV_SyncVldb(tserver, pnum, flags, 0 /*unused */ );
3718 PrintDiagnostics("syncvldb", code);
3722 /* Print a summary of what we did */
3724 fprintf(STDOUT, "VLDB volume %s synchronized", volname);
3726 fprintf(STDOUT, "VLDB synchronized");
3728 fprintf(STDOUT, " with state of server %s", as->parms[0].items->data);
3731 MapPartIdIntoName(pnum, part);
3732 fprintf(STDOUT, " partition %s\n", part);
3734 fprintf(STDOUT, "\n");
3741 register struct cmd_syndesc *as;
3744 afs_int32 pnum, code; /* part name */
3749 tserver = GetServer(as->parms[0].items->data);
3751 fprintf(STDERR, "vos: host '%s' not found in host table\n",
3752 as->parms[0].items->data);
3755 if (as->parms[1].items) {
3756 pnum = volutil_GetPartitionID(as->parms[1].items->data);
3758 fprintf(STDERR, "vos: could not interpret partition name '%s'\n",
3759 as->parms[1].items->data);
3762 if (!IsPartValid(pnum, tserver, &code)) { /*check for validity of the partition */
3764 PrintError("", code);
3767 "vos : partition %s does not exist on the server\n",
3768 as->parms[1].items->data);
3776 code = UV_SyncServer(tserver, pnum, flags, 0 /*unused */ );
3778 PrintDiagnostics("syncserv", code);
3782 MapPartIdIntoName(pnum, part);
3783 fprintf(STDOUT, "Server %s partition %s synchronized with VLDB\n",
3784 as->parms[0].items->data, part);
3786 fprintf(STDOUT, "Server %s synchronized with VLDB\n",
3787 as->parms[0].items->data);
3796 struct nvldbentry entry;
3799 /* The vlserver will handle names with the .readonly
3800 * and .backup extension as well as volume ids.
3802 vcode = VLDB_GetEntryByName(name, &entry);
3804 PrintError("", vcode);
3807 MapHostToNetwork(&entry);
3808 EnumerateEntry(&entry);
3810 /* Defect #3027: grubby check to handle locked volume.
3811 * If VLOP_ALLOPERS is set, the entry is locked.
3812 * Leave this routine as is, but put in correct check.
3814 if (entry.flags & VLOP_ALLOPERS)
3815 fprintf(STDOUT, " Volume is currently LOCKED \n");
3822 register struct cmd_syndesc *as;
3825 struct nvldbentry entry;
3826 afs_int32 volid, code, server, part, zapbackupid = 0, backupid = 0, err;
3828 if (as->parms[3].items) {
3829 /* force flag is on, use the other version */
3830 return NukeVolume(as);
3833 if (as->parms[4].items) {
3837 volid = vsu_GetVolumeID(as->parms[2].items->data, cstruct, &err);
3840 PrintError("", err);
3842 fprintf(STDERR, "vos: can't find volume '%s'\n",
3843 as->parms[2].items->data);
3846 part = volutil_GetPartitionID(as->parms[1].items->data);
3848 fprintf(STDERR, "vos: could not interpret partition name '%s'\n",
3849 as->parms[1].items->data);
3852 server = GetServer(as->parms[0].items->data);
3854 fprintf(STDERR, "vos: host '%s' not found in host table\n",
3855 as->parms[0].items->data);
3858 if (!IsPartValid(part, server, &code)) { /*check for validity of the partition */
3860 PrintError("", code);
3863 "vos : partition %s does not exist on the server\n",
3864 as->parms[1].items->data);
3867 code = VLDB_GetEntryByID(volid, -1, &entry);
3869 if (volid == entry.volumeId[RWVOL])
3870 backupid = entry.volumeId[BACKVOL];
3872 "Warning: Entry for volume number %lu exists in VLDB (but we're zapping it anyway!)\n",
3873 (unsigned long)volid);
3876 volintInfo *pntr = (volintInfo *) 0;
3879 code = UV_ListOneVolume(server, part, volid, &pntr);
3881 if (volid == pntr->parentID)
3882 backupid = pntr->backupID;
3888 code = UV_VolumeZap(server, part, backupid);
3890 PrintDiagnostics("zap", code);
3893 fprintf(STDOUT, "Backup Volume %lu deleted\n",
3894 (unsigned long)backupid);
3897 code = UV_VolumeZap(server, part, volid);
3899 PrintDiagnostics("zap", code);
3902 fprintf(STDOUT, "Volume %lu deleted\n", (unsigned long)volid);
3909 register struct cmd_syndesc *as;
3912 afs_int32 server, code;
3913 transDebugInfo *pntr, *oldpntr;
3918 server = GetServer(as->parms[0].items->data);
3920 fprintf(STDERR, "vos: host '%s' not found in host table\n",
3921 as->parms[0].items->data);
3924 code = UV_VolserStatus(server, &pntr, &count);
3926 PrintDiagnostics("status", code);
3931 fprintf(STDOUT, "No active transactions on %s\n",
3932 as->parms[0].items->data);
3934 fprintf(STDOUT, "Total transactions: %d\n", count);
3936 for (i = 0; i < count; i++) {
3937 /*print out the relevant info */
3938 fprintf(STDOUT, "--------------------------------------\n");
3939 fprintf(STDOUT, "transaction: %lu created: %s",
3940 (unsigned long)pntr->tid, ctime((time_t *) & pntr->time));
3941 if (pntr->returnCode) {
3942 fprintf(STDOUT, "returnCode: %lu\n",
3943 (unsigned long)pntr->returnCode);
3946 fprintf(STDOUT, "attachFlags: ");
3947 switch (pntr->iflags) {
3949 fprintf(STDOUT, "offline ");
3952 fprintf(STDOUT, "busy ");
3955 fprintf(STDOUT, "readonly ");
3958 fprintf(STDOUT, "create ");
3961 fprintf(STDOUT, "create volid ");
3964 fprintf(STDOUT, "\n");
3967 fprintf(STDOUT, "volumeStatus: ");
3968 switch (pntr->vflags) {
3969 case VTDeleteOnSalvage:
3970 fprintf(STDOUT, "deleteOnSalvage ");
3971 case VTOutOfService:
3972 fprintf(STDOUT, "outOfService ");
3974 fprintf(STDOUT, "deleted ");
3976 fprintf(STDOUT, "\n");
3979 fprintf(STDOUT, "transactionFlags: ");
3980 fprintf(STDOUT, "delete\n");
3982 MapPartIdIntoName(pntr->partition, pname);
3983 fprintf(STDOUT, "volume: %lu partition: %s procedure: %s\n",
3984 (unsigned long)pntr->volid, pname, pntr->lastProcName);
3985 if (pntr->callValid) {
3987 "packetRead: %lu lastReceiveTime: %d packetSend: %lu lastSendTime: %d\n",
3988 (unsigned long)pntr->readNext, pntr->lastReceiveTime,
3989 (unsigned long)pntr->transmitNext, pntr->lastSendTime);
3992 fprintf(STDOUT, "--------------------------------------\n");
3993 fprintf(STDOUT, "\n");
4002 register struct cmd_syndesc *as;
4004 afs_int32 code1, code2, code;
4005 struct nvldbentry entry;
4007 code1 = VLDB_GetEntryByName(as->parms[0].items->data, &entry);
4009 fprintf(STDERR, "vos: Could not find entry for volume %s\n",
4010 as->parms[0].items->data);
4013 code2 = VLDB_GetEntryByName(as->parms[1].items->data, &entry);
4014 if ((!code1) && (!code2)) { /*the newname already exists */
4015 fprintf(STDERR, "vos: volume %s already exists\n",
4016 as->parms[1].items->data);
4020 if (code1 && code2) {
4021 fprintf(STDERR, "vos: Could not find entry for volume %s or %s\n",
4022 as->parms[0].items->data, as->parms[1].items->data);
4025 if (!VolNameOK(as->parms[0].items->data)) {
4027 "Illegal volume name %s, should not end in .readonly or .backup\n",
4028 as->parms[0].items->data);
4031 if (!ISNAMEVALID(as->parms[1].items->data)) {
4033 "vos: the new volume name %s exceeds the size limit of %d\n",
4034 as->parms[1].items->data, VOLSER_OLDMAXVOLNAME - 10);
4037 if (!VolNameOK(as->parms[1].items->data)) {
4039 "Illegal volume name %s, should not end in .readonly or .backup\n",
4040 as->parms[1].items->data);
4043 if (IsNumeric(as->parms[1].items->data)) {
4044 fprintf(STDERR, "Illegal volume name %s, should not be a number\n",
4045 as->parms[1].items->data);
4048 MapHostToNetwork(&entry);
4050 UV_RenameVolume(&entry, as->parms[0].items->data,
4051 as->parms[1].items->data);
4053 PrintDiagnostics("rename", code);
4056 fprintf(STDOUT, "Renamed volume %s to %s\n", as->parms[0].items->data,
4057 as->parms[1].items->data);
4061 GetVolumeInfo(volid, server, part, voltype, rentry)
4062 afs_int32 *server, volid, *part, *voltype;
4063 register struct nvldbentry *rentry;
4068 vcode = VLDB_GetEntryByID(volid, -1, rentry);
4071 "Could not fetch the entry for volume %lu from VLDB \n",
4072 (unsigned long)volid);
4073 PrintError("", vcode);
4076 MapHostToNetwork(rentry);
4077 if (volid == rentry->volumeId[ROVOL]) {
4079 for (i = 0; i < rentry->nServers; i++) {
4080 if ((index == -1) && (rentry->serverFlags[i] & ITSROVOL)
4081 && !(rentry->serverFlags[i] & RO_DONTUSE))
4086 "RO volume is not found in VLDB entry for volume %lu\n",
4087 (unsigned long)volid);
4091 *server = rentry->serverNumber[index];
4092 *part = rentry->serverPartition[index];
4096 index = Lp_GetRwIndex(rentry);
4099 "RW Volume is not found in VLDB entry for volume %lu\n",
4100 (unsigned long)volid);
4103 if (volid == rentry->volumeId[RWVOL]) {
4105 *server = rentry->serverNumber[index];
4106 *part = rentry->serverPartition[index];
4109 if (volid == rentry->volumeId[BACKVOL]) {
4111 *server = rentry->serverNumber[index];
4112 *part = rentry->serverPartition[index];
4116 "unexpected volume type for volume %lu\n",
4117 (unsigned long)volid);
4123 register struct cmd_syndesc *as;
4129 struct VldbListByAttributes attributes;
4130 nbulkentries arrayEntries;
4131 register struct nvldbentry *vllist;
4132 struct cmd_item *itp;
4135 char prefix[VOLSER_MAXVOLNAME + 1];
4137 afs_int32 totalBack = 0, totalFail = 0, err;
4139 if (as->parms[0].items) { /* -id */
4140 if (as->parms[1].items || as->parms[2].items || as->parms[3].items) {
4142 "You cannot use -server, -partition, or -prefix with the -id argument\n");
4145 for (itp = as->parms[0].items; itp; itp = itp->next) {
4146 avolid = vsu_GetVolumeID(itp->data, cstruct, &err);
4149 PrintError("", err);
4151 fprintf(STDERR, "vos: can't find volume '%s'\n",
4155 if (as->parms[4].items) { /* -noexecute */
4156 fprintf(STDOUT, "Would have deleted VLDB entry for %s \n",
4161 vcode = ubik_Call(VL_DeleteEntry, cstruct, 0, avolid, RWVOL);
4163 fprintf(STDERR, "Could not delete entry for volume %s\n",
4166 "You must specify a RW volume name or ID "
4167 "(the entire VLDB entry will be deleted)\n");
4168 PrintError("", vcode);
4174 fprintf(STDOUT, "Deleted %d VLDB entries\n", totalBack);
4178 if (!as->parms[1].items && !as->parms[2].items && !as->parms[3].items) {
4179 fprintf(STDERR, "You must specify an option\n");
4183 /* Zero out search attributes */
4184 memset(&attributes, 0, sizeof(struct VldbListByAttributes));
4186 if (as->parms[1].items) { /* -prefix */
4187 strncpy(prefix, as->parms[1].items->data, VOLSER_MAXVOLNAME);
4189 if (!as->parms[2].items && !as->parms[3].items) { /* a single entry only */
4191 "You must provide -server with the -prefix argument\n");
4196 if (as->parms[2].items) { /* -server */
4198 aserver = GetServer(as->parms[2].items->data);
4200 fprintf(STDERR, "vos: server '%s' not found in host table\n",
4201 as->parms[2].items->data);
4204 attributes.server = ntohl(aserver);
4205 attributes.Mask |= VLLIST_SERVER;
4208 if (as->parms[3].items) { /* -partition */
4209 if (!as->parms[2].items) {
4211 "You must provide -server with the -partition argument\n");
4214 apart = volutil_GetPartitionID(as->parms[3].items->data);
4216 fprintf(STDERR, "vos: could not interpret partition name '%s'\n",
4217 as->parms[3].items->data);
4220 attributes.partition = apart;
4221 attributes.Mask |= VLLIST_PARTITION;
4224 /* Print status line of what we are doing */
4225 fprintf(STDOUT, "Deleting VLDB entries for ");
4226 if (as->parms[2].items) {
4227 fprintf(STDOUT, "server %s ", as->parms[2].items->data);
4229 if (as->parms[3].items) {
4231 MapPartIdIntoName(apart, pname);
4232 fprintf(STDOUT, "partition %s ", pname);
4235 fprintf(STDOUT, "which are prefixed with %s ", prefix);
4237 fprintf(STDOUT, "\n");
4240 /* Get all the VLDB entries on a server and/or partition */
4241 memset(&arrayEntries, 0, sizeof(arrayEntries));
4242 vcode = VLDB_ListAttributes(&attributes, &nentries, &arrayEntries);
4244 fprintf(STDERR, "Could not access the VLDB for attributes\n");
4245 PrintError("", vcode);
4249 /* Process each entry */
4250 for (j = 0; j < nentries; j++) {
4251 vllist = &arrayEntries.nbulkentries_val[j];
4253 /* It only deletes the RW volumes */
4254 if (strncmp(vllist->name, prefix, strlen(prefix))) {
4257 "Omitting to delete %s due to prefix %s mismatch\n",
4258 vllist->name, prefix);
4265 if (as->parms[4].items) { /* -noexecute */
4266 fprintf(STDOUT, "Would have deleted VLDB entry for %s \n",
4272 /* Only matches the RW volume name */
4273 avolid = vllist->volumeId[RWVOL];
4274 vcode = ubik_Call(VL_DeleteEntry, cstruct, 0, avolid, RWVOL);
4276 fprintf(STDOUT, "Could not delete VDLB entry for %s\n",
4279 PrintError("", vcode);
4284 fprintf(STDOUT, "Deleted VLDB entry for %s \n", vllist->name);
4289 fprintf(STDOUT, "----------------------\n");
4291 "Total VLDB entries deleted: %lu; failed to delete: %lu\n",
4292 (unsigned long)totalBack, (unsigned long)totalFail);
4293 if (arrayEntries.nbulkentries_val)
4294 free(arrayEntries.nbulkentries_val);
4300 CompareVldbEntryByName(p1, p2)
4303 struct nvldbentry *arg1, *arg2;
4305 arg1 = (struct nvldbentry *)p1;
4306 arg2 = (struct nvldbentry *)p2;
4307 return (strcmp(arg1->name, arg2->name));
4311 static int CompareVldbEntry(p1,p2)
4314 struct nvldbentry *arg1,*arg2;
4317 char comp1[100],comp2[100];
4318 char temp1[20],temp2[20];
4320 arg1 = (struct nvldbentry *)p1;
4321 arg2 = (struct nvldbentry *)p2;
4325 for(i = 0; i < arg1->nServers; i++)
4326 if(arg1->serverFlags[i] & ITSRWVOL) pos1 = i;
4327 for(i = 0; i < arg2->nServers; i++)
4328 if(arg2->serverFlags[i] & ITSRWVOL) pos2 = i;
4329 if(pos1 == -1 || pos2 == -1){
4333 sprintf(comp1,"%10u",arg1->serverNumber[pos1]);
4334 sprintf(comp2,"%10u",arg2->serverNumber[pos2]);
4335 sprintf(temp1,"%10u",arg1->serverPartition[pos1]);
4336 sprintf(temp2,"%10u",arg2->serverPartition[pos2]);
4337 strcat(comp1,temp1);
4338 strcat(comp2,temp2);
4339 strcat(comp1,arg1->name);
4340 strcat(comp1,arg2->name);
4341 return(strcmp(comp1,comp2));
4348 struct cmd_syndesc *as;
4351 afs_int32 aserver, code;
4353 struct VldbListByAttributes attributes;
4354 nbulkentries arrayEntries;
4355 struct nvldbentry *vllist, *tarray = 0, *ttarray;
4356 afs_int32 centries, nentries = 0, tarraysize, parraysize;
4359 int quiet, sort, lock;
4360 afs_int32 thisindex, nextindex;
4365 attributes.Mask = 0;
4366 lock = (as->parms[3].items ? 1 : 0); /* -lock flag */
4367 quiet = (as->parms[4].items ? 1 : 0); /* -quit flag */
4368 sort = (as->parms[5].items ? 0 : 1); /* -nosort flag */
4370 /* If the volume name is given, Use VolumeInfoCmd to look it up
4371 * and not ListAttributes.
4373 if (as->parms[0].items) {
4376 "vos: illegal use of '-locked' switch, need to specify server and/or partition\n");
4379 code = VolumeInfoCmd(as->parms[0].items->data);
4381 PrintError("", code);
4387 /* Server specified */
4388 if (as->parms[1].items) {
4389 aserver = GetServer(as->parms[1].items->data);
4391 fprintf(STDERR, "vos: server '%s' not found in host table\n",
4392 as->parms[1].items->data);
4395 attributes.server = ntohl(aserver);
4396 attributes.Mask |= VLLIST_SERVER;
4399 /* Partition specified */
4400 if (as->parms[2].items) {
4401 apart = volutil_GetPartitionID(as->parms[2].items->data);
4403 fprintf(STDERR, "vos: could not interpret partition name '%s'\n",
4404 as->parms[2].items->data);
4407 attributes.partition = apart;
4408 attributes.Mask |= VLLIST_PARTITION;
4412 attributes.Mask |= VLLIST_FLAG;
4413 attributes.flag = VLOP_ALLOPERS;
4416 /* Print header information */
4418 MapPartIdIntoName(apart, pname);
4419 fprintf(STDOUT, "VLDB entries for %s %s%s%s %s\n",
4420 (as->parms[1].items ? "server" : "all"),
4421 (as->parms[1].items ? as->parms[1].items->data : "servers"),
4422 (as->parms[2].items ? " partition " : ""),
4423 (as->parms[2].items ? pname : ""),
4424 (lock ? "which are locked:" : ""));
4427 for (thisindex = 0; (thisindex != -1); thisindex = nextindex) {
4428 memset(&arrayEntries, 0, sizeof(arrayEntries));
4433 VLDB_ListAttributesN2(&attributes, 0, thisindex, ¢ries,
4434 &arrayEntries, &nextindex);
4435 if (vcode == RXGEN_OPCODE) {
4436 /* Vlserver not running with ListAttributesN2. Fall back */
4438 VLDB_ListAttributes(&attributes, ¢ries, &arrayEntries);
4442 fprintf(STDERR, "Could not access the VLDB for attributes\n");
4443 PrintError("", vcode);
4446 nentries += centries;
4448 /* We don't sort, so just print the entries now */
4450 for (j = 0; j < centries; j++) { /* process each entry */
4451 vllist = &arrayEntries.nbulkentries_val[j];
4452 MapHostToNetwork(vllist);
4453 EnumerateEntry(vllist);
4455 if (vllist->flags & VLOP_ALLOPERS)
4456 fprintf(STDOUT, " Volume is currently LOCKED \n");
4460 /* So we sort. First we must collect all the entries and keep
4463 else if (centries > 0) {
4465 /* steal away the first bulk entries array */
4466 tarray = (struct nvldbentry *)arrayEntries.nbulkentries_val;
4467 tarraysize = centries * sizeof(struct nvldbentry);
4468 arrayEntries.nbulkentries_val = 0;
4470 /* Grow the tarray to keep the extra entries */
4471 parraysize = (centries * sizeof(struct nvldbentry));
4473 (struct nvldbentry *)realloc(tarray,
4474 tarraysize + parraysize);
4477 "Could not allocate enough space for the VLDB entries\n");
4483 memcpy(((char *)tarray) + tarraysize,
4484 (char *)arrayEntries.nbulkentries_val, parraysize);
4485 tarraysize += parraysize;
4489 /* Free the bulk array */
4490 if (arrayEntries.nbulkentries_val) {
4491 free(arrayEntries.nbulkentries_val);
4492 arrayEntries.nbulkentries_val = 0;
4496 /* Here is where we now sort all the entries and print them */
4497 if (sort && (nentries > 0)) {
4498 qsort((char *)tarray, nentries, sizeof(struct nvldbentry),
4499 CompareVldbEntryByName);
4500 for (vllist = tarray, j = 0; j < nentries; j++, vllist++) {
4501 MapHostToNetwork(vllist);
4502 EnumerateEntry(vllist);
4504 if (vllist->flags & VLOP_ALLOPERS)
4505 fprintf(STDOUT, " Volume is currently LOCKED \n");
4511 fprintf(STDOUT, "\nTotal entries: %lu\n", (unsigned long)nentries);
4519 register struct cmd_syndesc *as;
4521 afs_int32 apart = 0, avolid;
4522 afs_int32 aserver = 0, code, aserver1, apart1;
4524 struct VldbListByAttributes attributes;
4525 nbulkentries arrayEntries;
4526 register struct nvldbentry *vllist;
4530 int seenprefix, seenxprefix, exclude, ex, exp, noaction;
4531 afs_int32 totalBack = 0;
4532 afs_int32 totalFail = 0;
4533 int previdx = -1, error, same;
4535 struct cmd_item *ti;
4539 memset(&attributes, 0, sizeof(struct VldbListByAttributes));
4540 attributes.Mask = 0;
4542 seenprefix = (as->parms[0].items ? 1 : 0);
4543 exclude = (as->parms[3].items ? 1 : 0);
4544 seenxprefix = (as->parms[4].items ? 1 : 0);
4545 noaction = (as->parms[5].items ? 1 : 0);
4547 if (as->parms[1].items) { /* -server */
4548 aserver = GetServer(as->parms[1].items->data);
4550 fprintf(STDERR, "vos: server '%s' not found in host table\n",
4551 as->parms[1].items->data);
4554 attributes.server = ntohl(aserver);
4555 attributes.Mask |= VLLIST_SERVER;
4558 if (as->parms[2].items) { /* -partition */
4559 apart = volutil_GetPartitionID(as->parms[2].items->data);
4561 fprintf(STDERR, "vos: could not interpret partition name '%s'\n",
4562 as->parms[2].items->data);
4565 attributes.partition = apart;
4566 attributes.Mask |= VLLIST_PARTITION;
4569 /* Check to make sure the prefix and xprefix expressions compile ok */
4571 for (ti = as->parms[0].items; ti; ti = ti->next) {
4572 if (strncmp(ti->data, "^", 1) == 0) {
4573 #ifdef HAVE_POSIX_REGEX
4577 code = regcomp(&re, ti->data, REG_NOSUB);
4579 regerror(code, &re, errbuf, sizeof errbuf);
4581 "Unrecognizable -prefix regular expression: '%s': %s\n",
4587 ccode = (char *)re_comp(ti->data);
4590 "Unrecognizable -prefix regular expression: '%s': %s\n",
4599 for (ti = as->parms[4].items; ti; ti = ti->next) {
4600 if (strncmp(ti->data, "^", 1) == 0) {
4601 #ifdef HAVE_POSIX_REGEX
4605 code = regcomp(&re, ti->data, REG_NOSUB);
4607 regerror(code, &re, errbuf, sizeof errbuf);
4609 "Unrecognizable -xprefix regular expression: '%s': %s\n",
4615 ccode = (char *)re_comp(ti->data);
4618 "Unrecognizable -xprefix regular expression: '%s': %s\n",
4627 memset(&arrayEntries, 0, sizeof(arrayEntries)); /* initialize to hint the stub to alloc space */
4628 vcode = VLDB_ListAttributes(&attributes, &nentries, &arrayEntries);
4630 fprintf(STDERR, "Could not access the VLDB for attributes\n");
4631 PrintError("", vcode);
4635 if (as->parms[1].items || as->parms[2].items || verbose) {
4636 fprintf(STDOUT, "%s up volumes",
4637 (noaction ? "Would have backed" : "Backing"));
4639 if (as->parms[1].items) {
4640 fprintf(STDOUT, " on server %s", as->parms[1].items->data);
4641 } else if (as->parms[2].items) {
4642 fprintf(STDOUT, " for all servers");
4645 if (as->parms[2].items) {
4646 MapPartIdIntoName(apart, pname);
4647 fprintf(STDOUT, " partition %s", pname);
4650 if (seenprefix || (!seenprefix && seenxprefix)) {
4651 ti = (seenprefix ? as->parms[0].items : as->parms[4].items);
4652 ex = (seenprefix ? exclude : !exclude);
4653 exp = (strncmp(ti->data, "^", 1) == 0);
4654 fprintf(STDOUT, " which %smatch %s '%s'", (ex ? "do not " : ""),
4655 (exp ? "expression" : "prefix"), ti->data);
4656 for (ti = ti->next; ti; ti = ti->next) {
4657 exp = (strncmp(ti->data, "^", 1) == 0);
4658 printf(" %sor %s '%s'", (ex ? "n" : ""),
4659 (exp ? "expression" : "prefix"), ti->data);
4663 if (seenprefix && seenxprefix) {
4664 ti = as->parms[4].items;
4665 exp = (strncmp(ti->data, "^", 1) == 0);
4666 fprintf(STDOUT, " %swhich match %s '%s'",
4667 (exclude ? "adding those " : "removing those "),
4668 (exp ? "expression" : "prefix"), ti->data);
4669 for (ti = ti->next; ti; ti = ti->next) {
4670 exp = (strncmp(ti->data, "^", 1) == 0);
4671 printf(" or %s '%s'", (exp ? "expression" : "prefix"),
4675 fprintf(STDOUT, " .. ");
4677 fprintf(STDOUT, "\n");
4681 for (j = 0; j < nentries; j++) { /* process each vldb entry */
4682 vllist = &arrayEntries.nbulkentries_val[j];
4685 for (ti = as->parms[0].items; ti; ti = ti->next) {
4686 if (strncmp(ti->data, "^", 1) == 0) {
4687 #ifdef HAVE_POSIX_REGEX
4691 /* XXX -- should just do the compile once! */
4692 code = regcomp(&re, ti->data, REG_NOSUB);
4694 regerror(code, &re, errbuf, sizeof errbuf);
4696 "Error in -prefix regular expression: '%s': %s\n",
4700 match = (regexec(&re, vllist->name, 0, NULL, 0) == 0);
4703 ccode = (char *)re_comp(ti->data);
4706 "Error in -prefix regular expression: '%s': %s\n",
4710 match = (re_exec(vllist->name) == 1);
4714 (strncmp(vllist->name, ti->data, strlen(ti->data)) ==
4724 /* Without the -exclude flag: If it matches the prefix, then
4725 * check if we want to exclude any from xprefix.
4726 * With the -exclude flag: If it matches the prefix, then
4727 * check if we want to add any from xprefix.
4729 if (match && seenxprefix) {
4730 for (ti = as->parms[4].items; ti; ti = ti->next) {
4731 if (strncmp(ti->data, "^", 1) == 0) {
4732 #ifdef HAVE_POSIX_REGEX
4736 /* XXX -- should just do the compile once! */
4737 code = regcomp(&re, ti->data, REG_NOSUB);
4739 regerror(code, &re, errbuf, sizeof errbuf);
4741 "Error in -xprefix regular expression: '%s': %s\n",
4745 if (regexec(&re, vllist->name, 0, NULL, 0) == 0)
4749 ccode = (char *)re_comp(ti->data);
4752 "Error in -xprefix regular expression: '%s': %s\n",
4756 if (re_exec(vllist->name) == 1) {
4762 if (strncmp(vllist->name, ti->data, strlen(ti->data)) ==
4772 match = !match; /* -exclude will reverse the match */
4774 continue; /* Skip if no match */
4776 /* Print list of volumes to backup */
4778 fprintf(STDOUT, " %s\n", vllist->name);
4782 if (!(vllist->flags & RW_EXISTS)) {
4785 "Omitting to backup %s since RW volume does not exist \n",
4787 fprintf(STDOUT, "\n");
4793 avolid = vllist->volumeId[RWVOL];
4794 MapHostToNetwork(vllist);
4795 GetServerAndPart(vllist, RWVOL, &aserver1, &apart1, &previdx);
4796 if (aserver1 == -1 || apart1 == -1) {
4797 fprintf(STDOUT, "could not backup %s, invalid VLDB entry\n",
4803 same = VLDB_IsSameAddrs(aserver, aserver1, &error);
4806 "Failed to get info about server's %d address(es) from vlserver (err=%d); aborting call!\n",
4812 if ((aserver && !same) || (apart && (apart != apart1))) {
4815 "Omitting to backup %s since the RW is in a different location\n",
4821 time_t now = time(0);
4822 fprintf(STDOUT, "Creating backup volume for %s on %s",
4823 vllist->name, ctime(&now));
4827 code = UV_BackupVolume(aserver1, apart1, avolid);
4829 fprintf(STDOUT, "Could not backup %s\n", vllist->name);
4835 fprintf(STDOUT, "\n");
4837 } /* process each vldb entry */
4838 fprintf(STDOUT, "done\n");
4839 fprintf(STDOUT, "Total volumes backed up: %lu; failed to backup: %lu\n",
4840 (unsigned long)totalBack, (unsigned long)totalFail);
4842 if (arrayEntries.nbulkentries_val)
4843 free(arrayEntries.nbulkentries_val);
4849 register struct cmd_syndesc *as;
4852 afs_int32 aserver, code;
4854 struct VldbListByAttributes attributes;
4855 nbulkentries arrayEntries;
4856 register struct nvldbentry *vllist;
4865 attributes.Mask = 0;
4867 if (as->parms[0].items) { /* server specified */
4868 aserver = GetServer(as->parms[0].items->data);
4870 fprintf(STDERR, "vos: server '%s' not found in host table\n",
4871 as->parms[0].items->data);
4874 attributes.server = ntohl(aserver);
4875 attributes.Mask |= VLLIST_SERVER;
4877 if (as->parms[1].items) { /* partition specified */
4878 apart = volutil_GetPartitionID(as->parms[1].items->data);
4880 fprintf(STDERR, "vos: could not interpret partition name '%s'\n",
4881 as->parms[1].items->data);
4884 if (!IsPartValid(apart, aserver, &code)) { /*check for validity of the partition */
4886 PrintError("", code);
4889 "vos : partition %s does not exist on the server\n",
4890 as->parms[1].items->data);
4893 attributes.partition = apart;
4894 attributes.Mask |= VLLIST_PARTITION;
4896 attributes.flag = VLOP_ALLOPERS;
4897 attributes.Mask |= VLLIST_FLAG;
4898 memset(&arrayEntries, 0, sizeof(arrayEntries)); /*initialize to hint the stub to alloc space */
4899 vcode = VLDB_ListAttributes(&attributes, &nentries, &arrayEntries);
4901 fprintf(STDERR, "Could not access the VLDB for attributes\n");
4902 PrintError("", vcode);
4905 for (j = 0; j < nentries; j++) { /* process each entry */
4906 vllist = &arrayEntries.nbulkentries_val[j];
4907 volid = vllist->volumeId[RWVOL];
4909 ubik_Call(VL_ReleaseLock, cstruct, 0, volid, -1,
4910 LOCKREL_OPCODE | LOCKREL_AFSID | LOCKREL_TIMESTAMP);
4912 fprintf(STDERR, "Could not unlock entry for volume %s\n",
4914 PrintError("", vcode);
4919 MapPartIdIntoName(apart, pname);
4922 "Could not lock %lu VLDB entries of %lu locked entries\n",
4923 (unsigned long)totalE, (unsigned long)nentries);
4925 if (as->parms[0].items) {
4927 "Unlocked all the VLDB entries for volumes on server %s ",
4928 as->parms[0].items->data);
4929 if (as->parms[1].items) {
4930 MapPartIdIntoName(apart, pname);
4931 fprintf(STDOUT, "partition %s\n", pname);
4933 fprintf(STDOUT, "\n");
4935 } else if (as->parms[1].items) {
4936 MapPartIdIntoName(apart, pname);
4938 "Unlocked all the VLDB entries for volumes on partition %s on all servers\n",
4943 if (arrayEntries.nbulkentries_val)
4944 free(arrayEntries.nbulkentries_val);
4949 PrintInt64Size(afs_uint64 in)
4951 register afs_uint32 hi, lo;
4952 register char * units;
4953 static char output[16];
4955 SplitInt64(in,hi,lo);
4959 } else if (!(hi & 0xFFFFFC00)) {
4961 lo = (hi << 22) | (lo >> 10);
4962 } else if (!(hi & 0xFFF00000)) {
4964 lo = (hi << 12) | (lo >> 20);
4965 } else if (!(hi & 0xC0000000)) {
4967 lo = (hi << 2) | (lo >> 30);
4972 sprintf(output,"%u %s", lo, units);
4978 register struct cmd_syndesc *as;
4981 afs_int32 aserver, code;
4983 struct diskPartition partition;
4984 struct partList dummyPartList;
4986 int printSummary=0, sumPartitions=0;
4987 afs_uint64 sumFree, sumStorage, tmp;
4990 ZeroInt64(sumStorage);
4992 aserver = GetServer(as->parms[0].items->data);
4994 fprintf(STDERR, "vos: server '%s' not found in host table\n",
4995 as->parms[0].items->data);
4998 if (as->parms[1].items) {
4999 apart = volutil_GetPartitionID(as->parms[1].items->data);
5001 fprintf(STDERR, "vos: could not interpret partition name '%s'\n",
5002 as->parms[1].items->data);
5005 dummyPartList.partId[0] = apart;
5006 dummyPartList.partFlags[0] = PARTVALID;
5009 if (as->parms[2].items) {
5013 if (!IsPartValid(apart, aserver, &code)) { /*check for validity of the partition */
5015 PrintError("", code);
5018 "vos : partition %s does not exist on the server\n",
5019 as->parms[1].items->data);
5023 code = UV_ListPartitions(aserver, &dummyPartList, &cnt);
5025 PrintDiagnostics("listpart", code);
5029 for (i = 0; i < cnt; i++) {
5030 if (dummyPartList.partFlags[i] & PARTVALID) {
5031 MapPartIdIntoName(dummyPartList.partId[i], pname);
5032 code = UV_PartitionInfo(aserver, pname, &partition);
5034 fprintf(STDERR, "Could not get information on partition %s\n",
5036 PrintError("", code);
5040 "Free space on partition %s: %d K blocks out of total %d\n",
5041 pname, partition.free, partition.minFree);
5043 FillInt64(tmp,0,partition.free);
5044 AddUInt64(sumFree,tmp,&sumFree);
5045 FillInt64(tmp,0,partition.minFree);
5046 AddUInt64(sumStorage,tmp,&sumStorage);
5051 "Summary: %s free out of ",
5052 PrintInt64Size(sumFree));
5054 "%s on %d partitions\n",
5055 PrintInt64Size(sumStorage),
5063 register struct cmd_syndesc *as;
5066 afs_int32 ip1, ip2, vcode;
5069 ip1 = GetServer(as->parms[0].items->data);
5071 fprintf(STDERR, "vos: invalid host address\n");
5075 if ((as->parms[1].items && as->parms[2].items)
5076 || (!as->parms[1].items && !as->parms[2].items)) {
5078 "vos: Must specify either '-newaddr <addr>' or '-remove' flag\n");
5082 if (as->parms[1].items) {
5083 ip2 = GetServer(as->parms[1].items->data);
5085 fprintf(STDERR, "vos: invalid host address\n");
5089 /* Play a trick here. If we are removing an address, ip1 will be -1
5090 * and ip2 will be the original address. This switch prevents an
5091 * older revision vlserver from removing the IP address.
5098 vcode = ubik_Call_New(VL_ChangeAddr, cstruct, 0, ntohl(ip1), ntohl(ip2));
5101 fprintf(STDERR, "Could not remove server %s from the VLDB\n",
5102 as->parms[0].items->data);
5103 if (vcode == VL_NOENT) {
5105 "vlserver does not support the remove flag or ");
5108 fprintf(STDERR, "Could not change server %s to server %s\n",
5109 as->parms[0].items->data, as->parms[1].items->data);
5111 PrintError("", vcode);
5116 fprintf(STDOUT, "Removed server %s from the VLDB\n",
5117 as->parms[0].items->data);
5119 fprintf(STDOUT, "Changed server %s to server %s\n",
5120 as->parms[0].items->data, as->parms[1].items->data);
5126 print_addrs(const bulkaddrs * addrs, const afsUUID * m_uuid, int nentries,
5127 int print, int noresolve)
5131 struct VLCallBack vlcb;
5134 ListAddrByAttributes m_attrs;
5135 afs_int32 m_nentries, *m_addrp;
5136 afs_int32 base, index;
5140 afsUUID_to_string(m_uuid, buf, sizeof(buf));
5141 printf("UUID: %s\n", buf);
5144 /* print out the list of all the server */
5145 addrp = (afs_int32 *) addrs->bulkaddrs_val;
5146 for (i = 0; i < nentries; i++, addrp++) {
5147 /* If it is a multihomed address, then we will need to
5148 * get the addresses for this multihomed server from
5149 * the vlserver and print them.
5151 if (((*addrp & 0xff000000) == 0xff000000) && ((*addrp) & 0xffff)) {
5152 /* Get the list of multihomed fileservers */
5153 base = (*addrp >> 16) & 0xff;
5154 index = (*addrp) & 0xffff;
5156 if ((base >= 0) && (base <= VL_MAX_ADDREXTBLKS) && (index >= 1)
5157 && (index <= VL_MHSRV_PERBLK)) {
5158 m_attrs.Mask = VLADDR_INDEX;
5159 m_attrs.index = (base * VL_MHSRV_PERBLK) + index;
5161 m_addrs.bulkaddrs_val = 0;
5162 m_addrs.bulkaddrs_len = 0;
5164 ubik_Call(VL_GetAddrsU, cstruct, 0, &m_attrs, &m_uuid,
5165 &vlcb, &m_nentries, &m_addrs);
5168 "vos: could not list the multi-homed server addresses\n");
5169 PrintError("", vcode);
5172 /* Print the list */
5173 m_addrp = (afs_int32 *) m_addrs.bulkaddrs_val;
5174 for (j = 0; j < m_nentries; j++, m_addrp++) {
5175 *m_addrp = htonl(*m_addrp);
5178 printf("%s ", afs_inet_ntoa_r(*m_addrp, hoststr));
5180 printf("%s ", hostutil_GetNameByINet(*m_addrp));
5184 printf("<unknown>\n");
5193 /* Otherwise, it is a non-multihomed entry and contains
5194 * the IP address of the server - print it.
5196 *addrp = htonl(*addrp);
5199 printf("%s\n", afs_inet_ntoa_r(*addrp, hoststr));
5201 printf("%s\n", hostutil_GetNameByINet(*addrp));
5213 register struct cmd_syndesc *as;
5216 afs_int32 i, noresolve = 0, printuuid = 0;
5217 struct VLCallBack vlcb;
5220 ListAddrByAttributes m_attrs;
5221 afsUUID m_uuid, askuuid;
5222 afs_int32 m_nentries;
5224 memset(&m_attrs, 0, sizeof(struct ListAddrByAttributes));
5225 m_attrs.Mask = VLADDR_INDEX;
5227 memset(&m_addrs, 0, sizeof(bulkaddrs));
5228 memset(&askuuid, 0, sizeof(afsUUID));
5229 if (as->parms[0].items) {
5231 if (afsUUID_from_string(as->parms[0].items->data, &askuuid) < 0) {
5232 fprintf(STDERR, "vos: invalid UUID '%s'\n",
5233 as->parms[0].items->data);
5236 m_attrs.Mask = VLADDR_UUID;
5237 m_attrs.uuid = askuuid;
5239 if (as->parms[1].items) {
5243 he = hostutil_GetHostByName((char *)as->parms[1].items->data);
5245 fprintf(STDERR, "vos: Can't get host info for '%s'\n",
5246 as->parms[1].items->data);
5249 memcpy(&saddr, he->h_addr, 4);
5250 m_attrs.Mask = VLADDR_IPADDR;
5251 m_attrs.ipaddr = ntohl(saddr);
5253 if (as->parms[2].items) {
5256 if (as->parms[3].items) {
5260 m_addrs.bulkaddrs_val = 0;
5261 m_addrs.bulkaddrs_len = 0;
5264 ubik_Call_New(VL_GetAddrs, cstruct, 0, 0, 0, &vlcb, &nentries,
5267 fprintf(STDERR, "vos: could not list the server addresses\n");
5268 PrintError("", vcode);
5273 m_addrs.bulkaddrs_val = 0;
5274 m_addrs.bulkaddrs_len = 0;
5280 ubik_Call_New(VL_GetAddrsU, cstruct, 0, &m_attrs, &m_uuid,
5281 &vlcb, &m_nentries, &m_addrs);
5283 if (vcode == VL_NOENT) {
5284 if (m_attrs.Mask == VLADDR_UUID) {
5285 fprintf(STDERR, "vos: no entry for UUID '%s' found in VLDB\n",
5286 as->parms[0].items->data);
5288 } else if (m_attrs.Mask == VLADDR_IPADDR) {
5289 fprintf(STDERR, "vos: no entry for host '%s' [0x%08x] found in VLDB\n",
5290 as->parms[1].items->data, m_attrs.ipaddr);
5299 if (vcode == VL_INDEXERANGE) {
5304 fprintf(STDERR, "vos: could not list the server addresses\n");
5305 PrintError("", vcode);
5309 print_addrs(&m_addrs, &m_uuid, m_nentries, printuuid, noresolve);
5312 if ((as->parms[1].items) || (as->parms[0].items) || (i > nentries))
5321 register struct cmd_syndesc *as;
5324 afs_int32 avolid, vcode, err;
5326 avolid = vsu_GetVolumeID(as->parms[0].items->data, cstruct, &err);
5329 PrintError("", err);
5331 fprintf(STDERR, "vos: can't find volume '%s'\n",
5332 as->parms[0].items->data);
5335 vcode = ubik_Call(VL_SetLock, cstruct, 0, avolid, -1, VLOP_DELETE);
5337 fprintf(STDERR, "Could not lock VLDB entry for volume %s\n",
5338 as->parms[0].items->data);
5339 PrintError("", vcode);
5342 fprintf(STDOUT, "Locked VLDB entry for volume %s\n",
5343 as->parms[0].items->data);
5349 register struct cmd_syndesc *as;
5352 afs_int32 partition = -1;
5353 afs_int32 server, volid, code, i, same;
5354 struct nvldbentry entry, storeEntry;
5357 afs_int32 rwserver = 0;
5358 afs_int32 rwpartition;
5360 afs_int32 roserver = 0;
5361 afs_int32 ropartition;
5363 struct rx_connection *aconn;
5366 server = GetServer(as->parms[0].items->data);
5368 fprintf(STDERR, "vos: host '%s' not found in host table\n",
5369 as->parms[0].items->data);
5372 partition = volutil_GetPartitionID(as->parms[1].items->data);
5373 if (partition < 0) {
5374 fprintf(STDERR, "vos: could not interpret partition name '%s'\n",
5375 as->parms[1].items->data);
5378 if (!IsPartValid(partition, server, &code)) {
5380 PrintError("", code);
5383 "vos : partition %s does not exist on the server\n",
5384 as->parms[1].items->data);
5387 volid = vsu_GetVolumeID(as->parms[2].items->data, cstruct, &code);
5390 PrintError("", code);
5392 fprintf(STDERR, "Unknown volume ID or name '%s'\n",
5393 as->parms[0].items->data);
5396 if (as->parms[3].items)
5399 vcode = VLDB_GetEntryByID(volid, -1, &entry);
5402 "Could not fetch the entry for volume %lu from VLDB\n",
5403 (unsigned long)volid);
5404 PrintError("convertROtoRW", code);
5408 /* use RO volid even if user specified RW or BK volid */
5410 if (volid != entry.volumeId[ROVOL])
5411 volid = entry.volumeId[ROVOL];
5413 MapHostToNetwork(&entry);
5414 for (i = 0; i < entry.nServers; i++) {
5415 if (entry.serverFlags[i] & ITSRWVOL) {
5417 rwserver = entry.serverNumber[i];
5418 rwpartition = entry.serverPartition[i];
5420 if (entry.serverFlags[i] & ITSROVOL) {
5421 same = VLDB_IsSameAddrs(server, entry.serverNumber[i], &code);
5424 "Failed to get info about server's %d address(es) from vlserver (err=%d); aborting call!\n",
5430 roserver = entry.serverNumber[i];
5431 ropartition = entry.serverPartition[i];
5437 fprintf(STDERR, "Warning: RO volume didn't exist in vldb!\n");
5439 if (ropartition != partition) {
5441 "Warning: RO volume should be in partition %d instead of %d (vldb)\n",
5442 ropartition, partition);
5447 "VLDB indicates that a RW volume exists already on %s in partition %s.\n",
5448 hostutil_GetNameByINet(rwserver),
5449 volutil_PartitionName(rwpartition));
5451 fprintf(STDERR, "Overwrite this VLDB entry? [y|n] (n)\n");
5453 while (!(dc == EOF || dc == '\n'))
5454 dc = getchar(); /* goto end of line */
5455 if ((c != 'y') && (c != 'Y')) {
5456 fprintf(STDERR, "aborted.\n");
5463 ubik_Call(VL_SetLock, cstruct, 0, entry.volumeId[RWVOL], RWVOL,
5465 aconn = UV_Bind(server, AFSCONF_VOLUMEPORT);
5466 code = AFSVolConvertROtoRWvolume(aconn, partition, volid);
5469 "Converting RO volume %lu to RW volume failed with code %d\n",
5470 (unsigned long)volid, code);
5471 PrintError("convertROtoRW ", code);
5474 entry.serverFlags[roindex] = ITSRWVOL;
5475 entry.flags |= RW_EXISTS;
5476 entry.flags &= ~BACK_EXISTS;
5479 if (rwindex != entry.nServers) {
5480 entry.serverNumber[rwindex] = entry.serverNumber[entry.nServers];
5481 entry.serverPartition[rwindex] =
5482 entry.serverPartition[entry.nServers];
5483 entry.serverFlags[rwindex] = entry.serverFlags[entry.nServers];
5484 entry.serverNumber[entry.nServers] = 0;
5485 entry.serverPartition[entry.nServers] = 0;
5486 entry.serverFlags[entry.nServers] = 0;
5489 entry.flags &= ~RO_EXISTS;
5490 for (i = 0; i < entry.nServers; i++) {
5491 if (entry.serverFlags[i] & ITSROVOL) {
5492 if (!(entry.serverFlags[i] & (RO_DONTUSE | NEW_REPSITE)))
5493 entry.flags |= RO_EXISTS;
5496 MapNetworkToHost(&entry, &storeEntry);
5498 VLDB_ReplaceEntry(entry.volumeId[RWVOL], RWVOL, &storeEntry,
5499 (LOCKREL_OPCODE | LOCKREL_AFSID |
5500 LOCKREL_TIMESTAMP));
5503 "Warning: volume converted, but vldb update failed with code %d!\n",
5506 vcode = UV_LockRelease(entry.volumeId[RWVOL]);
5508 PrintDiagnostics("unlock", vcode);
5515 register struct cmd_syndesc *as;
5517 afs_int32 avolid, aserver, apart, voltype, fromdate = 0, code, err, i;
5518 struct nvldbentry entry;
5519 volintSize vol_size;
5521 rx_SetRxDeadTime(60 * 10);
5522 for (i = 0; i < MAXSERVERS; i++) {
5523 struct rx_connection *rxConn = ubik_GetRPCConn(cstruct, i);
5526 rx_SetConnDeadTime(rxConn, rx_connDeadTime);
5527 if (rxConn->service)
5528 rxConn->service->connDeadTime = rx_connDeadTime;
5531 avolid = vsu_GetVolumeID(as->parms[0].items->data, cstruct, &err);
5534 PrintError("", err);
5536 fprintf(STDERR, "vos: can't find volume '%s'\n",
5537 as->parms[0].items->data);
5541 if (as->parms[1].items || as->parms[2].items) {
5542 if (!as->parms[1].items || !as->parms[2].items) {
5544 "Must specify both -server and -partition options\n");
5547 aserver = GetServer(as->parms[2].items->data);
5549 fprintf(STDERR, "Invalid server name\n");
5552 apart = volutil_GetPartitionID(as->parms[1].items->data);
5554 fprintf(STDERR, "Invalid partition name\n");
5558 code = GetVolumeInfo(avolid, &aserver, &apart, &voltype, &entry);
5565 if (as->parms[4].items && strcmp(as->parms[4].items->data, "0")) {
5566 code = ktime_DateToInt32(as->parms[4].items->data, &fromdate);
5568 fprintf(STDERR, "vos: failed to parse date '%s' (error=%d))\n",
5569 as->parms[1].items->data, code);
5574 fprintf(STDOUT, "Volume: %s\n", as->parms[0].items->data);
5576 if (as->parms[3].items) { /* do the dump estimate */
5577 #ifdef AFS_64BIT_ENV
5578 vol_size.dump_size = 0;
5580 FillInt64(vol_size.dump_size,0, 1);
5582 code = UV_GetSize(avolid, aserver, apart, fromdate, &vol_size);
5584 PrintDiagnostics("size", code);
5587 /* presumably the size info is now gathered in pntr */
5588 /* now we display it */
5590 fprintf(STDOUT, "dump_size: %llu\n", vol_size.dump_size);
5598 PrintDiagnostics(astring, acode)
5602 if (acode == EACCES) {
5604 "You are not authorized to perform the 'vos %s' command (%d)\n",
5607 fprintf(STDERR, "Error in vos %s command.\n", astring);
5608 PrintError("", acode);
5615 MyBeforeProc(as, arock)
5616 struct cmd_syndesc *as;
5619 register char *tcell;
5620 register afs_int32 code;
5621 register afs_int32 sauth;
5623 /* Initialize the ubik_client connection */
5624 rx_SetRxDeadTime(90);
5625 cstruct = (struct ubik_client *)0;
5629 if (as->parms[12].items) /* if -cell specified */
5630 tcell = as->parms[12].items->data;
5631 if (as->parms[14].items) /* -serverauth specified */
5633 if (as->parms[16].items) /* -crypt specified */
5636 vsu_ClientInit((as->parms[13].items != 0), confdir, tcell, sauth,
5637 &cstruct, UV_SetSecurity))) {
5638 fprintf(STDERR, "could not initialize VLDB library (code=%lu) \n",
5639 (unsigned long)code);
5643 if (as->parms[15].items) /* -verbose flag set */
5653 /* this sucks but it works for now.
5658 #include "AFS_component_version_number.c"
5664 register afs_int32 code;
5666 register struct cmd_syndesc *ts;
5668 #ifdef AFS_AIX32_ENV
5670 * The following signal action for AIX is necessary so that in case of a
5671 * crash (i.e. core is generated) we can include the user's data section
5672 * in the core dump. Unfortunately, by default, only a partial core is
5673 * generated which, in many cases, isn't too useful.
5675 struct sigaction nsa;
5677 sigemptyset(&nsa.sa_mask);
5678 nsa.sa_handler = SIG_DFL;
5679 nsa.sa_flags = SA_FULLDUMP;
5680 sigaction(SIGSEGV, &nsa, NULL);
5683 confdir = AFSDIR_CLIENT_ETC_DIRPATH;
5685 cmd_SetBeforeProc(MyBeforeProc, NULL);
5687 ts = cmd_CreateSyntax("create", CreateVolume, 0, "create a new volume");
5688 cmd_AddParm(ts, "-server", CMD_SINGLE, 0, "machine name");
5689 cmd_AddParm(ts, "-partition", CMD_SINGLE, 0, "partition name");
5690 cmd_AddParm(ts, "-name", CMD_SINGLE, 0, "volume name");
5691 cmd_AddParm(ts, "-maxquota", CMD_SINGLE, CMD_OPTIONAL,
5692 "initial quota (KB)");
5694 cmd_AddParm(ts, "-minquota", CMD_SINGLE, CMD_OPTIONAL, "");
5698 ts = cmd_CreateSyntax("remove", DeleteVolume, 0, "delete a volume");
5699 cmd_AddParm(ts, "-server", CMD_SINGLE, CMD_OPTIONAL, "machine name");
5700 cmd_AddParm(ts, "-partition", CMD_SINGLE, CMD_OPTIONAL, "partition name");
5701 cmd_AddParm(ts, "-id", CMD_SINGLE, 0, "volume name or ID");
5705 ts = cmd_CreateSyntax("move", MoveVolume, 0, "move a volume");
5706 cmd_AddParm(ts, "-id", CMD_SINGLE, 0, "volume name or ID");
5707 cmd_AddParm(ts, "-fromserver", CMD_SINGLE, 0, "machine name on source");
5708 cmd_AddParm(ts, "-frompartition", CMD_SINGLE, 0,
5709 "partition name on source");
5710 cmd_AddParm(ts, "-toserver", CMD_SINGLE, 0,
5711 "machine name on destination");
5712 cmd_AddParm(ts, "-topartition", CMD_SINGLE, 0,
5713 "partition name on destination");
5714 cmd_AddParm(ts, "-live", CMD_FLAG, CMD_OPTIONAL,
5715 "copy live volume without cloning");
5718 ts = cmd_CreateSyntax("copy", CopyVolume, 0, "copy a volume");
5719 cmd_AddParm(ts, "-id", CMD_SINGLE, 0, "volume name or ID on source");
5720 cmd_AddParm(ts, "-fromserver", CMD_SINGLE, 0, "machine name on source");
5721 cmd_AddParm(ts, "-frompartition", CMD_SINGLE, 0,
5722 "partition name on source");
5723 cmd_AddParm(ts, "-toname", CMD_SINGLE, 0, "volume name on destination");
5724 cmd_AddParm(ts, "-toserver", CMD_SINGLE, 0,
5725 "machine name on destination");
5726 cmd_AddParm(ts, "-topartition", CMD_SINGLE, 0,
5727 "partition name on destination");
5728 cmd_AddParm(ts, "-offline", CMD_FLAG, CMD_OPTIONAL,
5729 "leave new volume offline");
5730 cmd_AddParm(ts, "-readonly", CMD_FLAG, CMD_OPTIONAL,
5731 "make new volume read-only");
5732 cmd_AddParm(ts, "-live", CMD_FLAG, CMD_OPTIONAL,
5733 "copy live volume without cloning");
5736 ts = cmd_CreateSyntax("shadow", ShadowVolume, 0,
5737 "make or update a shadow volume");
5738 cmd_AddParm(ts, "-id", CMD_SINGLE, 0, "volume name or ID on source");
5739 cmd_AddParm(ts, "-fromserver", CMD_SINGLE, 0, "machine name on source");
5740 cmd_AddParm(ts, "-frompartition", CMD_SINGLE, 0,
5741 "partition name on source");
5742 cmd_AddParm(ts, "-toserver", CMD_SINGLE, 0,
5743 "machine name on destination");
5744 cmd_AddParm(ts, "-topartition", CMD_SINGLE, 0,
5745 "partition name on destination");
5746 cmd_AddParm(ts, "-toname", CMD_SINGLE, CMD_OPTIONAL,
5747 "volume name on destination");
5748 cmd_AddParm(ts, "-toid", CMD_SINGLE, CMD_OPTIONAL,
5749 "volume ID on destination");
5750 cmd_AddParm(ts, "-offline", CMD_FLAG, CMD_OPTIONAL,
5751 "leave shadow volume offline");
5752 cmd_AddParm(ts, "-readonly", CMD_FLAG, CMD_OPTIONAL,
5753 "make shadow volume read-only");
5754 cmd_AddParm(ts, "-live", CMD_FLAG, CMD_OPTIONAL,
5755 "copy live volume without cloning");
5756 cmd_AddParm(ts, "-incremental", CMD_FLAG, CMD_OPTIONAL,
5757 "do incremental update if target exists");
5760 ts = cmd_CreateSyntax("backup", BackupVolume, 0,
5761 "make backup of a volume");
5762 cmd_AddParm(ts, "-id", CMD_SINGLE, 0, "volume name or ID");
5765 ts = cmd_CreateSyntax("clone", CloneVolume, 0,
5766 "make clone of a volume");
5767 cmd_AddParm(ts, "-id", CMD_SINGLE, 0, "volume name or ID");
5768 cmd_AddParm(ts, "-server", CMD_SINGLE, CMD_OPTIONAL, "server");
5769 cmd_AddParm(ts, "-partition", CMD_SINGLE, CMD_OPTIONAL, "partition");
5770 cmd_AddParm(ts, "-toname", CMD_SINGLE, CMD_OPTIONAL,
5771 "volume name on destination");
5772 cmd_AddParm(ts, "-toid", CMD_SINGLE, CMD_OPTIONAL,
5773 "volume ID on destination");
5774 cmd_AddParm(ts, "-offline", CMD_FLAG, CMD_OPTIONAL,
5775 "leave clone volume offline");
5776 cmd_AddParm(ts, "-readonly", CMD_FLAG, CMD_OPTIONAL,
5777 "make clone volume read-only, not readwrite");
5780 ts = cmd_CreateSyntax("release", ReleaseVolume, 0, "release a volume");
5781 cmd_AddParm(ts, "-id", CMD_SINGLE, 0, "volume name or ID");
5782 cmd_AddParm(ts, "-force", CMD_FLAG, CMD_OPTIONAL,
5783 "force a complete release");
5786 ts = cmd_CreateSyntax("dump", DumpVolume, 0, "dump a volume");
5787 cmd_AddParm(ts, "-id", CMD_SINGLE, 0, "volume name or ID");
5788 cmd_AddParm(ts, "-time", CMD_SINGLE, CMD_OPTIONAL, "dump from time");
5789 cmd_AddParm(ts, "-file", CMD_SINGLE, CMD_OPTIONAL, "dump file");
5790 cmd_AddParm(ts, "-server", CMD_SINGLE, CMD_OPTIONAL, "server");
5791 cmd_AddParm(ts, "-partition", CMD_SINGLE, CMD_OPTIONAL, "partition");
5792 cmd_AddParm(ts, "-clone", CMD_FLAG, CMD_OPTIONAL,
5793 "dump a clone of the volume");
5796 ts = cmd_CreateSyntax("restore", RestoreVolume, 0, "restore a volume");
5797 cmd_AddParm(ts, "-server", CMD_SINGLE, 0, "machine name");
5798 cmd_AddParm(ts, "-partition", CMD_SINGLE, 0, "partition name");
5799 cmd_AddParm(ts, "-name", CMD_SINGLE, 0, "name of volume to be restored");
5800 cmd_AddParm(ts, "-file", CMD_SINGLE, CMD_OPTIONAL, "dump file");
5801 cmd_AddParm(ts, "-id", CMD_SINGLE, CMD_OPTIONAL, "volume ID");
5802 cmd_AddParm(ts, "-overwrite", CMD_SINGLE, CMD_OPTIONAL,
5803 "abort | full | incremental");
5804 cmd_AddParm(ts, "-offline", CMD_FLAG, CMD_OPTIONAL,
5805 "leave restored volume offline");
5806 cmd_AddParm(ts, "-readonly", CMD_FLAG, CMD_OPTIONAL,
5807 "make restored volume read-only");
5808 cmd_AddParm(ts, "-creation", CMD_SINGLE, CMD_OPTIONAL,
5809 "dump | keep | new");
5810 cmd_AddParm(ts, "-lastupdate", CMD_SINGLE, CMD_OPTIONAL,
5811 "dump | keep | new");
5814 ts = cmd_CreateSyntax("unlock", LockReleaseCmd, 0,
5815 "release lock on VLDB entry for a volume");
5816 cmd_AddParm(ts, "-id", CMD_SINGLE, 0, "volume name or ID");
5819 ts = cmd_CreateSyntax("changeloc", ChangeLocation, 0,
5820 "change an RW volume's location in the VLDB");
5821 cmd_AddParm(ts, "-server", CMD_SINGLE, 0,
5822 "machine name for new location");
5823 cmd_AddParm(ts, "-partition", CMD_SINGLE, 0,
5824 "partition name for new location");
5825 cmd_AddParm(ts, "-id", CMD_SINGLE, 0, "volume name or ID");
5828 ts = cmd_CreateSyntax("addsite", AddSite, 0, "add a replication site");
5829 cmd_AddParm(ts, "-server", CMD_SINGLE, 0, "machine name for new site");
5830 cmd_AddParm(ts, "-partition", CMD_SINGLE, 0,
5831 "partition name for new site");
5832 cmd_AddParm(ts, "-id", CMD_SINGLE, 0, "volume name or ID");
5835 ts = cmd_CreateSyntax("remsite", RemoveSite, 0,
5836 "remove a replication site");
5837 cmd_AddParm(ts, "-server", CMD_SINGLE, 0, "machine name");
5838 cmd_AddParm(ts, "-partition", CMD_SINGLE, 0, "partition name");
5839 cmd_AddParm(ts, "-id", CMD_SINGLE, 0, "volume name or ID");
5842 ts = cmd_CreateSyntax("listpart", ListPartitions, 0, "list partitions");
5843 cmd_AddParm(ts, "-server", CMD_SINGLE, 0, "machine name");
5846 ts = cmd_CreateSyntax("listvol", ListVolumes, 0,
5847 "list volumes on server (bypass VLDB)");
5848 cmd_AddParm(ts, "-server", CMD_SINGLE, 0, "machine name");
5849 cmd_AddParm(ts, "-partition", CMD_SINGLE, CMD_OPTIONAL, "partition name");
5850 cmd_AddParm(ts, "-fast", CMD_FLAG, CMD_OPTIONAL, "minimal listing");
5851 cmd_AddParm(ts, "-long", CMD_FLAG, CMD_OPTIONAL,
5852 "list all normal volume fields");
5853 cmd_AddParm(ts, "-quiet", CMD_FLAG, CMD_OPTIONAL,
5854 "generate minimal information");
5855 cmd_AddParm(ts, "-extended", CMD_FLAG, CMD_OPTIONAL,
5856 "list extended volume fields");
5857 #ifdef FULL_LISTVOL_SWITCH
5858 cmd_AddParm(ts, "-format", CMD_FLAG, CMD_OPTIONAL,
5859 "machine readable format");
5860 #endif /* FULL_LISTVOL_SWITCH */
5863 ts = cmd_CreateSyntax("syncvldb", SyncVldb, 0,
5864 "synchronize VLDB with server");
5865 cmd_AddParm(ts, "-server", CMD_SINGLE, CMD_OPTIONAL, "machine name");
5866 cmd_AddParm(ts, "-partition", CMD_SINGLE, CMD_OPTIONAL, "partition name");
5867 cmd_AddParm(ts, "-volume", CMD_SINGLE, CMD_OPTIONAL, "volume name or ID");
5870 ts = cmd_CreateSyntax("syncserv", SyncServer, 0,
5871 "synchronize server with VLDB");
5872 cmd_AddParm(ts, "-server", CMD_SINGLE, 0, "machine name");
5873 cmd_AddParm(ts, "-partition", CMD_SINGLE, CMD_OPTIONAL, "partition name");
5876 ts = cmd_CreateSyntax("examine", ExamineVolume, 0,
5877 "everything about the volume");
5878 cmd_AddParm(ts, "-id", CMD_SINGLE, 0, "volume name or ID");
5879 cmd_AddParm(ts, "-extended", CMD_FLAG, CMD_OPTIONAL,
5880 "list extended volume fields");
5881 #ifdef FULL_LISTVOL_SWITCH
5882 cmd_AddParm(ts, "-format", CMD_FLAG, CMD_OPTIONAL,
5883 "machine readable format");
5884 #endif /* FULL_LISTVOL_SWITCH */
5886 cmd_CreateAlias(ts, "volinfo");
5888 ts = cmd_CreateSyntax("setfields", SetFields, 0,
5889 "change volume info fields");
5890 cmd_AddParm(ts, "-id", CMD_SINGLE, 0, "volume name or ID");
5891 cmd_AddParm(ts, "-maxquota", CMD_SINGLE, CMD_OPTIONAL, "quota (KB)");
5892 cmd_AddParm(ts, "-clearuse", CMD_FLAG, CMD_OPTIONAL, "clear dayUse");
5895 ts = cmd_CreateSyntax("offline", volOffline, 0, (char *)CMD_HIDDEN);
5896 cmd_AddParm(ts, "-server", CMD_SINGLE, 0, "server name");
5897 cmd_AddParm(ts, "-partition", CMD_SINGLE, 0, "partition name");
5898 cmd_AddParm(ts, "-id", CMD_SINGLE, 0, "volume name or ID");
5899 cmd_AddParm(ts, "-sleep", CMD_SINGLE, CMD_OPTIONAL, "seconds to sleep");
5900 cmd_AddParm(ts, "-busy", CMD_FLAG, CMD_OPTIONAL, "busy volume");
5903 ts = cmd_CreateSyntax("online", volOnline, 0, (char *)CMD_HIDDEN);
5904 cmd_AddParm(ts, "-server", CMD_SINGLE, 0, "server name");
5905 cmd_AddParm(ts, "-partition", CMD_SINGLE, 0, "partition name");
5906 cmd_AddParm(ts, "-id", CMD_SINGLE, 0, "volume name or ID");
5909 ts = cmd_CreateSyntax("zap", VolumeZap, 0,
5910 "delete the volume, don't bother with VLDB");
5911 cmd_AddParm(ts, "-server", CMD_SINGLE, 0, "machine name");
5912 cmd_AddParm(ts, "-partition", CMD_SINGLE, 0, "partition name");
5913 cmd_AddParm(ts, "-id", CMD_SINGLE, 0, "volume ID");
5914 cmd_AddParm(ts, "-force", CMD_FLAG, CMD_OPTIONAL,
5915 "force deletion of bad volumes");
5916 cmd_AddParm(ts, "-backup", CMD_FLAG, CMD_OPTIONAL,
5917 "also delete backup volume if one is found");
5920 ts = cmd_CreateSyntax("status", VolserStatus, 0,
5921 "report on volser status");
5922 cmd_AddParm(ts, "-server", CMD_SINGLE, 0, "machine name");
5925 ts = cmd_CreateSyntax("rename", RenameVolume, 0, "rename a volume");
5926 cmd_AddParm(ts, "-oldname", CMD_SINGLE, 0, "old volume name ");
5927 cmd_AddParm(ts, "-newname", CMD_SINGLE, 0, "new volume name ");
5930 ts = cmd_CreateSyntax("listvldb", ListVLDB, 0,
5931 "list volumes in the VLDB");
5932 cmd_AddParm(ts, "-name", CMD_SINGLE, CMD_OPTIONAL, "volume name or ID");
5933 cmd_AddParm(ts, "-server", CMD_SINGLE, CMD_OPTIONAL, "machine name");
5934 cmd_AddParm(ts, "-partition", CMD_SINGLE, CMD_OPTIONAL, "partition name");
5935 cmd_AddParm(ts, "-locked", CMD_FLAG, CMD_OPTIONAL, "locked volumes only");
5936 cmd_AddParm(ts, "-quiet", CMD_FLAG, CMD_OPTIONAL,
5937 "generate minimal information");
5938 cmd_AddParm(ts, "-nosort", CMD_FLAG, CMD_OPTIONAL,
5939 "do not alphabetically sort the volume names");
5942 ts = cmd_CreateSyntax("backupsys", BackSys, 0, "en masse backups");
5943 cmd_AddParm(ts, "-prefix", CMD_LIST, CMD_OPTIONAL,
5944 "common prefix on volume(s)");
5945 cmd_AddParm(ts, "-server", CMD_SINGLE, CMD_OPTIONAL, "machine name");
5946 cmd_AddParm(ts, "-partition", CMD_SINGLE, CMD_OPTIONAL, "partition name");
5947 cmd_AddParm(ts, "-exclude", CMD_FLAG, CMD_OPTIONAL,
5948 "exclude common prefix volumes");
5949 cmd_AddParm(ts, "-xprefix", CMD_LIST, CMD_OPTIONAL,
5950 "negative prefix on volume(s)");
5951 cmd_AddParm(ts, "-dryrun", CMD_FLAG, CMD_OPTIONAL, "no action");
5954 ts = cmd_CreateSyntax("delentry", DeleteEntry, 0,
5955 "delete VLDB entry for a volume");
5956 cmd_AddParm(ts, "-id", CMD_LIST, CMD_OPTIONAL, "volume name or ID");
5957 cmd_AddParm(ts, "-prefix", CMD_SINGLE, CMD_OPTIONAL,
5958 "prefix of the volume whose VLDB entry is to be deleted");
5959 cmd_AddParm(ts, "-server", CMD_SINGLE, CMD_OPTIONAL, "machine name");
5960 cmd_AddParm(ts, "-partition", CMD_SINGLE, CMD_OPTIONAL, "partition name");
5961 cmd_AddParm(ts, "-noexecute", CMD_FLAG, CMD_OPTIONAL | CMD_HIDE,
5965 ts = cmd_CreateSyntax("partinfo", PartitionInfo, 0,
5966 "list partition information");
5967 cmd_AddParm(ts, "-server", CMD_SINGLE, 0, "machine name");
5968 cmd_AddParm(ts, "-partition", CMD_SINGLE, CMD_OPTIONAL, "partition name");
5969 cmd_AddParm(ts, "-summary", CMD_FLAG, CMD_OPTIONAL,
5970 "print storage summary");
5973 ts = cmd_CreateSyntax("unlockvldb", UnlockVLDB, 0,
5974 "unlock all the locked entries in the VLDB");
5975 cmd_AddParm(ts, "-server", CMD_SINGLE, CMD_OPTIONAL, "machine name");
5976 cmd_AddParm(ts, "-partition", CMD_SINGLE, CMD_OPTIONAL, "partition name");
5979 ts = cmd_CreateSyntax("lock", LockEntry, 0,
5980 "lock VLDB entry for a volume");
5981 cmd_AddParm(ts, "-id", CMD_SINGLE, 0, "volume name or ID");
5984 ts = cmd_CreateSyntax("changeaddr", ChangeAddr, 0,
5985 "change the IP address of a file server");
5986 cmd_AddParm(ts, "-oldaddr", CMD_SINGLE, 0, "original IP address");
5987 cmd_AddParm(ts, "-newaddr", CMD_SINGLE, CMD_OPTIONAL, "new IP address");
5988 cmd_AddParm(ts, "-remove", CMD_FLAG, CMD_OPTIONAL,
5989 "remove the IP address from the VLDB");
5992 ts = cmd_CreateSyntax("listaddrs", ListAddrs, 0,
5993 "list the IP address of all file servers registered in the VLDB");
5994 cmd_AddParm(ts, "-uuid", CMD_SINGLE, CMD_OPTIONAL, "uuid of server");
5995 cmd_AddParm(ts, "-host", CMD_SINGLE, CMD_OPTIONAL, "address of host");
5996 cmd_AddParm(ts, "-noresolve", CMD_FLAG, CMD_OPTIONAL,
5997 "don't resolve addresses");
5998 cmd_AddParm(ts, "-printuuid", CMD_FLAG, CMD_OPTIONAL,
5999 "print uuid of hosts");
6002 ts = cmd_CreateSyntax("convertROtoRW", ConvertRO, 0,
6003 "convert a RO volume into a RW volume (after loss of old RW volume)");
6004 cmd_AddParm(ts, "-server", CMD_SINGLE, 0, "machine name");
6005 cmd_AddParm(ts, "-partition", CMD_SINGLE, 0, "partition name");
6006 cmd_AddParm(ts, "-id", CMD_SINGLE, 0, "volume name or ID");
6007 cmd_AddParm(ts, "-force", CMD_FLAG, CMD_OPTIONAL, "don't ask");
6010 ts = cmd_CreateSyntax("size", Sizes, 0,
6011 "obtain various sizes of the volume.");
6012 cmd_AddParm(ts, "-id", CMD_SINGLE, 0, "volume name or ID");
6013 cmd_AddParm(ts, "-partition", CMD_SINGLE, CMD_OPTIONAL, "partition name");
6014 cmd_AddParm(ts, "-server", CMD_SINGLE, CMD_OPTIONAL, "machine name");
6015 cmd_AddParm(ts, "-dump", CMD_FLAG, CMD_OPTIONAL,
6016 "Obtain the size of the dump");
6017 cmd_AddParm(ts, "-time", CMD_SINGLE, CMD_OPTIONAL, "dump from time");
6020 code = cmd_Dispatch(argc, argv);
6022 /* Shut down the ubik_client and rx connections */
6024 (void)ubik_ClientDestroy(cstruct);
6030 exit((code ? -1 : 0));