summaryrefslogtreecommitdiffstats
path: root/misc-utils
diff options
context:
space:
mode:
authorKarel Zak2011-11-11 12:48:38 +0100
committerKarel Zak2011-11-11 12:48:38 +0100
commit6611a3dd783006fd8c6b924a76c4820287278d36 (patch)
treefe1f6251302b89650e272c7c4800334a923d1e06 /misc-utils
parentlibblkid: add blkid_do_wipe() (diff)
downloadkernel-qcow2-util-linux-6611a3dd783006fd8c6b924a76c4820287278d36.tar.gz
kernel-qcow2-util-linux-6611a3dd783006fd8c6b924a76c4820287278d36.tar.xz
kernel-qcow2-util-linux-6611a3dd783006fd8c6b924a76c4820287278d36.zip
wipefs: improve -a, use blkid_do_wipe()
Some filesystems (e.g. FAT) is possible to detect in many ways -- for example if a magic string is stored on more places on the device. The current implementation always removes from the device only the firstly detected possibility. # wipefs /dev/sdb1 offset type ---------------------------------------------------------------- 0x36 vfat [filesystem] UUID: D203-A7F4 # wipefs -a /dev/sdb1 8 bytes [46 41 54 31 36 20 20 20] erased at offset 0x36 (vfat) # wipefs /dev/sdb1 offset type ---------------------------------------------------------------- 0x0 vfat [filesystem] UUID: D203-A7F4 This patch fixes this issue: # wipefs -a /dev/sdb1 8 bytes were erased at offset 0x00000036 (vfat): 46 41 54 31 36 20 20 20 1 bytes were erased at offset 0x00000000 (vfat): eb 2 bytes were erased at offset 0x000001fe (vfat): 55 aa Signed-off-by: Karel Zak <kzak@redhat.com>
Diffstat (limited to 'misc-utils')
-rw-r--r--misc-utils/wipefs.c158
1 files changed, 92 insertions, 66 deletions
diff --git a/misc-utils/wipefs.c b/misc-utils/wipefs.c
index 58fc03d00..1cd3159d1 100644
--- a/misc-utils/wipefs.c
+++ b/misc-utils/wipefs.c
@@ -49,6 +49,8 @@ struct wipe_desc {
char *label; /* FS label */
char *uuid; /* FS uuid */
+ int on_disk;
+
struct wipe_desc *next;
};
@@ -138,7 +140,7 @@ add_offset(struct wipe_desc *wp0, loff_t offset, int zap)
}
static struct wipe_desc *
-get_offset_from_probe(struct wipe_desc *wp, blkid_probe pr, int zap)
+get_desc_for_probe(struct wipe_desc *wp, blkid_probe pr)
{
const char *off, *type, *usage, *mag;
size_t len;
@@ -151,12 +153,13 @@ get_offset_from_probe(struct wipe_desc *wp, blkid_probe pr, int zap)
loff_t offset = strtoll(off, NULL, 10);
const char *p;
- wp = add_offset(wp, offset, zap);
+ wp = add_offset(wp, offset, 0);
if (!wp)
return NULL;
wp->usage = xstrdup(usage);
wp->type = xstrdup(type);
+ wp->on_disk = 1;
wp->magic = xmalloc(len);
memcpy(wp->magic, mag, len);
@@ -172,18 +175,28 @@ get_offset_from_probe(struct wipe_desc *wp, blkid_probe pr, int zap)
return wp;
}
-static struct wipe_desc *
-read_offsets(struct wipe_desc *wp, const char *fname, int zap)
+static blkid_probe
+new_probe(const char *devname, int mode)
{
blkid_probe pr;
int rc;
- if (!fname)
+ if (!devname)
return NULL;
- pr = blkid_new_probe_from_filename(fname);
+ if (mode) {
+ int fd = open(devname, mode);
+ if (fd < 0)
+ goto error;
+
+ pr = blkid_new_probe();
+ if (pr && blkid_probe_set_device(pr, fd, 0, 0))
+ goto error;
+ } else
+ pr = blkid_new_probe_from_filename(devname);
+
if (!pr)
- errx(EXIT_FAILURE, _("error: %s: probing initialization failed"), fname);
+ goto error;
blkid_probe_enable_superblocks(pr, 0); /* enabled by default ;-( */
@@ -195,7 +208,7 @@ read_offsets(struct wipe_desc *wp, const char *fname, int zap)
const char *type = NULL;
blkid_probe_lookup_value(pr, "PTTYPE", &type, NULL);
warnx(_("WARNING: %s: appears to contain '%s' "
- "partition table"), fname, type);
+ "partition table"), devname, type);
}
blkid_probe_enable_superblocks(pr, 1);
@@ -203,8 +216,22 @@ read_offsets(struct wipe_desc *wp, const char *fname, int zap)
BLKID_SUBLKS_TYPE | BLKID_SUBLKS_USAGE |
BLKID_SUBLKS_LABEL | BLKID_SUBLKS_UUID);
+ return pr;
+error:
+ err(EXIT_FAILURE, _("error: %s: probing initialization failed"), devname);
+ return NULL;
+}
+
+static struct wipe_desc *
+read_offsets(struct wipe_desc *wp, const char *devname)
+{
+ blkid_probe pr = new_probe(devname, 0);
+
+ if (!pr)
+ return NULL;
+
while (blkid_do_probe(pr) == 0) {
- wp = get_offset_from_probe(wp, pr, zap);
+ wp = get_desc_for_probe(wp, pr);
if (!wp)
break;
}
@@ -213,60 +240,54 @@ read_offsets(struct wipe_desc *wp, const char *fname, int zap)
return wp;
}
-static int
-do_wipe_offset(int fd, struct wipe_desc *wp, const char *fname, int noact)
+static struct wipe_desc *
+do_wipe(struct wipe_desc *wp, const char *devname, int noact, int all)
{
- char buf[BUFSIZ];
- off_t l;
- size_t i, len;
-
- if (!wp->type) {
- warnx(_("no magic string found at offset "
- "0x%jx -- ignored"), wp->offset);
- return 0;
- }
-
- l = lseek(fd, wp->offset, SEEK_SET);
- if (l == (off_t) -1)
- err(EXIT_FAILURE, _("%s: failed to seek to offset 0x%jx"),
- fname, wp->offset);
-
- len = wp->len > sizeof(buf) ? sizeof(buf) : wp->len;
-
- memset(buf, 0, len);
- if (noact == 0 && write_all(fd, buf, len))
- err(EXIT_FAILURE, _("%s: write failed"), fname);
+ blkid_probe pr = new_probe(devname, O_RDWR);
+ struct wipe_desc *w;
- printf(_("%zd bytes were erased at offset 0x%jx (%s)\nthey were: "),
- wp->len, wp->offset, wp->type);
+ if (!pr)
+ return NULL;
- for (i = 0; i < len; i++) {
- printf("%02x", wp->magic[i]);
- if (i + 1 < len)
- fputc(' ', stdout);
+ while (blkid_do_probe(pr) == 0) {
+ w = get_desc_for_probe(wp, pr);
+ if (!w)
+ break;
+ wp = w;
+ if (!wp->on_disk)
+ continue;
+ wp->zap = all ? 1 : wp->zap;
+ if (!wp->zap)
+ continue;
+
+ if (blkid_do_wipe(pr, noact))
+ warn(_("failed to erase %s magic string at offset 0x%08jx"),
+ wp->type, wp->offset);
+ else {
+ size_t i;
+
+ printf(_("%zd bytes were erased at offset 0x%08jx (%s): "),
+ wp->len, wp->offset, wp->type);
+
+ for (i = 0; i < wp->len; i++) {
+ printf("%02x", wp->magic[i]);
+ if (i + 1 < wp->len)
+ fputc(' ', stdout);
+ }
+ putchar('\n');
+ }
}
- printf("\n");
- return 0;
-}
-
-static int
-do_wipe(struct wipe_desc *wp, const char *fname, int noact)
-{
- int fd;
-
- fd = open(fname, O_WRONLY);
- if (fd < 0)
- err(EXIT_FAILURE, _("%s: open failed"), fname);
-
- while (wp) {
- if (wp->zap)
- do_wipe_offset(fd, wp, fname, noact);
- wp = wp->next;
+ for (w = wp; w != NULL; w = w->next) {
+ if (!w->on_disk)
+ warnx(_("offset 0x%jx not found"), w->offset);
}
- close(fd);
- return 0;
+ fsync(blkid_probe_get_fd(pr));
+ close(blkid_probe_get_fd(pr));
+ blkid_free_probe(pr);
+
+ return wp;
}
static void
@@ -323,7 +344,7 @@ main(int argc, char **argv)
{
struct wipe_desc *wp = NULL;
int c, all = 0, has_offset = 0, noact = 0, mode = 0;
- const char *fname;
+ const char *devname;
static const struct option longopts[] = {
{ "all", 0, 0, 'a' },
@@ -372,20 +393,25 @@ main(int argc, char **argv)
if (optind == argc)
usage(stderr);
- fname = argv[optind++];
+ devname = argv[optind++];
if (optind != argc)
errx(EXIT_FAILURE, _("only one device as argument is currently supported."));
- wp = read_offsets(wp, fname, all);
-
- if (wp) {
- if (has_offset || all)
- do_wipe(wp, fname, noact);
- else
+ if (!all && !has_offset) {
+ /*
+ * Print only
+ */
+ wp = read_offsets(wp, devname);
+ if (wp)
print_all(wp, mode);
-
- free_wipe(wp);
+ } else {
+ /*
+ * Erase
+ */
+ wp = do_wipe(wp, devname, noact, all);
}
+
+ free_wipe(wp);
return EXIT_SUCCESS;
}