mirror of
git://sourceware.org/git/lvm2.git
synced 2024-12-21 13:34:40 +03:00
wiping: add support for blkid wiping
This is actually the wipefs functionailty as a matter of fact (wipefs uses the same libblkid calls). libblkid is more rich when it comes to detecting various signatures, including filesystems and users can better decide what to erase and what should be kept. The code is shared for both pvcreate (where wiping is necessary to complete the pvcreate operation) and lvcreate where it's up to the user to decide. The verbose output contains a bit more information about the signature like LABEL and UUID. For example: raw/~ # lvcreate -L16m vg WARNING: linux_raid_member signature detected on /dev/vg/lvol0 at offset 4096. Wipe it? [y/n] or more verbose one: raw/~ # lvcreate -L16m vg -v ... Found existing signature on /dev/vg/lvol0 at offset 4096: LABEL="raw.virt:0" UUID="da6af139-8403-5d06-b8c4-13f6f24b73b1" TYPE="linux_raid_member" USAGE="raid" WARNING: linux_raid_member signature detected on /dev/vg/lvol0 at offset 4096. Wipe it? [y/n] The verbose output is the same output as found in blkid.
This commit is contained in:
parent
ab2f858af7
commit
eaa23d3273
@ -21,6 +21,10 @@
|
||||
#include <libgen.h>
|
||||
#include <ctype.h>
|
||||
|
||||
#ifdef BLKID_WIPING_SUPPORT
|
||||
#include <blkid/blkid.h>
|
||||
#endif
|
||||
|
||||
#include "device-types.h"
|
||||
|
||||
struct dev_types *create_dev_types(const char *proc_dir,
|
||||
@ -443,6 +447,102 @@ out:
|
||||
return ret;
|
||||
}
|
||||
|
||||
#ifdef BLKID_WIPING_SUPPORT
|
||||
|
||||
static int _blkid_wipe(blkid_probe probe, struct device *dev,
|
||||
const char *name, int yes, force_t force)
|
||||
{
|
||||
const char *offset = NULL, *type = NULL, *magic = NULL,
|
||||
*usage = NULL, *label = NULL, *uuid = NULL;
|
||||
loff_t offset_value;
|
||||
size_t len;
|
||||
|
||||
if (!blkid_probe_lookup_value(probe, "TYPE", &type, NULL)) {
|
||||
if (!blkid_probe_lookup_value(probe, "SBMAGIC_OFFSET", &offset, NULL) &&
|
||||
blkid_probe_lookup_value(probe, "SBMAGIC", &magic, &len))
|
||||
return_0;
|
||||
} else if (!blkid_probe_lookup_value(probe, "PTTYPE", &type, NULL)) {
|
||||
if (!blkid_probe_lookup_value(probe, "PTMAGIC_OFFSET", &offset, NULL) &&
|
||||
blkid_probe_lookup_value(probe, "PTMAGIC", &magic, &len))
|
||||
return_0;
|
||||
usage = "partition table";
|
||||
} else
|
||||
return_0;
|
||||
|
||||
offset_value = strtoll(offset, NULL, 10);
|
||||
|
||||
if (!usage)
|
||||
blkid_probe_lookup_value(probe, "USAGE", &usage, NULL);
|
||||
blkid_probe_lookup_value(probe, "LABEL", &label, NULL);
|
||||
blkid_probe_lookup_value(probe, "UUID", &uuid, NULL);
|
||||
|
||||
log_verbose("Found existing signature on %s at offset %s: LABEL=\"%s\" "
|
||||
"UUID=\"%s\" TYPE=\"%s\" USAGE=\"%s\"",
|
||||
name, offset, label, uuid, type, usage);
|
||||
|
||||
if (!yes && (force == PROMPT) &&
|
||||
yes_no_prompt("WARNING: %s signature detected on %s at offset %s. "
|
||||
"Wipe it? [y/n] ", type, name, offset) != 'y')
|
||||
return_0;
|
||||
|
||||
log_print_unless_silent("Wiping %s signature on %s.", type, name);
|
||||
if (!dev_set(dev, offset_value, len, 0)) {
|
||||
log_error("Failed to wipe %s signature on %s.", type, name);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int _wipe_known_signatures_with_blkid(struct device *dev, const char *name,
|
||||
int yes, force_t force)
|
||||
{
|
||||
blkid_probe probe = NULL;
|
||||
int found = 0, wiped = 0, left = 0;
|
||||
int r = 0;
|
||||
|
||||
/* TODO: Should we check for valid dev - _dev_is_valid(dev)? */
|
||||
|
||||
if (!(probe = blkid_new_probe_from_filename(dev_name(dev)))) {
|
||||
log_error("Failed to create a new blkid probe for device %s.", dev_name(dev));
|
||||
goto out;
|
||||
}
|
||||
|
||||
blkid_probe_enable_partitions(probe, 1);
|
||||
blkid_probe_set_partitions_flags(probe, BLKID_PARTS_MAGIC);
|
||||
|
||||
blkid_probe_enable_superblocks(probe, 1);
|
||||
blkid_probe_set_superblocks_flags(probe, BLKID_SUBLKS_LABEL |
|
||||
BLKID_SUBLKS_UUID |
|
||||
BLKID_SUBLKS_TYPE |
|
||||
BLKID_SUBLKS_USAGE |
|
||||
BLKID_SUBLKS_VERSION |
|
||||
BLKID_SUBLKS_MAGIC |
|
||||
BLKID_SUBLKS_BADCSUM);
|
||||
|
||||
while (!blkid_do_probe(probe)) {
|
||||
found++;
|
||||
if (_blkid_wipe(probe, dev, name, yes, force))
|
||||
wiped++;
|
||||
}
|
||||
|
||||
if (!found)
|
||||
r = 1;
|
||||
|
||||
left = found - wiped;
|
||||
if (!left)
|
||||
r = 1;
|
||||
else
|
||||
log_warn("%d existing signature%s left on the device.",
|
||||
left, left > 1 ? "s" : "");
|
||||
out:
|
||||
if (probe)
|
||||
blkid_free_probe(probe);
|
||||
return r;
|
||||
}
|
||||
|
||||
#endif /* BLKID_WIPING_SUPPORT */
|
||||
|
||||
static int _wipe_signature(struct device *dev, const char *type, const char *name,
|
||||
int wipe_len, int yes, force_t force,
|
||||
int (*signature_detection_fn)(struct device *dev, uint64_t *offset_found))
|
||||
@ -475,7 +575,8 @@ static int _wipe_signature(struct device *dev, const char *type, const char *nam
|
||||
return 1;
|
||||
}
|
||||
|
||||
int wipe_known_signatures(struct device *dev, const char *name, int yes, force_t force)
|
||||
static int _wipe_known_signatures_with_lvm(struct device *dev, const char *name,
|
||||
int yes, force_t force)
|
||||
{
|
||||
if (!_wipe_signature(dev, "software RAID md superblock", name, 4, yes, force, dev_is_md) ||
|
||||
!_wipe_signature(dev, "swap signature", name, 10, yes, force, dev_is_swap) ||
|
||||
@ -485,6 +586,16 @@ int wipe_known_signatures(struct device *dev, const char *name, int yes, force_t
|
||||
return 1;
|
||||
}
|
||||
|
||||
int wipe_known_signatures(struct cmd_context *cmd, struct device *dev,
|
||||
const char *name, int yes, force_t force)
|
||||
{
|
||||
#ifdef BLKID_WIPING_SUPPORT
|
||||
if (find_config_tree_bool(cmd, allocation_use_blkid_wiping_CFG, NULL))
|
||||
return _wipe_known_signatures_with_blkid(dev, name, yes, force);
|
||||
#endif
|
||||
return _wipe_known_signatures_with_lvm(dev, name, yes, force);
|
||||
}
|
||||
|
||||
#ifdef __linux__
|
||||
|
||||
static int _snprintf_attr(char *buf, size_t buf_size, const char *sysfs_dir,
|
||||
|
@ -60,7 +60,7 @@ int dev_is_swap(struct device *dev, uint64_t *signature);
|
||||
int dev_is_luks(struct device *dev, uint64_t *signature);
|
||||
|
||||
/* Signature wiping. */
|
||||
int wipe_known_signatures(struct device *dev, const char *name, int yes, force_t force);
|
||||
int wipe_known_signatures(struct cmd_context *cmd, struct device *dev, const char *name, int yes, force_t force);
|
||||
|
||||
/* Type-specific device properties */
|
||||
unsigned long dev_md_stripe_width(struct dev_types *dt, struct device *dev);
|
||||
|
@ -5429,7 +5429,7 @@ int wipe_lv(struct cmd_context *cmd, struct wipe_lv_params *wp)
|
||||
if (wp->do_wipe_signatures) {
|
||||
log_verbose("Wiping known signatures on logical volume \"%s/%s\"",
|
||||
wp->lv->vg->name, wp->lv->name);
|
||||
if (!wipe_known_sbs(dev, name, wp->yes, wp->force))
|
||||
if (!wipe_known_signatures(cmd, dev, name, wp->yes, wp->force))
|
||||
stack;
|
||||
}
|
||||
|
||||
|
@ -1330,7 +1330,7 @@ static int pvcreate_check(struct cmd_context *cmd, const char *name,
|
||||
goto bad;
|
||||
}
|
||||
|
||||
if (!wipe_known_signatures(dev, name, pp->yes, pp->force)) {
|
||||
if (!wipe_known_signatures(cmd, dev, name, pp->yes, pp->force)) {
|
||||
log_error("Aborting pvcreate on %s.", name);
|
||||
goto bad;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user