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
79 #define COMMONPARMS cmd_Seek(ts, 12);\
80 cmd_AddParm(ts, "-cell", CMD_SINGLE, CMD_OPTIONAL, "cell name");\
81 cmd_AddParm(ts, "-noauth", CMD_FLAG, CMD_OPTIONAL, "don't authenticate");\
82 cmd_AddParm(ts, "-localauth",CMD_FLAG,CMD_OPTIONAL,"use server tickets");\
83 cmd_AddParm(ts, "-verbose", CMD_FLAG, CMD_OPTIONAL, "verbose");\
84 cmd_AddParm(ts, "-encrypt", CMD_FLAG, CMD_OPTIONAL, "encrypt commands");\
86 #define ERROR_EXIT(code) {error=(code); goto error_exit;}
90 struct rx_connection *tconn;
92 extern struct ubik_client *cstruct;
95 static struct tqHead busyHead, notokHead;
98 qInit(struct tqHead *ahead)
100 memset((char *)ahead, 0, sizeof(struct tqHead));
106 qPut(struct tqHead *ahead, afs_int32 volid)
110 elem = (struct tqElem *)malloc(sizeof(struct tqElem));
111 elem->next = ahead->next;
119 qGet(struct tqHead *ahead, afs_int32 *volid)
123 if (ahead->count <= 0)
125 *volid = ahead->next->volid;
127 ahead->next = tmp->next;
133 /* returns 1 if <filename> exists else 0 */
135 FileExists(char *filename)
141 code = usd_Open(filename, USD_OPEN_RDONLY, 0, &ufd);
145 code = USD_IOCTL(ufd, USD_IOCTL_GETSIZE, &size);
153 /* returns 1 if <name> doesnot end in .readonly or .backup, else 0 */
155 VolNameOK(char *name)
160 total = strlen(name);
161 if (!strcmp(&name[total - 9], ".readonly")) {
163 } else if (!strcmp(&name[total - 7], ".backup")) {
170 /* return 1 if name is a number else 0 */
172 IsNumeric(char *name)
180 for (i = 0; i < len; i++) {
181 if (*ptr < '0' || *ptr > '9') {
193 * Parse a server name/address and return the address in HOST BYTE order
196 GetServer(char *aname)
198 register struct hostent *th;
201 register afs_int32 code;
202 char hostname[MAXHOSTCHARS];
204 code = sscanf(aname, "%d.%d.%d.%d", &b1, &b2, &b3, &b4);
206 addr = (b1 << 24) | (b2 << 16) | (b3 << 8) | b4;
207 addr = ntohl(addr); /* convert to host order */
209 th = gethostbyname(aname);
212 memcpy(&addr, th->h_addr, sizeof(addr));
215 if (addr == htonl(0x7f000001)) { /* local host */
216 code = gethostname(hostname, MAXHOSTCHARS);
219 th = gethostbyname(hostname); /* returns host byte order */
222 memcpy(&addr, th->h_addr, sizeof(addr));
229 GetVolumeType(char *aname)
232 if (!strcmp(aname, "ro"))
234 else if (!strcmp(aname, "rw"))
236 else if (!strcmp(aname, "bk"))
243 IsPartValid(afs_int32 partId, afs_int32 server, afs_int32 *code)
245 struct partList dummyPartList;
251 *code = UV_ListPartitions(server, &dummyPartList, &cnt);
254 for (i = 0; i < cnt; i++) {
255 if (dummyPartList.partFlags[i] & PARTVALID)
256 if (dummyPartList.partId[i] == partId)
264 /*sends the contents of file associated with <fd> and <blksize> to Rx Stream
265 * associated with <call> */
267 SendFile(usd_handle_t ufd, register struct rx_call *call, long blksize)
269 char *buffer = (char *)0;
274 buffer = (char *)malloc(blksize);
276 fprintf(STDERR, "malloc failed\n");
280 while (!error && !done) {
281 #ifndef AFS_NT40_ENV /* NT csn't select on non-socket fd's */
284 FD_SET((int)(ufd->handle), &in);
285 /* don't timeout if read blocks */
286 IOMGR_Select(((int)(ufd->handle)) + 1, &in, 0, 0, 0);
288 error = USD_READ(ufd, buffer, blksize, &nbytes);
290 fprintf(STDERR, "File system read failed\n");
297 if (rx_Write(call, buffer, nbytes) != nbytes) {
307 /* function invoked by UV_RestoreVolume, reads the data from rx_trx_stream and
308 * writes it out to the volume. */
310 WriteData(struct rx_call *call, char *rock)
315 afs_int32 error, code;
321 if (!filename || !*filename) {
322 usd_StandardInput(&ufd);
326 code = usd_Open(filename, USD_OPEN_RDONLY, 0, &ufd);
329 code = USD_IOCTL(ufd, USD_IOCTL_GETBLKSIZE, &blksize);
332 fprintf(STDERR, "Could not access file '%s'\n", filename);
337 code = SendFile(ufd, call, blksize);
344 code = USD_CLOSE(ufd);
346 fprintf(STDERR, "Could not close dump file %s\n",
347 (filename && *filename) ? filename : "STDOUT");
355 /* Receive data from <call> stream into file associated
356 * with <fd> <blksize>
359 ReceiveFile(usd_handle_t ufd, struct rx_call *call, long blksize)
363 afs_uint32 bytesleft, w;
366 buffer = (char *)malloc(blksize);
368 fprintf(STDERR, "memory allocation failed\n");
372 while ((bytesread = rx_Read(call, buffer, blksize)) > 0) {
373 for (bytesleft = bytesread; bytesleft; bytesleft -= w) {
374 #ifndef AFS_NT40_ENV /* NT csn't select on non-socket fd's */
377 FD_SET((int)(ufd->handle), &out);
378 /* don't timeout if write blocks */
379 IOMGR_Select(((int)(ufd->handle)) + 1, 0, &out, 0, 0);
382 USD_WRITE(ufd, &buffer[bytesread - bytesleft], bytesleft, &w);
384 fprintf(STDERR, "File system write failed\n");
397 DumpFunction(struct rx_call *call, char *filename)
399 usd_handle_t ufd; /* default is to stdout */
400 afs_int32 error = 0, code;
405 /* Open the output file */
406 if (!filename || !*filename) {
407 usd_StandardOutput(&ufd);
412 usd_Open(filename, USD_OPEN_CREATE | USD_OPEN_RDWR, 0666, &ufd);
416 code = USD_IOCTL(ufd, USD_IOCTL_SETSIZE, &size);
419 code = USD_IOCTL(ufd, USD_IOCTL_GETBLKSIZE, &blksize);
422 fprintf(STDERR, "Could not create file '%s'\n", filename);
423 ERROR_EXIT(VOLSERBADOP);
427 code = ReceiveFile(ufd, call, blksize);
432 /* Close the output file */
434 code = USD_CLOSE(ufd);
436 fprintf(STDERR, "Could not close dump file %s\n",
437 (filename && *filename) ? filename : "STDIN");
447 DisplayFormat(pntr, server, part, totalOK, totalNotOK, totalBusy, fast,
450 afs_int32 server, part;
451 int *totalOK, *totalNotOK, *totalBusy;
452 int fast, longlist, disp;
457 fprintf(STDOUT, "%-10lu\n", (unsigned long)pntr->volid);
458 } else if (longlist) {
459 if (pntr->status == VOK) {
460 fprintf(STDOUT, "%-32s ", pntr->name);
461 fprintf(STDOUT, "%10lu ", (unsigned long)pntr->volid);
463 fprintf(STDOUT, "RW ");
465 fprintf(STDOUT, "RO ");
467 fprintf(STDOUT, "BK ");
468 fprintf(STDOUT, "%10d K ", pntr->size);
469 if (pntr->inUse == 1) {
470 fprintf(STDOUT, "On-line");
473 fprintf(STDOUT, "Off-line");
476 if (pntr->needsSalvaged == 1)
477 fprintf(STDOUT, "**needs salvage**");
478 fprintf(STDOUT, "\n");
479 MapPartIdIntoName(part, pname);
480 fprintf(STDOUT, " %s %s \n", hostutil_GetNameByINet(server),
482 fprintf(STDOUT, " RWrite %10lu ROnly %10lu Backup %10lu \n",
483 (unsigned long)pntr->parentID,
484 (unsigned long)pntr->cloneID,
485 (unsigned long)pntr->backupID);
486 fprintf(STDOUT, " MaxQuota %10d K \n", pntr->maxquota);
487 fprintf(STDOUT, " Creation %s",
488 ctime((time_t *) & pntr->creationDate));
489 #ifdef FULL_LISTVOL_SWITCH
490 fprintf(STDOUT, " Copy %s",
491 ctime((time_t *) & pntr->copyDate));
492 if (!pntr->backupDate)
493 fprintf(STDOUT, " Backup Never\n");
495 fprintf(STDOUT, " Backup %s",
496 ctime((time_t *) & pntr->backupDate));
497 if (pntr->accessDate)
498 fprintf(STDOUT, " Last Access %s",
499 ctime((time_t *) & pntr->accessDate));
501 if (pntr->updateDate < pntr->creationDate)
502 fprintf(STDOUT, " Last Update %s",
503 ctime((time_t *) & pntr->creationDate));
505 fprintf(STDOUT, " Last Update %s",
506 ctime((time_t *) & pntr->updateDate));
508 " %d accesses in the past day (i.e., vnode references)\n",
510 } else if (pntr->status == VBUSY) {
512 qPut(&busyHead, pntr->volid);
514 fprintf(STDOUT, "**** Volume %lu is busy ****\n",
515 (unsigned long)pntr->volid);
518 qPut(¬okHead, pntr->volid);
520 fprintf(STDOUT, "**** Could not attach volume %lu ****\n",
521 (unsigned long)pntr->volid);
523 fprintf(STDOUT, "\n");
524 } else { /* default listing */
525 if (pntr->status == VOK) {
526 fprintf(STDOUT, "%-32s ", pntr->name);
527 fprintf(STDOUT, "%10lu ", (unsigned long)pntr->volid);
529 fprintf(STDOUT, "RW ");
531 fprintf(STDOUT, "RO ");
533 fprintf(STDOUT, "BK ");
534 fprintf(STDOUT, "%10d K ", pntr->size);
535 if (pntr->inUse == 1) {
536 fprintf(STDOUT, "On-line");
539 fprintf(STDOUT, "Off-line");
542 if (pntr->needsSalvaged == 1)
543 fprintf(STDOUT, "**needs salvage**");
544 fprintf(STDOUT, "\n");
545 } else if (pntr->status == VBUSY) {
547 qPut(&busyHead, pntr->volid);
549 fprintf(STDOUT, "**** Volume %lu is busy ****\n",
550 (unsigned long)pntr->volid);
553 qPut(¬okHead, pntr->volid);
555 fprintf(STDOUT, "**** Could not attach volume %lu ****\n",
556 (unsigned long)pntr->volid);
561 /*------------------------------------------------------------------------
562 * PRIVATE XDisplayFormat
565 * Display the contents of one extended volume info structure.
568 * a_xInfoP : Ptr to extended volume info struct to print.
569 * a_servID : Server ID to print.
570 * a_partID : Partition ID to print.
571 * a_totalOKP : Ptr to total-OK counter.
572 * a_totalNotOKP : Ptr to total-screwed counter.
573 * a_totalBusyP : Ptr to total-busy counter.
574 * a_fast : Fast listing?
575 * a_int32 : Int32 listing?
576 * a_showProblems : Show volume problems?
582 * Nothing interesting.
586 *------------------------------------------------------------------------*/
589 XDisplayFormat(a_xInfoP, a_servID, a_partID, a_totalOKP, a_totalNotOKP,
590 a_totalBusyP, a_fast, a_int32, a_showProblems)
591 volintXInfo *a_xInfoP;
601 { /*XDisplayFormat */
609 fprintf(STDOUT, "%-10lu\n", (unsigned long)a_xInfoP->volid);
610 } else if (a_int32) {
612 * Fully-detailed listing.
614 if (a_xInfoP->status == VOK) {
616 * Volume's status is OK - all the fields are valid.
618 fprintf(STDOUT, "%-32s ", a_xInfoP->name);
619 fprintf(STDOUT, "%10lu ", (unsigned long)a_xInfoP->volid);
620 if (a_xInfoP->type == 0)
621 fprintf(STDOUT, "RW ");
622 if (a_xInfoP->type == 1)
623 fprintf(STDOUT, "RO ");
624 if (a_xInfoP->type == 2)
625 fprintf(STDOUT, "BK ");
626 fprintf(STDOUT, "%10d K used ", a_xInfoP->size);
627 fprintf(STDOUT, "%d files ", a_xInfoP->filecount);
628 if (a_xInfoP->inUse == 1) {
629 fprintf(STDOUT, "On-line");
632 fprintf(STDOUT, "Off-line");
635 fprintf(STDOUT, "\n");
636 MapPartIdIntoName(a_partID, pname);
637 fprintf(STDOUT, " %s %s \n", hostutil_GetNameByINet(a_servID),
639 fprintf(STDOUT, " RWrite %10lu ROnly %10lu Backup %10lu \n",
640 (unsigned long)a_xInfoP->parentID,
641 (unsigned long)a_xInfoP->cloneID,
642 (unsigned long)a_xInfoP->backupID);
643 fprintf(STDOUT, " MaxQuota %10d K \n", a_xInfoP->maxquota);
644 fprintf(STDOUT, " Creation %s",
645 ctime((time_t *) & a_xInfoP->creationDate));
646 #ifdef FULL_LISTVOL_SWITCH
647 fprintf(STDOUT, " Copy %s",
648 ctime((time_t *) & a_xInfoP->copyDate));
649 if (!a_xInfoP->backupDate)
650 fprintf(STDOUT, " Backup Never\n");
652 fprintf(STDOUT, " Backup %s",
653 ctime((time_t *) & a_xInfoP->backupDate));
654 if (a_xInfoP->accessDate)
655 fprintf(STDOUT, " Last Access %s",
656 ctime((time_t *) & a_xInfoP->accessDate));
658 if (a_xInfoP->updateDate < a_xInfoP->creationDate)
659 fprintf(STDOUT, " Last Update %s",
660 ctime((time_t *) & a_xInfoP->creationDate));
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",
669 * Print all the read/write and authorship stats.
671 fprintf(STDOUT, "\n Raw Read/Write Stats\n");
673 " |-------------------------------------------|\n");
675 " | Same Network | Diff Network |\n");
677 " |----------|----------|----------|----------|\n");
679 " | Total | Auth | Total | Auth |\n");
681 " |----------|----------|----------|----------|\n");
682 fprintf(STDOUT, "Reads | %8d | %8d | %8d | %8d |\n",
683 a_xInfoP->stat_reads[VOLINT_STATS_SAME_NET],
684 a_xInfoP->stat_reads[VOLINT_STATS_SAME_NET_AUTH],
685 a_xInfoP->stat_reads[VOLINT_STATS_DIFF_NET],
686 a_xInfoP->stat_reads[VOLINT_STATS_DIFF_NET_AUTH]);
687 fprintf(STDOUT, "Writes | %8d | %8d | %8d | %8d |\n",
688 a_xInfoP->stat_writes[VOLINT_STATS_SAME_NET],
689 a_xInfoP->stat_writes[VOLINT_STATS_SAME_NET_AUTH],
690 a_xInfoP->stat_writes[VOLINT_STATS_DIFF_NET],
691 a_xInfoP->stat_writes[VOLINT_STATS_DIFF_NET_AUTH]);
693 " |-------------------------------------------|\n\n");
696 " Writes Affecting Authorship\n");
698 " |-------------------------------------------|\n");
700 " | File Authorship | Directory Authorship|\n");
702 " |----------|----------|----------|----------|\n");
704 " | Same | Diff | Same | Diff |\n");
706 " |----------|----------|----------|----------|\n");
707 fprintf(STDOUT, "0-60 sec | %8d | %8d | %8d | %8d |\n",
708 a_xInfoP->stat_fileSameAuthor[VOLINT_STATS_TIME_IDX_0],
709 a_xInfoP->stat_fileDiffAuthor[VOLINT_STATS_TIME_IDX_0],
710 a_xInfoP->stat_dirSameAuthor[VOLINT_STATS_TIME_IDX_0],
711 a_xInfoP->stat_dirDiffAuthor[VOLINT_STATS_TIME_IDX_0]);
712 fprintf(STDOUT, "1-10 min | %8d | %8d | %8d | %8d |\n",
713 a_xInfoP->stat_fileSameAuthor[VOLINT_STATS_TIME_IDX_1],
714 a_xInfoP->stat_fileDiffAuthor[VOLINT_STATS_TIME_IDX_1],
715 a_xInfoP->stat_dirSameAuthor[VOLINT_STATS_TIME_IDX_1],
716 a_xInfoP->stat_dirDiffAuthor[VOLINT_STATS_TIME_IDX_1]);
717 fprintf(STDOUT, "10min-1hr | %8d | %8d | %8d | %8d |\n",
718 a_xInfoP->stat_fileSameAuthor[VOLINT_STATS_TIME_IDX_2],
719 a_xInfoP->stat_fileDiffAuthor[VOLINT_STATS_TIME_IDX_2],
720 a_xInfoP->stat_dirSameAuthor[VOLINT_STATS_TIME_IDX_2],
721 a_xInfoP->stat_dirDiffAuthor[VOLINT_STATS_TIME_IDX_2]);
722 fprintf(STDOUT, "1hr-1day | %8d | %8d | %8d | %8d |\n",
723 a_xInfoP->stat_fileSameAuthor[VOLINT_STATS_TIME_IDX_3],
724 a_xInfoP->stat_fileDiffAuthor[VOLINT_STATS_TIME_IDX_3],
725 a_xInfoP->stat_dirSameAuthor[VOLINT_STATS_TIME_IDX_3],
726 a_xInfoP->stat_dirDiffAuthor[VOLINT_STATS_TIME_IDX_3]);
727 fprintf(STDOUT, "1day-1wk | %8d | %8d | %8d | %8d |\n",
728 a_xInfoP->stat_fileSameAuthor[VOLINT_STATS_TIME_IDX_4],
729 a_xInfoP->stat_fileDiffAuthor[VOLINT_STATS_TIME_IDX_4],
730 a_xInfoP->stat_dirSameAuthor[VOLINT_STATS_TIME_IDX_4],
731 a_xInfoP->stat_dirDiffAuthor[VOLINT_STATS_TIME_IDX_4]);
732 fprintf(STDOUT, "> 1wk | %8d | %8d | %8d | %8d |\n",
733 a_xInfoP->stat_fileSameAuthor[VOLINT_STATS_TIME_IDX_5],
734 a_xInfoP->stat_fileDiffAuthor[VOLINT_STATS_TIME_IDX_5],
735 a_xInfoP->stat_dirSameAuthor[VOLINT_STATS_TIME_IDX_5],
736 a_xInfoP->stat_dirDiffAuthor[VOLINT_STATS_TIME_IDX_5]);
738 " |-------------------------------------------|\n");
739 } /*Volume status OK */
740 else if (a_xInfoP->status == VBUSY) {
742 qPut(&busyHead, a_xInfoP->volid);
744 fprintf(STDOUT, "**** Volume %lu is busy ****\n",
745 (unsigned long)a_xInfoP->volid);
749 qPut(¬okHead, a_xInfoP->volid);
751 fprintf(STDOUT, "**** Could not attach volume %lu ****\n",
752 (unsigned long)a_xInfoP->volid);
753 } /*Screwed volume */
754 fprintf(STDOUT, "\n");
760 if (a_xInfoP->status == VOK) {
761 fprintf(STDOUT, "%-32s ", a_xInfoP->name);
762 fprintf(STDOUT, "%10lu ", (unsigned long)a_xInfoP->volid);
763 if (a_xInfoP->type == 0)
764 fprintf(STDOUT, "RW ");
765 if (a_xInfoP->type == 1)
766 fprintf(STDOUT, "RO ");
767 if (a_xInfoP->type == 2)
768 fprintf(STDOUT, "BK ");
769 fprintf(STDOUT, "%10d K ", a_xInfoP->size);
770 if (a_xInfoP->inUse == 1) {
771 fprintf(STDOUT, "On-line");
774 fprintf(STDOUT, "Off-line");
777 fprintf(STDOUT, "\n");
779 else if (a_xInfoP->status == VBUSY) {
781 qPut(&busyHead, a_xInfoP->volid);
783 fprintf(STDOUT, "**** Volume %lu is busy ****\n",
784 (unsigned long)a_xInfoP->volid);
788 qPut(¬okHead, a_xInfoP->volid);
790 fprintf(STDOUT, "**** Could not attach volume %lu ****\n",
791 (unsigned long)a_xInfoP->volid);
792 } /*Screwed volume */
793 } /*Default listing */
794 } /*XDisplayFormat */
796 #ifdef FULL_LISTVOL_SWITCH
798 DisplayFormat2(server, partition, pntr)
799 long server, partition;
802 static long server_cache = -1, partition_cache = -1;
803 static char hostname[256], address[32], pname[16];
805 if (server != server_cache) {
809 strcpy(hostname, hostutil_GetNameByINet(server));
810 strcpy(address, inet_ntoa(s));
811 server_cache = server;
813 if (partition != partition_cache) {
814 MapPartIdIntoName(partition, pname);
815 partition_cache = partition;
817 fprintf(STDOUT, "name\t\t%s\n", pntr->name);
818 fprintf(STDOUT, "id\t\t%lu\n", pntr->volid);
819 fprintf(STDOUT, "serv\t\t%s\t%s\n", address, hostname);
820 fprintf(STDOUT, "part\t\t%s\n", pname);
821 switch (pntr->status) {
823 fprintf(STDOUT, "status\t\tOK\n");
826 fprintf(STDOUT, "status\t\tBUSY\n");
829 fprintf(STDOUT, "status\t\tUNATTACHABLE\n");
832 fprintf(STDOUT, "backupID\t%lu\n", pntr->backupID);
833 fprintf(STDOUT, "parentID\t%lu\n", pntr->parentID);
834 fprintf(STDOUT, "cloneID\t\t%lu\n", pntr->cloneID);
835 fprintf(STDOUT, "inUse\t\t%s\n", pntr->inUse ? "Y" : "N");
836 fprintf(STDOUT, "needsSalvaged\t%s\n", pntr->needsSalvaged ? "Y" : "N");
837 /* 0xD3 is from afs/volume.h since I had trouble including the file */
838 fprintf(STDOUT, "destroyMe\t%s\n", pntr->destroyMe == 0xD3 ? "Y" : "N");
839 switch (pntr->type) {
841 fprintf(STDOUT, "type\t\tRW\n");
844 fprintf(STDOUT, "type\t\tRO\n");
847 fprintf(STDOUT, "type\t\tBK\n");
850 fprintf(STDOUT, "type\t\t?\n");
853 fprintf(STDOUT, "creationDate\t%-9lu\t%s", pntr->creationDate,
854 ctime(&pntr->creationDate));
855 fprintf(STDOUT, "accessDate\t%-9lu\t%s", pntr->accessDate,
856 ctime(&pntr->accessDate));
857 fprintf(STDOUT, "updateDate\t%-9lu\t%s", pntr->updateDate,
858 ctime(&pntr->updateDate));
859 fprintf(STDOUT, "backupDate\t%-9lu\t%s", pntr->backupDate,
860 ctime(&pntr->backupDate));
861 fprintf(STDOUT, "copyDate\t%-9lu\t%s", pntr->copyDate,
862 ctime(&pntr->copyDate));
863 fprintf(STDOUT, "flags\t\t%#lx\t(Optional)\n", pntr->flags);
864 fprintf(STDOUT, "diskused\t%u\n", pntr->size);
865 fprintf(STDOUT, "maxquota\t%u\n", pntr->maxquota);
866 fprintf(STDOUT, "minquota\t%lu\t(Optional)\n", pntr->spare0);
867 fprintf(STDOUT, "filecount\t%u\n", pntr->filecount);
868 fprintf(STDOUT, "dayUse\t\t%u\n", pntr->dayUse);
869 fprintf(STDOUT, "weekUse\t\t%lu\t(Optional)\n", pntr->spare1);
870 fprintf(STDOUT, "spare2\t\t%lu\t(Optional)\n", pntr->spare2);
871 fprintf(STDOUT, "spare3\t\t%lu\t(Optional)\n", pntr->spare3);
876 DisplayVolumes2(server, partition, pntr, count)
878 long server, partition, count;
882 for (i = 0; i < count; i++) {
883 fprintf(STDOUT, "BEGIN_OF_ENTRY\n");
884 DisplayFormat2(server, partition, pntr);
885 fprintf(STDOUT, "END_OF_ENTRY\n\n");
890 #endif /* FULL_LISTVOL_SWITCH */
893 DisplayVolumes(server, part, pntr, count, longlist, fast, quiet)
894 afs_int32 server, part;
896 afs_int32 count, longlist, fast;
899 int totalOK, totalNotOK, totalBusy, i;
907 for (i = 0; i < count; i++) {
908 DisplayFormat(pntr, server, part, &totalOK, &totalNotOK, &totalBusy,
913 while (busyHead.count) {
914 qGet(&busyHead, &volid);
915 fprintf(STDOUT, "**** Volume %lu is busy ****\n",
916 (unsigned long)volid);
920 while (notokHead.count) {
921 qGet(¬okHead, &volid);
922 fprintf(STDOUT, "**** Could not attach volume %lu ****\n",
923 (unsigned long)volid);
927 fprintf(STDOUT, "\n");
930 "Total volumes onLine %d ; Total volumes offLine %d ; Total busy %d\n\n",
931 totalOK, totalNotOK, totalBusy);
936 /*------------------------------------------------------------------------
937 * PRIVATE XDisplayVolumes
940 * Display extended volume information.
943 * a_servID : Pointer to the Rx call we're performing.
944 * a_partID : Partition for which we want the extended list.
945 * a_xInfoP : Ptr to extended volume info.
946 * a_count : Number of volume records contained above.
947 * a_int32 : Int32 listing generated?
948 * a_fast : Fast listing generated?
949 * a_quiet : Quiet listing generated?
955 * Nothing interesting.
959 *------------------------------------------------------------------------*/
962 XDisplayVolumes(a_servID, a_partID, a_xInfoP, a_count, a_int32, a_fast,
966 volintXInfo *a_xInfoP;
972 { /*XDisplayVolumes */
974 int totalOK; /*Total OK volumes */
975 int totalNotOK; /*Total screwed volumes */
976 int totalBusy; /*Total busy volumes */
977 int i; /*Loop variable */
978 afs_int32 volid; /*Current volume ID */
981 * Initialize counters and (global!!) queues.
990 * Display each volume in the list.
992 for (i = 0; i < a_count; i++) {
993 XDisplayFormat(a_xInfoP, a_servID, a_partID, &totalOK, &totalNotOK,
994 &totalBusy, a_fast, a_int32, 0);
999 * If any volumes were found to be busy or screwed, display them.
1002 while (busyHead.count) {
1003 qGet(&busyHead, &volid);
1004 fprintf(STDOUT, "**** Volume %lu is busy ****\n",
1005 (unsigned long)volid);
1009 while (notokHead.count) {
1010 qGet(¬okHead, &volid);
1011 fprintf(STDOUT, "**** Could not attach volume %lu ****\n",
1012 (unsigned long)volid);
1017 fprintf(STDOUT, "\n");
1020 "Total volumes: %d on-line, %d off-line, %d busyd\n\n",
1021 totalOK, totalNotOK, totalBusy);
1025 } /*XDisplayVolumes */
1027 /* set <server> and <part> to the correct values depending on
1028 * <voltype> and <entry> */
1030 GetServerAndPart(entry, voltype, server, part, previdx)
1031 struct nvldbentry *entry;
1032 afs_int32 *server, *part;
1036 int i, istart, vtype;
1041 /* Doesn't check for non-existance of backup volume */
1042 if ((voltype == RWVOL) || (voltype == BACKVOL)) {
1044 istart = 0; /* seach the entire entry */
1047 /* Seach from beginning of entry or pick up where we left off */
1048 istart = ((*previdx < 0) ? 0 : *previdx + 1);
1051 for (i = istart; i < entry->nServers; i++) {
1052 if (entry->serverFlags[i] & vtype) {
1053 *server = entry->serverNumber[i];
1054 *part = entry->serverPartition[i];
1060 /* Didn't find any, return -1 */
1066 PostVolumeStats(entry)
1067 struct nvldbentry *entry;
1069 SubEnumerateEntry(entry);
1070 /* Check for VLOP_ALLOPERS */
1071 if (entry->flags & VLOP_ALLOPERS)
1072 fprintf(STDOUT, " Volume is currently LOCKED \n");
1076 /*------------------------------------------------------------------------
1077 * PRIVATE XVolumeStats
1080 * Display extended volume information.
1083 * a_xInfoP : Ptr to extended volume info.
1084 * a_entryP : Ptr to the volume's VLDB entry.
1085 * a_srvID : Server ID.
1086 * a_partID : Partition ID.
1087 * a_volType : Type of volume to print.
1093 * Nothing interesting.
1097 *------------------------------------------------------------------------*/
1100 XVolumeStats(a_xInfoP, a_entryP, a_srvID, a_partID, a_volType)
1101 volintXInfo *a_xInfoP;
1102 struct nvldbentry *a_entryP;
1109 int totalOK, totalNotOK, totalBusy; /*Dummies - we don't really count here */
1111 XDisplayFormat(a_xInfoP, /*Ptr to extended volume info */
1112 a_srvID, /*Server ID to print */
1113 a_partID, /*Partition ID to print */
1114 &totalOK, /*Ptr to total-OK counter */
1115 &totalNotOK, /*Ptr to total-screwed counter */
1116 &totalBusy, /*Ptr to total-busy counter */
1117 0, /*Don't do a fast listing */
1118 1, /*Do a long listing */
1119 1); /*Show volume problems */
1125 VolumeStats(pntr, entry, server, part, voltype)
1127 struct nvldbentry *entry;
1129 afs_int32 server, part;
1131 int totalOK, totalNotOK, totalBusy;
1133 DisplayFormat(pntr, server, part, &totalOK, &totalNotOK, &totalBusy, 0, 1,
1138 /* command to forcibly remove a volume */
1141 register struct cmd_syndesc *as;
1143 register afs_int32 code;
1144 afs_int32 volID, err;
1149 server = GetServer(tp = as->parms[0].items->data);
1151 fprintf(STDERR, "vos: server '%s' not found in host table\n", tp);
1155 partID = volutil_GetPartitionID(tp = as->parms[1].items->data);
1157 fprintf(STDERR, "vos: could not parse '%s' as a partition name", tp);
1161 volID = vsu_GetVolumeID(tp = as->parms[2].items->data, cstruct, &err);
1164 PrintError("", err);
1167 "vos: could not parse '%s' as a numeric volume ID", tp);
1172 "vos: forcibly removing all traces of volume %d, please wait...",
1175 code = UV_NukeVolume(server, partID, volID);
1177 fprintf(STDOUT, "done.\n");
1179 fprintf(STDOUT, "failed with code %d.\n", code);
1184 /*------------------------------------------------------------------------
1185 * PRIVATE ExamineVolume
1188 * Routine used to examine a single volume, contacting the VLDB as
1189 * well as the Volume Server.
1192 * as : Ptr to parsed command line arguments.
1195 * 0 for a successful operation,
1196 * Otherwise, one of the ubik or VolServer error values.
1199 * Nothing interesting.
1203 *------------------------------------------------------------------------
1207 register struct cmd_syndesc *as;
1209 struct nvldbentry entry;
1210 afs_int32 vcode = 0;
1211 volintInfo *pntr = (volintInfo *) 0;
1212 volintXInfo *xInfoP = (volintXInfo *) 0;
1214 afs_int32 code, err, error = 0;
1215 int voltype, foundserv = 0, foundentry = 0;
1216 afs_int32 aserver, apart;
1218 int wantExtendedInfo; /*Do we want extended vol info? */
1220 wantExtendedInfo = (as->parms[1].items ? 1 : 0); /* -extended */
1222 volid = vsu_GetVolumeID(as->parms[0].items->data, cstruct, &err); /* -id */
1225 PrintError("", err);
1227 fprintf(STDERR, "Unknown volume ID or name '%s'\n",
1228 as->parms[0].items->data);
1233 fprintf(STDOUT, "Fetching VLDB entry for %lu .. ",
1234 (unsigned long)volid);
1237 vcode = VLDB_GetEntryByID(volid, -1, &entry);
1240 "Could not fetch the entry for volume number %lu from VLDB \n",
1241 (unsigned long)volid);
1245 fprintf(STDOUT, "done\n");
1246 MapHostToNetwork(&entry);
1248 if (entry.volumeId[RWVOL] == volid)
1250 else if (entry.volumeId[BACKVOL] == volid)
1252 else /* (entry.volumeId[ROVOL] == volid) */
1255 do { /* do {...} while (voltype == ROVOL) */
1256 /* Get the entry for the volume. If its a RW vol, get the RW entry.
1257 * It its a BK vol, get the RW entry (even if VLDB may say the BK doen't exist).
1258 * If its a RO vol, get the next RO entry.
1260 GetServerAndPart(&entry, ((voltype == ROVOL) ? ROVOL : RWVOL),
1261 &aserver, &apart, &previdx);
1262 if (previdx == -1) { /* searched all entries */
1264 fprintf(STDERR, "Volume %s does not exist in VLDB\n\n",
1265 as->parms[0].items->data);
1272 /* Get information about the volume from the server */
1274 fprintf(STDOUT, "Getting volume listing from the server %s .. ",
1275 hostutil_GetNameByINet(aserver));
1278 if (wantExtendedInfo)
1279 code = UV_XListOneVolume(aserver, apart, volid, &xInfoP);
1281 code = UV_ListOneVolume(aserver, apart, volid, &pntr);
1283 fprintf(STDOUT, "done\n");
1287 if (code == ENODEV) {
1288 if ((voltype == BACKVOL) && !(entry.flags & BACK_EXISTS)) {
1289 /* The VLDB says there is no backup volume and its not on disk */
1290 fprintf(STDERR, "Volume %s does not exist\n",
1291 as->parms[0].items->data);
1295 "Volume does not exist on server %s as indicated by the VLDB\n",
1296 hostutil_GetNameByINet(aserver));
1299 PrintDiagnostics("examine", code);
1301 fprintf(STDOUT, "\n");
1304 if (wantExtendedInfo)
1305 XVolumeStats(xInfoP, &entry, aserver, apart, voltype);
1307 #ifdef FULL_LISTVOL_SWITCH
1308 if (as->parms[2].items) {
1309 DisplayFormat2(aserver, apart, pntr);
1310 EnumerateEntry(&entry);
1312 #endif /* FULL_LISTVOL_SWITCH */
1313 VolumeStats(pntr, &entry, aserver, apart, voltype);
1315 if ((voltype == BACKVOL) && !(entry.flags & BACK_EXISTS)) {
1316 /* The VLDB says there is no backup volume yet we found one on disk */
1317 fprintf(STDERR, "Volume %s does not exist in VLDB\n",
1318 as->parms[0].items->data);
1327 } while (voltype == ROVOL);
1330 fprintf(STDERR, "Dump only information from VLDB\n\n");
1331 fprintf(STDOUT, "%s \n", entry.name); /* PostVolumeStats doesn't print name */
1333 PostVolumeStats(&entry);
1338 /*------------------------------------------------------------------------
1342 * Routine used to change the status of a single volume.
1345 * as : Ptr to parsed command line arguments.
1348 * 0 for a successful operation,
1349 * Otherwise, one of the ubik or VolServer error values.
1352 * Nothing interesting.
1356 *------------------------------------------------------------------------
1360 register struct cmd_syndesc *as;
1362 struct nvldbentry entry;
1363 afs_int32 vcode = 0;
1366 afs_int32 code, err;
1367 afs_int32 aserver, apart;
1370 volid = vsu_GetVolumeID(as->parms[0].items->data, cstruct, &err); /* -id */
1373 PrintError("", err);
1375 fprintf(STDERR, "Unknown volume ID or name '%s'\n",
1376 as->parms[0].items->data);
1380 code = VLDB_GetEntryByID(volid, RWVOL, &entry);
1383 "Could not fetch the entry for volume number %lu from VLDB \n",
1384 (unsigned long)volid);
1387 MapHostToNetwork(&entry);
1389 GetServerAndPart(&entry, RWVOL, &aserver, &apart, &previdx);
1390 if (previdx == -1) {
1391 fprintf(STDERR, "Volume %s does not exist in VLDB\n\n",
1392 as->parms[0].items->data);
1396 memset(&info, 0, sizeof(info));
1407 if (as->parms[1].items) {
1409 code = util_GetInt32(as->parms[1].items->data, &info.maxquota);
1411 fprintf(STDERR, "invalid quota value\n");
1415 if (as->parms[2].items) {
1419 code = UV_SetVolumeInfo(aserver, apart, volid, &info);
1422 "Could not update volume info fields for volume number %lu\n",
1423 (unsigned long)volid);
1427 /*------------------------------------------------------------------------
1431 * Brings a volume online.
1434 * as : Ptr to parsed command line arguments.
1437 * 0 for a successful operation,
1440 * Nothing interesting.
1444 *------------------------------------------------------------------------
1448 register struct cmd_syndesc *as;
1450 afs_int32 server, partition, volid;
1451 afs_int32 code, err = 0;
1453 server = GetServer(as->parms[0].items->data);
1455 fprintf(STDERR, "vos: server '%s' not found in host table\n",
1456 as->parms[0].items->data);
1460 partition = volutil_GetPartitionID(as->parms[1].items->data);
1461 if (partition < 0) {
1462 fprintf(STDERR, "vos: could not interpret partition name '%s'\n",
1463 as->parms[1].items->data);
1467 volid = vsu_GetVolumeID(as->parms[2].items->data, cstruct, &err); /* -id */
1470 PrintError("", err);
1472 fprintf(STDERR, "Unknown volume ID or name '%s'\n",
1473 as->parms[0].items->data);
1477 code = UV_SetVolume(server, partition, volid, ITOffline, 0 /*online */ ,
1480 fprintf(STDERR, "Failed to set volume. Code = %d\n", code);
1487 /*------------------------------------------------------------------------
1488 * PRIVATE volOffline
1491 * Brings a volume offline.
1494 * as : Ptr to parsed command line arguments.
1497 * 0 for a successful operation,
1500 * Nothing interesting.
1504 *------------------------------------------------------------------------
1507 volOffline(register struct cmd_syndesc *as)
1509 afs_int32 server, partition, volid;
1510 afs_int32 code, err = 0;
1511 afs_int32 transflag, sleeptime, transdone;
1513 server = GetServer(as->parms[0].items->data);
1515 fprintf(STDERR, "vos: server '%s' not found in host table\n",
1516 as->parms[0].items->data);
1520 partition = volutil_GetPartitionID(as->parms[1].items->data);
1521 if (partition < 0) {
1522 fprintf(STDERR, "vos: could not interpret partition name '%s'\n",
1523 as->parms[1].items->data);
1527 volid = vsu_GetVolumeID(as->parms[2].items->data, cstruct, &err); /* -id */
1530 PrintError("", err);
1532 fprintf(STDERR, "Unknown volume ID or name '%s'\n",
1533 as->parms[0].items->data);
1537 transflag = (as->parms[4].items ? ITBusy : ITOffline);
1538 sleeptime = (as->parms[3].items ? atol(as->parms[3].items->data) : 0);
1539 transdone = (sleeptime ? 0 /*online */ : VTOutOfService);
1540 if (as->parms[4].items && !as->parms[3].items) {
1541 fprintf(STDERR, "-sleep option must be used with -busy flag\n");
1546 UV_SetVolume(server, partition, volid, transflag, transdone,
1549 fprintf(STDERR, "Failed to set volume. Code = %d\n", code);
1557 CreateVolume(register struct cmd_syndesc *as)
1561 afs_int32 volid, code;
1562 struct nvldbentry entry;
1567 tserver = GetServer(as->parms[0].items->data);
1569 fprintf(STDERR, "vos: host '%s' not found in host table\n",
1570 as->parms[0].items->data);
1573 pname = volutil_GetPartitionID(as->parms[1].items->data);
1575 fprintf(STDERR, "vos: could not interpret partition name '%s'\n",
1576 as->parms[1].items->data);
1579 if (!IsPartValid(pname, tserver, &code)) { /*check for validity of the partition */
1581 PrintError("", code);
1584 "vos : partition %s does not exist on the server\n",
1585 as->parms[1].items->data);
1588 if (!ISNAMEVALID(as->parms[2].items->data)) {
1590 "vos: the name of the root volume %s exceeds the size limit of %d\n",
1591 as->parms[2].items->data, VOLSER_OLDMAXVOLNAME - 10);
1594 if (!VolNameOK(as->parms[2].items->data)) {
1596 "Illegal volume name %s, should not end in .readonly or .backup\n",
1597 as->parms[2].items->data);
1600 if (IsNumeric(as->parms[2].items->data)) {
1601 fprintf(STDERR, "Illegal volume name %s, should not be a number\n",
1602 as->parms[2].items->data);
1605 vcode = VLDB_GetEntryByName(as->parms[2].items->data, &entry);
1607 fprintf(STDERR, "Volume %s already exists\n",
1608 as->parms[2].items->data);
1609 PrintDiagnostics("create", code);
1613 if (as->parms[3].items) {
1614 if (!IsNumeric(as->parms[3].items->data)) {
1615 fprintf(STDERR, "Initial quota %s should be numeric.\n",
1616 as->parms[3].items->data);
1620 code = util_GetInt32(as->parms[3].items->data, "a);
1622 fprintf(STDERR, "vos: bad integer specified for quota.\n");
1628 UV_CreateVolume2(tserver, pname, as->parms[2].items->data, quota, 0,
1631 PrintDiagnostics("create", code);
1634 MapPartIdIntoName(pname, part);
1635 fprintf(STDOUT, "Volume %lu created on partition %s of %s\n",
1636 (unsigned long)volid, part, as->parms[0].items->data);
1643 struct nvldbentry *entry;
1646 afs_int32 error, code, curserver, curpart, volid;
1648 MapHostToNetwork(entry);
1650 for (i = 0; i < entry->nServers; i++) {
1651 curserver = entry->serverNumber[i];
1652 curpart = entry->serverPartition[i];
1653 if (entry->serverFlags[i] & ITSROVOL) {
1654 volid = entry->volumeId[ROVOL];
1656 volid = entry->volumeId[RWVOL];
1658 code = UV_DeleteVolume(curserver, curpart, volid);
1667 struct cmd_syndesc *as;
1669 afs_int32 err, code = 0;
1670 afs_int32 server = 0, partition = -1, volid;
1674 if (as->parms[0].items) {
1675 server = GetServer(as->parms[0].items->data);
1677 fprintf(STDERR, "vos: server '%s' not found in host table\n",
1678 as->parms[0].items->data);
1683 if (as->parms[1].items) {
1684 partition = volutil_GetPartitionID(as->parms[1].items->data);
1685 if (partition < 0) {
1686 fprintf(STDERR, "vos: could not interpret partition name '%s'\n",
1687 as->parms[1].items->data);
1691 /* Check for validity of the partition */
1692 if (!IsPartValid(partition, server, &code)) {
1694 PrintError("", code);
1697 "vos : partition %s does not exist on the server\n",
1698 as->parms[1].items->data);
1704 volid = vsu_GetVolumeID(as->parms[2].items->data, cstruct, &err);
1706 fprintf(STDERR, "Can't find volume name '%s' in VLDB\n",
1707 as->parms[2].items->data);
1709 PrintError("", err);
1713 /* If the server or partition option are not complete, try to fill
1714 * them in from the VLDB entry.
1716 if ((partition == -1) || !server) {
1717 struct nvldbentry entry;
1719 code = VLDB_GetEntryByID(volid, -1, &entry);
1722 "Could not fetch the entry for volume %lu from VLDB\n",
1723 (unsigned long)volid);
1724 PrintError("", code);
1728 if (((volid == entry.volumeId[RWVOL]) && (entry.flags & RW_EXISTS))
1729 || ((volid == entry.volumeId[BACKVOL])
1730 && (entry.flags & BACK_EXISTS))) {
1731 idx = Lp_GetRwIndex(&entry);
1732 if ((idx == -1) || (server && (server != entry.serverNumber[idx]))
1733 || ((partition != -1)
1734 && (partition != entry.serverPartition[idx]))) {
1735 fprintf(STDERR, "VLDB: Volume '%s' no match\n",
1736 as->parms[2].items->data);
1739 } else if ((volid == entry.volumeId[ROVOL])
1740 && (entry.flags & RO_EXISTS)) {
1741 for (idx = -1, j = 0; j < entry.nServers; j++) {
1742 if (entry.serverFlags[j] != ITSROVOL)
1745 if (((server == 0) || (server == entry.serverNumber[j]))
1746 && ((partition == -1)
1747 || (partition == entry.serverPartition[j]))) {
1750 "VLDB: Volume '%s' matches more than one RO\n",
1751 as->parms[2].items->data);
1758 fprintf(STDERR, "VLDB: Volume '%s' no match\n",
1759 as->parms[2].items->data);
1763 fprintf(STDERR, "VLDB: Volume '%s' no match\n",
1764 as->parms[2].items->data);
1768 server = htonl(entry.serverNumber[idx]);
1769 partition = entry.serverPartition[idx];
1773 code = UV_DeleteVolume(server, partition, volid);
1775 PrintDiagnostics("remove", code);
1779 MapPartIdIntoName(partition, pname);
1780 fprintf(STDOUT, "Volume %lu on partition %s server %s deleted\n",
1781 (unsigned long)volid, pname, hostutil_GetNameByINet(server));
1785 #define TESTM 0 /* set for move space tests, clear for production */
1788 register struct cmd_syndesc *as;
1791 afs_int32 volid, fromserver, toserver, frompart, topart, code, err;
1792 char fromPartName[10], toPartName[10];
1794 struct diskPartition partition; /* for space check */
1797 volid = vsu_GetVolumeID(as->parms[0].items->data, cstruct, &err);
1800 PrintError("", err);
1802 fprintf(STDERR, "vos: can't find volume ID or name '%s'\n",
1803 as->parms[0].items->data);
1806 fromserver = GetServer(as->parms[1].items->data);
1807 if (fromserver == 0) {
1808 fprintf(STDERR, "vos: server '%s' not found in host table\n",
1809 as->parms[1].items->data);
1812 toserver = GetServer(as->parms[3].items->data);
1813 if (toserver == 0) {
1814 fprintf(STDERR, "vos: server '%s' not found in host table\n",
1815 as->parms[3].items->data);
1818 frompart = volutil_GetPartitionID(as->parms[2].items->data);
1820 fprintf(STDERR, "vos: could not interpret partition name '%s'\n",
1821 as->parms[2].items->data);
1824 if (!IsPartValid(frompart, fromserver, &code)) { /*check for validity of the partition */
1826 PrintError("", code);
1829 "vos : partition %s does not exist on the server\n",
1830 as->parms[2].items->data);
1833 topart = volutil_GetPartitionID(as->parms[4].items->data);
1835 fprintf(STDERR, "vos: could not interpret partition name '%s'\n",
1836 as->parms[4].items->data);
1839 if (!IsPartValid(topart, toserver, &code)) { /*check for validity of the partition */
1841 PrintError("", code);
1844 "vos : partition %s does not exist on the server\n",
1845 as->parms[4].items->data);
1850 * check source partition for space to clone volume
1853 MapPartIdIntoName(topart, toPartName);
1854 MapPartIdIntoName(frompart, fromPartName);
1857 * check target partition for space to move volume
1860 code = UV_PartitionInfo(toserver, toPartName, &partition);
1862 fprintf(STDERR, "vos: cannot access partition %s\n", toPartName);
1866 fprintf(STDOUT, "target partition %s free space %d\n", toPartName,
1869 p = (volintInfo *) 0;
1870 code = UV_ListOneVolume(fromserver, frompart, volid, &p);
1872 fprintf(STDERR, "vos:cannot access volume %lu\n",
1873 (unsigned long)volid);
1878 fprintf(STDOUT, "volume %lu size %d\n", (unsigned long)volid,
1880 if (partition.free <= p->size) {
1882 "vos: no space on target partition %s to move volume %lu\n",
1883 toPartName, (unsigned long)volid);
1890 fprintf(STDOUT, "size test - don't do move\n");
1894 /* successful move still not guaranteed but shoot for it */
1896 code = UV_MoveVolume(volid, fromserver, frompart, toserver, topart);
1898 PrintDiagnostics("move", code);
1901 MapPartIdIntoName(topart, toPartName);
1902 MapPartIdIntoName(frompart, fromPartName);
1903 fprintf(STDOUT, "Volume %lu moved from %s %s to %s %s \n",
1904 (unsigned long)volid, as->parms[1].items->data, fromPartName,
1905 as->parms[3].items->data, toPartName);
1912 register struct cmd_syndesc *as;
1914 afs_int32 volid, fromserver, toserver, frompart, topart, code, err;
1915 char fromPartName[10], toPartName[10], *tovolume;
1916 struct nvldbentry entry;
1917 struct diskPartition partition; /* for space check */
1920 volid = vsu_GetVolumeID(as->parms[0].items->data, cstruct, &err);
1923 PrintError("", err);
1925 fprintf(STDERR, "vos: can't find volume ID or name '%s'\n",
1926 as->parms[0].items->data);
1929 fromserver = GetServer(as->parms[1].items->data);
1930 if (fromserver == 0) {
1931 fprintf(STDERR, "vos: server '%s' not found in host table\n",
1932 as->parms[1].items->data);
1936 toserver = GetServer(as->parms[4].items->data);
1937 if (toserver == 0) {
1938 fprintf(STDERR, "vos: server '%s' not found in host table\n",
1939 as->parms[3].items->data);
1943 tovolume = as->parms[3].items->data;
1944 if (!ISNAMEVALID(tovolume)) {
1946 "vos: the name of the root volume %s exceeds the size limit of %d\n",
1947 tovolume, VOLSER_OLDMAXVOLNAME - 10);
1950 if (!VolNameOK(tovolume)) {
1952 "Illegal volume name %s, should not end in .readonly or .backup\n",
1956 if (IsNumeric(tovolume)) {
1957 fprintf(STDERR, "Illegal volume name %s, should not be a number\n",
1961 code = VLDB_GetEntryByName(tovolume, &entry);
1963 fprintf(STDERR, "Volume %s already exists\n", tovolume);
1964 PrintDiagnostics("copy", code);
1968 frompart = volutil_GetPartitionID(as->parms[2].items->data);
1970 fprintf(STDERR, "vos: could not interpret partition name '%s'\n",
1971 as->parms[2].items->data);
1974 if (!IsPartValid(frompart, fromserver, &code)) { /*check for validity of the partition */
1976 PrintError("", code);
1979 "vos : partition %s does not exist on the server\n",
1980 as->parms[2].items->data);
1984 topart = volutil_GetPartitionID(as->parms[5].items->data);
1986 fprintf(STDERR, "vos: could not interpret partition name '%s'\n",
1987 as->parms[4].items->data);
1990 if (!IsPartValid(topart, toserver, &code)) { /*check for validity of the partition */
1992 PrintError("", code);
1995 "vos : partition %s does not exist on the server\n",
1996 as->parms[4].items->data);
2001 * check source partition for space to clone volume
2004 MapPartIdIntoName(topart, toPartName);
2005 MapPartIdIntoName(frompart, fromPartName);
2008 * check target partition for space to move volume
2011 code = UV_PartitionInfo(toserver, toPartName, &partition);
2013 fprintf(STDERR, "vos: cannot access partition %s\n", toPartName);
2017 fprintf(STDOUT, "target partition %s free space %d\n", toPartName,
2020 p = (volintInfo *) 0;
2021 code = UV_ListOneVolume(fromserver, frompart, volid, &p);
2023 fprintf(STDERR, "vos:cannot access volume %lu\n",
2024 (unsigned long)volid);
2029 if (partition.free <= p->size) {
2031 "vos: no space on target partition %s to copy volume %lu\n",
2032 toPartName, (unsigned long)volid);
2038 /* successful copy still not guaranteed but shoot for it */
2041 UV_CopyVolume(volid, fromserver, frompart, tovolume, toserver,
2044 PrintDiagnostics("copy", code);
2047 MapPartIdIntoName(topart, toPartName);
2048 MapPartIdIntoName(frompart, fromPartName);
2049 fprintf(STDOUT, "Volume %lu copied from %s %s to %s on %s %s \n",
2050 (unsigned long)volid, as->parms[1].items->data, fromPartName,
2051 tovolume, as->parms[4].items->data, toPartName);
2059 register struct cmd_syndesc *as;
2061 afs_int32 avolid, aserver, apart, vtype, code, err;
2062 struct nvldbentry entry;
2064 afs_int32 buvolid, buserver, bupart, butype;
2065 struct nvldbentry buentry;
2067 avolid = vsu_GetVolumeID(as->parms[0].items->data, cstruct, &err);
2070 PrintError("", err);
2072 fprintf(STDERR, "vos: can't find volume ID or name '%s'\n",
2073 as->parms[0].items->data);
2076 code = GetVolumeInfo(avolid, &aserver, &apart, &vtype, &entry);
2080 /* verify this is a readwrite volume */
2082 if (vtype != RWVOL) {
2083 fprintf(STDERR, "%s not RW volume\n", as->parms[0].items->data);
2087 /* is there a backup volume already? */
2089 if (entry.flags & BACK_EXISTS) {
2090 /* yep, where is it? */
2092 buvolid = entry.volumeId[BACKVOL];
2093 code = GetVolumeInfo(buvolid, &buserver, &bupart, &butype, &buentry);
2098 code = VLDB_IsSameAddrs(buserver, aserver, &err);
2101 "Failed to get info about server's %d address(es) from vlserver; aborting call!\n",
2107 "FATAL ERROR: backup volume %lu exists on server %lu\n",
2108 (unsigned long)buvolid, (unsigned long)buserver);
2113 /* nope, carry on */
2115 code = UV_BackupVolume(aserver, apart, avolid);
2118 PrintDiagnostics("backup", code);
2121 fprintf(STDOUT, "Created backup volume for %s \n",
2122 as->parms[0].items->data);
2128 register struct cmd_syndesc *as;
2131 struct nvldbentry entry;
2132 afs_int32 avolid, aserver, apart, vtype, code, err;
2135 if (as->parms[1].items)
2137 avolid = vsu_GetVolumeID(as->parms[0].items->data, cstruct, &err);
2140 PrintError("", err);
2142 fprintf(STDERR, "vos: can't find volume '%s'\n",
2143 as->parms[0].items->data);
2146 code = GetVolumeInfo(avolid, &aserver, &apart, &vtype, &entry);
2150 if (vtype != RWVOL) {
2151 fprintf(STDERR, "%s not a RW volume\n", as->parms[0].items->data);
2155 if (!ISNAMEVALID(entry.name)) {
2157 "Volume name %s is too long, rename before releasing\n",
2162 code = UV_ReleaseVolume(avolid, aserver, apart, force);
2164 PrintDiagnostics("release", code);
2167 fprintf(STDOUT, "Released volume %s successfully\n",
2168 as->parms[0].items->data);
2174 register struct cmd_syndesc *as;
2177 afs_int32 avolid, aserver, apart, voltype, fromdate = 0, code, err, i;
2178 char filename[NameLen];
2179 struct nvldbentry entry;
2181 rx_SetRxDeadTime(60 * 10);
2182 for (i = 0; i < MAXSERVERS; i++) {
2183 struct rx_connection *rxConn = ubik_GetRPCConn(cstruct, i);
2186 rx_SetConnDeadTime(rxConn, rx_connDeadTime);
2187 if (rxConn->service)
2188 rxConn->service->connDeadTime = rx_connDeadTime;
2191 avolid = vsu_GetVolumeID(as->parms[0].items->data, cstruct, &err);
2194 PrintError("", err);
2196 fprintf(STDERR, "vos: can't find volume '%s'\n",
2197 as->parms[0].items->data);
2201 if (as->parms[3].items || as->parms[4].items) {
2202 if (!as->parms[3].items || !as->parms[4].items) {
2204 "Must specify both -server and -partition options\n");
2207 aserver = GetServer(as->parms[3].items->data);
2209 fprintf(STDERR, "Invalid server name\n");
2212 apart = volutil_GetPartitionID(as->parms[4].items->data);
2214 fprintf(STDERR, "Invalid partition name\n");
2218 code = GetVolumeInfo(avolid, &aserver, &apart, &voltype, &entry);
2223 if (as->parms[1].items && strcmp(as->parms[1].items->data, "0")) {
2224 code = ktime_DateToInt32(as->parms[1].items->data, &fromdate);
2226 fprintf(STDERR, "vos: failed to parse date '%s' (error=%d))\n",
2227 as->parms[1].items->data, code);
2231 if (as->parms[2].items) {
2232 strcpy(filename, as->parms[2].items->data);
2234 strcpy(filename, "");
2237 if (as->parms[5].items) {
2239 UV_DumpClonedVolume(avolid, aserver, apart, fromdate,
2240 DumpFunction, filename);
2243 UV_DumpVolume(avolid, aserver, apart, fromdate, DumpFunction,
2247 PrintDiagnostics("dump", code);
2250 if (strcmp(filename, ""))
2251 fprintf(STDERR, "Dumped volume %s in file %s\n",
2252 as->parms[0].items->data, filename);
2254 fprintf(STDERR, "Dumped volume %s in stdout \n",
2255 as->parms[0].items->data);
2266 register struct cmd_syndesc *as;
2269 afs_int32 avolid, aserver, apart, code, vcode, err;
2270 afs_int32 aoverwrite = ASK;
2271 int restoreflags, readonly = 0, offline = 0, voltype = RWVOL;
2273 char afilename[NameLen], avolname[VOLSER_MAXVOLNAME + 1], apartName[10];
2274 char volname[VOLSER_MAXVOLNAME + 1];
2275 struct nvldbentry entry;
2279 if (as->parms[4].items) {
2280 avolid = vsu_GetVolumeID(as->parms[4].items->data, cstruct, &err);
2283 PrintError("", err);
2285 fprintf(STDERR, "vos: can't find volume '%s'\n",
2286 as->parms[4].items->data);
2292 if (as->parms[5].items) {
2293 if ((strcmp(as->parms[5].items->data, "a") == 0)
2294 || (strcmp(as->parms[5].items->data, "abort") == 0)) {
2296 } else if ((strcmp(as->parms[5].items->data, "f") == 0)
2297 || (strcmp(as->parms[5].items->data, "full") == 0)) {
2299 } else if ((strcmp(as->parms[5].items->data, "i") == 0)
2300 || (strcmp(as->parms[5].items->data, "inc") == 0)
2301 || (strcmp(as->parms[5].items->data, "increment") == 0)
2302 || (strcmp(as->parms[5].items->data, "incremental") == 0)) {
2305 fprintf(STDERR, "vos: %s is not a valid argument to -overwrite\n",
2306 as->parms[5].items->data);
2310 if (as->parms[6].items)
2312 if (as->parms[7].items) {
2317 aserver = GetServer(as->parms[0].items->data);
2319 fprintf(STDERR, "vos: server '%s' not found in host table\n",
2320 as->parms[0].items->data);
2323 apart = volutil_GetPartitionID(as->parms[1].items->data);
2325 fprintf(STDERR, "vos: could not interpret partition name '%s'\n",
2326 as->parms[1].items->data);
2329 if (!IsPartValid(apart, aserver, &code)) { /*check for validity of the partition */
2331 PrintError("", code);
2334 "vos : partition %s does not exist on the server\n",
2335 as->parms[1].items->data);
2338 strcpy(avolname, as->parms[2].items->data);
2339 if (!ISNAMEVALID(avolname)) {
2341 "vos: the name of the volume %s exceeds the size limit\n",
2345 if (!VolNameOK(avolname)) {
2347 "Illegal volume name %s, should not end in .readonly or .backup\n",
2351 if (as->parms[3].items) {
2352 strcpy(afilename, as->parms[3].items->data);
2353 if (!FileExists(afilename)) {
2354 fprintf(STDERR, "Can't access file %s\n", afilename);
2358 strcpy(afilename, "");
2361 /* Check if volume exists or not */
2363 vsu_ExtractName(volname, avolname);
2364 vcode = VLDB_GetEntryByName(volname, &entry);
2365 if (vcode) { /* no volume - do a full restore */
2366 restoreflags = RV_FULLRST;
2367 if ((aoverwrite == INC) || (aoverwrite == ABORT))
2369 "Volume does not exist; Will perform a full restore\n");
2372 else if ((!readonly && Lp_GetRwIndex(&entry) == -1) /* RW volume does not exist - do a full */
2373 ||(readonly && !Lp_ROMatch(0, 0, &entry))) { /* RO volume does not exist - do a full */
2374 restoreflags = RV_FULLRST;
2375 if ((aoverwrite == INC) || (aoverwrite == ABORT))
2377 "%s Volume does not exist; Will perform a full restore\n",
2378 readonly ? "RO" : "RW");
2381 avolid = entry.volumeId[voltype];
2382 } else if (entry.volumeId[voltype] != 0
2383 && entry.volumeId[voltype] != avolid) {
2384 avolid = entry.volumeId[voltype];
2388 else { /* volume exists - do we do a full incremental or abort */
2389 int Oserver, Opart, Otype, vol_elsewhere = 0;
2390 struct nvldbentry Oentry;
2394 avolid = entry.volumeId[voltype];
2395 } else if (entry.volumeId[voltype] != 0
2396 && entry.volumeId[voltype] != avolid) {
2397 avolid = entry.volumeId[voltype];
2400 /* A file name was specified - check if volume is on another partition */
2401 vcode = GetVolumeInfo(avolid, &Oserver, &Opart, &Otype, &Oentry);
2405 vcode = VLDB_IsSameAddrs(Oserver, aserver, &err);
2408 "Failed to get info about server's %d address(es) from vlserver (err=%d); aborting call!\n",
2412 if (!vcode || (Opart != apart))
2415 if (aoverwrite == ASK) {
2416 if (strcmp(afilename, "") == 0) { /* The file is from standard in */
2418 "Volume exists and no -overwrite option specified; Aborting restore command\n");
2422 /* Ask what to do */
2423 if (vol_elsewhere) {
2425 "The volume %s %u already exists on a different server/part\n",
2426 volname, entry.volumeId[voltype]);
2428 "Do you want to do a full restore or abort? [fa](a): ");
2431 "The volume %s %u already exists in the VLDB\n",
2432 volname, entry.volumeId[voltype]);
2434 "Do you want to do a full/incremental restore or abort? [fia](a): ");
2437 while (!(dc == EOF || dc == '\n'))
2438 dc = getchar(); /* goto end of line */
2439 if ((c == 'f') || (c == 'F'))
2441 else if ((c == 'i') || (c == 'I'))
2447 if (aoverwrite == ABORT) {
2448 fprintf(STDERR, "Volume exists; Aborting restore command\n");
2450 } else if (aoverwrite == FULL) {
2451 restoreflags = RV_FULLRST;
2453 "Volume exists; Will delete and perform full restore\n");
2454 } else if (aoverwrite == INC) {
2456 if (vol_elsewhere) {
2458 "%s volume %lu already exists on a different server/part; not allowed\n",
2459 readonly ? "RO" : "RW", (unsigned long)avolid);
2465 restoreflags |= RV_OFFLINE;
2467 restoreflags |= RV_RDONLY;
2469 UV_RestoreVolume(aserver, apart, avolid, avolname, restoreflags,
2470 WriteData, afilename);
2472 PrintDiagnostics("restore", code);
2475 MapPartIdIntoName(apart, apartName);
2478 * patch typo here - originally "parms[1]", should be "parms[0]"
2481 fprintf(STDOUT, "Restored volume %s on %s %s\n", avolname,
2482 as->parms[0].items->data, apartName);
2488 register struct cmd_syndesc *as;
2491 afs_int32 avolid, code, err;
2493 avolid = vsu_GetVolumeID(as->parms[0].items->data, cstruct, &err);
2496 PrintError("", err);
2498 fprintf(STDERR, "vos: can't find volume '%s'\n",
2499 as->parms[0].items->data);
2503 code = UV_LockRelease(avolid);
2505 PrintDiagnostics("unlock", code);
2508 fprintf(STDOUT, "Released lock on vldb entry for volume %s\n",
2509 as->parms[0].items->data);
2515 register struct cmd_syndesc *as;
2517 afs_int32 avolid, aserver, apart, code, err;
2518 char apartName[10], avolname[VOLSER_MAXVOLNAME + 1];
2520 vsu_ExtractName(avolname, as->parms[2].items->data);;
2521 avolid = vsu_GetVolumeID(avolname, cstruct, &err);
2524 PrintError("", err);
2526 fprintf(STDERR, "vos: can't find volume '%s'\n",
2527 as->parms[2].items->data);
2530 aserver = GetServer(as->parms[0].items->data);
2532 fprintf(STDERR, "vos: server '%s' not found in host table\n",
2533 as->parms[0].items->data);
2536 apart = volutil_GetPartitionID(as->parms[1].items->data);
2538 fprintf(STDERR, "vos: could not interpret partition name '%s'\n",
2539 as->parms[1].items->data);
2542 if (!IsPartValid(apart, aserver, &code)) { /*check for validity of the partition */
2544 PrintError("", code);
2547 "vos : partition %s does not exist on the server\n",
2548 as->parms[1].items->data);
2551 code = UV_AddSite(aserver, apart, avolid);
2553 PrintDiagnostics("addsite", code);
2556 MapPartIdIntoName(apart, apartName);
2557 fprintf(STDOUT, "Added replication site %s %s for volume %s\n",
2558 as->parms[0].items->data, apartName, as->parms[2].items->data);
2564 register struct cmd_syndesc *as;
2567 afs_int32 avolid, aserver, apart, code, err;
2568 char apartName[10], avolname[VOLSER_MAXVOLNAME + 1];
2570 vsu_ExtractName(avolname, as->parms[2].items->data);
2571 avolid = vsu_GetVolumeID(avolname, cstruct, &err);
2574 PrintError("", err);
2576 fprintf(STDERR, "vos: can't find volume '%s'\n",
2577 as->parms[2].items->data);
2580 aserver = GetServer(as->parms[0].items->data);
2582 fprintf(STDERR, "vos: server '%s' not found in host table\n",
2583 as->parms[0].items->data);
2586 apart = volutil_GetPartitionID(as->parms[1].items->data);
2588 fprintf(STDERR, "vos: could not interpret partition name '%s'\n",
2589 as->parms[1].items->data);
2593 *skip the partition validity check, since it is possible that the partition
2594 *has since been decomissioned.
2597 if (!IsPartValid(apart,aserver,&code)){
2598 if(code) PrintError("",code);
2599 else fprintf(STDERR,"vos : partition %s does not exist on the server\n",as->parms[1].items->data);
2603 code = UV_RemoveSite(aserver, apart, avolid);
2605 PrintDiagnostics("remsite", code);
2608 MapPartIdIntoName(apart, apartName);
2609 fprintf(STDOUT, "Removed replication site %s %s for volume %s\n",
2610 as->parms[0].items->data, apartName, as->parms[2].items->data);
2616 register struct cmd_syndesc *as;
2618 afs_int32 avolid, aserver, apart, code, err;
2621 avolid = vsu_GetVolumeID(as->parms[2].items->data, cstruct, &err);
2624 PrintError("", err);
2626 fprintf(STDERR, "vos: can't find volume '%s'\n",
2627 as->parms[2].items->data);
2630 aserver = GetServer(as->parms[0].items->data);
2632 fprintf(STDERR, "vos: server '%s' not found in host table\n",
2633 as->parms[0].items->data);
2636 apart = volutil_GetPartitionID(as->parms[1].items->data);
2638 fprintf(STDERR, "vos: could not interpret partition name '%s'\n",
2639 as->parms[1].items->data);
2642 if (!IsPartValid(apart, aserver, &code)) { /*check for validity of the partition */
2644 PrintError("", code);
2647 "vos : partition %s does not exist on the server\n",
2648 as->parms[1].items->data);
2651 code = UV_ChangeLocation(aserver, apart, avolid);
2653 PrintDiagnostics("addsite", code);
2656 MapPartIdIntoName(apart, apartName);
2657 fprintf(STDOUT, "Changed location to %s %s for volume %s\n",
2658 as->parms[0].items->data, apartName, as->parms[2].items->data);
2664 register struct cmd_syndesc *as;
2666 afs_int32 aserver, code;
2667 struct partList dummyPartList;
2672 aserver = GetServer(as->parms[0].items->data);
2674 fprintf(STDERR, "vos: server '%s' not found in host table\n",
2675 as->parms[0].items->data);
2680 code = UV_ListPartitions(aserver, &dummyPartList, &cnt);
2682 PrintDiagnostics("listpart", code);
2686 fprintf(STDOUT, "The partitions on the server are:\n");
2687 for (i = 0; i < cnt; i++) {
2688 if (dummyPartList.partFlags[i] & PARTVALID) {
2689 memset(pname, 0, sizeof(pname));
2690 MapPartIdIntoName(dummyPartList.partId[i], pname);
2691 fprintf(STDOUT, " %10s ", pname);
2693 if ((i % 5) == 0 && (i != 0))
2694 fprintf(STDOUT, "\n");
2697 fprintf(STDOUT, "\n");
2698 fprintf(STDOUT, "Total: %d\n", total);
2704 CompareVolName(p1, p2)
2707 volintInfo *arg1, *arg2;
2709 arg1 = (volintInfo *) p1;
2710 arg2 = (volintInfo *) p2;
2711 return (strcmp(arg1->name, arg2->name));
2715 /*------------------------------------------------------------------------
2716 * PRIVATE XCompareVolName
2719 * Comparison routine for volume names coming from an extended
2723 * a_obj1P : Char ptr to first extended vol info object
2724 * a_obj1P : Char ptr to second extended vol info object
2727 * The value of strcmp() on the volume names within the passed
2728 * objects (i,e., -1, 0, or 1).
2731 * Passed to qsort() as the designated comparison routine.
2735 *------------------------------------------------------------------------*/
2738 XCompareVolName(a_obj1P, a_obj2P)
2739 char *a_obj1P, *a_obj2P;
2741 { /*XCompareVolName */
2744 (((struct volintXInfo *)(a_obj1P))->name,
2745 ((struct volintXInfo *)(a_obj2P))->name));
2747 } /*XCompareVolName */
2750 CompareVolID(p1, p2)
2753 volintInfo *arg1, *arg2;
2755 arg1 = (volintInfo *) p1;
2756 arg2 = (volintInfo *) p2;
2757 if (arg1->volid == arg2->volid)
2759 if (arg1->volid > arg2->volid)
2766 /*------------------------------------------------------------------------
2767 * PRIVATE XCompareVolID
2770 * Comparison routine for volume IDs coming from an extended
2774 * a_obj1P : Char ptr to first extended vol info object
2775 * a_obj1P : Char ptr to second extended vol info object
2778 * The value of strcmp() on the volume names within the passed
2779 * objects (i,e., -1, 0, or 1).
2782 * Passed to qsort() as the designated comparison routine.
2786 *------------------------------------------------------------------------*/
2789 XCompareVolID(a_obj1P, a_obj2P)
2790 char *a_obj1P, *a_obj2P;
2792 { /*XCompareVolID */
2794 afs_int32 id1, id2; /*Volume IDs we're comparing */
2796 id1 = ((struct volintXInfo *)(a_obj1P))->volid;
2797 id2 = ((struct volintXInfo *)(a_obj2P))->volid;
2805 } /*XCompareVolID */
2807 /*------------------------------------------------------------------------
2808 * PRIVATE ListVolumes
2811 * Routine used to list volumes, contacting the Volume Server
2812 * directly, bypassing the VLDB.
2815 * as : Ptr to parsed command line arguments.
2818 * 0 Successful operation
2821 * Nothing interesting.
2825 *------------------------------------------------------------------------*/
2829 register struct cmd_syndesc *as;
2831 afs_int32 apart, int32list, fast;
2832 afs_int32 aserver, code;
2833 volintInfo *pntr, *oldpntr;
2837 volintXInfo *xInfoP, *origxInfoP; /*Ptr to current/orig extended vol info */
2838 int wantExtendedInfo; /*Do we want extended vol info? */
2841 struct partList dummyPartList;
2849 if (as->parms[3].items)
2851 if (as->parms[4].items)
2855 if (as->parms[2].items)
2861 if (as->parms[5].items) {
2863 * We can't coexist with the fast flag.
2867 "vos: Can't use the -fast and -extended flags together\n");
2872 * We need to turn on ``long'' listings to get the full effect.
2874 wantExtendedInfo = 1;
2877 wantExtendedInfo = 0;
2878 if (as->parms[1].items) {
2879 apart = volutil_GetPartitionID(as->parms[1].items->data);
2881 fprintf(STDERR, "vos: could not interpret partition name '%s'\n",
2882 as->parms[1].items->data);
2885 dummyPartList.partId[0] = apart;
2886 dummyPartList.partFlags[0] = PARTVALID;
2889 aserver = GetServer(as->parms[0].items->data);
2891 fprintf(STDERR, "vos: server '%s' not found in host table\n",
2892 as->parms[0].items->data);
2897 if (!IsPartValid(apart, aserver, &code)) { /*check for validity of the partition */
2899 PrintError("", code);
2902 "vos : partition %s does not exist on the server\n",
2903 as->parms[1].items->data);
2907 code = UV_ListPartitions(aserver, &dummyPartList, &cnt);
2909 PrintDiagnostics("listvol", code);
2913 for (i = 0; i < cnt; i++) {
2914 if (dummyPartList.partFlags[i] & PARTVALID) {
2915 if (wantExtendedInfo)
2917 UV_XListVolumes(aserver, dummyPartList.partId[i], all,
2921 UV_ListVolumes(aserver, dummyPartList.partId[i], all,
2924 PrintDiagnostics("listvol", code);
2929 if (wantExtendedInfo) {
2930 origxInfoP = xInfoP;
2931 base = (char *)xInfoP;
2934 base = (char *)pntr;
2938 if (wantExtendedInfo)
2939 qsort(base, count, sizeof(volintXInfo), XCompareVolName);
2941 qsort(base, count, sizeof(volintInfo), CompareVolName);
2943 if (wantExtendedInfo)
2944 qsort(base, count, sizeof(volintXInfo), XCompareVolID);
2946 qsort(base, count, sizeof(volintInfo), CompareVolID);
2948 MapPartIdIntoName(dummyPartList.partId[i], pname);
2951 "Total number of volumes on server %s partition %s: %lu \n",
2952 as->parms[0].items->data, pname,
2953 (unsigned long)count);
2954 if (wantExtendedInfo) {
2955 XDisplayVolumes(aserver, dummyPartList.partId[i], origxInfoP,
2956 count, int32list, fast, quiet);
2959 xInfoP = (volintXInfo *) 0;
2961 #ifdef FULL_LISTVOL_SWITCH
2962 if (as->parms[6].items)
2963 DisplayVolumes2(aserver, dummyPartList.partId[i], oldpntr,
2966 #endif /* FULL_LISTVOL_SWITCH */
2967 DisplayVolumes(aserver, dummyPartList.partId[i], oldpntr,
2968 count, int32list, fast, quiet);
2971 pntr = (volintInfo *) 0;
2980 register struct cmd_syndesc *as;
2982 afs_int32 pname, code; /* part name */
2988 if (as->parms[0].items) {
2989 tserver = GetServer(as->parms[0].items->data);
2991 fprintf(STDERR, "vos: host '%s' not found in host table\n",
2992 as->parms[0].items->data);
2997 if (as->parms[1].items) {
2998 pname = volutil_GetPartitionID(as->parms[1].items->data);
3000 fprintf(STDERR, "vos: could not interpret partition name '%s'\n",
3001 as->parms[1].items->data);
3004 if (!IsPartValid(pname, tserver, &code)) { /*check for validity of the partition */
3006 PrintError("", code);
3009 "vos: partition %s does not exist on the server\n",
3010 as->parms[1].items->data);
3017 "The -partition option requires a -server option\n");
3022 if (as->parms[2].items) {
3023 /* Synchronize an individual volume */
3024 volname = as->parms[2].items->data;
3025 code = UV_SyncVolume(tserver, pname, volname, flags);
3029 "Without a -volume option, the -server option is required\n");
3032 code = UV_SyncVldb(tserver, pname, flags, 0 /*unused */ );
3036 PrintDiagnostics("syncvldb", code);
3040 /* Print a summary of what we did */
3042 fprintf(STDOUT, "VLDB volume %s synchronized", volname);
3044 fprintf(STDOUT, "VLDB synchronized");
3046 fprintf(STDOUT, " with state of server %s", as->parms[0].items->data);
3049 MapPartIdIntoName(pname, part);
3050 fprintf(STDOUT, " partition %s\n", part);
3052 fprintf(STDOUT, "\n");
3059 register struct cmd_syndesc *as;
3062 afs_int32 pname, code; /* part name */
3067 tserver = GetServer(as->parms[0].items->data);
3069 fprintf(STDERR, "vos: host '%s' not found in host table\n",
3070 as->parms[0].items->data);
3073 if (as->parms[1].items) {
3074 pname = volutil_GetPartitionID(as->parms[1].items->data);
3076 fprintf(STDERR, "vos: could not interpret partition name '%s'\n",
3077 as->parms[1].items->data);
3080 if (!IsPartValid(pname, tserver, &code)) { /*check for validity of the partition */
3082 PrintError("", code);
3085 "vos : partition %s does not exist on the server\n",
3086 as->parms[1].items->data);
3092 code = UV_SyncServer(tserver, pname, flags, 0 /*unused */ );
3094 PrintDiagnostics("syncserv", code);
3098 MapPartIdIntoName(pname, part);
3099 fprintf(STDOUT, "Server %s partition %s synchronized with VLDB\n",
3100 as->parms[0].items->data, part);
3102 fprintf(STDOUT, "Server %s synchronized with VLDB\n",
3103 as->parms[0].items->data);
3112 struct nvldbentry entry;
3115 /* The vlserver will handle names with the .readonly
3116 * and .backup extension as well as volume ids.
3118 vcode = VLDB_GetEntryByName(name, &entry);
3120 PrintError("", vcode);
3123 MapHostToNetwork(&entry);
3124 EnumerateEntry(&entry);
3126 /* Defect #3027: grubby check to handle locked volume.
3127 * If VLOP_ALLOPERS is set, the entry is locked.
3128 * Leave this routine as is, but put in correct check.
3130 if (entry.flags & VLOP_ALLOPERS)
3131 fprintf(STDOUT, " Volume is currently LOCKED \n");
3138 register struct cmd_syndesc *as;
3141 struct nvldbentry entry;
3142 afs_int32 volid, code, server, part, zapbackupid = 0, backupid = 0, err;
3144 if (as->parms[3].items) {
3145 /* force flag is on, use the other version */
3146 return NukeVolume(as);
3149 if (as->parms[4].items) {
3153 volid = vsu_GetVolumeID(as->parms[2].items->data, cstruct, &err);
3156 PrintError("", err);
3158 fprintf(STDERR, "vos: can't find volume '%s'\n",
3159 as->parms[2].items->data);
3162 part = volutil_GetPartitionID(as->parms[1].items->data);
3164 fprintf(STDERR, "vos: could not interpret partition name '%s'\n",
3165 as->parms[1].items->data);
3168 server = GetServer(as->parms[0].items->data);
3170 fprintf(STDERR, "vos: host '%s' not found in host table\n",
3171 as->parms[0].items->data);
3174 if (!IsPartValid(part, server, &code)) { /*check for validity of the partition */
3176 PrintError("", code);
3179 "vos : partition %s does not exist on the server\n",
3180 as->parms[1].items->data);
3183 code = VLDB_GetEntryByID(volid, -1, &entry);
3185 if (volid == entry.volumeId[RWVOL])
3186 backupid = entry.volumeId[BACKVOL];
3188 "Warning: Entry for volume number %lu exists in VLDB (but we're zapping it anyway!)\n",
3189 (unsigned long)volid);
3192 volintInfo *pntr = (volintInfo *) 0;
3195 code = UV_ListOneVolume(server, part, volid, &pntr);
3197 if (volid == pntr->parentID)
3198 backupid = pntr->backupID;
3204 code = UV_VolumeZap(server, part, backupid);
3206 PrintDiagnostics("zap", code);
3209 fprintf(STDOUT, "Backup Volume %lu deleted\n",
3210 (unsigned long)backupid);
3213 code = UV_VolumeZap(server, part, volid);
3215 PrintDiagnostics("zap", code);
3218 fprintf(STDOUT, "Volume %lu deleted\n", (unsigned long)volid);
3225 register struct cmd_syndesc *as;
3228 afs_int32 server, code;
3229 transDebugInfo *pntr, *oldpntr;
3234 server = GetServer(as->parms[0].items->data);
3236 fprintf(STDERR, "vos: host '%s' not found in host table\n",
3237 as->parms[0].items->data);
3240 code = UV_VolserStatus(server, &pntr, &count);
3242 PrintDiagnostics("status", code);
3247 fprintf(STDOUT, "No active transactions on %s\n",
3248 as->parms[0].items->data);
3250 fprintf(STDOUT, "Total transactions: %d\n", count);
3252 for (i = 0; i < count; i++) {
3253 /*print out the relevant info */
3254 fprintf(STDOUT, "--------------------------------------\n");
3255 fprintf(STDOUT, "transaction: %lu created: %s",
3256 (unsigned long)pntr->tid, ctime((time_t *) & pntr->time));
3257 if (pntr->returnCode) {
3258 fprintf(STDOUT, "returnCode: %lu\n",
3259 (unsigned long)pntr->returnCode);
3262 fprintf(STDOUT, "attachFlags: ");
3263 switch (pntr->iflags) {
3265 fprintf(STDOUT, "offline ");
3268 fprintf(STDOUT, "busy ");
3271 fprintf(STDOUT, "readonly ");
3274 fprintf(STDOUT, "create ");
3277 fprintf(STDOUT, "create volid ");
3280 fprintf(STDOUT, "\n");
3283 fprintf(STDOUT, "volumeStatus: ");
3284 switch (pntr->vflags) {
3285 case VTDeleteOnSalvage:
3286 fprintf(STDOUT, "deleteOnSalvage ");
3287 case VTOutOfService:
3288 fprintf(STDOUT, "outOfService ");
3290 fprintf(STDOUT, "deleted ");
3292 fprintf(STDOUT, "\n");
3295 fprintf(STDOUT, "transactionFlags: ");
3296 fprintf(STDOUT, "delete\n");
3298 MapPartIdIntoName(pntr->partition, pname);
3299 fprintf(STDOUT, "volume: %lu partition: %s procedure: %s\n",
3300 (unsigned long)pntr->volid, pname, pntr->lastProcName);
3301 if (pntr->callValid) {
3303 "packetRead: %lu lastReceiveTime: %d packetSend: %lu lastSendTime: %d\n",
3304 (unsigned long)pntr->readNext, pntr->lastReceiveTime,
3305 (unsigned long)pntr->transmitNext, pntr->lastSendTime);
3308 fprintf(STDOUT, "--------------------------------------\n");
3309 fprintf(STDOUT, "\n");
3318 register struct cmd_syndesc *as;
3320 afs_int32 code1, code2, code;
3321 struct nvldbentry entry;
3323 code1 = VLDB_GetEntryByName(as->parms[0].items->data, &entry);
3325 fprintf(STDERR, "vos: Could not find entry for volume %s\n",
3326 as->parms[0].items->data);
3329 code2 = VLDB_GetEntryByName(as->parms[1].items->data, &entry);
3330 if ((!code1) && (!code2)) { /*the newname already exists */
3331 fprintf(STDERR, "vos: volume %s already exists\n",
3332 as->parms[1].items->data);
3336 if (code1 && code2) {
3337 fprintf(STDERR, "vos: Could not find entry for volume %s or %s\n",
3338 as->parms[0].items->data, as->parms[1].items->data);
3341 if (!VolNameOK(as->parms[0].items->data)) {
3343 "Illegal volume name %s, should not end in .readonly or .backup\n",
3344 as->parms[0].items->data);
3347 if (!ISNAMEVALID(as->parms[1].items->data)) {
3349 "vos: the new volume name %s exceeds the size limit of %d\n",
3350 as->parms[1].items->data, VOLSER_OLDMAXVOLNAME - 10);
3353 if (!VolNameOK(as->parms[1].items->data)) {
3355 "Illegal volume name %s, should not end in .readonly or .backup\n",
3356 as->parms[1].items->data);
3359 if (IsNumeric(as->parms[1].items->data)) {
3360 fprintf(STDERR, "Illegal volume name %s, should not be a number\n",
3361 as->parms[1].items->data);
3364 MapHostToNetwork(&entry);
3366 UV_RenameVolume(&entry, as->parms[0].items->data,
3367 as->parms[1].items->data);
3369 PrintDiagnostics("rename", code);
3372 fprintf(STDOUT, "Renamed volume %s to %s\n", as->parms[0].items->data,
3373 as->parms[1].items->data);
3377 GetVolumeInfo(volid, server, part, voltype, rentry)
3378 afs_int32 *server, volid, *part, *voltype;
3379 register struct nvldbentry *rentry;
3384 vcode = VLDB_GetEntryByID(volid, -1, rentry);
3387 "Could not fetch the entry for volume %lu from VLDB \n",
3388 (unsigned long)volid);
3389 PrintError("", vcode);
3392 MapHostToNetwork(rentry);
3393 if (volid == rentry->volumeId[ROVOL]) {
3395 for (i = 0; i < rentry->nServers; i++) {
3396 if ((index == -1) && (rentry->serverFlags[i] & ITSROVOL)
3397 && !(rentry->serverFlags[i] & RO_DONTUSE))
3402 "RO volume is not found in VLDB entry for volume %lu\n",
3403 (unsigned long)volid);
3407 *server = rentry->serverNumber[index];
3408 *part = rentry->serverPartition[index];
3412 index = Lp_GetRwIndex(rentry);
3415 "RW Volume is not found in VLDB entry for volume %lu\n",
3416 (unsigned long)volid);
3419 if (volid == rentry->volumeId[RWVOL]) {
3421 *server = rentry->serverNumber[index];
3422 *part = rentry->serverPartition[index];
3425 if (volid == rentry->volumeId[BACKVOL]) {
3427 *server = rentry->serverNumber[index];
3428 *part = rentry->serverPartition[index];
3432 "unexpected volume type for volume %lu\n",
3433 (unsigned long)volid);
3439 register struct cmd_syndesc *as;
3445 struct VldbListByAttributes attributes;
3446 nbulkentries arrayEntries;
3447 register struct nvldbentry *vllist;
3448 struct cmd_item *itp;
3451 char prefix[VOLSER_MAXVOLNAME + 1];
3453 afs_int32 totalBack = 0, totalFail = 0, err;
3455 if (as->parms[0].items) { /* -id */
3456 if (as->parms[1].items || as->parms[2].items || as->parms[3].items) {
3458 "You cannot use -server, -partition, or -prefix with the -id argument\n");
3461 for (itp = as->parms[0].items; itp; itp = itp->next) {
3462 avolid = vsu_GetVolumeID(itp->data, cstruct, &err);
3465 PrintError("", err);
3467 fprintf(STDERR, "vos: can't find volume '%s'\n",
3471 if (as->parms[4].items) { /* -noexecute */
3472 fprintf(STDOUT, "Would have deleted VLDB entry for %s \n",
3477 vcode = ubik_Call(VL_DeleteEntry, cstruct, 0, avolid, RWVOL);
3479 fprintf(STDERR, "Could not delete entry for volume %s\n",
3482 "You must specify a RW volume name or ID "
3483 "(the entire VLDB entry will be deleted)\n");
3484 PrintError("", vcode);
3490 fprintf(STDOUT, "Deleted %d VLDB entries\n", totalBack);
3494 if (!as->parms[1].items && !as->parms[2].items && !as->parms[3].items) {
3495 fprintf(STDERR, "You must specify an option\n");
3499 /* Zero out search attributes */
3500 memset(&attributes, 0, sizeof(struct VldbListByAttributes));
3502 if (as->parms[1].items) { /* -prefix */
3503 strncpy(prefix, as->parms[1].items->data, VOLSER_MAXVOLNAME);
3505 if (!as->parms[2].items && !as->parms[3].items) { /* a single entry only */
3507 "You must provide -server with the -prefix argument\n");
3512 if (as->parms[2].items) { /* -server */
3514 aserver = GetServer(as->parms[2].items->data);
3516 fprintf(STDERR, "vos: server '%s' not found in host table\n",
3517 as->parms[2].items->data);
3520 attributes.server = ntohl(aserver);
3521 attributes.Mask |= VLLIST_SERVER;
3524 if (as->parms[3].items) { /* -partition */
3525 if (!as->parms[2].items) {
3527 "You must provide -server with the -partition argument\n");
3530 apart = volutil_GetPartitionID(as->parms[3].items->data);
3532 fprintf(STDERR, "vos: could not interpret partition name '%s'\n",
3533 as->parms[3].items->data);
3536 attributes.partition = apart;
3537 attributes.Mask |= VLLIST_PARTITION;
3540 /* Print status line of what we are doing */
3541 fprintf(STDOUT, "Deleting VLDB entries for ");
3542 if (as->parms[2].items) {
3543 fprintf(STDOUT, "server %s ", as->parms[2].items->data);
3545 if (as->parms[3].items) {
3547 MapPartIdIntoName(apart, pname);
3548 fprintf(STDOUT, "partition %s ", pname);
3551 fprintf(STDOUT, "which are prefixed with %s ", prefix);
3553 fprintf(STDOUT, "\n");
3556 /* Get all the VLDB entries on a server and/or partition */
3557 memset(&arrayEntries, 0, sizeof(arrayEntries));
3558 vcode = VLDB_ListAttributes(&attributes, &nentries, &arrayEntries);
3560 fprintf(STDERR, "Could not access the VLDB for attributes\n");
3561 PrintError("", vcode);
3565 /* Process each entry */
3566 for (j = 0; j < nentries; j++) {
3567 vllist = &arrayEntries.nbulkentries_val[j];
3569 /* It only deletes the RW volumes */
3570 if (strncmp(vllist->name, prefix, strlen(prefix))) {
3573 "Omitting to delete %s due to prefix %s mismatch\n",
3574 vllist->name, prefix);
3581 if (as->parms[4].items) { /* -noexecute */
3582 fprintf(STDOUT, "Would have deleted VLDB entry for %s \n",
3588 /* Only matches the RW volume name */
3589 avolid = vllist->volumeId[RWVOL];
3590 vcode = ubik_Call(VL_DeleteEntry, cstruct, 0, avolid, RWVOL);
3592 fprintf(STDOUT, "Could not delete VDLB entry for %s\n",
3595 PrintError("", vcode);
3600 fprintf(STDOUT, "Deleted VLDB entry for %s \n", vllist->name);
3605 fprintf(STDOUT, "----------------------\n");
3607 "Total VLDB entries deleted: %lu; failed to delete: %lu\n",
3608 (unsigned long)totalBack, (unsigned long)totalFail);
3609 if (arrayEntries.nbulkentries_val)
3610 free(arrayEntries.nbulkentries_val);
3616 CompareVldbEntryByName(p1, p2)
3619 struct nvldbentry *arg1, *arg2;
3621 arg1 = (struct nvldbentry *)p1;
3622 arg2 = (struct nvldbentry *)p2;
3623 return (strcmp(arg1->name, arg2->name));
3627 static int CompareVldbEntry(p1,p2)
3630 struct nvldbentry *arg1,*arg2;
3633 char comp1[100],comp2[100];
3634 char temp1[20],temp2[20];
3636 arg1 = (struct nvldbentry *)p1;
3637 arg2 = (struct nvldbentry *)p2;
3641 for(i = 0; i < arg1->nServers; i++)
3642 if(arg1->serverFlags[i] & ITSRWVOL) pos1 = i;
3643 for(i = 0; i < arg2->nServers; i++)
3644 if(arg2->serverFlags[i] & ITSRWVOL) pos2 = i;
3645 if(pos1 == -1 || pos2 == -1){
3649 sprintf(comp1,"%10u",arg1->serverNumber[pos1]);
3650 sprintf(comp2,"%10u",arg2->serverNumber[pos2]);
3651 sprintf(temp1,"%10u",arg1->serverPartition[pos1]);
3652 sprintf(temp2,"%10u",arg2->serverPartition[pos2]);
3653 strcat(comp1,temp1);
3654 strcat(comp2,temp2);
3655 strcat(comp1,arg1->name);
3656 strcat(comp1,arg2->name);
3657 return(strcmp(comp1,comp2));
3664 struct cmd_syndesc *as;
3667 afs_int32 aserver, code;
3669 struct VldbListByAttributes attributes;
3670 nbulkentries arrayEntries;
3671 struct nvldbentry *vllist, *tarray = 0, *ttarray;
3672 afs_int32 centries, nentries = 0, tarraysize, parraysize;
3675 int quiet, sort, lock;
3676 afs_int32 thisindex, nextindex;
3681 attributes.Mask = 0;
3682 lock = (as->parms[3].items ? 1 : 0); /* -lock flag */
3683 quiet = (as->parms[4].items ? 1 : 0); /* -quit flag */
3684 sort = (as->parms[5].items ? 0 : 1); /* -nosort flag */
3686 /* If the volume name is given, Use VolumeInfoCmd to look it up
3687 * and not ListAttributes.
3689 if (as->parms[0].items) {
3692 "vos: illegal use of '-locked' switch, need to specify server and/or partition\n");
3695 code = VolumeInfoCmd(as->parms[0].items->data);
3697 PrintError("", code);
3703 /* Server specified */
3704 if (as->parms[1].items) {
3705 aserver = GetServer(as->parms[1].items->data);
3707 fprintf(STDERR, "vos: server '%s' not found in host table\n",
3708 as->parms[1].items->data);
3711 attributes.server = ntohl(aserver);
3712 attributes.Mask |= VLLIST_SERVER;
3715 /* Partition specified */
3716 if (as->parms[2].items) {
3717 apart = volutil_GetPartitionID(as->parms[2].items->data);
3719 fprintf(STDERR, "vos: could not interpret partition name '%s'\n",
3720 as->parms[2].items->data);
3723 attributes.partition = apart;
3724 attributes.Mask |= VLLIST_PARTITION;
3728 attributes.Mask |= VLLIST_FLAG;
3729 attributes.flag = VLOP_ALLOPERS;
3732 /* Print header information */
3734 MapPartIdIntoName(apart, pname);
3735 fprintf(STDOUT, "VLDB entries for %s %s%s%s %s\n",
3736 (as->parms[1].items ? "server" : "all"),
3737 (as->parms[1].items ? as->parms[1].items->data : "servers"),
3738 (as->parms[2].items ? " partition " : ""),
3739 (as->parms[2].items ? pname : ""),
3740 (lock ? "which are locked:" : ""));
3743 for (thisindex = 0; (thisindex != -1); thisindex = nextindex) {
3744 memset(&arrayEntries, 0, sizeof(arrayEntries));
3749 VLDB_ListAttributesN2(&attributes, 0, thisindex, ¢ries,
3750 &arrayEntries, &nextindex);
3751 if (vcode == RXGEN_OPCODE) {
3752 /* Vlserver not running with ListAttributesN2. Fall back */
3754 VLDB_ListAttributes(&attributes, ¢ries, &arrayEntries);
3758 fprintf(STDERR, "Could not access the VLDB for attributes\n");
3759 PrintError("", vcode);
3762 nentries += centries;
3764 /* We don't sort, so just print the entries now */
3766 for (j = 0; j < centries; j++) { /* process each entry */
3767 vllist = &arrayEntries.nbulkentries_val[j];
3768 MapHostToNetwork(vllist);
3769 EnumerateEntry(vllist);
3771 if (vllist->flags & VLOP_ALLOPERS)
3772 fprintf(STDOUT, " Volume is currently LOCKED \n");
3776 /* So we sort. First we must collect all the entries and keep
3779 else if (centries > 0) {
3781 /* steal away the first bulk entries array */
3782 tarray = (struct nvldbentry *)arrayEntries.nbulkentries_val;
3783 tarraysize = centries * sizeof(struct nvldbentry);
3784 arrayEntries.nbulkentries_val = 0;
3786 /* Grow the tarray to keep the extra entries */
3787 parraysize = (centries * sizeof(struct nvldbentry));
3789 (struct nvldbentry *)realloc(tarray,
3790 tarraysize + parraysize);
3793 "Could not allocate enough space for the VLDB entries\n");
3799 memcpy(((char *)tarray) + tarraysize,
3800 (char *)arrayEntries.nbulkentries_val, parraysize);
3801 tarraysize += parraysize;
3805 /* Free the bulk array */
3806 if (arrayEntries.nbulkentries_val) {
3807 free(arrayEntries.nbulkentries_val);
3808 arrayEntries.nbulkentries_val = 0;
3812 /* Here is where we now sort all the entries and print them */
3813 if (sort && (nentries > 0)) {
3814 qsort((char *)tarray, nentries, sizeof(struct nvldbentry),
3815 CompareVldbEntryByName);
3816 for (vllist = tarray, j = 0; j < nentries; j++, vllist++) {
3817 MapHostToNetwork(vllist);
3818 EnumerateEntry(vllist);
3820 if (vllist->flags & VLOP_ALLOPERS)
3821 fprintf(STDOUT, " Volume is currently LOCKED \n");
3827 fprintf(STDOUT, "\nTotal entries: %lu\n", (unsigned long)nentries);
3835 register struct cmd_syndesc *as;
3837 afs_int32 apart = 0, avolid;
3838 afs_int32 aserver = 0, code, aserver1, apart1;
3840 struct VldbListByAttributes attributes;
3841 nbulkentries arrayEntries;
3842 register struct nvldbentry *vllist;
3846 int seenprefix, seenxprefix, exclude, ex, exp, noaction;
3847 afs_int32 totalBack = 0;
3848 afs_int32 totalFail = 0;
3849 int previdx = -1, error, same;
3851 struct cmd_item *ti;
3855 memset(&attributes, 0, sizeof(struct VldbListByAttributes));
3856 attributes.Mask = 0;
3858 seenprefix = (as->parms[0].items ? 1 : 0);
3859 exclude = (as->parms[3].items ? 1 : 0);
3860 seenxprefix = (as->parms[4].items ? 1 : 0);
3861 noaction = (as->parms[5].items ? 1 : 0);
3863 if (as->parms[1].items) { /* -server */
3864 aserver = GetServer(as->parms[1].items->data);
3866 fprintf(STDERR, "vos: server '%s' not found in host table\n",
3867 as->parms[1].items->data);
3870 attributes.server = ntohl(aserver);
3871 attributes.Mask |= VLLIST_SERVER;
3874 if (as->parms[2].items) { /* -partition */
3875 apart = volutil_GetPartitionID(as->parms[2].items->data);
3877 fprintf(STDERR, "vos: could not interpret partition name '%s'\n",
3878 as->parms[2].items->data);
3881 attributes.partition = apart;
3882 attributes.Mask |= VLLIST_PARTITION;
3885 /* Check to make sure the prefix and xprefix expressions compile ok */
3887 for (ti = as->parms[0].items; ti; ti = ti->next) {
3888 if (strncmp(ti->data, "^", 1) == 0) {
3889 #ifdef HAVE_POSIX_REGEX
3893 code = regcomp(&re, ti->data, REG_NOSUB);
3895 regerror(code, &re, errbuf, sizeof errbuf);
3897 "Unrecognizable -prefix regular expression: '%s': %s\n",
3903 ccode = (char *)re_comp(ti->data);
3906 "Unrecognizable -prefix regular expression: '%s': %s\n",
3915 for (ti = as->parms[4].items; ti; ti = ti->next) {
3916 if (strncmp(ti->data, "^", 1) == 0) {
3917 #ifdef HAVE_POSIX_REGEX
3921 code = regcomp(&re, ti->data, REG_NOSUB);
3923 regerror(code, &re, errbuf, sizeof errbuf);
3925 "Unrecognizable -xprefix regular expression: '%s': %s\n",
3931 ccode = (char *)re_comp(ti->data);
3934 "Unrecognizable -xprefix regular expression: '%s': %s\n",
3943 memset(&arrayEntries, 0, sizeof(arrayEntries)); /* initialize to hint the stub to alloc space */
3944 vcode = VLDB_ListAttributes(&attributes, &nentries, &arrayEntries);
3946 fprintf(STDERR, "Could not access the VLDB for attributes\n");
3947 PrintError("", vcode);
3951 if (as->parms[1].items || as->parms[2].items || verbose) {
3952 fprintf(STDOUT, "%s up volumes",
3953 (noaction ? "Would have backed" : "Backing"));
3955 if (as->parms[1].items) {
3956 fprintf(STDOUT, " on server %s", as->parms[1].items->data);
3957 } else if (as->parms[2].items) {
3958 fprintf(STDOUT, " for all servers");
3961 if (as->parms[2].items) {
3962 MapPartIdIntoName(apart, pname);
3963 fprintf(STDOUT, " partition %s", pname);
3966 if (seenprefix || (!seenprefix && seenxprefix)) {
3967 ti = (seenprefix ? as->parms[0].items : as->parms[4].items);
3968 ex = (seenprefix ? exclude : !exclude);
3969 exp = (strncmp(ti->data, "^", 1) == 0);
3970 fprintf(STDOUT, " which %smatch %s '%s'", (ex ? "do not " : ""),
3971 (exp ? "expression" : "prefix"), ti->data);
3972 for (ti = ti->next; ti; ti = ti->next) {
3973 exp = (strncmp(ti->data, "^", 1) == 0);
3974 printf(" %sor %s '%s'", (ex ? "n" : ""),
3975 (exp ? "expression" : "prefix"), ti->data);
3979 if (seenprefix && seenxprefix) {
3980 ti = as->parms[4].items;
3981 exp = (strncmp(ti->data, "^", 1) == 0);
3982 fprintf(STDOUT, " %swhich match %s '%s'",
3983 (exclude ? "adding those " : "removing those "),
3984 (exp ? "expression" : "prefix"), ti->data);
3985 for (ti = ti->next; ti; ti = ti->next) {
3986 exp = (strncmp(ti->data, "^", 1) == 0);
3987 printf(" or %s '%s'", (exp ? "expression" : "prefix"),
3991 fprintf(STDOUT, " .. ");
3993 fprintf(STDOUT, "\n");
3997 for (j = 0; j < nentries; j++) { /* process each vldb entry */
3998 vllist = &arrayEntries.nbulkentries_val[j];
4001 for (ti = as->parms[0].items; ti; ti = ti->next) {
4002 if (strncmp(ti->data, "^", 1) == 0) {
4003 #ifdef HAVE_POSIX_REGEX
4007 /* XXX -- should just do the compile once! */
4008 code = regcomp(&re, ti->data, REG_NOSUB);
4010 regerror(code, &re, errbuf, sizeof errbuf);
4012 "Error in -prefix regular expression: '%s': %s\n",
4016 match = (regexec(&re, vllist->name, 0, NULL, 0) == 0);
4019 ccode = (char *)re_comp(ti->data);
4022 "Error in -prefix regular expression: '%s': %s\n",
4026 match = (re_exec(vllist->name) == 1);
4030 (strncmp(vllist->name, ti->data, strlen(ti->data)) ==
4040 /* Without the -exclude flag: If it matches the prefix, then
4041 * check if we want to exclude any from xprefix.
4042 * With the -exclude flag: If it matches the prefix, then
4043 * check if we want to add any from xprefix.
4045 if (match && seenxprefix) {
4046 for (ti = as->parms[4].items; ti; ti = ti->next) {
4047 if (strncmp(ti->data, "^", 1) == 0) {
4048 #ifdef HAVE_POSIX_REGEX
4052 /* XXX -- should just do the compile once! */
4053 code = regcomp(&re, ti->data, REG_NOSUB);
4055 regerror(code, &re, errbuf, sizeof errbuf);
4057 "Error in -xprefix regular expression: '%s': %s\n",
4061 if (regexec(&re, vllist->name, 0, NULL, 0) == 0)
4065 ccode = (char *)re_comp(ti->data);
4068 "Error in -xprefix regular expression: '%s': %s\n",
4072 if (re_exec(vllist->name) == 1) {
4078 if (strncmp(vllist->name, ti->data, strlen(ti->data)) ==
4088 match = !match; /* -exclude will reverse the match */
4090 continue; /* Skip if no match */
4092 /* Print list of volumes to backup */
4094 fprintf(STDOUT, " %s\n", vllist->name);
4098 if (!(vllist->flags & RW_EXISTS)) {
4101 "Omitting to backup %s since RW volume does not exist \n",
4103 fprintf(STDOUT, "\n");
4109 avolid = vllist->volumeId[RWVOL];
4110 MapHostToNetwork(vllist);
4111 GetServerAndPart(vllist, RWVOL, &aserver1, &apart1, &previdx);
4112 if (aserver1 == -1 || apart1 == -1) {
4113 fprintf(STDOUT, "could not backup %s, invalid VLDB entry\n",
4119 same = VLDB_IsSameAddrs(aserver, aserver1, &error);
4122 "Failed to get info about server's %d address(es) from vlserver (err=%d); aborting call!\n",
4128 if ((aserver && !same) || (apart && (apart != apart1))) {
4131 "Omitting to backup %s since the RW is in a different location\n",
4137 time_t now = time(0);
4138 fprintf(STDOUT, "Creating backup volume for %s on %s",
4139 vllist->name, ctime(&now));
4143 code = UV_BackupVolume(aserver1, apart1, avolid);
4145 fprintf(STDOUT, "Could not backup %s\n", vllist->name);
4151 fprintf(STDOUT, "\n");
4153 } /* process each vldb entry */
4154 fprintf(STDOUT, "done\n");
4155 fprintf(STDOUT, "Total volumes backed up: %lu; failed to backup: %lu\n",
4156 (unsigned long)totalBack, (unsigned long)totalFail);
4158 if (arrayEntries.nbulkentries_val)
4159 free(arrayEntries.nbulkentries_val);
4165 register struct cmd_syndesc *as;
4168 afs_int32 aserver, code;
4170 struct VldbListByAttributes attributes;
4171 nbulkentries arrayEntries;
4172 register struct nvldbentry *vllist;
4181 attributes.Mask = 0;
4183 if (as->parms[0].items) { /* server specified */
4184 aserver = GetServer(as->parms[0].items->data);
4186 fprintf(STDERR, "vos: server '%s' not found in host table\n",
4187 as->parms[0].items->data);
4190 attributes.server = ntohl(aserver);
4191 attributes.Mask |= VLLIST_SERVER;
4193 if (as->parms[1].items) { /* partition specified */
4194 apart = volutil_GetPartitionID(as->parms[1].items->data);
4196 fprintf(STDERR, "vos: could not interpret partition name '%s'\n",
4197 as->parms[1].items->data);
4200 if (!IsPartValid(apart, aserver, &code)) { /*check for validity of the partition */
4202 PrintError("", code);
4205 "vos : partition %s does not exist on the server\n",
4206 as->parms[1].items->data);
4209 attributes.partition = apart;
4210 attributes.Mask |= VLLIST_PARTITION;
4212 attributes.flag = VLOP_ALLOPERS;
4213 attributes.Mask |= VLLIST_FLAG;
4214 memset(&arrayEntries, 0, sizeof(arrayEntries)); /*initialize to hint the stub to alloc space */
4215 vcode = VLDB_ListAttributes(&attributes, &nentries, &arrayEntries);
4217 fprintf(STDERR, "Could not access the VLDB for attributes\n");
4218 PrintError("", vcode);
4221 for (j = 0; j < nentries; j++) { /* process each entry */
4222 vllist = &arrayEntries.nbulkentries_val[j];
4223 volid = vllist->volumeId[RWVOL];
4225 ubik_Call(VL_ReleaseLock, cstruct, 0, volid, -1,
4226 LOCKREL_OPCODE | LOCKREL_AFSID | LOCKREL_TIMESTAMP);
4228 fprintf(STDERR, "Could not unlock entry for volume %s\n",
4230 PrintError("", vcode);
4235 MapPartIdIntoName(apart, pname);
4238 "Could not lock %lu VLDB entries of %lu locked entries\n",
4239 (unsigned long)totalE, (unsigned long)nentries);
4241 if (as->parms[0].items) {
4243 "Unlocked all the VLDB entries for volumes on server %s ",
4244 as->parms[0].items->data);
4245 if (as->parms[1].items) {
4246 MapPartIdIntoName(apart, pname);
4247 fprintf(STDOUT, "partition %s\n", pname);
4249 fprintf(STDOUT, "\n");
4251 } else if (as->parms[1].items) {
4252 MapPartIdIntoName(apart, pname);
4254 "Unlocked all the VLDB entries for volumes on partition %s on all servers\n",
4259 if (arrayEntries.nbulkentries_val)
4260 free(arrayEntries.nbulkentries_val);
4266 register struct cmd_syndesc *as;
4269 afs_int32 aserver, code;
4271 struct diskPartition partition;
4272 struct partList dummyPartList;
4276 aserver = GetServer(as->parms[0].items->data);
4278 fprintf(STDERR, "vos: server '%s' not found in host table\n",
4279 as->parms[0].items->data);
4282 if (as->parms[1].items) {
4283 apart = volutil_GetPartitionID(as->parms[1].items->data);
4285 fprintf(STDERR, "vos: could not interpret partition name '%s'\n",
4286 as->parms[1].items->data);
4289 dummyPartList.partId[0] = apart;
4290 dummyPartList.partFlags[0] = PARTVALID;
4294 if (!IsPartValid(apart, aserver, &code)) { /*check for validity of the partition */
4296 PrintError("", code);
4299 "vos : partition %s does not exist on the server\n",
4300 as->parms[1].items->data);
4304 code = UV_ListPartitions(aserver, &dummyPartList, &cnt);
4306 PrintDiagnostics("listpart", code);
4310 for (i = 0; i < cnt; i++) {
4311 if (dummyPartList.partFlags[i] & PARTVALID) {
4312 MapPartIdIntoName(dummyPartList.partId[i], pname);
4313 code = UV_PartitionInfo(aserver, pname, &partition);
4315 fprintf(STDERR, "Could not get information on partition %s\n",