Adds some additional diag with -verbose to vos dump, and adds the -clone option to 
the vos dump syntax.

Without -clone, vos dump behaves as before. 

With -clone, vos dump clones the volume and dumps from the clone to dramatically 
shorten
the amount of time the volume is kept busy and blocking writes. (Not an issue with 
dumps of .backup or .readonly volumes, but if you're trying to get a up to date 
dump of a RW, it helps a lot.)

End result - w/o -clone, volume is busy during the whole time the dump is taking place
w/ -clone, volume is busy just during the cloning process

Implementation issue - currently, the clone volume is named 'dump-clone-temp', similar 
to the 'move-clone-temp' that MoveVolume does. It would be a small addition to 
actually name 
the volume identical to the volume you are dumping, but I wasn't sure if that would 
cause
problems during a salvage or anything like that. (Having a duplicated volname on same 
server.)

-- Nathan

------------------------------------------------------------
Nathan Neulinger                       EMail:  [EMAIL PROTECTED]
University of Missouri - Rolla         Phone: (573) 341-4841
Computing Services                       Fax: (573) 341-4216
Index: src/volser/vos.c
===================================================================
RCS file: /cvs/openafs/src/volser/vos.c,v
retrieving revision 1.18
diff -u -r1.18 vos.c
--- src/volser/vos.c    2002/08/21 18:14:34     1.18
+++ src/volser/vos.c    2002/10/23 17:05:59
@@ -1976,7 +1976,12 @@
        else{
            strcpy(filename,"");
        }
-       code = UV_DumpVolume(avolid, aserver, apart, fromdate, DumpFunction, filename);
+
+    if (as->parms[5].items) {
+               code = UV_DumpClonedVolume(avolid, aserver, apart, fromdate, 
+DumpFunction, filename);
+       } else {
+               code = UV_DumpVolume(avolid, aserver, apart, fromdate, DumpFunction, 
+filename);
+       }               
        if (code) {
            PrintDiagnostics("dump", code);
            return code;
@@ -4149,6 +4154,7 @@
     cmd_AddParm(ts, "-file", CMD_SINGLE, CMD_OPTIONAL, "dump file");
     cmd_AddParm(ts, "-server", CMD_SINGLE, CMD_OPTIONAL, "server");
     cmd_AddParm(ts, "-partition", CMD_SINGLE, CMD_OPTIONAL, "partition");
+    cmd_AddParm(ts, "-clone", CMD_FLAG, CMD_OPTIONAL, "dump a clone of the volume");
     COMMONPARMS;
 
     ts = cmd_CreateSyntax("restore", RestoreVolume, 0, "restore a volume");
Index: src/volser/vsprocs.c
===================================================================
RCS file: /cvs/openafs/src/volser/vsprocs.c,v
retrieving revision 1.16
diff -u -r1.16 vsprocs.c
--- src/volser/vsprocs.c        2002/10/16 03:59:30     1.16
+++ src/volser/vsprocs.c        2002/10/23 17:06:00
@@ -2599,28 +2599,35 @@
 #endif
    (void) signal(SIGINT,  dump_sig_handler);
 
+   if (!fromdate)
+   {
+      VPRINT("Full Dump ...\n");
+   }
+   else 
+   {
+      VPRINT1("Incremental Dump (as of %.24s)...\n", ctime((time_t *)&fromdate));
+   }
+
    /* get connections to the servers */
    fromconn = UV_Bind(afromserver, AFSCONF_VOLUMEPORT);
+
+   VPRINT1("Starting transaction on volume %u...", afromvol);
    code = AFSVolTransCreate(fromconn, afromvol, afrompart, ITBusy, &fromtid);
    EGOTO1(error_exit, code, "Could not start transaction on the volume %u to be 
dumped\n", afromvol);
+   VDONE;
 
-  if (!fromdate)
-{      VPRINT("Full Dump ..."); }
-  else 
-{
-       VPRINT1("Incremental Dump (as of %.24s) ...",
-               ctime((time_t *)&fromdate));
-}
-
    fromcall = rx_NewCall(fromconn);
+
+   VPRINT1("Starting volume dump on volume %u...", afromvol);
    code = StartAFSVolDump(fromcall, fromtid, fromdate);
    EGOTO(error_exit, code, "Could not start the dump process \n");
+   VDONE;
 
+   VPRINT1("Dumping volume %u...", afromvol);
    code = DumpFunction(fromcall, rock);
    EGOTO(error_exit, code, "Error while dumping volume \n");
+   VDONE;
 
-   VPRINT("completed\n");
-
  error_exit: 
    if (fromcall) {
       code = rx_EndCall(fromcall, rxError);
@@ -2630,11 +2637,13 @@
       }        
    }
    if (fromtid) {
+      VPRINT1("Ending transaction on volume %u...", afromvol);
       code = AFSVolEndTrans(fromconn, fromtid, &rcode);
       if (code || rcode) {
         fprintf(STDERR,"Could not end transaction on the volume %u\n", afromvol);
         if (!error) error = (code?code:rcode);
       }
+      VDONE;
    }
    if (fromconn)
       rx_DestroyConnection(fromconn);
@@ -2642,6 +2651,128 @@
    PrintError("", error);
    return(error);
 }
