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>
29 #include <sys/statfs.h>
45 #include <rx/rx_globals.h>
47 #include <afs/vlserver.h>
49 #include <afs/cellconfig.h>
51 #include <afs/afsutil.h>
53 #include <afs/afsint.h>
63 #include "volser_prototypes.h"
65 #ifdef HAVE_POSIX_REGEX
80 struct hostent *hostutil_GetHostByName(register char *ahost);
82 #define COMMONPARMS cmd_Seek(ts, 12);\
83 cmd_AddParm(ts, "-cell", CMD_SINGLE, CMD_OPTIONAL, "cell name");\
84 cmd_AddParm(ts, "-noauth", CMD_FLAG, CMD_OPTIONAL, "don't authenticate");\
85 cmd_AddParm(ts, "-localauth",CMD_FLAG,CMD_OPTIONAL,"use server tickets");\
86 cmd_AddParm(ts, "-verbose", CMD_FLAG, CMD_OPTIONAL, "verbose");\
87 cmd_AddParm(ts, "-encrypt", CMD_FLAG, CMD_OPTIONAL, "encrypt commands");\
89 #define ERROR_EXIT(code) {error=(code); goto error_exit;}
93 struct rx_connection *tconn;
95 extern struct ubik_client *cstruct;
97 extern struct rx_connection *UV_Bind();
98 extern int UV_SetSecurity();
99 extern int UV_SetVolumeInfo();
100 extern int vsu_SetCrypt();
102 extern VL_ReleaseLock();
103 extern VL_DeleteEntry();
104 extern VL_ListEntry();
105 extern VL_GetAddrs();
106 extern VL_GetAddrsU();
107 extern VL_ChangeAddr();
109 extern int vsu_ExtractName();
111 extern void EnumerateEntry();
112 extern void SubEnumerateEntry();
115 static struct tqHead busyHead, notokHead;
119 struct tqHead *ahead;
121 memset((char *)ahead, 0, sizeof(struct tqHead));
128 struct tqHead *ahead;
133 elem = (struct tqElem *)malloc(sizeof(struct tqElem));
134 elem->next = ahead->next;
143 struct tqHead *ahead;
148 if (ahead->count <= 0)
150 *volid = ahead->next->volid;
152 ahead->next = tmp->next;
158 /* returns 1 if <filename> exists else 0 */
167 code = usd_Open(filename, USD_OPEN_RDONLY, 0, &ufd);
171 code = USD_IOCTL(ufd, USD_IOCTL_GETSIZE, &size);
179 /* returns 1 if <name> doesnot end in .readonly or .backup, else 0 */
187 total = strlen(name);
188 if (!strcmp(&name[total - 9], ".readonly")) {
190 } else if (!strcmp(&name[total - 7], ".backup")) {
197 /* return 1 if name is a number else 0 */
208 for (i = 0; i < len; i++) {
209 if (*ptr < '0' || *ptr > '9') {
223 * Parse a server name/address and return the address in HOST BYTE order
229 register struct hostent *th;
232 register afs_int32 code;
233 char hostname[MAXHOSTCHARS];
235 code = sscanf(aname, "%d.%d.%d.%d", &b1, &b2, &b3, &b4);
237 addr = (b1 << 24) | (b2 << 16) | (b3 << 8) | b4;
238 addr = ntohl(addr); /* convert to host order */
240 th = gethostbyname(aname);
243 memcpy(&addr, th->h_addr, sizeof(addr));
246 if (addr == htonl(0x7f000001)) { /* local host */
247 code = gethostname(hostname, MAXHOSTCHARS);
250 th = gethostbyname(hostname); /* returns host byte order */
253 memcpy(&addr, th->h_addr, sizeof(addr));
264 if (!strcmp(aname, "ro"))
266 else if (!strcmp(aname, "rw"))
268 else if (!strcmp(aname, "bk"))
275 IsPartValid(partId, server, code)
276 afs_int32 server, partId, *code;
279 struct partList dummyPartList;
287 *code = UV_ListPartitions(server, &dummyPartList, &cnt);
290 for (i = 0; i < cnt; i++) {
291 if (dummyPartList.partFlags[i] & PARTVALID)
292 if (dummyPartList.partId[i] == partId)
300 /*sends the contents of file associated with <fd> and <blksize> to Rx Stream
301 * associated with <call> */
302 SendFile(ufd, call, blksize)
304 register struct rx_call *call;
307 char *buffer = (char *)0;
312 buffer = (char *)malloc(blksize);
314 fprintf(STDERR, "malloc failed\n");
318 while (!error && !done) {
319 #ifndef AFS_NT40_ENV /* NT csn't select on non-socket fd's */
322 FD_SET((int)(ufd->handle), &in);
323 /* don't timeout if read blocks */
324 IOMGR_Select(((int)(ufd->handle)) + 1, &in, 0, 0, 0);
326 error = USD_READ(ufd, buffer, blksize, &nbytes);
328 fprintf(STDERR, "File system read failed\n");
335 if (rx_Write(call, buffer, nbytes) != nbytes) {
345 /* function invoked by UV_RestoreVolume, reads the data from rx_trx_stream and
346 * writes it out to the volume. */
348 WriteData(call, rock)
349 struct rx_call *call;
355 afs_int32 error, code;
361 if (!filename || !*filename) {
362 usd_StandardInput(&ufd);
366 code = usd_Open(filename, USD_OPEN_RDONLY, 0, &ufd);
369 code = USD_IOCTL(ufd, USD_IOCTL_GETBLKSIZE, &blksize);
372 fprintf(STDERR, "Could not access file '%s'\n", filename);
377 code = SendFile(ufd, call, blksize);
384 code = USD_CLOSE(ufd);
386 fprintf(STDERR, "Could not close dump file %s\n",
387 (filename && *filename) ? filename : "STDOUT");
395 /* Receive data from <call> stream into file associated
396 * with <fd> <blksize>
399 ReceiveFile(ufd, call, blksize)
401 struct rx_call *call;
406 afs_uint32 bytesleft, w;
409 buffer = (char *)malloc(blksize);
411 fprintf(STDERR, "memory allocation failed\n");
415 while ((bytesread = rx_Read(call, buffer, blksize)) > 0) {
416 for (bytesleft = bytesread; bytesleft; bytesleft -= w) {
417 #ifndef AFS_NT40_ENV /* NT csn't select on non-socket fd's */
420 FD_SET((int)(ufd->handle), &out);
421 /* don't timeout if write blocks */
422 IOMGR_Select(((int)(ufd->handle)) + 1, 0, &out, 0, 0);
425 USD_WRITE(ufd, &buffer[bytesread - bytesleft], bytesleft, &w);
427 fprintf(STDERR, "File system write failed\n");
440 DumpFunction(call, filename)
441 struct rx_call *call;
444 usd_handle_t ufd; /* default is to stdout */
445 afs_int32 error = 0, code;
450 /* Open the output file */
451 if (!filename || !*filename) {
452 usd_StandardOutput(&ufd);
457 usd_Open(filename, USD_OPEN_CREATE | USD_OPEN_RDWR, 0666, &ufd);
461 code = USD_IOCTL(ufd, USD_IOCTL_SETSIZE, &size);
464 code = USD_IOCTL(ufd, USD_IOCTL_GETBLKSIZE, &blksize);
467 fprintf(STDERR, "Could not create file '%s'\n", filename);
468 ERROR_EXIT(VOLSERBADOP);
472 code = ReceiveFile(ufd, call, blksize);
477 /* Close the output file */
479 code = USD_CLOSE(ufd);
481 fprintf(STDERR, "Could not close dump file %s\n",
482 (filename && *filename) ? filename : "STDIN");
492 DisplayFormat(pntr, server, part, totalOK, totalNotOK, totalBusy, fast,
495 afs_int32 server, part;
496 int *totalOK, *totalNotOK, *totalBusy;
497 int fast, longlist, disp;
502 fprintf(STDOUT, "%-10lu\n", (unsigned long)pntr->volid);
503 } else if (longlist) {
504 if (pntr->status == VOK) {
505 fprintf(STDOUT, "%-32s ", pntr->name);
506 fprintf(STDOUT, "%10lu ", (unsigned long)pntr->volid);
508 fprintf(STDOUT, "RW ");
510 fprintf(STDOUT, "RO ");
512 fprintf(STDOUT, "BK ");
513 fprintf(STDOUT, "%10d K ", pntr->size);
514 if (pntr->inUse == 1) {
515 fprintf(STDOUT, "On-line");
518 fprintf(STDOUT, "Off-line");
521 if (pntr->needsSalvaged == 1)
522 fprintf(STDOUT, "**needs salvage**");
523 fprintf(STDOUT, "\n");
524 MapPartIdIntoName(part, pname);
525 fprintf(STDOUT, " %s %s \n", hostutil_GetNameByINet(server),
527 fprintf(STDOUT, " RWrite %10lu ROnly %10lu Backup %10lu \n",
528 (unsigned long)pntr->parentID,
529 (unsigned long)pntr->cloneID,
530 (unsigned long)pntr->backupID);
531 fprintf(STDOUT, " MaxQuota %10d K \n", pntr->maxquota);
532 fprintf(STDOUT, " Creation %s",
533 ctime((time_t *) & pntr->creationDate));
534 #ifdef FULL_LISTVOL_SWITCH
535 fprintf(STDOUT, " Copy %s",
536 ctime((time_t *) & pntr->copyDate));
537 if (!pntr->backupDate)
538 fprintf(STDOUT, " Backup Never\n");
540 fprintf(STDOUT, " Backup %s",
541 ctime((time_t *) & pntr->backupDate));
542 if (pntr->accessDate)
543 fprintf(STDOUT, " Last Access %s",
544 ctime((time_t *) & pntr->accessDate));
546 if (pntr->updateDate < pntr->creationDate)
547 fprintf(STDOUT, " Last Update %s",
548 ctime((time_t *) & pntr->creationDate));
550 fprintf(STDOUT, " Last Update %s",
551 ctime((time_t *) & pntr->updateDate));
553 " %d accesses in the past day (i.e., vnode references)\n",
555 } else if (pntr->status == VBUSY) {
557 qPut(&busyHead, pntr->volid);
559 fprintf(STDOUT, "**** Volume %lu is busy ****\n",
560 (unsigned long)pntr->volid);
563 qPut(¬okHead, pntr->volid);
565 fprintf(STDOUT, "**** Could not attach volume %lu ****\n",
566 (unsigned long)pntr->volid);
568 fprintf(STDOUT, "\n");
569 } else { /* default listing */
570 if (pntr->status == VOK) {
571 fprintf(STDOUT, "%-32s ", pntr->name);
572 fprintf(STDOUT, "%10lu ", (unsigned long)pntr->volid);
574 fprintf(STDOUT, "RW ");
576 fprintf(STDOUT, "RO ");
578 fprintf(STDOUT, "BK ");
579 fprintf(STDOUT, "%10d K ", pntr->size);
580 if (pntr->inUse == 1) {
581 fprintf(STDOUT, "On-line");
584 fprintf(STDOUT, "Off-line");
587 if (pntr->needsSalvaged == 1)
588 fprintf(STDOUT, "**needs salvage**");
589 fprintf(STDOUT, "\n");
590 } else if (pntr->status == VBUSY) {
592 qPut(&busyHead, pntr->volid);
594 fprintf(STDOUT, "**** Volume %lu is busy ****\n",
595 (unsigned long)pntr->volid);
598 qPut(¬okHead, pntr->volid);
600 fprintf(STDOUT, "**** Could not attach volume %lu ****\n",
601 (unsigned long)pntr->volid);
606 /*------------------------------------------------------------------------
607 * PRIVATE XDisplayFormat
610 * Display the contents of one extended volume info structure.
613 * a_xInfoP : Ptr to extended volume info struct to print.
614 * a_servID : Server ID to print.
615 * a_partID : Partition ID to print.
616 * a_totalOKP : Ptr to total-OK counter.
617 * a_totalNotOKP : Ptr to total-screwed counter.
618 * a_totalBusyP : Ptr to total-busy counter.
619 * a_fast : Fast listing?
620 * a_int32 : Int32 listing?
621 * a_showProblems : Show volume problems?
627 * Nothing interesting.
631 *------------------------------------------------------------------------*/
634 XDisplayFormat(a_xInfoP, a_servID, a_partID, a_totalOKP, a_totalNotOKP,
635 a_totalBusyP, a_fast, a_int32, a_showProblems)
636 volintXInfo *a_xInfoP;
646 { /*XDisplayFormat */
654 fprintf(STDOUT, "%-10lu\n", (unsigned long)a_xInfoP->volid);
655 } else if (a_int32) {
657 * Fully-detailed listing.
659 if (a_xInfoP->status == VOK) {
661 * Volume's status is OK - all the fields are valid.
663 fprintf(STDOUT, "%-32s ", a_xInfoP->name);
664 fprintf(STDOUT, "%10lu ", (unsigned long)a_xInfoP->volid);
665 if (a_xInfoP->type == 0)
666 fprintf(STDOUT, "RW ");
667 if (a_xInfoP->type == 1)
668 fprintf(STDOUT, "RO ");
669 if (a_xInfoP->type == 2)
670 fprintf(STDOUT, "BK ");
671 fprintf(STDOUT, "%10d K used ", a_xInfoP->size);
672 fprintf(STDOUT, "%d files ", a_xInfoP->filecount);
673 if (a_xInfoP->inUse == 1) {
674 fprintf(STDOUT, "On-line");
677 fprintf(STDOUT, "Off-line");
680 fprintf(STDOUT, "\n");
681 MapPartIdIntoName(a_partID, pname);
682 fprintf(STDOUT, " %s %s \n", hostutil_GetNameByINet(a_servID),
684 fprintf(STDOUT, " RWrite %10lu ROnly %10lu Backup %10lu \n",
685 (unsigned long)a_xInfoP->parentID,
686 (unsigned long)a_xInfoP->cloneID,
687 (unsigned long)a_xInfoP->backupID);
688 fprintf(STDOUT, " MaxQuota %10d K \n", a_xInfoP->maxquota);
689 fprintf(STDOUT, " Creation %s",
690 ctime((time_t *) & a_xInfoP->creationDate));
691 #ifdef FULL_LISTVOL_SWITCH
692 fprintf(STDOUT, " Copy %s",
693 ctime((time_t *) & a_xInfoP->copyDate));
694 if (!a_xInfoP->backupDate)
695 fprintf(STDOUT, " Backup Never\n");
697 fprintf(STDOUT, " Backup %s",
698 ctime((time_t *) & a_xInfoP->backupDate));
699 if (a_xInfoP->accessDate)
700 fprintf(STDOUT, " Last Access %s",
701 ctime((time_t *) & a_xInfoP->accessDate));
703 if (a_xInfoP->updateDate < a_xInfoP->creationDate)
704 fprintf(STDOUT, " Last Update %s",
705 ctime((time_t *) & a_xInfoP->creationDate));
707 fprintf(STDOUT, " Last Update %s",
708 ctime((time_t *) & a_xInfoP->updateDate));
710 " %d accesses in the past day (i.e., vnode references)\n",
714 * Print all the read/write and authorship stats.
716 fprintf(STDOUT, "\n Raw Read/Write Stats\n");
718 " |-------------------------------------------|\n");
720 " | Same Network | Diff Network |\n");
722 " |----------|----------|----------|----------|\n");
724 " | Total | Auth | Total | Auth |\n");
726 " |----------|----------|----------|----------|\n");
727 fprintf(STDOUT, "Reads | %8d | %8d | %8d | %8d |\n",
728 a_xInfoP->stat_reads[VOLINT_STATS_SAME_NET],
729 a_xInfoP->stat_reads[VOLINT_STATS_SAME_NET_AUTH],
730 a_xInfoP->stat_reads[VOLINT_STATS_DIFF_NET],
731 a_xInfoP->stat_reads[VOLINT_STATS_DIFF_NET_AUTH]);
732 fprintf(STDOUT, "Writes | %8d | %8d | %8d | %8d |\n",
733 a_xInfoP->stat_writes[VOLINT_STATS_SAME_NET],
734 a_xInfoP->stat_writes[VOLINT_STATS_SAME_NET_AUTH],
735 a_xInfoP->stat_writes[VOLINT_STATS_DIFF_NET],
736 a_xInfoP->stat_writes[VOLINT_STATS_DIFF_NET_AUTH]);
738 " |-------------------------------------------|\n\n");
741 " Writes Affecting Authorship\n");
743 " |-------------------------------------------|\n");
745 " | File Authorship | Directory Authorship|\n");
747 " |----------|----------|----------|----------|\n");
749 " | Same | Diff | Same | Diff |\n");
751 " |----------|----------|----------|----------|\n");
752 fprintf(STDOUT, "0-60 sec | %8d | %8d | %8d | %8d |\n",
753 a_xInfoP->stat_fileSameAuthor[VOLINT_STATS_TIME_IDX_0],
754 a_xInfoP->stat_fileDiffAuthor[VOLINT_STATS_TIME_IDX_0],
755 a_xInfoP->stat_dirSameAuthor[VOLINT_STATS_TIME_IDX_0],
756 a_xInfoP->stat_dirDiffAuthor[VOLINT_STATS_TIME_IDX_0]);
757 fprintf(STDOUT, "1-10 min | %8d | %8d | %8d | %8d |\n",
758 a_xInfoP->stat_fileSameAuthor[VOLINT_STATS_TIME_IDX_1],
759 a_xInfoP->stat_fileDiffAuthor[VOLINT_STATS_TIME_IDX_1],
760 a_xInfoP->stat_dirSameAuthor[VOLINT_STATS_TIME_IDX_1],
761 a_xInfoP->stat_dirDiffAuthor[VOLINT_STATS_TIME_IDX_1]);
762 fprintf(STDOUT, "10min-1hr | %8d | %8d | %8d | %8d |\n",
763 a_xInfoP->stat_fileSameAuthor[VOLINT_STATS_TIME_IDX_2],
764 a_xInfoP->stat_fileDiffAuthor[VOLINT_STATS_TIME_IDX_2],
765 a_xInfoP->stat_dirSameAuthor[VOLINT_STATS_TIME_IDX_2],
766 a_xInfoP->stat_dirDiffAuthor[VOLINT_STATS_TIME_IDX_2]);
767 fprintf(STDOUT, "1hr-1day | %8d | %8d | %8d | %8d |\n",
768 a_xInfoP->stat_fileSameAuthor[VOLINT_STATS_TIME_IDX_3],
769 a_xInfoP->stat_fileDiffAuthor[VOLINT_STATS_TIME_IDX_3],
770 a_xInfoP->stat_dirSameAuthor[VOLINT_STATS_TIME_IDX_3],
771 a_xInfoP->stat_dirDiffAuthor[VOLINT_STATS_TIME_IDX_3]);
772 fprintf(STDOUT, "1day-1wk | %8d | %8d | %8d | %8d |\n",
773 a_xInfoP->stat_fileSameAuthor[VOLINT_STATS_TIME_IDX_4],
774 a_xInfoP->stat_fileDiffAuthor[VOLINT_STATS_TIME_IDX_4],
775 a_xInfoP->stat_dirSameAuthor[VOLINT_STATS_TIME_IDX_4],
776 a_xInfoP->stat_dirDiffAuthor[VOLINT_STATS_TIME_IDX_4]);
777 fprintf(STDOUT, "> 1wk | %8d | %8d | %8d | %8d |\n",
778 a_xInfoP->stat_fileSameAuthor[VOLINT_STATS_TIME_IDX_5],
779 a_xInfoP->stat_fileDiffAuthor[VOLINT_STATS_TIME_IDX_5],
780 a_xInfoP->stat_dirSameAuthor[VOLINT_STATS_TIME_IDX_5],
781 a_xInfoP->stat_dirDiffAuthor[VOLINT_STATS_TIME_IDX_5]);
783 " |-------------------------------------------|\n");
784 } /*Volume status OK */
785 else if (a_xInfoP->status == VBUSY) {
787 qPut(&busyHead, a_xInfoP->volid);
789 fprintf(STDOUT, "**** Volume %lu is busy ****\n",
790 (unsigned long)a_xInfoP->volid);
794 qPut(¬okHead, a_xInfoP->volid);
796 fprintf(STDOUT, "**** Could not attach volume %lu ****\n",
797 (unsigned long)a_xInfoP->volid);
798 } /*Screwed volume */
799 fprintf(STDOUT, "\n");
805 if (a_xInfoP->status == VOK) {
806 fprintf(STDOUT, "%-32s ", a_xInfoP->name);
807 fprintf(STDOUT, "%10lu ", (unsigned long)a_xInfoP->volid);
808 if (a_xInfoP->type == 0)
809 fprintf(STDOUT, "RW ");
810 if (a_xInfoP->type == 1)
811 fprintf(STDOUT, "RO ");
812 if (a_xInfoP->type == 2)
813 fprintf(STDOUT, "BK ");
814 fprintf(STDOUT, "%10d K ", a_xInfoP->size);
815 if (a_xInfoP->inUse == 1) {
816 fprintf(STDOUT, "On-line");
819 fprintf(STDOUT, "Off-line");
822 fprintf(STDOUT, "\n");
824 else if (a_xInfoP->status == VBUSY) {
826 qPut(&busyHead, a_xInfoP->volid);
828 fprintf(STDOUT, "**** Volume %lu is busy ****\n",
829 (unsigned long)a_xInfoP->volid);
833 qPut(¬okHead, a_xInfoP->volid);
835 fprintf(STDOUT, "**** Could not attach volume %lu ****\n",
836 (unsigned long)a_xInfoP->volid);
837 } /*Screwed volume */
838 } /*Default listing */
839 } /*XDisplayFormat */
841 #ifdef FULL_LISTVOL_SWITCH
843 DisplayFormat2(server, partition, pntr)
844 long server, partition;
847 static long server_cache = -1, partition_cache = -1;
848 static char hostname[256], address[32], pname[16];
850 if (server != server_cache) {
854 strcpy(hostname, hostutil_GetNameByINet(server));
855 strcpy(address, inet_ntoa(s));
856 server_cache = server;
858 if (partition != partition_cache) {
859 MapPartIdIntoName(partition, pname);
860 partition_cache = partition;
862 fprintf(STDOUT, "name\t\t%s\n", pntr->name);
863 fprintf(STDOUT, "id\t\t%lu\n", pntr->volid);
864 fprintf(STDOUT, "serv\t\t%s\t%s\n", address, hostname);
865 fprintf(STDOUT, "part\t\t%s\n", pname);
866 switch (pntr->status) {
868 fprintf(STDOUT, "status\t\tOK\n");
871 fprintf(STDOUT, "status\t\tBUSY\n");
874 fprintf(STDOUT, "status\t\tUNATTACHABLE\n");
877 fprintf(STDOUT, "backupID\t%lu\n", pntr->backupID);
878 fprintf(STDOUT, "parentID\t%lu\n", pntr->parentID);
879 fprintf(STDOUT, "cloneID\t\t%lu\n", pntr->cloneID);
880 fprintf(STDOUT, "inUse\t\t%s\n", pntr->inUse ? "Y" : "N");
881 fprintf(STDOUT, "needsSalvaged\t%s\n", pntr->needsSalvaged ? "Y" : "N");
882 /* 0xD3 is from afs/volume.h since I had trouble including the file */
883 fprintf(STDOUT, "destroyMe\t%s\n", pntr->destroyMe == 0xD3 ? "Y" : "N");
884 switch (pntr->type) {
886 fprintf(STDOUT, "type\t\tRW\n");
889 fprintf(STDOUT, "type\t\tRO\n");
892 fprintf(STDOUT, "type\t\tBK\n");
895 fprintf(STDOUT, "type\t\t?\n");
898 fprintf(STDOUT, "creationDate\t%-9lu\t%s", pntr->creationDate,
899 ctime(&pntr->creationDate));
900 fprintf(STDOUT, "accessDate\t%-9lu\t%s", pntr->accessDate,
901 ctime(&pntr->accessDate));
902 fprintf(STDOUT, "updateDate\t%-9lu\t%s", pntr->updateDate,
903 ctime(&pntr->updateDate));
904 fprintf(STDOUT, "backupDate\t%-9lu\t%s", pntr->backupDate,
905 ctime(&pntr->backupDate));
906 fprintf(STDOUT, "copyDate\t%-9lu\t%s", pntr->copyDate,
907 ctime(&pntr->copyDate));
908 fprintf(STDOUT, "flags\t\t%#lx\t(Optional)\n", pntr->flags);
909 fprintf(STDOUT, "diskused\t%u\n", pntr->size);
910 fprintf(STDOUT, "maxquota\t%u\n", pntr->maxquota);
911 fprintf(STDOUT, "minquota\t%lu\t(Optional)\n", pntr->spare0);
912 fprintf(STDOUT, "filecount\t%u\n", pntr->filecount);
913 fprintf(STDOUT, "dayUse\t\t%u\n", pntr->dayUse);
914 fprintf(STDOUT, "weekUse\t\t%lu\t(Optional)\n", pntr->spare1);
915 fprintf(STDOUT, "spare2\t\t%lu\t(Optional)\n", pntr->spare2);
916 fprintf(STDOUT, "spare3\t\t%lu\t(Optional)\n", pntr->spare3);
921 DisplayVolumes2(server, partition, pntr, count)
923 long server, partition, count;
927 for (i = 0; i < count; i++) {
928 fprintf(STDOUT, "BEGIN_OF_ENTRY\n");
929 DisplayFormat2(server, partition, pntr);
930 fprintf(STDOUT, "END_OF_ENTRY\n\n");
935 #endif /* FULL_LISTVOL_SWITCH */
938 DisplayVolumes(server, part, pntr, count, longlist, fast, quiet)
939 afs_int32 server, part;
941 afs_int32 count, longlist, fast;
944 int totalOK, totalNotOK, totalBusy, i;
952 for (i = 0; i < count; i++) {
953 DisplayFormat(pntr, server, part, &totalOK, &totalNotOK, &totalBusy,
958 while (busyHead.count) {
959 qGet(&busyHead, &volid);
960 fprintf(STDOUT, "**** Volume %lu is busy ****\n",
961 (unsigned long)volid);
965 while (notokHead.count) {
966 qGet(¬okHead, &volid);
967 fprintf(STDOUT, "**** Could not attach volume %lu ****\n",
968 (unsigned long)volid);
972 fprintf(STDOUT, "\n");
975 "Total volumes onLine %d ; Total volumes offLine %d ; Total busy %d\n\n",
976 totalOK, totalNotOK, totalBusy);
981 /*------------------------------------------------------------------------
982 * PRIVATE XDisplayVolumes
985 * Display extended volume information.
988 * a_servID : Pointer to the Rx call we're performing.
989 * a_partID : Partition for which we want the extended list.
990 * a_xInfoP : Ptr to extended volume info.
991 * a_count : Number of volume records contained above.
992 * a_int32 : Int32 listing generated?
993 * a_fast : Fast listing generated?
994 * a_quiet : Quiet listing generated?
1000 * Nothing interesting.
1004 *------------------------------------------------------------------------*/
1007 XDisplayVolumes(a_servID, a_partID, a_xInfoP, a_count, a_int32, a_fast,
1011 volintXInfo *a_xInfoP;
1017 { /*XDisplayVolumes */
1019 int totalOK; /*Total OK volumes */
1020 int totalNotOK; /*Total screwed volumes */
1021 int totalBusy; /*Total busy volumes */
1022 int i; /*Loop variable */
1023 afs_int32 volid; /*Current volume ID */
1026 * Initialize counters and (global!!) queues.
1035 * Display each volume in the list.
1037 for (i = 0; i < a_count; i++) {
1038 XDisplayFormat(a_xInfoP, a_servID, a_partID, &totalOK, &totalNotOK,
1039 &totalBusy, a_fast, a_int32, 0);
1044 * If any volumes were found to be busy or screwed, display them.
1047 while (busyHead.count) {
1048 qGet(&busyHead, &volid);
1049 fprintf(STDOUT, "**** Volume %lu is busy ****\n",
1050 (unsigned long)volid);
1054 while (notokHead.count) {
1055 qGet(¬okHead, &volid);
1056 fprintf(STDOUT, "**** Could not attach volume %lu ****\n",
1057 (unsigned long)volid);
1062 fprintf(STDOUT, "\n");
1065 "Total volumes: %d on-line, %d off-line, %d busyd\n\n",
1066 totalOK, totalNotOK, totalBusy);
1070 } /*XDisplayVolumes */
1072 /* set <server> and <part> to the correct values depending on
1073 * <voltype> and <entry> */
1075 GetServerAndPart(entry, voltype, server, part, previdx)
1076 struct nvldbentry *entry;
1077 afs_int32 *server, *part;
1081 int i, istart, vtype;
1086 /* Doesn't check for non-existance of backup volume */
1087 if ((voltype == RWVOL) || (voltype == BACKVOL)) {
1089 istart = 0; /* seach the entire entry */
1092 /* Seach from beginning of entry or pick up where we left off */
1093 istart = ((*previdx < 0) ? 0 : *previdx + 1);
1096 for (i = istart; i < entry->nServers; i++) {
1097 if (entry->serverFlags[i] & vtype) {
1098 *server = entry->serverNumber[i];
1099 *part = entry->serverPartition[i];
1105 /* Didn't find any, return -1 */
1111 PostVolumeStats(entry)
1112 struct nvldbentry *entry;
1114 SubEnumerateEntry(entry);
1115 /* Check for VLOP_ALLOPERS */
1116 if (entry->flags & VLOP_ALLOPERS)
1117 fprintf(STDOUT, " Volume is currently LOCKED \n");
1121 /*------------------------------------------------------------------------
1122 * PRIVATE XVolumeStats
1125 * Display extended volume information.
1128 * a_xInfoP : Ptr to extended volume info.
1129 * a_entryP : Ptr to the volume's VLDB entry.
1130 * a_srvID : Server ID.
1131 * a_partID : Partition ID.
1132 * a_volType : Type of volume to print.
1138 * Nothing interesting.
1142 *------------------------------------------------------------------------*/
1145 XVolumeStats(a_xInfoP, a_entryP, a_srvID, a_partID, a_volType)
1146 volintXInfo *a_xInfoP;
1147 struct nvldbentry *a_entryP;
1154 int totalOK, totalNotOK, totalBusy; /*Dummies - we don't really count here */
1156 XDisplayFormat(a_xInfoP, /*Ptr to extended volume info */
1157 a_srvID, /*Server ID to print */
1158 a_partID, /*Partition ID to print */
1159 &totalOK, /*Ptr to total-OK counter */
1160 &totalNotOK, /*Ptr to total-screwed counter */
1161 &totalBusy, /*Ptr to total-busy counter */
1162 0, /*Don't do a fast listing */
1163 1, /*Do a long listing */
1164 1); /*Show volume problems */
1170 VolumeStats(pntr, entry, server, part, voltype)
1172 struct nvldbentry *entry;
1174 afs_int32 server, part;
1176 int totalOK, totalNotOK, totalBusy;
1177 afs_int32 vcode, vcode2;
1179 DisplayFormat(pntr, server, part, &totalOK, &totalNotOK, &totalBusy, 0, 1,
1184 /* command to forcibly remove a volume */
1187 register struct cmd_syndesc *as;
1189 register afs_int32 code;
1190 afs_int32 volID, err;
1195 server = GetServer(tp = as->parms[0].items->data);
1197 fprintf(STDERR, "vos: server '%s' not found in host table\n", tp);
1201 partID = volutil_GetPartitionID(tp = as->parms[1].items->data);
1203 fprintf(STDERR, "vos: could not parse '%s' as a partition name", tp);
1207 volID = vsu_GetVolumeID(tp = as->parms[2].items->data, cstruct, &err);
1210 PrintError("", err);
1213 "vos: could not parse '%s' as a numeric volume ID", tp);
1218 "vos: forcibly removing all traces of volume %d, please wait...",
1221 code = UV_NukeVolume(server, partID, volID);
1223 fprintf(STDOUT, "done.\n");
1225 fprintf(STDOUT, "failed with code %d.\n", code);
1230 /*------------------------------------------------------------------------
1231 * PRIVATE ExamineVolume
1234 * Routine used to examine a single volume, contacting the VLDB as
1235 * well as the Volume Server.
1238 * as : Ptr to parsed command line arguments.
1241 * 0 for a successful operation,
1242 * Otherwise, one of the ubik or VolServer error values.
1245 * Nothing interesting.
1249 *------------------------------------------------------------------------
1253 register struct cmd_syndesc *as;
1255 struct nvldbentry entry;
1256 afs_int32 vcode = 0;
1257 volintInfo *pntr = (volintInfo *) 0;
1258 volintXInfo *xInfoP = (volintXInfo *) 0;
1260 afs_int32 code, err, error = 0;
1261 int voltype, foundserv = 0, foundentry = 0;
1262 afs_int32 aserver, apart;
1264 int wantExtendedInfo; /*Do we want extended vol info? */
1266 wantExtendedInfo = (as->parms[1].items ? 1 : 0); /* -extended */
1268 volid = vsu_GetVolumeID(as->parms[0].items->data, cstruct, &err); /* -id */
1271 PrintError("", err);
1273 fprintf(STDERR, "Unknown volume ID or name '%s'\n",
1274 as->parms[0].items->data);
1279 fprintf(STDOUT, "Fetching VLDB entry for %lu .. ",
1280 (unsigned long)volid);
1283 vcode = VLDB_GetEntryByID(volid, -1, &entry);
1286 "Could not fetch the entry for volume number %lu from VLDB \n",
1287 (unsigned long)volid);
1291 fprintf(STDOUT, "done\n");
1292 MapHostToNetwork(&entry);
1294 if (entry.volumeId[RWVOL] == volid)
1296 else if (entry.volumeId[BACKVOL] == volid)
1298 else /* (entry.volumeId[ROVOL] == volid) */
1301 do { /* do {...} while (voltype == ROVOL) */
1302 /* Get the entry for the volume. If its a RW vol, get the RW entry.
1303 * It its a BK vol, get the RW entry (even if VLDB may say the BK doen't exist).
1304 * If its a RO vol, get the next RO entry.
1306 GetServerAndPart(&entry, ((voltype == ROVOL) ? ROVOL : RWVOL),
1307 &aserver, &apart, &previdx);
1308 if (previdx == -1) { /* searched all entries */
1310 fprintf(STDERR, "Volume %s does not exist in VLDB\n\n",
1311 as->parms[0].items->data);
1318 /* Get information about the volume from the server */
1320 fprintf(STDOUT, "Getting volume listing from the server %s .. ",
1321 hostutil_GetNameByINet(aserver));
1324 if (wantExtendedInfo)
1325 code = UV_XListOneVolume(aserver, apart, volid, &xInfoP);
1327 code = UV_ListOneVolume(aserver, apart, volid, &pntr);
1329 fprintf(STDOUT, "done\n");
1333 if (code == ENODEV) {
1334 if ((voltype == BACKVOL) && !(entry.flags & BACK_EXISTS)) {
1335 /* The VLDB says there is no backup volume and its not on disk */
1336 fprintf(STDERR, "Volume %s does not exist\n",
1337 as->parms[0].items->data);
1341 "Volume does not exist on server %s as indicated by the VLDB\n",
1342 hostutil_GetNameByINet(aserver));
1345 PrintDiagnostics("examine", code);
1347 fprintf(STDOUT, "\n");
1350 if (wantExtendedInfo)
1351 XVolumeStats(xInfoP, &entry, aserver, apart, voltype);
1353 #ifdef FULL_LISTVOL_SWITCH
1354 if (as->parms[2].items) {
1355 DisplayFormat2(aserver, apart, pntr);
1356 EnumerateEntry(&entry);
1358 #endif /* FULL_LISTVOL_SWITCH */
1359 VolumeStats(pntr, &entry, aserver, apart, voltype);
1361 if ((voltype == BACKVOL) && !(entry.flags & BACK_EXISTS)) {
1362 /* The VLDB says there is no backup volume yet we found one on disk */
1363 fprintf(STDERR, "Volume %s does not exist in VLDB\n",
1364 as->parms[0].items->data);
1373 } while (voltype == ROVOL);
1376 fprintf(STDERR, "Dump only information from VLDB\n\n");
1377 fprintf(STDOUT, "%s \n", entry.name); /* PostVolumeStats doesn't print name */
1379 PostVolumeStats(&entry);
1384 /*------------------------------------------------------------------------
1388 * Routine used to change the status of a single volume.
1391 * as : Ptr to parsed command line arguments.
1394 * 0 for a successful operation,
1395 * Otherwise, one of the ubik or VolServer error values.
1398 * Nothing interesting.
1402 *------------------------------------------------------------------------
1406 register struct cmd_syndesc *as;
1408 struct nvldbentry entry;
1409 afs_int32 vcode = 0;
1412 afs_int32 code, err;
1413 afs_int32 aserver, apart;
1416 volid = vsu_GetVolumeID(as->parms[0].items->data, cstruct, &err); /* -id */
1419 PrintError("", err);
1421 fprintf(STDERR, "Unknown volume ID or name '%s'\n",
1422 as->parms[0].items->data);
1426 code = VLDB_GetEntryByID(volid, RWVOL, &entry);
1429 "Could not fetch the entry for volume number %lu from VLDB \n",
1430 (unsigned long)volid);
1433 MapHostToNetwork(&entry);
1435 GetServerAndPart(&entry, RWVOL, &aserver, &apart, &previdx);
1436 if (previdx == -1) {
1437 fprintf(STDERR, "Volume %s does not exist in VLDB\n\n",
1438 as->parms[0].items->data);
1442 memset(&info, 0, sizeof(info));
1453 if (as->parms[1].items) {
1455 code = util_GetInt32(as->parms[1].items->data, &info.maxquota);
1457 fprintf(STDERR, "invalid quota value\n");
1461 if (as->parms[2].items) {
1465 code = UV_SetVolumeInfo(aserver, apart, volid, &info);
1468 "Could not update volume info fields for volume number %lu\n",
1469 (unsigned long)volid);
1473 /*------------------------------------------------------------------------
1477 * Brings a volume online.
1480 * as : Ptr to parsed command line arguments.
1483 * 0 for a successful operation,
1486 * Nothing interesting.
1490 *------------------------------------------------------------------------
1494 register struct cmd_syndesc *as;
1496 afs_int32 server, partition, volid;
1497 afs_int32 code, err = 0;
1499 server = GetServer(as->parms[0].items->data);
1501 fprintf(STDERR, "vos: server '%s' not found in host table\n",
1502 as->parms[0].items->data);
1506 partition = volutil_GetPartitionID(as->parms[1].items->data);
1507 if (partition < 0) {
1508 fprintf(STDERR, "vos: could not interpret partition name '%s'\n",
1509 as->parms[1].items->data);
1513 volid = vsu_GetVolumeID(as->parms[2].items->data, cstruct, &err); /* -id */
1516 PrintError("", err);
1518 fprintf(STDERR, "Unknown volume ID or name '%s'\n",
1519 as->parms[0].items->data);
1523 code = UV_SetVolume(server, partition, volid, ITOffline, 0 /*online */ ,
1526 fprintf(STDERR, "Failed to set volume. Code = %d\n", code);
1533 /*------------------------------------------------------------------------
1534 * PRIVATE volOffline
1537 * Brings a volume offline.
1540 * as : Ptr to parsed command line arguments.
1543 * 0 for a successful operation,
1546 * Nothing interesting.
1550 *------------------------------------------------------------------------
1553 volOffline(register struct cmd_syndesc *as)
1555 afs_int32 server, partition, volid;
1556 afs_int32 code, err = 0;
1557 afs_int32 transflag, sleeptime, transdone;
1559 server = GetServer(as->parms[0].items->data);
1561 fprintf(STDERR, "vos: server '%s' not found in host table\n",
1562 as->parms[0].items->data);
1566 partition = volutil_GetPartitionID(as->parms[1].items->data);
1567 if (partition < 0) {
1568 fprintf(STDERR, "vos: could not interpret partition name '%s'\n",
1569 as->parms[1].items->data);
1573 volid = vsu_GetVolumeID(as->parms[2].items->data, cstruct, &err); /* -id */
1576 PrintError("", err);
1578 fprintf(STDERR, "Unknown volume ID or name '%s'\n",
1579 as->parms[0].items->data);
1583 transflag = (as->parms[4].items ? ITBusy : ITOffline);
1584 sleeptime = (as->parms[3].items ? atol(as->parms[3].items->data) : 0);
1585 transdone = (sleeptime ? 0 /*online */ : VTOutOfService);
1586 if (as->parms[4].items && !as->parms[3].items) {
1587 fprintf(STDERR, "-sleep option must be used with -busy flag\n");
1592 UV_SetVolume(server, partition, volid, transflag, transdone,
1595 fprintf(STDERR, "Failed to set volume. Code = %d\n", code);
1603 CreateVolume(register struct cmd_syndesc *as)
1607 afs_int32 volid, code;
1608 struct nvldbentry entry;
1613 tserver = GetServer(as->parms[0].items->data);
1615 fprintf(STDERR, "vos: host '%s' not found in host table\n",
1616 as->parms[0].items->data);
1619 pname = volutil_GetPartitionID(as->parms[1].items->data);
1621 fprintf(STDERR, "vos: could not interpret partition name '%s'\n",
1622 as->parms[1].items->data);
1625 if (!IsPartValid(pname, tserver, &code)) { /*check for validity of the partition */
1627 PrintError("", code);
1630 "vos : partition %s does not exist on the server\n",
1631 as->parms[1].items->data);
1634 if (!ISNAMEVALID(as->parms[2].items->data)) {
1636 "vos: the name of the root volume %s exceeds the size limit of %d\n",
1637 as->parms[2].items->data, VOLSER_OLDMAXVOLNAME - 10);
1640 if (!VolNameOK(as->parms[2].items->data)) {
1642 "Illegal volume name %s, should not end in .readonly or .backup\n",
1643 as->parms[2].items->data);
1646 if (IsNumeric(as->parms[2].items->data)) {
1647 fprintf(STDERR, "Illegal volume name %s, should not be a number\n",
1648 as->parms[2].items->data);
1651 vcode = VLDB_GetEntryByName(as->parms[2].items->data, &entry);
1653 fprintf(STDERR, "Volume %s already exists\n",
1654 as->parms[2].items->data);
1655 PrintDiagnostics("create", code);
1659 if (as->parms[3].items) {
1660 if (!IsNumeric(as->parms[3].items->data)) {
1661 fprintf(STDERR, "Initial quota %s should be numeric.\n",
1662 as->parms[3].items->data);
1666 code = util_GetInt32(as->parms[3].items->data, "a);
1668 fprintf(STDERR, "vos: bad integer specified for quota.\n");
1674 UV_CreateVolume2(tserver, pname, as->parms[2].items->data, quota, 0,
1677 PrintDiagnostics("create", code);
1680 MapPartIdIntoName(pname, part);
1681 fprintf(STDOUT, "Volume %lu created on partition %s of %s\n",
1682 (unsigned long)volid, part, as->parms[0].items->data);
1689 struct nvldbentry *entry;
1692 afs_int32 error, code, curserver, curpart, volid;
1694 MapHostToNetwork(entry);
1696 for (i = 0; i < entry->nServers; i++) {
1697 curserver = entry->serverNumber[i];
1698 curpart = entry->serverPartition[i];
1699 if (entry->serverFlags[i] & ITSROVOL) {
1700 volid = entry->volumeId[ROVOL];
1702 volid = entry->volumeId[RWVOL];
1704 code = UV_DeleteVolume(curserver, curpart, volid);
1713 struct cmd_syndesc *as;
1715 afs_int32 err, code = 0;
1716 afs_int32 server = 0, partition = -1, volid;
1720 if (as->parms[0].items) {
1721 server = GetServer(as->parms[0].items->data);
1723 fprintf(STDERR, "vos: server '%s' not found in host table\n",
1724 as->parms[0].items->data);
1729 if (as->parms[1].items) {
1730 partition = volutil_GetPartitionID(as->parms[1].items->data);
1731 if (partition < 0) {
1732 fprintf(STDERR, "vos: could not interpret partition name '%s'\n",
1733 as->parms[1].items->data);
1737 /* Check for validity of the partition */
1738 if (!IsPartValid(partition, server, &code)) {
1740 PrintError("", code);
1743 "vos : partition %s does not exist on the server\n",
1744 as->parms[1].items->data);
1750 volid = vsu_GetVolumeID(as->parms[2].items->data, cstruct, &err);
1752 fprintf(STDERR, "Can't find volume name '%s' in VLDB\n",
1753 as->parms[2].items->data);
1755 PrintError("", err);
1759 /* If the server or partition option are not complete, try to fill
1760 * them in from the VLDB entry.
1762 if ((partition == -1) || !server) {
1763 struct nvldbentry entry;
1765 code = VLDB_GetEntryByID(volid, -1, &entry);
1768 "Could not fetch the entry for volume %lu from VLDB\n",
1769 (unsigned long)volid);
1770 PrintError("", code);
1774 if (((volid == entry.volumeId[RWVOL]) && (entry.flags & RW_EXISTS))
1775 || ((volid == entry.volumeId[BACKVOL])
1776 && (entry.flags & BACK_EXISTS))) {
1777 idx = Lp_GetRwIndex(&entry);
1778 if ((idx == -1) || (server && (server != entry.serverNumber[idx]))
1779 || ((partition != -1)
1780 && (partition != entry.serverPartition[idx]))) {
1781 fprintf(STDERR, "VLDB: Volume '%s' no match\n",
1782 as->parms[2].items->data);
1785 } else if ((volid == entry.volumeId[ROVOL])
1786 && (entry.flags & RO_EXISTS)) {
1787 for (idx = -1, j = 0; j < entry.nServers; j++) {
1788 if (entry.serverFlags[j] != ITSROVOL)
1791 if (((server == 0) || (server == entry.serverNumber[j]))
1792 && ((partition == -1)
1793 || (partition == entry.serverPartition[j]))) {
1796 "VLDB: Volume '%s' matches more than one RO\n",
1797 as->parms[2].items->data);
1804 fprintf(STDERR, "VLDB: Volume '%s' no match\n",
1805 as->parms[2].items->data);
1809 fprintf(STDERR, "VLDB: Volume '%s' no match\n",
1810 as->parms[2].items->data);
1814 server = htonl(entry.serverNumber[idx]);
1815 partition = entry.serverPartition[idx];
1819 code = UV_DeleteVolume(server, partition, volid);
1821 PrintDiagnostics("remove", code);
1825 MapPartIdIntoName(partition, pname);
1826 fprintf(STDOUT, "Volume %lu on partition %s server %s deleted\n",
1827 (unsigned long)volid, pname, hostutil_GetNameByINet(server));
1831 #define TESTM 0 /* set for move space tests, clear for production */
1834 register struct cmd_syndesc *as;
1837 afs_int32 volid, fromserver, toserver, frompart, topart, code, err;
1838 char fromPartName[10], toPartName[10];
1840 struct diskPartition partition; /* for space check */
1843 volid = vsu_GetVolumeID(as->parms[0].items->data, cstruct, &err);
1846 PrintError("", err);
1848 fprintf(STDERR, "vos: can't find volume ID or name '%s'\n",
1849 as->parms[0].items->data);
1852 fromserver = GetServer(as->parms[1].items->data);
1853 if (fromserver == 0) {
1854 fprintf(STDERR, "vos: server '%s' not found in host table\n",
1855 as->parms[1].items->data);
1858 toserver = GetServer(as->parms[3].items->data);
1859 if (toserver == 0) {
1860 fprintf(STDERR, "vos: server '%s' not found in host table\n",
1861 as->parms[3].items->data);
1864 frompart = volutil_GetPartitionID(as->parms[2].items->data);
1866 fprintf(STDERR, "vos: could not interpret partition name '%s'\n",
1867 as->parms[2].items->data);
1870 if (!IsPartValid(frompart, fromserver, &code)) { /*check for validity of the partition */
1872 PrintError("", code);
1875 "vos : partition %s does not exist on the server\n",
1876 as->parms[2].items->data);
1879 topart = volutil_GetPartitionID(as->parms[4].items->data);
1881 fprintf(STDERR, "vos: could not interpret partition name '%s'\n",
1882 as->parms[4].items->data);
1885 if (!IsPartValid(topart, toserver, &code)) { /*check for validity of the partition */
1887 PrintError("", code);
1890 "vos : partition %s does not exist on the server\n",
1891 as->parms[4].items->data);
1896 * check source partition for space to clone volume
1899 MapPartIdIntoName(topart, toPartName);
1900 MapPartIdIntoName(frompart, fromPartName);
1903 * check target partition for space to move volume
1906 code = UV_PartitionInfo(toserver, toPartName, &partition);
1908 fprintf(STDERR, "vos: cannot access partition %s\n", toPartName);
1912 fprintf(STDOUT, "target partition %s free space %d\n", toPartName,
1915 p = (volintInfo *) 0;
1916 code = UV_ListOneVolume(fromserver, frompart, volid, &p);
1918 fprintf(STDERR, "vos:cannot access volume %lu\n",
1919 (unsigned long)volid);
1924 fprintf(STDOUT, "volume %lu size %d\n", (unsigned long)volid,
1926 if (partition.free <= p->size) {
1928 "vos: no space on target partition %s to move volume %lu\n",
1929 toPartName, (unsigned long)volid);
1936 fprintf(STDOUT, "size test - don't do move\n");
1940 /* successful move still not guaranteed but shoot for it */
1942 code = UV_MoveVolume(volid, fromserver, frompart, toserver, topart);
1944 PrintDiagnostics("move", code);
1947 MapPartIdIntoName(topart, toPartName);
1948 MapPartIdIntoName(frompart, fromPartName);
1949 fprintf(STDOUT, "Volume %lu moved from %s %s to %s %s \n",
1950 (unsigned long)volid, as->parms[1].items->data, fromPartName,
1951 as->parms[3].items->data, toPartName);
1958 register struct cmd_syndesc *as;
1960 afs_int32 volid, fromserver, toserver, frompart, topart, code, err;
1961 char fromPartName[10], toPartName[10], *tovolume;
1962 struct nvldbentry entry;
1963 struct diskPartition partition; /* for space check */
1966 volid = vsu_GetVolumeID(as->parms[0].items->data, cstruct, &err);
1969 PrintError("", err);
1971 fprintf(STDERR, "vos: can't find volume ID or name '%s'\n",
1972 as->parms[0].items->data);
1975 fromserver = GetServer(as->parms[1].items->data);
1976 if (fromserver == 0) {
1977 fprintf(STDERR, "vos: server '%s' not found in host table\n",
1978 as->parms[1].items->data);
1982 toserver = GetServer(as->parms[4].items->data);
1983 if (toserver == 0) {
1984 fprintf(STDERR, "vos: server '%s' not found in host table\n",
1985 as->parms[3].items->data);
1989 tovolume = as->parms[3].items->data;
1990 if (!ISNAMEVALID(tovolume)) {
1992 "vos: the name of the root volume %s exceeds the size limit of %d\n",
1993 tovolume, VOLSER_OLDMAXVOLNAME - 10);
1996 if (!VolNameOK(tovolume)) {
1998 "Illegal volume name %s, should not end in .readonly or .backup\n",
2002 if (IsNumeric(tovolume)) {
2003 fprintf(STDERR, "Illegal volume name %s, should not be a number\n",
2007 code = VLDB_GetEntryByName(tovolume, &entry);
2009 fprintf(STDERR, "Volume %s already exists\n", tovolume);
2010 PrintDiagnostics("copy", code);
2014 frompart = volutil_GetPartitionID(as->parms[2].items->data);
2016 fprintf(STDERR, "vos: could not interpret partition name '%s'\n",
2017 as->parms[2].items->data);
2020 if (!IsPartValid(frompart, fromserver, &code)) { /*check for validity of the partition */
2022 PrintError("", code);
2025 "vos : partition %s does not exist on the server\n",
2026 as->parms[2].items->data);
2030 topart = volutil_GetPartitionID(as->parms[5].items->data);
2032 fprintf(STDERR, "vos: could not interpret partition name '%s'\n",
2033 as->parms[4].items->data);
2036 if (!IsPartValid(topart, toserver, &code)) { /*check for validity of the partition */
2038 PrintError("", code);
2041 "vos : partition %s does not exist on the server\n",
2042 as->parms[4].items->data);
2047 * check source partition for space to clone volume
2050 MapPartIdIntoName(topart, toPartName);
2051 MapPartIdIntoName(frompart, fromPartName);
2054 * check target partition for space to move volume
2057 code = UV_PartitionInfo(toserver, toPartName, &partition);
2059 fprintf(STDERR, "vos: cannot access partition %s\n", toPartName);
2063 fprintf(STDOUT, "target partition %s free space %d\n", toPartName,
2066 p = (volintInfo *) 0;
2067 code = UV_ListOneVolume(fromserver, frompart, volid, &p);
2069 fprintf(STDERR, "vos:cannot access volume %lu\n",
2070 (unsigned long)volid);
2075 if (partition.free <= p->size) {
2077 "vos: no space on target partition %s to copy volume %lu\n",
2078 toPartName, (unsigned long)volid);
2084 /* successful copy still not guaranteed but shoot for it */
2087 UV_CopyVolume(volid, fromserver, frompart, tovolume, toserver,
2090 PrintDiagnostics("copy", code);
2093 MapPartIdIntoName(topart, toPartName);
2094 MapPartIdIntoName(frompart, fromPartName);
2095 fprintf(STDOUT, "Volume %lu copied from %s %s to %s on %s %s \n",
2096 (unsigned long)volid, as->parms[1].items->data, fromPartName,
2097 tovolume, as->parms[4].items->data, toPartName);
2105 register struct cmd_syndesc *as;
2107 afs_int32 avolid, aserver, apart, vtype, code, err;
2108 struct nvldbentry entry;
2110 afs_int32 buvolid, buserver, bupart, butype;
2111 struct nvldbentry buentry;
2112 struct rx_connection *conn;
2114 struct nvldbentry store;
2116 avolid = vsu_GetVolumeID(as->parms[0].items->data, cstruct, &err);
2119 PrintError("", err);
2121 fprintf(STDERR, "vos: can't find volume ID or name '%s'\n",
2122 as->parms[0].items->data);
2125 code = GetVolumeInfo(avolid, &aserver, &apart, &vtype, &entry);
2129 /* verify this is a readwrite volume */
2131 if (vtype != RWVOL) {
2132 fprintf(STDERR, "%s not RW volume\n", as->parms[0].items->data);
2136 /* is there a backup volume already? */
2138 if (entry.flags & BACK_EXISTS) {
2139 /* yep, where is it? */
2141 buvolid = entry.volumeId[BACKVOL];
2142 code = GetVolumeInfo(buvolid, &buserver, &bupart, &butype, &buentry);
2147 code = VLDB_IsSameAddrs(buserver, aserver, &err);
2150 "Failed to get info about server's %d address(es) from vlserver; aborting call!\n",
2156 "FATAL ERROR: backup volume %lu exists on server %lu\n",
2157 (unsigned long)buvolid, (unsigned long)buserver);
2162 /* nope, carry on */
2164 code = UV_BackupVolume(aserver, apart, avolid);
2167 PrintDiagnostics("backup", code);
2170 fprintf(STDOUT, "Created backup volume for %s \n",
2171 as->parms[0].items->data);
2177 register struct cmd_syndesc *as;
2180 struct nvldbentry entry;
2181 afs_int32 avolid, aserver, apart, vtype, code, err;
2184 if (as->parms[1].items)
2186 avolid = vsu_GetVolumeID(as->parms[0].items->data, cstruct, &err);
2189 PrintError("", err);
2191 fprintf(STDERR, "vos: can't find volume '%s'\n",
2192 as->parms[0].items->data);
2195 code = GetVolumeInfo(avolid, &aserver, &apart, &vtype, &entry);
2199 if (vtype != RWVOL) {
2200 fprintf(STDERR, "%s not a RW volume\n", as->parms[0].items->data);
2204 if (!ISNAMEVALID(entry.name)) {
2206 "Volume name %s is too long, rename before releasing\n",
2211 code = UV_ReleaseVolume(avolid, aserver, apart, force);
2213 PrintDiagnostics("release", code);
2216 fprintf(STDOUT, "Released volume %s successfully\n",
2217 as->parms[0].items->data);
2223 register struct cmd_syndesc *as;
2226 afs_int32 avolid, aserver, apart, voltype, fromdate = 0, code, err, i;
2227 char filename[NameLen];
2228 struct nvldbentry entry;
2230 rx_SetRxDeadTime(60 * 10);
2231 for (i = 0; i < MAXSERVERS; i++) {
2232 struct rx_connection *rxConn = ubik_GetRPCConn(cstruct, i);
2235 rx_SetConnDeadTime(rxConn, rx_connDeadTime);
2236 if (rxConn->service)
2237 rxConn->service->connDeadTime = rx_connDeadTime;
2240 avolid = vsu_GetVolumeID(as->parms[0].items->data, cstruct, &err);
2243 PrintError("", err);
2245 fprintf(STDERR, "vos: can't find volume '%s'\n",
2246 as->parms[0].items->data);
2250 if (as->parms[3].items || as->parms[4].items) {
2251 if (!as->parms[3].items || !as->parms[4].items) {
2253 "Must specify both -server and -partition options\n");
2256 aserver = GetServer(as->parms[3].items->data);
2258 fprintf(STDERR, "Invalid server name\n");
2261 apart = volutil_GetPartitionID(as->parms[4].items->data);
2263 fprintf(STDERR, "Invalid partition name\n");
2267 code = GetVolumeInfo(avolid, &aserver, &apart, &voltype, &entry);
2272 if (as->parms[1].items && strcmp(as->parms[1].items->data, "0")) {
2273 code = ktime_DateToInt32(as->parms[1].items->data, &fromdate);
2275 fprintf(STDERR, "vos: failed to parse date '%s' (error=%d))\n",
2276 as->parms[1].items->data, code);
2280 if (as->parms[2].items) {
2281 strcpy(filename, as->parms[2].items->data);
2283 strcpy(filename, "");
2286 if (as->parms[5].items) {
2288 UV_DumpClonedVolume(avolid, aserver, apart, fromdate,
2289 DumpFunction, filename);
2292 UV_DumpVolume(avolid, aserver, apart, fromdate, DumpFunction,
2296 PrintDiagnostics("dump", code);
2299 if (strcmp(filename, ""))
2300 fprintf(STDERR, "Dumped volume %s in file %s\n",
2301 as->parms[0].items->data, filename);
2303 fprintf(STDERR, "Dumped volume %s in stdout \n",
2304 as->parms[0].items->data);
2315 register struct cmd_syndesc *as;
2318 afs_int32 avolid, aserver, apart, code, vcode, err;
2319 afs_int32 aoverwrite = ASK;
2320 int restoreflags, readonly = 0, offline = 0, voltype = RWVOL;
2322 char afilename[NameLen], avolname[VOLSER_MAXVOLNAME + 1], apartName[10];
2323 char volname[VOLSER_MAXVOLNAME + 1];
2324 struct nvldbentry entry;
2328 if (as->parms[4].items) {
2329 avolid = vsu_GetVolumeID(as->parms[4].items->data, cstruct, &err);
2332 PrintError("", err);
2334 fprintf(STDERR, "vos: can't find volume '%s'\n",
2335 as->parms[4].items->data);
2341 if (as->parms[5].items) {
2342 if ((strcmp(as->parms[5].items->data, "a") == 0)
2343 || (strcmp(as->parms[5].items->data, "abort") == 0)) {
2345 } else if ((strcmp(as->parms[5].items->data, "f") == 0)
2346 || (strcmp(as->parms[5].items->data, "full") == 0)) {
2348 } else if ((strcmp(as->parms[5].items->data, "i") == 0)
2349 || (strcmp(as->parms[5].items->data, "inc") == 0)
2350 || (strcmp(as->parms[5].items->data, "increment") == 0)
2351 || (strcmp(as->parms[5].items->data, "incremental") == 0)) {
2354 fprintf(STDERR, "vos: %s is not a valid argument to -overwrite\n",
2355 as->parms[5].items->data);
2359 if (as->parms[6].items)
2361 if (as->parms[7].items) {
2366 aserver = GetServer(as->parms[0].items->data);
2368 fprintf(STDERR, "vos: server '%s' not found in host table\n",
2369 as->parms[0].items->data);
2372 apart = volutil_GetPartitionID(as->parms[1].items->data);
2374 fprintf(STDERR, "vos: could not interpret partition name '%s'\n",
2375 as->parms[1].items->data);
2378 if (!IsPartValid(apart, aserver, &code)) { /*check for validity of the partition */
2380 PrintError("", code);
2383 "vos : partition %s does not exist on the server\n",
2384 as->parms[1].items->data);
2387 strcpy(avolname, as->parms[2].items->data);
2388 if (!ISNAMEVALID(avolname)) {
2390 "vos: the name of the volume %s exceeds the size limit\n",
2394 if (!VolNameOK(avolname)) {
2396 "Illegal volume name %s, should not end in .readonly or .backup\n",
2400 if (as->parms[3].items) {
2401 strcpy(afilename, as->parms[3].items->data);
2402 if (!FileExists(afilename)) {
2403 fprintf(STDERR, "Can't access file %s\n", afilename);
2407 strcpy(afilename, "");
2410 /* Check if volume exists or not */
2412 vsu_ExtractName(volname, avolname);
2413 vcode = VLDB_GetEntryByName(volname, &entry);
2414 if (vcode) { /* no volume - do a full restore */
2415 restoreflags = RV_FULLRST;
2416 if ((aoverwrite == INC) || (aoverwrite == ABORT))
2418 "Volume does not exist; Will perform a full restore\n");
2421 else if ((!readonly && Lp_GetRwIndex(&entry) == -1) /* RW volume does not exist - do a full */
2422 ||(readonly && !Lp_ROMatch(0, 0, &entry))) { /* RO volume does not exist - do a full */
2423 restoreflags = RV_FULLRST;
2424 if ((aoverwrite == INC) || (aoverwrite == ABORT))
2426 "%s Volume does not exist; Will perform a full restore\n",
2427 readonly ? "RO" : "RW");
2430 avolid = entry.volumeId[voltype];
2431 } else if (entry.volumeId[voltype] != 0
2432 && entry.volumeId[voltype] != avolid) {
2433 avolid = entry.volumeId[voltype];
2437 else { /* volume exists - do we do a full incremental or abort */
2438 int Oserver, Opart, Otype, vol_elsewhere = 0;
2439 struct nvldbentry Oentry;
2443 avolid = entry.volumeId[voltype];
2444 } else if (entry.volumeId[voltype] != 0
2445 && entry.volumeId[voltype] != avolid) {
2446 avolid = entry.volumeId[voltype];
2449 /* A file name was specified - check if volume is on another partition */
2450 vcode = GetVolumeInfo(avolid, &Oserver, &Opart, &Otype, &Oentry);
2454 vcode = VLDB_IsSameAddrs(Oserver, aserver, &err);
2457 "Failed to get info about server's %d address(es) from vlserver (err=%d); aborting call!\n",
2461 if (!vcode || (Opart != apart))
2464 if (aoverwrite == ASK) {
2465 if (strcmp(afilename, "") == 0) { /* The file is from standard in */
2467 "Volume exists and no -overwrite option specified; Aborting restore command\n");
2471 /* Ask what to do */
2472 if (vol_elsewhere) {
2474 "The volume %s %u already exists on a different server/part\n",
2475 volname, entry.volumeId[voltype]);
2477 "Do you want to do a full restore or abort? [fa](a): ");
2480 "The volume %s %u already exists in the VLDB\n",
2481 volname, entry.volumeId[voltype]);
2483 "Do you want to do a full/incremental restore or abort? [fia](a): ");
2486 while (!(dc == EOF || dc == '\n'))
2487 dc = getchar(); /* goto end of line */
2488 if ((c == 'f') || (c == 'F'))
2490 else if ((c == 'i') || (c == 'I'))
2496 if (aoverwrite == ABORT) {
2497 fprintf(STDERR, "Volume exists; Aborting restore command\n");
2499 } else if (aoverwrite == FULL) {
2500 restoreflags = RV_FULLRST;
2502 "Volume exists; Will delete and perform full restore\n");
2503 } else if (aoverwrite == INC) {
2505 if (vol_elsewhere) {
2507 "%s volume %lu already exists on a different server/part; not allowed\n",
2508 readonly ? "RO" : "RW", (unsigned long)avolid);
2514 restoreflags |= RV_OFFLINE;
2516 restoreflags |= RV_RDONLY;
2518 UV_RestoreVolume(aserver, apart, avolid, avolname, restoreflags,
2519 WriteData, afilename);
2521 PrintDiagnostics("restore", code);
2524 MapPartIdIntoName(apart, apartName);
2527 * patch typo here - originally "parms[1]", should be "parms[0]"
2530 fprintf(STDOUT, "Restored volume %s on %s %s\n", avolname,
2531 as->parms[0].items->data, apartName);
2537 register struct cmd_syndesc *as;
2540 afs_int32 avolid, code, err;
2542 avolid = vsu_GetVolumeID(as->parms[0].items->data, cstruct, &err);
2545 PrintError("", err);
2547 fprintf(STDERR, "vos: can't find volume '%s'\n",
2548 as->parms[0].items->data);
2552 code = UV_LockRelease(avolid);
2554 PrintDiagnostics("unlock", code);
2557 fprintf(STDOUT, "Released lock on vldb entry for volume %s\n",
2558 as->parms[0].items->data);
2564 register struct cmd_syndesc *as;
2566 afs_int32 avolid, aserver, apart, code, err;
2567 char apartName[10], avolname[VOLSER_MAXVOLNAME + 1];
2569 vsu_ExtractName(avolname, as->parms[2].items->data);;
2570 avolid = vsu_GetVolumeID(avolname, cstruct, &err);
2573 PrintError("", err);
2575 fprintf(STDERR, "vos: can't find volume '%s'\n",
2576 as->parms[2].items->data);
2579 aserver = GetServer(as->parms[0].items->data);
2581 fprintf(STDERR, "vos: server '%s' not found in host table\n",
2582 as->parms[0].items->data);
2585 apart = volutil_GetPartitionID(as->parms[1].items->data);
2587 fprintf(STDERR, "vos: could not interpret partition name '%s'\n",
2588 as->parms[1].items->data);
2591 if (!IsPartValid(apart, aserver, &code)) { /*check for validity of the partition */
2593 PrintError("", code);
2596 "vos : partition %s does not exist on the server\n",
2597 as->parms[1].items->data);
2600 code = UV_AddSite(aserver, apart, avolid);
2602 PrintDiagnostics("addsite", code);
2605 MapPartIdIntoName(apart, apartName);
2606 fprintf(STDOUT, "Added replication site %s %s for volume %s\n",
2607 as->parms[0].items->data, apartName, as->parms[2].items->data);
2613 register struct cmd_syndesc *as;
2616 afs_int32 avolid, aserver, apart, code, err;
2617 char apartName[10], avolname[VOLSER_MAXVOLNAME + 1];
2619 vsu_ExtractName(avolname, as->parms[2].items->data);
2620 avolid = vsu_GetVolumeID(avolname, cstruct, &err);
2623 PrintError("", err);
2625 fprintf(STDERR, "vos: can't find volume '%s'\n",
2626 as->parms[2].items->data);
2629 aserver = GetServer(as->parms[0].items->data);
2631 fprintf(STDERR, "vos: server '%s' not found in host table\n",
2632 as->parms[0].items->data);
2635 apart = volutil_GetPartitionID(as->parms[1].items->data);
2637 fprintf(STDERR, "vos: could not interpret partition name '%s'\n",
2638 as->parms[1].items->data);
2642 *skip the partition validity check, since it is possible that the partition
2643 *has since been decomissioned.
2646 if (!IsPartValid(apart,aserver,&code)){
2647 if(code) PrintError("",code);
2648 else fprintf(STDERR,"vos : partition %s does not exist on the server\n",as->parms[1].items->data);
2652 code = UV_RemoveSite(aserver, apart, avolid);
2654 PrintDiagnostics("remsite", code);
2657 MapPartIdIntoName(apart, apartName);
2658 fprintf(STDOUT, "Removed replication site %s %s for volume %s\n",
2659 as->parms[0].items->data, apartName, as->parms[2].items->data);
2665 register struct cmd_syndesc *as;
2667 afs_int32 avolid, aserver, apart, code, err;
2670 avolid = vsu_GetVolumeID(as->parms[2].items->data, cstruct, &err);
2673 PrintError("", err);
2675 fprintf(STDERR, "vos: can't find volume '%s'\n",
2676 as->parms[2].items->data);
2679 aserver = GetServer(as->parms[0].items->data);
2681 fprintf(STDERR, "vos: server '%s' not found in host table\n",
2682 as->parms[0].items->data);
2685 apart = volutil_GetPartitionID(as->parms[1].items->data);
2687 fprintf(STDERR, "vos: could not interpret partition name '%s'\n",
2688 as->parms[1].items->data);
2691 if (!IsPartValid(apart, aserver, &code)) { /*check for validity of the partition */
2693 PrintError("", code);
2696 "vos : partition %s does not exist on the server\n",
2697 as->parms[1].items->data);
2700 code = UV_ChangeLocation(aserver, apart, avolid);
2702 PrintDiagnostics("addsite", code);
2705 MapPartIdIntoName(apart, apartName);
2706 fprintf(STDOUT, "Changed location to %s %s for volume %s\n",
2707 as->parms[0].items->data, apartName, as->parms[2].items->data);
2713 register struct cmd_syndesc *as;
2715 afs_int32 aserver, code;
2716 struct partList dummyPartList;
2721 aserver = GetServer(as->parms[0].items->data);
2723 fprintf(STDERR, "vos: server '%s' not found in host table\n",
2724 as->parms[0].items->data);
2729 code = UV_ListPartitions(aserver, &dummyPartList, &cnt);
2731 PrintDiagnostics("listpart", code);
2735 fprintf(STDOUT, "The partitions on the server are:\n");
2736 for (i = 0; i < cnt; i++) {
2737 if (dummyPartList.partFlags[i] & PARTVALID) {
2738 memset(pname, 0, sizeof(pname));
2739 MapPartIdIntoName(dummyPartList.partId[i], pname);
2740 fprintf(STDOUT, " %10s ", pname);
2742 if ((i % 5) == 0 && (i != 0))
2743 fprintf(STDOUT, "\n");
2746 fprintf(STDOUT, "\n");
2747 fprintf(STDOUT, "Total: %d\n", total);
2753 CompareVolName(p1, p2)
2756 volintInfo *arg1, *arg2;
2758 arg1 = (volintInfo *) p1;
2759 arg2 = (volintInfo *) p2;
2760 return (strcmp(arg1->name, arg2->name));
2764 /*------------------------------------------------------------------------
2765 * PRIVATE XCompareVolName
2768 * Comparison routine for volume names coming from an extended
2772 * a_obj1P : Char ptr to first extended vol info object
2773 * a_obj1P : Char ptr to second extended vol info object
2776 * The value of strcmp() on the volume names within the passed
2777 * objects (i,e., -1, 0, or 1).
2780 * Passed to qsort() as the designated comparison routine.
2784 *------------------------------------------------------------------------*/
2787 XCompareVolName(a_obj1P, a_obj2P)
2788 char *a_obj1P, *a_obj2P;
2790 { /*XCompareVolName */
2793 (((struct volintXInfo *)(a_obj1P))->name,
2794 ((struct volintXInfo *)(a_obj2P))->name));
2796 } /*XCompareVolName */
2799 CompareVolID(p1, p2)
2802 volintInfo *arg1, *arg2;
2804 arg1 = (volintInfo *) p1;
2805 arg2 = (volintInfo *) p2;
2806 if (arg1->volid == arg2->volid)
2808 if (arg1->volid > arg2->volid)
2815 /*------------------------------------------------------------------------
2816 * PRIVATE XCompareVolID
2819 * Comparison routine for volume IDs coming from an extended
2823 * a_obj1P : Char ptr to first extended vol info object
2824 * a_obj1P : Char ptr to second extended vol info object
2827 * The value of strcmp() on the volume names within the passed
2828 * objects (i,e., -1, 0, or 1).
2831 * Passed to qsort() as the designated comparison routine.
2835 *------------------------------------------------------------------------*/
2838 XCompareVolID(a_obj1P, a_obj2P)
2839 char *a_obj1P, *a_obj2P;
2841 { /*XCompareVolID */
2843 afs_int32 id1, id2; /*Volume IDs we're comparing */
2845 id1 = ((struct volintXInfo *)(a_obj1P))->volid;
2846 id2 = ((struct volintXInfo *)(a_obj2P))->volid;
2854 } /*XCompareVolID */
2856 /*------------------------------------------------------------------------
2857 * PRIVATE ListVolumes
2860 * Routine used to list volumes, contacting the Volume Server
2861 * directly, bypassing the VLDB.
2864 * as : Ptr to parsed command line arguments.
2867 * 0 Successful operation
2870 * Nothing interesting.
2874 *------------------------------------------------------------------------*/
2878 register struct cmd_syndesc *as;
2880 afs_int32 apart, int32list, fast;
2881 afs_int32 aserver, code;
2882 volintInfo *pntr, *oldpntr;
2886 volintXInfo *xInfoP, *origxInfoP; /*Ptr to current/orig extended vol info */
2887 int wantExtendedInfo; /*Do we want extended vol info? */
2890 struct partList dummyPartList;
2898 if (as->parms[3].items)
2900 if (as->parms[4].items)
2904 if (as->parms[2].items)
2910 if (as->parms[5].items) {
2912 * We can't coexist with the fast flag.
2916 "vos: Can't use the -fast and -extended flags together\n");
2921 * We need to turn on ``long'' listings to get the full effect.
2923 wantExtendedInfo = 1;
2926 wantExtendedInfo = 0;
2927 if (as->parms[1].items) {
2928 apart = volutil_GetPartitionID(as->parms[1].items->data);
2930 fprintf(STDERR, "vos: could not interpret partition name '%s'\n",
2931 as->parms[1].items->data);
2934 dummyPartList.partId[0] = apart;
2935 dummyPartList.partFlags[0] = PARTVALID;
2938 aserver = GetServer(as->parms[0].items->data);
2940 fprintf(STDERR, "vos: server '%s' not found in host table\n",
2941 as->parms[0].items->data);
2946 if (!IsPartValid(apart, aserver, &code)) { /*check for validity of the partition */
2948 PrintError("", code);
2951 "vos : partition %s does not exist on the server\n",
2952 as->parms[1].items->data);
2956 code = UV_ListPartitions(aserver, &dummyPartList, &cnt);
2958 PrintDiagnostics("listvol", code);
2962 for (i = 0; i < cnt; i++) {
2963 if (dummyPartList.partFlags[i] & PARTVALID) {
2964 if (wantExtendedInfo)
2966 UV_XListVolumes(aserver, dummyPartList.partId[i], all,
2970 UV_ListVolumes(aserver, dummyPartList.partId[i], all,
2973 PrintDiagnostics("listvol", code);
2978 if (wantExtendedInfo) {
2979 origxInfoP = xInfoP;
2980 base = (char *)xInfoP;
2983 base = (char *)pntr;
2987 if (wantExtendedInfo)
2988 qsort(base, count, sizeof(volintXInfo), XCompareVolName);
2990 qsort(base, count, sizeof(volintInfo), CompareVolName);
2992 if (wantExtendedInfo)
2993 qsort(base, count, sizeof(volintXInfo), XCompareVolID);
2995 qsort(base, count, sizeof(volintInfo), CompareVolID);
2997 MapPartIdIntoName(dummyPartList.partId[i], pname);
3000 "Total number of volumes on server %s partition %s: %lu \n",
3001 as->parms[0].items->data, pname,
3002 (unsigned long)count);
3003 if (wantExtendedInfo) {
3004 XDisplayVolumes(aserver, dummyPartList.partId[i], origxInfoP,
3005 count, int32list, fast, quiet);
3008 xInfoP = (volintXInfo *) 0;
3010 #ifdef FULL_LISTVOL_SWITCH
3011 if (as->parms[6].items)
3012 DisplayVolumes2(aserver, dummyPartList.partId[i], oldpntr,
3015 #endif /* FULL_LISTVOL_SWITCH */
3016 DisplayVolumes(aserver, dummyPartList.partId[i], oldpntr,
3017 count, int32list, fast, quiet);
3020 pntr = (volintInfo *) 0;
3029 register struct cmd_syndesc *as;
3031 afs_int32 pname, code; /* part name */
3037 if (as->parms[0].items) {
3038 tserver = GetServer(as->parms[0].items->data);
3040 fprintf(STDERR, "vos: host '%s' not found in host table\n",
3041 as->parms[0].items->data);
3046 if (as->parms[1].items) {
3047 pname = volutil_GetPartitionID(as->parms[1].items->data);
3049 fprintf(STDERR, "vos: could not interpret partition name '%s'\n",
3050 as->parms[1].items->data);
3053 if (!IsPartValid(pname, tserver, &code)) { /*check for validity of the partition */
3055 PrintError("", code);
3058 "vos: partition %s does not exist on the server\n",
3059 as->parms[1].items->data);
3066 "The -partition option requires a -server option\n");
3071 if (as->parms[2].items) {
3072 /* Synchronize an individual volume */
3073 volname = as->parms[2].items->data;
3074 code = UV_SyncVolume(tserver, pname, volname, flags);
3078 "Without a -volume option, the -server option is required\n");
3081 code = UV_SyncVldb(tserver, pname, flags, 0 /*unused */ );
3085 PrintDiagnostics("syncvldb", code);
3089 /* Print a summary of what we did */
3091 fprintf(STDOUT, "VLDB volume %s synchronized", volname);
3093 fprintf(STDOUT, "VLDB synchronized");
3095 fprintf(STDOUT, " with state of server %s", as->parms[0].items->data);
3098 MapPartIdIntoName(pname, part);
3099 fprintf(STDOUT, " partition %s\n", part);
3101 fprintf(STDOUT, "\n");
3108 register struct cmd_syndesc *as;
3111 afs_int32 pname, code; /* part name */
3116 tserver = GetServer(as->parms[0].items->data);
3118 fprintf(STDERR, "vos: host '%s' not found in host table\n",
3119 as->parms[0].items->data);
3122 if (as->parms[1].items) {
3123 pname = volutil_GetPartitionID(as->parms[1].items->data);
3125 fprintf(STDERR, "vos: could not interpret partition name '%s'\n",
3126 as->parms[1].items->data);
3129 if (!IsPartValid(pname, tserver, &code)) { /*check for validity of the partition */
3131 PrintError("", code);
3134 "vos : partition %s does not exist on the server\n",
3135 as->parms[1].items->data);
3141 code = UV_SyncServer(tserver, pname, flags, 0 /*unused */ );
3143 PrintDiagnostics("syncserv", code);
3147 MapPartIdIntoName(pname, part);
3148 fprintf(STDOUT, "Server %s partition %s synchronized with VLDB\n",
3149 as->parms[0].items->data, part);
3151 fprintf(STDOUT, "Server %s synchronized with VLDB\n",
3152 as->parms[0].items->data);
3161 struct nvldbentry entry;
3164 /* The vlserver will handle names with the .readonly
3165 * and .backup extension as well as volume ids.
3167 vcode = VLDB_GetEntryByName(name, &entry);
3169 PrintError("", vcode);
3172 MapHostToNetwork(&entry);
3173 EnumerateEntry(&entry);
3175 /* Defect #3027: grubby check to handle locked volume.
3176 * If VLOP_ALLOPERS is set, the entry is locked.
3177 * Leave this routine as is, but put in correct check.
3179 if (entry.flags & VLOP_ALLOPERS)
3180 fprintf(STDOUT, " Volume is currently LOCKED \n");
3187 register struct cmd_syndesc *as;
3190 struct nvldbentry entry;
3191 afs_int32 volid, code, server, part, zapbackupid = 0, backupid = 0, err;
3193 if (as->parms[3].items) {
3194 /* force flag is on, use the other version */
3195 return NukeVolume(as);
3198 if (as->parms[4].items) {
3202 volid = vsu_GetVolumeID(as->parms[2].items->data, cstruct, &err);
3205 PrintError("", err);
3207 fprintf(STDERR, "vos: can't find volume '%s'\n",
3208 as->parms[2].items->data);
3211 part = volutil_GetPartitionID(as->parms[1].items->data);
3213 fprintf(STDERR, "vos: could not interpret partition name '%s'\n",
3214 as->parms[1].items->data);
3217 server = GetServer(as->parms[0].items->data);
3219 fprintf(STDERR, "vos: host '%s' not found in host table\n",
3220 as->parms[0].items->data);
3223 if (!IsPartValid(part, server, &code)) { /*check for validity of the partition */
3225 PrintError("", code);
3228 "vos : partition %s does not exist on the server\n",
3229 as->parms[1].items->data);
3232 code = VLDB_GetEntryByID(volid, -1, &entry);
3234 if (volid == entry.volumeId[RWVOL])
3235 backupid = entry.volumeId[BACKVOL];
3237 "Warning: Entry for volume number %lu exists in VLDB (but we're zapping it anyway!)\n",
3238 (unsigned long)volid);
3241 volintInfo *pntr = (volintInfo *) 0;
3244 code = UV_ListOneVolume(server, part, volid, &pntr);
3246 if (volid == pntr->parentID)
3247 backupid = pntr->backupID;
3253 code = UV_VolumeZap(server, part, backupid);
3255 PrintDiagnostics("zap", code);
3258 fprintf(STDOUT, "Backup Volume %lu deleted\n",
3259 (unsigned long)backupid);
3262 code = UV_VolumeZap(server, part, volid);
3264 PrintDiagnostics("zap", code);
3267 fprintf(STDOUT, "Volume %lu deleted\n", (unsigned long)volid);
3274 register struct cmd_syndesc *as;
3277 afs_int32 server, code;
3278 transDebugInfo *pntr, *oldpntr;
3283 server = GetServer(as->parms[0].items->data);
3285 fprintf(STDERR, "vos: host '%s' not found in host table\n",
3286 as->parms[0].items->data);
3289 code = UV_VolserStatus(server, &pntr, &count);
3291 PrintDiagnostics("status", code);
3296 fprintf(STDOUT, "No active transactions on %s\n",
3297 as->parms[0].items->data);
3299 fprintf(STDOUT, "Total transactions: %d\n", count);
3301 for (i = 0; i < count; i++) {
3302 /*print out the relevant info */
3303 fprintf(STDOUT, "--------------------------------------\n");
3304 fprintf(STDOUT, "transaction: %lu created: %s",
3305 (unsigned long)pntr->tid, ctime((time_t *) & pntr->time));
3306 if (pntr->returnCode) {
3307 fprintf(STDOUT, "returnCode: %lu\n",
3308 (unsigned long)pntr->returnCode);
3311 fprintf(STDOUT, "attachFlags: ");
3312 switch (pntr->iflags) {
3314 fprintf(STDOUT, "offline ");
3317 fprintf(STDOUT, "busy ");
3320 fprintf(STDOUT, "readonly ");
3323 fprintf(STDOUT, "create ");
3326 fprintf(STDOUT, "create volid ");
3329 fprintf(STDOUT, "\n");
3332 fprintf(STDOUT, "volumeStatus: ");
3333 switch (pntr->vflags) {
3334 case VTDeleteOnSalvage:
3335 fprintf(STDOUT, "deleteOnSalvage ");
3336 case VTOutOfService:
3337 fprintf(STDOUT, "outOfService ");
3339 fprintf(STDOUT, "deleted ");
3341 fprintf(STDOUT, "\n");
3344 fprintf(STDOUT, "transactionFlags: ");
3345 fprintf(STDOUT, "delete\n");
3347 MapPartIdIntoName(pntr->partition, pname);
3348 fprintf(STDOUT, "volume: %lu partition: %s procedure: %s\n",
3349 (unsigned long)pntr->volid, pname, pntr->lastProcName);
3350 if (pntr->callValid) {
3352 "packetRead: %lu lastReceiveTime: %d packetSend: %lu lastSendTime: %d\n",
3353 (unsigned long)pntr->readNext, pntr->lastReceiveTime,
3354 (unsigned long)pntr->transmitNext, pntr->lastSendTime);
3357 fprintf(STDOUT, "--------------------------------------\n");
3358 fprintf(STDOUT, "\n");
3367 register struct cmd_syndesc *as;
3369 afs_int32 code1, code2, code;
3370 struct nvldbentry entry;
3372 code1 = VLDB_GetEntryByName(as->parms[0].items->data, &entry);
3374 fprintf(STDERR, "vos: Could not find entry for volume %s\n",
3375 as->parms[0].items->data);
3378 code2 = VLDB_GetEntryByName(as->parms[1].items->data, &entry);
3379 if ((!code1) && (!code2)) { /*the newname already exists */
3380 fprintf(STDERR, "vos: volume %s already exists\n",
3381 as->parms[1].items->data);
3385 if (code1 && code2) {
3386 fprintf(STDERR, "vos: Could not find entry for volume %s or %s\n",
3387 as->parms[0].items->data, as->parms[1].items->data);
3390 if (!VolNameOK(as->parms[0].items->data)) {
3392 "Illegal volume name %s, should not end in .readonly or .backup\n",
3393 as->parms[0].items->data);
3396 if (!ISNAMEVALID(as->parms[1].items->data)) {
3398 "vos: the new volume name %s exceeds the size limit of %d\n",
3399 as->parms[1].items->data, VOLSER_OLDMAXVOLNAME - 10);
3402 if (!VolNameOK(as->parms[1].items->data)) {
3404 "Illegal volume name %s, should not end in .readonly or .backup\n",
3405 as->parms[1].items->data);
3408 if (IsNumeric(as->parms[1].items->data)) {
3409 fprintf(STDERR, "Illegal volume name %s, should not be a number\n",
3410 as->parms[1].items->data);
3413 MapHostToNetwork(&entry);
3415 UV_RenameVolume(&entry, as->parms[0].items->data,
3416 as->parms[1].items->data);
3418 PrintDiagnostics("rename", code);
3421 fprintf(STDOUT, "Renamed volume %s to %s\n", as->parms[0].items->data,
3422 as->parms[1].items->data);
3426 GetVolumeInfo(volid, server, part, voltype, rentry)
3427 afs_int32 *server, volid, *part, *voltype;
3428 register struct nvldbentry *rentry;
3433 vcode = VLDB_GetEntryByID(volid, -1, rentry);
3436 "Could not fetch the entry for volume %lu from VLDB \n",
3437 (unsigned long)volid);
3438 PrintError("", vcode);
3441 MapHostToNetwork(rentry);
3442 if (volid == rentry->volumeId[ROVOL]) {
3444 for (i = 0; i < rentry->nServers; i++) {
3445 if ((index == -1) && (rentry->serverFlags[i] & ITSROVOL)
3446 && !(rentry->serverFlags[i] & RO_DONTUSE))
3451 "RO volume is not found in VLDB entry for volume %lu\n",
3452 (unsigned long)volid);
3456 *server = rentry->serverNumber[index];
3457 *part = rentry->serverPartition[index];
3461 index = Lp_GetRwIndex(rentry);
3464 "RW Volume is not found in VLDB entry for volume %lu\n",
3465 (unsigned long)volid);
3468 if (volid == rentry->volumeId[RWVOL]) {
3470 *server = rentry->serverNumber[index];
3471 *part = rentry->serverPartition[index];
3474 if (volid == rentry->volumeId[BACKVOL]) {
3476 *server = rentry->serverNumber[index];
3477 *part = rentry->serverPartition[index];
3484 register struct cmd_syndesc *as;
3490 struct VldbListByAttributes attributes;
3491 nbulkentries arrayEntries;
3492 register struct nvldbentry *vllist;
3493 struct cmd_item *itp;
3496 char prefix[VOLSER_MAXVOLNAME + 1];
3498 afs_int32 totalBack = 0, totalFail = 0, err;
3500 if (as->parms[0].items) { /* -id */
3501 if (as->parms[1].items || as->parms[2].items || as->parms[3].items) {
3503 "You cannot use -server, -partition, or -prefix with the -id argument\n");
3506 for (itp = as->parms[0].items; itp; itp = itp->next) {
3507 avolid = vsu_GetVolumeID(itp->data, cstruct, &err);
3510 PrintError("", err);
3512 fprintf(STDERR, "vos: can't find volume '%s'\n",
3516 if (as->parms[4].items) { /* -noexecute */
3517 fprintf(STDOUT, "Would have deleted VLDB entry for %s \n",
3522 vcode = ubik_Call(VL_DeleteEntry, cstruct, 0, avolid, RWVOL);
3524 fprintf(STDERR, "Could not delete entry for volume %s\n",
3527 "You must specify a RW volume name or ID "
3528 "(the entire VLDB entry will be deleted)\n");
3529 PrintError("", vcode);
3535 fprintf(STDOUT, "Deleted %d VLDB entries\n", totalBack);
3539 if (!as->parms[1].items && !as->parms[2].items && !as->parms[3].items) {
3540 fprintf(STDERR, "You must specify an option\n");
3544 /* Zero out search attributes */
3545 memset(&attributes, 0, sizeof(struct VldbListByAttributes));
3547 if (as->parms[1].items) { /* -prefix */
3548 strncpy(prefix, as->parms[1].items->data, VOLSER_MAXVOLNAME);
3550 if (!as->parms[2].items && !as->parms[3].items) { /* a single entry only */
3552 "You must provide -server with the -prefix argument\n");
3557 if (as->parms[2].items) { /* -server */
3559 aserver = GetServer(as->parms[2].items->data);
3561 fprintf(STDERR, "vos: server '%s' not found in host table\n",
3562 as->parms[2].items->data);
3565 attributes.server = ntohl(aserver);
3566 attributes.Mask |= VLLIST_SERVER;
3569 if (as->parms[3].items) { /* -partition */
3570 if (!as->parms[2].items) {
3572 "You must provide -server with the -partition argument\n");
3575 apart = volutil_GetPartitionID(as->parms[3].items->data);
3577 fprintf(STDERR, "vos: could not interpret partition name '%s'\n",
3578 as->parms[3].items->data);
3581 attributes.partition = apart;
3582 attributes.Mask |= VLLIST_PARTITION;
3585 /* Print status line of what we are doing */
3586 fprintf(STDOUT, "Deleting VLDB entries for ");
3587 if (as->parms[2].items) {
3588 fprintf(STDOUT, "server %s ", as->parms[2].items->data);
3590 if (as->parms[3].items) {
3592 MapPartIdIntoName(apart, pname);
3593 fprintf(STDOUT, "partition %s ", pname);
3596 fprintf(STDOUT, "which are prefixed with %s ", prefix);
3598 fprintf(STDOUT, "\n");
3601 /* Get all the VLDB entries on a server and/or partition */
3602 memset(&arrayEntries, 0, sizeof(arrayEntries));
3603 vcode = VLDB_ListAttributes(&attributes, &nentries, &arrayEntries);
3605 fprintf(STDERR, "Could not access the VLDB for attributes\n");
3606 PrintError("", vcode);
3610 /* Process each entry */
3611 for (j = 0; j < nentries; j++) {
3612 vllist = &arrayEntries.nbulkentries_val[j];
3614 /* It only deletes the RW volumes */
3615 if (strncmp(vllist->name, prefix, strlen(prefix))) {
3618 "Omitting to delete %s due to prefix %s mismatch\n",
3619 vllist->name, prefix);
3626 if (as->parms[4].items) { /* -noexecute */
3627 fprintf(STDOUT, "Would have deleted VLDB entry for %s \n",
3633 /* Only matches the RW volume name */
3634 avolid = vllist->volumeId[RWVOL];
3635 vcode = ubik_Call(VL_DeleteEntry, cstruct, 0, avolid, RWVOL);
3637 fprintf(STDOUT, "Could not delete VDLB entry for %s\n",
3640 PrintError("", vcode);
3645 fprintf(STDOUT, "Deleted VLDB entry for %s \n", vllist->name);
3650 fprintf(STDOUT, "----------------------\n");
3652 "Total VLDB entries deleted: %lu; failed to delete: %lu\n",
3653 (unsigned long)totalBack, (unsigned long)totalFail);
3654 if (arrayEntries.nbulkentries_val)
3655 free(arrayEntries.nbulkentries_val);
3661 CompareVldbEntryByName(p1, p2)
3664 struct nvldbentry *arg1, *arg2;
3666 arg1 = (struct nvldbentry *)p1;
3667 arg2 = (struct nvldbentry *)p2;
3668 return (strcmp(arg1->name, arg2->name));
3672 static int CompareVldbEntry(p1,p2)
3675 struct nvldbentry *arg1,*arg2;
3678 char comp1[100],comp2[100];
3679 char temp1[20],temp2[20];
3681 arg1 = (struct nvldbentry *)p1;
3682 arg2 = (struct nvldbentry *)p2;
3686 for(i = 0; i < arg1->nServers; i++)
3687 if(arg1->serverFlags[i] & ITSRWVOL) pos1 = i;
3688 for(i = 0; i < arg2->nServers; i++)
3689 if(arg2->serverFlags[i] & ITSRWVOL) pos2 = i;
3690 if(pos1 == -1 || pos2 == -1){
3694 sprintf(comp1,"%10u",arg1->serverNumber[pos1]);
3695 sprintf(comp2,"%10u",arg2->serverNumber[pos2]);
3696 sprintf(temp1,"%10u",arg1->serverPartition[pos1]);
3697 sprintf(temp2,"%10u",arg2->serverPartition[pos2]);
3698 strcat(comp1,temp1);
3699 strcat(comp2,temp2);
3700 strcat(comp1,arg1->name);
3701 strcat(comp1,arg2->name);
3702 return(strcmp(comp1,comp2));
3709 struct cmd_syndesc *as;
3712 afs_int32 aserver, code;
3714 struct VldbListByAttributes attributes;
3715 nbulkentries arrayEntries;
3716 struct nvldbentry *vllist, *tarray = 0, *ttarray;
3717 afs_int32 centries, nentries = 0, tarraysize, parraysize;
3720 int quiet, sort, lock;
3721 afs_int32 thisindex, nextindex;
3726 attributes.Mask = 0;
3727 lock = (as->parms[3].items ? 1 : 0); /* -lock flag */
3728 quiet = (as->parms[4].items ? 1 : 0); /* -quit flag */
3729 sort = (as->parms[5].items ? 0 : 1); /* -nosort flag */
3731 /* If the volume name is given, Use VolumeInfoCmd to look it up
3732 * and not ListAttributes.
3734 if (as->parms[0].items) {
3737 "vos: illegal use of '-locked' switch, need to specify server and/or partition\n");
3740 code = VolumeInfoCmd(as->parms[0].items->data);
3742 PrintError("", code);
3748 /* Server specified */
3749 if (as->parms[1].items) {
3750 aserver = GetServer(as->parms[1].items->data);
3752 fprintf(STDERR, "vos: server '%s' not found in host table\n",
3753 as->parms[1].items->data);
3756 attributes.server = ntohl(aserver);
3757 attributes.Mask |= VLLIST_SERVER;
3760 /* Partition specified */
3761 if (as->parms[2].items) {
3762 apart = volutil_GetPartitionID(as->parms[2].items->data);
3764 fprintf(STDERR, "vos: could not interpret partition name '%s'\n",
3765 as->parms[2].items->data);
3768 attributes.partition = apart;
3769 attributes.Mask |= VLLIST_PARTITION;
3773 attributes.Mask |= VLLIST_FLAG;
3774 attributes.flag = VLOP_ALLOPERS;
3777 /* Print header information */
3779 MapPartIdIntoName(apart, pname);
3780 fprintf(STDOUT, "VLDB entries for %s %s%s%s %s\n",
3781 (as->parms[1].items ? "server" : "all"),
3782 (as->parms[1].items ? as->parms[1].items->data : "servers"),
3783 (as->parms[2].items ? " partition " : ""),
3784 (as->parms[2].items ? pname : ""),
3785 (lock ? "which are locked:" : ""));
3788 for (thisindex = 0; (thisindex != -1); thisindex = nextindex) {
3789 memset(&arrayEntries, 0, sizeof(arrayEntries));
3794 VLDB_ListAttributesN2(&attributes, 0, thisindex, ¢ries,
3795 &arrayEntries, &nextindex);
3796 if (vcode == RXGEN_OPCODE) {
3797 /* Vlserver not running with ListAttributesN2. Fall back */
3799 VLDB_ListAttributes(&attributes, ¢ries, &arrayEntries);
3803 fprintf(STDERR, "Could not access the VLDB for attributes\n");
3804 PrintError("", vcode);
3807 nentries += centries;
3809 /* We don't sort, so just print the entries now */
3811 for (j = 0; j < centries; j++) { /* process each entry */
3812 vllist = &arrayEntries.nbulkentries_val[j];
3813 MapHostToNetwork(vllist);
3814 EnumerateEntry(vllist);
3816 if (vllist->flags & VLOP_ALLOPERS)
3817 fprintf(STDOUT, " Volume is currently LOCKED \n");
3821 /* So we sort. First we must collect all the entries and keep
3824 else if (centries > 0) {
3826 /* steal away the first bulk entries array */
3827 tarray = (struct nvldbentry *)arrayEntries.nbulkentries_val;
3828 tarraysize = centries * sizeof(struct nvldbentry);
3829 arrayEntries.nbulkentries_val = 0;
3831 /* Grow the tarray to keep the extra entries */
3832 parraysize = (centries * sizeof(struct nvldbentry));
3834 (struct nvldbentry *)realloc(tarray,
3835 tarraysize + parraysize);
3838 "Could not allocate enough space for the VLDB entries\n");
3844 memcpy(((char *)tarray) + tarraysize,
3845 (char *)arrayEntries.nbulkentries_val, parraysize);
3846 tarraysize += parraysize;
3850 /* Free the bulk array */
3851 if (arrayEntries.nbulkentries_val) {
3852 free(arrayEntries.nbulkentries_val);
3853 arrayEntries.nbulkentries_val = 0;
3857 /* Here is where we now sort all the entries and print them */
3858 if (sort && (nentries > 0)) {
3859 qsort((char *)tarray, nentries, sizeof(struct nvldbentry),
3860 CompareVldbEntryByName);
3861 for (vllist = tarray, j = 0; j < nentries; j++, vllist++) {
3862 MapHostToNetwork(vllist);
3863 EnumerateEntry(vllist);
3865 if (vllist->flags & VLOP_ALLOPERS)
3866 fprintf(STDOUT, " Volume is currently LOCKED \n");
3872 fprintf(STDOUT, "\nTotal entries: %lu\n", (unsigned long)nentries);
3880 register struct cmd_syndesc *as;
3882 afs_int32 apart = 0, avolid;
3883 afs_int32 aserver = 0, code, aserver1, apart1;
3885 struct VldbListByAttributes attributes;
3886 nbulkentries arrayEntries;
3887 register struct nvldbentry *vllist;
3891 int seenprefix, seenxprefix, exclude, ex, exp, noaction;
3892 afs_int32 totalBack = 0;
3893 afs_int32 totalFail = 0;
3894 int previdx = -1, error, same;
3897 struct cmd_item *ti;
3901 memset(&attributes, 0, sizeof(struct VldbListByAttributes));
3902 attributes.Mask = 0;
3904 seenprefix = (as->parms[0].items ? 1 : 0);
3905 exclude = (as->parms[3].items ? 1 : 0);
3906 seenxprefix = (as->parms[4].items ? 1 : 0);
3907 noaction = (as->parms[5].items ? 1 : 0);
3909 if (as->parms[1].items) { /* -server */
3910 aserver = GetServer(as->parms[1].items->data);
3912 fprintf(STDERR, "vos: server '%s' not found in host table\n",
3913 as->parms[1].items->data);
3916 attributes.server = ntohl(aserver);
3917 attributes.Mask |= VLLIST_SERVER;
3920 if (as->parms[2].items) { /* -partition */
3921 apart = volutil_GetPartitionID(as->parms[2].items->data);
3923 fprintf(STDERR, "vos: could not interpret partition name '%s'\n",
3924 as->parms[2].items->data);
3927 attributes.partition = apart;
3928 attributes.Mask |= VLLIST_PARTITION;
3931 /* Check to make sure the prefix and xprefix expressions compile ok */
3933 for (ti = as->parms[0].items; ti; ti = ti->next) {
3934 if (strncmp(ti->data, "^", 1) == 0) {
3935 #ifdef HAVE_POSIX_REGEX
3939 code = regcomp(&re, ti->data, REG_NOSUB);
3941 regerror(code, &re, errbuf, sizeof errbuf);
3943 "Unrecognizable -prefix regular expression: '%s': %s\n",
3949 ccode = (char *)re_comp(ti->data);
3952 "Unrecognizable -prefix regular expression: '%s': %s\n",
3961 for (ti = as->parms[4].items; ti; ti = ti->next) {
3962 if (strncmp(ti->data, "^", 1) == 0) {
3963 #ifdef HAVE_POSIX_REGEX
3967 code = regcomp(&re, ti->data, REG_NOSUB);
3969 regerror(code, &re, errbuf, sizeof errbuf);
3971 "Unrecognizable -xprefix regular expression: '%s': %s\n",
3977 ccode = (char *)re_comp(ti->data);
3980 "Unrecognizable -xprefix regular expression: '%s': %s\n",
3989 memset(&arrayEntries, 0, sizeof(arrayEntries)); /* initialize to hint the stub to alloc space */
3990 vcode = VLDB_ListAttributes(&attributes, &nentries, &arrayEntries);
3992 fprintf(STDERR, "Could not access the VLDB for attributes\n");
3993 PrintError("", vcode);
3997 if (as->parms[1].items || as->parms[2].items || verbose) {
3998 fprintf(STDOUT, "%s up volumes",
3999 (noaction ? "Would have backed" : "Backing"));
4001 if (as->parms[1].items) {
4002 fprintf(STDOUT, " on server %s", as->parms[1].items->data);
4003 } else if (as->parms[2].items) {
4004 fprintf(STDOUT, " for all servers");
4007 if (as->parms[2].items) {
4008 MapPartIdIntoName(apart, pname);
4009 fprintf(STDOUT, " partition %s", pname);
4012 if (seenprefix || (!seenprefix && seenxprefix)) {
4013 ti = (seenprefix ? as->parms[0].items : as->parms[4].items);
4014 ex = (seenprefix ? exclude : !exclude);
4015 exp = (strncmp(ti->data, "^", 1) == 0);
4016 fprintf(STDOUT, " which %smatch %s '%s'", (ex ? "do not " : ""),
4017 (exp ? "expression" : "prefix"), ti->data);
4018 for (ti = ti->next; ti; ti = ti->next) {
4019 exp = (strncmp(ti->data, "^", 1) == 0);
4020 printf(" %sor %s '%s'", (ex ? "n" : ""),
4021 (exp ? "expression" : "prefix"), ti->data);
4025 if (seenprefix && seenxprefix) {
4026 ti = as->parms[4].items;
4027 exp = (strncmp(ti->data, "^", 1) == 0);
4028 fprintf(STDOUT, " %swhich match %s '%s'",
4029 (exclude ? "adding those " : "removing those "),
4030 (exp ? "expression" : "prefix"), ti->data);
4031 for (ti = ti->next; ti; ti = ti->next) {
4032 exp = (strncmp(ti->data, "^", 1) == 0);
4033 printf(" or %s '%s'", (exp ? "expression" : "prefix"),
4037 fprintf(STDOUT, " .. ");
4039 fprintf(STDOUT, "\n");
4043 for (j = 0; j < nentries; j++) { /* process each vldb entry */
4044 vllist = &arrayEntries.nbulkentries_val[j];
4047 for (ti = as->parms[0].items; ti; ti = ti->next) {
4048 if (strncmp(ti->data, "^", 1) == 0) {
4049 #ifdef HAVE_POSIX_REGEX
4053 /* XXX -- should just do the compile once! */
4054 code = regcomp(&re, ti->data, REG_NOSUB);
4056 regerror(code, &re, errbuf, sizeof errbuf);
4058 "Error in -prefix regular expression: '%s': %s\n",
4062 match = (regexec(&re, vllist->name, 0, NULL, 0) == 0);
4065 ccode = (char *)re_comp(ti->data);
4068 "Error in -prefix regular expression: '%s': %s\n",
4072 match = (re_exec(vllist->name) == 1);
4076 (strncmp(vllist->name, ti->data, strlen(ti->data)) ==
4086 /* Without the -exclude flag: If it matches the prefix, then
4087 * check if we want to exclude any from xprefix.
4088 * With the -exclude flag: If it matches the prefix, then
4089 * check if we want to add any from xprefix.
4091 if (match && seenxprefix) {
4092 for (ti = as->parms[4].items; ti; ti = ti->next) {
4093 if (strncmp(ti->data, "^", 1) == 0) {
4094 #ifdef HAVE_POSIX_REGEX
4098 /* XXX -- should just do the compile once! */
4099 code = regcomp(&re, ti->data, REG_NOSUB);
4101 regerror(code, &re, errbuf, sizeof errbuf);
4103 "Error in -xprefix regular expression: '%s': %s\n",
4107 if (regexec(&re, vllist->name, 0, NULL, 0) == 0)
4111 ccode = (char *)re_comp(ti->data);
4114 "Error in -xprefix regular expression: '%s': %s\n",
4118 if (re_exec(vllist->name) == 1) {
4124 if (strncmp(vllist->name, ti->data, strlen(ti->data)) ==
4134 match = !match; /* -exclude will reverse the match */
4136 continue; /* Skip if no match */
4138 /* Print list of volumes to backup */
4140 fprintf(STDOUT, " %s\n", vllist->name);
4144 if (!(vllist->flags & RW_EXISTS)) {
4147 "Omitting to backup %s since RW volume does not exist \n",
4149 fprintf(STDOUT, "\n");
4155 avolid = vllist->volumeId[RWVOL];
4156 MapHostToNetwork(vllist);
4157 GetServerAndPart(vllist, RWVOL, &aserver1, &apart1, &previdx);
4158 if (aserver1 == -1 || apart1 == -1) {
4159 fprintf(STDOUT, "could not backup %s, invalid VLDB entry\n",
4165 same = VLDB_IsSameAddrs(aserver, aserver1, &error);
4168 "Failed to get info about server's %d address(es) from vlserver (err=%d); aborting call!\n",
4174 if ((aserver && !same) || (apart && (apart != apart1))) {
4177 "Omitting to backup %s since the RW is in a different location\n",
4183 time_t now = time(0);
4184 fprintf(STDOUT, "Creating backup volume for %s on %s",
4185 vllist->name, ctime(&now));
4189 code = UV_BackupVolume(aserver1, apart1, avolid);
4191 fprintf(STDOUT, "Could not backup %s\n", vllist->name);
4197 fprintf(STDOUT, "\n");
4199 } /* process each vldb entry */
4200 fprintf(STDOUT, "done\n");
4201 fprintf(STDOUT, "Total volumes backed up: %lu; failed to backup: %lu\n",
4202 (unsigned long)totalBack, (unsigned long)totalFail);
4204 if (arrayEntries.nbulkentries_val)
4205 free(arrayEntries.nbulkentries_val);
4211 register struct cmd_syndesc *as;
4214 afs_int32 aserver, code;
4216 struct VldbListByAttributes attributes;
4217 nbulkentries arrayEntries;
4218 register struct nvldbentry *vllist;
4227 attributes.Mask = 0;
4229 if (as->parms[0].items) { /* server specified */
4230 aserver = GetServer(as->parms[0].items->data);
4232 fprintf(STDERR, "vos: server '%s' not found in host table\n",
4233 as->parms[0].items->data);
4236 attributes.server = ntohl(aserver);
4237 attributes.Mask |= VLLIST_SERVER;
4239 if (as->parms[1].items) { /* partition specified */
4240 apart = volutil_GetPartitionID(as->parms[1].items->data);
4242 fprintf(STDERR, "vos: could not interpret partition name '%s'\n",
4243 as->parms[1].items->data);
4246 if (!IsPartValid(apart, aserver, &code)) { /*check for validity of the partition */
4248 PrintError("", code);
4251 "vos : partition %s does not exist on the server\n",
4252 as->parms[1].items->data);
4255 attributes.partition = apart;
4256 attributes.Mask |= VLLIST_PARTITION;
4258 attributes.flag = VLOP_ALLOPERS;
4259 attributes.Mask |= VLLIST_FLAG;
4260 memset(&arrayEntries, 0, sizeof(arrayEntries)); /*initialize to hint the stub to alloc space */
4261 vcode = VLDB_ListAttributes(&attributes, &nentries, &arrayEntries);
4263 fprintf(STDERR, "Could not access the VLDB for attributes\n");
4264 PrintError("", vcode);
4267 for (j = 0; j < nentries; j++) { /* process each entry */
4268 vllist = &arrayEntries.nbulkentries_val[j];
4269 volid = vllist->volumeId[RWVOL];
4271 ubik_Call(VL_ReleaseLock, cstruct, 0, volid, -1,
4272 LOCKREL_OPCODE | LOCKREL_AFSID | LOCKREL_TIMESTAMP);
4274 fprintf(STDERR, "Could not unlock entry for volume %s\n",
4276 PrintError("", vcode);
4281 MapPartIdIntoName(apart, pname);
4284 "Could not lock %lu VLDB entries of %lu locked entries\n",
4285 (unsigned long)totalE, (unsigned long)nentries);
4287 if (as->parms[0].items) {
4289 "Unlocked all the VLDB entries for volumes on server %s ",
4290 as->parms[0].items->data);
4291 if (as->parms[1].items) {
4292 MapPartIdIntoName(apart, pname);
4293 fprintf(STDOUT, "partition %s\n", pname);
4295 fprintf(STDOUT, "\n");
4297 } else if (as->parms[1].items) {
4298 MapPartIdIntoName(apart, pname);
4300 "Unlocked all the VLDB entries for volumes on partition %s on all servers\n",
4305 if (arrayEntries.nbulkentries_val)
4306 free(arrayEntries.nbulkentries_val);
4312 register struct cmd_syndesc *as;
4315 afs_int32 aserver, code;
4317 struct diskPartition partition;
4318 struct partList dummyPartList;
4322 aserver = GetServer(as->parms[0].items->data);
4324 fprintf(STDERR, "vos: server '%s' not found in host table\n",
4325 as->parms[0].items->data);
4328 if (as->parms[1].items) {
4329 apart = volutil_GetPartitionID(as->parms[1].items->data);