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>
15 #include <sys/types.h>
24 #include <netinet/in.h>
28 #include <sys/statfs.h>
44 #include <rx/rx_globals.h>
46 #include <afs/vlserver.h>
48 #include <afs/cellconfig.h>
50 #include <afs/afsutil.h>
52 #include <afs/afsint.h>
74 struct hostent *hostutil_GetHostByName(register char *ahost);
76 #define COMMONPARMS cmd_Seek(ts, 12);\
77 cmd_AddParm(ts, "-cell", CMD_SINGLE, CMD_OPTIONAL, "cell name");\
78 cmd_AddParm(ts, "-noauth", CMD_FLAG, CMD_OPTIONAL, "don't authenticate");\
79 cmd_AddParm(ts, "-localauth",CMD_FLAG,CMD_OPTIONAL,"use server tickets");\
80 cmd_AddParm(ts, "-verbose", CMD_FLAG, CMD_OPTIONAL, "verbose");\
81 cmd_AddParm(ts, "-encrypt", CMD_FLAG, CMD_OPTIONAL, "encrypt commands");\
83 #define ERROR_EXIT(code) {error=(code); goto error_exit;}
87 struct rx_connection *tconn;
89 extern struct ubik_client *cstruct;
91 extern struct rx_connection *UV_Bind();
92 extern int UV_SetSecurity();
93 extern int UV_SetVolumeInfo();
94 extern int vsu_SetCrypt();
96 extern VL_ReleaseLock();
97 extern VL_DeleteEntry();
98 extern VL_ListEntry();
100 extern VL_GetAddrsU();
101 extern VL_ChangeAddr();
103 extern int vsu_ExtractName();
105 extern int MapPartIdIntoName();
106 extern int MapHostToNetwork();
107 extern int MapNetworkToHost();
108 extern void EnumerateEntry();
109 extern void SubEnumerateEntry();
112 static struct tqHead busyHead, notokHead;
114 static void qInit(ahead)
115 struct tqHead *ahead;
117 memset((char *)ahead, 0, sizeof(struct tqHead));
122 static void qPut(ahead,volid)
123 struct tqHead *ahead;
128 elem = (struct tqElem *)malloc(sizeof(struct tqElem));
129 elem->next = ahead->next;
136 static void qGet(ahead,volid)
137 struct tqHead *ahead;
142 if(ahead->count <= 0) return;
143 *volid = ahead->next->volid;
145 ahead->next = tmp->next;
151 /* returns 1 if <filename> exists else 0 */
152 static FileExists(filename)
159 code = usd_Open(filename, USD_OPEN_RDONLY, 0, &ufd);
163 code = USD_IOCTL(ufd, USD_IOCTL_GETSIZE, &size);
171 /* returns 1 if <name> doesnot end in .readonly or .backup, else 0 */
172 static VolNameOK(name)
178 total = strlen(name);
179 if(!strcmp(&name[total - 9],".readonly")) {
182 else if(!strcmp(&name[total - 7 ],".backup")) {
190 /* return 1 if name is a number else 0 */
191 static IsNumeric(name)
200 for(i = 0; i < len ; i++){
201 if(*ptr < '0' || *ptr > '9'){
215 * Parse a server name/address and return the address in HOST BYTE order
217 afs_int32 GetServer(aname)
219 register struct hostent *th;
222 register afs_int32 code;
223 char hostname[MAXHOSTCHARS];
225 code = sscanf(aname, "%d.%d.%d.%d", &b1, &b2, &b3, &b4);
227 addr = (b1<<24) | (b2<<16) | (b3<<8) | b4;
228 addr = ntohl(addr); /* convert to host order */
230 th = gethostbyname(aname);
232 memcpy(&addr, th->h_addr, sizeof(addr));
235 if (addr == htonl(0x7f000001)) { /* local host */
236 code = gethostname(hostname, MAXHOSTCHARS);
238 th = gethostbyname(hostname); /* returns host byte order */
240 memcpy(&addr, th->h_addr, sizeof(addr));
246 afs_int32 GetVolumeType(aname)
250 if(!strcmp(aname,"ro"))
252 else if(!strcmp(aname, "rw"))
254 else if(!strcmp(aname,"bk"))
259 int IsPartValid(partId, server, code)
260 afs_int32 server, partId,*code;
263 struct partList dummyPartList;
271 *code = UV_ListPartitions(server,&dummyPartList, &cnt);
272 if(*code) return success;
273 for(i = 0 ; i < cnt ; i++) {
274 if(dummyPartList.partFlags[i] & PARTVALID)
275 if(dummyPartList.partId[i] == partId)
283 /*sends the contents of file associated with <fd> and <blksize> to Rx Stream
284 * associated with <call> */
285 SendFile(ufd, call, blksize)
287 register struct rx_call *call;
290 char *buffer = (char*) 0;
295 buffer = (char *)malloc(blksize);
297 fprintf(STDERR,"malloc failed\n");
301 while (!error && !done) {
302 #ifndef AFS_NT40_ENV /* NT csn't select on non-socket fd's */
305 FD_SET((int)(ufd->handle), &in);
306 /* don't timeout if read blocks */
307 IOMGR_Select(((int)(ufd->handle))+1, &in, 0, 0, 0);
309 error = USD_READ(ufd, buffer, blksize, &nbytes);
311 fprintf(STDERR, "File system read failed\n");
318 if (rx_Write(call, buffer, nbytes) != nbytes){
323 if (buffer) free(buffer);
327 /* function invoked by UV_RestoreVolume, reads the data from rx_trx_stream and
328 * writes it out to the volume. */
329 afs_int32 WriteData(call,rock)
330 struct rx_call *call;
336 afs_int32 error,code;
342 if(!filename || !*filename) {
343 usd_StandardInput(&ufd);
347 code = usd_Open(filename, USD_OPEN_RDONLY, 0, &ufd);
350 code = USD_IOCTL(ufd, USD_IOCTL_GETBLKSIZE, &blksize);
353 fprintf(STDERR,"Could not access file '%s'\n", filename);
358 code = SendFile(ufd,call,blksize);
365 code = USD_CLOSE(ufd);
367 fprintf(STDERR,"Could not close dump file %s\n",
368 (filename && *filename)?filename:"STDOUT");
369 if(!error) error = code;
375 /* Receive data from <call> stream into file associated
376 * with <fd> <blksize>
378 int ReceiveFile(ufd, call, blksize)
380 struct rx_call *call;
385 afs_uint32 bytesleft, w;
388 buffer = (char *)malloc(blksize);
390 fprintf(STDERR,"memory allocation failed\n");
394 while ((bytesread=rx_Read(call,buffer,blksize)) > 0) {
395 for (bytesleft=bytesread; bytesleft; bytesleft-=w) {
396 #ifndef AFS_NT40_ENV /* NT csn't select on non-socket fd's */
399 FD_SET((int)(ufd->handle), &out);
400 /* don't timeout if write blocks */
401 IOMGR_Select(((int)(ufd->handle))+1, 0, &out, 0, 0);
403 error = USD_WRITE(ufd, &buffer[bytesread-bytesleft], bytesleft, &w);
405 fprintf(STDERR,"File system write failed\n");
412 if (buffer) free(buffer);
416 afs_int32 DumpFunction(call, filename)
417 struct rx_call *call;
420 usd_handle_t ufd; /* default is to stdout */
421 afs_int32 error=0, code;
426 /* Open the output file */
427 if (!filename || !*filename) {
428 usd_StandardOutput(&ufd);
432 code = usd_Open(filename, USD_OPEN_CREATE|USD_OPEN_RDWR, 0666, &ufd);
436 code = USD_IOCTL(ufd, USD_IOCTL_SETSIZE, &size);
439 code = USD_IOCTL(ufd, USD_IOCTL_GETBLKSIZE, &blksize);
442 fprintf(STDERR, "Could not create file '%s'\n", filename);
443 ERROR_EXIT(VOLSERBADOP);
447 code = ReceiveFile(ufd, call, blksize);
448 if (code) ERROR_EXIT(code);
451 /* Close the output file */
453 code = USD_CLOSE(ufd);
455 fprintf(STDERR,"Could not close dump file %s\n",
456 (filename && *filename)?filename:"STDIN");
457 if (!error) error = code;
464 static void DisplayFormat(pntr,server,part,totalOK,totalNotOK,totalBusy,fast,longlist,disp)
466 afs_int32 server,part;
467 int *totalOK,*totalNotOK,*totalBusy;
468 int fast,longlist, disp;
473 fprintf(STDOUT,"%-10u\n",pntr->volid);
476 if(pntr->status == VOK){
477 fprintf(STDOUT,"%-32s ",pntr->name);
478 fprintf(STDOUT,"%10u ",pntr->volid);
479 if(pntr->type == 0) fprintf(STDOUT,"RW ");
480 if(pntr->type == 1) fprintf(STDOUT,"RO ");
481 if(pntr->type == 2) fprintf(STDOUT,"BK ");
482 fprintf(STDOUT,"%10d K ",pntr->size);
483 if(pntr->inUse == 1) {
484 fprintf(STDOUT,"On-line");
487 fprintf(STDOUT,"Off-line");
490 if(pntr->needsSalvaged == 1) fprintf(STDOUT,"**needs salvage**");
491 fprintf(STDOUT,"\n");
492 MapPartIdIntoName(part,pname);
493 fprintf(STDOUT," %s %s \n",hostutil_GetNameByINet(server),pname);
494 fprintf(STDOUT," RWrite %10u ROnly %10u Backup %10u \n", pntr->parentID,pntr->cloneID, pntr->backupID);
495 fprintf(STDOUT," MaxQuota %10d K \n",pntr->maxquota);
496 fprintf(STDOUT," Creation %s",
497 ctime((time_t *)&pntr->creationDate));
498 #ifdef FULL_LISTVOL_SWITCH
499 fprintf(STDOUT," Copy %s",
500 ctime((time_t *)&pntr->copyDate));
501 if(!pntr->backupDate)
502 fprintf(STDOUT," Backup Never\n");
504 fprintf(STDOUT," Backup %s",
505 ctime((time_t *)&pntr->backupDate));
506 if (pntr->accessDate)
507 fprintf(STDOUT," Last Access %s",
508 ctime((time_t *)&pntr->accessDate));
510 if(pntr->updateDate < pntr->creationDate)
511 fprintf(STDOUT," Last Update %s",
512 ctime((time_t *)&pntr->creationDate));
514 fprintf(STDOUT," Last Update %s",
515 ctime((time_t *)&pntr->updateDate));
516 fprintf(STDOUT, " %d accesses in the past day (i.e., vnode references)\n",
519 else if (pntr->status == VBUSY) {
521 qPut(&busyHead,pntr->volid);
522 if (disp) fprintf(STDOUT,"**** Volume %u is busy ****\n",pntr->volid);
526 qPut(¬okHead,pntr->volid);
527 if (disp) fprintf(STDOUT,"**** Could not attach volume %u ****\n",pntr->volid);
529 fprintf(STDOUT,"\n");
531 else {/* default listing */
532 if(pntr->status == VOK){
533 fprintf(STDOUT,"%-32s ",pntr->name);
534 fprintf(STDOUT,"%10u ",pntr->volid);
535 if(pntr->type == 0) fprintf(STDOUT,"RW ");
536 if(pntr->type == 1) fprintf(STDOUT,"RO ");
537 if(pntr->type == 2) fprintf(STDOUT,"BK ");
538 fprintf(STDOUT,"%10d K ",pntr->size);
539 if(pntr->inUse == 1) {
540 fprintf(STDOUT,"On-line");
543 fprintf(STDOUT,"Off-line");
546 if(pntr->needsSalvaged == 1) fprintf(STDOUT,"**needs salvage**");
547 fprintf(STDOUT,"\n");
549 else if (pntr->status == VBUSY) {
551 qPut(&busyHead,pntr->volid);
552 if (disp) fprintf(STDOUT,"**** Volume %u is busy ****\n",pntr->volid);
556 qPut(¬okHead,pntr->volid);
557 if (disp) fprintf(STDOUT,"**** Could not attach volume %u ****\n",pntr->volid);
562 /*------------------------------------------------------------------------
563 * PRIVATE XDisplayFormat
566 * Display the contents of one extended volume info structure.
569 * a_xInfoP : Ptr to extended volume info struct to print.
570 * a_servID : Server ID to print.
571 * a_partID : Partition ID to print.
572 * a_totalOKP : Ptr to total-OK counter.
573 * a_totalNotOKP : Ptr to total-screwed counter.
574 * a_totalBusyP : Ptr to total-busy counter.
575 * a_fast : Fast listing?
576 * a_int32 : Int32 listing?
577 * a_showProblems : Show volume problems?
583 * Nothing interesting.
587 *------------------------------------------------------------------------*/
589 static void XDisplayFormat(a_xInfoP, a_servID, a_partID, a_totalOKP,
590 a_totalNotOKP, a_totalBusyP, a_fast, a_int32,
592 volintXInfo *a_xInfoP;
610 fprintf(STDOUT, "%-10u\n", a_xInfoP->volid);
615 * Fully-detailed listing.
617 if (a_xInfoP->status == VOK) {
619 * Volume's status is OK - all the fields are valid.
621 fprintf(STDOUT, "%-32s ", a_xInfoP->name);
622 fprintf(STDOUT, "%10u ", a_xInfoP->volid);
623 if (a_xInfoP->type == 0) fprintf(STDOUT,"RW ");
624 if (a_xInfoP->type == 1) fprintf(STDOUT,"RO ");
625 if (a_xInfoP->type == 2) 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");
633 fprintf(STDOUT, "Off-line");
636 fprintf(STDOUT, "\n");
637 MapPartIdIntoName(a_partID, pname);
638 fprintf(STDOUT, " %s %s \n",
639 hostutil_GetNameByINet(a_servID),
641 fprintf(STDOUT, " RWrite %10u ROnly %10u Backup %10u \n",
642 a_xInfoP->parentID, a_xInfoP->cloneID, a_xInfoP->backupID);
643 fprintf(STDOUT, " MaxQuota %10d K \n",
645 fprintf(STDOUT, " Creation %s",
646 ctime((time_t *)&a_xInfoP->creationDate));
647 #ifdef FULL_LISTVOL_SWITCH
648 fprintf(STDOUT," Copy %s",
649 ctime((time_t *)&a_xInfoP->copyDate));
650 if(!a_xInfoP->backupDate)
651 fprintf(STDOUT," Backup Never\n");
653 fprintf(STDOUT," Backup %s",
654 ctime((time_t *)&a_xInfoP->backupDate));
655 if (a_xInfoP->accessDate)
656 fprintf(STDOUT," Last Access %s",
657 ctime((time_t *)&a_xInfoP->accessDate));
659 if (a_xInfoP->updateDate < a_xInfoP->creationDate)
660 fprintf(STDOUT, " Last Update %s",
661 ctime((time_t *)&a_xInfoP->creationDate));
663 fprintf(STDOUT, " Last Update %s",
664 ctime((time_t *)&a_xInfoP->updateDate));
665 fprintf(STDOUT, " %d accesses in the past day (i.e., vnode references)\n",
669 * Print all the read/write and authorship stats.
672 "\n Raw Read/Write Stats\n");
674 " |-------------------------------------------|\n");
676 " | Same Network | Diff Network |\n");
678 " |----------|----------|----------|----------|\n");
680 " | Total | Auth | Total | Auth |\n");
682 " |----------|----------|----------|----------|\n");
684 "Reads | %8d | %8d | %8d | %8d |\n",
685 a_xInfoP->stat_reads[VOLINT_STATS_SAME_NET],
686 a_xInfoP->stat_reads[VOLINT_STATS_SAME_NET_AUTH],
687 a_xInfoP->stat_reads[VOLINT_STATS_DIFF_NET],
688 a_xInfoP->stat_reads[VOLINT_STATS_DIFF_NET_AUTH]);
690 "Writes | %8d | %8d | %8d | %8d |\n",
691 a_xInfoP->stat_writes[VOLINT_STATS_SAME_NET],
692 a_xInfoP->stat_writes[VOLINT_STATS_SAME_NET_AUTH],
693 a_xInfoP->stat_writes[VOLINT_STATS_DIFF_NET],
694 a_xInfoP->stat_writes[VOLINT_STATS_DIFF_NET_AUTH]);
696 " |-------------------------------------------|\n\n");
699 " Writes Affecting Authorship\n");
701 " |-------------------------------------------|\n");
703 " | File Authorship | Directory Authorship|\n");
705 " |----------|----------|----------|----------|\n");
707 " | Same | Diff | Same | Diff |\n");
709 " |----------|----------|----------|----------|\n");
711 "0-60 sec | %8d | %8d | %8d | %8d |\n",
712 a_xInfoP->stat_fileSameAuthor[VOLINT_STATS_TIME_IDX_0],
713 a_xInfoP->stat_fileDiffAuthor[VOLINT_STATS_TIME_IDX_0],
714 a_xInfoP->stat_dirSameAuthor[VOLINT_STATS_TIME_IDX_0],
715 a_xInfoP->stat_dirDiffAuthor[VOLINT_STATS_TIME_IDX_0]);
717 "1-10 min | %8d | %8d | %8d | %8d |\n",
718 a_xInfoP->stat_fileSameAuthor[VOLINT_STATS_TIME_IDX_1],
719 a_xInfoP->stat_fileDiffAuthor[VOLINT_STATS_TIME_IDX_1],
720 a_xInfoP->stat_dirSameAuthor[VOLINT_STATS_TIME_IDX_1],
721 a_xInfoP->stat_dirDiffAuthor[VOLINT_STATS_TIME_IDX_1]);
723 "10min-1hr | %8d | %8d | %8d | %8d |\n",
724 a_xInfoP->stat_fileSameAuthor[VOLINT_STATS_TIME_IDX_2],
725 a_xInfoP->stat_fileDiffAuthor[VOLINT_STATS_TIME_IDX_2],
726 a_xInfoP->stat_dirSameAuthor[VOLINT_STATS_TIME_IDX_2],
727 a_xInfoP->stat_dirDiffAuthor[VOLINT_STATS_TIME_IDX_2]);
729 "1hr-1day | %8d | %8d | %8d | %8d |\n",
730 a_xInfoP->stat_fileSameAuthor[VOLINT_STATS_TIME_IDX_3],
731 a_xInfoP->stat_fileDiffAuthor[VOLINT_STATS_TIME_IDX_3],
732 a_xInfoP->stat_dirSameAuthor[VOLINT_STATS_TIME_IDX_3],
733 a_xInfoP->stat_dirDiffAuthor[VOLINT_STATS_TIME_IDX_3]);
735 "1day-1wk | %8d | %8d | %8d | %8d |\n",
736 a_xInfoP->stat_fileSameAuthor[VOLINT_STATS_TIME_IDX_4],
737 a_xInfoP->stat_fileDiffAuthor[VOLINT_STATS_TIME_IDX_4],
738 a_xInfoP->stat_dirSameAuthor[VOLINT_STATS_TIME_IDX_4],
739 a_xInfoP->stat_dirDiffAuthor[VOLINT_STATS_TIME_IDX_4]);
741 "> 1wk | %8d | %8d | %8d | %8d |\n",
742 a_xInfoP->stat_fileSameAuthor[VOLINT_STATS_TIME_IDX_5],
743 a_xInfoP->stat_fileDiffAuthor[VOLINT_STATS_TIME_IDX_5],
744 a_xInfoP->stat_dirSameAuthor[VOLINT_STATS_TIME_IDX_5],
745 a_xInfoP->stat_dirDiffAuthor[VOLINT_STATS_TIME_IDX_5]);
747 " |-------------------------------------------|\n");
748 } /*Volume status OK*/
750 if (a_xInfoP->status == VBUSY) {
752 qPut(&busyHead, a_xInfoP->volid);
754 fprintf(STDOUT, "**** Volume %u is busy ****\n",
759 qPut(¬okHead, a_xInfoP->volid);
761 fprintf(STDOUT, "**** Could not attach volume %u ****\n",
764 fprintf(STDOUT,"\n");
770 if (a_xInfoP->status == VOK) {
771 fprintf(STDOUT, "%-32s ", a_xInfoP->name);
772 fprintf(STDOUT, "%10u ", a_xInfoP->volid);
773 if (a_xInfoP->type == 0) fprintf(STDOUT, "RW ");
774 if (a_xInfoP->type == 1) fprintf(STDOUT, "RO ");
775 if (a_xInfoP->type == 2) fprintf(STDOUT, "BK ");
776 fprintf(STDOUT, "%10d K ", a_xInfoP->size);
777 if(a_xInfoP->inUse == 1) {
778 fprintf(STDOUT, "On-line");
781 fprintf(STDOUT, "Off-line");
784 fprintf(STDOUT, "\n");
787 if (a_xInfoP->status == VBUSY) {
789 qPut(&busyHead, a_xInfoP->volid);
791 fprintf(STDOUT,"**** Volume %u is busy ****\n",
796 qPut(¬okHead, a_xInfoP->volid);
798 fprintf(STDOUT,"**** Could not attach volume %u ****\n",
801 } /*Default listing*/
804 #ifdef FULL_LISTVOL_SWITCH
805 static void DisplayFormat2(server, partition, pntr)
806 long server, partition;
809 static long server_cache = -1, partition_cache = -1;
810 static char hostname[256],
814 if (server != server_cache) {
818 strcpy(hostname, hostutil_GetNameByINet(server));
819 strcpy(address, inet_ntoa(s));
820 server_cache = server;
822 if (partition != partition_cache) {
823 MapPartIdIntoName(partition, pname);
824 partition_cache = partition;
826 fprintf(STDOUT, "name\t\t%s\n", pntr->name);
827 fprintf(STDOUT, "id\t\t%lu\n", pntr->volid);
828 fprintf(STDOUT, "serv\t\t%s\t%s\n", address, hostname);
829 fprintf(STDOUT, "part\t\t%s\n", pname);
830 switch (pntr->status) {
832 fprintf(STDOUT, "status\t\tOK\n");
835 fprintf(STDOUT, "status\t\tBUSY\n");
838 fprintf(STDOUT, "status\t\tUNATTACHABLE\n");
841 fprintf(STDOUT, "backupID\t%lu\n", pntr->backupID);
842 fprintf(STDOUT, "parentID\t%lu\n", pntr->parentID);
843 fprintf(STDOUT, "cloneID\t\t%lu\n", pntr->cloneID);
844 fprintf(STDOUT, "inUse\t\t%s\n", pntr->inUse ? "Y" : "N");
845 fprintf(STDOUT, "needsSalvaged\t%s\n", pntr->needsSalvaged ? "Y" : "N");
846 /* 0xD3 is from afs/volume.h since I had trouble including the file */
847 fprintf(STDOUT, "destroyMe\t%s\n", pntr->destroyMe == 0xD3 ? "Y" : "N");
848 switch (pntr->type) {
850 fprintf(STDOUT, "type\t\tRW\n");
853 fprintf(STDOUT, "type\t\tRO\n");
856 fprintf(STDOUT, "type\t\tBK\n");
859 fprintf(STDOUT, "type\t\t?\n");
862 fprintf(STDOUT, "creationDate\t%-9lu\t%s", pntr->creationDate, ctime(&pntr->creationDate));
863 fprintf(STDOUT, "accessDate\t%-9lu\t%s", pntr->accessDate, ctime(&pntr->accessDate));
864 fprintf(STDOUT, "updateDate\t%-9lu\t%s", pntr->updateDate, ctime(&pntr->updateDate));
865 fprintf(STDOUT, "backupDate\t%-9lu\t%s", pntr->backupDate, ctime(&pntr->backupDate));
866 fprintf(STDOUT, "copyDate\t%-9lu\t%s", pntr->copyDate, ctime(&pntr->copyDate));
867 fprintf(STDOUT, "flags\t\t%#lx\t(Optional)\n", pntr->flags);
868 fprintf(STDOUT, "diskused\t%u\n", pntr->size);
869 fprintf(STDOUT, "maxquota\t%u\n", pntr->maxquota);
870 fprintf(STDOUT, "minquota\t%lu\t(Optional)\n", pntr->spare0);
871 fprintf(STDOUT, "filecount\t%u\n", pntr->filecount);
872 fprintf(STDOUT, "dayUse\t\t%u\n", pntr->dayUse);
873 fprintf(STDOUT, "weekUse\t\t%lu\t(Optional)\n", pntr->spare1);
874 fprintf(STDOUT, "spare2\t\t%lu\t(Optional)\n", pntr->spare2);
875 fprintf(STDOUT, "spare3\t\t%lu\t(Optional)\n", pntr->spare3);
879 static void DisplayVolumes2(server, partition, pntr, count)
881 long server, partition, count;
885 for (i = 0; i < count; i++) {
886 fprintf(STDOUT, "BEGIN_OF_ENTRY\n");
887 DisplayFormat2(server, partition, pntr);
888 fprintf(STDOUT, "END_OF_ENTRY\n\n");
893 #endif /* FULL_LISTVOL_SWITCH */
895 static void DisplayVolumes(server,part,pntr,count,longlist,fast,quiet)
896 afs_int32 server,part;
898 afs_int32 count,longlist,fast;
901 int totalOK,totalNotOK,totalBusy, i;
909 for(i = 0; i < count; i++){
910 DisplayFormat(pntr,server,part,&totalOK,&totalNotOK,&totalBusy,fast,longlist,0);
914 while(busyHead.count){
915 qGet(&busyHead,&volid);
916 fprintf(STDOUT,"**** Volume %u is busy ****\n",volid);
920 while(notokHead.count){
921 qGet(¬okHead,&volid);
922 fprintf(STDOUT,"**** Could not attach volume %u ****\n",volid);
926 fprintf(STDOUT,"\n");
928 fprintf(STDOUT,"Total volumes onLine %d ; Total volumes offLine %d ; Total busy %d\n\n",totalOK,totalNotOK,totalBusy);
933 /*------------------------------------------------------------------------
934 * PRIVATE XDisplayVolumes
937 * Display extended volume information.
940 * a_servID : Pointer to the Rx call we're performing.
941 * a_partID : Partition for which we want the extended list.
942 * a_xInfoP : Ptr to extended volume info.
943 * a_count : Number of volume records contained above.
944 * a_int32 : Int32 listing generated?
945 * a_fast : Fast listing generated?
946 * a_quiet : Quiet listing generated?
952 * Nothing interesting.
956 *------------------------------------------------------------------------*/
958 static void XDisplayVolumes(a_servID, a_partID, a_xInfoP,
959 a_count, a_int32, a_fast, a_quiet)
962 volintXInfo *a_xInfoP;
968 { /*XDisplayVolumes*/
970 int totalOK; /*Total OK volumes*/
971 int totalNotOK; /*Total screwed volumes*/
972 int totalBusy; /*Total busy volumes*/
973 int i; /*Loop variable*/
974 afs_int32 volid; /*Current volume ID*/
977 * Initialize counters and (global!!) queues.
986 * Display each volume in the list.
988 for(i = 0; i < a_count; i++) {
989 XDisplayFormat(a_xInfoP,
1002 * If any volumes were found to be busy or screwed, display them.
1005 while (busyHead.count) {
1006 qGet(&busyHead, &volid);
1007 fprintf(STDOUT, "**** Volume %u is busy ****\n", volid);
1011 while (notokHead.count) {
1012 qGet(¬okHead, &volid);
1013 fprintf(STDOUT, "**** Could not attach volume %u ****\n", volid);
1018 fprintf(STDOUT, "\n");
1021 "Total volumes: %d on-line, %d off-line, %d busyd\n\n",
1022 totalOK, totalNotOK, totalBusy);
1026 } /*XDisplayVolumes*/
1028 /* set <server> and <part> to the correct values depending on
1029 * <voltype> and <entry> */
1030 static void 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 */
1065 static void PostVolumeStats(entry)
1066 struct nvldbentry *entry;
1068 SubEnumerateEntry(entry);
1069 /* Check for VLOP_ALLOPERS */
1070 if (entry->flags & VLOP_ALLOPERS)
1071 fprintf(STDOUT," Volume is currently LOCKED \n");
1075 /*------------------------------------------------------------------------
1076 * PRIVATE XVolumeStats
1079 * Display extended volume information.
1082 * a_xInfoP : Ptr to extended volume info.
1083 * a_entryP : Ptr to the volume's VLDB entry.
1084 * a_srvID : Server ID.
1085 * a_partID : Partition ID.
1086 * a_volType : Type of volume to print.
1092 * Nothing interesting.
1096 *------------------------------------------------------------------------*/
1098 static void XVolumeStats(a_xInfoP, a_entryP, a_srvID, a_partID, a_volType)
1099 volintXInfo *a_xInfoP;
1100 struct nvldbentry *a_entryP;
1107 int totalOK, totalNotOK, totalBusy; /*Dummies - we don't really count here*/
1109 XDisplayFormat(a_xInfoP, /*Ptr to extended volume info*/
1110 a_srvID, /*Server ID to print*/
1111 a_partID, /*Partition ID to print*/
1112 &totalOK, /*Ptr to total-OK counter*/
1113 &totalNotOK, /*Ptr to total-screwed counter*/
1114 &totalBusy, /*Ptr to total-busy counter*/
1115 0, /*Don't do a fast listing*/
1116 1, /*Do a long listing*/
1117 1); /*Show volume problems*/
1122 static void VolumeStats(pntr,entry,server,part,voltype)
1124 struct nvldbentry *entry;
1126 afs_int32 server,part;
1128 int totalOK,totalNotOK,totalBusy;
1129 afs_int32 vcode,vcode2;
1131 DisplayFormat(pntr,server,part,&totalOK,&totalNotOK,&totalBusy,0,1,1);
1135 /* command to forcibly remove a volume */
1136 static NukeVolume(as)
1137 register struct cmd_syndesc *as; {
1138 register afs_int32 code;
1139 afs_int32 volID, err;
1144 server = GetServer(tp = as->parms[0].items->data);
1146 fprintf(STDERR,"vos: server '%s' not found in host table\n", tp);
1150 partID = volutil_GetPartitionID(tp = as->parms[1].items->data);
1152 fprintf(STDERR, "vos: could not parse '%s' as a partition name", tp);
1156 volID = vsu_GetVolumeID(tp = as->parms[2].items->data, cstruct, &err);
1158 if (err) PrintError("", err);
1159 else fprintf(STDERR, "vos: could not parse '%s' as a numeric volume ID", tp);
1163 fprintf(STDOUT, "vos: forcibly removing all traces of volume %d, please wait...", volID);
1165 code = UV_NukeVolume(server, partID, volID);
1167 fprintf(STDOUT, "done.\n");
1169 fprintf(STDOUT, "failed with code %d.\n", code);
1174 /*------------------------------------------------------------------------
1175 * PRIVATE ExamineVolume
1178 * Routine used to examine a single volume, contacting the VLDB as
1179 * well as the Volume Server.
1182 * as : Ptr to parsed command line arguments.
1185 * 0 for a successful operation,
1186 * Otherwise, one of the ubik or VolServer error values.
1189 * Nothing interesting.
1193 *------------------------------------------------------------------------
1195 static ExamineVolume(as)
1196 register struct cmd_syndesc *as;
1198 struct nvldbentry entry;
1199 afs_int32 vcode = 0;
1200 volintInfo *pntr = (volintInfo *)0;
1201 volintXInfo *xInfoP = (volintXInfo *)0;
1203 afs_int32 code, err, error = 0;
1204 int voltype, foundserv = 0, foundentry = 0;
1205 afs_int32 aserver, apart;
1207 int wantExtendedInfo; /*Do we want extended vol info?*/
1209 wantExtendedInfo = (as->parms[1].items ? 1 : 0); /* -extended */
1211 volid = vsu_GetVolumeID(as->parms[0].items->data, cstruct, &err); /* -id */
1213 if (err) PrintError("", err);
1214 else fprintf(STDERR, "Unknown volume ID or name '%s'\n", as->parms[0].items->data);
1219 fprintf(STDOUT, "Fetching VLDB entry for %u .. ", volid);
1222 vcode = VLDB_GetEntryByID (volid, -1, &entry);
1224 fprintf(STDERR, "Could not fetch the entry for volume number %u from VLDB \n",volid);
1228 fprintf(STDOUT, "done\n");
1229 MapHostToNetwork(&entry);
1231 if (entry.volumeId[RWVOL] == volid)
1233 else if (entry.volumeId[BACKVOL] == volid)
1235 else /* (entry.volumeId[ROVOL] == volid) */
1238 do { /* do {...} while (voltype == ROVOL) */
1239 /* Get the entry for the volume. If its a RW vol, get the RW entry.
1240 * It its a BK vol, get the RW entry (even if VLDB may say the BK doen't exist).
1241 * If its a RO vol, get the next RO entry.
1243 GetServerAndPart(&entry, ((voltype == ROVOL) ? ROVOL : RWVOL), &aserver, &apart, &previdx);
1244 if (previdx == -1) { /* searched all entries */
1246 fprintf(STDERR,"Volume %s does not exist in VLDB\n\n", as->parms[0].items->data);
1253 /* Get information about the volume from the server */
1255 fprintf(STDOUT,"Getting volume listing from the server %s .. ",
1256 hostutil_GetNameByINet(aserver));
1259 if (wantExtendedInfo)
1260 code = UV_XListOneVolume(aserver, apart, volid, &xInfoP);
1262 code = UV_ListOneVolume(aserver, apart, volid, &pntr);
1264 fprintf(STDOUT,"done\n");
1268 if (code == ENODEV) {
1269 if ((voltype == BACKVOL) && !(entry.flags & BACK_EXISTS)) {
1270 /* The VLDB says there is no backup volume and its not on disk */
1271 fprintf(STDERR, "Volume %s does not exist\n", as->parms[0].items->data);
1274 fprintf(STDERR, "Volume does not exist on server %s as indicated by the VLDB\n",
1275 hostutil_GetNameByINet(aserver));
1278 PrintDiagnostics("examine", code);
1280 fprintf(STDOUT, "\n");
1283 if (wantExtendedInfo)
1284 XVolumeStats(xInfoP, &entry, aserver, apart, voltype);
1286 #ifdef FULL_LISTVOL_SWITCH
1287 if (as->parms[2].items) {
1288 DisplayFormat2(aserver, apart, pntr);
1289 EnumerateEntry(&entry);
1291 #endif /* FULL_LISTVOL_SWITCH */
1292 VolumeStats(pntr, &entry, aserver, apart, voltype);
1294 if ((voltype == BACKVOL) && !(entry.flags & BACK_EXISTS)) {
1295 /* The VLDB says there is no backup volume yet we found one on disk */
1296 fprintf(STDERR, "Volume %s does not exist in VLDB\n", as->parms[0].items->data);
1301 if (pntr) free(pntr);
1302 if (xInfoP) free(xInfoP);
1303 } while (voltype == ROVOL);
1306 fprintf(STDERR,"Dump only information from VLDB\n\n");
1307 fprintf(STDOUT,"%s \n", entry.name); /* PostVolumeStats doesn't print name */
1309 PostVolumeStats(&entry);
1314 /*------------------------------------------------------------------------
1318 * Routine used to change the status of a single volume.
1321 * as : Ptr to parsed command line arguments.
1324 * 0 for a successful operation,
1325 * Otherwise, one of the ubik or VolServer error values.
1328 * Nothing interesting.
1332 *------------------------------------------------------------------------
1334 static SetFields(as)
1335 register struct cmd_syndesc *as;
1337 struct nvldbentry entry;
1338 afs_int32 vcode = 0;
1341 afs_int32 code, err;
1342 afs_int32 aserver, apart;
1345 volid = vsu_GetVolumeID(as->parms[0].items->data, cstruct, &err); /* -id */
1347 if (err) PrintError("", err);
1348 else fprintf(STDERR, "Unknown volume ID or name '%s'\n", as->parms[0].items->data);
1352 code = VLDB_GetEntryByID (volid, RWVOL, &entry);
1354 fprintf(STDERR, "Could not fetch the entry for volume number %u from VLDB \n",volid);
1357 MapHostToNetwork(&entry);
1359 GetServerAndPart(&entry, RWVOL, &aserver, &apart, &previdx);
1360 if (previdx == -1) {
1361 fprintf(STDERR,"Volume %s does not exist in VLDB\n\n", as->parms[0].items->data);
1365 memset(&info, 0, sizeof(info));
1376 if (as->parms[1].items) {
1378 code = util_GetInt32(as->parms[1].items->data, &info.maxquota);
1380 fprintf(STDERR,"invalid quota value\n");
1384 if (as->parms[2].items) {
1388 code = UV_SetVolumeInfo(aserver, apart, volid, &info);
1390 fprintf(STDERR,"Could not update volume info fields for volume number %u\n",volid);
1394 /*------------------------------------------------------------------------
1398 * Brings a volume online.
1401 * as : Ptr to parsed command line arguments.
1404 * 0 for a successful operation,
1407 * Nothing interesting.
1411 *------------------------------------------------------------------------
1413 static volOnline(as)
1414 register struct cmd_syndesc *as;
1416 afs_int32 server, partition, volid;
1417 afs_int32 code, err=0;
1419 server = GetServer(as->parms[0].items->data);
1421 fprintf(STDERR,"vos: server '%s' not found in host table\n", as->parms[0].items->data);
1425 partition = volutil_GetPartitionID(as->parms[1].items->data);
1426 if (partition < 0) {
1427 fprintf(STDERR,"vos: could not interpret partition name '%s'\n", as->parms[1].items->data);
1431 volid = vsu_GetVolumeID(as->parms[2].items->data, cstruct, &err); /* -id */
1433 if (err) PrintError("", err);
1434 else fprintf(STDERR, "Unknown volume ID or name '%s'\n", as->parms[0].items->data);
1438 code = UV_SetVolume(server, partition, volid, ITOffline, 0/*online*/, 0/*sleep*/);
1440 fprintf(STDERR, "Failed to set volume. Code = %d\n", code);
1447 /*------------------------------------------------------------------------
1448 * PRIVATE volOffline
1451 * Brings a volume offline.
1454 * as : Ptr to parsed command line arguments.
1457 * 0 for a successful operation,
1460 * Nothing interesting.
1464 *------------------------------------------------------------------------
1466 static volOffline(as)
1467 register struct cmd_syndesc *as;
1469 afs_int32 server, partition, volid;
1470 afs_int32 code, err=0;
1471 afs_int32 transflag, sleeptime, transdone;
1473 server = GetServer(as->parms[0].items->data);
1475 fprintf(STDERR,"vos: server '%s' not found in host table\n", as->parms[0].items->data);
1479 partition = volutil_GetPartitionID(as->parms[1].items->data);
1480 if (partition < 0) {
1481 fprintf(STDERR,"vos: could not interpret partition name '%s'\n", as->parms[1].items->data);
1485 volid = vsu_GetVolumeID(as->parms[2].items->data, cstruct, &err); /* -id */
1487 if (err) PrintError("", err);
1488 else fprintf(STDERR, "Unknown volume ID or name '%s'\n", as->parms[0].items->data);
1492 transflag = (as->parms[4].items ? ITBusy : ITOffline);
1493 sleeptime = (as->parms[3].items ? atol(as->parms[3].items->data) : 0);
1494 transdone = (sleeptime ? 0/*online*/ : VTOutOfService);
1495 if (as->parms[4].items && !as->parms[3].items) {
1496 fprintf(STDERR,"-sleep option must be used with -busy flag\n");
1500 code = UV_SetVolume(server, partition, volid, transflag, transdone, sleeptime);
1502 fprintf(STDERR, "Failed to set volume. Code = %d\n", code);
1509 static CreateVolume(as)
1510 register struct cmd_syndesc *as;
1514 afs_int32 volid,code;
1515 struct nvldbentry entry;
1520 tserver = GetServer(as->parms[0].items->data);
1522 fprintf(STDERR,"vos: host '%s' not found in host table\n",as->parms[0].items->data );
1525 pname = volutil_GetPartitionID(as->parms[1].items->data);
1527 fprintf(STDERR,"vos: could not interpret partition name '%s'\n",as->parms[1].items->data );
1530 if (!IsPartValid(pname,tserver,&code)){/*check for validity of the partition */
1531 if(code) PrintError("",code);
1532 else fprintf(STDERR,"vos : partition %s does not exist on the server\n",as->parms[1].items->data);
1535 if(!ISNAMEVALID(as->parms[2].items->data)) {
1536 fprintf(STDERR,"vos: the name of the root volume %s exceeds the size limit of %d\n",as->parms[2].items->data,VOLSER_OLDMAXVOLNAME - 10);
1539 if(!VolNameOK(as->parms[2].items->data)){
1540 fprintf(STDERR,"Illegal volume name %s, should not end in .readonly or .backup\n",as->parms[2].items->data);
1543 if(IsNumeric(as->parms[2].items->data)){
1544 fprintf(STDERR,"Illegal volume name %s, should not be a number\n",as->parms[2].items->data);
1547 vcode = VLDB_GetEntryByName(as->parms[2].items->data, &entry);
1549 fprintf(STDERR,"Volume %s already exists\n",as->parms[2].items->data);
1550 PrintDiagnostics("create", code);
1554 if (as->parms[3].items) {
1555 if (!IsNumeric(as->parms[3].items->data)){
1556 fprintf(STDERR,"Initial quota %s should be numeric.\n", as->parms[3].items->data);
1560 code = util_GetInt32(as->parms[3].items->data, "a);
1562 fprintf(STDERR,"vos: bad integer specified for quota.\n");
1567 code = UV_CreateVolume2(tserver, pname,as->parms[2].items->data,
1568 quota, 0, 0, 0, 0, &volid);
1570 PrintDiagnostics("create", code);
1573 MapPartIdIntoName(pname, part);
1574 fprintf(STDOUT,"Volume %u created on partition %s of %s\n", volid, part,as->parms[0].items->data );
1579 static afs_int32 DeleteAll(entry)
1580 struct nvldbentry *entry;
1583 afs_int32 error, code, curserver, curpart, volid;
1585 MapHostToNetwork(entry);
1587 for(i=0; i < entry->nServers; i++){
1588 curserver = entry->serverNumber[i];
1589 curpart = entry->serverPartition[i];
1590 if(entry->serverFlags[i] & ITSROVOL){
1591 volid = entry->volumeId[ROVOL];
1594 volid = entry->volumeId[RWVOL];
1596 code = UV_DeleteVolume(curserver,curpart,volid);
1603 static DeleteVolume(as)
1604 struct cmd_syndesc *as;
1606 afs_int32 err, code = 0;
1607 afs_int32 server = 0, partition = -1, volid;
1611 if (as->parms[0].items) {
1612 server = GetServer(as->parms[0].items->data);
1614 fprintf(STDERR,"vos: server '%s' not found in host table\n",
1615 as->parms[0].items->data);
1620 if (as->parms[1].items) {
1621 partition = volutil_GetPartitionID(as->parms[1].items->data);
1622 if (partition < 0) {
1623 fprintf(STDERR,"vos: could not interpret partition name '%s'\n",
1624 as->parms[1].items->data );
1628 /* Check for validity of the partition */
1629 if (!IsPartValid(partition, server, &code)) {
1631 PrintError("", code);
1633 fprintf(STDERR,"vos : partition %s does not exist on the server\n",
1634 as->parms[1].items->data);
1640 volid = vsu_GetVolumeID(as->parms[2].items->data, cstruct, &err);
1642 fprintf(STDERR, "Can't find volume name '%s' in VLDB\n",
1643 as->parms[2].items->data);
1644 if (err) PrintError("", err);
1648 /* If the server or partition option are not complete, try to fill
1649 * them in from the VLDB entry.
1651 if ((partition == -1) || !server) {
1652 struct nvldbentry entry;
1654 code = VLDB_GetEntryByID(volid, -1, &entry);
1656 fprintf(STDERR,"Could not fetch the entry for volume %u from VLDB\n",
1658 PrintError("",code);
1662 if (((volid == entry.volumeId[RWVOL]) && (entry.flags & RW_EXISTS)) ||
1663 ((volid == entry.volumeId[BACKVOL]) && (entry.flags & BACK_EXISTS)) ) {
1664 idx = Lp_GetRwIndex(&entry);
1666 (server && (server != entry.serverNumber[idx])) ||
1667 ((partition != -1) && (partition != entry.serverPartition[idx])) ) {
1668 fprintf(STDERR,"VLDB: Volume '%s' no match\n", as->parms[2].items->data);
1672 else if ((volid == entry.volumeId[ROVOL]) && (entry.flags & RO_EXISTS)) {
1673 for (idx=-1,j=0; j<entry.nServers; j++) {
1674 if (entry.serverFlags[j] != ITSROVOL) continue;
1676 if ( ((server == 0) || (server == entry.serverNumber[j])) &&
1677 ((partition == -1) || (partition == entry.serverPartition[j])) ) {
1679 fprintf(STDERR,"VLDB: Volume '%s' matches more than one RO\n",
1680 as->parms[2].items->data);
1687 fprintf(STDERR,"VLDB: Volume '%s' no match\n", as->parms[2].items->data);
1692 fprintf(STDERR,"VLDB: Volume '%s' no match\n", as->parms[2].items->data);
1696 server = htonl(entry.serverNumber[idx]);
1697 partition = entry.serverPartition[idx];
1701 code = UV_DeleteVolume(server, partition, volid);
1703 PrintDiagnostics("remove", code);
1707 MapPartIdIntoName(partition, pname);
1708 fprintf(STDOUT,"Volume %u on partition %s server %s deleted\n",
1709 volid, pname, hostutil_GetNameByINet(server));
1713 #define TESTM 0 /* set for move space tests, clear for production */
1714 static MoveVolume(as)
1715 register struct cmd_syndesc *as;
1718 afs_int32 volid, fromserver, toserver, frompart, topart,code, err;
1719 char fromPartName[10], toPartName[10];
1721 struct diskPartition partition; /* for space check */
1724 volid = vsu_GetVolumeID(as->parms[0].items->data, cstruct, &err);
1726 if (err) PrintError("", err);
1727 else fprintf(STDERR, "vos: can't find volume ID or name '%s'\n",
1728 as->parms[0].items->data);
1731 fromserver = GetServer(as->parms[1].items->data);
1732 if (fromserver == 0) {
1733 fprintf(STDERR,"vos: server '%s' not found in host table\n", as->parms[1].items->data);
1736 toserver = GetServer(as->parms[3].items->data);
1737 if (toserver == 0) {
1738 fprintf(STDERR,"vos: server '%s' not found in host table\n", as->parms[3].items->data);
1741 frompart = volutil_GetPartitionID(as->parms[2].items->data);
1743 fprintf(STDERR,"vos: could not interpret partition name '%s'\n", as->parms[2].items->data);
1746 if (!IsPartValid(frompart,fromserver,&code)){/*check for validity of the partition */
1747 if(code) PrintError("",code);
1748 else fprintf(STDERR,"vos : partition %s does not exist on the server\n",as->parms[2].items->data);
1751 topart = volutil_GetPartitionID(as->parms[4].items->data);
1753 fprintf(STDERR,"vos: could not interpret partition name '%s'\n",as->parms[4].items->data);
1756 if (!IsPartValid(topart,toserver,&code)){/*check for validity of the partition */
1757 if(code) PrintError("",code);
1758 else fprintf(STDERR,"vos : partition %s does not exist on the server\n",as->parms[4].items->data);
1763 check source partition for space to clone volume
1766 MapPartIdIntoName(topart,toPartName);
1767 MapPartIdIntoName(frompart, fromPartName);
1770 check target partition for space to move volume
1773 code=UV_PartitionInfo(toserver,toPartName,&partition);
1776 fprintf(STDERR,"vos: cannot access partition %s\n",toPartName);
1780 fprintf(STDOUT,"target partition %s free space %d\n",
1781 toPartName,partition.free);
1784 code=UV_ListOneVolume(fromserver,frompart,volid,&p);
1787 fprintf(STDERR,"vos:cannot access volume %u\n",volid);
1792 fprintf(STDOUT,"volume %u size %d\n",volid,p->size);
1793 if(partition.free<=p->size)
1795 fprintf(STDERR,"vos: no space on target partition %s to move volume %u\n",
1804 fprintf(STDOUT,"size test - don't do move\n");
1808 /* successful move still not guaranteed but shoot for it */
1810 code = UV_MoveVolume(volid, fromserver, frompart, toserver, topart);
1812 PrintDiagnostics("move", code);
1815 MapPartIdIntoName(topart,toPartName);
1816 MapPartIdIntoName(frompart, fromPartName);
1817 fprintf(STDOUT,"Volume %u moved from %s %s to %s %s \n",volid,as->parms[1].items->data,fromPartName,as->parms[3].items->data,toPartName);
1822 static CopyVolume(as)
1823 register struct cmd_syndesc *as;
1826 afs_int32 volid, fromserver, toserver, tovolume, frompart, topart,code, err;
1827 char fromPartName[10], toPartName[10];
1828 struct nvldbentry entry;
1829 struct diskPartition partition; /* for space check */
1832 volid = vsu_GetVolumeID(as->parms[0].items->data, cstruct, &err);
1834 if (err) PrintError("", err);
1835 else fprintf(STDERR, "vos: can't find volume ID or name '%s'\n",
1836 as->parms[0].items->data);
1839 fromserver = GetServer(as->parms[1].items->data);
1840 if (fromserver == 0) {
1841 fprintf(STDERR,"vos: server '%s' not found in host table\n", as->parms[1].items->data);
1845 toserver = GetServer(as->parms[4].items->data);
1846 if (toserver == 0) {
1847 fprintf(STDERR,"vos: server '%s' not found in host table\n", as->parms[3].items->data);
1851 tovolume = as->parms[3].items->data;
1852 if(!ISNAMEVALID(tovolume)) {
1853 fprintf(STDERR,"vos: the name of the root volume %s exceeds the size limit of %d\n",
1854 tovolume,VOLSER_OLDMAXVOLNAME - 10);
1857 if(!VolNameOK(tovolume)){
1858 fprintf(STDERR,"Illegal volume name %s, should not end in .readonly or .backup\n",tovolume);
1861 if(IsNumeric(tovolume)){
1862 fprintf(STDERR,"Illegal volume name %s, should not be a number\n",tovolume);
1865 code = VLDB_GetEntryByName(tovolume, &entry);
1867 fprintf(STDERR,"Volume %s already exists\n",tovolume);
1868 PrintDiagnostics("copy", code);
1872 frompart = volutil_GetPartitionID(as->parms[2].items->data);
1874 fprintf(STDERR,"vos: could not interpret partition name '%s'\n", as->parms[2].items->data);
1877 if (!IsPartValid(frompart,fromserver,&code)){/*check for validity of the partition */
1878 if(code) PrintError("",code);
1879 else fprintf(STDERR,"vos : partition %s does not exist on the server\n",as->parms[2].items->data);
1883 topart = volutil_GetPartitionID(as->parms[5].items->data);
1885 fprintf(STDERR,"vos: could not interpret partition name '%s'\n",as->parms[4].items->data);
1888 if (!IsPartValid(topart,toserver,&code)){/*check for validity of the partition */
1889 if(code) PrintError("",code);
1890 else fprintf(STDERR,"vos : partition %s does not exist on the server\n",as->parms[4].items->data);
1895 check source partition for space to clone volume
1898 MapPartIdIntoName(topart,toPartName);
1899 MapPartIdIntoName(frompart, fromPartName);
1902 check target partition for space to move volume
1905 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",
1913 toPartName,partition.free);
1916 code=UV_ListOneVolume(fromserver,frompart,volid,&p);
1919 fprintf(STDERR,"vos:cannot access volume %u\n",volid);
1924 if(partition.free<=p->size)
1926 fprintf(STDERR,"vos: no space on target partition %s to copy volume %u\n",
1933 /* successful copy still not guaranteed but shoot for it */
1935 code = UV_CopyVolume(volid, fromserver, frompart, tovolume, toserver, topart);
1937 PrintDiagnostics("copy", code);
1940 MapPartIdIntoName(topart,toPartName);
1941 MapPartIdIntoName(frompart, fromPartName);
1942 fprintf(STDOUT,"Volume %u copied from %s %s to %s on %s %s \n",volid,
1943 as->parms[1].items->data,fromPartName,
1944 tovolume, as->parms[4].items->data,toPartName);
1950 static BackupVolume(as)
1951 register struct cmd_syndesc *as;
1953 afs_int32 avolid, aserver, apart,vtype,code, err;
1954 struct nvldbentry entry;
1956 afs_int32 buvolid,buserver,bupart,butype;
1957 struct nvldbentry buentry;
1958 struct rx_connection *conn;
1960 struct nvldbentry store;
1962 avolid = vsu_GetVolumeID(as->parms[0].items->data, cstruct, &err);
1964 if (err) PrintError("", err);
1965 else fprintf(STDERR, "vos: can't find volume ID or name '%s'\n",
1966 as->parms[0].items->data);
1969 code = GetVolumeInfo( avolid,&aserver, &apart,&vtype,&entry);
1972 /* verify this is a readwrite volume */
1976 fprintf(STDERR,"%s not RW volume\n",as->parms[0].items->data);
1980 /* is there a backup volume already? */
1982 if(entry.flags & BACK_EXISTS)
1984 /* yep, where is it? */
1986 buvolid=entry.volumeId[BACKVOL];
1987 code=GetVolumeInfo(buvolid,&buserver,&bupart,&butype,&buentry);
1991 code = VLDB_IsSameAddrs(buserver, aserver, &err);
1993 fprintf(STDERR,"Failed to get info about server's %d address(es) from vlserver; aborting call!\n", buserver);
1998 fprintf(STDERR,"FATAL ERROR: backup volume %u exists on server %u\n",
2004 /* nope, carry on */
2006 code = UV_BackupVolume(aserver, apart, avolid);
2009 PrintDiagnostics("backup", code);
2012 fprintf(STDOUT,"Created backup volume for %s \n",as->parms[0].items->data);
2015 static ReleaseVolume(as)
2016 register struct cmd_syndesc *as;
2019 struct nvldbentry entry;
2020 afs_int32 avolid, aserver, apart,vtype,code, err;
2023 if(as->parms[1].items) force = 1;
2024 avolid = vsu_GetVolumeID(as->parms[0].items->data, cstruct, &err);
2026 if (err) PrintError("", err);
2027 else fprintf(STDERR, "vos: can't find volume '%s'\n", as->parms[0].items->data);
2030 code = GetVolumeInfo( avolid,&aserver, &apart,&vtype,&entry);
2031 if(code) return code;
2033 if (vtype != RWVOL) {
2034 fprintf(STDERR,"%s not a RW volume\n", as->parms[0].items->data);
2038 if(!ISNAMEVALID(entry.name)){
2039 fprintf(STDERR,"Volume name %s is too long, rename before releasing\n",entry.name);
2043 code = UV_ReleaseVolume(avolid, aserver, apart, force);
2045 PrintDiagnostics("release", code);
2048 fprintf(STDOUT,"Released volume %s successfully\n",as->parms[0].items->data );
2051 static DumpVolume(as)
2052 register struct cmd_syndesc *as;
2055 afs_int32 avolid, aserver, apart,voltype,fromdate=0,code, err, i;
2056 char filename[NameLen];
2057 struct nvldbentry entry;
2059 rx_SetRxDeadTime(60 * 10);
2060 for (i = 0; i<MAXSERVERS; i++) {
2061 struct rx_connection *rxConn = ubik_GetRPCConn(cstruct,i);
2062 if (rxConn == 0) break;
2063 rx_SetConnDeadTime(rxConn, rx_connDeadTime);
2064 if (rxConn->service) rxConn->service->connDeadTime = rx_connDeadTime;
2067 avolid = vsu_GetVolumeID(as->parms[0].items->data, cstruct, &err);
2069 if (err) PrintError("", err);
2070 else fprintf(STDERR, "vos: can't find volume '%s'\n", as->parms[0].items->data);
2074 if (as->parms[3].items || as->parms[4].items) {
2075 if (!as->parms[3].items || !as->parms[4].items) {
2076 fprintf(STDERR, "Must specify both -server and -partition options\n");
2079 aserver = GetServer(as->parms[3].items->data);
2081 fprintf(STDERR, "Invalid server name\n");
2084 apart = volutil_GetPartitionID(as->parms[4].items->data);
2086 fprintf(STDERR, "Invalid partition name\n");
2090 code = GetVolumeInfo(avolid, &aserver, &apart, &voltype, &entry);
2091 if (code) return code;
2094 if (as->parms[1].items && strcmp(as->parms[1].items->data,"0")) {
2095 code = ktime_DateToInt32(as->parms[1].items->data, &fromdate);
2097 fprintf(STDERR,"vos: failed to parse date '%s' (error=%d))\n",
2098 as->parms[1].items->data, code);
2102 if(as->parms[2].items){
2103 strcpy(filename,as->parms[2].items->data);
2106 strcpy(filename,"");
2109 if (as->parms[5].items) {
2110 code = UV_DumpClonedVolume(avolid, aserver, apart, fromdate, DumpFunction, filename);
2112 code = UV_DumpVolume(avolid, aserver, apart, fromdate, DumpFunction, filename);
2115 PrintDiagnostics("dump", code);
2118 if(strcmp(filename,""))
2119 fprintf(STDERR,"Dumped volume %s in file %s\n",as->parms[0].items->data, filename);
2121 fprintf(STDERR,"Dumped volume %s in stdout \n",as->parms[0].items->data);
2130 static RestoreVolume(as)
2131 register struct cmd_syndesc *as;
2134 afs_int32 avolid, aserver, apart, code,vcode, err;
2135 afs_int32 aoverwrite = ASK;
2136 int restoreflags, readonly = 0, offline = 0, voltype = RWVOL;
2138 char afilename[NameLen], avolname[VOLSER_MAXVOLNAME +1],apartName[10];
2139 char volname[VOLSER_MAXVOLNAME +1];
2140 struct nvldbentry entry;
2144 if(as->parms[4].items){
2145 avolid = vsu_GetVolumeID(as->parms[4].items->data, cstruct, &err);
2147 if (err) PrintError("", err);
2148 else fprintf(STDERR, "vos: can't find volume '%s'\n", as->parms[4].items->data);
2155 if (as->parms[5].items) {
2156 if ( (strcmp(as->parms[5].items->data, "a") == 0) ||
2157 (strcmp(as->parms[5].items->data, "abort") == 0) ) {
2160 else if ( (strcmp(as->parms[5].items->data, "f") == 0) ||
2161 (strcmp(as->parms[5].items->data, "full") == 0) ) {
2164 else if ( (strcmp(as->parms[5].items->data, "i") == 0) ||
2165 (strcmp(as->parms[5].items->data, "inc") == 0) ||
2166 (strcmp(as->parms[5].items->data, "increment") == 0) ||
2167 (strcmp(as->parms[5].items->data, "incremental") == 0) ) {
2171 fprintf(STDERR, "vos: %s is not a valid argument to -overwrite\n",
2172 as->parms[5].items->data);
2176 if (as->parms[6].items) offline = 1;
2177 if (as->parms[7].items) {
2182 aserver = GetServer(as->parms[0].items->data);
2184 fprintf(STDERR,"vos: server '%s' not found in host table\n", as->parms[0].items->data);
2187 apart = volutil_GetPartitionID(as->parms[1].items->data);
2189 fprintf(STDERR,"vos: could not interpret partition name '%s'\n",as->parms[1].items->data );
2192 if (!IsPartValid(apart,aserver,&code)){/*check for validity of the partition */
2193 if(code) PrintError("",code);
2194 else fprintf(STDERR,"vos : partition %s does not exist on the server\n",as->parms[1].items->data);
2197 strcpy(avolname,as->parms[2].items->data );
2198 if(!ISNAMEVALID(avolname)) {
2199 fprintf(STDERR,"vos: the name of the volume %s exceeds the size limit\n",avolname);
2202 if(!VolNameOK(avolname)){
2203 fprintf(STDERR,"Illegal volume name %s, should not end in .readonly or .backup\n",avolname);
2206 if(as->parms[3].items){
2207 strcpy(afilename,as->parms[3].items->data );
2208 if(!FileExists(afilename)){
2209 fprintf(STDERR,"Can't access file %s\n",afilename);
2214 strcpy(afilename,"");
2217 /* Check if volume exists or not */
2219 vsu_ExtractName(volname,avolname);
2220 vcode = VLDB_GetEntryByName(volname, &entry);
2221 if (vcode) { /* no volume - do a full restore */
2222 restoreflags = RV_FULLRST;
2223 if ( (aoverwrite == INC) || (aoverwrite == ABORT) )
2224 fprintf(STDERR,"Volume does not exist; Will perform a full restore\n");
2227 else if ((!readonly && Lp_GetRwIndex(&entry) == -1) /* RW volume does not exist - do a full */
2228 || (readonly && !Lp_ROMatch(0, 0, &entry))) { /* RO volume does not exist - do a full */
2229 restoreflags = RV_FULLRST;
2230 if ( (aoverwrite == INC) || (aoverwrite == ABORT) )
2231 fprintf(STDERR,"%s Volume does not exist; Will perform a full restore\n",
2232 readonly ? "RO" : "RW");
2235 avolid = entry.volumeId[voltype];
2237 else if (entry.volumeId[voltype] != 0 && entry.volumeId[voltype] != avolid) {
2238 avolid = entry.volumeId[voltype];
2242 else { /* volume exists - do we do a full incremental or abort */
2243 int Oserver, Opart, Otype, vol_elsewhere = 0;
2244 struct nvldbentry Oentry;
2248 avolid = entry.volumeId[voltype];
2250 else if(entry.volumeId[voltype] != 0 && entry.volumeId[voltype] != avolid) {
2251 avolid = entry.volumeId[voltype];
2254 /* A file name was specified - check if volume is on another partition */
2255 vcode = GetVolumeInfo(avolid, &Oserver, &Opart, &Otype, &Oentry);
2258 vcode = VLDB_IsSameAddrs(Oserver, aserver, &err);
2260 fprintf(STDERR,"Failed to get info about server's %d address(es) from vlserver (err=%d); aborting call!\n",
2264 if (!vcode || (Opart != apart)) vol_elsewhere = 1;
2266 if (aoverwrite == ASK) {
2267 if (strcmp(afilename,"") == 0) { /* The file is from standard in */
2268 fprintf(STDERR,"Volume exists and no -overwrite option specified; Aborting restore command\n");
2272 /* Ask what to do */
2273 if (vol_elsewhere) {
2274 fprintf(STDERR,"The volume %s %u already exists on a different server/part\n",
2275 volname, entry.volumeId[voltype]);
2277 "Do you want to do a full restore or abort? [fa](a): ");
2281 fprintf(STDERR,"The volume %s %u already exists in the VLDB\n",
2282 volname, entry.volumeId[voltype]);
2284 "Do you want to do a full/incremental restore or abort? [fia](a): ");
2287 while (!(dc==EOF || dc=='\n')) dc=getchar(); /* goto end of line */
2288 if ((c == 'f') || (c == 'F')) aoverwrite = FULL;
2289 else if ((c == 'i') || (c == 'I')) aoverwrite = INC;
2290 else aoverwrite = ABORT;
2293 if (aoverwrite == ABORT) {
2294 fprintf(STDERR,"Volume exists; Aborting restore command\n");
2297 else if (aoverwrite == FULL) {
2298 restoreflags = RV_FULLRST;
2299 fprintf(STDERR,"Volume exists; Will delete and perform full restore\n");
2301 else if (aoverwrite == INC) {
2303 if (vol_elsewhere) {
2305 "%s volume %u already exists on a different server/part; not allowed\n",
2306 readonly ? "RO" : "RW", avolid);
2311 if (offline) restoreflags |= RV_OFFLINE;
2312 if (readonly) restoreflags |= RV_RDONLY;
2313 code = UV_RestoreVolume(aserver, apart, avolid, avolname,
2314 restoreflags, WriteData, afilename);
2316 PrintDiagnostics("restore", code);
2319 MapPartIdIntoName(apart,apartName);
2322 patch typo here - originally "parms[1]", should be "parms[0]"
2325 fprintf(STDOUT,"Restored volume %s on %s %s\n",
2326 avolname, as->parms[0].items->data, apartName);
2329 static LockReleaseCmd(as)
2330 register struct cmd_syndesc *as;
2333 afs_int32 avolid,code, err;
2335 avolid = vsu_GetVolumeID(as->parms[0].items->data, cstruct, &err);
2337 if (err) PrintError("", err);
2338 else fprintf(STDERR, "vos: can't find volume '%s'\n", as->parms[0].items->data);
2342 code = UV_LockRelease(avolid);
2344 PrintDiagnostics("unlock", code);
2347 fprintf(STDOUT,"Released lock on vldb entry for volume %s\n",as->parms[0].items->data);
2351 register struct cmd_syndesc *as;
2353 afs_int32 avolid, aserver, apart,code, err;
2354 char apartName[10], avolname[VOLSER_MAXVOLNAME+1];
2356 vsu_ExtractName(avolname, as->parms[2].items->data);;
2357 avolid = vsu_GetVolumeID(avolname, cstruct, &err);
2359 if (err) PrintError("", err);
2360 else fprintf(STDERR, "vos: can't find volume '%s'\n", as->parms[2].items->data);
2363 aserver = GetServer(as->parms[0].items->data);
2365 fprintf(STDERR,"vos: server '%s' not found in host table\n", as->parms[0].items->data);
2368 apart = volutil_GetPartitionID(as->parms[1].items->data);
2370 fprintf(STDERR,"vos: could not interpret partition name '%s'\n",as->parms[1].items->data );
2373 if (!IsPartValid(apart,aserver,&code)){/*check for validity of the partition */
2374 if(code) PrintError("",code);
2375 else fprintf(STDERR,"vos : partition %s does not exist on the server\n",as->parms[1].items->data);
2378 code = UV_AddSite(aserver, apart, avolid);
2380 PrintDiagnostics("addsite", code);
2383 MapPartIdIntoName(apart,apartName);
2384 fprintf(STDOUT,"Added replication site %s %s for volume %s\n",as->parms[0].items->data, apartName,as->parms[2].items->data);
2388 static RemoveSite(as)
2389 register struct cmd_syndesc *as;
2392 afs_int32 avolid, aserver, apart, code, err;
2393 char apartName[10], avolname[VOLSER_MAXVOLNAME+1];
2395 vsu_ExtractName(avolname, as->parms[2].items->data);
2396 avolid = vsu_GetVolumeID(avolname, cstruct, &err);
2398 if (err) PrintError("", err);
2399 else fprintf(STDERR, "vos: can't find volume '%s'\n", as->parms[2].items->data);
2402 aserver = GetServer(as->parms[0].items->data);
2404 fprintf(STDERR,"vos: server '%s' not found in host table\n", as->parms[0].items->data);
2407 apart = volutil_GetPartitionID(as->parms[1].items->data);
2409 fprintf(STDERR,"vos: could not interpret partition name '%s'\n",as->parms[1].items->data );
2413 *skip the partition validity check, since it is possible that the partition
2414 *has since been decomissioned.
2417 if (!IsPartValid(apart,aserver,&code)){
2418 if(code) PrintError("",code);
2419 else fprintf(STDERR,"vos : partition %s does not exist on the server\n",as->parms[1].items->data);
2423 code = UV_RemoveSite(aserver, apart, avolid);
2425 PrintDiagnostics("remsite", code);
2428 MapPartIdIntoName(apart,apartName);
2429 fprintf(STDOUT,"Removed replication site %s %s for volume %s\n",as->parms[0].items->data,apartName,as->parms[2].items->data);
2432 static ChangeLocation(as)
2433 register struct cmd_syndesc *as;
2435 afs_int32 avolid, aserver, apart,code, err;
2438 avolid = vsu_GetVolumeID(as->parms[2].items->data, cstruct, &err);
2440 if (err) PrintError("", err);
2441 else fprintf(STDERR, "vos: can't find volume '%s'\n", as->parms[2].items->data);
2444 aserver = GetServer(as->parms[0].items->data);
2446 fprintf(STDERR,"vos: server '%s' not found in host table\n", as->parms[0].items->data);
2449 apart = volutil_GetPartitionID(as->parms[1].items->data);
2451 fprintf(STDERR,"vos: could not interpret partition name '%s'\n",as->parms[1].items->data );
2454 if (!IsPartValid(apart,aserver,&code)){/*check for validity of the partition */
2455 if(code) PrintError("",code);
2456 else fprintf(STDERR,"vos : partition %s does not exist on the server\n",as->parms[1].items->data);
2459 code = UV_ChangeLocation(aserver, apart, avolid);
2461 PrintDiagnostics("addsite", code);
2464 MapPartIdIntoName(apart,apartName);
2465 fprintf(STDOUT,"Changed location to %s %s for volume %s\n",as->parms[0].items->data, apartName,as->parms[2].items->data);
2469 static ListPartitions(as)
2470 register struct cmd_syndesc *as;
2472 afs_int32 aserver,code;
2473 struct partList dummyPartList;
2478 aserver = GetServer(as->parms[0].items->data);
2480 fprintf(STDERR,"vos: server '%s' not found in host table\n", as->parms[0].items->data);
2485 code = UV_ListPartitions(aserver,&dummyPartList, &cnt);
2487 PrintDiagnostics("listpart", code);
2491 fprintf(STDOUT,"The partitions on the server are:\n");
2492 for(i = 0 ; i < cnt ; i++){
2493 if(dummyPartList.partFlags[i] & PARTVALID){
2494 memset(pname, 0, sizeof(pname));
2495 MapPartIdIntoName(dummyPartList.partId[i],pname);
2496 fprintf(STDOUT," %10s ",pname);
2498 if( (i % 5) == 0 && (i != 0)) fprintf(STDOUT,"\n");
2501 fprintf(STDOUT,"\n");
2502 fprintf(STDOUT,"Total: %d\n",total);
2507 static int CompareVolName(p1,p2)
2510 volintInfo *arg1,*arg2;
2512 arg1 = (volintInfo *)p1;
2513 arg2 = (volintInfo *)p2;
2514 return(strcmp(arg1->name,arg2->name));
2518 /*------------------------------------------------------------------------
2519 * PRIVATE XCompareVolName
2522 * Comparison routine for volume names coming from an extended
2526 * a_obj1P : Char ptr to first extended vol info object
2527 * a_obj1P : Char ptr to second extended vol info object
2530 * The value of strcmp() on the volume names within the passed
2531 * objects (i,e., -1, 0, or 1).
2534 * Passed to qsort() as the designated comparison routine.
2538 *------------------------------------------------------------------------*/
2540 static int XCompareVolName(a_obj1P, a_obj2P)
2541 char *a_obj1P, *a_obj2P;
2543 { /*XCompareVolName*/
2545 return(strcmp(((struct volintXInfo *)(a_obj1P))->name,
2546 ((struct volintXInfo *)(a_obj2P))->name));
2548 } /*XCompareVolName*/
2550 static int CompareVolID(p1,p2)
2553 volintInfo *arg1,*arg2;
2555 arg1 = (volintInfo *)p1;
2556 arg2 = (volintInfo *)p2;
2557 if(arg1->volid == arg2->volid) return 0;
2558 if(arg1->volid > arg2->volid) return 1;
2563 /*------------------------------------------------------------------------
2564 * PRIVATE XCompareVolID
2567 * Comparison routine for volume IDs coming from an extended
2571 * a_obj1P : Char ptr to first extended vol info object
2572 * a_obj1P : Char ptr to second extended vol info object
2575 * The value of strcmp() on the volume names within the passed
2576 * objects (i,e., -1, 0, or 1).
2579 * Passed to qsort() as the designated comparison routine.
2583 *------------------------------------------------------------------------*/
2585 static int XCompareVolID(a_obj1P, a_obj2P)
2586 char *a_obj1P, *a_obj2P;
2590 afs_int32 id1, id2; /*Volume IDs we're comparing*/
2592 id1 = ((struct volintXInfo *)(a_obj1P))->volid;
2593 id2 = ((struct volintXInfo *)(a_obj2P))->volid;
2604 /*------------------------------------------------------------------------
2605 * PRIVATE ListVolumes
2608 * Routine used to list volumes, contacting the Volume Server
2609 * directly, bypassing the VLDB.
2612 * as : Ptr to parsed command line arguments.
2615 * 0 Successful operation
2618 * Nothing interesting.
2622 *------------------------------------------------------------------------*/
2624 static ListVolumes(as)
2625 register struct cmd_syndesc *as;
2627 afs_int32 apart,int32list,fast;
2628 afs_int32 aserver,code;
2629 volintInfo *pntr,*oldpntr;
2633 volintXInfo *xInfoP, *origxInfoP; /*Ptr to current/orig extended vol info*/
2634 int wantExtendedInfo; /*Do we want extended vol info?*/
2637 struct partList dummyPartList;
2645 if(as->parms[3].items) int32list = 1;
2646 if(as->parms[4].items) quiet = 1;
2648 if(as->parms[2].items) fast = 1;
2651 if (as->parms[5].items) {
2653 * We can't coexist with the fast flag.
2657 "vos: Can't use the -fast and -extended flags together\n");
2662 * We need to turn on ``long'' listings to get the full effect.
2664 wantExtendedInfo = 1;
2668 wantExtendedInfo = 0;
2669 if(as->parms[1].items){
2670 apart = volutil_GetPartitionID(as->parms[1].items->data);
2672 fprintf(STDERR,"vos: could not interpret partition name '%s'\n", as->parms[1].items->data);
2675 dummyPartList.partId[0] = apart;
2676 dummyPartList.partFlags[0] = PARTVALID;
2679 aserver = GetServer(as->parms[0].items->data);
2681 fprintf(STDERR,"vos: server '%s' not found in host table\n",as->parms[0].items->data );
2686 if (!IsPartValid(apart,aserver,&code)){/*check for validity of the partition */
2687 if(code) PrintError("",code);
2688 else fprintf(STDERR,"vos : partition %s does not exist on the server\n",as->parms[1].items->data);
2693 code = UV_ListPartitions(aserver,&dummyPartList, &cnt);
2695 PrintDiagnostics("listvol", code);
2699 for(i = 0 ; i < cnt ; i++){
2700 if(dummyPartList.partFlags[i] & PARTVALID){
2701 if (wantExtendedInfo)
2702 code = UV_XListVolumes(aserver,
2703 dummyPartList.partId[i],
2708 code = UV_ListVolumes(aserver,
2709 dummyPartList.partId[i],
2714 PrintDiagnostics("listvol", code);
2715 if(pntr) free(pntr);
2718 if (wantExtendedInfo) {
2719 origxInfoP = xInfoP;
2720 base = (char *)xInfoP;
2723 base = (char *)pntr;
2727 if (wantExtendedInfo)
2728 qsort(base, count, sizeof(volintXInfo), XCompareVolName);
2730 qsort(base, count, sizeof(volintInfo), CompareVolName);
2732 if (wantExtendedInfo)
2733 qsort(base, count, sizeof(volintXInfo), XCompareVolID);
2735 qsort(base, count, sizeof(volintInfo), CompareVolID);
2737 MapPartIdIntoName(dummyPartList.partId[i],pname);
2739 fprintf(STDOUT,"Total number of volumes on server %s partition %s: %u \n",as->parms[0].items->data,pname,count);
2740 if (wantExtendedInfo) {
2741 XDisplayVolumes(aserver,
2742 dummyPartList.partId[i],
2750 xInfoP = (volintXInfo *)0;
2753 #ifdef FULL_LISTVOL_SWITCH
2754 if (as->parms[6].items)
2755 DisplayVolumes2(aserver, dummyPartList.partId[i], oldpntr,
2758 #endif /* FULL_LISTVOL_SWITCH */
2759 DisplayVolumes(aserver,
2760 dummyPartList.partId[i],
2768 pntr = (volintInfo *)0;
2776 register struct cmd_syndesc *as;
2778 afs_int32 pname, code; /* part name */
2784 if (as->parms[0].items) {
2785 tserver = GetServer(as->parms[0].items->data);
2787 fprintf(STDERR,"vos: host '%s' not found in host table\n",as->parms[0].items->data );
2792 if (as->parms[1].items) {
2793 pname = volutil_GetPartitionID(as->parms[1].items->data);
2795 fprintf(STDERR,"vos: could not interpret partition name '%s'\n",as->parms[1].items->data );
2798 if (!IsPartValid(pname,tserver,&code)) { /*check for validity of the partition */
2799 if(code) PrintError("",code);
2800 else fprintf(STDERR,"vos: partition %s does not exist on the server\n",
2801 as->parms[1].items->data);
2807 fprintf(STDERR,"The -partition option requires a -server option\n");
2812 if (as->parms[2].items) {
2813 /* Synchronize an individual volume */
2814 volname = as->parms[2].items->data;
2815 code = UV_SyncVolume(tserver, pname, volname, flags);
2818 fprintf(STDERR,"Without a -volume option, the -server option is required\n");
2821 code = UV_SyncVldb(tserver, pname, flags, 0/*unused*/);
2825 PrintDiagnostics("syncvldb", code);
2829 /* Print a summary of what we did */
2830 if (volname) fprintf(STDOUT,"VLDB volume %s synchronized", volname);
2831 else fprintf(STDOUT,"VLDB synchronized");
2833 fprintf(STDOUT," with state of server %s", as->parms[0].items->data);
2836 MapPartIdIntoName(pname,part);
2837 fprintf(STDOUT," partition %s\n", part);
2839 fprintf(STDOUT, "\n");
2844 static SyncServer(as)
2845 register struct cmd_syndesc *as;
2848 afs_int32 pname,code; /* part name */
2853 tserver = GetServer(as->parms[0].items->data);
2855 fprintf(STDERR,"vos: host '%s' not found in host table\n",as->parms[0].items->data );
2858 if(as->parms[1].items){
2859 pname = volutil_GetPartitionID(as->parms[1].items->data);
2861 fprintf(STDERR,"vos: could not interpret partition name '%s'\n",as->parms[1].items->data);
2864 if (!IsPartValid(pname,tserver,&code)){/*check for validity of the partition */
2865 if(code) PrintError("",code);
2866 else fprintf(STDERR,"vos : partition %s does not exist on the server\n",as->parms[1].items->data);
2872 code = UV_SyncServer(tserver, pname, flags, 0/*unused*/);
2874 PrintDiagnostics("syncserv", code);
2878 MapPartIdIntoName(pname,part);
2879 fprintf(STDOUT,"Server %s partition %s synchronized with VLDB\n",as->parms[0].items->data,part);
2881 else fprintf(STDOUT,"Server %s synchronized with VLDB\n",as->parms[0].items->data);
2886 static VolumeInfoCmd(name)
2889 struct nvldbentry entry;
2892 /* The vlserver will handle names with the .readonly
2893 * and .backup extension as well as volume ids.
2895 vcode = VLDB_GetEntryByName(name, &entry);
2897 PrintError("", vcode);
2900 MapHostToNetwork(&entry);
2901 EnumerateEntry(&entry);
2903 /* Defect #3027: grubby check to handle locked volume.
2904 * If VLOP_ALLOPERS is set, the entry is locked.
2905 * Leave this routine as is, but put in correct check.
2907 if (entry.flags & VLOP_ALLOPERS)
2908 fprintf(STDOUT," Volume is currently LOCKED \n");
2913 static VolumeZap(as)
2914 register struct cmd_syndesc *as;
2917 struct nvldbentry entry;
2918 afs_int32 volid,code,server,part, zapbackupid=0, backupid=0, err;
2920 if (as->parms[3].items) {
2921 /* force flag is on, use the other version */
2922 return NukeVolume(as);
2925 if (as->parms[4].items) {
2929 volid = vsu_GetVolumeID(as->parms[2].items->data, cstruct, &err);
2931 if (err) PrintError("", err);
2932 else fprintf(STDERR, "vos: can't find volume '%s'\n", as->parms[2].items->data);
2935 part = volutil_GetPartitionID(as->parms[1].items->data);
2937 fprintf(STDERR,"vos: could not interpret partition name '%s'\n",as->parms[1].items->data );
2940 server = GetServer(as->parms[0].items->data);
2942 fprintf(STDERR,"vos: host '%s' not found in host table\n",as->parms[0].items->data );
2945 if (!IsPartValid(part,server,&code)){/*check for validity of the partition */
2946 if(code) PrintError("",code);
2947 else fprintf(STDERR,"vos : partition %s does not exist on the server\n",as->parms[1].items->data);
2950 code = VLDB_GetEntryByID(volid,-1, &entry);
2952 if (volid == entry.volumeId[RWVOL])
2953 backupid = entry.volumeId[BACKVOL];
2954 fprintf(STDERR,"Warning: Entry for volume number %u exists in VLDB (but we're zapping it anyway!)\n",
2958 volintInfo *pntr = (volintInfo *)0;
2961 code = UV_ListOneVolume(server, part, volid, &pntr);
2963 if (volid == pntr->parentID)
2964 backupid = pntr->backupID;
2965 if (pntr) free(pntr);
2969 code = UV_VolumeZap(server,part, backupid);
2971 PrintDiagnostics("zap", code);
2974 fprintf(STDOUT,"Backup Volume %u deleted\n", backupid);
2977 code = UV_VolumeZap(server,part,volid);
2979 PrintDiagnostics("zap", code);
2982 fprintf(STDOUT,"Volume %u deleted\n",volid);
2987 static VolserStatus(as)
2988 register struct cmd_syndesc *as;
2991 afs_int32 server, code;
2992 transDebugInfo *pntr,*oldpntr;
2997 server = GetServer(as->parms[0].items->data);
2999 fprintf(STDERR,"vos: host '%s' not found in host table\n",as->parms[0].items->data );
3002 code = UV_VolserStatus(server,&pntr,&count);
3004 PrintDiagnostics("status",code);
3009 fprintf(STDOUT,"No active transactions on %s\n",as->parms[0].items->data);
3011 fprintf(STDOUT,"Total transactions: %d\n",count);
3013 for(i = 0; i < count ; i++){
3014 /*print out the relevant info */
3015 fprintf(STDOUT,"--------------------------------------\n");
3016 fprintf(STDOUT,"transaction: %u created: %s",pntr->tid,
3017 ctime((time_t *)&pntr->time));
3018 if(pntr->returnCode){
3019 fprintf(STDOUT,"returnCode: %u\n",pntr->returnCode);
3022 fprintf(STDOUT,"attachFlags: ");
3023 switch(pntr->iflags){
3024 case ITOffline: fprintf(STDOUT,"offline ");
3026 case ITBusy: fprintf(STDOUT,"busy ");
3028 case ITReadOnly: fprintf(STDOUT,"readonly ");
3030 case ITCreate: fprintf(STDOUT,"create ");
3032 case ITCreateVolID: fprintf(STDOUT,"create volid ");
3035 fprintf(STDOUT,"\n");
3038 fprintf(STDOUT,"volumeStatus: ");
3039 switch(pntr->vflags){
3040 case VTDeleteOnSalvage: fprintf(STDOUT,"deleteOnSalvage ");
3041 case VTOutOfService: fprintf(STDOUT,"outOfService ");
3042 case VTDeleted: fprintf(STDOUT,"deleted ");
3044 fprintf(STDOUT,"\n");
3047 fprintf(STDOUT,"transactionFlags: ");
3048 fprintf(STDOUT,"delete\n");
3050 MapPartIdIntoName(pntr->partition ,pname);
3051 fprintf(STDOUT,"volume: %u partition: %s procedure: %s\n",pntr->volid,pname, pntr->lastProcName);
3052 if(pntr->callValid){
3053 fprintf(STDOUT,"packetRead: %u lastReceiveTime: %d packetSend: %u lastSendTime: %d\n",pntr->readNext,pntr->lastReceiveTime,pntr->transmitNext, pntr->lastSendTime);
3056 fprintf(STDOUT,"--------------------------------------\n");
3057 fprintf(STDOUT,"\n");
3059 if(oldpntr) free(oldpntr);
3063 static RenameVolume(as)
3064 register struct cmd_syndesc *as;
3066 afs_int32 code1,code2,code;
3067 struct nvldbentry entry;
3069 code1 = VLDB_GetEntryByName(as->parms[0].items->data, &entry);
3071 fprintf(STDERR,"vos: Could not find entry for volume %s\n",as->parms[0].items->data);
3074 code2 = VLDB_GetEntryByName(as->parms[1].items->data, &entry);
3075 if((!code1) && (!code2)) { /*the newname already exists */
3076 fprintf(STDERR,"vos: volume %s already exists\n",as->parms[1].items->data);
3081 fprintf(STDERR,"vos: Could not find entry for volume %s or %s\n",as->parms[0].items->data,as->parms[1].items->data);
3084 if(!VolNameOK(as->parms[0].items->data)){
3085 fprintf(STDERR,"Illegal volume name %s, should not end in .readonly or .backup\n",as->parms[0].items->data);
3088 if(!ISNAMEVALID(as->parms[1].items->data)) {
3089 fprintf(STDERR,"vos: the new volume name %s exceeds the size limit of %d\n",as->parms[1].items->data,VOLSER_OLDMAXVOLNAME - 10);
3092 if(!VolNameOK(as->parms[1].items->data)){
3093 fprintf(STDERR,"Illegal volume name %s, should not end in .readonly or .backup\n",as->parms[1].items->data);
3096 if(IsNumeric(as->parms[1].items->data)){
3097 fprintf(STDERR,"Illegal volume name %s, should not be a number\n",as->parms[1].items->data);
3100 MapHostToNetwork(&entry);
3101 code = UV_RenameVolume(&entry,as->parms[0].items->data,as->parms[1].items->data);
3103 PrintDiagnostics("rename", code);
3106 fprintf(STDOUT,"Renamed volume %s to %s\n",as->parms[0].items->data,as->parms[1].items->data);
3110 GetVolumeInfo(volid, server, part, voltype,rentry)
3111 afs_int32 *server, volid, *part, *voltype;
3112 register struct nvldbentry *rentry;
3117 vcode = VLDB_GetEntryByID(volid, -1, rentry);
3119 fprintf(STDERR,"Could not fetch the entry for volume %u from VLDB \n",volid);
3120 PrintError("",vcode);
3123 MapHostToNetwork(rentry);
3124 if(volid == rentry->volumeId[ROVOL]){
3126 for (i = 0; i < rentry->nServers; i++) {
3127 if ( (index == -1) && (rentry->serverFlags[i] & ITSROVOL) &&
3128 !(rentry->serverFlags[i] & RO_DONTUSE) )
3132 fprintf(STDERR,"RO volume is not found in VLDB entry for volume %u\n", volid);
3136 *server = rentry->serverNumber[index];
3137 *part = rentry->serverPartition[index];
3141 index = Lp_GetRwIndex(rentry);
3143 fprintf(STDERR,"RW Volume is not found in VLDB entry for volume %u\n", volid);
3146 if(volid == rentry->volumeId[RWVOL]){
3148 *server = rentry->serverNumber[index];
3149 *part = rentry->serverPartition[index];
3152 if(volid == rentry->volumeId[BACKVOL]){
3154 *server = rentry->serverNumber[index];
3155 *part = rentry->serverPartition[index];
3160 static DeleteEntry(as)
3161 register struct cmd_syndesc *as;
3167 struct VldbListByAttributes attributes;
3168 nbulkentries arrayEntries;
3169 register struct nvldbentry *vllist;
3170 struct cmd_item *itp;
3173 char prefix[VOLSER_MAXVOLNAME+1];
3175 afs_int32 totalBack=0, totalFail=0, err;
3177 if (as->parms[0].items) { /* -id */
3178 if (as->parms[1].items || as->parms[2].items || as->parms[3].items) {
3179 fprintf(STDERR,"You cannot use -server, -partition, or -prefix with the -id argument\n");
3182 for (itp=as->parms[0].items; itp; itp=itp->next) {
3183 avolid = vsu_GetVolumeID(itp->data, cstruct, &err);
3185 if (err) PrintError("", err);
3186 else fprintf(STDERR, "vos: can't find volume '%s'\n", itp->data);
3189 if (as->parms[4].items) { /* -noexecute */
3190 fprintf(STDOUT,"Would have deleted VLDB entry for %s \n", itp->data);
3194 vcode = ubik_Call(VL_DeleteEntry,cstruct, 0, avolid, RWVOL);
3196 fprintf(STDERR,"Could not delete entry for volume %s\n", itp->data);
3197 fprintf(STDERR,"You must specify a RW volume name or ID "
3198 "(the entire VLDB entry will be deleted)\n", itp->data);
3199 PrintError("",vcode);
3205 fprintf(STDOUT,"Deleted %d VLDB entries\n", totalBack);
3209 if (!as->parms[1].items && !as->parms[2].items && !as->parms[3].items) {
3210 fprintf(STDERR,"You must specify an option\n");
3214 /* Zero out search attributes */
3215 memset(&attributes, 0, sizeof(struct VldbListByAttributes));
3217 if (as->parms[1].items) { /* -prefix */
3218 strncpy(prefix, as->parms[1].items->data, VOLSER_MAXVOLNAME);
3220 if (!as->parms[2].items && !as->parms[3].items) { /* a single entry only */
3221 fprintf(STDERR,"You must provide -server with the -prefix argument\n");
3226 if (as->parms[2].items) { /* -server */
3228 aserver = GetServer(as->parms[2].items->data);
3230 fprintf(STDERR,"vos: server '%s' not found in host table\n",as->parms[2].items->data );
3233 attributes.server = ntohl(aserver);
3234 attributes.Mask |= VLLIST_SERVER;
3237 if (as->parms[3].items) { /* -partition */
3238 if (!as->parms[2].items) {
3239 fprintf(STDERR,"You must provide -server with the -partition argument\n");
3242 apart = volutil_GetPartitionID(as->parms[3].items->data);
3244 fprintf(STDERR,"vos: could not interpret partition name '%s'\n",
3245 as->parms[3].items->data);
3248 attributes.partition = apart;
3249 attributes.Mask |= VLLIST_PARTITION;
3252 /* Print status line of what we are doing */
3253 fprintf(STDOUT,"Deleting VLDB entries for ");
3254 if (as->parms[2].items) {
3255 fprintf(STDOUT,"server %s ", as->parms[2].items->data);
3257 if (as->parms[3].items) {
3259 MapPartIdIntoName(apart, pname);
3260 fprintf(STDOUT,"partition %s ", pname);
3263 fprintf(STDOUT,"which are prefixed with %s ", prefix);
3265 fprintf(STDOUT,"\n");
3268 /* Get all the VLDB entries on a server and/or partition */
3269 memset(&arrayEntries, 0, sizeof(arrayEntries));
3270 vcode = VLDB_ListAttributes(&attributes, &nentries, &arrayEntries);
3272 fprintf(STDERR,"Could not access the VLDB for attributes\n");
3273 PrintError("",vcode);
3277 /* Process each entry */
3278 for (j=0; j<nentries; j++) {
3279 vllist = &arrayEntries.nbulkentries_val[j];
3281 /* It only deletes the RW volumes */
3282 if (strncmp(vllist->name, prefix, strlen(prefix))){
3284 fprintf(STDOUT,"Omitting to delete %s due to prefix %s mismatch\n",
3285 vllist->name, prefix);
3292 if (as->parms[4].items) { /* -noexecute */
3293 fprintf(STDOUT,"Would have deleted VLDB entry for %s \n", vllist->name);
3298 /* Only matches the RW volume name */
3299 avolid = vllist->volumeId[RWVOL];
3300 vcode = ubik_Call(VL_DeleteEntry, cstruct, 0, avolid, RWVOL);
3302 fprintf(STDOUT,"Could not delete VDLB entry for %s\n",vllist->name);
3304 PrintError("",vcode);
3309 fprintf(STDOUT,"Deleted VLDB entry for %s \n",vllist->name);
3314 fprintf(STDOUT,"----------------------\n");
3315 fprintf(STDOUT,"Total VLDB entries deleted: %u; failed to delete: %u\n",totalBack,totalFail);
3316 if (arrayEntries.nbulkentries_val) free(arrayEntries.nbulkentries_val);
3321 static int CompareVldbEntryByName(p1,p2)
3324 struct nvldbentry *arg1,*arg2;
3326 arg1 = (struct nvldbentry *)p1;
3327 arg2 = (struct nvldbentry *)p2;
3328 return(strcmp(arg1->name,arg2->name));
3332 static int CompareVldbEntry(p1,p2)
3335 struct nvldbentry *arg1,*arg2;
3338 char comp1[100],comp2[100];
3339 char temp1[20],temp2[20];
3341 arg1 = (struct nvldbentry *)p1;
3342 arg2 = (struct nvldbentry *)p2;
3346 for(i = 0; i < arg1->nServers; i++)
3347 if(arg1->serverFlags[i] & ITSRWVOL) pos1 = i;
3348 for(i = 0; i < arg2->nServers; i++)
3349 if(arg2->serverFlags[i] & ITSRWVOL) pos2 = i;
3350 if(pos1 == -1 || pos2 == -1){
3354 sprintf(comp1,"%10u",arg1->serverNumber[pos1]);
3355 sprintf(comp2,"%10u",arg2->serverNumber[pos2]);
3356 sprintf(temp1,"%10u",arg1->serverPartition[pos1]);
3357 sprintf(temp2,"%10u",arg2->serverPartition[pos2]);
3358 strcat(comp1,temp1);
3359 strcat(comp2,temp2);
3360 strcat(comp1,arg1->name);
3361 strcat(comp1,arg2->name);
3362 return(strcmp(comp1,comp2));
3368 struct cmd_syndesc *as;
3371 afs_int32 aserver,code;
3373 struct VldbListByAttributes attributes;
3374 nbulkentries arrayEntries;
3375 struct nvldbentry *vllist, *tarray=0, *ttarray;
3376 afs_int32 centries, nentries = 0, tarraysize, parraysize;
3379 int quiet, sort, lock;
3380 afs_int32 thisindex, nextindex;
3385 attributes.Mask = 0;
3386 lock = (as->parms[3].items ? 1 : 0); /* -lock flag */
3387 quiet = (as->parms[4].items ? 1 : 0); /* -quit flag */
3388 sort = (as->parms[5].items ? 0 : 1); /* -nosort flag */
3390 /* If the volume name is given, Use VolumeInfoCmd to look it up
3391 * and not ListAttributes.
3393 if (as->parms[0].items) {
3395 fprintf(STDERR,"vos: illegal use of '-locked' switch, need to specify server and/or partition\n");
3398 code = VolumeInfoCmd(as->parms[0].items->data);
3400 PrintError("",code);
3406 /* Server specified */
3407 if (as->parms[1].items) {
3408 aserver = GetServer(as->parms[1].items->data);
3410 fprintf(STDERR,"vos: server '%s' not found in host table\n",as->parms[1].items->data );
3413 attributes.server = ntohl(aserver);
3414 attributes.Mask |= VLLIST_SERVER;
3417 /* Partition specified */
3418 if (as->parms[2].items) {
3419 apart = volutil_GetPartitionID(as->parms[2].items->data);
3421 fprintf(STDERR,"vos: could not interpret partition name '%s'\n", as->parms[2].items->data);
3424 attributes.partition = apart;
3425 attributes.Mask |= VLLIST_PARTITION;
3429 attributes.Mask |= VLLIST_FLAG;
3430 attributes.flag = VLOP_ALLOPERS;
3433 /* Print header information */
3435 MapPartIdIntoName(apart, pname);
3436 fprintf(STDOUT,"VLDB entries for %s %s%s%s %s\n",
3437 (as->parms[1].items ? "server" : "all" ),
3438 (as->parms[1].items ? as->parms[1].items->data : "servers"),
3439 (as->parms[2].items ? " partition " : ""),
3440 (as->parms[2].items ? pname : ""),
3441 (lock ? "which are locked:" : ""));
3444 for (thisindex = 0; (thisindex != -1); thisindex = nextindex) {
3445 memset(&arrayEntries, 0, sizeof(arrayEntries));
3449 vcode = VLDB_ListAttributesN2(&attributes, 0, thisindex,
3450 ¢ries, &arrayEntries, &nextindex);
3451 if (vcode == RXGEN_OPCODE) {
3452 /* Vlserver not running with ListAttributesN2. Fall back */
3453 vcode = VLDB_ListAttributes(&attributes, ¢ries, &arrayEntries);
3457 fprintf(STDERR,"Could not access the VLDB for attributes\n");
3458 PrintError("",vcode);
3461 nentries += centries;
3463 /* We don't sort, so just print the entries now */
3465 for (j = 0; j < centries; j++) { /* process each entry */
3466 vllist = &arrayEntries.nbulkentries_val[j];
3467 MapHostToNetwork(vllist);
3468 EnumerateEntry(vllist);
3470 if(vllist->flags & VLOP_ALLOPERS)
3471 fprintf(STDOUT," Volume is currently LOCKED \n");
3475 /* So we sort. First we must collect all the entries and keep
3478 else if (centries > 0) {
3480 /* steal away the first bulk entries array */
3481 tarray = (struct nvldbentry *)arrayEntries.nbulkentries_val;
3482 tarraysize = centries * sizeof(struct nvldbentry);
3483 arrayEntries.nbulkentries_val = 0;
3485 /* Grow the tarray to keep the extra entries */
3486 parraysize = (centries * sizeof(struct nvldbentry));
3487 ttarray = (struct nvldbentry *) realloc(tarray, tarraysize + parraysize);
3489 fprintf(STDERR,"Could not allocate enough space for the VLDB entries\n");
3495 memcpy(((char *)tarray)+tarraysize, (char *)arrayEntries.nbulkentries_val, parraysize);
3496 tarraysize += parraysize;
3500 /* Free the bulk array */
3501 if (arrayEntries.nbulkentries_val) {
3502 free(arrayEntries.nbulkentries_val);
3503 arrayEntries.nbulkentries_val = 0;
3507 /* Here is where we now sort all the entries and print them */
3508 if (sort && (nentries > 0)) {
3509 qsort((char *)tarray, nentries, sizeof(struct nvldbentry), CompareVldbEntryByName);
3510 for (vllist=tarray, j=0; j<nentries; j++, vllist++) {
3511 MapHostToNetwork(vllist);
3512 EnumerateEntry(vllist);
3514 if(vllist->flags & VLOP_ALLOPERS)
3515 fprintf(STDOUT," Volume is currently LOCKED \n");
3520 if (!quiet) fprintf(STDOUT,"\nTotal entries: %u\n", nentries);
3521 if (tarray) free(tarray);
3526 register struct cmd_syndesc *as;
3528 afs_int32 apart=0, avolid;
3529 afs_int32 aserver=0, code, aserver1, apart1;
3531 struct VldbListByAttributes attributes;
3532 nbulkentries arrayEntries;
3533 register struct nvldbentry *vllist;
3537 int seenprefix, seenxprefix, exclude, ex, exp, noaction;
3538 afs_int32 totalBack=0;
3539 afs_int32 totalFail=0;
3540 int previdx=-1, error, same;
3543 struct cmd_item *ti;
3547 memset(&attributes, 0, sizeof(struct VldbListByAttributes));
3548 attributes.Mask = 0;
3550 seenprefix = (as->parms[0].items ? 1 : 0);
3551 exclude = (as->parms[3].items ? 1 : 0);
3552 seenxprefix = (as->parms[4].items ? 1 : 0);
3553 noaction = (as->parms[5].items ? 1 : 0);
3555 if (as->parms[1].items) { /* -server */
3556 aserver = GetServer(as->parms[1].items->data);
3558 fprintf(STDERR,"vos: server '%s' not found in host table\n",as->parms[1].items->data );
3561 attributes.server = ntohl(aserver);
3562 attributes.Mask |= VLLIST_SERVER;
3565 if (as->parms[2].items) { /* -partition */
3566 apart = volutil_GetPartitionID(as->parms[2].items->data);
3568 fprintf(STDERR,"vos: could not interpret partition name '%s'\n", as->parms[2].items->data);
3571 attributes.partition = apart;
3572 attributes.Mask |= VLLIST_PARTITION;
3575 /* Check to make sure the prefix and xprefix expressions compile ok */
3577 for (ti=as->parms[0].items; ti; ti=ti->next) {
3578 if (strncmp(ti->data,"^",1) == 0) {
3579 ccode = (char *)re_comp(ti->data);
3581 fprintf(STDERR,"Unrecognizable -prefix regular expression: '%s': %s\n",
3589 for (ti=as->parms[4].items; ti; ti=ti->next) {
3590 if (strncmp(ti->data,"^",1) == 0) {
3591 ccode = (char *)re_comp(ti->data);
3593 fprintf(STDERR,"Unrecognizable -xprefix regular expression: '%s': %s\n",
3601 memset(&arrayEntries, 0, sizeof(arrayEntries)); /* initialize to hint the stub to alloc space */
3602 vcode = VLDB_ListAttributes(&attributes, &nentries, &arrayEntries);
3604 fprintf(STDERR,"Could not access the VLDB for attributes\n");
3605 PrintError("",vcode);
3609 if (as->parms[1].items || as->parms[2].items || verbose) {
3610 fprintf(STDOUT,"%s up volumes", (noaction?"Would have backed":"Backing"));
3612 if (as->parms[1].items) {
3613 fprintf(STDOUT," on server %s", as->parms[1].items->data);
3614 } else if (as->parms[2].items) {
3615 fprintf(STDOUT," for all servers");
3618 if (as->parms[2].items) {
3619 MapPartIdIntoName(apart, pname);
3620 fprintf(STDOUT," partition %s", pname);
3623 if (seenprefix || (!seenprefix && seenxprefix)) {
3624 ti = (seenprefix ? as->parms[0].items : as->parms[4].items);
3625 ex = (seenprefix ? exclude : !exclude);
3626 exp = (strncmp(ti->data,"^",1) == 0);
3627 fprintf(STDOUT," which %smatch %s '%s'", (ex ? "do not " : ""),
3628 (exp?"expression":"prefix"), ti->data);
3629 for (ti=ti->next; ti; ti=ti->next) {
3630 exp = (strncmp(ti->data,"^",1) == 0);
3631 printf(" %sor %s '%s'", (ex ? "n" : ""),
3632 (exp?"expression":"prefix"), ti->data);
3636 if (seenprefix && seenxprefix) {
3637 ti = as->parms[4].items;
3638 exp = (strncmp(ti->data,"^",1) == 0);
3639 fprintf(STDOUT," %swhich match %s '%s'",
3640 (exclude?"adding those ":"removing those "),
3641 (exp?"expression":"prefix"), ti->data);
3642 for (ti=ti->next; ti; ti=ti->next) {
3643 exp = (strncmp(ti->data,"^",1) == 0);
3644 printf(" or %s '%s'", (exp?"expression":"prefix"), ti->data);
3647 fprintf(STDOUT," .. ");
3648 if (verbose) fprintf(STDOUT,"\n");
3652 for (j=0; j<nentries; j++) { /* process each vldb entry */
3653 vllist = &arrayEntries.nbulkentries_val[j];
3656 for (ti=as->parms[0].items; ti; ti=ti->next) {
3657 if (strncmp(ti->data,"^",1) == 0) {
3658 ccode = (char *)re_comp(ti->data);
3660 fprintf(STDERR,"Error in -prefix regular expression: '%s': %s\n",
3664 match = (re_exec(vllist->name) == 1);
3666 match = (strncmp(vllist->name,ti->data,strlen(ti->data)) == 0);
3674 /* Without the -exclude flag: If it matches the prefix, then
3675 * check if we want to exclude any from xprefix.
3676 * With the -exclude flag: If it matches the prefix, then
3677 * check if we want to add any from xprefix.
3679 if (match && seenxprefix) {
3680 for (ti=as->parms[4].items; ti; ti=ti->next) {
3681 if (strncmp(ti->data,"^",1) == 0) {
3682 ccode = (char *)re_comp(ti->data);
3684 fprintf(STDERR,"Error in -xprefix regular expression: '%s': %s\n",
3688 if (re_exec(vllist->name) == 1) {
3693 if (strncmp(vllist->name,ti->data,strlen(ti->data)) == 0) {
3701 if (exclude) match = !match; /* -exclude will reverse the match */
3702 if (!match) continue; /* Skip if no match */
3704 /* Print list of volumes to backup */
3706 fprintf(STDOUT," %s\n", vllist->name);
3710 if(!(vllist->flags & RW_EXISTS)){
3712 fprintf(STDOUT,"Omitting to backup %s since RW volume does not exist \n", vllist->name);
3713 fprintf(STDOUT,"\n");
3719 avolid = vllist->volumeId[RWVOL];
3720 MapHostToNetwork(vllist);
3721 GetServerAndPart(vllist,RWVOL,&aserver1,&apart1,&previdx);
3722 if(aserver1 == -1 || apart1 == -1){
3723 fprintf(STDOUT,"could not backup %s, invalid VLDB entry\n",vllist->name);
3728 same = VLDB_IsSameAddrs(aserver, aserver1, &error);
3730 fprintf(STDERR,"Failed to get info about server's %d address(es) from vlserver (err=%d); aborting call!\n",
3736 if ((aserver && !same) || (apart && (apart != apart1))) {
3738 fprintf(STDOUT, "Omitting to backup %s since the RW is in a different location\n", vllist->name);
3743 time_t now = time(0);
3744 fprintf(STDOUT,"Creating backup volume for %s on %s",vllist->name, ctime(&now));
3748 code = UV_BackupVolume(aserver1, apart1, avolid);
3750 fprintf(STDOUT,"Could not backup %s\n",vllist->name);
3756 if (verbose) fprintf(STDOUT,"\n");
3758 } /* process each vldb entry */
3759 fprintf(STDOUT,"done\n");
3760 fprintf(STDOUT,"Total volumes backed up: %u; failed to backup: %u\n",totalBack,totalFail);
3762 if(arrayEntries.nbulkentries_val) free(arrayEntries.nbulkentries_val);
3766 static UnlockVLDB(as)
3767 register struct cmd_syndesc *as;
3770 afs_int32 aserver,code;
3772 struct VldbListByAttributes attributes;
3773 nbulkentries arrayEntries;
3774 register struct nvldbentry *vllist;
3783 attributes.Mask = 0;
3785 if(as->parms[0].items) {/* server specified */
3786 aserver = GetServer(as->parms[0].items->data);
3788 fprintf(STDERR,"vos: server '%s' not found in host table\n",as->parms[0].items->data );
3791 attributes.server = ntohl(aserver);
3792 attributes.Mask |= VLLIST_SERVER;
3794 if(as->parms[1].items) {/* partition specified */
3795 apart = volutil_GetPartitionID(as->parms[1].items->data);
3797 fprintf(STDERR,"vos: could not interpret partition name '%s'\n", as->parms[1].items->data);
3800 if (!IsPartValid(apart,aserver,&code)){/*check for validity of the partition */
3801 if(code) PrintError("",code);
3802 else fprintf(STDERR,"vos : partition %s does not exist on the server\n",as->parms[1].items->data);
3805 attributes.partition = apart;
3806 attributes.Mask |= VLLIST_PARTITION;
3808 attributes.flag = VLOP_ALLOPERS;
3809 attributes.Mask |= VLLIST_FLAG;
3810 memset(&arrayEntries, 0, sizeof(arrayEntries)); /*initialize to hint the stub to alloc space */
3811 vcode = VLDB_ListAttributes(&attributes, &nentries, &arrayEntries);
3813 fprintf(STDERR,"Could not access the VLDB for attributes\n");
3814 PrintError("",vcode);
3817 for(j=0;j<nentries;j++) { /* process each entry */
3818 vllist = &arrayEntries.nbulkentries_val[j];
3819 volid = vllist->volumeId[RWVOL];
3820 vcode = ubik_Call(VL_ReleaseLock,cstruct, 0, volid,-1, LOCKREL_OPCODE | LOCKREL_AFSID | LOCKREL_TIMESTAMP);
3822 fprintf(STDERR,"Could not unlock entry for volume %s\n",vllist->name);
3823 PrintError("",vcode);
3828 MapPartIdIntoName(apart,pname);
3829 if(totalE) fprintf(STDOUT,"Could not lock %u VLDB entries of %u locked entries\n",totalE,nentries);
3831 if(as->parms[0].items) {
3832 fprintf(STDOUT,"Unlocked all the VLDB entries for volumes on server %s ",as->parms[0].items->data);
3833 if(as->parms[1].items){
3834 MapPartIdIntoName(apart,pname);
3835 fprintf(STDOUT,"partition %s\n",pname);
3837 else fprintf(STDOUT,"\n");
3840 else if(as->parms[1].items){
3841 MapPartIdIntoName(apart,pname);
3842 fprintf(STDOUT,"Unlocked all the VLDB entries for volumes on partition %s on all servers\n",pname);
3846 if(arrayEntries.nbulkentries_val) free(arrayEntries.nbulkentries_val);
3850 static PartitionInfo(as)
3851 register struct cmd_syndesc *as;
3854 afs_int32 aserver,code;
3856 struct diskPartition partition;
3857 struct partList dummyPartList;
3861 aserver = GetServer(as->parms[0].items->data);
3863 fprintf(STDERR,"vos: server '%s' not found in host table\n",as->parms[0].items->data );
3866 if(as->parms[1].items){
3867 apart = volutil_GetPartitionID(as->parms[1].items->data);
3869 fprintf(STDERR,"vos: could not interpret partition name '%s'\n", as->parms[1].items->data);
3872 dummyPartList.partId[0] = apart;
3873 dummyPartList.partFlags[0] = PARTVALID;
3877 if (!IsPartValid(apart,aserver,&code)){/*check for validity of the partition */
3878 if(code) PrintError("",code);
3879 else fprintf(STDERR,"vos : partition %s does not exist on the server\n",as->parms[1].items->data);
3884 code = UV_ListPartitions(aserver,&dummyPartList, &cnt);
3886 PrintDiagnostics("listpart", code);
3890 for(i = 0 ; i < cnt ; i++){
3891 if(dummyPartList.partFlags[i] & PARTVALID){
3892 MapPartIdIntoName(dummyPartList.partId[i],pname);
3893 code = UV_PartitionInfo(aserver,pname,&partition);
3895 fprintf(STDERR,"Could not get information on partition %s\n",pname);
3896 PrintError("",code);
3899 fprintf(STDOUT,"Free space on partition %s: %d K blocks out of total %d\n",pname,partition.free,partition.minFree);
3905 static ChangeAddr(as)
3906 register struct cmd_syndesc *as;
3909 afs_int32 ip1, ip2, vcode;
3912 ip1 = GetServer(as->parms[0].items->data);
3914 fprintf(STDERR, "vos: invalid host address\n");
3918 if ( ( as->parms[1].items && as->parms[2].items) ||
3919 (!as->parms[1].items && !as->parms[2].items) ) {
3920 fprintf(STDERR, "vos: Must specify either '-newaddr <addr>' or '-remove' flag\n");
3924 if (as->parms[1].items) {
3925 ip2 = GetServer(as->parms[1].items->data);
3927 fprintf(STDERR, "vos: invalid host address\n");
3931 /* Play a trick here. If we are removing an address, ip1 will be -1
3932 * and ip2 will be the original address. This switch prevents an
3933 * older revision vlserver from removing the IP address.
3940 vcode = ubik_Call_New(VL_ChangeAddr, cstruct, 0, ntohl(ip1), ntohl(ip2) );
3943 fprintf(STDERR,"Could not remove server %s from the VLDB\n",
3944 as->parms[0].items->data);
3945 if (vcode == VL_NOENT) {
3946 fprintf(STDERR, "vlserver does not support the remove flag or ");
3949 fprintf(STDERR,"Could not change server %s to server %s\n",
3950 as->parms[0].items->data, as->parms[1].items->data);
3952 PrintError("",vcode);
3957 fprintf(STDOUT,"Removed server %s from the VLDB\n",
3958 as->parms[0].items->data);
3960 fprintf(STDOUT,"Changed server %s to server %s\n",
3961 as->parms[0].items->data, as->parms[1].items->data);
3967 print_addrs(const bulkaddrs *addrs, const afsUUID *m_uuid, int nentries, int print, int noresolve)
3971 struct VLCallBack unused;
3974 ListAddrByAttributes m_attrs;
3975 afs_int32 m_unique, m_nentries, *m_addrp;
3976 afs_int32 base, index;
3980 afsUUID_to_string(m_uuid, buf, sizeof(buf));
3981 printf("UUID: %s\n", buf);
3984 /* print out the list of all the server */
3985 addrp = (afs_int32 *)addrs->bulkaddrs_val;
3986 for (i=0; i<nentries; i++, addrp++) {
3987 /* If it is a multihomed address, then we will need to
3988 * get the addresses for this multihomed server from
3989 * the vlserver and print them.
3991 if ( ((*addrp & 0xff000000) == 0xff000000) && ((*addrp)&0xffff) ) {
3992 /* Get the list of multihomed fileservers */
3993 base = (*addrp>>16) & 0xff;
3994 index = (*addrp) & 0xffff;
3996 if ( (base >= 0) && (base <= VL_MAX_ADDREXTBLKS) &&
3997 (index >= 1) && (index <= VL_MHSRV_PERBLK) ) {
3998 m_attrs.Mask = VLADDR_INDEX;
3999 m_attrs.index = (base * VL_MHSRV_PERBLK) + index;
4001 m_addrs.bulkaddrs_val = 0;
4002 m_addrs.bulkaddrs_len = 0;
4003 vcode = ubik_Call(VL_GetAddrsU, cstruct, 0,
4004 &m_attrs, &m_uuid, &m_unique, &m_nentries, &m_addrs);
4006 fprintf(STDERR,"vos: could not list the multi-homed server addresses\n");
4007 PrintError("",vcode);
4010 /* Print the list */
4011 m_addrp = (afs_int32 *)m_addrs.bulkaddrs_val;
4012 for (j=0; j<m_nentries; j++, m_addrp++) {
4013 *m_addrp = htonl(*m_addrp);
4016 printf("%s ", afs_inet_ntoa_r(*m_addrp,hoststr));
4018 printf("%s ", hostutil_GetNameByINet(*m_addrp));
4022 printf("<unknown>\n");
4031 /* Otherwise, it is a non-multihomed entry and contains
4032 * the IP address of the server - print it.
4034 *addrp = htonl(*addrp);
4037 printf("%s\n", afs_inet_ntoa_r(*addrp,hoststr));
4039 printf("%s\n", hostutil_GetNameByINet(*addrp));
4049 static ListAddrs(as)
4050 register struct cmd_syndesc *as;
4053 afs_int32 i, j, noresolve=0, printuuid=0;
4054 struct VLCallBack unused;
4055 afs_int32 nentries, *addrp;
4056 bulkaddrs addrs, m_addrs;
4057 ListAddrByAttributes m_attrs;
4058 afsUUID m_uuid, askuuid;
4059 afs_int32 m_unique, m_nentries, *m_addrp;
4060 afs_int32 base, index;
4062 memset(&m_attrs, 0, sizeof(struct ListAddrByAttributes));
4063 m_attrs.Mask = VLADDR_INDEX;
4065 memset(&m_addrs, 0, sizeof(bulkaddrs));
4066 memset(&askuuid, 0, sizeof(afsUUID));
4067 if (as->parms[0].items) {
4069 afsUUID_from_string(as->parms[0].items->data, &askuuid);
4070 m_attrs.Mask = VLADDR_UUID;
4071 m_attrs.uuid = askuuid;
4073 if (as->parms[1].items) {
4077 he = hostutil_GetHostByName((char*)as->parms[1].items->data);
4080 "Can't get host info for '%s'\n",
4081 as->parms[1].items->data);
4084 memcpy(&saddr, he->h_addr, 4);
4085 m_attrs.Mask = VLADDR_IPADDR;
4086 m_attrs.ipaddr = ntohl(saddr);
4088 if (as->parms[2].items) {
4091 if (as->parms[3].items) {
4095 m_addrs.bulkaddrs_val = 0;
4096 m_addrs.bulkaddrs_len = 0;
4098 vcode = ubik_Call_New(VL_GetAddrs, cstruct, 0,
4099 0, 0, &m_unique, &nentries, &m_addrs);
4101 fprintf(STDERR,"vos: could not list the server addresses\n");
4102 PrintError("",vcode);
4107 m_addrs.bulkaddrs_val = 0;
4108 m_addrs.bulkaddrs_len = 0;
4113 vcode = ubik_Call_New(VL_GetAddrsU, cstruct, 0, &m_attrs, &m_uuid,
4114 &m_unique, &m_nentries, &m_addrs);
4115 if(vcode == VL_NOENT) {
4121 if (vcode == VL_INDEXERANGE) {
4126 fprintf(STDERR,"vos: could not list the server addresses\n");
4127 PrintError("",vcode);
4131 print_addrs(&m_addrs, &m_uuid, m_nentries, printuuid, noresolve);
4134 if ((as->parms[1].items)||(as->parms[0].items)||(i>nentries))
4141 static LockEntry(as)
4142 register struct cmd_syndesc *as;
4145 afs_int32 avolid,vcode, err;
4147 avolid = vsu_GetVolumeID(as->parms[0].items->data, cstruct, &err);
4149 if (err) PrintError("", err);
4150 else fprintf(STDERR, "vos: can't find volume '%s'\n", as->parms[0].items->data);
4153 vcode = ubik_Call(VL_SetLock,cstruct, 0, avolid, -1, VLOP_DELETE);
4155 fprintf(STDERR,"Could not lock VLDB entry for volume %s\n",as->parms[0].items->data);
4156 PrintError("",vcode);
4159 fprintf(STDOUT,"Locked VLDB entry for volume %s\n",as->parms[0].items->data);
4163 PrintDiagnostics(astring, acode)
4167 if (acode == EACCES) {
4168 fprintf(STDERR,"You are not authorized to perform the 'vos %s' command (%d)\n",
4172 fprintf(STDERR,"Error in vos %s command.\n", astring);
4173 PrintError("", acode);
4179 static MyBeforeProc(as, arock)
4180 struct cmd_syndesc *as;
4182 register char *tcell;
4183 register afs_int32 code;
4184 register afs_int32 sauth;
4186 /* Initialize the ubik_client connection */
4187 rx_SetRxDeadTime(90);
4188 cstruct = (struct ubik_client *)0;
4192 if (as->parms[12].items) /* if -cell specified */
4193 tcell = as->parms[12].items->data;
4194 if(as->parms[14].items) /* -serverauth specified */
4196 if(as->parms[16].items) /* -crypt specified */
4198 if (code = vsu_ClientInit((as->parms[13].items != 0), confdir, tcell, sauth,
4199 &cstruct, UV_SetSecurity)) {
4200 fprintf(STDERR,"could not initialize VLDB library (code=%u) \n",code);
4204 if(as->parms[15].items) /* -verbose flag set */
4213 /* this sucks but it works for now.
4218 #include "AFS_component_version_number.c"
4223 register afs_int32 code;
4225 register struct cmd_syndesc *ts;
4227 #ifdef AFS_AIX32_ENV
4229 * The following signal action for AIX is necessary so that in case of a
4230 * crash (i.e. core is generated) we can include the user's data section
4231 * in the core dump. Unfortunately, by default, only a partial core is
4232 * generated which, in many cases, isn't too useful.
4234 struct sigaction nsa;
4236 sigemptyset(&nsa.sa_mask);
4237 nsa.sa_handler = SIG_DFL;
4238 nsa.sa_flags = SA_FULLDUMP;
4239 sigaction(SIGSEGV, &nsa, NULL);
4242 confdir = AFSDIR_CLIENT_ETC_DIRPATH;
4244 cmd_SetBeforeProc(MyBeforeProc, NULL);
4246 ts = cmd_CreateSyntax("create", CreateVolume, 0, "create a new volume");
4247 cmd_AddParm(ts, "-server", CMD_SINGLE, 0, "machine name");
4248 cmd_AddParm(ts, "-partition", CMD_SINGLE, 0, "partition name");
4249 cmd_AddParm(ts, "-name", CMD_SINGLE, 0, "volume name");
4250 cmd_AddParm(ts, "-maxquota", CMD_SINGLE, CMD_OPTIONAL, "initial quota (KB)");
4252 cmd_AddParm(ts, "-minquota", CMD_SINGLE, CMD_OPTIONAL, "");
4256 ts = cmd_CreateSyntax("remove", DeleteVolume, 0, "delete a volume");
4257 cmd_AddParm(ts, "-server", CMD_SINGLE, CMD_OPTIONAL, "machine name");
4258 cmd_AddParm(ts, "-partition", CMD_SINGLE, CMD_OPTIONAL, "partition name");
4259 cmd_AddParm(ts, "-id", CMD_SINGLE, 0, "volume name or ID");
4263 ts = cmd_CreateSyntax("move", MoveVolume, 0, "move a volume");
4264 cmd_AddParm(ts, "-id", CMD_SINGLE, 0, "volume name or ID");
4265 cmd_AddParm(ts, "-fromserver", CMD_SINGLE, 0, "machine name on source");
4266 cmd_AddParm(ts, "-frompartition", CMD_SINGLE, 0, "partition name on source");
4267 cmd_AddParm(ts, "-toserver", CMD_SINGLE, 0, "machine name on destination");
4268 cmd_AddParm(ts, "-topartition", CMD_SINGLE, 0, "partition name on destination");
4271 ts = cmd_CreateSyntax("copy", CopyVolume, 0, "copy a volume");
4272 cmd_AddParm(ts, "-id", CMD_SINGLE, 0, "volume name or ID on source");
4273 cmd_AddParm(ts, "-fromserver", CMD_SINGLE, 0, "machine name on source");
4274 cmd_AddParm(ts, "-frompartition", CMD_SINGLE, 0, "partition name on source");
4275 cmd_AddParm(ts, "-toname", CMD_SINGLE, 0, "volume name on destination");
4276 cmd_AddParm(ts, "-toserver", CMD_SINGLE, 0, "machine name on destination");
4277 cmd_AddParm(ts, "-topartition", CMD_SINGLE, 0, "partition name on destination");
4280 ts = cmd_CreateSyntax("backup", BackupVolume, 0, "make backup of a volume");
4281 cmd_AddParm(ts, "-id", CMD_SINGLE, 0, "volume name or ID");
4284 ts = cmd_CreateSyntax("release", ReleaseVolume, 0, "release a volume");
4285 cmd_AddParm(ts, "-id", CMD_SINGLE, 0, "volume name or ID");
4286 cmd_AddParm(ts, "-force", CMD_FLAG, CMD_OPTIONAL, "force a complete release");
4289 ts = cmd_CreateSyntax("dump", DumpVolume, 0, "dump a volume");
4290 cmd_AddParm(ts, "-id", CMD_SINGLE, 0, "volume name or ID");
4291 cmd_AddParm(ts, "-time", CMD_SINGLE, CMD_OPTIONAL, "dump from time");
4292 cmd_AddParm(ts, "-file", CMD_SINGLE, CMD_OPTIONAL, "dump file");
4293 cmd_AddParm(ts, "-server", CMD_SINGLE, CMD_OPTIONAL, "server");
4294 cmd_AddParm(ts, "-partition", CMD_SINGLE, CMD_OPTIONAL, "partition");
4295 cmd_AddParm(ts, "-clone", CMD_FLAG, CMD_OPTIONAL, "dump a clone of the volume");
4298 ts = cmd_CreateSyntax("restore", RestoreVolume, 0, "restore a volume");
4299 cmd_AddParm(ts, "-server", CMD_SINGLE, 0, "machine name");
4300 cmd_AddParm(ts, "-partition", CMD_SINGLE, 0, "partition name");
4301 cmd_AddParm(ts, "-name", CMD_SINGLE, 0, "name of volume to be restored");
4302 cmd_AddParm(ts, "-file", CMD_SINGLE,CMD_OPTIONAL, "dump file");
4303 cmd_AddParm(ts, "-id", CMD_SINGLE,CMD_OPTIONAL, "volume ID");
4304 cmd_AddParm(ts, "-overwrite", CMD_SINGLE,CMD_OPTIONAL, "abort | full | incremental");
4305 cmd_AddParm(ts, "-offline", CMD_FLAG, CMD_OPTIONAL,
4306 "leave restored volume offline");
4307 cmd_AddParm(ts, "-readonly", CMD_FLAG, CMD_OPTIONAL,
4308 "make restored volume read-only");
4311 ts = cmd_CreateSyntax("unlock", LockReleaseCmd, 0, "release lock on VLDB entry for a volume");
4312 cmd_AddParm(ts, "-id", CMD_SINGLE, 0, "volume name or ID");
4315 ts = cmd_CreateSyntax("changeloc", ChangeLocation, 0, "change an RW volume's location in the VLDB");
4316 cmd_AddParm(ts, "-server", CMD_SINGLE, 0, "machine name for new location");
4317 cmd_AddParm(ts, "-partition", CMD_SINGLE, 0, "partition name for new location");
4318 cmd_AddParm(ts, "-id", CMD_SINGLE, 0, "volume name or ID");
4321 ts = cmd_CreateSyntax("addsite", AddSite, 0, "add a replication site");
4322 cmd_AddParm(ts, "-server", CMD_SINGLE, 0, "machine name for new site");
4323 cmd_AddParm(ts, "-partition", CMD_SINGLE, 0, "partition name for new site");
4324 cmd_AddParm(ts, "-id", CMD_SINGLE, 0, "volume name or ID");
4327 ts = cmd_CreateSyntax("remsite", RemoveSite, 0, "remove a replication site");
4328 cmd_AddParm(ts, "-server", CMD_SINGLE, 0, "machine name");
4329 cmd_AddParm(ts, "-partition", CMD_SINGLE, 0, "partition name");
4330 cmd_AddParm(ts, "-id", CMD_SINGLE, 0, "volume name or ID");
4333 ts = cmd_CreateSyntax("listpart", ListPartitions, 0, "list partitions");
4334 cmd_AddParm(ts, "-server", CMD_SINGLE, 0, "machine name");
4337 ts = cmd_CreateSyntax("listvol", ListVolumes, 0, "list volumes on server (bypass VLDB)");
4338 cmd_AddParm(ts, "-server", CMD_SINGLE, 0, "machine name");
4339 cmd_AddParm(ts, "-partition", CMD_SINGLE,CMD_OPTIONAL, "partition name");
4340 cmd_AddParm(ts, "-fast", CMD_FLAG, CMD_OPTIONAL, "minimal listing");
4341 cmd_AddParm(ts, "-long", CMD_FLAG, CMD_OPTIONAL,
4342 "list all normal volume fields");
4343 cmd_AddParm(ts, "-quiet", CMD_FLAG, CMD_OPTIONAL, "generate minimal information");
4344 cmd_AddParm(ts, "-extended", CMD_FLAG, CMD_OPTIONAL,
4345 "list extended volume fields");
4346 #ifdef FULL_LISTVOL_SWITCH
4347 cmd_AddParm(ts, "-format", CMD_FLAG, CMD_OPTIONAL,
4348 "machine readable format");
4349 #endif /* FULL_LISTVOL_SWITCH */
4352 ts = cmd_CreateSyntax("syncvldb", SyncVldb, 0, "synchronize VLDB with server");
4353 cmd_AddParm(ts, "-server", CMD_SINGLE, CMD_OPTIONAL, "machine name");
4354 cmd_AddParm(ts, "-partition", CMD_SINGLE,CMD_OPTIONAL , "partition name");
4355 cmd_AddParm(ts, "-volume", CMD_SINGLE,CMD_OPTIONAL , "volume name or ID");
4358 ts = cmd_CreateSyntax("syncserv", SyncServer, 0, "synchronize server with VLDB");
4359 cmd_AddParm(ts, "-server", CMD_SINGLE, 0, "machine name");
4360 cmd_AddParm(ts, "-partition", CMD_SINGLE,CMD_OPTIONAL , "partition name");
4363 ts = cmd_CreateSyntax("examine", ExamineVolume, 0, "everything about the volume");
4364 cmd_AddParm(ts, "-id", CMD_SINGLE, 0, "volume name or ID");
4365 cmd_AddParm(ts, "-extended", CMD_FLAG, CMD_OPTIONAL,
4366 "list extended volume fields");
4367 #ifdef FULL_LISTVOL_SWITCH
4368 cmd_AddParm(ts, "-format", CMD_FLAG, CMD_OPTIONAL,
4369 "machine readable format");
4370 #endif /* FULL_LISTVOL_SWITCH */
4372 cmd_CreateAlias (ts, "volinfo");
4374 ts = cmd_CreateSyntax("setfields", SetFields, 0, "change volume info fields");
4375 cmd_AddParm(ts, "-id", CMD_SINGLE, 0, "volume name or ID");
4376 cmd_AddParm(ts, "-maxquota", CMD_SINGLE, CMD_OPTIONAL, "quota (KB)");
4377 cmd_AddParm(ts, "-clearuse", CMD_FLAG, CMD_OPTIONAL, "clear dayUse");
4380 ts = cmd_CreateSyntax("offline", volOffline, 0, (char *) CMD_HIDDEN);
4381 cmd_AddParm(ts, "-server", CMD_SINGLE, 0, "server name");
4382 cmd_AddParm(ts, "-partition", CMD_SINGLE, 0, "partition name");
4383 cmd_AddParm(ts, "-id", CMD_SINGLE, 0, "volume name or ID");
4384 cmd_AddParm(ts, "-sleep", CMD_SINGLE, CMD_OPTIONAL, "seconds to sleep");
4385 cmd_AddParm(ts, "-busy", CMD_FLAG, CMD_OPTIONAL, "busy volume");
4388 ts = cmd_CreateSyntax("online", volOnline, 0, (char *) CMD_HIDDEN);
4389 cmd_AddParm(ts, "-server", CMD_SINGLE, 0, "server name");
4390 cmd_AddParm(ts, "-partition", CMD_SINGLE, 0, "partition name");
4391 cmd_AddParm(ts, "-id", CMD_SINGLE, 0, "volume name or ID");
4394 ts = cmd_CreateSyntax("zap", VolumeZap, 0, "delete the volume, don't bother with VLDB");
4395 cmd_AddParm(ts, "-server", CMD_SINGLE, 0, "machine name");
4396 cmd_AddParm(ts, "-partition", CMD_SINGLE, 0, "partition name");
4397 cmd_AddParm(ts, "-id", CMD_SINGLE, 0, "volume ID");
4398 cmd_AddParm(ts, "-force", CMD_FLAG, CMD_OPTIONAL, "force deletion of bad volumes");
4399 cmd_AddParm(ts, "-backup", CMD_FLAG, CMD_OPTIONAL, "also delete backup volume if one is found");
4402 ts = cmd_CreateSyntax("status", VolserStatus, 0, "report on volser status");
4403 cmd_AddParm(ts, "-server", CMD_SINGLE, 0, "machine name");
4406 ts = cmd_CreateSyntax("rename", RenameVolume, 0, "rename a volume");
4407 cmd_AddParm(ts, "-oldname", CMD_SINGLE, 0, "old volume name ");
4408 cmd_AddParm(ts, "-newname", CMD_SINGLE, 0, "new volume name ");
4411 ts = cmd_CreateSyntax("listvldb", ListVLDB, 0, "list volumes in the VLDB");
4412 cmd_AddParm(ts, "-name", CMD_SINGLE,CMD_OPTIONAL, "volume name or ID");
4413 cmd_AddParm(ts, "-server", CMD_SINGLE,CMD_OPTIONAL, "machine name");
4414 cmd_AddParm(ts, "-partition", CMD_SINGLE,CMD_OPTIONAL, "partition name");
4415 cmd_AddParm(ts, "-locked", CMD_FLAG, CMD_OPTIONAL, "locked volumes only");
4416 cmd_AddParm(ts, "-quiet", CMD_FLAG, CMD_OPTIONAL, "generate minimal information");
4417 cmd_AddParm(ts, "-nosort", CMD_FLAG, CMD_OPTIONAL, "do not alphabetically sort the volume names");
4420 ts = cmd_CreateSyntax("backupsys", BackSys, 0, "en masse backups");
4421 cmd_AddParm(ts, "-prefix", CMD_LIST,CMD_OPTIONAL, "common prefix on volume(s)");
4422 cmd_AddParm(ts, "-server", CMD_SINGLE,CMD_OPTIONAL, "machine name");
4423 cmd_AddParm(ts, "-partition", CMD_SINGLE,CMD_OPTIONAL, "partition name");
4424 cmd_AddParm(ts, "-exclude", CMD_FLAG, CMD_OPTIONAL, "exclude common prefix volumes");
4425 cmd_AddParm(ts, "-xprefix", CMD_LIST, CMD_OPTIONAL, "negative prefix on volume(s)");
4426 cmd_AddParm(ts, "-dryrun", CMD_FLAG, CMD_OPTIONAL, "no action");
4429 ts = cmd_CreateSyntax("delentry", DeleteEntry, 0, "delete VLDB entry for a volume");
4430 cmd_AddParm(ts, "-id", CMD_LIST, CMD_OPTIONAL, "volume name or ID");
4431 cmd_AddParm(ts, "-prefix", CMD_SINGLE,CMD_OPTIONAL, "prefix of the volume whose VLDB entry is to be deleted");
4432 cmd_AddParm(ts, "-server", CMD_SINGLE,CMD_OPTIONAL, "machine name");
4433 cmd_AddParm(ts, "-partition", CMD_SINGLE,CMD_OPTIONAL, "partition name");
4434 cmd_AddParm(ts, "-noexecute", CMD_FLAG,CMD_OPTIONAL|CMD_HIDE, "no execute");
4437 ts = cmd_CreateSyntax("partinfo", PartitionInfo, 0, "list partition information");
4438 cmd_AddParm(ts, "-server", CMD_SINGLE, 0, "machine name");
4439 cmd_AddParm(ts, "-partition", CMD_SINGLE,CMD_OPTIONAL, "partition name");
4442 ts = cmd_CreateSyntax("unlockvldb", UnlockVLDB, 0, "unlock all the locked entries in the VLDB");
4443 cmd_AddParm(ts, "-server", CMD_SINGLE,CMD_OPTIONAL, "machine name");
4444 cmd_AddParm(ts, "-partition", CMD_SINGLE,CMD_OPTIONAL, "partition name");
4447 ts = cmd_CreateSyntax("lock", LockEntry, 0, "lock VLDB entry for a volume");
4448 cmd_AddParm(ts, "-id", CMD_SINGLE, 0, "volume name or ID");
4451 ts = cmd_CreateSyntax("changeaddr", ChangeAddr, 0, "change the IP address of a file server");
4452 cmd_AddParm(ts, "-oldaddr", CMD_SINGLE, 0, "original IP address");
4453 cmd_AddParm(ts, "-newaddr", CMD_SINGLE, CMD_OPTIONAL, "new IP address");
4454 cmd_AddParm(ts, "-remove", CMD_FLAG, CMD_OPTIONAL, "remove the IP address from the VLDB");
4457 ts = cmd_CreateSyntax("listaddrs", ListAddrs, 0, "list the IP address of all file servers registered in the VLDB");
4458 cmd_AddParm(ts, "-uuid", CMD_SINGLE, CMD_OPTIONAL, "uuid of server");
4459 cmd_AddParm(ts, "-host", CMD_SINGLE, CMD_OPTIONAL, "address of host");
4460 cmd_AddParm(ts, "-noresolve", CMD_FLAG, CMD_OPTIONAL, "don't resolve addresses");
4461 cmd_AddParm(ts, "-printuuid", CMD_FLAG, CMD_OPTIONAL, "print uuid of hosts");
4464 code = cmd_Dispatch(argc, argv);
4466 /* Shut down the ubik_client and rx connections */
4468 ubik_ClientDestroy (cstruct);