+
+/* Clone the volume <afromvol> on <afromserver> and
+ * <afrompart>, and then dump the clone volume to 
+ * <afilename> starting from <fromdate>.
+ * DumpFunction does the real work behind the scenes after
+ * extracting parameters from the rock 
+ */
+int UV_DumpClonedVolume(afs_int32 afromvol, afs_int32 afromserver, afs_int32 
+afrompart, 
+       afs_int32 fromdate, afs_int32 (*DumpFunction)(), char *rock)
+{
+       struct rx_connection *fromconn = (struct rx_connection *)0;
+       struct rx_call       *fromcall = (struct rx_call *)0;
+       afs_int32 fromtid=0, rxError=0, rcode=0;
+       afs_int32 clonetid=0;
+       afs_int32 code=0, vcode=0, error = 0;
+       afs_int32 clonevol=0;
+    char vname[64];
+
+       if (setjmp(env)) ERROR_EXIT(EPIPE);
+#ifndef AFS_NT40_ENV
+       (void) signal(SIGPIPE, dump_sig_handler);
+#endif
+       (void) signal(SIGINT,  dump_sig_handler);
+
+       if (!fromdate)
+       {
+         VPRINT("Full Dump ...\n");
+       }
+       else 
+       {
+         VPRINT1("Incremental Dump (as of %.24s)...\n", ctime((time_t *)&fromdate));
+       }
+
+       /* get connections to the servers */
+       fromconn = UV_Bind(afromserver, AFSCONF_VOLUMEPORT);
+
+       VPRINT1("Starting transaction on volume %u...", afromvol);
+       code = AFSVolTransCreate(fromconn, afromvol, afrompart, ITBusy, &fromtid);
+       EGOTO1(error_exit, code, "Could not start transaction on the volume %u to be 
+dumped\n", afromvol);
+       VDONE;
+
+    /* Get a clone id */
+    VPRINT1("Allocating new volume id for clone of volume %u ...", afromvol);
+    code = ubik_Call (VL_GetNewVolumeId, cstruct, 0, 1, &clonevol);
+    EGOTO1(error_exit, code, "Could not get an ID for the clone of volume %u from the 
+VLDB\n", afromvol);
+    VDONE;
+
+    /* Do the clone. Default flags on clone are set to delete on salvage and out of 
+service */
+    VPRINT2("Cloning source volume %u to clone volume %u...", afromvol, clonevol);
+    strcpy(vname, "dump-clone-temp");
+    code = AFSVolClone(fromconn, fromtid, 0, readonlyVolume, vname, &clonevol);
+    EGOTO1(error_exit, code, "Failed to clone the source volume %u\n", afromvol);
+    VDONE;
+
+    VPRINT1("Ending the transaction on the volume %u ...", afromvol);
+    rcode = 0;
+    code = AFSVolEndTrans(fromconn, fromtid, &rcode);
+    fromtid = 0;
+    if (!code) code = rcode;
+    EGOTO1(error_exit, code, "Failed to end the transaction on the volume %u\n", 
+afromvol);
+    VDONE;
+
+
+    VPRINT1("Starting transaction on the cloned volume %u ...", clonevol);
+    code = AFSVolTransCreate (fromconn, clonevol, afrompart, ITOffline, &clonetid);
+    EGOTO1(error_exit, code, "Failed to start a transaction on the cloned 
+volume%u\n", clonevol);
+    VDONE;
+
+    VPRINT1("Setting flags on cloned volume %u ...", clonevol);
+    code = AFSVolSetFlags (fromconn, clonetid, VTDeleteOnSalvage|VTOutOfService); 
+/*redundant */
+    EGOTO1(error_exit, code, "Could not set falgs on the cloned volume %u\n", 
+clonevol);
+    VDONE;
+
+
+       fromcall = rx_NewCall(fromconn);
+
+       VPRINT1("Starting volume dump from cloned volume %u...", clonevol);
+       code = StartAFSVolDump(fromcall, clonetid, fromdate);
+       EGOTO(error_exit, code, "Could not start the dump process \n");
+       VDONE;
+
+       VPRINT1("Dumping volume %u...", afromvol);
+       code = DumpFunction(fromcall, rock);
+       EGOTO(error_exit, code, "Error while dumping volume \n");
+       VDONE;
+
+ error_exit: 
+    /* now delete the clone */
+    VPRINT1("Deleting the cloned volume %u ...", clonevol);
+    code = AFSVolDeleteVolume(fromconn, clonetid);
+       if ( code )
+       {       
+           fprintf(STDERR,"Failed to delete the cloned volume %u\n", clonevol);
+       }
+       else
+       {
+           VDONE;
+       }
+
+       if (fromcall) {
+               code = rx_EndCall(fromcall, rxError);
+               if (code) {
+                       fprintf(STDERR,"Error in rx_EndCall\n");
+                       if (!error) error = code;
+               }       
+       }
+       if (fromtid) {
+               VPRINT1("Ending transaction on cloned volume %u...", clonevol);
+               code = AFSVolEndTrans(fromconn, clonetid, &rcode);
+               if (code || rcode) {
+                       fprintf(STDERR,"Could not end transaction on the cloned volume 
+%u\n", clonevol);
+                       if (!error) error = (code?code:rcode);
+               }
+               VDONE;
+       }
+       if (fromconn)
+               rx_DestroyConnection(fromconn);
+
+       PrintError("", error);
+       return(error);
+}
+
 
 
 /*

Reply via email to