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>
35 #include <rx/rx_globals.h>
37 #include <afs/vlserver.h>
39 #include <afs/cellconfig.h>
41 #include <afs/afsutil.h>
43 #include <afs/afsint.h>
65 #define COMMONPARMS cmd_Seek(ts, 12);\
66 cmd_AddParm(ts, "-cell", CMD_SINGLE, CMD_OPTIONAL, "cell name");\
67 cmd_AddParm(ts, "-noauth", CMD_FLAG, CMD_OPTIONAL, "don't authenticate");\
68 cmd_AddParm(ts, "-localauth",CMD_FLAG,CMD_OPTIONAL,"use server tickets");\
69 cmd_AddParm(ts, "-verbose", CMD_FLAG, CMD_OPTIONAL, "verbose");\
70 cmd_AddParm(ts, "-encrypt", CMD_FLAG, CMD_OPTIONAL, "encrypt commands");\
72 #define ERROR_EXIT(code) {error=(code); goto error_exit;}
76 struct rx_connection *tconn;
78 extern struct ubik_client *cstruct;
80 extern struct rx_connection *UV_Bind();
81 extern struct rx_securityClass *rxnull_NewClientSecurityObject();
82 extern int UV_SetSecurity();
83 extern int UV_SetVolumeInfo();
84 extern int vsu_SetCrypt();
86 extern VL_ReleaseLock();
87 extern VL_DeleteEntry();
88 extern VL_ListEntry();
90 extern VL_GetAddrsU();
91 extern VL_ChangeAddr();
93 extern int vsu_ExtractName();
95 extern int MapPartIdIntoName();
96 extern int MapHostToNetwork();
97 extern int MapNetworkToHost();
98 extern void EnumerateEntry();
99 extern void SubEnumerateEntry();
102 static struct tqHead busyHead, notokHead;
104 static void qInit(ahead)
105 struct tqHead *ahead;
107 memset((char *)ahead, 0, sizeof(struct tqHead));
112 static void qPut(ahead,volid)
113 struct tqHead *ahead;
118 elem = (struct tqElem *)malloc(sizeof(struct tqElem));
119 elem->next = ahead->next;
126 static void qGet(ahead,volid)
127 struct tqHead *ahead;
132 if(ahead->count <= 0) return;
133 *volid = ahead->next->volid;
135 ahead->next = tmp->next;
141 /* returns 1 if <filename> exists else 0 */
142 static FileExists(filename)
149 code = usd_Open(filename, USD_OPEN_RDONLY, 0, &ufd);
153 code = USD_IOCTL(ufd, USD_IOCTL_GETSIZE, &size);
161 /* returns 1 if <name> doesnot end in .readonly or .backup, else 0 */
162 static VolNameOK(name)
168 total = strlen(name);
169 if(!strcmp(&name[total - 9],".readonly")) {
172 else if(!strcmp(&name[total - 7 ],".backup")) {
180 /* return 1 if name is a number else 0 */
181 static IsNumeric(name)
190 for(i = 0; i < len ; i++){
191 if(*ptr < '0' || *ptr > '9'){
205 * Parse a server name/address and return the address in HOST BYTE order
207 afs_int32 GetServer(aname)
209 register struct hostent *th;
212 register afs_int32 code;
213 char hostname[MAXHOSTCHARS];
215 code = sscanf(aname, "%d.%d.%d.%d", &b1, &b2, &b3, &b4);
217 addr = (b1<<24) | (b2<<16) | (b3<<8) | b4;
218 addr = ntohl(addr); /* convert to host order */
220 th = gethostbyname(aname);
222 memcpy(&addr, th->h_addr, sizeof(addr));
225 if (addr == htonl(0x7f000001)) { /* local host */
226 code = gethostname(hostname, MAXHOSTCHARS);
228 th = gethostbyname(hostname); /* returns host byte order */
230 memcpy(&addr, th->h_addr, sizeof(addr));
236 afs_int32 GetVolumeType(aname)
240 if(!strcmp(aname,"ro"))
242 else if(!strcmp(aname, "rw"))
244 else if(!strcmp(aname,"bk"))
249 int IsPartValid(partId, server, code)
250 afs_int32 server, partId,*code;
253 struct partList dummyPartList;
261 *code = UV_ListPartitions(server,&dummyPartList, &cnt);
262 if(*code) return success;
263 for(i = 0 ; i < cnt ; i++) {
264 if(dummyPartList.partFlags[i] & PARTVALID)
265 if(dummyPartList.partId[i] == partId)
273 /*sends the contents of file associated with <fd> and <blksize> to Rx Stream
274 * associated with <call> */
275 SendFile(ufd, call, blksize)
277 register struct rx_call *call;
280 char *buffer = (char*) 0;
285 buffer = (char *)malloc(blksize);
287 fprintf(STDERR,"malloc failed\n");
291 while (!error && !done) {
292 #ifndef AFS_NT40_ENV /* NT csn't select on non-socket fd's */
295 FD_SET((int)(ufd->handle), &in);
296 /* don't timeout if read blocks */
297 IOMGR_Select(((int)(ufd->handle))+1, &in, 0, 0, 0);
299 error = USD_READ(ufd, buffer, blksize, &nbytes);
301 fprintf(STDERR, "File system read failed\n");
308 if (rx_Write(call, buffer, nbytes) != nbytes){
313 if (buffer) free(buffer);
317 /* function invoked by UV_RestoreVolume, reads the data from rx_trx_stream and
318 * writes it out to the volume. */
319 afs_int32 WriteData(call,rock)
320 struct rx_call *call;
326 afs_int32 error,code;
332 if(!filename || !*filename) {
333 usd_StandardInput(&ufd);
337 code = usd_Open(filename, USD_OPEN_RDONLY, 0, &ufd);
340 code = USD_IOCTL(ufd, USD_IOCTL_GETBLKSIZE, &blksize);
343 fprintf(STDERR,"Could not access file '%s'\n", filename);
348 code = SendFile(ufd,call,blksize);
355 code = USD_CLOSE(ufd);
357 fprintf(STDERR,"Could not close dump file %s\n",
358 (filename && *filename)?filename:"STDOUT");
359 if(!error) error = code;
365 /* Receive data from <call> stream into file associated
366 * with <fd> <blksize>
368 int ReceiveFile(ufd, call, blksize)
370 struct rx_call *call;
373 char *buffer = (char *) 0;
375 afs_uint32 bytesleft, w;
378 buffer = (char *)malloc(blksize);
380 fprintf(STDERR,"memory allocation failed\n");
384 while ((bytesread=rx_Read(call,buffer,blksize)) > 0) {
385 for (bytesleft=bytesread; bytesleft; bytesleft-=w) {
386 #ifndef AFS_NT40_ENV /* NT csn't select on non-socket fd's */
389 FD_SET((int)(ufd->handle), &out);
390 /* don't timeout if write blocks */
391 IOMGR_Select(((int)(ufd->handle))+1, 0, &out, 0, 0);
393 error = USD_WRITE(ufd, &buffer[bytesread-bytesleft], bytesleft, &w);
395 fprintf(STDERR,"File system write failed\n");
402 if (buffer) free(buffer);
406 afs_int32 DumpFunction(call, filename)
407 struct rx_call *call;
410 usd_handle_t ufd; /* default is to stdout */
411 afs_int32 error=0, code;
416 /* Open the output file */
417 if (!filename || !*filename) {
418 usd_StandardOutput(&ufd);
422 code = usd_Open(filename, USD_OPEN_CREATE|USD_OPEN_RDWR, 0666, &ufd);
426 code = USD_IOCTL(ufd, USD_IOCTL_SETSIZE, &size);
429 code = USD_IOCTL(ufd, USD_IOCTL_GETBLKSIZE, &blksize);
432 fprintf(STDERR, "Could not create file '%s'\n", filename);
433 ERROR_EXIT(VOLSERBADOP);
437 code = ReceiveFile(ufd, call, blksize);
438 if (code) ERROR_EXIT(code);
441 /* Close the output file */
443 code = USD_CLOSE(ufd);
445 fprintf(STDERR,"Could not close dump file %s\n",
446 (filename && *filename)?filename:"STDIN");
447 if (!error) error = code;
454 static void DisplayFormat(pntr,server,part,totalOK,totalNotOK,totalBusy,fast,longlist,disp)
456 afs_int32 server,part;
457 int *totalOK,*totalNotOK,*totalBusy;
458 int fast,longlist, disp;
463 fprintf(STDOUT,"%-10u\n",pntr->volid);
466 if(pntr->status == VOK){
467 fprintf(STDOUT,"%-32s ",pntr->name);
468 fprintf(STDOUT,"%10u ",pntr->volid);
469 if(pntr->type == 0) fprintf(STDOUT,"RW ");
470 if(pntr->type == 1) fprintf(STDOUT,"RO ");
471 if(pntr->type == 2) fprintf(STDOUT,"BK ");
472 fprintf(STDOUT,"%10d K ",pntr->size);
473 if(pntr->inUse == 1) {
474 fprintf(STDOUT,"On-line");
477 fprintf(STDOUT,"Off-line");
480 if(pntr->needsSalvaged == 1) fprintf(STDOUT,"**needs salvage**");
481 fprintf(STDOUT,"\n");
482 MapPartIdIntoName(part,pname);
483 fprintf(STDOUT," %s %s \n",hostutil_GetNameByINet(server),pname);
484 fprintf(STDOUT," RWrite %10u ROnly %10u Backup %10u \n", pntr->parentID,pntr->cloneID, pntr->backupID);
485 fprintf(STDOUT," MaxQuota %10d K \n",pntr->maxquota);
486 fprintf(STDOUT," Creation %s",
487 ctime((time_t *)&pntr->creationDate));
489 fprintf(STDOUT," Copy %s",
490 ctime((time_t *)&pntr->copyDate));
491 if(!pntr->backupDate)
492 fprintf(STDOUT," Backup Never\n");
494 fprintf(STDOUT," Backup %s",
495 ctime((time_t *)&pntr->backupDate));
496 if (pntr->accessDate)
497 fprintf(STDOUT," Last Access %s",
498 ctime((time_t *)&pntr->accessDate));
500 if(pntr->updateDate < pntr->creationDate)
501 fprintf(STDOUT," Last Update %s",
502 ctime((time_t *)&pntr->creationDate));
504 fprintf(STDOUT," Last Update %s",
505 ctime((time_t *)&pntr->updateDate));
506 fprintf(STDOUT, " %d accesses in the past day (i.e., vnode references)\n",
509 else if (pntr->status == VBUSY) {
511 qPut(&busyHead,pntr->volid);
512 if (disp) fprintf(STDOUT,"**** Volume %u is busy ****\n",pntr->volid);
516 qPut(¬okHead,pntr->volid);
517 if (disp) fprintf(STDOUT,"**** Could not attach volume %u ****\n",pntr->volid);
519 fprintf(STDOUT,"\n");
521 else {/* default listing */
522 if(pntr->status == VOK){
523 fprintf(STDOUT,"%-32s ",pntr->name);
524 fprintf(STDOUT,"%10u ",pntr->volid);
525 if(pntr->type == 0) fprintf(STDOUT,"RW ");
526 if(pntr->type == 1) fprintf(STDOUT,"RO ");
527 if(pntr->type == 2) fprintf(STDOUT,"BK ");
528 fprintf(STDOUT,"%10d K ",pntr->size);
529 if(pntr->inUse == 1) {
530 fprintf(STDOUT,"On-line");
533 fprintf(STDOUT,"Off-line");
536 if(pntr->needsSalvaged == 1) fprintf(STDOUT,"**needs salvage**");
537 fprintf(STDOUT,"\n");
539 else if (pntr->status == VBUSY) {
541 qPut(&busyHead,pntr->volid);
542 if (disp) fprintf(STDOUT,"**** Volume %u is busy ****\n",pntr->volid);
546 qPut(¬okHead,pntr->volid);
547 if (disp) fprintf(STDOUT,"**** Could not attach volume %u ****\n",pntr->volid);
552 /*------------------------------------------------------------------------
553 * PRIVATE XDisplayFormat
556 * Display the contents of one extended volume info structure.
559 * a_xInfoP : Ptr to extended volume info struct to print.
560 * a_servID : Server ID to print.
561 * a_partID : Partition ID to print.
562 * a_totalOKP : Ptr to total-OK counter.
563 * a_totalNotOKP : Ptr to total-screwed counter.
564 * a_totalBusyP : Ptr to total-busy counter.
565 * a_fast : Fast listing?
566 * a_int32 : Int32 listing?
567 * a_showProblems : Show volume problems?
573 * Nothing interesting.
577 *------------------------------------------------------------------------*/
579 static void XDisplayFormat(a_xInfoP, a_servID, a_partID, a_totalOKP,
580 a_totalNotOKP, a_totalBusyP, a_fast, a_int32,
582 volintXInfo *a_xInfoP;
600 fprintf(STDOUT, "%-10u\n", a_xInfoP->volid);
605 * Fully-detailed listing.
607 if (a_xInfoP->status == VOK) {
609 * Volume's status is OK - all the fields are valid.
611 fprintf(STDOUT, "%-32s ", a_xInfoP->name);
612 fprintf(STDOUT, "%10u ", a_xInfoP->volid);
613 if (a_xInfoP->type == 0) fprintf(STDOUT,"RW ");
614 if (a_xInfoP->type == 1) fprintf(STDOUT,"RO ");
615 if (a_xInfoP->type == 2) fprintf(STDOUT,"BK ");
616 fprintf(STDOUT, "%10d K used ", a_xInfoP->size);
617 fprintf(STDOUT, "%d files ", a_xInfoP->filecount);
618 if(a_xInfoP->inUse == 1) {
619 fprintf(STDOUT, "On-line");
623 fprintf(STDOUT, "Off-line");
626 fprintf(STDOUT, "\n");
627 MapPartIdIntoName(a_partID, pname);
628 fprintf(STDOUT, " %s %s \n",
629 hostutil_GetNameByINet(a_servID),
631 fprintf(STDOUT, " RWrite %10u ROnly %10u Backup %10u \n",
632 a_xInfoP->parentID, a_xInfoP->cloneID, a_xInfoP->backupID);
633 fprintf(STDOUT, " MaxQuota %10d K \n",
635 fprintf(STDOUT, " Creation %s",
636 ctime((time_t *)&a_xInfoP->creationDate));
638 fprintf(STDOUT," Copy %s",
639 ctime((time_t *)&a_xInfoP->copyDate));
640 if(!a_xInfoP->backupDate)
641 fprintf(STDOUT," Backup Never\n");
643 fprintf(STDOUT," Backup %s",
644 ctime((time_t *)&a_xInfoP->backupDate));
645 if (a_xInfoP->accessDate)
646 fprintf(STDOUT," Last Access %s",
647 ctime((time_t *)&a_xInfoP->accessDate));
649 if (a_xInfoP->updateDate < a_xInfoP->creationDate)
650 fprintf(STDOUT, " Last Update %s",
651 ctime((time_t *)&a_xInfoP->creationDate));
653 fprintf(STDOUT, " Last Update %s",
654 ctime((time_t *)&a_xInfoP->updateDate));
655 fprintf(STDOUT, " %d accesses in the past day (i.e., vnode references)\n",
659 * Print all the read/write and authorship stats.
662 "\n Raw Read/Write Stats\n");
664 " |-------------------------------------------|\n");
666 " | Same Network | Diff Network |\n");
668 " |----------|----------|----------|----------|\n");
670 " | Total | Auth | Total | Auth |\n");
672 " |----------|----------|----------|----------|\n");
674 "Reads | %8d | %8d | %8d | %8d |\n",
675 a_xInfoP->stat_reads[VOLINT_STATS_SAME_NET],
676 a_xInfoP->stat_reads[VOLINT_STATS_SAME_NET_AUTH],
677 a_xInfoP->stat_reads[VOLINT_STATS_DIFF_NET],
678 a_xInfoP->stat_reads[VOLINT_STATS_DIFF_NET_AUTH]);
680 "Writes | %8d | %8d | %8d | %8d |\n",
681 a_xInfoP->stat_writes[VOLINT_STATS_SAME_NET],
682 a_xInfoP->stat_writes[VOLINT_STATS_SAME_NET_AUTH],
683 a_xInfoP->stat_writes[VOLINT_STATS_DIFF_NET],
684 a_xInfoP->stat_writes[VOLINT_STATS_DIFF_NET_AUTH]);
686 " |-------------------------------------------|\n\n");
689 " Writes Affecting Authorship\n");
691 " |-------------------------------------------|\n");
693 " | File Authorship | Directory Authorship|\n");
695 " |----------|----------|----------|----------|\n");
697 " | Same | Diff | Same | Diff |\n");
699 " |----------|----------|----------|----------|\n");
701 "0-60 sec | %8d | %8d | %8d | %8d |\n",
702 a_xInfoP->stat_fileSameAuthor[VOLINT_STATS_TIME_IDX_0],
703 a_xInfoP->stat_fileDiffAuthor[VOLINT_STATS_TIME_IDX_0],
704 a_xInfoP->stat_dirSameAuthor[VOLINT_STATS_TIME_IDX_0],
705 a_xInfoP->stat_dirDiffAuthor[VOLINT_STATS_TIME_IDX_0]);
707 "1-10 min | %8d | %8d | %8d | %8d |\n",
708 a_xInfoP->stat_fileSameAuthor[VOLINT_STATS_TIME_IDX_1],
709 a_xInfoP->stat_fileDiffAuthor[VOLINT_STATS_TIME_IDX_1],
710 a_xInfoP->stat_dirSameAuthor[VOLINT_STATS_TIME_IDX_1],
711 a_xInfoP->stat_dirDiffAuthor[VOLINT_STATS_TIME_IDX_1]);
713 "10min-1hr | %8d | %8d | %8d | %8d |\n",
714 a_xInfoP->stat_fileSameAuthor[VOLINT_STATS_TIME_IDX_2],
715 a_xInfoP->stat_fileDiffAuthor[VOLINT_STATS_TIME_IDX_2],
716 a_xInfoP->stat_dirSameAuthor[VOLINT_STATS_TIME_IDX_2],
717 a_xInfoP->stat_dirDiffAuthor[VOLINT_STATS_TIME_IDX_2]);
719 "1hr-1day | %8d | %8d | %8d | %8d |\n",
720 a_xInfoP->stat_fileSameAuthor[VOLINT_STATS_TIME_IDX_3],
721 a_xInfoP->stat_fileDiffAuthor[VOLINT_STATS_TIME_IDX_3],
722 a_xInfoP->stat_dirSameAuthor[VOLINT_STATS_TIME_IDX_3],
723 a_xInfoP->stat_dirDiffAuthor[VOLINT_STATS_TIME_IDX_3]);
725 "1day-1wk | %8d | %8d | %8d | %8d |\n",
726 a_xInfoP->stat_fileSameAuthor[VOLINT_STATS_TIME_IDX_4],
727 a_xInfoP->stat_fileDiffAuthor[VOLINT_STATS_TIME_IDX_4],
728 a_xInfoP->stat_dirSameAuthor[VOLINT_STATS_TIME_IDX_4],
729 a_xInfoP->stat_dirDiffAuthor[VOLINT_STATS_TIME_IDX_4]);
731 "> 1wk | %8d | %8d | %8d | %8d |\n",
732 a_xInfoP->stat_fileSameAuthor[VOLINT_STATS_TIME_IDX_5],
733 a_xInfoP->stat_fileDiffAuthor[VOLINT_STATS_TIME_IDX_5],
734 a_xInfoP->stat_dirSameAuthor[VOLINT_STATS_TIME_IDX_5],
735 a_xInfoP->stat_dirDiffAuthor[VOLINT_STATS_TIME_IDX_5]);
737 " |-------------------------------------------|\n");
738 } /*Volume status OK*/
740 if (a_xInfoP->status == VBUSY) {
742 qPut(&busyHead, a_xInfoP->volid);
744 fprintf(STDOUT, "**** Volume %u is busy ****\n",
749 qPut(¬okHead, a_xInfoP->volid);
751 fprintf(STDOUT, "**** Could not attach volume %u ****\n",
754 fprintf(STDOUT,"\n");
760 if (a_xInfoP->status == VOK) {
761 fprintf(STDOUT, "%-32s ", a_xInfoP->name);
762 fprintf(STDOUT, "%10u ", a_xInfoP->volid);
763 if (a_xInfoP->type == 0) fprintf(STDOUT, "RW ");
764 if (a_xInfoP->type == 1) fprintf(STDOUT, "RO ");
765 if (a_xInfoP->type == 2) fprintf(STDOUT, "BK ");
766 fprintf(STDOUT, "%10d K ", a_xInfoP->size);
767 if(a_xInfoP->inUse == 1) {
768 fprintf(STDOUT, "On-line");
771 fprintf(STDOUT, "Off-line");
774 fprintf(STDOUT, "\n");
777 if (a_xInfoP->status == VBUSY) {
779 qPut(&busyHead, a_xInfoP->volid);
781 fprintf(STDOUT,"**** Volume %u is busy ****\n",
786 qPut(¬okHead, a_xInfoP->volid);
788 fprintf(STDOUT,"**** Could not attach volume %u ****\n",
791 } /*Default listing*/
794 #ifdef FULL_LISTVOL_SWITCH
795 static void DisplayFormat2(server, partition, pntr)
796 long server, partition;
799 static long server_cache = -1, partition_cache = -1;
800 static char hostname[256],
804 if (server != server_cache) {
808 strcpy(hostname, hostutil_GetNameByINet(server));
809 strcpy(address, inet_ntoa(s));
810 server_cache = server;
812 if (partition != partition_cache) {
813 MapPartIdIntoName(partition, pname);
814 partition_cache = partition;
816 fprintf(STDOUT, "name\t\t%s\n", pntr->name);
817 fprintf(STDOUT, "id\t\t%lu\n", pntr->volid);
818 fprintf(STDOUT, "serv\t\t%s\t%s\n", address, hostname);
819 fprintf(STDOUT, "part\t\t%s\n", pname);
820 switch (pntr->status) {
822 fprintf(STDOUT, "status\t\tOK\n");
825 fprintf(STDOUT, "status\t\tBUSY\n");
828 fprintf(STDOUT, "status\t\tUNATTACHABLE\n");
831 fprintf(STDOUT, "backupID\t%lu\n", pntr->backupID);
832 fprintf(STDOUT, "parentID\t%lu\n", pntr->parentID);
833 fprintf(STDOUT, "cloneID\t\t%lu\n", pntr->cloneID);
834 fprintf(STDOUT, "inUse\t\t%s\n", pntr->inUse ? "Y" : "N");
835 fprintf(STDOUT, "needsSalvaged\t%s\n", pntr->needsSalvaged ? "Y" : "N");
836 /* 0xD3 is from afs/volume.h since I had trouble including the file */
837 fprintf(STDOUT, "destroyMe\t%s\n", pntr->destroyMe == 0xD3 ? "Y" : "N");
838 switch (pntr->type) {
840 fprintf(STDOUT, "type\t\tRW\n");
843 fprintf(STDOUT, "type\t\tRO\n");
846 fprintf(STDOUT, "type\t\tBK\n");
849 fprintf(STDOUT, "type\t\t?\n");
852 fprintf(STDOUT, "creationDate\t%-9lu\t%s", pntr->creationDate, ctime(&pntr->creationDate));
853 fprintf(STDOUT, "accessDate\t%-9lu\t%s", pntr->accessDate, ctime(&pntr->accessDate));
854 fprintf(STDOUT, "updateDate\t%-9lu\t%s", pntr->updateDate, ctime(&pntr->updateDate));
855 fprintf(STDOUT, "backupDate\t%-9lu\t%s", pntr->backupDate, ctime(&pntr->backupDate));
856 fprintf(STDOUT, "copyDate\t%-9lu\t%s", pntr->copyDate, ctime(&pntr->copyDate));
857 fprintf(STDOUT, "flags\t\t%#lx\t(Optional)\n", pntr->flags);
858 fprintf(STDOUT, "diskused\t%u\n", pntr->size);
859 fprintf(STDOUT, "maxquota\t%u\n", pntr->maxquota);
860 fprintf(STDOUT, "minquota\t%lu\t(Optional)\n", pntr->spare0);
861 fprintf(STDOUT, "filecount\t%u\n", pntr->filecount);
862 fprintf(STDOUT, "dayUse\t\t%u\n", pntr->dayUse);
863 fprintf(STDOUT, "weekUse\t\t%lu\t(Optional)\n", pntr->spare1);
864 fprintf(STDOUT, "spare2\t\t%lu\t(Optional)\n", pntr->spare2);
865 fprintf(STDOUT, "spare3\t\t%lu\t(Optional)\n", pntr->spare3);
869 static void DisplayVolumes2(server, partition, pntr, count)
871 long server, partition, count;
875 for (i = 0; i < count; i++) {
876 fprintf(STDOUT, "BEGIN_OF_ENTRY\n");
877 DisplayFormat2(server, partition, pntr);
878 fprintf(STDOUT, "END_OF_ENTRY\n\n");
883 #endif /* FULL_LISTVOL_SWITCH */
885 static void DisplayVolumes(server,part,pntr,count,longlist,fast,quiet)
886 afs_int32 server,part;
888 afs_int32 count,longlist,fast;
891 int totalOK,totalNotOK,totalBusy, i;
899 for(i = 0; i < count; i++){
900 DisplayFormat(pntr,server,part,&totalOK,&totalNotOK,&totalBusy,fast,longlist,0);
904 while(busyHead.count){
905 qGet(&busyHead,&volid);
906 fprintf(STDOUT,"**** Volume %u is busy ****\n",volid);
910 while(notokHead.count){
911 qGet(¬okHead,&volid);
912 fprintf(STDOUT,"**** Could not attach volume %u ****\n",volid);
916 fprintf(STDOUT,"\n");
918 fprintf(STDOUT,"Total volumes onLine %d ; Total volumes offLine %d ; Total busy %d\n\n",totalOK,totalNotOK,totalBusy);
923 /*------------------------------------------------------------------------
924 * PRIVATE XDisplayVolumes
927 * Display extended volume information.
930 * a_servID : Pointer to the Rx call we're performing.
931 * a_partID : Partition for which we want the extended list.
932 * a_xInfoP : Ptr to extended volume info.
933 * a_count : Number of volume records contained above.
934 * a_int32 : Int32 listing generated?
935 * a_fast : Fast listing generated?
936 * a_quiet : Quiet listing generated?
942 * Nothing interesting.
946 *------------------------------------------------------------------------*/
948 static void XDisplayVolumes(a_servID, a_partID, a_xInfoP,
949 a_count, a_int32, a_fast, a_quiet)
952 volintXInfo *a_xInfoP;
958 { /*XDisplayVolumes*/
960 int totalOK; /*Total OK volumes*/
961 int totalNotOK; /*Total screwed volumes*/
962 int totalBusy; /*Total busy volumes*/
963 int i; /*Loop variable*/
964 afs_int32 volid; /*Current volume ID*/
967 * Initialize counters and (global!!) queues.
976 * Display each volume in the list.
978 for(i = 0; i < a_count; i++) {
979 XDisplayFormat(a_xInfoP,
992 * If any volumes were found to be busy or screwed, display them.
995 while (busyHead.count) {
996 qGet(&busyHead, &volid);
997 fprintf(STDOUT, "**** Volume %u is busy ****\n", volid);
1001 while (notokHead.count) {
1002 qGet(¬okHead, &volid);
1003 fprintf(STDOUT, "**** Could not attach volume %u ****\n", volid);
1008 fprintf(STDOUT, "\n");
1011 "Total volumes: %d on-line, %d off-line, %d busyd\n\n",
1012 totalOK, totalNotOK, totalBusy);
1016 } /*XDisplayVolumes*/
1018 /* set <server> and <part> to the correct values depending on
1019 * <voltype> and <entry> */
1020 static void GetServerAndPart (entry, voltype, server, part, previdx)
1021 struct nvldbentry *entry;
1022 afs_int32 *server,*part;
1026 int i, istart, vtype;
1031 /* Doesn't check for non-existance of backup volume */
1032 if ((voltype == RWVOL) || (voltype == BACKVOL)) {
1034 istart = 0; /* seach the entire entry */
1037 /* Seach from beginning of entry or pick up where we left off */
1038 istart = ((*previdx < 0) ? 0 : *previdx+1);
1041 for (i = istart; i < entry->nServers; i++) {
1042 if (entry->serverFlags[i] & vtype) {
1043 *server = entry->serverNumber[i];
1044 *part = entry->serverPartition[i];
1050 /* Didn't find any, return -1 */
1055 static void PostVolumeStats(entry)
1056 struct nvldbentry *entry;
1058 SubEnumerateEntry(entry);
1059 /* Check for VLOP_ALLOPERS */
1060 if (entry->flags & VLOP_ALLOPERS)
1061 fprintf(STDOUT," Volume is currently LOCKED \n");
1065 /*------------------------------------------------------------------------
1066 * PRIVATE XVolumeStats
1069 * Display extended volume information.
1072 * a_xInfoP : Ptr to extended volume info.
1073 * a_entryP : Ptr to the volume's VLDB entry.
1074 * a_srvID : Server ID.
1075 * a_partID : Partition ID.
1076 * a_volType : Type of volume to print.
1082 * Nothing interesting.
1086 *------------------------------------------------------------------------*/
1088 static void XVolumeStats(a_xInfoP, a_entryP, a_srvID, a_partID, a_volType)
1089 volintXInfo *a_xInfoP;
1090 struct nvldbentry *a_entryP;
1097 int totalOK, totalNotOK, totalBusy; /*Dummies - we don't really count here*/
1099 XDisplayFormat(a_xInfoP, /*Ptr to extended volume info*/
1100 a_srvID, /*Server ID to print*/
1101 a_partID, /*Partition ID to print*/
1102 &totalOK, /*Ptr to total-OK counter*/
1103 &totalNotOK, /*Ptr to total-screwed counter*/
1104 &totalBusy, /*Ptr to total-busy counter*/
1105 0, /*Don't do a fast listing*/
1106 1, /*Do a long listing*/
1107 1); /*Show volume problems*/
1112 static void VolumeStats(pntr,entry,server,part,voltype)
1114 struct nvldbentry *entry;
1116 afs_int32 server,part;
1118 int totalOK,totalNotOK,totalBusy;
1119 afs_int32 vcode,vcode2;
1121 DisplayFormat(pntr,server,part,&totalOK,&totalNotOK,&totalBusy,0,1,1);
1125 /* command to forcibly remove a volume */
1126 static NukeVolume(as)
1127 register struct cmd_syndesc *as; {
1128 register afs_int32 code;
1129 afs_int32 volID, err;
1134 server = GetServer(tp = as->parms[0].items->data);
1136 fprintf(STDERR,"vos: server '%s' not found in host table\n", tp);
1140 partID = volutil_GetPartitionID(tp = as->parms[1].items->data);
1142 fprintf(STDERR, "vos: could not parse '%s' as a partition name", tp);
1146 volID = vsu_GetVolumeID(tp = as->parms[2].items->data, cstruct, &err);
1148 if (err) PrintError("", err);
1149 else fprintf(STDERR, "vos: could not parse '%s' as a numeric volume ID", tp);
1153 fprintf(STDOUT, "vos: forcibly removing all traces of volume %d, please wait...", volID);
1155 code = UV_NukeVolume(server, partID, volID);
1157 fprintf(STDOUT, "done.\n");
1159 fprintf(STDOUT, "failed with code %d.\n", code);
1164 /*------------------------------------------------------------------------
1165 * PRIVATE ExamineVolume
1168 * Routine used to examine a single volume, contacting the VLDB as
1169 * well as the Volume Server.
1172 * as : Ptr to parsed command line arguments.
1175 * 0 for a successful operation,
1176 * Otherwise, one of the ubik or VolServer error values.
1179 * Nothing interesting.
1183 *------------------------------------------------------------------------
1185 static ExamineVolume(as)
1186 register struct cmd_syndesc *as;
1188 struct nvldbentry entry;
1189 afs_int32 vcode = 0;
1190 volintInfo *pntr = (volintInfo *)0;
1191 volintXInfo *xInfoP = (volintXInfo *)0;
1193 afs_int32 code, err, error = 0;
1194 int voltype, foundserv = 0, foundentry = 0;
1195 afs_int32 aserver, apart;
1197 int wantExtendedInfo; /*Do we want extended vol info?*/
1199 wantExtendedInfo = (as->parms[1].items ? 1 : 0); /* -extended */
1201 volid = vsu_GetVolumeID(as->parms[0].items->data, cstruct, &err); /* -id */
1203 if (err) PrintError("", err);
1204 else fprintf(STDERR, "Unknown volume ID or name '%s'\n", as->parms[0].items->data);
1209 fprintf(STDOUT, "Fetching VLDB entry for %u .. ", volid);
1212 vcode = VLDB_GetEntryByID (volid, -1, &entry);
1214 fprintf(STDERR, "Could not fetch the entry for volume number %u from VLDB \n",volid);
1218 fprintf(STDOUT, "done\n");
1219 MapHostToNetwork(&entry);
1221 if (entry.volumeId[RWVOL] == volid)
1223 else if (entry.volumeId[BACKVOL] == volid)
1225 else /* (entry.volumeId[ROVOL] == volid) */
1228 do { /* do {...} while (voltype == ROVOL) */
1229 /* Get the entry for the volume. If its a RW vol, get the RW entry.
1230 * It its a BK vol, get the RW entry (even if VLDB may say the BK doen't exist).
1231 * If its a RO vol, get the next RO entry.
1233 GetServerAndPart(&entry, ((voltype == ROVOL) ? ROVOL : RWVOL), &aserver, &apart, &previdx);
1234 if (previdx == -1) { /* searched all entries */
1236 fprintf(STDERR,"Volume %s does not exist in VLDB\n\n", as->parms[0].items->data);
1243 /* Get information about the volume from the server */
1245 fprintf(STDOUT,"Getting volume listing from the server %s .. ",
1246 hostutil_GetNameByINet(aserver));
1249 if (wantExtendedInfo)
1250 code = UV_XListOneVolume(aserver, apart, volid, &xInfoP);
1252 code = UV_ListOneVolume(aserver, apart, volid, &pntr);
1254 fprintf(STDOUT,"done\n");
1258 if (code == ENODEV) {
1259 if ((voltype == BACKVOL) && !(entry.flags & BACK_EXISTS)) {
1260 /* The VLDB says there is no backup volume and its not on disk */
1261 fprintf(STDERR, "Volume %s does not exist\n", as->parms[0].items->data);
1264 fprintf(STDERR, "Volume does not exist on server %s as indicated by the VLDB\n",
1265 hostutil_GetNameByINet(aserver));
1268 PrintDiagnostics("examine", code);
1270 fprintf(STDOUT, "\n");
1273 if (wantExtendedInfo)
1274 XVolumeStats(xInfoP, &entry, aserver, apart, voltype);
1276 #ifdef FULL_LISTVOL_SWITCH
1277 if (as->parms[2].items) {
1278 DisplayFormat2(aserver, apart, pntr);
1279 EnumerateEntry(&entry);
1281 #endif /* FULL_LISTVOL_SWITCH */
1282 VolumeStats(pntr, &entry, aserver, apart, voltype);
1284 if ((voltype == BACKVOL) && !(entry.flags & BACK_EXISTS)) {
1285 /* The VLDB says there is no backup volume yet we found one on disk */
1286 fprintf(STDERR, "Volume %s does not exist in VLDB\n", as->parms[0].items->data);
1291 if (pntr) free(pntr);
1292 if (xInfoP) free(xInfoP);
1293 } while (voltype == ROVOL);
1296 fprintf(STDERR,"Dump only information from VLDB\n\n");
1297 fprintf(STDOUT,"%s \n", entry.name); /* PostVolumeStats doesn't print name */
1299 PostVolumeStats(&entry);
1304 /*------------------------------------------------------------------------
1308 * Routine used to change the status of a single volume.
1311 * as : Ptr to parsed command line arguments.
1314 * 0 for a successful operation,
1315 * Otherwise, one of the ubik or VolServer error values.
1318 * Nothing interesting.
1322 *------------------------------------------------------------------------
1324 static SetFields(as)
1325 register struct cmd_syndesc *as;
1327 struct nvldbentry entry;
1328 afs_int32 vcode = 0;
1331 afs_int32 code, err;
1332 afs_int32 aserver, apart;
1335 volid = vsu_GetVolumeID(as->parms[0].items->data, cstruct, &err); /* -id */
1337 if (err) PrintError("", err);
1338 else fprintf(STDERR, "Unknown volume ID or name '%s'\n", as->parms[0].items->data);
1342 code = VLDB_GetEntryByID (volid, RWVOL, &entry);
1344 fprintf(STDERR, "Could not fetch the entry for volume number %u from VLDB \n",volid);
1347 MapHostToNetwork(&entry);
1349 GetServerAndPart(&entry, RWVOL, &aserver, &apart, &previdx);
1350 if (previdx == -1) {
1351 fprintf(STDERR,"Volume %s does not exist in VLDB\n\n", as->parms[0].items->data);
1355 memset(&info, 0, sizeof(info));
1366 if (as->parms[1].items) {
1368 code = util_GetInt32(as->parms[1].items->data, &info.maxquota);
1370 fprintf(STDERR,"invalid quota value\n");
1374 if (as->parms[2].items) {
1378 code = UV_SetVolumeInfo(aserver, apart, volid, &info);
1380 fprintf(STDERR,"Could not update volume info fields for volume number %u\n",volid);
1384 /*------------------------------------------------------------------------
1388 * Brings a volume online.
1391 * as : Ptr to parsed command line arguments.
1394 * 0 for a successful operation,
1397 * Nothing interesting.
1401 *------------------------------------------------------------------------
1403 static volOnline(as)
1404 register struct cmd_syndesc *as;
1406 afs_int32 server, partition, volid;
1407 afs_int32 code, err=0;
1409 server = GetServer(as->parms[0].items->data);
1411 fprintf(STDERR,"vos: server '%s' not found in host table\n", as->parms[0].items->data);
1415 partition = volutil_GetPartitionID(as->parms[1].items->data);
1416 if (partition < 0) {
1417 fprintf(STDERR,"vos: could not interpret partition name '%s'\n", as->parms[1].items->data);
1421 volid = vsu_GetVolumeID(as->parms[2].items->data, cstruct, &err); /* -id */
1423 if (err) PrintError("", err);
1424 else fprintf(STDERR, "Unknown volume ID or name '%s'\n", as->parms[0].items->data);
1428 code = UV_SetVolume(server, partition, volid, ITOffline, 0/*online*/, 0/*sleep*/);
1430 fprintf(STDERR, "Failed to set volume. Code = %d\n", code);
1437 /*------------------------------------------------------------------------
1438 * PRIVATE volOffline
1441 * Brings a volume offline.
1444 * as : Ptr to parsed command line arguments.
1447 * 0 for a successful operation,
1450 * Nothing interesting.
1454 *------------------------------------------------------------------------
1456 static volOffline(as)
1457 register struct cmd_syndesc *as;
1459 afs_int32 server, partition, volid;
1460 afs_int32 code, err=0;
1461 afs_int32 transflag, sleeptime, transdone;
1463 server = GetServer(as->parms[0].items->data);
1465 fprintf(STDERR,"vos: server '%s' not found in host table\n", as->parms[0].items->data);
1469 partition = volutil_GetPartitionID(as->parms[1].items->data);
1470 if (partition < 0) {
1471 fprintf(STDERR,"vos: could not interpret partition name '%s'\n", as->parms[1].items->data);
1475 volid = vsu_GetVolumeID(as->parms[2].items->data, cstruct, &err); /* -id */
1477 if (err) PrintError("", err);
1478 else fprintf(STDERR, "Unknown volume ID or name '%s'\n", as->parms[0].items->data);
1482 transflag = (as->parms[4].items ? ITBusy : ITOffline);
1483 sleeptime = (as->parms[3].items ? atol(as->parms[3].items->data) : 0);
1484 transdone = (sleeptime ? 0/*online*/ : VTOutOfService);
1485 if (as->parms[4].items && !as->parms[3].items) {
1486 fprintf(STDERR,"-sleep option must be used with -busy flag\n");
1490 code = UV_SetVolume(server, partition, volid, transflag, transdone, sleeptime);
1492 fprintf(STDERR, "Failed to set volume. Code = %d\n", code);
1499 static CreateVolume(as)
1500 register struct cmd_syndesc *as;
1504 afs_int32 volid,code;
1505 struct nvldbentry entry;
1510 tserver = GetServer(as->parms[0].items->data);
1512 fprintf(STDERR,"vos: host '%s' not found in host table\n",as->parms[0].items->data );
1515 pname = volutil_GetPartitionID(as->parms[1].items->data);
1517 fprintf(STDERR,"vos: could not interpret partition name '%s'\n",as->parms[1].items->data );
1520 if (!IsPartValid(pname,tserver,&code)){/*check for validity of the partition */
1521 if(code) PrintError("",code);
1522 else fprintf(STDERR,"vos : partition %s does not exist on the server\n",as->parms[1].items->data);
1525 if(!ISNAMEVALID(as->parms[2].items->data)) {
1526 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);
1529 if(!VolNameOK(as->parms[2].items->data)){
1530 fprintf(STDERR,"Illegal volume name %s, should not end in .readonly or .backup\n",as->parms[2].items->data);
1533 if(IsNumeric(as->parms[2].items->data)){
1534 fprintf(STDERR,"Illegal volume name %s, should not be a number\n",as->parms[2].items->data);
1537 vcode = VLDB_GetEntryByName(as->parms[2].items->data, &entry);
1539 fprintf(STDERR,"Volume %s already exists\n",as->parms[2].items->data);
1540 PrintDiagnostics("create", code);
1544 if (as->parms[3].items) {
1545 if (!IsNumeric(as->parms[3].items->data)){
1546 fprintf(STDERR,"Initial quota %s should be numeric.\n", as->parms[3].items->data);
1550 code = util_GetInt32(as->parms[3].items->data, "a);
1552 fprintf(STDERR,"vos: bad integer specified for quota.\n");
1557 code = UV_CreateVolume2(tserver, pname,as->parms[2].items->data,
1558 quota, 0, 0, 0, 0, &volid);
1560 PrintDiagnostics("create", code);
1563 MapPartIdIntoName(pname, part);
1564 fprintf(STDOUT,"Volume %u created on partition %s of %s\n", volid, part,as->parms[0].items->data );
1569 static afs_int32 DeleteAll(entry)
1570 struct nvldbentry *entry;
1573 afs_int32 error, code, curserver, curpart, volid;
1575 MapHostToNetwork(entry);
1577 for(i=0; i < entry->nServers; i++){
1578 curserver = entry->serverNumber[i];
1579 curpart = entry->serverPartition[i];
1580 if(entry->serverFlags[i] & ITSROVOL){
1581 volid = entry->volumeId[ROVOL];
1584 volid = entry->volumeId[RWVOL];
1586 code = UV_DeleteVolume(curserver,curpart,volid);
1593 static DeleteVolume(as)
1594 struct cmd_syndesc *as;
1596 afs_int32 err, code = 0;
1597 afs_int32 server = 0, partition = -1, volid;
1601 if (as->parms[0].items) {
1602 server = GetServer(as->parms[0].items->data);
1604 fprintf(STDERR,"vos: server '%s' not found in host table\n",
1605 as->parms[0].items->data);
1610 if (as->parms[1].items) {
1611 partition = volutil_GetPartitionID(as->parms[1].items->data);
1612 if (partition < 0) {
1613 fprintf(STDERR,"vos: could not interpret partition name '%s'\n",
1614 as->parms[1].items->data );
1618 /* Check for validity of the partition */
1619 if (!IsPartValid(partition, server, &code)) {
1621 PrintError("", code);
1623 fprintf(STDERR,"vos : partition %s does not exist on the server\n",
1624 as->parms[1].items->data);
1630 volid = vsu_GetVolumeID(as->parms[2].items->data, cstruct, &err);
1632 fprintf(STDERR, "Can't find volume name '%s' in VLDB\n",
1633 as->parms[2].items->data);
1634 if (err) PrintError("", err);
1638 /* If the server or partition option are not complete, try to fill
1639 * them in from the VLDB entry.
1641 if ((partition == -1) || !server) {
1642 struct nvldbentry entry;
1644 code = VLDB_GetEntryByID(volid, -1, &entry);
1646 fprintf(STDERR,"Could not fetch the entry for volume %u from VLDB\n",
1648 PrintError("",code);
1652 if (((volid == entry.volumeId[RWVOL]) && (entry.flags & RW_EXISTS)) ||
1653 ((volid == entry.volumeId[BACKVOL]) && (entry.flags & BACK_EXISTS)) ) {
1654 idx = Lp_GetRwIndex(&entry);
1656 (server && (server != entry.serverNumber[idx])) ||
1657 ((partition != -1) && (partition != entry.serverPartition[idx])) ) {
1658 fprintf(STDERR,"VLDB: Volume '%s' no match\n", as->parms[2].items->data);
1662 else if ((volid == entry.volumeId[ROVOL]) && (entry.flags & RO_EXISTS)) {
1663 for (idx=-1,j=0; j<entry.nServers; j++) {
1664 if (entry.serverFlags[j] != ITSROVOL) continue;
1666 if ( ((server == 0) || (server == entry.serverNumber[j])) &&
1667 ((partition == -1) || (partition == entry.serverPartition[j])) ) {
1669 fprintf(STDERR,"VLDB: Volume '%s' matches more than one RO\n",
1670 as->parms[2].items->data);
1677 fprintf(STDERR,"VLDB: Volume '%s' no match\n", as->parms[2].items->data);
1682 fprintf(STDERR,"VLDB: Volume '%s' no match\n", as->parms[2].items->data);
1686 server = htonl(entry.serverNumber[idx]);
1687 partition = entry.serverPartition[idx];
1691 code = UV_DeleteVolume(server, partition, volid);
1693 PrintDiagnostics("remove", code);
1697 MapPartIdIntoName(partition, pname);
1698 fprintf(STDOUT,"Volume %u on partition %s server %s deleted\n",
1699 volid, pname, hostutil_GetNameByINet(server));
1703 #define TESTM 0 /* set for move space tests, clear for production */
1704 static MoveVolume(as)
1705 register struct cmd_syndesc *as;
1708 afs_int32 volid, fromserver, toserver, frompart, topart,code, err;
1709 char fromPartName[10], toPartName[10];
1711 struct diskPartition partition; /* for space check */
1714 volid = vsu_GetVolumeID(as->parms[0].items->data, cstruct, &err);
1716 if (err) PrintError("", err);
1717 else fprintf(STDERR, "vos: can't find volume ID or name '%s'\n",
1718 as->parms[0].items->data);
1721 fromserver = GetServer(as->parms[1].items->data);
1722 if (fromserver == 0) {
1723 fprintf(STDERR,"vos: server '%s' not found in host table\n", as->parms[1].items->data);
1726 toserver = GetServer(as->parms[3].items->data);
1727 if (toserver == 0) {
1728 fprintf(STDERR,"vos: server '%s' not found in host table\n", as->parms[3].items->data);
1731 frompart = volutil_GetPartitionID(as->parms[2].items->data);
1733 fprintf(STDERR,"vos: could not interpret partition name '%s'\n", as->parms[2].items->data);
1736 if (!IsPartValid(frompart,fromserver,&code)){/*check for validity of the partition */
1737 if(code) PrintError("",code);
1738 else fprintf(STDERR,"vos : partition %s does not exist on the server\n",as->parms[2].items->data);
1741 topart = volutil_GetPartitionID(as->parms[4].items->data);
1743 fprintf(STDERR,"vos: could not interpret partition name '%s'\n",as->parms[4].items->data);
1746 if (!IsPartValid(topart,toserver,&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[4].items->data);
1753 check source partition for space to clone volume
1756 MapPartIdIntoName(topart,toPartName);
1757 MapPartIdIntoName(frompart, fromPartName);
1760 check target partition for space to move volume
1763 code=UV_PartitionInfo(toserver,toPartName,&partition);
1766 fprintf(STDERR,"vos: cannot access partition %s\n",toPartName);
1770 fprintf(STDOUT,"target partition %s free space %d\n",
1771 toPartName,partition.free);
1774 code=UV_ListOneVolume(fromserver,frompart,volid,&p);
1777 fprintf(STDERR,"vos:cannot access volume %u\n",volid);
1782 fprintf(STDOUT,"volume %u size %d\n",volid,p->size);
1783 if(partition.free<=p->size)
1785 fprintf(STDERR,"vos: no space on target partition %s to move volume %u\n",
1794 fprintf(STDOUT,"size test - don't do move\n");
1798 /* successful move still not guaranteed but shoot for it */
1800 code = UV_MoveVolume(volid, fromserver, frompart, toserver, topart);
1802 PrintDiagnostics("move", code);
1805 MapPartIdIntoName(topart,toPartName);
1806 MapPartIdIntoName(frompart, fromPartName);
1807 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);
1811 static BackupVolume(as)
1812 register struct cmd_syndesc *as;
1814 afs_int32 avolid, aserver, apart,vtype,code, err;
1815 struct nvldbentry entry;
1817 afs_int32 buvolid,buserver,bupart,butype;
1818 struct nvldbentry buentry;
1819 struct rx_connection *conn;
1821 struct nvldbentry store;
1823 avolid = vsu_GetVolumeID(as->parms[0].items->data, cstruct, &err);
1825 if (err) PrintError("", err);
1826 else fprintf(STDERR, "vos: can't find volume ID or name '%s'\n",
1827 as->parms[0].items->data);
1830 code = GetVolumeInfo( avolid,&aserver, &apart,&vtype,&entry);
1833 /* verify this is a readwrite volume */
1837 fprintf(STDERR,"%s not RW volume\n",as->parms[0].items->data);
1841 /* is there a backup volume already? */
1843 if(entry.flags & BACK_EXISTS)
1845 /* yep, where is it? */
1847 buvolid=entry.volumeId[BACKVOL];
1848 code=GetVolumeInfo(buvolid,&buserver,&bupart,&butype,&buentry);
1852 code = VLDB_IsSameAddrs(buserver, aserver, &err);
1854 fprintf(STDERR,"Failed to get info about server's %d address(es) from vlserver; aborting call!\n", buserver);
1859 fprintf(STDERR,"FATAL ERROR: backup volume %u exists on server %u\n",
1865 /* nope, carry on */
1867 code = UV_BackupVolume(aserver, apart, avolid);
1870 PrintDiagnostics("backup", code);
1873 fprintf(STDOUT,"Created backup volume for %s \n",as->parms[0].items->data);
1876 static ReleaseVolume(as)
1877 register struct cmd_syndesc *as;
1880 struct nvldbentry entry;
1881 afs_int32 avolid, aserver, apart,vtype,code, err;
1884 if(as->parms[1].items) force = 1;
1885 avolid = vsu_GetVolumeID(as->parms[0].items->data, cstruct, &err);
1887 if (err) PrintError("", err);
1888 else fprintf(STDERR, "vos: can't find volume '%s'\n", as->parms[0].items->data);
1891 code = GetVolumeInfo( avolid,&aserver, &apart,&vtype,&entry);
1892 if(code) return code;
1894 if (vtype != RWVOL) {
1895 fprintf(STDERR,"%s not a RW volume\n", as->parms[0].items->data);
1899 if(!ISNAMEVALID(entry.name)){
1900 fprintf(STDERR,"Volume name %s is too long, rename before releasing\n",entry.name);
1904 code = UV_ReleaseVolume(avolid, aserver, apart, force);
1906 PrintDiagnostics("release", code);
1909 fprintf(STDOUT,"Released volume %s successfully\n",as->parms[0].items->data );
1912 static DumpVolume(as)
1913 register struct cmd_syndesc *as;
1916 afs_int32 avolid, aserver, apart,voltype,fromdate=0,code, err, i;
1917 char filename[NameLen];
1918 struct nvldbentry entry;
1920 rx_SetRxDeadTime(60 * 10);
1921 for (i = 0; i<MAXSERVERS; i++) {
1922 struct rx_connection *rxConn = ubik_GetRPCConn(cstruct,i);
1923 if (rxConn == 0) break;
1924 rx_SetConnDeadTime(rxConn, rx_connDeadTime);
1925 if (rxConn->service) rxConn->service->connDeadTime = rx_connDeadTime;
1928 avolid = vsu_GetVolumeID(as->parms[0].items->data, cstruct, &err);
1930 if (err) PrintError("", err);
1931 else fprintf(STDERR, "vos: can't find volume '%s'\n", as->parms[0].items->data);
1935 if (as->parms[3].items || as->parms[4].items) {
1936 if (!as->parms[3].items || !as->parms[4].items) {
1937 fprintf(STDERR, "Must specify both -server and -partition options\n");
1940 aserver = GetServer(as->parms[3].items->data);
1942 fprintf(STDERR, "Invalid server name\n");
1945 apart = volutil_GetPartitionID(as->parms[4].items->data);
1947 fprintf(STDERR, "Invalid partition name\n");
1951 code = GetVolumeInfo(avolid, &aserver, &apart, &voltype, &entry);
1952 if (code) return code;
1955 if (as->parms[1].items && strcmp(as->parms[1].items->data,"0")) {
1956 code = ktime_DateToInt32(as->parms[1].items->data, &fromdate);
1958 fprintf(STDERR,"vos: failed to parse date '%s' (error=%d))\n",
1959 as->parms[1].items->data, code);
1963 if(as->parms[2].items){
1964 strcpy(filename,as->parms[2].items->data);
1967 strcpy(filename,"");
1969 code = UV_DumpVolume(avolid, aserver, apart, fromdate, DumpFunction, filename);
1971 PrintDiagnostics("dump", code);
1974 if(strcmp(filename,""))
1975 fprintf(STDERR,"Dumped volume %s in file %s\n",as->parms[0].items->data, filename);
1977 fprintf(STDERR,"Dumped volume %s in stdout \n",as->parms[0].items->data);
1986 static RestoreVolume(as)
1987 register struct cmd_syndesc *as;
1990 afs_int32 avolid, aserver, apart, code,vcode, err;
1991 afs_int32 aoverwrite = ASK;
1992 int restoreflags, readonly = 0, offline = 0, voltype = RWVOL;
1994 char afilename[NameLen], avolname[VOLSER_MAXVOLNAME +1],apartName[10];
1995 char volname[VOLSER_MAXVOLNAME +1];
1996 struct nvldbentry entry;
2000 if(as->parms[4].items){
2001 avolid = vsu_GetVolumeID(as->parms[4].items->data, cstruct, &err);
2003 if (err) PrintError("", err);
2004 else fprintf(STDERR, "vos: can't find volume '%s'\n", as->parms[4].items->data);
2011 if (as->parms[5].items) {
2012 if ( (strcmp(as->parms[5].items->data, "a") == 0) ||
2013 (strcmp(as->parms[5].items->data, "abort") == 0) ) {
2016 else if ( (strcmp(as->parms[5].items->data, "f") == 0) ||
2017 (strcmp(as->parms[5].items->data, "full") == 0) ) {
2020 else if ( (strcmp(as->parms[5].items->data, "i") == 0) ||
2021 (strcmp(as->parms[5].items->data, "inc") == 0) ||
2022 (strcmp(as->parms[5].items->data, "increment") == 0) ||
2023 (strcmp(as->parms[5].items->data, "incremental") == 0) ) {
2027 fprintf(STDERR, "vos: %s is not a valid argument to -overwrite\n",
2028 as->parms[5].items->data);
2032 if (as->parms[6].items) offline = 1;
2033 if (as->parms[7].items) {
2038 aserver = GetServer(as->parms[0].items->data);
2040 fprintf(STDERR,"vos: server '%s' not found in host table\n", as->parms[0].items->data);
2043 apart = volutil_GetPartitionID(as->parms[1].items->data);
2045 fprintf(STDERR,"vos: could not interpret partition name '%s'\n",as->parms[1].items->data );
2048 if (!IsPartValid(apart,aserver,&code)){/*check for validity of the partition */
2049 if(code) PrintError("",code);
2050 else fprintf(STDERR,"vos : partition %s does not exist on the server\n",as->parms[1].items->data);
2053 strcpy(avolname,as->parms[2].items->data );
2054 if(!ISNAMEVALID(avolname)) {
2055 fprintf(STDERR,"vos: the name of the volume %s exceeds the size limit\n",avolname);
2058 if(!VolNameOK(avolname)){
2059 fprintf(STDERR,"Illegal volume name %s, should not end in .readonly or .backup\n",avolname);
2062 if(as->parms[3].items){
2063 strcpy(afilename,as->parms[3].items->data );
2064 if(!FileExists(afilename)){
2065 fprintf(STDERR,"Can't access file %s\n",afilename);
2070 strcpy(afilename,"");
2073 /* Check if volume exists or not */
2075 vsu_ExtractName(volname,avolname);
2076 vcode = VLDB_GetEntryByName(volname, &entry);
2077 if (vcode) { /* no volume - do a full restore */
2078 restoreflags = RV_FULLRST;
2079 if ( (aoverwrite == INC) || (aoverwrite == ABORT) )
2080 fprintf(STDERR,"Volume does not exist; Will perform a full restore\n");
2083 else if ((!readonly && Lp_GetRwIndex(&entry) == -1) /* RW volume does not exist - do a full */
2084 || (readonly && !Lp_ROMatch(0, 0, &entry))) { /* RO volume does not exist - do a full */
2085 restoreflags = RV_FULLRST;
2086 if ( (aoverwrite == INC) || (aoverwrite == ABORT) )
2087 fprintf(STDERR,"%s Volume does not exist; Will perform a full restore\n",
2088 readonly ? "RO" : "RW");
2091 avolid = entry.volumeId[voltype];
2093 else if (entry.volumeId[voltype] != 0 && entry.volumeId[voltype] != avolid) {
2094 avolid = entry.volumeId[voltype];
2098 else { /* volume exists - do we do a full incremental or abort */
2099 int Oserver, Opart, Otype, vol_elsewhere = 0;
2100 struct nvldbentry Oentry;
2104 avolid = entry.volumeId[voltype];
2106 else if(entry.volumeId[voltype] != 0 && entry.volumeId[voltype] != avolid) {
2107 avolid = entry.volumeId[voltype];
2110 /* A file name was specified - check if volume is on another partition */
2111 vcode = GetVolumeInfo(avolid, &Oserver, &Opart, &Otype, &Oentry);
2114 vcode = VLDB_IsSameAddrs(Oserver, aserver, &err);
2116 fprintf(STDERR,"Failed to get info about server's %d address(es) from vlserver (err=%d); aborting call!\n",
2120 if (!vcode || (Opart != apart)) vol_elsewhere = 1;
2122 if (aoverwrite == ASK) {
2123 if (strcmp(afilename,"") == 0) { /* The file is from standard in */
2124 fprintf(STDERR,"Volume exists and no -overwrite option specified; Aborting restore command\n");
2128 /* Ask what to do */
2129 if (vol_elsewhere) {
2130 fprintf(STDERR,"The volume %s %u already exists on a different server/part\n",
2131 volname, entry.volumeId[voltype]);
2133 "Do you want to do a full restore or abort? [fa](a): ");
2137 fprintf(STDERR,"The volume %s %u already exists in the VLDB\n",
2138 volname, entry.volumeId[voltype]);
2140 "Do you want to do a full/incremental restore or abort? [fia](a): ");
2143 while (!(dc==EOF || dc=='\n')) dc=getchar(); /* goto end of line */
2144 if ((c == 'f') || (c == 'F')) aoverwrite = FULL;
2145 else if ((c == 'i') || (c == 'I')) aoverwrite = INC;
2146 else aoverwrite = ABORT;
2149 if (aoverwrite == ABORT) {
2150 fprintf(STDERR,"Volume exists; Aborting restore command\n");
2153 else if (aoverwrite == FULL) {
2154 restoreflags = RV_FULLRST;
2155 fprintf(STDERR,"Volume exists; Will delete and perform full restore\n");
2157 else if (aoverwrite == INC) {
2159 if (vol_elsewhere) {
2161 "%s volume %u already exists on a different server/part; not allowed\n",
2162 readonly ? "RO" : "RW", avolid);
2167 if (offline) restoreflags |= RV_OFFLINE;
2168 if (readonly) restoreflags |= RV_RDONLY;
2169 code = UV_RestoreVolume(aserver, apart, avolid, avolname,
2170 restoreflags, WriteData, afilename);
2172 PrintDiagnostics("restore", code);
2175 MapPartIdIntoName(apart,apartName);
2178 patch typo here - originally "parms[1]", should be "parms[0]"
2181 fprintf(STDOUT,"Restored volume %s on %s %s\n",
2182 avolname, as->parms[0].items->data, apartName);
2185 static LockReleaseCmd(as)
2186 register struct cmd_syndesc *as;
2189 afs_int32 avolid,code, err;
2191 avolid = vsu_GetVolumeID(as->parms[0].items->data, cstruct, &err);
2193 if (err) PrintError("", err);
2194 else fprintf(STDERR, "vos: can't find volume '%s'\n", as->parms[0].items->data);
2198 code = UV_LockRelease(avolid);
2200 PrintDiagnostics("unlock", code);
2203 fprintf(STDOUT,"Released lock on vldb entry for volume %s\n",as->parms[0].items->data);
2207 register struct cmd_syndesc *as;
2209 afs_int32 avolid, aserver, apart,code, err;
2210 char apartName[10], avolname[VOLSER_MAXVOLNAME+1];
2212 vsu_ExtractName(avolname, as->parms[2].items->data);;
2213 avolid = vsu_GetVolumeID(avolname, cstruct, &err);
2215 if (err) PrintError("", err);
2216 else fprintf(STDERR, "vos: can't find volume '%s'\n", as->parms[2].items->data);
2219 aserver = GetServer(as->parms[0].items->data);
2221 fprintf(STDERR,"vos: server '%s' not found in host table\n", as->parms[0].items->data);
2224 apart = volutil_GetPartitionID(as->parms[1].items->data);
2226 fprintf(STDERR,"vos: could not interpret partition name '%s'\n",as->parms[1].items->data );
2229 if (!IsPartValid(apart,aserver,&code)){/*check for validity of the partition */
2230 if(code) PrintError("",code);
2231 else fprintf(STDERR,"vos : partition %s does not exist on the server\n",as->parms[1].items->data);
2234 code = UV_AddSite(aserver, apart, avolid);
2236 PrintDiagnostics("addsite", code);
2239 MapPartIdIntoName(apart,apartName);
2240 fprintf(STDOUT,"Added replication site %s %s for volume %s\n",as->parms[0].items->data, apartName,as->parms[2].items->data);
2244 static RemoveSite(as)
2245 register struct cmd_syndesc *as;
2248 afs_int32 avolid, aserver, apart, code, err;
2249 char apartName[10], avolname[VOLSER_MAXVOLNAME+1];
2251 vsu_ExtractName(avolname, as->parms[2].items->data);
2252 avolid = vsu_GetVolumeID(avolname, cstruct, &err);
2254 if (err) PrintError("", err);
2255 else fprintf(STDERR, "vos: can't find volume '%s'\n", as->parms[2].items->data);
2258 aserver = GetServer(as->parms[0].items->data);
2260 fprintf(STDERR,"vos: server '%s' not found in host table\n", as->parms[0].items->data);
2263 apart = volutil_GetPartitionID(as->parms[1].items->data);
2265 fprintf(STDERR,"vos: could not interpret partition name '%s'\n",as->parms[1].items->data );
2269 *skip the partition validity check, since it is possible that the partition
2270 *has since been decomissioned.
2273 if (!IsPartValid(apart,aserver,&code)){
2274 if(code) PrintError("",code);
2275 else fprintf(STDERR,"vos : partition %s does not exist on the server\n",as->parms[1].items->data);
2279 code = UV_RemoveSite(aserver, apart, avolid);
2281 PrintDiagnostics("remsite", code);
2284 MapPartIdIntoName(apart,apartName);
2285 fprintf(STDOUT,"Removed replication site %s %s for volume %s\n",as->parms[0].items->data,apartName,as->parms[2].items->data);
2288 static ChangeLocation(as)
2289 register struct cmd_syndesc *as;
2291 afs_int32 avolid, aserver, apart,code, err;
2294 avolid = vsu_GetVolumeID(as->parms[2].items->data, cstruct, &err);
2296 if (err) PrintError("", err);
2297 else fprintf(STDERR, "vos: can't find volume '%s'\n", as->parms[2].items->data);
2300 aserver = GetServer(as->parms[0].items->data);
2302 fprintf(STDERR,"vos: server '%s' not found in host table\n", as->parms[0].items->data);
2305 apart = volutil_GetPartitionID(as->parms[1].items->data);
2307 fprintf(STDERR,"vos: could not interpret partition name '%s'\n",as->parms[1].items->data );
2310 if (!IsPartValid(apart,aserver,&code)){/*check for validity of the partition */
2311 if(code) PrintError("",code);
2312 else fprintf(STDERR,"vos : partition %s does not exist on the server\n",as->parms[1].items->data);
2315 code = UV_ChangeLocation(aserver, apart, avolid);
2317 PrintDiagnostics("addsite", code);
2320 MapPartIdIntoName(apart,apartName);
2321 fprintf(STDOUT,"Changed location to %s %s for volume %s\n",as->parms[0].items->data, apartName,as->parms[2].items->data);
2325 static ListPartitions(as)
2326 register struct cmd_syndesc *as;
2328 afs_int32 aserver,code;
2329 struct partList dummyPartList;
2334 aserver = GetServer(as->parms[0].items->data);
2336 fprintf(STDERR,"vos: server '%s' not found in host table\n", as->parms[0].items->data);
2341 code = UV_ListPartitions(aserver,&dummyPartList, &cnt);
2343 PrintDiagnostics("listpart", code);
2347 fprintf(STDOUT,"The partitions on the server are:\n");
2348 for(i = 0 ; i < cnt ; i++){
2349 if(dummyPartList.partFlags[i] & PARTVALID){
2350 memset(pname, 0, sizeof(pname));
2351 MapPartIdIntoName(dummyPartList.partId[i],pname);
2352 fprintf(STDOUT," %10s ",pname);
2354 if( (i % 5) == 0 && (i != 0)) fprintf(STDOUT,"\n");
2357 fprintf(STDOUT,"\n");
2358 fprintf(STDOUT,"Total: %d\n",total);
2363 static int CompareVolName(p1,p2)
2366 volintInfo *arg1,*arg2;
2368 arg1 = (volintInfo *)p1;
2369 arg2 = (volintInfo *)p2;
2370 return(strcmp(arg1->name,arg2->name));
2374 /*------------------------------------------------------------------------
2375 * PRIVATE XCompareVolName
2378 * Comparison routine for volume names coming from an extended
2382 * a_obj1P : Char ptr to first extended vol info object
2383 * a_obj1P : Char ptr to second extended vol info object
2386 * The value of strcmp() on the volume names within the passed
2387 * objects (i,e., -1, 0, or 1).
2390 * Passed to qsort() as the designated comparison routine.
2394 *------------------------------------------------------------------------*/
2396 static int XCompareVolName(a_obj1P, a_obj2P)
2397 char *a_obj1P, *a_obj2P;
2399 { /*XCompareVolName*/
2401 return(strcmp(((struct volintXInfo *)(a_obj1P))->name,
2402 ((struct volintXInfo *)(a_obj2P))->name));
2404 } /*XCompareVolName*/
2406 static int CompareVolID(p1,p2)
2409 volintInfo *arg1,*arg2;
2411 arg1 = (volintInfo *)p1;
2412 arg2 = (volintInfo *)p2;
2413 if(arg1->volid == arg2->volid) return 0;
2414 if(arg1->volid > arg2->volid) return 1;
2419 /*------------------------------------------------------------------------
2420 * PRIVATE XCompareVolID
2423 * Comparison routine for volume IDs coming from an extended
2427 * a_obj1P : Char ptr to first extended vol info object
2428 * a_obj1P : Char ptr to second extended vol info object
2431 * The value of strcmp() on the volume names within the passed
2432 * objects (i,e., -1, 0, or 1).
2435 * Passed to qsort() as the designated comparison routine.
2439 *------------------------------------------------------------------------*/
2441 static int XCompareVolID(a_obj1P, a_obj2P)
2442 char *a_obj1P, *a_obj2P;
2446 afs_int32 id1, id2; /*Volume IDs we're comparing*/
2448 id1 = ((struct volintXInfo *)(a_obj1P))->volid;
2449 id2 = ((struct volintXInfo *)(a_obj2P))->volid;
2460 /*------------------------------------------------------------------------
2461 * PRIVATE ListVolumes
2464 * Routine used to list volumes, contacting the Volume Server
2465 * directly, bypassing the VLDB.
2468 * as : Ptr to parsed command line arguments.
2471 * 0 Successful operation
2474 * Nothing interesting.
2478 *------------------------------------------------------------------------*/
2480 static ListVolumes(as)
2481 register struct cmd_syndesc *as;
2483 afs_int32 apart,int32list,fast;
2484 afs_int32 aserver,code;
2485 volintInfo *pntr,*oldpntr;
2489 volintXInfo *xInfoP, *origxInfoP; /*Ptr to current/orig extended vol info*/
2490 int wantExtendedInfo; /*Do we want extended vol info?*/
2493 struct partList dummyPartList;
2501 if(as->parms[3].items) int32list = 1;
2502 if(as->parms[4].items) quiet = 1;
2504 if(as->parms[2].items) fast = 1;
2507 if (as->parms[5].items) {
2509 * We can't coexist with the fast flag.
2513 "vos: Can't use the -fast and -extended flags together\n");
2518 * We need to turn on ``long'' listings to get the full effect.
2520 wantExtendedInfo = 1;
2524 wantExtendedInfo = 0;
2525 if(as->parms[1].items){
2526 apart = volutil_GetPartitionID(as->parms[1].items->data);
2528 fprintf(STDERR,"vos: could not interpret partition name '%s'\n", as->parms[1].items->data);
2531 dummyPartList.partId[0] = apart;
2532 dummyPartList.partFlags[0] = PARTVALID;
2535 aserver = GetServer(as->parms[0].items->data);
2537 fprintf(STDERR,"vos: server '%s' not found in host table\n",as->parms[0].items->data );
2542 if (!IsPartValid(apart,aserver,&code)){/*check for validity of the partition */
2543 if(code) PrintError("",code);
2544 else fprintf(STDERR,"vos : partition %s does not exist on the server\n",as->parms[1].items->data);
2549 code = UV_ListPartitions(aserver,&dummyPartList, &cnt);
2551 PrintDiagnostics("listvol", code);
2555 for(i = 0 ; i < cnt ; i++){
2556 if(dummyPartList.partFlags[i] & PARTVALID){
2557 if (wantExtendedInfo)
2558 code = UV_XListVolumes(aserver,
2559 dummyPartList.partId[i],
2564 code = UV_ListVolumes(aserver,
2565 dummyPartList.partId[i],
2570 PrintDiagnostics("listvol", code);
2571 if(pntr) free(pntr);
2574 if (wantExtendedInfo) {
2575 origxInfoP = xInfoP;
2576 base = (char *)xInfoP;
2579 base = (char *)pntr;
2583 if (wantExtendedInfo)
2584 qsort(base, count, sizeof(volintXInfo), XCompareVolName);
2586 qsort(base, count, sizeof(volintInfo), CompareVolName);
2588 if (wantExtendedInfo)
2589 qsort(base, count, sizeof(volintXInfo), XCompareVolID);
2591 qsort(base, count, sizeof(volintInfo), CompareVolID);
2593 MapPartIdIntoName(dummyPartList.partId[i],pname);
2595 fprintf(STDOUT,"Total number of volumes on server %s partition %s: %u \n",as->parms[0].items->data,pname,count);
2596 if (wantExtendedInfo) {
2597 XDisplayVolumes(aserver,
2598 dummyPartList.partId[i],
2606 xInfoP = (volintXInfo *)0;
2609 #ifdef FULL_LISTVOL_SWITCH
2610 if (as->parms[6].items)
2611 DisplayVolumes2(aserver, dummyPartList.partId[i], oldpntr,
2614 #endif /* FULL_LISTVOL_SWITCH */
2615 DisplayVolumes(aserver,
2616 dummyPartList.partId[i],
2624 pntr = (volintInfo *)0;
2632 register struct cmd_syndesc *as;
2634 afs_int32 pname, code; /* part name */
2640 if (as->parms[0].items) {
2641 tserver = GetServer(as->parms[0].items->data);
2643 fprintf(STDERR,"vos: host '%s' not found in host table\n",as->parms[0].items->data );
2648 if (as->parms[1].items) {
2649 pname = volutil_GetPartitionID(as->parms[1].items->data);
2651 fprintf(STDERR,"vos: could not interpret partition name '%s'\n",as->parms[1].items->data );
2654 if (!IsPartValid(pname,tserver,&code)) { /*check for validity of the partition */
2655 if(code) PrintError("",code);
2656 else fprintf(STDERR,"vos: partition %s does not exist on the server\n",
2657 as->parms[1].items->data);
2663 fprintf(STDERR,"The -partition option requires a -server option\n");
2668 if (as->parms[2].items) {
2669 /* Synchronize an individual volume */
2670 volname = as->parms[2].items->data;
2671 code = UV_SyncVolume(tserver, pname, volname, flags);
2674 fprintf(STDERR,"Without a -volume option, the -server option is required\n");
2677 code = UV_SyncVldb(tserver, pname, flags, 0/*unused*/);
2681 PrintDiagnostics("syncvldb", code);
2685 /* Print a summary of what we did */
2686 if (volname) fprintf(STDOUT,"VLDB volume %s synchronized", volname);
2687 else fprintf(STDOUT,"VLDB synchronized");
2689 fprintf(STDOUT," with state of server %s", as->parms[0].items->data);
2692 MapPartIdIntoName(pname,part);
2693 fprintf(STDOUT," partition %s\n", part);
2695 fprintf(STDOUT, "\n");
2700 static SyncServer(as)
2701 register struct cmd_syndesc *as;
2704 afs_int32 pname,code; /* part name */
2709 tserver = GetServer(as->parms[0].items->data);
2711 fprintf(STDERR,"vos: host '%s' not found in host table\n",as->parms[0].items->data );
2714 if(as->parms[1].items){
2715 pname = volutil_GetPartitionID(as->parms[1].items->data);
2717 fprintf(STDERR,"vos: could not interpret partition name '%s'\n",as->parms[1].items->data);
2720 if (!IsPartValid(pname,tserver,&code)){/*check for validity of the partition */
2721 if(code) PrintError("",code);
2722 else fprintf(STDERR,"vos : partition %s does not exist on the server\n",as->parms[1].items->data);
2728 code = UV_SyncServer(tserver, pname, flags, 0/*unused*/);
2730 PrintDiagnostics("syncserv", code);
2734 MapPartIdIntoName(pname,part);
2735 fprintf(STDOUT,"Server %s partition %s synchronized with VLDB\n",as->parms[0].items->data,part);
2737 else fprintf(STDOUT,"Server %s synchronized with VLDB\n",as->parms[0].items->data);
2742 static VolumeInfoCmd(name)
2745 struct nvldbentry entry;
2748 /* The vlserver will handle names with the .readonly
2749 * and .backup extension as well as volume ids.
2751 vcode = VLDB_GetEntryByName(name, &entry);
2753 PrintError("", vcode);
2756 MapHostToNetwork(&entry);
2757 EnumerateEntry(&entry);
2759 /* Defect #3027: grubby check to handle locked volume.
2760 * If VLOP_ALLOPERS is set, the entry is locked.
2761 * Leave this routine as is, but put in correct check.
2763 if (entry.flags & VLOP_ALLOPERS)
2764 fprintf(STDOUT," Volume is currently LOCKED \n");
2769 static VolumeZap(as)
2770 register struct cmd_syndesc *as;
2773 struct nvldbentry entry;
2774 afs_int32 volid,code,server,part, zapbackupid=0, backupid=0, err;
2776 if (as->parms[3].items) {
2777 /* force flag is on, use the other version */
2778 return NukeVolume(as);
2781 if (as->parms[4].items) {
2785 volid = vsu_GetVolumeID(as->parms[2].items->data, cstruct, &err);
2787 if (err) PrintError("", err);
2788 else fprintf(STDERR, "vos: can't find volume '%s'\n", as->parms[2].items->data);
2791 part = volutil_GetPartitionID(as->parms[1].items->data);
2793 fprintf(STDERR,"vos: could not interpret partition name '%s'\n",as->parms[1].items->data );
2796 server = GetServer(as->parms[0].items->data);
2798 fprintf(STDERR,"vos: host '%s' not found in host table\n",as->parms[0].items->data );
2801 if (!IsPartValid(part,server,&code)){/*check for validity of the partition */
2802 if(code) PrintError("",code);
2803 else fprintf(STDERR,"vos : partition %s does not exist on the server\n",as->parms[1].items->data);
2806 code = VLDB_GetEntryByID(volid,-1, &entry);
2808 if (volid == entry.volumeId[RWVOL])
2809 backupid = entry.volumeId[BACKVOL];
2810 fprintf(STDERR,"Warning: Entry for volume number %u exists in VLDB (but we're zapping it anyway!)\n",
2814 volintInfo *pntr = (volintInfo *)0;
2817 code = UV_ListOneVolume(server, part, volid, &pntr);
2819 if (volid == pntr->parentID)
2820 backupid = pntr->backupID;
2821 if (pntr) free(pntr);
2825 code = UV_VolumeZap(server,part, backupid);
2827 PrintDiagnostics("zap", code);
2830 fprintf(STDOUT,"Backup Volume %u deleted\n", backupid);
2833 code = UV_VolumeZap(server,part,volid);
2835 PrintDiagnostics("zap", code);
2838 fprintf(STDOUT,"Volume %u deleted\n",volid);
2843 static VolserStatus(as)
2844 register struct cmd_syndesc *as;
2847 afs_int32 server, code;
2848 transDebugInfo *pntr,*oldpntr;
2853 server = GetServer(as->parms[0].items->data);
2855 fprintf(STDERR,"vos: host '%s' not found in host table\n",as->parms[0].items->data );
2858 code = UV_VolserStatus(server,&pntr,&count);
2860 PrintDiagnostics("status",code);
2865 fprintf(STDOUT,"No active transactions on %s\n",as->parms[0].items->data);
2867 fprintf(STDOUT,"Total transactions: %d\n",count);
2869 for(i = 0; i < count ; i++){
2870 /*print out the relevant info */
2871 fprintf(STDOUT,"--------------------------------------\n");
2872 fprintf(STDOUT,"transaction: %u created: %s",pntr->tid,
2873 ctime((time_t *)&pntr->time));
2874 if(pntr->returnCode){
2875 fprintf(STDOUT,"returnCode: %u\n",pntr->returnCode);
2878 fprintf(STDOUT,"attachFlags: ");
2879 switch(pntr->iflags){
2880 case ITOffline: fprintf(STDOUT,"offline ");
2882 case ITBusy: fprintf(STDOUT,"busy ");
2884 case ITReadOnly: fprintf(STDOUT,"readonly ");
2886 case ITCreate: fprintf(STDOUT,"create ");
2888 case ITCreateVolID: fprintf(STDOUT,"create volid ");
2891 fprintf(STDOUT,"\n");
2894 fprintf(STDOUT,"volumeStatus: ");
2895 switch(pntr->vflags){
2896 case VTDeleteOnSalvage: fprintf(STDOUT,"deleteOnSalvage ");
2897 case VTOutOfService: fprintf(STDOUT,"outOfService ");
2898 case VTDeleted: fprintf(STDOUT,"deleted ");
2900 fprintf(STDOUT,"\n");
2903 fprintf(STDOUT,"transactionFlags: ");
2904 fprintf(STDOUT,"delete\n");
2906 MapPartIdIntoName(pntr->partition ,pname);
2907 fprintf(STDOUT,"volume: %u partition: %s procedure: %s\n",pntr->volid,pname, pntr->lastProcName);
2908 if(pntr->callValid){
2909 fprintf(STDOUT,"packetRead: %u lastReceiveTime: %d packetSend: %u lastSendTime: %d\n",pntr->readNext,pntr->lastReceiveTime,pntr->transmitNext, pntr->lastSendTime);
2912 fprintf(STDOUT,"--------------------------------------\n");
2913 fprintf(STDOUT,"\n");
2915 if(oldpntr) free(oldpntr);
2919 static RenameVolume(as)
2920 register struct cmd_syndesc *as;
2922 afs_int32 code1,code2,code;
2923 struct nvldbentry entry;
2925 code1 = VLDB_GetEntryByName(as->parms[0].items->data, &entry);
2927 fprintf(STDERR,"vos: Could not find entry for volume %s\n",as->parms[0].items->data);
2930 code2 = VLDB_GetEntryByName(as->parms[1].items->data, &entry);
2931 if((!code1) && (!code2)) { /*the newname already exists */
2932 fprintf(STDERR,"vos: volume %s already exists\n",as->parms[1].items->data);
2937 fprintf(STDERR,"vos: Could not find entry for volume %s or %s\n",as->parms[0].items->data,as->parms[1].items->data);
2940 if(!VolNameOK(as->parms[0].items->data)){
2941 fprintf(STDERR,"Illegal volume name %s, should not end in .readonly or .backup\n",as->parms[0].items->data);
2944 if(!ISNAMEVALID(as->parms[1].items->data)) {
2945 fprintf(STDERR,"vos: the new volume name %s exceeds the size limit of %d\n",as->parms[1].items->data,VOLSER_OLDMAXVOLNAME - 10);
2948 if(!VolNameOK(as->parms[1].items->data)){
2949 fprintf(STDERR,"Illegal volume name %s, should not end in .readonly or .backup\n",as->parms[1].items->data);
2952 if(IsNumeric(as->parms[1].items->data)){
2953 fprintf(STDERR,"Illegal volume name %s, should not be a number\n",as->parms[1].items->data);
2956 MapHostToNetwork(&entry);
2957 code = UV_RenameVolume(&entry,as->parms[0].items->data,as->parms[1].items->data);
2959 PrintDiagnostics("rename", code);
2962 fprintf(STDOUT,"Renamed volume %s to %s\n",as->parms[0].items->data,as->parms[1].items->data);
2966 GetVolumeInfo(volid, server, part, voltype,rentry)
2967 afs_int32 *server, volid, *part, *voltype;
2968 register struct nvldbentry *rentry;
2973 vcode = VLDB_GetEntryByID(volid, -1, rentry);
2975 fprintf(STDERR,"Could not fetch the entry for volume %u from VLDB \n",volid);
2976 PrintError("",vcode);
2979 MapHostToNetwork(rentry);
2980 if(volid == rentry->volumeId[ROVOL]){
2982 for (i = 0; i < rentry->nServers; i++) {
2983 if ( (index == -1) && (rentry->serverFlags[i] & ITSROVOL) &&
2984 !(rentry->serverFlags[i] & RO_DONTUSE) )
2988 fprintf(STDERR,"RO volume is not found in VLDB entry for volume %u\n", volid);
2992 *server = rentry->serverNumber[index];
2993 *part = rentry->serverPartition[index];
2997 index = Lp_GetRwIndex(rentry);
2999 fprintf(STDERR,"RW Volume is not found in VLDB entry for volume %u\n", volid);
3002 if(volid == rentry->volumeId[RWVOL]){
3004 *server = rentry->serverNumber[index];
3005 *part = rentry->serverPartition[index];
3008 if(volid == rentry->volumeId[BACKVOL]){
3010 *server = rentry->serverNumber[index];
3011 *part = rentry->serverPartition[index];
3016 static DeleteEntry(as)
3017 register struct cmd_syndesc *as;
3023 struct VldbListByAttributes attributes;
3024 nbulkentries arrayEntries;
3025 register struct nvldbentry *vllist;
3026 struct cmd_item *itp;
3029 char prefix[VOLSER_MAXVOLNAME+1];
3031 afs_int32 totalBack=0, totalFail=0, err;
3033 if (as->parms[0].items) { /* -id */
3034 if (as->parms[1].items || as->parms[2].items || as->parms[3].items) {
3035 fprintf(STDERR,"You cannot use -server, -partition, or -prefix with the -id argument\n");
3038 for (itp=as->parms[0].items; itp; itp=itp->next) {
3039 avolid = vsu_GetVolumeID(itp->data, cstruct, &err);
3041 if (err) PrintError("", err);
3042 else fprintf(STDERR, "vos: can't find volume '%s'\n", itp->data);
3045 if (as->parms[4].items) { /* -noexecute */
3046 fprintf(STDOUT,"Would have deleted VLDB entry for %s \n", itp->data);
3050 vcode = ubik_Call(VL_DeleteEntry,cstruct, 0, avolid, RWVOL);
3052 fprintf(STDERR,"Could not delete entry for volume %s\n", itp->data);
3053 fprintf(STDERR,"You must specify a RW volume name or ID "
3054 "(the entire VLDB entry will be deleted)\n", itp->data);
3055 PrintError("",vcode);
3061 fprintf(STDOUT,"Deleted %d VLDB entries\n", totalBack);
3065 if (!as->parms[1].items && !as->parms[2].items && !as->parms[3].items) {
3066 fprintf(STDERR,"You must specify an option\n");
3070 /* Zero out search attributes */
3071 memset(&attributes, 0, sizeof(struct VldbListByAttributes));
3073 if (as->parms[1].items) { /* -prefix */
3074 strncpy(prefix, as->parms[1].items->data, VOLSER_MAXVOLNAME);
3076 if (!as->parms[2].items && !as->parms[3].items) { /* a single entry only */
3077 fprintf(STDERR,"You must provide -server with the -prefix argument\n");
3082 if (as->parms[2].items) { /* -server */
3084 aserver = GetServer(as->parms[2].items->data);
3086 fprintf(STDERR,"vos: server '%s' not found in host table\n",as->parms[2].items->data );
3089 attributes.server = ntohl(aserver);
3090 attributes.Mask |= VLLIST_SERVER;
3093 if (as->parms[3].items) { /* -partition */
3094 if (!as->parms[2].items) {
3095 fprintf(STDERR,"You must provide -server with the -partition argument\n");
3098 apart = volutil_GetPartitionID(as->parms[3].items->data);
3100 fprintf(STDERR,"vos: could not interpret partition name '%s'\n",
3101 as->parms[3].items->data);
3104 attributes.partition = apart;
3105 attributes.Mask |= VLLIST_PARTITION;
3108 /* Print status line of what we are doing */
3109 fprintf(STDOUT,"Deleting VLDB entries for ");
3110 if (as->parms[2].items) {
3111 fprintf(STDOUT,"server %s ", as->parms[2].items->data);
3113 if (as->parms[3].items) {
3115 MapPartIdIntoName(apart, pname);
3116 fprintf(STDOUT,"partition %s ", pname);
3119 fprintf(STDOUT,"which are prefixed with %s ", prefix);
3121 fprintf(STDOUT,"\n");
3124 /* Get all the VLDB entries on a server and/or partition */
3125 memset(&arrayEntries, 0, sizeof(arrayEntries));
3126 vcode = VLDB_ListAttributes(&attributes, &nentries, &arrayEntries);
3128 fprintf(STDERR,"Could not access the VLDB for attributes\n");
3129 PrintError("",vcode);
3133 /* Process each entry */
3134 for (j=0; j<nentries; j++) {
3135 vllist = &arrayEntries.nbulkentries_val[j];
3137 /* It only deletes the RW volumes */
3138 if (strncmp(vllist->name, prefix, strlen(prefix))){
3140 fprintf(STDOUT,"Omitting to delete %s due to prefix %s mismatch\n",
3141 vllist->name, prefix);
3148 if (as->parms[4].items) { /* -noexecute */
3149 fprintf(STDOUT,"Would have deleted VLDB entry for %s \n", vllist->name);
3154 /* Only matches the RW volume name */
3155 avolid = vllist->volumeId[RWVOL];
3156 vcode = ubik_Call(VL_DeleteEntry, cstruct, 0, avolid, RWVOL);
3158 fprintf(STDOUT,"Could not delete VDLB entry for %s\n",vllist->name);
3160 PrintError("",vcode);
3165 fprintf(STDOUT,"Deleted VLDB entry for %s \n",vllist->name);
3170 fprintf(STDOUT,"----------------------\n");
3171 fprintf(STDOUT,"Total VLDB entries deleted: %u; failed to delete: %u\n",totalBack,totalFail);
3172 if (arrayEntries.nbulkentries_val) free(arrayEntries.nbulkentries_val);
3177 static int CompareVldbEntryByName(p1,p2)
3180 struct nvldbentry *arg1,*arg2;
3182 arg1 = (struct nvldbentry *)p1;
3183 arg2 = (struct nvldbentry *)p2;
3184 return(strcmp(arg1->name,arg2->name));
3188 static int CompareVldbEntry(p1,p2)
3191 struct nvldbentry *arg1,*arg2;
3194 char comp1[100],comp2[100];
3195 char temp1[20],temp2[20];
3197 arg1 = (struct nvldbentry *)p1;
3198 arg2 = (struct nvldbentry *)p2;
3202 for(i = 0; i < arg1->nServers; i++)
3203 if(arg1->serverFlags[i] & ITSRWVOL) pos1 = i;
3204 for(i = 0; i < arg2->nServers; i++)
3205 if(arg2->serverFlags[i] & ITSRWVOL) pos2 = i;
3206 if(pos1 == -1 || pos2 == -1){
3210 sprintf(comp1,"%10u",arg1->serverNumber[pos1]);
3211 sprintf(comp2,"%10u",arg2->serverNumber[pos2]);
3212 sprintf(temp1,"%10u",arg1->serverPartition[pos1]);
3213 sprintf(temp2,"%10u",arg2->serverPartition[pos2]);
3214 strcat(comp1,temp1);
3215 strcat(comp2,temp2);
3216 strcat(comp1,arg1->name);
3217 strcat(comp1,arg2->name);
3218 return(strcmp(comp1,comp2));
3224 struct cmd_syndesc *as;
3227 afs_int32 aserver,code;
3229 struct VldbListByAttributes attributes;
3230 nbulkentries arrayEntries;
3231 struct nvldbentry *vllist, *tarray=0, *ttarray;
3232 afs_int32 centries, nentries = 0, tarraysize, parraysize;
3235 int quiet, sort, lock;
3236 afs_int32 thisindex, nextindex;
3241 attributes.Mask = 0;
3242 lock = (as->parms[3].items ? 1 : 0); /* -lock flag */
3243 quiet = (as->parms[4].items ? 1 : 0); /* -quit flag */
3244 sort = (as->parms[5].items ? 0 : 1); /* -nosort flag */
3246 /* If the volume name is given, Use VolumeInfoCmd to look it up
3247 * and not ListAttributes.
3249 if (as->parms[0].items) {
3251 fprintf(STDERR,"vos: illegal use of '-locked' switch, need to specify server and/or partition\n");
3254 code = VolumeInfoCmd(as->parms[0].items->data);
3256 PrintError("",code);
3262 /* Server specified */
3263 if (as->parms[1].items) {
3264 aserver = GetServer(as->parms[1].items->data);
3266 fprintf(STDERR,"vos: server '%s' not found in host table\n",as->parms[1].items->data );
3269 attributes.server = ntohl(aserver);
3270 attributes.Mask |= VLLIST_SERVER;
3273 /* Partition specified */
3274 if (as->parms[2].items) {
3275 apart = volutil_GetPartitionID(as->parms[2].items->data);
3277 fprintf(STDERR,"vos: could not interpret partition name '%s'\n", as->parms[2].items->data);
3280 attributes.partition = apart;
3281 attributes.Mask |= VLLIST_PARTITION;
3285 attributes.Mask |= VLLIST_FLAG;
3286 attributes.flag = VLOP_ALLOPERS;
3289 /* Print header information */
3291 MapPartIdIntoName(apart, pname);
3292 fprintf(STDOUT,"VLDB entries for %s %s%s%s %s\n",
3293 (as->parms[1].items ? "server" : "all" ),
3294 (as->parms[1].items ? as->parms[1].items->data : "servers"),
3295 (as->parms[2].items ? " partition " : ""),
3296 (as->parms[2].items ? pname : ""),
3297 (lock ? "which are locked:" : ""));
3300 for (thisindex = 0; (thisindex != -1); thisindex = nextindex) {
3301 memset(&arrayEntries, 0, sizeof(arrayEntries));
3305 vcode = VLDB_ListAttributesN2(&attributes, 0, thisindex,
3306 ¢ries, &arrayEntries, &nextindex);
3307 if (vcode == RXGEN_OPCODE) {
3308 /* Vlserver not running with ListAttributesN2. Fall back */
3309 vcode = VLDB_ListAttributes(&attributes, ¢ries, &arrayEntries);
3313 fprintf(STDERR,"Could not access the VLDB for attributes\n");
3314 PrintError("",vcode);
3317 nentries += centries;
3319 /* We don't sort, so just print the entries now */
3321 for (j = 0; j < centries; j++) { /* process each entry */
3322 vllist = &arrayEntries.nbulkentries_val[j];
3323 MapHostToNetwork(vllist);
3324 EnumerateEntry(vllist);
3326 if(vllist->flags & VLOP_ALLOPERS)
3327 fprintf(STDOUT," Volume is currently LOCKED \n");
3331 /* So we sort. First we must collect all the entries and keep
3334 else if (centries > 0) {
3336 /* steal away the first bulk entries array */
3337 tarray = (struct nvldbentry *)arrayEntries.nbulkentries_val;
3338 tarraysize = centries * sizeof(struct nvldbentry);
3339 arrayEntries.nbulkentries_val = 0;
3341 /* Grow the tarray to keep the extra entries */
3342 parraysize = (centries * sizeof(struct nvldbentry));
3343 ttarray = (struct nvldbentry *) realloc(tarray, tarraysize + parraysize);
3345 fprintf(STDERR,"Could not allocate enough space for the VLDB entries\n");
3351 memcpy(((char *)tarray)+tarraysize, (char *)arrayEntries.nbulkentries_val, parraysize);
3352 tarraysize += parraysize;
3356 /* Free the bulk array */
3357 if (arrayEntries.nbulkentries_val) {
3358 free(arrayEntries.nbulkentries_val);
3359 arrayEntries.nbulkentries_val = 0;
3363 /* Here is where we now sort all the entries and print them */
3364 if (sort && (nentries > 0)) {
3365 qsort((char *)tarray, nentries, sizeof(struct nvldbentry), CompareVldbEntryByName);
3366 for (vllist=tarray, j=0; j<nentries; j++, vllist++) {
3367 MapHostToNetwork(vllist);
3368 EnumerateEntry(vllist);
3370 if(vllist->flags & VLOP_ALLOPERS)
3371 fprintf(STDOUT," Volume is currently LOCKED \n");
3376 if (!quiet) fprintf(STDOUT,"\nTotal entries: %u\n", nentries);
3377 if (tarray) free(tarray);
3382 register struct cmd_syndesc *as;
3384 afs_int32 apart=0, avolid;
3385 afs_int32 aserver=0, code, aserver1, apart1;
3387 struct VldbListByAttributes attributes;
3388 nbulkentries arrayEntries;
3389 register struct nvldbentry *vllist;
3393 int seenprefix, seenxprefix, exclude, ex, exp, noaction;
3394 afs_int32 totalBack=0;
3395 afs_int32 totalFail=0;
3396 int previdx=-1, error, same;
3399 struct cmd_item *ti;
3403 memset(&attributes, 0, sizeof(struct VldbListByAttributes));
3404 attributes.Mask = 0;
3406 seenprefix = (as->parms[0].items ? 1 : 0);
3407 exclude = (as->parms[3].items ? 1 : 0);
3408 seenxprefix = (as->parms[4].items ? 1 : 0);
3409 noaction = (as->parms[5].items ? 1 : 0);
3411 if (as->parms[1].items) { /* -server */
3412 aserver = GetServer(as->parms[1].items->data);
3414 fprintf(STDERR,"vos: server '%s' not found in host table\n",as->parms[1].items->data );
3417 attributes.server = ntohl(aserver);
3418 attributes.Mask |= VLLIST_SERVER;
3421 if (as->parms[2].items) { /* -partition */
3422 apart = volutil_GetPartitionID(as->parms[2].items->data);
3424 fprintf(STDERR,"vos: could not interpret partition name '%s'\n", as->parms[2].items->data);
3427 attributes.partition = apart;
3428 attributes.Mask |= VLLIST_PARTITION;
3431 /* Check to make sure the prefix and xprefix expressions compile ok */
3433 for (ti=as->parms[0].items; ti; ti=ti->next) {
3434 if (strncmp(ti->data,"^",1) == 0) {
3435 ccode = (char *)re_comp(ti->data);
3437 fprintf(STDERR,"Unrecognizable -prefix regular expression: '%s': %s\n",
3445 for (ti=as->parms[4].items; ti; ti=ti->next) {
3446 if (strncmp(ti->data,"^",1) == 0) {
3447 ccode = (char *)re_comp(ti->data);
3449 fprintf(STDERR,"Unrecognizable -xprefix regular expression: '%s': %s\n",
3457 memset(&arrayEntries, 0, sizeof(arrayEntries)); /* initialize to hint the stub to alloc space */
3458 vcode = VLDB_ListAttributes(&attributes, &nentries, &arrayEntries);
3460 fprintf(STDERR,"Could not access the VLDB for attributes\n");
3461 PrintError("",vcode);
3465 if (as->parms[1].items || as->parms[2].items || verbose) {
3466 fprintf(STDOUT,"%s up volumes", (noaction?"Would have backed":"Backing"));
3468 if (as->parms[1].items) {
3469 fprintf(STDOUT," on server %s", as->parms[1].items->data);
3470 } else if (as->parms[2].items) {
3471 fprintf(STDOUT," for all servers");
3474 if (as->parms[2].items) {
3475 MapPartIdIntoName(apart, pname);
3476 fprintf(STDOUT," partition %s", pname);
3479 if (seenprefix || (!seenprefix && seenxprefix)) {
3480 ti = (seenprefix ? as->parms[0].items : as->parms[4].items);
3481 ex = (seenprefix ? exclude : !exclude);
3482 exp = (strncmp(ti->data,"^",1) == 0);
3483 fprintf(STDOUT," which %smatch %s '%s'", (ex ? "do not " : ""),
3484 (exp?"expression":"prefix"), ti->data);
3485 for (ti=ti->next; ti; ti=ti->next) {
3486 exp = (strncmp(ti->data,"^",1) == 0);
3487 printf(" %sor %s '%s'", (ex ? "n" : ""),
3488 (exp?"expression":"prefix"), ti->data);
3492 if (seenprefix && seenxprefix) {
3493 ti = as->parms[4].items;
3494 exp = (strncmp(ti->data,"^",1) == 0);
3495 fprintf(STDOUT," %swhich match %s '%s'",
3496 (exclude?"adding those ":"removing those "),
3497 (exp?"expression":"prefix"), ti->data);
3498 for (ti=ti->next; ti; ti=ti->next) {
3499 exp = (strncmp(ti->data,"^",1) == 0);
3500 printf(" or %s '%s'", (exp?"expression":"prefix"), ti->data);
3503 fprintf(STDOUT," .. ");
3504 if (verbose) fprintf(STDOUT,"\n");
3508 for (j=0; j<nentries; j++) { /* process each vldb entry */
3509 vllist = &arrayEntries.nbulkentries_val[j];
3512 for (ti=as->parms[0].items; ti; ti=ti->next) {
3513 if (strncmp(ti->data,"^",1) == 0) {
3514 ccode = (char *)re_comp(ti->data);
3516 fprintf(STDERR,"Error in -prefix regular expression: '%s': %s\n",
3520 match = (re_exec(vllist->name) == 1);
3522 match = (strncmp(vllist->name,ti->data,strlen(ti->data)) == 0);
3530 /* Without the -exclude flag: If it matches the prefix, then
3531 * check if we want to exclude any from xprefix.
3532 * With the -exclude flag: If it matches the prefix, then
3533 * check if we want to add any from xprefix.
3535 if (match && seenxprefix) {
3536 for (ti=as->parms[4].items; ti; ti=ti->next) {
3537 if (strncmp(ti->data,"^",1) == 0) {
3538 ccode = (char *)re_comp(ti->data);
3540 fprintf(STDERR,"Error in -xprefix regular expression: '%s': %s\n",
3544 if (re_exec(vllist->name) == 1) {
3549 if (strncmp(vllist->name,ti->data,strlen(ti->data)) == 0) {
3557 if (exclude) match = !match; /* -exclude will reverse the match */
3558 if (!match) continue; /* Skip if no match */
3560 /* Print list of volumes to backup */
3562 fprintf(STDOUT," %s\n", vllist->name);
3566 if(!(vllist->flags & RW_EXISTS)){
3568 fprintf(STDOUT,"Omitting to backup %s since RW volume does not exist \n", vllist->name);
3569 fprintf(STDOUT,"\n");
3575 avolid = vllist->volumeId[RWVOL];
3576 MapHostToNetwork(vllist);
3577 GetServerAndPart(vllist,RWVOL,&aserver1,&apart1,&previdx);
3578 if(aserver1 == -1 || apart1 == -1){
3579 fprintf(STDOUT,"could not backup %s, invalid VLDB entry\n",vllist->name);
3584 same = VLDB_IsSameAddrs(aserver, aserver1, &error);
3586 fprintf(STDERR,"Failed to get info about server's %d address(es) from vlserver (err=%d); aborting call!\n",
3592 if ((aserver && !same) || (apart && (apart != apart1))) {
3594 fprintf(STDOUT, "Omitting to backup %s since the RW is in a different location\n", vllist->name);
3599 time_t now = time(0);
3600 fprintf(STDOUT,"Creating backup volume for %s on %s",vllist->name, ctime(&now));
3604 code = UV_BackupVolume(aserver1, apart1, avolid);
3606 fprintf(STDOUT,"Could not backup %s\n",vllist->name);
3612 if (verbose) fprintf(STDOUT,"\n");
3614 } /* process each vldb entry */
3615 fprintf(STDOUT,"done\n");
3616 fprintf(STDOUT,"Total volumes backed up: %u; failed to backup: %u\n",totalBack,totalFail);
3618 if(arrayEntries.nbulkentries_val) free(arrayEntries.nbulkentries_val);
3622 static UnlockVLDB(as)
3623 register struct cmd_syndesc *as;
3626 afs_int32 aserver,code;
3628 struct VldbListByAttributes attributes;
3629 nbulkentries arrayEntries;
3630 register struct nvldbentry *vllist;
3639 attributes.Mask = 0;
3641 if(as->parms[0].items) {/* server specified */
3642 aserver = GetServer(as->parms[0].items->data);
3644 fprintf(STDERR,"vos: server '%s' not found in host table\n",as->parms[0].items->data );
3647 attributes.server = ntohl(aserver);
3648 attributes.Mask |= VLLIST_SERVER;
3650 if(as->parms[1].items) {/* partition specified */
3651 apart = volutil_GetPartitionID(as->parms[1].items->data);
3653 fprintf(STDERR,"vos: could not interpret partition name '%s'\n", as->parms[1].items->data);
3656 if (!IsPartValid(apart,aserver,&code)){/*check for validity of the partition */
3657 if(code) PrintError("",code);
3658 else fprintf(STDERR,"vos : partition %s does not exist on the server\n",as->parms[1].items->data);
3661 attributes.partition = apart;
3662 attributes.Mask |= VLLIST_PARTITION;
3664 attributes.flag = VLOP_ALLOPERS;
3665 attributes.Mask |= VLLIST_FLAG;
3666 memset(&arrayEntries, 0, sizeof(arrayEntries)); /*initialize to hint the stub to alloc space */
3667 vcode = VLDB_ListAttributes(&attributes, &nentries, &arrayEntries);
3669 fprintf(STDERR,"Could not access the VLDB for attributes\n");
3670 PrintError("",vcode);
3673 for(j=0;j<nentries;j++) { /* process each entry */
3674 vllist = &arrayEntries.nbulkentries_val[j];
3675 volid = vllist->volumeId[RWVOL];
3676 vcode = ubik_Call(VL_ReleaseLock,cstruct, 0, volid,-1, LOCKREL_OPCODE | LOCKREL_AFSID | LOCKREL_TIMESTAMP);
3678 fprintf(STDERR,"Could not unlock entry for volume %s\n",vllist->name);
3679 PrintError("",vcode);
3684 MapPartIdIntoName(apart,pname);
3685 if(totalE) fprintf(STDOUT,"Could not lock %u VLDB entries of %u locked entries\n",totalE,nentries);
3687 if(as->parms[0].items) {
3688 fprintf(STDOUT,"Unlocked all the VLDB entries for volumes on server %s ",as->parms[0].items->data);
3689 if(as->parms[1].items){
3690 MapPartIdIntoName(apart,pname);
3691 fprintf(STDOUT,"partition %s\n",pname);
3693 else fprintf(STDOUT,"\n");
3696 else if(as->parms[1].items){
3697 MapPartIdIntoName(apart,pname);
3698 fprintf(STDOUT,"Unlocked all the VLDB entries for volumes on partition %s on all servers\n",pname);
3702 if(arrayEntries.nbulkentries_val) free(arrayEntries.nbulkentries_val);
3706 static PartitionInfo(as)
3707 register struct cmd_syndesc *as;
3710 afs_int32 aserver,code;
3712 struct diskPartition partition;
3713 struct partList dummyPartList;
3717 aserver = GetServer(as->parms[0].items->data);
3719 fprintf(STDERR,"vos: server '%s' not found in host table\n",as->parms[0].items->data );
3722 if(as->parms[1].items){
3723 apart = volutil_GetPartitionID(as->parms[1].items->data);
3725 fprintf(STDERR,"vos: could not interpret partition name '%s'\n", as->parms[1].items->data);
3728 dummyPartList.partId[0] = apart;
3729 dummyPartList.partFlags[0] = PARTVALID;
3733 if (!IsPartValid(apart,aserver,&code)){/*check for validity of the partition */
3734 if(code) PrintError("",code);
3735 else fprintf(STDERR,"vos : partition %s does not exist on the server\n",as->parms[1].items->data);
3740 code = UV_ListPartitions(aserver,&dummyPartList, &cnt);
3742 PrintDiagnostics("listpart", code);
3746 for(i = 0 ; i < cnt ; i++){
3747 if(dummyPartList.partFlags[i] & PARTVALID){
3748 MapPartIdIntoName(dummyPartList.partId[i],pname);
3749 code = UV_PartitionInfo(aserver,pname,&partition);
3751 fprintf(STDERR,"Could not get information on partition %s\n",pname);
3752 PrintError("",code);
3755 fprintf(STDOUT,"Free space on partition %s: %d K blocks out of total %d\n",pname,partition.free,partition.minFree);
3761 static ChangeAddr(as)
3762 register struct cmd_syndesc *as;
3765 afs_int32 ip1, ip2, vcode;
3768 ip1 = GetServer(as->parms[0].items->data);
3770 fprintf(STDERR, "vos: invalid host address\n");
3774 if ( ( as->parms[1].items && as->parms[2].items) ||
3775 (!as->parms[1].items && !as->parms[2].items) ) {
3776 fprintf(STDERR, "vos: Must specify either '-newaddr <addr>' or '-remove' flag\n");
3780 if (as->parms[1].items) {
3781 ip2 = GetServer(as->parms[1].items->data);
3783 fprintf(STDERR, "vos: invalid host address\n");
3787 /* Play a trick here. If we are removing an address, ip1 will be -1
3788 * and ip2 will be the original address. This switch prevents an
3789 * older revision vlserver from removing the IP address.
3796 vcode = ubik_Call_New(VL_ChangeAddr, cstruct, 0, ntohl(ip1), ntohl(ip2) );
3799 fprintf(STDERR,"Could not remove server %s from the VLDB\n",
3800 as->parms[0].items->data);
3801 if (vcode == VL_NOENT) {
3802 fprintf(STDERR, "vlserver does not support the remove flag or ");
3805 fprintf(STDERR,"Could not change server %s to server %s\n",
3806 as->parms[0].items->data, as->parms[1].items->data);
3808 PrintError("",vcode);
3813 fprintf(STDOUT,"Removed server %s from the VLDB\n",
3814 as->parms[0].items->data);
3816 fprintf(STDOUT,"Changed server %s to server %s\n",
3817 as->parms[0].items->data, as->parms[1].items->data);
3822 static ListAddrs(as)
3823 register struct cmd_syndesc *as;
3828 struct VLCallBack unused;
3829 afs_int32 nentries, *addrp;
3830 bulkaddrs addrs, m_addrs;
3831 ListAddrByAttributes m_attrs;
3833 afs_int32 m_unique, m_nentries, *m_addrp;
3834 afs_int32 base, index;
3836 /* Get the list of non multihomed fileservers */
3837 addrs.bulkaddrs_val = 0;
3838 addrs.bulkaddrs_len = 0;
3839 vcode = ubik_Call_New(VL_GetAddrs, cstruct, 0,
3840 0, 0, &unused, &nentries, &addrs);
3842 fprintf(STDERR,"vos: could not list the server addresses\n");
3843 PrintError("",vcode);
3847 /* print out the list of all the server */
3848 addrp = (afs_int32 *)addrs.bulkaddrs_val;
3849 for (i=0; i<nentries; i++, addrp++) {
3850 /* If it is a multihomed address, then we will need to
3851 * get the addresses for this multihomed server from
3852 * the vlserver and print them.
3854 if ( ((*addrp & 0xff000000) == 0xff000000) && ((*addrp)&0xffff) ) {
3855 /* Get the list of multihomed fileservers */
3856 base = (*addrp>>16) & 0xff;
3857 index = (*addrp) & 0xffff;
3859 if ( (base >= 0) && (base <= VL_MAX_ADDREXTBLKS) &&
3860 (index >= 1) && (index <= VL_MHSRV_PERBLK) ) {
3861 m_attrs.Mask = VLADDR_INDEX;
3862 m_attrs.index = (base * VL_MHSRV_PERBLK) + index;
3864 m_addrs.bulkaddrs_val = 0;
3865 m_addrs.bulkaddrs_len = 0;
3866 vcode = ubik_Call(VL_GetAddrsU, cstruct, 0,
3867 &m_attrs, &m_uuid, &m_unique, &m_nentries, &m_addrs);
3869 fprintf(STDERR,"vos: could not list the multi-homed server addresses\n");
3870 PrintError("",vcode);
3873 /* Print the list */
3874 m_addrp = (afs_int32 *)m_addrs.bulkaddrs_val;
3875 for (j=0; j<m_nentries; j++, m_addrp++) {
3876 *m_addrp = htonl(*m_addrp);
3877 printf("%s ", hostutil_GetNameByINet(*m_addrp));
3880 printf("<unknown>\n");
3889 /* Otherwise, it is a non-multihomed entry and contains
3890 * the IP address of the server - print it.
3892 printf ("%s\n", hostutil_GetNameByINet(htonl(*addrp)));
3895 if (addrs.bulkaddrs_val) {
3896 free (addrs.bulkaddrs_val);
3901 static LockEntry(as)
3902 register struct cmd_syndesc *as;
3905 afs_int32 avolid,vcode, err;
3907 avolid = vsu_GetVolumeID(as->parms[0].items->data, cstruct, &err);
3909 if (err) PrintError("", err);
3910 else fprintf(STDERR, "vos: can't find volume '%s'\n", as->parms[0].items->data);
3913 vcode = ubik_Call(VL_SetLock,cstruct, 0, avolid, -1, VLOP_DELETE);
3915 fprintf(STDERR,"Could not lock VLDB entry for volume %s\n",as->parms[0].items->data);
3916 PrintError("",vcode);
3919 fprintf(STDOUT,"Locked VLDB entry for volume %s\n",as->parms[0].items->data);
3923 PrintDiagnostics(astring, acode)
3927 if (acode == EACCES) {
3928 fprintf(STDERR,"You are not authorized to perform the 'vos %s' command (%d)\n",
3932 fprintf(STDERR,"Error in vos %s command.\n", astring);
3933 PrintError("", acode);
3939 static MyBeforeProc(as, arock)
3940 struct cmd_syndesc *as;
3942 register char *tcell;
3943 register afs_int32 code;
3944 register afs_int32 sauth;
3946 /* Initialize the ubik_client connection */
3947 rx_SetRxDeadTime(90);
3948 cstruct = (struct ubik_client *)0;
3952 if (as->parms[12].items) /* if -cell specified */
3953 tcell = as->parms[12].items->data;
3954 if(as->parms[14].items) /* -serverauth specified */
3956 if(as->parms[16].items) /* -crypt specified */
3958 if (code = vsu_ClientInit((as->parms[13].items != 0), confdir, tcell, sauth,
3959 &cstruct, UV_SetSecurity)) {
3960 fprintf(STDERR,"could not initialize VLDB library (code=%u) \n",code);
3964 if(as->parms[15].items) /* -verbose flag set */
3973 /* this sucks but it works for now.
3978 #include "AFS_component_version_number.c"
3983 register afs_int32 code;
3985 register struct cmd_syndesc *ts;
3987 #ifdef AFS_AIX32_ENV
3989 * The following signal action for AIX is necessary so that in case of a
3990 * crash (i.e. core is generated) we can include the user's data section
3991 * in the core dump. Unfortunately, by default, only a partial core is
3992 * generated which, in many cases, isn't too useful.
3994 struct sigaction nsa;
3996 sigemptyset(&nsa.sa_mask);
3997 nsa.sa_handler = SIG_DFL;
3998 nsa.sa_flags = SA_FULLDUMP;
3999 sigaction(SIGSEGV, &nsa, NULL);
4002 confdir = AFSDIR_CLIENT_ETC_DIRPATH;
4004 cmd_SetBeforeProc(MyBeforeProc, (char *) 0);
4006 ts = cmd_CreateSyntax("create", CreateVolume, 0, "create a new volume");
4007 cmd_AddParm(ts, "-server", CMD_SINGLE, 0, "machine name");
4008 cmd_AddParm(ts, "-partition", CMD_SINGLE, 0, "partition name");
4009 cmd_AddParm(ts, "-name", CMD_SINGLE, 0, "volume name");
4010 cmd_AddParm(ts, "-maxquota", CMD_SINGLE, CMD_OPTIONAL, "initial quota (KB)");
4012 cmd_AddParm(ts, "-minquota", CMD_SINGLE, CMD_OPTIONAL, "");
4016 ts = cmd_CreateSyntax("remove", DeleteVolume, 0, "delete a volume");
4017 cmd_AddParm(ts, "-server", CMD_SINGLE, CMD_OPTIONAL, "machine name");
4018 cmd_AddParm(ts, "-partition", CMD_SINGLE, CMD_OPTIONAL, "partition name");
4019 cmd_AddParm(ts, "-id", CMD_SINGLE, 0, "volume name or ID");
4023 ts = cmd_CreateSyntax("move", MoveVolume, 0, "move a volume");
4024 cmd_AddParm(ts, "-id", CMD_SINGLE, 0, "volume name or ID");
4025 cmd_AddParm(ts, "-fromserver", CMD_SINGLE, 0, "machine name on source");
4026 cmd_AddParm(ts, "-frompartition", CMD_SINGLE, 0, "partition name on source");
4027 cmd_AddParm(ts, "-toserver", CMD_SINGLE, 0, "machine name on destination");
4028 cmd_AddParm(ts, "-topartition", CMD_SINGLE, 0, "partition name on destination");
4031 ts = cmd_CreateSyntax("backup", BackupVolume, 0, "make backup of a volume");
4032 cmd_AddParm(ts, "-id", CMD_SINGLE, 0, "volume name or ID");
4035 ts = cmd_CreateSyntax("release", ReleaseVolume, 0, "release a volume");
4036 cmd_AddParm(ts, "-id", CMD_SINGLE, 0, "volume name or ID");
4037 cmd_AddParm(ts, "-force", CMD_FLAG, CMD_OPTIONAL, "force a complete release");
4040 ts = cmd_CreateSyntax("dump", DumpVolume, 0, "dump a volume");
4041 cmd_AddParm(ts, "-id", CMD_SINGLE, 0, "volume name or ID");
4042 cmd_AddParm(ts, "-time", CMD_SINGLE, CMD_OPTIONAL, "dump from time");
4043 cmd_AddParm(ts, "-file", CMD_SINGLE, CMD_OPTIONAL, "dump file");
4044 cmd_AddParm(ts, "-server", CMD_SINGLE, CMD_OPTIONAL, "server");
4045 cmd_AddParm(ts, "-partition", CMD_SINGLE, CMD_OPTIONAL, "partition");
4048 ts = cmd_CreateSyntax("restore", RestoreVolume, 0, "restore a volume");
4049 cmd_AddParm(ts, "-server", CMD_SINGLE, 0, "machine name");
4050 cmd_AddParm(ts, "-partition", CMD_SINGLE, 0, "partition name");
4051 cmd_AddParm(ts, "-name", CMD_SINGLE, 0, "name of volume to be restored");
4052 cmd_AddParm(ts, "-file", CMD_SINGLE,CMD_OPTIONAL, "dump file");
4053 cmd_AddParm(ts, "-id", CMD_SINGLE,CMD_OPTIONAL, "volume ID");
4054 cmd_AddParm(ts, "-overwrite", CMD_SINGLE,CMD_OPTIONAL, "abort | full | incremental");
4055 cmd_AddParm(ts, "-offline", CMD_FLAG, CMD_OPTIONAL,
4056 "leave restored volume offline");
4057 cmd_AddParm(ts, "-readonly", CMD_FLAG, CMD_OPTIONAL,
4058 "make restored volume read-only");
4061 ts = cmd_CreateSyntax("unlock", LockReleaseCmd, 0, "release lock on VLDB entry for a volume");
4062 cmd_AddParm(ts, "-id", CMD_SINGLE, 0, "volume name or ID");
4065 ts = cmd_CreateSyntax("changeloc", ChangeLocation, 0, "change an RW volume's location in the VLDB");
4066 cmd_AddParm(ts, "-server", CMD_SINGLE, 0, "machine name for new location");
4067 cmd_AddParm(ts, "-partition", CMD_SINGLE, 0, "partition name for new location");
4068 cmd_AddParm(ts, "-id", CMD_SINGLE, 0, "volume name or ID");
4071 ts = cmd_CreateSyntax("addsite", AddSite, 0, "add a replication site");
4072 cmd_AddParm(ts, "-server", CMD_SINGLE, 0, "machine name for new site");
4073 cmd_AddParm(ts, "-partition", CMD_SINGLE, 0, "partition name for new site");
4074 cmd_AddParm(ts, "-id", CMD_SINGLE, 0, "volume name or ID");
4077 ts = cmd_CreateSyntax("remsite", RemoveSite, 0, "remove a replication site");
4078 cmd_AddParm(ts, "-server", CMD_SINGLE, 0, "machine name");
4079 cmd_AddParm(ts, "-partition", CMD_SINGLE, 0, "partition name");
4080 cmd_AddParm(ts, "-id", CMD_SINGLE, 0, "volume name or ID");
4083 ts = cmd_CreateSyntax("listpart", ListPartitions, 0, "list partitions");
4084 cmd_AddParm(ts, "-server", CMD_SINGLE, 0, "machine name");
4087 ts = cmd_CreateSyntax("listvol", ListVolumes, 0, "list volumes on server (bypass VLDB)");
4088 cmd_AddParm(ts, "-server", CMD_SINGLE, 0, "machine name");
4089 cmd_AddParm(ts, "-partition", CMD_SINGLE,CMD_OPTIONAL, "partition name");
4090 cmd_AddParm(ts, "-fast", CMD_FLAG, CMD_OPTIONAL, "minimal listing");
4091 cmd_AddParm(ts, "-long", CMD_FLAG, CMD_OPTIONAL,
4092 "list all normal volume fields");
4093 cmd_AddParm(ts, "-quiet", CMD_FLAG, CMD_OPTIONAL, "generate minimal information");
4094 cmd_AddParm(ts, "-extended", CMD_FLAG, CMD_OPTIONAL,
4095 "list extended volume fields");
4096 #ifdef FULL_LISTVOL_SWITCH
4097 cmd_AddParm(ts, "-format", CMD_FLAG, CMD_OPTIONAL,
4098 "machine readable format");
4099 #endif /* FULL_LISTVOL_SWITCH */
4102 ts = cmd_CreateSyntax("syncvldb", SyncVldb, 0, "synchronize VLDB with server");
4103 cmd_AddParm(ts, "-server", CMD_SINGLE, CMD_OPTIONAL, "machine name");
4104 cmd_AddParm(ts, "-partition", CMD_SINGLE,CMD_OPTIONAL , "partition name");
4105 cmd_AddParm(ts, "-volume", CMD_SINGLE,CMD_OPTIONAL , "volume name or ID");
4108 ts = cmd_CreateSyntax("syncserv", SyncServer, 0, "synchronize server with VLDB");
4109 cmd_AddParm(ts, "-server", CMD_SINGLE, 0, "machine name");
4110 cmd_AddParm(ts, "-partition", CMD_SINGLE,CMD_OPTIONAL , "partition name");
4113 ts = cmd_CreateSyntax("examine", ExamineVolume, 0, "everything about the volume");
4114 cmd_AddParm(ts, "-id", CMD_SINGLE, 0, "volume name or ID");
4115 cmd_AddParm(ts, "-extended", CMD_FLAG, CMD_OPTIONAL,
4116 "list extended volume fields");
4117 #ifdef FULL_LISTVOL_SWITCH
4118 cmd_AddParm(ts, "-format", CMD_FLAG, CMD_OPTIONAL,
4119 "machine readable format");
4120 #endif /* FULL_LISTVOL_SWITCH */
4122 cmd_CreateAlias (ts, "volinfo");
4124 ts = cmd_CreateSyntax("setfields", SetFields, 0, "change volume info fields");
4125 cmd_AddParm(ts, "-id", CMD_SINGLE, 0, "volume name or ID");
4126 cmd_AddParm(ts, "-maxquota", CMD_SINGLE, CMD_OPTIONAL, "quota (KB)");
4127 cmd_AddParm(ts, "-clearuse", CMD_FLAG, CMD_OPTIONAL, "clear dayUse");
4130 ts = cmd_CreateSyntax("offline", volOffline, 0, (char *) CMD_HIDDEN);
4131 cmd_AddParm(ts, "-server", CMD_SINGLE, 0, "server name");
4132 cmd_AddParm(ts, "-partition", CMD_SINGLE, 0, "partition name");
4133 cmd_AddParm(ts, "-id", CMD_SINGLE, 0, "volume name or ID");
4134 cmd_AddParm(ts, "-sleep", CMD_SINGLE, CMD_OPTIONAL, "seconds to sleep");
4135 cmd_AddParm(ts, "-busy", CMD_FLAG, CMD_OPTIONAL, "busy volume");
4138 ts = cmd_CreateSyntax("online", volOnline, 0, (char *) CMD_HIDDEN);
4139 cmd_AddParm(ts, "-server", CMD_SINGLE, 0, "server name");
4140 cmd_AddParm(ts, "-partition", CMD_SINGLE, 0, "partition name");
4141 cmd_AddParm(ts, "-id", CMD_SINGLE, 0, "volume name or ID");
4144 ts = cmd_CreateSyntax("zap", VolumeZap, 0, "delete the volume, don't bother with VLDB");
4145 cmd_AddParm(ts, "-server", CMD_SINGLE, 0, "machine name");
4146 cmd_AddParm(ts, "-partition", CMD_SINGLE, 0, "partition name");
4147 cmd_AddParm(ts, "-id", CMD_SINGLE, 0, "volume ID");
4148 cmd_AddParm(ts, "-force", CMD_FLAG, CMD_OPTIONAL, "force deletion of bad volumes");
4149 cmd_AddParm(ts, "-backup", CMD_FLAG, CMD_OPTIONAL, "also delete backup volume if one is found");
4152 ts = cmd_CreateSyntax("status", VolserStatus, 0, "report on volser status");
4153 cmd_AddParm(ts, "-server", CMD_SINGLE, 0, "machine name");
4156 ts = cmd_CreateSyntax("rename", RenameVolume, 0, "rename a volume");
4157 cmd_AddParm(ts, "-oldname", CMD_SINGLE, 0, "old volume name ");
4158 cmd_AddParm(ts, "-newname", CMD_SINGLE, 0, "new volume name ");
4161 ts = cmd_CreateSyntax("listvldb", ListVLDB, 0, "list volumes in the VLDB");
4162 cmd_AddParm(ts, "-name", CMD_SINGLE,CMD_OPTIONAL, "volume name or ID");
4163 cmd_AddParm(ts, "-server", CMD_SINGLE,CMD_OPTIONAL, "machine name");
4164 cmd_AddParm(ts, "-partition", CMD_SINGLE,CMD_OPTIONAL, "partition name");
4165 cmd_AddParm(ts, "-locked", CMD_FLAG, CMD_OPTIONAL, "locked volumes only");
4166 cmd_AddParm(ts, "-quiet", CMD_FLAG, CMD_OPTIONAL, "generate minimal information");
4167 cmd_AddParm(ts, "-nosort", CMD_FLAG, CMD_OPTIONAL, "do not alphabetically sort the volume names");
4170 ts = cmd_CreateSyntax("backupsys", BackSys, 0, "en masse backups");
4171 cmd_AddParm(ts, "-prefix", CMD_LIST,CMD_OPTIONAL, "common prefix on volume(s)");
4172 cmd_AddParm(ts, "-server", CMD_SINGLE,CMD_OPTIONAL, "machine name");
4173 cmd_AddParm(ts, "-partition", CMD_SINGLE,CMD_OPTIONAL, "partition name");
4174 cmd_AddParm(ts, "-exclude", CMD_FLAG, CMD_OPTIONAL, "exclude common prefix volumes");
4175 cmd_AddParm(ts, "-xprefix", CMD_LIST, CMD_OPTIONAL, "negative prefix on volume(s)");
4176 cmd_AddParm(ts, "-dryrun", CMD_FLAG, CMD_OPTIONAL, "no action");
4179 ts = cmd_CreateSyntax("delentry", DeleteEntry, 0, "delete VLDB entry for a volume");
4180 cmd_AddParm(ts, "-id", CMD_LIST, CMD_OPTIONAL, "volume name or ID");
4181 cmd_AddParm(ts, "-prefix", CMD_SINGLE,CMD_OPTIONAL, "prefix of the volume whose VLDB entry is to be deleted");
4182 cmd_AddParm(ts, "-server", CMD_SINGLE,CMD_OPTIONAL, "machine name");
4183 cmd_AddParm(ts, "-partition", CMD_SINGLE,CMD_OPTIONAL, "partition name");
4184 cmd_AddParm(ts, "-noexecute", CMD_FLAG,CMD_OPTIONAL|CMD_HIDE, "no execute");
4187 ts = cmd_CreateSyntax("partinfo", PartitionInfo, 0, "list partition information");
4188 cmd_AddParm(ts, "-server", CMD_SINGLE, 0, "machine name");
4189 cmd_AddParm(ts, "-partition", CMD_SINGLE,CMD_OPTIONAL, "partition name");
4192 ts = cmd_CreateSyntax("unlockvldb", UnlockVLDB, 0, "unlock all the locked entries in the VLDB");
4193 cmd_AddParm(ts, "-server", CMD_SINGLE,CMD_OPTIONAL, "machine name");
4194 cmd_AddParm(ts, "-partition", CMD_SINGLE,CMD_OPTIONAL, "partition name");
4197 ts = cmd_CreateSyntax("lock", LockEntry, 0, "lock VLDB entry for a volume");
4198 cmd_AddParm(ts, "-id", CMD_SINGLE, 0, "volume name or ID");
4201 ts = cmd_CreateSyntax("changeaddr", ChangeAddr, 0, "change the IP address of a file server");
4202 cmd_AddParm(ts, "-oldaddr", CMD_SINGLE, 0, "original IP address");
4203 cmd_AddParm(ts, "-newaddr", CMD_SINGLE, CMD_OPTIONAL, "new IP address");
4204 cmd_AddParm(ts, "-remove", CMD_FLAG, CMD_OPTIONAL, "remove the IP address from the VLDB");
4207 ts = cmd_CreateSyntax("listaddrs", ListAddrs, 0, "list the IP address of all file servers registered in the VLDB");
4210 code = cmd_Dispatch(argc, argv);
4212 /* Shut down the ubik_client and rx connections */
4214 ubik_ClientDestroy (cstruct);