master - tests: check for cache and raid
by Zdenek Kabelac
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=75c4d268e9b0b7...
Commit: 75c4d268e9b0b70c58f8b8b018fe200aca7b8bb2
Parent: c59ef732067988b708c7f809719ff887596a1e9f
Author: Zdenek Kabelac <zkabelac(a)redhat.com>
AuthorDate: Tue Oct 7 10:12:49 2014 +0200
Committer: Zdenek Kabelac <zkabelac(a)redhat.com>
CommitterDate: Tue Oct 7 10:19:33 2014 +0200
tests: check for cache and raid
Skip some tests on systems without cache or raid.
---
test/shell/lvconvert-cache.sh | 4 ++--
test/shell/lvconvert-thin.sh | 4 ++--
2 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/test/shell/lvconvert-cache.sh b/test/shell/lvconvert-cache.sh
index ae2de35..4f266ba 100644
--- a/test/shell/lvconvert-cache.sh
+++ b/test/shell/lvconvert-cache.sh
@@ -121,10 +121,10 @@ fail lvconvert --yes --type cache $vg/$lv2 --cachepool $vg/$lv1
fail lvconvert --yes --type cache $vg/$lv1 --cachepool $vg/$lv2
fail lvconvert --yes --type cache-pool $vg/$lv1
fail lvconvert --yes --type mirror -m1 $vg/$lv1
-fail lvconvert --yes --type raid1 -m1 $vg/$lv1
+not aux have_raid 1 0 0 || fail lvconvert --yes --type raid1 -m1 $vg/$lv1
fail lvconvert --yes --type snapshot $vg/$lv1 $vg/$lv2
fail lvconvert --yes --type snapshot $vg/$lv2 $vg/$lv1
-fail lvconvert --yes -T --thinpool $vg/$lv2 $vg/$lv1
+not aux have_thin 1 0 0 || fail lvconvert --yes -T --thinpool $vg/$lv2 $vg/$lv1
lvremove -f $vg
diff --git a/test/shell/lvconvert-thin.sh b/test/shell/lvconvert-thin.sh
index bd43d58..e61e470 100644
--- a/test/shell/lvconvert-thin.sh
+++ b/test/shell/lvconvert-thin.sh
@@ -134,9 +134,9 @@ lvcreate -L32 -n $lv1 $vg
lvcreate -L16 -n $lv2 $vg
lvconvert --yes --thinpool $vg/$lv1
-fail lvconvert --yes --type cache-pool $vg/$lv1
+not aux have_cache 1 3 0 || fail lvconvert --yes --type cache-pool $vg/$lv1
fail lvconvert --yes --type mirror -m1 $vg/$lv1
-fail lvconvert --yes --type raid1 -m1 $vg/$lv1
+not aux have_raid 1 0 0 || fail lvconvert --yes --type raid1 -m1 $vg/$lv1
fail lvconvert --yes --type snapshot $vg/$lv1 $vg/$lv2
fail lvconvert --yes --type snapshot $vg/$lv2 $vg/$lv1
fail lvconvert --yes --type thin-pool $vg/$lv1
8 years, 11 months
master - tests: move cache raid to separate file
by Zdenek Kabelac
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=c59ef732067988...
Commit: c59ef732067988b708c7f809719ff887596a1e9f
Parent: 9810f8aac7c0e38bd6cb88a45140bb41d52cd5b5
Author: Zdenek Kabelac <zkabelac(a)redhat.com>
AuthorDate: Tue Oct 7 10:12:39 2014 +0200
Committer: Zdenek Kabelac <zkabelac(a)redhat.com>
CommitterDate: Tue Oct 7 10:19:33 2014 +0200
tests: move cache raid to separate file
---
test/shell/lvconvert-cache-raid.sh | 64 ++++++++++++++++++++++++++++++++++++
test/shell/lvconvert-cache.sh | 41 -----------------------
2 files changed, 64 insertions(+), 41 deletions(-)
diff --git a/test/shell/lvconvert-cache-raid.sh b/test/shell/lvconvert-cache-raid.sh
new file mode 100644
index 0000000..0678846
--- /dev/null
+++ b/test/shell/lvconvert-cache-raid.sh
@@ -0,0 +1,64 @@
+#!/bin/sh
+# Copyright (C) 2014 Red Hat, Inc. All rights reserved.
+#
+# This copyrighted material is made available to anyone wishing to use,
+# modify, copy, or redistribute it subject to the terms and conditions
+# of the GNU General Public License v.2.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software Foundation,
+# Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+# Exercise usage of stacked cache volume using raid volume
+
+. lib/inittest
+
+aux have_cache 1 3 0 || skip
+aux have_raid 1 0 0 || skip
+
+aux prepare_vg 5 80
+
+# Bug 1095843
+# lvcreate RAID1 origin, lvcreate cache-pool, and lvconvert to cache
+lvcreate --type raid1 -m 1 -l 2 -n $lv1 $vg
+lvcreate --type cache-pool -l 1 -n ${lv1}_cachepool $vg
+lvconvert --cache --cachepool $vg/${lv1}_cachepool $vg/$lv1
+check lv_exists $vg/${lv1}_corig_rimage_0 # ensure images are properly renamed
+dmsetup table ${vg}-$lv1 | grep cache # ensure it is loaded in kernel
+lvremove -f $vg
+
+
+# lvcreate RAID1 origin, lvcreate RAID1 cache-pool, and lvconvert to cache
+lvcreate --type raid1 -m 1 -l 2 -n $lv1 $vg
+lvcreate --type raid1 -m 1 -l 2 -n ${lv1}_cachepool $vg
+#should lvs -a $vg/${lv1}_cdata_rimage_0 # ensure images are properly renamed
+lvconvert --yes --type cache --cachepool $vg/${lv1}_cachepool $vg/$lv1
+check lv_exists $vg/${lv1}_corig_rimage_0 # ensure images are properly renamed
+dmsetup table ${vg}-$lv1 | grep cache # ensure it is loaded in kernel
+lvremove -f $vg
+
+
+lvcreate -n corigin -m 1 --type raid1 -l 10 $vg
+lvcreate -n cpool --type cache $vg/corigin -l 10
+lvconvert --splitmirrors 1 --name split $vg/corigin "$dev1"
+
+lvremove -f $vg
+
+lvcreate -n cpool_meta -m 1 --type raid1 -l 10 $vg
+lvcreate -n cpool -m 1 --type raid1 -l 10 $vg
+lvconvert --yes --type cache-pool --poolmetadata $vg/cpool_meta $vg/cpool
+lvcreate -n corigin --type cache --cachepool $vg/cpool -l 10
+
+lvconvert --repair -y $vg/cpool_cmeta
+lvconvert --repair -y $vg/cpool_cdata
+
+# do not allow reserved names for *new* LVs
+not lvconvert --splitmirrors 1 --name split_cmeta $vg/cpool_cmeta "$dev1"
+not lvconvert --splitmirrors 1 --name split_cdata $vg/cpool_cdata "$dev1"
+
+# but allow manipulating existing LVs with reserved names
+lvconvert --splitmirrors 1 --name split_meta $vg/cpool_cmeta "$dev1"
+lvconvert --splitmirrors 1 --name split_data $vg/cpool_cdata "$dev1"
+
+
+vgremove -f $vg
diff --git a/test/shell/lvconvert-cache.sh b/test/shell/lvconvert-cache.sh
index d2f591f..ae2de35 100644
--- a/test/shell/lvconvert-cache.sh
+++ b/test/shell/lvconvert-cache.sh
@@ -63,26 +63,6 @@ check lv_exists $vg $lv1 ${lv1}_cachepool
lvremove -f $vg
-# Bug 1095843
-# lvcreate RAID1 origin, lvcreate cache-pool, and lvconvert to cache
-lvcreate --type raid1 -m 1 -l 2 -n $lv1 $vg
-lvcreate --type cache-pool -l 1 -n ${lv1}_cachepool $vg
-lvconvert --cache --cachepool $vg/${lv1}_cachepool $vg/$lv1
-check lv_exists $vg/${lv1}_corig_rimage_0 # ensure images are properly renamed
-dmsetup table ${vg}-$lv1 | grep cache # ensure it is loaded in kernel
-lvremove -ff $vg
-
-
-# lvcreate RAID1 origin, lvcreate RAID1 cache-pool, and lvconvert to cache
-lvcreate --type raid1 -m 1 -l 2 -n $lv1 $vg
-lvcreate --type raid1 -m 1 -l 2 -n ${lv1}_cachepool $vg
-#should lvs -a $vg/${lv1}_cdata_rimage_0 # ensure images are properly renamed
-lvconvert --yes --type cache --cachepool $vg/${lv1}_cachepool $vg/$lv1
-check lv_exists $vg/${lv1}_corig_rimage_0 # ensure images are properly renamed
-dmsetup table ${vg}-$lv1 | grep cache # ensure it is loaded in kernel
-lvremove -ff $vg
-
-
lvcreate -n corigin -l 10 $vg
lvcreate -n pool -l 10 $vg
lvs -a -o +devices
@@ -90,27 +70,6 @@ fail lvconvert --type cache --cachepool $vg/pool $vg/corigin
lvconvert --yes --cache --cachepool $vg/pool $vg/corigin
lvremove -ff $vg
-lvcreate -n corigin -m 1 --type raid1 -l 10 $vg
-lvcreate -n cpool --type cache $vg/corigin -l 10
-lvconvert --splitmirrors 1 --name split $vg/corigin $dev1
-
-lvremove -f $vg
-
-lvcreate -n cpool_meta -m 1 --type raid1 -l 10 $vg
-lvcreate -n cpool -m 1 --type raid1 -l 10 $vg
-lvconvert --yes --type cache-pool --poolmetadata $vg/cpool_meta $vg/cpool
-lvcreate -n corigin --type cache --cachepool $vg/cpool -l 10
-
-lvconvert --repair -y $vg/cpool_cmeta
-lvconvert --repair -y $vg/cpool_cdata
-
-# do not allow reserved names for *new* LVs
-not lvconvert --splitmirrors 1 --name split_cmeta $vg/cpool_cmeta $dev1
-not lvconvert --splitmirrors 1 --name split_cdata $vg/cpool_cdata $dev1
-
-# but allow manipulating existing LVs with reserved names
-lvconvert --splitmirrors 1 --name split_meta $vg/cpool_cmeta $dev1
-lvconvert --splitmirrors 1 --name split_data $vg/cpool_cdata $dev1
#######################
# Invalid conversions #
8 years, 11 months
master - cleanup: dont hide pv_dev declaration from pv
by Zdenek Kabelac
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=9810f8aac7c0e3...
Commit: 9810f8aac7c0e38bd6cb88a45140bb41d52cd5b5
Parent: b836525d9cc267a04881b82935a6a045753631bf
Author: Zdenek Kabelac <zkabelac(a)redhat.com>
AuthorDate: Tue Oct 7 10:17:34 2014 +0200
Committer: Zdenek Kabelac <zkabelac(a)redhat.com>
CommitterDate: Tue Oct 7 10:19:32 2014 +0200
cleanup: dont hide pv_dev declaration from pv
Just skip using local vars here...
---
lib/metadata/metadata.c | 9 +++------
1 files changed, 3 insertions(+), 6 deletions(-)
diff --git a/lib/metadata/metadata.c b/lib/metadata/metadata.c
index 681c2dd..3e5bd5d 100644
--- a/lib/metadata/metadata.c
+++ b/lib/metadata/metadata.c
@@ -1778,12 +1778,9 @@ struct pv_list *find_pv_in_vg(const struct volume_group *vg,
const char *pv_name)
{
struct pv_list *pvl;
- struct device *pv_dev, *cached_dev;
dm_list_iterate_items(pvl, &vg->pvs) {
- pv_dev = pvl->pv->dev;
- cached_dev = dev_cache_get(pv_name, vg->cmd->filter);
- if (!pv_dev) {
+ if (!pvl->pv->dev) {
/*
* pv_dev can't be NULL here!
* We have to catch this situation earlier in the
@@ -1800,10 +1797,10 @@ struct pv_list *find_pv_in_vg(const struct volume_group *vg,
* handled earlier in the code in that case.
*/
log_error(INTERNAL_ERROR "find_pv_in_vg: PV that is not "
- "bound to any existing device found");
+ "bound to any existing device found.");
return NULL;
}
- if (pv_dev == cached_dev)
+ if (pvl->pv->dev == dev_cache_get(pv_name, vg->cmd->filter))
return pvl;
}
8 years, 11 months
master - test: Creating a cache on top of active RAID works now.
by Petr Rockai
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=b836525d9cc267...
Commit: b836525d9cc267a04881b82935a6a045753631bf
Parent: 888da17495bc4b8a62833315cf7ad1a0bfd8fe2a
Author: Petr Rockai <prockai(a)redhat.com>
AuthorDate: Tue Oct 7 09:31:21 2014 +0200
Committer: Petr Rockai <prockai(a)redhat.com>
CommitterDate: Tue Oct 7 09:32:24 2014 +0200
test: Creating a cache on top of active RAID works now.
---
test/shell/lvconvert-cache.sh | 3 ---
test/shell/lvcreate-cache.sh | 5 +----
2 files changed, 1 insertions(+), 7 deletions(-)
diff --git a/test/shell/lvconvert-cache.sh b/test/shell/lvconvert-cache.sh
index 1c62309..d2f591f 100644
--- a/test/shell/lvconvert-cache.sh
+++ b/test/shell/lvconvert-cache.sh
@@ -90,11 +90,8 @@ fail lvconvert --type cache --cachepool $vg/pool $vg/corigin
lvconvert --yes --cache --cachepool $vg/pool $vg/corigin
lvremove -ff $vg
-
-# TODO: creating a cache on top of active RAID appears to be broken
lvcreate -n corigin -m 1 --type raid1 -l 10 $vg
lvcreate -n cpool --type cache $vg/corigin -l 10
-lvchange --refresh $vg # fix up DM tables
lvconvert --splitmirrors 1 --name split $vg/corigin $dev1
lvremove -f $vg
diff --git a/test/shell/lvcreate-cache.sh b/test/shell/lvcreate-cache.sh
index 63591c4..3bc8f40 100644
--- a/test/shell/lvcreate-cache.sh
+++ b/test/shell/lvcreate-cache.sh
@@ -156,13 +156,10 @@ grep "is bigger" out
# --poolmetadatasize
# --poolmetadataspare
-# TODO: creating a cache on top of active RAID appears to be broken
lvremove -f $vg
lvcreate -n corigin -m 1 --type raid1 -l 10 $vg
lvcreate -n cpool --type cache $vg/corigin -l 10
-should check active $vg corigin_corig
-dmsetup table | grep ^$PREFIX | should grep corigin_corig
-lvchange --refresh $vg
+check active $vg corigin_corig
dmsetup table | grep ^$PREFIX | grep corigin_corig
vgremove -ff $vg
8 years, 11 months
master - metadata: add internal error if PV has no existing device attached during find_pv_in_vg
by Peter Rajnoha
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=888da17495bc4b...
Commit: 888da17495bc4b8a62833315cf7ad1a0bfd8fe2a
Parent: b66f16fd63014c958d65ab37df4b72f1566176d3
Author: Peter Rajnoha <prajnoha(a)redhat.com>
AuthorDate: Tue Oct 7 08:58:51 2014 +0200
Committer: Peter Rajnoha <prajnoha(a)redhat.com>
CommitterDate: Tue Oct 7 09:15:12 2014 +0200
metadata: add internal error if PV has no existing device attached during find_pv_in_vg
find_pv_in_vg fn iterates over the list of PVs covered by the VG and
each PV's pvl->pv->dev is compared with device acquired from device
cache. However, in case pvl->pv->dev is NULL as well as device cache
returns NULL (e.g. when device is filtered), we'll get incorrect match
and the code calling find_pv_in_vg uses incorrect PV (as it thinks
it's the exact PV with the pv_name). The INTERNAL_ERROR covers this
situation and errors out immediately.
---
lib/metadata/metadata.c | 28 ++++++++++++++++++++++++++--
1 files changed, 26 insertions(+), 2 deletions(-)
diff --git a/lib/metadata/metadata.c b/lib/metadata/metadata.c
index 8443f94..681c2dd 100644
--- a/lib/metadata/metadata.c
+++ b/lib/metadata/metadata.c
@@ -1778,10 +1778,34 @@ struct pv_list *find_pv_in_vg(const struct volume_group *vg,
const char *pv_name)
{
struct pv_list *pvl;
+ struct device *pv_dev, *cached_dev;
- dm_list_iterate_items(pvl, &vg->pvs)
- if (pvl->pv->dev == dev_cache_get(pv_name, vg->cmd->filter))
+ dm_list_iterate_items(pvl, &vg->pvs) {
+ pv_dev = pvl->pv->dev;
+ cached_dev = dev_cache_get(pv_name, vg->cmd->filter);
+ if (!pv_dev) {
+ /*
+ * pv_dev can't be NULL here!
+ * We have to catch this situation earlier in the
+ * code if this internal error is hit. Otherwise,
+ * there's a possibility that pv_dev will match
+ * cached_dev in case both are NULL.
+ *
+ * NULL cached_dev may happen in case this device
+ * is filtered and NULL pv_dev may happen if the
+ * device is missing!
+ *
+ * If such incorrect match was hit, simply incorrect
+ * PV would be processed. This really needs to be
+ * handled earlier in the code in that case.
+ */
+ log_error(INTERNAL_ERROR "find_pv_in_vg: PV that is not "
+ "bound to any existing device found");
+ return NULL;
+ }
+ if (pv_dev == cached_dev)
return pvl;
+ }
return NULL;
}
8 years, 11 months
master - lvconvert: Allow --repair and --splitmirrors on reserved-name LVs.
by Petr Rockai
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=b66f16fd63014c...
Commit: b66f16fd63014c958d65ab37df4b72f1566176d3
Parent: 86dad329be2fa20a528066776aab77f26a29790c
Author: Petr Rockai <prockai(a)redhat.com>
AuthorDate: Tue Oct 7 08:55:09 2014 +0200
Committer: Petr Rockai <prockai(a)redhat.com>
CommitterDate: Tue Oct 7 08:58:24 2014 +0200
lvconvert: Allow --repair and --splitmirrors on reserved-name LVs.
---
test/shell/lvconvert-cache.sh | 16 ++++++++++++++++
tools/lvconvert.c | 2 ++
2 files changed, 18 insertions(+), 0 deletions(-)
diff --git a/test/shell/lvconvert-cache.sh b/test/shell/lvconvert-cache.sh
index c108008..1c62309 100644
--- a/test/shell/lvconvert-cache.sh
+++ b/test/shell/lvconvert-cache.sh
@@ -99,6 +99,22 @@ lvconvert --splitmirrors 1 --name split $vg/corigin $dev1
lvremove -f $vg
+lvcreate -n cpool_meta -m 1 --type raid1 -l 10 $vg
+lvcreate -n cpool -m 1 --type raid1 -l 10 $vg
+lvconvert --yes --type cache-pool --poolmetadata $vg/cpool_meta $vg/cpool
+lvcreate -n corigin --type cache --cachepool $vg/cpool -l 10
+
+lvconvert --repair -y $vg/cpool_cmeta
+lvconvert --repair -y $vg/cpool_cdata
+
+# do not allow reserved names for *new* LVs
+not lvconvert --splitmirrors 1 --name split_cmeta $vg/cpool_cmeta $dev1
+not lvconvert --splitmirrors 1 --name split_cdata $vg/cpool_cdata $dev1
+
+# but allow manipulating existing LVs with reserved names
+lvconvert --splitmirrors 1 --name split_meta $vg/cpool_cmeta $dev1
+lvconvert --splitmirrors 1 --name split_data $vg/cpool_cdata $dev1
+
#######################
# Invalid conversions #
#######################
diff --git a/tools/lvconvert.c b/tools/lvconvert.c
index 8f25561..fc22823 100644
--- a/tools/lvconvert.c
+++ b/tools/lvconvert.c
@@ -160,6 +160,8 @@ static int _lvconvert_name_params(struct lvconvert_params *lp,
lp->lv_name = lp->lv_name_full;
if (!lp->merge_mirror &&
+ !arg_count(cmd, repair_ARG) &&
+ !arg_count(cmd, splitmirrors_ARG) &&
!strstr(lp->lv_name, "_tdata") &&
!strstr(lp->lv_name, "_tmeta") &&
!apply_lvname_restrictions(lp->lv_name))
8 years, 11 months
master - test: Add process-each toollib tests.
by Alasdair Kergon
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=86dad329be2fa2...
Commit: 86dad329be2fa20a528066776aab77f26a29790c
Parent: 8dc5f42254b319430d02e2d0ca4cffd36b2cbaca
Author: David Teigland <teigland(a)redhat.com>
AuthorDate: Tue Oct 7 01:08:03 2014 +0100
Committer: Alasdair G Kergon <agk(a)redhat.com>
CommitterDate: Tue Oct 7 01:15:43 2014 +0100
test: Add process-each toollib tests.
---
WHATS_NEW | 4 +
test/shell/process-each-pv-nomda-all.sh | 60 ++
test/shell/process-each-pv-nomda.sh | 27 +
test/shell/process-each-pv.sh | 1285 +++++++++++++++++++++++++++++++
test/shell/process-each-pvresize.sh | 561 ++++++++++++++
5 files changed, 1937 insertions(+), 0 deletions(-)
diff --git a/WHATS_NEW b/WHATS_NEW
index 875ab20..fa4ff65 100644
--- a/WHATS_NEW
+++ b/WHATS_NEW
@@ -1,5 +1,8 @@
Version 2.02.112 -
=====================================
+ Introduce WARN_ flags to control some metadata warning messages.
+ Use process_each_pv in vgreduce.
+ Refactor process_each_pv in toollib.
Introduce single validation routine for pool chunk size.
Support --yes like --force in vg/lvremove to skip y|n prompt.
Support --yes with lvconvert --splitsnapshot.
@@ -14,6 +17,7 @@ Version 2.02.112 -
Support lvconvert --splitcache and --uncache of cached LV.
Option --cache has also shortcut -H (i.e. lvcreate -H).
Refactor lvcreate code and better preserve --type argument.
+ Refactor process_each_lv in toollib.
Refactor process_each_vg in toollib.
Pools cannot be used as external origin.
Use lv_update_and_reload() for snapshot reload.
diff --git a/test/shell/process-each-pv-nomda-all.sh b/test/shell/process-each-pv-nomda-all.sh
new file mode 100644
index 0000000..ae9f8e5
--- /dev/null
+++ b/test/shell/process-each-pv-nomda-all.sh
@@ -0,0 +1,60 @@
+#!/bin/sh
+# Copyright (C) 2008-2013 Red Hat, Inc. All rights reserved.
+#
+# This copyrighted material is made available to anyone wishing to use,
+# modify, copy, or redistribute it subject to the terms and conditions
+# of the GNU General Public License v.2.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software Foundation,
+# Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+test_description='Test process_each_pv with zero mda'
+
+. lib/inittest
+
+aux prepare_devs 14
+
+# for vg1
+pvcreate $dev10
+
+# for vg2
+pvcreate $dev2 --metadatacopies 0
+pvcreate $dev3
+pvcreate $dev4
+pvcreate $dev5
+
+# for vg3
+pvcreate $dev6 --metadatacopies 0
+pvcreate $dev7 --metadatacopies 0
+pvcreate $dev8 --metadatacopies 0
+pvcreate $dev9
+
+# orphan with mda
+pvcreate "$dev11"
+# orphan without mda
+pvcreate "$dev14" --metadatacopies 0
+
+# non-pv devs
+# dev12
+# dev13
+
+vgcreate $vg1 "$dev10"
+vgcreate $vg2 "$dev2" "$dev3" "$dev4" "$dev5"
+vgcreate $vg3 "$dev6" "$dev7" "$dev8" "$dev9"
+
+pvs -a >err
+grep $dev10 err
+grep $dev2 err
+grep $dev3 err
+grep $dev4 err
+grep $dev5 err
+grep $dev6 err
+grep $dev7 err
+grep $dev8 err
+grep $dev9 err
+grep $dev11 err
+grep $dev12 err
+grep $dev13 err
+grep $dev14 err
+
diff --git a/test/shell/process-each-pv-nomda.sh b/test/shell/process-each-pv-nomda.sh
new file mode 100644
index 0000000..10ce878
--- /dev/null
+++ b/test/shell/process-each-pv-nomda.sh
@@ -0,0 +1,27 @@
+#!/bin/sh
+# Copyright (C) 2008-2013 Red Hat, Inc. All rights reserved.
+#
+# This copyrighted material is made available to anyone wishing to use,
+# modify, copy, or redistribute it subject to the terms and conditions
+# of the GNU General Public License v.2.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software Foundation,
+# Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+test_description='Test process_each_pv with zero mda'
+
+. lib/inittest
+
+aux prepare_devs 2
+
+pvcreate $dev1 --metadatacopies 0
+pvcreate $dev2
+
+vgcreate $vg1 "$dev1" "$dev2"
+
+pvdisplay -a -C >err
+cat err
+grep $dev1 err
+grep $dev2 err
+
diff --git a/test/shell/process-each-pv.sh b/test/shell/process-each-pv.sh
new file mode 100644
index 0000000..a24b80b
--- /dev/null
+++ b/test/shell/process-each-pv.sh
@@ -0,0 +1,1285 @@
+#!/bin/sh
+# Copyright (C) 2008-2013 Red Hat, Inc. All rights reserved.
+#
+# This copyrighted material is made available to anyone wishing to use,
+# modify, copy, or redistribute it subject to the terms and conditions
+# of the GNU General Public License v.2.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software Foundation,
+# Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+test_description='Exercise toollib process_each_pv'
+
+. lib/inittest
+
+aux prepare_devs 14
+
+#
+# process_each_pv is used by a number of pv commands:
+# pvdisplay
+# pvresize
+# pvs
+# vgreduce
+#
+# process-each-pvresize.sh covers pvresize,
+# the others are covered here.
+#
+
+
+#
+# set up
+#
+# use use dev10 instead of dev1 because simple grep for
+# dev1 matchines dev10,dev11,etc
+#
+
+vgcreate $vg1 "$dev10"
+vgcreate $vg2 "$dev2" "$dev3" "$dev4" "$dev5"
+vgcreate $vg3 "$dev6" "$dev7" "$dev8" "$dev9"
+
+pvchange --addtag V2D3 "$dev3"
+pvchange --addtag V2D4 "$dev4"
+pvchange --addtag V2D45 "$dev4"
+pvchange --addtag V2D5 "$dev5"
+pvchange --addtag V2D45 "$dev5"
+
+pvchange --addtag V3 "$dev6" "$dev7" "$dev8" "$dev9"
+pvchange --addtag V3D9 "$dev9"
+
+# orphan
+pvcreate "$dev11"
+
+# dev (a non-pv device)
+pvcreate "$dev12"
+pvremove "$dev12"
+
+# dev13 is intentionally untouched so we can
+# test that it is handled appropriately as a non-pv
+
+# orphan
+pvcreate "$dev14"
+
+
+#
+# test pvdisplay
+#
+
+# pv in vg
+pvdisplay -s $dev10 >err
+grep $dev10 err
+not grep $dev2 err
+not grep $dev3 err
+not grep $dev4 err
+not grep $dev5 err
+not grep $dev6 err
+not grep $dev7 err
+not grep $dev8 err
+not grep $dev9 err
+not grep $dev11 err
+not grep $dev12 err
+not grep $dev13 err
+not grep $dev14 err
+
+# pv not in vg (one orphan)
+pvdisplay -s $dev11 >err
+not grep $dev10 err
+not grep $dev2 err
+not grep $dev3 err
+not grep $dev4 err
+not grep $dev5 err
+not grep $dev6 err
+not grep $dev7 err
+not grep $dev8 err
+not grep $dev9 err
+grep $dev11 err
+not grep $dev12 err
+not grep $dev13 err
+not grep $dev14 err
+
+# dev is not a pv
+not pvdisplay -s $dev12 >err
+not grep $dev10 err
+not grep $dev2 err
+not grep $dev3 err
+not grep $dev4 err
+not grep $dev5 err
+not grep $dev6 err
+not grep $dev7 err
+not grep $dev8 err
+not grep $dev9 err
+not grep $dev11 err
+not grep $dev12 err
+not grep $dev13 err
+not grep $dev14 err
+
+# two pvs in different vgs
+pvdisplay -s $dev10 $dev2 >err
+grep $dev10 err
+grep $dev2 err
+not grep $dev3 err
+not grep $dev4 err
+not grep $dev5 err
+not grep $dev6 err
+not grep $dev7 err
+not grep $dev8 err
+not grep $dev9 err
+not grep $dev11 err
+not grep $dev12 err
+not grep $dev13 err
+not grep $dev14 err
+
+# -a is invalid when used alone
+not pvdisplay -a >err
+not grep $dev10 err
+not grep $dev2 err
+not grep $dev3 err
+not grep $dev4 err
+not grep $dev5 err
+not grep $dev6 err
+not grep $dev7 err
+not grep $dev8 err
+not grep $dev9 err
+not grep $dev11 err
+not grep $dev12 err
+not grep $dev13 err
+not grep $dev14 err
+
+# one pv and one orphan
+pvdisplay -s $dev10 $dev11 >err
+grep $dev10 err
+not grep $dev2 err
+not grep $dev3 err
+not grep $dev4 err
+not grep $dev5 err
+not grep $dev6 err
+not grep $dev7 err
+not grep $dev8 err
+not grep $dev9 err
+grep $dev11 err
+not grep $dev12 err
+not grep $dev13 err
+not grep $dev14 err
+
+# one pv and one dev (dev refers to a non-pv device)
+not pvdisplay -s $dev10 $dev12 >err
+grep $dev10 err
+not grep $dev2 err
+not grep $dev3 err
+not grep $dev4 err
+not grep $dev5 err
+not grep $dev6 err
+not grep $dev7 err
+not grep $dev8 err
+not grep $dev9 err
+not grep $dev11 err
+not grep $dev12 err
+not grep $dev13 err
+not grep $dev14 err
+
+# one orphan and one dev
+not pvdisplay -s $dev11 $dev12 >err
+not grep $dev10 err
+not grep $dev2 err
+not grep $dev3 err
+not grep $dev4 err
+not grep $dev5 err
+not grep $dev6 err
+not grep $dev7 err
+not grep $dev8 err
+not grep $dev9 err
+grep $dev11 err
+not grep $dev12 err
+not grep $dev13 err
+not grep $dev14 err
+
+# all pvs (pvs in vgs and orphan pvs)
+pvdisplay -s >err
+grep $dev10 err
+grep $dev2 err
+grep $dev3 err
+grep $dev4 err
+grep $dev5 err
+grep $dev6 err
+grep $dev7 err
+grep $dev8 err
+grep $dev9 err
+grep $dev11 err
+not grep $dev12 err
+not grep $dev13 err
+grep $dev14 err
+
+# all devs (pvs in vgs, orphan pvs, and devs)
+pvdisplay -a -C >err
+grep $dev10 err
+grep $dev2 err
+grep $dev3 err
+grep $dev4 err
+grep $dev5 err
+grep $dev6 err
+grep $dev7 err
+grep $dev8 err
+grep $dev9 err
+grep $dev11 err
+grep $dev12 err
+grep $dev13 err
+grep $dev14 err
+
+# pv and orphan and dev
+not pvdisplay -s $dev9 $dev11 $dev12 > err
+not grep $dev10 err
+not grep $dev2 err
+not grep $dev3 err
+not grep $dev4 err
+not grep $dev5 err
+not grep $dev6 err
+not grep $dev7 err
+not grep $dev8 err
+grep $dev9 err
+grep $dev11 err
+not grep $dev12 err
+not grep $dev13 err
+not grep $dev14 err
+
+# -s option not allowed with -a -C
+not pvdisplay -s -a -C > err
+not grep $dev10 err
+not grep $dev2 err
+not grep $dev3 err
+not grep $dev4 err
+not grep $dev5 err
+not grep $dev6 err
+not grep $dev7 err
+not grep $dev8 err
+not grep $dev9 err
+not grep $dev11 err
+not grep $dev12 err
+not grep $dev13 err
+not grep $dev14 err
+
+# pv and all (all ignored)
+pvdisplay -a -C $dev9 > err
+not grep $dev10 err
+not grep $dev2 err
+not grep $dev3 err
+not grep $dev4 err
+not grep $dev5 err
+not grep $dev6 err
+not grep $dev7 err
+not grep $dev8 err
+grep $dev9 err
+not grep $dev11 err
+not grep $dev12 err
+not grep $dev13 err
+not grep $dev14 err
+
+# orphan and all (all ignored)
+pvdisplay -a -C $dev11 > err
+not grep $dev10 err
+not grep $dev2 err
+not grep $dev3 err
+not grep $dev4 err
+not grep $dev5 err
+not grep $dev6 err
+not grep $dev7 err
+not grep $dev8 err
+not grep $dev9 err
+grep $dev11 err
+not grep $dev12 err
+not grep $dev13 err
+not grep $dev14 err
+
+# one tag
+pvdisplay -s @V2D3 > err
+not grep $dev10 err
+not grep $dev2 err
+grep $dev3 err
+not grep $dev4 err
+not grep $dev5 err
+not grep $dev6 err
+not grep $dev7 err
+not grep $dev8 err
+not grep $dev9 err
+not grep $dev11 err
+not grep $dev12 err
+not grep $dev13 err
+not grep $dev14 err
+
+# two tags
+pvdisplay -s @V2D3 @V2D45 > err
+not grep $dev10 err
+not grep $dev2 err
+grep $dev3 err
+grep $dev4 err
+grep $dev5 err
+not grep $dev6 err
+not grep $dev7 err
+not grep $dev8 err
+not grep $dev9 err
+not grep $dev11 err
+not grep $dev12 err
+not grep $dev13 err
+not grep $dev14 err
+
+# tag and pv
+pvdisplay -s @V2D3 $dev4 > err
+not grep $dev10 err
+not grep $dev2 err
+grep $dev3 err
+grep $dev4 err
+not grep $dev5 err
+not grep $dev6 err
+not grep $dev7 err
+not grep $dev8 err
+not grep $dev9 err
+not grep $dev11 err
+not grep $dev12 err
+not grep $dev13 err
+not grep $dev14 err
+
+# tag and orphan
+pvdisplay -s @V2D3 $dev11 > err
+not grep $dev10 err
+not grep $dev2 err
+grep $dev3 err
+not grep $dev4 err
+not grep $dev5 err
+not grep $dev6 err
+not grep $dev7 err
+not grep $dev8 err
+not grep $dev9 err
+grep $dev11 err
+not grep $dev12 err
+not grep $dev13 err
+not grep $dev14 err
+
+# tag and dev
+not pvdisplay -s @V2D3 $dev12 > err
+not grep $dev10 err
+not grep $dev2 err
+grep $dev3 err
+not grep $dev4 err
+not grep $dev5 err
+not grep $dev6 err
+not grep $dev7 err
+not grep $dev8 err
+not grep $dev9 err
+not grep $dev11 err
+not grep $dev12 err
+not grep $dev13 err
+not grep $dev14 err
+
+# tag and all (all ignored)
+pvdisplay @V2D3 -a -C > err
+not grep $dev10 err
+not grep $dev2 err
+grep $dev3 err
+not grep $dev4 err
+not grep $dev5 err
+not grep $dev6 err
+not grep $dev7 err
+not grep $dev8 err
+not grep $dev9 err
+not grep $dev11 err
+not grep $dev12 err
+not grep $dev13 err
+not grep $dev14 err
+
+# tag and pv redundant
+pvdisplay -s @V2D3 $dev3 > err
+not grep $dev10 err
+not grep $dev2 err
+grep $dev3 err
+not grep $dev4 err
+not grep $dev5 err
+not grep $dev6 err
+not grep $dev7 err
+not grep $dev8 err
+not grep $dev9 err
+not grep $dev11 err
+not grep $dev12 err
+not grep $dev13 err
+not grep $dev14 err
+
+
+#
+# test pvs
+#
+
+# pv in vg
+pvs $dev10 >err
+grep $dev10 err
+not grep $dev2 err
+not grep $dev3 err
+not grep $dev4 err
+not grep $dev5 err
+not grep $dev6 err
+not grep $dev7 err
+not grep $dev8 err
+not grep $dev9 err
+not grep $dev11 err
+not grep $dev12 err
+not grep $dev13 err
+not grep $dev14 err
+
+# pv not in vg (one orphan)
+pvs $dev11 >err
+not grep $dev10 err
+not grep $dev2 err
+not grep $dev3 err
+not grep $dev4 err
+not grep $dev5 err
+not grep $dev6 err
+not grep $dev7 err
+not grep $dev8 err
+not grep $dev9 err
+grep $dev11 err
+not grep $dev12 err
+not grep $dev13 err
+not grep $dev14 err
+
+# dev is not a pv
+not pvs $dev12 >err
+not grep $dev10 err
+not grep $dev2 err
+not grep $dev3 err
+not grep $dev4 err
+not grep $dev5 err
+not grep $dev6 err
+not grep $dev7 err
+not grep $dev8 err
+not grep $dev9 err
+not grep $dev11 err
+not grep $dev12 err
+not grep $dev13 err
+not grep $dev14 err
+
+# two pvs in different vgs
+pvs $dev10 $dev2 >err
+grep $dev10 err
+grep $dev2 err
+not grep $dev3 err
+not grep $dev4 err
+not grep $dev5 err
+not grep $dev6 err
+not grep $dev7 err
+not grep $dev8 err
+not grep $dev9 err
+not grep $dev11 err
+not grep $dev12 err
+not grep $dev13 err
+not grep $dev14 err
+
+# one pv and one orphan
+pvs $dev10 $dev11 >err
+grep $dev10 err
+not grep $dev2 err
+not grep $dev3 err
+not grep $dev4 err
+not grep $dev5 err
+not grep $dev6 err
+not grep $dev7 err
+not grep $dev8 err
+not grep $dev9 err
+grep $dev11 err
+not grep $dev12 err
+not grep $dev13 err
+not grep $dev14 err
+
+# one pv and one dev
+not pvs $dev10 $dev12 >err
+grep $dev10 err
+not grep $dev2 err
+not grep $dev3 err
+not grep $dev4 err
+not grep $dev5 err
+not grep $dev6 err
+not grep $dev7 err
+not grep $dev8 err
+not grep $dev9 err
+not grep $dev11 err
+not grep $dev12 err
+not grep $dev13 err
+not grep $dev14 err
+
+# one orphan and one dev
+not pvs $dev11 $dev12 >err
+not grep $dev10 err
+not grep $dev2 err
+not grep $dev3 err
+not grep $dev4 err
+not grep $dev5 err
+not grep $dev6 err
+not grep $dev7 err
+not grep $dev8 err
+not grep $dev9 err
+grep $dev11 err
+not grep $dev12 err
+not grep $dev13 err
+not grep $dev14 err
+
+# all pvs (pvs in vgs and orphan pvs)
+pvs >err
+grep $dev10 err
+grep $dev2 err
+grep $dev3 err
+grep $dev4 err
+grep $dev5 err
+grep $dev6 err
+grep $dev7 err
+grep $dev8 err
+grep $dev9 err
+grep $dev11 err
+not grep $dev12 err
+not grep $dev13 err
+grep $dev14 err
+
+# all devs (pvs in vgs, orphan pvs, and devs)
+pvs -a >err
+grep $dev10 err
+grep $dev2 err
+grep $dev3 err
+grep $dev4 err
+grep $dev5 err
+grep $dev6 err
+grep $dev7 err
+grep $dev8 err
+grep $dev9 err
+grep $dev11 err
+grep $dev12 err
+grep $dev13 err
+grep $dev14 err
+
+# pv and orphan and dev
+not pvs $dev9 $dev11 $dev12 > err
+not grep $dev10 err
+not grep $dev2 err
+not grep $dev3 err
+not grep $dev4 err
+not grep $dev5 err
+not grep $dev6 err
+not grep $dev7 err
+not grep $dev8 err
+grep $dev9 err
+grep $dev11 err
+not grep $dev12 err
+not grep $dev13 err
+not grep $dev14 err
+
+# pv and all (all ignored)
+pvs -a $dev9 > err
+not grep $dev10 err
+not grep $dev2 err
+not grep $dev3 err
+not grep $dev4 err
+not grep $dev5 err
+not grep $dev6 err
+not grep $dev7 err
+not grep $dev8 err
+grep $dev9 err
+not grep $dev11 err
+not grep $dev12 err
+not grep $dev13 err
+not grep $dev14 err
+
+# orphan and all (all ignored)
+pvs -a $dev11 > err
+not grep $dev10 err
+not grep $dev2 err
+not grep $dev3 err
+not grep $dev4 err
+not grep $dev5 err
+not grep $dev6 err
+not grep $dev7 err
+not grep $dev8 err
+not grep $dev9 err
+grep $dev11 err
+not grep $dev12 err
+not grep $dev13 err
+not grep $dev14 err
+
+# one tag
+pvs @V2D3 > err
+not grep $dev10 err
+not grep $dev2 err
+grep $dev3 err
+not grep $dev4 err
+not grep $dev5 err
+not grep $dev6 err
+not grep $dev7 err
+not grep $dev8 err
+not grep $dev9 err
+not grep $dev11 err
+not grep $dev12 err
+not grep $dev13 err
+not grep $dev14 err
+
+# two tags
+pvs @V2D3 @V2D45 > err
+not grep $dev10 err
+not grep $dev2 err
+grep $dev3 err
+grep $dev4 err
+grep $dev5 err
+not grep $dev6 err
+not grep $dev7 err
+not grep $dev8 err
+not grep $dev9 err
+not grep $dev11 err
+not grep $dev12 err
+not grep $dev13 err
+not grep $dev14 err
+
+# tag and pv
+pvs @V2D3 $dev4 > err
+not grep $dev10 err
+not grep $dev2 err
+grep $dev3 err
+grep $dev4 err
+not grep $dev5 err
+not grep $dev6 err
+not grep $dev7 err
+not grep $dev8 err
+not grep $dev9 err
+not grep $dev11 err
+not grep $dev12 err
+not grep $dev13 err
+not grep $dev14 err
+
+# tag and orphan
+pvs @V2D3 $dev11 > err
+not grep $dev10 err
+not grep $dev2 err
+grep $dev3 err
+not grep $dev4 err
+not grep $dev5 err
+not grep $dev6 err
+not grep $dev7 err
+not grep $dev8 err
+not grep $dev9 err
+grep $dev11 err
+not grep $dev12 err
+not grep $dev13 err
+not grep $dev14 err
+
+# tag and dev
+not pvs @V2D3 $dev12 > err
+not grep $dev10 err
+not grep $dev2 err
+grep $dev3 err
+not grep $dev4 err
+not grep $dev5 err
+not grep $dev6 err
+not grep $dev7 err
+not grep $dev8 err
+not grep $dev9 err
+not grep $dev11 err
+not grep $dev12 err
+not grep $dev13 err
+not grep $dev14 err
+
+# tag and all (all ignored)
+pvs @V2D3 -a > err
+not grep $dev10 err
+not grep $dev2 err
+grep $dev3 err
+not grep $dev4 err
+not grep $dev5 err
+not grep $dev6 err
+not grep $dev7 err
+not grep $dev8 err
+not grep $dev9 err
+not grep $dev11 err
+not grep $dev12 err
+not grep $dev13 err
+not grep $dev14 err
+
+# tag and pv redundant
+pvs @V2D3 $dev3 > err
+not grep $dev10 err
+not grep $dev2 err
+grep $dev3 err
+not grep $dev4 err
+not grep $dev5 err
+not grep $dev6 err
+not grep $dev7 err
+not grep $dev8 err
+not grep $dev9 err
+not grep $dev11 err
+not grep $dev12 err
+not grep $dev13 err
+not grep $dev14 err
+
+
+#
+# test vgreduce
+#
+
+# fail without dev
+not vgreduce $vg2
+
+
+# fail with dev and -a
+not vgreduce $vg2 $dev2 -a
+check pv_field $dev2 vg_name $vg2
+check pv_field $dev3 vg_name $vg2
+check pv_field $dev4 vg_name $vg2
+check pv_field $dev5 vg_name $vg2
+check pv_field $dev6 vg_name $vg3
+check pv_field $dev7 vg_name $vg3
+check pv_field $dev8 vg_name $vg3
+check pv_field $dev9 vg_name $vg3
+
+
+# remove one pv
+vgreduce $vg2 $dev2
+not check pv_field $dev2 vg_name $vg2
+check pv_field $dev3 vg_name $vg2
+check pv_field $dev4 vg_name $vg2
+check pv_field $dev5 vg_name $vg2
+check pv_field $dev6 vg_name $vg3
+check pv_field $dev7 vg_name $vg3
+check pv_field $dev8 vg_name $vg3
+check pv_field $dev9 vg_name $vg3
+# reset
+vgextend $vg2 $dev2
+
+
+# remove two pvs
+vgreduce $vg2 $dev2 $dev3
+not check pv_field $dev2 vg_name $vg2
+not check pv_field $dev3 vg_name $vg2
+check pv_field $dev4 vg_name $vg2
+check pv_field $dev5 vg_name $vg2
+check pv_field $dev6 vg_name $vg3
+check pv_field $dev7 vg_name $vg3
+check pv_field $dev8 vg_name $vg3
+check pv_field $dev9 vg_name $vg3
+# reset
+vgextend $vg2 $dev2 $dev3
+pvchange --addtag V2D3 "$dev3"
+
+
+# remove one pv with tag
+vgreduce $vg2 @V2D3
+check pv_field $dev2 vg_name $vg2
+not check pv_field $dev3 vg_name $vg2
+check pv_field $dev4 vg_name $vg2
+check pv_field $dev5 vg_name $vg2
+check pv_field $dev6 vg_name $vg3
+check pv_field $dev7 vg_name $vg3
+check pv_field $dev8 vg_name $vg3
+check pv_field $dev9 vg_name $vg3
+# reset
+vgextend $vg2 $dev3
+pvchange --addtag V2D3 "$dev3"
+
+
+# remove two pvs, each with different tag
+vgreduce $vg2 @V2D3 @V2D4
+check pv_field $dev2 vg_name $vg2
+not check pv_field $dev3 vg_name $vg2
+not check pv_field $dev4 vg_name $vg2
+check pv_field $dev5 vg_name $vg2
+check pv_field $dev6 vg_name $vg3
+check pv_field $dev7 vg_name $vg3
+check pv_field $dev8 vg_name $vg3
+check pv_field $dev9 vg_name $vg3
+# reset
+vgextend $vg2 $dev3 $dev4
+pvchange --addtag V2D3 "$dev3"
+pvchange --addtag V2D4 "$dev4"
+pvchange --addtag V2D45 "$dev4"
+
+
+# remove two pvs, both with same tag
+vgreduce $vg2 @V2D45
+check pv_field $dev2 vg_name $vg2
+check pv_field $dev3 vg_name $vg2
+not check pv_field $dev4 vg_name $vg2
+not check pv_field $dev5 vg_name $vg2
+check pv_field $dev6 vg_name $vg3
+check pv_field $dev7 vg_name $vg3
+check pv_field $dev8 vg_name $vg3
+check pv_field $dev9 vg_name $vg3
+# reset
+vgextend $vg2 $dev4 $dev5
+pvchange --addtag V2D4 "$dev4"
+pvchange --addtag V2D45 "$dev4"
+pvchange --addtag V2D5 "$dev5"
+pvchange --addtag V2D45 "$dev5"
+
+
+# remove two pvs, one by name, one by tag
+vgreduce $vg2 $dev2 @V2D3
+not check pv_field $dev2 vg_name $vg2
+not check pv_field $dev3 vg_name $vg2
+check pv_field $dev4 vg_name $vg2
+check pv_field $dev5 vg_name $vg2
+check pv_field $dev6 vg_name $vg3
+check pv_field $dev7 vg_name $vg3
+check pv_field $dev8 vg_name $vg3
+check pv_field $dev9 vg_name $vg3
+# reset
+vgextend $vg2 $dev2 $dev3
+pvchange --addtag V2D3 "$dev3"
+
+
+# remove one pv by tag, where another vg has a pv with same tag
+pvchange --addtag V2D5V3D9 "$dev5"
+pvchange --addtag V2D5V3D9 "$dev9"
+vgreduce $vg2 @V2D5V3D9
+check pv_field $dev2 vg_name $vg2
+check pv_field $dev3 vg_name $vg2
+check pv_field $dev4 vg_name $vg2
+not check pv_field $dev5 vg_name $vg2
+check pv_field $dev6 vg_name $vg3
+check pv_field $dev7 vg_name $vg3
+check pv_field $dev8 vg_name $vg3
+check pv_field $dev9 vg_name $vg3
+# reset
+vgextend $vg2 $dev5
+pvchange --addtag V2D5 "$dev5"
+pvchange --addtag V2D45 "$dev5"
+
+
+# fail to remove last pv (don't know which will be last)
+not vgreduce -a $vg2
+# reset
+vgremove $vg2
+vgcreate $vg2 "$dev2" "$dev3" "$dev4" "$dev5"
+pvchange --addtag V2D3 "$dev3"
+pvchange --addtag V2D4 "$dev4"
+pvchange --addtag V2D45 "$dev4"
+pvchange --addtag V2D5 "$dev5"
+pvchange --addtag V2D45 "$dev5"
+
+
+# lvcreate on one pv to make it used
+# remove all unused pvs
+lvcreate -n $lv1 -l 2 $vg2 $dev2
+not vgreduce -a $vg2
+check pv_field $dev2 vg_name $vg2
+not check pv_field $dev3 vg_name $vg2
+not check pv_field $dev4 vg_name $vg2
+not check pv_field $dev5 vg_name $vg2
+check pv_field $dev6 vg_name $vg3
+check pv_field $dev7 vg_name $vg3
+check pv_field $dev8 vg_name $vg3
+check pv_field $dev9 vg_name $vg3
+# reset
+vgextend $vg2 $dev3 $dev4 $dev5
+pvchange --addtag V2D3 "$dev3"
+pvchange --addtag V2D4 "$dev4"
+pvchange --addtag V2D45 "$dev4"
+pvchange --addtag V2D5 "$dev5"
+pvchange --addtag V2D45 "$dev5"
+lvchange -an $vg2/$lv1
+lvremove $vg2/$lv1
+
+
+#
+# tests including pvs without mdas
+#
+
+# remove old config
+vgremove $vg1
+vgremove $vg2
+vgremove $vg3
+pvremove $dev11
+pvremove $dev14
+
+# new config with some pvs that have zero mdas
+
+# for vg1
+pvcreate $dev10
+
+# for vg2
+pvcreate $dev2 --metadatacopies 0
+pvcreate $dev3
+pvcreate $dev4
+pvcreate $dev5
+
+# for vg3
+pvcreate $dev6 --metadatacopies 0
+pvcreate $dev7 --metadatacopies 0
+pvcreate $dev8 --metadatacopies 0
+pvcreate $dev9
+
+# orphan with mda
+pvcreate "$dev11"
+# orphan without mda
+pvcreate "$dev14" --metadatacopies 0
+
+# non-pv devs
+# dev12
+# dev13
+
+vgcreate $vg1 "$dev10"
+vgcreate $vg2 "$dev2" "$dev3" "$dev4" "$dev5"
+vgcreate $vg3 "$dev6" "$dev7" "$dev8" "$dev9"
+
+pvchange --addtag V2D3 "$dev3"
+pvchange --addtag V2D4 "$dev4"
+pvchange --addtag V2D45 "$dev4"
+pvchange --addtag V2D5 "$dev5"
+pvchange --addtag V2D45 "$dev5"
+
+pvchange --addtag V3 "$dev6" "$dev7" "$dev8" "$dev9"
+pvchange --addtag V3D8 "$dev8"
+pvchange --addtag V3D9 "$dev9"
+
+
+#
+# pvdisplay including pvs without mdas
+#
+
+# pv with mda
+pvdisplay -s $dev10 >err
+grep $dev10 err
+not grep $dev2 err
+not grep $dev3 err
+not grep $dev4 err
+not grep $dev5 err
+not grep $dev6 err
+not grep $dev7 err
+not grep $dev8 err
+not grep $dev9 err
+not grep $dev11 err
+not grep $dev12 err
+not grep $dev13 err
+not grep $dev14 err
+
+# pv without mda
+pvdisplay -s $dev2 >err
+not grep $dev10 err
+grep $dev2 err
+not grep $dev3 err
+not grep $dev4 err
+not grep $dev5 err
+not grep $dev6 err
+not grep $dev7 err
+not grep $dev8 err
+not grep $dev9 err
+not grep $dev11 err
+not grep $dev12 err
+not grep $dev13 err
+not grep $dev14 err
+
+# orphan with mda
+pvdisplay -s $dev11 >err
+not grep $dev10 err
+not grep $dev2 err
+not grep $dev3 err
+not grep $dev4 err
+not grep $dev5 err
+not grep $dev6 err
+not grep $dev7 err
+not grep $dev8 err
+not grep $dev9 err
+grep $dev11 err
+not grep $dev12 err
+not grep $dev13 err
+not grep $dev14 err
+
+# orphan without mda
+pvdisplay -s $dev14 >err
+not grep $dev10 err
+not grep $dev2 err
+not grep $dev3 err
+not grep $dev4 err
+not grep $dev5 err
+not grep $dev6 err
+not grep $dev7 err
+not grep $dev8 err
+not grep $dev9 err
+not grep $dev11 err
+not grep $dev12 err
+not grep $dev13 err
+grep $dev14 err
+
+# pv with mda, pv without mda, orphan with mda, orphan without mda
+pvdisplay -s $dev10 $dev2 $dev11 $dev14 >err
+grep $dev10 err
+grep $dev2 err
+not grep $dev3 err
+not grep $dev4 err
+not grep $dev5 err
+not grep $dev6 err
+not grep $dev7 err
+not grep $dev8 err
+not grep $dev9 err
+grep $dev11 err
+not grep $dev12 err
+not grep $dev13 err
+grep $dev14 err
+
+# tag refering to pv with mda and pv without mda
+pvdisplay -s @V3 >err
+not grep $dev10 err
+not grep $dev2 err
+not grep $dev3 err
+not grep $dev4 err
+not grep $dev5 err
+grep $dev6 err
+grep $dev7 err
+grep $dev8 err
+grep $dev9 err
+not grep $dev11 err
+not grep $dev12 err
+not grep $dev13 err
+not grep $dev14 err
+
+# tag refering to one pv without mda
+pvdisplay -s @V3D8 >err
+not grep $dev10 err
+not grep $dev2 err
+not grep $dev3 err
+not grep $dev4 err
+not grep $dev5 err
+not grep $dev6 err
+not grep $dev7 err
+grep $dev8 err
+not grep $dev9 err
+not grep $dev11 err
+not grep $dev12 err
+not grep $dev13 err
+not grep $dev14 err
+
+# all pvs (pvs in vgs and orphan pvs)
+pvdisplay -s >err
+grep $dev10 err
+grep $dev2 err
+grep $dev3 err
+grep $dev4 err
+grep $dev5 err
+grep $dev6 err
+grep $dev7 err
+grep $dev8 err
+grep $dev9 err
+grep $dev11 err
+not grep $dev12 err
+not grep $dev13 err
+grep $dev14 err
+
+# all devs (pvs in vgs, orphan pvs, and devs)
+pvdisplay -a -C >err
+grep $dev10 err
+grep $dev2 err
+grep $dev3 err
+grep $dev4 err
+grep $dev5 err
+grep $dev6 err
+grep $dev7 err
+grep $dev8 err
+grep $dev9 err
+grep $dev11 err
+grep $dev12 err
+grep $dev13 err
+grep $dev14 err
+
+#
+# pvs including pvs without mdas
+#
+
+# pv with mda
+pvs $dev10 >err
+grep $dev10 err
+not grep $dev2 err
+not grep $dev3 err
+not grep $dev4 err
+not grep $dev5 err
+not grep $dev6 err
+not grep $dev7 err
+not grep $dev8 err
+not grep $dev9 err
+not grep $dev11 err
+not grep $dev12 err
+not grep $dev13 err
+not grep $dev14 err
+
+# pv without mda
+pvs $dev2 >err
+not grep $dev10 err
+grep $dev2 err
+not grep $dev3 err
+not grep $dev4 err
+not grep $dev5 err
+not grep $dev6 err
+not grep $dev7 err
+not grep $dev8 err
+not grep $dev9 err
+not grep $dev11 err
+not grep $dev12 err
+not grep $dev13 err
+not grep $dev14 err
+
+# orphan with mda
+pvs $dev11 >err
+not grep $dev10 err
+not grep $dev2 err
+not grep $dev3 err
+not grep $dev4 err
+not grep $dev5 err
+not grep $dev6 err
+not grep $dev7 err
+not grep $dev8 err
+not grep $dev9 err
+grep $dev11 err
+not grep $dev12 err
+not grep $dev13 err
+not grep $dev14 err
+
+# orphan without mda
+pvs $dev14 >err
+not grep $dev10 err
+not grep $dev2 err
+not grep $dev3 err
+not grep $dev4 err
+not grep $dev5 err
+not grep $dev6 err
+not grep $dev7 err
+not grep $dev8 err
+not grep $dev9 err
+not grep $dev11 err
+not grep $dev12 err
+not grep $dev13 err
+grep $dev14 err
+
+# pv with mda, pv without mda, orphan with mda, orphan without mda
+pvs $dev10 $dev2 $dev11 $dev14 >err
+grep $dev10 err
+grep $dev2 err
+not grep $dev3 err
+not grep $dev4 err
+not grep $dev5 err
+not grep $dev6 err
+not grep $dev7 err
+not grep $dev8 err
+not grep $dev9 err
+grep $dev11 err
+not grep $dev12 err
+not grep $dev13 err
+grep $dev14 err
+
+# tag refering to pv with mda and pv without mda
+pvs @V3 >err
+not grep $dev10 err
+not grep $dev2 err
+not grep $dev3 err
+not grep $dev4 err
+not grep $dev5 err
+grep $dev6 err
+grep $dev7 err
+grep $dev8 err
+grep $dev9 err
+not grep $dev11 err
+not grep $dev12 err
+not grep $dev13 err
+not grep $dev14 err
+
+# tag refering to one pv without mda
+pvs @V3D8 >err
+not grep $dev10 err
+not grep $dev2 err
+not grep $dev3 err
+not grep $dev4 err
+not grep $dev5 err
+not grep $dev6 err
+not grep $dev7 err
+grep $dev8 err
+not grep $dev9 err
+not grep $dev11 err
+not grep $dev12 err
+not grep $dev13 err
+not grep $dev14 err
+
+# all pvs (pvs in vgs and orphan pvs)
+pvs >err
+grep $dev10 err
+grep $dev2 err
+grep $dev3 err
+grep $dev4 err
+grep $dev5 err
+grep $dev6 err
+grep $dev7 err
+grep $dev8 err
+grep $dev9 err
+grep $dev11 err
+not grep $dev12 err
+not grep $dev13 err
+grep $dev14 err
+
+# all devs (pvs in vgs, orphan pvs, and devs)
+pvs -a >err
+grep $dev10 err
+grep $dev2 err
+grep $dev3 err
+grep $dev4 err
+grep $dev5 err
+grep $dev6 err
+grep $dev7 err
+grep $dev8 err
+grep $dev9 err
+grep $dev11 err
+grep $dev12 err
+grep $dev13 err
+grep $dev14 err
+
+
+#
+# vgreduce including pvs without mdas
+#
+
+# remove pv without mda
+vgreduce $vg2 $dev2
+not check pv_field $dev2 vg_name $vg2
+check pv_field $dev3 vg_name $vg2
+check pv_field $dev4 vg_name $vg2
+check pv_field $dev5 vg_name $vg2
+check pv_field $dev6 vg_name $vg3
+check pv_field $dev7 vg_name $vg3
+check pv_field $dev8 vg_name $vg3
+check pv_field $dev9 vg_name $vg3
+# reset
+vgextend $vg2 $dev2
+
+# remove pv with mda and pv without mda
+vgreduce $vg2 $dev2 $dev3
+not check pv_field $dev2 vg_name $vg2
+not check pv_field $dev3 vg_name $vg2
+check pv_field $dev4 vg_name $vg2
+check pv_field $dev5 vg_name $vg2
+check pv_field $dev6 vg_name $vg3
+check pv_field $dev7 vg_name $vg3
+check pv_field $dev8 vg_name $vg3
+check pv_field $dev9 vg_name $vg3
+# reset
+vgextend $vg2 $dev2
+vgextend $vg2 $dev3
+
+# fail to remove only pv with mda
+not vgreduce $vg3 $dev9
+check pv_field $dev6 vg_name $vg3
+check pv_field $dev7 vg_name $vg3
+check pv_field $dev8 vg_name $vg3
+check pv_field $dev9 vg_name $vg3
+check pv_field $dev2 vg_name $vg2
+check pv_field $dev3 vg_name $vg2
+check pv_field $dev4 vg_name $vg2
+check pv_field $dev5 vg_name $vg2
+
+# remove by tag a pv without mda
+vgreduce $vg3 @V3D8
+check pv_field $dev6 vg_name $vg3
+check pv_field $dev7 vg_name $vg3
+not check pv_field $dev8 vg_name $vg3
+check pv_field $dev9 vg_name $vg3
+check pv_field $dev2 vg_name $vg2
+check pv_field $dev3 vg_name $vg2
+check pv_field $dev4 vg_name $vg2
+check pv_field $dev5 vg_name $vg2
+# reset
+vgextend $vg3 $dev8
+
+
diff --git a/test/shell/process-each-pvresize.sh b/test/shell/process-each-pvresize.sh
new file mode 100644
index 0000000..caa0890
--- /dev/null
+++ b/test/shell/process-each-pvresize.sh
@@ -0,0 +1,561 @@
+#!/bin/sh
+# Copyright (C) 2008-2013 Red Hat, Inc. All rights reserved.
+#
+# This copyrighted material is made available to anyone wishing to use,
+# modify, copy, or redistribute it subject to the terms and conditions
+# of the GNU General Public License v.2.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software Foundation,
+# Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+test_description='Exercise toollib process_each_pv'
+
+. lib/inittest
+
+aux prepare_devs 14
+
+#
+# process_each_pv is used by a number of pv commands:
+# pvdisplay
+# pvresize
+# pvs
+# vgreduce
+#
+
+
+#
+# set up
+#
+# use use dev10 instead of dev1 because simple grep for
+# dev1 matchines dev10,dev11,etc
+#
+
+vgcreate $vg1 "$dev10"
+vgcreate $vg2 "$dev2" "$dev3" "$dev4" "$dev5"
+vgcreate $vg3 "$dev6" "$dev7" "$dev8" "$dev9"
+
+pvchange --addtag V2D3 "$dev3"
+pvchange --addtag V2D4 "$dev4"
+pvchange --addtag V2D45 "$dev4"
+pvchange --addtag V2D5 "$dev5"
+pvchange --addtag V2D45 "$dev5"
+
+pvchange --addtag V3 "$dev6" "$dev7" "$dev8" "$dev9"
+pvchange --addtag V3D9 "$dev9"
+
+# orphan
+pvcreate "$dev11"
+
+# dev (a non-pv device)
+pvcreate "$dev12"
+pvremove "$dev12"
+
+# dev13 is intentionally untouched so we can
+# test that it is handled appropriately as a non-pv
+
+# orphan
+pvcreate "$dev14"
+
+#
+# test pvresize without orphans and and without non-pv devs
+#
+
+# For pvs in vgs, pvresize setphysicalvolumesize does not give us
+# the size requested, but reduces the requested size by some the
+# amount for alignment, metadata areas and pv headers. So, when we resize
+# to 30M, the result is 28M, and when we resize to 20M, the result is 16M.
+# For orphans, the resulting size is the same as requested.
+# It suspect that these reduction amounts might be inconsistent, and
+# depend on other changing factors, so it may be that we eventually
+# want to give up checking the exact resulting size, but just check
+# that the result is less than the original size.
+
+old_request="30.00m"
+old_reduced="28.00m"
+new_request="20.00m"
+new_reduced="16.00m"
+
+pvresize --setphysicalvolumesize $old_request $dev10 $dev2 $dev3 $dev4 $dev5 $dev6 $dev7 $dev8 $dev9
+check pv_field $dev10 pv_size $old_reduced
+check pv_field $dev2 pv_size $old_reduced
+check pv_field $dev3 pv_size $old_reduced
+check pv_field $dev4 pv_size $old_reduced
+check pv_field $dev5 pv_size $old_reduced
+check pv_field $dev6 pv_size $old_reduced
+check pv_field $dev7 pv_size $old_reduced
+check pv_field $dev8 pv_size $old_reduced
+check pv_field $dev9 pv_size $old_reduced
+
+# one pv
+pvresize --setphysicalvolumesize $new_request $dev10
+check pv_field $dev10 pv_size $new_reduced
+# unchanged
+check pv_field $dev2 pv_size $old_reduced
+check pv_field $dev3 pv_size $old_reduced
+check pv_field $dev4 pv_size $old_reduced
+check pv_field $dev5 pv_size $old_reduced
+check pv_field $dev6 pv_size $old_reduced
+check pv_field $dev7 pv_size $old_reduced
+check pv_field $dev8 pv_size $old_reduced
+check pv_field $dev9 pv_size $old_reduced
+# reset back to old size
+pvresize --setphysicalvolumesize $old_request $dev10 $dev2 $dev3 $dev4 $dev5 $dev6 $dev7 $dev8 $dev9
+
+# two pvs in separate vgs
+pvresize --setphysicalvolumesize $new_request $dev2 $dev6
+check pv_field $dev2 pv_size $new_reduced
+check pv_field $dev6 pv_size $new_reduced
+# unchanged
+check pv_field $dev10 pv_size $old_reduced
+check pv_field $dev3 pv_size $old_reduced
+check pv_field $dev4 pv_size $old_reduced
+check pv_field $dev5 pv_size $old_reduced
+check pv_field $dev7 pv_size $old_reduced
+check pv_field $dev8 pv_size $old_reduced
+check pv_field $dev9 pv_size $old_reduced
+# reset back to old size
+pvresize --setphysicalvolumesize $old_request $dev10 $dev2 $dev3 $dev4 $dev5 $dev6 $dev7 $dev8 $dev9
+
+# one tag on one pv
+pvresize --setphysicalvolumesize $new_request @V2D4
+check pv_field $dev4 pv_size $new_reduced
+# unchanged
+check pv_field $dev10 pv_size $old_reduced
+check pv_field $dev2 pv_size $old_reduced
+check pv_field $dev3 pv_size $old_reduced
+check pv_field $dev5 pv_size $old_reduced
+check pv_field $dev6 pv_size $old_reduced
+check pv_field $dev7 pv_size $old_reduced
+check pv_field $dev8 pv_size $old_reduced
+check pv_field $dev9 pv_size $old_reduced
+# reset back to old size
+pvresize --setphysicalvolumesize $old_request $dev10 $dev2 $dev3 $dev4 $dev5 $dev6 $dev7 $dev8 $dev9
+
+# one tag on all pvs in one vg
+pvresize --setphysicalvolumesize $new_request @V3
+check pv_field $dev6 pv_size $new_reduced
+check pv_field $dev7 pv_size $new_reduced
+check pv_field $dev8 pv_size $new_reduced
+check pv_field $dev9 pv_size $new_reduced
+# unchanged
+check pv_field $dev10 pv_size $old_reduced
+check pv_field $dev2 pv_size $old_reduced
+check pv_field $dev3 pv_size $old_reduced
+check pv_field $dev4 pv_size $old_reduced
+check pv_field $dev5 pv_size $old_reduced
+# reset back to old size
+pvresize --setphysicalvolumesize $old_request $dev10 $dev2 $dev3 $dev4 $dev5 $dev6 $dev7 $dev8 $dev9
+
+# one tag on some pvs in one vg
+pvresize --setphysicalvolumesize $new_request @V2D45
+check pv_field $dev4 pv_size $new_reduced
+check pv_field $dev5 pv_size $new_reduced
+# unchanged
+check pv_field $dev10 pv_size $old_reduced
+check pv_field $dev2 pv_size $old_reduced
+check pv_field $dev3 pv_size $old_reduced
+check pv_field $dev6 pv_size $old_reduced
+check pv_field $dev7 pv_size $old_reduced
+check pv_field $dev8 pv_size $old_reduced
+check pv_field $dev9 pv_size $old_reduced
+# reset back to old size
+pvresize --setphysicalvolumesize $old_request $dev10 $dev2 $dev3 $dev4 $dev5 $dev6 $dev7 $dev8 $dev9
+
+# one tag on multiple pvs in separate vgs
+pvchange --addtag V12 "$dev10" "$dev2" "$dev3" "$dev4" "$dev5"
+pvresize --setphysicalvolumesize $new_request @V12
+check pv_field $dev10 pv_size $new_reduced
+check pv_field $dev2 pv_size $new_reduced
+check pv_field $dev3 pv_size $new_reduced
+check pv_field $dev4 pv_size $new_reduced
+check pv_field $dev5 pv_size $new_reduced
+# unchanged
+check pv_field $dev6 pv_size $old_reduced
+check pv_field $dev7 pv_size $old_reduced
+check pv_field $dev8 pv_size $old_reduced
+check pv_field $dev9 pv_size $old_reduced
+# reset back to old size
+pvresize --setphysicalvolumesize $old_request $dev10 $dev2 $dev3 $dev4 $dev5 $dev6 $dev7 $dev8 $dev9
+
+# one pv and one tag on different pv
+pvresize --setphysicalvolumesize $new_request $dev10 @V3D9
+check pv_field $dev10 pv_size $new_reduced
+check pv_field $dev9 pv_size $new_reduced
+# unchanged
+check pv_field $dev2 pv_size $old_reduced
+check pv_field $dev3 pv_size $old_reduced
+check pv_field $dev4 pv_size $old_reduced
+check pv_field $dev5 pv_size $old_reduced
+check pv_field $dev6 pv_size $old_reduced
+check pv_field $dev7 pv_size $old_reduced
+check pv_field $dev8 pv_size $old_reduced
+# reset back to old size
+pvresize --setphysicalvolumesize $old_request $dev10 $dev2 $dev3 $dev4 $dev5 $dev6 $dev7 $dev8 $dev9
+
+# redundant pv and tag
+pvresize --setphysicalvolumesize $new_request $dev9 @V3D9
+check pv_field $dev9 pv_size $new_reduced
+# unchanged
+check pv_field $dev10 pv_size $old_reduced
+check pv_field $dev2 pv_size $old_reduced
+check pv_field $dev3 pv_size $old_reduced
+check pv_field $dev4 pv_size $old_reduced
+check pv_field $dev5 pv_size $old_reduced
+check pv_field $dev6 pv_size $old_reduced
+check pv_field $dev7 pv_size $old_reduced
+check pv_field $dev8 pv_size $old_reduced
+# reset back to old size
+pvresize --setphysicalvolumesize $old_request $dev10 $dev2 $dev3 $dev4 $dev5 $dev6 $dev7 $dev8 $dev9
+
+# two tags on pvs in separate vgs
+pvresize --setphysicalvolumesize $new_request @V3D9 @V2D3
+check pv_field $dev9 pv_size $new_reduced
+check pv_field $dev3 pv_size $new_reduced
+# unchanged
+check pv_field $dev10 pv_size $old_reduced
+check pv_field $dev2 pv_size $old_reduced
+check pv_field $dev4 pv_size $old_reduced
+check pv_field $dev5 pv_size $old_reduced
+check pv_field $dev6 pv_size $old_reduced
+check pv_field $dev7 pv_size $old_reduced
+check pv_field $dev8 pv_size $old_reduced
+# reset back to old size
+pvresize --setphysicalvolumesize $old_request $dev10 $dev2 $dev3 $dev4 $dev5 $dev6 $dev7 $dev8 $dev9
+
+
+#
+# test pvresize with orphans
+#
+
+old_request="30.00m"
+old_reduced="28.00m"
+old_orphan="30.00m"
+new_request="20.00m"
+new_reduced="16.00m"
+new_orphan="20.00m"
+
+pvresize --setphysicalvolumesize $old_request $dev10 $dev2 $dev3 $dev4 $dev5 $dev6 $dev7 $dev8 $dev9
+pvresize --setphysicalvolumesize $old_request $dev11 $dev14
+check pv_field $dev10 pv_size $old_reduced
+check pv_field $dev2 pv_size $old_reduced
+check pv_field $dev3 pv_size $old_reduced
+check pv_field $dev4 pv_size $old_reduced
+check pv_field $dev5 pv_size $old_reduced
+check pv_field $dev6 pv_size $old_reduced
+check pv_field $dev7 pv_size $old_reduced
+check pv_field $dev8 pv_size $old_reduced
+check pv_field $dev9 pv_size $old_reduced
+check pv_field $dev11 pv_size $old_orphan
+check pv_field $dev14 pv_size $old_orphan
+
+# one orphan
+pvresize --setphysicalvolumesize $new_request $dev11
+check pv_field $dev11 pv_size $new_orphan
+# unchanged
+check pv_field $dev10 pv_size $old_reduced
+check pv_field $dev2 pv_size $old_reduced
+check pv_field $dev3 pv_size $old_reduced
+check pv_field $dev4 pv_size $old_reduced
+check pv_field $dev5 pv_size $old_reduced
+check pv_field $dev6 pv_size $old_reduced
+check pv_field $dev7 pv_size $old_reduced
+check pv_field $dev8 pv_size $old_reduced
+check pv_field $dev9 pv_size $old_reduced
+check pv_field $dev14 pv_size $old_orphan
+# reset back to old size
+pvresize --setphysicalvolumesize $old_request $dev10 $dev2 $dev3 $dev4 $dev5 $dev6 $dev7 $dev8 $dev9
+pvresize --setphysicalvolumesize $old_request $dev11 $dev14
+
+# two orphans
+pvresize --setphysicalvolumesize $new_request $dev11 $dev14
+check pv_field $dev11 pv_size $new_orphan
+check pv_field $dev14 pv_size $new_orphan
+# unchanged
+check pv_field $dev10 pv_size $old_reduced
+check pv_field $dev2 pv_size $old_reduced
+check pv_field $dev3 pv_size $old_reduced
+check pv_field $dev4 pv_size $old_reduced
+check pv_field $dev5 pv_size $old_reduced
+check pv_field $dev6 pv_size $old_reduced
+check pv_field $dev7 pv_size $old_reduced
+check pv_field $dev8 pv_size $old_reduced
+check pv_field $dev9 pv_size $old_reduced
+# reset back to old size
+pvresize --setphysicalvolumesize $old_request $dev10 $dev2 $dev3 $dev4 $dev5 $dev6 $dev7 $dev8 $dev9
+pvresize --setphysicalvolumesize $old_request $dev11 $dev14
+
+# one orphan, one tag
+pvresize --setphysicalvolumesize $new_request @V3D9 $dev14
+check pv_field $dev9 pv_size $new_reduced
+check pv_field $dev14 pv_size $new_orphan
+# unchanged
+check pv_field $dev10 pv_size $old_reduced
+check pv_field $dev2 pv_size $old_reduced
+check pv_field $dev3 pv_size $old_reduced
+check pv_field $dev4 pv_size $old_reduced
+check pv_field $dev5 pv_size $old_reduced
+check pv_field $dev6 pv_size $old_reduced
+check pv_field $dev7 pv_size $old_reduced
+check pv_field $dev8 pv_size $old_reduced
+check pv_field $dev11 pv_size $old_orphan
+# reset back to old size
+pvresize --setphysicalvolumesize $old_request $dev10 $dev2 $dev3 $dev4 $dev5 $dev6 $dev7 $dev8 $dev9
+pvresize --setphysicalvolumesize $old_request $dev11 $dev14
+
+# one pv, one orphan, one tag
+pvresize --setphysicalvolumesize $new_request @V3D9 $dev14 $dev10
+check pv_field $dev9 pv_size $new_reduced
+check pv_field $dev10 pv_size $new_reduced
+check pv_field $dev14 pv_size $new_orphan
+# unchanged
+check pv_field $dev2 pv_size $old_reduced
+check pv_field $dev3 pv_size $old_reduced
+check pv_field $dev4 pv_size $old_reduced
+check pv_field $dev5 pv_size $old_reduced
+check pv_field $dev6 pv_size $old_reduced
+check pv_field $dev7 pv_size $old_reduced
+check pv_field $dev8 pv_size $old_reduced
+check pv_field $dev11 pv_size $old_orphan
+# reset back to old size
+pvresize --setphysicalvolumesize $old_request $dev10 $dev2 $dev3 $dev4 $dev5 $dev6 $dev7 $dev8 $dev9
+pvresize --setphysicalvolumesize $old_request $dev11 $dev14
+
+
+#
+# test pvresize with non-pv devs
+#
+
+# one dev (non-pv)
+not pvresize --setphysicalvolumesize $new_request $dev13
+# unchanged
+check pv_field $dev10 pv_size $old_reduced
+check pv_field $dev2 pv_size $old_reduced
+check pv_field $dev3 pv_size $old_reduced
+check pv_field $dev4 pv_size $old_reduced
+check pv_field $dev5 pv_size $old_reduced
+check pv_field $dev6 pv_size $old_reduced
+check pv_field $dev7 pv_size $old_reduced
+check pv_field $dev8 pv_size $old_reduced
+check pv_field $dev9 pv_size $old_reduced
+check pv_field $dev11 pv_size $old_orphan
+check pv_field $dev14 pv_size $old_orphan
+
+# one orphan and one dev (non-pv)
+not pvresize --setphysicalvolumesize $new_request $dev14 $dev13
+check pv_field $dev14 pv_size $new_orphan
+# unchanged
+check pv_field $dev10 pv_size $old_reduced
+check pv_field $dev2 pv_size $old_reduced
+check pv_field $dev3 pv_size $old_reduced
+check pv_field $dev4 pv_size $old_reduced
+check pv_field $dev5 pv_size $old_reduced
+check pv_field $dev6 pv_size $old_reduced
+check pv_field $dev7 pv_size $old_reduced
+check pv_field $dev8 pv_size $old_reduced
+check pv_field $dev9 pv_size $old_reduced
+check pv_field $dev11 pv_size $old_orphan
+# reset back to old size
+pvresize --setphysicalvolumesize $old_request $dev10 $dev2 $dev3 $dev4 $dev5 $dev6 $dev7 $dev8 $dev9
+pvresize --setphysicalvolumesize $old_request $dev11 $dev14
+
+# one pv and one dev (non-pv)
+not pvresize --setphysicalvolumesize $new_request $dev9 $dev13
+check pv_field $dev9 pv_size $new_reduced
+# unchanged
+check pv_field $dev10 pv_size $old_reduced
+check pv_field $dev2 pv_size $old_reduced
+check pv_field $dev3 pv_size $old_reduced
+check pv_field $dev4 pv_size $old_reduced
+check pv_field $dev5 pv_size $old_reduced
+check pv_field $dev6 pv_size $old_reduced
+check pv_field $dev7 pv_size $old_reduced
+check pv_field $dev8 pv_size $old_reduced
+check pv_field $dev11 pv_size $old_orphan
+check pv_field $dev14 pv_size $old_orphan
+# reset back to old size
+pvresize --setphysicalvolumesize $old_request $dev10 $dev2 $dev3 $dev4 $dev5 $dev6 $dev7 $dev8 $dev9
+pvresize --setphysicalvolumesize $old_request $dev11 $dev14
+
+# one tag and one dev (non-pv)
+not pvresize --setphysicalvolumesize $new_request @V3D9 $dev13
+check pv_field $dev9 pv_size $new_reduced
+# unchanged
+check pv_field $dev10 pv_size $old_reduced
+check pv_field $dev2 pv_size $old_reduced
+check pv_field $dev3 pv_size $old_reduced
+check pv_field $dev4 pv_size $old_reduced
+check pv_field $dev5 pv_size $old_reduced
+check pv_field $dev6 pv_size $old_reduced
+check pv_field $dev7 pv_size $old_reduced
+check pv_field $dev8 pv_size $old_reduced
+check pv_field $dev11 pv_size $old_orphan
+check pv_field $dev14 pv_size $old_orphan
+# reset back to old size
+pvresize --setphysicalvolumesize $old_request $dev10 $dev2 $dev3 $dev4 $dev5 $dev6 $dev7 $dev8 $dev9
+pvresize --setphysicalvolumesize $old_request $dev11 $dev14
+
+# one pv, one orphan, one tag, one dev
+not pvresize --setphysicalvolumesize $new_request @V3D9 $dev13 $dev14 $dev10
+check pv_field $dev9 pv_size $new_reduced
+check pv_field $dev10 pv_size $new_reduced
+check pv_field $dev14 pv_size $new_orphan
+# unchanged
+check pv_field $dev2 pv_size $old_reduced
+check pv_field $dev3 pv_size $old_reduced
+check pv_field $dev4 pv_size $old_reduced
+check pv_field $dev5 pv_size $old_reduced
+check pv_field $dev6 pv_size $old_reduced
+check pv_field $dev7 pv_size $old_reduced
+check pv_field $dev8 pv_size $old_reduced
+check pv_field $dev11 pv_size $old_orphan
+# reset back to old size
+pvresize --setphysicalvolumesize $old_request $dev10 $dev2 $dev3 $dev4 $dev5 $dev6 $dev7 $dev8 $dev9
+pvresize --setphysicalvolumesize $old_request $dev11 $dev14
+
+
+#
+# pvresize including pvs without mdas
+#
+
+pvresize --setphysicalvolumesize $old_request $dev10 $dev2 $dev3 $dev4 $dev5 $dev6 $dev7 $dev8 $dev9
+pvresize --setphysicalvolumesize $old_request $dev11 $dev14
+check pv_field $dev10 pv_size $old_reduced
+check pv_field $dev2 pv_size $old_reduced
+check pv_field $dev3 pv_size $old_reduced
+check pv_field $dev4 pv_size $old_reduced
+check pv_field $dev5 pv_size $old_reduced
+check pv_field $dev6 pv_size $old_reduced
+check pv_field $dev7 pv_size $old_reduced
+check pv_field $dev8 pv_size $old_reduced
+check pv_field $dev9 pv_size $old_reduced
+check pv_field $dev11 pv_size $old_orphan
+check pv_field $dev14 pv_size $old_orphan
+
+# one pv without mda
+pvresize --setphysicalvolumesize $new_request $dev2
+check pv_field $dev2 pv_size $new_reduced
+# unchanged
+check pv_field $dev10 pv_size $old_reduced
+check pv_field $dev3 pv_size $old_reduced
+check pv_field $dev4 pv_size $old_reduced
+check pv_field $dev5 pv_size $old_reduced
+check pv_field $dev6 pv_size $old_reduced
+check pv_field $dev7 pv_size $old_reduced
+check pv_field $dev8 pv_size $old_reduced
+check pv_field $dev9 pv_size $old_reduced
+check pv_field $dev11 pv_size $old_orphan
+check pv_field $dev14 pv_size $old_orphan
+# reset back to old size
+pvresize --setphysicalvolumesize $old_request $dev10 $dev2 $dev3 $dev4 $dev5 $dev6 $dev7 $dev8 $dev9
+pvresize --setphysicalvolumesize $old_request $dev11 $dev14
+
+# two pvs without mdas
+pvresize --setphysicalvolumesize $new_request $dev6 $dev7
+check pv_field $dev6 pv_size $new_reduced
+check pv_field $dev7 pv_size $new_reduced
+# unchanged
+check pv_field $dev10 pv_size $old_reduced
+check pv_field $dev2 pv_size $old_reduced
+check pv_field $dev3 pv_size $old_reduced
+check pv_field $dev4 pv_size $old_reduced
+check pv_field $dev5 pv_size $old_reduced
+check pv_field $dev8 pv_size $old_reduced
+check pv_field $dev9 pv_size $old_reduced
+check pv_field $dev11 pv_size $old_orphan
+check pv_field $dev14 pv_size $old_orphan
+# reset back to old size
+pvresize --setphysicalvolumesize $old_request $dev10 $dev2 $dev3 $dev4 $dev5 $dev6 $dev7 $dev8 $dev9
+pvresize --setphysicalvolumesize $old_request $dev11 $dev14
+
+# one pv with mda and one pv without mda
+pvresize --setphysicalvolumesize $new_request $dev8 $dev9
+check pv_field $dev8 pv_size $new_reduced
+check pv_field $dev9 pv_size $new_reduced
+# unchanged
+check pv_field $dev10 pv_size $old_reduced
+check pv_field $dev2 pv_size $old_reduced
+check pv_field $dev3 pv_size $old_reduced
+check pv_field $dev4 pv_size $old_reduced
+check pv_field $dev5 pv_size $old_reduced
+check pv_field $dev6 pv_size $old_reduced
+check pv_field $dev7 pv_size $old_reduced
+check pv_field $dev11 pv_size $old_orphan
+check pv_field $dev14 pv_size $old_orphan
+# reset back to old size
+pvresize --setphysicalvolumesize $old_request $dev10 $dev2 $dev3 $dev4 $dev5 $dev6 $dev7 $dev8 $dev9
+pvresize --setphysicalvolumesize $old_request $dev11 $dev14
+
+# one orphan with mda
+pvresize --setphysicalvolumesize $new_request $dev11
+check pv_field $dev11 pv_size $new_orphan
+# unchanged
+check pv_field $dev10 pv_size $old_reduced
+check pv_field $dev2 pv_size $old_reduced
+check pv_field $dev3 pv_size $old_reduced
+check pv_field $dev4 pv_size $old_reduced
+check pv_field $dev5 pv_size $old_reduced
+check pv_field $dev6 pv_size $old_reduced
+check pv_field $dev7 pv_size $old_reduced
+check pv_field $dev8 pv_size $old_reduced
+check pv_field $dev9 pv_size $old_reduced
+check pv_field $dev14 pv_size $old_orphan
+# reset back to old size
+pvresize --setphysicalvolumesize $old_request $dev10 $dev2 $dev3 $dev4 $dev5 $dev6 $dev7 $dev8 $dev9
+pvresize --setphysicalvolumesize $old_request $dev11 $dev14
+
+# one orphan without mda
+pvresize --setphysicalvolumesize $new_request $dev14
+check pv_field $dev14 pv_size $new_orphan
+# unchanged
+check pv_field $dev10 pv_size $old_reduced
+check pv_field $dev2 pv_size $old_reduced
+check pv_field $dev3 pv_size $old_reduced
+check pv_field $dev4 pv_size $old_reduced
+check pv_field $dev5 pv_size $old_reduced
+check pv_field $dev6 pv_size $old_reduced
+check pv_field $dev7 pv_size $old_reduced
+check pv_field $dev8 pv_size $old_reduced
+check pv_field $dev9 pv_size $old_reduced
+check pv_field $dev11 pv_size $old_orphan
+# reset back to old size
+pvresize --setphysicalvolumesize $old_request $dev10 $dev2 $dev3 $dev4 $dev5 $dev6 $dev7 $dev8 $dev9
+pvresize --setphysicalvolumesize $old_request $dev11 $dev14
+
+# one orphan with mda and one orphan without mda
+pvresize --setphysicalvolumesize $new_request $dev14 $dev11
+check pv_field $dev11 pv_size $new_orphan
+check pv_field $dev14 pv_size $new_orphan
+# unchanged
+check pv_field $dev10 pv_size $old_reduced
+check pv_field $dev2 pv_size $old_reduced
+check pv_field $dev3 pv_size $old_reduced
+check pv_field $dev4 pv_size $old_reduced
+check pv_field $dev5 pv_size $old_reduced
+check pv_field $dev6 pv_size $old_reduced
+check pv_field $dev7 pv_size $old_reduced
+check pv_field $dev8 pv_size $old_reduced
+check pv_field $dev9 pv_size $old_reduced
+# reset back to old size
+pvresize --setphysicalvolumesize $old_request $dev10 $dev2 $dev3 $dev4 $dev5 $dev6 $dev7 $dev8 $dev9
+pvresize --setphysicalvolumesize $old_request $dev11 $dev14
+
+# one pv with mda and one pv without mda, and
+# one orphan with mda and one orphan without mda
+pvresize --setphysicalvolumesize $new_request $dev8 $dev9 $dev14 $dev11
+check pv_field $dev8 pv_size $new_reduced
+check pv_field $dev9 pv_size $new_reduced
+check pv_field $dev11 pv_size $new_orphan
+check pv_field $dev14 pv_size $new_orphan
+# unchanged
+check pv_field $dev10 pv_size $old_reduced
+check pv_field $dev2 pv_size $old_reduced
+check pv_field $dev3 pv_size $old_reduced
+check pv_field $dev4 pv_size $old_reduced
+check pv_field $dev5 pv_size $old_reduced
+check pv_field $dev6 pv_size $old_reduced
+check pv_field $dev7 pv_size $old_reduced
+# reset back to old size
+pvresize --setphysicalvolumesize $old_request $dev10 $dev2 $dev3 $dev4 $dev5 $dev6 $dev7 $dev8 $dev9
+pvresize --setphysicalvolumesize $old_request $dev11 $dev14
+
8 years, 11 months
master - metadata: Use flags to control warnings.
by Alasdair Kergon
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=8dc5f42254b319...
Commit: 8dc5f42254b319430d02e2d0ca4cffd36b2cbaca
Parent: e458fc9a6a3a82231367450b5f54f3c12700cd20
Author: David Teigland <teigland(a)redhat.com>
AuthorDate: Tue Oct 7 01:04:09 2014 +0100
Committer: Alasdair G Kergon <agk(a)redhat.com>
CommitterDate: Tue Oct 7 01:15:43 2014 +0100
metadata: Use flags to control warnings.
The warnings arg was used to enable logging of warnings
when reading a PV. This arg is turned into a set of flags
with the WARN_PV_READ flag matching the existing behavior.
A new flag WARN_INCONSISTENT is added that will cause
vg_read_internal() to log the "VG is not consistent"
warning so the various callers do not need to log
this warning themselves.
A new vg_read flag READ_WARN_INCONSISTENT is used from
reporting to enable the WARN_INCONSISTENT flag in
vg_read_internal.
[Committed by agk with cosmetic changes and tweaks.]
---
daemons/clvmd/lvm-functions.c | 2 +-
lib/format_text/import.c | 10 ++--
lib/metadata/metadata-exported.h | 11 ++++-
lib/metadata/metadata.c | 92 +++++++++++++++++++-------------------
tools/toollib.c | 2 +-
5 files changed, 62 insertions(+), 55 deletions(-)
diff --git a/daemons/clvmd/lvm-functions.c b/daemons/clvmd/lvm-functions.c
index f3a56ce..4ebd059 100644
--- a/daemons/clvmd/lvm-functions.c
+++ b/daemons/clvmd/lvm-functions.c
@@ -842,7 +842,7 @@ void lvm_do_backup(const char *vgname)
pthread_mutex_lock(&lvm_lock);
- vg = vg_read_internal(cmd, vgname, NULL /*vgid*/, 1, &consistent);
+ vg = vg_read_internal(cmd, vgname, NULL /*vgid*/, WARN_PV_READ, &consistent);
if (vg && consistent)
check_current_backup(vg);
diff --git a/lib/format_text/import.c b/lib/format_text/import.c
index 1b1f332..4b02264 100644
--- a/lib/format_text/import.c
+++ b/lib/format_text/import.c
@@ -51,8 +51,10 @@ const char *text_vgname_import(const struct format_type *fmt,
if ((!dev && !config_file_read(cft)) ||
(dev && !config_file_read_fd(cft, dev, offset, size,
- offset2, size2, checksum_fn, checksum)))
- goto_out;
+ offset2, size2, checksum_fn, checksum))) {
+ log_error("Couldn't read volume group metadata.");
+ goto out;
+ }
/*
* Find a set of version functions that can read this file
@@ -97,10 +99,8 @@ struct volume_group *text_vg_import_fd(struct format_instance *fid,
if ((!dev && !config_file_read(cft)) ||
(dev && !config_file_read_fd(cft, dev, offset, size,
- offset2, size2, checksum_fn, checksum))) {
- log_error("Couldn't read volume group metadata.");
+ offset2, size2, checksum_fn, checksum)))
goto out;
- }
/*
* Find a set of version functions that can read this file
diff --git a/lib/metadata/metadata-exported.h b/lib/metadata/metadata-exported.h
index 4843d2c..4ab7672 100644
--- a/lib/metadata/metadata-exported.h
+++ b/lib/metadata/metadata-exported.h
@@ -144,6 +144,7 @@
#define READ_ALLOW_INCONSISTENT 0x00010000U
#define READ_ALLOW_EXPORTED 0x00020000U
#define READ_WITHOUT_LOCK 0x00040000U
+#define READ_WARN_INCONSISTENT 0x00080000U
/* A meta-flag, useful with toollib for_each_* functions. */
#define READ_FOR_UPDATE 0x00100000U
@@ -544,13 +545,19 @@ int pvcreate_single(struct cmd_context *cmd, const char *pv_name,
void pvcreate_params_set_defaults(struct pvcreate_params *pp);
/*
+ * Flags that indicate which warnings a library function should issue.
+ */
+#define WARN_PV_READ 0x00000001
+#define WARN_INCONSISTENT 0x00000002
+
+/*
* Utility functions
*/
int vg_write(struct volume_group *vg);
int vg_commit(struct volume_group *vg);
void vg_revert(struct volume_group *vg);
struct volume_group *vg_read_internal(struct cmd_context *cmd, const char *vg_name,
- const char *vgid, int warnings, int *consistent);
+ const char *vgid, uint32_t warn_flags, int *consistent);
#define get_pvs( cmd ) get_pvs_internal((cmd), NULL, NULL)
#define get_pvs_perserve_vg( cmd, pv_list, vg_list ) get_pvs_internal((cmd), (pv_list), (vg_list))
@@ -568,7 +575,7 @@ void lv_set_hidden(struct logical_volume *lv);
struct dm_list *get_vgnames(struct cmd_context *cmd, int include_internal);
struct dm_list *get_vgids(struct cmd_context *cmd, int include_internal);
-int scan_vgs_for_pvs(struct cmd_context *cmd, int warnings);
+int scan_vgs_for_pvs(struct cmd_context *cmd, uint32_t warn_flags);
int pv_write(struct cmd_context *cmd, struct physical_volume *pv, int allow_non_orphan);
int move_pv(struct volume_group *vg_from, struct volume_group *vg_to,
diff --git a/lib/metadata/metadata.c b/lib/metadata/metadata.c
index 6719fe4..8443f94 100644
--- a/lib/metadata/metadata.c
+++ b/lib/metadata/metadata.c
@@ -39,7 +39,7 @@ static struct physical_volume *_pv_read(struct cmd_context *cmd,
struct dm_pool *pvmem,
const char *pv_name,
struct format_instance *fid,
- int warnings, int scan_label_only);
+ uint32_t warn_flags, int scan_label_only);
static uint32_t _vg_bad_status_bits(const struct volume_group *vg,
uint64_t status);
@@ -333,18 +333,15 @@ int get_pv_from_vg_by_id(const struct format_type *fmt, const char *vg_name,
{
struct volume_group *vg;
struct pv_list *pvl;
+ uint32_t warn_flags = WARN_PV_READ | WARN_INCONSISTENT;
int r = 0, consistent = 0;
- if (!(vg = vg_read_internal(fmt->cmd, vg_name, vgid, 1, &consistent))) {
+ if (!(vg = vg_read_internal(fmt->cmd, vg_name, vgid, warn_flags, &consistent))) {
log_error("get_pv_from_vg_by_id: vg_read_internal failed to read VG %s",
vg_name);
return 0;
}
- if (!consistent)
- log_warn("WARNING: Volume group %s is not consistent",
- vg_name);
-
dm_list_iterate_items(pvl, &vg->pvs) {
if (id_equal(&pvl->pv->id, (const struct id *) pvid)) {
if (!_copy_pv(fmt->cmd->mem, pv, pvl->pv)) {
@@ -1045,7 +1042,7 @@ struct volume_group *vg_create(struct cmd_context *cmd, const char *vg_name)
/* FIXME: Is this vg_read_internal necessary? Move it inside
vg_lock_newname? */
/* is this vg name already in use ? */
- if ((vg = vg_read_internal(cmd, vg_name, NULL, 1, &consistent))) {
+ if ((vg = vg_read_internal(cmd, vg_name, NULL, WARN_PV_READ, &consistent))) {
log_error("A volume group called '%s' already exists.", vg_name);
unlock_and_release_vg(cmd, vg, vg_name);
return _vg_make_handle(cmd, NULL, FAILED_EXIST);
@@ -2909,7 +2906,7 @@ void vg_revert(struct volume_group *vg)
struct _vg_read_orphan_baton {
struct volume_group *vg;
- int warnings;
+ uint32_t warn_flags;
};
static int _vg_read_orphan_pv(struct lvmcache_info *info, void *baton)
@@ -2919,7 +2916,7 @@ static int _vg_read_orphan_pv(struct lvmcache_info *info, void *baton)
struct pv_list *pvl;
if (!(pv = _pv_read(b->vg->cmd, b->vg->vgmem, dev_name(lvmcache_device(info)),
- b->vg->fid, b->warnings, 0))) {
+ b->vg->fid, b->warn_flags, 0))) {
stack;
return 1;
}
@@ -2936,7 +2933,7 @@ static int _vg_read_orphan_pv(struct lvmcache_info *info, void *baton)
/* Make orphan PVs look like a VG. */
static struct volume_group *_vg_read_orphans(struct cmd_context *cmd,
- int warnings,
+ uint32_t warn_flags,
const char *orphan_vgname)
{
const struct format_type *fmt;
@@ -2969,7 +2966,7 @@ static struct volume_group *_vg_read_orphans(struct cmd_context *cmd,
vg->extent_count = 0;
vg->free_count = 0;
- baton.warnings = warnings;
+ baton.warn_flags = warn_flags;
baton.vg = vg;
while ((pvl = (struct pv_list *) dm_list_first(&head.list))) {
@@ -3118,7 +3115,7 @@ static int _check_mda_in_use(struct metadata_area *mda, void *_in_use)
static struct volume_group *_vg_read(struct cmd_context *cmd,
const char *vgname,
const char *vgid,
- int warnings,
+ uint32_t warn_flags,
int *consistent, unsigned precommitted)
{
struct format_instance *fid = NULL;
@@ -3147,7 +3144,7 @@ static struct volume_group *_vg_read(struct cmd_context *cmd,
return NULL;
}
*consistent = 1;
- return _vg_read_orphans(cmd, warnings, vgname);
+ return _vg_read_orphans(cmd, warn_flags, vgname);
}
if (lvmetad_active() && !use_precommitted) {
@@ -3584,19 +3581,20 @@ static struct volume_group *_vg_read(struct cmd_context *cmd,
}
struct volume_group *vg_read_internal(struct cmd_context *cmd, const char *vgname,
- const char *vgid, int warnings, int *consistent)
+ const char *vgid, uint32_t warn_flags, int *consistent)
{
struct volume_group *vg;
struct lv_list *lvl;
- if (!(vg = _vg_read(cmd, vgname, vgid, warnings, consistent, 0)))
- return NULL;
+ if (!(vg = _vg_read(cmd, vgname, vgid, warn_flags, consistent, 0)))
+ goto_out;
if (!check_pv_segments(vg)) {
log_error(INTERNAL_ERROR "PV segments corrupted in %s.",
vg->name);
release_vg(vg);
- return NULL;
+ vg = NULL;
+ goto out;
}
dm_list_iterate_items(lvl, &vg->lvs) {
@@ -3604,7 +3602,8 @@ struct volume_group *vg_read_internal(struct cmd_context *cmd, const char *vgnam
log_error(INTERNAL_ERROR "LV segments corrupted in %s.",
lvl->lv->name);
release_vg(vg);
- return NULL;
+ vg = NULL;
+ goto out;
}
}
@@ -3616,10 +3615,15 @@ struct volume_group *vg_read_internal(struct cmd_context *cmd, const char *vgnam
log_error(INTERNAL_ERROR "LV segments corrupted in %s.",
lvl->lv->name);
release_vg(vg);
- return NULL;
+ vg = NULL;
+ goto out;
}
}
+out:
+ if (!*consistent && (warn_flags & WARN_INCONSISTENT))
+ log_warn("WARNING: Volume Group %s is not consistent", vgname);
+
return vg;
}
@@ -3643,16 +3647,13 @@ static struct volume_group *_vg_read_by_vgid(struct cmd_context *cmd,
struct dm_list *vgnames;
struct volume_group *vg;
struct dm_str_list *strl;
+ uint32_t warn_flags = WARN_PV_READ | WARN_INCONSISTENT;
int consistent = 0;
/* Is corresponding vgname already cached? */
if (lvmcache_vgid_is_cached(vgid)) {
- if ((vg = _vg_read(cmd, NULL, vgid, 1,
- &consistent, precommitted)) &&
+ if ((vg = _vg_read(cmd, NULL, vgid, warn_flags, &consistent, precommitted)) &&
id_equal(&vg->id, (const struct id *)vgid)) {
- if (!consistent)
- log_error("Volume group %s metadata is "
- "inconsistent", vg->name);
return vg;
}
release_vg(vg);
@@ -3678,12 +3679,9 @@ static struct volume_group *_vg_read_by_vgid(struct cmd_context *cmd,
if (!vgname)
continue; // FIXME Unnecessary?
consistent = 0;
- if ((vg = _vg_read(cmd, vgname, vgid, 1, &consistent,
- precommitted)) &&
+ if ((vg = _vg_read(cmd, vgname, vgid, warn_flags, &consistent, precommitted)) &&
id_equal(&vg->id, (const struct id *)vgid)) {
if (!consistent) {
- log_error("Volume group %s metadata is "
- "inconsistent", vgname);
release_vg(vg);
return NULL;
}
@@ -3747,7 +3745,7 @@ const char *find_vgname_from_pvid(struct cmd_context *cmd,
* every PV on the system.
*/
if (lvmcache_uncertain_ownership(info)) {
- if (!scan_vgs_for_pvs(cmd, 1)) {
+ if (!scan_vgs_for_pvs(cmd, WARN_PV_READ)) {
log_error("Rescan for PVs without "
"metadata areas failed.");
return NULL;
@@ -3781,7 +3779,7 @@ static struct physical_volume *_pv_read(struct cmd_context *cmd,
struct dm_pool *pvmem,
const char *pv_name,
struct format_instance *fid,
- int warnings, int scan_label_only)
+ uint32_t warn_flags, int scan_label_only)
{
struct physical_volume *pv;
struct label *label;
@@ -3799,13 +3797,13 @@ static struct physical_volume *_pv_read(struct cmd_context *cmd,
if (!lvmetad_pv_lookup_by_dev(cmd, dev, &found))
return_NULL;
if (!found) {
- if (warnings)
+ if (warn_flags & WARN_PV_READ)
log_error("No physical volume found in lvmetad cache for %s",
pv_name);
return NULL;
}
if (!(info = lvmcache_info_from_pvid(dev->pvid, 0))) {
- if (warnings)
+ if (warn_flags & WARN_PV_READ)
log_error("No cache info in lvmetad cache for %s.",
pv_name);
return NULL;
@@ -3814,7 +3812,7 @@ static struct physical_volume *_pv_read(struct cmd_context *cmd,
label = lvmcache_get_label(info);
} else {
if (!(label_read(dev, &label, UINT64_C(0)))) {
- if (warnings)
+ if (warn_flags & WARN_PV_READ)
log_error("No physical volume label read from %s",
pv_name);
return NULL;
@@ -3870,7 +3868,7 @@ struct dm_list *get_vgids(struct cmd_context *cmd, int include_internal)
return lvmcache_get_vgids(cmd, include_internal);
}
-static int _get_pvs(struct cmd_context *cmd, int warnings,
+static int _get_pvs(struct cmd_context *cmd, uint32_t warn_flags,
struct dm_list *pvslist, struct dm_list *vgslist)
{
struct dm_str_list *strl;
@@ -3913,13 +3911,13 @@ static int _get_pvs(struct cmd_context *cmd, int warnings,
* vgid will be NULL.
* FIXME Remove this hack.
*/
- if (!(vg = vg_read_internal(cmd, vgname, (!vgslist) ? vgid : NULL, warnings, &consistent))) {
+
+ warn_flags |= WARN_INCONSISTENT;
+
+ if (!(vg = vg_read_internal(cmd, vgname, (!vgslist) ? vgid : NULL, warn_flags, &consistent))) {
stack;
continue;
}
- if (!consistent)
- log_warn("WARNING: Volume Group %s is not consistent",
- vgname);
/* Move PVs onto results list */
if (pvslist)
@@ -4001,7 +3999,7 @@ struct dm_list *get_pvs_internal(struct cmd_context *cmd,
dm_list_init(results);
}
- if (!_get_pvs(cmd, 1, results, vgslist)) {
+ if (!_get_pvs(cmd, WARN_PV_READ, results, vgslist)) {
if (!pvslist)
dm_pool_free(cmd->mem, results);
return NULL;
@@ -4009,9 +4007,9 @@ struct dm_list *get_pvs_internal(struct cmd_context *cmd,
return results;
}
-int scan_vgs_for_pvs(struct cmd_context *cmd, int warnings)
+int scan_vgs_for_pvs(struct cmd_context *cmd, uint32_t warn_flags)
{
- return _get_pvs(cmd, warnings, NULL, NULL);
+ return _get_pvs(cmd, warn_flags, NULL, NULL);
}
int pv_write(struct cmd_context *cmd __attribute__((unused)),
@@ -4217,7 +4215,7 @@ static struct volume_group *_recover_vg(struct cmd_context *cmd,
if (!lock_vol(cmd, vg_name, LCK_VG_WRITE, NULL))
return_NULL;
- if (!(vg = vg_read_internal(cmd, vg_name, vgid, 1, &consistent))) {
+ if (!(vg = vg_read_internal(cmd, vg_name, vgid, WARN_PV_READ, &consistent))) {
unlock_vg(cmd, vg_name);
return_NULL;
}
@@ -4250,6 +4248,7 @@ static struct volume_group *_vg_lock_and_read(struct cmd_context *cmd, const cha
int consistent = 1;
int consistent_in;
uint32_t failure = 0;
+ uint32_t warn_flags = 0;
int already_locked;
if (misc_flags & READ_ALLOW_INCONSISTENT || lock_flags != LCK_VG_WRITE)
@@ -4274,16 +4273,17 @@ static struct volume_group *_vg_lock_and_read(struct cmd_context *cmd, const cha
consistent_in = consistent;
+ warn_flags = WARN_PV_READ;
+ if (consistent || (misc_flags & READ_WARN_INCONSISTENT))
+ warn_flags |= WARN_INCONSISTENT;
+
/* If consistent == 1, we get NULL here if correction fails. */
- if (!(vg = vg_read_internal(cmd, vg_name, vgid, 1, &consistent))) {
+ if (!(vg = vg_read_internal(cmd, vg_name, vgid, warn_flags, &consistent))) {
if (consistent_in && !consistent) {
- log_error("Volume group \"%s\" inconsistent.", vg_name);
failure |= FAILED_INCONSISTENT;
goto bad;
}
-
log_error("Volume group \"%s\" not found", vg_name);
-
failure |= FAILED_NOTFOUND;
goto bad;
}
diff --git a/tools/toollib.c b/tools/toollib.c
index 16aeaa2..1ee8469 100644
--- a/tools/toollib.c
+++ b/tools/toollib.c
@@ -2136,7 +2136,7 @@ static int _process_pvs_in_vgs(struct cmd_context *cmd, uint32_t flags,
ret = 0;
skip = 0;
- vg = vg_read(cmd, vg_name, vg_uuid, flags);
+ vg = vg_read(cmd, vg_name, vg_uuid, flags | READ_WARN_INCONSISTENT);
if (ignore_vg(vg, vg_name, flags & READ_ALLOW_INCONSISTENT, &ret)) {
if (ret > ret_max)
ret_max = ret;
8 years, 11 months
master - vgreduce: Use process_each_pv.
by Alasdair Kergon
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=e458fc9a6a3a82...
Commit: e458fc9a6a3a82231367450b5f54f3c12700cd20
Parent: f1a000a477558e157532d5f2cd2f9c9139d4f87c
Author: David Teigland <teigland(a)redhat.com>
AuthorDate: Tue Oct 7 00:53:56 2014 +0100
Committer: Alasdair G Kergon <agk(a)redhat.com>
CommitterDate: Tue Oct 7 01:15:43 2014 +0100
vgreduce: Use process_each_pv.
Adapt process_each_pv for use by vgreduce in the non-repair case.
[Committed by agk with cosmetic changes and tweaks.]
---
tools/toollib.c | 51 +++++++++++-------------
tools/toollib.h | 2 +-
tools/vgreduce.c | 116 +++++++++++++++++++++++++----------------------------
3 files changed, 79 insertions(+), 90 deletions(-)
diff --git a/tools/toollib.c b/tools/toollib.c
index b65351e..16aeaa2 100644
--- a/tools/toollib.c
+++ b/tools/toollib.c
@@ -1373,13 +1373,27 @@ static int _get_arg_vgnames(struct cmd_context *cmd,
*/
static int _get_vgnameids_on_system(struct cmd_context *cmd,
struct dm_list *vgnameids_on_system,
- int include_internal)
+ const char *only_this_vgname, int include_internal)
{
struct vgnameid_list *vgnl;
struct dm_list *vgids;
struct dm_str_list *sl;
const char *vgid;
+ if (only_this_vgname) {
+ vgnl = dm_pool_alloc(cmd->mem, sizeof(*vgnl));
+ if (!vgnl) {
+ log_error("name_id_list allocation failed");
+ return ECMD_FAILED;
+ }
+
+ vgnl->vg_name = dm_pool_strdup(cmd->mem, only_this_vgname);
+ vgnl->vgid = NULL;
+
+ dm_list_add(vgnameids_on_system, &vgnl->list);
+ return ECMD_PROCESSED;
+ }
+
log_verbose("Finding all volume groups");
if (!lvmetad_vg_list_to_lvmcache(cmd))
@@ -1530,7 +1544,7 @@ int process_each_vg(struct cmd_context *cmd, int argc, char **argv,
* no VG names were given and the command defaults to processing all VGs.
*/
if (((dm_list_empty(&arg_vgnames) && enable_all_vgs) || !dm_list_empty(&arg_tags)) &&
- ((ret = _get_vgnameids_on_system(cmd, &vgnameids_on_system, 0)) != ECMD_PROCESSED)) {
+ ((ret = _get_vgnameids_on_system(cmd, &vgnameids_on_system, NULL, 0)) != ECMD_PROCESSED)) {
stack;
return ret;
}
@@ -1864,7 +1878,7 @@ int process_each_lv(struct cmd_context *cmd, int argc, char **argv, uint32_t fla
* no VG names were given and the command defaults to processing all VGs.
*/
if (((dm_list_empty(&arg_vgnames) && enable_all_vgs) || !dm_list_empty(&arg_tags)) &&
- (ret = _get_vgnameids_on_system(cmd, &vgnameids_on_system, 0) != ECMD_PROCESSED)) {
+ (ret = _get_vgnameids_on_system(cmd, &vgnameids_on_system, NULL, 0) != ECMD_PROCESSED)) {
stack;
return ret;
}
@@ -2159,16 +2173,15 @@ static int _process_pvs_in_vgs(struct cmd_context *cmd, uint32_t flags,
int process_each_pv(struct cmd_context *cmd,
int argc, char **argv,
- struct volume_group *vg,
+ const char *only_this_vgname,
uint32_t flags,
void *handle,
process_single_pv_fn_t process_single_pv)
{
- struct dm_list arg_tags; /* str_list */
- struct dm_list arg_pvnames; /* str_list */
- struct dm_list all_vgnameids; /* vgnameid_list */
- struct dm_list all_devices; /* device_list */
- struct dm_str_list *sl;
+ struct dm_list arg_tags; /* str_list */
+ struct dm_list arg_pvnames; /* str_list */
+ struct dm_list all_vgnameids; /* vgnameid_list */
+ struct dm_list all_devices; /* device_list */
int process_all_pvs;
int process_all_devices;
int ret_max = ECMD_PROCESSED;
@@ -2194,24 +2207,6 @@ int process_each_pv(struct cmd_context *cmd,
arg_count(cmd, all_ARG);
/*
- * If vg is set, the caller already selected, locked, and read one
- * VG. This code is unused.
- */
- if (vg) {
- ret = _process_pvs_in_vg(cmd, vg, NULL,
- &arg_pvnames, &arg_tags, process_all_pvs, 0,
- handle, process_single_pv);
-
- dm_list_iterate_items(sl, &arg_pvnames) {
- log_error("Physical Volume \"%s\" not found in Volume Group \"%s\"",
- sl->str, vg->name);
- ret = ECMD_FAILED;
- }
-
- return ret;
- }
-
- /*
* If the caller wants to process all devices (not just PVs), then all PVs
* from all VGs are processed first, removing them from all_devices. Then
* any devs remaining in all_devices are processed.
@@ -2221,7 +2216,7 @@ int process_each_pv(struct cmd_context *cmd,
return ret;
}
- if ((ret = _get_vgnameids_on_system(cmd, &all_vgnameids, 1) != ECMD_PROCESSED)) {
+ if ((ret = _get_vgnameids_on_system(cmd, &all_vgnameids, only_this_vgname, 1) != ECMD_PROCESSED)) {
stack;
return ret;
}
diff --git a/tools/toollib.h b/tools/toollib.h
index 483ac68..5b42f28 100644
--- a/tools/toollib.h
+++ b/tools/toollib.h
@@ -49,7 +49,7 @@ int process_each_vg(struct cmd_context *cmd, int argc, char **argv,
process_single_vg_fn_t process_single_vg);
int process_each_pv(struct cmd_context *cmd, int argc, char **argv,
- struct volume_group *vg, uint32_t lock_type,
+ const char *vg_name, uint32_t lock_type,
void *handle, process_single_pv_fn_t process_single_pv);
int process_each_label(struct cmd_context *cmd, int argc, char **argv,
diff --git a/tools/vgreduce.c b/tools/vgreduce.c
index 493a084..7af5a76 100644
--- a/tools/vgreduce.c
+++ b/tools/vgreduce.c
@@ -125,16 +125,18 @@ static int _vgreduce_single(struct cmd_context *cmd, struct volume_group *vg,
struct physical_volume *pv,
void *handle __attribute__((unused)))
{
- int r = vgreduce_single(cmd, vg, pv, 1);
+ int r;
+ if (!vg_check_status(vg, EXPORTED_VG | LVM_WRITE | RESIZEABLE_VG))
+ return ECMD_FAILED;
+
+ r = vgreduce_single(cmd, vg, pv, 1);
if (!r)
return ECMD_FAILED;
return ECMD_PROCESSED;
}
-
-
int vgreduce(struct cmd_context *cmd, int argc, char **argv)
{
struct volume_group *vg;
@@ -181,12 +183,17 @@ int vgreduce(struct cmd_context *cmd, int argc, char **argv)
argv++;
argc--;
+ if (!repairing)
+ /* FIXME: Pass private struct through to all these functions */
+ /* and update in batch afterwards? */
+ return process_each_pv(cmd, argc, argv, vg_name,
+ READ_FOR_UPDATE, NULL,
+ _vgreduce_single);
+
log_verbose("Finding volume group \"%s\"", vg_name);
- if (repairing) {
- init_ignore_suspended_devices(1);
- cmd->handles_missing_pvs = 1;
- }
+ init_ignore_suspended_devices(1);
+ cmd->handles_missing_pvs = 1;
vg = vg_read_for_update(cmd, vg_name, NULL, READ_ALLOW_EXPORTED);
if (vg_read_error(vg) == FAILED_ALLOCATION ||
@@ -194,65 +201,54 @@ int vgreduce(struct cmd_context *cmd, int argc, char **argv)
goto_out;
/* FIXME We want to allow read-only VGs to be changed here? */
- if (vg_read_error(vg) && vg_read_error(vg) != FAILED_READ_ONLY
- && !arg_count(cmd, removemissing_ARG))
+ if (vg_read_error(vg) &&
+ (vg_read_error(vg) != FAILED_READ_ONLY) &&
+ !arg_count(cmd, removemissing_ARG))
goto_out;
locked = !vg_read_error(vg);
- if (repairing) {
- if (!vg_read_error(vg) && !vg_missing_pv_count(vg)) {
- log_error("Volume group \"%s\" is already consistent",
- vg_name);
- ret = ECMD_PROCESSED;
- goto out;
- }
+ if (!vg_read_error(vg) && !vg_missing_pv_count(vg)) {
+ log_error("Volume group \"%s\" is already consistent", vg_name);
+ ret = ECMD_PROCESSED;
+ goto out;
+ }
- release_vg(vg);
- log_verbose("Trying to open VG %s for recovery...", vg_name);
+ release_vg(vg);
+ log_verbose("Trying to open VG %s for recovery...", vg_name);
- vg = vg_read_for_update(cmd, vg_name, NULL,
- READ_ALLOW_INCONSISTENT
- | READ_ALLOW_EXPORTED);
+ vg = vg_read_for_update(cmd, vg_name, NULL,
+ READ_ALLOW_INCONSISTENT | READ_ALLOW_EXPORTED);
- locked |= !vg_read_error(vg);
- if (vg_read_error(vg) && vg_read_error(vg) != FAILED_READ_ONLY
- && vg_read_error(vg) != FAILED_INCONSISTENT)
- goto_out;
+ locked |= !vg_read_error(vg);
- if (!archive(vg))
- goto_out;
+ if (vg_read_error(vg) &&
+ (vg_read_error(vg) != FAILED_READ_ONLY) &&
+ (vg_read_error(vg) != FAILED_INCONSISTENT))
+ goto_out;
- if (arg_count(cmd, force_ARG)) {
- if (!_make_vg_consistent(cmd, vg))
- goto_out;
- } else
- fixed = _consolidate_vg(cmd, vg);
+ if (!archive(vg))
+ goto_out;
- if (!vg_write(vg) || !vg_commit(vg)) {
- log_error("Failed to write out a consistent VG for %s",
- vg_name);
- goto out;
- }
- backup(vg);
+ if (arg_count(cmd, force_ARG)) {
+ if (!_make_vg_consistent(cmd, vg))
+ goto_out;
+ } else
+ fixed = _consolidate_vg(cmd, vg);
- if (fixed) {
- log_print_unless_silent("Wrote out consistent volume group %s",
- vg_name);
- ret = ECMD_PROCESSED;
- } else
- ret = ECMD_FAILED;
+ if (!vg_write(vg) || !vg_commit(vg)) {
+ log_error("Failed to write out a consistent VG for %s", vg_name);
+ goto out;
+ }
- } else {
- if (!vg_check_status(vg, EXPORTED_VG | LVM_WRITE | RESIZEABLE_VG))
- goto_out;
+ backup(vg);
- /* FIXME: Pass private struct through to all these functions */
- /* and update in batch here? */
- ret = process_each_pv(cmd, argc, argv, vg, READ_FOR_UPDATE, NULL,
- _vgreduce_single);
+ if (fixed) {
+ log_print_unless_silent("Wrote out consistent volume group %s", vg_name);
+ ret = ECMD_PROCESSED;
+ } else
+ ret = ECMD_FAILED;
- }
out:
init_ignore_suspended_devices(saved_ignore_suspended_devices);
if (locked)
@@ -265,16 +261,14 @@ out:
/******* FIXME
log_error ("no empty physical volumes found in volume group \"%s\"", vg_name);
- log_verbose
- ("volume group \"%s\" will be reduced by %d physical volume%s",
- vg_name, np, np > 1 ? "s" : "");
- log_verbose ("reducing volume group \"%s\" by physical volume \"%s\"",
- vg_name, pv_names[p]);
+ log_verbose("volume group \"%s\" will be reduced by %d physical volume%s",
+ vg_name, np, np > 1 ? "s" : "");
+ log_verbose("reducing volume group \"%s\" by physical volume \"%s\"",
+ vg_name, pv_names[p]);
- log_print
- ("volume group \"%s\" %ssuccessfully reduced by physical volume%s:",
- vg_name, error > 0 ? "NOT " : "", p > 1 ? "s" : "");
- log_print("%s", pv_this[p]->pv_name);
+ log_print("volume group \"%s\" %ssuccessfully reduced by physical volume%s:",
+ vg_name, error > 0 ? "NOT " : "", p > 1 ? "s" : "");
+ log_print("%s", pv_this[p]->pv_name);
********/
}
8 years, 11 months
master - toollib: Rewrite process_each_pv.
by Alasdair Kergon
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=f1a000a477558e...
Commit: f1a000a477558e157532d5f2cd2f9c9139d4f87c
Parent: aeb4d3b740434ed04993e9e7ef74f6e3462efb50
Author: David Teigland <teigland(a)redhat.com>
AuthorDate: Tue Oct 7 00:34:04 2014 +0100
Committer: Alasdair G Kergon <agk(a)redhat.com>
CommitterDate: Tue Oct 7 01:15:43 2014 +0100
toollib: Rewrite process_each_pv.
Process PVs by iterating through VGs, then iterating through
devices if the command needs to process non-PV devices.
The process_single function can always use the VG and PV args.
[Committed by agk with cosmetic changes and tweaks.]
---
lib/metadata/pv_manip.c | 22 --
lib/report/report.c | 8 +-
tools/pvdisplay.c | 59 +++----
tools/pvresize.c | 2 +-
tools/reporter.c | 83 +++------
tools/toollib.c | 505 ++++++++++++++++++++++++++++++-----------------
tools/toollib.h | 6 +-
tools/vgdisplay.c | 2 +-
tools/vgreduce.c | 2 +-
9 files changed, 379 insertions(+), 310 deletions(-)
diff --git a/lib/metadata/pv_manip.c b/lib/metadata/pv_manip.c
index 2cc7892..9a0f287 100644
--- a/lib/metadata/pv_manip.c
+++ b/lib/metadata/pv_manip.c
@@ -615,31 +615,12 @@ int pv_resize_single(struct cmd_context *cmd,
struct physical_volume *pv,
const uint64_t new_size)
{
- struct pv_list *pvl;
uint64_t size = 0;
int r = 0;
const char *pv_name = pv_dev_name(pv);
const char *vg_name = pv->vg_name;
- struct volume_group *old_vg = vg;
int vg_needs_pv_write = 0;
- vg = vg_read_for_update(cmd, vg_name, NULL, 0);
-
- if (vg_read_error(vg)) {
- release_vg(vg);
- log_error("Unable to read volume group \"%s\".",
- vg_name);
- return 0;
- }
-
- if (!(pvl = find_pv_in_vg(vg, pv_name))) {
- log_error("Unable to find \"%s\" in volume group \"%s\"",
- pv_name, vg->name);
- goto out;
- }
-
- pv = pvl->pv;
-
if (!archive(vg))
goto out;
@@ -698,9 +679,6 @@ out:
if (!r && vg_needs_pv_write)
log_error("Use pvcreate and vgcfgrestore "
"to repair from archived metadata.");
- unlock_vg(cmd, vg_name);
- if (!old_vg)
- release_vg(vg);
return r;
}
diff --git a/lib/report/report.c b/lib/report/report.c
index 69f75ed..3f63e1c 100644
--- a/lib/report/report.c
+++ b/lib/report/report.c
@@ -272,7 +272,7 @@ static int _vgfmt_disp(struct dm_report *rh, struct dm_pool *mem,
{
const struct volume_group *vg = (const struct volume_group *) data;
- if (vg->fid)
+ if (vg->fid && vg->fid->fmt)
return _string_disp(rh, mem, field, &vg->fid->fmt->name, private);
return _field_set_value(field, "", NULL);
@@ -1880,8 +1880,12 @@ int report_object(void *handle, struct volume_group *vg,
obj.label = &dummy_label;
}
+ /* Never report orphan VGs. */
+ if (vg && is_orphan_vg(vg->name))
+ obj.vg = NULL;
+
/* The two format fields might as well match. */
- if (!vg && pv)
+ if (!obj.vg && pv)
_dummy_fid.fmt = pv->fmt;
return dm_report_object(handle, &obj);
diff --git a/tools/pvdisplay.c b/tools/pvdisplay.c
index 773d9a9..d4cb516 100644
--- a/tools/pvdisplay.c
+++ b/tools/pvdisplay.c
@@ -19,36 +19,9 @@ static int _pvdisplay_single(struct cmd_context *cmd,
struct volume_group *vg,
struct physical_volume *pv, void *handle)
{
- struct pv_list *pvl;
+ const char *pv_name = pv_dev_name(pv);
int ret = ECMD_PROCESSED;
uint64_t size;
- struct volume_group *old_vg = vg;
-
- const char *pv_name = pv_dev_name(pv);
- const char *vg_name = NULL;
-
- if (!is_orphan(pv) && !vg) {
- vg_name = pv_vg_name(pv);
- vg = vg_read(cmd, vg_name, (char *)&pv->vgid, 0);
- if (ignore_vg(vg, vg_name, 0, &ret)) {
- release_vg(vg);
- stack;
- return ret;
- }
-
- /*
- * Replace possibly incomplete PV structure with new one
- * allocated in vg_read_internal() path.
- */
- if (!(pvl = find_pv_in_vg(vg, pv_name))) {
- log_error("Unable to find \"%s\" in volume group \"%s\"",
- pv_name, vg->name);
- ret = ECMD_FAILED;
- goto out;
- }
-
- pv = pvl->pv;
- }
if (is_orphan(pv))
size = pv_size(pv);
@@ -81,16 +54,14 @@ static int _pvdisplay_single(struct cmd_context *cmd,
pvdisplay_segments(pv);
out:
- if (vg_name)
- unlock_vg(cmd, vg_name);
- if (!old_vg)
- release_vg(vg);
-
return ret;
}
int pvdisplay(struct cmd_context *cmd, int argc, char **argv)
{
+ int lock_global = 0;
+ int ret;
+
if (arg_count(cmd, columns_ARG)) {
if (arg_count(cmd, colon_ARG) || arg_count(cmd, maps_ARG) ||
arg_count(cmd, short_ARG)) {
@@ -122,6 +93,24 @@ int pvdisplay(struct cmd_context *cmd, int argc, char **argv)
return EINVALID_CMD_LINE;
}
- return process_each_pv(cmd, argc, argv, NULL, 0, 0, NULL,
- _pvdisplay_single);
+ /*
+ * If the lock_type is LCK_VG_READ (used only in reporting commands),
+ * we lock VG_GLOBAL to enable use of metadata cache.
+ * This can pause alongide pvscan or vgscan process for a while.
+ */
+ if (!lvmetad_active()) {
+ lock_global = 1;
+ if (!lock_vol(cmd, VG_GLOBAL, LCK_VG_READ, NULL)) {
+ log_error("Unable to obtain global lock.");
+ return ECMD_FAILED;
+ }
+ }
+
+ ret = process_each_pv(cmd, argc, argv, NULL, 0, NULL,
+ _pvdisplay_single);
+
+ if (lock_global)
+ unlock_vg(cmd, VG_GLOBAL);
+
+ return ret;
}
diff --git a/tools/pvresize.c b/tools/pvresize.c
index 1bb8a15..70b564d 100644
--- a/tools/pvresize.c
+++ b/tools/pvresize.c
@@ -61,7 +61,7 @@ int pvresize(struct cmd_context *cmd, int argc, char **argv)
params.done = 0;
params.total = 0;
- ret = process_each_pv(cmd, argc, argv, NULL, READ_FOR_UPDATE, 0, ¶ms,
+ ret = process_each_pv(cmd, argc, argv, NULL, READ_FOR_UPDATE, ¶ms,
_pvresize_single);
log_print_unless_silent("%d physical volume(s) resized / %d physical volume(s) "
diff --git a/tools/reporter.c b/tools/reporter.c
index 462ca8a..c55d653 100644
--- a/tools/reporter.c
+++ b/tools/reporter.c
@@ -209,61 +209,10 @@ static int _pvsegs_with_lv_info_single(struct cmd_context *cmd,
static int _pvs_single(struct cmd_context *cmd, struct volume_group *vg,
struct physical_volume *pv, void *handle)
{
- struct pv_list *pvl;
- int ret = ECMD_PROCESSED;
- const char *vg_name = NULL;
- struct volume_group *old_vg = vg;
- char uuid[64] __attribute__((aligned(8)));
-
- if (is_pv(pv) && !is_orphan(pv) && !vg) {
- vg_name = pv_vg_name(pv);
-
- vg = vg_read(cmd, vg_name, (char *)&pv->vgid, 0);
- if (ignore_vg(vg, vg_name, 0, &ret)) {
- release_vg(vg);
- stack;
- return ret;
- }
-
- /*
- * Replace possibly incomplete PV structure with new one
- * allocated in vg_read.
- */
- if (!is_missing_pv(pv)) {
- if (!(pvl = find_pv_in_vg(vg, pv_dev_name(pv)))) {
- log_error("Unable to find \"%s\" in volume group \"%s\"",
- pv_dev_name(pv), vg->name);
- ret = ECMD_FAILED;
- goto out;
- }
- } else if (!(pvl = find_pv_in_vg_by_uuid(vg, &pv->id))) {
- if (!id_write_format(&pv->id, uuid, sizeof(uuid))) {
- stack;
- uuid[0] = '\0';
- }
-
- log_error("Unable to find missing PV %s in volume group %s",
- uuid, vg->name);
- ret = ECMD_FAILED;
- goto out;
- }
-
- pv = pvl->pv;
- }
-
- if (!report_object(handle, vg, NULL, pv, NULL, NULL, NULL, NULL)) {
- stack;
- ret = ECMD_FAILED;
- }
-
-out:
- if (vg_name)
- unlock_vg(cmd, vg_name);
-
- if (!old_vg)
- release_vg(vg);
+ if (!report_object(handle, vg, NULL, pv, NULL, NULL, NULL, NULL))
+ return_ECMD_FAILED;
- return ret;
+ return ECMD_PROCESSED;
}
static int _label_single(struct cmd_context *cmd, struct label *label,
@@ -286,7 +235,7 @@ static int _pvs_in_vg(struct cmd_context *cmd, const char *vg_name,
return ret;
}
- return process_each_pv_in_vg(cmd, vg, NULL, handle, &_pvs_single);
+ return process_each_pv_in_vg(cmd, vg, handle, &_pvs_single);
}
static int _pvsegs_in_vg(struct cmd_context *cmd, const char *vg_name,
@@ -300,7 +249,7 @@ static int _pvsegs_in_vg(struct cmd_context *cmd, const char *vg_name,
return ret;
}
- return process_each_pv_in_vg(cmd, vg, NULL, handle, &_pvsegs_single);
+ return process_each_pv_in_vg(cmd, vg, handle, &_pvsegs_single);
}
static int _report(struct cmd_context *cmd, int argc, char **argv,
@@ -314,6 +263,7 @@ static int _report(struct cmd_context *cmd, int argc, char **argv,
int aligned, buffered, headings, field_prefixes, quoted;
int columns_as_rows;
unsigned args_are_pvs, lv_info_needed;
+ int lock_global = 0;
aligned = find_config_tree_bool(cmd, report_aligned_CFG, NULL);
buffered = find_config_tree_bool(cmd, report_buffered_CFG, NULL);
@@ -460,6 +410,19 @@ static int _report(struct cmd_context *cmd, int argc, char **argv,
else if (report_type & LVS)
report_type = LVS;
+ /*
+ * We lock VG_GLOBAL to enable use of metadata cache.
+ * This can pause alongide pvscan or vgscan process for a while.
+ */
+ if (args_are_pvs && (report_type == PVS || report_type == PVSEGS) &&
+ !lvmetad_active()) {
+ lock_global = 1;
+ if (!lock_vol(cmd, VG_GLOBAL, LCK_VG_READ, NULL)) {
+ log_error("Unable to obtain global lock.");
+ return ECMD_FAILED;
+ }
+ }
+
switch (report_type) {
case DEVTYPES:
r = _process_each_devtype(cmd, argc, report_handle);
@@ -483,7 +446,7 @@ static int _report(struct cmd_context *cmd, int argc, char **argv,
case PVS:
if (args_are_pvs)
r = process_each_pv(cmd, argc, argv, NULL, 0,
- 0, report_handle, &_pvs_single);
+ report_handle, &_pvs_single);
else
r = process_each_vg(cmd, argc, argv, 0,
report_handle, &_pvs_in_vg);
@@ -496,7 +459,7 @@ static int _report(struct cmd_context *cmd, int argc, char **argv,
case PVSEGS:
if (args_are_pvs)
r = process_each_pv(cmd, argc, argv, NULL, 0,
- 0, report_handle,
+ report_handle,
lv_info_needed ? &_pvsegs_with_lv_info_single
: &_pvsegs_single);
else
@@ -508,6 +471,10 @@ static int _report(struct cmd_context *cmd, int argc, char **argv,
dm_report_output(report_handle);
dm_report_free(report_handle);
+
+ if (lock_global)
+ unlock_vg(cmd, VG_GLOBAL);
+
return r;
}
diff --git a/tools/toollib.c b/tools/toollib.c
index 4b0ba22..b65351e 100644
--- a/tools/toollib.c
+++ b/tools/toollib.c
@@ -359,8 +359,8 @@ static int _add_pe_range(struct dm_pool *mem, const char *pvname,
/* Ensure no overlap with existing areas */
dm_list_iterate_items(per, pe_ranges) {
- if (((start < per->start) && (start + count - 1 >= per->start))
- || ((start >= per->start) &&
+ if (((start < per->start) && (start + count - 1 >= per->start)) ||
+ ((start >= per->start) &&
(per->start + per->count - 1) >= start)) {
log_error("Overlapping PE ranges specified (%" PRIu32
"-%" PRIu32 ", %" PRIu32 "-%" PRIu32 ")"
@@ -383,14 +383,16 @@ static int _add_pe_range(struct dm_pool *mem, const char *pvname,
return 1;
}
-static int xstrtouint32(const char *s, char **p, int base, uint32_t *result)
+static int _xstrtouint32(const char *s, char **p, int base, uint32_t *result)
{
unsigned long ul;
errno = 0;
ul = strtoul(s, p, base);
+
if (errno || *p == s || ul > UINT32_MAX)
return 0;
+
*result = ul;
return 1;
@@ -425,7 +427,7 @@ static int _parse_pes(struct dm_pool *mem, char *c, struct dm_list *pe_ranges,
/* Start extent given? */
if (isdigit(*c)) {
- if (!xstrtouint32(c, &endptr, 10, &start))
+ if (!_xstrtouint32(c, &endptr, 10, &start))
goto error;
c = endptr;
/* Just one number given? */
@@ -436,14 +438,14 @@ static int _parse_pes(struct dm_pool *mem, char *c, struct dm_list *pe_ranges,
if (*c == '-') {
c++;
if (isdigit(*c)) {
- if (!xstrtouint32(c, &endptr, 10, &end))
+ if (!_xstrtouint32(c, &endptr, 10, &end))
goto error;
c = endptr;
}
} else if (*c == '+') { /* Length? */
c++;
if (isdigit(*c)) {
- if (!xstrtouint32(c, &endptr, 10, &len))
+ if (!_xstrtouint32(c, &endptr, 10, &len))
goto error;
c = endptr;
end = start + (len ? (len - 1) : 0);
@@ -1370,7 +1372,8 @@ static int _get_arg_vgnames(struct cmd_context *cmd,
* Obtain complete list of VG name/vgid pairs known on the system.
*/
static int _get_vgnameids_on_system(struct cmd_context *cmd,
- struct dm_list *vgnameids_on_system)
+ struct dm_list *vgnameids_on_system,
+ int include_internal)
{
struct vgnameid_list *vgnl;
struct dm_list *vgids;
@@ -1385,7 +1388,7 @@ static int _get_vgnameids_on_system(struct cmd_context *cmd,
/*
* Start with complete vgid list because multiple VGs might have same name.
*/
- vgids = get_vgids(cmd, 0);
+ vgids = get_vgids(cmd, include_internal);
if (!vgids || dm_list_empty(vgids)) {
stack;
return ECMD_PROCESSED;
@@ -1527,7 +1530,7 @@ int process_each_vg(struct cmd_context *cmd, int argc, char **argv,
* no VG names were given and the command defaults to processing all VGs.
*/
if (((dm_list_empty(&arg_vgnames) && enable_all_vgs) || !dm_list_empty(&arg_tags)) &&
- ((ret = _get_vgnameids_on_system(cmd, &vgnameids_on_system)) != ECMD_PROCESSED)) {
+ ((ret = _get_vgnameids_on_system(cmd, &vgnameids_on_system, 0)) != ECMD_PROCESSED)) {
stack;
return ret;
}
@@ -1861,7 +1864,7 @@ int process_each_lv(struct cmd_context *cmd, int argc, char **argv, uint32_t fla
* no VG names were given and the command defaults to processing all VGs.
*/
if (((dm_list_empty(&arg_vgnames) && enable_all_vgs) || !dm_list_empty(&arg_tags)) &&
- (ret = _get_vgnameids_on_system(cmd, &vgnameids_on_system) != ECMD_PROCESSED)) {
+ (ret = _get_vgnameids_on_system(cmd, &vgnameids_on_system, 0) != ECMD_PROCESSED)) {
stack;
return ret;
}
@@ -1887,245 +1890,375 @@ int process_each_lv(struct cmd_context *cmd, int argc, char **argv, uint32_t fla
&arg_tags, handle, process_single_lv);
}
-int process_each_pv_in_vg(struct cmd_context *cmd, struct volume_group *vg,
- const struct dm_list *tagsl, void *handle,
- process_single_pv_fn_t process_single_pv)
+static int _get_arg_pvnames(struct cmd_context *cmd,
+ int argc, char **argv,
+ struct dm_list *arg_pvnames,
+ struct dm_list *arg_tags)
{
+ int opt = 0;
+ char *at_sign, *tagname;
+ char *arg_name;
int ret_max = ECMD_PROCESSED;
- int ret;
- struct pv_list *pvl;
- dm_list_iterate_items(pvl, &vg->pvs) {
- if (sigint_caught())
- return_ECMD_FAILED;
- if (tagsl && !dm_list_empty(tagsl) &&
- !str_list_match_list(tagsl, &pvl->pv->tags, NULL)) {
+ log_verbose("Using physical volume(s) on command line");
+
+ for (; opt < argc; opt++) {
+ arg_name = argv[opt];
+
+ dm_unescape_colons_and_at_signs(arg_name, NULL, &at_sign);
+ if (at_sign && (at_sign == arg_name)) {
+ tagname = at_sign + 1;
+
+ if (!validate_tag(tagname)) {
+ log_error("Skipping invalid tag %s", tagname);
+ if (ret_max < EINVALID_CMD_LINE)
+ ret_max = EINVALID_CMD_LINE;
+ continue;
+ }
+ if (!str_list_add(cmd->mem, arg_tags,
+ dm_pool_strdup(cmd->mem, tagname))) {
+ log_error("strlist allocation failed");
+ return ECMD_FAILED;
+ }
continue;
}
- if ((ret = process_single_pv(cmd, vg, pvl->pv, handle)) > ret_max)
- ret_max = ret;
+
+ if (!str_list_add(cmd->mem, arg_pvnames,
+ dm_pool_strdup(cmd->mem, arg_name))) {
+ log_error("strlist allocation failed");
+ return ECMD_FAILED;
+ }
}
return ret_max;
}
-static int _process_all_devs(struct cmd_context *cmd, void *handle,
- process_single_pv_fn_t process_single_pv)
+static int _get_all_devices(struct cmd_context *cmd, struct dm_list *all_devices)
{
- struct pv_list *pvl;
- struct dm_list *pvslist;
- struct physical_volume *pv;
- struct physical_volume pv_dummy;
struct dev_iter *iter;
struct device *dev;
-
- int ret_max = ECMD_PROCESSED;
- int ret;
+ struct device_list *devl;
lvmcache_seed_infos_from_lvmetad(cmd);
- if (!(pvslist = get_pvs(cmd)))
- return_ECMD_FAILED;
if (!(iter = dev_iter_create(cmd->filter, 1))) {
log_error("dev_iter creation failed");
return ECMD_FAILED;
}
- while ((dev = dev_iter_get(iter)))
- {
- if (sigint_caught()) {
- ret_max = ECMD_FAILED;
- stack;
- break;
+ while ((dev = dev_iter_get(iter))) {
+ if (!(devl = dm_pool_alloc(cmd->mem, sizeof(*devl)))) {
+ log_error("device_list alloc failed");
+ return ECMD_FAILED;
}
+ devl->dev = dev;
+ dm_list_add(all_devices, &devl->list);
+ }
+
+ dev_iter_destroy(iter);
+
+ return ECMD_PROCESSED;
+}
+
+static int _device_list_remove(struct dm_list *all_devices, struct device *dev)
+{
+ struct device_list *devl;
+
+ dm_list_iterate_items(devl, all_devices) {
+ if (devl->dev == dev) {
+ dm_list_del(&devl->list);
+ return 1;
+ }
+ }
+
+ return 0;
+}
+
+static int _process_device_list(struct cmd_context *cmd, struct dm_list *all_devices,
+ void *handle, process_single_pv_fn_t process_single_pv)
+{
+ struct physical_volume pv_dummy;
+ struct physical_volume *pv;
+ struct device_list *devl;
+ int ret_max = ECMD_PROCESSED;
+ int ret = 0;
+
+ /*
+ * Pretend that each device is a PV with dummy values.
+ * FIXME Formalise this extension or find an alternative.
+ */
+ dm_list_iterate_items(devl, all_devices) {
memset(&pv_dummy, 0, sizeof(pv_dummy));
dm_list_init(&pv_dummy.tags);
dm_list_init(&pv_dummy.segments);
- pv_dummy.dev = dev;
+ pv_dummy.dev = devl->dev;
pv = &pv_dummy;
- /* TODO use a device-indexed hash here */
- dm_list_iterate_items(pvl, pvslist)
- if (pvl->pv->dev == dev)
- pv = pvl->pv;
+ log_very_verbose("Processing device %s", dev_name(devl->dev));
ret = process_single_pv(cmd, NULL, pv, handle);
if (ret > ret_max)
ret_max = ret;
- free_pv_fid(pv);
+ if (sigint_caught())
+ return_ECMD_FAILED;
}
- dev_iter_destroy(iter);
- dm_list_iterate_items(pvl, pvslist)
- free_pv_fid(pvl->pv);
+ return ECMD_PROCESSED;
+}
+
+static int _process_pvs_in_vg(struct cmd_context *cmd,
+ struct volume_group *vg,
+ struct dm_list *all_devices,
+ struct dm_list *arg_pvnames,
+ struct dm_list *arg_tags,
+ int process_all,
+ int skip,
+ void *handle,
+ process_single_pv_fn_t process_single_pv)
+{
+ struct physical_volume *pv;
+ struct pv_list *pvl;
+ const char *pv_name;
+ int process_pv;
+ int dev_found;
+ int ret_max = ECMD_PROCESSED;
+ int ret = 0;
+
+ dm_list_iterate_items(pvl, &vg->pvs) {
+ pv = pvl->pv;
+ pv_name = pv_dev_name(pv);
+
+ process_pv = process_all;
+
+ /* Remove each pvname as it is processed. */
+ if (!process_pv && !dm_list_empty(arg_pvnames) &&
+ str_list_match_item(arg_pvnames, pv_name)) {
+ process_pv = 1;
+ str_list_del(arg_pvnames, pv_name);
+ }
+
+ if (!process_pv && !dm_list_empty(arg_tags) &&
+ str_list_match_list(arg_tags, &pv->tags, NULL))
+ process_pv = 1;
+
+ if (process_pv) {
+ if (skip)
+ log_verbose("Skipping PV %s in VG %s", pv_name, vg->name);
+ else
+ log_very_verbose("Processing PV %s in VG %s", pv_name, vg->name);
+
+ dev_found = _device_list_remove(all_devices, pv->dev);
+
+ /*
+ * FIXME PVs with no mdas may turn up in an orphan VG when
+ * not using lvmetad as well as their correct VG. They
+ * will be missing from all_devices the second time
+ * around but must not be processed twice or trigger a message.
+ *
+ * Missing PVs will also need processing even though they are
+ * not present in all_devices.
+ */
+ if (!dev_found && !is_missing_pv(pv)) {
+ log_verbose("Skipping PV %s in VG %s: not in device list", pv_name, vg->name);
+ continue;
+ }
+
+ if (!skip)
+ ret = process_single_pv(cmd, vg, pv, handle);
+
+ if (ret > ret_max)
+ ret_max = ret;
+ }
+
+ if (sigint_caught())
+ return_ECMD_FAILED;
+
+ /*
+ * When processing only specific PV names, we can quit
+ * once they've all been found.
+ */
+ if (!process_all && dm_list_empty(arg_tags) && dm_list_empty(arg_pvnames))
+ break;
+ }
return ret_max;
}
/*
- * If the lock_type is LCK_VG_READ (used only in reporting commands),
- * we lock VG_GLOBAL to enable use of metadata cache.
- * This can pause alongide pvscan or vgscan process for a while.
+ * Iterate through all PVs in each listed VG. Process a PV if
+ * the name or tag matches arg_pvnames or arg_tags. If both
+ * arg_pvnames and arg_tags are empty, then process all PVs.
+ * No PV should be processed more than once.
+ *
+ * Each PV is removed from arg_pvnames and all_devices when it is
+ * processed. Any names remaining in arg_pvnames were not found, and
+ * should produce an error. Any devices remaining in all_devices were
+ * not found and should be processed by process_all_devices().
*/
-int process_each_pv(struct cmd_context *cmd, int argc, char **argv,
- struct volume_group *vg, uint32_t flags,
- int scan_label_only, void *handle,
- process_single_pv_fn_t process_single_pv)
+static int _process_pvs_in_vgs(struct cmd_context *cmd, uint32_t flags,
+ struct dm_list *all_vgnameids,
+ struct dm_list *all_devices,
+ struct dm_list *arg_pvnames,
+ struct dm_list *arg_tags,
+ int process_all,
+ void *handle,
+ process_single_pv_fn_t process_single_pv)
{
- int opt = 0;
+ struct volume_group *vg;
+ struct vgnameid_list *vgnl;
+ struct dm_str_list *sl;
+ const char *vg_name;
+ const char *vg_uuid;
+ int skip;
int ret_max = ECMD_PROCESSED;
int ret;
- int lock_global = !(flags & READ_WITHOUT_LOCK) && !(flags & READ_FOR_UPDATE) && !lvmetad_active();
- struct pv_list *pvl;
- struct physical_volume *pv;
- struct dm_list *pvslist = NULL, *vgnames;
- struct dm_list tagsl;
- struct dm_str_list *sll;
- char *at_sign, *tagname;
- struct device *dev;
+ dm_list_iterate_items(vgnl, all_vgnameids) {
+ vg_name = vgnl->vg_name;
+ vg_uuid = vgnl->vgid;
+ ret = 0;
+ skip = 0;
- dm_list_init(&tagsl);
+ vg = vg_read(cmd, vg_name, vg_uuid, flags);
+ if (ignore_vg(vg, vg_name, flags & READ_ALLOW_INCONSISTENT, &ret)) {
+ if (ret > ret_max)
+ ret_max = ret;
+ skip = 1;
+ }
- if (lock_global && !lock_vol(cmd, VG_GLOBAL, LCK_VG_READ, NULL)) {
- log_error("Unable to obtain global lock.");
- return ECMD_FAILED;
+ ret = _process_pvs_in_vg(cmd, vg, all_devices, arg_pvnames, arg_tags,
+ process_all, skip, handle, process_single_pv);
+
+ if (ret > ret_max)
+ ret_max = ret;
+
+ if (skip)
+ release_vg(vg);
+ else
+ unlock_and_release_vg(cmd, vg, vg->name);
+
+ if (sigint_caught())
+ return_ECMD_FAILED;
+
+ /* Quit early when possible. */
+ if (!process_all && dm_list_empty(arg_tags) && dm_list_empty(arg_pvnames))
+ return ret_max;
}
- if (argc) {
- log_verbose("Using physical volume(s) on command line");
- for (; opt < argc; opt++) {
- if (sigint_caught()) {
- ret_max = ECMD_FAILED;
- goto_out;
- }
- dm_unescape_colons_and_at_signs(argv[opt], NULL, &at_sign);
- if (at_sign && (at_sign == argv[opt])) {
- tagname = at_sign + 1;
-
- if (!validate_tag(tagname)) {
- log_error("Skipping invalid tag %s",
- tagname);
- if (ret_max < EINVALID_CMD_LINE)
- ret_max = EINVALID_CMD_LINE;
- continue;
- }
- if (!str_list_add(cmd->mem, &tagsl,
- dm_pool_strdup(cmd->mem,
- tagname))) {
- log_error("strlist allocation failed");
- goto bad;
- }
- continue;
- }
- if (vg) {
- if (!(pvl = find_pv_in_vg(vg, argv[opt]))) {
- log_error("Physical Volume \"%s\" not "
- "found in Volume Group "
- "\"%s\"", argv[opt],
- vg->name);
- ret_max = ECMD_FAILED;
- continue;
- }
- pv = pvl->pv;
- } else {
- if (!pvslist) {
- lvmcache_seed_infos_from_lvmetad(cmd);
- if (!(pvslist = get_pvs(cmd)))
- goto bad;
- }
+ /* Return an error if a pvname arg was not found. */
+ dm_list_iterate_items(sl, arg_pvnames) {
+ log_error("Failed to find physical volume \"%s\"", sl->str);
+ ret_max = ECMD_FAILED;
+ }
- if (!(dev = dev_cache_get(argv[opt], cmd->filter))) {
- log_error("Failed to find device "
- "\"%s\"", argv[opt]);
- ret_max = ECMD_FAILED;
- continue;
- }
+ return ret_max;
+}
- pv = NULL;
- dm_list_iterate_items(pvl, pvslist)
- if (pvl->pv->dev == dev)
- pv = pvl->pv;
+int process_each_pv(struct cmd_context *cmd,
+ int argc, char **argv,
+ struct volume_group *vg,
+ uint32_t flags,
+ void *handle,
+ process_single_pv_fn_t process_single_pv)
+{
+ struct dm_list arg_tags; /* str_list */
+ struct dm_list arg_pvnames; /* str_list */
+ struct dm_list all_vgnameids; /* vgnameid_list */
+ struct dm_list all_devices; /* device_list */
+ struct dm_str_list *sl;
+ int process_all_pvs;
+ int process_all_devices;
+ int ret_max = ECMD_PROCESSED;
+ int ret;
- if (!pv) {
- log_error("Failed to find physical volume "
- "\"%s\"", argv[opt]);
- ret_max = ECMD_FAILED;
- continue;
- }
- }
+ dm_list_init(&arg_tags);
+ dm_list_init(&arg_pvnames);
+ dm_list_init(&all_vgnameids);
+ dm_list_init(&all_devices);
- ret = process_single_pv(cmd, vg, pv, handle);
+ /*
+ * Create two lists from argv:
+ * arg_pvnames: pvs explicitly named in argv
+ * arg_tags: tags explicitly named in argv
+ */
+ if ((ret = _get_arg_pvnames(cmd, argc, argv, &arg_pvnames, &arg_tags)) != ECMD_PROCESSED)
+ return ret;
- if (ret > ret_max)
- ret_max = ret;
- }
- if (!dm_list_empty(&tagsl) && (vgnames = get_vgnames(cmd, 1)) &&
- !dm_list_empty(vgnames)) {
- dm_list_iterate_items(sll, vgnames) {
- if (sigint_caught()) {
- ret_max = ECMD_FAILED;
- goto_out;
- }
- vg = vg_read(cmd, sll->str, NULL, flags);
- if (ignore_vg(vg, sll->str, 0, &ret_max)) {
- release_vg(vg);
- stack;
- continue;
- }
+ process_all_pvs = dm_list_empty(&arg_pvnames) && dm_list_empty(&arg_tags);
- ret = process_each_pv_in_vg(cmd, vg, &tagsl,
- handle,
- process_single_pv);
- if (ret > ret_max)
- ret_max = ret;
+ process_all_devices = process_all_pvs &&
+ (cmd->command->flags & ENABLE_ALL_DEVS) &&
+ arg_count(cmd, all_ARG);
- unlock_and_release_vg(cmd, vg, sll->str);
- }
+ /*
+ * If vg is set, the caller already selected, locked, and read one
+ * VG. This code is unused.
+ */
+ if (vg) {
+ ret = _process_pvs_in_vg(cmd, vg, NULL,
+ &arg_pvnames, &arg_tags, process_all_pvs, 0,
+ handle, process_single_pv);
+
+ dm_list_iterate_items(sl, &arg_pvnames) {
+ log_error("Physical Volume \"%s\" not found in Volume Group \"%s\"",
+ sl->str, vg->name);
+ ret = ECMD_FAILED;
}
- } else {
- if (vg) {
- log_verbose("Using all physical volume(s) in "
- "volume group");
- ret_max = process_each_pv_in_vg(cmd, vg, NULL, handle,
- process_single_pv);
- } else if (arg_count(cmd, all_ARG)) {
- ret_max = _process_all_devs(cmd, handle, process_single_pv);
- } else {
- log_verbose("Scanning for physical volume names");
- lvmcache_seed_infos_from_lvmetad(cmd);
- if (!(pvslist = get_pvs(cmd)))
- goto bad;
+ return ret;
+ }
- dm_list_iterate_items(pvl, pvslist) {
- if (sigint_caught()) {
- ret_max = ECMD_FAILED;
- goto_out;
- }
- ret = process_single_pv(cmd, NULL, pvl->pv,
- handle);
- if (ret > ret_max)
- ret_max = ret;
+ /*
+ * If the caller wants to process all devices (not just PVs), then all PVs
+ * from all VGs are processed first, removing them from all_devices. Then
+ * any devs remaining in all_devices are processed.
+ */
+ if ((ret = _get_all_devices(cmd, &all_devices) != ECMD_PROCESSED)) {
+ stack;
+ return ret;
+ }
- free_pv_fid(pvl->pv);
- }
- }
+ if ((ret = _get_vgnameids_on_system(cmd, &all_vgnameids, 1) != ECMD_PROCESSED)) {
+ stack;
+ return ret;
}
-out:
- if (pvslist)
- dm_list_iterate_items(pvl, pvslist)
- free_pv_fid(pvl->pv);
- if (lock_global)
- unlock_vg(cmd, VG_GLOBAL);
+ ret = _process_pvs_in_vgs(cmd, flags, &all_vgnameids, &all_devices,
+ &arg_pvnames, &arg_tags, process_all_pvs,
+ handle, process_single_pv);
+ if (ret > ret_max)
+ ret_max = ret;
+
+ if (sigint_caught())
+ return_ECMD_FAILED;
+
+ if (!process_all_devices)
+ goto_out;
+
+ ret = _process_device_list(cmd, &all_devices, handle, process_single_pv);
+ if (ret > ret_max)
+ ret_max = ret;
+
+out:
return ret_max;
-bad:
- if (lock_global)
- unlock_vg(cmd, VG_GLOBAL);
+}
+
+int process_each_pv_in_vg(struct cmd_context *cmd, struct volume_group *vg,
+ void *handle, process_single_pv_fn_t process_single_pv)
+{
+ int ret_max = ECMD_PROCESSED;
+ int ret;
+ struct pv_list *pvl;
- return ECMD_FAILED;
+ dm_list_iterate_items(pvl, &vg->pvs) {
+ if (sigint_caught())
+ return_ECMD_FAILED;
+ if ((ret = process_single_pv(cmd, vg, pvl->pv, handle)) > ret_max)
+ ret_max = ret;
+ }
+
+ return ret_max;
}
diff --git a/tools/toollib.h b/tools/toollib.h
index ae4b21e..483ac68 100644
--- a/tools/toollib.h
+++ b/tools/toollib.h
@@ -50,8 +50,7 @@ int process_each_vg(struct cmd_context *cmd, int argc, char **argv,
int process_each_pv(struct cmd_context *cmd, int argc, char **argv,
struct volume_group *vg, uint32_t lock_type,
- int scan_label_only, void *handle,
- process_single_pv_fn_t process_single_pv);
+ void *handle, process_single_pv_fn_t process_single_pv);
int process_each_label(struct cmd_context *cmd, int argc, char **argv,
void *handle, process_single_label_fn_t process_single_label);
@@ -72,8 +71,7 @@ int process_each_segment_in_lv(struct cmd_context *cmd,
process_single_seg_fn_t process_single_seg);
int process_each_pv_in_vg(struct cmd_context *cmd, struct volume_group *vg,
- const struct dm_list *tagsl, void *handle,
- process_single_pv_fn_t process_single_pv);
+ void *handle, process_single_pv_fn_t process_single_pv);
int process_each_lv_in_vg(struct cmd_context *cmd,
diff --git a/tools/vgdisplay.c b/tools/vgdisplay.c
index 39cdaf3..95a5ebd 100644
--- a/tools/vgdisplay.c
+++ b/tools/vgdisplay.c
@@ -43,7 +43,7 @@ static int vgdisplay_single(struct cmd_context *cmd, const char *vg_name,
(process_single_lv_fn_t)lvdisplay_full);
log_print("--- Physical volumes ---");
- process_each_pv_in_vg(cmd, vg, NULL, NULL,
+ process_each_pv_in_vg(cmd, vg, NULL,
(process_single_pv_fn_t)pvdisplay_short);
}
diff --git a/tools/vgreduce.c b/tools/vgreduce.c
index 970f61c..493a084 100644
--- a/tools/vgreduce.c
+++ b/tools/vgreduce.c
@@ -249,7 +249,7 @@ int vgreduce(struct cmd_context *cmd, int argc, char **argv)
/* FIXME: Pass private struct through to all these functions */
/* and update in batch here? */
- ret = process_each_pv(cmd, argc, argv, vg, READ_FOR_UPDATE, 0, NULL,
+ ret = process_each_pv(cmd, argc, argv, vg, READ_FOR_UPDATE, NULL,
_vgreduce_single);
}
8 years, 11 months