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 struct hostent *hostutil_GetHostByName(register char *ahost);
67 #define COMMONPARMS cmd_Seek(ts, 12);\
68 cmd_AddParm(ts, "-cell", CMD_SINGLE, CMD_OPTIONAL, "cell name");\
69 cmd_AddParm(ts, "-noauth", CMD_FLAG, CMD_OPTIONAL, "don't authenticate");\
70 cmd_AddParm(ts, "-localauth",CMD_FLAG,CMD_OPTIONAL,"use server tickets");\
71 cmd_AddParm(ts, "-verbose", CMD_FLAG, CMD_OPTIONAL, "verbose");\
72 cmd_AddParm(ts, "-encrypt", CMD_FLAG, CMD_OPTIONAL, "encrypt commands");\
74 #define ERROR_EXIT(code) {error=(code); goto error_exit;}
78 struct rx_connection *tconn;
80 extern struct ubik_client *cstruct;
82 extern struct rx_connection *UV_Bind();
83 extern struct rx_securityClass *rxnull_NewClientSecurityObject();
84 extern int UV_SetSecurity();
85 extern int UV_SetVolumeInfo();
86 extern int vsu_SetCrypt();
88 extern VL_ReleaseLock();
89 extern VL_DeleteEntry();
90 extern VL_ListEntry();
92 extern VL_GetAddrsU();
93 extern VL_ChangeAddr();
95 extern int vsu_ExtractName();
97 extern int MapPartIdIntoName();
98 extern int MapHostToNetwork();
99 extern int MapNetworkToHost();
100 extern void EnumerateEntry();
101 extern void SubEnumerateEntry();
104 static struct tqHead busyHead, notokHead;
106 static void qInit(ahead)
107 struct tqHead *ahead;
109 memset((char *)ahead, 0, sizeof(struct tqHead));
114 static void qPut(ahead,volid)
115 struct tqHead *ahead;
120 elem = (struct tqElem *)malloc(sizeof(struct tqElem));
121 elem->next = ahead->next;
128 static void qGet(ahead,volid)
129 struct tqHead *ahead;
134 if(ahead->count <= 0) return;
135 *volid = ahead->next->volid;
137 ahead->next = tmp->next;
143 /* returns 1 if <filename> exists else 0 */
144 static FileExists(filename)
151 code = usd_Open(filename, USD_OPEN_RDONLY, 0, &ufd);
155 code = USD_IOCTL(ufd, USD_IOCTL_GETSIZE, &size);
163 /* returns 1 if <name> doesnot end in .readonly or .backup, else 0 */
164 static VolNameOK(name)
170 total = strlen(name);
171 if(!strcmp(&name[total - 9],".readonly")) {
174 else if(!strcmp(&name[total - 7 ],".backup")) {
182 /* return 1 if name is a number else 0 */
183 static IsNumeric(name)
192 for(i = 0; i < len ; i++){
193 if(*ptr < '0' || *ptr > '9'){
207 * Parse a server name/address and return the address in HOST BYTE order
209 afs_int32 GetServer(aname)
211 register struct hostent *th;
214 register afs_int32 code;
215 char hostname[MAXHOSTCHARS];
217 code = sscanf(aname, "%d.%d.%d.%d", &b1, &b2, &b3, &b4);
219 addr = (b1<<24) | (b2<<16) | (b3<<8) | b4;
220 addr = ntohl(addr); /* convert to host order */
222 th = gethostbyname(aname);
224 memcpy(&addr, th->h_addr, sizeof(addr));
227 if (addr == htonl(0x7f000001)) { /* local host */
228 code = gethostname(hostname, MAXHOSTCHARS);
230 th = gethostbyname(hostname); /* returns host byte order */
232 memcpy(&addr, th->h_addr, sizeof(addr));
238 afs_int32 GetVolumeType(aname)
242 if(!strcmp(aname,"ro"))
244 else if(!strcmp(aname, "rw"))
246 else if(!strcmp(aname,"bk"))
251 int IsPartValid(partId, server, code)
252 afs_int32 server, partId,*code;
255 struct partList dummyPartList;
263 *code = UV_ListPartitions(server,&dummyPartList, &cnt);
264 if(*code) return success;
265 for(i = 0 ; i < cnt ; i++) {
266 if(dummyPartList.partFlags[i] & PARTVALID)
267 if(dummyPartList.partId[i] == partId)
275 /*sends the contents of file associated with <fd> and <blksize> to Rx Stream
276 * associated with <call> */
277 SendFile(ufd, call, blksize)
279 register struct rx_call *call;
282 char *buffer = (char*) 0;
287 buffer = (char *)malloc(blksize);
289 fprintf(STDERR,"malloc failed\n");
293 while (!error && !done) {
294 #ifndef AFS_NT40_ENV /* NT csn't select on non-socket fd's */
297 FD_SET((int)(ufd->handle), &in);
298 /* don't timeout if read blocks */
299 IOMGR_Select(((int)(ufd->handle))+1, &in, 0, 0, 0);
301 error = USD_READ(ufd, buffer, blksize, &nbytes);
303 fprintf(STDERR, "File system read failed\n");
310 if (rx_Write(call, buffer, nbytes) != nbytes){
315 if (buffer) free(buffer);
319 /* function invoked by UV_RestoreVolume, reads the data from rx_trx_stream and
320 * writes it out to the volume. */
321 afs_int32 WriteData(call,rock)
322 struct rx_call *call;
328 afs_int32 error,code;
334 if(!filename || !*filename) {
335 usd_StandardInput(&ufd);
339 code = usd_Open(filename, USD_OPEN_RDONLY, 0, &ufd);
342 code = USD_IOCTL(ufd, USD_IOCTL_GETBLKSIZE, &blksize);
345 fprintf(STDERR,"Could not access file '%s'\n", filename);
350 code = SendFile(ufd,call,blksize);
357 code = USD_CLOSE(ufd);
359 fprintf(STDERR,"Could not close dump file %s\n",
360 (filename && *filename)?filename:"STDOUT");
361 if(!error) error = code;
367 /* Receive data from <call> stream into file associated
368 * with <fd> <blksize>
370 int ReceiveFile(ufd, call, blksize)
372 struct rx_call *call;
375 char *buffer = (char *) 0;
377 afs_uint32 bytesleft, w;
380 buffer = (char *)malloc(blksize);
382 fprintf(STDERR,"memory allocation failed\n");
386 while ((bytesread=rx_Read(call,buffer,blksize)) > 0) {
387 for (bytesleft=bytesread; bytesleft; bytesleft-=w) {
388 #ifndef AFS_NT40_ENV /* NT csn't select on non-socket fd's */
391 FD_SET((int)(ufd->handle), &out);
392 /* don't timeout if write blocks */
393 IOMGR_Select(((int)(ufd->handle))+1, 0, &out, 0, 0);
395 error = USD_WRITE(ufd, &buffer[bytesread-bytesleft], bytesleft, &w);
397 fprintf(STDERR,"File system write failed\n");
404 if (buffer) free(buffer);
408 afs_int32 DumpFunction(call, filename)
409 struct rx_call *call;
412 usd_handle_t ufd; /* default is to stdout */
413 afs_int32 error=0, code;
418 /* Open the output file */
419 if (!filename || !*filename) {
420 usd_StandardOutput(&ufd);
424 code = usd_Open(filename, USD_OPEN_CREATE|USD_OPEN_RDWR, 0666, &ufd);
428 code = USD_IOCTL(ufd, USD_IOCTL_SETSIZE, &size);
431 code = USD_IOCTL(ufd, USD_IOCTL_GETBLKSIZE, &blksize);
434 fprintf(STDERR, "Could not create file '%s'\n", filename);
435 ERROR_EXIT(VOLSERBADOP);
439 code = ReceiveFile(ufd, call, blksize);
440 if (code) ERROR_EXIT(code);
443 /* Close the output file */
445 code = USD_CLOSE(ufd);
447 fprintf(STDERR,"Could not close dump file %s\n",
448 (filename && *filename)?filename:"STDIN");
449 if (!error) error = code;
456 static void DisplayFormat(pntr,server,part,totalOK,totalNotOK,totalBusy,fast,longlist,disp)
458 afs_int32 server,part;
459 int *totalOK,*totalNotOK,*totalBusy;
460 int fast,longlist, disp;
465 fprintf(STDOUT,"%-10u\n",pntr->volid);
468 if(pntr->status == VOK){
469 fprintf(STDOUT,"%-32s ",pntr->name);
470 fprintf(STDOUT,"%10u ",pntr->volid);
471 if(pntr->type == 0) fprintf(STDOUT,"RW ");
472 if(pntr->type == 1) fprintf(STDOUT,"RO ");
473 if(pntr->type == 2) fprintf(STDOUT,"BK ");
474 fprintf(STDOUT,"%10d K ",pntr->size);
475 if(pntr->inUse == 1) {
476 fprintf(STDOUT,"On-line");
479 fprintf(STDOUT,"Off-line");
482 if(pntr->needsSalvaged == 1) fprintf(STDOUT,"**needs salvage**");
483 fprintf(STDOUT,"\n");
484 MapPartIdIntoName(part,pname);
485 fprintf(STDOUT," %s %s \n",hostutil_GetNameByINet(server),pname);
486 fprintf(STDOUT," RWrite %10u ROnly %10u Backup %10u \n", pntr->parentID,pntr->cloneID, pntr->backupID);
487 fprintf(STDOUT," MaxQuota %10d K \n",pntr->maxquota);
488 fprintf(STDOUT," Creation %s",
489 ctime((time_t *)&pntr->creationDate));
490 #ifdef FULL_LISTVOL_SWITCH
491 fprintf(STDOUT," Copy %s",
492 ctime((time_t *)&pntr->copyDate));
493 if(!pntr->backupDate)
494 fprintf(STDOUT," Backup Never\n");
496 fprintf(STDOUT," Backup %s",
497 ctime((time_t *)&pntr->backupDate));
498 if (pntr->accessDate)
499 fprintf(STDOUT," Last Access %s",
500 ctime((time_t *)&pntr->accessDate));
502 if(pntr->updateDate < pntr->creationDate)
503 fprintf(STDOUT," Last Update %s",
504 ctime((time_t *)&pntr->creationDate));
506 fprintf(STDOUT," Last Update %s",
507 ctime((time_t *)&pntr->updateDate));
508 fprintf(STDOUT, " %d accesses in the past day (i.e., vnode references)\n",
511 else if (pntr->status == VBUSY) {
513 qPut(&busyHead,pntr->volid);
514 if (disp) fprintf(STDOUT,"**** Volume %u is busy ****\n",pntr->volid);
518 qPut(¬okHead,pntr->volid);
519 if (disp) fprintf(STDOUT,"**** Could not attach volume %u ****\n",pntr->volid);
521 fprintf(STDOUT,"\n");
523 else {/* default listing */
524 if(pntr->status == VOK){
525 fprintf(STDOUT,"%-32s ",pntr->name);
526 fprintf(STDOUT,"%10u ",pntr->volid);
527 if(pntr->type == 0) fprintf(STDOUT,"RW ");
528 if(pntr->type == 1) fprintf(STDOUT,"RO ");
529 if(pntr->type == 2) fprintf(STDOUT,"BK ");
530 fprintf(STDOUT,"%10d K ",pntr->size);
531 if(pntr->inUse == 1) {
532 fprintf(STDOUT,"On-line");
535 fprintf(STDOUT,"Off-line");
538 if(pntr->needsSalvaged == 1) fprintf(STDOUT,"**needs salvage**");
539 fprintf(STDOUT,"\n");
541 else if (pntr->status == VBUSY) {
543 qPut(&busyHead,pntr->volid);
544 if (disp) fprintf(STDOUT,"**** Volume %u is busy ****\n",pntr->volid);
548 qPut(¬okHead,pntr->volid);
549 if (disp) fprintf(STDOUT,"**** Could not attach volume %u ****\n",pntr->volid);
554 /*------------------------------------------------------------------------
555 * PRIVATE XDisplayFormat
558 * Display the contents of one extended volume info structure.
561 * a_xInfoP : Ptr to extended volume info struct to print.
562 * a_servID : Server ID to print.
563 * a_partID : Partition ID to print.
564 * a_totalOKP : Ptr to total-OK counter.
565 * a_totalNotOKP : Ptr to total-screwed counter.
566 * a_totalBusyP : Ptr to total-busy counter.
567 * a_fast : Fast listing?
568 * a_int32 : Int32 listing?
569 * a_showProblems : Show volume problems?
575 * Nothing interesting.
579 *------------------------------------------------------------------------*/
581 static void XDisplayFormat(a_xInfoP, a_servID, a_partID, a_totalOKP,
582 a_totalNotOKP, a_totalBusyP, a_fast, a_int32,
584 volintXInfo *a_xInfoP;
602 fprintf(STDOUT, "%-10u\n", a_xInfoP->volid);
607 * Fully-detailed listing.
609 if (a_xInfoP->status == VOK) {
611 * Volume's status is OK - all the fields are valid.
613 fprintf(STDOUT, "%-32s ", a_xInfoP->name);
614 fprintf(STDOUT, "%10u ", a_xInfoP->volid);
615 if (a_xInfoP->type == 0) fprintf(STDOUT,"RW ");
616 if (a_xInfoP->type == 1) fprintf(STDOUT,"RO ");
617 if (a_xInfoP->type == 2) fprintf(STDOUT,"BK ");
618 fprintf(STDOUT, "%10d K used ", a_xInfoP->size);
619 fprintf(STDOUT, "%d files ", a_xInfoP->filecount);
620 if(a_xInfoP->inUse == 1) {
621 fprintf(STDOUT, "On-line");
625 fprintf(STDOUT, "Off-line");
628 fprintf(STDOUT, "\n");
629 MapPartIdIntoName(a_partID, pname);
630 fprintf(STDOUT, " %s %s \n",
631 hostutil_GetNameByINet(a_servID),
633 fprintf(STDOUT, " RWrite %10u ROnly %10u Backup %10u \n",
634 a_xInfoP->parentID, a_xInfoP->cloneID, a_xInfoP->backupID);
635 fprintf(STDOUT, " MaxQuota %10d K \n",
637 fprintf(STDOUT, " Creation %s",
638 ctime((time_t *)&a_xInfoP->creationDate));
639 #ifdef FULL_LISTVOL_SWITCH
640 fprintf(STDOUT," Copy %s",
641 ctime((time_t *)&a_xInfoP->copyDate));
642 if(!a_xInfoP->backupDate)
643 fprintf(STDOUT," Backup Never\n");
645 fprintf(STDOUT," Backup %s",
646 ctime((time_t *)&a_xInfoP->backupDate));
647 if (a_xInfoP->accessDate)
648 fprintf(STDOUT," Last Access %s",
649 ctime((time_t *)&a_xInfoP->accessDate));
651 if (a_xInfoP->updateDate < a_xInfoP->creationDate)
652 fprintf(STDOUT, " Last Update %s",
653 ctime((time_t *)&a_xInfoP->creationDate));
655 fprintf(STDOUT, " Last Update %s",
656 ctime((time_t *)&a_xInfoP->updateDate));
657 fprintf(STDOUT, " %d accesses in the past day (i.e., vnode references)\n",
661 * Print all the read/write and authorship stats.
664 "\n Raw Read/Write Stats\n");
666 " |-------------------------------------------|\n");
668 " | Same Network | Diff Network |\n");
670 " |----------|----------|----------|----------|\n");
672 " | Total | Auth | Total | Auth |\n");
674 " |----------|----------|----------|----------|\n");
676 "Reads | %8d | %8d | %8d | %8d |\n",
677 a_xInfoP->stat_reads[VOLINT_STATS_SAME_NET],
678 a_xInfoP->stat_reads[VOLINT_STATS_SAME_NET_AUTH],
679 a_xInfoP->stat_reads[VOLINT_STATS_DIFF_NET],
680 a_xInfoP->stat_reads[VOLINT_STATS_DIFF_NET_AUTH]);
682 "Writes | %8d | %8d | %8d | %8d |\n",
683 a_xInfoP->stat_writes[VOLINT_STATS_SAME_NET],
684 a_xInfoP->stat_writes[VOLINT_STATS_SAME_NET_AUTH],
685 a_xInfoP->stat_writes[VOLINT_STATS_DIFF_NET],
686 a_xInfoP->stat_writes[VOLINT_STATS_DIFF_NET_AUTH]);
688 " |-------------------------------------------|\n\n");
691 " Writes Affecting Authorship\n");
693 " |-------------------------------------------|\n");
695 " | File Authorship | Directory Authorship|\n");
697 " |----------|----------|----------|----------|\n");
699 " | Same | Diff | Same | Diff |\n");
701 " |----------|----------|----------|----------|\n");
703 "0-60 sec | %8d | %8d | %8d | %8d |\n",
704 a_xInfoP->stat_fileSameAuthor[VOLINT_STATS_TIME_IDX_0],
705 a_xInfoP->stat_fileDiffAuthor[VOLINT_STATS_TIME_IDX_0],
706 a_xInfoP->stat_dirSameAuthor[VOLINT_STATS_TIME_IDX_0],
707 a_xInfoP->stat_dirDiffAuthor[VOLINT_STATS_TIME_IDX_0]);
709 "1-10 min | %8d | %8d | %8d | %8d |\n",
710 a_xInfoP->stat_fileSameAuthor[VOLINT_STATS_TIME_IDX_1],
711 a_xInfoP->stat_fileDiffAuthor[VOLINT_STATS_TIME_IDX_1],
712 a_xInfoP->stat_dirSameAuthor[VOLINT_STATS_TIME_IDX_1],
713 a_xInfoP->stat_dirDiffAuthor[VOLINT_STATS_TIME_IDX_1]);
715 "10min-1hr | %8d | %8d | %8d | %8d |\n",
716 a_xInfoP->stat_fileSameAuthor[VOLINT_STATS_TIME_IDX_2],
717 a_xInfoP->stat_fileDiffAuthor[VOLINT_STATS_TIME_IDX_2],
718 a_xInfoP->stat_dirSameAuthor[VOLINT_STATS_TIME_IDX_2],
719 a_xInfoP->stat_dirDiffAuthor[VOLINT_STATS_TIME_IDX_2]);
721 "1hr-1day | %8d | %8d | %8d | %8d |\n",
722 a_xInfoP->stat_fileSameAuthor[VOLINT_STATS_TIME_IDX_3],
723 a_xInfoP->stat_fileDiffAuthor[VOLINT_STATS_TIME_IDX_3],
724 a_xInfoP->stat_dirSameAuthor[VOLINT_STATS_TIME_IDX_3],
725 a_xInfoP->stat_dirDiffAuthor[VOLINT_STATS_TIME_IDX_3]);
727 "1day-1wk | %8d | %8d | %8d | %8d |\n",
728 a_xInfoP->stat_fileSameAuthor[VOLINT_STATS_TIME_IDX_4],
729 a_xInfoP->stat_fileDiffAuthor[VOLINT_STATS_TIME_IDX_4],
730 a_xInfoP->stat_dirSameAuthor[VOLINT_STATS_TIME_IDX_4],
731 a_xInfoP->stat_dirDiffAuthor[VOLINT_STATS_TIME_IDX_4]);
733 "> 1wk | %8d | %8d | %8d | %8d |\n",
734 a_xInfoP->stat_fileSameAuthor[VOLINT_STATS_TIME_IDX_5],
735 a_xInfoP->stat_fileDiffAuthor[VOLINT_STATS_TIME_IDX_5],
736 a_xInfoP->stat_dirSameAuthor[VOLINT_STATS_TIME_IDX_5],
737 a_xInfoP->stat_dirDiffAuthor[VOLINT_STATS_TIME_IDX_5]);
739 " |-------------------------------------------|\n");
740 } /*Volume status OK*/
742 if (a_xInfoP->status == VBUSY) {
744 qPut(&busyHead, a_xInfoP->volid);
746 fprintf(STDOUT, "**** Volume %u is busy ****\n",
751 qPut(¬okHead, a_xInfoP->volid);
753 fprintf(STDOUT, "**** Could not attach volume %u ****\n",
756 fprintf(STDOUT,"\n");
762 if (a_xInfoP->status == VOK) {
763 fprintf(STDOUT, "%-32s ", a_xInfoP->name);
764 fprintf(STDOUT, "%10u ", a_xInfoP->volid);
765 if (a_xInfoP->type == 0) fprintf(STDOUT, "RW ");
766 if (a_xInfoP->type == 1) fprintf(STDOUT, "RO ");
767 if (a_xInfoP->type == 2) fprintf(STDOUT, "BK ");
768 fprintf(STDOUT, "%10d K ", a_xInfoP->size);
769 if(a_xInfoP->inUse == 1) {
770 fprintf(STDOUT, "On-line");
773 fprintf(STDOUT, "Off-line");
776 fprintf(STDOUT, "\n");
779 if (a_xInfoP->status == VBUSY) {
781 qPut(&busyHead, a_xInfoP->volid);
783 fprintf(STDOUT,"**** Volume %u is busy ****\n",
788 qPut(¬okHead, a_xInfoP->volid);
790 fprintf(STDOUT,"**** Could not attach volume %u ****\n",
793 } /*Default listing*/
796 #ifdef FULL_LISTVOL_SWITCH
797 static void DisplayFormat2(server, partition, pntr)
798 long server, partition;
801 static long server_cache = -1, partition_cache = -1;
802 static char hostname[256],
806 if (server != server_cache) {
810 strcpy(hostname, hostutil_GetNameByINet(server));
811 strcpy(address, inet_ntoa(s));
812 server_cache = server;
814 if (partition != partition_cache) {
815 MapPartIdIntoName(partition, pname);
816 partition_cache = partition;
818 fprintf(STDOUT, "name\t\t%s\n", pntr->name);
819 fprintf(STDOUT, "id\t\t%lu\n", pntr->volid);
820 fprintf(STDOUT, "serv\t\t%s\t%s\n", address, hostname);
821 fprintf(STDOUT, "part\t\t%s\n", pname);
822 switch (pntr->status) {
824 fprintf(STDOUT, "status\t\tOK\n");
827 fprintf(STDOUT, "status\t\tBUSY\n");
830 fprintf(STDOUT, "status\t\tUNATTACHABLE\n");
833 fprintf(STDOUT, "backupID\t%lu\n", pntr->backupID);
834 fprintf(STDOUT, "parentID\t%lu\n", pntr->parentID);
835 fprintf(STDOUT, "cloneID\t\t%lu\n", pntr->cloneID);
836 fprintf(STDOUT, "inUse\t\t%s\n", pntr->inUse ? "Y" : "N");
837 fprintf(STDOUT, "needsSalvaged\t%s\n", pntr->needsSalvaged ? "Y" : "N");
838 /* 0xD3 is from afs/volume.h since I had trouble including the file */
839 fprintf(STDOUT, "destroyMe\t%s\n", pntr->destroyMe == 0xD3 ? "Y" : "N");
840 switch (pntr->type) {
842 fprintf(STDOUT, "type\t\tRW\n");
845 fprintf(STDOUT, "type\t\tRO\n");
848 fprintf(STDOUT, "type\t\tBK\n");
851 fprintf(STDOUT, "type\t\t?\n");
854 fprintf(STDOUT, "creationDate\t%-9lu\t%s", pntr->creationDate, ctime(&pntr->creationDate));
855 fprintf(STDOUT, "accessDate\t%-9lu\t%s", pntr->accessDate, ctime(&pntr->accessDate));
856 fprintf(STDOUT, "updateDate\t%-9lu\t%s", pntr->updateDate, ctime(&pntr->updateDate));
857 fprintf(STDOUT, "backupDate\t%-9lu\t%s", pntr->backupDate, ctime(&pntr->backupDate));
858 fprintf(STDOUT, "copyDate\t%-9lu\t%s", pntr->copyDate, ctime(&pntr->copyDate));
859 fprintf(STDOUT, "flags\t\t%#lx\t(Optional)\n", pntr->flags);
860 fprintf(STDOUT, "diskused\t%u\n", pntr->size);
861 fprintf(STDOUT, "maxquota\t%u\n", pntr->maxquota);
862 fprintf(STDOUT, "minquota\t%lu\t(Optional)\n", pntr->spare0);
863 fprintf(STDOUT, "filecount\t%u\n", pntr->filecount);
864 fprintf(STDOUT, "dayUse\t\t%u\n", pntr->dayUse);
865 fprintf(STDOUT, "weekUse\t\t%lu\t(Optional)\n", pntr->spare1);
866 fprintf(STDOUT, "spare2\t\t%lu\t(Optional)\n", pntr->spare2);
867 fprintf(STDOUT, "spare3\t\t%lu\t(Optional)\n", pntr->spare3);
871 static void DisplayVolumes2(server, partition, pntr, count)
873 long server, partition, count;
877 for (i = 0; i < count; i++) {
878 fprintf(STDOUT, "BEGIN_OF_ENTRY\n");
879 DisplayFormat2(server, partition, pntr);
880 fprintf(STDOUT, "END_OF_ENTRY\n\n");
885 #endif /* FULL_LISTVOL_SWITCH */
887 static void DisplayVolumes(server,part,pntr,count,longlist,fast,quiet)
888 afs_int32 server,part;
890 afs_int32 count,longlist,fast;
893 int totalOK,totalNotOK,totalBusy, i;
901 for(i = 0; i < count; i++){
902 DisplayFormat(pntr,server,part,&totalOK,&totalNotOK,&totalBusy,fast,longlist,0);
906 while(busyHead.count){
907 qGet(&busyHead,&volid);
908 fprintf(STDOUT,"**** Volume %u is busy ****\n",volid);
912 while(notokHead.count){
913 qGet(¬okHead,&volid);
914 fprintf(STDOUT,"**** Could not attach volume %u ****\n",volid);
918 fprintf(STDOUT,"\n");
920 fprintf(STDOUT,"Total volumes onLine %d ; Total volumes offLine %d ; Total busy %d\n\n",totalOK,totalNotOK,totalBusy);
925 /*------------------------------------------------------------------------
926 * PRIVATE XDisplayVolumes
929 * Display extended volume information.
932 * a_servID : Pointer to the Rx call we're performing.
933 * a_partID : Partition for which we want the extended list.
934 * a_xInfoP : Ptr to extended volume info.
935 * a_count : Number of volume records contained above.
936 * a_int32 : Int32 listing generated?
937 * a_fast : Fast listing generated?
938 * a_quiet : Quiet listing generated?
944 * Nothing interesting.
948 *------------------------------------------------------------------------*/
950 static void XDisplayVolumes(a_servID, a_partID, a_xInfoP,
951 a_count, a_int32, a_fast, a_quiet)
954 volintXInfo *a_xInfoP;
960 { /*XDisplayVolumes*/
962 int totalOK; /*Total OK volumes*/
963 int totalNotOK; /*Total screwed volumes*/
964 int totalBusy; /*Total busy volumes*/
965 int i; /*Loop variable*/
966 afs_int32 volid; /*Current volume ID*/
969 * Initialize counters and (global!!) queues.
978 * Display each volume in the list.
980 for(i = 0; i < a_count; i++) {
981 XDisplayFormat(a_xInfoP,
994 * If any volumes were found to be busy or screwed, display them.
997 while (busyHead.count) {
998 qGet(&busyHead, &volid);
999 fprintf(STDOUT, "**** Volume %u is busy ****\n", volid);
1003 while (notokHead.count) {
1004 qGet(¬okHead, &volid);
1005 fprintf(STDOUT, "**** Could not attach volume %u ****\n", volid);
1010 fprintf(STDOUT, "\n");
1013 "Total volumes: %d on-line, %d off-line, %d busyd\n\n",
1014 totalOK, totalNotOK, totalBusy);
1018 } /*XDisplayVolumes*/
1020 /* set <server> and <part> to the correct values depending on
1021 * <voltype> and <entry> */
1022 static void GetServerAndPart (entry, voltype, server, part, previdx)
1023 struct nvldbentry *entry;
1024 afs_int32 *server,*part;
1028 int i, istart, vtype;
1033 /* Doesn't check for non-existance of backup volume */
1034 if ((voltype == RWVOL) || (voltype == BACKVOL)) {
1036 istart = 0; /* seach the entire entry */
1039 /* Seach from beginning of entry or pick up where we left off */
1040 istart = ((*previdx < 0) ? 0 : *previdx+1);
1043 for (i = istart; i < entry->nServers; i++) {
1044 if (entry->serverFlags[i] & vtype) {
1045 *server = entry->serverNumber[i];
1046 *part = entry->serverPartition[i];
1052 /* Didn't find any, return -1 */
1057 static void PostVolumeStats(entry)
1058 struct nvldbentry *entry;
1060 SubEnumerateEntry(entry);
1061 /* Check for VLOP_ALLOPERS */
1062 if (entry->flags & VLOP_ALLOPERS)
1063 fprintf(STDOUT," Volume is currently LOCKED \n");
1067 /*------------------------------------------------------------------------
1068 * PRIVATE XVolumeStats
1071 * Display extended volume information.
1074 * a_xInfoP : Ptr to extended volume info.
1075 * a_entryP : Ptr to the volume's VLDB entry.
1076 * a_srvID : Server ID.
1077 * a_partID : Partition ID.
1078 * a_volType : Type of volume to print.
1084 * Nothing interesting.
1088 *------------------------------------------------------------------------*/
1090 static void XVolumeStats(a_xInfoP, a_entryP, a_srvID, a_partID, a_volType)
1091 volintXInfo *a_xInfoP;
1092 struct nvldbentry *a_entryP;
1099 int totalOK, totalNotOK, totalBusy; /*Dummies - we don't really count here*/
1101 XDisplayFormat(a_xInfoP, /*Ptr to extended volume info*/
1102 a_srvID, /*Server ID to print*/
1103 a_partID, /*Partition ID to print*/
1104 &totalOK, /*Ptr to total-OK counter*/
1105 &totalNotOK, /*Ptr to total-screwed counter*/
1106 &totalBusy, /*Ptr to total-busy counter*/
1107 0, /*Don't do a fast listing*/
1108 1, /*Do a long listing*/
1109 1); /*Show volume problems*/
1114 static void VolumeStats(pntr,entry,server,part,voltype)
1116 struct nvldbentry *entry;
1118 afs_int32 server,part;
1120 int totalOK,totalNotOK,totalBusy;
1121 afs_int32 vcode,vcode2;
1123 DisplayFormat(pntr,server,part,&totalOK,&totalNotOK,&totalBusy,0,1,1);
1127 /* command to forcibly remove a volume */
1128 static NukeVolume(as)
1129 register struct cmd_syndesc *as; {
1130 register afs_int32 code;
1131 afs_int32 volID, err;
1136 server = GetServer(tp = as->parms[0].items->data);
1138 fprintf(STDERR,"vos: server '%s' not found in host table\n", tp);
1142 partID = volutil_GetPartitionID(tp = as->parms[1].items->data);
1144 fprintf(STDERR, "vos: could not parse '%s' as a partition name", tp);
1148 volID = vsu_GetVolumeID(tp = as->parms[2].items->data, cstruct, &err);
1150 if (err) PrintError("", err);
1151 else fprintf(STDERR, "vos: could not parse '%s' as a numeric volume ID", tp);
1155 fprintf(STDOUT, "vos: forcibly removing all traces of volume %d, please wait...", volID);
1157 code = UV_NukeVolume(server, partID, volID);
1159 fprintf(STDOUT, "done.\n");
1161 fprintf(STDOUT, "failed with code %d.\n", code);
1166 /*------------------------------------------------------------------------
1167 * PRIVATE ExamineVolume
1170 * Routine used to examine a single volume, contacting the VLDB as
1171 * well as the Volume Server.
1174 * as : Ptr to parsed command line arguments.
1177 * 0 for a successful operation,
1178 * Otherwise, one of the ubik or VolServer error values.
1181 * Nothing interesting.
1185 *------------------------------------------------------------------------
1187 static ExamineVolume(as)
1188 register struct cmd_syndesc *as;
1190 struct nvldbentry entry;
1191 afs_int32 vcode = 0;
1192 volintInfo *pntr = (volintInfo *)0;
1193 volintXInfo *xInfoP = (volintXInfo *)0;
1195 afs_int32 code, err, error = 0;
1196 int voltype, foundserv = 0, foundentry = 0;
1197 afs_int32 aserver, apart;
1199 int wantExtendedInfo; /*Do we want extended vol info?*/
1201 wantExtendedInfo = (as->parms[1].items ? 1 : 0); /* -extended */
1203 volid = vsu_GetVolumeID(as->parms[0].items->data, cstruct, &err); /* -id */
1205 if (err) PrintError("", err);
1206 else fprintf(STDERR, "Unknown volume ID or name '%s'\n", as->parms[0].items->data);
1211 fprintf(STDOUT, "Fetching VLDB entry for %u .. ", volid);
1214 vcode = VLDB_GetEntryByID (volid, -1, &entry);
1216 fprintf(STDERR, "Could not fetch the entry for volume number %u from VLDB \n",volid);
1220 fprintf(STDOUT, "done\n");
1221 MapHostToNetwork(&entry);
1223 if (entry.volumeId[RWVOL] == volid)
1225 else if (entry.volumeId[BACKVOL] == volid)
1227 else /* (entry.volumeId[ROVOL] == volid) */
1230 do { /* do {...} while (voltype == ROVOL) */
1231 /* Get the entry for the volume. If its a RW vol, get the RW entry.
1232 * It its a BK vol, get the RW entry (even if VLDB may say the BK doen't exist).
1233 * If its a RO vol, get the next RO entry.
1235 GetServerAndPart(&entry, ((voltype == ROVOL) ? ROVOL : RWVOL), &aserver, &apart, &previdx);
1236 if (previdx == -1) { /* searched all entries */
1238 fprintf(STDERR,"Volume %s does not exist in VLDB\n\n", as->parms[0].items->data);
1245 /* Get information about the volume from the server */
1247 fprintf(STDOUT,"Getting volume listing from the server %s .. ",
1248 hostutil_GetNameByINet(aserver));
1251 if (wantExtendedInfo)
1252 code = UV_XListOneVolume(aserver, apart, volid, &xInfoP);
1254 code = UV_ListOneVolume(aserver, apart, volid, &pntr);
1256 fprintf(STDOUT,"done\n");
1260 if (code == ENODEV) {
1261 if ((voltype == BACKVOL) && !(entry.flags & BACK_EXISTS)) {
1262 /* The VLDB says there is no backup volume and its not on disk */
1263 fprintf(STDERR, "Volume %s does not exist\n", as->parms[0].items->data);
1266 fprintf(STDERR, "Volume does not exist on server %s as indicated by the VLDB\n",
1267 hostutil_GetNameByINet(aserver));
1270 PrintDiagnostics("examine", code);
1272 fprintf(STDOUT, "\n");
1275 if (wantExtendedInfo)
1276 XVolumeStats(xInfoP, &entry, aserver, apart, voltype);
1278 #ifdef FULL_LISTVOL_SWITCH
1279 if (as->parms[2].items) {
1280 DisplayFormat2(aserver, apart, pntr);
1281 EnumerateEntry(&entry);
1283 #endif /* FULL_LISTVOL_SWITCH */
1284 VolumeStats(pntr, &entry, aserver, apart, voltype);
1286 if ((voltype == BACKVOL) && !(entry.flags & BACK_EXISTS)) {
1287 /* The VLDB says there is no backup volume yet we found one on disk */
1288 fprintf(STDERR, "Volume %s does not exist in VLDB\n", as->parms[0].items->data);
1293 if (pntr) free(pntr);
1294 if (xInfoP) free(xInfoP);
1295 } while (voltype == ROVOL);
1298 fprintf(STDERR,"Dump only information from VLDB\n\n");
1299 fprintf(STDOUT,"%s \n", entry.name); /* PostVolumeStats doesn't print name */
1301 PostVolumeStats(&entry);
1306 /*------------------------------------------------------------------------
1310 * Routine used to change the status of a single volume.
1313 * as : Ptr to parsed command line arguments.
1316 * 0 for a successful operation,
1317 * Otherwise, one of the ubik or VolServer error values.
1320 * Nothing interesting.
1324 *------------------------------------------------------------------------
1326 static SetFields(as)
1327 register struct cmd_syndesc *as;
1329 struct nvldbentry entry;
1330 afs_int32 vcode = 0;
1333 afs_int32 code, err;
1334 afs_int32 aserver, apart;
1337 volid = vsu_GetVolumeID(as->parms[0].items->data, cstruct, &err); /* -id */
1339 if (err) PrintError("", err);
1340 else fprintf(STDERR, "Unknown volume ID or name '%s'\n", as->parms[0].items->data);
1344 code = VLDB_GetEntryByID (volid, RWVOL, &entry);
1346 fprintf(STDERR, "Could not fetch the entry for volume number %u from VLDB \n",volid);
1349 MapHostToNetwork(&entry);
1351 GetServerAndPart(&entry, RWVOL, &aserver, &apart, &previdx);
1352 if (previdx == -1) {
1353 fprintf(STDERR,"Volume %s does not exist in VLDB\n\n", as->parms[0].items->data);
1357 memset(&info, 0, sizeof(info));
1368 if (as->parms[1].items) {
1370 code = util_GetInt32(as->parms[1].items->data, &info.maxquota);
1372 fprintf(STDERR,"invalid quota value\n");
1376 if (as->parms[2].items) {
1380 code = UV_SetVolumeInfo(aserver, apart, volid, &info);
1382 fprintf(STDERR,"Could not update volume info fields for volume number %u\n",volid);
1386 /*------------------------------------------------------------------------
1390 * Brings a volume online.
1393 * as : Ptr to parsed command line arguments.
1396 * 0 for a successful operation,
1399 * Nothing interesting.
1403 *------------------------------------------------------------------------
1405 static volOnline(as)
1406 register struct cmd_syndesc *as;
1408 afs_int32 server, partition, volid;
1409 afs_int32 code, err=0;
1411 server = GetServer(as->parms[0].items->data);
1413 fprintf(STDERR,"vos: server '%s' not found in host table\n", as->parms[0].items->data);
1417 partition = volutil_GetPartitionID(as->parms[1].items->data);
1418 if (partition < 0) {
1419 fprintf(STDERR,"vos: could not interpret partition name '%s'\n", as->parms[1].items->data);
1423 volid = vsu_GetVolumeID(as->parms[2].items->data, cstruct, &err); /* -id */
1425 if (err) PrintError("", err);
1426 else fprintf(STDERR, "Unknown volume ID or name '%s'\n", as->parms[0].items->data);
1430 code = UV_SetVolume(server, partition, volid, ITOffline, 0/*online*/, 0/*sleep*/);
1432 fprintf(STDERR, "Failed to set volume. Code = %d\n", code);
1439 /*------------------------------------------------------------------------
1440 * PRIVATE volOffline
1443 * Brings a volume offline.
1446 * as : Ptr to parsed command line arguments.
1449 * 0 for a successful operation,
1452 * Nothing interesting.
1456 *------------------------------------------------------------------------
1458 static volOffline(as)
1459 register struct cmd_syndesc *as;
1461 afs_int32 server, partition, volid;
1462 afs_int32 code, err=0;
1463 afs_int32 transflag, sleeptime, transdone;
1465 server = GetServer(as->parms[0].items->data);
1467 fprintf(STDERR,"vos: server '%s' not found in host table\n", as->parms[0].items->data);
1471 partition = volutil_GetPartitionID(as->parms[1].items->data);
1472 if (partition < 0) {
1473 fprintf(STDERR,"vos: could not interpret partition name '%s'\n", as->parms[1].items->data);
1477 volid = vsu_GetVolumeID(as->parms[2].items->data, cstruct, &err); /* -id */
1479 if (err) PrintError("", err);
1480 else fprintf(STDERR, "Unknown volume ID or name '%s'\n", as->parms[0].items->data);
1484 transflag = (as->parms[4].items ? ITBusy : ITOffline);
1485 sleeptime = (as->parms[3].items ? atol(as->parms[3].items->data) : 0);
1486 transdone = (sleeptime ? 0/*online*/ : VTOutOfService);
1487 if (as->parms[4].items && !as->parms[3].items) {
1488 fprintf(STDERR,"-sleep option must be used with -busy flag\n");
1492 code = UV_SetVolume(server, partition, volid, transflag, transdone, sleeptime);
1494 fprintf(STDERR, "Failed to set volume. Code = %d\n", code);
1501 static CreateVolume(as)
1502 register struct cmd_syndesc *as;
1506 afs_int32 volid,code;
1507 struct nvldbentry entry;
1512 tserver = GetServer(as->parms[0].items->data);
1514 fprintf(STDERR,"vos: host '%s' not found in host table\n",as->parms[0].items->data );
1517 pname = volutil_GetPartitionID(as->parms[1].items->data);
1519 fprintf(STDERR,"vos: could not interpret partition name '%s'\n",as->parms[1].items->data );
1522 if (!IsPartValid(pname,tserver,&code)){/*check for validity of the partition */
1523 if(code) PrintError("",code);
1524 else fprintf(STDERR,"vos : partition %s does not exist on the server\n",as->parms[1].items->data);
1527 if(!ISNAMEVALID(as->parms[2].items->data)) {
1528 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);
1531 if(!VolNameOK(as->parms[2].items->data)){
1532 fprintf(STDERR,"Illegal volume name %s, should not end in .readonly or .backup\n",as->parms[2].items->data);
1535 if(IsNumeric(as->parms[2].items->data)){
1536 fprintf(STDERR,"Illegal volume name %s, should not be a number\n",as->parms[2].items->data);
1539 vcode = VLDB_GetEntryByName(as->parms[2].items->data, &entry);
1541 fprintf(STDERR,"Volume %s already exists\n",as->parms[2].items->data);
1542 PrintDiagnostics("create", code);
1546 if (as->parms[3].items) {
1547 if (!IsNumeric(as->parms[3].items->data)){
1548 fprintf(STDERR,"Initial quota %s should be numeric.\n", as->parms[3].items->data);
1552 code = util_GetInt32(as->parms[3].items->data, "a);
1554 fprintf(STDERR,"vos: bad integer specified for quota.\n");
1559 code = UV_CreateVolume2(tserver, pname,as->parms[2].items->data,
1560 quota, 0, 0, 0, 0, &volid);
1562 PrintDiagnostics("create", code);
1565 MapPartIdIntoName(pname, part);
1566 fprintf(STDOUT,"Volume %u created on partition %s of %s\n", volid, part,as->parms[0].items->data );
1571 static afs_int32 DeleteAll(entry)
1572 struct nvldbentry *entry;
1575 afs_int32 error, code, curserver, curpart, volid;
1577 MapHostToNetwork(entry);
1579 for(i=0; i < entry->nServers; i++){
1580 curserver = entry->serverNumber[i];
1581 curpart = entry->serverPartition[i];
1582 if(entry->serverFlags[i] & ITSROVOL){
1583 volid = entry->volumeId[ROVOL];
1586 volid = entry->volumeId[RWVOL];
1588 code = UV_DeleteVolume(curserver,curpart,volid);
1595 static DeleteVolume(as)
1596 struct cmd_syndesc *as;
1598 afs_int32 err, code = 0;
1599 afs_int32 server = 0, partition = -1, volid;
1603 if (as->parms[0].items) {
1604 server = GetServer(as->parms[0].items->data);
1606 fprintf(STDERR,"vos: server '%s' not found in host table\n",
1607 as->parms[0].items->data);
1612 if (as->parms[1].items) {
1613 partition = volutil_GetPartitionID(as->parms[1].items->data);
1614 if (partition < 0) {
1615 fprintf(STDERR,"vos: could not interpret partition name '%s'\n",
1616 as->parms[1].items->data );
1620 /* Check for validity of the partition */
1621 if (!IsPartValid(partition, server, &code)) {
1623 PrintError("", code);
1625 fprintf(STDERR,"vos : partition %s does not exist on the server\n",
1626 as->parms[1].items->data);
1632 volid = vsu_GetVolumeID(as->parms[2].items->data, cstruct, &err);
1634 fprintf(STDERR, "Can't find volume name '%s' in VLDB\n",
1635 as->parms[2].items->data);
1636 if (err) PrintError("", err);
1640 /* If the server or partition option are not complete, try to fill
1641 * them in from the VLDB entry.
1643 if ((partition == -1) || !server) {
1644 struct nvldbentry entry;
1646 code = VLDB_GetEntryByID(volid, -1, &entry);
1648 fprintf(STDERR,"Could not fetch the entry for volume %u from VLDB\n",
1650 PrintError("",code);
1654 if (((volid == entry.volumeId[RWVOL]) && (entry.flags & RW_EXISTS)) ||
1655 ((volid == entry.volumeId[BACKVOL]) && (entry.flags & BACK_EXISTS)) ) {
1656 idx = Lp_GetRwIndex(&entry);
1658 (server && (server != entry.serverNumber[idx])) ||
1659 ((partition != -1) && (partition != entry.serverPartition[idx])) ) {
1660 fprintf(STDERR,"VLDB: Volume '%s' no match\n", as->parms[2].items->data);
1664 else if ((volid == entry.volumeId[ROVOL]) && (entry.flags & RO_EXISTS)) {
1665 for (idx=-1,j=0; j<entry.nServers; j++) {
1666 if (entry.serverFlags[j] != ITSROVOL) continue;
1668 if ( ((server == 0) || (server == entry.serverNumber[j])) &&
1669 ((partition == -1) || (partition == entry.serverPartition[j])) ) {
1671 fprintf(STDERR,"VLDB: Volume '%s' matches more than one RO\n",
1672 as->parms[2].items->data);
1679 fprintf(STDERR,"VLDB: Volume '%s' no match\n", as->parms[2].items->data);
1684 fprintf(STDERR,"VLDB: Volume '%s' no match\n", as->parms[2].items->data);
1688 server = htonl(entry.serverNumber[idx]);
1689 partition = entry.serverPartition[idx];
1693 code = UV_DeleteVolume(server, partition, volid);
1695 PrintDiagnostics("remove", code);
1699 MapPartIdIntoName(partition, pname);
1700 fprintf(STDOUT,"Volume %u on partition %s server %s deleted\n",
1701 volid, pname, hostutil_GetNameByINet(server));
1705 #define TESTM 0 /* set for move space tests, clear for production */
1706 static MoveVolume(as)
1707 register struct cmd_syndesc *as;
1710 afs_int32 volid, fromserver, toserver, frompart, topart,code, err;
1711 char fromPartName[10], toPartName[10];
1713 struct diskPartition partition; /* for space check */
1716 volid = vsu_GetVolumeID(as->parms[0].items->data, cstruct, &err);
1718 if (err) PrintError("", err);
1719 else fprintf(STDERR, "vos: can't find volume ID or name '%s'\n",
1720 as->parms[0].items->data);
1723 fromserver = GetServer(as->parms[1].items->data);
1724 if (fromserver == 0) {
1725 fprintf(STDERR,"vos: server '%s' not found in host table\n", as->parms[1].items->data);
1728 toserver = GetServer(as->parms[3].items->data);
1729 if (toserver == 0) {
1730 fprintf(STDERR,"vos: server '%s' not found in host table\n", as->parms[3].items->data);
1733 frompart = volutil_GetPartitionID(as->parms[2].items->data);
1735 fprintf(STDERR,"vos: could not interpret partition name '%s'\n", as->parms[2].items->data);
1738 if (!IsPartValid(frompart,fromserver,&code)){/*check for validity of the partition */
1739 if(code) PrintError("",code);
1740 else fprintf(STDERR,"vos : partition %s does not exist on the server\n",as->parms[2].items->data);
1743 topart = volutil_GetPartitionID(as->parms[4].items->data);
1745 fprintf(STDERR,"vos: could not interpret partition name '%s'\n",as->parms[4].items->data);
1748 if (!IsPartValid(topart,toserver,&code)){/*check for validity of the partition */
1749 if(code) PrintError("",code);
1750 else fprintf(STDERR,"vos : partition %s does not exist on the server\n",as->parms[4].items->data);
1755 check source partition for space to clone volume
1758 MapPartIdIntoName(topart,toPartName);
1759 MapPartIdIntoName(frompart, fromPartName);
1762 check target partition for space to move volume
1765 code=UV_PartitionInfo(toserver,toPartName,&partition);
1768 fprintf(STDERR,"vos: cannot access partition %s\n",toPartName);
1772 fprintf(STDOUT,"target partition %s free space %d\n",
1773 toPartName,partition.free);
1776 code=UV_ListOneVolume(fromserver,frompart,volid,&p);
1779 fprintf(STDERR,"vos:cannot access volume %u\n",volid);
1784 fprintf(STDOUT,"volume %u size %d\n",volid,p->size);
1785 if(partition.free<=p->size)
1787 fprintf(STDERR,"vos: no space on target partition %s to move volume %u\n",
1796 fprintf(STDOUT,"size test - don't do move\n");
1800 /* successful move still not guaranteed but shoot for it */
1802 code = UV_MoveVolume(volid, fromserver, frompart, toserver, topart);
1804 PrintDiagnostics("move", code);
1807 MapPartIdIntoName(topart,toPartName);
1808 MapPartIdIntoName(frompart, fromPartName);
1809 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);
1813 static BackupVolume(as)
1814 register struct cmd_syndesc *as;
1816 afs_int32 avolid, aserver, apart,vtype,code, err;
1817 struct nvldbentry entry;
1819 afs_int32 buvolid,buserver,bupart,butype;
1820 struct nvldbentry buentry;
1821 struct rx_connection *conn;
1823 struct nvldbentry store;
1825 avolid = vsu_GetVolumeID(as->parms[0].items->data, cstruct, &err);
1827 if (err) PrintError("", err);
1828 else fprintf(STDERR, "vos: can't find volume ID or name '%s'\n",
1829 as->parms[0].items->data);
1832 code = GetVolumeInfo( avolid,&aserver, &apart,&vtype,&entry);
1835 /* verify this is a readwrite volume */
1839 fprintf(STDERR,"%s not RW volume\n",as->parms[0].items->data);
1843 /* is there a backup volume already? */
1845 if(entry.flags & BACK_EXISTS)
1847 /* yep, where is it? */
1849 buvolid=entry.volumeId[BACKVOL];
1850 code=GetVolumeInfo(buvolid,&buserver,&bupart,&butype,&buentry);
1854 code = VLDB_IsSameAddrs(buserver, aserver, &err);
1856 fprintf(STDERR,"Failed to get info about server's %d address(es) from vlserver; aborting call!\n", buserver);
1861 fprintf(STDERR,"FATAL ERROR: backup volume %u exists on server %u\n",
1867 /* nope, carry on */
1869 code = UV_BackupVolume(aserver, apart, avolid);
1872 PrintDiagnostics("backup", code);
1875 fprintf(STDOUT,"Created backup volume for %s \n",as->parms[0].items->data);
1878 static ReleaseVolume(as)
1879 register struct cmd_syndesc *as;
1882 struct nvldbentry entry;
1883 afs_int32 avolid, aserver, apart,vtype,code, err;
1886 if(as->parms[1].items) force = 1;
1887 avolid = vsu_GetVolumeID(as->parms[0].items->data, cstruct, &err);
1889 if (err) PrintError("", err);
1890 else fprintf(STDERR, "vos: can't find volume '%s'\n", as->parms[0].items->data);
1893 code = GetVolumeInfo( avolid,&aserver, &apart,&vtype,&entry);
1894 if(code) return code;
1896 if (vtype != RWVOL) {
1897 fprintf(STDERR,"%s not a RW volume\n", as->parms[0].items->data);
1901 if(!ISNAMEVALID(entry.name)){
1902 fprintf(STDERR,"Volume name %s is too long, rename before releasing\n",entry.name);
1906 code = UV_ReleaseVolume(avolid, aserver, apart, force);
1908 PrintDiagnostics("release", code);
1911 fprintf(STDOUT,"Released volume %s successfully\n",as->parms[0].items->data );
1914 static DumpVolume(as)
1915 register struct cmd_syndesc *as;
1918 afs_int32 avolid, aserver, apart,voltype,fromdate=0,code, err, i;
1919 char filename[NameLen];
1920 struct nvldbentry entry;
1922 rx_SetRxDeadTime(60 * 10);
1923 for (i = 0; i<MAXSERVERS; i++) {
1924 struct rx_connection *rxConn = ubik_GetRPCConn(cstruct,i);
1925 if (rxConn == 0) break;
1926 rx_SetConnDeadTime(rxConn, rx_connDeadTime);
1927 if (rxConn->service) rxConn->service->connDeadTime = rx_connDeadTime;
1930 avolid = vsu_GetVolumeID(as->parms[0].items->data, cstruct, &err);
1932 if (err) PrintError("", err);
1933 else fprintf(STDERR, "vos: can't find volume '%s'\n", as->parms[0].items->data);
1937 if (as->parms[3].items || as->parms[4].items) {
1938 if (!as->parms[3].items || !as->parms[4].items) {
1939 fprintf(STDERR, "Must specify both -server and -partition options\n");
1942 aserver = GetServer(as->parms[3].items->data);
1944 fprintf(STDERR, "Invalid server name\n");
1947 apart = volutil_GetPartitionID(as->parms[4].items->data);
1949 fprintf(STDERR, "Invalid partition name\n");
1953 code = GetVolumeInfo(avolid, &aserver, &apart, &voltype, &entry);
1954 if (code) return code;
1957 if (as->parms[1].items && strcmp(as->parms[1].items->data,"0")) {
1958 code = ktime_DateToInt32(as->parms[1].items->data, &fromdate);
1960 fprintf(STDERR,"vos: failed to parse date '%s' (error=%d))\n",
1961 as->parms[1].items->data, code);
1965 if(as->parms[2].items){
1966 strcpy(filename,as->parms[2].items->data);
1969 strcpy(filename,"");
1971 code = UV_DumpVolume(avolid, aserver, apart, fromdate, DumpFunction, filename);
1973 PrintDiagnostics("dump", code);
1976 if(strcmp(filename,""))
1977 fprintf(STDERR,"Dumped volume %s in file %s\n",as->parms[0].items->data, filename);
1979 fprintf(STDERR,"Dumped volume %s in stdout \n",as->parms[0].items->data);
1988 static RestoreVolume(as)
1989 register struct cmd_syndesc *as;
1992 afs_int32 avolid, aserver, apart, code,vcode, err;
1993 afs_int32 aoverwrite = ASK;
1994 int restoreflags, readonly = 0, offline = 0, voltype = RWVOL;
1996 char afilename[NameLen], avolname[VOLSER_MAXVOLNAME +1],apartName[10];
1997 char volname[VOLSER_MAXVOLNAME +1];
1998 struct nvldbentry entry;
2002 if(as->parms[4].items){
2003 avolid = vsu_GetVolumeID(as->parms[4].items->data, cstruct, &err);
2005 if (err) PrintError("", err);
2006 else fprintf(STDERR, "vos: can't find volume '%s'\n", as->parms[4].items->data);
2013 if (as->parms[5].items) {
2014 if ( (strcmp(as->parms[5].items->data, "a") == 0) ||
2015 (strcmp(as->parms[5].items->data, "abort") == 0) ) {
2018 else if ( (strcmp(as->parms[5].items->data, "f") == 0) ||
2019 (strcmp(as->parms[5].items->data, "full") == 0) ) {
2022 else if ( (strcmp(as->parms[5].items->data, "i") == 0) ||
2023 (strcmp(as->parms[5].items->data, "inc") == 0) ||
2024 (strcmp(as->parms[5].items->data, "increment") == 0) ||
2025 (strcmp(as->parms[5].items->data, "incremental") == 0) ) {
2029 fprintf(STDERR, "vos: %s is not a valid argument to -overwrite\n",
2030 as->parms[5].items->data);
2034 if (as->parms[6].items) offline = 1;
2035 if (as->parms[7].items) {
2040 aserver = GetServer(as->parms[0].items->data);
2042 fprintf(STDERR,"vos: server '%s' not found in host table\n", as->parms[0].items->data);
2045 apart = volutil_GetPartitionID(as->parms[1].items->data);
2047 fprintf(STDERR,"vos: could not interpret partition name '%s'\n",as->parms[1].items->data );
2050 if (!IsPartValid(apart,aserver,&code)){/*check for validity of the partition */
2051 if(code) PrintError("",code);
2052 else fprintf(STDERR,"vos : partition %s does not exist on the server\n",as->parms[1].items->data);
2055 strcpy(avolname,as->parms[2].items->data );
2056 if(!ISNAMEVALID(avolname)) {
2057 fprintf(STDERR,"vos: the name of the volume %s exceeds the size limit\n",avolname);
2060 if(!VolNameOK(avolname)){
2061 fprintf(STDERR,"Illegal volume name %s, should not end in .readonly or .backup\n",avolname);
2064 if(as->parms[3].items){
2065 strcpy(afilename,as->parms[3].items->data );
2066 if(!FileExists(afilename)){
2067 fprintf(STDERR,"Can't access file %s\n",afilename);
2072 strcpy(afilename,"");
2075 /* Check if volume exists or not */
2077 vsu_ExtractName(volname,avolname);
2078 vcode = VLDB_GetEntryByName(volname, &entry);
2079 if (vcode) { /* no volume - do a full restore */
2080 restoreflags = RV_FULLRST;
2081 if ( (aoverwrite == INC) || (aoverwrite == ABORT) )
2082 fprintf(STDERR,"Volume does not exist; Will perform a full restore\n");
2085 else if ((!readonly && Lp_GetRwIndex(&entry) == -1) /* RW volume does not exist - do a full */
2086 || (readonly && !Lp_ROMatch(0, 0, &entry))) { /* RO volume does not exist - do a full */
2087 restoreflags = RV_FULLRST;
2088 if ( (aoverwrite == INC) || (aoverwrite == ABORT) )
2089 fprintf(STDERR,"%s Volume does not exist; Will perform a full restore\n",
2090 readonly ? "RO" : "RW");
2093 avolid = entry.volumeId[voltype];
2095 else if (entry.volumeId[voltype] != 0 && entry.volumeId[voltype] != avolid) {
2096 avolid = entry.volumeId[voltype];
2100 else { /* volume exists - do we do a full incremental or abort */
2101 int Oserver, Opart, Otype, vol_elsewhere = 0;
2102 struct nvldbentry Oentry;
2106 avolid = entry.volumeId[voltype];
2108 else if(entry.volumeId[voltype] != 0 && entry.volumeId[voltype] != avolid) {
2109 avolid = entry.volumeId[voltype];
2112 /* A file name was specified - check if volume is on another partition */
2113 vcode = GetVolumeInfo(avolid, &Oserver, &Opart, &Otype, &Oentry);
2116 vcode = VLDB_IsSameAddrs(Oserver, aserver, &err);
2118 fprintf(STDERR,"Failed to get info about server's %d address(es) from vlserver (err=%d); aborting call!\n",
2122 if (!vcode || (Opart != apart)) vol_elsewhere = 1;
2124 if (aoverwrite == ASK) {
2125 if (strcmp(afilename,"") == 0) { /* The file is from standard in */
2126 fprintf(STDERR,"Volume exists and no -overwrite option specified; Aborting restore command\n");
2130 /* Ask what to do */
2131 if (vol_elsewhere) {
2132 fprintf(STDERR,"The volume %s %u already exists on a different server/part\n",
2133 volname, entry.volumeId[voltype]);
2135 "Do you want to do a full restore or abort? [fa](a): ");
2139 fprintf(STDERR,"The volume %s %u already exists in the VLDB\n",
2140 volname, entry.volumeId[voltype]);
2142 "Do you want to do a full/incremental restore or abort? [fia](a): ");
2145 while (!(dc==EOF || dc=='\n')) dc=getchar(); /* goto end of line */
2146 if ((c == 'f') || (c == 'F')) aoverwrite = FULL;
2147 else if ((c == 'i') || (c == 'I')) aoverwrite = INC;
2148 else aoverwrite = ABORT;
2151 if (aoverwrite == ABORT) {
2152 fprintf(STDERR,"Volume exists; Aborting restore command\n");
2155 else if (aoverwrite == FULL) {
2156 restoreflags = RV_FULLRST;
2157 fprintf(STDERR,"Volume exists; Will delete and perform full restore\n");
2159 else if (aoverwrite == INC) {
2161 if (vol_elsewhere) {
2163 "%s volume %u already exists on a different server/part; not allowed\n",
2164 readonly ? "RO" : "RW", avolid);
2169 if (offline) restoreflags |= RV_OFFLINE;
2170 if (readonly) restoreflags |= RV_RDONLY;
2171 code = UV_RestoreVolume(aserver, apart, avolid, avolname,
2172 restoreflags, WriteData, afilename);
2174 PrintDiagnostics("restore", code);
2177 MapPartIdIntoName(apart,apartName);
2180 patch typo here - originally "parms[1]", should be "parms[0]"
2183 fprintf(STDOUT,"Restored volume %s on %s %s\n",
2184 avolname, as->parms[0].items->data, apartName);
2187 static LockReleaseCmd(as)
2188 register struct cmd_syndesc *as;
2191 afs_int32 avolid,code, err;
2193 avolid = vsu_GetVolumeID(as->parms[0].items->data, cstruct, &err);
2195 if (err) PrintError("", err);
2196 else fprintf(STDERR, "vos: can't find volume '%s'\n", as->parms[0].items->data);
2200 code = UV_LockRelease(avolid);
2202 PrintDiagnostics("unlock", code);
2205 fprintf(STDOUT,"Released lock on vldb entry for volume %s\n",as->parms[0].items->data);
2209 register struct cmd_syndesc *as;
2211 afs_int32 avolid, aserver, apart,code, err;
2212 char apartName[10], avolname[VOLSER_MAXVOLNAME+1];
2214 vsu_ExtractName(avolname, as->parms[2].items->data);;
2215 avolid = vsu_GetVolumeID(avolname, cstruct, &err);
2217 if (err) PrintError("", err);
2218 else fprintf(STDERR, "vos: can't find volume '%s'\n", as->parms[2].items->data);
2221 aserver = GetServer(as->parms[0].items->data);
2223 fprintf(STDERR,"vos: server '%s' not found in host table\n", as->parms[0].items->data);
2226 apart = volutil_GetPartitionID(as->parms[1].items->data);
2228 fprintf(STDERR,"vos: could not interpret partition name '%s'\n",as->parms[1].items->data );
2231 if (!IsPartValid(apart,aserver,&code)){/*check for validity of the partition */
2232 if(code) PrintError("",code);
2233 else fprintf(STDERR,"vos : partition %s does not exist on the server\n",as->parms[1].items->data);
2236 code = UV_AddSite(aserver, apart, avolid);
2238 PrintDiagnostics("addsite", code);
2241 MapPartIdIntoName(apart,apartName);
2242 fprintf(STDOUT,"Added replication site %s %s for volume %s\n",as->parms[0].items->data, apartName,as->parms[2].items->data);
2246 static RemoveSite(as)
2247 register struct cmd_syndesc *as;
2250 afs_int32 avolid, aserver, apart, code, err;
2251 char apartName[10], avolname[VOLSER_MAXVOLNAME+1];
2253 vsu_ExtractName(avolname, as->parms[2].items->data);
2254 avolid = vsu_GetVolumeID(avolname, cstruct, &err);
2256 if (err) PrintError("", err);
2257 else fprintf(STDERR, "vos: can't find volume '%s'\n", as->parms[2].items->data);
2260 aserver = GetServer(as->parms[0].items->data);
2262 fprintf(STDERR,"vos: server '%s' not found in host table\n", as->parms[0].items->data);
2265 apart = volutil_GetPartitionID(as->parms[1].items->data);
2267 fprintf(STDERR,"vos: could not interpret partition name '%s'\n",as->parms[1].items->data );
2271 *skip the partition validity check, since it is possible that the partition
2272 *has since been decomissioned.
2275 if (!IsPartValid(apart,aserver,&code)){
2276 if(code) PrintError("",code);
2277 else fprintf(STDERR,"vos : partition %s does not exist on the server\n",as->parms[1].items->data);
2281 code = UV_RemoveSite(aserver, apart, avolid);
2283 PrintDiagnostics("remsite", code);
2286 MapPartIdIntoName(apart,apartName);
2287 fprintf(STDOUT,"Removed replication site %s %s for volume %s\n",as->parms[0].items->data,apartName,as->parms[2].items->data);
2290 static ChangeLocation(as)
2291 register struct cmd_syndesc *as;
2293 afs_int32 avolid, aserver, apart,code, err;
2296 avolid = vsu_GetVolumeID(as->parms[2].items->data, cstruct, &err);
2298 if (err) PrintError("", err);
2299 else fprintf(STDERR, "vos: can't find volume '%s'\n", as->parms[2].items->data);
2302 aserver = GetServer(as->parms[0].items->data);
2304 fprintf(STDERR,"vos: server '%s' not found in host table\n", as->parms[0].items->data);
2307 apart = volutil_GetPartitionID(as->parms[1].items->data);
2309 fprintf(STDERR,"vos: could not interpret partition name '%s'\n",as->parms[1].items->data );
2312 if (!IsPartValid(apart,aserver,&code)){/*check for validity of the partition */
2313 if(code) PrintError("",code);
2314 else fprintf(STDERR,"vos : partition %s does not exist on the server\n",as->parms[1].items->data);
2317 code = UV_ChangeLocation(aserver, apart, avolid);
2319 PrintDiagnostics("addsite", code);
2322 MapPartIdIntoName(apart,apartName);
2323 fprintf(STDOUT,"Changed location to %s %s for volume %s\n",as->parms[0].items->data, apartName,as->parms[2].items->data);
2327 static ListPartitions(as)
2328 register struct cmd_syndesc *as;
2330 afs_int32 aserver,code;
2331 struct partList dummyPartList;
2336 aserver = GetServer(as->parms[0].items->data);
2338 fprintf(STDERR,"vos: server '%s' not found in host table\n", as->parms[0].items->data);
2343 code = UV_ListPartitions(aserver,&dummyPartList, &cnt);
2345 PrintDiagnostics("listpart", code);
2349 fprintf(STDOUT,"The partitions on the server are:\n");
2350 for(i = 0 ; i < cnt ; i++){
2351 if(dummyPartList.partFlags[i] & PARTVALID){
2352 memset(pname, 0, sizeof(pname));
2353 MapPartIdIntoName(dummyPartList.partId[i],pname);
2354 fprintf(STDOUT," %10s ",pname);
2356 if( (i % 5) == 0 && (i != 0)) fprintf(STDOUT,"\n");
2359 fprintf(STDOUT,"\n");
2360 fprintf(STDOUT,"Total: %d\n",total);
2365 static int CompareVolName(p1,p2)
2368 volintInfo *arg1,*arg2;
2370 arg1 = (volintInfo *)p1;
2371 arg2 = (volintInfo *)p2;
2372 return(strcmp(arg1->name,arg2->name));
2376 /*------------------------------------------------------------------------
2377 * PRIVATE XCompareVolName
2380 * Comparison routine for volume names coming from an extended
2384 * a_obj1P : Char ptr to first extended vol info object
2385 * a_obj1P : Char ptr to second extended vol info object
2388 * The value of strcmp() on the volume names within the passed
2389 * objects (i,e., -1, 0, or 1).
2392 * Passed to qsort() as the designated comparison routine.
2396 *------------------------------------------------------------------------*/
2398 static int XCompareVolName(a_obj1P, a_obj2P)
2399 char *a_obj1P, *a_obj2P;
2401 { /*XCompareVolName*/
2403 return(strcmp(((struct volintXInfo *)(a_obj1P))->name,
2404 ((struct volintXInfo *)(a_obj2P))->name));
2406 } /*XCompareVolName*/
2408 static int CompareVolID(p1,p2)
2411 volintInfo *arg1,*arg2;
2413 arg1 = (volintInfo *)p1;
2414 arg2 = (volintInfo *)p2;
2415 if(arg1->volid == arg2->volid) return 0;
2416 if(arg1->volid > arg2->volid) return 1;
2421 /*------------------------------------------------------------------------
2422 * PRIVATE XCompareVolID
2425 * Comparison routine for volume IDs coming from an extended
2429 * a_obj1P : Char ptr to first extended vol info object
2430 * a_obj1P : Char ptr to second extended vol info object
2433 * The value of strcmp() on the volume names within the passed
2434 * objects (i,e., -1, 0, or 1).
2437 * Passed to qsort() as the designated comparison routine.
2441 *------------------------------------------------------------------------*/
2443 static int XCompareVolID(a_obj1P, a_obj2P)
2444 char *a_obj1P, *a_obj2P;
2448 afs_int32 id1, id2; /*Volume IDs we're comparing*/
2450 id1 = ((struct volintXInfo *)(a_obj1P))->volid;
2451 id2 = ((struct volintXInfo *)(a_obj2P))->volid;
2462 /*------------------------------------------------------------------------
2463 * PRIVATE ListVolumes
2466 * Routine used to list volumes, contacting the Volume Server
2467 * directly, bypassing the VLDB.
2470 * as : Ptr to parsed command line arguments.
2473 * 0 Successful operation
2476 * Nothing interesting.
2480 *------------------------------------------------------------------------*/
2482 static ListVolumes(as)
2483 register struct cmd_syndesc *as;
2485 afs_int32 apart,int32list,fast;
2486 afs_int32 aserver,code;
2487 volintInfo *pntr,*oldpntr;
2491 volintXInfo *xInfoP, *origxInfoP; /*Ptr to current/orig extended vol info*/
2492 int wantExtendedInfo; /*Do we want extended vol info?*/
2495 struct partList dummyPartList;
2503 if(as->parms[3].items) int32list = 1;
2504 if(as->parms[4].items) quiet = 1;
2506 if(as->parms[2].items) fast = 1;
2509 if (as->parms[5].items) {
2511 * We can't coexist with the fast flag.
2515 "vos: Can't use the -fast and -extended flags together\n");
2520 * We need to turn on ``long'' listings to get the full effect.
2522 wantExtendedInfo = 1;
2526 wantExtendedInfo = 0;
2527 if(as->parms[1].items){
2528 apart = volutil_GetPartitionID(as->parms[1].items->data);
2530 fprintf(STDERR,"vos: could not interpret partition name '%s'\n", as->parms[1].items->data);
2533 dummyPartList.partId[0] = apart;
2534 dummyPartList.partFlags[0] = PARTVALID;
2537 aserver = GetServer(as->parms[0].items->data);
2539 fprintf(STDERR,"vos: server '%s' not found in host table\n",as->parms[0].items->data );
2544 if (!IsPartValid(apart,aserver,&code)){/*check for validity of the partition */
2545 if(code) PrintError("",code);
2546 else fprintf(STDERR,"vos : partition %s does not exist on the server\n",as->parms[1].items->data);
2551 code = UV_ListPartitions(aserver,&dummyPartList, &cnt);
2553 PrintDiagnostics("listvol", code);
2557 for(i = 0 ; i < cnt ; i++){
2558 if(dummyPartList.partFlags[i] & PARTVALID){
2559 if (wantExtendedInfo)
2560 code = UV_XListVolumes(aserver,
2561 dummyPartList.partId[i],
2566 code = UV_ListVolumes(aserver,
2567 dummyPartList.partId[i],
2572 PrintDiagnostics("listvol", code);
2573 if(pntr) free(pntr);
2576 if (wantExtendedInfo) {
2577 origxInfoP = xInfoP;
2578 base = (char *)xInfoP;
2581 base = (char *)pntr;
2585 if (wantExtendedInfo)
2586 qsort(base, count, sizeof(volintXInfo), XCompareVolName);
2588 qsort(base, count, sizeof(volintInfo), CompareVolName);
2590 if (wantExtendedInfo)
2591 qsort(base, count, sizeof(volintXInfo), XCompareVolID);
2593 qsort(base, count, sizeof(volintInfo), CompareVolID);
2595 MapPartIdIntoName(dummyPartList.partId[i],pname);
2597 fprintf(STDOUT,"Total number of volumes on server %s partition %s: %u \n",as->parms[0].items->data,pname,count);
2598 if (wantExtendedInfo) {
2599 XDisplayVolumes(aserver,
2600 dummyPartList.partId[i],
2608 xInfoP = (volintXInfo *)0;
2611 #ifdef FULL_LISTVOL_SWITCH
2612 if (as->parms[6].items)
2613 DisplayVolumes2(aserver, dummyPartList.partId[i], oldpntr,
2616 #endif /* FULL_LISTVOL_SWITCH */
2617 DisplayVolumes(aserver,
2618 dummyPartList.partId[i],
2626 pntr = (volintInfo *)0;
2634 register struct cmd_syndesc *as;
2636 afs_int32 pname, code; /* part name */
2642 if (as->parms[0].items) {
2643 tserver = GetServer(as->parms[0].items->data);
2645 fprintf(STDERR,"vos: host '%s' not found in host table\n",as->parms[0].items->data );
2650 if (as->parms[1].items) {
2651 pname = volutil_GetPartitionID(as->parms[1].items->data);
2653 fprintf(STDERR,"vos: could not interpret partition name '%s'\n",as->parms[1].items->data );
2656 if (!IsPartValid(pname,tserver,&code)) { /*check for validity of the partition */
2657 if(code) PrintError("",code);
2658 else fprintf(STDERR,"vos: partition %s does not exist on the server\n",
2659 as->parms[1].items->data);
2665 fprintf(STDERR,"The -partition option requires a -server option\n");
2670 if (as->parms[2].items) {
2671 /* Synchronize an individual volume */
2672 volname = as->parms[2].items->data;
2673 code = UV_SyncVolume(tserver, pname, volname, flags);
2676 fprintf(STDERR,"Without a -volume option, the -server option is required\n");
2679 code = UV_SyncVldb(tserver, pname, flags, 0/*unused*/);
2683 PrintDiagnostics("syncvldb", code);
2687 /* Print a summary of what we did */
2688 if (volname) fprintf(STDOUT,"VLDB volume %s synchronized", volname);
2689 else fprintf(STDOUT,"VLDB synchronized");
2691 fprintf(STDOUT," with state of server %s", as->parms[0].items->data);
2694 MapPartIdIntoName(pname,part);
2695 fprintf(STDOUT," partition %s\n", part);
2697 fprintf(STDOUT, "\n");
2702 static SyncServer(as)
2703 register struct cmd_syndesc *as;
2706 afs_int32 pname,code; /* part name */
2711 tserver = GetServer(as->parms[0].items->data);
2713 fprintf(STDERR,"vos: host '%s' not found in host table\n",as->parms[0].items->data );
2716 if(as->parms[1].items){
2717 pname = volutil_GetPartitionID(as->parms[1].items->data);
2719 fprintf(STDERR,"vos: could not interpret partition name '%s'\n",as->parms[1].items->data);
2722 if (!IsPartValid(pname,tserver,&code)){/*check for validity of the partition */
2723 if(code) PrintError("",code);
2724 else fprintf(STDERR,"vos : partition %s does not exist on the server\n",as->parms[1].items->data);
2730 code = UV_SyncServer(tserver, pname, flags, 0/*unused*/);
2732 PrintDiagnostics("syncserv", code);
2736 MapPartIdIntoName(pname,part);
2737 fprintf(STDOUT,"Server %s partition %s synchronized with VLDB\n",as->parms[0].items->data,part);
2739 else fprintf(STDOUT,"Server %s synchronized with VLDB\n",as->parms[0].items->data);
2744 static VolumeInfoCmd(name)
2747 struct nvldbentry entry;
2750 /* The vlserver will handle names with the .readonly
2751 * and .backup extension as well as volume ids.
2753 vcode = VLDB_GetEntryByName(name, &entry);
2755 PrintError("", vcode);
2758 MapHostToNetwork(&entry);
2759 EnumerateEntry(&entry);
2761 /* Defect #3027: grubby check to handle locked volume.
2762 * If VLOP_ALLOPERS is set, the entry is locked.
2763 * Leave this routine as is, but put in correct check.
2765 if (entry.flags & VLOP_ALLOPERS)
2766 fprintf(STDOUT," Volume is currently LOCKED \n");
2771 static VolumeZap(as)
2772 register struct cmd_syndesc *as;
2775 struct nvldbentry entry;
2776 afs_int32 volid,code,server,part, zapbackupid=0, backupid=0, err;
2778 if (as->parms[3].items) {
2779 /* force flag is on, use the other version */
2780 return NukeVolume(as);
2783 if (as->parms[4].items) {
2787 volid = vsu_GetVolumeID(as->parms[2].items->data, cstruct, &err);
2789 if (err) PrintError("", err);
2790 else fprintf(STDERR, "vos: can't find volume '%s'\n", as->parms[2].items->data);
2793 part = volutil_GetPartitionID(as->parms[1].items->data);
2795 fprintf(STDERR,"vos: could not interpret partition name '%s'\n",as->parms[1].items->data );
2798 server = GetServer(as->parms[0].items->data);
2800 fprintf(STDERR,"vos: host '%s' not found in host table\n",as->parms[0].items->data );
2803 if (!IsPartValid(part,server,&code)){/*check for validity of the partition */
2804 if(code) PrintError("",code);
2805 else fprintf(STDERR,"vos : partition %s does not exist on the server\n",as->parms[1].items->data);
2808 code = VLDB_GetEntryByID(volid,-1, &entry);
2810 if (volid == entry.volumeId[RWVOL])
2811 backupid = entry.volumeId[BACKVOL];
2812 fprintf(STDERR,"Warning: Entry for volume number %u exists in VLDB (but we're zapping it anyway!)\n",
2816 volintInfo *pntr = (volintInfo *)0;
2819 code = UV_ListOneVolume(server, part, volid, &pntr);
2821 if (volid == pntr->parentID)
2822 backupid = pntr->backupID;
2823 if (pntr) free(pntr);
2827 code = UV_VolumeZap(server,part, backupid);
2829 PrintDiagnostics("zap", code);
2832 fprintf(STDOUT,"Backup Volume %u deleted\n", backupid);
2835 code = UV_VolumeZap(server,part,volid);
2837 PrintDiagnostics("zap", code);
2840 fprintf(STDOUT,"Volume %u deleted\n",volid);
2845 static VolserStatus(as)
2846 register struct cmd_syndesc *as;
2849 afs_int32 server, code;
2850 transDebugInfo *pntr,*oldpntr;
2855 server = GetServer(as->parms[0].items->data);
2857 fprintf(STDERR,"vos: host '%s' not found in host table\n",as->parms[0].items->data );
2860 code = UV_VolserStatus(server,&pntr,&count);
2862 PrintDiagnostics("status",code);
2867 fprintf(STDOUT,"No active transactions on %s\n",as->parms[0].items->data);
2869 fprintf(STDOUT,"Total transactions: %d\n",count);
2871 for(i = 0; i < count ; i++){
2872 /*print out the relevant info */
2873 fprintf(STDOUT,"--------------------------------------\n");
2874 fprintf(STDOUT,"transaction: %u created: %s",pntr->tid,
2875 ctime((time_t *)&pntr->time));
2876 if(pntr->returnCode){
2877 fprintf(STDOUT,"returnCode: %u\n",pntr->returnCode);
2880 fprintf(STDOUT,"attachFlags: ");
2881 switch(pntr->iflags){
2882 case ITOffline: fprintf(STDOUT,"offline ");
2884 case ITBusy: fprintf(STDOUT,"busy ");
2886 case ITReadOnly: fprintf(STDOUT,"readonly ");
2888 case ITCreate: fprintf(STDOUT,"create ");
2890 case ITCreateVolID: fprintf(STDOUT,"create volid ");
2893 fprintf(STDOUT,"\n");
2896 fprintf(STDOUT,"volumeStatus: ");
2897 switch(pntr->vflags){
2898 case VTDeleteOnSalvage: fprintf(STDOUT,"deleteOnSalvage ");
2899 case VTOutOfService: fprintf(STDOUT,"outOfService ");
2900 case VTDeleted: fprintf(STDOUT,"deleted ");
2902 fprintf(STDOUT,"\n");
2905 fprintf(STDOUT,"transactionFlags: ");
2906 fprintf(STDOUT,"delete\n");
2908 MapPartIdIntoName(pntr->partition ,pname);
2909 fprintf(STDOUT,"volume: %u partition: %s procedure: %s\n",pntr->volid,pname, pntr->lastProcName);
2910 if(pntr->callValid){
2911 fprintf(STDOUT,"packetRead: %u lastReceiveTime: %d packetSend: %u lastSendTime: %d\n",pntr->readNext,pntr->lastReceiveTime,pntr->transmitNext, pntr->lastSendTime);
2914 fprintf(STDOUT,"--------------------------------------\n");
2915 fprintf(STDOUT,"\n");
2917 if(oldpntr) free(oldpntr);
2921 static RenameVolume(as)
2922 register struct cmd_syndesc *as;
2924 afs_int32 code1,code2,code;
2925 struct nvldbentry entry;
2927 code1 = VLDB_GetEntryByName(as->parms[0].items->data, &entry);
2929 fprintf(STDERR,"vos: Could not find entry for volume %s\n",as->parms[0].items->data);
2932 code2 = VLDB_GetEntryByName(as->parms[1].items->data, &entry);
2933 if((!code1) && (!code2)) { /*the newname already exists */
2934 fprintf(STDERR,"vos: volume %s already exists\n",as->parms[1].items->data);
2939 fprintf(STDERR,"vos: Could not find entry for volume %s or %s\n",as->parms[0].items->data,as->parms[1].items->data);
2942 if(!VolNameOK(as->parms[0].items->data)){
2943 fprintf(STDERR,"Illegal volume name %s, should not end in .readonly or .backup\n",as->parms[0].items->data);
2946 if(!ISNAMEVALID(as->parms[1].items->data)) {
2947 fprintf(STDERR,"vos: the new volume name %s exceeds the size limit of %d\n",as->parms[1].items->data,VOLSER_OLDMAXVOLNAME - 10);
2950 if(!VolNameOK(as->parms[1].items->data)){
2951 fprintf(STDERR,"Illegal volume name %s, should not end in .readonly or .backup\n",as->parms[1].items->data);
2954 if(IsNumeric(as->parms[1].items->data)){
2955 fprintf(STDERR,"Illegal volume name %s, should not be a number\n",as->parms[1].items->data);
2958 MapHostToNetwork(&entry);
2959 code = UV_RenameVolume(&entry,as->parms[0].items->data,as->parms[1].items->data);
2961 PrintDiagnostics("rename", code);
2964 fprintf(STDOUT,"Renamed volume %s to %s\n",as->parms[0].items->data,as->parms[1].items->data);
2968 GetVolumeInfo(volid, server, part, voltype,rentry)
2969 afs_int32 *server, volid, *part, *voltype;
2970 register struct nvldbentry *rentry;
2975 vcode = VLDB_GetEntryByID(volid, -1, rentry);
2977 fprintf(STDERR,"Could not fetch the entry for volume %u from VLDB \n",volid);
2978 PrintError("",vcode);
2981 MapHostToNetwork(rentry);
2982 if(volid == rentry->volumeId[ROVOL]){
2984 for (i = 0; i < rentry->nServers; i++) {
2985 if ( (index == -1) && (rentry->serverFlags[i] & ITSROVOL) &&
2986 !(rentry->serverFlags[i] & RO_DONTUSE) )
2990 fprintf(STDERR,"RO volume is not found in VLDB entry for volume %u\n", volid);
2994 *server = rentry->serverNumber[index];
2995 *part = rentry->serverPartition[index];
2999 index = Lp_GetRwIndex(rentry);
3001 fprintf(STDERR,"RW Volume is not found in VLDB entry for volume %u\n", volid);
3004 if(volid == rentry->volumeId[RWVOL]){
3006 *server = rentry->serverNumber[index];
3007 *part = rentry->serverPartition[index];
3010 if(volid == rentry->volumeId[BACKVOL]){
3012 *server = rentry->serverNumber[index];
3013 *part = rentry->serverPartition[index];
3018 static DeleteEntry(as)
3019 register struct cmd_syndesc *as;
3025 struct VldbListByAttributes attributes;
3026 nbulkentries arrayEntries;
3027 register struct nvldbentry *vllist;
3028 struct cmd_item *itp;
3031 char prefix[VOLSER_MAXVOLNAME+1];
3033 afs_int32 totalBack=0, totalFail=0, err;
3035 if (as->parms[0].items) { /* -id */
3036 if (as->parms[1].items || as->parms[2].items || as->parms[3].items) {
3037 fprintf(STDERR,"You cannot use -server, -partition, or -prefix with the -id argument\n");
3040 for (itp=as->parms[0].items; itp; itp=itp->next) {
3041 avolid = vsu_GetVolumeID(itp->data, cstruct, &err);
3043 if (err) PrintError("", err);
3044 else fprintf(STDERR, "vos: can't find volume '%s'\n", itp->data);
3047 if (as->parms[4].items) { /* -noexecute */
3048 fprintf(STDOUT,"Would have deleted VLDB entry for %s \n", itp->data);
3052 vcode = ubik_Call(VL_DeleteEntry,cstruct, 0, avolid, RWVOL);
3054 fprintf(STDERR,"Could not delete entry for volume %s\n", itp->data);
3055 fprintf(STDERR,"You must specify a RW volume name or ID "
3056 "(the entire VLDB entry will be deleted)\n", itp->data);
3057 PrintError("",vcode);
3063 fprintf(STDOUT,"Deleted %d VLDB entries\n", totalBack);
3067 if (!as->parms[1].items && !as->parms[2].items && !as->parms[3].items) {
3068 fprintf(STDERR,"You must specify an option\n");
3072 /* Zero out search attributes */
3073 memset(&attributes, 0, sizeof(struct VldbListByAttributes));
3075 if (as->parms[1].items) { /* -prefix */
3076 strncpy(prefix, as->parms[1].items->data, VOLSER_MAXVOLNAME);
3078 if (!as->parms[2].items && !as->parms[3].items) { /* a single entry only */
3079 fprintf(STDERR,"You must provide -server with the -prefix argument\n");
3084 if (as->parms[2].items) { /* -server */
3086 aserver = GetServer(as->parms[2].items->data);
3088 fprintf(STDERR,"vos: server '%s' not found in host table\n",as->parms[2].items->data );
3091 attributes.server = ntohl(aserver);
3092 attributes.Mask |= VLLIST_SERVER;
3095 if (as->parms[3].items) { /* -partition */
3096 if (!as->parms[2].items) {
3097 fprintf(STDERR,"You must provide -server with the -partition argument\n");
3100 apart = volutil_GetPartitionID(as->parms[3].items->data);
3102 fprintf(STDERR,"vos: could not interpret partition name '%s'\n",
3103 as->parms[3].items->data);
3106 attributes.partition = apart;
3107 attributes.Mask |= VLLIST_PARTITION;
3110 /* Print status line of what we are doing */
3111 fprintf(STDOUT,"Deleting VLDB entries for ");
3112 if (as->parms[2].items) {
3113 fprintf(STDOUT,"server %s ", as->parms[2].items->data);
3115 if (as->parms[3].items) {
3117 MapPartIdIntoName(apart, pname);
3118 fprintf(STDOUT,"partition %s ", pname);
3121 fprintf(STDOUT,"which are prefixed with %s ", prefix);
3123 fprintf(STDOUT,"\n");
3126 /* Get all the VLDB entries on a server and/or partition */
3127 memset(&arrayEntries, 0, sizeof(arrayEntries));
3128 vcode = VLDB_ListAttributes(&attributes, &nentries, &arrayEntries);
3130 fprintf(STDERR,"Could not access the VLDB for attributes\n");
3131 PrintError("",vcode);
3135 /* Process each entry */
3136 for (j=0; j<nentries; j++) {
3137 vllist = &arrayEntries.nbulkentries_val[j];
3139 /* It only deletes the RW volumes */
3140 if (strncmp(vllist->name, prefix, strlen(prefix))){
3142 fprintf(STDOUT,"Omitting to delete %s due to prefix %s mismatch\n",
3143 vllist->name, prefix);
3150 if (as->parms[4].items) { /* -noexecute */
3151 fprintf(STDOUT,"Would have deleted VLDB entry for %s \n", vllist->name);
3156 /* Only matches the RW volume name */
3157 avolid = vllist->volumeId[RWVOL];
3158 vcode = ubik_Call(VL_DeleteEntry, cstruct, 0, avolid, RWVOL);
3160 fprintf(STDOUT,"Could not delete VDLB entry for %s\n",vllist->name);
3162 PrintError("",vcode);
3167 fprintf(STDOUT,"Deleted VLDB entry for %s \n",vllist->name);
3172 fprintf(STDOUT,"----------------------\n");
3173 fprintf(STDOUT,"Total VLDB entries deleted: %u; failed to delete: %u\n",totalBack,totalFail);
3174 if (arrayEntries.nbulkentries_val) free(arrayEntries.nbulkentries_val);
3179 static int CompareVldbEntryByName(p1,p2)
3182 struct nvldbentry *arg1,*arg2;
3184 arg1 = (struct nvldbentry *)p1;
3185 arg2 = (struct nvldbentry *)p2;
3186 return(strcmp(arg1->name,arg2->name));
3190 static int CompareVldbEntry(p1,p2)
3193 struct nvldbentry *arg1,*arg2;
3196 char comp1[100],comp2[100];
3197 char temp1[20],temp2[20];
3199 arg1 = (struct nvldbentry *)p1;
3200 arg2 = (struct nvldbentry *)p2;
3204 for(i = 0; i < arg1->nServers; i++)
3205 if(arg1->serverFlags[i] & ITSRWVOL) pos1 = i;
3206 for(i = 0; i < arg2->nServers; i++)
3207 if(arg2->serverFlags[i] & ITSRWVOL) pos2 = i;
3208 if(pos1 == -1 || pos2 == -1){
3212 sprintf(comp1,"%10u",arg1->serverNumber[pos1]);
3213 sprintf(comp2,"%10u",arg2->serverNumber[pos2]);
3214 sprintf(temp1,"%10u",arg1->serverPartition[pos1]);
3215 sprintf(temp2,"%10u",arg2->serverPartition[pos2]);
3216 strcat(comp1,temp1);
3217 strcat(comp2,temp2);
3218 strcat(comp1,arg1->name);
3219 strcat(comp1,arg2->name);
3220 return(strcmp(comp1,comp2));
3226 struct cmd_syndesc *as;
3229 afs_int32 aserver,code;
3231 struct VldbListByAttributes attributes;
3232 nbulkentries arrayEntries;
3233 struct nvldbentry *vllist, *tarray=0, *ttarray;
3234 afs_int32 centries, nentries = 0, tarraysize, parraysize;
3237 int quiet, sort, lock;
3238 afs_int32 thisindex, nextindex;
3243 attributes.Mask = 0;
3244 lock = (as->parms[3].items ? 1 : 0); /* -lock flag */
3245 quiet = (as->parms[4].items ? 1 : 0); /* -quit flag */
3246 sort = (as->parms[5].items ? 0 : 1); /* -nosort flag */
3248 /* If the volume name is given, Use VolumeInfoCmd to look it up
3249 * and not ListAttributes.
3251 if (as->parms[0].items) {
3253 fprintf(STDERR,"vos: illegal use of '-locked' switch, need to specify server and/or partition\n");
3256 code = VolumeInfoCmd(as->parms[0].items->data);
3258 PrintError("",code);
3264 /* Server specified */
3265 if (as->parms[1].items) {
3266 aserver = GetServer(as->parms[1].items->data);
3268 fprintf(STDERR,"vos: server '%s' not found in host table\n",as->parms[1].items->data );
3271 attributes.server = ntohl(aserver);
3272 attributes.Mask |= VLLIST_SERVER;
3275 /* Partition specified */
3276 if (as->parms[2].items) {
3277 apart = volutil_GetPartitionID(as->parms[2].items->data);
3279 fprintf(STDERR,"vos: could not interpret partition name '%s'\n", as->parms[2].items->data);
3282 attributes.partition = apart;
3283 attributes.Mask |= VLLIST_PARTITION;
3287 attributes.Mask |= VLLIST_FLAG;
3288 attributes.flag = VLOP_ALLOPERS;
3291 /* Print header information */
3293 MapPartIdIntoName(apart, pname);
3294 fprintf(STDOUT,"VLDB entries for %s %s%s%s %s\n",
3295 (as->parms[1].items ? "server" : "all" ),
3296 (as->parms[1].items ? as->parms[1].items->data : "servers"),
3297 (as->parms[2].items ? " partition " : ""),
3298 (as->parms[2].items ? pname : ""),
3299 (lock ? "which are locked:" : ""));
3302 for (thisindex = 0; (thisindex != -1); thisindex = nextindex) {
3303 memset(&arrayEntries, 0, sizeof(arrayEntries));
3307 vcode = VLDB_ListAttributesN2(&attributes, 0, thisindex,
3308 ¢ries, &arrayEntries, &nextindex);
3309 if (vcode == RXGEN_OPCODE) {
3310 /* Vlserver not running with ListAttributesN2. Fall back */
3311 vcode = VLDB_ListAttributes(&attributes, ¢ries, &arrayEntries);
3315 fprintf(STDERR,"Could not access the VLDB for attributes\n");
3316 PrintError("",vcode);
3319 nentries += centries;
3321 /* We don't sort, so just print the entries now */
3323 for (j = 0; j < centries; j++) { /* process each entry */
3324 vllist = &arrayEntries.nbulkentries_val[j];
3325 MapHostToNetwork(vllist);
3326 EnumerateEntry(vllist);
3328 if(vllist->flags & VLOP_ALLOPERS)
3329 fprintf(STDOUT," Volume is currently LOCKED \n");
3333 /* So we sort. First we must collect all the entries and keep
3336 else if (centries > 0) {
3338 /* steal away the first bulk entries array */
3339 tarray = (struct nvldbentry *)arrayEntries.nbulkentries_val;
3340 tarraysize = centries * sizeof(struct nvldbentry);
3341 arrayEntries.nbulkentries_val = 0;
3343 /* Grow the tarray to keep the extra entries */
3344 parraysize = (centries * sizeof(struct nvldbentry));
3345 ttarray = (struct nvldbentry *) realloc(tarray, tarraysize + parraysize);
3347 fprintf(STDERR,"Could not allocate enough space for the VLDB entries\n");
3353 memcpy(((char *)tarray)+tarraysize, (char *)arrayEntries.nbulkentries_val, parraysize);
3354 tarraysize += parraysize;
3358 /* Free the bulk array */
3359 if (arrayEntries.nbulkentries_val) {
3360 free(arrayEntries.nbulkentries_val);
3361 arrayEntries.nbulkentries_val = 0;
3365 /* Here is where we now sort all the entries and print them */
3366 if (sort && (nentries > 0)) {
3367 qsort((char *)tarray, nentries, sizeof(struct nvldbentry), CompareVldbEntryByName);
3368 for (vllist=tarray, j=0; j<nentries; j++, vllist++) {
3369 MapHostToNetwork(vllist);
3370 EnumerateEntry(vllist);
3372 if(vllist->flags & VLOP_ALLOPERS)
3373 fprintf(STDOUT," Volume is currently LOCKED \n");
3378 if (!quiet) fprintf(STDOUT,"\nTotal entries: %u\n", nentries);
3379 if (tarray) free(tarray);
3384 register struct cmd_syndesc *as;
3386 afs_int32 apart=0, avolid;
3387 afs_int32 aserver=0, code, aserver1, apart1;
3389 struct VldbListByAttributes attributes;
3390 nbulkentries arrayEntries;
3391 register struct nvldbentry *vllist;
3395 int seenprefix, seenxprefix, exclude, ex, exp, noaction;
3396 afs_int32 totalBack=0;
3397 afs_int32 totalFail=0;
3398 int previdx=-1, error, same;
3401 struct cmd_item *ti;
3405 memset(&attributes, 0, sizeof(struct VldbListByAttributes));
3406 attributes.Mask = 0;
3408 seenprefix = (as->parms[0].items ? 1 : 0);
3409 exclude = (as->parms[3].items ? 1 : 0);
3410 seenxprefix = (as->parms[4].items ? 1 : 0);
3411 noaction = (as->parms[5].items ? 1 : 0);
3413 if (as->parms[1].items) { /* -server */
3414 aserver = GetServer(as->parms[1].items->data);
3416 fprintf(STDERR,"vos: server '%s' not found in host table\n",as->parms[1].items->data );
3419 attributes.server = ntohl(aserver);
3420 attributes.Mask |= VLLIST_SERVER;
3423 if (as->parms[2].items) { /* -partition */
3424 apart = volutil_GetPartitionID(as->parms[2].items->data);
3426 fprintf(STDERR,"vos: could not interpret partition name '%s'\n", as->parms[2].items->data);
3429 attributes.partition = apart;
3430 attributes.Mask |= VLLIST_PARTITION;
3433 /* Check to make sure the prefix and xprefix expressions compile ok */
3435 for (ti=as->parms[0].items; ti; ti=ti->next) {
3436 if (strncmp(ti->data,"^",1) == 0) {
3437 ccode = (char *)re_comp(ti->data);
3439 fprintf(STDERR,"Unrecognizable -prefix regular expression: '%s': %s\n",
3447 for (ti=as->parms[4].items; ti; ti=ti->next) {
3448 if (strncmp(ti->data,"^",1) == 0) {
3449 ccode = (char *)re_comp(ti->data);
3451 fprintf(STDERR,"Unrecognizable -xprefix regular expression: '%s': %s\n",
3459 memset(&arrayEntries, 0, sizeof(arrayEntries)); /* initialize to hint the stub to alloc space */
3460 vcode = VLDB_ListAttributes(&attributes, &nentries, &arrayEntries);
3462 fprintf(STDERR,"Could not access the VLDB for attributes\n");
3463 PrintError("",vcode);
3467 if (as->parms[1].items || as->parms[2].items || verbose) {
3468 fprintf(STDOUT,"%s up volumes", (noaction?"Would have backed":"Backing"));
3470 if (as->parms[1].items) {
3471 fprintf(STDOUT," on server %s", as->parms[1].items->data);
3472 } else if (as->parms[2].items) {
3473 fprintf(STDOUT," for all servers");
3476 if (as->parms[2].items) {
3477 MapPartIdIntoName(apart, pname);
3478 fprintf(STDOUT," partition %s", pname);
3481 if (seenprefix || (!seenprefix && seenxprefix)) {
3482 ti = (seenprefix ? as->parms[0].items : as->parms[4].items);
3483 ex = (seenprefix ? exclude : !exclude);
3484 exp = (strncmp(ti->data,"^",1) == 0);
3485 fprintf(STDOUT," which %smatch %s '%s'", (ex ? "do not " : ""),
3486 (exp?"expression":"prefix"), ti->data);
3487 for (ti=ti->next; ti; ti=ti->next) {
3488 exp = (strncmp(ti->data,"^",1) == 0);
3489 printf(" %sor %s '%s'", (ex ? "n" : ""),
3490 (exp?"expression":"prefix"), ti->data);
3494 if (seenprefix && seenxprefix) {
3495 ti = as->parms[4].items;
3496 exp = (strncmp(ti->data,"^",1) == 0);
3497 fprintf(STDOUT," %swhich match %s '%s'",
3498 (exclude?"adding those ":"removing those "),
3499 (exp?"expression":"prefix"), ti->data);
3500 for (ti=ti->next; ti; ti=ti->next) {
3501 exp = (strncmp(ti->data,"^",1) == 0);
3502 printf(" or %s '%s'", (exp?"expression":"prefix"), ti->data);
3505 fprintf(STDOUT," .. ");
3506 if (verbose) fprintf(STDOUT,"\n");
3510 for (j=0; j<nentries; j++) { /* process each vldb entry */
3511 vllist = &arrayEntries.nbulkentries_val[j];
3514 for (ti=as->parms[0].items; ti; ti=ti->next) {
3515 if (strncmp(ti->data,"^",1) == 0) {
3516 ccode = (char *)re_comp(ti->data);
3518 fprintf(STDERR,"Error in -prefix regular expression: '%s': %s\n",
3522 match = (re_exec(vllist->name) == 1);
3524 match = (strncmp(vllist->name,ti->data,strlen(ti->data)) == 0);
3532 /* Without the -exclude flag: If it matches the prefix, then
3533 * check if we want to exclude any from xprefix.
3534 * With the -exclude flag: If it matches the prefix, then
3535 * check if we want to add any from xprefix.
3537 if (match && seenxprefix) {
3538 for (ti=as->parms[4].items; ti; ti=ti->next) {
3539 if (strncmp(ti->data,"^",1) == 0) {
3540 ccode = (char *)re_comp(ti->data);
3542 fprintf(STDERR,"Error in -xprefix regular expression: '%s': %s\n",
3546 if (re_exec(vllist->name) == 1) {
3551 if (strncmp(vllist->name,ti->data,strlen(ti->data)) == 0) {
3559 if (exclude) match = !match; /* -exclude will reverse the match */
3560 if (!match) continue; /* Skip if no match */
3562 /* Print list of volumes to backup */
3564 fprintf(STDOUT," %s\n", vllist->name);
3568 if(!(vllist->flags & RW_EXISTS)){
3570 fprintf(STDOUT,"Omitting to backup %s since RW volume does not exist \n", vllist->name);
3571 fprintf(STDOUT,"\n");
3577 avolid = vllist->volumeId[RWVOL];
3578 MapHostToNetwork(vllist);
3579 GetServerAndPart(vllist,RWVOL,&aserver1,&apart1,&previdx);
3580 if(aserver1 == -1 || apart1 == -1){
3581 fprintf(STDOUT,"could not backup %s, invalid VLDB entry\n",vllist->name);
3586 same = VLDB_IsSameAddrs(aserver, aserver1, &error);
3588 fprintf(STDERR,"Failed to get info about server's %d address(es) from vlserver (err=%d); aborting call!\n",
3594 if ((aserver && !same) || (apart && (apart != apart1))) {
3596 fprintf(STDOUT, "Omitting to backup %s since the RW is in a different location\n", vllist->name);
3601 time_t now = time(0);
3602 fprintf(STDOUT,"Creating backup volume for %s on %s",vllist->name, ctime(&now));
3606 code = UV_BackupVolume(aserver1, apart1, avolid);
3608 fprintf(STDOUT,"Could not backup %s\n",vllist->name);
3614 if (verbose) fprintf(STDOUT,"\n");
3616 } /* process each vldb entry */
3617 fprintf(STDOUT,"done\n");
3618 fprintf(STDOUT,"Total volumes backed up: %u; failed to backup: %u\n",totalBack,totalFail);
3620 if(arrayEntries.nbulkentries_val) free(arrayEntries.nbulkentries_val);
3624 static UnlockVLDB(as)
3625 register struct cmd_syndesc *as;
3628 afs_int32 aserver,code;
3630 struct VldbListByAttributes attributes;
3631 nbulkentries arrayEntries;
3632 register struct nvldbentry *vllist;
3641 attributes.Mask = 0;
3643 if(as->parms[0].items) {/* server specified */
3644 aserver = GetServer(as->parms[0].items->data);
3646 fprintf(STDERR,"vos: server '%s' not found in host table\n",as->parms[0].items->data );
3649 attributes.server = ntohl(aserver);
3650 attributes.Mask |= VLLIST_SERVER;
3652 if(as->parms[1].items) {/* partition specified */
3653 apart = volutil_GetPartitionID(as->parms[1].items->data);
3655 fprintf(STDERR,"vos: could not interpret partition name '%s'\n", as->parms[1].items->data);
3658 if (!IsPartValid(apart,aserver,&code)){/*check for validity of the partition */
3659 if(code) PrintError("",code);
3660 else fprintf(STDERR,"vos : partition %s does not exist on the server\n",as->parms[1].items->data);
3663 attributes.partition = apart;
3664 attributes.Mask |= VLLIST_PARTITION;
3666 attributes.flag = VLOP_ALLOPERS;
3667 attributes.Mask |= VLLIST_FLAG;
3668 memset(&arrayEntries, 0, sizeof(arrayEntries)); /*initialize to hint the stub to alloc space */
3669 vcode = VLDB_ListAttributes(&attributes, &nentries, &arrayEntries);
3671 fprintf(STDERR,"Could not access the VLDB for attributes\n");
3672 PrintError("",vcode);
3675 for(j=0;j<nentries;j++) { /* process each entry */
3676 vllist = &arrayEntries.nbulkentries_val[j];
3677 volid = vllist->volumeId[RWVOL];
3678 vcode = ubik_Call(VL_ReleaseLock,cstruct, 0, volid,-1, LOCKREL_OPCODE | LOCKREL_AFSID | LOCKREL_TIMESTAMP);
3680 fprintf(STDERR,"Could not unlock entry for volume %s\n",vllist->name);
3681 PrintError("",vcode);
3686 MapPartIdIntoName(apart,pname);
3687 if(totalE) fprintf(STDOUT,"Could not lock %u VLDB entries of %u locked entries\n",totalE,nentries);
3689 if(as->parms[0].items) {
3690 fprintf(STDOUT,"Unlocked all the VLDB entries for volumes on server %s ",as->parms[0].items->data);
3691 if(as->parms[1].items){
3692 MapPartIdIntoName(apart,pname);
3693 fprintf(STDOUT,"partition %s\n",pname);
3695 else fprintf(STDOUT,"\n");
3698 else if(as->parms[1].items){
3699 MapPartIdIntoName(apart,pname);
3700 fprintf(STDOUT,"Unlocked all the VLDB entries for volumes on partition %s on all servers\n",pname);
3704 if(arrayEntries.nbulkentries_val) free(arrayEntries.nbulkentries_val);
3708 static PartitionInfo(as)
3709 register struct cmd_syndesc *as;
3712 afs_int32 aserver,code;
3714 struct diskPartition partition;
3715 struct partList dummyPartList;
3719 aserver = GetServer(as->parms[0].items->data);
3721 fprintf(STDERR,"vos: server '%s' not found in host table\n",as->parms[0].items->data );
3724 if(as->parms[1].items){
3725 apart = volutil_GetPartitionID(as->parms[1].items->data);
3727 fprintf(STDERR,"vos: could not interpret partition name '%s'\n", as->parms[1].items->data);
3730 dummyPartList.partId[0] = apart;
3731 dummyPartList.partFlags[0] = PARTVALID;
3735 if (!IsPartValid(apart,aserver,&code)){/*check for validity of the partition */
3736 if(code) PrintError("",code);
3737 else fprintf(STDERR,"vos : partition %s does not exist on the server\n",as->parms[1].items->data);
3742 code = UV_ListPartitions(aserver,&dummyPartList, &cnt);
3744 PrintDiagnostics("listpart", code);
3748 for(i = 0 ; i < cnt ; i++){
3749 if(dummyPartList.partFlags[i] & PARTVALID){
3750 MapPartIdIntoName(dummyPartList.partId[i],pname);
3751 code = UV_PartitionInfo(aserver,pname,&partition);
3753 fprintf(STDERR,"Could not get information on partition %s\n",pname);
3754 PrintError("",code);
3757 fprintf(STDOUT,"Free space on partition %s: %d K blocks out of total %d\n",pname,partition.free,partition.minFree);
3763 static ChangeAddr(as)
3764 register struct cmd_syndesc *as;
3767 afs_int32 ip1, ip2, vcode;
3770 ip1 = GetServer(as->parms[0].items->data);
3772 fprintf(STDERR, "vos: invalid host address\n");
3776 if ( ( as->parms[1].items && as->parms[2].items) ||
3777 (!as->parms[1].items && !as->parms[2].items) ) {
3778 fprintf(STDERR, "vos: Must specify either '-newaddr <addr>' or '-remove' flag\n");
3782 if (as->parms[1].items) {
3783 ip2 = GetServer(as->parms[1].items->data);
3785 fprintf(STDERR, "vos: invalid host address\n");
3789 /* Play a trick here. If we are removing an address, ip1 will be -1
3790 * and ip2 will be the original address. This switch prevents an
3791 * older revision vlserver from removing the IP address.
3798 vcode = ubik_Call_New(VL_ChangeAddr, cstruct, 0, ntohl(ip1), ntohl(ip2) );
3801 fprintf(STDERR,"Could not remove server %s from the VLDB\n",
3802 as->parms[0].items->data);
3803 if (vcode == VL_NOENT) {
3804 fprintf(STDERR, "vlserver does not support the remove flag or ");
3807 fprintf(STDERR,"Could not change server %s to server %s\n",
3808 as->parms[0].items->data, as->parms[1].items->data);
3810 PrintError("",vcode);
3815 fprintf(STDOUT,"Removed server %s from the VLDB\n",
3816 as->parms[0].items->data);
3818 fprintf(STDOUT,"Changed server %s to server %s\n",
3819 as->parms[0].items->data, as->parms[1].items->data);
3825 print_addrs(const bulkaddrs *addrs, const afsUUID *m_uuid, int nentries, int print, int noresolve)
3829 struct VLCallBack unused;
3832 ListAddrByAttributes m_attrs;
3833 afs_int32 m_unique, m_nentries, *m_addrp;
3834 afs_int32 base, index;
3838 afsUUID_to_string(m_uuid, buf, sizeof(buf));
3839 printf("UUID: %s\n", buf);
3842 /* print out the list of all the server */
3843 addrp = (afs_int32 *)addrs->bulkaddrs_val;
3844 for (i=0; i<nentries; i++, addrp++) {
3845 /* If it is a multihomed address, then we will need to
3846 * get the addresses for this multihomed server from
3847 * the vlserver and print them.
3849 if ( ((*addrp & 0xff000000) == 0xff000000) && ((*addrp)&0xffff) ) {
3850 /* Get the list of multihomed fileservers */
3851 base = (*addrp>>16) & 0xff;
3852 index = (*addrp) & 0xffff;
3854 if ( (base >= 0) && (base <= VL_MAX_ADDREXTBLKS) &&
3855 (index >= 1) && (index <= VL_MHSRV_PERBLK) ) {
3856 m_attrs.Mask = VLADDR_INDEX;
3857 m_attrs.index = (base * VL_MHSRV_PERBLK) + index;
3859 m_addrs.bulkaddrs_val = 0;
3860 m_addrs.bulkaddrs_len = 0;
3861 vcode = ubik_Call(VL_GetAddrsU, cstruct, 0,
3862 &m_attrs, &m_uuid, &m_unique, &m_nentries, &m_addrs);
3864 fprintf(STDERR,"vos: could not list the multi-homed server addresses\n");
3865 PrintError("",vcode);
3868 /* Print the list */
3869 m_addrp = (afs_int32 *)m_addrs.bulkaddrs_val;
3870 for (j=0; j<m_nentries; j++, m_addrp++) {
3871 *m_addrp = htonl(*m_addrp);
3874 printf("%s ", afs_inet_ntoa_r(*m_addrp,hoststr));
3876 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 *addrp = htonl(*addrp);
3895 printf("%s\n", afs_inet_ntoa_r(*addrp,hoststr));
3897 printf("%s\n", hostutil_GetNameByINet(*addrp));
3907 static ListAddrs(as)
3908 register struct cmd_syndesc *as;
3911 afs_int32 i, j, noresolve=0, printuuid=0;
3912 struct VLCallBack unused;
3913 afs_int32 nentries, *addrp;
3914 bulkaddrs addrs, m_addrs;
3915 ListAddrByAttributes m_attrs;
3916 afsUUID m_uuid, askuuid;
3917 afs_int32 m_unique, m_nentries, *m_addrp;
3918 afs_int32 base, index;
3920 memset(&m_attrs, 0, sizeof(struct ListAddrByAttributes));
3921 m_attrs.Mask = VLADDR_INDEX;
3923 memset(&m_addrs, 0, sizeof(bulkaddrs));
3924 memset(&askuuid, 0, sizeof(afsUUID));
3925 if (as->parms[0].items) {
3927 afsUUID_from_string(as->parms[0].items->data, &askuuid);
3928 m_attrs.Mask = VLADDR_UUID;
3929 m_attrs.uuid = askuuid;
3931 if (as->parms[1].items) {
3935 he = hostutil_GetHostByName((char*)as->parms[1].items->data);
3936 if (he == (struct hostent *)0) {
3938 "Can't get host info for '%s'\n",
3939 as->parms[1].items->data);
3942 memcpy(&saddr, he->h_addr, 4);
3943 m_attrs.Mask = VLADDR_IPADDR;
3944 m_attrs.ipaddr = ntohl(saddr);
3946 if (as->parms[2].items) {
3949 if (as->parms[3].items) {
3953 m_addrs.bulkaddrs_val = 0;
3954 m_addrs.bulkaddrs_len = 0;
3956 vcode = ubik_Call_New(VL_GetAddrs, cstruct, 0,
3957 0, 0, &m_unique, &nentries, &m_addrs);
3959 fprintf(STDERR,"vos: could not list the server addresses\n");
3960 PrintError("",vcode);
3965 m_addrs.bulkaddrs_val = 0;
3966 m_addrs.bulkaddrs_len = 0;
3971 vcode = ubik_Call_New(VL_GetAddrsU, cstruct, 0, &m_attrs, &m_uuid,
3972 &m_unique, &m_nentries, &m_addrs);
3973 if(vcode == VL_NOENT) {
3980 fprintf(STDERR,"vos: could not list the server addresses\n");
3981 PrintError("",vcode);
3985 print_addrs(&m_addrs, &m_uuid, m_nentries, printuuid, noresolve);
3988 if ((as->parms[1].items)||(as->parms[0].items)||(i>nentries))
3995 static LockEntry(as)
3996 register struct cmd_syndesc *as;
3999 afs_int32 avolid,vcode, err;
4001 avolid = vsu_GetVolumeID(as->parms[0].items->data, cstruct, &err);
4003 if (err) PrintError("", err);
4004 else fprintf(STDERR, "vos: can't find volume '%s'\n", as->parms[0].items->data);
4007 vcode = ubik_Call(VL_SetLock,cstruct, 0, avolid, -1, VLOP_DELETE);
4009 fprintf(STDERR,"Could not lock VLDB entry for volume %s\n",as->parms[0].items->data);
4010 PrintError("",vcode);
4013 fprintf(STDOUT,"Locked VLDB entry for volume %s\n",as->parms[0].items->data);
4017 PrintDiagnostics(astring, acode)
4021 if (acode == EACCES) {
4022 fprintf(STDERR,"You are not authorized to perform the 'vos %s' command (%d)\n",
4026 fprintf(STDERR,"Error in vos %s command.\n", astring);
4027 PrintError("", acode);
4033 static MyBeforeProc(as, arock)
4034 struct cmd_syndesc *as;
4036 register char *tcell;
4037 register afs_int32 code;
4038 register afs_int32 sauth;
4040 /* Initialize the ubik_client connection */
4041 rx_SetRxDeadTime(90);
4042 cstruct = (struct ubik_client *)0;
4046 if (as->parms[12].items) /* if -cell specified */
4047 tcell = as->parms[12].items->data;
4048 if(as->parms[14].items) /* -serverauth specified */
4050 if(as->parms[16].items) /* -crypt specified */
4052 if (code = vsu_ClientInit((as->parms[13].items != 0), confdir, tcell, sauth,
4053 &cstruct, UV_SetSecurity)) {
4054 fprintf(STDERR,"could not initialize VLDB library (code=%u) \n",code);
4058 if(as->parms[15].items) /* -verbose flag set */
4067 /* this sucks but it works for now.
4072 #include "AFS_component_version_number.c"
4077 register afs_int32 code;
4079 register struct cmd_syndesc *ts;
4081 #ifdef AFS_AIX32_ENV
4083 * The following signal action for AIX is necessary so that in case of a
4084 * crash (i.e. core is generated) we can include the user's data section
4085 * in the core dump. Unfortunately, by default, only a partial core is
4086 * generated which, in many cases, isn't too useful.
4088 struct sigaction nsa;
4090 sigemptyset(&nsa.sa_mask);
4091 nsa.sa_handler = SIG_DFL;
4092 nsa.sa_flags = SA_FULLDUMP;
4093 sigaction(SIGSEGV, &nsa, NULL);
4096 confdir = AFSDIR_CLIENT_ETC_DIRPATH;
4098 cmd_SetBeforeProc(MyBeforeProc, (char *) 0);
4100 ts = cmd_CreateSyntax("create", CreateVolume, 0, "create a new volume");
4101 cmd_AddParm(ts, "-server", CMD_SINGLE, 0, "machine name");
4102 cmd_AddParm(ts, "-partition", CMD_SINGLE, 0, "partition name");
4103 cmd_AddParm(ts, "-name", CMD_SINGLE, 0, "volume name");
4104 cmd_AddParm(ts, "-maxquota", CMD_SINGLE, CMD_OPTIONAL, "initial quota (KB)");
4106 cmd_AddParm(ts, "-minquota", CMD_SINGLE, CMD_OPTIONAL, "");
4110 ts = cmd_CreateSyntax("remove", DeleteVolume, 0, "delete a volume");
4111 cmd_AddParm(ts, "-server", CMD_SINGLE, CMD_OPTIONAL, "machine name");
4112 cmd_AddParm(ts, "-partition", CMD_SINGLE, CMD_OPTIONAL, "partition name");
4113 cmd_AddParm(ts, "-id", CMD_SINGLE, 0, "volume name or ID");
4117 ts = cmd_CreateSyntax("move", MoveVolume, 0, "move a volume");
4118 cmd_AddParm(ts, "-id", CMD_SINGLE, 0, "volume name or ID");
4119 cmd_AddParm(ts, "-fromserver", CMD_SINGLE, 0, "machine name on source");
4120 cmd_AddParm(ts, "-frompartition", CMD_SINGLE, 0, "partition name on source");
4121 cmd_AddParm(ts, "-toserver", CMD_SINGLE, 0, "machine name on destination");
4122 cmd_AddParm(ts, "-topartition", CMD_SINGLE, 0, "partition name on destination");
4125 ts = cmd_CreateSyntax("backup", BackupVolume, 0, "make backup of a volume");
4126 cmd_AddParm(ts, "-id", CMD_SINGLE, 0, "volume name or ID");
4129 ts = cmd_CreateSyntax("release", ReleaseVolume, 0, "release a volume");
4130 cmd_AddParm(ts, "-id", CMD_SINGLE, 0, "volume name or ID");
4131 cmd_AddParm(ts, "-force", CMD_FLAG, CMD_OPTIONAL, "force a complete release");
4134 ts = cmd_CreateSyntax("dump", DumpVolume, 0, "dump a volume");
4135 cmd_AddParm(ts, "-id", CMD_SINGLE, 0, "volume name or ID");
4136 cmd_AddParm(ts, "-time", CMD_SINGLE, CMD_OPTIONAL, "dump from time");
4137 cmd_AddParm(ts, "-file", CMD_SINGLE, CMD_OPTIONAL, "dump file");
4138 cmd_AddParm(ts, "-server", CMD_SINGLE, CMD_OPTIONAL, "server");
4139 cmd_AddParm(ts, "-partition", CMD_SINGLE, CMD_OPTIONAL, "partition");
4142 ts = cmd_CreateSyntax("restore", RestoreVolume, 0, "restore a volume");
4143 cmd_AddParm(ts, "-server", CMD_SINGLE, 0, "machine name");
4144 cmd_AddParm(ts, "-partition", CMD_SINGLE, 0, "partition name");
4145 cmd_AddParm(ts, "-name", CMD_SINGLE, 0, "name of volume to be restored");
4146 cmd_AddParm(ts, "-file", CMD_SINGLE,CMD_OPTIONAL, "dump file");
4147 cmd_AddParm(ts, "-id", CMD_SINGLE,CMD_OPTIONAL, "volume ID");
4148 cmd_AddParm(ts, "-overwrite", CMD_SINGLE,CMD_OPTIONAL, "abort | full | incremental");
4149 cmd_AddParm(ts, "-offline", CMD_FLAG, CMD_OPTIONAL,
4150 "leave restored volume offline");
4151 cmd_AddParm(ts, "-readonly", CMD_FLAG, CMD_OPTIONAL,
4152 "make restored volume read-only");
4155 ts = cmd_CreateSyntax("unlock", LockReleaseCmd, 0, "release lock on VLDB entry for a volume");
4156 cmd_AddParm(ts, "-id", CMD_SINGLE, 0, "volume name or ID");
4159 ts = cmd_CreateSyntax("changeloc", ChangeLocation, 0, "change an RW volume's location in the VLDB");
4160 cmd_AddParm(ts, "-server", CMD_SINGLE, 0, "machine name for new location");
4161 cmd_AddParm(ts, "-partition", CMD_SINGLE, 0, "partition name for new location");
4162 cmd_AddParm(ts, "-id", CMD_SINGLE, 0, "volume name or ID");
4165 ts = cmd_CreateSyntax("addsite", AddSite, 0, "add a replication site");
4166 cmd_AddParm(ts, "-server", CMD_SINGLE, 0, "machine name for new site");
4167 cmd_AddParm(ts, "-partition", CMD_SINGLE, 0, "partition name for new site");
4168 cmd_AddParm(ts, "-id", CMD_SINGLE, 0, "volume name or ID");
4171 ts = cmd_CreateSyntax("remsite", RemoveSite, 0, "remove a replication site");
4172 cmd_AddParm(ts, "-server", CMD_SINGLE, 0, "machine name");
4173 cmd_AddParm(ts, "-partition", CMD_SINGLE, 0, "partition name");
4174 cmd_AddParm(ts, "-id", CMD_SINGLE, 0, "volume name or ID");
4177 ts = cmd_CreateSyntax("listpart", ListPartitions, 0, "list partitions");
4178 cmd_AddParm(ts, "-server", CMD_SINGLE, 0, "machine name");
4181 ts = cmd_CreateSyntax("listvol", ListVolumes, 0, "list volumes on server (bypass VLDB)");
4182 cmd_AddParm(ts, "-server", CMD_SINGLE, 0, "machine name");
4183 cmd_AddParm(ts, "-partition", CMD_SINGLE,CMD_OPTIONAL, "partition name");
4184 cmd_AddParm(ts, "-fast", CMD_FLAG, CMD_OPTIONAL, "minimal listing");
4185 cmd_AddParm(ts, "-long", CMD_FLAG, CMD_OPTIONAL,
4186 "list all normal volume fields");
4187 cmd_AddParm(ts, "-quiet", CMD_FLAG, CMD_OPTIONAL, "generate minimal information");
4188 cmd_AddParm(ts, "-extended", CMD_FLAG, CMD_OPTIONAL,
4189 "list extended volume fields");
4190 #ifdef FULL_LISTVOL_SWITCH
4191 cmd_AddParm(ts, "-format", CMD_FLAG, CMD_OPTIONAL,
4192 "machine readable format");
4193 #endif /* FULL_LISTVOL_SWITCH */
4196 ts = cmd_CreateSyntax("syncvldb", SyncVldb, 0, "synchronize VLDB with server");
4197 cmd_AddParm(ts, "-server", CMD_SINGLE, CMD_OPTIONAL, "machine name");
4198 cmd_AddParm(ts, "-partition", CMD_SINGLE,CMD_OPTIONAL , "partition name");
4199 cmd_AddParm(ts, "-volume", CMD_SINGLE,CMD_OPTIONAL , "volume name or ID");
4202 ts = cmd_CreateSyntax("syncserv", SyncServer, 0, "synchronize server with VLDB");
4203 cmd_AddParm(ts, "-server", CMD_SINGLE, 0, "machine name");
4204 cmd_AddParm(ts, "-partition", CMD_SINGLE,CMD_OPTIONAL , "partition name");
4207 ts = cmd_CreateSyntax("examine", ExamineVolume, 0, "everything about the volume");
4208 cmd_AddParm(ts, "-id", CMD_SINGLE, 0, "volume name or ID");
4209 cmd_AddParm(ts, "-extended", CMD_FLAG, CMD_OPTIONAL,
4210 "list extended volume fields");
4211 #ifdef FULL_LISTVOL_SWITCH
4212 cmd_AddParm(ts, "-format", CMD_FLAG, CMD_OPTIONAL,
4213 "machine readable format");
4214 #endif /* FULL_LISTVOL_SWITCH */
4216 cmd_CreateAlias (ts, "volinfo");
4218 ts = cmd_CreateSyntax("setfields", SetFields, 0, "change volume info fields");
4219 cmd_AddParm(ts, "-id", CMD_SINGLE, 0, "volume name or ID");
4220 cmd_AddParm(ts, "-maxquota", CMD_SINGLE, CMD_OPTIONAL, "quota (KB)");
4221 cmd_AddParm(ts, "-clearuse", CMD_FLAG, CMD_OPTIONAL, "clear dayUse");
4224 ts = cmd_CreateSyntax("offline", volOffline, 0, (char *) CMD_HIDDEN);
4225 cmd_AddParm(ts, "-server", CMD_SINGLE, 0, "server name");
4226 cmd_AddParm(ts, "-partition", CMD_SINGLE, 0, "partition name");
4227 cmd_AddParm(ts, "-id", CMD_SINGLE, 0, "volume name or ID");
4228 cmd_AddParm(ts, "-sleep", CMD_SINGLE, CMD_OPTIONAL, "seconds to sleep");
4229 cmd_AddParm(ts, "-busy", CMD_FLAG, CMD_OPTIONAL, "busy volume");
4232 ts = cmd_CreateSyntax("online", volOnline, 0, (char *) CMD_HIDDEN);
4233 cmd_AddParm(ts, "-server", CMD_SINGLE, 0, "server name");
4234 cmd_AddParm(ts, "-partition", CMD_SINGLE, 0, "partition name");
4235 cmd_AddParm(ts, "-id", CMD_SINGLE, 0, "volume name or ID");
4238 ts = cmd_CreateSyntax("zap", VolumeZap, 0, "delete the volume, don't bother with VLDB");
4239 cmd_AddParm(ts, "-server", CMD_SINGLE, 0, "machine name");
4240 cmd_AddParm(ts, "-partition", CMD_SINGLE, 0, "partition name");
4241 cmd_AddParm(ts, "-id", CMD_SINGLE, 0, "volume ID");
4242 cmd_AddParm(ts, "-force", CMD_FLAG, CMD_OPTIONAL, "force deletion of bad volumes");
4243 cmd_AddParm(ts, "-backup", CMD_FLAG, CMD_OPTIONAL, "also delete backup volume if one is found");
4246 ts = cmd_CreateSyntax("status", VolserStatus, 0, "report on volser status");
4247 cmd_AddParm(ts, "-server", CMD_SINGLE, 0, "machine name");
4250 ts = cmd_CreateSyntax("rename", RenameVolume, 0, "rename a volume");
4251 cmd_AddParm(ts, "-oldname", CMD_SINGLE, 0, "old volume name ");
4252 cmd_AddParm(ts, "-newname", CMD_SINGLE, 0, "new volume name ");
4255 ts = cmd_CreateSyntax("listvldb", ListVLDB, 0, "list volumes in the VLDB");
4256 cmd_AddParm(ts, "-name", CMD_SINGLE,CMD_OPTIONAL, "volume name or ID");
4257 cmd_AddParm(ts, "-server", CMD_SINGLE,CMD_OPTIONAL, "machine name");
4258 cmd_AddParm(ts, "-partition", CMD_SINGLE,CMD_OPTIONAL, "partition name");
4259 cmd_AddParm(ts, "-locked", CMD_FLAG, CMD_OPTIONAL, "locked volumes only");
4260 cmd_AddParm(ts, "-quiet", CMD_FLAG, CMD_OPTIONAL, "generate minimal information");
4261 cmd_AddParm(ts, "-nosort", CMD_FLAG, CMD_OPTIONAL, "do not alphabetically sort the volume names");
4264 ts = cmd_CreateSyntax("backupsys", BackSys, 0, "en masse backups");
4265 cmd_AddParm(ts, "-prefix", CMD_LIST,CMD_OPTIONAL, "common prefix on volume(s)");
4266 cmd_AddParm(ts, "-server", CMD_SINGLE,CMD_OPTIONAL, "machine name");
4267 cmd_AddParm(ts, "-partition", CMD_SINGLE,CMD_OPTIONAL, "partition name");
4268 cmd_AddParm(ts, "-exclude", CMD_FLAG, CMD_OPTIONAL, "exclude common prefix volumes");
4269 cmd_AddParm(ts, "-xprefix", CMD_LIST, CMD_OPTIONAL, "negative prefix on volume(s)");
4270 cmd_AddParm(ts, "-dryrun", CMD_FLAG, CMD_OPTIONAL, "no action");
4273 ts = cmd_CreateSyntax("delentry", DeleteEntry, 0, "delete VLDB entry for a volume");
4274 cmd_AddParm(ts, "-id", CMD_LIST, CMD_OPTIONAL, "volume name or ID");
4275 cmd_AddParm(ts, "-prefix", CMD_SINGLE,CMD_OPTIONAL, "prefix of the volume whose VLDB entry is to be deleted");
4276 cmd_AddParm(ts, "-server", CMD_SINGLE,CMD_OPTIONAL, "machine name");
4277 cmd_AddParm(ts, "-partition", CMD_SINGLE,CMD_OPTIONAL, "partition name");
4278 cmd_AddParm(ts, "-noexecute", CMD_FLAG,CMD_OPTIONAL|CMD_HIDE, "no execute");
4281 ts = cmd_CreateSyntax("partinfo", PartitionInfo, 0, "list partition information");
4282 cmd_AddParm(ts, "-server", CMD_SINGLE, 0, "machine name");
4283 cmd_AddParm(ts, "-partition", CMD_SINGLE,CMD_OPTIONAL, "partition name");
4286 ts = cmd_CreateSyntax("unlockvldb", UnlockVLDB, 0, "unlock all the locked entries in the VLDB");
4287 cmd_AddParm(ts, "-server", CMD_SINGLE,CMD_OPTIONAL, "machine name");
4288 cmd_AddParm(ts, "-partition", CMD_SINGLE,CMD_OPTIONAL, "partition name");
4291 ts = cmd_CreateSyntax("lock", LockEntry, 0, "lock VLDB entry for a volume");
4292 cmd_AddParm(ts, "-id", CMD_SINGLE, 0, "volume name or ID");
4295 ts = cmd_CreateSyntax("changeaddr", ChangeAddr, 0, "change the IP address of a file server");
4296 cmd_AddParm(ts, "-oldaddr", CMD_SINGLE, 0, "original IP address");
4297 cmd_AddParm(ts, "-newaddr", CMD_SINGLE, CMD_OPTIONAL, "new IP address");
4298 cmd_AddParm(ts, "-remove", CMD_FLAG, CMD_OPTIONAL, "remove the IP address from the VLDB");
4301 ts = cmd_CreateSyntax("listaddrs", ListAddrs, 0, "list the IP address of all file servers registered in the VLDB");
4302 cmd_AddParm(ts, "-uuid", CMD_SINGLE, CMD_OPTIONAL, "uuid of server");
4303 cmd_AddParm(ts, "-host", CMD_SINGLE, CMD_OPTIONAL, "address of host");
4304 cmd_AddParm(ts, "-noresolve", CMD_FLAG, CMD_OPTIONAL, "don't resolve addresses");
4305 cmd_AddParm(ts, "-printuuid", CMD_FLAG, CMD_OPTIONAL, "print uuid of hosts");
4308 code = cmd_Dispatch(argc, argv);
4310 /* Shut down the ubik_client and rx connections */
4312 ubik_ClientDestroy (cstruct);