[OpenAFS-devel] Vos dump improvements

Nathan Neulinger nneul@umr.edu
Wed, 23 Oct 2002 12:13:21 -0500


--Q68bSM7Ycu6FN28Q
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline

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:  nneul@umr.edu
University of Missouri - Rolla         Phone: (573) 341-4841
Computing Services                       Fax: (573) 341-4216

--Q68bSM7Ycu6FN28Q
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment; filename="clean.diff"

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);
+}
+
 
 
 /*

--Q68bSM7Ycu6FN28Q--