master - backup: backup_restore_vg: register PVs that need writing via vg->pvs_to_write list
by Peter Rajnoha
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=d84a80afb5e654...
Commit: d84a80afb5e65420fdca3c283754a90e5b0bacaa
Parent: 531ced90dcaa6d7b18189cb9169456b74c6a2d65
Author: Peter Rajnoha <prajnoha(a)redhat.com>
AuthorDate: Thu Mar 26 14:20:46 2015 +0100
Committer: Peter Rajnoha <prajnoha(a)redhat.com>
CommitterDate: Mon Feb 15 12:44:46 2016 +0100
backup: backup_restore_vg: register PVs that need writing via vg->pvs_to_write list
The backup_restore_vg is used directly for restoring the VG from backup.
It's also used to do the VG conversions from one metadata format to
another which means vgconvert calls backup_restore_vg too.
When restoring VG from backup, we need to rewrite/write PV headers as
PVs may have been orphans before and now they're becoming part of some
VG - we need to write the PV_EXT_USED flag at least.
When using the backup_restore_vg for vgconvert, we need to write
completely new PV header in different format.
Avoid the special "pv_write" call and handling that was used before
this patch in vgconvert (vgconvert_single function to be more precise)
and reuse existing internal interface to register PV header for writing
(or rewriting) via vg->pvs_to_write list instead like we do it elsewhere
in the code.
This patch also resolves a problem in which PV headers with target
format were written in the vgconvert_single fn as orphans and VG
metadata were added later on - this was a tiny hack actually.
We can't do this now - we need to write the PV as belonging
to a VG because otherwise the PV_EXT_USED flag won't be written
properly (if the PV header is written as orphan, the PV_EXT_USED
is set to 0, of course, even though metadata are attached later).
So this patch removes this tiny inconsistency which was passing
just fine before because we didn't have any relation to the VG
in PV header before. Now we have the PV_EXT_USED flag which says
the "PV is used in some VG".
---
lib/format_text/archiver.c | 120 +++++++++++++++++++++++++++++++++++++++----
lib/format_text/archiver.h | 3 +-
tools/vgconvert.c | 89 +++++----------------------------
3 files changed, 123 insertions(+), 89 deletions(-)
diff --git a/lib/format_text/archiver.c b/lib/format_text/archiver.c
index 56eb1ca..1bc9557 100644
--- a/lib/format_text/archiver.c
+++ b/lib/format_text/archiver.c
@@ -329,28 +329,113 @@ struct volume_group *backup_read_vg(struct cmd_context *cmd,
return vg;
}
+static int _restore_vg_should_write_pv(struct physical_volume *pv, struct pvcreate_params *pp)
+{
+ struct lvmcache_info *info;
+
+ if (pp)
+ return 1;
+
+ if (!(pv->fmt->features & FMT_PV_FLAGS))
+ return 0;
+
+ if (!(info = lvmcache_info_from_pvid(pv->dev->pvid, 0))) {
+ log_error("Failed to find cached info for PV %s.", pv_dev_name(pv));
+ return -1;
+ }
+
+ /*
+ * We're restoring a VG and if the PV_EXT_USED
+ * flag is not set yet in PV, we need to set it now!
+ * This may happen if we have plain PVs without a VG
+ * and we're restoring former VG from backup on top
+ * of these PVs.
+ */
+ if (!(lvmcache_ext_flags(info) & PV_EXT_USED))
+ return 1;
+
+ return 0;
+}
+
/* ORPHAN and VG locks held before calling this */
-int backup_restore_vg(struct cmd_context *cmd, struct volume_group *vg, int drop_lvmetad)
+int backup_restore_vg(struct cmd_context *cmd, struct volume_group *vg,
+ struct pvcreate_params *pp, int drop_lvmetad)
{
- struct pv_list *pvl;
+ struct dm_list new_pvs;
+ struct pv_list *pvl, *new_pvl;
+ struct physical_volume *existing_pv, *pv;
+ struct dm_list *pvs = &vg->pvs;;
struct format_instance *fid;
struct format_instance_ctx fic;
+ int should_write_pv;
struct pv_to_write *pvw;
- uint32_t tmp;
+ uint32_t tmp_extent_size;
/*
* FIXME: Check that the PVs referenced in the backup are
* not members of other existing VGs.
*/
+ /* Prepare new PVs if needed. */
+ if (pp) {
+ dm_list_init(&new_pvs);
+
+ dm_list_iterate_items(pvl, &vg->pvs) {
+ existing_pv = pvl->pv;
+
+ pp->rp.id = existing_pv->id;
+ pp->rp.idp = &pp->rp.id;
+ pp->rp.pe_start = pv_pe_start(existing_pv);
+ pp->rp.extent_count = pv_pe_count(existing_pv);
+ pp->rp.extent_size = pv_pe_size(existing_pv);
+ /* pe_end = pv_pe_count(existing_pv) * pv_pe_size(existing_pv) + pe_start - 1 */
+
+ if (!(pv = pv_create(cmd, pv_dev(existing_pv),
+ 0, 0, 0,
+ pp->labelsector,
+ pp->pvmetadatacopies,
+ pp->pvmetadatasize,
+ 0, &pp->rp))) {
+ log_error("Failed to setup physical volume \"%s\".",
+ pv_dev_name(existing_pv));
+ return 0;
+ }
+ pv->vg_name = vg->name;
+ pv->vgid = vg->id;
+
+ if (!(new_pvl = dm_pool_zalloc(vg->vgmem, sizeof(*new_pvl)))) {
+ log_error("Failed to allocate PV list item for \"%s\".",
+ pv_dev_name(pvl->pv));
+ return 0;
+ }
+ new_pvl->pv = pv;
+ dm_list_add(&new_pvs, &new_pvl->list);
+
+ log_verbose("Set up physical volume for \"%s\" with %" PRIu64
+ " available sectors.", pv_dev_name(pv), pv_size(pv));
+ }
+
+ pvs = &new_pvs;
+ }
+
/* Attempt to write out using currently active format */
fic.type = FMT_INSTANCE_AUX_MDAS;
fic.context.vg_ref.vg_name = vg->name;
fic.context.vg_ref.vg_id = NULL;
if (!(fid = cmd->fmt->ops->create_instance(cmd->fmt, &fic))) {
- log_error("Failed to allocate format instance");
+ log_error("Failed to allocate format instance.");
return 0;
}
+
+ if (pp) {
+ log_verbose("Deleting existing metadata for VG %s.", vg->name);
+ if (!vg_remove_mdas(vg)) {
+ cmd->fmt->ops->destroy_instance(fid);
+ log_error("Removal of existing metadata for VG %s failed.", vg->name);
+ return 0;
+ }
+ }
+
vg_set_fid(vg, fid);
/*
@@ -363,25 +448,36 @@ int backup_restore_vg(struct cmd_context *cmd, struct volume_group *vg, int drop
}
/* Add any metadata areas on the PVs */
- dm_list_iterate_items(pvl, &vg->pvs) {
- if (pvl->pv->fmt->features & FMT_PV_FLAGS) {
+ dm_list_iterate_items(pvl, pvs) {
+ if ((should_write_pv = _restore_vg_should_write_pv(pvl->pv, pp)) < 0)
+ return_0;
+
+ if (should_write_pv) {
if (!(pvw = dm_pool_zalloc(vg->vgmem, sizeof(*pvw)))) {
- log_error("pv_to_write allocation for '%s' failed", pv_dev_name(pvl->pv));
+ log_error("Failed to allocate structure for scheduled "
+ "writing of PV '%s'.", pv_dev_name(pvl->pv));
return 0;
}
+
+ if (pp) {
+ pvw->new_pv = 1;
+ pvw->pp = pp;
+ }
+
pvw->pv = pvl->pv;
dm_list_add(&vg->pvs_to_write, &pvw->list);
}
- tmp = vg->extent_size;
+ /* Add any metadata areas on the PV. */
+ tmp_extent_size = vg->extent_size;
vg->extent_size = 0;
if (!vg->fid->fmt->ops->pv_setup(vg->fid->fmt, pvl->pv, vg)) {
- vg->extent_size = tmp;
- log_error("Format-specific setup for %s failed",
+ vg->extent_size = tmp_extent_size;
+ log_error("Format-specific setup for %s failed.",
pv_dev_name(pvl->pv));
return 0;
}
- vg->extent_size = tmp;
+ vg->extent_size = tmp_extent_size;
}
if (!vg_write(vg))
@@ -435,7 +531,7 @@ int backup_restore_from_file(struct cmd_context *cmd, const char *vg_name,
missing_pvs = vg_missing_pv_count(vg);
if (missing_pvs == 0)
- r = backup_restore_vg(cmd, vg, 1);
+ r = backup_restore_vg(cmd, vg, NULL, 1);
else
log_error("Cannot restore Volume Group %s with %i PVs "
"marked as missing.", vg->name, missing_pvs);
diff --git a/lib/format_text/archiver.h b/lib/format_text/archiver.h
index c283420..f85e5af 100644
--- a/lib/format_text/archiver.h
+++ b/lib/format_text/archiver.h
@@ -51,7 +51,8 @@ int backup_remove(struct cmd_context *cmd, const char *vg_name);
struct volume_group *backup_read_vg(struct cmd_context *cmd,
const char *vg_name, const char *file);
-int backup_restore_vg(struct cmd_context *cmd, struct volume_group *vg, int drop_lvmetad);
+int backup_restore_vg(struct cmd_context *cmd, struct volume_group *vg,
+ struct pvcreate_params *pp, int drop_lvmetad);
int backup_restore_from_file(struct cmd_context *cmd, const char *vg_name,
const char *file, int force);
int backup_restore(struct cmd_context *cmd, const char *vg_name, int force);
diff --git a/tools/vgconvert.c b/tools/vgconvert.c
index 0b680b9..de21a47 100644
--- a/tools/vgconvert.c
+++ b/tools/vgconvert.c
@@ -19,14 +19,9 @@ static int vgconvert_single(struct cmd_context *cmd, const char *vg_name,
struct volume_group *vg,
struct processing_handle *handle __attribute__((unused)))
{
- struct physical_volume *pv, *existing_pv;
- struct pvcreate_restorable_params rp;
+ struct pvcreate_params pp;
struct logical_volume *lv;
struct lv_list *lvl;
- int pvmetadatacopies = 0;
- uint64_t pvmetadatasize = 0;
- struct pv_list *pvl;
- int change_made = 0;
struct lvinfo info;
int active = 0;
@@ -39,21 +34,22 @@ static int vgconvert_single(struct cmd_context *cmd, const char *vg_name,
return ECMD_FAILED;
}
+ pvcreate_params_set_defaults(&pp);
+
if (cmd->fmt->features & FMT_MDAS) {
if (arg_sign_value(cmd, metadatasize_ARG, SIGN_NONE) == SIGN_MINUS) {
log_error("Metadata size may not be negative");
return EINVALID_CMD_LINE;
}
- pvmetadatasize = arg_uint64_value(cmd, metadatasize_ARG,
- UINT64_C(0));
- if (!pvmetadatasize)
- pvmetadatasize =
+ pp.pvmetadatasize = arg_uint64_value(cmd, metadatasize_ARG, UINT64_C(0));
+ if (!pp.pvmetadatasize)
+ pp.pvmetadatasize =
find_config_tree_int(cmd, metadata_pvmetadatasize_CFG, NULL);
- pvmetadatacopies = arg_int_value(cmd, pvmetadatacopies_ARG, -1);
- if (pvmetadatacopies < 0)
- pvmetadatacopies =
+ pp.pvmetadatacopies = arg_int_value(cmd, pvmetadatacopies_ARG, -1);
+ if (pp.pvmetadatacopies < 0)
+ pp.pvmetadatacopies =
find_config_tree_int(cmd, metadata_pvmetadatacopies_CFG, NULL);
}
@@ -63,9 +59,11 @@ static int vgconvert_single(struct cmd_context *cmd, const char *vg_name,
return EINVALID_CMD_LINE;
}
- rp.ba_size = arg_uint64_value(cmd, bootloaderareasize_ARG, UINT64_C(0));
+ pp.rp.ba_size = arg_uint64_value(cmd, bootloaderareasize_ARG, UINT64_C(0));
}
+ pp.labelsector = arg_int64_value(cmd, labelsector_ARG, DEFAULT_LABELSECTOR);
+
if (!vg_check_new_extent_size(cmd->fmt, vg->extent_size))
return_ECMD_FAILED;
@@ -124,67 +122,6 @@ static int vgconvert_single(struct cmd_context *cmd, const char *vg_name,
if (active)
return_ECMD_FAILED;
- dm_list_iterate_items(pvl, &vg->pvs) {
- existing_pv = pvl->pv;
-
- rp.id = existing_pv->id;
- rp.idp = &rp.id;
- rp.pe_start = pv_pe_start(existing_pv);
- rp.extent_count = pv_pe_count(existing_pv);
- rp.extent_size = pv_pe_size(existing_pv);
-
- /* pe_end = pv_pe_count(existing_pv) * pv_pe_size(existing_pv) + pe_start - 1; */
-
- if (!(pv = pv_create(cmd, pv_dev(existing_pv),
- 0, 0, 0,
- arg_int64_value(cmd, labelsector_ARG,
- DEFAULT_LABELSECTOR),
- pvmetadatacopies, pvmetadatasize, 0, &rp))) {
- log_error("Failed to setup physical volume \"%s\"",
- pv_dev_name(existing_pv));
- if (change_made)
- log_error("Use pvcreate and vgcfgrestore to "
- "repair from archived metadata.");
- return ECMD_FAILED;
- }
-
- /* Need to revert manually if it fails after this point */
- change_made = 1;
-
- log_verbose("Set up physical volume for \"%s\" with %" PRIu64
- " available sectors", pv_dev_name(pv), pv_size(pv));
-
- /* Wipe existing label first */
- if (!label_remove(pv_dev(pv))) {
- log_error("Failed to wipe existing label on %s",
- pv_dev_name(pv));
- log_error("Use pvcreate and vgcfgrestore to repair "
- "from archived metadata.");
- return ECMD_FAILED;
- }
-
- log_very_verbose("Writing physical volume data to disk \"%s\"",
- pv_dev_name(pv));
- if (!(pv_write(cmd, pv, 0))) {
- log_error("Failed to write physical volume \"%s\"",
- pv_dev_name(pv));
- log_error("Use pvcreate and vgcfgrestore to repair "
- "from archived metadata.");
- return ECMD_FAILED;
- }
- log_verbose("Physical volume \"%s\" successfully created",
- pv_dev_name(pv));
- }
-
- log_verbose("Deleting existing metadata for VG %s", vg_name);
- if (!vg_remove_mdas(vg)) {
- log_error("Removal of existing metadata for %s failed.",
- vg_name);
- log_error("Use pvcreate and vgcfgrestore to repair "
- "from archived metadata.");
- return ECMD_FAILED;
- }
-
/* FIXME Cache the label format change so we don't have to skip this */
if (test_mode()) {
log_verbose("Test mode: Skipping metadata writing for VG %s in"
@@ -194,7 +131,7 @@ static int vgconvert_single(struct cmd_context *cmd, const char *vg_name,
log_verbose("Writing metadata for VG %s using format %s", vg_name,
cmd->fmt->name);
- if (!backup_restore_vg(cmd, vg, 0)) {
+ if (!backup_restore_vg(cmd, vg, &pp, 0)) {
log_error("Conversion failed for volume group %s.", vg_name);
log_error("Use pvcreate and vgcfgrestore to repair from "
"archived metadata.");
8 years, 2 months
master - metadata: _vg_read: check if PV_EXT_USED flag is set correctly for non-orphan PVs and do a repair if needed
by Peter Rajnoha
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=531ced90dcaa6d...
Commit: 531ced90dcaa6d7b18189cb9169456b74c6a2d65
Parent: f75e42c06cd925d414c1069d6c51e0b50e1934a8
Author: Peter Rajnoha <prajnoha(a)redhat.com>
AuthorDate: Thu Mar 19 07:53:22 2015 +0100
Committer: Peter Rajnoha <prajnoha(a)redhat.com>
CommitterDate: Mon Feb 15 12:44:46 2016 +0100
metadata: _vg_read: check if PV_EXT_USED flag is set correctly for non-orphan PVs and do a repair if needed
The same check as we already do for orphan PVs, just the other way
round now: if the PV is surely part of some VG and any PV the VG
contains does not have the PV_EXT_USED flag set, repair it.
For example - /dev/sda here is in VG vg and it's incorrectly not
marked as used by PV_EXT_USED flag:
pvs --binary -o pv_ext_vsn,pv_in_use
WARNING: Volume Group vg is not consistent.
WARNING: Repairing Physical Volume /dev/sda that is in Volume Group vg but not marked as used.
PV VG Fmt Attr PSize PFree ExtVsn PInUse
/dev/sda vg lvm2 a-- 124.00m 124.00m 2 1
---
lib/metadata/metadata.c | 57 ++++++++++++++++++++++++++++++++++++++++++++++-
1 files changed, 56 insertions(+), 1 deletions(-)
diff --git a/lib/metadata/metadata.c b/lib/metadata/metadata.c
index 172edc1..a08cfc3 100644
--- a/lib/metadata/metadata.c
+++ b/lib/metadata/metadata.c
@@ -3569,6 +3569,52 @@ static int _check_reappeared_pv(struct volume_group *correct_vg,
return rv;
}
+static int _check_or_repair_pv_ext(struct cmd_context *cmd,
+ struct physical_volume *pv,
+ int repair, int *inconsistent_pvs)
+{
+ struct lvmcache_info *info;
+ uint32_t ext_version, ext_flags;
+
+ /* Missing PV - nothing to do. */
+ if (!pv->dev)
+ return 1;
+
+ if (!(info = lvmcache_info_from_pvid(pv->dev->pvid, 0))) {
+ log_error("Failed to find cached info for PV %s.", pv_dev_name(pv));
+ return 0;
+ }
+
+ ext_version = lvmcache_ext_version(info);
+ if (ext_version < 2) {
+ *inconsistent_pvs = 0;
+ return 1;
+ }
+
+ ext_flags = lvmcache_ext_flags(info);
+ if (!(ext_flags & PV_EXT_USED)) {
+ if (!repair) {
+ *inconsistent_pvs = 1;
+ return 1;
+ }
+
+ log_warn("WARNING: Repairing Physical Volume %s that is "
+ "in Volume Group %s but not marked as used.",
+ pv_dev_name(pv), pv->vg->name);
+
+ /* pv write will set correct ext_flags */
+ if (!pv_write(cmd, pv, 1)) {
+ *inconsistent_pvs = 1;
+ log_error("Failed to repair physical volume \"%s\".",
+ pv_dev_name(pv));
+ return 0;
+ }
+ }
+
+ *inconsistent_pvs = 0;
+ return 1;
+}
+
static int _repair_inconsistent_vg(struct volume_group *vg)
{
unsigned saved_handles_missing_pvs = vg->cmd->handles_missing_pvs;
@@ -3872,6 +3918,7 @@ static struct volume_group *_vg_read(struct cmd_context *cmd,
inconsistent_pvs = 1;
break;
}
+
if (lvmcache_mda_count(info)) {
if (!lvmcache_fid_add_mdas_pv(info, fid)) {
release_vg(correct_vg);
@@ -4149,7 +4196,15 @@ static struct volume_group *_vg_read(struct cmd_context *cmd,
return NULL;
}
- *consistent = 1;
+ /* We have the VG now finally, check if PV ext info is in sync with VG metadata. */
+ dm_list_iterate_items(pvl, &correct_vg->pvs) {
+ if (!_check_or_repair_pv_ext(cmd, pvl->pv, *consistent, &inconsistent_pvs)) {
+ release_vg(correct_vg);
+ return_NULL;
+ }
+ }
+
+ *consistent = !inconsistent_pvs;
return correct_vg;
}
8 years, 2 months
master - report: add pv_ext_vsn field to display PV header extension version used
by Peter Rajnoha
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=f75e42c06cd925...
Commit: f75e42c06cd925d414c1069d6c51e0b50e1934a8
Parent: e0b141510523bb09e5a784d6e1b30f106e8dbbf3
Author: Peter Rajnoha <prajnoha(a)redhat.com>
AuthorDate: Tue Mar 17 09:49:08 2015 +0100
Committer: Peter Rajnoha <prajnoha(a)redhat.com>
CommitterDate: Mon Feb 15 12:44:46 2016 +0100
report: add pv_ext_vsn field to display PV header extension version used
For example:
$ pvs -o pv_name,vg_name,pv_ext_vsn,pv_in_use
PV VG ExtVsn InUse
/dev/sda 2
/dev/sdb vg 2 used
/dev/vda2 fedora 1 used
---
lib/report/columns.h | 1 +
lib/report/properties.c | 2 ++
lib/report/report.c | 17 +++++++++++++++++
3 files changed, 20 insertions(+), 0 deletions(-)
diff --git a/lib/report/columns.h b/lib/report/columns.h
index e6f8485..7ea7f52 100644
--- a/lib/report/columns.h
+++ b/lib/report/columns.h
@@ -122,6 +122,7 @@ FIELD(LABEL, label, SIZ, "DevSize", dev, 7, devsize, dev_size, "Size of underlyi
FIELD(LABEL, label, STR, "PV", dev, 10, dev_name, pv_name, "Name.", 0)
FIELD(LABEL, label, SIZ, "PMdaFree", type, 9, pvmdafree, pv_mda_free, "Free metadata area space on this device in current units.", 0)
FIELD(LABEL, label, SIZ, "PMdaSize", type, 9, pvmdasize, pv_mda_size, "Size of smallest metadata area on this device in current units.", 0)
+FIELD(LABEL, label, NUM, "PExtVsn", type, 7, pvextvsn, pv_ext_vsn, "PV header extension version.", 0)
FIELD(PVS, pv, NUM, "1st PE", pe_start, 7, size64, pe_start, "Offset to the start of data on the underlying device.", 0)
FIELD(PVS, pv, SIZ, "PSize", id, 5, pvsize, pv_size, "Size of PV in current units.", 0)
diff --git a/lib/report/properties.c b/lib/report/properties.c
index 118e659..d23e4c9 100644
--- a/lib/report/properties.c
+++ b/lib/report/properties.c
@@ -190,6 +190,8 @@ GET_PV_NUM_PROPERTY_FN(pv_ba_size, SECTOR_SIZE * pv->ba_size)
#define _pv_exported_get prop_not_implemented_get
#define _pv_missing_set prop_not_implemented_set
#define _pv_missing_get prop_not_implemented_get
+#define _pv_ext_vsn_get prop_not_implemented_get
+#define _pv_ext_vsn_set prop_not_implemented_set
#define _pv_in_use_get prop_not_implemented_get
#define _pv_in_use_set prop_not_implemented_set
diff --git a/lib/report/report.c b/lib/report/report.c
index f7f3775..3f2bd0c 100644
--- a/lib/report/report.c
+++ b/lib/report/report.c
@@ -2554,6 +2554,23 @@ static int _pvmdasize_disp(struct dm_report *rh, struct dm_pool *mem,
return _size64_disp(rh, mem, field, &min_mda_size, private);
}
+static int _pvextvsn_disp(struct dm_report *rh, struct dm_pool *mem,
+ struct dm_report_field *field,
+ const void *data, void *private)
+{
+ const struct label *label = (const struct label *) data;
+ struct lvmcache_info *info = label->info;
+ uint32_t ext_version;
+
+ if (info) {
+ ext_version = lvmcache_ext_version(info);
+ return _uint32_disp(rh, mem, field, &ext_version, private);
+ }
+
+ return _field_set_value(field, "", &GET_TYPE_RESERVED_VALUE(num_undef_64));
+}
+
+
static int _vgmdasize_disp(struct dm_report *rh, struct dm_pool *mem,
struct dm_report_field *field,
const void *data, void *private)
8 years, 2 months
master - metadata: check for PV extension version before doing any checks on PV extension flags
by Peter Rajnoha
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=e0b141510523bb...
Commit: e0b141510523bb09e5a784d6e1b30f106e8dbbf3
Parent: d97f1c89deb9a75452059cd62ebb20cf7d2d6bfa
Author: Peter Rajnoha <prajnoha(a)redhat.com>
AuthorDate: Mon Mar 16 18:23:43 2015 +0100
Committer: Peter Rajnoha <prajnoha(a)redhat.com>
CommitterDate: Mon Feb 15 12:44:46 2016 +0100
metadata: check for PV extension version before doing any checks on PV extension flags
PV header extension versions:
0 - the original PV without any extensions
1 - bootloader area support added
2 - PV_EXT_USED flag support added
So do the associated checks related to PV_EXT_USED flag only if
PV header extension found is of version 2 and higher.
---
lib/metadata/metadata.c | 12 ++++++++++++
1 files changed, 12 insertions(+), 0 deletions(-)
diff --git a/lib/metadata/metadata.c b/lib/metadata/metadata.c
index 61084bc..172edc1 100644
--- a/lib/metadata/metadata.c
+++ b/lib/metadata/metadata.c
@@ -3348,9 +3348,21 @@ static int _check_or_repair_orphan_pv_ext(struct physical_volume *pv,
struct lvmcache_info *info,
struct _vg_read_orphan_baton *b)
{
+ uint32_t ext_version = lvmcache_ext_version(info);
uint32_t ext_flags = lvmcache_ext_flags(info);
int at_least_one_mda_used;
+ /*
+ * Nothing to do if PV header extension < 2:
+ * - version 0 is PV header without any extensions,
+ * - version 1 has bootloader area support only and
+ * we're not checking anything for that one here.
+ */
+ if (ext_version < 2) {
+ b->consistent = 1;
+ return 1;
+ }
+
if (ext_flags & PV_EXT_USED) {
if (lvmcache_mda_count(info)) {
at_least_one_mda_used = 0;
8 years, 2 months
master - metadata: _vg_read: check if PV_EXT_USED flag is set correctly for orphan PVs and do a repair if needed
by Peter Rajnoha
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=d97f1c89deb9a7...
Commit: d97f1c89deb9a75452059cd62ebb20cf7d2d6bfa
Parent: 3436d5b79116d067e8f20d5365ae0dae6bd19dc8
Author: Peter Rajnoha <prajnoha(a)redhat.com>
AuthorDate: Wed Mar 11 16:18:42 2015 +0100
Committer: Peter Rajnoha <prajnoha(a)redhat.com>
CommitterDate: Mon Feb 15 12:44:46 2016 +0100
metadata: _vg_read: check if PV_EXT_USED flag is set correctly for orphan PVs and do a repair if needed
If we know that the PV is orphan, meaning there's at least one MDA on
that PV which does not reference any VG and at the same time there's
PV_EXT_USED flag set, we're certainly in an inconsistent state and we
need to fix this.
For example, such situation can happen during vgremove/vgreduce if we
removed/reduced the VG, but we haven't written PV headers yet because
vgremove stopped abruptly for whatever reason just before writing new
PV headers with updated state, including PV extension flags (and so the
PV_EXT_USED flag).
However, in case the PV has no MDAs at all, we can't double-check
whether the PV_EXT_USED is correct or not - if that PV is marked
as used, it's either:
- really used (but other disks with MDAs are missing)
- or the error state as described above is hit
User needs to overwrite the PV header directly if it's really clear
the PV having no MDAs does not belong to any VG and at the same time
it's still marked as being in use (pvcreate -ff <dev_name> will fix this).
For example - /dev/sda here has 1 MDA, orphan and is incorrectly marked
with PV_EXT_USED flag:
$ pvs --binary -o+pv_in_use
WARNING: Found inconsistent standalone Physical Volumes.
WARNING: Repairing flag incorrectly marking Physical Volume /dev/sda as used.
PV VG Fmt Attr PSize PFree InUse
/dev/sda lvm2 --- 128.00m 128.00m 0
---
lib/metadata/metadata.c | 92 +++++++++++++++++++++++++++++++++++++++--------
tools/toollib.c | 5 ++-
2 files changed, 81 insertions(+), 16 deletions(-)
diff --git a/lib/metadata/metadata.c b/lib/metadata/metadata.c
index 7af545a..61084bc 100644
--- a/lib/metadata/metadata.c
+++ b/lib/metadata/metadata.c
@@ -3328,11 +3328,64 @@ void vg_revert(struct volume_group *vg)
stack; // FIXME: What should we do?
}
+static int _check_mda_in_use(struct metadata_area *mda, void *_in_use)
+{
+ int *in_use = _in_use;
+ if (!mda_is_ignored(mda))
+ *in_use = 1;
+ return 1;
+}
+
struct _vg_read_orphan_baton {
+ struct cmd_context *cmd;
struct volume_group *vg;
uint32_t warn_flags;
+ int consistent;
+ int repair;
};
+static int _check_or_repair_orphan_pv_ext(struct physical_volume *pv,
+ struct lvmcache_info *info,
+ struct _vg_read_orphan_baton *b)
+{
+ uint32_t ext_flags = lvmcache_ext_flags(info);
+ int at_least_one_mda_used;
+
+ if (ext_flags & PV_EXT_USED) {
+ if (lvmcache_mda_count(info)) {
+ at_least_one_mda_used = 0;
+ lvmcache_foreach_mda(info, _check_mda_in_use, &at_least_one_mda_used);
+
+ /*
+ * We've found a PV that is marked as used with PV_EXT_USED flag
+ * and it's orphan at the same time while it contains MDAs.
+ * This is incorrect state and it needs to be fixed.
+ * The PV_EXT_USED flag needs to be dropped!
+ */
+ if (b->repair) {
+ if (at_least_one_mda_used) {
+ log_warn("WARNING: Repairing flag incorrectly marking "
+ "Physical Volume %s as used.", pv_dev_name(pv));
+
+ /* pv_write will set correct ext_flags */
+ if (!pv_write(b->cmd, pv, 0)) {
+ b->consistent = 0;
+ log_error("Failed to repair physical volume \"%s\".",
+ pv_dev_name(pv));
+ return 0;
+ }
+ }
+ b->consistent = 1;
+ } else if (at_least_one_mda_used) {
+ /* mark as inconsistent only if there's at least 1 MDA used */
+ b->consistent = 0;
+ }
+ }
+ }
+
+ return 1;
+}
+
static int _vg_read_orphan_pv(struct lvmcache_info *info, void *baton)
{
struct _vg_read_orphan_baton *b = baton;
@@ -3352,13 +3405,20 @@ static int _vg_read_orphan_pv(struct lvmcache_info *info, void *baton)
}
pvl->pv = pv;
add_pvl_to_vgs(b->vg, pvl);
+
+ if (!_check_or_repair_orphan_pv_ext(pv, info, baton)) {
+ stack;
+ return 0;
+ }
+
return 1;
}
/* Make orphan PVs look like a VG. */
static struct volume_group *_vg_read_orphans(struct cmd_context *cmd,
uint32_t warn_flags,
- const char *orphan_vgname)
+ const char *orphan_vgname,
+ int *consistent)
{
const struct format_type *fmt;
struct lvmcache_vginfo *vginfo;
@@ -3390,8 +3450,11 @@ static struct volume_group *_vg_read_orphans(struct cmd_context *cmd,
vg->extent_count = 0;
vg->free_count = 0;
+ baton.cmd = cmd;
baton.warn_flags = warn_flags;
baton.vg = vg;
+ baton.consistent = 1;
+ baton.repair = *consistent;
while ((pvl = (struct pv_list *) dm_list_first(&head.list))) {
dm_list_del(&pvl->list);
@@ -3403,6 +3466,7 @@ static struct volume_group *_vg_read_orphans(struct cmd_context *cmd,
if (!lvmcache_foreach_pv(vginfo, _vg_read_orphan_pv, &baton))
return_NULL;
+ *consistent = baton.consistent;
return vg;
}
@@ -3526,14 +3590,6 @@ static int _repair_inconsistent_vg(struct volume_group *vg)
return 1;
}
-static int _check_mda_in_use(struct metadata_area *mda, void *_in_use)
-{
- int *in_use = _in_use;
- if (!mda_is_ignored(mda))
- *in_use = 1;
- return 1;
-}
-
static int _wipe_outdated_pvs(struct cmd_context *cmd, struct volume_group *vg, struct dm_list *to_check)
{
struct pv_list *pvl, *pvl2;
@@ -3631,8 +3687,7 @@ static struct volume_group *_vg_read(struct cmd_context *cmd,
"with pre-commit.");
return NULL;
}
- *consistent = 1;
- return _vg_read_orphans(cmd, warn_flags, vgname);
+ return _vg_read_orphans(cmd, warn_flags, vgname, consistent);
}
if (lvmetad_active() && !use_precommitted) {
@@ -4131,8 +4186,12 @@ struct volume_group *vg_read_internal(struct cmd_context *cmd, const char *vgnam
}
out:
- if (!*consistent && (warn_flags & WARN_INCONSISTENT))
- log_warn("WARNING: Volume Group %s is not consistent.", vgname);
+ if (!*consistent && (warn_flags & WARN_INCONSISTENT)) {
+ if (is_orphan_vg(vgname))
+ log_warn("WARNING: Found inconsistent standalone Physical Volumes.");
+ else
+ log_warn("WARNING: Volume Group %s is not consistent.", vgname);
+ }
return vg;
}
@@ -5126,8 +5185,11 @@ static struct volume_group *_vg_lock_and_read(struct cmd_context *cmd, const cha
if (!consistent && !failure) {
release_vg(vg);
if (!(vg = _recover_vg(cmd, vg_name, vgid))) {
- log_error("Recovery of volume group \"%s\" failed.",
- vg_name);
+ if (is_orphan_vg(vg_name))
+ log_error("Recovery of standalone physical volumes failed.");
+ else
+ log_error("Recovery of volume group \"%s\" failed.",
+ vg_name);
failure |= FAILED_RECOVERY;
goto bad_no_unlock;
}
diff --git a/tools/toollib.c b/tools/toollib.c
index f9ac259..7f8c2eb 100644
--- a/tools/toollib.c
+++ b/tools/toollib.c
@@ -258,7 +258,10 @@ static int _ignore_vg(struct volume_group *vg, const char *vg_name,
if (read_error != SUCCESS) {
*skip = 0;
- log_error("Cannot process volume group %s", vg_name);
+ if (is_orphan_vg(vg_name))
+ log_error("Cannot process standalone physical volumes");
+ else
+ log_error("Cannot process volume group %s", vg_name);
return 1;
}
8 years, 2 months
master - report: add pv_in_use field to display whether PV is in use or not
by Peter Rajnoha
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=3436d5b79116d0...
Commit: 3436d5b79116d067e8f20d5365ae0dae6bd19dc8
Parent: b6e3080fff7f101f2bbec21a7757e54e6026d61d
Author: Peter Rajnoha <prajnoha(a)redhat.com>
AuthorDate: Tue Mar 10 16:10:16 2015 +0100
Committer: Peter Rajnoha <prajnoha(a)redhat.com>
CommitterDate: Mon Feb 15 12:44:46 2016 +0100
report: add pv_in_use field to display whether PV is in use or not
For example:
$ pvs -o pv_name,vg_name,pv_in_use
PV VG InUse
/dev/sda vg used
/dev/sdb
/dev/sdc used
(sda is part of vg - it's used
sdb is not part of vg - it's not used
sdc is part of vg, but MDAs missing - it's used)
---
lib/report/columns.h | 1 +
lib/report/properties.c | 2 ++
lib/report/report.c | 13 +++++++++++++
lib/report/values.h | 1 +
4 files changed, 17 insertions(+), 0 deletions(-)
diff --git a/lib/report/columns.h b/lib/report/columns.h
index 5cf9d04..e6f8485 100644
--- a/lib/report/columns.h
+++ b/lib/report/columns.h
@@ -138,6 +138,7 @@ FIELD(PVS, pv, NUM, "#PMda", id, 5, pvmdas, pv_mda_count, "Number of metadata ar
FIELD(PVS, pv, NUM, "#PMdaUse", id, 8, pvmdasused, pv_mda_used_count, "Number of metadata areas in use on this device.", 0)
FIELD(PVS, pv, SIZ, "BA start", ba_start, 8, size64, pv_ba_start, "Offset to the start of PV Bootloader Area on the underlying device in current units.", 0)
FIELD(PVS, pv, SIZ, "BA size", ba_size, 7, size64, pv_ba_size, "Size of PV Bootloader Area in current units.", 0)
+FIELD(PVS, pv, BIN, "PInUse", id, 6, pvinuse, pv_in_use, "Set if PV is used.", 0)
FIELD(VGS, vg, STR, "Fmt", cmd, 3, vgfmt, vg_fmt, "Type of metadata.", 0)
FIELD(VGS, vg, STR, "VG UUID", id, 38, uuid, vg_uuid, "Unique identifier.", 0)
diff --git a/lib/report/properties.c b/lib/report/properties.c
index ef5a671..118e659 100644
--- a/lib/report/properties.c
+++ b/lib/report/properties.c
@@ -190,6 +190,8 @@ GET_PV_NUM_PROPERTY_FN(pv_ba_size, SECTOR_SIZE * pv->ba_size)
#define _pv_exported_get prop_not_implemented_get
#define _pv_missing_set prop_not_implemented_set
#define _pv_missing_get prop_not_implemented_get
+#define _pv_in_use_get prop_not_implemented_get
+#define _pv_in_use_set prop_not_implemented_set
#define _vg_permissions_set prop_not_implemented_set
#define _vg_permissions_get prop_not_implemented_get
diff --git a/lib/report/report.c b/lib/report/report.c
index 34e71f2..f7f3775 100644
--- a/lib/report/report.c
+++ b/lib/report/report.c
@@ -2866,6 +2866,19 @@ static int _pvmissing_disp(struct dm_report *rh, struct dm_pool *mem,
return _binary_disp(rh, mem, field, missing, GET_FIRST_RESERVED_NAME(pv_missing_y), private);
}
+static int _pvinuse_disp(struct dm_report *rh, struct dm_pool *mem,
+ struct dm_report_field *field,
+ const void *data, void *private)
+{
+ const struct physical_volume *pv = (const struct physical_volume *) data;
+ int used = is_used_pv(pv);
+
+ if (used < 0)
+ return _binary_undef_disp(rh, mem, field, private);
+
+ return _binary_disp(rh, mem, field, used, GET_FIRST_RESERVED_NAME(pv_in_use_y), private);
+}
+
static int _vgpermissions_disp(struct dm_report *rh, struct dm_pool *mem,
struct dm_report_field *field,
const void *data, void *private)
diff --git a/lib/report/values.h b/lib/report/values.h
index 1db85a2..8a430fc 100644
--- a/lib/report/values.h
+++ b/lib/report/values.h
@@ -52,6 +52,7 @@ TYPE_RESERVED_VALUE(NUM, NOFLAG, num_undef_64, "Reserved value for undefined num
FIELD_RESERVED_BINARY_VALUE(pv_allocatable, pv_allocatable, "", "allocatable")
FIELD_RESERVED_BINARY_VALUE(pv_exported, pv_exported, "", "exported")
FIELD_RESERVED_BINARY_VALUE(pv_missing, pv_missing, "", "missing")
+FIELD_RESERVED_BINARY_VALUE(pv_in_use, pv_in_use, "", "used", "in use")
/* Reserved values for VG fields */
FIELD_RESERVED_BINARY_VALUE(vg_extendable, vg_extendable, "", "extendable")
8 years, 2 months
master - pv: _pvcreate_write: do label removal and zeroing only if creating a new PV
by Peter Rajnoha
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=b6e3080fff7f10...
Commit: b6e3080fff7f101f2bbec21a7757e54e6026d61d
Parent: 73f1d444c8fccf7f0c95d09ff4b2a6c9f0e40e02
Author: Peter Rajnoha <prajnoha(a)redhat.com>
AuthorDate: Thu Mar 12 15:18:52 2015 +0100
Committer: Peter Rajnoha <prajnoha(a)redhat.com>
CommitterDate: Mon Feb 15 12:44:46 2016 +0100
pv: _pvcreate_write: do label removal and zeroing only if creating a new PV
---
lib/metadata/metadata.c | 33 +++++++++++++++++----------------
1 files changed, 17 insertions(+), 16 deletions(-)
diff --git a/lib/metadata/metadata.c b/lib/metadata/metadata.c
index 90643fa..7af545a 100644
--- a/lib/metadata/metadata.c
+++ b/lib/metadata/metadata.c
@@ -1637,32 +1637,33 @@ void pvcreate_params_set_defaults(struct pvcreate_params *pp)
static int _pvcreate_write(struct cmd_context *cmd, struct pv_to_write *pvw)
{
- int zero = pvw->pp ? pvw->pp->zero : 1;
struct physical_volume *pv = pvw->pv;
struct device *dev = pv->dev;
const char *pv_name = dev_name(dev);
- /* Wipe existing label first */
- if (!label_remove(pv_dev(pv))) {
- log_error("Failed to wipe existing label on %s", pv_name);
- return 0;
- }
-
- if (zero) {
- log_verbose("Zeroing start of device %s", pv_name);
- if (!dev_open_quiet(dev)) {
- log_error("%s not opened: device not zeroed", pv_name);
+ if (pvw->new_pv) {
+ /* Wipe existing label first */
+ if (!label_remove(pv_dev(pv))) {
+ log_error("Failed to wipe existing label on %s", pv_name);
return 0;
}
- if (!dev_set(dev, UINT64_C(0), (size_t) 2048, 0)) {
- log_error("%s not wiped: aborting", pv_name);
+ if (pvw->pp->zero) {
+ log_verbose("Zeroing start of device %s", pv_name);
+ if (!dev_open_quiet(dev)) {
+ log_error("%s not opened: device not zeroed", pv_name);
+ return 0;
+ }
+
+ if (!dev_set(dev, UINT64_C(0), (size_t) 2048, 0)) {
+ log_error("%s not wiped: aborting", pv_name);
+ if (!dev_close(dev))
+ stack;
+ return 0;
+ }
if (!dev_close(dev))
stack;
- return 0;
}
- if (!dev_close(dev))
- stack;
}
log_verbose("Writing physical volume data to disk \"%s\"",
8 years, 2 months
master - pv: issue different message of different type when we're overwriting existing PV header instead of creating a new one
by Peter Rajnoha
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=73f1d444c8fccf...
Commit: 73f1d444c8fccf7f0c95d09ff4b2a6c9f0e40e02
Parent: 52999133a36e5ab194dfa10d9108ca09ff1c930d
Author: Peter Rajnoha <prajnoha(a)redhat.com>
AuthorDate: Tue Mar 10 14:19:20 2015 +0100
Committer: Peter Rajnoha <prajnoha(a)redhat.com>
CommitterDate: Mon Feb 15 12:44:46 2016 +0100
pv: issue different message of different type when we're overwriting existing PV header instead of creating a new one
Scenario:
$ pvcreate /dev/sda
Physical volume "/dev/sda" successfully created
We're adding the PV to a VG.
Before this patch:
$ vgcreate vg /dev/sda
Physical volume "/dev/sda" successfully created
Volume group "vg" successfully created
With this path applied:
$ vgcreate vg /dev/sda
Volume group "vg" successfully created
...and verbose log containing: "Physical volume "/dev/sda" successfully written"
---
lib/metadata/metadata.c | 8 +++++++-
lib/metadata/vg.h | 1 +
2 files changed, 8 insertions(+), 1 deletions(-)
diff --git a/lib/metadata/metadata.c b/lib/metadata/metadata.c
index a463754..90643fa 100644
--- a/lib/metadata/metadata.c
+++ b/lib/metadata/metadata.c
@@ -297,6 +297,7 @@ int add_pv_to_vg(struct volume_group *vg, const char *pv_name,
}
pvw->pv = pv;
pvw->pp = new_pv ? pp : NULL;
+ pvw->new_pv = new_pv;
dm_list_add(&vg->pvs_to_write, &pvw->list);
}
@@ -1672,7 +1673,11 @@ static int _pvcreate_write(struct cmd_context *cmd, struct pv_to_write *pvw)
return 0;
}
- log_print_unless_silent("Physical volume \"%s\" successfully created", pv_name);
+ if (pvw->new_pv)
+ log_print_unless_silent("Physical volume \"%s\" successfully created", pv_name);
+ else
+ log_verbose("Physical volume \"%s\" successfully written", pv_name);
+
return 1;
}
@@ -1791,6 +1796,7 @@ struct physical_volume *pvcreate_vol(struct cmd_context *cmd, const char *pv_nam
struct pv_to_write pvw;
pvw.pp = pp;
pvw.pv = pv;
+ pvw.new_pv = 1;
if (!_pvcreate_write(cmd, &pvw))
goto bad;
}
diff --git a/lib/metadata/vg.h b/lib/metadata/vg.h
index 1c7c31c..f6c7bcc 100644
--- a/lib/metadata/vg.h
+++ b/lib/metadata/vg.h
@@ -36,6 +36,7 @@ struct pv_to_write {
struct dm_list list;
struct physical_volume *pv;
struct pvcreate_params *pp;
+ int new_pv;
};
#define MAX_EXTENT_COUNT (UINT32_MAX)
8 years, 2 months
master - pv: check for the PV_EXT_USED flag and deny pvcreate/pvchange/pvremove/vgcreate on such PV (unless forced)
by Peter Rajnoha
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=52999133a36e5a...
Commit: 52999133a36e5ab194dfa10d9108ca09ff1c930d
Parent: d320d9c52bd1817daf5573b772e01a871837d2ee
Author: Peter Rajnoha <prajnoha(a)redhat.com>
AuthorDate: Tue Mar 10 11:25:14 2015 +0100
Committer: Peter Rajnoha <prajnoha(a)redhat.com>
CommitterDate: Mon Feb 15 12:44:46 2016 +0100
pv: check for the PV_EXT_USED flag and deny pvcreate/pvchange/pvremove/vgcreate on such PV (unless forced)
Make sure we won't use a PV that is already marked as used. Normally,
VG metadata would stop us from doing that, but we can run into a
situation where such metadata is missing because PVs with MDAs
are missing and the PVs left are the ones with 0 MDAs.
(/dev/sda in this example has 0 MDAs and it belongs to a VG,
but other PVs with MDA are missing)
$ pvs -o pv_name,pv_mda_count /dev/sda
PV #PMda
/dev/sda 0
$ pvcreate /dev/sda
PV '/dev/sda' is marked as belonging to a VG but its metadata is missing.
Can't initialize PV '/dev/sda' without -ff.
$ pvchange -u /dev/sda
PV '/dev/sda' is marked as belonging to a VG but its metadata is missing.
Can't change PV '/dev/sda' without -ff.
Physical volume /dev/sda not changed
0 physical volumes changed / 1 physical volume not changed
$ pvremove /dev/sda
PV '/dev/sda' is marked as belonging to a VG but its metadata is missing.
(If you are certain you need pvremove, then confirm by using --force twice.)
$ vgcreate vg /dev/sda
Physical volume '/dev/sda' is marked as belonging to a VG but its metadata is missing.
Unable to add physical volume '/dev/sda' to volume group 'vg'.
---
lib/metadata/metadata.c | 30 ++++++++++++++++++++++++++----
lib/metadata/pv_manip.c | 15 +++++++++++++--
tools/pvchange.c | 20 ++++++++++++++++----
3 files changed, 55 insertions(+), 10 deletions(-)
diff --git a/lib/metadata/metadata.c b/lib/metadata/metadata.c
index 9c0423e..a463754 100644
--- a/lib/metadata/metadata.c
+++ b/lib/metadata/metadata.c
@@ -185,6 +185,7 @@ int add_pv_to_vg(struct volume_group *vg, const char *pv_name,
struct format_instance *fid = vg->fid;
struct dm_pool *mem = vg->vgmem;
char uuid[64] __attribute__((aligned(8)));
+ int used;
log_verbose("Adding physical volume '%s' to volume group '%s'",
pv_name, vg->name);
@@ -198,6 +199,15 @@ int add_pv_to_vg(struct volume_group *vg, const char *pv_name,
log_error("Physical volume '%s' is already in volume group "
"'%s'", pv_name, pv->vg_name);
return 0;
+ } else if (!new_pv) {
+ if ((used = is_used_pv(pv)) < 0)
+ return_0;
+
+ if (used) {
+ log_error("Physical volume '%s' is marked as belonging to a VG "
+ "but its metadata is missing.", pv_name);
+ return 0;
+ }
}
if (pv->fmt != fid->fmt) {
@@ -1464,6 +1474,7 @@ static int _pvcreate_check(struct cmd_context *cmd, const char *name,
int r = 0;
int scan_needed = 0;
int filter_refresh_needed = 0;
+ int used;
/* FIXME Check partition type is LVM unless --force is given */
@@ -1474,10 +1485,21 @@ static int _pvcreate_check(struct cmd_context *cmd, const char *name,
/* Allow partial & exported VGs to be destroyed. */
/* We must have -ff to overwrite a non orphan */
- if (pv && !is_orphan(pv) && pp->force != DONT_PROMPT_OVERRIDE) {
- log_error("Can't initialize physical volume \"%s\" of "
- "volume group \"%s\" without -ff", name, pv_vg_name(pv));
- goto out;
+ if (pv) {
+ if (!is_orphan(pv) && pp->force != DONT_PROMPT_OVERRIDE) {
+ log_error("Can't initialize physical volume \"%s\" of "
+ "volume group \"%s\" without -ff.", name, pv_vg_name(pv));
+ goto out;
+ }
+
+ if ((used = is_used_pv(pv)) < 0)
+ goto_out;
+
+ if (used && pp->force != DONT_PROMPT_OVERRIDE) {
+ log_error("PV '%s' is marked as belonging to a VG but its metadata is missing.", name);
+ log_error("Can't initialize PV '%s' without -ff.", name);
+ goto out;
+ }
}
/* prompt */
diff --git a/lib/metadata/pv_manip.c b/lib/metadata/pv_manip.c
index 7126048..423b647 100644
--- a/lib/metadata/pv_manip.c
+++ b/lib/metadata/pv_manip.c
@@ -697,11 +697,12 @@ const char _really_wipe[] =
static int pvremove_check(struct cmd_context *cmd, const char *name,
unsigned force_count, unsigned prompt, struct dm_list *pvslist)
{
+ static const char pvremove_force_hint_msg[] = "(If you are certain you need pvremove, then confirm by using --force twice.)";
struct device *dev;
struct label *label;
struct pv_list *pvl;
-
struct physical_volume *pv = NULL;
+ int used;
int r = 0;
/* FIXME Check partition type is LVM unless --force is given */
@@ -731,6 +732,16 @@ static int pvremove_check(struct cmd_context *cmd, const char *name,
}
if (is_orphan(pv)) {
+ if ((used = is_used_pv(pv)) < 0)
+ goto_out;
+
+ if (used && force_count < 2) {
+ log_error("PV '%s' is marked as belonging to a VG "
+ "but its metadata is missing.", name);
+ log_error("%s", pvremove_force_hint_msg);
+ goto out;
+ }
+
r = 1;
goto out;
}
@@ -738,7 +749,7 @@ static int pvremove_check(struct cmd_context *cmd, const char *name,
/* we must have -ff to overwrite a non orphan */
if (force_count < 2) {
log_error("PV %s belongs to Volume Group %s so please use vgreduce first.", name, pv_vg_name(pv));
- log_error("(If you are certain you need pvremove, then confirm by using --force twice.)");
+ log_error("%s", pvremove_force_hint_msg);
goto out;
}
diff --git a/tools/pvchange.c b/tools/pvchange.c
index 82b60f1..7f9aaf8 100644
--- a/tools/pvchange.c
+++ b/tools/pvchange.c
@@ -27,6 +27,7 @@ static int _pvchange_single(struct cmd_context *cmd, struct volume_group *vg,
const char *pv_name = pv_dev_name(pv);
char uuid[64] __attribute__((aligned(8)));
unsigned done = 0;
+ int used;
int allocatable = arg_int_value(cmd, allocatable_ARG, 0);
int mda_ignore = arg_int_value(cmd, metadataignore_ARG, 0);
@@ -48,10 +49,21 @@ static int _pvchange_single(struct cmd_context *cmd, struct volume_group *vg,
}
if (!archive(vg))
goto_bad;
- } else if (tagargs) {
- log_error("Can't change tag on Physical Volume %s not "
- "in volume group", pv_name);
- goto bad;
+ } else {
+ if (tagargs) {
+ log_error("Can't change tag on Physical Volume %s not "
+ "in volume group", pv_name);
+ goto bad;
+ }
+
+ if ((used = is_used_pv(pv)) < 0)
+ goto_bad;
+
+ if (used && (arg_count(cmd, force_ARG) != DONT_PROMPT_OVERRIDE)) {
+ log_error("PV '%s' is marked as belonging to a VG but its metadata is missing.", pv_name);
+ log_error("Can't change PV '%s' without -ff.", pv_name);
+ goto bad;
+ }
}
if (arg_count(cmd, allocatable_ARG)) {
8 years, 2 months
master - pv: format-text: store PV_EXT_USED flag if PV is used and unset it otherwise
by Peter Rajnoha
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=d320d9c52bd181...
Commit: d320d9c52bd1817daf5573b772e01a871837d2ee
Parent: 10128c9bd67a027b480e0f0637745f97fb39ecfa
Author: Peter Rajnoha <prajnoha(a)redhat.com>
AuthorDate: Fri Feb 12 10:59:27 2016 +0100
Committer: Peter Rajnoha <prajnoha(a)redhat.com>
CommitterDate: Mon Feb 15 12:44:46 2016 +0100
pv: format-text: store PV_EXT_USED flag if PV is used and unset it otherwise
When adding a PV to VG, set the PV_EXT_USED flag in PV header and
vice versa - if the PV is no longer in a VG, unset the flag.
---
lib/format_text/format-text.c | 18 ++++++++++++++++++
1 files changed, 18 insertions(+), 0 deletions(-)
diff --git a/lib/format_text/format-text.c b/lib/format_text/format-text.c
index f290619..7202658 100644
--- a/lib/format_text/format-text.c
+++ b/lib/format_text/format-text.c
@@ -1319,6 +1319,21 @@ static int _write_single_mda(struct metadata_area *mda, void *baton)
return 1;
}
+static int _set_ext_flags(struct physical_volume *pv, struct lvmcache_info *info)
+{
+ uint32_t ext_flags = lvmcache_ext_flags(info);
+
+ if (is_orphan(pv))
+ ext_flags &= ~PV_EXT_USED;
+ else
+ ext_flags |= PV_EXT_USED;
+
+ lvmcache_set_ext_version(info, PV_HEADER_EXTENSION_VSN);
+ lvmcache_set_ext_flags(info, ext_flags);
+
+ return 1;
+}
+
/* Only for orphans - FIXME That's not true any more */
static int _text_pv_write(const struct format_type *fmt, struct physical_volume *pv)
{
@@ -1402,6 +1417,9 @@ static int _text_pv_write(const struct format_type *fmt, struct physical_volume
if (!lvmcache_foreach_mda(info, _write_single_mda, &baton))
return_0;
+ if (!_set_ext_flags(pv, info))
+ return_0;
+
if (!label_write(pv->dev, label)) {
stack;
if (!dev_close(pv->dev))
8 years, 2 months