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 .B \-p
options. options.
.TP .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" .BI \-z " undo_file"
Before overwriting a file system block, write the old contents of the block to 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 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; ext2fs_inode_bitmap inodes_to_rebuild;
/* Patch file */
char *patch_file;
/* Undo file */ /* Undo file */
char *undo_file; char *undo_file;
}; };

View File

@ -76,7 +76,7 @@ static void usage(e2fsck_t ctx)
fprintf(stderr, fprintf(stderr,
_("Usage: %s [-panyrcdfktvDFV] [-b superblock] [-B blocksize]\n" _("Usage: %s [-panyrcdfktvDFV] [-b superblock] [-B blocksize]\n"
"\t\t[-l|-L bad_blocks_file] [-C fd] [-j external_journal]\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); ctx->program_name);
fprintf(stderr, "%s", _("\nEmergency help:\n" 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" " -j external_journal Set location of the external journal\n"
" -l bad_blocks_file Add to badblocks list\n" " -l bad_blocks_file Add to badblocks list\n"
" -L bad_blocks_file Set 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" " -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; phys_mem_kb = get_memory_size() / 1024;
ctx->readahead_kb = ~0ULL; 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) { switch (c) {
case 'C': case 'C':
ctx->progress = e2fsck_update_progress; ctx->progress = e2fsck_update_progress;
@ -936,6 +937,9 @@ static errcode_t PRS(int argc, char *argv[], e2fsck_t *ret_ctx)
case 'k': case 'k':
keep_bad_blocks++; keep_bad_blocks++;
break; break;
case 'T':
ctx->patch_file = optarg;
break;
case 'z': case 'z':
ctx->undo_file = optarg; ctx->undo_file = optarg;
break; break;
@ -1233,6 +1237,19 @@ check_error:
return retval; 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) static int e2fsck_setup_tdb(e2fsck_t ctx, io_manager *io_ptr)
{ {
errcode_t retval = ENOMEM; errcode_t retval = ENOMEM;
@ -1430,7 +1447,11 @@ restart:
flags &= ~EXT2_FLAG_EXCLUSIVE; 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); retval = e2fsck_setup_tdb(ctx, &io_ptr);
if (retval) if (retval)
exit(FSCK_ERROR); exit(FSCK_ERROR);

View File

@ -47,7 +47,7 @@ static char *device_name, *io_options;
static void usage (char *prog) static void usage (char *prog)
{ {
fprintf (stderr, _("Usage: %s [-d debug_flags] [-f] [-F] [-M] [-P] " 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); prog);
exit (1); 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, static int resize2fs_setup_tdb(const char *device, char *undo_file,
io_manager *io_ptr) io_manager *io_ptr)
{ {
@ -267,7 +281,7 @@ int main (int argc, char ** argv)
unsigned int blocksize; unsigned int blocksize;
long sysval; long sysval;
int len, mount_flags; int len, mount_flags;
char *mtpt, *undo_file = NULL; char *mtpt, *undo_file = NULL, *patch_file = NULL;
#ifdef ENABLE_NLS #ifdef ENABLE_NLS
setlocale(LC_MESSAGES, ""); setlocale(LC_MESSAGES, "");
@ -284,7 +298,7 @@ int main (int argc, char ** argv)
if (argc && *argv) if (argc && *argv)
program_name = *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) { switch (c) {
case 'h': case 'h':
usage(program_name); usage(program_name);
@ -316,6 +330,9 @@ int main (int argc, char ** argv)
case 's': case 's':
flags |= RESIZE_DISABLE_64BIT; flags |= RESIZE_DISABLE_64BIT;
break; break;
case 'T':
patch_file = optarg;
break;
case 'z': case 'z':
undo_file = optarg; undo_file = optarg;
break; break;
@ -402,7 +419,11 @@ int main (int argc, char ** argv)
io_flags = EXT2_FLAG_RW | EXT2_FLAG_EXCLUSIVE; io_flags = EXT2_FLAG_RW | EXT2_FLAG_EXCLUSIVE;
io_flags |= EXT2_FLAG_64BITS; 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); retval = resize2fs_setup_tdb(device_name, undo_file, &io_ptr);
if (retval) if (retval)
exit(1); 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 when the filesystem was created. This option allows the user to
explicitly specify a RAID stride setting to be used by resize2fs instead. explicitly specify a RAID stride setting to be used by resize2fs instead.
.TP .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" .BI \-z " undo_file"
Before overwriting a file system block, write the old contents of the block to 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 an undo file. This undo file can be used with e2undo(8) to restore the old