mirror of
https://git.openafs.org/openafs.git
synced 2025-01-18 15:00:12 +00:00
vos: Check end-of-dump magic before deleting volume
When restoring a volume with a regular file, vos restore verifies the dump file is terminated with the end-of-dump magic number before sending the dump to the volume server. Unfortunately, this check is done after the target volume is deleted (which happens when doing a full restore of a volume), in which case the target volume is unnecessarily removed. Currently, UV_RestoreVolume2() invokes the WriteData() function as callback to transmit the dump stream to the volume server. WriteData() opens the usd file handle, performs the end-of-dump magic check (if the file is seekable), sends the data using the SendFile() helper function, then closes the dump file handle. Instead, open and check the dump file magic before calling UV_RestoreVolume2(). Pass the usd file handle and a pointer to the SendFile() function to UV_RestoreVolume2() to send the dump data to the volume server. Move the code to perform the dump file magic check to the new CheckDumpFile() helper function and remove the now unneeded WriteData() function. Change-Id: Ia04f378540b40c2e6360aa120592fbd793c33cae Reviewed-on: https://gerrit.openafs.org/14710 Reviewed-by: Cheyenne Wills <cwills@sinenomine.net> Tested-by: BuildBot <buildbot@rampaginggeek.com> Reviewed-by: Andrew Deason <adeason@sinenomine.net>
This commit is contained in:
parent
a193d76070
commit
22e8fa88d1
@ -285,16 +285,17 @@ IsPartValid(afs_int32 partId, afs_uint32 server, afs_int32 *code)
|
||||
/**
|
||||
* Send the contents of a dump file to the volume server.
|
||||
*
|
||||
* @param[in] ufd usd file handle opened for read
|
||||
* @param[in] call rx call object
|
||||
* @param[in] rock usd file handle opened for read
|
||||
*
|
||||
* @returns status
|
||||
* @retval 0 success
|
||||
* @retval -1 error
|
||||
*/
|
||||
static int
|
||||
SendFile(usd_handle_t ufd, struct rx_call *call)
|
||||
SendFile(struct rx_call *call, void *rock)
|
||||
{
|
||||
usd_handle_t ufd = rock;
|
||||
char *buffer = NULL;
|
||||
afs_int32 error;
|
||||
afs_uint32 nbytes;
|
||||
@ -343,13 +344,15 @@ SendFile(usd_handle_t ufd, struct rx_call *call)
|
||||
return error;
|
||||
}
|
||||
|
||||
/* function invoked by UV_RestoreVolume, reads the data from rx_trx_stream and
|
||||
* writes it out to the volume. */
|
||||
static afs_int32
|
||||
WriteData(struct rx_call *call, void *rock)
|
||||
/**
|
||||
* Test if we have a valid dump file.
|
||||
*
|
||||
* @param[in] ufd dump file handle
|
||||
* @retval 0 file appears to contain a volume dump
|
||||
*/
|
||||
static int
|
||||
CheckDumpFile(usd_handle_t ufd)
|
||||
{
|
||||
usd_handle_t ufd = (usd_handle_t)rock;
|
||||
afs_int32 error = 0;
|
||||
afs_int32 code;
|
||||
int is_seekable = 0;
|
||||
|
||||
@ -358,8 +361,7 @@ WriteData(struct rx_call *call, void *rock)
|
||||
if (code != 0) {
|
||||
fprintf(STDERR, "Failed to determine if '%s' is seekable; code=%d\n",
|
||||
ufd->fullPathName, code);
|
||||
error = code;
|
||||
goto wfail;
|
||||
return code;
|
||||
}
|
||||
if (is_seekable) {
|
||||
afs_int64 offset = 0;
|
||||
@ -370,44 +372,33 @@ WriteData(struct rx_call *call, void *rock)
|
||||
if (code != 0) {
|
||||
fprintf(STDERR, "Failed seek to end of '%s'; code=%d\n",
|
||||
ufd->fullPathName, code);
|
||||
error = code;
|
||||
goto wfail;
|
||||
return code;
|
||||
}
|
||||
if (offset < sizeof(magic)) {
|
||||
fprintf(STDERR, "End of dump signature not found in '%s'.\n",
|
||||
ufd->fullPathName);
|
||||
error = VOLSERBADOP;
|
||||
goto wfail;
|
||||
return VOLSERBADOP;
|
||||
}
|
||||
code = USD_SEEK(ufd, offset - sizeof(magic), SEEK_SET, &offset);
|
||||
if (code != 0) {
|
||||
fprintf(STDERR, "Failed seek to dump end signature in '%s'; code=%d\n",
|
||||
ufd->fullPathName, code);
|
||||
error = code;
|
||||
goto wfail;
|
||||
return code;
|
||||
}
|
||||
code = USD_READ(ufd, (char *)&magic, sizeof(magic), &got);
|
||||
if (code != 0 || got != sizeof(magic) || ntohl(magic) != DUMPENDMAGIC) {
|
||||
fprintf(STDERR, "End of dump signature not found in '%s'.\n",
|
||||
ufd->fullPathName);
|
||||
error = VOLSERBADOP;
|
||||
goto wfail;
|
||||
return VOLSERBADOP;
|
||||
}
|
||||
code = USD_SEEK(ufd, 0, SEEK_SET, &offset);
|
||||
if (code != 0) {
|
||||
fprintf(STDERR, "Failed seek to start of '%s'; code=%d\n",
|
||||
ufd->fullPathName, code);
|
||||
error = code;
|
||||
goto wfail;
|
||||
return code;
|
||||
}
|
||||
}
|
||||
code = SendFile(ufd, call);
|
||||
if (code) {
|
||||
error = code;
|
||||
goto wfail;
|
||||
}
|
||||
wfail:
|
||||
return error;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -3142,6 +3133,12 @@ RestoreVolumeCmd(struct cmd_syndesc *as, void *arock)
|
||||
}
|
||||
}
|
||||
|
||||
code = CheckDumpFile(ufd);
|
||||
if (code != 0) {
|
||||
fprintf(STDERR, "Dump file check failed; code=%d\n", code);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/* Check if volume exists or not */
|
||||
|
||||
vsu_ExtractName(volname, avolname);
|
||||
@ -3289,7 +3286,7 @@ RestoreVolumeCmd(struct cmd_syndesc *as, void *arock)
|
||||
|
||||
code =
|
||||
UV_RestoreVolume2(aserver, apart, avolid, aparentid,
|
||||
avolname, restoreflags, WriteData, ufd);
|
||||
avolname, restoreflags, SendFile, ufd);
|
||||
USD_CLOSE(ufd);
|
||||
if (code) {
|
||||
PrintDiagnostics("restore", code);
|
||||
|
Loading…
Reference in New Issue
Block a user