master - test: Make timeouts a little more robust & verbose.
by Petr Rockai
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=c1217e6881f6d6...
Commit: c1217e6881f6d679c0589078c00350f00c6bee10
Parent: 9a1da7b262e6284422bedfb565ff46d2ac203027
Author: Petr Rockai <prockai(a)redhat.com>
AuthorDate: Mon Aug 5 21:11:49 2013 +0200
Committer: Petr Rockai <prockai(a)redhat.com>
CommitterDate: Wed Aug 28 14:53:23 2013 +0200
test: Make timeouts a little more robust & verbose.
---
test/lib/harness.c | 7 ++++---
1 files changed, 4 insertions(+), 3 deletions(-)
diff --git a/test/lib/harness.c b/test/lib/harness.c
index 043ca9b..586c5d3 100644
--- a/test/lib/harness.c
+++ b/test/lib/harness.c
@@ -381,13 +381,14 @@ static void run(int i, char *f) {
FD_SET(fds[1], &master_set);
while ((w = wait4(pid, &st, WNOHANG, &usage)) == 0) {
if ((fullbuffer && fullbuffer++ == 8000) ||
- time(NULL) - start > 120) // a 2 minute timeout
+ time(NULL) - start > 5) // a 2 minute timeout
{
- kill(-pid, SIGINT);
+ system("echo t > /proc/sysrq-trigger");
+ kill(pid, SIGINT);
sleep(5); /* wait a bit for a reaction */
if ((w = waitpid(pid, &st, WNOHANG)) == 0) {
kill(-pid, SIGKILL);
- w = waitpid(pid, &st, NULL);
+ w = pid; // waitpid(pid, &st, NULL);
}
drain();
runaway = 1;
10 years, 8 months
master - TEST: Add a timeout to the harness, killing tests after 2 minutes.
by Petr Rockai
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=9a1da7b262e628...
Commit: 9a1da7b262e6284422bedfb565ff46d2ac203027
Parent: e72b2d047dd64fca941cc6853c72dfe6b8e52399
Author: Petr Rockai <prockai(a)redhat.com>
AuthorDate: Tue Jul 23 11:42:34 2013 +0200
Committer: Petr Rockai <prockai(a)redhat.com>
CommitterDate: Wed Aug 28 14:53:23 2013 +0200
TEST: Add a timeout to the harness, killing tests after 2 minutes.
---
test/lib/harness.c | 50 +++++++++++++++++++++++++++++++++++++++-----------
1 files changed, 39 insertions(+), 11 deletions(-)
diff --git a/test/lib/harness.c b/test/lib/harness.c
index cea9a15..043ca9b 100644
--- a/test/lib/harness.c
+++ b/test/lib/harness.c
@@ -71,11 +71,12 @@ enum {
WARNED,
KNOWNFAIL,
INTERRUPTED,
+ TIMEOUT,
};
static void handler( int sig ) {
signal( sig, SIG_DFL );
- kill( pid, sig );
+ kill( -pid, sig );
die = sig;
}
@@ -169,7 +170,7 @@ static void _append_buf(const char *buf, size_t len)
if ((readbuf_sz >= MAX_LOG_SIZE) &&
!getenv("LVM_TEST_UNLIMITED")) {
if (fullbuffer++ == 0)
- kill(pid, SIGINT);
+ kill(-pid, SIGINT);
return;
}
readbuf_sz = readbuf_sz ? 2 * readbuf_sz : 4096;
@@ -293,6 +294,17 @@ static void interrupted(int i, char *f) {
}
}
+static void timeout(int i, char *f) {
+ ++ s.ninterrupted;
+ s.status[i] = TIMEOUT;
+ printf("timeout.\n");
+ if (!verbose && readbuf) {
+ printf("-- Timed out %s ------------------------------------\n", f);
+ dump();
+ printf("\n-- Timed out %s (end) ------------------------------\n", f);
+ }
+}
+
static void skipped(int i, char *f) {
++ s.nskipped;
s.status[i] = SKIPPED;
@@ -341,6 +353,7 @@ static void run(int i, char *f) {
} else {
strcpy(script, f);
}
+ setpgid(0, 0);
execlp("bash", "bash", "-noprofile", "-norc", script, NULL);
perror("execlp");
fflush(stderr);
@@ -351,8 +364,9 @@ static void run(int i, char *f) {
char buf[128];
char outpath[PATH_MAX];
char *c = outpath + strlen(results) + 1;
- struct timeval timeout;
+ struct timeval selectwait;
fd_set master_set, copy_set;
+ int runaway = 0;
snprintf(buf, sizeof(buf), "%s ...", f);
printf("Running %-60s ", buf);
@@ -366,13 +380,24 @@ static void run(int i, char *f) {
FD_ZERO(&master_set);
FD_SET(fds[1], &master_set);
while ((w = wait4(pid, &st, WNOHANG, &usage)) == 0) {
- if (fullbuffer && fullbuffer++ == 8000)
- /* Output doesn't won't to stop... */
- kill(pid, SIGKILL);
+ if ((fullbuffer && fullbuffer++ == 8000) ||
+ time(NULL) - start > 120) // a 2 minute timeout
+ {
+ kill(-pid, SIGINT);
+ sleep(5); /* wait a bit for a reaction */
+ if ((w = waitpid(pid, &st, WNOHANG)) == 0) {
+ kill(-pid, SIGKILL);
+ w = waitpid(pid, &st, NULL);
+ }
+ drain();
+ runaway = 1;
+ break;
+ }
+
memcpy(©_set, &master_set, sizeof(master_set));
- timeout.tv_sec = 0;
- timeout.tv_usec = 500000;
- if (select(fds[1] + 1, ©_set, NULL, NULL, &timeout) <= 0)
+ selectwait.tv_sec = 0;
+ selectwait.tv_usec = 500000;
+ if (select(fds[1] + 1, ©_set, NULL, NULL, &selectwait) <= 0)
continue;
drain();
}
@@ -381,9 +406,11 @@ static void run(int i, char *f) {
exit(206);
}
drain();
- if (fullbuffer || (die == 2))
+ if (die == 2)
interrupted(i, f);
- else if (WIFEXITED(st)) {
+ else if (runaway) {
+ timeout(i, f);
+ } else if (WIFEXITED(st)) {
if (WEXITSTATUS(st) == 0)
passed(i, f, start, &usage);
else if (WEXITSTATUS(st) == 200)
@@ -467,6 +494,7 @@ int main(int argc, char **argv) {
case FAILED: result = "failed"; break;
case SKIPPED: result = "skipped"; break;
case WARNED: result = "warnings"; break;
+ case TIMEOUT: result = "timeout"; break;
case INTERRUPTED: result = "interrupted"; break;
default: result = "unknown"; break;
}
10 years, 8 months
master - TEST: Add tests for lvchange actions of RAID under thin
by Jonathan Brassow
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=e72b2d047dd64f...
Commit: e72b2d047dd64fca941cc6853c72dfe6b8e52399
Parent: 0799e81ee08a76c877d774b2f7df75ad3ec29897
Author: Jonathan Brassow <jbrassow(a)redhat.com>
AuthorDate: Tue Aug 27 16:46:40 2013 -0500
Committer: Jonathan Brassow <jbrassow(a)redhat.com>
CommitterDate: Tue Aug 27 16:46:40 2013 -0500
TEST: Add tests for lvchange actions of RAID under thin
Patch includes RAID1,4,5,6,10 tests for:
- setting writemostly/writebehind
* syncaction changes (i.e. scrubbing operations)
- refresh (i.e. reviving devices after transient failures)
- setting recovery rate (sync I/O throttling)
while the RAID LVs are under a thin-pool (both data and metadata)
* not fully tested because I haven't found a way to force bad
blocks to be noticed in the testsuite yet. Works just fine
when dealing with "real" devices.
---
test/shell/lvchange-raid.sh | 315 +++++++++++++++++++++++++++----------------
1 files changed, 197 insertions(+), 118 deletions(-)
diff --git a/test/shell/lvchange-raid.sh b/test/shell/lvchange-raid.sh
index 715df15..38b9c4c 100644
--- a/test/shell/lvchange-raid.sh
+++ b/test/shell/lvchange-raid.sh
@@ -11,6 +11,8 @@
. lib/test
+THIN_POSTFIX=""
+
# Writemostly has been in every version since the begining
# Device refresh in 1.5.1 upstream and 1.3.4 < x < 1.4.0 in RHEL6
# Sync action in 1.5.0 upstream and 1.3.3 < x < 1.4.0 in RHEL6
@@ -21,102 +23,106 @@ aux target_at_least dm-raid 1 3 5 &&
! aux target_at_least dm-raid 1 4 0 ||
aux target_at_least dm-raid 1 5 2 || skip
+# DEVICE "$dev6" is reserved for non-RAID LVs that
+# will not undergo failure
aux prepare_vg 6
# run_writemostly_check <VG> <LV>
run_writemostly_check() {
local d0
local d1
+ local vg=$1
+ local lv=${2}${THIN_POSTFIX}
printf "#\n#\n#\n# %s/%s (%s): run_writemostly_check\n#\n#\n#\n" \
- $1 $2 `lvs --noheadings -o segtype $1/$2`
- d0=`lvs -a --noheadings -o devices $1/${2}_rimage_0 | sed s/\(.\)//`
+ $vg $lv `lvs -a --noheadings -o segtype $vg/$lv`
+ d0=`lvs -a --noheadings -o devices $vg/${lv}_rimage_0 | sed s/\(.\)//`
d0=$(sed s/^[[:space:]]*// <<< "$d0")
- d1=`lvs -a --noheadings -o devices $1/${2}_rimage_1 | sed s/\(.\)//`
+ d1=`lvs -a --noheadings -o devices $vg/${lv}_rimage_1 | sed s/\(.\)//`
d1=$(sed s/^[[:space:]]*// <<< "$d1")
# No writemostly flag should be there yet.
- lvs -a --noheadings -o lv_attr $1/${2}_rimage_0 | grep '.*-.$'
- lvs -a --noheadings -o lv_attr $1/${2}_rimage_1 | grep '.*-.$'
+ lvs -a --noheadings -o lv_attr $vg/${lv}_rimage_0 | grep '.*-.$'
+ lvs -a --noheadings -o lv_attr $vg/${lv}_rimage_1 | grep '.*-.$'
- if [ `lvs --noheadings -o segtype $1/$2` != "raid1" ]; then
- not lvchange --writemostly $d0 $1/$2
+ if [ `lvs -a --noheadings -o segtype $vg/$lv` != "raid1" ]; then
+ not lvchange --writemostly $d0 $vg/$lv
return
fi
# Set the flag
- lvchange --writemostly $d0 $1/$2
- lvs -a --noheadings -o lv_attr $1/${2}_rimage_0 | grep '.*w.$'
+ lvchange --writemostly $d0 $vg/$lv
+ lvs -a --noheadings -o lv_attr $vg/${lv}_rimage_0 | grep '.*w.$'
# Running again should leave it set (not toggle)
- lvchange --writemostly $d0 $1/$2
- lvs -a --noheadings -o lv_attr $1/${2}_rimage_0 | grep '.*w.$'
+ lvchange --writemostly $d0 $vg/$lv
+ lvs -a --noheadings -o lv_attr $vg/${lv}_rimage_0 | grep '.*w.$'
# Running again with ':y' should leave it set
- lvchange --writemostly $d0:y $1/$2
- lvs -a --noheadings -o lv_attr $1/${2}_rimage_0 | grep '.*w.$'
+ lvchange --writemostly $d0:y $vg/$lv
+ lvs -a --noheadings -o lv_attr $vg/${lv}_rimage_0 | grep '.*w.$'
# ':n' should unset it
- lvchange --writemostly $d0:n $1/$2
- lvs -a --noheadings -o lv_attr $1/${2}_rimage_0 | grep '.*-.$'
+ lvchange --writemostly $d0:n $vg/$lv
+ lvs -a --noheadings -o lv_attr $vg/${lv}_rimage_0 | grep '.*-.$'
# ':n' again should leave it unset
- lvchange --writemostly $d0:n $1/$2
- lvs -a --noheadings -o lv_attr $1/${2}_rimage_0 | grep '.*-.$'
+ lvchange --writemostly $d0:n $vg/$lv
+ lvs -a --noheadings -o lv_attr $vg/${lv}_rimage_0 | grep '.*-.$'
# ':t' toggle to set
- lvchange --writemostly $d0:t $1/$2
- lvs -a --noheadings -o lv_attr $1/${2}_rimage_0 | grep '.*w.$'
+ lvchange --writemostly $d0:t $vg/$lv
+ lvs -a --noheadings -o lv_attr $vg/${lv}_rimage_0 | grep '.*w.$'
# ':t' toggle to unset
- lvchange --writemostly $d0:t $1/$2
- lvs -a --noheadings -o lv_attr $1/${2}_rimage_0 | grep '.*-.$'
+ lvchange --writemostly $d0:t $vg/$lv
+ lvs -a --noheadings -o lv_attr $vg/${lv}_rimage_0 | grep '.*-.$'
# ':y' to set
- lvchange --writemostly $d0:y $1/$2
- lvs -a --noheadings -o lv_attr $1/${2}_rimage_0 | grep '.*w.$'
+ lvchange --writemostly $d0:y $vg/$lv
+ lvs -a --noheadings -o lv_attr $vg/${lv}_rimage_0 | grep '.*w.$'
# Toggle both at once
- lvchange --writemostly $d0:t --writemostly $d1:t $1/$2
- lvs -a --noheadings -o lv_attr $1/${2}_rimage_0 | grep '.*-.$'
- lvs -a --noheadings -o lv_attr $1/${2}_rimage_1 | grep '.*w.$'
+ lvchange --writemostly $d0:t --writemostly $d1:t $vg/$lv
+ lvs -a --noheadings -o lv_attr $vg/${lv}_rimage_0 | grep '.*-.$'
+ lvs -a --noheadings -o lv_attr $vg/${lv}_rimage_1 | grep '.*w.$'
# Toggle both at once again
- lvchange --writemostly $d0:t --writemostly $d1:t $1/$2
- lvs -a --noheadings -o lv_attr $1/${2}_rimage_0 | grep '.*w.$'
- lvs -a --noheadings -o lv_attr $1/${2}_rimage_1 | grep '.*-.$'
+ lvchange --writemostly $d0:t --writemostly $d1:t $vg/$lv
+ lvs -a --noheadings -o lv_attr $vg/${lv}_rimage_0 | grep '.*w.$'
+ lvs -a --noheadings -o lv_attr $vg/${lv}_rimage_1 | grep '.*-.$'
# Toggle one, unset the other
- lvchange --writemostly $d0:n --writemostly $d1:t $1/$2
- lvs -a --noheadings -o lv_attr $1/${2}_rimage_0 | grep '.*-.$'
- lvs -a --noheadings -o lv_attr $1/${2}_rimage_1 | grep '.*w.$'
+ lvchange --writemostly $d0:n --writemostly $d1:t $vg/$lv
+ lvs -a --noheadings -o lv_attr $vg/${lv}_rimage_0 | grep '.*-.$'
+ lvs -a --noheadings -o lv_attr $vg/${lv}_rimage_1 | grep '.*w.$'
# Toggle one, set the other
- lvchange --writemostly $d0:y --writemostly $d1:t $1/$2
- lvs -a --noheadings -o lv_attr $1/${2}_rimage_0 | grep '.*w.$'
- lvs -a --noheadings -o lv_attr $1/${2}_rimage_1 | grep '.*-.$'
+ lvchange --writemostly $d0:y --writemostly $d1:t $vg/$lv
+ lvs -a --noheadings -o lv_attr $vg/${lv}_rimage_0 | grep '.*w.$'
+ lvs -a --noheadings -o lv_attr $vg/${lv}_rimage_1 | grep '.*-.$'
# Partial flag supercedes writemostly flag
aux disable_dev $d0
- lvs -a --noheadings -o lv_attr $1/${2}_rimage_0 | grep '.*p.$'
+ lvs -a --noheadings -o lv_attr $vg/${lv}_rimage_0 | grep '.*p.$'
aux enable_dev $d0
- lvs -a --noheadings -o lv_attr $1/${2}_rimage_0 | grep '.*w.$'
+ lvs -a --noheadings -o lv_attr $vg/${lv}_rimage_0 | grep '.*w.$'
# Catch Bad writebehind values
- not lvchange --writebehind "invalid" $1/$2
- not lvchange --writebehind -256 $1/$2
+ not lvchange --writebehind "invalid" $vg/$lv
+ not lvchange --writebehind -256 $vg/$lv
# Set writebehind
- [ ! `lvs --noheadings -o raid_write_behind $1/$2` ]
- lvchange --writebehind 512 $1/$2
- [ `lvs --noheadings -o raid_write_behind $1/$2` -eq 512 ]
+ [ ! `lvs --noheadings -o raid_write_behind $vg/$lv` ]
+ lvchange --writebehind 512 $vg/$lv
+ [ `lvs --noheadings -o raid_write_behind $vg/$lv` -eq 512 ]
# Converting to linear should clear flags and writebehind
- lvconvert -m 0 $1/$2 $d1
- lvconvert --type raid1 -m 1 $1/$2 $d1
- [ ! `lvs --noheadings -o raid_write_behind $1/$2` ]
- lvs -a --noheadings -o lv_attr $1/${2}_rimage_0 | grep '.*-.$'
- lvs -a --noheadings -o lv_attr $1/${2}_rimage_1 | grep '.*-.$'
+ lvconvert -m 0 $vg/$lv $d1
+ lvconvert --type raid1 -m 1 $vg/$lv $d1
+ [ ! `lvs --noheadings -o raid_write_behind $vg/$lv` ]
+ lvs -a --noheadings -o lv_attr $vg/${lv}_rimage_0 | grep '.*-.$'
+ lvs -a --noheadings -o lv_attr $vg/${lv}_rimage_1 | grep '.*-.$'
}
# run_syncaction_check <VG> <LV>
@@ -125,15 +131,17 @@ run_syncaction_check() {
local seek
local size
local tmp
+ local vg=$1
+ local lv=${2}${THIN_POSTFIX}
printf "#\n#\n#\n# %s/%s (%s): run_syncaction_check\n#\n#\n#\n" \
- $1 $2 `lvs --noheadings -o segtype $1/$2`
- aux wait_for_sync $1 $2
+ $vg $lv `lvs -a --noheadings -o segtype $vg/$lv`
+ aux wait_for_sync $vg $lv
- device=`lvs -a --noheadings -o devices $1/${2}_rimage_1 | sed s/\(.\)//`
+ device=`lvs -a --noheadings -o devices $vg/${lv}_rimage_1 | sed s/\(.\)//`
device=$(sed s/^[[:space:]]*// <<< "$device")
- size=`lvs -a --noheadings -o size --units 1k $1/${2}_rimage_1 | sed s/\.00k//`
+ size=`lvs -a --noheadings -o size --units 1k $vg/${lv}_rimage_1 | sed s/\.00k//`
size=$(sed s/^[[:space:]]*// <<< "$size")
size=$(($size / 2))
@@ -141,116 +149,182 @@ run_syncaction_check() {
tmp=$(sed s/^[[:space:]]*// <<< "$tmp")
seek=$tmp # Jump over MDA
- tmp=`lvs -a --noheadings -o size --units 1k $1/${2}_rmeta_1 | sed s/\.00k//`
+ tmp=`lvs -a --noheadings -o size --units 1k $vg/${lv}_rmeta_1 | sed s/\.00k//`
tmp=$(sed s/^[[:space:]]*// <<< "$tmp")
seek=$(($seek + $tmp)) # Jump over RAID metadata image
seek=$(($seek + $size)) # Jump halfway through the RAID image
- lvs --noheadings -o lv_attr $1/$2 | grep '.*-.$'
- [ `lvs --noheadings -o raid_mismatch_count $1/$2` == 0 ]
+ lvs --noheadings -o lv_attr $vg/$lv | grep '.*-.$'
+ [ `lvs --noheadings -o raid_mismatch_count $vg/$lv` == 0 ]
# Overwrite the last half of one of the PVs with crap
dd if=/dev/urandom of=$device bs=1k count=$size seek=$seek
- # FIXME: Why is this necessary? caching effects?
- # I don't need to do this when testing "real" devices...
- lvchange -an $1/$2; lvchange -ay $1/$2
+ if [ ! -z $THIN_POSTFIX ]; then
+ #
+ # Seems to work fine on real devices,
+ # but can't make the system notice the bad blocks
+ # in the testsuite - especially when thin is layered
+ # on top of RAID. In other cases, I can deactivate
+ # and reactivate and it works. Here, even that doesn't
+ # work.
+ return 0
+ lvchange -an $vg/$2
+ lvchange -ay $vg/$2
+ else
+ lvchange -an $vg/$lv
+ lvchange -ay $vg/$lv
+ fi
# "check" should find discrepancies but not change them
# 'lvs' should show results
- lvchange --syncaction check $1/$2
- aux wait_for_sync $1 $2
- lvs --noheadings -o lv_attr $1/$2 | grep '.*m.$'
- [ `lvs --noheadings -o raid_mismatch_count $1/$2` != 0 ]
+ lvchange --syncaction check $vg/$lv
+ aux wait_for_sync $vg $lv
+ if ! lvs --noheadings -o lv_attr $vg/$lv | grep '.*m.$'; then
+ lvs --noheadings -o lv_attr $vg/$lv
+ dmsetup status | grep $vg
+ false
+ fi
+ [ `lvs --noheadings -o raid_mismatch_count $vg/$lv` != 0 ]
# "repair" will fix discrepancies
- lvchange --syncaction repair $1/$2
- aux wait_for_sync $1 $2
+ lvchange --syncaction repair $vg/$lv
+ aux wait_for_sync $vg $lv
# Final "check" should show no mismatches
# 'lvs' should show results
- lvchange --syncaction check $1/$2
- aux wait_for_sync $1 $2
- lvs --noheadings -o lv_attr $1/$2 | grep '.*-.$'
- [ `lvs --noheadings -o raid_mismatch_count $1/$2` == 0 ]
+ lvchange --syncaction check $vg/$lv
+ aux wait_for_sync $vg $lv
+ lvs --noheadings -o lv_attr $vg/$lv | grep '.*-.$'
+ [ `lvs --noheadings -o raid_mismatch_count $vg/$lv` == 0 ]
}
# run_refresh_check <VG> <LV>
# Assumes "$dev2" is in the array
run_refresh_check() {
local size
+ local vg=$1
+ local lv=${2}${THIN_POSTFIX}
printf "#\n#\n#\n# %s/%s (%s): run_refresh_check\n#\n#\n#\n" \
- $1 $2 `lvs --noheadings -o segtype $1/$2`
+ $vg $lv `lvs -a --noheadings -o segtype $vg/$lv`
- aux wait_for_sync $1 $2
+ aux wait_for_sync $vg $lv
- size=`lvs -a --noheadings -o size --units 1k $1/$2 | sed s/\.00k//`
+ if [ -z $THIN_POSTFIX ]; then
+ size=`lvs -a --noheadings -o size --units 1k $vg/$lv | sed s/\.00k//`
+ else
+ size=`lvs -a --noheadings -o size --units 1k $vg/thinlv | sed s/\.00k//`
+ fi
size=$(sed s/^[[:space:]]*// <<< "$size")
# Disable dev2 and do some I/O to make the kernel notice
aux disable_dev "$dev2"
- dd if=/dev/urandom of=/dev/$1/$2 bs=1k count=$size
+ if [ -z $THIN_POSTFIX ]; then
+ dd if=/dev/urandom of=/dev/$vg/$lv bs=1k count=$size
+ else
+ dd if=/dev/urandom of=/dev/$vg/thinlv bs=1k count=$size
+ sync; sync; sync
+ fi
# Check for 'p'artial flag
- lvs --noheadings -o lv_attr $1/$2 | grep '.*p.$'
+ lvs --noheadings -o lv_attr $vg/$lv | grep '.*p.$'
+ dmsetup status
+ lvs -a -o name,attr,devices $vg
aux enable_dev "$dev2"
+ dmsetup status
+ lvs -a -o name,attr,devices $vg
+
# Check for 'r'efresh flag
- lvs --noheadings -o lv_attr $1/$2 | grep '.*r.$'
+ lvs --noheadings -o lv_attr $vg/$lv | grep '.*r.$'
- lvchange --refresh $1/$2
- aux wait_for_sync $1 $2
- lvs --noheadings -o lv_attr $1/$2 | grep '.*-.$'
+ lvchange --refresh $vg/$lv
+ aux wait_for_sync $vg $lv
+ lvs --noheadings -o lv_attr $vg/$lv | grep '.*-.$'
# Writing random data above should mean that the devices
# were out-of-sync. The refresh should have taken care
- # of properly reintegrating the device. If any mismatches
- # are repaired, it will show up in the 'lvs' output.
- lvchange --syncaction repair $1/$2
- aux wait_for_sync $1 $2
- lvs --noheadings -o lv_attr $1/$2 | grep '.*-.$'
+ # of properly reintegrating the device.
+ lvchange --syncaction repair $vg/$lv
+ aux wait_for_sync $vg $lv
+ lvs --noheadings -o lv_attr $vg/$lv | grep '.*-.$'
}
# run_recovery_rate_check <VG> <LV>
# Assumes "$dev2" is in the array
run_recovery_rate_check() {
+ local vg=$1
+ local lv=${2}${THIN_POSTFIX}
+
printf "#\n#\n#\n# %s/%s (%s): run_recovery_rate_check\n#\n#\n#\n" \
- $1 $2 `lvs --noheadings -o segtype $1/$2`
+ $vg $lv `lvs -a --noheadings -o segtype $vg/$lv`
- lvchange --minrecoveryrate 50 $1/$2
- lvchange --maxrecoveryrate 100 $1/$2
+ lvchange --minrecoveryrate 50 $vg/$lv
+ lvchange --maxrecoveryrate 100 $vg/$lv
- [ `lvs --noheadings -o raid_min_recovery_rate $1/$2` == "50" ]
- [ `lvs --noheadings -o raid_max_recovery_rate $1/$2` == "100" ]
+ [ `lvs --noheadings -o raid_min_recovery_rate $vg/$lv` == "50" ]
+ [ `lvs --noheadings -o raid_max_recovery_rate $vg/$lv` == "100" ]
}
-# run_checks <VG> <LV> [snapshot_dev]
+# run_checks <VG> <LV> <"-"|snapshot_dev|"thinpool_data"|"thinpool_meta">
run_checks() {
- # Without snapshots
- run_writemostly_check $1 $2
+ THIN_POSTFIX=""
- run_syncaction_check $1 $2
+ if [ -z $3 ]; then
+ printf "#\n#\n# run_checks: Too few arguments\n#\n#\n"
+ return 1
+ elif [ '-' == $3 ]; then
+ printf "#\n#\n# run_checks: Simple check\n#\n#\n"
- run_refresh_check $1 $2
-
- run_recovery_rate_check $1 $2
+ run_writemostly_check $1 $2
+ run_syncaction_check $1 $2
+ run_refresh_check $1 $2
+ run_recovery_rate_check $1 $2
+ elif [ 'thinpool_data' == $3 ]; then
+ aux target_at_least dm-thin-pool 1 8 0 || return 0
+ printf "#\n#\n# run_checks: RAID as thinpool data\n#\n#\n"
- # With snapshots
- if [ ! -z $3 ]; then
- lvcreate -s $1/$2 -l 4 -n snap $3
+# Hey, specifying devices for thin allocation doesn't work
+# lvconvert --thinpool $1/$2 "$dev6"
+ lvcreate -L 2M -n ${2}_meta $1 "$dev6"
+ lvconvert --thinpool $1/$2 --poolmetadata ${2}_meta
+ lvcreate -T $1/$2 -V 1 -n thinlv
+ THIN_POSTFIX="_tdata"
run_writemostly_check $1 $2
-
run_syncaction_check $1 $2
+ run_refresh_check $1 $2
+ run_recovery_rate_check $1 $2
+ elif [ 'thinpool_meta' == $3 ]; then
+ aux target_at_least dm-thin-pool 1 8 0 || return 0
+ printf "#\n#\n# run_checks: RAID as thinpool metadata\n#\n#\n"
+ lvrename $1/$2 ${2}_meta
+ lvcreate -L 2M -n $2 $1 "$dev6"
+ lvconvert --thinpool $1/$2 --poolmetadata ${2}_meta
+ lvcreate -T $1/$2 -V 1 -n thinlv
+ THIN_POSTFIX="_tmeta"
+
+ run_writemostly_check $1 $2
+ run_syncaction_check $1 $2
run_refresh_check $1 $2
+ run_recovery_rate_check $1 $2
+ elif [ 'snapshot' == $3 ]; then
+ printf "#\n#\n# run_checks: RAID under snapshot\n#\n#\n"
+ lvcreate -s $1/$2 -l 4 -n snap "$dev6"
+ run_writemostly_check $1 $2
+ run_syncaction_check $1 $2
+ run_refresh_check $1 $2
run_recovery_rate_check $1 $2
lvremove -ff $1/snap
+ else
+ printf "#\n#\n# run_checks: Invalid argument\n#\n#\n"
+ return 1
fi
}
@@ -258,24 +332,29 @@ run_checks() {
# MAIN
########################################################
-lvcreate --type raid1 -m 1 -l 2 -n $lv1 $vg "$dev1" "$dev2"
-run_checks $vg $lv1 "$dev3"
-lvremove -ff $vg
-
-lvcreate --type raid4 -i 2 -l 4 -n $lv1 $vg "$dev1" "$dev2" "$dev3" "$dev4"
-run_checks $vg $lv1 "$dev5"
-lvremove -ff $vg
-
-lvcreate --type raid5 -i 2 -l 4 -n $lv1 $vg "$dev1" "$dev2" "$dev3" "$dev4"
-run_checks $vg $lv1 "$dev5"
-lvremove -ff $vg
-
-lvcreate --type raid6 -i 3 -l 6 -n $lv1 $vg \
- "$dev1" "$dev2" "$dev3" "$dev4" "$dev5"
-run_checks $vg $lv1 "$dev6"
-lvremove -ff $vg
-
-lvcreate --type raid10 -m 1 -i 2 -l 4 -n $lv1 $vg \
- "$dev1" "$dev2" "$dev3" "$dev4"
-run_checks $vg $lv1 "$dev5"
-lvremove -ff $vg
+for i in "-" "snapshot" "thinpool_data" "thinpool_meta"; do
+ lvcreate --type raid1 -m 1 -L 2M -n $lv1 $vg \
+ "$dev1" "$dev2"
+ run_checks $vg $lv1 $i
+ lvremove -ff $vg
+
+ lvcreate --type raid4 -i 2 -L 2M -n $lv1 $vg \
+ "$dev1" "$dev2" "$dev3" "$dev4"
+ run_checks $vg $lv1 $i
+ lvremove -ff $vg
+
+ lvcreate --type raid5 -i 2 -L 2M -n $lv1 $vg \
+ "$dev1" "$dev2" "$dev3" "$dev4"
+ run_checks $vg $lv1 $i
+ lvremove -ff $vg
+
+ lvcreate --type raid6 -i 3 -L 2M -n $lv1 $vg \
+ "$dev1" "$dev2" "$dev3" "$dev4" "$dev5"
+ run_checks $vg $lv1 $i
+ lvremove -ff $vg
+
+ lvcreate --type raid10 -m 1 -i 2 -L 2M -n $lv1 $vg \
+ "$dev1" "$dev2" "$dev3" "$dev4"
+ run_checks $vg $lv1 $i
+ lvremove -ff $vg
+done
10 years, 8 months
master - test: pvmove tests for all the different segment types.
by Jonathan Brassow
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=0799e81ee08a76...
Commit: 0799e81ee08a76c877d774b2f7df75ad3ec29897
Parent: 2ef48b91ed74f732b6150a9492da624d204b331d
Author: Jonathan Brassow <jbrassow(a)redhat.com>
AuthorDate: Mon Aug 26 16:38:54 2013 -0500
Committer: Jonathan Brassow <jbrassow(a)redhat.com>
CommitterDate: Mon Aug 26 16:38:54 2013 -0500
test: pvmove tests for all the different segment types.
Test moving linear, mirror, snapshot, RAID1,5,10, thinpool, thin
and thin on RAID. Perform the moves along with a dummy LV and
also without the dummy LV by specifying a logical volume name as
an argument to pvmove.
---
test/shell/pvmove-all-segtypes.sh | 304 +++++++++++++++++++++++++++++++++++++
1 files changed, 304 insertions(+), 0 deletions(-)
diff --git a/test/shell/pvmove-all-segtypes.sh b/test/shell/pvmove-all-segtypes.sh
new file mode 100644
index 0000000..13b8fba
--- /dev/null
+++ b/test/shell/pvmove-all-segtypes.sh
@@ -0,0 +1,304 @@
+#!/bin/sh
+# Copyright (C) 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="ensure pvmove works with all segment types"
+
+. lib/test
+
+which mkfs.ext2 || skip
+which md5sum || skip
+
+# ---------------------------------------------------------------------
+# Utilities
+lvdev_() {
+ echo "$DM_DEV_DIR/$1/$2"
+}
+
+# lv_is_on_pvs <VG> <LV> <PV1> <PV2> ...
+lv_is_on_pvs() {
+ local vg=$1
+ local lv_list=( $2 )
+ local new_lv_list=()
+ local run_again=true
+
+ shift 2
+
+ while $run_again; do
+ run_again=false
+ for tmplv in ${lv_list[*]}; do
+ if [[ $(lvs -a --noheadings -o attr $vg/$tmplv) =~ ^[[:space:]]*r.* ]] ||
+ [[ $(lvs -a --noheadings -o attr $vg/$tmplv) =~ ^[[:space:]]*R.* ]]; then
+ # Expand RAID
+ echo "$tmplv is a RAID LV"
+ new_lv_list=( ${new_lv_list[*]} `lvs -a --noheadings -o name | grep ${tmplv}_r` )
+ run_again=true
+ elif [[ $(lvs -a --noheadings -o attr $vg/$tmplv) =~ ^[[:space:]]*m.* ]] ||
+ [[ $(lvs -a --noheadings -o attr $vg/$tmplv) =~ ^[[:space:]]*M.* ]]; then
+ # Expand Mirror
+ echo "$tmplv is a mirror LV"
+ new_lv_list=( ${new_lv_list[*]} `lvs -a --noheadings -o devices $vg/$tmplv | sed s/,/' '/g` )
+ new_lv_list=( ${new_lv_list[*]} `lvs -a --noheadings -o mirror_log $vg/$tmplv | sed s/,/' '/g` )
+ run_again=true
+ elif [[ $(lvs -a --noheadings -o attr $vg/$tmplv) =~ ^[[:space:]]*t.* ]]; then
+ # Expand Thin Pool
+ echo "$tmplv is a thin-pool LV"
+ new_lv_list=( ${new_lv_list[*]} `lvs -a --noheadings -o data_lv,metadata_lv $vg/$tmplv | sed s/,/' '/g` )
+ run_again=true
+ elif [[ $(lvs -a --noheadings -o attr $vg/$tmplv) =~ ^[[:space:]]*V.* ]]; then
+ # Expand Thin-LV
+ echo "$tmplv is a thin-LV"
+ new_lv_list=( ${new_lv_list[*]} `lvs -a --noheadings -o pool_lv $vg/$tmplv | sed s/,/' '/g` )
+ run_again=true
+ elif [[ $(lvs -a --noheadings -o attr $vg/$tmplv) =~ ^[[:space:]]*e.* ]] &&
+ lvs -a --noheadings -o devices $vg/$tmplv | grep $tmplv; then
+ # Expand Thin Pool Meta, which is also RAID
+ echo "$tmplv is a thinpool (RAID) metadata"
+ new_lv_list=( ${new_lv_list[*]} `lvs -a --noheadings -o name | grep ${tmplv}_r` )
+ run_again=true
+ else
+ new_lv_list=( ${new_lv_list[*]} $tmplv )
+ fi
+ done
+ printf "\nOld LV list: ${lv_list[*]}\n\n"
+
+ lv_list=()
+ for tmplv in ${new_lv_list[*]}; do
+ lv_list=( ${lv_list[*]} $(echo $tmplv | sed s/\(.*\)/''/ | sed s/\\[/''/ | sed s/]/''/) )
+ done
+ printf "\nExpanded LV list: ${lv_list[*]}\n\n"
+
+ new_lv_list=()
+ done
+
+ [ -e out-$$ ] && rm out-$$
+ for tmplv in ${lv_list[*]}; do
+ lvs -a -odevices --noheadings $vg/$tmplv | sed 's/,/\n/g' >> out-$$
+ done
+
+ #is on all specified devs
+ for d in $*; do
+ if ! grep "$d(" out-$$; then
+ cat out-$$
+ false
+ fi
+ done
+
+ #isn't on any other dev (we are set -e remember)
+ cat out-$$
+ [ -e tmp-$$ ] && rm tmp-$$
+ for d in $*; do
+ echo "Removing $d"
+ ! grep -v "$d(" out-$$ >> tmp-$$
+ mv tmp-$$ out-$$
+ cat out-$$
+ done
+ # out-$$ must be empty - no additional devs allowed
+ [ ! -s out-$$ ]
+
+ rm out-$$
+ return 0
+}
+
+save_dev_sum_() {
+ mkfs.ext2 $1 > /dev/null && md5sum $1 > md5.$(basename $1)
+}
+
+check_dev_sum_() {
+ md5sum -c md5.$(basename $1)
+}
+# ---------------------------------------------------------------------
+
+aux prepare_vg 5 30
+
+# Each of the following tests does:
+# 1) Create two LVs - one linear and one other segment type
+# The two LVs will share a PV.
+# 2) Move both LVs together
+# 3) Move only the second LV by name
+
+printf "##\n# Testing pvmove of linear LV\n##\n"
+lvcreate -l 2 -n ${lv1}_foo $vg "$dev1"
+lvcreate -l 2 -n $lv1 $vg "$dev1"
+lv_is_on_pvs $vg ${lv1}_foo "$dev1"
+lv_is_on_pvs $vg $lv1 "$dev1"
+save_dev_sum_ $(lvdev_ $vg $lv1)
+pvmove "$dev1" "$dev5"
+lv_is_on_pvs $vg ${lv1}_foo "$dev5"
+lv_is_on_pvs $vg $lv1 "$dev5"
+check_dev_sum_ $(lvdev_ $vg $lv1)
+pvmove -n $lv1 "$dev5" "$dev4"
+lv_is_on_pvs $vg $lv1 "$dev4"
+lv_is_on_pvs $vg ${lv1}_foo "$dev5"
+check_dev_sum_ $(lvdev_ $vg $lv1)
+lvremove -ff $vg
+
+printf "##\n# Testing pvmove of stripe LV\n##\n"
+lvcreate -l 2 -n ${lv1}_foo $vg "$dev1"
+lvcreate -l 4 -i 2 -n $lv1 $vg "$dev1" "$dev2"
+lv_is_on_pvs $vg ${lv1}_foo "$dev1"
+lv_is_on_pvs $vg $lv1 "$dev1" "$dev2"
+save_dev_sum_ $(lvdev_ $vg $lv1)
+pvmove "$dev1" "$dev5"
+lv_is_on_pvs $vg ${lv1}_foo "$dev5"
+lv_is_on_pvs $vg $lv1 "$dev2" "$dev5"
+check_dev_sum_ $(lvdev_ $vg $lv1)
+pvmove -n $lv1 "$dev5" "$dev4"
+lv_is_on_pvs $vg $lv1 "$dev2" "$dev4"
+lv_is_on_pvs $vg ${lv1}_foo "$dev5"
+check_dev_sum_ $(lvdev_ $vg $lv1)
+lvremove -ff $vg
+
+printf "##\n# Testing pvmove of mirror LV\n##\n"
+lvcreate -l 2 -n ${lv1}_foo $vg "$dev1"
+lvcreate -l 2 --type mirror -m 1 -n $lv1 $vg "$dev1" "$dev2"
+lv_is_on_pvs $vg ${lv1}_foo "$dev1"
+lv_is_on_pvs $vg $lv1 "$dev1" "$dev2"
+save_dev_sum_ $(lvdev_ $vg $lv1)
+pvmove "$dev1" "$dev5"
+lv_is_on_pvs $vg ${lv1}_foo "$dev5"
+lv_is_on_pvs $vg $lv1 "$dev2" "$dev5"
+check_dev_sum_ $(lvdev_ $vg $lv1)
+pvmove -n $lv1 "$dev5" "$dev4"
+lv_is_on_pvs $vg $lv1 "$dev2" "$dev4"
+lv_is_on_pvs $vg ${lv1}_foo "$dev5"
+check_dev_sum_ $(lvdev_ $vg $lv1)
+lvremove -ff $vg
+
+# Dummy LV and snap share dev1, while origin is on dev2
+printf "##\n# Testing pvmove of snapshot LV\n##\n"
+lvcreate -l 2 -n ${lv1}_foo $vg "$dev1"
+lvcreate -l 2 -n $lv1 $vg "$dev2"
+lvcreate -s $vg/$lv1 -l 2 -n snap "$dev1"
+lv_is_on_pvs $vg ${lv1}_foo "$dev1"
+lv_is_on_pvs $vg snap "$dev1"
+save_dev_sum_ $(lvdev_ $vg snap)
+pvmove "$dev1" "$dev5"
+lv_is_on_pvs $vg ${lv1}_foo "$dev5"
+lv_is_on_pvs $vg snap "$dev5"
+check_dev_sum_ $(lvdev_ $vg snap)
+pvmove -n snap "$dev5" "$dev4"
+lv_is_on_pvs $vg snap "$dev4"
+lv_is_on_pvs $vg ${lv1}_foo "$dev5"
+check_dev_sum_ $(lvdev_ $vg snap)
+lvremove -ff $vg
+
+##
+# RAID
+##
+if aux target_at_least dm-raid 1 3 5; then
+ printf "##\n# Testing pvmove of RAID1 LV\n##\n"
+ lvcreate -l 2 -n ${lv1}_foo $vg "$dev1"
+ lvcreate -l 2 --type raid1 -m 1 -n $lv1 $vg "$dev1" "$dev2"
+ lv_is_on_pvs $vg ${lv1}_foo "$dev1"
+ lv_is_on_pvs $vg $lv1 "$dev1" "$dev2"
+ save_dev_sum_ $(lvdev_ $vg $lv1)
+ pvmove "$dev1" "$dev5"
+ lv_is_on_pvs $vg ${lv1}_foo "$dev5"
+ lv_is_on_pvs $vg $lv1 "$dev2" "$dev5"
+ check_dev_sum_ $(lvdev_ $vg $lv1)
+ pvmove -n $lv1 "$dev5" "$dev4"
+ lv_is_on_pvs $vg $lv1 "$dev2" "$dev4"
+ lv_is_on_pvs $vg ${lv1}_foo "$dev5"
+ check_dev_sum_ $(lvdev_ $vg $lv1)
+ lvremove -ff $vg
+
+ printf "##\n# Testing pvmove of RAID10 LV\n##\n"
+ lvcreate -l 2 -n ${lv1}_foo $vg "$dev1"
+ lvcreate -l 4 --type raid10 -i 2 -m 1 -n $lv1 $vg \
+ "$dev1" "$dev2" "$dev3" "$dev4"
+ lv_is_on_pvs $vg ${lv1}_foo "$dev1"
+ lv_is_on_pvs $vg $lv1 "$dev1" "$dev2" "$dev3" "$dev4"
+ save_dev_sum_ $(lvdev_ $vg $lv1)
+ pvmove "$dev1" "$dev5"
+ lv_is_on_pvs $vg ${lv1}_foo "$dev5"
+ lv_is_on_pvs $vg $lv1 "$dev2" "$dev3" "$dev4" "$dev5"
+ check_dev_sum_ $(lvdev_ $vg $lv1)
+ pvmove -n $lv1 "$dev5" "$dev1"
+ lv_is_on_pvs $vg $lv1 "$dev1" "$dev2" "$dev3" "$dev4"
+ lv_is_on_pvs $vg ${lv1}_foo "$dev5"
+ check_dev_sum_ $(lvdev_ $vg $lv1)
+ lvremove -ff $vg
+
+ printf "##\n# Testing pvmove of RAID5 LV\n##\n"
+ lvcreate -l 2 -n ${lv1}_foo $vg "$dev1"
+ lvcreate -l 4 --type raid5 -i 2 -n $lv1 $vg \
+ "$dev1" "$dev2" "$dev3"
+ lv_is_on_pvs $vg ${lv1}_foo "$dev1"
+ lv_is_on_pvs $vg $lv1 "$dev1" "$dev2" "$dev3"
+ save_dev_sum_ $(lvdev_ $vg $lv1)
+ pvmove "$dev1" "$dev5"
+ lv_is_on_pvs $vg ${lv1}_foo "$dev5"
+ lv_is_on_pvs $vg $lv1 "$dev2" "$dev3" "$dev5"
+ check_dev_sum_ $(lvdev_ $vg $lv1)
+ pvmove -n $lv1 "$dev5" "$dev4"
+ lv_is_on_pvs $vg $lv1 "$dev2" "$dev3" "$dev4"
+ lv_is_on_pvs $vg ${lv1}_foo "$dev5"
+ check_dev_sum_ $(lvdev_ $vg $lv1)
+ lvremove -ff $vg
+fi
+
+##
+# Thin
+##
+if aux target_at_least dm-thin-pool 1 8 0; then
+
+ printf "##\n# Testing pvmove of thin-pool LV\n##\n"
+ lvcreate -l 2 -n ${lv1}_foo $vg "$dev1"
+ lvcreate -T $vg/$lv1 -l 4 "$dev1"
+ lv_is_on_pvs $vg ${lv1}_foo "$dev1"
+ lv_is_on_pvs $vg $lv1 "$dev1"
+ save_dev_sum_ $(lvdev_ $vg $lv1)
+ pvmove "$dev1" "$dev5"
+ lv_is_on_pvs $vg ${lv1}_foo "$dev5"
+ lv_is_on_pvs $vg $lv1 "$dev5"
+ check_dev_sum_ $(lvdev_ $vg $lv1)
+ pvmove -n $lv1 "$dev5" "$dev4"
+ lv_is_on_pvs $vg $lv1 "$dev4"
+ lv_is_on_pvs $vg ${lv1}_foo "$dev5"
+ check_dev_sum_ $(lvdev_ $vg $lv1)
+ lvremove -ff $vg
+
+ printf "##\n# Testing pvmove of thin LV\n##\n"
+ lvcreate -l 2 -n ${lv1}_foo $vg "$dev1"
+ lvcreate -T $vg/${lv1}_pool -l 4 -V 8 -n $lv1 "$dev1"
+ lv_is_on_pvs $vg ${lv1}_foo "$dev1"
+ lv_is_on_pvs $vg $lv1 "$dev1"
+ save_dev_sum_ $(lvdev_ $vg $lv1)
+ pvmove "$dev1" "$dev5"
+ lv_is_on_pvs $vg ${lv1}_foo "$dev5"
+ lv_is_on_pvs $vg $lv1 "$dev5"
+ check_dev_sum_ $(lvdev_ $vg $lv1)
+ pvmove -n $lv1 "$dev5" "$dev4"
+ lv_is_on_pvs $vg $lv1 "$dev4"
+ lv_is_on_pvs $vg ${lv1}_foo "$dev5"
+ check_dev_sum_ $(lvdev_ $vg $lv1)
+ lvremove -ff $vg
+
+ printf "##\n# Testing pvmove of thin LV on RAID\n##\n"
+ lvcreate -l 2 -n ${lv1}_foo $vg "$dev1"
+ lvcreate --type raid1 -m 1 -l 4 -n ${lv1}_raid1_pool $vg "$dev1" "$dev2"
+ lvcreate --type raid1 -m 1 -l 4 -n ${lv1}_raid1_meta $vg "$dev1" "$dev2"
+ lvconvert --thinpool $vg/${lv1}_raid1_pool \
+ --poolmetadata ${lv1}_raid1_meta
+ lvcreate -T $vg/${lv1}_raid1_pool -V 8 -n $lv1
+ lv_is_on_pvs $vg ${lv1}_foo "$dev1"
+ lv_is_on_pvs $vg $lv1 "$dev1" "$dev2"
+ save_dev_sum_ $(lvdev_ $vg $lv1)
+ pvmove "$dev1" "$dev5"
+ lv_is_on_pvs $vg ${lv1}_foo "$dev5"
+ lv_is_on_pvs $vg $lv1 "$dev2" "$dev5"
+ check_dev_sum_ $(lvdev_ $vg $lv1)
+ pvmove -n $lv1 "$dev5" "$dev4"
+ lv_is_on_pvs $vg $lv1 "$dev2" "$dev4"
+ lv_is_on_pvs $vg ${lv1}_foo "$dev5"
+ check_dev_sum_ $(lvdev_ $vg $lv1)
+ lvremove -ff $vg
+fi
10 years, 8 months
master - pvmove: Allow moving snapshot/origin. Disallow converting and merging LVs
by Jonathan Brassow
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=2ef48b91ed74f7...
Commit: 2ef48b91ed74f732b6150a9492da624d204b331d
Parent: caa77b33f2d5e59f2906b9f08f59ac2e64b14682
Author: Jonathan Brassow <jbrassow(a)redhat.com>
AuthorDate: Mon Aug 26 16:36:30 2013 -0500
Committer: Jonathan Brassow <jbrassow(a)redhat.com>
CommitterDate: Mon Aug 26 16:36:30 2013 -0500
pvmove: Allow moving snapshot/origin. Disallow converting and merging LVs
The patch allows the user to also pvmove snapshots and origin logical
volumes. This means pvmove should be able to move all segment types.
I have, however, disallowed moving converting or merging logical volumes.
---
WHATS_NEW | 2 ++
man/pvmove.8.in | 5 -----
tools/pvmove.c | 12 +++++++-----
3 files changed, 9 insertions(+), 10 deletions(-)
diff --git a/WHATS_NEW b/WHATS_NEW
index 069c3c2..29af78d 100644
--- a/WHATS_NEW
+++ b/WHATS_NEW
@@ -1,5 +1,7 @@
Version 2.02.101 -
===================================
+ Disable pvmove of merging or converting logical volumes.
+ Enable pvmove of snapshots and snapshot origins.
Fix inability to specify LV name when pvmove'ing a RAID, mirror, or thin-LV.
Inform lvmetad about any lost PV label to make it in sync with system state.
Support most of lvchange operations on stacked thin pool meta/data LVs.
diff --git a/man/pvmove.8.in b/man/pvmove.8.in
index ba6ea1e..79ccf1c 100644
--- a/man/pvmove.8.in
+++ b/man/pvmove.8.in
@@ -75,9 +75,6 @@ is updated so that the Logical Volumes reflect the new data locations.
Note that this new process cannot support the original LVM1
type of on-disk metadata. Metadata can be converted using \fBvgconvert\fP(8).
-N.B. The moving of non-thinly provisioned snapshots and their
-origins is not supported.
-
.SH OPTIONS
See \fBlvm\fP(8) for common options.
.TP
@@ -110,8 +107,6 @@ To move all Physical Extents that are used by simple Logical Volumes on
.sp
.B pvmove /dev/sdb1
.P
-Any non-thinly provisioned snapshots and their origins are left unchanged.
-.P
Additionally, a specific destination device /dev/sdc1
can be specified like this:
.sp
diff --git a/tools/pvmove.c b/tools/pvmove.c
index 2868290..1007370 100644
--- a/tools/pvmove.c
+++ b/tools/pvmove.c
@@ -295,6 +295,13 @@ static struct logical_volume *_set_up_pvmove_lv(struct cmd_context *cmd,
if (!lv_is_on_pvs(lv, source_pvl))
continue;
+ if (lv->status & (CONVERTING | MERGING)) {
+ log_error("Unable to pvmove when %s volumes are present",
+ (lv->status & CONVERTING) ?
+ "converting" : "merging");
+ return NULL;
+ }
+
if (seg_is_raid(first_seg(lv)) ||
seg_is_mirrored(first_seg(lv))) {
dm_list_init(&trim_list);
@@ -327,11 +334,6 @@ static struct logical_volume *_set_up_pvmove_lv(struct cmd_context *cmd,
if (!lv_is_on_pvs(lv, source_pvl))
continue;
- if (lv_is_origin(lv) || lv_is_cow(lv)) {
- lv_skipped = 1;
- log_print_unless_silent("Skipping snapshot-related LV %s", lv->name);
- continue;
- }
seg = first_seg(lv);
if (seg_is_raid(seg) || seg_is_mirrored(seg) ||
lv_is_thin_volume(lv) || lv_is_thin_pool(lv)) {
10 years, 8 months
master - pvmove: Fix inability to specify LV name when moving RAID, mirror, or thin LV
by Jonathan Brassow
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=caa77b33f2d5e5...
Commit: caa77b33f2d5e59f2906b9f08f59ac2e64b14682
Parent: d34ab5e0d39543db4f17994432a49a77709b3487
Author: Jonathan Brassow <jbrassow(a)redhat.com>
AuthorDate: Mon Aug 26 14:12:31 2013 -0500
Committer: Jonathan Brassow <jbrassow(a)redhat.com>
CommitterDate: Mon Aug 26 14:12:31 2013 -0500
pvmove: Fix inability to specify LV name when moving RAID, mirror, or thin LV
Top-level LVs (like RAID, mirror or thin) are ignored when determining which
portions of an LV to pvmove. If the user specified the name of an LV to
move and it was one of the above types, it would be skipped. The code would
never move on to check whether its sub-LVs needed moving because their names
did not match what the user specified.
The solution is to check whether a sub-LVs is part of the LV whose name was
specified by the user - not just if there was a name match.
---
WHATS_NEW | 1 +
tools/pvmove.c | 26 +++++++++++++++++++++++++-
2 files changed, 26 insertions(+), 1 deletions(-)
diff --git a/WHATS_NEW b/WHATS_NEW
index c0744f6..069c3c2 100644
--- a/WHATS_NEW
+++ b/WHATS_NEW
@@ -1,5 +1,6 @@
Version 2.02.101 -
===================================
+ Fix inability to specify LV name when pvmove'ing a RAID, mirror, or thin-LV.
Inform lvmetad about any lost PV label to make it in sync with system state.
Support most of lvchange operations on stacked thin pool meta/data LVs.
Add ability to pvmove RAID, mirror, and thin volumes.
diff --git a/tools/pvmove.c b/tools/pvmove.c
index 8e95048..2868290 100644
--- a/tools/pvmove.c
+++ b/tools/pvmove.c
@@ -16,6 +16,7 @@
#include "tools.h"
#include "polldaemon.h"
#include "display.h"
+#include "metadata.h" /* for 'get_only_segment_using_this_lv' */
#define PVMOVE_FIRST_TIME 0x00000001 /* Called for first time */
#define PVMOVE_EXCLUSIVE 0x00000002 /* Require exclusive LV */
@@ -209,6 +210,29 @@ static int _insert_pvmove_mirrors(struct cmd_context *cmd,
return 1;
}
+/*
+ * Is 'lv' a sub_lv of the LV by the name of 'lv_name'?
+ *
+ * Returns: 1 if true, 0 otherwise
+ */
+static int sub_lv_of(struct logical_volume *lv, const char *lv_name)
+{
+ struct lv_segment *seg;
+
+ /* Sub-LVs only ever have one segment using them */
+ if (dm_list_size(&lv->segs_using_this_lv) != 1)
+ return 0;
+
+ if (!(seg = get_only_segment_using_this_lv(lv)))
+ return_0;
+
+ if (!strcmp(seg->lv->name, lv_name))
+ return 1;
+
+ /* Continue up the tree */
+ return sub_lv_of(seg->lv, lv_name);
+}
+
/* Create new LV with mirror segments for the required copies */
static struct logical_volume *_set_up_pvmove_lv(struct cmd_context *cmd,
struct volume_group *vg,
@@ -295,7 +319,7 @@ static struct logical_volume *_set_up_pvmove_lv(struct cmd_context *cmd,
if (lv == lv_mirr)
continue;
if (lv_name) {
- if (strcmp(lv->name, lv_name))
+ if (strcmp(lv->name, lv_name) && !sub_lv_of(lv, lv_name))
continue;
lv_found = 1;
}
10 years, 8 months
master - WHATS_NEW: for 4d3b5724e0b51782000a45027de00e0fed1c9833
by Peter Rajnoha
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=d34ab5e0d39543...
Commit: d34ab5e0d39543db4f17994432a49a77709b3487
Parent: 4d3b5724e0b51782000a45027de00e0fed1c9833
Author: Peter Rajnoha <prajnoha(a)redhat.com>
AuthorDate: Mon Aug 26 15:52:15 2013 +0200
Committer: Peter Rajnoha <prajnoha(a)redhat.com>
CommitterDate: Mon Aug 26 15:52:15 2013 +0200
WHATS_NEW: for 4d3b5724e0b51782000a45027de00e0fed1c9833
---
WHATS_NEW | 1 +
1 files changed, 1 insertions(+), 0 deletions(-)
diff --git a/WHATS_NEW b/WHATS_NEW
index bf13023..c0744f6 100644
--- a/WHATS_NEW
+++ b/WHATS_NEW
@@ -1,5 +1,6 @@
Version 2.02.101 -
===================================
+ Inform lvmetad about any lost PV label to make it in sync with system state.
Support most of lvchange operations on stacked thin pool meta/data LVs.
Add ability to pvmove RAID, mirror, and thin volumes.
Make lvm2-activation-generator silent unless it's in error state.
10 years, 8 months
master - udev: inform lvmetad about lost PV label
by Peter Rajnoha
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=4d3b5724e0b517...
Commit: 4d3b5724e0b51782000a45027de00e0fed1c9833
Parent: 6b416f837f4ee71ca5705cb40fad22b26b0c664a
Author: Peter Rajnoha <prajnoha(a)redhat.com>
AuthorDate: Mon Aug 26 15:27:00 2013 +0200
Committer: Peter Rajnoha <prajnoha(a)redhat.com>
CommitterDate: Mon Aug 26 15:40:16 2013 +0200
udev: inform lvmetad about lost PV label
In stacked environment where we have a PV layered on top of a
snapshot LV and then removing the LV, lvmetad still keeps information
about the PV:
[0] raw/~ $ pvcreate /dev/sda
Physical volume "/dev/sda" successfully created
[0] raw/~ $ vgcreate vg /dev/sda
Volume group "vg" successfully created
[0] raw/~ $ lvcreate -L32m vg
Logical volume "lvol0" created
[0] raw/~ $ lvcreate -L32m -s vg/lvol0
Logical volume "lvol1" created
[0] raw/~ $ pvcreate /dev/vg/lvol1
Physical volume "/dev/vg/lvol1" successfully created
[0] raw/~ $ lvremove -ff vg/lvol1
Logical volume "lvol1" successfully removed
[0] raw/~ $ pvs
No device found for PV BdNlu2-7bHV-XcIp-mFFC-PPuR-ef6K-yffdzO.
PV VG Fmt Attr PSize PFree
/dev/sda vg lvm2 a-- 124.00m 92.00m
[0] raw/~ $ pvscan --cache --major 253 --minor 3
Device 253:3 not found. Cleared from lvmetad cache.
This is because of the reactivation that is done just before
snapshot removal as part of the process (vg/lvol1 from the example above).
This causes a CHANGE event to be generated, but any scan done
on the LV does not see the original data anymore (in this case
the stacked PV label on top) and consequently the ID_FS_TYPE="LVM2_member"
(provided by blkid scan) is not stored in udev db anymore for the LV.
Consequently, the pvscan --cache is not run anymore as the dev is not
identified as LVM PV by the "LVM2_member" id - lvmetad loses this info
and still keeps records about the PV.
We can run into a very similar problem with erasing the PV label directly:
[0] raw/~ $ lvcreate -L32m vg
Logical volume "lvol0" created
[0] raw/~ $ pvcreate /dev/vg/lvol0
Physical volume "/dev/vg/lvol0" successfully created
[0] raw/~ $ dd if=/dev/zero of=/dev/vg/lvol0 bs=1M
dd: error writing '/dev/vg/lvol0': No space left on device
33+0 records in
32+0 records out
33554432 bytes (34 MB) copied, 0.380921 s, 88.1 MB/s
[0] raw/~ $ pvs
PV VG Fmt Attr PSize PFree
/dev/sda vg lvm2 a-- 124.00m 92.00m
/dev/vg/lvol0 lvm2 a-- 32.00m 32.00m
[0] raw/~ $ pvscan --cache --major 253 --minor 2
No PV label found on /dev/vg/lvol0.
This patch adds detection of this change from ID_FS_LABEL="LVM2_member"
to ID_FS_LABEL="<whatever_else>" and hence informing the lvmetad
about PV being gone.
---
udev/13-dm-disk.rules.in | 4 ++++
udev/69-dm-lvm-metad.rules.in | 3 +++
2 files changed, 7 insertions(+), 0 deletions(-)
diff --git a/udev/13-dm-disk.rules.in b/udev/13-dm-disk.rules.in
index 1920260..f8e4ac6 100644
--- a/udev/13-dm-disk.rules.in
+++ b/udev/13-dm-disk.rules.in
@@ -17,6 +17,10 @@ ENV{DM_UDEV_DISABLE_DISK_RULES_FLAG}=="1", GOTO="dm_end"
SYMLINK+="disk/by-id/dm-name-$env{DM_NAME}"
ENV{DM_UUID}=="?*", SYMLINK+="disk/by-id/dm-uuid-$env{DM_UUID}"
+# Save previously detected dev type.
+IMPORT{db}="ID_FS_TYPE"
+ENV{ID_FS_TYPE}=="?*", ENV{DM_ID_FS_TYPE_OLD}="$env{ID_FS_TYPE}", ENV{ID_FS_TYPE}=""
+
ENV{DM_SUSPENDED}=="1", GOTO="dm_end"
(BLKID_RULE)
diff --git a/udev/69-dm-lvm-metad.rules.in b/udev/69-dm-lvm-metad.rules.in
index d5087e3..2d6720e 100644
--- a/udev/69-dm-lvm-metad.rules.in
+++ b/udev/69-dm-lvm-metad.rules.in
@@ -17,6 +17,9 @@
SUBSYSTEM!="block", GOTO="lvm_end"
(LVM_EXEC_RULE)
+# If the PV label got lost, inform lvmetad about it.
+ENV{DM_ID_FS_TYPE_OLD}=="LVM2_member", ENV{DM_ID_FS_TYPE}!="LVM2_member", GOTO="lvm_scan"
+
# Only process devices already marked as a PV - this requires blkid to be called before.
ENV{ID_FS_TYPE}!="LVM2_member|LVM1_member", GOTO="lvm_end"
10 years, 8 months
master - thin: support lvchange for data and metadata
by Zdenek Kabelac
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=6b416f837f4ee7...
Commit: 6b416f837f4ee71ca5705cb40fad22b26b0c664a
Parent: 7d6a125e97085ea140c582a0b6c1ef2ca4cb0f93
Author: Zdenek Kabelac <zkabelac(a)redhat.com>
AuthorDate: Sat Aug 10 01:13:27 2013 +0200
Committer: Zdenek Kabelac <zkabelac(a)redhat.com>
CommitterDate: Mon Aug 26 14:55:22 2013 +0200
thin: support lvchange for data and metadata
Support lvchange operation on stacked thin pool data and metadata
volumes.
---
WHATS_NEW | 1 +
tools/lvchange.c | 8 +++++++-
2 files changed, 8 insertions(+), 1 deletions(-)
diff --git a/WHATS_NEW b/WHATS_NEW
index 3ea8786..bf13023 100644
--- a/WHATS_NEW
+++ b/WHATS_NEW
@@ -1,5 +1,6 @@
Version 2.02.101 -
===================================
+ Support most of lvchange operations on stacked thin pool meta/data LVs.
Add ability to pvmove RAID, mirror, and thin volumes.
Make lvm2-activation-generator silent unless it's in error state.
Remove "mpath major is not dm major" msg for mpath component scan (2.02.94).
diff --git a/tools/lvchange.c b/tools/lvchange.c
index 525022f..34e230c 100644
--- a/tools/lvchange.c
+++ b/tools/lvchange.c
@@ -982,7 +982,13 @@ static int lvchange_single(struct cmd_context *cmd, struct logical_volume *lv,
lv_is_virtual_origin(origin = origin_from_cow(lv)))
lv = origin;
- if (!(lv_is_visible(lv)) && !lv_is_virtual_origin(lv)) {
+ if ((lv_is_thin_pool_data(lv) || lv_is_thin_pool_metadata(lv)) &&
+ !arg_count(cmd, activate_ARG) &&
+ !arg_count(cmd, permission_ARG) &&
+ !arg_count(cmd, setactivationskip_ARG))
+ /* Rest can be changed for stacked thin pool meta/data volumes */
+ ;
+ else if (!(lv_is_visible(lv)) && !lv_is_virtual_origin(lv)) {
log_error("Unable to change internal LV %s directly",
lv->name);
return ECMD_FAILED;
10 years, 8 months
master - test: add process-each-vg and process-each-lv
by David Teigland
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=7d6a125e97085e...
Commit: 7d6a125e97085ea140c582a0b6c1ef2ca4cb0f93
Parent: 506bc045b55799df3c20107020e76e0e42995f04
Author: David Teigland <teigland(a)redhat.com>
AuthorDate: Fri Aug 23 14:38:48 2013 -0500
Committer: David Teigland <teigland(a)redhat.com>
CommitterDate: Fri Aug 23 14:38:48 2013 -0500
test: add process-each-vg and process-each-lv
These test the toollib functions that select
vgs/lvs to process based on command line args:
empty, vg name(s), lv names(s), vg tag(s),
lv tags(s), and combinations of all.
---
test/shell/process-each-lv.sh | 954 +++++++++++++++++++++++++++++++++++++++++
test/shell/process-each-vg.sh | 264 ++++++++++++
2 files changed, 1218 insertions(+), 0 deletions(-)
diff --git a/test/shell/process-each-lv.sh b/test/shell/process-each-lv.sh
new file mode 100644
index 0000000..0140c26
--- /dev/null
+++ b/test/shell/process-each-lv.sh
@@ -0,0 +1,954 @@
+#!/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_lv'
+
+. lib/test
+
+aux prepare_devs 10
+
+#
+# process_each_lv is used by a number of lv commands:
+# lvconvert lv (none is error)
+# lvchange vg|lv (none is error)
+# lvremove vg|lv (none is error)
+# lvdisplay [vg|lv] (none is all)
+# vgmknodes [vg|lv] (none is all)
+# lvs [vg|lv] (none is all)
+# lvscan (none is all)
+#
+# (lv can also be a tag matching an lv tag, and
+# vg can also be a tag matching a vg tag.)
+#
+# The logic in process_each_vl is mainly related to
+# selecting which vgs/lvs to process.
+#
+
+#
+# test lvremove vg|lv names
+#
+
+# set up vgs/lvs that we will remove
+vgcreate $vg1 "$dev1" "$dev2"
+vgcreate $vg2 "$dev3" "$dev4"
+vgcreate $vg3 "$dev5" "$dev6"
+vgcreate $vg4 "$dev7" "$dev8"
+vgcreate $vg5 "$dev9" "$dev10"
+lvcreate -l 2 -n $lv1 $vg1
+lvcreate -l 2 -n $lv1 $vg2
+lvcreate -l 2 -n $lv2 $vg2
+lvcreate -l 2 -n $lv1 $vg3
+lvcreate -l 2 -n $lv2 $vg3
+lvcreate -l 2 -n $lv3 $vg3
+lvcreate -l 2 -n $lv1 $vg5
+lvcreate -l 2 -n $lv2 $vg5
+lvcreate -l 2 -n $lv3 $vg5
+lvcreate -l 2 -n $lv4 $vg5
+lvcreate -l 2 -n $lv5 $vg5
+vgchange -an $vg1
+vgchange -an $vg2
+vgchange -an $vg3
+vgchange -an $vg4
+vgchange -an $vg5
+
+not lvremove
+not lvremove garbage
+not lvremove $vg1/garbage
+
+lvremove $vg1
+lvs $vg1
+not lvs $vg1/$lv1
+vgremove $vg1
+
+lvremove $vg2
+lvs $vg2
+not lvs $vg2/$lv1
+not lvs $vg2/$lv2
+vgremove $vg2
+
+lvremove $vg3/$lv1
+lvremove $vg3/$lv2 $vg3/$lv3
+lvs $vg3
+not lvs $vg3/$lv1
+not lvs $vg3/$lv2
+not lvs $vg3/$lv3
+vgremove $vg3
+
+lvremove $vg4
+lvs $vg4
+vgremove $vg4
+
+lvremove $vg5/$lv1 $vg5 $vg5/$lv3
+not lvs $vg5/$lv1
+not lvs $vg5/$lv2
+not lvs $vg5/$lv3
+not lvs $vg5/$lv4
+not lvs $vg5/$lv5
+vgremove $vg5
+
+
+#
+# test lvremove vg|lv names from multiple vgs
+#
+
+# set up vgs/lvs that we will remove
+vgcreate $vg1 "$dev1" "$dev2"
+vgcreate $vg2 "$dev3" "$dev4"
+vgcreate $vg3 "$dev5" "$dev6"
+vgcreate $vg4 "$dev7" "$dev8"
+vgcreate $vg5 "$dev9" "$dev10"
+lvcreate -l 2 -n $lv1 $vg1
+lvcreate -l 2 -n $lv1 $vg2
+lvcreate -l 2 -n $lv2 $vg2
+lvcreate -l 2 -n $lv1 $vg3
+lvcreate -l 2 -n $lv2 $vg3
+lvcreate -l 2 -n $lv3 $vg3
+lvcreate -l 2 -n $lv1 $vg5
+lvcreate -l 2 -n $lv2 $vg5
+lvcreate -l 2 -n $lv3 $vg5
+lvcreate -l 2 -n $lv4 $vg5
+lvcreate -l 2 -n $lv5 $vg5
+vgchange -an $vg1
+vgchange -an $vg2
+vgchange -an $vg3
+vgchange -an $vg4
+vgchange -an $vg5
+
+lvremove $vg2 $vg3/$lv3 $vg5/$lv1
+not lvs $vg2/$lv1
+not lvs $vg2/$lv2
+not lvs $vg3/$lv3
+not lvs $vg5/$lv1
+
+lvremove $vg2 $vg1
+not lvs $vg1/$lv1
+
+lvremove $vg3/$lv1 $vg3 $vg4 $vg5/$lv2
+not lvs $vg3/$lv1
+not lvs $vg3/$lv2
+not lvs $vg5/$lv2
+
+lvremove $vg5 $vg1 $vg5/$lv3
+not lvs $vg5/$lv3
+not lvs $vg5/$lv4
+not lvs $vg5/$lv5
+
+vgremove $vg1
+vgremove $vg2
+vgremove $vg3
+vgremove $vg4
+vgremove $vg5
+
+
+#
+# test lvremove @lvtags
+#
+
+# set up vgs/lvs that we will remove
+vgcreate $vg1 "$dev1" "$dev2"
+vgcreate $vg2 "$dev3" "$dev4"
+vgcreate $vg3 "$dev5" "$dev6"
+vgcreate $vg4 "$dev7" "$dev8"
+vgcreate $vg5 "$dev9" "$dev10"
+lvcreate -l 2 -n $lv1 $vg1
+lvcreate -l 2 -n $lv1 $vg2
+lvcreate -l 2 -n $lv2 $vg2
+lvcreate -l 2 -n $lv1 $vg3
+lvcreate -l 2 -n $lv2 $vg3
+lvcreate -l 2 -n $lv3 $vg3
+lvcreate -l 2 -n $lv1 $vg5
+lvcreate -l 2 -n $lv2 $vg5
+lvcreate -l 2 -n $lv3 $vg5
+lvcreate -l 2 -n $lv4 $vg5
+lvcreate -l 2 -n $lv5 $vg5
+lvchange --addtag V1L1 $vg1/$lv1
+lvchange --addtag V2L1 $vg2/$lv1
+lvchange --addtag V2L2 $vg2/$lv2
+lvchange --addtag V23 $vg2/$lv1
+lvchange --addtag V23 $vg2/$lv2
+lvchange --addtag V23 $vg3/$lv1
+lvchange --addtag V23 $vg3/$lv2
+lvchange --addtag V23 $vg3/$lv3
+lvchange --addtag V3L2 $vg3/$lv2
+lvchange --addtag V3L3A $vg3/$lv3
+lvchange --addtag V3L3B $vg3/$lv3
+lvchange --addtag V5L1 $vg5/$lv1
+lvchange --addtag V5L234 $vg5/$lv2
+lvchange --addtag V5L234 $vg5/$lv3
+lvchange --addtag V5L234 $vg5/$lv4
+lvchange --addtag V5L5 $vg5/$lv5
+vgchange -an $vg1
+vgchange -an $vg2
+vgchange -an $vg3
+vgchange -an $vg4
+vgchange -an $vg5
+
+# verify all exist
+lvs $vg1/$lv1
+lvs $vg2/$lv1
+lvs $vg2/$lv2
+lvs $vg3/$lv1
+lvs $vg3/$lv2
+lvs $vg3/$lv3
+lvs $vg5/$lv1
+lvs $vg5/$lv2
+lvs $vg5/$lv3
+lvs $vg5/$lv4
+lvs $vg5/$lv5
+
+lvremove @garbage
+
+lvremove @V3L3A
+not lvs $vg3/$lv3
+# verify unremoved still exist
+lvs $vg1/$lv1
+lvs $vg2/$lv1
+lvs $vg2/$lv2
+lvs $vg3/$lv1
+lvs $vg3/$lv2
+lvs $vg5/$lv1
+lvs $vg5/$lv2
+lvs $vg5/$lv3
+lvs $vg5/$lv4
+lvs $vg5/$lv5
+
+lvremove @V5L234
+not lvs $vg5/$lv2
+not lvs $vg5/$lv3
+not lvs $vg5/$lv4
+# verify unremoved still exist
+lvs $vg1/$lv1
+lvs $vg2/$lv1
+lvs $vg2/$lv2
+lvs $vg3/$lv1
+lvs $vg3/$lv2
+lvs $vg5/$lv1
+lvs $vg5/$lv5
+
+lvremove @V5L1 @V5L5
+not lvs $vg5/$lv1
+not lvs $vg5/$lv5
+# verify unremoved still exist
+lvs $vg1/$lv1
+lvs $vg2/$lv1
+lvs $vg2/$lv2
+lvs $vg3/$lv1
+lvs $vg3/$lv2
+
+lvremove @V23 @V1L1 @V3L2
+not lvs $vg1/$lv1
+not lvs $vg2/$lv1
+not lvs $vg2/$lv2
+not lvs $vg3/$lv1
+not lvs $vg3/$lv2
+
+vgremove $vg1
+vgremove $vg2
+vgremove $vg3
+vgremove $vg4
+vgremove $vg5
+
+
+#
+# test lvremove @vgtags
+#
+
+# set up vgs/lvs that we will remove
+vgcreate $vg1 "$dev1" "$dev2"
+vgcreate $vg2 "$dev3" "$dev4"
+vgcreate $vg3 "$dev5" "$dev6"
+vgcreate $vg4 "$dev7" "$dev8"
+vgcreate $vg5 "$dev9" "$dev10"
+lvcreate -l 2 -n $lv1 $vg1
+lvcreate -l 2 -n $lv1 $vg2
+lvcreate -l 2 -n $lv2 $vg2
+lvcreate -l 2 -n $lv1 $vg3
+lvcreate -l 2 -n $lv2 $vg3
+lvcreate -l 2 -n $lv3 $vg3
+lvcreate -l 2 -n $lv1 $vg5
+lvcreate -l 2 -n $lv2 $vg5
+lvcreate -l 2 -n $lv3 $vg5
+lvcreate -l 2 -n $lv4 $vg5
+lvcreate -l 2 -n $lv5 $vg5
+vgchange --addtag V1 $vg1
+vgchange --addtag V23 $vg2
+vgchange --addtag V23 $vg3
+vgchange --addtag V35 $vg3
+vgchange --addtag V4 $vg4
+vgchange --addtag V35 $vg5
+vgchange --addtag V5 $vg5
+vgchange -an $vg1
+vgchange -an $vg2
+vgchange -an $vg3
+vgchange -an $vg4
+vgchange -an $vg5
+
+lvremove @V4
+# verify unremoved exist
+lvs $vg1/$lv1
+lvs $vg2/$lv1
+lvs $vg2/$lv2
+lvs $vg3/$lv1
+lvs $vg3/$lv2
+lvs $vg3/$lv3
+lvs $vg5/$lv1
+lvs $vg5/$lv2
+lvs $vg5/$lv3
+lvs $vg5/$lv4
+lvs $vg5/$lv5
+
+lvremove @V5
+not lvs $vg5/$lv1
+not lvs $vg5/$lv2
+not lvs $vg5/$lv3
+not lvs $vg5/$lv4
+not lvs $vg5/$lv5
+# verify unremoved exist
+lvs $vg1/$lv1
+lvs $vg2/$lv1
+lvs $vg2/$lv2
+lvs $vg3/$lv1
+lvs $vg3/$lv2
+lvs $vg3/$lv3
+
+lvremove @V1 @V23
+not lvs $vg1/$lv1
+not lvs $vg2/$lv1
+not lvs $vg2/$lv2
+not lvs $vg3/$lv1
+not lvs $vg3/$lv2
+not lvs $vg3/$lv3
+
+vgremove $vg1
+vgremove $vg2
+vgremove $vg3
+vgremove $vg4
+vgremove $vg5
+
+# set up vgs/lvs that we will remove
+vgcreate $vg1 "$dev1" "$dev2"
+vgcreate $vg2 "$dev3" "$dev4"
+vgcreate $vg3 "$dev5" "$dev6"
+vgcreate $vg4 "$dev7" "$dev8"
+vgcreate $vg5 "$dev9" "$dev10"
+lvcreate -l 2 -n $lv1 $vg1
+lvcreate -l 2 -n $lv1 $vg2
+lvcreate -l 2 -n $lv2 $vg2
+lvcreate -l 2 -n $lv1 $vg3
+lvcreate -l 2 -n $lv2 $vg3
+lvcreate -l 2 -n $lv3 $vg3
+lvcreate -l 2 -n $lv1 $vg5
+lvcreate -l 2 -n $lv2 $vg5
+lvcreate -l 2 -n $lv3 $vg5
+lvcreate -l 2 -n $lv4 $vg5
+lvcreate -l 2 -n $lv5 $vg5
+vgchange --addtag V1 $vg1
+vgchange --addtag V23 $vg2
+vgchange --addtag V23 $vg3
+vgchange --addtag V35 $vg3
+vgchange --addtag V4 $vg4
+vgchange --addtag V35 $vg5
+vgchange --addtag V5 $vg5
+vgchange -an $vg1
+vgchange -an $vg2
+vgchange -an $vg3
+vgchange -an $vg4
+vgchange -an $vg5
+
+lvremove @V35 @V5
+not lvs $vg3/$lv1
+not lvs $vg3/$lv2
+not lvs $vg3/$lv3
+not lvs $vg5/$lv1
+not lvs $vg5/$lv2
+not lvs $vg5/$lv3
+not lvs $vg5/$lv4
+not lvs $vg5/$lv5
+# verify unremoved exist
+lvs $vg1/$lv1
+lvs $vg2/$lv1
+lvs $vg2/$lv2
+
+lvremove @V1 @V23
+not lvs $vg1/$lv1
+not lvs $vg2/$lv1
+not lvs $vg2/$lv2
+
+vgremove $vg1
+vgremove $vg2
+vgremove $vg3
+vgremove $vg4
+vgremove $vg5
+
+
+#
+# test lvremove vg|lv names and @lvtags
+#
+
+# set up vgs/lvs that we will remove
+vgcreate $vg1 "$dev1" "$dev2"
+vgcreate $vg2 "$dev3" "$dev4"
+vgcreate $vg3 "$dev5" "$dev6"
+vgcreate $vg4 "$dev7" "$dev8"
+vgcreate $vg5 "$dev9" "$dev10"
+lvcreate -l 2 -n $lv1 $vg1
+lvcreate -l 2 -n $lv1 $vg2
+lvcreate -l 2 -n $lv2 $vg2
+lvcreate -l 2 -n $lv1 $vg3
+lvcreate -l 2 -n $lv2 $vg3
+lvcreate -l 2 -n $lv3 $vg3
+lvcreate -l 2 -n $lv1 $vg5
+lvcreate -l 2 -n $lv2 $vg5
+lvcreate -l 2 -n $lv3 $vg5
+lvcreate -l 2 -n $lv4 $vg5
+lvcreate -l 2 -n $lv5 $vg5
+lvchange --addtag V1L1 $vg1/$lv1
+lvchange --addtag V2L1 $vg2/$lv1
+lvchange --addtag V2L2 $vg2/$lv2
+lvchange --addtag V23 $vg2/$lv1
+lvchange --addtag V23 $vg2/$lv2
+lvchange --addtag V23 $vg3/$lv1
+lvchange --addtag V23 $vg3/$lv2
+lvchange --addtag V23 $vg3/$lv3
+lvchange --addtag V3L2 $vg3/$lv2
+lvchange --addtag V3L3A $vg3/$lv3
+lvchange --addtag V3L3B $vg3/$lv3
+lvchange --addtag V5L1 $vg5/$lv1
+lvchange --addtag V5L234 $vg5/$lv2
+lvchange --addtag V5L234 $vg5/$lv3
+lvchange --addtag V5L234 $vg5/$lv4
+lvchange --addtag V5L5 $vg5/$lv5
+vgchange -an $vg1
+vgchange -an $vg2
+vgchange -an $vg3
+vgchange -an $vg4
+vgchange -an $vg5
+
+lvremove $vg1/$lv1 @V3L2 @V5L234
+not lvs $vg1/$lv1
+not lvs $vg3/$lv2
+not lvs $vg5/$lv2
+not lvs $vg5/$lv3
+not lvs $vg5/$lv4
+# verify unremoved exist
+lvs $vg2/$lv1
+lvs $vg2/$lv2
+lvs $vg3/$lv1
+lvs $vg3/$lv3
+lvs $vg5/$lv1
+lvs $vg5/$lv5
+
+lvremove $vg2/$lv1 @V23 $vg5/$lv1 @V5L5
+
+vgremove $vg1
+vgremove $vg2
+vgremove $vg3
+vgremove $vg4
+vgremove $vg5
+
+
+#
+# test lvremove vg|lv names and @vgtags
+#
+
+# set up vgs/lvs that we will remove
+vgcreate $vg1 "$dev1" "$dev2"
+vgcreate $vg2 "$dev3" "$dev4"
+vgcreate $vg3 "$dev5" "$dev6"
+vgcreate $vg4 "$dev7" "$dev8"
+vgcreate $vg5 "$dev9" "$dev10"
+lvcreate -l 2 -n $lv1 $vg1
+lvcreate -l 2 -n $lv1 $vg2
+lvcreate -l 2 -n $lv2 $vg2
+lvcreate -l 2 -n $lv1 $vg3
+lvcreate -l 2 -n $lv2 $vg3
+lvcreate -l 2 -n $lv3 $vg3
+lvcreate -l 2 -n $lv1 $vg5
+lvcreate -l 2 -n $lv2 $vg5
+lvcreate -l 2 -n $lv3 $vg5
+lvcreate -l 2 -n $lv4 $vg5
+lvcreate -l 2 -n $lv5 $vg5
+vgchange --addtag V1 $vg1
+vgchange --addtag V23 $vg2
+vgchange --addtag V23 $vg3
+vgchange --addtag V35 $vg3
+vgchange --addtag V4 $vg4
+vgchange --addtag V35 $vg5
+vgchange --addtag V5 $vg5
+vgchange -an $vg1
+vgchange -an $vg2
+vgchange -an $vg3
+vgchange -an $vg4
+vgchange -an $vg5
+
+lvremove $vg1/$lv1 @V35
+not lvs $vg1/$lv1
+not lvs $vg3/$lv1
+not lvs $vg3/$lv2
+not lvs $vg3/$lv3
+not lvs $vg5/$lv1
+not lvs $vg5/$lv2
+not lvs $vg5/$lv3
+not lvs $vg5/$lv4
+not lvs $vg5/$lv5
+# verify unremoved exist
+lvs $vg2/$lv1
+lvs $vg2/$lv2
+
+lvremove $vg2/$lv1 @V23 $vg2/$lv2
+
+vgremove $vg1
+vgremove $vg2
+vgremove $vg3
+vgremove $vg4
+vgremove $vg5
+
+
+#
+# test lvremove @lvtags and @vgtags
+#
+
+# set up vgs/lvs that we will remove
+vgcreate $vg1 "$dev1" "$dev2"
+vgcreate $vg2 "$dev3" "$dev4"
+vgcreate $vg3 "$dev5" "$dev6"
+vgcreate $vg4 "$dev7" "$dev8"
+vgcreate $vg5 "$dev9" "$dev10"
+lvcreate -l 2 -n $lv1 $vg1
+lvcreate -l 2 -n $lv1 $vg2
+lvcreate -l 2 -n $lv2 $vg2
+lvcreate -l 2 -n $lv1 $vg3
+lvcreate -l 2 -n $lv2 $vg3
+lvcreate -l 2 -n $lv3 $vg3
+lvcreate -l 2 -n $lv1 $vg5
+lvcreate -l 2 -n $lv2 $vg5
+lvcreate -l 2 -n $lv3 $vg5
+lvcreate -l 2 -n $lv4 $vg5
+lvcreate -l 2 -n $lv5 $vg5
+lvchange --addtag V1L1 $vg1/$lv1
+lvchange --addtag V2L1 $vg2/$lv1
+lvchange --addtag V2L2 $vg2/$lv2
+lvchange --addtag V23 $vg2/$lv1
+lvchange --addtag V23 $vg2/$lv2
+lvchange --addtag V23 $vg3/$lv1
+lvchange --addtag V23 $vg3/$lv2
+# to check that vg tag @V23 includes this
+# lvchange --addtag V23 $vg3/$lv3
+lvchange --addtag V3L2 $vg3/$lv2
+lvchange --addtag V3L3A $vg3/$lv3
+lvchange --addtag V3L3B $vg3/$lv3
+lvchange --addtag V5L1 $vg5/$lv1
+lvchange --addtag V5L234 $vg5/$lv2
+lvchange --addtag V5L234 $vg5/$lv3
+lvchange --addtag V5L234 $vg5/$lv4
+lvchange --addtag V5L5 $vg5/$lv5
+vgchange --addtag V1 $vg1
+vgchange --addtag V23 $vg2
+vgchange --addtag V23 $vg3
+vgchange --addtag V35 $vg3
+vgchange --addtag V4 $vg4
+vgchange --addtag V35 $vg5
+vgchange --addtag V5 $vg5
+vgchange -an $vg1
+vgchange -an $vg2
+vgchange -an $vg3
+vgchange -an $vg4
+vgchange -an $vg5
+
+lvremove @V23 @V35
+not lvs $vg2/$lv1
+not lvs $vg2/$lv2
+not lvs $vg3/$lv1
+not lvs $vg3/$lv2
+not lvs $vg3/$lv3
+not lvs $vg5/$lv1
+not lvs $vg5/$lv2
+not lvs $vg5/$lv3
+not lvs $vg5/$lv4
+not lvs $vg5/$lv5
+# verify unremoved exist
+lvs $vg1/$lv1
+
+lvremove @V1 @V1L1
+not lvs $vg1/$lv1
+
+vgremove $vg1
+vgremove $vg2
+vgremove $vg3
+vgremove $vg4
+vgremove $vg5
+
+
+#
+# test lvremove vg|lv names and @lvtags and @vgtags
+#
+
+# set up vgs/lvs that we will remove
+vgcreate $vg1 "$dev1" "$dev2"
+vgcreate $vg2 "$dev3" "$dev4"
+vgcreate $vg3 "$dev5" "$dev6"
+vgcreate $vg4 "$dev7" "$dev8"
+vgcreate $vg5 "$dev9" "$dev10"
+lvcreate -l 2 -n $lv1 $vg1
+lvcreate -l 2 -n $lv1 $vg2
+lvcreate -l 2 -n $lv2 $vg2
+lvcreate -l 2 -n $lv1 $vg3
+lvcreate -l 2 -n $lv2 $vg3
+lvcreate -l 2 -n $lv3 $vg3
+lvcreate -l 2 -n $lv1 $vg5
+lvcreate -l 2 -n $lv2 $vg5
+lvcreate -l 2 -n $lv3 $vg5
+lvcreate -l 2 -n $lv4 $vg5
+lvcreate -l 2 -n $lv5 $vg5
+lvchange --addtag V1L1 $vg1/$lv1
+lvchange --addtag V2L1 $vg2/$lv1
+lvchange --addtag V2L2 $vg2/$lv2
+lvchange --addtag V23 $vg2/$lv1
+lvchange --addtag V23 $vg2/$lv2
+lvchange --addtag V23 $vg3/$lv1
+lvchange --addtag V23 $vg3/$lv2
+# to check that vg tag @V23 includes this
+# lvchange --addtag V23 $vg3/$lv3
+lvchange --addtag V3L2 $vg3/$lv2
+lvchange --addtag V3L3A $vg3/$lv3
+lvchange --addtag V3L3B $vg3/$lv3
+lvchange --addtag V5L1 $vg5/$lv1
+lvchange --addtag V5L234 $vg5/$lv2
+lvchange --addtag V5L234 $vg5/$lv3
+lvchange --addtag V5L234 $vg5/$lv4
+lvchange --addtag V5L5 $vg5/$lv5
+vgchange --addtag V1 $vg1
+vgchange --addtag V23 $vg2
+vgchange --addtag V23 $vg3
+vgchange --addtag V35 $vg3
+vgchange --addtag V4 $vg4
+vgchange --addtag V35 $vg5
+vgchange --addtag V5 $vg5
+vgchange -an $vg1
+vgchange -an $vg2
+vgchange -an $vg3
+vgchange -an $vg4
+vgchange -an $vg5
+
+lvremove $vg1/$lv1 @V23 @V5L5
+not lvs $vg1/$lv1
+not lvs $vg2/$lv1
+not lvs $vg2/$lv2
+not lvs $vg3/$lv1
+not lvs $vg3/$lv2
+not lvs $vg3/$lv3
+not lvs $vg5/$lv5
+# verify unremoved exist
+lvs $vg5/$lv1
+lvs $vg5/$lv2
+lvs $vg5/$lv3
+lvs $vg5/$lv4
+
+lvremove $vg5/$lv2 @V5L234 @V5
+not lvs $vg5/$lv1
+not lvs $vg5/$lv2
+not lvs $vg5/$lv3
+not lvs $vg5/$lv4
+
+vgremove $vg1
+vgremove $vg2
+vgremove $vg3
+vgremove $vg4
+vgremove $vg5
+
+
+#
+# test lvs: empty, vg(s), lv(s), vgtag(s), lvtag(s), garbage, combinations
+#
+
+# set up vgs/lvs that we will remove
+vgcreate $vg1 "$dev1" "$dev2"
+vgcreate $vg2 "$dev3" "$dev4"
+vgcreate $vg3 "$dev5" "$dev6"
+vgcreate $vg4 "$dev7" "$dev8"
+vgcreate $vg5 "$dev9" "$dev10"
+lvcreate -l 2 -n $lv1 $vg1
+lvcreate -l 2 -n $lv1 $vg2
+lvcreate -l 2 -n $lv2 $vg2
+lvcreate -l 2 -n $lv1 $vg3
+lvcreate -l 2 -n $lv2 $vg3
+lvcreate -l 2 -n $lv3 $vg3
+lvcreate -l 2 -n $lv1 $vg5
+lvcreate -l 2 -n $lv2 $vg5
+lvcreate -l 2 -n $lv3 $vg5
+lvcreate -l 2 -n $lv4 $vg5
+lvcreate -l 2 -n $lv5 $vg5
+lvchange --addtag V1L1 $vg1/$lv1
+lvchange --addtag V2L1 $vg2/$lv1
+lvchange --addtag V2L2 $vg2/$lv2
+lvchange --addtag V23 $vg2/$lv1
+lvchange --addtag V23 $vg2/$lv2
+lvchange --addtag V23 $vg3/$lv1
+lvchange --addtag V23 $vg3/$lv2
+lvchange --addtag V23 $vg3/$lv3
+lvchange --addtag V3L2 $vg3/$lv2
+lvchange --addtag V3L3A $vg3/$lv3
+lvchange --addtag V3L3B $vg3/$lv3
+lvchange --addtag V5L1 $vg5/$lv1
+lvchange --addtag V5L234 $vg5/$lv2
+lvchange --addtag V5L234 $vg5/$lv3
+lvchange --addtag V5L234 $vg5/$lv4
+lvchange --addtag V5L5 $vg5/$lv5
+vgchange --addtag V1 $vg1
+vgchange --addtag V23 $vg2
+vgchange --addtag V23 $vg3
+vgchange --addtag V35 $vg3
+vgchange --addtag V4 $vg4
+vgchange --addtag V35 $vg5
+vgchange --addtag V5 $vg5
+vgchange -an $vg1
+vgchange -an $vg2
+vgchange -an $vg3
+vgchange -an $vg4
+vgchange -an $vg5
+
+# empty
+lvs -o vg_name,lv_name --separator '-' >err
+grep $vg1-$lv1 err
+grep $vg2-$lv1 err
+grep $vg2-$lv2 err
+grep $vg3-$lv1 err
+grep $vg3-$lv2 err
+grep $vg3-$lv3 err
+grep $vg5-$lv1 err
+grep $vg5-$lv2 err
+grep $vg5-$lv3 err
+grep $vg5-$lv4 err
+grep $vg5-$lv5 err
+
+# vg
+lvs -o vg_name,lv_name --separator '-' $vg1 >err
+grep $vg1-$lv1 err
+not grep $vg2-$lv1 err
+not grep $vg2-$lv2 err
+not grep $vg3-$lv1 err
+not grep $vg3-$lv2 err
+not grep $vg3-$lv3 err
+not grep $vg5-$lv1 err
+not grep $vg5-$lv2 err
+not grep $vg5-$lv3 err
+not grep $vg5-$lv4 err
+not grep $vg5-$lv5 err
+
+# vgs
+lvs -o vg_name,lv_name --separator '-' $vg1 $vg2 >err
+grep $vg1-$lv1 err
+grep $vg2-$lv1 err
+grep $vg2-$lv2 err
+not grep $vg3-$lv1 err
+not grep $vg3-$lv2 err
+not grep $vg3-$lv3 err
+not grep $vg5-$lv1 err
+not grep $vg5-$lv2 err
+not grep $vg5-$lv3 err
+not grep $vg5-$lv4 err
+not grep $vg5-$lv5 err
+
+# lv
+lvs -o vg_name,lv_name --separator '-' $vg1/$lv1 >err
+grep $vg1-$lv1 err
+not grep $vg2-$lv1 err
+not grep $vg2-$lv2 err
+not grep $vg3-$lv1 err
+not grep $vg3-$lv2 err
+not grep $vg3-$lv3 err
+not grep $vg5-$lv1 err
+not grep $vg5-$lv2 err
+not grep $vg5-$lv3 err
+not grep $vg5-$lv4 err
+not grep $vg5-$lv5 err
+
+# lvs
+lvs -o vg_name,lv_name --separator '-' $vg1/$lv1 $vg2/$lv1 $vg2/$lv2 >err
+grep $vg1-$lv1 err
+grep $vg2-$lv1 err
+grep $vg2-$lv2 err
+not grep $vg3-$lv1 err
+not grep $vg3-$lv2 err
+not grep $vg3-$lv3 err
+not grep $vg5-$lv1 err
+not grep $vg5-$lv2 err
+not grep $vg5-$lv3 err
+not grep $vg5-$lv4 err
+not grep $vg5-$lv5 err
+
+# vgtag
+lvs -o vg_name,lv_name --separator '-' @V1 >err
+grep $vg1-$lv1 err
+not grep $vg2-$lv1 err
+not grep $vg2-$lv2 err
+not grep $vg3-$lv1 err
+not grep $vg3-$lv2 err
+not grep $vg3-$lv3 err
+not grep $vg5-$lv1 err
+not grep $vg5-$lv2 err
+not grep $vg5-$lv3 err
+not grep $vg5-$lv4 err
+not grep $vg5-$lv5 err
+
+# vgtags
+lvs -o vg_name,lv_name --separator '-' @V1 @V35 >err
+grep $vg1-$lv1 err
+not grep $vg2-$lv1 err
+not grep $vg2-$lv2 err
+grep $vg3-$lv1 err
+grep $vg3-$lv2 err
+grep $vg3-$lv3 err
+grep $vg5-$lv1 err
+grep $vg5-$lv2 err
+grep $vg5-$lv3 err
+grep $vg5-$lv4 err
+grep $vg5-$lv5 err
+
+# lvtag
+lvs -o vg_name,lv_name --separator '-' @V1L1 >err
+grep $vg1-$lv1 err
+not grep $vg2-$lv1 err
+not grep $vg2-$lv2 err
+not grep $vg3-$lv1 err
+not grep $vg3-$lv2 err
+not grep $vg3-$lv3 err
+not grep $vg5-$lv1 err
+not grep $vg5-$lv2 err
+not grep $vg5-$lv3 err
+not grep $vg5-$lv4 err
+not grep $vg5-$lv5 err
+
+# lvtags
+lvs -o vg_name,lv_name --separator '-' @V1L1 @V5L234 >err
+grep $vg1-$lv1 err
+not grep $vg2-$lv1 err
+not grep $vg2-$lv2 err
+not grep $vg3-$lv1 err
+not grep $vg3-$lv2 err
+not grep $vg3-$lv3 err
+not grep $vg5-$lv1 err
+grep $vg5-$lv2 err
+grep $vg5-$lv3 err
+grep $vg5-$lv4 err
+not grep $vg5-$lv5 err
+
+# vg and lv and vgtag and lvtag
+lvs -o vg_name,lv_name --separator '-' $vg2 $vg5/$lv5 @V1 @V5L234 >err
+grep $vg1-$lv1 err
+grep $vg2-$lv1 err
+grep $vg2-$lv2 err
+not grep $vg3-$lv1 err
+not grep $vg3-$lv2 err
+not grep $vg3-$lv3 err
+not grep $vg5-$lv1 err
+grep $vg5-$lv2 err
+grep $vg5-$lv3 err
+grep $vg5-$lv4 err
+grep $vg5-$lv5 err
+
+# garbage name gives an error if used without a tag
+
+not lvs -o vg_name,lv_name --separator '-' garbage >err
+not grep $vg1-$lv1 err
+not grep $vg2-$lv1 err
+not grep $vg2-$lv2 err
+not grep $vg3-$lv1 err
+not grep $vg3-$lv2 err
+not grep $vg3-$lv3 err
+not grep $vg5-$lv1 err
+not grep $vg5-$lv2 err
+not grep $vg5-$lv3 err
+not grep $vg5-$lv4 err
+not grep $vg5-$lv5 err
+
+not lvs -o vg_name,lv_name --separator '-' $vg1/$lv1 garbage >err
+grep $vg1-$lv1 err
+not grep $vg2-$lv1 err
+not grep $vg2-$lv2 err
+not grep $vg3-$lv1 err
+not grep $vg3-$lv2 err
+not grep $vg3-$lv3 err
+not grep $vg5-$lv1 err
+not grep $vg5-$lv2 err
+not grep $vg5-$lv3 err
+not grep $vg5-$lv4 err
+not grep $vg5-$lv5 err
+
+# garbage name does not give an error if used with a tag
+
+lvs -o vg_name,lv_name --separator '-' @V1 garbage >err
+grep $vg1-$lv1 err
+not grep $vg2-$lv1 err
+not grep $vg2-$lv2 err
+not grep $vg3-$lv1 err
+not grep $vg3-$lv2 err
+not grep $vg3-$lv3 err
+not grep $vg5-$lv1 err
+not grep $vg5-$lv2 err
+not grep $vg5-$lv3 err
+not grep $vg5-$lv4 err
+not grep $vg5-$lv5 err
+
+lvs -o vg_name,lv_name --separator '-' @garbage garbage >err
+not grep $vg1-$lv1 err
+not grep $vg2-$lv1 err
+not grep $vg2-$lv2 err
+not grep $vg3-$lv1 err
+not grep $vg3-$lv2 err
+not grep $vg3-$lv3 err
+not grep $vg5-$lv1 err
+not grep $vg5-$lv2 err
+not grep $vg5-$lv3 err
+not grep $vg5-$lv4 err
+not grep $vg5-$lv5 err
+
+# garbage tag never gives an error
+
+lvs -o vg_name,lv_name --separator '-' @V1 @garbage >err
+grep $vg1-$lv1 err
+not grep $vg2-$lv1 err
+not grep $vg2-$lv2 err
+not grep $vg3-$lv1 err
+not grep $vg3-$lv2 err
+not grep $vg3-$lv3 err
+not grep $vg5-$lv1 err
+not grep $vg5-$lv2 err
+not grep $vg5-$lv3 err
+not grep $vg5-$lv4 err
+not grep $vg5-$lv5 err
+
+lvs -o vg_name,lv_name --separator '-' $vg1/$lv1 @garbage >err
+grep $vg1-$lv1 err
+not grep $vg2-$lv1 err
+not grep $vg2-$lv2 err
+not grep $vg3-$lv1 err
+not grep $vg3-$lv2 err
+not grep $vg3-$lv3 err
+not grep $vg5-$lv1 err
+not grep $vg5-$lv2 err
+not grep $vg5-$lv3 err
+not grep $vg5-$lv4 err
+not grep $vg5-$lv5 err
+
+lvs -o vg_name,lv_name --separator '-' @garbage >err
+not grep $vg1-$lv1 err
+not grep $vg2-$lv1 err
+not grep $vg2-$lv2 err
+not grep $vg3-$lv1 err
+not grep $vg3-$lv2 err
+not grep $vg3-$lv3 err
+not grep $vg5-$lv1 err
+not grep $vg5-$lv2 err
+not grep $vg5-$lv3 err
+not grep $vg5-$lv4 err
+not grep $vg5-$lv5 err
+
diff --git a/test/shell/process-each-vg.sh b/test/shell/process-each-vg.sh
new file mode 100644
index 0000000..90c0dbc
--- /dev/null
+++ b/test/shell/process-each-vg.sh
@@ -0,0 +1,264 @@
+#!/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_vg'
+
+. lib/test
+
+aux prepare_devs 6
+
+#
+# process_each_vg is used by a number of vg commands;
+# use 'vgremove' and 'vgs' to test it.
+#
+# The logic in process_each_vg is mainly related to
+# selecting which vg's to process.
+#
+
+#
+# set up four vgs that we will remove
+#
+vgcreate $vg1 "$dev1"
+vgcreate $vg2 "$dev2"
+vgcreate $vg3 "$dev3"
+vgcreate $vg4 "$dev4"
+
+# these two vgs will not be removed
+vgcreate $vg5 "$dev5"
+vgchange --addtag tagvg5 $vg5
+lvcreate -l 4 -n $lv1 $vg5
+vgcreate $vg6 "$dev6"
+lvcreate -l 4 -n $lv2 $vg6
+
+# should fail without any arg
+not vgremove
+
+# should succeed
+vgremove $vg1
+vgremove $vg2 $vg3 $vg4
+
+# these should fail because they are already removed
+not vgremove $vg1
+not vgremove $vg2
+not vgremove $vg3
+not vgremove $vg4
+
+# these should fail because they have lvs in them
+not vgremove $vg5
+not vgremove $vg6
+
+# check that the vgs we removed are gone
+not vgs $vg1
+not vgs $vg2
+not vgs $vg3
+not vgs $vg4
+
+
+#
+# set up four vgs that we will remove
+#
+vgcreate --addtag tagfoo $vg1 "$dev1"
+vgcreate --addtag tagfoo $vg2 "$dev2"
+vgcreate --addtag tagfoo2 $vg3 "$dev3"
+vgcreate --addtag tagbar $vg4 "$dev4"
+vgchange --addtag foo $vg4
+
+# should do nothing and fail
+not vgremove garbage
+
+# should find nothing to remove
+vgremove @garbage
+
+# should find nothing to remove
+vgremove @$vg1
+
+# should succeed
+vgremove $vg1
+not vgs $vg1
+
+vgremove $vg2 $vg3 $vg4
+not vgs $vg2
+not vgs $vg3
+not vgs $vg4
+
+
+#
+# set up four vgs that we will remove
+#
+vgcreate --addtag tagfoo $vg1 "$dev1"
+vgcreate --addtag tagfoo $vg2 "$dev2"
+vgcreate --addtag tagfoo2 $vg3 "$dev3"
+vgcreate --addtag tagbar $vg4 "$dev4"
+vgchange --addtag foo $vg4
+
+vgremove @tagfoo
+not vgs $vg1
+not vgs $vg2
+
+vgremove @tagfoo2 @tagbar
+not vgs $vg3
+not vgs $vg4
+
+
+#
+# set up four vgs that we will remove
+#
+vgcreate --addtag tagfoo $vg1 "$dev1"
+vgcreate --addtag tagfoo $vg2 "$dev2"
+vgcreate --addtag tagfoo2 $vg3 "$dev3"
+vgcreate --addtag tagbar $vg4 "$dev4"
+vgchange --addtag foo $vg4
+
+vgremove $vg1 @tagfoo2
+not vgs $vg1
+not vgs $vg3
+
+vgremove @tagbar $vg2
+not vgs $vg2
+not vgs $vg4
+
+
+#
+# set up four vgs that we will remove
+#
+vgcreate --addtag tagfoo $vg1 "$dev1"
+vgcreate --addtag tagfoo $vg2 "$dev2"
+vgcreate --addtag tagfoo2 $vg3 "$dev3"
+vgcreate --addtag tagbar $vg4 "$dev4"
+vgchange --addtag foo $vg4
+
+vgremove @foo @tagfoo2 $vg1 $vg2
+not vgs $vg1
+not vgs $vg2
+not vgs $vg3
+not vgs $vg4
+
+
+#
+# set up four vgs that we will remove
+#
+vgcreate --addtag tagfoo $vg1 "$dev1"
+vgcreate --addtag tagfoo $vg2 "$dev2"
+vgcreate --addtag tagfoo2 $vg3 "$dev3"
+vgcreate --addtag tagbar $vg4 "$dev4"
+vgchange --addtag foo $vg4
+
+vgremove @tagfoo $vg1 @tagfoo @tagfoo2 $vg3 @tagbar
+not vgs $vg1
+not vgs $vg2
+not vgs $vg3
+not vgs $vg4
+
+
+#
+# set up four vgs that we will remove
+#
+vgcreate --addtag tagfoo $vg1 "$dev1"
+vgcreate --addtag tagfoo $vg2 "$dev2"
+vgcreate --addtag tagfoo2 $vg3 "$dev3"
+vgcreate --addtag tagbar $vg4 "$dev4"
+vgchange --addtag foo $vg4
+
+not vgremove garbage $vg1
+not vgs $vg1
+
+not vgremove $vg2 garbage
+not vgs $vg2
+
+vgremove $vg3 @garbage
+not vgs $vg3
+
+vgremove @garbage $vg4
+not vgs $vg4
+
+
+#
+# end vgremove tests
+# check that the two vgs we did not intend to remove
+# are still there, and then remove them
+#
+vgs $vg5
+vgs $vg6
+vgremove -f $vg5
+vgremove -f $vg6
+not vgs $vg5
+not vgs $vg6
+
+
+#
+# set up four vgs that we will report
+#
+vgcreate --addtag tagfoo $vg1 "$dev1"
+vgcreate --addtag tagfoo $vg2 "$dev2"
+vgcreate --addtag tagfoo2 $vg3 "$dev3"
+vgcreate --addtag tagbar $vg4 "$dev4"
+vgchange --addtag foo $vg4
+
+vgs >err
+grep $vg1 err
+grep $vg2 err
+grep $vg3 err
+grep $vg4 err
+
+vgs $vg1 $vg2 >err
+grep $vg1 err
+grep $vg2 err
+not grep $vg3 err
+not grep $vg4 err
+
+vgs @tagfoo >err
+grep $vg1 err
+grep $vg2 err
+not grep $vg3 err
+not grep $vg4 err
+
+vgs @tagfoo2 >err
+grep $vg3 err
+not grep $vg1 err
+not grep $vg2 err
+not grep $vg4 err
+
+vgs @tagfoo2 @tagbar >err
+grep $vg3 err
+grep $vg4 err
+not grep $vg1 err
+not grep $vg2 err
+
+vgs $vg1 @tagbar >err
+grep $vg1 err
+grep $vg4 err
+not grep $vg2 err
+not grep $vg3 err
+
+vgs $vg1 @tagfoo >err
+grep $vg1 err
+grep $vg2 err
+not grep $vg3 err
+not grep $vg4 err
+
+not vgs garbage >err
+not grep $vg1 err
+not grep $vg2 err
+not grep $vg3 err
+not grep $vg4 err
+
+not vgs garbage $vg1 >err
+grep $vg1 err
+not grep $vg2 err
+not grep $vg3 err
+not grep $vg4 err
+
+vgs @garbage @foo >err
+grep $vg4 err
+not grep $vg1 err
+not grep $vg2 err
+not grep $vg3 err
+
10 years, 8 months