Search is temporarily disabled.
See ticket for more info.
Thread View
j
: Next unread message
k
: Previous unread message
j a
: Jump to all threads
j l
: Jump to MailingList overview
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=c7b9f0ab424136b6…
Commit: c7b9f0ab424136b686cd08ff7416078e7c3728c3
Parent: 0dc3684b872fa1f225e06deeb0136d1ef66d4c1e
Author: Alasdair G Kergon <agk(a)redhat.com>
AuthorDate: Fri Aug 1 00:35:43 2014 +0100
Committer: Alasdair G Kergon <agk(a)redhat.com>
CommitterDate: Fri Aug 1 00:35:43 2014 +0100
lvresize: Allow approximation with +%FREE.
Make lvresize -l+%FREE support approximate allocation.
Move existing "Reducing/Extending' message to verbose level
and change it to say 'up to' if approximate allocation is being used.
Replace it with a new message that gives the actual old and new size or
says 'unchanged'.
---
WHATS_NEW | 2 ++
lib/metadata/lv_manip.c | 22 ++++++++++++++++++----
2 files changed, 20 insertions(+), 4 deletions(-)
diff --git a/WHATS_NEW b/WHATS_NEW
index 03cf668..a1099fe 100644
--- a/WHATS_NEW
+++ b/WHATS_NEW
@@ -1,5 +1,7 @@
Version 2.02.109 -
=================================
+ Display actual size changed when resizing LV.
+ Allow approximate allocation with +%FREE in lvextend.
Remove possible spurious "not found" message on PV create before wiping.
Handle upgrade from 2.02.105 when an LV now gaining a uuid suffix is active.
diff --git a/lib/metadata/lv_manip.c b/lib/metadata/lv_manip.c
index 0d39166..3e1f9e9 100644
--- a/lib/metadata/lv_manip.c
+++ b/lib/metadata/lv_manip.c
@@ -4155,6 +4155,8 @@ static int _lvresize_adjust_extents(struct cmd_context *cmd, struct logical_volu
if (lp->sign == SIGN_NONE && (lp->percent != PERCENT_LV && lp->percent != PERCENT_ORIGIN))
lp->approx_alloc = 1;
/* FIXME Adjust for parallel areas here before processing relative allocations */
+ if (lp->sign == SIGN_PLUS && lp->percent == PERCENT_FREE)
+ lp->approx_alloc = 1;
}
if (lp->sign == SIGN_PLUS) {
@@ -4456,6 +4458,7 @@ static struct logical_volume *_lvresize_volume(struct cmd_context *cmd,
struct volume_group *vg = lv->vg;
struct logical_volume *lock_lv = NULL;
struct lv_segment *seg = NULL;
+ uint32_t old_extents;
int status;
alloc_policy_t alloc;
@@ -4500,10 +4503,11 @@ static struct logical_volume *_lvresize_volume(struct cmd_context *cmd,
if (!archive(vg))
return_NULL;
- log_print_unless_silent("%sing logical volume %s to %s",
- (lp->resize == LV_REDUCE) ? "Reduc" : "Extend",
- lv->name,
- display_size(cmd, (uint64_t) lp->extents * vg->extent_size));
+ old_extents = lv->le_count;
+ log_verbose("%sing logical volume %s to %s%s",
+ (lp->resize == LV_REDUCE) ? "Reduc" : "Extend",
+ display_lvname(lv), lp->approx_alloc ? "up to " : "",
+ display_size(cmd, (uint64_t) lp->extents * vg->extent_size));
if (lp->resize == LV_REDUCE) {
if (!lv_reduce(lv, lv->le_count - lp->extents))
@@ -4516,6 +4520,16 @@ static struct logical_volume *_lvresize_volume(struct cmd_context *cmd,
pvh, alloc, lp->approx_alloc))
return_NULL;
+ if (old_extents == lv->le_count)
+ log_print_unless_silent("Size of logical volume %s unchanged from %s.",
+ display_lvname(lv),
+ display_size(cmd, (uint64_t) old_extents * vg->extent_size));
+ else
+ log_print_unless_silent("Size of logical volume %s changed from %s to %s.",
+ display_lvname(lv),
+ display_size(cmd, (uint64_t) old_extents * vg->extent_size),
+ display_size(cmd, (uint64_t) lv->le_count * vg->extent_size));
+
if (lock_lv) {
/* Update thin pool segment from the layered LV */
seg->area_len = lv->le_count;
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=0dc3684b872fa1f2…
Commit: 0dc3684b872fa1f225e06deeb0136d1ef66d4c1e
Parent: ef8599798069b2c49aa1c296e6f8b050458b6aeb
Author: Marian Csontos <mcsontos(a)redhat.com>
AuthorDate: Thu Jul 31 22:56:19 2014 +0200
Committer: Marian Csontos <mcsontos(a)redhat.com>
CommitterDate: Thu Jul 31 22:56:19 2014 +0200
test: Skip lvextend-thin when thin not available
---
test/shell/lvextend-thin.sh | 2 ++
1 files changed, 2 insertions(+), 0 deletions(-)
diff --git a/test/shell/lvextend-thin.sh b/test/shell/lvextend-thin.sh
index 0d5a2f5..1a0b440 100644
--- a/test/shell/lvextend-thin.sh
+++ b/test/shell/lvextend-thin.sh
@@ -11,6 +11,8 @@
. lib/inittest
+aux have_thin 1 0 0 || skip
+
aux prepare_vg 3
lvcreate -i2 -l2 -T $vg/pool2
lvextend -l+2 $vg/pool2 $dev2 $dev3
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=ef8599798069b2c4…
Commit: ef8599798069b2c49aa1c296e6f8b050458b6aeb
Parent: 7cff640d9ae20a94647610e5adbb4151b7652fe5
Author: Peter Rajnoha <prajnoha(a)redhat.com>
AuthorDate: Thu Jul 31 09:30:25 2014 +0200
Committer: Peter Rajnoha <prajnoha(a)redhat.com>
CommitterDate: Thu Jul 31 10:03:30 2014 +0200
metadata: remove spurious "Physical volume <dev_name> not found"
This is addendum to commit 2e82a070f3c9224da5c9f383d47e75a1715586cf
which fixed these spurious messages that appeared after commit
651d5093edde3e0ebee9d75be1c9834efc152d91 ("avoid pv_read in
find_pv_by_name").
There was one more "not found" message issued in case the device
could not be found in device cache (commit 2e82a07 fixed this only
for PV lookup itself). But if we "allow_unformatted" for
find_pv_by_name, we should not issue this message even in case
the device can't be found in dev cache as we just need to know
whether there's a PV or not for the code to decide on next steps
and we don't want to issue any messages if either device itself
is not found or PV is not found.
For example, when we were creating a new PV (and so allow_unformatted = 1)
and the device had a signature on it which caused it to be filtered
by device filter (e.g. MD signature if md filtering is enabled),
or it was part of some other subsystem (e.g. multipath), this message
was issued on find_pv_by_name call which was misleading.
Also, remove misleading "stack" call in case find_pv_by_name
returns NULL in pvcreate_check - any error state is reported
later by pvcreate_check code so no need to "stack" here.
There's one more and proper check to issue "not found" message if
the device can't be found in device cache within pvcreate_check fn
so this situation is still covered properly later in the code.
Before this patch (/dev/sda contains MD signature and is therefore filtered):
$ pvcreate /dev/sda
Physical volume /dev/sda not found
WARNING: linux_raid_member signature detected on /dev/sda at offset 4096. Wipe it? [y/n]:
With this patch applied:
$ pvcreate /dev/sda
WARNING: linux_raid_member signature detected on /dev/sda at offset 4096. Wipe it? [y/n]:
Non-existent devices are still caught properly:
$ pvcreate /dev/sdx
Device /dev/sdx not found (or ignored by filtering).
---
WHATS_NEW | 1 +
lib/metadata/metadata.c | 7 ++++---
2 files changed, 5 insertions(+), 3 deletions(-)
diff --git a/WHATS_NEW b/WHATS_NEW
index ace357b..03cf668 100644
--- a/WHATS_NEW
+++ b/WHATS_NEW
@@ -1,5 +1,6 @@
Version 2.02.109 -
=================================
+ Remove possible spurious "not found" message on PV create before wiping.
Handle upgrade from 2.02.105 when an LV now gaining a uuid suffix is active.
Version 2.02.108 - 23rd July 2014
diff --git a/lib/metadata/metadata.c b/lib/metadata/metadata.c
index 0832750..39fa45f 100644
--- a/lib/metadata/metadata.c
+++ b/lib/metadata/metadata.c
@@ -685,8 +685,8 @@ static int vg_extend_single_pv(struct volume_group *vg, char *pv_name,
{
struct physical_volume *pv;
- if (!(pv = find_pv_by_name(vg->cmd, pv_name, 1, 1)))
- stack;
+ pv = find_pv_by_name(vg->cmd, pv_name, 1, 1);
+
if (!pv && !pp) {
log_error("%s not identified as an existing "
"physical volume", pv_name);
@@ -1858,7 +1858,8 @@ struct physical_volume *find_pv_by_name(struct cmd_context *cmd,
lvmcache_seed_infos_from_lvmetad(cmd);
if (!(dev = dev_cache_get(pv_name, cmd->filter))) {
- log_error("Physical volume %s not found", pv_name);
+ if (!allow_unformatted)
+ log_error("Physical volume %s not found", pv_name);
return_NULL;
}
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=7cff640d9ae20a94…
Commit: 7cff640d9ae20a94647610e5adbb4151b7652fe5
Parent: c4484d90503c4e5c2bc945461da50a6b85c5d7e7
Author: Alasdair G Kergon <agk(a)redhat.com>
AuthorDate: Wed Jul 30 21:55:11 2014 +0100
Committer: Alasdair G Kergon <agk(a)redhat.com>
CommitterDate: Wed Jul 30 21:55:11 2014 +0100
activation: Fix upgrades using uuid suffixes.
2.02.106 added suffixes to some LV uuids in the kernel.
If any of these LVs is activated with 2.02.105 or earlier,
and then a later version is used, the LVs appear invisible and
activation commands fail.
The code now has to check the kernel for both old and new uuids.
---
WHATS_NEW | 1 +
WHATS_NEW_DM | 1 +
lib/activate/dev_manager.c | 29 ++++++++++++++++++++++++++++-
lib/misc/lvm-string.c | 1 +
libdm/libdevmapper.h | 5 +++++
libdm/libdm-deptree.c | 41 +++++++++++++++++++++++++++++++++++++++--
6 files changed, 75 insertions(+), 3 deletions(-)
diff --git a/WHATS_NEW b/WHATS_NEW
index 64b174b..ace357b 100644
--- a/WHATS_NEW
+++ b/WHATS_NEW
@@ -1,5 +1,6 @@
Version 2.02.109 -
=================================
+ Handle upgrade from 2.02.105 when an LV now gaining a uuid suffix is active.
Version 2.02.108 - 23rd July 2014
=================================
diff --git a/WHATS_NEW_DM b/WHATS_NEW_DM
index ad25215..b663bfc 100644
--- a/WHATS_NEW_DM
+++ b/WHATS_NEW_DM
@@ -1,5 +1,6 @@
Version 1.02.88 -
================================
+ Add dm_tree_set_optional_uuid_suffixes to handle upgrades.
Version 1.02.87 - 23rd July 2014
================================
diff --git a/lib/activate/dev_manager.c b/lib/activate/dev_manager.c
index d5fe620..2cf0b65 100644
--- a/lib/activate/dev_manager.c
+++ b/lib/activate/dev_manager.c
@@ -41,6 +41,9 @@ typedef enum {
CLEAN
} action_t;
+/* This list must match lib/misc/lvm-string.c:build_dm_uuid(). */
+const char *uuid_suffix_list[] = { "pool", "cdata", "cmeta", "tdata", "tmeta", NULL};
+
struct dev_manager {
struct dm_pool *mem;
@@ -482,11 +485,31 @@ static int _info(const char *dlid, int with_open_count, int with_read_ahead,
struct dm_info *info, uint32_t *read_ahead)
{
int r = 0;
+ char old_style_dlid[sizeof(UUID_PREFIX) + 2 * ID_LEN];
+ const char *suffix, *suffix_position;
+ unsigned i = 0;
+ /* Check for dlid */
if ((r = _info_run(NULL, dlid, info, read_ahead, 0, with_open_count,
with_read_ahead, 0, 0)) && info->exists)
return 1;
- else if ((r = _info_run(NULL, dlid + sizeof(UUID_PREFIX) - 1, info,
+
+ /* Check for original version of dlid before the suffixes got added in 2.02.106 */
+ if ((suffix_position = rindex(dlid, '-'))) {
+ while ((suffix = uuid_suffix_list[i++])) {
+ if (strcmp(suffix_position + 1, suffix))
+ continue;
+
+ (void) strncpy(old_style_dlid, dlid, sizeof(old_style_dlid));
+ old_style_dlid[sizeof(old_style_dlid) - 1] = '\0';
+ if ((r = _info_run(NULL, old_style_dlid, info, read_ahead, 0, with_open_count,
+ with_read_ahead, 0, 0)) && info->exists)
+ return 1;
+ }
+ }
+
+ /* Check for dlid before UUID_PREFIX was added */
+ if ((r = _info_run(NULL, dlid + sizeof(UUID_PREFIX) - 1, info,
read_ahead, 0, with_open_count,
with_read_ahead, 0, 0)) && info->exists)
return 1;
@@ -2011,6 +2034,8 @@ static struct dm_tree *_create_partial_dtree(struct dev_manager *dm, struct logi
return NULL;
}
+ dm_tree_set_optional_uuid_suffixes(dtree, &uuid_suffix_list[0]);
+
if (!_add_lv_to_dtree(dm, dtree, lv, (lv_is_origin(lv) || lv_is_thin_volume(lv)) ? origin_only : 0))
goto_bad;
@@ -3001,6 +3026,8 @@ int dev_manager_device_uses_vg(struct device *dev,
return r;
}
+ dm_tree_set_optional_uuid_suffixes(dtree, &uuid_suffix_list[0]);
+
if (!dm_tree_add_dev(dtree, (uint32_t) MAJOR(dev->dev), (uint32_t) MINOR(dev->dev))) {
log_error("Failed to add device %s (%" PRIu32 ":%" PRIu32") to dtree",
dev_name(dev), (uint32_t) MAJOR(dev->dev), (uint32_t) MINOR(dev->dev));
diff --git a/lib/misc/lvm-string.c b/lib/misc/lvm-string.c
index 5858638..84c8708 100644
--- a/lib/misc/lvm-string.c
+++ b/lib/misc/lvm-string.c
@@ -185,6 +185,7 @@ char *build_dm_uuid(struct dm_pool *mem, const struct logical_volume *lv,
* an internal LV they should not scan.
* Should also make internal detection simpler.
*/
+ /* Suffixes used here MUST match lib/activate/dev_manager.c */
layer = lv_is_cache_pool_data(lv) ? "cdata" :
lv_is_cache_pool_metadata(lv) ? "cmeta" :
// FIXME: dm-tree needs fixes for mirrors/raids
diff --git a/libdm/libdevmapper.h b/libdm/libdevmapper.h
index dc3da78..e37ee39 100644
--- a/libdm/libdevmapper.h
+++ b/libdm/libdevmapper.h
@@ -526,6 +526,11 @@ struct dm_tree *dm_tree_create(void);
void dm_tree_free(struct dm_tree *tree);
/*
+ * List of suffixes to be ignored when matching uuids against existing devices.
+ */
+void dm_tree_set_optional_uuid_suffixes(struct dm_tree *dtree, const char **optional_uuid_suffixes);
+
+/*
* Add nodes to the tree for a given device and all the devices it uses.
*/
int dm_tree_add_dev(struct dm_tree *tree, uint32_t major, uint32_t minor);
diff --git a/libdm/libdm-deptree.c b/libdm/libdm-deptree.c
index f34c40f..55f061a 100644
--- a/libdm/libdm-deptree.c
+++ b/libdm/libdm-deptree.c
@@ -16,6 +16,7 @@
#include "libdm-targets.h"
#include "libdm-common.h"
#include "kdev_t.h"
+#include "dm-ioctl.h"
#include <stdarg.h>
#include <sys/param.h>
@@ -300,6 +301,7 @@ struct dm_tree {
int no_flush; /* 1 sets noflush (mirrors/multipath) */
int retry_remove; /* 1 retries remove if not successful */
uint32_t cookie;
+ const char **optional_uuid_suffixes; /* uuid suffixes ignored when matching */
};
/*
@@ -325,6 +327,7 @@ struct dm_tree *dm_tree_create(void)
dtree->skip_lockfs = 0;
dtree->no_flush = 0;
dtree->mem = dmem;
+ dtree->optional_uuid_suffixes = NULL;
if (!(dtree->devs = dm_hash_create(8))) {
log_error("dtree hash creation failed");
@@ -539,23 +542,57 @@ static struct dm_tree_node *_find_dm_tree_node(struct dm_tree *dtree,
sizeof(dev));
}
+void dm_tree_set_optional_uuid_suffixes(struct dm_tree *dtree, const char **optional_uuid_suffixes)
+{
+ dtree->optional_uuid_suffixes = optional_uuid_suffixes;
+}
+
static struct dm_tree_node *_find_dm_tree_node_by_uuid(struct dm_tree *dtree,
const char *uuid)
{
struct dm_tree_node *node;
const char *default_uuid_prefix;
size_t default_uuid_prefix_len;
+ const char *suffix, *suffix_position;
+ char uuid_without_suffix[DM_UUID_LEN];
+ unsigned i = 0;
+ const char **suffix_list = dtree->optional_uuid_suffixes;
- if ((node = dm_hash_lookup(dtree->uuids, uuid)))
+ if ((node = dm_hash_lookup(dtree->uuids, uuid))) {
+ log_debug("Matched uuid %s in deptree.", uuid);
return node;
+ }
default_uuid_prefix = dm_uuid_prefix();
default_uuid_prefix_len = strlen(default_uuid_prefix);
+ if (suffix_list && (suffix_position = rindex(uuid, '-'))) {
+ while ((suffix = suffix_list[i++])) {
+ if (strcmp(suffix_position + 1, suffix))
+ continue;
+
+ (void) strncpy(uuid_without_suffix, uuid, sizeof(uuid_without_suffix));
+ uuid_without_suffix[suffix_position - uuid] = '\0';
+
+ if ((node = dm_hash_lookup(dtree->uuids, uuid_without_suffix))) {
+ log_debug("Matched uuid %s (missing suffix -%s) in deptree.", uuid_without_suffix, suffix);
+ return node;
+ }
+
+ break;
+ };
+ }
+
if (strncmp(uuid, default_uuid_prefix, default_uuid_prefix_len))
return NULL;
- return dm_hash_lookup(dtree->uuids, uuid + default_uuid_prefix_len);
+ if ((node = dm_hash_lookup(dtree->uuids, uuid + default_uuid_prefix_len))) {
+ log_debug("Matched uuid %s (missing prefix) in deptree.", uuid + default_uuid_prefix_len);
+ return node;
+ }
+
+ log_debug("Not matched uuid %s in deptree.", uuid + default_uuid_prefix_len);
+ return NULL;
}
void dm_tree_node_set_udev_flags(struct dm_tree_node *dnode, uint16_t udev_flags)
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=c4484d90503c4e5c…
Commit: c4484d90503c4e5c2bc945461da50a6b85c5d7e7
Parent: 321bed713727a81d743b42c98c1fd91c18ecddb5
Author: Petr Rockai <prockai(a)redhat.com>
AuthorDate: Wed Jul 30 16:15:16 2014 +0200
Committer: Petr Rockai <prockai(a)redhat.com>
CommitterDate: Wed Jul 30 16:17:29 2014 +0200
test: Add a test for lvextend -l+100%FREE of a striped thin pool.
---
test/shell/lvextend-thin.sh | 17 +++++++++++++++++
1 files changed, 17 insertions(+), 0 deletions(-)
diff --git a/test/shell/lvextend-thin.sh b/test/shell/lvextend-thin.sh
new file mode 100644
index 0000000..0d5a2f5
--- /dev/null
+++ b/test/shell/lvextend-thin.sh
@@ -0,0 +1,17 @@
+#!/bin/sh
+# Copyright (C) 2014 Red Hat, Inc. All rights reserved.
+#
+# This copyrighted material is made available to anyone wishing to use,
+# modify, copy, or redistribute it subject to the terms and conditions
+# of the GNU General Public License v.2.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software Foundation,
+# Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+. lib/inittest
+
+aux prepare_vg 3
+lvcreate -i2 -l2 -T $vg/pool2
+lvextend -l+2 $vg/pool2 $dev2 $dev3
+should lvextend -l+100%FREE $vg/pool2
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=321bed713727a81d…
Commit: 321bed713727a81d743b42c98c1fd91c18ecddb5
Parent: 52217f6ebd3dee25808344a9425fc085427075e4
Author: Alasdair G Kergon <agk(a)redhat.com>
AuthorDate: Wed Jul 23 16:23:52 2014 +0100
Committer: Alasdair G Kergon <agk(a)redhat.com>
CommitterDate: Wed Jul 23 16:23:52 2014 +0100
post-release
---
VERSION | 2 +-
VERSION_DM | 2 +-
WHATS_NEW | 3 +++
WHATS_NEW_DM | 3 +++
4 files changed, 8 insertions(+), 2 deletions(-)
diff --git a/VERSION b/VERSION
index fa96924..79c463f 100644
--- a/VERSION
+++ b/VERSION
@@ -1 +1 @@
-2.02.108(2)-git (2014-07-23)
+2.02.109(2)-git (2014-07-23)
diff --git a/VERSION_DM b/VERSION_DM
index 307f41d..a6ea805 100644
--- a/VERSION_DM
+++ b/VERSION_DM
@@ -1 +1 @@
-1.02.87-git (2014-07-23)
+1.02.88-git (2014-07-23)
diff --git a/WHATS_NEW b/WHATS_NEW
index e443834..64b174b 100644
--- a/WHATS_NEW
+++ b/WHATS_NEW
@@ -1,3 +1,6 @@
+Version 2.02.109 -
+=================================
+
Version 2.02.108 - 23rd July 2014
=================================
Add lvscan --cache which re-scans constituents of a particular LV.
diff --git a/WHATS_NEW_DM b/WHATS_NEW_DM
index a39099f..ad25215 100644
--- a/WHATS_NEW_DM
+++ b/WHATS_NEW_DM
@@ -1,3 +1,6 @@
+Version 1.02.88 -
+================================
+
Version 1.02.87 - 23rd July 2014
================================
Fix dm_report_field_string_list to handle delimiter with multiple chars.
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=52217f6ebd3dee25…
Commit: 52217f6ebd3dee25808344a9425fc085427075e4
Parent: 25fa725b05a83dd67e907802d1938bf983ffaad8
Author: Alasdair G Kergon <agk(a)redhat.com>
AuthorDate: Wed Jul 23 16:13:12 2014 +0100
Committer: Alasdair G Kergon <agk(a)redhat.com>
CommitterDate: Wed Jul 23 16:13:12 2014 +0100
raid: Fix partial activation logic for non-raid.
---
lib/activate/activate.c | 4 ++--
1 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/lib/activate/activate.c b/lib/activate/activate.c
index ebeaa79..1230c9a 100644
--- a/lib/activate/activate.c
+++ b/lib/activate/activate.c
@@ -2224,8 +2224,8 @@ static int _lv_activate(struct cmd_context *cmd, const char *lvid_s,
goto out;
}
- if ((!lv->vg->cmd->partial_activation) && (lv->status & PARTIAL_LV) && lv_is_raid_type(lv)) {
- if (!partial_raid_lv_supports_degraded_activation(lv)) {
+ if ((!lv->vg->cmd->partial_activation) && (lv->status & PARTIAL_LV)) {
+ if (!lv_is_raid_type(lv) || !partial_raid_lv_supports_degraded_activation(lv)) {
log_error("Refusing activation of partial LV %s. "
"Use '--activationmode partial' to override.",
display_lvname(lv));
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=25fa725b05a83dd6…
Commit: 25fa725b05a83dd67e907802d1938bf983ffaad8
Parent: 8d63d94d853b9675f9d3a86de8b34c68db5d5226
Author: Alasdair G Kergon <agk(a)redhat.com>
AuthorDate: Wed Jul 23 16:05:22 2014 +0100
Committer: Alasdair G Kergon <agk(a)redhat.com>
CommitterDate: Wed Jul 23 16:05:22 2014 +0100
pre-release
---
VERSION | 2 +-
VERSION_DM | 2 +-
WHATS_NEW | 2 +-
WHATS_NEW_DM | 2 +-
4 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/VERSION b/VERSION
index 4695aab..fa96924 100644
--- a/VERSION
+++ b/VERSION
@@ -1 +1 @@
-2.02.108(2)-git (2014-06-23)
+2.02.108(2)-git (2014-07-23)
diff --git a/VERSION_DM b/VERSION_DM
index 12a8c3d..307f41d 100644
--- a/VERSION_DM
+++ b/VERSION_DM
@@ -1 +1 @@
-1.02.87-git (2014-06-23)
+1.02.87-git (2014-07-23)
diff --git a/WHATS_NEW b/WHATS_NEW
index 3595517..e443834 100644
--- a/WHATS_NEW
+++ b/WHATS_NEW
@@ -1,4 +1,4 @@
-Version 2.02.108 -
+Version 2.02.108 - 23rd July 2014
=================================
Add lvscan --cache which re-scans constituents of a particular LV.
Make dmeventd's RAID plugin re-scan failed PVs when lvmetad is in use.
diff --git a/WHATS_NEW_DM b/WHATS_NEW_DM
index ab94bc4..a39099f 100644
--- a/WHATS_NEW_DM
+++ b/WHATS_NEW_DM
@@ -1,4 +1,4 @@
-Version 1.02.87 -
+Version 1.02.87 - 23rd July 2014
================================
Fix dm_report_field_string_list to handle delimiter with multiple chars.
Add dm_report_field_reserved_value for per-field reserved value definition.
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=8d63d94d853b9675…
Commit: 8d63d94d853b9675f9d3a86de8b34c68db5d5226
Parent: 22be7c441784fd89cf76cb6ed56fd50da126864d
Author: Zdenek Kabelac <zkabelac(a)redhat.com>
AuthorDate: Wed Jul 23 00:29:32 2014 +0200
Committer: Zdenek Kabelac <zkabelac(a)redhat.com>
CommitterDate: Wed Jul 23 00:29:32 2014 +0200
tests: still unusable kernel
---
test/lib/aux.sh | 1 +
1 files changed, 1 insertions(+), 0 deletions(-)
diff --git a/test/lib/aux.sh b/test/lib/aux.sh
index 7b96ad4..dcc86ed 100644
--- a/test/lib/aux.sh
+++ b/test/lib/aux.sh
@@ -736,6 +736,7 @@ raid456_replace_works() {
3.13.*.fc20.i686*|3.13.*.fc20.x86_64) return 1 ;;
3.14.*.fc21.i686*|3.14.*.fc21.x86_64) return 1 ;;
3.15.*rc6*.fc21.i686*|3.15.*rc6*.fc21.x86_64) return 1 ;;
+ 3.16.*rc4*.fc21.i686*|3.16.*rc4*.fc21.x86_64) return 1 ;;
esac
}
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=22be7c441784fd89…
Commit: 22be7c441784fd89cf76cb6ed56fd50da126864d
Parent: 3a8bb8d3a4ef379298e97ca5f087a1c8908841ed
Author: Zdenek Kabelac <zkabelac(a)redhat.com>
AuthorDate: Wed Jul 23 00:25:49 2014 +0200
Committer: Zdenek Kabelac <zkabelac(a)redhat.com>
CommitterDate: Wed Jul 23 00:25:49 2014 +0200
tests: support cluster run
needs exclusive activation
---
test/shell/lvcreate-cache.sh | 6 +++---
1 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/test/shell/lvcreate-cache.sh b/test/shell/lvcreate-cache.sh
index 4274897..03ff214 100644
--- a/test/shell/lvcreate-cache.sh
+++ b/test/shell/lvcreate-cache.sh
@@ -71,14 +71,14 @@ lvremove -f $vg/cache_pool
# Bug 1110026
# Create origin, then cache_pool and cache
-lvcreate -l 2 -n $lv1 $vg
+lvcreate -aey -l 2 -n $lv1 $vg
lvcreate --type cache -l 1 $vg/$lv1
#should dmsetup table ${vg}-$lv1 | grep cache # ensure it is loaded in kernel
lvremove -ff $vg
# Bug 1110026 & Bug 1095843
# Create RAID1 origin, then cache_pool and cache
-lvcreate -l 2 -n $lv1 $vg
+lvcreate -aey -l 2 -n $lv1 $vg
lvcreate --type cache -l 1 $vg/$lv1
#should lvs -a $vg/${lv1}_corig_rimage_0 # ensure images are properly renamed
#should dmsetup table ${vg}-$lv1 | grep cache # ensure it is loaded in kernel
@@ -101,7 +101,7 @@ done
##############################
# Attempt to create smaller cache than origin should fail
-lvcreate -l 1 -n $lv1 $vg
+lvcreate -aey -l 1 -n $lv1 $vg
not lvcreate --type cache -l 2 $vg/$lv1
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=3a8bb8d3a4ef3792…
Commit: 3a8bb8d3a4ef379298e97ca5f087a1c8908841ed
Parent: ab1887fe4719a296c2bd4b4778348f55f1b7a49a
Author: Zdenek Kabelac <zkabelac(a)redhat.com>
AuthorDate: Tue Jul 22 23:43:26 2014 +0200
Committer: Zdenek Kabelac <zkabelac(a)redhat.com>
CommitterDate: Tue Jul 22 23:44:06 2014 +0200
tests: use exclusive activation
---
test/shell/lvconvert-raid-allocation.sh | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/test/shell/lvconvert-raid-allocation.sh b/test/shell/lvconvert-raid-allocation.sh
index aef786c..bd2cab5 100644
--- a/test/shell/lvconvert-raid-allocation.sh
+++ b/test/shell/lvconvert-raid-allocation.sh
@@ -18,7 +18,7 @@ vgcreate -s 256k $vg $(cat DEVICES)
# Start with linear on 2 PV and ensure that converting to
# RAID is not allowed to reuse PVs for different images. (Bug 1113180)
-lvcreate -l 4 -n $lv1 $vg "$dev1:0-1" "$dev2:0-1"
+lvcreate -aey -l 4 -n $lv1 $vg "$dev1:0-1" "$dev2:0-1"
not lvconvert --type raid1 -m 1 $vg/$lv1 "$dev1" "$dev2"
not lvconvert --type raid1 -m 1 $vg/$lv1 "$dev1" "$dev3:0-2"
lvconvert --type raid1 -m 1 $vg/$lv1 "$dev3"
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=ab1887fe4719a296…
Commit: ab1887fe4719a296c2bd4b4778348f55f1b7a49a
Parent: 66686a5bc5ec09a48b0e549f5539424cbf2c7de8
Author: Petr Rockai <prockai(a)redhat.com>
AuthorDate: Tue Jul 22 22:47:27 2014 +0200
Committer: Petr Rockai <prockai(a)redhat.com>
CommitterDate: Tue Jul 22 22:48:41 2014 +0200
man: Update the lvscan manpage with a section on --cache.
---
man/lvscan.8.in | 9 +++++++++
1 files changed, 9 insertions(+), 0 deletions(-)
diff --git a/man/lvscan.8.in b/man/lvscan.8.in
index fad0fbe..0b6e50b 100644
--- a/man/lvscan.8.in
+++ b/man/lvscan.8.in
@@ -34,6 +34,15 @@ mimage_0, mimage_1, and mlog.
.BR \-b ", " \-\-blockdevice
This option is now ignored. Instead, use \fBlvs\fP(8) or
\fBlvdisplay\fP(8) to obtain the device number.
+.TP
+.IR \fB\-\-cache " " LogicalVolume
+Applicable only when \fBlvmetad\fP(8) is in use (see also \fBlvm.conf\fP(5),
+global/use_lvmetad). This command issues a rescan of physical volume labels and
+metadata areas of all PVs that the logical volume uses. In particular, this can
+be used when a RAID logical volume becomes degraded, to update information
+about physical volume availability. This is only necessary if the logical
+volume is \fBnot\fP being monitored by dmeventd (see \fBlvchange\fP(8), option
+\fB\-\-monitor\fP).
.SH SEE ALSO
.BR lvm (8),
.BR lvcreate (8),
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=66686a5bc5ec09a4…
Commit: 66686a5bc5ec09a48b0e549f5539424cbf2c7de8
Parent: 5dc6671bb550f4b480befee03d234373d08e188a
Author: Petr Rockai <prockai(a)redhat.com>
AuthorDate: Tue Jul 22 22:33:42 2014 +0200
Committer: Petr Rockai <prockai(a)redhat.com>
CommitterDate: Tue Jul 22 22:48:41 2014 +0200
WHATS_NEW: lvscan --cache, dmeventd RAID + lvmetad
---
WHATS_NEW | 2 ++
1 files changed, 2 insertions(+), 0 deletions(-)
diff --git a/WHATS_NEW b/WHATS_NEW
index 88319bf..3595517 100644
--- a/WHATS_NEW
+++ b/WHATS_NEW
@@ -1,5 +1,7 @@
Version 2.02.108 -
=================================
+ Add lvscan --cache which re-scans constituents of a particular LV.
+ Make dmeventd's RAID plugin re-scan failed PVs when lvmetad is in use.
Improve code sharing for lvconvert and lvcreate and pools (cache & thin).
Improve lvconvert --merge validation.
Improve lvconvert --splitsnapshot validation.
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=5dc6671bb550f4b4…
Commit: 5dc6671bb550f4b480befee03d234373d08e188a
Parent: a9ea014e5152b806f57f6099311b64a2c03ca482
Author: Petr Rockai <prockai(a)redhat.com>
AuthorDate: Mon Jul 21 04:33:21 2014 +0200
Committer: Petr Rockai <prockai(a)redhat.com>
CommitterDate: Tue Jul 22 22:48:21 2014 +0200
dmeventd: Call lvscan --cache in the RAID plugin.
---
daemons/dmeventd/plugins/raid/dmeventd_raid.c | 10 ++++++++++
1 files changed, 10 insertions(+), 0 deletions(-)
diff --git a/daemons/dmeventd/plugins/raid/dmeventd_raid.c b/daemons/dmeventd/plugins/raid/dmeventd_raid.c
index 3fbae15..4690cfa 100644
--- a/daemons/dmeventd/plugins/raid/dmeventd_raid.c
+++ b/daemons/dmeventd/plugins/raid/dmeventd_raid.c
@@ -33,10 +33,20 @@ static int run_repair(const char *device)
char cmd_str[CMD_SIZE];
if (!dmeventd_lvm2_command(dmeventd_lvm2_pool(), cmd_str, sizeof(cmd_str),
+ "lvscan --cache", device))
+ return -1;
+
+ r = dmeventd_lvm2_run(cmd_str);
+
+ if (!r)
+ syslog(LOG_INFO, "Re-scan of RAID device %s failed.", device);
+
+ if (!dmeventd_lvm2_command(dmeventd_lvm2_pool(), cmd_str, sizeof(cmd_str),
"lvconvert --config devices{ignore_suspended_devices=1} "
"--repair --use-policies", device))
return -1;
+ /* if repair goes OK, report success even if lvscan has failed */
r = dmeventd_lvm2_run(cmd_str);
if (!r)
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=a9ea014e5152b806…
Commit: a9ea014e5152b806f57f6099311b64a2c03ca482
Parent: 653fd7bee3d9f765fdf81743331f2d9e91ea28bf
Author: Petr Rockai <prockai(a)redhat.com>
AuthorDate: Mon Jul 21 03:55:46 2014 +0200
Committer: Petr Rockai <prockai(a)redhat.com>
CommitterDate: Tue Jul 22 22:48:21 2014 +0200
lvscan: Implement a --cache mode.
---
tools/commands.h | 3 ++-
tools/lvscan.c | 27 ++++++++++++++++++++++++++-
2 files changed, 28 insertions(+), 2 deletions(-)
diff --git a/tools/commands.h b/tools/commands.h
index 1f9d03c..6e115d9 100644
--- a/tools/commands.h
+++ b/tools/commands.h
@@ -581,6 +581,7 @@ xx(lvscan,
"lvscan " "\n"
"\t[-a|--all]\n"
"\t[-b|--blockdevice] " "\n"
+ "\t[--cache]\n"
"\t[--commandprofile ProfileName]\n"
"\t[-d|--debug] " "\n"
"\t[-h|-?|--help] " "\n"
@@ -591,7 +592,7 @@ xx(lvscan,
"\t[--version]\n",
all_ARG, blockdevice_ARG, ignorelockingfailure_ARG, partial_ARG,
- readonly_ARG)
+ readonly_ARG, cache_ARG)
xx(pvchange,
"Change attributes of physical volume(s)",
diff --git a/tools/lvscan.c b/tools/lvscan.c
index 2641054..df8a12e 100644
--- a/tools/lvscan.c
+++ b/tools/lvscan.c
@@ -15,6 +15,28 @@
#include "tools.h"
+static int _lvscan_single_lvmetad(struct cmd_context *cmd, struct logical_volume *lv)
+{
+ struct pv_list *pvl;
+ struct dm_list pvs;
+
+ if (!lvmetad_used()) {
+ log_verbose("Ignoring lvscan --cache because lvmetad is not in use.");
+ return ECMD_PROCESSED;
+ }
+
+ dm_list_init(&pvs);
+
+ if (!get_pv_list_for_lv(lv->vg->vgmem, lv, &pvs))
+ return ECMD_FAILED;
+
+ dm_list_iterate_items(pvl, &pvs)
+ if (!lvmetad_pvscan_single(cmd, pvl->pv->dev, NULL))
+ return ECMD_FAILED;
+
+ return ECMD_PROCESSED;
+}
+
static int lvscan_single(struct cmd_context *cmd, struct logical_volume *lv,
void *handle __attribute__((unused)))
{
@@ -24,6 +46,9 @@ static int lvscan_single(struct cmd_context *cmd, struct logical_volume *lv,
const char *active_str, *snapshot_str;
+ if (arg_count(cmd, cache_ARG))
+ return _lvscan_single_lvmetad(cmd, lv);
+
if (!arg_count(cmd, all_ARG) && !lv_is_visible(lv))
return ECMD_PROCESSED;
@@ -58,7 +83,7 @@ static int lvscan_single(struct cmd_context *cmd, struct logical_volume *lv,
int lvscan(struct cmd_context *cmd, int argc, char **argv)
{
- if (argc) {
+ if (argc && !arg_count(cmd, cache_ARG)) {
log_error("No additional command line arguments allowed");
return EINVALID_CMD_LINE;
}
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=653fd7bee3d9f765…
Commit: 653fd7bee3d9f765fdf81743331f2d9e91ea28bf
Parent: ee11bb841612ec4dba173c31bf795a8560ca134e
Author: Zdenek Kabelac <zkabelac(a)redhat.com>
AuthorDate: Fri Jul 11 12:15:46 2014 +0200
Committer: Zdenek Kabelac <zkabelac(a)redhat.com>
CommitterDate: Tue Jul 22 22:41:41 2014 +0200
tests: new lvconvert features
---
test/shell/lvconvert-cache.sh | 44 +++++++++++++++++++++++++++++++-
test/shell/lvconvert-thin-external.sh | 2 +-
test/shell/lvconvert-thin.sh | 12 ++++++--
3 files changed, 52 insertions(+), 6 deletions(-)
diff --git a/test/shell/lvconvert-cache.sh b/test/shell/lvconvert-cache.sh
index 79d5fd1..6c2acd9 100644
--- a/test/shell/lvconvert-cache.sh
+++ b/test/shell/lvconvert-cache.sh
@@ -16,10 +16,50 @@ aux have_cache 1 3 0 || skip
aux prepare_vg 5 80
# lvcreate origin, lvcreate cache-pool, and lvconvert to cache
-lvcreate -l 2 -n $lv1 $vg
+lvcreate -L 2 -n $lv1 $vg
+lvcreate -L 8 -n $lv2 $vg
+lvcreate -L 8 -n $lv3 $vg
+
+# undefined cachepool
+invalid lvconvert --type cache --poolmetadata $vg/$lv2 $vg/$lv1
+
+# cannot mix with thins
+invalid lvconvert --type cache --poolmetadata $vg/$lv2 --thinpool $vg/$lv1
+invalid lvconvert --type cache --thin --poolmetadata $vg/$lv2 $vg/$lv1
+
+# undefined cached volume
+invalid lvconvert --type cache --cachepool $vg/$lv1
+invalid lvconvert --cache --cachepool $vg/$lv1
+
+# single vg
+invalid lvconvert --type cache --cachepool $vg/$lv1 --poolmetadata $vg1/$lv2 $vg/$lv3
+invalid lvconvert --type cache --cachepool $vg/$lv1 --poolmetadata $lv2 $vg1/$lv3
+invalid lvconvert --type cache --cachepool $vg1/$lv1 --poolmetadata $vg2/$lv2 $vg/$lv3
+
+invalid lvconvert --cachepool $vg1/$lv1 --poolmetadata $vg2/$lv2
+invalid lvconvert --type cache-pool --poolmetadata $vg2/$lv2 $vg1/$lv1
+
+fail lvconvert --yes --type cache-pool --chunksize 16M --poolmetadata $lv2 $vg/$lv1
+
+lvconvert --yes --type cache-pool --cachepool $vg/$lv1
+
+#fail lvconvert --cachepool $vg/$lv1 --poolmetadata $vg/$lv2
+#lvconvert --yes --type cache-pool --poolmetadata $vg/$lv2 $vg/$lv1
+#lvconvert --yes --poolmetadata $vg/$lv2 --cachepool $vg/$lv1
+
+lvremove -ff $vg
+
+lvcreate -L 2 -n $lv1 $vg
lvcreate --type cache-pool -l 1 -n ${lv1}_cachepool $vg
-lvconvert --type cache --cachepool $vg/${lv1}_cachepool $vg/$lv1
+
+lvconvert --cache --cachepool $vg/${lv1}_cachepool $vg/$lv1
dmsetup table ${vg}-$lv1 | grep cache # ensure it is loaded in kernel
+
+#lvconvert --cachepool $vg/${lv1}_cachepool $vg/$lv1
+#lvconvert --cachepool $vg/${lv1}_cachepool --poolmetadatasize 20 "$dev3"
+
+
+fail lvconvert --type cache --cachepool $vg/${lv1}_cachepool $vg/$lv1
lvremove -ff $vg
# Bug 1095843
diff --git a/test/shell/lvconvert-thin-external.sh b/test/shell/lvconvert-thin-external.sh
index 676851e..1e9887a 100644
--- a/test/shell/lvconvert-thin-external.sh
+++ b/test/shell/lvconvert-thin-external.sh
@@ -109,7 +109,7 @@ lvchange -aey $vg
lvs -a -o+origin_size,seg_size $vg
# Chain external origins
-lvconvert --originname extorg1 --thinpool $vg/pool -T $vg/extorg
+lvconvert --type thin --originname extorg1 --thinpool $vg/pool $vg/extorg
check inactive $vg extorg1
lvconvert --originname extorg2 --thinpool $vg/pool -T $vg/extorg1
diff --git a/test/shell/lvconvert-thin.sh b/test/shell/lvconvert-thin.sh
index 80f55dd..4aee7d2 100644
--- a/test/shell/lvconvert-thin.sh
+++ b/test/shell/lvconvert-thin.sh
@@ -12,8 +12,7 @@
. lib/inittest
-prepare_lvs()
-{
+prepare_lvs() {
lvremove -f $vg
lvcreate -L10M -n $lv1 $vg
lvcreate -L8M -n $lv2 $vg
@@ -38,6 +37,13 @@ aux extend_filter_LVMTEST
pvcreate "$DM_DEV_DIR/$vg1/$lv"
vgcreate $vg -s 64K $(tail -n+4 DEVICES) "$DM_DEV_DIR/$vg1/$lv"
+lvcreate -L1T -n $lv1 $vg
+invalid lvconvert --yes -c 8M --type thin --poolmetadatasize 1G $vg/$lv1
+
+# needs some --cachepool or --thinpool
+invalid lvconvert --yes --poolmetadatasize 1G $vg/$lv1
+lvremove -f $vg
+
# create mirrored LVs for data and metadata volumes
lvcreate -aey -L10M --type mirror -m1 --mirrorlog core -n $lv1 $vg
lvcreate -aey -L10M -n $lv2 $vg
@@ -60,7 +66,7 @@ lvconvert --yes -c 64 --stripes 2 --thinpool $vg/$lv1 --readahead 48
lvremove -f $vg
lvcreate -L1T -n $lv1 $vg
-lvconvert --yes -c 8M --thinpool $vg/$lv1
+lvconvert --yes -c 8M --type thin-pool $vg/$lv1
lvremove -f $vg
# test with bigger sizes
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=ee11bb841612ec4d…
Commit: ee11bb841612ec4dba173c31bf795a8560ca134e
Parent: b51f1b3df6c07f611ce364b4b662af7a2d1c9544
Author: Zdenek Kabelac <zkabelac(a)redhat.com>
AuthorDate: Tue Jul 22 22:14:31 2014 +0200
Committer: Zdenek Kabelac <zkabelac(a)redhat.com>
CommitterDate: Tue Jul 22 22:41:41 2014 +0200
tests: use full option name
Don't overuse shortcut support -
since poolmetadatasize was the only allowed option
it's been equivalent to poolmetadata
---
test/shell/lvresize-thin-metadata.sh | 6 +++---
1 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/test/shell/lvresize-thin-metadata.sh b/test/shell/lvresize-thin-metadata.sh
index a034d07..9e2ae4d 100644
--- a/test/shell/lvresize-thin-metadata.sh
+++ b/test/shell/lvresize-thin-metadata.sh
@@ -26,14 +26,14 @@ for deactivate in true false; do
test $deactivate && lvchange -an $vg
- lvresize --poolmetadata +2M $vg/pool
+ lvresize --poolmetadatasize +2M $vg/pool
# Test it's been resized to 4M
check lv_field $vg/pool_tmeta size "4.00m"
- lvresize --poolmetadata +256M $vg/pool
+ lvresize --poolmetadatasize +256M $vg/pool
check lv_field $vg/pool_tmeta size "260.00m"
- lvresize --poolmetadata +3G $vg/pool
+ lvresize --poolmetadatasize +3G $vg/pool
check lv_field $vg/pool_tmeta size "3.25g"
vgchange -an $vg
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=b51f1b3df6c07f61…
Commit: b51f1b3df6c07f611ce364b4b662af7a2d1c9544
Parent: d7d81e11574baad841def2fc1efb7a22ea44cd3e
Author: Zdenek Kabelac <zkabelac(a)redhat.com>
AuthorDate: Tue Jul 22 17:31:22 2014 +0200
Committer: Zdenek Kabelac <zkabelac(a)redhat.com>
CommitterDate: Tue Jul 22 22:41:41 2014 +0200
man: lvconvert poolmetadataspare
Add missing description for --poolmetadataspare option.
---
man/lvconvert.8.in | 11 +++++++++++
man/lvcreate.8.in | 4 ++--
2 files changed, 13 insertions(+), 2 deletions(-)
diff --git a/man/lvconvert.8.in b/man/lvconvert.8.in
index 032fbff..93fb9a9 100644
--- a/man/lvconvert.8.in
+++ b/man/lvconvert.8.in
@@ -118,6 +118,8 @@ lvconvert \(em convert a logical volume from linear to mirror or snapshot
.RI { ReadAheadSectors | auto | none }]
.RB [ \-\-stripes \ \fIStripes
.RB [ \-I | \-\-stripesize \ \fIStripeSize ]]]
+.RB [ \-\-poolmetadataspare
+.RI { y | n }]
.RB [ \-Z | \-\-zero \ { \fIy | \fIn }]]
.RI [[ ExternalOrigin | ThinPool ] LogicalVolume { Name | Path }]
.RI [ PhysicalVolume [ Path ][ :PE
@@ -141,6 +143,8 @@ lvconvert \(em convert a logical volume from linear to mirror or snapshot
|
.B \-\-poolmetadatasize
.IR CachePoolMetadataSize [ bBsSkKmMgG ]}]
+.RB [ \-\-poolmetadataspare
+.RI { y | n }]
.IR LogicalVolume { Name | Path }
.RI [ PhysicalVolume [ Path ][ :PE [ \-PE ]]...]
.RB [ \-\-commandprofile
@@ -373,6 +377,13 @@ The default value is estimated with this formula
(Pool_LV_size / Pool_LV_chunk_size * 64b).
Default unit is megabytes.
.TP
+.IR \fB\-\-poolmetadataspare " {" y | n }
+Controls creation and maintanence of pool metadata spare logical volume
+that will be used for automated pool recovery.
+Only one such volume is maintained within a volume group
+with the size of the biggest pool metadata volume.
+Default is \fIy\fPes.
+.TP
.IR \fB\-r ", " \fB\-\-readahead " {" ReadAheadSectors | auto | none }
Sets read ahead sector count of thin pool metadata logical volume.
The default value is "\fIauto\fP" which allows the kernel to choose
diff --git a/man/lvcreate.8.in b/man/lvcreate.8.in
index 4ae2b9a..5440ced 100644
--- a/man/lvcreate.8.in
+++ b/man/lvcreate.8.in
@@ -346,9 +346,9 @@ Default unit is megabytes.
.TP
.IR \fB\-\-poolmetadataspare " {" y | n }
Controls creation and maintanence of pool metadata spare logical volume
-that will be used for automated thin pool recovery.
+that will be used for automated pool recovery.
Only one such volume is maintained within a volume group
-with the size of the biggest thin metadata volume.
+with the size of the biggest pool metadata volume.
Default is \fIy\fPes.
.TP
.IR \fB\-r ", " \fB\-\-readahead " {" ReadAheadSectors | auto | none }
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=d7d81e11574baad8…
Commit: d7d81e11574baad841def2fc1efb7a22ea44cd3e
Parent: 894eda4707dbcf9e160922d95621703c0fa58f94
Author: Zdenek Kabelac <zkabelac(a)redhat.com>
AuthorDate: Tue Jul 22 17:29:53 2014 +0200
Committer: Zdenek Kabelac <zkabelac(a)redhat.com>
CommitterDate: Tue Jul 22 22:41:40 2014 +0200
cleanup: show better messages
---
lib/metadata/cache_manip.c | 4 ++--
1 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/lib/metadata/cache_manip.c b/lib/metadata/cache_manip.c
index e6b6551..184df79 100644
--- a/lib/metadata/cache_manip.c
+++ b/lib/metadata/cache_manip.c
@@ -41,8 +41,8 @@ int update_cache_pool_params(struct volume_group *vg, unsigned attr,
}
if (*chunk_size & (DM_CACHE_MIN_DATA_BLOCK_SIZE - 1)) {
- log_error("Chunk size must be a multiple of %u sectors.",
- DM_CACHE_MIN_DATA_BLOCK_SIZE);
+ log_error("Chunk size must be a multiple of %s.",
+ display_size(vg->cmd, DM_CACHE_MIN_DATA_BLOCK_SIZE));
return 0;
}
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=894eda4707dbcf9e…
Commit: 894eda4707dbcf9e160922d95621703c0fa58f94
Parent: 8c56c5fbacf6a4e9a0130b6f1fdc5683d6f108ec
Author: Zdenek Kabelac <zkabelac(a)redhat.com>
AuthorDate: Tue Jul 22 22:20:18 2014 +0200
Committer: Zdenek Kabelac <zkabelac(a)redhat.com>
CommitterDate: Tue Jul 22 22:41:38 2014 +0200
thin and cache: unify pool common code
Fix get_pool_params to only read params.
Add poolmetadataspare option to get_pool_params.
Move all profile code into update_pool_params.
Move recalculate code into pool_manip.c
---
WHATS_NEW | 1 +
lib/config/config.c | 6 +-
lib/metadata/cache_manip.c | 11 ++--
lib/metadata/lv_manip.c | 104 +++-------------------------------
lib/metadata/metadata-exported.h | 24 +++++---
lib/metadata/pool_manip.c | 116 ++++++++++++++++++++++++++++++++++++++
lib/metadata/thin_manip.c | 63 +++++++--------------
tools/lvconvert.c | 84 ++++++++-------------------
tools/lvcreate.c | 57 +++++-------------
tools/toollib.c | 69 +++++++++++++----------
tools/toollib.h | 6 +-
11 files changed, 253 insertions(+), 288 deletions(-)
diff --git a/WHATS_NEW b/WHATS_NEW
index c800dd0..88319bf 100644
--- a/WHATS_NEW
+++ b/WHATS_NEW
@@ -1,5 +1,6 @@
Version 2.02.108 -
=================================
+ Improve code sharing for lvconvert and lvcreate and pools (cache & thin).
Improve lvconvert --merge validation.
Improve lvconvert --splitsnapshot validation.
Add report/list_item_separator lvm.conf option.
diff --git a/lib/config/config.c b/lib/config/config.c
index 8148a18..a71cbdc 100644
--- a/lib/config/config.c
+++ b/lib/config/config.c
@@ -1988,9 +1988,9 @@ int get_default_allocation_thin_pool_chunk_size_CFG(struct cmd_context *cmd, str
}
if (!strcasecmp(str, "generic"))
- chunk_size = DEFAULT_THIN_POOL_CHUNK_SIZE;
+ chunk_size = DEFAULT_THIN_POOL_CHUNK_SIZE * 2;
else if (!strcasecmp(str, "performance"))
- chunk_size = DEFAULT_THIN_POOL_CHUNK_SIZE_PERFORMANCE;
+ chunk_size = DEFAULT_THIN_POOL_CHUNK_SIZE_PERFORMANCE * 2;
else {
log_error("Thin pool chunk size calculation policy \"%s\" is unrecognised.", str);
return 0;
@@ -2001,5 +2001,5 @@ int get_default_allocation_thin_pool_chunk_size_CFG(struct cmd_context *cmd, str
int get_default_allocation_cache_pool_chunk_size_CFG(struct cmd_context *cmd, struct profile *profile)
{
- return DEFAULT_CACHE_POOL_CHUNK_SIZE;
+ return DEFAULT_CACHE_POOL_CHUNK_SIZE * 2;
}
diff --git a/lib/metadata/cache_manip.c b/lib/metadata/cache_manip.c
index 8a5e5e3..e6b6551 100644
--- a/lib/metadata/cache_manip.c
+++ b/lib/metadata/cache_manip.c
@@ -23,14 +23,15 @@
#include "defaults.h"
int update_cache_pool_params(struct volume_group *vg, unsigned attr,
- int passed_args,
- uint32_t data_extents, uint32_t extent_size,
- int *chunk_size_calc_method, uint32_t *chunk_size,
- thin_discards_t *discards,
- uint64_t *pool_metadata_size, int *zero)
+ int passed_args, uint32_t data_extents,
+ uint64_t *pool_metadata_size,
+ int *chunk_size_calc_method, uint32_t *chunk_size)
{
uint64_t min_meta_size;
+ if (!(passed_args & PASS_ARG_CHUNK_SIZE))
+ *chunk_size = DEFAULT_CACHE_POOL_CHUNK_SIZE * 2;
+
if ((*chunk_size < DM_CACHE_MIN_DATA_BLOCK_SIZE) ||
(*chunk_size > DM_CACHE_MAX_DATA_BLOCK_SIZE)) {
log_error("Chunk size must be in the range %s to %s.",
diff --git a/lib/metadata/lv_manip.c b/lib/metadata/lv_manip.c
index c55b31f..0d39166 100644
--- a/lib/metadata/lv_manip.c
+++ b/lib/metadata/lv_manip.c
@@ -6040,97 +6040,6 @@ int lv_activation_skip(struct logical_volume *lv, activation_change_t activate,
return 1;
}
-/* Greatest common divisor */
-static unsigned long _gcd(unsigned long n1, unsigned long n2)
-{
- unsigned long remainder;
-
- do {
- remainder = n1 % n2;
- n1 = n2;
- n2 = remainder;
- } while (n2);
-
- return n1;
-}
-
-/* Least common multiple */
-static unsigned long _lcm(unsigned long n1, unsigned long n2)
-{
- if (!n1 || !n2)
- return 0;
- return (n1 * n2) / _gcd(n1, n2);
-}
-
-static int _recalculate_pool_chunk_size_with_dev_hints(struct lvcreate_params *lp,
- struct logical_volume *pool_lv)
-{
- struct logical_volume *pool_data_lv;
- struct lv_segment *seg;
- struct physical_volume *pv;
- struct cmd_context *cmd = pool_lv->vg->cmd;
- unsigned long previous_hint = 0, hint = 0;
- uint32_t chunk_size = lp->chunk_size;
- uint32_t default_chunk_size;
- uint32_t min_chunk_size, max_chunk_size;
-
- if (lp->passed_args & PASS_ARG_CHUNK_SIZE)
- goto out;
-
- if (seg_is_thin_pool(lp)) {
- if (find_config_tree_int(cmd, allocation_thin_pool_chunk_size_CFG, NULL))
- goto out;
-
- min_chunk_size = DM_THIN_MIN_DATA_BLOCK_SIZE;
- max_chunk_size = DM_THIN_MAX_DATA_BLOCK_SIZE;
- default_chunk_size = get_default_allocation_thin_pool_chunk_size_CFG(cmd, NULL) * 2;
- } else if (seg_is_cache_pool(lp)) {
- if (find_config_tree_int(cmd, allocation_cache_pool_chunk_size_CFG, NULL))
- goto out;
- min_chunk_size = DM_CACHE_MIN_DATA_BLOCK_SIZE;
- max_chunk_size = DM_CACHE_MAX_DATA_BLOCK_SIZE;
- default_chunk_size = get_default_allocation_cache_pool_chunk_size_CFG(cmd, NULL) * 2;
- } else {
- log_error(INTERNAL_ERROR "%s is not a thin pool or cache pool",
- pool_lv->name);
- return 0;
- }
-
- pool_data_lv = seg_lv(first_seg(pool_lv), 0);
-
- dm_list_iterate_items(seg, &pool_data_lv->segments) {
- pv = seg_pv(seg, 0);
- if (lp->thin_chunk_size_calc_policy == THIN_CHUNK_SIZE_CALC_METHOD_PERFORMANCE)
- hint = dev_optimal_io_size(cmd->dev_types, pv_dev(pv));
- else
- hint = dev_minimum_io_size(cmd->dev_types, pv_dev(pv));
-
- if (!hint)
- continue;
- if (previous_hint)
- hint = _lcm(previous_hint, hint);
- previous_hint = hint;
- }
-
- if (!hint) {
- log_debug_alloc("No usable device hint found while recalculating"
- " thin pool chunk size for %s.", pool_lv->name);
- goto out;
- }
-
- if ((hint < min_chunk_size) || (hint > max_chunk_size)) {
- log_debug_alloc("Calculated chunk size value of %ld sectors for"
- " thin pool %s is out of allowed range (%d-%d).",
- hint, pool_lv->name,
- min_chunk_size, max_chunk_size);
- } else
- chunk_size = (hint >= default_chunk_size) ?
- hint : default_chunk_size;
-out:
- first_seg(pool_lv)->chunk_size = chunk_size;
- return 1;
-}
-
static int _should_wipe_lv(struct lvcreate_params *lp, struct logical_volume *lv) {
int r = lp->zero | lp->wipe_signatures;
@@ -6496,16 +6405,21 @@ static struct logical_volume *_lv_create_an_lv(struct volume_group *vg,
return_NULL;
if (seg_is_cache_pool(lp)) {
- if (!_recalculate_pool_chunk_size_with_dev_hints(lp, lv))
- return_NULL;
+ first_seg(lv)->chunk_size = lp->chunk_size;
first_seg(lv)->feature_flags = lp->feature_flags;
- } else if (seg_is_thin_pool(lp)) {
- if (!_recalculate_pool_chunk_size_with_dev_hints(lp, lv))
+ /* TODO: some calc_policy solution for cache ? */
+ if (!recalculate_pool_chunk_size_with_dev_hints(lv, lp->passed_args,
+ THIN_CHUNK_SIZE_CALC_METHOD_GENERIC))
return_NULL;
+ } else if (seg_is_thin_pool(lp)) {
+ first_seg(lv)->chunk_size = lp->chunk_size;
first_seg(lv)->zero_new_blocks = lp->zero ? 1 : 0;
first_seg(lv)->discards = lp->discards;
/* FIXME: use lowwatermark via lvm.conf global for all thinpools ? */
first_seg(lv)->low_water_mark = 0;
+ if (!recalculate_pool_chunk_size_with_dev_hints(lv, lp->passed_args,
+ lp->thin_chunk_size_calc_policy))
+ return_NULL;
} else if (seg_is_thin_volume(lp)) {
pool_lv = first_seg(lv)->pool_lv;
if (!(first_seg(lv)->device_id =
diff --git a/lib/metadata/metadata-exported.h b/lib/metadata/metadata-exported.h
index 9d7a653..fa96a1a 100644
--- a/lib/metadata/metadata-exported.h
+++ b/lib/metadata/metadata-exported.h
@@ -703,17 +703,25 @@ struct logical_volume *find_pool_lv(const struct logical_volume *lv);
int pool_is_active(const struct logical_volume *pool_lv);
int pool_supports_external_origin(const struct lv_segment *pool_seg, const struct logical_volume *external_lv);
int thin_pool_feature_supported(const struct logical_volume *pool_lv, int feature);
+int recalculate_pool_chunk_size_with_dev_hints(struct logical_volume *pool_lv,
+ int passed_args,
+ int chunk_size_calc_policy);
int update_pool_lv(struct logical_volume *lv, int activate);
+int update_pool_params(const struct segment_type *segtype,
+ struct volume_group *vg, unsigned target_attr,
+ int passed_args, uint32_t data_extents,
+ uint64_t *pool_metadata_size,
+ int *chunk_size_calc_policy, uint32_t *chunk_size,
+ thin_discards_t *discards, int *zero);
int update_profilable_pool_params(struct cmd_context *cmd, struct profile *profile,
int passed_args, int *chunk_size_calc_method,
uint32_t *chunk_size, thin_discards_t *discards,
int *zero);
int update_thin_pool_params(struct volume_group *vg, unsigned attr,
- int passed_args,
- uint32_t data_extents, uint32_t extent_size,
+ int passed_args, uint32_t data_extents,
+ uint64_t *pool_metadata_size,
int *chunk_size_calc_method, uint32_t *chunk_size,
- thin_discards_t *discards,
- uint64_t *pool_metadata_size, int *zero);
+ thin_discards_t *discards, int *zero);
int get_pool_discards(const char *str, thin_discards_t *discards);
const char *get_pool_discards_name(thin_discards_t discards);
struct logical_volume *alloc_pool_metadata(struct logical_volume *pool_lv,
@@ -1043,11 +1051,9 @@ int partial_raid_lv_supports_degraded_activation(struct logical_volume *lv);
/* ++ metadata/cache_manip.c */
int update_cache_pool_params(struct volume_group *vg, unsigned attr,
- int passed_args,
- uint32_t data_extents, uint32_t extent_size,
- int *chunk_size_calc_method, uint32_t *chunk_size,
- thin_discards_t *discards,
- uint64_t *pool_metadata_size, int *zero);
+ int passed_args, uint32_t data_extents,
+ uint64_t *pool_metadata_size,
+ int *chunk_size_calc_method, uint32_t *chunk_size);
struct logical_volume *lv_cache_create(struct logical_volume *pool,
struct logical_volume *origin);
int lv_cache_remove(struct logical_volume *cache_lv);
diff --git a/lib/metadata/pool_manip.c b/lib/metadata/pool_manip.c
index e32b109..0ed5d64 100644
--- a/lib/metadata/pool_manip.c
+++ b/lib/metadata/pool_manip.c
@@ -23,7 +23,9 @@
#include "segtype.h"
#include "lv_alloc.h"
#include "defaults.h"
+#include "dev-type.h"
#include "display.h"
+#include "toolcontext.h"
int attach_pool_metadata_lv(struct lv_segment *pool_seg,
struct logical_volume *metadata_lv)
@@ -230,6 +232,120 @@ struct lv_segment *find_pool_seg(const struct lv_segment *seg)
return pool_seg;
}
+/* Greatest common divisor */
+static unsigned long _gcd(unsigned long n1, unsigned long n2)
+{
+ unsigned long remainder;
+
+ do {
+ remainder = n1 % n2;
+ n1 = n2;
+ n2 = remainder;
+ } while (n2);
+
+ return n1;
+}
+
+/* Least common multiple */
+static unsigned long _lcm(unsigned long n1, unsigned long n2)
+{
+ if (!n1 || !n2)
+ return 0;
+ return (n1 * n2) / _gcd(n1, n2);
+}
+
+int recalculate_pool_chunk_size_with_dev_hints(struct logical_volume *pool_lv,
+ int passed_args,
+ int chunk_size_calc_policy)
+{
+ struct logical_volume *pool_data_lv;
+ struct lv_segment *seg;
+ struct physical_volume *pv;
+ struct cmd_context *cmd = pool_lv->vg->cmd;
+ unsigned long previous_hint = 0, hint = 0;
+ uint32_t default_chunk_size;
+ uint32_t min_chunk_size, max_chunk_size;
+
+ if (passed_args & PASS_ARG_CHUNK_SIZE)
+ return 1;
+
+ if (lv_is_thin_pool(pool_lv)) {
+ if (find_config_tree_int(cmd, allocation_thin_pool_chunk_size_CFG, NULL))
+ return 1;
+ min_chunk_size = DM_THIN_MIN_DATA_BLOCK_SIZE;
+ max_chunk_size = DM_THIN_MAX_DATA_BLOCK_SIZE;
+ default_chunk_size = get_default_allocation_thin_pool_chunk_size_CFG(cmd, NULL);
+ } else if (lv_is_cache_pool(pool_lv)) {
+ if (find_config_tree_int(cmd, allocation_cache_pool_chunk_size_CFG, NULL))
+ return 1;
+ min_chunk_size = DM_CACHE_MIN_DATA_BLOCK_SIZE;
+ max_chunk_size = DM_CACHE_MAX_DATA_BLOCK_SIZE;
+ default_chunk_size = get_default_allocation_cache_pool_chunk_size_CFG(cmd, NULL);
+ } else {
+ log_error(INTERNAL_ERROR "%s is not a pool logical volume.", display_lvname(pool_lv));
+ return 0;
+ }
+
+ pool_data_lv = seg_lv(first_seg(pool_lv), 0);
+ dm_list_iterate_items(seg, &pool_data_lv->segments) {
+ pv = seg_pv(seg, 0);
+ if (chunk_size_calc_policy == THIN_CHUNK_SIZE_CALC_METHOD_PERFORMANCE)
+ hint = dev_optimal_io_size(cmd->dev_types, pv_dev(pv));
+ else
+ hint = dev_minimum_io_size(cmd->dev_types, pv_dev(pv));
+ if (!hint)
+ continue;
+ if (previous_hint)
+ hint = _lcm(previous_hint, hint);
+ previous_hint = hint;
+ }
+
+ if (!hint)
+ log_debug_alloc("No usable device hint found while recalculating "
+ "pool chunk size for %s.", display_lvname(pool_lv));
+ else if ((hint < min_chunk_size) || (hint > max_chunk_size))
+ log_debug_alloc("Calculated chunk size %s for pool %s "
+ "is out of allowed range (%s-%s).",
+ display_size(cmd, hint), display_lvname(pool_lv),
+ display_size(cmd, min_chunk_size),
+ display_size(cmd, max_chunk_size));
+ else
+ first_seg(pool_lv)->chunk_size =
+ (hint >= default_chunk_size) ? hint : default_chunk_size;
+
+ return 1;
+}
+
+int update_pool_params(const struct segment_type *segtype,
+ struct volume_group *vg, unsigned target_attr,
+ int passed_args, uint32_t data_extents,
+ uint64_t *pool_metadata_size,
+ int *chunk_size_calc_policy, uint32_t *chunk_size,
+ thin_discards_t *discards, int *zero)
+{
+ if (segtype_is_cache_pool(segtype) || segtype_is_cache(segtype)) {
+ if (!update_cache_pool_params(vg, target_attr, passed_args,
+ data_extents, pool_metadata_size,
+ chunk_size_calc_policy, chunk_size))
+ return_0;
+ } else if (!update_thin_pool_params(vg, target_attr, passed_args,
+ data_extents, pool_metadata_size,
+ chunk_size_calc_policy, chunk_size,
+ discards, zero)) /* thin-pool */
+ return_0;
+
+ if ((uint64_t) *chunk_size > (uint64_t) data_extents * vg->extent_size) {
+ log_error("Chunk size %s is bigger then pool data size.",
+ display_size(vg->cmd, *chunk_size));
+ return 0;
+ }
+
+ log_verbose("Using pool metadata size %s.",
+ display_size(vg->cmd, *pool_metadata_size));
+
+ return 1;
+}
+
int create_pool(struct logical_volume *pool_lv,
const struct segment_type *segtype,
struct alloc_handle *ah, uint32_t stripes, uint32_t stripe_size)
diff --git a/lib/metadata/thin_manip.c b/lib/metadata/thin_manip.c
index 28b6bbf..07246f7 100644
--- a/lib/metadata/thin_manip.c
+++ b/lib/metadata/thin_manip.c
@@ -348,11 +348,16 @@ int update_pool_lv(struct logical_volume *lv, int activate)
return 1;
}
-int update_profilable_pool_params(struct cmd_context *cmd, struct profile *profile,
- int passed_args, int *chunk_size_calc_method,
- uint32_t *chunk_size, thin_discards_t *discards,
- int *zero)
+int update_thin_pool_params(struct volume_group *vg,
+ unsigned attr, int passed_args, uint32_t data_extents,
+ uint64_t *pool_metadata_size,
+ int *chunk_size_calc_method, uint32_t *chunk_size,
+ thin_discards_t *discards, int *zero)
{
+ struct cmd_context *cmd = vg->cmd;
+ struct profile *profile = vg->profile;
+ uint32_t extent_size = vg->extent_size;
+ size_t estimate_chunk_size;
const char *str;
if (!(passed_args & PASS_ARG_CHUNK_SIZE)) {
@@ -369,7 +374,8 @@ int update_profilable_pool_params(struct cmd_context *cmd, struct profile *profi
log_error("Thin pool chunk size calculation policy \"%s\" is unrecognised.", str);
return 0;
}
- *chunk_size = get_default_allocation_thin_pool_chunk_size_CFG(cmd, profile) * 2;
+ if (!(*chunk_size = get_default_allocation_thin_pool_chunk_size_CFG(cmd, profile)))
+ return_0;
}
}
@@ -393,24 +399,6 @@ int update_profilable_pool_params(struct cmd_context *cmd, struct profile *profi
if (!(passed_args & PASS_ARG_ZERO))
*zero = find_config_tree_bool(cmd, allocation_thin_pool_zero_CFG, profile);
- return 1;
-}
-
-int update_thin_pool_params(struct volume_group *vg, unsigned attr,
- int passed_args,
- uint32_t data_extents, uint32_t extent_size,
- int *chunk_size_calc_method, uint32_t *chunk_size,
- thin_discards_t *discards,
- uint64_t *pool_metadata_size, int *zero)
-{
- size_t estimate_chunk_size;
- struct cmd_context *cmd = vg->cmd;
-
- if (!update_profilable_pool_params(cmd, vg->profile, passed_args,
- chunk_size_calc_method, chunk_size,
- discards, zero))
- return_0;
-
if (!(attr & THIN_FEATURE_BLOCK_SIZE) &&
(*chunk_size & (*chunk_size - 1))) {
log_error("Chunk size must be a power of 2 for this thin target version.");
@@ -435,11 +423,10 @@ int update_thin_pool_params(struct volume_group *vg, unsigned attr,
}
log_verbose("Setting chunk size to %s.",
display_size(cmd, *chunk_size));
- } else if (*pool_metadata_size > (2 * DEFAULT_THIN_POOL_MAX_METADATA_SIZE)) {
+ } else if (*pool_metadata_size > (DEFAULT_THIN_POOL_MAX_METADATA_SIZE * 2)) {
/* Suggest bigger chunk size */
estimate_chunk_size = (uint64_t) data_extents * extent_size /
- (2 * DEFAULT_THIN_POOL_MAX_METADATA_SIZE *
- (SECTOR_SIZE / UINT64_C(64)));
+ (DEFAULT_THIN_POOL_MAX_METADATA_SIZE * 2 * (SECTOR_SIZE / UINT64_C(64)));
log_warn("WARNING: Chunk size is too small for pool, suggested minimum is %s.",
display_size(cmd, UINT64_C(1) << (ffs(estimate_chunk_size) + 1)));
}
@@ -448,19 +435,17 @@ int update_thin_pool_params(struct volume_group *vg, unsigned attr,
if (*pool_metadata_size % extent_size)
*pool_metadata_size += extent_size - *pool_metadata_size % extent_size;
} else {
- estimate_chunk_size = (uint64_t) data_extents * extent_size /
+ estimate_chunk_size = (uint64_t) data_extents * extent_size /
(*pool_metadata_size * (SECTOR_SIZE / UINT64_C(64)));
+ if (estimate_chunk_size < DM_THIN_MIN_DATA_BLOCK_SIZE)
+ estimate_chunk_size = DM_THIN_MIN_DATA_BLOCK_SIZE;
+ else if (estimate_chunk_size > DM_THIN_MAX_DATA_BLOCK_SIZE)
+ estimate_chunk_size = DM_THIN_MAX_DATA_BLOCK_SIZE;
+
/* Check to eventually use bigger chunk size */
if (!(passed_args & PASS_ARG_CHUNK_SIZE)) {
*chunk_size = estimate_chunk_size;
-
- if (*chunk_size < DM_THIN_MIN_DATA_BLOCK_SIZE)
- *chunk_size = DM_THIN_MIN_DATA_BLOCK_SIZE;
- else if (*chunk_size > DM_THIN_MAX_DATA_BLOCK_SIZE)
- *chunk_size = DM_THIN_MAX_DATA_BLOCK_SIZE;
-
- log_verbose("Setting chunk size %s.",
- display_size(cmd, *chunk_size));
+ log_verbose("Setting chunk size %s.", display_size(cmd, *chunk_size));
} else if (*chunk_size < estimate_chunk_size) {
/* Suggest bigger chunk size */
log_warn("WARNING: Chunk size is smaller then suggested minimum size %s.",
@@ -468,11 +453,6 @@ int update_thin_pool_params(struct volume_group *vg, unsigned attr,
}
}
- if ((uint64_t) *chunk_size > (uint64_t) data_extents * extent_size) {
- log_error("Chunk size is bigger then pool data size.");
- return 0;
- }
-
if (*pool_metadata_size > (2 * DEFAULT_THIN_POOL_MAX_METADATA_SIZE)) {
*pool_metadata_size = 2 * DEFAULT_THIN_POOL_MAX_METADATA_SIZE;
if (passed_args & PASS_ARG_POOL_METADATA_SIZE)
@@ -485,9 +465,6 @@ int update_thin_pool_params(struct volume_group *vg, unsigned attr,
display_size(cmd, *pool_metadata_size));
}
- log_verbose("Setting pool metadata size to %s.",
- display_size(cmd, *pool_metadata_size));
-
return 1;
}
diff --git a/tools/lvconvert.c b/tools/lvconvert.c
index 61b1660..333459d 100644
--- a/tools/lvconvert.c
+++ b/tools/lvconvert.c
@@ -290,38 +290,24 @@ static int _read_pool_params(struct lvconvert_params *lp, struct cmd_context *cm
if (thinpool || cachepool) {
if (arg_from_list_is_set(cmd, "is invalid with pools",
merge_ARG, mirrors_ARG, repair_ARG, snapshot_ARG,
- splitmirrors_ARG, -1))
+ splitmirrors_ARG, splitsnapshot_ARG, -1))
return_0;
- if (arg_count(cmd, poolmetadatasize_ARG)) {
- if (arg_sign_value(cmd, poolmetadatasize_ARG, SIGN_NONE) == SIGN_MINUS) {
- log_error("Negative pool metadata size is invalid.");
- return 0;
- }
- if (arg_count(cmd, poolmetadata_ARG)) {
- log_error("Please specify either metadata logical volume or its size.");
- return 0;
- }
- /* value is read in get_pool_params() */
- }
-
- if ((lp->pool_metadata_lv_name = arg_str_value(cmd, poolmetadata_ARG, NULL))) {
- if (arg_count(cmd, stripesize_ARG) || arg_count(cmd, stripes_long_ARG)) {
- log_error("Can't use --stripes and --stripesize with --poolmetadata.");
- return 0;
- }
+ if (!(lp->segtype = get_segtype_from_string(cmd, type_str)))
+ return_0;
- if (arg_count(cmd, readahead_ARG)) {
- log_error("Can't use --readahead with --poolmetadata.");
- return 0;
- }
- }
+ if (!get_pool_params(cmd, lp->segtype, &lp->passed_args,
+ &lp->pool_metadata_size,
+ &lp->poolmetadataspare,
+ &lp->chunk_size, &lp->discards,
+ &lp->zero))
+ return_0;
- if (arg_count(cmd, chunksize_ARG) &&
- (arg_sign_value(cmd, chunksize_ARG, SIGN_NONE) == SIGN_MINUS)) {
- log_error("Negative chunk size is invalid.");
- return 0;
- }
+ if ((lp->pool_metadata_lv_name = arg_str_value(cmd, poolmetadata_ARG, NULL)) &&
+ arg_from_list_is_set(cmd, "is invalid with --poolmetadata",
+ stripesize_ARG, stripes_long_ARG,
+ readahead_ARG, -1))
+ return_0;
if (!lp->pool_data_lv_name) {
if (!*pargc) {
@@ -334,12 +320,11 @@ static int _read_pool_params(struct lvconvert_params *lp, struct cmd_context *cm
if (!lp->thin && !lp->cache)
lp->lv_name_full = lp->pool_data_lv_name;
+
/* Hmm _read_activation_params */
lp->read_ahead = arg_uint_value(cmd, readahead_ARG,
cmd->default_settings.read_ahead);
- if (!(lp->segtype = get_segtype_from_string(cmd, type_str)))
- return_0;
} else if (arg_from_list_is_set(cmd, "is valid only with pools",
poolmetadatasize_ARG, poolmetadataspare_ARG,
-1))
@@ -638,9 +623,6 @@ static int _read_params(struct lvconvert_params *lp, struct cmd_context *cmd,
} /* else segtype will default to current type */
}
- /* TODO: default in lvm.conf ? */
- lp->poolmetadataspare = arg_int_value(cmd, poolmetadataspare_ARG,
- DEFAULT_POOL_METADATA_SPARE);
lp->force = arg_count(cmd, force_ARG);
lp->yes = arg_count(cmd, yes_ARG);
@@ -2663,26 +2645,16 @@ revert_new_lv:
static int _lvconvert_update_pool_params(struct logical_volume *pool_lv,
struct lvconvert_params *lp)
{
- if (seg_is_cache_pool(lp))
- return update_cache_pool_params(pool_lv->vg, lp->target_attr,
- lp->passed_args,
- pool_lv->le_count,
- pool_lv->vg->extent_size,
- &lp->thin_chunk_size_calc_policy,
- &lp->chunk_size,
- &lp->discards,
- &lp->pool_metadata_size,
- &lp->zero);
-
- return update_thin_pool_params(pool_lv->vg, lp->target_attr,
- lp->passed_args,
- pool_lv->le_count,
- pool_lv->vg->extent_size,
- &lp->thin_chunk_size_calc_policy,
- &lp->chunk_size,
- &lp->discards,
- &lp->pool_metadata_size,
- &lp->zero);
+ return update_pool_params(lp->segtype,
+ pool_lv->vg,
+ lp->target_attr,
+ lp->passed_args,
+ pool_lv->le_count,
+ &lp->pool_metadata_size,
+ &lp->thin_chunk_size_calc_policy,
+ &lp->chunk_size,
+ &lp->discards,
+ &lp->zero);
}
/*
@@ -3156,12 +3128,6 @@ static int _lvconvert_single(struct cmd_context *cmd, struct logical_volume *lv,
if (!_lvconvert_snapshot(cmd, lv, lp))
return_ECMD_FAILED;
} else if (segtype_is_pool(lp->segtype) || lp->thin || lp->cache) {
- if (!get_pool_params(cmd, lv_config_profile(lv),
- &lp->passed_args, &lp->thin_chunk_size_calc_policy,
- &lp->chunk_size, &lp->discards,
- &lp->pool_metadata_size, &lp->zero))
- return_ECMD_FAILED;
-
if (!_lvconvert_pool(cmd, lv, lp))
return_ECMD_FAILED;
diff --git a/tools/lvcreate.c b/tools/lvcreate.c
index e9a170c..541fd51 100644
--- a/tools/lvcreate.c
+++ b/tools/lvcreate.c
@@ -267,20 +267,11 @@ static int _determine_snapshot_type(struct volume_group *vg,
static int _lvcreate_update_pool_params(struct volume_group *vg,
struct lvcreate_params *lp)
{
- if (seg_is_cache_pool(lp))
- return update_cache_pool_params(vg, lp->target_attr,
- lp->passed_args,
- lp->extents, vg->extent_size,
- &lp->thin_chunk_size_calc_policy,
- &lp->chunk_size, &lp->discards,
- &lp->poolmetadatasize,
- &lp->zero);
-
- return update_thin_pool_params(vg, lp->target_attr, lp->passed_args,
- lp->extents, vg->extent_size,
- &lp->thin_chunk_size_calc_policy,
- &lp->chunk_size, &lp->discards,
- &lp->poolmetadatasize, &lp->zero);
+ return update_pool_params(lp->segtype, vg, lp->target_attr,
+ lp->passed_args, lp->extents,
+ &lp->poolmetadatasize,
+ &lp->thin_chunk_size_calc_policy, &lp->chunk_size,
+ &lp->discards, &lp->zero);
}
/*
@@ -320,9 +311,6 @@ static int _determine_cache_argument(struct volume_group *vg,
} else {
lp->pool = NULL;
lp->create_pool = 1;
- lp->poolmetadataspare = arg_int_value(vg->cmd,
- poolmetadataspare_ARG,
- DEFAULT_POOL_METADATA_SPARE);
}
return 1;
@@ -505,7 +493,7 @@ static int _read_size_params(struct lvcreate_params *lp,
lp->create_pool = 1;
if (!lp->create_pool && arg_count(cmd, poolmetadatasize_ARG)) {
- log_error("--poolmetadatasize may only be specified when allocating the thin pool.");
+ log_error("--poolmetadatasize may only be specified when allocating the pool.");
return 0;
}
@@ -705,14 +693,6 @@ static int _read_cache_pool_params(struct lvcreate_params *lp,
if (!segtype_is_cache_pool(lp->segtype))
return 1;
- if (arg_sign_value(cmd, chunksize_ARG, SIGN_NONE) == SIGN_MINUS) {
- log_error("Negative chunk size is invalid.");
- return 0;
- }
-
- lp->chunk_size = arg_uint_value(cmd, chunksize_ARG,
- DEFAULT_CACHE_POOL_CHUNK_SIZE * 2);
-
if ((str_arg = arg_str_value(cmd, cachemode_ARG, NULL)) &&
!get_cache_mode(str_arg, &lp->feature_flags))
return_0;
@@ -884,6 +864,8 @@ static int _lvcreate_params(struct lvcreate_params *lp,
}
else if (arg_count(cmd, thin_ARG) || arg_count(cmd, thinpool_ARG))
segtype_str = "thin";
+ else if (arg_count(cmd, cache_ARG) || arg_count(cmd, cachepool_ARG))
+ segtype_str = "cache";
else
segtype_str = "striped";
@@ -907,12 +889,9 @@ static int _lvcreate_params(struct lvcreate_params *lp,
(!seg_is_thin(lp) && arg_count(cmd, virtualsize_ARG)))
lp->snapshot = 1;
- if (seg_is_cache_pool(lp))
- lp->create_pool = 1;
-
- if (seg_is_thin_pool(lp)) {
+ if (seg_is_pool(lp)) {
if (lp->snapshot) {
- log_error("Snapshots are incompatible with thin_pool segment_type.");
+ log_error("Snapshots are incompatible with pool segment_type.");
return 0;
}
lp->create_pool = 1;
@@ -1035,10 +1014,9 @@ static int _lvcreate_params(struct lvcreate_params *lp,
!_read_size_params(lp, lcp, cmd) ||
!get_stripe_params(cmd, &lp->stripes, &lp->stripe_size) ||
(lp->create_pool &&
- !get_pool_params(cmd, NULL, &lp->passed_args,
- &lp->thin_chunk_size_calc_policy,
- &lp->chunk_size, &lp->discards,
- &lp->poolmetadatasize, &lp->zero)) ||
+ !get_pool_params(cmd, lp->segtype, &lp->passed_args,
+ &lp->poolmetadatasize, &lp->poolmetadataspare,
+ &lp->chunk_size, &lp->discards, &lp->zero)) ||
!_read_mirror_params(lp, cmd) ||
!_read_raid_params(lp, cmd) ||
!_read_cache_pool_params(lp, cmd))
@@ -1061,12 +1039,9 @@ static int _lvcreate_params(struct lvcreate_params *lp,
return 0;
}
- if (lp->create_pool) {
- /* TODO: add lvm.conf default y|n */
- lp->poolmetadataspare = arg_int_value(cmd, poolmetadataspare_ARG,
- DEFAULT_POOL_METADATA_SPARE);
- } else if (arg_count(cmd, poolmetadataspare_ARG)) {
- log_error("--poolmetadataspare is only available with thin pool creation.");
+ if (!lp->create_pool &&
+ arg_count(cmd, poolmetadataspare_ARG)) {
+ log_error("--poolmetadataspare is only available with pool creation.");
return 0;
}
/*
diff --git a/tools/toollib.c b/tools/toollib.c
index 312a76d..d6ef845 100644
--- a/tools/toollib.c
+++ b/tools/toollib.c
@@ -1650,59 +1650,68 @@ int get_activation_monitoring_mode(struct cmd_context *cmd,
return 1;
}
+/*
+ * Read pool options from cmdline
+ */
int get_pool_params(struct cmd_context *cmd,
- struct profile *profile,
+ const struct segment_type *segtype,
int *passed_args,
- int *chunk_size_calc_method,
+ uint64_t *pool_metadata_size,
+ int *pool_metadata_spare,
uint32_t *chunk_size,
thin_discards_t *discards,
- uint64_t *pool_metadata_size,
int *zero)
{
- int cache_pool = 0;
-
- if (!strcmp("cache-pool", arg_str_value(cmd, type_ARG, "")))
- cache_pool = 1;
-
*passed_args = 0;
- if (!cache_pool && arg_count(cmd, zero_ARG)) {
- *passed_args |= PASS_ARG_ZERO;
- *zero = strcmp(arg_str_value(cmd, zero_ARG, "y"), "n");
- log_very_verbose("Setting pool zeroing: %u", *zero);
- }
- if (!cache_pool && arg_count(cmd, discards_ARG)) {
- *passed_args |= PASS_ARG_DISCARDS;
- *discards = (thin_discards_t) arg_uint_value(cmd, discards_ARG, 0);
- log_very_verbose("Setting pool discards: %s",
- get_pool_discards_name(*discards));
+ if (segtype_is_thin_pool(segtype) || segtype_is_thin(segtype)) {
+ if (arg_count(cmd, zero_ARG)) {
+ *passed_args |= PASS_ARG_ZERO;
+ *zero = strcmp(arg_str_value(cmd, zero_ARG, "y"), "n");
+ log_very_verbose("Setting pool zeroing: %u", *zero);
+ }
+
+ if (arg_count(cmd, discards_ARG)) {
+ *passed_args |= PASS_ARG_DISCARDS;
+ *discards = (thin_discards_t) arg_uint_value(cmd, discards_ARG, 0);
+ log_very_verbose("Setting pool discards: %s",
+ get_pool_discards_name(*discards));
+ }
}
if (arg_count(cmd, chunksize_ARG)) {
+ if (arg_sign_value(cmd, chunksize_ARG, SIGN_NONE) == SIGN_MINUS) {
+ log_error("Negative chunk size is invalid.");
+ return 0;
+ }
+
*passed_args |= PASS_ARG_CHUNK_SIZE;
- *chunk_size = arg_uint_value(cmd, chunksize_ARG, cache_pool ?
- DM_CACHE_MIN_DATA_BLOCK_SIZE :
- DM_THIN_MIN_DATA_BLOCK_SIZE);
+ *chunk_size = arg_uint_value(cmd, chunksize_ARG, 0);
log_very_verbose("Setting pool chunk size: %s",
display_size(cmd, *chunk_size));
}
- if (cache_pool) {
- //FIXME: add cache_pool support to update_profilable_pool_params
- if (!(*passed_args & PASS_ARG_CHUNK_SIZE))
- *chunk_size = DEFAULT_CACHE_POOL_CHUNK_SIZE * 2;
- } else if (!update_profilable_pool_params(cmd, profile, *passed_args,
- chunk_size_calc_method,
- chunk_size, discards, zero))
- return_0;
-
if (arg_count(cmd, poolmetadatasize_ARG)) {
+ if (arg_sign_value(cmd, poolmetadatasize_ARG, SIGN_NONE) == SIGN_MINUS) {
+ log_error("Negative pool metadata size is invalid.");
+ return 0;
+ }
+
+ if (arg_count(cmd, poolmetadata_ARG)) {
+ log_error("Please specify either metadata logical volume or its size.");
+ return 0;
+ }
+
*passed_args |= PASS_ARG_POOL_METADATA_SIZE;
*pool_metadata_size = arg_uint64_value(cmd, poolmetadatasize_ARG,
UINT64_C(0));
} else if (arg_count(cmd, poolmetadata_ARG))
*passed_args |= PASS_ARG_POOL_METADATA_SIZE; /* fixed size */
+ /* TODO: default in lvm.conf ? */
+ *pool_metadata_spare = arg_int_value(cmd, poolmetadataspare_ARG,
+ DEFAULT_POOL_METADATA_SPARE);
+
return 1;
}
diff --git a/tools/toollib.h b/tools/toollib.h
index 54636ab..b51c637 100644
--- a/tools/toollib.h
+++ b/tools/toollib.h
@@ -125,12 +125,12 @@ int get_activation_monitoring_mode(struct cmd_context *cmd,
int *monitoring_mode);
int get_pool_params(struct cmd_context *cmd,
- struct profile *profile,
+ const struct segment_type *segtype,
int *passed_args,
- int *chunk_size_calc_method,
+ uint64_t *pool_metadata_size,
+ int *pool_metadataspare,
uint32_t *chunk_size,
thin_discards_t *discards,
- uint64_t *pool_metadata_size,
int *zero);
int get_stripe_params(struct cmd_context *cmd, uint32_t *stripes,
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=8c56c5fbacf6a4e9…
Commit: 8c56c5fbacf6a4e9a0130b6f1fdc5683d6f108ec
Parent: ab7bcc26f60edd529fc498a856f0dde2479919be
Author: Zdenek Kabelac <zkabelac(a)redhat.com>
AuthorDate: Fri Jul 18 12:19:40 2014 +0200
Committer: Zdenek Kabelac <zkabelac(a)redhat.com>
CommitterDate: Tue Jul 22 22:38:59 2014 +0200
lvconvert: better testing order
Avoid duplicate tests through implicit calls - check directly
result of string assignment.
---
tools/lvconvert.c | 49 ++++++++++++++++++++-----------------------------
1 files changed, 20 insertions(+), 29 deletions(-)
diff --git a/tools/lvconvert.c b/tools/lvconvert.c
index 206c041..61b1660 100644
--- a/tools/lvconvert.c
+++ b/tools/lvconvert.c
@@ -234,7 +234,7 @@ static int _read_pool_params(struct lvconvert_params *lp, struct cmd_context *cm
int cachepool = 0;
int thinpool = 0;
- if (arg_count(cmd, cachepool_ARG)) {
+ if ((lp->pool_data_lv_name = arg_str_value(cmd, cachepool_ARG, NULL))) {
if (type_str[0] &&
strcmp(type_str, "cache") &&
strcmp(type_str, "cache-pool")) {
@@ -242,13 +242,11 @@ static int _read_pool_params(struct lvconvert_params *lp, struct cmd_context *cm
" the cache or cache-pool segment type.");
return 0;
}
- lp->pool_data_lv_name = arg_str_value(cmd, cachepool_ARG, NULL);
cachepool = 1;
type_str = "cache-pool";
} else if (!strcmp(type_str, "cache-pool"))
cachepool = 1;
-
- if (arg_count(cmd, thinpool_ARG)) {
+ else if ((lp->pool_data_lv_name = arg_str_value(cmd, thinpool_ARG, NULL))) {
if (type_str[0] &&
strcmp(type_str, "thin") &&
strcmp(type_str, "thin-pool")) {
@@ -256,33 +254,18 @@ static int _read_pool_params(struct lvconvert_params *lp, struct cmd_context *cm
" the thin or thin-pool segment type.");
return 0;
}
- lp->pool_data_lv_name = arg_str_value(cmd, thinpool_ARG, NULL);
thinpool = 1;
type_str = "thin-pool";
} else if (!strcmp(type_str, "thin-pool"))
thinpool = 1;
- if (thinpool) {
- lp->discards = (thin_discards_t) arg_uint_value(cmd, discards_ARG, THIN_DISCARDS_PASSDOWN);
- lp->origin_lv_name = arg_str_value(cmd, originname_ARG, NULL);
- } else {
- if (arg_from_list_is_set(cmd, "is valid only with thin pools",
- discards_ARG, originname_ARG, zero_ARG,
- -1))
- return_0;
- if (lp->thin) {
- log_error("--thin requires --thinpool.");
- return 0;
- }
- }
-
if (cachepool) {
if ((tmp_str = arg_str_value(cmd, cachemode_ARG, NULL)) &&
!get_cache_mode(tmp_str, &lp->feature_flags))
return_0;
} else {
if (arg_from_list_is_set(cmd, "is valid only with cache pools",
- cachemode_ARG, -1))
+ cachepool_ARG, cachemode_ARG, -1))
return_0;
if (lp->cache) {
log_error("--cache requires --cachepool.");
@@ -290,6 +273,20 @@ static int _read_pool_params(struct lvconvert_params *lp, struct cmd_context *cm
}
}
+ if (thinpool) {
+ lp->discards = (thin_discards_t) arg_uint_value(cmd, discards_ARG, THIN_DISCARDS_PASSDOWN);
+ lp->origin_lv_name = arg_str_value(cmd, originname_ARG, NULL);
+ } else {
+ if (arg_from_list_is_set(cmd, "is valid only with thin pools",
+ discards_ARG, originname_ARG, thinpool_ARG,
+ zero_ARG, -1))
+ return_0;
+ if (lp->thin) {
+ log_error("--thin requires --thinpool.");
+ return 0;
+ }
+ }
+
if (thinpool || cachepool) {
if (arg_from_list_is_set(cmd, "is invalid with pools",
merge_ARG, mirrors_ARG, repair_ARG, snapshot_ARG,
@@ -308,7 +305,7 @@ static int _read_pool_params(struct lvconvert_params *lp, struct cmd_context *cm
/* value is read in get_pool_params() */
}
- if (arg_count(cmd, poolmetadata_ARG)) {
+ if ((lp->pool_metadata_lv_name = arg_str_value(cmd, poolmetadata_ARG, NULL))) {
if (arg_count(cmd, stripesize_ARG) || arg_count(cmd, stripes_long_ARG)) {
log_error("Can't use --stripes and --stripesize with --poolmetadata.");
return 0;
@@ -318,11 +315,6 @@ static int _read_pool_params(struct lvconvert_params *lp, struct cmd_context *cm
log_error("Can't use --readahead with --poolmetadata.");
return 0;
}
-
- if (!(lp->pool_metadata_lv_name = arg_str_value(cmd, poolmetadata_ARG, NULL))) {
- log_error("Missing --poolmetadata argument.");
- return 0;
- }
}
if (arg_count(cmd, chunksize_ARG) &&
@@ -331,14 +323,13 @@ static int _read_pool_params(struct lvconvert_params *lp, struct cmd_context *cm
return 0;
}
- if (!arg_count(cmd, cachepool_ARG) &&
- !arg_count(cmd, thinpool_ARG)) {
+ if (!lp->pool_data_lv_name) {
if (!*pargc) {
log_error("Please specify the pool data LV.");
return 0;
}
lp->pool_data_lv_name = (*pargv)[0];
- (*pargv)++, (*pargc)--;
+ (*pargv)++, (*pargc)--;
}
if (!lp->thin && !lp->cache)
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=ab7bcc26f60edd52…
Commit: ab7bcc26f60edd529fc498a856f0dde2479919be
Parent: 864ff3cb181183ccfabc8a2e3c53ddcd1e36390f
Author: Zdenek Kabelac <zkabelac(a)redhat.com>
AuthorDate: Fri Jul 18 21:56:37 2014 +0200
Committer: Zdenek Kabelac <zkabelac(a)redhat.com>
CommitterDate: Tue Jul 22 22:38:59 2014 +0200
tools: switch logic for new arg_ func
Revert logic and rename new arg_ functions to:
arg_from_list_is_set()
arg_outside_list_is_set()
When err_found is given, log_error message is automaticaly
printed.
---
tools/lvconvert.c | 58 ++++++++++++++++++++++++++--------------------------
tools/lvmcmdline.c | 28 ++++++++++++++----------
tools/tools.h | 4 +-
3 files changed, 47 insertions(+), 43 deletions(-)
diff --git a/tools/lvconvert.c b/tools/lvconvert.c
index 63a1d98..206c041 100644
--- a/tools/lvconvert.c
+++ b/tools/lvconvert.c
@@ -266,9 +266,9 @@ static int _read_pool_params(struct lvconvert_params *lp, struct cmd_context *cm
lp->discards = (thin_discards_t) arg_uint_value(cmd, discards_ARG, THIN_DISCARDS_PASSDOWN);
lp->origin_lv_name = arg_str_value(cmd, originname_ARG, NULL);
} else {
- if (!arg_is_any_set(cmd, "is valid only with thin pools",
- discards_ARG, originname_ARG, zero_ARG,
- -1))
+ if (arg_from_list_is_set(cmd, "is valid only with thin pools",
+ discards_ARG, originname_ARG, zero_ARG,
+ -1))
return_0;
if (lp->thin) {
log_error("--thin requires --thinpool.");
@@ -281,8 +281,8 @@ static int _read_pool_params(struct lvconvert_params *lp, struct cmd_context *cm
!get_cache_mode(tmp_str, &lp->feature_flags))
return_0;
} else {
- if (!arg_is_any_set(cmd, "is valid only with cache pools",
- cachemode_ARG, -1))
+ if (arg_from_list_is_set(cmd, "is valid only with cache pools",
+ cachemode_ARG, -1))
return_0;
if (lp->cache) {
log_error("--cache requires --cachepool.");
@@ -291,9 +291,9 @@ static int _read_pool_params(struct lvconvert_params *lp, struct cmd_context *cm
}
if (thinpool || cachepool) {
- if (!arg_is_any_set(cmd, "is invalid with pools",
- merge_ARG, mirrors_ARG, repair_ARG, snapshot_ARG,
- splitmirrors_ARG, -1))
+ if (arg_from_list_is_set(cmd, "is invalid with pools",
+ merge_ARG, mirrors_ARG, repair_ARG, snapshot_ARG,
+ splitmirrors_ARG, -1))
return_0;
if (arg_count(cmd, poolmetadatasize_ARG)) {
@@ -349,9 +349,9 @@ static int _read_pool_params(struct lvconvert_params *lp, struct cmd_context *cm
if (!(lp->segtype = get_segtype_from_string(cmd, type_str)))
return_0;
- } else if (!arg_is_any_set(cmd, "is valid only with pools",
- poolmetadatasize_ARG, poolmetadataspare_ARG,
- -1))
+ } else if (arg_from_list_is_set(cmd, "is valid only with pools",
+ poolmetadatasize_ARG, poolmetadataspare_ARG,
+ -1))
return_0;
return 1;
@@ -374,12 +374,12 @@ static int _read_params(struct lvconvert_params *lp, struct cmd_context *cmd,
return_0;
if (arg_count(cmd, repair_ARG) &&
- !arg_is_only_set(cmd, "cannot be used with --repair",
- repair_ARG,
- alloc_ARG, use_policies_ARG,
- stripes_long_ARG, stripesize_ARG,
- force_ARG, noudevsync_ARG, test_ARG,
- -1))
+ arg_outside_list_is_set(cmd, "cannot be used with --repair",
+ repair_ARG,
+ alloc_ARG, use_policies_ARG,
+ stripes_long_ARG, stripesize_ARG,
+ force_ARG, noudevsync_ARG, test_ARG,
+ -1))
return_0;
if (arg_is_set(cmd, mirrorlog_ARG) && arg_is_set(cmd, corelog_ARG)) {
@@ -388,10 +388,10 @@ static int _read_params(struct lvconvert_params *lp, struct cmd_context *cmd,
}
if (arg_is_set(cmd, splitsnapshot_ARG)) {
- if (!arg_is_only_set(cmd, "cannot be used with --splitsnapshot",
- splitsnapshot_ARG,
- force_ARG, noudevsync_ARG, test_ARG,
- -1))
+ if (arg_outside_list_is_set(cmd, "cannot be used with --splitsnapshot",
+ splitsnapshot_ARG,
+ force_ARG, noudevsync_ARG, test_ARG,
+ -1))
return_0;
lp->splitsnapshot = 1;
}
@@ -504,11 +504,11 @@ static int _read_params(struct lvconvert_params *lp, struct cmd_context *cmd,
/* There are six types of lvconvert. */
if (lp->merge) { /* Snapshot merge */
- if (!arg_is_only_set(cmd, "cannot be used with --merge",
- merge_ARG,
- background_ARG, interval_ARG,
- force_ARG, noudevsync_ARG, test_ARG,
- -1))
+ if (arg_outside_list_is_set(cmd, "cannot be used with --merge",
+ merge_ARG,
+ background_ARG, interval_ARG,
+ force_ARG, noudevsync_ARG, test_ARG,
+ -1))
return_0;
if (!(lp->segtype = get_segtype_from_string(cmd, "snapshot")))
@@ -2796,9 +2796,9 @@ static int _lvconvert_pool(struct cmd_context *cmd,
lp->pool_data_lv = pool_lv;
if (!metadata_lv) {
- if (!arg_is_any_set(cmd, "is invalid with existing pool",
- cachemode_ARG,chunksize_ARG, discards_ARG,
- zero_ARG, poolmetadatasize_ARG, -1))
+ if (arg_from_list_is_set(cmd, "is invalid with existing pool",
+ cachemode_ARG,chunksize_ARG, discards_ARG,
+ zero_ARG, poolmetadatasize_ARG, -1))
return_0;
return 1;
}
diff --git a/tools/lvmcmdline.c b/tools/lvmcmdline.c
index 4654978..10dac8f 100644
--- a/tools/lvmcmdline.c
+++ b/tools/lvmcmdline.c
@@ -68,25 +68,26 @@ unsigned arg_is_set(const struct cmd_context *cmd, int a)
return arg_count(cmd, a) ? 1 : 0;
}
-int arg_is_any_set(const struct cmd_context *cmd, const char *err, ...)
+int arg_from_list_is_set(const struct cmd_context *cmd, const char *err_found, ...)
{
int arg;
va_list ap;
- va_start(ap, err);
+ va_start(ap, err_found);
while ((arg = va_arg(ap, int)) != -1 && !arg_count(cmd, arg))
/* empty */;
va_end(ap);
- if (arg != -1) {
- log_error("%s %s.", arg_long_option_name(arg), err);
+ if (arg == -1)
return 0;
- }
+
+ if (err_found)
+ log_error("%s %s.", arg_long_option_name(arg), err_found);
return 1;
}
-int arg_is_only_set(const struct cmd_context *cmd, const char *err, ...)
+int arg_outside_list_is_set(const struct cmd_context *cmd, const char *err_found, ...)
{
int i, arg;
va_list ap;
@@ -109,18 +110,21 @@ int arg_is_only_set(const struct cmd_context *cmd, const char *err, ...)
}
if (!arg_count(cmd, i))
continue; /* unset */
- va_start(ap, err);
+ va_start(ap, err_found);
while (((arg = va_arg(ap, int)) != -1) && (arg != i))
/* empty */;
va_end(ap);
- if (arg != i) {
- log_error("Option %s %s.", arg_long_option_name(i), err);
- return 0;
- }
+ if (arg == i)
+ continue; /* set and in list */
+
+ if (err_found)
+ log_error("Option %s %s.", arg_long_option_name(i), err_found);
+
+ return 1;
}
- return 1;
+ return 0;
}
unsigned grouped_arg_is_set(const struct arg_values *av, int a)
diff --git a/tools/tools.h b/tools/tools.h
index a92845a..beb1671 100644
--- a/tools/tools.h
+++ b/tools/tools.h
@@ -144,8 +144,8 @@ int major_minor_valid(const struct cmd_context * cmd, const struct format_type *
/* we use the enums to access the switches */
unsigned arg_count(const struct cmd_context *cmd, int a);
unsigned arg_is_set(const struct cmd_context *cmd, int a);
-int arg_is_any_set(const struct cmd_context *cmd, const char *err, ...);
-int arg_is_only_set(const struct cmd_context *cmd, const char *err, ...);
+int arg_from_list_is_set(const struct cmd_context *cmd, const char *err_found, ...);
+int arg_outside_list_is_set(const struct cmd_context *cmd, const char *err_found, ...);
const char *arg_long_option_name(int a);
const char *arg_value(struct cmd_context *cmd, int a);
const char *arg_str_value(struct cmd_context *cmd, int a, const char *def);
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=864ff3cb181183cc…
Commit: 864ff3cb181183ccfabc8a2e3c53ddcd1e36390f
Parent: 50961f43d03aec309dd06e121d03a6fd7b301850
Author: David Teigland <teigland(a)redhat.com>
AuthorDate: Tue Jul 22 15:10:35 2014 -0500
Committer: David Teigland <teigland(a)redhat.com>
CommitterDate: Tue Jul 22 15:12:02 2014 -0500
man: rework lvmcache to match lvmthin
Reorganize and rewrite parts to match lvmthin(7).
---
man/lvmcache.7.in | 251 ++++++++++++++++++++++++++++++++--------------------
1 files changed, 154 insertions(+), 97 deletions(-)
diff --git a/man/lvmcache.7.in b/man/lvmcache.7.in
index 4b21a8a..cc92673 100644
--- a/man/lvmcache.7.in
+++ b/man/lvmcache.7.in
@@ -4,7 +4,7 @@ lvmcache \(em LVM caching
.SH DESCRIPTION
-The \fIcache\fP logical volume type uses a small and fast LV to improve
+The \fBcache\fP logical volume type uses a small and fast LV to improve
the performance of a large and slow LV. It does this by storing the
frequently used blocks on the faster LV.
LVM refers to the small fast LV as a \fBcache pool LV\fP. The large
@@ -27,59 +27,60 @@ cache pool LV CachePoolLV CacheDataLV + CacheMetaLV
cache LV CacheLV OriginLV + CachePoolLV
.fi
-.SH Cache Steps
-The steps to create a logical volume of \fIcache\fP type are as follows:
-.TP
-0.
-Create an LV or identify an existing LV to be the origin LV.
-.TP
-1.
-Create the cache data LV. The size of this LV is the size of the cache
-and will be reported as the size of the cache pool LV.
-.TP
-2.
-Create the cache metadata LV.
-The size of this LV should be 1000 times smaller than the cache data LV
-with a minimum size of 8MiB.
-.TP
-3.
-Create the cache pool LV by combining the cache data LV (from step 1)
-and cache metadata LV (from step 2). When performing this step,
-behavioral characteristics of the cache pool LV can be set.
-The name of the cache pool LV takes the name of the cache data LV and
-the cache data LV and cache metadata LV are renamed
-to CachePoolLV_cdata and CachePoolLV_cmeta.
-.TP
-4.
-Create a cache LV by linking the cache pool LV to the origin LV.
-The user accessible cache LV takes the name of the origin LV,
-while the origin LV becomes a hidden LV with the name
-OriginLV_corig. Users can perform this step while the origin LV
-is in use.
+.SH Cache Usage
-.P
-The steps above represent the best way to create a cache LV.
-They provide the most options and have the ability to create the
-most robust logical volumes. The examples below illustrate how these
-steps might be used in practice.
+The primary method for using a cache type logical volume:
-.SH Cache Commands
-0. create OriginLV
-.br
-.B lvcreate \-L LargeSize \-n OriginLV VG SlowPVs
+.SS 0. create OriginLV
-1. create CacheDataLV
+Create an LV or identify an existing LV to be the origin LV.
+
+.B lvcreate \-n OriginLV \-L LargeSize VG SlowPVs
+
+.I Example
.br
-.B lvcreate \-L CacheSize \-n CacheDataLV VG FastPVs
+# lvcreate \-n lvol0 \-L 100G vg
+
-2. create CacheMetaLV
+.SS 1. create CacheDataLV
+
+Create the cache data LV. This LV will hold data blocks from the
+OriginLV. The size of this LV is the size of the cache and will be
+reported as the size of the cache pool LV.
+
+.B lvcreate \-n CacheDataLV \-L CacheSize VG FastPVs
+
+.I Example
.br
-.B lvcreate \-L MetaSize \-n CacheMetaLV VG FastPVs
+# lvcreate \-n cache0 \-L 10G vg /dev/fast
+
-3. create CachePoolLV
+.SS 2. create CacheMetaLV
+
+Create the cache metadata LV. This LV will hold cache pool metadata. The
+size of this LV should be 1000 times smaller than the cache data LV, with
+a minimum size of 8MiB.
+
+.B lvcreate \-n CacheMetaLV \-L MetaSize VG FastPVs
+
+.I Example
.br
-.B lvconvert \-\-cachepool VG/CacheDataLV \-\-poolmetadata VG/CacheMetaLV
+# lvcreate \-n cache0meta \-L 12M vg /dev/fast
+
+.nf
+# lvs -a vg
+ LV VG Attr LSize Pool Origin
+ cache0 vg -wi-a----- 10.00g
+ cache0meta vg -wi-a----- 12.00m
+ lvol0 vg -wi-a----- 100.00g
+.fi
+
+
+.SS 3. create CachePoolLV
+
+Combine the data and metadata LVs into a cache pool LV.
+The behavior of the cache pool LV can be set in this step.
.br
CachePoolLV takes the name of CacheDataLV.
.br
@@ -87,44 +88,108 @@ CacheDataLV is renamed CachePoolLV_cdata and becomes hidden.
.br
CacheMetaLV is renamed CachePoolLV_cmeta and becomes hidden.
-4. create CacheLV
+.B lvconvert \-\-cachepool VG/CacheDataLV \-\-poolmetadata VG/CacheMetaLV
+
+.I Example
.br
-.B lvconvert \-\-type cache \-\-cachepool VG/CachePoolLV VG/OriginLV
+# lvconvert \-\-cachepool vg/cache0 \-\-poolmetadata vg/cache0meta
+
+.nf
+# lvs -a vg
+ LV VG Attr LSize Pool Origin
+ cache0 vg Cwi---C--- 10.00g
+ [cache0_cdata] vg Cwi------- 10.00g
+ [cache0_cmeta] vg ewi------- 12.00m
+ lvol0 vg -wi-a----- 100.00g
+.fi
+
+
+.SS 4. create CacheLV
+
+Create a cache LV by linking the cache pool LV to the origin LV.
+The user accessible cache LV takes the name of the origin LV,
+while the origin LV becomes a hidden LV with the name
+OriginLV_corig. This can be done while the origin LV is in use.
.br
CacheLV takes the name of OriginLV.
.br
OriginLV is renamed OriginLV_corig and becomes hidden.
+.B lvconvert \-\-type cache \-\-cachepool VG/CachePoolLV VG/OriginLV
-.SH Cache Examples
+.I Example
+.br
+# lvconvert \-\-type cache \-\-cachepool vg/cache0 vg/lvol0
+
+.nf
+# lvs -a vg
+ LV VG Attr LSize Pool Origin
+ cache0 vg Cwi---C--- 10.00g
+ [cache0_cdata] vg Cwi-ao---- 10.00g
+ [cache0_cmeta] vg ewi-ao---- 12.00m
+ lvol0 vg Cwi-a-C--- 100.00g cache0 [lvol0_corig]
+ [lvol0_corig] vg -wi-ao---- 100.00g
+.fi
+
+
+.SH Cache Removal
-.SS Example 1
-Create a simple cache LV.
+.SS Removing a cache pool LV without removing its linked origin LV
+\&
+
+This writes back data from the cache pool to the origin LV when necessary,
+then removes the cache pool LV, leaving the un-cached origin LV.
+
+.B lvremove VG/CachePoolLV
+
+.I Example
.nf
-0. Create the origin LV
-# lvcreate \-L 10G \-n lvx vg /dev/slow_dev
+# lvs vg
+ LV VG Attr LSize Pool Origin
+ cache0 vg Cwi---C--- 10.00g
+ lvol0 vg Cwi-a-C--- 100.00g cache0 [lvol0_corig]
-1. Create a cache data LV
-# lvcreate \-L 1G \-n lvx_cache vg /dev/fast_dev
+# lvremove vg/cache0
-2. Create a cache metadata LV (~1/1000th size of CacheDataLV or 8MiB)
-# lvcreate \-L 8M \-n lvx_cache_meta vg /dev/fast_dev
+# lvs vg
+ LV VG Attr LSize Pool Origin
+ lvol0 vg -wi-a----- 100.00g
+.fi
-3. Create a cache pool LV, combining cache data LV and cache metadata LV
-# lvconvert \-\-cachepool vg/lvx_cache \-\-poolmetadata vg/lvx_cache_meta
+.SS Removing an origin LV without removing its linked cache pool LV
-4. Create a cached LV by combining the cache pool LV and origin LV
-# lvconvert \-\-type cache \-\-cachepool vg/lvx_cache vg/lvx
+\&
+
+This removes the origin LV, leaving the cache pool LV which can be linked
+to another origin LV.
+
+.B lvremove VG/CacheLV
+
+.I Example
+.nf
+# lvs vg
+ LV VG Attr LSize Pool Origin
+ cache0 vg Cwi---C--- 10.00g
+ lvol0 vg Cwi-a-C--- 100.00g cache0 [lvol0_corig]
+
+# lvremove vg/lvol0
+
+# lvs vg
+ LV VG Attr LSize Pool Origin
+ cache0 vg Cwi---C--- 10.00g
.fi
-.SS Example 2
-Create a cache LV with a fault tolerant cache pool LV.
-Users who are concerned about the possibility of failures in their fast devices
-that could lead to data loss might consider making their cache pool sub-LVs
-redundant. Example 2 illustrates how to do that. Note that only steps
-1 & 2 change.
+.SH Cache Topics
+
+.SS Tolerate device failures in a cache pool LV
+
+\&
+
+Users who are concerned about the possibility of failures in their fast
+devices that could lead to data loss might consider making their cache
+pool sub-LVs redundant.
.nf
0. Create an origin LV we wish to cache
@@ -145,16 +210,16 @@ redundant. Example 2 illustrates how to do that. Note that only steps
# lvconvert \-\-type cache \-\-cachepool vg/lvx_cache vg/lvx
.fi
-.SS Example 3
-Create a simple cache LV with \fIwritethough\fP caching.
+.SS Writethough caching
-Some users wish to ensure that any data written will be stored both in the
-cache pool LV and on the origin LV. The loss of a device associated with
-the cache pool LV in this case would not mean the loss of any data. When
-combining the cache data LV and the cache metadata LV to form the cache pool
-LV, properties of the cache can be specified - in this case,
-\fIwritethrough\fP vs. \fIwriteback\fP. Note that only step 3 is affected
-in this case.
+\&
+
+Writethrough caching ensures that any data written will be stored both in
+the cache pool LV and on the origin LV. The loss of a device associated
+with the cache pool LV in this case would not mean the loss of any data.
+When combining the cache data LV and the cache metadata LV to form the
+cache pool LV, properties of the cache can be specified - in this case,
+\fIwritethrough\fP vs. \fIwriteback\fP.
.nf
0. Create an origin LV we wish to cache (yours may already exist)
@@ -174,35 +239,27 @@ in this case.
# lvconvert \-\-type cache \-\-cachepool vg/lvx_cache vg/lvx
.fi
-.SH Cache Removal
-
-.SS Removing a cache pool LV without removing an associated origin LV
+.SS Spare metadata LV
-This writes back data from the cache pool to the origin LV, then removes
-the cache pool LV, leaving the un-cached origin LV. (If the origin LV
-will also be removed, the data flushing can be avoided; see "Removing
-both" below.)
+\&
-.B lvremove VG/CachePoolLV
+See
+.BR lvmthin (7)
+for a description of the "pool metadata spare" LV.
+The same concept is used for cache pools.
-.SS Removing both an origin LV and its associated cache pool LV
+.SS Automatic pool metadata LV
-This removes the cache LV, which includes removing both the origin LV and
-its associated cache pool LV. Data blocks from the cache pool are not
-written back to the origin LV.
+\&
-.B lvremove VG/CacheLV
+A cache data LV can be converted to cache pool LV without specifying a
+cache pool metadata LV. LVM will automatically create a metadata LV from
+the same VG.
-./" .SS Separating a cache pool LV from an origin LV
-./" This writes back data from the cache pool to the origin LV, then removes
-./" the association between the cache pool LV and the origin LV.
-./" .br
-./" Not yet implemented.
+.B lvcreate -n CacheDataLV -L CacheSize VG
+.br
+.B lvconvert --cachepool VG/CacheDataLV
-./" .SS Removing an origin LV without removing an associated cache pool LV
-./" Separate the cache pool LV from the origin LV, then remove the origin LV.
-./" .br
-./" Not yet implemented.
.SH SEE ALSO
.BR lvm.conf (5),
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=50961f43d03aec30…
Commit: 50961f43d03aec309dd06e121d03a6fd7b301850
Parent: 99e3c1301294fdd1cd8be25adb303e24e1260c76
Author: Alasdair G Kergon <agk(a)redhat.com>
AuthorDate: Tue Jul 22 20:57:57 2014 +0100
Committer: Alasdair G Kergon <agk(a)redhat.com>
CommitterDate: Tue Jul 22 20:57:57 2014 +0100
report: Remove lv_target_type field.
This field is too complicated to be useful on its own and either needs
redefining or splitting up into multiple fields.
---
lib/report/columns.h | 2 +-
lib/report/properties.c | 5 ++---
lib/report/report.c | 2 ++
3 files changed, 5 insertions(+), 4 deletions(-)
diff --git a/lib/report/columns.h b/lib/report/columns.h
index af39008..0d95806 100644
--- a/lib/report/columns.h
+++ b/lib/report/columns.h
@@ -49,7 +49,7 @@ FIELD(LVS, lv, BIN, "AllocLock", lvid, 10, lvallocationlocked, lv_allocation_loc
FIELD(LVS, lv, BIN, "FixMin", lvid, 10, lvfixedminor, lv_fixed_minor, "Set if LV has fixed minor number assigned.", 0)
FIELD(LVS, lv, BIN, "MergeFailed", lvid, 15, lvmergefailed, lv_merge_failed, "Set if snapshot merge failed.", 0)
FIELD(LVS, lv, BIN, "SnapInvalid", lvid, 15, lvsnapshotinvalid, lv_snapshot_invalid, "Set if snapshot LV is invalid.", 0)
-FIELD(LVS, lv, STR, "TargetType", lvid, 10, lvtargettype, lv_target_type, "Kernel target type the LV is related to.", 0)
+//FIELD(LVS, lv, STR, "TargetType", lvid, 10, lvtargettype, lv_target_type, "Kernel target type the LV is related to.", 0)
FIELD(LVS, lv, STR, "Health", lvid, 15, lvhealthstatus, lv_health_status, "LV health status.", 0)
FIELD(LVS, lv, BIN, "SkipAct", lvid, 15, lvskipactivation, lv_skip_activation, "Set if LV is skipped on activation.", 0)
FIELD(LVS, lv, STR, "Active", lvid, 6, lvactive, lv_active, "Active state of the LV.", 0)
diff --git a/lib/report/properties.c b/lib/report/properties.c
index b4e183f..72d689d 100644
--- a/lib/report/properties.c
+++ b/lib/report/properties.c
@@ -216,11 +216,10 @@ GET_PV_NUM_PROPERTY_FN(pv_ba_size, SECTOR_SIZE * pv->ba_size)
#define _lv_inactive_table_get prop_not_implemented_get
#define _lv_device_open_set prop_not_implemented_set
#define _lv_device_open_get prop_not_implemented_get
-#define _lv_target_type_set prop_not_implemented_set
-#define _lv_target_type_get prop_not_implemented_get
+//#define _lv_target_type_set prop_not_implemented_set
+//#define _lv_target_type_get prop_not_implemented_get
#define _lv_health_status_set prop_not_implemented_set
#define _lv_health_status_get prop_not_implemented_get
-#define _lv_target_type_get prop_not_implemented_get
#define _lv_skip_activation_set prop_not_implemented_set
#define _lv_skip_activation_get prop_not_implemented_get
diff --git a/lib/report/report.c b/lib/report/report.c
index 91dfac0..cea2c3c 100644
--- a/lib/report/report.c
+++ b/lib/report/report.c
@@ -1603,6 +1603,7 @@ static int _lvdeviceopen_disp(struct dm_report *rh, struct dm_pool *mem,
return _binary_undef_disp(rh, mem, field, private);
}
+/* FIXME Replace with something that provides a complete unique description for every combination.
static int _lvtargettype_disp(struct dm_report *rh, struct dm_pool *mem,
struct dm_report_field *field,
const void *data, void *private)
@@ -1629,6 +1630,7 @@ static int _lvtargettype_disp(struct dm_report *rh, struct dm_pool *mem,
return _string_disp(rh, mem, field, &target_type, private);
}
+*/
static int _thinzero_disp(struct dm_report *rh, struct dm_pool *mem,
struct dm_report_field *field,
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=99e3c1301294fdd1…
Commit: 99e3c1301294fdd1cd8be25adb303e24e1260c76
Parent: fe5b282a4a51bcc2780da9ef7ab298d97c45f3db
Author: Alasdair G Kergon <agk(a)redhat.com>
AuthorDate: Tue Jul 22 20:50:29 2014 +0100
Committer: Alasdair G Kergon <agk(a)redhat.com>
CommitterDate: Tue Jul 22 20:50:29 2014 +0100
raid: Moved degraded activation code to raid_manip.
Adjust some messages & fn names.
---
lib/activate/activate.c | 119 ++-----------------------------------
lib/metadata/metadata-exported.h | 1 +
lib/metadata/raid_manip.c | 105 +++++++++++++++++++++++++++++++++
tools/lvmcmdline.c | 7 +-
4 files changed, 117 insertions(+), 115 deletions(-)
diff --git a/lib/activate/activate.c b/lib/activate/activate.c
index deb09e2..ebeaa79 100644
--- a/lib/activate/activate.c
+++ b/lib/activate/activate.c
@@ -2203,112 +2203,6 @@ out:
return r;
}
-/* FIXME Move this non-activation code elsewhere */
-static int _lv_raid_is_redundant(struct logical_volume *lv)
-{
- struct lv_segment *raid_seg = first_seg(lv);
- uint32_t copies;
- uint32_t i, s, rebuilds_per_group = 0;
- uint32_t failed_components = 0;
-
- if (!(lv->status & PARTIAL_LV)) {
- /*
- * Redundant, but this function shouldn't
- * be called in this case.
- */
- log_error(INTERNAL_ERROR "%s is not a partial LV", lv->name);
- return 1;
- }
-
- if (!lv_is_raid(lv))
- return 0; /* Not RAID, not redundant */
-
- if (!strcmp(raid_seg->segtype->name, "raid10")) {
- /* FIXME: We only support 2-way mirrors in RAID10 currently */
- copies = 2;
- for (i = 0; i < raid_seg->area_count * copies; i++) {
- s = i % raid_seg->area_count;
- if (!(i % copies))
- rebuilds_per_group = 0;
- if ((seg_lv(raid_seg, s)->status & PARTIAL_LV) ||
- (seg_metalv(raid_seg, s)->status & PARTIAL_LV) ||
- lv_is_virtual(seg_lv(raid_seg, s)) ||
- lv_is_virtual(seg_metalv(raid_seg, s)))
- rebuilds_per_group++;
- if (rebuilds_per_group >= copies) {
- log_debug("An entire mirror group "
- "has failed in %s", lv->name);
- return 0; /* Not redundant */
- }
- }
- return 1; /* Redundant */
- }
-
- for (s = 0; s < raid_seg->area_count; s++) {
- if ((seg_lv(raid_seg, s)->status & PARTIAL_LV) ||
- (seg_metalv(raid_seg, s)->status & PARTIAL_LV) ||
- lv_is_virtual(seg_lv(raid_seg, s)) ||
- lv_is_virtual(seg_metalv(raid_seg, s)))
- failed_components++;
- }
- if (failed_components == raid_seg->area_count) {
- log_debug("All components in %s have failed", lv->name);
- return 0;
- } else if (raid_seg->segtype->parity_devs &&
- (failed_components > raid_seg->segtype->parity_devs)) {
- log_debug("More than %u components from (%s) %s/%s have failed",
- raid_seg->segtype->parity_devs,
- raid_seg->segtype->ops->name(raid_seg),
- lv->vg->name, lv->name);
- return 0;
- }
-
- return 1;
-}
-
-static int _lv_is_not_degraded_capable(struct logical_volume *lv, void *data)
-{
- int *not_capable = (int *)data;
- uint32_t s;
- struct lv_segment *seg;
-
- if (!(lv->status & PARTIAL_LV))
- return 1;
-
- if (lv_is_raid(lv))
- return _lv_raid_is_redundant(lv);
-
- /* Ignore RAID sub-LVs. */
- if (lv_is_raid_type(lv))
- return 1;
-
- dm_list_iterate_items(seg, &lv->segments)
- for (s = 0; s < seg->area_count; s++)
- if (seg_type(seg, s) != AREA_LV) {
- log_debug("%s is not capable of degraded mode",
- lv->name);
- *not_capable = 1;
- }
-
- return 1;
-}
-
-static int lv_is_degraded_capable(struct logical_volume *lv)
-{
- int not_capable = 0;
-
- if (!(lv->status & PARTIAL_LV))
- return 1;
-
- if (!_lv_is_not_degraded_capable(lv, ¬_capable) || not_capable)
- return 0;
-
- if (!for_each_sub_lv(lv, _lv_is_not_degraded_capable, ¬_capable))
- log_error(INTERNAL_ERROR "for_each_sub_lv failure.");
-
- return !not_capable;
-}
-
static int _lv_activate(struct cmd_context *cmd, const char *lvid_s,
struct lv_activate_opts *laopts, int filter,
struct logical_volume *lv)
@@ -2330,19 +2224,20 @@ static int _lv_activate(struct cmd_context *cmd, const char *lvid_s,
goto out;
}
- if ((!lv->vg->cmd->partial_activation) && (lv->status & PARTIAL_LV)) {
- if (!lv_is_degraded_capable(lv)) {
+ if ((!lv->vg->cmd->partial_activation) && (lv->status & PARTIAL_LV) && lv_is_raid_type(lv)) {
+ if (!partial_raid_lv_supports_degraded_activation(lv)) {
log_error("Refusing activation of partial LV %s. "
"Use '--activationmode partial' to override.",
- lv->name);
+ display_lvname(lv));
goto out;
- } else if (!lv->vg->cmd->degraded_activation) {
+ }
+
+ if (!lv->vg->cmd->degraded_activation) {
log_error("Refusing activation of partial LV %s. "
"Try '--activationmode degraded'.",
- lv->name);
+ display_lvname(lv));
goto out;
}
- log_print_unless_silent("Attempting activation of partial RAID LV, %s.", lv->name);
}
if (lv_has_unknown_segments(lv)) {
diff --git a/lib/metadata/metadata-exported.h b/lib/metadata/metadata-exported.h
index 2b06718..9d7a653 100644
--- a/lib/metadata/metadata-exported.h
+++ b/lib/metadata/metadata-exported.h
@@ -1038,6 +1038,7 @@ int lv_raid_reshape(struct logical_volume *lv,
int lv_raid_replace(struct logical_volume *lv, struct dm_list *remove_pvs,
struct dm_list *allocate_pvs);
int lv_raid_remove_missing(struct logical_volume *lv);
+int partial_raid_lv_supports_degraded_activation(struct logical_volume *lv);
/* -- metadata/raid_manip.c */
/* ++ metadata/cache_manip.c */
diff --git a/lib/metadata/raid_manip.c b/lib/metadata/raid_manip.c
index 6fead9a..ab30af9 100644
--- a/lib/metadata/raid_manip.c
+++ b/lib/metadata/raid_manip.c
@@ -1938,3 +1938,108 @@ int lv_raid_remove_missing(struct logical_volume *lv)
return 1;
}
+
+/* Return 1 if a partial raid LV can be activated redundantly */
+static int _partial_raid_lv_is_redundant(struct logical_volume *lv)
+{
+ struct lv_segment *raid_seg = first_seg(lv);
+ uint32_t copies;
+ uint32_t i, s, rebuilds_per_group = 0;
+ uint32_t failed_components = 0;
+
+ if (!strcmp(raid_seg->segtype->name, "raid10")) {
+ /* FIXME: We only support 2-way mirrors in RAID10 currently */
+ copies = 2;
+ for (i = 0; i < raid_seg->area_count * copies; i++) {
+ s = i % raid_seg->area_count;
+
+ if (!(i % copies))
+ rebuilds_per_group = 0;
+
+ if ((seg_lv(raid_seg, s)->status & PARTIAL_LV) ||
+ (seg_metalv(raid_seg, s)->status & PARTIAL_LV) ||
+ lv_is_virtual(seg_lv(raid_seg, s)) ||
+ lv_is_virtual(seg_metalv(raid_seg, s)))
+ rebuilds_per_group++;
+
+ if (rebuilds_per_group >= copies) {
+ log_verbose("An entire mirror group has failed in %s",
+ display_lvname(lv));
+ return 0; /* Insufficient redundancy to activate */
+ }
+ }
+
+ return 1; /* Redundant */
+ }
+
+ for (s = 0; s < raid_seg->area_count; s++) {
+ if ((seg_lv(raid_seg, s)->status & PARTIAL_LV) ||
+ (seg_metalv(raid_seg, s)->status & PARTIAL_LV) ||
+ lv_is_virtual(seg_lv(raid_seg, s)) ||
+ lv_is_virtual(seg_metalv(raid_seg, s)))
+ failed_components++;
+ }
+
+ if (failed_components == raid_seg->area_count) {
+ log_verbose("All components of raid LV %s have failed",
+ display_lvname(lv));
+ return 0; /* Insufficient redundancy to activate */
+ } else if (raid_seg->segtype->parity_devs &&
+ (failed_components > raid_seg->segtype->parity_devs)) {
+ log_verbose("More than %u components from %s %s have failed",
+ raid_seg->segtype->parity_devs,
+ raid_seg->segtype->ops->name(raid_seg),
+ display_lvname(lv));
+ return 0; /* Insufficient redundancy to activate */
+ }
+
+ return 1;
+}
+
+/* Sets *data to 1 if the LV cannot be activated without data loss */
+static int _lv_may_be_activated_in_degraded_mode(struct logical_volume *lv, void *data)
+{
+ int *not_capable = (int *)data;
+ uint32_t s;
+ struct lv_segment *seg;
+
+ if (*not_capable)
+ return 1; /* No further checks needed */
+
+ if (!(lv->status & PARTIAL_LV))
+ return 1;
+
+ if (lv_is_raid(lv)) {
+ *not_capable = !_partial_raid_lv_is_redundant(lv);
+ return 1;
+ }
+
+ /* Ignore RAID sub-LVs. */
+ if (lv_is_raid_type(lv))
+ return 1;
+
+ dm_list_iterate_items(seg, &lv->segments)
+ for (s = 0; s < seg->area_count; s++)
+ if (seg_type(seg, s) != AREA_LV) {
+ log_verbose("%s contains a segment incapable of degraded activation",
+ display_lvname(lv));
+ *not_capable = 1;
+ }
+
+ return 1;
+}
+
+int partial_raid_lv_supports_degraded_activation(struct logical_volume *lv)
+{
+ int not_capable = 0;
+
+ if (!_lv_may_be_activated_in_degraded_mode(lv, ¬_capable) || not_capable)
+ return 0;
+
+ if (!for_each_sub_lv(lv, _lv_may_be_activated_in_degraded_mode, ¬_capable)) {
+ log_error(INTERNAL_ERROR "for_each_sub_lv failure.");
+ return 0;
+ }
+
+ return !not_capable;
+}
diff --git a/tools/lvmcmdline.c b/tools/lvmcmdline.c
index a9769f2..4654978 100644
--- a/tools/lvmcmdline.c
+++ b/tools/lvmcmdline.c
@@ -980,10 +980,9 @@ static int _get_settings(struct cmd_context *cmd)
if (!strcmp(activation_mode, "partial")) {
cmd->partial_activation = 1;
log_warn("PARTIAL MODE. Incomplete logical volumes will be processed.");
- } else if (!strcmp(activation_mode, "degraded")) {
+ } else if (!strcmp(activation_mode, "degraded"))
cmd->degraded_activation = 1;
- log_verbose("DEGRADED MODE. Incomplete RAID LVs will be processed.");
- } else if (strcmp(activation_mode, "complete")) {
+ else if (strcmp(activation_mode, "complete")) {
log_error("Invalid activation mode given.");
return EINVALID_CMD_LINE;
}
@@ -1339,6 +1338,8 @@ int lvm_run_command(struct cmd_context *cmd, int argc, char **argv)
if ((ret = _get_settings(cmd)))
goto_out;
_apply_settings(cmd);
+ if (cmd->degraded_activation)
+ log_verbose("DEGRADED MODE. Incomplete RAID LVs will be processed.");
if (!get_activation_monitoring_mode(cmd, &monitoring))
goto_out;
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=fe5b282a4a51bcc2…
Commit: fe5b282a4a51bcc2780da9ef7ab298d97c45f3db
Parent: 1fe487043dadf189b08b9862f45d21438f197cf2
Author: David Teigland <teigland(a)redhat.com>
AuthorDate: Mon Jul 21 15:41:42 2014 -0500
Committer: David Teigland <teigland(a)redhat.com>
CommitterDate: Mon Jul 21 15:41:42 2014 -0500
man: lvmcache updates
- use the lvconvert --cachepool syntax to match the lvmthin style
- rewrite removal information
- very minor formatting adjustments
---
man/lvmcache.7.in | 101 +++++++++++++++++++++++++++++++---------------------
1 files changed, 60 insertions(+), 41 deletions(-)
diff --git a/man/lvmcache.7.in b/man/lvmcache.7.in
index 87fb9f4..4b21a8a 100644
--- a/man/lvmcache.7.in
+++ b/man/lvmcache.7.in
@@ -18,7 +18,7 @@ on the origin LV or on the cache data LV). Users should be familiar with
these LVs if they wish to create the best and most robust cached
logical volumes.
-.SS Cache Terms
+.SH Cache Terms
.nf
origin LV OriginLV large slow LV
cache data LV CacheDataLV small fast LV for cache pool data
@@ -27,7 +27,7 @@ cache pool LV CachePoolLV CacheDataLV + CacheMetaLV
cache LV CacheLV OriginLV + CachePoolLV
.fi
-.SS Cache Steps
+.SH Cache Steps
The steps to create a logical volume of \fIcache\fP type are as follows:
.TP
0.
@@ -63,34 +63,43 @@ They provide the most options and have the ability to create the
most robust logical volumes. The examples below illustrate how these
steps might be used in practice.
-.SS Cache Commands
-.nf
+.SH Cache Commands
+
0. create OriginLV
-lvcreate \-L LargeSize \-n OriginLV VG SlowPVs
+.br
+.B lvcreate \-L LargeSize \-n OriginLV VG SlowPVs
1. create CacheDataLV
-lvcreate \-L CacheSize \-n CacheDataLV VG FastPVs
+.br
+.B lvcreate \-L CacheSize \-n CacheDataLV VG FastPVs
2. create CacheMetaLV
-lvcreate \-L MetaSize \-n CacheMetaLV VG FastPVs
+.br
+.B lvcreate \-L MetaSize \-n CacheMetaLV VG FastPVs
3. create CachePoolLV
-lvconvert \-\-type cache-pool \-\-poolmetadata VG/CacheMetaLV VG/CacheDataLV
+.br
+.B lvconvert \-\-cachepool VG/CacheDataLV \-\-poolmetadata VG/CacheMetaLV
+.br
CachePoolLV takes the name of CacheDataLV.
+.br
CacheDataLV is renamed CachePoolLV_cdata and becomes hidden.
+.br
CacheMetaLV is renamed CachePoolLV_cmeta and becomes hidden.
4. create CacheLV
-lvconvert \-\-type cache \-\-cachepool VG/CachePoolLV VG/OriginLV
+.br
+.B lvconvert \-\-type cache \-\-cachepool VG/CachePoolLV VG/OriginLV
+.br
CacheLV takes the name of OriginLV.
+.br
OriginLV is renamed OriginLV_corig and becomes hidden.
-.fi
-.SS Cache Examples
-.B Example 1:
-Creating a simple cache LV.
-.br
+.SH Cache Examples
+
+.SS Example 1
+Create a simple cache LV.
.nf
0. Create the origin LV
@@ -103,15 +112,14 @@ Creating a simple cache LV.
# lvcreate \-L 8M \-n lvx_cache_meta vg /dev/fast_dev
3. Create a cache pool LV, combining cache data LV and cache metadata LV
-# lvconvert \-\-type cache-pool \-\-poolmetadata vg/lvx_cache_meta \\
- vg/lvx_cache
+# lvconvert \-\-cachepool vg/lvx_cache \-\-poolmetadata vg/lvx_cache_meta
4. Create a cached LV by combining the cache pool LV and origin LV
# lvconvert \-\-type cache \-\-cachepool vg/lvx_cache vg/lvx
.fi
-.B Example 2:
-Creating a cache LV with a fault tolerant cache pool LV.
+.SS Example 2
+Create a cache LV with a fault tolerant cache pool LV.
Users who are concerned about the possibility of failures in their fast devices
that could lead to data loss might consider making their cache pool sub-LVs
@@ -131,15 +139,14 @@ redundant. Example 2 illustrates how to do that. Note that only steps
/dev/fast1 /dev/fast2
3. Create a cache pool LV combining cache data LV and cache metadata LV
-# lvconvert \-\-type cache-pool \-\-poolmetadata vg/lvx_cache_meta \\
- vg/lvx_cache
+# lvconvert \-\-cachepool vg/lvx_cache \-\-poolmetadata vg/lvx_cache_meta
4. Create a cached LV by combining the cache pool LV and origin LV
# lvconvert \-\-type cache \-\-cachepool vg/lvx_cache vg/lvx
.fi
-.B Example 3:
-Creating a simple cache LV with \fIwritethough\fP caching.
+.SS Example 3
+Create a simple cache LV with \fIwritethough\fP caching.
Some users wish to ensure that any data written will be stored both in the
cache pool LV and on the origin LV. The loss of a device associated with
@@ -160,30 +167,42 @@ in this case.
# lvcreate \-L 8M \-n lvx_cache_meta vg /dev/fast
3. Create a cache pool LV specifying cache mode "writethrough"
-# lvconvert \-\-type cache-pool \-\-poolmetadata vg/lvx_cache_meta \\
- \-\-cachemode writethrough vg/lvx_cache
+# lvconvert \-\-cachepool vg/lvx_cache \-\-poolmetadata vg/lvx_cache_meta \\
+ \-\-cachemode writethrough
4. Create a cache LV by combining the cache pool LV and origin LV
# lvconvert \-\-type cache \-\-cachepool vg/lvx_cache vg/lvx
.fi
-.SS Removing Cache Logical Volumes
-If you wish to remove all logical volumes associated with a cache
-LV, you must remove both top-level, user-visible devices.
-The cache metadata LV and cache data LV cannot be removed
-directly. If only the cache pool LV is specfied for removal, any cached
-blocks not yet on the origin LV will be flush, the cache pool LV will be
-removed, and the now un-cached origin LV will remain. If the user
-specifies a cache LV for removal, then the origin LV is
-removed and only the cache pool LV will remain. The cache pool LV can then
-be used to create another cache LV with a different origin LV if desired.
-
-When users intend to remove all logical volumes associated with a
-cache LV, it is generally better to start with the origin LV and then
-remove the cache pool LV. If the operations are performed in the
-reverse order, the user will have to wait for the contents of the
-cache pool LV to be flushed before the origin LV is removed. This
-could take some time.
+.SH Cache Removal
+
+.SS Removing a cache pool LV without removing an associated origin LV
+
+This writes back data from the cache pool to the origin LV, then removes
+the cache pool LV, leaving the un-cached origin LV. (If the origin LV
+will also be removed, the data flushing can be avoided; see "Removing
+both" below.)
+
+.B lvremove VG/CachePoolLV
+
+.SS Removing both an origin LV and its associated cache pool LV
+
+This removes the cache LV, which includes removing both the origin LV and
+its associated cache pool LV. Data blocks from the cache pool are not
+written back to the origin LV.
+
+.B lvremove VG/CacheLV
+
+./" .SS Separating a cache pool LV from an origin LV
+./" This writes back data from the cache pool to the origin LV, then removes
+./" the association between the cache pool LV and the origin LV.
+./" .br
+./" Not yet implemented.
+
+./" .SS Removing an origin LV without removing an associated cache pool LV
+./" Separate the cache pool LV from the origin LV, then remove the origin LV.
+./" .br
+./" Not yet implemented.
.SH SEE ALSO
.BR lvm.conf (5),
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=1fe487043dadf189…
Commit: 1fe487043dadf189b08b9862f45d21438f197cf2
Parent: 3366baf07675a259eeb7828fb6e605108a5a4290
Author: David Teigland <teigland(a)redhat.com>
AuthorDate: Mon Jul 21 10:28:20 2014 -0500
Committer: David Teigland <teigland(a)redhat.com>
CommitterDate: Mon Jul 21 10:28:20 2014 -0500
man: use macros for indenting in lvmthin
---
man/lvmthin.7.in | 8 ++++++--
1 files changed, 6 insertions(+), 2 deletions(-)
diff --git a/man/lvmthin.7.in b/man/lvmthin.7.in
index d534b42..6652f7e 100644
--- a/man/lvmthin.7.in
+++ b/man/lvmthin.7.in
@@ -818,7 +818,9 @@ Command to set the discard mode when creating a thin pool LV:
.br
.B lvconvert \-\-discards {ignore|nopassdown|passdown}
.br
-.B " " \-\-thinpool VG/ThinDataLV \-\-poolmetadata VG/ThinMetaLV
+.RS
+.B \-\-thinpool VG/ThinDataLV \-\-poolmetadata VG/ThinMetaLV
+.RE
Command to change the discard mode of an existing thin pool LV:
.br
@@ -933,7 +935,9 @@ name of ExampleLV.
.B lvconvert \-\-type thin \-\-thinpool VG/ThinPoolLV
.br
-.B " " \-\-originname NewExternalOriginLV \-\-thin VG/ExampleLV
+.RS
+.B \-\-originname NewExternalOriginLV \-\-thin VG/ExampleLV
+.RE
.I Example
.br
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=3366baf07675a259…
Commit: 3366baf07675a259eeb7828fb6e605108a5a4290
Parent: 513fd029a635470522e1c8a9cdddb70eec39474a
Author: Alasdair G Kergon <agk(a)redhat.com>
AuthorDate: Mon Jul 21 15:54:20 2014 +0100
Committer: Alasdair G Kergon <agk(a)redhat.com>
CommitterDate: Mon Jul 21 15:54:20 2014 +0100
metadata: Reinstate system info in metadata.
Revert part of cac0722cacaac06ac1211194f1d6c21572a32998
This was deliberate and aids the investigation of problems.
---
lib/format_text/export.c | 8 +++-----
1 files changed, 3 insertions(+), 5 deletions(-)
diff --git a/lib/format_text/export.c b/lib/format_text/export.c
index aa0d905..bea97de 100644
--- a/lib/format_text/export.c
+++ b/lib/format_text/export.c
@@ -329,7 +329,6 @@ static int _print_header(struct formatter *f,
{
char *buf;
time_t t;
- char com[PATH_MAX];
t = time(NULL);
@@ -345,10 +344,9 @@ static int _print_header(struct formatter *f,
}
outf(f, "description = \"%s\"", dm_escape_double_quotes(buf, desc));
outnl(f);
- (void) dm_snprintf(com, sizeof(com), "# %s %s %s %s %s",
- _utsname.sysname, _utsname.nodename, _utsname.release,
- _utsname.version, _utsname.machine);
- outfc(f, com, "creation_host = \"%s\"", _utsname.nodename);
+ outf(f, "creation_host = \"%s\"\t# %s %s %s %s %s", _utsname.nodename,
+ _utsname.sysname, _utsname.nodename, _utsname.release,
+ _utsname.version, _utsname.machine);
outf(f, "creation_time = %lu\t# %s", t, ctime(&t));
return 1;
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=513fd029a6354705…
Commit: 513fd029a635470522e1c8a9cdddb70eec39474a
Parent: 8c231a5f4d8e3e309dd018c92644580d06b11dd1
Author: Alasdair G Kergon <agk(a)redhat.com>
AuthorDate: Mon Jul 21 15:50:47 2014 +0100
Committer: Alasdair G Kergon <agk(a)redhat.com>
CommitterDate: Mon Jul 21 15:50:47 2014 +0100
config: Adjust description of activation_mode.
---
WHATS_NEW | 3 ++-
conf/example.conf.in | 32 +++++++++++++++-----------------
lib/activate/activate.c | 1 +
3 files changed, 18 insertions(+), 18 deletions(-)
diff --git a/WHATS_NEW b/WHATS_NEW
index 956b07b..c800dd0 100644
--- a/WHATS_NEW
+++ b/WHATS_NEW
@@ -10,7 +10,8 @@ Version 2.02.108 -
Prompt for confirmation before change LV into a snapshot exception store.
Return proper error codes for some failing lvconvert funtions.
Add initial code to use cache tools (cache_check|dump|repair|restore).
- Add "degraded" activation mode and make it the default.
+ Support lvdisplay --maps for raid.
+ Add --activationmode degraded to activate degraded raid volumes by default.
Add separate lv_active_{locally,remotely,exclusively} LV reporting fields.
Recognize "auto"/"unmanaged" values in selection for appropriate fields only.
Add report/binary_values_as_numeric lvm.conf option for binary values as 0/1.
diff --git a/conf/example.conf.in b/conf/example.conf.in
index 2930054..21c553a 100644
--- a/conf/example.conf.in
+++ b/conf/example.conf.in
@@ -1042,26 +1042,24 @@ activation {
# operation is complete.
polling_interval = 15
- # 'activation_mode' determines how logical volumes are activated if
- # devices are missing. Possible settings are:
- #
- # "complete" - Only allow activation of an LV if all of the PVs
- # that it uses are available (i.e. the volume group
- # is complete). There may be a failed PV in the
- # volume group; but if a particular LV is not on that
- # PV, it is still allowed to activate in this mode.
- #
- # "degraded" - Like "complete", except that RAID logical volumes of
- # segment type "raid{1,4,5,6,10}" are activated if
- # they have sufficient redundancy to present the entire
- # addressable range of the logical volume.
- #
- # "partial" - Allow activation for any logical volume - even if
- # a missing or failed PV would cause a portion of the
- # logical volume to be inaccessible. (E.g. a stripe
- # volume that has lost one of its members would be
- # unable to access a portion of the logical volume.)
- # This setting is not recommended for normal use.
+ # 'activation_mode' determines how Logical Volumes are activated if
+ # any devices are missing. Possible settings are:
+ #
+ # "complete" - Only allow activation of an LV if all of the Physical
+ # Volumes it uses are present. Other PVs in the Volume
+ # Group may be missing.
+ #
+ # "degraded" - Like "complete", but additionally RAID Logical Volumes of
+ # segment type raid1, raid4, raid5, radid6 and raid10 will
+ # be activated if there is no data loss, i.e. they have
+ # sufficient redundancy to present the entire addressable
+ # range of the Logical Volume.
+ #
+ # "partial" - Allows the activation of any Logical Volume even if
+ # a missing or failed PV could cause data loss with a
+ # portion of the Logical Volume inaccessible.
+ # This setting should not normally be used, but may
+ # sometimes assist with data recovery.
#
# This setting was introduced in LVM version 2.02.108. It corresponds
# with the '--activationmode' option for lvchange and vgchange.
diff --git a/lib/activate/activate.c b/lib/activate/activate.c
index 70777fd..deb09e2 100644
--- a/lib/activate/activate.c
+++ b/lib/activate/activate.c
@@ -2203,6 +2203,7 @@ out:
return r;
}
+/* FIXME Move this non-activation code elsewhere */
static int _lv_raid_is_redundant(struct logical_volume *lv)
{
struct lv_segment *raid_seg = first_seg(lv);
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=8c231a5f4d8e3e30…
Commit: 8c231a5f4d8e3e309dd018c92644580d06b11dd1
Parent: 27574d0e410c9b78a1bdc14dc6fd3c9ed2b6ca9f
Author: Alasdair G Kergon <agk(a)redhat.com>
AuthorDate: Mon Jul 21 15:40:59 2014 +0100
Committer: Alasdair G Kergon <agk(a)redhat.com>
CommitterDate: Mon Jul 21 15:40:59 2014 +0100
raid: Correct degraded warning message level
---
tools/lvmcmdline.c | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/tools/lvmcmdline.c b/tools/lvmcmdline.c
index ccef904..a9769f2 100644
--- a/tools/lvmcmdline.c
+++ b/tools/lvmcmdline.c
@@ -982,7 +982,7 @@ static int _get_settings(struct cmd_context *cmd)
log_warn("PARTIAL MODE. Incomplete logical volumes will be processed.");
} else if (!strcmp(activation_mode, "degraded")) {
cmd->degraded_activation = 1;
- log_debug("DEGRADED MODE. Incomplete RAID LVs will be processed.");
+ log_verbose("DEGRADED MODE. Incomplete RAID LVs will be processed.");
} else if (strcmp(activation_mode, "complete")) {
log_error("Invalid activation mode given.");
return EINVALID_CMD_LINE;
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=27574d0e410c9b78…
Commit: 27574d0e410c9b78a1bdc14dc6fd3c9ed2b6ca9f
Parent: 53b787e519261008c4b1d96ea58243c9e2e06f25
Author: Zdenek Kabelac <zkabelac(a)redhat.com>
AuthorDate: Thu Jul 17 16:27:39 2014 +0200
Committer: Zdenek Kabelac <zkabelac(a)redhat.com>
CommitterDate: Thu Jul 17 16:27:39 2014 +0200
tests: use bigger metadata
Until resolved - use bigger then 4MB cache pool metadata.
---
test/shell/pvmove-cache-segtypes.sh | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/test/shell/pvmove-cache-segtypes.sh b/test/shell/pvmove-cache-segtypes.sh
index 1f5c6d9..9eaf186 100644
--- a/test/shell/pvmove-cache-segtypes.sh
+++ b/test/shell/pvmove-cache-segtypes.sh
@@ -142,7 +142,7 @@ lvremove -ff $vg
#################################################
lvcreate -l 2 -n ${lv1}_foo $vg "$dev1"
# RAID for cachepool
-lvcreate --type raid1 -m 1 -L 4M -n meta $vg "$dev1" "$dev2"
+lvcreate --type raid1 -m 1 -L 6M -n meta $vg "$dev1" "$dev2"
lvcreate --type raid1 -m 1 -L 4M -n cachepool $vg "$dev1" "$dev2"
lvconvert --yes --type cache-pool $vg/cachepool --poolmetadata $vg/meta
# RAID for thin pool data LV
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=53b787e519261008…
Commit: 53b787e519261008c4b1d96ea58243c9e2e06f25
Parent: ffa1a7b046b0ec62d478a848181f16c4ee0126bb
Author: Zdenek Kabelac <zkabelac(a)redhat.com>
AuthorDate: Thu Jul 17 14:47:58 2014 +0200
Committer: Zdenek Kabelac <zkabelac(a)redhat.com>
CommitterDate: Thu Jul 17 16:20:21 2014 +0200
cleanup: drop testing impossible path
We cannot get NULL in this test - since if the arg is set
it will always return non-NULL value here.
(in-release update)
---
tools/lvconvert.c | 18 +++---------------
1 files changed, 3 insertions(+), 15 deletions(-)
diff --git a/tools/lvconvert.c b/tools/lvconvert.c
index b630ee2..63a1d98 100644
--- a/tools/lvconvert.c
+++ b/tools/lvconvert.c
@@ -242,10 +242,7 @@ static int _read_pool_params(struct lvconvert_params *lp, struct cmd_context *cm
" the cache or cache-pool segment type.");
return 0;
}
- if (!(lp->pool_data_lv_name = arg_str_value(cmd, cachepool_ARG, NULL))) {
- log_error("Missing cache pool logical volume name.");
- return 0;
- }
+ lp->pool_data_lv_name = arg_str_value(cmd, cachepool_ARG, NULL);
cachepool = 1;
type_str = "cache-pool";
} else if (!strcmp(type_str, "cache-pool"))
@@ -259,10 +256,7 @@ static int _read_pool_params(struct lvconvert_params *lp, struct cmd_context *cm
" the thin or thin-pool segment type.");
return 0;
}
- if (!(lp->pool_data_lv_name = arg_str_value(cmd, thinpool_ARG, NULL))) {
- log_error("Missing thin pool logical volume name.");
- return 0;
- }
+ lp->pool_data_lv_name = arg_str_value(cmd, thinpool_ARG, NULL);
thinpool = 1;
type_str = "thin-pool";
} else if (!strcmp(type_str, "thin-pool"))
@@ -270,13 +264,7 @@ static int _read_pool_params(struct lvconvert_params *lp, struct cmd_context *cm
if (thinpool) {
lp->discards = (thin_discards_t) arg_uint_value(cmd, discards_ARG, THIN_DISCARDS_PASSDOWN);
-
- if (arg_count(cmd, originname_ARG)) {
- if (!(lp->origin_lv_name = arg_str_value(cmd, originname_ARG, NULL))) {
- log_error("Missing --originname argument.");
- return 0;
- }
- }
+ lp->origin_lv_name = arg_str_value(cmd, originname_ARG, NULL);
} else {
if (!arg_is_any_set(cmd, "is valid only with thin pools",
discards_ARG, originname_ARG, zero_ARG,
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=ffa1a7b046b0ec62…
Commit: ffa1a7b046b0ec62d478a848181f16c4ee0126bb
Parent: ab72cdbf81ef5a52a63098b1997b3a6765a9edc5
Author: Zdenek Kabelac <zkabelac(a)redhat.com>
AuthorDate: Thu Jul 17 14:46:38 2014 +0200
Committer: Zdenek Kabelac <zkabelac(a)redhat.com>
CommitterDate: Thu Jul 17 16:19:57 2014 +0200
cleanup: typo in message
in-release fix.
---
tools/lvconvert.c | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/tools/lvconvert.c b/tools/lvconvert.c
index eef408a..b630ee2 100644
--- a/tools/lvconvert.c
+++ b/tools/lvconvert.c
@@ -529,7 +529,7 @@ static int _read_params(struct lvconvert_params *lp, struct cmd_context *cmd,
;
else if (lp->snapshot) { /* Snapshot creation from pre-existing cow */
if (!argc) {
- log_error("Please provide logical volume path for snaphost origin.");
+ log_error("Please provide logical volume path for snapshot origin.");
return 0;
}
lp->origin_lv_name = argv[0];
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=ab72cdbf81ef5a52…
Commit: ab72cdbf81ef5a52a63098b1997b3a6765a9edc5
Parent: 321592af71686b8963a6bae276533f4f19946578
Author: Zdenek Kabelac <zkabelac(a)redhat.com>
AuthorDate: Mon Jul 14 17:34:49 2014 +0200
Committer: Zdenek Kabelac <zkabelac(a)redhat.com>
CommitterDate: Thu Jul 17 16:18:35 2014 +0200
cleanup: check arg_count once
Do not check quiet_ARG more then necessary.
---
tools/lvmcmdline.c | 4 +---
1 files changed, 1 insertions(+), 3 deletions(-)
diff --git a/tools/lvmcmdline.c b/tools/lvmcmdline.c
index be7844b..ccef904 100644
--- a/tools/lvmcmdline.c
+++ b/tools/lvmcmdline.c
@@ -935,11 +935,9 @@ static int _get_settings(struct cmd_context *cmd)
if (arg_count(cmd, quiet_ARG)) {
cmd->current_settings.debug = 0;
cmd->current_settings.verbose = 0;
+ cmd->current_settings.silent = (arg_count(cmd, quiet_ARG) > 1) ? 1 : 0;
}
- if (arg_count(cmd, quiet_ARG) > 1)
- cmd->current_settings.silent = 1;
-
if (arg_count(cmd, test_ARG))
cmd->current_settings.test = arg_count(cmd, test_ARG);
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=321592af71686b89…
Commit: 321592af71686b8963a6bae276533f4f19946578
Parent: cac0722cacaac06ac1211194f1d6c21572a32998
Author: Zdenek Kabelac <zkabelac(a)redhat.com>
AuthorDate: Wed Jul 16 23:55:46 2014 +0200
Committer: Zdenek Kabelac <zkabelac(a)redhat.com>
CommitterDate: Thu Jul 17 16:18:34 2014 +0200
raid: support lvdisplay --maps
Add legs printing for --maps
Somewhat similar to mirror support - maybe there are more things to
show...
---
lib/raid/raid.c | 16 ++++++++++++++++
1 files changed, 16 insertions(+), 0 deletions(-)
diff --git a/lib/raid/raid.c b/lib/raid/raid.c
index 33ba5b7..c3f5c3f 100644
--- a/lib/raid/raid.c
+++ b/lib/raid/raid.c
@@ -30,6 +30,21 @@ static const char *_raid_name(const struct lv_segment *seg)
return seg->segtype->name;
}
+static void _raid_display(const struct lv_segment *seg)
+{
+ unsigned s;
+
+ for (s = 0; s < seg->area_count; ++s) {
+ log_print(" Raid Data LV%2d", s);
+ display_stripe(seg, s, " ");
+ }
+
+ for (s = 0; s < seg->area_count; ++s)
+ log_print(" Raid Metadata LV%2d\t%s", s, seg_metalv(seg, s)->name);
+
+ log_print(" ");
+}
+
static int _raid_text_import_area_count(const struct dm_config_node *sn,
uint32_t *area_count)
{
@@ -404,6 +419,7 @@ static int _raid_target_unmonitor_events(struct lv_segment *seg, int events)
static struct segtype_handler _raid_ops = {
.name = _raid_name,
+ .display = _raid_display,
.text_import_area_count = _raid_text_import_area_count,
.text_import = _raid_text_import,
.text_export = _raid_text_export,
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=cac0722cacaac06a…
Commit: cac0722cacaac06ac1211194f1d6c21572a32998
Parent: f5d6c4b0f3527b42ff3e7ef7a68010c3540d6f41
Author: Zdenek Kabelac <zkabelac(a)redhat.com>
AuthorDate: Wed Jul 16 23:57:43 2014 +0200
Committer: Zdenek Kabelac <zkabelac(a)redhat.com>
CommitterDate: Thu Jul 17 16:17:44 2014 +0200
metadata: use outfc for comments
Few unecessary comments were written to on-disc metadata.
Use outfc() to have comments only in archived files.
(may also save couple bytes in ringbuffer).
TODO: needed validation against newline char...
---
lib/format_text/export.c | 10 ++++++----
lib/striped/striped.c | 4 ++--
2 files changed, 8 insertions(+), 6 deletions(-)
diff --git a/lib/format_text/export.c b/lib/format_text/export.c
index 319e5ea..aa0d905 100644
--- a/lib/format_text/export.c
+++ b/lib/format_text/export.c
@@ -329,6 +329,7 @@ static int _print_header(struct formatter *f,
{
char *buf;
time_t t;
+ char com[PATH_MAX];
t = time(NULL);
@@ -344,9 +345,10 @@ static int _print_header(struct formatter *f,
}
outf(f, "description = \"%s\"", dm_escape_double_quotes(buf, desc));
outnl(f);
- outf(f, "creation_host = \"%s\"\t# %s %s %s %s %s", _utsname.nodename,
- _utsname.sysname, _utsname.nodename, _utsname.release,
- _utsname.version, _utsname.machine);
+ (void) dm_snprintf(com, sizeof(com), "# %s %s %s %s %s",
+ _utsname.sysname, _utsname.nodename, _utsname.release,
+ _utsname.version, _utsname.machine);
+ outfc(f, com, "creation_host = \"%s\"", _utsname.nodename);
outf(f, "creation_time = %lu\t# %s", t, ctime(&t));
return 1;
@@ -396,7 +398,7 @@ static int _print_vg(struct formatter *f, struct volume_group *vg)
outf(f, "seqno = %u", vg->seqno);
if (vg->fid && vg->fid->fmt)
- outf(f, "format = \"%s\" # informational", vg->fid->fmt->name);
+ outfc(f, "# informational", "format = \"%s\"", vg->fid->fmt->name);
if (!_print_flag_config(f, vg->status, VG_FLAGS))
return_0;
diff --git a/lib/striped/striped.c b/lib/striped/striped.c
index 3b08467..dfd4518 100644
--- a/lib/striped/striped.c
+++ b/lib/striped/striped.c
@@ -94,8 +94,8 @@ static int _striped_text_import(struct lv_segment *seg, const struct dm_config_n
static int _striped_text_export(const struct lv_segment *seg, struct formatter *f)
{
- outf(f, "stripe_count = %u%s", seg->area_count,
- (seg->area_count == 1) ? "\t# linear" : "");
+ outfc(f, (seg->area_count == 1) ? "# linear" : NULL,
+ "stripe_count = %u", seg->area_count);
if (seg->area_count > 1)
outsize(f, (uint64_t) seg->stripe_size,
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=f5d6c4b0f3527b42…
Commit: f5d6c4b0f3527b42ff3e7ef7a68010c3540d6f41
Parent: 8f9f18013948f696bffaddb612d55a94f6279c9c
Author: Zdenek Kabelac <zkabelac(a)redhat.com>
AuthorDate: Thu Jul 17 15:12:21 2014 +0200
Committer: Zdenek Kabelac <zkabelac(a)redhat.com>
CommitterDate: Thu Jul 17 16:16:45 2014 +0200
cache: use get_cache_mode for validation
Use a single function to validate cache mode arg
and set DM_ feature flags.
---
lib/cache_segtype/cache.c | 6 +-----
lib/metadata/cache_manip.c | 14 ++++++++++++++
lib/metadata/metadata-exported.h | 1 +
tools/lvconvert.c | 13 +++----------
tools/lvcreate.c | 14 +++-----------
5 files changed, 22 insertions(+), 26 deletions(-)
diff --git a/lib/cache_segtype/cache.c b/lib/cache_segtype/cache.c
index 0e49530..ddaf3cf 100644
--- a/lib/cache_segtype/cache.c
+++ b/lib/cache_segtype/cache.c
@@ -74,11 +74,7 @@ static int _cache_pool_text_import(struct lv_segment *seg,
if (dm_config_has_node(sn, "cache_mode")) {
if (!(str = dm_config_find_str(sn, "cache_mode", NULL)))
return SEG_LOG_ERROR("cache_mode must be a string in");
- if (!strcmp(str, "writethrough"))
- seg->feature_flags |= DM_CACHE_FEATURE_WRITETHROUGH;
- else if (!strcmp(str, "writeback"))
- seg->feature_flags |= DM_CACHE_FEATURE_WRITEBACK;
- else
+ if (!get_cache_mode(str, &seg->feature_flags))
return SEG_LOG_ERROR("Unknown cache_mode in");
}
diff --git a/lib/metadata/cache_manip.c b/lib/metadata/cache_manip.c
index e220dd9..8a5e5e3 100644
--- a/lib/metadata/cache_manip.c
+++ b/lib/metadata/cache_manip.c
@@ -299,3 +299,17 @@ int lv_cache_remove(struct logical_volume *cache_lv)
return 1;
}
+
+int get_cache_mode(const char *str, uint32_t *flags)
+{
+ if (!strcmp(str, "writethrough"))
+ *flags |= DM_CACHE_FEATURE_WRITETHROUGH;
+ else if (!strcmp(str, "writeback"))
+ *flags |= DM_CACHE_FEATURE_WRITEBACK;
+ else {
+ log_error("Cache pool cachemode \"%s\" is unknown.", str);
+ return 0;
+ }
+
+ return 1;
+}
diff --git a/lib/metadata/metadata-exported.h b/lib/metadata/metadata-exported.h
index f2521db..2b06718 100644
--- a/lib/metadata/metadata-exported.h
+++ b/lib/metadata/metadata-exported.h
@@ -1050,6 +1050,7 @@ int update_cache_pool_params(struct volume_group *vg, unsigned attr,
struct logical_volume *lv_cache_create(struct logical_volume *pool,
struct logical_volume *origin);
int lv_cache_remove(struct logical_volume *cache_lv);
+int get_cache_mode(const char *str, uint32_t *flags);
/* -- metadata/cache_manip.c */
struct cmd_vg *cmd_vg_add(struct dm_pool *mem, struct dm_list *cmd_vgs,
diff --git a/tools/lvconvert.c b/tools/lvconvert.c
index e128b81..eef408a 100644
--- a/tools/lvconvert.c
+++ b/tools/lvconvert.c
@@ -289,16 +289,9 @@ static int _read_pool_params(struct lvconvert_params *lp, struct cmd_context *cm
}
if (cachepool) {
- if ((tmp_str = arg_str_value(cmd, cachemode_ARG, NULL))) {
- if (!strcmp(tmp_str, "writeback"))
- lp->feature_flags |= DM_CACHE_FEATURE_WRITEBACK;
- else if (!strcmp(tmp_str, "writethrough"))
- lp->feature_flags |= DM_CACHE_FEATURE_WRITETHROUGH;
- else {
- log_error("Unknown cachemode argument");
- return 0;
- }
- }
+ if ((tmp_str = arg_str_value(cmd, cachemode_ARG, NULL)) &&
+ !get_cache_mode(tmp_str, &lp->feature_flags))
+ return_0;
} else {
if (!arg_is_any_set(cmd, "is valid only with cache pools",
cachemode_ARG, -1))
diff --git a/tools/lvcreate.c b/tools/lvcreate.c
index 8e45cc1..e9a170c 100644
--- a/tools/lvcreate.c
+++ b/tools/lvcreate.c
@@ -713,17 +713,9 @@ static int _read_cache_pool_params(struct lvcreate_params *lp,
lp->chunk_size = arg_uint_value(cmd, chunksize_ARG,
DEFAULT_CACHE_POOL_CHUNK_SIZE * 2);
- str_arg = arg_str_value(cmd, cachemode_ARG, NULL);
- if (str_arg) {
- if (!strcmp(str_arg, "writeback"))
- lp->feature_flags |= DM_CACHE_FEATURE_WRITEBACK;
- else if (!strcmp(str_arg, "writethrough"))
- lp->feature_flags |= DM_CACHE_FEATURE_WRITETHROUGH;
- else {
- log_error("Unknown cachemode argument");
- return 0;
- }
- }
+ if ((str_arg = arg_str_value(cmd, cachemode_ARG, NULL)) &&
+ !get_cache_mode(str_arg, &lp->feature_flags))
+ return_0;
return 1;
}
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=8f9f18013948f696…
Commit: 8f9f18013948f696bffaddb612d55a94f6279c9c
Parent: 7abad9ef88a9c47e302a454fe15d0c9989bf89a0
Author: Zdenek Kabelac <zkabelac(a)redhat.com>
AuthorDate: Thu Jul 17 15:38:13 2014 +0200
Committer: Zdenek Kabelac <zkabelac(a)redhat.com>
CommitterDate: Thu Jul 17 16:16:00 2014 +0200
lvconvert: improve merge validation
Easier check for conflicting options with --merge.
---
WHATS_NEW | 1 +
tools/lvconvert.c | 15 ++++++---------
2 files changed, 7 insertions(+), 9 deletions(-)
diff --git a/WHATS_NEW b/WHATS_NEW
index 9b498b0..956b07b 100644
--- a/WHATS_NEW
+++ b/WHATS_NEW
@@ -1,5 +1,6 @@
Version 2.02.108 -
=================================
+ Improve lvconvert --merge validation.
Improve lvconvert --splitsnapshot validation.
Add report/list_item_separator lvm.conf option.
Add lv_active_{locally,remotely,exclusively} LV reporting fields.
diff --git a/tools/lvconvert.c b/tools/lvconvert.c
index 0f58677..e128b81 100644
--- a/tools/lvconvert.c
+++ b/tools/lvconvert.c
@@ -523,15 +523,12 @@ static int _read_params(struct lvconvert_params *lp, struct cmd_context *cmd,
/* There are six types of lvconvert. */
if (lp->merge) { /* Snapshot merge */
- if (arg_count(cmd, regionsize_ARG) || arg_count(cmd, chunksize_ARG) ||
- arg_count(cmd, zero_ARG) || arg_count(cmd, regionsize_ARG) ||
- arg_count(cmd, poolmetadata_ARG) || arg_count(cmd, poolmetadatasize_ARG) ||
- arg_count(cmd, readahead_ARG) ||
- arg_count(cmd, stripes_long_ARG) || arg_count(cmd, stripesize_ARG)) {
- log_error("Only --background and --interval are valid "
- "arguments for snapshot merge");
- return 0;
- }
+ if (!arg_is_only_set(cmd, "cannot be used with --merge",
+ merge_ARG,
+ background_ARG, interval_ARG,
+ force_ARG, noudevsync_ARG, test_ARG,
+ -1))
+ return_0;
if (!(lp->segtype = get_segtype_from_string(cmd, "snapshot")))
return_0;
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=7abad9ef88a9c47e…
Commit: 7abad9ef88a9c47e302a454fe15d0c9989bf89a0
Parent: 4dcacbe369346e957398fd4951fc1a6d1fd4560f
Author: Zdenek Kabelac <zkabelac(a)redhat.com>
AuthorDate: Thu Jul 17 15:36:07 2014 +0200
Committer: Zdenek Kabelac <zkabelac(a)redhat.com>
CommitterDate: Thu Jul 17 16:15:30 2014 +0200
lvconvert: improve splitsnapshot test
Easier check for conflicting options with --splitsnapshot.
---
WHATS_NEW | 1 +
tools/lvconvert.c | 23 +++++++----------------
2 files changed, 8 insertions(+), 16 deletions(-)
diff --git a/WHATS_NEW b/WHATS_NEW
index db78347..9b498b0 100644
--- a/WHATS_NEW
+++ b/WHATS_NEW
@@ -1,5 +1,6 @@
Version 2.02.108 -
=================================
+ Improve lvconvert --splitsnapshot validation.
Add report/list_item_separator lvm.conf option.
Add lv_active_{locally,remotely,exclusively} LV reporting fields.
Comment out devices/{preferred_names,filter} in default lvm.conf file.
diff --git a/tools/lvconvert.c b/tools/lvconvert.c
index 6ec7fa5..0f58677 100644
--- a/tools/lvconvert.c
+++ b/tools/lvconvert.c
@@ -406,8 +406,14 @@ static int _read_params(struct lvconvert_params *lp, struct cmd_context *cmd,
return 0;
}
- if (arg_count(cmd, splitsnapshot_ARG))
+ if (arg_is_set(cmd, splitsnapshot_ARG)) {
+ if (!arg_is_only_set(cmd, "cannot be used with --splitsnapshot",
+ splitsnapshot_ARG,
+ force_ARG, noudevsync_ARG, test_ARG,
+ -1))
+ return_0;
lp->splitsnapshot = 1;
+ }
if ((_snapshot_type_requested(cmd, type_str) || arg_count(cmd, merge_ARG)) &&
(arg_count(cmd, mirrorlog_ARG) || _mirror_or_raid_type_requested(cmd, type_str) ||
@@ -513,21 +519,6 @@ static int _read_params(struct lvconvert_params *lp, struct cmd_context *cmd,
lp->mirrors_sign = arg_sign_value(cmd, mirrors_ARG, SIGN_NONE);
}
- if (lp->splitsnapshot &&
- (lp->snapshot || lp->thin || lp->merge || lp->merge_mirror || arg_count(cmd, thinpool_ARG) ||
- arg_count(cmd, mirrors_ARG) || arg_count(cmd, repair_ARG) || arg_count(cmd, replace_ARG) ||
- arg_count(cmd, chunksize_ARG) || arg_count(cmd, zero_ARG) || arg_count(cmd, regionsize_ARG) ||
- arg_count(cmd, poolmetadata_ARG) || arg_count(cmd, poolmetadatasize_ARG) ||
- arg_count(cmd, readahead_ARG) || arg_count(cmd, stripes_long_ARG) ||
- arg_count(cmd, stripesize_ARG) || arg_count(cmd, background_ARG) ||
- arg_count(cmd, interval_ARG) || arg_count(cmd, type_ARG) || arg_count(cmd, alloc_ARG) ||
- arg_count(cmd, corelog_ARG) || arg_count(cmd, mirrorlog_ARG) ||
- arg_count(cmd, splitmirrors_ARG) || arg_count(cmd, originname_ARG) ||
- arg_count(cmd, trackchanges_ARG) || arg_count(cmd, use_policies_ARG))) {
- log_error("Incompatible arguments supplied with --splitsnapshot.");
- return 0;
- }
-
lp->alloc = (alloc_policy_t) arg_uint_value(cmd, alloc_ARG, ALLOC_INHERIT);
/* There are six types of lvconvert. */
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=4dcacbe369346e95…
Commit: 4dcacbe369346e957398fd4951fc1a6d1fd4560f
Parent: 04acf7a8d0713c858df893584401e96100f9d9d5
Author: Zdenek Kabelac <zkabelac(a)redhat.com>
AuthorDate: Thu Jul 17 12:19:48 2014 +0200
Committer: Zdenek Kabelac <zkabelac(a)redhat.com>
CommitterDate: Thu Jul 17 16:14:36 2014 +0200
lvconvert: move to single name validation
Validate all LV names in _lvconvert_name_params().
---
tools/lvconvert.c | 19 ++++---------------
1 files changed, 4 insertions(+), 15 deletions(-)
diff --git a/tools/lvconvert.c b/tools/lvconvert.c
index 8370b49..6ec7fa5 100644
--- a/tools/lvconvert.c
+++ b/tools/lvconvert.c
@@ -146,6 +146,9 @@ static int _lvconvert_name_params(struct lvconvert_params *lp,
if (!_lvconvert_vg_name(lp, cmd, &lp->origin_lv_name))
return_0;
+ if (!_lvconvert_vg_name(lp, cmd, &lp->lv_split_name))
+ return_0;
+
if (strchr(lp->lv_name_full, '/') &&
(vg_name = extract_vgname(cmd, lp->lv_name_full)) &&
lp->vg_name && strcmp(vg_name, lp->vg_name)) {
@@ -483,21 +486,7 @@ static int _read_params(struct lvconvert_params *lp, struct cmd_context *cmd,
return 0;
}
- lp->lv_split_name = arg_value(cmd, name_ARG);
- if (lp->lv_split_name) {
- if (strchr(lp->lv_split_name, '/')) {
- if (!(lp->vg_name = extract_vgname(cmd, lp->lv_split_name)))
- return_0;
-
- /* Strip VG from lv_split_name */
- if ((tmp_str = strrchr(lp->lv_split_name, '/')))
- lp->lv_split_name = tmp_str + 1;
- }
-
- if (!apply_lvname_restrictions(lp->lv_split_name))
- return_0;
- }
-
+ lp->lv_split_name = arg_str_value(cmd, name_ARG, NULL);
lp->keep_mimages = 1;
lp->mirrors = arg_uint_value(cmd, splitmirrors_ARG, 0);
lp->mirrors_sign = SIGN_MINUS;
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=04acf7a8d0713c85…
Commit: 04acf7a8d0713c858df893584401e96100f9d9d5
Parent: 3e4f24115a9b5dc8f60436195bffc60100d02620
Author: Zdenek Kabelac <zkabelac(a)redhat.com>
AuthorDate: Thu Jul 17 11:28:21 2014 +0200
Committer: Zdenek Kabelac <zkabelac(a)redhat.com>
CommitterDate: Thu Jul 17 16:14:18 2014 +0200
lvconvert: add missing option for repair
Few more option needs to be allowed with --repair.
(in-release fix).
---
tools/lvconvert.c | 3 ++-
1 files changed, 2 insertions(+), 1 deletions(-)
diff --git a/tools/lvconvert.c b/tools/lvconvert.c
index 2ad1603..8370b49 100644
--- a/tools/lvconvert.c
+++ b/tools/lvconvert.c
@@ -392,8 +392,9 @@ static int _read_params(struct lvconvert_params *lp, struct cmd_context *cmd,
if (arg_count(cmd, repair_ARG) &&
!arg_is_only_set(cmd, "cannot be used with --repair",
repair_ARG,
- use_policies_ARG,
+ alloc_ARG, use_policies_ARG,
stripes_long_ARG, stripesize_ARG,
+ force_ARG, noudevsync_ARG, test_ARG,
-1))
return_0;
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=3e4f24115a9b5dc8…
Commit: 3e4f24115a9b5dc8f60436195bffc60100d02620
Parent: 65a3f50556c3544f1145d86b1b2ddd517838a950
Author: David Teigland <teigland(a)redhat.com>
AuthorDate: Fri Jul 11 15:15:03 2014 -0500
Committer: David Teigland <teigland(a)redhat.com>
CommitterDate: Fri Jul 11 15:15:03 2014 -0500
man: lvmthin fix line breaks
The html rendering inserted some unpleasant line breaks,
so insert better breaks explicitly.
---
man/lvmthin.7.in | 14 +++++++++++---
1 files changed, 11 insertions(+), 3 deletions(-)
diff --git a/man/lvmthin.7.in b/man/lvmthin.7.in
index fbd7a91..d534b42 100644
--- a/man/lvmthin.7.in
+++ b/man/lvmthin.7.in
@@ -662,7 +662,10 @@ of an existing thin pool LV:
.B lvchange \-\-monitor {y|n} VG/ThinPoolLV
.BR lvm.conf (5)
-.B thin_pool_autoextend_threshold thin_pool_autoextend_percent
+.B thin_pool_autoextend_threshold
+.br
+.BR lvm.conf (5)
+.B thin_pool_autoextend_percent
.br
control the default autoextend behavior.
@@ -769,7 +772,10 @@ indicated by the "z" attribute displayed by lvs. The option \-Z
Command to set the zeroing mode when creating a thin pool LV:
.br
-.B lvconvert \-Z{y|n} \-\-thinpool VG/ThinDataLV \-\-poolmetadata VG/ThinMetaLV
+.B lvconvert \-Z{y|n} \-\-thinpool VG/ThinDataLV
+.br
+.B " " \-\-poolmetadata VG/ThinMetaLV
+
Command to change the zeroing mode of an existing thin pool LV:
.br
@@ -987,7 +993,9 @@ and creates a thin LV in the new pool.
.br
\-V VirtualSize specifies the virtual size of the thin LV.
-.B lvcreate \-L LargeSize \-V VirtualSize \-n ThinLV \-\-thinpool VG/ThinPoolLV
+.B lvcreate \-L LargeSize \-V VirtualSize \-n ThinLV
+.br
+.B " " \-\-thinpool VG/ThinPoolLV
Equivalent to:
.br
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=65a3f50556c3544f…
Commit: 65a3f50556c3544f1145d86b1b2ddd517838a950
Parent: af219fbc042db96cc588c03557614b00097ccf6c
Author: Zdenek Kabelac <zkabelac(a)redhat.com>
AuthorDate: Fri Jul 11 14:40:51 2014 +0200
Committer: Zdenek Kabelac <zkabelac(a)redhat.com>
CommitterDate: Fri Jul 11 14:42:21 2014 +0200
lvconvert: fix missing repair option
Support --repair and --use-policies with mirrors.
(fixes another regression from lvconvert change for thin and cache).
TODO: the code path for mirror needs update.
---
tools/lvconvert.c | 8 +++++---
1 files changed, 5 insertions(+), 3 deletions(-)
diff --git a/tools/lvconvert.c b/tools/lvconvert.c
index ba592a2..2ad1603 100644
--- a/tools/lvconvert.c
+++ b/tools/lvconvert.c
@@ -391,9 +391,10 @@ static int _read_params(struct lvconvert_params *lp, struct cmd_context *cmd,
if (arg_count(cmd, repair_ARG) &&
!arg_is_only_set(cmd, "cannot be used with --repair",
- repair_ARG,
- stripes_long_ARG, stripesize_ARG,
- -1))
+ repair_ARG,
+ use_policies_ARG,
+ stripes_long_ARG, stripesize_ARG,
+ -1))
return_0;
if (arg_is_set(cmd, mirrorlog_ARG) && arg_is_set(cmd, corelog_ARG)) {
@@ -617,6 +618,7 @@ static int _read_params(struct lvconvert_params *lp, struct cmd_context *cmd,
return_0;
}
} else if (_mirror_or_raid_type_requested(cmd, type_str) ||
+ arg_is_set(cmd, repair_ARG) ||
arg_is_set(cmd, mirrorlog_ARG) ||
arg_is_set(cmd, corelog_ARG)) { /* Mirrors (and some RAID functions) */
if (arg_count(cmd, chunksize_ARG)) {
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=af219fbc042db96c…
Commit: af219fbc042db96cc588c03557614b00097ccf6c
Parent: c0ebe78ef89e2a29d2dacc40184e41970ffc5564
Author: Zdenek Kabelac <zkabelac(a)redhat.com>
AuthorDate: Fri Jul 11 14:19:22 2014 +0200
Committer: Zdenek Kabelac <zkabelac(a)redhat.com>
CommitterDate: Fri Jul 11 14:19:22 2014 +0200
cleanup: lets make it really obvious for gcc
---
tools/lvconvert.c | 3 ++-
1 files changed, 2 insertions(+), 1 deletions(-)
diff --git a/tools/lvconvert.c b/tools/lvconvert.c
index c51158b..ba592a2 100644
--- a/tools/lvconvert.c
+++ b/tools/lvconvert.c
@@ -2958,7 +2958,8 @@ static int _lvconvert_pool(struct cmd_context *cmd,
/* Swap normal LV with pool's metadata LV ? */
if (lv_is_pool(pool_lv)) {
/* Swap names between old and new metadata LV */
- if (!detach_pool_metadata_lv(first_seg(pool_lv), &pool_metadata_lv))
+ seg = first_seg(pool_lv);
+ if (!detach_pool_metadata_lv(seg, &pool_metadata_lv))
return_0;
old_name = metadata_lv->name;
if (!lv_rename_update(cmd, metadata_lv, "pvmove_tmeta", 0))
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=c0ebe78ef89e2a29…
Commit: c0ebe78ef89e2a29d2dacc40184e41970ffc5564
Parent: 17b92001ea4093e01d93ebd3645aa935896b9940
Author: Zdenek Kabelac <zkabelac(a)redhat.com>
AuthorDate: Fri Jul 11 14:09:32 2014 +0200
Committer: Zdenek Kabelac <zkabelac(a)redhat.com>
CommitterDate: Fri Jul 11 14:12:35 2014 +0200
lvconvert: fix mirror path
lvconvert rewrite commit missed proper handling
of mirror path for --corelog and --mirrorlog options.
Document this even in man page.
---
man/lvconvert.8.in | 2 ++
tools/lvconvert.c | 4 +++-
2 files changed, 5 insertions(+), 1 deletions(-)
diff --git a/man/lvconvert.8.in b/man/lvconvert.8.in
index e038371..032fbff 100644
--- a/man/lvconvert.8.in
+++ b/man/lvconvert.8.in
@@ -169,7 +169,9 @@ See \fBlvm\fP(8) for common options.
.br
Exactly one of
.BR \-\-cache ,
+.BR \-\-corelog ,
.BR \-\-merge ,
+.BR \-\-mirrorlog ,
.BR \-\-mirrors ,
.BR \-\-repair ,
.BR \-\-replace ,
diff --git a/tools/lvconvert.c b/tools/lvconvert.c
index 04bb202..c51158b 100644
--- a/tools/lvconvert.c
+++ b/tools/lvconvert.c
@@ -616,7 +616,9 @@ static int _read_params(struct lvconvert_params *lp, struct cmd_context *cmd,
tmp_str)))
return_0;
}
- } else if (_mirror_or_raid_type_requested(cmd, type_str)) { /* Mirrors (and some RAID functions) */
+ } else if (_mirror_or_raid_type_requested(cmd, type_str) ||
+ arg_is_set(cmd, mirrorlog_ARG) ||
+ arg_is_set(cmd, corelog_ARG)) { /* Mirrors (and some RAID functions) */
if (arg_count(cmd, chunksize_ARG)) {
log_error("--chunksize is only available with snapshots or pools.");
return 0;
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=17b92001ea4093e0…
Commit: 17b92001ea4093e01d93ebd3645aa935896b9940
Parent: 7913f64a020db49cf2715d64982571d035ced893
Author: Peter Rajnoha <prajnoha(a)redhat.com>
AuthorDate: Fri Jul 11 14:09:05 2014 +0200
Committer: Peter Rajnoha <prajnoha(a)redhat.com>
CommitterDate: Fri Jul 11 14:09:05 2014 +0200
WHATS_NEW: recent commits
Commits:
d169ff1e039ecdfb1efac0a6464ca149d71d8767
bccc2bef33af081264bbc356e37efe89ef78b796
f76879ba440aa93f2e237335fe2cca6951a636bf
---
WHATS_NEW | 3 +++
1 files changed, 3 insertions(+), 0 deletions(-)
diff --git a/WHATS_NEW b/WHATS_NEW
index a81fddb..db78347 100644
--- a/WHATS_NEW
+++ b/WHATS_NEW
@@ -1,5 +1,8 @@
Version 2.02.108 -
=================================
+ Add report/list_item_separator lvm.conf option.
+ Add lv_active_{locally,remotely,exclusively} LV reporting fields.
+ Comment out devices/{preferred_names,filter} in default lvm.conf file.
Enhance lvconvert thin, thinpool, cache and cachepool command line support.
Display 'C' only for cache and cache-pool target types in lvs.
Prompt for confirmation before change LV into a snapshot exception store.
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=7913f64a020db49c…
Commit: 7913f64a020db49cf2715d64982571d035ced893
Parent: a62cea3371cfac10f74a135b1969120e10f48f60
Author: Zdenek Kabelac <zkabelac(a)redhat.com>
AuthorDate: Fri Jul 11 13:54:54 2014 +0200
Committer: Zdenek Kabelac <zkabelac(a)redhat.com>
CommitterDate: Fri Jul 11 13:54:54 2014 +0200
cleanup: drop unintend debug error line
---
tools/lvconvert.c | 4 +---
1 files changed, 1 insertions(+), 3 deletions(-)
diff --git a/tools/lvconvert.c b/tools/lvconvert.c
index 3a5f129..04bb202 100644
--- a/tools/lvconvert.c
+++ b/tools/lvconvert.c
@@ -165,7 +165,7 @@ static int _lvconvert_name_params(struct lvconvert_params *lp,
if ((ptr = strrchr(lp->lv_name_full, '/')))
lp->lv_name = ptr + 1;
else
- lp->lv_name = lp->lv_name_full;
+ lp->lv_name = lp->lv_name_full;
if (!lp->merge_mirror &&
!strstr(lp->lv_name, "_tdata") &&
@@ -173,8 +173,6 @@ static int _lvconvert_name_params(struct lvconvert_params *lp,
!apply_lvname_restrictions(lp->lv_name))
return_0;
- log_error("PAR %d t:%d c:%d m:%s d:%s l:%s", *pargc, lp->thin,lp->cache,
- lp->pool_metadata_lv_name, lp->pool_data_lv_name, lp->lv_name);
if (*pargc) {
if (lp->snapshot) {
log_error("Too many arguments provided for snapshots.");
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=a62cea3371cfac10…
Commit: a62cea3371cfac10f74a135b1969120e10f48f60
Parent: d7065f154e497ffe26006bf47b533b23383a8810
Author: Zdenek Kabelac <zkabelac(a)redhat.com>
AuthorDate: Fri Jul 11 13:47:50 2014 +0200
Committer: Zdenek Kabelac <zkabelac(a)redhat.com>
CommitterDate: Fri Jul 11 13:52:30 2014 +0200
cleanup: older gcc is not smart enough
Avoid gcc warning about uninitialized 'seg' variable.
It's not easy for older gcc compiler to deduce it's been set.
---
tools/lvconvert.c | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/tools/lvconvert.c b/tools/lvconvert.c
index ff32f76..3a5f129 100644
--- a/tools/lvconvert.c
+++ b/tools/lvconvert.c
@@ -2958,7 +2958,7 @@ static int _lvconvert_pool(struct cmd_context *cmd,
/* Swap normal LV with pool's metadata LV ? */
if (lv_is_pool(pool_lv)) {
/* Swap names between old and new metadata LV */
- if (!detach_pool_metadata_lv(seg, &pool_metadata_lv))
+ if (!detach_pool_metadata_lv(first_seg(pool_lv), &pool_metadata_lv))
return_0;
old_name = metadata_lv->name;
if (!lv_rename_update(cmd, metadata_lv, "pvmove_tmeta", 0))
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=d7065f154e497ffe…
Commit: d7065f154e497ffe26006bf47b533b23383a8810
Parent: 9f703d35a0ac4f74934ff8c7dc9e5610986caff6
Author: Zdenek Kabelac <zkabelac(a)redhat.com>
AuthorDate: Fri Jul 11 13:13:56 2014 +0200
Committer: Zdenek Kabelac <zkabelac(a)redhat.com>
CommitterDate: Fri Jul 11 13:32:52 2014 +0200
tests: updates for new lvconvert
---
test/shell/lvconvert-thin-raid.sh | 4 ++--
test/shell/lvconvert-thin.sh | 4 ++--
test/shell/pvmove-cache-segtypes.sh | 4 ++--
3 files changed, 6 insertions(+), 6 deletions(-)
diff --git a/test/shell/lvconvert-thin-raid.sh b/test/shell/lvconvert-thin-raid.sh
index 7e5efbd..d7a353b 100644
--- a/test/shell/lvconvert-thin-raid.sh
+++ b/test/shell/lvconvert-thin-raid.sh
@@ -23,8 +23,8 @@ lvcreate -aey --nosync -L8M --type raid1 -m1 -n $lv2 $vg
lvchange -an $vg/$lv1
# conversion fails for internal volumes
-fail lvconvert --thinpool $vg/${lv1}_rimage_0
-fail lvconvert --yes --thinpool $vg/$lv1 --poolmetadata $vg/${lv2}_rimage_0
+invalid lvconvert --thinpool $vg/${lv1}_rimage_0
+invalid lvconvert --yes --thinpool $vg/$lv1 --poolmetadata $vg/${lv2}_rimage_0
lvconvert --yes --thinpool $vg/$lv1 --poolmetadata $vg/$lv2
diff --git a/test/shell/lvconvert-thin.sh b/test/shell/lvconvert-thin.sh
index 4a200bb..80f55dd 100644
--- a/test/shell/lvconvert-thin.sh
+++ b/test/shell/lvconvert-thin.sh
@@ -80,7 +80,7 @@ fail lvconvert -c 4 --thinpool $vg/$lv1 --poolmetadata $vg/$lv2
# too big chunk size fails
fail lvconvert -c 2G --thinpool $vg/$lv1 --poolmetadata $vg/$lv2
# negative chunk size fails
-fail lvconvert -c -256 --thinpool $vg/$lv1 --poolmetadata $vg/$lv2
+invalid lvconvert -c -256 --thinpool $vg/$lv1 --poolmetadata $vg/$lv2
# non power of 2 fails
fail lvconvert -c 88 --thinpool $vg/$lv1 --poolmetadata $vg/$lv2
@@ -93,7 +93,7 @@ lvcreate -L1T -n $lv1 $vg
lvcreate -L32G -n $lv2 $vg
# Warning about bigger then needed
lvconvert --yes --thinpool $vg/$lv1 --poolmetadata $vg/$lv2 |& tee err
-grep "WARNING: Maximum size" err
+grep "WARNING: Maximum" err
lvremove -f $vg
diff --git a/test/shell/pvmove-cache-segtypes.sh b/test/shell/pvmove-cache-segtypes.sh
index 94a3848..1f5c6d9 100644
--- a/test/shell/pvmove-cache-segtypes.sh
+++ b/test/shell/pvmove-cache-segtypes.sh
@@ -110,7 +110,7 @@ lvremove -ff $vg
# Testing pvmove of a RAID cachepool (metadata and data)
########################################################
lvcreate -l 2 -n ${lv1}_foo $vg "$dev1"
-lvcreate --type raid1 -L 2M -n meta $vg "$dev1" "$dev2"
+lvcreate --type raid1 -L 6M -n meta $vg "$dev1" "$dev2"
lvcreate --type raid1 -L 4M -n ${lv1}_pool $vg "$dev1" "$dev2"
lvconvert --yes --type cache-pool $vg/${lv1}_pool --poolmetadata $vg/meta
lvcreate --type cache -n $lv1 -L 8M $vg/${lv1}_pool "$dev5"
@@ -142,7 +142,7 @@ lvremove -ff $vg
#################################################
lvcreate -l 2 -n ${lv1}_foo $vg "$dev1"
# RAID for cachepool
-lvcreate --type raid1 -m 1 -L 2M -n meta $vg "$dev1" "$dev2"
+lvcreate --type raid1 -m 1 -L 4M -n meta $vg "$dev1" "$dev2"
lvcreate --type raid1 -m 1 -L 4M -n cachepool $vg "$dev1" "$dev2"
lvconvert --yes --type cache-pool $vg/cachepool --poolmetadata $vg/meta
# RAID for thin pool data LV
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=9f703d35a0ac4f74…
Commit: 9f703d35a0ac4f74934ff8c7dc9e5610986caff6
Parent: 4bbfac359c5e7e82a0600fa3d41bf7ea308e485f
Author: Zdenek Kabelac <zkabelac(a)redhat.com>
AuthorDate: Thu Jul 10 20:59:39 2014 +0200
Committer: Zdenek Kabelac <zkabelac(a)redhat.com>
CommitterDate: Fri Jul 11 13:32:23 2014 +0200
cleanup: lvconvert reoder repair check
---
tools/lvconvert.c | 28 ++++++++++++++--------------
1 files changed, 14 insertions(+), 14 deletions(-)
diff --git a/tools/lvconvert.c b/tools/lvconvert.c
index 9710134..ff32f76 100644
--- a/tools/lvconvert.c
+++ b/tools/lvconvert.c
@@ -3163,20 +3163,20 @@ static int _lvconvert_single(struct cmd_context *cmd, struct logical_volume *lv,
if (lp->splitsnapshot)
return _lvconvert_splitsnapshot(cmd, lv, lp);
- if (arg_count(cmd, repair_ARG) && lv_is_pool(lv)) {
- if (!_lvconvert_pool_repair(cmd, lv, lp))
- return_ECMD_FAILED;
- return ECMD_PROCESSED;
- }
-
- if (arg_count(cmd, repair_ARG) &&
- !(lv->status & MIRRORED) && !(lv->status & RAID)) {
- if (arg_count(cmd, use_policies_ARG))
- return ECMD_PROCESSED; /* nothing to be done here */
- log_error("Can't repair LV \"%s\" of segtype %s.",
- lv->name,
- first_seg(lv)->segtype->ops->name(first_seg(lv)));
- return ECMD_FAILED;
+ if (arg_count(cmd, repair_ARG)) {
+ if (lv_is_pool(lv)) {
+ if (!_lvconvert_pool_repair(cmd, lv, lp))
+ return_ECMD_FAILED;
+ return ECMD_PROCESSED;
+ }
+ if (!lv_is_mirrored(lv) && !lv_is_raid(lv)) {
+ if (arg_count(cmd, use_policies_ARG))
+ return ECMD_PROCESSED; /* nothing to be done here */
+ log_error("Can't repair LV \"%s\" of segtype %s.",
+ lv->name,
+ first_seg(lv)->segtype->ops->name(first_seg(lv)));
+ return ECMD_FAILED;
+ }
}
if (!lp->segtype) {
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=4bbfac359c5e7e82…
Commit: 4bbfac359c5e7e82a0600fa3d41bf7ea308e485f
Parent: b2988a917af8ca16814b067c1d73f899e871e1d4
Author: Zdenek Kabelac <zkabelac(a)redhat.com>
AuthorDate: Mon Jul 7 22:28:43 2014 +0200
Committer: Zdenek Kabelac <zkabelac(a)redhat.com>
CommitterDate: Fri Jul 11 13:32:23 2014 +0200
man: lvconvert update
Update lvconvert doc for conversion of pools
(thin and cache pools and volumes)
Various more cleanups.
---
man/lvconvert.8.in | 178 +++++++++++++++++++++++++++++-----------------------
1 files changed, 99 insertions(+), 79 deletions(-)
diff --git a/man/lvconvert.8.in b/man/lvconvert.8.in
index f96cee2..e038371 100644
--- a/man/lvconvert.8.in
+++ b/man/lvconvert.8.in
@@ -5,26 +5,26 @@ lvconvert \(em convert a logical volume from linear to mirror or snapshot
.B lvconvert
.BR \-m | \-\-mirrors
.I Mirrors
+.RB [ \-\-type
+.IR SegmentType ]
.RB [ \-\-mirrorlog
.RI { disk | core | mirrored }]
.RB [ \-\-corelog ]
.RB [ \-R | \-\-regionsize
.IR MirrorLogRegionSize ]
-.RB [ \-\-type
-.IR SegmentType ]
+.RB [ \-\-stripes
+.I Stripes
+.RB [ \-I | \-\-stripesize
+.IR StripeSize ]]
.RB [ \-A | \-\-alloc
.IR AllocationPolicy ]
.RB [ \-b | \-\-background ]
-.RB [ \-\-commandprofile
-.IR ProfileName ]
.RB [ \-f | \-\-force ]
.RB [ \-i | \-\-interval
.IR Seconds ]
+.RB [ \-\-commandprofile
+.IR ProfileName ]
.RB [ \-h | \-? | \-\-help ]
-.RB [ \-\-stripes
-.I Stripes
-.RB [ \-I | \-\-stripesize
-.IR StripeSize ]]
.RB [ \-\-noudevsync ]
.RB [ \-v | \-\-verbose ]
.RB [ \-y | \-\-yes ]
@@ -33,12 +33,12 @@ lvconvert \(em convert a logical volume from linear to mirror or snapshot
.RI [ PhysicalVolume [ Path ][ :PE [ \-PE ]]...]
.sp
.B lvconvert \-\-splitmirrors \fIImages
-.RB [ \-\-commandprofile
-.IR ProfileName ]
.RB [ \-\-name
.IR SplitLogicalVolumeName ]
.RB [ \-\-trackchanges ]
.IR MirrorLogicalVolume [ Path ]
+.RB [ \-\-commandprofile
+.IR ProfileName ]
.RI [ SplittablePhysicalVolume [ Path ][ :PE [ \-PE ]]...]
.sp
.B lvconvert
@@ -53,38 +53,38 @@ lvconvert \(em convert a logical volume from linear to mirror or snapshot
.sp
.B lvconvert
.BR \-s | \-\-snapshot
-.RB [ \-\-commandprofile
-.IR ProfileName ]
.RB [ \-c | \-\-chunksize
.IR ChunkSize [ bBsSkK ]]
+.RB [ \-Z | \-\-zero
+.RI { y | n }]
+.RB [ \-\-commandprofile
+.IR ProfileName ]
.RB [ \-h | \-? | \-\-help ]
.RB [ \-\-noudevsync ]
.RB [ \-v | \-\-verbose ]
-.RB [ \-Z | \-\-zero
-.RI { y | n }]
.RB [ \-\-version ]
.IR OriginalLogicalVolume [ Path ]
.IR SnapshotLogicalVolume [ Path ]
.sp
.B lvconvert \-\-merge
-.RB [ \-\-commandprofile
-.IR ProfileName ]
.RB [ \-b | \-\-background ]
.RB [ \-i | \-\-interval
.IR Seconds ]
+.RB [ \-\-commandprofile
+.IR ProfileName ]
.RB [ \-h | \-? | \-\-help ]
.RB [ \-v | \-\-verbose ]
.RB [ \-\-version ]
.IR LogicalVolume [ Path ]...
.sp
.B lvconvert \-\-repair
-.RB [ \-\-commandprofile
-.IR ProfileName ]
-.RB [ \-h | \-? | \-\-help ]
.RB [ \-\-stripes
.I Stripes
.RB [ \-I | \-\-stripesize
.IR StripeSize ]]
+.RB [ \-\-commandprofile
+.IR ProfileName ]
+.RB [ \-h | \-? | \-\-help ]
.RB [ \-v | \-\-verbose ]
.RB [ \-\-version ]
.IR LogicalVolume [ Path ]
@@ -99,10 +99,12 @@ lvconvert \(em convert a logical volume from linear to mirror or snapshot
.IR LogicalVolume [ Path ]
.RI [ PhysicalVolume [ Path ]...]
.sp
-.B lvconvert \-\-thinpool
+.B lvconvert
+.RB [{ \-\-type \ \fIthin [ \fI\-pool ]| \-T | \-\-thin }
+.RB [ \-\-originname
+.IR NewExternalOriginVolumeName ]]
+.RB [ \-\-thinpool
.IR ThinPoolLogicalVolume { Name | Path }
-.RB [ \-\-commandprofile
-.IR ProfileName ]
.RB [ \-c | \-\-chunksize
.IR ChunkSize [ bBsSkKmMgG ]]
.RB [ \-\-discards
@@ -114,24 +116,22 @@ lvconvert \(em convert a logical volume from linear to mirror or snapshot
.IR ThinPoolMetadataSize [ bBsSkKmMgG ]}]
.RB [ \-r | \-\-readahead
.RI { ReadAheadSectors | auto | none }]
-.RB [ \-\-stripes
-.I Stripes
-.RB [ \-I | \-\-stripesize
-.IR StripeSize ]]]
-.RB [ \-Z | \-\-zero
-.RI { y | n }]
-.RB [ \-T | \-\-thin
-.IR ExternalOriginLogicalVolume { Name | Path }
-.RB [ \-\-originname
-.IR NewExternalOriginVolumeName ]]
-.RI [ PhysicalVolume [ Path ][ :PE [ \-PE ]]...]
+.RB [ \-\-stripes \ \fIStripes
+.RB [ \-I | \-\-stripesize \ \fIStripeSize ]]]
+.RB [ \-Z | \-\-zero \ { \fIy | \fIn }]]
+.RI [[ ExternalOrigin | ThinPool ] LogicalVolume { Name | Path }]
+.RI [ PhysicalVolume [ Path ][ :PE
+.RI [ \-PE ]]...]
+.RB [ \-\-commandprofile
+.IR ProfileName ]
.RB [ \-h | \-? | \-\-help ]
.RB [ \-v | \-\-verbose ]
.RB [ \-\-version ]
.sp
-.B lvconvert \-\-type \fIcache-pool
-.RB [ \-\-commandprofile
-.IR ProfileName ]
+.B lvconvert
+.RB [ \-\-type \ \fIcache [ \fI\-pool ]| \-\-cache ]
+.RB [ \-\-cachepool
+.IR CachePoolLV { Name | Path }]
.RB [ \-c | \-\-chunksize
.IR ChunkSize [ bBsSkKmMgG ]]
.RB [ \-\-cachemode
@@ -141,16 +141,8 @@ lvconvert \(em convert a logical volume from linear to mirror or snapshot
|
.B \-\-poolmetadatasize
.IR CachePoolMetadataSize [ bBsSkKmMgG ]}]
-.IR LogicalVolume [ Path ]
+.IR LogicalVolume { Name | Path }
.RI [ PhysicalVolume [ Path ][ :PE [ \-PE ]]...]
-.RB [ \-h | \-? | \-\-help ]
-.RB [ \-v | \-\-verbose ]
-.RB [ \-\-version ]
-.sp
-.B lvconvert \-\-type \fIcache
-.B \-\-cachepool
-.IR CachePoolLV { Name | Path }
-.IR LogicalVolume [ Path ]
.RB [ \-\-commandprofile
.IR ProfileName ]
.RB [ \-h | \-? | \-\-help ]
@@ -176,6 +168,7 @@ the freed extents come first from the specified PhysicalVolumes.
See \fBlvm\fP(8) for common options.
.br
Exactly one of
+.BR \-\-cache ,
.BR \-\-merge ,
.BR \-\-mirrors ,
.BR \-\-repair ,
@@ -183,8 +176,7 @@ Exactly one of
.BR \-\-splitsnapshot ,
.BR \-\-snapshot ,
.BR \-\-splitmirrors ,
-.BR \-\-thin ,
-.BR \-\-thinpool
+.BR \-\-thin
or
.BR \-\-type
arguments is required.
@@ -192,20 +184,25 @@ arguments is required.
.BR \-b ", " \-\-background
Run the daemon in the background.
.TP
+.BR \-\-cache ", " \-\-type\ \fIcache
+Converts logical volume to a cached LV with the use of cache pool
+specified with \fB\-\-cachepool\fP.
+For more information on cache pool LVs and cache LVs, see \fBlvmcache\fP(8).
+.TP
.BR \-\-cachepool " " \fICachePoolLV
This argument is necessary when converting a logical volume to a cache LV.
-For more information on cache pool LVs and cache LVs, see \fBlvm\fP(8).
+For more information on cache pool LVs and cache LVs, see \fBlvmcache\fP(8).
.TP
.BR \-m ", " \-\-mirrors " " \fIMirrors
Specifies the degree of the mirror you wish to create.
For example, "\fB\-m 1\fP" would convert the original logical
volume to a mirror volume with 2-sides; that is, a
linear volume plus one copy. There are two implementations of mirroring
-which correspond to the "raid1" and "mirror" segment types. The default
-mirroring segment type is "raid1". If the legacy "mirror" segment type
+which correspond to the "\fIraid1\fP" and "\fImirror\fP" segment types. The default
+mirroring segment type is "\fIraid1\fP". If the legacy "\fImirror\fP" segment type
is desired, the \fB\-\-type\fP argument must be used to explicitly
select the desired type. The \fB\-\-mirrorlog\fP and \fB\-\-corelog\fP
-options below are only relevant to the legacy "mirror" segment type.
+options below are only relevant to the legacy "\fImirror\fP" segment type.
.TP
.IR \fB\-\-mirrorlog " {" disk | core | mirrored }
Specifies the type of log to use.
@@ -227,14 +224,19 @@ uses this granularity to track which regions are in sync.
.TP
.B \-\-type \fISegmentType
Used to convert a logical volume to another segment type, like
-.IR cache-pool ,
.IR cache ,
+.IR cache-pool ,
.IR raid1 ,
+.IR snapshot ,
+.IR thin ,
or
.IR thin-pool .
When converting a logical volume to a cache LV, the
.B \-\-cachepool
argument is required.
+When converting a logical volume to a thin LV, the
+.B \-\-thinpool
+argument is required.
See \fBlvmcache\fP(7) for more info about caching support
and \fBlvmthin\fP(7) for thin provisioning support.
.TP
@@ -274,28 +276,30 @@ along with the metadata describing them. This volume can be wiped and then
destroyed with lvremove.
The inverse of \fB\-\-snapshot\fP.
.TP
-.B \-s, \-\-snapshot
+.BR \-s ", " \-\-snapshot ", " \-\-type\ \fIsnapshot
Recreates a snapshot from constituent logical volumes (or copies of them) after
having been separated using \fB\-\-splitsnapshot\fP.
For this to work correctly, no changes may be made to the contents
of either volume after the split.
.TP
.BR \-c ", " \-\-chunksize " " \fIChunkSize [ \fIbBsSkKmMgG ]
-Gives the size of chunk for snapshot and thin pool logical volumes.
+Gives the size of chunk for snapshot, cache pool and thin pool logical volumes.
Default unit is in kilobytes.
-.br
+.sp
For snapshots the value must be power of 2 between 4KiB and 512KiB
and the default value is 4.
-.br
+.sp
+For cache pools the value must be between 32KiB and 1GiB and
+the default value is 64.
+.sp
For thin pools the value must be between 64KiB and
1GiB and the default value starts with 64 and scales
up to fit the pool metadata size within 128MiB,
if the pool metadata size is not specified.
-The value must be a multiple of 64KiB.
+The value must be a multiple of 64KiB.
(Early kernel support until thin target version 1.4 required the value
to be a power of 2. Discards weren't supported for non-power of 2 values
until thin target version 1.5.)
-Default unit is in kilobytes.
.TP
.BR \-\-discards " {" \fIignore | \fInopassdown | \fIpassdown }
Specifies whether or not discards will be processed by the thin layer in the
@@ -306,7 +310,7 @@ Default is \fIpassdown\fP.
Controls zeroing of the first 4KiB of data in the snapshot.
If the volume is read-only the snapshot will not be zeroed.
For thin pool volumes it controls zeroing of provisioned blocks.
-Note: Provisioning of large zeroed chunks impacts performance.
+Note: Provisioning of large zeroed chunks negatively impacts performance.
.TP
.B \-\-merge
Merges a snapshot into its origin volume or merges a raid1 image that has
@@ -327,25 +331,35 @@ be specified on the commandline or a @tag may be used to specify
multiple snapshots be merged to their respective origin.
.TP
.B \-\-originname \fINewExternalOriginVolumeName\fP
-The new name for original logical volume, which becomes external origin volume.
+The new name for original logical volume, which becomes external origin volume
+for a thin logical volume that will use given \fB\-\-thinpool\fP.
.br
-Without this option a default names of "lvol#" will be generated where
-# is the LVM internal number of the logical volume.
+Without this option a default name of "lvol<n>" will be generated where
+<n> is the LVM internal number of the logical volume.
This volume will be read-only and cannot be further modified as long,
-as it is being used as external origin.
+as it is being used as the external origin.
.TP
.BR \-\-poolmetadata " " \fIThinPoolMetadataLogicalVolume { \fIName | \fIPath }
-Specifies thin pool metadata logical volume.
+Specifies cache or thin pool metadata logical volume.
The size should be in between 2MiB and 16GiB.
+Cache pool is specified with the option
+\fB\-\-cachepool\fP.
Thin pool is specified with the option
\fB\-\-thinpool\fP.
-When the specified thin pool already exists,
-the thin pool's metadata volume will be swapped with the given LV.
-Properties of the thin pool like chunk size, discards or zero
+When the specified pool already exists,
+the pool's metadata volume will be swapped with the given LV.
+Pool properties (like chunk size, discards or zero)
are preserved by default in this case.
-It can be useful for thin pool metadata repair or its offline resize,
-since the content of metadata becomes accessible for
-thin provisioning tools \fBthin_dump\fP(8) and \fBthin_restore\fP(8).
+It can be useful for pool metadata repair or its offline resize,
+since the metadata volume is available as regular volume for a user with
+thin provisioning tools
+.BR cache_dump (8),
+.BR cache_repair (8),
+.BR cache_restore (8),
+.BR thin_dump (8),
+.BR thin_repair (8)
+and
+.BR thin_restore (8).
.TP
.BR \-\-poolmetadatasize " " \fIThinPoolMetadataSize [ \fIbBsSkKmMgG ]
Sets the size of thin pool's metadata logical volume,
@@ -380,13 +394,16 @@ Only inactive thin pool volumes can be repaired.
There is no validation of metadata between kernel and lvm2.
This requires further manual work.
After successfull repair the old unmodified metadata are still
-available in \fB<pool>_meta<n>\fP LV.
+available in "<pool>_meta<n>" LV.
.TP
.B \-\-replace \fIPhysicalVolume
Remove the specified device (\fIPhysicalVolume\fP) and replace it with one
that is available in the volume group or from the specific list provided.
This option is only available to RAID segment types
-(e.g. "raid1", "raid5", etc).
+(e.g.
+.IR raid1 ,
+.IR raid5 ,
+etc).
.TP
.BR \-\-stripes " " \fIStripes
Gives the number of stripes.
@@ -401,17 +418,17 @@ StripeSize must be 2^n (n = 2 to 9) for metadata in LVM1 format.
For metadata in LVM2 format, the stripe size may be a larger
power of 2 but must not exceed the physical extent size.
.TP
-.IR \fB\-T ", " \fB\-\-thin " " ExternalOriginLogicalVolume { Name | Path }
+.IR \fB\-T ", " \fB\-\-thin ", " \fB\-\-type " " thin
Converts the logical volume into a thin logical volume of the thin pool
specified with \fB\-\-thinpool\fP. The original logical volume
.I ExternalOriginLogicalVolume
is renamed into a new read-only logical volume.
-The non-default name for this volume use \fB\-\-originname\fP.
+For the non-default name for this volume use \fB\-\-originname\fP.
The volume cannot be further modified as long as it is used as an
external origin volume for unprovisioned areas of any thin logical volume.
.TP
.IR \fB\-\-thinpool " " ThinPoolLogicalVolume { Name | Path }
-Switches logical volume into a thin pool's data volume.
+Specifies or converts logical volume into a thin pool's data volume.
Content of converted volume is lost.
Thin pool's metadata logical volume can be specified with the option
\fB\-\-poolmetadata\fP or allocated with \fB\-\-poolmetadatasize\fP.
@@ -507,14 +524,14 @@ and convert "vg00/lv1" into a thin volume using this pool. Original "vg00/lv1"
is used as an external read-only origin, where all writes to such volume
are stored in the "vg00/lvpool".
.sp
-.B lvconvert \-\-thinpool vg00/lvpool \-c 128 \-T lv1
+.B lvconvert \-\-type thin \-\-thinpool vg00/lvpool \-c 128 lv1
Convert the logical volume "vg00/origin" into a thin volume from the thin pool
"vg00/lvpool". This thin volume will use "vg00/origin" as an external origin
volume for unprovisioned areas in this volume.
For the read-only external origin use the new name "vg00/external".
.sp
-.B lvconvert \-\-thinpool vg00/lvpool \-\-originname external \-T vg00/origin
+.B lvconvert \-T \-\-thinpool vg00/lvpool \-\-originname external vg00/origin
Convert an existing logical volume to a cache pool LV using the
given cache metadata LV.
@@ -526,7 +543,7 @@ given cache metadata LV.
Convert an existing logical volume to a cache LV using the given
cache pool LV.
.sp
-.B lvconvert \-\-type cache \-\-cachepool vg00/lvx_cachepool vg00/lvx
+.B lvconvert \-\-cache \-\-cachepool vg00/lvx_cachepool vg00/lvx
.SH SEE ALSO
.BR lvm (8),
@@ -540,6 +557,9 @@ cache pool LV.
.BR lvrename (8),
.BR lvscan (8),
.BR vgcreate (8),
+.BR cache_dump (8),
+.BR cache_repair (8),
+.BR cache_restore (8),
.BR thin_dump (8),
-.BR thin_repair (8)
+.BR thin_repair (8),
.BR thin_restore (8)
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=b2988a917af8ca16…
Commit: b2988a917af8ca16814b067c1d73f899e871e1d4
Parent: 970989655ff5cd9ca960bf3113b7bfdf6f575d78
Author: Zdenek Kabelac <zkabelac(a)redhat.com>
AuthorDate: Mon Jul 7 22:54:33 2014 +0200
Committer: Zdenek Kabelac <zkabelac(a)redhat.com>
CommitterDate: Fri Jul 11 13:32:22 2014 +0200
lvconvert: update help
Extend help for lvconvert.
Use COMMON_OPTS for some common options.
---
tools/commands.h | 68 ++++++++++++++++++-----------------------------------
1 files changed, 23 insertions(+), 45 deletions(-)
diff --git a/tools/commands.h b/tools/commands.h
index 5fae835..1f9d03c 100644
--- a/tools/commands.h
+++ b/tools/commands.h
@@ -47,7 +47,6 @@ xx(devtypes,
"\t[--separator Separator]\n"
"\t[--unbuffered]\n"
"\t[--unquoted]\n"
- "\t[-v|--verbose]\n"
"\t[--version]" "\n",
aligned_ARG, binary_ARG, nameprefixes_ARG,
@@ -154,6 +153,10 @@ xx(lvchange,
refresh_ARG, setactivationskip_ARG, syncaction_ARG, sysinit_ARG, test_ARG,
writebehind_ARG, writemostly_ARG, zero_ARG)
+#define COMMON_OPTS \
+ "\t[--commandprofile ProfileName] [-d|--debug] [-h|-?|--help]\n" \
+ "\t[--noudevsync] [-t|--test] [-v|--verbose] [--version] [-y|--yes]\n"
+
xx(lvconvert,
"Change logical volume layout",
0,
@@ -165,88 +168,64 @@ xx(lvconvert,
"\t[-R|--regionsize MirrorLogRegionSize]\n"
"\t[--alloc AllocationPolicy]\n"
"\t[-b|--background]\n"
- "\t[--commandprofile ProfileName]\n"
- "\t[-d|--debug]\n"
"\t[-f|--force]\n"
- "\t[-h|-?|--help]\n"
"\t[-i|--interval seconds]\n"
"\t[--stripes Stripes [-I|--stripesize StripeSize]]\n"
- "\t[--noudevsync]\n"
- "\t[-v|--verbose]\n"
- "\t[-y|--yes]\n"
- "\t[--version]" "\n"
+ COMMON_OPTS
"\tLogicalVolume[Path] [PhysicalVolume[Path]...]\n\n"
"lvconvert "
"[--splitmirrors Images --trackchanges]\n"
- "[--splitmirrors Images --name SplitLogicalVolumeName]\n"
- "\t[--commandprofile ProfileName]\n"
+ "\t[--splitmirrors Images --name SplitLogicalVolumeName]\n"
+ COMMON_OPTS
"\tLogicalVolume[Path] [SplittablePhysicalVolume[Path]...]\n\n"
"lvconvert "
"--splitsnapshot\n"
- "\t[--commandprofile ProfileName]\n"
- "\t[-d|--debug]\n"
- "\t[-h|-?|--help]\n"
- "\t[--noudevsync]\n"
- "\t[-v|--verbose]\n"
- "\t[--version]" "\n"
+ COMMON_OPTS
"\tSnapshotLogicalVolume[Path]\n\n"
"lvconvert "
- "[-s|--snapshot]\n"
+ "[--type snapshot|-s|--snapshot]\n"
"\t[-c|--chunksize]\n"
- "\t[--commandprofile ProfileName]\n"
- "\t[-d|--debug]\n"
- "\t[-h|-?|--help]\n"
- "\t[--noudevsync]\n"
- "\t[-v|--verbose]\n"
"\t[-Z|--zero {y|n}]\n"
- "\t[--version]" "\n"
+ COMMON_OPTS
"\tOriginalLogicalVolume[Path] SnapshotLogicalVolume[Path]\n\n"
"lvconvert "
"--merge\n"
"\t[-b|--background]\n"
"\t[-i|--interval seconds]\n"
- "\t[--commandprofile ProfileName]\n"
- "\t[-d|--debug]\n"
- "\t[-h|-?|--help]\n"
- "\t[-v|--verbose]\n"
+ COMMON_OPTS
"\tLogicalVolume[Path]\n\n"
"lvconvert "
- "--thinpool ThinPoolLogicalVolume[Path]\n"
+ "[--type thin[-pool]|-T|--thin]\n"
+ "\t[--thinpool ThinPoolLogicalVolume[Path]]\n"
"\t[--chunksize size]\n"
"\t[--discards {ignore|nopassdown|passdown}]\n"
+ "\t[--poolmetadataspare {y|n}]\n"
"\t[--poolmetadata ThinMetadataLogicalVolume[Path] |\n"
"\t [--poolmetadatasize size]\n"
- "\t [--poolmetadataspare {y|n}]\n"
"\t [-r|--readahead ReadAheadSectors|auto|none]\n"
"\t [--stripes Stripes [-I|--stripesize StripeSize]]]\n"
- "\t[-T|--thin ExternalLogicalVolume[Path]\n"
- "\t [--originname NewExternalOriginVolumeName]]\n"
+ "\t[--originname NewExternalOriginVolumeName]]\n"
"\t[-Z|--zero {y|n}]\n"
- "\t[--commandprofile ProfileName]\n"
- "\t[-d|--debug] [-h|-?|--help] [-v|--verbose]\n\n"
+ COMMON_OPTS
+ "\t[ExternalOrigin|ThinDataPool]LogicalVolume[Path]\n\n"
"lvconvert "
- "--type cache-pool\n"
+ "[--type cache[-pool]|--cache]\n"
+ "\t[--cachepool CacheDataLogicalVolume[Path]]\n"
"\t[--cachemode CacheMode]\n"
"\t[--chunksize size]\n"
+ "\t[--poolmetadataspare {y|n}]]\n"
"\t[--poolmetadata CacheMetadataLogicalVolume[Path] |\n"
"\t [--poolmetadatasize size]\n"
- "\t [--poolmetadataspare {y|n}]]\n"
- "\t[--commandprofile ProfileName]\n"
- "\tCacheDataLogicalVolume[Path]\n\n"
+ COMMON_OPTS
+ "\t[Cache|CacheDataPool]LogicalVolume[Path]\n\n",
- "lvconvert "
- "--type cache\n"
- "\t--cachepool CachePoolLogicalVolume[Path]\n"
- "\t[--commandprofile ProfileName]\n"
- "\tLogicalVolume[Path]\n\n",
-
- alloc_ARG, background_ARG, cachemode_ARG, cachepool_ARG, chunksize_ARG,
+ alloc_ARG, background_ARG, cache_ARG, cachemode_ARG, cachepool_ARG, chunksize_ARG,
corelog_ARG, discards_ARG, force_ARG, interval_ARG, merge_ARG, mirrorlog_ARG,
mirrors_ARG, name_ARG, noudevsync_ARG, originname_ARG, poolmetadata_ARG,
poolmetadatasize_ARG, poolmetadataspare_ARG, readahead_ARG, regionsize_ARG,
@@ -1278,4 +1257,3 @@ xx(version,
"Display software and driver version information",
PERMITTED_READ_ONLY,
"version\n" )
-
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=970989655ff5cd9c…
Commit: 970989655ff5cd9ca960bf3113b7bfdf6f575d78
Parent: fe3ea94e5846f48baf3b00d0f6b913f585b4404e
Author: Zdenek Kabelac <zkabelac(a)redhat.com>
AuthorDate: Fri Jul 11 12:15:23 2014 +0200
Committer: Zdenek Kabelac <zkabelac(a)redhat.com>
CommitterDate: Fri Jul 11 13:32:22 2014 +0200
lvconvert: update for thin a cache
Major update of lvconvert code to handle cache and thin.
related targets.
Code tries to unify handling of cache and thin pools.
Better supports lvm2 syntax:
lvconvert --type cache --cachepool vg/pool vg/cache
lvconvert --type thin --thinpool vg/pool vg/extorg
lvconvert --type cache-pool vg/pool
lvconvert --type thin-pool vg/pool
as well as:
lvconvert --cache --cachepool vg/pool vg/cache
lvconvert --thin --thinpool vg/pool vg/extorg
lvconvert --cachepool vg/pool
lvconvert --thinpool vg/pool
While catching much more command line errors.
(Yet couple paths still needs more tests)
Detects as much cmdline errors prior opening VG.
Uses single lvconvert_name_params to convert LV names.
Detects as much incompatibilies in VG prior prompting.
Uses single prompt to confirm whole conversion.
TODO: still the code needs fixes...
---
WHATS_NEW | 1 +
tools/lvconvert.c | 992 ++++++++++++++++++++++++++++-------------------------
tools/toollib.c | 22 +-
3 files changed, 539 insertions(+), 476 deletions(-)
diff --git a/WHATS_NEW b/WHATS_NEW
index 6cbf221..a81fddb 100644
--- a/WHATS_NEW
+++ b/WHATS_NEW
@@ -1,5 +1,6 @@
Version 2.02.108 -
=================================
+ Enhance lvconvert thin, thinpool, cache and cachepool command line support.
Display 'C' only for cache and cache-pool target types in lvs.
Prompt for confirmation before change LV into a snapshot exception store.
Return proper error codes for some failing lvconvert funtions.
diff --git a/tools/lvconvert.c b/tools/lvconvert.c
index 8c960f9..9710134 100644
--- a/tools/lvconvert.c
+++ b/tools/lvconvert.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2005-2013 Red Hat, Inc. All rights reserved.
+ * Copyright (C) 2005-2014 Red Hat, Inc. All rights reserved.
*
* This file is part of LVM2.
*
@@ -17,6 +17,7 @@
#include "lv_alloc.h"
struct lvconvert_params {
+ int cache;
int force;
int snapshot;
int splitsnapshot;
@@ -27,8 +28,6 @@ struct lvconvert_params {
int yes;
int zero;
- const char *origin;
- const char *cachepool;
const char *lv_name;
const char *lv_split_name;
const char *lv_name_full;
@@ -64,84 +63,88 @@ struct lvconvert_params {
struct logical_volume *lv_to_poll;
int passed_args;
- uint64_t poolmetadata_size;
+ uint64_t pool_metadata_size;
const char *origin_lv_name;
const char *pool_data_lv_name;
+ struct logical_volume *pool_data_lv;
const char *pool_metadata_lv_name;
+ struct logical_volume *pool_metadata_lv;
thin_discards_t discards;
};
+static int _lvconvert_vg_name(struct lvconvert_params *lp,
+ struct cmd_context *cmd,
+ const char **lv_name)
+{
+ const char *vg_name;
+ const char *tmp_str;
+
+ if (!lv_name || !*lv_name)
+ return 1;
+
+ /* If contains VG name, extract it. */
+ if ((tmp_str = strchr(*lv_name, (int) '/'))) {
+ if (!(vg_name = extract_vgname(cmd, *lv_name)))
+ return_0;
+ if (!lp->vg_name)
+ lp->vg_name = vg_name;
+ else if (strcmp(vg_name, lp->vg_name)) {
+ log_error("Please use a single volume group name "
+ "(\"%s\" or \"%s\")", vg_name, lp->vg_name);
+ return 0;
+ }
+ /* Strip VG from lv_name */
+ *lv_name = tmp_str + 1;
+ }
+
+ if (!apply_lvname_restrictions(*lv_name))
+ return_0;
+
+ return 1;
+}
+
static int _lvconvert_name_params(struct lvconvert_params *lp,
struct cmd_context *cmd,
int *pargc, char ***pargv)
{
char *ptr;
const char *vg_name = NULL;
- const char *tmp_str;
if (lp->merge)
return 1;
- if (lp->snapshot) {
- if (!*pargc) {
+ if (!*pargc) {
+ if (lp->cache) {
+ log_error("Logical volume name for caching is missing.");
+ return 0;
+ }
+ if (lp->thin) {
log_error("Please specify a logical volume to act as "
- "the snapshot origin.");
+ "the external origin.");
return 0;
}
-
- lp->origin = *pargv[0];
- (*pargv)++, (*pargc)--;
- if (!(lp->vg_name = extract_vgname(cmd, lp->origin))) {
- log_error("The origin name should include the "
- "volume group.");
+ if (lp->snapshot) {
+ log_error("Please specify a logical volume to act as "
+ "the snapshot exception store.");
return 0;
}
-
- /* Strip the volume group from the origin */
- if ((ptr = strrchr(lp->origin, (int) '/')))
- lp->origin = ptr + 1;
- }
-
- if (lp->pool_data_lv_name) {
- if (*pargc) {
- if (!lp->thin) {
- log_error("More then one logical volume name specified.");
- return 0;
- }
- } else {
- if (lp->thin) {
- log_error("External thin volume name is missing.");
- return 0;
- }
-
- if (!lp->vg_name || !validate_name(lp->vg_name)) {
- log_error("Please provide a valid volume group name.");
- return 0;
- }
-
- lp->lv_name = lp->pool_data_lv_name;
- return 1;
+ if (!lp->lv_name_full) {
+ log_error("Please provide logical volume path.");
+ return 0;
}
+ } else if (!lp->lv_name_full) {
+ lp->lv_name_full = (*pargv)[0];
+ (*pargv)++, (*pargc)--;
}
- if (lp->origin_lv_name) {
- /* FIXME: Using generic routine */
- if (strchr(lp->origin_lv_name, '/')) {
- if (!(lp->vg_name = extract_vgname(cmd, lp->origin_lv_name)))
- return_0;
- /* Strip VG from origin_lv_name */
- if ((tmp_str = strrchr(lp->origin_lv_name, '/')))
- lp->origin_lv_name = tmp_str + 1;
- }
- }
+ if (!_lvconvert_vg_name(lp, cmd, &lp->pool_metadata_lv_name))
+ return_0;
- if (!*pargc) {
- log_error("Please provide logical volume path");
- return 0;
- }
+ if (!_lvconvert_vg_name(lp, cmd, &lp->pool_data_lv_name))
+ return_0;
- lp->lv_name = lp->lv_name_full = (*pargv)[0];
- (*pargv)++, (*pargc)--;
+ if (!_lvconvert_vg_name(lp, cmd, &lp->origin_lv_name))
+ return_0;
if (strchr(lp->lv_name_full, '/') &&
(vg_name = extract_vgname(cmd, lp->lv_name_full)) &&
@@ -161,6 +164,8 @@ static int _lvconvert_name_params(struct lvconvert_params *lp,
if ((ptr = strrchr(lp->lv_name_full, '/')))
lp->lv_name = ptr + 1;
+ else
+ lp->lv_name = lp->lv_name_full;
if (!lp->merge_mirror &&
!strstr(lp->lv_name, "_tdata") &&
@@ -168,19 +173,21 @@ static int _lvconvert_name_params(struct lvconvert_params *lp,
!apply_lvname_restrictions(lp->lv_name))
return_0;
- if (*pargc && lp->snapshot) {
- log_error("Too many arguments provided for snapshots");
- return 0;
- }
-
- if (lp->splitsnapshot && *pargc) {
- log_error("Too many arguments provided with --splitsnapshot.");
- return 0;
- }
-
- if (lp->pool_data_lv_name && lp->lv_name && lp->poolmetadata_size) {
- log_error("Please specify either metadata logical volume or its size.");
- return 0;
+ log_error("PAR %d t:%d c:%d m:%s d:%s l:%s", *pargc, lp->thin,lp->cache,
+ lp->pool_metadata_lv_name, lp->pool_data_lv_name, lp->lv_name);
+ if (*pargc) {
+ if (lp->snapshot) {
+ log_error("Too many arguments provided for snapshots.");
+ return 0;
+ }
+ if (lp->splitsnapshot) {
+ log_error("Too many arguments provided with --splitsnapshot.");
+ return 0;
+ }
+ if (lp->pool_data_lv_name && lp->pool_metadata_lv_name) {
+ log_error("Too many arguments provided for pool.");
+ return 0;
+ }
}
return 1;
@@ -219,11 +226,159 @@ static int _mirror_or_raid_type_requested(struct cmd_context *cmd, const char *t
return (arg_count(cmd, mirrors_ARG) || !strncmp(type_str, "raid", 4) || !strcmp(type_str, "mirror"));
}
+static int _read_pool_params(struct lvconvert_params *lp, struct cmd_context *cmd,
+ const char *type_str, int *pargc, char ***pargv)
+{
+ const char *tmp_str;
+ int cachepool = 0;
+ int thinpool = 0;
+
+ if (arg_count(cmd, cachepool_ARG)) {
+ if (type_str[0] &&
+ strcmp(type_str, "cache") &&
+ strcmp(type_str, "cache-pool")) {
+ log_error("--cachepool argument is only valid with "
+ " the cache or cache-pool segment type.");
+ return 0;
+ }
+ if (!(lp->pool_data_lv_name = arg_str_value(cmd, cachepool_ARG, NULL))) {
+ log_error("Missing cache pool logical volume name.");
+ return 0;
+ }
+ cachepool = 1;
+ type_str = "cache-pool";
+ } else if (!strcmp(type_str, "cache-pool"))
+ cachepool = 1;
+
+ if (arg_count(cmd, thinpool_ARG)) {
+ if (type_str[0] &&
+ strcmp(type_str, "thin") &&
+ strcmp(type_str, "thin-pool")) {
+ log_error("--thinpool argument is only valid with "
+ " the thin or thin-pool segment type.");
+ return 0;
+ }
+ if (!(lp->pool_data_lv_name = arg_str_value(cmd, thinpool_ARG, NULL))) {
+ log_error("Missing thin pool logical volume name.");
+ return 0;
+ }
+ thinpool = 1;
+ type_str = "thin-pool";
+ } else if (!strcmp(type_str, "thin-pool"))
+ thinpool = 1;
+
+ if (thinpool) {
+ lp->discards = (thin_discards_t) arg_uint_value(cmd, discards_ARG, THIN_DISCARDS_PASSDOWN);
+
+ if (arg_count(cmd, originname_ARG)) {
+ if (!(lp->origin_lv_name = arg_str_value(cmd, originname_ARG, NULL))) {
+ log_error("Missing --originname argument.");
+ return 0;
+ }
+ }
+ } else {
+ if (!arg_is_any_set(cmd, "is valid only with thin pools",
+ discards_ARG, originname_ARG, zero_ARG,
+ -1))
+ return_0;
+ if (lp->thin) {
+ log_error("--thin requires --thinpool.");
+ return 0;
+ }
+ }
+
+ if (cachepool) {
+ if ((tmp_str = arg_str_value(cmd, cachemode_ARG, NULL))) {
+ if (!strcmp(tmp_str, "writeback"))
+ lp->feature_flags |= DM_CACHE_FEATURE_WRITEBACK;
+ else if (!strcmp(tmp_str, "writethrough"))
+ lp->feature_flags |= DM_CACHE_FEATURE_WRITETHROUGH;
+ else {
+ log_error("Unknown cachemode argument");
+ return 0;
+ }
+ }
+ } else {
+ if (!arg_is_any_set(cmd, "is valid only with cache pools",
+ cachemode_ARG, -1))
+ return_0;
+ if (lp->cache) {
+ log_error("--cache requires --cachepool.");
+ return 0;
+ }
+ }
+
+ if (thinpool || cachepool) {
+ if (!arg_is_any_set(cmd, "is invalid with pools",
+ merge_ARG, mirrors_ARG, repair_ARG, snapshot_ARG,
+ splitmirrors_ARG, -1))
+ return_0;
+
+ if (arg_count(cmd, poolmetadatasize_ARG)) {
+ if (arg_sign_value(cmd, poolmetadatasize_ARG, SIGN_NONE) == SIGN_MINUS) {
+ log_error("Negative pool metadata size is invalid.");
+ return 0;
+ }
+ if (arg_count(cmd, poolmetadata_ARG)) {
+ log_error("Please specify either metadata logical volume or its size.");
+ return 0;
+ }
+ /* value is read in get_pool_params() */
+ }
+
+ if (arg_count(cmd, poolmetadata_ARG)) {
+ if (arg_count(cmd, stripesize_ARG) || arg_count(cmd, stripes_long_ARG)) {
+ log_error("Can't use --stripes and --stripesize with --poolmetadata.");
+ return 0;
+ }
+
+ if (arg_count(cmd, readahead_ARG)) {
+ log_error("Can't use --readahead with --poolmetadata.");
+ return 0;
+ }
+
+ if (!(lp->pool_metadata_lv_name = arg_str_value(cmd, poolmetadata_ARG, NULL))) {
+ log_error("Missing --poolmetadata argument.");
+ return 0;
+ }
+ }
+
+ if (arg_count(cmd, chunksize_ARG) &&
+ (arg_sign_value(cmd, chunksize_ARG, SIGN_NONE) == SIGN_MINUS)) {
+ log_error("Negative chunk size is invalid.");
+ return 0;
+ }
+
+ if (!arg_count(cmd, cachepool_ARG) &&
+ !arg_count(cmd, thinpool_ARG)) {
+ if (!*pargc) {
+ log_error("Please specify the pool data LV.");
+ return 0;
+ }
+ lp->pool_data_lv_name = (*pargv)[0];
+ (*pargv)++, (*pargc)--;
+ }
+
+ if (!lp->thin && !lp->cache)
+ lp->lv_name_full = lp->pool_data_lv_name;
+ /* Hmm _read_activation_params */
+ lp->read_ahead = arg_uint_value(cmd, readahead_ARG,
+ cmd->default_settings.read_ahead);
+
+ if (!(lp->segtype = get_segtype_from_string(cmd, type_str)))
+ return_0;
+ } else if (!arg_is_any_set(cmd, "is valid only with pools",
+ poolmetadatasize_ARG, poolmetadataspare_ARG,
+ -1))
+ return_0;
+
+ return 1;
+}
+
static int _read_params(struct lvconvert_params *lp, struct cmd_context *cmd,
int argc, char **argv)
{
int i;
- int cache_pool = 0;
const char *tmp_str;
struct arg_value_group_list *group;
int region_size;
@@ -269,84 +424,45 @@ static int _read_params(struct lvconvert_params *lp, struct cmd_context *cmd,
return 0;
}
- if (!strcmp(type_str, "cache-pool")) {
- cache_pool = 1;
- if ((tmp_str = arg_str_value(cmd, cachemode_ARG, NULL))) {
- if (!strcmp(tmp_str, "writeback"))
- lp->feature_flags |= DM_CACHE_FEATURE_WRITEBACK;
- else if (!strcmp(tmp_str, "writethrough"))
- lp->feature_flags |= DM_CACHE_FEATURE_WRITETHROUGH;
- else {
- log_error("Unknown cachemode argument");
- return 0;
- }
- }
- }
+ if (arg_count(cmd, cache_ARG))
+ lp->cache = 1;
- if (!arg_count(cmd, background_ARG))
- lp->wait_completion = 1;
-
- if (_snapshot_type_requested(cmd, type_str))
- lp->snapshot = 1;
-
- if (_snapshot_type_requested(cmd, type_str) && arg_count(cmd, merge_ARG)) {
- log_error("--snapshot and --merge are mutually exclusive");
- return 0;
- }
-
- if (arg_count(cmd, splitmirrors_ARG) && _mirror_or_raid_type_requested(cmd, type_str)) {
- log_error("--mirrors/--type mirror/--type raid* and --splitmirrors are "
- "mutually exclusive");
- return 0;
+ if (!strcmp(type_str, "cache"))
+ lp->cache = 1;
+ else if (lp->cache) {
+ if (type_str[0]) {
+ log_error("--cache is incompatible with --type %s", type_str);
+ return 0;
+ }
+ type_str = "cache";
}
if (arg_count(cmd, thin_ARG))
lp->thin = 1;
- if (arg_count(cmd, cachepool_ARG)) {
- if (strcmp(type_str, "cache")) {
- log_error("--cachepool argument is only valid with "
- " the \"cache\" segment type");
+ if (!strcmp(type_str, "thin"))
+ lp->thin = 1;
+ else if (lp->thin) {
+ if (type_str[0]) {
+ log_error("--thin is incompatible with --type %s", type_str);
return 0;
}
- lp->cachepool = arg_str_value(cmd, cachepool_ARG, NULL);
- } else if (arg_count(cmd, thinpool_ARG) || cache_pool) {
+ type_str = "thin";
+ }
+
+ if (!_read_pool_params(lp, cmd, type_str, &argc, &argv))
+ return_0;
+
+ if (!arg_count(cmd, background_ARG))
+ lp->wait_completion = 1;
+
+ if (_snapshot_type_requested(cmd, type_str)) {
if (arg_count(cmd, merge_ARG)) {
- log_error("--%spool and --merge are mutually exlusive.",
- cache_pool ? "type cache_" : "thin");
+ log_error("--snapshot and --merge are mutually exclusive.");
return 0;
}
- if (_mirror_or_raid_type_requested(cmd, type_str)) {
- log_error("--%spool and --mirrors/--type mirror/--type raid* are mutually exlusive.",
- cache_pool ? "type cache_" : "thin");
- return 0;
- }
- if (arg_count(cmd, repair_ARG)) {
- log_error("--%spool and --repair are mutually exlusive.",
- cache_pool ? "type cache_" : "thin");
- return 0;
- }
- if (_snapshot_type_requested(cmd, type_str)) {
- log_error("--%spool and --snapshot/--type snapshot are mutually exlusive.",
- cache_pool ? "type cache_" : "thin");
- return 0;
- }
- if (arg_count(cmd, splitmirrors_ARG)) {
- log_error("--%spool and --splitmirrors are mutually exlusive.",
- cache_pool ? "type cache_" : "thin");
- return 0;
- }
- if (!cache_pool)
- lp->discards = (thin_discards_t) arg_uint_value(cmd, discards_ARG, THIN_DISCARDS_PASSDOWN);
- } else if (lp->thin) {
- log_error("--thin is only valid with --thinpool.");
- return 0;
- } else if (arg_count(cmd, discards_ARG)) {
- log_error("--discards is only valid with --thinpool.");
- return 0;
- } else if (arg_count(cmd, poolmetadataspare_ARG)) {
- log_error("--poolmetadataspare is only valid with --thinpool.");
- return 0;
+
+ lp->snapshot = 1;
}
/*
@@ -356,6 +472,11 @@ static int _read_params(struct lvconvert_params *lp, struct cmd_context *cmd,
* discarding it.
*/
if (arg_count(cmd, splitmirrors_ARG)) {
+ if (_mirror_or_raid_type_requested(cmd, type_str)) {
+ log_error("--mirrors/--type mirror/--type raid* and --splitmirrors are "
+ "mutually exclusive.");
+ return 0;
+ }
if (!arg_count(cmd, name_ARG) &&
!arg_count(cmd, trackchanges_ARG)) {
log_error("Please name the new logical volume using '--name'");
@@ -437,6 +558,13 @@ static int _read_params(struct lvconvert_params *lp, struct cmd_context *cmd,
} else if (lp->splitsnapshot) /* Destroy snapshot retaining cow as separate LV */
;
else if (lp->snapshot) { /* Snapshot creation from pre-existing cow */
+ if (!argc) {
+ log_error("Please provide logical volume path for snaphost origin.");
+ return 0;
+ }
+ lp->origin_lv_name = argv[0];
+ argv++, argc--;
+
if (arg_count(cmd, regionsize_ARG)) {
log_error("--regionsize is only available with mirrors");
return 0;
@@ -490,65 +618,7 @@ static int _read_params(struct lvconvert_params *lp, struct cmd_context *cmd,
tmp_str)))
return_0;
}
- } else if (arg_count(cmd, thinpool_ARG) || cache_pool) {
- if (cache_pool) {
- if (!argc) {
- log_error("Please specify the pool data LV.");
- return 0;
- }
- lp->pool_data_lv_name = argv[0];
- argv++, argc--;
- } else if (!(lp->pool_data_lv_name = arg_str_value(cmd, thinpool_ARG, NULL))) {
- log_error("Missing pool logical volume name.");
- return 0;
- }
-
- if (arg_count(cmd, poolmetadata_ARG)) {
- if (arg_count(cmd, poolmetadatasize_ARG)) {
- log_error("--poolmetadatasize is invalid with --poolmetadata.");
- return 0;
- }
- if (arg_count(cmd, stripesize_ARG) || arg_count(cmd, stripes_long_ARG)) {
- log_error("Can't use --stripes and --stripesize with --poolmetadata.");
- return 0;
- }
-
- if (arg_count(cmd, readahead_ARG)) {
- log_error("Can't use --readahead with --poolmetadata.");
- return 0;
- }
- lp->pool_metadata_lv_name = arg_str_value(cmd, poolmetadata_ARG, "");
- }
-
- /* Hmm _read_activation_params */
- lp->read_ahead = arg_uint_value(cmd, readahead_ARG,
- cmd->default_settings.read_ahead);
-
- /* If pool_data_lv_name contains VG name, extract it. */
- if ((tmp_str = strchr(lp->pool_data_lv_name, (int) '/'))) {
- if (!(lp->vg_name = extract_vgname(cmd, lp->pool_data_lv_name)))
- return 0;
- /* Strip VG from pool */
- lp->pool_data_lv_name = tmp_str + 1;
- }
-
- if (arg_count(cmd, originname_ARG)) {
- if (!(lp->origin_lv_name = arg_str_value(cmd, originname_ARG, NULL))) {
- log_error("--originname is invalid.");
- return 0;
- }
- }
-
- lp->segtype = get_segtype_from_string(cmd, arg_str_value(cmd, type_ARG, cache_pool ? "cache-pool" : "thin-pool"));
- if (!lp->segtype)
- return_0;
-
- if (arg_count(cmd, chunksize_ARG) &&
- (arg_sign_value(cmd, chunksize_ARG, SIGN_NONE) == SIGN_MINUS)) {
- log_error("Negative chunk size is invalid.");
- return 0;
- }
- } else { /* Mirrors (and some RAID functions) */
+ } else if (_mirror_or_raid_type_requested(cmd, type_str)) { /* Mirrors (and some RAID functions) */
if (arg_count(cmd, chunksize_ARG)) {
log_error("--chunksize is only available with snapshots or pools.");
return 0;
@@ -2046,14 +2116,14 @@ static int _lvconvert_snapshot(struct cmd_context *cmd,
return 0;
}
- if (!(org = find_lv(lv->vg, lp->origin))) {
- log_error("Couldn't find origin volume '%s'.", lp->origin);
+ if (!(org = find_lv(lv->vg, lp->origin_lv_name))) {
+ log_error("Couldn't find origin volume %s.", lp->origin_lv_name);
return 0;
}
if (org == lv) {
- log_error("Unable to use \"%s\" as both snapshot and origin.",
- lv->name);
+ log_error("Unable to use %s as both snapshot and origin.",
+ display_lvname(lv));
return 0;
}
@@ -2327,9 +2397,9 @@ out:
return r;
}
-static int _lvconvert_thinpool_repair(struct cmd_context *cmd,
- struct logical_volume *pool_lv,
- struct lvconvert_params *lp)
+static int _lvconvert_pool_repair(struct cmd_context *cmd,
+ struct logical_volume *pool_lv,
+ struct lvconvert_params *lp)
{
const char *dmdir = dm_dir();
const char *thin_dump =
@@ -2526,12 +2596,12 @@ deactivate_pmslv:
return 1;
}
-static int _lvconvert_thinpool_external(struct cmd_context *cmd,
- struct logical_volume *pool_lv,
- struct logical_volume *external_lv,
- struct lvconvert_params *lp)
+/* Currently converts only to thin volume with external origin */
+static int _lvconvert_thin(struct cmd_context *cmd,
+ struct logical_volume *lv,
+ struct lvconvert_params *lp)
{
- struct logical_volume *torigin_lv;
+ struct logical_volume *torigin_lv, *pool_lv = lp->pool_data_lv;
struct volume_group *vg = pool_lv->vg;
struct lvcreate_params lvc = {
.activate = CHANGE_AE,
@@ -2544,18 +2614,33 @@ static int _lvconvert_thinpool_external(struct cmd_context *cmd,
.pvh = &vg->pvs,
.read_ahead = DM_READ_AHEAD_AUTO,
.stripes = 1,
- .voriginextents = external_lv->le_count,
- .voriginsize = external_lv->size,
+ .voriginextents = lv->le_count,
+ .voriginsize = lv->size,
};
+ if (lv == pool_lv) {
+ log_error("Can't use same LV %s for thin pool and thin volume.",
+ display_lvname(pool_lv));
+ return 0;
+ }
+
+ if (lv_is_thin_pool(lv)) {
+ log_error("Can't use pool %s as external origin.",
+ display_lvname(lv));
+ return 0;
+ }
+
dm_list_init(&lvc.tags);
- if (!pool_supports_external_origin(first_seg(pool_lv), external_lv))
+ if (!pool_supports_external_origin(first_seg(pool_lv), lv))
return_0;
if (!(lvc.segtype = get_segtype_from_string(cmd, "thin")))
return_0;
+ if (!archive(vg))
+ return_0;
+
/* New thin LV needs to be created (all messages sent to pool) */
if (!(torigin_lv = lv_create_single(vg, &lvc)))
return_0;
@@ -2572,15 +2657,15 @@ static int _lvconvert_thinpool_external(struct cmd_context *cmd,
* which could be easily removed by the user after i.e. power-off
*/
- if (!_swap_lv_identifiers(cmd, torigin_lv, external_lv)) {
+ if (!_swap_lv_identifiers(cmd, torigin_lv, lv)) {
stack;
goto revert_new_lv;
}
/* Preserve read-write status of original LV here */
- torigin_lv->status |= (external_lv->status & LVM_WRITE);
+ torigin_lv->status |= (lv->status & LVM_WRITE);
- if (!attach_thin_external_origin(first_seg(torigin_lv), external_lv)) {
+ if (!attach_thin_external_origin(first_seg(torigin_lv), lv)) {
stack;
goto revert_new_lv;
}
@@ -2590,15 +2675,17 @@ static int _lvconvert_thinpool_external(struct cmd_context *cmd,
goto deactivate_and_revert_new_lv;
}
- log_print_unless_silent("Converted \"%s/%s\" to thin volume with "
- "external origin \"%s/%s\".",
- vg->name, torigin_lv->name,
- vg->name, external_lv->name);
+ log_print_unless_silent("Converted %s to thin volume with "
+ "external origin %s.",
+ display_lvname(torigin_lv),
+ display_lvname(lv));
+
+ backup(vg);
return 1;
deactivate_and_revert_new_lv:
- if (!_swap_lv_identifiers(cmd, torigin_lv, external_lv))
+ if (!_swap_lv_identifiers(cmd, torigin_lv, lv))
stack;
if (!deactivate_lv(cmd, torigin_lv)) {
@@ -2632,7 +2719,7 @@ static int _lvconvert_update_pool_params(struct logical_volume *pool_lv,
&lp->thin_chunk_size_calc_policy,
&lp->chunk_size,
&lp->discards,
- &lp->poolmetadata_size,
+ &lp->pool_metadata_size,
&lp->zero);
return update_thin_pool_params(pool_lv->vg, lp->target_attr,
@@ -2642,101 +2729,95 @@ static int _lvconvert_update_pool_params(struct logical_volume *pool_lv,
&lp->thin_chunk_size_calc_policy,
&lp->chunk_size,
&lp->discards,
- &lp->poolmetadata_size,
+ &lp->pool_metadata_size,
&lp->zero);
}
-
-
/*
* Thin lvconvert version which
* rename metadata
* convert/layers thinpool over data
* attach metadata
*/
-static int _lvconvert_to_pool(struct cmd_context *cmd,
- struct logical_volume *pool_lv,
- struct lvconvert_params *lp)
+static int _lvconvert_pool(struct cmd_context *cmd,
+ struct logical_volume *pool_lv,
+ struct lvconvert_params *lp)
{
int r = 0;
- uint64_t min_metadata_size;
- uint64_t max_metadata_size;
const char *old_name;
struct lv_segment *seg;
+ struct volume_group *vg = pool_lv->vg;
struct logical_volume *data_lv;
- struct logical_volume *metadata_lv;
+ struct logical_volume *metadata_lv = NULL;
struct logical_volume *pool_metadata_lv;
- struct logical_volume *external_lv = NULL;
char metadata_name[NAME_LEN], data_name[NAME_LEN];
int activate_pool;
- if (!lv_is_visible(pool_lv)) {
- log_error("Can't convert internal LV %s/%s.",
- pool_lv->vg->name, pool_lv->name);
+ if (lp->pool_data_lv_name &&
+ !(pool_lv = find_lv(vg, lp->pool_data_lv_name))) {
+ log_error("Unknown pool data LV %s.", lp->pool_data_lv_name);
return 0;
}
- if (lv_is_mirrored(pool_lv) && !lv_is_raid_type(pool_lv)) {
- log_error("Mirror logical volumes cannot be used as thinpools.\n"
- "Try \"raid1\" segment type instead.");
- return 0;
- }
-
- if (lp->thin) {
- if (strcmp(pool_lv->name, lp->pool_data_lv_name) == 0) {
- log_error("Can't use same LV %s/%s for thin pool and thin volume.",
- pool_lv->vg->name, pool_lv->name);
+ if (lp->pool_metadata_lv_name) {
+ if (!(lp->pool_metadata_lv = find_lv(vg, lp->pool_metadata_lv_name))) {
+ log_error("Unknown pool metadata LV %s.", lp->pool_metadata_lv_name);
return 0;
}
+ lp->pool_metadata_size = lp->pool_metadata_lv->size;
+ metadata_lv = lp->pool_metadata_lv;
- external_lv = pool_lv;
- if (!(pool_lv = find_lv(external_lv->vg, lp->pool_data_lv_name))) {
- log_error("Can't find pool LV %s/%s.",
- external_lv->vg->name, lp->pool_data_lv_name);
+ if (!lv_is_visible(metadata_lv)) {
+ log_error("Can't convert internal LV %s.",
+ display_lvname(metadata_lv));
return 0;
}
-
- if (lv_is_thin_pool(external_lv)) {
- log_error("Can't convert pool \"%s/%s\" to external origin.",
- external_lv->vg->name, lp->pool_data_lv_name);
+ if (lv_is_mirrored(metadata_lv) && !lv_is_raid_type(metadata_lv)) {
+ log_error("Mirror logical volumes cannot be used "
+ "for pool metadata.");
+ log_error("Try \"raid1\" segment type instead.");
+ return 0;
+ }
+ if (metadata_lv->status & LOCKED) {
+ log_error("Can't convert locked LV %s.",
+ display_lvname(metadata_lv));
+ return 0;
+ }
+ if (metadata_lv == pool_lv) {
+ log_error("Can't use same LV for pool data and metadata LV %s.",
+ display_lvname(metadata_lv));
+ return 0;
+ }
+ if (lv_is_thin_type(metadata_lv) ||
+ lv_is_cache_type(metadata_lv)) {
+ log_error("Can't use %s LV %s for pool metadata.",
+ lv_type_name(metadata_lv), display_lvname(metadata_lv));
return 0;
}
- if (lv_is_thin_pool(pool_lv)) {
- activate_pool = lv_is_active(pool_lv);
- r = 1; /* Already existing thin pool */
- goto out;
+ if (!lv_is_pool(pool_lv)) {
+ if (!_lvconvert_update_pool_params(pool_lv, lp))
+ return_0;
+
+ if (lp->pool_metadata_size > metadata_lv->size) {
+ log_error("Logical volume %s is too small for metadata.",
+ display_lvname(metadata_lv));
+ return 0;
+ }
}
}
- if (lv_is_thin_type(pool_lv) && !lp->pool_metadata_lv_name) {
- log_error("Can't use thin logical volume %s/%s for thin pool data.",
- pool_lv->vg->name, pool_lv->name);
+ if (!lv_is_visible(pool_lv)) {
+ log_error("Can't convert internal LV %s.", display_lvname(pool_lv));
return 0;
}
- if (segtype_is_cache_pool(lp->segtype))
- activate_pool = 0; /* Cannot activate cache pool */
- else
- /* Allow to have only thinpool active and restore it's active state */
- activate_pool = lv_is_active(pool_lv);
-
- /* We are changing target type, so deactivate first */
- if (!deactivate_lv(cmd, pool_lv)) {
- log_error("Aborting. Failed to deactivate logical volume %s/%s.",
- pool_lv->vg->name, pool_lv->name);
+ if (lv_is_mirrored(pool_lv) && !lv_is_raid_type(pool_lv)) {
+ log_error("Mirror logical volumes cannot be used as pools.\n"
+ "Try \"raid1\" segment type instead.");
return 0;
}
- if (lv_is_thin_pool(pool_lv)) {
- if (pool_is_active(pool_lv)) {
- /* If any thin volume is also active - abort here */
- log_error("Cannot convert pool %s/%s with active thin volumes.",
- pool_lv->vg->name, pool_lv->name);
- return 0;
- }
- }
-
if ((dm_snprintf(metadata_name, sizeof(metadata_name), "%s%s",
pool_lv->name,
(segtype_is_cache_pool(lp->segtype)) ?
@@ -2750,149 +2831,144 @@ static int _lvconvert_to_pool(struct cmd_context *cmd,
return 0;
}
- if (!lp->pool_metadata_lv_name) {
- if (!_lvconvert_update_pool_params(pool_lv, lp))
- return_0;
-
- if (!get_stripe_params(cmd, &lp->stripes, &lp->stripe_size))
- return_0;
+ if (lv_is_pool(pool_lv)) {
+ lp->pool_data_lv = pool_lv;
- if (!(metadata_lv = alloc_pool_metadata(pool_lv, metadata_name,
- lp->read_ahead, lp->stripes,
- lp->stripe_size,
- lp->poolmetadata_size,
- lp->alloc, lp->pvh)))
- return_0;
- } else {
- if (!(metadata_lv = find_lv(pool_lv->vg, lp->pool_metadata_lv_name))) {
- log_error("Unknown metadata LV %s.", lp->pool_metadata_lv_name);
- return 0;
- }
- if (!lv_is_visible(metadata_lv)) {
- log_error("Can't convert internal LV %s/%s.",
- metadata_lv->vg->name, metadata_lv->name);
- return 0;
- }
- if (lv_is_mirrored(pool_lv) && !lv_is_raid_type(pool_lv)) {
- log_error("Mirror logical volumes cannot be used"
- " for thinpool metadata.\n"
- "Try \"raid1\" segment type instead.");
- return 0;
- }
- if (metadata_lv->status & LOCKED) {
- log_error("Can't convert locked LV %s/%s.",
- metadata_lv->vg->name, metadata_lv->name);
- return 0;
+ if (!metadata_lv) {
+ if (!arg_is_any_set(cmd, "is invalid with existing pool",
+ cachemode_ARG,chunksize_ARG, discards_ARG,
+ zero_ARG, poolmetadatasize_ARG, -1))
+ return_0;
+ return 1;
}
- if (metadata_lv == pool_lv) {
- log_error("Can't use same LV for thin pool data and metadata LV %s/%s.",
- metadata_lv->vg->name, metadata_lv->name);
+
+ if (lp->thin || lp->cache) {
+ log_error("--%s and pool metadata swap is not supported.",
+ lp->thin ? "thin" : "cache");
return 0;
}
- if (lv_is_thin_type(metadata_lv)) {
- log_error("Can't use thin type LV %s/%s for thin pool metadata.",
- metadata_lv->vg->name, metadata_lv->name);
+
+ /* FIXME cache pool */
+ if (lv_is_thin_pool(pool_lv) && pool_is_active(pool_lv)) {
+ /* If any volume referencing pool active - abort here */
+ log_error("Cannot convert pool %s with active volumes.",
+ display_lvname(pool_lv));
return 0;
}
- /* Swap normal LV with pool's metadata LV ? */
- if (lv_is_thin_pool(pool_lv)) {
- if (!deactivate_lv(cmd, metadata_lv)) {
- log_error("Aborting. Failed to deactivate LV %s/%s.",
- metadata_lv->vg->name, metadata_lv->name);
- return 0;
- }
+ seg = first_seg(pool_lv);
- seg = first_seg(pool_lv);
-
- if (!arg_count(cmd, chunksize_ARG))
- lp->chunk_size = seg->chunk_size;
- else if (lp->chunk_size != seg->chunk_size) {
- if (lp->force == PROMPT) {
- log_error("Chunk size can be only changed with --force. Conversion aborted.");
- return 0;
- }
- /* Ok, user has likely some serious reason for this */
- if (!lp->yes &&
- yes_no_prompt("Do you really want to change chunk size %s to %s "
- "for %s/%s pool volume? [y/n]: ",
- display_size(cmd, seg->chunk_size),
- display_size(cmd, lp->chunk_size),
- pool_lv->vg->name, pool_lv->name) == 'n') {
- log_error("Conversion aborted.");
- return 0;
- }
- log_warn("WARNING: Changing chunk size %s to %s for %s/%s pool volume.",
- display_size(cmd, seg->chunk_size),
- display_size(cmd, lp->chunk_size),
- pool_lv->vg->name, pool_lv->name);
+ /* Normally do NOT change chunk size when swapping */
+ if (arg_count(cmd, chunksize_ARG) &&
+ (lp->chunk_size != seg->chunk_size)) {
+ if (lp->force == PROMPT) {
+ log_error("Chunk size can be only changed with --force. Conversion aborted.");
+ return 0;
}
-
+ log_warn("WARNING: Changing chunk size %s to "
+ "%s for %s pool volume.",
+ display_size(cmd, seg->chunk_size),
+ display_size(cmd, lp->chunk_size),
+ display_lvname(pool_lv));
+ /* Ok, user has likely some serious reason for this */
if (!lp->yes &&
- yes_no_prompt("Do you want to swap metadata of %s/%s pool with "
- "volume %s/%s? [y/n]: ",
- pool_lv->vg->name, pool_lv->name,
- metadata_lv->vg->name, metadata_lv->name) == 'n') {
+ yes_no_prompt("Do you really want to change chunk size "
+ "for %s pool volume? [y/n]: ",
+ display_lvname(pool_lv)) == 'n') {
log_error("Conversion aborted.");
return 0;
}
+ } else
+ lp->chunk_size = seg->chunk_size;
- /* Swap names between old and new metadata LV */
- if (!detach_pool_metadata_lv(seg, &pool_metadata_lv))
- return_0;
- old_name = metadata_lv->name;
- if (!lv_rename_update(cmd, metadata_lv, "pvmove_tmeta", 0))
- return_0;
- if (!lv_rename_update(cmd, pool_metadata_lv, old_name, 0))
- return_0;
+ if (!_lvconvert_update_pool_params(pool_lv, lp))
+ return_0;
- if (!arg_count(cmd, discards_ARG))
- lp->discards = seg->discards;
- if (!arg_count(cmd, zero_ARG))
- lp->zero = seg->zero_new_blocks;
+ if (metadata_lv->size < lp->pool_metadata_size)
+ log_print_unless_silent("Continuing with swap...");
- goto mda_write;
- }
+ if (!arg_count(cmd, discards_ARG))
+ lp->discards = seg->discards;
+ if (!arg_count(cmd, zero_ARG))
+ lp->zero = seg->zero_new_blocks;
- if (!deactivate_lv(cmd, metadata_lv)) {
- log_error("Aborting. Failed to deactivate \"%s/%s\".",
- metadata_lv->vg->name, metadata_lv->name);
+ if (!lp->yes &&
+ yes_no_prompt("Do you want to swap metadata of %s "
+ "pool with %s volume %s? [y/n]: ",
+ display_lvname(pool_lv),
+ lv_type_name(metadata_lv),
+ display_lvname(metadata_lv)) == 'n') {
+ log_error("Conversion aborted.");
return 0;
}
+ } else if (lv_is_thin_type(pool_lv)) {
+ log_error("Can't use %s logical volume %s for thin pool data.",
+ lv_type_name(pool_lv), display_lvname(pool_lv));
+ return 0;
+ } else {
+ log_warn("WARNING: Converting logical volume %s%s%s to pool's data%s.",
+ display_lvname(pool_lv),
+ metadata_lv ? " and " : "",
+ metadata_lv ? display_lvname(metadata_lv) : "",
+ metadata_lv ? " and metadata volumes" : " volume");
+ log_warn("THIS WILL DESTROY CONTENT OF LOGICAL VOLUME (filesystem etc.)");
- lp->poolmetadata_size = metadata_lv->size;
- max_metadata_size = (segtype_is_cache_pool(lp->segtype)) ?
- DEFAULT_CACHE_POOL_MAX_METADATA_SIZE * 2 :
- DEFAULT_THIN_POOL_MAX_METADATA_SIZE * 2;
- min_metadata_size = (segtype_is_cache_pool(lp->segtype)) ?
- DEFAULT_CACHE_POOL_MIN_METADATA_SIZE * 2 :
- DEFAULT_THIN_POOL_MIN_METADATA_SIZE * 2;
-
- if (lp->poolmetadata_size > max_metadata_size) {
- log_warn("WARNING: Maximum size used by metadata is %s, rest is unused.",
- display_size(cmd, max_metadata_size));
- lp->poolmetadata_size = max_metadata_size;
- } else if (lp->poolmetadata_size < min_metadata_size) {
- log_error("Logical volume %s/%s is too small (<%s) for metadata.",
- metadata_lv->vg->name, metadata_lv->name,
- display_size(cmd, min_metadata_size));
+ if (!lp->yes &&
+ yes_no_prompt("Do you really want to convert %s%s%s? [y/n]: ",
+ display_lvname(pool_lv),
+ metadata_lv ? " and " : "",
+ metadata_lv ? display_lvname(metadata_lv) : "") == 'n') {
+ log_error("Conversion aborted.");
return 0;
}
+ }
+ if (segtype_is_cache_pool(lp->segtype))
+ activate_pool = 0; /* Cannot activate cache pool */
+ else
+ /* Allow to have only thinpool active and restore it's active state */
+ activate_pool = lv_is_active(pool_lv);
+
+ if (!metadata_lv) {
if (!_lvconvert_update_pool_params(pool_lv, lp))
return_0;
- log_warn("WARNING: Converting logical volume %s/%s to pool's metadata volume.",
- metadata_lv->vg->name, metadata_lv->name);
- log_warn("THIS WILL DESTROY CONTENT OF LOGICAL VOLUME (filesystem etc.)");
+ if (!get_stripe_params(cmd, &lp->stripes, &lp->stripe_size))
+ return_0;
- if (!lp->yes &&
- yes_no_prompt("Do you really want to convert %s/%s? [y/n]: ",
- metadata_lv->vg->name, metadata_lv->name) == 'n') {
- log_error("Conversion aborted.");
+ if (!archive(vg))
+ return_0;
+
+ if (!(metadata_lv = alloc_pool_metadata(pool_lv, metadata_name,
+ lp->read_ahead, lp->stripes,
+ lp->stripe_size,
+ lp->pool_metadata_size,
+ lp->alloc, lp->pvh)))
+ return_0;
+ } else {
+ if (!deactivate_lv(cmd, metadata_lv)) {
+ log_error("Aborting. Failed to deactivate %s.",
+ display_lvname(metadata_lv));
return 0;
}
+ if (!archive(vg))
+ return_0;
+
+ /* Swap normal LV with pool's metadata LV ? */
+ if (lv_is_pool(pool_lv)) {
+ /* Swap names between old and new metadata LV */
+ if (!detach_pool_metadata_lv(seg, &pool_metadata_lv))
+ return_0;
+ old_name = metadata_lv->name;
+ if (!lv_rename_update(cmd, metadata_lv, "pvmove_tmeta", 0))
+ return_0;
+ if (!lv_rename_update(cmd, pool_metadata_lv, old_name, 0))
+ return_0;
+
+ goto mda_write;
+ }
+
metadata_lv->status |= LV_TEMPORARY;
if (!activate_lv_local(cmd, metadata_lv)) {
log_error("Aborting. Failed to activate metadata lv.");
@@ -2905,27 +2981,17 @@ static int _lvconvert_to_pool(struct cmd_context *cmd,
}
}
+ /* We are changing target type, so deactivate first */
if (!deactivate_lv(cmd, metadata_lv)) {
log_error("Aborting. Failed to deactivate metadata lv. "
"Manual intervention required.");
return 0;
}
- if (!handle_pool_metadata_spare(pool_lv->vg, metadata_lv->le_count,
- lp->pvh, lp->poolmetadataspare))
- return_0;
-
- if (!lv_is_thin_pool(pool_lv)) {
- log_warn("WARNING: Converting logical volume %s/%s to pool's data volume.",
- pool_lv->vg->name, pool_lv->name);
- log_warn("THIS WILL DESTROY CONTENT OF LOGICAL VOLUME (filesystem etc.)");
-
- if (!lp->yes &&
- yes_no_prompt("Do you really want to convert %s/%s? [y/n]: ",
- pool_lv->vg->name, pool_lv->name) == 'n') {
- log_error("Conversion aborted.");
- return 0;
- }
+ if (!deactivate_lv(cmd, pool_lv)) {
+ log_error("Aborting. Failed to deactivate logical volume %s.",
+ display_lvname(pool_lv));
+ return 0;
}
data_lv = pool_lv;
@@ -2943,12 +3009,12 @@ static int _lvconvert_to_pool(struct cmd_context *cmd,
((segtype_is_cache_pool(lp->segtype)) ?
CACHE_POOL : THIN_POOL) |
VISIBLE_LV | LVM_READ | LVM_WRITE,
- ALLOC_INHERIT, data_lv->vg))) {
+ ALLOC_INHERIT, vg))) {
log_error("Creation of pool LV failed.");
return 0;
}
- /* Allocate a new linear segment */
+ /* Allocate a new pool segment */
if (!(seg = alloc_lv_segment(lp->segtype, pool_lv, 0, data_lv->le_count,
pool_lv->status, 0, NULL, NULL, 1,
data_lv->le_count, 0, 0, 0, NULL)))
@@ -2982,13 +3048,22 @@ mda_write:
if (!attach_pool_metadata_lv(seg, metadata_lv))
return_0;
- if (!vg_write(pool_lv->vg) || !vg_commit(pool_lv->vg))
+ if (!handle_pool_metadata_spare(vg, metadata_lv->le_count,
+ lp->pvh, lp->poolmetadataspare))
return_0;
+ if (!vg_write(vg) || !vg_commit(vg))
+ return_0;
+
+ if (seg->zero_new_blocks &&
+ seg->chunk_size >= DEFAULT_THIN_POOL_CHUNK_SIZE_PERFORMANCE * 2)
+ log_warn("WARNING: Pool zeroing and large %s chunk size slows down "
+ "provisioning.", display_size(cmd, seg->chunk_size));
+
if (activate_pool &&
!activate_lv_excl(cmd, pool_lv)) {
- log_error("Failed to activate pool logical volume %s/%s.",
- pool_lv->vg->name, pool_lv->name);
+ log_error("Failed to activate pool logical volume %s.",
+ display_lvname(pool_lv));
/* Deactivate subvolumes */
if (!deactivate_lv(cmd, seg_lv(seg, 0)))
log_error("Failed to deactivate pool data logical volume.");
@@ -2997,53 +3072,68 @@ mda_write:
goto out;
}
- log_print_unless_silent("Converted \"%s/%s\" to %s pool.",
- pool_lv->vg->name, pool_lv->name,
+ log_print_unless_silent("Converted %s to %s pool.",
+ display_lvname(pool_lv),
(segtype_is_cache_pool(lp->segtype)) ?
"cache" : "thin");
r = 1;
-out:
- if (r && external_lv &&
- !(r = _lvconvert_thinpool_external(cmd, pool_lv, external_lv, lp)))
- stack;
- backup(pool_lv->vg);
+ lp->pool_data_lv = pool_lv;
+
+out:
+ backup(vg);
return r;
+#if 0
+revert_new_lv:
+ /* TBD */
+ if (!lp->pool_metadata_lv_name) {
+ if (!deactivate_lv(cmd, metadata_lv)) {
+ log_error("Failed to deactivate metadata lv.");
+ return 0;
+ }
+ if (!lv_remove(metadata_lv) || !vg_write(vg) || !vg_commit(vg))
+ log_error("Manual intervention may be required to remove "
+ "abandoned LV(s) before retrying.");
+ else
+ backup(vg);
+ }
+
+ return 0;
+#endif
}
-static int _lvconvert_cache(struct logical_volume *origin,
+static int _lvconvert_cache(struct cmd_context *cmd,
+ struct logical_volume *origin,
struct lvconvert_params *lp)
{
- struct cmd_context *cmd = origin->vg->cmd;
+ struct logical_volume *pool_lv = lp->pool_data_lv;
struct logical_volume *cache_lv;
- struct logical_volume *cachepool;
- if (!lp->cachepool) {
- log_error("--cachepool argument is required.");
+ if (origin == pool_lv) {
+ log_error("Can't use same LV %s for cache pool and cache volume.",
+ display_lvname(pool_lv));
return 0;
}
- if (!(cachepool = find_lv(origin->vg, lp->cachepool))) {
- log_error("Unable to find cache pool LV, %s", lp->cachepool);
+ if (lv_is_pool(origin) || lv_is_cache_type(origin)) {
+ log_error("Can't cache %s volume %s.",
+ lv_type_name(origin), display_lvname(origin));
return 0;
}
- if (!(cache_lv = lv_cache_create(cachepool, origin)))
+ if (!archive(origin->vg))
return_0;
- if (!vg_write(cache_lv->vg))
- return_0;
- if (!suspend_lv(cmd, cache_lv))
- return_0;
- if (!vg_commit(cache_lv->vg))
+ if (!(cache_lv = lv_cache_create(pool_lv, origin)))
return_0;
- if (!resume_lv(cmd, cache_lv))
+
+ if (!_reload_lv(cmd, cache_lv->vg, cache_lv))
return_0;
- log_print_unless_silent("%s/%s is now cached.",
- cache_lv->vg->name, cache_lv->name);
+ log_print_unless_silent("Logical volume %s is now cached.",
+ display_lvname(cache_lv));
return 1;
}
@@ -3073,8 +3163,8 @@ static int _lvconvert_single(struct cmd_context *cmd, struct logical_volume *lv,
if (lp->splitsnapshot)
return _lvconvert_splitsnapshot(cmd, lv, lp);
- if (arg_count(cmd, repair_ARG) && lv_is_thin_pool(lv)) {
- if (!_lvconvert_thinpool_repair(cmd, lv, lp))
+ if (arg_count(cmd, repair_ARG) && lv_is_pool(lv)) {
+ if (!_lvconvert_pool_repair(cmd, lv, lp))
return_ECMD_FAILED;
return ECMD_PROCESSED;
}
@@ -3112,28 +3202,19 @@ static int _lvconvert_single(struct cmd_context *cmd, struct logical_volume *lv,
} else if (lp->snapshot) {
if (!_lvconvert_snapshot(cmd, lv, lp))
return_ECMD_FAILED;
-
- } else if (segtype_is_cache(lp->segtype)) {
- if (!archive(lv->vg))
+ } else if (segtype_is_pool(lp->segtype) || lp->thin || lp->cache) {
+ if (!get_pool_params(cmd, lv_config_profile(lv),
+ &lp->passed_args, &lp->thin_chunk_size_calc_policy,
+ &lp->chunk_size, &lp->discards,
+ &lp->pool_metadata_size, &lp->zero))
return_ECMD_FAILED;
- if (!_lvconvert_cache(lv, lp))
+ if (!_lvconvert_pool(cmd, lv, lp))
return_ECMD_FAILED;
- } else if (segtype_is_cache_pool(lp->segtype)) {
- if (!archive(lv->vg))
+ if ((lp->thin && !_lvconvert_thin(cmd, lv, lp)) ||
+ (lp->cache && !_lvconvert_cache(cmd, lv, lp)))
return_ECMD_FAILED;
-
- if (!_lvconvert_to_pool(cmd, lv, lp))
- return_ECMD_FAILED;
-
- } else if (arg_count(cmd, thinpool_ARG)) {
- if (!archive(lv->vg))
- return_ECMD_FAILED;
-
- if (!_lvconvert_to_pool(cmd, lv, lp))
- return_ECMD_FAILED;
-
} else if (segtype_is_raid(lp->segtype) ||
(lv->status & RAID) || lp->merge_mirror) {
if (!archive(lv->vg))
@@ -3223,16 +3304,9 @@ static int lvconvert_single(struct cmd_context *cmd, struct lvconvert_params *lp
cmd->handles_missing_pvs = 1;
}
- lv = get_vg_lock_and_logical_volume(cmd, lp->vg_name, lp->lv_name);
- if (!lv)
+ if (!(lv = get_vg_lock_and_logical_volume(cmd, lp->vg_name, lp->lv_name)))
goto_out;
- if (!get_pool_params(cmd, lv_config_profile(lv),
- &lp->passed_args, &lp->thin_chunk_size_calc_policy,
- &lp->chunk_size, &lp->discards,
- &lp->poolmetadata_size, &lp->zero))
- goto_bad;
-
/*
* lp->pvh holds the list of PVs available for allocation or removal
*/
diff --git a/tools/toollib.c b/tools/toollib.c
index b4e02d6..312a76d 100644
--- a/tools/toollib.c
+++ b/tools/toollib.c
@@ -1661,18 +1661,9 @@ int get_pool_params(struct cmd_context *cmd,
{
int cache_pool = 0;
- if (!strcmp("cache-pool", arg_str_value(cmd, type_ARG, "none")))
+ if (!strcmp("cache-pool", arg_str_value(cmd, type_ARG, "")))
cache_pool = 1;
- if (!cache_pool && !arg_count(cmd, thinpool_ARG)) {
- /* Check for arguments that should only go with pools */
- if (arg_count(cmd, poolmetadata_ARG)) {
- log_error("'--poolmetadata' argument is only valid when"
- " converting to pool LVs.");
- return_0;
- }
- }
-
*passed_args = 0;
if (!cache_pool && arg_count(cmd, zero_ARG)) {
*passed_args |= PASS_ARG_ZERO;
@@ -1706,14 +1697,11 @@ int get_pool_params(struct cmd_context *cmd,
return_0;
if (arg_count(cmd, poolmetadatasize_ARG)) {
- if (arg_sign_value(cmd, poolmetadatasize_ARG, SIGN_NONE) == SIGN_MINUS) {
- log_error("Negative pool metadata size is invalid.");
- return 0;
- }
*passed_args |= PASS_ARG_POOL_METADATA_SIZE;
- }
- *pool_metadata_size = arg_uint64_value(cmd, poolmetadatasize_ARG,
- UINT64_C(0));
+ *pool_metadata_size = arg_uint64_value(cmd, poolmetadatasize_ARG,
+ UINT64_C(0));
+ } else if (arg_count(cmd, poolmetadata_ARG))
+ *passed_args |= PASS_ARG_POOL_METADATA_SIZE; /* fixed size */
return 1;
}
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=fe3ea94e5846f48b…
Commit: fe3ea94e5846f48baf3b00d0f6b913f585b4404e
Parent: 9955204e0d9d8d50c19564d475ece03995a6e837
Author: Zdenek Kabelac <zkabelac(a)redhat.com>
AuthorDate: Mon Jul 7 22:40:36 2014 +0200
Committer: Zdenek Kabelac <zkabelac(a)redhat.com>
CommitterDate: Fri Jul 11 13:32:22 2014 +0200
cleanup: shift detection of chunksize sign
Sign should be checked prior opening of VG.
Since get_pool_params() needs profiles,
we need to move check for sign earlier.
---
tools/lvconvert.c | 15 +++++++++++----
tools/lvcreate.c | 12 +++++++-----
tools/toollib.c | 4 ----
3 files changed, 18 insertions(+), 13 deletions(-)
diff --git a/tools/lvconvert.c b/tools/lvconvert.c
index 95ca245..8c960f9 100644
--- a/tools/lvconvert.c
+++ b/tools/lvconvert.c
@@ -447,10 +447,12 @@ static int _read_params(struct lvconvert_params *lp, struct cmd_context *cmd,
return 0;
}
- if (arg_sign_value(cmd, chunksize_ARG, SIGN_NONE) == SIGN_MINUS) {
- log_error("Negative chunk size is invalid");
+ if (arg_count(cmd, chunksize_ARG) &&
+ (arg_sign_value(cmd, chunksize_ARG, SIGN_NONE) == SIGN_MINUS)) {
+ log_error("Negative chunk size is invalid.");
return 0;
}
+
lp->chunk_size = arg_uint_value(cmd, chunksize_ARG, 8);
if (lp->chunk_size < 8 || lp->chunk_size > 1024 ||
(lp->chunk_size & (lp->chunk_size - 1))) {
@@ -540,10 +542,15 @@ static int _read_params(struct lvconvert_params *lp, struct cmd_context *cmd,
lp->segtype = get_segtype_from_string(cmd, arg_str_value(cmd, type_ARG, cache_pool ? "cache-pool" : "thin-pool"));
if (!lp->segtype)
return_0;
+
+ if (arg_count(cmd, chunksize_ARG) &&
+ (arg_sign_value(cmd, chunksize_ARG, SIGN_NONE) == SIGN_MINUS)) {
+ log_error("Negative chunk size is invalid.");
+ return 0;
+ }
} else { /* Mirrors (and some RAID functions) */
if (arg_count(cmd, chunksize_ARG)) {
- log_error("--chunksize is only available with "
- "snapshots or thin pools.");
+ log_error("--chunksize is only available with snapshots or pools.");
return 0;
}
diff --git a/tools/lvcreate.c b/tools/lvcreate.c
index 47459ec..8e45cc1 100644
--- a/tools/lvcreate.c
+++ b/tools/lvcreate.c
@@ -1033,6 +1033,12 @@ static int _lvcreate_params(struct lvcreate_params *lp,
lp->wipe_signatures = 0;
}
+ if (arg_count(cmd, chunksize_ARG) &&
+ (arg_sign_value(cmd, chunksize_ARG, SIGN_NONE) == SIGN_MINUS)) {
+ log_error("Negative chunk size is invalid.");
+ return 0;
+ }
+
if (!_lvcreate_name_params(lp, cmd, &argc, &argv) ||
!_read_size_params(lp, lcp, cmd) ||
!get_stripe_params(cmd, &lp->stripes, &lp->stripe_size) ||
@@ -1047,10 +1053,6 @@ static int _lvcreate_params(struct lvcreate_params *lp,
return_0;
if (lp->snapshot && (lp->extents || lcp->size)) {
- if (arg_sign_value(cmd, chunksize_ARG, SIGN_NONE) == SIGN_MINUS) {
- log_error("Negative chunk size is invalid.");
- return 0;
- }
lp->chunk_size = arg_uint_value(cmd, chunksize_ARG, 8);
if (lp->chunk_size < 8 || lp->chunk_size > 1024 ||
(lp->chunk_size & (lp->chunk_size - 1))) {
@@ -1063,7 +1065,7 @@ static int _lvcreate_params(struct lvcreate_params *lp,
if (!(lp->segtype = get_segtype_from_string(cmd, "snapshot")))
return_0;
} else if (!lp->create_pool && arg_count(cmd, chunksize_ARG)) {
- log_error("--chunksize is only available with snapshots and thin pools.");
+ log_error("--chunksize is only available with snapshots and pools.");
return 0;
}
diff --git a/tools/toollib.c b/tools/toollib.c
index 7cd6e60..b4e02d6 100644
--- a/tools/toollib.c
+++ b/tools/toollib.c
@@ -1688,10 +1688,6 @@ int get_pool_params(struct cmd_context *cmd,
}
if (arg_count(cmd, chunksize_ARG)) {
- if (arg_sign_value(cmd, chunksize_ARG, SIGN_NONE) == SIGN_MINUS) {
- log_error("Negative chunk size is invalid.");
- return 0;
- }
*passed_args |= PASS_ARG_CHUNK_SIZE;
*chunk_size = arg_uint_value(cmd, chunksize_ARG, cache_pool ?
DM_CACHE_MIN_DATA_BLOCK_SIZE :
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=9955204e0d9d8d50…
Commit: 9955204e0d9d8d50c19564d475ece03995a6e837
Parent: de1ee0bc52255987f3b21819a55c0ef9ddf261bb
Author: Zdenek Kabelac <zkabelac(a)redhat.com>
AuthorDate: Mon Jul 7 22:24:35 2014 +0200
Committer: Zdenek Kabelac <zkabelac(a)redhat.com>
CommitterDate: Fri Jul 11 13:32:21 2014 +0200
cleanup: reorder code
Simplify code.
---
lib/metadata/thin_manip.c | 8 ++++----
1 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/lib/metadata/thin_manip.c b/lib/metadata/thin_manip.c
index 33ab31c..28b6bbf 100644
--- a/lib/metadata/thin_manip.c
+++ b/lib/metadata/thin_manip.c
@@ -474,15 +474,15 @@ int update_thin_pool_params(struct volume_group *vg, unsigned attr,
}
if (*pool_metadata_size > (2 * DEFAULT_THIN_POOL_MAX_METADATA_SIZE)) {
+ *pool_metadata_size = 2 * DEFAULT_THIN_POOL_MAX_METADATA_SIZE;
if (passed_args & PASS_ARG_POOL_METADATA_SIZE)
log_warn("WARNING: Maximum supported pool metadata size is %s.",
- display_size(cmd, 2 * DEFAULT_THIN_POOL_MAX_METADATA_SIZE));
- *pool_metadata_size = 2 * DEFAULT_THIN_POOL_MAX_METADATA_SIZE;
+ display_size(cmd, *pool_metadata_size));
} else if (*pool_metadata_size < (2 * DEFAULT_THIN_POOL_MIN_METADATA_SIZE)) {
+ *pool_metadata_size = 2 * DEFAULT_THIN_POOL_MIN_METADATA_SIZE;
if (passed_args & PASS_ARG_POOL_METADATA_SIZE)
log_warn("WARNING: Minimum supported pool metadata size is %s.",
- display_size(cmd, 2 * DEFAULT_THIN_POOL_MIN_METADATA_SIZE));
- *pool_metadata_size = 2 * DEFAULT_THIN_POOL_MIN_METADATA_SIZE;
+ display_size(cmd, *pool_metadata_size));
}
log_verbose("Setting pool metadata size to %s.",
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=de1ee0bc52255987…
Commit: de1ee0bc52255987f3b21819a55c0ef9ddf261bb
Parent: d5d883d91ba132bd601fb27d44191d3a9c9f64f1
Author: Zdenek Kabelac <zkabelac(a)redhat.com>
AuthorDate: Wed Jul 9 17:22:16 2014 +0200
Committer: Zdenek Kabelac <zkabelac(a)redhat.com>
CommitterDate: Fri Jul 11 13:32:21 2014 +0200
cleanup: move merge option
Put long --merge option into section with long options.
---
tools/args.h | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/tools/args.h b/tools/args.h
index 9632478..dc467d2 100644
--- a/tools/args.h
+++ b/tools/args.h
@@ -59,6 +59,7 @@ arg(trackchanges_ARG, '\0', "trackchanges", NULL, 0)
arg(replace_ARG, '\0', "replace", string_arg, ARG_GROUPABLE)
arg(repair_ARG, '\0', "repair", NULL, 0)
arg(use_policies_ARG, '\0', "use-policies", NULL, 0)
+arg(merge_ARG, '\0', "merge", NULL, 0)
arg(monitor_ARG, '\0', "monitor", yes_no_arg, 0)
arg(config_ARG, '\0', "config", string_arg, 0)
arg(trustcache_ARG, '\0', "trustcache", NULL, 0)
@@ -152,7 +153,6 @@ arg(list_ARG, 'l', "list", NULL, 0)
arg(size_ARG, 'L', "size", size_mb_arg, 0)
arg(logicalextent_ARG, 'L', "logicalextent", int_arg_with_sign, 0)
arg(persistent_ARG, 'M', "persistent", yes_no_arg, 0)
-arg(merge_ARG, '\0', "merge", NULL, 0)
arg(major_ARG, 'j', "major", int_arg, ARG_GROUPABLE)
arg(setactivationskip_ARG, 'k', "setactivationskip", yes_no_arg, 0)
arg(ignoreactivationskip_ARG, 'K', "ignoreactivationskip", NULL, 0)
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=d5d883d91ba132bd…
Commit: d5d883d91ba132bd601fb27d44191d3a9c9f64f1
Parent: f7d661406196568abce68abb66a45b27177b4379
Author: Zdenek Kabelac <zkabelac(a)redhat.com>
AuthorDate: Fri Jul 11 12:25:18 2014 +0200
Committer: Zdenek Kabelac <zkabelac(a)redhat.com>
CommitterDate: Fri Jul 11 13:32:21 2014 +0200
cleanup: indent changes
---
tools/lvconvert.c | 34 +++++++++++++++++-----------------
tools/toollib.c | 4 ++--
2 files changed, 19 insertions(+), 19 deletions(-)
diff --git a/tools/lvconvert.c b/tools/lvconvert.c
index 2892d00..95ca245 100644
--- a/tools/lvconvert.c
+++ b/tools/lvconvert.c
@@ -553,9 +553,9 @@ static int _read_params(struct lvconvert_params *lp, struct cmd_context *cmd,
}
/*
- * --regionsize is only valid if converting an LV into a mirror.
- * Checked when we know the state of the LV being converted.
- */
+ * --regionsize is only valid if converting an LV into a mirror.
+ * Checked when we know the state of the LV being converted.
+ */
if (arg_count(cmd, regionsize_ARG)) {
if (arg_sign_value(cmd, regionsize_ARG, SIGN_NONE) ==
@@ -715,7 +715,7 @@ static int _finish_lvconvert_mirror(struct cmd_context *cmd,
log_very_verbose("Updating logical volume \"%s\" on disk(s)", lv->name);
- if (!(_reload_lv(cmd, vg, lv)))
+ if (!_reload_lv(cmd, vg, lv))
return_0;
log_print_unless_silent("Logical volume %s converted.", lv->name);
@@ -1026,7 +1026,7 @@ static struct dm_list *_failed_pv_list(struct volume_group *vg)
if (!is_missing_pv(pvl->pv))
continue;
- /*
+ /*
* Finally, --repair will remove empty PVs.
* But we only want remove these which are output of repair,
* Do not count these which are already empty here.
@@ -1992,20 +1992,20 @@ static int _lvconvert_splitsnapshot(struct cmd_context *cmd, struct logical_volu
return ECMD_FAILED;
}
- if (lv_info(cmd, cow, 0, &info, 1, 0)) {
- if (!lv_check_not_in_use(cmd, cow, &info))
+ if (lv_info(cmd, cow, 0, &info, 1, 0)) {
+ if (!lv_check_not_in_use(cmd, cow, &info))
return_ECMD_FAILED;
- if ((lp->force == PROMPT) &&
- lv_is_visible(cow) &&
- lv_is_active(cow)) {
- if (yes_no_prompt("Do you really want to split off active "
- "logical volume %s? [y/n]: ", cow->name) == 'n') {
- log_error("Logical volume %s not split.", cow->name);
- return ECMD_FAILED;
- }
- }
- }
+ if ((lp->force == PROMPT) &&
+ lv_is_visible(cow) &&
+ lv_is_active(cow)) {
+ if (yes_no_prompt("Do you really want to split off active "
+ "logical volume %s? [y/n]: ", cow->name) == 'n') {
+ log_error("Logical volume %s not split.", cow->name);
+ return ECMD_FAILED;
+ }
+ }
+ }
if (!archive(vg))
return_ECMD_FAILED;
diff --git a/tools/toollib.c b/tools/toollib.c
index 34db90c..7cd6e60 100644
--- a/tools/toollib.c
+++ b/tools/toollib.c
@@ -106,7 +106,7 @@ int become_daemon(struct cmd_context *cmd, int skip_lvm)
* Strip dev_dir if present
*/
const char *skip_dev_dir(struct cmd_context *cmd, const char *vg_name,
- unsigned *dev_dir_found)
+ unsigned *dev_dir_found)
{
const char *dmdir = dm_dir();
size_t dmdir_len = strlen(dmdir), vglv_sz;
@@ -1773,7 +1773,7 @@ int get_stripe_params(struct cmd_context *cmd, uint32_t *stripes, uint32_t *stri
return 0;
}
- if(arg_uint64_value(cmd, stripesize_ARG, 0) > STRIPE_SIZE_LIMIT * 2) {
+ if (arg_uint64_value(cmd, stripesize_ARG, 0) > STRIPE_SIZE_LIMIT * 2) {
log_error("Stripe size cannot be larger than %s",
display_size(cmd, (uint64_t) STRIPE_SIZE_LIMIT));
return 0;
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=f7d661406196568a…
Commit: f7d661406196568abce68abb66a45b27177b4379
Parent: 04b8e55f2a2a96d2ffbd124fe3c0fc7c452cfb26
Author: Zdenek Kabelac <zkabelac(a)redhat.com>
AuthorDate: Fri Jul 11 12:12:51 2014 +0200
Committer: Zdenek Kabelac <zkabelac(a)redhat.com>
CommitterDate: Fri Jul 11 13:31:19 2014 +0200
cache: warn about metadata size limits
Cache pools are similar as with thin pools.
Add (needs %s) - since cache has currently
a bit strange need for extra few kb over
our default 4M extent size so make it more obvious.
---
lib/metadata/cache_manip.c | 17 ++++++++++-------
1 files changed, 10 insertions(+), 7 deletions(-)
diff --git a/lib/metadata/cache_manip.c b/lib/metadata/cache_manip.c
index 6a0f0f6..e220dd9 100644
--- a/lib/metadata/cache_manip.c
+++ b/lib/metadata/cache_manip.c
@@ -60,15 +60,18 @@ int update_cache_pool_params(struct volume_group *vg, unsigned attr,
if (!*pool_metadata_size)
*pool_metadata_size = min_meta_size;
- if (*pool_metadata_size < min_meta_size) {
- *pool_metadata_size = min_meta_size;
- log_print("Increasing metadata device size to %"
- PRIu64 " sectors", *pool_metadata_size);
- }
if (*pool_metadata_size > (2 * DEFAULT_CACHE_POOL_MAX_METADATA_SIZE)) {
*pool_metadata_size = 2 * DEFAULT_CACHE_POOL_MAX_METADATA_SIZE;
- log_print("Reducing metadata device size to %" PRIu64 " sectors",
- *pool_metadata_size);
+ if (passed_args & PASS_ARG_POOL_METADATA_SIZE)
+ log_warn("WARNING: Maximum supported pool metadata size is %s.",
+ display_size(vg->cmd, *pool_metadata_size));
+ } else if (*pool_metadata_size < min_meta_size) {
+ if (passed_args & PASS_ARG_POOL_METADATA_SIZE)
+ log_warn("WARNING: Minimum supported pool metadata size is %s "
+ "(needs extra %s).",
+ display_size(vg->cmd, min_meta_size),
+ display_size(vg->cmd, min_meta_size - *pool_metadata_size));
+ *pool_metadata_size = min_meta_size;
}
return 1;
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=04b8e55f2a2a96d2…
Commit: 04b8e55f2a2a96d2ffbd124fe3c0fc7c452cfb26
Parent: 1931d1e58e1b7af8251d96ed84694c3ba5c7352e
Author: Zdenek Kabelac <zkabelac(a)redhat.com>
AuthorDate: Thu Jul 10 22:02:54 2014 +0200
Committer: Zdenek Kabelac <zkabelac(a)redhat.com>
CommitterDate: Fri Jul 11 12:57:45 2014 +0200
lvconvert: relocate mirror tests
---
tools/lvconvert.c | 25 ++++++++++++-------------
1 files changed, 12 insertions(+), 13 deletions(-)
diff --git a/tools/lvconvert.c b/tools/lvconvert.c
index 264b86c..2892d00 100644
--- a/tools/lvconvert.c
+++ b/tools/lvconvert.c
@@ -236,6 +236,18 @@ static int _read_params(struct lvconvert_params *lp, struct cmd_context *cmd,
if (!_check_conversion_type(cmd, type_str))
return_0;
+ if (arg_count(cmd, repair_ARG) &&
+ !arg_is_only_set(cmd, "cannot be used with --repair",
+ repair_ARG,
+ stripes_long_ARG, stripesize_ARG,
+ -1))
+ return_0;
+
+ if (arg_is_set(cmd, mirrorlog_ARG) && arg_is_set(cmd, corelog_ARG)) {
+ log_error("--mirrorlog and --corelog are incompatible.");
+ return 0;
+ }
+
if (arg_count(cmd, splitsnapshot_ARG))
lp->splitsnapshot = 1;
@@ -1273,19 +1285,6 @@ static int _lvconvert_mirrors_parse_params(struct cmd_context *cmd,
return 1;
}
- if ((arg_count(cmd, mirrors_ARG) && repair) ||
- (arg_count(cmd, mirrorlog_ARG) && repair) ||
- (arg_count(cmd, corelog_ARG) && repair)) {
- log_error("--repair cannot be used with --mirrors, --mirrorlog,"
- " or --corelog");
- return 0;
- }
-
- if (arg_count(cmd, mirrorlog_ARG) && arg_count(cmd, corelog_ARG)) {
- log_error("--mirrorlog and --corelog are incompatible");
- return 0;
- }
-
/*
* Adjusting mimage count?
*/
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=1931d1e58e1b7af8…
Commit: 1931d1e58e1b7af8251d96ed84694c3ba5c7352e
Parent: c0c1ada88eef8e112515f5415dc4dd89b4191214
Author: Zdenek Kabelac <zkabelac(a)redhat.com>
AuthorDate: Thu Jul 10 22:52:53 2014 +0200
Committer: Zdenek Kabelac <zkabelac(a)redhat.com>
CommitterDate: Fri Jul 11 12:57:45 2014 +0200
tools: arg_is_any_set and arg_is_only_set
Helpful functions to more easily detect conflicting
set of options.
---
tools/lvmcmdline.c | 55 ++++++++++++++++++++++++++++++++++++++++++++++++++++
tools/tools.h | 2 +
2 files changed, 57 insertions(+), 0 deletions(-)
diff --git a/tools/lvmcmdline.c b/tools/lvmcmdline.c
index fc51c4a..be7844b 100644
--- a/tools/lvmcmdline.c
+++ b/tools/lvmcmdline.c
@@ -68,6 +68,61 @@ unsigned arg_is_set(const struct cmd_context *cmd, int a)
return arg_count(cmd, a) ? 1 : 0;
}
+int arg_is_any_set(const struct cmd_context *cmd, const char *err, ...)
+{
+ int arg;
+ va_list ap;
+
+ va_start(ap, err);
+ while ((arg = va_arg(ap, int)) != -1 && !arg_count(cmd, arg))
+ /* empty */;
+ va_end(ap);
+
+ if (arg != -1) {
+ log_error("%s %s.", arg_long_option_name(arg), err);
+ return 0;
+ }
+
+ return 1;
+}
+
+int arg_is_only_set(const struct cmd_context *cmd, const char *err, ...)
+{
+ int i, arg;
+ va_list ap;
+
+ for (i = 0; i < ARG_COUNT; ++i) {
+ switch (i) {
+ /* skip common options */
+ case commandprofile_ARG:
+ case config_ARG:
+ case debug_ARG:
+ case driverloaded_ARG:
+ case help2_ARG:
+ case help_ARG:
+ case profile_ARG:
+ case quiet_ARG:
+ case verbose_ARG:
+ case version_ARG:
+ case yes_ARG:
+ continue;
+ }
+ if (!arg_count(cmd, i))
+ continue; /* unset */
+ va_start(ap, err);
+ while (((arg = va_arg(ap, int)) != -1) && (arg != i))
+ /* empty */;
+ va_end(ap);
+
+ if (arg != i) {
+ log_error("Option %s %s.", arg_long_option_name(i), err);
+ return 0;
+ }
+ }
+
+ return 1;
+}
+
unsigned grouped_arg_is_set(const struct arg_values *av, int a)
{
return grouped_arg_count(av, a) ? 1 : 0;
diff --git a/tools/tools.h b/tools/tools.h
index 2b09f37..a92845a 100644
--- a/tools/tools.h
+++ b/tools/tools.h
@@ -144,6 +144,8 @@ int major_minor_valid(const struct cmd_context * cmd, const struct format_type *
/* we use the enums to access the switches */
unsigned arg_count(const struct cmd_context *cmd, int a);
unsigned arg_is_set(const struct cmd_context *cmd, int a);
+int arg_is_any_set(const struct cmd_context *cmd, const char *err, ...);
+int arg_is_only_set(const struct cmd_context *cmd, const char *err, ...);
const char *arg_long_option_name(int a);
const char *arg_value(struct cmd_context *cmd, int a);
const char *arg_str_value(struct cmd_context *cmd, int a, const char *def);
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=c0c1ada88eef8e11…
Commit: c0c1ada88eef8e112515f5415dc4dd89b4191214
Parent: 120bd2d6b13fb7a297ff6cfc9fe59c0b241ab46f
Author: Zdenek Kabelac <zkabelac(a)redhat.com>
AuthorDate: Wed Jul 9 17:24:34 2014 +0200
Committer: Zdenek Kabelac <zkabelac(a)redhat.com>
CommitterDate: Fri Jul 11 12:57:45 2014 +0200
pool: callback handle cache
Extend the callback functionality to handle also cache pools.
cache_check is now executed on cachepool metadata when
it's activated and deactivated.
---
lib/activate/dev_manager.c | 172 +++++++++++++++++++++++++++++---------------
1 files changed, 114 insertions(+), 58 deletions(-)
diff --git a/lib/activate/dev_manager.c b/lib/activate/dev_manager.c
index 0305bb4..d5fe620 100644
--- a/lib/activate/dev_manager.c
+++ b/lib/activate/dev_manager.c
@@ -1703,114 +1703,153 @@ static int _add_partial_replicator_to_dtree(struct dev_manager *dm,
return 1;
}
-struct thin_cb_data {
- const struct logical_volume *pool_lv;
+struct pool_cb_data {
struct dev_manager *dm;
+ const struct logical_volume *pool_lv;
+
+ int skip_zero; /* to skip zeroed device header (check first 64B) */
+ int exec; /* which binary to call */
+ int opts;
+ const char *defaults;
+ const char *global;
};
-static int _thin_pool_callback(struct dm_tree_node *node,
- dm_node_callback_t type, void *cb_data)
+static int _pool_callback(struct dm_tree_node *node,
+ dm_node_callback_t type, void *cb_data)
{
- int ret, status;
- const struct thin_cb_data *data = cb_data;
- const char *dmdir = dm_dir();
+ int ret, status, fd;
+ char *split;
const struct dm_config_node *cn;
const struct dm_config_value *cv;
- const char *thin_check =
- find_config_tree_str_allow_empty(data->pool_lv->vg->cmd, global_thin_check_executable_CFG, NULL);
- const struct logical_volume *mlv = first_seg(data->pool_lv)->metadata_lv;
- size_t len = strlen(dmdir) + 2 * (strlen(mlv->vg->name) + strlen(mlv->name)) + 3;
- char meta_path[len];
+ const struct pool_cb_data *data = cb_data;
+ const struct logical_volume *pool_lv = data->pool_lv;
+ const struct logical_volume *mlv = first_seg(pool_lv)->metadata_lv;
+ long buf[64 / sizeof(long)]; /* buffer for short disk header (64B) */
int args = 0;
- const char *argv[19]; /* Max supported 15 args */
- char *split, *dm_name;
+ const char *argv[19] = { /* Max supported 15 args */
+ find_config_tree_str_allow_empty(pool_lv->vg->cmd, data->exec, NULL) /* argv[0] */
+ };
- if (!thin_check[0])
+ if (!*argv[0])
return 1; /* Checking disabled */
- if (!(dm_name = dm_build_dm_name(data->dm->mem, mlv->vg->name,
- mlv->name, NULL)) ||
- (dm_snprintf(meta_path, len, "%s/%s", dmdir, dm_name) < 0)) {
- log_error("Failed to build thin metadata path.");
- return 0;
- }
-
- if ((cn = find_config_tree_node(mlv->vg->cmd, global_thin_check_options_CFG, NULL))) {
+ if ((cn = find_config_tree_node(mlv->vg->cmd, data->opts, NULL))) {
for (cv = cn->v; cv && args < 16; cv = cv->next) {
if (cv->type != DM_CFG_STRING) {
log_error("Invalid string in config file: "
- "global/thin_check_options");
+ "global/%s_check_options",
+ data->global);
return 0;
}
argv[++args] = cv->v.str;
}
} else {
/* Use default options (no support for options with spaces) */
- if (!(split = dm_pool_strdup(data->dm->mem, DEFAULT_THIN_CHECK_OPTIONS))) {
- log_error("Failed to duplicate thin check string.");
+ if (!(split = dm_pool_strdup(data->dm->mem, data->defaults))) {
+ log_error("Failed to duplicate defaults.");
return 0;
}
args = dm_split_words(split, 16, 0, (char**) argv + 1);
}
if (args == 16) {
- log_error("Too many options for thin check command.");
+ log_error("Too many options for %s command.", argv[0]);
return 0;
}
- argv[0] = thin_check;
- argv[++args] = meta_path;
- argv[++args] = NULL;
+ if (!(argv[++args] = lv_dmpath_dup(data->dm->mem, mlv))) {
+ log_error("Failed to build pool metadata path.");
+ return 0;
+ }
- if (!(ret = exec_cmd(data->pool_lv->vg->cmd, (const char * const *)argv,
+ if (data->skip_zero) {
+ if ((fd = open(argv[args], O_RDONLY)) < 0) {
+ log_sys_error("open", argv[args]);
+ return 0;
+ }
+ /* let's assume there is no problem to read 64 bytes */
+ if (read(fd, buf, sizeof(buf)) < sizeof(buf)) {
+ log_sys_error("read", argv[args]);
+ return 0;
+ }
+ for (ret = 0; ret < DM_ARRAY_SIZE(buf); ++ret)
+ if (buf[ret])
+ break;
+
+ if (close(fd))
+ log_sys_error("close", argv[args]);
+
+ if (ret == DM_ARRAY_SIZE(buf)) {
+ log_debug("%s skipped, detect empty disk header on %s.",
+ argv[0], argv[args]);
+ return 1;
+ }
+ }
+
+ if (!(ret = exec_cmd(pool_lv->vg->cmd, (const char * const *)argv,
&status, 0))) {
switch (type) {
case DM_NODE_CALLBACK_PRELOADED:
- log_err_once("Check of thin pool %s/%s failed (status:%d). "
- "Manual repair required (thin_dump --repair %s)!",
- data->pool_lv->vg->name, data->pool_lv->name,
- status, meta_path);
+ log_err_once("Check of pool %s failed (status:%d). "
+ "Manual repair required!",
+ display_lvname(pool_lv), status);
break;
default:
- log_warn("WARNING: Integrity check of metadata for thin pool "
- "%s/%s failed.",
- data->pool_lv->vg->name, data->pool_lv->name);
+ log_warn("WARNING: Integrity check of metadata for pool "
+ "%s failed.", display_lvname(pool_lv));
}
/*
* FIXME: What should we do here??
*
* Maybe mark the node, so it's not activating
- * as thin_pool but as error/linear and let the
+ * as pool but as error/linear and let the
* dm tree resolve the issue.
*/
}
- dm_pool_free(data->dm->mem, dm_name);
-
return ret;
}
-static int _thin_pool_register_callback(struct dev_manager *dm,
- struct dm_tree_node *node,
- const struct logical_volume *lv)
+static int _pool_register_callback(struct dev_manager *dm,
+ struct dm_tree_node *node,
+ const struct logical_volume *lv)
{
- struct thin_cb_data *data;
+ struct pool_cb_data *data;
- /* Skip metadata testing for unused pool. */
- if (!first_seg(lv)->transaction_id ||
- ((first_seg(lv)->transaction_id == 1) &&
- pool_has_message(first_seg(lv), NULL, 0)))
+ /* Skip metadata testing for unused thin pool. */
+ if (lv_is_thin_pool(lv) &&
+ (!first_seg(lv)->transaction_id ||
+ ((first_seg(lv)->transaction_id == 1) &&
+ pool_has_message(first_seg(lv), NULL, 0))))
return 1;
- if (!(data = dm_pool_alloc(dm->mem, sizeof(*data)))) {
+ if (!(data = dm_pool_zalloc(dm->mem, sizeof(*data)))) {
log_error("Failed to allocated path for callback.");
return 0;
}
data->dm = dm;
- data->pool_lv = lv;
- dm_tree_node_set_callback(node, _thin_pool_callback, data);
+ if (lv_is_thin_pool(lv)) {
+ data->pool_lv = lv;
+ data->skip_zero = 1;
+ data->exec = global_thin_check_executable_CFG;
+ data->opts = global_thin_check_options_CFG;
+ data->defaults = DEFAULT_THIN_CHECK_OPTIONS;
+ data->global = "thin";
+ } else if (lv_is_cache(lv)) { /* cache pool */
+ data->pool_lv = first_seg(lv)->pool_lv;
+ data->skip_zero = dm->activation;
+ data->exec = global_cache_check_executable_CFG;
+ data->opts = global_cache_check_options_CFG;
+ data->defaults = DEFAULT_CACHE_CHECK_OPTIONS;
+ data->global = "cache";
+ } else {
+ log_error(INTERNAL_ERROR "Registering unsupported pool callback.");
+ return 0;
+ }
+
+ dm_tree_node_set_callback(node, _pool_callback, data);
return 1;
}
@@ -1825,7 +1864,7 @@ static int _add_lv_to_dtree(struct dev_manager *dm, struct dm_tree *dtree,
struct seg_list *sl;
struct dm_list *snh;
struct lv_segment *seg;
- struct dm_tree_node *thin_node;
+ struct dm_tree_node *node;
const char *uuid;
if (lv_is_cache_pool(lv)) {
@@ -1857,8 +1896,8 @@ static int _add_lv_to_dtree(struct dev_manager *dm, struct dm_tree *dtree,
/* FIXME Implement dm_tree_node_skip_childrens optimisation */
if (!(uuid = build_dm_uuid(dm->mem, lv, lv_layer(lv))))
return_0;
- if ((thin_node = dm_tree_find_node_by_uuid(dtree, uuid)))
- dm_tree_node_skip_childrens(thin_node, 1);
+ if ((node = dm_tree_find_node_by_uuid(dtree, uuid)))
+ dm_tree_node_skip_childrens(node, 1);
#endif
}
@@ -1887,8 +1926,21 @@ static int _add_lv_to_dtree(struct dev_manager *dm, struct dm_tree *dtree,
/* TODO: extend _cached_info() to return dnode */
if (!(uuid = build_dm_uuid(dm->mem, lv, lv_layer(lv))))
return_0;
- if ((thin_node = dm_tree_find_node_by_uuid(dtree, uuid)) &&
- !_thin_pool_register_callback(dm, thin_node, lv))
+ if ((node = dm_tree_find_node_by_uuid(dtree, uuid)) &&
+ !_pool_register_callback(dm, node, lv))
+ return_0;
+ }
+ }
+
+ if (!origin_only && lv_is_cache(lv)) {
+ if (!dm->activation) {
+ /* Setup callback for non-activation partial tree */
+ /* Activation gets own callback when needed */
+ /* TODO: extend _cached_info() to return dnode */
+ if (!(uuid = build_dm_uuid(dm->mem, lv, lv_layer(lv))))
+ return_0;
+ if ((node = dm_tree_find_node_by_uuid(dtree, uuid)) &&
+ !_pool_register_callback(dm, node, lv))
return_0;
}
}
@@ -2633,7 +2685,11 @@ static int _add_new_lv_to_dtree(struct dev_manager *dm, struct dm_tree *dtree,
/* Setup thin pool callback */
if (lv_is_thin_pool(lv) && layer &&
- !_thin_pool_register_callback(dm, dnode, lv))
+ !_pool_register_callback(dm, dnode, lv))
+ return_0;
+
+ if (lv_is_cache(lv) &&
+ !_pool_register_callback(dm, dnode, lv))
return_0;
if (read_ahead == DM_READ_AHEAD_AUTO) {
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=120bd2d6b13fb7a2…
Commit: 120bd2d6b13fb7a297ff6cfc9fe59c0b241ab46f
Parent: 4db5d78cefa99c053ba1f0bf73aa0eb55cafb279
Author: Zdenek Kabelac <zkabelac(a)redhat.com>
AuthorDate: Tue Jul 8 15:19:47 2014 +0200
Committer: Zdenek Kabelac <zkabelac(a)redhat.com>
CommitterDate: Fri Jul 11 12:57:25 2014 +0200
pool: move code to pool source file
More code is used commonly for all pool types (cache & thin)
---
lib/metadata/pool_manip.c | 233 +++++++++++++++++++++++++++++++++++++++++++++
lib/metadata/thin_manip.c | 230 --------------------------------------------
2 files changed, 233 insertions(+), 230 deletions(-)
diff --git a/lib/metadata/pool_manip.c b/lib/metadata/pool_manip.c
index ab52ff1..e32b109 100644
--- a/lib/metadata/pool_manip.c
+++ b/lib/metadata/pool_manip.c
@@ -23,6 +23,7 @@
#include "segtype.h"
#include "lv_alloc.h"
#include "defaults.h"
+#include "display.h"
int attach_pool_metadata_lv(struct lv_segment *pool_seg,
struct logical_volume *metadata_lv)
@@ -41,6 +42,26 @@ int attach_pool_metadata_lv(struct lv_segment *pool_seg,
return add_seg_to_segs_using_this_lv(metadata_lv, pool_seg);
}
+int detach_pool_metadata_lv(struct lv_segment *pool_seg, struct logical_volume **metadata_lv)
+{
+ struct logical_volume *lv = pool_seg->metadata_lv;
+
+ if (!lv ||
+ !lv_is_pool_metadata(lv) ||
+ !remove_seg_from_segs_using_this_lv(lv, pool_seg)) {
+ log_error(INTERNAL_ERROR "Logical volume %s is not valid pool.",
+ display_lvname(pool_seg->lv));
+ return 0;
+ }
+
+ lv_set_visible(lv);
+ lv->status &= ~(THIN_POOL_METADATA | CACHE_POOL_METADATA);
+ *metadata_lv = lv;
+ pool_seg->metadata_lv = NULL;
+
+ return 1;
+}
+
int attach_pool_data_lv(struct lv_segment *pool_seg,
struct logical_volume *pool_data_lv)
{
@@ -326,3 +347,215 @@ bad:
return 0;
}
+
+struct logical_volume *alloc_pool_metadata(struct logical_volume *pool_lv,
+ const char *name, uint32_t read_ahead,
+ uint32_t stripes, uint32_t stripe_size,
+ uint64_t size, alloc_policy_t alloc,
+ struct dm_list *pvh)
+{
+ struct logical_volume *metadata_lv;
+ /* FIXME: Make lvm2api usable */
+ struct lvcreate_params lvc = {
+ .activate = CHANGE_ALY,
+ .alloc = alloc,
+ .major = -1,
+ .minor = -1,
+ .permission = LVM_READ | LVM_WRITE,
+ .pvh = pvh,
+ .read_ahead = read_ahead,
+ .stripe_size = stripe_size,
+ .stripes = stripes,
+ .zero = 1,
+ };
+
+ dm_list_init(&lvc.tags);
+
+ if (!(lvc.extents = extents_from_size(pool_lv->vg->cmd, size,
+ pool_lv->vg->extent_size)))
+ return_0;
+
+ if (!(lvc.segtype = get_segtype_from_string(pool_lv->vg->cmd, "striped")))
+ return_0;
+
+ /* FIXME: allocate properly space for metadata_lv */
+
+ if (!(metadata_lv = lv_create_single(pool_lv->vg, &lvc)))
+ return_0;
+
+ if (!lv_rename_update(pool_lv->vg->cmd, metadata_lv, name, 0))
+ return_0;
+
+ return metadata_lv;
+}
+
+static struct logical_volume *_alloc_pool_metadata_spare(struct volume_group *vg,
+ uint32_t extents,
+ struct dm_list *pvh)
+{
+ struct logical_volume *lv;
+
+ /* FIXME: Make lvm2api usable */
+ struct lvcreate_params lp = {
+ .activate = CHANGE_ALY,
+ .alloc = ALLOC_INHERIT,
+ .extents = extents,
+ .major = -1,
+ .minor = -1,
+ .permission = LVM_READ | LVM_WRITE,
+ .pvh = pvh ? : &vg->pvs,
+ .read_ahead = DM_READ_AHEAD_AUTO,
+ .stripes = 1,
+ .zero = 1,
+ .temporary = 1,
+ };
+
+ dm_list_init(&lp.tags);
+
+ if (!(lp.segtype = get_segtype_from_string(vg->cmd, "striped")))
+ return_0;
+
+ /* FIXME: Maybe using silent mode ? */
+ if (!(lv = lv_create_single(vg, &lp)))
+ return_0;
+
+ /* Spare LV should not be active */
+ if (!deactivate_lv_local(vg->cmd, lv)) {
+ log_error("Unable to deactivate pool metadata spare LV. "
+ "Manual intervention required.");
+ return 0;
+ }
+
+ if (!vg_set_pool_metadata_spare(lv))
+ return_0;
+
+ return lv;
+}
+
+/*
+ * Create/resize pool metadata spare LV
+ * Caller does vg_write(), vg_commit() with pool creation
+ * extents is 0, max size is determined
+ */
+int handle_pool_metadata_spare(struct volume_group *vg, uint32_t extents,
+ struct dm_list *pvh, int poolmetadataspare)
+{
+ struct logical_volume *lv = vg->pool_metadata_spare_lv;
+ uint32_t seg_mirrors;
+ struct lv_segment *seg;
+ const struct lv_list *lvl;
+
+ if (!extents)
+ /* Find maximal size of metadata LV */
+ dm_list_iterate_items(lvl, &vg->lvs)
+ if (lv_is_pool_metadata(lvl->lv) &&
+ (lvl->lv->le_count > extents))
+ extents = lvl->lv->le_count;
+
+ if (!poolmetadataspare) {
+ /* TODO: Not showing when lvm.conf would define 'n' ? */
+ if (DEFAULT_POOL_METADATA_SPARE && extents)
+ /* Warn if there would be any user */
+ log_warn("WARNING: recovery of pools without pool "
+ "metadata spare LV is not automated.");
+ return 1;
+ }
+
+ if (!lv) {
+ if (!_alloc_pool_metadata_spare(vg, extents, pvh))
+ return_0;
+
+ return 1;
+ }
+
+ seg = last_seg(lv);
+ seg_mirrors = lv_mirror_count(lv);
+
+ /* Check spare LV is big enough and preserve segtype */
+ if ((lv->le_count < extents) && seg &&
+ !lv_extend(lv, seg->segtype,
+ seg->area_count / seg_mirrors,
+ seg->stripe_size,
+ seg_mirrors,
+ seg->region_size,
+ extents - lv->le_count, NULL,
+ pvh, lv->alloc, 0))
+ return_0;
+
+ return 1;
+}
+
+int vg_set_pool_metadata_spare(struct logical_volume *lv)
+{
+ char new_name[NAME_LEN];
+ struct volume_group *vg = lv->vg;
+
+ if (vg->pool_metadata_spare_lv) {
+ if (vg->pool_metadata_spare_lv == lv)
+ return 1;
+ if (!vg_remove_pool_metadata_spare(vg))
+ return_0;
+ }
+
+ if (dm_snprintf(new_name, sizeof(new_name), "%s_pmspare", lv->name) < 0) {
+ log_error("Can't create pool metadata spare. Name of pool LV "
+ "%s is too long.", lv->name);
+ return 0;
+ }
+
+ if (!lv_rename_update(vg->cmd, lv, new_name, 0))
+ return_0;
+
+ lv_set_hidden(lv);
+ lv->status |= POOL_METADATA_SPARE;
+ vg->pool_metadata_spare_lv = lv;
+
+ return 1;
+}
+
+int vg_remove_pool_metadata_spare(struct volume_group *vg)
+{
+ char new_name[NAME_LEN];
+ char *c;
+
+ struct logical_volume *lv = vg->pool_metadata_spare_lv;
+
+ if (!(lv->status & POOL_METADATA_SPARE)) {
+ log_error(INTERNAL_ERROR "LV %s is not pool metadata spare.",
+ lv->name);
+ return 0;
+ }
+
+ vg->pool_metadata_spare_lv = NULL;
+ lv->status &= ~POOL_METADATA_SPARE;
+ lv_set_visible(lv);
+
+ /* Cut off suffix _pmspare */
+ (void) dm_strncpy(new_name, lv->name, sizeof(new_name));
+ if (!(c = strchr(new_name, '_'))) {
+ log_error(INTERNAL_ERROR "LV %s has no suffix for pool metadata spare.",
+ new_name);
+ return 0;
+ }
+ *c = 0;
+
+ /* If the name is in use, generate new lvol%d */
+ if (find_lv_in_vg(vg, new_name) &&
+ !generate_lv_name(vg, "lvol%d", new_name, sizeof(new_name))) {
+ log_error("Failed to generate unique name for "
+ "pool metadata spare logical volume.");
+ return 0;
+ }
+
+ log_print_unless_silent("Renaming existing pool metadata spare "
+ "logical volume \"%s/%s\" to \"%s/%s\".",
+ vg->name, lv->name, vg->name, new_name);
+
+ if (!lv_rename_update(vg->cmd, lv, new_name, 0))
+ return_0;
+
+ /* To display default warning */
+ (void) handle_pool_metadata_spare(vg, 0, 0, 0);
+
+ return 1;
+}
diff --git a/lib/metadata/thin_manip.c b/lib/metadata/thin_manip.c
index b2ebaa1..33ab31c 100644
--- a/lib/metadata/thin_manip.c
+++ b/lib/metadata/thin_manip.c
@@ -20,24 +20,6 @@
#include "defaults.h"
#include "display.h"
-int detach_pool_metadata_lv(struct lv_segment *pool_seg, struct logical_volume **metadata_lv)
-{
- struct logical_volume *lv = pool_seg->metadata_lv;
-
- if (!lv || !lv_is_thin_pool_metadata(lv) ||
- !remove_seg_from_segs_using_this_lv(lv, pool_seg)) {
- log_error(INTERNAL_ERROR "LV %s is invalid thin pool.", pool_seg->lv->name);
- return 0;
- }
-
- lv_set_visible(lv);
- lv->status &= ~THIN_POOL_METADATA;
- *metadata_lv = lv;
- pool_seg->metadata_lv = NULL;
-
- return 1;
-}
-
int attach_pool_message(struct lv_segment *pool_seg, dm_thin_message_t type,
struct logical_volume *lv, uint32_t delete_id,
int no_update)
@@ -540,215 +522,3 @@ const char *get_pool_discards_name(thin_discards_t discards)
return "unknown";
}
-
-struct logical_volume *alloc_pool_metadata(struct logical_volume *pool_lv,
- const char *name, uint32_t read_ahead,
- uint32_t stripes, uint32_t stripe_size,
- uint64_t size, alloc_policy_t alloc,
- struct dm_list *pvh)
-{
- struct logical_volume *metadata_lv;
- /* FIXME: Make lvm2api usable */
- struct lvcreate_params lvc = {
- .activate = CHANGE_ALY,
- .alloc = alloc,
- .major = -1,
- .minor = -1,
- .permission = LVM_READ | LVM_WRITE,
- .pvh = pvh,
- .read_ahead = read_ahead,
- .stripe_size = stripe_size,
- .stripes = stripes,
- .zero = 1,
- };
-
- dm_list_init(&lvc.tags);
-
- if (!(lvc.extents = extents_from_size(pool_lv->vg->cmd, size,
- pool_lv->vg->extent_size)))
- return_0;
-
- if (!(lvc.segtype = get_segtype_from_string(pool_lv->vg->cmd, "striped")))
- return_0;
-
- /* FIXME: allocate properly space for metadata_lv */
-
- if (!(metadata_lv = lv_create_single(pool_lv->vg, &lvc)))
- return_0;
-
- if (!lv_rename_update(pool_lv->vg->cmd, metadata_lv, name, 0))
- return_0;
-
- return metadata_lv;
-}
-
-static struct logical_volume *_alloc_pool_metadata_spare(struct volume_group *vg,
- uint32_t extents,
- struct dm_list *pvh)
-{
- struct logical_volume *lv;
-
- /* FIXME: Make lvm2api usable */
- struct lvcreate_params lp = {
- .activate = CHANGE_ALY,
- .alloc = ALLOC_INHERIT,
- .extents = extents,
- .major = -1,
- .minor = -1,
- .permission = LVM_READ | LVM_WRITE,
- .pvh = pvh ? : &vg->pvs,
- .read_ahead = DM_READ_AHEAD_AUTO,
- .stripes = 1,
- .zero = 1,
- .temporary = 1,
- };
-
- dm_list_init(&lp.tags);
-
- if (!(lp.segtype = get_segtype_from_string(vg->cmd, "striped")))
- return_0;
-
- /* FIXME: Maybe using silent mode ? */
- if (!(lv = lv_create_single(vg, &lp)))
- return_0;
-
- /* Spare LV should not be active */
- if (!deactivate_lv_local(vg->cmd, lv)) {
- log_error("Unable to deactivate pool metadata spare LV. "
- "Manual intervention required.");
- return 0;
- }
-
- if (!vg_set_pool_metadata_spare(lv))
- return_0;
-
- return lv;
-}
-
-/*
- * Create/resize pool metadata spare LV
- * Caller does vg_write(), vg_commit() with pool creation
- * extents is 0, max size is determined
- */
-int handle_pool_metadata_spare(struct volume_group *vg, uint32_t extents,
- struct dm_list *pvh, int poolmetadataspare)
-{
- struct logical_volume *lv = vg->pool_metadata_spare_lv;
- uint32_t seg_mirrors;
- struct lv_segment *seg;
- const struct lv_list *lvl;
-
- if (!extents)
- /* Find maximal size of metadata LV */
- dm_list_iterate_items(lvl, &vg->lvs)
- if (lv_is_thin_pool_metadata(lvl->lv) &&
- (lvl->lv->le_count > extents))
- extents = lvl->lv->le_count;
-
- if (!poolmetadataspare) {
- /* TODO: Not showing when lvm.conf would define 'n' ? */
- if (DEFAULT_POOL_METADATA_SPARE && extents)
- /* Warn if there would be any user */
- log_warn("WARNING: recovery of pools without pool "
- "metadata spare LV is not automated.");
- return 1;
- }
-
- if (!lv) {
- if (!_alloc_pool_metadata_spare(vg, extents, pvh))
- return_0;
-
- return 1;
- }
-
- seg = last_seg(lv);
- seg_mirrors = lv_mirror_count(lv);
-
- /* Check spare LV is big enough and preserve segtype */
- if ((lv->le_count < extents) && seg &&
- !lv_extend(lv, seg->segtype,
- seg->area_count / seg_mirrors,
- seg->stripe_size,
- seg_mirrors,
- seg->region_size,
- extents - lv->le_count, NULL,
- pvh, lv->alloc, 0))
- return_0;
-
- return 1;
-}
-
-int vg_set_pool_metadata_spare(struct logical_volume *lv)
-{
- char new_name[NAME_LEN];
- struct volume_group *vg = lv->vg;
-
- if (vg->pool_metadata_spare_lv) {
- if (vg->pool_metadata_spare_lv == lv)
- return 1;
- if (!vg_remove_pool_metadata_spare(vg))
- return_0;
- }
-
- if (dm_snprintf(new_name, sizeof(new_name), "%s_pmspare", lv->name) < 0) {
- log_error("Can't create pool metadata spare. Name of pool LV "
- "%s is too long.", lv->name);
- return 0;
- }
-
- if (!lv_rename_update(vg->cmd, lv, new_name, 0))
- return_0;
-
- lv_set_hidden(lv);
- lv->status |= POOL_METADATA_SPARE;
- vg->pool_metadata_spare_lv = lv;
-
- return 1;
-}
-
-int vg_remove_pool_metadata_spare(struct volume_group *vg)
-{
- char new_name[NAME_LEN];
- char *c;
-
- struct logical_volume *lv = vg->pool_metadata_spare_lv;
-
- if (!(lv->status & POOL_METADATA_SPARE)) {
- log_error(INTERNAL_ERROR "LV %s is not pool metadata spare.",
- lv->name);
- return 0;
- }
-
- vg->pool_metadata_spare_lv = NULL;
- lv->status &= ~POOL_METADATA_SPARE;
- lv_set_visible(lv);
-
- /* Cut off suffix _pmspare */
- (void) dm_strncpy(new_name, lv->name, sizeof(new_name));
- if (!(c = strchr(new_name, '_'))) {
- log_error(INTERNAL_ERROR "LV %s has no suffix for pool metadata spare.",
- new_name);
- return 0;
- }
- *c = 0;
-
- /* If the name is in use, generate new lvol%d */
- if (find_lv_in_vg(vg, new_name) &&
- !generate_lv_name(vg, "lvol%d", new_name, sizeof(new_name))) {
- log_error("Failed to generate unique name for "
- "pool metadata spare logical volume.");
- return 0;
- }
-
- log_print_unless_silent("Renaming existing pool metadata spare "
- "logical volume \"%s/%s\" to \"%s/%s\".",
- vg->name, lv->name, vg->name, new_name);
-
- if (!lv_rename_update(vg->cmd, lv, new_name, 0))
- return_0;
-
- /* To display default warning */
- (void) handle_pool_metadata_spare(vg, 0, 0, 0);
-
- return 1;
-}
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=4db5d78cefa99c05…
Commit: 4db5d78cefa99c053ba1f0bf73aa0eb55cafb279
Parent: ba048612a3dcb9ca35c54f05a006ec458da4164f
Author: Zdenek Kabelac <zkabelac(a)redhat.com>
AuthorDate: Mon Jul 7 22:26:56 2014 +0200
Committer: Zdenek Kabelac <zkabelac(a)redhat.com>
CommitterDate: Fri Jul 11 12:50:44 2014 +0200
display: show C only for cache and cachepool
Keep target type (attr6) as the cache data and metadata volume has.
(i.e. when will show 'raid' type if metadata is raid)
---
WHATS_NEW | 1 +
lib/metadata/lv.c | 10 ++++------
2 files changed, 5 insertions(+), 6 deletions(-)
diff --git a/WHATS_NEW b/WHATS_NEW
index 7891d76..6cbf221 100644
--- a/WHATS_NEW
+++ b/WHATS_NEW
@@ -1,5 +1,6 @@
Version 2.02.108 -
=================================
+ Display 'C' only for cache and cache-pool target types in lvs.
Prompt for confirmation before change LV into a snapshot exception store.
Return proper error codes for some failing lvconvert funtions.
Add initial code to use cache tools (cache_check|dump|repair|restore).
diff --git a/lib/metadata/lv.c b/lib/metadata/lv.c
index d8fd320..f2c9b12 100644
--- a/lib/metadata/lv.c
+++ b/lib/metadata/lv.c
@@ -640,14 +640,12 @@ char *lv_attr_dup(struct dm_pool *mem, const struct logical_volume *lv)
/* Origin takes precedence over mirror and thin volume */
else if (lv_is_origin(lv) || lv_is_external_origin(lv))
repstr[0] = (lv_is_merging_origin(lv)) ? 'O' : 'o';
- else if (lv_is_cache_pool_metadata(lv))
+ else if (lv_is_pool_metadata(lv) ||
+ lv_is_pool_metadata_spare(lv) ||
+ lv_is_raid_metadata(lv))
repstr[0] = 'e';
else if (lv_is_cache_type(lv))
repstr[0] = 'C';
- else if (lv_is_thin_pool_metadata(lv) ||
- lv_is_pool_metadata_spare(lv) ||
- (lv->status & RAID_META))
- repstr[0] = 'e';
else if (lv->status & RAID)
repstr[0] = (lv->status & LV_NOTSYNCED) ? 'R' : 'r';
else if (lv->status & MIRRORED)
@@ -739,7 +737,7 @@ char *lv_attr_dup(struct dm_pool *mem, const struct logical_volume *lv)
if (lv_is_thin_pool(lv) || lv_is_thin_volume(lv))
repstr[6] = 't';
- else if (lv_is_cache_type(lv))
+ else if (lv_is_cache_pool(lv) || lv_is_cache(lv))
repstr[6] = 'C';
else if (lv_is_raid_type(lv))
repstr[6] = 'r';
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=ba048612a3dcb9ca…
Commit: ba048612a3dcb9ca35c54f05a006ec458da4164f
Parent: 8932d4a6257cfb842adb43c71d650515ef041ba6
Author: Zdenek Kabelac <zkabelac(a)redhat.com>
AuthorDate: Wed Jul 9 17:55:10 2014 +0200
Committer: Zdenek Kabelac <zkabelac(a)redhat.com>
CommitterDate: Fri Jul 11 12:50:06 2014 +0200
lvchange: just skip on cache pool
---
tools/lvchange.c | 8 +++-----
1 files changed, 3 insertions(+), 5 deletions(-)
diff --git a/tools/lvchange.c b/tools/lvchange.c
index 9bd6a88..992efde 100644
--- a/tools/lvchange.c
+++ b/tools/lvchange.c
@@ -215,6 +215,9 @@ static int _lvchange_activate(struct cmd_context *cmd, struct logical_volume *lv
activate = (activation_change_t) arg_uint_value(cmd, activate_ARG, CHANGE_AY);
+ if (lv_is_cache_pool(lv))
+ return 1;
+
if (lv_activation_skip(lv, activate, arg_count(cmd, ignoreactivationskip_ARG)))
return 1;
@@ -951,11 +954,6 @@ static int _lvchange_single(struct cmd_context *cmd, struct logical_volume *lv,
return EINVALID_CMD_LINE;
}
- if (lv_is_cache_pool(lv)) {
- log_error("Can't change cache pool logical volume.");
- return ECMD_FAILED;
- }
-
if (lv_is_origin(lv) && !lv_is_thin_volume(lv) &&
(arg_count(cmd, contiguous_ARG) || arg_count(cmd, permission_ARG) ||
arg_count(cmd, readahead_ARG) || arg_count(cmd, persistent_ARG) ||
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=8932d4a6257cfb84…
Commit: 8932d4a6257cfb842adb43c71d650515ef041ba6
Parent: 56c5ad7b194f5b991ae3835abca1c951450f34df
Author: Zdenek Kabelac <zkabelac(a)redhat.com>
AuthorDate: Mon Jul 7 22:14:08 2014 +0200
Committer: Zdenek Kabelac <zkabelac(a)redhat.com>
CommitterDate: Fri Jul 11 12:50:06 2014 +0200
lv_is_pool: add new defines
Defines for lv_is_pool() and lv_is_pool_metadata()
Also update comments for prompts for their current meaning.
(Though maybe they should be renamed)
---
lib/metadata/metadata-exported.h | 10 +++++-----
1 files changed, 5 insertions(+), 5 deletions(-)
diff --git a/lib/metadata/metadata-exported.h b/lib/metadata/metadata-exported.h
index bfb4651..f2521db 100644
--- a/lib/metadata/metadata-exported.h
+++ b/lib/metadata/metadata-exported.h
@@ -187,6 +187,8 @@
#define lv_is_cache_type(lv) (((lv)->status & (CACHE | CACHE_POOL | CACHE_POOL_DATA | CACHE_POOL_METADATA)) ? 1 : 0)
#define lv_is_virtual(lv) (((lv)->status & (VIRTUAL)) ? 1 : 0)
+#define lv_is_pool(lv) (((lv)->status & (CACHE_POOL | THIN_POOL)) ? 1 : 0)
+#define lv_is_pool_metadata(lv) (((lv)->status & (CACHE_POOL_METADATA | THIN_POOL_METADATA)) ? 1 : 0)
#define lv_is_pool_metadata_spare(lv) (((lv)->status & (POOL_METADATA_SPARE)) ? 1 : 0)
/* Ordered list - see lv_manip.c */
@@ -196,13 +198,11 @@ typedef enum {
AREA_LV
} area_type_t;
-/*
- * Whether or not to force an operation.
- */
+/* Whether or not to force an operation */
typedef enum {
PROMPT = 0, /* Issue yes/no prompt to confirm operation */
- DONT_PROMPT = 1, /* Skip yes/no prompt */
- DONT_PROMPT_OVERRIDE = 2 /* Skip prompt + override a second condition */
+ DONT_PROMPT = 1, /* Add more prompts */
+ DONT_PROMPT_OVERRIDE = 2 /* Add even more dangerous prompts */
} force_t;
typedef enum {
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=56c5ad7b194f5b99…
Commit: 56c5ad7b194f5b991ae3835abca1c951450f34df
Parent: 64828d877edbf1907557d76e44eb86d00f7a1f3a
Author: Zdenek Kabelac <zkabelac(a)redhat.com>
AuthorDate: Mon Jul 7 22:33:31 2014 +0200
Committer: Zdenek Kabelac <zkabelac(a)redhat.com>
CommitterDate: Fri Jul 11 12:49:55 2014 +0200
lvconvert: snapshot prompts to confirm conversion
Since the type passed LV is changed and content of data detroyed,
query user with prompt to confirm this operation.
Also add a proper wiping of header.
Using '--yes' will skip this prompt:
lvconvert -s --yes vg/lv vg/lvcow
---
WHATS_NEW | 1 +
test/shell/lvconvert-snapshot.sh | 4 +++-
tools/lvconvert.c | 30 +++++++++++++++++++++++++-----
3 files changed, 29 insertions(+), 6 deletions(-)
diff --git a/WHATS_NEW b/WHATS_NEW
index dcaaf23..7891d76 100644
--- a/WHATS_NEW
+++ b/WHATS_NEW
@@ -1,5 +1,6 @@
Version 2.02.108 -
=================================
+ Prompt for confirmation before change LV into a snapshot exception store.
Return proper error codes for some failing lvconvert funtions.
Add initial code to use cache tools (cache_check|dump|repair|restore).
Add "degraded" activation mode and make it the default.
diff --git a/test/shell/lvconvert-snapshot.sh b/test/shell/lvconvert-snapshot.sh
index f59bb7b..3d81573 100644
--- a/test/shell/lvconvert-snapshot.sh
+++ b/test/shell/lvconvert-snapshot.sh
@@ -25,6 +25,7 @@ lvcreate -L1 -s -n $lv3 $vg/$lv2
lvcreate -l1 -n $lv4 $vg
lvcreate -L1 -n $lv5 $vg
+lvcreate -L1 -n $lv6 $vg
not lvconvert -s $vg/$lv1 $vg/not_exist
@@ -52,6 +53,7 @@ not lvconvert -s $vg/$lv2 $vg/$lv4 2>&1 | tee err
grep "smaller" err
# This should pass
-lvconvert -s $vg/$lv2 $vg/$lv5
+lvconvert --yes -s $vg/$lv2 $vg/$lv5
+lvconvert --yes --type snapshot $vg/$lv2 $vg/$lv6
vgremove -f $vg
diff --git a/tools/lvconvert.c b/tools/lvconvert.c
index 62a9d4e..264b86c 100644
--- a/tools/lvconvert.c
+++ b/tools/lvconvert.c
@@ -2063,11 +2063,14 @@ static int _lvconvert_snapshot(struct cmd_context *cmd,
return 0;
}
- if (!lp->zero || !(lv->status & LVM_WRITE))
- log_warn("WARNING: \"%s\" not zeroed", lv->name);
- else if (!wipe_lv(lv, (struct wipe_params) { .do_zero = 1 })) {
- log_error("Aborting. Failed to wipe snapshot "
- "exception store.");
+ log_warn("WARNING: Converting logical volume %s to snapshot exception store.",
+ display_lvname(lv));
+ log_warn("THIS WILL DESTROY CONTENT OF LOGICAL VOLUME (filesystem etc.)");
+
+ if (!lp->yes &&
+ yes_no_prompt("Do you really want to convert %s? [y/n]: ",
+ display_lvname(lv)) == 'n') {
+ log_error("Conversion aborted.");
return 0;
}
@@ -2076,6 +2079,23 @@ static int _lvconvert_snapshot(struct cmd_context *cmd,
return 0;
}
+ if (!lp->zero || !(lv->status & LVM_WRITE))
+ log_warn("WARNING: \"%s\" not zeroed", lv->name);
+ else {
+ lv->status |= LV_TEMPORARY;
+ if (!activate_lv_local(cmd, lv) ||
+ !wipe_lv(lv, (struct wipe_params) { .do_zero = 1 })) {
+ log_error("Aborting. Failed to wipe snapshot exception store.");
+ return 0;
+ }
+ lv->status &= ~LV_TEMPORARY;
+ /* Deactivates cleared metadata LV */
+ if (!deactivate_lv_local(lv->vg->cmd, lv)) {
+ log_error("Failed to deactivate zeroed snapshot exception store.");
+ return 0;
+ }
+ }
+
if (!archive(lv->vg))
return_0;
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=64828d877edbf190…
Commit: 64828d877edbf1907557d76e44eb86d00f7a1f3a
Parent: baf825331cb37fd29007e7ed7596fb3683c8b37d
Author: Zdenek Kabelac <zkabelac(a)redhat.com>
AuthorDate: Fri Jul 11 12:24:32 2014 +0200
Committer: Zdenek Kabelac <zkabelac(a)redhat.com>
CommitterDate: Fri Jul 11 12:49:02 2014 +0200
lvconvert: fix return codes
Error codes in some function are directly used
as command result - thus return 0 is not error code,
but success - switch to proper ECMD_FAILED.
---
WHATS_NEW | 1 +
tools/lvconvert.c | 16 +++++++++-------
2 files changed, 10 insertions(+), 7 deletions(-)
diff --git a/WHATS_NEW b/WHATS_NEW
index 77cc2d7..dcaaf23 100644
--- a/WHATS_NEW
+++ b/WHATS_NEW
@@ -1,5 +1,6 @@
Version 2.02.108 -
=================================
+ Return proper error codes for some failing lvconvert funtions.
Add initial code to use cache tools (cache_check|dump|repair|restore).
Add "degraded" activation mode and make it the default.
Add separate lv_active_{locally,remotely,exclusively} LV reporting fields.
diff --git a/tools/lvconvert.c b/tools/lvconvert.c
index 2a2a398..62a9d4e 100644
--- a/tools/lvconvert.c
+++ b/tools/lvconvert.c
@@ -894,7 +894,7 @@ int lvconvert_poll(struct cmd_context *cmd, struct logical_volume *lv,
if (dm_snprintf(lv_full_name, sizeof(lv_full_name), "%s/%s", lv->vg->name, lv->name) < 0) {
log_error(INTERNAL_ERROR "Name \"%s/%s\" is too long.", lv->vg->name, lv->name);
- return 0;
+ return ECMD_FAILED;
}
memcpy(uuid, &lv->lvid, sizeof(lv->lvid));
@@ -1995,7 +1995,7 @@ static int _lvconvert_splitsnapshot(struct cmd_context *cmd, struct logical_volu
if (lv_info(cmd, cow, 0, &info, 1, 0)) {
if (!lv_check_not_in_use(cmd, cow, &info))
- return_0;
+ return_ECMD_FAILED;
if ((lp->force == PROMPT) &&
lv_is_visible(cow) &&
@@ -3047,8 +3047,11 @@ static int _lvconvert_single(struct cmd_context *cmd, struct logical_volume *lv,
if (lp->splitsnapshot)
return _lvconvert_splitsnapshot(cmd, lv, lp);
- if (arg_count(cmd, repair_ARG) && lv_is_thin_pool(lv))
- return _lvconvert_thinpool_repair(cmd, lv, lp);
+ if (arg_count(cmd, repair_ARG) && lv_is_thin_pool(lv)) {
+ if (!_lvconvert_thinpool_repair(cmd, lv, lp))
+ return_ECMD_FAILED;
+ return ECMD_PROCESSED;
+ }
if (arg_count(cmd, repair_ARG) &&
!(lv->status & MIRRORED) && !(lv->status & RAID)) {
@@ -3070,9 +3073,8 @@ static int _lvconvert_single(struct cmd_context *cmd, struct logical_volume *lv,
* to consult the default.
*/
if (arg_count(cmd, mirrors_ARG) && !lv_is_mirrored(lv)) {
- lp->segtype = get_segtype_from_string(cmd, find_config_tree_str(cmd, global_mirror_segtype_default_CFG, NULL));
- if (!lp->segtype)
- return_0;
+ if (!(lp->segtype = get_segtype_from_string(cmd, find_config_tree_str(cmd, global_mirror_segtype_default_CFG, NULL))))
+ return_ECMD_FAILED;
}
}
if (lp->merge) {
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=baf825331cb37fd2…
Commit: baf825331cb37fd29007e7ed7596fb3683c8b37d
Parent: 39cb8aa3abd4e3eea7bbbdcc24225e8475c3aff3
Author: Zdenek Kabelac <zkabelac(a)redhat.com>
AuthorDate: Mon Jul 7 21:03:15 2014 +0200
Committer: Zdenek Kabelac <zkabelac(a)redhat.com>
CommitterDate: Fri Jul 11 12:47:41 2014 +0200
prompt: display 'n' for EOF
When EOF is detect - it could be either 'Ctrl+C'
or empty stdin.
For Ctrl+C there is visual ^C sign.
For EOF print 'n' so decision is clear in debug print.
---
lib/display/display.c | 6 +++++-
1 files changed, 5 insertions(+), 1 deletions(-)
diff --git a/lib/display/display.c b/lib/display/display.c
index cd204a0..cfd83c9 100644
--- a/lib/display/display.c
+++ b/lib/display/display.c
@@ -883,7 +883,7 @@ void display_name_error(name_error_t name_error)
*/
char yes_no_prompt(const char *prompt, ...)
{
- int c = 0, ret = 0;
+ int c = 0, ret = 0, cb = 0;
va_list ap;
sigint_allow();
@@ -903,6 +903,7 @@ char yes_no_prompt(const char *prompt, ...)
if ((c = getchar()) == EOF) {
ret = 'n'; /* SIGINT */
+ cb = 1;
break;
}
@@ -918,6 +919,9 @@ char yes_no_prompt(const char *prompt, ...)
sigint_restore();
+ if (cb && !sigint_caught())
+ fputc(ret, stderr);
+
if (c != '\n')
fputc('\n', stderr);
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=39cb8aa3abd4e3ee…
Commit: 39cb8aa3abd4e3eea7bbbdcc24225e8475c3aff3
Parent: f9d80c9d31d7113ab8bc08baf6bba96a7449261f
Author: Zdenek Kabelac <zkabelac(a)redhat.com>
AuthorDate: Fri Jul 4 16:31:05 2014 +0200
Committer: Zdenek Kabelac <zkabelac(a)redhat.com>
CommitterDate: Fri Jul 11 12:47:41 2014 +0200
configure
---
configure | 521 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
1 files changed, 517 insertions(+), 4 deletions(-)
diff --git a/configure b/configure
index dec82de..40ab256 100755
--- a/configure
+++ b/configure
@@ -768,6 +768,10 @@ PKGCONFIGINIT_CFLAGS
PKG_CONFIG_LIBDIR
PKG_CONFIG_PATH
PKG_CONFIG
+CACHE_RESTORE_CMD
+CACHE_REPAIR_CMD
+CACHE_DUMP_CMD
+CACHE_CHECK_CMD
THIN_RESTORE_CMD
THIN_REPAIR_CMD
THIN_DUMP_CMD
@@ -874,6 +878,10 @@ with_thin_repair
with_thin_restore
enable_thin_check_needs_check
with_cache
+with_cache_check
+with_cache_dump
+with_cache_repair
+with_cache_restore
enable_readline
enable_realtime
enable_ocf
@@ -1661,6 +1669,12 @@ Optional Packages:
--with-thin-restore=PATH
thin_restore tool: [[autodetect]]
--with-cache=TYPE cache support: internal/shared/none [[TYPE=none]]
+ --with-cache-check=PATH cache_check tool: [[autodetect]]
+ --with-cache-dump=PATH cache_dump tool: [[autodetect]]
+ --with-cache-repair=PATH
+ cache_repair tool: [[autodetect]]
+ --with-cache-restore=PATH
+ cache_restore tool: [[autodetect]]
--with-ocfdir=DIR install OCF files in DIR
[[PREFIX/lib/ocf/resource.d/lvm2]]
--with-default-pid-dir=PID_DIR
@@ -7450,7 +7464,7 @@ $as_echo "$as_me: WARNING: $THIN_CHECK_CMD: Old version \"$THIN_CHECK_VSN\" foun
THIN_CHECK_NEEDS_CHECK=no
fi
fi
- # Empty means a config way to ignore thin checking
+ # Empty means a config way to ignore thin dumping
if test "$THIN_DUMP_CMD" = "autodetect"; then
if test -n "$ac_tool_prefix"; then
# Extract the first word of "${ac_tool_prefix}thin_dump", so it can be a program name with args.
@@ -7557,7 +7571,7 @@ $as_echo "$as_me: WARNING: thin_dump not found in path $PATH" >&2;}
THIN_CONFIGURE_WARN=y
}
fi
- # Empty means a config way to ignore thin checking
+ # Empty means a config way to ignore thin repairing
if test "$THIN_REPAIR_CMD" = "autodetect"; then
if test -n "$ac_tool_prefix"; then
# Extract the first word of "${ac_tool_prefix}thin_repair", so it can be a program name with args.
@@ -7664,7 +7678,7 @@ $as_echo "$as_me: WARNING: thin_repair not found in path $PATH" >&2;}
THIN_CONFIGURE_WARN=y
}
fi
- # Empty means a config way to ignore thin checking
+ # Empty means a config way to ignore thin restoring
if test "$THIN_RESTORE_CMD" = "autodetect"; then
if test -n "$ac_tool_prefix"; then
# Extract the first word of "${ac_tool_prefix}thin_restore", so it can be a program name with args.
@@ -7816,7 +7830,39 @@ $as_echo_n "checking whether to include cache... " >&6; }
if test "${with_cache+set}" = set; then :
withval=$with_cache; CACHE=$withval
else
- CACHE=none
+ CACHE="none"
+fi
+
+
+# Check whether --with-cache-check was given.
+if test "${with_cache_check+set}" = set; then :
+ withval=$with_cache_check; CACHE_CHECK_CMD=$withval
+else
+ CACHE_CHECK_CMD="autodetect"
+fi
+
+
+# Check whether --with-cache-dump was given.
+if test "${with_cache_dump+set}" = set; then :
+ withval=$with_cache_dump; CACHE_DUMP_CMD=$withval
+else
+ CACHE_DUMP_CMD="autodetect"
+fi
+
+
+# Check whether --with-cache-repair was given.
+if test "${with_cache_repair+set}" = set; then :
+ withval=$with_cache_repair; CACHE_REPAIR_CMD=$withval
+else
+ CACHE_REPAIR_CMD="autodetect"
+fi
+
+
+# Check whether --with-cache-restore was given.
+if test "${with_cache_restore+set}" = set; then :
+ withval=$with_cache_restore; CACHE_RESTORE_CMD=$withval
+else
+ CACHE_RESTORE_CMD="autodetect"
fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $CACHE" >&5
@@ -7830,6 +7876,466 @@ $as_echo "#define CACHE_INTERNAL 1" >>confdefs.h
*) as_fn_error $? "--with-cache parameter invalid" "$LINENO" 5 ;;
esac
+# Test if necessary cache tools are available
+# if not - use plain defaults and warn user
+case "$CACHE" in
+ internal|shared)
+ # Empty means a config way to ignore cache checking
+ if test "$CACHE_CHECK_CMD" = "autodetect"; then
+ if test -n "$ac_tool_prefix"; then
+ # Extract the first word of "${ac_tool_prefix}cache_check", so it can be a program name with args.
+set dummy ${ac_tool_prefix}cache_check; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_path_CACHE_CHECK_CMD+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ case $CACHE_CHECK_CMD in
+ [\\/]* | ?:[\\/]*)
+ ac_cv_path_CACHE_CHECK_CMD="$CACHE_CHECK_CMD" # Let the user override the test with a path.
+ ;;
+ *)
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_path_CACHE_CHECK_CMD="$as_dir/$ac_word$ac_exec_ext"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+ ;;
+esac
+fi
+CACHE_CHECK_CMD=$ac_cv_path_CACHE_CHECK_CMD
+if test -n "$CACHE_CHECK_CMD"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CACHE_CHECK_CMD" >&5
+$as_echo "$CACHE_CHECK_CMD" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_path_CACHE_CHECK_CMD"; then
+ ac_pt_CACHE_CHECK_CMD=$CACHE_CHECK_CMD
+ # Extract the first word of "cache_check", so it can be a program name with args.
+set dummy cache_check; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_path_ac_pt_CACHE_CHECK_CMD+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ case $ac_pt_CACHE_CHECK_CMD in
+ [\\/]* | ?:[\\/]*)
+ ac_cv_path_ac_pt_CACHE_CHECK_CMD="$ac_pt_CACHE_CHECK_CMD" # Let the user override the test with a path.
+ ;;
+ *)
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_path_ac_pt_CACHE_CHECK_CMD="$as_dir/$ac_word$ac_exec_ext"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+ ;;
+esac
+fi
+ac_pt_CACHE_CHECK_CMD=$ac_cv_path_ac_pt_CACHE_CHECK_CMD
+if test -n "$ac_pt_CACHE_CHECK_CMD"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_pt_CACHE_CHECK_CMD" >&5
+$as_echo "$ac_pt_CACHE_CHECK_CMD" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+ if test "x$ac_pt_CACHE_CHECK_CMD" = x; then
+ CACHE_CHECK_CMD=""
+ else
+ case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+ CACHE_CHECK_CMD=$ac_pt_CACHE_CHECK_CMD
+ fi
+else
+ CACHE_CHECK_CMD="$ac_cv_path_CACHE_CHECK_CMD"
+fi
+
+ if test -z "$CACHE_CHECK_CMD"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache_check not found in path $PATH" >&5
+$as_echo "$as_me: WARNING: cache_check not found in path $PATH" >&2;}
+ CACHE_CHECK_CMD=/usr/sbin/cache_check
+ CACHE_CONFIGURE_WARN=y
+ fi
+ fi
+ # Empty means a config way to ignore cache dumping
+ if test "$CACHE_DUMP_CMD" = "autodetect"; then
+ if test -n "$ac_tool_prefix"; then
+ # Extract the first word of "${ac_tool_prefix}cache_dump", so it can be a program name with args.
+set dummy ${ac_tool_prefix}cache_dump; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_path_CACHE_DUMP_CMD+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ case $CACHE_DUMP_CMD in
+ [\\/]* | ?:[\\/]*)
+ ac_cv_path_CACHE_DUMP_CMD="$CACHE_DUMP_CMD" # Let the user override the test with a path.
+ ;;
+ *)
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_path_CACHE_DUMP_CMD="$as_dir/$ac_word$ac_exec_ext"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+ ;;
+esac
+fi
+CACHE_DUMP_CMD=$ac_cv_path_CACHE_DUMP_CMD
+if test -n "$CACHE_DUMP_CMD"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CACHE_DUMP_CMD" >&5
+$as_echo "$CACHE_DUMP_CMD" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_path_CACHE_DUMP_CMD"; then
+ ac_pt_CACHE_DUMP_CMD=$CACHE_DUMP_CMD
+ # Extract the first word of "cache_dump", so it can be a program name with args.
+set dummy cache_dump; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_path_ac_pt_CACHE_DUMP_CMD+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ case $ac_pt_CACHE_DUMP_CMD in
+ [\\/]* | ?:[\\/]*)
+ ac_cv_path_ac_pt_CACHE_DUMP_CMD="$ac_pt_CACHE_DUMP_CMD" # Let the user override the test with a path.
+ ;;
+ *)
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_path_ac_pt_CACHE_DUMP_CMD="$as_dir/$ac_word$ac_exec_ext"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+ ;;
+esac
+fi
+ac_pt_CACHE_DUMP_CMD=$ac_cv_path_ac_pt_CACHE_DUMP_CMD
+if test -n "$ac_pt_CACHE_DUMP_CMD"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_pt_CACHE_DUMP_CMD" >&5
+$as_echo "$ac_pt_CACHE_DUMP_CMD" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+ if test "x$ac_pt_CACHE_DUMP_CMD" = x; then
+ CACHE_DUMP_CMD=""
+ else
+ case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+ CACHE_DUMP_CMD=$ac_pt_CACHE_DUMP_CMD
+ fi
+else
+ CACHE_DUMP_CMD="$ac_cv_path_CACHE_DUMP_CMD"
+fi
+
+ test -z "$CACHE_DUMP_CMD" && {
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache_dump not found in path $PATH" >&5
+$as_echo "$as_me: WARNING: cache_dump not found in path $PATH" >&2;}
+ CACHE_DUMP_CMD=/usr/sbin/cache_dump
+ CACHE_CONFIGURE_WARN=y
+ }
+ fi
+ # Empty means a config way to ignore cache repairing
+ if test "$CACHE_REPAIR_CMD" = "autodetect"; then
+ if test -n "$ac_tool_prefix"; then
+ # Extract the first word of "${ac_tool_prefix}cache_repair", so it can be a program name with args.
+set dummy ${ac_tool_prefix}cache_repair; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_path_CACHE_REPAIR_CMD+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ case $CACHE_REPAIR_CMD in
+ [\\/]* | ?:[\\/]*)
+ ac_cv_path_CACHE_REPAIR_CMD="$CACHE_REPAIR_CMD" # Let the user override the test with a path.
+ ;;
+ *)
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_path_CACHE_REPAIR_CMD="$as_dir/$ac_word$ac_exec_ext"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+ ;;
+esac
+fi
+CACHE_REPAIR_CMD=$ac_cv_path_CACHE_REPAIR_CMD
+if test -n "$CACHE_REPAIR_CMD"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CACHE_REPAIR_CMD" >&5
+$as_echo "$CACHE_REPAIR_CMD" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_path_CACHE_REPAIR_CMD"; then
+ ac_pt_CACHE_REPAIR_CMD=$CACHE_REPAIR_CMD
+ # Extract the first word of "cache_repair", so it can be a program name with args.
+set dummy cache_repair; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_path_ac_pt_CACHE_REPAIR_CMD+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ case $ac_pt_CACHE_REPAIR_CMD in
+ [\\/]* | ?:[\\/]*)
+ ac_cv_path_ac_pt_CACHE_REPAIR_CMD="$ac_pt_CACHE_REPAIR_CMD" # Let the user override the test with a path.
+ ;;
+ *)
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_path_ac_pt_CACHE_REPAIR_CMD="$as_dir/$ac_word$ac_exec_ext"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+ ;;
+esac
+fi
+ac_pt_CACHE_REPAIR_CMD=$ac_cv_path_ac_pt_CACHE_REPAIR_CMD
+if test -n "$ac_pt_CACHE_REPAIR_CMD"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_pt_CACHE_REPAIR_CMD" >&5
+$as_echo "$ac_pt_CACHE_REPAIR_CMD" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+ if test "x$ac_pt_CACHE_REPAIR_CMD" = x; then
+ CACHE_REPAIR_CMD=""
+ else
+ case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+ CACHE_REPAIR_CMD=$ac_pt_CACHE_REPAIR_CMD
+ fi
+else
+ CACHE_REPAIR_CMD="$ac_cv_path_CACHE_REPAIR_CMD"
+fi
+
+ test -z "$CACHE_REPAIR_CMD" && {
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache_repair not found in path $PATH" >&5
+$as_echo "$as_me: WARNING: cache_repair not found in path $PATH" >&2;}
+ CACHE_REPAIR_CMD=/usr/sbin/cache_repair
+ CACHE_CONFIGURE_WARN=y
+ }
+ fi
+ # Empty means a config way to ignore cache restoring
+ if test "$CACHE_RESTORE_CMD" = "autodetect"; then
+ if test -n "$ac_tool_prefix"; then
+ # Extract the first word of "${ac_tool_prefix}cache_restore", so it can be a program name with args.
+set dummy ${ac_tool_prefix}cache_restore; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_path_CACHE_RESTORE_CMD+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ case $CACHE_RESTORE_CMD in
+ [\\/]* | ?:[\\/]*)
+ ac_cv_path_CACHE_RESTORE_CMD="$CACHE_RESTORE_CMD" # Let the user override the test with a path.
+ ;;
+ *)
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_path_CACHE_RESTORE_CMD="$as_dir/$ac_word$ac_exec_ext"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+ ;;
+esac
+fi
+CACHE_RESTORE_CMD=$ac_cv_path_CACHE_RESTORE_CMD
+if test -n "$CACHE_RESTORE_CMD"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CACHE_RESTORE_CMD" >&5
+$as_echo "$CACHE_RESTORE_CMD" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_path_CACHE_RESTORE_CMD"; then
+ ac_pt_CACHE_RESTORE_CMD=$CACHE_RESTORE_CMD
+ # Extract the first word of "cache_restore", so it can be a program name with args.
+set dummy cache_restore; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_path_ac_pt_CACHE_RESTORE_CMD+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ case $ac_pt_CACHE_RESTORE_CMD in
+ [\\/]* | ?:[\\/]*)
+ ac_cv_path_ac_pt_CACHE_RESTORE_CMD="$ac_pt_CACHE_RESTORE_CMD" # Let the user override the test with a path.
+ ;;
+ *)
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_path_ac_pt_CACHE_RESTORE_CMD="$as_dir/$ac_word$ac_exec_ext"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+ ;;
+esac
+fi
+ac_pt_CACHE_RESTORE_CMD=$ac_cv_path_ac_pt_CACHE_RESTORE_CMD
+if test -n "$ac_pt_CACHE_RESTORE_CMD"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_pt_CACHE_RESTORE_CMD" >&5
+$as_echo "$ac_pt_CACHE_RESTORE_CMD" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+ if test "x$ac_pt_CACHE_RESTORE_CMD" = x; then
+ CACHE_RESTORE_CMD=""
+ else
+ case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+ CACHE_RESTORE_CMD=$ac_pt_CACHE_RESTORE_CMD
+ fi
+else
+ CACHE_RESTORE_CMD="$ac_cv_path_CACHE_RESTORE_CMD"
+fi
+
+ test -z "$CACHE_RESTORE_CMD" && {
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache_restore not found in path $PATH" >&5
+$as_echo "$as_me: WARNING: cache_restore not found in path $PATH" >&2;}
+ CACHE_RESTORE_CMD=/usr/sbin/cache_restore
+ CACHE_CONFIGURE_WARN=y
+ }
+ fi
+ ;;
+esac
+
+
+cat >>confdefs.h <<_ACEOF
+#define CACHE_CHECK_CMD "$CACHE_CHECK_CMD"
+_ACEOF
+
+
+
+cat >>confdefs.h <<_ACEOF
+#define CACHE_DUMP_CMD "$CACHE_DUMP_CMD"
+_ACEOF
+
+
+
+cat >>confdefs.h <<_ACEOF
+#define CACHE_REPAIR_CMD "$CACHE_REPAIR_CMD"
+_ACEOF
+
+
+
+cat >>confdefs.h <<_ACEOF
+#define CACHE_RESTORE_CMD "$CACHE_RESTORE_CMD"
+_ACEOF
+
+
+
################################################################################
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to enable readline" >&5
$as_echo_n "checking whether to enable readline... " >&6; }
@@ -12091,6 +12597,10 @@ LVM_LIBAPI=`echo "$VER" | $AWK -F '[()]' '{print $2}'`
+
+
+
+
################################################################################
ac_config_files="$ac_config_files Makefile make.tmpl daemons/Makefile daemons/clvmd/Makefile daemons/cmirrord/Makefile daemons/dmeventd/Makefile daemons/dmeventd/libdevmapper-event.pc daemons/dmeventd/plugins/Makefile daemons/dmeventd/plugins/lvm2/Makefile daemons/dmeventd/plugins/raid/Makefile daemons/dmeventd/plugins/mirror/Makefile daemons/dmeventd/plugins/snapshot/Makefile daemons/dmeventd/plugins/thin/Makefile daemons/lvmetad/Makefile conf/Makefile conf/example.conf conf/command_profile_template.profile conf/metadata_profile_template.profile include/.symlinks include/Makefile lib/Makefile lib/format1/Makefile lib/format_pool/Makefile lib/locking/Makefile lib/mirror/Makefile lib/replicator/Makefile lib/misc/lvm-version.h lib/raid/Makefile lib/snapshot/Makefile lib/thin/Makefile lib/cache_segtype/Makefile libdaemon/Makefile libdaemon/client/Makefile libdaemon/server/Makefile libdm/Makefile libdm/libdevmapper.pc liblvm/Makefile liblvm/liblvm2app.pc man/Makefile po/Makefile
python/Makefile python/setup.py scripts/blkdeactivate.sh scripts/blk_availability_init_red_hat scripts/blk_availability_systemd_red_hat.service scripts/clvmd_init_red_hat scripts/cmirrord_init_red_hat scripts/dm_event_systemd_red_hat.service scripts/dm_event_systemd_red_hat.socket scripts/lvm2_cluster_activation_red_hat.sh scripts/lvm2_cluster_activation_systemd_red_hat.service scripts/lvm2_clvmd_systemd_red_hat.service scripts/lvm2_cmirrord_systemd_red_hat.service scripts/lvm2_lvmetad_init_red_hat scripts/lvm2_lvmetad_systemd_red_hat.service scripts/lvm2_lvmetad_systemd_red_hat.socket scripts/lvm2_monitoring_init_red_hat scripts/lvm2_monitoring_systemd_red_hat.service scripts/lvm2_pvscan_systemd_red_hat@.service scripts/lvm2_tmpfiles_red_hat.conf scripts/Makefile test/Makefile test/api/Makefile test/unit/Makefile tools/Makefile udev/Makefile unit-tests/datastruct/Makefile unit-tests/regex/Makefile unit-tests/mm/Makefile"
@@ -13455,5 +13965,8 @@ $as_echo "$as_me: WARNING: Support for thin provisioning is limited since some t
test -n "$THIN_CHECK_VERSION_WARN" && { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: You should also install thin_check vsn 0.3.2 (or later) to use lvm2 thin provisioning" >&5
$as_echo "$as_me: WARNING: You should also install thin_check vsn 0.3.2 (or later) to use lvm2 thin provisioning" >&2;}
+test -n "$CACHE_CONFIGURE_WARN" && { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Support for cache is limited since some cache tools are missing!" >&5
+$as_echo "$as_me: WARNING: Support for cache is limited since some cache tools are missing!" >&2;}
+
test "$ODIRECT" = yes || { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: O_DIRECT disabled: low-memory pvmove may lock up" >&5
$as_echo "$as_me: WARNING: O_DIRECT disabled: low-memory pvmove may lock up" >&2;}
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=f9d80c9d31d7113a…
Commit: f9d80c9d31d7113ab8bc08baf6bba96a7449261f
Parent: 5c3d8940136f39a017ab434651789647161350b1
Author: Zdenek Kabelac <zkabelac(a)redhat.com>
AuthorDate: Fri Jul 4 16:31:29 2014 +0200
Committer: Zdenek Kabelac <zkabelac(a)redhat.com>
CommitterDate: Fri Jul 11 12:47:35 2014 +0200
cache: add tool support
Introducing cache tool support.
---
WHATS_NEW | 1 +
conf/example.conf.in | 30 ++++++++++++++
configure.in | 89 +++++++++++++++++++++++++++++++++++++++---
lib/config/config_settings.h | 5 ++
lib/config/defaults.h | 2 +
lib/misc/configure.h.in | 12 ++++++
6 files changed, 133 insertions(+), 6 deletions(-)
diff --git a/WHATS_NEW b/WHATS_NEW
index 29a0aa3..77cc2d7 100644
--- a/WHATS_NEW
+++ b/WHATS_NEW
@@ -1,5 +1,6 @@
Version 2.02.108 -
=================================
+ Add initial code to use cache tools (cache_check|dump|repair|restore).
Add "degraded" activation mode and make it the default.
Add separate lv_active_{locally,remotely,exclusively} LV reporting fields.
Recognize "auto"/"unmanaged" values in selection for appropriate fields only.
diff --git a/conf/example.conf.in b/conf/example.conf.in
index 91768fb..2930054 100644
--- a/conf/example.conf.in
+++ b/conf/example.conf.in
@@ -744,6 +744,36 @@ global {
# external_origin_extend
#
# thin_disabled_features = [ "discards", "block_size" ]
+
+ # Full path of the utility called to check that a cache metadata device
+ # is in a state that allows it to be used.
+ # Each time a cached LV needs to be used or after it is deactivated
+ # this utility is executed. The activation will only proceed if the utility
+ # has an exit status of 0.
+ # Set to "" to skip this check. (Not recommended.)
+ # The cache tools are available as part of the device-mapper-persistent-data
+ # package from https://github.com/jthornber/thin-provisioning-tools .
+ #
+ # cache_check_executable = "@CACHE_CHECK_CMD@"
+
+ # Array of string options passed with cache_check command. By default,
+ # option "-q" is for quiet output.
+ #
+ # cache_check_options = [ "-q" ]
+
+ # Full path of the utility called to repair a cache metadata device.
+ # Each time a cache metadata needs repair this utility is executed.
+ # See cache_check_executable how to obtain binaries.
+ #
+ # cache_repair_executable = "@CACHE_REPAIR_CMD@"
+
+ # Array of extra string options passed with cache_repair command.
+ # cache_repair_options = [ "" ]
+
+ # Full path of the utility called to dump cache metadata content.
+ # See cache_check_executable how to obtain binaries.
+ #
+ # cache_dump_executable = "@CACHE_DUMP_CMD@"
}
activation {
diff --git a/configure.in b/configure.in
index d92e03e..1b8c338 100644
--- a/configure.in
+++ b/configure.in
@@ -447,7 +447,7 @@ case "$THIN" in
THIN_CHECK_NEEDS_CHECK=no
fi
fi
- # Empty means a config way to ignore thin checking
+ # Empty means a config way to ignore thin dumping
if test "$THIN_DUMP_CMD" = "autodetect"; then
AC_PATH_TOOL(THIN_DUMP_CMD, thin_dump)
test -z "$THIN_DUMP_CMD" && {
@@ -456,7 +456,7 @@ case "$THIN" in
THIN_CONFIGURE_WARN=y
}
fi
- # Empty means a config way to ignore thin checking
+ # Empty means a config way to ignore thin repairing
if test "$THIN_REPAIR_CMD" = "autodetect"; then
AC_PATH_TOOL(THIN_REPAIR_CMD, thin_repair)
test -z "$THIN_REPAIR_CMD" && {
@@ -465,7 +465,7 @@ case "$THIN" in
THIN_CONFIGURE_WARN=y
}
fi
- # Empty means a config way to ignore thin checking
+ # Empty means a config way to ignore thin restoring
if test "$THIN_RESTORE_CMD" = "autodetect"; then
AC_PATH_TOOL(THIN_RESTORE_CMD, thin_restore)
test -z "$THIN_RESTORE_CMD" && {
@@ -500,9 +500,24 @@ dnl -- cache inclusion type
AC_MSG_CHECKING(whether to include cache)
AC_ARG_WITH(cache,
AC_HELP_STRING([--with-cache=TYPE],
- [cache support: internal/shared/none
- [[TYPE=none]]]),
- CACHE=$withval, CACHE=none)
+ [cache support: internal/shared/none [[TYPE=none]]]),
+ CACHE=$withval, CACHE="none")
+AC_ARG_WITH(cache-check,
+ AC_HELP_STRING([--with-cache-check=PATH],
+ [cache_check tool: [[autodetect]]]),
+ CACHE_CHECK_CMD=$withval, CACHE_CHECK_CMD="autodetect")
+AC_ARG_WITH(cache-dump,
+ AC_HELP_STRING([--with-cache-dump=PATH],
+ [cache_dump tool: [[autodetect]]]),
+ CACHE_DUMP_CMD=$withval, CACHE_DUMP_CMD="autodetect")
+AC_ARG_WITH(cache-repair,
+ AC_HELP_STRING([--with-cache-repair=PATH],
+ [cache_repair tool: [[autodetect]]]),
+ CACHE_REPAIR_CMD=$withval, CACHE_REPAIR_CMD="autodetect")
+AC_ARG_WITH(cache-restore,
+ AC_HELP_STRING([--with-cache-restore=PATH],
+ [cache_restore tool: [[autodetect]]]),
+ CACHE_RESTORE_CMD=$withval, CACHE_RESTORE_CMD="autodetect")
AC_MSG_RESULT($CACHE)
case "$CACHE" in
@@ -511,6 +526,62 @@ case "$CACHE" in
*) AC_MSG_ERROR([--with-cache parameter invalid]) ;;
esac
+# Test if necessary cache tools are available
+# if not - use plain defaults and warn user
+case "$CACHE" in
+ internal|shared)
+ # Empty means a config way to ignore cache checking
+ if test "$CACHE_CHECK_CMD" = "autodetect"; then
+ AC_PATH_TOOL(CACHE_CHECK_CMD, cache_check)
+ if test -z "$CACHE_CHECK_CMD"; then
+ AC_MSG_WARN([cache_check not found in path $PATH])
+ CACHE_CHECK_CMD=/usr/sbin/cache_check
+ CACHE_CONFIGURE_WARN=y
+ fi
+ fi
+ # Empty means a config way to ignore cache dumping
+ if test "$CACHE_DUMP_CMD" = "autodetect"; then
+ AC_PATH_TOOL(CACHE_DUMP_CMD, cache_dump)
+ test -z "$CACHE_DUMP_CMD" && {
+ AC_MSG_WARN(cache_dump not found in path $PATH)
+ CACHE_DUMP_CMD=/usr/sbin/cache_dump
+ CACHE_CONFIGURE_WARN=y
+ }
+ fi
+ # Empty means a config way to ignore cache repairing
+ if test "$CACHE_REPAIR_CMD" = "autodetect"; then
+ AC_PATH_TOOL(CACHE_REPAIR_CMD, cache_repair)
+ test -z "$CACHE_REPAIR_CMD" && {
+ AC_MSG_WARN(cache_repair not found in path $PATH)
+ CACHE_REPAIR_CMD=/usr/sbin/cache_repair
+ CACHE_CONFIGURE_WARN=y
+ }
+ fi
+ # Empty means a config way to ignore cache restoring
+ if test "$CACHE_RESTORE_CMD" = "autodetect"; then
+ AC_PATH_TOOL(CACHE_RESTORE_CMD, cache_restore)
+ test -z "$CACHE_RESTORE_CMD" && {
+ AC_MSG_WARN(cache_restore not found in path $PATH)
+ CACHE_RESTORE_CMD=/usr/sbin/cache_restore
+ CACHE_CONFIGURE_WARN=y
+ }
+ fi
+ ;;
+esac
+
+AC_DEFINE_UNQUOTED([CACHE_CHECK_CMD], ["$CACHE_CHECK_CMD"],
+ [The path to 'cache_check', if available.])
+
+AC_DEFINE_UNQUOTED([CACHE_DUMP_CMD], ["$CACHE_DUMP_CMD"],
+ [The path to 'cache_dump', if available.])
+
+AC_DEFINE_UNQUOTED([CACHE_REPAIR_CMD], ["$CACHE_REPAIR_CMD"],
+ [The path to 'cache_repair', if available.])
+
+AC_DEFINE_UNQUOTED([CACHE_RESTORE_CMD], ["$CACHE_RESTORE_CMD"],
+ [The path to 'cache_restore', if available.])
+
+
################################################################################
dnl -- Disable readline
AC_MSG_CHECKING(whether to enable readline)
@@ -1660,6 +1731,10 @@ AC_SUBST(THIN_CHECK_CMD)
AC_SUBST(THIN_DUMP_CMD)
AC_SUBST(THIN_REPAIR_CMD)
AC_SUBST(THIN_RESTORE_CMD)
+AC_SUBST(CACHE_CHECK_CMD)
+AC_SUBST(CACHE_DUMP_CMD)
+AC_SUBST(CACHE_REPAIR_CMD)
+AC_SUBST(CACHE_RESTORE_CMD)
AC_SUBST(UDEV_PC)
AC_SUBST(UDEV_RULES)
AC_SUBST(UDEV_SYNC)
@@ -1764,4 +1839,6 @@ test -n "$THIN_CONFIGURE_WARN" && AC_MSG_WARN([Support for thin provisioning is
test -n "$THIN_CHECK_VERSION_WARN" && AC_MSG_WARN([You should also install thin_check vsn 0.3.2 (or later) to use lvm2 thin provisioning])
+test -n "$CACHE_CONFIGURE_WARN" && AC_MSG_WARN([Support for cache is limited since some cache tools are missing!])
+
test "$ODIRECT" = yes || AC_MSG_WARN([O_DIRECT disabled: low-memory pvmove may lock up])
diff --git a/lib/config/config_settings.h b/lib/config/config_settings.h
index 455eb4f..c6be2e3 100644
--- a/lib/config/config_settings.h
+++ b/lib/config/config_settings.h
@@ -182,6 +182,11 @@ cfg_array(global_thin_disabled_features_CFG, "thin_disabled_features", global_CF
cfg(global_thin_dump_executable_CFG, "thin_dump_executable", global_CFG_SECTION, CFG_ALLOW_EMPTY, CFG_TYPE_STRING, THIN_DUMP_CMD, vsn(2, 2, 100), NULL)
cfg(global_thin_repair_executable_CFG, "thin_repair_executable", global_CFG_SECTION, CFG_ALLOW_EMPTY, CFG_TYPE_STRING, THIN_REPAIR_CMD, vsn(2, 2, 100), NULL)
cfg_array(global_thin_repair_options_CFG, "thin_repair_options", global_CFG_SECTION, 0, CFG_TYPE_STRING, "#S" DEFAULT_THIN_REPAIR_OPTIONS, vsn(2, 2, 100), NULL)
+cfg(global_cache_check_executable_CFG, "cache_check_executable", global_CFG_SECTION, CFG_ALLOW_EMPTY, CFG_TYPE_STRING, CACHE_CHECK_CMD, vsn(2, 2, 108), NULL)
+cfg_array(global_cache_check_options_CFG, "cache_check_options", global_CFG_SECTION, 0, CFG_TYPE_STRING, "#S" DEFAULT_CACHE_CHECK_OPTIONS, vsn(2, 2, 108), NULL)
+cfg(global_cache_dump_executable_CFG, "cache_dump_executable", global_CFG_SECTION, CFG_ALLOW_EMPTY, CFG_TYPE_STRING, CACHE_DUMP_CMD, vsn(2, 2, 108), NULL)
+cfg(global_cache_repair_executable_CFG, "cache_repair_executable", global_CFG_SECTION, CFG_ALLOW_EMPTY, CFG_TYPE_STRING, CACHE_REPAIR_CMD, vsn(2, 2, 108), NULL)
+cfg_array(global_cache_repair_options_CFG, "cache_repair_options", global_CFG_SECTION, 0, CFG_TYPE_STRING, "#S" DEFAULT_CACHE_REPAIR_OPTIONS, vsn(2, 2, 108), NULL)
cfg(activation_checks_CFG, "checks", activation_CFG_SECTION, 0, CFG_TYPE_BOOL, DEFAULT_ACTIVATION_CHECKS, vsn(2, 2, 86), NULL)
cfg(activation_udev_sync_CFG, "udev_sync", activation_CFG_SECTION, 0, CFG_TYPE_BOOL, DEFAULT_UDEV_SYNC, vsn(2, 2, 51), NULL)
diff --git a/lib/config/defaults.h b/lib/config/defaults.h
index 815d6a3..05187b0 100644
--- a/lib/config/defaults.h
+++ b/lib/config/defaults.h
@@ -90,6 +90,8 @@
#define DEFAULT_THIN_POOL_ZERO 1
#define DEFAULT_POOL_METADATA_SPARE 1 /* thin + cache */
+#define DEFAULT_CACHE_CHECK_OPTIONS "-q"
+#define DEFAULT_CACHE_REPAIR_OPTIONS ""
#define DEFAULT_CACHE_POOL_METADATA_REQUIRE_SEPARATE_PVS 0
#define DEFAULT_CACHE_POOL_CHUNK_SIZE 64 /* KB */
#define DEFAULT_CACHE_POOL_MIN_METADATA_SIZE 2048 /* KB */
diff --git a/lib/misc/configure.h.in b/lib/misc/configure.h.in
index c618ff4..f137f14 100644
--- a/lib/misc/configure.h.in
+++ b/lib/misc/configure.h.in
@@ -3,9 +3,21 @@
/* Define to 1 to use libblkid detection of signatures when wiping. */
#undef BLKID_WIPING_SUPPORT
+/* The path to 'cache_check', if available. */
+#undef CACHE_CHECK_CMD
+
+/* The path to 'cache_dump', if available. */
+#undef CACHE_DUMP_CMD
+
/* Define to 1 to include built-in support for cache. */
#undef CACHE_INTERNAL
+/* The path to 'cache_repair', if available. */
+#undef CACHE_REPAIR_CMD
+
+/* The path to 'cache_restore', if available. */
+#undef CACHE_RESTORE_CMD
+
/* Define to 1 if the `closedir' function returns void instead of `int'. */
#undef CLOSEDIR_VOID
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=5c3d8940136f39a0…
Commit: 5c3d8940136f39a017ab434651789647161350b1
Parent: fd5912762b4815deb7a58fc4c5971801888e0ed3
Author: Peter Rajnoha <prajnoha(a)redhat.com>
AuthorDate: Fri Jul 11 12:24:15 2014 +0200
Committer: Peter Rajnoha <prajnoha(a)redhat.com>
CommitterDate: Fri Jul 11 12:24:15 2014 +0200
metadata: fix ALLOCATABLE_PV for lvm1 format
This is addendum for commit 6dc7b783c80c6834aa724df49b5d47b9b5601506.
LVM1 format stores the ALLOCATABLE flag directly in PV header, not
in VG metadata. So the code needs to be fixed further to work
properly for lvm1 format so that the correct PV header is written
(the flag is set only if the PV is in some VG, unset otherwise).
---
lib/format1/format1.c | 6 +++++-
lib/metadata/metadata.c | 2 +-
2 files changed, 6 insertions(+), 2 deletions(-)
diff --git a/lib/format1/format1.c b/lib/format1/format1.c
index 16746e3..8ee2f48 100644
--- a/lib/format1/format1.c
+++ b/lib/format1/format1.c
@@ -381,6 +381,7 @@ static int _format1_pv_setup(const struct format_type *fmt,
struct physical_volume *pv,
struct volume_group *vg)
{
+ int r;
struct pvcreate_restorable_params rp = {.restorefile = NULL,
.id = {{0}},
.idp = NULL,
@@ -390,7 +391,10 @@ static int _format1_pv_setup(const struct format_type *fmt,
.extent_count = 0,
.extent_size = vg->extent_size};
- return _format1_pv_initialise(fmt, -1, 0, 0, &rp, pv);
+ if ((r = _format1_pv_initialise(fmt, -1, 0, 0, &rp, pv)))
+ pv->status |= ALLOCATABLE_PV;
+
+ return r;
}
static int _format1_lv_setup(struct format_instance *fid, struct logical_volume *lv)
diff --git a/lib/metadata/metadata.c b/lib/metadata/metadata.c
index 2d69714..0832750 100644
--- a/lib/metadata/metadata.c
+++ b/lib/metadata/metadata.c
@@ -602,7 +602,7 @@ int vg_remove(struct volume_group *vg)
log_verbose("Removing physical volume \"%s\" from "
"volume group \"%s\"", pv_dev_name(pv), vg->name);
pv->vg_name = vg->fid->fmt->orphan_vg_name;
- pv->status = ALLOCATABLE_PV;
+ pv->status &= ~ALLOCATABLE_PV;
if (!dev_get_size(pv_dev(pv), &pv->size)) {
log_error("%s: Couldn't get size.", pv_dev_name(pv));
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=fd5912762b4815de…
Commit: fd5912762b4815deb7a58fc4c5971801888e0ed3
Parent: c9ae21798e1fa94e56c0f07ece1527377cbf1623
Author: Peter Rajnoha <prajnoha(a)redhat.com>
AuthorDate: Fri Jul 11 11:56:50 2014 +0200
Committer: Peter Rajnoha <prajnoha(a)redhat.com>
CommitterDate: Fri Jul 11 11:56:50 2014 +0200
report: display 'unknown' value for lv_active_remotely field if the LV is also active locally
Currently, we can't determine whether the LV is active remotely
or not in that case.
---
lib/report/report.c | 23 ++++++++++++++++++++++-
1 files changed, 22 insertions(+), 1 deletions(-)
diff --git a/lib/report/report.c b/lib/report/report.c
index e9f379a..91dfac0 100644
--- a/lib/report/report.c
+++ b/lib/report/report.c
@@ -1478,7 +1478,28 @@ static int _lvactiveremotely_disp(struct dm_report *rh, struct dm_pool *mem,
if (vg_is_clustered(lv->vg)) {
lv = lv_lock_holder(lv);
- active_remotely = lv_is_active_but_not_locally(lv);
+ /* FIXME: It seems we have no way to get this info correctly
+ * with current interface - we'd need to check number
+ * of responses from the cluster:
+ * - if number of nodes that responded == 1
+ * - and LV is active on local node
+ * ..then we may say that LV is *not* active remotely.
+ *
+ * Otherwise ((responses > 1 && LV active locally) ||
+ * (responses == 1 && LV not active locally)), it's
+ * active remotely.
+ *
+ * We have this info, but hidden underneath the
+ * locking interface (locking_type.query_resource fn).
+ *
+ * For now, let's use 'unknown' for remote status if
+ * the LV is found active locally until we find a way to
+ * smuggle the proper information out of the interface.
+ */
+ if (lv_is_active_locally(lv))
+ return _binary_undef_disp(rh, mem, field, private);
+ else
+ active_remotely = lv_is_active_but_not_locally(lv);
} else
active_remotely = 0;
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=c9ae21798e1fa94e…
Commit: c9ae21798e1fa94e56c0f07ece1527377cbf1623
Parent: 52af0dfbc0ebc442d3f1163e944e9ad88d05d46e
Author: Peter Rajnoha <prajnoha(a)redhat.com>
AuthorDate: Fri Jul 11 11:15:06 2014 +0200
Committer: Peter Rajnoha <prajnoha(a)redhat.com>
CommitterDate: Fri Jul 11 11:15:06 2014 +0200
report: display 'unknown' value for active/active_locally/active_remotely/active_exclusively if info bypassed
Before the patch:
$ lvs -o name,active vg/lvol1 --driverloaded n
WARNING: Activation disabled. No device-mapper interaction will beattempted.
LV Active
lvol1 active
With this patch applied:
$ lvs -o name,active vg/lvol1 --driverloaded n
WARNING: Activation disabled. No device-mapper interaction will be attempted.
LV Active
lvol1 unknown
The same for active_{locally,remotely,exclusively} fields.
Also, rename headings for these fields (ActLocal/ActRemote/ActExcl).
---
lib/metadata/lv.c | 7 ++++++-
lib/report/columns.h | 6 +++---
lib/report/report.c | 9 +++++++++
3 files changed, 18 insertions(+), 4 deletions(-)
diff --git a/lib/metadata/lv.c b/lib/metadata/lv.c
index 1ede9d6..d8fd320 100644
--- a/lib/metadata/lv.c
+++ b/lib/metadata/lv.c
@@ -910,6 +910,11 @@ char *lv_active_dup(struct dm_pool *mem, const struct logical_volume *lv)
{
const char *s;
+ if (!activation()) {
+ s = "unknown";
+ goto out;
+ }
+
if (vg_is_clustered(lv->vg)) {
//const struct logical_volume *lvo = lv;
lv = lv_lock_holder(lv);
@@ -927,7 +932,7 @@ char *lv_active_dup(struct dm_pool *mem, const struct logical_volume *lv)
else /* locally active */
s = lv_is_active_but_not_locally(lv) ?
"remotely" : "locally";
-
+out:
return dm_pool_strdup(mem, s);
}
diff --git a/lib/report/columns.h b/lib/report/columns.h
index dd5aa9e..af39008 100644
--- a/lib/report/columns.h
+++ b/lib/report/columns.h
@@ -53,9 +53,9 @@ FIELD(LVS, lv, STR, "TargetType", lvid, 10, lvtargettype, lv_target_type, "Kerne
FIELD(LVS, lv, STR, "Health", lvid, 15, lvhealthstatus, lv_health_status, "LV health status.", 0)
FIELD(LVS, lv, BIN, "SkipAct", lvid, 15, lvskipactivation, lv_skip_activation, "Set if LV is skipped on activation.", 0)
FIELD(LVS, lv, STR, "Active", lvid, 6, lvactive, lv_active, "Active state of the LV.", 0)
-FIELD(LVS, lv, BIN, "ActiveLoc", lvid, 10, lvactivelocally, lv_active_locally, "Set if the LV is active locally.", 0)
-FIELD(LVS, lv, BIN, "ActiveRem", lvid, 10, lvactiveremotely, lv_active_remotely, "Set if the LV is active remotely.", 0)
-FIELD(LVS, lv, BIN, "ActiveExcl", lvid, 10, lvactiveexclusively, lv_active_exclusively, "Set if the LV is active exclusively.", 0)
+FIELD(LVS, lv, BIN, "ActLocal", lvid, 10, lvactivelocally, lv_active_locally, "Set if the LV is active locally.", 0)
+FIELD(LVS, lv, BIN, "ActRemote", lvid, 10, lvactiveremotely, lv_active_remotely, "Set if the LV is active remotely.", 0)
+FIELD(LVS, lv, BIN, "ActExcl", lvid, 10, lvactiveexclusively, lv_active_exclusively, "Set if the LV is active exclusively.", 0)
FIELD(LVS, lv, NUM, "Maj", major, 3, int32, lv_major, "Persistent major number or -1 if not persistent.", 0)
FIELD(LVS, lv, NUM, "Min", minor, 3, int32, lv_minor, "Persistent minor number or -1 if not persistent.", 0)
FIELD(LVS, lv, SIZ, "Rahead", lvid, 6, lvreadahead, lv_read_ahead, "Read ahead setting in current units.", 0)
diff --git a/lib/report/report.c b/lib/report/report.c
index 061e39e..e9f379a 100644
--- a/lib/report/report.c
+++ b/lib/report/report.c
@@ -1454,6 +1454,9 @@ static int _lvactivelocally_disp(struct dm_report *rh, struct dm_pool *mem,
const struct logical_volume *lv = (const struct logical_volume *) data;
int active_locally;
+ if (!activation())
+ return _binary_undef_disp(rh, mem, field, private);
+
if (vg_is_clustered(lv->vg)) {
lv = lv_lock_holder(lv);
active_locally = lv_is_active_locally(lv);
@@ -1470,6 +1473,9 @@ static int _lvactiveremotely_disp(struct dm_report *rh, struct dm_pool *mem,
const struct logical_volume *lv = (const struct logical_volume *) data;
int active_remotely;
+ if (!activation())
+ return _binary_undef_disp(rh, mem, field, private);
+
if (vg_is_clustered(lv->vg)) {
lv = lv_lock_holder(lv);
active_remotely = lv_is_active_but_not_locally(lv);
@@ -1486,6 +1492,9 @@ static int _lvactiveexclusively_disp(struct dm_report *rh, struct dm_pool *mem,
const struct logical_volume *lv = (const struct logical_volume *) data;
int active_exclusively;
+ if (!activation())
+ return _binary_undef_disp(rh, mem, field, private);
+
if (vg_is_clustered(lv->vg)) {
lv = lv_lock_holder(lv);
active_exclusively = lv_is_active_exclusive(lv);
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=52af0dfbc0ebc442…
Commit: 52af0dfbc0ebc442d3f1163e944e9ad88d05d46e
Parent: f33d75e2e586a88ddeb20d860765f091098b8ab5
Author: Peter Rajnoha <prajnoha(a)redhat.com>
AuthorDate: Fri Jul 11 10:18:59 2014 +0200
Committer: Peter Rajnoha <prajnoha(a)redhat.com>
CommitterDate: Fri Jul 11 10:18:59 2014 +0200
report: display 'unknown' value for LVSINFO fields if unable to get info
If the lv_info call fails for whatever reason/INFO dm ioctl fails or
the dm driver communication is disabled (--driverloaded n), make
sure we always display "unknown" for LVSINFO fields as that's exactly
what happens - we don't know the state.
Before the patch:
$ lvs -o name,device_open --driverloaded n
WARNING: Activation disabled. No device-mapper interaction will be attempted.
Command failed with status code 5.
With this patch applied:
$ lvs -o name,device_open --driverloaded n
WARNING: Activation disabled. No device-mapper interaction will be attempted.
LV DevOpen
lvol1 unknown
---
lib/report/report.c | 4 +++-
tools/reporter.c | 22 +++++++++++++---------
2 files changed, 16 insertions(+), 10 deletions(-)
diff --git a/lib/report/report.c b/lib/report/report.c
index d193c47..061e39e 100644
--- a/lib/report/report.c
+++ b/lib/report/report.c
@@ -1394,7 +1394,9 @@ static int _lvpermissions_disp(struct dm_report *rh, struct dm_pool *mem,
if (!(lvi->lv->status & PVMOVE)) {
if (lvi->lv->status & LVM_WRITE) {
- if (lvi->info->read_only)
+ if (!lvi->info->exists)
+ perms = _str_unknown;
+ else if (lvi->info->read_only)
perms = FIRST_NAME(lv_permissions_r_override);
else
perms = FIRST_NAME(lv_permissions_rw);
diff --git a/tools/reporter.c b/tools/reporter.c
index 0780283..462ca8a 100644
--- a/tools/reporter.c
+++ b/tools/reporter.c
@@ -48,14 +48,20 @@ static int _lvs_single(struct cmd_context *cmd, struct logical_volume *lv,
return ECMD_PROCESSED;
}
+static void _get_lv_info_for_report(struct cmd_context *cmd,
+ struct logical_volume *lv,
+ struct lvinfo *lvinfo)
+{
+ if (!lv_info(cmd, lv, 0, lvinfo, 1, 1))
+ lvinfo->exists = 0;
+}
+
static int _lvs_with_info_single(struct cmd_context *cmd, struct logical_volume *lv,
void *handle)
{
struct lvinfo lvinfo;
- if (!lv_info(cmd, lv, 0, &lvinfo, 1, 1))
- return_ECMD_FAILED;
-
+ _get_lv_info_for_report(cmd, lv, &lvinfo);
if (!report_object(handle, lv->vg, lv, NULL, NULL, NULL, &lvinfo, NULL))
return_ECMD_FAILED;
@@ -76,8 +82,8 @@ static int _segs_with_lv_info_single(struct cmd_context *cmd __attribute__((unus
{
struct lvinfo lvinfo;
- if (!lv_info(cmd, seg->lv, 0, &lvinfo, 1, 1) ||
- !report_object(handle, seg->lv->vg, seg->lv, NULL, seg, NULL, &lvinfo, NULL))
+ _get_lv_info_for_report(cmd, seg->lv, &lvinfo);
+ if (!report_object(handle, seg->lv->vg, seg->lv, NULL, seg, NULL, &lvinfo, NULL))
return_ECMD_FAILED;
return ECMD_PROCESSED;
@@ -137,10 +143,8 @@ static int _do_pvsegs_sub_single(struct cmd_context *cmd,
dm_list_init(&_free_logical_volume.snapshot_segs);
lvinfo.exists = 0;
- if (seg && lv_info_needed && !lv_info(cmd, seg->lv, 0, &lvinfo, 1, 1)) {
- ret = ECMD_FAILED;
- goto_out;
- }
+ if (seg && lv_info_needed)
+ _get_lv_info_for_report(cmd, seg->lv, &lvinfo);
if (!report_object(handle, vg, seg ? seg->lv : &_free_logical_volume, pvseg->pv,
seg ? : &_free_lv_segment, pvseg, &lvinfo, pv_label(pvseg->pv))) {
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=f33d75e2e586a88d…
Commit: f33d75e2e586a88ddeb20d860765f091098b8ab5
Parent: 3063b48602220b0aa5e1ad7a91dc4ca60d717e36
Author: Jonathan Brassow <jbrassow(a)redhat.com>
AuthorDate: Thu Jul 10 18:52:55 2014 -0500
Committer: Jonathan Brassow <jbrassow(a)redhat.com>
CommitterDate: Thu Jul 10 18:53:46 2014 -0500
test: Test failing due to too few PVs
Commit 33d69162e4b45e7926d4c0e4a425fedb4246088e reduced the number of
PVs to a level where the test could not function. (It is impossible
to replace 3 PVs of a 4-way RAID1 LV if there are only 5 PVs.)
---
test/shell/lvconvert-raid.sh | 2 +-
test/shell/lvconvert-raid456.sh | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/test/shell/lvconvert-raid.sh b/test/shell/lvconvert-raid.sh
index 6f17303..bcf3874 100644
--- a/test/shell/lvconvert-raid.sh
+++ b/test/shell/lvconvert-raid.sh
@@ -24,7 +24,7 @@ get_image_pvs() {
########################################################
aux have_raid 1 3 0 || skip
-aux prepare_pvs 5
+aux prepare_pvs 9
vgcreate -s 256k $vg $(cat DEVICES)
###########################################
diff --git a/test/shell/lvconvert-raid456.sh b/test/shell/lvconvert-raid456.sh
index 1ead128..833b10e 100644
--- a/test/shell/lvconvert-raid456.sh
+++ b/test/shell/lvconvert-raid456.sh
@@ -25,7 +25,7 @@ get_image_pvs() {
aux raid456_replace_works || skip
aux have_raid 1 3 0 || skip
-aux prepare_pvs 6
+aux prepare_pvs 7 # 7 devices for 2 dev replacement of 5-dev RAID6
vgcreate -s 256k $vg $(cat DEVICES)
# RAID 4/5/6 (can replace up to 'parity' devices)
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=3063b48602220b0a…
Commit: 3063b48602220b0aa5e1ad7a91dc4ca60d717e36
Parent: d169ff1e039ecdfb1efac0a6464ca149d71d8767
Author: Peter Rajnoha <prajnoha(a)redhat.com>
AuthorDate: Thu Jul 10 16:41:42 2014 +0200
Committer: Peter Rajnoha <prajnoha(a)redhat.com>
CommitterDate: Thu Jul 10 16:41:42 2014 +0200
report: also report linear and striped for lv_target_type
---
lib/report/report.c | 4 ++++
1 files changed, 4 insertions(+), 0 deletions(-)
diff --git a/lib/report/report.c b/lib/report/report.c
index 6dc792b..d193c47 100644
--- a/lib/report/report.c
+++ b/lib/report/report.c
@@ -1590,6 +1590,10 @@ static int _lvtargettype_disp(struct dm_report *rh, struct dm_pool *mem,
target_type = "snapshot";
else if (lv_is_virtual(lv))
target_type = "virtual";
+ else if (lv_is_linear(lv))
+ target_type = "linear";
+ else if (lv_is_striped(lv))
+ target_type = "striped";
return _string_disp(rh, mem, field, &target_type, private);
}
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=d169ff1e039ecdfb…
Commit: d169ff1e039ecdfb1efac0a6464ca149d71d8767
Parent: e38af4e28fba0c6854f4bc2dc3842d74a11d199e
Author: Peter Rajnoha <prajnoha(a)redhat.com>
AuthorDate: Thu Jul 10 16:18:45 2014 +0200
Committer: Peter Rajnoha <prajnoha(a)redhat.com>
CommitterDate: Thu Jul 10 16:18:45 2014 +0200
conf: add report/list_item_separator lvm.conf option
For example:
$ lvm dumpconfig report/list_item_separator
list_item_separator=","
$ lvs -o name,tags vg/lvol1
LV LV Tags
lvol1 a,x,y
$ lvm dumpconfig report/list_item_separator
list_item_separator=":"
$ lvs -o name,tags vg/lvol1
LV LV Tags
lvol1 a:x:y
---
conf/command_profile_template.profile.in | 1 +
conf/example.conf.in | 3 +++
lib/commands/toolcontext.c | 1 +
lib/commands/toolcontext.h | 1 +
lib/config/config_settings.h | 1 +
lib/config/defaults.h | 1 +
lib/report/report.c | 13 ++++++++++---
7 files changed, 18 insertions(+), 3 deletions(-)
diff --git a/conf/command_profile_template.profile.in b/conf/command_profile_template.profile.in
index 7401aa5..0c1e6f0 100644
--- a/conf/command_profile_template.profile.in
+++ b/conf/command_profile_template.profile.in
@@ -22,6 +22,7 @@ report {
buffered=1
headings=1
separator=" "
+ list_item_separator=","
prefixes=0
quoted=1
colums_as_rows=0
diff --git a/conf/example.conf.in b/conf/example.conf.in
index 11f50f0..91768fb 100644
--- a/conf/example.conf.in
+++ b/conf/example.conf.in
@@ -1057,6 +1057,9 @@ activation {
# A separator to use on report after each field.
# separator=" "
+ # A separator to use for list items when reported.
+ # list_item_separator=","
+
# Use a field name prefix for each field reported.
# prefixes=0
diff --git a/lib/commands/toolcontext.c b/lib/commands/toolcontext.c
index 6ac4a42..fe79a81 100644
--- a/lib/commands/toolcontext.c
+++ b/lib/commands/toolcontext.c
@@ -299,6 +299,7 @@ int process_profilable_config(struct cmd_context *cmd) {
cmd->si_unit_consistency = find_config_tree_bool(cmd, global_si_unit_consistency_CFG, NULL);
cmd->report_binary_values_as_numeric = find_config_tree_bool(cmd, report_binary_values_as_numeric_CFG, NULL);
cmd->default_settings.suffix = find_config_tree_bool(cmd, global_suffix_CFG, NULL);
+ cmd->report_list_item_separator = find_config_tree_str(cmd, report_list_item_separator_CFG, NULL);
return 1;
}
diff --git a/lib/commands/toolcontext.h b/lib/commands/toolcontext.h
index d06dd7d..57c51d2 100644
--- a/lib/commands/toolcontext.h
+++ b/lib/commands/toolcontext.h
@@ -119,6 +119,7 @@ struct cmd_context {
/* List of defined tags */
struct dm_list tags;
+ const char *report_list_item_separator;
int hosttags;
const char *lib_dir; /* Cache value global/library_dir */
diff --git a/lib/config/config_settings.h b/lib/config/config_settings.h
index 7289a04..455eb4f 100644
--- a/lib/config/config_settings.h
+++ b/lib/config/config_settings.h
@@ -231,6 +231,7 @@ cfg(report_aligned_CFG, "aligned", report_CFG_SECTION, CFG_PROFILABLE, CFG_TYPE_
cfg(report_buffered_CFG, "buffered", report_CFG_SECTION, CFG_PROFILABLE, CFG_TYPE_BOOL, DEFAULT_REP_BUFFERED, vsn(1, 0, 0), NULL)
cfg(report_headings_CFG, "headings", report_CFG_SECTION, CFG_PROFILABLE, CFG_TYPE_BOOL, DEFAULT_REP_HEADINGS, vsn(1, 0, 0), NULL)
cfg(report_separator_CFG, "separator", report_CFG_SECTION, CFG_PROFILABLE, CFG_TYPE_STRING, DEFAULT_REP_SEPARATOR, vsn(1, 0, 0), NULL)
+cfg(report_list_item_separator_CFG, "list_item_separator", report_CFG_SECTION, CFG_PROFILABLE, CFG_TYPE_STRING, DEFAULT_REP_LIST_ITEM_SEPARATOR, vsn(2, 2, 108), NULL)
cfg(report_prefixes_CFG, "prefixes", report_CFG_SECTION, CFG_PROFILABLE, CFG_TYPE_BOOL, DEFAULT_REP_PREFIXES, vsn(2, 2, 36), NULL)
cfg(report_quoted_CFG, "quoted", report_CFG_SECTION, CFG_PROFILABLE, CFG_TYPE_BOOL, DEFAULT_REP_QUOTED, vsn(2, 2, 39), NULL)
cfg(report_colums_as_rows_CFG, "colums_as_rows", report_CFG_SECTION, CFG_PROFILABLE, CFG_TYPE_BOOL, DEFAULT_REP_COLUMNS_AS_ROWS, vsn(1, 0, 0), NULL)
diff --git a/lib/config/defaults.h b/lib/config/defaults.h
index 086f7fd..815d6a3 100644
--- a/lib/config/defaults.h
+++ b/lib/config/defaults.h
@@ -180,6 +180,7 @@
#define DEFAULT_REP_PREFIXES 0
#define DEFAULT_REP_QUOTED 1
#define DEFAULT_REP_SEPARATOR " "
+#define DEFAULT_REP_LIST_ITEM_SEPARATOR ","
#define DEFAULT_LVS_COLS "lv_name,vg_name,lv_attr,lv_size,pool_lv,origin,data_percent,metadata_percent,move_pv,mirror_log,copy_percent,convert_lv"
#define DEFAULT_VGS_COLS "vg_name,pv_count,lv_count,snap_count,vg_attr,vg_size,vg_free"
diff --git a/lib/report/report.c b/lib/report/report.c
index 5931021..6dc792b 100644
--- a/lib/report/report.c
+++ b/lib/report/report.c
@@ -139,6 +139,13 @@ static int _field_set_value(struct dm_report_field *field, const void *data, con
return 1;
}
+static int _field_set_string_list(struct dm_report *rh, struct dm_report_field *field,
+ const struct dm_list *list, void *private)
+{
+ struct cmd_context *cmd = (struct cmd_context *) private;
+ return dm_report_field_string_list(rh, field, list, cmd->report_list_item_separator);
+}
+
/*
* Data-munging functions to prepare each data type for display and sorting
*/
@@ -221,11 +228,11 @@ static int _peranges_disp(struct dm_report *rh __attribute__((unused)), struct d
static int _tags_disp(struct dm_report *rh, struct dm_pool *mem,
struct dm_report_field *field,
- const void *data, void *private __attribute__((unused)))
+ const void *data, void *private)
{
const struct dm_list *tagsl = (const struct dm_list *) data;
- return dm_report_field_string_list(rh, field, tagsl, NULL);
+ return _field_set_string_list(rh, field, tagsl, private);
}
static int _modules_disp(struct dm_report *rh, struct dm_pool *mem,
@@ -243,7 +250,7 @@ static int _modules_disp(struct dm_report *rh, struct dm_pool *mem,
if (!(list_lv_modules(mem, lv, modules)))
return_0;
- return dm_report_field_string_list(rh, field, modules, NULL);
+ return _field_set_string_list(rh, field, modules, private);
}
static int _lvprofile_disp(struct dm_report *rh, struct dm_pool *mem,
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=e38af4e28fba0c68…
Commit: e38af4e28fba0c6854f4bc2dc3842d74a11d199e
Parent: 1e5ec893c7d9cf243a6ecb17ed6320d37e9a147c
Author: Peter Rajnoha <prajnoha(a)redhat.com>
AuthorDate: Thu Jul 10 16:09:58 2014 +0200
Committer: Peter Rajnoha <prajnoha(a)redhat.com>
CommitterDate: Thu Jul 10 16:18:05 2014 +0200
libdm: report: fix string list internal representation if delimiter is composed of more than one char
---
WHATS_NEW_DM | 1 +
libdm/libdm-report.c | 2 +-
2 files changed, 2 insertions(+), 1 deletions(-)
diff --git a/WHATS_NEW_DM b/WHATS_NEW_DM
index 852d313..ab94bc4 100644
--- a/WHATS_NEW_DM
+++ b/WHATS_NEW_DM
@@ -1,5 +1,6 @@
Version 1.02.87 -
================================
+ Fix dm_report_field_string_list to handle delimiter with multiple chars.
Add dm_report_field_reserved_value for per-field reserved value definition.
Version 1.02.86 - 23rd June 2014
diff --git a/libdm/libdm-report.c b/libdm/libdm-report.c
index 9b4ea87..b94cc00 100644
--- a/libdm/libdm-report.c
+++ b/libdm/libdm-report.c
@@ -420,7 +420,7 @@ int dm_report_field_string_list(struct dm_report *rh,
*/
sort_value->items[i].pos = pos;
sort_value->items[i].len = len;
- pos = i == list_size ? pos+len : pos+len+1;
+ pos = i == list_size ? pos+len : pos+len+delimiter_len;
}
if (!dm_pool_grow_object(rh->mem, "\0", 1)) {
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=1e5ec893c7d9cf24…
Commit: 1e5ec893c7d9cf243a6ecb17ed6320d37e9a147c
Parent: e2448bb0dcfa63b2a8fae24b989393a821917120
Author: Peter Rajnoha <prajnoha(a)redhat.com>
AuthorDate: Thu Jul 10 15:30:28 2014 +0200
Committer: Peter Rajnoha <prajnoha(a)redhat.com>
CommitterDate: Thu Jul 10 15:30:28 2014 +0200
tests: LV's zero field now reported as binary field
---
test/shell/profiles-thin.sh | 6 +++---
test/shell/thin-defaults.sh | 2 +-
2 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/test/shell/profiles-thin.sh b/test/shell/profiles-thin.sh
index 704ef2d..3519985 100644
--- a/test/shell/profiles-thin.sh
+++ b/test/shell/profiles-thin.sh
@@ -34,7 +34,7 @@ vgcreate $vg "$dev1"
lvcreate -L8m -T $vg/pool_generic
check lv_field $vg/pool_generic profile ""
check lv_field $vg/pool_generic chunk_size 64.00k
-check lv_field $vg/pool_generic zero 1
+check lv_field $vg/pool_generic zero "zero"
# If "thin-performance" profile is used, the "performance"
# policy is used to calculate chunk size which is 512KiB
@@ -44,7 +44,7 @@ check lv_field $vg/pool_generic zero 1
lvcreate --profile thin-performance -L8m -T $vg/pool_performance
check lv_field $vg/pool_performance profile "thin-performance"
check lv_field $vg/pool_performance chunk_size 1.00m
-check lv_field $vg/pool_performance zero 0
+check lv_field $vg/pool_performance zero ""
vgremove -ff $vg
@@ -56,4 +56,4 @@ lvcreate -L8m -T $vg/pool_performance_inherited
check vg_field $vg profile "thin-performance"
check lv_field $vg/pool_performance_inherited profile ""
check lv_field $vg/pool_performance_inherited chunk_size 1.00m
-check lv_field $vg/pool_performance_inherited zero 0
+check lv_field $vg/pool_performance_inherited zero ""
diff --git a/test/shell/thin-defaults.sh b/test/shell/thin-defaults.sh
index 4f873cc..3a681a1 100644
--- a/test/shell/thin-defaults.sh
+++ b/test/shell/thin-defaults.sh
@@ -30,6 +30,6 @@ lvcreate -T -L8M $vg/pool1
check lv_field $vg/pool1 chunksize "128.00k"
check lv_field $vg/pool1 discards "ignore"
-check lv_field $vg/pool1 zero 0
+check lv_field $vg/pool1 zero ""
vgremove -f $vg
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=e2448bb0dcfa63b2…
Commit: e2448bb0dcfa63b2a8fae24b989393a821917120
Parent: e31ec38d8e657d5f6d6efca6eade083357675276
Author: Peter Rajnoha <prajnoha(a)redhat.com>
AuthorDate: Thu Jul 10 15:23:56 2014 +0200
Committer: Peter Rajnoha <prajnoha(a)redhat.com>
CommitterDate: Thu Jul 10 15:25:01 2014 +0200
report: report LV's zero field as binary field
Like other binary fields we already have:
$ lvs -o name,zero vg/lvx vg/pool vg/pool1
LV Zero
lvx unknown
pool
pool1 zero
$ lvs -o name,zero vg/lvx vg/pool vg/pool1 --binary
LV Zero
lvx -1
pool 0
pool1 1
---
lib/report/columns.h | 2 +-
lib/report/report.c | 4 ++--
lib/report/values.h | 1 +
3 files changed, 4 insertions(+), 3 deletions(-)
diff --git a/lib/report/columns.h b/lib/report/columns.h
index 3d3d76e..dd5aa9e 100644
--- a/lib/report/columns.h
+++ b/lib/report/columns.h
@@ -158,7 +158,7 @@ FIELD(SEGS, seg, SIZ, "Chunk", list, 5, chunksize, chunksize, "For snapshots, th
FIELD(SEGS, seg, SIZ, "Chunk", list, 5, chunksize, chunk_size, "For snapshots, the unit of data used when tracking changes.", 0)
FIELD(SEGS, seg, NUM, "#Thins", list, 4, thincount, thin_count, "For thin pools, the number of thin volumes in this pool.", 0)
FIELD(SEGS, seg, STR, "Discards", list, 8, discards, discards, "For thin pools, how discards are handled.", 0)
-FIELD(SEGS, seg, NUM, "Zero", list, 4, thinzero, zero, "For thin pools, if zeroing is enabled.", 0)
+FIELD(SEGS, seg, BIN, "Zero", list, 4, thinzero, zero, "For thin pools, if zeroing is enabled.", 0)
FIELD(SEGS, seg, NUM, "TransId", list, 4, transactionid, transaction_id, "For thin pools, the transaction id.", 0)
FIELD(SEGS, seg, NUM, "ThId", list, 4, thinid, thin_id, "For thin volume, the thin device id.", 0)
FIELD(SEGS, seg, NUM, "Start", list, 5, segstart, seg_start, "Offset within the LV to the start of the segment in current units.", 0)
diff --git a/lib/report/report.c b/lib/report/report.c
index 63b1647..5931021 100644
--- a/lib/report/report.c
+++ b/lib/report/report.c
@@ -1594,9 +1594,9 @@ static int _thinzero_disp(struct dm_report *rh, struct dm_pool *mem,
const struct lv_segment *seg = (const struct lv_segment *) data;
if (seg_is_thin_pool(seg))
- return _uint32_disp(rh, mem, field, &seg->zero_new_blocks, private);
+ return _binary_disp(rh, mem, field, seg->zero_new_blocks, FIRST_NAME(zero_y), private);
- return _field_set_value(field, "", &RESERVED(number_undef_64));
+ return _binary_undef_disp(rh, mem, field, private);
}
static int _lvhealthstatus_disp(struct dm_report *rh, struct dm_pool *mem,
diff --git a/lib/report/values.h b/lib/report/values.h
index d8de665..7425bc6 100644
--- a/lib/report/values.h
+++ b/lib/report/values.h
@@ -75,6 +75,7 @@ FIELD_RESERVED_BINARY_VALUE(lv_live_table, lv_live_table, "", "live table presen
FIELD_RESERVED_BINARY_VALUE(lv_inactive_table, lv_inactive_table, "", "inactive table present", "inactive table", "inactive")
FIELD_RESERVED_BINARY_VALUE(lv_device_open, lv_device_open, "", "open")
FIELD_RESERVED_BINARY_VALUE(lv_skip_activation, lv_skip_activation, "", "skip activation", "skip")
+FIELD_RESERVED_BINARY_VALUE(zero, zero, "", "zero")
FIELD_RESERVED_VALUE(lv_permissions, lv_permissions_rw, "", FIRST_NAME(lv_permissions_rw), "writeable", "rw", "read-write")
FIELD_RESERVED_VALUE(lv_permissions, lv_permissions_r, "", FIRST_NAME(lv_permissions_r), "", "read-only", "r", "ro")
FIELD_RESERVED_VALUE(lv_permissions, lv_permissions_r_override, "", FIRST_NAME(lv_permissions_r_override), "", "read-only-override", "ro-override", "r-override", "R")
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=e31ec38d8e657d5f…
Commit: e31ec38d8e657d5f6d6efca6eade083357675276
Parent: 175de52deddbd0727c42d7a3e34d27b6f70f2deb
Author: Peter Rajnoha <prajnoha(a)redhat.com>
AuthorDate: Thu Jul 10 13:42:16 2014 +0200
Committer: Peter Rajnoha <prajnoha(a)redhat.com>
CommitterDate: Thu Jul 10 13:42:16 2014 +0200
report: reserved value: description for undefined value
---
lib/report/values.h | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/lib/report/values.h b/lib/report/values.h
index 3ee6192..d8de665 100644
--- a/lib/report/values.h
+++ b/lib/report/values.h
@@ -42,7 +42,7 @@
/* *INDENT-OFF* */
/* Per-type reserved values usable for all fields of certain type. */
-TYPE_RESERVED_VALUE(NUM, number_undef_64, "", UINT64_C(-1), "-1", "unknown", "undefined", "undef")
+TYPE_RESERVED_VALUE(NUM, number_undef_64, "Reserved value for undefined numeric value.", UINT64_C(-1), "-1", "unknown", "undefined", "undef")
/* Reserved values for PV fields */
FIELD_RESERVED_BINARY_VALUE(pv_allocatable, pv_allocatable, "", "allocatable")
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=175de52deddbd072…
Commit: 175de52deddbd0727c42d7a3e34d27b6f70f2deb
Parent: f598aa38aeee369be912153a2a577520f69e8d88
Author: Peter Rajnoha <prajnoha(a)redhat.com>
AuthorDate: Thu Jul 10 13:37:26 2014 +0200
Committer: Peter Rajnoha <prajnoha(a)redhat.com>
CommitterDate: Thu Jul 10 13:37:40 2014 +0200
cleanup: also use values.h for final dm_report_reserved_value array composition
---
lib/report/report.c | 64 +++++++++++------------------------------------
lib/report/values.h | 68 +++++++++++++++++++++++++-------------------------
2 files changed, 49 insertions(+), 83 deletions(-)
diff --git a/lib/report/report.c b/lib/report/report.c
index 1d70016..63b1647 100644
--- a/lib/report/report.c
+++ b/lib/report/report.c
@@ -73,9 +73,9 @@ static const int32_t _reserved_number_undef_32 = INT32_C(-1);
* All names listed are synonyms recognized in selection criteria.
* For binary-based values we map all reserved names listed onto value 1, blank onto value 0.
*
- * TYPE_RESERVED_VALUE(type, reserved_value_id, value, reserved name, ...)
- * FIELD_RESERVED_VALUE(field_id, reserved_value_id, value, reserved name, ...)
- * FIELD_RESERVED_BINARY_VALUE(field_id, reserved_value_id, value, reserved name for 1, ...)
+ * TYPE_RESERVED_VALUE(type, reserved_value_id, description, value, reserved name, ...)
+ * FIELD_RESERVED_VALUE(field_id, reserved_value_id, description, value, reserved name, ...)
+ * FIELD_RESERVED_BINARY_VALUE(field_id, reserved_value_id, description, reserved name for 1, ...)
*
* Note: FIELD_RESERVED_BINARY_VALUE creates:
* - 'reserved_value_id_y' (for 1)
@@ -86,17 +86,17 @@ static const int32_t _reserved_number_undef_32 = INT32_C(-1);
#define NUM uint64_t
-#define TYPE_RESERVED_VALUE(type, id, value, ...) \
+#define TYPE_RESERVED_VALUE(type, id, desc, value, ...) \
static const char *_reserved_ ## id ## _names[] = { __VA_ARGS__, NULL}; \
static const type _reserved_ ## id = value;
-#define FIELD_RESERVED_VALUE(field_id, id, value, ...) \
+#define FIELD_RESERVED_VALUE(field_id, id, desc, value, ...) \
static const char *_reserved_ ## id ## _names[] = { __VA_ARGS__ , NULL}; \
static const struct dm_report_field_reserved_value _reserved_ ## id = {field_ ## field_id, &value};
-#define FIELD_RESERVED_BINARY_VALUE(field_id, id, ...) \
- FIELD_RESERVED_VALUE(field_id, id ## _y, _one64, __VA_ARGS__, _str_yes) \
- FIELD_RESERVED_VALUE(field_id, id ## _n, _zero64, __VA_ARGS__, _str_no)
+#define FIELD_RESERVED_BINARY_VALUE(field_id, id, desc, ...) \
+ FIELD_RESERVED_VALUE(field_id, id ## _y, desc, _one64, __VA_ARGS__, _str_yes) \
+ FIELD_RESERVED_VALUE(field_id, id ## _n, desc, _zero64, __VA_ARGS__, _str_no)
#include "values.h"
@@ -110,54 +110,20 @@ static const int32_t _reserved_number_undef_32 = INT32_C(-1);
* dm_report_init_with_selection function that initializes report with
* selection criteria. Selection code then recognizes these reserved values
* when parsing selection criteria.
- *
- * TYPE_RESERVED_VALUE_REG(report_type, reserved_value_id, description)
- * FIELD_RESERVED_VALUE_REG(reserved_value_id, description)
- * FIELD_RESERVED_BINARY_BALUE_REG(reserved_value_id, description)
- */
+*/
#define NUM DM_REPORT_FIELD_TYPE_NUMBER
-#define TYPE_RESERVED_VALUE_REG(type, id, description) {type, &_reserved_ ## id, _reserved_ ## id ## _names, description},
+#define TYPE_RESERVED_VALUE(type, id, desc, value, ...) {type, &_reserved_ ## id, _reserved_ ## id ## _names, desc},
-#define FIELD_RESERVED_VALUE_REG(id, description) {DM_REPORT_FIELD_TYPE_NONE, &_reserved_ ## id, _reserved_ ## id ## _names, description},
+#define FIELD_RESERVED_VALUE(field_id, id, desc, value, ...) {DM_REPORT_FIELD_TYPE_NONE, &_reserved_ ## id, _reserved_ ## id ## _names, desc},
-#define FIELD_RESERVED_BINARY_VALUE_REG(id, description) \
- FIELD_RESERVED_VALUE_REG(id ## _y, description) \
- FIELD_RESERVED_VALUE_REG(id ## _n, description)
+#define FIELD_RESERVED_BINARY_VALUE(field_id, id, desc, ...) \
+ FIELD_RESERVED_VALUE(field_id, id ## _y, desc, _one64, __VA_ARGS__) \
+ FIELD_RESERVED_VALUE(field_id, id ## _n, desc, _zero64, __VA_ARGS__)
static const struct dm_report_reserved_value _report_reserved_values[] = {
- TYPE_RESERVED_VALUE_REG(NUM, number_undef_64, "Reserved value for undefined numeric value.")
- FIELD_RESERVED_BINARY_VALUE_REG(pv_allocatable, "pv_allocatable reserved values")
- FIELD_RESERVED_BINARY_VALUE_REG(pv_exported, "pv_exported reserved values")
- FIELD_RESERVED_BINARY_VALUE_REG(pv_missing, "pv_missing reserved values")
- FIELD_RESERVED_BINARY_VALUE_REG(vg_extendable, "vg_extendable reserved values")
- FIELD_RESERVED_BINARY_VALUE_REG(vg_exported, "vg_exported reserved values")
- FIELD_RESERVED_BINARY_VALUE_REG(vg_partial, "vg_partial reserved values")
- FIELD_RESERVED_BINARY_VALUE_REG(vg_clustered, "vg_clustered reserved values")
- FIELD_RESERVED_VALUE_REG(vg_permissions_rw, "vg_permissions reserved values (writeable)")
- FIELD_RESERVED_VALUE_REG(vg_permissions_r, "vg_permissions reserved values (read-only)")
- FIELD_RESERVED_VALUE_REG(vg_mda_copies, "vg_mda_copies reserved values (unmanaged)")
- FIELD_RESERVED_BINARY_VALUE_REG(lv_initial_image_sync, "lv_initial_image_sync reserved values")
- FIELD_RESERVED_BINARY_VALUE_REG(lv_image_synced, "lv_image_synced reserved values")
- FIELD_RESERVED_BINARY_VALUE_REG(lv_merging, "lv_merging reserved values")
- FIELD_RESERVED_BINARY_VALUE_REG(lv_converting, "lv_converting reserved values")
- FIELD_RESERVED_BINARY_VALUE_REG(lv_allocation_locked, "lv_allocation_locked reserved values")
- FIELD_RESERVED_BINARY_VALUE_REG(lv_fixed_minor, "lv_fixed_minor reserved values")
- FIELD_RESERVED_BINARY_VALUE_REG(lv_active_locally, "lv_active_locally reserved values")
- FIELD_RESERVED_BINARY_VALUE_REG(lv_active_remotely, "lv_active_remotelly reserved values")
- FIELD_RESERVED_BINARY_VALUE_REG(lv_active_exclusively, "lv_active_exclusively reserved values")
- FIELD_RESERVED_BINARY_VALUE_REG(lv_merge_failed, "lv_merge_failed reserved values")
- FIELD_RESERVED_BINARY_VALUE_REG(lv_snapshot_invalid, "lv_snapshot_invalid reserved values")
- FIELD_RESERVED_BINARY_VALUE_REG(lv_suspended, "lv_suspended reserved values")
- FIELD_RESERVED_BINARY_VALUE_REG(lv_live_table, "lv_live_table reserved values")
- FIELD_RESERVED_BINARY_VALUE_REG(lv_inactive_table, "lv_inactive_table reserved values")
- FIELD_RESERVED_BINARY_VALUE_REG(lv_device_open, "lv_device_open reserved values")
- FIELD_RESERVED_BINARY_VALUE_REG(lv_skip_activation, "lv_inactive_table reserved values")
- FIELD_RESERVED_VALUE_REG(lv_permissions_rw, "lv_permissions reserved values (writeable)")
- FIELD_RESERVED_VALUE_REG(lv_permissions_r, "lv_permissions reserved values (read-only)")
- FIELD_RESERVED_VALUE_REG(lv_permissions_r_override, "lv_permissions reserved values (read-only-override)")
- FIELD_RESERVED_VALUE_REG(lv_read_ahead, "lv_read_ahead reserved values (auto)")
+ #include "values.h"
{0, NULL, NULL}
};
diff --git a/lib/report/values.h b/lib/report/values.h
index 5c4b5ab..3ee6192 100644
--- a/lib/report/values.h
+++ b/lib/report/values.h
@@ -34,50 +34,50 @@
*/
/*
- * TYPE_RESERVED_VALUE(type, id, value, reserved_name, ...)
- * FIELD_RESERVED_VALUE(field_id, reserved_value_id, value, reserved_name, ...)
- * FIELD_BINARY_RESERVED_VALUE(field_id, reserved_value_id, reserved_name, ...)
+ * TYPE_RESERVED_VALUE(type, reserved_value_id, description, value, reserved_name, ...)
+ * FIELD_RESERVED_VALUE(field_id, reserved_value_id, description, value, reserved_name, ...)
+ * FIELD_BINARY_RESERVED_VALUE(field_id, reserved_value_id, description, reserved_name for 1, ...)
*/
/* *INDENT-OFF* */
/* Per-type reserved values usable for all fields of certain type. */
-TYPE_RESERVED_VALUE(NUM, number_undef_64, UINT64_C(-1), "-1", "unknown", "undefined", "undef");
+TYPE_RESERVED_VALUE(NUM, number_undef_64, "", UINT64_C(-1), "-1", "unknown", "undefined", "undef")
/* Reserved values for PV fields */
-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_allocatable, pv_allocatable, "", "allocatable")
+FIELD_RESERVED_BINARY_VALUE(pv_exported, pv_exported, "", "exported")
+FIELD_RESERVED_BINARY_VALUE(pv_missing, pv_missing, "", "missing")
/* Reserved values for VG fields */
-FIELD_RESERVED_BINARY_VALUE(vg_extendable, vg_extendable, "extendable")
-FIELD_RESERVED_BINARY_VALUE(vg_exported, vg_exported, "exported")
-FIELD_RESERVED_BINARY_VALUE(vg_partial, vg_partial, "partial")
-FIELD_RESERVED_BINARY_VALUE(vg_clustered, vg_clustered, "clustered")
-FIELD_RESERVED_VALUE(vg_permissions, vg_permissions_rw, FIRST_NAME(vg_permissions_rw), "writeable", "rw", "read-write")
-FIELD_RESERVED_VALUE(vg_permissions, vg_permissions_r, FIRST_NAME(vg_permissions_r), "read-only", "r", "ro")
-FIELD_RESERVED_VALUE(vg_mda_copies, vg_mda_copies, RESERVED(number_undef_64), "unmanaged")
+FIELD_RESERVED_BINARY_VALUE(vg_extendable, vg_extendable, "", "extendable")
+FIELD_RESERVED_BINARY_VALUE(vg_exported, vg_exported, "", "exported")
+FIELD_RESERVED_BINARY_VALUE(vg_partial, vg_partial, "", "partial")
+FIELD_RESERVED_BINARY_VALUE(vg_clustered, vg_clustered, "", "clustered")
+FIELD_RESERVED_VALUE(vg_permissions, vg_permissions_rw, "", FIRST_NAME(vg_permissions_rw), "writeable", "rw", "read-write")
+FIELD_RESERVED_VALUE(vg_permissions, vg_permissions_r, "", FIRST_NAME(vg_permissions_r), "read-only", "r", "ro")
+FIELD_RESERVED_VALUE(vg_mda_copies, vg_mda_copies, "", RESERVED(number_undef_64), "unmanaged")
/* Reserved values for LV fields */
-FIELD_RESERVED_BINARY_VALUE(lv_initial_image_sync, lv_initial_image_sync, "initial image sync", "sync")
-FIELD_RESERVED_BINARY_VALUE(lv_image_synced, lv_image_synced, "image synced", "synced")
-FIELD_RESERVED_BINARY_VALUE(lv_merging, lv_merging, "merging")
-FIELD_RESERVED_BINARY_VALUE(lv_converting, lv_converting, "converting")
-FIELD_RESERVED_BINARY_VALUE(lv_allocation_locked, lv_allocation_locked, "allocation locked", "locked")
-FIELD_RESERVED_BINARY_VALUE(lv_fixed_minor, lv_fixed_minor, "fixed minor", "fixed")
-FIELD_RESERVED_BINARY_VALUE(lv_active_locally, lv_active_locally, "active locally", "active", "locally")
-FIELD_RESERVED_BINARY_VALUE(lv_active_remotely, lv_active_remotely, "active remotely", "active", "remotely")
-FIELD_RESERVED_BINARY_VALUE(lv_active_exclusively, lv_active_exclusively, "active exclusively", "active", "exclusively")
-FIELD_RESERVED_BINARY_VALUE(lv_merge_failed, lv_merge_failed, "merge failed", "failed")
-FIELD_RESERVED_BINARY_VALUE(lv_snapshot_invalid, lv_snapshot_invalid, "snapshot invalid", "invalid")
-FIELD_RESERVED_BINARY_VALUE(lv_suspended, lv_suspended, "suspended")
-FIELD_RESERVED_BINARY_VALUE(lv_live_table, lv_live_table, "live table present", "live table", "live")
-FIELD_RESERVED_BINARY_VALUE(lv_inactive_table, lv_inactive_table, "inactive table present", "inactive table", "inactive")
-FIELD_RESERVED_BINARY_VALUE(lv_device_open, lv_device_open, "open")
-FIELD_RESERVED_BINARY_VALUE(lv_skip_activation, lv_skip_activation, "skip activation", "skip")
-FIELD_RESERVED_VALUE(lv_permissions, lv_permissions_rw, FIRST_NAME(lv_permissions_rw), "writeable", "rw", "read-write")
-FIELD_RESERVED_VALUE(lv_permissions, lv_permissions_r, FIRST_NAME(lv_permissions_r), "read-only", "r", "ro")
-FIELD_RESERVED_VALUE(lv_permissions, lv_permissions_r_override, FIRST_NAME(lv_permissions_r_override), "read-only-override", "ro-override", "r-override", "R")
-FIELD_RESERVED_VALUE(lv_read_ahead, lv_read_ahead, RESERVED(number_undef_64), "auto")
+FIELD_RESERVED_BINARY_VALUE(lv_initial_image_sync, lv_initial_image_sync, "", "initial image sync", "sync")
+FIELD_RESERVED_BINARY_VALUE(lv_image_synced, lv_image_synced, "", "image synced", "synced")
+FIELD_RESERVED_BINARY_VALUE(lv_merging, lv_merging, "", "merging")
+FIELD_RESERVED_BINARY_VALUE(lv_converting, lv_converting, "", "converting")
+FIELD_RESERVED_BINARY_VALUE(lv_allocation_locked, lv_allocation_locked, "", "allocation locked", "locked")
+FIELD_RESERVED_BINARY_VALUE(lv_fixed_minor, lv_fixed_minor, "", "fixed minor", "fixed")
+FIELD_RESERVED_BINARY_VALUE(lv_active_locally, lv_active_locally, "", "active locally", "active", "locally")
+FIELD_RESERVED_BINARY_VALUE(lv_active_remotely, lv_active_remotely, "", "active remotely", "active", "remotely")
+FIELD_RESERVED_BINARY_VALUE(lv_active_exclusively, lv_active_exclusively, "", "active exclusively", "active", "exclusively")
+FIELD_RESERVED_BINARY_VALUE(lv_merge_failed, lv_merge_failed, "", "merge failed", "failed")
+FIELD_RESERVED_BINARY_VALUE(lv_snapshot_invalid, lv_snapshot_invalid, "", "snapshot invalid", "invalid")
+FIELD_RESERVED_BINARY_VALUE(lv_suspended, lv_suspended, "", "suspended")
+FIELD_RESERVED_BINARY_VALUE(lv_live_table, lv_live_table, "", "live table present", "live table", "live")
+FIELD_RESERVED_BINARY_VALUE(lv_inactive_table, lv_inactive_table, "", "inactive table present", "inactive table", "inactive")
+FIELD_RESERVED_BINARY_VALUE(lv_device_open, lv_device_open, "", "open")
+FIELD_RESERVED_BINARY_VALUE(lv_skip_activation, lv_skip_activation, "", "skip activation", "skip")
+FIELD_RESERVED_VALUE(lv_permissions, lv_permissions_rw, "", FIRST_NAME(lv_permissions_rw), "writeable", "rw", "read-write")
+FIELD_RESERVED_VALUE(lv_permissions, lv_permissions_r, "", FIRST_NAME(lv_permissions_r), "", "read-only", "r", "ro")
+FIELD_RESERVED_VALUE(lv_permissions, lv_permissions_r_override, "", FIRST_NAME(lv_permissions_r_override), "", "read-only-override", "ro-override", "r-override", "R")
+FIELD_RESERVED_VALUE(lv_read_ahead, lv_read_ahead, "", RESERVED(number_undef_64), "auto")
/* *INDENT-ON* */
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=f598aa38aeee369b…
Commit: f598aa38aeee369be912153a2a577520f69e8d88
Parent: fafd10d564151b91e814f6be3e735bdf0b7d33dd
Author: Peter Rajnoha <prajnoha(a)redhat.com>
AuthorDate: Thu Jul 10 11:54:37 2014 +0200
Committer: Peter Rajnoha <prajnoha(a)redhat.com>
CommitterDate: Thu Jul 10 11:54:37 2014 +0200
cleanup: report reserved value macros
---
lib/report/report.c | 57 ++++++++++++++++++++++++++++++--------------------
lib/report/values.h | 23 ++++++++++++++------
2 files changed, 50 insertions(+), 30 deletions(-)
diff --git a/lib/report/report.c b/lib/report/report.c
index d3dbefc..1d70016 100644
--- a/lib/report/report.c
+++ b/lib/report/report.c
@@ -58,7 +58,6 @@ static const char const _str_zero[] = "0";
static const char const _str_one[] = "1";
static const char const _str_no[] = "no";
static const char const _str_yes[] = "yes";
-static const char const _str_minus_one[] = "-1";
static const char const _str_unknown[] = "unknown";
/*
@@ -82,20 +81,26 @@ static const int32_t _reserved_number_undef_32 = INT32_C(-1);
* - 'reserved_value_id_y' (for 1)
* - 'reserved_value_id_n' (for 0)
*/
+#define RESERVED(id) _reserved_ ## id
#define FIRST_NAME(id) _reserved_ ## id ## _names[0]
+
+#define NUM uint64_t
+
#define TYPE_RESERVED_VALUE(type, id, value, ...) \
static const char *_reserved_ ## id ## _names[] = { __VA_ARGS__, NULL}; \
static const type _reserved_ ## id = value;
+
#define FIELD_RESERVED_VALUE(field_id, id, value, ...) \
static const char *_reserved_ ## id ## _names[] = { __VA_ARGS__ , NULL}; \
static const struct dm_report_field_reserved_value _reserved_ ## id = {field_ ## field_id, &value};
+
#define FIELD_RESERVED_BINARY_VALUE(field_id, id, ...) \
FIELD_RESERVED_VALUE(field_id, id ## _y, _one64, __VA_ARGS__, _str_yes) \
FIELD_RESERVED_VALUE(field_id, id ## _n, _zero64, __VA_ARGS__, _str_no)
-TYPE_RESERVED_VALUE(uint64_t, number_undef_64, UINT64_C(-1), _str_minus_one, _str_unknown, "undefined", "undef");
#include "values.h"
+#undef NUM
#undef TYPE_RESERVED_VALUE
#undef FIELD_RESERVED_VALUE
#undef FIELD_RESERVED_BINARY_VALUE
@@ -110,14 +115,19 @@ TYPE_RESERVED_VALUE(uint64_t, number_undef_64, UINT64_C(-1), _str_minus_one, _st
* FIELD_RESERVED_VALUE_REG(reserved_value_id, description)
* FIELD_RESERVED_BINARY_BALUE_REG(reserved_value_id, description)
*/
-#define TYPE_RESERVED_VALUE_REG(type, id, description) {DM_REPORT_FIELD_TYPE_ ## type, &_reserved_ ## id, _reserved_ ## id ## _names, description},
+
+#define NUM DM_REPORT_FIELD_TYPE_NUMBER
+
+#define TYPE_RESERVED_VALUE_REG(type, id, description) {type, &_reserved_ ## id, _reserved_ ## id ## _names, description},
+
#define FIELD_RESERVED_VALUE_REG(id, description) {DM_REPORT_FIELD_TYPE_NONE, &_reserved_ ## id, _reserved_ ## id ## _names, description},
+
#define FIELD_RESERVED_BINARY_VALUE_REG(id, description) \
FIELD_RESERVED_VALUE_REG(id ## _y, description) \
FIELD_RESERVED_VALUE_REG(id ## _n, description)
static const struct dm_report_reserved_value _report_reserved_values[] = {
- TYPE_RESERVED_VALUE_REG(NUMBER, number_undef_64, "Reserved value for undefined numeric value.")
+ TYPE_RESERVED_VALUE_REG(NUM, number_undef_64, "Reserved value for undefined numeric value.")
FIELD_RESERVED_BINARY_VALUE_REG(pv_allocatable, "pv_allocatable reserved values")
FIELD_RESERVED_BINARY_VALUE_REG(pv_exported, "pv_exported reserved values")
FIELD_RESERVED_BINARY_VALUE_REG(pv_missing, "pv_missing reserved values")
@@ -151,6 +161,7 @@ static const struct dm_report_reserved_value _report_reserved_values[] = {
{0, NULL, NULL}
};
+#undef NUM
#undef TYPE_RESERVED_VALUE_REG
#undef FIELD_RESERVED_VALUE_REG
#undef FIELD_RESERVED_BINARY_VALUE_REG
@@ -190,9 +201,9 @@ static int _binary_undef_disp(struct dm_report *rh, struct dm_pool *mem __attrib
const struct cmd_context *cmd = (const struct cmd_context *) private;
if (cmd->report_binary_values_as_numeric)
- return _field_set_value(field, FIRST_NAME(number_undef_64), &_reserved_number_undef_64);
+ return _field_set_value(field, FIRST_NAME(number_undef_64), &RESERVED(number_undef_64));
else
- return _field_set_value(field, _str_unknown, &_reserved_number_undef_64);
+ return _field_set_value(field, _str_unknown, &RESERVED(number_undef_64));
}
static int _string_disp(struct dm_report *rh, struct dm_pool *mem __attribute__((unused)),
@@ -317,7 +328,7 @@ static int _lvkmaj_disp(struct dm_report *rh, struct dm_pool *mem __attribute__(
if (lvi->info && lvi->info->exists && lvi->info->major >= 0)
return dm_report_field_int(rh, field, &lvi->info->major);
- return dm_report_field_int32(rh, field, &_reserved_number_undef_32);
+ return dm_report_field_int32(rh, field, &RESERVED(number_undef_32));
}
static int _lvkmin_disp(struct dm_report *rh, struct dm_pool *mem __attribute__((unused)),
@@ -329,7 +340,7 @@ static int _lvkmin_disp(struct dm_report *rh, struct dm_pool *mem __attribute__(
if (lvi->info && lvi->info->exists && lvi->info->minor >= 0)
return dm_report_field_int(rh, field, &lvi->info->minor);
- return dm_report_field_int32(rh, field, &_reserved_number_undef_32);
+ return dm_report_field_int32(rh, field, &RESERVED(number_undef_32));
}
static int _lvstatus_disp(struct dm_report *rh __attribute__((unused)), struct dm_pool *mem,
@@ -654,7 +665,7 @@ static int _lvreadahead_disp(struct dm_report *rh, struct dm_pool *mem,
const struct logical_volume *lv = (const struct logical_volume *) data;
if (lv->read_ahead == DM_READ_AHEAD_AUTO)
- return _field_set_value(field, "auto", &_reserved_number_undef_64);
+ return _field_set_value(field, "auto", &RESERVED(number_undef_64));
return _size32_disp(rh, mem, field, &lv->read_ahead, private);
}
@@ -667,7 +678,7 @@ static int _lvkreadahead_disp(struct dm_report *rh, struct dm_pool *mem,
const struct lv_with_info *lvi = (const struct lv_with_info *) data;
if (!lvi->info || !lvi->info->exists)
- return dm_report_field_int32(rh, field, &_reserved_number_undef_32);
+ return dm_report_field_int32(rh, field, &RESERVED(number_undef_32));
return _size32_disp(rh, mem, field, &lvi->info->read_ahead, private);
}
@@ -755,7 +766,7 @@ static int _transactionid_disp(struct dm_report *rh, struct dm_pool *mem,
if (seg_is_thin_pool(seg))
return dm_report_field_uint64(rh, field, &seg->transaction_id);
- return _field_set_value(field, "", &_reserved_number_undef_64);
+ return _field_set_value(field, "", &RESERVED(number_undef_64));
}
static int _thinid_disp(struct dm_report *rh, struct dm_pool *mem,
@@ -767,7 +778,7 @@ static int _thinid_disp(struct dm_report *rh, struct dm_pool *mem,
if (seg_is_thin_volume(seg))
return dm_report_field_uint32(rh, field, &seg->device_id);
- return _field_set_value(field, "", &_reserved_number_undef_64);
+ return _field_set_value(field, "", &RESERVED(number_undef_64));
}
static int _discards_disp(struct dm_report *rh, struct dm_pool *mem,
@@ -933,7 +944,7 @@ static int _vgmdacopies_disp(struct dm_report *rh, struct dm_pool *mem,
uint32_t count = vg_mda_copies(vg);
if (count == VGMETADATACOPIES_UNMANAGED)
- return _field_set_value(field, "unmanaged", &_reserved_number_undef_64);
+ return _field_set_value(field, "unmanaged", &RESERVED(number_undef_64));
return _uint32_disp(rh, mem, field, &count, private);
}
@@ -1095,7 +1106,7 @@ static int _raidmismatchcount_disp(struct dm_report *rh __attribute__((unused)),
if (lv_is_raid(lv) && lv_raid_mismatch_count(lv, &mismatch_count))
return dm_report_field_uint64(rh, field, &mismatch_count);
- return _field_set_value(field, "", &_reserved_number_undef_64);
+ return _field_set_value(field, "", &RESERVED(number_undef_64));
}
static int _raidwritebehind_disp(struct dm_report *rh __attribute__((unused)),
@@ -1109,7 +1120,7 @@ static int _raidwritebehind_disp(struct dm_report *rh __attribute__((unused)),
if (lv_is_raid_type(lv) && first_seg(lv)->writebehind)
return dm_report_field_uint32(rh, field, &first_seg(lv)->writebehind);
- return _field_set_value(field, "", &_reserved_number_undef_64);
+ return _field_set_value(field, "", &RESERVED(number_undef_64));
}
static int _raidminrecoveryrate_disp(struct dm_report *rh __attribute__((unused)),
@@ -1124,7 +1135,7 @@ static int _raidminrecoveryrate_disp(struct dm_report *rh __attribute__((unused)
return dm_report_field_uint32(rh, field,
&first_seg(lv)->min_recovery_rate);
- return _field_set_value(field, "", &_reserved_number_undef_64);
+ return _field_set_value(field, "", &RESERVED(number_undef_64));
}
static int _raidmaxrecoveryrate_disp(struct dm_report *rh __attribute__((unused)),
@@ -1139,7 +1150,7 @@ static int _raidmaxrecoveryrate_disp(struct dm_report *rh __attribute__((unused)
return dm_report_field_uint32(rh, field,
&first_seg(lv)->max_recovery_rate);
- return _field_set_value(field, "", &_reserved_number_undef_64);
+ return _field_set_value(field, "", &RESERVED(number_undef_64));
}
/* Called only with lv_is_thin_pool/volume */
@@ -1192,7 +1203,7 @@ static int _metadatapercent_disp(struct dm_report *rh,
if (lv_is_thin_pool(lv))
return _dtpercent_disp(1, rh, field, data, private);
- return _field_set_value(field, "", &_reserved_number_undef_64);
+ return _field_set_value(field, "", &RESERVED(number_undef_64));
}
static int _lvmetadatasize_disp(struct dm_report *rh, struct dm_pool *mem,
@@ -1207,7 +1218,7 @@ static int _lvmetadatasize_disp(struct dm_report *rh, struct dm_pool *mem,
return _size64_disp(rh, mem, field, &size, private);
}
- return _field_set_value(field, "", &_reserved_number_undef_64);
+ return _field_set_value(field, "", &RESERVED(number_undef_64));
}
static int _thincount_disp(struct dm_report *rh, struct dm_pool *mem,
@@ -1222,7 +1233,7 @@ static int _thincount_disp(struct dm_report *rh, struct dm_pool *mem,
return _uint32_disp(rh, mem, field, &count, private);
}
- return _field_set_value(field, "", &_reserved_number_undef_64);
+ return _field_set_value(field, "", &RESERVED(number_undef_64));
}
static int _lvtime_disp(struct dm_report *rh, struct dm_pool *mem,
@@ -1518,7 +1529,7 @@ static int _lvmergefailed_disp(struct dm_report *rh, struct dm_pool *mem,
int merge_failed;
if (!lv_is_cow(lv) || !lv_snapshot_percent(lv, &snap_percent))
- return _field_set_value(field, _str_unknown, &_reserved_number_undef_64);
+ return _field_set_value(field, _str_unknown, &RESERVED(number_undef_64));
merge_failed = snap_percent == LVM_PERCENT_MERGE_FAILED;
return _binary_disp(rh, mem, field, merge_failed, FIRST_NAME(lv_merge_failed_y), private);
@@ -1533,7 +1544,7 @@ static int _lvsnapshotinvalid_disp(struct dm_report *rh, struct dm_pool *mem,
int snap_invalid;
if (!lv_is_cow(lv))
- return _field_set_value(field, _str_unknown, &_reserved_number_undef_64);
+ return _field_set_value(field, _str_unknown, &RESERVED(number_undef_64));
snap_invalid = !lv_snapshot_percent(lv, &snap_percent) || snap_percent == DM_PERCENT_INVALID;
return _binary_disp(rh, mem, field, snap_invalid, FIRST_NAME(lv_snapshot_invalid_y), private);
@@ -1619,7 +1630,7 @@ static int _thinzero_disp(struct dm_report *rh, struct dm_pool *mem,
if (seg_is_thin_pool(seg))
return _uint32_disp(rh, mem, field, &seg->zero_new_blocks, private);
- return _field_set_value(field, "", &_reserved_number_undef_64);
+ return _field_set_value(field, "", &RESERVED(number_undef_64));
}
static int _lvhealthstatus_disp(struct dm_report *rh, struct dm_pool *mem,
diff --git a/lib/report/values.h b/lib/report/values.h
index 4566057..5c4b5ab 100644
--- a/lib/report/values.h
+++ b/lib/report/values.h
@@ -19,22 +19,31 @@
* uses the exact value defined whenever the reserved name is hit, for
* example during selection criteria processing.
*
- * FIELD_RESERVED_VALUE can be used for any field.
+ * TYPE_RESERVED_VALUE defines reserved value that is not bound to any field,
+ * but rather it's bound to a certain type. This can be used as a reserved
+ * value for all fields of that type then.
*
- * FIELD_BINARY_RESERVED_VALUE is specifically designed for fields with
- * binary values where the reserved names given denote the value 1.
+ * FIELD_RESERVED_VALUE defines reserved value bound to a single field.
+ *
+ * FIELD_BINARY_RESERVED_VALUE is similar to FIELD_RESERVED_VALUE but it
+ * is specifically designed for defintion of reserved names for fields
+ * with binary values where the reserved names given denote value 1.
* The first reserved_name given is also used for reporting,
- * others are synonyms.
+ * others are synonyms which are recognized in addition.
*
*/
/*
- * FIELD_RESERVED_VALUE(field_id, reserved_value_id, reserved_name, ...)
+ * TYPE_RESERVED_VALUE(type, id, value, reserved_name, ...)
+ * FIELD_RESERVED_VALUE(field_id, reserved_value_id, value, reserved_name, ...)
* FIELD_BINARY_RESERVED_VALUE(field_id, reserved_value_id, reserved_name, ...)
*/
/* *INDENT-OFF* */
+/* Per-type reserved values usable for all fields of certain type. */
+TYPE_RESERVED_VALUE(NUM, number_undef_64, UINT64_C(-1), "-1", "unknown", "undefined", "undef");
+
/* Reserved values for PV fields */
FIELD_RESERVED_BINARY_VALUE(pv_allocatable, pv_allocatable, "allocatable")
FIELD_RESERVED_BINARY_VALUE(pv_exported, pv_exported, "exported")
@@ -47,7 +56,7 @@ FIELD_RESERVED_BINARY_VALUE(vg_partial, vg_partial, "partial")
FIELD_RESERVED_BINARY_VALUE(vg_clustered, vg_clustered, "clustered")
FIELD_RESERVED_VALUE(vg_permissions, vg_permissions_rw, FIRST_NAME(vg_permissions_rw), "writeable", "rw", "read-write")
FIELD_RESERVED_VALUE(vg_permissions, vg_permissions_r, FIRST_NAME(vg_permissions_r), "read-only", "r", "ro")
-FIELD_RESERVED_VALUE(vg_mda_copies, vg_mda_copies, _reserved_number_undef_64, "unmanaged")
+FIELD_RESERVED_VALUE(vg_mda_copies, vg_mda_copies, RESERVED(number_undef_64), "unmanaged")
/* Reserved values for LV fields */
FIELD_RESERVED_BINARY_VALUE(lv_initial_image_sync, lv_initial_image_sync, "initial image sync", "sync")
@@ -69,6 +78,6 @@ FIELD_RESERVED_BINARY_VALUE(lv_skip_activation, lv_skip_activation, "skip activa
FIELD_RESERVED_VALUE(lv_permissions, lv_permissions_rw, FIRST_NAME(lv_permissions_rw), "writeable", "rw", "read-write")
FIELD_RESERVED_VALUE(lv_permissions, lv_permissions_r, FIRST_NAME(lv_permissions_r), "read-only", "r", "ro")
FIELD_RESERVED_VALUE(lv_permissions, lv_permissions_r_override, FIRST_NAME(lv_permissions_r_override), "read-only-override", "ro-override", "r-override", "R")
-FIELD_RESERVED_VALUE(lv_read_ahead, lv_read_ahead, _reserved_number_undef_64, "auto")
+FIELD_RESERVED_VALUE(lv_read_ahead, lv_read_ahead, RESERVED(number_undef_64), "auto")
/* *INDENT-ON* */
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=fafd10d564151b91…
Commit: fafd10d564151b91e814f6be3e735bdf0b7d33dd
Parent: a4e798bd304253b91b906ca77988b11576685d72
Author: Peter Rajnoha <prajnoha(a)redhat.com>
AuthorDate: Thu Jul 10 09:48:45 2014 +0200
Committer: Peter Rajnoha <prajnoha(a)redhat.com>
CommitterDate: Thu Jul 10 09:48:45 2014 +0200
conf: command_profile_template: global/binary_values_as_numeric -> report/binary_values_as_numeric
---
conf/command_profile_template.profile.in | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/conf/command_profile_template.profile.in b/conf/command_profile_template.profile.in
index 592a69d..7401aa5 100644
--- a/conf/command_profile_template.profile.in
+++ b/conf/command_profile_template.profile.in
@@ -13,7 +13,6 @@
#
global {
units="h"
- report_binary_values_as_numeric=0
si_unit_consistency=1
suffix=1
lvdisplay_shows_full_device_path=0
@@ -26,6 +25,7 @@ report {
prefixes=0
quoted=1
colums_as_rows=0
+ binary_values_as_numeric=0
devtypes_sort="devtype_name"
devtypes_cols="devtype_name,devtype_max_partitions,devtype_description"
devtypes_cols_verbose="devtype_name,devtype_max_partitions,devtype_description"
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=a4e798bd304253b9…
Commit: a4e798bd304253b91b906ca77988b11576685d72
Parent: be75076dfc842945a03fa42073e9e03f51bd3a3c
Author: Peter Rajnoha <prajnoha(a)redhat.com>
AuthorDate: Thu Jul 10 09:22:45 2014 +0200
Committer: Peter Rajnoha <prajnoha(a)redhat.com>
CommitterDate: Thu Jul 10 09:41:21 2014 +0200
report: add values.h for per-field reserved value declaration
---
lib/report/report.c | 78 +++++++++++++++++++++------------------------------
lib/report/values.h | 74 ++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 106 insertions(+), 46 deletions(-)
diff --git a/lib/report/report.c b/lib/report/report.c
index a2f4541..d3dbefc 100644
--- a/lib/report/report.c
+++ b/lib/report/report.c
@@ -68,17 +68,6 @@ static const char const _str_unknown[] = "unknown";
*/
static const int32_t _reserved_number_undef_32 = INT32_C(-1);
-#define FIRST_NAME(id) _reserved_ ## id ## _names[0]
-#define TYPE_RESERVED_VALUE(type, id, value, ...) \
- static const char *_reserved_ ## id ## _names[] = { __VA_ARGS__, NULL}; \
- static const type _reserved_ ## id = value;
-#define FIELD_RESERVED_VALUE(field_id, id, value, ...) \
- static const char *_reserved_ ## id ## _names[] = { __VA_ARGS__ , NULL}; \
- static const struct dm_report_field_reserved_value _reserved_ ## id = {field_ ## field_id, &value};
-#define FIELD_RESERVED_BINARY_VALUE(field_id, id, ...) \
- FIELD_RESERVED_VALUE(field_id, id ## _y, _one64, __VA_ARGS__, _str_yes) \
- FIELD_RESERVED_VALUE(field_id, id ## _n, _zero64, __VA_ARGS__, _str_no)
-
/*
* Reserved values and their assigned names.
* The first name is the one that is also used for reporting.
@@ -89,51 +78,44 @@ static const int32_t _reserved_number_undef_32 = INT32_C(-1);
* FIELD_RESERVED_VALUE(field_id, reserved_value_id, value, reserved name, ...)
* FIELD_RESERVED_BINARY_VALUE(field_id, reserved_value_id, value, reserved name for 1, ...)
*
+ * Note: FIELD_RESERVED_BINARY_VALUE creates:
+ * - 'reserved_value_id_y' (for 1)
+ * - 'reserved_value_id_n' (for 0)
*/
+#define FIRST_NAME(id) _reserved_ ## id ## _names[0]
+#define TYPE_RESERVED_VALUE(type, id, value, ...) \
+ static const char *_reserved_ ## id ## _names[] = { __VA_ARGS__, NULL}; \
+ static const type _reserved_ ## id = value;
+#define FIELD_RESERVED_VALUE(field_id, id, value, ...) \
+ static const char *_reserved_ ## id ## _names[] = { __VA_ARGS__ , NULL}; \
+ static const struct dm_report_field_reserved_value _reserved_ ## id = {field_ ## field_id, &value};
+#define FIELD_RESERVED_BINARY_VALUE(field_id, id, ...) \
+ FIELD_RESERVED_VALUE(field_id, id ## _y, _one64, __VA_ARGS__, _str_yes) \
+ FIELD_RESERVED_VALUE(field_id, id ## _n, _zero64, __VA_ARGS__, _str_no)
TYPE_RESERVED_VALUE(uint64_t, number_undef_64, UINT64_C(-1), _str_minus_one, _str_unknown, "undefined", "undef");
-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(vg_extendable, vg_extendable, "extendable")
-FIELD_RESERVED_BINARY_VALUE(vg_exported, vg_exported, "exported")
-FIELD_RESERVED_BINARY_VALUE(vg_partial, vg_partial, "partial")
-FIELD_RESERVED_BINARY_VALUE(vg_clustered, vg_clustered, "clustered")
-FIELD_RESERVED_VALUE(vg_permissions, vg_permissions_rw, FIRST_NAME(vg_permissions_rw), "writeable", "rw", "read_write")
-FIELD_RESERVED_VALUE(vg_permissions, vg_permissions_r, FIRST_NAME(vg_permissions_r), "read-only", "r", "ro")
-FIELD_RESERVED_VALUE(vg_mda_copies, vg_mda_copies, _reserved_number_undef_64, "unmanaged")
-FIELD_RESERVED_BINARY_VALUE(lv_initial_image_sync, lv_initial_image_sync, "initial image sync", "sync")
-FIELD_RESERVED_BINARY_VALUE(lv_image_synced, lv_image_synced, "image synced", "synced")
-FIELD_RESERVED_BINARY_VALUE(lv_merging, lv_merging, "merging")
-FIELD_RESERVED_BINARY_VALUE(lv_converting, lv_converting, "converting")
-FIELD_RESERVED_BINARY_VALUE(lv_allocation_locked, lv_allocation_locked, "allocation locked", "locked")
-FIELD_RESERVED_BINARY_VALUE(lv_fixed_minor, lv_fixed_minor, "fixed minor", "fixed")
-FIELD_RESERVED_BINARY_VALUE(lv_active_locally, lv_active_locally, "active locally", "active", "locally")
-FIELD_RESERVED_BINARY_VALUE(lv_active_remotely, lv_active_remotely, "active remotely", "active", "remotely")
-FIELD_RESERVED_BINARY_VALUE(lv_active_exclusively, lv_active_exclusively, "active exclusively", "active", "exclusively")
-FIELD_RESERVED_BINARY_VALUE(lv_merge_failed, lv_merge_failed, "merge failed", "failed")
-FIELD_RESERVED_BINARY_VALUE(lv_snapshot_invalid, lv_snapshot_invalid, "snapsot invalid", "invalid")
-FIELD_RESERVED_BINARY_VALUE(lv_suspended, lv_suspended, "suspended")
-FIELD_RESERVED_BINARY_VALUE(lv_live_table, lv_live_table, "live table present", "live table", "live")
-FIELD_RESERVED_BINARY_VALUE(lv_inactive_table, lv_inactive_table, "inactive table present", "inactive table", "inactive")
-FIELD_RESERVED_BINARY_VALUE(lv_device_open, lv_device_open, "open")
-FIELD_RESERVED_BINARY_VALUE(lv_skip_activation, lv_skip_activation, "skip activation", "skip")
-FIELD_RESERVED_VALUE(lv_permissions, lv_permissions_rw, FIRST_NAME(lv_permissions_rw), "writeable", "rw", "read-write")
-FIELD_RESERVED_VALUE(lv_permissions, lv_permissions_r, FIRST_NAME(lv_permissions_r), "read-only", "r", "ro")
-FIELD_RESERVED_VALUE(lv_permissions, lv_permissions_r_override, FIRST_NAME(lv_permissions_r_override), "read-only-override", "ro-override", "r-override", "R")
-FIELD_RESERVED_VALUE(lv_read_ahead, lv_read_ahead, _reserved_number_undef_64, "auto")
+#include "values.h"
+#undef TYPE_RESERVED_VALUE
+#undef FIELD_RESERVED_VALUE
+#undef FIELD_RESERVED_BINARY_VALUE
+
+/*
+ * Create array of reserved values to be registered with reporting code via
+ * dm_report_init_with_selection function that initializes report with
+ * selection criteria. Selection code then recognizes these reserved values
+ * when parsing selection criteria.
+ *
+ * TYPE_RESERVED_VALUE_REG(report_type, reserved_value_id, description)
+ * FIELD_RESERVED_VALUE_REG(reserved_value_id, description)
+ * FIELD_RESERVED_BINARY_BALUE_REG(reserved_value_id, description)
+ */
#define TYPE_RESERVED_VALUE_REG(type, id, description) {DM_REPORT_FIELD_TYPE_ ## type, &_reserved_ ## id, _reserved_ ## id ## _names, description},
#define FIELD_RESERVED_VALUE_REG(id, description) {DM_REPORT_FIELD_TYPE_NONE, &_reserved_ ## id, _reserved_ ## id ## _names, description},
#define FIELD_RESERVED_BINARY_VALUE_REG(id, description) \
FIELD_RESERVED_VALUE_REG(id ## _y, description) \
FIELD_RESERVED_VALUE_REG(id ## _n, description)
-/*
- * Create array of reserved values to be passed for dm_report_init_with_selection
- * function that initializes report with selection criteria. Selection code then
- * recognizes these reserved values when parsing selection criteria.
- */
static const struct dm_report_reserved_value _report_reserved_values[] = {
TYPE_RESERVED_VALUE_REG(NUMBER, number_undef_64, "Reserved value for undefined numeric value.")
FIELD_RESERVED_BINARY_VALUE_REG(pv_allocatable, "pv_allocatable reserved values")
@@ -169,6 +151,10 @@ static const struct dm_report_reserved_value _report_reserved_values[] = {
{0, NULL, NULL}
};
+#undef TYPE_RESERVED_VALUE_REG
+#undef FIELD_RESERVED_VALUE_REG
+#undef FIELD_RESERVED_BINARY_VALUE_REG
+
static int _field_set_value(struct dm_report_field *field, const void *data, const void *sort)
{
dm_report_field_set_value(field, data, sort);
diff --git a/lib/report/values.h b/lib/report/values.h
new file mode 100644
index 0000000..4566057
--- /dev/null
+++ b/lib/report/values.h
@@ -0,0 +1,74 @@
+/*
+ * Copyright (C) 2014 Red Hat, Inc. All rights reserved.
+ *
+ * This file is part of LVM2.
+ *
+ * This copyrighted material is made available to anyone wishing to use,
+ * modify, copy, or redistribute it subject to the terms and conditions
+ * of the GNU Lesser General Public License v.2.1.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+/*
+ * This file defines reserved names for field values.
+ *
+ * This is used for registering reserved names with reporting code that
+ * uses the exact value defined whenever the reserved name is hit, for
+ * example during selection criteria processing.
+ *
+ * FIELD_RESERVED_VALUE can be used for any field.
+ *
+ * FIELD_BINARY_RESERVED_VALUE is specifically designed for fields with
+ * binary values where the reserved names given denote the value 1.
+ * The first reserved_name given is also used for reporting,
+ * others are synonyms.
+ *
+ */
+
+/*
+ * FIELD_RESERVED_VALUE(field_id, reserved_value_id, reserved_name, ...)
+ * FIELD_BINARY_RESERVED_VALUE(field_id, reserved_value_id, reserved_name, ...)
+ */
+
+/* *INDENT-OFF* */
+
+/* Reserved values for PV fields */
+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")
+
+/* Reserved values for VG fields */
+FIELD_RESERVED_BINARY_VALUE(vg_extendable, vg_extendable, "extendable")
+FIELD_RESERVED_BINARY_VALUE(vg_exported, vg_exported, "exported")
+FIELD_RESERVED_BINARY_VALUE(vg_partial, vg_partial, "partial")
+FIELD_RESERVED_BINARY_VALUE(vg_clustered, vg_clustered, "clustered")
+FIELD_RESERVED_VALUE(vg_permissions, vg_permissions_rw, FIRST_NAME(vg_permissions_rw), "writeable", "rw", "read-write")
+FIELD_RESERVED_VALUE(vg_permissions, vg_permissions_r, FIRST_NAME(vg_permissions_r), "read-only", "r", "ro")
+FIELD_RESERVED_VALUE(vg_mda_copies, vg_mda_copies, _reserved_number_undef_64, "unmanaged")
+
+/* Reserved values for LV fields */
+FIELD_RESERVED_BINARY_VALUE(lv_initial_image_sync, lv_initial_image_sync, "initial image sync", "sync")
+FIELD_RESERVED_BINARY_VALUE(lv_image_synced, lv_image_synced, "image synced", "synced")
+FIELD_RESERVED_BINARY_VALUE(lv_merging, lv_merging, "merging")
+FIELD_RESERVED_BINARY_VALUE(lv_converting, lv_converting, "converting")
+FIELD_RESERVED_BINARY_VALUE(lv_allocation_locked, lv_allocation_locked, "allocation locked", "locked")
+FIELD_RESERVED_BINARY_VALUE(lv_fixed_minor, lv_fixed_minor, "fixed minor", "fixed")
+FIELD_RESERVED_BINARY_VALUE(lv_active_locally, lv_active_locally, "active locally", "active", "locally")
+FIELD_RESERVED_BINARY_VALUE(lv_active_remotely, lv_active_remotely, "active remotely", "active", "remotely")
+FIELD_RESERVED_BINARY_VALUE(lv_active_exclusively, lv_active_exclusively, "active exclusively", "active", "exclusively")
+FIELD_RESERVED_BINARY_VALUE(lv_merge_failed, lv_merge_failed, "merge failed", "failed")
+FIELD_RESERVED_BINARY_VALUE(lv_snapshot_invalid, lv_snapshot_invalid, "snapshot invalid", "invalid")
+FIELD_RESERVED_BINARY_VALUE(lv_suspended, lv_suspended, "suspended")
+FIELD_RESERVED_BINARY_VALUE(lv_live_table, lv_live_table, "live table present", "live table", "live")
+FIELD_RESERVED_BINARY_VALUE(lv_inactive_table, lv_inactive_table, "inactive table present", "inactive table", "inactive")
+FIELD_RESERVED_BINARY_VALUE(lv_device_open, lv_device_open, "open")
+FIELD_RESERVED_BINARY_VALUE(lv_skip_activation, lv_skip_activation, "skip activation", "skip")
+FIELD_RESERVED_VALUE(lv_permissions, lv_permissions_rw, FIRST_NAME(lv_permissions_rw), "writeable", "rw", "read-write")
+FIELD_RESERVED_VALUE(lv_permissions, lv_permissions_r, FIRST_NAME(lv_permissions_r), "read-only", "r", "ro")
+FIELD_RESERVED_VALUE(lv_permissions, lv_permissions_r_override, FIRST_NAME(lv_permissions_r_override), "read-only-override", "ro-override", "r-override", "R")
+FIELD_RESERVED_VALUE(lv_read_ahead, lv_read_ahead, _reserved_number_undef_64, "auto")
+
+/* *INDENT-ON* */
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=be75076dfc842945…
Commit: be75076dfc842945a03fa42073e9e03f51bd3a3c
Parent: a098cba0ebbd0682570cff2fc756a59533321f03
Author: Jonathan Brassow <jbrassow(a)redhat.com>
AuthorDate: Wed Jul 9 22:56:11 2014 -0500
Committer: Jonathan Brassow <jbrassow(a)redhat.com>
CommitterDate: Wed Jul 9 22:56:11 2014 -0500
activation: Add "degraded" activation mode
Currently, we have two modes of activation, an unnamed nominal mode
(which I will refer to as "complete") and "partial" mode. The
"complete" mode requires that a volume group be 'complete' - that
is, no missing PVs. If there are any missing PVs, no affected LVs
are allowed to activate - even RAID LVs which might be able to
tolerate a failure. The "partial" mode allows anything to be
activated (or at least attempted). If a non-redundant LV is
missing a portion of its addressable space due to a device failure,
it will be replaced with an error target. RAID LVs will either
activate or fail to activate depending on how badly their
redundancy is compromised.
This patch adds a third option, "degraded" mode. This mode can
be selected via the '--activationmode {complete|degraded|partial}'
option to lvchange/vgchange. It can also be set in lvm.conf.
The "degraded" activation mode allows RAID LVs with a sufficient
level of redundancy to activate (e.g. a RAID5 LV with one device
failure, a RAID6 with two device failures, or RAID1 with n-1
failures). RAID LVs with too many device failures are not allowed
to activate - nor are any non-redundant LVs that may have been
affected. This patch also makes the "degraded" mode the default
activation mode.
The degraded activation mode does not yet work in a cluster. A
new cluster lock flag (LCK_DEGRADED_MODE) will need to be created
to make that work. Currently, there is limited space for this
extra flag and I am looking for possible solutions. One possible
solution is to usurp LCK_CONVERT, as it is not used. When the
locking_type is 3, the degraded mode flag simply gets dropped and
the old ("complete") behavior is exhibited.
---
WHATS_NEW | 1 +
conf/example.conf.in | 25 +++++++++
lib/activate/activate.c | 120 ++++++++++++++++++++++++++++++++++++++++-
lib/activate/dev_manager.c | 9 ++-
lib/commands/toolcontext.h | 1 +
lib/config/config_settings.h | 1 +
lib/config/defaults.h | 1 +
man/lvchange.8.in | 19 +++++++
man/vgchange.8.in | 18 ++++++
tools/args.h | 2 +
tools/commands.h | 8 ++-
tools/lvmcmdline.c | 28 +++++++++-
tools/toollib.c | 3 +-
13 files changed, 226 insertions(+), 10 deletions(-)
diff --git a/WHATS_NEW b/WHATS_NEW
index 21668f2..29a0aa3 100644
--- a/WHATS_NEW
+++ b/WHATS_NEW
@@ -1,5 +1,6 @@
Version 2.02.108 -
=================================
+ Add "degraded" activation mode and make it the default.
Add separate lv_active_{locally,remotely,exclusively} LV reporting fields.
Recognize "auto"/"unmanaged" values in selection for appropriate fields only.
Add report/binary_values_as_numeric lvm.conf option for binary values as 0/1.
diff --git a/conf/example.conf.in b/conf/example.conf.in
index e1afbb6..11f50f0 100644
--- a/conf/example.conf.in
+++ b/conf/example.conf.in
@@ -1011,6 +1011,31 @@ activation {
# are no progress reports, but the process is awoken immediately the
# operation is complete.
polling_interval = 15
+
+ # 'activation_mode' determines how logical volumes are activated if
+ # devices are missing. Possible settings are:
+ #
+ # "complete" - Only allow activation of an LV if all of the PVs
+ # that it uses are available (i.e. the volume group
+ # is complete). There may be a failed PV in the
+ # volume group; but if a particular LV is not on that
+ # PV, it is still allowed to activate in this mode.
+ #
+ # "degraded" - Like "complete", except that RAID logical volumes of
+ # segment type "raid{1,4,5,6,10}" are activated if
+ # they have sufficient redundancy to present the entire
+ # addressable range of the logical volume.
+ #
+ # "partial" - Allow activation for any logical volume - even if
+ # a missing or failed PV would cause a portion of the
+ # logical volume to be inaccessible. (E.g. a stripe
+ # volume that has lost one of its members would be
+ # unable to access a portion of the logical volume.)
+ # This setting is not recommended for normal use.
+ #
+ # This setting was introduced in LVM version 2.02.108. It corresponds
+ # with the '--activationmode' option for lvchange and vgchange.
+ activation_mode = "degraded"
}
# Report settings.
diff --git a/lib/activate/activate.c b/lib/activate/activate.c
index adaff52..70777fd 100644
--- a/lib/activate/activate.c
+++ b/lib/activate/activate.c
@@ -2203,6 +2203,111 @@ out:
return r;
}
+static int _lv_raid_is_redundant(struct logical_volume *lv)
+{
+ struct lv_segment *raid_seg = first_seg(lv);
+ uint32_t copies;
+ uint32_t i, s, rebuilds_per_group = 0;
+ uint32_t failed_components = 0;
+
+ if (!(lv->status & PARTIAL_LV)) {
+ /*
+ * Redundant, but this function shouldn't
+ * be called in this case.
+ */
+ log_error(INTERNAL_ERROR "%s is not a partial LV", lv->name);
+ return 1;
+ }
+
+ if (!lv_is_raid(lv))
+ return 0; /* Not RAID, not redundant */
+
+ if (!strcmp(raid_seg->segtype->name, "raid10")) {
+ /* FIXME: We only support 2-way mirrors in RAID10 currently */
+ copies = 2;
+ for (i = 0; i < raid_seg->area_count * copies; i++) {
+ s = i % raid_seg->area_count;
+ if (!(i % copies))
+ rebuilds_per_group = 0;
+ if ((seg_lv(raid_seg, s)->status & PARTIAL_LV) ||
+ (seg_metalv(raid_seg, s)->status & PARTIAL_LV) ||
+ lv_is_virtual(seg_lv(raid_seg, s)) ||
+ lv_is_virtual(seg_metalv(raid_seg, s)))
+ rebuilds_per_group++;
+ if (rebuilds_per_group >= copies) {
+ log_debug("An entire mirror group "
+ "has failed in %s", lv->name);
+ return 0; /* Not redundant */
+ }
+ }
+ return 1; /* Redundant */
+ }
+
+ for (s = 0; s < raid_seg->area_count; s++) {
+ if ((seg_lv(raid_seg, s)->status & PARTIAL_LV) ||
+ (seg_metalv(raid_seg, s)->status & PARTIAL_LV) ||
+ lv_is_virtual(seg_lv(raid_seg, s)) ||
+ lv_is_virtual(seg_metalv(raid_seg, s)))
+ failed_components++;
+ }
+ if (failed_components == raid_seg->area_count) {
+ log_debug("All components in %s have failed", lv->name);
+ return 0;
+ } else if (raid_seg->segtype->parity_devs &&
+ (failed_components > raid_seg->segtype->parity_devs)) {
+ log_debug("More than %u components from (%s) %s/%s have failed",
+ raid_seg->segtype->parity_devs,
+ raid_seg->segtype->ops->name(raid_seg),
+ lv->vg->name, lv->name);
+ return 0;
+ }
+
+ return 1;
+}
+
+static int _lv_is_not_degraded_capable(struct logical_volume *lv, void *data)
+{
+ int *not_capable = (int *)data;
+ uint32_t s;
+ struct lv_segment *seg;
+
+ if (!(lv->status & PARTIAL_LV))
+ return 1;
+
+ if (lv_is_raid(lv))
+ return _lv_raid_is_redundant(lv);
+
+ /* Ignore RAID sub-LVs. */
+ if (lv_is_raid_type(lv))
+ return 1;
+
+ dm_list_iterate_items(seg, &lv->segments)
+ for (s = 0; s < seg->area_count; s++)
+ if (seg_type(seg, s) != AREA_LV) {
+ log_debug("%s is not capable of degraded mode",
+ lv->name);
+ *not_capable = 1;
+ }
+
+ return 1;
+}
+
+static int lv_is_degraded_capable(struct logical_volume *lv)
+{
+ int not_capable = 0;
+
+ if (!(lv->status & PARTIAL_LV))
+ return 1;
+
+ if (!_lv_is_not_degraded_capable(lv, ¬_capable) || not_capable)
+ return 0;
+
+ if (!for_each_sub_lv(lv, _lv_is_not_degraded_capable, ¬_capable))
+ log_error(INTERNAL_ERROR "for_each_sub_lv failure.");
+
+ return !not_capable;
+}
+
static int _lv_activate(struct cmd_context *cmd, const char *lvid_s,
struct lv_activate_opts *laopts, int filter,
struct logical_volume *lv)
@@ -2225,9 +2330,18 @@ static int _lv_activate(struct cmd_context *cmd, const char *lvid_s,
}
if ((!lv->vg->cmd->partial_activation) && (lv->status & PARTIAL_LV)) {
- log_error("Refusing activation of partial LV %s. Use --partial to override.",
- lv->name);
- goto out;
+ if (!lv_is_degraded_capable(lv)) {
+ log_error("Refusing activation of partial LV %s. "
+ "Use '--activationmode partial' to override.",
+ lv->name);
+ goto out;
+ } else if (!lv->vg->cmd->degraded_activation) {
+ log_error("Refusing activation of partial LV %s. "
+ "Try '--activationmode degraded'.",
+ lv->name);
+ goto out;
+ }
+ log_print_unless_silent("Attempting activation of partial RAID LV, %s.", lv->name);
}
if (lv_has_unknown_segments(lv)) {
diff --git a/lib/activate/dev_manager.c b/lib/activate/dev_manager.c
index e30b176..0305bb4 100644
--- a/lib/activate/dev_manager.c
+++ b/lib/activate/dev_manager.c
@@ -2067,9 +2067,12 @@ int add_areas_line(struct dev_manager *dm, struct lv_segment *seg,
stat(name, &info) < 0 || !S_ISBLK(info.st_mode))) ||
(seg_type(seg, s) == AREA_LV && !seg_lv(seg, s))) {
if (!seg->lv->vg->cmd->partial_activation) {
- log_error("Aborting. LV %s is now incomplete "
- "and --partial was not specified.", seg->lv->name);
- return 0;
+ if (!seg->lv->vg->cmd->degraded_activation ||
+ !lv_is_raid_type(seg->lv)) {
+ log_error("Aborting. LV %s is now incomplete "
+ "and '--activationmode partial' was not specified.", seg->lv->name);
+ return 0;
+ }
}
if (!_add_error_area(dm, node, seg, s))
return_0;
diff --git a/lib/commands/toolcontext.h b/lib/commands/toolcontext.h
index 162af55..d06dd7d 100644
--- a/lib/commands/toolcontext.h
+++ b/lib/commands/toolcontext.h
@@ -86,6 +86,7 @@ struct cmd_context {
unsigned handles_unknown_segments:1;
unsigned use_linear_target:1;
unsigned partial_activation:1;
+ unsigned degraded_activation:1;
unsigned auto_set_activation_skip:1;
unsigned si_unit_consistency:1;
unsigned report_binary_values_as_numeric:1;
diff --git a/lib/config/config_settings.h b/lib/config/config_settings.h
index 2ddf888..7289a04 100644
--- a/lib/config/config_settings.h
+++ b/lib/config/config_settings.h
@@ -212,6 +212,7 @@ cfg(activation_use_mlockall_CFG, "use_mlockall", activation_CFG_SECTION, 0, CFG_
cfg(activation_monitoring_CFG, "monitoring", activation_CFG_SECTION, 0, CFG_TYPE_BOOL, DEFAULT_DMEVENTD_MONITOR, vsn(2, 2, 63), NULL)
cfg(activation_polling_interval_CFG, "polling_interval", activation_CFG_SECTION, 0, CFG_TYPE_INT, DEFAULT_INTERVAL, vsn(2, 2, 63), NULL)
cfg(activation_auto_set_activation_skip_CFG, "auto_set_activation_skip", activation_CFG_SECTION, 0, CFG_TYPE_BOOL, DEFAULT_AUTO_SET_ACTIVATION_SKIP, vsn(2,2,99), NULL)
+cfg(activation_mode_CFG, "activation_mode", activation_CFG_SECTION, 0, CFG_TYPE_STRING, DEFAULT_ACTIVATION_MODE, vsn(2,2,108), NULL)
cfg(metadata_pvmetadatacopies_CFG, "pvmetadatacopies", metadata_CFG_SECTION, CFG_ADVANCED, CFG_TYPE_INT, DEFAULT_PVMETADATACOPIES, vsn(1, 0, 0), NULL)
cfg(metadata_vgmetadatacopies_CFG, "vgmetadatacopies", metadata_CFG_SECTION, CFG_ADVANCED, CFG_TYPE_INT, DEFAULT_VGMETADATACOPIES, vsn(2, 2, 69), NULL)
diff --git a/lib/config/defaults.h b/lib/config/defaults.h
index 4200dc8..086f7fd 100644
--- a/lib/config/defaults.h
+++ b/lib/config/defaults.h
@@ -163,6 +163,7 @@
#define DEFAULT_PROCESS_PRIORITY -18
#define DEFAULT_AUTO_SET_ACTIVATION_SKIP 1
+#define DEFAULT_ACTIVATION_MODE "degraded"
#define DEFAULT_USE_LINEAR_TARGET 1
#define DEFAULT_STRIPE_FILLER "error"
#define DEFAULT_RAID_REGION_SIZE 512 /* KB */
diff --git a/man/lvchange.8.in b/man/lvchange.8.in
index f7aee8f..39187f0 100644
--- a/man/lvchange.8.in
+++ b/man/lvchange.8.in
@@ -9,6 +9,8 @@ lvchange \(em change attributes of a logical volume
.RI { y | n }]
.RB [ \-a | \-\-activate
.RI [ a | e | l ]{ y | n }]
+.RB [ \-\-activationmode
+.IR { complete | degraded | partial } ]
.RB [ \-k | \-\-setactivationskip { y | n } ]
.RB [ \-K | \-\-ignoreactivationskip ]
.RB [ \-\-alloc
@@ -18,6 +20,7 @@ lvchange \(em change attributes of a logical volume
.RB [ \-C | \-\-contiguous
.RI { y | n }]
.RB [ \-d | \-\-debug ]
+.RB [ \-\-degraded ]
.RB [ \-\-deltag
.IR Tag ]
.RB [ \-\-detachprofile ]
@@ -97,6 +100,22 @@ To deactivate only on the local node use -aln.
Logical volumes with single-host snapshots are always activated
exclusively because they can only be used on one node at once.
.TP
+.BR \-\-activationmode " {" \fIcomplete | \fIdegraded | \fIpartial }
+The activation mode determines whether logical volumes are allowed to
+activate when there are physical volumes missing (e.g. due to a device
+failure). \fIcomplete is the most restrictive; allowing only those
+logical volumes to be activated that are not affected by the missing
+PVs. \fIdegraded allows RAID logical volumes to be activated even if
+they have PVs missing. (Note that the "mirror" segment type is not
+considered a RAID logical volume. The "raid1" segment type should
+be used instead.) Finally, \fIpartial allows any logical volume to
+be activated even if portions are missing due to a missing or failed
+PV. This last option should only be used when performing recovery or
+repair operations. \fIdegraded is the default mode. To change it, modify
+.B activation_mode
+in
+.BR lvm.conf (5).
+.TP
.BR \-k ", " \-\-setactivationskip " {" \fIy | \fIn }
Controls whether Logical Volumes are persistently flagged to be
skipped during activation. By default, thin snapshot volumes are
diff --git a/man/vgchange.8.in b/man/vgchange.8.in
index 9ea2f65..150b77d 100644
--- a/man/vgchange.8.in
+++ b/man/vgchange.8.in
@@ -12,6 +12,8 @@ vgchange \(em change attributes of a volume group
.RB [ \-a | \-\-activate
.RI [ a | e | l ]
.RI { y | n }]
+.RB [ \-\-activationmode
+.IR { complete | degraded | partial } ]
.RB [ \-K | \-\-ignoreactivationskip ]
.RB [ \-\-monitor
.RI { y | n }]
@@ -98,6 +100,22 @@ on the local node.
Logical volumes with single-host snapshots are always activated
exclusively because they can only be used on one node at once.
.TP
+.BR \-\-activationmode " {" \fIcomplete | \fIdegraded | \fIpartial }
+The activation mode determines whether logical volumes are allowed to
+activate when there are physical volumes missing (e.g. due to a device
+failure). \fIcomplete is the most restrictive; allowing only those
+logical volumes to be activated that are not affected by the missing
+PVs. \fIdegraded allows RAID logical volumes to be activated even if
+they have PVs missing. (Note that the "mirror" segment type is not
+considered a RAID logical volume. The "raid1" segment type should
+be used instead.) Finally, \fIpartial allows any logical volume to
+be activated even if portions are missing due to a missing or failed
+PV. This last option should only be used when performing recovery or
+repair operations. \fIdegraded is the default mode. To change it, modify
+.B activation_mode
+in
+.BR lvm.conf (5).
+.TP
.BR \-K ", " \-\-ignoreactivationskip
Ignore the flag to skip Logical Volumes during activation.
.TP
diff --git a/tools/args.h b/tools/args.h
index d4a8643..9632478 100644
--- a/tools/args.h
+++ b/tools/args.h
@@ -109,6 +109,8 @@ arg(ignoreskippedcluster_ARG, '\0', "ignoreskippedcluster", NULL, 0)
arg(splitsnapshot_ARG, '\0', "splitsnapshot", NULL, 0)
arg(readonly_ARG, '\0', "readonly", NULL, 0)
arg(atomic_ARG, '\0', "atomic", NULL, 0)
+arg(activationmode_ARG, '\0', "activationmode", string_arg, 0)
+
/* Allow some variations */
arg(resizable_ARG, '\0', "resizable", yes_no_arg, 0)
diff --git a/tools/commands.h b/tools/commands.h
index 7d36bc5..5fae835 100644
--- a/tools/commands.h
+++ b/tools/commands.h
@@ -103,6 +103,7 @@ xx(lvchange,
"lvchange\n"
"\t[-A|--autobackup y|n]\n"
"\t[-a|--activate [a|e|l]{y|n}]\n"
+ "\t[--activationmode {complete|degraded|partial}"
"\t[--addtag Tag]\n"
"\t[--alloc AllocationPolicy]\n"
"\t[-C|--contiguous y|n]\n"
@@ -141,7 +142,8 @@ xx(lvchange,
"\t[-Z|--zero {y|n}]\n"
"\tLogicalVolume[Path] [LogicalVolume[Path]...]\n",
- addtag_ARG, alloc_ARG, autobackup_ARG, activate_ARG, available_ARG,
+ activationmode_ARG, addtag_ARG, alloc_ARG, autobackup_ARG, activate_ARG,
+ available_ARG,
contiguous_ARG, deltag_ARG, discards_ARG, detachprofile_ARG, force_ARG,
ignorelockingfailure_ARG, ignoremonitoring_ARG, ignoreactivationskip_ARG,
ignoreskippedcluster_ARG, major_ARG, metadataprofile_ARG, minor_ARG,
@@ -933,6 +935,7 @@ xx(vgchange,
"\t[-v|--verbose] " "\n"
"\t[--version]" "\n"
"\t{-a|--activate [a|e|l]{y|n} |" "\n"
+ "\t[--activationmode {complete|degraded|partial}]" "\n"
"\t -c|--clustered {y|n} |" "\n"
"\t -x|--resizeable {y|n} |" "\n"
"\t -l|--logicalvolume MaxLogicalVolumes |" "\n"
@@ -942,7 +945,8 @@ xx(vgchange,
"\t --deltag Tag}\n"
"\t[VolumeGroupName...]\n",
- addtag_ARG, alloc_ARG, allocation_ARG, autobackup_ARG, activate_ARG,
+ activationmode_ARG, addtag_ARG, alloc_ARG, allocation_ARG, autobackup_ARG,
+ activate_ARG,
available_ARG, clustered_ARG, deltag_ARG, detachprofile_ARG,
ignoreactivationskip_ARG, ignorelockingfailure_ARG, ignoremonitoring_ARG,
ignoreskippedcluster_ARG, logicalvolume_ARG, maxphysicalvolumes_ARG,
diff --git a/tools/lvmcmdline.c b/tools/lvmcmdline.c
index 780e9d0..fc51c4a 100644
--- a/tools/lvmcmdline.c
+++ b/tools/lvmcmdline.c
@@ -866,6 +866,8 @@ int version(struct cmd_context *cmd __attribute__((unused)),
static int _get_settings(struct cmd_context *cmd)
{
+ const char *activation_mode;
+
cmd->current_settings = cmd->default_settings;
if (arg_count(cmd, debug_ARG))
@@ -903,10 +905,34 @@ static int _get_settings(struct cmd_context *cmd)
}
cmd->partial_activation = 0;
+ cmd->degraded_activation = 0;
+ activation_mode = find_config_tree_str(cmd, activation_mode_CFG, NULL);
+ if (!activation_mode)
+ activation_mode = DEFAULT_ACTIVATION_MODE;
+
+ if (arg_count(cmd, activationmode_ARG)) {
+ activation_mode = arg_str_value(cmd, activationmode_ARG,
+ activation_mode);
+
+ /* complain only if the two arguments conflict */
+ if (arg_count(cmd, partial_ARG) &&
+ strcmp(activation_mode, "partial")) {
+ log_error("--partial and --activationmode are mutually"
+ " exclusive arguments");
+ return EINVALID_CMD_LINE;
+ }
+ } else if (arg_count(cmd, partial_ARG))
+ activation_mode = "partial";
- if (arg_count(cmd, partial_ARG)) {
+ if (!strcmp(activation_mode, "partial")) {
cmd->partial_activation = 1;
log_warn("PARTIAL MODE. Incomplete logical volumes will be processed.");
+ } else if (!strcmp(activation_mode, "degraded")) {
+ cmd->degraded_activation = 1;
+ log_debug("DEGRADED MODE. Incomplete RAID LVs will be processed.");
+ } else if (strcmp(activation_mode, "complete")) {
+ log_error("Invalid activation mode given.");
+ return EINVALID_CMD_LINE;
}
if (arg_count(cmd, ignorelockingfailure_ARG) || arg_count(cmd, sysinit_ARG))
diff --git a/tools/toollib.c b/tools/toollib.c
index d4c915d..34db90c 100644
--- a/tools/toollib.c
+++ b/tools/toollib.c
@@ -1431,7 +1431,8 @@ int lv_change_activate(struct cmd_context *cmd, struct logical_volume *lv,
int lv_refresh(struct cmd_context *cmd, struct logical_volume *lv)
{
if (!cmd->partial_activation && (lv->status & PARTIAL_LV)) {
- log_error("Refusing refresh of partial LV %s. Use --partial to override.",
+ log_error("Refusing refresh of partial LV %s."
+ " Use '--activationmode partial' to override.",
lv->name);
return 0;
}
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=a098cba0ebbd0682…
Commit: a098cba0ebbd0682570cff2fc756a59533321f03
Parent: 46ea315f09306836cc10826b0e94da4685351d1c
Author: Alasdair G Kergon <agk(a)redhat.com>
AuthorDate: Wed Jul 9 23:33:09 2014 +0100
Committer: Alasdair G Kergon <agk(a)redhat.com>
CommitterDate: Wed Jul 9 23:33:09 2014 +0100
report: Rename common fields to special fields.
Change the help heading from 'Common Fields' to 'Special Fields' for
the fields: selected, help, ?
Remove the code that does 'all' processing with these special fields as
each of them changes the behaviour of the command in an undesirable way.
'lvs -o all,selected' was of course just printing help.
(via internal expansion to 'lv_all,common_all')
and if we ignored the help fields, then '-o common_all' would still
pull in 'selected' and change the way rows were output.
---
libdm/libdm-report.c | 52 ++++++++++++++++++++++---------------------------
1 files changed, 23 insertions(+), 29 deletions(-)
diff --git a/libdm/libdm-report.c b/libdm/libdm-report.c
index ad89cf2..9b4ea87 100644
--- a/libdm/libdm-report.c
+++ b/libdm/libdm-report.c
@@ -193,10 +193,10 @@ struct row {
/*
* Implicit report types and fields.
*/
-#define COMMON_REPORT_TYPE 0x80000000
-#define COMMON_FIELD_SELECTED_ID "selected"
-#define COMMON_FIELD_HELP_ID "help"
-#define COMMON_FIELD_HELP_ALT_ID "?"
+#define SPECIAL_REPORT_TYPE 0x80000000
+#define SPECIAL_FIELD_SELECTED_ID "selected"
+#define SPECIAL_FIELD_HELP_ID "help"
+#define SPECIAL_FIELD_HELP_ALT_ID "?"
static void *_null_returning_fn(void *obj __attribute__((unused)))
{
@@ -222,26 +222,26 @@ static int _selected_disp(struct dm_report *rh,
return dm_report_field_int(rh, field, &row->selected);
}
-static const struct dm_report_object_type _implicit_common_report_types[] = {
- { COMMON_REPORT_TYPE, "Common", "common_", _null_returning_fn },
+static const struct dm_report_object_type _implicit_special_report_types[] = {
+ { SPECIAL_REPORT_TYPE, "Special", "special_", _null_returning_fn },
{ 0, "", "", NULL }
};
-static const struct dm_report_field_type _implicit_common_report_fields[] = {
- { COMMON_REPORT_TYPE, DM_REPORT_FIELD_TYPE_NUMBER | FLD_CMP_UNCOMPARABLE, 0, 8, COMMON_FIELD_HELP_ID, "Help", _no_report_fn, "Show help." },
- { COMMON_REPORT_TYPE, DM_REPORT_FIELD_TYPE_NUMBER | FLD_CMP_UNCOMPARABLE, 0, 8, COMMON_FIELD_HELP_ALT_ID, "Help", _no_report_fn, "Show help." },
+static const struct dm_report_field_type _implicit_special_report_fields[] = {
+ { SPECIAL_REPORT_TYPE, DM_REPORT_FIELD_TYPE_NUMBER | FLD_CMP_UNCOMPARABLE , 0, 8, SPECIAL_FIELD_HELP_ID, "Help", _no_report_fn, "Show help." },
+ { SPECIAL_REPORT_TYPE, DM_REPORT_FIELD_TYPE_NUMBER | FLD_CMP_UNCOMPARABLE , 0, 8, SPECIAL_FIELD_HELP_ALT_ID, "Help", _no_report_fn, "Show help." },
{ 0, 0, 0, 0, "", "", 0, 0}
};
-static const struct dm_report_field_type _implicit_common_report_fields_with_selection[] = {
- { COMMON_REPORT_TYPE, DM_REPORT_FIELD_TYPE_NUMBER, 0, 8, COMMON_FIELD_SELECTED_ID, "Selected", _selected_disp, "Item passes selection criteria." },
- { COMMON_REPORT_TYPE, DM_REPORT_FIELD_TYPE_NUMBER | FLD_CMP_UNCOMPARABLE, 0, 8, COMMON_FIELD_HELP_ID, "Help", _no_report_fn, "Show help." },
- { COMMON_REPORT_TYPE, DM_REPORT_FIELD_TYPE_NUMBER | FLD_CMP_UNCOMPARABLE, 0, 8, COMMON_FIELD_HELP_ALT_ID, "Help", _no_report_fn, "Show help." },
+static const struct dm_report_field_type _implicit_special_report_fields_with_selection[] = {
+ { SPECIAL_REPORT_TYPE, DM_REPORT_FIELD_TYPE_NUMBER, 0, 8, SPECIAL_FIELD_SELECTED_ID, "Selected", _selected_disp, "Set if item passes selection criteria." },
+ { SPECIAL_REPORT_TYPE, DM_REPORT_FIELD_TYPE_NUMBER | FLD_CMP_UNCOMPARABLE , 0, 8, SPECIAL_FIELD_HELP_ID, "Help", _no_report_fn, "Show help." },
+ { SPECIAL_REPORT_TYPE, DM_REPORT_FIELD_TYPE_NUMBER | FLD_CMP_UNCOMPARABLE , 0, 8, SPECIAL_FIELD_HELP_ALT_ID, "Help", _no_report_fn, "Show help." },
{ 0, 0, 0, 0, "", "", 0, 0}
};
-static const struct dm_report_object_type *_implicit_report_types = _implicit_common_report_types;
-static const struct dm_report_field_type *_implicit_report_fields = _implicit_common_report_fields;
+static const struct dm_report_object_type *_implicit_report_types = _implicit_special_report_types;
+static const struct dm_report_field_type *_implicit_report_fields = _implicit_special_report_fields;
static const struct dm_report_object_type *_find_type(struct dm_report *rh,
uint32_t report_type)
@@ -626,11 +626,10 @@ static void _display_fields_more(struct dm_report *rh,
log_warn("%*.*s", (int) strlen(desc) + 7,
(int) strlen(desc) + 7,
"-------------------------------------------------------------------------------");
- if (display_all_fields_item) {
+ if (display_all_fields_item && type->id != SPECIAL_REPORT_TYPE)
log_warn(" %sall%-*s - %s", type->prefix,
(int) (id_len - 3 - strlen(type->prefix)), "",
"All fields in this section.");
- }
}
/* FIXME Add line-wrapping at terminal width (or 80 cols) */
log_warn(" %-*s - %s%s%s%s%s", (int) id_len, fields[f].id, fields[f].desc,
@@ -783,7 +782,6 @@ static uint32_t _all_match(struct dm_report *rh, const char *field, size_t flen)
}
/* Combine all report types that have a matching prefix. */
- _all_match_combine(_implicit_report_types, unprefixed_all_matched, field, flen, &report_types);
_all_match_combine(rh->types, unprefixed_all_matched, field, flen, &report_types);
return report_types;
@@ -796,10 +794,6 @@ static int _add_all_fields(struct dm_report *rh, uint32_t type)
{
uint32_t f;
- for (f = 0; _implicit_report_fields[f].report_fn; f++)
- if ((_implicit_report_fields[f].type & type) && !_add_field(rh, f, 1, 0))
- return 0;
-
for (f = 0; rh->fields[f].report_fn; f++)
if ((rh->fields[f].type & type) && !_add_field(rh, f, 0, 0))
return 0;
@@ -1030,8 +1024,8 @@ static int _help_requested(struct dm_report *rh)
dm_list_iterate_items(fp, &rh->field_props) {
if (fp->implicit &&
- (!strcmp(_implicit_report_fields[fp->field_num].id, COMMON_FIELD_HELP_ID) ||
- !strcmp(_implicit_report_fields[fp->field_num].id, COMMON_FIELD_HELP_ALT_ID)))
+ (!strcmp(_implicit_report_fields[fp->field_num].id, SPECIAL_FIELD_HELP_ID) ||
+ !strcmp(_implicit_report_fields[fp->field_num].id, SPECIAL_FIELD_HELP_ALT_ID)))
return 1;
}
@@ -1181,7 +1175,7 @@ static void *_report_get_field_data(struct dm_report *rh,
static void *_report_get_implicit_field_data(struct dm_report *rh __attribute__((unused)),
struct field_properties *fp, struct row *row)
{
- if (!strcmp(_implicit_report_fields[fp->field_num].id, COMMON_FIELD_SELECTED_ID))
+ if (!strcmp(_implicit_report_fields[fp->field_num].id, SPECIAL_FIELD_SELECTED_ID))
return row;
return NULL;
@@ -1468,7 +1462,7 @@ int dm_report_object(struct dm_report *rh, void *object)
if (fp->implicit) {
fields = _implicit_report_fields;
- if (!strcmp(fields[fp->field_num].id, COMMON_FIELD_SELECTED_ID))
+ if (!strcmp(fields[fp->field_num].id, SPECIAL_FIELD_SELECTED_ID))
field_sel_status = field;
} else
fields = rh->fields;
@@ -2700,7 +2694,7 @@ struct dm_report *dm_report_init_with_selection(uint32_t *report_types,
struct selection_node *root = NULL;
const char *fin, *next;
- _implicit_report_fields = _implicit_common_report_fields_with_selection;
+ _implicit_report_fields = _implicit_special_report_fields_with_selection;
if (!(rh = dm_report_init(report_types, types, fields, output_fields,
output_separator, output_flags, sort_keys, private_data)))
@@ -2719,8 +2713,8 @@ struct dm_report *dm_report_init_with_selection(uint32_t *report_types,
}
rh->reserved_values = reserved_values;
- if (!strcasecmp(selection, COMMON_FIELD_HELP_ID) ||
- !strcmp(selection, COMMON_FIELD_HELP_ALT_ID)) {
+ if (!strcasecmp(selection, SPECIAL_FIELD_HELP_ID) ||
+ !strcmp(selection, SPECIAL_FIELD_HELP_ALT_ID)) {
_display_fields(rh, 0, 1);
log_warn(" ");
_display_selection_help(rh);
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=46ea315f09306836…
Commit: 46ea315f09306836cc10826b0e94da4685351d1c
Parent: c1bed36b670660527caf70182c39080764df71d0
Author: Peter Rajnoha <prajnoha(a)redhat.com>
AuthorDate: Wed Jul 9 15:10:43 2014 +0200
Committer: Peter Rajnoha <prajnoha(a)redhat.com>
CommitterDate: Wed Jul 9 15:57:05 2014 +0200
report: also recognize 'yes'/'no' for selection criteria on binary fields
We have 1/"descriptive word"/"yes" for 1 and 0/"no" for 0.
For example (the new recognized values are "yes" and "no"):
$ lvs -o name,device_open fedora vg/lvol1 vg/lvol2
LV DevOpen
root open
swap open
lvol1 open
lvol2
$ lvs -o name,device_open fedora vg/lvol1 vg/lvol2 -S 'device_open=open'
LV DevOpen
root open
swap open
lvol1 open
$ lvs -o name,device_open fedora vg/lvol1 vg/lvol2 -S 'device_open=1'
LV DevOpen
root open
swap open
lvol1 open
$ lvs -o name,device_open fedora vg/lvol1 vg/lvol2 -S 'device_open=yes'
LV DevOpen
root open
swap open
lvol1 open
$ lvs -o name,device_open fedora vg/lvol1 vg/lvol2 -S 'device_open=0'
LV DevOpen
lvol2
$ lvs -o name,device_open fedora vg/lvol1 vg/lvol2 -S 'device_open=no'
LV DevOpen
lvol2
---
lib/report/report.c | 144 +++++++++++++++++++++++++++------------------------
1 files changed, 77 insertions(+), 67 deletions(-)
diff --git a/lib/report/report.c b/lib/report/report.c
index 198fdfa..a2f4541 100644
--- a/lib/report/report.c
+++ b/lib/report/report.c
@@ -56,6 +56,8 @@ static const uint64_t _zero64 = UINT64_C(0);
static const uint64_t _one64 = UINT64_C(1);
static const char const _str_zero[] = "0";
static const char const _str_one[] = "1";
+static const char const _str_no[] = "no";
+static const char const _str_yes[] = "yes";
static const char const _str_minus_one[] = "-1";
static const char const _str_unknown[] = "unknown";
@@ -73,6 +75,9 @@ static const int32_t _reserved_number_undef_32 = INT32_C(-1);
#define FIELD_RESERVED_VALUE(field_id, id, value, ...) \
static const char *_reserved_ ## id ## _names[] = { __VA_ARGS__ , NULL}; \
static const struct dm_report_field_reserved_value _reserved_ ## id = {field_ ## field_id, &value};
+#define FIELD_RESERVED_BINARY_VALUE(field_id, id, ...) \
+ FIELD_RESERVED_VALUE(field_id, id ## _y, _one64, __VA_ARGS__, _str_yes) \
+ FIELD_RESERVED_VALUE(field_id, id ## _n, _zero64, __VA_ARGS__, _str_no)
/*
* Reserved values and their assigned names.
@@ -82,35 +87,37 @@ static const int32_t _reserved_number_undef_32 = INT32_C(-1);
*
* TYPE_RESERVED_VALUE(type, reserved_value_id, value, reserved name, ...)
* FIELD_RESERVED_VALUE(field_id, reserved_value_id, value, reserved name, ...)
+ * FIELD_RESERVED_BINARY_VALUE(field_id, reserved_value_id, value, reserved name for 1, ...)
*
*/
+
TYPE_RESERVED_VALUE(uint64_t, number_undef_64, UINT64_C(-1), _str_minus_one, _str_unknown, "undefined", "undef");
-FIELD_RESERVED_VALUE(pv_allocatable, pv_allocatable, _one64, "allocatable")
-FIELD_RESERVED_VALUE(pv_exported, pv_exported, _one64, "exported")
-FIELD_RESERVED_VALUE(pv_missing, pv_missing, _one64, "missing")
-FIELD_RESERVED_VALUE(vg_extendable, vg_extendable, _one64, "extendable")
-FIELD_RESERVED_VALUE(vg_exported, vg_exported, _one64, "exported")
-FIELD_RESERVED_VALUE(vg_partial, vg_partial, _one64, "partial")
-FIELD_RESERVED_VALUE(vg_clustered, vg_clustered, _one64, "clustered")
+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(vg_extendable, vg_extendable, "extendable")
+FIELD_RESERVED_BINARY_VALUE(vg_exported, vg_exported, "exported")
+FIELD_RESERVED_BINARY_VALUE(vg_partial, vg_partial, "partial")
+FIELD_RESERVED_BINARY_VALUE(vg_clustered, vg_clustered, "clustered")
FIELD_RESERVED_VALUE(vg_permissions, vg_permissions_rw, FIRST_NAME(vg_permissions_rw), "writeable", "rw", "read_write")
FIELD_RESERVED_VALUE(vg_permissions, vg_permissions_r, FIRST_NAME(vg_permissions_r), "read-only", "r", "ro")
FIELD_RESERVED_VALUE(vg_mda_copies, vg_mda_copies, _reserved_number_undef_64, "unmanaged")
-FIELD_RESERVED_VALUE(lv_initial_image_sync, lv_initial_image_sync, _one64, "initial image sync", "sync")
-FIELD_RESERVED_VALUE(lv_image_synced, lv_image_synced, _one64, "image synced", "synced")
-FIELD_RESERVED_VALUE(lv_merging, lv_merging, _one64, "merging")
-FIELD_RESERVED_VALUE(lv_converting, lv_converting, _one64, "converting")
-FIELD_RESERVED_VALUE(lv_allocation_locked, lv_allocation_locked, _one64, "allocation locked", "locked")
-FIELD_RESERVED_VALUE(lv_fixed_minor, lv_fixed_minor, _one64, "fixed minor", "fixed")
-FIELD_RESERVED_VALUE(lv_active_locally, lv_active_locally, _one64, "active locally", "active", "locally")
-FIELD_RESERVED_VALUE(lv_active_remotely, lv_active_remotely, _one64, "active remotely", "active", "remotely")
-FIELD_RESERVED_VALUE(lv_active_exclusively, lv_active_exclusively, _one64, "active exclusively", "active", "exclusively")
-FIELD_RESERVED_VALUE(lv_merge_failed, lv_merge_failed, _one64, "merge failed", "failed")
-FIELD_RESERVED_VALUE(lv_snapshot_invalid, lv_snapshot_invalid, _one64, "snapsot invalid", "invalid")
-FIELD_RESERVED_VALUE(lv_suspended, lv_suspended, _one64, "suspended")
-FIELD_RESERVED_VALUE(lv_live_table, lv_live_table, _one64, "live table present", "live table", "live")
-FIELD_RESERVED_VALUE(lv_inactive_table, lv_inactive_table, _one64, "inactive table present", "inactive table", "inactive")
-FIELD_RESERVED_VALUE(lv_device_open, lv_device_open, _one64, "open")
-FIELD_RESERVED_VALUE(lv_skip_activation, lv_skip_activation, _one64, "skip activation", "skip")
+FIELD_RESERVED_BINARY_VALUE(lv_initial_image_sync, lv_initial_image_sync, "initial image sync", "sync")
+FIELD_RESERVED_BINARY_VALUE(lv_image_synced, lv_image_synced, "image synced", "synced")
+FIELD_RESERVED_BINARY_VALUE(lv_merging, lv_merging, "merging")
+FIELD_RESERVED_BINARY_VALUE(lv_converting, lv_converting, "converting")
+FIELD_RESERVED_BINARY_VALUE(lv_allocation_locked, lv_allocation_locked, "allocation locked", "locked")
+FIELD_RESERVED_BINARY_VALUE(lv_fixed_minor, lv_fixed_minor, "fixed minor", "fixed")
+FIELD_RESERVED_BINARY_VALUE(lv_active_locally, lv_active_locally, "active locally", "active", "locally")
+FIELD_RESERVED_BINARY_VALUE(lv_active_remotely, lv_active_remotely, "active remotely", "active", "remotely")
+FIELD_RESERVED_BINARY_VALUE(lv_active_exclusively, lv_active_exclusively, "active exclusively", "active", "exclusively")
+FIELD_RESERVED_BINARY_VALUE(lv_merge_failed, lv_merge_failed, "merge failed", "failed")
+FIELD_RESERVED_BINARY_VALUE(lv_snapshot_invalid, lv_snapshot_invalid, "snapsot invalid", "invalid")
+FIELD_RESERVED_BINARY_VALUE(lv_suspended, lv_suspended, "suspended")
+FIELD_RESERVED_BINARY_VALUE(lv_live_table, lv_live_table, "live table present", "live table", "live")
+FIELD_RESERVED_BINARY_VALUE(lv_inactive_table, lv_inactive_table, "inactive table present", "inactive table", "inactive")
+FIELD_RESERVED_BINARY_VALUE(lv_device_open, lv_device_open, "open")
+FIELD_RESERVED_BINARY_VALUE(lv_skip_activation, lv_skip_activation, "skip activation", "skip")
FIELD_RESERVED_VALUE(lv_permissions, lv_permissions_rw, FIRST_NAME(lv_permissions_rw), "writeable", "rw", "read-write")
FIELD_RESERVED_VALUE(lv_permissions, lv_permissions_r, FIRST_NAME(lv_permissions_r), "read-only", "r", "ro")
FIELD_RESERVED_VALUE(lv_permissions, lv_permissions_r_override, FIRST_NAME(lv_permissions_r_override), "read-only-override", "ro-override", "r-override", "R")
@@ -118,6 +125,9 @@ FIELD_RESERVED_VALUE(lv_read_ahead, lv_read_ahead, _reserved_number_undef_64, "a
#define TYPE_RESERVED_VALUE_REG(type, id, description) {DM_REPORT_FIELD_TYPE_ ## type, &_reserved_ ## id, _reserved_ ## id ## _names, description},
#define FIELD_RESERVED_VALUE_REG(id, description) {DM_REPORT_FIELD_TYPE_NONE, &_reserved_ ## id, _reserved_ ## id ## _names, description},
+#define FIELD_RESERVED_BINARY_VALUE_REG(id, description) \
+ FIELD_RESERVED_VALUE_REG(id ## _y, description) \
+ FIELD_RESERVED_VALUE_REG(id ## _n, description)
/*
* Create array of reserved values to be passed for dm_report_init_with_selection
@@ -126,32 +136,32 @@ FIELD_RESERVED_VALUE(lv_read_ahead, lv_read_ahead, _reserved_number_undef_64, "a
*/
static const struct dm_report_reserved_value _report_reserved_values[] = {
TYPE_RESERVED_VALUE_REG(NUMBER, number_undef_64, "Reserved value for undefined numeric value.")
- FIELD_RESERVED_VALUE_REG(pv_allocatable, "pv_allocatable reserved values")
- FIELD_RESERVED_VALUE_REG(pv_exported, "pv_exported reserved values")
- FIELD_RESERVED_VALUE_REG(pv_missing, "pv_missing reserved values")
- FIELD_RESERVED_VALUE_REG(vg_extendable, "vg_extendable reserved values")
- FIELD_RESERVED_VALUE_REG(vg_exported, "vg_exported reserved values")
- FIELD_RESERVED_VALUE_REG(vg_partial, "vg_partial reserved values")
- FIELD_RESERVED_VALUE_REG(vg_clustered, "vg_clustered reserved values")
+ FIELD_RESERVED_BINARY_VALUE_REG(pv_allocatable, "pv_allocatable reserved values")
+ FIELD_RESERVED_BINARY_VALUE_REG(pv_exported, "pv_exported reserved values")
+ FIELD_RESERVED_BINARY_VALUE_REG(pv_missing, "pv_missing reserved values")
+ FIELD_RESERVED_BINARY_VALUE_REG(vg_extendable, "vg_extendable reserved values")
+ FIELD_RESERVED_BINARY_VALUE_REG(vg_exported, "vg_exported reserved values")
+ FIELD_RESERVED_BINARY_VALUE_REG(vg_partial, "vg_partial reserved values")
+ FIELD_RESERVED_BINARY_VALUE_REG(vg_clustered, "vg_clustered reserved values")
FIELD_RESERVED_VALUE_REG(vg_permissions_rw, "vg_permissions reserved values (writeable)")
FIELD_RESERVED_VALUE_REG(vg_permissions_r, "vg_permissions reserved values (read-only)")
FIELD_RESERVED_VALUE_REG(vg_mda_copies, "vg_mda_copies reserved values (unmanaged)")
- FIELD_RESERVED_VALUE_REG(lv_initial_image_sync, "lv_initial_image_sync reserved values")
- FIELD_RESERVED_VALUE_REG(lv_image_synced, "lv_image_synced reserved values")
- FIELD_RESERVED_VALUE_REG(lv_merging, "lv_merging reserved values")
- FIELD_RESERVED_VALUE_REG(lv_converting, "lv_converting reserved values")
- FIELD_RESERVED_VALUE_REG(lv_allocation_locked, "lv_allocation_locked reserved values")
- FIELD_RESERVED_VALUE_REG(lv_fixed_minor, "lv_fixed_minor reserved values")
- FIELD_RESERVED_VALUE_REG(lv_active_locally, "lv_active_locally reserved values")
- FIELD_RESERVED_VALUE_REG(lv_active_remotely, "lv_active_remotelly reserved values")
- FIELD_RESERVED_VALUE_REG(lv_active_exclusively, "lv_active_exclusively reserved values")
- FIELD_RESERVED_VALUE_REG(lv_merge_failed, "lv_merge_failed reserved values")
- FIELD_RESERVED_VALUE_REG(lv_snapshot_invalid, "lv_snapshot_invalid reserved values")
- FIELD_RESERVED_VALUE_REG(lv_suspended, "lv_suspended reserved values")
- FIELD_RESERVED_VALUE_REG(lv_live_table, "lv_live_table reserved values")
- FIELD_RESERVED_VALUE_REG(lv_inactive_table, "lv_inactive_table reserved values")
- FIELD_RESERVED_VALUE_REG(lv_device_open, "lv_device_open reserved values")
- FIELD_RESERVED_VALUE_REG(lv_skip_activation, "lv_inactive_table reserved values")
+ FIELD_RESERVED_BINARY_VALUE_REG(lv_initial_image_sync, "lv_initial_image_sync reserved values")
+ FIELD_RESERVED_BINARY_VALUE_REG(lv_image_synced, "lv_image_synced reserved values")
+ FIELD_RESERVED_BINARY_VALUE_REG(lv_merging, "lv_merging reserved values")
+ FIELD_RESERVED_BINARY_VALUE_REG(lv_converting, "lv_converting reserved values")
+ FIELD_RESERVED_BINARY_VALUE_REG(lv_allocation_locked, "lv_allocation_locked reserved values")
+ FIELD_RESERVED_BINARY_VALUE_REG(lv_fixed_minor, "lv_fixed_minor reserved values")
+ FIELD_RESERVED_BINARY_VALUE_REG(lv_active_locally, "lv_active_locally reserved values")
+ FIELD_RESERVED_BINARY_VALUE_REG(lv_active_remotely, "lv_active_remotelly reserved values")
+ FIELD_RESERVED_BINARY_VALUE_REG(lv_active_exclusively, "lv_active_exclusively reserved values")
+ FIELD_RESERVED_BINARY_VALUE_REG(lv_merge_failed, "lv_merge_failed reserved values")
+ FIELD_RESERVED_BINARY_VALUE_REG(lv_snapshot_invalid, "lv_snapshot_invalid reserved values")
+ FIELD_RESERVED_BINARY_VALUE_REG(lv_suspended, "lv_suspended reserved values")
+ FIELD_RESERVED_BINARY_VALUE_REG(lv_live_table, "lv_live_table reserved values")
+ FIELD_RESERVED_BINARY_VALUE_REG(lv_inactive_table, "lv_inactive_table reserved values")
+ FIELD_RESERVED_BINARY_VALUE_REG(lv_device_open, "lv_device_open reserved values")
+ FIELD_RESERVED_BINARY_VALUE_REG(lv_skip_activation, "lv_inactive_table reserved values")
FIELD_RESERVED_VALUE_REG(lv_permissions_rw, "lv_permissions reserved values (writeable)")
FIELD_RESERVED_VALUE_REG(lv_permissions_r, "lv_permissions reserved values (read-only)")
FIELD_RESERVED_VALUE_REG(lv_permissions_r_override, "lv_permissions reserved values (read-only-override)")
@@ -1270,7 +1280,7 @@ static int _pvallocatable_disp(struct dm_report *rh, struct dm_pool *mem,
const void *data, void *private)
{
int allocatable = (((const struct physical_volume *) data)->status & ALLOCATABLE_PV) != 0;
- return _binary_disp(rh, mem, field, allocatable, FIRST_NAME(pv_allocatable), private);
+ return _binary_disp(rh, mem, field, allocatable, FIRST_NAME(pv_allocatable_y), private);
}
static int _pvexported_disp(struct dm_report *rh, struct dm_pool *mem,
@@ -1278,7 +1288,7 @@ static int _pvexported_disp(struct dm_report *rh, struct dm_pool *mem,
const void *data, void *private)
{
int exported = (((const struct physical_volume *) data)->status & EXPORTED_VG) != 0;
- return _binary_disp(rh, mem, field, exported, FIRST_NAME(pv_exported), private);
+ return _binary_disp(rh, mem, field, exported, FIRST_NAME(pv_exported_y), private);
}
static int _pvmissing_disp(struct dm_report *rh, struct dm_pool *mem,
@@ -1286,7 +1296,7 @@ static int _pvmissing_disp(struct dm_report *rh, struct dm_pool *mem,
const void *data, void *private)
{
int missing = (((const struct physical_volume *) data)->status & MISSING_PV) != 0;
- return _binary_disp(rh, mem, field, missing, FIRST_NAME(pv_missing), private);
+ return _binary_disp(rh, mem, field, missing, FIRST_NAME(pv_missing_y), private);
}
static int _vgpermissions_disp(struct dm_report *rh, struct dm_pool *mem,
@@ -1303,7 +1313,7 @@ static int _vgextendable_disp(struct dm_report *rh, struct dm_pool *mem,
const void *data, void *private)
{
int extendable = (vg_is_resizeable((const struct volume_group *) data)) != 0;
- return _binary_disp(rh, mem, field, extendable, FIRST_NAME(vg_extendable), private);
+ return _binary_disp(rh, mem, field, extendable, FIRST_NAME(vg_extendable_y),private);
}
static int _vgexported_disp(struct dm_report *rh, struct dm_pool *mem,
@@ -1311,7 +1321,7 @@ static int _vgexported_disp(struct dm_report *rh, struct dm_pool *mem,
const void *data, void *private)
{
int exported = (vg_is_exported((const struct volume_group *) data)) != 0;
- return _binary_disp(rh, mem, field, exported, FIRST_NAME(vg_exported), private);
+ return _binary_disp(rh, mem, field, exported, FIRST_NAME(vg_exported_y), private);
}
static int _vgpartial_disp(struct dm_report *rh, struct dm_pool *mem,
@@ -1319,7 +1329,7 @@ static int _vgpartial_disp(struct dm_report *rh, struct dm_pool *mem,
const void *data, void *private)
{
int partial = (vg_missing_pv_count((const struct volume_group *) data)) != 0;
- return _binary_disp(rh, mem, field, partial, FIRST_NAME(vg_partial), private);
+ return _binary_disp(rh, mem, field, partial, FIRST_NAME(vg_partial_y), private);
}
static int _vgallocationpolicy_disp(struct dm_report *rh, struct dm_pool *mem,
@@ -1335,7 +1345,7 @@ static int _vgclustered_disp(struct dm_report *rh, struct dm_pool *mem,
const void *data, void *private)
{
int clustered = (vg_is_clustered((const struct volume_group *) data)) != 0;
- return _binary_disp(rh, mem, field, clustered, FIRST_NAME(vg_clustered), private);
+ return _binary_disp(rh, mem, field, clustered, FIRST_NAME(vg_clustered_y), private);
}
static int _lvvolumetype_disp(struct dm_report *rh, struct dm_pool *mem,
@@ -1358,7 +1368,7 @@ static int _lvinitialimagesync_disp(struct dm_report *rh, struct dm_pool *mem,
else
initial_image_sync = 0;
- return _binary_disp(rh, mem, field, initial_image_sync, FIRST_NAME(lv_initial_image_sync), private);
+ return _binary_disp(rh, mem, field, initial_image_sync, FIRST_NAME(lv_initial_image_sync_y), private);
}
static int _lvimagesynced_disp(struct dm_report *rh, struct dm_pool *mem,
@@ -1375,7 +1385,7 @@ static int _lvimagesynced_disp(struct dm_report *rh, struct dm_pool *mem,
else
image_synced = 0;
- return _binary_disp(rh, mem, field, image_synced, FIRST_NAME(lv_image_synced), private);
+ return _binary_disp(rh, mem, field, image_synced, FIRST_NAME(lv_image_synced_y), private);
}
static int _lvmerging_disp(struct dm_report *rh, struct dm_pool *mem,
@@ -1394,7 +1404,7 @@ static int _lvmerging_disp(struct dm_report *rh, struct dm_pool *mem,
else
merging = 0;
- return _binary_disp(rh, mem, field, merging, FIRST_NAME(lv_merging), private);
+ return _binary_disp(rh, mem, field, merging, FIRST_NAME(lv_merging_y), private);
}
static int _lvconverting_disp(struct dm_report *rh, struct dm_pool *mem,
@@ -1440,7 +1450,7 @@ static int _lvallocationlocked_disp(struct dm_report *rh, struct dm_pool *mem,
const void *data, void *private)
{
int alloc_locked = (((const struct logical_volume *) data)->status & LOCKED) != 0;
- return _binary_disp(rh, mem, field, alloc_locked, FIRST_NAME(lv_allocation_locked), private);
+ return _binary_disp(rh, mem, field, alloc_locked, FIRST_NAME(lv_allocation_locked_y), private);
}
static int _lvfixedminor_disp(struct dm_report *rh, struct dm_pool *mem,
@@ -1448,7 +1458,7 @@ static int _lvfixedminor_disp(struct dm_report *rh, struct dm_pool *mem,
const void *data, void *private)
{
int fixed_minor = (((const struct logical_volume *) data)->status & FIXED_MINOR) != 0;
- return _binary_disp(rh, mem, field, fixed_minor, FIRST_NAME(lv_fixed_minor), private);
+ return _binary_disp(rh, mem, field, fixed_minor, FIRST_NAME(lv_fixed_minor_y), private);
}
static int _lvactive_disp(struct dm_report *rh, struct dm_pool *mem,
@@ -1478,7 +1488,7 @@ static int _lvactivelocally_disp(struct dm_report *rh, struct dm_pool *mem,
} else
active_locally = lv_is_active(lv);
- return _binary_disp(rh, mem, field, active_locally, FIRST_NAME(lv_active_locally), private);
+ return _binary_disp(rh, mem, field, active_locally, FIRST_NAME(lv_active_locally_y), private);
}
static int _lvactiveremotely_disp(struct dm_report *rh, struct dm_pool *mem,
@@ -1494,7 +1504,7 @@ static int _lvactiveremotely_disp(struct dm_report *rh, struct dm_pool *mem,
} else
active_remotely = 0;
- return _binary_disp(rh, mem, field, active_remotely, FIRST_NAME(lv_active_remotely), private);
+ return _binary_disp(rh, mem, field, active_remotely, FIRST_NAME(lv_active_remotely_y), private);
}
static int _lvactiveexclusively_disp(struct dm_report *rh, struct dm_pool *mem,
@@ -1510,7 +1520,7 @@ static int _lvactiveexclusively_disp(struct dm_report *rh, struct dm_pool *mem,
} else
active_exclusively = lv_is_active(lv);
- return _binary_disp(rh, mem, field, active_exclusively, FIRST_NAME(lv_active_exclusively), private);
+ return _binary_disp(rh, mem, field, active_exclusively, FIRST_NAME(lv_active_exclusively_y), private);
}
static int _lvmergefailed_disp(struct dm_report *rh, struct dm_pool *mem,
@@ -1525,7 +1535,7 @@ static int _lvmergefailed_disp(struct dm_report *rh, struct dm_pool *mem,
return _field_set_value(field, _str_unknown, &_reserved_number_undef_64);
merge_failed = snap_percent == LVM_PERCENT_MERGE_FAILED;
- return _binary_disp(rh, mem, field, merge_failed, FIRST_NAME(lv_merge_failed), private);
+ return _binary_disp(rh, mem, field, merge_failed, FIRST_NAME(lv_merge_failed_y), private);
}
static int _lvsnapshotinvalid_disp(struct dm_report *rh, struct dm_pool *mem,
@@ -1540,7 +1550,7 @@ static int _lvsnapshotinvalid_disp(struct dm_report *rh, struct dm_pool *mem,
return _field_set_value(field, _str_unknown, &_reserved_number_undef_64);
snap_invalid = !lv_snapshot_percent(lv, &snap_percent) || snap_percent == DM_PERCENT_INVALID;
- return _binary_disp(rh, mem, field, snap_invalid, FIRST_NAME(lv_snapshot_invalid), private);
+ return _binary_disp(rh, mem, field, snap_invalid, FIRST_NAME(lv_snapshot_invalid_y), private);
}
static int _lvsuspended_disp(struct dm_report *rh, struct dm_pool *mem,
@@ -1550,7 +1560,7 @@ static int _lvsuspended_disp(struct dm_report *rh, struct dm_pool *mem,
const struct lv_with_info *lvi = (const struct lv_with_info *) data;
if (lvi->info->exists)
- return _binary_disp(rh, mem, field, lvi->info->suspended, FIRST_NAME(lv_suspended), private);
+ return _binary_disp(rh, mem, field, lvi->info->suspended, FIRST_NAME(lv_suspended_y), private);
return _binary_undef_disp(rh, mem, field, private);
}
@@ -1562,7 +1572,7 @@ static int _lvlivetable_disp(struct dm_report *rh, struct dm_pool *mem,
const struct lv_with_info *lvi = (const struct lv_with_info *) data;
if (lvi->info->exists)
- return _binary_disp(rh, mem, field, lvi->info->live_table, FIRST_NAME(lv_live_table), private);
+ return _binary_disp(rh, mem, field, lvi->info->live_table, FIRST_NAME(lv_live_table_y), private);
return _binary_undef_disp(rh, mem, field, private);
}
@@ -1574,7 +1584,7 @@ static int _lvinactivetable_disp(struct dm_report *rh, struct dm_pool *mem,
const struct lv_with_info *lvi = (const struct lv_with_info *) data;
if (lvi->info->exists)
- return _binary_disp(rh, mem, field, lvi->info->inactive_table, FIRST_NAME(lv_inactive_table), private);
+ return _binary_disp(rh, mem, field, lvi->info->inactive_table, FIRST_NAME(lv_inactive_table_y), private);
return _binary_undef_disp(rh, mem, field, private);
}
@@ -1586,7 +1596,7 @@ static int _lvdeviceopen_disp(struct dm_report *rh, struct dm_pool *mem,
const struct lv_with_info *lvi = (const struct lv_with_info *) data;
if (lvi->info->exists)
- return _binary_disp(rh, mem, field, lvi->info->open_count, FIRST_NAME(lv_device_open), private);
+ return _binary_disp(rh, mem, field, lvi->info->open_count, FIRST_NAME(lv_device_open_y), private);
return _binary_undef_disp(rh, mem, field, private);
}
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=c1bed36b67066052…
Commit: c1bed36b670660527caf70182c39080764df71d0
Parent: bccc2bef33af081264bbc356e37efe89ef78b796
Author: Peter Rajnoha <prajnoha(a)redhat.com>
AuthorDate: Wed Jul 9 14:37:01 2014 +0200
Committer: Peter Rajnoha <prajnoha(a)redhat.com>
CommitterDate: Wed Jul 9 15:57:05 2014 +0200
cleanup: move _lvactive_disp and _thinzero_disp under 'attribute' display functions
So all attribute reporting functions are all in one section of code
for quick orientation (all these functions are defined in the order
of their attribute character displayed in pv/vg/lv_attr field).
---
lib/report/report.c | 52 +++++++++++++++++++++++++-------------------------
1 files changed, 26 insertions(+), 26 deletions(-)
diff --git a/lib/report/report.c b/lib/report/report.c
index d28c767..198fdfa 100644
--- a/lib/report/report.c
+++ b/lib/report/report.c
@@ -750,18 +750,6 @@ static int _chunksize_disp(struct dm_report *rh, struct dm_pool *mem,
return _size64_disp(rh, mem, field, &size, private);
}
-static int _thinzero_disp(struct dm_report *rh, struct dm_pool *mem,
- struct dm_report_field *field,
- const void *data, void *private)
-{
- const struct lv_segment *seg = (const struct lv_segment *) data;
-
- if (seg_is_thin_pool(seg))
- return _uint32_disp(rh, mem, field, &seg->zero_new_blocks, private);
-
- return _field_set_value(field, "", &_reserved_number_undef_64);
-}
-
static int _transactionid_disp(struct dm_report *rh, struct dm_pool *mem,
struct dm_report_field *field,
const void *data, void *private)
@@ -1275,20 +1263,6 @@ static int _lvhost_disp(struct dm_report *rh, struct dm_pool *mem,
return _field_set_value(field, repstr, NULL);
}
-static int _lvactive_disp(struct dm_report *rh, struct dm_pool *mem,
- struct dm_report_field *field,
- const void *data, void *private)
-{
- char *repstr;
-
- if (!(repstr = lv_active_dup(mem, (const struct logical_volume *) data))) {
- log_error("Failed to allocate buffer for active.");
- return 0;
- }
-
- return _field_set_value(field, repstr, NULL);
-}
-
/* PV/VG/LV Attributes */
static int _pvallocatable_disp(struct dm_report *rh, struct dm_pool *mem,
@@ -1477,6 +1451,20 @@ static int _lvfixedminor_disp(struct dm_report *rh, struct dm_pool *mem,
return _binary_disp(rh, mem, field, fixed_minor, FIRST_NAME(lv_fixed_minor), private);
}
+static int _lvactive_disp(struct dm_report *rh, struct dm_pool *mem,
+ struct dm_report_field *field,
+ const void *data, void *private)
+{
+ char *repstr;
+
+ if (!(repstr = lv_active_dup(mem, (const struct logical_volume *) data))) {
+ log_error("Failed to allocate buffer for active.");
+ return 0;
+ }
+
+ return _field_set_value(field, repstr, NULL);
+}
+
static int _lvactivelocally_disp(struct dm_report *rh, struct dm_pool *mem,
struct dm_report_field *field,
const void *data, void *private)
@@ -1626,6 +1614,18 @@ static int _lvtargettype_disp(struct dm_report *rh, struct dm_pool *mem,
return _string_disp(rh, mem, field, &target_type, private);
}
+static int _thinzero_disp(struct dm_report *rh, struct dm_pool *mem,
+ struct dm_report_field *field,
+ const void *data, void *private)
+{
+ const struct lv_segment *seg = (const struct lv_segment *) data;
+
+ if (seg_is_thin_pool(seg))
+ return _uint32_disp(rh, mem, field, &seg->zero_new_blocks, private);
+
+ return _field_set_value(field, "", &_reserved_number_undef_64);
+}
+
static int _lvhealthstatus_disp(struct dm_report *rh, struct dm_pool *mem,
struct dm_report_field *field,
const void *data, void *private)
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=bccc2bef33af0812…
Commit: bccc2bef33af081264bbc356e37efe89ef78b796
Parent: b6ac8819f694d0b28fc592e89f01a8cf8e4f1802
Author: Peter Rajnoha <prajnoha(a)redhat.com>
AuthorDate: Wed Jul 9 14:28:50 2014 +0200
Committer: Peter Rajnoha <prajnoha(a)redhat.com>
CommitterDate: Wed Jul 9 15:57:05 2014 +0200
report: add lv_active_{locally,remotely,exclusively} LV reporting fields
lv_active_{locally,remotely,exclusively} display the original
"lv_active" field in a more separate way so that we can create
selection criteria in a binary-based form (yes/no).
---
WHATS_NEW | 1 +
lib/report/columns.h | 3 ++
lib/report/properties.c | 6 +++++
lib/report/report.c | 54 +++++++++++++++++++++++++++++++++++++++++++++++
4 files changed, 64 insertions(+), 0 deletions(-)
diff --git a/WHATS_NEW b/WHATS_NEW
index d4649e4..21668f2 100644
--- a/WHATS_NEW
+++ b/WHATS_NEW
@@ -1,5 +1,6 @@
Version 2.02.108 -
=================================
+ Add separate lv_active_{locally,remotely,exclusively} LV reporting fields.
Recognize "auto"/"unmanaged" values in selection for appropriate fields only.
Add report/binary_values_as_numeric lvm.conf option for binary values as 0/1.
Add --binary arg to pvs,vgs,lvs and {pv,vg,lv}display -C for 0/1 on reports.
diff --git a/lib/report/columns.h b/lib/report/columns.h
index 5013834..3d3d76e 100644
--- a/lib/report/columns.h
+++ b/lib/report/columns.h
@@ -53,6 +53,9 @@ FIELD(LVS, lv, STR, "TargetType", lvid, 10, lvtargettype, lv_target_type, "Kerne
FIELD(LVS, lv, STR, "Health", lvid, 15, lvhealthstatus, lv_health_status, "LV health status.", 0)
FIELD(LVS, lv, BIN, "SkipAct", lvid, 15, lvskipactivation, lv_skip_activation, "Set if LV is skipped on activation.", 0)
FIELD(LVS, lv, STR, "Active", lvid, 6, lvactive, lv_active, "Active state of the LV.", 0)
+FIELD(LVS, lv, BIN, "ActiveLoc", lvid, 10, lvactivelocally, lv_active_locally, "Set if the LV is active locally.", 0)
+FIELD(LVS, lv, BIN, "ActiveRem", lvid, 10, lvactiveremotely, lv_active_remotely, "Set if the LV is active remotely.", 0)
+FIELD(LVS, lv, BIN, "ActiveExcl", lvid, 10, lvactiveexclusively, lv_active_exclusively, "Set if the LV is active exclusively.", 0)
FIELD(LVS, lv, NUM, "Maj", major, 3, int32, lv_major, "Persistent major number or -1 if not persistent.", 0)
FIELD(LVS, lv, NUM, "Min", minor, 3, int32, lv_minor, "Persistent minor number or -1 if not persistent.", 0)
FIELD(LVS, lv, SIZ, "Rahead", lvid, 6, lvreadahead, lv_read_ahead, "Read ahead setting in current units.", 0)
diff --git a/lib/report/properties.c b/lib/report/properties.c
index 8fb1e92..b4e183f 100644
--- a/lib/report/properties.c
+++ b/lib/report/properties.c
@@ -196,6 +196,12 @@ GET_PV_NUM_PROPERTY_FN(pv_ba_size, SECTOR_SIZE * pv->ba_size)
#define _lv_allocation_policy_get prop_not_implemented_get
#define _lv_allocation_locked_set prop_not_implemented_set
#define _lv_allocation_locked_get prop_not_implemented_get
+#define _lv_active_locally_set prop_not_implemented_set
+#define _lv_active_locally_get prop_not_implemented_get
+#define _lv_active_remotely_set prop_not_implemented_set
+#define _lv_active_remotely_get prop_not_implemented_get
+#define _lv_active_exclusively_set prop_not_implemented_set
+#define _lv_active_exclusively_get prop_not_implemented_get
#define _lv_fixed_minor_set prop_not_implemented_set
#define _lv_fixed_minor_get prop_not_implemented_get
#define _lv_merge_failed_set prop_not_implemented_set
diff --git a/lib/report/report.c b/lib/report/report.c
index adcd2be..d28c767 100644
--- a/lib/report/report.c
+++ b/lib/report/report.c
@@ -101,6 +101,9 @@ FIELD_RESERVED_VALUE(lv_merging, lv_merging, _one64, "merging")
FIELD_RESERVED_VALUE(lv_converting, lv_converting, _one64, "converting")
FIELD_RESERVED_VALUE(lv_allocation_locked, lv_allocation_locked, _one64, "allocation locked", "locked")
FIELD_RESERVED_VALUE(lv_fixed_minor, lv_fixed_minor, _one64, "fixed minor", "fixed")
+FIELD_RESERVED_VALUE(lv_active_locally, lv_active_locally, _one64, "active locally", "active", "locally")
+FIELD_RESERVED_VALUE(lv_active_remotely, lv_active_remotely, _one64, "active remotely", "active", "remotely")
+FIELD_RESERVED_VALUE(lv_active_exclusively, lv_active_exclusively, _one64, "active exclusively", "active", "exclusively")
FIELD_RESERVED_VALUE(lv_merge_failed, lv_merge_failed, _one64, "merge failed", "failed")
FIELD_RESERVED_VALUE(lv_snapshot_invalid, lv_snapshot_invalid, _one64, "snapsot invalid", "invalid")
FIELD_RESERVED_VALUE(lv_suspended, lv_suspended, _one64, "suspended")
@@ -139,6 +142,9 @@ static const struct dm_report_reserved_value _report_reserved_values[] = {
FIELD_RESERVED_VALUE_REG(lv_converting, "lv_converting reserved values")
FIELD_RESERVED_VALUE_REG(lv_allocation_locked, "lv_allocation_locked reserved values")
FIELD_RESERVED_VALUE_REG(lv_fixed_minor, "lv_fixed_minor reserved values")
+ FIELD_RESERVED_VALUE_REG(lv_active_locally, "lv_active_locally reserved values")
+ FIELD_RESERVED_VALUE_REG(lv_active_remotely, "lv_active_remotelly reserved values")
+ FIELD_RESERVED_VALUE_REG(lv_active_exclusively, "lv_active_exclusively reserved values")
FIELD_RESERVED_VALUE_REG(lv_merge_failed, "lv_merge_failed reserved values")
FIELD_RESERVED_VALUE_REG(lv_snapshot_invalid, "lv_snapshot_invalid reserved values")
FIELD_RESERVED_VALUE_REG(lv_suspended, "lv_suspended reserved values")
@@ -1471,6 +1477,54 @@ static int _lvfixedminor_disp(struct dm_report *rh, struct dm_pool *mem,
return _binary_disp(rh, mem, field, fixed_minor, FIRST_NAME(lv_fixed_minor), private);
}
+static int _lvactivelocally_disp(struct dm_report *rh, struct dm_pool *mem,
+ struct dm_report_field *field,
+ const void *data, void *private)
+{
+ const struct logical_volume *lv = (const struct logical_volume *) data;
+ int active_locally;
+
+ if (vg_is_clustered(lv->vg)) {
+ lv = lv_lock_holder(lv);
+ active_locally = lv_is_active_locally(lv);
+ } else
+ active_locally = lv_is_active(lv);
+
+ return _binary_disp(rh, mem, field, active_locally, FIRST_NAME(lv_active_locally), private);
+}
+
+static int _lvactiveremotely_disp(struct dm_report *rh, struct dm_pool *mem,
+ struct dm_report_field *field,
+ const void *data, void *private)
+{
+ const struct logical_volume *lv = (const struct logical_volume *) data;
+ int active_remotely;
+
+ if (vg_is_clustered(lv->vg)) {
+ lv = lv_lock_holder(lv);
+ active_remotely = lv_is_active_but_not_locally(lv);
+ } else
+ active_remotely = 0;
+
+ return _binary_disp(rh, mem, field, active_remotely, FIRST_NAME(lv_active_remotely), private);
+}
+
+static int _lvactiveexclusively_disp(struct dm_report *rh, struct dm_pool *mem,
+ struct dm_report_field *field,
+ const void *data, void *private)
+{
+ const struct logical_volume *lv = (const struct logical_volume *) data;
+ int active_exclusively;
+
+ if (vg_is_clustered(lv->vg)) {
+ lv = lv_lock_holder(lv);
+ active_exclusively = lv_is_active_exclusive(lv);
+ } else
+ active_exclusively = lv_is_active(lv);
+
+ return _binary_disp(rh, mem, field, active_exclusively, FIRST_NAME(lv_active_exclusively), private);
+}
+
static int _lvmergefailed_disp(struct dm_report *rh, struct dm_pool *mem,
struct dm_report_field *field,
const void *data, void *private)
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=b6ac8819f694d0b2…
Commit: b6ac8819f694d0b28fc592e89f01a8cf8e4f1802
Parent: ccab185aa7accd348409b9c0261bc3200570710d
Author: Peter Rajnoha <prajnoha(a)redhat.com>
AuthorDate: Wed Jul 9 13:41:25 2014 +0200
Committer: Peter Rajnoha <prajnoha(a)redhat.com>
CommitterDate: Wed Jul 9 15:57:05 2014 +0200
report: 'whether' -> 'set if' in field description
---
lib/report/columns.h | 40 ++++++++++++++++++++--------------------
1 files changed, 20 insertions(+), 20 deletions(-)
diff --git a/lib/report/columns.h b/lib/report/columns.h
index 21ca585..5013834 100644
--- a/lib/report/columns.h
+++ b/lib/report/columns.h
@@ -40,18 +40,18 @@ FIELD(LVS, lv, STR, "DMPath", lvid, 6, lvdmpath, lv_dm_path, "Internal device-ma
FIELD(LVS, lv, STR, "Parent", lvid, 6, lvparent, lv_parent, "For LVs that are components of another LV, the parent LV.", 0)
FIELD(LVS, lv, STR, "Attr", lvid, 4, lvstatus, lv_attr, "Various attributes - see man page.", 0)
FIELD(LVS, lv, STR, "Type", lvid, 10, lvvolumetype, lv_volume_type, "LV volume type.", 0)
-FIELD(LVS, lv, BIN, "InitImgSync", lvid, 10, lvinitialimagesync, lv_initial_image_sync, "Whether mirror/RAID images underwent initial resynchronization.", 0)
-FIELD(LVS, lv, BIN, "ImgSynced", lvid, 10, lvimagesynced, lv_image_synced, "Whether mirror/RAID image is synchronized.", 0)
-FIELD(LVS, lv, BIN, "Merging", lvid, 10, lvmerging, lv_merging, "Whether snapshot LV is being merged to origin.", 0)
-FIELD(LVS, lv, BIN, "Converting", lvid, 10, lvconverting, lv_converting, "Whether LV is being converted.", 0)
+FIELD(LVS, lv, BIN, "InitImgSync", lvid, 10, lvinitialimagesync, lv_initial_image_sync, "Set if mirror/RAID images underwent initial resynchronization.", 0)
+FIELD(LVS, lv, BIN, "ImgSynced", lvid, 10, lvimagesynced, lv_image_synced, "Set if mirror/RAID image is synchronized.", 0)
+FIELD(LVS, lv, BIN, "Merging", lvid, 10, lvmerging, lv_merging, "Set if snapshot LV is being merged to origin.", 0)
+FIELD(LVS, lv, BIN, "Converting", lvid, 10, lvconverting, lv_converting, "Set if LV is being converted.", 0)
FIELD(LVS, lv, STR, "AllocPol", lvid, 10, lvallocationpolicy, lv_allocation_policy, "LV allocation policy.", 0)
-FIELD(LVS, lv, BIN, "AllocLock", lvid, 10, lvallocationlocked, lv_allocation_locked, "Whether LV is locked against allocation changes.", 0)
-FIELD(LVS, lv, BIN, "FixMin", lvid, 10, lvfixedminor, lv_fixed_minor, "Whether LV has fixed minor number assigned.", 0)
-FIELD(LVS, lv, BIN, "MergeFailed", lvid, 15, lvmergefailed, lv_merge_failed, "Whether snapshot merge failed.", 0)
-FIELD(LVS, lv, BIN, "SnapInvalid", lvid, 15, lvsnapshotinvalid, lv_snapshot_invalid, "Whether snapshot LV is invalid.", 0)
+FIELD(LVS, lv, BIN, "AllocLock", lvid, 10, lvallocationlocked, lv_allocation_locked, "Set if LV is locked against allocation changes.", 0)
+FIELD(LVS, lv, BIN, "FixMin", lvid, 10, lvfixedminor, lv_fixed_minor, "Set if LV has fixed minor number assigned.", 0)
+FIELD(LVS, lv, BIN, "MergeFailed", lvid, 15, lvmergefailed, lv_merge_failed, "Set if snapshot merge failed.", 0)
+FIELD(LVS, lv, BIN, "SnapInvalid", lvid, 15, lvsnapshotinvalid, lv_snapshot_invalid, "Set if snapshot LV is invalid.", 0)
FIELD(LVS, lv, STR, "TargetType", lvid, 10, lvtargettype, lv_target_type, "Kernel target type the LV is related to.", 0)
FIELD(LVS, lv, STR, "Health", lvid, 15, lvhealthstatus, lv_health_status, "LV health status.", 0)
-FIELD(LVS, lv, BIN, "SkipAct", lvid, 15, lvskipactivation, lv_skip_activation, "Whether LV is skipped on activation.", 0)
+FIELD(LVS, lv, BIN, "SkipAct", lvid, 15, lvskipactivation, lv_skip_activation, "Set if LV is skipped on activation.", 0)
FIELD(LVS, lv, STR, "Active", lvid, 6, lvactive, lv_active, "Active state of the LV.", 0)
FIELD(LVS, lv, NUM, "Maj", major, 3, int32, lv_major, "Persistent major number or -1 if not persistent.", 0)
FIELD(LVS, lv, NUM, "Min", minor, 3, int32, lv_minor, "Persistent minor number or -1 if not persistent.", 0)
@@ -87,10 +87,10 @@ FIELD(LVSINFO, lv, NUM, "KMaj", lvid, 4, lvkmaj, lv_kernel_major, "Currently ass
FIELD(LVSINFO, lv, NUM, "KMin", lvid, 4, lvkmin, lv_kernel_minor, "Currently assigned minor number or -1 if LV is not active.", 0)
FIELD(LVSINFO, lv, SIZ, "KRahead", lvid, 7, lvkreadahead, lv_kernel_read_ahead, "Currently-in-use read ahead setting in current units.", 0)
FIELD(LVSINFO, lv, STR, "LPerms", lvid, 8, lvpermissions, lv_permissions, "LV permissions.", 0)
-FIELD(LVSINFO, lv, BIN, "Suspended", lvid, 10, lvsuspended, lv_suspended, "Whether LV is suspended.", 0)
-FIELD(LVSINFO, lv, BIN, "LiveTable", lvid, 20, lvlivetable, lv_live_table, "Whether LV has live table present.", 0)
-FIELD(LVSINFO, lv, BIN, "InactiveTable", lvid, 20, lvinactivetable, lv_inactive_table, "Whether LV has inactive table present.", 0)
-FIELD(LVSINFO, lv, BIN, "DevOpen", lvid, 10, lvdeviceopen, lv_device_open, "Whether LV device is open.", 0)
+FIELD(LVSINFO, lv, BIN, "Suspended", lvid, 10, lvsuspended, lv_suspended, "Set if LV is suspended.", 0)
+FIELD(LVSINFO, lv, BIN, "LiveTable", lvid, 20, lvlivetable, lv_live_table, "Set if LV has live table present.", 0)
+FIELD(LVSINFO, lv, BIN, "InactiveTable", lvid, 20, lvinactivetable, lv_inactive_table, "Set if LV has inactive table present.", 0)
+FIELD(LVSINFO, lv, BIN, "DevOpen", lvid, 10, lvdeviceopen, lv_device_open, "Set if LV device is open.", 0)
FIELD(LABEL, label, STR, "Fmt", type, 3, pvfmt, pv_fmt, "Type of metadata.", 0)
FIELD(LABEL, label, STR, "PV UUID", type, 38, pvuuid, pv_uuid, "Unique identifier.", 0)
@@ -104,9 +104,9 @@ FIELD(PVS, pv, SIZ, "PSize", id, 5, pvsize, pv_size, "Size of PV in current unit
FIELD(PVS, pv, SIZ, "PFree", id, 5, pvfree, pv_free, "Total amount of unallocated space in current units.", 0)
FIELD(PVS, pv, SIZ, "Used", id, 4, pvused, pv_used, "Total amount of allocated space in current units.", 0)
FIELD(PVS, pv, STR, "Attr", id, 4, pvstatus, pv_attr, "Various attributes - see man page.", 0)
-FIELD(PVS, pv, BIN, "Allocatable", id, 10, pvallocatable, pv_allocatable, "Whether this device can be used for allocation.", 0)
-FIELD(PVS, pv, BIN, "Exported", id, 10, pvexported, pv_exported, "Whether this device is exported.", 0)
-FIELD(PVS, pv, BIN, "Missing", id, 10, pvmissing, pv_missing, "Whether this device is missing in system.", 0)
+FIELD(PVS, pv, BIN, "Allocatable", id, 10, pvallocatable, pv_allocatable, "Set if this device can be used for allocation.", 0)
+FIELD(PVS, pv, BIN, "Exported", id, 10, pvexported, pv_exported, "Set if this device is exported.", 0)
+FIELD(PVS, pv, BIN, "Missing", id, 10, pvmissing, pv_missing, "Set if this device is missing in system.", 0)
FIELD(PVS, pv, NUM, "PE", pe_count, 3, uint32, pv_pe_count, "Total number of Physical Extents.", 0)
FIELD(PVS, pv, NUM, "Alloc", pe_alloc_count, 5, uint32, pv_pe_alloc_count, "Total number of allocated Physical Extents.", 0)
FIELD(PVS, pv, STR_LIST, "PV Tags", tags, 7, tags, pv_tags, "Tags, if any.", 0)
@@ -120,11 +120,11 @@ FIELD(VGS, vg, STR, "VG UUID", id, 38, uuid, vg_uuid, "Unique identifier.", 0)
FIELD(VGS, vg, STR, "VG", name, 4, string, vg_name, "Name.", 0)
FIELD(VGS, vg, STR, "Attr", cmd, 5, vgstatus, vg_attr, "Various attributes - see man page.", 0)
FIELD(VGS, vg, STR, "VPerms", cmd, 10, vgpermissions, vg_permissions, "VG permissions.", 0)
-FIELD(VGS, vg, BIN, "Extendable", cmd, 10, vgextendable, vg_extendable, "Whether VG is extendable.", 0)
-FIELD(VGS, vg, BIN, "Exported", cmd, 10, vgexported, vg_exported, "Whether VG is exported.", 0)
-FIELD(VGS, vg, BIN, "Partial", cmd, 10, vgpartial, vg_partial, "Whether VG is partial.", 0)
+FIELD(VGS, vg, BIN, "Extendable", cmd, 10, vgextendable, vg_extendable, "Set if VG is extendable.", 0)
+FIELD(VGS, vg, BIN, "Exported", cmd, 10, vgexported, vg_exported, "Set if VG is exported.", 0)
+FIELD(VGS, vg, BIN, "Partial", cmd, 10, vgpartial, vg_partial, "Set if VG is partial.", 0)
FIELD(VGS, vg, STR, "AllocPol", cmd, 10, vgallocationpolicy, vg_allocation_policy, "VG allocation policy.", 0)
-FIELD(VGS, vg, BIN, "Clustered", cmd, 10, vgclustered, vg_clustered, "Whether VG is clustered.", 0)
+FIELD(VGS, vg, BIN, "Clustered", cmd, 10, vgclustered, vg_clustered, "Set if VG is clustered.", 0)
FIELD(VGS, vg, SIZ, "VSize", cmd, 5, vgsize, vg_size, "Total size of VG in current units.", 0)
FIELD(VGS, vg, NUM, "VFree", cmd, 5, vgfree, vg_free, "Total amount of free space in current units.", 0)
FIELD(VGS, vg, STR, "SYS ID", system_id, 6, string, vg_sysid, "System ID indicating when and where it was created.", 0)
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=ccab185aa7accd34…
Commit: ccab185aa7accd348409b9c0261bc3200570710d
Parent: 1a05862732d8e809f888313c546e97381c4e1f49
Author: Peter Rajnoha <prajnoha(a)redhat.com>
AuthorDate: Tue Jul 8 12:40:45 2014 +0200
Committer: Peter Rajnoha <prajnoha(a)redhat.com>
CommitterDate: Wed Jul 9 15:55:54 2014 +0200
cleanup: use macros for definition of reporting/selection reserved values
The macros for reserved value definition makes the process a bit easier,
but there's still a place for improvement and make this even more
transparent. We can optimize and provide better automatism here later on.
---
lib/report/columns.h | 4 +
lib/report/report.c | 329 ++++++++++++++++++++++----------------------------
2 files changed, 149 insertions(+), 184 deletions(-)
diff --git a/lib/report/columns.h b/lib/report/columns.h
index 2769c2d..21ca585 100644
--- a/lib/report/columns.h
+++ b/lib/report/columns.h
@@ -27,6 +27,10 @@
* Help text ends with a full stop.
*/
+/*
+ * FIELD(report_object_type, structure, sort_type, heading, structure_field, output width, reporting_function, field_id, description, settable_via_lib)
+ */
+
/* *INDENT-OFF* */
FIELD(LVS, lv, STR, "LV UUID", lvid.id[1], 38, uuid, lv_uuid, "Unique identifier.", 0)
FIELD(LVS, lv, STR, "LV", lvid, 4, lvname, lv_name, "Name. LVs created for internal use are enclosed in brackets.", 0)
diff --git a/lib/report/report.c b/lib/report/report.c
index 4ec75aa..adcd2be 100644
--- a/lib/report/report.c
+++ b/lib/report/report.c
@@ -41,159 +41,118 @@ struct lvm_report_object {
struct label *label;
};
-/* Enum for field_num index to use in per-field reserved value definition. */
+/*
+ * Enum for field_num index to use in per-field reserved value definition.
+ * Each field is represented by enum value with name "field_<id>" where <id>
+ * is the field_id of the field as registered in columns.h.
+ */
#define FIELD(type, strct, sorttype, head, field_name, width, func, id, desc, writeable) field_ ## id,
enum {
#include "columns.h"
};
#undef FIELD
-
static const uint64_t _zero64 = UINT64_C(0);
static const uint64_t _one64 = UINT64_C(1);
-static const char * const _str_zero = "0";
-static const char * const _str_one = "1";
+static const char const _str_zero[] = "0";
+static const char const _str_one[] = "1";
+static const char const _str_minus_one[] = "-1";
+static const char const _str_unknown[] = "unknown";
/*
- * TODO: try to automate reserved value definition and declare reserved values
- * using FIELD macro directly. The FIELD macro should be able to define
- * proper structures automatically then.
- */
-
-/* Per-type reserved values. */
-static const uint64_t _reserved_number_undef_64 = UINT64_C(-1);
-/*
* 32 bit signed is casted to 64 bit unsigned in dm_report_field internally!
* So when stored in the struct, the _reserved_number_undef_32 is actually
* equal to _reserved_number_undef_64.
*/
static const int32_t _reserved_number_undef_32 = INT32_C(-1);
-/* Per-field reserved values. */
-static const struct dm_report_field_reserved_value _reserved_pv_allocatable = {field_pv_allocatable, &_one64};
-static const struct dm_report_field_reserved_value _reserved_pv_exported = {field_pv_exported, &_one64};
-static const struct dm_report_field_reserved_value _reserved_pv_missing = {field_pv_missing, &_one64};
-static const struct dm_report_field_reserved_value _reserved_vg_extendable = {field_vg_extendable, &_one64};
-static const struct dm_report_field_reserved_value _reserved_vg_exported = {field_vg_exported, &_one64};
-static const struct dm_report_field_reserved_value _reserved_vg_partial = {field_vg_partial, &_one64};
-static const struct dm_report_field_reserved_value _reserved_vg_clustered = {field_vg_clustered, &_one64};
-static const struct dm_report_field_reserved_value _reserved_vg_permissions_rw = {field_vg_permissions, "writeable"};
-static const struct dm_report_field_reserved_value _reserved_vg_permissions_r = {field_vg_permissions, "read-only"};
-static const struct dm_report_field_reserved_value _reserved_vg_mda_copies = {field_vg_mda_copies, &_reserved_number_undef_64};
-static const struct dm_report_field_reserved_value _reserved_lv_initial_image_sync = {field_lv_initial_image_sync, &_one64};
-static const struct dm_report_field_reserved_value _reserved_lv_image_synced = {field_lv_image_synced, &_one64};
-static const struct dm_report_field_reserved_value _reserved_lv_merging = {field_lv_merging, &_one64};
-static const struct dm_report_field_reserved_value _reserved_lv_converting = {field_lv_converting, &_one64};
-static const struct dm_report_field_reserved_value _reserved_lv_allocation_locked = {field_lv_allocation_locked, &_one64};
-static const struct dm_report_field_reserved_value _reserved_lv_fixed_minor = {field_lv_fixed_minor, &_one64};
-static const struct dm_report_field_reserved_value _reserved_lv_merge_failed = {field_lv_merge_failed, &_one64};
-static const struct dm_report_field_reserved_value _reserved_lv_snapshot_invalid = {field_lv_snapshot_invalid, &_one64};
-static const struct dm_report_field_reserved_value _reserved_lv_suspended = {field_lv_suspended, &_one64};
-static const struct dm_report_field_reserved_value _reserved_lv_live_table = {field_lv_live_table, &_one64};
-static const struct dm_report_field_reserved_value _reserved_lv_inactive_table = {field_lv_inactive_table, &_one64};
-static const struct dm_report_field_reserved_value _reserved_lv_device_open = {field_lv_device_open, &_one64};
-static const struct dm_report_field_reserved_value _reserved_lv_skip_activation = {field_lv_skip_activation, &_one64};
-static const struct dm_report_field_reserved_value _reserved_lv_permissions_rw = {field_lv_permissions, "writeable"};
-static const struct dm_report_field_reserved_value _reserved_lv_permissions_r = {field_lv_permissions, "read-only"};
-static const struct dm_report_field_reserved_value _reserved_lv_permissions_r_override = {field_lv_permissions, "read-only-override"};
-static const struct dm_report_field_reserved_value _reserved_lv_read_ahead = {field_lv_read_ahead, &_reserved_number_undef_64};
-
-/* Per-type reserved names. */
-static const char const *_reserved_number_undef_64_names[]={"-1", "undefined", "undef", "unknown", NULL};
-
-/* Per-field reserved names. */
-static const char *_reserved_pv_allocatable_names[]={"allocatable", NULL};
-static const char *_reserved_pv_exported_names[]={"exported", NULL};
-static const char *_reserved_pv_missing_names[]={"missing", NULL};
-static const char *_reserved_vg_extendable_names[]={"extendable", NULL};
-static const char *_reserved_vg_exported_names[]={"exported", NULL};
-static const char *_reserved_vg_partial_names[]={"partial", NULL};
-static const char *_reserved_vg_clustered_names[]={"clustered", NULL};
-static const char *_reserved_vg_permissions_rw_names[]={"writeable", "rw", "read-write", NULL};
-static const char *_reserved_vg_permissions_r_names[]={"read-only", "r", "ro", NULL};
-static const char *_reserved_vg_mda_copies_names[]={"unmanaged", NULL};
-static const char *_reserved_lv_initial_image_sync_names[]={"initial image sync", "sync", NULL};
-static const char *_reserved_lv_image_synced_names[]={"image synced", "synced", NULL};
-static const char *_reserved_lv_merging_names[]={"merging", NULL};
-static const char *_reserved_lv_converting_names[]={"converting", NULL};
-static const char *_reserved_lv_allocation_locked_names[]={"allocation locked", "locked", NULL};
-static const char *_reserved_lv_fixed_minor_names[]={"fixed minor", "fixed", NULL};
-static const char *_reserved_lv_merge_failed_names[]={"merge failed", "failed", NULL};
-static const char *_reserved_lv_snapshot_invalid_names[]={"snapsot invalid", "invalid", NULL};
-static const char *_reserved_lv_suspended_names[]={"suspended", NULL};
-static const char *_reserved_lv_live_table_names[]={"live table present", "live table", "live", NULL};
-static const char *_reserved_lv_inactive_table_names[]={"inactive table present", "inactive table", "inactive", NULL};
-static const char *_reserved_lv_device_open_names[]={"open", NULL};
-static const char *_reserved_lv_skip_activation_names[]={"skip activation", "skip", NULL};
-static const char *_reserved_lv_permissions_rw_names[]={"writeable", "rw", "read-write", NULL};
-static const char *_reserved_lv_permissions_r_names[]={"read-only", "r", "ro", NULL};
-static const char *_reserved_lv_permissions_r_override_names[]={"read-only-override", "ro-override", "r-override", "R", NULL};
-static const char *_reserved_lv_read_ahead_names[]={"auto", NULL};
-
-/* Put together arrays of reserved names with their reserved values. */
+#define FIRST_NAME(id) _reserved_ ## id ## _names[0]
+#define TYPE_RESERVED_VALUE(type, id, value, ...) \
+ static const char *_reserved_ ## id ## _names[] = { __VA_ARGS__, NULL}; \
+ static const type _reserved_ ## id = value;
+#define FIELD_RESERVED_VALUE(field_id, id, value, ...) \
+ static const char *_reserved_ ## id ## _names[] = { __VA_ARGS__ , NULL}; \
+ static const struct dm_report_field_reserved_value _reserved_ ## id = {field_ ## field_id, &value};
+
+/*
+ * Reserved values and their assigned names.
+ * The first name is the one that is also used for reporting.
+ * All names listed are synonyms recognized in selection criteria.
+ * For binary-based values we map all reserved names listed onto value 1, blank onto value 0.
+ *
+ * TYPE_RESERVED_VALUE(type, reserved_value_id, value, reserved name, ...)
+ * FIELD_RESERVED_VALUE(field_id, reserved_value_id, value, reserved name, ...)
+ *
+ */
+TYPE_RESERVED_VALUE(uint64_t, number_undef_64, UINT64_C(-1), _str_minus_one, _str_unknown, "undefined", "undef");
+FIELD_RESERVED_VALUE(pv_allocatable, pv_allocatable, _one64, "allocatable")
+FIELD_RESERVED_VALUE(pv_exported, pv_exported, _one64, "exported")
+FIELD_RESERVED_VALUE(pv_missing, pv_missing, _one64, "missing")
+FIELD_RESERVED_VALUE(vg_extendable, vg_extendable, _one64, "extendable")
+FIELD_RESERVED_VALUE(vg_exported, vg_exported, _one64, "exported")
+FIELD_RESERVED_VALUE(vg_partial, vg_partial, _one64, "partial")
+FIELD_RESERVED_VALUE(vg_clustered, vg_clustered, _one64, "clustered")
+FIELD_RESERVED_VALUE(vg_permissions, vg_permissions_rw, FIRST_NAME(vg_permissions_rw), "writeable", "rw", "read_write")
+FIELD_RESERVED_VALUE(vg_permissions, vg_permissions_r, FIRST_NAME(vg_permissions_r), "read-only", "r", "ro")
+FIELD_RESERVED_VALUE(vg_mda_copies, vg_mda_copies, _reserved_number_undef_64, "unmanaged")
+FIELD_RESERVED_VALUE(lv_initial_image_sync, lv_initial_image_sync, _one64, "initial image sync", "sync")
+FIELD_RESERVED_VALUE(lv_image_synced, lv_image_synced, _one64, "image synced", "synced")
+FIELD_RESERVED_VALUE(lv_merging, lv_merging, _one64, "merging")
+FIELD_RESERVED_VALUE(lv_converting, lv_converting, _one64, "converting")
+FIELD_RESERVED_VALUE(lv_allocation_locked, lv_allocation_locked, _one64, "allocation locked", "locked")
+FIELD_RESERVED_VALUE(lv_fixed_minor, lv_fixed_minor, _one64, "fixed minor", "fixed")
+FIELD_RESERVED_VALUE(lv_merge_failed, lv_merge_failed, _one64, "merge failed", "failed")
+FIELD_RESERVED_VALUE(lv_snapshot_invalid, lv_snapshot_invalid, _one64, "snapsot invalid", "invalid")
+FIELD_RESERVED_VALUE(lv_suspended, lv_suspended, _one64, "suspended")
+FIELD_RESERVED_VALUE(lv_live_table, lv_live_table, _one64, "live table present", "live table", "live")
+FIELD_RESERVED_VALUE(lv_inactive_table, lv_inactive_table, _one64, "inactive table present", "inactive table", "inactive")
+FIELD_RESERVED_VALUE(lv_device_open, lv_device_open, _one64, "open")
+FIELD_RESERVED_VALUE(lv_skip_activation, lv_skip_activation, _one64, "skip activation", "skip")
+FIELD_RESERVED_VALUE(lv_permissions, lv_permissions_rw, FIRST_NAME(lv_permissions_rw), "writeable", "rw", "read-write")
+FIELD_RESERVED_VALUE(lv_permissions, lv_permissions_r, FIRST_NAME(lv_permissions_r), "read-only", "r", "ro")
+FIELD_RESERVED_VALUE(lv_permissions, lv_permissions_r_override, FIRST_NAME(lv_permissions_r_override), "read-only-override", "ro-override", "r-override", "R")
+FIELD_RESERVED_VALUE(lv_read_ahead, lv_read_ahead, _reserved_number_undef_64, "auto")
+
+#define TYPE_RESERVED_VALUE_REG(type, id, description) {DM_REPORT_FIELD_TYPE_ ## type, &_reserved_ ## id, _reserved_ ## id ## _names, description},
+#define FIELD_RESERVED_VALUE_REG(id, description) {DM_REPORT_FIELD_TYPE_NONE, &_reserved_ ## id, _reserved_ ## id ## _names, description},
+
+/*
+ * Create array of reserved values to be passed for dm_report_init_with_selection
+ * function that initializes report with selection criteria. Selection code then
+ * recognizes these reserved values when parsing selection criteria.
+ */
static const struct dm_report_reserved_value _report_reserved_values[] = {
- {DM_REPORT_FIELD_TYPE_NUMBER, &_reserved_number_undef_64, _reserved_number_undef_64_names,
- "Reserved value for undefined numeric value."},
- {DM_REPORT_FIELD_TYPE_NONE, &_reserved_pv_allocatable, _reserved_pv_allocatable_names,
- "pv_allocatable reserved values"},
- {DM_REPORT_FIELD_TYPE_NONE, &_reserved_pv_exported, _reserved_pv_exported_names,
- "pv_exported reserved values"},
- {DM_REPORT_FIELD_TYPE_NONE, &_reserved_pv_missing, _reserved_pv_missing_names,
- "pv_missing reserved values"},
- {DM_REPORT_FIELD_TYPE_NONE, &_reserved_vg_extendable, _reserved_vg_extendable_names,
- "vg_extendable reserved values"},
- {DM_REPORT_FIELD_TYPE_NONE, &_reserved_vg_exported, _reserved_vg_exported_names,
- "vg_exported reserved values"},
- {DM_REPORT_FIELD_TYPE_NONE, &_reserved_vg_partial, _reserved_vg_partial_names,
- "vg_partial reserved values"},
- {DM_REPORT_FIELD_TYPE_NONE, &_reserved_vg_clustered, _reserved_vg_clustered_names,
- "vg_clustered reserved values"},
- {DM_REPORT_FIELD_TYPE_NONE, &_reserved_vg_permissions_rw, _reserved_vg_permissions_rw_names,
- "vg_permissions reserved values (writeable)"},
- {DM_REPORT_FIELD_TYPE_NONE, &_reserved_vg_permissions_r, _reserved_vg_permissions_r_names,
- "vg_permissions reserved values (read-only)"},
- {DM_REPORT_FIELD_TYPE_NONE, &_reserved_vg_mda_copies, _reserved_vg_mda_copies_names,
- "vg_mda_copies reserved values (unmanaged)"},
- {DM_REPORT_FIELD_TYPE_NONE, &_reserved_lv_initial_image_sync, _reserved_lv_initial_image_sync_names,
- "lv_initial_image_sync reserved values"},
- {DM_REPORT_FIELD_TYPE_NONE, &_reserved_lv_image_synced, _reserved_lv_image_synced_names,
- "lv_image_synced reserved values"},
- {DM_REPORT_FIELD_TYPE_NONE, &_reserved_lv_merging, _reserved_lv_merging_names,
- "lv_merging reserved values"},
- {DM_REPORT_FIELD_TYPE_NONE, &_reserved_lv_converting, _reserved_lv_converting_names,
- "lv_converting reserved values"},
- {DM_REPORT_FIELD_TYPE_NONE, &_reserved_lv_allocation_locked, _reserved_lv_allocation_locked_names,
- "lv_allocation_locked reserved values"},
- {DM_REPORT_FIELD_TYPE_NONE, &_reserved_lv_fixed_minor, _reserved_lv_fixed_minor_names,
- "lv_fixed_minor reserved values"},
- {DM_REPORT_FIELD_TYPE_NONE, &_reserved_lv_merge_failed, _reserved_lv_merge_failed_names,
- "lv_merge_failed reserved values"},
- {DM_REPORT_FIELD_TYPE_NONE, &_reserved_lv_snapshot_invalid, _reserved_lv_snapshot_invalid_names,
- "lv_snapshot_invalid reserved values"},
- {DM_REPORT_FIELD_TYPE_NONE, &_reserved_lv_suspended, _reserved_lv_suspended_names,
- "lv_suspended reserved values"},
- {DM_REPORT_FIELD_TYPE_NONE, &_reserved_lv_live_table, _reserved_lv_live_table_names,
- "lv_live_table reserved values"},
- {DM_REPORT_FIELD_TYPE_NONE, &_reserved_lv_inactive_table, _reserved_lv_inactive_table_names,
- "lv_inactive_table reserved values"},
- {DM_REPORT_FIELD_TYPE_NONE, &_reserved_lv_device_open, _reserved_lv_device_open_names,
- "lv_device_open reserved values"},
- {DM_REPORT_FIELD_TYPE_NONE, &_reserved_lv_skip_activation, _reserved_lv_skip_activation_names,
- "lv_inactive_table reserved values"},
- {DM_REPORT_FIELD_TYPE_NONE, &_reserved_lv_permissions_rw, _reserved_lv_permissions_rw_names,
- "lv_permissions reserved values (writeable)"},
- {DM_REPORT_FIELD_TYPE_NONE, &_reserved_lv_permissions_r, _reserved_lv_permissions_r_names,
- "lv_permissions reserved values (read-only)"},
- {DM_REPORT_FIELD_TYPE_NONE, &_reserved_lv_permissions_r_override, _reserved_lv_permissions_r_override_names,
- "lv_permissions reserved values (read-only-override)"},
- {DM_REPORT_FIELD_TYPE_NONE, &_reserved_lv_read_ahead, _reserved_lv_read_ahead_names,
- "lv_read_ahead reserved values (auto)"},
+ TYPE_RESERVED_VALUE_REG(NUMBER, number_undef_64, "Reserved value for undefined numeric value.")
+ FIELD_RESERVED_VALUE_REG(pv_allocatable, "pv_allocatable reserved values")
+ FIELD_RESERVED_VALUE_REG(pv_exported, "pv_exported reserved values")
+ FIELD_RESERVED_VALUE_REG(pv_missing, "pv_missing reserved values")
+ FIELD_RESERVED_VALUE_REG(vg_extendable, "vg_extendable reserved values")
+ FIELD_RESERVED_VALUE_REG(vg_exported, "vg_exported reserved values")
+ FIELD_RESERVED_VALUE_REG(vg_partial, "vg_partial reserved values")
+ FIELD_RESERVED_VALUE_REG(vg_clustered, "vg_clustered reserved values")
+ FIELD_RESERVED_VALUE_REG(vg_permissions_rw, "vg_permissions reserved values (writeable)")
+ FIELD_RESERVED_VALUE_REG(vg_permissions_r, "vg_permissions reserved values (read-only)")
+ FIELD_RESERVED_VALUE_REG(vg_mda_copies, "vg_mda_copies reserved values (unmanaged)")
+ FIELD_RESERVED_VALUE_REG(lv_initial_image_sync, "lv_initial_image_sync reserved values")
+ FIELD_RESERVED_VALUE_REG(lv_image_synced, "lv_image_synced reserved values")
+ FIELD_RESERVED_VALUE_REG(lv_merging, "lv_merging reserved values")
+ FIELD_RESERVED_VALUE_REG(lv_converting, "lv_converting reserved values")
+ FIELD_RESERVED_VALUE_REG(lv_allocation_locked, "lv_allocation_locked reserved values")
+ FIELD_RESERVED_VALUE_REG(lv_fixed_minor, "lv_fixed_minor reserved values")
+ FIELD_RESERVED_VALUE_REG(lv_merge_failed, "lv_merge_failed reserved values")
+ FIELD_RESERVED_VALUE_REG(lv_snapshot_invalid, "lv_snapshot_invalid reserved values")
+ FIELD_RESERVED_VALUE_REG(lv_suspended, "lv_suspended reserved values")
+ FIELD_RESERVED_VALUE_REG(lv_live_table, "lv_live_table reserved values")
+ FIELD_RESERVED_VALUE_REG(lv_inactive_table, "lv_inactive_table reserved values")
+ FIELD_RESERVED_VALUE_REG(lv_device_open, "lv_device_open reserved values")
+ FIELD_RESERVED_VALUE_REG(lv_skip_activation, "lv_inactive_table reserved values")
+ FIELD_RESERVED_VALUE_REG(lv_permissions_rw, "lv_permissions reserved values (writeable)")
+ FIELD_RESERVED_VALUE_REG(lv_permissions_r, "lv_permissions reserved values (read-only)")
+ FIELD_RESERVED_VALUE_REG(lv_permissions_r_override, "lv_permissions reserved values (read-only-override)")
+ FIELD_RESERVED_VALUE_REG(lv_read_ahead, "lv_read_ahead reserved values (auto)")
{0, NULL, NULL}
};
-static const char *_str_unknown = "unknown";
-static const char *_str_minus_one = "-1";
-
static int _field_set_value(struct dm_report_field *field, const void *data, const void *sort)
{
dm_report_field_set_value(field, data, sort);
@@ -204,6 +163,36 @@ static int _field_set_value(struct dm_report_field *field, const void *data, con
/*
* Data-munging functions to prepare each data type for display and sorting
*/
+
+/*
+ * Display either "0"/"1" or ""/"word" based on bin_value,
+ * cmd->report_binary_values_as_numeric selects the mode to use.
+*/
+static int _binary_disp(struct dm_report *rh, struct dm_pool *mem __attribute__((unused)),
+ struct dm_report_field *field, int bin_value, const char *word,
+ void *private)
+{
+ const struct cmd_context *cmd = (const struct cmd_context *) private;
+
+ if (cmd->report_binary_values_as_numeric)
+ /* "0"/"1" */
+ return _field_set_value(field, bin_value ? _str_one : _str_zero, bin_value ? &_one64 : &_zero64);
+ else
+ /* blank/"word" */
+ return _field_set_value(field, bin_value ? word : "", bin_value ? &_one64 : &_zero64);
+}
+
+static int _binary_undef_disp(struct dm_report *rh, struct dm_pool *mem __attribute__((unused)),
+ struct dm_report_field *field, void *private)
+{
+ const struct cmd_context *cmd = (const struct cmd_context *) private;
+
+ if (cmd->report_binary_values_as_numeric)
+ return _field_set_value(field, FIRST_NAME(number_undef_64), &_reserved_number_undef_64);
+ else
+ return _field_set_value(field, _str_unknown, &_reserved_number_undef_64);
+}
+
static int _string_disp(struct dm_report *rh, struct dm_pool *mem __attribute__((unused)),
struct dm_report_field *field,
const void *data, void *private __attribute__((unused)))
@@ -1296,41 +1285,12 @@ static int _lvactive_disp(struct dm_report *rh, struct dm_pool *mem,
/* PV/VG/LV Attributes */
-/*
- * Display either "0"/"1" or ""/"word" based on bin_value,
- * cmd->report_binary_values_as_numeric selects the mode to use.
-*/
-static int _binary_disp(struct dm_report *rh, struct dm_pool *mem __attribute__((unused)),
- struct dm_report_field *field, int bin_value, const char *word,
- void *private)
-{
- const struct cmd_context *cmd = (const struct cmd_context *) private;
-
- if (cmd->report_binary_values_as_numeric)
- /* "0"/"1" */
- return _field_set_value(field, bin_value ? _str_one : _str_zero, bin_value ? &_one64 : &_zero64);
- else
- /* blank/"word" */
- return _field_set_value(field, bin_value ? word : "", bin_value ? &_one64 : &_zero64);
-}
-
-static int _binary_undef_disp(struct dm_report *rh, struct dm_pool *mem __attribute__((unused)),
- struct dm_report_field *field, void *private)
-{
- const struct cmd_context *cmd = (const struct cmd_context *) private;
-
- if (cmd->report_binary_values_as_numeric)
- return _field_set_value(field, _str_minus_one, &_reserved_number_undef_64);
- else
- return _field_set_value(field, _str_unknown, &_reserved_number_undef_64);
-}
-
static int _pvallocatable_disp(struct dm_report *rh, struct dm_pool *mem,
struct dm_report_field *field,
const void *data, void *private)
{
int allocatable = (((const struct physical_volume *) data)->status & ALLOCATABLE_PV) != 0;
- return _binary_disp(rh, mem, field, allocatable, "allocatable", private);
+ return _binary_disp(rh, mem, field, allocatable, FIRST_NAME(pv_allocatable), private);
}
static int _pvexported_disp(struct dm_report *rh, struct dm_pool *mem,
@@ -1338,7 +1298,7 @@ static int _pvexported_disp(struct dm_report *rh, struct dm_pool *mem,
const void *data, void *private)
{
int exported = (((const struct physical_volume *) data)->status & EXPORTED_VG) != 0;
- return _binary_disp(rh, mem, field, exported, "exported", private);
+ return _binary_disp(rh, mem, field, exported, FIRST_NAME(pv_exported), private);
}
static int _pvmissing_disp(struct dm_report *rh, struct dm_pool *mem,
@@ -1346,14 +1306,15 @@ static int _pvmissing_disp(struct dm_report *rh, struct dm_pool *mem,
const void *data, void *private)
{
int missing = (((const struct physical_volume *) data)->status & MISSING_PV) != 0;
- return _binary_disp(rh, mem, field, missing, "missing", private);
+ return _binary_disp(rh, mem, field, missing, FIRST_NAME(pv_missing), private);
}
static int _vgpermissions_disp(struct dm_report *rh, struct dm_pool *mem,
struct dm_report_field *field,
const void *data, void *private)
{
- const char *perms = ((const struct volume_group *) data)->status & LVM_WRITE ? "writeable" : "read-only";
+ const char *perms = ((const struct volume_group *) data)->status & LVM_WRITE ? FIRST_NAME(vg_permissions_rw)
+ : FIRST_NAME(vg_permissions_r);
return _string_disp(rh, mem, field, &perms, private);
}
@@ -1362,7 +1323,7 @@ static int _vgextendable_disp(struct dm_report *rh, struct dm_pool *mem,
const void *data, void *private)
{
int extendable = (vg_is_resizeable((const struct volume_group *) data)) != 0;
- return _binary_disp(rh, mem, field, extendable, "extendable", private);
+ return _binary_disp(rh, mem, field, extendable, FIRST_NAME(vg_extendable), private);
}
static int _vgexported_disp(struct dm_report *rh, struct dm_pool *mem,
@@ -1370,7 +1331,7 @@ static int _vgexported_disp(struct dm_report *rh, struct dm_pool *mem,
const void *data, void *private)
{
int exported = (vg_is_exported((const struct volume_group *) data)) != 0;
- return _binary_disp(rh, mem, field, exported, "exported", private);
+ return _binary_disp(rh, mem, field, exported, FIRST_NAME(vg_exported), private);
}
static int _vgpartial_disp(struct dm_report *rh, struct dm_pool *mem,
@@ -1378,7 +1339,7 @@ static int _vgpartial_disp(struct dm_report *rh, struct dm_pool *mem,
const void *data, void *private)
{
int partial = (vg_missing_pv_count((const struct volume_group *) data)) != 0;
- return _binary_disp(rh, mem, field, partial, "partial", private);
+ return _binary_disp(rh, mem, field, partial, FIRST_NAME(vg_partial), private);
}
static int _vgallocationpolicy_disp(struct dm_report *rh, struct dm_pool *mem,
@@ -1394,7 +1355,7 @@ static int _vgclustered_disp(struct dm_report *rh, struct dm_pool *mem,
const void *data, void *private)
{
int clustered = (vg_is_clustered((const struct volume_group *) data)) != 0;
- return _binary_disp(rh, mem, field, clustered, "clustered", private);
+ return _binary_disp(rh, mem, field, clustered, FIRST_NAME(vg_clustered), private);
}
static int _lvvolumetype_disp(struct dm_report *rh, struct dm_pool *mem,
@@ -1417,7 +1378,7 @@ static int _lvinitialimagesync_disp(struct dm_report *rh, struct dm_pool *mem,
else
initial_image_sync = 0;
- return _binary_disp(rh, mem, field, initial_image_sync, "initial image sync", private);
+ return _binary_disp(rh, mem, field, initial_image_sync, FIRST_NAME(lv_initial_image_sync), private);
}
static int _lvimagesynced_disp(struct dm_report *rh, struct dm_pool *mem,
@@ -1434,7 +1395,7 @@ static int _lvimagesynced_disp(struct dm_report *rh, struct dm_pool *mem,
else
image_synced = 0;
- return _binary_disp(rh, mem, field, image_synced, "image synced", private);
+ return _binary_disp(rh, mem, field, image_synced, FIRST_NAME(lv_image_synced), private);
}
static int _lvmerging_disp(struct dm_report *rh, struct dm_pool *mem,
@@ -1453,7 +1414,7 @@ static int _lvmerging_disp(struct dm_report *rh, struct dm_pool *mem,
else
merging = 0;
- return _binary_disp(rh, mem, field, merging, "merging", private);
+ return _binary_disp(rh, mem, field, merging, FIRST_NAME(lv_merging), private);
}
static int _lvconverting_disp(struct dm_report *rh, struct dm_pool *mem,
@@ -1474,11 +1435,11 @@ static int _lvpermissions_disp(struct dm_report *rh, struct dm_pool *mem,
if (!(lvi->lv->status & PVMOVE)) {
if (lvi->lv->status & LVM_WRITE) {
if (lvi->info->read_only)
- perms = "read-only-override";
+ perms = FIRST_NAME(lv_permissions_r_override);
else
- perms = "writeable";
+ perms = FIRST_NAME(lv_permissions_rw);
} else if (lvi->lv->status & LVM_READ)
- perms = "read-only";
+ perms = FIRST_NAME(lv_permissions_r);
else
perms = _str_unknown;
}
@@ -1499,7 +1460,7 @@ static int _lvallocationlocked_disp(struct dm_report *rh, struct dm_pool *mem,
const void *data, void *private)
{
int alloc_locked = (((const struct logical_volume *) data)->status & LOCKED) != 0;
- return _binary_disp(rh, mem, field, alloc_locked, "allocation locked", private);
+ return _binary_disp(rh, mem, field, alloc_locked, FIRST_NAME(lv_allocation_locked), private);
}
static int _lvfixedminor_disp(struct dm_report *rh, struct dm_pool *mem,
@@ -1507,7 +1468,7 @@ static int _lvfixedminor_disp(struct dm_report *rh, struct dm_pool *mem,
const void *data, void *private)
{
int fixed_minor = (((const struct logical_volume *) data)->status & FIXED_MINOR) != 0;
- return _binary_disp(rh, mem, field, fixed_minor, "fixed minor", private);
+ return _binary_disp(rh, mem, field, fixed_minor, FIRST_NAME(lv_fixed_minor), private);
}
static int _lvmergefailed_disp(struct dm_report *rh, struct dm_pool *mem,
@@ -1522,7 +1483,7 @@ static int _lvmergefailed_disp(struct dm_report *rh, struct dm_pool *mem,
return _field_set_value(field, _str_unknown, &_reserved_number_undef_64);
merge_failed = snap_percent == LVM_PERCENT_MERGE_FAILED;
- return _binary_disp(rh, mem, field, merge_failed, "merge failed", private);
+ return _binary_disp(rh, mem, field, merge_failed, FIRST_NAME(lv_merge_failed), private);
}
static int _lvsnapshotinvalid_disp(struct dm_report *rh, struct dm_pool *mem,
@@ -1537,7 +1498,7 @@ static int _lvsnapshotinvalid_disp(struct dm_report *rh, struct dm_pool *mem,
return _field_set_value(field, _str_unknown, &_reserved_number_undef_64);
snap_invalid = !lv_snapshot_percent(lv, &snap_percent) || snap_percent == DM_PERCENT_INVALID;
- return _binary_disp(rh, mem, field, snap_invalid, "snapshot invalid", private);
+ return _binary_disp(rh, mem, field, snap_invalid, FIRST_NAME(lv_snapshot_invalid), private);
}
static int _lvsuspended_disp(struct dm_report *rh, struct dm_pool *mem,
@@ -1547,7 +1508,7 @@ static int _lvsuspended_disp(struct dm_report *rh, struct dm_pool *mem,
const struct lv_with_info *lvi = (const struct lv_with_info *) data;
if (lvi->info->exists)
- return _binary_disp(rh, mem, field, lvi->info->suspended, "suspended", private);
+ return _binary_disp(rh, mem, field, lvi->info->suspended, FIRST_NAME(lv_suspended), private);
return _binary_undef_disp(rh, mem, field, private);
}
@@ -1559,7 +1520,7 @@ static int _lvlivetable_disp(struct dm_report *rh, struct dm_pool *mem,
const struct lv_with_info *lvi = (const struct lv_with_info *) data;
if (lvi->info->exists)
- return _binary_disp(rh, mem, field, lvi->info->live_table, "live table present", private);
+ return _binary_disp(rh, mem, field, lvi->info->live_table, FIRST_NAME(lv_live_table), private);
return _binary_undef_disp(rh, mem, field, private);
}
@@ -1571,7 +1532,7 @@ static int _lvinactivetable_disp(struct dm_report *rh, struct dm_pool *mem,
const struct lv_with_info *lvi = (const struct lv_with_info *) data;
if (lvi->info->exists)
- return _binary_disp(rh, mem, field, lvi->info->inactive_table, "inactive table present", private);
+ return _binary_disp(rh, mem, field, lvi->info->inactive_table, FIRST_NAME(lv_inactive_table), private);
return _binary_undef_disp(rh, mem, field, private);
}
@@ -1583,7 +1544,7 @@ static int _lvdeviceopen_disp(struct dm_report *rh, struct dm_pool *mem,
const struct lv_with_info *lvi = (const struct lv_with_info *) data;
if (lvi->info->exists)
- return _binary_disp(rh, mem, field, lvi->info->open_count, "open", private);
+ return _binary_disp(rh, mem, field, lvi->info->open_count, FIRST_NAME(lv_device_open), private);
return _binary_undef_disp(rh, mem, field, private);
}
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=1a05862732d8e809…
Commit: 1a05862732d8e809f888313c546e97381c4e1f49
Parent: f76879ba440aa93f2e237335fe2cca6951a636bf
Author: Peter Rajnoha <prajnoha(a)redhat.com>
AuthorDate: Tue Jul 8 12:15:14 2014 +0200
Committer: Peter Rajnoha <prajnoha(a)redhat.com>
CommitterDate: Tue Jul 8 16:16:02 2014 +0200
report: report unknown/-1 for binary fields with unknown value
Also respect --binary arg and/or report/binary_values_as_numeric
when displaying unknown values. If textual form is used, use "unknown",
if numeric value is used, use "-1" (which we already use to denote
unknown numeric values in other reports like lv_kernel_major and
lv_kernel_minor).
---
lib/report/report.c | 20 ++++++++++++++++----
1 files changed, 16 insertions(+), 4 deletions(-)
diff --git a/lib/report/report.c b/lib/report/report.c
index 7cc3599..4ec75aa 100644
--- a/lib/report/report.c
+++ b/lib/report/report.c
@@ -192,6 +192,7 @@ static const struct dm_report_reserved_value _report_reserved_values[] = {
};
static const char *_str_unknown = "unknown";
+static const char *_str_minus_one = "-1";
static int _field_set_value(struct dm_report_field *field, const void *data, const void *sort)
{
@@ -1313,6 +1314,17 @@ static int _binary_disp(struct dm_report *rh, struct dm_pool *mem __attribute__(
return _field_set_value(field, bin_value ? word : "", bin_value ? &_one64 : &_zero64);
}
+static int _binary_undef_disp(struct dm_report *rh, struct dm_pool *mem __attribute__((unused)),
+ struct dm_report_field *field, void *private)
+{
+ const struct cmd_context *cmd = (const struct cmd_context *) private;
+
+ if (cmd->report_binary_values_as_numeric)
+ return _field_set_value(field, _str_minus_one, &_reserved_number_undef_64);
+ else
+ return _field_set_value(field, _str_unknown, &_reserved_number_undef_64);
+}
+
static int _pvallocatable_disp(struct dm_report *rh, struct dm_pool *mem,
struct dm_report_field *field,
const void *data, void *private)
@@ -1537,7 +1549,7 @@ static int _lvsuspended_disp(struct dm_report *rh, struct dm_pool *mem,
if (lvi->info->exists)
return _binary_disp(rh, mem, field, lvi->info->suspended, "suspended", private);
- return _field_set_value(field, _str_unknown, &_reserved_number_undef_64);
+ return _binary_undef_disp(rh, mem, field, private);
}
static int _lvlivetable_disp(struct dm_report *rh, struct dm_pool *mem,
@@ -1549,7 +1561,7 @@ static int _lvlivetable_disp(struct dm_report *rh, struct dm_pool *mem,
if (lvi->info->exists)
return _binary_disp(rh, mem, field, lvi->info->live_table, "live table present", private);
- return _field_set_value(field, _str_unknown, &_reserved_number_undef_64);
+ return _binary_undef_disp(rh, mem, field, private);
}
static int _lvinactivetable_disp(struct dm_report *rh, struct dm_pool *mem,
@@ -1561,7 +1573,7 @@ static int _lvinactivetable_disp(struct dm_report *rh, struct dm_pool *mem,
if (lvi->info->exists)
return _binary_disp(rh, mem, field, lvi->info->inactive_table, "inactive table present", private);
- return _field_set_value(field, _str_unknown, &_reserved_number_undef_64);
+ return _binary_undef_disp(rh, mem, field, private);
}
static int _lvdeviceopen_disp(struct dm_report *rh, struct dm_pool *mem,
@@ -1573,7 +1585,7 @@ static int _lvdeviceopen_disp(struct dm_report *rh, struct dm_pool *mem,
if (lvi->info->exists)
return _binary_disp(rh, mem, field, lvi->info->open_count, "open", private);
- return _field_set_value(field, _str_unknown, &_reserved_number_undef_64);
+ return _binary_undef_disp(rh, mem, field, private);
}
static int _lvtargettype_disp(struct dm_report *rh, struct dm_pool *mem,
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=f76879ba440aa93f…
Commit: f76879ba440aa93f2e237335fe2cca6951a636bf
Parent: f6001465efe064611920b30f5b913c1d09004ded
Author: Peter Rajnoha <prajnoha(a)redhat.com>
AuthorDate: Tue Jul 8 10:22:59 2014 +0200
Committer: Peter Rajnoha <prajnoha(a)redhat.com>
CommitterDate: Tue Jul 8 10:22:59 2014 +0200
conf: comment out devices/preferred_names and filter setting
This avoids creating void matchers which have no effect anyway and
they just use resources. Also, it makes lvm dumpconfig --type diff
to mark these settings properly as not being different from defaults
(where by default, devices/preferred_names as well as devices/filter
are void).
Also, add a few comments about builtin rules used to select device
alias in case preferred_names is not defined or it doesn't match
any of device aliases.
---
conf/example.conf.in | 23 +++++++++++++++++++++--
1 files changed, 21 insertions(+), 2 deletions(-)
diff --git a/conf/example.conf.in b/conf/example.conf.in
index 162770a..e1afbb6 100644
--- a/conf/example.conf.in
+++ b/conf/example.conf.in
@@ -53,11 +53,30 @@ devices {
# same block device and the tools need to display a name for device,
# all the pathnames are matched against each item in the following
# list of regular expressions in turn and the first match is used.
- preferred_names = [ ]
+
+ # By default no preferred names are defined.
+ # preferred_names = [ ]
# Try to avoid using undescriptive /dev/dm-N names, if present.
# preferred_names = [ "^/dev/mpath/", "^/dev/mapper/mpath", "^/dev/[hs]d" ]
+ # In case no prefererred name matches or if preferred_names are not
+ # defined at all, builtin rules are used to determine the preference.
+ #
+ # The first builtin rule checks path prefixes and it gives preference
+ # based on this ordering (where "dev" depends on devices/dev setting):
+ # /dev/mapper > /dev/disk > /dev/dm-* > /dev/block
+ #
+ # If the ordering above cannot be applied, the path with fewer slashes
+ # gets preference then.
+ #
+ # If the number of slashes is the same, a symlink gets preference.
+ #
+ # Finally, if all the rules mentioned above are not applicable,
+ # lexicographical order is used over paths and the smallest one
+ # of all gets preference.
+
+
# A filter that tells LVM2 to only use a restricted set of devices.
# The filter consists of an array of regular expressions. These
# expressions can be delimited by a character of your choice, and
@@ -84,7 +103,7 @@ devices {
# lvmetad is used" comment that is attached to global/use_lvmetad setting.
# By default we accept every block device:
- filter = [ "a/.*/" ]
+ # filter = [ "a/.*/" ]
# Exclude the cdrom drive
# filter = [ "r|/dev/cdrom|" ]
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=f6001465efe06461…
Commit: f6001465efe064611920b30f5b913c1d09004ded
Parent: 4b65d7ec72869ba7e70a1c93567ef0f271ed395e
Author: Peter Rajnoha <prajnoha(a)redhat.com>
AuthorDate: Mon Jul 7 17:02:06 2014 +0200
Committer: Peter Rajnoha <prajnoha(a)redhat.com>
CommitterDate: Mon Jul 7 17:02:06 2014 +0200
lv_manip: pool-metadata-spare is just a spare LV, not tightly bound to thin or cache
---
lib/metadata/lv_manip.c | 10 +++-------
1 files changed, 3 insertions(+), 7 deletions(-)
diff --git a/lib/metadata/lv_manip.c b/lib/metadata/lv_manip.c
index fc98b2a..c55b31f 100644
--- a/lib/metadata/lv_manip.c
+++ b/lib/metadata/lv_manip.c
@@ -94,12 +94,11 @@ typedef enum {
LV_TYPE_THIN_POOL,
LV_TYPE_THIN_POOL_DATA,
LV_TYPE_THIN_POOL_METADATA,
- LV_TYPE_THIN_POOL_METADATA_SPARE,
LV_TYPE_CACHE,
LV_TYPE_CACHE_POOL,
LV_TYPE_CACHE_POOL_DATA,
LV_TYPE_CACHE_POOL_METADATA,
- LV_TYPE_CACHE_POOL_METADATA_SPARE,
+ LV_TYPE_POOL_METADATA_SPARE,
LV_TYPE_VIRTUAL,
LV_TYPE_RAID,
LV_TYPE_RAID_IMAGE,
@@ -122,12 +121,11 @@ static const char *_lv_type_names[] = {
[LV_TYPE_THIN_POOL] = "thin-pool",
[LV_TYPE_THIN_POOL_DATA] = "thin-pool-data",
[LV_TYPE_THIN_POOL_METADATA] = "thin-pool-metadata",
- [LV_TYPE_THIN_POOL_METADATA_SPARE] = "thin-pool-metadata-spare",
[LV_TYPE_CACHE] = "cache",
[LV_TYPE_CACHE_POOL] = "cache-pool",
[LV_TYPE_CACHE_POOL_DATA] = "cache-pool-data",
[LV_TYPE_CACHE_POOL_METADATA] = "cache-pool-metadata",
- [LV_TYPE_CACHE_POOL_METADATA_SPARE] = "cache-pool-metadata-spare",
+ [LV_TYPE_POOL_METADATA_SPARE] = "pool-metadata-spare",
[LV_TYPE_VIRTUAL] = "virtual",
[LV_TYPE_RAID] = "raid",
[LV_TYPE_RAID_IMAGE] = "raid-image",
@@ -161,7 +159,7 @@ static lv_type_t _get_lv_type(const struct logical_volume *lv)
else if (lv_is_thin_pool_metadata(lv))
type = LV_TYPE_THIN_POOL_METADATA;
else if (lv_is_pool_metadata_spare(lv))
- type = LV_TYPE_THIN_POOL_METADATA_SPARE;
+ type = LV_TYPE_POOL_METADATA_SPARE;
else if (lv_is_cache(lv))
type = LV_TYPE_CACHE;
else if (lv_is_cache_pool(lv))
@@ -170,8 +168,6 @@ static lv_type_t _get_lv_type(const struct logical_volume *lv)
type = LV_TYPE_CACHE_POOL_DATA;
else if (lv_is_cache_pool_metadata(lv))
type = LV_TYPE_CACHE_POOL_METADATA;
- else if (lv_is_pool_metadata_spare(lv))
- type = LV_TYPE_CACHE_POOL_METADATA_SPARE;
else if (lv_is_virtual(lv))
type = LV_TYPE_VIRTUAL;
else if (lv_is_raid(lv))
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=4b65d7ec72869ba7…
Commit: 4b65d7ec72869ba7e70a1c93567ef0f271ed395e
Parent: 9e1c4a3818fa2af76b7b7890939c9e7ec9cb6818
Author: Peter Rajnoha <prajnoha(a)redhat.com>
AuthorDate: Mon Jul 7 16:52:43 2014 +0200
Committer: Peter Rajnoha <prajnoha(a)redhat.com>
CommitterDate: Mon Jul 7 16:52:43 2014 +0200
WHATS_NEW: commits a473435..7021c8f1
---
WHATS_NEW | 5 +++++
WHATS_NEW_DM | 1 +
2 files changed, 6 insertions(+), 0 deletions(-)
diff --git a/WHATS_NEW b/WHATS_NEW
index ab36cb3..d4649e4 100644
--- a/WHATS_NEW
+++ b/WHATS_NEW
@@ -1,5 +1,10 @@
Version 2.02.108 -
=================================
+ Recognize "auto"/"unmanaged" values in selection for appropriate fields only.
+ Add report/binary_values_as_numeric lvm.conf option for binary values as 0/1.
+ Add --binary arg to pvs,vgs,lvs and {pv,vg,lv}display -C for 0/1 on reports.
+ Add separate reporting fields for each each {pv,vg,lv}_attr bit.
+ Separate LV device status reporting fields out of LV fields.
Fix regression causing PVs not in VGs to be marked as allocatable (2.02.59).
Fix VG component of lvid in vgsplit/vgmerge and check in vg_validate.
Add lv_full_name, lv_parent and lv_dm_path fields to reports.
diff --git a/WHATS_NEW_DM b/WHATS_NEW_DM
index f25fa92..852d313 100644
--- a/WHATS_NEW_DM
+++ b/WHATS_NEW_DM
@@ -1,5 +1,6 @@
Version 1.02.87 -
================================
+ Add dm_report_field_reserved_value for per-field reserved value definition.
Version 1.02.86 - 23rd June 2014
================================
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=9e1c4a3818fa2af7…
Commit: 9e1c4a3818fa2af76b7b7890939c9e7ec9cb6818
Parent: 83b55c2dfba12db95fa5247039470278741372ab
Author: Peter Rajnoha <prajnoha(a)redhat.com>
AuthorDate: Mon Jul 7 16:28:13 2014 +0200
Committer: Peter Rajnoha <prajnoha(a)redhat.com>
CommitterDate: Mon Jul 7 16:28:13 2014 +0200
report: addendum for previous commit
Really call lv_info only if needed!
---
tools/reporter.c | 5 +++--
1 files changed, 3 insertions(+), 2 deletions(-)
diff --git a/tools/reporter.c b/tools/reporter.c
index 5e9fb24..0780283 100644
--- a/tools/reporter.c
+++ b/tools/reporter.c
@@ -91,7 +91,7 @@ static int _do_pvsegs_sub_single(struct cmd_context *cmd,
{
int ret = ECMD_PROCESSED;
struct lv_segment *seg = pvseg->lvseg;
- struct lvinfo lvinfo = {.exists = 0};
+ struct lvinfo lvinfo;
struct volume_group _free_vg = {
.cmd = cmd,
@@ -136,7 +136,8 @@ static int _do_pvsegs_sub_single(struct cmd_context *cmd,
dm_list_init(&_free_logical_volume.segs_using_this_lv);
dm_list_init(&_free_logical_volume.snapshot_segs);
- if (seg && !lv_info(cmd, seg->lv, 0, &lvinfo, 1, 1)) {
+ lvinfo.exists = 0;
+ if (seg && lv_info_needed && !lv_info(cmd, seg->lv, 0, &lvinfo, 1, 1)) {
ret = ECMD_FAILED;
goto_out;
}
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=83b55c2dfba12db9…
Commit: 83b55c2dfba12db95fa5247039470278741372ab
Parent: 6dc7b783c80c6834aa724df49b5d47b9b5601506
Author: Peter Rajnoha <prajnoha(a)redhat.com>
AuthorDate: Mon Jul 7 15:54:13 2014 +0200
Committer: Peter Rajnoha <prajnoha(a)redhat.com>
CommitterDate: Mon Jul 7 15:54:13 2014 +0200
report: fix segfault while reporting PV/LV segment fields together with LV fields needeing device status (LVSINFO)
There was missing lv_info call for situations where there were
mixed PV/LV segment fields together with LVSINFO fields which
require extra lv_info call for LV device status. This ended up
with NULL lvinfo passed to the field reporting functions, hence
the segfault.
---
tools/reporter.c | 79 +++++++++++++++++++++++++++++++++++++++++++++++------
1 files changed, 70 insertions(+), 9 deletions(-)
diff --git a/tools/reporter.c b/tools/reporter.c
index 524d6c4..5e9fb24 100644
--- a/tools/reporter.c
+++ b/tools/reporter.c
@@ -70,12 +70,28 @@ static int _segs_single(struct cmd_context *cmd __attribute__((unused)),
return ECMD_PROCESSED;
}
-static int _pvsegs_sub_single(struct cmd_context *cmd,
- struct volume_group *vg,
- struct pv_segment *pvseg, void *handle)
+
+static int _segs_with_lv_info_single(struct cmd_context *cmd __attribute__((unused)),
+ struct lv_segment *seg, void *handle)
+{
+ struct lvinfo lvinfo;
+
+ if (!lv_info(cmd, seg->lv, 0, &lvinfo, 1, 1) ||
+ !report_object(handle, seg->lv->vg, seg->lv, NULL, seg, NULL, &lvinfo, NULL))
+ return_ECMD_FAILED;
+
+ return ECMD_PROCESSED;
+}
+
+static int _do_pvsegs_sub_single(struct cmd_context *cmd,
+ struct volume_group *vg,
+ struct pv_segment *pvseg,
+ int lv_info_needed,
+ void *handle)
{
int ret = ECMD_PROCESSED;
struct lv_segment *seg = pvseg->lvseg;
+ struct lvinfo lvinfo = {.exists = 0};
struct volume_group _free_vg = {
.cmd = cmd,
@@ -120,8 +136,13 @@ static int _pvsegs_sub_single(struct cmd_context *cmd,
dm_list_init(&_free_logical_volume.segs_using_this_lv);
dm_list_init(&_free_logical_volume.snapshot_segs);
+ if (seg && !lv_info(cmd, seg->lv, 0, &lvinfo, 1, 1)) {
+ ret = ECMD_FAILED;
+ goto_out;
+ }
+
if (!report_object(handle, vg, seg ? seg->lv : &_free_logical_volume, pvseg->pv,
- seg ? : &_free_lv_segment, pvseg, NULL, pv_label(pvseg->pv))) {
+ seg ? : &_free_lv_segment, pvseg, &lvinfo, pv_label(pvseg->pv))) {
ret = ECMD_FAILED;
goto_out;
}
@@ -130,6 +151,21 @@ static int _pvsegs_sub_single(struct cmd_context *cmd,
return ret;
}
+static int _pvsegs_sub_single(struct cmd_context *cmd,
+ struct volume_group *vg,
+ struct pv_segment *pvseg, void *handle)
+{
+ return _do_pvsegs_sub_single(cmd, vg, pvseg, 0, handle);
+}
+
+static int _pvsegs_with_lv_info_sub_single(struct cmd_context *cmd,
+ struct volume_group *vg,
+ struct pv_segment *pvseg,
+ void *handle)
+{
+ return _do_pvsegs_sub_single(cmd, vg, pvseg, 1, handle);
+}
+
static int _lvsegs_single(struct cmd_context *cmd, struct logical_volume *lv,
void *handle)
{
@@ -139,6 +175,16 @@ static int _lvsegs_single(struct cmd_context *cmd, struct logical_volume *lv,
return process_each_segment_in_lv(cmd, lv, handle, _segs_single);
}
+static int _lvsegs_with_lv_info_single(struct cmd_context *cmd,
+ struct logical_volume *lv,
+ void *handle)
+{
+ if (!arg_count(cmd, all_ARG) && !lv_is_visible(lv))
+ return ECMD_PROCESSED;
+
+ return process_each_segment_in_lv(cmd, lv, handle, _segs_with_lv_info_single);
+}
+
static int _pvsegs_single(struct cmd_context *cmd, struct volume_group *vg,
struct physical_volume *pv, void *handle)
{
@@ -146,6 +192,15 @@ static int _pvsegs_single(struct cmd_context *cmd, struct volume_group *vg,
_pvsegs_sub_single);
}
+static int _pvsegs_with_lv_info_single(struct cmd_context *cmd,
+ struct volume_group *vg,
+ struct physical_volume *pv,
+ void *handle)
+{
+ return process_each_segment_in_pv(cmd, vg, pv, handle,
+ _pvsegs_with_lv_info_sub_single);
+}
+
static int _pvs_single(struct cmd_context *cmd, struct volume_group *vg,
struct physical_volume *pv, void *handle)
{
@@ -253,7 +308,7 @@ static int _report(struct cmd_context *cmd, int argc, char **argv,
int r = ECMD_PROCESSED;
int aligned, buffered, headings, field_prefixes, quoted;
int columns_as_rows;
- unsigned args_are_pvs;
+ unsigned args_are_pvs, lv_info_needed;
aligned = find_config_tree_bool(cmd, report_aligned_CFG, NULL);
buffered = find_config_tree_bool(cmd, report_buffered_CFG, NULL);
@@ -371,12 +426,15 @@ static int _report(struct cmd_context *cmd, int argc, char **argv,
columns_as_rows, selection)))
return_ECMD_FAILED;
+ /* Do we need lv_info to be called for LV device status? */
+ lv_info_needed = (report_type & LVSINFO) ? 1 : 0;
+
/* Ensure options selected are compatible */
if (report_type & SEGS)
report_type |= LVS;
if (report_type & PVSEGS)
report_type |= PVS;
- if ((report_type & LVS) && (report_type & (PVS | LABEL)) && !args_are_pvs) {
+ if ((report_type & (LVS | LVSINFO)) && (report_type & (PVS | LABEL)) && !args_are_pvs) {
log_error("Can't report LV and PV fields at the same time");
dm_report_free(report_handle);
return ECMD_FAILED;
@@ -384,7 +442,7 @@ static int _report(struct cmd_context *cmd, int argc, char **argv,
/* Change report type if fields specified makes this necessary */
if ((report_type & PVSEGS) ||
- ((report_type & (PVS | LABEL)) && (report_type & LVS)))
+ ((report_type & (PVS | LABEL)) && (report_type & (LVS | LVSINFO))))
report_type = PVSEGS;
else if ((report_type & LABEL) && (report_type & VGS))
report_type = PVS;
@@ -427,12 +485,15 @@ static int _report(struct cmd_context *cmd, int argc, char **argv,
break;
case SEGS:
r = process_each_lv(cmd, argc, argv, 0, report_handle,
- &_lvsegs_single);
+ lv_info_needed ? &_lvsegs_with_lv_info_single
+ : &_lvsegs_single);
break;
case PVSEGS:
if (args_are_pvs)
r = process_each_pv(cmd, argc, argv, NULL, 0,
- 0, report_handle, &_pvsegs_single);
+ 0, report_handle,
+ lv_info_needed ? &_pvsegs_with_lv_info_single
+ : &_pvsegs_single);
else
r = process_each_vg(cmd, argc, argv, 0,
report_handle, &_pvsegs_in_vg);
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=6dc7b783c80c6834…
Commit: 6dc7b783c80c6834aa724df49b5d47b9b5601506
Parent: 7021c8f1a483d91a58ce2abc52583e73e2910da7
Author: Peter Rajnoha <prajnoha(a)redhat.com>
AuthorDate: Mon Jul 7 13:58:42 2014 +0200
Committer: Peter Rajnoha <prajnoha(a)redhat.com>
CommitterDate: Mon Jul 7 14:07:21 2014 +0200
metadata: fix regression causing PVs not in VGs to be marked as allocatable
If the PV is not yet in a VG, it's not allocatable.
A regression introduced by commit 0283c439ec2dc195184a12f86a060b271476aae0
(_pv_create) and later commit a7ca10151795b4c4ed6fa4bf7d3d6b1a687430b0
(pv_read).
---
WHATS_NEW | 1 +
lib/metadata/metadata.c | 1 -
test/shell/pvchange-usage.sh | 11 +++++++++++
3 files changed, 12 insertions(+), 1 deletions(-)
diff --git a/WHATS_NEW b/WHATS_NEW
index 5a1e214..ab36cb3 100644
--- a/WHATS_NEW
+++ b/WHATS_NEW
@@ -1,5 +1,6 @@
Version 2.02.108 -
=================================
+ Fix regression causing PVs not in VGs to be marked as allocatable (2.02.59).
Fix VG component of lvid in vgsplit/vgmerge and check in vg_validate.
Add lv_full_name, lv_parent and lv_dm_path fields to reports.
Change lv_path field to suppress devices that never appear in /dev/vg.
diff --git a/lib/metadata/metadata.c b/lib/metadata/metadata.c
index 50d44ec..2d69714 100644
--- a/lib/metadata/metadata.c
+++ b/lib/metadata/metadata.c
@@ -1599,7 +1599,6 @@ static struct physical_volume *_alloc_pv(struct dm_pool *mem, struct device *dev
}
pv->dev = dev;
- pv->status = ALLOCATABLE_PV;
dm_list_init(&pv->tags);
dm_list_init(&pv->segments);
diff --git a/test/shell/pvchange-usage.sh b/test/shell/pvchange-usage.sh
index ac63aec..72ab16b 100644
--- a/test/shell/pvchange-usage.sh
+++ b/test/shell/pvchange-usage.sh
@@ -19,6 +19,17 @@ check_changed_uuid_() {
aux prepare_pvs 4
+# check 'allocatable' pv attribute
+pvcreate $dev1
+check pv_field "$dev1" pv_attr ---
+vgcreate $vg1 "$dev1"
+check pv_field "$dev1" pv_attr a--
+pvchange --allocatable n "$dev1"
+check pv_field "$dev1" pv_attr ---
+vgremove -ff $vg1
+not pvchange --allocatable y "$dev1"
+pvremove -ff "$dev1"
+
for mda in 0 1 2
do
# "setup pv with metadatacopies = $mda"
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=7021c8f1a483d91a…
Commit: 7021c8f1a483d91a58ce2abc52583e73e2910da7
Parent: 0956fd230fea550707acb2889223438996102de4
Author: Peter Rajnoha <prajnoha(a)redhat.com>
AuthorDate: Fri Jul 4 12:08:52 2014 +0200
Committer: Peter Rajnoha <prajnoha(a)redhat.com>
CommitterDate: Fri Jul 4 15:50:50 2014 +0200
report: define reserved values/synonyms for some attribute fields
All binary attr fields have synonyms so selection criteria can use
either 0/1 or words to match against the field value (base type
for these binary fields is numeric one - DM_REPORT_FIELD_TYPE_NUMBER
so words are registered as reserved values):
pv_allocatable - "allocatable"
pv_exported - "exported"
pv_missing - "missing"
vg_extendable - "extendable"
vg_exported - "exported"
vg_partial - "partial"
vg_clustered - "clustered"
lv_initial_image_sync - "initial image sync", "sync"
lv_image_synced_names - "image synced", "synced"
lv_merging_names - "merging"
lv_converting_names - "converting"
lv_allocation_locked - "allocation locked", "locked"
lv_fixed_minor - "fixed minor", "fixed"
lv_merge_failed - "merge failed", "failed"
For example, these three are all equivalent:
$ lvs -o name,fixed_minor -S 'fixed_minor=fixed'
LV FixMin
lvol8 fixed minor
$ lvs -o name,fixed_minor -S 'fixed_minor="fixed minor"'
LV FixMin
lvol8 fixed minor
$ lvs -o name,fixed_minor -S 'fixed_minor=1'
LV FixMin
lvol8 fixed minor
The same with binary output - it has no effect on this functionality:
$ lvs -o name,fixed_minor --binary -S 'fixed_minor=fixed'
LV FixMin
lvol8 1
$ lvs -o name,fixed_minor --binary -S 'fixed_minor="fixed
minor"'
LV FixMin
lvol8 1
[1] f20/~ # lvs -o name,fixed_minor --binary -S 'fixed_minor=1'
LV FixMin
lvol8 1
---
lib/report/report.c | 142 +++++++++++++++++++++++++++++++++++++++++++++++----
1 files changed, 131 insertions(+), 11 deletions(-)
diff --git a/lib/report/report.c b/lib/report/report.c
index 284a718..7cc3599 100644
--- a/lib/report/report.c
+++ b/lib/report/report.c
@@ -41,15 +41,27 @@ struct lvm_report_object {
struct label *label;
};
+/* Enum for field_num index to use in per-field reserved value definition. */
+#define FIELD(type, strct, sorttype, head, field_name, width, func, id, desc, writeable) field_ ## id,
+enum {
+#include "columns.h"
+};
+#undef FIELD
+
+
static const uint64_t _zero64 = UINT64_C(0);
static const uint64_t _one64 = UINT64_C(1);
static const char * const _str_zero = "0";
static const char * const _str_one = "1";
-static const uint64_t _reserved_number_undef_64 = UINT64_C(-1);
-static const uint64_t _reserved_number_unmanaged_64 = UINT64_C(-2);
-static const uint64_t _reserved_size_auto_64 = UINT64_C(-1);
+/*
+ * TODO: try to automate reserved value definition and declare reserved values
+ * using FIELD macro directly. The FIELD macro should be able to define
+ * proper structures automatically then.
+ */
+/* Per-type reserved values. */
+static const uint64_t _reserved_number_undef_64 = UINT64_C(-1);
/*
* 32 bit signed is casted to 64 bit unsigned in dm_report_field internally!
* So when stored in the struct, the _reserved_number_undef_32 is actually
@@ -57,17 +69,125 @@ static const uint64_t _reserved_size_auto_64 = UINT64_C(-1);
*/
static const int32_t _reserved_number_undef_32 = INT32_C(-1);
+/* Per-field reserved values. */
+static const struct dm_report_field_reserved_value _reserved_pv_allocatable = {field_pv_allocatable, &_one64};
+static const struct dm_report_field_reserved_value _reserved_pv_exported = {field_pv_exported, &_one64};
+static const struct dm_report_field_reserved_value _reserved_pv_missing = {field_pv_missing, &_one64};
+static const struct dm_report_field_reserved_value _reserved_vg_extendable = {field_vg_extendable, &_one64};
+static const struct dm_report_field_reserved_value _reserved_vg_exported = {field_vg_exported, &_one64};
+static const struct dm_report_field_reserved_value _reserved_vg_partial = {field_vg_partial, &_one64};
+static const struct dm_report_field_reserved_value _reserved_vg_clustered = {field_vg_clustered, &_one64};
+static const struct dm_report_field_reserved_value _reserved_vg_permissions_rw = {field_vg_permissions, "writeable"};
+static const struct dm_report_field_reserved_value _reserved_vg_permissions_r = {field_vg_permissions, "read-only"};
+static const struct dm_report_field_reserved_value _reserved_vg_mda_copies = {field_vg_mda_copies, &_reserved_number_undef_64};
+static const struct dm_report_field_reserved_value _reserved_lv_initial_image_sync = {field_lv_initial_image_sync, &_one64};
+static const struct dm_report_field_reserved_value _reserved_lv_image_synced = {field_lv_image_synced, &_one64};
+static const struct dm_report_field_reserved_value _reserved_lv_merging = {field_lv_merging, &_one64};
+static const struct dm_report_field_reserved_value _reserved_lv_converting = {field_lv_converting, &_one64};
+static const struct dm_report_field_reserved_value _reserved_lv_allocation_locked = {field_lv_allocation_locked, &_one64};
+static const struct dm_report_field_reserved_value _reserved_lv_fixed_minor = {field_lv_fixed_minor, &_one64};
+static const struct dm_report_field_reserved_value _reserved_lv_merge_failed = {field_lv_merge_failed, &_one64};
+static const struct dm_report_field_reserved_value _reserved_lv_snapshot_invalid = {field_lv_snapshot_invalid, &_one64};
+static const struct dm_report_field_reserved_value _reserved_lv_suspended = {field_lv_suspended, &_one64};
+static const struct dm_report_field_reserved_value _reserved_lv_live_table = {field_lv_live_table, &_one64};
+static const struct dm_report_field_reserved_value _reserved_lv_inactive_table = {field_lv_inactive_table, &_one64};
+static const struct dm_report_field_reserved_value _reserved_lv_device_open = {field_lv_device_open, &_one64};
+static const struct dm_report_field_reserved_value _reserved_lv_skip_activation = {field_lv_skip_activation, &_one64};
+static const struct dm_report_field_reserved_value _reserved_lv_permissions_rw = {field_lv_permissions, "writeable"};
+static const struct dm_report_field_reserved_value _reserved_lv_permissions_r = {field_lv_permissions, "read-only"};
+static const struct dm_report_field_reserved_value _reserved_lv_permissions_r_override = {field_lv_permissions, "read-only-override"};
+static const struct dm_report_field_reserved_value _reserved_lv_read_ahead = {field_lv_read_ahead, &_reserved_number_undef_64};
+
+/* Per-type reserved names. */
static const char const *_reserved_number_undef_64_names[]={"-1", "undefined", "undef", "unknown", NULL};
-static const char const *_reserved_number_unmanaged_64_names[]={"unmanaged", NULL};
-static const char const *_reserved_size_auto_64_names[]={"auto", NULL};
+/* Per-field reserved names. */
+static const char *_reserved_pv_allocatable_names[]={"allocatable", NULL};
+static const char *_reserved_pv_exported_names[]={"exported", NULL};
+static const char *_reserved_pv_missing_names[]={"missing", NULL};
+static const char *_reserved_vg_extendable_names[]={"extendable", NULL};
+static const char *_reserved_vg_exported_names[]={"exported", NULL};
+static const char *_reserved_vg_partial_names[]={"partial", NULL};
+static const char *_reserved_vg_clustered_names[]={"clustered", NULL};
+static const char *_reserved_vg_permissions_rw_names[]={"writeable", "rw", "read-write", NULL};
+static const char *_reserved_vg_permissions_r_names[]={"read-only", "r", "ro", NULL};
+static const char *_reserved_vg_mda_copies_names[]={"unmanaged", NULL};
+static const char *_reserved_lv_initial_image_sync_names[]={"initial image sync", "sync", NULL};
+static const char *_reserved_lv_image_synced_names[]={"image synced", "synced", NULL};
+static const char *_reserved_lv_merging_names[]={"merging", NULL};
+static const char *_reserved_lv_converting_names[]={"converting", NULL};
+static const char *_reserved_lv_allocation_locked_names[]={"allocation locked", "locked", NULL};
+static const char *_reserved_lv_fixed_minor_names[]={"fixed minor", "fixed", NULL};
+static const char *_reserved_lv_merge_failed_names[]={"merge failed", "failed", NULL};
+static const char *_reserved_lv_snapshot_invalid_names[]={"snapsot invalid", "invalid", NULL};
+static const char *_reserved_lv_suspended_names[]={"suspended", NULL};
+static const char *_reserved_lv_live_table_names[]={"live table present", "live table", "live", NULL};
+static const char *_reserved_lv_inactive_table_names[]={"inactive table present", "inactive table", "inactive", NULL};
+static const char *_reserved_lv_device_open_names[]={"open", NULL};
+static const char *_reserved_lv_skip_activation_names[]={"skip activation", "skip", NULL};
+static const char *_reserved_lv_permissions_rw_names[]={"writeable", "rw", "read-write", NULL};
+static const char *_reserved_lv_permissions_r_names[]={"read-only", "r", "ro", NULL};
+static const char *_reserved_lv_permissions_r_override_names[]={"read-only-override", "ro-override", "r-override", "R", NULL};
+static const char *_reserved_lv_read_ahead_names[]={"auto", NULL};
+
+/* Put together arrays of reserved names with their reserved values. */
static const struct dm_report_reserved_value _report_reserved_values[] = {
{DM_REPORT_FIELD_TYPE_NUMBER, &_reserved_number_undef_64, _reserved_number_undef_64_names,
"Reserved value for undefined numeric value."},
- {DM_REPORT_FIELD_TYPE_NUMBER, &_reserved_number_unmanaged_64, _reserved_number_unmanaged_64_names,
- "Reserved value for unmanaged number of metadata copies in VG."},
- {DM_REPORT_FIELD_TYPE_SIZE, &_reserved_size_auto_64, _reserved_size_auto_64_names,
- "Reserved value for size that is automatically calculated."},
+ {DM_REPORT_FIELD_TYPE_NONE, &_reserved_pv_allocatable, _reserved_pv_allocatable_names,
+ "pv_allocatable reserved values"},
+ {DM_REPORT_FIELD_TYPE_NONE, &_reserved_pv_exported, _reserved_pv_exported_names,
+ "pv_exported reserved values"},
+ {DM_REPORT_FIELD_TYPE_NONE, &_reserved_pv_missing, _reserved_pv_missing_names,
+ "pv_missing reserved values"},
+ {DM_REPORT_FIELD_TYPE_NONE, &_reserved_vg_extendable, _reserved_vg_extendable_names,
+ "vg_extendable reserved values"},
+ {DM_REPORT_FIELD_TYPE_NONE, &_reserved_vg_exported, _reserved_vg_exported_names,
+ "vg_exported reserved values"},
+ {DM_REPORT_FIELD_TYPE_NONE, &_reserved_vg_partial, _reserved_vg_partial_names,
+ "vg_partial reserved values"},
+ {DM_REPORT_FIELD_TYPE_NONE, &_reserved_vg_clustered, _reserved_vg_clustered_names,
+ "vg_clustered reserved values"},
+ {DM_REPORT_FIELD_TYPE_NONE, &_reserved_vg_permissions_rw, _reserved_vg_permissions_rw_names,
+ "vg_permissions reserved values (writeable)"},
+ {DM_REPORT_FIELD_TYPE_NONE, &_reserved_vg_permissions_r, _reserved_vg_permissions_r_names,
+ "vg_permissions reserved values (read-only)"},
+ {DM_REPORT_FIELD_TYPE_NONE, &_reserved_vg_mda_copies, _reserved_vg_mda_copies_names,
+ "vg_mda_copies reserved values (unmanaged)"},
+ {DM_REPORT_FIELD_TYPE_NONE, &_reserved_lv_initial_image_sync, _reserved_lv_initial_image_sync_names,
+ "lv_initial_image_sync reserved values"},
+ {DM_REPORT_FIELD_TYPE_NONE, &_reserved_lv_image_synced, _reserved_lv_image_synced_names,
+ "lv_image_synced reserved values"},
+ {DM_REPORT_FIELD_TYPE_NONE, &_reserved_lv_merging, _reserved_lv_merging_names,
+ "lv_merging reserved values"},
+ {DM_REPORT_FIELD_TYPE_NONE, &_reserved_lv_converting, _reserved_lv_converting_names,
+ "lv_converting reserved values"},
+ {DM_REPORT_FIELD_TYPE_NONE, &_reserved_lv_allocation_locked, _reserved_lv_allocation_locked_names,
+ "lv_allocation_locked reserved values"},
+ {DM_REPORT_FIELD_TYPE_NONE, &_reserved_lv_fixed_minor, _reserved_lv_fixed_minor_names,
+ "lv_fixed_minor reserved values"},
+ {DM_REPORT_FIELD_TYPE_NONE, &_reserved_lv_merge_failed, _reserved_lv_merge_failed_names,
+ "lv_merge_failed reserved values"},
+ {DM_REPORT_FIELD_TYPE_NONE, &_reserved_lv_snapshot_invalid, _reserved_lv_snapshot_invalid_names,
+ "lv_snapshot_invalid reserved values"},
+ {DM_REPORT_FIELD_TYPE_NONE, &_reserved_lv_suspended, _reserved_lv_suspended_names,
+ "lv_suspended reserved values"},
+ {DM_REPORT_FIELD_TYPE_NONE, &_reserved_lv_live_table, _reserved_lv_live_table_names,
+ "lv_live_table reserved values"},
+ {DM_REPORT_FIELD_TYPE_NONE, &_reserved_lv_inactive_table, _reserved_lv_inactive_table_names,
+ "lv_inactive_table reserved values"},
+ {DM_REPORT_FIELD_TYPE_NONE, &_reserved_lv_device_open, _reserved_lv_device_open_names,
+ "lv_device_open reserved values"},
+ {DM_REPORT_FIELD_TYPE_NONE, &_reserved_lv_skip_activation, _reserved_lv_skip_activation_names,
+ "lv_inactive_table reserved values"},
+ {DM_REPORT_FIELD_TYPE_NONE, &_reserved_lv_permissions_rw, _reserved_lv_permissions_rw_names,
+ "lv_permissions reserved values (writeable)"},
+ {DM_REPORT_FIELD_TYPE_NONE, &_reserved_lv_permissions_r, _reserved_lv_permissions_r_names,
+ "lv_permissions reserved values (read-only)"},
+ {DM_REPORT_FIELD_TYPE_NONE, &_reserved_lv_permissions_r_override, _reserved_lv_permissions_r_override_names,
+ "lv_permissions reserved values (read-only-override)"},
+ {DM_REPORT_FIELD_TYPE_NONE, &_reserved_lv_read_ahead, _reserved_lv_read_ahead_names,
+ "lv_read_ahead reserved values (auto)"},
{0, NULL, NULL}
};
@@ -542,7 +662,7 @@ static int _lvreadahead_disp(struct dm_report *rh, struct dm_pool *mem,
const struct logical_volume *lv = (const struct logical_volume *) data;
if (lv->read_ahead == DM_READ_AHEAD_AUTO)
- return _field_set_value(field, "auto", &_reserved_size_auto_64);
+ return _field_set_value(field, "auto", &_reserved_number_undef_64);
return _size32_disp(rh, mem, field, &lv->read_ahead, private);
}
@@ -833,7 +953,7 @@ static int _vgmdacopies_disp(struct dm_report *rh, struct dm_pool *mem,
uint32_t count = vg_mda_copies(vg);
if (count == VGMETADATACOPIES_UNMANAGED)
- return _field_set_value(field, "unmanaged", &_reserved_number_unmanaged_64);
+ return _field_set_value(field, "unmanaged", &_reserved_number_undef_64);
return _uint32_disp(rh, mem, field, &count, private);
}
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=0956fd230fea5507…
Commit: 0956fd230fea550707acb2889223438996102de4
Parent: da545ce3b471e76b3ebcfcb5528118d8dd9264df
Author: Peter Rajnoha <prajnoha(a)redhat.com>
AuthorDate: Fri Jul 4 11:21:38 2014 +0200
Committer: Peter Rajnoha <prajnoha(a)redhat.com>
CommitterDate: Fri Jul 4 15:50:50 2014 +0200
report: adapt selection code to recognize per-field reserved values
In contrast to per-type reserved values that are applied for all fields
of that type, per-field reserved values are only applied for concrete
field only.
Also add 'struct dm_report_field_reserved_value' to libdm for per-field
reserved value definition. This is defined by field number (an index
in the 'fields' array which is given for the dm_report_init_with_selection
function during report initialization) and the value to use for any
of the specified reserved names.
---
libdm/libdevmapper.h | 27 ++++++++++++
libdm/libdm-report.c | 112 +++++++++++++++++++++++++++++++++-----------------
2 files changed, 101 insertions(+), 38 deletions(-)
diff --git a/libdm/libdevmapper.h b/libdm/libdevmapper.h
index ad504da..dc3da78 100644
--- a/libdm/libdevmapper.h
+++ b/libdm/libdevmapper.h
@@ -1633,6 +1633,7 @@ struct dm_report_field;
#define DM_REPORT_FIELD_ALIGN_LEFT 0x00000001
#define DM_REPORT_FIELD_ALIGN_RIGHT 0x00000002
#define DM_REPORT_FIELD_TYPE_MASK 0x00000FF0
+#define DM_REPORT_FIELD_TYPE_NONE 0x00000000
#define DM_REPORT_FIELD_TYPE_STRING 0x00000010
#define DM_REPORT_FIELD_TYPE_NUMBER 0x00000020
#define DM_REPORT_FIELD_TYPE_SIZE 0x00000040
@@ -1658,9 +1659,35 @@ struct dm_report_field_type {
const char *desc; /* description of the field */
};
+/*
+ * Per-field reserved value.
+ */
+struct dm_report_field_reserved_value {
+ /* field_num is the position of the field in 'fields'
+ array passed to dm_report_init_with_selection */
+ uint32_t field_num;
+ /* the value is of the same type as the field
+ identified by field_num */
+ const void *value;
+};
+
+/*
+ * Reserved value is a 'value' that is used directly if any of the 'names' is hit.
+ *
+ * If type is any of DM_REPORT_FIELD_TYPE_*, the reserved value is recognized
+ * for all fields of that type.
+ *
+ * If type is DM_REPORT_FIELD_TYPE_NONE, the reserved value is recognized
+ * for the exact field specified - hence the type of the value is automatically
+ * the same as the type of the field itself.
+ *
+ * The array of reserved values is used to initialize reporting with
+ * selection enabled (see also dm_report_init_with_selection function).
+ */
struct dm_report_reserved_value {
const unsigned type; /* DM_REPORT_FIELD_TYPE_* */
const void *value; /* reserved value:
+ struct dm_report_field_reserved_value for DM_REPORT_FIELD_TYPE_NONE
uint64_t for DM_REPORT_FIELD_TYPE_NUMBER
uint64_t for DM_REPORT_FIELD_TYPE_SIZE (number of 512-byte sectors)
uint64_t for DM_REPORT_FIELD_TYPE_PERCENT
diff --git a/libdm/libdm-report.c b/libdm/libdm-report.c
index 00c3d3f..ad89cf2 100644
--- a/libdm/libdm-report.c
+++ b/libdm/libdm-report.c
@@ -1599,6 +1599,18 @@ static int _tok_op_cmp(const char *s, const char **end)
return _tok_op(_op_cmp, s, end, 0);
}
+static char _get_and_skip_quote_char(char const **s)
+{
+ char c = 0;
+
+ if (**s == '"' || **s == '\'') {
+ c = **s;
+ (*s)++;
+ }
+
+ return c;
+}
+
/*
*
* Input:
@@ -1689,38 +1701,62 @@ static const char *_tok_value_string(const char *s,
return s;
}
+static const char *_reserved_name(const char **names, const char *s, size_t len)
+{
+ const char **name = names;
+ while (*name) {
+ if ((strlen(*name) == len) && !strncmp(*name, s, len))
+ return *name;
+ name++;
+ }
+ return NULL;
+}
+
/*
* Used to replace a string representation of the reserved value
* found in selection with the exact reserved value of certain type.
*/
-static const char *_get_reserved_value(struct dm_report *rh, unsigned type,
- const char *s, const char **begin, const char **end,
- const struct dm_report_reserved_value **reserved)
-{
- const struct dm_report_reserved_value *iter = rh->reserved_values;
- const char **name;
+static const char *_get_reserved(struct dm_report *rh, unsigned type,
+ uint32_t field_num, int implicit,
+ const char *s, const char **begin, const char **end,
+ const struct dm_report_reserved_value **reserved)
+{
+ const struct dm_report_reserved_value *iter = implicit ? NULL : rh->reserved_values;
+ const char *tmp_begin, *tmp_end, *tmp_s = s;
+ const char *name = NULL;
+ char c;
*reserved = NULL;
if (!iter)
return s;
- while (iter->type) {
- if (iter->type & type) {
- name = iter->names;
- while (*name) {
- if (!strcmp(*name, s)) {
- *begin = s;
- *end = s += strlen(*name);
- *reserved = iter;
- return s;
- }
- name++;
- }
+ c = _get_and_skip_quote_char(&tmp_s);
+ if (!(tmp_s = _tok_value_string(tmp_s, &tmp_begin, &tmp_end, c, SEL_AND | SEL_OR | SEL_PRECEDENCE_PE, NULL)))
+ return s;
+
+ while (iter->value) {
+ if (!iter->type) {
+ /* DM_REPORT_FIELD_TYPE_NONE - per-field reserved value */
+ if (((((const struct dm_report_field_reserved_value *) iter->value)->field_num) == field_num) &&
+ (name = _reserved_name(iter->names, tmp_begin, tmp_end - tmp_begin)))
+ break;
+ } else if (iter->type & type) {
+ /* DM_REPORT_FIELD_TYPE_* - per-type reserved value */
+ if ((name = _reserved_name(iter->names, tmp_begin, tmp_end - tmp_begin)))
+ break;
}
iter++;
}
+ if (name) {
+ /* found! */
+ *begin = tmp_begin;
+ *end = tmp_end;
+ s = tmp_s;
+ *reserved = iter;
+ }
+
return s;
}
@@ -1880,18 +1916,6 @@ static int _add_item_to_string_list(struct dm_pool *mem, const char *begin,
return 1;
}
-static char _get_and_skip_quote_char(char const **s)
-{
- char c = 0;
-
- if (**s == '"' || **s == '\'') {
- c = **s;
- (*s)++;
- }
-
- return c;
-}
-
/*
* Input:
* ft - field type for which the value is parsed
@@ -2033,8 +2057,10 @@ bad:
*/
static const char *_tok_value(struct dm_report *rh,
const struct dm_report_field_type *ft,
- const char *s, const char **begin,
- const char **end, uint32_t *flags,
+ uint32_t field_num, int implicit,
+ const char *s,
+ const char **begin, const char **end,
+ uint32_t *flags,
const struct dm_report_reserved_value **reserved,
struct dm_pool *mem, void *custom)
{
@@ -2046,7 +2072,7 @@ static const char *_tok_value(struct dm_report *rh,
s = _skip_space(s);
- s = _get_reserved_value(rh, expected_type, s, begin, end, reserved);
+ s = _get_reserved(rh, expected_type, field_num, implicit, s, begin, end, reserved);
if (*reserved) {
*flags |= expected_type;
return s;
@@ -2149,6 +2175,14 @@ static const char *_tok_field_name(const char *s,
return s;
}
+static const void *_get_reserved_value(const struct dm_report_reserved_value *reserved)
+{
+ if (reserved->type)
+ return reserved->value;
+ else
+ return ((const struct dm_report_field_reserved_value *) reserved->value)->value;
+}
+
static struct field_selection *_create_field_selection(struct dm_report *rh,
uint32_t field_num,
int implicit,
@@ -2229,7 +2263,7 @@ static struct field_selection *_create_field_selection(struct dm_report *rh,
switch (flags & DM_REPORT_FIELD_TYPE_MASK) {
case DM_REPORT_FIELD_TYPE_STRING:
if (reserved) {
- fs->v.s = (const char *) reserved->value;
+ fs->v.s = (const char *) _get_reserved_value(reserved);
dm_pool_free(rh->mem, s);
} else {
fs->v.s = s;
@@ -2241,7 +2275,7 @@ static struct field_selection *_create_field_selection(struct dm_report *rh,
break;
case DM_REPORT_FIELD_TYPE_NUMBER:
if (reserved)
- fs->v.i = *(uint64_t *) reserved->value;
+ fs->v.i = *(uint64_t *) _get_reserved_value(reserved);
else {
if (((fs->v.i = strtoull(s, NULL, 10)) == ULLONG_MAX) &&
(errno == ERANGE)) {
@@ -2257,7 +2291,7 @@ static struct field_selection *_create_field_selection(struct dm_report *rh,
break;
case DM_REPORT_FIELD_TYPE_SIZE:
if (reserved)
- fs->v.d = (double) * (uint64_t *) reserved->value;
+ fs->v.d = (double) * (uint64_t *) _get_reserved_value(reserved);
else {
fs->v.d = strtod(s, NULL);
if (errno == ERANGE) {
@@ -2276,7 +2310,7 @@ static struct field_selection *_create_field_selection(struct dm_report *rh,
break;
case DM_REPORT_FIELD_TYPE_PERCENT:
if (reserved)
- fs->v.i = *(uint64_t *) reserved->value;
+ fs->v.i = *(uint64_t *) _get_reserved_value(reserved);
else {
fs->v.d = strtod(s, NULL);
if ((errno == ERANGE) || (fs->v.d < 0) || (fs->v.d > 100)) {
@@ -2508,7 +2542,9 @@ static struct selection_node *_parse_selection(struct dm_report *rh,
custom = &str_list;
else
custom = NULL;
- if (!(last = _tok_value(rh, ft, last, &vs, &ve, &flags, &reserved, rh->mem, custom)))
+ if (!(last = _tok_value(rh, ft, field_num, implicit,
+ last, &vs, &ve, &flags,
+ &reserved, rh->mem, custom)))
goto_bad;
}
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=da545ce3b471e76b…
Commit: da545ce3b471e76b3ebcfcb5528118d8dd9264df
Parent: d2af4f84c94cb8202565ac32c5f1df673cd92e0c
Author: Peter Rajnoha <prajnoha(a)redhat.com>
AuthorDate: Wed Jul 2 13:16:32 2014 +0200
Committer: Peter Rajnoha <prajnoha(a)redhat.com>
CommitterDate: Fri Jul 4 15:40:17 2014 +0200
tools: add --binary arg to pvs,vgs,lvs and {pv,vg,lv}display -C and report/binary_values_as_numeric lvm.conf option
The --binary option, if used, causes all the binary values reported
in reporting commands to be displayed as "0" or "1" instead of descriptive
literal values (value "unknown" is still used for values that could not be
determined).
Also, add report/binary_values_as_numeric lvm.conf option with the same
functionality as the --binary option (the --binary option prevails
if both --binary cmd option and report/binary_values_as_numeric lvm.conf
option is used at the same time). The report/binary_values_as_numeric is
also profilable.
This makes it easier to use and check lvm reporting command output in scripts.
---
conf/command_profile_template.profile.in | 1 +
conf/example.conf.in | 6 +++++
lib/commands/toolcontext.c | 1 +
lib/commands/toolcontext.h | 1 +
lib/config/config_settings.h | 1 +
lib/report/report.c | 15 +++++++++++++-
man/lvdisplay.8.in | 1 +
man/lvs.8.in | 6 +++++
man/pvdisplay.8.in | 1 +
man/pvs.8.in | 6 +++++
man/vgdisplay.8.in | 1 +
man/vgs.8.in | 6 +++++
tools/args.h | 1 +
tools/commands.h | 32 +++++++++++++++++------------
tools/lvmcmdline.c | 3 ++
15 files changed, 68 insertions(+), 14 deletions(-)
diff --git a/conf/command_profile_template.profile.in b/conf/command_profile_template.profile.in
index 36d4343..592a69d 100644
--- a/conf/command_profile_template.profile.in
+++ b/conf/command_profile_template.profile.in
@@ -13,6 +13,7 @@
#
global {
units="h"
+ report_binary_values_as_numeric=0
si_unit_consistency=1
suffix=1
lvdisplay_shows_full_device_path=0
diff --git a/conf/example.conf.in b/conf/example.conf.in
index 935d3e7..162770a 100644
--- a/conf/example.conf.in
+++ b/conf/example.conf.in
@@ -1022,6 +1022,12 @@ activation {
# Output each column as a row. If set, this also implies report/prefixes=1.
# colums_as_rows=0
+ # Use binary values "0" or "1" instead of descriptive literal values for
+ # columns that have exactly two valid values to report (not counting the
+ # "unknown" value which denotes that the value could not be determined).
+ #
+ # binary_values_as_numeric = 0
+
# Comma separated list of columns to sort by when reporting 'lvm devtypes' command.
# See 'lvm devtypes -o help' for the list of possible fields.
# devtypes_sort="devtype_name"
diff --git a/lib/commands/toolcontext.c b/lib/commands/toolcontext.c
index 18fa12d..6ac4a42 100644
--- a/lib/commands/toolcontext.c
+++ b/lib/commands/toolcontext.c
@@ -297,6 +297,7 @@ int process_profilable_config(struct cmd_context *cmd) {
}
cmd->si_unit_consistency = find_config_tree_bool(cmd, global_si_unit_consistency_CFG, NULL);
+ cmd->report_binary_values_as_numeric = find_config_tree_bool(cmd, report_binary_values_as_numeric_CFG, NULL);
cmd->default_settings.suffix = find_config_tree_bool(cmd, global_suffix_CFG, NULL);
return 1;
diff --git a/lib/commands/toolcontext.h b/lib/commands/toolcontext.h
index 9023a6c..162af55 100644
--- a/lib/commands/toolcontext.h
+++ b/lib/commands/toolcontext.h
@@ -88,6 +88,7 @@ struct cmd_context {
unsigned partial_activation:1;
unsigned auto_set_activation_skip:1;
unsigned si_unit_consistency:1;
+ unsigned report_binary_values_as_numeric:1;
unsigned metadata_read_only:1;
unsigned ignore_clustered_vgs:1;
unsigned threaded:1; /* Set if running within a thread e.g. clvmd */
diff --git a/lib/config/config_settings.h b/lib/config/config_settings.h
index d277e0e..2ddf888 100644
--- a/lib/config/config_settings.h
+++ b/lib/config/config_settings.h
@@ -233,6 +233,7 @@ cfg(report_separator_CFG, "separator", report_CFG_SECTION, CFG_PROFILABLE, CFG_T
cfg(report_prefixes_CFG, "prefixes", report_CFG_SECTION, CFG_PROFILABLE, CFG_TYPE_BOOL, DEFAULT_REP_PREFIXES, vsn(2, 2, 36), NULL)
cfg(report_quoted_CFG, "quoted", report_CFG_SECTION, CFG_PROFILABLE, CFG_TYPE_BOOL, DEFAULT_REP_QUOTED, vsn(2, 2, 39), NULL)
cfg(report_colums_as_rows_CFG, "colums_as_rows", report_CFG_SECTION, CFG_PROFILABLE, CFG_TYPE_BOOL, DEFAULT_REP_COLUMNS_AS_ROWS, vsn(1, 0, 0), NULL)
+cfg(report_binary_values_as_numeric_CFG, "binary_values_as_numeric", report_CFG_SECTION, CFG_PROFILABLE, CFG_TYPE_BOOL, 0, vsn(2, 2, 108), NULL)
cfg(report_devtypes_sort_CFG, "devtypes_sort", report_CFG_SECTION, CFG_PROFILABLE, CFG_TYPE_STRING, DEFAULT_DEVTYPES_SORT, vsn(2, 2, 101), NULL)
cfg(report_devtypes_cols_CFG, "devtypes_cols", report_CFG_SECTION, CFG_PROFILABLE, CFG_TYPE_STRING, DEFAULT_DEVTYPES_COLS, vsn(2, 2, 101), NULL)
cfg(report_devtypes_cols_verbose_CFG, "devtypes_cols_verbose", report_CFG_SECTION, CFG_PROFILABLE, CFG_TYPE_STRING, DEFAULT_DEVTYPES_COLS_VERB, vsn(2, 2, 101), NULL)
diff --git a/lib/report/report.c b/lib/report/report.c
index d74321e..284a718 100644
--- a/lib/report/report.c
+++ b/lib/report/report.c
@@ -43,6 +43,8 @@ struct lvm_report_object {
static const uint64_t _zero64 = UINT64_C(0);
static const uint64_t _one64 = UINT64_C(1);
+static const char * const _str_zero = "0";
+static const char * const _str_one = "1";
static const uint64_t _reserved_number_undef_64 = UINT64_C(-1);
static const uint64_t _reserved_number_unmanaged_64 = UINT64_C(-2);
@@ -1173,11 +1175,22 @@ static int _lvactive_disp(struct dm_report *rh, struct dm_pool *mem,
/* PV/VG/LV Attributes */
+/*
+ * Display either "0"/"1" or ""/"word" based on bin_value,
+ * cmd->report_binary_values_as_numeric selects the mode to use.
+*/
static int _binary_disp(struct dm_report *rh, struct dm_pool *mem __attribute__((unused)),
struct dm_report_field *field, int bin_value, const char *word,
void *private)
{
- return _field_set_value(field, bin_value ? word : "", bin_value ? &_one64 : &_zero64);
+ const struct cmd_context *cmd = (const struct cmd_context *) private;
+
+ if (cmd->report_binary_values_as_numeric)
+ /* "0"/"1" */
+ return _field_set_value(field, bin_value ? _str_one : _str_zero, bin_value ? &_one64 : &_zero64);
+ else
+ /* blank/"word" */
+ return _field_set_value(field, bin_value ? word : "", bin_value ? &_one64 : &_zero64);
}
static int _pvallocatable_disp(struct dm_report *rh, struct dm_pool *mem,
diff --git a/man/lvdisplay.8.in b/man/lvdisplay.8.in
index 1283d58..ed113dd 100644
--- a/man/lvdisplay.8.in
+++ b/man/lvdisplay.8.in
@@ -25,6 +25,7 @@ lvdisplay \(em display attributes of a logical volume
.B lvdisplay
.BR \-C | \-\-columns
.RB [ \-\-aligned ]
+.RB [ \-\-binary ]
.RB [ \-a | \-\-all ]
.RB [ \-\-commandprofile
.IR ProfileName ]
diff --git a/man/lvs.8.in b/man/lvs.8.in
index 1afd63d..b7e3ecc 100644
--- a/man/lvs.8.in
+++ b/man/lvs.8.in
@@ -4,6 +4,7 @@ lvs \(em report information about logical volumes
.SH SYNOPSIS
.B lvs
.RB [ \-\-aligned ]
+.RB [ \-\-binary ]
.RB [ \-a | \-\-all ]
.RB [ \-\-commandprofile
.IR ProfileName ]
@@ -44,6 +45,11 @@ for common options.
.B \-\-aligned
Use with \fB\-\-separator\fP to align the output columns.
.TP
+.B \-\-binary
+Use binary values "0" or "1" instead of descriptive literal values
+for columns that have exactly two valid values to report (not counting
+the "unknown" value which denotes that the value could not be determined).
+.TP
.B \-\-all
Include information in the output about internal Logical Volumes that
are components of normally-accessible Logical Volumes, such as mirrors,
diff --git a/man/pvdisplay.8.in b/man/pvdisplay.8.in
index 0399c1e..70c9bfc 100644
--- a/man/pvdisplay.8.in
+++ b/man/pvdisplay.8.in
@@ -26,6 +26,7 @@ pvdisplay \- display attributes of a physical volume
.B pvdisplay
.BR \-C | \-\-columns
.RB [ \-\-aligned ]
+.RB [ \-\-binary ]
.RB [ \-a |