wipefs: add --backup
[kzak@redhat.com: - don't wipe if failed to create a backup file - use ts_scsi_debug_init in the regression tests] Signed-off-by: Ondrej Oprala <ooprala@redhat.com> Signed-off-by: Karel Zak <kzak@redhat.com>
This commit is contained in:
parent
0adc576dec
commit
7e658c15a2
|
@ -40,6 +40,10 @@ erased.
|
|||
Erase all available signatures. The set of erased signatures can be
|
||||
restricted with the \fB\-t\fP \fIlist\fP option.
|
||||
.TP
|
||||
.BR \-b , " \-\-backup"
|
||||
Create a signature backup to the file $HOME/wipefs-<devname>-<offset>.bak.
|
||||
For more details see EXAMPLES section.
|
||||
.TP
|
||||
.BR \-f , " \-\-force"
|
||||
Force erasure, even if the filesystem is mounted. This is required in
|
||||
order to erase the partition table on a block device.
|
||||
|
@ -75,6 +79,14 @@ taken. For more details see mount(8).
|
|||
.TP
|
||||
.BR -V , " \-\-version"
|
||||
Output version information and exit.
|
||||
.SH EXAMPLES
|
||||
.TP
|
||||
.BR "wipefs --all --backup /dev/sdb"
|
||||
Erases all signatures from the device /dev/sdb and creates a signature backup
|
||||
file ~/wipefs-sdb-<offset>.bak for each signature.
|
||||
.TP
|
||||
.BR "dd if=~/wipefs-sdb-0x00000438.bak of=/dev/sdb seek=$((0x00000438)) bs=1 conv=notrunc"
|
||||
Restores ext2 signature from the backup file ~/wipefs-sdb-0x00000438.bak.
|
||||
.SH AUTHOR
|
||||
Karel Zak <kzak@redhat.com>
|
||||
.SH ENVIRONMENT
|
||||
|
|
|
@ -309,13 +309,33 @@ static void do_wipe_real(blkid_probe pr, const char *devname, struct wipe_desc *
|
|||
putchar('\n');
|
||||
}
|
||||
|
||||
static void do_backup(struct wipe_desc *wp, const char *base)
|
||||
{
|
||||
char *fname = NULL;
|
||||
int fd;
|
||||
|
||||
xasprintf(&fname, "%s0x%08jx.bak", base, wp->offset);
|
||||
|
||||
fd = open(fname, O_CREAT | O_WRONLY, S_IRUSR | S_IWUSR);
|
||||
if (fd < 0)
|
||||
goto err;
|
||||
if (write_all(fd, wp->magic, wp->len) != 0)
|
||||
goto err;
|
||||
close(fd);
|
||||
free(fname);
|
||||
return;
|
||||
err:
|
||||
err(EXIT_FAILURE, _("%s: failed to create a signature backup"), fname);
|
||||
}
|
||||
|
||||
static struct wipe_desc *
|
||||
do_wipe(struct wipe_desc *wp, const char *devname, int noact, int all, int quiet, int force)
|
||||
do_wipe(struct wipe_desc *wp, const char *devname, int noact, int all, int bkp, int quiet, int force)
|
||||
{
|
||||
int flags;
|
||||
blkid_probe pr;
|
||||
struct wipe_desc *w, *wp0;
|
||||
int zap = all ? 1 : wp->zap;
|
||||
char *fn_base = NULL;
|
||||
|
||||
flags = O_RDWR;
|
||||
if (!force)
|
||||
|
@ -324,6 +344,13 @@ do_wipe(struct wipe_desc *wp, const char *devname, int noact, int all, int quiet
|
|||
if (!pr)
|
||||
return NULL;
|
||||
|
||||
if (zap && bkp) {
|
||||
const char *home = getenv ("HOME");
|
||||
if (!home)
|
||||
errx(EXIT_FAILURE, _("failed to create a signature backup, $HOME undefined"));
|
||||
xasprintf (&fn_base, "%s/wipefs-%s-", home, basename(devname));
|
||||
}
|
||||
|
||||
wp0 = clone_offset(wp);
|
||||
|
||||
while (blkid_do_probe(pr) == 0) {
|
||||
|
@ -345,8 +372,11 @@ do_wipe(struct wipe_desc *wp, const char *devname, int noact, int all, int quiet
|
|||
if (!wp->on_disk)
|
||||
continue;
|
||||
|
||||
if (zap)
|
||||
if (zap) {
|
||||
if (bkp)
|
||||
do_backup(wp, fn_base);
|
||||
do_wipe_real(pr, devname, wp, noact, quiet);
|
||||
}
|
||||
}
|
||||
|
||||
for (w = wp0; w != NULL; w = w->next) {
|
||||
|
@ -358,6 +388,7 @@ do_wipe(struct wipe_desc *wp, const char *devname, int noact, int all, int quiet
|
|||
close(blkid_probe_get_fd(pr));
|
||||
blkid_free_probe(pr);
|
||||
free_wipe(wp0);
|
||||
free(fn_base);
|
||||
|
||||
return wp;
|
||||
}
|
||||
|
@ -372,6 +403,7 @@ usage(FILE *out)
|
|||
|
||||
fputs(_("\nOptions:\n"), out);
|
||||
fputs(_(" -a, --all wipe all magic strings (BE CAREFUL!)\n"
|
||||
" -b, --backup create a signature backup in $HOME\n"
|
||||
" -f, --force force erasure\n"
|
||||
" -h, --help show this help text\n"
|
||||
" -n, --no-act do everything except the actual write() call\n"
|
||||
|
@ -391,11 +423,12 @@ int
|
|||
main(int argc, char **argv)
|
||||
{
|
||||
struct wipe_desc *wp0 = NULL, *wp;
|
||||
int c, all = 0, force = 0, has_offset = 0, noact = 0, quiet = 0;
|
||||
int c, all = 0, bkp = 0, force = 0, has_offset = 0, noact = 0, quiet = 0;
|
||||
int mode = WP_MODE_PRETTY;
|
||||
|
||||
static const struct option longopts[] = {
|
||||
{ "all", 0, 0, 'a' },
|
||||
{ "backup", 0, 0, 'b' },
|
||||
{ "force", 0, 0, 'f' },
|
||||
{ "help", 0, 0, 'h' },
|
||||
{ "no-act", 0, 0, 'n' },
|
||||
|
@ -426,6 +459,9 @@ main(int argc, char **argv)
|
|||
case 'a':
|
||||
all++;
|
||||
break;
|
||||
case 'b':
|
||||
bkp++;
|
||||
break;
|
||||
case 'f':
|
||||
force++;
|
||||
break;
|
||||
|
@ -461,6 +497,9 @@ main(int argc, char **argv)
|
|||
if (optind == argc)
|
||||
usage(stderr);
|
||||
|
||||
if (bkp && !(all || has_offset))
|
||||
warnx(_("The --backup option is meaningless in this context"));
|
||||
|
||||
if (!all && !has_offset) {
|
||||
/*
|
||||
* Print only
|
||||
|
@ -477,7 +516,7 @@ main(int argc, char **argv)
|
|||
*/
|
||||
while (optind < argc) {
|
||||
wp = clone_offset(wp0);
|
||||
wp = do_wipe(wp, argv[optind++], noact, all, quiet,
|
||||
wp = do_wipe(wp, argv[optind++], noact, all, bkp, quiet,
|
||||
force);
|
||||
free_wipe(wp);
|
||||
}
|
||||
|
|
|
@ -66,3 +66,4 @@ TS_CMD_UL=${TS_CMD_UL-"$top_builddir/ul"}
|
|||
TS_CMD_UMOUNT=${TS_CMD_UMOUNT:-"$top_builddir/umount"}
|
||||
TS_CMD_UTMPDUMP=${TS_CMD_UTMPDUMP-"$top_builddir/utmpdump"}
|
||||
TS_CMD_WHEREIS=${TS_CMD_WHEREIS-"$top_builddir/whereis"}
|
||||
TS_CMD_WIPEFS=${TS_CMD_WIPEFS-"$top_builddir/wipefs"}
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
OK
|
|
@ -0,0 +1,30 @@
|
|||
#!/bin/bash
|
||||
|
||||
TS_TOPDIR="$(dirname $0)/../.."
|
||||
TS_DESC="wipefs"
|
||||
|
||||
. $TS_TOPDIR/functions.sh
|
||||
ts_skip_nonroot
|
||||
ts_init "$*"
|
||||
|
||||
DEVICE=$(ts_scsi_debug_init dev_size_mb=50 num_parts=2)
|
||||
|
||||
# remove old backups
|
||||
rm -rf $HOME/wipefs-$(basename ${DEVICE})-*.bak
|
||||
|
||||
#remove the magic byte, back it up
|
||||
$TS_CMD_WIPEFS --all --backup ${DEVICE} &>/dev/null || ts_die "wipefs failed"
|
||||
|
||||
#there should be just one magic string/backup file in this case
|
||||
INFILE=$(ls $HOME/wipefs-$(basename ${DEVICE})-*.bak)
|
||||
OFFT=$(echo $INFILE | sed -E 's/^.*-(.*).bak$/\1/')
|
||||
dd if=$INFILE of=$DEVICE bs=1 conv=notrunc seek=$(($OFFT)) &>/dev/null
|
||||
|
||||
#the bytes should be copied back, check if wipefs can recognize it
|
||||
$TS_CMD_WIPEFS -a ${DEVICE} > $TS_OUTDIR/out 2>/dev/null
|
||||
|
||||
# check for output
|
||||
[ -s $TS_OUTDIR/out ] && echo "OK" &> $TS_OUTPUT || exit 1
|
||||
|
||||
rmmod scsi_debug &>/dev/null
|
||||
ts_finalize
|
Loading…
Reference in New Issue