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