dev-prajnoha-pv-ext-flag-used - 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=12752adfa9fe86...
Commit: 12752adfa9fe864cd32a43c0f5f43886c3f58588
Parent: 95fbbca4f1be486bb05cd99bd5d71f61dbd06015
Author: Peter Rajnoha <prajnoha(a)redhat.com>
AuthorDate: Tue Mar 17 09:49:08 2015 +0100
Committer: Peter Rajnoha <prajnoha(a)redhat.com>
CommitterDate: Fri Aug 21 11:15:53 2015 +0200
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 unknown
---
lib/report/columns.h | 3 ++-
lib/report/properties.c | 2 ++
lib/report/report.c | 16 ++++++++++++++++
3 files changed, 20 insertions(+), 1 deletions(-)
diff --git a/lib/report/columns.h b/lib/report/columns.h
index b29a93b..98f637c 100644
--- a/lib/report/columns.h
+++ b/lib/report/columns.h
@@ -113,7 +113,8 @@ 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, BIN, "PInUse", type, 6, pvinuse, pv_in_use, "Set if PV is used.", 0)
+FIELD(LABEL, label, NUM, "PExtVsn", type, 7, pvextvsn, pv_ext_vsn, "PV header extension version.", 0)
+FIELD(LABEL, label, BIN, "PInUse", type, 5, pvinuse, pv_in_use, "Set if PV is used.", 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 76c7158..b675aaa 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 21d2b05..1bc8e16 100644
--- a/lib/report/report.c
+++ b/lib/report/report.c
@@ -2301,6 +2301,22 @@ 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 _pvinuse_disp(struct dm_report *rh, struct dm_pool *mem,
struct dm_report_field *field,
const void *data, void *private)
8 years, 8 months
dev-prajnoha-pv-ext-flag-used - report: display 'unknown' value for pv_in_use field if PV extension version < 2
by Peter Rajnoha
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=95fbbca4f1be48...
Commit: 95fbbca4f1be486bb05cd99bd5d71f61dbd06015
Parent: 149dfe84901f3825d7576b66279322d35793d5ef
Author: Peter Rajnoha <prajnoha(a)redhat.com>
AuthorDate: Tue Mar 17 09:37:06 2015 +0100
Committer: Peter Rajnoha <prajnoha(a)redhat.com>
CommitterDate: Fri Aug 21 11:15:53 2015 +0200
report: display 'unknown' value for pv_in_use field if PV extension version < 2
For example:
$ pvs -o pv_name,vg_name,pv_in_use
PV VG InUse
/dev/sda
/dev/sdb vg used
/dev/vda2 fedora unknown
---
lib/report/report.c | 6 ++++--
1 files changed, 4 insertions(+), 2 deletions(-)
diff --git a/lib/report/report.c b/lib/report/report.c
index 4b80eaf..21d2b05 100644
--- a/lib/report/report.c
+++ b/lib/report/report.c
@@ -2310,8 +2310,10 @@ static int _pvinuse_disp(struct dm_report *rh, struct dm_pool *mem,
uint32_t ext_flags;
if (info) {
- ext_flags = lvmcache_ext_flags(info);
- return _binary_disp(rh, mem, field, ext_flags & PV_EXT_USED, GET_FIRST_RESERVED_NAME(pv_in_use_y), private);
+ if (lvmcache_ext_version(info) >= 2) {
+ ext_flags = lvmcache_ext_flags(info);
+ return _binary_disp(rh, mem, field, ext_flags & PV_EXT_USED, GET_FIRST_RESERVED_NAME(pv_in_use_y), private);
+ }
}
return _binary_undef_disp(rh, mem, field, private);
8 years, 8 months
dev-prajnoha-pv-ext-flag-used - 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=149dfe84901f38...
Commit: 149dfe84901f3825d7576b66279322d35793d5ef
Parent: e09842e17456628a378db8e22660d487095dbf00
Author: Peter Rajnoha <prajnoha(a)redhat.com>
AuthorDate: Mon Mar 16 18:23:43 2015 +0100
Committer: Peter Rajnoha <prajnoha(a)redhat.com>
CommitterDate: Fri Aug 21 11:15:53 2015 +0200
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 a147d40..8670fd6 100644
--- a/lib/metadata/metadata.c
+++ b/lib/metadata/metadata.c
@@ -3314,9 +3314,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, 8 months
dev-prajnoha-pv-ext-flag-used - lvmcache/lvmetad: cache PV extension version
by Peter Rajnoha
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=e09842e1745662...
Commit: e09842e17456628a378db8e22660d487095dbf00
Parent: 530efe587f0a0cbb9def7bda7f4b312b07ffde92
Author: Peter Rajnoha <prajnoha(a)redhat.com>
AuthorDate: Mon Mar 16 17:58:33 2015 +0100
Committer: Peter Rajnoha <prajnoha(a)redhat.com>
CommitterDate: Fri Aug 21 11:15:53 2015 +0200
lvmcache/lvmetad: cache PV extension version
Store PV extension version in lvmcache/lvmetad for use throughout the code.
---
lib/cache/lvmcache.c | 9 +++++++++
lib/cache/lvmcache.h | 2 ++
lib/cache/lvmetad.c | 3 +++
lib/format_text/format-text.c | 1 +
lib/format_text/layout.h | 7 ++++++-
lib/format_text/text_label.c | 3 +++
6 files changed, 24 insertions(+), 1 deletions(-)
diff --git a/lib/cache/lvmcache.c b/lib/cache/lvmcache.c
index b7261cf..1842e8e 100644
--- a/lib/cache/lvmcache.c
+++ b/lib/cache/lvmcache.c
@@ -42,6 +42,7 @@ struct lvmcache_info {
const struct format_type *fmt;
struct device *dev;
uint64_t device_size; /* Bytes */
+ uint32_t ext_version; /* Extension version */
uint32_t ext_flags; /* Extension flags */
uint32_t status;
};
@@ -2278,6 +2279,14 @@ void lvmcache_set_device_size(struct lvmcache_info *info, uint64_t size) {
struct device *lvmcache_device(struct lvmcache_info *info) {
return info->dev;
}
+void lvmcache_set_ext_version(struct lvmcache_info *info, uint32_t version)
+{
+ info->ext_version = version;
+}
+
+uint32_t lvmcache_ext_version(struct lvmcache_info *info) {
+ return info->ext_version;
+}
void lvmcache_set_ext_flags(struct lvmcache_info *info, uint32_t flags) {
info->ext_flags = flags;
diff --git a/lib/cache/lvmcache.h b/lib/cache/lvmcache.h
index 471530c..063a8d1 100644
--- a/lib/cache/lvmcache.h
+++ b/lib/cache/lvmcache.h
@@ -149,6 +149,8 @@ int lvmcache_add_mda(struct lvmcache_info *info, struct device *dev,
int lvmcache_add_da(struct lvmcache_info *info, uint64_t start, uint64_t size);
int lvmcache_add_ba(struct lvmcache_info *info, uint64_t start, uint64_t size);
+void lvmcache_set_ext_version(struct lvmcache_info *info, uint32_t version);
+uint32_t lvmcache_ext_version(struct lvmcache_info *info);
void lvmcache_set_ext_flags(struct lvmcache_info *info, uint32_t flags);
uint32_t lvmcache_ext_flags(struct lvmcache_info *info);
diff --git a/lib/cache/lvmetad.c b/lib/cache/lvmetad.c
index b07ba50..97120b0 100644
--- a/lib/cache/lvmetad.c
+++ b/lib/cache/lvmetad.c
@@ -296,6 +296,7 @@ static int _pv_populate_lvmcache(struct cmd_context *cmd,
uint64_t devsize = dm_config_find_int64(cn->child, "dev_size", 0),
label_sector = dm_config_find_int64(cn->child, "label_sector", 0);
uint32_t ext_flags = (uint32_t) dm_config_find_int64(cn->child, "ext_flags", 0);
+ uint32_t ext_version = (uint32_t) dm_config_find_int64(cn->child, "ext_version", 0);
if (!fmt && fmt_name)
fmt = get_format_by_name(cmd, fmt_name);
@@ -403,6 +404,7 @@ static int _pv_populate_lvmcache(struct cmd_context *cmd,
lvmcache_set_preferred_duplicates((const char *)&vgid);
lvmcache_set_ext_flags(info, ext_flags);
+ lvmcache_set_ext_version(info, ext_version);
return 1;
}
@@ -915,6 +917,7 @@ int lvmetad_pv_found(const struct id *pvid, struct device *dev, const struct for
"format = %s", fmt->name,
"label_sector = %"PRId64, (int64_t) label_sector,
"id = %s", uuid,
+ "ext_version = %"PRId64, (int64_t) lvmcache_ext_version(info),
"ext_flags = %"PRId64, (int64_t) lvmcache_ext_flags(info),
NULL))
{
diff --git a/lib/format_text/format-text.c b/lib/format_text/format-text.c
index 3d8329f..311f86c 100644
--- a/lib/format_text/format-text.c
+++ b/lib/format_text/format-text.c
@@ -1328,6 +1328,7 @@ static void _set_ext_flags(struct physical_volume *pv, struct lvmcache_info *inf
else
ext_flags |= PV_EXT_USED;
+ lvmcache_set_ext_version(info, PV_HEADER_EXTENSION_VSN);
lvmcache_set_ext_flags(info, ext_flags);
}
diff --git a/lib/format_text/layout.h b/lib/format_text/layout.h
index 64fc0e1..3f17be3 100644
--- a/lib/format_text/layout.h
+++ b/lib/format_text/layout.h
@@ -23,7 +23,12 @@
/* disk_locn and data_area_list are defined in format-text.h */
-#define PV_HEADER_EXTENSION_VSN 1
+/*
+ * PV header extension versions:
+ * - version 1: bootloader area support
+ * - version 2: PV_EXT_USED flag support
+ */
+#define PV_HEADER_EXTENSION_VSN 2
struct pv_header_extension {
uint32_t version;
diff --git a/lib/format_text/text_label.c b/lib/format_text/text_label.c
index 1bdff02..022384e 100644
--- a/lib/format_text/text_label.c
+++ b/lib/format_text/text_label.c
@@ -421,6 +421,9 @@ static int _text_read(struct labeller *l, struct device *dev, void *buf,
log_debug_metadata("%s: PV header extension version %" PRIu32 " found",
dev_name(dev), ext_version);
+ /* Extension version */
+ lvmcache_set_ext_version(info, xlate32(pvhdr_ext->version));
+
/* Extension flags */
lvmcache_set_ext_flags(info, xlate32(pvhdr_ext->flags));
8 years, 8 months
dev-prajnoha-pv-ext-flag-used - 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=530efe587f0a0c...
Commit: 530efe587f0a0cbb9def7bda7f4b312b07ffde92
Parent: 812e0828e4829cb47e0a339b850371c0b10a1261
Author: Peter Rajnoha <prajnoha(a)redhat.com>
AuthorDate: Wed Mar 11 16:18:42 2015 +0100
Committer: Peter Rajnoha <prajnoha(a)redhat.com>
CommitterDate: Fri Aug 21 11:15:53 2015 +0200
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 8bc4302..a147d40 100644
--- a/lib/metadata/metadata.c
+++ b/lib/metadata/metadata.c
@@ -3294,11 +3294,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;
@@ -3318,13 +3371,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;
@@ -3356,8 +3416,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);
@@ -3369,6 +3432,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;
}
@@ -3480,14 +3544,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;
@@ -3561,8 +3617,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) {
@@ -4047,8 +4102,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;
}
@@ -5023,8 +5082,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 01146a4..86e3820 100644
--- a/tools/toollib.c
+++ b/tools/toollib.c
@@ -250,7 +250,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, 8 months
dev-prajnoha-pv-ext-flag-used - 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=812e0828e4829c...
Commit: 812e0828e4829cb47e0a339b850371c0b10a1261
Parent: c8a30abbfa8ba51eb83b49f33bff3cbbac96d3a1
Author: Peter Rajnoha <prajnoha(a)redhat.com>
AuthorDate: Tue Mar 10 16:10:16 2015 +0100
Committer: Peter Rajnoha <prajnoha(a)redhat.com>
CommitterDate: Fri Aug 21 11:15:53 2015 +0200
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 | 16 ++++++++++++++++
lib/report/values.h | 1 +
4 files changed, 20 insertions(+), 0 deletions(-)
diff --git a/lib/report/columns.h b/lib/report/columns.h
index fe9aad9..b29a93b 100644
--- a/lib/report/columns.h
+++ b/lib/report/columns.h
@@ -113,6 +113,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, BIN, "PInUse", type, 6, pvinuse, pv_in_use, "Set if PV is used.", 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 e38359b..76c7158 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 a17af32..4b80eaf 100644
--- a/lib/report/report.c
+++ b/lib/report/report.c
@@ -2301,6 +2301,22 @@ static int _pvmdasize_disp(struct dm_report *rh, struct dm_pool *mem,
return _size64_disp(rh, mem, field, &min_mda_size, 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 label *label = (const struct label *) data;
+ struct lvmcache_info *info = label->info;
+ uint32_t ext_flags;
+
+ if (info) {
+ ext_flags = lvmcache_ext_flags(info);
+ return _binary_disp(rh, mem, field, ext_flags & PV_EXT_USED, GET_FIRST_RESERVED_NAME(pv_in_use_y), private);
+ }
+
+ return _binary_undef_disp(rh, mem, field, private);
+}
+
static int _vgmdasize_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 728760c..ac01934 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, 8 months
dev-prajnoha-pv-ext-flag-used - 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=c8a30abbfa8ba5...
Commit: c8a30abbfa8ba51eb83b49f33bff3cbbac96d3a1
Parent: e9a46414c55af0220848da2eb0789a40ddf18216
Author: Peter Rajnoha <prajnoha(a)redhat.com>
AuthorDate: Thu Mar 12 15:18:52 2015 +0100
Committer: Peter Rajnoha <prajnoha(a)redhat.com>
CommitterDate: Fri Aug 21 11:15:53 2015 +0200
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 2c467f5..8bc4302 100644
--- a/lib/metadata/metadata.c
+++ b/lib/metadata/metadata.c
@@ -1604,32 +1604,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, 8 months
dev-prajnoha-pv-ext-flag-used - 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=e9a46414c55af0...
Commit: e9a46414c55af0220848da2eb0789a40ddf18216
Parent: 384e46fb762e843a145616ff1558e6b7b70a0495
Author: Peter Rajnoha <prajnoha(a)redhat.com>
AuthorDate: Tue Mar 10 14:19:20 2015 +0100
Committer: Peter Rajnoha <prajnoha(a)redhat.com>
CommitterDate: Fri Aug 21 11:15:53 2015 +0200
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 55f5840..2c467f5 100644
--- a/lib/metadata/metadata.c
+++ b/lib/metadata/metadata.c
@@ -294,6 +294,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);
return 1;
@@ -1639,7 +1640,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;
}
@@ -1758,6 +1763,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 46cf169..55c1cfd 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, 8 months
dev-prajnoha-pv-ext-flag-used - 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=384e46fb762e84...
Commit: 384e46fb762e843a145616ff1558e6b7b70a0495
Parent: 82a1c6ccc141de84f3450d97f8049c5f2d08863c
Author: Peter Rajnoha <prajnoha(a)redhat.com>
AuthorDate: Tue Mar 10 11:25:14 2015 +0100
Committer: Peter Rajnoha <prajnoha(a)redhat.com>
CommitterDate: Fri Aug 21 11:15:53 2015 +0200
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
Can't initialize physical volume "/dev/sda" that is marked as used without -ff.
$ pvchange -u /dev/sda
Can't change PV "/dev/sda" that is marked as used 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 used.
(If you are certain you need pvremove, then confirm by using --force twice.)
$ vgcreate vg /dev/sda
Physical volume '/dev/sda' is marked as used.
Unable to add physical volume '/dev/sda' to volume group 'vg'.
---
lib/metadata/metadata.c | 37 +++++++++++++++++++++++++++++++++----
lib/metadata/pv_manip.c | 18 ++++++++++++++++--
tools/pvchange.c | 23 +++++++++++++++++++----
3 files changed, 68 insertions(+), 10 deletions(-)
diff --git a/lib/metadata/metadata.c b/lib/metadata/metadata.c
index cf54f58..55f5840 100644
--- a/lib/metadata/metadata.c
+++ b/lib/metadata/metadata.c
@@ -185,6 +185,8 @@ 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)));
+ struct lvmcache_info *info;
+ uint32_t ext_flags;
log_verbose("Adding physical volume '%s' to volume group '%s'",
pv_name, vg->name);
@@ -198,6 +200,17 @@ 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 (!(info = lvmcache_info_from_pvid((const char *)&pv->id, 0))) {
+ log_error("Failed to find cached info for PV %s.", pv_name);
+ return 0;
+ }
+
+ ext_flags = lvmcache_ext_flags(info);
+ if (ext_flags & PV_EXT_USED) {
+ log_error("Physical volume '%s' is marked as used.", pv_name);
+ return 0;
+ }
}
if (pv->fmt != fid->fmt) {
@@ -1421,6 +1434,8 @@ static int _pvcreate_check(struct cmd_context *cmd, const char *name,
struct pvcreate_params *pp, int *wiped)
{
struct physical_volume *pv;
+ struct lvmcache_info *info;
+ uint32_t ext_flags;
struct device *dev;
int r = 0;
int scan_needed = 0;
@@ -1435,10 +1450,24 @@ 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 (!(info = lvmcache_info_from_pvid((const char *)&pv->id, 0))) {
+ log_error("Failed to find cached info for PV %s.", name);
+ goto out;
+ }
+
+ ext_flags = lvmcache_ext_flags(info);
+ if (ext_flags & PV_EXT_USED && pp->force != DONT_PROMPT_OVERRIDE) {
+ log_error("Can't initialize physical volume \"%s\" that is marked as used "
+ "without -ff.", name);
+ goto out;
+ }
}
/* prompt */
diff --git a/lib/metadata/pv_manip.c b/lib/metadata/pv_manip.c
index ce7f661..92e48f8 100644
--- a/lib/metadata/pv_manip.c
+++ b/lib/metadata/pv_manip.c
@@ -697,10 +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 lvmcache_info *info;
+ uint32_t ext_flags;
struct physical_volume *pv = NULL;
int r = 0;
@@ -731,6 +733,18 @@ static int pvremove_check(struct cmd_context *cmd, const char *name,
}
if (is_orphan(pv)) {
+ if (!(info = lvmcache_info_from_pvid((const char *)&pv->id, 0))) {
+ log_error("Failed to find cached info for PV %s.", name);
+ goto out;
+ }
+
+ ext_flags = lvmcache_ext_flags(info);
+ if (ext_flags & PV_EXT_USED && force_count < 2) {
+ log_error("PV %s is marked as used.", name);
+ log_error("%s", pvremove_force_hint_msg);
+ goto out;
+ }
+
r = 1;
goto out;
}
@@ -738,7 +752,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 91e93c1..409f759 100644
--- a/tools/pvchange.c
+++ b/tools/pvchange.c
@@ -25,6 +25,8 @@ static int _pvchange_single(struct cmd_context *cmd, struct volume_group *vg,
{
struct pvchange_params *params = (struct pvchange_params *) handle->custom_handle;
const char *pv_name = pv_dev_name(pv);
+ struct lvmcache_info *info;
+ uint32_t ext_flags;
char uuid[64] __attribute__((aligned(8)));
unsigned done = 0;
@@ -48,10 +50,23 @@ 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 (!(info = lvmcache_info_from_pvid((const char *) &pv->id,0))) {
+ log_error("Failed to find cached info for PV %s.", pv_name);
+ goto bad;
+ }
+
+ ext_flags = lvmcache_ext_flags(info);
+ if (ext_flags & PV_EXT_USED && (arg_count(cmd, force_ARG) != DONT_PROMPT_OVERRIDE)) {
+ log_error("Can't change PV \"%s\" that is marked as used without -ff.", pv_name);
+ goto bad;
+ }
}
if (arg_count(cmd, allocatable_ARG)) {
8 years, 8 months
dev-prajnoha-pv-ext-flag-used - metadata: schedule PV for header rewrite if adding a PV to VG or restoring VG
by Peter Rajnoha
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=82a1c6ccc141de...
Commit: 82a1c6ccc141de84f3450d97f8049c5f2d08863c
Parent: 7fcc36bf94943ab9b5dc5b295c925d790f1fb081
Author: Peter Rajnoha <prajnoha(a)redhat.com>
AuthorDate: Thu Mar 12 14:49:10 2015 +0100
Committer: Peter Rajnoha <prajnoha(a)redhat.com>
CommitterDate: Fri Aug 21 11:15:53 2015 +0200
metadata: schedule PV for header rewrite if adding a PV to VG or restoring VG
When adding PV to VG, we need to rewrite PV header as there's a flip
in PV_EXT_USED flag. The same applies if we're restoring VG from backup.
---
lib/format_text/archiver.c | 8 ++++++++
lib/metadata/metadata.c | 14 ++++++--------
2 files changed, 14 insertions(+), 8 deletions(-)
diff --git a/lib/format_text/archiver.c b/lib/format_text/archiver.c
index e3d3d57..fa7ce88 100644
--- a/lib/format_text/archiver.c
+++ b/lib/format_text/archiver.c
@@ -325,6 +325,7 @@ int backup_restore_vg(struct cmd_context *cmd, struct volume_group *vg, int drop
struct pv_list *pvl;
struct format_instance *fid;
struct format_instance_ctx fic;
+ struct pv_to_write *pvw;
uint32_t tmp;
/*
@@ -353,6 +354,13 @@ 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 (!(pvw = dm_pool_zalloc(vg->vgmem, sizeof(*pvw)))) {
+ log_error("pv_to_write allocation for '%s' failed", pv_dev_name(pvl->pv));
+ return 0;
+ }
+ pvw->pv = pvl->pv;
+ dm_list_add(&vg->pvs_to_write, &pvw->list);
+
tmp = vg->extent_size;
vg->extent_size = 0;
if (!vg->fid->fmt->ops->pv_setup(vg->fid->fmt, pvl->pv, vg)) {
diff --git a/lib/metadata/metadata.c b/lib/metadata/metadata.c
index 4efd47a..cf54f58 100644
--- a/lib/metadata/metadata.c
+++ b/lib/metadata/metadata.c
@@ -275,15 +275,13 @@ int add_pv_to_vg(struct volume_group *vg, const char *pv_name,
break;
}
- if (pv->status & UNLABELLED_PV) {
- if (!(pvw = dm_pool_zalloc(mem, sizeof(*pvw)))) {
- log_error("pv_to_write allocation for '%s' failed", pv_name);
- return 0;
- }
- pvw->pv = pv;
- pvw->pp = new_pv ? pp : NULL;
- dm_list_add(&vg->pvs_to_write, &pvw->list);
+ if (!(pvw = dm_pool_zalloc(mem, sizeof(*pvw)))) {
+ log_error("pv_to_write allocation for '%s' failed", pv_name);
+ return 0;
}
+ pvw->pv = pv;
+ pvw->pp = new_pv ? pp : NULL;
+ dm_list_add(&vg->pvs_to_write, &pvw->list);
return 1;
}
8 years, 8 months