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=b0d8a524a2c1d9cc…
Commit: b0d8a524a2c1d9ccf191392bf47a2023087ae362
Parent: 37a33d7414b85e4ce69a2ab6727522faba8a86eb
Author: Zdenek Kabelac <zkabelac(a)redhat.com>
AuthorDate: Thu Jun 30 16:21:03 2016 +0200
Committer: Zdenek Kabelac <zkabelac(a)redhat.com>
CommitterDate: Fri Jul 1 00:44:49 2016 +0200
tests: test foreign users of thin-pool
Note: dmeventd should not need any notification and automatically
try to resize again when there is some metadata change.
---
test/shell/thin-foreign-dmeventd.sh | 104 +++++++++++++++++++++++++++++++++++
1 files changed, 104 insertions(+), 0 deletions(-)
diff --git a/test/shell/thin-foreign-dmeventd.sh b/test/shell/thin-foreign-dmeventd.sh
new file mode 100644
index 0000000..a96b206
--- /dev/null
+++ b/test/shell/thin-foreign-dmeventd.sh
@@ -0,0 +1,104 @@
+#!/bin/sh
+
+# Copyright (C) 2016 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+# test foreing user of thin-pool
+
+SKIP_WITH_LVMLOCKD=1
+SKIP_WITH_LVMPOLLD=1
+
+. lib/inittest
+
+MOUNT_DIR=mnt
+
+cleanup_mounted_and_teardown()
+{
+ umount "$MOUNT_DIR" || true
+ dmsetup remove $THIN
+ vgremove -ff $vg
+ aux teardown
+}
+
+percent_() {
+ get lv_field $vg/pool data_percent | cut -d. -f1
+}
+
+#
+# Main
+#
+aux have_thin 1 0 0 || skip
+which mkfs.ext4 || skip
+
+aux prepare_dmeventd
+aux prepare_pvs 2 64
+
+vgcreate $vg -s 64K $(cat DEVICES)
+
+# Create named pool only
+lvcreate --errorwhenfull y -L2100K -T $vg/pool
+
+POOL="$vg-pool"
+THIN="${PREFIX}_thin"
+
+# Foreing user is using own ioctl command to create thin devices
+dmsetup message $POOL 0 "create_thin 0"
+dmsetup message $POOL 0 "set_transaction_id 0 1"
+
+dmsetup status
+# Once the transaction id has changed, lvm2 shall not be able to create thinLV
+fail lvcreate -V10 $vg/pool
+
+trap 'cleanup_mounted_and_teardown' EXIT
+
+# 20M thin device
+dmsetup create $THIN --table "0 40960 thin $DM_DEV_DIR/mapper/$POOL 0"
+
+dmsetup table
+dmsetup info -c
+
+mkdir "$MOUNT_DIR"
+# This mkfs fills 2.2MB pool over 95%
+# no autoresize is configured
+mkfs.ext4 "$DM_DEV_DIR/mapper/$THIN"
+test $(percent_) -gt 95
+mount "$DM_DEV_DIR/mapper/$THIN" "$MOUNT_DIR"
+
+pvchange -x n "$dev1" "$dev2"
+
+test $(percent_) -gt 95
+# Configure autoresize
+aux lvmconf 'activation/thin_pool_autoextend_percent = 10' \
+ 'activation/thin_pool_autoextend_threshold = 75'
+
+# Give it some time to left dmeventd do some work
+sleep 20
+
+# And check foreign thin device is still mounted
+mount | grep "$MOUNT_DIR" | grep "$THIN"
+test $(percent_) -gt 95
+
+pvchange -x y "$dev1" "$dev2"
+
+# FIXME: ATM tell dmeventd explicitely we've changed metadata
+# however dmeventd shall be aware of any metadata change
+# and automagically retry resize operation after that.
+lvchange --refresh $vg/pool
+
+# Give it some time and let dmeventd do some work
+for i in $(seq 1 15) ; do
+ test $(percent_) -ge 75 || break
+ sleep 1
+done
+
+test $(percent_) -lt 75
+
+# And check foreign thin device is still mounted
+mount | grep "$MOUNT_DIR" | grep "$THIN"
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=37a33d7414b85e4c…
Commit: 37a33d7414b85e4ce69a2ab6727522faba8a86eb
Parent: 3fd458488649c27f18f1ddb993ba9360f259d47b
Author: Zdenek Kabelac <zkabelac(a)redhat.com>
AuthorDate: Mon Jun 27 11:13:43 2016 +0200
Committer: Zdenek Kabelac <zkabelac(a)redhat.com>
CommitterDate: Fri Jul 1 00:44:48 2016 +0200
cleanup: warns from older gcc
---
lib/cache/lvmcache.c | 3 +--
lib/display/display.c | 2 +-
2 files changed, 2 insertions(+), 3 deletions(-)
diff --git a/lib/cache/lvmcache.c b/lib/cache/lvmcache.c
index 9d89b80..6ce778d 100644
--- a/lib/cache/lvmcache.c
+++ b/lib/cache/lvmcache.c
@@ -2137,7 +2137,6 @@ struct lvmcache_info *lvmcache_add(struct labeller *labeller,
char pvid_s[ID_LEN + 1] __attribute__((aligned(8)));
char uuid[64] __attribute__((aligned(8)));
struct lvmcache_vgsummary vgsummary = { 0 };
- const struct format_type *fmt = labeller->fmt;
struct lvmcache_info *info;
struct lvmcache_info *info_lookup;
struct device_list *devl;
@@ -2178,7 +2177,7 @@ struct lvmcache_info *lvmcache_add(struct labeller *labeller,
if (!_found_duplicate_pvs && lvmetad_used()) {
log_warn("WARNING: Disabling lvmetad cache which does not support duplicate PVs.");
- lvmetad_set_disabled(fmt->cmd, LVMETAD_DISABLE_REASON_DUPLICATES);
+ lvmetad_set_disabled(labeller->fmt->cmd, LVMETAD_DISABLE_REASON_DUPLICATES);
}
_found_duplicate_pvs = 1;
diff --git a/lib/display/display.c b/lib/display/display.c
index 19421e7..f8dd338 100644
--- a/lib/display/display.c
+++ b/lib/display/display.c
@@ -843,7 +843,7 @@ char yes_no_prompt(const char *prompt, ...)
static const char _no[] = "no";
const char *answer = NULL;
int c = silent_mode() ? EOF : 0;
- int i, ret = 0, sig = 0;
+ int i = 0, ret = 0, sig = 0;
char buf[12];
va_list ap;
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=3fd458488649c27f…
Commit: 3fd458488649c27f18f1ddb993ba9360f259d47b
Parent: b9d3e8c8a8cd5faf23e30336303f6aeef5c32804
Author: Zdenek Kabelac <zkabelac(a)redhat.com>
AuthorDate: Thu Jun 30 10:45:58 2016 +0200
Committer: Zdenek Kabelac <zkabelac(a)redhat.com>
CommitterDate: Fri Jul 1 00:44:48 2016 +0200
cleanup: lvchange uses display_lvname
Convert messages to report vg/lv name consistently.
Also drop unneeded 'info_obtaned' variable since the
obtained info is not reused in any code path.
---
tools/lvchange.c | 212 +++++++++++++++++++++++++++---------------------------
1 files changed, 107 insertions(+), 105 deletions(-)
diff --git a/tools/lvchange.c b/tools/lvchange.c
index b9944f7..c5461f9 100644
--- a/tools/lvchange.c
+++ b/tools/lvchange.c
@@ -1,6 +1,6 @@
/*
* Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
- * Copyright (C) 2004-2014 Red Hat, Inc. All rights reserved.
+ * Copyright (C) 2004-2016 Red Hat, Inc. All rights reserved.
*
* This file is part of LVM2.
*
@@ -22,72 +22,69 @@ static int _lvchange_permission(struct cmd_context *cmd,
{
uint32_t lv_access;
struct lvinfo info;
- unsigned info_obtained = 0;
lv_access = arg_uint_value(cmd, permission_ARG, 0);
if (lv_is_external_origin(lv)) {
- log_error("Cannot change permissions of external origin "
- "\"%s\".", lv->name);
+ log_error("Cannot change permissions of external origin %s.",
+ display_lvname(lv));
return 0;
}
if (!(lv_access & LVM_WRITE) && !(lv->status & LVM_WRITE)) {
/* Refresh if it's read-only in metadata but read-write in kernel */
- if (lv_info(cmd, lv, 0, &info, 0, 0) &&
- (info_obtained = 1, info.exists) && !info.read_only) {
- log_print_unless_silent("Logical volume \"%s\" is already read-only. Refreshing kernel state.",
- lv->name);
+ if (lv_info(cmd, lv, 0, &info, 0, 0) && info.exists && !info.read_only) {
+ log_print_unless_silent("Logical volume %s is already read-only. Refreshing kernel state.",
+ display_lvname(lv));
return lv_refresh(cmd, lv);
}
- log_error("Logical volume \"%s\" is already read only",
- lv->name);
+ log_error("Logical volume \"%s\" is already read only.",
+ display_lvname(lv));
return 0;
}
if ((lv_access & LVM_WRITE) && (lv->status & LVM_WRITE)) {
/* Refresh if it's read-write in metadata but read-only in kernel */
- if (lv_info(cmd, lv, 0, &info, 0, 0) &&
- (info_obtained = 1, info.exists) && info.read_only) {
- log_print_unless_silent("Logical volume \"%s\" is already writable. Refreshing kernel state.",
- lv->name);
+ if (lv_info(cmd, lv, 0, &info, 0, 0) && info.exists && info.read_only) {
+ log_print_unless_silent("Logical volume %s is already writable. Refreshing kernel state.",
+ display_lvname(lv));
return lv_refresh(cmd, lv);
}
- log_error("Logical volume \"%s\" is already writable",
- lv->name);
+ log_error("Logical volume %s is already writable.",
+ display_lvname(lv));
return 0;
}
if (lv_is_mirrored(lv) && vg_is_clustered(lv->vg) &&
- (info_obtained || lv_info(cmd, lv, 0, &info, 0, 0)) && info.exists) {
- log_error("Cannot change permissions of mirror \"%s\" "
- "while active.", lv->name);
+ lv_info(cmd, lv, 0, &info, 0, 0) && info.exists) {
+ log_error("Cannot change permissions of mirror %s while active.",
+ display_lvname(lv));
return 0;
}
/* Not allowed to change permissions on RAID sub-LVs directly */
if (lv_is_raid_metadata(lv) || lv_is_raid_image(lv)) {
- log_error("Cannot change permissions of RAID %s \"%s\"",
- lv_is_raid_image(lv) ? "image" :
- "metadata area", lv->name);
+ log_error("Cannot change permissions of RAID %s %s.",
+ lv_is_raid_image(lv) ? "image" : "metadata area",
+ display_lvname(lv));
return 0;
}
if (!(lv_access & LVM_WRITE) && lv_is_thin_pool(lv)) {
- log_error("Change permissions of thin pool \"%s\" not "
- "yet supported.", lv->name);
+ log_error("Change permissions of thin pool %s not yet supported.",
+ display_lvname(lv));
return 0;
}
if (lv_access & LVM_WRITE) {
lv->status |= LVM_WRITE;
- log_verbose("Setting logical volume \"%s\" read/write",
- lv->name);
+ log_verbose("Setting logical volume %s read/write.",
+ display_lvname(lv));
} else {
lv->status &= ~LVM_WRITE;
- log_verbose("Setting logical volume \"%s\" read-only",
- lv->name);
+ log_verbose("Setting logical volume %s read-only.",
+ display_lvname(lv));
}
if (!lv_update_and_reload(lv))
@@ -104,7 +101,8 @@ static int _lvchange_pool_update(struct cmd_context *cmd,
thin_discards_t discards;
if (!lv_is_thin_pool(lv)) {
- log_error("Logical volume \"%s\" is not a thin pool.", lv->name);
+ log_error("Logical volume %s is not a thin pool.",
+ display_lvname(lv));
return 0;
}
@@ -114,14 +112,15 @@ static int _lvchange_pool_update(struct cmd_context *cmd,
if (((discards == THIN_DISCARDS_IGNORE) ||
(first_seg(lv)->discards == THIN_DISCARDS_IGNORE)) &&
pool_is_active(lv))
- log_error("Cannot change support for discards while pool volume \"%s\" is active.", lv->name);
+ log_error("Cannot change support for discards while pool volume %s is active.",
+ display_lvname(lv));
else {
first_seg(lv)->discards = discards;
update++;
}
} else
- log_error("Logical volume \"%s\" already uses --discards %s.",
- lv->name, get_pool_discards_name(discards));
+ log_error("Logical volume %s already uses --discards %s.",
+ display_lvname(lv), get_pool_discards_name(discards));
}
if (arg_is_set(cmd, zero_ARG)) {
@@ -130,8 +129,8 @@ static int _lvchange_pool_update(struct cmd_context *cmd,
first_seg(lv)->zero_new_blocks = val;
update++;
} else
- log_error("Logical volume \"%s\" already %szero new blocks.",
- lv->name, val ? "" : "does not ");
+ log_error("Logical volume %s already %szero new blocks.",
+ display_lvname(lv), val ? "" : "does not ");
}
if (!update)
@@ -150,7 +149,7 @@ static int _lvchange_monitoring(struct cmd_context *cmd,
if (!lv_info(cmd, lv, lv_is_thin_pool(lv) ? 1 : 0,
&info, 0, 0) || !info.exists) {
- log_error("Logical volume, %s, is not active", lv->name);
+ log_error("Logical volume %s is not active.", display_lvname(lv));
return 0;
}
@@ -171,7 +170,7 @@ static int _lvchange_background_polling(struct cmd_context *cmd,
struct lvinfo info;
if (!lv_info(cmd, lv, 0, &info, 0, 0) || !info.exists) {
- log_error("Logical volume, %s, is not active", lv->name);
+ log_error("Logical volume %s is not active.", display_lvname(lv));
return 0;
}
@@ -290,7 +289,7 @@ static int attach_metadata_devices(struct lv_segment *seg, struct dm_list *list)
*/
static int _lvchange_refresh(struct cmd_context *cmd, struct logical_volume *lv)
{
- log_verbose("Refreshing logical volume \"%s\" (if active)", lv->name);
+ log_verbose("Refreshing logical volume %s (if active).", display_lvname(lv));
return lv_refresh(cmd, lv);
}
@@ -329,33 +328,33 @@ static int _lvchange_resync(struct cmd_context *cmd, struct logical_volume *lv)
if (!seg_is_mirror(seg) && !seg_is_raid(seg)) {
log_error("Unable to resync %s. It is not RAID or mirrored.",
- lv->name);
+ display_lvname(lv));
return 0;
}
if (lv_is_pvmove(lv)) {
- log_error("Unable to resync pvmove volume %s", lv->name);
+ log_error("Unable to resync pvmove volume %s.", display_lvname(lv));
return 0;
}
if (lv_is_locked(lv)) {
- log_error("Unable to resync locked volume %s", lv->name);
+ log_error("Unable to resync locked volume %s.", display_lvname(lv));
return 0;
}
if (lv_is_active_locally(lv)) {
if (!lv_check_not_in_use(lv, 1)) {
- log_error("Can't resync open logical volume \"%s\"",
- lv->name);
+ log_error("Can't resync open logical volume %s.",
+ display_lvname(lv));
return 0;
}
if (!arg_is_set(cmd, yes_ARG) &&
yes_no_prompt("Do you really want to deactivate "
"logical volume %s to resync it? [y/n]: ",
- lv->name) == 'n') {
- log_error("Logical volume \"%s\" not resynced",
- lv->name);
+ display_lvname(lv)) == 'n') {
+ log_error("Logical volume %s not resynced.",
+ display_lvname(lv));
return 0;
}
@@ -365,8 +364,8 @@ static int _lvchange_resync(struct cmd_context *cmd, struct logical_volume *lv)
}
if (seg_is_raid(seg) && active && !exclusive) {
- log_error("RAID logical volume %s/%s cannot be active remotely.",
- lv->vg->name, lv->name);
+ log_error("RAID logical volume %s cannot be active remotely.",
+ display_lvname(lv));
return 0;
}
@@ -376,13 +375,13 @@ static int _lvchange_resync(struct cmd_context *cmd, struct logical_volume *lv)
init_dmeventd_monitor(0);
if (!deactivate_lv(cmd, lv)) {
- log_error("Unable to deactivate %s for resync", lv->name);
+ log_error("Unable to deactivate %s for resync.", display_lvname(lv));
return 0;
}
if (vg_is_clustered(lv->vg) && lv_is_active(lv)) {
- log_error("Can't get exclusive access to clustered volume %s",
- lv->name);
+ log_error("Can't get exclusive access to clustered volume %s.",
+ display_lvname(lv));
return 0;
}
@@ -390,12 +389,12 @@ static int _lvchange_resync(struct cmd_context *cmd, struct logical_volume *lv)
init_dmeventd_monitor(monitored);
init_mirror_in_sync(0);
- log_very_verbose("Starting resync of %s%s%s%s \"%s\"",
+ log_very_verbose("Starting resync of %s%s%s%s %s.",
(active) ? "active " : "",
vg_is_clustered(lv->vg) ? "clustered " : "",
(seg->log_lv) ? "disk-logged " :
seg_is_raid(seg) ? "" : "core-logged ",
- lvseg_name(seg), lv->name);
+ lvseg_name(seg), display_lvname(lv));
/*
* If this mirror has a core log (i.e. !seg->log_lv),
@@ -406,8 +405,8 @@ static int _lvchange_resync(struct cmd_context *cmd, struct logical_volume *lv)
if (!seg_is_raid(seg) && !seg->log_lv) {
if (lv->status & LV_NOTSYNCED) {
lv->status &= ~LV_NOTSYNCED;
- log_very_verbose("Updating logical volume \"%s\""
- " on disk(s)", lv->name);
+ log_very_verbose("Updating logical volume %s on disk(s).",
+ display_lvname(lv));
if (!vg_write(lv->vg) || !vg_commit(lv->vg)) {
log_error("Failed to update metadata on disk.");
return 0;
@@ -415,8 +414,8 @@ static int _lvchange_resync(struct cmd_context *cmd, struct logical_volume *lv)
}
if (!_reactivate_lv(lv, active, exclusive)) {
- log_error("Failed to reactivate %s to resynchronize "
- "mirror", lv->name);
+ log_error("Failed to reactivate %s to resynchronize mirror.",
+ display_lvname(lv));
return 0;
}
@@ -430,9 +429,9 @@ static int _lvchange_resync(struct cmd_context *cmd, struct logical_volume *lv)
/* Separate mirror log or metadata devices so we can clear them */
if (!detach_metadata_devices(seg, &device_list)) {
- log_error("Failed to clear %s %s for %s",
+ log_error("Failed to clear %s %s for %s.",
seg->segtype->name, seg_is_raid(seg) ?
- "metadata area" : "mirror log", lv->name);
+ "metadata area" : "mirror log", display_lvname(lv));
return 0;
}
@@ -448,16 +447,16 @@ static int _lvchange_resync(struct cmd_context *cmd, struct logical_volume *lv)
dm_list_iterate_items(lvl, &device_list) {
if (!activate_lv_excl_local(cmd, lvl->lv)) {
- log_error("Unable to activate %s for %s clearing",
- lvl->lv->name, (seg_is_raid(seg)) ?
+ log_error("Unable to activate %s for %s clearing.",
+ display_lvname(lvl->lv), (seg_is_raid(seg)) ?
"metadata area" : "mirror log");
return 0;
}
if (!wipe_lv(lvl->lv, (struct wipe_params)
{ .do_zero = 1, .zero_sectors = lvl->lv->size })) {
- log_error("Unable to reset sync status for %s",
- lv->name);
+ log_error("Unable to reset sync status for %s.",
+ display_lvname(lv));
if (!deactivate_lv(cmd, lvl->lv))
log_error("Failed to deactivate log LV after "
"wiping failed");
@@ -466,36 +465,37 @@ static int _lvchange_resync(struct cmd_context *cmd, struct logical_volume *lv)
if (!deactivate_lv(cmd, lvl->lv)) {
log_error("Unable to deactivate %s LV %s "
- "after wiping for resync",
+ "after wiping for resync.",
(seg_is_raid(seg)) ? "metadata" : "log",
- lvl->lv->name);
+ display_lvname(lvl->lv));
return 0;
}
}
/* Wait until devices are away */
if (!sync_local_dev_names(lv->vg->cmd)) {
- log_error("Failed to sync local devices after updating %s",
+ log_error("Failed to sync local devices after updating %s.",
display_lvname(lv));
return 0;
}
/* Put metadata sub-LVs back in place */
if (!attach_metadata_devices(seg, &device_list)) {
- log_error("Failed to reattach %s device after clearing",
+ log_error("Failed to reattach %s device after clearing.",
(seg_is_raid(seg)) ? "metadata" : "log");
return 0;
}
if (!vg_write(lv->vg) || !vg_commit(lv->vg)) {
- log_error("Failed to update metadata on disk.");
+ log_error("Failed to update metadata on disk for %s.",
+ display_lvname(lv));
return 0;
}
if (!_reactivate_lv(lv, active, exclusive)) {
backup(lv->vg);
- log_error("Failed to reactivate %s after resync",
- lv->name);
+ log_error("Failed to reactivate %s after resync.",
+ display_lvname(lv));
return 0;
}
@@ -512,8 +512,8 @@ static int _lvchange_alloc(struct cmd_context *cmd, struct logical_volume *lv)
? ALLOC_CONTIGUOUS : ALLOC_INHERIT);
if (alloc == lv->alloc) {
- log_error("Allocation policy of logical volume \"%s\" is "
- "already %s", lv->name, get_alloc_string(alloc));
+ log_error("Allocation policy of logical volume %s is already %s.",
+ display_lvname(lv), get_alloc_string(alloc));
return 0;
}
@@ -521,10 +521,10 @@ static int _lvchange_alloc(struct cmd_context *cmd, struct logical_volume *lv)
/* FIXME If contiguous, check existing extents already are */
- log_verbose("Setting contiguous allocation policy for \"%s\" to %s",
- lv->name, get_alloc_string(alloc));
+ log_verbose("Setting contiguous allocation policy for %s to %s.",
+ display_lvname(lv), get_alloc_string(alloc));
- log_very_verbose("Updating logical volume \"%s\" on disk(s)", lv->name);
+ log_very_verbose("Updating logical volume %s on disk(s).", display_lvname(lv));
/* No need to suspend LV for this change */
if (!vg_write(lv->vg) || !vg_commit(lv->vg))
@@ -584,17 +584,18 @@ static int _lvchange_readahead(struct cmd_context *cmd,
if (lv->read_ahead == read_ahead) {
if (read_ahead == DM_READ_AHEAD_AUTO)
- log_error("Read ahead is already auto for \"%s\"", lv->name);
+ log_error("Read ahead is already auto for %s.",
+ display_lvname(lv));
else
- log_error("Read ahead is already %u for \"%s\"",
- read_ahead, lv->name);
+ log_error("Read ahead is already %u for %s.",
+ read_ahead, display_lvname(lv));
return 0;
}
lv->read_ahead = read_ahead;
- log_verbose("Setting read ahead to %u for \"%s\"", read_ahead,
- lv->name);
+ log_verbose("Setting read ahead to %u for %s.",
+ read_ahead, display_lvname(lv));
if (!lv_update_and_reload(lv))
return_0;
@@ -629,7 +630,8 @@ static int _lvchange_persistent(struct cmd_context *cmd,
!arg_is_set(cmd, yes_ARG) &&
yes_no_prompt("Logical volume %s will be "
"deactivated temporarily. "
- "Continue? [y/n]: ", lv->name) == 'n') {
+ "Continue? [y/n]: ",
+ display_lvname(lv)) == 'n') {
log_error("%s device number not changed.",
display_lvname(lv));
return 0;
@@ -665,9 +667,9 @@ static int _lvchange_persistent(struct cmd_context *cmd,
return_0;
if (activate != CHANGE_AN) {
- log_verbose("Re-activating logical volume %s", display_lvname(lv));
+ log_verbose("Re-activating logical volume %s.", display_lvname(lv));
if (!lv_active_change(cmd, lv, activate, 0)) {
- log_error("%s: reactivation failed", display_lvname(lv));
+ log_error("%s: reactivation failed.", display_lvname(lv));
backup(lv->vg);
return 0;
}
@@ -736,7 +738,7 @@ static int _lvchange_tag(struct cmd_context *cmd, struct logical_volume *lv, int
if (!change_tag(cmd, NULL, lv, NULL, arg))
return_0;
- log_very_verbose("Updating logical volume \"%s\" on disk(s)", lv->name);
+ log_very_verbose("Updating logical volume %s on disk(s).", display_lvname(lv));
/* No need to suspend LV for this change */
if (!vg_write(lv->vg) || !vg_commit(lv->vg))
@@ -759,7 +761,7 @@ static int _lvchange_writemostly(struct logical_volume *lv)
struct lv_segment *raid_seg = first_seg(lv);
if (!seg_is_raid1(raid_seg)) {
- log_error("--write%s can only be used with 'raid1' segment type",
+ log_error("--write%s can only be used with 'raid1' segment type.",
arg_is_set(cmd, writemostly_ARG) ? "mostly" : "behind");
return 0;
}
@@ -853,8 +855,8 @@ static int _lvchange_recovery_rate(struct logical_volume *lv)
struct lv_segment *raid_seg = first_seg(lv);
if (!seg_is_raid(raid_seg)) {
- log_error("Unable to change the recovery rate of non-RAID"
- " logical volume.");
+ log_error("Unable to change the recovery rate of non-RAID "
+ "logical volume %s.", display_lvname(lv));
return 0;
}
@@ -867,8 +869,7 @@ static int _lvchange_recovery_rate(struct logical_volume *lv)
if (raid_seg->max_recovery_rate &&
(raid_seg->max_recovery_rate < raid_seg->min_recovery_rate)) {
- log_error("Minumum recovery rate cannot"
- " be higher than maximum.");
+ log_error("Minimum recovery rate cannot be higher than maximum.");
return 0;
}
@@ -899,7 +900,7 @@ static int _lvchange_profile(struct logical_volume *lv)
}
log_verbose("Changing configuration profile for LV %s: %s -> %s.",
- lv->name, old_profile_name, new_profile_name);
+ display_lvname(lv), old_profile_name, new_profile_name);
if (!vg_write(lv->vg) || !vg_commit(lv->vg))
return_0;
@@ -916,7 +917,7 @@ static int _lvchange_activation_skip(struct logical_volume *lv)
lv_set_activation_skip(lv, 1, skip);
log_verbose("Changing activation skip flag to %s for LV %s.",
- lv->name, skip ? "enabled" : "disabled");
+ display_lvname(lv), skip ? "enabled" : "disabled");
if (!vg_write(lv->vg) || !vg_commit(lv->vg))
return_0;
@@ -949,8 +950,8 @@ static int _lvchange_single(struct cmd_context *cmd, struct logical_volume *lv,
readahead_ARG,
zero_ARG,
-1)) {
- log_error("Only -a permitted with read-only volume "
- "group \"%s\"", lv->vg->name);
+ log_error("Only -a permitted with read-only volume group %s.",
+ lv->vg->name);
return ECMD_FAILED;
}
@@ -964,26 +965,27 @@ static int _lvchange_single(struct cmd_context *cmd, struct logical_volume *lv,
profile_ARG,
readahead_ARG,
-1)) {
- log_error("Can't change logical volume \"%s\" under snapshot",
- lv->name);
+ log_error("Can't change logical volume %s under snapshot.",
+ display_lvname(lv));
return ECMD_FAILED;
}
if (lv_is_pvmove(lv)) {
- log_error("Unable to change pvmove LV %s", lv->name);
+ log_error("Unable to change pvmove LV %s.", display_lvname(lv));
if (arg_is_set(cmd, activate_ARG))
log_error("Use 'pvmove --abort' to abandon a pvmove");
return ECMD_FAILED;
}
if (lv_is_mirror_log(lv)) {
- log_error("Unable to change mirror log LV %s directly", lv->name);
+ log_error("Unable to change mirror log LV %s directly.",
+ display_lvname(lv));
return ECMD_FAILED;
}
if (lv_is_mirror_image(lv)) {
- log_error("Unable to change mirror image LV %s directly",
- lv->name);
+ log_error("Unable to change mirror image LV %s directly.",
+ display_lvname(lv));
return ECMD_FAILED;
}
@@ -1000,8 +1002,8 @@ static int _lvchange_single(struct cmd_context *cmd, struct logical_volume *lv,
/* Rest can be changed for stacked thin pool meta/data volumes */
;
else if (!lv_is_visible(lv) && !lv_is_virtual_origin(lv)) {
- log_error("Unable to change internal LV %s directly",
- lv->name);
+ log_error("Unable to change internal LV %s directly.",
+ display_lvname(lv));
return ECMD_FAILED;
}
@@ -1278,22 +1280,22 @@ int lvchange(struct cmd_context *cmd, int argc, char **argv)
if ((arg_is_set(cmd, minor_ARG) || arg_is_set(cmd, major_ARG)) &&
!arg_is_set(cmd, persistent_ARG)) {
- log_error("--major and --minor require -My");
+ log_error("--major and --minor require -My.");
return EINVALID_CMD_LINE;
}
if (arg_is_set(cmd, minor_ARG) && argc != 1) {
- log_error("Only give one logical volume when specifying minor");
+ log_error("Only give one logical volume when specifying minor.");
return EINVALID_CMD_LINE;
}
if (arg_is_set(cmd, contiguous_ARG) && arg_is_set(cmd, alloc_ARG)) {
- log_error("Only one of --alloc and --contiguous permitted");
+ log_error("Only one of --alloc and --contiguous permitted.");
return EINVALID_CMD_LINE;
}
if (arg_is_set(cmd, poll_ARG) && arg_is_set(cmd, sysinit_ARG)) {
- log_error("Only one of --poll and --sysinit permitted");
+ log_error("Only one of --poll and --sysinit permitted.");
return EINVALID_CMD_LINE;
}
@@ -1306,7 +1308,7 @@ int lvchange(struct cmd_context *cmd, int argc, char **argv)
*/
if (arg_is_set(cmd, sysinit_ARG) && (arg_uint_value(cmd, activate_ARG, 0) == CHANGE_AAY)) {
if (lvmetad_used()) {
- log_warn("WARNING: lvmetad is active, skipping direct activation during sysinit");
+ log_warn("WARNING: lvmetad is active, skipping direct activation during sysinit.");
return ECMD_PROCESSED;
}
}
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=b9d3e8c8a8cd5faf…
Commit: b9d3e8c8a8cd5faf23e30336303f6aeef5c32804
Parent: 1e3411aa3724ee9ee32f5cb4378526b9c355854d
Author: Zdenek Kabelac <zkabelac(a)redhat.com>
AuthorDate: Thu Jun 30 10:45:52 2016 +0200
Committer: Zdenek Kabelac <zkabelac(a)redhat.com>
CommitterDate: Fri Jul 1 00:44:48 2016 +0200
cleanup: drop unused assignments
In all code paths we set a value for these variables, so drop
their initial unused assign.
---
daemons/lvmetad/lvmetad-core.c | 2 +-
daemons/lvmpolld/lvmpolld-cmd-utils.c | 2 +-
lib/cache/lvmetad.c | 2 +-
3 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/daemons/lvmetad/lvmetad-core.c b/daemons/lvmetad/lvmetad-core.c
index 1ec9e3b..31d0933 100644
--- a/daemons/lvmetad/lvmetad-core.c
+++ b/daemons/lvmetad/lvmetad-core.c
@@ -2646,7 +2646,7 @@ static response dump(lvmetad_state *s)
static response handler(daemon_state s, client_handle h, request r)
{
- response res = { 0 };
+ response res;
lvmetad_state *state = s.private;
char prev_token[128] = { 0 };
const char *rq;
diff --git a/daemons/lvmpolld/lvmpolld-cmd-utils.c b/daemons/lvmpolld/lvmpolld-cmd-utils.c
index 86f5000..f70fd0d 100644
--- a/daemons/lvmpolld/lvmpolld-cmd-utils.c
+++ b/daemons/lvmpolld/lvmpolld-cmd-utils.c
@@ -31,7 +31,7 @@ const char *polling_op(enum poll_type type)
static int add_to_cmd_arr(const char ***cmdargv, const char *str, unsigned *ind)
{
- const char **newargv = *cmdargv;
+ const char **newargv;
if (*ind && !(*ind % MIN_ARGV_SIZE)) {
newargv = dm_realloc(*cmdargv, (*ind / MIN_ARGV_SIZE + 1) * MIN_ARGV_SIZE * sizeof(char *));
diff --git a/lib/cache/lvmetad.c b/lib/cache/lvmetad.c
index 94059dd..476448d 100644
--- a/lib/cache/lvmetad.c
+++ b/lib/cache/lvmetad.c
@@ -955,7 +955,7 @@ struct volume_group *lvmetad_vg_lookup(struct cmd_context *cmd, const char *vgna
{
struct volume_group *vg = NULL;
struct volume_group *vg2 = NULL;
- daemon_reply reply = { 0 };
+ daemon_reply reply;
int found;
char uuid[64];
struct format_instance *fid = NULL;
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=1e3411aa3724ee9e…
Commit: 1e3411aa3724ee9ee32f5cb4378526b9c355854d
Parent: 458918b31953943a3cc44976388f008ca850c124
Author: Zdenek Kabelac <zkabelac(a)redhat.com>
AuthorDate: Thu Jun 30 10:27:10 2016 +0200
Committer: Zdenek Kabelac <zkabelac(a)redhat.com>
CommitterDate: Fri Jul 1 00:44:48 2016 +0200
cleanup: add extra test for argc==0
Cleaup some compiler warning about posibility to allocate 0 size.
---
daemons/cmirrord/functions.c | 6 ++++++
1 files changed, 6 insertions(+), 0 deletions(-)
diff --git a/daemons/cmirrord/functions.c b/daemons/cmirrord/functions.c
index e9d3c09..757d8e8 100644
--- a/daemons/cmirrord/functions.c
+++ b/daemons/cmirrord/functions.c
@@ -573,6 +573,12 @@ static int clog_ctr(struct dm_ulog_request *rq)
for (argc = 0, p = rq->data; (p = strstr(p, " ")); p++, argc++)
*p = '\0';
+ if (!argc) {
+ LOG_ERROR("Received constructor request with bad data %s",
+ rq->data);
+ return -EINVAL;
+ }
+
argv = malloc(argc * sizeof(char *));
if (!argv)
return -ENOMEM;
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=458918b31953943a…
Commit: 458918b31953943a3cc44976388f008ca850c124
Parent: 2f638e07e814617152d617a2ca7c8acdae41968a
Author: Zdenek Kabelac <zkabelac(a)redhat.com>
AuthorDate: Thu Jun 30 15:54:27 2016 +0200
Committer: Zdenek Kabelac <zkabelac(a)redhat.com>
CommitterDate: Fri Jul 1 00:44:46 2016 +0200
thin: fix link validation for unused thin-pool
This patch fixes link validation for used thin-pool.
Udev rules correctly creates symlinks only for unused new thin-pool.
Such thin-pool can be used by foreing apps (like Docker) thus
has /dev/vg/lv link.
However when thin-pool becomes used by thinLV - this link is no
longer exposed to user - but internal verfication missed this
and caused messages like this to be printed upon 'vgchange -ay':
The link /dev/vg/pool should have been created by udev but it was not
found. Falling back to direct link creation.
And same with 'vgchange -an':
The link /dev/vg/pool should have been removed by udev but it is still
present. Falling back to direct link removal.
This patch ensures only unused thin-pool has this link.
---
WHATS_NEW | 1 +
lib/activate/dev_manager.c | 10 ++++++++--
test/shell/thin-overprovisioning.sh | 4 ++++
3 files changed, 13 insertions(+), 2 deletions(-)
diff --git a/WHATS_NEW b/WHATS_NEW
index a73744e..4d71ea8 100644
--- a/WHATS_NEW
+++ b/WHATS_NEW
@@ -1,5 +1,6 @@
Version 2.02.159 -
=================================
+ Fix created link for a used pool for vgmknode.
Introduce and use is_power_of_2 macro.
Support conversions between striped and raid0 segment types.
Add infrastructure for raid takeover lvconvert options.
diff --git a/lib/activate/dev_manager.c b/lib/activate/dev_manager.c
index 51f1a9a..233a216 100644
--- a/lib/activate/dev_manager.c
+++ b/lib/activate/dev_manager.c
@@ -1599,6 +1599,12 @@ static int _dev_manager_lv_rmnodes(const struct logical_volume *lv)
return fs_del_lv(lv);
}
+static int _lv_has_mknode(const struct logical_volume *lv)
+{
+ return (lv_is_visible(lv) &&
+ (!lv_is_thin_pool(lv) || lv_is_new_thin_pool(lv)));
+}
+
int dev_manager_mknodes(const struct logical_volume *lv)
{
struct dm_info dminfo;
@@ -1610,7 +1616,7 @@ int dev_manager_mknodes(const struct logical_volume *lv)
if ((r = _info_run(MKNODES, name, NULL, &dminfo, NULL, NULL, 0, 0, 0, 0))) {
if (dminfo.exists) {
- if (lv_is_visible(lv))
+ if (_lv_has_mknode(lv))
r = _dev_manager_lv_mknodes(lv);
} else
r = _dev_manager_lv_rmnodes(lv);
@@ -2993,7 +2999,7 @@ static int _create_lv_symlinks(struct dev_manager *dm, struct dm_tree_node *root
r = 0;
continue;
}
- if (lv_is_visible(lvlayer->lv)) {
+ if (_lv_has_mknode(lvlayer->lv)) {
if (!_dev_manager_lv_mknodes(lvlayer->lv))
r = 0;
continue;
diff --git a/test/shell/thin-overprovisioning.sh b/test/shell/thin-overprovisioning.sh
index 8a396b6..07c74cc 100644
--- a/test/shell/thin-overprovisioning.sh
+++ b/test/shell/thin-overprovisioning.sh
@@ -24,6 +24,8 @@ aux have_thin 1 3 0 || skip
aux prepare_vg 2 33
lvcreate -L32 -T $vg/pool
+# check there is link node for UNUSED thin-pool
+test -e "$DM_DEV_DIR/$vg/pool"
# leave 12M free space
lvcreate -an -n $lv1 -L16 $vg 2>&1 | tee out
@@ -31,6 +33,8 @@ vgs $vg
lvcreate -n thin1 -V30 $vg/pool 2>&1 | tee out
not grep "WARNING: Sum" out
+# check again link node is now gone for a USED thin-pool
+test ! -e "$DM_DEV_DIR/$vg/pool"
# Pool gets overprovisioned
lvcreate -an -n thin2 -V4 $vg/pool 2>&1 | tee out
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=2f638e07e8146171…
Commit: 2f638e07e814617152d617a2ca7c8acdae41968a
Parent: 103c188681fce748ef193115c126bfbbc65fbab9
Author: Zdenek Kabelac <zkabelac(a)redhat.com>
AuthorDate: Wed Jun 29 15:56:29 2016 +0200
Committer: Zdenek Kabelac <zkabelac(a)redhat.com>
CommitterDate: Fri Jul 1 00:43:45 2016 +0200
dmeventd: thin plugin umount over 95%
Run umount code only when either thin data or metadata are
above 95% - so if there are resize failures with 60%.
system fill keep running.
Also umount will only be tried with lvm2 LVs.
Foreign users are ATM unsuppored.
---
WHATS_NEW_DM | 1 +
daemons/dmeventd/plugins/thin/dmeventd_thin.c | 99 ++++++++++++++++++++++---
2 files changed, 89 insertions(+), 11 deletions(-)
diff --git a/WHATS_NEW_DM b/WHATS_NEW_DM
index 5043c23..30d6d82 100644
--- a/WHATS_NEW_DM
+++ b/WHATS_NEW_DM
@@ -1,5 +1,6 @@
Version 1.02.129 -
=================================
+ Thin dmeventd plugin umounts lvm2 volume only when pool is 95% or more.
Version 1.02.128 - 25th June 2016
=================================
diff --git a/daemons/dmeventd/plugins/thin/dmeventd_thin.c b/daemons/dmeventd/plugins/thin/dmeventd_thin.c
index 0cef168..c27cf50 100644
--- a/daemons/dmeventd/plugins/thin/dmeventd_thin.c
+++ b/daemons/dmeventd/plugins/thin/dmeventd_thin.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2011-2015 Red Hat, Inc. All rights reserved.
+ * Copyright (C) 2011-2016 Red Hat, Inc. All rights reserved.
*
* This file is part of LVM2.
*
@@ -30,6 +30,9 @@
/* First warning when thin data or metadata is 80% full. */
#define WARNING_THRESH (DM_PERCENT_1 * 80)
+/* Umount thin LVs when thin data or metadata LV is >=
+ * and lvextend --use-policies has failed. */
+#define UMOUNT_THRESH (DM_PERCENT_1 * 95)
/* Run a check every 5%. */
#define CHECK_STEP (DM_PERCENT_1 * 5)
/* Do not bother checking thin data or metadata is less than 50% full. */
@@ -53,6 +56,53 @@ struct dso_state {
DM_EVENT_LOG_FN("thin")
+#define UUID_PREFIX "LVM-"
+
+/* Figure out device UUID has LVM- prefix and is OPEN */
+static int _has_unmountable_prefix(int major, int minor)
+{
+ struct dm_task *dmt;
+ struct dm_info info;
+ const char *uuid;
+ int r = 0;
+
+ if (!(dmt = dm_task_create(DM_DEVICE_INFO)))
+ return_0;
+
+ if (!dm_task_set_major_minor(dmt, major, minor, 1))
+ goto_out;
+
+ if (!dm_task_no_flush(dmt))
+ stack;
+
+ if (!dm_task_run(dmt))
+ goto out;
+
+ if (!dm_task_get_info(dmt, &info))
+ goto out;
+
+ if (!info.exists || !info.open_count)
+ goto out; /* Not open -> not mounted */
+
+ if (!(uuid = dm_task_get_uuid(dmt)))
+ goto out;
+
+ /* Check it's public mountable LV
+ * has prefix LVM- and UUID size is 68 chars */
+ if (memcmp(uuid, UUID_PREFIX, sizeof(UUID_PREFIX) - 1) ||
+ strlen(uuid) != 68)
+ goto out;
+
+#if THIN_DEBUG
+ log_debug("Found LV (%u:%u) %s.", major, minor, uuid);
+#endif
+ r = 1;
+out:
+ dm_task_destroy(dmt);
+
+ return r;
+}
+
/* Get dependencies for device, and try to find matching device */
static int _has_deps(const char *name, int tp_major, int tp_minor, int *dev_minor)
{
@@ -90,6 +140,9 @@ static int _has_deps(const char *name, int tp_major, int tp_minor, int *dev_mino
*dev_minor = info.minor;
+ if (!_has_unmountable_prefix(major, info.minor))
+ goto out;
+
#if THIN_DEBUG
{
char dev_name[PATH_MAX];
@@ -206,7 +259,7 @@ static int _umount_device(char *buffer, unsigned major, unsigned minor,
}
/*
- * Find all thin pool users and try to umount them.
+ * Find all thin pool LV users and try to umount them.
* TODO: work with read-only thin pool support
*/
static void _umount(struct dm_task *dmt)
@@ -240,7 +293,7 @@ out:
dm_bitset_destroy(data.minors);
}
-static void _use_policy(struct dm_task *dmt, struct dso_state *state)
+static int _use_policy(struct dm_task *dmt, struct dso_state *state)
{
#if THIN_DEBUG
log_info("dmeventd executes: %s.", state->cmd_str);
@@ -248,10 +301,12 @@ static void _use_policy(struct dm_task *dmt, struct dso_state *state)
if (!dmeventd_lvm2_run_with_lock(state->cmd_str)) {
log_error("Failed to extend thin pool %s.",
dm_task_get_name(dmt));
- _umount(dmt);
state->fails++;
- } else
- state->fails = 0;
+ return 0;
+ }
+
+ state->fails = 0;
+ return 1;
}
void process_event(struct dm_task *dmt,
@@ -267,6 +322,13 @@ void process_event(struct dm_task *dmt,
char *target_type = NULL;
char *params;
int needs_policy = 0;
+ int needs_umount = 0;
+
+#if THIN_DEBUG
+ log_debug("Watch for tp-data:%.2f%% tp-metadata:%.2f%%.",
+ dm_percent_to_float(state->data_percent_check),
+ dm_percent_to_float(state->metadata_percent_check));
+#endif
#if 0
/* No longer monitoring, waiting for remove */
@@ -275,8 +337,10 @@ void process_event(struct dm_task *dmt,
#endif
if (event & DM_EVENT_DEVICE_ERROR) {
/* Error -> no need to check and do instant resize */
- _use_policy(dmt, state);
- goto out;
+ if (_use_policy(dmt, state))
+ goto out;
+
+ stack;
}
dm_get_next_target(dmt, next, &start, &length, &target_type, ¶ms);
@@ -288,7 +352,7 @@ void process_event(struct dm_task *dmt,
if (!dm_get_status_thin_pool(state->mem, params, &tps)) {
log_error("Failed to parse status.");
- _umount(dmt);
+ needs_umount = 1;
goto out;
}
@@ -323,6 +387,9 @@ void process_event(struct dm_task *dmt,
log_warn("WARNING: Thin pool %s metadata is now %.2f%% full.",
device, dm_percent_to_float(percent));
needs_policy = 1;
+
+ if (percent >= UMOUNT_THRESH)
+ needs_umount = 1;
}
percent = dm_make_percent(tps->used_data_blocks, tps->total_data_blocks);
@@ -337,11 +404,21 @@ void process_event(struct dm_task *dmt,
log_warn("WARNING: Thin pool %s data is now %.2f%% full.",
device, dm_percent_to_float(percent));
needs_policy = 1;
+
+ if (percent >= UMOUNT_THRESH)
+ needs_umount = 1;
}
- if (needs_policy)
- _use_policy(dmt, state);
+ if (needs_policy &&
+ _use_policy(dmt, state))
+ needs_umount = 0; /* No umount when command was successful */
out:
+ if (needs_umount) {
+ _umount(dmt);
+ /* Until something changes, do not retry any more actions */
+ state->data_percent_check = state->metadata_percent_check = (DM_PERCENT_1 * 101);
+ }
+
if (tps)
dm_pool_free(state->mem, tps);
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=103c188681fce748…
Commit: 103c188681fce748ef193115c126bfbbc65fbab9
Parent: aed8bc8ae7b2f1c20a84470b033daababfb7c166
Author: David Teigland <teigland(a)redhat.com>
AuthorDate: Thu Jun 30 12:02:43 2016 -0500
Committer: David Teigland <teigland(a)redhat.com>
CommitterDate: Thu Jun 30 17:08:50 2016 -0500
lvconvert: add comments describing conversions
---
tools/lvconvert.c | 387 ++++++++++++++++++++++++++++++++++++++++++++++++-----
1 files changed, 352 insertions(+), 35 deletions(-)
diff --git a/tools/lvconvert.c b/tools/lvconvert.c
index 3b98116..795deef 100644
--- a/tools/lvconvert.c
+++ b/tools/lvconvert.c
@@ -18,6 +18,25 @@
#include "lv_alloc.h"
#include "lvconvert_poll.h"
+/*
+ * Guidelines for mapping options to operations.
+ *
+ * There should be a clear and unique correspondence between an option
+ * name and the operation to be performed.
+ *
+ * An option with a given name should always perform the same operation.
+ * If the same operation applies to two types of LV, then the same option
+ * name can be used with both LV types. But, a given option name should
+ * not be used to perform different operations depending on the LV type it
+ * is used with.
+ *
+ * --merge and --split are examples where a single option name has been
+ * overloaded with different operations. The case of --split has been
+ * corrected with the clear and unique variations --splitcache,
+ * --splitsnapshot, --splitmirror, which should allow --split to be
+ * deprecated. (The same is still needed for --merge.)
+ */
+
struct lvconvert_params {
/* Exactly one of these options is chosen */
int merge; /* Either merge_snapshot or merge_mirror is also set */
@@ -3295,24 +3314,44 @@ static int _lvconvert_cache(struct cmd_context *cmd,
* moved into the _convert_lvtype_operation() functions below.
*/
+/*
+ * Separate a COW snapshot LV from its origin.
+ * lvconvert --splitsnapshot LV
+ */
+
static int _convert_cow_snapshot_splitsnapshot(struct cmd_context *cmd, struct logical_volume *lv,
struct lvconvert_params *lp)
{
return _lvconvert_splitsnapshot(cmd, lv, lp);
}
+/*
+ * Merge a COW snapshot LV into its origin.
+ * lvconvert --merge LV
+ */
+
static int _convert_cow_snapshot_merge(struct cmd_context *cmd, struct logical_volume *lv,
struct lvconvert_params *lp)
{
return _lvconvert_merge_old_snapshot(cmd, lv, lp);
}
+/*
+ * Merge a snapshot thin LV into its origin.
+ * lvconvert --merge LV
+ */
+
static int _convert_thin_volume_merge(struct cmd_context *cmd, struct logical_volume *lv,
struct lvconvert_params *lp)
{
return _lvconvert_merge_thin_snapshot(cmd, lv, lp);
}
+/*
+ * Split and preserve a cache pool from the data portion of a thin pool LV.
+ * lvconvert --splitcache LV
+ */
+
static int _convert_thin_pool_splitcache(struct cmd_context *cmd, struct logical_volume *lv,
struct lvconvert_params *lp)
{
@@ -3328,6 +3367,11 @@ static int _convert_thin_pool_splitcache(struct cmd_context *cmd, struct logical
return _lvconvert_split_cached(cmd, sublv1);
}
+/*
+ * Split and remove a cache pool from the data portion of a thin pool LV.
+ * lvconvert --uncache LV
+ */
+
static int _convert_thin_pool_uncache(struct cmd_context *cmd, struct logical_volume *lv,
struct lvconvert_params *lp)
{
@@ -3343,16 +3387,35 @@ static int _convert_thin_pool_uncache(struct cmd_context *cmd, struct logical_vo
return _lvconvert_uncache(cmd, sublv1, lp);
}
+/*
+ * Repair a thin pool LV.
+ * lvconvert --repair LV
+ */
+
static int _convert_thin_pool_repair(struct cmd_context *cmd, struct logical_volume *lv,
struct lvconvert_params *lp)
{
return _lvconvert_thin_pool_repair(cmd, lv, lp);
}
+/*
+ * Convert the data portion of a thin pool LV to a cache LV.
+ * lvconvert --type cache LV
+ *
+ * Required options:
+ * --cachepool LV
+ *
+ * Auxiliary operation:
+ * Converts the --cachepool arg to a cache pool if it is not already.
+ *
+ * Alternate syntax:
+ * lvconvert --cache LV
+ */
+
static int _convert_thin_pool_cache(struct cmd_context *cmd, struct logical_volume *lv,
struct lvconvert_params *lp)
{
- /* lvconvert --cache includes an implicit conversion of the cachepool arg to type cache-pool. */
+ /* lvconvert --type cache includes an implicit conversion of the cachepool arg to type cache-pool. */
if (!_lvconvert_pool(cmd, lv, lp)) {
log_error("Implicit conversion of --cachepool arg to type cache-pool failed.");
return 0;
@@ -3363,24 +3426,49 @@ static int _convert_thin_pool_cache(struct cmd_context *cmd, struct logical_volu
return _lvconvert_cache(cmd, lv, lp);
}
+/*
+ * Replace the metadata LV in a thin pool LV.
+ * lvconvert --poolmetadata NewLV --thinpool LV
+ * FIXME: this will change so --swap-poolmetadata defines the operation.
+ * FIXME: should be lvconvert --swap-poolmetadata NewLV LV
+ */
+
static int _convert_thin_pool_swapmetadata(struct cmd_context *cmd, struct logical_volume *lv,
struct lvconvert_params *lp)
{
return _lvconvert_pool(cmd, lv, lp);
}
+/*
+ * Split and preserve a cache pool from a cache LV.
+ * lvconvert --splitcache LV
+ */
+
static int _convert_cache_volume_splitcache(struct cmd_context *cmd, struct logical_volume *lv,
struct lvconvert_params *lp)
{
return _lvconvert_split_cached(cmd, lv);
}
+/*
+ * Split and remove a cache pool from a cache LV.
+ * lvconvert --uncache LV
+ */
+
static int _convert_cache_volume_uncache(struct cmd_context *cmd, struct logical_volume *lv,
struct lvconvert_params *lp)
{
return _lvconvert_uncache(cmd, lv, lp);
}
+/*
+ * Split images from the raid1|mirror origin of a cache LV and use them to create a new LV.
+ * lvconvert --splitmirrors Number LV
+ *
+ * Required options:
+ * --trackchanges | --name Name
+ */
+
static int _convert_cache_volume_splitmirrors(struct cmd_context *cmd, struct logical_volume *lv,
struct lvconvert_params *lp)
{
@@ -3398,12 +3486,26 @@ static int _convert_cache_volume_splitmirrors(struct cmd_context *cmd, struct lo
return 0;
}
+/*
+ * Convert a cache LV to a thin pool (using the cache LV for thin pool data).
+ * lvconvert --type thin-pool LV
+ *
+ * Alternate syntax:
+ * This is equivalent to above, but not preferred because it's ambiguous and inconsistent.
+ * lvconvert --thinpool LV
+ */
+
static int _convert_cache_volume_thin_pool(struct cmd_context *cmd, struct logical_volume *lv,
struct lvconvert_params *lp)
{
return _lvconvert_pool(cmd, lv, lp);
}
+/*
+ * Split a cache volume from a cache pool LV.
+ * lvconvert --splitcache LV
+ */
+
static int _convert_cache_pool_splitcache(struct cmd_context *cmd, struct logical_volume *lv,
struct lvconvert_params *lp)
{
@@ -3429,30 +3531,63 @@ static int _convert_cache_pool_splitcache(struct cmd_context *cmd, struct logica
return _lvconvert_split_cached(cmd, sublv1);
}
+/*
+ * Replace the metadata LV in a cache pool LV.
+ * lvconvert --poolmetadata NewLV --cachepool LV
+ * FIXME: this will change so --swap-poolmetadata defines the operation.
+ * FIXME: should be lvconvert --swap-poolmetadata NewLV LV
+ */
+
static int _convert_cache_pool_swapmetadata(struct cmd_context *cmd, struct logical_volume *lv,
struct lvconvert_params *lp)
{
return _lvconvert_pool(cmd, lv, lp);
}
+/*
+ * Change the number of images in a mirror LV.
+ * lvconvert --mirrors Number LV
+ */
+
static int _convert_mirror_number(struct cmd_context *cmd, struct logical_volume *lv,
struct lvconvert_params *lp)
{
return _lvconvert_mirrors(cmd, lv, lp);
}
+/*
+ * Split images from a mirror LV and use them to create a new LV.
+ * lvconvert --splitmirrors Number LV
+ *
+ * Required options:
+ * --name Name
+ */
+
static int _convert_mirror_splitmirrors(struct cmd_context *cmd, struct logical_volume *lv,
struct lvconvert_params *lp)
{
return _lvconvert_mirrors(cmd, lv, lp);
}
+/*
+ * Change the type of log used by a mirror LV.
+ * lvconvert --mirrorlog Type LV
+ */
+
static int _convert_mirror_log(struct cmd_context *cmd, struct logical_volume *lv,
struct lvconvert_params *lp)
{
return _lvconvert_mirrors(cmd, lv, lp);
}
+/*
+ * Replace failed PVs in a mirror LV.
+ * lvconvert --repair LV
+ *
+ * Auxiliary operation:
+ * Removes missing, empty PVs from the VG, like vgreduce.
+ */
+
static int _convert_mirror_repair(struct cmd_context *cmd, struct logical_volume *lv,
struct lvconvert_params *lp)
{
@@ -3469,18 +3604,38 @@ static int _convert_mirror_repair(struct cmd_context *cmd, struct logical_volume
return ret;
}
+/*
+ * Convert mirror LV to raid1 LV.
+ * lvconvert --type raid1 LV
+ *
+ * FIXME: this is not yet implemented in the raid code.
+ */
+
static int _convert_mirror_raid(struct cmd_context *cmd, struct logical_volume *lv,
struct lvconvert_params *lp)
{
return _lvconvert_raid(lv, lp);
}
+/*
+ * Change the number of images in a raid1 LV.
+ * lvconvert --mirrors Number LV
+ */
+
static int _convert_raid_number(struct cmd_context *cmd, struct logical_volume *lv,
struct lvconvert_params *lp)
{
return _lvconvert_raid(lv, lp);
}
+/*
+ * Split images from a raid1 LV and use them to create a new LV.
+ * lvconvert --splitmirrors Number LV
+ *
+ * Required options:
+ * --trackchanges | --name Name
+ */
+
static int _convert_raid_splitmirrors(struct cmd_context *cmd, struct logical_volume *lv,
struct lvconvert_params *lp)
{
@@ -3488,6 +3643,12 @@ static int _convert_raid_splitmirrors(struct cmd_context *cmd, struct logical_vo
return _lvconvert_raid(lv, lp);
}
+/*
+ * Merge a raid1 LV into originalLV if the raid1 LV was
+ * previously split from the originalLV using --trackchanges.
+ * lvconvert --merge LV
+ */
+
static int _convert_raid_merge(struct cmd_context *cmd, struct logical_volume *lv,
struct lvconvert_params *lp)
{
@@ -3495,6 +3656,14 @@ static int _convert_raid_merge(struct cmd_context *cmd, struct logical_volume *l
return _lvconvert_raid(lv, lp);
}
+/*
+ * Replace failed PVs in a raid* LV.
+ * lvconvert --repair LV
+ *
+ * Auxiliary operation:
+ * Removes missing, empty PVs from the VG, like vgreduce.
+ */
+
static int _convert_raid_repair(struct cmd_context *cmd, struct logical_volume *lv,
struct lvconvert_params *lp)
{
@@ -3512,6 +3681,11 @@ static int _convert_raid_repair(struct cmd_context *cmd, struct logical_volume *
return ret;
}
+/*
+ * Replace a specific PV in a raid* LV with another PV.
+ * lvconvert --replace PV LV
+ */
+
static int _convert_raid_replace(struct cmd_context *cmd, struct logical_volume *lv,
struct lvconvert_params *lp)
{
@@ -3519,12 +3693,35 @@ static int _convert_raid_replace(struct cmd_context *cmd, struct logical_volume
return _lvconvert_raid(lv, lp);
}
+/*
+ * Combine a raid* LV with a snapshot LV that was previously
+ * split from the raid* LV using --splitsnapshot.
+ * lvconvert --type snapshot LV SnapshotLV
+ *
+ * Alternate syntax:
+ * lvconvert --snapshot LV SnapshotLV
+ */
+
static int _convert_raid_snapshot(struct cmd_context *cmd, struct logical_volume *lv,
struct lvconvert_params *lp)
{
return _lvconvert_snapshot(cmd, lv, lp);
}
+/*
+ * Convert a raid* LV to a thin LV with an external origin.
+ * lvconvert --type thin LV
+ *
+ * Required options:
+ * --thinpool LV
+ *
+ * Auxiliary operation:
+ * Converts the --thinpool arg to a thin pool if it is not already.
+ *
+ * Alternate syntax:
+ * lvconvert --thin LV
+ */
+
static int _convert_raid_thin(struct cmd_context *cmd, struct logical_volume *lv,
struct lvconvert_params *lp)
{
@@ -3537,10 +3734,24 @@ static int _convert_raid_thin(struct cmd_context *cmd, struct logical_volume *lv
return _lvconvert_thin(cmd, lv, lp);
}
+/*
+ * Convert a raid* LV to a cache LV.
+ * lvconvert --type cache LV
+ *
+ * Required options:
+ * --cachepool LV
+ *
+ * Auxiliary operation:
+ * Converts the --cachepool arg to a cache pool if it is not already.
+ *
+ * Alternate syntax:
+ * lvconvert --cache LV
+ */
+
static int _convert_raid_cache(struct cmd_context *cmd, struct logical_volume *lv,
struct lvconvert_params *lp)
{
- /* lvconvert --cache includes an implicit conversion of the cachepool arg to type cache-pool. */
+ /* lvconvert --type cache includes an implicit conversion of the cachepool arg to type cache-pool. */
if (!_lvconvert_pool(cmd, lv, lp)) {
log_error("Implicit conversion of --cachepool arg to type cache-pool failed.");
return 0;
@@ -3549,41 +3760,74 @@ static int _convert_raid_cache(struct cmd_context *cmd, struct logical_volume *l
return _lvconvert_cache(cmd, lv, lp);
}
+/*
+ * Convert a raid* LV to a thin-pool LV.
+ * lvconvert --type thin-pool LV
+ *
+ * Alternate syntax:
+ * This is equivalent to above, but not preferred because it's ambiguous and inconsistent.
+ * lvconvert --thinpool LV
+ */
+
static int _convert_raid_thin_pool(struct cmd_context *cmd, struct logical_volume *lv,
struct lvconvert_params *lp)
{
return _lvconvert_pool(cmd, lv, lp);
}
+/*
+ * Convert a raid* LV to cache-pool LV.
+ * lvconvert --type cache-pool LV
+ */
+
static int _convert_raid_cache_pool(struct cmd_context *cmd, struct logical_volume *lv,
struct lvconvert_params *lp)
{
return _lvconvert_pool(cmd, lv, lp);
}
+/*
+ * Convert a raid* LV to use a different raid level.
+ * lvconvert --type raid* LV
+ */
+
static int _convert_raid_raid(struct cmd_context *cmd, struct logical_volume *lv,
struct lvconvert_params *lp)
{
return _lvconvert_raid(lv, lp);
}
+/*
+ * Convert a raid* LV to a striped LV.
+ * lvconvert --type striped LV
+ *
+ * FIXME: this is not yet implemented in the raid code.
+ */
+
static int _convert_raid_striped(struct cmd_context *cmd, struct logical_volume *lv,
struct lvconvert_params *lp)
{
return _lvconvert_raid(lv, lp);
}
+/*
+ * Convert a raid* LV to a linear LV.
+ * lvconvert --type linear LV
+ *
+ * FIXME: this is not yet implemented in the raid code.
+ */
+
static int _convert_raid_linear(struct cmd_context *cmd, struct logical_volume *lv,
struct lvconvert_params *lp)
{
return _lvconvert_raid(lv, lp);
}
-static int _convert_striped_snapshot(struct cmd_context *cmd, struct logical_volume *lv,
- struct lvconvert_params *lp)
-{
- return _lvconvert_snapshot(cmd, lv, lp);
-}
+/*
+ * Merge a striped/linear LV into a raid1 LV if the striped/linear LV was
+ * previously split from the raid1 LV using --trackchanges.
+ * lvconvert --merge LV
+ */
static int _convert_striped_merge(struct cmd_context *cmd, struct logical_volume *lv,
struct lvconvert_params *lp)
@@ -3591,6 +3835,35 @@ static int _convert_striped_merge(struct cmd_context *cmd, struct logical_volume
return _lvconvert_raid(lv, lp);
}
+/*
+ * Combine a linear/striped LV with a snapshot LV that was previously
+ * split from the linear/striped LV using --splitsnapshot.
+ * lvconvert --type snapshot LV SnapshotLV
+ *
+ * Alternate syntax:
+ * lvconvert --snapshot LV SnapshotLV
+ */
+
+static int _convert_striped_snapshot(struct cmd_context *cmd, struct logical_volume *lv,
+ struct lvconvert_params *lp)
+{
+ return _lvconvert_snapshot(cmd, lv, lp);
+}
+
+/*
+ * Convert a striped/linear LV to a thin LV with an external origin.
+ * lvconvert --type thin LV
+ *
+ * Required options:
+ * --thinpool LV
+ *
+ * Auxiliary operation:
+ * Converts the --thinpool arg to a thin pool if it is not already.
+ *
+ * Alternate syntax:
+ * lvconvert --thin LV
+ */
+
static int _convert_striped_thin(struct cmd_context *cmd, struct logical_volume *lv,
struct lvconvert_params *lp)
{
@@ -3603,6 +3876,20 @@ static int _convert_striped_thin(struct cmd_context *cmd, struct logical_volume
return _lvconvert_thin(cmd, lv, lp);
}
+/*
+ * Convert a striped/linear LV to a cache LV.
+ * lvconvert --type cache LV
+ *
+ * Required options:
+ * --cachepool LV
+ *
+ * Auxiliary operation:
+ * Converts the --cachepool arg to a cache pool if it is not already.
+ *
+ * Alternate syntax:
+ * lvconvert --cache LV
+ */
+
static int _convert_striped_cache(struct cmd_context *cmd, struct logical_volume *lv,
struct lvconvert_params *lp)
{
@@ -3615,24 +3902,62 @@ static int _convert_striped_cache(struct cmd_context *cmd, struct logical_volume
return _lvconvert_cache(cmd, lv, lp);
}
+/*
+ * Convert a striped/linear LV to a thin-pool LV.
+ * lvconvert --type thin-pool LV
+ *
+ * Alternate syntax:
+ * This is equivalent to above, but not preferred because it's ambiguous and inconsistent.
+ * lvconvert --thinpool LV
+ */
+
static int _convert_striped_thin_pool(struct cmd_context *cmd, struct logical_volume *lv,
struct lvconvert_params *lp)
{
return _lvconvert_pool(cmd, lv, lp);
}
+/*
+ * Convert a striped/linear LV to a cache-pool LV.
+ * lvconvert --type cache-pool LV
+ */
+
static int _convert_striped_cache_pool(struct cmd_context *cmd, struct logical_volume *lv,
struct lvconvert_params *lp)
{
return _lvconvert_pool(cmd, lv, lp);
}
+/*
+ * Convert a striped/linear LV to a mirror LV.
+ * lvconvert --type mirror LV
+ *
+ * Required options:
+ * --mirrors Number
+ *
+ * Alternate syntax:
+ * This is equivalent to above when global/mirror_segtype_default="mirror".
+ * lvconvert --mirrors Number LV
+ */
+
static int _convert_striped_mirror(struct cmd_context *cmd, struct logical_volume *lv,
struct lvconvert_params *lp)
{
return _lvconvert_mirrors(cmd, lv, lp);
}
+/*
+ * Convert a striped/linear LV to a raid* LV.
+ * lvconvert --type raid* LV
+ *
+ * Required options:
+ * --mirrors Number
+ *
+ * Alternate syntax:
+ * This is equivalent to above when global/mirror_segtype_default="raid1".
+ * lvconvert --mirrors Number LV
+ */
+
static int _convert_striped_raid(struct cmd_context *cmd, struct logical_volume *lv,
struct lvconvert_params *lp)
{
@@ -3696,9 +4021,9 @@ static int _convert_thin_pool(struct cmd_context *cmd, struct logical_volume *lv
log_error("Operation not permitted on thin pool LV %s", display_lvname(lv));
log_error("Operations permitted on a thin pool LV are:\n"
- " --splitcache (operates on cache sub LV)\n"
- " --uncache (operates on cache sub LV)\n"
- " --cache (operates on data sub LV)\n"
+ " --splitcache (operates on cache sub LV)\n"
+ " --uncache (operates on cache sub LV)\n"
+ " --type cache | --cache (operates on data sub LV)\n"
" --repair\n");
return 0;
}
@@ -3718,12 +4043,12 @@ static int _convert_cache_volume(struct cmd_context *cmd, struct logical_volume
if (arg_is_set(cmd, splitmirrors_ARG))
return _convert_cache_volume_splitmirrors(cmd, lv, lp);
- /* The --thinpool alias is ambiguous and not preferred. */
+ /* Using --thinpool is ambiguous and not preferred. */
if ((new_type && !strcmp(new_type, "thin-pool")) || arg_is_set(cmd, thinpool_ARG))
return _convert_cache_volume_thin_pool(cmd, lv, lp);
- /* The --thinpool alias for --type thin-pool is not preferred, so not shown. */
+ /* The --thinpool alternative for --type thin-pool is not preferred, so not shown. */
log_error("Operation not permitted on cache LV %s", display_lvname(lv));
log_error("Operations permitted on a cache LV are:\n"
@@ -3782,6 +4107,7 @@ static int _convert_mirror(struct cmd_context *cmd, struct logical_volume *lv,
* explicit option should be added to enable this case,
* rather than making it the result of an ambiguous
* "lvconvert vg/lv" command.
+ * Add 'lvconvert --poll-mirror vg/lv' for this case.
*
* Old behavior was described as:
* "Collapsing a stack of mirrors.
@@ -3837,7 +4163,7 @@ static int _convert_raid(struct cmd_context *cmd, struct logical_volume *lv,
if (lp->cache)
return _convert_raid_cache(cmd, lv, lp);
- /* The --thinpool alias is ambiguous and not preferred. */
+ /* Using --thinpool is ambiguous and not preferred. */
if ((new_type && !strcmp(new_type, "thin-pool")) || arg_is_set(cmd, thinpool_ARG))
return _convert_raid_thin_pool(cmd, lv, lp);
@@ -3854,7 +4180,7 @@ static int _convert_raid(struct cmd_context *cmd, struct logical_volume *lv,
if (new_type && !strcmp(new_type, "linear"))
return _convert_raid_linear(cmd, lv, lp);
- /* The --thinpool alias for --type thin-pool is not preferred, so not shown. */
+ /* The --thinpool alternative for --type thin-pool is not preferred, so not shown. */
log_error("Operation not permitted on raid LV %s", display_lvname(lv));
log_error("Operations permitted on a raid LV are:\n"
@@ -3863,9 +4189,9 @@ static int _convert_raid(struct cmd_context *cmd, struct logical_volume *lv,
" --merge\n"
" --repair\n"
" --replace\n"
- " --snapshot\n"
- " --thin\n"
- " --cache\n"
+ " --type snapshot | --snapshot\n"
+ " --type thin | --thin\n"
+ " --type cache | --cache\n"
" --type thin-pool\n"
" --type cache-pool\n"
" --type raid*\n"
@@ -3884,20 +4210,20 @@ static int _convert_striped(struct cmd_context *cmd, struct logical_volume *lv,
if (new_type)
new_segtype = get_segtype_from_string(cmd, new_type);
- if (lp->snapshot)
- return _convert_striped_snapshot(cmd, lv, lp);
-
/* FIXME: add a new option to make this case more clear, e.g. --merge-splitmirror */
if (lp->merge)
return _convert_striped_merge(cmd, lv, lp);
+ if (lp->snapshot)
+ return _convert_striped_snapshot(cmd, lv, lp);
+
if (lp->thin)
return _convert_striped_thin(cmd, lv, lp);
if (lp->cache)
return _convert_striped_cache(cmd, lv, lp);
- /* The --thinpool alias is ambiguous and not preferred. */
+ /* Using --thinpool is ambiguous and not preferred. */
if ((new_type && !strcmp(new_type, "thin-pool")) || arg_is_set(cmd, thinpool_ARG))
return _convert_striped_thin_pool(cmd, lv, lp);
@@ -3919,14 +4245,14 @@ static int _convert_striped(struct cmd_context *cmd, struct logical_volume *lv,
if (arg_is_set(cmd, mirrors_ARG) && mirrors_type && !strcmp(mirrors_type, "raid1"))
return _convert_striped_raid(cmd, lv, lp);
- /* The --thinpool alias for --type thin-pool is not preferred, so not shown. */
+ /* The --thinpool alternative for --type thin-pool is not preferred, so not shown. */
log_error("Operation not permitted on striped or linear LV %s", display_lvname(lv));
log_error("Operations permitted on a striped or linear LV are:\n"
- " --snapshot\n"
" --merge\n"
- " --thin\n"
- " --cache\n"
+ " --type snapshot | --snapshot\n"
+ " --type thin | --thin\n"
+ " --type cache | --cache\n"
" --type thin-pool\n"
" --type cache-pool\n"
" --type mirror | --mirrors\n"
@@ -3949,6 +4275,7 @@ static int _convert_striped(struct cmd_context *cmd, struct logical_volume *lv,
* _convert_lvtype();
* for each lp->operation
* _convert_lvtype_operation();
+ *
*/
static int _lvconvert(struct cmd_context *cmd, struct logical_volume *lv,
@@ -3957,12 +4284,6 @@ static int _lvconvert(struct cmd_context *cmd, struct logical_volume *lv,
struct lv_segment *lv_seg = first_seg(lv);
int ret = 0;
- log_debug("lvconvert lv %s is type %s status %llx to type %s",
- display_lvname(lv),
- lv_seg->segtype->name,
- (unsigned long long)lv->status,
- arg_str_value(cmd, type_ARG, ""));
-
/*
* Check some conditions that can never be processed.
*/
@@ -4048,10 +4369,6 @@ static int _lvconvert(struct cmd_context *cmd, struct logical_volume *lv,
}
/*
- * Check for LV types that cannot be converted and print an error.
- */
-
- /*
* The intention is to explicitly check all cases above and never
* reach here, but this covers anything that was missed.
*/
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=aed8bc8ae7b2f1c2…
Commit: aed8bc8ae7b2f1c20a84470b033daababfb7c166
Parent: a8e39530efdffc42d21e9bc968ab3966b719876a
Author: Alasdair G Kergon <agk(a)redhat.com>
AuthorDate: Thu Jun 30 17:59:44 2016 +0100
Committer: Alasdair G Kergon <agk(a)redhat.com>
CommitterDate: Thu Jun 30 17:59:44 2016 +0100
macros: Use is_power_of_2.
---
WHATS_NEW | 1 +
lib/format_pool/import_export.c | 2 +-
lib/metadata/lv_manip.c | 4 ++--
lib/metadata/thin_manip.c | 2 +-
lib/metadata/vg.c | 4 ++--
lib/thin/thin.c | 4 ++--
tools/lvconvert.c | 4 ++--
tools/lvcreate.c | 4 ++--
tools/toollib.c | 2 +-
9 files changed, 14 insertions(+), 13 deletions(-)
diff --git a/WHATS_NEW b/WHATS_NEW
index 619c64d..a73744e 100644
--- a/WHATS_NEW
+++ b/WHATS_NEW
@@ -1,5 +1,6 @@
Version 2.02.159 -
=================================
+ Introduce and use is_power_of_2 macro.
Support conversions between striped and raid0 segment types.
Add infrastructure for raid takeover lvconvert options.
diff --git a/lib/format_pool/import_export.c b/lib/format_pool/import_export.c
index 39b33ba..1529df5 100644
--- a/lib/format_pool/import_export.c
+++ b/lib/format_pool/import_export.c
@@ -181,7 +181,7 @@ static int _add_stripe_seg(struct dm_pool *mem,
unsigned j;
uint32_t area_len;
- if (usp->striping & (usp->striping - 1)) {
+ if (!is_power_of_2(usp->striping)) {
log_error("Stripe size must be a power of 2");
return 0;
}
diff --git a/lib/metadata/lv_manip.c b/lib/metadata/lv_manip.c
index db71939..a706578 100644
--- a/lib/metadata/lv_manip.c
+++ b/lib/metadata/lv_manip.c
@@ -712,7 +712,7 @@ int get_default_region_size(struct cmd_context *cmd)
{
int region_size = _get_default_region_size(cmd);
- if (region_size & (region_size - 1)) {
+ if (!is_power_of_2(region_size)) {
region_size = _round_down_pow2(region_size);
log_verbose("Reducing region size to %u kiB (power of 2).",
region_size / 2);
@@ -4329,7 +4329,7 @@ static int _validate_stripesize(const struct volume_group *vg,
lp->stripe_size = vg->extent_size;
}
- if (lp->stripe_size & (lp->stripe_size - 1)) {
+ if (!is_power_of_2(lp->stripe_size)) {
log_error("Stripe size must be power of 2.");
return 0;
}
diff --git a/lib/metadata/thin_manip.c b/lib/metadata/thin_manip.c
index 06d4242..3b92909 100644
--- a/lib/metadata/thin_manip.c
+++ b/lib/metadata/thin_manip.c
@@ -588,7 +588,7 @@ int update_thin_pool_params(const struct segment_type *segtype,
*zero = find_config_tree_bool(cmd, allocation_thin_pool_zero_CFG, profile);
if (!(attr & THIN_FEATURE_BLOCK_SIZE) &&
- (*chunk_size & (*chunk_size - 1))) {
+ !is_power_of_2(*chunk_size)) {
log_error("Chunk size must be a power of 2 for this thin target version.");
return 0;
}
diff --git a/lib/metadata/vg.c b/lib/metadata/vg.c
index 01dcad9..9f48a9b 100644
--- a/lib/metadata/vg.c
+++ b/lib/metadata/vg.c
@@ -379,7 +379,7 @@ int vg_check_new_extent_size(const struct format_type *fmt, uint32_t new_extent_
}
if ((fmt->features & FMT_NON_POWER2_EXTENTS)) {
- if ((new_extent_size & (new_extent_size - 1)) &&
+ if (!is_power_of_2(new_extent_size) &&
(new_extent_size % MIN_NON_POWER2_EXTENT_SIZE)) {
log_error("Physical Extent size must be a multiple of %s when not a power of 2.",
display_size(fmt->cmd, (uint64_t) MIN_NON_POWER2_EXTENT_SIZE));
@@ -389,7 +389,7 @@ int vg_check_new_extent_size(const struct format_type *fmt, uint32_t new_extent_
}
/* Apply original format1 restrictions */
- if ((new_extent_size & (new_extent_size - 1))) {
+ if (!is_power_of_2(new_extent_size)) {
log_error("Metadata format only supports Physical Extent sizes that are powers of 2.");
return 0;
}
diff --git a/lib/thin/thin.c b/lib/thin/thin.c
index a850757..1e29566 100644
--- a/lib/thin/thin.c
+++ b/lib/thin/thin.c
@@ -271,7 +271,7 @@ static int _thin_pool_add_target_line(struct dev_manager *dm,
}
if (!(attr & THIN_FEATURE_BLOCK_SIZE) &&
- (seg->chunk_size & (seg->chunk_size - 1))) {
+ !is_power_of_2(seg->chunk_size)) {
log_error("Thin pool target does not support %s chunk size (needs"
" kernel >= 3.6).", display_size(cmd, seg->chunk_size));
return 0;
@@ -311,7 +311,7 @@ static int _thin_pool_add_target_line(struct dev_manager *dm,
/* Use ignore for discards ignore or non-power-of-2 chunk_size and <1.5 target */
/* FIXME: Check whether underlying dev supports discards */
if (((!(attr & THIN_FEATURE_DISCARDS_NON_POWER_2) &&
- (seg->chunk_size & (seg->chunk_size - 1))) ||
+ !is_power_of_2(seg->chunk_size)) ||
(seg->discards == THIN_DISCARDS_IGNORE))) {
if (!dm_tree_node_set_thin_pool_discard(node, 1, 0))
return_0;
diff --git a/tools/lvconvert.c b/tools/lvconvert.c
index 8ceb1c7..3b98116 100644
--- a/tools/lvconvert.c
+++ b/tools/lvconvert.c
@@ -650,7 +650,7 @@ static int _read_params(struct cmd_context *cmd, int argc, char **argv,
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))) {
+ !is_power_of_2(lp->chunk_size)) {
log_error("Chunk size must be a power of 2 in the "
"range 4K to 512K");
return 0;
@@ -724,7 +724,7 @@ static int _read_params(struct cmd_context *cmd, int argc, char **argv,
return 0;
}
- if (lp->region_size & (lp->region_size - 1)) {
+ if (!is_power_of_2(lp->region_size)) {
log_error("Region size (%" PRIu32
") must be a power of 2", lp->region_size);
return 0;
diff --git a/tools/lvcreate.c b/tools/lvcreate.c
index 6b99717..8db68c1 100644
--- a/tools/lvcreate.c
+++ b/tools/lvcreate.c
@@ -555,7 +555,7 @@ static int _read_mirror_and_raid_params(struct cmd_context *cmd,
return 0;
}
- if (lp->region_size & (lp->region_size - 1)) {
+ if (!is_power_of_2(lp->region_size)) {
log_error("Region size (%" PRIu32 ") must be a power of 2",
lp->region_size);
return 0;
@@ -1036,7 +1036,7 @@ static int _lvcreate_params(struct cmd_context *cmd,
if (lp->snapshot && (lp->extents || lcp->size)) {
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))) {
+ !is_power_of_2(lp->chunk_size)) {
log_error("Chunk size must be a power of 2 in the "
"range 4K to 512K.");
return 0;
diff --git a/tools/toollib.c b/tools/toollib.c
index 35b687b..a76599c 100644
--- a/tools/toollib.c
+++ b/tools/toollib.c
@@ -1294,7 +1294,7 @@ static int _validate_stripe_params(struct cmd_context *cmd, uint32_t *stripes,
}
if (*stripes > 1 && (*stripe_size < STRIPE_SIZE_MIN ||
- *stripe_size & (*stripe_size - 1))) {
+ !is_power_of_2(*stripe_size))) {
log_error("Invalid stripe size %s.",
display_size(cmd, (uint64_t) *stripe_size));
return 0;
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=a8e39530efdffc42…
Commit: a8e39530efdffc42d21e9bc968ab3966b719876a
Parent: 802ed9d4597443e21086b392d9ee160f6d99dde9
Author: David Teigland <teigland(a)redhat.com>
AuthorDate: Thu Jun 30 10:09:54 2016 -0500
Committer: David Teigland <teigland(a)redhat.com>
CommitterDate: Thu Jun 30 10:09:54 2016 -0500
lvconvert: add missing alias for a thin-pool conversion
The case of converting a cache volume to a thin pool missed
recognizing the --thinpool alias for --type thin-pool.
---
tools/lvconvert.c | 6 +++++-
1 files changed, 5 insertions(+), 1 deletions(-)
diff --git a/tools/lvconvert.c b/tools/lvconvert.c
index 4808090..8ceb1c7 100644
--- a/tools/lvconvert.c
+++ b/tools/lvconvert.c
@@ -3718,9 +3718,13 @@ static int _convert_cache_volume(struct cmd_context *cmd, struct logical_volume
if (arg_is_set(cmd, splitmirrors_ARG))
return _convert_cache_volume_splitmirrors(cmd, lv, lp);
- if (new_type && !strcmp(new_type, "thin-pool"))
+ /* The --thinpool alias is ambiguous and not preferred. */
+
+ if ((new_type && !strcmp(new_type, "thin-pool")) || arg_is_set(cmd, thinpool_ARG))
return _convert_cache_volume_thin_pool(cmd, lv, lp);
+ /* The --thinpool alias for --type thin-pool is not preferred, so not shown. */
+
log_error("Operation not permitted on cache LV %s", display_lvname(lv));
log_error("Operations permitted on a cache LV are:\n"
" --splitcache\n"
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=802ed9d4597443e2…
Commit: 802ed9d4597443e21086b392d9ee160f6d99dde9
Parent: 2282f53ac73d33311661226894ee90e72772f0db
Author: David Teigland <teigland(a)redhat.com>
AuthorDate: Wed Jun 29 16:59:32 2016 -0500
Committer: David Teigland <teigland(a)redhat.com>
CommitterDate: Wed Jun 29 16:59:32 2016 -0500
lvconvert: remove unused code
This code became unused with the previous commit 2282f5.
---
tools/lvconvert.c | 221 -----------------------------------------------------
1 files changed, 0 insertions(+), 221 deletions(-)
diff --git a/tools/lvconvert.c b/tools/lvconvert.c
index 1a863a4..4808090 100644
--- a/tools/lvconvert.c
+++ b/tools/lvconvert.c
@@ -2023,68 +2023,6 @@ static int _lvconvert_split_cached(struct cmd_context *cmd,
return 1;
}
-#if 0
-static int _lvconvert_splitcache(struct cmd_context *cmd,
- struct logical_volume *lv,
- struct lvconvert_params *lp)
-{
- struct lv_segment *seg;
-
- if (lv_is_thin_pool(lv))
- lv = seg_lv(first_seg(lv), 0); /* cached _tdata ? */
-
- /* When passed used cache-pool of used cached LV -> split cached LV */
- if (lv_is_cache_pool(lv) &&
- (dm_list_size(&lv->segs_using_this_lv) == 1) &&
- (seg = get_only_segment_using_this_lv(lv)) &&
- seg_is_cache(seg))
- lv = seg->lv;
-
- /* Supported LV types for split */
- if (!lv_is_cache(lv)) {
- log_error("Split of %s is not cache.", display_lvname(lv));
- return 0;
- }
-
- if (!_lvconvert_split_cached(cmd, lv))
- return_0;
-
- return 1;
-}
-#endif
-
-#if 0
-static int _lvconvert_split(struct cmd_context *cmd,
- struct logical_volume *lv,
- struct lvconvert_params *lp)
-{
- struct lv_segment *seg;
-
- if (lv_is_thin_pool(lv) &&
- lv_is_cache(seg_lv(first_seg(lv), 0)))
- lv = seg_lv(first_seg(lv), 0); /* cached _tdata ? */
-
- /* When passed used cache-pool of used cached LV -> split cached LV */
- if (lv_is_cache_pool(lv) &&
- (dm_list_size(&lv->segs_using_this_lv) == 1) &&
- (seg = get_only_segment_using_this_lv(lv)) &&
- seg_is_cache(seg))
- lv = seg->lv;
-
- /* Supported LV types for split */
- if (lv_is_cache(lv)) {
- if (!_lvconvert_split_cached(cmd, lv))
- return_0;
- /* Add more types here */
- } else {
- log_error("Split of %s is unsupported.", display_lvname(lv));
- return 0;
- }
-
- return 1;
-}
-#endif
-
static int _lvconvert_uncache(struct cmd_context *cmd,
struct logical_volume *lv,
struct lvconvert_params *lp)
@@ -3341,165 +3279,6 @@ static int _lvconvert_cache(struct cmd_context *cmd,
return 1;
}
-#if 0
-static int _lvconvert(struct cmd_context *cmd, struct logical_volume *lv,
- struct lvconvert_params *lp)
-{
- struct logical_volume *origin = NULL;
- struct dm_list *failed_pvs;
-
- if (lv_is_locked(lv)) {
- log_error("Cannot convert locked LV %s.", display_lvname(lv));
- return ECMD_FAILED;
- }
-
- if (lv_is_cow(lv) && !lp->merge_snapshot && !lp->splitsnapshot) {
- log_error("Cannot convert snapshot logical volume %s.",
- display_lvname(lv));
- return ECMD_FAILED;
- }
-
- if (lv_is_pvmove(lv)) {
- log_error("Unable to convert pvmove LV %s.",
- display_lvname(lv));
- return ECMD_FAILED;
- }
-
- if (lp->splitsnapshot) {
- if (!_lvconvert_splitsnapshot(cmd, lv, lp))
- return_ECMD_FAILED;
- return ECMD_PROCESSED;
- }
-
- if (lp->splitcache) {
- if (!_lvconvert_splitcache(cmd, lv, lp))
- return_ECMD_FAILED;
- return ECMD_PROCESSED;
- }
-
- if (lp->split) {
- if (!_lvconvert_split(cmd, lv, lp))
- return_ECMD_FAILED;
- return ECMD_PROCESSED;
- }
-
- if (lp->uncache) {
- if (!_lvconvert_uncache(cmd, lv, lp))
- return_ECMD_FAILED;
- return ECMD_PROCESSED;
- }
-
- /* Validate origin prior we start conversion of pool */
- if (lp->cache &&
- !validate_lv_cache_create_origin(lv))
- return_ECMD_FAILED;
-
- if (lp->thin) {
- if (lv_is_cache_type(lv) ||
- lv_is_pool(lv) ||
- lv_is_thin_pool_data(lv) ||
- lv_is_thin_pool_metadata(lv)) {
- log_error("Can't convert %s %s to external origin.",
- first_seg(lv)->segtype->name,
- display_lvname(lv));
- return ECMD_FAILED;
- }
- }
-
- if (lp->repair) {
- if (lv_is_pool(lv)) {
- if (lv_is_cache_pool(lv)) {
- log_error("Repair for cache pool %s not yet implemented.",
- display_lvname(lv));
- return ECMD_FAILED;
- }
- if (!_lvconvert_thin_pool_repair(cmd, lv, lp))
- return_ECMD_FAILED;
- return ECMD_PROCESSED;
- }
- if (!lv_is_mirrored(lv) && !lv_is_raid(lv)) {
- if (arg_is_set(cmd, usepolicies_ARG))
- return ECMD_PROCESSED; /* nothing to be done here */
- log_error("Cannot repair logical volume %s of segtype %s.",
- display_lvname(lv), lvseg_name(first_seg(lv)));
- return ECMD_FAILED;
- }
- }
-
- /* forward splitmirror operations to the cache origin, which may be raid
- * or old-style mirror */
- if (lp->keep_mimages && lv_is_cache_type(lv) &&
- (origin = seg_lv(first_seg(lv), 0)) && lv_is_cache_origin(origin)) {
- log_warn("WARNING: Selected operation does not work with cache-type LVs.");
- log_warn("WARNING: Proceeding using the cache origin volume %s instead.",
- display_lvname(origin));
- lv = origin;
- }
-
- if (!lp->segtype) {
- /* segtype not explicitly set in _read_params */
- lp->segtype = first_seg(lv)->segtype;
-
- /*
- * If we are converting to mirror/raid1 and
- * the segtype was not specified, then we need
- * to consult the default.
- */
- if (lp->mirrors_supplied && !lv_is_mirrored(lv)) {
- 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_snapshot) {
- if ((lv_is_thin_volume(lv) && !_lvconvert_merge_thin_snapshot(cmd, lv, lp)) ||
- (!lv_is_thin_volume(lv) && !_lvconvert_merge_old_snapshot(cmd, lv, lp))) {
- log_print_unless_silent("Unable to merge volume %s into its origin.",
- display_lvname(lv));
- return ECMD_FAILED;
- }
- } else if (lp->snapshot) {
- if (!_lvconvert_snapshot(cmd, lv, lp))
- return_ECMD_FAILED;
- } else if (segtype_is_pool(lp->segtype) || lp->thin || lp->cache) {
- if (!_lvconvert_pool(cmd, lv, lp))
- return_ECMD_FAILED;
-
- if ((lp->thin && !_lvconvert_thin(cmd, lv, lp)) ||
- (lp->cache && !_lvconvert_cache(cmd, lv, lp)))
- return_ECMD_FAILED;
- } else if (segtype_is_raid(lp->segtype) ||
- (lv->status & RAID) || lp->merge_mirror) {
- if (!archive(lv->vg))
- return_ECMD_FAILED;
-
- if (!_lvconvert_raid(lv, lp))
- return_ECMD_FAILED;
-
- if (!(failed_pvs = _failed_pv_list(lv->vg)))
- return_ECMD_FAILED;
-
- /* If repairing and using policies, remove missing PVs from VG */
- if (lp->repair && arg_is_set(cmd, usepolicies_ARG))
- _remove_missing_empty_pv(lv->vg, failed_pvs);
- } else if (lp->mirrors_supplied || lp->keep_mimages || lv_is_mirrored(lv)) {
- if (!archive(lv->vg))
- return_ECMD_FAILED;
-
- if (!_lvconvert_mirrors(cmd, lv, lp))
- return_ECMD_FAILED;
-
- if (!(failed_pvs = _failed_pv_list(lv->vg)))
- return_ECMD_FAILED;
-
- /* If repairing and using policies, remove missing PVs from VG */
- if (lp->repair && arg_is_set(cmd, usepolicies_ARG))
- _remove_missing_empty_pv(lv->vg, failed_pvs);
- }
-
- return ECMD_PROCESSED;
-}
-#endif
-
/*
* Functions called to perform a specific operation on a specific LV type.
*
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=2282f53ac73d3331…
Commit: 2282f53ac73d33311661226894ee90e72772f0db
Parent: eac0706761e628532ffcd27f3e4d7fa559a5f818
Author: David Teigland <teigland(a)redhat.com>
AuthorDate: Tue Jun 28 12:24:41 2016 -0500
Committer: David Teigland <teigland(a)redhat.com>
CommitterDate: Wed Jun 29 16:55:27 2016 -0500
lvconvert: rework routing of operations
Add new logic to identify each unique operation and route
it to the correct function to perform it. The functions
that perform the conversions remain unchanged.
This new code checks every allowed combination of LV type
and requested operation, and for each valid combination
calls the function that performs that conversion.
The first stage of option validation which checks for
incompatible combinations of command line options, is done
done before process_each is called. This is unchanged.
(This new code will allow that first stage validation to
be simplified in a future commit.)
The second stage of checking options against the specific
LV type is done by this new code. For each valid combination
of operation + LV type, the new code calls an existing
function that implements it.
With this in place, the ad hoc checks for valid combinations
of LV types and operations can be removed from the existing
code in a future commit.
(The #if 0 is used to keep the patch clean, and the
disabled code will be removed by a following patch.)
---
test/shell/lvconvert-cache.sh | 2 +-
test/shell/lvconvert-mirror.sh | 21 +-
tools/lvconvert.c | 786 ++++++++++++++++++++++++++++++++++++++++
3 files changed, 799 insertions(+), 10 deletions(-)
diff --git a/test/shell/lvconvert-cache.sh b/test/shell/lvconvert-cache.sh
index cab5964..58274de 100644
--- a/test/shell/lvconvert-cache.sh
+++ b/test/shell/lvconvert-cache.sh
@@ -144,7 +144,7 @@ lvcreate -H -L 4 -n corigin --cachepool $vg/cpool
# unsupported yet
fail lvconvert --repair $vg/cpool 2>&1 | tee out
-grep "not yet implemented" out
+grep "Cannot convert internal LV" out
lvremove -f $vg
diff --git a/test/shell/lvconvert-mirror.sh b/test/shell/lvconvert-mirror.sh
index 078ebad..1d4fb08 100644
--- a/test/shell/lvconvert-mirror.sh
+++ b/test/shell/lvconvert-mirror.sh
@@ -85,9 +85,12 @@ offset=$(( offset + 2 ))
# update in case mirror ever gets faster and allows parallel read
aux delay_dev "$dev2" 0 2000 ${offset}:1
lvcreate -aey -l5 -Zn -Wn --type mirror --regionsize 16K -m2 -n $lv1 $vg "$dev1" "$dev2" "$dev4" "$dev3:$DEVRANGE"
+# FIXME: add a new explicit option to define the polling behavior
+# done here with 'lvconvert vg/lv'. That option can specify
+# that the command succeeds even if the LV doesn't need polling.
should not lvconvert -m-1 $vg/$lv1 "$dev1"
aux enable_dev "$dev2"
-lvconvert $vg/$lv1 # wait
+should lvconvert $vg/$lv1 # wait
lvconvert -m2 $vg/$lv1 "$dev1" "$dev2" "$dev4" "$dev3:0" # If the above "should" failed...
aux wait_for_sync $vg $lv1
@@ -113,7 +116,7 @@ LVM_TEST_TAG="kill_me_$PREFIX" lvconvert -m+1 -b $vg/$lv1 "$dev4"
# Next convert should fail b/c we can't have 2 at once
should not lvconvert -m+1 $vg/$lv1 "$dev5"
aux enable_dev "$dev4"
-lvconvert $vg/$lv1 # wait
+should lvconvert $vg/$lv1 # wait
lvconvert -m2 $vg/$lv1 # In case the above "should" actually failed
check mirror $vg $lv1 "$dev3"
@@ -156,7 +159,7 @@ lvcreate -aey -l2 --type mirror -m1 -n $lv1 $vg "$dev1" "$dev2" "$dev3:$DEVRANGE
lvchange -an $vg/$lv1
lvconvert -m+1 $vg/$lv1 "$dev4"
lvchange -aey $vg/$lv1
-lvconvert $vg/$lv1 # wait
+should lvconvert $vg/$lv1 # wait
check mirror $vg $lv1 "$dev3"
check mirror_no_temporaries $vg $lv1
lvremove -ff $vg
@@ -168,7 +171,7 @@ lvremove -ff $vg
lvcreate -aey -l2 --type mirror -m1 -n $lv1 $vg "$dev1" "$dev2" "$dev3:$DEVRANGE"
LVM_TEST_TAG="kill_me_$PREFIX" lvconvert -m+1 -b $vg/$lv1 "$dev4"
lvconvert -m-1 $vg/$lv1 "$dev4"
-lvconvert $vg/$lv1 # wait
+should lvconvert $vg/$lv1 # wait
check mirror $vg $lv1 "$dev3"
check mirror_no_temporaries $vg $lv1
@@ -179,7 +182,7 @@ lvremove -ff $vg
lvcreate -aey -l2 --type mirror -m1 -n $lv1 $vg "$dev1" "$dev2" "$dev3:$DEVRANGE"
LVM_TEST_TAG="kill_me_$PREFIX" lvconvert -m+2 -b $vg/$lv1 "$dev4" "$dev5"
lvconvert -m-1 $vg/$lv1 "$dev4"
-lvconvert $vg/$lv1 # wait
+should lvconvert $vg/$lv1 # wait
check mirror $vg $lv1 "$dev3"
check mirror_no_temporaries $vg $lv1
@@ -192,9 +195,9 @@ LVM_TEST_TAG="kill_me_$PREFIX" lvconvert -m+1 -b $vg/$lv1 "$dev4"
# FIXME: Extra wait here for mirror upconvert synchronization
# otherwise we may fail her on parallel upconvert and downconvert
# lvconvert-mirror-updown.sh tests this errornous case separately
-lvconvert $vg/$lv1
+should lvconvert $vg/$lv1
lvconvert -m-1 $vg/$lv1 "$dev2"
-lvconvert $vg/$lv1
+should lvconvert $vg/$lv1
check mirror $vg $lv1 "$dev3"
check mirror_no_temporaries $vg $lv1
@@ -207,9 +210,9 @@ LVM_TEST_TAG="kill_me_$PREFIX" lvconvert -m+1 -b $vg/$lv1 "$dev4"
# FIXME: Extra wait here for mirror upconvert synchronization
# otherwise we may fail her on parallel upconvert and downconvert
# lvconvert-mirror-updown.sh tests this errornous case separately
-lvconvert $vg/$lv1
+should lvconvert $vg/$lv1
lvconvert -m-1 $vg/$lv1 "$dev2"
-lvconvert $vg/$lv1
+should lvconvert $vg/$lv1
check mirror $vg $lv1 "$dev3"
check mirror_no_temporaries $vg $lv1
diff --git a/tools/lvconvert.c b/tools/lvconvert.c
index 65143a1..1a863a4 100644
--- a/tools/lvconvert.c
+++ b/tools/lvconvert.c
@@ -2023,6 +2023,7 @@ static int _lvconvert_split_cached(struct cmd_context *cmd,
return 1;
}
+#if 0
static int _lvconvert_splitcache(struct cmd_context *cmd,
struct logical_volume *lv,
struct lvconvert_params *lp)
@@ -2050,7 +2051,9 @@ static int _lvconvert_splitcache(struct cmd_context *cmd,
return 1;
}
+#endif
+#if 0
static int _lvconvert_split(struct cmd_context *cmd,
struct logical_volume *lv,
struct lvconvert_params *lp)
@@ -2080,6 +2083,7 @@ static int _lvconvert_split(struct cmd_context *cmd,
return 1;
}
+#endif
static int _lvconvert_uncache(struct cmd_context *cmd,
struct logical_volume *lv,
@@ -3337,6 +3341,7 @@ static int _lvconvert_cache(struct cmd_context *cmd,
return 1;
}
+#if 0
static int _lvconvert(struct cmd_context *cmd, struct logical_volume *lv,
struct lvconvert_params *lp)
{
@@ -3493,6 +3498,787 @@ static int _lvconvert(struct cmd_context *cmd, struct logical_volume *lv,
return ECMD_PROCESSED;
}
+#endif
+
+/*
+ * Functions called to perform a specific operation on a specific LV type.
+ *
+ * _convert_<lvtype>_<operation>
+ *
+ * For cases where an operation does not apply to the LV itself, but
+ * is implicitly redirected to a sub-LV, these functions locate the
+ * correct sub-LV and call the operation on that sub-LV. If a sub-LV
+ * of the proper type is not found, these functions report the error.
+ *
+ * FIXME: the _lvconvert_foo() functions can be cleaned up since they
+ * are now only called for valid combinations of LV type and operation.
+ * After that happens, the code remaining in those functions can be
+ * moved into the _convert_lvtype_operation() functions below.
+ */
+
+static int _convert_cow_snapshot_splitsnapshot(struct cmd_context *cmd, struct logical_volume *lv,
+ struct lvconvert_params *lp)
+{
+ return _lvconvert_splitsnapshot(cmd, lv, lp);
+}
+
+static int _convert_cow_snapshot_merge(struct cmd_context *cmd, struct logical_volume *lv,
+ struct lvconvert_params *lp)
+{
+ return _lvconvert_merge_old_snapshot(cmd, lv, lp);
+}
+
+static int _convert_thin_volume_merge(struct cmd_context *cmd, struct logical_volume *lv,
+ struct lvconvert_params *lp)
+{
+ return _lvconvert_merge_thin_snapshot(cmd, lv, lp);
+}
+
+static int _convert_thin_pool_splitcache(struct cmd_context *cmd, struct logical_volume *lv,
+ struct lvconvert_params *lp)
+{
+ struct logical_volume *sublv1;
+
+ sublv1 = seg_lv(first_seg(lv), 0); /* cached _tdata ? */
+
+ if (!lv_is_cache(sublv1)) {
+ log_error("Sub LV %s must be cache.", display_lvname(sublv1));
+ return 0;
+ }
+
+ return _lvconvert_split_cached(cmd, sublv1);
+}
+
+static int _convert_thin_pool_uncache(struct cmd_context *cmd, struct logical_volume *lv,
+ struct lvconvert_params *lp)
+{
+ struct logical_volume *sublv1 = NULL;
+
+ sublv1 = seg_lv(first_seg(lv), 0); /* cached _tdata ? */
+
+ if (!lv_is_cache(sublv1)) {
+ log_error("Sub LV %s must be cache.", display_lvname(sublv1));
+ return 0;
+ }
+
+ return _lvconvert_uncache(cmd, sublv1, lp);
+}
+
+static int _convert_thin_pool_repair(struct cmd_context *cmd, struct logical_volume *lv,
+ struct lvconvert_params *lp)
+{
+ return _lvconvert_thin_pool_repair(cmd, lv, lp);
+}
+
+static int _convert_thin_pool_cache(struct cmd_context *cmd, struct logical_volume *lv,
+ struct lvconvert_params *lp)
+{
+ /* lvconvert --cache includes an implicit conversion of the cachepool arg to type cache-pool. */
+ if (!_lvconvert_pool(cmd, lv, lp)) {
+ log_error("Implicit conversion of --cachepool arg to type cache-pool failed.");
+ return 0;
+ }
+
+ /* Do we need to grab the tdata sub LV to pass on? */
+
+ return _lvconvert_cache(cmd, lv, lp);
+}
+
+static int _convert_thin_pool_swapmetadata(struct cmd_context *cmd, struct logical_volume *lv,
+ struct lvconvert_params *lp)
+{
+ return _lvconvert_pool(cmd, lv, lp);
+}
+
+static int _convert_cache_volume_splitcache(struct cmd_context *cmd, struct logical_volume *lv,
+ struct lvconvert_params *lp)
+{
+ return _lvconvert_split_cached(cmd, lv);
+}
+
+static int _convert_cache_volume_uncache(struct cmd_context *cmd, struct logical_volume *lv,
+ struct lvconvert_params *lp)
+{
+ return _lvconvert_uncache(cmd, lv, lp);
+}
+
+static int _convert_cache_volume_splitmirrors(struct cmd_context *cmd, struct logical_volume *lv,
+ struct lvconvert_params *lp)
+{
+ struct logical_volume *sublv1;
+
+ sublv1 = seg_lv(first_seg(lv), 0);
+
+ if (lv_is_raid(sublv1))
+ return _lvconvert_raid(sublv1, lp);
+
+ if (lv_is_mirror(sublv1))
+ return _lvconvert_mirrors(cmd, lv, lp);
+
+ log_error("Sub LV %s must be raid or mirror.", display_lvname(sublv1));
+ return 0;
+}
+
+static int _convert_cache_volume_thin_pool(struct cmd_context *cmd, struct logical_volume *lv,
+ struct lvconvert_params *lp)
+{
+ return _lvconvert_pool(cmd, lv, lp);
+}
+
+static int _convert_cache_pool_splitcache(struct cmd_context *cmd, struct logical_volume *lv,
+ struct lvconvert_params *lp)
+{
+ struct logical_volume *sublv1;
+ struct lv_segment *seg;
+
+ /* When passed used cache-pool of used cached LV -> split cached LV */
+
+ if ((dm_list_size(&lv->segs_using_this_lv) == 1) &&
+ (seg = get_only_segment_using_this_lv(lv)) &&
+ seg_is_cache(seg))
+ sublv1 = seg->lv;
+ else {
+ log_error("Sub LV of cache type not found.");
+ return 0;
+ }
+
+ if (!lv_is_cache(sublv1)) {
+ log_error("Sub LV %s must be cache.", display_lvname(sublv1));
+ return 0;
+ }
+
+ return _lvconvert_split_cached(cmd, sublv1);
+}
+
+static int _convert_cache_pool_swapmetadata(struct cmd_context *cmd, struct logical_volume *lv,
+ struct lvconvert_params *lp)
+{
+ return _lvconvert_pool(cmd, lv, lp);
+}
+
+static int _convert_mirror_number(struct cmd_context *cmd, struct logical_volume *lv,
+ struct lvconvert_params *lp)
+{
+ return _lvconvert_mirrors(cmd, lv, lp);
+}
+
+static int _convert_mirror_splitmirrors(struct cmd_context *cmd, struct logical_volume *lv,
+ struct lvconvert_params *lp)
+{
+ return _lvconvert_mirrors(cmd, lv, lp);
+}
+
+static int _convert_mirror_log(struct cmd_context *cmd, struct logical_volume *lv,
+ struct lvconvert_params *lp)
+{
+ return _lvconvert_mirrors(cmd, lv, lp);
+}
+
+static int _convert_mirror_repair(struct cmd_context *cmd, struct logical_volume *lv,
+ struct lvconvert_params *lp)
+{
+ struct dm_list *failed_pvs;
+ int ret;
+
+ ret = _lvconvert_mirrors_repair(cmd, lv, lp);
+
+ if (ret && arg_is_set(cmd, usepolicies_ARG)) {
+ if ((failed_pvs = _failed_pv_list(lv->vg)))
+ _remove_missing_empty_pv(lv->vg, failed_pvs);
+ }
+
+ return ret;
+}
+
+static int _convert_mirror_raid(struct cmd_context *cmd, struct logical_volume *lv,
+ struct lvconvert_params *lp)
+{
+ return _lvconvert_raid(lv, lp);
+}
+
+static int _convert_raid_number(struct cmd_context *cmd, struct logical_volume *lv,
+ struct lvconvert_params *lp)
+{
+ return _lvconvert_raid(lv, lp);
+}
+
+static int _convert_raid_splitmirrors(struct cmd_context *cmd, struct logical_volume *lv,
+ struct lvconvert_params *lp)
+{
+ /* FIXME: split the splitmirrors section out of _lvconvert_raid and call it here. */
+ return _lvconvert_raid(lv, lp);
+}
+
+static int _convert_raid_merge(struct cmd_context *cmd, struct logical_volume *lv,
+ struct lvconvert_params *lp)
+{
+ /* FIXME: split the merge section out of _lvconvert_raid and call it here. */
+ return _lvconvert_raid(lv, lp);
+}
+
+static int _convert_raid_repair(struct cmd_context *cmd, struct logical_volume *lv,
+ struct lvconvert_params *lp)
+{
+ struct dm_list *failed_pvs;
+ int ret;
+
+ /* FIXME: split the repair section out of _lvconvert_raid and call it here. */
+ ret = _lvconvert_raid(lv, lp);
+
+ if (ret && arg_is_set(cmd, usepolicies_ARG)) {
+ if ((failed_pvs = _failed_pv_list(lv->vg)))
+ _remove_missing_empty_pv(lv->vg, failed_pvs);
+ }
+
+ return ret;
+}
+
+static int _convert_raid_replace(struct cmd_context *cmd, struct logical_volume *lv,
+ struct lvconvert_params *lp)
+{
+ /* FIXME: remove the replace section from _lvconvert_raid */
+ return _lvconvert_raid(lv, lp);
+}
+
+static int _convert_raid_snapshot(struct cmd_context *cmd, struct logical_volume *lv,
+ struct lvconvert_params *lp)
+{
+ return _lvconvert_snapshot(cmd, lv, lp);
+}
+
+static int _convert_raid_thin(struct cmd_context *cmd, struct logical_volume *lv,
+ struct lvconvert_params *lp)
+{
+ /* lvconvert --thin includes an implicit conversion of the thinpool arg to type thin-pool. */
+ if (!_lvconvert_pool(cmd, lv, lp)) {
+ log_error("Implicit conversion of --thinpool arg to type thin-pool failed.");
+ return 0;
+ }
+
+ return _lvconvert_thin(cmd, lv, lp);
+}
+
+static int _convert_raid_cache(struct cmd_context *cmd, struct logical_volume *lv,
+ struct lvconvert_params *lp)
+{
+ /* lvconvert --cache includes an implicit conversion of the cachepool arg to type cache-pool. */
+ if (!_lvconvert_pool(cmd, lv, lp)) {
+ log_error("Implicit conversion of --cachepool arg to type cache-pool failed.");
+ return 0;
+ }
+
+ return _lvconvert_cache(cmd, lv, lp);
+}
+
+static int _convert_raid_thin_pool(struct cmd_context *cmd, struct logical_volume *lv,
+ struct lvconvert_params *lp)
+{
+ return _lvconvert_pool(cmd, lv, lp);
+}
+
+static int _convert_raid_cache_pool(struct cmd_context *cmd, struct logical_volume *lv,
+ struct lvconvert_params *lp)
+{
+ return _lvconvert_pool(cmd, lv, lp);
+}
+
+static int _convert_raid_raid(struct cmd_context *cmd, struct logical_volume *lv,
+ struct lvconvert_params *lp)
+{
+ return _lvconvert_raid(lv, lp);
+}
+
+static int _convert_raid_striped(struct cmd_context *cmd, struct logical_volume *lv,
+ struct lvconvert_params *lp)
+{
+ return _lvconvert_raid(lv, lp);
+}
+
+static int _convert_raid_linear(struct cmd_context *cmd, struct logical_volume *lv,
+ struct lvconvert_params *lp)
+{
+ return _lvconvert_raid(lv, lp);
+}
+
+static int _convert_striped_snapshot(struct cmd_context *cmd, struct logical_volume *lv,
+ struct lvconvert_params *lp)
+{
+ return _lvconvert_snapshot(cmd, lv, lp);
+}
+
+static int _convert_striped_merge(struct cmd_context *cmd, struct logical_volume *lv,
+ struct lvconvert_params *lp)
+{
+ return _lvconvert_raid(lv, lp);
+}
+
+static int _convert_striped_thin(struct cmd_context *cmd, struct logical_volume *lv,
+ struct lvconvert_params *lp)
+{
+ /* lvconvert --thin includes an implicit conversion of the thinpool arg to type thin-pool. */
+ if (!_lvconvert_pool(cmd, lv, lp)) {
+ log_error("Implicit conversion of --thinpool arg to type thin-pool failed.");
+ return 0;
+ }
+
+ return _lvconvert_thin(cmd, lv, lp);
+}
+
+static int _convert_striped_cache(struct cmd_context *cmd, struct logical_volume *lv,
+ struct lvconvert_params *lp)
+{
+ /* lvconvert --cache includes an implicit conversion of the cachepool arg to type cache-pool. */
+ if (!_lvconvert_pool(cmd, lv, lp)) {
+ log_error("Implicit conversion of --cachepool arg to type cache-pool failed.");
+ return 0;
+ }
+
+ return _lvconvert_cache(cmd, lv, lp);
+}
+
+static int _convert_striped_thin_pool(struct cmd_context *cmd, struct logical_volume *lv,
+ struct lvconvert_params *lp)
+{
+ return _lvconvert_pool(cmd, lv, lp);
+}
+
+static int _convert_striped_cache_pool(struct cmd_context *cmd, struct logical_volume *lv,
+ struct lvconvert_params *lp)
+{
+ return _lvconvert_pool(cmd, lv, lp);
+}
+
+static int _convert_striped_mirror(struct cmd_context *cmd, struct logical_volume *lv,
+ struct lvconvert_params *lp)
+{
+ return _lvconvert_mirrors(cmd, lv, lp);
+}
+
+static int _convert_striped_raid(struct cmd_context *cmd, struct logical_volume *lv,
+ struct lvconvert_params *lp)
+{
+ return _lvconvert_raid(lv, lp);
+}
+
+/*
+ * Functions called to perform all valid operations on a given LV type.
+ *
+ * _convert_<lvtype>
+ */
+
+static int _convert_cow_snapshot(struct cmd_context *cmd, struct logical_volume *lv,
+ struct lvconvert_params *lp)
+{
+ if (lp->splitsnapshot)
+ return _convert_cow_snapshot_splitsnapshot(cmd, lv, lp);
+
+ if (lp->merge)
+ return _convert_cow_snapshot_merge(cmd, lv, lp);
+
+ log_error("Operation not permitted on COW snapshot LV %s", display_lvname(lv));
+ log_error("Operations permitted on a COW snapshot LV are:\n"
+ " --splitsnapshot\n"
+ " --merge\n");
+ return 0;
+}
+
+static int _convert_thin_volume(struct cmd_context *cmd, struct logical_volume *lv,
+ struct lvconvert_params *lp)
+{
+ if (lp->merge)
+ return _convert_thin_volume_merge(cmd, lv, lp);
+
+ log_error("Operation not permitted on thin LV %s", display_lvname(lv));
+ log_error("Operations permitted on a thin LV are:\n"
+ " --merge\n");
+ return 0;
+}
+
+static int _convert_thin_pool(struct cmd_context *cmd, struct logical_volume *lv,
+ struct lvconvert_params *lp)
+{
+ if (lp->splitcache || lp->split)
+ return _convert_thin_pool_splitcache(cmd, lv, lp);
+
+ if (lp->uncache)
+ return _convert_thin_pool_uncache(cmd, lv, lp);
+
+ if (lp->cache)
+ return _convert_thin_pool_cache(cmd, lv, lp);
+
+ if (lp->repair)
+ return _convert_thin_pool_repair(cmd, lv, lp);
+
+ /* FIXME: swapping the thin pool metadata LV needs a specific option like --swapmetadata */
+ if (arg_is_set(cmd, poolmetadata_ARG))
+ return _convert_thin_pool_swapmetadata(cmd, lv, lp);
+
+ /* FIXME: add --swapmetadata to list of permitted operations. */
+
+ log_error("Operation not permitted on thin pool LV %s", display_lvname(lv));
+ log_error("Operations permitted on a thin pool LV are:\n"
+ " --splitcache (operates on cache sub LV)\n"
+ " --uncache (operates on cache sub LV)\n"
+ " --cache (operates on data sub LV)\n"
+ " --repair\n");
+ return 0;
+}
+
+static int _convert_cache_volume(struct cmd_context *cmd, struct logical_volume *lv,
+ struct lvconvert_params *lp)
+{
+ const char *new_type = arg_str_value(cmd, type_ARG, NULL);
+
+ if (lp->splitcache || lp->split)
+ return _convert_cache_volume_splitcache(cmd, lv, lp);
+
+ if (lp->uncache)
+ return _convert_cache_volume_uncache(cmd, lv, lp);
+
+ /* FIXME: add lp->splitmirrors to reflect the arg. */
+ if (arg_is_set(cmd, splitmirrors_ARG))
+ return _convert_cache_volume_splitmirrors(cmd, lv, lp);
+
+ if (new_type && !strcmp(new_type, "thin-pool"))
+ return _convert_cache_volume_thin_pool(cmd, lv, lp);
+
+ log_error("Operation not permitted on cache LV %s", display_lvname(lv));
+ log_error("Operations permitted on a cache LV are:\n"
+ " --splitcache\n"
+ " --uncache\n"
+ " --splitmirrors (operates on mirror or raid sub LV)\n"
+ " --type thin-pool\n");
+ return 0;
+}
+
+static int _convert_cache_pool(struct cmd_context *cmd, struct logical_volume *lv,
+ struct lvconvert_params *lp)
+{
+ if (lp->splitcache || lp->split)
+ return _convert_cache_pool_splitcache(cmd, lv, lp);
+
+ /* FIXME: swapping the cache pool metadata LV needs a specific option like --swapmetadata */
+ if (arg_is_set(cmd, poolmetadata_ARG))
+ return _convert_cache_pool_swapmetadata(cmd, lv, lp);
+
+ /* FIXME: add --swapmetadata to list of permitted operations. */
+
+ log_error("Operation not permitted on cache pool LV %s", display_lvname(lv));
+ log_error("Operations permitted on a cache pool LV are:\n"
+ " --splitcache (operates on cache LV)\n");
+ return 0;
+}
+
+static int _convert_mirror(struct cmd_context *cmd, struct logical_volume *lv,
+ struct lvconvert_params *lp)
+{
+ const char *new_type = arg_str_value(cmd, type_ARG, NULL);
+ const struct segment_type *new_segtype = NULL;
+
+ if (new_type)
+ new_segtype = get_segtype_from_string(cmd, new_type);
+
+ if (lp->mirrors_supplied)
+ return _convert_mirror_number(cmd, lv, lp);
+
+ /* FIXME: add lp->splitmirrors to reflect the arg. */
+ if (arg_is_set(cmd, splitmirrors_ARG))
+ return _convert_mirror_splitmirrors(cmd, lv, lp);
+
+ if (lp->mirrorlog || lp->corelog)
+ return _convert_mirror_log(cmd, lv, lp);
+
+ if (lp->repair)
+ return _convert_mirror_repair(cmd, lv, lp);
+
+ if (new_type && new_segtype && segtype_is_raid(new_segtype))
+ return _convert_mirror_raid(cmd, lv, lp);
+
+ /*
+ * FIXME: this is here to preserve old behavior, but an
+ * explicit option should be added to enable this case,
+ * rather than making it the result of an ambiguous
+ * "lvconvert vg/lv" command.
+ *
+ * Old behavior was described as:
+ * "Collapsing a stack of mirrors.
+ * If called with no argument, try collapsing the resync layers"
+ */
+ log_debug("Checking if LV %s is converting.", display_lvname(lv));
+ if (lv_is_converting(lv)) {
+ lp->need_polling = 1;
+ return 1;
+ }
+
+ log_error("Operation not permitted on mirror LV %s", display_lvname(lv));
+ log_error("Operations permitted on a mirror LV are:\n"
+ " --mirrors\n"
+ " --splitmirrors\n"
+ " --mirrorlog\n"
+ " --repair\n"
+ " --type raid*\n");
+ return 0;
+}
+
+static int _convert_raid(struct cmd_context *cmd, struct logical_volume *lv,
+ struct lvconvert_params *lp)
+{
+ const char *new_type = arg_str_value(cmd, type_ARG, NULL);
+ const struct segment_type *new_segtype = NULL;
+
+ if (new_type)
+ new_segtype = get_segtype_from_string(cmd, new_type);
+
+ if (lp->mirrors_supplied)
+ return _convert_raid_number(cmd, lv, lp);
+
+ /* FIXME: add lp->splitmirrors to reflect the arg. */
+ if (arg_is_set(cmd, splitmirrors_ARG))
+ return _convert_raid_splitmirrors(cmd, lv, lp);
+
+ if (lp->merge_mirror)
+ return _convert_raid_merge(cmd, lv, lp);
+
+ if (lp->repair)
+ return _convert_raid_repair(cmd, lv, lp);
+
+ if (lp->replace)
+ return _convert_raid_replace(cmd, lv, lp);
+
+ if (lp->snapshot)
+ return _convert_raid_snapshot(cmd, lv, lp);
+
+ if (lp->thin)
+ return _convert_raid_thin(cmd, lv, lp);
+
+ if (lp->cache)
+ return _convert_raid_cache(cmd, lv, lp);
+
+ /* The --thinpool alias is ambiguous and not preferred. */
+
+ if ((new_type && !strcmp(new_type, "thin-pool")) || arg_is_set(cmd, thinpool_ARG))
+ return _convert_raid_thin_pool(cmd, lv, lp);
+
+ if (new_type && !strcmp(new_type, "cache-pool"))
+ return _convert_raid_cache_pool(cmd, lv, lp);
+
+ if (new_type && new_segtype && segtype_is_raid(new_segtype))
+ return _convert_raid_raid(cmd, lv, lp);
+
+ if (new_type && !strcmp(new_type, "striped"))
+ return _convert_raid_striped(cmd, lv, lp);
+
+ if (new_type && !strcmp(new_type, "linear"))
+ return _convert_raid_linear(cmd, lv, lp);
+
+ /* The --thinpool alias for --type thin-pool is not preferred, so not shown. */
+
+ log_error("Operation not permitted on raid LV %s", display_lvname(lv));
+ log_error("Operations permitted on a raid LV are:\n"
+ " --mirrors\n"
+ " --splitmirrors\n"
+ " --merge\n"
+ " --repair\n"
+ " --replace\n"
+ " --snapshot\n"
+ " --thin\n"
+ " --cache\n"
+ " --type thin-pool\n"
+ " --type cache-pool\n"
+ " --type raid*\n"
+ " --type striped\n"
+ " --type linear\n");
+ return 0;
+}
+
+static int _convert_striped(struct cmd_context *cmd, struct logical_volume *lv,
+ struct lvconvert_params *lp)
+{
+ const char *new_type = arg_str_value(cmd, type_ARG, NULL);
+ const struct segment_type *new_segtype = NULL;
+ const char *mirrors_type = find_config_tree_str(cmd, global_mirror_segtype_default_CFG, NULL);
+
+ if (new_type)
+ new_segtype = get_segtype_from_string(cmd, new_type);
+
+ if (lp->snapshot)
+ return _convert_striped_snapshot(cmd, lv, lp);
+
+ /* FIXME: add a new option to make this case more clear, e.g. --merge-splitmirror */
+ if (lp->merge)
+ return _convert_striped_merge(cmd, lv, lp);
+
+ if (lp->thin)
+ return _convert_striped_thin(cmd, lv, lp);
+
+ if (lp->cache)
+ return _convert_striped_cache(cmd, lv, lp);
+
+ /* The --thinpool alias is ambiguous and not preferred. */
+
+ if ((new_type && !strcmp(new_type, "thin-pool")) || arg_is_set(cmd, thinpool_ARG))
+ return _convert_striped_thin_pool(cmd, lv, lp);
+
+ if (new_type && !strcmp(new_type, "cache-pool"))
+ return _convert_striped_cache_pool(cmd, lv, lp);
+
+ if (new_type && !strcmp(new_type, "mirror"))
+ return _convert_striped_mirror(cmd, lv, lp);
+
+ if (new_type && new_segtype && segtype_is_raid(new_segtype))
+ return _convert_striped_raid(cmd, lv, lp);
+
+ /* --mirrors can mean --type mirror or --type raid1 depending on config setting. */
+
+ if (arg_is_set(cmd, mirrors_ARG) && mirrors_type && !strcmp(mirrors_type, "mirror"))
+ return _convert_striped_mirror(cmd, lv, lp);
+
+ if (arg_is_set(cmd, mirrors_ARG) && mirrors_type && !strcmp(mirrors_type, "raid1"))
+ return _convert_striped_raid(cmd, lv, lp);
+
+ /* The --thinpool alias for --type thin-pool is not preferred, so not shown. */
+
+ log_error("Operation not permitted on striped or linear LV %s", display_lvname(lv));
+ log_error("Operations permitted on a striped or linear LV are:\n"
+ " --snapshot\n"
+ " --merge\n"
+ " --thin\n"
+ " --cache\n"
+ " --type thin-pool\n"
+ " --type cache-pool\n"
+ " --type mirror | --mirrors\n"
+ " --type raid* | --mirrors\n");
+ return 0;
+}
+
+/*
+ * lvconvert performs a specific <operation> on a specific <lv_type>.
+ *
+ * The <operation> is specified by command args found in lp fields.
+ * The <lv_type> is found using lv_is_foo(lv) functions.
+ *
+ * lvconvert --operation LV
+ *
+ * lp->operation = arg_value(operation);
+ * lv_type = lv_is_foo(LV);
+ *
+ * for each lvtype,
+ * _convert_lvtype();
+ * for each lp->operation
+ * _convert_lvtype_operation();
+ */
+
+static int _lvconvert(struct cmd_context *cmd, struct logical_volume *lv,
+ struct lvconvert_params *lp)
+{
+ struct lv_segment *lv_seg = first_seg(lv);
+ int ret = 0;
+
+ log_debug("lvconvert lv %s is type %s status %llx to type %s",
+ display_lvname(lv),
+ lv_seg->segtype->name,
+ (unsigned long long)lv->status,
+ arg_str_value(cmd, type_ARG, ""));
+
+ /*
+ * Check some conditions that can never be processed.
+ */
+
+ if (lv_is_locked(lv)) {
+ log_error("Cannot convert locked LV %s.", display_lvname(lv));
+ ret = 0;
+ goto out;
+ }
+
+ if (lv_is_pvmove(lv)) {
+ log_error("Cannot convert pvmove LV %s.", display_lvname(lv));
+ ret = 0;
+ goto out;
+ }
+
+ if (!lv_is_visible(lv)) {
+ /*
+ * FIXME: there are some exceptions to the rule of only
+ * operating on visible LVs. These should be fixed by running
+ * the command on the visible LV with an option indicating
+ * which sub LV is intended rather than naming the !visible LV.
+ */
+ if (!lv_is_cache_pool_metadata(lv) &&
+ !lv_is_cache_pool_data(lv) &&
+ !lv_is_thin_pool_metadata(lv) &&
+ !lv_is_thin_pool_data(lv) &&
+ !lv_is_raid_image(lv)) {
+ log_error("Cannot convert internal LV %s.", display_lvname(lv));
+ ret = 0;
+ goto out;
+ }
+ }
+
+ /*
+ * Each LV type that can be converted.
+ * (The existing type of the LV, not a requested type.)
+ */
+
+ if (lv_is_cow(lv)) {
+ ret = _convert_cow_snapshot(cmd, lv, lp);
+ goto out;
+ }
+
+ if (lv_is_thin_volume(lv)) {
+ ret = _convert_thin_volume(cmd, lv, lp);
+ goto out;
+ }
+
+ if (lv_is_thin_pool(lv)) {
+ ret = _convert_thin_pool(cmd, lv, lp);
+ goto out;
+ }
+
+ if (lv_is_cache(lv)) {
+ ret = _convert_cache_volume(cmd, lv, lp);
+ goto out;
+ }
+
+ if (lv_is_cache_pool(lv)) {
+ ret = _convert_cache_pool(cmd, lv, lp);
+ goto out;
+ }
+
+ if (lv_is_mirror(lv)) {
+ ret = _convert_mirror(cmd, lv, lp);
+ goto out;
+ }
+
+ if (lv_is_raid(lv)) {
+ ret = _convert_raid(cmd, lv, lp);
+ goto out;
+ }
+
+ /*
+ * FIXME: add lv_is_striped() and lv_is_linear()?
+ * This does not include raid0.
+ * If operations differ between striped and linear, split this case.
+ */
+ if (segtype_is_striped(lv_seg->segtype) || segtype_is_linear(lv_seg->segtype)) {
+ ret = _convert_striped(cmd, lv, lp);
+ goto out;
+ }
+
+ /*
+ * Check for LV types that cannot be converted and print an error.
+ */
+
+ /*
+ * The intention is to explicitly check all cases above and never
+ * reach here, but this covers anything that was missed.
+ */
+ log_error("Cannot convert LV %s.", display_lvname(lv));
+ ret = 0;
+
+out:
+ return ret ? ECMD_PROCESSED : ECMD_FAILED;
+
+}
static struct convert_poll_id_list* _convert_poll_id_list_create(struct cmd_context *cmd,
const struct logical_volume *lv)
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=eac0706761e62853…
Commit: eac0706761e628532ffcd27f3e4d7fa559a5f818
Parent: 686acce23fed6bd72af63201e4cc56bc5958379e
Author: Peter Rajnoha <prajnoha(a)redhat.com>
AuthorDate: Wed Jun 29 15:58:14 2016 +0200
Committer: Peter Rajnoha <prajnoha(a)redhat.com>
CommitterDate: Wed Jun 29 15:58:18 2016 +0200
libdm: do not issue 'Failed to create directory' message for failure in dm_create_dir
There are detailed messages inside _create_dir_recursive that
dm_create_dir calls (except EROFS which where the message is not
generated, like anywhere else in the code).
---
libdm/libdm-file.c | 6 ++----
1 files changed, 2 insertions(+), 4 deletions(-)
diff --git a/libdm/libdm-file.c b/libdm/libdm-file.c
index 9867824..2c313b3 100644
--- a/libdm/libdm-file.c
+++ b/libdm/libdm-file.c
@@ -97,10 +97,8 @@ int dm_create_dir(const char *dir)
if (stat(dir, &info) == 0 && S_ISDIR(info.st_mode))
return 1;
- if (!_create_dir_recursive(dir)) {
- log_error("Failed to create directory %s.", dir);
- return 0;
- }
+ if (!_create_dir_recursive(dir))
+ return_0;
return 1;
}
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=686acce23fed6bd7…
Commit: 686acce23fed6bd72af63201e4cc56bc5958379e
Parent: 6f216692b47b38f480e50d213de5c513a309d9e0
Author: Alasdair G Kergon <agk(a)redhat.com>
AuthorDate: Tue Jun 28 23:44:15 2016 +0100
Committer: Alasdair G Kergon <agk(a)redhat.com>
CommitterDate: Tue Jun 28 23:44:15 2016 +0100
lvconvert: Conversions between striped and raid0.
---
WHATS_NEW | 1 +
lib/metadata/lv.c | 30 ++-
lib/metadata/lv_manip.c | 3 +-
lib/metadata/metadata.h | 4 +
lib/metadata/raid_manip.c | 595 +++++++++++++++++++++++++++++++++++++++++----
lib/metadata/segtype.c | 13 +
lib/metadata/segtype.h | 2 +
lib/misc/util.h | 2 +
8 files changed, 593 insertions(+), 57 deletions(-)
diff --git a/WHATS_NEW b/WHATS_NEW
index 3184412..619c64d 100644
--- a/WHATS_NEW
+++ b/WHATS_NEW
@@ -1,5 +1,6 @@
Version 2.02.159 -
=================================
+ Support conversions between striped and raid0 segment types.
Add infrastructure for raid takeover lvconvert options.
Version 2.02.158 - 25th June 2016
diff --git a/lib/metadata/lv.c b/lib/metadata/lv.c
index cdf658e..e7a56cf 100644
--- a/lib/metadata/lv.c
+++ b/lib/metadata/lv.c
@@ -577,14 +577,14 @@ char *lv_name_dup(struct dm_pool *mem, const struct logical_volume *lv)
char *lv_fullname_dup(struct dm_pool *mem, const struct logical_volume *lv)
{
- char lvfullname[NAME_LEN * 2 + 2];
+ char lvfullname[NAME_LEN * 2 + 2];
- if (dm_snprintf(lvfullname, sizeof(lvfullname), "%s/%s", lv->vg->name, lv->name) < 0) {
- log_error("lvfullname snprintf failed");
- return NULL;
- }
+ if (dm_snprintf(lvfullname, sizeof(lvfullname), "%s/%s", lv->vg->name, lv->name) < 0) {
+ log_error("lvfullname snprintf failed");
+ return NULL;
+ }
- return dm_pool_strdup(mem, lvfullname);
+ return dm_pool_strdup(mem, lvfullname);
}
struct logical_volume *lv_parent(const struct logical_volume *lv)
@@ -930,7 +930,7 @@ char *lv_dmpath_dup(struct dm_pool *mem, const struct logical_volume *lv)
if (!*lv->vg->name)
return dm_pool_strdup(mem, "");
- if (!(name = dm_build_dm_name(mem, lv->vg->name, lv->name, NULL))) {
+ if (!(name = dm_build_dm_name(mem, lv->vg->name, lv->name, NULL))) {
log_error("dm_build_dm_name failed");
return NULL;
}
@@ -1581,3 +1581,19 @@ struct profile *lv_config_profile(const struct logical_volume *lv)
{
return lv->profile ? : lv->vg->profile;
}
+
+int lv_has_constant_stripes(struct logical_volume *lv)
+{
+ uint32_t previous_area_count = 0;
+ struct lv_segment *seg;
+
+ dm_list_iterate_items(seg, &lv->segments) {
+ if (!seg_is_striped(seg))
+ return 0;
+ if (previous_area_count && previous_area_count != seg->area_count)
+ return 0;
+ previous_area_count = seg->area_count;
+ }
+
+ return 1;
+}
diff --git a/lib/metadata/lv_manip.c b/lib/metadata/lv_manip.c
index 40c1c1a..db71939 100644
--- a/lib/metadata/lv_manip.c
+++ b/lib/metadata/lv_manip.c
@@ -3301,7 +3301,8 @@ static struct alloc_handle *_alloc_init(struct cmd_context *cmd,
void alloc_destroy(struct alloc_handle *ah)
{
- dm_pool_destroy(ah->mem);
+ if (ah)
+ dm_pool_destroy(ah->mem);
}
/*
diff --git a/lib/metadata/metadata.h b/lib/metadata/metadata.h
index 31c9346..e6dc14a 100644
--- a/lib/metadata/metadata.h
+++ b/lib/metadata/metadata.h
@@ -415,6 +415,10 @@ struct logical_volume *alloc_lv(struct dm_pool *mem);
*/
int check_lv_segments(struct logical_volume *lv, int complete_vg);
+/*
+ * Does every LV segment have the same number of stripes?
+ */
+int lv_has_constant_stripes(struct logical_volume *lv);
/*
* Checks that a replicator segment is correct.
diff --git a/lib/metadata/raid_manip.c b/lib/metadata/raid_manip.c
index 2cef777..71334b5 100644
--- a/lib/metadata/raid_manip.c
+++ b/lib/metadata/raid_manip.c
@@ -116,16 +116,16 @@ static int _raid_in_sync(struct logical_volume *lv)
/*
* _raid_remove_top_layer
* @lv
- * @removal_list
+ * @removal_lvs
*
* Remove top layer of RAID LV in order to convert to linear.
* This function makes no on-disk changes. The residual LVs
- * returned in 'removal_list' must be freed by the caller.
+ * returned in 'removal_lvs' must be freed by the caller.
*
* Returns: 1 on succes, 0 on failure
*/
static int _raid_remove_top_layer(struct logical_volume *lv,
- struct dm_list *removal_list)
+ struct dm_list *removal_lvs)
{
struct lv_list *lvl_array, *lvl;
struct lv_segment *seg = first_seg(lv);
@@ -147,19 +147,19 @@ static int _raid_remove_top_layer(struct logical_volume *lv,
if (!(lvl_array = dm_pool_alloc(lv->vg->vgmem, 2 * sizeof(*lvl))))
return_0;
- /* Add last metadata area to removal_list */
+ /* Add last metadata area to removal_lvs */
lvl_array[0].lv = seg_metalv(seg, 0);
lv_set_visible(seg_metalv(seg, 0));
if (!remove_seg_from_segs_using_this_lv(seg_metalv(seg, 0), seg))
return_0;
seg_metatype(seg, 0) = AREA_UNASSIGNED;
- dm_list_add(removal_list, &(lvl_array[0].list));
+ dm_list_add(removal_lvs, &(lvl_array[0].list));
- /* Remove RAID layer and add residual LV to removal_list*/
+ /* Remove RAID layer and add residual LV to removal_lvs*/
seg_lv(seg, 0)->status &= ~RAID_IMAGE;
lv_set_visible(seg_lv(seg, 0));
lvl_array[1].lv = seg_lv(seg, 0);
- dm_list_add(removal_list, &(lvl_array[1].list));
+ dm_list_add(removal_lvs, &(lvl_array[1].list));
if (!remove_layer_from_lv(lv, seg_lv(seg, 0)))
return_0;
@@ -377,13 +377,6 @@ static struct logical_volume *_alloc_image_component(struct logical_volume *lv,
struct logical_volume *tmp_lv;
const struct segment_type *segtype;
- if (!ah) {
- log_error(INTERNAL_ERROR
- "Stand-alone %s area allocation not implemented",
- (type == RAID_META) ? "metadata" : "data");
- return 0;
- }
-
switch (type) {
case RAID_META:
type_suffix = "rmeta";
@@ -409,12 +402,14 @@ static struct logical_volume *_alloc_image_component(struct logical_volume *lv,
return 0;
}
- if (!(segtype = get_segtype_from_string(lv->vg->cmd, SEG_TYPE_NAME_STRIPED)))
- return_0;
+ if (ah) {
+ if (!(segtype = get_segtype_from_string(lv->vg->cmd, SEG_TYPE_NAME_STRIPED)))
+ return_0;
- if (!lv_add_segment(ah, first_area, 1, tmp_lv, segtype, 0, status, 0)) {
- log_error("Failed to add segment to LV, %s", img_name);
- return 0;
+ if (!lv_add_segment(ah, first_area, 1, tmp_lv, segtype, 0, status, 0)) {
+ log_error("Failed to add segment to LV, %s", img_name);
+ return 0;
+ }
}
lv_set_visible(tmp_lv);
@@ -432,7 +427,7 @@ static int _alloc_image_components(struct logical_volume *lv,
uint32_t extents;
struct lv_segment *seg = first_seg(lv);
const struct segment_type *segtype;
- struct alloc_handle *ah;
+ struct alloc_handle *ah = NULL;
struct dm_list *parallel_areas;
struct lv_list *lvl_array;
@@ -473,7 +468,9 @@ static int _alloc_image_components(struct logical_volume *lv,
(lv->le_count / (seg->area_count - segtype->parity_devs)) :
lv->le_count;
- if (!(ah = allocate_extents(lv->vg, NULL, segtype, 0, count, count,
+ /* Do we need to allocate any extents? */
+ if (pvs && !dm_list_empty(pvs) &&
+ !(ah = allocate_extents(lv->vg, NULL, segtype, 0, count, count,
region_size, extents, pvs,
lv->alloc, 0, parallel_areas)))
return_0;
@@ -485,19 +482,25 @@ static int _alloc_image_components(struct logical_volume *lv,
* allocated areas. Thus, the metadata areas are pulled
* from 's + count'.
*/
- if (!(lvl_array[s + count].lv =
- _alloc_image_component(lv, NULL, ah, s + count, RAID_META))) {
- alloc_destroy(ah);
- return_0;
+
+ /* new_meta_lvs are optional for raid0 */
+ if (new_meta_lvs) {
+ if (!(lvl_array[s + count].lv =
+ _alloc_image_component(lv, NULL, ah, s + count, RAID_META))) {
+ alloc_destroy(ah);
+ return_0;
+ }
+ dm_list_add(new_meta_lvs, &(lvl_array[s + count].list));
}
- dm_list_add(new_meta_lvs, &(lvl_array[s + count].list));
- if (!(lvl_array[s].lv =
- _alloc_image_component(lv, NULL, ah, s, RAID_IMAGE))) {
- alloc_destroy(ah);
- return_0;
+ if (new_data_lvs) {
+ if (!(lvl_array[s].lv =
+ _alloc_image_component(lv, NULL, ah, s, RAID_IMAGE))) {
+ alloc_destroy(ah);
+ return_0;
+ }
+ dm_list_add(new_data_lvs, &(lvl_array[s].list));
}
- dm_list_add(new_data_lvs, &(lvl_array[s].list));
}
alloc_destroy(ah);
@@ -955,16 +958,16 @@ static int _raid_extract_images(struct logical_volume *lv, uint32_t new_count,
static int _raid_remove_images(struct logical_volume *lv,
uint32_t new_count, struct dm_list *pvs)
{
- struct dm_list removal_list;
+ struct dm_list removal_lvs;
struct lv_list *lvl;
if (!archive(lv->vg))
return_0;
- dm_list_init(&removal_list);
+ dm_list_init(&removal_lvs);
if (!_raid_extract_images(lv, new_count, pvs, 1,
- &removal_list, &removal_list)) {
+ &removal_lvs, &removal_lvs)) {
log_error("Failed to extract images from %s/%s",
lv->vg->name, lv->name);
return 0;
@@ -972,7 +975,7 @@ static int _raid_remove_images(struct logical_volume *lv,
/* Convert to linear? */
if (new_count == 1) {
- if (!_raid_remove_top_layer(lv, &removal_list)) {
+ if (!_raid_remove_top_layer(lv, &removal_lvs)) {
log_error("Failed to remove RAID layer"
" after linear conversion");
return 0;
@@ -1005,7 +1008,7 @@ static int _raid_remove_images(struct logical_volume *lv,
* and won't conflict with the remaining (possibly shifted)
* sub-LVs.
*/
- dm_list_iterate_items(lvl, &removal_list) {
+ dm_list_iterate_items(lvl, &removal_lvs) {
if (!activate_lv_excl_local(lv->vg->cmd, lvl->lv)) {
log_error("Failed to resume extracted LVs");
return 0;
@@ -1027,8 +1030,8 @@ static int _raid_remove_images(struct logical_volume *lv,
/*
* Eliminate the extracted LVs
*/
- if (!dm_list_empty(&removal_list)) {
- dm_list_iterate_items(lvl, &removal_list) {
+ if (!dm_list_empty(&removal_lvs)) {
+ dm_list_iterate_items(lvl, &removal_lvs) {
if (!deactivate_lv(lv->vg->cmd, lvl->lv))
return_0;
if (!lv_remove(lvl->lv))
@@ -1089,14 +1092,14 @@ int lv_raid_split(struct logical_volume *lv, const char *split_name,
uint32_t new_count, struct dm_list *splittable_pvs)
{
struct lv_list *lvl;
- struct dm_list removal_list, data_list;
+ struct dm_list removal_lvs, data_list;
struct cmd_context *cmd = lv->vg->cmd;
uint32_t old_count = lv_raid_image_count(lv);
struct logical_volume *tracking;
struct dm_list tracking_pvs;
int historical;
- dm_list_init(&removal_list);
+ dm_list_init(&removal_lvs);
dm_list_init(&data_list);
if (is_lockd_type(lv->vg->lock_type)) {
@@ -1151,14 +1154,14 @@ int lv_raid_split(struct logical_volume *lv, const char *split_name,
}
if (!_raid_extract_images(lv, new_count, splittable_pvs, 1,
- &removal_list, &data_list)) {
+ &removal_lvs, &data_list)) {
log_error("Failed to extract images from %s/%s",
lv->vg->name, lv->name);
return 0;
}
/* Convert to linear? */
- if ((new_count == 1) && !_raid_remove_top_layer(lv, &removal_list)) {
+ if ((new_count == 1) && !_raid_remove_top_layer(lv, &removal_lvs)) {
log_error("Failed to remove RAID layer after linear conversion");
return 0;
}
@@ -1197,7 +1200,7 @@ int lv_raid_split(struct logical_volume *lv, const char *split_name,
if (!activate_lv_excl_local(cmd, lvl->lv))
return_0;
- dm_list_iterate_items(lvl, &removal_list)
+ dm_list_iterate_items(lvl, &removal_lvs)
if (!activate_lv_excl_local(cmd, lvl->lv))
return_0;
@@ -1217,7 +1220,7 @@ int lv_raid_split(struct logical_volume *lv, const char *split_name,
/*
* Eliminate the residual LVs
*/
- dm_list_iterate_items(lvl, &removal_list) {
+ dm_list_iterate_items(lvl, &removal_lvs) {
if (!deactivate_lv(cmd, lvl->lv))
return_0;
@@ -1365,6 +1368,9 @@ int lv_raid_merge(struct logical_volume *image_lv)
return 1;
}
+/*
+ * General conversion functions
+ */
static int _convert_mirror_to_raid1(struct logical_volume *lv,
const struct segment_type *new_segtype)
{
@@ -1460,6 +1466,470 @@ static int _convert_mirror_to_raid1(struct logical_volume *lv,
return 1;
}
+/* Add new @lvs to @lv at @area_offset */
+static int _add_image_component_list(struct lv_segment *seg, int delete_from_list,
+ uint64_t lv_flags, struct dm_list *lvs, uint32_t area_offset)
+{
+ uint32_t s = area_offset;
+ struct lv_list *lvl, *tmp;
+
+ dm_list_iterate_items_safe(lvl, tmp, lvs) {
+ if (delete_from_list)
+ dm_list_del(&lvl->list);
+
+ if (lv_flags & VISIBLE_LV)
+ lv_set_visible(lvl->lv);
+ else
+ lv_set_hidden(lvl->lv);
+
+ if (lv_flags & LV_REBUILD)
+ lvl->lv->status |= LV_REBUILD;
+ else
+ lvl->lv->status &= ~LV_REBUILD;
+
+ if (!set_lv_segment_area_lv(seg, s++, lvl->lv, 0 /* le */, lvl->lv->status)) {
+ log_error("Failed to add sublv %s", lvl->lv->name);
+ return 0;
+ }
+ }
+
+ return 1;
+}
+
+/*
+ * All areas from LV segments are moved to new
+ * segments allocated with area_count=1 for data_lvs.
+ */
+static int _striped_to_raid0_move_segs_to_raid0_lvs(struct logical_volume *lv,
+ struct dm_list *data_lvs)
+{
+ uint32_t s = 0, le;
+ struct logical_volume *dlv;
+ struct lv_segment *seg_from, *seg_new;
+ struct lv_list *lvl;
+ struct segment_type *segtype;
+ uint64_t status;
+
+ if (!(segtype = get_segtype_from_string(lv->vg->cmd, SEG_TYPE_NAME_STRIPED)))
+ return_0;
+
+ /* Move segment areas across to the N data LVs of the new raid0 LV */
+ dm_list_iterate_items(lvl, data_lvs) {
+ dlv = lvl->lv;
+ le = 0;
+ dm_list_iterate_items(seg_from, &lv->segments) {
+ status = RAID | SEG_RAID | (seg_from->status & (LVM_READ | LVM_WRITE));
+
+ /* Allocate a data LV segment with one area for each segment in the striped LV */
+ if (!(seg_new = alloc_lv_segment(segtype, dlv,
+ le, seg_from->area_len,
+ status,
+ 0 /* stripe_size */, NULL, 1 /* area_count */,
+ seg_from->area_len,
+ 0 /* chunk_size */, 0 /* region_size */, 0, NULL)))
+ return_0;
+
+ seg_type(seg_new, 0) = AREA_UNASSIGNED;
+ dm_list_add(&dlv->segments, &seg_new->list);
+ le += seg_from->area_len;
+
+ /* Move the respective area across to our new segment */
+ if (!move_lv_segment_area(seg_new, 0, seg_from, s))
+ return_0;
+ }
+
+ /* Adjust le count and LV size */
+ dlv->le_count = le;
+ dlv->size = (uint64_t) le * lv->vg->extent_size;
+ s++;
+ }
+
+ /* Remove the empty segments from the striped LV */
+ dm_list_init(&lv->segments);
+
+ return 1;
+}
+
+/*
+ * Find the smallest area across all the subLV segments at area_le.
+ */
+static uint32_t _min_sublv_area_at_le(struct lv_segment *seg, uint32_t area_le)
+{
+ uint32_t s, area_len = ~0U;
+ struct lv_segment *seg1;
+
+ /* Find smallest segment of each of the data image LVs at offset area_le */
+ for (s = 0; s < seg->area_count; s++) {
+ seg1 = find_seg_by_le(seg_lv(seg, s), area_le);
+ area_len = min(area_len, seg1->len);
+ }
+
+ return area_len;
+}
+
+/*
+ * Split segments in segment LVs in all areas of seg at offset area_le
+ */
+static int _split_area_lvs_segments(struct lv_segment *seg, uint32_t area_le)
+{
+ uint32_t s;
+
+ /* Make sure that there's a segment starting at area_le in all data LVs */
+ for (s = 0; s < seg->area_count; s++)
+ if (area_le < seg_lv(seg, s)->le_count &&
+ !lv_split_segment(seg_lv(seg, s), area_le))
+ return_0;
+
+ return 1;
+}
+
+static int _alloc_and_add_new_striped_segment(struct logical_volume *lv,
+ uint32_t le, uint32_t area_len,
+ struct dm_list *new_segments)
+{
+ struct lv_segment *seg, *new_seg;
+ struct segment_type *striped_segtype;
+
+ seg = first_seg(lv);
+
+ if (!(striped_segtype = get_segtype_from_string(lv->vg->cmd, SEG_TYPE_NAME_STRIPED)))
+ return_0;
+
+ /* Allocate a segment with seg->area_count areas */
+ if (!(new_seg = alloc_lv_segment(striped_segtype, lv, le, area_len * seg->area_count,
+ seg->status & ~RAID,
+ seg->stripe_size, NULL, seg->area_count,
+ area_len, seg->chunk_size, 0, 0, NULL)))
+ return_0;
+
+ dm_list_add(new_segments, &new_seg->list);
+
+ return 1;
+}
+
+static int _extract_image_component_error_seg(struct lv_segment *seg,
+ uint64_t type, uint32_t idx,
+ struct logical_volume **extracted_lv,
+ int set_error_seg)
+{
+ struct logical_volume *lv;
+
+ switch (type) {
+ case RAID_META:
+ lv = seg_metalv(seg, idx);
+ seg_metalv(seg, idx) = NULL;
+ seg_metatype(seg, idx) = AREA_UNASSIGNED;
+ break;
+ case RAID_IMAGE:
+ lv = seg_lv(seg, idx);
+ seg_lv(seg, idx) = NULL;
+ seg_type(seg, idx) = AREA_UNASSIGNED;
+ break;
+ default:
+ log_error(INTERNAL_ERROR "Bad type provided to %s.", __func__);
+ return 0;
+ }
+
+ log_very_verbose("Extracting image component %s from %s", lv->name, lvseg_name(seg));
+ lv->status &= ~(type | RAID);
+ lv_set_visible(lv);
+
+ /* remove reference from seg to lv */
+ if (!remove_seg_from_segs_using_this_lv(lv, seg))
+ return_0;
+
+ if (!(lv->name = _generate_raid_name(lv, "extracted_", -1)))
+ return_0;
+
+ if (set_error_seg && !replace_lv_with_error_segment(lv))
+ return_0;
+
+ *extracted_lv = lv;
+
+ return 1;
+}
+
+/*
+ * Extract all sub LVs of type from seg starting at idx excluding end and
+ * put them on removal_lvs setting mappings to "error" if error_seg.
+ */
+static int _extract_image_component_sublist(struct lv_segment *seg,
+ uint64_t type, uint32_t idx, uint32_t end,
+ struct dm_list *removal_lvs,
+ int error_seg)
+{
+ uint32_t s;
+ struct lv_list *lvl;
+
+ if (!(lvl = dm_pool_alloc(seg_lv(seg, idx)->vg->vgmem, sizeof(*lvl) * (end - idx))))
+ return_0;
+
+ for (s = idx; s < end; s++) {
+ if (!_extract_image_component_error_seg(seg, type, s, &lvl->lv, error_seg))
+ return 0;
+
+ dm_list_add(removal_lvs, &lvl->list);
+ lvl++;
+ }
+
+ if (!idx && end == seg->area_count) {
+ if (type == RAID_IMAGE)
+ seg->areas = NULL;
+ else
+ seg->meta_areas = NULL;
+ }
+
+ return 1;
+}
+
+/* Extract all sub LVs of type from seg starting with idx and put them on removal_Lvs */
+static int _extract_image_component_list(struct lv_segment *seg,
+ uint64_t type, uint32_t idx,
+ struct dm_list *removal_lvs)
+{
+ return _extract_image_component_sublist(seg, type, idx, seg->area_count, removal_lvs, 1);
+}
+
+/*
+ * All areas from lv image component LV's segments are
+ * being split at "striped" compatible boundaries and
+ * moved to allocated new_segments.
+ *
+ * The data component LVs are mapped to an
+ * error target and linked to removal_lvs for disposal
+ * by the caller.
+ */
+static int _raid0_to_striped_retrieve_segments_and_lvs(struct logical_volume *lv,
+ struct dm_list *removal_lvs)
+{
+ uint32_t s, area_le, area_len, le;
+ struct lv_segment *data_seg, *seg, *seg_to;
+ struct dm_list new_segments;
+
+ seg = first_seg(lv);
+
+ dm_list_init(&new_segments);
+
+ /*
+ * Walk all segments of all data LVs splitting them up at proper boundaries
+ * and create the number of new striped segments we need to move them across
+ */
+ area_le = le = 0;
+ while (le < lv->le_count) {
+ area_len = _min_sublv_area_at_le(seg, area_le);
+ area_le += area_len;
+
+ if (!_split_area_lvs_segments(seg, area_le) ||
+ !_alloc_and_add_new_striped_segment(lv, le, area_len, &new_segments))
+ return_0;
+
+ le = area_le * seg->area_count;
+ }
+
+ /* Now move the prepared split areas across to the new segments */
+ area_le = 0;
+ dm_list_iterate_items(seg_to, &new_segments) {
+ for (s = 0; s < seg->area_count; s++) {
+ data_seg = find_seg_by_le(seg_lv(seg, s), area_le);
+
+ /* Move the respective area across to our new segments area */
+ if (!move_lv_segment_area(seg_to, s, data_seg, 0))
+ return_0;
+ }
+
+ /* Presumes all data LVs have equal size */
+ area_le += data_seg->len;
+ }
+
+ /* Extract any metadata LVs and the empty data LVs for disposal by the caller */
+ if (!_extract_image_component_list(seg, RAID_IMAGE, 0, removal_lvs))
+ return_0;
+
+ /*
+ * Remove the one segment holding the image component areas
+ * from the top-level LV, then add the new segments to it
+ */
+ dm_list_del(&seg->list);
+ dm_list_splice(&lv->segments, &new_segments);
+
+ return 1;
+}
+
+/*
+ * Deactivate and remove the LVs on removal_lvs list from vg.
+ */
+static int _deactivate_and_remove_lvs(struct volume_group *vg, struct dm_list *removal_lvs)
+{
+ struct lv_list *lvl;
+
+ dm_list_iterate_items(lvl, removal_lvs)
+ if (!deactivate_lv(vg->cmd, lvl->lv) ||
+ !lv_remove(lvl->lv))
+ return_0;
+
+ return 1;
+}
+
+/* FIXME Move this out */
+/* Write, commit and optionally backup metadata of vg */
+static int _vg_write_commit_backup(struct volume_group *vg)
+{
+ if (!vg_write(vg) || !vg_commit(vg)) {
+ log_error("Failed to commit VG %s metadata.", vg->name);
+ return 0;
+ }
+
+ if (!backup(vg))
+ log_warn("WARNING: Backup of VG %s metadata failed. Continuing.", vg->name);
+
+ return 1;
+}
+
+/*
+ * Eliminate the extracted LVs on @removal_lvs from @vg incl. vg write, commit and backup
+ */
+static int _eliminate_extracted_lvs_optional_write_vg(struct volume_group *vg,
+ struct dm_list *removal_lvs,
+ int vg_write_requested)
+{
+ if (!removal_lvs || dm_list_empty(removal_lvs))
+ return 1;
+
+ if (!_deactivate_and_remove_lvs(vg, removal_lvs))
+ return_0;
+
+ dm_list_init(removal_lvs);
+
+ /* Wait for events following any deactivation. */
+ sync_local_dev_names(vg->cmd);
+
+ if (vg_write_requested && !_vg_write_commit_backup(vg))
+ return_0;
+
+ return 1;
+}
+
+static int _eliminate_extracted_lvs(struct volume_group *vg, struct dm_list *removal_lvs)
+{
+ return _eliminate_extracted_lvs_optional_write_vg(vg, removal_lvs, 1);
+}
+/*
+ * Convert a RAID0 set to striped
+ */
+static int _convert_raid0_to_striped(struct logical_volume *lv,
+ int update_and_reload,
+ struct dm_list *removal_lvs)
+{
+ struct lv_segment *seg = first_seg(lv);
+
+ /* Move the AREA_PV areas across to new top-level segments of type "striped" */
+ if (!_raid0_to_striped_retrieve_segments_and_lvs(lv, removal_lvs)) {
+ log_error("Failed to retrieve raid0 segments from %s.", lv->name);
+ return 0;
+ }
+
+ lv->status &= ~RAID;
+
+ if (!(seg->segtype = get_segtype_from_string(lv->vg->cmd, SEG_TYPE_NAME_STRIPED)))
+ return_0;
+
+ if (update_and_reload) {
+ if (!lv_update_and_reload(lv))
+ return_0;
+
+ /* Eliminate the residual LVs, write VG, commit it and take a backup */
+ return _eliminate_extracted_lvs(lv->vg, removal_lvs);
+ }
+
+ return 1;
+}
+
+/*
+ * Inserts hidden LVs for all segments and the parallel areas in lv and moves
+ * given segments and areas across.
+ *
+ * Optionally updates metadata and reloads mappings.
+ */
+static struct lv_segment *_convert_striped_to_raid0(struct logical_volume *lv,
+ int update_and_reload,
+ struct dm_list *allocate_pvs)
+{
+ uint32_t area_count, area_len = 0, stripe_size;
+ struct lv_segment *seg, *raid0_seg;
+ struct segment_type *segtype;
+ struct dm_list data_lvs;
+
+ dm_list_iterate_items(seg, &lv->segments)
+ area_len += seg->area_len;
+
+ seg = first_seg(lv);
+ stripe_size = seg->stripe_size;
+ area_count = seg->area_count;
+
+ /* Check for not (yet) supported varying area_count on multi-segment striped LVs */
+ if (!lv_has_constant_stripes(lv)) {
+ log_error("Cannot convert striped LV %s with varying stripe count to raid0",
+ display_lvname(lv));
+ return NULL;
+ }
+
+ if (!is_power_of_2(seg->stripe_size)) {
+ log_error("Cannot convert striped LV %s with non-power of 2 stripe size %u",
+ display_lvname(lv), seg->stripe_size);
+ // log_error("Please use \"lvconvert --duplicate ...\"");
+ return NULL;
+ }
+
+ if (!(segtype = get_segtype_from_flag(lv->vg->cmd, SEG_RAID0)))
+ return_NULL;
+
+ /* Allocate empty rimage components */
+ dm_list_init(&data_lvs);
+ if (!_alloc_image_components(lv, NULL, area_count, NULL, &data_lvs)) {
+ log_error("Failed to allocate empty image components for raid0 LV %s.",
+ display_lvname(lv));
+ return NULL;
+ }
+
+ /* Move the AREA_PV areas across to the new rimage components; empties lv->segments */
+ if (!_striped_to_raid0_move_segs_to_raid0_lvs(lv, &data_lvs)) {
+ log_error("Failed to insert linear LVs underneath %s.", display_lvname(lv));
+ return NULL;
+ }
+
+ /*
+ * Allocate single segment to hold the image component
+ * areas based on the first data LVs properties derived
+ * from the first new raid0 LVs first segment
+ */
+ seg = first_seg(dm_list_item(dm_list_first(&data_lvs), struct lv_list)->lv);
+ if (!(raid0_seg = alloc_lv_segment(segtype, lv,
+ 0 /* le */, lv->le_count /* len */,
+ seg->status | SEG_RAID,
+ stripe_size, NULL /* log_lv */,
+ area_count, area_len,
+ 0 /* chunk_size */,
+ 0 /* seg->region_size */, 0u /* extents_copied */ ,
+ NULL /* pvmove_source_seg */))) {
+ log_error("Failed to allocate new raid0 segement for LV %s.", display_lvname(lv));
+ return NULL;
+ }
+
+ /* Add new single raid0 segment to emptied LV segments list */
+ dm_list_add(&lv->segments, &raid0_seg->list);
+
+ /* Add data LVs to the top-level LVs segment; resets LV_REBUILD flag on them */
+ if (!_add_image_component_list(raid0_seg, 1, 0, &data_lvs, 0))
+ return NULL;
+
+ lv->status |= RAID;
+
+ if (update_and_reload && !lv_update_and_reload(lv))
+ return NULL;
+
+ return raid0_seg;
+}
+
/*
* Individual takeover functions.
*/
@@ -1480,7 +1950,7 @@ typedef int (*takeover_fn_t)(TAKEOVER_FN_ARGS);
*/
static int _takeover_noop(TAKEOVER_FN_ARGS)
{
- log_error("Logical volume %s is already of requested type %s",
+ log_error("Logical volume %s is already of requested type %s.",
display_lvname(lv), lvseg_name(first_seg(lv)));
return 0;
@@ -1500,9 +1970,9 @@ static int _takeover_unsupported(TAKEOVER_FN_ARGS)
static int _takeover_not_possible(takeover_fn_t takeover_fn)
{
if (takeover_fn == _takeover_noop || takeover_fn == _takeover_unsupported)
- return 0;
+ return 1;
- return 1;
+ return 0;
}
static int _takeover_unsupported_yet(const struct logical_volume *lv, const struct segment_type *new_segtype)
@@ -1598,7 +2068,16 @@ static int _takeover_from_raid0_to_raid6(TAKEOVER_FN_ARGS)
static int _takeover_from_raid0_to_striped(TAKEOVER_FN_ARGS)
{
- return _takeover_unsupported_yet(lv, new_segtype);
+ struct dm_list removal_lvs;
+
+ dm_list_init(&removal_lvs);
+
+ /* Archive metadata */
+ if (!archive(lv->vg))
+ return_0;
+
+ /* FIXME update_and_reload is only needed if the LV is already active */
+ return _convert_raid0_to_striped(lv, 1, &removal_lvs);
}
/*
@@ -1743,9 +2222,26 @@ static int _takeover_from_raid6_to_striped(TAKEOVER_FN_ARGS)
return _takeover_unsupported_yet(lv, new_segtype);
}
+static int _striped_to_raid0_wrapper(struct logical_volume *lv,
+ const struct segment_type *new_segtype,
+ int yes, int force, int alloc_metadata_devs,
+ struct dm_list *allocate_pvs)
+{
+ /* Archive metadata */
+ if (!archive(lv->vg))
+ return_0;
+
+ /* FIXME update_and_reload is only needed if the LV is already active */
+ /* FIXME Some of the validation in here needs moving before the archiving */
+ if (!_convert_striped_to_raid0(lv, 1 /* update_and_reload */, allocate_pvs))
+ return_0;
+
+ return 1;
+}
+
static int _takeover_from_striped_to_raid0(TAKEOVER_FN_ARGS)
{
- return _takeover_unsupported_yet(lv, new_segtype);
+ return _striped_to_raid0_wrapper(lv, new_segtype, yes, force, 0, allocate_pvs);
}
static int _takeover_from_striped_to_raid01(TAKEOVER_FN_ARGS)
@@ -1921,6 +2417,7 @@ int lv_raid_convert(struct logical_volume *lv,
return takeover_fn(lv, new_segtype, yes, force, new_image_count, new_stripes, new_stripe_size, allocate_pvs);
/* FIXME If not active, prompt and activate */
+ /* FIXME Some operations do not require the LV to be active */
/* LV must be active to perform raid conversion operations */
if (!lv_is_active(lv)) {
log_error("%s must be active to perform this operation.",
diff --git a/lib/metadata/segtype.c b/lib/metadata/segtype.c
index 0e17111..8d8b28c 100644
--- a/lib/metadata/segtype.c
+++ b/lib/metadata/segtype.c
@@ -34,3 +34,16 @@ struct segment_type *get_segtype_from_string(struct cmd_context *cmd,
return segtype;
}
+
+struct segment_type *get_segtype_from_flag(struct cmd_context *cmd, uint64_t flag)
+{
+ struct segment_type *segtype;
+
+ dm_list_iterate_items(segtype, &cmd->segtypes)
+ if (flag & segtype->flags)
+ return segtype;
+
+ log_error(INTERNAL_ERROR "Unrecognised segment type flag 0x%" PRIu64, flag);
+
+ return NULL;
+}
diff --git a/lib/metadata/segtype.h b/lib/metadata/segtype.h
index f3b1510..b43f228 100644
--- a/lib/metadata/segtype.h
+++ b/lib/metadata/segtype.h
@@ -222,6 +222,8 @@ struct segtype_handler {
struct segment_type *get_segtype_from_string(struct cmd_context *cmd,
const char *str);
+struct segment_type *get_segtype_from_flag(struct cmd_context *cmd,
+ uint64_t flag);
struct segtype_library;
int lvm_register_segtype(struct segtype_library *seglib,
diff --git a/lib/misc/util.h b/lib/misc/util.h
index 1011fdd..730b903 100644
--- a/lib/misc/util.h
+++ b/lib/misc/util.h
@@ -27,6 +27,8 @@
(void) (&_a == &_b); \
_a > _b ? _a : _b; })
+#define is_power_of_2(n) ((n) && !((n) & ((n) - 1)))
+
#if defined(__clang__) || (defined(__GNUC__) && __GNUC__ >= 4 && __GNUC_MINOR__ >= 6)
#define uninitialized_var(x) x
#else
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=6f216692b47b38f4…
Commit: 6f216692b47b38f480e50d213de5c513a309d9e0
Parent: 1d3532d0a7d458550b53218a6b21798eab30b68e
Author: Tony Asleson <tasleson(a)redhat.com>
AuthorDate: Tue Jun 28 13:36:32 2016 -0500
Committer: Tony Asleson <tasleson(a)redhat.com>
CommitterDate: Tue Jun 28 13:36:32 2016 -0500
lvmdbustest: Comment out refresh check for LV create
When we test Vg.LvCreateRaid some of the hidden LVs volume type go from
'I' to 'i' between the time it takes us to create the LV and
the time it takes to call into refresh to verify the service is up to date.
This is a fairly rare occurance.
---
test/dbus/lvmdbustest.py | 6 +++++-
1 files changed, 5 insertions(+), 1 deletions(-)
diff --git a/test/dbus/lvmdbustest.py b/test/dbus/lvmdbustest.py
index 4443b0c..457db96 100755
--- a/test/dbus/lvmdbustest.py
+++ b/test/dbus/lvmdbustest.py
@@ -373,7 +373,11 @@ class TestDbusService(unittest.TestCase):
lv = ClientProxy(self.bus, path)
# TODO verify object properties
- self.assertEqual(self._refresh(), 0)
+ # We are quick enough now that we can get VolumeType changes from
+ # 'I' to 'i' between the time it takes to create a RAID and it returns
+ # and when we refresh state here. Not sure how we can handle this as
+ # we cannot just sit and poll all the time for changes...
+ # self.assertEqual(self._refresh(), 0)
return lv
def test_lv_create(self):
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=1d3532d0a7d45855…
Commit: 1d3532d0a7d458550b53218a6b21798eab30b68e
Parent: e6e5c3d3ecb7de18ec2d103df8e5b0229df9ce1c
Author: Tony Asleson <tasleson(a)redhat.com>
AuthorDate: Tue Jun 28 13:32:39 2016 -0500
Committer: Tony Asleson <tasleson(a)redhat.com>
CommitterDate: Tue Jun 28 13:32:39 2016 -0500
lvmdbusd: Add --nojson command line option
Add ability to not use the JSON output even if available.
---
daemons/lvmdbusd/main.py | 6 +++++-
1 files changed, 5 insertions(+), 1 deletions(-)
diff --git a/daemons/lvmdbusd/main.py b/daemons/lvmdbusd/main.py
index aa16a2e..f28b402 100644
--- a/daemons/lvmdbusd/main.py
+++ b/daemons/lvmdbusd/main.py
@@ -101,6 +101,10 @@ def main():
help="Dump debug messages", default=False,
dest='debug')
+ parser.add_argument("--nojson", action='store_false',
+ help="Do not use LVM JSON output", default=None,
+ dest='use_json')
+
use_session = os.getenv('LVMDBUSD_USE_SESSION', False)
# Ensure that we get consistent output for parsing stdout/stderr
@@ -137,7 +141,7 @@ def main():
cfg.load = load
- cfg.db = lvmdb.DataStore()
+ cfg.db = lvmdb.DataStore(args.use_json)
# Start up thread to monitor pv moves
thread_list.append(
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=e6e5c3d3ecb7de18…
Commit: e6e5c3d3ecb7de18ec2d103df8e5b0229df9ce1c
Parent: 7c5a08521b687c7c7074b41d880e1e559d4ea6b8
Author: Tony Asleson <tasleson(a)redhat.com>
AuthorDate: Tue Jun 28 12:52:31 2016 -0500
Committer: Tony Asleson <tasleson(a)redhat.com>
CommitterDate: Tue Jun 28 12:54:48 2016 -0500
lvmdbusd: Remove WARNING for 'lvm help'
We call 'lvm help' to find out if fullreport is supported. Lvm
dumps help to stderr. Common code prints a warning if we exit
with 0, but have something in stderr so we are skipping the warning
message.
---
daemons/lvmdbusd/cmdhandler.py | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/daemons/lvmdbusd/cmdhandler.py b/daemons/lvmdbusd/cmdhandler.py
index 560b389..391757d 100644
--- a/daemons/lvmdbusd/cmdhandler.py
+++ b/daemons/lvmdbusd/cmdhandler.py
@@ -110,7 +110,7 @@ def call_lvm(command, debug=False):
_debug_c(command, process.returncode, (stdout_text, stderr_text))
if process.returncode == 0:
- if cfg.DEBUG and out[1] and len(out[1]):
+ if cfg.DEBUG and out[1] and len(out[1]) and 'help' not in command:
log_error('WARNING: lvm is out-putting text to STDERR on success!')
_debug_c(command, process.returncode, (stdout_text, stderr_text))
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=7c5a08521b687c7c…
Commit: 7c5a08521b687c7c7074b41d880e1e559d4ea6b8
Parent: 9e3ad37828a14924dd12f65e62194bef286a16f0
Author: Tony Asleson <tasleson(a)redhat.com>
AuthorDate: Tue Jun 28 12:45:55 2016 -0500
Committer: Tony Asleson <tasleson(a)redhat.com>
CommitterDate: Tue Jun 28 12:45:55 2016 -0500
lvmdbusd: Remove unneeded comment
---
daemons/lvmdbusd/lv.py | 2 --
1 files changed, 0 insertions(+), 2 deletions(-)
diff --git a/daemons/lvmdbusd/lv.py b/daemons/lvmdbusd/lv.py
index 8f063dc..5658d29 100644
--- a/daemons/lvmdbusd/lv.py
+++ b/daemons/lvmdbusd/lv.py
@@ -472,8 +472,6 @@ class Lv(LvCommon):
# it is a thin lv
if not dbo.IsThinVolume:
if optional_size == 0:
- # TODO: Should we pick a sane default or force user to
- # make a decision?
space = dbo.SizeBytes / 80
remainder = space % 512
optional_size = space + 512 - remainder
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=9e3ad37828a14924…
Commit: 9e3ad37828a14924dd12f65e62194bef286a16f0
Parent: c11003c860fe9242f49ba6ccffadd964501f1d1f
Author: Tony Asleson <tasleson(a)redhat.com>
AuthorDate: Tue Jun 28 12:45:28 2016 -0500
Committer: Tony Asleson <tasleson(a)redhat.com>
CommitterDate: Tue Jun 28 12:45:28 2016 -0500
lvmdbusd: Clean up ws
---
daemons/lvmdbusd/cmdhandler.py | 2 +-
daemons/lvmdbusd/lvmdb.py | 1 -
daemons/lvmdbusd/objectmanager.py | 2 +-
3 files changed, 2 insertions(+), 3 deletions(-)
diff --git a/daemons/lvmdbusd/cmdhandler.py b/daemons/lvmdbusd/cmdhandler.py
index 138142f..560b389 100644
--- a/daemons/lvmdbusd/cmdhandler.py
+++ b/daemons/lvmdbusd/cmdhandler.py
@@ -448,7 +448,7 @@ def lvm_full_report_json():
'vg_uuid']
pv_seg_columns = ['pvseg_start', 'pvseg_size', 'segtype',
- 'pv_uuid', 'lv_uuid', 'pv_name']
+ 'pv_uuid', 'lv_uuid', 'pv_name']
vg_columns = ['vg_name', 'vg_uuid', 'vg_fmt', 'vg_size', 'vg_free',
'vg_sysid', 'vg_extent_size', 'vg_extent_count',
diff --git a/daemons/lvmdbusd/lvmdb.py b/daemons/lvmdbusd/lvmdb.py
index 51794d5..2dc593b 100755
--- a/daemons/lvmdbusd/lvmdb.py
+++ b/daemons/lvmdbusd/lvmdb.py
@@ -234,7 +234,6 @@ class DataStore(object):
return DataStore._parse_lvs_common(c_lvs, c_lv_full_lookup)
-
@staticmethod
def _parse_lvs_json(_all):
diff --git a/daemons/lvmdbusd/objectmanager.py b/daemons/lvmdbusd/objectmanager.py
index c93f207..178003e 100644
--- a/daemons/lvmdbusd/objectmanager.py
+++ b/daemons/lvmdbusd/objectmanager.py
@@ -224,7 +224,7 @@ class ObjectManager(AutomatedProperties):
return path
def get_object_path_by_uuid_lvm_id(self, uuid, lvm_id, path_create=None,
- gen_new=True):
+ gen_new=True):
"""
For a given lvm asset return the dbus object registered to it. If the
object is not found and gen_new == True and path_create is a valid
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=c11003c860fe9242…
Commit: c11003c860fe9242f49ba6ccffadd964501f1d1f
Parent: dd5d865020acd545712d4bcc0f3236143de4d76d
Author: Tony Asleson <tasleson(a)redhat.com>
AuthorDate: Tue Jun 28 12:44:45 2016 -0500
Committer: Tony Asleson <tasleson(a)redhat.com>
CommitterDate: Tue Jun 28 12:44:45 2016 -0500
lvmdbusd: Remove unused imports and function parameter
---
daemons/lvmdbusd/background.py | 6 ++----
1 files changed, 2 insertions(+), 4 deletions(-)
diff --git a/daemons/lvmdbusd/background.py b/daemons/lvmdbusd/background.py
index ca3d60e..2c719fc 100644
--- a/daemons/lvmdbusd/background.py
+++ b/daemons/lvmdbusd/background.py
@@ -13,9 +13,7 @@ from . import cfg
import time
from .cmdhandler import options_to_cli_args
import dbus
-from .job import Job, JobState
-from .utils import pv_range_append, pv_dest_ranges, log_debug, log_error
-from .request import RequestEntry
+from .utils import pv_range_append, pv_dest_ranges, log_error
import traceback
_rlock = threading.RLock()
@@ -125,7 +123,7 @@ def background_reaper():
time.sleep(3)
-def background_execute(command, background_job, skip_first_line=False):
+def background_execute(command, background_job):
# Wrap this whole operation in an exception handler, otherwise if we
# hit a code bug we will silently exit this thread without anyone being
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=dd5d865020acd545…
Commit: dd5d865020acd545712d4bcc0f3236143de4d76d
Parent: 5274c2f11b9e262588c1dec86609e829618d2e76
Author: Tony Asleson <tasleson(a)redhat.com>
AuthorDate: Tue Jun 28 12:07:21 2016 -0500
Committer: Tony Asleson <tasleson(a)redhat.com>
CommitterDate: Tue Jun 28 12:09:28 2016 -0500
lvmdbusd: Fix hang when lvm compiled with 'enable-notify-dbus'
The following operations would hang if lvm was compiled with
'enable-notify-dbus' and the client specified -1 for the timeout:
* LV snapshot merge
* VG move
* LV move
This was caused because the implementation of these three dbus methods is
different. Most of the dbus method calls are executed by gathering information
needed to fulfill it, placing that information on a thread safe queue and
returning. The results later to be returned to the client with callbacks.
With this approach we can process an arbitrary number of commands without any
of them blocking other dbus commands. However, the 3 dbus methods listed
above did not utilize this functionality because they were implemented with a
separate thread that handles the fork & exec of lvm. This is done because these
operations can be very slow to complete. However, because of this the lvm
command that we were waiting on is trying to call back into the dbus service to
notify it that something changed. Because the code was blocking the process
that handles the incoming dbus activity the lvm command blocked. We were stuck
until the client timed-out the connection, which then causes the service to
unblock and continue. If the client did not have a timeout, we would have been
hung indefinitely.
The fix is to always utilize the worker queue on all dbus methods. We need to
ensure that lvm is tested with 'enable-notify-dbus' enabled and disabled.
---
daemons/lvmdbusd/background.py | 77 ++++++++++-----------------------------
daemons/lvmdbusd/job.py | 2 +-
daemons/lvmdbusd/lv.py | 34 ++++++++++++-----
daemons/lvmdbusd/request.py | 5 ++-
daemons/lvmdbusd/vg.py | 19 +++++++---
5 files changed, 62 insertions(+), 75 deletions(-)
diff --git a/daemons/lvmdbusd/background.py b/daemons/lvmdbusd/background.py
index 4265154..ca3d60e 100644
--- a/daemons/lvmdbusd/background.py
+++ b/daemons/lvmdbusd/background.py
@@ -43,40 +43,22 @@ def lv_merge_cmd(merge_options, lv_full_name):
return cmd
-def _create_background_dbus_job(job_state):
- job_obj = Job(None, job_state)
- cfg.om.register_object(job_obj)
- return job_obj.dbus_object_path()
-
-
-def _move_merge(interface_name, cmd, time_out):
- # Create job object to be used while running the command
- rc = '/'
- job_state = JobState(None)
+def _move_merge(interface_name, cmd, job_state):
add(cmd, job_state)
- if time_out == -1:
- # Waiting forever
- done = job_state.Wait(time_out)
- if not done:
- ec, err_msg = job_state.GetError
- raise dbus.exceptions.DBusException(
- interface_name,
- 'Exit code %s, stderr = %s' % (str(ec), err_msg))
- elif time_out == 0:
- # Immediately create and return a job
- rc = _create_background_dbus_job(job_state)
- else:
- # Willing to wait for a bit
- done = job_state.Wait(time_out)
- if not done:
- rc = _create_background_dbus_job(job_state)
+ done = job_state.Wait(-1)
+ if not done:
+ ec, err_msg = job_state.GetError
+ raise dbus.exceptions.DBusException(
+ interface_name,
+ 'Exit code %s, stderr = %s' % (str(ec), err_msg))
- return rc
+ cfg.load()
+ return '/'
def move(interface_name, lv_name, pv_src_obj, pv_source_range,
- pv_dests_and_ranges, move_options, time_out):
+ pv_dests_and_ranges, move_options, job_state):
"""
Common code for the pvmove handling.
:param interface_name: What dbus interface we are providing for
@@ -85,8 +67,8 @@ def move(interface_name, lv_name, pv_src_obj, pv_source_range,
:param pv_source_range: (0,0 to ignore, else start, end segments)
:param pv_dests_and_ranges: Array of PV object paths and start/end segs
:param move_options: Hash with optional arguments
- :param time_out:
- :return: Object path to job object
+ :param job_state: Used to convey information about jobs between processes
+ :return: '/' When complete, the empty object path
"""
pv_dests = []
pv_src = cfg.om.get_object_by_path(pv_src_obj)
@@ -112,18 +94,18 @@ def move(interface_name, lv_name, pv_src_obj, pv_source_range,
pv_source_range,
pv_dests)
- return _move_merge(interface_name, cmd, time_out)
+ return _move_merge(interface_name, cmd, job_state)
else:
raise dbus.exceptions.DBusException(
interface_name, 'pv_src_obj (%s) not found' % pv_src_obj)
-def merge(interface_name, lv_uuid, lv_name, merge_options, time_out):
+def merge(interface_name, lv_uuid, lv_name, merge_options, job_state):
# Make sure we have a dbus object representing it
dbo = cfg.om.get_object_by_uuid_lvm_id(lv_uuid, lv_name)
if dbo:
cmd = lv_merge_cmd(merge_options, dbo.lvm_id)
- return _move_merge(interface_name, cmd, time_out)
+ return _move_merge(interface_name, cmd, job_state)
else:
raise dbus.exceptions.DBusException(
interface_name,
@@ -143,17 +125,6 @@ def background_reaper():
time.sleep(3)
-def process_background_result(job_object, exit_code, error_msg):
- cfg.load()
- job_object.set_result(exit_code, error_msg)
- return None
-
-
-# noinspection PyUnusedLocal
-def empty_cb(disregard):
- pass
-
-
def background_execute(command, background_job, skip_first_line=False):
# Wrap this whole operation in an exception handler, otherwise if we
@@ -181,23 +152,15 @@ def background_execute(command, background_job, skip_first_line=False):
if process.returncode == 0:
background_job.Percent = 100
- # Queue up the result so that it gets executed in same thread as others.
- r = RequestEntry(
- -1, process_background_result,
- (background_job, process.returncode, out[1]),
- empty_cb, empty_cb, False)
- cfg.worker_q.put(r)
+ background_job.set_result(process.returncode, out[1])
+
except Exception:
- # In the unlikely event that we blew up, lets notify fill out the
- # job object so that the client doesn't hang potentially forever!
+ # In the unlikely event that we blow up, we need to unblock caller which
+ # is waiting on an answer.
st = traceback.format_exc()
error = "Exception in background thread: \n%s" % st
log_error(error)
- r = RequestEntry(
- -1, process_background_result,
- (background_job, 1, error),
- empty_cb, empty_cb, False)
- cfg.worker_q.put(r)
+ background_job.set_result(1, error)
def add(command, reporting_job):
diff --git a/daemons/lvmdbusd/job.py b/daemons/lvmdbusd/job.py
index b16f8e6..d7f8187 100644
--- a/daemons/lvmdbusd/job.py
+++ b/daemons/lvmdbusd/job.py
@@ -17,7 +17,7 @@ import threading
# noinspection PyPep8Naming
class JobState(object):
- def __init__(self, request):
+ def __init__(self, request=None):
self.rlock = threading.RLock()
self._percent = 0
diff --git a/daemons/lvmdbusd/lv.py b/daemons/lvmdbusd/lv.py
index 5c7b3b5..8f063dc 100644
--- a/daemons/lvmdbusd/lv.py
+++ b/daemons/lvmdbusd/lv.py
@@ -22,6 +22,7 @@ from .loader import common
from .state import State
from . import background
from .utils import round_size
+from .job import JobState
# Try and build a key for a LV, so that we sort the LVs with least dependencies
@@ -444,14 +445,21 @@ class Lv(LvCommon):
@dbus.service.method(
dbus_interface=LV_INTERFACE,
in_signature='o(tt)a(ott)ia{sv}',
- out_signature='o')
+ out_signature='o',
+ async_callbacks=('cb', 'cbe'))
def Move(self, pv_src_obj, pv_source_range,
pv_dests_and_ranges,
- tmo, move_options):
- return background.move(
- LV_INTERFACE, self.lvm_id, pv_src_obj,
- pv_source_range, pv_dests_and_ranges,
- move_options, tmo)
+ tmo, move_options, cb, cbe):
+
+ job_state = JobState()
+
+ r = RequestEntry(
+ tmo, background.move,
+ (LV_INTERFACE, self.lvm_id, pv_src_obj, pv_source_range,
+ pv_dests_and_ranges, move_options, job_state), cb, cbe, False,
+ job_state)
+
+ cfg.worker_q.put(r)
@staticmethod
def _snap_shot(lv_uuid, lv_name, name, optional_size,
@@ -875,7 +883,13 @@ class LvSnapShot(Lv):
@dbus.service.method(
dbus_interface=SNAPSHOT_INTERFACE,
in_signature='ia{sv}',
- out_signature='o')
- def Merge(self, tmo, merge_options):
- return background.merge(SNAPSHOT_INTERFACE, self.Uuid, self.lvm_id,
- merge_options, tmo)
+ out_signature='o',
+ async_callbacks=('cb', 'cbe'))
+ def Merge(self, tmo, merge_options, cb, cbe):
+ job_state = JobState()
+
+ r = RequestEntry(tmo, background.merge,
+ (SNAPSHOT_INTERFACE, self.Uuid, self.lvm_id,
+ merge_options, job_state), cb, cbe, False,
+ job_state)
+ cfg.worker_q.put(r)
diff --git a/daemons/lvmdbusd/request.py b/daemons/lvmdbusd/request.py
index 3e29b82..ce6a6ef 100644
--- a/daemons/lvmdbusd/request.py
+++ b/daemons/lvmdbusd/request.py
@@ -18,7 +18,7 @@ from .utils import log_error
class RequestEntry(object):
def __init__(self, tmo, method, arguments, cb, cb_error,
- return_tuple=True):
+ return_tuple=True, job_state=None):
self.tmo = tmo
self.method = method
self.arguments = arguments
@@ -33,6 +33,7 @@ class RequestEntry(object):
self._rc = 0
self._rc_error = None
self._return_tuple = return_tuple
+ self._job_state = job_state
if self.tmo < 0:
# Client is willing to block forever
@@ -53,7 +54,7 @@ class RequestEntry(object):
r.timer_expired()
def _return_job(self):
- self._job = Job(self)
+ self._job = Job(self, self._job_state)
cfg.om.register_object(self._job, True)
if self._return_tuple:
self.cb(('/', self._job.dbus_object_path()))
diff --git a/daemons/lvmdbusd/vg.py b/daemons/lvmdbusd/vg.py
index c700667..4cc938e 100644
--- a/daemons/lvmdbusd/vg.py
+++ b/daemons/lvmdbusd/vg.py
@@ -20,6 +20,7 @@ from .loader import common
from .state import State
from . import background
from .utils import round_size
+from .job import JobState
# noinspection PyUnusedLocal
@@ -352,12 +353,20 @@ class Vg(AutomatedProperties):
@dbus.service.method(
dbus_interface=VG_INTERFACE,
in_signature='o(tt)a(ott)ia{sv}',
- out_signature='o')
+ out_signature='o',
+ async_callbacks=('cb', 'cbe'))
def Move(self, pv_src_obj, pv_source_range, pv_dests_and_ranges,
- tmo, move_options):
- return background.move(
- VG_INTERFACE, None, pv_src_obj, pv_source_range,
- pv_dests_and_ranges, move_options, tmo)
+ tmo, move_options, cb, cbe):
+
+ job_state = JobState()
+
+ r = RequestEntry(
+ tmo, background.move,
+ (VG_INTERFACE, None, pv_src_obj, pv_source_range,
+ pv_dests_and_ranges, move_options, job_state), cb, cbe, False,
+ job_state)
+
+ cfg.worker_q.put(r)
@staticmethod
def _lv_create(uuid, vg_name, name, size_bytes, pv_dests_and_ranges,
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=5274c2f11b9e2625…
Commit: 5274c2f11b9e262588c1dec86609e829618d2e76
Parent: 4f26eae40f07399f11a2abe675aef850b0dd5239
Author: Tony Asleson <tasleson(a)redhat.com>
AuthorDate: Tue Jun 28 11:45:05 2016 -0500
Committer: Tony Asleson <tasleson(a)redhat.com>
CommitterDate: Tue Jun 28 12:09:28 2016 -0500
lvmdbusd: request.py, initialize _job to None
_job is a job object, not a boolean so initialize it to None instead.
---
daemons/lvmdbusd/request.py | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/daemons/lvmdbusd/request.py b/daemons/lvmdbusd/request.py
index 02f8c88..3e29b82 100644
--- a/daemons/lvmdbusd/request.py
+++ b/daemons/lvmdbusd/request.py
@@ -29,7 +29,7 @@ class RequestEntry(object):
self.lock = threading.RLock()
self.done = False
self._result = None
- self._job = False
+ self._job = None
self._rc = 0
self._rc_error = None
self._return_tuple = return_tuple
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=4f26eae40f07399f…
Commit: 4f26eae40f07399f11a2abe675aef850b0dd5239
Parent: 0aadd6b0fb4eaa9e59d6f750f2efe2fdfdacdd8f
Author: Tony Asleson <tasleson(a)redhat.com>
AuthorDate: Mon Jun 27 17:07:20 2016 -0500
Committer: Tony Asleson <tasleson(a)redhat.com>
CommitterDate: Tue Jun 28 12:09:28 2016 -0500
lvmdbusd: Correct pv_seg_start -> pvseg_start
Code was using the incorrect column names for pvseg_start which only
became apparent when utilizing the JSON.
---
daemons/lvmdbusd/cmdhandler.py | 4 ++--
daemons/lvmdbusd/lvmdb.py | 11 +++++------
2 files changed, 7 insertions(+), 8 deletions(-)
diff --git a/daemons/lvmdbusd/cmdhandler.py b/daemons/lvmdbusd/cmdhandler.py
index 2ca23e7..138142f 100644
--- a/daemons/lvmdbusd/cmdhandler.py
+++ b/daemons/lvmdbusd/cmdhandler.py
@@ -447,7 +447,7 @@ def lvm_full_report_json():
'pv_pe_alloc_count', 'pv_attr', 'pv_tags', 'vg_name',
'vg_uuid']
- pv_seg_columns = ['pv_seg_start', 'pv_seg_size', 'segtype',
+ pv_seg_columns = ['pvseg_start', 'pvseg_size', 'segtype',
'pv_uuid', 'lv_uuid', 'pv_name']
vg_columns = ['vg_name', 'vg_uuid', 'vg_fmt', 'vg_size', 'vg_free',
@@ -491,7 +491,7 @@ def pv_retrieve_with_segs(device=None):
'pv_used', 'dev_size', 'pv_mda_size', 'pv_mda_free',
'pv_ba_start', 'pv_ba_size', 'pe_start', 'pv_pe_count',
'pv_pe_alloc_count', 'pv_attr', 'pv_tags', 'vg_name',
- 'vg_uuid', 'pv_seg_start', 'pvseg_size', 'segtype']
+ 'vg_uuid', 'pvseg_start', 'pvseg_size', 'segtype']
# Lvm has some issues where it returns failure when querying pvs when other
# operations are in process, see:
diff --git a/daemons/lvmdbusd/lvmdb.py b/daemons/lvmdbusd/lvmdb.py
index f070bb6..51794d5 100755
--- a/daemons/lvmdbusd/lvmdb.py
+++ b/daemons/lvmdbusd/lvmdb.py
@@ -83,7 +83,7 @@ class DataStore(object):
for p in pvs:
DataStore._insert_record(
c_pvs, p['pv_uuid'], p,
- ['pv_seg_start', 'pvseg_size', 'segtype'])
+ ['pvseg_start', 'pvseg_size', 'segtype'])
for p in c_pvs.values():
# Capture which PVs are associated with which VG
@@ -124,16 +124,15 @@ class DataStore(object):
if 'pvseg' in r:
for s in r['pvseg']:
- # TODO Why is json pvseg_start, not pv_seg_start?
r = c_pvs[s['pv_uuid']]
- r.setdefault('pv_seg_start', []).append(s['pvseg_start'])
+ r.setdefault('pvseg_start', []).append(s['pvseg_start'])
r.setdefault('pvseg_size', []).append(s['pvseg_size'])
r.setdefault('segtype', []).append(s['segtype'])
# TODO: Remove this bug work around when we have orphan segs.
for i in c_pvs.values():
- if 'pv_seg_start' not in i:
- i['pv_seg_start'] = '0'
+ if 'pvseg_start' not in i:
+ i['pvseg_start'] = '0'
i['pvseg_size'] = i['pv_pe_count']
i['segtype'] = 'free'
@@ -469,7 +468,7 @@ class DataStore(object):
def pv_pe_segments(self, pv_uuid):
pv = self.pvs[pv_uuid]
- return list(zip(pv['pv_seg_start'], pv['pvseg_size']))
+ return list(zip(pv['pvseg_start'], pv['pvseg_size']))
def pv_contained_lv(self, pv_device):
rc = []
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=0aadd6b0fb4eaa9e…
Commit: 0aadd6b0fb4eaa9e59d6f750f2efe2fdfdacdd8f
Parent: 4b337b20d47953e130edc8a456e9431eba58a778
Author: Tony Asleson <tasleson(a)redhat.com>
AuthorDate: Mon Jun 27 17:04:44 2016 -0500
Committer: Tony Asleson <tasleson(a)redhat.com>
CommitterDate: Tue Jun 28 12:09:28 2016 -0500
lvmdbusd: Correct command line args for JSON
Use the updated syntax.
---
daemons/lvmdbusd/cmdhandler.py | 10 +++++-----
1 files changed, 5 insertions(+), 5 deletions(-)
diff --git a/daemons/lvmdbusd/cmdhandler.py b/daemons/lvmdbusd/cmdhandler.py
index 0440dbd..2ca23e7 100644
--- a/daemons/lvmdbusd/cmdhandler.py
+++ b/daemons/lvmdbusd/cmdhandler.py
@@ -467,11 +467,11 @@ def lvm_full_report_json():
cmd = _dc('fullreport', [
'-a', # Need hidden too
- '-o', '/pv/' + ','.join(pv_columns),
- '-o', '/vg/' + ','.join(vg_columns),
- '-o', '/lv/' + ','.join(lv_columns),
- '-o', '/seg/' + ','.join(lv_seg_columns),
- '-o', '/pvseg/' + ','.join(pv_seg_columns),
+ '--configreport', 'pv', '-o', ','.join(pv_columns),
+ '--configreport', 'vg', '-o', ','.join(vg_columns),
+ '--configreport', 'lv', '-o', ','.join(lv_columns),
+ '--configreport', 'seg', '-o', ','.join(lv_seg_columns),
+ '--configreport', 'pvseg', '-o', ','.join(pv_seg_columns),
'--reportformat', 'json'
])
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=4b337b20d47953e1…
Commit: 4b337b20d47953e130edc8a456e9431eba58a778
Parent: e514284c65a7cffa24549a34612392731f6e06af
Author: Tony Asleson <tasleson(a)redhat.com>
AuthorDate: Mon Jun 6 15:08:20 2016 -0500
Committer: Tony Asleson <tasleson(a)redhat.com>
CommitterDate: Tue Jun 28 12:09:28 2016 -0500
lvmdbusd: Remove sorting in db layer
When using the JSON this does not yield a totally sorted list as we don't
have a complete set of LVs, so remove this sort.
---
daemons/lvmdbusd/lvmdb.py | 8 +-------
1 files changed, 1 insertions(+), 7 deletions(-)
diff --git a/daemons/lvmdbusd/lvmdb.py b/daemons/lvmdbusd/lvmdb.py
index 5ac90e3..f070bb6 100755
--- a/daemons/lvmdbusd/lvmdb.py
+++ b/daemons/lvmdbusd/lvmdb.py
@@ -245,16 +245,10 @@ class DataStore(object):
# Each item item in the report is a collection of information pertaining
# to the vg
for r in _all['report']:
- tmp_lv = []
# Get the lv data for this VG.
if 'lv' in r:
- tmp_lv.extend(r['lv'])
-
- # Sort them
- sorted_tmp_lv = sorted(tmp_lv, key=lambda vk: vk['lv_name'])
-
# Add them to result set
- for i in sorted_tmp_lv:
+ for i in r['lv']:
full_name = "%s/%s" % (i['vg_name'], i['lv_name'])
c_lv_full_lookup[full_name] = i['lv_uuid']
c_lvs[i['lv_uuid']] = i
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=e514284c65a7cffa…
Commit: e514284c65a7cffa24549a34612392731f6e06af
Parent: ec45be9976a3c0633d89e0516f7947c305c61e47
Author: Tony Asleson <tasleson(a)redhat.com>
AuthorDate: Fri Jun 3 16:52:17 2016 -0500
Committer: Tony Asleson <tasleson(a)redhat.com>
CommitterDate: Tue Jun 28 12:09:28 2016 -0500
lvmdbusd: Add hidden in for json too
---
daemons/lvmdbusd/cmdhandler.py | 1 +
1 files changed, 1 insertions(+), 0 deletions(-)
diff --git a/daemons/lvmdbusd/cmdhandler.py b/daemons/lvmdbusd/cmdhandler.py
index 46fb68c..0440dbd 100644
--- a/daemons/lvmdbusd/cmdhandler.py
+++ b/daemons/lvmdbusd/cmdhandler.py
@@ -466,6 +466,7 @@ def lvm_full_report_json():
lv_seg_columns = ['seg_pe_ranges', 'segtype', 'lv_uuid']
cmd = _dc('fullreport', [
+ '-a', # Need hidden too
'-o', '/pv/' + ','.join(pv_columns),
'-o', '/vg/' + ','.join(vg_columns),
'-o', '/lv/' + ','.join(lv_columns),
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=ec45be9976a3c063…
Commit: ec45be9976a3c0633d89e0516f7947c305c61e47
Parent: 79446ffad7358dd8c130ff498514150d1e0ea08b
Author: Tony Asleson <tasleson(a)redhat.com>
AuthorDate: Fri Jun 3 13:18:21 2016 -0500
Committer: Tony Asleson <tasleson(a)redhat.com>
CommitterDate: Tue Jun 28 12:09:28 2016 -0500
lvmdbusd: Initial support for json output
---
daemons/lvmdbusd/cmdhandler.py | 54 ++++++++++++
daemons/lvmdbusd/lvmdb.py | 175 +++++++++++++++++++++++++++++++++++-----
2 files changed, 209 insertions(+), 20 deletions(-)
diff --git a/daemons/lvmdbusd/cmdhandler.py b/daemons/lvmdbusd/cmdhandler.py
index 1522ebf..46fb68c 100644
--- a/daemons/lvmdbusd/cmdhandler.py
+++ b/daemons/lvmdbusd/cmdhandler.py
@@ -22,6 +22,11 @@ except SystemError:
from utils import pv_dest_ranges, log_debug, log_error
from lvm_shell_proxy import LVMShellProxy
+try:
+ import simplejson as json
+except ImportError:
+ import json
+
SEP = '{|}'
total_time = 0.0
@@ -426,6 +431,55 @@ def lv_detach_cache(lv_full_name, detach_options, destroy_cache):
return call(cmd)
+def supports_json():
+ cmd = ['help']
+ rc, out, err = call(cmd)
+ if rc == 0:
+ if 'fullreport' in err:
+ return True
+ return False
+
+
+def lvm_full_report_json():
+ pv_columns = ['pv_name', 'pv_uuid', 'pv_fmt', 'pv_size', 'pv_free',
+ 'pv_used', 'dev_size', 'pv_mda_size', 'pv_mda_free',
+ 'pv_ba_start', 'pv_ba_size', 'pe_start', 'pv_pe_count',
+ 'pv_pe_alloc_count', 'pv_attr', 'pv_tags', 'vg_name',
+ 'vg_uuid']
+
+ pv_seg_columns = ['pv_seg_start', 'pv_seg_size', 'segtype',
+ 'pv_uuid', 'lv_uuid', 'pv_name']
+
+ vg_columns = ['vg_name', 'vg_uuid', 'vg_fmt', 'vg_size', 'vg_free',
+ 'vg_sysid', 'vg_extent_size', 'vg_extent_count',
+ 'vg_free_count', 'vg_profile', 'max_lv', 'max_pv',
+ 'pv_count', 'lv_count', 'snap_count', 'vg_seqno',
+ 'vg_mda_count', 'vg_mda_free', 'vg_mda_size',
+ 'vg_mda_used_count', 'vg_attr', 'vg_tags']
+
+ lv_columns = ['lv_uuid', 'lv_name', 'lv_path', 'lv_size',
+ 'vg_name', 'pool_lv_uuid', 'pool_lv', 'origin_uuid',
+ 'origin', 'data_percent',
+ 'lv_attr', 'lv_tags', 'vg_uuid', 'lv_active', 'data_lv',
+ 'metadata_lv', 'lv_parent', 'lv_role', 'lv_layout']
+
+ lv_seg_columns = ['seg_pe_ranges', 'segtype', 'lv_uuid']
+
+ cmd = _dc('fullreport', [
+ '-o', '/pv/' + ','.join(pv_columns),
+ '-o', '/vg/' + ','.join(vg_columns),
+ '-o', '/lv/' + ','.join(lv_columns),
+ '-o', '/seg/' + ','.join(lv_seg_columns),
+ '-o', '/pvseg/' + ','.join(pv_seg_columns),
+ '--reportformat', 'json'
+ ])
+
+ rc, out, err = call(cmd)
+ if rc == 0:
+ return json.loads(out)
+ return None
+
+
def pv_retrieve_with_segs(device=None):
d = []
err = ""
diff --git a/daemons/lvmdbusd/lvmdb.py b/daemons/lvmdbusd/lvmdb.py
index d14ae3b..5ac90e3 100755
--- a/daemons/lvmdbusd/lvmdb.py
+++ b/daemons/lvmdbusd/lvmdb.py
@@ -13,6 +13,7 @@ from collections import OrderedDict
import pprint as prettyprint
import os
+import sys
try:
from . import cmdhandler
@@ -23,7 +24,7 @@ except SystemError:
class DataStore(object):
- def __init__(self):
+ def __init__(self, usejson=None):
self.pvs = {}
self.vgs = {}
self.lvs = {}
@@ -41,6 +42,11 @@ class DataStore(object):
# self.refresh()
self.num_refreshes = 0
+ if usejson is None:
+ self.json = cmdhandler.supports_json()
+ else:
+ self.json = usejson
+
@staticmethod
def _insert_record(table, key, record, allowed_multiple):
if key in table:
@@ -94,6 +100,58 @@ class DataStore(object):
return c_pvs, c_lookup, c_pvs_in_vgs
@staticmethod
+ def _parse_pvs_json(_all):
+
+ c_pvs = OrderedDict()
+ c_lookup = {}
+ c_pvs_in_vgs = {}
+
+ # Each item item in the report is a collection of information pertaining
+ # to the vg
+ for r in _all['report']:
+ tmp_pv = []
+
+ # Get the pv data for this VG.
+ if 'pv' in r:
+ tmp_pv.extend(r['pv'])
+
+ # Sort them
+ sorted_tmp_pv = sorted(tmp_pv, key=lambda pk: pk['pv_name'])
+
+ # Add them to result set
+ for p in sorted_tmp_pv:
+ c_pvs[p['pv_uuid']] = p
+
+ if 'pvseg' in r:
+ for s in r['pvseg']:
+ # TODO Why is json pvseg_start, not pv_seg_start?
+ r = c_pvs[s['pv_uuid']]
+ r.setdefault('pv_seg_start', []).append(s['pvseg_start'])
+ r.setdefault('pvseg_size', []).append(s['pvseg_size'])
+ r.setdefault('segtype', []).append(s['segtype'])
+
+ # TODO: Remove this bug work around when we have orphan segs.
+ for i in c_pvs.values():
+ if 'pv_seg_start' not in i:
+ i['pv_seg_start'] = '0'
+ i['pvseg_size'] = i['pv_pe_count']
+ i['segtype'] = 'free'
+
+ for p in c_pvs.values():
+ # Capture which PVs are associated with which VG
+ if p['vg_uuid'] not in c_pvs_in_vgs:
+ c_pvs_in_vgs[p['vg_uuid']] = []
+
+ if p['vg_name']:
+ c_pvs_in_vgs[p['vg_uuid']].append(
+ (p['pv_name'], p['pv_uuid']))
+
+ # Lookup for translating between /dev/<name> and pv uuid
+ c_lookup[p['pv_name']] = p['pv_uuid']
+
+ return c_pvs, c_lookup, c_pvs_in_vgs
+
+ @staticmethod
def _parse_vgs(_vgs):
vgs = sorted(_vgs, key=lambda vk: vk['vg_name'])
@@ -107,20 +165,31 @@ class DataStore(object):
return c_vgs, c_lookup
@staticmethod
- def _parse_lvs(_lvs):
- lvs = sorted(_lvs, key=lambda vk: vk['lv_name'])
+ def _parse_vgs_json(_all):
- c_lvs = OrderedDict()
- c_lvs_in_vgs = {}
- c_lvs_hidden = {}
- c_lv_full_lookup = {}
+ tmp_vg = []
+ for r in _all['report']:
+ # Get the pv data for this VG.
+ if 'vg' in r:
+ tmp_vg.extend(r['vg'])
- for i in lvs:
- full_name = "%s/%s" % (i['vg_name'], i['lv_name'])
- c_lv_full_lookup[full_name] = i['lv_uuid']
- DataStore._insert_record(
- c_lvs, i['lv_uuid'], i,
- ['seg_pe_ranges', 'segtype'])
+ # Sort for consistent output, however this is optional
+ vgs = sorted(tmp_vg, key=lambda vk: vk['vg_name'])
+
+ c_vgs = OrderedDict()
+ c_lookup = {}
+
+ for i in vgs:
+ c_lookup[i['vg_name']] = i['vg_uuid']
+ c_vgs[i['vg_uuid']] = i
+
+ return c_vgs, c_lookup
+
+ @staticmethod
+ def _parse_lvs_common(c_lvs, c_lv_full_lookup):
+
+ c_lvs_in_vgs = OrderedDict()
+ c_lvs_hidden = OrderedDict()
for i in c_lvs.values():
if i['vg_uuid'] not in c_lvs_in_vgs:
@@ -151,6 +220,55 @@ class DataStore(object):
return c_lvs, c_lvs_in_vgs, c_lvs_hidden, c_lv_full_lookup
@staticmethod
+ def _parse_lvs(_lvs):
+ lvs = sorted(_lvs, key=lambda vk: vk['lv_name'])
+
+ c_lvs = OrderedDict()
+ c_lv_full_lookup = OrderedDict()
+
+ for i in lvs:
+ full_name = "%s/%s" % (i['vg_name'], i['lv_name'])
+ c_lv_full_lookup[full_name] = i['lv_uuid']
+ DataStore._insert_record(
+ c_lvs, i['lv_uuid'], i,
+ ['seg_pe_ranges', 'segtype'])
+
+ return DataStore._parse_lvs_common(c_lvs, c_lv_full_lookup)
+
+
+ @staticmethod
+ def _parse_lvs_json(_all):
+
+ c_lvs = OrderedDict()
+ c_lv_full_lookup = {}
+
+ # Each item item in the report is a collection of information pertaining
+ # to the vg
+ for r in _all['report']:
+ tmp_lv = []
+ # Get the lv data for this VG.
+ if 'lv' in r:
+ tmp_lv.extend(r['lv'])
+
+ # Sort them
+ sorted_tmp_lv = sorted(tmp_lv, key=lambda vk: vk['lv_name'])
+
+ # Add them to result set
+ for i in sorted_tmp_lv:
+ full_name = "%s/%s" % (i['vg_name'], i['lv_name'])
+ c_lv_full_lookup[full_name] = i['lv_uuid']
+ c_lvs[i['lv_uuid']] = i
+
+ # Add in the segment data
+ if 'seg' in r:
+ for s in r['seg']:
+ r = c_lvs[s['lv_uuid']]
+ r.setdefault('seg_pe_ranges', []).append(s['seg_pe_ranges'])
+ r.setdefault('segtype', []).append(s['segtype'])
+
+ return DataStore._parse_lvs_common(c_lvs, c_lv_full_lookup)
+
+ @staticmethod
def _make_list(l):
if not isinstance(l, list):
l = [l]
@@ -278,13 +396,22 @@ class DataStore(object):
log_debug("lvmdb - refresh entry")
# Grab everything first then parse it
- _raw_pvs = cmdhandler.pv_retrieve_with_segs()
- _raw_vgs = cmdhandler.vg_retrieve(None)
- _raw_lvs = cmdhandler.lv_retrieve_with_segments()
+ if self.json:
+ # Do a single lvm retrieve for everything in json
+ a = cmdhandler.lvm_full_report_json()
- _pvs, _pvs_lookup, _pvs_in_vgs = self._parse_pvs(_raw_pvs)
- _vgs, _vgs_lookup = self._parse_vgs(_raw_vgs)
- _lvs, _lvs_in_vgs, _lvs_hidden, _lvs_lookup = self._parse_lvs(_raw_lvs)
+ _pvs, _pvs_lookup, _pvs_in_vgs = self._parse_pvs_json(a)
+ _vgs, _vgs_lookup = self._parse_vgs_json(a)
+ _lvs, _lvs_in_vgs, _lvs_hidden, _lvs_lookup = self._parse_lvs_json(a)
+
+ else:
+ _raw_pvs = cmdhandler.pv_retrieve_with_segs()
+ _raw_vgs = cmdhandler.vg_retrieve(None)
+ _raw_lvs = cmdhandler.lv_retrieve_with_segments()
+
+ _pvs, _pvs_lookup, _pvs_in_vgs = self._parse_pvs(_raw_pvs)
+ _vgs, _vgs_lookup = self._parse_vgs(_raw_vgs)
+ _lvs, _lvs_in_vgs, _lvs_hidden, _lvs_lookup = self._parse_lvs(_raw_lvs)
# Set all
self.pvs = _pvs
@@ -389,12 +516,20 @@ class DataStore(object):
if __name__ == "__main__":
pp = prettyprint.PrettyPrinter(indent=4)
- ds = DataStore()
+ use_json = False
+
+ if len(sys.argv) != 1:
+ print(len(sys.argv))
+ use_json = True
+
+ ds = DataStore(use_json)
ds.refresh()
+ print("PVS")
for v in ds.pvs.values():
pp.pprint(v)
+ print("VGS")
for v in ds.vgs.values():
pp.pprint(v)
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=79446ffad7358dd8…
Commit: 79446ffad7358dd8c130ff498514150d1e0ea08b
Parent: ff3c4ed1c0e2e554e9fb5f9b7ff20fdf5a835852
Author: Alasdair G Kergon <agk(a)redhat.com>
AuthorDate: Tue Jun 28 02:42:30 2016 +0100
Committer: Alasdair G Kergon <agk(a)redhat.com>
CommitterDate: Tue Jun 28 02:42:30 2016 +0100
raid: Infrastructure for raid takeover.
---
WHATS_NEW | 1 +
lib/config/defaults.h | 3 +-
lib/metadata/metadata-exported.h | 1 -
lib/metadata/raid_manip.c | 490 ++++++++++++++++++++++++++++++++++++--
lib/metadata/takeover_matrix.h | 120 ++++++++++
tools/lvconvert.c | 7 +-
6 files changed, 596 insertions(+), 26 deletions(-)
diff --git a/WHATS_NEW b/WHATS_NEW
index cfa707f..3184412 100644
--- a/WHATS_NEW
+++ b/WHATS_NEW
@@ -1,5 +1,6 @@
Version 2.02.159 -
=================================
+ Add infrastructure for raid takeover lvconvert options.
Version 2.02.158 - 25th June 2016
=================================
diff --git a/lib/config/defaults.h b/lib/config/defaults.h
index 3d449ff..addb14f 100644
--- a/lib/config/defaults.h
+++ b/lib/config/defaults.h
@@ -66,7 +66,8 @@
#define DEFAULT_MIRROR_LOG_FAULT_POLICY "allocate"
#define DEFAULT_MIRROR_IMAGE_FAULT_POLICY "remove"
#define DEFAULT_MIRROR_MAX_IMAGES 8 /* limited by kernel DM_KCOPYD_MAX_REGIONS */
-#define DEFAULT_RAID_MAX_IMAGES 8
+// FIXME Increase this to 64
+#define DEFAULT_RAID_MAX_IMAGES 8 /* limited by kernel failed devices bitfield in superblock (raid4/5/6 max 253) */
#define DEFAULT_RAID_FAULT_POLICY "warn"
diff --git a/lib/metadata/metadata-exported.h b/lib/metadata/metadata-exported.h
index f47fa1d..7765d23 100644
--- a/lib/metadata/metadata-exported.h
+++ b/lib/metadata/metadata-exported.h
@@ -1196,7 +1196,6 @@ int lv_raid_merge(struct logical_volume *lv);
int lv_raid_convert(struct logical_volume *lv,
const struct segment_type *new_segtype,
int yes, int force,
- const unsigned image_count,
const unsigned stripes,
const unsigned new_stripe_size,
struct dm_list *allocate_pvs);
diff --git a/lib/metadata/raid_manip.c b/lib/metadata/raid_manip.c
index 132eef3..2cef777 100644
--- a/lib/metadata/raid_manip.c
+++ b/lib/metadata/raid_manip.c
@@ -96,7 +96,7 @@ static int _raid_in_sync(struct logical_volume *lv)
if (sync_percent == DM_PERCENT_0) {
/*
* FIXME We repeat the status read here to workaround an
- * unresolved kernel bug when we see 0 even though the
+ * unresolved kernel bug when we see 0 even though the
* the array is 100% in sync.
* https://bugzilla.redhat.com/1210637
*/
@@ -174,9 +174,9 @@ static int _raid_remove_top_layer(struct logical_volume *lv,
* @lv
*
* If LV is active:
- * clear first block of device
+ * clear first block of device
* otherwise:
- * activate, clear, deactivate
+ * activate, clear, deactivate
*
* Returns: 1 on success, 0 on failure
*/
@@ -839,10 +839,10 @@ static int _extract_image_components(struct lv_segment *seg, uint32_t idx,
* @new_count: The absolute count of images (e.g. '2' for a 2-way mirror)
* @target_pvs: The list of PVs that are candidates for removal
* @shift: If set, use _shift_and_rename_image_components().
- * Otherwise, leave the [meta_]areas as AREA_UNASSIGNED and
- * seg->area_count unchanged.
+ * Otherwise, leave the [meta_]areas as AREA_UNASSIGNED and
+ * seg->area_count unchanged.
* @extracted_[meta|data]_lvs: The LVs removed from the array. If 'shift'
- * is set, then there will likely be name conflicts.
+ * is set, then there will likely be name conflicts.
*
* This function extracts _both_ portions of the indexed image. It
* does /not/ commit the results. (IOW, erroring-out requires no unwinding
@@ -851,9 +851,9 @@ static int _extract_image_components(struct lv_segment *seg, uint32_t idx,
* Returns: 1 on success, 0 on failure
*/
static int _raid_extract_images(struct logical_volume *lv, uint32_t new_count,
- struct dm_list *target_pvs, int shift,
- struct dm_list *extracted_meta_lvs,
- struct dm_list *extracted_data_lvs)
+ struct dm_list *target_pvs, int shift,
+ struct dm_list *extracted_meta_lvs,
+ struct dm_list *extracted_data_lvs)
{
int ss, s, extract, lvl_idx = 0;
struct lv_list *lvl_array;
@@ -1461,9 +1461,428 @@ static int _convert_mirror_to_raid1(struct logical_volume *lv,
}
/*
- * lv_raid_reshape
- * @lv
- * @new_segtype
+ * Individual takeover functions.
+ */
+#define TAKEOVER_FN_ARGS \
+ struct logical_volume *lv, \
+ const struct segment_type *new_segtype, \
+ int yes, \
+ int force, \
+ unsigned new_image_count, \
+ const unsigned new_stripes, \
+ unsigned new_stripe_size, \
+ struct dm_list *allocate_pvs
+
+typedef int (*takeover_fn_t)(TAKEOVER_FN_ARGS);
+
+/*
+ * Common takeover functions.
+ */
+static int _takeover_noop(TAKEOVER_FN_ARGS)
+{
+ log_error("Logical volume %s is already of requested type %s",
+ display_lvname(lv), lvseg_name(first_seg(lv)));
+
+ return 0;
+}
+
+static int _takeover_unsupported(TAKEOVER_FN_ARGS)
+{
+ log_error("Converting the segment type for %s from %s to %s is not supported.",
+ display_lvname(lv), lvseg_name(first_seg(lv)), new_segtype->name);
+
+ return 0;
+}
+
+/*
+ * Will this particular takeover combination be possible?
+ */
+static int _takeover_not_possible(takeover_fn_t takeover_fn)
+{
+ if (takeover_fn == _takeover_noop || takeover_fn == _takeover_unsupported)
+ return 0;
+
+ return 1;
+}
+
+static int _takeover_unsupported_yet(const struct logical_volume *lv, const struct segment_type *new_segtype)
+{
+ log_error("Converting the segment type for %s from %s to %s is not supported yet.",
+ display_lvname(lv), lvseg_name(first_seg(lv)), new_segtype->name);
+
+ return 0;
+}
+
+/*
+ * Customised takeover functions
+ */
+static int _takeover_from_linear_to_raid0(TAKEOVER_FN_ARGS)
+{
+ return _takeover_unsupported_yet(lv, new_segtype);
+}
+
+static int _takeover_from_linear_to_raid1(TAKEOVER_FN_ARGS)
+{
+ return _takeover_unsupported_yet(lv, new_segtype);
+}
+
+static int _takeover_from_linear_to_raid10(TAKEOVER_FN_ARGS)
+{
+ return _takeover_unsupported_yet(lv, new_segtype);
+}
+
+static int _takeover_from_linear_to_raid45(TAKEOVER_FN_ARGS)
+{
+ return _takeover_unsupported_yet(lv, new_segtype);
+}
+
+static int _takeover_from_mirrored_to_raid0(TAKEOVER_FN_ARGS)
+{
+ return _takeover_unsupported_yet(lv, new_segtype);
+}
+
+static int _takeover_from_mirrored_to_raid0_meta(TAKEOVER_FN_ARGS)
+{
+ return _takeover_unsupported_yet(lv, new_segtype);
+}
+
+static int _takeover_from_mirrored_to_raid1(TAKEOVER_FN_ARGS)
+{
+ return _convert_mirror_to_raid1(lv, new_segtype);
+}
+
+static int _takeover_from_mirrored_to_raid10(TAKEOVER_FN_ARGS)
+{
+ return _takeover_unsupported_yet(lv, new_segtype);
+}
+
+static int _takeover_from_mirrored_to_raid45(TAKEOVER_FN_ARGS)
+{
+ return _takeover_unsupported_yet(lv, new_segtype);
+}
+
+static int _takeover_from_raid0_to_linear(TAKEOVER_FN_ARGS)
+{
+ return _takeover_unsupported_yet(lv, new_segtype);
+}
+
+static int _takeover_from_raid0_to_mirrored(TAKEOVER_FN_ARGS)
+{
+ return _takeover_unsupported_yet(lv, new_segtype);
+}
+
+static int _takeover_from_raid0_to_raid0_meta(TAKEOVER_FN_ARGS)
+{
+ return _takeover_unsupported_yet(lv, new_segtype);
+}
+
+static int _takeover_from_raid0_to_raid1(TAKEOVER_FN_ARGS)
+{
+ return _takeover_unsupported_yet(lv, new_segtype);
+}
+
+static int _takeover_from_raid0_to_raid10(TAKEOVER_FN_ARGS)
+{
+ return _takeover_unsupported_yet(lv, new_segtype);
+}
+
+static int _takeover_from_raid0_to_raid45(TAKEOVER_FN_ARGS)
+{
+ return _takeover_unsupported_yet(lv, new_segtype);
+}
+
+static int _takeover_from_raid0_to_raid6(TAKEOVER_FN_ARGS)
+{
+ return _takeover_unsupported_yet(lv, new_segtype);
+}
+
+static int _takeover_from_raid0_to_striped(TAKEOVER_FN_ARGS)
+{
+ return _takeover_unsupported_yet(lv, new_segtype);
+}
+
+/*
+static int _takeover_from_raid0_meta_to_linear(TAKEOVER_FN_ARGS)
+{
+ return _takeover_unsupported_yet(lv, new_segtype);
+}
+
+static int _takeover_from_raid0_meta_to_mirrored(TAKEOVER_FN_ARGS)
+{
+ return _takeover_unsupported_yet(lv, new_segtype);
+}
+
+static int _takeover_from_raid0_meta_to_raid0(TAKEOVER_FN_ARGS)
+{
+ return _takeover_unsupported_yet(lv, new_segtype);
+}
+
+static int _takeover_from_raid0_meta_to_raid1(TAKEOVER_FN_ARGS)
+{
+ return _takeover_unsupported_yet(lv, new_segtype);
+}
+
+static int _takeover_from_raid0_meta_to_raid10(TAKEOVER_FN_ARGS)
+{
+ return _takeover_unsupported_yet(lv, new_segtype);
+}
+
+static int _takeover_from_raid0_meta_to_raid45(TAKEOVER_FN_ARGS)
+{
+ return _takeover_unsupported_yet(lv, new_segtype);
+}
+
+static int _takeover_from_raid0_meta_to_raid6(TAKEOVER_FN_ARGS)
+{
+ return _takeover_unsupported_yet(lv, new_segtype);
+}
+
+static int _takeover_from_raid0_meta_to_striped(TAKEOVER_FN_ARGS)
+{
+ return _takeover_unsupported_yet(lv, new_segtype);
+}
+*/
+
+static int _takeover_from_raid1_to_linear(TAKEOVER_FN_ARGS)
+{
+ return _takeover_unsupported_yet(lv, new_segtype);
+}
+
+static int _takeover_from_raid1_to_mirrored(TAKEOVER_FN_ARGS)
+{
+ return _takeover_unsupported_yet(lv, new_segtype);
+}
+
+static int _takeover_from_raid1_to_raid0(TAKEOVER_FN_ARGS)
+{
+ return _takeover_unsupported_yet(lv, new_segtype);
+}
+
+static int _takeover_from_raid1_to_raid0_meta(TAKEOVER_FN_ARGS)
+{
+ return _takeover_unsupported_yet(lv, new_segtype);
+}
+
+static int _takeover_from_raid1_to_raid1(TAKEOVER_FN_ARGS)
+{
+ return _takeover_unsupported_yet(lv, new_segtype);
+}
+
+static int _takeover_from_raid1_to_raid10(TAKEOVER_FN_ARGS)
+{
+ return _takeover_unsupported_yet(lv, new_segtype);
+}
+
+static int _takeover_from_raid1_to_raid45(TAKEOVER_FN_ARGS)
+{
+ return _takeover_unsupported_yet(lv, new_segtype);
+}
+
+static int _takeover_from_raid1_to_striped(TAKEOVER_FN_ARGS)
+{
+ return _takeover_unsupported_yet(lv, new_segtype);
+}
+
+static int _takeover_from_raid45_to_linear(TAKEOVER_FN_ARGS)
+{
+ return _takeover_unsupported_yet(lv, new_segtype);
+}
+
+static int _takeover_from_raid45_to_mirrored(TAKEOVER_FN_ARGS)
+{
+ return _takeover_unsupported_yet(lv, new_segtype);
+}
+
+static int _takeover_from_raid45_to_raid0(TAKEOVER_FN_ARGS)
+{
+ return _takeover_unsupported_yet(lv, new_segtype);
+}
+
+static int _takeover_from_raid45_to_raid0_meta(TAKEOVER_FN_ARGS)
+{
+ return _takeover_unsupported_yet(lv, new_segtype);
+}
+
+static int _takeover_from_raid45_to_raid1(TAKEOVER_FN_ARGS)
+{
+ return _takeover_unsupported_yet(lv, new_segtype);
+}
+
+static int _takeover_from_raid45_to_raid54(TAKEOVER_FN_ARGS)
+{
+ return _takeover_unsupported_yet(lv, new_segtype);
+}
+
+static int _takeover_from_raid45_to_raid6(TAKEOVER_FN_ARGS)
+{
+ return _takeover_unsupported_yet(lv, new_segtype);
+}
+
+static int _takeover_from_raid45_to_striped(TAKEOVER_FN_ARGS)
+{
+ return _takeover_unsupported_yet(lv, new_segtype);
+}
+
+static int _takeover_from_raid6_to_raid0(TAKEOVER_FN_ARGS)
+{
+ return _takeover_unsupported_yet(lv, new_segtype);
+}
+
+static int _takeover_from_raid6_to_raid0_meta(TAKEOVER_FN_ARGS)
+{
+ return _takeover_unsupported_yet(lv, new_segtype);
+}
+
+static int _takeover_from_raid6_to_raid45(TAKEOVER_FN_ARGS)
+{
+ return _takeover_unsupported_yet(lv, new_segtype);
+}
+
+static int _takeover_from_raid6_to_striped(TAKEOVER_FN_ARGS)
+{
+ return _takeover_unsupported_yet(lv, new_segtype);
+}
+
+static int _takeover_from_striped_to_raid0(TAKEOVER_FN_ARGS)
+{
+ return _takeover_unsupported_yet(lv, new_segtype);
+}
+
+static int _takeover_from_striped_to_raid01(TAKEOVER_FN_ARGS)
+{
+ return _takeover_unsupported_yet(lv, new_segtype);
+}
+
+static int _takeover_from_striped_to_raid0_meta(TAKEOVER_FN_ARGS)
+{
+ return _takeover_unsupported_yet(lv, new_segtype);
+}
+
+static int _takeover_from_striped_to_raid10(TAKEOVER_FN_ARGS)
+{
+ return _takeover_unsupported_yet(lv, new_segtype);
+}
+
+static int _takeover_from_striped_to_raid45(TAKEOVER_FN_ARGS)
+{
+ return _takeover_unsupported_yet(lv, new_segtype);
+}
+
+static int _takeover_from_striped_to_raid6(TAKEOVER_FN_ARGS)
+{
+ return _takeover_unsupported_yet(lv, new_segtype);
+}
+
+/*
+static int _takeover_from_raid01_to_raid01(TAKEOVER_FN_ARGS)
+{
+ return _takeover_unsupported_yet(lv, new_segtype);
+}
+
+static int _takeover_from_raid01_to_raid10(TAKEOVER_FN_ARGS)
+{
+ return _takeover_unsupported_yet(lv, new_segtype);
+}
+
+static int _takeover_from_raid01_to_striped(TAKEOVER_FN_ARGS)
+{
+ return _takeover_unsupported_yet(lv, new_segtype);
+}
+
+static int _takeover_from_raid10_to_linear(TAKEOVER_FN_ARGS)
+{
+ return _takeover_unsupported_yet(lv, new_segtype);
+}
+
+static int _takeover_from_raid10_to_mirrored(TAKEOVER_FN_ARGS)
+{
+ return _takeover_unsupported_yet(lv, new_segtype);
+}
+
+static int _takeover_from_raid10_to_raid0(TAKEOVER_FN_ARGS)
+{
+ return _takeover_unsupported_yet(lv, new_segtype);
+}
+
+static int _takeover_from_raid10_to_raid01(TAKEOVER_FN_ARGS)
+{
+ return _takeover_unsupported_yet(lv, new_segtype);
+}
+
+static int _takeover_from_raid10_to_raid0_meta(TAKEOVER_FN_ARGS)
+{
+ return _takeover_unsupported_yet(lv, new_segtype);
+}
+
+static int _takeover_from_raid10_to_raid1(TAKEOVER_FN_ARGS)
+{
+ return _takeover_unsupported_yet(lv, new_segtype);
+}
+
+static int _takeover_from_raid10_to_raid10(TAKEOVER_FN_ARGS)
+{
+ return _takeover_unsupported_yet(lv, new_segtype);
+}
+
+static int _takeover_from_raid10_to_striped(TAKEOVER_FN_ARGS)
+{
+ return _takeover_unsupported_yet(lv, new_segtype);
+}
+*/
+
+/*
+ * Import takeover matrix.
+ */
+#include "takeover_matrix.h"
+
+static unsigned _segtype_ix(const struct segment_type *segtype, uint32_t area_count)
+{
+ int i = 2, j;
+
+ /* Linear special case */
+ if (segtype_is_striped(segtype)) {
+ if (area_count == 1)
+ return 0; /* linear */
+ if (!segtype_is_raid0(segtype))
+ return 1; /* striped */
+ }
+
+ while ((j = _segtype_index[i++]))
+ if (segtype->flags & j)
+ break;
+
+ return (i - 1);
+}
+
+/* Call appropriate takeover function */
+static takeover_fn_t _get_takeover_fn(const struct lv_segment *seg, const struct segment_type *new_segtype, unsigned new_image_count)
+{
+ return _takeover_fns[_segtype_ix(seg->segtype, seg->area_count)][_segtype_ix(new_segtype, new_image_count)];
+}
+
+/*
+ * Check for maximum number of raid devices.
+ * Constrained by kernel MD maximum device limits _and_ dm-raid superblock
+ * bitfield constraints.
+ */
+static int _check_max_raid_devices(uint32_t image_count)
+{
+ if (image_count > DEFAULT_RAID_MAX_IMAGES) {
+ log_error("Unable to handle arrays with more than %u devices",
+ DEFAULT_RAID_MAX_IMAGES);
+ return 0;
+ }
+ return 1;
+}
+
+/* Number of data (not parity) rimages */
+static uint32_t _data_rimages_count(const struct lv_segment *seg, const uint32_t total_rimages)
+{
+ return total_rimages - seg->segtype->parity_devs;
+}
+
+/*
+ * lv_raid_convert
*
* Convert an LV from one RAID type (or 'mirror' segtype) to another.
*
@@ -1472,33 +1891,60 @@ static int _convert_mirror_to_raid1(struct logical_volume *lv,
int lv_raid_convert(struct logical_volume *lv,
const struct segment_type *new_segtype,
int yes, int force,
- unsigned new_image_count,
const unsigned new_stripes,
const unsigned new_stripe_size,
struct dm_list *allocate_pvs)
{
struct lv_segment *seg = first_seg(lv);
+ uint32_t stripes, stripe_size;
+ uint32_t new_image_count = seg->area_count;
+ takeover_fn_t takeover_fn;
if (!new_segtype) {
log_error(INTERNAL_ERROR "New segtype not specified");
return 0;
}
+ if (!_check_max_raid_devices(new_image_count))
+ return_0;
+
+ stripes = new_stripes ?: _data_rimages_count(seg, seg->area_count);
+
+ /* FIXME Ensure caller does *not* set wrong default value! */
+ /* Define new stripe size if not passed in */
+ stripe_size = new_stripe_size ?: seg->stripe_size;
+
+ takeover_fn = _get_takeover_fn(first_seg(lv), new_segtype, new_image_count);
+
+ /* Exit without doing activation checks if the combination isn't possible */
+ if (_takeover_not_possible(takeover_fn))
+ return takeover_fn(lv, new_segtype, yes, force, new_image_count, new_stripes, new_stripe_size, allocate_pvs);
+
+ /* FIXME If not active, prompt and activate */
+ /* LV must be active to perform raid conversion operations */
+ if (!lv_is_active(lv)) {
+ log_error("%s must be active to perform this operation.",
+ display_lvname(lv));
+ return 0;
+ }
+
+ /* In clustered VGs, the LV must be active on this node exclusively. */
if (vg_is_clustered(lv->vg) && !lv_is_active_exclusive_locally(lv)) {
- log_error("%s/%s must be active exclusive locally to"
- " perform this operation.", lv->vg->name, lv->name);
+ log_error("%s must be active exclusive locally to "
+ "perform this operation.", display_lvname(lv));
return 0;
}
- if (seg_is_mirror(seg) && segtype_is_raid1(new_segtype))
- return _convert_mirror_to_raid1(lv, new_segtype);
+ /* LV must be in sync. */
+ if (!_raid_in_sync(lv)) {
+ log_error("Unable to convert %s while it is not in-sync",
+ display_lvname(lv));
+ return 0;
+ }
- log_error("Converting the segment type for %s/%s from %s to %s is not yet supported.",
- lv->vg->name, lv->name, lvseg_name(seg), new_segtype->name);
- return 0;
+ return takeover_fn(lv, new_segtype, yes, force, new_image_count, new_stripes, new_stripe_size, allocate_pvs);
}
-
static int _remove_partial_multi_segment_image(struct logical_volume *lv,
struct dm_list *remove_pvs)
{
@@ -1876,7 +2322,7 @@ int lv_raid_remove_missing(struct logical_volume *lv)
*/
for (s = 0; s < seg->area_count; s++) {
- if (!lv_is_partial(seg_lv(seg, s)) &&
+ if (!lv_is_partial(seg_lv(seg, s)) &&
(!seg->meta_areas || !seg_metalv(seg, s) || !lv_is_partial(seg_metalv(seg, s))))
continue;
diff --git a/lib/metadata/takeover_matrix.h b/lib/metadata/takeover_matrix.h
new file mode 100644
index 0000000..25a8197
--- /dev/null
+++ b/lib/metadata/takeover_matrix.h
@@ -0,0 +1,120 @@
+/*
+ * Copyright (C) 2016 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#define N _takeover_noop
+#define X _takeover_unsupported
+
+#define lin_r0 _takeover_from_linear_to_raid0
+#define lin_r0 _takeover_from_linear_to_raid0
+#define lin_r1 _takeover_from_linear_to_raid1
+#define lin_r10 _takeover_from_linear_to_raid10
+#define lin_r45 _takeover_from_linear_to_raid45
+#define mir_r0 _takeover_from_mirrored_to_raid0
+#define mir_r0m _takeover_from_mirrored_to_raid0_meta
+#define mir_r1 _takeover_from_mirrored_to_raid1
+#define mir_r10 _takeover_from_mirrored_to_raid10
+#define mir_r45 _takeover_from_mirrored_to_raid45
+#define r01_r01 _takeover_from_raid01_to_raid01
+#define r01_r10 _takeover_from_raid01_to_raid10
+#define r01_str _takeover_from_raid01_to_striped
+#define r0__lin _takeover_from_raid0_to_linear
+#define r0__mir _takeover_from_raid0_to_mirrored
+#define r0m_lin _takeover_from_raid0_meta_to_linear
+#define r0m_mir _takeover_from_raid0_meta_to_mirrored
+#define r0m_r0 _takeover_from_raid0_meta_to_raid0
+#define r0m_r1 _takeover_from_raid0_meta_to_raid1
+#define r0m_r10 _takeover_from_raid0_meta_to_raid10
+#define r0m_r45 _takeover_from_raid0_meta_to_raid45
+#define r0m_r6 _takeover_from_raid0_meta_to_raid6
+#define r0m_str _takeover_from_raid0_meta_to_striped
+#define r0__r0m _takeover_from_raid0_to_raid0_meta
+#define r0__r1 _takeover_from_raid0_to_raid1
+#define r0__r10 _takeover_from_raid0_to_raid10
+#define r0__r45 _takeover_from_raid0_to_raid45
+#define r0__r6 _takeover_from_raid0_to_raid6
+#define r0__str _takeover_from_raid0_to_striped
+#define r10_lin _takeover_from_raid10_to_linear
+#define r10_mir _takeover_from_raid10_to_mirrored
+#define r10_r0 _takeover_from_raid10_to_raid0
+#define r10_r01 _takeover_from_raid10_to_raid01
+#define r10_r0m _takeover_from_raid10_to_raid0_meta
+#define r10_r1 _takeover_from_raid10_to_raid1
+#define r10_r10 _takeover_from_raid10_to_raid10
+#define r10_str _takeover_from_raid10_to_striped
+#define r1__lin _takeover_from_raid1_to_linear
+#define r1__mir _takeover_from_raid1_to_mirrored
+#define r1__r0 _takeover_from_raid1_to_raid0
+#define r1__r0m _takeover_from_raid1_to_raid0_meta
+#define r1__r1 _takeover_from_raid1_to_raid1
+#define r1__r10 _takeover_from_raid1_to_raid10
+#define r1__r45 _takeover_from_raid1_to_raid45
+#define r1__str _takeover_from_raid1_to_striped
+#define r45_lin _takeover_from_raid45_to_linear
+#define r45_mir _takeover_from_raid45_to_mirrored
+#define r45_r0 _takeover_from_raid45_to_raid0
+#define r45_r0m _takeover_from_raid45_to_raid0_meta
+#define r45_r1 _takeover_from_raid45_to_raid1
+#define r45_r54 _takeover_from_raid45_to_raid54
+#define r45_r6 _takeover_from_raid45_to_raid6
+#define r45_str _takeover_from_raid45_to_striped
+#define r6__r0 _takeover_from_raid6_to_raid0
+#define r6__r0m _takeover_from_raid6_to_raid0_meta
+#define r6__r45 _takeover_from_raid6_to_raid45
+#define r6__str _takeover_from_raid6_to_striped
+#define str_r0 _takeover_from_striped_to_raid0
+#define str_r01 _takeover_from_striped_to_raid01
+#define str_r0m _takeover_from_striped_to_raid0_meta
+#define str_r10 _takeover_from_striped_to_raid10
+#define str_r45 _takeover_from_striped_to_raid45
+#define str_r6 _takeover_from_striped_to_raid6
+
+static uint64_t _segtype_index[] = {
+ 1, /* linear */
+ 1, /* striped */
+ SEG_MIRROR,
+ SEG_RAID0,
+ // SEG_RAID0_META,
+ SEG_RAID1,
+ SEG_RAID4 | SEG_RAID5_LS | SEG_RAID5_LA | SEG_RAID5_LS | SEG_RAID5_RS | SEG_RAID5_RA | SEG_RAID5_N,
+ SEG_RAID6_LS_6 | SEG_RAID6_LA_6 | SEG_RAID6_RS_6 | SEG_RAID6_RA_6 | SEG_RAID6_NC | SEG_RAID6_NR | SEG_RAID6_ZR | SEG_RAID6_N_6,
+ 0, // SEG_RAID10_NEAR | SEG_RAID10_FAR | SEG_RAID10_OFFSET,
+ 0, // SEG_RAID01,
+ 0
+};
+
+/*
+ * Matrix of takeover functions.
+ * Row corresponds to original segment type.
+ * Column corresponds to new segment type.
+ * N represents a combination that has no effect (no-op).
+ * X represents a combination that is unsupported.
+ */
+static takeover_fn_t _takeover_fns[][11] = {
+ /* from, to -> linear striped mirror raid0 raid0_meta raid1 raid4/5 raid6 raid10 raid01 other*/
+ /* | */
+ /* v */
+ /* linear */ { N , X , X , lin_r0, lin_r0 , lin_r1, lin_r45, X , lin_r10, X , X },
+ /* striped */ { X , N , X , str_r0, str_r0m, lin_r1, str_r45, str_r6, str_r10, str_r01, X },
+ /* mirror */ { X , X , N , mir_r0, mir_r0m, mir_r1, mir_r45, X , mir_r10, X , X },
+ /* raid0 */ { r0__lin, r0__str, r0__mir, N , r0__r0m, r0__r1, r0__r45, r0__r6, r0__r10, X , X },
+ /* raid0_meta */ // { r0m_lin, r0m_str, r0m_mir, r0m_r0, N , r0m_r1, r0m_r45, r0m_r6, r0m_r10, X , X },
+ /* raid1 */ { r1__lin, r1__str, r1__mir, r1__r0, r1__r0m, r1__r1, r1__r45, X , r1__r10, X , X },
+ /* raid4/5 */ { r45_lin, r45_str, r45_mir, r45_r0, r45_r0m, r45_r1, r45_r54, r45_r6, X , X , X },
+ /* raid6 */ { X , r6__str, X , r6__r0, r6__r0m, X , r6__r45, X , X , X , X },
+ /* raid10 */ // { r10_lin, r10_str, r10_mir, r10_r0, r10_r0m, r10_r1, X , X , r10_r10, r10_r01, X },
+ /* raid01 */ // { X , r01_str, X , X , X , X , X , X , r01_r10, r01_r01, X },
+ /* other */ { X , X , X , X , X , X , X , X , X , X , X },
+};
+#undef X
+#undef N
diff --git a/tools/lvconvert.c b/tools/lvconvert.c
index f99291a..65143a1 100644
--- a/tools/lvconvert.c
+++ b/tools/lvconvert.c
@@ -1845,13 +1845,16 @@ static int _lvconvert_raid(struct logical_volume *lv, struct lvconvert_params *l
return lv_raid_change_image_count(lv, image_count, lp->pvh);
if ((seg_is_linear(seg) || seg_is_striped(seg) || seg_is_mirrored(seg) || lv_is_raid(lv)) &&
- ((lp->type_str && lp->type_str[0]) || image_count)) {
+ (lp->type_str && lp->type_str[0])) {
if (segtype_is_any_raid0(lp->segtype) &&
!(lp->target_attr & RAID_FEATURE_RAID0)) {
log_error("RAID module does not support RAID0.");
return 0;
}
- return lv_raid_convert(lv, lp->segtype, lp->yes, lp->force, image_count, lp->stripes, lp->stripe_size, lp->pvh);
+ if (!lv_raid_convert(lv, lp->segtype, lp->yes, lp->force, lp->stripes, lp->stripe_size, lp->pvh))
+ return_0;
+ log_print_unless_silent("Logical volume %s successfully converted", display_lvname(lv));
+ return 1;
}
if (lp->replace)
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=6d0c49df5b466e3d…
Commit: 6d0c49df5b466e3d5f842272d76452fd2b9e5dec
Parent: 0000000000000000000000000000000000000000
Author: Alasdair G Kergon <agk(a)redhat.com>
AuthorDate: 2016-06-25 19:35 +0000
Committer: Alasdair G Kergon <agk(a)redhat.com>
CommitterDate: 2016-06-25 19:35 +0000
annotated tag: v2_02_158 has been created
at 6d0c49df5b466e3d5f842272d76452fd2b9e5dec (tag)
tagging 887f071b2545bb2b60e13de854898ab71a6b0ff5 (commit)
replaces v2_02_157
Release 2.02.158.
An interim development release incorporating major extensions to the reporting
code (including a json facility). The interface changes are not yet frozen.
The vgimportclone script is also replaced with a new built-in implementation.
133 files changed, 4796 insertions(+), 1818 deletions(-)
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v2.0.14 (GNU/Linux)
iEYEABECAAYFAldu3m8ACgkQIoGRwVZ+LBcy0gCg2xMhF+rYQSYsuztV/w3u6W3E
pP8An1UtPzdIRLbj3hmFBFFS97lV2aAl
=zD0Y
-----END PGP SIGNATURE-----
Alasdair G Kergon (7):
post-release
tools: Use arg_is_set instead of arg_count.
lvconvert: Refactor argument handling code.
lvconvert: Fix --stripes handling.
Revert "locking: trace errors from dir creation"
doc: Resync kernel docs.
pre-release
David Teigland (9):
lvmlockd: fix dropping PVs in rescanning VG
vgreduce: fix location of lvmlockd global lock
vgscan: fix process_each args
vgcfgrestore: use lvmetad disabled state
lvmetad: process new connections after shutdown signal
lvmlockd: always try to connect to lvmetad
vgcfgrestore: check for missing device
vgcfgrestore: rescan to reenable lvmetad on error path
vgimportclone: add native command
Peter Rajnoha (55):
libdm: report: introduce dm_report_group
libdm: report: implement DM_REPORT_GROUP_SINGLE for a group containing single report only
libdm: report: implement DM_REPORT_GROUP_BASIC for extended report output
libdm: report: implement DM_REPORT_GROUP_JSON for JSON report output
report: add CMDLOG report type
conf: add log/command_log_{sort,cols} config settings
toollib: add report_format_init fn to create report group and to create/add log report handle
conf: add report/output_format config setting
conf: add log/report_command_log config setting
report: separate common report and per-report args
toollib: add report_group and log_rh to processing_handle and initialize cmd processing log report
toollib: add 'parent' field to processing_handle; init report format only if there's no parent
report: add current report to existing group
commands: recognize --reportformat option for pvs,vgs,lvs and devtypes command
commands: recognize --reportformat option for other commands
commands: report: add lvm fullreport command
conf: add report/{vgs,pvs,lvs,pvsegs,segs}_{cols,sort}_full config settings
args: add priorities for grouping args
args: add --configreport arg
report: add _get_report_idx_from_name and _should_process_report_idx helper fns
report: recognize list of fields to report (-o|--options) for each subreport
report: recognize list of keys to sort report by (-O|--sort) for each subreport; make -O|--sort groupable
report: recognize selection (-S|--select) for each subreport; make -S|--select groupable
report: check report type and options used for full report's subreports
toollib: make it possible to also process internal VGs, add 'include_internal' switch to process_each_vg fn
log: log warnings and errors via report if set; add log_set_report* fns
report: add report_current_object_cmdlog fn as a shortcut for reporting current object's log item
log: also pass log_print through report and add log_print_bypass_report for use in libdm-report for direct print without report
libdm: report: remember special field to display selection status in struct row's field_sel_status variable
refactor: move field width calculation and sort preparation from _do_report_object to dm_report_output
libdm: report: add DM_REPORT_OUTPUT_MULTIPLE_TIMES report flag to keep report data even after output is done
libdm: report: add dm_report_set_selection
report: add 'multiple_output' arg to report_init
log: annotate processing code with log_set_report_{context,object_type,id_and_name}
log: annotate processing code with report_current_object_cmdlog
refactor: move 'interactive' field from struct command_line to struct cmd_context as 'is_interactive' switch
tools: add 'lvm lastlog' command for interactive query and display of last command's log
log: use separate 'orphan' report object type for orphan VGs
conf: add log/command_log_selection config setting
libdm: select: recognize special selection string 'all' as an alias for blank selection string
report: use report type description for report's name if using DM_REPORT_GROUP_BASIC output format
report: add --logonly arg to report only log for a command
conf: regenerate profile templates
commands: add --configreport arg for all relevant commands
report: compare --configreport value with basic report type
log: add 'label' log report object type; annotate process_each_label with log_set_report_object_{type, id_and_name} and report_log_ret_code
cleanup: log: use hex numbers instead of decimal for _LOG_*
conf: add more comments for new settings related to output format and log report
filters: add comments about internal filter position in filter chain
log: move original print_log code to _vprint_log and make print_log a wrapper over _vprint_log
libdm: log: remove log_print_bypass_report calls and register new print_log_libdm for libdm during lvm initialization instead
commands: fix typo in arg assignment
commands: help: add missing --reportformat references
man: document --configreport, --logonly, --reportformat
man: lvs: move doc about --all so it's ordered alphabetically in the man page
Zdenek Kabelac (26):
activation: switch to warning
activation: _lv_active returns 0 on error
monitoring: preserve monitoring status during update
locking: trace errors from dir creation
lvresize: move and extend resizefs ignoring check
lvresize: inform about ignored args with --use-polices
lvresize: drop extra sigint handling
cleanup: code lines reodered
cleanup: add dots to some messages
cleanup: use display_lvname
lvresize: update lvresize_params struct
lvresize: check pvh list is vg->pvs
lvresize: pass only needed params to _fsadm_cmd
lvresize: do not pass struct cmd
lvresize: support more resized LVs
lvresize: return 0/1
cleanup: remove unused sizearg variable
cleanup: remove unused code
cleanup: drop setting lv_name
tests: aux prepare_thin_metadata
lvresize: fixes for recent commit
lvresize: let pass even protected names like _tmeta
cleanup: type cleanup
tests: smaller number of devs created to fill metadata
tests: update test for modified output
cleanup: clean warns from older gcc
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=ff3c4ed1c0e2e554…
Commit: ff3c4ed1c0e2e554e9fb5f9b7ff20fdf5a835852
Parent: a7c45ddc59449fa8b1823bcab31e3fbb64fed97c
Author: David Teigland <teigland(a)redhat.com>
AuthorDate: Wed Jun 8 16:02:45 2016 -0500
Committer: Alasdair G Kergon <agk(a)redhat.com>
CommitterDate: Tue Jun 28 02:30:36 2016 +0100
lvmetad: two phase vg_remove
Apply the same idea as vg_update.
Before doing the VG remove on disk, invalidate
the VG in lvmetad. After the VG is removed,
remove the VG in lvmetad. If the command fails
after removing the VG on disk, but before removing
the VG metadata from lvmetad, then a subsequent
command will see the INVALID flag and not use the
stale metadata from lvmetad.
---
lib/cache/lvmetad.c | 36 ++++++++++++++++++++++++++++++++----
lib/cache/lvmetad.h | 6 ++++--
lib/metadata/metadata.c | 8 ++++++--
3 files changed, 42 insertions(+), 8 deletions(-)
diff --git a/lib/cache/lvmetad.c b/lib/cache/lvmetad.c
index 784a529..94059dd 100644
--- a/lib/cache/lvmetad.c
+++ b/lib/cache/lvmetad.c
@@ -648,10 +648,9 @@ static int _lvmetad_handle_reply(daemon_reply reply, const char *id, const char
action = "set VG info";
else if (!strcmp(id, "vg_update"))
action = "update VG";
- else if (!strcmp(id, "vg_remove")) {
+ else if (!strcmp(id, "vg_remove"))
action = "remove VG";
- action_modifies = 1;
- } else if (!strcmp(id, "pv_found")) {
+ else if (!strcmp(id, "pv_found")) {
action = "update PV";
action_modifies = 1;
} else if (!strcmp(id, "pv_gone")) {
@@ -1272,7 +1271,36 @@ int lvmetad_vg_update_finish(struct volume_group *vg)
return 1;
}
-int lvmetad_vg_remove(struct volume_group *vg)
+int lvmetad_vg_remove_pending(struct volume_group *vg)
+{
+ char uuid[64] __attribute__((aligned(8)));
+ daemon_reply reply;
+
+ if (!lvmetad_used() || test_mode())
+ return 1; /* fake it */
+
+ if (!id_write_format(&vg->id, uuid, sizeof(uuid)))
+ return_0;
+
+ /* Sending version/seqno 0 in set_vg_info will set the INVALID flag. */
+
+ log_debug_lvmetad("Sending lvmetad pending remove VG %s", vg->name);
+ reply = _lvmetad_send(vg->cmd, "set_vg_info",
+ "name = %s", vg->name,
+ "uuid = %s", uuid,
+ "version = %d", 0,
+ NULL);
+
+ if (!_lvmetad_handle_reply(reply, "set_vg_info", vg->name, NULL)) {
+ daemon_reply_destroy(reply);
+ return_0;
+ }
+
+ daemon_reply_destroy(reply);
+ return 1;
+}
+
+int lvmetad_vg_remove_finish(struct volume_group *vg)
{
char uuid[64];
daemon_reply reply;
diff --git a/lib/cache/lvmetad.h b/lib/cache/lvmetad.h
index 9ee4e2d..d47ce41 100644
--- a/lib/cache/lvmetad.h
+++ b/lib/cache/lvmetad.h
@@ -86,7 +86,8 @@ int lvmetad_vg_update_finish(struct volume_group *vg);
* only needed during vgremove, which does not wipe PV labels and therefore
* cannot mark the PVs as gone.
*/
-int lvmetad_vg_remove(struct volume_group *vg);
+int lvmetad_vg_remove_pending(struct volume_group *vg);
+int lvmetad_vg_remove_finish(struct volume_group *vg);
/*
* Notify lvmetad that a PV has been found. It is not an error if the PV is
@@ -174,7 +175,8 @@ void lvmetad_clear_disabled(struct cmd_context *cmd);
# define lvmetad_vg_update(vg) (1)
# define lvmetad_vg_update_pending(vg) (1)
# define lvmetad_vg_update_finish(vg) (1)
-# define lvmetad_vg_remove(vg) (1)
+# define lvmetad_vg_remove_pending(vg) (1)
+# define lvmetad_vg_remove_finish(vg) (1)
# define lvmetad_pv_found(cmd, pvid, dev, fmt, label_sector, vg, found_vgnames, changed_vgnames) (1)
# define lvmetad_pv_gone(devno, pv_name) (1)
# define lvmetad_pv_gone_by_dev(dev) (1)
diff --git a/lib/metadata/metadata.c b/lib/metadata/metadata.c
index e100bc6..d8bb726 100644
--- a/lib/metadata/metadata.c
+++ b/lib/metadata/metadata.c
@@ -568,6 +568,11 @@ int vg_remove_direct(struct volume_group *vg)
struct pv_list *pvl;
int ret = 1;
+ if (!lvmetad_vg_remove_pending(vg)) {
+ log_error("Failed to update lvmetad for pending remove.");
+ return 0;
+ }
+
if (!vg_remove_mdas(vg)) {
log_error("vg_remove_mdas %s failed", vg->name);
return 0;
@@ -599,8 +604,7 @@ int vg_remove_direct(struct volume_group *vg)
}
}
- /* FIXME Handle partial failures from above. */
- if (!lvmetad_vg_remove(vg))
+ if (!lvmetad_vg_remove_finish(vg))
stack;
lockd_vg_update(vg);
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=a7c45ddc59449fa8…
Commit: a7c45ddc59449fa8b1823bcab31e3fbb64fed97c
Parent: cc3e7c7c31de8d69d9f1eb610181584482ee90a3
Author: David Teigland <teigland(a)redhat.com>
AuthorDate: Wed Jun 8 14:42:03 2016 -0500
Committer: Alasdair G Kergon <agk(a)redhat.com>
CommitterDate: Tue Jun 28 02:30:31 2016 +0100
lvmetad: two phase vg_update
Previously, a command sent lvmetad new VG metadata in vg_commit().
In vg_commit(), devices are suspended, so any memory allocation
done by the command while sending to lvmetad, or by lvmetad while
updating its cache could deadlock if memory reclaim was triggered.
Now lvmetad is updated in unlock_vg(), after devices are resumed.
The new method for updating VG metadata in lvmetad is in two phases:
1. In vg_write(), before devices are suspended, the command sends
lvmetad a short message ("set_vg_info") telling it what the new
VG seqno will be. lvmetad sees that the seqno is newer than
the seqno of its cached VG, so it sets the INVALID flag for the
cached VG. If sending the message to lvmetad fails, the command
fails before the metadata is committed and the change is not made.
If sending the message succeeds, vg_commit() is called.
2. In unlock_vg(), after devices are resumed, the command sends
lvmetad the standard vg_update message with the new metadata.
lvmetad sees that the seqno in the new metadata matches the
seqno it saved from set_vg_info, and knows it has the latest
copy, so it clears the INVALID flag for the cached VG.
If a command fails between 1 and 2 (after committing the VG on disk,
but before sending lvmetad the new metadata), the cached VG retains
the INVALID flag in lvmetad. A subsequent command will read the
cached VG from lvmetad, see the INVALID flag, ignore the cached
copy, read the VG from disk instead, update the lvmetad copy
with the latest copy from disk, (this clears the INVALID flag
in lvmetad), and use the correct VG metadata for the command.
(This INVALID mechanism already existed for use by lvmlockd.)
---
daemons/lvmetad/lvmetad-core.c | 9 ++-
lib/cache/lvmetad.c | 113 ++++++++++++++++++++++++++++++++-------
lib/cache/lvmetad.h | 5 ++-
lib/format_text/archiver.c | 1 +
lib/locking/locking.h | 6 ++-
lib/metadata/metadata.c | 37 +++++++++----
lib/metadata/pv_manip.c | 2 +-
lib/metadata/replicator_manip.c | 1 +
lib/metadata/vg.c | 1 +
lib/metadata/vg.h | 1 +
liblvm/lvm_pv.c | 5 +-
liblvm/lvm_vg.c | 7 ++-
tools/pvchange.c | 2 +-
tools/pvcreate.c | 2 +-
tools/pvdisplay.c | 2 +-
tools/pvremove.c | 2 +-
tools/pvscan.c | 4 +-
tools/reporter.c | 2 +-
tools/toollib.c | 10 ++--
tools/vgcfgrestore.c | 10 ++--
tools/vgcreate.c | 10 ++--
tools/vgextend.c | 2 +-
tools/vgimportclone.c | 4 +-
tools/vgrename.c | 6 +-
tools/vgscan.c | 2 +-
tools/vgsplit.c | 6 ++
26 files changed, 181 insertions(+), 71 deletions(-)
diff --git a/daemons/lvmetad/lvmetad-core.c b/daemons/lvmetad/lvmetad-core.c
index aab569f..1ec9e3b 100644
--- a/daemons/lvmetad/lvmetad-core.c
+++ b/daemons/lvmetad/lvmetad-core.c
@@ -2464,10 +2464,10 @@ static response set_vg_info(lvmetad_state *s, request r)
{
struct dm_config_tree *vg;
struct vg_info *info;
- const char *name;
- const char *uuid;
+ const char *name = NULL;
+ const char *uuid = NULL;
const int64_t new_version = daemon_request_int(r, "version", -1);
- int64_t cache_version;
+ int64_t cache_version = -1;
if (new_version == -1)
goto out;
@@ -2500,6 +2500,9 @@ vers:
if (cache_version != -1 && new_version != -1 && cache_version >= new_version)
goto out;
inval:
+ DEBUGLOG(s, "set info VG name %s uuid %s cache_version %d new_version %d",
+ name ?: "none", uuid ?: "none", (int)cache_version, (int)new_version);
+
info = dm_hash_lookup(s->vgid_to_info, uuid);
if (!info) {
info = malloc(sizeof(struct vg_info));
diff --git a/lib/cache/lvmetad.c b/lib/cache/lvmetad.c
index a0a17ac..784a529 100644
--- a/lib/cache/lvmetad.c
+++ b/lib/cache/lvmetad.c
@@ -644,10 +644,11 @@ static int _lvmetad_handle_reply(daemon_reply reply, const char *id, const char
action = "clear info about all PVs";
else if (!strcmp(id, "vg_clear_outdated_pvs"))
action = "clear the list of outdated PVs";
- else if (!strcmp(id, "vg_update")) {
+ else if (!strcmp(id, "set_vg_info"))
+ action = "set VG info";
+ else if (!strcmp(id, "vg_update"))
action = "update VG";
- action_modifies = 1;
- } else if (!strcmp(id, "vg_remove")) {
+ else if (!strcmp(id, "vg_remove")) {
action = "remove VG";
action_modifies = 1;
} else if (!strcmp(id, "pv_found")) {
@@ -1073,7 +1074,13 @@ struct volume_group *lvmetad_vg_lookup(struct cmd_context *cmd, const char *vgna
log_debug_lvmetad("Rescan VG %s because no lvmlockd lock is held", vgname);
rescan = 1;
} else if (dm_config_find_node(reply.cft->root, "vg_invalid")) {
- log_debug_lvmetad("Rescan VG %s because lvmetad returned invalid", vgname);
+ if (!is_lockd_type(vg->lock_type)) {
+ /* Can happen if a previous command failed/crashed without updating lvmetad. */
+ log_warn("WARNING: Reading VG %s from disk because lvmetad metadata is invalid.", vgname);
+ } else {
+ /* This is normal when the VG was modified by another host. */
+ log_debug_lvmetad("Rescan VG %s because lvmetad returned invalid", vgname);
+ }
rescan = 1;
}
@@ -1137,32 +1144,98 @@ static int _fixup_ignored(struct metadata_area *mda, void *baton) {
return 1;
}
-int lvmetad_vg_update(struct volume_group *vg)
+/*
+ * After the VG is written to disk, but before it's committed,
+ * lvmetad is told the new seqno. lvmetad sets the INVALID
+ * flag on the cached VG and saves the new seqno.
+ *
+ * After the VG is committed on disk, the command sends the
+ * new VG metadata, containing the new seqno. lvmetad sees
+ * that it has the updated metadata and clears the INVALID
+ * flag on the cached VG.
+ *
+ * If the command fails after committing the metadata on disk
+ * but before sending the new metadata to lvmetad, then the
+ * next command that asks lvmetad for the metadata will get
+ * back the INVALID flag. That command will then read the
+ * VG metadata from disk to use, and will send the latest
+ * metadata from disk to lvmetad which will clear the
+ * INVALID flag.
+ */
+
+int lvmetad_vg_update_pending(struct volume_group *vg)
{
+ char uuid[64] __attribute__((aligned(8)));
+ daemon_reply reply;
+
+ if (!lvmetad_used() || test_mode())
+ return 1; /* fake it */
+
+ if (!id_write_format(&vg->id, uuid, sizeof(uuid)))
+ return_0;
+
+ log_debug_lvmetad("Sending lvmetad pending VG %s (seqno %" PRIu32 ")", vg->name, vg->seqno);
+ reply = _lvmetad_send(vg->cmd, "set_vg_info",
+ "name = %s", vg->name,
+ "uuid = %s", uuid,
+ "version = %"PRId64, (int64_t)vg->seqno,
+ NULL);
+
+ if (!_lvmetad_handle_reply(reply, "set_vg_info", vg->name, NULL)) {
+ daemon_reply_destroy(reply);
+ return_0;
+ }
+
+ vg->lvmetad_update_pending = 1;
+
+ daemon_reply_destroy(reply);
+ return 1;
+}
+
+int lvmetad_vg_update_finish(struct volume_group *vg)
+{
+ char uuid[64] __attribute__((aligned(8)));
daemon_reply reply;
struct dm_hash_node *n;
struct metadata_area *mda;
char mda_id[128], *num;
+ struct dm_config_tree *vgmeta;
struct pv_list *pvl;
struct lvmcache_info *info;
struct _fixup_baton baton;
- if (!vg)
- return 0;
+ if (!vg->lvmetad_update_pending)
+ return 1;
+
+ if (!(vg->fid->fmt->features & FMT_PRECOMMIT))
+ return 1;
if (!lvmetad_used() || test_mode())
return 1; /* fake it */
- if (!vg->cft_precommitted) {
- log_error(INTERNAL_ERROR "VG update without precommited");
+ if (!id_write_format(&vg->id, uuid, sizeof(uuid)))
+ return_0;
+
+ if (!(vgmeta = export_vg_to_config_tree(vg))) {
+ log_error("Failed to export VG to config tree.");
return 0;
}
- log_debug_lvmetad("Sending lvmetad updated metadata for VG %s (seqno %" PRIu32 ")", vg->name, vg->seqno);
- reply = _lvmetad_send(vg->cmd, "vg_update", "vgname = %s", vg->name,
- "metadata = %t", vg->cft_precommitted, NULL);
+ log_debug_lvmetad("Sending lvmetad updated VG %s (seqno %" PRIu32 ")", vg->name, vg->seqno);
+ reply = _lvmetad_send(vg->cmd, "vg_update",
+ "vgname = %s", vg->name,
+ "metadata = %t", vgmeta,
+ NULL);
+
+ dm_config_destroy(vgmeta);
if (!_lvmetad_handle_reply(reply, "vg_update", vg->name, NULL)) {
+ /*
+ * In this failure case, the VG cached in lvmetad remains in
+ * the INVALID state (from lvmetad_vg_update_pending).
+ * A subsequent command will see INVALID, ignore the cached
+ * copy, read the VG from disk, and update the cached copy.
+ */
daemon_reply_destroy(reply);
return 0;
}
@@ -1195,6 +1268,7 @@ int lvmetad_vg_update(struct volume_group *vg)
return 0;
}
+ vg->lvmetad_update_pending = 0;
return 1;
}
@@ -1207,6 +1281,8 @@ int lvmetad_vg_remove(struct volume_group *vg)
if (!lvmetad_used() || test_mode())
return 1; /* just fake it */
+ vg->lvmetad_update_pending = 0;
+
if (!id_write_format(&vg->id, uuid, sizeof(uuid)))
return_0;
@@ -1887,10 +1963,6 @@ scan_more:
/*
* Update lvmetad with the newly read version of the VG.
- * The "precommitted" name is a misnomer in this case,
- * but that is the field which lvmetad_vg_update() uses
- * to send the metadata cft to lvmetad.
- *
* When the seqno is unchanged the cached VG can be left.
*/
if (save_seqno != vg->seqno) {
@@ -1905,10 +1977,13 @@ scan_more:
log_debug_lvmetad("Rescan VG %s updating lvmetad from seqno %u to seqno %u.",
vg->name, vg->seqno, save_seqno);
- vg_ret->cft_precommitted = vgmeta_ret;
- if (!lvmetad_vg_update(vg_ret))
+ /*
+ * If this vg_update fails the cached metadata in
+ * lvmetad will remain invalid.
+ */
+ vg_ret->lvmetad_update_pending = 1;
+ if (!lvmetad_vg_update_finish(vg_ret))
log_error("Failed to update lvmetad with new VG meta");
- vg_ret->cft_precommitted = NULL;
}
dm_config_destroy(vgmeta_ret);
}
diff --git a/lib/cache/lvmetad.h b/lib/cache/lvmetad.h
index 3bb2b7c..9ee4e2d 100644
--- a/lib/cache/lvmetad.h
+++ b/lib/cache/lvmetad.h
@@ -78,7 +78,8 @@ void lvmetad_release_token(void);
* lvmetad_vg_commit. The request is validated immediately and lvmetad_vg_commit
* only constitutes a pointer update.
*/
-int lvmetad_vg_update(struct volume_group *vg);
+int lvmetad_vg_update_pending(struct volume_group *vg);
+int lvmetad_vg_update_finish(struct volume_group *vg);
/*
* Inform lvmetad that a VG has been removed. This is not entirely safe, but is
@@ -171,6 +172,8 @@ void lvmetad_clear_disabled(struct cmd_context *cmd);
# define lvmetad_set_token(a) do { } while (0)
# define lvmetad_release_token() do { } while (0)
# define lvmetad_vg_update(vg) (1)
+# define lvmetad_vg_update_pending(vg) (1)
+# define lvmetad_vg_update_finish(vg) (1)
# define lvmetad_vg_remove(vg) (1)
# define lvmetad_pv_found(cmd, pvid, dev, fmt, label_sector, vg, found_vgnames, changed_vgnames) (1)
# define lvmetad_pv_gone(devno, pv_name) (1)
diff --git a/lib/format_text/archiver.c b/lib/format_text/archiver.c
index 92799e4..2acd8f5 100644
--- a/lib/format_text/archiver.c
+++ b/lib/format_text/archiver.c
@@ -22,6 +22,7 @@
#include "memlock.h"
#include "toolcontext.h"
#include "locking.h"
+#include "lvmetad-client.h"
#include <unistd.h>
diff --git a/lib/locking/locking.h b/lib/locking/locking.h
index ceeb73c..18bce2d 100644
--- a/lib/locking/locking.h
+++ b/lib/locking/locking.h
@@ -198,8 +198,10 @@ int check_lvm1_vg_inactive(struct cmd_context *cmd, const char *vgname);
rr; \
})
-#define unlock_vg(cmd, vol) \
+#define unlock_vg(cmd, vg, vol) \
do { \
+ if (vg && !lvmetad_vg_update_finish(vg)) \
+ stack; \
if (is_real_vg(vol) && !sync_dev_names(cmd)) \
stack; \
if (!lock_vol(cmd, vol, LCK_VG_UNLOCK, NULL)) \
@@ -207,7 +209,7 @@ int check_lvm1_vg_inactive(struct cmd_context *cmd, const char *vgname);
} while (0)
#define unlock_and_release_vg(cmd, vg, vol) \
do { \
- unlock_vg(cmd, vol); \
+ unlock_vg(cmd, vg, vol); \
release_vg(vg); \
} while (0)
diff --git a/lib/metadata/metadata.c b/lib/metadata/metadata.c
index e55463b..e100bc6 100644
--- a/lib/metadata/metadata.c
+++ b/lib/metadata/metadata.c
@@ -629,7 +629,7 @@ int vg_remove(struct volume_group *vg)
ret = vg_remove_direct(vg);
- unlock_vg(vg->cmd, VG_ORPHANS);
+ unlock_vg(vg->cmd, vg, VG_ORPHANS);
return ret;
}
@@ -3548,6 +3548,17 @@ int vg_write(struct volume_group *vg)
lockd_vg_update(vg);
+ /*
+ * This tells lvmetad the new seqno it should expect to receive
+ * the metadata for after the commit. The cached VG will be
+ * invalid in lvmetad until this command sends the new metadata
+ * after it's committed.
+ */
+ if (!lvmetad_vg_update_pending(vg)) {
+ log_error("Failed to prepare new VG metadata in lvmetad cache.");
+ return 0;
+ }
+
return 1;
}
@@ -3598,10 +3609,6 @@ int vg_commit(struct volume_group *vg)
return cache_updated;
}
- /* Skip if we already did this in vg_write */
- if ((vg->fid->fmt->features & FMT_PRECOMMIT) && !lvmetad_vg_update(vg))
- return_0;
-
cache_updated = _vg_commit_mdas(vg);
set_vg_notify(vg->cmd);
@@ -3641,6 +3648,14 @@ void vg_revert(struct volume_group *vg)
struct metadata_area *mda;
struct lv_list *lvl;
+ /*
+ * This will leave the cached copy in lvmetad INVALID (from
+ * lvmetad_vg_update_pending) and means the VG will be reread from disk
+ * to update the lvmetad copy, which is what we want to ensure that the
+ * cached copy is correct.
+ */
+ vg->lvmetad_update_pending = 0;
+
dm_list_iterate_items(lvl, &vg->lvs) {
if (lvl->lv->new_lock_args) {
lockd_free_lv(vg->cmd, vg, lvl->lv->name, &lvl->lv->lvid.id[1], lvl->lv->lock_args);
@@ -5465,7 +5480,7 @@ static struct volume_group *_recover_vg(struct cmd_context *cmd,
int consistent = 1;
struct volume_group *vg;
- unlock_vg(cmd, vg_name);
+ unlock_vg(cmd, NULL, vg_name);
dev_close_all();
@@ -5473,13 +5488,13 @@ static struct volume_group *_recover_vg(struct cmd_context *cmd,
return_NULL;
if (!(vg = vg_read_internal(cmd, vg_name, vgid, WARN_PV_READ, &consistent))) {
- unlock_vg(cmd, vg_name);
+ unlock_vg(cmd, NULL, vg_name);
return_NULL;
}
if (!consistent) {
release_vg(vg);
- unlock_vg(cmd, vg_name);
+ unlock_vg(cmd, NULL, vg_name);
return_NULL;
}
@@ -5825,7 +5840,7 @@ static struct volume_group *_vg_lock_and_read(struct cmd_context *cmd, const cha
bad:
if (!already_locked)
- unlock_vg(cmd, vg_name);
+ unlock_vg(cmd, vg, vg_name);
bad_no_unlock:
return _vg_make_handle(cmd, vg, failure);
@@ -5926,7 +5941,7 @@ uint32_t vg_lock_newname(struct cmd_context *cmd, const char *vgname)
* FIXME: Disallow calling this function if
* critical_section() is true.
*/
- unlock_vg(cmd, vgname);
+ unlock_vg(cmd, NULL, vgname);
return FAILED_LOCKING;
}
lvmcache_force_next_label_scan();
@@ -5939,7 +5954,7 @@ uint32_t vg_lock_newname(struct cmd_context *cmd, const char *vgname)
}
/* Found vgname so cannot reserve. */
- unlock_vg(cmd, vgname);
+ unlock_vg(cmd, NULL, vgname);
return FAILED_EXIST;
}
diff --git a/lib/metadata/pv_manip.c b/lib/metadata/pv_manip.c
index 567cede..5689a11 100644
--- a/lib/metadata/pv_manip.c
+++ b/lib/metadata/pv_manip.c
@@ -854,7 +854,7 @@ int pvremove_many(struct cmd_context *cmd, struct dm_list *pv_names,
}
out:
- unlock_vg(cmd, VG_ORPHANS);
+ unlock_vg(cmd, NULL, VG_ORPHANS);
if (pvslist)
dm_list_iterate_items(pvl, pvslist)
diff --git a/lib/metadata/replicator_manip.c b/lib/metadata/replicator_manip.c
index 5197b63..0501713 100644
--- a/lib/metadata/replicator_manip.c
+++ b/lib/metadata/replicator_manip.c
@@ -17,6 +17,7 @@
#include "metadata.h"
#include "segtype.h"
#include "toolcontext.h"
+#include "lvmetad.h"
/* Add lv as replicator_dev device */
int replicator_dev_add_rimage(struct replicator_device *rdev,
diff --git a/lib/metadata/vg.c b/lib/metadata/vg.c
index 7ac1a2c..01dcad9 100644
--- a/lib/metadata/vg.c
+++ b/lib/metadata/vg.c
@@ -20,6 +20,7 @@
#include "toolcontext.h"
#include "lvmcache.h"
#include "archiver.h"
+#include "lvmetad.h"
struct volume_group *alloc_vg(const char *pool_name, struct cmd_context *cmd,
const char *vg_name)
diff --git a/lib/metadata/vg.h b/lib/metadata/vg.h
index 069cdc8..4ce7151 100644
--- a/lib/metadata/vg.h
+++ b/lib/metadata/vg.h
@@ -51,6 +51,7 @@ struct volume_group {
uint32_t cmd_missing_vgs;/* Flag marks missing VG */
uint32_t seqno; /* Metadata sequence number */
unsigned skip_validate_lock_args : 1;
+ unsigned lvmetad_update_pending: 1;
/*
* The parsed committed (on-disk) copy of this VG; is NULL if this VG is committed
diff --git a/liblvm/lvm_pv.c b/liblvm/lvm_pv.c
index 4c40b8b..3dd8433 100644
--- a/liblvm/lvm_pv.c
+++ b/liblvm/lvm_pv.c
@@ -22,6 +22,7 @@
#include "locking.h"
#include "toolcontext.h"
#include "lvm_misc.h"
+#include "lvmetad.h"
struct lvm_pv_create_params
{
@@ -205,7 +206,7 @@ int lvm_list_pvs_free(struct dm_list *pvlist)
dm_list_iterate_items(pvl, &to_delete->pvslist)
free_pv_fid(pvl->pv);
- unlock_vg(to_delete->cmd, VG_GLOBAL);
+ unlock_vg(to_delete->cmd, NULL, VG_GLOBAL);
to_delete->magic = 0xA5A5A5A5;
restore_user_env(&e);
@@ -437,7 +438,7 @@ static int _pv_create(pv_create_params_t params)
if (!(pvcreate_vol(cmd, params->pv_name, ¶ms->pv_p, 1)))
rc = -1;
- unlock_vg(cmd, VG_ORPHANS);
+ unlock_vg(cmd, NULL, VG_ORPHANS);
return rc;
}
diff --git a/liblvm/lvm_vg.c b/liblvm/lvm_vg.c
index 8b3fc91..8f83230 100644
--- a/liblvm/lvm_vg.c
+++ b/liblvm/lvm_vg.c
@@ -22,6 +22,7 @@
#include "lvm_misc.h"
#include "lvm2app.h"
#include "display.h"
+#include "lvmetad.h"
int lvm_vg_add_tag(vg_t vg, const char *tag)
{
@@ -84,14 +85,14 @@ static int _lvm_vg_extend(vg_t vg, const char *device)
pvcreate_params_set_defaults(&pp);
if (!vg_extend(vg, 1, &device, &pp)) {
- unlock_vg(vg->cmd, VG_ORPHANS);
+ unlock_vg(vg->cmd, NULL, VG_ORPHANS);
return -1;
}
/*
* FIXME: Either commit to disk, or keep holding VG_ORPHANS and
* release in lvm_vg_close().
*/
- unlock_vg(vg->cmd, VG_ORPHANS);
+ unlock_vg(vg->cmd, NULL, VG_ORPHANS);
return 0;
}
@@ -165,7 +166,7 @@ static int _lvm_vg_write(vg_t vg)
/* FIXME: do pvremove / label_remove()? */
}
dm_list_init(&vg->removed_pvs);
- unlock_vg(vg->cmd, VG_ORPHANS);
+ unlock_vg(vg->cmd, NULL, VG_ORPHANS);
}
return 0;
diff --git a/tools/pvchange.c b/tools/pvchange.c
index e68e181..8c19268 100644
--- a/tools/pvchange.c
+++ b/tools/pvchange.c
@@ -255,7 +255,7 @@ int pvchange(struct cmd_context *cmd, int argc, char **argv)
ret = process_each_pv(cmd, argc, argv, NULL, 0, READ_FOR_UPDATE | READ_ALLOW_EXPORTED, handle, _pvchange_single);
if (!argc)
- unlock_vg(cmd, VG_GLOBAL);
+ unlock_vg(cmd, NULL, VG_GLOBAL);
log_print_unless_silent("%d physical volume%s changed / %d physical volume%s not changed",
params.done, params.done == 1 ? "" : "s",
diff --git a/tools/pvcreate.c b/tools/pvcreate.c
index fe6611f..e69eed4 100644
--- a/tools/pvcreate.c
+++ b/tools/pvcreate.c
@@ -156,7 +156,7 @@ int pvcreate(struct cmd_context *cmd, int argc, char **argv)
ret = ECMD_FAILED;
else {
/* pvcreate_each_device returns with orphans locked */
- unlock_vg(cmd, VG_ORPHANS);
+ unlock_vg(cmd, NULL, VG_ORPHANS);
ret = ECMD_PROCESSED;
}
diff --git a/tools/pvdisplay.c b/tools/pvdisplay.c
index 404e02b..5f033f3 100644
--- a/tools/pvdisplay.c
+++ b/tools/pvdisplay.c
@@ -112,7 +112,7 @@ int pvdisplay(struct cmd_context *cmd, int argc, char **argv)
NULL, _pvdisplay_single);
if (lock_global)
- unlock_vg(cmd, VG_GLOBAL);
+ unlock_vg(cmd, NULL, VG_GLOBAL);
return ret;
}
diff --git a/tools/pvremove.c b/tools/pvremove.c
index e262eb0..28c7b83 100644
--- a/tools/pvremove.c
+++ b/tools/pvremove.c
@@ -58,7 +58,7 @@ int pvremove(struct cmd_context *cmd, int argc, char **argv)
ret = ECMD_FAILED;
else {
/* pvcreate_each_device returns with orphans locked */
- unlock_vg(cmd, VG_ORPHANS);
+ unlock_vg(cmd, NULL, VG_ORPHANS);
ret = ECMD_PROCESSED;
}
diff --git a/tools/pvscan.c b/tools/pvscan.c
index c29401c..f5367e4 100644
--- a/tools/pvscan.c
+++ b/tools/pvscan.c
@@ -536,7 +536,7 @@ out:
if (!sync_local_dev_names(cmd))
stack;
- unlock_vg(cmd, VG_GLOBAL);
+ unlock_vg(cmd, NULL, VG_GLOBAL);
return ret;
}
@@ -654,7 +654,7 @@ int pvscan(struct cmd_context *cmd, int argc, char **argv)
params.new_pvs_found, display_size(cmd, params.size_new));
out:
- unlock_vg(cmd, VG_GLOBAL);
+ unlock_vg(cmd, NULL, VG_GLOBAL);
destroy_processing_handle(cmd, handle);
return ret;
diff --git a/tools/reporter.c b/tools/reporter.c
index 6f8ed8f..ad0a356 100644
--- a/tools/reporter.c
+++ b/tools/reporter.c
@@ -1171,7 +1171,7 @@ static int _do_report(struct cmd_context *cmd, struct processing_handle *handle,
dm_report_output(report_handle);
if (lock_global)
- unlock_vg(cmd, VG_GLOBAL);
+ unlock_vg(cmd, NULL, VG_GLOBAL);
out:
if (report_handle) {
if (report_in_group && !dm_report_group_pop(handle->report_group))
diff --git a/tools/toollib.c b/tools/toollib.c
index 4c24b16..35b687b 100644
--- a/tools/toollib.c
+++ b/tools/toollib.c
@@ -1962,7 +1962,7 @@ static int _process_vgnameid_list(struct cmd_context *cmd, uint32_t read_flags,
}
if (!vg_read_error(vg) && !already_locked)
- unlock_vg(cmd, vg_name);
+ unlock_vg(cmd, vg, vg_name);
endvg:
release_vg(vg);
if (!lockd_vg(cmd, vg_name, "un", 0, &lockd_state))
@@ -2826,7 +2826,7 @@ static int _process_lv_vgnameid_list(struct cmd_context *cmd, uint32_t read_flag
ret_max = ret;
if (!already_locked)
- unlock_vg(cmd, vg_name);
+ unlock_vg(cmd, vg, vg_name);
endvg:
release_vg(vg);
if (!lockd_vg(cmd, vg_name, "un", 0, &lockd_state))
@@ -3501,7 +3501,7 @@ static int _process_pvs_in_vgs(struct cmd_context *cmd, uint32_t read_flags,
ret_max = ret;
if (!skip && !already_locked)
- unlock_vg(cmd, vg->name);
+ unlock_vg(cmd, vg, vg->name);
endvg:
release_vg(vg);
if (!lockd_vg(cmd, vg_name, "un", 0, &lockd_state))
@@ -4654,7 +4654,7 @@ int pvcreate_each_device(struct cmd_context *cmd,
* the questions, reacquire the orphans lock, verify that the PVs were
* not used during the questions, then do the create steps.
*/
- unlock_vg(cmd, VG_ORPHANS);
+ unlock_vg(cmd, NULL, VG_ORPHANS);
/*
* Process prompts that require asking the user. The orphans lock is
@@ -4941,7 +4941,7 @@ do_command:
return 1;
bad:
- unlock_vg(cmd, VG_ORPHANS);
+ unlock_vg(cmd, NULL, VG_ORPHANS);
out:
return 0;
}
diff --git a/tools/vgcfgrestore.c b/tools/vgcfgrestore.c
index 8a60ab3..b5a2add 100644
--- a/tools/vgcfgrestore.c
+++ b/tools/vgcfgrestore.c
@@ -70,7 +70,7 @@ int vgcfgrestore(struct cmd_context *cmd, int argc, char **argv)
if (!lock_vol(cmd, VG_ORPHANS, LCK_VG_WRITE, NULL)) {
log_error("Unable to lock orphans");
- unlock_vg(cmd, vg_name);
+ unlock_vg(cmd, NULL, vg_name);
return ECMD_FAILED;
}
@@ -81,8 +81,8 @@ int vgcfgrestore(struct cmd_context *cmd, int argc, char **argv)
arg_str_value(cmd, file_ARG, ""),
arg_count(cmd, force_long_ARG)) :
backup_restore(cmd, vg_name, arg_count(cmd, force_long_ARG)))) {
- unlock_vg(cmd, VG_ORPHANS);
- unlock_vg(cmd, vg_name);
+ unlock_vg(cmd, NULL, VG_ORPHANS);
+ unlock_vg(cmd, NULL, vg_name);
log_error("Restore failed.");
ret = ECMD_FAILED;
goto rescan;
@@ -91,8 +91,8 @@ int vgcfgrestore(struct cmd_context *cmd, int argc, char **argv)
ret = ECMD_PROCESSED;
log_print_unless_silent("Restored volume group %s", vg_name);
- unlock_vg(cmd, VG_ORPHANS);
- unlock_vg(cmd, vg_name);
+ unlock_vg(cmd, NULL, VG_ORPHANS);
+ unlock_vg(cmd, NULL, vg_name);
rescan:
if (lvmetad_rescan) {
if (!lvmetad_connect(cmd)) {
diff --git a/tools/vgcreate.c b/tools/vgcreate.c
index 14e0d53..1a6a240 100644
--- a/tools/vgcreate.c
+++ b/tools/vgcreate.c
@@ -90,7 +90,7 @@ int vgcreate(struct cmd_context *cmd, int argc, char **argv)
* VG lock to be released, so the lvmcache destroy rule about locks
* seems to be unwarranted here.
*/
- unlock_vg(cmd, vp_new.vg_name);
+ unlock_vg(cmd, NULL, vp_new.vg_name);
if (!(handle = init_processing_handle(cmd, NULL))) {
log_error("Failed to initialize processing handle.");
@@ -181,8 +181,8 @@ int vgcreate(struct cmd_context *cmd, int argc, char **argv)
goto_bad;
}
- unlock_vg(cmd, VG_ORPHANS);
- unlock_vg(cmd, vp_new.vg_name);
+ unlock_vg(cmd, NULL, VG_ORPHANS);
+ unlock_vg(cmd, vg, vp_new.vg_name);
backup(vg);
@@ -222,8 +222,8 @@ out:
return ECMD_PROCESSED;
bad:
- unlock_vg(cmd, vp_new.vg_name);
- unlock_vg(cmd, VG_ORPHANS);
+ unlock_vg(cmd, vg, vp_new.vg_name);
+ unlock_vg(cmd, NULL, VG_ORPHANS);
release_vg(vg);
destroy_processing_handle(cmd, handle);
return ECMD_FAILED;
diff --git a/tools/vgextend.c b/tools/vgextend.c
index 4b2a13e..344dff0 100644
--- a/tools/vgextend.c
+++ b/tools/vgextend.c
@@ -204,6 +204,6 @@ int vgextend(struct cmd_context *cmd, int argc, char **argv)
destroy_processing_handle(cmd, handle);
if (!restoremissing)
- unlock_vg(cmd, VG_ORPHANS);
+ unlock_vg(cmd, NULL, VG_ORPHANS);
return ret;
}
diff --git a/tools/vgimportclone.c b/tools/vgimportclone.c
index 7028fbb..09b3a7c 100644
--- a/tools/vgimportclone.c
+++ b/tools/vgimportclone.c
@@ -333,9 +333,9 @@ retry_name:
ret = process_each_vg(cmd, 0, NULL, vp.old_vgname, NULL, READ_FOR_UPDATE | READ_ALLOW_EXPORTED, 0, handle, _vgimportclone_vg_single);
- unlock_vg(cmd, vp.new_vgname);
+ unlock_vg(cmd, NULL, vp.new_vgname);
out:
- unlock_vg(cmd, VG_GLOBAL);
+ unlock_vg(cmd, NULL, VG_GLOBAL);
internal_filter_clear();
init_internal_filtering(0);
lvmcache_lock_ordering(1);
diff --git a/tools/vgrename.c b/tools/vgrename.c
index 2006193..293f63c 100644
--- a/tools/vgrename.c
+++ b/tools/vgrename.c
@@ -161,7 +161,7 @@ static int _vgrename_single(struct cmd_context *cmd, const char *vg_name,
if (!backup_remove(cmd, vg_name))
stack;
- unlock_vg(cmd, vp->vg_name_new);
+ unlock_vg(cmd, vg, vp->vg_name_new);
vp->unlock_new_name = 0;
log_print_unless_silent("Volume group \"%s\" successfully renamed to \"%s\"",
@@ -169,7 +169,7 @@ static int _vgrename_single(struct cmd_context *cmd, const char *vg_name,
return 1;
error:
- unlock_vg(cmd, vp->vg_name_new);
+ unlock_vg(cmd, vg, vp->vg_name_new);
vp->unlock_new_name = 0;
lockd_rename_vg_final(cmd, vg, 0);
@@ -250,7 +250,7 @@ int vgrename(struct cmd_context *cmd, int argc, char **argv)
/* Needed if process_each_vg returns error before calling _single. */
if (vp.unlock_new_name)
- unlock_vg(cmd, vg_name_new);
+ unlock_vg(cmd, NULL, vg_name_new);
destroy_processing_handle(cmd, handle);
return ret;
diff --git a/tools/vgscan.c b/tools/vgscan.c
index e09724a..4deab73 100644
--- a/tools/vgscan.c
+++ b/tools/vgscan.c
@@ -125,6 +125,6 @@ int vgscan(struct cmd_context *cmd, int argc, char **argv)
maxret = ret;
}
- unlock_vg(cmd, VG_GLOBAL);
+ unlock_vg(cmd, NULL, VG_GLOBAL);
return maxret;
}
diff --git a/tools/vgsplit.c b/tools/vgsplit.c
index cb6b0ef..6114a72 100644
--- a/tools/vgsplit.c
+++ b/tools/vgsplit.c
@@ -653,6 +653,8 @@ int vgsplit(struct cmd_context *cmd, int argc, char **argv)
if (!vg_write(vg_to) || !vg_commit(vg_to))
goto_bad;
+ lvmetad_vg_update_finish(vg_to);
+
backup(vg_to);
/*
@@ -664,6 +666,8 @@ int vgsplit(struct cmd_context *cmd, int argc, char **argv)
if (!vg_write(vg_from) || !vg_commit(vg_from))
goto_bad;
+ lvmetad_vg_update_finish(vg_from);
+
backup(vg_from);
}
@@ -686,6 +690,8 @@ int vgsplit(struct cmd_context *cmd, int argc, char **argv)
if (!vg_write(vg_to) || !vg_commit(vg_to))
goto_bad;
+ lvmetad_vg_update_finish(vg_to);
+
backup(vg_to);
log_print_unless_silent("%s volume group \"%s\" successfully split from \"%s\"",
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=cc3e7c7c31de8d69…
Commit: cc3e7c7c31de8d69d9f1eb610181584482ee90a3
Parent: 5a327755b4cfe45b35863a2b4177a6b32c17642f
Author: David Teigland <teigland(a)redhat.com>
AuthorDate: Tue Jun 7 16:09:45 2016 -0500
Committer: Alasdair G Kergon <agk(a)redhat.com>
CommitterDate: Tue Jun 28 02:30:25 2016 +0100
lvmetad: remove unused code for other format types
lvmetad is no longer used at all with the lvm1 format,
so the text format is the only one that uses lvmetad.
---
lib/metadata/metadata.c | 7 -------
1 files changed, 0 insertions(+), 7 deletions(-)
diff --git a/lib/metadata/metadata.c b/lib/metadata/metadata.c
index 9b1fd31..e55463b 100644
--- a/lib/metadata/metadata.c
+++ b/lib/metadata/metadata.c
@@ -3546,13 +3546,6 @@ int vg_write(struct volume_group *vg)
if (!_vg_update_vg_precommitted(vg)) /* prepare precommited */
return_0;
- /*
- * If precommit is not supported, changes take effect immediately.
- * FIXME Replace with a more-accurate FMT_COMMIT flag.
- */
- if (!(vg->fid->fmt->features & FMT_PRECOMMIT) && !lvmetad_vg_update(vg))
- return_0;
-
lockd_vg_update(vg);
return 1;
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=5a327755b4cfe45b…
Commit: 5a327755b4cfe45b35863a2b4177a6b32c17642f
Parent: 17ad29ebba4ba1a9361cd424ad1f58e89418a986
Author: David Teigland <teigland(a)redhat.com>
AuthorDate: Mon Jun 27 11:10:58 2016 -0500
Committer: Alasdair G Kergon <agk(a)redhat.com>
CommitterDate: Tue Jun 28 02:28:57 2016 +0100
WHATS_NEW: add recent changes
---
WHATS_NEW | 6 ++++++
1 files changed, 6 insertions(+), 0 deletions(-)
diff --git a/WHATS_NEW b/WHATS_NEW
index 4b074a6..cfa707f 100644
--- a/WHATS_NEW
+++ b/WHATS_NEW
@@ -3,6 +3,12 @@ Version 2.02.159 -
Version 2.02.158 - 25th June 2016
=================================
+ Add a more efficient native vgimportclone command to replace the script.
+ Make lvmlockd always attempt to connect to lvmetad if no connection exists.
+ Let lvmetad handle new connections after shutdown signal.
+ Disable lvmetad when vgcfgrestore begins and enable it again after.
+ Make pvscan do activation if lvmetad is configured but not running.
+ Fix rescanning the PVs for a single VG when using lvmetad.
Pool metadata lvresize uses now same code as resize of normal volume.
Preserve monitoring status when updating thin-pool metadata.
Return 0 (inactive) when status cannot be queried in _lv_active().
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=17ad29ebba4ba1a9…
Commit: 17ad29ebba4ba1a9361cd424ad1f58e89418a986
Parent: 3985b12a2d11d3f4fd3d98090caa8664be594f5c
Author: David Teigland <teigland(a)redhat.com>
AuthorDate: Mon Jun 27 11:02:07 2016 -0500
Committer: Alasdair G Kergon <agk(a)redhat.com>
CommitterDate: Tue Jun 28 02:28:49 2016 +0100
lvmlockd: fix coverity report
---
daemons/lvmlockd/lvmlockd-core.c | 1 +
1 files changed, 1 insertions(+), 0 deletions(-)
diff --git a/daemons/lvmlockd/lvmlockd-core.c b/daemons/lvmlockd/lvmlockd-core.c
index f61939a..b561529 100644
--- a/daemons/lvmlockd/lvmlockd-core.c
+++ b/daemons/lvmlockd/lvmlockd-core.c
@@ -1031,6 +1031,7 @@ retry:
log_error("lvmetad_open reconnect error %d", err);
memset(&reply, 0, sizeof(reply));
reply.error = err;
+ va_end(ap);
return reply;
} else {
log_debug("lvmetad reconnected");
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=3985b12a2d11d3f4…
Commit: 3985b12a2d11d3f4fd3d98090caa8664be594f5c
Parent: 1b11f09d2a3bd3f6421776a004e62215054fa835
Author: Peter Rajnoha <prajnoha(a)redhat.com>
AuthorDate: Mon Jun 27 14:27:43 2016 +0200
Committer: Alasdair G Kergon <agk(a)redhat.com>
CommitterDate: Tue Jun 28 02:28:40 2016 +0100
libdm: report: fix field width calculation when using dm_report_column_headings
This fixes commit 0ba5f4b8e977a6f2f45f95777da508b42d84c01a which moved
field recalculation (field width and sort position) from
dm_report_object to dm_report_output but it didn't handle the case when
dm_report_column_headings was used separately to report headings (before
dm_report_outpout call) and hence we ended up with intial widths for
fields in the headings.
If we're using dm_report_column_headings, we need to recalculate
fields if we haven't done so yet, the same way as we do in
dm_report_output.
---
libdm/libdm-report.c | 65 +++++++++++++++++++++++++++++++------------------
1 files changed, 41 insertions(+), 24 deletions(-)
diff --git a/libdm/libdm-report.c b/libdm/libdm-report.c
index ad03c6e..8993201 100644
--- a/libdm/libdm-report.c
+++ b/libdm/libdm-report.c
@@ -25,7 +25,8 @@
*/
#define RH_SORT_REQUIRED 0x00000100
#define RH_HEADINGS_PRINTED 0x00000200
-#define RH_ALREADY_REPORTED 0x00000400
+#define RH_FIELD_CALC_NEEDED 0x00000400
+#define RH_ALREADY_REPORTED 0x00000800
struct selection {
struct dm_pool *mem;
@@ -1282,6 +1283,8 @@ struct dm_report *dm_report_init(uint32_t *report_types,
if (output_flags & DM_REPORT_OUTPUT_BUFFERED)
rh->flags |= RH_SORT_REQUIRED;
+ rh->flags |= RH_FIELD_CALC_NEEDED;
+
dm_list_init(&rh->field_props);
dm_list_init(&rh->rows);
@@ -4032,6 +4035,7 @@ static void _reset_field_props(struct dm_report *rh)
struct field_properties *fp;
dm_list_iterate_items(fp, &rh->field_props)
fp->width = fp->initial_width;
+ rh->flags |= RH_FIELD_CALC_NEEDED;
}
int dm_report_set_selection(struct dm_report *rh, const char *selection)
@@ -4188,11 +4192,45 @@ static int _report_headings(struct dm_report *rh)
return 0;
}
+static int _should_display_row(struct row *row)
+{
+ return row->field_sel_status || row->selected;
+}
+
+static void _recalculate_fields(struct dm_report *rh)
+{
+ struct row *row;
+ struct dm_report_field *field;
+ size_t len;
+
+ dm_list_iterate_items(row, &rh->rows) {
+ dm_list_iterate_items(field, &row->fields) {
+ if ((rh->flags & RH_SORT_REQUIRED) &&
+ (field->props->flags & FLD_SORT_KEY)) {
+ (*row->sort_fields)[field->props->sort_posn] = field;
+ }
+
+ if (_should_display_row(row)) {
+ len = (int) strlen(field->report_string);
+ if ((len > field->props->width))
+ field->props->width = len;
+
+ }
+ }
+ }
+
+ rh->flags &= ~RH_FIELD_CALC_NEEDED;
+}
+
int dm_report_column_headings(struct dm_report *rh)
{
/* Columns-as-rows does not use _report_headings. */
if (rh->flags & DM_REPORT_OUTPUT_COLUMNS_AS_ROWS)
return 1;
+
+ if (rh->flags & RH_FIELD_CALC_NEEDED)
+ _recalculate_fields(rh);
+
return _report_headings(rh);
}
@@ -4246,11 +4284,6 @@ static int _row_compare(const void *a, const void *b)
return 0; /* Identical */
}
-static int _should_display_row(struct row *row)
-{
- return row->field_sel_status || row->selected;
-}
-
static int _sort_rows(struct dm_report *rh)
{
struct row *(*rows)[];
@@ -4701,9 +4734,6 @@ static int _print_basic_report_header(struct dm_report *rh)
int dm_report_output(struct dm_report *rh)
{
- struct row *row;
- struct dm_report_field *field;
- size_t len;
int r = 0;
if (_is_json_report(rh) &&
@@ -4715,21 +4745,8 @@ int dm_report_output(struct dm_report *rh)
goto out;
}
- dm_list_iterate_items(row, &rh->rows) {
- dm_list_iterate_items(field, &row->fields) {
- if ((rh->flags & RH_SORT_REQUIRED) &&
- (field->props->flags & FLD_SORT_KEY)) {
- (*row->sort_fields)[field->props->sort_posn] = field;
- }
-
- if (_should_display_row(row)) {
- len = (int) strlen(field->report_string);
- if ((len > field->props->width))
- field->props->width = len;
-
- }
- }
- }
+ if (rh->flags & RH_FIELD_CALC_NEEDED)
+ _recalculate_fields(rh);
if ((rh->flags & RH_SORT_REQUIRED))
_sort_rows(rh);
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=1b11f09d2a3bd3f6…
Commit: 1b11f09d2a3bd3f6421776a004e62215054fa835
Parent: f0768f636edb8da08e46b029380779fd623399de
Author: Peter Rajnoha <prajnoha(a)redhat.com>
AuthorDate: Mon Jun 27 10:14:17 2016 +0200
Committer: Alasdair G Kergon <agk(a)redhat.com>
CommitterDate: Tue Jun 28 02:27:19 2016 +0100
reporter: simplify --configreport handling for -S|--select and fix an issue reported by coverity
Simplify code around _do_get_report_selection - remove "expected_idxs[]"
argument which is superfluous and add "allow_single" switch instead to
allow for recognition of "--configreport <report_name> -S" as well as
single "-S" if needed.
Null pointer dereferences (FORWARD_NULL) /safe/guest2/covscan/LVM2.2.02.158/tools/reporter.c: 961 in _do_report_get_selection()
Null pointer dereferences (FORWARD_NULL) Dereferencing null pointer "single_args".
---
lib/report/report.h | 2 +-
tools/reporter.c | 60 +++++++++++++++++++++++----------------------------
tools/toollib.c | 2 +-
3 files changed, 29 insertions(+), 35 deletions(-)
diff --git a/lib/report/report.h b/lib/report/report.h
index b9028fe..ba3a8fa 100644
--- a/lib/report/report.h
+++ b/lib/report/report.h
@@ -90,7 +90,7 @@ void *report_init(struct cmd_context *cmd, const char *format, const char *keys,
int aligned, int buffered, int headings, int field_prefixes,
int quoted, int columns_as_rows, const char *selection,
int multiple_output);
-int report_get_single_selection(struct cmd_context *cmd, const char **selection);
+int report_get_single_selection(struct cmd_context *cmd, report_type_t report_type, const char **selection);
void *report_init_for_selection(struct cmd_context *cmd, report_type_t *report_type,
const char *selection);
int report_get_prefix_and_desc(report_type_t report_type_id,
diff --git a/tools/reporter.c b/tools/reporter.c
index 40d449c..6f8ed8f 100644
--- a/tools/reporter.c
+++ b/tools/reporter.c
@@ -29,6 +29,8 @@ typedef enum {
REPORT_IDX_COUNT
} report_idx_t;
+#define REPORT_IDX_FULL_START REPORT_IDX_FULL_VGS
+
struct single_report_args {
report_type_t report_type;
char report_prefix[32];
@@ -748,12 +750,10 @@ static report_idx_t _get_report_idx_from_name(report_type_t report_type, const c
return REPORT_IDX_NULL;
/* Change to basic report type for comparison. */
- if (report_type == LABEL)
+ if ((report_type == LABEL) || (report_type == PVSEGS))
report_type = PVS;
else if (report_type == SEGS)
report_type = LVS;
- else if (report_type == PVSEGS)
- report_type = PVSEGS;
if (!strcasecmp(name, "log"))
idx = REPORT_IDX_LOG;
@@ -778,11 +778,11 @@ static report_idx_t _get_report_idx_from_name(report_type_t report_type, const c
return idx;
}
-static int _should_process_report_idx(report_type_t report_type, report_idx_t idx)
+static int _should_process_report_idx(report_type_t report_type, int allow_single, report_idx_t idx)
{
if (((idx == REPORT_IDX_LOG) && (report_type != CMDLOG)) ||
- ((idx == REPORT_IDX_SINGLE) && ((report_type == FULL) || (report_type == CMDLOG))) ||
- ((idx > REPORT_IDX_LOG) && report_type != FULL))
+ ((idx == REPORT_IDX_SINGLE) && !allow_single) ||
+ ((idx >= REPORT_IDX_FULL_START) && report_type != FULL))
return 0;
return 1;
@@ -867,7 +867,7 @@ static int _get_report_options(struct cmd_context *cmd,
action = OPTS_REPLACE;
}
- if (!_should_process_report_idx(single_args->report_type, idx))
+ if (!_should_process_report_idx(single_args->report_type, !(single_args->report_type & (CMDLOG | FULL)), idx))
continue;
if ((action != OPTS_COMPACT) &&
@@ -932,6 +932,9 @@ static int _get_report_keys(struct cmd_context *cmd,
goto_out;
}
+ if (!_should_process_report_idx(single_args->report_type, !(single_args->report_type & (CMDLOG | FULL)), idx))
+ continue;
+
args->single_args[idx].keys = grouped_arg_str_value(current_group->arg_values, sort_ARG, NULL);
}
@@ -941,16 +944,15 @@ out:
}
static int _do_report_get_selection(struct cmd_context *cmd,
+ report_type_t report_type,
+ int allow_single,
struct report_args *args,
- struct single_report_args *single_args,
- report_idx_t expected_idxs[],
- const char **ret_selection)
+ const char **last_selection)
{
struct arg_value_group_list *current_group;
- const char *final_selection = "", *selection = NULL;
+ const char *final_selection = NULL, *selection = NULL;
const char *report_name = NULL;
report_idx_t idx = REPORT_IDX_SINGLE;
- int i;
dm_list_iterate_items(current_group, &cmd->arg_value_groups) {
if (!grouped_arg_is_set(current_group->arg_values, select_ARG))
@@ -958,27 +960,21 @@ static int _do_report_get_selection(struct cmd_context *cmd,
if (grouped_arg_is_set(current_group->arg_values, configreport_ARG)) {
report_name = grouped_arg_str_value(current_group->arg_values, configreport_ARG, NULL);
- if ((idx = _get_report_idx_from_name(single_args->report_type, report_name)) == REPORT_IDX_NULL)
+ if ((idx = _get_report_idx_from_name(report_type, report_name)) == REPORT_IDX_NULL)
return_0;
}
selection = grouped_arg_str_value(current_group->arg_values, select_ARG, NULL);
- if (single_args) {
- if (!_should_process_report_idx(single_args->report_type, idx))
- continue;
+ if (!_should_process_report_idx(report_type, allow_single, idx))
+ continue;
+ if (args)
args->single_args[idx].selection = selection;
- final_selection = selection;
- } else {
- for (i = 0; expected_idxs[i] != REPORT_IDX_NULL; i++) {
- if (idx == expected_idxs[i])
- final_selection = selection;
- }
- }
+ final_selection = selection;
}
- if (ret_selection)
- *ret_selection = final_selection;
+ if (last_selection)
+ *last_selection = final_selection;
return 1;
}
@@ -987,13 +983,13 @@ static int _get_report_selection(struct cmd_context *cmd,
struct report_args *args,
struct single_report_args *single_args)
{
- return _do_report_get_selection(cmd, args, single_args, NULL, NULL) ? ECMD_PROCESSED : ECMD_FAILED;
+ return _do_report_get_selection(cmd, single_args->report_type, !(single_args->report_type & (CMDLOG | FULL)),
+ args, NULL) ? ECMD_PROCESSED : ECMD_FAILED;
}
-int report_get_single_selection(struct cmd_context *cmd, const char **selection)
+int report_get_single_selection(struct cmd_context *cmd, report_type_t report_type, const char **selection)
{
- report_idx_t expected_idxs[] = {REPORT_IDX_SINGLE, REPORT_IDX_NULL};
- return _do_report_get_selection(cmd, NULL, NULL, expected_idxs, selection);
+ return _do_report_get_selection(cmd, report_type, 1, NULL, selection);
}
static int _set_report_prefix_and_name(struct report_args *args,
@@ -1525,9 +1521,8 @@ bad:
int lastlog(struct cmd_context *cmd, int argc, char **argv)
{
- static report_idx_t expected_idxs[] = {REPORT_IDX_SINGLE, REPORT_IDX_LOG, REPORT_IDX_NULL};
struct dm_report_group *report_group = NULL;
- const char *selection = NULL;
+ const char *selection;
int r = ECMD_FAILED;
if (!cmd->log_rh) {
@@ -1538,8 +1533,7 @@ int lastlog(struct cmd_context *cmd, int argc, char **argv)
if (!report_format_init(cmd, NULL, &report_group, &cmd->log_rh, NULL, NULL))
goto_out;
- if (arg_is_set(cmd, select_ARG) &&
- !_do_report_get_selection(cmd, NULL, NULL, expected_idxs, &selection))
+ if (!_do_report_get_selection(cmd, CMDLOG, 1, NULL, &selection))
goto_out;
if (!dm_report_set_selection(cmd->log_rh, selection)) {
diff --git a/tools/toollib.c b/tools/toollib.c
index 80d0f32..4c24b16 100644
--- a/tools/toollib.c
+++ b/tools/toollib.c
@@ -1771,7 +1771,7 @@ int init_selection_handle(struct cmd_context *cmd, struct processing_handle *han
return 0;
}
- if (!report_get_single_selection(cmd, &selection))
+ if (!report_get_single_selection(cmd, initial_report_type, &selection))
return_0;
sh->report_type = initial_report_type;
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=f0768f636edb8da0…
Commit: f0768f636edb8da08e46b029380779fd623399de
Parent: a46f5242471018faca5d20204d0bab5fb2d6b9cd
Author: Peter Rajnoha <prajnoha(a)redhat.com>
AuthorDate: Mon Jun 27 10:12:41 2016 +0200
Committer: Alasdair G Kergon <agk(a)redhat.com>
CommitterDate: Tue Jun 28 02:26:54 2016 +0100
coverity: fix issues detected in recent code
Uninitialized variables (UNINIT) /safe/guest2/covscan/LVM2.2.02.158/tools/toollib.c: 3520 in _process_pvs_in_vgs()
Uninitialized variables (UNINIT) Using uninitialized value "do_report_ret_code".
Null pointer dereferences (REVERSE_INULL) /safe/guest2/covscan/LVM2.2.02.158/libdm/libdm-report.c: 4745 in dm_report_output()
Null pointer dereferences (REVERSE_INULL) Null-checking "rh" suggests that it may be null, but it has already been dereferenced on all paths leading to the check.
Incorrect expression (MISSING_COMMA) /safe/guest2/covscan/LVM2.2.02.158/lib/log/log.c: 280 in _get_log_level_name()
Incorrect expression (MISSING_COMMA) In the initialization of "log_level_names", a suspicious concatenated string ""noticeinfo"" is produced.
Null pointer dereferences (FORWARD_NULL) /safe/guest2/covscan/LVM2.2.02.158/tools/reporter.c: 816 in_get_report_options()
Null pointer dereferences (FORWARD_NULL) Comparing "mem" to null implies that "mem" might be null.
---
lib/log/log.c | 2 +-
libdm/libdm-report.c | 4 ++--
tools/reporter.c | 2 +-
tools/toollib.c | 2 +-
4 files changed, 5 insertions(+), 5 deletions(-)
diff --git a/lib/log/log.c b/lib/log/log.c
index b3453dc..30d71ef 100644
--- a/lib/log/log.c
+++ b/lib/log/log.c
@@ -277,7 +277,7 @@ static const char *_get_log_level_name(int use_stderr, int level)
"fatal", /* _LOG_FATAL */
"error", /* _LOG_ERROR */
"warn", /* _LOG_WARN */
- "notice" /* _LOG_NOTICE */
+ "notice",/* _LOG_NOTICE */
"info", /* _LOG_INFO */
"debug" /* _LOG_DEBUG */
};
diff --git a/libdm/libdm-report.c b/libdm/libdm-report.c
index 6bea34c..ad03c6e 100644
--- a/libdm/libdm-report.c
+++ b/libdm/libdm-report.c
@@ -4001,7 +4001,7 @@ static int _report_set_selection(struct dm_report *rh, const char *selection, in
goto_bad;
}
- if (!selection || !strcasecmp(selection, SPECIAL_SELECTION_ALL))
+ if (!selection || !selection[0] || !strcasecmp(selection, SPECIAL_SELECTION_ALL))
return 1;
rh->selection->add_new_fields = add_new_fields;
@@ -4742,7 +4742,7 @@ int dm_report_output(struct dm_report *rh)
else
r = _output_as_columns(rh);
out:
- if (r && rh && rh->group_item)
+ if (r && rh->group_item)
rh->group_item->output_done = 1;
return r;
}
diff --git a/tools/reporter.c b/tools/reporter.c
index ee2d251..40d449c 100644
--- a/tools/reporter.c
+++ b/tools/reporter.c
@@ -815,7 +815,7 @@ static int _get_report_options(struct cmd_context *cmd,
if (!(mem = dm_pool_create("report_options", 128))) {
log_error("Failed to create temporary mempool to process report options.");
- goto out;
+ return ECMD_FAILED;
}
if (single_args->report_type == CMDLOG) {
diff --git a/tools/toollib.c b/tools/toollib.c
index 5c61ddd..80d0f32 100644
--- a/tools/toollib.c
+++ b/tools/toollib.c
@@ -3439,7 +3439,7 @@ static int _process_pvs_in_vgs(struct cmd_context *cmd, uint32_t read_flags,
int skip;
int notfound;
int already_locked;
- int do_report_ret_code;
+ int do_report_ret_code = 1;
log_set_report_object_type(LOG_REPORT_OBJECT_TYPE_VG);
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=a46f5242471018fa…
Commit: a46f5242471018faca5d20204d0bab5fb2d6b9cd
Parent: 887f071b2545bb2b60e13de854898ab71a6b0ff5
Author: Alasdair G Kergon <agk(a)redhat.com>
AuthorDate: Sat Jun 25 20:47:49 2016 +0100
Committer: Alasdair G Kergon <agk(a)redhat.com>
CommitterDate: Sat Jun 25 20:47:49 2016 +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 8cb5c44..6605e1a 100644
--- a/VERSION
+++ b/VERSION
@@ -1 +1 @@
-2.02.158(2)-git (2016-06-25)
+2.02.159(2)-git (2016-06-25)
diff --git a/VERSION_DM b/VERSION_DM
index 389871f..87ac527 100644
--- a/VERSION_DM
+++ b/VERSION_DM
@@ -1 +1 @@
-1.02.128-git (2016-06-25)
+1.02.129-git (2016-06-25)
diff --git a/WHATS_NEW b/WHATS_NEW
index 530ece8..4b074a6 100644
--- a/WHATS_NEW
+++ b/WHATS_NEW
@@ -1,3 +1,6 @@
+Version 2.02.159 -
+=================================
+
Version 2.02.158 - 25th June 2016
=================================
Pool metadata lvresize uses now same code as resize of normal volume.
diff --git a/WHATS_NEW_DM b/WHATS_NEW_DM
index a03308b..5043c23 100644
--- a/WHATS_NEW_DM
+++ b/WHATS_NEW_DM
@@ -1,3 +1,6 @@
+Version 1.02.129 -
+=================================
+
Version 1.02.128 - 25th June 2016
=================================
Recognize 'all' keyword used in selection as synonym for "" (no selection).
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=887f071b2545bb2b…
Commit: 887f071b2545bb2b60e13de854898ab71a6b0ff5
Parent: 15b932a70e4a29f386ea57e1b845d637780b463b
Author: Alasdair G Kergon <agk(a)redhat.com>
AuthorDate: Sat Jun 25 20:35:14 2016 +0100
Committer: Alasdair G Kergon <agk(a)redhat.com>
CommitterDate: Sat Jun 25 20:35:14 2016 +0100
pre-release
---
VERSION | 2 +-
VERSION_DM | 2 +-
WHATS_NEW | 5 ++++-
WHATS_NEW_DM | 2 +-
4 files changed, 7 insertions(+), 4 deletions(-)
diff --git a/VERSION b/VERSION
index 34e00b1..8cb5c44 100644
--- a/VERSION
+++ b/VERSION
@@ -1 +1 @@
-2.02.158(2)-git (2016-06-17)
+2.02.158(2)-git (2016-06-25)
diff --git a/VERSION_DM b/VERSION_DM
index dd57819..389871f 100644
--- a/VERSION_DM
+++ b/VERSION_DM
@@ -1 +1 @@
-1.02.128-git (2016-06-17)
+1.02.128-git (2016-06-25)
diff --git a/WHATS_NEW b/WHATS_NEW
index 7238568..530ece8 100644
--- a/WHATS_NEW
+++ b/WHATS_NEW
@@ -1,10 +1,13 @@
-Version 2.02.158 -
+Version 2.02.158 - 25th June 2016
=================================
Pool metadata lvresize uses now same code as resize of normal volume.
Preserve monitoring status when updating thin-pool metadata.
Return 0 (inactive) when status cannot be queried in _lv_active().
Switch to log_warn() for failing activation status query.
+ Replace vgimportclone script with binary.
+ While lvmetad is shutting down, continue handling all connections cleanly.
Refactor lvconvert argument handling code.
+ Notify lvmetad when vgcfgrestore changes VG metadata.
Add --logonly option to report only cmd log for a command, not other reports.
Add log/command_log_selection to configure default selection used on cmd log.
Use 'orphan' object type in cmd log for groups to collect PVs not yet in VGs.
diff --git a/WHATS_NEW_DM b/WHATS_NEW_DM
index 8911e36..a03308b 100644
--- a/WHATS_NEW_DM
+++ b/WHATS_NEW_DM
@@ -1,4 +1,4 @@
-Version 1.02.128 -
+Version 1.02.128 - 25th June 2016
=================================
Recognize 'all' keyword used in selection as synonym for "" (no selection).
Add dm_report_set_selection to set selection for multiple output of report.
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=f8e17d9af660fbfe…
Commit: f8e17d9af660fbfec9baadc4b05652e3dcc2a345
Parent: 886da20c4dce3f3ab5c9fdc22580a98b49c6e269
Author: David Teigland <teigland(a)redhat.com>
AuthorDate: Wed Jun 8 16:02:45 2016 -0500
Committer: David Teigland <teigland(a)redhat.com>
CommitterDate: Mon Jun 27 11:22:26 2016 -0500
lvmetad: two phase vg_remove
Apply the same idea as vg_update.
Before doing the VG remove on disk, invalidate
the VG in lvmetad. After the VG is removed,
remove the VG in lvmetad. If the command fails
after removing the VG on disk, but before removing
the VG metadata from lvmetad, then a subsequent
command will see the INVALID flag and not use the
stale metadata from lvmetad.
---
lib/cache/lvmetad.c | 36 ++++++++++++++++++++++++++++++++----
lib/cache/lvmetad.h | 6 ++++--
lib/metadata/metadata.c | 8 ++++++--
3 files changed, 42 insertions(+), 8 deletions(-)
diff --git a/lib/cache/lvmetad.c b/lib/cache/lvmetad.c
index 784a529..94059dd 100644
--- a/lib/cache/lvmetad.c
+++ b/lib/cache/lvmetad.c
@@ -648,10 +648,9 @@ static int _lvmetad_handle_reply(daemon_reply reply, const char *id, const char
action = "set VG info";
else if (!strcmp(id, "vg_update"))
action = "update VG";
- else if (!strcmp(id, "vg_remove")) {
+ else if (!strcmp(id, "vg_remove"))
action = "remove VG";
- action_modifies = 1;
- } else if (!strcmp(id, "pv_found")) {
+ else if (!strcmp(id, "pv_found")) {
action = "update PV";
action_modifies = 1;
} else if (!strcmp(id, "pv_gone")) {
@@ -1272,7 +1271,36 @@ int lvmetad_vg_update_finish(struct volume_group *vg)
return 1;
}
-int lvmetad_vg_remove(struct volume_group *vg)
+int lvmetad_vg_remove_pending(struct volume_group *vg)
+{
+ char uuid[64] __attribute__((aligned(8)));
+ daemon_reply reply;
+
+ if (!lvmetad_used() || test_mode())
+ return 1; /* fake it */
+
+ if (!id_write_format(&vg->id, uuid, sizeof(uuid)))
+ return_0;
+
+ /* Sending version/seqno 0 in set_vg_info will set the INVALID flag. */
+
+ log_debug_lvmetad("Sending lvmetad pending remove VG %s", vg->name);
+ reply = _lvmetad_send(vg->cmd, "set_vg_info",
+ "name = %s", vg->name,
+ "uuid = %s", uuid,
+ "version = %d", 0,
+ NULL);
+
+ if (!_lvmetad_handle_reply(reply, "set_vg_info", vg->name, NULL)) {
+ daemon_reply_destroy(reply);
+ return_0;
+ }
+
+ daemon_reply_destroy(reply);
+ return 1;
+}
+
+int lvmetad_vg_remove_finish(struct volume_group *vg)
{
char uuid[64];
daemon_reply reply;
diff --git a/lib/cache/lvmetad.h b/lib/cache/lvmetad.h
index 9ee4e2d..d47ce41 100644
--- a/lib/cache/lvmetad.h
+++ b/lib/cache/lvmetad.h
@@ -86,7 +86,8 @@ int lvmetad_vg_update_finish(struct volume_group *vg);
* only needed during vgremove, which does not wipe PV labels and therefore
* cannot mark the PVs as gone.
*/
-int lvmetad_vg_remove(struct volume_group *vg);
+int lvmetad_vg_remove_pending(struct volume_group *vg);
+int lvmetad_vg_remove_finish(struct volume_group *vg);
/*
* Notify lvmetad that a PV has been found. It is not an error if the PV is
@@ -174,7 +175,8 @@ void lvmetad_clear_disabled(struct cmd_context *cmd);
# define lvmetad_vg_update(vg) (1)
# define lvmetad_vg_update_pending(vg) (1)
# define lvmetad_vg_update_finish(vg) (1)
-# define lvmetad_vg_remove(vg) (1)
+# define lvmetad_vg_remove_pending(vg) (1)
+# define lvmetad_vg_remove_finish(vg) (1)
# define lvmetad_pv_found(cmd, pvid, dev, fmt, label_sector, vg, found_vgnames, changed_vgnames) (1)
# define lvmetad_pv_gone(devno, pv_name) (1)
# define lvmetad_pv_gone_by_dev(dev) (1)
diff --git a/lib/metadata/metadata.c b/lib/metadata/metadata.c
index e100bc6..d8bb726 100644
--- a/lib/metadata/metadata.c
+++ b/lib/metadata/metadata.c
@@ -568,6 +568,11 @@ int vg_remove_direct(struct volume_group *vg)
struct pv_list *pvl;
int ret = 1;
+ if (!lvmetad_vg_remove_pending(vg)) {
+ log_error("Failed to update lvmetad for pending remove.");
+ return 0;
+ }
+
if (!vg_remove_mdas(vg)) {
log_error("vg_remove_mdas %s failed", vg->name);
return 0;
@@ -599,8 +604,7 @@ int vg_remove_direct(struct volume_group *vg)
}
}
- /* FIXME Handle partial failures from above. */
- if (!lvmetad_vg_remove(vg))
+ if (!lvmetad_vg_remove_finish(vg))
stack;
lockd_vg_update(vg);
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=886da20c4dce3f3a…
Commit: 886da20c4dce3f3ab5c9fdc22580a98b49c6e269
Parent: e6c376ee2dae4539b1cc38ed6d9c5430777d2753
Author: David Teigland <teigland(a)redhat.com>
AuthorDate: Wed Jun 8 14:42:03 2016 -0500
Committer: David Teigland <teigland(a)redhat.com>
CommitterDate: Mon Jun 27 11:22:21 2016 -0500
lvmetad: two phase vg_update
Previously, a command sent lvmetad new VG metadata in vg_commit().
In vg_commit(), devices are suspended, so any memory allocation
done by the command while sending to lvmetad, or by lvmetad while
updating its cache could deadlock if memory reclaim was triggered.
Now lvmetad is updated in unlock_vg(), after devices are resumed.
The new method for updating VG metadata in lvmetad is in two phases:
1. In vg_write(), before devices are suspended, the command sends
lvmetad a short message ("set_vg_info") telling it what the new
VG seqno will be. lvmetad sees that the seqno is newer than
the seqno of its cached VG, so it sets the INVALID flag for the
cached VG. If sending the message to lvmetad fails, the command
fails before the metadata is committed and the change is not made.
If sending the message succeeds, vg_commit() is called.
2. In unlock_vg(), after devices are resumed, the command sends
lvmetad the standard vg_update message with the new metadata.
lvmetad sees that the seqno in the new metadata matches the
seqno it saved from set_vg_info, and knows it has the latest
copy, so it clears the INVALID flag for the cached VG.
If a command fails between 1 and 2 (after committing the VG on disk,
but before sending lvmetad the new metadata), the cached VG retains
the INVALID flag in lvmetad. A subsequent command will read the
cached VG from lvmetad, see the INVALID flag, ignore the cached
copy, read the VG from disk instead, update the lvmetad copy
with the latest copy from disk, (this clears the INVALID flag
in lvmetad), and use the correct VG metadata for the command.
(This INVALID mechanism already existed for use by lvmlockd.)
---
daemons/lvmetad/lvmetad-core.c | 9 ++-
lib/cache/lvmetad.c | 113 ++++++++++++++++++++++++++++++++-------
lib/cache/lvmetad.h | 5 ++-
lib/format_text/archiver.c | 1 +
lib/locking/locking.h | 6 ++-
lib/metadata/metadata.c | 37 +++++++++----
lib/metadata/pv_manip.c | 2 +-
lib/metadata/replicator_manip.c | 1 +
lib/metadata/vg.c | 1 +
lib/metadata/vg.h | 1 +
liblvm/lvm_pv.c | 5 +-
liblvm/lvm_vg.c | 7 ++-
tools/pvchange.c | 2 +-
tools/pvcreate.c | 2 +-
tools/pvdisplay.c | 2 +-
tools/pvremove.c | 2 +-
tools/pvscan.c | 4 +-
tools/reporter.c | 2 +-
tools/toollib.c | 10 ++--
tools/vgcfgrestore.c | 10 ++--
tools/vgcreate.c | 10 ++--
tools/vgextend.c | 2 +-
tools/vgimportclone.c | 4 +-
tools/vgrename.c | 6 +-
tools/vgscan.c | 2 +-
tools/vgsplit.c | 6 ++
26 files changed, 181 insertions(+), 71 deletions(-)
diff --git a/daemons/lvmetad/lvmetad-core.c b/daemons/lvmetad/lvmetad-core.c
index aab569f..1ec9e3b 100644
--- a/daemons/lvmetad/lvmetad-core.c
+++ b/daemons/lvmetad/lvmetad-core.c
@@ -2464,10 +2464,10 @@ static response set_vg_info(lvmetad_state *s, request r)
{
struct dm_config_tree *vg;
struct vg_info *info;
- const char *name;
- const char *uuid;
+ const char *name = NULL;
+ const char *uuid = NULL;
const int64_t new_version = daemon_request_int(r, "version", -1);
- int64_t cache_version;
+ int64_t cache_version = -1;
if (new_version == -1)
goto out;
@@ -2500,6 +2500,9 @@ vers:
if (cache_version != -1 && new_version != -1 && cache_version >= new_version)
goto out;
inval:
+ DEBUGLOG(s, "set info VG name %s uuid %s cache_version %d new_version %d",
+ name ?: "none", uuid ?: "none", (int)cache_version, (int)new_version);
+
info = dm_hash_lookup(s->vgid_to_info, uuid);
if (!info) {
info = malloc(sizeof(struct vg_info));
diff --git a/lib/cache/lvmetad.c b/lib/cache/lvmetad.c
index a0a17ac..784a529 100644
--- a/lib/cache/lvmetad.c
+++ b/lib/cache/lvmetad.c
@@ -644,10 +644,11 @@ static int _lvmetad_handle_reply(daemon_reply reply, const char *id, const char
action = "clear info about all PVs";
else if (!strcmp(id, "vg_clear_outdated_pvs"))
action = "clear the list of outdated PVs";
- else if (!strcmp(id, "vg_update")) {
+ else if (!strcmp(id, "set_vg_info"))
+ action = "set VG info";
+ else if (!strcmp(id, "vg_update"))
action = "update VG";
- action_modifies = 1;
- } else if (!strcmp(id, "vg_remove")) {
+ else if (!strcmp(id, "vg_remove")) {
action = "remove VG";
action_modifies = 1;
} else if (!strcmp(id, "pv_found")) {
@@ -1073,7 +1074,13 @@ struct volume_group *lvmetad_vg_lookup(struct cmd_context *cmd, const char *vgna
log_debug_lvmetad("Rescan VG %s because no lvmlockd lock is held", vgname);
rescan = 1;
} else if (dm_config_find_node(reply.cft->root, "vg_invalid")) {
- log_debug_lvmetad("Rescan VG %s because lvmetad returned invalid", vgname);
+ if (!is_lockd_type(vg->lock_type)) {
+ /* Can happen if a previous command failed/crashed without updating lvmetad. */
+ log_warn("WARNING: Reading VG %s from disk because lvmetad metadata is invalid.", vgname);
+ } else {
+ /* This is normal when the VG was modified by another host. */
+ log_debug_lvmetad("Rescan VG %s because lvmetad returned invalid", vgname);
+ }
rescan = 1;
}
@@ -1137,32 +1144,98 @@ static int _fixup_ignored(struct metadata_area *mda, void *baton) {
return 1;
}
-int lvmetad_vg_update(struct volume_group *vg)
+/*
+ * After the VG is written to disk, but before it's committed,
+ * lvmetad is told the new seqno. lvmetad sets the INVALID
+ * flag on the cached VG and saves the new seqno.
+ *
+ * After the VG is committed on disk, the command sends the
+ * new VG metadata, containing the new seqno. lvmetad sees
+ * that it has the updated metadata and clears the INVALID
+ * flag on the cached VG.
+ *
+ * If the command fails after committing the metadata on disk
+ * but before sending the new metadata to lvmetad, then the
+ * next command that asks lvmetad for the metadata will get
+ * back the INVALID flag. That command will then read the
+ * VG metadata from disk to use, and will send the latest
+ * metadata from disk to lvmetad which will clear the
+ * INVALID flag.
+ */
+
+int lvmetad_vg_update_pending(struct volume_group *vg)
{
+ char uuid[64] __attribute__((aligned(8)));
+ daemon_reply reply;
+
+ if (!lvmetad_used() || test_mode())
+ return 1; /* fake it */
+
+ if (!id_write_format(&vg->id, uuid, sizeof(uuid)))
+ return_0;
+
+ log_debug_lvmetad("Sending lvmetad pending VG %s (seqno %" PRIu32 ")", vg->name, vg->seqno);
+ reply = _lvmetad_send(vg->cmd, "set_vg_info",
+ "name = %s", vg->name,
+ "uuid = %s", uuid,
+ "version = %"PRId64, (int64_t)vg->seqno,
+ NULL);
+
+ if (!_lvmetad_handle_reply(reply, "set_vg_info", vg->name, NULL)) {
+ daemon_reply_destroy(reply);
+ return_0;
+ }
+
+ vg->lvmetad_update_pending = 1;
+
+ daemon_reply_destroy(reply);
+ return 1;
+}
+
+int lvmetad_vg_update_finish(struct volume_group *vg)
+{
+ char uuid[64] __attribute__((aligned(8)));
daemon_reply reply;
struct dm_hash_node *n;
struct metadata_area *mda;
char mda_id[128], *num;
+ struct dm_config_tree *vgmeta;
struct pv_list *pvl;
struct lvmcache_info *info;
struct _fixup_baton baton;
- if (!vg)
- return 0;
+ if (!vg->lvmetad_update_pending)
+ return 1;
+
+ if (!(vg->fid->fmt->features & FMT_PRECOMMIT))
+ return 1;
if (!lvmetad_used() || test_mode())
return 1; /* fake it */
- if (!vg->cft_precommitted) {
- log_error(INTERNAL_ERROR "VG update without precommited");
+ if (!id_write_format(&vg->id, uuid, sizeof(uuid)))
+ return_0;
+
+ if (!(vgmeta = export_vg_to_config_tree(vg))) {
+ log_error("Failed to export VG to config tree.");
return 0;
}
- log_debug_lvmetad("Sending lvmetad updated metadata for VG %s (seqno %" PRIu32 ")", vg->name, vg->seqno);
- reply = _lvmetad_send(vg->cmd, "vg_update", "vgname = %s", vg->name,
- "metadata = %t", vg->cft_precommitted, NULL);
+ log_debug_lvmetad("Sending lvmetad updated VG %s (seqno %" PRIu32 ")", vg->name, vg->seqno);
+ reply = _lvmetad_send(vg->cmd, "vg_update",
+ "vgname = %s", vg->name,
+ "metadata = %t", vgmeta,
+ NULL);
+
+ dm_config_destroy(vgmeta);
if (!_lvmetad_handle_reply(reply, "vg_update", vg->name, NULL)) {
+ /*
+ * In this failure case, the VG cached in lvmetad remains in
+ * the INVALID state (from lvmetad_vg_update_pending).
+ * A subsequent command will see INVALID, ignore the cached
+ * copy, read the VG from disk, and update the cached copy.
+ */
daemon_reply_destroy(reply);
return 0;
}
@@ -1195,6 +1268,7 @@ int lvmetad_vg_update(struct volume_group *vg)
return 0;
}
+ vg->lvmetad_update_pending = 0;
return 1;
}
@@ -1207,6 +1281,8 @@ int lvmetad_vg_remove(struct volume_group *vg)
if (!lvmetad_used() || test_mode())
return 1; /* just fake it */
+ vg->lvmetad_update_pending = 0;
+
if (!id_write_format(&vg->id, uuid, sizeof(uuid)))
return_0;
@@ -1887,10 +1963,6 @@ scan_more:
/*
* Update lvmetad with the newly read version of the VG.
- * The "precommitted" name is a misnomer in this case,
- * but that is the field which lvmetad_vg_update() uses
- * to send the metadata cft to lvmetad.
- *
* When the seqno is unchanged the cached VG can be left.
*/
if (save_seqno != vg->seqno) {
@@ -1905,10 +1977,13 @@ scan_more:
log_debug_lvmetad("Rescan VG %s updating lvmetad from seqno %u to seqno %u.",
vg->name, vg->seqno, save_seqno);
- vg_ret->cft_precommitted = vgmeta_ret;
- if (!lvmetad_vg_update(vg_ret))
+ /*
+ * If this vg_update fails the cached metadata in
+ * lvmetad will remain invalid.
+ */
+ vg_ret->lvmetad_update_pending = 1;
+ if (!lvmetad_vg_update_finish(vg_ret))
log_error("Failed to update lvmetad with new VG meta");
- vg_ret->cft_precommitted = NULL;
}
dm_config_destroy(vgmeta_ret);
}
diff --git a/lib/cache/lvmetad.h b/lib/cache/lvmetad.h
index 3bb2b7c..9ee4e2d 100644
--- a/lib/cache/lvmetad.h
+++ b/lib/cache/lvmetad.h
@@ -78,7 +78,8 @@ void lvmetad_release_token(void);
* lvmetad_vg_commit. The request is validated immediately and lvmetad_vg_commit
* only constitutes a pointer update.
*/
-int lvmetad_vg_update(struct volume_group *vg);
+int lvmetad_vg_update_pending(struct volume_group *vg);
+int lvmetad_vg_update_finish(struct volume_group *vg);
/*
* Inform lvmetad that a VG has been removed. This is not entirely safe, but is
@@ -171,6 +172,8 @@ void lvmetad_clear_disabled(struct cmd_context *cmd);
# define lvmetad_set_token(a) do { } while (0)
# define lvmetad_release_token() do { } while (0)
# define lvmetad_vg_update(vg) (1)
+# define lvmetad_vg_update_pending(vg) (1)
+# define lvmetad_vg_update_finish(vg) (1)
# define lvmetad_vg_remove(vg) (1)
# define lvmetad_pv_found(cmd, pvid, dev, fmt, label_sector, vg, found_vgnames, changed_vgnames) (1)
# define lvmetad_pv_gone(devno, pv_name) (1)
diff --git a/lib/format_text/archiver.c b/lib/format_text/archiver.c
index 92799e4..2acd8f5 100644
--- a/lib/format_text/archiver.c
+++ b/lib/format_text/archiver.c
@@ -22,6 +22,7 @@
#include "memlock.h"
#include "toolcontext.h"
#include "locking.h"
+#include "lvmetad-client.h"
#include <unistd.h>
diff --git a/lib/locking/locking.h b/lib/locking/locking.h
index ceeb73c..18bce2d 100644
--- a/lib/locking/locking.h
+++ b/lib/locking/locking.h
@@ -198,8 +198,10 @@ int check_lvm1_vg_inactive(struct cmd_context *cmd, const char *vgname);
rr; \
})
-#define unlock_vg(cmd, vol) \
+#define unlock_vg(cmd, vg, vol) \
do { \
+ if (vg && !lvmetad_vg_update_finish(vg)) \
+ stack; \
if (is_real_vg(vol) && !sync_dev_names(cmd)) \
stack; \
if (!lock_vol(cmd, vol, LCK_VG_UNLOCK, NULL)) \
@@ -207,7 +209,7 @@ int check_lvm1_vg_inactive(struct cmd_context *cmd, const char *vgname);
} while (0)
#define unlock_and_release_vg(cmd, vg, vol) \
do { \
- unlock_vg(cmd, vol); \
+ unlock_vg(cmd, vg, vol); \
release_vg(vg); \
} while (0)
diff --git a/lib/metadata/metadata.c b/lib/metadata/metadata.c
index e55463b..e100bc6 100644
--- a/lib/metadata/metadata.c
+++ b/lib/metadata/metadata.c
@@ -629,7 +629,7 @@ int vg_remove(struct volume_group *vg)
ret = vg_remove_direct(vg);
- unlock_vg(vg->cmd, VG_ORPHANS);
+ unlock_vg(vg->cmd, vg, VG_ORPHANS);
return ret;
}
@@ -3548,6 +3548,17 @@ int vg_write(struct volume_group *vg)
lockd_vg_update(vg);
+ /*
+ * This tells lvmetad the new seqno it should expect to receive
+ * the metadata for after the commit. The cached VG will be
+ * invalid in lvmetad until this command sends the new metadata
+ * after it's committed.
+ */
+ if (!lvmetad_vg_update_pending(vg)) {
+ log_error("Failed to prepare new VG metadata in lvmetad cache.");
+ return 0;
+ }
+
return 1;
}
@@ -3598,10 +3609,6 @@ int vg_commit(struct volume_group *vg)
return cache_updated;
}
- /* Skip if we already did this in vg_write */
- if ((vg->fid->fmt->features & FMT_PRECOMMIT) && !lvmetad_vg_update(vg))
- return_0;
-
cache_updated = _vg_commit_mdas(vg);
set_vg_notify(vg->cmd);
@@ -3641,6 +3648,14 @@ void vg_revert(struct volume_group *vg)
struct metadata_area *mda;
struct lv_list *lvl;
+ /*
+ * This will leave the cached copy in lvmetad INVALID (from
+ * lvmetad_vg_update_pending) and means the VG will be reread from disk
+ * to update the lvmetad copy, which is what we want to ensure that the
+ * cached copy is correct.
+ */
+ vg->lvmetad_update_pending = 0;
+
dm_list_iterate_items(lvl, &vg->lvs) {
if (lvl->lv->new_lock_args) {
lockd_free_lv(vg->cmd, vg, lvl->lv->name, &lvl->lv->lvid.id[1], lvl->lv->lock_args);
@@ -5465,7 +5480,7 @@ static struct volume_group *_recover_vg(struct cmd_context *cmd,
int consistent = 1;
struct volume_group *vg;
- unlock_vg(cmd, vg_name);
+ unlock_vg(cmd, NULL, vg_name);
dev_close_all();
@@ -5473,13 +5488,13 @@ static struct volume_group *_recover_vg(struct cmd_context *cmd,
return_NULL;
if (!(vg = vg_read_internal(cmd, vg_name, vgid, WARN_PV_READ, &consistent))) {
- unlock_vg(cmd, vg_name);
+ unlock_vg(cmd, NULL, vg_name);
return_NULL;
}
if (!consistent) {
release_vg(vg);
- unlock_vg(cmd, vg_name);
+ unlock_vg(cmd, NULL, vg_name);
return_NULL;
}
@@ -5825,7 +5840,7 @@ static struct volume_group *_vg_lock_and_read(struct cmd_context *cmd, const cha
bad:
if (!already_locked)
- unlock_vg(cmd, vg_name);
+ unlock_vg(cmd, vg, vg_name);
bad_no_unlock:
return _vg_make_handle(cmd, vg, failure);
@@ -5926,7 +5941,7 @@ uint32_t vg_lock_newname(struct cmd_context *cmd, const char *vgname)
* FIXME: Disallow calling this function if
* critical_section() is true.
*/
- unlock_vg(cmd, vgname);
+ unlock_vg(cmd, NULL, vgname);
return FAILED_LOCKING;
}
lvmcache_force_next_label_scan();
@@ -5939,7 +5954,7 @@ uint32_t vg_lock_newname(struct cmd_context *cmd, const char *vgname)
}
/* Found vgname so cannot reserve. */
- unlock_vg(cmd, vgname);
+ unlock_vg(cmd, NULL, vgname);
return FAILED_EXIST;
}
diff --git a/lib/metadata/pv_manip.c b/lib/metadata/pv_manip.c
index 567cede..5689a11 100644
--- a/lib/metadata/pv_manip.c
+++ b/lib/metadata/pv_manip.c
@@ -854,7 +854,7 @@ int pvremove_many(struct cmd_context *cmd, struct dm_list *pv_names,
}
out:
- unlock_vg(cmd, VG_ORPHANS);
+ unlock_vg(cmd, NULL, VG_ORPHANS);
if (pvslist)
dm_list_iterate_items(pvl, pvslist)
diff --git a/lib/metadata/replicator_manip.c b/lib/metadata/replicator_manip.c
index 5197b63..0501713 100644
--- a/lib/metadata/replicator_manip.c
+++ b/lib/metadata/replicator_manip.c
@@ -17,6 +17,7 @@
#include "metadata.h"
#include "segtype.h"
#include "toolcontext.h"
+#include "lvmetad.h"
/* Add lv as replicator_dev device */
int replicator_dev_add_rimage(struct replicator_device *rdev,
diff --git a/lib/metadata/vg.c b/lib/metadata/vg.c
index 7ac1a2c..01dcad9 100644
--- a/lib/metadata/vg.c
+++ b/lib/metadata/vg.c
@@ -20,6 +20,7 @@
#include "toolcontext.h"
#include "lvmcache.h"
#include "archiver.h"
+#include "lvmetad.h"
struct volume_group *alloc_vg(const char *pool_name, struct cmd_context *cmd,
const char *vg_name)
diff --git a/lib/metadata/vg.h b/lib/metadata/vg.h
index 069cdc8..4ce7151 100644
--- a/lib/metadata/vg.h
+++ b/lib/metadata/vg.h
@@ -51,6 +51,7 @@ struct volume_group {
uint32_t cmd_missing_vgs;/* Flag marks missing VG */
uint32_t seqno; /* Metadata sequence number */
unsigned skip_validate_lock_args : 1;
+ unsigned lvmetad_update_pending: 1;
/*
* The parsed committed (on-disk) copy of this VG; is NULL if this VG is committed
diff --git a/liblvm/lvm_pv.c b/liblvm/lvm_pv.c
index 4c40b8b..3dd8433 100644
--- a/liblvm/lvm_pv.c
+++ b/liblvm/lvm_pv.c
@@ -22,6 +22,7 @@
#include "locking.h"
#include "toolcontext.h"
#include "lvm_misc.h"
+#include "lvmetad.h"
struct lvm_pv_create_params
{
@@ -205,7 +206,7 @@ int lvm_list_pvs_free(struct dm_list *pvlist)
dm_list_iterate_items(pvl, &to_delete->pvslist)
free_pv_fid(pvl->pv);
- unlock_vg(to_delete->cmd, VG_GLOBAL);
+ unlock_vg(to_delete->cmd, NULL, VG_GLOBAL);
to_delete->magic = 0xA5A5A5A5;
restore_user_env(&e);
@@ -437,7 +438,7 @@ static int _pv_create(pv_create_params_t params)
if (!(pvcreate_vol(cmd, params->pv_name, ¶ms->pv_p, 1)))
rc = -1;
- unlock_vg(cmd, VG_ORPHANS);
+ unlock_vg(cmd, NULL, VG_ORPHANS);
return rc;
}
diff --git a/liblvm/lvm_vg.c b/liblvm/lvm_vg.c
index 8b3fc91..8f83230 100644
--- a/liblvm/lvm_vg.c
+++ b/liblvm/lvm_vg.c
@@ -22,6 +22,7 @@
#include "lvm_misc.h"
#include "lvm2app.h"
#include "display.h"
+#include "lvmetad.h"
int lvm_vg_add_tag(vg_t vg, const char *tag)
{
@@ -84,14 +85,14 @@ static int _lvm_vg_extend(vg_t vg, const char *device)
pvcreate_params_set_defaults(&pp);
if (!vg_extend(vg, 1, &device, &pp)) {
- unlock_vg(vg->cmd, VG_ORPHANS);
+ unlock_vg(vg->cmd, NULL, VG_ORPHANS);
return -1;
}
/*
* FIXME: Either commit to disk, or keep holding VG_ORPHANS and
* release in lvm_vg_close().
*/
- unlock_vg(vg->cmd, VG_ORPHANS);
+ unlock_vg(vg->cmd, NULL, VG_ORPHANS);
return 0;
}
@@ -165,7 +166,7 @@ static int _lvm_vg_write(vg_t vg)
/* FIXME: do pvremove / label_remove()? */
}
dm_list_init(&vg->removed_pvs);
- unlock_vg(vg->cmd, VG_ORPHANS);
+ unlock_vg(vg->cmd, NULL, VG_ORPHANS);
}
return 0;
diff --git a/tools/pvchange.c b/tools/pvchange.c
index e68e181..8c19268 100644
--- a/tools/pvchange.c
+++ b/tools/pvchange.c
@@ -255,7 +255,7 @@ int pvchange(struct cmd_context *cmd, int argc, char **argv)
ret = process_each_pv(cmd, argc, argv, NULL, 0, READ_FOR_UPDATE | READ_ALLOW_EXPORTED, handle, _pvchange_single);
if (!argc)
- unlock_vg(cmd, VG_GLOBAL);
+ unlock_vg(cmd, NULL, VG_GLOBAL);
log_print_unless_silent("%d physical volume%s changed / %d physical volume%s not changed",
params.done, params.done == 1 ? "" : "s",
diff --git a/tools/pvcreate.c b/tools/pvcreate.c
index fe6611f..e69eed4 100644
--- a/tools/pvcreate.c
+++ b/tools/pvcreate.c
@@ -156,7 +156,7 @@ int pvcreate(struct cmd_context *cmd, int argc, char **argv)
ret = ECMD_FAILED;
else {
/* pvcreate_each_device returns with orphans locked */
- unlock_vg(cmd, VG_ORPHANS);
+ unlock_vg(cmd, NULL, VG_ORPHANS);
ret = ECMD_PROCESSED;
}
diff --git a/tools/pvdisplay.c b/tools/pvdisplay.c
index 404e02b..5f033f3 100644
--- a/tools/pvdisplay.c
+++ b/tools/pvdisplay.c
@@ -112,7 +112,7 @@ int pvdisplay(struct cmd_context *cmd, int argc, char **argv)
NULL, _pvdisplay_single);
if (lock_global)
- unlock_vg(cmd, VG_GLOBAL);
+ unlock_vg(cmd, NULL, VG_GLOBAL);
return ret;
}
diff --git a/tools/pvremove.c b/tools/pvremove.c
index e262eb0..28c7b83 100644
--- a/tools/pvremove.c
+++ b/tools/pvremove.c
@@ -58,7 +58,7 @@ int pvremove(struct cmd_context *cmd, int argc, char **argv)
ret = ECMD_FAILED;
else {
/* pvcreate_each_device returns with orphans locked */
- unlock_vg(cmd, VG_ORPHANS);
+ unlock_vg(cmd, NULL, VG_ORPHANS);
ret = ECMD_PROCESSED;
}
diff --git a/tools/pvscan.c b/tools/pvscan.c
index c29401c..f5367e4 100644
--- a/tools/pvscan.c
+++ b/tools/pvscan.c
@@ -536,7 +536,7 @@ out:
if (!sync_local_dev_names(cmd))
stack;
- unlock_vg(cmd, VG_GLOBAL);
+ unlock_vg(cmd, NULL, VG_GLOBAL);
return ret;
}
@@ -654,7 +654,7 @@ int pvscan(struct cmd_context *cmd, int argc, char **argv)
params.new_pvs_found, display_size(cmd, params.size_new));
out:
- unlock_vg(cmd, VG_GLOBAL);
+ unlock_vg(cmd, NULL, VG_GLOBAL);
destroy_processing_handle(cmd, handle);
return ret;
diff --git a/tools/reporter.c b/tools/reporter.c
index 6f8ed8f..ad0a356 100644
--- a/tools/reporter.c
+++ b/tools/reporter.c
@@ -1171,7 +1171,7 @@ static int _do_report(struct cmd_context *cmd, struct processing_handle *handle,
dm_report_output(report_handle);
if (lock_global)
- unlock_vg(cmd, VG_GLOBAL);
+ unlock_vg(cmd, NULL, VG_GLOBAL);
out:
if (report_handle) {
if (report_in_group && !dm_report_group_pop(handle->report_group))
diff --git a/tools/toollib.c b/tools/toollib.c
index 4c24b16..35b687b 100644
--- a/tools/toollib.c
+++ b/tools/toollib.c
@@ -1962,7 +1962,7 @@ static int _process_vgnameid_list(struct cmd_context *cmd, uint32_t read_flags,
}
if (!vg_read_error(vg) && !already_locked)
- unlock_vg(cmd, vg_name);
+ unlock_vg(cmd, vg, vg_name);
endvg:
release_vg(vg);
if (!lockd_vg(cmd, vg_name, "un", 0, &lockd_state))
@@ -2826,7 +2826,7 @@ static int _process_lv_vgnameid_list(struct cmd_context *cmd, uint32_t read_flag
ret_max = ret;
if (!already_locked)
- unlock_vg(cmd, vg_name);
+ unlock_vg(cmd, vg, vg_name);
endvg:
release_vg(vg);
if (!lockd_vg(cmd, vg_name, "un", 0, &lockd_state))
@@ -3501,7 +3501,7 @@ static int _process_pvs_in_vgs(struct cmd_context *cmd, uint32_t read_flags,
ret_max = ret;
if (!skip && !already_locked)
- unlock_vg(cmd, vg->name);
+ unlock_vg(cmd, vg, vg->name);
endvg:
release_vg(vg);
if (!lockd_vg(cmd, vg_name, "un", 0, &lockd_state))
@@ -4654,7 +4654,7 @@ int pvcreate_each_device(struct cmd_context *cmd,
* the questions, reacquire the orphans lock, verify that the PVs were
* not used during the questions, then do the create steps.
*/
- unlock_vg(cmd, VG_ORPHANS);
+ unlock_vg(cmd, NULL, VG_ORPHANS);
/*
* Process prompts that require asking the user. The orphans lock is
@@ -4941,7 +4941,7 @@ do_command:
return 1;
bad:
- unlock_vg(cmd, VG_ORPHANS);
+ unlock_vg(cmd, NULL, VG_ORPHANS);
out:
return 0;
}
diff --git a/tools/vgcfgrestore.c b/tools/vgcfgrestore.c
index 8a60ab3..b5a2add 100644
--- a/tools/vgcfgrestore.c
+++ b/tools/vgcfgrestore.c
@@ -70,7 +70,7 @@ int vgcfgrestore(struct cmd_context *cmd, int argc, char **argv)
if (!lock_vol(cmd, VG_ORPHANS, LCK_VG_WRITE, NULL)) {
log_error("Unable to lock orphans");
- unlock_vg(cmd, vg_name);
+ unlock_vg(cmd, NULL, vg_name);
return ECMD_FAILED;
}
@@ -81,8 +81,8 @@ int vgcfgrestore(struct cmd_context *cmd, int argc, char **argv)
arg_str_value(cmd, file_ARG, ""),
arg_count(cmd, force_long_ARG)) :
backup_restore(cmd, vg_name, arg_count(cmd, force_long_ARG)))) {
- unlock_vg(cmd, VG_ORPHANS);
- unlock_vg(cmd, vg_name);
+ unlock_vg(cmd, NULL, VG_ORPHANS);
+ unlock_vg(cmd, NULL, vg_name);
log_error("Restore failed.");
ret = ECMD_FAILED;
goto rescan;
@@ -91,8 +91,8 @@ int vgcfgrestore(struct cmd_context *cmd, int argc, char **argv)
ret = ECMD_PROCESSED;
log_print_unless_silent("Restored volume group %s", vg_name);
- unlock_vg(cmd, VG_ORPHANS);
- unlock_vg(cmd, vg_name);
+ unlock_vg(cmd, NULL, VG_ORPHANS);
+ unlock_vg(cmd, NULL, vg_name);
rescan:
if (lvmetad_rescan) {
if (!lvmetad_connect(cmd)) {
diff --git a/tools/vgcreate.c b/tools/vgcreate.c
index 14e0d53..1a6a240 100644
--- a/tools/vgcreate.c
+++ b/tools/vgcreate.c
@@ -90,7 +90,7 @@ int vgcreate(struct cmd_context *cmd, int argc, char **argv)
* VG lock to be released, so the lvmcache destroy rule about locks
* seems to be unwarranted here.
*/
- unlock_vg(cmd, vp_new.vg_name);
+ unlock_vg(cmd, NULL, vp_new.vg_name);
if (!(handle = init_processing_handle(cmd, NULL))) {
log_error("Failed to initialize processing handle.");
@@ -181,8 +181,8 @@ int vgcreate(struct cmd_context *cmd, int argc, char **argv)
goto_bad;
}
- unlock_vg(cmd, VG_ORPHANS);
- unlock_vg(cmd, vp_new.vg_name);
+ unlock_vg(cmd, NULL, VG_ORPHANS);
+ unlock_vg(cmd, vg, vp_new.vg_name);
backup(vg);
@@ -222,8 +222,8 @@ out:
return ECMD_PROCESSED;
bad:
- unlock_vg(cmd, vp_new.vg_name);
- unlock_vg(cmd, VG_ORPHANS);
+ unlock_vg(cmd, vg, vp_new.vg_name);
+ unlock_vg(cmd, NULL, VG_ORPHANS);
release_vg(vg);
destroy_processing_handle(cmd, handle);
return ECMD_FAILED;
diff --git a/tools/vgextend.c b/tools/vgextend.c
index 4b2a13e..344dff0 100644
--- a/tools/vgextend.c
+++ b/tools/vgextend.c
@@ -204,6 +204,6 @@ int vgextend(struct cmd_context *cmd, int argc, char **argv)
destroy_processing_handle(cmd, handle);
if (!restoremissing)
- unlock_vg(cmd, VG_ORPHANS);
+ unlock_vg(cmd, NULL, VG_ORPHANS);
return ret;
}
diff --git a/tools/vgimportclone.c b/tools/vgimportclone.c
index 7028fbb..09b3a7c 100644
--- a/tools/vgimportclone.c
+++ b/tools/vgimportclone.c
@@ -333,9 +333,9 @@ retry_name:
ret = process_each_vg(cmd, 0, NULL, vp.old_vgname, NULL, READ_FOR_UPDATE | READ_ALLOW_EXPORTED, 0, handle, _vgimportclone_vg_single);
- unlock_vg(cmd, vp.new_vgname);
+ unlock_vg(cmd, NULL, vp.new_vgname);
out:
- unlock_vg(cmd, VG_GLOBAL);
+ unlock_vg(cmd, NULL, VG_GLOBAL);
internal_filter_clear();
init_internal_filtering(0);
lvmcache_lock_ordering(1);
diff --git a/tools/vgrename.c b/tools/vgrename.c
index 2006193..293f63c 100644
--- a/tools/vgrename.c
+++ b/tools/vgrename.c
@@ -161,7 +161,7 @@ static int _vgrename_single(struct cmd_context *cmd, const char *vg_name,
if (!backup_remove(cmd, vg_name))
stack;
- unlock_vg(cmd, vp->vg_name_new);
+ unlock_vg(cmd, vg, vp->vg_name_new);
vp->unlock_new_name = 0;
log_print_unless_silent("Volume group \"%s\" successfully renamed to \"%s\"",
@@ -169,7 +169,7 @@ static int _vgrename_single(struct cmd_context *cmd, const char *vg_name,
return 1;
error:
- unlock_vg(cmd, vp->vg_name_new);
+ unlock_vg(cmd, vg, vp->vg_name_new);
vp->unlock_new_name = 0;
lockd_rename_vg_final(cmd, vg, 0);
@@ -250,7 +250,7 @@ int vgrename(struct cmd_context *cmd, int argc, char **argv)
/* Needed if process_each_vg returns error before calling _single. */
if (vp.unlock_new_name)
- unlock_vg(cmd, vg_name_new);
+ unlock_vg(cmd, NULL, vg_name_new);
destroy_processing_handle(cmd, handle);
return ret;
diff --git a/tools/vgscan.c b/tools/vgscan.c
index e09724a..4deab73 100644
--- a/tools/vgscan.c
+++ b/tools/vgscan.c
@@ -125,6 +125,6 @@ int vgscan(struct cmd_context *cmd, int argc, char **argv)
maxret = ret;
}
- unlock_vg(cmd, VG_GLOBAL);
+ unlock_vg(cmd, NULL, VG_GLOBAL);
return maxret;
}
diff --git a/tools/vgsplit.c b/tools/vgsplit.c
index cb6b0ef..6114a72 100644
--- a/tools/vgsplit.c
+++ b/tools/vgsplit.c
@@ -653,6 +653,8 @@ int vgsplit(struct cmd_context *cmd, int argc, char **argv)
if (!vg_write(vg_to) || !vg_commit(vg_to))
goto_bad;
+ lvmetad_vg_update_finish(vg_to);
+
backup(vg_to);
/*
@@ -664,6 +666,8 @@ int vgsplit(struct cmd_context *cmd, int argc, char **argv)
if (!vg_write(vg_from) || !vg_commit(vg_from))
goto_bad;
+ lvmetad_vg_update_finish(vg_from);
+
backup(vg_from);
}
@@ -686,6 +690,8 @@ int vgsplit(struct cmd_context *cmd, int argc, char **argv)
if (!vg_write(vg_to) || !vg_commit(vg_to))
goto_bad;
+ lvmetad_vg_update_finish(vg_to);
+
backup(vg_to);
log_print_unless_silent("%s volume group \"%s\" successfully split from \"%s\"",
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=e6c376ee2dae4539…
Commit: e6c376ee2dae4539b1cc38ed6d9c5430777d2753
Parent: 8eebb4bfb901caa5330676697557943fdb9733a5
Author: David Teigland <teigland(a)redhat.com>
AuthorDate: Tue Jun 7 16:09:45 2016 -0500
Committer: David Teigland <teigland(a)redhat.com>
CommitterDate: Mon Jun 27 11:16:35 2016 -0500
lvmetad: remove unused code for other format types
lvmetad is no longer used at all with the lvm1 format,
so the text format is the only one that uses lvmetad.
---
lib/metadata/metadata.c | 7 -------
1 files changed, 0 insertions(+), 7 deletions(-)
diff --git a/lib/metadata/metadata.c b/lib/metadata/metadata.c
index 9b1fd31..e55463b 100644
--- a/lib/metadata/metadata.c
+++ b/lib/metadata/metadata.c
@@ -3546,13 +3546,6 @@ int vg_write(struct volume_group *vg)
if (!_vg_update_vg_precommitted(vg)) /* prepare precommited */
return_0;
- /*
- * If precommit is not supported, changes take effect immediately.
- * FIXME Replace with a more-accurate FMT_COMMIT flag.
- */
- if (!(vg->fid->fmt->features & FMT_PRECOMMIT) && !lvmetad_vg_update(vg))
- return_0;
-
lockd_vg_update(vg);
return 1;
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=8eebb4bfb901caa5…
Commit: 8eebb4bfb901caa5330676697557943fdb9733a5
Parent: 20f22a8bc0fa84d9abd09f580b93d53d37c4c361
Author: David Teigland <teigland(a)redhat.com>
AuthorDate: Mon Jun 27 11:10:58 2016 -0500
Committer: David Teigland <teigland(a)redhat.com>
CommitterDate: Mon Jun 27 11:10:58 2016 -0500
WHATS_NEW: add recent changes
---
WHATS_NEW | 6 ++++++
1 files changed, 6 insertions(+), 0 deletions(-)
diff --git a/WHATS_NEW b/WHATS_NEW
index 7238568..7a1f3cb 100644
--- a/WHATS_NEW
+++ b/WHATS_NEW
@@ -1,5 +1,11 @@
Version 2.02.158 -
=================================
+ Add a more efficient native vgimportclone command to replace the script.
+ Make lvmlockd always attempt to connect to lvmetad if no connection exists.
+ Let lvmetad handle new connections after shutdown signal.
+ Disable lvmetad when vgcfgrestore begins and enable it again after.
+ Make pvscan do activation if lvmetad is configured but not running.
+ Fix rescanning the PVs for a single VG when using lvmetad.
Pool metadata lvresize uses now same code as resize of normal volume.
Preserve monitoring status when updating thin-pool metadata.
Return 0 (inactive) when status cannot be queried in _lv_active().
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=20f22a8bc0fa84d9…
Commit: 20f22a8bc0fa84d9abd09f580b93d53d37c4c361
Parent: 6c86d942193e35077537753de91970afbcb0acdd
Author: David Teigland <teigland(a)redhat.com>
AuthorDate: Mon Jun 27 11:02:07 2016 -0500
Committer: David Teigland <teigland(a)redhat.com>
CommitterDate: Mon Jun 27 11:02:07 2016 -0500
lvmlockd: fix coverity report
---
daemons/lvmlockd/lvmlockd-core.c | 1 +
1 files changed, 1 insertions(+), 0 deletions(-)
diff --git a/daemons/lvmlockd/lvmlockd-core.c b/daemons/lvmlockd/lvmlockd-core.c
index f61939a..b561529 100644
--- a/daemons/lvmlockd/lvmlockd-core.c
+++ b/daemons/lvmlockd/lvmlockd-core.c
@@ -1031,6 +1031,7 @@ retry:
log_error("lvmetad_open reconnect error %d", err);
memset(&reply, 0, sizeof(reply));
reply.error = err;
+ va_end(ap);
return reply;
} else {
log_debug("lvmetad reconnected");
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=6c86d942193e3507…
Commit: 6c86d942193e35077537753de91970afbcb0acdd
Parent: 05196373bec81dcaad490a889388c57e7af1331a
Author: Peter Rajnoha <prajnoha(a)redhat.com>
AuthorDate: Mon Jun 27 14:27:43 2016 +0200
Committer: Peter Rajnoha <prajnoha(a)redhat.com>
CommitterDate: Mon Jun 27 14:33:28 2016 +0200
libdm: report: fix field width calculation when using dm_report_column_headings
This fixes commit 0ba5f4b8e977a6f2f45f95777da508b42d84c01a which moved
field recalculation (field width and sort position) from
dm_report_object to dm_report_output but it didn't handle the case when
dm_report_column_headings was used separately to report headings (before
dm_report_outpout call) and hence we ended up with intial widths for
fields in the headings.
If we're using dm_report_column_headings, we need to recalculate
fields if we haven't done so yet, the same way as we do in
dm_report_output.
---
libdm/libdm-report.c | 65 +++++++++++++++++++++++++++++++------------------
1 files changed, 41 insertions(+), 24 deletions(-)
diff --git a/libdm/libdm-report.c b/libdm/libdm-report.c
index ad03c6e..8993201 100644
--- a/libdm/libdm-report.c
+++ b/libdm/libdm-report.c
@@ -25,7 +25,8 @@
*/
#define RH_SORT_REQUIRED 0x00000100
#define RH_HEADINGS_PRINTED 0x00000200
-#define RH_ALREADY_REPORTED 0x00000400
+#define RH_FIELD_CALC_NEEDED 0x00000400
+#define RH_ALREADY_REPORTED 0x00000800
struct selection {
struct dm_pool *mem;
@@ -1282,6 +1283,8 @@ struct dm_report *dm_report_init(uint32_t *report_types,
if (output_flags & DM_REPORT_OUTPUT_BUFFERED)
rh->flags |= RH_SORT_REQUIRED;
+ rh->flags |= RH_FIELD_CALC_NEEDED;
+
dm_list_init(&rh->field_props);
dm_list_init(&rh->rows);
@@ -4032,6 +4035,7 @@ static void _reset_field_props(struct dm_report *rh)
struct field_properties *fp;
dm_list_iterate_items(fp, &rh->field_props)
fp->width = fp->initial_width;
+ rh->flags |= RH_FIELD_CALC_NEEDED;
}
int dm_report_set_selection(struct dm_report *rh, const char *selection)
@@ -4188,11 +4192,45 @@ static int _report_headings(struct dm_report *rh)
return 0;
}
+static int _should_display_row(struct row *row)
+{
+ return row->field_sel_status || row->selected;
+}
+
+static void _recalculate_fields(struct dm_report *rh)
+{
+ struct row *row;
+ struct dm_report_field *field;
+ size_t len;
+
+ dm_list_iterate_items(row, &rh->rows) {
+ dm_list_iterate_items(field, &row->fields) {
+ if ((rh->flags & RH_SORT_REQUIRED) &&
+ (field->props->flags & FLD_SORT_KEY)) {
+ (*row->sort_fields)[field->props->sort_posn] = field;
+ }
+
+ if (_should_display_row(row)) {
+ len = (int) strlen(field->report_string);
+ if ((len > field->props->width))
+ field->props->width = len;
+
+ }
+ }
+ }
+
+ rh->flags &= ~RH_FIELD_CALC_NEEDED;
+}
+
int dm_report_column_headings(struct dm_report *rh)
{
/* Columns-as-rows does not use _report_headings. */
if (rh->flags & DM_REPORT_OUTPUT_COLUMNS_AS_ROWS)
return 1;
+
+ if (rh->flags & RH_FIELD_CALC_NEEDED)
+ _recalculate_fields(rh);
+
return _report_headings(rh);
}
@@ -4246,11 +4284,6 @@ static int _row_compare(const void *a, const void *b)
return 0; /* Identical */
}
-static int _should_display_row(struct row *row)
-{
- return row->field_sel_status || row->selected;
-}
-
static int _sort_rows(struct dm_report *rh)
{
struct row *(*rows)[];
@@ -4701,9 +4734,6 @@ static int _print_basic_report_header(struct dm_report *rh)
int dm_report_output(struct dm_report *rh)
{
- struct row *row;
- struct dm_report_field *field;
- size_t len;
int r = 0;
if (_is_json_report(rh) &&
@@ -4715,21 +4745,8 @@ int dm_report_output(struct dm_report *rh)
goto out;
}
- dm_list_iterate_items(row, &rh->rows) {
- dm_list_iterate_items(field, &row->fields) {
- if ((rh->flags & RH_SORT_REQUIRED) &&
- (field->props->flags & FLD_SORT_KEY)) {
- (*row->sort_fields)[field->props->sort_posn] = field;
- }
-
- if (_should_display_row(row)) {
- len = (int) strlen(field->report_string);
- if ((len > field->props->width))
- field->props->width = len;
-
- }
- }
- }
+ if (rh->flags & RH_FIELD_CALC_NEEDED)
+ _recalculate_fields(rh);
if ((rh->flags & RH_SORT_REQUIRED))
_sort_rows(rh);
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=05196373bec81dca…
Commit: 05196373bec81dcaad490a889388c57e7af1331a
Parent: 82f4f073bb7eb68aa7cb23a0c6ee75ba03fd0e57
Author: Peter Rajnoha <prajnoha(a)redhat.com>
AuthorDate: Mon Jun 27 10:14:17 2016 +0200
Committer: Peter Rajnoha <prajnoha(a)redhat.com>
CommitterDate: Mon Jun 27 11:26:38 2016 +0200
reporter: simplify --configreport handling for -S|--select and fix an issue reported by coverity
Simplify code around _do_get_report_selection - remove "expected_idxs[]"
argument which is superfluous and add "allow_single" switch instead to
allow for recognition of "--configreport <report_name> -S" as well as
single "-S" if needed.
Null pointer dereferences (FORWARD_NULL) /safe/guest2/covscan/LVM2.2.02.158/tools/reporter.c: 961 in _do_report_get_selection()
Null pointer dereferences (FORWARD_NULL) Dereferencing null pointer "single_args".
---
lib/report/report.h | 2 +-
tools/reporter.c | 60 +++++++++++++++++++++++----------------------------
tools/toollib.c | 2 +-
3 files changed, 29 insertions(+), 35 deletions(-)
diff --git a/lib/report/report.h b/lib/report/report.h
index b9028fe..ba3a8fa 100644
--- a/lib/report/report.h
+++ b/lib/report/report.h
@@ -90,7 +90,7 @@ void *report_init(struct cmd_context *cmd, const char *format, const char *keys,
int aligned, int buffered, int headings, int field_prefixes,
int quoted, int columns_as_rows, const char *selection,
int multiple_output);
-int report_get_single_selection(struct cmd_context *cmd, const char **selection);
+int report_get_single_selection(struct cmd_context *cmd, report_type_t report_type, const char **selection);
void *report_init_for_selection(struct cmd_context *cmd, report_type_t *report_type,
const char *selection);
int report_get_prefix_and_desc(report_type_t report_type_id,
diff --git a/tools/reporter.c b/tools/reporter.c
index 40d449c..6f8ed8f 100644
--- a/tools/reporter.c
+++ b/tools/reporter.c
@@ -29,6 +29,8 @@ typedef enum {
REPORT_IDX_COUNT
} report_idx_t;
+#define REPORT_IDX_FULL_START REPORT_IDX_FULL_VGS
+
struct single_report_args {
report_type_t report_type;
char report_prefix[32];
@@ -748,12 +750,10 @@ static report_idx_t _get_report_idx_from_name(report_type_t report_type, const c
return REPORT_IDX_NULL;
/* Change to basic report type for comparison. */
- if (report_type == LABEL)
+ if ((report_type == LABEL) || (report_type == PVSEGS))
report_type = PVS;
else if (report_type == SEGS)
report_type = LVS;
- else if (report_type == PVSEGS)
- report_type = PVSEGS;
if (!strcasecmp(name, "log"))
idx = REPORT_IDX_LOG;
@@ -778,11 +778,11 @@ static report_idx_t _get_report_idx_from_name(report_type_t report_type, const c
return idx;
}
-static int _should_process_report_idx(report_type_t report_type, report_idx_t idx)
+static int _should_process_report_idx(report_type_t report_type, int allow_single, report_idx_t idx)
{
if (((idx == REPORT_IDX_LOG) && (report_type != CMDLOG)) ||
- ((idx == REPORT_IDX_SINGLE) && ((report_type == FULL) || (report_type == CMDLOG))) ||
- ((idx > REPORT_IDX_LOG) && report_type != FULL))
+ ((idx == REPORT_IDX_SINGLE) && !allow_single) ||
+ ((idx >= REPORT_IDX_FULL_START) && report_type != FULL))
return 0;
return 1;
@@ -867,7 +867,7 @@ static int _get_report_options(struct cmd_context *cmd,
action = OPTS_REPLACE;
}
- if (!_should_process_report_idx(single_args->report_type, idx))
+ if (!_should_process_report_idx(single_args->report_type, !(single_args->report_type & (CMDLOG | FULL)), idx))
continue;
if ((action != OPTS_COMPACT) &&
@@ -932,6 +932,9 @@ static int _get_report_keys(struct cmd_context *cmd,
goto_out;
}
+ if (!_should_process_report_idx(single_args->report_type, !(single_args->report_type & (CMDLOG | FULL)), idx))
+ continue;
+
args->single_args[idx].keys = grouped_arg_str_value(current_group->arg_values, sort_ARG, NULL);
}
@@ -941,16 +944,15 @@ out:
}
static int _do_report_get_selection(struct cmd_context *cmd,
+ report_type_t report_type,
+ int allow_single,
struct report_args *args,
- struct single_report_args *single_args,
- report_idx_t expected_idxs[],
- const char **ret_selection)
+ const char **last_selection)
{
struct arg_value_group_list *current_group;
- const char *final_selection = "", *selection = NULL;
+ const char *final_selection = NULL, *selection = NULL;
const char *report_name = NULL;
report_idx_t idx = REPORT_IDX_SINGLE;
- int i;
dm_list_iterate_items(current_group, &cmd->arg_value_groups) {
if (!grouped_arg_is_set(current_group->arg_values, select_ARG))
@@ -958,27 +960,21 @@ static int _do_report_get_selection(struct cmd_context *cmd,
if (grouped_arg_is_set(current_group->arg_values, configreport_ARG)) {
report_name = grouped_arg_str_value(current_group->arg_values, configreport_ARG, NULL);
- if ((idx = _get_report_idx_from_name(single_args->report_type, report_name)) == REPORT_IDX_NULL)
+ if ((idx = _get_report_idx_from_name(report_type, report_name)) == REPORT_IDX_NULL)
return_0;
}
selection = grouped_arg_str_value(current_group->arg_values, select_ARG, NULL);
- if (single_args) {
- if (!_should_process_report_idx(single_args->report_type, idx))
- continue;
+ if (!_should_process_report_idx(report_type, allow_single, idx))
+ continue;
+ if (args)
args->single_args[idx].selection = selection;
- final_selection = selection;
- } else {
- for (i = 0; expected_idxs[i] != REPORT_IDX_NULL; i++) {
- if (idx == expected_idxs[i])
- final_selection = selection;
- }
- }
+ final_selection = selection;
}
- if (ret_selection)
- *ret_selection = final_selection;
+ if (last_selection)
+ *last_selection = final_selection;
return 1;
}
@@ -987,13 +983,13 @@ static int _get_report_selection(struct cmd_context *cmd,
struct report_args *args,
struct single_report_args *single_args)
{
- return _do_report_get_selection(cmd, args, single_args, NULL, NULL) ? ECMD_PROCESSED : ECMD_FAILED;
+ return _do_report_get_selection(cmd, single_args->report_type, !(single_args->report_type & (CMDLOG | FULL)),
+ args, NULL) ? ECMD_PROCESSED : ECMD_FAILED;
}
-int report_get_single_selection(struct cmd_context *cmd, const char **selection)
+int report_get_single_selection(struct cmd_context *cmd, report_type_t report_type, const char **selection)
{
- report_idx_t expected_idxs[] = {REPORT_IDX_SINGLE, REPORT_IDX_NULL};
- return _do_report_get_selection(cmd, NULL, NULL, expected_idxs, selection);
+ return _do_report_get_selection(cmd, report_type, 1, NULL, selection);
}
static int _set_report_prefix_and_name(struct report_args *args,
@@ -1525,9 +1521,8 @@ bad:
int lastlog(struct cmd_context *cmd, int argc, char **argv)
{
- static report_idx_t expected_idxs[] = {REPORT_IDX_SINGLE, REPORT_IDX_LOG, REPORT_IDX_NULL};
struct dm_report_group *report_group = NULL;
- const char *selection = NULL;
+ const char *selection;
int r = ECMD_FAILED;
if (!cmd->log_rh) {
@@ -1538,8 +1533,7 @@ int lastlog(struct cmd_context *cmd, int argc, char **argv)
if (!report_format_init(cmd, NULL, &report_group, &cmd->log_rh, NULL, NULL))
goto_out;
- if (arg_is_set(cmd, select_ARG) &&
- !_do_report_get_selection(cmd, NULL, NULL, expected_idxs, &selection))
+ if (!_do_report_get_selection(cmd, CMDLOG, 1, NULL, &selection))
goto_out;
if (!dm_report_set_selection(cmd->log_rh, selection)) {
diff --git a/tools/toollib.c b/tools/toollib.c
index 80d0f32..4c24b16 100644
--- a/tools/toollib.c
+++ b/tools/toollib.c
@@ -1771,7 +1771,7 @@ int init_selection_handle(struct cmd_context *cmd, struct processing_handle *han
return 0;
}
- if (!report_get_single_selection(cmd, &selection))
+ if (!report_get_single_selection(cmd, initial_report_type, &selection))
return_0;
sh->report_type = initial_report_type;
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=82f4f073bb7eb68a…
Commit: 82f4f073bb7eb68aa7cb23a0c6ee75ba03fd0e57
Parent: 15b932a70e4a29f386ea57e1b845d637780b463b
Author: Peter Rajnoha <prajnoha(a)redhat.com>
AuthorDate: Mon Jun 27 10:12:41 2016 +0200
Committer: Peter Rajnoha <prajnoha(a)redhat.com>
CommitterDate: Mon Jun 27 11:22:29 2016 +0200
coverity: fix issues detected in recent code
Uninitialized variables (UNINIT) /safe/guest2/covscan/LVM2.2.02.158/tools/toollib.c: 3520 in _process_pvs_in_vgs()
Uninitialized variables (UNINIT) Using uninitialized value "do_report_ret_code".
Null pointer dereferences (REVERSE_INULL) /safe/guest2/covscan/LVM2.2.02.158/libdm/libdm-report.c: 4745 in dm_report_output()
Null pointer dereferences (REVERSE_INULL) Null-checking "rh" suggests that it may be null, but it has already been dereferenced on all paths leading to the check.
Incorrect expression (MISSING_COMMA) /safe/guest2/covscan/LVM2.2.02.158/lib/log/log.c: 280 in _get_log_level_name()
Incorrect expression (MISSING_COMMA) In the initialization of "log_level_names", a suspicious concatenated string ""noticeinfo"" is produced.
Null pointer dereferences (FORWARD_NULL) /safe/guest2/covscan/LVM2.2.02.158/tools/reporter.c: 816 in_get_report_options()
Null pointer dereferences (FORWARD_NULL) Comparing "mem" to null implies that "mem" might be null.
---
lib/log/log.c | 2 +-
libdm/libdm-report.c | 4 ++--
tools/reporter.c | 2 +-
tools/toollib.c | 2 +-
4 files changed, 5 insertions(+), 5 deletions(-)
diff --git a/lib/log/log.c b/lib/log/log.c
index b3453dc..30d71ef 100644
--- a/lib/log/log.c
+++ b/lib/log/log.c
@@ -277,7 +277,7 @@ static const char *_get_log_level_name(int use_stderr, int level)
"fatal", /* _LOG_FATAL */
"error", /* _LOG_ERROR */
"warn", /* _LOG_WARN */
- "notice" /* _LOG_NOTICE */
+ "notice",/* _LOG_NOTICE */
"info", /* _LOG_INFO */
"debug" /* _LOG_DEBUG */
};
diff --git a/libdm/libdm-report.c b/libdm/libdm-report.c
index 6bea34c..ad03c6e 100644
--- a/libdm/libdm-report.c
+++ b/libdm/libdm-report.c
@@ -4001,7 +4001,7 @@ static int _report_set_selection(struct dm_report *rh, const char *selection, in
goto_bad;
}
- if (!selection || !strcasecmp(selection, SPECIAL_SELECTION_ALL))
+ if (!selection || !selection[0] || !strcasecmp(selection, SPECIAL_SELECTION_ALL))
return 1;
rh->selection->add_new_fields = add_new_fields;
@@ -4742,7 +4742,7 @@ int dm_report_output(struct dm_report *rh)
else
r = _output_as_columns(rh);
out:
- if (r && rh && rh->group_item)
+ if (r && rh->group_item)
rh->group_item->output_done = 1;
return r;
}
diff --git a/tools/reporter.c b/tools/reporter.c
index ee2d251..40d449c 100644
--- a/tools/reporter.c
+++ b/tools/reporter.c
@@ -815,7 +815,7 @@ static int _get_report_options(struct cmd_context *cmd,
if (!(mem = dm_pool_create("report_options", 128))) {
log_error("Failed to create temporary mempool to process report options.");
- goto out;
+ return ECMD_FAILED;
}
if (single_args->report_type == CMDLOG) {
diff --git a/tools/toollib.c b/tools/toollib.c
index 5c61ddd..80d0f32 100644
--- a/tools/toollib.c
+++ b/tools/toollib.c
@@ -3439,7 +3439,7 @@ static int _process_pvs_in_vgs(struct cmd_context *cmd, uint32_t read_flags,
int skip;
int notfound;
int already_locked;
- int do_report_ret_code;
+ int do_report_ret_code = 1;
log_set_report_object_type(LOG_REPORT_OBJECT_TYPE_VG);
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=15b932a70e4a29f3…
Commit: 15b932a70e4a29f386ea57e1b845d637780b463b
Parent: d914151591dab4ac924fe3b72fb296bc66f2e51c
Author: Alasdair G Kergon <agk(a)redhat.com>
AuthorDate: Sat Jun 25 19:59:49 2016 +0100
Committer: Alasdair G Kergon <agk(a)redhat.com>
CommitterDate: Sat Jun 25 19:59:49 2016 +0100
doc: Resync kernel docs.
---
doc/kernel/cache-policies.txt | 102 +++++++++++++++++++++++--------------
doc/kernel/cache.txt | 15 +++++-
doc/kernel/delay.txt | 1 +
doc/kernel/raid.txt | 33 ++++++++++++
doc/kernel/snapshot.txt | 10 +++-
doc/kernel/statistics.txt | 47 ++++++++++++++++--
doc/kernel/thin-provisioning.txt | 9 +++-
doc/kernel/verity.txt | 40 ++++++++++++++-
8 files changed, 205 insertions(+), 52 deletions(-)
diff --git a/doc/kernel/cache-policies.txt b/doc/kernel/cache-policies.txt
index 0d124a9..d3ca8af 100644
--- a/doc/kernel/cache-policies.txt
+++ b/doc/kernel/cache-policies.txt
@@ -11,7 +11,7 @@ Every bio that is mapped by the target is referred to the policy.
The policy can return a simple HIT or MISS or issue a migration.
Currently there's no way for the policy to issue background work,
-e.g. to start writing back dirty blocks that are going to be evicte
+e.g. to start writing back dirty blocks that are going to be evicted
soon.
Because we map bios, rather than requests it's easy for the policy
@@ -25,53 +25,77 @@ trying to see when the io scheduler has let the ios run.
Overview of supplied cache replacement policies
===============================================
-multiqueue
-----------
+multiqueue (mq)
+---------------
-This policy is the default.
-
-The multiqueue policy has three sets of 16 queues: one set for entries
-waiting for the cache and another two for those in the cache (a set for
-clean entries and a set for dirty entries).
+This policy is now an alias for smq (see below).
-Cache entries in the queues are aged based on logical time. Entry into
-the cache is based on variable thresholds and queue selection is based
-on hit count on entry. The policy aims to take different cache miss
-costs into account and to adjust to varying load patterns automatically.
+The following tunables are accepted, but have no effect:
-Message and constructor argument pairs are:
'sequential_threshold <#nr_sequential_ios>'
'random_threshold <#nr_random_ios>'
'read_promote_adjustment <value>'
'write_promote_adjustment <value>'
'discard_promote_adjustment <value>'
-The sequential threshold indicates the number of contiguous I/Os
-required before a stream is treated as sequential. Once a stream is
-considered sequential it will bypass the cache. The random threshold
-is the number of intervening non-contiguous I/Os that must be seen
-before the stream is treated as random again.
-
-The sequential and random thresholds default to 512 and 4 respectively.
-
-Large, sequential I/Os are probably better left on the origin device
-since spindles tend to have good sequential I/O bandwidth. The
-io_tracker counts contiguous I/Os to try to spot when the I/O is in one
-of these sequential modes. But there are use-cases for wanting to
-promote sequential blocks to the cache (e.g. fast application startup).
-If sequential threshold is set to 0 the sequential I/O detection is
-disabled and sequential I/O will no longer implicitly bypass the cache.
-Setting the random threshold to 0 does _not_ disable the random I/O
-stream detection.
-
-Internally the mq policy determines a promotion threshold. If the hit
-count of a block not in the cache goes above this threshold it gets
-promoted to the cache. The read, write and discard promote adjustment
-tunables allow you to tweak the promotion threshold by adding a small
-value based on the io type. They default to 4, 8 and 1 respectively.
-If you're trying to quickly warm a new cache device you may wish to
-reduce these to encourage promotion. Remember to switch them back to
-their defaults after the cache fills though.
+Stochastic multiqueue (smq)
+---------------------------
+
+This policy is the default.
+
+The stochastic multi-queue (smq) policy addresses some of the problems
+with the multiqueue (mq) policy.
+
+The smq policy (vs mq) offers the promise of less memory utilization,
+improved performance and increased adaptability in the face of changing
+workloads. smq also does not have any cumbersome tuning knobs.
+
+Users may switch from "mq" to "smq" simply by appropriately reloading a
+DM table that is using the cache target. Doing so will cause all of the
+mq policy's hints to be dropped. Also, performance of the cache may
+degrade slightly until smq recalculates the origin device's hotspots
+that should be cached.
+
+Memory usage:
+The mq policy used a lot of memory; 88 bytes per cache block on a 64
+bit machine.
+
+smq uses 28bit indexes to implement it's data structures rather than
+pointers. It avoids storing an explicit hit count for each block. It
+has a 'hotspot' queue, rather than a pre-cache, which uses a quarter of
+the entries (each hotspot block covers a larger area than a single
+cache block).
+
+All this means smq uses ~25bytes per cache block. Still a lot of
+memory, but a substantial improvement nontheless.
+
+Level balancing:
+mq placed entries in different levels of the multiqueue structures
+based on their hit count (~ln(hit count)). This meant the bottom
+levels generally had the most entries, and the top ones had very
+few. Having unbalanced levels like this reduced the efficacy of the
+multiqueue.
+
+smq does not maintain a hit count, instead it swaps hit entries with
+the least recently used entry from the level above. The overall
+ordering being a side effect of this stochastic process. With this
+scheme we can decide how many entries occupy each multiqueue level,
+resulting in better promotion/demotion decisions.
+
+Adaptability:
+The mq policy maintained a hit count for each cache block. For a
+different block to get promoted to the cache it's hit count has to
+exceed the lowest currently in the cache. This meant it could take a
+long time for the cache to adapt between varying IO patterns.
+
+smq doesn't maintain hit counts, so a lot of this problem just goes
+away. In addition it tracks performance of the hotspot queue, which
+is used to decide which blocks to promote. If the hotspot queue is
+performing badly then it starts moving entries more quickly between
+levels. This lets it adapt to new IO patterns very quickly.
+
+Performance:
+Testing smq shows substantially better performance than mq.
cleaner
-------
diff --git a/doc/kernel/cache.txt b/doc/kernel/cache.txt
index 68c0f51..785eab8 100644
--- a/doc/kernel/cache.txt
+++ b/doc/kernel/cache.txt
@@ -221,6 +221,7 @@ Status
<#read hits> <#read misses> <#write hits> <#write misses>
<#demotions> <#promotions> <#dirty> <#features> <features>*
<#core args> <core args>* <policy name> <#policy args> <policy args>*
+<cache metadata mode>
metadata block size : Fixed block size for each metadata block in
sectors
@@ -251,8 +252,18 @@ core args : Key/value pairs for tuning the core
e.g. migration_threshold
policy name : Name of the policy
#policy args : Number of policy arguments to follow (must be even)
-policy args : Key/value pairs
- e.g. sequential_threshold
+policy args : Key/value pairs e.g. sequential_threshold
+cache metadata mode : ro if read-only, rw if read-write
+ In serious cases where even a read-only mode is deemed unsafe
+ no further I/O will be permitted and the status will just
+ contain the string 'Fail'. The userspace recovery tools
+ should then be used.
+needs_check : 'needs_check' if set, '-' if not set
+ A metadata operation has failed, resulting in the needs_check
+ flag being set in the metadata's superblock. The metadata
+ device must be deactivated and checked/repaired before the
+ cache can be made fully operational again. '-' indicates
+ needs_check is not set.
Messages
--------
diff --git a/doc/kernel/delay.txt b/doc/kernel/delay.txt
index 15adc55..a07b592 100644
--- a/doc/kernel/delay.txt
+++ b/doc/kernel/delay.txt
@@ -8,6 +8,7 @@ Parameters:
<device> <offset> <delay> [<write_device> <write_offset> <write_delay>]
With separate write parameters, the first set is only used for reads.
+Offsets are specified in sectors.
Delays are specified in milliseconds.
Example scripts
diff --git a/doc/kernel/raid.txt b/doc/kernel/raid.txt
index ef8ba9f..df2d636 100644
--- a/doc/kernel/raid.txt
+++ b/doc/kernel/raid.txt
@@ -209,6 +209,37 @@ include:
"repair" - Initiate a repair of the array.
"reshape"- Currently unsupported (-EINVAL).
+
+Discard Support
+---------------
+The implementation of discard support among hardware vendors varies.
+When a block is discarded, some storage devices will return zeroes when
+the block is read. These devices set the 'discard_zeroes_data'
+attribute. Other devices will return random data. Confusingly, some
+devices that advertise 'discard_zeroes_data' will not reliably return
+zeroes when discarded blocks are read! Since RAID 4/5/6 uses blocks
+from a number of devices to calculate parity blocks and (for performance
+reasons) relies on 'discard_zeroes_data' being reliable, it is important
+that the devices be consistent. Blocks may be discarded in the middle
+of a RAID 4/5/6 stripe and if subsequent read results are not
+consistent, the parity blocks may be calculated differently at any time;
+making the parity blocks useless for redundancy. It is important to
+understand how your hardware behaves with discards if you are going to
+enable discards with RAID 4/5/6.
+
+Since the behavior of storage devices is unreliable in this respect,
+even when reporting 'discard_zeroes_data', by default RAID 4/5/6
+discard support is disabled -- this ensures data integrity at the
+expense of losing some performance.
+
+Storage devices that properly support 'discard_zeroes_data' are
+increasingly whitelisted in the kernel and can thus be trusted.
+
+For trusted devices, the following dm-raid module parameter can be set
+to safely enable discard support for RAID 4/5/6:
+ 'devices_handle_discards_safely'
+
+
Version History
---------------
1.0.0 Initial version. Support for RAID 4/5/6
@@ -224,3 +255,5 @@ Version History
New status (STATUSTYPE_INFO) fields: sync_action and mismatch_cnt.
1.5.1 Add ability to restore transiently failed devices on resume.
1.5.2 'mismatch_cnt' is zero unless [last_]sync_action is "check".
+1.6.0 Add discard support (and devices_handle_discard_safely module param).
+1.7.0 Add support for MD RAID0 mappings.
diff --git a/doc/kernel/snapshot.txt b/doc/kernel/snapshot.txt
index 0d5bc46..ad6949b 100644
--- a/doc/kernel/snapshot.txt
+++ b/doc/kernel/snapshot.txt
@@ -41,9 +41,13 @@ useless and be disabled, returning errors. So it is important to monitor
the amount of free space and expand the <COW device> before it fills up.
<persistent?> is P (Persistent) or N (Not persistent - will not survive
-after reboot).
-The difference is that for transient snapshots less metadata must be
-saved on disk - they can be kept in memory by the kernel.
+after reboot). O (Overflow) can be added as a persistent store option
+to allow userspace to advertise its support for seeing "Overflow" in the
+snapshot status. So supported store types are "P", "PO" and "N".
+
+The difference between persistent and transient is with transient
+snapshots less metadata must be saved on disk - they can be kept in
+memory by the kernel.
* snapshot-merge <origin> <COW device> <persistent> <chunksize>
diff --git a/doc/kernel/statistics.txt b/doc/kernel/statistics.txt
index 2a1673a..170ac02 100644
--- a/doc/kernel/statistics.txt
+++ b/doc/kernel/statistics.txt
@@ -13,9 +13,14 @@ the range specified.
The I/O statistics counters for each step-sized area of a region are
in the same format as /sys/block/*/stat or /proc/diskstats (see:
Documentation/iostats.txt). But two extra counters (12 and 13) are
-provided: total time spent reading and writing in milliseconds. All
-these counters may be accessed by sending the @stats_print message to
-the appropriate DM device via dmsetup.
+provided: total time spent reading and writing. When the histogram
+argument is used, the 14th parameter is reported that represents the
+histogram of latencies. All these counters may be accessed by sending
+the @stats_print message to the appropriate DM device via dmsetup.
+
+The reported times are in milliseconds and the granularity depends on
+the kernel ticks. When the option precise_timestamps is used, the
+reported times are in nanoseconds.
Each region has a corresponding unique identifier, which we call a
region_id, that is assigned when the region is created. The region_id
@@ -33,7 +38,9 @@ memory is used by reading
Messages
========
- @stats_create <range> <step> [<program_id> [<aux_data>]]
+ @stats_create <range> <step>
+ [<number_of_optional_arguments> <optional_arguments>...]
+ [<program_id> [<aux_data>]]
Create a new region and return the region_id.
@@ -48,6 +55,29 @@ Messages
"/<number_of_areas>" - the range is subdivided into the specified
number of areas.
+ <number_of_optional_arguments>
+ The number of optional arguments
+
+ <optional_arguments>
+ The following optional arguments are supported
+ precise_timestamps - use precise timer with nanosecond resolution
+ instead of the "jiffies" variable. When this argument is
+ used, the resulting times are in nanoseconds instead of
+ milliseconds. Precise timestamps are a little bit slower
+ to obtain than jiffies-based timestamps.
+ histogram:n1,n2,n3,n4,... - collect histogram of latencies. The
+ numbers n1, n2, etc are times that represent the boundaries
+ of the histogram. If precise_timestamps is not used, the
+ times are in milliseconds, otherwise they are in
+ nanoseconds. For each range, the kernel will report the
+ number of requests that completed within this range. For
+ example, if we use "histogram:10,20,30", the kernel will
+ report four numbers a:b:c:d. a is the number of requests
+ that took 0-10 ms to complete, b is the number of requests
+ that took 10-20 ms to complete, c is the number of requests
+ that took 20-30 ms to complete and d is the number of
+ requests that took more than 30 ms to complete.
+
<program_id>
An optional parameter. A name that uniquely identifies
the userspace owner of the range. This groups ranges together
@@ -55,6 +85,9 @@ Messages
created and ignore those created by others.
The kernel returns this string back in the output of
@stats_list message, but it doesn't use it for anything else.
+ If we omit the number of optional arguments, program id must not
+ be a number, otherwise it would be interpreted as the number of
+ optional arguments.
<aux_data>
An optional parameter. A word that provides auxiliary data
@@ -88,6 +121,10 @@ Messages
Output format:
<region_id>: <start_sector>+<length> <step> <program_id> <aux_data>
+ precise_timestamps histogram:n1,n2,n3,...
+
+ The strings "precise_timestamps" and "histogram" are printed only
+ if they were specified when creating the region.
@stats_print <region_id> [<starting_line> <number_of_lines>]
@@ -168,7 +205,7 @@ statistics on them:
dmsetup message vol 0 @stats_create - /100
-Set the auxillary data string to "foo bar baz" (the escape for each
+Set the auxiliary data string to "foo bar baz" (the escape for each
space must also be escaped, otherwise the shell will consume them):
dmsetup message vol 0 @stats_set_aux 0 foo\\ bar\\ baz
diff --git a/doc/kernel/thin-provisioning.txt b/doc/kernel/thin-provisioning.txt
index 4f67578..1699a55 100644
--- a/doc/kernel/thin-provisioning.txt
+++ b/doc/kernel/thin-provisioning.txt
@@ -296,7 +296,7 @@ ii) Status
underlying device. When this is enabled when loading the table,
it can get disabled if the underlying device doesn't support it.
- ro|rw
+ ro|rw|out_of_data_space
If the pool encounters certain types of device failures it will
drop into a read-only metadata mode in which no changes to
the pool metadata (like allocating new blocks) are permitted.
@@ -314,6 +314,13 @@ ii) Status
module parameter can be used to change this timeout -- it
defaults to 60 seconds but may be disabled using a value of 0.
+ needs_check
+ A metadata operation has failed, resulting in the needs_check
+ flag being set in the metadata's superblock. The metadata
+ device must be deactivated and checked/repaired before the
+ thin-pool can be made fully operational again. '-' indicates
+ needs_check is not set.
+
iii) Messages
create_thin <dev id>
diff --git a/doc/kernel/verity.txt b/doc/kernel/verity.txt
index e15bc1a..89fd8f9 100644
--- a/doc/kernel/verity.txt
+++ b/doc/kernel/verity.txt
@@ -18,11 +18,11 @@ Construction Parameters
0 is the original format used in the Chromium OS.
The salt is appended when hashing, digests are stored continuously and
- the rest of the block is padded with zeros.
+ the rest of the block is padded with zeroes.
1 is the current format that should be used for new devices.
The salt is prepended when hashing and each digest is
- padded with zeros to the power of two.
+ padded with zeroes to the power of two.
<dev>
This is the device containing data, the integrity of which needs to be
@@ -79,6 +79,37 @@ restart_on_corruption
not compatible with ignore_corruption and requires user space support to
avoid restart loops.
+ignore_zero_blocks
+ Do not verify blocks that are expected to contain zeroes and always return
+ zeroes instead. This may be useful if the partition contains unused blocks
+ that are not guaranteed to contain zeroes.
+
+use_fec_from_device <fec_dev>
+ Use forward error correction (FEC) to recover from corruption if hash
+ verification fails. Use encoding data from the specified device. This
+ may be the same device where data and hash blocks reside, in which case
+ fec_start must be outside data and hash areas.
+
+ If the encoding data covers additional metadata, it must be accessible
+ on the hash device after the hash blocks.
+
+ Note: block sizes for data and hash devices must match. Also, if the
+ verity <dev> is encrypted the <fec_dev> should be too.
+
+fec_roots <num>
+ Number of generator roots. This equals to the number of parity bytes in
+ the encoding data. For example, in RS(M, N) encoding, the number of roots
+ is M-N.
+
+fec_blocks <num>
+ The number of encoding data blocks on the FEC device. The block size for
+ the FEC device is <data_block_size>.
+
+fec_start <offset>
+ This is the offset, in <data_block_size> blocks, from the start of the
+ FEC device to the beginning of the encoding data.
+
+
Theory of operation
===================
@@ -98,6 +129,11 @@ per-block basis. This allows for a lightweight hash computation on first read
into the page cache. Block hashes are stored linearly, aligned to the nearest
block size.
+If forward error correction (FEC) support is enabled any recovery of
+corrupted data will be verified using the cryptographic hash of the
+corresponding data. This is why combining error correction with
+integrity checking is essential.
+
Hash Tree
---------
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=d914151591dab4ac…
Commit: d914151591dab4ac924fe3b72fb296bc66f2e51c
Parent: a910052a2e7da4531ff0e39e569ab2eaa56b1870
Author: Peter Rajnoha <prajnoha(a)redhat.com>
AuthorDate: Fri Jun 24 14:56:43 2016 +0200
Committer: Peter Rajnoha <prajnoha(a)redhat.com>
CommitterDate: Fri Jun 24 14:57:09 2016 +0200
man: lvs: move doc about --all so it's ordered alphabetically in the man page
---
man/lvs.8.in | 20 ++++++++++----------
1 files changed, 10 insertions(+), 10 deletions(-)
diff --git a/man/lvs.8.in b/man/lvs.8.in
index 7bd25a6..3cb2d2b 100644
--- a/man/lvs.8.in
+++ b/man/lvs.8.in
@@ -53,6 +53,16 @@ for common options.
.B \-\-aligned
Use with \fB\-\-separator\fP to align the output columns.
.TP
+.B \-\-all
+Include information in the output about internal Logical Volumes that
+are components of normally-accessible Logical Volumes, such as mirrors,
+but which are not independently accessible (e.g. not mountable).
+The names of such Logical Volumes are enclosed within square brackets
+in the output. For example, after creating a mirror using
+.B lvcreate -m1 \-\-mirrorlog disk
+, this option will reveal three internal Logical
+Volumes, with suffixes mimage_0, mimage_1, and mlog.
+.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
@@ -67,16 +77,6 @@ command's main report is assumed. The log report is available only if
enabled by \fBlog/report_command_log\fP \fBlvm.conf\fP(5) setting or
if \fB\-\-logonly\fP option is used.
.TP
-.B \-\-all
-Include information in the output about internal Logical Volumes that
-are components of normally-accessible Logical Volumes, such as mirrors,
-but which are not independently accessible (e.g. not mountable).
-The names of such Logical Volumes are enclosed within square brackets
-in the output. For example, after creating a mirror using
-.B lvcreate -m1 \-\-mirrorlog disk
-, this option will reveal three internal Logical
-Volumes, with suffixes mimage_0, mimage_1, and mlog.
-.TP
.B \-H ", " \-\-history
Include historical logical volumes in the output.
(This has no effect unless logical volumes were removed while the configuration
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=a910052a2e7da453…
Commit: a910052a2e7da4531ff0e39e569ab2eaa56b1870
Parent: 9a414245b908bfa1bacb12b6416908de65f0e317
Author: Peter Rajnoha <prajnoha(a)redhat.com>
AuthorDate: Fri Jun 24 14:51:20 2016 +0200
Committer: Peter Rajnoha <prajnoha(a)redhat.com>
CommitterDate: Fri Jun 24 14:51:20 2016 +0200
man: document --configreport, --logonly, --reportformat
---
man/lvchange.8.in | 2 ++
man/lvcreate.8.in | 4 ++++
man/lvdisplay.8.in | 20 ++++++++++++++------
man/lvextend.8.in | 2 ++
man/lvm.8.in | 10 ++++++++++
man/lvreduce.8.in | 2 ++
man/lvremove.8.in | 2 ++
man/lvrename.8.in | 2 ++
man/lvresize.8.in | 2 ++
man/lvs.8.in | 29 ++++++++++++++++++++++++-----
man/lvscan.8.in | 2 ++
man/pvchange.8.in | 2 ++
man/pvcreate.8.in | 2 ++
man/pvdisplay.8.in | 21 ++++++++++++++-------
man/pvmove.8.in | 2 ++
man/pvremove.8.in | 2 ++
man/pvresize.8.in | 2 ++
man/pvs.8.in | 30 ++++++++++++++++++++++++------
man/pvscan.8.in | 4 ++++
man/vgcfgbackup.8.in | 2 ++
man/vgchange.8.in | 2 ++
man/vgck.8.in | 2 ++
man/vgconvert.8.in | 2 ++
man/vgcreate.8.in | 2 ++
man/vgdisplay.8.in | 20 ++++++++++++++------
man/vgexport.8.in | 2 ++
man/vgextend.8.in | 2 ++
man/vgimport.8.in | 2 ++
man/vgmknodes.8.in | 2 ++
man/vgreduce.8.in | 2 ++
man/vgremove.8.in | 2 ++
man/vgrename.8.in | 2 ++
man/vgs.8.in | 30 ++++++++++++++++++++++++------
man/vgscan.8.in | 2 ++
34 files changed, 182 insertions(+), 36 deletions(-)
diff --git a/man/lvchange.8.in b/man/lvchange.8.in
index 2bfe7c0..3800369 100644
--- a/man/lvchange.8.in
+++ b/man/lvchange.8.in
@@ -76,6 +76,8 @@ lvchange \(em change attributes of a logical volume
.RB [ \-r | \-\-readahead
.RB { \fIReadAheadSectors | auto | none }]
.RB [ \-\-refresh ]
+.RB [ \-\-reportformat
+.RB { basic | json }]
.RB [ \-\-resync ]
.RB [ \-S | \-\-select
.IR Selection ]
diff --git a/man/lvcreate.8.in b/man/lvcreate.8.in
index c28bc41..3e2bf32 100644
--- a/man/lvcreate.8.in
+++ b/man/lvcreate.8.in
@@ -93,6 +93,8 @@ lvcreate \- create a logical volume in an existing volume group
.IR Rate ]
.RB [ \-r | \-\-readahead
.RB { \fIReadAheadSectors | auto | none }]
+.RB [ \-\-reportformat
+.RB {basic | json}]
.RB \%[ \-k | \-\-setactivationskip
.RB { y | n }]
.RB [ \-s | \-\-snapshot ]
@@ -133,6 +135,8 @@ lvcreate \- create a logical volume in an existing volume group
.RB { y | n }]
.RB [ \-n | \-\-name
.IR SnapshotLogicalVolumeName ]
+.RB [ \-\-reportformat
+.RB {basic | json}]
.BR \-s | \-\-snapshot | \-H | \-\-cache
.RI \%{[ VolumeGroup \fB/\fP] OriginalLogicalVolume
.RB \%[ \-V | \-\-virtualsize
diff --git a/man/lvdisplay.8.in b/man/lvdisplay.8.in
index f14fa03..e8e7809 100644
--- a/man/lvdisplay.8.in
+++ b/man/lvdisplay.8.in
@@ -14,6 +14,8 @@ lvdisplay \(em display attributes of a logical volume
.RB [ \-\-maps ]
.RB [ \-\-nosuffix ]
.RB [ \-P | \-\-partial ]
+.RB [ \-\-reportformat
+.RB { basic | json }]
.RB [ \-S | \-\-select
.IR Selection ]
.RB [ \-\-units
@@ -30,20 +32,26 @@ lvdisplay \(em display attributes of a logical volume
.RB [ \-a | \-\-all ]
.RB [ \-\-commandprofile
.IR ProfileName ]
+.RB [[ \-\-configreport
+.IR ReportName ]
+.RB [ \-o | \-\-options
+.RI [ + | \- | # ] Field1 [, Field2 ...]
+.RB [ \-O | \-\-sort
+.RI [ + | \- ] Key1 [, Key2 ...]]
+.RB [ \-S | \-\-select
+.IR Selection ]
+.RB ...]
.RB [ \-d | \-\-debug ]
.RB [ \-h | \-? | \-\-help ]
.RB [ \-\-ignorelockingfailure ]
.RB [ \-\-ignoreskippedcluster ]
+.RB [ \-\-logonly ]
.RB [ \-\-noheadings ]
.RB [ \-\-nosuffix ]
-.RB [ \-o | \-\-options
-.RI [ + | \- | # ] Field [ ,Field ...]]
-.RB [ \-O | \-\-sort
-.RI [ + | \- ] Key1 [ , [ + | \- ] Key2 ...]]
.RB [ \-P | \-\-partial ]
+.RB [ \-\-reportformat
+.RB { basic | json }]
.RB [ \-\-segments ]
-.RB [ \-S | \-\-select
-.IR Selection ]
.RB [ \-\-separator
.IR Separator ]
.RB [ \-\-unbuffered ]
diff --git a/man/lvextend.8.in b/man/lvextend.8.in
index 8deab54..eefbf79 100644
--- a/man/lvextend.8.in
+++ b/man/lvextend.8.in
@@ -24,6 +24,8 @@ lvextend \(em extend the size of a logical volume
.RB [ \-n | \-\-nofsck ]
.RB [ \-\-noudevsync]
.RB [ \-r | \-\-resizefs ]
+.RB [ \-\-reportformat
+.RB { basic | json }]
.RB [ \-\-use\-policies ]
.RB [ \-t | \-\-test ]
.RB [ \-v | \-\-verbose ]
diff --git a/man/lvm.8.in b/man/lvm.8.in
index f8400cf..729518b 100644
--- a/man/lvm.8.in
+++ b/man/lvm.8.in
@@ -466,6 +466,16 @@ for any other command (with the exception of \fBlvmconfig\fP command where the
\fB\-\-profile\fP has special meaning, see \fBlvmconfig\fP(8) for more information).
.
.HP
+.BR \-\-reportformat
+.IR {basic|json}
+.br
+Overrides current output format for reports which is defined globally by
+\fBreport/output_format\fP configuration setting in \fBlvm.conf\fP(5).
+The \fBbasic\fP format is the original format with columns and rows and
+if there is more than one report per command, each report is prefixed
+with report's name for identification. The \fBjson\fP stands for report
+output in JSON format.
+.HP
.BR \-\-config
.IR ConfigurationString
.br
diff --git a/man/lvreduce.8.in b/man/lvreduce.8.in
index 5aca24e..edf0c92 100644
--- a/man/lvreduce.8.in
+++ b/man/lvreduce.8.in
@@ -20,6 +20,8 @@ lvreduce \(em reduce the size of a logical volume
.BR \-L | \-\-size
.RI [ \- ] LogicalVolumeSize [ bBsSkKmMgGtTpPeE ]}
.RB [ \-n | \-\-nofsck ]
+.RB [ \-\-reportformat
+.RB { basic | json }]
.RB [ \-r | \-\-resizefs ]
.IR LogicalVolume { Name | Path }
.SH DESCRIPTION
diff --git a/man/lvremove.8.in b/man/lvremove.8.in
index 433c277..fe9375c 100644
--- a/man/lvremove.8.in
+++ b/man/lvremove.8.in
@@ -10,6 +10,8 @@ lvremove \(em remove a logical volume
.RB [ \-d | \-\-debug ]
.RB [ \-h | \-\-help ]
.RB [ \-\-nohistory ]
+.RB [ \-\-reportformat
+.RB { basic | json }]
.RB [ \-S | \-\-select
.IR Selection ]
.RB [ \-t | \-\-test ]
diff --git a/man/lvrename.8.in b/man/lvrename.8.in
index fdacac7..de6e519 100644
--- a/man/lvrename.8.in
+++ b/man/lvrename.8.in
@@ -14,6 +14,8 @@ lvrename \(em rename a logical volume
.RB [ \-\-version ]
.RB [ \-f | \-\-force ]
.RB [ \-\-noudevsync ]
+.RB [ \-\-reportformat
+.RB { basic | json }]
.RI { OldLogicalVolume { Name | Path }
.IR NewLogicalVolume { Name | Path }
|
diff --git a/man/lvresize.8.in b/man/lvresize.8.in
index a5bda53..9cdb787 100644
--- a/man/lvresize.8.in
+++ b/man/lvresize.8.in
@@ -17,6 +17,8 @@ lvresize \(em resize a logical volume
.RI [ + ] MetadataVolumeSize [ bBsSkKmMgG ]]
.RB [ \-f | \-\-force ]
.RB [ \-n | \-\-nofsck ]
+.RB [ \-\-reportformat
+.RB { basic | json }]
.RB [ \-r | \-\-resizefs ]
.IR LogicalVolume { Name | Path }
.RI [ PhysicalVolumePath [ :PE [ \-PE ]]...]
diff --git a/man/lvs.8.in b/man/lvs.8.in
index d4bc7f2..7bd25a6 100644
--- a/man/lvs.8.in
+++ b/man/lvs.8.in
@@ -8,22 +8,29 @@ lvs \(em report information about logical volumes
.RB [ \-a | \-\-all ]
.RB [ \-\-commandprofile
.IR ProfileName ]
+.RB [[ \-\-configreport
+.IR ReportName ]
+.RB [ \-o | \-\-options
+.RI [ + | \- | # ] Field1 [, Field2 ...]
+.RB [ \-O | \-\-sort
+.RI [ + | \- ] Key1 [, Key2 ...]]
+.RB [ \-S | \-\-select
+.IR Selection ]
+.RB ...]
.RB [ \-d | \-\-debug ]
.RB [ \-h | \-? | \-\-help ]
.RB [ \-H | \-\-history ]
.RB [ \-\-ignorelockingfailure ]
.RB [ \-\-ignoreskippedcluster ]
+.RB [ \-\-logonly ]
.RB [ \-\-nameprefixes ]
.RB [ \-\-noheadings ]
.RB [ \-\-nosuffix ]
-.RB [ \-o | \-\-options
-.RI [ + | \- | # ] Field [, Field ]]
-.RB [ \-O | \-\-sort
.RI [ + | \- ] Key1 [,[ + | \- ] Key2 [,...]]]
.RB [ \-P | \-\-partial ]
+.RB [ \-\-reportformat
+.RB { basic | json }]
.RB [ \-\-rows ]
-.RB [ \-S | \-\-select
-.IR Selection ]
.RB [ \-\-separator
.IR Separator ]
.RB [ \-\-segments ]
@@ -51,6 +58,15 @@ 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 \-\-configreport \fI ReportName
+Make any subsequent \fB\-o, \-\-options\fP, \fB\-O, \-\-sort\fP or
+\fB\-S, \-\-select\fP to apply for \fIReportName\fP where \fIReportName\fP
+is either 'lvs' for command's main report or 'log' for log report.
+If \fB\-\-configreport\fP option is not used to identify a report, then
+command's main report is assumed. The log report is available only if
+enabled by \fBlog/report_command_log\fP \fBlvm.conf\fP(5) setting or
+if \fB\-\-logonly\fP option is used.
+.TP
.B \-\-all
Include information in the output about internal Logical Volumes that
are components of normally-accessible Logical Volumes, such as mirrors,
@@ -66,6 +82,9 @@ Include historical logical volumes in the output.
(This has no effect unless logical volumes were removed while the configuration
setting \fBmetadata/record_lvs_history\fP was enabled.)
.TP
+.B \-\-logonly
+Suppress the lvs report itself and display only log report on output.
+.TP
.B \-\-nameprefixes
Add an "LVM2_" prefix plus the field name to the output. Useful
with \fB\-\-noheadings\fP to produce a list of field=value pairs that can
diff --git a/man/lvscan.8.in b/man/lvscan.8.in
index 0b6e50b..5710e3c 100644
--- a/man/lvscan.8.in
+++ b/man/lvscan.8.in
@@ -11,6 +11,8 @@ lvscan \(em scan (all disks) for Logical Volumes
.RB [ \-h | \-\-help ]
.RB [ \-\-ignorelockingfailure ]
.RB [ \-P | \-\-partial ]
+.RB [ \-\-reportformat
+.RB { basic | json }]
.RB [ \-v | \-\-verbose ]
.SH DESCRIPTION
lvscan scans all known volume groups or all supported LVM block devices
diff --git a/man/pvchange.8.in b/man/pvchange.8.in
index 5c5b809..c7ddc58 100644
--- a/man/pvchange.8.in
+++ b/man/pvchange.8.in
@@ -16,6 +16,8 @@ pvchange \(em change attributes of a physical volume
.RB [ \-\-metadataignore
.RI { y | n }]
.RB [ \-h | \-? | \-\-help ]
+.RB [ \-\-reportformat
+.RB { basic | json }]
.RB [ \-S | \-\-select
.IR Selection ]
.RB [ \-t | \-\-test ]
diff --git a/man/pvcreate.8.in b/man/pvcreate.8.in
index a50aaa7..97a9909 100644
--- a/man/pvcreate.8.in
+++ b/man/pvcreate.8.in
@@ -31,6 +31,8 @@ pvcreate \(em initialize a disk or partition for use by LVM
.RB [ \-\-restorefile
.IR file ]
.RB [ \-\-norestorefile ]
+.RB [ \-\-reportformat
+.RB { basic | json }]
.RB [ \-\-setphysicalvolumesize
.IR size ]
.RB [ \-u | \-\-uuid
diff --git a/man/pvdisplay.8.in b/man/pvdisplay.8.in
index 5f93634..9bca720 100644
--- a/man/pvdisplay.8.in
+++ b/man/pvdisplay.8.in
@@ -12,6 +12,8 @@ pvdisplay \- display attributes of a physical volume
.RB [ \-\-ignoreskippedcluster ]
.RB [ \-\-maps ]
.RB [ \-\-nosuffix ]
+.RB [ \-\-reportformat
+.RB { basic | json }]
.RB [ \-s | \-\-short ]
.RB [ \-S | \-\-select
.IR Selection ]
@@ -30,19 +32,24 @@ pvdisplay \- display attributes of a physical volume
.RB [ \-\-binary ]
.RB [ \-a | \-\-all ]
.RB [ \-\-commandprofile
+.RB [[ \-\-configreport
+.IR ReportName ]
+.RB [ \-o | \-\-options
+.RI [ + | \- | # ] Field1 [, Field2 ...]
+.RB [ \-O | \-\-sort
+.RI [ + | \- ] Key1 [, Key2 ...]]
+.RB [ \-S | \-\-select
+.IR Selection ]
+.RB ...]
.IR ProfileName ]
.RB [ \-d | \-\-debug ]
.RB [ \-h | \-? | \-\-help ]
.RB [ \-\-ignorelockingfailure ]
+.RB [ \-\-logonly ]
.RB [ \-\-noheadings ]
.RB [ \-\-nosuffix ]
-.RB [ \-o | \-\-options
-.RI [ + | \- | # ] Field [ ,Field ...]]
-.RB [ \-O | \-\-sort
-.RI [ + | \- ] Key1 [ , [ + | \- ] Key2 ...
-.RI ]]
-.RB [ \-S | \-\-select
-.IR Selection ]
+.RB [ \-\-reportformat
+.RB { basic | json }]
.RB [ \-\-separator
.IR Separator ]
.RB [ \-\-unbuffered ]
diff --git a/man/pvmove.8.in b/man/pvmove.8.in
index 43a4e00..39fdfe4 100644
--- a/man/pvmove.8.in
+++ b/man/pvmove.8.in
@@ -15,6 +15,8 @@ pvmove \(em move physical extents
.RB [ \-i | \-\-interval
.IR Seconds ]
.RB [ \-\-noudevsync ]
+.RB [ \-\-reportformat
+.RB { basic | json }]
.RB [ \-v | \-\-verbose ]
.RB [ \-n | \-\-name
.IR LogicalVolume ]
diff --git a/man/pvremove.8.in b/man/pvremove.8.in
index 5f9b055..6444884 100644
--- a/man/pvremove.8.in
+++ b/man/pvremove.8.in
@@ -12,6 +12,8 @@ pvremove \(em remove a physical volume
.RB [ \-\-version ]
.RB [ \-f [ f ]| \-\-force
.RB [ \-\-force ]]
+.RB [ \-\-reportformat
+.RB { basic | json }]
.RB [ \-y | \-\-yes ]
.I PhysicalVolume
.RI [ PhysicalVolume ...]
diff --git a/man/pvresize.8.in b/man/pvresize.8.in
index 8b78651..b7d8f33 100644
--- a/man/pvresize.8.in
+++ b/man/pvresize.8.in
@@ -10,6 +10,8 @@ pvresize \(em resize a disk or partition in use by LVM2
.RB [ \-t | \-\-test ]
.RB [ \-v | \-\-verbose ]
.RB [ \-\-version ]
+.RB [ \-\-reportformat
+.RB { basic | json }]
.RB [ \-\-setphysicalvolumesize
.IR size ]
.I PhysicalVolume
diff --git a/man/pvs.8.in b/man/pvs.8.in
index 24d16fb..0a60b6f 100644
--- a/man/pvs.8.in
+++ b/man/pvs.8.in
@@ -8,22 +8,28 @@ pvs \(em report information about physical volumes
.RB [ \-\-binary ]
.RB [ \-\-commandprofile
.IR ProfileName ]
+.RB [[ \-\-configreport
+.IR ReportName ]
+.RB [ \-o | \-\-options
+.RI [ + | \- | # ] Field1 [, Field2 ...]
+.RB [ \-O | \-\-sort
+.RI [ + | \- ] Key1 [, Key2 ...]]
+.RB [ \-S | \-\-select
+.IR Selection ]
+.RB ...]
.RB [ \-d | \-\-debug ]
.RB [ \-h | \-? | \-\-help ]
.RB [ \-\-ignorelockingfailure ]
.RB [ \-\-ignoreskippedcluster ]
+.RB [ \-\-logonly ]
.RB [ \-\-nameprefixes ]
.RB [ \-\-noheadings ]
.RB [ \-\-nosuffix ]
-.RB [ \-o | \-\-options
-.RI [ + | \- | # ] Field [ ,Field ...]]
-.RB [ \-O | \-\-sort
-.RI [ + | \- ] Key1 [ , [ + | \- ] Key2 ...]]
.RB [ \-P | \-\-partial ]
+.RB [ \-\-reportformat
+.RB { basic | json }]
.RB [ \-\-rows ]
.RB [ \-\-segments ]
-.RB [ \-S | \-\-select
-.IR Selection ]
.RB [ \-\-separator
.IR Separator ]
.RB [ \-\-unbuffered ]
@@ -51,6 +57,18 @@ 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 \-\-configreport \fI ReportName
+Make any subsequent \fB\-o, \-\-options\fP, \fB\-O, \-\-sort\fP or
+\fB\-S, \-\-select\fP to apply for \fIReportName\fP where \fIReportName\fP
+is either 'pvs' for command's main report or 'log' for log report.
+If \fB\-\-configreport\fP option is not used to identify a report, then
+command's main report is assumed. The log report is available only if
+enabled by \fBlog/report_command_log\fP \fBlvm.conf\fP(5) setting or
+if \fB\-\-logonly\fP option is used.
+.TP
+.B \-\-logonly
+Suppress the pvs report itself and display only log report on output.
+.TP
.B \-\-nameprefixes
Add an "LVM2_" prefix plus the field name to the output. Useful
with \fB\-\-noheadings\fP to produce a list of field=value pairs that can
diff --git a/man/pvscan.8.in b/man/pvscan.8.in
index 010c091..38f424f 100644
--- a/man/pvscan.8.in
+++ b/man/pvscan.8.in
@@ -13,6 +13,8 @@ pvscan \(em scan all disks for physical volumes
.RB [ \-\-ignorelockingfailure ]
.RB [ \-e | \-\-exported ]
.RB [ \-n | \-\-novolumegroup ]
+.RB [ \-\-reportformat
+.RB { basic | json }]
.RB [ \-s | \-\-short ]
.RB [ \-u | \-\-uuid ]
.BR
@@ -23,6 +25,8 @@ pvscan \(em scan all disks for physical volumes
.B \-\-cache
.RB [ \-a | \-\-activate " " \fIay ]
.RB [ \-b | \-\-background ]
+.RB [ \-\-reportformat
+.RB { basic | json }]
.RB [ \-\-major
.I major
.B \-\-minor
diff --git a/man/vgcfgbackup.8.in b/man/vgcfgbackup.8.in
index 898764a..c6f20d9 100644
--- a/man/vgcfgbackup.8.in
+++ b/man/vgcfgbackup.8.in
@@ -11,6 +11,8 @@ vgcfgbackup \(em backup volume group descriptor area
.RB [ \-h | \-\-help ]
.RB [ \-\-ignorelockingfailure ]
.RB [ \-P | \-\-partial ]
+.RB [ \-\-reportformat
+.RB { basic | json }]
.RB [ \-v | \-\-verbose ]
.RI [ VolumeGroupName ...]
.SH DESCRIPTION
diff --git a/man/vgchange.8.in b/man/vgchange.8.in
index e334fd1..3b2fc3e 100644
--- a/man/vgchange.8.in
+++ b/man/vgchange.8.in
@@ -49,6 +49,8 @@ vgchange \(em change attributes of a volume group
.RB [ \-P | \-\-partial ]
.RB [ \-s | \-\-physicalextentsize
.IR PhysicalExtentSize [ bBsSkKmMgGtTpPeE ]]
+.RB [ \-\-reportformat
+.RB { basic | json }]
.RB [ \-S | \-\-select
.IR Selection ]
.RB [ \-\-systemid
diff --git a/man/vgck.8.in b/man/vgck.8.in
index f09e709..b10f57e 100644
--- a/man/vgck.8.in
+++ b/man/vgck.8.in
@@ -7,6 +7,8 @@ vgck \(em check volume group metadata
.IR ProfileName ]
.RB [ \-d | \-\-debug ]
.RB [ \-h | \-? | \-\-help ]
+.RB [ \-\-reportformat
+.RB { basic | json }]
.RB [ \-v | \-\-verbose ]
.RI [ VolumeGroupName ...]
.SH DESCRIPTION
diff --git a/man/vgconvert.8.in b/man/vgconvert.8.in
index c77d529..d864483 100644
--- a/man/vgconvert.8.in
+++ b/man/vgconvert.8.in
@@ -18,6 +18,8 @@ vgconvert \- convert volume group metadata format
.IR NumberOfCopies ]
.RB [ \-\-metadatasize
.IR size ]
+.RB [ \-\-reportformat
+.RB { basic | json }]
.RB [ \-\-version ]
.I VolumeGroupName
.RI [ VolumeGroupName ...]
diff --git a/man/vgcreate.8.in b/man/vgcreate.8.in
index 764d76e..c66753b 100644
--- a/man/vgcreate.8.in
+++ b/man/vgcreate.8.in
@@ -27,6 +27,8 @@ vgcreate \(em create a volume group
.IR NumberOfCopies | unmanaged | all ]
.RB [ \-s | \-\-physicalextentsize
.IR PhysicalExtentSize [ bBsSkKmMgGtTpPeE ]]
+.RB [ \-\-reportformat
+.RB { basic | json }]
.RB [ \-\-shared ]
.RB [ \-\-systemid
.IR SystemID ]
diff --git a/man/vgdisplay.8.in b/man/vgdisplay.8.in
index 89a7a5a..045a6ae 100644
--- a/man/vgdisplay.8.in
+++ b/man/vgdisplay.8.in
@@ -7,6 +7,8 @@ vgdisplay \(em display attributes of volume groups
.RB [ \-c | \-\-colon ]
.RB [ \-\-commandprofile
.IR ProfileName ]
+.RB [ \-\-reportformat
+.RB { basic | json }]
.RB [ \-s | \-\-short ]
.RB [ \-S | \-\-select
.IR Selection ]
@@ -30,19 +32,25 @@ vgdisplay \(em display attributes of volume groups
.RB [ \-\-binary ]
.RB [ \-\-commandprofile
.IR ProfileName ]
+.RB [[ \-\-configreport
+.IR ReportName ]
+.RB [ \-o | \-\-options
+.RI [ + | \- | # ] Field1 [, Field2 ...]
+.RB [ \-O | \-\-sort
+.RI [ + | \- ] Key1 [, Key2 ...]]
+.RB [ \-S | \-\-select
+.IR Selection ]
+.RB ...]
.RB [ \-d | \-\-debug ]
.RB [ \-h | \-? | \-\-help ]
.RB [ \-\-ignorelockingfailure ]
.RB [ \-\-ignoreskippedcluster ]
+.RB [ \-\-logonly ]
.RB [ \-\-noheadings ]
.RB [ \-\-nosuffix ]
-.RB [ \-o|\-\-options
-.RI [ + | \- | # ] Field1 [ ,Field2 ...]]
-.RB [ \-O | \-\-sort
-.RI [ + | \- ] Key1 [ , [ + | \- ] Key2 ...]]
.RB [ \-P | \-\-partial ]
-.RB [ \-S | \-\-select
-.IR Selection ]
+.RB [ \-\-reportformat
+.RB { basic | json }]
.RB [ \-\-separator
.IR Separator ]
.RB [ \-\-unbuffered ]
diff --git a/man/vgexport.8.in b/man/vgexport.8.in
index 08c1d78..6e2ecbf 100644
--- a/man/vgexport.8.in
+++ b/man/vgexport.8.in
@@ -8,6 +8,8 @@ vgexport \- make volume groups unknown to the system
.IR ProfileName ]
.RB [ \-d | \-\-debug ]
.RB [ \-h | \-? | \-\-help ]
+.RB [ \-\-reportformat
+.RB { basic | json }]
.RB [ \-S | \-\-select
.IR Selection ]
.RB [ \-v | \-\-verbose ]
diff --git a/man/vgextend.8.in b/man/vgextend.8.in
index 52837db..51bd615 100644
--- a/man/vgextend.8.in
+++ b/man/vgextend.8.in
@@ -9,6 +9,8 @@ vgextend \(em add physical volumes to a volume group
.IR ProfileName ]
.RB [ \-d | \-\-debug ]
.RB [ \-h | \-? | \-\-help ]
+.RB [ \-\-reportformat
+.RB { basic | json }]
.RB [ \-\-restoremissing ]
.RB [ \-f | \-\-force ]
.RB [ \-t | \-\-test ]
diff --git a/man/vgimport.8.in b/man/vgimport.8.in
index cd34049..ba4fdf9 100644
--- a/man/vgimport.8.in
+++ b/man/vgimport.8.in
@@ -6,6 +6,8 @@ vgimport \(em make exported volume groups known to the system
.RB [ \-a | \-\-all ]
.RB [ \-d | \-\-debug ]
.RB [ \-h | \-? | \-\-help ]
+.RB [ \-\-reportformat
+.RB { basic | json }]
.RB [ \-S | \-\-select
.IR Selection ]
.RB [ \-v | \-\-verbose ]
diff --git a/man/vgmknodes.8.in b/man/vgmknodes.8.in
index 4f5bbfe..c5bb5d4 100644
--- a/man/vgmknodes.8.in
+++ b/man/vgmknodes.8.in
@@ -8,6 +8,8 @@ vgmknodes \(em recreate volume group directory and logical volume special files
.RB [ \-d | \-\-debug ]
.RB [ \-h | \-\-help ]
.RB [ \-\-refresh ]
+.RB [ \-\-reportformat
+.RB { basic | json }]
.RB [ \-v | \-\-verbose ]
.RI [[ VolumeGroupName | LogicalVolumePath ]...]
.SH DESCRIPTION
diff --git a/man/vgreduce.8.in b/man/vgreduce.8.in
index 9e70a0a..cce31e8 100644
--- a/man/vgreduce.8.in
+++ b/man/vgreduce.8.in
@@ -11,6 +11,8 @@ vgreduce \(em reduce a volume group
.RB [ \-d | \-\-debug ]
.RB [ \-h | \-? | \-\-help ]
.RB [ \-\-removemissing ]
+.RB [ \-\-reportformat
+.RB { basic | json }]
.RB [ \-t | \-\-test ]
.RB [ \-v | \-\-verbose ]
.I VolumeGroupName
diff --git a/man/vgremove.8.in b/man/vgremove.8.in
index 082c1f3..4e600ef 100644
--- a/man/vgremove.8.in
+++ b/man/vgremove.8.in
@@ -9,6 +9,8 @@ vgremove \(em remove a volume group
.RB [ \-f | \-\-force ]
.RB [ \-h | \-? | \-\-help ]
.RB [ \-\-noudevsync ]
+.RB [ \-\-reportformat
+.RB { basic | json }]
.RB [ \-S | \-\-select
.IR Selection ]
.RB [ \-t | \-\-test ]
diff --git a/man/vgrename.8.in b/man/vgrename.8.in
index 1f2539b..322d740 100644
--- a/man/vgrename.8.in
+++ b/man/vgrename.8.in
@@ -9,6 +9,8 @@ vgrename \(em rename a volume group
.IR ProfileName ]
.RB [ \-d | \-\-debug ]
.RB [ \-h | \-? | \-\-help ]
+.RB [ \-\-reportformat
+.RB { basic | json }]
.RB [ \-t | \-\-test ]
.RB [ \-v | \-\-verbose ]
.IR OldVolumeGroup { Path | Name | UUID }
diff --git a/man/vgs.8.in b/man/vgs.8.in
index f219665..ab9d9ac 100644
--- a/man/vgs.8.in
+++ b/man/vgs.8.in
@@ -8,21 +8,27 @@ vgs \(em report information about volume groups
.RB [ \-\-binary ]
.RB [ \-\-commandprofile
.IR ProfileName ]
+.RB [[ \-\-configreport
+.IR ReportName ]
+.RB [ \-o | \-\-options
+.RI [ + | \- | # ] Field1 [, Field2 ...]
+.RB [ \-O | \-\-sort
+.RI [ + | \- ] Key1 [, Key2 ...]]
+.RB [ \-S | \-\-select
+.IR Selection ]
+.RB ...]
.RB [ \-d | \-\-debug ]
.RB [ \-h | \-? | \-\-help ]
.RB [ \-\-ignorelockingfailure ]
.RB [ \-\-ignoreskippedcluster ]
+.RB [ \-\-logonly ]
.RB [ \-\-nameprefixes ]
.RB [ \-\-noheadings ]
.RB [ \-\-nosuffix ]
-.RB [ \-o | \-\-options
-.RI [ + | \- | # ] Field1 [ ,Field2 ...]]
-.RB [ \-O | \-\-sort
-.RI [ + | \- ] Key1 [ , [ + | \- ] Key2 ...]]
.RB [ \-P | \-\-partial ]
+.RB [ \-\-reportformat
+.RB { basic | json }]
.RB [ \-\-rows ]
-.RB [ \-S | \-\-select
-.IR Selection ]
.RB [ \-\-separator
.IR Separator ]
.RB [ \-\-unbuffered ]
@@ -49,6 +55,18 @@ 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 \-\-configreport \fI ReportName
+Make any subsequent \fB\-o, \-\-options\fP, \fB\-O, \-\-sort\fP or
+\fB\-S, \-\-select\fP to apply for \fIReportName\fP where \fIReportName\fP
+is either 'vgs' for command's main report or 'log' for log report.
+If \fB\-\-configreport\fP option is not used to identify a report, then
+command's main report is assumed. The log report is available only if
+enabled by \fBlog/report_command_log\fP \fBlvm.conf\fP(5) setting or
+if \fB\-\-logonly\fP option is used.
+.TP
+.B \-\-logonly
+Suppress the vgs report itself and display only log report on output.
+.TP
.B \-\-nameprefixes
Add an "LVM2_" prefix plus the field name to the output. Useful
with \fB\-\-noheadings\fP to produce a list of field=value pairs that can
diff --git a/man/vgscan.8.in b/man/vgscan.8.in
index 8c699d1..e85d817 100644
--- a/man/vgscan.8.in
+++ b/man/vgscan.8.in
@@ -11,6 +11,8 @@ vgscan \(em scan all disks for volume groups and rebuild caches
.RB [ \-\-mknodes ]
.RB [ \-\-notifydbus ]
.RB [ \-P | \-\-partial ]
+.RB [ \-\-reportformat
+.RB { basic | json }]
.RB [ \-v | \-\-verbose ]
.SH DESCRIPTION
vgscan scans all SCSI, (E)IDE disks, multiple devices and a bunch
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=9a414245b908bfa1…
Commit: 9a414245b908bfa1bacb12b6416908de65f0e317
Parent: 14da3cc793a368f925f26706e6b50f91a6dbede1
Author: Peter Rajnoha <prajnoha(a)redhat.com>
AuthorDate: Fri Jun 24 14:49:13 2016 +0200
Committer: Peter Rajnoha <prajnoha(a)redhat.com>
CommitterDate: Fri Jun 24 14:49:13 2016 +0200
commands: help: add missing --reportformat references
---
tools/commands.h | 7 +++++--
1 files changed, 5 insertions(+), 2 deletions(-)
diff --git a/tools/commands.h b/tools/commands.h
index 5589c9e..c348753 100644
--- a/tools/commands.h
+++ b/tools/commands.h
@@ -158,7 +158,7 @@ xx(fullreport,
"\t[-O|--sort [+|-]key1[,[+|-]key2[,...]]]\n"
"\t[-P|--partial]\n"
"\t[--readonly]\n"
- "\t[--reportformat {json}]\n"
+ "\t[--reportformat {basic|json}]\n"
"\t[--rows]\n"
"\t[-S|--select Selection]\n"
"\t[--separator Separator]\n"
@@ -181,7 +181,7 @@ xx(lastlog,
"Display last command's log report",
PERMITTED_READ_ONLY | NO_METADATA_PROCESSING,
"log\n"
- "\t[--reportformat {json}]\n"
+ "\t[--reportformat {basic|json}]\n"
"\t[-S|--select Selection]\n",
reportformat_ARG, select_ARG)
@@ -472,6 +472,7 @@ xx(lvdisplay,
"\t[--nosuffix]\n"
"\t[-P|--partial]\n"
"\t[--readonly]\n"
+ "\t[--reportformat {basic|json}]\n"
"\t[-S|--select Selection]\n"
"\t[--units hHbBsSkKmMgGtTpPeE]\n"
"\t[-v|--verbose]\n"
@@ -908,6 +909,7 @@ xx(pvdisplay,
"\t[-m|--maps]\n"
"\t[--nosuffix]\n"
"\t[--readonly]\n"
+ "\t[--reportformat {basic|json}]\n"
"\t[-S|--select Selection]\n"
"\t[-s|--short]\n"
"\t[--units hHbBsSkKmMgGtTpPeE]\n"
@@ -1263,6 +1265,7 @@ xx(vgdisplay,
"\t[--nosuffix]\n"
"\t[-P|--partial]\n"
"\t[--readonly]\n"
+ "\t[--reportformat {basic|json}]\n"
"\t[-S|--select Selection]\n"
"\t[--units hHbBsSkKmMgGtTpPeE]\n"
"\t[--version]\n"
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=14da3cc793a368f9…
Commit: 14da3cc793a368f925f26706e6b50f91a6dbede1
Parent: e88e9ee9eda8981cccb03d053189d05718891d53
Author: Peter Rajnoha <prajnoha(a)redhat.com>
AuthorDate: Fri Jun 24 11:10:10 2016 +0200
Committer: Peter Rajnoha <prajnoha(a)redhat.com>
CommitterDate: Fri Jun 24 11:10:10 2016 +0200
commands: fix typo in arg assignment
---
tools/commands.h | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/tools/commands.h b/tools/commands.h
index ed86b7f..5589c9e 100644
--- a/tools/commands.h
+++ b/tools/commands.h
@@ -508,7 +508,7 @@ xx(lvdisplay,
"\t[LogicalVolume[Path] [LogicalVolume[Path]...]]\n",
aligned_ARG, all_ARG, binary_ARG, colon_ARG, columns_ARG,
- configreport_ARG< foreign_ARG, history_ARG, ignorelockingfailure_ARG,
+ configreport_ARG, foreign_ARG, history_ARG, ignorelockingfailure_ARG,
ignoreskippedcluster_ARG, logonly_ARG, maps_ARG, noheadings_ARG,
nosuffix_ARG, options_ARG, sort_ARG, partial_ARG, readonly_ARG,
reportformat_ARG, segments_ARG, select_ARG, separator_ARG,
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=e88e9ee9eda8981c…
Commit: e88e9ee9eda8981cccb03d053189d05718891d53
Parent: 5070e7fcf79a3bcb21982d219c6f8dd484e523ea
Author: Zdenek Kabelac <zkabelac(a)redhat.com>
AuthorDate: Fri Jun 24 01:10:04 2016 +0200
Committer: Zdenek Kabelac <zkabelac(a)redhat.com>
CommitterDate: Fri Jun 24 01:10:04 2016 +0200
cleanup: clean warns from older gcc
Don't report uninitialized use by older gcc.
---
lib/cache/lvmetad.c | 4 ++--
1 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/lib/cache/lvmetad.c b/lib/cache/lvmetad.c
index ee44202..a0a17ac 100644
--- a/lib/cache/lvmetad.c
+++ b/lib/cache/lvmetad.c
@@ -1484,8 +1484,8 @@ int lvmetad_pv_found(struct cmd_context *cmd, const struct id *pvid, struct devi
daemon_reply reply;
struct lvmcache_info *info;
struct dm_config_tree *pvmeta, *vgmeta;
- const char *status, *vgname;
- int64_t changed;
+ const char *status = NULL, *vgname = NULL;
+ int64_t changed = 0;
int result;
if (!lvmetad_used() || test_mode())
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=5070e7fcf79a3bcb…
Commit: 5070e7fcf79a3bcb21982d219c6f8dd484e523ea
Parent: fc174f6b74ee1d0fc12cca9fe5c392621acf069f
Author: Zdenek Kabelac <zkabelac(a)redhat.com>
AuthorDate: Thu Jun 23 22:35:51 2016 +0200
Committer: Zdenek Kabelac <zkabelac(a)redhat.com>
CommitterDate: Fri Jun 24 00:39:15 2016 +0200
tests: update test for modified output
We now print vg/lv for lv resized volume
---
test/shell/lvextend-percent-extents.sh | 12 ++++++------
1 files changed, 6 insertions(+), 6 deletions(-)
diff --git a/test/shell/lvextend-percent-extents.sh b/test/shell/lvextend-percent-extents.sh
index e2666e9..67c36b2 100644
--- a/test/shell/lvextend-percent-extents.sh
+++ b/test/shell/lvextend-percent-extents.sh
@@ -30,8 +30,8 @@ not lvextend -l 10 -L 64m $vg/$lv "$dev1" 2>err
grep "Please specify either size or extents but not both." err
# 'lvextend accepts no size or extents but one PV - bz154691'
-lvextend $vg/$lv "$dev1" >out
-grep "Logical volume $lv successfully resized" out
+lvextend $vg/$lv "$dev1" | tee out
+grep "Logical volume $vg/$lv successfully resized" out
check pv_field "$dev1" pv_free "0"
lvremove -f $vg/$lv
@@ -47,8 +47,8 @@ lvremove -f $vg/$lv
lvcreate -L 64m -n $lv $vg
# 'lvextend accepts no size but extents 100%PVS and two PVs - bz154691'
-lvextend -l +100%PVS $vg/$lv "$dev1" "$dev2" >out
-grep "Logical volume $lv successfully resized" out
+lvextend -l +100%PVS $vg/$lv "$dev1" "$dev2" | tee out
+grep "Logical volume $vg/$lv successfully resized" out
check pv_field "$dev1" pv_free "0"
check pv_field "$dev2" pv_free "0"
@@ -80,8 +80,8 @@ check lv_field $vg/$lv lv_size "48.00m"
# 'lvextend with partially allocated PVs and extents 100%PVS with PE ranges'
extend_pvs=$(for i in $(seq 0 6 18); do echo -n "$dev1:$i-$(($i + 2)) "; done)
-lvextend -l +100%PVS $vg/$lv $extend_pvs >out
-grep "Logical volume $lv successfully resized" out
+lvextend -l +100%PVS $vg/$lv $extend_pvs | tee out
+grep "Logical volume $vg/$lv successfully resized" out
check lv_field $vg/$lv lv_size "72.00m"
# Simple seg_count validation; initially create the LV with half the # of
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=fc174f6b74ee1d0f…
Commit: fc174f6b74ee1d0fc12cca9fe5c392621acf069f
Parent: 1c212371fa6e65c783d7df50eab0108acb7b0cf8
Author: Zdenek Kabelac <zkabelac(a)redhat.com>
AuthorDate: Fri Jun 24 00:35:42 2016 +0200
Committer: Zdenek Kabelac <zkabelac(a)redhat.com>
CommitterDate: Fri Jun 24 00:39:14 2016 +0200
tests: smaller number of devs created to fill metadata
---
test/shell/thin-flags.sh | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/test/shell/thin-flags.sh b/test/shell/thin-flags.sh
index 395b98d..7d87553 100644
--- a/test/shell/thin-flags.sh
+++ b/test/shell/thin-flags.sh
@@ -67,7 +67,7 @@ aux lvmconf 'global/thin_check_executable = ""'
# Prepare some fake metadata prefilled to ~100%
lvcreate -L2 -n $lv1 $vg # tmp for metadata
-aux prepare_thin_metadata 500 1 | tee data
+aux prepare_thin_metadata 490 1 | tee data
"$LVM_TEST_THIN_RESTORE_CMD" -i data -o "$DM_DEV_DIR/mapper/$vg-$lv1"
# Swap volume with restored fake metadata
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=1c212371fa6e65c7…
Commit: 1c212371fa6e65c783d7df50eab0108acb7b0cf8
Parent: 7c921f18e236055b2d6b20794be076124489d6ac
Author: Zdenek Kabelac <zkabelac(a)redhat.com>
AuthorDate: Fri Jun 24 00:35:03 2016 +0200
Committer: Zdenek Kabelac <zkabelac(a)redhat.com>
CommitterDate: Fri Jun 24 00:39:14 2016 +0200
cleanup: type cleanup
Fix return code 1.
Since we always check for !() - this fix has no other effect.
---
tools/toollib.c | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/tools/toollib.c b/tools/toollib.c
index 77c9f01..5c61ddd 100644
--- a/tools/toollib.c
+++ b/tools/toollib.c
@@ -1655,7 +1655,7 @@ int validate_restricted_lvname_param(struct cmd_context *cmd, const char **vg_na
if (lv_name && *lv_name && !apply_lvname_restrictions(*lv_name))
return_0;
- return -1;
+ return 1;
}
/*
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=7c921f18e236055b…
Commit: 7c921f18e236055b2d6b20794be076124489d6ac
Parent: 1bb7a155d169c3fc115533658206c242f43bdd0c
Author: Zdenek Kabelac <zkabelac(a)redhat.com>
AuthorDate: Fri Jun 24 00:33:40 2016 +0200
Committer: Zdenek Kabelac <zkabelac(a)redhat.com>
CommitterDate: Fri Jun 24 00:39:14 2016 +0200
lvresize: let pass even protected names like _tmeta
Only later validation can decide if the volume is actually restricted
from being resized (unlike in lvcreate time).
---
tools/lvresize.c | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/tools/lvresize.c b/tools/lvresize.c
index 35b7044..28fd0fd 100644
--- a/tools/lvresize.c
+++ b/tools/lvresize.c
@@ -113,7 +113,7 @@ static int _lvresize_params(struct cmd_context *cmd, int argc, char **argv,
lp->lv_name = argv[0];
- if (!validate_restricted_lvname_param(cmd, &lp->vg_name, &lp->lv_name))
+ if (!validate_lvname_param(cmd, &lp->vg_name, &lp->lv_name))
return_0;
/* Check for $LVM_VG_NAME */
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=1bb7a155d169c3fc…
Commit: 1bb7a155d169c3fc115533658206c242f43bdd0c
Parent: e99a31c9502a2081c6608a831b601081008cc3b0
Author: Zdenek Kabelac <zkabelac(a)redhat.com>
AuthorDate: Fri Jun 24 00:24:26 2016 +0200
Committer: Zdenek Kabelac <zkabelac(a)redhat.com>
CommitterDate: Fri Jun 24 00:39:14 2016 +0200
lvresize: fixes for recent commit
Merging process and patch rework missed some bits - fix them.
---
lib/metadata/lv_manip.c | 7 +++++--
tools/lvresize.c | 6 +-----
2 files changed, 6 insertions(+), 7 deletions(-)
diff --git a/lib/metadata/lv_manip.c b/lib/metadata/lv_manip.c
index 8f07267..40c1c1a 100644
--- a/lib/metadata/lv_manip.c
+++ b/lib/metadata/lv_manip.c
@@ -4452,7 +4452,7 @@ static uint32_t _adjust_amount(dm_percent_t percent, int policy_threshold, int p
percent = (percent / policy_threshold + (DM_PERCENT_1 - 1) / 100) / (DM_PERCENT_1 / 100) - 100;
/* Use it if current policy amount is smaller */
- return (policy_amount < percent) ? (uint32_t) policy_amount : (uint32_t) percent;
+ return (policy_amount < percent) ? (uint32_t) percent : (uint32_t) policy_amount;
}
static int _lvresize_adjust_policy(const struct logical_volume *lv,
@@ -5241,7 +5241,10 @@ int lv_resize(struct logical_volume *lv,
return_0;
if (lp->use_policies) {
- lp->percent = SIGN_PLUS;
+ lp->extents = 0;
+ lp->sign = SIGN_PLUS;
+ lp->percent = PERCENT_LV;
+
aux_lp = *lp;
if (!_lvresize_adjust_policy(lv, &lp->extents, &aux_lp.extents))
return_0;
diff --git a/tools/lvresize.c b/tools/lvresize.c
index 45d3558..35b7044 100644
--- a/tools/lvresize.c
+++ b/tools/lvresize.c
@@ -34,11 +34,7 @@ static int _lvresize_params(struct cmd_context *cmd, int argc, char **argv,
lp->sign = lp->poolmetadata_sign = SIGN_NONE;
if ((lp->use_policies = arg_is_set(cmd, usepolicies_ARG))) {
- /* do nothing; _lvresize will handle --use-policies itself */
- lp->extents = 0;
- lp->sign = SIGN_PLUS;
- lp->percent = PERCENT_LV;
-
+ /* do nothing; lv_resize will handle --use-policies itself */
if (arg_from_list_is_set(cmd, NULL,
chunksize_ARG, extents_ARG,
poolmetadatasize_ARG,
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=e99a31c9502a2081…
Commit: e99a31c9502a2081c6608a831b601081008cc3b0
Parent: a67a5d465576d4a7c17b22a737725d6dee059e18
Author: Alasdair G Kergon <agk(a)redhat.com>
AuthorDate: Thu Jun 23 21:31:49 2016 +0100
Committer: Alasdair G Kergon <agk(a)redhat.com>
CommitterDate: Thu Jun 23 21:31:49 2016 +0100
Revert "locking: trace errors from dir creation"
This reverts commit fa69ed0bc845df3d2c7ae68d03cdd4a3dec339d8.
This code sometimes expects to be presented with a read-only filesystem
(during some boot sequences for example) and copes appropriately with
this and it should not lead to expected error messages that might cause
unnecessary alarm.
---
WHATS_NEW | 3 +--
lib/locking/file_locking.c | 6 ++----
2 files changed, 3 insertions(+), 6 deletions(-)
diff --git a/WHATS_NEW b/WHATS_NEW
index a24325f..7238568 100644
--- a/WHATS_NEW
+++ b/WHATS_NEW
@@ -1,9 +1,8 @@
Version 2.02.158 -
=================================
Pool metadata lvresize uses now same code as resize of normal volume.
- Log system error when locking dir cannot be accessed.
Preserve monitoring status when updating thin-pool metadata.
- Rerurn 0 (inactive) when status cannot be queried in _lv_active().
+ Return 0 (inactive) when status cannot be queried in _lv_active().
Switch to log_warn() for failing activation status query.
Refactor lvconvert argument handling code.
Add --logonly option to report only cmd log for a command, not other reports.
diff --git a/lib/locking/file_locking.c b/lib/locking/file_locking.c
index 390f49f..230303b 100644
--- a/lib/locking/file_locking.c
+++ b/lib/locking/file_locking.c
@@ -158,13 +158,11 @@ int init_file_locking(struct locking_type *locking, struct cmd_context *cmd,
(void) dm_prepare_selinux_context(NULL, 0);
if (!r)
- return_0;
+ return 0;
/* Trap a read-only file system */
- if ((access(_lock_dir, R_OK | W_OK | X_OK) == -1) && (errno == EROFS)) {
- log_sys_error("access", _lock_dir);
+ if ((access(_lock_dir, R_OK | W_OK | X_OK) == -1) && (errno == EROFS))
return 0;
- }
return 1;
}
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=a67a5d465576d4a7…
Commit: a67a5d465576d4a7c17b22a737725d6dee059e18
Parent: 83d483269de367facc14eee9072b79ffabdcaf82
Author: Zdenek Kabelac <zkabelac(a)redhat.com>
AuthorDate: Mon Jun 13 14:35:09 2016 +0200
Committer: Zdenek Kabelac <zkabelac(a)redhat.com>
CommitterDate: Thu Jun 23 14:59:29 2016 +0200
tests: aux prepare_thin_metadata
---
test/lib/aux.sh | 23 +++++++++++++++++++++++
test/shell/lvextend-thin-full.sh | 18 +-----------------
test/shell/thin-flags.sh | 20 +-------------------
3 files changed, 25 insertions(+), 36 deletions(-)
diff --git a/test/lib/aux.sh b/test/lib/aux.sh
index d51a65c..8653149 100644
--- a/test/lib/aux.sh
+++ b/test/lib/aux.sh
@@ -354,6 +354,29 @@ prepare_lvmdbusd() {
echo ok
}
+#
+# Temporary solution to create some occupied thin metadata
+# This heavily depends on thin metadata output format to stay as is.
+# Currently it expects 2MB thin metadata and 200MB data volume size
+# Argument specifies how many devices should be created.
+#
+prepare_thin_metadata() {
+ local devices=$1
+ local transaction_id=${2:-0}
+ local data_block_size=${3:-128}
+ local nr_data_blocks=${4:-3200}
+ local i
+
+ echo '<superblock uuid="" time="1" transaction="'$transaction_id'" data_block_size="'$data_block_size'" nr_data_blocks="'$nr_data_blocks'">'
+ for i in $(seq 1 $devices)
+ do
+ echo ' <device dev_id="'$i'" mapped_blocks="37" transaction="'$i'" creation_time="0" snap_time="1">'
+ echo ' <range_mapping origin_begin="0" data_begin="0" length="37" time="0"/>'
+ echo ' </device>'
+ done
+ echo "</superblock>"
+}
+
teardown_devs_prefixed() {
local prefix=$1
local stray=${2:-0}
diff --git a/test/shell/lvextend-thin-full.sh b/test/shell/lvextend-thin-full.sh
index cd4705d..8fc89a8 100644
--- a/test/shell/lvextend-thin-full.sh
+++ b/test/shell/lvextend-thin-full.sh
@@ -25,22 +25,6 @@ aux have_thin 1 0 0 || skip
test -n "$LVM_TEST_THIN_RESTORE_CMD" || LVM_TEST_THIN_RESTORE_CMD=$(which thin_restore) || skip
"$LVM_TEST_THIN_RESTORE_CMD" -V || skip
-#
-# Temporary solution to create some occupied thin metadata
-# This heavily depends on thin metadata output format to stay as is.
-# Currently it expects 2MB thin metadata and 200MB data volume size
-# Argument specifies how many devices should be created.
-fake_metadata_() {
- echo '<superblock uuid="" time="1" transaction="'$2'" data_block_size="128" nr_data_blocks="3200">'
- for i in $(seq 1 $1)
- do
- echo ' <device dev_id="'$i'" mapped_blocks="37" transaction="0" creation_time="0" snap_time="1">'
- echo ' <range_mapping origin_begin="0" data_begin="0" length="37" time="0"/>'
- echo ' </device>'
- done
- echo "</superblock>"
-}
-
aux have_thin 1 10 0 || skip
aux prepare_pvs 3 256
@@ -50,7 +34,7 @@ vgcreate -s 1M $vg $(cat DEVICES)
aux lvmconf 'activation/thin_pool_autoextend_percent = 30' \
'activation/thin_pool_autoextend_threshold = 70'
-fake_metadata_ 400 0 >data
+aux prepare_thin_metadata 400 0 | tee data
lvcreate -L200 -T $vg/pool
lvchange -an $vg
diff --git a/test/shell/thin-flags.sh b/test/shell/thin-flags.sh
index 3fcafb2..395b98d 100644
--- a/test/shell/thin-flags.sh
+++ b/test/shell/thin-flags.sh
@@ -16,24 +16,6 @@ SKIP_WITH_LVMPOLLD=1
export LVM_TEST_THIN_REPAIR_CMD=${LVM_TEST_THIN_REPAIR_CMD-/bin/false}
-
-# TODO - aux/get support for this....
-fake_metadata_() {
- echo '<superblock uuid="" time="0" transaction="'$2'" data_block_size="128" nr_data_blocks="3200">'
- echo ' <device dev_id="1" mapped_blocks="0" transaction="0" creation_time="0" snap_time="0">'
- echo ' </device>'
- for i in $(seq 10 $1)
- do
- echo ' <device dev_id="'$i'" mapped_blocks="30" transaction="0" creation_time="0" snap_time="0">'
- echo ' <range_mapping origin_begin="0" data_begin="0" length="29" time="0"/>'
- echo ' </device>'
- set +x
- done
- echo "</superblock>"
- set -x
-}
-
-
. lib/inittest
#
@@ -85,7 +67,7 @@ aux lvmconf 'global/thin_check_executable = ""'
# Prepare some fake metadata prefilled to ~100%
lvcreate -L2 -n $lv1 $vg # tmp for metadata
-fake_metadata_ 500 1 >data
+aux prepare_thin_metadata 500 1 | tee data
"$LVM_TEST_THIN_RESTORE_CMD" -i data -o "$DM_DEV_DIR/mapper/$vg-$lv1"
# Swap volume with restored fake metadata
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=83d483269de367fa…
Commit: 83d483269de367facc14eee9072b79ffabdcaf82
Parent: e5b7ebcddabb885dd8a2f4cb5b5a0a32af834076
Author: Zdenek Kabelac <zkabelac(a)redhat.com>
AuthorDate: Wed Jun 15 14:55:37 2016 +0200
Committer: Zdenek Kabelac <zkabelac(a)redhat.com>
CommitterDate: Thu Jun 23 14:59:29 2016 +0200
cleanup: drop setting lv_name
lv_name arg is only used without known LV for resolving '*lv'.
Once we know *lv, never use lv_name ever again.
So setting it when passing *lv has not needed.
---
lib/locking/lvmlockd.c | 1 -
liblvm/lvm_lv.c | 1 -
2 files changed, 0 insertions(+), 2 deletions(-)
diff --git a/lib/locking/lvmlockd.c b/lib/locking/lvmlockd.c
index f9d215a..e025428 100644
--- a/lib/locking/lvmlockd.c
+++ b/lib/locking/lvmlockd.c
@@ -367,7 +367,6 @@ static int _extend_sanlock_lv(struct cmd_context *cmd, struct volume_group *vg,
{
struct logical_volume *lv = vg->sanlock_lv;
struct lvresize_params lp = {
- .lv_name = vg->sanlock_lv->name,
.sign = SIGN_NONE,
.size = lv->size + ((extend_mb * 1024 * 1024) / SECTOR_SIZE),
.percent = PERCENT_NONE,
diff --git a/liblvm/lvm_lv.c b/liblvm/lvm_lv.c
index ccdc340..05dd482 100644
--- a/liblvm/lvm_lv.c
+++ b/liblvm/lvm_lv.c
@@ -457,7 +457,6 @@ int lvm_lv_resize(const lv_t lv, uint64_t new_size)
{
int rc = 0;
struct lvresize_params lp = {
- .lv_name = lv->name,
.sign = SIGN_NONE,
.percent = PERCENT_NONE,
.resize = LV_ANY,
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=e5b7ebcddabb885d…
Commit: e5b7ebcddabb885dd8a2f4cb5b5a0a32af834076
Parent: 5a919e48053079670e6318fe862783e720dd2aea
Author: Zdenek Kabelac <zkabelac(a)redhat.com>
AuthorDate: Fri Jun 17 15:22:27 2016 +0200
Committer: Zdenek Kabelac <zkabelac(a)redhat.com>
CommitterDate: Thu Jun 23 14:59:29 2016 +0200
cleanup: remove unused code
---
lib/metadata/lv_manip.c | 83 --------------------------------------
lib/metadata/metadata-exported.h | 1 -
2 files changed, 0 insertions(+), 84 deletions(-)
diff --git a/lib/metadata/lv_manip.c b/lib/metadata/lv_manip.c
index 46815e3..8f07267 100644
--- a/lib/metadata/lv_manip.c
+++ b/lib/metadata/lv_manip.c
@@ -4549,89 +4549,6 @@ static uint32_t lvseg_get_stripes(struct lv_segment *seg, uint32_t *stripesize)
return 0;
}
-static int _lvresize_poolmetadata_prepare(struct logical_volume *pool_lv,
- struct lvresize_params *lp)
-{
- uint32_t extents;
- struct logical_volume *lv = first_seg(pool_lv)->metadata_lv;
- struct volume_group *vg = pool_lv->vg;
-
- lp->poolmetadataextents = 0;
-
- if (!thin_pool_feature_supported(pool_lv, THIN_FEATURE_METADATA_RESIZE)) {
- log_error("Support for online metadata resize not detected.");
- return 0;
- }
-
- if (lp->poolmetadata_size % vg->extent_size) {
- lp->poolmetadata_size += vg->extent_size -
- (lp->poolmetadata_size % vg->extent_size);
- log_print_unless_silent("Rounding pool metadata size to boundary between physical extents: %s",
- display_size(vg->cmd, lp->poolmetadata_size));
- }
-
- if (!(extents = extents_from_size(vg->cmd, lp->poolmetadata_size,
- vg->extent_size)))
- return_0;
-
- if (lp->poolmetadata_sign == SIGN_PLUS) {
- if (extents >= (MAX_EXTENT_COUNT - lv->le_count)) {
- log_error("Unable to extend %s by %u extents, exceeds limit (%u).",
- lv->name, lv->le_count, MAX_EXTENT_COUNT);
- return 0;
- }
- extents += lv->le_count;
- }
-
- if ((uint64_t)extents * vg->extent_size > DM_THIN_MAX_METADATA_SIZE) {
- log_print_unless_silent("Rounding size to maximum supported size 16GiB "
- "for metadata volume %s.", lv->name);
- extents = (DM_THIN_MAX_METADATA_SIZE + vg->extent_size - 1) /
- vg->extent_size;
- }
-
- /* FIXME Split here and move validation code earlier alongside rest of validation code */
- if (extents == lv->le_count) {
- log_print_unless_silent("Metadata volume %s has already %s.",
- display_lvname(lv), display_size(vg->cmd, lv->size));
- return 2;
- }
-
- lp->poolmetadataextents = extents;
-
- return 1;
-}
-
-static int _lvresize_poolmetadata(struct logical_volume *pool_lv,
- struct lvresize_params *lp,
- struct dm_list *pvh)
-{
- struct logical_volume *lv = first_seg(pool_lv)->metadata_lv;
- struct volume_group *vg = lv->vg;
- alloc_policy_t alloc = lp->alloc ? : lv->alloc;
- struct lv_segment *mseg = last_seg(lv);
- uint32_t seg_mirrors = lv_mirror_count(lv);
-
- if (!archive(vg))
- return_0;
-
- log_print_unless_silent("Extending logical volume %s to %s.",
- display_lvname(lv),
- display_size(vg->cmd, (uint64_t) lp->poolmetadataextents *
- vg->extent_size));
- if (!lv_extend(lv,
- mseg->segtype,
- mseg->area_count / seg_mirrors,
- mseg->stripe_size,
- seg_mirrors,
- mseg->region_size,
- lp->poolmetadataextents - lv->le_count,
- pvh, alloc, 0))
- return_0;
-
- return 1;
-}
-
static int _lvresize_check(struct logical_volume *lv,
struct lvresize_params *lp)
{
diff --git a/lib/metadata/metadata-exported.h b/lib/metadata/metadata-exported.h
index b8275d6..f47fa1d 100644
--- a/lib/metadata/metadata-exported.h
+++ b/lib/metadata/metadata-exported.h
@@ -609,7 +609,6 @@ struct lvresize_params {
uint64_t poolmetadata_size;
sign_t poolmetadata_sign;
- uint32_t poolmetadataextents;
/* Per LV applied parameters */
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=5a919e4805307967…
Commit: 5a919e48053079670e6318fe862783e720dd2aea
Parent: 4de15aa58d2cd25075d3b17c3d3d9ad06b4bb493
Author: Zdenek Kabelac <zkabelac(a)redhat.com>
AuthorDate: Fri Jun 17 13:25:56 2016 +0200
Committer: Zdenek Kabelac <zkabelac(a)redhat.com>
CommitterDate: Thu Jun 23 14:59:29 2016 +0200
cleanup: remove unused sizearg variable
It's not used for anything now.
---
lib/locking/lvmlockd.c | 1 -
lib/metadata/lv_manip.c | 1 -
lib/metadata/metadata-exported.h | 1 -
liblvm/lvm_lv.c | 1 -
tools/lvresize.c | 1 -
5 files changed, 0 insertions(+), 5 deletions(-)
diff --git a/lib/locking/lvmlockd.c b/lib/locking/lvmlockd.c
index e865c10..f9d215a 100644
--- a/lib/locking/lvmlockd.c
+++ b/lib/locking/lvmlockd.c
@@ -373,7 +373,6 @@ static int _extend_sanlock_lv(struct cmd_context *cmd, struct volume_group *vg,
.percent = PERCENT_NONE,
.resize = LV_EXTEND,
.force = 1,
- .sizeargs = 1,
};
if (!lv_resize(lv, &lp, &vg->pvs)) {
diff --git a/lib/metadata/lv_manip.c b/lib/metadata/lv_manip.c
index 70969e8..46815e3 100644
--- a/lib/metadata/lv_manip.c
+++ b/lib/metadata/lv_manip.c
@@ -5004,7 +5004,6 @@ static int _lvresize_adjust_extents(struct logical_volume *lv,
seg_size = lp->extents - existing_logical_extents; // Recalculate
if (lp->extents == existing_logical_extents) {
/* Signal that normal resizing is not required */
- lp->sizeargs = 0;
return 1;
}
}
diff --git a/lib/metadata/metadata-exported.h b/lib/metadata/metadata-exported.h
index d2c9db2..b8275d6 100644
--- a/lib/metadata/metadata-exported.h
+++ b/lib/metadata/metadata-exported.h
@@ -607,7 +607,6 @@ struct lvresize_params {
const struct segment_type *segtype;
- int sizeargs;
uint64_t poolmetadata_size;
sign_t poolmetadata_sign;
uint32_t poolmetadataextents;
diff --git a/liblvm/lvm_lv.c b/liblvm/lvm_lv.c
index d732ed7..ccdc340 100644
--- a/liblvm/lvm_lv.c
+++ b/liblvm/lvm_lv.c
@@ -463,7 +463,6 @@ int lvm_lv_resize(const lv_t lv, uint64_t new_size)
.resize = LV_ANY,
.size = new_size >> SECTOR_SHIFT,
.force = 1, /* Assume the user has a good backup? */
- .sizeargs = 1,
};
struct saved_env e = store_user_env(lv->vg->cmd);
diff --git a/tools/lvresize.c b/tools/lvresize.c
index 1258f14..45d3558 100644
--- a/tools/lvresize.c
+++ b/tools/lvresize.c
@@ -55,7 +55,6 @@ static int _lvresize_params(struct cmd_context *cmd, int argc, char **argv,
* If only --poolmetadatasize is specified with list of PVs,
* then metadata will be extended there.
*/
- lp->sizeargs = arg_is_set(cmd, extents_ARG) + arg_is_set(cmd, size_ARG);
if ((lp->extents = arg_uint_value(cmd, extents_ARG, 0))) {
lp->sign = arg_sign_value(cmd, extents_ARG, SIGN_NONE);
lp->percent = arg_percent_value(cmd, extents_ARG, PERCENT_NONE);
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=4de15aa58d2cd250…
Commit: 4de15aa58d2cd25075d3b17c3d3d9ad06b4bb493
Parent: 7092c6ba1084dcc029ffef918c0419ebdd41b5f4
Author: Zdenek Kabelac <zkabelac(a)redhat.com>
AuthorDate: Fri Jun 17 11:29:28 2016 +0200
Committer: Zdenek Kabelac <zkabelac(a)redhat.com>
CommitterDate: Thu Jun 23 14:59:29 2016 +0200
lvresize: return 0/1
Returning locking LV is no longer used from here, so return 1/0.
---
lib/metadata/lv_manip.c | 34 +++++++++++-----------------------
1 files changed, 11 insertions(+), 23 deletions(-)
diff --git a/lib/metadata/lv_manip.c b/lib/metadata/lv_manip.c
index 17e44cc..70969e8 100644
--- a/lib/metadata/lv_manip.c
+++ b/lib/metadata/lv_manip.c
@@ -5197,13 +5197,12 @@ static int _lvresize_check_type(const struct logical_volume *lv,
return 1;
}
-static struct logical_volume *_lvresize_volume(struct logical_volume *lv,
- struct lvresize_params *lp,
- struct dm_list *pvh)
+static int _lvresize_volume(struct logical_volume *lv,
+ struct lvresize_params *lp,
+ struct dm_list *pvh)
{
struct volume_group *vg = lv->vg;
struct cmd_context *cmd = vg->cmd;
- struct logical_volume *lock_lv = NULL;
uint32_t old_extents;
int status;
alloc_policy_t alloc = lp->alloc ? : lv->alloc;
@@ -5214,14 +5213,14 @@ static struct logical_volume *_lvresize_volume(struct logical_volume *lv,
/* Request confirmation before operations that are often mistakes. */
if ((lp->resizefs || (lp->resize == LV_REDUCE)) &&
!_request_confirmation(lv, lp))
- return_NULL;
+ return_0;
if (lp->resizefs) {
if (!lp->nofsck &&
!_fsadm_cmd(FSADM_CMD_CHECK, lv, 0, lp->force, &status)) {
if (status != FSADM_CHECK_FAILS_FOR_MOUNTED) {
log_error("Filesystem check failed.");
- return NULL;
+ return 0;
}
/* some filesystems support online resize */
}
@@ -5230,12 +5229,12 @@ static struct logical_volume *_lvresize_volume(struct logical_volume *lv,
if ((lp->resize == LV_REDUCE) &&
!_fsadm_cmd(FSADM_CMD_RESIZE, lv, lp->extents, lp->force, NULL)) {
log_error("Filesystem resize failed.");
- return NULL;
+ return 0;
}
}
if (!archive(vg))
- return_NULL;
+ return_0;
old_extents = lv->le_count;
log_verbose("%sing logical volume %s to %s%s",
@@ -5245,18 +5244,18 @@ static struct logical_volume *_lvresize_volume(struct logical_volume *lv,
if (lp->resize == LV_REDUCE) {
if (!lv_reduce(lv, lv->le_count - lp->extents))
- return_NULL;
+ return_0;
} else if ((lp->extents > lv->le_count) && /* Ensure we extend */
!lv_extend(lv, lp->segtype,
lp->stripes, lp->stripe_size,
lp->mirrors, first_seg(lv)->region_size,
lp->extents - lv->le_count,
pvh, alloc, lp->approx_alloc))
- return_NULL;
+ return_0;
/* Check for over provisioning only when lv_extend() passed,
* ATM this check does not fail */
else if (!pool_check_overprovisioning(lv))
- return_NULL;
+ return_0;
if (old_extents == lv->le_count)
log_print_unless_silent("Size of logical volume %s unchanged from %s (%" PRIu32 " extents).",
@@ -5268,18 +5267,7 @@ static struct logical_volume *_lvresize_volume(struct logical_volume *lv,
display_size(cmd, (uint64_t) old_extents * vg->extent_size), old_extents,
display_size(cmd, (uint64_t) lv->le_count * vg->extent_size), lv->le_count);
- if (lock_lv) {
- /* If thin metadata, must suspend thin pool */
- } else if (lv_is_thin_pool_metadata(lv)) {
- if (!(lock_lv = find_pool_lv(lv)))
- return_NULL;
- /* If snapshot, must suspend all associated devices */
- } else if (lv_is_cow(lv))
- lock_lv = origin_from_cow(lv);
- else
- lock_lv = lv;
-
- return lock_lv;
+ return 1;
}
static int _lvresize_prepare(struct logical_volume **lv,
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=7092c6ba1084dcc0…
Commit: 7092c6ba1084dcc029ffef918c0419ebdd41b5f4
Parent: d44e653fe184a6c179a13998b41e13f737d4926c
Author: Zdenek Kabelac <zkabelac(a)redhat.com>
AuthorDate: Wed Jun 22 23:32:35 2016 +0200
Committer: Zdenek Kabelac <zkabelac(a)redhat.com>
CommitterDate: Thu Jun 23 14:59:27 2016 +0200
lvresize: support more resized LVs
Add code to support more LVs to be resized through a same code path
using a single lvresize_params struct.
(Now it's used for thin-pool metadata resize,
next user will be snapshot virtual resize).
Update code to adjust percent amount resize for use_policies.
Properly activate inactive thin-pool in case of any pool resize
as the command should not 'deffer' this operation to next activation.
---
WHATS_NEW | 1 +
lib/metadata/lv_manip.c | 221 +++++++++++++++++++++++++----------------------
2 files changed, 120 insertions(+), 102 deletions(-)
diff --git a/WHATS_NEW b/WHATS_NEW
index 5e2cb5a..a24325f 100644
--- a/WHATS_NEW
+++ b/WHATS_NEW
@@ -1,5 +1,6 @@
Version 2.02.158 -
=================================
+ Pool metadata lvresize uses now same code as resize of normal volume.
Log system error when locking dir cannot be accessed.
Preserve monitoring status when updating thin-pool metadata.
Rerurn 0 (inactive) when status cannot be queried in _lv_active().
diff --git a/lib/metadata/lv_manip.c b/lib/metadata/lv_manip.c
index e42a73c..17e44cc 100644
--- a/lib/metadata/lv_manip.c
+++ b/lib/metadata/lv_manip.c
@@ -4439,7 +4439,7 @@ static int _fsadm_cmd(enum fsadm_cmd_e fcmd,
return exec_cmd(cmd, argv, status, 1);
}
-static int _adjust_amount(dm_percent_t percent, int policy_threshold, int *policy_amount)
+static uint32_t _adjust_amount(dm_percent_t percent, int policy_threshold, int policy_amount)
{
if (!(DM_PERCENT_0 < percent && percent <= DM_PERCENT_100) ||
percent <= (policy_threshold * DM_PERCENT_1))
@@ -4452,18 +4452,18 @@ static int _adjust_amount(dm_percent_t percent, int policy_threshold, int *polic
percent = (percent / policy_threshold + (DM_PERCENT_1 - 1) / 100) / (DM_PERCENT_1 / 100) - 100;
/* Use it if current policy amount is smaller */
- if (*policy_amount < percent)
- *policy_amount = percent;
-
- return 1;
+ return (policy_amount < percent) ? (uint32_t) policy_amount : (uint32_t) percent;
}
-static int _adjust_policy_params(struct logical_volume *lv, struct lvresize_params *lp)
+static int _lvresize_adjust_policy(const struct logical_volume *lv,
+ uint32_t *amount, uint32_t *meta_amount)
{
struct cmd_context *cmd = lv->vg->cmd;
dm_percent_t percent;
int policy_threshold, policy_amount;
+ *amount = *meta_amount = 0;
+
if (lv_is_thin_pool(lv)) {
policy_threshold =
find_config_tree_int(cmd, activation_thin_pool_autoextend_threshold_CFG,
@@ -4488,11 +4488,8 @@ static int _adjust_policy_params(struct logical_volume *lv, struct lvresize_para
}
}
- if (policy_threshold >= 100) {
- lp->extents = lp->poolmetadata_size = 0;
- lp->sizeargs = 0;
+ if (policy_threshold >= 100)
return 1; /* nothing to do */
- }
if (!policy_amount) {
log_error("Can't extend %s with %s autoextend percent set to 0%%.",
@@ -4509,16 +4506,9 @@ static int _adjust_policy_params(struct logical_volume *lv, struct lvresize_para
if (lv_is_thin_pool(lv)) {
if (!lv_thin_pool_percent(lv, 1, &percent))
return_0;
- if (_adjust_amount(percent, policy_threshold, &policy_amount)) {
- if (!thin_pool_feature_supported(lv, THIN_FEATURE_METADATA_RESIZE)) {
- log_error_once("Online metadata resize for %s is not supported.",
- display_lvname(lv));
- return 0;
- }
- lp->poolmetadata_size = (first_seg(lv)->metadata_lv->size *
- policy_amount + 99) / 100;
- lp->poolmetadata_sign = SIGN_PLUS;
- }
+
+ *meta_amount = _adjust_amount(percent, policy_threshold, policy_amount);
+
if (!lv_thin_pool_percent(lv, 0, &percent))
return_0;
} else {
@@ -4526,11 +4516,7 @@ static int _adjust_policy_params(struct logical_volume *lv, struct lvresize_para
return_0;
}
- if (!_adjust_amount(percent, policy_threshold, &policy_amount))
- return 1; /* nothing to do */
-
- lp->extents = policy_amount;
- lp->sizeargs = (lp->extents) ? 1 : 0;
+ *amount = _adjust_amount(percent, policy_threshold, policy_amount);
return 1;
}
@@ -4646,8 +4632,8 @@ static int _lvresize_poolmetadata(struct logical_volume *pool_lv,
return 1;
}
-static int _lvresize_check_lv(struct logical_volume *lv,
- struct lvresize_params *lp)
+static int _lvresize_check(struct logical_volume *lv,
+ struct lvresize_params *lp)
{
struct volume_group *vg = lv->vg;
@@ -4884,10 +4870,6 @@ static int _lvresize_adjust_extents(struct logical_volume *lv,
uint32_t new_extents;
int reducing = 0;
- if (lv_is_thin_pool(lv))
- /* Manipulate the thin data layer underneath */
- lv = seg_lv(first_seg(lv), 0);
-
seg_last = last_seg(lv);
/* FIXME Support LVs with mixed segment types */
@@ -5086,12 +5068,6 @@ static int _lvresize_adjust_extents(struct logical_volume *lv,
}
if (lp->extents == existing_logical_extents) {
- if (lp->poolmetadata_size || lp->use_policies) {
- /* Signal that normal resizing is not required */
- lp->sizeargs = 0;
- return 1;
- }
-
if (!lp->resizefs) {
log_error("New size (%d extents) matches existing size "
"(%d extents)", lp->extents, existing_logical_extents);
@@ -5192,8 +5168,9 @@ static int _lvresize_check_type(const struct logical_volume *lv,
}
if (lp->resize == LV_REDUCE) {
- if (lv_is_thin_pool(lv)) {
- log_error("Thin pool volumes cannot be reduced in size yet.");
+ if (lv_is_thin_pool_data(lv)) {
+ log_error("Thin pool volumes %s cannot be reduced in size yet.",
+ display_lvname(lv));
return 0;
}
if (lv_is_thin_pool_metadata(lv)) {
@@ -5201,6 +5178,13 @@ static int _lvresize_check_type(const struct logical_volume *lv,
return 0;
}
} else if (lp->resize == LV_EXTEND) {
+ if (lv_is_thin_pool_metadata(lv) &&
+ !thin_pool_feature_supported(find_pool_seg(first_seg(lv))->lv, THIN_FEATURE_METADATA_RESIZE)) {
+ log_error("Support for online metadata resize of %s not detected.",
+ display_lvname(lv));
+ return 0;
+ }
+
/* Validate thin target supports bigger size of thin volume then external origin */
if (lv_is_thin_volume(lv) && first_seg(lv)->external_lv &&
(lv->size > first_seg(lv)->external_lv->size) &&
@@ -5220,18 +5204,9 @@ static struct logical_volume *_lvresize_volume(struct logical_volume *lv,
struct volume_group *vg = lv->vg;
struct cmd_context *cmd = vg->cmd;
struct logical_volume *lock_lv = NULL;
- struct lv_segment *seg = NULL;
uint32_t old_extents;
int status;
- alloc_policy_t alloc;
-
- if (lv_is_thin_pool(lv)) {
- lock_lv = lv;
- seg = first_seg(lv);
- /* Switch to layered LV resizing */
- lv = seg_lv(seg, 0);
- }
- alloc = lp->alloc ? : lv->alloc;
+ alloc_policy_t alloc = lp->alloc ? : lv->alloc;
if ((lp->resize == LV_REDUCE) && (pvh != &vg->pvs))
log_print_unless_silent("Ignoring PVs on command line when reducing.");
@@ -5307,81 +5282,106 @@ static struct logical_volume *_lvresize_volume(struct logical_volume *lv,
return lock_lv;
}
-static int _lvresize_prepare(struct logical_volume *lv,
+static int _lvresize_prepare(struct logical_volume **lv,
struct lvresize_params *lp,
struct dm_list *pvh)
{
- if (!_lvresize_check_lv(lv, lp))
- return_0;
+ struct volume_group *vg = (*lv)->vg;
- if (lp->use_policies && !_adjust_policy_params(lv, lp))
- return_0;
+ if (lv_is_thin_pool(*lv))
+ *lv = seg_lv(first_seg(*lv), 0); /* switch to data LV */
- if (lp->size && !_lvresize_adjust_size(lv->vg, lp->size, lp->sign,
- &lp->extents))
- return_0;
- else if (lp->extents && !_lvresize_extents_from_percent(lv, lp, pvh))
+ /* Resolve extents from size */
+ if (lp->size && !_lvresize_adjust_size(vg, lp->size, lp->sign, &lp->extents))
return_0;
-
- if (lp->extents && !_lvresize_adjust_extents(lv, lp, pvh))
+ else if (lp->extents && !_lvresize_extents_from_percent(*lv, lp, pvh))
return_0;
- if ((lp->extents == lv->le_count) && lp->use_policies) {
- /* Nothing to do. */
- lp->sizeargs = 0;
- lp->poolmetadata_size = 0;
- }
-
- if (lp->extents && !_lvresize_check_type(lv, lp))
+ if (lp->extents && !_lvresize_adjust_extents(*lv, lp, pvh))
return_0;
- if (lp->poolmetadata_size &&
- !_lvresize_poolmetadata_prepare(lv, lp))
+ if (lp->extents && !_lvresize_check_type(*lv, lp))
return_0;
return 1;
}
+/* Set aux LV properties, we can't use those from command line */
+static struct logical_volume *_lvresize_setup_aux(struct logical_volume *lv,
+ struct lvresize_params *lp)
+{
+ struct lv_segment *mseg = last_seg(lv);
+
+ lp->alloc = lv->alloc;
+ lp->mirrors = seg_is_mirrored(mseg) ? lv_mirror_count(lv) : 0;
+ lp->resizefs = 0;
+ lp->stripes = lp->mirrors ? mseg->area_count / lp->mirrors : 0;
+ lp->stripe_size = mseg->stripe_size;
+
+ return lv;
+}
+
int lv_resize(struct logical_volume *lv,
struct lvresize_params *lp,
struct dm_list *pvh)
{
struct volume_group *vg = lv->vg;
struct cmd_context *cmd = vg->cmd;
- struct logical_volume *lock_lv = NULL;
- int inactive = 0;
+ struct logical_volume *lock_lv = (struct logical_volume*) lv_lock_holder(lv);
+ struct logical_volume *aux_lv = NULL; /* Note: aux_lv never resizes fs */
+ struct lvresize_params aux_lp;
+ int activated = 0;
+ int ret = 0;
- if (!_lvresize_prepare(lv, lp, pvh))
+ if (!_lvresize_check(lv, lp))
return_0;
- if (lv_is_cache_type(lv)) {
- log_error("Unable to resize logical volumes of cache type.");
- return 0;
+ if (lp->use_policies) {
+ lp->percent = SIGN_PLUS;
+ aux_lp = *lp;
+ if (!_lvresize_adjust_policy(lv, &lp->extents, &aux_lp.extents))
+ return_0;
+
+ if (!lp->extents) {
+ if (!aux_lp.extents)
+ return 1; /* Nothing to do */
+ /* Resize thin-pool metadata as mainlv */
+ lv = first_seg(lv)->metadata_lv; /* metadata LV */
+ lp->extents = aux_lp.extents;
+ } else if (aux_lp.extents) {
+ /* Also resize thin-pool metadata */
+ aux_lv = _lvresize_setup_aux(first_seg(lv)->metadata_lv, &aux_lp);
+ }
+ } else if (lp->poolmetadata_size) {
+ if (!lp->extents && !lp->size) {
+ /* When only --poolmetadatasize give and not --size
+ * swith directly to resize metadata LV */
+ lv = first_seg(lv)->metadata_lv;
+ lp->size = lp->poolmetadata_size;
+ lp->sign = lp->poolmetadata_sign;
+ } else {
+ aux_lp = *lp;
+ aux_lv = _lvresize_setup_aux(first_seg(lv)->metadata_lv, &aux_lp);
+ aux_lp.size = lp->poolmetadata_size;
+ aux_lp.sign = lp->poolmetadata_sign;
+ }
}
- /*
- * If the LV is locked from activation, this lock call is a no-op.
- * Otherwise, this acquires a transient lock on the lv (not PERSISTENT).
- */
- if (!lockd_lv(cmd, lv, "ex", 0))
+ if (aux_lv && !_lvresize_prepare(&aux_lv, &aux_lp, pvh))
return_0;
- if (lp->extents &&
- !(lock_lv = _lvresize_volume(lv, lp, pvh)))
+ if (!_lvresize_prepare(&lv, lp, pvh))
return_0;
- if (lp->poolmetadataextents) {
- if (!_lvresize_poolmetadata(lv, lp, pvh))
- return_0;
- lock_lv = lv;
- }
-
- if (!lock_lv)
- return 1; /* Nothing to do */
-
- if (lv_is_thin_pool(lock_lv) &&
- pool_is_active(lock_lv) &&
+ if (lv_is_thin_pool(lock_lv) && /* Lock holder is thin-pool */
!lv_is_active(lock_lv)) {
+
+ if (!activation()) {
+ log_error("Cannot resize %s without using "
+ "device-mapper kernel driver.",
+ display_lvname(lock_lv));
+ return 0;
+ }
/*
* Active 'hidden' -tpool can be waiting for resize, but the
* pool LV itself might be inactive.
@@ -5390,13 +5390,33 @@ int lv_resize(struct logical_volume *lv,
* then use suspend and resume and deactivate pool LV,
* instead of searching for an active thin volume.
*/
- inactive = 1;
if (!activate_lv_excl(cmd, lock_lv)) {
log_error("Failed to activate %s.", display_lvname(lock_lv));
return 0;
}
+
+ activated = 1;
}
+ /*
+ * If the LV is locked from activation, this lock call is a no-op.
+ * Otherwise, this acquires a transient lock on the lv (not PERSISTENT).
+ */
+ if (!lockd_lv(cmd, lock_lv, "ex", 0))
+ return_0;
+
+ if (aux_lv) {
+ if (!_lvresize_volume(aux_lv, &aux_lp, pvh))
+ goto_bad;
+
+ /* store vg on disk(s) */
+ if (!lv_update_and_reload(lock_lv))
+ goto_bad;
+ }
+
+ if (!_lvresize_volume(lv, lp, pvh))
+ goto_bad;
+
/* store vg on disk(s) */
if (!lv_update_and_reload(lock_lv))
goto_bad;
@@ -5411,11 +5431,6 @@ int lv_resize(struct logical_volume *lv,
goto_bad;
backup(vg);
-
- if (inactive && !deactivate_lv(cmd, lock_lv)) {
- log_error("Problem deactivating %s.", display_lvname(lock_lv));
- return 0;
- }
}
log_print_unless_silent("Logical volume %s successfully resized.",
@@ -5425,12 +5440,14 @@ int lv_resize(struct logical_volume *lv,
!_fsadm_cmd(FSADM_CMD_RESIZE, lv, lp->extents, lp->force, NULL))
return_0;
- return 1;
+ ret = 1;
bad:
- if (inactive && !deactivate_lv(cmd, lock_lv))
+ if (activated && !deactivate_lv(cmd, lock_lv)) {
log_error("Problem deactivating %s.", display_lvname(lock_lv));
+ ret = 0;
+ }
- return 0;
+ return ret;
}
char *generate_lv_name(struct volume_group *vg, const char *format,
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=d44e653fe184a6c1…
Commit: d44e653fe184a6c179a13998b41e13f737d4926c
Parent: 5013999c8bd3f2b455ab6fe436df4884da6ebaf5
Author: Zdenek Kabelac <zkabelac(a)redhat.com>
AuthorDate: Tue Jun 14 15:32:21 2016 +0200
Committer: Zdenek Kabelac <zkabelac(a)redhat.com>
CommitterDate: Thu Jun 23 14:57:09 2016 +0200
lvresize: do not pass struct cmd
Use common API design and pass just LV pointer to lv_manip.c functions.
Read cmd struct via lv->vg->cmd when needed.
Also do not try to return EINVALID_CMD_LINE error when we
have already openned VG - this error code can only be returned before
locking VG.
---
lib/locking/lvmlockd.c | 3 +-
lib/metadata/lv_manip.c | 42 ++++++++++++++++++++++---------------
lib/metadata/metadata-exported.h | 7 ++---
liblvm/lvm_lv.c | 3 +-
tools/lvresize.c | 7 +-----
5 files changed, 31 insertions(+), 31 deletions(-)
diff --git a/lib/locking/lvmlockd.c b/lib/locking/lvmlockd.c
index e2b3e25..e865c10 100644
--- a/lib/locking/lvmlockd.c
+++ b/lib/locking/lvmlockd.c
@@ -376,8 +376,7 @@ static int _extend_sanlock_lv(struct cmd_context *cmd, struct volume_group *vg,
.sizeargs = 1,
};
- if (!lv_resize_prepare(cmd, lv, &lp, &vg->pvs) ||
- !lv_resize(cmd, lv, &lp, &vg->pvs)) {
+ if (!lv_resize(lv, &lp, &vg->pvs)) {
log_error("Extend LV %s to size %s failed.",
display_lvname(lv), display_size(cmd, lp.size));
return 0;
diff --git a/lib/metadata/lv_manip.c b/lib/metadata/lv_manip.c
index 487d7f9..e42a73c 100644
--- a/lib/metadata/lv_manip.c
+++ b/lib/metadata/lv_manip.c
@@ -4336,10 +4336,10 @@ static int _validate_stripesize(const struct volume_group *vg,
return 1;
}
-static int _request_confirmation(const struct volume_group *vg,
- const struct logical_volume *lv,
+static int _request_confirmation(const struct logical_volume *lv,
const struct lvresize_params *lp)
{
+ const struct volume_group *vg = lv->vg;
struct lvinfo info = { 0 };
if (!lv_info(vg->cmd, lv, 0, &info, 1, 0) && driver_version(NULL, 0)) {
@@ -4766,10 +4766,11 @@ static int _lvresize_adjust_size(struct volume_group *vg,
/*
* If percent options were used, convert them into actual numbers of extents.
*/
-static int _lvresize_extents_from_percent(struct logical_volume *lv, struct lvresize_params *lp,
+static int _lvresize_extents_from_percent(const struct logical_volume *lv,
+ struct lvresize_params *lp,
struct dm_list *pvh)
{
- struct volume_group *vg = lv->vg;
+ const struct volume_group *vg = lv->vg;
uint32_t pv_extent_count;
uint32_t old_extents = lp->extents;
@@ -4859,10 +4860,12 @@ static uint32_t _lv_pe_count(struct logical_volume *lv)
}
/* FIXME Avoid having variables like lp->extents mean different things at different places */
-static int _lvresize_adjust_extents(struct cmd_context *cmd, struct logical_volume *lv,
- struct lvresize_params *lp, struct dm_list *pvh)
+static int _lvresize_adjust_extents(struct logical_volume *lv,
+ struct lvresize_params *lp,
+ struct dm_list *pvh)
{
struct volume_group *vg = lv->vg;
+ struct cmd_context *cmd = vg->cmd;
uint32_t logical_extents_used = 0;
uint32_t physical_extents_used = 0;
uint32_t seg_stripes = 0, seg_stripesize = 0;
@@ -5173,7 +5176,7 @@ static int _lvresize_adjust_extents(struct cmd_context *cmd, struct logical_volu
}
static int _lvresize_check_type(const struct logical_volume *lv,
- struct lvresize_params *lp)
+ const struct lvresize_params *lp)
{
if (lv_is_origin(lv)) {
if (lp->resize == LV_REDUCE) {
@@ -5210,12 +5213,12 @@ static int _lvresize_check_type(const struct logical_volume *lv,
return 1;
}
-static struct logical_volume *_lvresize_volume(struct cmd_context *cmd,
- struct logical_volume *lv,
+static struct logical_volume *_lvresize_volume(struct logical_volume *lv,
struct lvresize_params *lp,
struct dm_list *pvh)
{
struct volume_group *vg = lv->vg;
+ struct cmd_context *cmd = vg->cmd;
struct logical_volume *lock_lv = NULL;
struct lv_segment *seg = NULL;
uint32_t old_extents;
@@ -5235,7 +5238,7 @@ static struct logical_volume *_lvresize_volume(struct cmd_context *cmd,
/* Request confirmation before operations that are often mistakes. */
if ((lp->resizefs || (lp->resize == LV_REDUCE)) &&
- !_request_confirmation(vg, lv, lp))
+ !_request_confirmation(lv, lp))
return_NULL;
if (lp->resizefs) {
@@ -5304,8 +5307,9 @@ static struct logical_volume *_lvresize_volume(struct cmd_context *cmd,
return lock_lv;
}
-int lv_resize_prepare(struct cmd_context *cmd, struct logical_volume *lv,
- struct lvresize_params *lp, struct dm_list *pvh)
+static int _lvresize_prepare(struct logical_volume *lv,
+ struct lvresize_params *lp,
+ struct dm_list *pvh)
{
if (!_lvresize_check_lv(lv, lp))
return_0;
@@ -5319,7 +5323,7 @@ int lv_resize_prepare(struct cmd_context *cmd, struct logical_volume *lv,
else if (lp->extents && !_lvresize_extents_from_percent(lv, lp, pvh))
return_0;
- if (lp->extents && !_lvresize_adjust_extents(cmd, lv, lp, pvh))
+ if (lp->extents && !_lvresize_adjust_extents(lv, lp, pvh))
return_0;
if ((lp->extents == lv->le_count) && lp->use_policies) {
@@ -5338,14 +5342,18 @@ int lv_resize_prepare(struct cmd_context *cmd, struct logical_volume *lv,
return 1;
}
-/* lv_resize_prepare MUST be called before this */
-int lv_resize(struct cmd_context *cmd, struct logical_volume *lv,
- struct lvresize_params *lp, struct dm_list *pvh)
+int lv_resize(struct logical_volume *lv,
+ struct lvresize_params *lp,
+ struct dm_list *pvh)
{
struct volume_group *vg = lv->vg;
+ struct cmd_context *cmd = vg->cmd;
struct logical_volume *lock_lv = NULL;
int inactive = 0;
+ if (!_lvresize_prepare(lv, lp, pvh))
+ return_0;
+
if (lv_is_cache_type(lv)) {
log_error("Unable to resize logical volumes of cache type.");
return 0;
@@ -5359,7 +5367,7 @@ int lv_resize(struct cmd_context *cmd, struct logical_volume *lv,
return_0;
if (lp->extents &&
- !(lock_lv = _lvresize_volume(cmd, lv, lp, pvh)))
+ !(lock_lv = _lvresize_volume(lv, lp, pvh)))
return_0;
if (lp->poolmetadataextents) {
diff --git a/lib/metadata/metadata-exported.h b/lib/metadata/metadata-exported.h
index ddf51fc..d2c9db2 100644
--- a/lib/metadata/metadata-exported.h
+++ b/lib/metadata/metadata-exported.h
@@ -693,10 +693,9 @@ int vgs_are_compatible(struct cmd_context *cmd,
struct volume_group *vg_to);
uint32_t vg_lock_newname(struct cmd_context *cmd, const char *vgname);
-int lv_resize_prepare(struct cmd_context *cmd, struct logical_volume *lv,
- struct lvresize_params *lp, struct dm_list *pvh);
-int lv_resize(struct cmd_context *cmd, struct logical_volume *lv,
- struct lvresize_params *lp, struct dm_list *pvh);
+int lv_resize(struct logical_volume *lv,
+ struct lvresize_params *lp,
+ struct dm_list *pvh);
/*
* Return a handle to VG metadata.
diff --git a/liblvm/lvm_lv.c b/liblvm/lvm_lv.c
index 467a9d0..d732ed7 100644
--- a/liblvm/lvm_lv.c
+++ b/liblvm/lvm_lv.c
@@ -467,8 +467,7 @@ int lvm_lv_resize(const lv_t lv, uint64_t new_size)
};
struct saved_env e = store_user_env(lv->vg->cmd);
- if (!lv_resize_prepare(lv->vg->cmd, lv, &lp, &lv->vg->pvs) ||
- !lv_resize(lv->vg->cmd, lv, &lp, &lv->vg->pvs)) {
+ if (!lv_resize(lv, &lp, &lv->vg->pvs)) {
/* FIXME Improve msg */
log_error("LV resize failed.");
/* FIXME Define consistent symbolic return codes */
diff --git a/tools/lvresize.c b/tools/lvresize.c
index af2b3ac..1258f14 100644
--- a/tools/lvresize.c
+++ b/tools/lvresize.c
@@ -175,12 +175,7 @@ static int _lvresize_single(struct cmd_context *cmd, const char *vg_name,
if (!(pvh = lp->argc ? create_pv_list(cmd->mem, vg, lp->argc, lp->argv, 1) : &vg->pvs))
goto_out;
- if (!lv_resize_prepare(cmd, lv, lp, pvh)) {
- ret = EINVALID_CMD_LINE;
- goto_out;
- }
-
- if (!lv_resize(cmd, lv, lp, pvh))
+ if (!lv_resize(lv, lp, pvh))
goto_out;
ret = ECMD_PROCESSED;
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=5013999c8bd3f2b4…
Commit: 5013999c8bd3f2b455ab6fe436df4884da6ebaf5
Parent: d30c2cec880e22ac2ce6cb6a1ee09584f2dc6aae
Author: Zdenek Kabelac <zkabelac(a)redhat.com>
AuthorDate: Wed Jun 15 15:46:03 2016 +0200
Committer: Zdenek Kabelac <zkabelac(a)redhat.com>
CommitterDate: Thu Jun 23 14:57:09 2016 +0200
lvresize: pass only needed params to _fsadm_cmd
Do not pass whole lvresize_params into _fsadm_cmd,
and give it only needed args.
---
lib/metadata/lv_manip.c | 26 ++++++++++++++------------
1 files changed, 14 insertions(+), 12 deletions(-)
diff --git a/lib/metadata/lv_manip.c b/lib/metadata/lv_manip.c
index f4abc4f..487d7f9 100644
--- a/lib/metadata/lv_manip.c
+++ b/lib/metadata/lv_manip.c
@@ -4387,12 +4387,14 @@ enum fsadm_cmd_e { FSADM_CMD_CHECK, FSADM_CMD_RESIZE };
* FSADM_CMD --dry-run --verbose --force check lv_path
* FSADM_CMD --dry-run --verbose --force resize lv_path size
*/
-static int _fsadm_cmd(struct cmd_context *cmd,
- const struct volume_group *vg,
- const struct lvresize_params *lp,
- enum fsadm_cmd_e fcmd,
+static int _fsadm_cmd(enum fsadm_cmd_e fcmd,
+ struct logical_volume *lv,
+ uint32_t extents,
+ int force,
int *status)
{
+ struct volume_group *vg = lv->vg;
+ struct cmd_context *cmd = vg->cmd;
char lv_path[PATH_MAX];
char size_buf[SIZE_BUF];
const char *argv[FSADM_CMD_MAX_ARGS + 2];
@@ -4406,7 +4408,7 @@ static int _fsadm_cmd(struct cmd_context *cmd,
if (verbose_level() >= _LOG_NOTICE)
argv[i++] = "--verbose";
- if (lp->force)
+ if (force)
argv[i++] = "--force";
argv[i++] = (fcmd == FSADM_CMD_RESIZE) ? "resize" : "check";
@@ -4415,8 +4417,8 @@ static int _fsadm_cmd(struct cmd_context *cmd,
*status = -1;
if (dm_snprintf(lv_path, sizeof(lv_path), "%s%s/%s", cmd->dev_dir,
- vg->name, lp->lv_name) < 0) {
- log_error("Couldn't create LV path for %s", lp->lv_name);
+ vg->name, lv->name) < 0) {
+ log_error("Couldn't create LV path for %s.", display_lvname(lv));
return 0;
}
@@ -4424,8 +4426,8 @@ static int _fsadm_cmd(struct cmd_context *cmd,
if (fcmd == FSADM_CMD_RESIZE) {
if (dm_snprintf(size_buf, sizeof(size_buf), FMTu64 "K",
- (uint64_t) lp->extents * (vg->extent_size / 2)) < 0) {
- log_error("Couldn't generate new LV size string");
+ (uint64_t) extents * (vg->extent_size / 2)) < 0) {
+ log_error("Couldn't generate new LV size string.");
return 0;
}
@@ -5238,7 +5240,7 @@ static struct logical_volume *_lvresize_volume(struct cmd_context *cmd,
if (lp->resizefs) {
if (!lp->nofsck &&
- !_fsadm_cmd(cmd, vg, lp, FSADM_CMD_CHECK, &status)) {
+ !_fsadm_cmd(FSADM_CMD_CHECK, lv, 0, lp->force, &status)) {
if (status != FSADM_CHECK_FAILS_FOR_MOUNTED) {
log_error("Filesystem check failed.");
return NULL;
@@ -5248,7 +5250,7 @@ static struct logical_volume *_lvresize_volume(struct cmd_context *cmd,
/* FIXME forks here */
if ((lp->resize == LV_REDUCE) &&
- !_fsadm_cmd(cmd, vg, lp, FSADM_CMD_RESIZE, NULL)) {
+ !_fsadm_cmd(FSADM_CMD_RESIZE, lv, lp->extents, lp->force, NULL)) {
log_error("Filesystem resize failed.");
return NULL;
}
@@ -5412,7 +5414,7 @@ int lv_resize(struct cmd_context *cmd, struct logical_volume *lv,
display_lvname(lv));
if (lp->resizefs && (lp->resize == LV_EXTEND) &&
- !_fsadm_cmd(cmd, vg, lp, FSADM_CMD_RESIZE, NULL))
+ !_fsadm_cmd(FSADM_CMD_RESIZE, lv, lp->extents, lp->force, NULL))
return_0;
return 1;
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=d30c2cec880e22ac…
Commit: d30c2cec880e22ac2ce6cb6a1ee09584f2dc6aae
Parent: f45b68940667563e1a8d3bbd5d30864c04381bdf
Author: Zdenek Kabelac <zkabelac(a)redhat.com>
AuthorDate: Thu Jun 16 14:39:26 2016 +0200
Committer: Zdenek Kabelac <zkabelac(a)redhat.com>
CommitterDate: Thu Jun 23 14:57:09 2016 +0200
lvresize: check pvh list is vg->pvs
Instead of checking lp->argc for arg count, compare directly whether
passed pvh is vg->pvs.
---
lib/metadata/lv_manip.c | 4 ++--
1 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/lib/metadata/lv_manip.c b/lib/metadata/lv_manip.c
index 562047c..f4abc4f 100644
--- a/lib/metadata/lv_manip.c
+++ b/lib/metadata/lv_manip.c
@@ -4785,7 +4785,7 @@ static int _lvresize_extents_from_percent(struct logical_volume *lv, struct lvre
(lp->sign != SIGN_MINUS));
break;
case PERCENT_PVS:
- if (lp->argc) {
+ if (pvh != &vg->pvs) {
pv_extent_count = pv_list_extents_free(pvh);
lp->extents = percent_of_extents(lp->extents, pv_extent_count,
(lp->sign != SIGN_MINUS));
@@ -5228,7 +5228,7 @@ static struct logical_volume *_lvresize_volume(struct cmd_context *cmd,
}
alloc = lp->alloc ? : lv->alloc;
- if ((lp->resize == LV_REDUCE) && lp->argc)
+ if ((lp->resize == LV_REDUCE) && (pvh != &vg->pvs))
log_print_unless_silent("Ignoring PVs on command line when reducing.");
/* Request confirmation before operations that are often mistakes. */
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=f45b68940667563e…
Commit: f45b68940667563e1a8d3bbd5d30864c04381bdf
Parent: 698082e67875fe71970fb932ffe2170d777f2807
Author: Zdenek Kabelac <zkabelac(a)redhat.com>
AuthorDate: Fri Jun 17 13:25:41 2016 +0200
Committer: Zdenek Kabelac <zkabelac(a)redhat.com>
CommitterDate: Thu Jun 23 14:57:09 2016 +0200
lvresize: update lvresize_params struct
Reorganise struct lvresize_params to better fit lvresize needs to be
able to resize more then just a single LV.
---
lib/locking/lvmlockd.c | 2 +-
lib/metadata/lv_manip.c | 98 ++++++++++++++--------------
lib/metadata/metadata-exported.h | 52 +++++++---------
liblvm/lvm_lv.c | 2 +-
tools/lvresize.c | 128 +++++++++++++++----------------------
5 files changed, 126 insertions(+), 156 deletions(-)
diff --git a/lib/locking/lvmlockd.c b/lib/locking/lvmlockd.c
index 9eb7f92..e2b3e25 100644
--- a/lib/locking/lvmlockd.c
+++ b/lib/locking/lvmlockd.c
@@ -372,7 +372,7 @@ static int _extend_sanlock_lv(struct cmd_context *cmd, struct volume_group *vg,
.size = lv->size + ((extend_mb * 1024 * 1024) / SECTOR_SIZE),
.percent = PERCENT_NONE,
.resize = LV_EXTEND,
- .ac_force = 1,
+ .force = 1,
.sizeargs = 1,
};
diff --git a/lib/metadata/lv_manip.c b/lib/metadata/lv_manip.c
index 9f0d06d..562047c 100644
--- a/lib/metadata/lv_manip.c
+++ b/lib/metadata/lv_manip.c
@@ -4314,23 +4314,19 @@ int lv_rename(struct cmd_context *cmd, struct logical_volume *lv,
static int _validate_stripesize(const struct volume_group *vg,
struct lvresize_params *lp)
{
-
- if (lp->ac_stripesize_value > (STRIPE_SIZE_LIMIT * 2)) {
+ if (lp->stripe_size > (STRIPE_SIZE_LIMIT * 2)) {
log_error("Stripe size cannot be larger than %s.",
display_size(vg->cmd, (uint64_t) STRIPE_SIZE_LIMIT));
return 0;
}
- if (!(vg->fid->fmt->features & FMT_SEGMENTS))
- log_print_unless_silent("Varied stripesize not supported. Ignoring.");
- else if (lp->ac_stripesize_value > vg->extent_size) {
+ if (lp->stripe_size > vg->extent_size) {
log_print_unless_silent("Reducing stripe size %s to maximum, "
"physical extent size %s.",
- display_size(vg->cmd, lp->ac_stripesize_value),
+ display_size(vg->cmd, lp->stripe_size),
display_size(vg->cmd, vg->extent_size));
lp->stripe_size = vg->extent_size;
- } else
- lp->stripe_size = lp->ac_stripesize_value;
+ }
if (lp->stripe_size & (lp->stripe_size - 1)) {
log_error("Stripe size must be power of 2.");
@@ -4370,7 +4366,7 @@ static int _request_confirmation(const struct volume_group *vg,
log_warn("THIS MAY DESTROY YOUR DATA (filesystem etc.)");
- if (!lp->ac_force) {
+ if (!lp->force) {
if (yes_no_prompt("Do you really want to reduce %s? [y/n]: ",
display_lvname(lv)) == 'n') {
log_error("Logical volume %s NOT reduced.",
@@ -4410,7 +4406,7 @@ static int _fsadm_cmd(struct cmd_context *cmd,
if (verbose_level() >= _LOG_NOTICE)
argv[i++] = "--verbose";
- if (lp->ac_force)
+ if (lp->force)
argv[i++] = "--force";
argv[i++] = (fcmd == FSADM_CMD_RESIZE) ? "resize" : "check";
@@ -4491,7 +4487,7 @@ static int _adjust_policy_params(struct logical_volume *lv, struct lvresize_para
}
if (policy_threshold >= 100) {
- lp->extents = lp->poolmetadatasize = 0;
+ lp->extents = lp->poolmetadata_size = 0;
lp->sizeargs = 0;
return 1; /* nothing to do */
}
@@ -4517,9 +4513,9 @@ static int _adjust_policy_params(struct logical_volume *lv, struct lvresize_para
display_lvname(lv));
return 0;
}
- lp->poolmetadatasize = (first_seg(lv)->metadata_lv->size *
- policy_amount + 99) / 100;
- lp->poolmetadatasign = SIGN_PLUS;
+ lp->poolmetadata_size = (first_seg(lv)->metadata_lv->size *
+ policy_amount + 99) / 100;
+ lp->poolmetadata_sign = SIGN_PLUS;
}
if (!lv_thin_pool_percent(lv, 0, &percent))
return_0;
@@ -4579,18 +4575,18 @@ static int _lvresize_poolmetadata_prepare(struct logical_volume *pool_lv,
return 0;
}
- if (lp->poolmetadatasize % vg->extent_size) {
- lp->poolmetadatasize += vg->extent_size -
- (lp->poolmetadatasize % vg->extent_size);
+ if (lp->poolmetadata_size % vg->extent_size) {
+ lp->poolmetadata_size += vg->extent_size -
+ (lp->poolmetadata_size % vg->extent_size);
log_print_unless_silent("Rounding pool metadata size to boundary between physical extents: %s",
- display_size(vg->cmd, lp->poolmetadatasize));
+ display_size(vg->cmd, lp->poolmetadata_size));
}
- if (!(extents = extents_from_size(vg->cmd, lp->poolmetadatasize,
+ if (!(extents = extents_from_size(vg->cmd, lp->poolmetadata_size,
vg->extent_size)))
return_0;
- if (lp->poolmetadatasign == SIGN_PLUS) {
+ if (lp->poolmetadata_sign == SIGN_PLUS) {
if (extents >= (MAX_EXTENT_COUNT - lv->le_count)) {
log_error("Unable to extend %s by %u extents, exceeds limit (%u).",
lv->name, lv->le_count, MAX_EXTENT_COUNT);
@@ -4624,7 +4620,7 @@ static int _lvresize_poolmetadata(struct logical_volume *pool_lv,
{
struct logical_volume *lv = first_seg(pool_lv)->metadata_lv;
struct volume_group *vg = lv->vg;
- alloc_policy_t alloc = lp->ac_alloc ? : lv->alloc;
+ alloc_policy_t alloc = lp->alloc ? : lv->alloc;
struct lv_segment *mseg = last_seg(lv);
uint32_t seg_mirrors = lv_mirror_count(lv);
@@ -4676,7 +4672,7 @@ static int _lvresize_check_lv(struct logical_volume *lv,
return 0;
}
- if (lp->ac_policy && !lv_is_cow(lv) && !lv_is_thin_pool(lv)) {
+ if (lp->use_policies && !lv_is_cow(lv) && !lv_is_thin_pool(lv)) {
log_error("Policy-based resize is supported only for snapshot and thin pool volumes.");
return 0;
}
@@ -4699,13 +4695,18 @@ static int _lvresize_check_lv(struct logical_volume *lv,
return 0;
}
- if (!lv_is_thin_pool(lv) && lp->poolmetadatasize) {
+ if (!lv_is_thin_pool(lv) && lp->poolmetadata_size) {
log_error("--poolmetadatasize can be used only with thin pools.");
return 0;
}
- if (lp->ac_stripesize && !_validate_stripesize(vg, lp))
- return_0;
+ if (lp->stripe_size) {
+ if (!(vg->fid->fmt->features & FMT_SEGMENTS)) {
+ log_print_unless_silent("Varied stripesize not supported. Ignoring.");
+ lp->stripe_size = lp->stripes = 0;
+ } else if (!_validate_stripesize(vg, lp))
+ return_0;
+ }
if (lp->resizefs &&
(lv_is_thin_pool(lv) ||
@@ -4718,18 +4719,16 @@ static int _lvresize_check_lv(struct logical_volume *lv,
lp->resizefs = 0;
}
- if (lp->ac_stripes) {
- if (!(vg->fid->fmt->features & FMT_SEGMENTS))
- log_print_unless_silent("Varied striping not supported. Ignoring.");
- else
- lp->stripes = lp->ac_stripes_value;
+ if (lp->stripes &&
+ !(vg->fid->fmt->features & FMT_SEGMENTS)) {
+ log_print_unless_silent("Varied striping not supported. Ignoring.");
+ lp->stripes = 0;
}
- if (lp->ac_mirrors) {
- if (!(vg->fid->fmt->features & FMT_SEGMENTS))
- log_print_unless_silent("Mirrors not supported. Ignoring.");
- else
- lp->mirrors = lp->ac_mirrors_value;
+ if (lp->mirrors &&
+ !(vg->fid->fmt->features & FMT_SEGMENTS)) {
+ log_print_unless_silent("Mirrors not supported. Ignoring.");
+ lp->mirrors = 0;
}
return 1;
@@ -4885,15 +4884,16 @@ static int _lvresize_adjust_extents(struct cmd_context *cmd, struct logical_volu
lv = seg_lv(first_seg(lv), 0);
seg_last = last_seg(lv);
- /* Use segment type of last segment */
- lp->segtype = seg_last->segtype;
/* FIXME Support LVs with mixed segment types */
- if (lp->segtype != get_segtype_from_string(cmd, lp->ac_type ? : lp->segtype->name)) {
+ if (lp->segtype && (lp->segtype != seg_last->segtype)) {
log_error("VolumeType does not match (%s).", lp->segtype->name);
return 0;
}
+ /* Use segment type of last segment */
+ lp->segtype = seg_last->segtype;
+
/* For virtual devices, just pretend the physical size matches. */
existing_physical_extents = saved_existing_physical_extents = _lv_pe_count(lv);
if (!existing_physical_extents) {
@@ -4913,10 +4913,10 @@ static int _lvresize_adjust_extents(struct cmd_context *cmd, struct logical_volu
if (!reducing) {
seg_mirrors = seg_is_mirrored(seg_last) ? lv_mirror_count(lv) : 0;
- if (!lp->ac_mirrors && seg_mirrors) {
+ if (!lp->mirrors && seg_mirrors) {
log_print_unless_silent("Extending %" PRIu32 " mirror images.", seg_mirrors);
lp->mirrors = seg_mirrors;
- } else if ((lp->ac_mirrors || seg_mirrors) && (lp->mirrors != seg_mirrors)) {
+ } else if ((lp->mirrors || seg_mirrors) && (lp->mirrors != seg_mirrors)) {
log_error("Cannot vary number of mirrors in LV yet.");
return 0;
}
@@ -5023,7 +5023,7 @@ static int _lvresize_adjust_extents(struct cmd_context *cmd, struct logical_volu
}
}
} else { /* If reducing, find stripes, stripesize & size of last segment */
- if (lp->ac_stripes || lp->ac_stripesize || lp->ac_mirrors)
+ if (lp->stripes || lp->stripe_size || lp->mirrors)
log_print_unless_silent("Ignoring stripes, stripesize and mirrors "
"arguments when reducing.");
@@ -5081,7 +5081,7 @@ static int _lvresize_adjust_extents(struct cmd_context *cmd, struct logical_volu
}
if (lp->extents == existing_logical_extents) {
- if (lp->poolmetadatasize || lp->ac_policy) {
+ if (lp->poolmetadata_size || lp->use_policies) {
/* Signal that normal resizing is not required */
lp->sizeargs = 0;
return 1;
@@ -5146,7 +5146,7 @@ static int _lvresize_adjust_extents(struct cmd_context *cmd, struct logical_volu
return 0;
}
lp->resize = LV_EXTEND;
- } else if ((lp->extents == existing_logical_extents) && !lp->ac_policy) {
+ } else if ((lp->extents == existing_logical_extents) && !lp->use_policies) {
if (!lp->resizefs) {
log_error("New size (%d extents) matches existing size "
"(%d extents)", lp->extents, existing_logical_extents);
@@ -5160,7 +5160,7 @@ static int _lvresize_adjust_extents(struct cmd_context *cmd, struct logical_volu
* extents of a mirror not to have an initial sync?
*/
if ((lp->extents > existing_logical_extents)) {
- if (seg_is_mirrored(first_seg(lv)) && lp->ac_no_sync)
+ if (seg_is_mirrored(first_seg(lv)) && lp->nosync)
lv->status |= LV_NOTSYNCED;
}
@@ -5226,7 +5226,7 @@ static struct logical_volume *_lvresize_volume(struct cmd_context *cmd,
/* Switch to layered LV resizing */
lv = seg_lv(seg, 0);
}
- alloc = lp->ac_alloc ? : lv->alloc;
+ alloc = lp->alloc ? : lv->alloc;
if ((lp->resize == LV_REDUCE) && lp->argc)
log_print_unless_silent("Ignoring PVs on command line when reducing.");
@@ -5308,7 +5308,7 @@ int lv_resize_prepare(struct cmd_context *cmd, struct logical_volume *lv,
if (!_lvresize_check_lv(lv, lp))
return_0;
- if (lp->ac_policy && !_adjust_policy_params(lv, lp))
+ if (lp->use_policies && !_adjust_policy_params(lv, lp))
return_0;
if (lp->size && !_lvresize_adjust_size(lv->vg, lp->size, lp->sign,
@@ -5320,16 +5320,16 @@ int lv_resize_prepare(struct cmd_context *cmd, struct logical_volume *lv,
if (lp->extents && !_lvresize_adjust_extents(cmd, lv, lp, pvh))
return_0;
- if ((lp->extents == lv->le_count) && lp->ac_policy) {
+ if ((lp->extents == lv->le_count) && lp->use_policies) {
/* Nothing to do. */
lp->sizeargs = 0;
- lp->poolmetadatasize = 0;
+ lp->poolmetadata_size = 0;
}
if (lp->extents && !_lvresize_check_type(lv, lp))
return_0;
- if (lp->poolmetadatasize &&
+ if (lp->poolmetadata_size &&
!_lvresize_poolmetadata_prepare(lv, lp))
return_0;
diff --git a/lib/metadata/metadata-exported.h b/lib/metadata/metadata-exported.h
index 5948404..ddf51fc 100644
--- a/lib/metadata/metadata-exported.h
+++ b/lib/metadata/metadata-exported.h
@@ -599,26 +599,20 @@ struct pvcreate_params {
};
struct lvresize_params {
+ int argc;
+ char **argv;
+
const char *vg_name; /* only-used when VG is not yet opened (in /tools) */
const char *lv_name;
- uint32_t stripes;
- uint32_t stripe_size;
- uint32_t mirrors;
-
const struct segment_type *segtype;
- /* size */
- uint32_t extents;
- uint64_t size;
int sizeargs;
- sign_t sign;
- uint64_t poolmetadatasize;
- sign_t poolmetadatasign;
+ uint64_t poolmetadata_size;
+ sign_t poolmetadata_sign;
uint32_t poolmetadataextents;
- int approx_alloc;
- int extents_are_pes; /* Is 'extents' counting PEs or LEs? */
- percent_type_t percent;
+
+ /* Per LV applied parameters */
enum {
LV_ANY = 0,
@@ -626,25 +620,25 @@ struct lvresize_params {
LV_EXTEND = 2
} resize;
- int resizefs;
+ int use_policies;
+
+ alloc_policy_t alloc;
+ int force;
+ int nosync;
int nofsck;
+ int resizefs;
- int argc;
- char **argv;
+ unsigned mirrors;
+ uint32_t stripes;
+ uint64_t stripe_size;
- /* FIXME Deal with meaningless 'ac' */
- /* Arg counts & values */
- alloc_policy_t ac_alloc;
- unsigned ac_force;
- unsigned ac_mirrors;
- uint32_t ac_mirrors_value;
- unsigned ac_no_sync;
- unsigned ac_policy;
- unsigned ac_stripes;
- uint32_t ac_stripes_value;
- unsigned ac_stripesize;
- uint64_t ac_stripesize_value;
- const char *ac_type;
+ uint32_t extents;
+ uint64_t size;
+ sign_t sign;
+ percent_type_t percent;
+
+ int approx_alloc;
+ int extents_are_pes; /* Is 'extents' counting PEs or LEs? */
};
void pvcreate_params_set_defaults(struct pvcreate_params *pp);
diff --git a/liblvm/lvm_lv.c b/liblvm/lvm_lv.c
index ee0d48b..467a9d0 100644
--- a/liblvm/lvm_lv.c
+++ b/liblvm/lvm_lv.c
@@ -462,7 +462,7 @@ int lvm_lv_resize(const lv_t lv, uint64_t new_size)
.percent = PERCENT_NONE,
.resize = LV_ANY,
.size = new_size >> SECTOR_SHIFT,
- .ac_force = 1, /* Assume the user has a good backup? */
+ .force = 1, /* Assume the user has a good backup? */
.sizeargs = 1,
};
struct saved_env e = store_user_env(lv->vg->cmd);
diff --git a/tools/lvresize.c b/tools/lvresize.c
index f7e17b8..af2b3ac 100644
--- a/tools/lvresize.c
+++ b/tools/lvresize.c
@@ -19,7 +19,10 @@ static int _lvresize_params(struct cmd_context *cmd, int argc, char **argv,
struct lvresize_params *lp)
{
const char *cmd_name = command_name(cmd);
- char *st;
+ const char *type_str = arg_str_value(cmd, type_ARG, NULL);
+
+ if (type_str && (lp->segtype = get_segtype_from_string(cmd, type_str)))
+ return_0;
if (!strcmp(cmd_name, "lvreduce"))
lp->resize = LV_REDUCE;
@@ -28,9 +31,9 @@ static int _lvresize_params(struct cmd_context *cmd, int argc, char **argv,
else
lp->resize = LV_ANY;
- lp->sign = lp->poolmetadatasign = SIGN_NONE;
+ lp->sign = lp->poolmetadata_sign = SIGN_NONE;
- if ((lp->ac_policy = arg_is_set(cmd, usepolicies_ARG))) {
+ if ((lp->use_policies = arg_is_set(cmd, usepolicies_ARG))) {
/* do nothing; _lvresize will handle --use-policies itself */
lp->extents = 0;
lp->sign = SIGN_PLUS;
@@ -53,6 +56,10 @@ static int _lvresize_params(struct cmd_context *cmd, int argc, char **argv,
* then metadata will be extended there.
*/
lp->sizeargs = arg_is_set(cmd, extents_ARG) + arg_is_set(cmd, size_ARG);
+ if ((lp->extents = arg_uint_value(cmd, extents_ARG, 0))) {
+ lp->sign = arg_sign_value(cmd, extents_ARG, SIGN_NONE);
+ lp->percent = arg_percent_value(cmd, extents_ARG, PERCENT_NONE);
+ }
if (arg_from_list_is_zero(cmd, "may not be zero",
chunksize_ARG, extents_ARG,
@@ -64,39 +71,31 @@ static int _lvresize_params(struct cmd_context *cmd, int argc, char **argv,
-1))
return_0;
- if (arg_is_set(cmd, poolmetadatasize_ARG)) {
- lp->poolmetadatasize = arg_uint64_value(cmd, poolmetadatasize_ARG, 0);
- lp->poolmetadatasign = arg_sign_value(cmd, poolmetadatasize_ARG, SIGN_NONE);
- if (lp->poolmetadatasign == SIGN_MINUS) {
+ if ((lp->poolmetadata_size = arg_uint64_value(cmd, poolmetadatasize_ARG, 0))) {
+ lp->poolmetadata_sign = arg_sign_value(cmd, poolmetadatasize_ARG, SIGN_NONE);
+ if (lp->poolmetadata_sign == SIGN_MINUS) {
log_error("Can't reduce pool metadata size.");
return 0;
}
}
- if ((lp->sizeargs == 0) && (argc >= 2)) {
- lp->extents = 100;
- lp->percent = PERCENT_PVS;
- lp->sign = SIGN_PLUS;
- lp->sizeargs = !lp->poolmetadatasize ? 1 : 0;
- } else if ((lp->sizeargs != 1) &&
- ((lp->sizeargs == 2) ||
- !arg_is_set(cmd, poolmetadatasize_ARG))) {
- log_error("Please specify either size or extents but not "
- "both.");
- return 0;
+ if ((lp->size = arg_uint64_value(cmd, size_ARG, 0))) {
+ lp->sign = arg_sign_value(cmd, size_ARG, SIGN_NONE);
+ lp->percent = PERCENT_NONE;
}
- if (arg_is_set(cmd, extents_ARG)) {
- lp->extents = arg_uint_value(cmd, extents_ARG, 0);
- lp->sign = arg_sign_value(cmd, extents_ARG, SIGN_NONE);
- lp->percent = arg_percent_value(cmd, extents_ARG, PERCENT_NONE);
+ if (lp->size && lp->extents) {
+ log_error("Please specify either size or extents but not both.");
+ return 0;
}
- /* Size returned in kilobyte units; held in sectors */
- if (arg_is_set(cmd, size_ARG)) {
- lp->size = arg_uint64_value(cmd, size_ARG, 0);
- lp->sign = arg_sign_value(cmd, size_ARG, SIGN_NONE);
- lp->percent = PERCENT_NONE;
+ if (!lp->extents &&
+ !lp->size &&
+ !lp->poolmetadata_size &&
+ (argc >= 2)) {
+ lp->extents = 100;
+ lp->percent = PERCENT_PVS;
+ lp->sign = SIGN_PLUS;
}
}
@@ -106,77 +105,54 @@ static int _lvresize_params(struct cmd_context *cmd, int argc, char **argv,
}
if (lp->resize == LV_REDUCE &&
- ((lp->sign == SIGN_PLUS) || (lp->poolmetadatasign == SIGN_PLUS))) {
+ ((lp->sign == SIGN_PLUS) ||
+ (lp->poolmetadata_sign == SIGN_PLUS))) {
log_error("Positive sign not permitted - use lvextend.");
return 0;
}
- lp->resizefs = arg_is_set(cmd, resizefs_ARG);
- lp->nofsck = arg_is_set(cmd, nofsck_ARG);
-
if (!argc) {
log_error("Please provide the logical volume name.");
return 0;
}
lp->lv_name = argv[0];
- argv++;
- argc--;
- if (!(lp->lv_name = skip_dev_dir(cmd, lp->lv_name, NULL)) ||
- !(lp->vg_name = extract_vgname(cmd, lp->lv_name))) {
- log_error("Please provide a volume group name");
- return 0;
- }
+ if (!validate_restricted_lvname_param(cmd, &lp->vg_name, &lp->lv_name))
+ return_0;
- if (!validate_name(lp->vg_name)) {
- log_error("Volume group name %s has invalid characters",
- lp->vg_name);
+ /* Check for $LVM_VG_NAME */
+ if (!lp->vg_name && !(lp->vg_name = extract_vgname(cmd, NULL))) {
+ log_error("Please specify a logical volume path.");
return 0;
}
- if ((st = strrchr(lp->lv_name, '/')))
- lp->lv_name = st + 1;
-
- lp->argc = argc;
- lp->argv = argv;
-
- lp->ac_policy = arg_is_set(cmd, usepolicies_ARG);
- lp->ac_stripes = arg_is_set(cmd, stripes_ARG);
- if (lp->ac_stripes) {
- lp->ac_stripes_value = arg_uint_value(cmd, stripes_ARG, 1);
- } else {
- lp->ac_stripes_value = 0;
+ if ((lp->mirrors = arg_count(cmd, mirrors_ARG)) &&
+ (arg_sign_value(cmd, mirrors_ARG, SIGN_NONE) == SIGN_MINUS)) {
+ log_error("Mirrors argument may not be signed.");
+ return 0;
}
- lp->ac_mirrors = arg_is_set(cmd, mirrors_ARG);
-
- if (lp->ac_mirrors) {
- if (arg_sign_value(cmd, mirrors_ARG, SIGN_NONE) == SIGN_MINUS) {
- log_error("Mirrors argument may not be negative");
- return 0;
- }
-
- lp->ac_mirrors_value = arg_uint_value(cmd, mirrors_ARG, 1) + 1;
- } else {
- lp->ac_mirrors_value = 0;
+ if ((lp->stripes = arg_uint_value(cmd, stripes_ARG, 0)) &&
+ (arg_sign_value(cmd, stripes_ARG, SIGN_NONE) == SIGN_MINUS)) {
+ log_error("Stripes argument may not be negative.");
+ return 0;
}
- lp->ac_stripesize = arg_is_set(cmd, stripesize_ARG);
- if (lp->ac_stripesize) {
- if (arg_sign_value(cmd, stripesize_ARG, SIGN_NONE) == SIGN_MINUS) {
- log_error("Stripesize may not be negative.");
- return 0;
- }
-
- lp->ac_stripesize_value = arg_uint64_value(cmd, stripesize_ARG, 0);
+ if ((lp->stripe_size = arg_uint64_value(cmd, stripesize_ARG, 0)) &&
+ (arg_sign_value(cmd, stripesize_ARG, SIGN_NONE) == SIGN_MINUS)) {
+ log_error("Stripesize may not be negative.");
+ return 0;
}
- lp->ac_no_sync = arg_is_set(cmd, nosync_ARG);
- lp->ac_alloc = (alloc_policy_t) arg_uint_value(cmd, alloc_ARG, 0);
+ lp->argc = --argc;
+ lp->argv = ++argv;
- lp->ac_type = arg_str_value(cmd, type_ARG, NULL);
- lp->ac_force = arg_count(cmd, force_ARG);
+ lp->alloc = (alloc_policy_t) arg_uint_value(cmd, alloc_ARG, 0);
+ lp->force = arg_is_set(cmd, force_ARG);
+ lp->nofsck = arg_is_set(cmd, nofsck_ARG);
+ lp->nosync = arg_is_set(cmd, nosync_ARG);
+ lp->resizefs = arg_is_set(cmd, resizefs_ARG);
return 1;
}
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=698082e67875fe71…
Commit: 698082e67875fe71970fb932ffe2170d777f2807
Parent: 6268d0a080f61c85c2681b3dcfdd5b00f849ace1
Author: Zdenek Kabelac <zkabelac(a)redhat.com>
AuthorDate: Thu Jun 23 13:04:37 2016 +0200
Committer: Zdenek Kabelac <zkabelac(a)redhat.com>
CommitterDate: Thu Jun 23 14:57:08 2016 +0200
cleanup: use display_lvname
---
lib/metadata/lv.c | 30 ++++++++++++-----------
lib/metadata/lv_manip.c | 57 ++++++++++++++++++++++++--------------------
lib/metadata/thin_manip.c | 6 +++-
3 files changed, 51 insertions(+), 42 deletions(-)
diff --git a/lib/metadata/lv.c b/lib/metadata/lv.c
index 06f47f4..cdf658e 100644
--- a/lib/metadata/lv.c
+++ b/lib/metadata/lv.c
@@ -1432,49 +1432,50 @@ int lv_active_change(struct cmd_context *cmd, struct logical_volume *lv,
if (is_change_activating(activate) &&
!lockd_lv(cmd, lv, ay_with_mode, LDLV_PERSISTENT)) {
- log_error("Failed to lock logical volume %s/%s", lv->vg->name, lv->name);
+ log_error("Failed to lock logical volume %s.", display_lvname(lv));
return 0;
}
switch (activate) {
case CHANGE_AN:
deactivate:
- log_verbose("Deactivating logical volume \"%s\"", lv->name);
+ log_verbose("Deactivating logical volume %s.", display_lvname(lv));
if (!deactivate_lv(cmd, lv))
return_0;
break;
case CHANGE_ALN:
if (vg_is_clustered(lv->vg) && (needs_exclusive || _lv_is_exclusive(lv))) {
if (!lv_is_active_locally(lv)) {
- log_error("Cannot deactivate remotely exclusive device locally.");
+ log_error("Cannot deactivate remotely exclusive device %s locally.",
+ display_lvname(lv));
return 0;
}
/* Unlock whole exclusive activation */
goto deactivate;
}
- log_verbose("Deactivating logical volume \"%s\" locally.",
- lv->name);
+ log_verbose("Deactivating logical volume %s locally.",
+ display_lvname(lv));
if (!deactivate_lv_local(cmd, lv))
return_0;
break;
case CHANGE_ALY:
case CHANGE_AAY:
if (needs_exclusive || _lv_is_exclusive(lv)) {
- log_verbose("Activating logical volume \"%s\" exclusively locally.",
- lv->name);
+ log_verbose("Activating logical volume %s exclusively locally.",
+ display_lvname(lv));
if (!activate_lv_excl_local(cmd, lv))
return_0;
} else {
- log_verbose("Activating logical volume \"%s\" locally.",
- lv->name);
+ log_verbose("Activating logical volume %s locally.",
+ display_lvname(lv));
if (!activate_lv_local(cmd, lv))
return_0;
}
break;
case CHANGE_AEY:
exclusive:
- log_verbose("Activating logical volume \"%s\" exclusively.",
- lv->name);
+ log_verbose("Activating logical volume %s exclusively.",
+ display_lvname(lv));
if (!activate_lv_excl(cmd, lv))
return_0;
break;
@@ -1483,14 +1484,14 @@ exclusive:
default:
if (needs_exclusive || _lv_is_exclusive(lv))
goto exclusive;
- log_verbose("Activating logical volume \"%s\".", lv->name);
+ log_verbose("Activating logical volume %s.", display_lvname(lv));
if (!activate_lv(cmd, lv))
return_0;
}
if (!is_change_activating(activate) &&
!lockd_lv(cmd, lv, "un", LDLV_PERSISTENT))
- log_error("Failed to unlock logical volume %s/%s", lv->vg->name, lv->name);
+ log_error("Failed to unlock logical volume %s.", display_lvname(lv));
return 1;
}
@@ -1549,7 +1550,8 @@ const struct logical_volume *lv_lock_holder(const struct logical_volume *lv)
/* Find any active LV from the pool */
dm_list_iterate_items(sl, &lv->segs_using_this_lv)
if (lv_is_active(sl->seg->lv)) {
- log_debug("Thin volume \"%s\" is active.", sl->seg->lv->name);
+ log_debug_activation("Thin volume %s is active.",
+ display_lvname(lv));
return sl->seg->lv;
}
diff --git a/lib/metadata/lv_manip.c b/lib/metadata/lv_manip.c
index 6cf7323..9f0d06d 100644
--- a/lib/metadata/lv_manip.c
+++ b/lib/metadata/lv_manip.c
@@ -5000,7 +5000,7 @@ static int _lvresize_adjust_extents(struct cmd_context *cmd, struct logical_volu
if (seg_size >= (MAX_EXTENT_COUNT - existing_logical_extents)) {
log_error("Unable to extend %s by %u logical extents: exceeds limit (%u).",
- lp->lv_name, seg_size, MAX_EXTENT_COUNT);
+ display_lvname(lv), seg_size, MAX_EXTENT_COUNT);
return 0;
}
@@ -5029,7 +5029,8 @@ static int _lvresize_adjust_extents(struct cmd_context *cmd, struct logical_volu
if (lp->sign == SIGN_MINUS) {
if (lp->extents >= existing_extents) {
- log_error("Unable to reduce %s below 1 extent.", lp->lv_name);
+ log_error("Unable to reduce %s below 1 extent.",
+ display_lvname(lv));
return 0;
}
new_extents = existing_extents - lp->extents;
@@ -5407,7 +5408,8 @@ int lv_resize(struct cmd_context *cmd, struct logical_volume *lv,
}
}
- log_print_unless_silent("Logical volume %s successfully resized.", lp->lv_name);
+ log_print_unless_silent("Logical volume %s successfully resized.",
+ display_lvname(lv));
if (lp->resizefs && (lp->resize == LV_EXTEND) &&
!_fsadm_cmd(cmd, vg, lp, FSADM_CMD_RESIZE, NULL))
@@ -6068,19 +6070,22 @@ int lv_remove_with_dependencies(struct cmd_context *cmd, struct logical_volume *
if (lv_info(lv->vg->cmd, lv, 0, &info, 1, 0) &&
info.exists && info.live_table) {
if (!lv_snapshot_percent(lv, &snap_percent)) {
- log_error("Failed to obtain merging snapshot progress percentage for logical volume %s.",
- lv->name);
+ log_error("Failed to obtain merging snapshot progress "
+ "percentage for logical volume %s.",
+ display_lvname(lv));
return 0;
}
if ((snap_percent != DM_PERCENT_INVALID) &&
(snap_percent != LVM_PERCENT_MERGE_FAILED)) {
- log_error("Can't remove merging snapshot logical volume \"%s\"",
- lv->name);
+ log_error("Can't remove merging snapshot logical volume %s.",
+ display_lvname(lv));
return 0;
} else if ((snap_percent == LVM_PERCENT_MERGE_FAILED) &&
- (force == PROMPT) &&
- yes_no_prompt("Removing snapshot \"%s\" that failed to merge may leave origin \"%s\" inconsistent. "
- "Proceed? [y/n]: ", lv->name, origin_from_cow(lv)->name) == 'n')
+ (force == PROMPT) &&
+ yes_no_prompt("Removing snapshot %s that failed to merge "
+ "may leave origin %s inconsistent. Proceed? [y/n]: ",
+ display_lvname(lv),
+ display_lvname(origin_from_cow(lv))) == 'n')
goto no_remove;
}
} else if (!level && lv_is_virtual_origin(origin = origin_from_cow(lv)))
@@ -6108,22 +6113,22 @@ int lv_remove_with_dependencies(struct cmd_context *cmd, struct logical_volume *
if (lv_is_merging_origin(lv)) {
if (!deactivate_lv(cmd, lv)) {
- log_error("Unable to fully deactivate merging origin \"%s\".",
- lv->name);
+ log_error("Unable to fully deactivate merging origin %s.",
+ display_lvname(lv));
return 0;
}
if (!lv_remove_with_dependencies(cmd, find_snapshot(lv)->lv,
force, level + 1)) {
- log_error("Unable to remove merging origin \"%s\".",
- lv->name);
+ log_error("Unable to remove merging origin %s.",
+ display_lvname(lv));
return 0;
}
}
if (!level && lv_is_merging_thin_snapshot(lv)) {
/* Merged snapshot LV is no longer available for the user */
- log_error("Unable to remove \"%s\", volume is merged to \"%s\".",
- lv->name, first_seg(lv)->merge_lv->name);
+ log_error("Unable to remove %s, volume is merged to %s.",
+ display_lvname(lv), display_lvname(first_seg(lv)->merge_lv));
return 0;
}
@@ -6139,10 +6144,10 @@ int lv_remove_with_dependencies(struct cmd_context *cmd, struct logical_volume *
(force == PROMPT)) {
dm_list_iterate_items(lvl, &lv->vg->lvs)
if (lv_is_pool_metadata(lvl->lv)) {
- if (yes_no_prompt("Removal of pool metadata spare logical volume"
- " \"%s\" disables automatic recovery attempts"
- " after damage to a thin or cache pool."
- " Proceed? [y/n]: ", lv->name) == 'n')
+ if (yes_no_prompt("Removal of pool metadata spare logical volume "
+ "%s disables automatic recovery attempts "
+ "after damage to a thin or cache pool. "
+ "Proceed? [y/n]: ", display_lvname(lv)) == 'n')
goto no_remove;
break;
}
@@ -6151,7 +6156,7 @@ int lv_remove_with_dependencies(struct cmd_context *cmd, struct logical_volume *
return lv_remove_single(cmd, lv, force, 0);
no_remove:
- log_error("Logical volume \"%s\" not removed.", lv->name);
+ log_error("Logical volume %s not removed.", display_lvname(lv));
return 0;
}
@@ -6229,16 +6234,16 @@ static int _split_parent_area(struct lv_segment *seg, uint32_t s,
while (parent_area_len > 0) {
/* Find the layer segment pointed at */
if (!(spvs = _find_seg_pvs_by_le(layer_seg_pvs, layer_le))) {
- log_error("layer segment for %s:%" PRIu32 " not found",
- seg->lv->name, parent_le);
+ log_error("layer segment for %s:" FMTu32 " not found.",
+ display_lvname(seg->lv), parent_le);
return 0;
}
if (spvs->le != layer_le) {
log_error("Incompatible layer boundary: "
- "%s:%" PRIu32 "[%" PRIu32 "] on %s:%" PRIu32,
- seg->lv->name, parent_le, s,
- seg_lv(seg, s)->name, layer_le);
+ "%s:" FMTu32 "[" FMTu32 "] on %s:" FMTu32 ".",
+ display_lvname(seg->lv), parent_le, s,
+ display_lvname(seg_lv(seg, s)), layer_le);
return 0;
}
diff --git a/lib/metadata/thin_manip.c b/lib/metadata/thin_manip.c
index 2f66675..06d4242 100644
--- a/lib/metadata/thin_manip.c
+++ b/lib/metadata/thin_manip.c
@@ -171,7 +171,8 @@ int pool_is_active(const struct logical_volume *lv)
const struct seg_list *sl;
if (!lv_is_thin_pool(lv)) {
- log_error(INTERNAL_ERROR "pool_is_active called with non-pool LV %s.", lv->name);
+ log_error(INTERNAL_ERROR "pool_is_active called with non-pool volume %s.",
+ display_lvname(lv));
return 0;
}
@@ -182,7 +183,8 @@ int pool_is_active(const struct logical_volume *lv)
dm_list_iterate_items(sl, &lv->segs_using_this_lv)
if (lv_is_active(sl->seg->lv)) {
- log_debug("Thin volume \"%s\" is active.", sl->seg->lv->name);
+ log_debug_activation("Pool's thin volume %s is active.",
+ display_lvname(sl->seg->lv));
return 1;
}
} else if (lv_info(lv->vg->cmd, lv, 1, &info, 0, 0) && info.exists)
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=6268d0a080f61c85…
Commit: 6268d0a080f61c85c2681b3dcfdd5b00f849ace1
Parent: 0a525832f9902f6268d155f22975653f27877816
Author: Zdenek Kabelac <zkabelac(a)redhat.com>
AuthorDate: Tue Jun 14 14:56:17 2016 +0200
Committer: Zdenek Kabelac <zkabelac(a)redhat.com>
CommitterDate: Thu Jun 23 14:57:08 2016 +0200
cleanup: add dots to some messages
Add missing dots and one comment.
---
lib/activate/activate.c | 2 +-
lib/metadata/lv_manip.c | 11 ++++++-----
lib/metadata/thin_manip.c | 4 ++--
tools/lvresize.c | 10 +++++-----
4 files changed, 14 insertions(+), 13 deletions(-)
diff --git a/lib/activate/activate.c b/lib/activate/activate.c
index 7f5d36f..d4c297e 100644
--- a/lib/activate/activate.c
+++ b/lib/activate/activate.c
@@ -1394,7 +1394,7 @@ int lvs_in_vg_opened(const struct volume_group *vg)
if (lv_is_visible(lvl->lv))
count += (_lv_open_count(vg->cmd, lvl->lv) > 0);
- log_debug_activation("Counted %d open LVs in VG %s", count, vg->name);
+ log_debug_activation("Counted %d open LVs in VG %s.", count, vg->name);
return count;
}
diff --git a/lib/metadata/lv_manip.c b/lib/metadata/lv_manip.c
index 439a3d7..6cf7323 100644
--- a/lib/metadata/lv_manip.c
+++ b/lib/metadata/lv_manip.c
@@ -4347,7 +4347,7 @@ static int _request_confirmation(const struct volume_group *vg,
struct lvinfo info = { 0 };
if (!lv_info(vg->cmd, lv, 0, &info, 1, 0) && driver_version(NULL, 0)) {
- log_error("lv_info failed: aborting");
+ log_error("lv_info failed: aborting.");
return 0;
}
@@ -4373,7 +4373,7 @@ static int _request_confirmation(const struct volume_group *vg,
if (!lp->ac_force) {
if (yes_no_prompt("Do you really want to reduce %s? [y/n]: ",
display_lvname(lv)) == 'n') {
- log_error("Logical volume %s NOT reduced",
+ log_error("Logical volume %s NOT reduced.",
display_lvname(lv));
return 0;
}
@@ -4890,7 +4890,7 @@ static int _lvresize_adjust_extents(struct cmd_context *cmd, struct logical_volu
/* FIXME Support LVs with mixed segment types */
if (lp->segtype != get_segtype_from_string(cmd, lp->ac_type ? : lp->segtype->name)) {
- log_error("VolumeType does not match (%s)", lp->segtype->name);
+ log_error("VolumeType does not match (%s).", lp->segtype->name);
return 0;
}
@@ -5174,8 +5174,7 @@ static int _lvresize_check_type(const struct logical_volume *lv,
{
if (lv_is_origin(lv)) {
if (lp->resize == LV_REDUCE) {
- log_error("Snapshot origin volumes cannot be reduced "
- "in size yet.");
+ log_error("Snapshot origin volumes cannot be reduced in size yet.");
return 0;
}
@@ -5273,6 +5272,8 @@ static struct logical_volume *_lvresize_volume(struct cmd_context *cmd,
lp->extents - lv->le_count,
pvh, alloc, lp->approx_alloc))
return_NULL;
+ /* Check for over provisioning only when lv_extend() passed,
+ * ATM this check does not fail */
else if (!pool_check_overprovisioning(lv))
return_NULL;
diff --git a/lib/metadata/thin_manip.c b/lib/metadata/thin_manip.c
index 0d850d6..2f66675 100644
--- a/lib/metadata/thin_manip.c
+++ b/lib/metadata/thin_manip.c
@@ -206,7 +206,7 @@ int thin_pool_feature_supported(const struct logical_volume *lv, int feature)
seg->segtype->ops->target_present &&
!seg->segtype->ops->target_present(lv->vg->cmd, NULL, &attr)) {
log_error("%s: Required device-mapper target(s) not "
- "detected in your kernel", seg->segtype->name);
+ "detected in your kernel.", seg->segtype->name);
return 0;
}
@@ -753,7 +753,7 @@ int check_new_thin_pool(const struct logical_volume *pool_lv)
return 0;
}
- log_verbose("Deactivating public thin pool %s",
+ log_verbose("Deactivating public thin pool %s.",
display_lvname(pool_lv));
/* Prevent any 'race' with in-use thin pool and always deactivate */
diff --git a/tools/lvresize.c b/tools/lvresize.c
index ee6678f..f7e17b8 100644
--- a/tools/lvresize.c
+++ b/tools/lvresize.c
@@ -101,13 +101,13 @@ static int _lvresize_params(struct cmd_context *cmd, int argc, char **argv,
}
if (lp->resize == LV_EXTEND && lp->sign == SIGN_MINUS) {
- log_error("Negative argument not permitted - use lvreduce");
+ log_error("Negative argument not permitted - use lvreduce.");
return 0;
}
if (lp->resize == LV_REDUCE &&
((lp->sign == SIGN_PLUS) || (lp->poolmetadatasign == SIGN_PLUS))) {
- log_error("Positive sign not permitted - use lvextend");
+ log_error("Positive sign not permitted - use lvextend.");
return 0;
}
@@ -115,7 +115,7 @@ static int _lvresize_params(struct cmd_context *cmd, int argc, char **argv,
lp->nofsck = arg_is_set(cmd, nofsck_ARG);
if (!argc) {
- log_error("Please provide the logical volume name");
+ log_error("Please provide the logical volume name.");
return 0;
}
@@ -191,8 +191,8 @@ static int _lvresize_single(struct cmd_context *cmd, const char *vg_name,
/* Does LV exist? */
if (!(lv = find_lv(vg, lp->lv_name))) {
- log_error("Logical volume %s not found in volume group %s",
- lp->lv_name, lp->vg_name);
+ log_error("Logical volume %s not found in volume group %s.",
+ lp->lv_name, vg->name);
goto out;
}
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=0a525832f9902f62…
Commit: 0a525832f9902f6268d155f22975653f27877816
Parent: 3a4107c982e706dd97117e7e182bf9cbf7e85cac
Author: Zdenek Kabelac <zkabelac(a)redhat.com>
AuthorDate: Wed Jun 15 11:35:16 2016 +0200
Committer: Zdenek Kabelac <zkabelac(a)redhat.com>
CommitterDate: Thu Jun 23 14:57:08 2016 +0200
cleanup: code lines reodered
---
tools/lvresize.c | 16 +++++++---------
1 files changed, 7 insertions(+), 9 deletions(-)
diff --git a/tools/lvresize.c b/tools/lvresize.c
index 9fb35bd..ee6678f 100644
--- a/tools/lvresize.c
+++ b/tools/lvresize.c
@@ -18,21 +18,19 @@
static int _lvresize_params(struct cmd_context *cmd, int argc, char **argv,
struct lvresize_params *lp)
{
- const char *cmd_name;
+ const char *cmd_name = command_name(cmd);
char *st;
- int use_policy = arg_is_set(cmd, usepolicies_ARG);
- lp->sign = SIGN_NONE;
- lp->poolmetadatasign = SIGN_NONE;
- lp->resize = LV_ANY;
-
- cmd_name = command_name(cmd);
if (!strcmp(cmd_name, "lvreduce"))
lp->resize = LV_REDUCE;
- if (!strcmp(cmd_name, "lvextend"))
+ else if (!strcmp(cmd_name, "lvextend"))
lp->resize = LV_EXTEND;
+ else
+ lp->resize = LV_ANY;
+
+ lp->sign = lp->poolmetadatasign = SIGN_NONE;
- if (use_policy) {
+ if ((lp->ac_policy = arg_is_set(cmd, usepolicies_ARG))) {
/* do nothing; _lvresize will handle --use-policies itself */
lp->extents = 0;
lp->sign = SIGN_PLUS;
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=3a4107c982e706dd…
Commit: 3a4107c982e706dd97117e7e182bf9cbf7e85cac
Parent: d578d8d3a1bbf5d20151ed8bc33caa307e2c7292
Author: Zdenek Kabelac <zkabelac(a)redhat.com>
AuthorDate: Wed Jun 8 23:29:13 2016 +0200
Committer: Zdenek Kabelac <zkabelac(a)redhat.com>
CommitterDate: Thu Jun 23 14:57:08 2016 +0200
lvresize: drop extra sigint handling
yes_no_prompt() now already handles signal checking,
so drop redundant test.
---
lib/metadata/lv_manip.c | 2 --
1 files changed, 0 insertions(+), 2 deletions(-)
diff --git a/lib/metadata/lv_manip.c b/lib/metadata/lv_manip.c
index a628683..439a3d7 100644
--- a/lib/metadata/lv_manip.c
+++ b/lib/metadata/lv_manip.c
@@ -4377,8 +4377,6 @@ static int _request_confirmation(const struct volume_group *vg,
display_lvname(lv));
return 0;
}
- if (sigint_caught())
- return_0;
}
return 1;
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=d578d8d3a1bbf5d2…
Commit: d578d8d3a1bbf5d20151ed8bc33caa307e2c7292
Parent: 58d414f7f5d998e32234e7a6c2d6c9d0ad38f996
Author: Zdenek Kabelac <zkabelac(a)redhat.com>
AuthorDate: Tue Jun 14 13:40:57 2016 +0200
Committer: Zdenek Kabelac <zkabelac(a)redhat.com>
CommitterDate: Thu Jun 23 14:57:08 2016 +0200
lvresize: inform about ignored args with --use-polices
When --use-polices is specified, all size args are meaningless,
as the resize is based upon policy. So just keep user informed.
---
tools/lvresize.c | 9 +++++++++
1 files changed, 9 insertions(+), 0 deletions(-)
diff --git a/tools/lvresize.c b/tools/lvresize.c
index fe200d4..9fb35bd 100644
--- a/tools/lvresize.c
+++ b/tools/lvresize.c
@@ -37,6 +37,15 @@ static int _lvresize_params(struct cmd_context *cmd, int argc, char **argv,
lp->extents = 0;
lp->sign = SIGN_PLUS;
lp->percent = PERCENT_LV;
+
+ if (arg_from_list_is_set(cmd, NULL,
+ chunksize_ARG, extents_ARG,
+ poolmetadatasize_ARG,
+ regionsize_ARG,
+ size_ARG,
+ stripes_ARG, stripesize_ARG,
+ -1))
+ log_print_unless_silent("Ignoring size parameters with --use-policies.");
} else {
/*
* Allow omission of extents and size if the user has given us
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=58d414f7f5d998e3…
Commit: 58d414f7f5d998e32234e7a6c2d6c9d0ad38f996
Parent: fa69ed0bc845df3d2c7ae68d03cdd4a3dec339d8
Author: Zdenek Kabelac <zkabelac(a)redhat.com>
AuthorDate: Wed Jan 20 13:16:53 2016 +0100
Committer: Zdenek Kabelac <zkabelac(a)redhat.com>
CommitterDate: Thu Jun 23 14:57:08 2016 +0200
lvresize: move and extend resizefs ignoring check
Move check for 'ignoring' --resizefs option and extend check
for some more types.
---
lib/metadata/lv_manip.c | 15 +++++++++++----
1 files changed, 11 insertions(+), 4 deletions(-)
diff --git a/lib/metadata/lv_manip.c b/lib/metadata/lv_manip.c
index a908e1e..a628683 100644
--- a/lib/metadata/lv_manip.c
+++ b/lib/metadata/lv_manip.c
@@ -4709,6 +4709,17 @@ static int _lvresize_check_lv(struct logical_volume *lv,
if (lp->ac_stripesize && !_validate_stripesize(vg, lp))
return_0;
+ if (lp->resizefs &&
+ (lv_is_thin_pool(lv) ||
+ lv_is_thin_pool_data(lv) ||
+ lv_is_thin_pool_metadata(lv) ||
+ lv_is_pool_metadata_spare(lv) ||
+ lv_is_lockd_sanlock_lv(lv))) {
+ log_print_unless_silent("Ignoring --resizefs as volume %s does not have a filesystem.",
+ display_lvname(lv));
+ lp->resizefs = 0;
+ }
+
if (lp->ac_stripes) {
if (!(vg->fid->fmt->features & FMT_SEGMENTS))
log_print_unless_silent("Varied striping not supported. Ignoring.");
@@ -5212,10 +5223,6 @@ static struct logical_volume *_lvresize_volume(struct cmd_context *cmd,
alloc_policy_t alloc;
if (lv_is_thin_pool(lv)) {
- if (lp->resizefs) {
- log_print_unless_silent("Ignoring --resizefs as thin pool volumes do not have filesystem.");
- lp->resizefs = 0;
- }
lock_lv = lv;
seg = first_seg(lv);
/* Switch to layered LV resizing */
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=fa69ed0bc845df3d…
Commit: fa69ed0bc845df3d2c7ae68d03cdd4a3dec339d8
Parent: dc8c5c1886ea7c090a3bfa96de8f22ca060614ec
Author: Zdenek Kabelac <zkabelac(a)redhat.com>
AuthorDate: Thu Jun 16 11:54:24 2016 +0200
Committer: Zdenek Kabelac <zkabelac(a)redhat.com>
CommitterDate: Thu Jun 23 14:57:06 2016 +0200
locking: trace errors from dir creation
---
WHATS_NEW | 1 +
lib/locking/file_locking.c | 6 ++++--
2 files changed, 5 insertions(+), 2 deletions(-)
diff --git a/WHATS_NEW b/WHATS_NEW
index e61fbb2..5e2cb5a 100644
--- a/WHATS_NEW
+++ b/WHATS_NEW
@@ -1,5 +1,6 @@
Version 2.02.158 -
=================================
+ Log system error when locking dir cannot be accessed.
Preserve monitoring status when updating thin-pool metadata.
Rerurn 0 (inactive) when status cannot be queried in _lv_active().
Switch to log_warn() for failing activation status query.
diff --git a/lib/locking/file_locking.c b/lib/locking/file_locking.c
index 230303b..390f49f 100644
--- a/lib/locking/file_locking.c
+++ b/lib/locking/file_locking.c
@@ -158,11 +158,13 @@ int init_file_locking(struct locking_type *locking, struct cmd_context *cmd,
(void) dm_prepare_selinux_context(NULL, 0);
if (!r)
- return 0;
+ return_0;
/* Trap a read-only file system */
- if ((access(_lock_dir, R_OK | W_OK | X_OK) == -1) && (errno == EROFS))
+ if ((access(_lock_dir, R_OK | W_OK | X_OK) == -1) && (errno == EROFS)) {
+ log_sys_error("access", _lock_dir);
return 0;
+ }
return 1;
}
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=dc8c5c1886ea7c09…
Commit: dc8c5c1886ea7c090a3bfa96de8f22ca060614ec
Parent: eb51be4fbee95d76b53e5255242a8032c3028aa2
Author: Zdenek Kabelac <zkabelac(a)redhat.com>
AuthorDate: Wed Jun 22 23:21:27 2016 +0200
Committer: Zdenek Kabelac <zkabelac(a)redhat.com>
CommitterDate: Thu Jun 23 14:56:10 2016 +0200
monitoring: preserve monitoring status during update
Ignore monitoring during whole update (suspend/resume) of thin-pool.
---
WHATS_NEW | 1 +
lib/metadata/thin_manip.c | 21 +++++++++++++--------
2 files changed, 14 insertions(+), 8 deletions(-)
diff --git a/WHATS_NEW b/WHATS_NEW
index 7cd46d1..e61fbb2 100644
--- a/WHATS_NEW
+++ b/WHATS_NEW
@@ -1,5 +1,6 @@
Version 2.02.158 -
=================================
+ Preserve monitoring status when updating thin-pool metadata.
Rerurn 0 (inactive) when status cannot be queried in _lv_active().
Switch to log_warn() for failing activation status query.
Refactor lvconvert argument handling code.
diff --git a/lib/metadata/thin_manip.c b/lib/metadata/thin_manip.c
index aa5f388..0d850d6 100644
--- a/lib/metadata/thin_manip.c
+++ b/lib/metadata/thin_manip.c
@@ -451,9 +451,15 @@ int update_pool_lv(struct logical_volume *lv, int activate)
if (activate) {
/* If the pool is not active, do activate deactivate */
+ monitored = dmeventd_monitor_mode();
+ init_dmeventd_monitor(DMEVENTD_MONITOR_IGNORE);
if (!lv_is_active(lv)) {
- monitored = dmeventd_monitor_mode();
- init_dmeventd_monitor(DMEVENTD_MONITOR_IGNORE);
+ /*
+ * FIXME:
+ * Rewrite activation code to handle whole tree of thinLVs
+ * as this version has major problem when it does not know
+ * which Node has pool active.
+ */
if (!activate_lv_excl(lv->vg->cmd, lv)) {
init_dmeventd_monitor(monitored);
return_0;
@@ -481,13 +487,12 @@ int update_pool_lv(struct logical_volume *lv, int activate)
}
}
- if (activate) {
- if (!deactivate_lv(lv->vg->cmd, lv)) {
- log_error("Failed to deactivate %s.", display_lvname(lv));
- ret = 0;
- }
- init_dmeventd_monitor(monitored);
+ if (activate &&
+ !deactivate_lv(lv->vg->cmd, lv)) {
+ log_error("Failed to deactivate %s.", display_lvname(lv));
+ ret = 0;
}
+ init_dmeventd_monitor(monitored);
/* Unlock memory if possible */
memlock_unlock(lv->vg->cmd);
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=eb51be4fbee95d76…
Commit: eb51be4fbee95d76b53e5255242a8032c3028aa2
Parent: af36f5ad369ebf4c1d768145a827436ccef22f63
Author: Zdenek Kabelac <zkabelac(a)redhat.com>
AuthorDate: Wed Jun 22 23:04:53 2016 +0200
Committer: Zdenek Kabelac <zkabelac(a)redhat.com>
CommitterDate: Thu Jun 23 14:55:35 2016 +0200
activation: _lv_active returns 0 on error
We have only 2 users of _lv_active() - one was already checking for ==1
while the other use (_lv_is_active()) could have take '-1' as a sign of having
an LV active. So return 0 and log_debug also the reason while detection
has failed (i.e. in case --driverload n - it's kind of expectable,
but might have confused user seeing just <backtrace>).
---
WHATS_NEW | 1 +
lib/activate/activate.c | 6 ++++--
2 files changed, 5 insertions(+), 2 deletions(-)
diff --git a/WHATS_NEW b/WHATS_NEW
index 6788e6a..7cd46d1 100644
--- a/WHATS_NEW
+++ b/WHATS_NEW
@@ -1,5 +1,6 @@
Version 2.02.158 -
=================================
+ Rerurn 0 (inactive) when status cannot be queried in _lv_active().
Switch to log_warn() for failing activation status query.
Refactor lvconvert argument handling code.
Add --logonly option to report only cmd log for a command, not other reports.
diff --git a/lib/activate/activate.c b/lib/activate/activate.c
index 8892a2a..7f5d36f 100644
--- a/lib/activate/activate.c
+++ b/lib/activate/activate.c
@@ -1266,8 +1266,10 @@ static int _lv_active(struct cmd_context *cmd, const struct logical_volume *lv)
struct lvinfo info;
if (!lv_info(cmd, lv, 0, &info, 0, 0)) {
- stack;
- return -1;
+ log_debug("Cannot determine activation status of %s%s.",
+ display_lvname(lv),
+ activation() ? "" : " (no device driver)");
+ return 0;
}
return info.exists;
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=af36f5ad369ebf4c…
Commit: af36f5ad369ebf4c1d768145a827436ccef22f63
Parent: 751163a74375cc3bfc9f338f1317f14a23798812
Author: Zdenek Kabelac <zkabelac(a)redhat.com>
AuthorDate: Tue Jun 21 15:16:03 2016 +0200
Committer: Zdenek Kabelac <zkabelac(a)redhat.com>
CommitterDate: Thu Jun 23 14:53:59 2016 +0200
activation: switch to warning
Since this function does not have a way to return error use correct
reporting level as warning.
---
WHATS_NEW | 1 +
lib/activate/activate.c | 4 ++--
2 files changed, 3 insertions(+), 2 deletions(-)
diff --git a/WHATS_NEW b/WHATS_NEW
index ce77b6c..6788e6a 100644
--- a/WHATS_NEW
+++ b/WHATS_NEW
@@ -1,5 +1,6 @@
Version 2.02.158 -
=================================
+ Switch to log_warn() for failing activation status query.
Refactor lvconvert argument handling code.
Add --logonly option to report only cmd log for a command, not other reports.
Add log/command_log_selection to configure default selection used on cmd log.
diff --git a/lib/activate/activate.c b/lib/activate/activate.c
index 089af53..8892a2a 100644
--- a/lib/activate/activate.c
+++ b/lib/activate/activate.c
@@ -1454,9 +1454,9 @@ static int _lv_is_active(const struct logical_volume *lv,
* Old users of this function will never be affected by this,
* since they are only concerned about active vs. not active.
* New users of this function who specifically ask for 'exclusive'
- * will be given an error message.
+ * will be given a warning message.
*/
- log_error("Unable to determine exclusivity of %s.", display_lvname(lv));
+ log_warn("WARNING: Unable to determine exclusivity of %s.", display_lvname(lv));
e = 0;
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=751163a74375cc3b…
Commit: 751163a74375cc3bfc9f338f1317f14a23798812
Parent: 6eeb66e51d0a230e2b8a03e5c060d31d939fd52c
Author: Peter Rajnoha <prajnoha(a)redhat.com>
AuthorDate: Thu Jun 23 13:55:39 2016 +0200
Committer: Peter Rajnoha <prajnoha(a)redhat.com>
CommitterDate: Thu Jun 23 14:45:52 2016 +0200
libdm: log: remove log_print_bypass_report calls and register new print_log_libdm for libdm during lvm initialization instead
This fixes commit f50d4011cdd3ef38c15b9dea05e73321592d93c2 which
introduced a problem when using older lvm2 code with newer libdm.
In this case, the old LVM didn't recognize new _LOG_BYPASS_REPORT flag
that libdm-report code used. This ended up with no output at all
from libdm where log_print_bypass_report was called because the
_LOG_BYPASS_REPORT was not masked properly in lvm2's print_log fn
which was called as callback function for logging.
With this patch, the lvm2 registers separate print_log_libdm logging
function for libdm instead. The print_log_libdm is exactly the same
as print_log (used throughout lvm2 code) but it checks whether we're
printing common line on output where "common" means not going to stderr,
not a warning and not an error and if we are, it adds the
_LOG_BYPASS_REPORT flag so the log_print goes directly to output, not
to any log report.
So this achieves the same goal as in f50d4011cdd3ef38c15b9dea05e73321592d93c2,
just doing it in a way that newer libdm is still compatible with older
lvm2 code (libdm-report is the only code using log_print).
Looking at the opposite mixture - older libdm with newer lvm2 code,
that won't be compilable because the new log report functionality
that is in lvm2 also requires new dm_report_group_* libdm functions
so we don't need to care here.
---
lib/commands/toolcontext.c | 2 +-
lib/log/log.c | 19 +++++++++++++++++++
lib/log/log.h | 1 -
lib/log/lvm-logging.h | 4 ++++
libdm/libdm-report.c | 32 ++++++++++++++++----------------
5 files changed, 40 insertions(+), 18 deletions(-)
diff --git a/lib/commands/toolcontext.c b/lib/commands/toolcontext.c
index d263e13..d3bd5bc 100644
--- a/lib/commands/toolcontext.c
+++ b/lib/commands/toolcontext.c
@@ -365,7 +365,7 @@ static void _init_logging(struct cmd_context *cmd)
/* Tell device-mapper about our logging */
#ifdef DEVMAPPER_SUPPORT
if (!dm_log_is_non_default())
- dm_log_with_errno_init(print_log);
+ dm_log_with_errno_init(print_log_libdm);
#endif
reset_log_duplicated();
reset_lvm_errno(1);
diff --git a/lib/log/log.c b/lib/log/log.c
index febd2e5..b3453dc 100644
--- a/lib/log/log.c
+++ b/lib/log/log.c
@@ -540,6 +540,25 @@ void print_log(int level, const char *file, int line, int dm_errno_or_class,
va_end(ap);
}
+void print_log_libdm(int level, const char *file, int line, int dm_errno_or_class,
+ const char *format, ...)
+{
+ va_list ap;
+
+ /*
+ * Bypass report if printing output from libdm and if we have
+ * LOG_WARN level and it's not going to stderr (so we're
+ * printing common message that is not an error/warning).
+ */
+ if (!(level & _LOG_STDERR) &&
+ ((level & ~(_LOG_STDERR|_LOG_ONCE|_LOG_BYPASS_REPORT)) == _LOG_WARN))
+ level |= _LOG_BYPASS_REPORT;
+
+ va_start(ap, format);
+ _vprint_log(level, file, line, dm_errno_or_class, format, ap);
+ va_end(ap);
+}
+
log_report_t log_get_report_state(void)
{
return _log_report;
diff --git a/lib/log/log.h b/lib/log/log.h
index 1bc9cbe..dac627e 100644
--- a/lib/log/log.h
+++ b/lib/log/log.h
@@ -94,7 +94,6 @@
#define log_very_verbose(args...) log_info(args)
#define log_verbose(args...) log_notice(args)
#define log_print(args...) LOG_LINE(_LOG_WARN, args)
-#define log_print_bypass_report(args...) LOG_LINE(_LOG_WARN | _LOG_BYPASS_REPORT, args)
#define log_print_unless_silent(args...) LOG_LINE(silent_mode() ? _LOG_NOTICE : _LOG_WARN, args)
#define log_error(args...) log_err(args)
#define log_error_suppress(s, args...) log_err_suppress(s, args)
diff --git a/lib/log/lvm-logging.h b/lib/log/lvm-logging.h
index 59ed7ac..4101bc8 100644
--- a/lib/log/lvm-logging.h
+++ b/lib/log/lvm-logging.h
@@ -20,6 +20,10 @@ __attribute__ ((format(printf, 5, 6)))
void print_log(int level, const char *file, int line, int dm_errno_or_class,
const char *format, ...);
+__attribute__ ((format(printf, 5, 6)))
+void print_log_libdm(int level, const char *file, int line, int dm_errno_or_class,
+ const char *format, ...);
+
#define LOG_LINE(l, x...) \
print_log(l, __FILE__, __LINE__ , 0, ## x)
diff --git a/libdm/libdm-report.c b/libdm/libdm-report.c
index 1326fdf..6bea34c 100644
--- a/libdm/libdm-report.c
+++ b/libdm/libdm-report.c
@@ -4175,7 +4175,7 @@ static int _report_headings(struct dm_report *rh)
/* print all headings */
heading = (char *) dm_pool_end_object(rh->mem);
- log_print_bypass_report("%s", heading);
+ log_print("%s", heading);
dm_pool_free(rh->mem, (void *)heading);
dm_free(buf);
@@ -4490,7 +4490,7 @@ static int _output_as_rows(struct dm_report *rh)
log_error("dm_report: Failed to terminate row");
goto bad;
}
- log_print_bypass_report("%s", (char *) dm_pool_end_object(rh->mem));
+ log_print("%s", (char *) dm_pool_end_object(rh->mem));
}
_destroy_rows(rh);
@@ -4583,7 +4583,7 @@ static int _output_as_columns(struct dm_report *rh)
}
line = (char *) dm_pool_end_object(rh->mem);
- log_print_bypass_report("%*s", rh->group_item ? rh->group_item->group->indent + (int) strlen(line) : 0, line);
+ log_print("%*s", rh->group_item ? rh->group_item->group->indent + (int) strlen(line) : 0, line);
if (!(rh->flags & DM_REPORT_OUTPUT_MULTIPLE_TIMES))
dm_list_del(&row->list);
}
@@ -4635,14 +4635,14 @@ static int _json_output_array_start(struct dm_pool *mem, struct report_group_ite
}
if (item->parent->store.finished_count > 0)
- log_print_bypass_report("%*s", item->group->indent + (int) sizeof(JSON_SEPARATOR) - 1, JSON_SEPARATOR);
+ log_print("%*s", item->group->indent + (int) sizeof(JSON_SEPARATOR) - 1, JSON_SEPARATOR);
if (item->parent->parent && item->parent->data) {
- log_print_bypass_report("%*s", item->group->indent + (int) sizeof(JSON_OBJECT_START) - 1, JSON_OBJECT_START);
+ log_print("%*s", item->group->indent + (int) sizeof(JSON_OBJECT_START) - 1, JSON_OBJECT_START);
item->group->indent += JSON_INDENT_UNIT;
}
- log_print_bypass_report("%*s", item->group->indent + (int) strlen(output), output);
+ log_print("%*s", item->group->indent + (int) strlen(output), output);
item->group->indent += JSON_INDENT_UNIT;
dm_pool_free(mem, output);
@@ -4691,9 +4691,9 @@ static int _print_basic_report_header(struct dm_report *rh)
memset(underline, '=', len);
if (rh->group_item->parent->store.finished_count > 0)
- log_print_bypass_report("%s", "");
- log_print_bypass_report("%s", report_name);
- log_print_bypass_report("%s", underline);
+ log_print("%s", "");
+ log_print("%s", report_name);
+ log_print("%s", underline);
dm_pool_free(rh->mem, underline);
return 1;
@@ -4759,7 +4759,7 @@ static int _report_group_create_basic(struct dm_report_group *group)
static int _report_group_create_json(struct dm_report_group *group)
{
- log_print_bypass_report(JSON_OBJECT_START);
+ log_print(JSON_OBJECT_START);
group->indent += JSON_INDENT_UNIT;
return 1;
}
@@ -4840,7 +4840,7 @@ static int _report_group_push_basic(struct report_group_item *item, const char *
item->report->flags &= ~(DM_REPORT_OUTPUT_MULTIPLE_TIMES);
} else {
if (!name && item->parent->store.finished_count > 0)
- log_print_bypass_report("%s", "");
+ log_print("%s", "");
}
return 1;
@@ -4868,8 +4868,8 @@ static int _report_group_push_json(struct report_group_item *item, const char *n
return 0;
}
if (item->parent->store.finished_count > 0)
- log_print_bypass_report("%*s", item->group->indent + (int) sizeof(JSON_SEPARATOR) - 1, JSON_SEPARATOR);
- log_print_bypass_report("%*s", item->group->indent + (int) sizeof(JSON_OBJECT_START) - 1, JSON_OBJECT_START);
+ log_print("%*s", item->group->indent + (int) sizeof(JSON_SEPARATOR) - 1, JSON_SEPARATOR);
+ log_print("%*s", item->group->indent + (int) sizeof(JSON_OBJECT_START) - 1, JSON_OBJECT_START);
item->group->indent += JSON_INDENT_UNIT;
}
@@ -4948,11 +4948,11 @@ static int _report_group_pop_json(struct report_group_item *item)
if (item->output_done && item->needs_closing) {
if (item->data) {
item->group->indent -= JSON_INDENT_UNIT;
- log_print_bypass_report("%*s", item->group->indent + (int) sizeof(JSON_ARRAY_END) - 1, JSON_ARRAY_END);
+ log_print("%*s", item->group->indent + (int) sizeof(JSON_ARRAY_END) - 1, JSON_ARRAY_END);
}
if (item->parent->data && item->parent->parent) {
item->group->indent -= JSON_INDENT_UNIT;
- log_print_bypass_report("%*s", item->group->indent + (int) sizeof(JSON_OBJECT_END) - 1, JSON_OBJECT_END);
+ log_print("%*s", item->group->indent + (int) sizeof(JSON_OBJECT_END) - 1, JSON_OBJECT_END);
}
item->needs_closing = 0;
}
@@ -5015,7 +5015,7 @@ static int _report_group_destroy_basic(void)
static int _report_group_destroy_json(void)
{
- log_print_bypass_report(JSON_OBJECT_END);
+ log_print(JSON_OBJECT_END);
return 1;
}
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=6eeb66e51d0a230e…
Commit: 6eeb66e51d0a230e2b8a03e5c060d31d939fd52c
Parent: 79eaaee50af92d2fd6f6590670787c87b9ce0225
Author: Peter Rajnoha <prajnoha(a)redhat.com>
AuthorDate: Thu Jun 23 13:39:38 2016 +0200
Committer: Peter Rajnoha <prajnoha(a)redhat.com>
CommitterDate: Thu Jun 23 14:45:52 2016 +0200
log: move original print_log code to _vprint_log and make print_log a wrapper over _vprint_log
Move code from original print_log fn to a separate _vprint_log function
that accepts va_list and make print_log a wrapper over _vprint_log.
The print_log just initializes the va_list and uses it for _vprint_log
call now. This way, we can reuse _vprint_log if needed.
---
lib/log/log.c | 25 ++++++++++++++++++-------
1 files changed, 18 insertions(+), 7 deletions(-)
diff --git a/lib/log/log.c b/lib/log/log.c
index 0d253e7..febd2e5 100644
--- a/lib/log/log.c
+++ b/lib/log/log.c
@@ -306,8 +306,9 @@ const char *log_get_report_object_type_name(log_report_object_type_t object_type
return log_object_type_names[object_type];
}
-void print_log(int level, const char *file, int line, int dm_errno_or_class,
- const char *format, ...)
+__attribute__ ((format(printf, 5, 0)))
+static void _vprint_log(int level, const char *file, int line, int dm_errno_or_class,
+ const char *format, va_list orig_ap)
{
va_list ap;
char buf[1024], message[4096];
@@ -360,7 +361,7 @@ void print_log(int level, const char *file, int line, int dm_errno_or_class,
(_store_errmsg && (level <= _LOG_ERR)) ||
(_log_report.report && !log_bypass_report && (use_stderr || (level <=_LOG_WARN))) ||
log_once) {
- va_start(ap, format);
+ va_copy(ap, orig_ap);
n = vsnprintf(message, sizeof(message), trformat, ap);
va_end(ap);
@@ -445,7 +446,7 @@ void print_log(int level, const char *file, int line, int dm_errno_or_class,
default: /* nothing to do */;
}
- va_start(ap, format);
+ va_copy(ap, orig_ap);
switch (level) {
case _LOG_DEBUG:
if (verbose_level() < _LOG_DEBUG)
@@ -480,7 +481,7 @@ void print_log(int level, const char *file, int line, int dm_errno_or_class,
fprintf(_log_file, "%s:%d %s%s", file, line, log_command_name(),
_msg_prefix);
- va_start(ap, format);
+ va_copy(ap, orig_ap);
vfprintf(_log_file, trformat, ap);
va_end(ap);
@@ -489,7 +490,7 @@ void print_log(int level, const char *file, int line, int dm_errno_or_class,
}
if (_syslog && (_log_while_suspended || !critical_section())) {
- va_start(ap, format);
+ va_copy(ap, orig_ap);
vsyslog(level, trformat, ap);
va_end(ap);
}
@@ -509,7 +510,7 @@ void print_log(int level, const char *file, int line, int dm_errno_or_class,
bufused += n; /* n does not include '\0' */
- va_start(ap, format);
+ va_copy(ap, orig_ap);
n = vsnprintf(buf + bufused, sizeof(buf) - bufused,
trformat, ap);
va_end(ap);
@@ -529,6 +530,16 @@ void print_log(int level, const char *file, int line, int dm_errno_or_class,
}
}
+void print_log(int level, const char *file, int line, int dm_errno_or_class,
+ const char *format, ...)
+{
+ va_list ap;
+
+ va_start(ap, format);
+ _vprint_log(level, file, line, dm_errno_or_class, format, ap);
+ va_end(ap);
+}
+
log_report_t log_get_report_state(void)
{
return _log_report;
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=973a808451e0b3fd…
Commit: 973a808451e0b3fdd6a74be31fc2cab82d6e2733
Parent: 082dee738aea58800a6ec6d0c864fa68c5dfc629
Author: Peter Rajnoha <prajnoha(a)redhat.com>
AuthorDate: Thu Jun 23 13:55:39 2016 +0200
Committer: Peter Rajnoha <prajnoha(a)redhat.com>
CommitterDate: Thu Jun 23 14:22:10 2016 +0200
libdm: log: remove log_print_bypass_report calls and register new print_log_libdm for libdm during lvm initialization instead
This fixes commit f50d4011cdd3ef38c15b9dea05e73321592d93c2 which
introduced a problem when using older lvm2 code with newer libdm.
In this case, the old LVM didn't recognize new _LOG_BYPASS_REPORT flag
that libdm-report code used. This ended up with no output at all
from libdm where log_print_bypass_report was called because the
_LOG_BYPASS_REPORT was not masked properly in lvm2's print_log fn
which was called as callback function for logging.
With this patch, the lvm2 registers separate print_log_libdm logging
function for libdm instead. The print_log_libdm is exactly the same
as print_log (used throughout lvm2 code) but it checks whether we're
printing common line on output where "common" means not going to stderr,
not a warning and not an error and if we are, it adds the
_LOG_BYPASS_REPORT flag so the log_print goes directly to output, not
to any log report.
So this achieves the same goal as in f50d4011cdd3ef38c15b9dea05e73321592d93c2,
just doing it in a way that newer libdm is still compatible with older
lvm2 code (libdm-report is the only code using log_print).
Looking at the opposite mixture - older libdm with newer lvm2 code,
that won't be compilable because the new log report functionality
that is in lvm2 also requires new dm_report_group_* libdm functions
so we don't need to care here.
---
lib/commands/toolcontext.c | 2 +-
lib/log/log.c | 19 +++++++++++++++++++
lib/log/log.h | 1 -
lib/log/lvm-logging.h | 4 ++++
libdm/libdm-report.c | 32 ++++++++++++++++----------------
5 files changed, 40 insertions(+), 18 deletions(-)
diff --git a/lib/commands/toolcontext.c b/lib/commands/toolcontext.c
index d263e13..d3bd5bc 100644
--- a/lib/commands/toolcontext.c
+++ b/lib/commands/toolcontext.c
@@ -365,7 +365,7 @@ static void _init_logging(struct cmd_context *cmd)
/* Tell device-mapper about our logging */
#ifdef DEVMAPPER_SUPPORT
if (!dm_log_is_non_default())
- dm_log_with_errno_init(print_log);
+ dm_log_with_errno_init(print_log_libdm);
#endif
reset_log_duplicated();
reset_lvm_errno(1);
diff --git a/lib/log/log.c b/lib/log/log.c
index d29628e..f2398e2 100644
--- a/lib/log/log.c
+++ b/lib/log/log.c
@@ -528,6 +528,25 @@ void print_log(int level, const char *file, int line, int dm_errno_or_class,
va_end(ap);
}
+void print_log_libdm(int level, const char *file, int line, int dm_errno_or_class,
+ const char *format, ...)
+{
+ va_list ap;
+
+ /*
+ * Bypass report if printing output from libdm and if we have
+ * LOG_WARN level and it's not going to stderr (so we're
+ * printing common message that is not an error/warning).
+ */
+ if (!(level & _LOG_STDERR) &&
+ ((level & ~(_LOG_STDERR|_LOG_ONCE|_LOG_BYPASS_REPORT)) == _LOG_WARN))
+ level |= _LOG_BYPASS_REPORT;
+
+ va_start(ap, format);
+ _vprint_log(level, file, line, dm_errno_or_class, format, ap);
+ va_end(ap);
+}
+
log_report_t log_get_report_state(void)
{
return _log_report;
diff --git a/lib/log/log.h b/lib/log/log.h
index 1bc9cbe..dac627e 100644
--- a/lib/log/log.h
+++ b/lib/log/log.h
@@ -94,7 +94,6 @@
#define log_very_verbose(args...) log_info(args)
#define log_verbose(args...) log_notice(args)
#define log_print(args...) LOG_LINE(_LOG_WARN, args)
-#define log_print_bypass_report(args...) LOG_LINE(_LOG_WARN | _LOG_BYPASS_REPORT, args)
#define log_print_unless_silent(args...) LOG_LINE(silent_mode() ? _LOG_NOTICE : _LOG_WARN, args)
#define log_error(args...) log_err(args)
#define log_error_suppress(s, args...) log_err_suppress(s, args)
diff --git a/lib/log/lvm-logging.h b/lib/log/lvm-logging.h
index 59ed7ac..4101bc8 100644
--- a/lib/log/lvm-logging.h
+++ b/lib/log/lvm-logging.h
@@ -20,6 +20,10 @@ __attribute__ ((format(printf, 5, 6)))
void print_log(int level, const char *file, int line, int dm_errno_or_class,
const char *format, ...);
+__attribute__ ((format(printf, 5, 6)))
+void print_log_libdm(int level, const char *file, int line, int dm_errno_or_class,
+ const char *format, ...);
+
#define LOG_LINE(l, x...) \
print_log(l, __FILE__, __LINE__ , 0, ## x)
diff --git a/libdm/libdm-report.c b/libdm/libdm-report.c
index 1326fdf..6bea34c 100644
--- a/libdm/libdm-report.c
+++ b/libdm/libdm-report.c
@@ -4175,7 +4175,7 @@ static int _report_headings(struct dm_report *rh)
/* print all headings */
heading = (char *) dm_pool_end_object(rh->mem);
- log_print_bypass_report("%s", heading);
+ log_print("%s", heading);
dm_pool_free(rh->mem, (void *)heading);
dm_free(buf);
@@ -4490,7 +4490,7 @@ static int _output_as_rows(struct dm_report *rh)
log_error("dm_report: Failed to terminate row");
goto bad;
}
- log_print_bypass_report("%s", (char *) dm_pool_end_object(rh->mem));
+ log_print("%s", (char *) dm_pool_end_object(rh->mem));
}
_destroy_rows(rh);
@@ -4583,7 +4583,7 @@ static int _output_as_columns(struct dm_report *rh)
}
line = (char *) dm_pool_end_object(rh->mem);
- log_print_bypass_report("%*s", rh->group_item ? rh->group_item->group->indent + (int) strlen(line) : 0, line);
+ log_print("%*s", rh->group_item ? rh->group_item->group->indent + (int) strlen(line) : 0, line);
if (!(rh->flags & DM_REPORT_OUTPUT_MULTIPLE_TIMES))
dm_list_del(&row->list);
}
@@ -4635,14 +4635,14 @@ static int _json_output_array_start(struct dm_pool *mem, struct report_group_ite
}
if (item->parent->store.finished_count > 0)
- log_print_bypass_report("%*s", item->group->indent + (int) sizeof(JSON_SEPARATOR) - 1, JSON_SEPARATOR);
+ log_print("%*s", item->group->indent + (int) sizeof(JSON_SEPARATOR) - 1, JSON_SEPARATOR);
if (item->parent->parent && item->parent->data) {
- log_print_bypass_report("%*s", item->group->indent + (int) sizeof(JSON_OBJECT_START) - 1, JSON_OBJECT_START);
+ log_print("%*s", item->group->indent + (int) sizeof(JSON_OBJECT_START) - 1, JSON_OBJECT_START);
item->group->indent += JSON_INDENT_UNIT;
}
- log_print_bypass_report("%*s", item->group->indent + (int) strlen(output), output);
+ log_print("%*s", item->group->indent + (int) strlen(output), output);
item->group->indent += JSON_INDENT_UNIT;
dm_pool_free(mem, output);
@@ -4691,9 +4691,9 @@ static int _print_basic_report_header(struct dm_report *rh)
memset(underline, '=', len);
if (rh->group_item->parent->store.finished_count > 0)
- log_print_bypass_report("%s", "");
- log_print_bypass_report("%s", report_name);
- log_print_bypass_report("%s", underline);
+ log_print("%s", "");
+ log_print("%s", report_name);
+ log_print("%s", underline);
dm_pool_free(rh->mem, underline);
return 1;
@@ -4759,7 +4759,7 @@ static int _report_group_create_basic(struct dm_report_group *group)
static int _report_group_create_json(struct dm_report_group *group)
{
- log_print_bypass_report(JSON_OBJECT_START);
+ log_print(JSON_OBJECT_START);
group->indent += JSON_INDENT_UNIT;
return 1;
}
@@ -4840,7 +4840,7 @@ static int _report_group_push_basic(struct report_group_item *item, const char *
item->report->flags &= ~(DM_REPORT_OUTPUT_MULTIPLE_TIMES);
} else {
if (!name && item->parent->store.finished_count > 0)
- log_print_bypass_report("%s", "");
+ log_print("%s", "");
}
return 1;
@@ -4868,8 +4868,8 @@ static int _report_group_push_json(struct report_group_item *item, const char *n
return 0;
}
if (item->parent->store.finished_count > 0)
- log_print_bypass_report("%*s", item->group->indent + (int) sizeof(JSON_SEPARATOR) - 1, JSON_SEPARATOR);
- log_print_bypass_report("%*s", item->group->indent + (int) sizeof(JSON_OBJECT_START) - 1, JSON_OBJECT_START);
+ log_print("%*s", item->group->indent + (int) sizeof(JSON_SEPARATOR) - 1, JSON_SEPARATOR);
+ log_print("%*s", item->group->indent + (int) sizeof(JSON_OBJECT_START) - 1, JSON_OBJECT_START);
item->group->indent += JSON_INDENT_UNIT;
}
@@ -4948,11 +4948,11 @@ static int _report_group_pop_json(struct report_group_item *item)
if (item->output_done && item->needs_closing) {
if (item->data) {
item->group->indent -= JSON_INDENT_UNIT;
- log_print_bypass_report("%*s", item->group->indent + (int) sizeof(JSON_ARRAY_END) - 1, JSON_ARRAY_END);
+ log_print("%*s", item->group->indent + (int) sizeof(JSON_ARRAY_END) - 1, JSON_ARRAY_END);
}
if (item->parent->data && item->parent->parent) {
item->group->indent -= JSON_INDENT_UNIT;
- log_print_bypass_report("%*s", item->group->indent + (int) sizeof(JSON_OBJECT_END) - 1, JSON_OBJECT_END);
+ log_print("%*s", item->group->indent + (int) sizeof(JSON_OBJECT_END) - 1, JSON_OBJECT_END);
}
item->needs_closing = 0;
}
@@ -5015,7 +5015,7 @@ static int _report_group_destroy_basic(void)
static int _report_group_destroy_json(void)
{
- log_print_bypass_report(JSON_OBJECT_END);
+ log_print(JSON_OBJECT_END);
return 1;
}
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=082dee738aea5880…
Commit: 082dee738aea58800a6ec6d0c864fa68c5dfc629
Parent: 79eaaee50af92d2fd6f6590670787c87b9ce0225
Author: Peter Rajnoha <prajnoha(a)redhat.com>
AuthorDate: Thu Jun 23 13:39:38 2016 +0200
Committer: Peter Rajnoha <prajnoha(a)redhat.com>
CommitterDate: Thu Jun 23 14:21:06 2016 +0200
log: move original print_log code to _vprint_log and make print_log a wrapper over _vprint_log
Move code from original print_log fn to a separate _vprint_log function
that accepts va_list and make print_log a wrapper over _vprint_log.
The print_log just initializes the va_list and uses it for _vprint_log
call now. This way, we can reuse _vprint_log if needed.
---
lib/log/log.c | 29 ++++++++++++++---------------
1 files changed, 14 insertions(+), 15 deletions(-)
diff --git a/lib/log/log.c b/lib/log/log.c
index 0d253e7..d29628e 100644
--- a/lib/log/log.c
+++ b/lib/log/log.c
@@ -306,10 +306,10 @@ const char *log_get_report_object_type_name(log_report_object_type_t object_type
return log_object_type_names[object_type];
}
-void print_log(int level, const char *file, int line, int dm_errno_or_class,
- const char *format, ...)
+__attribute__ ((format(printf, 5, 0)))
+static void _vprint_log(int level, const char *file, int line, int dm_errno_or_class,
+ const char *format, va_list ap)
{
- va_list ap;
char buf[1024], message[4096];
int bufused, n;
const char *trformat; /* Translated format string */
@@ -360,9 +360,7 @@ void print_log(int level, const char *file, int line, int dm_errno_or_class,
(_store_errmsg && (level <= _LOG_ERR)) ||
(_log_report.report && !log_bypass_report && (use_stderr || (level <=_LOG_WARN))) ||
log_once) {
- va_start(ap, format);
n = vsnprintf(message, sizeof(message), trformat, ap);
- va_end(ap);
/* When newer glibc returns >= sizeof(locn), we will just log what
* has fit into buffer, it's '\0' terminated string */
@@ -445,7 +443,6 @@ void print_log(int level, const char *file, int line, int dm_errno_or_class,
default: /* nothing to do */;
}
- va_start(ap, format);
switch (level) {
case _LOG_DEBUG:
if (verbose_level() < _LOG_DEBUG)
@@ -466,7 +463,6 @@ void print_log(int level, const char *file, int line, int dm_errno_or_class,
vfprintf(stream, trformat, ap);
fputc('\n', stream);
}
- va_end(ap);
}
if ((level > debug_level()) ||
@@ -480,19 +476,14 @@ void print_log(int level, const char *file, int line, int dm_errno_or_class,
fprintf(_log_file, "%s:%d %s%s", file, line, log_command_name(),
_msg_prefix);
- va_start(ap, format);
vfprintf(_log_file, trformat, ap);
- va_end(ap);
fputc('\n', _log_file);
fflush(_log_file);
}
- if (_syslog && (_log_while_suspended || !critical_section())) {
- va_start(ap, format);
+ if (_syslog && (_log_while_suspended || !critical_section()))
vsyslog(level, trformat, ap);
- va_end(ap);
- }
if (fatal_internal_error)
abort();
@@ -509,10 +500,8 @@ void print_log(int level, const char *file, int line, int dm_errno_or_class,
bufused += n; /* n does not include '\0' */
- va_start(ap, format);
n = vsnprintf(buf + bufused, sizeof(buf) - bufused,
trformat, ap);
- va_end(ap);
if (n < 0)
goto done;
@@ -529,6 +518,16 @@ void print_log(int level, const char *file, int line, int dm_errno_or_class,
}
}
+void print_log(int level, const char *file, int line, int dm_errno_or_class,
+ const char *format, ...)
+{
+ va_list ap;
+
+ va_start(ap, format);
+ _vprint_log(level, file, line, dm_errno_or_class, format, ap);
+ va_end(ap);
+}
+
log_report_t log_get_report_state(void)
{
return _log_report;
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=79eaaee50af92d2f…
Commit: 79eaaee50af92d2fd6f6590670787c87b9ce0225
Parent: 6513a7a44950ded037e1fb3e974a089b8e5690df
Author: Peter Rajnoha <prajnoha(a)redhat.com>
AuthorDate: Thu Jun 23 09:37:51 2016 +0200
Committer: Peter Rajnoha <prajnoha(a)redhat.com>
CommitterDate: Thu Jun 23 09:37:51 2016 +0200
filters: add comments about internal filter position in filter chain
---
lib/commands/toolcontext.c | 4 ++--
1 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/lib/commands/toolcontext.c b/lib/commands/toolcontext.c
index 3ee9410..d263e13 100644
--- a/lib/commands/toolcontext.c
+++ b/lib/commands/toolcontext.c
@@ -1166,7 +1166,7 @@ bad:
* If lvmetad is used, there are three filter chains:
*
* - cmd->lvmetad_filter - the lvmetad filter chain used when scanning devs for lvmetad update:
- * sysfs filter -> global regex filter -> type filter ->
+ * sysfs filter -> internal filter -> global regex filter -> type filter ->
* usable device filter(FILTER_MODE_PRE_LVMETAD) ->
* mpath component filter -> partitioned filter ->
* md component filter -> fw raid filter
@@ -1180,7 +1180,7 @@ bad:
* If lvmetad is not used, there's just one filter chain:
*
* - cmd->filter == cmd->full_filter:
- * persistent filter -> sysfs filter -> global regex filter ->
+ * persistent filter -> sysfs filter -> internal filter -> global regex filter ->
* regex_filter -> type filter -> usable device filter(FILTER_MODE_NO_LVMETAD) ->
* mpath component filter -> partitioned filter -> md component filter -> fw raid filter
*
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=6513a7a44950ded0…
Commit: 6513a7a44950ded037e1fb3e974a089b8e5690df
Parent: ebd2758dab39bb70fd63d0d77314971f8bc9cbfd
Author: Alasdair G Kergon <agk(a)redhat.com>
AuthorDate: Wed Jun 22 22:10:42 2016 +0100
Committer: Alasdair G Kergon <agk(a)redhat.com>
CommitterDate: Wed Jun 22 22:10:42 2016 +0100
lvconvert: Fix --stripes handling.
Only treat --stripes as meaning --type striped if no other type was
first detected. If a segtype got selected, don't override it later.
---
tools/lvconvert.c | 11 +++++------
1 files changed, 5 insertions(+), 6 deletions(-)
diff --git a/tools/lvconvert.c b/tools/lvconvert.c
index 9c7f9c2..f99291a 100644
--- a/tools/lvconvert.c
+++ b/tools/lvconvert.c
@@ -554,10 +554,9 @@ static int _read_params(struct cmd_context *cmd, int argc, char **argv,
lp->replace = 1;
/* If no other case was identified, then use of --stripes means --type striped */
- if (!arg_is_set(cmd, type_ARG) && !lp->merge && !lp->splitsnapshot &&
+ if (!arg_is_set(cmd, type_ARG) && !*lp->type_str && !lp->merge && !lp->splitsnapshot &&
!lp->splitcache && !lp->split && !lp->snapshot && !lp->uncache && !lp->cache && !lp->thin &&
- !lp->replace && !_mirror_or_raid_type_requested(cmd, lp->type_str) &&
- !lp->repair && !lp->mirrorlog && !lp->corelog &&
+ !lp->replace && !lp->repair && !lp->mirrorlog && !lp->corelog &&
(arg_is_set(cmd, stripes_long_ARG) || arg_is_set(cmd, stripesize_ARG)))
lp->type_str = "striped";
@@ -750,7 +749,7 @@ static int _read_params(struct cmd_context *cmd, int argc, char **argv,
/* changing mirror type? */
if (!(lp->segtype = get_segtype_from_string(cmd, arg_str_value(cmd, type_ARG, find_config_tree_str(cmd, global_mirror_segtype_default_CFG, NULL)))))
return_0;
- } /* else segtype will default to current type */
+ }
} else if (_raid0_type_requested(cmd, lp->type_str) || _striped_type_requested(cmd, lp->type_str)) { /* striped or raid0 */
if (arg_from_list_is_set(cmd, "cannot be used with --type raid0 or --type striped",
chunksize_ARG, corelog_ARG, mirrors_ARG, mirrorlog_ARG, regionsize_ARG, zero_ARG,
@@ -762,7 +761,7 @@ static int _read_params(struct cmd_context *cmd, int argc, char **argv,
if (!(lp->segtype = get_segtype_from_string(cmd, lp->type_str)))
return_0;
- }
+ } /* else segtype will default to current type */
lp->force = arg_count(cmd, force_ARG);
lp->yes = arg_count(cmd, yes_ARG);
@@ -1790,7 +1789,7 @@ static int _lvconvert_raid(struct logical_volume *lv, struct lvconvert_params *l
struct lv_segment *seg = first_seg(lv);
dm_percent_t sync_percent;
- if (!arg_is_set(cmd, type_ARG))
+ if (!lp->segtype)
lp->segtype = seg->segtype;
/* Can only change image count for raid1 and linear */
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=ebd2758dab39bb70…
Commit: ebd2758dab39bb70fd63d0d77314971f8bc9cbfd
Parent: dfc516f9bfd35ec36c60165bd319a9b0008764a3
Author: David Teigland <teigland(a)redhat.com>
AuthorDate: Wed May 25 13:57:33 2016 -0500
Committer: David Teigland <teigland(a)redhat.com>
CommitterDate: Wed Jun 22 13:13:10 2016 -0500
vgimportclone: add native command
This is cleaner and more efficient than the script.
The args and usage are unchanged.
---
lib/Makefile.in | 1 +
lib/commands/toolcontext.c | 9 +-
lib/filters/filter-internal.c | 81 +++++++++
lib/filters/filter.h | 4 +
lib/metadata/metadata.c | 3 +
lib/misc/lvm-globals.c | 11 ++
lib/misc/lvm-globals.h | 2 +
scripts/Makefile.in | 2 +-
test/Makefile.in | 3 +-
tools/Makefile.in | 1 +
tools/args.h | 2 +
tools/commands.h | 15 ++
tools/vgimportclone.c | 363 +++++++++++++++++++++++++++++++++++++++++
13 files changed, 493 insertions(+), 4 deletions(-)
diff --git a/lib/Makefile.in b/lib/Makefile.in
index 467ef90..451d96d 100644
--- a/lib/Makefile.in
+++ b/lib/Makefile.in
@@ -76,6 +76,7 @@ SOURCES =\
filters/filter-partitioned.c \
filters/filter-type.c \
filters/filter-usable.c \
+ filters/filter-internal.c \
format_text/archive.c \
format_text/archiver.c \
format_text/export.c \
diff --git a/lib/commands/toolcontext.c b/lib/commands/toolcontext.c
index 75f19c9..3ee9410 100644
--- a/lib/commands/toolcontext.c
+++ b/lib/commands/toolcontext.c
@@ -1053,7 +1053,7 @@ static int _init_dev_cache(struct cmd_context *cmd)
return 1;
}
-#define MAX_FILTERS 8
+#define MAX_FILTERS 9
static struct dev_filter *_init_lvmetad_filter_chain(struct cmd_context *cmd)
{
@@ -1078,6 +1078,13 @@ static struct dev_filter *_init_lvmetad_filter_chain(struct cmd_context *cmd)
nr_filt++;
}
+ /* internal filter used by command processing. */
+ if (!(filters[nr_filt] = internal_filter_create())) {
+ log_error("Failed to create internal device filter");
+ goto bad;
+ }
+ nr_filt++;
+
/* global regex filter. Optional. */
if ((cn = find_config_tree_node(cmd, devices_global_filter_CFG, NULL))) {
if (!(filters[nr_filt] = regex_filter_create(cn->v))) {
diff --git a/lib/filters/filter-internal.c b/lib/filters/filter-internal.c
new file mode 100644
index 0000000..1a58a37
--- /dev/null
+++ b/lib/filters/filter-internal.c
@@ -0,0 +1,81 @@
+/*
+ * Copyright (C) 2006 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "lib.h"
+#include "filter.h"
+
+static DM_LIST_INIT(_allow_devs);
+
+int internal_filter_allow(struct dm_pool *mem, struct device *dev)
+{
+ struct device_list *devl;
+
+ if (!(devl = dm_pool_alloc(mem, sizeof(*devl)))) {
+ log_error("device_list element allocation failed");
+ return 0;
+ }
+ devl->dev = dev;
+
+ dm_list_add(&_allow_devs, &devl->list);
+ return 1;
+}
+
+void internal_filter_clear(void)
+{
+ dm_list_init(&_allow_devs);
+}
+
+static int _passes_internal(struct dev_filter *f __attribute__((unused)),
+ struct device *dev)
+{
+ struct device_list *devl;
+
+ if (!internal_filtering())
+ return 1;
+
+ dm_list_iterate_items(devl, &_allow_devs) {
+ if (devl->dev == dev)
+ return 1;
+ }
+
+ log_debug_devs("%s: Skipping for internal filtering.", dev_name(dev));
+ return 0;
+}
+
+static void _destroy(struct dev_filter *f)
+{
+ if (f->use_count)
+ log_error(INTERNAL_ERROR "Destroying internal filter while in use %u times.", f->use_count);
+
+ dm_free(f);
+}
+
+struct dev_filter *internal_filter_create(void)
+{
+ struct dev_filter *f;
+
+ if (!(f = dm_zalloc(sizeof(*f)))) {
+ log_error("md filter allocation failed");
+ return NULL;
+ }
+
+ f->passes_filter = _passes_internal;
+ f->destroy = _destroy;
+ f->use_count = 0;
+
+ log_debug_devs("internal filter initialised.");
+
+ return f;
+}
+
diff --git a/lib/filters/filter.h b/lib/filters/filter.h
index ebd25e2..d75f6e1 100644
--- a/lib/filters/filter.h
+++ b/lib/filters/filter.h
@@ -32,6 +32,10 @@ struct dev_filter *persistent_filter_create(struct dev_types *dt,
const char *file);
struct dev_filter *sysfs_filter_create(void);
+struct dev_filter *internal_filter_create(void);
+int internal_filter_allow(struct dm_pool *mem, struct device *dev);
+void internal_filter_clear(void);
+
/*
* patterns must be an array of strings of the form:
* [ra]<sep><regex><sep>, eg,
diff --git a/lib/metadata/metadata.c b/lib/metadata/metadata.c
index ea42fb7..9b1fd31 100644
--- a/lib/metadata/metadata.c
+++ b/lib/metadata/metadata.c
@@ -3306,6 +3306,9 @@ static int _check_old_pv_ext_for_vg(struct volume_group *vg)
!pvl->pv->fmt->ops->pv_needs_rewrite)
continue;
+ if (_pv_in_pv_list(pvl->pv, &vg->pv_write_list))
+ continue;
+
if (!pvl->pv->fmt->ops->pv_needs_rewrite(pvl->pv->fmt, pvl->pv,
&pv_needs_rewrite))
return_0;
diff --git a/lib/misc/lvm-globals.c b/lib/misc/lvm-globals.c
index b7af353..9c78f3e 100644
--- a/lib/misc/lvm-globals.c
+++ b/lib/misc/lvm-globals.c
@@ -26,6 +26,7 @@ static int _verbose_level = VERBOSE_BASE_LEVEL;
static int _silent = 0;
static int _test = 0;
static int _md_filtering = 0;
+static int _internal_filtering = 0;
static int _fwraid_filtering = 0;
static int _pvmove = 0;
static int _full_scan_done = 0; /* Restrict to one full scan during each cmd */
@@ -79,6 +80,11 @@ void init_md_filtering(int level)
_md_filtering = level;
}
+void init_internal_filtering(int level)
+{
+ _internal_filtering = level;
+}
+
void init_fwraid_filtering(int level)
{
_fwraid_filtering = level;
@@ -242,6 +248,11 @@ int md_filtering(void)
return _md_filtering;
}
+int internal_filtering(void)
+{
+ return _internal_filtering;
+}
+
int fwraid_filtering(void)
{
return _fwraid_filtering;
diff --git a/lib/misc/lvm-globals.h b/lib/misc/lvm-globals.h
index 77c01b4..14a7d43 100644
--- a/lib/misc/lvm-globals.h
+++ b/lib/misc/lvm-globals.h
@@ -26,6 +26,7 @@ void init_verbose(int level);
void init_silent(int silent);
void init_test(int level);
void init_md_filtering(int level);
+void init_internal_filtering(int level);
void init_fwraid_filtering(int level);
void init_pvmove(int level);
void init_full_scan_done(int level);
@@ -60,6 +61,7 @@ void set_sysfs_dir_path(const char *path);
int test_mode(void);
int md_filtering(void);
+int internal_filtering(void);
int fwraid_filtering(void);
int pvmove_mode(void);
int full_scan_done(void);
diff --git a/scripts/Makefile.in b/scripts/Makefile.in
index 9c3d72d..e674239 100644
--- a/scripts/Makefile.in
+++ b/scripts/Makefile.in
@@ -31,7 +31,7 @@ endif
LVMLIBS = @LVM2APP_LIB@ -ldevmapper
endif
-LVM_SCRIPTS = lvmdump.sh lvmconf.sh vgimportclone.sh
+LVM_SCRIPTS = lvmdump.sh lvmconf.sh
DM_SCRIPTS =
ifeq ("@FSADM@", "yes")
diff --git a/test/Makefile.in b/test/Makefile.in
index 59fcc96..f48d6ea 100644
--- a/test/Makefile.in
+++ b/test/Makefile.in
@@ -321,7 +321,6 @@ LIB = $(addprefix lib/, $(LIB_SHARED) $(LIB_LOCAL) $(LIB_NOT) $(LIB_LINK_NOT) $(
$(LN_S) -f $(abs_top_builddir)/tools/dmsetup lib/dmstats
$(LN_S) -f $(abs_top_srcdir)/conf/thin-performance.profile lib/
$(LN_S) -f $(abs_top_srcdir)/scripts/fsadm.sh lib/fsadm
- $(LN_S) -f $(abs_top_srcdir)/scripts/vgimportclone.sh lib/vgimportclone
test "$(srcdir)" = . || for i in $(LIB_LVMLOCKD_CONF); do \
$(LN_S) -f $(abs_top_srcdir)/test/lib/$$i lib/; done
touch $@
@@ -333,7 +332,7 @@ endif
CLEAN_TARGETS += .lib-dir-stamp .tests-stamp $(LIB) $(addprefix lib/,\
$(CMDS) clvmd dmeventd dmsetup dmstats lvmetad lvmpolld \
- harness thin-performance.profile fsadm vgimportclone \
+ harness thin-performance.profile fsadm \
dm-version-expected version-expected \
paths-installed paths-installed-t paths-common paths-common-t)
diff --git a/tools/Makefile.in b/tools/Makefile.in
index 8dfac7f..d93c31b 100644
--- a/tools/Makefile.in
+++ b/tools/Makefile.in
@@ -60,6 +60,7 @@ SOURCES =\
vgmerge.c \
vgmknodes.c \
lvpoll.c \
+ vgimportclone.c \
vgreduce.c \
vgremove.c \
vgrename.c \
diff --git a/tools/args.h b/tools/args.h
index 670d6a0..5902513 100644
--- a/tools/args.h
+++ b/tools/args.h
@@ -154,6 +154,7 @@ arg(autobackup_ARG, 'A', "autobackup", yes_no_arg, 0, 0)
arg(activevolumegroups_ARG, 'A', "activevolumegroups", NULL, 0, 0)
arg(background_ARG, 'b', "background", NULL, 0, 0)
arg(backgroundfork_ARG, 'b', "background", NULL, 0, 0)
+arg(basevgname_ARG, 'n', "basevgname", string_arg, 0, 0)
arg(blockdevice_ARG, 'b', "blockdevice", NULL, 0, 0)
arg(chunksize_ARG, 'c', "chunksize", size_kb_arg, 0, 0)
arg(clustered_ARG, 'c', "clustered", yes_no_arg, 0, 0)
@@ -170,6 +171,7 @@ arg(help_ARG, 'h', "help", NULL, 0, 0)
arg(cache_ARG, 'H', "cache", NULL, 0, 0)
arg(history_ARG, 'H', "history", NULL, 0, 0)
arg(help2_ARG, '?', "", NULL, 0, 0)
+arg(import_ARG, 'i', "import", NULL, 0, 0)
arg(interval_ARG, 'i', "interval", int_arg, 0, 0)
arg(iop_version_ARG, 'i', "iop_version", NULL, 0, 0)
arg(stripes_ARG, 'i', "stripes", int_arg, 0, 0)
diff --git a/tools/commands.h b/tools/commands.h
index c0b3f3b..ed86b7f 100644
--- a/tools/commands.h
+++ b/tools/commands.h
@@ -1358,6 +1358,21 @@ xx(vgimport,
all_ARG, force_ARG, reportformat_ARG, select_ARG, test_ARG)
+xx(vgimportclone,
+ "Import a VG from cloned PVs",
+ NO_LVMETAD_AUTOSCAN,
+ "vgimportclone\n"
+ "\t[-d|--debug]\n"
+ "\t[-h|--help]\n"
+ "\t[-i|--import]\n"
+ "\t[-n|--basevgname]\n"
+ "\t[-t|--test]\n"
+ "\t[-v|--verbose]\n"
+ "\t[--version]\n"
+ "\t[PhysicalVolumePath...]\n",
+
+ basevgname_ARG, test_ARG, import_ARG)
+
xx(vgmerge,
"Merge volume groups",
0,
diff --git a/tools/vgimportclone.c b/tools/vgimportclone.c
new file mode 100644
index 0000000..7028fbb
--- /dev/null
+++ b/tools/vgimportclone.c
@@ -0,0 +1,363 @@
+/*
+ * Copyright (C) 2016 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "tools.h"
+#include "lvmcache.h"
+#include "lvmetad-client.h"
+#include "filter.h"
+
+struct vgimportclone_params {
+ unsigned done;
+ unsigned total;
+
+ int import_vg;
+ int found_args;
+ struct dm_list arg_import;
+ const char *base_vgname;
+ const char *old_vgname;
+ const char *new_vgname;
+};
+
+struct vgimportclone_device {
+ struct dm_list list;
+ struct device *dev;
+ unsigned found_in_vg : 1;
+};
+
+static int _vgimportclone_pv_single(struct cmd_context *cmd, struct volume_group *vg,
+ struct physical_volume *pv, struct processing_handle *handle)
+{
+ struct vgimportclone_params *vp = (struct vgimportclone_params *) handle->custom_handle;
+ struct vgimportclone_device *vd;
+
+ if (vg && is_orphan_vg(vg->name)) {
+ log_error("Cannot import clone of orphan PV %s.", dev_name(pv->dev));
+ return ECMD_FAILED;
+ }
+
+ if (!(vd = dm_pool_zalloc(cmd->mem, sizeof(*vd)))) {
+ log_error("alloc failed.");
+ return ECMD_FAILED;
+ }
+
+ vd->dev = pv->dev;
+ dm_list_add(&vp->arg_import, &vd->list);
+
+ log_debug("vgimportclone dev %s VG %s found to import",
+ dev_name(vd->dev), vg ? vg->name : "<none>");
+
+ vp->found_args++;
+
+ return ECMD_PROCESSED;
+}
+
+static int _vgimportclone_vg_single(struct cmd_context *cmd, const char *vg_name,
+ struct volume_group *vg, struct processing_handle *handle)
+{
+ char uuid[64] __attribute__((aligned(8)));
+ struct vgimportclone_params *vp = (struct vgimportclone_params *) handle->custom_handle;
+ struct vgimportclone_device *vd;
+ struct pv_list *pvl, *new_pvl;
+ struct lv_list *lvl;
+ int devs_used_for_lv = 0;
+ int found;
+
+ if (vg_is_exported(vg) && !vp->import_vg) {
+ log_error("VG %s is exported, use the --import option.", vg->name);
+ goto_bad;
+ }
+
+ if (vg_status(vg) & PARTIAL_VG) {
+ log_error("VG %s is partial, it must be complete.", vg->name);
+ goto_bad;
+ }
+
+ /*
+ * N.B. lvs_in_vg_activated() is not smart enough to distinguish
+ * between LVs that are active in the original VG vs the cloned VG
+ * that's being imported, so check DEV_USED_FOR_LV.
+ */
+ dm_list_iterate_items(pvl, &vg->pvs) {
+ if (pvl->pv->dev->flags & DEV_USED_FOR_LV) {
+ log_error("Device %s has active LVs, deactivate first.", dev_name(pvl->pv->dev));
+ devs_used_for_lv++;
+ }
+ }
+
+ if (devs_used_for_lv)
+ goto_bad;
+
+ /*
+ * The arg_import list must match the PVs in VG.
+ */
+
+ dm_list_iterate_items(pvl, &vg->pvs) {
+ found = 0;
+
+ dm_list_iterate_items(vd, &vp->arg_import) {
+ if (pvl->pv->dev != vd->dev)
+ continue;
+ vd->found_in_vg = 1;
+ found = 1;
+ break;
+ }
+
+ if (!found) {
+ if (!id_write_format(&pvl->pv->id, uuid, sizeof(uuid)))
+ goto_bad;
+
+ /* all PVs in the VG must be imported together, pvl is missing from args. */
+ log_error("PV with UUID %s is part of VG %s, but is not included in the devices to import.",
+ uuid, vg->name);
+ log_error("All PVs in the VG must be imported together.");
+ goto_bad;
+ }
+ }
+
+ dm_list_iterate_items(vd, &vp->arg_import) {
+ if (!vd->found_in_vg) {
+ /* device arg is not in the VG. */
+ log_error("Device %s was not found in VG %s.", dev_name(vd->dev), vg->name);
+ log_error("The devices to import must match the devices in the VG.");
+ goto_bad;
+ }
+ }
+
+ /*
+ * Write changes.
+ */
+
+ if (!archive(vg))
+ return_ECMD_FAILED;
+
+ if (vp->import_vg)
+ vg->status &= ~EXPORTED_VG;
+
+ if (!id_create(&vg->id))
+ goto_bad;
+
+ /* Low level vg_write code needs old_name to be set! */
+ vg->old_name = vg->name;
+
+ if (!(vg->name = dm_pool_strdup(vg->vgmem, vp->new_vgname)))
+ goto_bad;
+
+ dm_list_iterate_items(pvl, &vg->pvs) {
+ if (!(new_pvl = dm_pool_zalloc(vg->vgmem, sizeof(*new_pvl))))
+ goto_bad;
+
+ new_pvl->pv = pvl->pv;
+
+ if (!(pvl->pv->vg_name = dm_pool_strdup(vg->vgmem, vp->new_vgname)))
+ goto_bad;
+
+ if (vp->import_vg)
+ new_pvl->pv->status &= ~EXPORTED_VG;
+
+ /* Low level pv_write code needs old_id to be set! */
+ memcpy(&new_pvl->pv->old_id, &new_pvl->pv->id, sizeof(new_pvl->pv->id));
+
+ if (!id_create(&new_pvl->pv->id))
+ goto_bad;
+
+ dm_list_add(&vg->pv_write_list, &new_pvl->list);
+ }
+
+ dm_list_iterate_items(lvl, &vg->lvs)
+ memcpy(&lvl->lv->lvid, &vg->id, sizeof(vg->id));
+
+ if (!vg_write(vg) || !vg_commit(vg))
+ goto_bad;
+
+ return ECMD_PROCESSED;
+bad:
+ return ECMD_FAILED;
+}
+
+int vgimportclone(struct cmd_context *cmd, int argc, char **argv)
+{
+ struct vgimportclone_params vp = { 0 };
+ struct processing_handle *handle = NULL;
+ struct dm_list vgnameids_on_system; /* vgnameid_list */
+ struct vgnameid_list *vgnl;
+ struct vgimportclone_device *vd;
+ struct lvmcache_info *info;
+ const char *vgname;
+ char base_vgname[NAME_LEN] = { 0 };
+ char tmp_vgname[NAME_LEN] = { 0 };
+ unsigned int vgname_count;
+ int lvmetad_rescan = 0;
+ int ret = ECMD_FAILED;
+
+ if (!argc) {
+ log_error("PV names required.");
+ return EINVALID_CMD_LINE;
+ }
+
+ dm_list_init(&vgnameids_on_system);
+ dm_list_init(&vp.arg_import);
+
+ set_pv_notify(cmd);
+
+ vp.import_vg = arg_is_set(cmd, import_ARG);
+
+ if (lvmetad_used()) {
+ lvmetad_set_disabled(cmd, LVMETAD_DISABLE_REASON_DUPLICATES);
+ lvmetad_disconnect();
+ lvmetad_rescan = 1;
+ }
+
+ if (!(handle = init_processing_handle(cmd, NULL))) {
+ log_error("Failed to initialize processing handle.");
+ return ECMD_FAILED;
+ }
+ handle->custom_handle = &vp;
+
+ if (!lock_vol(cmd, VG_GLOBAL, LCK_VG_WRITE, NULL)) {
+ log_error("Unable to obtain global lock.");
+ destroy_processing_handle(cmd, handle);
+ return ECMD_FAILED;
+ }
+
+ if (!lockd_gl(cmd, "ex", 0))
+ goto_out;
+ cmd->lockd_gl_disable = 1;
+
+ /*
+ * Find the devices being imported which are named on the command line.
+ * They may be in the list of unchosen duplicates.
+ */
+
+ log_debug("Finding devices to import.");
+ cmd->command->flags |= ENABLE_DUPLICATE_DEVS;
+ process_each_pv(cmd, argc, argv, NULL, 0, READ_ALLOW_EXPORTED, handle, _vgimportclone_pv_single);
+
+ if (vp.found_args != argc) {
+ log_error("Failed to find all devices.");
+ goto_out;
+ }
+
+ /*
+ * Find the VG name of the PVs being imported, save as old_vgname.
+ * N.B. If vd->dev is a duplicate, then it may not match info->dev.
+ */
+
+ dm_list_iterate_items(vd, &vp.arg_import) {
+ if (!(info = lvmcache_info_from_pvid(vd->dev->pvid, NULL, 0))) {
+ log_error("Failed to find PVID for device %s in lvmcache.", dev_name(vd->dev));
+ goto_out;
+ }
+
+ if (!(vgname = lvmcache_vgname_from_info(info))) {
+ log_error("Failed to find VG name for device %s in lvmcache.", dev_name(vd->dev));
+ goto_out;
+ }
+
+ if (!vp.old_vgname) {
+ if (!(vp.old_vgname = dm_pool_strdup(cmd->mem, vgname)))
+ goto_out;
+ } else {
+ if (strcmp(vp.old_vgname, vgname)) {
+ log_error("Devices must be from the same VG.");
+ goto_out;
+ }
+ }
+ }
+
+ /*
+ * Pick a new VG name, save as new_vgname. The new name begins with
+ * the basevgname or old_vgname, plus a $i suffix, if necessary, to
+ * make it unique. This requires comparing the old_vgname with all the
+ * VG names on the system.
+ */
+
+ if (arg_is_set(cmd, basevgname_ARG)) {
+ snprintf(base_vgname, sizeof(base_vgname) - 1, "%s", arg_str_value(cmd, basevgname_ARG, ""));
+ memcpy(tmp_vgname, base_vgname, NAME_LEN);
+ vgname_count = 0;
+ } else {
+ snprintf(base_vgname, sizeof(base_vgname) - 1, "%s", vp.old_vgname);
+ snprintf(tmp_vgname, sizeof(tmp_vgname) - 1, "%s1", vp.old_vgname);
+ vgname_count = 1;
+ }
+
+ if (!get_vgnameids(cmd, &vgnameids_on_system, NULL, 0))
+ goto_out;
+
+retry_name:
+ dm_list_iterate_items(vgnl, &vgnameids_on_system) {
+ if (!strcmp(vgnl->vg_name, tmp_vgname)) {
+ vgname_count++;
+ snprintf(tmp_vgname, sizeof(tmp_vgname) - 1, "%s%u", base_vgname, vgname_count);
+ goto retry_name;
+ }
+ }
+
+ if (!(vp.new_vgname = dm_pool_strdup(cmd->mem, tmp_vgname)))
+ goto_out;
+ log_debug("Using new VG name %s.", vp.new_vgname);
+
+ /*
+ * Create a device filter so that we are only working with the devices
+ * in arg_import. With the original devs hidden (that arg_import were
+ * cloned from), we can read and write the cloned PVs and VG without
+ * touching the original PVs/VG.
+ */
+
+ init_internal_filtering(1);
+ dm_list_iterate_items(vd, &vp.arg_import)
+ internal_filter_allow(cmd->mem, vd->dev);
+ lvmcache_destroy(cmd, 1, 0);
+ dev_cache_full_scan(cmd->full_filter);
+
+ log_debug("Changing VG %s to %s.", vp.old_vgname, vp.new_vgname);
+
+ /* We don't care if the new name comes before the old in lock order. */
+ lvmcache_lock_ordering(0);
+
+ if (!lock_vol(cmd, vp.new_vgname, LCK_VG_WRITE, NULL)) {
+ log_error("Can't get lock for new VG name %s", vp.new_vgname);
+ goto out;
+ }
+
+ ret = process_each_vg(cmd, 0, NULL, vp.old_vgname, NULL, READ_FOR_UPDATE | READ_ALLOW_EXPORTED, 0, handle, _vgimportclone_vg_single);
+
+ unlock_vg(cmd, vp.new_vgname);
+out:
+ unlock_vg(cmd, VG_GLOBAL);
+ internal_filter_clear();
+ init_internal_filtering(0);
+ lvmcache_lock_ordering(1);
+ destroy_processing_handle(cmd, handle);
+
+ /* Enable lvmetad again if no duplicates are left. */
+ if (lvmetad_rescan) {
+ if (!lvmetad_connect(cmd)) {
+ log_warn("WARNING: Failed to connect to lvmetad.");
+ log_warn("WARNING: Update lvmetad with pvscan --cache.");
+ return ret;
+ }
+
+ if (!refresh_filters(cmd))
+ stack;
+
+ if (!lvmetad_pvscan_all_devs(cmd, 1)) {
+ log_warn("WARNING: Failed to scan devices.");
+ log_warn("WARNING: Update lvmetad with pvscan --cache.");
+ }
+ }
+
+ return ret;
+}
+
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=dfc516f9bfd35ec3…
Commit: dfc516f9bfd35ec36c60165bd319a9b0008764a3
Parent: 7e671e5dd0af699244902d5ce71a7159253c9e2b
Author: Alasdair G Kergon <agk(a)redhat.com>
AuthorDate: Wed Jun 22 18:40:22 2016 +0100
Committer: Alasdair G Kergon <agk(a)redhat.com>
CommitterDate: Wed Jun 22 18:40:22 2016 +0100
lvconvert: Refactor argument handling code.
Begin disentangling the different lvconvert modes of operation
from each other.
---
WHATS_NEW | 1 +
lib/metadata/metadata-exported.h | 9 +-
lib/metadata/raid_manip.c | 9 +-
tools/lvconvert.c | 294 ++++++++++++++++++++++++-------------
4 files changed, 206 insertions(+), 107 deletions(-)
diff --git a/WHATS_NEW b/WHATS_NEW
index 86a53ce..ce77b6c 100644
--- a/WHATS_NEW
+++ b/WHATS_NEW
@@ -1,5 +1,6 @@
Version 2.02.158 -
=================================
+ Refactor lvconvert argument handling code.
Add --logonly option to report only cmd log for a command, not other reports.
Add log/command_log_selection to configure default selection used on cmd log.
Use 'orphan' object type in cmd log for groups to collect PVs not yet in VGs.
diff --git a/lib/metadata/metadata-exported.h b/lib/metadata/metadata-exported.h
index a88ba1e..5948404 100644
--- a/lib/metadata/metadata-exported.h
+++ b/lib/metadata/metadata-exported.h
@@ -1202,8 +1202,13 @@ int lv_raid_split(struct logical_volume *lv, const char *split_name,
int lv_raid_split_and_track(struct logical_volume *lv,
struct dm_list *splittable_pvs);
int lv_raid_merge(struct logical_volume *lv);
-int lv_raid_reshape(struct logical_volume *lv,
- const struct segment_type *new_segtype);
+int lv_raid_convert(struct logical_volume *lv,
+ const struct segment_type *new_segtype,
+ int yes, int force,
+ const unsigned image_count,
+ const unsigned stripes,
+ const unsigned new_stripe_size,
+ struct dm_list *allocate_pvs);
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);
diff --git a/lib/metadata/raid_manip.c b/lib/metadata/raid_manip.c
index 739e144..132eef3 100644
--- a/lib/metadata/raid_manip.c
+++ b/lib/metadata/raid_manip.c
@@ -1469,8 +1469,13 @@ static int _convert_mirror_to_raid1(struct logical_volume *lv,
*
* Returns: 1 on success, 0 on failure
*/
-int lv_raid_reshape(struct logical_volume *lv,
- const struct segment_type *new_segtype)
+int lv_raid_convert(struct logical_volume *lv,
+ const struct segment_type *new_segtype,
+ int yes, int force,
+ unsigned new_image_count,
+ const unsigned new_stripes,
+ const unsigned new_stripe_size,
+ struct dm_list *allocate_pvs)
{
struct lv_segment *seg = first_seg(lv);
diff --git a/tools/lvconvert.c b/tools/lvconvert.c
index ae9b052..9c7f9c2 100644
--- a/tools/lvconvert.c
+++ b/tools/lvconvert.c
@@ -19,18 +19,29 @@
#include "lvconvert_poll.h"
struct lvconvert_params {
+ /* Exactly one of these options is chosen */
+ int merge; /* Either merge_snapshot or merge_mirror is also set */
int cache;
- int force;
+ int corelog;
+ int mirrorlog;
+ int mirrors_supplied; /* When type_str is not set, this may be set with keep_mimages for --splitmirrors */
+ int repair;
+ int replace;
int snapshot;
int split;
int splitcache;
int splitsnapshot;
- int merge;
- int merge_mirror;
- int poolmetadataspare;
- int repair;
int thin;
int uncache;
+ const char *type_str; /* When this is set, mirrors_supplied may optionally also be set */
+
+ const struct segment_type *segtype;
+
+ int merge_snapshot; /* merge is also set */
+ int merge_mirror; /* merge is also set */
+
+ int poolmetadataspare;
+ int force;
int yes;
int zero;
@@ -55,7 +66,6 @@ struct lvconvert_params {
const char *policy_name; /* cache */
struct dm_config_tree *policy_settings; /* cache */
- const struct segment_type *segtype;
unsigned target_attr;
alloc_policy_t alloc;
@@ -116,11 +126,21 @@ static int _lvconvert_name_params(struct lvconvert_params *lp,
int *pargc, char ***pargv)
{
if (lp->merge) {
+ /* FIXME Multiple arguments that mix snap and mirror? */
if (!*pargc) {
log_error("Please specify a logical volume path.");
return 0;
}
- return 1;
+
+ if (!strstr((*pargv)[0], "_rimage_")) { /* Snapshot */
+ if (!(lp->segtype = get_segtype_from_string(cmd, SEG_TYPE_NAME_SNAPSHOT)))
+ return_0;
+ lp->merge_snapshot = 1;
+ return 1;
+ }
+
+ /* Mirror */
+ lp->merge_mirror = 1;
}
if (!*pargc) {
@@ -191,7 +211,7 @@ static int _lvconvert_name_params(struct lvconvert_params *lp,
if (!lp->merge_mirror &&
!lp->repair &&
- !arg_is_set(cmd, splitmirrors_ARG) &&
+ !lp->keep_mimages &&
!strstr(lp->lv_name, "_tdata") &&
!strstr(lp->lv_name, "_tmeta") &&
!strstr(lp->lv_name, "_cdata") &&
@@ -247,6 +267,7 @@ static int _check_conversion_type(struct cmd_context *cmd, const char *type_str)
/* FIXME: Check thin-pool and thin more thoroughly! */
if (!strcmp(type_str, "snapshot") ||
+ !strcmp(type_str, "striped") ||
!strncmp(type_str, "raid", 4) ||
!strcmp(type_str, "cache-pool") || !strcmp(type_str, "cache") ||
!strcmp(type_str, "thin-pool") || !strcmp(type_str, "thin"))
@@ -257,43 +278,57 @@ static int _check_conversion_type(struct cmd_context *cmd, const char *type_str)
}
/* -s/--snapshot and --type snapshot are synonyms */
-static int _snapshot_type_requested(struct cmd_context *cmd, const char *type_str) {
+static int _snapshot_type_requested(struct cmd_context *cmd, const char *type_str)
+{
return (arg_is_set(cmd, snapshot_ARG) || !strcmp(type_str, "snapshot"));
}
+
+static int _raid0_type_requested(struct cmd_context *cmd, const char *type_str)
+{
+ return (!strcmp(type_str, "raid0"));
+}
+
/* mirror/raid* (1,10,4,5,6 and their variants) reshape */
-static int _mirror_or_raid_type_requested(struct cmd_context *cmd, const char *type_str) {
- return (arg_is_set(cmd, mirrors_ARG) || !strncmp(type_str, "raid", 4) || !strcmp(type_str, "mirror"));
+static int _mirror_or_raid_type_requested(struct cmd_context *cmd, const char *type_str)
+{
+ return (arg_is_set(cmd, mirrors_ARG) || !strcmp(type_str, "mirror") ||
+ (!strncmp(type_str, "raid", 4) && !_raid0_type_requested(cmd, type_str)));
+}
+
+static int _striped_type_requested(struct cmd_context *cmd, const char *type_str)
+{
+ return (!strcmp(type_str, "striped"));
}
static int _read_pool_params(struct cmd_context *cmd, int *pargc, char ***pargv,
- const char *type_str, struct lvconvert_params *lp)
+ struct lvconvert_params *lp)
{
int cachepool = 0;
int thinpool = 0;
if ((lp->pool_data_name = arg_str_value(cmd, cachepool_ARG, NULL))) {
- if (type_str[0] &&
- strcmp(type_str, "cache") &&
- strcmp(type_str, "cache-pool")) {
+ if (lp->type_str[0] &&
+ strcmp(lp->type_str, "cache") &&
+ strcmp(lp->type_str, "cache-pool")) {
log_error("--cachepool argument is only valid with "
" the cache or cache-pool segment type.");
return 0;
}
cachepool = 1;
- type_str = "cache-pool";
- } else if (!strcmp(type_str, "cache-pool"))
+ lp->type_str = "cache-pool";
+ } else if (!strcmp(lp->type_str, "cache-pool"))
cachepool = 1;
else if ((lp->pool_data_name = arg_str_value(cmd, thinpool_ARG, NULL))) {
- if (type_str[0] &&
- strcmp(type_str, "thin") &&
- strcmp(type_str, "thin-pool")) {
+ if (lp->type_str[0] &&
+ strcmp(lp->type_str, "thin") &&
+ strcmp(lp->type_str, "thin-pool")) {
log_error("--thinpool argument is only valid with "
" the thin or thin-pool segment type.");
return 0;
}
thinpool = 1;
- type_str = "thin-pool";
- } else if (!strcmp(type_str, "thin-pool"))
+ lp->type_str = "thin-pool";
+ } else if (!strcmp(lp->type_str, "thin-pool"))
thinpool = 1;
if (lp->cache && !cachepool) {
@@ -326,7 +361,7 @@ static int _read_pool_params(struct cmd_context *cmd, int *pargc, char ***pargv,
splitmirrors_ARG, splitsnapshot_ARG, -1))
return_0;
- if (!(lp->segtype = get_segtype_from_string(cmd, type_str)))
+ if (!(lp->segtype = get_segtype_from_string(cmd, lp->type_str)))
return_0;
if (!get_pool_params(cmd, lp->segtype, &lp->passed_args,
@@ -374,11 +409,13 @@ static int _read_params(struct cmd_context *cmd, int argc, char **argv,
struct arg_value_group_list *group;
int region_size;
int pagesize = lvm_getpagesize();
- const char *type_str = arg_str_value(cmd, type_ARG, "");
- if (!_check_conversion_type(cmd, type_str))
+ lp->type_str = arg_str_value(cmd, type_ARG, "");
+
+ if (arg_is_set(cmd, type_ARG) && !_check_conversion_type(cmd, lp->type_str))
return_0;
+ /* If --repair, check for incompatible args. */
if (arg_is_set(cmd, repair_ARG)) {
if (arg_outside_list_is_set(cmd, "cannot be used with --repair",
repair_ARG,
@@ -390,7 +427,12 @@ static int _read_params(struct cmd_context *cmd, int argc, char **argv,
lp->repair = 1;
}
- if (arg_is_set(cmd, mirrorlog_ARG) && arg_is_set(cmd, corelog_ARG)) {
+ if (arg_is_set(cmd, mirrorlog_ARG))
+ lp->mirrorlog = 1;
+ if (arg_is_set(cmd, corelog_ARG))
+ lp->corelog = 1;
+
+ if (lp->mirrorlog && lp->corelog) {
log_error("--mirrorlog and --corelog are incompatible.");
return 0;
}
@@ -432,57 +474,40 @@ static int _read_params(struct cmd_context *cmd, int argc, char **argv,
lp->uncache = 1;
}
- if ((_snapshot_type_requested(cmd, type_str) || arg_is_set(cmd, merge_ARG)) &&
- (arg_is_set(cmd, mirrorlog_ARG) || _mirror_or_raid_type_requested(cmd, type_str) ||
- lp->repair || arg_is_set(cmd, thinpool_ARG))) {
- log_error("--snapshot/--type snapshot or --merge argument "
- "cannot be mixed with --mirrors/--type mirror/--type raid*, "
- "--mirrorlog, --repair or --thinpool.");
- return 0;
- }
-
- if ((arg_is_set(cmd, stripes_long_ARG) || arg_is_set(cmd, stripesize_ARG)) &&
- !(_mirror_or_raid_type_requested(cmd, type_str) ||
- lp->repair ||
- arg_is_set(cmd, thinpool_ARG))) {
- log_error("--stripes or --stripesize argument is only valid "
- "with --mirrors/--type mirror/--type raid*, --repair and --thinpool");
- return 0;
- }
-
if (arg_is_set(cmd, cache_ARG))
lp->cache = 1;
- if (!strcmp(type_str, "cache"))
+ if (!strcmp(lp->type_str, "cache"))
lp->cache = 1;
else if (lp->cache) {
- if (type_str[0]) {
- log_error("--cache is incompatible with --type %s", type_str);
+ if (lp->type_str[0]) {
+ log_error("--cache is incompatible with --type %s", lp->type_str);
return 0;
}
- type_str = "cache";
+ lp->type_str = "cache";
}
if (arg_is_set(cmd, thin_ARG))
lp->thin = 1;
- if (!strcmp(type_str, "thin"))
+ if (!strcmp(lp->type_str, "thin"))
lp->thin = 1;
else if (lp->thin) {
- if (type_str[0]) {
- log_error("--thin is incompatible with --type %s", type_str);
+ if (lp->type_str[0]) {
+ log_error("--thin is incompatible with --type %s", lp->type_str);
return 0;
}
- type_str = "thin";
+ lp->type_str = "thin";
}
- if (!_read_pool_params(cmd, &argc, &argv, type_str, lp))
+ /* May set lp->segtype */
+ if (!_read_pool_params(cmd, &argc, &argv, lp))
return_0;
if (!arg_is_set(cmd, background_ARG))
lp->wait_completion = 1;
- if (_snapshot_type_requested(cmd, type_str)) {
+ if (_snapshot_type_requested(cmd, lp->type_str)) {
if (arg_is_set(cmd, merge_ARG)) {
log_error("--snapshot and --merge are mutually exclusive.");
return 0;
@@ -493,6 +518,7 @@ static int _read_params(struct cmd_context *cmd, int argc, char **argv,
if (lp->split) {
lp->lv_split_name = arg_str_value(cmd, name_ARG, NULL);
+
/*
* The '--splitmirrors n' argument is equivalent to '--mirrors -n'
* (note the minus sign), except that it signifies the additional
@@ -500,7 +526,7 @@ static int _read_params(struct cmd_context *cmd, int argc, char **argv,
* discarding it.
*/
} else if (arg_is_set(cmd, splitmirrors_ARG)) {
- if (_mirror_or_raid_type_requested(cmd, type_str)) {
+ if (_mirror_or_raid_type_requested(cmd, lp->type_str)) {
log_error("--mirrors/--type mirror/--type raid* and --splitmirrors are "
"mutually exclusive.");
return 0;
@@ -521,38 +547,84 @@ static int _read_params(struct cmd_context *cmd, int argc, char **argv,
return 0;
}
- if (arg_is_set(cmd, merge_ARG)) {
- if ((argc == 1) && strstr(argv[0], "_rimage_"))
- lp->merge_mirror = 1;
- else
- lp->merge = 1;
+ if (arg_is_set(cmd, merge_ARG))
+ lp->merge = 1;
+
+ if (arg_is_set(cmd, replace_ARG))
+ lp->replace = 1;
+
+ /* If no other case was identified, then use of --stripes means --type striped */
+ if (!arg_is_set(cmd, type_ARG) && !lp->merge && !lp->splitsnapshot &&
+ !lp->splitcache && !lp->split && !lp->snapshot && !lp->uncache && !lp->cache && !lp->thin &&
+ !lp->replace && !_mirror_or_raid_type_requested(cmd, lp->type_str) &&
+ !lp->repair && !lp->mirrorlog && !lp->corelog &&
+ (arg_is_set(cmd, stripes_long_ARG) || arg_is_set(cmd, stripesize_ARG)))
+ lp->type_str = "striped";
+
+ if ((_snapshot_type_requested(cmd, lp->type_str) || lp->merge) &&
+ (lp->mirrorlog || _mirror_or_raid_type_requested(cmd, lp->type_str) ||
+ lp->repair || arg_is_set(cmd, thinpool_ARG) || _raid0_type_requested(cmd, lp->type_str) ||
+ _striped_type_requested(cmd, lp->type_str))) {
+ log_error("--snapshot/--type snapshot or --merge argument "
+ "cannot be mixed with --mirrors/--type mirror/--type raid*/--stripes/--type striped, "
+ "--mirrorlog, --repair or --thinpool.");
+ return 0;
+ }
+
+ if ((arg_is_set(cmd, stripes_long_ARG) || arg_is_set(cmd, stripesize_ARG)) &&
+ !(_mirror_or_raid_type_requested(cmd, lp->type_str) || _striped_type_requested(cmd, lp->type_str) ||
+ _raid0_type_requested(cmd, lp->type_str) || lp->repair || arg_is_set(cmd, thinpool_ARG))) {
+ log_error("--stripes or --stripesize argument is only valid "
+ "with --mirrors/--type mirror/--type raid*/--type striped, --repair and --thinpool");
+ return 0;
}
if (arg_is_set(cmd, mirrors_ARG)) {
/*
- * --splitmirrors has been chosen as the mechanism for
- * specifying the intent of detaching and keeping a mimage
- * versus an additional qualifying argument being added here.
+ * --splitmirrors is the mechanism for detaching and keeping a mimage
*/
+ lp->mirrors_supplied = 1;
lp->mirrors = arg_uint_value(cmd, mirrors_ARG, 0);
lp->mirrors_sign = arg_sign_value(cmd, mirrors_ARG, SIGN_NONE);
}
lp->alloc = (alloc_policy_t) arg_uint_value(cmd, alloc_ARG, ALLOC_INHERIT);
- /* There are six types of lvconvert. */
- if (lp->merge) { /* Snapshot merge */
+ /*
+ * Final checking of each case:
+ * lp->merge
+ * lp->splitsnapshot
+ * lp->splitcache
+ * lp->split
+ * lp->uncache
+ * lp->cache
+ * lp->thin
+ * lp->snapshot
+ * lp->replace
+ * --type mirror|raid lp->repair lp->mirrorlog lp->corelog
+ * --type raid0|striped
+ */
+ if (lp->merge) { /* Snapshot or mirror merge */
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, SEG_TYPE_NAME_SNAPSHOT)))
- return_0;
} else if (lp->splitsnapshot) /* Destroy snapshot retaining cow as separate LV */
;
+ else if (lp->splitcache)
+ ;
+ else if (lp->split)
+ ;
+ else if (lp->uncache)
+ ;
+ else if (lp->cache)
+ ;
+ else if (lp->thin)
+ ;
+ else if (lp->keep_mimages) /* --splitmirrors */
+ ;
else if (lp->snapshot) { /* Snapshot creation from pre-existing cow */
if (!argc) {
log_error("Please provide logical volume path for snapshot origin.");
@@ -592,7 +664,7 @@ static int _read_params(struct cmd_context *cmd, int argc, char **argv,
lp->zero = (lp->segtype->flags & SEG_CANNOT_BE_ZEROED)
? 0 : arg_int_value(cmd, zero_ARG, 1);
- } else if (arg_is_set(cmd, replace_ARG)) { /* RAID device replacement */
+ } else if (lp->replace) { /* RAID device replacement */
lp->replace_pv_count = arg_count(cmd, replace_ARG);
lp->replace_pvs = dm_pool_alloc(cmd->mem, sizeof(char *) * lp->replace_pv_count);
if (!lp->replace_pvs)
@@ -612,10 +684,8 @@ static int _read_params(struct cmd_context *cmd, int argc, char **argv,
tmp_str)))
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) */
+ } else if (_mirror_or_raid_type_requested(cmd, lp->type_str) ||
+ lp->repair || lp->mirrorlog || lp->corelog) { /* Mirrors (and some RAID functions) */
if (arg_is_set(cmd, chunksize_ARG)) {
log_error("--chunksize is only available with snapshots or pools.");
return 0;
@@ -630,7 +700,6 @@ static int _read_params(struct cmd_context *cmd, int argc, char **argv,
* --regionsize is only valid if converting an LV into a mirror.
* Checked when we know the state of the LV being converted.
*/
-
if (arg_is_set(cmd, regionsize_ARG)) {
if (arg_sign_value(cmd, regionsize_ARG, SIGN_NONE) ==
SIGN_MINUS) {
@@ -671,7 +740,8 @@ static int _read_params(struct cmd_context *cmd, int argc, char **argv,
if (!get_stripe_params(cmd, &lp->stripes, &lp->stripe_size))
return_0;
- if (arg_is_set(cmd, mirrors_ARG) && !lp->mirrors) {
+ /* FIXME man page says in one place that --type and --mirrors can't be mixed */
+ if (lp->mirrors_supplied && !lp->mirrors) {
/* down-converting to linear/stripe? */
if (!(lp->segtype =
get_segtype_from_string(cmd, SEG_TYPE_NAME_STRIPED)))
@@ -681,6 +751,17 @@ static int _read_params(struct cmd_context *cmd, int argc, char **argv,
if (!(lp->segtype = get_segtype_from_string(cmd, arg_str_value(cmd, type_ARG, find_config_tree_str(cmd, global_mirror_segtype_default_CFG, NULL)))))
return_0;
} /* else segtype will default to current type */
+ } else if (_raid0_type_requested(cmd, lp->type_str) || _striped_type_requested(cmd, lp->type_str)) { /* striped or raid0 */
+ if (arg_from_list_is_set(cmd, "cannot be used with --type raid0 or --type striped",
+ chunksize_ARG, corelog_ARG, mirrors_ARG, mirrorlog_ARG, regionsize_ARG, zero_ARG,
+ -1))
+ return_0;
+
+ if (!get_stripe_params(cmd, &lp->stripes, &lp->stripe_size))
+ return_0;
+
+ if (!(lp->segtype = get_segtype_from_string(cmd, lp->type_str)))
+ return_0;
}
lp->force = arg_count(cmd, force_ARG);
@@ -1139,7 +1220,7 @@ static int _lvconvert_mirrors_parse_params(struct cmd_context *cmd,
*old_mimage_count = lv_mirror_count(lv);
*old_log_count = _get_log_count(lv);
- if (is_lockd_type(lv->vg->lock_type) && arg_is_set(cmd, splitmirrors_ARG)) {
+ if (is_lockd_type(lv->vg->lock_type) && lp->keep_mimages) {
/* FIXME: we need to create a lock for the new LV. */
log_error("Unable to split mirrors in VG with lock_type %s", lv->vg->lock_type);
return 0;
@@ -1150,9 +1231,9 @@ static int _lvconvert_mirrors_parse_params(struct cmd_context *cmd,
*
* If called with no argument, try collapsing the resync layers
*/
- if (!arg_is_set(cmd, mirrors_ARG) && !arg_is_set(cmd, mirrorlog_ARG) &&
- !arg_is_set(cmd, corelog_ARG) && !arg_is_set(cmd, regionsize_ARG) &&
- !arg_is_set(cmd, splitmirrors_ARG) && !lp->repair) {
+ if (!lp->mirrors_supplied && !lp->mirrorlog &&
+ !lp->corelog && !arg_is_set(cmd, regionsize_ARG) &&
+ !lp->keep_mimages && !lp->repair) {
*new_mimage_count = *old_mimage_count;
*new_log_count = *old_log_count;
@@ -1164,7 +1245,7 @@ static int _lvconvert_mirrors_parse_params(struct cmd_context *cmd,
/*
* Adjusting mimage count?
*/
- if (!arg_is_set(cmd, mirrors_ARG) && !arg_is_set(cmd, splitmirrors_ARG))
+ if (!lp->mirrors_supplied && !lp->keep_mimages)
lp->mirrors = *old_mimage_count;
else if (lp->mirrors_sign == SIGN_PLUS)
lp->mirrors = *old_mimage_count + lp->mirrors;
@@ -1207,11 +1288,10 @@ static int _lvconvert_mirrors_parse_params(struct cmd_context *cmd,
* position that the user would like a 'disk' log.
*/
*new_log_count = (*old_mimage_count > 1) ? *old_log_count : 1;
- if (!arg_is_set(cmd, corelog_ARG) && !arg_is_set(cmd, mirrorlog_ARG))
+ if (!lp->corelog && !lp->mirrorlog)
return 1;
- *new_log_count = arg_int_value(cmd, mirrorlog_ARG,
- arg_is_set(cmd, corelog_ARG) ? MIRROR_LOG_CORE : DEFAULT_MIRRORLOG);
+ *new_log_count = arg_int_value(cmd, mirrorlog_ARG, lp->corelog ? MIRROR_LOG_CORE : DEFAULT_MIRRORLOG);
/*
* No mirrored logs for cluster mirrors until
@@ -1665,6 +1745,10 @@ static int _is_valid_raid_conversion(const struct segment_type *from_segtype,
if (from_segtype == to_segtype)
return 1;
+ /* Support raid0 <-> striped conversions */
+ if (segtype_is_striped(from_segtype) && segtype_is_striped(to_segtype))
+ return 1;
+
if (!segtype_is_raid(from_segtype) && !segtype_is_raid(to_segtype))
return_0; /* Not converting to or from RAID? */
@@ -1710,8 +1794,7 @@ static int _lvconvert_raid(struct logical_volume *lv, struct lvconvert_params *l
lp->segtype = seg->segtype;
/* Can only change image count for raid1 and linear */
- if (arg_is_set(cmd, mirrors_ARG) &&
- !seg_is_mirrored(seg) && !seg_is_linear(seg)) {
+ if (lp->mirrors_supplied && !seg_is_mirrored(seg) && !seg_is_linear(seg)) {
log_error("'--mirrors/-m' is not compatible with %s",
lvseg_name(seg));
return 0;
@@ -1727,13 +1810,13 @@ static int _lvconvert_raid(struct logical_volume *lv, struct lvconvert_params *l
return 0;
}
- if (seg_is_linear(seg) && !lp->merge_mirror && !arg_is_set(cmd, mirrors_ARG)) {
+ if (seg_is_linear(seg) && !lp->merge_mirror && !lp->mirrors_supplied) {
log_error("Raid conversions require -m/--mirrors");
return 0;
}
/* Change number of RAID1 images */
- if (arg_is_set(cmd, mirrors_ARG) || arg_is_set(cmd, splitmirrors_ARG)) {
+ if (lp->mirrors_supplied || lp->keep_mimages) {
image_count = lv_raid_image_count(lv);
if (lp->mirrors_sign == SIGN_PLUS)
image_count += lp->mirrors;
@@ -1744,8 +1827,7 @@ static int _lvconvert_raid(struct logical_volume *lv, struct lvconvert_params *l
if (image_count < 1) {
log_error("Unable to %s images by specified amount",
- arg_is_set(cmd, splitmirrors_ARG) ?
- "split" : "reduce");
+ lp->keep_mimages ? "split" : "reduce");
return 0;
}
}
@@ -1756,17 +1838,24 @@ static int _lvconvert_raid(struct logical_volume *lv, struct lvconvert_params *l
if (arg_is_set(cmd, trackchanges_ARG))
return lv_raid_split_and_track(lv, lp->pvh);
- if (arg_is_set(cmd, splitmirrors_ARG))
+ if (lp->keep_mimages)
return lv_raid_split(lv, lp->lv_split_name,
image_count, lp->pvh);
- if (arg_is_set(cmd, mirrors_ARG))
+ if (lp->mirrors_supplied)
return lv_raid_change_image_count(lv, image_count, lp->pvh);
- if (arg_is_set(cmd, type_ARG))
- return lv_raid_reshape(lv, lp->segtype);
+ if ((seg_is_linear(seg) || seg_is_striped(seg) || seg_is_mirrored(seg) || lv_is_raid(lv)) &&
+ ((lp->type_str && lp->type_str[0]) || image_count)) {
+ if (segtype_is_any_raid0(lp->segtype) &&
+ !(lp->target_attr & RAID_FEATURE_RAID0)) {
+ log_error("RAID module does not support RAID0.");
+ return 0;
+ }
+ return lv_raid_convert(lv, lp->segtype, lp->yes, lp->force, image_count, lp->stripes, lp->stripe_size, lp->pvh);
+ }
- if (arg_is_set(cmd, replace_ARG))
+ if (lp->replace)
return lv_raid_replace(lv, lp->replace_pvh, lp->pvh);
if (lp->repair) {
@@ -1778,7 +1867,8 @@ static int _lvconvert_raid(struct logical_volume *lv, struct lvconvert_params *l
return 0;
}
- if (!lv_raid_percent(lv, &sync_percent)) {
+ if (!seg_is_striped(seg) && !seg_is_any_raid0(seg) &&
+ !lv_raid_percent(lv, &sync_percent)) {
log_error("Unable to determine sync status of %s/%s.",
lv->vg->name, lv->name);
return 0;
@@ -3256,7 +3346,7 @@ static int _lvconvert(struct cmd_context *cmd, struct logical_volume *lv,
return ECMD_FAILED;
}
- if (lv_is_cow(lv) && !lp->merge && !lp->splitsnapshot) {
+ if (lv_is_cow(lv) && !lp->merge_snapshot && !lp->splitsnapshot) {
log_error("Cannot convert snapshot logical volume %s.",
display_lvname(lv));
return ECMD_FAILED;
@@ -3331,8 +3421,8 @@ static int _lvconvert(struct cmd_context *cmd, struct logical_volume *lv,
/* forward splitmirror operations to the cache origin, which may be raid
* or old-style mirror */
- if (arg_is_set(cmd, splitmirrors_ARG) && lv_is_cache_type(lv)
- && (origin = seg_lv(first_seg(lv), 0)) && lv_is_cache_origin(origin)) {
+ if (lp->keep_mimages && lv_is_cache_type(lv) &&
+ (origin = seg_lv(first_seg(lv), 0)) && lv_is_cache_origin(origin)) {
log_warn("WARNING: Selected operation does not work with cache-type LVs.");
log_warn("WARNING: Proceeding using the cache origin volume %s instead.",
display_lvname(origin));
@@ -3348,12 +3438,12 @@ static int _lvconvert(struct cmd_context *cmd, struct logical_volume *lv,
* the segtype was not specified, then we need
* to consult the default.
*/
- if (arg_is_set(cmd, mirrors_ARG) && !lv_is_mirrored(lv)) {
+ if (lp->mirrors_supplied && !lv_is_mirrored(lv)) {
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) {
+ if (lp->merge_snapshot) {
if ((lv_is_thin_volume(lv) && !_lvconvert_merge_thin_snapshot(cmd, lv, lp)) ||
(!lv_is_thin_volume(lv) && !_lvconvert_merge_old_snapshot(cmd, lv, lp))) {
log_print_unless_silent("Unable to merge volume %s into its origin.",
@@ -3384,9 +3474,7 @@ static int _lvconvert(struct cmd_context *cmd, struct logical_volume *lv,
/* If repairing and using policies, remove missing PVs from VG */
if (lp->repair && arg_is_set(cmd, usepolicies_ARG))
_remove_missing_empty_pv(lv->vg, failed_pvs);
- } else if (arg_is_set(cmd, mirrors_ARG) ||
- arg_is_set(cmd, splitmirrors_ARG) ||
- lv_is_mirrored(lv)) {
+ } else if (lp->mirrors_supplied || lp->keep_mimages || lv_is_mirrored(lv)) {
if (!archive(lv->vg))
return_ECMD_FAILED;
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=7e671e5dd0af6992…
Commit: 7e671e5dd0af699244902d5ce71a7159253c9e2b
Parent: 6c269e639a121329fc035685f944816a763b23cf
Author: Alasdair G Kergon <agk(a)redhat.com>
AuthorDate: Tue Jun 21 22:24:52 2016 +0100
Committer: Alasdair G Kergon <agk(a)redhat.com>
CommitterDate: Tue Jun 21 22:24:52 2016 +0100
tools: Use arg_is_set instead of arg_count.
---
tools/dumpconfig.c | 62 +++++++++++++-------------
tools/lvchange.c | 116 ++++++++++++++++++++++++------------------------
tools/lvconvert.c | 122 +++++++++++++++++++++++++-------------------------
tools/lvcreate.c | 18 ++++----
tools/lvdisplay.c | 26 +++++-----
tools/lvmcmdline.c | 98 ++++++++++++++++++++--------------------
tools/lvmdiskscan.c | 6 +-
tools/lvresize.c | 22 +++++-----
tools/lvscan.c | 6 +-
tools/pvchange.c | 26 +++++-----
tools/pvcreate.c | 12 +++---
tools/pvdisplay.c | 32 +++++++-------
tools/pvmove.c | 4 +-
tools/pvscan.c | 24 +++++-----
tools/reporter.c | 42 +++++++++---------
tools/toollib.c | 46 +++++++++---------
tools/vgcfgbackup.c | 2 +-
tools/vgcfgrestore.c | 8 ++--
tools/vgchange.c | 98 ++++++++++++++++++++--------------------
tools/vgconvert.c | 10 ++--
tools/vgcreate.c | 2 +-
tools/vgdisplay.c | 36 +++++++-------
tools/vgexport.c | 4 +-
tools/vgextend.c | 6 +-
tools/vgimport.c | 6 +-
tools/vgmknodes.c | 2 +-
tools/vgreduce.c | 10 ++--
tools/vgscan.c | 2 +-
tools/vgsplit.c | 16 +++---
29 files changed, 432 insertions(+), 432 deletions(-)
diff --git a/tools/dumpconfig.c b/tools/dumpconfig.c
index 0880740..3da04f0 100644
--- a/tools/dumpconfig.c
+++ b/tools/dumpconfig.c
@@ -20,9 +20,9 @@ static int _get_vsn(struct cmd_context *cmd, uint16_t *version_int)
const char *vsn;
unsigned int major, minor, patchlevel;
- if (arg_count(cmd, atversion_ARG))
+ if (arg_is_set(cmd, atversion_ARG))
vsn = arg_str_value(cmd, atversion_ARG, NULL);
- else if (arg_count(cmd, sinceversion_ARG))
+ else if (arg_is_set(cmd, sinceversion_ARG))
vsn = arg_str_value(cmd, sinceversion_ARG, NULL);
else
vsn = LVM_VERSION;
@@ -98,7 +98,7 @@ static int _config_validate(struct cmd_context *cmd, struct dm_config_tree *cft)
int dumpconfig(struct cmd_context *cmd, int argc, char **argv)
{
const char *file = arg_str_value(cmd, file_ARG, NULL);
- const char *type = arg_str_value(cmd, configtype_ARG, arg_count(cmd, list_ARG) ? "list" : "current");
+ const char *type = arg_str_value(cmd, configtype_ARG, arg_is_set(cmd, list_ARG) ? "list" : "current");
struct config_def_tree_spec tree_spec = {0};
struct dm_config_tree *cft = NULL;
struct cft_check_handle *cft_check_handle = NULL;
@@ -107,43 +107,43 @@ int dumpconfig(struct cmd_context *cmd, int argc, char **argv)
tree_spec.cmd = cmd;
- if (arg_count(cmd, configtype_ARG) && arg_count(cmd, validate_ARG)) {
+ if (arg_is_set(cmd, configtype_ARG) && arg_is_set(cmd, validate_ARG)) {
log_error("Only one of --type and --validate permitted.");
return EINVALID_CMD_LINE;
}
- if (arg_count(cmd, configtype_ARG) && arg_count(cmd, list_ARG)) {
+ if (arg_is_set(cmd, configtype_ARG) && arg_is_set(cmd, list_ARG)) {
log_error("Only one of --type and --list permitted.");
return EINVALID_CMD_LINE;
}
- if (arg_count(cmd, atversion_ARG)) {
- if (arg_count(cmd, sinceversion_ARG)) {
+ if (arg_is_set(cmd, atversion_ARG)) {
+ if (arg_is_set(cmd, sinceversion_ARG)) {
log_error("Only one of --atversion and --sinceversion permitted.");
return EINVALID_CMD_LINE;
}
- if (!arg_count(cmd, configtype_ARG) && !arg_count(cmd, list_ARG)) {
+ if (!arg_is_set(cmd, configtype_ARG) && !arg_is_set(cmd, list_ARG)) {
log_error("--atversion requires --type or --list");
return EINVALID_CMD_LINE;
}
- } else if (arg_count(cmd, sinceversion_ARG)) {
- if (!arg_count(cmd, configtype_ARG) || strcmp(type, "new")) {
+ } else if (arg_is_set(cmd, sinceversion_ARG)) {
+ if (!arg_is_set(cmd, configtype_ARG) || strcmp(type, "new")) {
log_error("--sinceversion requires --type new");
return EINVALID_CMD_LINE;
}
}
- if (arg_count(cmd, ignoreadvanced_ARG))
+ if (arg_is_set(cmd, ignoreadvanced_ARG))
tree_spec.ignoreadvanced = 1;
- if (arg_count(cmd, ignoreunsupported_ARG)) {
- if (arg_count(cmd, showunsupported_ARG)) {
+ if (arg_is_set(cmd, ignoreunsupported_ARG)) {
+ if (arg_is_set(cmd, showunsupported_ARG)) {
log_error("Only one of --ignoreunsupported and --showunsupported permitted.");
return EINVALID_CMD_LINE;
}
tree_spec.ignoreunsupported = 1;
- } else if (arg_count(cmd, showunsupported_ARG)) {
+ } else if (arg_is_set(cmd, showunsupported_ARG)) {
tree_spec.ignoreunsupported = 0;
} else if (strcmp(type, "current") && strcmp(type, "diff")) {
/*
@@ -165,28 +165,28 @@ int dumpconfig(struct cmd_context *cmd, int argc, char **argv)
* is lower than the version in which the
* setting was deprecated.
*/
- if (!arg_count(cmd, showdeprecated_ARG))
+ if (!arg_is_set(cmd, showdeprecated_ARG))
tree_spec.ignoredeprecated = 1;
}
- if (arg_count(cmd, ignorelocal_ARG))
+ if (arg_is_set(cmd, ignorelocal_ARG))
tree_spec.ignorelocal = 1;
if (!strcmp(type, "current") || !strcmp(type, "full")) {
- if (arg_count(cmd, atversion_ARG)) {
+ if (arg_is_set(cmd, atversion_ARG)) {
log_error("--atversion has no effect with --type %s", type);
return EINVALID_CMD_LINE;
}
- if ((arg_count(cmd, ignoreunsupported_ARG) ||
- arg_count(cmd, ignoreadvanced_ARG)) &&
+ if ((arg_is_set(cmd, ignoreunsupported_ARG) ||
+ arg_is_set(cmd, ignoreadvanced_ARG)) &&
!strcmp(type, "current")) {
/* FIXME: allow these even for --type current */
log_error("--ignoreadvanced and --ignoreunsupported has "
"no effect with --type current");
return EINVALID_CMD_LINE;
}
- } else if (arg_count(cmd, mergedconfig_ARG)) {
+ } else if (arg_is_set(cmd, mergedconfig_ARG)) {
log_error("--mergedconfig has no effect without --type current or --type full");
return EINVALID_CMD_LINE;
}
@@ -199,7 +199,7 @@ int dumpconfig(struct cmd_context *cmd, int argc, char **argv)
* but it is used just for dumping the profile content and not for
* application.
*/
- if (arg_count(cmd, profile_ARG) &&
+ if (arg_is_set(cmd, profile_ARG) &&
(!(profile = add_profile(cmd, arg_str_value(cmd, profile_ARG, NULL), CONFIG_PROFILE_COMMAND)) ||
!override_config_tree_from_profile(cmd, profile))) {
log_error("Failed to load profile %s.", arg_str_value(cmd, profile_ARG, NULL));
@@ -210,7 +210,7 @@ int dumpconfig(struct cmd_context *cmd, int argc, char **argv)
* Set the 'cft' to work with based on whether we need the plain
* config tree or merged config tree cascade if --mergedconfig is used.
*/
- if ((arg_count(cmd, mergedconfig_ARG) || !strcmp(type, "full") || !strcmp(type, "diff")) && cmd->cft->cascade) {
+ if ((arg_is_set(cmd, mergedconfig_ARG) || !strcmp(type, "full") || !strcmp(type, "diff")) && cmd->cft->cascade) {
if (!_merge_config_cascade(cmd, cmd->cft, &cft)) {
log_error("Failed to merge configuration.");
r = ECMD_FAILED;
@@ -220,7 +220,7 @@ int dumpconfig(struct cmd_context *cmd, int argc, char **argv)
cft = cmd->cft;
tree_spec.current_cft = cft;
- if (arg_count(cmd, validate_ARG)) {
+ if (arg_is_set(cmd, validate_ARG)) {
if (_config_validate(cmd, cft)) {
log_print("LVM configuration valid.");
goto out;
@@ -231,9 +231,9 @@ int dumpconfig(struct cmd_context *cmd, int argc, char **argv)
}
}
- if (!strcmp(type, "list") || arg_count(cmd, list_ARG)) {
+ if (!strcmp(type, "list") || arg_is_set(cmd, list_ARG)) {
tree_spec.type = CFG_DEF_TREE_LIST;
- if (arg_count(cmd, withcomments_ARG)) {
+ if (arg_is_set(cmd, withcomments_ARG)) {
log_error("--withcomments has no effect with --type list");
return EINVALID_CMD_LINE;
}
@@ -270,7 +270,7 @@ int dumpconfig(struct cmd_context *cmd, int argc, char **argv)
}
}
else if (!strcmp(type, "new")) {
- tree_spec.type = arg_count(cmd, sinceversion_ARG) ? CFG_DEF_TREE_NEW_SINCE
+ tree_spec.type = arg_is_set(cmd, sinceversion_ARG) ? CFG_DEF_TREE_NEW_SINCE
: CFG_DEF_TREE_NEW;
/* new type does not require check status */
}
@@ -294,17 +294,17 @@ int dumpconfig(struct cmd_context *cmd, int argc, char **argv)
goto out;
}
- if (arg_count(cmd, withsummary_ARG) || arg_count(cmd, list_ARG))
+ if (arg_is_set(cmd, withsummary_ARG) || arg_is_set(cmd, list_ARG))
tree_spec.withsummary = 1;
- if (arg_count(cmd, withcomments_ARG))
+ if (arg_is_set(cmd, withcomments_ARG))
tree_spec.withcomments = 1;
- if (arg_count(cmd, unconfigured_ARG))
+ if (arg_is_set(cmd, unconfigured_ARG))
tree_spec.unconfigured = 1;
- if (arg_count(cmd, withversions_ARG))
+ if (arg_is_set(cmd, withversions_ARG))
tree_spec.withversions = 1;
- if (arg_count(cmd, withspaces_ARG))
+ if (arg_is_set(cmd, withspaces_ARG))
tree_spec.withspaces = 1;
if (cft_check_handle)
diff --git a/tools/lvchange.c b/tools/lvchange.c
index 16ede56..b9944f7 100644
--- a/tools/lvchange.c
+++ b/tools/lvchange.c
@@ -108,7 +108,7 @@ static int _lvchange_pool_update(struct cmd_context *cmd,
return 0;
}
- if (arg_count(cmd, discards_ARG)) {
+ if (arg_is_set(cmd, discards_ARG)) {
discards = (thin_discards_t) arg_uint_value(cmd, discards_ARG, THIN_DISCARDS_IGNORE);
if (discards != first_seg(lv)->discards) {
if (((discards == THIN_DISCARDS_IGNORE) ||
@@ -124,7 +124,7 @@ static int _lvchange_pool_update(struct cmd_context *cmd,
lv->name, get_pool_discards_name(discards));
}
- if (arg_count(cmd, zero_ARG)) {
+ if (arg_is_set(cmd, zero_ARG)) {
val = arg_uint_value(cmd, zero_ARG, 1);
if (val != first_seg(lv)->zero_new_blocks) {
first_seg(lv)->zero_new_blocks = val;
@@ -200,7 +200,7 @@ static int _lvchange_activate(struct cmd_context *cmd, struct logical_volume *lv
return ECMD_FAILED;
}
- if (lv_activation_skip(lv, activate, arg_count(cmd, ignoreactivationskip_ARG)))
+ if (lv_activation_skip(lv, activate, arg_is_set(cmd, ignoreactivationskip_ARG)))
return 1;
if (lv_is_cow(lv) && !lv_is_virtual_origin(origin_from_cow(lv)))
@@ -350,7 +350,7 @@ static int _lvchange_resync(struct cmd_context *cmd, struct logical_volume *lv)
return 0;
}
- if (!arg_count(cmd, yes_ARG) &&
+ if (!arg_is_set(cmd, yes_ARG) &&
yes_no_prompt("Do you really want to deactivate "
"logical volume %s to resync it? [y/n]: ",
lv->name) == 'n') {
@@ -625,8 +625,8 @@ static int _lvchange_persistent(struct cmd_context *cmd,
display_lvname(lv));
} else {
if (lv_is_active(lv)) {
- if (!arg_count(cmd, force_ARG) &&
- !arg_count(cmd, yes_ARG) &&
+ if (!arg_is_set(cmd, force_ARG) &&
+ !arg_is_set(cmd, yes_ARG) &&
yes_no_prompt("Logical volume %s will be "
"deactivated temporarily. "
"Continue? [y/n]: ", lv->name) == 'n') {
@@ -760,11 +760,11 @@ static int _lvchange_writemostly(struct logical_volume *lv)
if (!seg_is_raid1(raid_seg)) {
log_error("--write%s can only be used with 'raid1' segment type",
- arg_count(cmd, writemostly_ARG) ? "mostly" : "behind");
+ arg_is_set(cmd, writemostly_ARG) ? "mostly" : "behind");
return 0;
}
- if (arg_count(cmd, writebehind_ARG))
+ if (arg_is_set(cmd, writebehind_ARG))
raid_seg->writebehind = arg_uint_value(cmd, writebehind_ARG, 0);
if ((pv_count = arg_count(cmd, writemostly_ARG))) {
@@ -858,10 +858,10 @@ static int _lvchange_recovery_rate(struct logical_volume *lv)
return 0;
}
- if (arg_count(cmd, minrecoveryrate_ARG))
+ if (arg_is_set(cmd, minrecoveryrate_ARG))
raid_seg->min_recovery_rate =
arg_uint_value(cmd, minrecoveryrate_ARG, 0) / 2;
- if (arg_count(cmd, maxrecoveryrate_ARG))
+ if (arg_is_set(cmd, maxrecoveryrate_ARG))
raid_seg->max_recovery_rate =
arg_uint_value(cmd, maxrecoveryrate_ARG, 0) / 2;
@@ -885,11 +885,11 @@ static int _lvchange_profile(struct logical_volume *lv)
old_profile_name = lv->profile ? lv->profile->name : "(inherited)";
- if (arg_count(lv->vg->cmd, detachprofile_ARG)) {
+ if (arg_is_set(lv->vg->cmd, detachprofile_ARG)) {
new_profile_name = "(inherited)";
lv->profile = NULL;
} else {
- if (arg_count(lv->vg->cmd, metadataprofile_ARG))
+ if (arg_is_set(lv->vg->cmd, metadataprofile_ARG))
new_profile_name = arg_str_value(lv->vg->cmd, metadataprofile_ARG, NULL);
else
new_profile_name = arg_str_value(lv->vg->cmd, profile_ARG, NULL);
@@ -971,7 +971,7 @@ static int _lvchange_single(struct cmd_context *cmd, struct logical_volume *lv,
if (lv_is_pvmove(lv)) {
log_error("Unable to change pvmove LV %s", lv->name);
- if (arg_count(cmd, activate_ARG))
+ if (arg_is_set(cmd, activate_ARG))
log_error("Use 'pvmove --abort' to abandon a pvmove");
return ECMD_FAILED;
}
@@ -988,15 +988,15 @@ static int _lvchange_single(struct cmd_context *cmd, struct logical_volume *lv,
}
/* If LV is sparse, activate origin instead */
- if (arg_count(cmd, activate_ARG) && lv_is_cow(lv) &&
+ if (arg_is_set(cmd, activate_ARG) && lv_is_cow(lv) &&
lv_is_virtual_origin(origin = origin_from_cow(lv)))
lv = origin;
if ((lv_is_thin_pool_data(lv) || lv_is_thin_pool_metadata(lv) ||
lv_is_cache_pool_data(lv) || lv_is_cache_pool_metadata(lv)) &&
- !arg_count(cmd, activate_ARG) &&
- !arg_count(cmd, permission_ARG) &&
- !arg_count(cmd, setactivationskip_ARG))
+ !arg_is_set(cmd, activate_ARG) &&
+ !arg_is_set(cmd, permission_ARG) &&
+ !arg_is_set(cmd, setactivationskip_ARG))
/* Rest can be changed for stacked thin pool meta/data volumes */
;
else if (!lv_is_visible(lv) && !lv_is_virtual_origin(lv)) {
@@ -1005,7 +1005,7 @@ static int _lvchange_single(struct cmd_context *cmd, struct logical_volume *lv,
return ECMD_FAILED;
}
- if (lv_is_cow(lv) && arg_count(cmd, activate_ARG)) {
+ if (lv_is_cow(lv) && arg_is_set(cmd, activate_ARG)) {
origin = origin_from_cow(lv);
if (origin->origin_count < 2)
snaps_msg[0] = '\0';
@@ -1016,7 +1016,7 @@ static int _lvchange_single(struct cmd_context *cmd, struct logical_volume *lv,
return ECMD_FAILED;
}
- if (!arg_count(cmd, yes_ARG) &&
+ if (!arg_is_set(cmd, yes_ARG) &&
(yes_no_prompt("Change of snapshot %s will also change its "
"origin %s%s. Proceed? [y/n]: ",
display_lvname(lv), display_lvname(origin),
@@ -1031,12 +1031,12 @@ static int _lvchange_single(struct cmd_context *cmd, struct logical_volume *lv,
return ECMD_FAILED;
}
- if (arg_count(cmd, persistent_ARG) && lv_is_pool(lv)) {
+ if (arg_is_set(cmd, persistent_ARG) && lv_is_pool(lv)) {
log_error("Persistent major and minor numbers are not supported with pools.");
return ECMD_FAILED;
}
- if (!arg_count(cmd, activate_ARG) && !arg_count(cmd, refresh_ARG)) {
+ if (!arg_is_set(cmd, activate_ARG) && !arg_is_set(cmd, refresh_ARG)) {
/*
* If a persistent lv lock already exists from activation
* (with the needed mode or higher), this will be a no-op.
@@ -1061,12 +1061,12 @@ static int _lvchange_single(struct cmd_context *cmd, struct logical_volume *lv,
*
* Do not initiate any polling if --sysinit option is used.
*/
- init_background_polling(arg_count(cmd, sysinit_ARG) ? 0 :
+ init_background_polling(arg_is_set(cmd, sysinit_ARG) ? 0 :
arg_int_value(cmd, poll_ARG,
DEFAULT_BACKGROUND_POLLING));
/* access permission change */
- if (arg_count(cmd, permission_ARG)) {
+ if (arg_is_set(cmd, permission_ARG)) {
if (!archive(lv->vg))
return_ECMD_FAILED;
doit += _lvchange_permission(cmd, lv);
@@ -1074,7 +1074,7 @@ static int _lvchange_single(struct cmd_context *cmd, struct logical_volume *lv,
}
/* allocation policy change */
- if (arg_count(cmd, contiguous_ARG) || arg_count(cmd, alloc_ARG)) {
+ if (arg_is_set(cmd, contiguous_ARG) || arg_is_set(cmd, alloc_ARG)) {
if (!archive(lv->vg))
return_ECMD_FAILED;
doit += _lvchange_alloc(cmd, lv);
@@ -1082,7 +1082,7 @@ static int _lvchange_single(struct cmd_context *cmd, struct logical_volume *lv,
}
/* error when full change */
- if (arg_count(cmd, errorwhenfull_ARG)) {
+ if (arg_is_set(cmd, errorwhenfull_ARG)) {
if (!archive(lv->vg))
return_ECMD_FAILED;
doit += _lvchange_errorwhenfull(cmd, lv);
@@ -1090,7 +1090,7 @@ static int _lvchange_single(struct cmd_context *cmd, struct logical_volume *lv,
}
/* read ahead sector change */
- if (arg_count(cmd, readahead_ARG)) {
+ if (arg_is_set(cmd, readahead_ARG)) {
if (!archive(lv->vg))
return_ECMD_FAILED;
doit += _lvchange_readahead(cmd, lv);
@@ -1098,15 +1098,15 @@ static int _lvchange_single(struct cmd_context *cmd, struct logical_volume *lv,
}
/* persistent device number change */
- if (arg_count(cmd, persistent_ARG)) {
+ if (arg_is_set(cmd, persistent_ARG)) {
if (!archive(lv->vg))
return_ECMD_FAILED;
doit += _lvchange_persistent(cmd, lv);
docmds++;
}
- if (arg_count(cmd, discards_ARG) ||
- arg_count(cmd, zero_ARG)) {
+ if (arg_is_set(cmd, discards_ARG) ||
+ arg_is_set(cmd, zero_ARG)) {
if (!archive(lv->vg))
return_ECMD_FAILED;
doit += _lvchange_pool_update(cmd, lv);
@@ -1114,7 +1114,7 @@ static int _lvchange_single(struct cmd_context *cmd, struct logical_volume *lv,
}
/* add tag */
- if (arg_count(cmd, addtag_ARG)) {
+ if (arg_is_set(cmd, addtag_ARG)) {
if (!archive(lv->vg))
return_ECMD_FAILED;
doit += _lvchange_tag(cmd, lv, addtag_ARG);
@@ -1122,7 +1122,7 @@ static int _lvchange_single(struct cmd_context *cmd, struct logical_volume *lv,
}
/* del tag */
- if (arg_count(cmd, deltag_ARG)) {
+ if (arg_is_set(cmd, deltag_ARG)) {
if (!archive(lv->vg))
return_ECMD_FAILED;
doit += _lvchange_tag(cmd, lv, deltag_ARG);
@@ -1130,7 +1130,7 @@ static int _lvchange_single(struct cmd_context *cmd, struct logical_volume *lv,
}
/* change writemostly/writebehind */
- if (arg_count(cmd, writemostly_ARG) || arg_count(cmd, writebehind_ARG)) {
+ if (arg_is_set(cmd, writemostly_ARG) || arg_is_set(cmd, writebehind_ARG)) {
if (!archive(lv->vg))
return_ECMD_FAILED;
doit += _lvchange_writemostly(lv);
@@ -1138,8 +1138,8 @@ static int _lvchange_single(struct cmd_context *cmd, struct logical_volume *lv,
}
/* change [min|max]_recovery_rate */
- if (arg_count(cmd, minrecoveryrate_ARG) ||
- arg_count(cmd, maxrecoveryrate_ARG)) {
+ if (arg_is_set(cmd, minrecoveryrate_ARG) ||
+ arg_is_set(cmd, maxrecoveryrate_ARG)) {
if (!archive(lv->vg))
return_ECMD_FAILED;
doit += _lvchange_recovery_rate(lv);
@@ -1147,15 +1147,15 @@ static int _lvchange_single(struct cmd_context *cmd, struct logical_volume *lv,
}
/* change configuration profile */
- if (arg_count(cmd, profile_ARG) || arg_count(cmd, metadataprofile_ARG) ||
- arg_count(cmd, detachprofile_ARG)) {
+ if (arg_is_set(cmd, profile_ARG) || arg_is_set(cmd, metadataprofile_ARG) ||
+ arg_is_set(cmd, detachprofile_ARG)) {
if (!archive(lv->vg))
return_ECMD_FAILED;
doit += _lvchange_profile(lv);
docmds++;
}
- if (arg_count(cmd, setactivationskip_ARG)) {
+ if (arg_is_set(cmd, setactivationskip_ARG)) {
if (!archive(lv->vg))
return_ECMD_FAILED;
doit += _lvchange_activation_skip(lv);
@@ -1163,7 +1163,7 @@ static int _lvchange_single(struct cmd_context *cmd, struct logical_volume *lv,
}
if (arg_is_set(cmd, cachemode_ARG) ||
- arg_count(cmd, cachepolicy_ARG) || arg_count(cmd, cachesettings_ARG)) {
+ arg_is_set(cmd, cachepolicy_ARG) || arg_is_set(cmd, cachesettings_ARG)) {
if (!archive(lv->vg))
return_ECMD_FAILED;
doit += _lvchange_cache(cmd, lv);
@@ -1173,27 +1173,27 @@ static int _lvchange_single(struct cmd_context *cmd, struct logical_volume *lv,
if (doit)
log_print_unless_silent("Logical volume %s changed.", display_lvname(lv));
- if (arg_count(cmd, resync_ARG) &&
+ if (arg_is_set(cmd, resync_ARG) &&
!_lvchange_resync(cmd, lv))
return_ECMD_FAILED;
- if (arg_count(cmd, syncaction_ARG) &&
+ if (arg_is_set(cmd, syncaction_ARG) &&
!lv_raid_message(lv, arg_str_value(cmd, syncaction_ARG, NULL)))
return_ECMD_FAILED;
/* activation change */
- if (arg_count(cmd, activate_ARG)) {
+ if (arg_is_set(cmd, activate_ARG)) {
if (!_lvchange_activate(cmd, lv))
return_ECMD_FAILED;
- } else if (arg_count(cmd, refresh_ARG)) {
+ } else if (arg_is_set(cmd, refresh_ARG)) {
if (!_lvchange_refresh(cmd, lv))
return_ECMD_FAILED;
} else {
- if (arg_count(cmd, monitor_ARG) &&
+ if (arg_is_set(cmd, monitor_ARG) &&
!_lvchange_monitoring(cmd, lv))
return_ECMD_FAILED;
- if (arg_count(cmd, poll_ARG) &&
+ if (arg_is_set(cmd, poll_ARG) &&
!_lvchange_background_polling(cmd, lv))
return_ECMD_FAILED;
}
@@ -1243,27 +1243,27 @@ int lvchange(struct cmd_context *cmd, int argc, char **argv)
int update = update_partial_safe || update_partial_unsafe;
if (!update &&
- !arg_count(cmd, activate_ARG) && !arg_count(cmd, refresh_ARG) &&
- !arg_count(cmd, monitor_ARG) && !arg_count(cmd, poll_ARG)) {
+ !arg_is_set(cmd, activate_ARG) && !arg_is_set(cmd, refresh_ARG) &&
+ !arg_is_set(cmd, monitor_ARG) && !arg_is_set(cmd, poll_ARG)) {
log_error("Need 1 or more of -a, -C, -M, -p, -r, -Z, "
"--resync, --refresh, --alloc, --addtag, --deltag, "
"--monitor, --poll or --discards");
return EINVALID_CMD_LINE;
}
- if ((arg_count(cmd, profile_ARG) || arg_count(cmd, metadataprofile_ARG)) &&
- arg_count(cmd, detachprofile_ARG)) {
+ if ((arg_is_set(cmd, profile_ARG) || arg_is_set(cmd, metadataprofile_ARG)) &&
+ arg_is_set(cmd, detachprofile_ARG)) {
log_error("Only one of --metadataprofile and --detachprofile permitted.");
return EINVALID_CMD_LINE;
}
- if (arg_count(cmd, activate_ARG) && arg_count(cmd, refresh_ARG)) {
+ if (arg_is_set(cmd, activate_ARG) && arg_is_set(cmd, refresh_ARG)) {
log_error("Only one of -a and --refresh permitted.");
return EINVALID_CMD_LINE;
}
- if ((arg_count(cmd, ignorelockingfailure_ARG) ||
- arg_count(cmd, sysinit_ARG)) && update) {
+ if ((arg_is_set(cmd, ignorelockingfailure_ARG) ||
+ arg_is_set(cmd, sysinit_ARG)) && update) {
log_error("Only -a permitted with --ignorelockingfailure and --sysinit");
return EINVALID_CMD_LINE;
}
@@ -1276,23 +1276,23 @@ int lvchange(struct cmd_context *cmd, int argc, char **argv)
return EINVALID_CMD_LINE;
}
- if ((arg_count(cmd, minor_ARG) || arg_count(cmd, major_ARG)) &&
- !arg_count(cmd, persistent_ARG)) {
+ if ((arg_is_set(cmd, minor_ARG) || arg_is_set(cmd, major_ARG)) &&
+ !arg_is_set(cmd, persistent_ARG)) {
log_error("--major and --minor require -My");
return EINVALID_CMD_LINE;
}
- if (arg_count(cmd, minor_ARG) && argc != 1) {
+ if (arg_is_set(cmd, minor_ARG) && argc != 1) {
log_error("Only give one logical volume when specifying minor");
return EINVALID_CMD_LINE;
}
- if (arg_count(cmd, contiguous_ARG) && arg_count(cmd, alloc_ARG)) {
+ if (arg_is_set(cmd, contiguous_ARG) && arg_is_set(cmd, alloc_ARG)) {
log_error("Only one of --alloc and --contiguous permitted");
return EINVALID_CMD_LINE;
}
- if (arg_count(cmd, poll_ARG) && arg_count(cmd, sysinit_ARG)) {
+ if (arg_is_set(cmd, poll_ARG) && arg_is_set(cmd, sysinit_ARG)) {
log_error("Only one of --poll and --sysinit permitted");
return EINVALID_CMD_LINE;
}
@@ -1304,7 +1304,7 @@ int lvchange(struct cmd_context *cmd, int argc, char **argv)
* not neet to be running at this moment yet - it could be
* just too early during system initialization time.
*/
- if (arg_count(cmd, sysinit_ARG) && (arg_uint_value(cmd, activate_ARG, 0) == CHANGE_AAY)) {
+ if (arg_is_set(cmd, sysinit_ARG) && (arg_uint_value(cmd, activate_ARG, 0) == CHANGE_AAY)) {
if (lvmetad_used()) {
log_warn("WARNING: lvmetad is active, skipping direct activation during sysinit");
return ECMD_PROCESSED;
@@ -1324,7 +1324,7 @@ int lvchange(struct cmd_context *cmd, int argc, char **argv)
* are cases where lvchange does not modify the vg, so they can use
* the sh lock mode.
*/
- if (arg_count(cmd, activate_ARG) || arg_count(cmd, refresh_ARG)) {
+ if (arg_is_set(cmd, activate_ARG) || arg_is_set(cmd, refresh_ARG)) {
cmd->lockd_vg_default_sh = 1;
/* Allow deactivating if locks fail. */
if (is_change_activating((activation_change_t)arg_uint_value(cmd, activate_ARG, CHANGE_AY)))
diff --git a/tools/lvconvert.c b/tools/lvconvert.c
index a711c31..ae9b052 100644
--- a/tools/lvconvert.c
+++ b/tools/lvconvert.c
@@ -191,7 +191,7 @@ static int _lvconvert_name_params(struct lvconvert_params *lp,
if (!lp->merge_mirror &&
!lp->repair &&
- !arg_count(cmd, splitmirrors_ARG) &&
+ !arg_is_set(cmd, splitmirrors_ARG) &&
!strstr(lp->lv_name, "_tdata") &&
!strstr(lp->lv_name, "_tmeta") &&
!strstr(lp->lv_name, "_cdata") &&
@@ -238,7 +238,7 @@ static int _check_conversion_type(struct cmd_context *cmd, const char *type_str)
return 1;
if (!strcmp(type_str, "mirror")) {
- if (!arg_count(cmd, mirrors_ARG)) {
+ if (!arg_is_set(cmd, mirrors_ARG)) {
log_error("Conversions to --type mirror require -m/--mirrors");
return 0;
}
@@ -258,11 +258,11 @@ static int _check_conversion_type(struct cmd_context *cmd, const char *type_str)
/* -s/--snapshot and --type snapshot are synonyms */
static int _snapshot_type_requested(struct cmd_context *cmd, const char *type_str) {
- return (arg_count(cmd, snapshot_ARG) || !strcmp(type_str, "snapshot"));
+ return (arg_is_set(cmd, snapshot_ARG) || !strcmp(type_str, "snapshot"));
}
/* mirror/raid* (1,10,4,5,6 and their variants) reshape */
static int _mirror_or_raid_type_requested(struct cmd_context *cmd, const char *type_str) {
- return (arg_count(cmd, mirrors_ARG) || !strncmp(type_str, "raid", 4) || !strcmp(type_str, "mirror"));
+ return (arg_is_set(cmd, mirrors_ARG) || !strncmp(type_str, "raid", 4) || !strcmp(type_str, "mirror"));
}
static int _read_pool_params(struct cmd_context *cmd, int *pargc, char ***pargv,
@@ -379,7 +379,7 @@ static int _read_params(struct cmd_context *cmd, int argc, char **argv,
if (!_check_conversion_type(cmd, type_str))
return_0;
- if (arg_count(cmd, repair_ARG)) {
+ if (arg_is_set(cmd, repair_ARG)) {
if (arg_outside_list_is_set(cmd, "cannot be used with --repair",
repair_ARG,
alloc_ARG, usepolicies_ARG,
@@ -432,25 +432,25 @@ static int _read_params(struct cmd_context *cmd, int argc, char **argv,
lp->uncache = 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) ||
- lp->repair || arg_count(cmd, thinpool_ARG))) {
+ if ((_snapshot_type_requested(cmd, type_str) || arg_is_set(cmd, merge_ARG)) &&
+ (arg_is_set(cmd, mirrorlog_ARG) || _mirror_or_raid_type_requested(cmd, type_str) ||
+ lp->repair || arg_is_set(cmd, thinpool_ARG))) {
log_error("--snapshot/--type snapshot or --merge argument "
"cannot be mixed with --mirrors/--type mirror/--type raid*, "
"--mirrorlog, --repair or --thinpool.");
return 0;
}
- if ((arg_count(cmd, stripes_long_ARG) || arg_count(cmd, stripesize_ARG)) &&
+ if ((arg_is_set(cmd, stripes_long_ARG) || arg_is_set(cmd, stripesize_ARG)) &&
!(_mirror_or_raid_type_requested(cmd, type_str) ||
lp->repair ||
- arg_count(cmd, thinpool_ARG))) {
+ arg_is_set(cmd, thinpool_ARG))) {
log_error("--stripes or --stripesize argument is only valid "
"with --mirrors/--type mirror/--type raid*, --repair and --thinpool");
return 0;
}
- if (arg_count(cmd, cache_ARG))
+ if (arg_is_set(cmd, cache_ARG))
lp->cache = 1;
if (!strcmp(type_str, "cache"))
@@ -463,7 +463,7 @@ static int _read_params(struct cmd_context *cmd, int argc, char **argv,
type_str = "cache";
}
- if (arg_count(cmd, thin_ARG))
+ if (arg_is_set(cmd, thin_ARG))
lp->thin = 1;
if (!strcmp(type_str, "thin"))
@@ -479,11 +479,11 @@ static int _read_params(struct cmd_context *cmd, int argc, char **argv,
if (!_read_pool_params(cmd, &argc, &argv, type_str, lp))
return_0;
- if (!arg_count(cmd, background_ARG))
+ if (!arg_is_set(cmd, background_ARG))
lp->wait_completion = 1;
if (_snapshot_type_requested(cmd, type_str)) {
- if (arg_count(cmd, merge_ARG)) {
+ if (arg_is_set(cmd, merge_ARG)) {
log_error("--snapshot and --merge are mutually exclusive.");
return 0;
}
@@ -499,14 +499,14 @@ static int _read_params(struct cmd_context *cmd, int argc, char **argv,
* intent to keep the mimage that is detached, rather than
* discarding it.
*/
- } else if (arg_count(cmd, splitmirrors_ARG)) {
+ } else if (arg_is_set(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)) {
+ if (!arg_is_set(cmd, name_ARG) &&
+ !arg_is_set(cmd, trackchanges_ARG)) {
log_error("Please name the new logical volume using '--name'");
return 0;
}
@@ -515,20 +515,20 @@ static int _read_params(struct cmd_context *cmd, int argc, char **argv,
lp->keep_mimages = 1;
lp->mirrors = arg_uint_value(cmd, splitmirrors_ARG, 0);
lp->mirrors_sign = SIGN_MINUS;
- } else if (arg_count(cmd, name_ARG)) {
+ } else if (arg_is_set(cmd, name_ARG)) {
log_error("The 'name' argument is only valid"
" with --splitmirrors");
return 0;
}
- if (arg_count(cmd, merge_ARG)) {
+ if (arg_is_set(cmd, merge_ARG)) {
if ((argc == 1) && strstr(argv[0], "_rimage_"))
lp->merge_mirror = 1;
else
lp->merge = 1;
}
- if (arg_count(cmd, mirrors_ARG)) {
+ if (arg_is_set(cmd, mirrors_ARG)) {
/*
* --splitmirrors has been chosen as the mechanism for
* specifying the intent of detaching and keeping a mimage
@@ -561,17 +561,17 @@ static int _read_params(struct cmd_context *cmd, int argc, char **argv,
lp->origin_name = argv[0];
argv++, argc--;
- if (arg_count(cmd, regionsize_ARG)) {
+ if (arg_is_set(cmd, regionsize_ARG)) {
log_error("--regionsize is only available with mirrors");
return 0;
}
- if (arg_count(cmd, stripesize_ARG) || arg_count(cmd, stripes_long_ARG)) {
+ if (arg_is_set(cmd, stripesize_ARG) || arg_is_set(cmd, stripes_long_ARG)) {
log_error("--stripes and --stripesize are only available with striped mirrors");
return 0;
}
- if (arg_count(cmd, chunksize_ARG) &&
+ if (arg_is_set(cmd, chunksize_ARG) &&
(arg_sign_value(cmd, chunksize_ARG, SIGN_NONE) == SIGN_MINUS)) {
log_error("Negative chunk size is invalid.");
return 0;
@@ -592,7 +592,7 @@ static int _read_params(struct cmd_context *cmd, int argc, char **argv,
lp->zero = (lp->segtype->flags & SEG_CANNOT_BE_ZEROED)
? 0 : arg_int_value(cmd, zero_ARG, 1);
- } else if (arg_count(cmd, replace_ARG)) { /* RAID device replacement */
+ } else if (arg_is_set(cmd, replace_ARG)) { /* RAID device replacement */
lp->replace_pv_count = arg_count(cmd, replace_ARG);
lp->replace_pvs = dm_pool_alloc(cmd->mem, sizeof(char *) * lp->replace_pv_count);
if (!lp->replace_pvs)
@@ -616,12 +616,12 @@ static int _read_params(struct cmd_context *cmd, int argc, char **argv,
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)) {
+ if (arg_is_set(cmd, chunksize_ARG)) {
log_error("--chunksize is only available with snapshots or pools.");
return 0;
}
- if (arg_count(cmd, zero_ARG)) {
+ if (arg_is_set(cmd, zero_ARG)) {
log_error("--zero is only available with snapshots or thin pools.");
return 0;
}
@@ -631,7 +631,7 @@ static int _read_params(struct cmd_context *cmd, int argc, char **argv,
* Checked when we know the state of the LV being converted.
*/
- if (arg_count(cmd, regionsize_ARG)) {
+ if (arg_is_set(cmd, regionsize_ARG)) {
if (arg_sign_value(cmd, regionsize_ARG, SIGN_NONE) ==
SIGN_MINUS) {
log_error("Negative regionsize is invalid");
@@ -671,12 +671,12 @@ static int _read_params(struct cmd_context *cmd, int argc, char **argv,
if (!get_stripe_params(cmd, &lp->stripes, &lp->stripe_size))
return_0;
- if (arg_count(cmd, mirrors_ARG) && !lp->mirrors) {
+ if (arg_is_set(cmd, mirrors_ARG) && !lp->mirrors) {
/* down-converting to linear/stripe? */
if (!(lp->segtype =
get_segtype_from_string(cmd, SEG_TYPE_NAME_STRIPED)))
return_0;
- } else if (arg_count(cmd, type_ARG)) {
+ } else if (arg_is_set(cmd, type_ARG)) {
/* changing mirror type? */
if (!(lp->segtype = get_segtype_from_string(cmd, arg_str_value(cmd, type_ARG, find_config_tree_str(cmd, global_mirror_segtype_default_CFG, NULL)))))
return_0;
@@ -945,7 +945,7 @@ static void _lvconvert_mirrors_repair_ask(struct cmd_context *cmd,
int force = arg_count(cmd, force_ARG);
int yes = arg_count(cmd, yes_ARG);
- if (arg_count(cmd, usepolicies_ARG)) {
+ if (arg_is_set(cmd, usepolicies_ARG)) {
leg_policy = find_config_tree_str(cmd, activation_mirror_image_fault_policy_CFG, NULL);
log_policy = find_config_tree_str(cmd, activation_mirror_log_fault_policy_CFG, NULL);
*replace_mirrors = strcmp(leg_policy, "remove");
@@ -1139,7 +1139,7 @@ static int _lvconvert_mirrors_parse_params(struct cmd_context *cmd,
*old_mimage_count = lv_mirror_count(lv);
*old_log_count = _get_log_count(lv);
- if (is_lockd_type(lv->vg->lock_type) && arg_count(cmd, splitmirrors_ARG)) {
+ if (is_lockd_type(lv->vg->lock_type) && arg_is_set(cmd, splitmirrors_ARG)) {
/* FIXME: we need to create a lock for the new LV. */
log_error("Unable to split mirrors in VG with lock_type %s", lv->vg->lock_type);
return 0;
@@ -1150,9 +1150,9 @@ static int _lvconvert_mirrors_parse_params(struct cmd_context *cmd,
*
* If called with no argument, try collapsing the resync layers
*/
- if (!arg_count(cmd, mirrors_ARG) && !arg_count(cmd, mirrorlog_ARG) &&
- !arg_count(cmd, corelog_ARG) && !arg_count(cmd, regionsize_ARG) &&
- !arg_count(cmd, splitmirrors_ARG) && !lp->repair) {
+ if (!arg_is_set(cmd, mirrors_ARG) && !arg_is_set(cmd, mirrorlog_ARG) &&
+ !arg_is_set(cmd, corelog_ARG) && !arg_is_set(cmd, regionsize_ARG) &&
+ !arg_is_set(cmd, splitmirrors_ARG) && !lp->repair) {
*new_mimage_count = *old_mimage_count;
*new_log_count = *old_log_count;
@@ -1164,7 +1164,7 @@ static int _lvconvert_mirrors_parse_params(struct cmd_context *cmd,
/*
* Adjusting mimage count?
*/
- if (!arg_count(cmd, mirrors_ARG) && !arg_count(cmd, splitmirrors_ARG))
+ if (!arg_is_set(cmd, mirrors_ARG) && !arg_is_set(cmd, splitmirrors_ARG))
lp->mirrors = *old_mimage_count;
else if (lp->mirrors_sign == SIGN_PLUS)
lp->mirrors = *old_mimage_count + lp->mirrors;
@@ -1207,7 +1207,7 @@ static int _lvconvert_mirrors_parse_params(struct cmd_context *cmd,
* position that the user would like a 'disk' log.
*/
*new_log_count = (*old_mimage_count > 1) ? *old_log_count : 1;
- if (!arg_count(cmd, corelog_ARG) && !arg_count(cmd, mirrorlog_ARG))
+ if (!arg_is_set(cmd, corelog_ARG) && !arg_is_set(cmd, mirrorlog_ARG))
return 1;
*new_log_count = arg_int_value(cmd, mirrorlog_ARG,
@@ -1227,7 +1227,7 @@ static int _lvconvert_mirrors_parse_params(struct cmd_context *cmd,
/*
* Region size must not change on existing mirrors
*/
- if (arg_count(cmd, regionsize_ARG) && lv_is_mirrored(lv) &&
+ if (arg_is_set(cmd, regionsize_ARG) && lv_is_mirrored(lv) &&
(lp->region_size != first_seg(lv)->region_size)) {
log_error("Mirror log region size cannot be changed on "
"an existing mirror.");
@@ -1395,7 +1395,7 @@ static int _lvconvert_mirrors_aux(struct cmd_context *cmd,
/* Reduce number of mirrors */
if (lp->keep_mimages) {
- if (arg_count(cmd, trackchanges_ARG)) {
+ if (arg_is_set(cmd, trackchanges_ARG)) {
log_error("--trackchanges is not available "
"to 'mirror' segment type");
return 0;
@@ -1559,7 +1559,7 @@ static int _lvconvert_mirrors_repair(struct cmd_context *cmd,
original_logs - _get_log_count(lv), original_logs,
display_lvname(lv));
- /* if (!arg_count(cmd, use_policies_ARG) && (lp->mirrors != old_mimage_count
+ /* if (!arg_is_set(cmd, use_policies_ARG) && (lp->mirrors != old_mimage_count
|| log_count != old_log_count))
return 0; */
@@ -1679,7 +1679,7 @@ static void _lvconvert_raid_repair_ask(struct cmd_context *cmd,
*replace_dev = 1;
- if (arg_count(cmd, usepolicies_ARG)) {
+ if (arg_is_set(cmd, usepolicies_ARG)) {
dev_policy = find_config_tree_str(cmd, activation_raid_fault_policy_CFG, NULL);
if (!strcmp(dev_policy, "allocate") ||
@@ -1706,11 +1706,11 @@ static int _lvconvert_raid(struct logical_volume *lv, struct lvconvert_params *l
struct lv_segment *seg = first_seg(lv);
dm_percent_t sync_percent;
- if (!arg_count(cmd, type_ARG))
+ if (!arg_is_set(cmd, type_ARG))
lp->segtype = seg->segtype;
/* Can only change image count for raid1 and linear */
- if (arg_count(cmd, mirrors_ARG) &&
+ if (arg_is_set(cmd, mirrors_ARG) &&
!seg_is_mirrored(seg) && !seg_is_linear(seg)) {
log_error("'--mirrors/-m' is not compatible with %s",
lvseg_name(seg));
@@ -1727,13 +1727,13 @@ static int _lvconvert_raid(struct logical_volume *lv, struct lvconvert_params *l
return 0;
}
- if (seg_is_linear(seg) && !lp->merge_mirror && !arg_count(cmd, mirrors_ARG)) {
+ if (seg_is_linear(seg) && !lp->merge_mirror && !arg_is_set(cmd, mirrors_ARG)) {
log_error("Raid conversions require -m/--mirrors");
return 0;
}
/* Change number of RAID1 images */
- if (arg_count(cmd, mirrors_ARG) || arg_count(cmd, splitmirrors_ARG)) {
+ if (arg_is_set(cmd, mirrors_ARG) || arg_is_set(cmd, splitmirrors_ARG)) {
image_count = lv_raid_image_count(lv);
if (lp->mirrors_sign == SIGN_PLUS)
image_count += lp->mirrors;
@@ -1744,7 +1744,7 @@ static int _lvconvert_raid(struct logical_volume *lv, struct lvconvert_params *l
if (image_count < 1) {
log_error("Unable to %s images by specified amount",
- arg_count(cmd, splitmirrors_ARG) ?
+ arg_is_set(cmd, splitmirrors_ARG) ?
"split" : "reduce");
return 0;
}
@@ -1753,20 +1753,20 @@ static int _lvconvert_raid(struct logical_volume *lv, struct lvconvert_params *l
if (lp->merge_mirror)
return lv_raid_merge(lv);
- if (arg_count(cmd, trackchanges_ARG))
+ if (arg_is_set(cmd, trackchanges_ARG))
return lv_raid_split_and_track(lv, lp->pvh);
- if (arg_count(cmd, splitmirrors_ARG))
+ if (arg_is_set(cmd, splitmirrors_ARG))
return lv_raid_split(lv, lp->lv_split_name,
image_count, lp->pvh);
- if (arg_count(cmd, mirrors_ARG))
+ if (arg_is_set(cmd, mirrors_ARG))
return lv_raid_change_image_count(lv, image_count, lp->pvh);
- if (arg_count(cmd, type_ARG))
+ if (arg_is_set(cmd, type_ARG))
return lv_raid_reshape(lv, lp->segtype);
- if (arg_count(cmd, replace_ARG))
+ if (arg_is_set(cmd, replace_ARG))
return lv_raid_replace(lv, lp->replace_pvh, lp->pvh);
if (lp->repair) {
@@ -1815,7 +1815,7 @@ static int _lvconvert_raid(struct logical_volume *lv, struct lvconvert_params *l
}
/* "warn" if policy not set to replace */
- if (arg_count(cmd, usepolicies_ARG))
+ if (arg_is_set(cmd, usepolicies_ARG))
log_warn("Use 'lvconvert --repair %s/%s' to replace "
"failed device.", lv->vg->name, lv->name);
return 1;
@@ -2905,7 +2905,7 @@ static int _lvconvert_pool(struct cmd_context *cmd,
seg = first_seg(pool_lv);
/* Normally do NOT change chunk size when swapping */
- if (arg_count(cmd, chunksize_ARG) &&
+ if (arg_is_set(cmd, chunksize_ARG) &&
(lp->chunk_size != seg->chunk_size) &&
!dm_list_empty(&pool_lv->segs_using_this_lv)) {
if (lp->force == PROMPT) {
@@ -2934,9 +2934,9 @@ static int _lvconvert_pool(struct cmd_context *cmd,
if (metadata_lv->le_count < lp->pool_metadata_extents)
log_print_unless_silent("Continuing with swap...");
- if (!arg_count(cmd, discards_ARG))
+ if (!arg_is_set(cmd, discards_ARG))
lp->discards = seg->discards;
- if (!arg_count(cmd, zero_ARG))
+ if (!arg_is_set(cmd, zero_ARG))
lp->zero = seg->zero_new_blocks;
if (!lp->yes &&
@@ -3321,7 +3321,7 @@ static int _lvconvert(struct cmd_context *cmd, struct logical_volume *lv,
return ECMD_PROCESSED;
}
if (!lv_is_mirrored(lv) && !lv_is_raid(lv)) {
- if (arg_count(cmd, usepolicies_ARG))
+ if (arg_is_set(cmd, usepolicies_ARG))
return ECMD_PROCESSED; /* nothing to be done here */
log_error("Cannot repair logical volume %s of segtype %s.",
display_lvname(lv), lvseg_name(first_seg(lv)));
@@ -3331,7 +3331,7 @@ static int _lvconvert(struct cmd_context *cmd, struct logical_volume *lv,
/* forward splitmirror operations to the cache origin, which may be raid
* or old-style mirror */
- if (arg_count(cmd, splitmirrors_ARG) && lv_is_cache_type(lv)
+ if (arg_is_set(cmd, splitmirrors_ARG) && lv_is_cache_type(lv)
&& (origin = seg_lv(first_seg(lv), 0)) && lv_is_cache_origin(origin)) {
log_warn("WARNING: Selected operation does not work with cache-type LVs.");
log_warn("WARNING: Proceeding using the cache origin volume %s instead.",
@@ -3348,7 +3348,7 @@ static int _lvconvert(struct cmd_context *cmd, struct logical_volume *lv,
* the segtype was not specified, then we need
* to consult the default.
*/
- if (arg_count(cmd, mirrors_ARG) && !lv_is_mirrored(lv)) {
+ if (arg_is_set(cmd, mirrors_ARG) && !lv_is_mirrored(lv)) {
if (!(lp->segtype = get_segtype_from_string(cmd, find_config_tree_str(cmd, global_mirror_segtype_default_CFG, NULL))))
return_ECMD_FAILED;
}
@@ -3382,10 +3382,10 @@ static int _lvconvert(struct cmd_context *cmd, struct logical_volume *lv,
return_ECMD_FAILED;
/* If repairing and using policies, remove missing PVs from VG */
- if (lp->repair && arg_count(cmd, usepolicies_ARG))
+ if (lp->repair && arg_is_set(cmd, usepolicies_ARG))
_remove_missing_empty_pv(lv->vg, failed_pvs);
- } else if (arg_count(cmd, mirrors_ARG) ||
- arg_count(cmd, splitmirrors_ARG) ||
+ } else if (arg_is_set(cmd, mirrors_ARG) ||
+ arg_is_set(cmd, splitmirrors_ARG) ||
lv_is_mirrored(lv)) {
if (!archive(lv->vg))
return_ECMD_FAILED;
@@ -3397,7 +3397,7 @@ static int _lvconvert(struct cmd_context *cmd, struct logical_volume *lv,
return_ECMD_FAILED;
/* If repairing and using policies, remove missing PVs from VG */
- if (lp->repair && arg_count(cmd, usepolicies_ARG))
+ if (lp->repair && arg_is_set(cmd, usepolicies_ARG))
_remove_missing_empty_pv(lv->vg, failed_pvs);
}
diff --git a/tools/lvcreate.c b/tools/lvcreate.c
index 88518d2..6b99717 100644
--- a/tools/lvcreate.c
+++ b/tools/lvcreate.c
@@ -131,7 +131,7 @@ static int _lvcreate_name_params(struct cmd_context *cmd,
"in one command is not yet supported.");
return 0;
}
- } else if (lp->snapshot && !arg_count(cmd, virtualsize_ARG)) {
+ } else if (lp->snapshot && !arg_is_set(cmd, virtualsize_ARG)) {
/* argv[0] might be [vg/]origin */
if (!argc) {
log_error("Please specify a logical volume to act as "
@@ -414,14 +414,14 @@ static int _read_size_params(struct cmd_context *cmd,
lcp->virtual_size = arg_uint64_value(cmd, virtualsize_ARG, UINT64_C(0));
- if (arg_count(cmd, extents_ARG)) {
- if (arg_count(cmd, size_ARG)) {
+ if (arg_is_set(cmd, extents_ARG)) {
+ if (arg_is_set(cmd, size_ARG)) {
log_error("Please specify either size or extents (not both).");
return 0;
}
lp->extents = arg_uint_value(cmd, extents_ARG, 0);
lcp->percent = arg_percent_value(cmd, extents_ARG, PERCENT_NONE);
- } else if (arg_count(cmd, size_ARG)) {
+ } else if (arg_is_set(cmd, size_ARG)) {
lcp->size = arg_uint64_value(cmd, size_ARG, UINT64_C(0));
lcp->percent = PERCENT_NONE;
} else if (!lp->snapshot && !seg_is_thin_volume(lp)) {
@@ -459,7 +459,7 @@ static int _read_raid_params(struct cmd_context *cmd,
struct lvcreate_params *lp)
{
if ((lp->stripes < 2) && segtype_is_raid10(lp->segtype)) {
- if (arg_count(cmd, stripes_ARG)) {
+ if (arg_is_set(cmd, stripes_ARG)) {
/* User supplied the bad argument */
log_error("Segment type 'raid10' requires 2 or more stripes.");
return 0;
@@ -479,7 +479,7 @@ static int _read_raid_params(struct cmd_context *cmd,
return 0;
}
- if (arg_count(cmd, mirrors_ARG) && segtype_is_raid(lp->segtype) &&
+ if (arg_is_set(cmd, mirrors_ARG) && segtype_is_raid(lp->segtype) &&
!segtype_is_raid1(lp->segtype) && !segtype_is_raid10(lp->segtype)) {
log_error("Mirror argument cannot be used with segment type, %s",
lp->segtype->name);
@@ -509,7 +509,7 @@ static int _read_mirror_and_raid_params(struct cmd_context *cmd,
const char *segtype_name;
/* Common mirror and raid params */
- if (arg_count(cmd, mirrors_ARG)) {
+ if (arg_is_set(cmd, mirrors_ARG)) {
lp->mirrors = arg_uint_value(cmd, mirrors_ARG, 0) + 1;
if (segtype_is_raid1(lp->segtype)) {
segtype_name = SEG_TYPE_NAME_RAID1;
@@ -1228,7 +1228,7 @@ static int _check_raid_parameters(struct volume_group *vg,
* If number of devices was not supplied, we can infer from
* the PVs given.
*/
- if (!arg_count(cmd, stripes_ARG) &&
+ if (!arg_is_set(cmd, stripes_ARG) &&
(devs > 2 * lp->segtype->parity_devs))
lp->stripes = devs - lp->segtype->parity_devs;
@@ -1239,7 +1239,7 @@ static int _check_raid_parameters(struct volume_group *vg,
return 0;
}
} else if (segtype_is_raid10(lp->segtype)) {
- if (!arg_count(cmd, stripes_ARG))
+ if (!arg_is_set(cmd, stripes_ARG))
lp->stripes = devs / lp->mirrors;
if (lp->stripes < 2) {
log_error("Unable to create RAID10 LV,"
diff --git a/tools/lvdisplay.c b/tools/lvdisplay.c
index e4d8bae..c60b463 100644
--- a/tools/lvdisplay.c
+++ b/tools/lvdisplay.c
@@ -18,14 +18,14 @@
static int _lvdisplay_single(struct cmd_context *cmd, struct logical_volume *lv,
struct processing_handle *handle __attribute__ ((unused)))
{
- if (!arg_count(cmd, all_ARG) && !lv_is_visible(lv))
+ if (!arg_is_set(cmd, all_ARG) && !lv_is_visible(lv))
return ECMD_PROCESSED;
- if (arg_count(cmd, colon_ARG))
+ if (arg_is_set(cmd, colon_ARG))
lvdisplay_colons(lv);
else {
lvdisplay_full(cmd, lv, NULL);
- if (arg_count(cmd, maps_ARG))
+ if (arg_is_set(cmd, maps_ARG))
lvdisplay_segments(lv);
}
@@ -34,26 +34,26 @@ static int _lvdisplay_single(struct cmd_context *cmd, struct logical_volume *lv,
int lvdisplay(struct cmd_context *cmd, int argc, char **argv)
{
- if (arg_count(cmd, columns_ARG)) {
- if (arg_count(cmd, colon_ARG) || arg_count(cmd, maps_ARG)) {
+ if (arg_is_set(cmd, columns_ARG)) {
+ if (arg_is_set(cmd, colon_ARG) || arg_is_set(cmd, maps_ARG)) {
log_error("Incompatible options selected");
return EINVALID_CMD_LINE;
}
return lvs(cmd, argc, argv);
}
- if (arg_count(cmd, aligned_ARG) ||
- arg_count(cmd, binary_ARG) ||
- arg_count(cmd, noheadings_ARG) ||
- arg_count(cmd, options_ARG) ||
- arg_count(cmd, separator_ARG) ||
- arg_count(cmd, sort_ARG) ||
- arg_count(cmd, unbuffered_ARG)) {
+ if (arg_is_set(cmd, aligned_ARG) ||
+ arg_is_set(cmd, binary_ARG) ||
+ arg_is_set(cmd, noheadings_ARG) ||
+ arg_is_set(cmd, options_ARG) ||
+ arg_is_set(cmd, separator_ARG) ||
+ arg_is_set(cmd, sort_ARG) ||
+ arg_is_set(cmd, unbuffered_ARG)) {
log_error("Incompatible options selected.");
return EINVALID_CMD_LINE;
}
- if (arg_count(cmd, colon_ARG) && arg_count(cmd, maps_ARG)) {
+ if (arg_is_set(cmd, colon_ARG) && arg_is_set(cmd, maps_ARG)) {
log_error("Options -c and -m are incompatible.");
return EINVALID_CMD_LINE;
}
diff --git a/tools/lvmcmdline.c b/tools/lvmcmdline.c
index 870a8c3..fd00ce6 100644
--- a/tools/lvmcmdline.c
+++ b/tools/lvmcmdline.c
@@ -82,7 +82,7 @@ int arg_from_list_is_set(const struct cmd_context *cmd, const char *err_found, .
va_list ap;
va_start(ap, err_found);
- while ((arg = va_arg(ap, int)) != -1 && !arg_count(cmd, arg))
+ while ((arg = va_arg(ap, int)) != -1 && !arg_is_set(cmd, arg))
/* empty */;
va_end(ap);
@@ -116,7 +116,7 @@ int arg_outside_list_is_set(const struct cmd_context *cmd, const char *err_found
case yes_ARG:
continue;
}
- if (!arg_count(cmd, i))
+ if (!arg_is_set(cmd, i))
continue; /* unset */
va_start(ap, err_found);
while (((arg = va_arg(ap, int)) != -1) && (arg != i))
@@ -187,7 +187,7 @@ const char *arg_value(const struct cmd_context *cmd, int a)
const char *arg_str_value(const struct cmd_context *cmd, int a, const char *def)
{
- return arg_count(cmd, a) ? cmd->arg_values[a].value : def;
+ return arg_is_set(cmd, a) ? cmd->arg_values[a].value : def;
}
const char *grouped_arg_str_value(const struct arg_values *av, int a, const char *def)
@@ -217,39 +217,39 @@ int32_t first_grouped_arg_int_value(const struct cmd_context *cmd, int a, const
int32_t arg_int_value(const struct cmd_context *cmd, int a, const int32_t def)
{
return (_cmdline.arg_props[a].flags & ARG_GROUPABLE) ?
- first_grouped_arg_int_value(cmd, a, def) : (arg_count(cmd, a) ? cmd->arg_values[a].i_value : def);
+ first_grouped_arg_int_value(cmd, a, def) : (arg_is_set(cmd, a) ? cmd->arg_values[a].i_value : def);
}
uint32_t arg_uint_value(const struct cmd_context *cmd, int a, const uint32_t def)
{
- return arg_count(cmd, a) ? cmd->arg_values[a].ui_value : def;
+ return arg_is_set(cmd, a) ? cmd->arg_values[a].ui_value : def;
}
int64_t arg_int64_value(const struct cmd_context *cmd, int a, const int64_t def)
{
- return arg_count(cmd, a) ? cmd->arg_values[a].i64_value : def;
+ return arg_is_set(cmd, a) ? cmd->arg_values[a].i64_value : def;
}
uint64_t arg_uint64_value(const struct cmd_context *cmd, int a, const uint64_t def)
{
- return arg_count(cmd, a) ? cmd->arg_values[a].ui64_value : def;
+ return arg_is_set(cmd, a) ? cmd->arg_values[a].ui64_value : def;
}
/* No longer used.
const void *arg_ptr_value(struct cmd_context *cmd, int a, const void *def)
{
- return arg_count(cmd, a) ? cmd->arg_values[a].ptr : def;
+ return arg_is_set(cmd, a) ? cmd->arg_values[a].ptr : def;
}
*/
sign_t arg_sign_value(const struct cmd_context *cmd, int a, const sign_t def)
{
- return arg_count(cmd, a) ? cmd->arg_values[a].sign : def;
+ return arg_is_set(cmd, a) ? cmd->arg_values[a].sign : def;
}
percent_type_t arg_percent_value(const struct cmd_context *cmd, int a, const percent_type_t def)
{
- return arg_count(cmd, a) ? cmd->arg_values[a].percent : def;
+ return arg_is_set(cmd, a) ? cmd->arg_values[a].percent : def;
}
int arg_count_increment(struct cmd_context *cmd, int a)
@@ -993,7 +993,7 @@ static int _merge_synonym(struct cmd_context *cmd, int oldarg, int newarg)
struct arg_values *av;
struct arg_value_group_list *current_group;
- if (arg_count(cmd, oldarg) && arg_count(cmd, newarg)) {
+ if (arg_is_set(cmd, oldarg) && arg_is_set(cmd, newarg)) {
log_error("%s and %s are synonyms. Please only supply one.",
_cmdline.arg_props[oldarg].long_arg, _cmdline.arg_props[newarg].long_arg);
return 0;
@@ -1001,12 +1001,12 @@ static int _merge_synonym(struct cmd_context *cmd, int oldarg, int newarg)
/* Not groupable? */
if (!(_cmdline.arg_props[oldarg].flags & ARG_GROUPABLE)) {
- if (arg_count(cmd, oldarg))
+ if (arg_is_set(cmd, oldarg))
_copy_arg_values(cmd->arg_values, oldarg, newarg);
return 1;
}
- if (arg_count(cmd, oldarg))
+ if (arg_is_set(cmd, oldarg))
cmd->arg_values[newarg].count = cmd->arg_values[oldarg].count;
/* Groupable */
@@ -1050,23 +1050,23 @@ static int _get_settings(struct cmd_context *cmd)
cmd->current_settings = cmd->default_settings;
- if (arg_count(cmd, debug_ARG))
+ if (arg_is_set(cmd, debug_ARG))
cmd->current_settings.debug = _LOG_FATAL +
(arg_count(cmd, debug_ARG) - 1);
- if (arg_count(cmd, verbose_ARG))
+ if (arg_is_set(cmd, verbose_ARG))
cmd->current_settings.verbose = arg_count(cmd, verbose_ARG);
- if (arg_count(cmd, quiet_ARG)) {
+ if (arg_is_set(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, test_ARG))
- cmd->current_settings.test = arg_count(cmd, test_ARG);
+ if (arg_is_set(cmd, test_ARG))
+ cmd->current_settings.test = arg_is_set(cmd, test_ARG);
- if (arg_count(cmd, driverloaded_ARG)) {
+ if (arg_is_set(cmd, driverloaded_ARG)) {
cmd->current_settings.activation =
arg_int_value(cmd, driverloaded_ARG,
cmd->default_settings.activation);
@@ -1076,7 +1076,7 @@ static int _get_settings(struct cmd_context *cmd)
cmd->current_settings.backup = arg_int_value(cmd, autobackup_ARG, cmd->current_settings.backup);
cmd->current_settings.cache_vgmetadata = cmd->command->flags & CACHE_VGMETADATA ? 1 : 0;
- if (arg_count(cmd, readonly_ARG)) {
+ if (arg_is_set(cmd, readonly_ARG)) {
cmd->current_settings.activation = 0;
cmd->current_settings.archive = 0;
cmd->current_settings.backup = 0;
@@ -1091,18 +1091,18 @@ static int _get_settings(struct cmd_context *cmd)
if (!activation_mode)
activation_mode = DEFAULT_ACTIVATION_MODE;
- if (arg_count(cmd, activationmode_ARG)) {
+ if (arg_is_set(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) &&
+ if (arg_is_set(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))
+ } else if (arg_is_set(cmd, partial_ARG))
activation_mode = "partial";
if (!strcmp(activation_mode, "partial")) {
@@ -1115,7 +1115,7 @@ static int _get_settings(struct cmd_context *cmd)
return EINVALID_CMD_LINE;
}
- if (arg_count(cmd, ignorelockingfailure_ARG) || arg_count(cmd, sysinit_ARG))
+ if (arg_is_set(cmd, ignorelockingfailure_ARG) || arg_is_set(cmd, sysinit_ARG))
init_ignorelockingfailure(1);
else
init_ignorelockingfailure(0);
@@ -1133,10 +1133,10 @@ static int _get_settings(struct cmd_context *cmd)
*/
cmd->vg_read_print_access_error = 1;
- if (arg_count(cmd, nosuffix_ARG))
+ if (arg_is_set(cmd, nosuffix_ARG))
cmd->current_settings.suffix = 0;
- if (arg_count(cmd, units_ARG))
+ if (arg_is_set(cmd, units_ARG))
if (!(cmd->current_settings.unit_factor =
dm_units_to_factor(arg_str_value(cmd, units_ARG, ""),
&cmd->current_settings.unit_type, 1, NULL))) {
@@ -1144,11 +1144,11 @@ static int _get_settings(struct cmd_context *cmd)
return EINVALID_CMD_LINE;
}
- if (arg_count(cmd, binary_ARG))
+ if (arg_is_set(cmd, binary_ARG))
cmd->report_binary_values_as_numeric = 1;
- if (arg_count(cmd, trustcache_ARG)) {
- if (arg_count(cmd, all_ARG)) {
+ if (arg_is_set(cmd, trustcache_ARG)) {
+ if (arg_is_set(cmd, all_ARG)) {
log_error("--trustcache is incompatible with --all");
return EINVALID_CMD_LINE;
}
@@ -1158,7 +1158,7 @@ static int _get_settings(struct cmd_context *cmd)
} else
init_trust_cache(0);
- if (arg_count(cmd, noudevsync_ARG))
+ if (arg_is_set(cmd, noudevsync_ARG))
cmd->current_settings.udev_sync = 0;
/* Handle synonyms */
@@ -1186,12 +1186,12 @@ static