Add patch_io manager support to resize2fs and e2fsck

master
Vitaliy Filippov 2016-09-16 11:34:20 +03:00
parent b3782b2e5b
commit 7e0136332c
5 changed files with 64 additions and 7 deletions

View File

@ -345,6 +345,12 @@ or
.B \-p
options.
.TP
.BI \-T " patch_file"
Do not apply changes to the real filesystem; write updates into a sparse file
named 'patch_file' to safely apply them later with e2patch(8) utility.
You'll also be able to create a backup before applying patch and safely
restore it in case of power outage or system crash.
.TP
.BI \-z " undo_file"
Before overwriting a file system block, write the old contents of the block to
an undo file. This undo file can be used with e2undo(8) to restore the old

View File

@ -391,6 +391,9 @@ struct e2fsck_struct {
*/
ext2fs_inode_bitmap inodes_to_rebuild;
/* Patch file */
char *patch_file;
/* Undo file */
char *undo_file;
};

View File

@ -76,7 +76,7 @@ static void usage(e2fsck_t ctx)
fprintf(stderr,
_("Usage: %s [-panyrcdfktvDFV] [-b superblock] [-B blocksize]\n"
"\t\t[-l|-L bad_blocks_file] [-C fd] [-j external_journal]\n"
"\t\t[-E extended-options] [-z undo_file] device\n"),
"\t\t[-E extended-options] [-T patch_file] [-z undo_file] device\n"),
ctx->program_name);
fprintf(stderr, "%s", _("\nEmergency help:\n"
@ -92,6 +92,7 @@ static void usage(e2fsck_t ctx)
" -j external_journal Set location of the external journal\n"
" -l bad_blocks_file Add to badblocks list\n"
" -L bad_blocks_file Set badblocks list\n"
" -T patch_file Create a patch file instead of applying changes to real FS\n"
" -z undo_file Create an undo file\n"
));
@ -804,7 +805,7 @@ static errcode_t PRS(int argc, char *argv[], e2fsck_t *ret_ctx)
phys_mem_kb = get_memory_size() / 1024;
ctx->readahead_kb = ~0ULL;
while ((c = getopt(argc, argv, "panyrcC:B:dE:fvtFVM:b:I:j:P:l:L:N:SsDkz:")) != EOF)
while ((c = getopt(argc, argv, "panyrcC:B:dE:fvtFVM:b:I:j:P:l:L:N:SsDkT:z:")) != EOF)
switch (c) {
case 'C':
ctx->progress = e2fsck_update_progress;
@ -936,6 +937,9 @@ static errcode_t PRS(int argc, char *argv[], e2fsck_t *ret_ctx)
case 'k':
keep_bad_blocks++;
break;
case 'T':
ctx->patch_file = optarg;
break;
case 'z':
ctx->undo_file = optarg;
break;
@ -1233,6 +1237,19 @@ check_error:
return retval;
}
static int e2fsck_setup_patch(e2fsck_t ctx, io_manager *io_ptr)
{
set_patch_io_backing_manager(*io_ptr);
set_patch_io_patch_file(ctx->patch_file);
*io_ptr = patch_io_manager;
printf(_("To make backup before applying changes run:\n"
" e2patch backup %s %s %s.backup\n"
"Then, to apply the operation to the real filesystem run:\n"
" e2patch apply %s %s\n"),
ctx->device_name, ctx->patch_file, ctx->patch_file, ctx->device_name, ctx->patch_file);
return 0;
}
static int e2fsck_setup_tdb(e2fsck_t ctx, io_manager *io_ptr)
{
errcode_t retval = ENOMEM;
@ -1430,7 +1447,11 @@ restart:
flags &= ~EXT2_FLAG_EXCLUSIVE;
}
if (ctx->undo_file) {
if (ctx->patch_file) {
retval = e2fsck_setup_patch(ctx, &io_ptr);
if (retval)
exit(FSCK_ERROR);
} else if (ctx->undo_file) {
retval = e2fsck_setup_tdb(ctx, &io_ptr);
if (retval)
exit(FSCK_ERROR);

View File

@ -47,7 +47,7 @@ static char *device_name, *io_options;
static void usage (char *prog)
{
fprintf (stderr, _("Usage: %s [-d debug_flags] [-f] [-F] [-M] [-P] "
"[-p] device [-b|-s|new_size] [-z undo_file]\n\n"),
"[-p] device [-b|-s|new_size] [-T patch_file] [-z undo_file]\n\n"),
prog);
exit (1);
@ -167,6 +167,20 @@ static void bigalloc_check(ext2_filsys fs, int force)
}
}
static int resize2fs_setup_patch(const char *device, char *patch_file,
io_manager *io_ptr)
{
set_patch_io_backing_manager(*io_ptr);
set_patch_io_patch_file(patch_file);
*io_ptr = patch_io_manager;
printf(_("To make backup before applying changes run:\n"
" e2patch backup %s %s %s.backup\n"
"Then, to apply the operation to the real filesystem run:\n"
" e2patch apply %s %s\n"),
device, patch_file, patch_file, device, patch_file);
return 0;
}
static int resize2fs_setup_tdb(const char *device, char *undo_file,
io_manager *io_ptr)
{
@ -267,7 +281,7 @@ int main (int argc, char ** argv)
unsigned int blocksize;
long sysval;
int len, mount_flags;
char *mtpt, *undo_file = NULL;
char *mtpt, *undo_file = NULL, *patch_file = NULL;
#ifdef ENABLE_NLS
setlocale(LC_MESSAGES, "");
@ -284,7 +298,7 @@ int main (int argc, char ** argv)
if (argc && *argv)
program_name = *argv;
while ((c = getopt(argc, argv, "d:fFhMPpS:bsz:")) != EOF) {
while ((c = getopt(argc, argv, "d:fFhMPpS:bsT:z:")) != EOF) {
switch (c) {
case 'h':
usage(program_name);
@ -316,6 +330,9 @@ int main (int argc, char ** argv)
case 's':
flags |= RESIZE_DISABLE_64BIT;
break;
case 'T':
patch_file = optarg;
break;
case 'z':
undo_file = optarg;
break;
@ -402,7 +419,11 @@ int main (int argc, char ** argv)
io_flags = EXT2_FLAG_RW | EXT2_FLAG_EXCLUSIVE;
io_flags |= EXT2_FLAG_64BITS;
if (undo_file) {
if (patch_file) {
retval = resize2fs_setup_patch(device_name, patch_file, &io_ptr);
if (retval)
exit(1);
} else if (undo_file) {
retval = resize2fs_setup_tdb(device_name, undo_file, &io_ptr);
if (retval)
exit(1);

View File

@ -159,6 +159,12 @@ program will heuristically determine the RAID stride that was specified
when the filesystem was created. This option allows the user to
explicitly specify a RAID stride setting to be used by resize2fs instead.
.TP
.BI \-T " patch_file"
Do not apply changes to the real filesystem; write updates into a sparse file
named 'patch_file' to safely apply them later with e2patch(8) utility.
You'll also be able to create a backup before applying patch and safely
restore it in case of power outage or system crash.
.TP
.BI \-z " undo_file"
Before overwriting a file system block, write the old contents of the block to
an undo file. This undo file can be used with e2undo(8) to restore the old