diff --git a/e2fsck/e2fsck.8.in b/e2fsck/e2fsck.8.in index 915273d8..4274de2a 100644 --- a/e2fsck/e2fsck.8.in +++ b/e2fsck/e2fsck.8.in @@ -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 diff --git a/e2fsck/e2fsck.h b/e2fsck/e2fsck.h index f3568106..6d658059 100644 --- a/e2fsck/e2fsck.h +++ b/e2fsck/e2fsck.h @@ -391,6 +391,9 @@ struct e2fsck_struct { */ ext2fs_inode_bitmap inodes_to_rebuild; + /* Patch file */ + char *patch_file; + /* Undo file */ char *undo_file; }; diff --git a/e2fsck/unix.c b/e2fsck/unix.c index e00fa166..fe79469b 100644 --- a/e2fsck/unix.c +++ b/e2fsck/unix.c @@ -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); diff --git a/resize/main.c b/resize/main.c index 5a99483c..44e1c42f 100644 --- a/resize/main.c +++ b/resize/main.c @@ -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); diff --git a/resize/resize2fs.8.in b/resize/resize2fs.8.in index 76434d74..29dd17cd 100644 --- a/resize/resize2fs.8.in +++ b/resize/resize2fs.8.in @@ -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