mirror of https://github.com/vitalif/e2fsprogs
resize2fs: optionally create undo file
Provide the user with an option to create an undo file so that they can roll back a failed resize operation. Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com> Signed-off-by: Theodore Ts'o <tytso@mit.edu>debian
parent
ce9b74ab4f
commit
03f9fd2ad9
|
@ -29,6 +29,7 @@ extern int optind;
|
|||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
#include <libgen.h>
|
||||
|
||||
#include "e2p/e2p.h"
|
||||
|
||||
|
@ -42,7 +43,8 @@ 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]\n\n"), prog);
|
||||
"[-p] device [-b|-s|new_size] [-z undo_file]\n\n"),
|
||||
prog);
|
||||
|
||||
exit (1);
|
||||
}
|
||||
|
@ -162,6 +164,82 @@ static void bigalloc_check(ext2_filsys fs, int force)
|
|||
}
|
||||
}
|
||||
|
||||
static int resize2fs_setup_tdb(const char *device_name, char *undo_file,
|
||||
io_manager *io_ptr)
|
||||
{
|
||||
errcode_t retval = ENOMEM;
|
||||
char *tdb_dir = NULL, *tdb_file = NULL;
|
||||
char *dev_name, *tmp_name;
|
||||
int free_tdb_dir = 0;
|
||||
|
||||
/* (re)open a specific undo file */
|
||||
if (undo_file && undo_file[0] != 0) {
|
||||
set_undo_io_backing_manager(*io_ptr);
|
||||
*io_ptr = undo_io_manager;
|
||||
retval = set_undo_io_backup_file(undo_file);
|
||||
if (retval)
|
||||
goto err;
|
||||
printf(_("Overwriting existing filesystem; this can be undone "
|
||||
"using the command:\n"
|
||||
" e2undo %s %s\n\n"),
|
||||
undo_file, device_name);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Configuration via a conf file would be
|
||||
* nice
|
||||
*/
|
||||
tdb_dir = getenv("E2FSPROGS_UNDO_DIR");
|
||||
|
||||
if (tdb_dir == NULL || !strcmp(tdb_dir, "none") || (tdb_dir[0] == 0) ||
|
||||
access(tdb_dir, W_OK)) {
|
||||
if (free_tdb_dir)
|
||||
free(tdb_dir);
|
||||
return 0;
|
||||
}
|
||||
|
||||
tmp_name = strdup(device_name);
|
||||
if (!tmp_name)
|
||||
goto errout;
|
||||
dev_name = basename(tmp_name);
|
||||
tdb_file = malloc(strlen(tdb_dir) + 8 + strlen(dev_name) + 7 + 1);
|
||||
if (!tdb_file) {
|
||||
free(tmp_name);
|
||||
goto errout;
|
||||
}
|
||||
sprintf(tdb_file, "%s/resize2fs-%s.e2undo", tdb_dir, dev_name);
|
||||
free(tmp_name);
|
||||
|
||||
if ((unlink(tdb_file) < 0) && (errno != ENOENT)) {
|
||||
retval = errno;
|
||||
goto errout;
|
||||
}
|
||||
|
||||
set_undo_io_backing_manager(*io_ptr);
|
||||
*io_ptr = undo_io_manager;
|
||||
retval = set_undo_io_backup_file(tdb_file);
|
||||
if (retval)
|
||||
goto errout;
|
||||
printf(_("Overwriting existing filesystem; this can be undone "
|
||||
"using the command:\n"
|
||||
" e2undo %s %s\n\n"), tdb_file, device_name);
|
||||
|
||||
if (free_tdb_dir)
|
||||
free(tdb_dir);
|
||||
free(tdb_file);
|
||||
return 0;
|
||||
|
||||
errout:
|
||||
if (free_tdb_dir)
|
||||
free(tdb_dir);
|
||||
free(tdb_file);
|
||||
err:
|
||||
com_err(program_name, retval, "%s",
|
||||
_("while trying to setup undo file\n"));
|
||||
return retval;
|
||||
}
|
||||
|
||||
int main (int argc, char ** argv)
|
||||
{
|
||||
errcode_t retval;
|
||||
|
@ -186,7 +264,7 @@ int main (int argc, char ** argv)
|
|||
unsigned int blocksize;
|
||||
long sysval;
|
||||
int len, mount_flags;
|
||||
char *mtpt;
|
||||
char *mtpt, *undo_file = NULL;
|
||||
|
||||
#ifdef ENABLE_NLS
|
||||
setlocale(LC_MESSAGES, "");
|
||||
|
@ -203,7 +281,7 @@ int main (int argc, char ** argv)
|
|||
if (argc && *argv)
|
||||
program_name = *argv;
|
||||
|
||||
while ((c = getopt(argc, argv, "d:fFhMPpS:bs")) != EOF) {
|
||||
while ((c = getopt(argc, argv, "d:fFhMPpS:bsz:")) != EOF) {
|
||||
switch (c) {
|
||||
case 'h':
|
||||
usage(program_name);
|
||||
|
@ -235,6 +313,9 @@ int main (int argc, char ** argv)
|
|||
case 's':
|
||||
flags |= RESIZE_DISABLE_64BIT;
|
||||
break;
|
||||
case 'z':
|
||||
undo_file = optarg;
|
||||
break;
|
||||
default:
|
||||
usage(program_name);
|
||||
}
|
||||
|
@ -318,7 +399,11 @@ int main (int argc, char ** argv)
|
|||
io_flags = EXT2_FLAG_RW | EXT2_FLAG_EXCLUSIVE;
|
||||
|
||||
io_flags |= EXT2_FLAG_64BITS;
|
||||
|
||||
if (undo_file) {
|
||||
retval = resize2fs_setup_tdb(device_name, undo_file, &io_ptr);
|
||||
if (retval)
|
||||
exit(1);
|
||||
}
|
||||
retval = ext2fs_open2(device_name, io_options, io_flags,
|
||||
0, 0, io_ptr, &fs);
|
||||
if (retval) {
|
||||
|
|
|
@ -18,6 +18,10 @@ resize2fs \- ext2/ext3/ext4 file system resizer
|
|||
.B \-S
|
||||
.I RAID-stride
|
||||
]
|
||||
[
|
||||
.B \-z
|
||||
.I undo_file
|
||||
]
|
||||
.I device
|
||||
[
|
||||
.I size
|
||||
|
@ -149,6 +153,16 @@ The
|
|||
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 \-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
|
||||
contents of the file system should something go wrong. If the empty string is
|
||||
passed as the undo_file argument, the undo file will be written to a file named
|
||||
resize2fs-\fIdevice\fR.e2undo in the directory specified via the
|
||||
\fIE2FSPROGS_UNDO_DIR\fR environment variable.
|
||||
|
||||
WARNING: The undo file cannot be used to recover from a power or system crash.
|
||||
.SH KNOWN BUGS
|
||||
The minimum size of the filesystem as estimated by resize2fs may be
|
||||
incorrect, especially for filesystems with 1k and 2k blocksizes.
|
||||
|
|
Loading…
Reference in New Issue