add an rpc, give vos a switch, allow incrementals which do not include directory objects
#define VOLFORWARDMULTIPLE 128
#define VOLCONVERTRO 65536
#define VOLGETSIZE 65537
+#define VOLDUMPV2 65538
+
+/* Bits for flags for DumpV2 */
+%#define VOLDUMPV2_OMITDIRS 1
const SIZE = 1024;
IN afs_int32 fromDate,
OUT struct volintSize *size
) = VOLGETSIZE;
+
+proc DumpV2(
+ IN afs_int32 fromTrans,
+ IN afs_int32 fromDate,
+ IN afs_int32 flags
+) split = VOLDUMPV2;
+
{
afs_int32 code;
- code = VolDump(acid, fromTrans, fromDate);
+ code = VolDump(acid, fromTrans, fromDate, 0);
osi_auditU(acid, VS_DumpEvent, code, AUD_LONG, fromTrans, AUD_END);
return code;
}
afs_int32
-VolDump(struct rx_call *acid, afs_int32 fromTrans, afs_int32 fromDate)
+SAFSVolDumpV2(struct rx_call *acid, afs_int32 fromTrans, afs_int32 fromDate, afs_int32 flags)
+{
+ afs_int32 code;
+
+ code = VolDump(acid, fromTrans, fromDate, flags);
+ osi_auditU(acid, VS_DumpEvent, code, AUD_LONG, fromTrans, AUD_END);
+ return code;
+}
+
+afs_int32
+VolDump(struct rx_call *acid, afs_int32 fromTrans, afs_int32 fromDate, afs_int32 flags)
{
int code = 0;
register struct volser_trans *tt;
}
strcpy(tt->lastProcName, "Dump");
tt->rxCallPtr = acid;
- code = DumpVolume(acid, tt->volume, fromDate, 1); /* squirt out the volume's data, too */
+ code = DumpVolume(acid, tt->volume, fromDate, (flags & VOLDUMPV2_OMITDIRS)
+ ? 0 : 1); /* squirt out the volume's data, too */
if (code) {
tt->rxCallPtr = (struct rx_call *)0;
TRELE(tt);
extern void dump_sig_handler(int x);
extern int UV_DumpVolume(afs_int32 afromvol, afs_int32 afromserver,
afs_int32 afrompart, afs_int32 fromdate,
- afs_int32(*DumpFunction) (), char *rock);
+ afs_int32(*DumpFunction) (), char *rock, afs_int32 flags);
extern int UV_RestoreVolume(afs_int32 toserver, afs_int32 topart,
afs_int32 tovolid, char tovolname[], int flags,
afs_int32(*WriteData) (), char *rock);
register struct cmd_syndesc *as;
{
- afs_int32 avolid, aserver, apart, voltype, fromdate = 0, code, err, i;
+ afs_int32 avolid, aserver, apart, voltype, fromdate = 0, code, err, i, flags;
char filename[MAXPATHLEN];
struct nvldbentry entry;
strcpy(filename, "");
}
+ flags = as->parms[6].items ? VOLDUMPV2_OMITDIRS : 0;
+retry_dump:
if (as->parms[5].items) {
code =
UV_DumpClonedVolume(avolid, aserver, apart, fromdate,
- DumpFunction, filename);
+ DumpFunction, filename, flags);
} else {
code =
UV_DumpVolume(avolid, aserver, apart, fromdate, DumpFunction,
- filename);
+ filename, flags);
+ }
+ if ((code == RXGEN_OPCODE) && (as->parms[6].items)) {
+ flags &= ~VOLDUMPV2_OMITDIRS;
+ goto retry_dump;
}
if (code) {
PrintDiagnostics("dump", code);
cmd_AddParm(ts, "-partition", CMD_SINGLE, CMD_OPTIONAL, "partition");
cmd_AddParm(ts, "-clone", CMD_FLAG, CMD_OPTIONAL,
"dump a clone of the volume");
+ cmd_AddParm(ts, "-omitdirs", CMD_FLAG, CMD_OPTIONAL,
+ "omit unchanged directories from an incremental dump");
COMMONPARMS;
ts = cmd_CreateSyntax("restore", RestoreVolume, 0, "restore a volume");
*/
int
UV_DumpVolume(afs_int32 afromvol, afs_int32 afromserver, afs_int32 afrompart,
- afs_int32 fromdate, afs_int32(*DumpFunction) (), char *rock)
+ afs_int32 fromdate, afs_int32(*DumpFunction) (), char *rock,
+ afs_int32 flags)
{
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 code, error = 0;
+ afs_int32 code, error = 0, retry = 0;
time_t tmv = fromdate;
if (setjmp(env))
fromcall = rx_NewCall(fromconn);
VPRINT1("Starting volume dump on volume %u...", afromvol);
- code = StartAFSVolDump(fromcall, fromtid, fromdate);
+ if (flags & VOLDUMPV2_OMITDIRS)
+ code = StartAFSVolDumpV2(fromcall, fromtid, fromdate, flags);
+ else
+ retryold:
+ 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);
+ if (code == RXGEN_OPCODE)
+ goto error_exit;
EGOTO(error_exit, code, "Error while dumping volume \n");
VDONE;
error_exit:
if (fromcall) {
code = rx_EndCall(fromcall, rxError);
- if (code) {
+ if (code && code != RXGEN_OPCODE)
fprintf(STDERR, "Error in rx_EndCall\n");
- if (!error)
- error = code;
- }
+ if (code && !error)
+ error = code;
}
if (fromtid) {
VPRINT1("Ending transaction on volume %u...", afromvol);
if (fromconn)
rx_DestroyConnection(fromconn);
- PrintError("", error);
+ if (retry)
+ goto retryold;
+ if (error != RXGEN_OPCODE)
+ PrintError("", error);
return (error);
}
int
UV_DumpClonedVolume(afs_int32 afromvol, afs_int32 afromserver,
afs_int32 afrompart, afs_int32 fromdate,
- afs_int32(*DumpFunction) (), char *rock)
+ afs_int32(*DumpFunction) (), char *rock, afs_int32 flags)
{
struct rx_connection *fromconn = (struct rx_connection *)0;
struct rx_call *fromcall = (struct rx_call *)0;
fromcall = rx_NewCall(fromconn);
VPRINT1("Starting volume dump from cloned volume %u...", clonevol);
- code = StartAFSVolDump(fromcall, clonetid, fromdate);
+ if (flags & VOLDUMPV2_OMITDIRS)
+ code = StartAFSVolDumpV2(fromcall, clonetid, fromdate, flags);
+ else
+ code = StartAFSVolDump(fromcall, clonetid, fromdate);
EGOTO(error_exit, code, "Could not start the dump process \n");
VDONE;