2 * Copyright 2000, International Business Machines Corporation and others.
5 * This software has been released under the terms of the IBM Public
6 * License. For details, see the LICENSE file in the top-level source
7 * directory or online at http://www.openafs.org/dl/license10.html
10 #include <afsconfig.h>
11 #include <afs/param.h>
15 #include <sys/types.h>
24 #include <netinet/in.h>
28 #include <sys/statfs.h>
44 #include <rx/rx_globals.h>
46 #include <afs/vlserver.h>
48 #include <afs/cellconfig.h>
50 #include <afs/afsutil.h>
52 #include <afs/afsint.h>
74 struct hostent *hostutil_GetHostByName(register char *ahost);
76 #define COMMONPARMS cmd_Seek(ts, 12);\
77 cmd_AddParm(ts, "-cell", CMD_SINGLE, CMD_OPTIONAL, "cell name");\
78 cmd_AddParm(ts, "-noauth", CMD_FLAG, CMD_OPTIONAL, "don't authenticate");\
79 cmd_AddParm(ts, "-localauth",CMD_FLAG,CMD_OPTIONAL,"use server tickets");\
80 cmd_AddParm(ts, "-verbose", CMD_FLAG, CMD_OPTIONAL, "verbose");\
81 cmd_AddParm(ts, "-encrypt", CMD_FLAG, CMD_OPTIONAL, "encrypt commands");\
83 #define ERROR_EXIT(code) {error=(code); goto error_exit;}
87 struct rx_connection *tconn;
89 extern struct ubik_client *cstruct;
91 extern struct rx_connection *UV_Bind();
92 extern int UV_SetSecurity();
93 extern int UV_SetVolumeInfo();
94 extern int vsu_SetCrypt();
96 extern VL_ReleaseLock();
97 extern VL_DeleteEntry();
98 extern VL_ListEntry();
100 extern VL_GetAddrsU();
101 extern VL_ChangeAddr();
103 extern int vsu_ExtractName();
105 extern int MapPartIdIntoName();
106 extern int MapHostToNetwork();
107 extern int MapNetworkToHost();
108 extern void EnumerateEntry();
109 extern void SubEnumerateEntry();
112 static struct tqHead busyHead, notokHead;
114 static void qInit(ahead)
115 struct tqHead *ahead;
117 memset((char *)ahead, 0, sizeof(struct tqHead));
122 static void qPut(ahead,volid)
123 struct tqHead *ahead;
128 elem = (struct tqElem *)malloc(sizeof(struct tqElem));
129 elem->next = ahead->next;
136 static void qGet(ahead,volid)
137 struct tqHead *ahead;
142 if(ahead->count <= 0) return;
143 *volid = ahead->next->volid;
145 ahead->next = tmp->next;
151 /* returns 1 if <filename> exists else 0 */
152 static FileExists(filename)
159 code = usd_Open(filename, USD_OPEN_RDONLY, 0, &ufd);
163 code = USD_IOCTL(ufd, USD_IOCTL_GETSIZE, &size);
171 /* returns 1 if <name> doesnot end in .readonly or .backup, else 0 */
172 static VolNameOK(name)
178 total = strlen(name);
179 if(!strcmp(&name[total - 9],".readonly")) {
182 else if(!strcmp(&name[total - 7 ],".backup")) {
190 /* return 1 if name is a number else 0 */
191 static IsNumeric(name)
200 for(i = 0; i < len ; i++){
201 if(*ptr < '0' || *ptr > '9'){
215 * Parse a server name/address and return the address in HOST BYTE order
217 afs_int32 GetServer(aname)
219 register struct hostent *th;
222 register afs_int32 code;
223 char hostname[MAXHOSTCHARS];
225 code = sscanf(aname, "%d.%d.%d.%d", &b1, &b2, &b3, &b4);
227 addr = (b1<<24) | (b2<<16) | (b3<<8) | b4;
228 addr = ntohl(addr); /* convert to host order */
230 th = gethostbyname(aname);
232 memcpy(&addr, th->h_addr, sizeof(addr));
235 if (addr == htonl(0x7f000001)) { /* local host */
236 code = gethostname(hostname, MAXHOSTCHARS);
238 th = gethostbyname(hostname); /* returns host byte order */
240 memcpy(&addr, th->h_addr, sizeof(addr));
246 afs_int32 GetVolumeType(aname)
250 if(!strcmp(aname,"ro"))
252 else if(!strcmp(aname, "rw"))
254 else if(!strcmp(aname,"bk"))
259 int IsPartValid(partId, server, code)
260 afs_int32 server, partId,*code;
263 struct partList dummyPartList;
271 *code = UV_ListPartitions(server,&dummyPartList, &cnt);
272 if(*code) return success;
273 for(i = 0 ; i < cnt ; i++) {
274 if(dummyPartList.partFlags[i] & PARTVALID)
275 if(dummyPartList.partId[i] == partId)
283 /*sends the contents of file associated with <fd> and <blksize> to Rx Stream
284 * associated with <call> */
285 SendFile(ufd, call, blksize)
287 register struct rx_call *call;
290 char *buffer = (char*) 0;
295 buffer = (char *)malloc(blksize);
297 fprintf(STDERR,"malloc failed\n");
301 while (!error && !done) {
302 #ifndef AFS_NT40_ENV /* NT csn't select on non-socket fd's */
305 FD_SET((int)(ufd->handle), &in);
306 /* don't timeout if read blocks */
307 IOMGR_Select(((int)(ufd->handle))+1, &in, 0, 0, 0);
309 error = USD_READ(ufd, buffer, blksize, &nbytes);
311 fprintf(STDERR, "File system read failed\n");
318 if (rx_Write(call, buffer, nbytes) != nbytes){
323 if (buffer) free(buffer);
327 /* function invoked by UV_RestoreVolume, reads the data from rx_trx_stream and
328 * writes it out to the volume. */
329 afs_int32 WriteData(call,rock)
330 struct rx_call *call;
336 afs_int32 error,code;
342 if(!filename || !*filename) {
343 usd_StandardInput(&ufd);
347 code = usd_Open(filename, USD_OPEN_RDONLY, 0, &ufd);
350 code = USD_IOCTL(ufd, USD_IOCTL_GETBLKSIZE, &blksize);
353 fprintf(STDERR,"Could not access file '%s'\n", filename);
358 code = SendFile(ufd,call,blksize);
365 code = USD_CLOSE(ufd);
367 fprintf(STDERR,"Could not close dump file %s\n",
368 (filename && *filename)?filename:"STDOUT");
369 if(!error) error = code;
375 /* Receive data from <call> stream into file associated
376 * with <fd> <blksize>
378 int ReceiveFile(ufd, call, blksize)
380 struct rx_call *call;
385 afs_uint32 bytesleft, w;
388 buffer = (char *)malloc(blksize);
390 fprintf(STDERR,"memory allocation failed\n");
394 while ((bytesread=rx_Read(call,buffer,blksize)) > 0) {
395 for (bytesleft=bytesread; bytesleft; bytesleft-=w) {
396 #ifndef AFS_NT40_ENV /* NT csn't select on non-socket fd's */
399 FD_SET((int)(ufd->handle), &out);
400 /* don't timeout if write blocks */
401 IOMGR_Select(((int)(ufd->handle))+1, 0, &out, 0, 0);
403 error = USD_WRITE(ufd, &buffer[bytesread-bytesleft], bytesleft, &w);
405 fprintf(STDERR,"File system write failed\n");
412 if (buffer) free(buffer);
416 afs_int32 DumpFunction(call, filename)
417 struct rx_call *call;
420 usd_handle_t ufd; /* default is to stdout */
421 afs_int32 error=0, code;
426 /* Open the output file */
427 if (!filename || !*filename) {
428 usd_StandardOutput(&ufd);
432 code = usd_Open(filename, USD_OPEN_CREATE|USD_OPEN_RDWR, 0666, &ufd);
436 code = USD_IOCTL(ufd, USD_IOCTL_SETSIZE, &size);
439 code = USD_IOCTL(ufd, USD_IOCTL_GETBLKSIZE, &blksize);
442 fprintf(STDERR, "Could not create file '%s'\n", filename);
443 ERROR_EXIT(VOLSERBADOP);
447 code = ReceiveFile(ufd, call, blksize);
448 if (code) ERROR_EXIT(code);
451 /* Close the output file */
453 code = USD_CLOSE(ufd);
455 fprintf(STDERR,"Could not close dump file %s\n",
456 (filename && *filename)?filename:"STDIN");
457 if (!error) error = code;
464 static void DisplayFormat(pntr,server,part,totalOK,totalNotOK,totalBusy,fast,longlist,disp)
466 afs_int32 server,part;
467 int *totalOK,*totalNotOK,*totalBusy;
468 int fast,longlist, disp;
473 fprintf(STDOUT,"%-10u\n",pntr->volid);
476 if(pntr->status == VOK){
477 fprintf(STDOUT,"%-32s ",pntr->name);
478 fprintf(STDOUT,"%10u ",pntr->volid);
479 if(pntr->type == 0) fprintf(STDOUT,"RW ");
480 if(pntr->type == 1) fprintf(STDOUT,"RO ");
481 if(pntr->type == 2) fprintf(STDOUT,"BK ");
482 fprintf(STDOUT,"%10d K ",pntr->size);
483 if(pntr->inUse == 1) {
484 fprintf(STDOUT,"On-line");
487 fprintf(STDOUT,"Off-line");
490 if(pntr->needsSalvaged == 1) fprintf(STDOUT,"**needs salvage**");
491 fprintf(STDOUT,"\n");
492 MapPartIdIntoName(part,pname);
493 fprintf(STDOUT," %s %s \n",hostutil_GetNameByINet(server),pname);
494 fprintf(STDOUT," RWrite %10u ROnly %10u Backup %10u \n", pntr->parentID,pntr->cloneID, pntr->backupID);
495 fprintf(STDOUT," MaxQuota %10d K \n",pntr->maxquota);
496 fprintf(STDOUT," Creation %s",
497 ctime((time_t *)&pntr->creationDate));
498 #ifdef FULL_LISTVOL_SWITCH
499 fprintf(STDOUT," Copy %s",
500 ctime((time_t *)&pntr->copyDate));
501 if(!pntr->backupDate)
502 fprintf(STDOUT," Backup Never\n");
504 fprintf(STDOUT," Backup %s",
505 ctime((time_t *)&pntr->backupDate));
506 if (pntr->accessDate)
507 fprintf(STDOUT," Last Access %s",
508 ctime((time_t *)&pntr->accessDate));
510 if(pntr->updateDate < pntr->creationDate)
511 fprintf(STDOUT," Last Update %s",
512 ctime((time_t *)&pntr->creationDate));
514 fprintf(STDOUT," Last Update %s",
515 ctime((time_t *)&pntr->updateDate));
516 fprintf(STDOUT, " %d accesses in the past day (i.e., vnode references)\n",
519 else if (pntr->status == VBUSY) {
521 qPut(&busyHead,pntr->volid);
522 if (disp) fprintf(STDOUT,"**** Volume %u is busy ****\n",pntr->volid);
526 qPut(¬okHead,pntr->volid);
527 if (disp) fprintf(STDOUT,"**** Could not attach volume %u ****\n",pntr->volid);
529 fprintf(STDOUT,"\n");
531 else {/* default listing */
532 if(pntr->status == VOK){
533 fprintf(STDOUT,"%-32s ",pntr->name);
534 fprintf(STDOUT,"%10u ",pntr->volid);
535 if(pntr->type == 0) fprintf(STDOUT,"RW ");
536 if(pntr->type == 1) fprintf(STDOUT,"RO ");
537 if(pntr->type == 2) fprintf(STDOUT,"BK ");
538 fprintf(STDOUT,"%10d K ",pntr->size);
539 if(pntr->inUse == 1) {
540 fprintf(STDOUT,"On-line");
543 fprintf(STDOUT,"Off-line");
546 if(pntr->needsSalvaged == 1) fprintf(STDOUT,"**needs salvage**");
547 fprintf(STDOUT,"\n");
549 else if (pntr->status == VBUSY) {
551 qPut(&busyHead,pntr->volid);
552 if (disp) fprintf(STDOUT,"**** Volume %u is busy ****\n",pntr->volid);
556 qPut(¬okHead,pntr->volid);
557 if (disp) fprintf(STDOUT,"**** Could not attach volume %u ****\n",pntr->volid);
562 /*------------------------------------------------------------------------
563 * PRIVATE XDisplayFormat
566 * Display the contents of one extended volume info structure.
569 * a_xInfoP : Ptr to extended volume info struct to print.
570 * a_servID : Server ID to print.
571 * a_partID : Partition ID to print.
572 * a_totalOKP : Ptr to total-OK counter.
573 * a_totalNotOKP : Ptr to total-screwed counter.
574 * a_totalBusyP : Ptr to total-busy counter.
575 * a_fast : Fast listing?
576 * a_int32 : Int32 listing?
577 * a_showProblems : Show volume problems?
583 * Nothing interesting.
587 *------------------------------------------------------------------------*/
589 static void XDisplayFormat(a_xInfoP, a_servID, a_partID, a_totalOKP,
590 a_totalNotOKP, a_totalBusyP, a_fast, a_int32,
592 volintXInfo *a_xInfoP;
610 fprintf(STDOUT, "%-10u\n", a_xInfoP->volid);
615 * Fully-detailed listing.
617 if (a_xInfoP->status == VOK) {
619 * Volume's status is OK - all the fields are valid.
621 fprintf(STDOUT, "%-32s ", a_xInfoP->name);
622 fprintf(STDOUT, "%10u ", a_xInfoP->volid);
623 if (a_xInfoP->type == 0) fprintf(STDOUT,"RW ");
624 if (a_xInfoP->type == 1) fprintf(STDOUT,"RO ");
625 if (a_xInfoP->type == 2) fprintf(STDOUT,"BK ");
626 fprintf(STDOUT, "%10d K used ", a_xInfoP->size);
627 fprintf(STDOUT, "%d files ", a_xInfoP->filecount);
628 if(a_xInfoP->inUse == 1) {
629 fprintf(STDOUT, "On-line");
633 fprintf(STDOUT, "Off-line");
636 fprintf(STDOUT, "\n");
637 MapPartIdIntoName(a_partID, pname);
638 fprintf(STDOUT, " %s %s \n",
639 hostutil_GetNameByINet(a_servID),
641 fprintf(STDOUT, " RWrite %10u ROnly %10u Backup %10u \n",
642 a_xInfoP->parentID, a_xInfoP->cloneID, a_xInfoP->backupID);
643 fprintf(STDOUT, " MaxQuota %10d K \n",
645 fprintf(STDOUT, " Creation %s",
646 ctime((time_t *)&a_xInfoP->creationDate));
647 #ifdef FULL_LISTVOL_SWITCH
648 fprintf(STDOUT," Copy %s",
649 ctime((time_t *)&a_xInfoP->copyDate));
650 if(!a_xInfoP->backupDate)
651 fprintf(STDOUT," Backup Never\n");
653 fprintf(STDOUT," Backup %s",
654 ctime((time_t *)&a_xInfoP->backupDate));
655 if (a_xInfoP->accessDate)
656 fprintf(STDOUT," Last Access %s",
657 ctime((time_t *)&a_xInfoP->accessDate));
659 if (a_xInfoP->updateDate < a_xInfoP->creationDate)
660 fprintf(STDOUT, " Last Update %s",
661 ctime((time_t *)&a_xInfoP->creationDate));
663 fprintf(STDOUT, " Last Update %s",
664 ctime((time_t *)&a_xInfoP->updateDate));
665 fprintf(STDOUT, " %d accesses in the past day (i.e., vnode references)\n",
669 * Print all the read/write and authorship stats.
672 "\n Raw Read/Write Stats\n");
674 " |-------------------------------------------|\n");
676 " | Same Network | Diff Network |\n");
678 " |----------|----------|----------|----------|\n");
680 " | Total | Auth | Total | Auth |\n");
682 " |----------|----------|----------|----------|\n");
684 "Reads | %8d | %8d | %8d | %8d |\n",
685 a_xInfoP->stat_reads[VOLINT_STATS_SAME_NET],
686 a_xInfoP->stat_reads[VOLINT_STATS_SAME_NET_AUTH],
687 a_xInfoP->stat_reads[VOLINT_STATS_DIFF_NET],
688 a_xInfoP->stat_reads[VOLINT_STATS_DIFF_NET_AUTH]);
690 "Writes | %8d | %8d | %8d | %8d |\n",
691 a_xInfoP->stat_writes[VOLINT_STATS_SAME_NET],
692 a_xInfoP->stat_writes[VOLINT_STATS_SAME_NET_AUTH],
693 a_xInfoP->stat_writes[VOLINT_STATS_DIFF_NET],
694 a_xInfoP->stat_writes[VOLINT_STATS_DIFF_NET_AUTH]);
696 " |-------------------------------------------|\n\n");
699 " Writes Affecting Authorship\n");
701 " |-------------------------------------------|\n");
703 " | File Authorship | Directory Authorship|\n");
705 " |----------|----------|----------|----------|\n");
707 " | Same | Diff | Same | Diff |\n");
709 " |----------|----------|----------|----------|\n");
711 "0-60 sec | %8d | %8d | %8d | %8d |\n",
712 a_xInfoP->stat_fileSameAuthor[VOLINT_STATS_TIME_IDX_0],
713 a_xInfoP->stat_fileDiffAuthor[VOLINT_STATS_TIME_IDX_0],
714 a_xInfoP->stat_dirSameAuthor[VOLINT_STATS_TIME_IDX_0],
715 a_xInfoP->stat_dirDiffAuthor[VOLINT_STATS_TIME_IDX_0]);
717 "1-10 min | %8d | %8d | %8d | %8d |\n",
718 a_xInfoP->stat_fileSameAuthor[VOLINT_STATS_TIME_IDX_1],
719 a_xInfoP->stat_fileDiffAuthor[VOLINT_STATS_TIME_IDX_1],
720 a_xInfoP->stat_dirSameAuthor[VOLINT_STATS_TIME_IDX_1],
721 a_xInfoP->stat_dirDiffAuthor[VOLINT_STATS_TIME_IDX_1]);
723 "10min-1hr | %8d | %8d | %8d | %8d |\n",
724 a_xInfoP->stat_fileSameAuthor[VOLINT_STATS_TIME_IDX_2],
725 a_xInfoP->stat_fileDiffAuthor[VOLINT_STATS_TIME_IDX_2],
726 a_xInfoP->stat_dirSameAuthor[VOLINT_STATS_TIME_IDX_2],
727 a_xInfoP->stat_dirDiffAuthor[VOLINT_STATS_TIME_IDX_2]);
729 "1hr-1day | %8d | %8d | %8d | %8d |\n",
730 a_xInfoP->stat_fileSameAuthor[VOLINT_STATS_TIME_IDX_3],
731 a_xInfoP->stat_fileDiffAuthor[VOLINT_STATS_TIME_IDX_3],
732 a_xInfoP->stat_dirSameAuthor[VOLINT_STATS_TIME_IDX_3],
733 a_xInfoP->stat_dirDiffAuthor[VOLINT_STATS_TIME_IDX_3]);
735 "1day-1wk | %8d | %8d | %8d | %8d |\n",
736 a_xInfoP->stat_fileSameAuthor[VOLINT_STATS_TIME_IDX_4],
737 a_xInfoP->stat_fileDiffAuthor[VOLINT_STATS_TIME_IDX_4],
738 a_xInfoP->stat_dirSameAuthor[VOLINT_STATS_TIME_IDX_4],
739 a_xInfoP->stat_dirDiffAuthor[VOLINT_STATS_TIME_IDX_4]);
741 "> 1wk | %8d | %8d | %8d | %8d |\n",
742 a_xInfoP->stat_fileSameAuthor[VOLINT_STATS_TIME_IDX_5],
743 a_xInfoP->stat_fileDiffAuthor[VOLINT_STATS_TIME_IDX_5],
744 a_xInfoP->stat_dirSameAuthor[VOLINT_STATS_TIME_IDX_5],
745 a_xInfoP->stat_dirDiffAuthor[VOLINT_STATS_TIME_IDX_5]);
747 " |-------------------------------------------|\n");
748 } /*Volume status OK*/
750 if (a_xInfoP->status == VBUSY) {
752 qPut(&busyHead, a_xInfoP->volid);
754 fprintf(STDOUT, "**** Volume %u is busy ****\n",
759 qPut(¬okHead, a_xInfoP->volid);
761 fprintf(STDOUT, "**** Could not attach volume %u ****\n",
764 fprintf(STDOUT,"\n");
770 if (a_xInfoP->status == VOK) {
771 fprintf(STDOUT, "%-32s ", a_xInfoP->name);
772 fprintf(STDOUT, "%10u ", a_xInfoP->volid);
773 if (a_xInfoP->type == 0) fprintf(STDOUT, "RW ");
774 if (a_xInfoP->type == 1) fprintf(STDOUT, "RO ");
775 if (a_xInfoP->type == 2) fprintf(STDOUT, "BK ");
776 fprintf(STDOUT, "%10d K ", a_xInfoP->size);
777 if(a_xInfoP->inUse == 1) {
778 fprintf(STDOUT, "On-line");
781 fprintf(STDOUT, "Off-line");
784 fprintf(STDOUT, "\n");
787 if (a_xInfoP->status == VBUSY) {
789 qPut(&busyHead, a_xInfoP->volid);
791 fprintf(STDOUT,"**** Volume %u is busy ****\n",
796 qPut(¬okHead, a_xInfoP->volid);
798 fprintf(STDOUT,"**** Could not attach volume %u ****\n",
801 } /*Default listing*/
804 #ifdef FULL_LISTVOL_SWITCH
805 static void DisplayFormat2(server, partition, pntr)
806 long server, partition;
809 static long server_cache = -1, partition_cache = -1;
810 static char hostname[256],
814 if (server != server_cache) {
818 strcpy(hostname, hostutil_GetNameByINet(server));
819 strcpy(address, inet_ntoa(s));
820 server_cache = server;
822 if (partition != partition_cache) {
823 MapPartIdIntoName(partition, pname);
824 partition_cache = partition;
826 fprintf(STDOUT, "name\t\t%s\n", pntr->name);
827 fprintf(STDOUT, "id\t\t%lu\n", pntr->volid);
828 fprintf(STDOUT, "serv\t\t%s\t%s\n", address, hostname);
829 fprintf(STDOUT, "part\t\t%s\n", pname);
830 switch (pntr->status) {
832 fprintf(STDOUT, "status\t\tOK\n");
835 fprintf(STDOUT, "status\t\tBUSY\n");
838 fprintf(STDOUT, "status\t\tUNATTACHABLE\n");
841 fprintf(STDOUT, "backupID\t%lu\n", pntr->backupID);
842 fprintf(STDOUT, "parentID\t%lu\n", pntr->parentID);
843 fprintf(STDOUT, "cloneID\t\t%lu\n", pntr->cloneID);
844 fprintf(STDOUT, "inUse\t\t%s\n", pntr->inUse ? "Y" : "N");
845 fprintf(STDOUT, "needsSalvaged\t%s\n", pntr->needsSalvaged ? "Y" : "N");
846 /* 0xD3 is from afs/volume.h since I had trouble including the file */
847 fprintf(STDOUT, "destroyMe\t%s\n", pntr->destroyMe == 0xD3 ? "Y" : "N");
848 switch (pntr->type) {
850 fprintf(STDOUT, "type\t\tRW\n");
853 fprintf(STDOUT, "type\t\tRO\n");
856 fprintf(STDOUT, "type\t\tBK\n");
859 fprintf(STDOUT, "type\t\t?\n");
862 fprintf(STDOUT, "creationDate\t%-9lu\t%s", pntr->creationDate, ctime(&pntr->creationDate));
863 fprintf(STDOUT, "accessDate\t%-9lu\t%s", pntr->accessDate, ctime(&pntr->accessDate));
864 fprintf(STDOUT, "updateDate\t%-9lu\t%s", pntr->updateDate, ctime(&pntr->updateDate));
865 fprintf(STDOUT, "backupDate\t%-9lu\t%s", pntr->backupDate, ctime(&pntr->backupDate));
866 fprintf(STDOUT, "copyDate\t%-9lu\t%s", pntr->copyDate, ctime(&pntr->copyDate));
867 fprintf(STDOUT, "flags\t\t%#lx\t(Optional)\n", pntr->flags);
868 fprintf(STDOUT, "diskused\t%u\n", pntr->size);
869 fprintf(STDOUT, "maxquota\t%u\n", pntr->maxquota);
870 fprintf(STDOUT, "minquota\t%lu\t(Optional)\n", pntr->spare0);
871 fprintf(STDOUT, "filecount\t%u\n", pntr->filecount);
872 fprintf(STDOUT, "dayUse\t\t%u\n", pntr->dayUse);
873 fprintf(STDOUT, "weekUse\t\t%lu\t(Optional)\n", pntr->spare1);
874 fprintf(STDOUT, "spare2\t\t%lu\t(Optional)\n", pntr->spare2);
875 fprintf(STDOUT, "spare3\t\t%lu\t(Optional)\n", pntr->spare3);
879 static void DisplayVolumes2(server, partition, pntr, count)
881 long server, partition, count;
885 for (i = 0; i < count; i++) {
886 fprintf(STDOUT, "BEGIN_OF_ENTRY\n");
887 DisplayFormat2(server, partition, pntr);
888 fprintf(STDOUT, "END_OF_ENTRY\n\n");
893 #endif /* FULL_LISTVOL_SWITCH */
895 static void DisplayVolumes(server,part,pntr,count,longlist,fast,quiet)
896 afs_int32 server,part;
898 afs_int32 count,longlist,fast;
901 int totalOK,totalNotOK,totalBusy, i;
909 for(i = 0; i < count; i++){
910 DisplayFormat(pntr,server,part,&totalOK,&totalNotOK,&totalBusy,fast,longlist,0);
914 while(busyHead.count){
915 qGet(&busyHead,&volid);
916 fprintf(STDOUT,"**** Volume %u is busy ****\n",volid);
920 while(notokHead.count){
921 qGet(¬okHead,&volid);
922 fprintf(STDOUT,"**** Could not attach volume %u ****\n",volid);
926 fprintf(STDOUT,"\n");
928 fprintf(STDOUT,"Total volumes onLine %d ; Total volumes offLine %d ; Total busy %d\n\n",totalOK,totalNotOK,totalBusy);
933 /*------------------------------------------------------------------------
934 * PRIVATE XDisplayVolumes
937 * Display extended volume information.
940 * a_servID : Pointer to the Rx call we're performing.
941 * a_partID : Partition for which we want the extended list.
942 * a_xInfoP : Ptr to extended volume info.
943 * a_count : Number of volume records contained above.
944 * a_int32 : Int32 listing generated?
945 * a_fast : Fast listing generated?
946 * a_quiet : Quiet listing generated?
952 * Nothing interesting.
956 *------------------------------------------------------------------------*/
958 static void XDisplayVolumes(a_servID, a_partID, a_xInfoP,
959 a_count, a_int32, a_fast, a_quiet)
962 volintXInfo *a_xInfoP;
968 { /*XDisplayVolumes*/
970 int totalOK; /*Total OK volumes*/
971 int totalNotOK; /*Total screwed volumes*/
972 int totalBusy; /*Total busy volumes*/
973 int i; /*Loop variable*/
974 afs_int32 volid; /*Current volume ID*/
977 * Initialize counters and (global!!) queues.
986 * Display each volume in the list.
988 for(i = 0; i < a_count; i++) {
989 XDisplayFormat(a_xInfoP,
1002 * If any volumes were found to be busy or screwed, display them.
1005 while (busyHead.count) {
1006 qGet(&busyHead, &volid);
1007 fprintf(STDOUT, "**** Volume %u is busy ****\n", volid);
1011 while (notokHead.count) {
1012 qGet(¬okHead, &volid);
1013 fprintf(STDOUT, "**** Could not attach volume %u ****\n", volid);
1018 fprintf(STDOUT, "\n");
1021 "Total volumes: %d on-line, %d off-line, %d busyd\n\n",
1022 totalOK, totalNotOK, totalBusy);
1026 } /*XDisplayVolumes*/
1028 /* set <server> and <part> to the correct values depending on
1029 * <voltype> and <entry> */
1030 static void GetServerAndPart (entry, voltype, server, part, previdx)
1031 struct nvldbentry *entry;
1032 afs_int32 *server,*part;
1036 int i, istart, vtype;
1041 /* Doesn't check for non-existance of backup volume */
1042 if ((voltype == RWVOL) || (voltype == BACKVOL)) {
1044 istart = 0; /* seach the entire entry */
1047 /* Seach from beginning of entry or pick up where we left off */
1048 istart = ((*previdx < 0) ? 0 : *previdx+1);
1051 for (i = istart; i < entry->nServers; i++) {
1052 if (entry->serverFlags[i] & vtype) {
1053 *server = entry->serverNumber[i];
1054 *part = entry->serverPartition[i];
1060 /* Didn't find any, return -1 */
1065 static void PostVolumeStats(entry)
1066 struct nvldbentry *entry;
1068 SubEnumerateEntry(entry);
1069 /* Check for VLOP_ALLOPERS */
1070 if (entry->flags & VLOP_ALLOPERS)
1071 fprintf(STDOUT," Volume is currently LOCKED \n");
1075 /*------------------------------------------------------------------------
1076 * PRIVATE XVolumeStats
1079 * Display extended volume information.
1082 * a_xInfoP : Ptr to extended volume info.
1083 * a_entryP : Ptr to the volume's VLDB entry.
1084 * a_srvID : Server ID.
1085 * a_partID : Partition ID.
1086 * a_volType : Type of volume to print.
1092 * Nothing interesting.
1096 *------------------------------------------------------------------------*/
1098 static void XVolumeStats(a_xInfoP, a_entryP, a_srvID, a_partID, a_volType)
1099 volintXInfo *a_xInfoP;
1100 struct nvldbentry *a_entryP;
1107 int totalOK, totalNotOK, totalBusy; /*Dummies - we don't really count here*/
1109 XDisplayFormat(a_xInfoP, /*Ptr to extended volume info*/
1110 a_srvID, /*Server ID to print*/
1111 a_partID, /*Partition ID to print*/
1112 &totalOK, /*Ptr to total-OK counter*/
1113 &totalNotOK, /*Ptr to total-screwed counter*/
1114 &totalBusy, /*Ptr to total-busy counter*/
1115 0, /*Don't do a fast listing*/
1116 1, /*Do a long listing*/
1117 1); /*Show volume problems*/
1122 static void VolumeStats(pntr,entry,server,part,voltype)
1124 struct nvldbentry *entry;
1126 afs_int32 server,part;
1128 int totalOK,totalNotOK,totalBusy;
1129 afs_int32 vcode,vcode2;
1131 DisplayFormat(pntr,server,part,&totalOK,&totalNotOK,&totalBusy,0,1,1);
1135 /* command to forcibly remove a volume */
1136 static NukeVolume(as)
1137 register struct cmd_syndesc *as; {
1138 register afs_int32 code;
1139 afs_int32 volID, err;
1144 server = GetServer(tp = as->parms[0].items->data);
1146 fprintf(STDERR,"vos: server '%s' not found in host table\n", tp);
1150 partID = volutil_GetPartitionID(tp = as->parms[1].items->data);
1152 fprintf(STDERR, "vos: could not parse '%s' as a partition name", tp);
1156 volID = vsu_GetVolumeID(tp = as->parms[2].items->data, cstruct, &err);
1158 if (err) PrintError("", err);
1159 else fprintf(STDERR, "vos: could not parse '%s' as a numeric volume ID", tp);
1163 fprintf(STDOUT, "vos: forcibly removing all traces of volume %d, please wait...", volID);
1165 code = UV_NukeVolume(server, partID, volID);
1167 fprintf(STDOUT, "done.\n");
1169 fprintf(STDOUT, "failed with code %d.\n", code);
1174 /*------------------------------------------------------------------------
1175 * PRIVATE ExamineVolume
1178 * Routine used to examine a single volume, contacting the VLDB as
1179 * well as the Volume Server.
1182 * as : Ptr to parsed command line arguments.
1185 * 0 for a successful operation,
1186 * Otherwise, one of the ubik or VolServer error values.
1189 * Nothing interesting.
1193 *------------------------------------------------------------------------
1195 static ExamineVolume(as)
1196 register struct cmd_syndesc *as;
1198 struct nvldbentry entry;
1199 afs_int32 vcode = 0;
1200 volintInfo *pntr = (volintInfo *)0;
1201 volintXInfo *xInfoP = (volintXInfo *)0;
1203 afs_int32 code, err, error = 0;
1204 int voltype, foundserv = 0, foundentry = 0;
1205 afs_int32 aserver, apart;
1207 int wantExtendedInfo; /*Do we want extended vol info?*/
1209 wantExtendedInfo = (as->parms[1].items ? 1 : 0); /* -extended */
1211 volid = vsu_GetVolumeID(as->parms[0].items->data, cstruct, &err); /* -id */
1213 if (err) PrintError("", err);
1214 else fprintf(STDERR, "Unknown volume ID or name '%s'\n", as->parms[0].items->data);
1219 fprintf(STDOUT, "Fetching VLDB entry for %u .. ", volid);
1222 vcode = VLDB_GetEntryByID (volid, -1, &entry);
1224 fprintf(STDERR, "Could not fetch the entry for volume number %u from VLDB \n",volid);
1228 fprintf(STDOUT, "done\n");
1229 MapHostToNetwork(&entry);
1231 if (entry.volumeId[RWVOL] == volid)
1233 else if (entry.volumeId[BACKVOL] == volid)
1235 else /* (entry.volumeId[ROVOL] == volid) */
1238 do { /* do {...} while (voltype == ROVOL) */
1239 /* Get the entry for the volume. If its a RW vol, get the RW entry.
1240 * It its a BK vol, get the RW entry (even if VLDB may say the BK doen't exist).
1241 * If its a RO vol, get the next RO entry.
1243 GetServerAndPart(&entry, ((voltype == ROVOL) ? ROVOL : RWVOL), &aserver, &apart, &previdx);
1244 if (previdx == -1) { /* searched all entries */
1246 fprintf(STDERR,"Volume %s does not exist in VLDB\n\n", as->parms[0].items->data);
1253 /* Get information about the volume from the server */
1255 fprintf(STDOUT,"Getting volume listing from the server %s .. ",
1256 hostutil_GetNameByINet(aserver));
1259 if (wantExtendedInfo)
1260 code = UV_XListOneVolume(aserver, apart, volid, &xInfoP);
1262 code = UV_ListOneVolume(aserver, apart, volid, &pntr);
1264 fprintf(STDOUT,"done\n");
1268 if (code == ENODEV) {
1269 if ((voltype == BACKVOL) && !(entry.flags & BACK_EXISTS)) {
1270 /* The VLDB says there is no backup volume and its not on disk */
1271 fprintf(STDERR, "Volume %s does not exist\n", as->parms[0].items->data);
1274 fprintf(STDERR, "Volume does not exist on server %s as indicated by the VLDB\n",
1275 hostutil_GetNameByINet(aserver));
1278 PrintDiagnostics("examine", code);
1280 fprintf(STDOUT, "\n");
1283 if (wantExtendedInfo)
1284 XVolumeStats(xInfoP, &entry, aserver, apart, voltype);
1286 #ifdef FULL_LISTVOL_SWITCH
1287 if (as->parms[2].items) {
1288 DisplayFormat2(aserver, apart, pntr);
1289 EnumerateEntry(&entry);
1291 #endif /* FULL_LISTVOL_SWITCH */
1292 VolumeStats(pntr, &entry, aserver, apart, voltype);
1294 if ((voltype == BACKVOL) && !(entry.flags & BACK_EXISTS)) {
1295 /* The VLDB says there is no backup volume yet we found one on disk */
1296 fprintf(STDERR, "Volume %s does not exist in VLDB\n", as->parms[0].items->data);
1301 if (pntr) free(pntr);
1302 if (xInfoP) free(xInfoP);
1303 } while (voltype == ROVOL);
1306 fprintf(STDERR,"Dump only information from VLDB\n\n");
1307 fprintf(STDOUT,"%s \n", entry.name); /* PostVolumeStats doesn't print name */
1309 PostVolumeStats(&entry);
1314 /*------------------------------------------------------------------------
1318 * Routine used to change the status of a single volume.
1321 * as : Ptr to parsed command line arguments.
1324 * 0 for a successful operation,
1325 * Otherwise, one of the ubik or VolServer error values.
1328 * Nothing interesting.
1332 *------------------------------------------------------------------------
1334 static SetFields(as)
1335 register struct cmd_syndesc *as;
1337 struct nvldbentry entry;
1338 afs_int32 vcode = 0;
1341 afs_int32 code, err;
1342 afs_int32 aserver, apart;
1345 volid = vsu_GetVolumeID(as->parms[0].items->data, cstruct, &err); /* -id */
1347 if (err) PrintError("", err);
1348 else fprintf(STDERR, "Unknown volume ID or name '%s'\n", as->parms[0].items->data);
1352 code = VLDB_GetEntryByID (volid, RWVOL, &entry);
1354 fprintf(STDERR, "Could not fetch the entry for volume number %u from VLDB \n",volid);
1357 MapHostToNetwork(&entry);
1359 GetServerAndPart(&entry, RWVOL, &aserver, &apart, &previdx);
1360 if (previdx == -1) {
1361 fprintf(STDERR,"Volume %s does not exist in VLDB\n\n", as->parms[0].items->data);
1365 memset(&info, 0, sizeof(info));
1376 if (as->parms[1].items) {
1378 code = util_GetInt32(as->parms[1].items->data, &info.maxquota);
1380 fprintf(STDERR,"invalid quota value\n");
1384 if (as->parms[2].items) {
1388 code = UV_SetVolumeInfo(aserver, apart, volid, &info);
1390 fprintf(STDERR,"Could not update volume info fields for volume number %u\n",volid);
1394 /*------------------------------------------------------------------------
1398 * Brings a volume online.
1401 * as : Ptr to parsed command line arguments.
1404 * 0 for a successful operation,
1407 * Nothing interesting.
1411 *------------------------------------------------------------------------
1413 static volOnline(as)
1414 register struct cmd_syndesc *as;
1416 afs_int32 server, partition, volid;
1417 afs_int32 code, err=0;
1419 server = GetServer(as->parms[0].items->data);
1421 fprintf(STDERR,"vos: server '%s' not found in host table\n", as->parms[0].items->data);
1425 partition = volutil_GetPartitionID(as->parms[1].items->data);
1426 if (partition < 0) {
1427 fprintf(STDERR,"vos: could not interpret partition name '%s'\n", as->parms[1].items->data);
1431 volid = vsu_GetVolumeID(as->parms[2].items->data, cstruct, &err); /* -id */
1433 if (err) PrintError("", err);
1434 else fprintf(STDERR, "Unknown volume ID or name '%s'\n", as->parms[0].items->data);
1438 code = UV_SetVolume(server, partition, volid, ITOffline, 0/*online*/, 0/*sleep*/);
1440 fprintf(STDERR, "Failed to set volume. Code = %d\n", code);
1447 /*------------------------------------------------------------------------
1448 * PRIVATE volOffline
1451 * Brings a volume offline.
1454 * as : Ptr to parsed command line arguments.
1457 * 0 for a successful operation,
1460 * Nothing interesting.
1464 *------------------------------------------------------------------------
1466 static volOffline(as)
1467 register struct cmd_syndesc *as;
1469 afs_int32 server, partition, volid;
1470 afs_int32 code, err=0;
1471 afs_int32 transflag, sleeptime, transdone;
1473 server = GetServer(as->parms[0].items->data);
1475 fprintf(STDERR,"vos: server '%s' not found in host table\n", as->parms[0].items->data);
1479 partition = volutil_GetPartitionID(as->parms[1].items->data);
1480 if (partition < 0) {
1481 fprintf(STDERR,"vos: could not interpret partition name '%s'\n", as->parms[1].items->data);
1485 volid = vsu_GetVolumeID(as->parms[2].items->data, cstruct, &err); /* -id */
1487 if (err) PrintError("", err);
1488 else fprintf(STDERR, "Unknown volume ID or name '%s'\n", as->parms[0].items->data);
1492 transflag = (as->parms[4].items ? ITBusy : ITOffline);
1493 sleeptime = (as->parms[3].items ? atol(as->parms[3].items->data) : 0);
1494 transdone = (sleeptime ? 0/*online*/ : VTOutOfService);
1495 if (as->parms[4].items && !as->parms[3].items) {
1496 fprintf(STDERR,"-sleep option must be used with -busy flag\n");
1500 code = UV_SetVolume(server, partition, volid, transflag, transdone, sleeptime);
1502 fprintf(STDERR, "Failed to set volume. Code = %d\n", code);
1509 static CreateVolume(as)
1510 register struct cmd_syndesc *as;
1514 afs_int32 volid,code;
1515 struct nvldbentry entry;
1520 tserver = GetServer(as->parms[0].items->data);
1522 fprintf(STDERR,"vos: host '%s' not found in host table\n",as->parms[0].items->data );
1525 pname = volutil_GetPartitionID(as->parms[1].items->data);
1527 fprintf(STDERR,"vos: could not interpret partition name '%s'\n",as->parms[1].items->data );
1530 if (!IsPartValid(pname,tserver,&code)){/*check for validity of the partition */
1531 if(code) PrintError("",code);
1532 else fprintf(STDERR,"vos : partition %s does not exist on the server\n",as->parms[1].items->data);
1535 if(!ISNAMEVALID(as->parms[2].items->data)) {
1536 fprintf(STDERR,"vos: the name of the root volume %s exceeds the size limit of %d\n",as->parms[2].items->data,VOLSER_OLDMAXVOLNAME - 10);
1539 if(!VolNameOK(as->parms[2].items->data)){
1540 fprintf(STDERR,"Illegal volume name %s, should not end in .readonly or .backup\n",as->parms[2].items->data);
1543 if(IsNumeric(as->parms[2].items->data)){
1544 fprintf(STDERR,"Illegal volume name %s, should not be a number\n",as->parms[2].items->data);
1547 vcode = VLDB_GetEntryByName(as->parms[2].items->data, &entry);
1549 fprintf(STDERR,"Volume %s already exists\n",as->parms[2].items->data);
1550 PrintDiagnostics("create", code);
1554 if (as->parms[3].items) {
1555 if (!IsNumeric(as->parms[3].items->data)){
1556 fprintf(STDERR,"Initial quota %s should be numeric.\n", as->parms[3].items->data);
1560 code = util_GetInt32(as->parms[3].items->data, "a);
1562 fprintf(STDERR,"vos: bad integer specified for quota.\n");
1567 code = UV_CreateVolume2(tserver, pname,as->parms[2].items->data,
1568 quota, 0, 0, 0, 0, &volid);
1570 PrintDiagnostics("create", code);
1573 MapPartIdIntoName(pname, part);
1574 fprintf(STDOUT,"Volume %u created on partition %s of %s\n", volid, part,as->parms[0].items->data );
1579 static afs_int32 DeleteAll(entry)
1580 struct nvldbentry *entry;
1583 afs_int32 error, code, curserver, curpart, volid;
1585 MapHostToNetwork(entry);
1587 for(i=0; i < entry->nServers; i++){
1588 curserver = entry->serverNumber[i];
1589 curpart = entry->serverPartition[i];
1590 if(entry->serverFlags[i] & ITSROVOL){
1591 volid = entry->volumeId[ROVOL];
1594 volid = entry->volumeId[RWVOL];
1596 code = UV_DeleteVolume(curserver,curpart,volid);
1603 static DeleteVolume(as)
1604 struct cmd_syndesc *as;
1606 afs_int32 err, code = 0;
1607 afs_int32 server = 0, partition = -1, volid;
1611 if (as->parms[0].items) {
1612 server = GetServer(as->parms[0].items->data);
1614 fprintf(STDERR,"vos: server '%s' not found in host table\n",
1615 as->parms[0].items->data);
1620 if (as->parms[1].items) {
1621 partition = volutil_GetPartitionID(as->parms[1].items->data);
1622 if (partition < 0) {
1623 fprintf(STDERR,"vos: could not interpret partition name '%s'\n",
1624 as->parms[1].items->data );
1628 /* Check for validity of the partition */
1629 if (!IsPartValid(partition, server, &code)) {
1631 PrintError("", code);
1633 fprintf(STDERR,"vos : partition %s does not exist on the server\n",
1634 as->parms[1].items->data);
1640 volid = vsu_GetVolumeID(as->parms[2].items->data, cstruct, &err);
1642 fprintf(STDERR, "Can't find volume name '%s' in VLDB\n",
1643 as->parms[2].items->data);
1644 if (err) PrintError("", err);
1648 /* If the server or partition option are not complete, try to fill
1649 * them in from the VLDB entry.
1651 if ((partition == -1) || !server) {
1652 struct nvldbentry entry;
1654 code = VLDB_GetEntryByID(volid, -1, &entry);
1656 fprintf(STDERR,"Could not fetch the entry for volume %u from VLDB\n",
1658 PrintError("",code);
1662 if (((volid == entry.volumeId[RWVOL]) && (entry.flags & RW_EXISTS)) ||
1663 ((volid == entry.volumeId[BACKVOL]) && (entry.flags & BACK_EXISTS)) ) {
1664 idx = Lp_GetRwIndex(&entry);
1666 (server && (server != entry.serverNumber[idx])) ||
1667 ((partition != -1) && (partition != entry.serverPartition[idx])) ) {
1668 fprintf(STDERR,"VLDB: Volume '%s' no match\n", as->parms[2].items->data);
1672 else if ((volid == entry.volumeId[ROVOL]) && (entry.flags & RO_EXISTS)) {
1673 for (idx=-1,j=0; j<entry.nServers; j++) {
1674 if (entry.serverFlags[j] != ITSROVOL) continue;
1676 if ( ((server == 0) || (server == entry.serverNumber[j])) &&
1677 ((partition == -1) || (partition == entry.serverPartition[j])) ) {
1679 fprintf(STDERR,"VLDB: Volume '%s' matches more than one RO\n",
1680 as->parms[2].items->data);
1687 fprintf(STDERR,"VLDB: Volume '%s' no match\n", as->parms[2].items->data);
1692 fprintf(STDERR,"VLDB: Volume '%s' no match\n", as->parms[2].items->data);
1696 server = htonl(entry.serverNumber[idx]);
1697 partition = entry.serverPartition[idx];
1701 code = UV_DeleteVolume(server, partition, volid);
1703 PrintDiagnostics("remove", code);
1707 MapPartIdIntoName(partition, pname);
1708 fprintf(STDOUT,"Volume %u on partition %s server %s deleted\n",
1709 volid, pname, hostutil_GetNameByINet(server));
1713 #define TESTM 0 /* set for move space tests, clear for production */
1714 static MoveVolume(as)
1715 register struct cmd_syndesc *as;
1718 afs_int32 volid, fromserver, toserver, frompart, topart,code, err;
1719 char fromPartName[10], toPartName[10];
1721 struct diskPartition partition; /* for space check */
1724 volid = vsu_GetVolumeID(as->parms[0].items->data, cstruct, &err);
1726 if (err) PrintError("", err);
1727 else fprintf(STDERR, "vos: can't find volume ID or name '%s'\n",
1728 as->parms[0].items->data);
1731 fromserver = GetServer(as->parms[1].items->data);
1732 if (fromserver == 0) {
1733 fprintf(STDERR,"vos: server '%s' not found in host table\n", as->parms[1].items->data);
1736 toserver = GetServer(as->parms[3].items->data);
1737 if (toserver == 0) {
1738 fprintf(STDERR,"vos: server '%s' not found in host table\n", as->parms[3].items->data);
1741 frompart = volutil_GetPartitionID(as->parms[2].items->data);
1743 fprintf(STDERR,"vos: could not interpret partition name '%s'\n", as->parms[2].items->data);
1746 if (!IsPartValid(frompart,fromserver,&code)){/*check for validity of the partition */
1747 if(code) PrintError("",code);
1748 else fprintf(STDERR,"vos : partition %s does not exist on the server\n",as->parms[2].items->data);
1751 topart = volutil_GetPartitionID(as->parms[4].items->data);
1753 fprintf(STDERR,"vos: could not interpret partition name '%s'\n",as->parms[4].items->data);
1756 if (!IsPartValid(topart,toserver,&code)){/*check for validity of the partition */
1757 if(code) PrintError("",code);
1758 else fprintf(STDERR,"vos : partition %s does not exist on the server\n",as->parms[4].items->data);
1763 check source partition for space to clone volume
1766 MapPartIdIntoName(topart,toPartName);
1767 MapPartIdIntoName(frompart, fromPartName);
1770 check target partition for space to move volume
1773 code=UV_PartitionInfo(toserver,toPartName,&partition);
1776 fprintf(STDERR,"vos: cannot access partition %s\n",toPartName);
1780 fprintf(STDOUT,"target partition %s free space %d\n",
1781 toPartName,partition.free);
1784 code=UV_ListOneVolume(fromserver,frompart,volid,&p);
1787 fprintf(STDERR,"vos:cannot access volume %u\n",volid);
1792 fprintf(STDOUT,"volume %u size %d\n",volid,p->size);
1793 if(partition.free<=p->size)
1795 fprintf(STDERR,"vos: no space on target partition %s to move volume %u\n",
1804 fprintf(STDOUT,"size test - don't do move\n");
1808 /* successful move still not guaranteed but shoot for it */
1810 code = UV_MoveVolume(volid, fromserver, frompart, toserver, topart);
1812 PrintDiagnostics("move", code);
1815 MapPartIdIntoName(topart,toPartName);
1816 MapPartIdIntoName(frompart, fromPartName);
1817 fprintf(STDOUT,"Volume %u moved from %s %s to %s %s \n",volid,as->parms[1].items->data,fromPartName,as->parms[3].items->data,toPartName);
1822 static CopyVolume(as)
1823 register struct cmd_syndesc *as;
1825 afs_int32 volid, fromserver, toserver, frompart, topart,code, err;
1826 char fromPartName[10], toPartName[10], *tovolume;
1827 struct nvldbentry entry;
1828 struct diskPartition partition; /* for space check */
1831 volid = vsu_GetVolumeID(as->parms[0].items->data, cstruct, &err);
1833 if (err) PrintError("", err);
1834 else fprintf(STDERR, "vos: can't find volume ID or name '%s'\n",
1835 as->parms[0].items->data);
1838 fromserver = GetServer(as->parms[1].items->data);
1839 if (fromserver == 0) {
1840 fprintf(STDERR,"vos: server '%s' not found in host table\n", as->parms[1].items->data);
1844 toserver = GetServer(as->parms[4].items->data);
1845 if (toserver == 0) {
1846 fprintf(STDERR,"vos: server '%s' not found in host table\n", as->parms[3].items->data);
1850 tovolume = as->parms[3].items->data;
1851 if(!ISNAMEVALID(tovolume)) {
1852 fprintf(STDERR,"vos: the name of the root volume %s exceeds the size limit of %d\n",
1853 tovolume,VOLSER_OLDMAXVOLNAME - 10);
1856 if(!VolNameOK(tovolume)){
1857 fprintf(STDERR,"Illegal volume name %s, should not end in .readonly or .backup\n",tovolume);
1860 if(IsNumeric(tovolume)){
1861 fprintf(STDERR,"Illegal volume name %s, should not be a number\n",tovolume);
1864 code = VLDB_GetEntryByName(tovolume, &entry);
1866 fprintf(STDERR,"Volume %s already exists\n",tovolume);
1867 PrintDiagnostics("copy", code);
1871 frompart = volutil_GetPartitionID(as->parms[2].items->data);
1873 fprintf(STDERR,"vos: could not interpret partition name '%s'\n", as->parms[2].items->data);
1876 if (!IsPartValid(frompart,fromserver,&code)){ /*check for validity of the partition */
1877 if(code) PrintError("",code);
1878 else fprintf(STDERR,"vos : partition %s does not exist on the server\n",as->parms[2].items->data);
1882 topart = volutil_GetPartitionID(as->parms[5].items->data);
1884 fprintf(STDERR,"vos: could not interpret partition name '%s'\n",as->parms[4].items->data);
1887 if (!IsPartValid(topart,toserver,&code)){ /*check for validity of the partition */
1888 if(code) PrintError("",code);
1889 else fprintf(STDERR,"vos : partition %s does not exist on the server\n",as->parms[4].items->data);
1894 * check source partition for space to clone volume
1897 MapPartIdIntoName(topart,toPartName);
1898 MapPartIdIntoName(frompart, fromPartName);
1901 * check target partition for space to move volume
1904 code=UV_PartitionInfo(toserver,toPartName,&partition);
1907 fprintf(STDERR,"vos: cannot access partition %s\n",toPartName);
1911 fprintf(STDOUT,"target partition %s free space %d\n",
1912 toPartName,partition.free);
1915 code=UV_ListOneVolume(fromserver,frompart,volid,&p);
1918 fprintf(STDERR,"vos:cannot access volume %u\n",volid);
1923 if(partition.free<=p->size)
1925 fprintf(STDERR,"vos: no space on target partition %s to copy volume %u\n",
1932 /* successful copy still not guaranteed but shoot for it */
1934 code = UV_CopyVolume(volid, fromserver, frompart, tovolume, toserver, topart);
1936 PrintDiagnostics("copy", code);
1939 MapPartIdIntoName(topart,toPartName);
1940 MapPartIdIntoName(frompart, fromPartName);
1941 fprintf(STDOUT,"Volume %u copied from %s %s to %s on %s %s \n",volid,
1942 as->parms[1].items->data,fromPartName,
1943 tovolume, as->parms[4].items->data,toPartName);
1949 static BackupVolume(as)
1950 register struct cmd_syndesc *as;
1952 afs_int32 avolid, aserver, apart,vtype,code, err;
1953 struct nvldbentry entry;
1955 afs_int32 buvolid,buserver,bupart,butype;
1956 struct nvldbentry buentry;
1957 struct rx_connection *conn;
1959 struct nvldbentry store;
1961 avolid = vsu_GetVolumeID(as->parms[0].items->data, cstruct, &err);
1963 if (err) PrintError("", err);
1964 else fprintf(STDERR, "vos: can't find volume ID or name '%s'\n",
1965 as->parms[0].items->data);
1968 code = GetVolumeInfo( avolid,&aserver, &apart,&vtype,&entry);
1971 /* verify this is a readwrite volume */
1975 fprintf(STDERR,"%s not RW volume\n",as->parms[0].items->data);
1979 /* is there a backup volume already? */
1981 if(entry.flags & BACK_EXISTS)
1983 /* yep, where is it? */
1985 buvolid=entry.volumeId[BACKVOL];
1986 code=GetVolumeInfo(buvolid,&buserver,&bupart,&butype,&buentry);
1990 code = VLDB_IsSameAddrs(buserver, aserver, &err);
1992 fprintf(STDERR,"Failed to get info about server's %d address(es) from vlserver; aborting call!\n", buserver);
1997 fprintf(STDERR,"FATAL ERROR: backup volume %u exists on server %u\n",
2003 /* nope, carry on */
2005 code = UV_BackupVolume(aserver, apart, avolid);
2008 PrintDiagnostics("backup", code);
2011 fprintf(STDOUT,"Created backup volume for %s \n",as->parms[0].items->data);
2014 static ReleaseVolume(as)
2015 register struct cmd_syndesc *as;
2018 struct nvldbentry entry;
2019 afs_int32 avolid, aserver, apart,vtype,code, err;
2022 if(as->parms[1].items) force = 1;
2023 avolid = vsu_GetVolumeID(as->parms[0].items->data, cstruct, &err);
2025 if (err) PrintError("", err);
2026 else fprintf(STDERR, "vos: can't find volume '%s'\n", as->parms[0].items->data);
2029 code = GetVolumeInfo( avolid,&aserver, &apart,&vtype,&entry);
2030 if(code) return code;
2032 if (vtype != RWVOL) {
2033 fprintf(STDERR,"%s not a RW volume\n", as->parms[0].items->data);
2037 if(!ISNAMEVALID(entry.name)){
2038 fprintf(STDERR,"Volume name %s is too long, rename before releasing\n",entry.name);
2042 code = UV_ReleaseVolume(avolid, aserver, apart, force);
2044 PrintDiagnostics("release", code);
2047 fprintf(STDOUT,"Released volume %s successfully\n",as->parms[0].items->data );
2050 static DumpVolume(as)
2051 register struct cmd_syndesc *as;
2054 afs_int32 avolid, aserver, apart,voltype,fromdate=0,code, err, i;
2055 char filename[NameLen];
2056 struct nvldbentry entry;
2058 rx_SetRxDeadTime(60 * 10);
2059 for (i = 0; i<MAXSERVERS; i++) {
2060 struct rx_connection *rxConn = ubik_GetRPCConn(cstruct,i);
2061 if (rxConn == 0) break;
2062 rx_SetConnDeadTime(rxConn, rx_connDeadTime);
2063 if (rxConn->service) rxConn->service->connDeadTime = rx_connDeadTime;
2066 avolid = vsu_GetVolumeID(as->parms[0].items->data, cstruct, &err);
2068 if (err) PrintError("", err);
2069 else fprintf(STDERR, "vos: can't find volume '%s'\n", as->parms[0].items->data);
2073 if (as->parms[3].items || as->parms[4].items) {
2074 if (!as->parms[3].items || !as->parms[4].items) {
2075 fprintf(STDERR, "Must specify both -server and -partition options\n");
2078 aserver = GetServer(as->parms[3].items->data);
2080 fprintf(STDERR, "Invalid server name\n");
2083 apart = volutil_GetPartitionID(as->parms[4].items->data);
2085 fprintf(STDERR, "Invalid partition name\n");
2089 code = GetVolumeInfo(avolid, &aserver, &apart, &voltype, &entry);
2090 if (code) return code;
2093 if (as->parms[1].items && strcmp(as->parms[1].items->data,"0")) {
2094 code = ktime_DateToInt32(as->parms[1].items->data, &fromdate);
2096 fprintf(STDERR,"vos: failed to parse date '%s' (error=%d))\n",
2097 as->parms[1].items->data, code);
2101 if(as->parms[2].items){
2102 strcpy(filename,as->parms[2].items->data);
2105 strcpy(filename,"");
2108 if (as->parms[5].items) {
2109 code = UV_DumpClonedVolume(avolid, aserver, apart, fromdate, DumpFunction, filename);
2111 code = UV_DumpVolume(avolid, aserver, apart, fromdate, DumpFunction, filename);
2114 PrintDiagnostics("dump", code);
2117 if(strcmp(filename,""))
2118 fprintf(STDERR,"Dumped volume %s in file %s\n",as->parms[0].items->data, filename);
2120 fprintf(STDERR,"Dumped volume %s in stdout \n",as->parms[0].items->data);
2129 static RestoreVolume(as)
2130 register struct cmd_syndesc *as;
2133 afs_int32 avolid, aserver, apart, code,vcode, err;
2134 afs_int32 aoverwrite = ASK;
2135 int restoreflags, readonly = 0, offline = 0, voltype = RWVOL;
2137 char afilename[NameLen], avolname[VOLSER_MAXVOLNAME +1],apartName[10];
2138 char volname[VOLSER_MAXVOLNAME +1];
2139 struct nvldbentry entry;
2143 if(as->parms[4].items){
2144 avolid = vsu_GetVolumeID(as->parms[4].items->data, cstruct, &err);
2146 if (err) PrintError("", err);
2147 else fprintf(STDERR, "vos: can't find volume '%s'\n", as->parms[4].items->data);
2154 if (as->parms[5].items) {
2155 if ( (strcmp(as->parms[5].items->data, "a") == 0) ||
2156 (strcmp(as->parms[5].items->data, "abort") == 0) ) {
2159 else if ( (strcmp(as->parms[5].items->data, "f") == 0) ||
2160 (strcmp(as->parms[5].items->data, "full") == 0) ) {
2163 else if ( (strcmp(as->parms[5].items->data, "i") == 0) ||
2164 (strcmp(as->parms[5].items->data, "inc") == 0) ||
2165 (strcmp(as->parms[5].items->data, "increment") == 0) ||
2166 (strcmp(as->parms[5].items->data, "incremental") == 0) ) {
2170 fprintf(STDERR, "vos: %s is not a valid argument to -overwrite\n",
2171 as->parms[5].items->data);
2175 if (as->parms[6].items) offline = 1;
2176 if (as->parms[7].items) {
2181 aserver = GetServer(as->parms[0].items->data);
2183 fprintf(STDERR,"vos: server '%s' not found in host table\n", as->parms[0].items->data);
2186 apart = volutil_GetPartitionID(as->parms[1].items->data);
2188 fprintf(STDERR,"vos: could not interpret partition name '%s'\n",as->parms[1].items->data );
2191 if (!IsPartValid(apart,aserver,&code)){/*check for validity of the partition */
2192 if(code) PrintError("",code);
2193 else fprintf(STDERR,"vos : partition %s does not exist on the server\n",as->parms[1].items->data);
2196 strcpy(avolname,as->parms[2].items->data );
2197 if(!ISNAMEVALID(avolname)) {
2198 fprintf(STDERR,"vos: the name of the volume %s exceeds the size limit\n",avolname);
2201 if(!VolNameOK(avolname)){
2202 fprintf(STDERR,"Illegal volume name %s, should not end in .readonly or .backup\n",avolname);
2205 if(as->parms[3].items){
2206 strcpy(afilename,as->parms[3].items->data );
2207 if(!FileExists(afilename)){
2208 fprintf(STDERR,"Can't access file %s\n",afilename);
2213 strcpy(afilename,"");
2216 /* Check if volume exists or not */
2218 vsu_ExtractName(volname,avolname);
2219 vcode = VLDB_GetEntryByName(volname, &entry);
2220 if (vcode) { /* no volume - do a full restore */
2221 restoreflags = RV_FULLRST;
2222 if ( (aoverwrite == INC) || (aoverwrite == ABORT) )
2223 fprintf(STDERR,"Volume does not exist; Will perform a full restore\n");
2226 else if ((!readonly && Lp_GetRwIndex(&entry) == -1) /* RW volume does not exist - do a full */
2227 || (readonly && !Lp_ROMatch(0, 0, &entry))) { /* RO volume does not exist - do a full */
2228 restoreflags = RV_FULLRST;
2229 if ( (aoverwrite == INC) || (aoverwrite == ABORT) )
2230 fprintf(STDERR,"%s Volume does not exist; Will perform a full restore\n",
2231 readonly ? "RO" : "RW");
2234 avolid = entry.volumeId[voltype];
2236 else if (entry.volumeId[voltype] != 0 && entry.volumeId[voltype] != avolid) {
2237 avolid = entry.volumeId[voltype];
2241 else { /* volume exists - do we do a full incremental or abort */
2242 int Oserver, Opart, Otype, vol_elsewhere = 0;
2243 struct nvldbentry Oentry;
2247 avolid = entry.volumeId[voltype];
2249 else if(entry.volumeId[voltype] != 0 && entry.volumeId[voltype] != avolid) {
2250 avolid = entry.volumeId[voltype];
2253 /* A file name was specified - check if volume is on another partition */
2254 vcode = GetVolumeInfo(avolid, &Oserver, &Opart, &Otype, &Oentry);
2257 vcode = VLDB_IsSameAddrs(Oserver, aserver, &err);
2259 fprintf(STDERR,"Failed to get info about server's %d address(es) from vlserver (err=%d); aborting call!\n",
2263 if (!vcode || (Opart != apart)) vol_elsewhere = 1;
2265 if (aoverwrite == ASK) {
2266 if (strcmp(afilename,"") == 0) { /* The file is from standard in */
2267 fprintf(STDERR,"Volume exists and no -overwrite option specified; Aborting restore command\n");
2271 /* Ask what to do */
2272 if (vol_elsewhere) {
2273 fprintf(STDERR,"The volume %s %u already exists on a different server/part\n",
2274 volname, entry.volumeId[voltype]);
2276 "Do you want to do a full restore or abort? [fa](a): ");
2280 fprintf(STDERR,"The volume %s %u already exists in the VLDB\n",
2281 volname, entry.volumeId[voltype]);
2283 "Do you want to do a full/incremental restore or abort? [fia](a): ");
2286 while (!(dc==EOF || dc=='\n')) dc=getchar(); /* goto end of line */
2287 if ((c == 'f') || (c == 'F')) aoverwrite = FULL;
2288 else if ((c == 'i') || (c == 'I')) aoverwrite = INC;
2289 else aoverwrite = ABORT;
2292 if (aoverwrite == ABORT) {
2293 fprintf(STDERR,"Volume exists; Aborting restore command\n");
2296 else if (aoverwrite == FULL) {
2297 restoreflags = RV_FULLRST;
2298 fprintf(STDERR,"Volume exists; Will delete and perform full restore\n");
2300 else if (aoverwrite == INC) {
2302 if (vol_elsewhere) {
2304 "%s volume %u already exists on a different server/part; not allowed\n",
2305 readonly ? "RO" : "RW", avolid);
2310 if (offline) restoreflags |= RV_OFFLINE;
2311 if (readonly) restoreflags |= RV_RDONLY;
2312 code = UV_RestoreVolume(aserver, apart, avolid, avolname,
2313 restoreflags, WriteData, afilename);
2315 PrintDiagnostics("restore", code);
2318 MapPartIdIntoName(apart,apartName);
2321 patch typo here - originally "parms[1]", should be "parms[0]"
2324 fprintf(STDOUT,"Restored volume %s on %s %s\n",
2325 avolname, as->parms[0].items->data, apartName);
2328 static LockReleaseCmd(as)
2329 register struct cmd_syndesc *as;
2332 afs_int32 avolid,code, err;
2334 avolid = vsu_GetVolumeID(as->parms[0].items->data, cstruct, &err);
2336 if (err) PrintError("", err);
2337 else fprintf(STDERR, "vos: can't find volume '%s'\n", as->parms[0].items->data);
2341 code = UV_LockRelease(avolid);
2343 PrintDiagnostics("unlock", code);
2346 fprintf(STDOUT,"Released lock on vldb entry for volume %s\n",as->parms[0].items->data);
2350 register struct cmd_syndesc *as;
2352 afs_int32 avolid, aserver, apart,code, err;
2353 char apartName[10], avolname[VOLSER_MAXVOLNAME+1];
2355 vsu_ExtractName(avolname, as->parms[2].items->data);;
2356 avolid = vsu_GetVolumeID(avolname, cstruct, &err);
2358 if (err) PrintError("", err);
2359 else fprintf(STDERR, "vos: can't find volume '%s'\n", as->parms[2].items->data);
2362 aserver = GetServer(as->parms[0].items->data);
2364 fprintf(STDERR,"vos: server '%s' not found in host table\n", as->parms[0].items->data);
2367 apart = volutil_GetPartitionID(as->parms[1].items->data);
2369 fprintf(STDERR,"vos: could not interpret partition name '%s'\n",as->parms[1].items->data );
2372 if (!IsPartValid(apart,aserver,&code)){/*check for validity of the partition */
2373 if(code) PrintError("",code);
2374 else fprintf(STDERR,"vos : partition %s does not exist on the server\n",as->parms[1].items->data);
2377 code = UV_AddSite(aserver, apart, avolid);
2379 PrintDiagnostics("addsite", code);
2382 MapPartIdIntoName(apart,apartName);
2383 fprintf(STDOUT,"Added replication site %s %s for volume %s\n",as->parms[0].items->data, apartName,as->parms[2].items->data);
2387 static RemoveSite(as)
2388 register struct cmd_syndesc *as;
2391 afs_int32 avolid, aserver, apart, code, err;
2392 char apartName[10], avolname[VOLSER_MAXVOLNAME+1];
2394 vsu_ExtractName(avolname, as->parms[2].items->data);
2395 avolid = vsu_GetVolumeID(avolname, cstruct, &err);
2397 if (err) PrintError("", err);
2398 else fprintf(STDERR, "vos: can't find volume '%s'\n", as->parms[2].items->data);
2401 aserver = GetServer(as->parms[0].items->data);
2403 fprintf(STDERR,"vos: server '%s' not found in host table\n", as->parms[0].items->data);
2406 apart = volutil_GetPartitionID(as->parms[1].items->data);
2408 fprintf(STDERR,"vos: could not interpret partition name '%s'\n",as->parms[1].items->data );
2412 *skip the partition validity check, since it is possible that the partition
2413 *has since been decomissioned.
2416 if (!IsPartValid(apart,aserver,&code)){
2417 if(code) PrintError("",code);
2418 else fprintf(STDERR,"vos : partition %s does not exist on the server\n",as->parms[1].items->data);
2422 code = UV_RemoveSite(aserver, apart, avolid);
2424 PrintDiagnostics("remsite", code);
2427 MapPartIdIntoName(apart,apartName);
2428 fprintf(STDOUT,"Removed replication site %s %s for volume %s\n",as->parms[0].items->data,apartName,as->parms[2].items->data);
2431 static ChangeLocation(as)
2432 register struct cmd_syndesc *as;
2434 afs_int32 avolid, aserver, apart,code, err;
2437 avolid = vsu_GetVolumeID(as->parms[2].items->data, cstruct, &err);
2439 if (err) PrintError("", err);
2440 else fprintf(STDERR, "vos: can't find volume '%s'\n", as->parms[2].items->data);
2443 aserver = GetServer(as->parms[0].items->data);
2445 fprintf(STDERR,"vos: server '%s' not found in host table\n", as->parms[0].items->data);
2448 apart = volutil_GetPartitionID(as->parms[1].items->data);
2450 fprintf(STDERR,"vos: could not interpret partition name '%s'\n",as->parms[1].items->data );
2453 if (!IsPartValid(apart,aserver,&code)){/*check for validity of the partition */
2454 if(code) PrintError("",code);
2455 else fprintf(STDERR,"vos : partition %s does not exist on the server\n",as->parms[1].items->data);
2458 code = UV_ChangeLocation(aserver, apart, avolid);
2460 PrintDiagnostics("addsite", code);
2463 MapPartIdIntoName(apart,apartName);
2464 fprintf(STDOUT,"Changed location to %s %s for volume %s\n",as->parms[0].items->data, apartName,as->parms[2].items->data);
2468 static ListPartitions(as)
2469 register struct cmd_syndesc *as;
2471 afs_int32 aserver,code;
2472 struct partList dummyPartList;
2477 aserver = GetServer(as->parms[0].items->data);
2479 fprintf(STDERR,"vos: server '%s' not found in host table\n", as->parms[0].items->data);
2484 code = UV_ListPartitions(aserver,&dummyPartList, &cnt);
2486 PrintDiagnostics("listpart", code);
2490 fprintf(STDOUT,"The partitions on the server are:\n");
2491 for(i = 0 ; i < cnt ; i++){
2492 if(dummyPartList.partFlags[i] & PARTVALID){
2493 memset(pname, 0, sizeof(pname));
2494 MapPartIdIntoName(dummyPartList.partId[i],pname);
2495 fprintf(STDOUT," %10s ",pname);
2497 if( (i % 5) == 0 && (i != 0)) fprintf(STDOUT,"\n");
2500 fprintf(STDOUT,"\n");
2501 fprintf(STDOUT,"Total: %d\n",total);
2506 static int CompareVolName(p1,p2)
2509 volintInfo *arg1,*arg2;
2511 arg1 = (volintInfo *)p1;
2512 arg2 = (volintInfo *)p2;
2513 return(strcmp(arg1->name,arg2->name));
2517 /*------------------------------------------------------------------------
2518 * PRIVATE XCompareVolName
2521 * Comparison routine for volume names coming from an extended
2525 * a_obj1P : Char ptr to first extended vol info object
2526 * a_obj1P : Char ptr to second extended vol info object
2529 * The value of strcmp() on the volume names within the passed
2530 * objects (i,e., -1, 0, or 1).
2533 * Passed to qsort() as the designated comparison routine.
2537 *------------------------------------------------------------------------*/
2539 static int XCompareVolName(a_obj1P, a_obj2P)
2540 char *a_obj1P, *a_obj2P;
2542 { /*XCompareVolName*/
2544 return(strcmp(((struct volintXInfo *)(a_obj1P))->name,
2545 ((struct volintXInfo *)(a_obj2P))->name));
2547 } /*XCompareVolName*/
2549 static int CompareVolID(p1,p2)
2552 volintInfo *arg1,*arg2;
2554 arg1 = (volintInfo *)p1;
2555 arg2 = (volintInfo *)p2;
2556 if(arg1->volid == arg2->volid) return 0;
2557 if(arg1->volid > arg2->volid) return 1;
2562 /*------------------------------------------------------------------------
2563 * PRIVATE XCompareVolID
2566 * Comparison routine for volume IDs coming from an extended
2570 * a_obj1P : Char ptr to first extended vol info object
2571 * a_obj1P : Char ptr to second extended vol info object
2574 * The value of strcmp() on the volume names within the passed
2575 * objects (i,e., -1, 0, or 1).
2578 * Passed to qsort() as the designated comparison routine.
2582 *------------------------------------------------------------------------*/
2584 static int XCompareVolID(a_obj1P, a_obj2P)
2585 char *a_obj1P, *a_obj2P;
2589 afs_int32 id1, id2; /*Volume IDs we're comparing*/
2591 id1 = ((struct volintXInfo *)(a_obj1P))->volid;
2592 id2 = ((struct volintXInfo *)(a_obj2P))->volid;
2603 /*------------------------------------------------------------------------
2604 * PRIVATE ListVolumes
2607 * Routine used to list volumes, contacting the Volume Server
2608 * directly, bypassing the VLDB.
2611 * as : Ptr to parsed command line arguments.
2614 * 0 Successful operation
2617 * Nothing interesting.
2621 *------------------------------------------------------------------------*/
2623 static ListVolumes(as)
2624 register struct cmd_syndesc *as;
2626 afs_int32 apart,int32list,fast;
2627 afs_int32 aserver,code;
2628 volintInfo *pntr,*oldpntr;
2632 volintXInfo *xInfoP, *origxInfoP; /*Ptr to current/orig extended vol info*/
2633 int wantExtendedInfo; /*Do we want extended vol info?*/
2636 struct partList dummyPartList;
2644 if(as->parms[3].items) int32list = 1;
2645 if(as->parms[4].items) quiet = 1;
2647 if(as->parms[2].items) fast = 1;
2650 if (as->parms[5].items) {
2652 * We can't coexist with the fast flag.
2656 "vos: Can't use the -fast and -extended flags together\n");
2661 * We need to turn on ``long'' listings to get the full effect.
2663 wantExtendedInfo = 1;
2667 wantExtendedInfo = 0;
2668 if(as->parms[1].items){
2669 apart = volutil_GetPartitionID(as->parms[1].items->data);
2671 fprintf(STDERR,"vos: could not interpret partition name '%s'\n", as->parms[1].items->data);
2674 dummyPartList.partId[0] = apart;
2675 dummyPartList.partFlags[0] = PARTVALID;
2678 aserver = GetServer(as->parms[0].items->data);
2680 fprintf(STDERR,"vos: server '%s' not found in host table\n",as->parms[0].items->data );
2685 if (!IsPartValid(apart,aserver,&code)){/*check for validity of the partition */
2686 if(code) PrintError("",code);
2687 else fprintf(STDERR,"vos : partition %s does not exist on the server\n",as->parms[1].items->data);
2692 code = UV_ListPartitions(aserver,&dummyPartList, &cnt);
2694 PrintDiagnostics("listvol", code);
2698 for(i = 0 ; i < cnt ; i++){
2699 if(dummyPartList.partFlags[i] & PARTVALID){
2700 if (wantExtendedInfo)
2701 code = UV_XListVolumes(aserver,
2702 dummyPartList.partId[i],
2707 code = UV_ListVolumes(aserver,
2708 dummyPartList.partId[i],
2713 PrintDiagnostics("listvol", code);
2714 if(pntr) free(pntr);
2717 if (wantExtendedInfo) {
2718 origxInfoP = xInfoP;
2719 base = (char *)xInfoP;
2722 base = (char *)pntr;
2726 if (wantExtendedInfo)
2727 qsort(base, count, sizeof(volintXInfo), XCompareVolName);
2729 qsort(base, count, sizeof(volintInfo), CompareVolName);
2731 if (wantExtendedInfo)
2732 qsort(base, count, sizeof(volintXInfo), XCompareVolID);
2734 qsort(base, count, sizeof(volintInfo), CompareVolID);
2736 MapPartIdIntoName(dummyPartList.partId[i],pname);
2738 fprintf(STDOUT,"Total number of volumes on server %s partition %s: %u \n",as->parms[0].items->data,pname,count);
2739 if (wantExtendedInfo) {
2740 XDisplayVolumes(aserver,
2741 dummyPartList.partId[i],
2749 xInfoP = (volintXInfo *)0;
2752 #ifdef FULL_LISTVOL_SWITCH
2753 if (as->parms[6].items)
2754 DisplayVolumes2(aserver, dummyPartList.partId[i], oldpntr,
2757 #endif /* FULL_LISTVOL_SWITCH */
2758 DisplayVolumes(aserver,
2759 dummyPartList.partId[i],
2767 pntr = (volintInfo *)0;
2775 register struct cmd_syndesc *as;
2777 afs_int32 pname, code; /* part name */
2783 if (as->parms[0].items) {
2784 tserver = GetServer(as->parms[0].items->data);
2786 fprintf(STDERR,"vos: host '%s' not found in host table\n",as->parms[0].items->data );
2791 if (as->parms[1].items) {
2792 pname = volutil_GetPartitionID(as->parms[1].items->data);
2794 fprintf(STDERR,"vos: could not interpret partition name '%s'\n",as->parms[1].items->data );
2797 if (!IsPartValid(pname,tserver,&code)) { /*check for validity of the partition */
2798 if(code) PrintError("",code);
2799 else fprintf(STDERR,"vos: partition %s does not exist on the server\n",
2800 as->parms[1].items->data);
2806 fprintf(STDERR,"The -partition option requires a -server option\n");
2811 if (as->parms[2].items) {
2812 /* Synchronize an individual volume */
2813 volname = as->parms[2].items->data;
2814 code = UV_SyncVolume(tserver, pname, volname, flags);
2817 fprintf(STDERR,"Without a -volume option, the -server option is required\n");
2820 code = UV_SyncVldb(tserver, pname, flags, 0/*unused*/);
2824 PrintDiagnostics("syncvldb", code);
2828 /* Print a summary of what we did */
2829 if (volname) fprintf(STDOUT,"VLDB volume %s synchronized", volname);
2830 else fprintf(STDOUT,"VLDB synchronized");
2832 fprintf(STDOUT," with state of server %s", as->parms[0].items->data);
2835 MapPartIdIntoName(pname,part);
2836 fprintf(STDOUT," partition %s\n", part);
2838 fprintf(STDOUT, "\n");
2843 static SyncServer(as)
2844 register struct cmd_syndesc *as;
2847 afs_int32 pname,code; /* part name */
2852 tserver = GetServer(as->parms[0].items->data);
2854 fprintf(STDERR,"vos: host '%s' not found in host table\n",as->parms[0].items->data );
2857 if(as->parms[1].items){
2858 pname = volutil_GetPartitionID(as->parms[1].items->data);
2860 fprintf(STDERR,"vos: could not interpret partition name '%s'\n",as->parms[1].items->data);
2863 if (!IsPartValid(pname,tserver,&code)){/*check for validity of the partition */
2864 if(code) PrintError("",code);
2865 else fprintf(STDERR,"vos : partition %s does not exist on the server\n",as->parms[1].items->data);
2871 code = UV_SyncServer(tserver, pname, flags, 0/*unused*/);
2873 PrintDiagnostics("syncserv", code);
2877 MapPartIdIntoName(pname,part);
2878 fprintf(STDOUT,"Server %s partition %s synchronized with VLDB\n",as->parms[0].items->data,part);
2880 else fprintf(STDOUT,"Server %s synchronized with VLDB\n",as->parms[0].items->data);
2885 static VolumeInfoCmd(name)
2888 struct nvldbentry entry;
2891 /* The vlserver will handle names with the .readonly
2892 * and .backup extension as well as volume ids.
2894 vcode = VLDB_GetEntryByName(name, &entry);
2896 PrintError("", vcode);
2899 MapHostToNetwork(&entry);
2900 EnumerateEntry(&entry);
2902 /* Defect #3027: grubby check to handle locked volume.
2903 * If VLOP_ALLOPERS is set, the entry is locked.
2904 * Leave this routine as is, but put in correct check.
2906 if (entry.flags & VLOP_ALLOPERS)
2907 fprintf(STDOUT," Volume is currently LOCKED \n");
2912 static VolumeZap(as)
2913 register struct cmd_syndesc *as;
2916 struct nvldbentry entry;
2917 afs_int32 volid,code,server,part, zapbackupid=0, backupid=0, err;
2919 if (as->parms[3].items) {
2920 /* force flag is on, use the other version */
2921 return NukeVolume(as);
2924 if (as->parms[4].items) {
2928 volid = vsu_GetVolumeID(as->parms[2].items->data, cstruct, &err);
2930 if (err) PrintError("", err);
2931 else fprintf(STDERR, "vos: can't find volume '%s'\n", as->parms[2].items->data);
2934 part = volutil_GetPartitionID(as->parms[1].items->data);
2936 fprintf(STDERR,"vos: could not interpret partition name '%s'\n",as->parms[1].items->data );
2939 server = GetServer(as->parms[0].items->data);
2941 fprintf(STDERR,"vos: host '%s' not found in host table\n",as->parms[0].items->data );
2944 if (!IsPartValid(part,server,&code)){/*check for validity of the partition */
2945 if(code) PrintError("",code);
2946 else fprintf(STDERR,"vos : partition %s does not exist on the server\n",as->parms[1].items->data);
2949 code = VLDB_GetEntryByID(volid,-1, &entry);
2951 if (volid == entry.volumeId[RWVOL])
2952 backupid = entry.volumeId[BACKVOL];
2953 fprintf(STDERR,"Warning: Entry for volume number %u exists in VLDB (but we're zapping it anyway!)\n",
2957 volintInfo *pntr = (volintInfo *)0;
2960 code = UV_ListOneVolume(server, part, volid, &pntr);
2962 if (volid == pntr->parentID)
2963 backupid = pntr->backupID;
2964 if (pntr) free(pntr);
2968 code = UV_VolumeZap(server,part, backupid);
2970 PrintDiagnostics("zap", code);
2973 fprintf(STDOUT,"Backup Volume %u deleted\n", backupid);
2976 code = UV_VolumeZap(server,part,volid);
2978 PrintDiagnostics("zap", code);
2981 fprintf(STDOUT,"Volume %u deleted\n",volid);
2986 static VolserStatus(as)
2987 register struct cmd_syndesc *as;
2990 afs_int32 server, code;
2991 transDebugInfo *pntr,*oldpntr;
2996 server = GetServer(as->parms[0].items->data);
2998 fprintf(STDERR,"vos: host '%s' not found in host table\n",as->parms[0].items->data );
3001 code = UV_VolserStatus(server,&pntr,&count);
3003 PrintDiagnostics("status",code);
3008 fprintf(STDOUT,"No active transactions on %s\n",as->parms[0].items->data);
3010 fprintf(STDOUT,"Total transactions: %d\n",count);
3012 for(i = 0; i < count ; i++){
3013 /*print out the relevant info */
3014 fprintf(STDOUT,"--------------------------------------\n");
3015 fprintf(STDOUT,"transaction: %u created: %s",pntr->tid,
3016 ctime((time_t *)&pntr->time));
3017 if(pntr->returnCode){
3018 fprintf(STDOUT,"returnCode: %u\n",pntr->returnCode);
3021 fprintf(STDOUT,"attachFlags: ");
3022 switch(pntr->iflags){
3023 case ITOffline: fprintf(STDOUT,"offline ");
3025 case ITBusy: fprintf(STDOUT,"busy ");
3027 case ITReadOnly: fprintf(STDOUT,"readonly ");
3029 case ITCreate: fprintf(STDOUT,"create ");
3031 case ITCreateVolID: fprintf(STDOUT,"create volid ");
3034 fprintf(STDOUT,"\n");
3037 fprintf(STDOUT,"volumeStatus: ");
3038 switch(pntr->vflags){
3039 case VTDeleteOnSalvage: fprintf(STDOUT,"deleteOnSalvage ");
3040 case VTOutOfService: fprintf(STDOUT,"outOfService ");
3041 case VTDeleted: fprintf(STDOUT,"deleted ");
3043 fprintf(STDOUT,"\n");
3046 fprintf(STDOUT,"transactionFlags: ");
3047 fprintf(STDOUT,"delete\n");
3049 MapPartIdIntoName(pntr->partition ,pname);
3050 fprintf(STDOUT,"volume: %u partition: %s procedure: %s\n",pntr->volid,pname, pntr->lastProcName);
3051 if(pntr->callValid){
3052 fprintf(STDOUT,"packetRead: %u lastReceiveTime: %d packetSend: %u lastSendTime: %d\n",pntr->readNext,pntr->lastReceiveTime,pntr->transmitNext, pntr->lastSendTime);
3055 fprintf(STDOUT,"--------------------------------------\n");
3056 fprintf(STDOUT,"\n");
3058 if(oldpntr) free(oldpntr);
3062 static RenameVolume(as)
3063 register struct cmd_syndesc *as;
3065 afs_int32 code1,code2,code;
3066 struct nvldbentry entry;
3068 code1 = VLDB_GetEntryByName(as->parms[0].items->data, &entry);
3070 fprintf(STDERR,"vos: Could not find entry for volume %s\n",as->parms[0].items->data);
3073 code2 = VLDB_GetEntryByName(as->parms[1].items->data, &entry);
3074 if((!code1) && (!code2)) { /*the newname already exists */
3075 fprintf(STDERR,"vos: volume %s already exists\n",as->parms[1].items->data);
3080 fprintf(STDERR,"vos: Could not find entry for volume %s or %s\n",as->parms[0].items->data,as->parms[1].items->data);
3083 if(!VolNameOK(as->parms[0].items->data)){
3084 fprintf(STDERR,"Illegal volume name %s, should not end in .readonly or .backup\n",as->parms[0].items->data);
3087 if(!ISNAMEVALID(as->parms[1].items->data)) {
3088 fprintf(STDERR,"vos: the new volume name %s exceeds the size limit of %d\n",as->parms[1].items->data,VOLSER_OLDMAXVOLNAME - 10);
3091 if(!VolNameOK(as->parms[1].items->data)){
3092 fprintf(STDERR,"Illegal volume name %s, should not end in .readonly or .backup\n",as->parms[1].items->data);
3095 if(IsNumeric(as->parms[1].items->data)){
3096 fprintf(STDERR,"Illegal volume name %s, should not be a number\n",as->parms[1].items->data);
3099 MapHostToNetwork(&entry);
3100 code = UV_RenameVolume(&entry,as->parms[0].items->data,as->parms[1].items->data);
3102 PrintDiagnostics("rename", code);
3105 fprintf(STDOUT,"Renamed volume %s to %s\n",as->parms[0].items->data,as->parms[1].items->data);
3109 GetVolumeInfo(volid, server, part, voltype,rentry)
3110 afs_int32 *server, volid, *part, *voltype;
3111 register struct nvldbentry *rentry;
3116 vcode = VLDB_GetEntryByID(volid, -1, rentry);
3118 fprintf(STDERR,"Could not fetch the entry for volume %u from VLDB \n",volid);
3119 PrintError("",vcode);
3122 MapHostToNetwork(rentry);
3123 if(volid == rentry->volumeId[ROVOL]){
3125 for (i = 0; i < rentry->nServers; i++) {
3126 if ( (index == -1) && (rentry->serverFlags[i] & ITSROVOL) &&
3127 !(rentry->serverFlags[i] & RO_DONTUSE) )
3131 fprintf(STDERR,"RO volume is not found in VLDB entry for volume %u\n", volid);
3135 *server = rentry->serverNumber[index];
3136 *part = rentry->serverPartition[index];
3140 index = Lp_GetRwIndex(rentry);
3142 fprintf(STDERR,"RW Volume is not found in VLDB entry for volume %u\n", volid);
3145 if(volid == rentry->volumeId[RWVOL]){
3147 *server = rentry->serverNumber[index];
3148 *part = rentry->serverPartition[index];
3151 if(volid == rentry->volumeId[BACKVOL]){
3153 *server = rentry->serverNumber[index];
3154 *part = rentry->serverPartition[index];
3159 static DeleteEntry(as)
3160 register struct cmd_syndesc *as;
3166 struct VldbListByAttributes attributes;
3167 nbulkentries arrayEntries;
3168 register struct nvldbentry *vllist;
3169 struct cmd_item *itp;
3172 char prefix[VOLSER_MAXVOLNAME+1];
3174 afs_int32 totalBack=0, totalFail=0, err;
3176 if (as->parms[0].items) { /* -id */
3177 if (as->parms[1].items || as->parms[2].items || as->parms[3].items) {
3178 fprintf(STDERR,"You cannot use -server, -partition, or -prefix with the -id argument\n");
3181 for (itp=as->parms[0].items; itp; itp=itp->next) {
3182 avolid = vsu_GetVolumeID(itp->data, cstruct, &err);
3184 if (err) PrintError("", err);
3185 else fprintf(STDERR, "vos: can't find volume '%s'\n", itp->data);
3188 if (as->parms[4].items) { /* -noexecute */
3189 fprintf(STDOUT,"Would have deleted VLDB entry for %s \n", itp->data);
3193 vcode = ubik_Call(VL_DeleteEntry,cstruct, 0, avolid, RWVOL);
3195 fprintf(STDERR,"Could not delete entry for volume %s\n", itp->data);
3196 fprintf(STDERR,"You must specify a RW volume name or ID "
3197 "(the entire VLDB entry will be deleted)\n", itp->data);
3198 PrintError("",vcode);
3204 fprintf(STDOUT,"Deleted %d VLDB entries\n", totalBack);
3208 if (!as->parms[1].items && !as->parms[2].items && !as->parms[3].items) {
3209 fprintf(STDERR,"You must specify an option\n");
3213 /* Zero out search attributes */
3214 memset(&attributes, 0, sizeof(struct VldbListByAttributes));
3216 if (as->parms[1].items) { /* -prefix */
3217 strncpy(prefix, as->parms[1].items->data, VOLSER_MAXVOLNAME);
3219 if (!as->parms[2].items && !as->parms[3].items) { /* a single entry only */
3220 fprintf(STDERR,"You must provide -server with the -prefix argument\n");
3225 if (as->parms[2].items) { /* -server */
3227 aserver = GetServer(as->parms[2].items->data);
3229 fprintf(STDERR,"vos: server '%s' not found in host table\n",as->parms[2].items->data );
3232 attributes.server = ntohl(aserver);
3233 attributes.Mask |= VLLIST_SERVER;
3236 if (as->parms[3].items) { /* -partition */
3237 if (!as->parms[2].items) {
3238 fprintf(STDERR,"You must provide -server with the -partition argument\n");
3241 apart = volutil_GetPartitionID(as->parms[3].items->data);
3243 fprintf(STDERR,"vos: could not interpret partition name '%s'\n",
3244 as->parms[3].items->data);
3247 attributes.partition = apart;
3248 attributes.Mask |= VLLIST_PARTITION;
3251 /* Print status line of what we are doing */
3252 fprintf(STDOUT,"Deleting VLDB entries for ");
3253 if (as->parms[2].items) {
3254 fprintf(STDOUT,"server %s ", as->parms[2].items->data);
3256 if (as->parms[3].items) {
3258 MapPartIdIntoName(apart, pname);
3259 fprintf(STDOUT,"partition %s ", pname);
3262 fprintf(STDOUT,"which are prefixed with %s ", prefix);
3264 fprintf(STDOUT,"\n");
3267 /* Get all the VLDB entries on a server and/or partition */
3268 memset(&arrayEntries, 0, sizeof(arrayEntries));
3269 vcode = VLDB_ListAttributes(&attributes, &nentries, &arrayEntries);
3271 fprintf(STDERR,"Could not access the VLDB for attributes\n");
3272 PrintError("",vcode);
3276 /* Process each entry */
3277 for (j=0; j<nentries; j++) {
3278 vllist = &arrayEntries.nbulkentries_val[j];
3280 /* It only deletes the RW volumes */
3281 if (strncmp(vllist->name, prefix, strlen(prefix))){
3283 fprintf(STDOUT,"Omitting to delete %s due to prefix %s mismatch\n",
3284 vllist->name, prefix);
3291 if (as->parms[4].items) { /* -noexecute */
3292 fprintf(STDOUT,"Would have deleted VLDB entry for %s \n", vllist->name);
3297 /* Only matches the RW volume name */
3298 avolid = vllist->volumeId[RWVOL];
3299 vcode = ubik_Call(VL_DeleteEntry, cstruct, 0, avolid, RWVOL);
3301 fprintf(STDOUT,"Could not delete VDLB entry for %s\n",vllist->name);
3303 PrintError("",vcode);
3308 fprintf(STDOUT,"Deleted VLDB entry for %s \n",vllist->name);
3313 fprintf(STDOUT,"----------------------\n");
3314 fprintf(STDOUT,"Total VLDB entries deleted: %u; failed to delete: %u\n",totalBack,totalFail);
3315 if (arrayEntries.nbulkentries_val) free(arrayEntries.nbulkentries_val);
3320 static int CompareVldbEntryByName(p1,p2)
3323 struct nvldbentry *arg1,*arg2;
3325 arg1 = (struct nvldbentry *)p1;
3326 arg2 = (struct nvldbentry *)p2;
3327 return(strcmp(arg1->name,arg2->name));
3331 static int CompareVldbEntry(p1,p2)
3334 struct nvldbentry *arg1,*arg2;
3337 char comp1[100],comp2[100];
3338 char temp1[20],temp2[20];
3340 arg1 = (struct nvldbentry *)p1;
3341 arg2 = (struct nvldbentry *)p2;
3345 for(i = 0; i < arg1->nServers; i++)
3346 if(arg1->serverFlags[i] & ITSRWVOL) pos1 = i;
3347 for(i = 0; i < arg2->nServers; i++)
3348 if(arg2->serverFlags[i] & ITSRWVOL) pos2 = i;
3349 if(pos1 == -1 || pos2 == -1){
3353 sprintf(comp1,"%10u",arg1->serverNumber[pos1]);
3354 sprintf(comp2,"%10u",arg2->serverNumber[pos2]);
3355 sprintf(temp1,"%10u",arg1->serverPartition[pos1]);
3356 sprintf(temp2,"%10u",arg2->serverPartition[pos2]);
3357 strcat(comp1,temp1);
3358 strcat(comp2,temp2);
3359 strcat(comp1,arg1->name);
3360 strcat(comp1,arg2->name);
3361 return(strcmp(comp1,comp2));
3367 struct cmd_syndesc *as;
3370 afs_int32 aserver,code;
3372 struct VldbListByAttributes attributes;
3373 nbulkentries arrayEntries;
3374 struct nvldbentry *vllist, *tarray=0, *ttarray;
3375 afs_int32 centries, nentries = 0, tarraysize, parraysize;
3378 int quiet, sort, lock;
3379 afs_int32 thisindex, nextindex;
3384 attributes.Mask = 0;
3385 lock = (as->parms[3].items ? 1 : 0); /* -lock flag */
3386 quiet = (as->parms[4].items ? 1 : 0); /* -quit flag */
3387 sort = (as->parms[5].items ? 0 : 1); /* -nosort flag */
3389 /* If the volume name is given, Use VolumeInfoCmd to look it up
3390 * and not ListAttributes.
3392 if (as->parms[0].items) {
3394 fprintf(STDERR,"vos: illegal use of '-locked' switch, need to specify server and/or partition\n");
3397 code = VolumeInfoCmd(as->parms[0].items->data);
3399 PrintError("",code);
3405 /* Server specified */
3406 if (as->parms[1].items) {
3407 aserver = GetServer(as->parms[1].items->data);
3409 fprintf(STDERR,"vos: server '%s' not found in host table\n",as->parms[1].items->data );
3412 attributes.server = ntohl(aserver);
3413 attributes.Mask |= VLLIST_SERVER;
3416 /* Partition specified */
3417 if (as->parms[2].items) {
3418 apart = volutil_GetPartitionID(as->parms[2].items->data);
3420 fprintf(STDERR,"vos: could not interpret partition name '%s'\n", as->parms[2].items->data);
3423 attributes.partition = apart;
3424 attributes.Mask |= VLLIST_PARTITION;
3428 attributes.Mask |= VLLIST_FLAG;
3429 attributes.flag = VLOP_ALLOPERS;
3432 /* Print header information */
3434 MapPartIdIntoName(apart, pname);
3435 fprintf(STDOUT,"VLDB entries for %s %s%s%s %s\n",
3436 (as->parms[1].items ? "server" : "all" ),
3437 (as->parms[1].items ? as->parms[1].items->data : "servers"),
3438 (as->parms[2].items ? " partition " : ""),
3439 (as->parms[2].items ? pname : ""),
3440 (lock ? "which are locked:" : ""));
3443 for (thisindex = 0; (thisindex != -1); thisindex = nextindex) {
3444 memset(&arrayEntries, 0, sizeof(arrayEntries));
3448 vcode = VLDB_ListAttributesN2(&attributes, 0, thisindex,
3449 ¢ries, &arrayEntries, &nextindex);
3450 if (vcode == RXGEN_OPCODE) {
3451 /* Vlserver not running with ListAttributesN2. Fall back */
3452 vcode = VLDB_ListAttributes(&attributes, ¢ries, &arrayEntries);
3456 fprintf(STDERR,"Could not access the VLDB for attributes\n");
3457 PrintError("",vcode);
3460 nentries += centries;
3462 /* We don't sort, so just print the entries now */
3464 for (j = 0; j < centries; j++) { /* process each entry */
3465 vllist = &arrayEntries.nbulkentries_val[j];
3466 MapHostToNetwork(vllist);
3467 EnumerateEntry(vllist);
3469 if(vllist->flags & VLOP_ALLOPERS)
3470 fprintf(STDOUT," Volume is currently LOCKED \n");
3474 /* So we sort. First we must collect all the entries and keep
3477 else if (centries > 0) {
3479 /* steal away the first bulk entries array */
3480 tarray = (struct nvldbentry *)arrayEntries.nbulkentries_val;
3481 tarraysize = centries * sizeof(struct nvldbentry);
3482 arrayEntries.nbulkentries_val = 0;
3484 /* Grow the tarray to keep the extra entries */
3485 parraysize = (centries * sizeof(struct nvldbentry));
3486 ttarray = (struct nvldbentry *) realloc(tarray, tarraysize + parraysize);
3488 fprintf(STDERR,"Could not allocate enough space for the VLDB entries\n");
3494 memcpy(((char *)tarray)+tarraysize, (char *)arrayEntries.nbulkentries_val, parraysize);
3495 tarraysize += parraysize;
3499 /* Free the bulk array */
3500 if (arrayEntries.nbulkentries_val) {
3501 free(arrayEntries.nbulkentries_val);
3502 arrayEntries.nbulkentries_val = 0;
3506 /* Here is where we now sort all the entries and print them */
3507 if (sort && (nentries > 0)) {
3508 qsort((char *)tarray, nentries, sizeof(struct nvldbentry), CompareVldbEntryByName);
3509 for (vllist=tarray, j=0; j<nentries; j++, vllist++) {
3510 MapHostToNetwork(vllist);
3511 EnumerateEntry(vllist);
3513 if(vllist->flags & VLOP_ALLOPERS)
3514 fprintf(STDOUT," Volume is currently LOCKED \n");
3519 if (!quiet) fprintf(STDOUT,"\nTotal entries: %u\n", nentries);
3520 if (tarray) free(tarray);
3525 register struct cmd_syndesc *as;
3527 afs_int32 apart=0, avolid;
3528 afs_int32 aserver=0, code, aserver1, apart1;
3530 struct VldbListByAttributes attributes;
3531 nbulkentries arrayEntries;
3532 register struct nvldbentry *vllist;
3536 int seenprefix, seenxprefix, exclude, ex, exp, noaction;
3537 afs_int32 totalBack=0;
3538 afs_int32 totalFail=0;
3539 int previdx=-1, error, same;
3542 struct cmd_item *ti;
3546 memset(&attributes, 0, sizeof(struct VldbListByAttributes));
3547 attributes.Mask = 0;
3549 seenprefix = (as->parms[0].items ? 1 : 0);
3550 exclude = (as->parms[3].items ? 1 : 0);
3551 seenxprefix = (as->parms[4].items ? 1 : 0);
3552 noaction = (as->parms[5].items ? 1 : 0);
3554 if (as->parms[1].items) { /* -server */
3555 aserver = GetServer(as->parms[1].items->data);
3557 fprintf(STDERR,"vos: server '%s' not found in host table\n",as->parms[1].items->data );
3560 attributes.server = ntohl(aserver);
3561 attributes.Mask |= VLLIST_SERVER;
3564 if (as->parms[2].items) { /* -partition */
3565 apart = volutil_GetPartitionID(as->parms[2].items->data);
3567 fprintf(STDERR,"vos: could not interpret partition name '%s'\n", as->parms[2].items->data);
3570 attributes.partition = apart;
3571 attributes.Mask |= VLLIST_PARTITION;
3574 /* Check to make sure the prefix and xprefix expressions compile ok */
3576 for (ti=as->parms[0].items; ti; ti=ti->next) {
3577 if (strncmp(ti->data,"^",1) == 0) {
3578 ccode = (char *)re_comp(ti->data);
3580 fprintf(STDERR,"Unrecognizable -prefix regular expression: '%s': %s\n",
3588 for (ti=as->parms[4].items; ti; ti=ti->next) {
3589 if (strncmp(ti->data,"^",1) == 0) {
3590 ccode = (char *)re_comp(ti->data);
3592 fprintf(STDERR,"Unrecognizable -xprefix regular expression: '%s': %s\n",
3600 memset(&arrayEntries, 0, sizeof(arrayEntries)); /* initialize to hint the stub to alloc space */
3601 vcode = VLDB_ListAttributes(&attributes, &nentries, &arrayEntries);
3603 fprintf(STDERR,"Could not access the VLDB for attributes\n");
3604 PrintError("",vcode);
3608 if (as->parms[1].items || as->parms[2].items || verbose) {
3609 fprintf(STDOUT,"%s up volumes", (noaction?"Would have backed":"Backing"));
3611 if (as->parms[1].items) {
3612 fprintf(STDOUT," on server %s", as->parms[1].items->data);
3613 } else if (as->parms[2].items) {
3614 fprintf(STDOUT," for all servers");
3617 if (as->parms[2].items) {
3618 MapPartIdIntoName(apart, pname);
3619 fprintf(STDOUT," partition %s", pname);
3622 if (seenprefix || (!seenprefix && seenxprefix)) {
3623 ti = (seenprefix ? as->parms[0].items : as->parms[4].items);
3624 ex = (seenprefix ? exclude : !exclude);
3625 exp = (strncmp(ti->data,"^",1) == 0);
3626 fprintf(STDOUT," which %smatch %s '%s'", (ex ? "do not " : ""),
3627 (exp?"expression":"prefix"), ti->data);
3628 for (ti=ti->next; ti; ti=ti->next) {
3629 exp = (strncmp(ti->data,"^",1) == 0);
3630 printf(" %sor %s '%s'", (ex ? "n" : ""),
3631 (exp?"expression":"prefix"), ti->data);
3635 if (seenprefix && seenxprefix) {
3636 ti = as->parms[4].items;
3637 exp = (strncmp(ti->data,"^",1) == 0);
3638 fprintf(STDOUT," %swhich match %s '%s'",
3639 (exclude?"adding those ":"removing those "),
3640 (exp?"expression":"prefix"), ti->data);
3641 for (ti=ti->next; ti; ti=ti->next) {
3642 exp = (strncmp(ti->data,"^",1) == 0);
3643 printf(" or %s '%s'", (exp?"expression":"prefix"), ti->data);
3646 fprintf(STDOUT," .. ");
3647 if (verbose) fprintf(STDOUT,"\n");
3651 for (j=0; j<nentries; j++) { /* process each vldb entry */
3652 vllist = &arrayEntries.nbulkentries_val[j];
3655 for (ti=as->parms[0].items; ti; ti=ti->next) {
3656 if (strncmp(ti->data,"^",1) == 0) {
3657 ccode = (char *)re_comp(ti->data);
3659 fprintf(STDERR,"Error in -prefix regular expression: '%s': %s\n",
3663 match = (re_exec(vllist->name) == 1);
3665 match = (strncmp(vllist->name,ti->data,strlen(ti->data)) == 0);
3673 /* Without the -exclude flag: If it matches the prefix, then
3674 * check if we want to exclude any from xprefix.
3675 * With the -exclude flag: If it matches the prefix, then
3676 * check if we want to add any from xprefix.
3678 if (match && seenxprefix) {
3679 for (ti=as->parms[4].items; ti; ti=ti->next) {
3680 if (strncmp(ti->data,"^",1) == 0) {
3681 ccode = (char *)re_comp(ti->data);
3683 fprintf(STDERR,"Error in -xprefix regular expression: '%s': %s\n",
3687 if (re_exec(vllist->name) == 1) {
3692 if (strncmp(vllist->name,ti->data,strlen(ti->data)) == 0) {
3700 if (exclude) match = !match; /* -exclude will reverse the match */
3701 if (!match) continue; /* Skip if no match */
3703 /* Print list of volumes to backup */
3705 fprintf(STDOUT," %s\n", vllist->name);
3709 if(!(vllist->flags & RW_EXISTS)){
3711 fprintf(STDOUT,"Omitting to backup %s since RW volume does not exist \n", vllist->name);
3712 fprintf(STDOUT,"\n");
3718 avolid = vllist->volumeId[RWVOL];
3719 MapHostToNetwork(vllist);
3720 GetServerAndPart(vllist,RWVOL,&aserver1,&apart1,&previdx);
3721 if(aserver1 == -1 || apart1 == -1){
3722 fprintf(STDOUT,"could not backup %s, invalid VLDB entry\n",vllist->name);
3727 same = VLDB_IsSameAddrs(aserver, aserver1, &error);
3729 fprintf(STDERR,"Failed to get info about server's %d address(es) from vlserver (err=%d); aborting call!\n",
3735 if ((aserver && !same) || (apart && (apart != apart1))) {
3737 fprintf(STDOUT, "Omitting to backup %s since the RW is in a different location\n", vllist->name);
3742 time_t now = time(0);
3743 fprintf(STDOUT,"Creating backup volume for %s on %s",vllist->name, ctime(&now));
3747 code = UV_BackupVolume(aserver1, apart1, avolid);
3749 fprintf(STDOUT,"Could not backup %s\n",vllist->name);
3755 if (verbose) fprintf(STDOUT,"\n");
3757 } /* process each vldb entry */
3758 fprintf(STDOUT,"done\n");
3759 fprintf(STDOUT,"Total volumes backed up: %u; failed to backup: %u\n",totalBack,totalFail);
3761 if(arrayEntries.nbulkentries_val) free(arrayEntries.nbulkentries_val);
3765 static UnlockVLDB(as)
3766 register struct cmd_syndesc *as;
3769 afs_int32 aserver,code;
3771 struct VldbListByAttributes attributes;
3772 nbulkentries arrayEntries;
3773 register struct nvldbentry *vllist;
3782 attributes.Mask = 0;
3784 if(as->parms[0].items) {/* server specified */
3785 aserver = GetServer(as->parms[0].items->data);
3787 fprintf(STDERR,"vos: server '%s' not found in host table\n",as->parms[0].items->data );
3790 attributes.server = ntohl(aserver);
3791 attributes.Mask |= VLLIST_SERVER;
3793 if(as->parms[1].items) {/* partition specified */
3794 apart = volutil_GetPartitionID(as->parms[1].items->data);
3796 fprintf(STDERR,"vos: could not interpret partition name '%s'\n", as->parms[1].items->data);
3799 if (!IsPartValid(apart,aserver,&code)){/*check for validity of the partition */
3800 if(code) PrintError("",code);
3801 else fprintf(STDERR,"vos : partition %s does not exist on the server\n",as->parms[1].items->data);
3804 attributes.partition = apart;
3805 attributes.Mask |= VLLIST_PARTITION;
3807 attributes.flag = VLOP_ALLOPERS;
3808 attributes.Mask |= VLLIST_FLAG;
3809 memset(&arrayEntries, 0, sizeof(arrayEntries)); /*initialize to hint the stub to alloc space */
3810 vcode = VLDB_ListAttributes(&attributes, &nentries, &arrayEntries);
3812 fprintf(STDERR,"Could not access the VLDB for attributes\n");
3813 PrintError("",vcode);
3816 for(j=0;j<nentries;j++) { /* process each entry */
3817 vllist = &arrayEntries.nbulkentries_val[j];
3818 volid = vllist->volumeId[RWVOL];
3819 vcode = ubik_Call(VL_ReleaseLock,cstruct, 0, volid,-1, LOCKREL_OPCODE | LOCKREL_AFSID | LOCKREL_TIMESTAMP);
3821 fprintf(STDERR,"Could not unlock entry for volume %s\n",vllist->name);
3822 PrintError("",vcode);
3827 MapPartIdIntoName(apart,pname);
3828 if(totalE) fprintf(STDOUT,"Could not lock %u VLDB entries of %u locked entries\n",totalE,nentries);
3830 if(as->parms[0].items) {
3831 fprintf(STDOUT,"Unlocked all the VLDB entries for volumes on server %s ",as->parms[0].items->data);
3832 if(as->parms[1].items){
3833 MapPartIdIntoName(apart,pname);
3834 fprintf(STDOUT,"partition %s\n",pname);
3836 else fprintf(STDOUT,"\n");
3839 else if(as->parms[1].items){
3840 MapPartIdIntoName(apart,pname);
3841 fprintf(STDOUT,"Unlocked all the VLDB entries for volumes on partition %s on all servers\n",pname);
3845 if(arrayEntries.nbulkentries_val) free(arrayEntries.nbulkentries_val);
3849 static PartitionInfo(as)
3850 register struct cmd_syndesc *as;
3853 afs_int32 aserver,code;
3855 struct diskPartition partition;
3856 struct partList dummyPartList;
3860 aserver = GetServer(as->parms[0].items->data);
3862 fprintf(STDERR,"vos: server '%s' not found in host table\n",as->parms[0].items->data );
3865 if(as->parms[1].items){
3866 apart = volutil_GetPartitionID(as->parms[1].items->data);
3868 fprintf(STDERR,"vos: could not interpret partition name '%s'\n", as->parms[1].items->data);
3871 dummyPartList.partId[0] = apart;
3872 dummyPartList.partFlags[0] = PARTVALID;
3876 if (!IsPartValid(apart,aserver,&code)){/*check for validity of the partition */
3877 if(code) PrintError("",code);
3878 else fprintf(STDERR,"vos : partition %s does not exist on the server\n",as->parms[1].items->data);
3883 code = UV_ListPartitions(aserver,&dummyPartList, &cnt);
3885 PrintDiagnostics("listpart", code);
3889 for(i = 0 ; i < cnt ; i++){
3890 if(dummyPartList.partFlags[i] & PARTVALID){
3891 MapPartIdIntoName(dummyPartList.partId[i],pname);
3892 code = UV_PartitionInfo(aserver,pname,&partition);
3894 fprintf(STDERR,"Could not get information on partition %s\n",pname);
3895 PrintError("",code);
3898 fprintf(STDOUT,"Free space on partition %s: %d K blocks out of total %d\n",pname,partition.free,partition.minFree);
3904 static ChangeAddr(as)
3905 register struct cmd_syndesc *as;
3908 afs_int32 ip1, ip2, vcode;
3911 ip1 = GetServer(as->parms[0].items->data);
3913 fprintf(STDERR, "vos: invalid host address\n");
3917 if ( ( as->parms[1].items && as->parms[2].items) ||
3918 (!as->parms[1].items && !as->parms[2].items) ) {
3919 fprintf(STDERR, "vos: Must specify either '-newaddr <addr>' or '-remove' flag\n");
3923 if (as->parms[1].items) {
3924 ip2 = GetServer(as->parms[1].items->data);
3926 fprintf(STDERR, "vos: invalid host address\n");
3930 /* Play a trick here. If we are removing an address, ip1 will be -1
3931 * and ip2 will be the original address. This switch prevents an
3932 * older revision vlserver from removing the IP address.
3939 vcode = ubik_Call_New(VL_ChangeAddr, cstruct, 0, ntohl(ip1), ntohl(ip2) );
3942 fprintf(STDERR,"Could not remove server %s from the VLDB\n",
3943 as->parms[0].items->data);
3944 if (vcode == VL_NOENT) {
3945 fprintf(STDERR, "vlserver does not support the remove flag or ");
3948 fprintf(STDERR,"Could not change server %s to server %s\n",
3949 as->parms[0].items->data, as->parms[1].items->data);
3951 PrintError("",vcode);
3956 fprintf(STDOUT,"Removed server %s from the VLDB\n",
3957 as->parms[0].items->data);
3959 fprintf(STDOUT,"Changed server %s to server %s\n",
3960 as->parms[0].items->data, as->parms[1].items->data);
3966 print_addrs(const bulkaddrs *addrs, const afsUUID *m_uuid, int nentries, int print, int noresolve)
3970 struct VLCallBack unused;
3973 ListAddrByAttributes m_attrs;
3974 afs_int32 m_unique, m_nentries, *m_addrp;
3975 afs_int32 base, index;
3979 afsUUID_to_string(m_uuid, buf, sizeof(buf));
3980 printf("UUID: %s\n", buf);
3983 /* print out the list of all the server */
3984 addrp = (afs_int32 *)addrs->bulkaddrs_val;
3985 for (i=0; i<nentries; i++, addrp++) {
3986 /* If it is a multihomed address, then we will need to
3987 * get the addresses for this multihomed server from
3988 * the vlserver and print them.
3990 if ( ((*addrp & 0xff000000) == 0xff000000) && ((*addrp)&0xffff) ) {
3991 /* Get the list of multihomed fileservers */
3992 base = (*addrp>>16) & 0xff;
3993 index = (*addrp) & 0xffff;
3995 if ( (base >= 0) && (base <= VL_MAX_ADDREXTBLKS) &&
3996 (index >= 1) && (index <= VL_MHSRV_PERBLK) ) {
3997 m_attrs.Mask = VLADDR_INDEX;
3998 m_attrs.index = (base * VL_MHSRV_PERBLK) + index;
4000 m_addrs.bulkaddrs_val = 0;
4001 m_addrs.bulkaddrs_len = 0;
4002 vcode = ubik_Call(VL_GetAddrsU, cstruct, 0,
4003 &m_attrs, &m_uuid, &m_unique, &m_nentries, &m_addrs);
4005 fprintf(STDERR,"vos: could not list the multi-homed server addresses\n");
4006 PrintError("",vcode);
4009 /* Print the list */
4010 m_addrp = (afs_int32 *)m_addrs.bulkaddrs_val;
4011 for (j=0; j<m_nentries; j++, m_addrp++) {
4012 *m_addrp = htonl(*m_addrp);
4015 printf("%s ", afs_inet_ntoa_r(*m_addrp,hoststr));
4017 printf("%s ", hostutil_GetNameByINet(*m_addrp));
4021 printf("<unknown>\n");
4030 /* Otherwise, it is a non-multihomed entry and contains
4031 * the IP address of the server - print it.
4033 *addrp = htonl(*addrp);
4036 printf("%s\n", afs_inet_ntoa_r(*addrp,hoststr));
4038 printf("%s\n", hostutil_GetNameByINet(*addrp));
4048 static ListAddrs(as)
4049 register struct cmd_syndesc *as;
4052 afs_int32 i, j, noresolve=0, printuuid=0;
4053 struct VLCallBack unused;
4054 afs_int32 nentries, *addrp;
4055 bulkaddrs addrs, m_addrs;
4056 ListAddrByAttributes m_attrs;
4057 afsUUID m_uuid, askuuid;
4058 afs_int32 m_unique, m_nentries, *m_addrp;
4059 afs_int32 base, index;
4061 memset(&m_attrs, 0, sizeof(struct ListAddrByAttributes));
4062 m_attrs.Mask = VLADDR_INDEX;
4064 memset(&m_addrs, 0, sizeof(bulkaddrs));
4065 memset(&askuuid, 0, sizeof(afsUUID));
4066 if (as->parms[0].items) {
4068 afsUUID_from_string(as->parms[0].items->data, &askuuid);
4069 m_attrs.Mask = VLADDR_UUID;
4070 m_attrs.uuid = askuuid;
4072 if (as->parms[1].items) {
4076 he = hostutil_GetHostByName((char*)as->parms[1].items->data);
4079 "Can't get host info for '%s'\n",
4080 as->parms[1].items->data);
4083 memcpy(&saddr, he->h_addr, 4);
4084 m_attrs.Mask = VLADDR_IPADDR;
4085 m_attrs.ipaddr = ntohl(saddr);
4087 if (as->parms[2].items) {
4090 if (as->parms[3].items) {
4094 m_addrs.bulkaddrs_val = 0;
4095 m_addrs.bulkaddrs_len = 0;
4097 vcode = ubik_Call_New(VL_GetAddrs, cstruct, 0,
4098 0, 0, &m_unique, &nentries, &m_addrs);
4100 fprintf(STDERR,"vos: could not list the server addresses\n");
4101 PrintError("",vcode);
4106 m_addrs.bulkaddrs_val = 0;
4107 m_addrs.bulkaddrs_len = 0;
4112 vcode = ubik_Call_New(VL_GetAddrsU, cstruct, 0, &m_attrs, &m_uuid,
4113 &m_unique, &m_nentries, &m_addrs);
4114 if(vcode == VL_NOENT) {
4120 if (vcode == VL_INDEXERANGE) {
4125 fprintf(STDERR,"vos: could not list the server addresses\n");
4126 PrintError("",vcode);
4130 print_addrs(&m_addrs, &m_uuid, m_nentries, printuuid, noresolve);
4133 if ((as->parms[1].items)||(as->parms[0].items)||(i>nentries))
4140 static LockEntry(as)
4141 register struct cmd_syndesc *as;
4144 afs_int32 avolid,vcode, err;
4146 avolid = vsu_GetVolumeID(as->parms[0].items->data, cstruct, &err);
4148 if (err) PrintError("", err);
4149 else fprintf(STDERR, "vos: can't find volume '%s'\n", as->parms[0].items->data);
4152 vcode = ubik_Call(VL_SetLock,cstruct, 0, avolid, -1, VLOP_DELETE);
4154 fprintf(STDERR,"Could not lock VLDB entry for volume %s\n",as->parms[0].items->data);
4155 PrintError("",vcode);
4158 fprintf(STDOUT,"Locked VLDB entry for volume %s\n",as->parms[0].items->data);
4162 static ConvertRO(as)
4163 register struct cmd_syndesc *as;
4166 afs_int32 partition = -1;
4167 afs_int32 server, volid, code, i, same;
4168 struct nvldbentry entry, storeEntry;
4171 afs_int32 rwserver = 0;
4172 afs_int32 rwpartition;
4174 afs_int32 roserver = 0;
4175 afs_int32 ropartition;
4177 struct rx_connection *aconn;
4180 server = GetServer(as->parms[0].items->data);
4182 fprintf(STDERR,"vos: host '%s' not found in host table\n",as->parms[0].items->data );
4185 partition = volutil_GetPartitionID(as->parms[1].items->data);
4186 if (partition < 0) {
4187 fprintf(STDERR,"vos: could not interpret partition name '%s'\n",as->parms[1].items->data );
4190 if (!IsPartValid(partition, server, &code)) {
4191 if(code) PrintError("",code);
4192 else fprintf(STDERR,"vos : partition %s does not exist on the server\n",as->parms[1].items->data);
4195 volid = vsu_GetVolumeID(as->parms[2].items->data, cstruct, &code);
4197 if (code) PrintError("", code);
4198 else fprintf(STDERR, "Unknown volume ID or name '%s'\n", as->parms[0].items->data);
4201 if (as->parms[3].items)
4204 vcode = VLDB_GetEntryByID (volid, -1, &entry);
4206 fprintf(STDERR,"Could not fetch the entry for volume %u from VLDB\n",
4208 PrintError("convertROtoRW", code);
4212 /* use RO volid even if user specified RW or BK volid */
4214 if (volid != entry.volumeId[ROVOL])
4215 volid = entry.volumeId[ROVOL];
4217 MapHostToNetwork(&entry);
4218 for (i=0; i< entry.nServers; i++) {
4219 if (entry.serverFlags[i] & ITSRWVOL) {
4221 rwserver = entry.serverNumber[i];
4222 rwpartition = entry.serverPartition[i];
4224 if (entry.serverFlags[i] & ITSROVOL) {
4225 same = VLDB_IsSameAddrs(server, entry.serverNumber[i], &code);
4227 fprintf(STDERR, "Failed to get info about server's %d address(es) from vlserver (err=%d); aborting call!\n",
4233 roserver = entry.serverNumber[i];
4234 ropartition = entry.serverPartition[i];
4240 fprintf(STDERR, "Warning: RO volume didn't exist in vldb!\n");
4242 if (ropartition != partition) {
4243 fprintf(STDERR, "Warning: RO volume should be in partition %d instead of %d (vldb)\n", ropartition, partition);
4248 "VLDB indicates that a RW volume exists already on %s in partition %s.\n", hostutil_GetNameByINet(rwserver), volutil_PartitionName(rwpartition));
4250 fprintf(STDERR, "Overwrite this VLDB entry? [y|n] (n)\n");
4252 while (!(dc==EOF || dc=='\n')) dc=getchar(); /* goto end of line */
4253 if ((c != 'y') && (c != 'Y')) {
4254 fprintf(STDERR, "aborted.\n");
4260 vcode = ubik_Call(VL_SetLock, cstruct, 0, entry.volumeId[RWVOL], RWVOL,
4262 aconn = UV_Bind(server, AFSCONF_VOLUMEPORT);
4263 code = AFSVolConvertROtoRWvolume(aconn, partition, volid);
4265 fprintf(STDERR,"Converting RO volume %u to RW volume failed with code %d\n", volid, code);
4266 PrintError("convertROtoRW ", code);
4269 entry.serverFlags[roindex] = ITSRWVOL;
4270 entry.flags |= RW_EXISTS;
4271 entry.flags &= ~BACK_EXISTS;
4274 if (rwindex != entry.nServers) {
4275 entry.serverNumber[rwindex] = entry.serverNumber[entry.nServers];
4276 entry.serverPartition[rwindex] = entry.serverPartition[entry.nServers];
4277 entry.serverFlags[rwindex] = entry.serverFlags[entry.nServers];
4278 entry.serverNumber[entry.nServers] = 0;
4279 entry.serverPartition[entry.nServers] = 0;
4280 entry.serverFlags[entry.nServers] = 0;
4283 entry.flags &= ~RO_EXISTS;
4284 for (i=0; i<entry.nServers; i++) {
4285 if (entry.serverFlags[i] & ITSROVOL) {
4286 if (!(entry.serverFlags[i] & (RO_DONTUSE | NEW_REPSITE)))
4287 entry.flags |= RO_EXISTS;
4290 MapNetworkToHost(&entry, &storeEntry);
4291 code = VLDB_ReplaceEntry(entry.volumeId[RWVOL], RWVOL, &storeEntry,
4292 (LOCKREL_OPCODE | LOCKREL_AFSID | LOCKREL_TIMESTAMP));
4294 fprintf(STDERR, "Warning: volume converted, but vldb update failed with code %d!\n", code);
4296 vcode = UV_LockRelease(entry.volumeId[RWVOL]);
4298 PrintDiagnostics("unlock", vcode);
4303 PrintDiagnostics(astring, acode)
4307 if (acode == EACCES) {
4308 fprintf(STDERR,"You are not authorized to perform the 'vos %s' command (%d)\n",
4312 fprintf(STDERR,"Error in vos %s command.\n", astring);
4313 PrintError("", acode);
4319 static MyBeforeProc(as, arock)
4320 struct cmd_syndesc *as;
4322 register char *tcell;
4323 register afs_int32 code;
4324 register afs_int32 sauth;
4326 /* Initialize the ubik_client connection */
4327 rx_SetRxDeadTime(90);
4328 cstruct = (struct ubik_client *)0;
4332 if (as->parms[12].items) /* if -cell specified */
4333 tcell = as->parms[12].items->data;
4334 if(as->parms[14].items) /* -serverauth specified */
4336 if(as->parms[16].items) /* -crypt specified */
4338 if (code = vsu_ClientInit((as->parms[13].items != 0), confdir, tcell, sauth,
4339 &cstruct, UV_SetSecurity)) {
4340 fprintf(STDERR,"could not initialize VLDB library (code=%u) \n",code);
4344 if(as->parms[15].items) /* -verbose flag set */
4353 /* this sucks but it works for now.
4358 #include "AFS_component_version_number.c"
4363 register afs_int32 code;
4365 register struct cmd_syndesc *ts;
4367 #ifdef AFS_AIX32_ENV
4369 * The following signal action for AIX is necessary so that in case of a
4370 * crash (i.e. core is generated) we can include the user's data section
4371 * in the core dump. Unfortunately, by default, only a partial core is
4372 * generated which, in many cases, isn't too useful.
4374 struct sigaction nsa;
4376 sigemptyset(&nsa.sa_mask);
4377 nsa.sa_handler = SIG_DFL;
4378 nsa.sa_flags = SA_FULLDUMP;
4379 sigaction(SIGSEGV, &nsa, NULL);
4382 confdir = AFSDIR_CLIENT_ETC_DIRPATH;
4384 cmd_SetBeforeProc(MyBeforeProc, NULL);
4386 ts = cmd_CreateSyntax("create", CreateVolume, 0, "create a new volume");
4387 cmd_AddParm(ts, "-server", CMD_SINGLE, 0, "machine name");
4388 cmd_AddParm(ts, "-partition", CMD_SINGLE, 0, "partition name");
4389 cmd_AddParm(ts, "-name", CMD_SINGLE, 0, "volume name");
4390 cmd_AddParm(ts, "-maxquota", CMD_SINGLE, CMD_OPTIONAL, "initial quota (KB)");
4392 cmd_AddParm(ts, "-minquota", CMD_SINGLE, CMD_OPTIONAL, "");
4396 ts = cmd_CreateSyntax("remove", DeleteVolume, 0, "delete a volume");
4397 cmd_AddParm(ts, "-server", CMD_SINGLE, CMD_OPTIONAL, "machine name");
4398 cmd_AddParm(ts, "-partition", CMD_SINGLE, CMD_OPTIONAL, "partition name");
4399 cmd_AddParm(ts, "-id", CMD_SINGLE, 0, "volume name or ID");
4403 ts = cmd_CreateSyntax("move", MoveVolume, 0, "move a volume");
4404 cmd_AddParm(ts, "-id", CMD_SINGLE, 0, "volume name or ID");
4405 cmd_AddParm(ts, "-fromserver", CMD_SINGLE, 0, "machine name on source");
4406 cmd_AddParm(ts, "-frompartition", CMD_SINGLE, 0, "partition name on source");
4407 cmd_AddParm(ts, "-toserver", CMD_SINGLE, 0, "machine name on destination");
4408 cmd_AddParm(ts, "-topartition", CMD_SINGLE, 0, "partition name on destination");
4411 ts = cmd_CreateSyntax("copy", CopyVolume, 0, "copy a volume");
4412 cmd_AddParm(ts, "-id", CMD_SINGLE, 0, "volume name or ID on source");
4413 cmd_AddParm(ts, "-fromserver", CMD_SINGLE, 0, "machine name on source");
4414 cmd_AddParm(ts, "-frompartition", CMD_SINGLE, 0, "partition name on source");
4415 cmd_AddParm(ts, "-toname", CMD_SINGLE, 0, "volume name on destination");
4416 cmd_AddParm(ts, "-toserver", CMD_SINGLE, 0, "machine name on destination");
4417 cmd_AddParm(ts, "-topartition", CMD_SINGLE, 0, "partition name on destination");
4420 ts = cmd_CreateSyntax("backup", BackupVolume, 0, "make backup of a volume");
4421 cmd_AddParm(ts, "-id", CMD_SINGLE, 0, "volume name or ID");
4424 ts = cmd_CreateSyntax("release", ReleaseVolume, 0, "release a volume");
4425 cmd_AddParm(ts, "-id", CMD_SINGLE, 0, "volume name or ID");
4426 cmd_AddParm(ts, "-force", CMD_FLAG, CMD_OPTIONAL, "force a complete release");
4429 ts = cmd_CreateSyntax("dump", DumpVolume, 0, "dump a volume");
4430 cmd_AddParm(ts, "-id", CMD_SINGLE, 0, "volume name or ID");
4431 cmd_AddParm(ts, "-time", CMD_SINGLE, CMD_OPTIONAL, "dump from time");
4432 cmd_AddParm(ts, "-file", CMD_SINGLE, CMD_OPTIONAL, "dump file");
4433 cmd_AddParm(ts, "-server", CMD_SINGLE, CMD_OPTIONAL, "server");
4434 cmd_AddParm(ts, "-partition", CMD_SINGLE, CMD_OPTIONAL, "partition");
4435 cmd_AddParm(ts, "-clone", CMD_FLAG, CMD_OPTIONAL, "dump a clone of the volume");
4438 ts = cmd_CreateSyntax("restore", RestoreVolume, 0, "restore a volume");
4439 cmd_AddParm(ts, "-server", CMD_SINGLE, 0, "machine name");
4440 cmd_AddParm(ts, "-partition", CMD_SINGLE, 0, "partition name");
4441 cmd_AddParm(ts, "-name", CMD_SINGLE, 0, "name of volume to be restored");
4442 cmd_AddParm(ts, "-file", CMD_SINGLE,CMD_OPTIONAL, "dump file");
4443 cmd_AddParm(ts, "-id", CMD_SINGLE,CMD_OPTIONAL, "volume ID");
4444 cmd_AddParm(ts, "-overwrite", CMD_SINGLE,CMD_OPTIONAL, "abort | full | incremental");
4445 cmd_AddParm(ts, "-offline", CMD_FLAG, CMD_OPTIONAL,
4446 "leave restored volume offline");
4447 cmd_AddParm(ts, "-readonly", CMD_FLAG, CMD_OPTIONAL,
4448 "make restored volume read-only");
4451 ts = cmd_CreateSyntax("unlock", LockReleaseCmd, 0, "release lock on VLDB entry for a volume");
4452 cmd_AddParm(ts, "-id", CMD_SINGLE, 0, "volume name or ID");
4455 ts = cmd_CreateSyntax("changeloc", ChangeLocation, 0, "change an RW volume's location in the VLDB");
4456 cmd_AddParm(ts, "-server", CMD_SINGLE, 0, "machine name for new location");
4457 cmd_AddParm(ts, "-partition", CMD_SINGLE, 0, "partition name for new location");
4458 cmd_AddParm(ts, "-id", CMD_SINGLE, 0, "volume name or ID");
4461 ts = cmd_CreateSyntax("addsite", AddSite, 0, "add a replication site");
4462 cmd_AddParm(ts, "-server", CMD_SINGLE, 0, "machine name for new site");
4463 cmd_AddParm(ts, "-partition", CMD_SINGLE, 0, "partition name for new site");
4464 cmd_AddParm(ts, "-id", CMD_SINGLE, 0, "volume name or ID");
4467 ts = cmd_CreateSyntax("remsite", RemoveSite, 0, "remove a replication site");
4468 cmd_AddParm(ts, "-server", CMD_SINGLE, 0, "machine name");
4469 cmd_AddParm(ts, "-partition", CMD_SINGLE, 0, "partition name");
4470 cmd_AddParm(ts, "-id", CMD_SINGLE, 0, "volume name or ID");
4473 ts = cmd_CreateSyntax("listpart", ListPartitions, 0, "list partitions");
4474 cmd_AddParm(ts, "-server", CMD_SINGLE, 0, "machine name");
4477 ts = cmd_CreateSyntax("listvol", ListVolumes, 0, "list volumes on server (bypass VLDB)");
4478 cmd_AddParm(ts, "-server", CMD_SINGLE, 0, "machine name");
4479 cmd_AddParm(ts, "-partition", CMD_SINGLE,CMD_OPTIONAL, "partition name");
4480 cmd_AddParm(ts, "-fast", CMD_FLAG, CMD_OPTIONAL, "minimal listing");
4481 cmd_AddParm(ts, "-long", CMD_FLAG, CMD_OPTIONAL,
4482 "list all normal volume fields");
4483 cmd_AddParm(ts, "-quiet", CMD_FLAG, CMD_OPTIONAL, "generate minimal information");
4484 cmd_AddParm(ts, "-extended", CMD_FLAG, CMD_OPTIONAL,
4485 "list extended volume fields");
4486 #ifdef FULL_LISTVOL_SWITCH
4487 cmd_AddParm(ts, "-format", CMD_FLAG, CMD_OPTIONAL,
4488 "machine readable format");
4489 #endif /* FULL_LISTVOL_SWITCH */
4492 ts = cmd_CreateSyntax("syncvldb", SyncVldb, 0, "synchronize VLDB with server");
4493 cmd_AddParm(ts, "-server", CMD_SINGLE, CMD_OPTIONAL, "machine name");
4494 cmd_AddParm(ts, "-partition", CMD_SINGLE,CMD_OPTIONAL , "partition name");
4495 cmd_AddParm(ts, "-volume", CMD_SINGLE,CMD_OPTIONAL , "volume name or ID");
4498 ts = cmd_CreateSyntax("syncserv", SyncServer, 0, "synchronize server with VLDB");
4499 cmd_AddParm(ts, "-server", CMD_SINGLE, 0, "machine name");
4500 cmd_AddParm(ts, "-partition", CMD_SINGLE,CMD_OPTIONAL , "partition name");
4503 ts = cmd_CreateSyntax("examine", ExamineVolume, 0, "everything about the volume");
4504 cmd_AddParm(ts, "-id", CMD_SINGLE, 0, "volume name or ID");
4505 cmd_AddParm(ts, "-extended", CMD_FLAG, CMD_OPTIONAL,
4506 "list extended volume fields");
4507 #ifdef FULL_LISTVOL_SWITCH
4508 cmd_AddParm(ts, "-format", CMD_FLAG, CMD_OPTIONAL,
4509 "machine readable format");
4510 #endif /* FULL_LISTVOL_SWITCH */
4512 cmd_CreateAlias (ts, "volinfo");
4514 ts = cmd_CreateSyntax("setfields", SetFields, 0, "change volume info fields");
4515 cmd_AddParm(ts, "-id", CMD_SINGLE, 0, "volume name or ID");
4516 cmd_AddParm(ts, "-maxquota", CMD_SINGLE, CMD_OPTIONAL, "quota (KB)");
4517 cmd_AddParm(ts, "-clearuse", CMD_FLAG, CMD_OPTIONAL, "clear dayUse");
4520 ts = cmd_CreateSyntax("offline", volOffline, 0, (char *) CMD_HIDDEN);
4521 cmd_AddParm(ts, "-server", CMD_SINGLE, 0, "server name");
4522 cmd_AddParm(ts, "-partition", CMD_SINGLE, 0, "partition name");
4523 cmd_AddParm(ts, "-id", CMD_SINGLE, 0, "volume name or ID");
4524 cmd_AddParm(ts, "-sleep", CMD_SINGLE, CMD_OPTIONAL, "seconds to sleep");
4525 cmd_AddParm(ts, "-busy", CMD_FLAG, CMD_OPTIONAL, "busy volume");
4528 ts = cmd_CreateSyntax("online", volOnline, 0, (char *) CMD_HIDDEN);
4529 cmd_AddParm(ts, "-server", CMD_SINGLE, 0, "server name");
4530 cmd_AddParm(ts, "-partition", CMD_SINGLE, 0, "partition name");
4531 cmd_AddParm(ts, "-id", CMD_SINGLE, 0, "volume name or ID");
4534 ts = cmd_CreateSyntax("zap", VolumeZap, 0, "delete the volume, don't bother with VLDB");
4535 cmd_AddParm(ts, "-server", CMD_SINGLE, 0, "machine name");
4536 cmd_AddParm(ts, "-partition", CMD_SINGLE, 0, "partition name");
4537 cmd_AddParm(ts, "-id", CMD_SINGLE, 0, "volume ID");
4538 cmd_AddParm(ts, "-force", CMD_FLAG, CMD_OPTIONAL, "force deletion of bad volumes");
4539 cmd_AddParm(ts, "-backup", CMD_FLAG, CMD_OPTIONAL, "also delete backup volume if one is found");
4542 ts = cmd_CreateSyntax("status", VolserStatus, 0, "report on volser status");
4543 cmd_AddParm(ts, "-server", CMD_SINGLE, 0, "machine name");
4546 ts = cmd_CreateSyntax("rename", RenameVolume, 0, "rename a volume");
4547 cmd_AddParm(ts, "-oldname", CMD_SINGLE, 0, "old volume name ");
4548 cmd_AddParm(ts, "-newname", CMD_SINGLE, 0, "new volume name ");
4551 ts = cmd_CreateSyntax("listvldb", ListVLDB, 0, "list volumes in the VLDB");
4552 cmd_AddParm(ts, "-name", CMD_SINGLE,CMD_OPTIONAL, "volume name or ID");
4553 cmd_AddParm(ts, "-server", CMD_SINGLE,CMD_OPTIONAL, "machine name");
4554 cmd_AddParm(ts, "-partition", CMD_SINGLE,CMD_OPTIONAL, "partition name");
4555 cmd_AddParm(ts, "-locked", CMD_FLAG, CMD_OPTIONAL, "locked volumes only");
4556 cmd_AddParm(ts, "-quiet", CMD_FLAG, CMD_OPTIONAL, "generate minimal information");
4557 cmd_AddParm(ts, "-nosort", CMD_FLAG, CMD_OPTIONAL, "do not alphabetically sort the volume names");
4560 ts = cmd_CreateSyntax("backupsys", BackSys, 0, "en masse backups");
4561 cmd_AddParm(ts, "-prefix", CMD_LIST,CMD_OPTIONAL, "common prefix on volume(s)");
4562 cmd_AddParm(ts, "-server", CMD_SINGLE,CMD_OPTIONAL, "machine name");
4563 cmd_AddParm(ts, "-partition", CMD_SINGLE,CMD_OPTIONAL, "partition name");
4564 cmd_AddParm(ts, "-exclude", CMD_FLAG, CMD_OPTIONAL, "exclude common prefix volumes");
4565 cmd_AddParm(ts, "-xprefix", CMD_LIST, CMD_OPTIONAL, "negative prefix on volume(s)");
4566 cmd_AddParm(ts, "-dryrun", CMD_FLAG, CMD_OPTIONAL, "no action");
4569 ts = cmd_CreateSyntax("delentry", DeleteEntry, 0, "delete VLDB entry for a volume");
4570 cmd_AddParm(ts, "-id", CMD_LIST, CMD_OPTIONAL, "volume name or ID");
4571 cmd_AddParm(ts, "-prefix", CMD_SINGLE,CMD_OPTIONAL, "prefix of the volume whose VLDB entry is to be deleted");
4572 cmd_AddParm(ts, "-server", CMD_SINGLE,CMD_OPTIONAL, "machine name");
4573 cmd_AddParm(ts, "-partition", CMD_SINGLE,CMD_OPTIONAL, "partition name");
4574 cmd_AddParm(ts, "-noexecute", CMD_FLAG,CMD_OPTIONAL|CMD_HIDE, "no execute");
4577 ts = cmd_CreateSyntax("partinfo", PartitionInfo, 0, "list partition information");
4578 cmd_AddParm(ts, "-server", CMD_SINGLE, 0, "machine name");
4579 cmd_AddParm(ts, "-partition", CMD_SINGLE,CMD_OPTIONAL, "partition name");
4582 ts = cmd_CreateSyntax("unlockvldb", UnlockVLDB, 0, "unlock all the locked entries in the VLDB");
4583 cmd_AddParm(ts, "-server", CMD_SINGLE,CMD_OPTIONAL, "machine name");
4584 cmd_AddParm(ts, "-partition", CMD_SINGLE,CMD_OPTIONAL, "partition name");
4587 ts = cmd_CreateSyntax("lock", LockEntry, 0, "lock VLDB entry for a volume");
4588 cmd_AddParm(ts, "-id", CMD_SINGLE, 0, "volume name or ID");
4591 ts = cmd_CreateSyntax("changeaddr", ChangeAddr, 0, "change the IP address of a file server");
4592 cmd_AddParm(ts, "-oldaddr", CMD_SINGLE, 0, "original IP address");
4593 cmd_AddParm(ts, "-newaddr", CMD_SINGLE, CMD_OPTIONAL, "new IP address");
4594 cmd_AddParm(ts, "-remove", CMD_FLAG, CMD_OPTIONAL, "remove the IP address from the VLDB");
4597 ts = cmd_CreateSyntax("listaddrs", ListAddrs, 0, "list the IP address of all file servers registered in the VLDB");
4598 cmd_AddParm(ts, "-uuid", CMD_SINGLE, CMD_OPTIONAL, "uuid of server");
4599 cmd_AddParm(ts, "-host", CMD_SINGLE, CMD_OPTIONAL, "address of host");
4600 cmd_AddParm(ts, "-noresolve", CMD_FLAG, CMD_OPTIONAL, "don't resolve addresses");
4601 cmd_AddParm(ts, "-printuuid", CMD_FLAG, CMD_OPTIONAL, "print uuid of hosts");
4604 ts = cmd_CreateSyntax("convertROtoRW", ConvertRO, 0, "convert a RO volume into a RW volume (after loss of old RW volume)");
4605 cmd_AddParm(ts, "-server", CMD_SINGLE,0, "machine name");
4606 cmd_AddParm(ts, "-partition", CMD_SINGLE,0, "partition name");
4607 cmd_AddParm(ts, "-id", CMD_SINGLE, 0, "volume name or ID");
4608 cmd_AddParm(ts, "-force", CMD_FLAG, CMD_OPTIONAL, "don't ask");
4611 code = cmd_Dispatch(argc, argv);
4613 /* Shut down the ubik_client and rx connections */
4615 ubik_ClientDestroy (cstruct);