master - tests: avoid clobering dmesg
by Zdenek Kabelac
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=abcab54cca4b4f...
Commit: abcab54cca4b4f9ff157a5f51718c69ffdf34c7a
Parent: 3d845e492adab0aba279f24e244d8617faa3279d
Author: Zdenek Kabelac <zkabelac(a)redhat.com>
AuthorDate: Fri May 8 22:43:06 2015 +0200
Committer: Zdenek Kabelac <zkabelac(a)redhat.com>
CommitterDate: Sat May 9 09:17:26 2015 +0200
tests: avoid clobering dmesg
Restore old harness access to /dev/kmsg.
---
test/lib/brick-shelltest.h | 28 ++++++++++------------------
1 files changed, 10 insertions(+), 18 deletions(-)
diff --git a/test/lib/brick-shelltest.h b/test/lib/brick-shelltest.h
index af8051e..e64a166 100644
--- a/test/lib/brick-shelltest.h
+++ b/test/lib/brick-shelltest.h
@@ -541,26 +541,22 @@ struct FileSource : Source {
struct KMsg : Source {
bool can_clear;
- KMsg() : can_clear( true ) {}
-
- bool dev_kmsg() {
- return fd >= 0;
- }
-
- void reset() {
+ KMsg() : can_clear( strcmp(getenv("LVM_TEST_CAN_CLOBBER_DMESG") ? : "0", "0") ) {
#ifdef __unix
- if ( dev_kmsg() ) {
- if ( (fd = open("/dev/kmsg", O_RDONLY | O_NONBLOCK)) < 0 ) {
- if (errno != ENOENT) /* Older kernels (<3.5) do not support /dev/kmsg */
- perror("opening /dev/kmsg");
- } else if (lseek(fd, 0L, SEEK_END) == (off_t) -1)
- perror("lseek /dev/kmsg");
- } else
+ if ( (fd = open("/dev/kmsg", O_RDONLY | O_NONBLOCK)) < 0 ) {
+ if (errno != ENOENT) /* Older kernels (<3.5) do not support /dev/kmsg */
+ perror("opening /dev/kmsg");
if ( klogctl( BRICK_SYSLOG_ACTION_CLEAR, 0, 0 ) < 0 )
can_clear = false;
+ } else if (lseek(fd, 0L, SEEK_END) == (off_t) -1)
+ perror("lseek /dev/kmsg");
#endif
}
+ bool dev_kmsg() {
+ return fd >= 0;
+ }
+
void sync( Sink *s ) {
#ifdef __unix
ssize_t sz;
@@ -569,10 +565,6 @@ struct KMsg : Source {
if ( dev_kmsg() ) {
while ( (sz = ::read(fd, buf, sizeof(buf) - 1)) > 0 )
s->push( std::string( buf, sz ) );
- if ( sz < 0 ) {
- fd = -1;
- sync( s );
- }
} else if ( can_clear ) {
while ( (sz = klogctl( BRICK_SYSLOG_ACTION_READ_CLEAR, buf,
sizeof(buf) - 1 )) > 0 )
9 years
master - cleanup: drop extra test for NULL
by Zdenek Kabelac
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=3d845e492adab0...
Commit: 3d845e492adab0aba279f24e244d8617faa3279d
Parent: e047f043948758be0405ccc67c4a066e237dcbb1
Author: Zdenek Kabelac <zkabelac(a)redhat.com>
AuthorDate: Fri May 8 23:01:32 2015 +0200
Committer: Zdenek Kabelac <zkabelac(a)redhat.com>
CommitterDate: Sat May 9 09:17:26 2015 +0200
cleanup: drop extra test for NULL
vg cannot be NULL here - it's been already used in the code above.
---
tools/pvmove_poll.c | 3 +--
1 files changed, 1 insertions(+), 2 deletions(-)
diff --git a/tools/pvmove_poll.c b/tools/pvmove_poll.c
index 61ebd23..df896b5 100644
--- a/tools/pvmove_poll.c
+++ b/tools/pvmove_poll.c
@@ -89,8 +89,7 @@ int pvmove_update_metadata(struct cmd_context *cmd, struct volume_group *vg,
}
if (!suspend_lv(cmd, lv_mirr)) {
- if (vg)
- vg_revert(vg);
+ vg_revert(vg);
log_error("ABORTING: Temporary pvmove mirror reload failed.");
if (!revert_lv(cmd, lv_mirr))
stack;
9 years
master - cleanup: remove extraneous parentheses
by Zdenek Kabelac
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=e047f043948758...
Commit: e047f043948758be0405ccc67c4a066e237dcbb1
Parent: e587b0677b705786a78f21bac1966621f70b2752
Author: Zdenek Kabelac <zkabelac(a)redhat.com>
AuthorDate: Fri May 8 22:58:00 2015 +0200
Committer: Zdenek Kabelac <zkabelac(a)redhat.com>
CommitterDate: Sat May 9 09:17:26 2015 +0200
cleanup: remove extraneous parentheses
---
tools/toollib.c | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/tools/toollib.c b/tools/toollib.c
index ae48e7b..ca198dc 100644
--- a/tools/toollib.c
+++ b/tools/toollib.c
@@ -214,7 +214,7 @@ static int _ignore_vg(struct volume_group *vg, const char *vg_name,
}
}
- if ((read_error == FAILED_CLUSTERED)) {
+ if (read_error == FAILED_CLUSTERED) {
*skip = 1;
stack; /* Error already logged */
return 1;
9 years
master - lvmpolld: Add standalone polldaemon.
by Alasdair Kergon
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=e587b0677b7057...
Commit: e587b0677b705786a78f21bac1966621f70b2752
Parent: be23fae488b7df19147259d3e8505fc8301076cd
Author: Ondrej Kozina <okozina(a)redhat.com>
AuthorDate: Sat May 9 00:59:18 2015 +0100
Committer: Alasdair G Kergon <agk(a)redhat.com>
CommitterDate: Sat May 9 00:59:18 2015 +0100
lvmpolld: Add standalone polldaemon.
See doc/lvmpolld_overview.txt
---
WHATS_NEW | 2 +
conf/example.conf.in | 10 +
configure | 49 ++-
configure.in | 30 +
daemons/Makefile.in | 10 +-
daemons/lvmpolld/Makefile.in | 49 ++
daemons/lvmpolld/lvmpolld-cmd-utils.c | 140 ++++
daemons/lvmpolld/lvmpolld-cmd-utils.h | 25 +
daemons/lvmpolld/lvmpolld-common.h | 36 +
daemons/lvmpolld/lvmpolld-core.c | 817 +++++++++++++++++++++
daemons/lvmpolld/lvmpolld-data-utils.c | 388 ++++++++++
daemons/lvmpolld/lvmpolld-data-utils.h | 215 ++++++
daemons/lvmpolld/lvmpolld-protocol.h | 49 ++
daemons/lvmpolld/polling_ops.h | 25 +
doc/lvmpolld_overview.txt | 81 ++
include/.symlinks.in | 4 +
lib/Makefile.in | 5 +
lib/commands/toolcontext.c | 11 +
lib/config/config_settings.h | 9 +
lib/lvmpolld/lvmpolld-client.c | 311 ++++++++
lib/lvmpolld/lvmpolld-client.h | 52 ++
lib/lvmpolld/polldaemon.h | 93 +++
lib/misc/configure.h.in | 6 +
libdaemon/Makefile.in | 2 +-
make.tmpl.in | 2 +-
man/Makefile.in | 8 +-
man/lvm.8.in | 6 +
man/lvmpolld.8.in | 86 +++
scripts/.gitignore | 3 +
scripts/Makefile.in | 9 +
scripts/lvm2_lvmpolld_init_red_hat.in | 114 +++
scripts/lvm2_lvmpolld_systemd_red_hat.service.in | 17 +
scripts/lvm2_lvmpolld_systemd_red_hat.socket.in | 12 +
scripts/lvmdump.sh | 24 +-
test/Makefile.in | 28 +-
test/lib/aux.sh | 100 +++-
test/lib/flavour-ndev-cluster-lvmpolld.sh | 2 +
test/lib/flavour-ndev-lvmetad-lvmpolld.sh | 3 +
test/lib/flavour-ndev-lvmpolld.sh | 2 +
test/lib/flavour-udev-cluster-lvmpolld.sh | 3 +
test/lib/flavour-udev-lvmetad-lvmpolld.sh | 4 +
test/lib/flavour-udev-lvmpolld.sh | 3 +
test/lib/inittest.sh | 7 +
test/shell/000-basic.sh | 2 +
test/shell/activate-minor.sh | 1 +
test/shell/activate-missing-segment.sh | 2 +
test/shell/activate-missing.sh | 2 +
test/shell/activate-partial.sh | 2 +
test/shell/activation-skip.sh | 2 +
test/shell/clvmd-restart.sh | 1 +
test/shell/covercmd.sh | 2 +
test/shell/discards-thin.sh | 2 +
test/shell/dmeventd-restart.sh | 2 +
test/shell/dumpconfig.sh | 2 +
test/shell/error-usage.sh | 2 +
test/shell/fsadm.sh | 2 +
test/shell/inconsistent-metadata.sh | 2 +
test/shell/listings.sh | 2 +
test/shell/lock-blocking.sh | 4 +-
test/shell/lock-parallel.sh | 2 +
test/shell/lvchange-cache.sh | 2 +
test/shell/lvchange-mirror.sh | 2 +
test/shell/lvchange-partial-raid10.sh | 2 +
test/shell/lvchange-partial.sh | 1 +
test/shell/lvchange-raid10.sh | 2 +
test/shell/lvchange-raid456.sh | 2 +
test/shell/lvchange-syncaction-raid.sh | 2 +
test/shell/lvchange-thin.sh | 2 +
test/shell/lvconvert-cache-raid.sh | 2 +
test/shell/lvconvert-cache-thin.sh | 2 +
test/shell/lvconvert-cache.sh | 2 +
test/shell/lvconvert-raid-allocation.sh | 2 +
test/shell/lvconvert-raid.sh | 2 +
test/shell/lvconvert-raid10.sh | 2 +
test/shell/lvconvert-raid456.sh | 2 +
test/shell/lvconvert-repair-dmeventd.sh | 2 +
test/shell/lvconvert-repair-raid-dmeventd.sh | 2 +
test/shell/lvconvert-repair-raid.sh | 2 +
test/shell/lvconvert-repair-snapshot.sh | 2 +
test/shell/lvconvert-repair-thin.sh | 2 +
test/shell/lvconvert-repair-transient-dmeventd.sh | 2 +
test/shell/lvconvert-repair-transient.sh | 2 +
test/shell/lvconvert-snapshot.sh | 2 +
test/shell/lvconvert-thin-external.sh | 2 +
test/shell/lvconvert-thin-raid.sh | 2 +
test/shell/lvconvert-thin.sh | 2 +
test/shell/lvcreate-cache.sh | 2 +
test/shell/lvcreate-large-raid.sh | 2 +
test/shell/lvcreate-large-raid10.sh | 2 +
test/shell/lvcreate-large.sh | 2 +
test/shell/lvcreate-mirror.sh | 3 +
test/shell/lvcreate-missing.sh | 2 +
test/shell/lvcreate-operation.sh | 2 +
test/shell/lvcreate-pvtags.sh | 2 +
test/shell/lvcreate-raid.sh | 2 +
test/shell/lvcreate-raid10.sh | 2 +
test/shell/lvcreate-repair.sh | 2 +
test/shell/lvcreate-signature-wiping.sh | 2 +
test/shell/lvcreate-small-snap.sh | 2 +
test/shell/lvcreate-striped-mirror.sh | 2 +
test/shell/lvcreate-thin-big.sh | 2 +
test/shell/lvcreate-thin-external.sh | 2 +
test/shell/lvcreate-thin-power2.sh | 2 +
test/shell/lvcreate-thin-snap.sh | 2 +
test/shell/lvcreate-thin.sh | 2 +
test/shell/lvextend-percent-extents.sh | 2 +
test/shell/lvextend-snapshot-dmeventd.sh | 2 +
test/shell/lvextend-snapshot-policy.sh | 2 +
test/shell/lvextend-thin-metadata-dmeventd.sh | 2 +
test/shell/lvextend-thin.sh | 2 +
test/shell/lvm-init.sh | 2 +
test/shell/lvmcache-exercise.sh | 2 +
test/shell/lvmetad-ambiguous.sh | 1 +
test/shell/lvmetad-client-filter.sh | 2 +
test/shell/lvmetad-disabled.sh | 2 +
test/shell/lvmetad-dump.sh | 2 +
test/shell/lvmetad-lvm1.sh | 2 +
test/shell/lvmetad-lvscan-cache.sh | 1 +
test/shell/lvmetad-no-cluster.sh | 2 +
test/shell/lvmetad-override.sh | 2 +
test/shell/lvmetad-pvs.sh | 2 +
test/shell/lvmetad-pvscan-cache.sh | 1 +
test/shell/lvmetad-pvscan-filter.sh | 1 +
test/shell/lvmetad-pvscan-md.sh | 1 +
test/shell/lvmetad-pvscan-nomda.sh | 2 +
test/shell/lvmetad-restart.sh | 2 +
test/shell/lvmetad-test.sh | 2 +
test/shell/lvmetad-warning.sh | 2 +
test/shell/lvresize-mirror.sh | 2 +
test/shell/lvresize-raid.sh | 2 +
test/shell/lvresize-raid10.sh | 2 +
test/shell/lvresize-rounding.sh | 2 +
test/shell/lvresize-thin-external-origin.sh | 2 +
test/shell/lvresize-thin-metadata.sh | 2 +
test/shell/lvresize-usage.sh | 2 +
test/shell/lvs-cache.sh | 2 +
test/shell/mda-rollback.sh | 2 +
test/shell/mdata-strings.sh | 2 +
test/shell/metadata-balance.sh | 2 +
test/shell/metadata-dirs.sh | 2 +
test/shell/metadata.sh | 2 +
test/shell/mirror-names.sh | 18 +
test/shell/mirror-vgreduce-removemissing.sh | 2 +
test/shell/name-mangling.sh | 1 +
test/shell/nomda-missing.sh | 2 +
test/shell/nomda-restoremissing.sh | 2 +
test/shell/orphan-ondisk.sh | 2 +
test/shell/pool-labels.sh | 1 +
test/shell/process-each-duplicate-vgnames.sh | 2 +
test/shell/process-each-lv.sh | 2 +
test/shell/process-each-pv-nomda-all.sh | 2 +
test/shell/process-each-pv-nomda.sh | 2 +
test/shell/process-each-pv.sh | 2 +
test/shell/process-each-pvresize.sh | 2 +
test/shell/process-each-vg.sh | 2 +
test/shell/profiles-thin.sh | 2 +
test/shell/profiles.sh | 2 +
test/shell/pv-duplicate-uuid.sh | 2 +
test/shell/pv-duplicate.sh | 2 +
test/shell/pv-min-size.sh | 2 +
test/shell/pvchange-usage.sh | 2 +
test/shell/pvcreate-bootloaderarea.sh | 2 +
test/shell/pvcreate-ff.sh | 2 +
test/shell/pvcreate-metadata0.sh | 2 +
test/shell/pvcreate-operation-md.sh | 2 +
test/shell/pvcreate-operation.sh | 2 +
test/shell/pvcreate-usage.sh | 2 +
test/shell/pvmove-restart.sh | 8 +-
test/shell/pvmove-resume-1.sh | 64 ++-
test/shell/pvmove-resume-2.sh | 42 +-
test/shell/pvmove-resume-multiseg.sh | 48 ++-
test/shell/pvremove-thin.sh | 2 +
test/shell/pvremove-usage.sh | 2 +
test/shell/pvremove-warnings.sh | 2 +
test/shell/read-ahead.sh | 2 +
test/shell/select-report.sh | 2 +
test/shell/select-tools-thin.sh | 2 +
test/shell/select-tools.sh | 2 +
test/shell/snapshot-autoumount-dmeventd.sh | 2 +
test/shell/snapshot-cluster.sh | 2 +
test/shell/snapshot-lvm1.sh | 2 +
test/shell/snapshot-maxsize.sh | 2 +
test/shell/snapshot-reactivate.sh | 2 +
test/shell/snapshot-rename.sh | 2 +
test/shell/snapshot-usage-exa.sh | 2 +
test/shell/snapshot-usage.sh | 2 +
test/shell/stray-device-node.sh | 2 +
test/shell/system_id.sh | 2 +
test/shell/tags.sh | 2 +
test/shell/test-partition.sh | 2 +
test/shell/thin-autoumount-dmeventd.sh | 2 +
test/shell/thin-defaults.sh | 2 +
test/shell/thin-restore.sh | 2 +
test/shell/thin-volume-list.sh | 2 +
test/shell/topology-support.sh | 2 +
test/shell/unknown-segment.sh | 2 +
test/shell/unlost-pv.sh | 2 +
test/shell/vg-name-from-env.sh | 2 +
test/shell/vgcfgbackup-usage.sh | 2 +
test/shell/vgchange-many.sh | 2 +
test/shell/vgchange-maxlv.sh | 2 +
test/shell/vgchange-partial.sh | 2 +
test/shell/vgchange-sysinit.sh | 1 +
test/shell/vgchange-usage.sh | 2 +
test/shell/vgck.sh | 2 +
test/shell/vgcreate-many-pvs.sh | 2 +
test/shell/vgcreate-usage.sh | 2 +
test/shell/vgextend-restoremissing.sh | 2 +
test/shell/vgextend-usage.sh | 2 +
test/shell/vgimportclone.sh | 2 +
test/shell/vgmerge-operation.sh | 2 +
test/shell/vgmerge-usage.sh | 2 +
test/shell/vgreduce-usage.sh | 2 +
test/shell/vgremove-corrupt-vg.sh | 2 +
test/shell/vgrename-usage.sh | 2 +
test/shell/vgsplit-operation.sh | 2 +
test/shell/vgsplit-raid.sh | 2 +
test/shell/vgsplit-stacked.sh | 2 +
test/shell/vgsplit-thin.sh | 2 +
test/shell/vgsplit-usage.sh | 2 +
test/shell/zero-usage.sh | 2 +
tools/Makefile.in | 3 +-
tools/args.h | 2 +
tools/commands.h | 16 +
tools/lvpoll.c | 115 +++
tools/polldaemon.c | 181 +++++-
tools/polldaemon.h | 93 ---
tools/pvmove.c | 2 +-
228 files changed, 3640 insertions(+), 142 deletions(-)
diff --git a/WHATS_NEW b/WHATS_NEW
index 24f0c76..7052016 100644
--- a/WHATS_NEW
+++ b/WHATS_NEW
@@ -1,5 +1,7 @@
Version 2.02.120 -
===============================
+ Add lvpoll for cmdline communication with lvmpolld.
+ Add lvmpolld acting as a free-standing version of polldaemon.
Properly validate PV size for pvcreate --restorefile.
Fix check if pvcreate wiped device (2.02.117).
Fix storing of vgid when caching metadata (2.02.118).
diff --git a/conf/example.conf.in b/conf/example.conf.in
index c1a8f03..e16aa7f 100644
--- a/conf/example.conf.in
+++ b/conf/example.conf.in
@@ -938,6 +938,16 @@ global {
# Comments starting with the character # are ignored.
# This configuration option does not have a default value defined.
# system_id_file = ""
+
+ # Indicates whether to use lvmpolld instead of classical polldaemon (a process
+ # forked off an initiating lvm command) or not. When set to 1 and native systemd
+ # service is installed in the system lvm starts using lvmpolld. lvmpolld gets
+ # auto-activated by systemd when a message lands on the respective lvmpolld socket.
+ # All commands that would require polling of in-progress operation are therefore
+ # spawned in lvmpolld's service cgroup.
+ #
+ # When set to 0 lvm falls back to classical polling.
+ use_lvmpolld = 0
}
# Configuration section activation.
diff --git a/configure b/configure
index 51a8f35..8c51c71 100755
--- a/configure
+++ b/configure
@@ -636,6 +636,7 @@ kerneldir
interface
CMIRRORD_PIDFILE
CLVMD_PIDFILE
+LVMPOLLD_PIDFILE
LVMETAD_PIDFILE
DMEVENTD_PIDFILE
WRITE_INSTALL
@@ -724,6 +725,7 @@ CLDWHOLEARCHIVE
CLDNOWHOLEARCHIVE
CLDFLAGS
CACHE
+BUILD_LVMPOLLD
BUILD_LVMETAD
BUILD_DMEVENTD
BUILD_CMIRRORD
@@ -914,6 +916,8 @@ enable_valgrind_pool
enable_devmapper
enable_lvmetad
with_lvmetad_pidfile
+enable_lvmpolld
+with_lvmpolld_pidfile
enable_blkid_wiping
enable_udev_systemd_background_jobs
enable_udev_sync
@@ -1627,6 +1631,7 @@ Optional Features:
--enable-valgrind-pool enable valgrind awareness of pools
--disable-devmapper disable LVM2 device-mapper interaction
--enable-lvmetad enable the LVM Metadata Daemon
+ --enable-lvmpolld enable the LVM Polling Daemon
--disable-blkid_wiping disable libblkid detection of signatures when wiping
and use native code instead
--disable-udev-systemd-background-jobs
@@ -1718,6 +1723,8 @@ Optional Packages:
--with-optimisation=OPT C optimisation flag [OPT=-O2]
--with-lvmetad-pidfile=PATH
lvmetad pidfile [PID_DIR/lvmetad.pid]
+ --with-lvmpolld-pidfile=PATH
+ lvmpolld pidfile [PID_DIR/lvmpolld.pid]
--with-localedir=DIR translation files in DIR [PREFIX/share/locale]
--with-confdir=DIR configuration files in DIR [/etc]
--with-staticdir=DIR static binaries in DIR [EPREFIX/sbin]
@@ -3033,6 +3040,7 @@ case "$host_os" in
LIB_SUFFIX=so
DEVMAPPER=yes
LVMETAD=no
+ LVMPOLLD=no
ODIRECT=yes
DM_IOCTLS=yes
SELINUX=yes
@@ -10856,6 +10864,39 @@ _ACEOF
fi
################################################################################
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to build lvmpolld" >&5
+$as_echo_n "checking whether to build lvmpolld... " >&6; }
+# Check whether --enable-lvmpolld was given.
+if test "${enable_lvmpolld+set}" = set; then :
+ enableval=$enable_lvmpolld; LVMPOLLD=$enableval
+fi
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $LVMPOLLD" >&5
+$as_echo "$LVMPOLLD" >&6; }
+
+BUILD_LVMPOLLD=$LVMPOLLD
+
+if test "$BUILD_LVMPOLLD" = yes; then
+
+$as_echo "#define LVMPOLLD_SUPPORT 1" >>confdefs.h
+
+
+
+# Check whether --with-lvmpolld-pidfile was given.
+if test "${with_lvmpolld_pidfile+set}" = set; then :
+ withval=$with_lvmpolld_pidfile; LVMPOLLD_PIDFILE=$withval
+else
+ LVMPOLLD_PIDFILE="$DEFAULT_PID_DIR/lvmpolld.pid"
+fi
+
+
+cat >>confdefs.h <<_ACEOF
+#define LVMPOLLD_PIDFILE "$LVMPOLLD_PIDFILE"
+_ACEOF
+
+fi
+
+################################################################################
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to enable libblkid detection of signatures when wiping" >&5
$as_echo_n "checking whether to enable libblkid detection of signatures when wiping... " >&6; }
# Check whether --enable-blkid_wiping was given.
@@ -13147,8 +13188,10 @@ LVM_LIBAPI=`echo "$VER" | $AWK -F '[()]' '{print $2}'`
+
+
################################################################################
-ac_config_files="$ac_config_files Makefile make.tmpl daemons/Makefile daemons/clvmd/Makefile daemons/cmirrord/Makefile daemons/dmeventd/Makefile daemons/dmeventd/libdevmapper-event.pc daemons/dmeventd/plugins/Makefile daemons/dmeventd/plugins/lvm2/Makefile daemons/dmeventd/plugins/raid/Makefile daemons/dmeventd/plugins/mirror/Makefile daemons/dmeventd/plugins/snapshot/Makefile daemons/dmeventd/plugins/thin/Makefile daemons/lvmetad/Makefile conf/Makefile conf/example.conf conf/lvmlocal.conf conf/command_profile_template.profile conf/metadata_profile_template.profile include/.symlinks include/Makefile lib/Makefile lib/format1/Makefile lib/format_pool/Makefile lib/locking/Makefile lib/mirror/Makefile lib/replicator/Makefile lib/misc/lvm-version.h lib/raid/Makefile lib/snapshot/Makefile lib/thin/Makefile lib/cache_segtype/Makefile libdaemon/Makefile libdaemon/client/Makefile libdaemon/server/Makefile libdm/Makefile libdm/libdevmapper.pc liblvm/Makefile liblvm/liblvm2app.pc man/M
akefile po/Makefile python/Makefile python/setup.py scripts/blkdeactivate.sh scripts/blk_availability_init_red_hat scripts/blk_availability_systemd_red_hat.service scripts/clvmd_init_red_hat scripts/cmirrord_init_red_hat scripts/dm_event_systemd_red_hat.service scripts/dm_event_systemd_red_hat.socket scripts/lvm2_cluster_activation_red_hat.sh scripts/lvm2_cluster_activation_systemd_red_hat.service scripts/lvm2_clvmd_systemd_red_hat.service scripts/lvm2_cmirrord_systemd_red_hat.service scripts/lvm2_lvmetad_init_red_hat scripts/lvm2_lvmetad_systemd_red_hat.service scripts/lvm2_lvmetad_systemd_red_hat.socket scripts/lvm2_monitoring_init_red_hat scripts/lvm2_monitoring_systemd_red_hat.service scripts/lvm2_pvscan_systemd_red_hat@.service scripts/lvm2_tmpfiles_red_hat.conf scripts/Makefile test/Makefile test/api/Makefile test/unit/Makefile tools/Makefile udev/Makefile unit-tests/datastruct/Makefile unit-tests/regex/Makefile unit-tests/mm/Makefile"
+ac_config_files="$ac_config_files Makefile make.tmpl daemons/Makefile daemons/clvmd/Makefile daemons/cmirrord/Makefile daemons/dmeventd/Makefile daemons/dmeventd/libdevmapper-event.pc daemons/dmeventd/plugins/Makefile daemons/dmeventd/plugins/lvm2/Makefile daemons/dmeventd/plugins/raid/Makefile daemons/dmeventd/plugins/mirror/Makefile daemons/dmeventd/plugins/snapshot/Makefile daemons/dmeventd/plugins/thin/Makefile daemons/lvmetad/Makefile daemons/lvmpolld/Makefile conf/Makefile conf/example.conf conf/lvmlocal.conf conf/command_profile_template.profile conf/metadata_profile_template.profile include/.symlinks include/Makefile lib/Makefile lib/format1/Makefile lib/format_pool/Makefile lib/locking/Makefile lib/mirror/Makefile lib/replicator/Makefile lib/misc/lvm-version.h lib/raid/Makefile lib/snapshot/Makefile lib/thin/Makefile lib/cache_segtype/Makefile libdaemon/Makefile libdaemon/client/Makefile libdaemon/server/Makefile libdm/Makefile libdm/libdevmapper.pc liblvm/Makefile
liblvm/liblvm2app.pc man/Makefile po/Makefile python/Makefile python/setup.py scripts/blkdeactivate.sh scripts/blk_availability_init_red_hat scripts/blk_availability_systemd_red_hat.service scripts/clvmd_init_red_hat scripts/cmirrord_init_red_hat scripts/dm_event_systemd_red_hat.service scripts/dm_event_systemd_red_hat.socket scripts/lvm2_cluster_activation_red_hat.sh scripts/lvm2_cluster_activation_systemd_red_hat.service scripts/lvm2_clvmd_systemd_red_hat.service scripts/lvm2_cmirrord_systemd_red_hat.service scripts/lvm2_lvmetad_init_red_hat scripts/lvm2_lvmetad_systemd_red_hat.service scripts/lvm2_lvmetad_systemd_red_hat.socket scripts/lvm2_lvmpolld_init_red_hat scripts/lvm2_lvmpolld_systemd_red_hat.service scripts/lvm2_lvmpolld_systemd_red_hat.socket scripts/lvm2_monitoring_init_red_hat scripts/lvm2_monitoring_systemd_red_hat.service scripts/lvm2_pvscan_systemd_red_hat@.service scripts/lvm2_tmpfiles_red_hat.conf scripts/Makefile test/Makefile test/api/Makefile test/unit/
Makefile tools/Makefile udev/Makefile unit-tests/datastruct/Makefile unit-tests/regex/Makefile unit-tests/mm/Makefile"
cat >confcache <<\_ACEOF
# This file is a shell script that caches the results of configure
@@ -13857,6 +13900,7 @@ do
"daemons/dmeventd/plugins/snapshot/Makefile") CONFIG_FILES="$CONFIG_FILES daemons/dmeventd/plugins/snapshot/Makefile" ;;
"daemons/dmeventd/plugins/thin/Makefile") CONFIG_FILES="$CONFIG_FILES daemons/dmeventd/plugins/thin/Makefile" ;;
"daemons/lvmetad/Makefile") CONFIG_FILES="$CONFIG_FILES daemons/lvmetad/Makefile" ;;
+ "daemons/lvmpolld/Makefile") CONFIG_FILES="$CONFIG_FILES daemons/lvmpolld/Makefile" ;;
"conf/Makefile") CONFIG_FILES="$CONFIG_FILES conf/Makefile" ;;
"conf/example.conf") CONFIG_FILES="$CONFIG_FILES conf/example.conf" ;;
"conf/lvmlocal.conf") CONFIG_FILES="$CONFIG_FILES conf/lvmlocal.conf" ;;
@@ -13900,6 +13944,9 @@ do
"scripts/lvm2_lvmetad_init_red_hat") CONFIG_FILES="$CONFIG_FILES scripts/lvm2_lvmetad_init_red_hat" ;;
"scripts/lvm2_lvmetad_systemd_red_hat.service") CONFIG_FILES="$CONFIG_FILES scripts/lvm2_lvmetad_systemd_red_hat.service" ;;
"scripts/lvm2_lvmetad_systemd_red_hat.socket") CONFIG_FILES="$CONFIG_FILES scripts/lvm2_lvmetad_systemd_red_hat.socket" ;;
+ "scripts/lvm2_lvmpolld_init_red_hat") CONFIG_FILES="$CONFIG_FILES scripts/lvm2_lvmpolld_init_red_hat" ;;
+ "scripts/lvm2_lvmpolld_systemd_red_hat.service") CONFIG_FILES="$CONFIG_FILES scripts/lvm2_lvmpolld_systemd_red_hat.service" ;;
+ "scripts/lvm2_lvmpolld_systemd_red_hat.socket") CONFIG_FILES="$CONFIG_FILES scripts/lvm2_lvmpolld_systemd_red_hat.socket" ;;
"scripts/lvm2_monitoring_init_red_hat") CONFIG_FILES="$CONFIG_FILES scripts/lvm2_monitoring_init_red_hat" ;;
"scripts/lvm2_monitoring_systemd_red_hat.service") CONFIG_FILES="$CONFIG_FILES scripts/lvm2_monitoring_systemd_red_hat.service" ;;
"scripts/lvm2_pvscan_systemd_red_hat@.service") CONFIG_FILES="$CONFIG_FILES scripts/lvm2_pvscan_systemd_red_hat@.service" ;;
diff --git a/configure.in b/configure.in
index a14540f..1887757 100644
--- a/configure.in
+++ b/configure.in
@@ -39,6 +39,7 @@ case "$host_os" in
LIB_SUFFIX=so
DEVMAPPER=yes
LVMETAD=no
+ LVMPOLLD=no
ODIRECT=yes
DM_IOCTLS=yes
SELINUX=yes
@@ -1078,6 +1079,29 @@ if test "$BUILD_LVMETAD" = yes; then
fi
################################################################################
+dnl -- Build lvmpolld
+AC_MSG_CHECKING(whether to build lvmpolld)
+AC_ARG_ENABLE(lvmpolld,
+ AC_HELP_STRING([--enable-lvmpolld],
+ [enable the LVM Polling Daemon]),
+ LVMPOLLD=$enableval)
+AC_MSG_RESULT($LVMPOLLD)
+
+BUILD_LVMPOLLD=$LVMPOLLD
+
+if test "$BUILD_LVMPOLLD" = yes; then
+ AC_DEFINE([LVMPOLLD_SUPPORT], 1, [Define to 1 to include code that uses lvmpolld.])
+
+ AC_ARG_WITH(lvmpolld-pidfile,
+ AC_HELP_STRING([--with-lvmpolld-pidfile=PATH],
+ [lvmpolld pidfile [PID_DIR/lvmpolld.pid]]),
+ LVMPOLLD_PIDFILE=$withval,
+ LVMPOLLD_PIDFILE="$DEFAULT_PID_DIR/lvmpolld.pid")
+ AC_DEFINE_UNQUOTED(LVMPOLLD_PIDFILE, ["$LVMPOLLD_PIDFILE"],
+ [Path to lvmpolld pidfile.])
+fi
+
+################################################################################
dnl -- Enable blkid wiping functionality
AC_MSG_CHECKING(whether to enable libblkid detection of signatures when wiping)
AC_ARG_ENABLE(blkid_wiping,
@@ -1687,6 +1711,7 @@ AC_SUBST(BLKID_WIPING)
AC_SUBST(BUILD_CMIRRORD)
AC_SUBST(BUILD_DMEVENTD)
AC_SUBST(BUILD_LVMETAD)
+AC_SUBST(BUILD_LVMPOLLD)
AC_SUBST(CACHE)
AC_SUBST(CFLAGS)
AC_SUBST(CFLOW_CMD)
@@ -1805,6 +1830,7 @@ AC_SUBST(VALGRIND_POOL)
AC_SUBST(WRITE_INSTALL)
AC_SUBST(DMEVENTD_PIDFILE)
AC_SUBST(LVMETAD_PIDFILE)
+AC_SUBST(LVMPOLLD_PIDFILE)
AC_SUBST(CLVMD_PIDFILE)
AC_SUBST(CMIRRORD_PIDFILE)
AC_SUBST(interface)
@@ -1838,6 +1864,7 @@ daemons/dmeventd/plugins/mirror/Makefile
daemons/dmeventd/plugins/snapshot/Makefile
daemons/dmeventd/plugins/thin/Makefile
daemons/lvmetad/Makefile
+daemons/lvmpolld/Makefile
conf/Makefile
conf/example.conf
conf/lvmlocal.conf
@@ -1881,6 +1908,9 @@ scripts/lvm2_cmirrord_systemd_red_hat.service
scripts/lvm2_lvmetad_init_red_hat
scripts/lvm2_lvmetad_systemd_red_hat.service
scripts/lvm2_lvmetad_systemd_red_hat.socket
+scripts/lvm2_lvmpolld_init_red_hat
+scripts/lvm2_lvmpolld_systemd_red_hat.service
+scripts/lvm2_lvmpolld_systemd_red_hat.socket
scripts/lvm2_monitoring_init_red_hat
scripts/lvm2_monitoring_systemd_red_hat.service
scripts/lvm2_pvscan_systemd_red_hat@.service
diff --git a/daemons/Makefile.in b/daemons/Makefile.in
index 9a73516..8a466b3 100644
--- a/daemons/Makefile.in
+++ b/daemons/Makefile.in
@@ -1,5 +1,5 @@
#
-# Copyright (C) 2004-2011 Red Hat, Inc. All rights reserved.
+# Copyright (C) 2004-2015 Red Hat, Inc. All rights reserved.
#
# This file is part of LVM2.
#
@@ -15,7 +15,7 @@ srcdir = @srcdir@
top_srcdir = @top_srcdir@
top_builddir = @top_builddir@
-.PHONY: dmeventd clvmd cmirrord lvmetad
+.PHONY: dmeventd clvmd cmirrord lvmetad lvmpolld
ifneq ("@CLVMD@", "none")
SUBDIRS += clvmd
@@ -36,8 +36,12 @@ ifeq ("@BUILD_LVMETAD@", "yes")
SUBDIRS += lvmetad
endif
+ifeq ("@BUILD_LVMPOLLD@", "yes")
+ SUBDIRS += lvmpolld
+endif
+
ifeq ($(MAKECMDGOALS),distclean)
- SUBDIRS = clvmd cmirrord dmeventd lvmetad
+ SUBDIRS = clvmd cmirrord dmeventd lvmetad lvmpolld
endif
include $(top_builddir)/make.tmpl
diff --git a/daemons/lvmpolld/Makefile.in b/daemons/lvmpolld/Makefile.in
new file mode 100644
index 0000000..55f3dad
--- /dev/null
+++ b/daemons/lvmpolld/Makefile.in
@@ -0,0 +1,49 @@
+#
+# Copyright (C) 2014-2015 Red Hat, Inc.
+#
+# This file is part of LVM2.
+#
+# This copyrighted material is made available to anyone wishing to use,
+# modify, copy, or redistribute it subject to the terms and conditions
+# of the GNU Lesser General Public License v.2.1.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with this program; if not, write to the Free Software Foundation,
+# Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+srcdir = @srcdir@
+top_srcdir = @top_srcdir@
+top_builddir = @top_builddir@
+
+SOURCES = lvmpolld-core.c lvmpolld-data-utils.c lvmpolld-cmd-utils.c
+
+TARGETS = lvmpolld
+
+.PHONY: install_lvmpolld
+
+CFLOW_LIST = $(SOURCES)
+CFLOW_LIST_TARGET = $(LIB_NAME).cflow
+CFLOW_TARGET = lvmpolld
+
+include $(top_builddir)/make.tmpl
+
+INCLUDES += -I$(top_srcdir)/libdaemon/server
+LVMLIBS = -ldaemonserver $(LVMINTERNAL_LIBS) -ldevmapper
+
+LIBS += $(PTHREAD_LIBS)
+
+LDFLAGS += -L$(top_builddir)/libdaemon/server $(DAEMON_LDFLAGS)
+CLDFLAGS += -L$(top_builddir)/libdaemon/server
+CFLAGS += $(DAEMON_CFLAGS)
+
+lvmpolld: $(OBJECTS) $(top_builddir)/libdaemon/client/libdaemonclient.a \
+ $(top_builddir)/libdaemon/server/libdaemonserver.a
+ $(CC) $(CFLAGS) $(LDFLAGS) -o $@ $(OBJECTS) \
+ $(DL_LIBS) $(LVMLIBS) $(LIBS)
+
+install_lvmpolld: lvmpolld
+ $(INSTALL_PROGRAM) -D $< $(sbindir)/$(<F)
+
+install_lvm2: install_lvmpolld
+
+install: install_lvm2
diff --git a/daemons/lvmpolld/lvmpolld-cmd-utils.c b/daemons/lvmpolld/lvmpolld-cmd-utils.c
new file mode 100644
index 0000000..cd789a3
--- /dev/null
+++ b/daemons/lvmpolld/lvmpolld-cmd-utils.c
@@ -0,0 +1,140 @@
+/*
+ * Copyright (C) 2015 Red Hat, Inc.
+ *
+ * This file is part of LVM2.
+ *
+ * This copyrighted material is made available to anyone wishing to use,
+ * modify, copy, or redistribute it subject to the terms and conditions
+ * of the GNU Lesser General Public License v.2.1.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include "lvmpolld-common.h"
+
+/* extract this info from autoconf/automake files */
+#define LVPOLL_CMD "lvpoll"
+
+#define MIN_ARGV_SIZE 8
+
+static const char *const const polling_ops[] = { [PVMOVE] = LVMPD_REQ_PVMOVE,
+ [CONVERT] = LVMPD_REQ_CONVERT,
+ [MERGE] = LVMPD_REQ_MERGE,
+ [MERGE_THIN] = LVMPD_REQ_MERGE_THIN };
+
+const char *polling_op(enum poll_type type)
+{
+ return type < POLL_TYPE_MAX ? polling_ops[type] : "<undefined>";
+}
+
+static int add_to_cmd_arr(const char ***cmdargv, const char *str, unsigned *ind)
+{
+ const char **newargv = *cmdargv;
+
+ if (*ind && !(*ind % MIN_ARGV_SIZE)) {
+ newargv = dm_realloc(*cmdargv, (*ind / MIN_ARGV_SIZE + 1) * MIN_ARGV_SIZE * sizeof(char *));
+ if (!newargv)
+ return 0;
+ *cmdargv = newargv;
+ }
+
+ *(*cmdargv + (*ind)++) = str;
+
+ return 1;
+}
+
+const char **cmdargv_ctr(const struct lvmpolld_lv *pdlv, const char *lvm_binary, unsigned abort_polling, unsigned handle_missing_pvs)
+{
+ unsigned i = 0;
+ const char **cmd_argv = dm_malloc(MIN_ARGV_SIZE * sizeof(char *));
+
+ if (!cmd_argv)
+ return NULL;
+
+ /* path to lvm2 binary */
+ if (!add_to_cmd_arr(&cmd_argv, lvm_binary, &i))
+ goto err;
+
+ /* cmd to execute */
+ if (!add_to_cmd_arr(&cmd_argv, LVPOLL_CMD, &i))
+ goto err;
+
+ /* transfer internal polling interval */
+ if (pdlv->sinterval &&
+ (!add_to_cmd_arr(&cmd_argv, "--interval", &i) ||
+ !add_to_cmd_arr(&cmd_argv, pdlv->sinterval, &i)))
+ goto err;
+
+ /* pass abort param */
+ if (abort_polling &&
+ !add_to_cmd_arr(&cmd_argv, "--abort", &i))
+ goto err;
+
+ /* pass handle-missing-pvs. used by mirror polling operation */
+ if (handle_missing_pvs &&
+ !add_to_cmd_arr(&cmd_argv, "--handlemissingpvs", &i))
+ goto err;
+
+ /* one of: "convert", "pvmove", "merge", "merge_thin" */
+ if (!add_to_cmd_arr(&cmd_argv, "--polloperation", &i) ||
+ !add_to_cmd_arr(&cmd_argv, polling_ops[pdlv->type], &i))
+ goto err;
+
+ /* vg/lv name */
+ if (!add_to_cmd_arr(&cmd_argv, pdlv->lvname, &i))
+ goto err;
+
+ /* terminating NULL */
+ if (!add_to_cmd_arr(&cmd_argv, NULL, &i))
+ goto err;
+
+ return cmd_argv;
+err:
+ dm_free(cmd_argv);
+ return NULL;
+}
+
+/* FIXME: in fact exclude should be va list */
+static int copy_env(const char ***cmd_envp, unsigned *i, const char *exclude)
+{
+ const char * const* tmp = (const char * const*) environ;
+
+ if (!tmp)
+ return 0;
+
+ while (*tmp) {
+ if (strncmp(*tmp, exclude, strlen(exclude)) && !add_to_cmd_arr(cmd_envp, *tmp, i))
+ return 0;
+ tmp++;
+ }
+
+ return 1;
+}
+
+const char **cmdenvp_ctr(const struct lvmpolld_lv *pdlv)
+{
+ unsigned i = 0;
+ const char **cmd_envp = dm_malloc(MIN_ARGV_SIZE * sizeof(char *));
+
+ if (!cmd_envp)
+ return NULL;
+
+ /* copy whole environment from lvmpolld, exclude LVM_SYSTEM_DIR if set */
+ if (!copy_env(&cmd_envp, &i, "LVM_SYSTEM_DIR="))
+ goto err;
+
+ /* Add per client LVM_SYSTEM_DIR variable if set */
+ if (*pdlv->lvm_system_dir_env && !add_to_cmd_arr(&cmd_envp, pdlv->lvm_system_dir_env, &i))
+ goto err;
+
+ /* terminating NULL */
+ if (!add_to_cmd_arr(&cmd_envp, NULL, &i))
+ goto err;
+
+ return cmd_envp;
+err:
+ dm_free(cmd_envp);
+ return NULL;
+}
diff --git a/daemons/lvmpolld/lvmpolld-cmd-utils.h b/daemons/lvmpolld/lvmpolld-cmd-utils.h
new file mode 100644
index 0000000..509c2e9
--- /dev/null
+++ b/daemons/lvmpolld/lvmpolld-cmd-utils.h
@@ -0,0 +1,25 @@
+/*
+ * Copyright (C) 2015 Red Hat, Inc.
+ *
+ * This file is part of LVM2.
+ *
+ * This copyrighted material is made available to anyone wishing to use,
+ * modify, copy, or redistribute it subject to the terms and conditions
+ * of the GNU Lesser General Public License v.2.1.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef _LVM_LVMPOLLD_CMD_UTILS_H
+#define _LVM_LVMPOLLD_CMD_UTILS_H
+
+#include "lvmpolld-data-utils.h"
+
+const char **cmdargv_ctr(const struct lvmpolld_lv *pdlv, const char *lvm_binary, unsigned abort, unsigned handle_missing_pvs);
+const char **cmdenvp_ctr(const struct lvmpolld_lv *pdlv);
+
+const char *polling_op(enum poll_type);
+
+#endif /* _LVM_LVMPOLLD_CMD_UTILS_H */
diff --git a/daemons/lvmpolld/lvmpolld-common.h b/daemons/lvmpolld/lvmpolld-common.h
new file mode 100644
index 0000000..81423f0
--- /dev/null
+++ b/daemons/lvmpolld/lvmpolld-common.h
@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) 2010-2015 Red Hat, Inc. All rights reserved.
+ *
+ * This file is part of LVM2.
+ *
+ * This copyrighted material is made available to anyone wishing to use,
+ * modify, copy, or redistribute it subject to the terms and conditions
+ * of the GNU Lesser General Public License v.2.1.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+/*
+ * This file must be included first by every lvmpolld source file.
+ */
+#ifndef _LVM_LVMPOLLD_COMMON_H
+#define _LVM_LVMPOLLD_COMMON_H
+
+#include "configure.h"
+
+#define _REENTRANT
+#define _GNU_SOURCE
+#define _FILE_OFFSET_BITS 64
+
+#include "libdevmapper.h"
+
+#include "lvmpolld-cmd-utils.h"
+#include "lvmpolld-protocol.h"
+
+#include <assert.h>
+#include <errno.h>
+#include <unistd.h>
+
+#endif /* _LVM_LVMPOLLD_COMMON_H */
diff --git a/daemons/lvmpolld/lvmpolld-core.c b/daemons/lvmpolld/lvmpolld-core.c
new file mode 100644
index 0000000..a770f89
--- /dev/null
+++ b/daemons/lvmpolld/lvmpolld-core.c
@@ -0,0 +1,817 @@
+/*
+ * Copyright (C) 2014-2015 Red Hat, Inc.
+ *
+ * This file is part of LVM2.
+ *
+ * This copyrighted material is made available to anyone wishing to use,
+ * modify, copy, or redistribute it subject to the terms and conditions
+ * of the GNU Lesser General Public License v.2.1.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include "lvmpolld-common.h"
+
+#include "lvm-version.h"
+#include "daemon-server.h"
+#include "daemon-log.h"
+
+#include <poll.h>
+#include <wait.h>
+
+#define LVMPOLLD_SOCKET DEFAULT_RUN_DIR "/lvmpolld.socket"
+
+#define PD_LOG_PREFIX "LVMPOLLD"
+#define LVM2_LOG_PREFIX "\tLVPOLL"
+
+/* predefined reason for response = "failed" case */
+#define REASON_REQ_NOT_IMPLEMENTED "request not implemented"
+#define REASON_MISSING_LVID "request requires lvid set"
+#define REASON_MISSING_LVNAME "request requires lvname set"
+#define REASON_MISSING_VGNAME "request requires vgname set"
+#define REASON_POLLING_FAILED "polling of lvm command failed"
+#define REASON_ILLEGAL_ABORT_REQUEST "abort only supported with PVMOVE polling operation"
+#define REASON_DIFFERENT_OPERATION_IN_PROGRESS "Different operation on LV already in progress"
+#define REASON_INVALID_INTERVAL "request requires interval set"
+#define REASON_ENOMEM "not enough memory"
+
+struct lvmpolld_state {
+ daemon_idle *idle;
+ log_state *log;
+ const char *log_config;
+ const char *lvm_binary;
+
+ struct lvmpolld_store *id_to_pdlv_abort;
+ struct lvmpolld_store *id_to_pdlv_poll;
+};
+
+static pthread_key_t key;
+
+static const char *_strerror_r(int errnum, struct lvmpolld_thread_data *data)
+{
+#ifdef _GNU_SOURCE
+ return strerror_r(errnum, data->buf, sizeof(data->buf)); /* never returns NULL */
+#elif (_POSIX_C_SOURCE >= 200112L || _XOPEN_SOURCE >= 600)
+ return strerror_r(errnum, data->buf, sizeof(data->buf)) ? "" : data->buf;
+#else
+# warning "Can't decide proper strerror_r implementation. lvmpolld will not issue specific system error messages"
+ return "";
+#endif
+}
+
+static void usage(const char *prog, FILE *file)
+{
+ fprintf(file, "Usage:\n"
+ "%s [-V] [-h] [-f] [-l {all|wire|debug}] [-s path]\n\n"
+ " -V Show version info\n"
+ " -h Show this help information\n"
+ " -f Don't fork, run in the foreground\n"
+ " -l Logging message level (-l {all|wire|debug})\n"
+ " -p Set path to the pidfile\n"
+ " -s Set path to the socket to listen on\n"
+ " -B Path to lvm2 binary\n"
+ " -t Time to wait in seconds before shutdown on idle (missing or 0 = inifinite)\n\n", prog);
+}
+
+static int init(struct daemon_state *s)
+{
+ struct lvmpolld_state *ls = s->private;
+ ls->log = s->log;
+
+ if (!daemon_log_parse(ls->log, DAEMON_LOG_OUTLET_STDERR, ls->log_config, 1))
+ return 0;
+
+ if (pthread_key_create(&key, lvmpolld_thread_data_destroy)) {
+ FATAL(ls, "%s: %s", PD_LOG_PREFIX, "Failed to create pthread key");
+ return 0;
+ }
+
+ ls->id_to_pdlv_poll = pdst_init("polling");
+ ls->id_to_pdlv_abort = pdst_init("abort");
+
+ if (!ls->id_to_pdlv_poll || !ls->id_to_pdlv_abort) {
+ FATAL(ls, "%s: %s", PD_LOG_PREFIX, "Failed to allocate internal data structures");
+ return 0;
+ }
+
+ ls->lvm_binary = ls->lvm_binary ?: LVM_PATH;
+
+ if (access(ls->lvm_binary, X_OK)) {
+ FATAL(ls, "%s: %s %s", PD_LOG_PREFIX, "Execute access rights denied on", ls->lvm_binary);
+ return 0;
+ }
+
+ if (ls->idle)
+ ls->idle->is_idle = 1;
+
+ return 1;
+}
+
+static void lvmpolld_stores_lock(struct lvmpolld_state *ls)
+{
+ pdst_lock(ls->id_to_pdlv_poll);
+ pdst_lock(ls->id_to_pdlv_abort);
+}
+
+static void lvmpolld_stores_unlock(struct lvmpolld_state *ls)
+{
+ pdst_unlock(ls->id_to_pdlv_abort);
+ pdst_unlock(ls->id_to_pdlv_poll);
+}
+
+static void lvmpolld_global_lock(struct lvmpolld_state *ls)
+{
+ lvmpolld_stores_lock(ls);
+
+ pdst_locked_lock_all_pdlvs(ls->id_to_pdlv_poll);
+ pdst_locked_lock_all_pdlvs(ls->id_to_pdlv_abort);
+}
+
+static void lvmpolld_global_unlock(struct lvmpolld_state *ls)
+{
+ pdst_locked_unlock_all_pdlvs(ls->id_to_pdlv_abort);
+ pdst_locked_unlock_all_pdlvs(ls->id_to_pdlv_poll);
+
+ lvmpolld_stores_unlock(ls);
+}
+
+static int fini(struct daemon_state *s)
+{
+ int done;
+ const struct timespec t = { .tv_nsec = 250000000 }; /* .25 sec */
+ struct lvmpolld_state *ls = s->private;
+
+ DEBUGLOG(s, "fini");
+
+ DEBUGLOG(s, "sending cancel requests");
+
+ lvmpolld_global_lock(ls);
+ pdst_locked_send_cancel(ls->id_to_pdlv_poll);
+ pdst_locked_send_cancel(ls->id_to_pdlv_abort);
+ lvmpolld_global_unlock(ls);
+
+ DEBUGLOG(s, "waiting for background threads to finish");
+
+ while(1) {
+ lvmpolld_stores_lock(ls);
+ done = !pdst_locked_get_active_count(ls->id_to_pdlv_poll) &&
+ !pdst_locked_get_active_count(ls->id_to_pdlv_abort);
+ lvmpolld_stores_unlock(ls);
+ if (done)
+ break;
+ nanosleep(&t, NULL);
+ }
+
+ DEBUGLOG(s, "destroying internal data structures");
+
+ lvmpolld_stores_lock(ls);
+ pdst_locked_destroy_all_pdlvs(ls->id_to_pdlv_poll);
+ pdst_locked_destroy_all_pdlvs(ls->id_to_pdlv_abort);
+ lvmpolld_stores_unlock(ls);
+
+ pdst_destroy(ls->id_to_pdlv_poll);
+ pdst_destroy(ls->id_to_pdlv_abort);
+
+ pthread_key_delete(key);
+
+ return 1;
+}
+
+static response reply(const char *res, const char *reason)
+{
+ return daemon_reply_simple(res, "reason = %s", reason, NULL);
+}
+
+static int read_single_line(struct lvmpolld_thread_data *data, int err)
+{
+ ssize_t r = getline(&data->line, &data->line_size, err ? data->ferr : data->fout);
+
+ if (r > 0 && *(data->line + r - 1) == '\n')
+ *(data->line + r - 1) = '\0';
+
+ return (r > 0);
+}
+
+static void update_idle_state(struct lvmpolld_state *ls)
+{
+ if (!ls->idle)
+ return;
+
+ lvmpolld_stores_lock(ls);
+
+ ls->idle->is_idle = !pdst_locked_get_active_count(ls->id_to_pdlv_poll) &&
+ !pdst_locked_get_active_count(ls->id_to_pdlv_abort);
+
+ lvmpolld_stores_unlock(ls);
+
+ DEBUGLOG(ls, "%s: %s %s%s", PD_LOG_PREFIX, "daemon is", ls->idle->is_idle ? "" : "not ", "idle");
+}
+
+/* make this configurable */
+#define MAX_TIMEOUT 2
+
+static int poll_for_output(struct lvmpolld_lv *pdlv, struct lvmpolld_thread_data *data)
+{
+ int ch_stat, r, err = 1, fds_count = 2, timeout = 0;
+ pid_t pid;
+ struct lvmpolld_cmd_stat cmd_state = { .retcode = -1, .signal = 0 };
+ struct pollfd fds[] = { { .fd = data->outpipe[0], .events = POLLIN },
+ { .fd = data->errpipe[0], .events = POLLIN } };
+
+ if (!(data->fout = fdopen(data->outpipe[0], "r")) || !(data->ferr = fdopen(data->errpipe[0], "r"))) {
+ ERROR(pdlv->ls, "%s: %s: (%d) %s", PD_LOG_PREFIX, "failed to open file stream",
+ errno, _strerror_r(errno, data));
+ goto out;
+ }
+
+ while (1) {
+ do {
+ r = poll(fds, 2, pdlv_get_timeout(pdlv) * 1000);
+ } while (r < 0 && errno == EINTR);
+
+ DEBUGLOG(pdlv->ls, "%s: %s %d", PD_LOG_PREFIX, "poll() returned", r);
+ if (r < 0) {
+ ERROR(pdlv->ls, "%s: %s (PID %d) failed: (%d) %s",
+ PD_LOG_PREFIX, "poll() for LVM2 cmd", pdlv->cmd_pid,
+ errno, _strerror_r(errno, data));
+ goto out;
+ } else if (!r) {
+ timeout++;
+
+ WARN(pdlv->ls, "%s: %s (PID %d) %s", PD_LOG_PREFIX,
+ "polling for output of the lvm cmd", pdlv->cmd_pid,
+ "has timed out");
+
+ if (timeout > MAX_TIMEOUT) {
+ ERROR(pdlv->ls, "%s: %s (PID %d) (no output for %d seconds)",
+ PD_LOG_PREFIX,
+ "LVM2 cmd is unresponsive too long",
+ pdlv->cmd_pid,
+ timeout * pdlv_get_timeout(pdlv));
+ goto out;
+ }
+
+ continue; /* while(1) */
+ }
+
+ timeout = 0;
+
+ /* handle the command's STDOUT */
+ if (fds[0].revents & POLLIN) {
+ DEBUGLOG(pdlv->ls, "%s: %s", PD_LOG_PREFIX, "caught input data in STDOUT");
+
+ assert(read_single_line(data, 0)); /* may block indef. anyway */
+ INFO(pdlv->ls, "%s: PID %d: %s: '%s'", LVM2_LOG_PREFIX,
+ pdlv->cmd_pid, "STDOUT", data->line);
+ } else if (fds[0].revents) {
+ if (fds[0].revents & POLLHUP)
+ DEBUGLOG(pdlv->ls, "%s: %s", PD_LOG_PREFIX, "caught POLLHUP");
+ else
+ WARN(pdlv->ls, "%s: %s", PD_LOG_PREFIX, "poll for command's STDOUT failed");
+
+ fds[0].fd = -1;
+ fds_count--;
+ }
+
+ /* handle the command's STDERR */
+ if (fds[1].revents & POLLIN) {
+ DEBUGLOG(pdlv->ls, "%s: %s", PD_LOG_PREFIX,
+ "caught input data in STDERR");
+
+ assert(read_single_line(data, 1)); /* may block indef. anyway */
+ INFO(pdlv->ls, "%s: PID %d: %s: '%s'", LVM2_LOG_PREFIX,
+ pdlv->cmd_pid, "STDERR", data->line);
+ } else if (fds[1].revents) {
+ if (fds[1].revents & POLLHUP)
+ DEBUGLOG(pdlv->ls, "%s: %s", PD_LOG_PREFIX, "caught err POLLHUP");
+ else
+ WARN(pdlv->ls, "%s: %s", PD_LOG_PREFIX, "poll for command's STDOUT failed");
+
+ fds[1].fd = -1;
+ fds_count--;
+ }
+
+ do {
+ /*
+ * fds_count == 0 means polling reached EOF
+ * or received error on both descriptors.
+ * In such case, just wait for command to finish
+ */
+ pid = waitpid(pdlv->cmd_pid, &ch_stat, fds_count ? WNOHANG : 0);
+ } while (pid < 0 && errno == EINTR);
+
+ if (pid) {
+ if (pid < 0) {
+ ERROR(pdlv->ls, "%s: %s (PID %d) failed: (%d) %s",
+ PD_LOG_PREFIX, "waitpid() for lvm2 cmd",
+ pdlv->cmd_pid, errno,
+ _strerror_r(errno, data));
+ goto out;
+ }
+ DEBUGLOG(pdlv->ls, "%s: %s", PD_LOG_PREFIX, "child exited");
+ break;
+ }
+ } /* while(1) */
+
+ DEBUGLOG(pdlv->ls, "%s: %s", PD_LOG_PREFIX, "about to collect remaining lines");
+ if (fds[0].fd >= 0)
+ while (read_single_line(data, 0)) {
+ assert(r > 0);
+ INFO(pdlv->ls, "%s: PID %d: %s: %s", LVM2_LOG_PREFIX, pdlv->cmd_pid, "STDOUT", data->line);
+ }
+ if (fds[1].fd >= 0)
+ while (read_single_line(data, 1)) {
+ assert(r > 0);
+ INFO(pdlv->ls, "%s: PID %d: %s: %s", LVM2_LOG_PREFIX, pdlv->cmd_pid, "STDERR", data->line);
+ }
+
+ if (WIFEXITED(ch_stat)) {
+ INFO(pdlv->ls, "%s: %s (PID %d) %s (%d)", PD_LOG_PREFIX,
+ "lvm2 cmd", pdlv->cmd_pid, "exited with", WEXITSTATUS(ch_stat));
+ cmd_state.retcode = WEXITSTATUS(ch_stat);
+ } else if (WIFSIGNALED(ch_stat)) {
+ WARN(pdlv->ls, "%s: %s (PID %d) %s (%d)", PD_LOG_PREFIX,
+ "lvm2 cmd", pdlv->cmd_pid, "got terminated by signal",
+ WTERMSIG(ch_stat));
+ cmd_state.signal = WTERMSIG(ch_stat);
+ }
+
+ err = 0;
+out:
+ if (!err)
+ pdlv_set_cmd_state(pdlv, &cmd_state);
+
+ return err;
+}
+
+static void debug_print(struct lvmpolld_state *ls, const char * const* ptr)
+{
+ const char * const* tmp = ptr;
+
+ if (!tmp)
+ return;
+
+ while (*tmp) {
+ DEBUGLOG(ls, "%s: %s", PD_LOG_PREFIX, *tmp);
+ tmp++;
+ }
+}
+
+static void *fork_and_poll(void *args)
+{
+ int outfd, errfd, state;
+ struct lvmpolld_thread_data *data;
+ pid_t r;
+
+ int error = 1;
+ struct lvmpolld_lv *pdlv = (struct lvmpolld_lv *) args;
+ struct lvmpolld_state *ls = pdlv->ls;
+
+ pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &state);
+ data = lvmpolld_thread_data_constructor(pdlv);
+ pthread_setspecific(key, data);
+ pthread_setcancelstate(state, &state);
+
+ if (!data) {
+ ERROR(ls, "%s: %s", PD_LOG_PREFIX, "Failed to initialize per-thread data");
+ goto err;
+ }
+
+ DEBUGLOG(ls, "%s: %s", PD_LOG_PREFIX, "cmd line arguments:");
+ debug_print(ls, pdlv->cmdargv);
+ DEBUGLOG(ls, "%s: %s", PD_LOG_PREFIX, "---end---");
+
+ DEBUGLOG(ls, "%s: %s", PD_LOG_PREFIX, "cmd environment variables:");
+ debug_print(ls, pdlv->cmdenvp);
+ DEBUGLOG(ls, "%s: %s", PD_LOG_PREFIX, "---end---");
+
+ outfd = data->outpipe[1];
+ errfd = data->errpipe[1];
+
+ r = fork();
+ if (!r) {
+ /* child */
+ /* !!! Do not touch any posix thread primitives !!! */
+
+ if ((dup2(outfd, STDOUT_FILENO ) != STDOUT_FILENO) ||
+ (dup2(errfd, STDERR_FILENO ) != STDERR_FILENO))
+ _exit(100);
+
+ execve(*(pdlv->cmdargv), (char *const *)pdlv->cmdargv, (char *const *)pdlv->cmdenvp);
+
+ _exit(101);
+ } else {
+ /* parent */
+ if (r == -1) {
+ ERROR(ls, "%s: %s: (%d) %s", PD_LOG_PREFIX, "fork failed",
+ errno, _strerror_r(errno, data));
+ goto err;
+ }
+
+ INFO(ls, "%s: LVM2 cmd \"%s\" (PID: %d)", PD_LOG_PREFIX, *(pdlv->cmdargv), r);
+
+ pdlv->cmd_pid = r;
+
+ /* failure to close write end of any pipe will result in broken polling */
+ if (close(data->outpipe[1])) {
+ ERROR(ls, "%s: %s: (%d) %s", PD_LOG_PREFIX, "failed to close write end of pipe",
+ errno, _strerror_r(errno, data));
+ goto err;
+ }
+ data->outpipe[1] = -1;
+
+ if (close(data->errpipe[1])) {
+ ERROR(ls, "%s: %s: (%d) %s", PD_LOG_PREFIX, "failed to close write end of err pipe",
+ errno, _strerror_r(errno, data));
+ goto err;
+ }
+ data->errpipe[1] = -1;
+
+ error = poll_for_output(pdlv, data);
+ DEBUGLOG(ls, "%s: %s", PD_LOG_PREFIX, "polling for lvpoll output has finished");
+ }
+
+err:
+ r = 0;
+
+ pdst_lock(pdlv->pdst);
+
+ if (error) {
+ /* last reader is responsible for pdlv cleanup */
+ r = pdlv->cmd_pid;
+ pdlv_set_error(pdlv, 1);
+ }
+
+ pdlv_set_polling_finished(pdlv, 1);
+ if (data)
+ data->pdlv = NULL;
+
+ pdst_locked_dec(pdlv->pdst);
+
+ pdst_unlock(pdlv->pdst);
+
+ pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &state);
+ lvmpolld_thread_data_destroy(data);
+ pthread_setspecific(key, NULL);
+ pthread_setcancelstate(state, &state);
+
+ update_idle_state(ls);
+
+ /*
+ * This is unfortunate case where we
+ * know nothing about state of lvm cmd and
+ * (eventually) ongoing progress.
+ *
+ * harvest zombies
+ */
+ if (r)
+ while(waitpid(r, NULL, 0) < 0 && errno == EINTR);
+
+ return NULL;
+}
+
+static response progress_info(client_handle h, struct lvmpolld_state *ls, request req)
+{
+ char *id;
+ struct lvmpolld_lv *pdlv;
+ struct lvmpolld_store *pdst;
+ struct lvmpolld_lv_state st;
+ response r;
+ const char *lvid = daemon_request_str(req, LVMPD_PARM_LVID, NULL);
+ const char *sysdir = daemon_request_str(req, LVMPD_PARM_SYSDIR, NULL);
+ unsigned abort_polling = daemon_request_int(req, LVMPD_PARM_ABORT, 0);
+
+ if (!lvid)
+ return reply(LVMPD_RESP_FAILED, REASON_MISSING_LVID);
+
+ id = construct_id(sysdir, lvid);
+ if (!id) {
+ ERROR(ls, "%s: %s", PD_LOG_PREFIX, "progress_info request failed to construct ID.");
+ return reply(LVMPD_RESP_FAILED, REASON_ENOMEM);
+ }
+
+ DEBUGLOG(ls, "%s: %s: %s", PD_LOG_PREFIX, "ID", id);
+
+ pdst = abort_polling ? ls->id_to_pdlv_abort : ls->id_to_pdlv_poll;
+
+ pdst_lock(pdst);
+
+ pdlv = pdst_locked_lookup(pdst, id);
+ if (pdlv) {
+ /*
+ * with store lock held, I'm the only reader accessing the pdlv
+ */
+ st = pdlv_get_status(pdlv);
+
+ if (st.error || st.polling_finished) {
+ INFO(ls, "%s: %s %s", PD_LOG_PREFIX,
+ "Polling finished. Removing related data structure for LV",
+ lvid);
+ pdst_locked_remove(pdst, id);
+ pdlv_destroy(pdlv);
+ }
+ }
+ /* pdlv must not be dereferenced from now on */
+
+ pdst_unlock(pdst);
+
+ dm_free(id);
+
+ if (pdlv) {
+ if (st.error)
+ return reply(LVMPD_RESP_FAILED, REASON_POLLING_FAILED);
+
+ if (st.polling_finished)
+ r = daemon_reply_simple(LVMPD_RESP_FINISHED,
+ "reason = %s", st.cmd_state.signal ? LVMPD_REAS_SIGNAL : LVMPD_REAS_RETCODE,
+ LVMPD_PARM_VALUE " = %d", st.cmd_state.signal ?: st.cmd_state.retcode,
+ NULL);
+ else
+ r = daemon_reply_simple(LVMPD_RESP_IN_PROGRESS, NULL);
+ }
+ else
+ r = daemon_reply_simple(LVMPD_RESP_NOT_FOUND, NULL);
+
+ return r;
+}
+
+static struct lvmpolld_lv *construct_pdlv(request req, struct lvmpolld_state *ls,
+ struct lvmpolld_store *pdst,
+ const char *interval, const char *id,
+ const char *vgname, const char *lvname,
+ const char *sysdir, enum poll_type type,
+ unsigned abort_polling, unsigned uinterval)
+{
+ const char **cmdargv, **cmdenvp;
+ struct lvmpolld_lv *pdlv;
+ unsigned handle_missing_pvs = daemon_request_int(req, LVMPD_PARM_HANDLE_MISSING_PVS, 0);
+
+ pdlv = pdlv_create(ls, id, vgname, lvname, sysdir, type,
+ interval, uinterval, pdst);
+
+ if (!pdlv) {
+ ERROR(ls, "%s: %s", PD_LOG_PREFIX, "failed to create internal LV data structure.");
+ return NULL;
+ }
+
+ cmdargv = cmdargv_ctr(pdlv, pdlv->ls->lvm_binary, abort_polling, handle_missing_pvs);
+ if (!cmdargv) {
+ pdlv_destroy(pdlv);
+ ERROR(ls, "%s: %s", PD_LOG_PREFIX, "failed to construct cmd arguments for lvpoll command");
+ return NULL;
+ }
+
+ cmdenvp = cmdenvp_ctr(pdlv);
+ if (!cmdenvp) {
+ pdlv_destroy(pdlv);
+ ERROR(ls, "%s: %s", PD_LOG_PREFIX, "failed to construct cmd environment for lvpoll command");
+ return NULL;
+ }
+
+ pdlv->cmdargv = cmdargv;
+ pdlv->cmdenvp = cmdenvp;
+
+ return pdlv;
+}
+
+static int spawn_detached_thread(struct lvmpolld_lv *pdlv)
+{
+ int r;
+ pthread_attr_t attr;
+
+ pthread_attr_init(&attr);
+ pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
+
+ r = pthread_create(&pdlv->tid, &attr, fork_and_poll, (void *)pdlv);
+
+ pthread_attr_destroy(&attr);
+
+ return !r;
+}
+
+static response poll_init(client_handle h, struct lvmpolld_state *ls, request req, enum poll_type type)
+{
+ char *id;
+ struct lvmpolld_lv *pdlv;
+ struct lvmpolld_store *pdst;
+ unsigned uinterval;
+
+ const char *interval = daemon_request_str(req, LVMPD_PARM_INTERVAL, NULL);
+ const char *lvid = daemon_request_str(req, LVMPD_PARM_LVID, NULL);
+ const char *lvname = daemon_request_str(req, LVMPD_PARM_LVNAME, NULL);
+ const char *vgname = daemon_request_str(req, LVMPD_PARM_VGNAME, NULL);
+ const char *sysdir = daemon_request_str(req, LVMPD_PARM_SYSDIR, NULL);
+ unsigned abort_polling = daemon_request_int(req, LVMPD_PARM_ABORT, 0);
+
+ assert(type < POLL_TYPE_MAX);
+
+ if (abort_polling && type != PVMOVE)
+ return reply(LVMPD_RESP_EINVAL, REASON_ILLEGAL_ABORT_REQUEST);
+
+ if (!interval || strpbrk(interval, "-") || sscanf(interval, "%u", &uinterval) != 1)
+ return reply(LVMPD_RESP_EINVAL, REASON_INVALID_INTERVAL);
+
+ if (!lvname)
+ return reply(LVMPD_RESP_FAILED, REASON_MISSING_LVNAME);
+
+ if (!lvid)
+ return reply(LVMPD_RESP_FAILED, REASON_MISSING_LVID);
+
+ if (!vgname)
+ return reply(LVMPD_RESP_FAILED, REASON_MISSING_VGNAME);
+
+ id = construct_id(sysdir, lvid);
+ if (!id) {
+ ERROR(ls, "%s: %s", PD_LOG_PREFIX, "poll_init request failed to construct ID.");
+ return reply(LVMPD_RESP_FAILED, REASON_ENOMEM);
+ }
+
+ DEBUGLOG(ls, "%s: %s=%s", PD_LOG_PREFIX, "ID", id);
+
+ pdst = abort_polling ? ls->id_to_pdlv_abort : ls->id_to_pdlv_poll;
+
+ pdst_lock(pdst);
+
+ pdlv = pdst_locked_lookup(pdst, id);
+ if (pdlv && pdlv_get_polling_finished(pdlv)) {
+ WARN(ls, "%s: %s %s", PD_LOG_PREFIX, "Force removal of uncollected info for LV",
+ lvid);
+ /*
+ * lvmpolld has to remove uncollected results in this case.
+ * otherwise it would have to refuse request for new polling
+ * lv with same id.
+ */
+ pdst_locked_remove(pdst, id);
+ pdlv_destroy(pdlv);
+ pdlv = NULL;
+ }
+
+ if (pdlv) {
+ if (!pdlv_is_type(pdlv, type)) {
+ pdst_unlock(pdst);
+ ERROR(ls, "%s: %s '%s': expected: %s, requested: %s",
+ PD_LOG_PREFIX, "poll operation type mismatch on LV identified by",
+ id,
+ polling_op(pdlv_get_type(pdlv)), polling_op(type));
+ dm_free(id);
+ return reply(LVMPD_RESP_EINVAL,
+ REASON_DIFFERENT_OPERATION_IN_PROGRESS);
+ }
+ pdlv->init_rq_count++; /* safe. protected by store lock */
+ } else {
+ pdlv = construct_pdlv(req, ls, pdst, interval, id, vgname,
+ lvname, sysdir, type, abort_polling, 2 * uinterval);
+ if (!pdlv) {
+ pdst_unlock(pdst);
+ dm_free(id);
+ return reply(LVMPD_RESP_FAILED, REASON_ENOMEM);
+ }
+ if (!pdst_locked_insert(pdst, id, pdlv)) {
+ pdlv_destroy(pdlv);
+ pdst_unlock(pdst);
+ ERROR(ls, "%s: %s", PD_LOG_PREFIX, "couldn't store internal LV data structure");
+ dm_free(id);
+ return reply(LVMPD_RESP_FAILED, REASON_ENOMEM);
+ }
+ if (!spawn_detached_thread(pdlv)) {
+ ERROR(ls, "%s: %s", PD_LOG_PREFIX, "failed to spawn detached monitoring thread");
+ pdst_locked_remove(pdst, id);
+ pdlv_destroy(pdlv);
+ pdst_unlock(pdst);
+ dm_free(id);
+ return reply(LVMPD_RESP_FAILED, REASON_ENOMEM);
+ }
+
+ pdst_locked_inc(pdst);
+ if (ls->idle)
+ ls->idle->is_idle = 0;
+ }
+
+ pdst_unlock(pdst);
+
+ dm_free(id);
+
+ return daemon_reply_simple(LVMPD_RESP_OK, NULL);
+}
+
+static response dump_state(client_handle h, struct lvmpolld_state *ls, request r)
+{
+ response res = { 0 };
+ struct buffer *b = &res.buffer;
+
+ buffer_init(b);
+
+ lvmpolld_global_lock(ls);
+
+ buffer_append(b, "# Registered polling operations\n\n");
+ buffer_append(b, "poll {\n");
+ pdst_locked_dump(ls->id_to_pdlv_poll, b);
+ buffer_append(b, "}\n\n");
+
+ buffer_append(b, "# Registered abort operations\n\n");
+ buffer_append(b, "abort {\n");
+ pdst_locked_dump(ls->id_to_pdlv_abort, b);
+ buffer_append(b, "}\n\n");
+
+ lvmpolld_global_unlock(ls);
+
+ return res;
+}
+
+static response handler(struct daemon_state s, client_handle h, request r)
+{
+ struct lvmpolld_state *ls = s.private;
+ const char *rq = daemon_request_str(r, "request", "NONE");
+
+ if (!strcmp(rq, LVMPD_REQ_PVMOVE))
+ return poll_init(h, ls, r, PVMOVE);
+ else if (!strcmp(rq, LVMPD_REQ_CONVERT))
+ return poll_init(h, ls, r, CONVERT);
+ else if (!strcmp(rq, LVMPD_REQ_MERGE))
+ return poll_init(h, ls, r, MERGE);
+ else if (!strcmp(rq, LVMPD_REQ_MERGE_THIN))
+ return poll_init(h, ls, r, MERGE_THIN);
+ else if (!strcmp(rq, LVMPD_REQ_PROGRESS))
+ return progress_info(h, ls, r);
+ else if (!strcmp(rq, LVMPD_REQ_DUMP))
+ return dump_state(h, ls, r);
+ else
+ return reply(LVMPD_RESP_EINVAL, REASON_REQ_NOT_IMPLEMENTED);
+}
+
+static int process_timeout_arg(const char *str, unsigned *max_timeouts)
+{
+ char *endptr;
+ unsigned long l;
+
+ l = strtoul(str, &endptr, 10);
+ if (errno || *endptr || l >= UINT_MAX)
+ return 0;
+
+ *max_timeouts = (unsigned) l;
+
+ return 1;
+}
+
+int main(int argc, char *argv[])
+{
+ signed char opt;
+ struct timeval timeout;
+ daemon_idle di = { .ptimeout = &timeout };
+ struct lvmpolld_state ls = { .log_config = "" };
+ daemon_state s = {
+ .daemon_fini = fini,
+ .daemon_init = init,
+ .handler = handler,
+ .name = "lvmpolld",
+ .pidfile = getenv("LVM_LVMPOLLD_PIDFILE") ?: LVMPOLLD_PIDFILE,
+ .private = &ls,
+ .protocol = LVMPOLLD_PROTOCOL,
+ .protocol_version = LVMPOLLD_PROTOCOL_VERSION,
+ .socket_path = getenv("LVM_LVMPOLLD_SOCKET") ?: LVMPOLLD_SOCKET,
+ };
+
+ while ((opt = getopt(argc, argv, "?fhVl:p:s:B:t:")) != EOF) {
+ switch (opt) {
+ case '?':
+ usage(argv[0], stderr);
+ exit(0);
+ case 'B': /* --binary */
+ ls.lvm_binary = optarg;
+ break;
+ case 'V':
+ printf("lvmpolld version: " LVM_VERSION "\n");
+ exit(1);
+ case 'f':
+ s.foreground = 1;
+ break;
+ case 'h':
+ usage(argv[0], stdout);
+ exit(0);
+ case 'l':
+ ls.log_config = optarg;
+ break;
+ case 'p':
+ s.pidfile = optarg;
+ break;
+ case 's': /* --socket */
+ s.socket_path = optarg;
+ break;
+ case 't': /* --timeout in seconds */
+ if (!process_timeout_arg(optarg, &di.max_timeouts)) {
+ fprintf(stderr, "Invalid value of timeout parameter");
+ exit(1);
+ }
+ /* 0 equals to wait indefinitely */
+ if (di.max_timeouts)
+ s.idle = ls.idle = &di;
+ break;
+ }
+ }
+
+ daemon_start(s);
+
+ return 0;
+}
diff --git a/daemons/lvmpolld/lvmpolld-data-utils.c b/daemons/lvmpolld/lvmpolld-data-utils.c
new file mode 100644
index 0000000..92147df
--- /dev/null
+++ b/daemons/lvmpolld/lvmpolld-data-utils.c
@@ -0,0 +1,388 @@
+/*
+ * Copyright (C) 2014-2015 Red Hat, Inc.
+ *
+ * This file is part of LVM2.
+ *
+ * This copyrighted material is made available to anyone wishing to use,
+ * modify, copy, or redistribute it subject to the terms and conditions
+ * of the GNU Lesser General Public License v.2.1.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include "lvmpolld-common.h"
+
+#include "config-util.h"
+
+#include <fcntl.h>
+#include <signal.h>
+
+static char *_construct_full_lvname(const char *vgname, const char *lvname)
+{
+ char *name;
+ size_t l;
+
+ l = strlen(vgname) + strlen(lvname) + 2; /* vg/lv and \0 */
+ name = (char *) dm_malloc(l * sizeof(char));
+ if (!name)
+ return NULL;
+
+ if (dm_snprintf(name, l, "%s/%s", vgname, lvname) < 0) {
+ dm_free(name);
+ name = NULL;
+ }
+
+ return name;
+}
+
+static char *_construct_lvm_system_dir_env(const char *sysdir)
+{
+ /*
+ * Store either "LVM_SYSTEM_DIR=/path/to..."
+ * - or -
+ * just single char to store NULL byte
+ */
+ size_t l = sysdir ? strlen(sysdir) + 16 : 1;
+ char *env = (char *) dm_malloc(l * sizeof(char));
+
+ if (!env)
+ return NULL;
+
+ *env = '\0';
+
+ if (sysdir && dm_snprintf(env, l, "LVM_SYSTEM_DIR=%s", sysdir) < 0) {
+ dm_free(env);
+ env = NULL;
+ }
+
+ return env;
+}
+
+static const char *_get_lvid(const char *lvmpolld_id, const char *sysdir)
+{
+ return lvmpolld_id ? (lvmpolld_id + (sysdir ? strlen(sysdir) : 0)) : NULL;
+}
+
+char *construct_id(const char *sysdir, const char *uuid)
+{
+ char *id;
+ int r;
+ size_t l;
+
+ l = strlen(uuid) + (sysdir ? strlen(sysdir) : 0) + 1;
+ id = (char *) dm_malloc(l * sizeof(char));
+ if (!id)
+ return NULL;
+
+ r = sysdir ? dm_snprintf(id, l, "%s%s", sysdir, uuid) :
+ dm_snprintf(id, l, "%s", uuid);
+
+ if (r < 0) {
+ dm_free(id);
+ id = NULL;
+ }
+
+ return id;
+}
+
+struct lvmpolld_lv *pdlv_create(struct lvmpolld_state *ls, const char *id,
+ const char *vgname, const char *lvname,
+ const char *sysdir, enum poll_type type,
+ const char *sinterval, unsigned pdtimeout,
+ struct lvmpolld_store *pdst)
+{
+ char *lvmpolld_id = dm_strdup(id), /* copy */
+ *full_lvname = _construct_full_lvname(vgname, lvname), /* copy */
+ *lvm_system_dir_env = _construct_lvm_system_dir_env(sysdir); /* copy */
+
+ struct lvmpolld_lv tmp = {
+ .ls = ls,
+ .type = type,
+ .lvmpolld_id = lvmpolld_id,
+ .lvid = _get_lvid(lvmpolld_id, sysdir),
+ .lvname = full_lvname,
+ .lvm_system_dir_env = lvm_system_dir_env,
+ .sinterval = dm_strdup(sinterval), /* copy */
+ .pdtimeout = pdtimeout < MIN_POLLING_TIMEOUT ? MIN_POLLING_TIMEOUT : pdtimeout,
+ .cmd_state = { .retcode = -1, .signal = 0 },
+ .pdst = pdst,
+ .init_rq_count = 1
+ }, *pdlv = (struct lvmpolld_lv *) dm_malloc(sizeof(struct lvmpolld_lv));
+
+ if (!pdlv || !tmp.lvid || !tmp.lvname || !tmp.lvm_system_dir_env || !tmp.sinterval)
+ goto err;
+
+ memcpy(pdlv, &tmp, sizeof(*pdlv));
+
+ if (pthread_mutex_init(&pdlv->lock, NULL))
+ goto err;
+
+ return pdlv;
+
+err:
+ dm_free((void *)full_lvname);
+ dm_free((void *)lvmpolld_id);
+ dm_free((void *)lvm_system_dir_env);
+ dm_free((void *)tmp.sinterval);
+ dm_free((void *)pdlv);
+
+ return NULL;
+}
+
+void pdlv_destroy(struct lvmpolld_lv *pdlv)
+{
+ dm_free((void *)pdlv->lvmpolld_id);
+ dm_free((void *)pdlv->lvname);
+ dm_free((void *)pdlv->sinterval);
+ dm_free((void *)pdlv->lvm_system_dir_env);
+ dm_free((void *)pdlv->cmdargv);
+ dm_free((void *)pdlv->cmdenvp);
+
+ pthread_mutex_destroy(&pdlv->lock);
+
+ dm_free((void *)pdlv);
+}
+
+unsigned pdlv_get_polling_finished(struct lvmpolld_lv *pdlv)
+{
+ unsigned ret;
+
+ pdlv_lock(pdlv);
+ ret = pdlv->polling_finished;
+ pdlv_unlock(pdlv);
+
+ return ret;
+}
+
+struct lvmpolld_lv_state pdlv_get_status(struct lvmpolld_lv *pdlv)
+{
+ struct lvmpolld_lv_state r;
+
+ pdlv_lock(pdlv);
+ r.error = pdlv_locked_error(pdlv);
+ r.polling_finished = pdlv_locked_polling_finished(pdlv);
+ r.cmd_state = pdlv_locked_cmd_state(pdlv);
+ pdlv_unlock(pdlv);
+
+ return r;
+}
+
+void pdlv_set_cmd_state(struct lvmpolld_lv *pdlv, const struct lvmpolld_cmd_stat *cmd_state)
+{
+ pdlv_lock(pdlv);
+ pdlv->cmd_state = *cmd_state;
+ pdlv_unlock(pdlv);
+}
+
+void pdlv_set_error(struct lvmpolld_lv *pdlv, unsigned error)
+{
+ pdlv_lock(pdlv);
+ pdlv->error = error;
+ pdlv_unlock(pdlv);
+}
+
+void pdlv_set_polling_finished(struct lvmpolld_lv *pdlv, unsigned finished)
+{
+ pdlv_lock(pdlv);
+ pdlv->polling_finished = finished;
+ pdlv_unlock(pdlv);
+}
+
+struct lvmpolld_store *pdst_init(const char *name)
+{
+ struct lvmpolld_store *pdst = (struct lvmpolld_store *) dm_malloc(sizeof(struct lvmpolld_store));
+ if (!pdst)
+ return NULL;
+
+ pdst->store = dm_hash_create(32);
+ if (!pdst->store)
+ goto err_hash;
+ if (pthread_mutex_init(&pdst->lock, NULL))
+ goto err_mutex;
+
+ pdst->name = name;
+
+ return pdst;
+
+err_mutex:
+ dm_hash_destroy(pdst->store);
+err_hash:
+ dm_free(pdst);
+ return NULL;
+}
+
+void pdst_destroy(struct lvmpolld_store *pdst)
+{
+ if (!pdst)
+ return;
+
+ dm_hash_destroy(pdst->store);
+ pthread_mutex_destroy(&pdst->lock);
+ dm_free(pdst);
+}
+
+void pdst_locked_lock_all_pdlvs(const struct lvmpolld_store *pdst)
+{
+ struct dm_hash_node *n;
+
+ dm_hash_iterate(n, pdst->store)
+ pdlv_lock(dm_hash_get_data(pdst->store, n));
+}
+
+void pdst_locked_unlock_all_pdlvs(const struct lvmpolld_store *pdst)
+{
+ struct dm_hash_node *n;
+
+ dm_hash_iterate(n, pdst->store)
+ pdlv_unlock(dm_hash_get_data(pdst->store, n));
+}
+
+static void _pdlv_locked_dump(struct buffer *buff, const struct lvmpolld_lv *pdlv)
+{
+ char tmp[1024];
+ const struct lvmpolld_cmd_stat *cmd_state = &pdlv->cmd_state;
+
+ /* pdlv-section { */
+ if (dm_snprintf(tmp, sizeof(tmp), "\t%s {\n", pdlv->lvmpolld_id) > 0)
+ buffer_append(buff, tmp);
+
+ if (dm_snprintf(tmp, sizeof(tmp), "\t\tlvid=\"%s\"\n", pdlv->lvid) > 0)
+ buffer_append(buff, tmp);
+ if (dm_snprintf(tmp, sizeof(tmp), "\t\ttype=\"%s\"\n", polling_op(pdlv->type)) > 0)
+ buffer_append(buff, tmp);
+ if (dm_snprintf(tmp, sizeof(tmp), "\t\tlvname=\"%s\"\n", pdlv->lvname) > 0)
+ buffer_append(buff, tmp);
+ if (dm_snprintf(tmp, sizeof(tmp), "\t\tlvmpolld_internal_timeout=%d\n", pdlv->pdtimeout) > 0)
+ buffer_append(buff, tmp);
+ if (dm_snprintf(tmp, sizeof(tmp), "\t\tlvm_command_interval=\"%s\"\n", pdlv->sinterval ?: "<undefined>") > 0)
+ buffer_append(buff, tmp);
+ if (dm_snprintf(tmp, sizeof(tmp), "\t\tLVM_SYSTEM_DIR=\"%s\"\n",
+ (*pdlv->lvm_system_dir_env ? (pdlv->lvm_system_dir_env + strlen("LVM_SYSTEM_DIR=")) : "<undefined>")) > 0)
+ buffer_append(buff, tmp);
+ if (dm_snprintf(tmp, sizeof(tmp), "\t\tlvm_command_pid=%d\n", pdlv->cmd_pid) > 0)
+ buffer_append(buff, tmp);
+ if (dm_snprintf(tmp, sizeof(tmp), "\t\tpolling_finished=%d\n", pdlv->polling_finished) > 0)
+ buffer_append(buff, tmp);
+ if (dm_snprintf(tmp, sizeof(tmp), "\t\terror_occured=%d\n", pdlv->error) > 0)
+ buffer_append(buff, tmp);
+ if (dm_snprintf(tmp, sizeof(tmp), "\t\tinit_requests_count=%d\n", pdlv->init_rq_count) > 0)
+ buffer_append(buff, tmp);
+
+ /* lvm_commmand-section { */
+ buffer_append(buff, "\t\tlvm_command {\n");
+ if (cmd_state->retcode == -1 && !cmd_state->signal)
+ buffer_append(buff, "\t\t\tstate=\"" LVMPD_RESP_IN_PROGRESS "\"\n");
+ else {
+ buffer_append(buff, "\t\t\tstate=\"" LVMPD_RESP_FINISHED "\"\n");
+ if (dm_snprintf(tmp, sizeof(tmp), "\t\t\treason=\"%s\"\n\t\t\tvalue=%d\n",
+ (cmd_state->signal ? LVMPD_REAS_SIGNAL : LVMPD_REAS_RETCODE),
+ (cmd_state->signal ?: cmd_state->retcode)) > 0)
+ buffer_append(buff, tmp);
+ }
+ buffer_append(buff, "\t\t}\n");
+ /* } lvm_commmand-section */
+
+ buffer_append(buff, "\t}\n");
+ /* } pdlv-section */
+}
+
+void pdst_locked_dump(const struct lvmpolld_store *pdst, struct buffer *buff)
+{
+ struct dm_hash_node *n;
+
+ dm_hash_iterate(n, pdst->store)
+ _pdlv_locked_dump(buff, dm_hash_get_data(pdst->store, n));
+}
+
+void pdst_locked_send_cancel(const struct lvmpolld_store *pdst)
+{
+ struct lvmpolld_lv *pdlv;
+ struct dm_hash_node *n;
+
+ dm_hash_iterate(n, pdst->store) {
+ pdlv = dm_hash_get_data(pdst->store, n);
+ if (!pdlv_locked_polling_finished(pdlv))
+ pthread_cancel(pdlv->tid);
+ }
+}
+
+void pdst_locked_destroy_all_pdlvs(const struct lvmpolld_store *pdst)
+{
+ struct dm_hash_node *n;
+
+ dm_hash_iterate(n, pdst->store)
+ pdlv_destroy(dm_hash_get_data(pdst->store, n));
+}
+
+struct lvmpolld_thread_data *lvmpolld_thread_data_constructor(struct lvmpolld_lv *pdlv)
+{
+ struct lvmpolld_thread_data *data = (struct lvmpolld_thread_data *) dm_malloc(sizeof(struct lvmpolld_thread_data));
+ if (!data)
+ return NULL;
+
+ data->pdlv = NULL;
+ data->line = NULL;
+ data->fout = data->ferr = NULL;
+ data->outpipe[0] = data->outpipe[1] = data->errpipe[0] = data->errpipe[1] = -1;
+
+ if (pipe(data->outpipe) || pipe(data->errpipe)) {
+ lvmpolld_thread_data_destroy(data);
+ return NULL;
+ }
+
+ if (fcntl(data->outpipe[0], F_SETFD, FD_CLOEXEC) ||
+ fcntl(data->outpipe[1], F_SETFD, FD_CLOEXEC) ||
+ fcntl(data->errpipe[0], F_SETFD, FD_CLOEXEC) ||
+ fcntl(data->errpipe[1], F_SETFD, FD_CLOEXEC)) {
+ lvmpolld_thread_data_destroy(data);
+ return NULL;
+ }
+
+ data->pdlv = pdlv;
+
+ return data;
+}
+
+void lvmpolld_thread_data_destroy(void *thread_private)
+{
+ struct lvmpolld_thread_data *data = (struct lvmpolld_thread_data *) thread_private;
+ if (!data)
+ return;
+
+ if (data->pdlv) {
+ pdst_lock(data->pdlv->pdst);
+ /*
+ * FIXME: skip this step if lvmpolld is activated
+ * by systemd.
+ */
+ if (!pdlv_get_polling_finished(data->pdlv))
+ kill(data->pdlv->cmd_pid, SIGTERM);
+ pdlv_set_polling_finished(data->pdlv, 1);
+ pdst_locked_dec(data->pdlv->pdst);
+ pdst_unlock(data->pdlv->pdst);
+ }
+
+ dm_free(data->line);
+
+ if (data->fout && !fclose(data->fout))
+ data->outpipe[0] = -1;
+
+ if (data->ferr && !fclose(data->ferr))
+ data->errpipe[0] = -1;
+
+ if (data->outpipe[0] >= 0)
+ close(data->outpipe[0]);
+
+ if (data->outpipe[1] >= 0)
+ close(data->outpipe[1]);
+
+ if (data->errpipe[0] >= 0)
+ close(data->errpipe[0]);
+
+ if (data->errpipe[1] >= 0)
+ close(data->errpipe[1]);
+
+ dm_free(data);
+}
diff --git a/daemons/lvmpolld/lvmpolld-data-utils.h b/daemons/lvmpolld/lvmpolld-data-utils.h
new file mode 100644
index 0000000..e3bede1
--- /dev/null
+++ b/daemons/lvmpolld/lvmpolld-data-utils.h
@@ -0,0 +1,215 @@
+/*
+ * Copyright (C) 2014-2015 Red Hat, Inc.
+ *
+ * This file is part of LVM2.
+ *
+ * This copyrighted material is made available to anyone wishing to use,
+ * modify, copy, or redistribute it subject to the terms and conditions
+ * of the GNU Lesser General Public License v.2.1.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef _LVM_LVMPOLLD_DATA_UTILS_H
+#define _LVM_LVMPOLLD_DATA_UTILS_H
+
+#include <pthread.h>
+
+struct buffer;
+struct lvmpolld_state;
+
+enum poll_type {
+ PVMOVE = 0,
+ CONVERT,
+ MERGE,
+ MERGE_THIN,
+ POLL_TYPE_MAX
+};
+
+struct lvmpolld_cmd_stat {
+ int retcode;
+ int signal;
+};
+
+struct lvmpolld_store {
+ pthread_mutex_t lock;
+ void *store;
+ const char *name;
+ unsigned active_polling_count;
+};
+
+struct lvmpolld_lv {
+ /*
+ * accessing following vars doesn't
+ * require struct lvmpolld_lv lock
+ */
+ struct lvmpolld_state *const ls;
+ const enum poll_type type;
+ const char *const lvid;
+ const char *const lvmpolld_id;
+ const char *const lvname; /* full vg/lv name */
+ const unsigned pdtimeout; /* in seconds */
+ const char *const sinterval;
+ const char *const lvm_system_dir_env;
+ struct lvmpolld_store *const pdst;
+ const char *const *cmdargv;
+ const char *const *cmdenvp;
+
+ /* only used by write */
+ pid_t cmd_pid;
+ pthread_t tid;
+
+ pthread_mutex_t lock;
+
+ /* block of shared variables protected by lock */
+ struct lvmpolld_cmd_stat cmd_state;
+ unsigned init_rq_count; /* for debuging purposes only */
+ unsigned polling_finished:1; /* no more updates */
+ unsigned error:1; /* unrecoverable error occured in lvmpolld */
+};
+
+typedef void (*lvmpolld_parse_output_fn_t) (struct lvmpolld_lv *pdlv, const char *line);
+
+/* TODO: replace with configuration option */
+#define MIN_POLLING_TIMEOUT 60
+
+struct lvmpolld_lv_state {
+ unsigned error:1;
+ unsigned polling_finished:1;
+ struct lvmpolld_cmd_stat cmd_state;
+};
+
+struct lvmpolld_thread_data {
+ char *line;
+ size_t line_size;
+ int outpipe[2];
+ int errpipe[2];
+ FILE *fout;
+ FILE *ferr;
+ char buf[1024];
+ struct lvmpolld_lv *pdlv;
+};
+
+char *construct_id(const char *sysdir, const char *lvid);
+
+/* LVMPOLLD_LV_T section */
+
+/* only call with appropriate struct lvmpolld_store lock held */
+struct lvmpolld_lv *pdlv_create(struct lvmpolld_state *ls, const char *id,
+ const char *vgname, const char *lvname,
+ const char *sysdir, enum poll_type type,
+ const char *sinterval, unsigned pdtimeout,
+ struct lvmpolld_store *pdst);
+
+/* only call with appropriate struct lvmpolld_store lock held */
+void pdlv_destroy(struct lvmpolld_lv *pdlv);
+
+static inline void pdlv_lock(struct lvmpolld_lv *pdlv)
+{
+ pthread_mutex_lock(&pdlv->lock);
+}
+
+static inline void pdlv_unlock(struct lvmpolld_lv *pdlv)
+{
+ pthread_mutex_unlock(&pdlv->lock);
+}
+
+/*
+ * no struct lvmpolld_lv lock required section
+ */
+static inline int pdlv_is_type(const struct lvmpolld_lv *pdlv, enum poll_type type)
+{
+ return pdlv->type == type;
+}
+
+static inline unsigned pdlv_get_timeout(const struct lvmpolld_lv *pdlv)
+{
+ return pdlv->pdtimeout;
+}
+
+static inline enum poll_type pdlv_get_type(const struct lvmpolld_lv *pdlv)
+{
+ return pdlv->type;
+}
+
+unsigned pdlv_get_polling_finished(struct lvmpolld_lv *pdlv);
+struct lvmpolld_lv_state pdlv_get_status(struct lvmpolld_lv *pdlv);
+void pdlv_set_cmd_state(struct lvmpolld_lv *pdlv, const struct lvmpolld_cmd_stat *cmd_state);
+void pdlv_set_error(struct lvmpolld_lv *pdlv, unsigned error);
+void pdlv_set_polling_finished(struct lvmpolld_lv *pdlv, unsigned finished);
+
+/*
+ * struct lvmpolld_lv lock required section
+ */
+static inline struct lvmpolld_cmd_stat pdlv_locked_cmd_state(const struct lvmpolld_lv *pdlv)
+{
+ return pdlv->cmd_state;
+}
+
+static inline int pdlv_locked_polling_finished(const struct lvmpolld_lv *pdlv)
+{
+ return pdlv->polling_finished;
+}
+
+static inline unsigned pdlv_locked_error(const struct lvmpolld_lv *pdlv)
+{
+ return pdlv->error;
+}
+
+/* struct lvmpolld_store manipulation routines */
+
+struct lvmpolld_store *pdst_init(const char *name);
+void pdst_destroy(struct lvmpolld_store *pdst);
+
+void pdst_locked_dump(const struct lvmpolld_store *pdst, struct buffer *buff);
+void pdst_locked_lock_all_pdlvs(const struct lvmpolld_store *pdst);
+void pdst_locked_unlock_all_pdlvs(const struct lvmpolld_store *pdst);
+void pdst_locked_destroy_all_pdlvs(const struct lvmpolld_store *pdst);
+void pdst_locked_send_cancel(const struct lvmpolld_store *pdst);
+
+static inline void pdst_lock(struct lvmpolld_store *pdst)
+{
+ pthread_mutex_lock(&pdst->lock);
+}
+
+static inline void pdst_unlock(struct lvmpolld_store *pdst)
+{
+ pthread_mutex_unlock(&pdst->lock);
+}
+
+static inline void pdst_locked_inc(struct lvmpolld_store *pdst)
+{
+ pdst->active_polling_count++;
+}
+
+static inline void pdst_locked_dec(struct lvmpolld_store *pdst)
+{
+ pdst->active_polling_count--;
+}
+
+static inline unsigned pdst_locked_get_active_count(const struct lvmpolld_store *pdst)
+{
+ return pdst->active_polling_count;
+}
+
+static inline int pdst_locked_insert(struct lvmpolld_store *pdst, const char *key, struct lvmpolld_lv *pdlv)
+{
+ return dm_hash_insert(pdst->store, key, pdlv);
+}
+
+static inline struct lvmpolld_lv *pdst_locked_lookup(struct lvmpolld_store *pdst, const char *key)
+{
+ return dm_hash_lookup(pdst->store, key);
+}
+
+static inline void pdst_locked_remove(struct lvmpolld_store *pdst, const char *key)
+{
+ dm_hash_remove(pdst->store, key);
+}
+
+struct lvmpolld_thread_data *lvmpolld_thread_data_constructor(struct lvmpolld_lv *pdlv);
+void lvmpolld_thread_data_destroy(void *thread_private);
+
+#endif /* _LVM_LVMPOLLD_DATA_UTILS_H */
diff --git a/daemons/lvmpolld/lvmpolld-protocol.h b/daemons/lvmpolld/lvmpolld-protocol.h
new file mode 100644
index 0000000..7d9821b
--- /dev/null
+++ b/daemons/lvmpolld/lvmpolld-protocol.h
@@ -0,0 +1,49 @@
+/*
+ * Copyright (C) 2015 Red Hat, Inc.
+ *
+ * This file is part of LVM2.
+ *
+ * This copyrighted material is made available to anyone wishing to use,
+ * modify, copy, or redistribute it subject to the terms and conditions
+ * of the GNU Lesser General Public License v.2.1.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef _LVM_LVMPOLLD_PROTOCOL_H
+#define _LVM_LVMPOLLD_PROTOCOL_H
+
+#include "polling_ops.h"
+
+#define LVMPOLLD_PROTOCOL "lvmpolld"
+#define LVMPOLLD_PROTOCOL_VERSION 1
+
+#define LVMPD_REQ_CONVERT CONVERT_POLL
+#define LVMPD_REQ_DUMP "dump"
+#define LVMPD_REQ_MERGE MERGE_POLL
+#define LVMPD_REQ_MERGE_THIN MERGE_THIN_POLL
+#define LVMPD_REQ_PROGRESS "progress_info"
+#define LVMPD_REQ_PVMOVE PVMOVE_POLL
+
+#define LVMPD_PARM_ABORT "abort"
+#define LVMPD_PARM_HANDLE_MISSING_PVS "handle_missing_pvs"
+#define LVMPD_PARM_INTERVAL "interval"
+#define LVMPD_PARM_LVID "lvid"
+#define LVMPD_PARM_LVNAME "lvname"
+#define LVMPD_PARM_SYSDIR "sysdir"
+#define LVMPD_PARM_VALUE "value" /* either retcode or signal value */
+#define LVMPD_PARM_VGNAME "vgname"
+
+#define LVMPD_RESP_FAILED "failed"
+#define LVMPD_RESP_FINISHED "finished"
+#define LVMPD_RESP_IN_PROGRESS "in_progress"
+#define LVMPD_RESP_EINVAL "invalid"
+#define LVMPD_RESP_NOT_FOUND "not_found"
+#define LVMPD_RESP_OK "OK"
+
+#define LVMPD_REAS_RETCODE "retcode" /* lvm cmd ret code */
+#define LVMPD_REAS_SIGNAL "signal" /* lvm cmd terminating singal */
+
+#endif /* _LVM_LVMPOLLD_PROTOCOL_H */
diff --git a/daemons/lvmpolld/polling_ops.h b/daemons/lvmpolld/polling_ops.h
new file mode 100644
index 0000000..9f4dd58
--- /dev/null
+++ b/daemons/lvmpolld/polling_ops.h
@@ -0,0 +1,25 @@
+/*
+ * Copyright (C) 2014-2015 Red Hat, Inc. All rights reserved.
+ *
+ * This file is part of LVM2.
+ *
+ * This copyrighted material is made available to anyone wishing to use,
+ * modify, copy, or redistribute it subject to the terms and conditions
+ * of the GNU Lesser General Public License v.2.1.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef _LVM_TOOL_POLLING_OPS_H
+#define _LVM_TOOL_POLLING_OPS_H
+
+/* this file is also part of lvmpolld protocol */
+
+#define PVMOVE_POLL "pvmove"
+#define CONVERT_POLL "convert"
+#define MERGE_POLL "merge"
+#define MERGE_THIN_POLL "merge_thin"
+
+#endif /* _LVM_TOOL_POLLING_OPS_H */
diff --git a/doc/lvmpolld_overview.txt b/doc/lvmpolld_overview.txt
new file mode 100644
index 0000000..8c66e5e
--- /dev/null
+++ b/doc/lvmpolld_overview.txt
@@ -0,0 +1,81 @@
+LVM poll daemon overview
+========================
+
+(last updated: 2015-05-09)
+
+LVM poll daemon (lvmpolld) is the alternative for lvm2 classical polling
+mechanisms. The motivation behind new lvmpolld was to create persistent
+system service that would be more durable and transparent. It's suited
+particularly for any systemd enabled distribution.
+
+Before lvmpolld any background polling process originating in a lvm2 command
+initiated inside cgroup of a systemd service could get killed if the main
+process (service) exited in such cgroup. That could lead to premature termination
+of such lvm2 polling process.
+
+Also without lvmpolld there were no means to detect a particular polling process
+suited for monitoring of specific operation is already in-progress and therefore
+it's not desirable to start next one with exactly same task. lvmpolld is able to
+detect such duplicate requests and not spawn such redundant process.
+
+lvmpolld is primarily targeted for systems with systemd as init process. For systems
+without systemd there's no need to install lvmpolld because there is no issue
+with observation described in second paragraph. You can still benefit from
+avoiding duplicate polling process being spawned, but without systemd lvmpolld
+can't easily be run on-demand (activated by a socket maintained by systemd).
+
+lvmpolld implement shutdown on idle and can shutdown automatically when idle
+for requested time. 60 second is recommended default here. This behaviour can be
+turned off if found useless.
+
+Data structures
+---------------
+
+a) Logical Volume (struct lvmpolld_lv)
+
+Each operation is identified by LV. Internal identifier within lvmpolld
+is full LV uuid (vg_uuid+lv_uuid) prefixed with LVM_SYSTEM_DIR if set by client.
+
+such full identifier may look like:
+
+ "/etc/lvm/lvm.confWFd2dU67S8Av29IcJCnYzqQirdfElnxzhCdzEh7EJrfCn9R1TIQjIj58weUZDre4"
+
+or without LVM_SYSTEM_DIR being set explicitly:
+
+ "WFd2dU67S8Av29IcJCnYzqQirdfElnxzhCdzEh7EJrfCn9R1TIQjIj58weUZDre4"
+
+
+LV carries various metadata about polling operation. The most significant are:
+
+VG name
+LV name
+polling interval (usually --interval passed to lvm2 command or default from lvm2
+ configuration)
+operation type (one of: pvmove, convert, merge, thin_merge)
+LVM_SYSTEM_DIR (if set, this is also passed among environment variables of lvpoll
+ command spawned by lvmpolld)
+
+b) LV stores (struct lvmpolld_store)
+
+lvmpolld uses two stores for Logical volumes (struct lvmpolld_lv). One store for polling
+operations in-progress. These operations are as of now: PV move, mirror up-conversion,
+classical snapshot merge, thin snapshot merge.
+
+The second store is suited only for pvmove --abort operations in-progress. Both
+stores are independent and identical LVs (pvmove /dev/sda3 and pvmove --abort /dev/sda3)
+can be run concurently from lvmpolld point of view (on lvm2 side the consistency is
+guaranteed by lvm2 locking mechanism).
+
+Locking order
+-------------
+
+There are two types of locks in lvmpolld. Each store has own store lock and each LV has
+own lv lock.
+
+Locking order is:
+1) store lock
+2) LV lock
+
+Each LV has to be inside a store. When daemon requires to take both locks it has
+to take a store lock first and LV lock has to be taken afterwards (after the
+appropriate store lock where the LV is being stored :))
diff --git a/include/.symlinks.in b/include/.symlinks.in
index 96f4a01..d6a95fd 100644
--- a/include/.symlinks.in
+++ b/include/.symlinks.in
@@ -1,6 +1,8 @@
@top_srcdir(a)/daemons/clvmd/clvm.h
@top_srcdir(a)/daemons/dmeventd/libdevmapper-event.h
@top_srcdir(a)/daemons/lvmetad/lvmetad-client.h
+@top_srcdir(a)/daemons/lvmpolld/lvmpolld-protocol.h
+@top_srcdir(a)/daemons/lvmpolld/polling_ops.h
@top_srcdir(a)/liblvm/lvm2app.h
@top_srcdir(a)/lib/activate/activate.h
@top_srcdir(a)/lib/activate/targets.h
@@ -29,6 +31,8 @@
@top_srcdir(a)/lib/locking/locking.h
@top_srcdir(a)/lib/log/log.h
@top_srcdir(a)/lib/log/lvm-logging.h
+@top_srcdir(a)/lib/lvmpolld/lvmpolld-client.h
+@top_srcdir(a)/lib/lvmpolld/polldaemon.h
@top_srcdir(a)/lib/metadata/lv.h
@top_srcdir(a)/lib/metadata/lv_alloc.h
@top_srcdir(a)/lib/metadata/metadata.h
diff --git a/lib/Makefile.in b/lib/Makefile.in
index 749342d..4a282eb 100644
--- a/lib/Makefile.in
+++ b/lib/Makefile.in
@@ -196,6 +196,11 @@ ifeq ("@BUILD_LVMETAD@", "yes")
cache/lvmetad.c
endif
+ifeq ("@BUILD_LVMPOLLD@", "yes")
+ SOURCES +=\
+ lvmpolld/lvmpolld-client.c
+endif
+
ifeq ("@DMEVENTD@", "yes")
CLDFLAGS += -L$(top_builddir)/daemons/dmeventd
LIBS += -ldevmapper-event
diff --git a/lib/commands/toolcontext.c b/lib/commands/toolcontext.c
index fb0e94d..43d878b 100644
--- a/lib/commands/toolcontext.c
+++ b/lib/commands/toolcontext.c
@@ -30,6 +30,7 @@
#include "lvmcache.h"
#include "lvmetad.h"
#include "archiver.h"
+#include "lvmpolld-client.h"
#ifdef HAVE_LIBDL
#include "sharedlib.h"
@@ -475,6 +476,7 @@ static int _process_config(struct cmd_context *cmd)
const struct dm_config_value *cv;
int64_t pv_min_kb;
const char *lvmetad_socket;
+ const char *lvmpolld_socket;
int udev_disabled = 0;
char sysfs_dir[PATH_MAX];
@@ -618,6 +620,7 @@ static int _process_config(struct cmd_context *cmd)
(find_config_tree_bool(cmd, global_detect_internal_vg_cache_corruption_CFG, NULL));
lvmetad_disconnect();
+ lvmpolld_disconnect();
lvmetad_socket = getenv("LVM_LVMETAD_SOCKET");
if (!lvmetad_socket)
@@ -644,6 +647,13 @@ static int _process_config(struct cmd_context *cmd)
if (!_init_system_id(cmd))
return_0;
+ lvmpolld_socket = getenv("LVM_LVMPOLLD_SOCKET");
+ if (!lvmpolld_socket)
+ lvmpolld_socket = DEFAULT_RUN_DIR "/lvmpolld.socket";
+ lvmpolld_set_socket(lvmpolld_socket);
+
+ lvmpolld_set_active(find_config_tree_bool(cmd, global_use_lvmpolld_CFG, NULL));
+
return 1;
}
@@ -2065,6 +2075,7 @@ void destroy_toolcontext(struct cmd_context *cmd)
lvmetad_release_token();
lvmetad_disconnect();
+ lvmpolld_disconnect();
release_log_memory();
activation_exit();
diff --git a/lib/config/config_settings.h b/lib/config/config_settings.h
index 31609d4..59a7c1c 100644
--- a/lib/config/config_settings.h
+++ b/lib/config/config_settings.h
@@ -920,6 +920,15 @@ cfg(activation_checks_CFG, "checks", activation_CFG_SECTION, 0, CFG_TYPE_BOOL, D
"Some of the checks may be expensive, so it's best to use\n"
"this only when there seems to be a problem.\n")
+cfg(global_use_lvmpolld_CFG, "use_lvmpolld", global_CFG_SECTION, 0, CFG_TYPE_BOOL, 0, vsn(2, 2, 120), NULL, 0, NULL,
+ "Indicates whether to use lvmpolld instead of classical polldaemon (a process\n"
+ "forked off an initiating lvm command) or not. When set to 1 and native systemd\n"
+ "service is installed in the system lvm starts using lvmpolld. lvmpolld gets\n"
+ "auto-activated by systemd when a message lands on the respective lvmpolld socket.\n"
+ "All commands that would require polling of in-progress operation are therefore\n"
+ "spawned in lvmpolld's service cgroup.\n"
+ "When set to 0 lvm falls back to classical polling.\n")
+
cfg(activation_udev_sync_CFG, "udev_sync", activation_CFG_SECTION, 0, CFG_TYPE_BOOL, DEFAULT_UDEV_SYNC, vsn(2, 2, 51), NULL, 0, NULL,
"Use udev notifications to synchronize udev and LVM.\n"
"When disabled, LVM commands will not wait for notifications\n"
diff --git a/lib/lvmpolld/lvmpolld-client.c b/lib/lvmpolld/lvmpolld-client.c
new file mode 100644
index 0000000..ee8860f
--- /dev/null
+++ b/lib/lvmpolld/lvmpolld-client.c
@@ -0,0 +1,311 @@
+/*
+ * Copyright (C) 2015 Red Hat, Inc.
+ *
+ * This file is part of LVM2.
+ *
+ * This copyrighted material is made available to anyone wishing to use,
+ * modify, copy, or redistribute it subject to the terms and conditions
+ * of the GNU Lesser General Public License v.2.1.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include "lib.h"
+
+#include "daemon-io.h"
+#include "lvmpolld-client.h"
+#include "lvmpolld-protocol.h"
+#include "metadata-exported.h"
+#include "polldaemon.h"
+#include "toolcontext.h"
+
+struct progress_info {
+ unsigned error:1;
+ unsigned finished:1;
+ int cmd_signal;
+ int cmd_retcode;
+};
+
+static int _lvmpolld_use;
+static int _lvmpolld_connected;
+static const char* _lvmpolld_socket;
+
+static daemon_handle _lvmpolld = { .error = 0 };
+
+static daemon_handle _lvmpolld_connect(const char *socket)
+{
+ daemon_info lvmpolld_info = {
+ .path = "lvmpolld",
+ .socket = socket ?: LVMPOLLD_SOCKET,
+ .protocol = LVMPOLLD_PROTOCOL,
+ .protocol_version = LVMPOLLD_PROTOCOL_VERSION
+ };
+
+ return daemon_open(lvmpolld_info);
+}
+
+void lvmpolld_set_active(int active)
+{
+ _lvmpolld_use = active;
+}
+
+void lvmpolld_set_socket(const char *socket)
+{
+ _lvmpolld_socket = socket;
+}
+
+int lvmpolld_use(void)
+{
+ if (!_lvmpolld_use)
+ return 0;
+
+ if (!_lvmpolld_connected && !_lvmpolld.error) {
+ _lvmpolld = _lvmpolld_connect(_lvmpolld_socket);
+ _lvmpolld_connected = _lvmpolld.socket_fd >= 0;
+ }
+
+ return _lvmpolld_connected;
+}
+
+void lvmpolld_disconnect(void)
+{
+ if (_lvmpolld_connected) {
+ daemon_close(_lvmpolld);
+ _lvmpolld_connected = 0;
+ }
+}
+
+static void _process_error_response(daemon_reply rep)
+{
+ if (!strcmp(daemon_reply_str(rep, "response", ""), LVMPD_RESP_FAILED))
+ log_error("lvmpolld failed to process a request. The reason was: %s.",
+ daemon_reply_str(rep, "reason", "<empty>"));
+ else if (!strcmp(daemon_reply_str(rep, "response", ""), LVMPD_RESP_EINVAL))
+ log_error("lvmpolld couldn't handle a request. "
+ "It might be due to daemon internal state. The reason was: %s.",
+ daemon_reply_str(rep, "reason", "<empty>"));
+ else
+ log_error("Unexpected response %s. The reason: %s.",
+ daemon_reply_str(rep, "response", "<empty>"),
+ daemon_reply_str(rep, "reason", "<empty>"));
+
+ log_print_unless_silent("For more detailed information see lvmpolld log file.");
+}
+
+static struct progress_info _request_progress_info(const char *uuid, unsigned abort_polling)
+{
+ daemon_reply rep;
+ const char *e = getenv("LVM_SYSTEM_DIR");
+ struct progress_info ret = { .error = 1, .finished = 1 };
+ daemon_request req = daemon_request_make(LVMPD_REQ_PROGRESS);
+
+ if (!daemon_request_extend(req, LVMPD_PARM_LVID " = %s", uuid, NULL)) {
+ log_error("Failed to create " LVMPD_REQ_PROGRESS " request.");
+ goto out_req;
+ }
+
+ if (abort_polling &&
+ !daemon_request_extend(req, LVMPD_PARM_ABORT " = %d", abort_polling, NULL)) {
+ log_error("Failed to create " LVMPD_REQ_PROGRESS " request.");
+ goto out_req;
+ }
+
+ if (e &&
+ !(daemon_request_extend(req, LVMPD_PARM_SYSDIR " = %s",
+ e, NULL))) {
+ log_error("Failed to create " LVMPD_REQ_PROGRESS " request.");
+ goto out_req;
+ }
+
+ rep = daemon_send(_lvmpolld, req);
+ if (rep.error) {
+ log_error("Failed to process request with error %s (errno: %d).",
+ strerror(rep.error), rep.error);
+ goto out_rep;
+ }
+
+ if (!strcmp(daemon_reply_str(rep, "response", ""), LVMPD_RESP_IN_PROGRESS)) {
+ ret.finished = 0;
+ ret.error = 0;
+ } else if (!strcmp(daemon_reply_str(rep, "response", ""), LVMPD_RESP_FINISHED)) {
+ if (!strcmp(daemon_reply_str(rep, "reason", ""), LVMPD_REAS_SIGNAL))
+ ret.cmd_signal = daemon_reply_int(rep, LVMPD_PARM_VALUE, 0);
+ else
+ ret.cmd_retcode = daemon_reply_int(rep, LVMPD_PARM_VALUE, -1);
+ ret.error = 0;
+ } else if (!strcmp(daemon_reply_str(rep, "response", ""), LVMPD_RESP_NOT_FOUND)) {
+ log_verbose("No polling operation in progress regarding LV %s.", uuid);
+ ret.error = 0;
+ } else {
+ _process_error_response(rep);
+ stack;
+ }
+
+out_rep:
+ daemon_reply_destroy(rep);
+out_req:
+ daemon_request_destroy(req);
+
+ return ret;
+}
+
+/*
+ * interval in seconds long
+ * enough for more than a year
+ * of waiting
+ */
+#define INTERV_SIZE 10
+
+static int _process_poll_init(const struct cmd_context *cmd, const char *poll_type,
+ const struct poll_operation_id *id, const struct daemon_parms *parms)
+{
+ char *str;
+ daemon_reply rep;
+ daemon_request req;
+ const char *e = getenv("LVM_SYSTEM_DIR");
+ int r = 0;
+
+ str = dm_malloc(INTERV_SIZE * sizeof(char));
+ if (!str)
+ return r;
+
+ if (snprintf(str, INTERV_SIZE, "%u", parms->interval) >= INTERV_SIZE) {
+ log_warn("Interval string conversion got truncated.");
+ str[INTERV_SIZE - 1] = '\0';
+ }
+
+ req = daemon_request_make(poll_type);
+ if (!daemon_request_extend(req, LVMPD_PARM_LVID " = %s", id->uuid,
+ LVMPD_PARM_VGNAME " = %s", id->vg_name,
+ LVMPD_PARM_LVNAME " = %s", id->lv_name,
+ LVMPD_PARM_INTERVAL " = %s", str,
+ "cmdline = %s", cmd->cmd_line, /* FIXME: debug param only */
+ NULL)) {
+ log_error("Failed to create %s request.", poll_type);
+ goto out_req;
+ }
+
+ if (parms->aborting &&
+ !(daemon_request_extend(req, LVMPD_PARM_ABORT " = %d", parms->aborting, NULL))) {
+ log_error("Failed to create %s request." , poll_type);
+ goto out_req;
+ }
+
+ if (cmd->handles_missing_pvs &&
+ !(daemon_request_extend(req, LVMPD_PARM_HANDLE_MISSING_PVS " = %d",
+ cmd->handles_missing_pvs, NULL))) {
+ log_error("Failed to create %s request." , poll_type);
+ goto out_req;
+ }
+
+ if (e &&
+ !(daemon_request_extend(req, LVMPD_PARM_SYSDIR " = %s",
+ e, NULL))) {
+ log_error("Failed to create %s request." , poll_type);
+ goto out_req;
+ }
+
+ rep = daemon_send(_lvmpolld, req);
+
+ if (rep.error) {
+ log_error("Failed to process request with error %s (errno: %d).",
+ strerror(rep.error), rep.error);
+ goto out_rep;
+ }
+
+ if (!strcmp(daemon_reply_str(rep, "response", ""), LVMPD_RESP_OK))
+ r = 1;
+ else {
+ _process_error_response(rep);
+ stack;
+ }
+
+out_rep:
+ daemon_reply_destroy(rep);
+out_req:
+ daemon_request_destroy(req);
+ dm_free(str);
+
+ return r;
+}
+
+int lvmpolld_poll_init(const struct cmd_context *cmd, const struct poll_operation_id *id,
+ const struct daemon_parms *parms)
+{
+ int r = 0;
+
+ if (!id->uuid) {
+ log_error(INTERNAL_ERROR "Use of lvmpolld requires uuid set");
+ return 0;
+ }
+
+ if (!id->vg_name) {
+ log_error(INTERNAL_ERROR "Use of lvmpolld requires vgname set");
+ return 0;
+ }
+
+ if (!id->lv_name) {
+ log_error(INTERNAL_ERROR "Use of lvmpolld requires lvname set");
+ return 0;
+ }
+
+ if (parms->lv_type & PVMOVE) {
+ log_verbose("lvmpolld: Requesting pvmove%s", parms->aborting ? " abort." : ".");
+ r = _process_poll_init(cmd, LVMPD_REQ_PVMOVE, id, parms);
+ } else if (parms->lv_type & CONVERTING) {
+ log_verbose("lvmpolld: Requesting convert mirror.");
+ r = _process_poll_init(cmd, LVMPD_REQ_CONVERT, id, parms);
+ } else if (parms->lv_type & MERGING) {
+ if (parms->lv_type & SNAPSHOT) {
+ log_verbose("lvmpolld: Requesting snapshot merge.");
+ r = _process_poll_init(cmd, LVMPD_REQ_MERGE, id, parms);
+ }
+ else if (parms->lv_type & THIN_VOLUME) {
+ log_verbose("lvmpolld: Thin snapshot merge.");
+ r = _process_poll_init(cmd, LVMPD_REQ_MERGE_THIN, id, parms);
+ }
+ else {
+ log_error(INTERNAL_ERROR "Unsupported poll operation.");
+ }
+ } else
+ log_error(INTERNAL_ERROR "Unsupported poll operation");
+
+ return r;
+}
+
+int lvmpolld_request_info(const struct poll_operation_id *id, const struct daemon_parms *parms, unsigned *finished)
+{
+ struct progress_info info;
+ int ret = 0;
+
+ *finished = 1;
+
+ if (!id->uuid) {
+ log_error(INTERNAL_ERROR "use of lvmpolld requires uuid being set");
+ return 0;
+ }
+
+ info = _request_progress_info(id->uuid, parms->aborting);
+ *finished = info.finished;
+
+ if (info.error)
+ return_0;
+
+ if (info.finished) {
+ if (info.cmd_signal)
+ log_error("Polling command got terminated by signal (%d).",
+ info.cmd_signal);
+ else if (info.cmd_retcode)
+ log_error("Polling command exited with return code: %d.",
+ info.cmd_retcode);
+ else {
+ log_verbose("Polling finished successfully.");
+ ret = 1;
+ }
+ } else
+ ret = 1;
+
+ return ret;
+}
diff --git a/lib/lvmpolld/lvmpolld-client.h b/lib/lvmpolld/lvmpolld-client.h
new file mode 100644
index 0000000..09dd959
--- /dev/null
+++ b/lib/lvmpolld/lvmpolld-client.h
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2014-2015 Red Hat, Inc.
+ *
+ * This file is part of LVM2.
+ *
+ * This copyrighted material is made available to anyone wishing to use,
+ * modify, copy, or redistribute it subject to the terms and conditions
+ * of the GNU Lesser General Public License v.2.1.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef _LVM_LVMPOLLD_CLIENT_H
+#define _LVM_LVMPOLLD_CLIENT_H
+# ifdef LVMPOLLD_SUPPORT
+
+# include "daemon-client.h"
+
+# define LVMPOLLD_SOCKET DEFAULT_RUN_DIR "/lvmpolld.socket"
+
+struct cmd_context;
+struct poll_operation_id;
+struct daemon_parms;
+
+void lvmpolld_disconnect(void);
+
+int lvmpolld_poll_init(const struct cmd_context *cmd, const struct poll_operation_id *id,
+ const struct daemon_parms *parms);
+
+int lvmpolld_request_info(const struct poll_operation_id *id, const struct daemon_parms *parms,
+ unsigned *finished);
+
+int lvmpolld_use(void);
+
+void lvmpolld_set_active(int active);
+
+void lvmpolld_set_socket(const char *socket);
+
+# else
+
+# define lvmpolld_disconnect() do {} while (0)
+# define lvmpolld_poll_init(cmd, id, parms) (0)
+# define lvmpolld_request_info(id, parms, finished) (0)
+# define lvmpolld_use() (0)
+# define lvmpolld_set_active(active) do {} while (0)
+# define lvmpolld_set_socket(socket) do {} while (0)
+
+# endif /* LVMPOLLD_SUPPORT */
+
+#endif /* _LVM_LVMPOLLD_CLIENT_H */
diff --git a/lib/lvmpolld/polldaemon.h b/lib/lvmpolld/polldaemon.h
new file mode 100644
index 0000000..6309a5f
--- /dev/null
+++ b/lib/lvmpolld/polldaemon.h
@@ -0,0 +1,93 @@
+/*
+ * Copyright (C) 2003-2004 Sistina Software, Inc. All rights reserved.
+ * Copyright (C) 2004-2015 Red Hat, Inc. All rights reserved.
+ *
+ * This file is part of LVM2.
+ *
+ * This copyrighted material is made available to anyone wishing to use,
+ * modify, copy, or redistribute it subject to the terms and conditions
+ * of the GNU Lesser General Public License v.2.1.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef _LVM_TOOL_POLLDAEMON_H
+#define _LVM_TOOL_POLLDAEMON_H
+
+#include "metadata-exported.h"
+
+typedef enum {
+ PROGRESS_CHECK_FAILED = 0,
+ PROGRESS_UNFINISHED = 1,
+ PROGRESS_FINISHED_SEGMENT = 2,
+ PROGRESS_FINISHED_ALL = 3
+} progress_t;
+
+struct daemon_parms;
+
+struct poll_functions {
+ const char *(*get_copy_name_from_lv) (const struct logical_volume *lv);
+ struct volume_group *(*get_copy_vg) (struct cmd_context *cmd,
+ const char *name,
+ const char *uuid,
+ uint32_t flags);
+ struct logical_volume *(*get_copy_lv) (struct cmd_context *cmd,
+ struct volume_group *vg,
+ const char *name,
+ const char *uuid,
+ uint64_t lv_type);
+ progress_t (*poll_progress)(struct cmd_context *cmd,
+ struct logical_volume *lv,
+ const char *name,
+ struct daemon_parms *parms);
+ int (*update_metadata) (struct cmd_context *cmd,
+ struct volume_group *vg,
+ struct logical_volume *lv,
+ struct dm_list *lvs_changed, unsigned flags);
+ int (*finish_copy) (struct cmd_context *cmd,
+ struct volume_group *vg,
+ struct logical_volume *lv,
+ struct dm_list *lvs_changed);
+};
+
+struct poll_operation_id {
+ const char *vg_name;
+ const char *lv_name;
+ const char *display_name;
+ const char *uuid;
+};
+
+struct daemon_parms {
+ unsigned interval;
+ unsigned wait_before_testing;
+ unsigned aborting;
+ unsigned background;
+ unsigned outstanding_count;
+ unsigned progress_display;
+ const char *progress_title;
+ uint64_t lv_type;
+ struct poll_functions *poll_fns;
+};
+
+int poll_daemon(struct cmd_context *cmd, unsigned background,
+ uint64_t lv_type, struct poll_functions *poll_fns,
+ const char *progress_title, struct poll_operation_id *id);
+
+progress_t poll_mirror_progress(struct cmd_context *cmd,
+ struct logical_volume *lv, const char *name,
+ struct daemon_parms *parms);
+
+struct volume_group *poll_get_copy_vg(struct cmd_context *cmd, const char *name,
+ const char *uuid, uint32_t flags);
+
+struct logical_volume *poll_get_copy_lv(struct cmd_context *cmd,
+ struct volume_group *vg,
+ const char *name, const char *uuid,
+ uint64_t lv_type);
+
+int wait_for_single_lv(struct cmd_context *cmd, struct poll_operation_id *id,
+ struct daemon_parms *parms);
+
+#endif
diff --git a/lib/misc/configure.h.in b/lib/misc/configure.h.in
index 48ae3f6..45a8462 100644
--- a/lib/misc/configure.h.in
+++ b/lib/misc/configure.h.in
@@ -500,6 +500,12 @@
/* Define to 1 to include code that uses lvmetad. */
#undef LVMETAD_SUPPORT
+/* Path to lvmpolld pidfile. */
+#undef LVMPOLLD_PIDFILE
+
+/* Define to 1 to include code that uses lvmpolld. */
+#undef LVMPOLLD_SUPPORT
+
/* Path to lvm binary. */
#undef LVM_PATH
diff --git a/libdaemon/Makefile.in b/libdaemon/Makefile.in
index dbe6516..c0379a4 100644
--- a/libdaemon/Makefile.in
+++ b/libdaemon/Makefile.in
@@ -19,7 +19,7 @@ top_builddir = @top_builddir@
SUBDIRS += client
-ifeq ("@BUILD_LVMETAD@", "yes")
+ifeq (yes, $(shell test @BUILD_LVMETAD@ == yes -o @BUILD_LVMPOLLD@ == yes && echo yes))
SUBDIRS += server
server: client
endif
diff --git a/make.tmpl.in b/make.tmpl.in
index 5b98ae1..1cac75e 100644
--- a/make.tmpl.in
+++ b/make.tmpl.in
@@ -491,7 +491,7 @@ distclean: cleandir $(SUBDIRS.distclean)
echo " local:"; echo " *;"; echo "};") > $@
ifeq (,$(findstring $(MAKECMDGOALS),cscope.out cflow clean distclean lcov \
- help check check_local check_cluster check_lvmetad))
+ help check check_local check_cluster check_lvmetad check_lvmpolld))
ifdef SOURCES
-include $(SOURCES:.c=.d) $(CXXSOURCES:.cpp=.d)
endif
diff --git a/man/Makefile.in b/man/Makefile.in
index b93c5cb..fd92372 100644
--- a/man/Makefile.in
+++ b/man/Makefile.in
@@ -40,6 +40,12 @@ else
LVMETAD =
endif
+ifeq ("@BUILD_LVMPOLLD@", "yes")
+LVMPOLLD = lvmpolld.8
+else
+LVMPOLLD =
+endif
+
MAN5=lvm.conf.5
MAN7=lvmsystemid.7
MAN8=lvm-config.8 lvm-dumpconfig.8 \
@@ -50,7 +56,7 @@ MAN8=lvm-config.8 lvm-dumpconfig.8 \
pvresize.8 pvs.8 pvscan.8 vgcfgbackup.8 vgcfgrestore.8 vgchange.8 \
vgck.8 vgcreate.8 vgconvert.8 vgdisplay.8 vgexport.8 vgextend.8 \
vgimport.8 vgimportclone.8 vgmerge.8 vgmknodes.8 vgreduce.8 vgremove.8 \
- vgrename.8 vgs.8 vgscan.8 vgsplit.8 $(FSADMMAN) $(LVMETAD)
+ vgrename.8 vgs.8 vgscan.8 vgsplit.8 $(FSADMMAN) $(LVMETAD) $(LVMPOLLD)
ifneq ("@CLVMD@", "none")
MAN8CLUSTER=clvmd.8
diff --git a/man/lvm.8.in b/man/lvm.8.in
index 298d05b..28769d2 100644
--- a/man/lvm.8.in
+++ b/man/lvm.8.in
@@ -525,6 +525,12 @@ Path for the lvmetad pid file.
.TP
.B LVM_LVMETAD_SOCKET
Path for the lvmetad socket file.
+.TP
+.B LVM_LVMPOLLD_PIDFILE
+Path for the lvmpolld pid file.
+.TP
+.B LVM_LVMPOLLD_SOCKET
+Path for the lvmpolld socket file.
.SH FILES
.I #DEFAULT_SYS_DIR#/lvm.conf
.br
diff --git a/man/lvmpolld.8.in b/man/lvmpolld.8.in
new file mode 100644
index 0000000..8573395
--- /dev/null
+++ b/man/lvmpolld.8.in
@@ -0,0 +1,86 @@
+.TH LVMETAD 8 "LVM TOOLS #VERSION#" "Red Hat Inc" \" -*- nroff -*-
+.SH NAME
+lvmpolld \(em LVM poll daemon
+.SH SYNOPSIS
+.B lvmpolld
+.RB [ \-l
+.RI { all | wire | debug }]
+.RB [ \-p
+.IR pidfile_path ]
+.RB [ \-s
+.IR socket_path ]
+.RB [ \-B
+.IR lvm_binary_path ]
+.RB [ \-t
+.IR timeout_value ]
+.RB [ \-f ]
+.RB [ \-h ]
+.RB [ \-V ]
+.RB [ \-? ]
+.SH DESCRIPTION
+lvmpolld is polling daemon for LVM. The daemon receives requests for polling
+of already initialised operations originating in LVM2 command line tool.
+The requests for polling originates in \fBlvconvert\fP, \fBpvmove\fP,
+\fBlvchange\fP or \fBvgchange\fP LVM2 command.
+
+The purpose of lvmpolld is to reduce the number of spawned background processes
+per otherwise unique polling operation. There should be only one. It also eliminates
+the possibility of unsolicited termination of background process by external factors.
+
+lvmpolld is used by LVM only if it is enabled in \fBlvm.conf\fP(5) by specifying the
+\fBglobal/use_lvmpolld\fP setting. If this is not defined in the LVM configuration
+explicitly then default setting is used instead (see the output of
+\fBlvmconfig \-\-type default global/use_lvmpolld\fP command).
+.SH OPTIONS
+
+To run the daemon in a test environment both the pidfile_path and the
+socket_path should be changed from the defaults.
+.TP
+.B \-f
+Don't fork, but run in the foreground.
+.TP
+.BR \-h ", " \-?
+Show help information.
+.TP
+.IR \fB\-l " {" all | wire | debug }
+Select the type of log messages to generate.
+Messages are logged by syslog.
+Additionally, when \-f is given they are also sent to standard error.
+There are two classes of messages: wire and debug. Selecting 'all' supplies both
+and is equivalent to a comma-separated list \-l wire,debug.
+.TP
+.B \-p \fIpidfile_path
+Path to the pidfile. This overrides both the built-in default
+(#DEFAULT_PID_DIR#/lvmpolld.pid) and the environment variable
+\fBLVM_LVMPOLLD_PIDFILE\fP. This file is used to prevent more
+than one instance of the daemon running simultaneously.
+.TP
+.B \-s \fIsocket_path
+Path to the socket file. This overrides both the built-in default
+(#DEFAULT_RUN_DIR#/lvmpolld.socket) and the environment variable
+\fBLVM_LVMPOLLD_SOCKET\fP.
+.TP
+.B \-t \fItimeout_value
+When runs as native systemd service daemon may shutdown after being
+idle for the given time (in seconds). When the option is omitted or
+the value given is zero the daemon never shutdowns on idle. When
+the daemon doesn't run as native systemd service the timeout is
+ignored and never shutdowns on idle.
+.TP
+.B \-B \fIlvm_binary_path
+Optional path to alternative LVM binary (default: #LVM_PATH#). Use for
+testing purposes only.
+.TP
+.B \-V
+Display the version of lvmpolld daemon.
+.SH ENVIRONMENT VARIABLES
+.TP
+.B LVM_LVMPOLLD_PIDFILE
+Path for the pid file.
+.TP
+.B LVM_LVMPOLLD_SOCKET
+Path for the socket file.
+
+.SH SEE ALSO
+.BR lvm (8),
+.BR lvm.conf (5)
diff --git a/scripts/.gitignore b/scripts/.gitignore
index 6fd8a2d..2b9162d 100644
--- a/scripts/.gitignore
+++ b/scripts/.gitignore
@@ -4,6 +4,9 @@ dm_event_systemd_red_hat.service
lvm2_lvmetad_init_red_hat
lvm2_lvmetad_systemd_red_hat.service
lvm2_lvmetad_systemd_red_hat.socket
+lvm2_lvmpolld_init_red_hat
+lvm2_lvmpolld_systemd_red_hat.service
+lvm2_lvmpolld_systemd_red_hat.socket
lvm2_monitoring_init_red_hat
lvm2_monitoring_systemd_red_hat.service
lvm2_tmpfiles_red_hat.conf
diff --git a/scripts/Makefile.in b/scripts/Makefile.in
index 60797ef..e9cce3a 100644
--- a/scripts/Makefile.in
+++ b/scripts/Makefile.in
@@ -75,6 +75,9 @@ endif
ifeq ("@BUILD_LVMETAD@", "yes")
$(INSTALL_SCRIPT) lvm2_lvmetad_init_red_hat $(initdir)/lvm2-lvmetad
endif
+ifeq ("@BUILD_LVMPOLLD@", "yes")
+ $(INSTALL_SCRIPT) lvm2_lvmpolld_init_red_hat $(initdir)/lvm2-lvmpolld
+endif
ifneq ("@CLVMD@", "none")
$(INSTALL_SCRIPT) clvmd_init_red_hat $(initdir)/clvmd
endif
@@ -114,6 +117,10 @@ ifeq ("@BUILD_LVMETAD@", "yes")
$(INSTALL_DATA) lvm2_lvmetad_systemd_red_hat.service $(systemd_unit_dir)/lvm2-lvmetad.service
$(INSTALL_DATA) lvm2_pvscan_systemd_red_hat@.service $(systemd_unit_dir)/lvm2-pvscan@.service
endif
+ifeq ("@BUILD_LVMPOLLD@", "yes")
+ $(INSTALL_DATA) lvm2_lvmpolld_systemd_red_hat.socket $(systemd_unit_dir)/lvm2-lvmpolld.socket
+ $(INSTALL_DATA) lvm2_lvmpolld_systemd_red_hat.service $(systemd_unit_dir)/lvm2-lvmpolld.service
+endif
ifneq ("@CLVMD@", "none")
$(INSTALL_DATA) lvm2_clvmd_systemd_red_hat.service $(systemd_unit_dir)/lvm2-clvmd.service
$(INSTALL_DATA) lvm2_cluster_activation_systemd_red_hat.service $(systemd_unit_dir)/lvm2-cluster-activation.service
@@ -142,6 +149,8 @@ DISTCLEAN_TARGETS += \
lvm2_lvmetad_init_red_hat \
lvm2_lvmetad_systemd_red_hat.service \
lvm2_lvmetad_systemd_red_hat.socket \
+ lvm2_lvmpolld_systemd_red_hat.service \
+ lvm2_lvmpolld_systemd_red_hat.socket \
lvm2_monitoring_init_red_hat \
lvm2_monitoring_systemd_red_hat.service \
lvm2_pvscan_systemd_red_hat@.service \
diff --git a/scripts/lvm2_lvmpolld_init_red_hat.in b/scripts/lvm2_lvmpolld_init_red_hat.in
new file mode 100644
index 0000000..0a03f01
--- /dev/null
+++ b/scripts/lvm2_lvmpolld_init_red_hat.in
@@ -0,0 +1,114 @@
+#!/bin/bash
+#
+# Copyright (C) 2015 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
+#
+# This file is part of LVM2.
+# It is required for the proper handling of failures of LVM2 mirror
+# devices that were created using the -m option of lvcreate.
+#
+#
+# chkconfig: 12345 02 99
+# description: Starts and stops LVM poll daemon
+#
+# For Red-Hat-based distributions such as Fedora, RHEL, CentOS.
+#
+### BEGIN INIT INFO
+# Provides: lvm2-lvmpolld
+# Required-Start: $local_fs
+# Required-Stop: $local_fs
+# Default-Start: 1 2 3 4 5
+# Default-Stop: 0 6
+# Short-Description: A daemon that is responsible for monitoring in-progress
+# and possibly longer term operations on logical volumes.
+# It helps to reduce the number of spawned processes if same
+# logical volume is requested to get monitored multiple times.
+# Also avoids unsolicited termination due to external factors.
+### END INIT INFO
+
+. /etc/init.d/functions
+
+DAEMON=lvmpolld
+
+exec_prefix=@exec_prefix@
+sbindir=@sbindir@
+
+LOCK_FILE="/var/lock/subsys/$DAEMON"
+PID_FILE="@LVMPOLLD_PIDFILE@"
+
+rh_status() {
+ status -p $PID_FILE $DAEMON
+}
+
+rh_status_q() {
+ rh_status >/dev/null 2>&1
+}
+
+start()
+{
+ ret=0
+ action "Starting LVM poll daemon:" $DAEMON || ret=$?
+ return $ret
+}
+
+
+stop()
+{
+ ret=0
+ action "Signaling LVM poll daemon to exit:" killproc -p $PID_FILE $DAEMON -TERM || ret=$?
+ return $ret
+}
+
+rtrn=1
+
+# See how we were called.
+case "$1" in
+ start)
+ rh_status_q && exit 0
+ start
+ rtrn=$?
+ [ $rtrn = 0 ] && touch $LOCK_FILE
+ ;;
+
+ stop|force-stop)
+ rh_status_q || exit 0
+ stop
+ rtrn=$?
+ [ $rtrn = 0 ] && rm -f $LOCK_FILE
+ ;;
+
+ restart)
+ if stop
+ then
+ start
+ fi
+ rtrn=$?
+ ;;
+
+ condrestart|try-restart)
+ rh_status_q || exit 0
+ if stop
+ then
+ start
+ fi
+ rtrn=$?
+ ;;
+
+ status)
+ rh_status
+ rtrn=$?
+ ;;
+
+ *)
+ echo $"Usage: $0 {start|stop|force-stop|restart|condrestart|try-restart|status}"
+ ;;
+esac
+
+exit $rtrn
diff --git a/scripts/lvm2_lvmpolld_systemd_red_hat.service.in b/scripts/lvm2_lvmpolld_systemd_red_hat.service.in
new file mode 100644
index 0000000..d7ff492
--- /dev/null
+++ b/scripts/lvm2_lvmpolld_systemd_red_hat.service.in
@@ -0,0 +1,17 @@
+[Unit]
+Description=LVM2 poll daemon
+Documentation=man:lvmpolld(8)
+Requires=lvm2-lvmpolld.socket
+After=lvm2-lvmpolld.socket
+DefaultDependencies=no
+Conflicts=shutdown.target
+
+[Service]
+Type=simple
+NonBlocking=true
+ExecStart=@sbindir@/lvmpolld -t 60 -f
+Environment=SD_ACTIVATION=1
+PIDFile=@LVMPOLLD_PIDFILE@
+
+[Install]
+WantedBy=sysinit.target
diff --git a/scripts/lvm2_lvmpolld_systemd_red_hat.socket.in b/scripts/lvm2_lvmpolld_systemd_red_hat.socket.in
new file mode 100644
index 0000000..ca9f123
--- /dev/null
+++ b/scripts/lvm2_lvmpolld_systemd_red_hat.socket.in
@@ -0,0 +1,12 @@
+[Unit]
+Description=LVM2 poll daemon socket
+Documentation=man:lvmpolld(8)
+DefaultDependencies=no
+
+[Socket]
+ListenStream=@DEFAULT_RUN_DIR(a)/lvmpolld.socket
+SocketMode=0600
+RemoveOnStop=true
+
+[Install]
+WantedBy=sysinit.target
diff --git a/scripts/lvmdump.sh b/scripts/lvmdump.sh
index 9229912..879dd0c 100755
--- a/scripts/lvmdump.sh
+++ b/scripts/lvmdump.sh
@@ -1,7 +1,7 @@
#!/bin/bash
# We use some bash-isms (getopts?)
-# Copyright (C) 2007-2010 Red Hat, Inc. All rights reserved.
+# Copyright (C) 2007-2015 Red Hat, Inc. All rights reserved.
#
# This file is part of LVM2.
#
@@ -41,6 +41,7 @@ NC=nc
LVM=${LVM_BINARY-lvm}
DMSETUP=${DMSETUP_BINARY-dmsetup}
LVMETAD_SOCKET=${LVM_LVMETAD_SOCKET-/var/run/lvm/lvmetad.socket}
+LVMPOLLD_SOCKET=${LVM_LVMPOLLD_SOCKET-/var/run/lvm/lvmpolld.socket}
die() {
code=$1; shift
@@ -59,6 +60,7 @@ function usage {
echo " -c if running clvmd, gather cluster data as well"
echo " -d <directory> dump into a directory instead of tarball"
echo " -l gather lvmetad state if running"
+ echo " -p gather lvmpolld state if running"
echo " -m gather LVM metadata from the PVs"
echo " -s gather system info and context"
echo " -u gather udev info and context"
@@ -72,13 +74,14 @@ clustered=0
metadata=0
sysreport=0
udev=0
-while getopts :acd:hlmus opt; do
+while getopts :acd:hlpmus opt; do
case $opt in
a) advanced=1 ;;
c) clustered=1 ;;
d) userdir=$OPTARG ;;
h) usage ;;
l) lvmetad=1 ;;
+ p) lvmpolld=1 ;;
m) metadata=1 ;;
s) sysreport=1 ;;
u) udev=1 ;;
@@ -236,6 +239,7 @@ if (( $metadata )); then
done
fi
+# FIXME: add lvmpolld.service here
if (( $sysreport )); then
myecho "Gathering system info..."
@@ -296,6 +300,22 @@ if (( $lvmetad )); then
} > "$dir/lvmetad.txt"
fi
+if (( $lvmpolld )); then
+ (echo 'request="dump"'; echo '##') | {
+ if type -p $SOCAT >& /dev/null; then
+ echo "$SOCAT unix-connect:$LVMPOLLD_SOCKET -" >> "$log"
+ $SOCAT "unix-connect:$LVMPOLLD_SOCKET" - 2>> "$log"
+ elif echo | $NC -U "$LVMPOLLD_SOCKET"; then
+ echo "$NC -U $LVMPOLLD_SOCKET" >> "$log"
+ $NC -U "$LVMPOLLD_SOCKET" 2>> "$log"
+ else
+ myecho "WARNING: Neither socat nor nc -U seems to be available." 1>&2
+ echo "# DUMP FAILED"
+ return 1
+ fi
+ } > "$dir/lvmpolld.txt"
+fi
+
if test -z "$userdir"; then
lvm_dump="$dirbase.tgz"
myecho "Creating report tarball in $HOME/$lvm_dump..."
diff --git a/test/Makefile.in b/test/Makefile.in
index 4144d14..051a38e 100644
--- a/test/Makefile.in
+++ b/test/Makefile.in
@@ -56,6 +56,11 @@ LVMETAD_NDEV_FLAVOUR = ,ndev-lvmetad
LVMETAD_UDEV_FLAVOUR = ,udev-lvmetad
endif
+ifeq ("@BUILD_LVMPOLLD@", "yes")
+LVMPOLLD_RUN_BASE = $(RUN_BASE)
+LVMPOLLD_NDEV_FLAVOUR = ,ndev-lvmpolld,ndev-cluster-lvmpolld,ndev-lvmetad-lvmpolld
+LVMPOLLD_UDEV_FLAVOUR = ,udev-lvmpolld,udev-cluster-lvmpolld,udev-lvmetad-lvmpolld
+endif
# Shell quote;
SHELL_PATH_SQ = $(subst ','\'',$(SHELL_PATH))
@@ -73,6 +78,7 @@ help:
@echo " check_local Run tests without clvmd and lvmetad."
@echo " check_cluster Run tests with cluster daemon."
@echo " check_lvmetad Run tests with lvmetad daemon."
+ @echo " check_lvmpolld Run tests with lvmpolld daemon."
@echo " clean Clean dir."
@echo " help Display callable targets."
@echo -e "\nSupported variables:"
@@ -83,6 +89,7 @@ help:
@echo " LVM_TEST_LOCKING Normal (1), Cluster (3)."
@echo " LVM_TEST_LVMETAD Start lvmetad (1)."
@echo " LVM_TEST_LVMETAD_DEBUG_OPTS Allows to override debug opts [-l all]."
+ @echo " LVM_TEST_LVMPOLLD Start lvmpolld"
@echo " LVM_TEST_NODEBUG Do not debug lvm commands."
@echo " LVM_TEST_PARALLEL May skip agresive wipe of LVMTEST resources."
@echo " LVM_TEST_RESULTS Where to create result files [results]."
@@ -109,12 +116,12 @@ help:
check: .tests-stamp
VERBOSE=$(VERBOSE) ./lib/runner \
--testdir . --outdir $(LVM_TEST_RESULTS) \
- --flavours ndev-vanilla,ndev-cluster$(LVMETAD_NDEV_FLAVOUR) --only $(T) --skip $(S)
+ --flavours ndev-vanilla,ndev-cluster$(LVMETAD_NDEV_FLAVOUR)$(LVMPOLLD_NDEV_FLAVOUR) --only $(T) --skip $(S)
check_system: .tests-stamp
VERBOSE=$(VERBOSE) ./lib/runner \
--testdir . --outdir $(LVM_TEST_RESULTS) \
- --flavours udev-vanilla,udev-cluster$(LVMETAD_UDEV_FLAVOUR) --only $(T) --skip $(S)
+ --flavours udev-vanilla,udev-cluster$(LVMETAD_UDEV_FLAVOUR)$(LVMPOLLD_UDEV_FLAVOUR) --only $(T) --skip $(S)
check_cluster: .tests-stamp
VERBOSE=$(VERBOSE) ./lib/runner \
@@ -133,11 +140,21 @@ check_lvmetad: .tests-stamp
--flavours ndev-lvmetad --only $(T) --skip $(S)
endif
+ifeq ("@BUILD_LVMPOLLD@", "yes")
+check_lvmpolld: .tests-stamp
+ VERBOSE=$(VERBOSE) ./lib/runner \
+ --testdir . --outdir results \
+ --flavours udev-lvmpolld,udev-cluster-lvmpolld,udev-lvmetad-lvmpolld --only $(T) --skip $(S)
+endif
+
DATADIR = $(datadir)/lvm2-testsuite
EXECDIR = $(libexecdir)/lvm2-testsuite
LIB_FLAVOURS = lib/flavour-ndev-vanilla lib/flavour-ndev-cluster lib/flavour-ndev-lvmetad \
- lib/flavour-udev-vanilla lib/flavour-udev-cluster lib/flavour-udev-lvmetad
+ lib/flavour-udev-vanilla lib/flavour-udev-cluster lib/flavour-udev-lvmetad \
+ lib/flavour-udev-lvmpolld lib/flavour-ndev-lvmpolld lib/flavour-ndev-cluster-lvmpolld \
+ lib/flavour-ndev-lvmetad-lvmpolld lib/flavour-udev-lvmpolld lib/flavour-udev-cluster-lvmpolld \
+ lib/flavour-udev-lvmetad-lvmpolld
LIB_LOCAL = lib/paths lib/runner
LIB_EXEC = lib/not lib/invalid lib/fail lib/should
@@ -190,6 +207,7 @@ lib/paths-common: $(srcdir)/Makefile.in .lib-dir-stamp Makefile
echo 'export RAID=@RAID@' >> $@-t
echo 'export CACHE=@CACHE@' >> $@-t
echo 'export LVMETAD_PIDFILE="@LVMETAD_PIDFILE@"' >> $@-t
+ echo 'export LVMPOLLD_PIDFILE="@LVMPOLLD_PIDFILE@"' >> $@-t
echo 'export DMEVENTD_PIDFILE="@DMEVENTD_PIDFILE@"' >> $@-t
echo 'export CLVMD_PIDFILE="@CLVMD_PIDFILE@"' >> $@-t
echo 'export LVM_TEST_THIN_CHECK_CMD=$${LVM_TEST_THIN_CHECK_CMD-@THIN_CHECK_CMD@}' >> $@-t
@@ -240,6 +258,7 @@ LIB = $(LIB_SHARED) $(LIB_LOCAL) $(LIB_EXEC) $(LIB_FLAVOURS)
ln -fs $(abs_top_builddir)/daemons/clvmd/clvmd lib/clvmd
ln -fs $(abs_top_builddir)/daemons/dmeventd/dmeventd lib/dmeventd
ln -fs $(abs_top_builddir)/daemons/lvmetad/lvmetad lib/lvmetad
+ ln -fs $(abs_top_builddir)/daemons/lvmpolld/lvmpolld lib/lvmpolld
ln -fs $(abs_top_srcdir)/scripts/vgimportclone.sh lib/vgimportclone
ln -fs $(abs_top_srcdir)/scripts/fsadm.sh lib/fsadm
ln -fs $(abs_top_srcdir)/conf/thin-performance.profile lib/thin-performance.profile
@@ -256,7 +275,8 @@ CLEAN_TARGETS += .lib-dir-stamp .tests-stamp $(LIB) $(addprefix lib/,$(CMDS)) \
lib/clvmd lib/dmeventd lib/dmsetup lib/lvmetad lib/fsadm lib/vgimportclone \
lib/thin-performance.profile lib/harness \
lib/paths-installed lib/paths-installed-t \
- lib/paths-common lib/paths-common-t
+ lib/paths-common lib/paths-common-t \
+ lib/lvmpolld
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@
diff --git a/test/lib/aux.sh b/test/lib/aux.sh
index d1d38f8..cb0fe4f 100644
--- a/test/lib/aux.sh
+++ b/test/lib/aux.sh
@@ -136,6 +136,47 @@ notify_lvmetad() {
fi
}
+prepare_lvmpolld() {
+ set -x
+ rm -f debug.log
+ # skip if we don't have our own lvmpolld...
+ (which lvmpolld 2>/dev/null | grep "$abs_builddir") || skip
+
+ lvmconf "global/use_lvmpolld = 1"
+
+ local run_valgrind=
+ test "${LVM_VALGRIND_LVMPOLLD:-0}" -eq 0 || run_valgrind="run_valgrind"
+
+ kill_sleep_kill_ LOCAL_LVMPOLLD ${LVM_VALGRIND_LVMPOLLD:-0}
+
+ echo "preparing lvmpolld..."
+ $run_valgrind lvmpolld -f "$@" -s "$TESTDIR/lvmpolld.socket" -B "$TESTDIR/lib/lvm" -l all &
+ echo $! > LOCAL_LVMPOLLD
+ while ! test -e "$TESTDIR/lvmpolld.socket"; do echo -n .; sleep .1; done # wait for the socket
+ echo ok
+}
+
+lvmpolld_talk() {
+ local use=nc
+ if type -p socat >& /dev/null; then
+ use=socat
+ elif echo | not nc -U "$TESTDIR/lvmpolld.socket" ; then
+ echo "WARNING: Neither socat nor nc -U seems to be available." 1>&2
+ echo "# failed to contact lvmpolld"
+ return 1
+ fi
+
+ if test "$use" = nc ; then
+ nc -U "$TESTDIR/lvmpolld.socket"
+ else
+ socat "unix-connect:$TESTDIR/lvmpolld.socket" -
+ fi | tee -a lvmpolld-talk.txt
+}
+
+lvmpolld_dump() {
+ (echo 'request="dump"'; echo '##') | lvmpolld_talk "$@"
+}
+
teardown_devs_prefixed() {
local prefix=$1
local stray=${2:-0}
@@ -286,6 +327,10 @@ teardown() {
$vg $vg1 $vg2 $vg3 $vg4 &>/dev/null || rm -f debug.log strace.log
}
+ kill_sleep_kill_ LOCAL_LVMPOLLD ${LVM_VALGRIND_LVMPOLLD:-0}
+
+ echo -n .
+
kill_sleep_kill_ LOCAL_CLVMD ${LVM_VALGRIND_CLVMD:-0}
echo -n .
@@ -1094,16 +1139,57 @@ dmsetup_wrapped() {
dmsetup "$@"
}
+awk_parse_init_count_in_lvmpolld_dump() {
+ printf '%s' \
+ \
+ $'BEGINFILE { x=0; answ=0; FS="="; key="[[:space:]]*"vkey }' \
+ $'{' \
+ $'if (/.*{$/) { x++ }' \
+ $'else if (/.*}$/) { x-- }' \
+ $'else if ( x == 2 && $1 ~ key) { value=substr($2, 2); value=substr(value, 1, length(value) - 1); }' \
+ $'if ( x == 2 && value == vvalue && $1 ~ /[[:space:]]*init_requests_count/) { answ=$2 }' \
+ $'if (answ > 0) { exit 0 }' \
+ $'}' \
+ $'END { printf "%d", answ }'
+}
+
+check_lvmpolld_init_rq_count() {
+ local ret=$(awk -v vvalue="$2" -v vkey=${3:-lvname} "$(awk_parse_init_count_in_lvmpolld_dump)" lvmpolld_dump.txt)
+ test $ret -eq $1 || {
+ echo "check_lvmpolld_init_rq_count failed. Expected $1, got $ret"
+ return 1
+ }
+}
+
wait_pvmove_lv_ready() {
# given sleep .1 this is about 60 secs of waiting
local retries=${2:-300}
- while : ; do
- test $retries -le 0 && die "Waiting for pvmove LV to get activated has timed out"
- dmsetup info -c -o tables_loaded $1 > out 2>/dev/null|| true;
- not grep Live out >/dev/null || break
- sleep .1
- retries=$((retries-1))
- done
+
+ if [ -e LOCAL_LVMPOLLD ]; then
+ local lvid
+ while : ; do
+ test $retries -le 0 && die "Waiting for lvmpolld timed out"
+ test -n "$lvid" || {
+ lvid=$(get lv_field ${1//-/\/} vg_uuid,lv_uuid -a 2>/dev/null)
+ lvid=${lvid//\ /}
+ lvid=${lvid//-/}
+ }
+ test -z "$lvid" || {
+ lvmpolld_dump > lvmpolld_dump.txt
+ ! check_lvmpolld_init_rq_count 1 $lvid lvid || break;
+ }
+ sleep .1
+ retries=$((retries-1))
+ done
+ else
+ while : ; do
+ test $retries -le 0 && die "Waiting for pvmove LV to get activated has timed out"
+ dmsetup info -c -o tables_loaded $1 > out 2>/dev/null|| true;
+ not grep Live out >/dev/null || break
+ sleep .1
+ retries=$((retries-1))
+ done
+ fi
}
# return total memory size in kB units
diff --git a/test/lib/flavour-ndev-cluster-lvmpolld.sh b/test/lib/flavour-ndev-cluster-lvmpolld.sh
new file mode 100644
index 0000000..fe31bb4
--- /dev/null
+++ b/test/lib/flavour-ndev-cluster-lvmpolld.sh
@@ -0,0 +1,2 @@
+export LVM_TEST_LOCKING=3
+export LVM_TEST_LVMPOLLD=1
diff --git a/test/lib/flavour-ndev-lvmetad-lvmpolld.sh b/test/lib/flavour-ndev-lvmetad-lvmpolld.sh
new file mode 100644
index 0000000..496b3bc
--- /dev/null
+++ b/test/lib/flavour-ndev-lvmetad-lvmpolld.sh
@@ -0,0 +1,3 @@
+export LVM_TEST_LOCKING=1
+export LVM_TEST_LVMETAD=1
+export LVM_TEST_LVMPOLLD=1
diff --git a/test/lib/flavour-ndev-lvmpolld.sh b/test/lib/flavour-ndev-lvmpolld.sh
new file mode 100644
index 0000000..0a70703
--- /dev/null
+++ b/test/lib/flavour-ndev-lvmpolld.sh
@@ -0,0 +1,2 @@
+export LVM_TEST_LOCKING=1
+export LVM_TEST_LVMPOLLD=1
diff --git a/test/lib/flavour-udev-cluster-lvmpolld.sh b/test/lib/flavour-udev-cluster-lvmpolld.sh
new file mode 100644
index 0000000..abf76e9
--- /dev/null
+++ b/test/lib/flavour-udev-cluster-lvmpolld.sh
@@ -0,0 +1,3 @@
+export LVM_TEST_LOCKING=3
+export LVM_TEST_LVMPOLLD=1
+export LVM_TEST_DEVDIR=/dev
diff --git a/test/lib/flavour-udev-lvmetad-lvmpolld.sh b/test/lib/flavour-udev-lvmetad-lvmpolld.sh
new file mode 100644
index 0000000..64253d1
--- /dev/null
+++ b/test/lib/flavour-udev-lvmetad-lvmpolld.sh
@@ -0,0 +1,4 @@
+export LVM_TEST_LOCKING=1
+export LVM_TEST_LVMETAD=1
+export LVM_TEST_LVMPOLLD=1
+export LVM_TEST_DEVDIR=/dev
diff --git a/test/lib/flavour-udev-lvmpolld.sh b/test/lib/flavour-udev-lvmpolld.sh
new file mode 100644
index 0000000..c7f40b5
--- /dev/null
+++ b/test/lib/flavour-udev-lvmpolld.sh
@@ -0,0 +1,3 @@
+export LVM_TEST_LOCKING=1
+export LVM_TEST_LVMPOLLD=1
+export LVM_TEST_DEVDIR=/dev
diff --git a/test/lib/inittest.sh b/test/lib/inittest.sh
index cd6471c..1af0503 100644
--- a/test/lib/inittest.sh
+++ b/test/lib/inittest.sh
@@ -100,6 +100,13 @@ else
aux prepare_clvmd
fi
+echo "LVM_TEST_LVMPOLLD=$LVM_TEST_LVMPOLLD"
+test -n "$LVM_TEST_LVMPOLLD" && {
+ export LVM_LVMPOLLD_SOCKET="$TESTDIR/lvmpolld.socket"
+ export LVM_LVMPOLLD_PIDFILE="$TESTDIR/lvmpolld.pid"
+ aux prepare_lvmpolld
+}
+
echo "<======== Processing test: \"$TESTNAME\" ========>"
set -vx
diff --git a/test/shell/000-basic.sh b/test/shell/000-basic.sh
index 027969e..573bbd1 100644
--- a/test/shell/000-basic.sh
+++ b/test/shell/000-basic.sh
@@ -11,6 +11,8 @@
. lib/inittest
+test -e LOCAL_LVMPOLLD && skip
+
lvm version
test -n "$abs_top_builddir" || skip
diff --git a/test/shell/activate-minor.sh b/test/shell/activate-minor.sh
index 1c5386c..d7ae5f9 100644
--- a/test/shell/activate-minor.sh
+++ b/test/shell/activate-minor.sh
@@ -14,6 +14,7 @@
# Just skip this test if minor is already in use...
dmsetup info | tee info
egrep "^Major, minor: *[0-9]+, 123" info && skip
+test -e LOCAL_LVMPOLLD && skip
aux prepare_vg 2
lvcreate -a n --zero n -l 1 -n foo $vg
diff --git a/test/shell/activate-missing-segment.sh b/test/shell/activate-missing-segment.sh
index 5f43c72..988c9cb 100644
--- a/test/shell/activate-missing-segment.sh
+++ b/test/shell/activate-missing-segment.sh
@@ -18,6 +18,8 @@
. lib/inittest
+test -e LOCAL_LVMPOLLD && skip
+
aux prepare_vg 2
lvcreate -l100%FREE -n span $vg
diff --git a/test/shell/activate-missing.sh b/test/shell/activate-missing.sh
index 8e2ff1e..e33a6ef 100644
--- a/test/shell/activate-missing.sh
+++ b/test/shell/activate-missing.sh
@@ -18,6 +18,8 @@
. lib/inittest
+test -e LOCAL_LVMPOLLD && skip
+
aux prepare_vg 4
lvcreate -l1 -n linear1 $vg "$dev1"
diff --git a/test/shell/activate-partial.sh b/test/shell/activate-partial.sh
index 0b5d1b6..3720e1d 100644
--- a/test/shell/activate-partial.sh
+++ b/test/shell/activate-partial.sh
@@ -11,6 +11,8 @@
. lib/inittest
+test -e LOCAL_LVMPOLLD && skip
+
aux prepare_vg 3
lvcreate -aey --type mirror -m 1 -l 1 --nosync -n mirror $vg
diff --git a/test/shell/activation-skip.sh b/test/shell/activation-skip.sh
index ca562a7..5259d9d 100644
--- a/test/shell/activation-skip.sh
+++ b/test/shell/activation-skip.sh
@@ -11,6 +11,8 @@
. lib/inittest
+test -e LOCAL_LVMPOLLD && skip
+
# Test skip activation flag -k|--setactivationskip
aux prepare_vg
diff --git a/test/shell/clvmd-restart.sh b/test/shell/clvmd-restart.sh
index cb06bf6..afe4834 100644
--- a/test/shell/clvmd-restart.sh
+++ b/test/shell/clvmd-restart.sh
@@ -16,6 +16,7 @@ export LVM_BINARY=lvm
. lib/inittest
# only clvmd based test, skip otherwise
+test -e LOCAL_LVMPOLLD && skip
test -e LOCAL_CLVMD || skip
read LOCAL_CLVMD < LOCAL_CLVMD
diff --git a/test/shell/covercmd.sh b/test/shell/covercmd.sh
index c84c967..5e47bd9 100644
--- a/test/shell/covercmd.sh
+++ b/test/shell/covercmd.sh
@@ -16,6 +16,8 @@
. lib/inittest
+test -e LOCAL_LVMPOLLD && skip
+
aux prepare_pvs 5
get_devs
diff --git a/test/shell/discards-thin.sh b/test/shell/discards-thin.sh
index a2cac52..8acb20d 100644
--- a/test/shell/discards-thin.sh
+++ b/test/shell/discards-thin.sh
@@ -15,6 +15,8 @@
. lib/inittest
+test -e LOCAL_LVMPOLLD && skip
+
#
# Main
#
diff --git a/test/shell/dmeventd-restart.sh b/test/shell/dmeventd-restart.sh
index 022b8a8..a64509e 100644
--- a/test/shell/dmeventd-restart.sh
+++ b/test/shell/dmeventd-restart.sh
@@ -11,6 +11,8 @@
. lib/inittest
+test -e LOCAL_LVMPOLLD && skip
+
aux prepare_dmeventd
aux prepare_vg 5
diff --git a/test/shell/dumpconfig.sh b/test/shell/dumpconfig.sh
index f52157f..0d33761 100644
--- a/test/shell/dumpconfig.sh
+++ b/test/shell/dumpconfig.sh
@@ -11,6 +11,8 @@
. lib/inittest
+test -e LOCAL_LVMPOLLD && skip
+
flatten() {
cat > flatten.config
for s in `egrep '^[a-z]+ {$' flatten.config | sed -e s,{$,,`; do
diff --git a/test/shell/error-usage.sh b/test/shell/error-usage.sh
index 61e282b..f617b61 100644
--- a/test/shell/error-usage.sh
+++ b/test/shell/error-usage.sh
@@ -13,6 +13,8 @@
. lib/inittest
+test -e LOCAL_LVMPOLLD && skip
+
which md5sum || skip
aux prepare_pvs 1
diff --git a/test/shell/fsadm.sh b/test/shell/fsadm.sh
index 368e747..12f1593 100644
--- a/test/shell/fsadm.sh
+++ b/test/shell/fsadm.sh
@@ -13,6 +13,8 @@ test_description='Exercise fsadm filesystem resize'
. lib/inittest
+test -e LOCAL_LVMPOLLD && skip
+
aux prepare_vg 1 100
# set to "skip" to avoid testing given fs and test warning result
diff --git a/test/shell/inconsistent-metadata.sh b/test/shell/inconsistent-metadata.sh
index 69d1f33..a606330 100644
--- a/test/shell/inconsistent-metadata.sh
+++ b/test/shell/inconsistent-metadata.sh
@@ -11,6 +11,8 @@
. lib/inittest
+test -e LOCAL_LVMPOLLD && skip
+
aux prepare_vg 3 12
lvcreate -aye --type mirror -m 1 -l 1 -n mirror $vg
diff --git a/test/shell/listings.sh b/test/shell/listings.sh
index fcf6308..d018510 100644
--- a/test/shell/listings.sh
+++ b/test/shell/listings.sh
@@ -15,6 +15,8 @@
. lib/inittest
+test -e LOCAL_LVMPOLLD && skip
+
aux prepare_devs 5
get_devs
diff --git a/test/shell/lock-blocking.sh b/test/shell/lock-blocking.sh
index 7c33067..5c004c9 100644
--- a/test/shell/lock-blocking.sh
+++ b/test/shell/lock-blocking.sh
@@ -13,8 +13,10 @@ test_description='test some blocking / non-blocking multi-vg operations'
. lib/inittest
-aux prepare_devs 3
+test -e LOCAL_LVMPOLLD && skip
test -e LOCAL_CLVMD && skip
+
+aux prepare_devs 3
pvcreate "$dev1" "$dev2"
vgcreate $vg "$dev1" "$dev2"
diff --git a/test/shell/lock-parallel.sh b/test/shell/lock-parallel.sh
index 98d3d4c..ebe6336 100644
--- a/test/shell/lock-parallel.sh
+++ b/test/shell/lock-parallel.sh
@@ -14,6 +14,8 @@
. lib/inittest
+test -e LOCAL_LVMPOLLD && skip
+
which mkfs.ext3 || skip
which fsck || skip
diff --git a/test/shell/lvchange-cache.sh b/test/shell/lvchange-cache.sh
index 20826fb..9ce0314 100644
--- a/test/shell/lvchange-cache.sh
+++ b/test/shell/lvchange-cache.sh
@@ -11,6 +11,8 @@
. lib/inittest
+test -e LOCAL_LVMPOLLD && skip
+
aux have_cache 1 3 0 || skip
aux prepare_vg 3
diff --git a/test/shell/lvchange-mirror.sh b/test/shell/lvchange-mirror.sh
index f28e486..bd4c868 100644
--- a/test/shell/lvchange-mirror.sh
+++ b/test/shell/lvchange-mirror.sh
@@ -11,6 +11,8 @@
. lib/inittest
+test -e LOCAL_LVMPOLLD && skip
+
# FIXME RESYNC doesn't work in cluster with exclusive activation
# seriously broken!
test -e LOCAL_CLVMD && skip
diff --git a/test/shell/lvchange-partial-raid10.sh b/test/shell/lvchange-partial-raid10.sh
index 8014abd..d83d193 100644
--- a/test/shell/lvchange-partial-raid10.sh
+++ b/test/shell/lvchange-partial-raid10.sh
@@ -11,6 +11,8 @@
. lib/inittest
+test -e LOCAL_LVMPOLLD && skip
+
aux have_raid 1 3 2 || skip
aux prepare_vg 4
diff --git a/test/shell/lvchange-partial.sh b/test/shell/lvchange-partial.sh
index c65c07b..7b1f68d 100644
--- a/test/shell/lvchange-partial.sh
+++ b/test/shell/lvchange-partial.sh
@@ -11,6 +11,7 @@
. lib/inittest
+test -e LOCAL_LVMPOLLD && skip
aux prepare_vg 4
diff --git a/test/shell/lvchange-raid10.sh b/test/shell/lvchange-raid10.sh
index 0d17928..574ac7d 100644
--- a/test/shell/lvchange-raid10.sh
+++ b/test/shell/lvchange-raid10.sh
@@ -13,6 +13,8 @@ TEST_RAID=raid10
. shell/lvchange-raid.sh
+test -e LOCAL_LVMPOLLD && skip
+
aux have_raid 1 5 2 || skip
run_types raid10 -m 1 -i 2 "$dev1" "$dev2" "$dev3" "$dev4"
diff --git a/test/shell/lvchange-raid456.sh b/test/shell/lvchange-raid456.sh
index b1dd1db..bdce2e6 100644
--- a/test/shell/lvchange-raid456.sh
+++ b/test/shell/lvchange-raid456.sh
@@ -13,6 +13,8 @@ TEST_RAID=raid456
. shell/lvchange-raid.sh
+test -e LOCAL_LVMPOLLD && skip
+
aux raid456_replace_works || skip
aux have_raid 1 5 2 || skip
diff --git a/test/shell/lvchange-syncaction-raid.sh b/test/shell/lvchange-syncaction-raid.sh
index 9c51299..558157b 100644
--- a/test/shell/lvchange-syncaction-raid.sh
+++ b/test/shell/lvchange-syncaction-raid.sh
@@ -13,6 +13,8 @@
. lib/inittest
+test -e LOCAL_LVMPOLLD && skip
+
# Proper mismatch count 1.5.2+ upstream, 1.3.5 < x < 1.4.0 in RHEL6
aux have_raid 1 3 5 &&
! aux have_raid 1 4 0 ||
diff --git a/test/shell/lvchange-thin.sh b/test/shell/lvchange-thin.sh
index 87919bc..763bc34 100644
--- a/test/shell/lvchange-thin.sh
+++ b/test/shell/lvchange-thin.sh
@@ -11,6 +11,8 @@
. lib/inittest
+test -e LOCAL_LVMPOLLD && skip
+
aux have_thin 1 0 0 || skip
aux prepare_pvs 3
diff --git a/test/shell/lvconvert-cache-raid.sh b/test/shell/lvconvert-cache-raid.sh
index faab251..b8333d9 100644
--- a/test/shell/lvconvert-cache-raid.sh
+++ b/test/shell/lvconvert-cache-raid.sh
@@ -13,6 +13,8 @@
. lib/inittest
+test -e LOCAL_LVMPOLLD && skip
+
aux have_cache 1 3 0 || skip
aux have_raid 1 0 0 || skip
diff --git a/test/shell/lvconvert-cache-thin.sh b/test/shell/lvconvert-cache-thin.sh
index 87256a4..12b8dfe 100644
--- a/test/shell/lvconvert-cache-thin.sh
+++ b/test/shell/lvconvert-cache-thin.sh
@@ -13,6 +13,8 @@
. lib/inittest
+test -e LOCAL_LVMPOLLD && skip
+
aux have_cache 1 3 0 || skip
aux have_thin 1 0 0 || skip
diff --git a/test/shell/lvconvert-cache.sh b/test/shell/lvconvert-cache.sh
index ed414ed..6ac62c4 100644
--- a/test/shell/lvconvert-cache.sh
+++ b/test/shell/lvconvert-cache.sh
@@ -13,6 +13,8 @@
. lib/inittest
+test -e LOCAL_LVMPOLLD && skip
+
aux have_cache 1 3 0 || skip
aux prepare_vg 5 80
diff --git a/test/shell/lvconvert-raid-allocation.sh b/test/shell/lvconvert-raid-allocation.sh
index a1b1c39..f118d9c 100644
--- a/test/shell/lvconvert-raid-allocation.sh
+++ b/test/shell/lvconvert-raid-allocation.sh
@@ -11,6 +11,8 @@
. lib/inittest
+test -e LOCAL_LVMPOLLD && skip
+
aux have_raid 1 3 0 || skip
aux prepare_pvs 5
diff --git a/test/shell/lvconvert-raid.sh b/test/shell/lvconvert-raid.sh
index d3253eb..6529ee2 100644
--- a/test/shell/lvconvert-raid.sh
+++ b/test/shell/lvconvert-raid.sh
@@ -14,6 +14,8 @@ export LVM_TEST_LVMETAD_DEBUG_OPTS=${LVM_TEST_LVMETAD_DEBUG_OPTS-}
. lib/inittest
+test -e LOCAL_LVMPOLLD && skip
+
get_image_pvs() {
local d
local images
diff --git a/test/shell/lvconvert-raid10.sh b/test/shell/lvconvert-raid10.sh
index c4b92f1..244a79e 100644
--- a/test/shell/lvconvert-raid10.sh
+++ b/test/shell/lvconvert-raid10.sh
@@ -11,6 +11,8 @@
. lib/inittest
+test -e LOCAL_LVMPOLLD && skip
+
get_image_pvs() {
local d
local images
diff --git a/test/shell/lvconvert-raid456.sh b/test/shell/lvconvert-raid456.sh
index 833b10e..0fb5a5b 100644
--- a/test/shell/lvconvert-raid456.sh
+++ b/test/shell/lvconvert-raid456.sh
@@ -11,6 +11,8 @@
. lib/inittest
+test -e LOCAL_LVMPOLLD && skip
+
get_image_pvs() {
local d
local images
diff --git a/test/shell/lvconvert-repair-dmeventd.sh b/test/shell/lvconvert-repair-dmeventd.sh
index eed0819..2acf461 100644
--- a/test/shell/lvconvert-repair-dmeventd.sh
+++ b/test/shell/lvconvert-repair-dmeventd.sh
@@ -11,6 +11,8 @@
. lib/inittest
+test -e LOCAL_LVMPOLLD && skip
+
which mkfs.ext2 || skip
aux mirror_recovery_works || skip
diff --git a/test/shell/lvconvert-repair-raid-dmeventd.sh b/test/shell/lvconvert-repair-raid-dmeventd.sh
index eeb424e..df55449 100644
--- a/test/shell/lvconvert-repair-raid-dmeventd.sh
+++ b/test/shell/lvconvert-repair-raid-dmeventd.sh
@@ -11,6 +11,8 @@
. lib/inittest
+test -e LOCAL_LVMPOLLD && skip
+
which mkfs.ext3 || skip
aux have_raid 1 3 0 || skip
diff --git a/test/shell/lvconvert-repair-raid.sh b/test/shell/lvconvert-repair-raid.sh
index 6b1e51f..580516e 100644
--- a/test/shell/lvconvert-repair-raid.sh
+++ b/test/shell/lvconvert-repair-raid.sh
@@ -11,6 +11,8 @@
. lib/inittest
+test -e LOCAL_LVMPOLLD && skip
+
aux have_raid 1 3 0 || skip
aux raid456_replace_works || skip
diff --git a/test/shell/lvconvert-repair-snapshot.sh b/test/shell/lvconvert-repair-snapshot.sh
index a0c0399..1bb4138 100644
--- a/test/shell/lvconvert-repair-snapshot.sh
+++ b/test/shell/lvconvert-repair-snapshot.sh
@@ -11,6 +11,8 @@
. lib/inittest
+test -e LOCAL_LVMPOLLD && skip
+
aux prepare_vg 5
aux lvmconf 'allocation/maximise_cling = 0' \
'allocation/mirror_logs_require_separate_pvs = 1'
diff --git a/test/shell/lvconvert-repair-thin.sh b/test/shell/lvconvert-repair-thin.sh
index 73f061c..c699e12 100644
--- a/test/shell/lvconvert-repair-thin.sh
+++ b/test/shell/lvconvert-repair-thin.sh
@@ -14,6 +14,8 @@
. lib/inittest
+test -e LOCAL_LVMPOLLD && skip
+
which mkfs.ext2 || skip
#
diff --git a/test/shell/lvconvert-repair-transient-dmeventd.sh b/test/shell/lvconvert-repair-transient-dmeventd.sh
index 4f6171d..30fd47c 100644
--- a/test/shell/lvconvert-repair-transient-dmeventd.sh
+++ b/test/shell/lvconvert-repair-transient-dmeventd.sh
@@ -11,6 +11,8 @@
. lib/inittest
+test -e LOCAL_LVMPOLLD && skip
+
aux prepare_dmeventd
aux mirror_recovery_works || skip
aux prepare_vg 5
diff --git a/test/shell/lvconvert-repair-transient.sh b/test/shell/lvconvert-repair-transient.sh
index c9253f4..52e1825 100644
--- a/test/shell/lvconvert-repair-transient.sh
+++ b/test/shell/lvconvert-repair-transient.sh
@@ -11,6 +11,8 @@
. lib/inittest
+test -e LOCAL_LVMPOLLD && skip
+
aux mirror_recovery_works || skip
aux prepare_vg 5
diff --git a/test/shell/lvconvert-snapshot.sh b/test/shell/lvconvert-snapshot.sh
index 55fcb1a..ad500e2 100644
--- a/test/shell/lvconvert-snapshot.sh
+++ b/test/shell/lvconvert-snapshot.sh
@@ -14,6 +14,8 @@
. lib/inittest
+test -e LOCAL_LVMPOLLD && skip
+
aux prepare_pvs 1
vgcreate -s 1k $vg $(cat DEVICES)
diff --git a/test/shell/lvconvert-thin-external.sh b/test/shell/lvconvert-thin-external.sh
index 1e9887a..b688d3a 100644
--- a/test/shell/lvconvert-thin-external.sh
+++ b/test/shell/lvconvert-thin-external.sh
@@ -14,6 +14,8 @@
. lib/inittest
+test -e LOCAL_LVMPOLLD && skip
+
which mkfs.ext2 || skip
which fsck || skip
diff --git a/test/shell/lvconvert-thin-raid.sh b/test/shell/lvconvert-thin-raid.sh
index 3d7eee5..8b4052c 100644
--- a/test/shell/lvconvert-thin-raid.sh
+++ b/test/shell/lvconvert-thin-raid.sh
@@ -12,6 +12,8 @@
. lib/inittest
+test -e LOCAL_LVMPOLLD && skip
+
aux have_thin 1 0 0 || skip
aux have_raid 1 4 0 || skip
diff --git a/test/shell/lvconvert-thin.sh b/test/shell/lvconvert-thin.sh
index 951f694..b510589 100644
--- a/test/shell/lvconvert-thin.sh
+++ b/test/shell/lvconvert-thin.sh
@@ -12,6 +12,8 @@
. lib/inittest
+test -e LOCAL_LVMPOLLD && skip
+
prepare_lvs() {
lvremove -f $vg
lvcreate -L10M -n $lv1 $vg
diff --git a/test/shell/lvcreate-cache.sh b/test/shell/lvcreate-cache.sh
index 89efc4d..9e245c6 100644
--- a/test/shell/lvcreate-cache.sh
+++ b/test/shell/lvcreate-cache.sh
@@ -16,6 +16,8 @@
. lib/inittest
+test -e LOCAL_LVMPOLLD && skip
+
aux have_cache 1 3 0 || skip
# FIXME: parallel cache metadata allocator is crashing when used value 8000!
diff --git a/test/shell/lvcreate-large-raid.sh b/test/shell/lvcreate-large-raid.sh
index 182b267..c59eded 100644
--- a/test/shell/lvcreate-large-raid.sh
+++ b/test/shell/lvcreate-large-raid.sh
@@ -13,6 +13,8 @@
. lib/inittest
+test -e LOCAL_LVMPOLLD && skip
+
# FIXME update test to make something useful on <16T
aux can_use_16T || skip
diff --git a/test/shell/lvcreate-large-raid10.sh b/test/shell/lvcreate-large-raid10.sh
index de1cc02..47dda2b 100644
--- a/test/shell/lvcreate-large-raid10.sh
+++ b/test/shell/lvcreate-large-raid10.sh
@@ -13,6 +13,8 @@
. lib/inittest
+test -e LOCAL_LVMPOLLD && skip
+
# FIXME update test to make something useful on <16T
aux can_use_16T || skip
diff --git a/test/shell/lvcreate-large.sh b/test/shell/lvcreate-large.sh
index 29bdd33..e547fcc 100644
--- a/test/shell/lvcreate-large.sh
+++ b/test/shell/lvcreate-large.sh
@@ -13,6 +13,8 @@
. lib/inittest
+test -e LOCAL_LVMPOLLD && skip
+
# FIXME update test to make something useful on <16T
aux can_use_16T || skip
diff --git a/test/shell/lvcreate-mirror.sh b/test/shell/lvcreate-mirror.sh
index f62bee7..275c036 100644
--- a/test/shell/lvcreate-mirror.sh
+++ b/test/shell/lvcreate-mirror.sh
@@ -10,6 +10,9 @@
# Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
. lib/inittest
+
+test -e LOCAL_LVMPOLLD && skip
+
aux prepare_vg 5 80
aux lvmconf 'allocation/maximise_cling = 0' \
'allocation/mirror_logs_require_separate_pvs = 1'
diff --git a/test/shell/lvcreate-missing.sh b/test/shell/lvcreate-missing.sh
index 4553e98..012962f 100644
--- a/test/shell/lvcreate-missing.sh
+++ b/test/shell/lvcreate-missing.sh
@@ -11,6 +11,8 @@
. lib/inittest
+test -e LOCAL_LVMPOLLD && skip
+
aux prepare_vg 2
aux disable_dev "$dev1"
diff --git a/test/shell/lvcreate-operation.sh b/test/shell/lvcreate-operation.sh
index fac7219..3947bf8 100644
--- a/test/shell/lvcreate-operation.sh
+++ b/test/shell/lvcreate-operation.sh
@@ -13,6 +13,8 @@
. lib/inittest
+test -e LOCAL_LVMPOLLD && skip
+
cleanup_lvs() {
lvremove -ff $vg
(dm_table | not grep $vg) || \
diff --git a/test/shell/lvcreate-pvtags.sh b/test/shell/lvcreate-pvtags.sh
index 6bfb55b..99a7f07 100644
--- a/test/shell/lvcreate-pvtags.sh
+++ b/test/shell/lvcreate-pvtags.sh
@@ -11,6 +11,8 @@
. lib/inittest
+test -e LOCAL_LVMPOLLD && skip
+
aux prepare_pvs 3
aux lvmconf 'allocation/maximise_cling = 0' \
'allocation/mirror_logs_require_separate_pvs = 1'
diff --git a/test/shell/lvcreate-raid.sh b/test/shell/lvcreate-raid.sh
index 956ebb5..2ddc7e3 100644
--- a/test/shell/lvcreate-raid.sh
+++ b/test/shell/lvcreate-raid.sh
@@ -11,6 +11,8 @@
. lib/inittest
+test -e LOCAL_LVMPOLLD && skip
+
lv_devices() {
test $3 -eq $(get lv_devices $1/$2 | wc -w)
}
diff --git a/test/shell/lvcreate-raid10.sh b/test/shell/lvcreate-raid10.sh
index 5f22a2d..884653b 100644
--- a/test/shell/lvcreate-raid10.sh
+++ b/test/shell/lvcreate-raid10.sh
@@ -11,6 +11,8 @@
. lib/inittest
+test -e LOCAL_LVMPOLLD && skip
+
lv_devices() {
test $3 -eq $(get lv_devices $1/$2 | wc -w)
}
diff --git a/test/shell/lvcreate-repair.sh b/test/shell/lvcreate-repair.sh
index 1690565..469bf39 100644
--- a/test/shell/lvcreate-repair.sh
+++ b/test/shell/lvcreate-repair.sh
@@ -11,6 +11,8 @@
. lib/inittest
+test -e LOCAL_LVMPOLLD && skip
+
aux prepare_vg 3
# fail multiple devices
diff --git a/test/shell/lvcreate-signature-wiping.sh b/test/shell/lvcreate-signature-wiping.sh
index 32ef363..d2d23c5 100644
--- a/test/shell/lvcreate-signature-wiping.sh
+++ b/test/shell/lvcreate-signature-wiping.sh
@@ -13,6 +13,8 @@
. lib/inittest
+test -e LOCAL_LVMPOLLD && skip
+
init_lv_() {
mkswap "$DM_DEV_DIR/$vg/$lv1"
}
diff --git a/test/shell/lvcreate-small-snap.sh b/test/shell/lvcreate-small-snap.sh
index b29c5f8..b5610c7 100644
--- a/test/shell/lvcreate-small-snap.sh
+++ b/test/shell/lvcreate-small-snap.sh
@@ -11,6 +11,8 @@
. lib/inittest
+test -e LOCAL_LVMPOLLD && skip
+
aux prepare_pvs
vgcreate -s 1k $vg $(cat DEVICES)
diff --git a/test/shell/lvcreate-striped-mirror.sh b/test/shell/lvcreate-striped-mirror.sh
index eaa7fb8..735b396 100644
--- a/test/shell/lvcreate-striped-mirror.sh
+++ b/test/shell/lvcreate-striped-mirror.sh
@@ -11,6 +11,8 @@
. lib/inittest
+test -e LOCAL_LVMPOLLD && skip
+
aux prepare_vg 9
lvcreate -aey --nosync -i2 -l2 --type mirror -m1 --mirrorlog core -n $lv1 $vg 2>&1 | tee log
diff --git a/test/shell/lvcreate-thin-big.sh b/test/shell/lvcreate-thin-big.sh
index 1a8fa30..0ef5cbc 100644
--- a/test/shell/lvcreate-thin-big.sh
+++ b/test/shell/lvcreate-thin-big.sh
@@ -15,6 +15,8 @@
. lib/inittest
+test -e LOCAL_LVMPOLLD && skip
+
aux have_thin 1 0 0 || skip
# Test --poolmetadatasize range
diff --git a/test/shell/lvcreate-thin-external.sh b/test/shell/lvcreate-thin-external.sh
index 65401fb..bb5cef2 100644
--- a/test/shell/lvcreate-thin-external.sh
+++ b/test/shell/lvcreate-thin-external.sh
@@ -14,6 +14,8 @@
. lib/inittest
+test -e LOCAL_LVMPOLLD && skip
+
which mkfs.ext2 || skip
which fsck || skip
diff --git a/test/shell/lvcreate-thin-power2.sh b/test/shell/lvcreate-thin-power2.sh
index ed62db3..fcae643 100644
--- a/test/shell/lvcreate-thin-power2.sh
+++ b/test/shell/lvcreate-thin-power2.sh
@@ -15,6 +15,8 @@
. lib/inittest
+test -e LOCAL_LVMPOLLD && skip
+
#
# Main
#
diff --git a/test/shell/lvcreate-thin-snap.sh b/test/shell/lvcreate-thin-snap.sh
index 784eb5d..d801d4a 100644
--- a/test/shell/lvcreate-thin-snap.sh
+++ b/test/shell/lvcreate-thin-snap.sh
@@ -12,6 +12,8 @@
. lib/inittest
+test -e LOCAL_LVMPOLLD && skip
+
check_lv_field_modules_()
{
mod=$1
diff --git a/test/shell/lvcreate-thin.sh b/test/shell/lvcreate-thin.sh
index 66d986b..18e4644 100644
--- a/test/shell/lvcreate-thin.sh
+++ b/test/shell/lvcreate-thin.sh
@@ -15,6 +15,8 @@
. lib/inittest
+test -e LOCAL_LVMPOLLD && skip
+
check_lv_field_modules_()
{
mod=$1
diff --git a/test/shell/lvextend-percent-extents.sh b/test/shell/lvextend-percent-extents.sh
index 9b5dc5d..ec98e59 100644
--- a/test/shell/lvextend-percent-extents.sh
+++ b/test/shell/lvextend-percent-extents.sh
@@ -13,6 +13,8 @@
. lib/inittest
+test -e LOCAL_LVMPOLLD && skip
+
aux prepare_pvs 2 128
vgcreate $vg $(cat DEVICES)
diff --git a/test/shell/lvextend-snapshot-dmeventd.sh b/test/shell/lvextend-snapshot-dmeventd.sh
index f073a81..1ad4864 100644
--- a/test/shell/lvextend-snapshot-dmeventd.sh
+++ b/test/shell/lvextend-snapshot-dmeventd.sh
@@ -11,6 +11,8 @@
. lib/inittest
+test -e LOCAL_LVMPOLLD && skip
+
extend() {
lvextend --use-policies --config "activation { snapshot_autoextend_threshold = $1 }" $vg/snap
}
diff --git a/test/shell/lvextend-snapshot-policy.sh b/test/shell/lvextend-snapshot-policy.sh
index b0a611e..c76e36e 100644
--- a/test/shell/lvextend-snapshot-policy.sh
+++ b/test/shell/lvextend-snapshot-policy.sh
@@ -11,6 +11,8 @@
. lib/inittest
+test -e LOCAL_LVMPOLLD && skip
+
which mkfs.ext2 || skip
extend() {
diff --git a/test/shell/lvextend-thin-metadata-dmeventd.sh b/test/shell/lvextend-thin-metadata-dmeventd.sh
index d7be3a2..78dce6d 100644
--- a/test/shell/lvextend-thin-metadata-dmeventd.sh
+++ b/test/shell/lvextend-thin-metadata-dmeventd.sh
@@ -12,6 +12,8 @@
# Test autoextension of thin metadata volume
. lib/inittest
+test -e LOCAL_LVMPOLLD && skip
+
meta_percent_() {
get lv_field $vg/pool metadata_percent | cut -d. -f1
}
diff --git a/test/shell/lvextend-thin.sh b/test/shell/lvextend-thin.sh
index f9e24ce..ab538a7 100644
--- a/test/shell/lvextend-thin.sh
+++ b/test/shell/lvextend-thin.sh
@@ -11,6 +11,8 @@
. lib/inittest
+test -e LOCAL_LVMPOLLD && skip
+
aux have_thin 1 0 0 || skip
aux prepare_vg 3
diff --git a/test/shell/lvm-init.sh b/test/shell/lvm-init.sh
index c3f7ecf..cfdd4cc 100644
--- a/test/shell/lvm-init.sh
+++ b/test/shell/lvm-init.sh
@@ -15,6 +15,8 @@
. lib/inittest
+test -e LOCAL_LVMPOLLD && skip
+
aux prepare_devs 5
# invalid units
diff --git a/test/shell/lvmcache-exercise.sh b/test/shell/lvmcache-exercise.sh
index 2aaf650..f0d3ee9 100644
--- a/test/shell/lvmcache-exercise.sh
+++ b/test/shell/lvmcache-exercise.sh
@@ -11,6 +11,8 @@
. lib/inittest
+test -e LOCAL_LVMPOLLD && skip
+
aux prepare_pvs 5
vgcreate $vg1 "$dev1"
diff --git a/test/shell/lvmetad-ambiguous.sh b/test/shell/lvmetad-ambiguous.sh
index 2e7c6c5..777a63e 100644
--- a/test/shell/lvmetad-ambiguous.sh
+++ b/test/shell/lvmetad-ambiguous.sh
@@ -12,6 +12,7 @@
. lib/inittest
test -e LOCAL_LVMETAD || skip
+test -e LOCAL_LVMPOLLD && skip
aux prepare_pvs 2
diff --git a/test/shell/lvmetad-client-filter.sh b/test/shell/lvmetad-client-filter.sh
index 3002a47..5e6d967 100644
--- a/test/shell/lvmetad-client-filter.sh
+++ b/test/shell/lvmetad-client-filter.sh
@@ -12,6 +12,8 @@
. lib/inittest
test -e LOCAL_LVMETAD || skip
+test -e LOCAL_LVMPOLLD && skip
+
aux prepare_pvs 2
pvs --config 'devices { filter = [ "r%.*%" ] }' 2>&1 | grep rejected
diff --git a/test/shell/lvmetad-disabled.sh b/test/shell/lvmetad-disabled.sh
index efdca16..9c71717 100644
--- a/test/shell/lvmetad-disabled.sh
+++ b/test/shell/lvmetad-disabled.sh
@@ -12,6 +12,8 @@
. lib/inittest
test -e LOCAL_LVMETAD || skip
+test -e LOCAL_LVMPOLLD && skip
+
kill $(< LOCAL_LVMETAD)
while test -e "$TESTDIR/lvmetad.socket"; do echo -n .; sleep .1; done # wait for the socket close
test ! -e "$LVM_LVMETAD_PIDFILE"
diff --git a/test/shell/lvmetad-dump.sh b/test/shell/lvmetad-dump.sh
index 14d5753..631636e 100644
--- a/test/shell/lvmetad-dump.sh
+++ b/test/shell/lvmetad-dump.sh
@@ -10,7 +10,9 @@
# Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
. lib/inittest
+
test -e LOCAL_LVMETAD || skip
+test -e LOCAL_LVMPOLLD && skip
aux prepare_pvs 2
vgcreate $vg1 "$dev1" "$dev2"
diff --git a/test/shell/lvmetad-lvm1.sh b/test/shell/lvmetad-lvm1.sh
index f071b14..f234b15 100644
--- a/test/shell/lvmetad-lvm1.sh
+++ b/test/shell/lvmetad-lvm1.sh
@@ -12,6 +12,8 @@
. lib/inittest
test -e LOCAL_LVMETAD || skip
+test -e LOCAL_LVMPOLLD && skip
+
aux prepare_devs 2
pvcreate --metadatatype 1 "$dev1"
should vgscan --cache
diff --git a/test/shell/lvmetad-lvscan-cache.sh b/test/shell/lvmetad-lvscan-cache.sh
index 1d9d8a4..220e464 100644
--- a/test/shell/lvmetad-lvscan-cache.sh
+++ b/test/shell/lvmetad-lvscan-cache.sh
@@ -12,6 +12,7 @@
. lib/inittest
test -e LOCAL_LVMETAD || skip
+test -e LOCAL_LVMPOLLD && skip
aux prepare_pvs 2
diff --git a/test/shell/lvmetad-no-cluster.sh b/test/shell/lvmetad-no-cluster.sh
index 85c1ea9..83fee47 100644
--- a/test/shell/lvmetad-no-cluster.sh
+++ b/test/shell/lvmetad-no-cluster.sh
@@ -12,6 +12,8 @@
. lib/inittest
test -e LOCAL_CLVMD || skip
+test -e LOCAL_LVMPOLLD && skip
+
aux prepare_vg 2
aux prepare_lvmetad
vgs -vv 2> errs
diff --git a/test/shell/lvmetad-override.sh b/test/shell/lvmetad-override.sh
index ea76b35..15ada7b 100644
--- a/test/shell/lvmetad-override.sh
+++ b/test/shell/lvmetad-override.sh
@@ -12,6 +12,8 @@
. lib/inittest
test -e LOCAL_LVMETAD || skip
+test -e LOCAL_LVMPOLLD && skip
+
aux prepare_pvs 2
vgcreate $vg1 "$dev1" "$dev2"
diff --git a/test/shell/lvmetad-pvs.sh b/test/shell/lvmetad-pvs.sh
index 7f25490..81174f4 100644
--- a/test/shell/lvmetad-pvs.sh
+++ b/test/shell/lvmetad-pvs.sh
@@ -11,6 +11,8 @@
. lib/inittest
+test -e LOCAL_LVMPOLLD && skip
+
aux prepare_pvs 1 20000
pvs $(cat DEVICES) | grep "$dev1"
diff --git a/test/shell/lvmetad-pvscan-cache.sh b/test/shell/lvmetad-pvscan-cache.sh
index 75890a5..33b4d94 100644
--- a/test/shell/lvmetad-pvscan-cache.sh
+++ b/test/shell/lvmetad-pvscan-cache.sh
@@ -12,6 +12,7 @@
. lib/inittest
test -e LOCAL_LVMETAD || skip
+test -e LOCAL_LVMPOLLD && skip
aux prepare_pvs 2
diff --git a/test/shell/lvmetad-pvscan-filter.sh b/test/shell/lvmetad-pvscan-filter.sh
index 05666df..b7bdf33 100644
--- a/test/shell/lvmetad-pvscan-filter.sh
+++ b/test/shell/lvmetad-pvscan-filter.sh
@@ -12,6 +12,7 @@
. lib/inittest
test -e LOCAL_LVMETAD || skip
+test -e LOCAL_LVMPOLLD && skip
aux prepare_pvs 2
diff --git a/test/shell/lvmetad-pvscan-md.sh b/test/shell/lvmetad-pvscan-md.sh
index bfa6171..9c5e3fa 100644
--- a/test/shell/lvmetad-pvscan-md.sh
+++ b/test/shell/lvmetad-pvscan-md.sh
@@ -12,6 +12,7 @@
. lib/inittest
test -e LOCAL_LVMETAD || skip
+test -e LOCAL_LVMPOLLD && skip
test -f /proc/mdstat && grep -q raid0 /proc/mdstat || \
modprobe raid0 || skip
diff --git a/test/shell/lvmetad-pvscan-nomda.sh b/test/shell/lvmetad-pvscan-nomda.sh
index 395e326..f7e13a7 100644
--- a/test/shell/lvmetad-pvscan-nomda.sh
+++ b/test/shell/lvmetad-pvscan-nomda.sh
@@ -12,6 +12,8 @@
. lib/inittest
test -e LOCAL_LVMETAD || skip
+test -e LOCAL_LVMPOLLD && skip
+
kill $(< LOCAL_LVMETAD)
rm LOCAL_LVMETAD
diff --git a/test/shell/lvmetad-restart.sh b/test/shell/lvmetad-restart.sh
index e4136df..8805bc8 100644
--- a/test/shell/lvmetad-restart.sh
+++ b/test/shell/lvmetad-restart.sh
@@ -12,6 +12,8 @@
. lib/inittest
test -e LOCAL_LVMETAD || skip
+test -e LOCAL_LVMPOLLD && skip
+
aux prepare_pvs 2
vgcreate $vg1 "$dev1" "$dev2"
diff --git a/test/shell/lvmetad-test.sh b/test/shell/lvmetad-test.sh
index 6ebd9ad..146a7f1 100644
--- a/test/shell/lvmetad-test.sh
+++ b/test/shell/lvmetad-test.sh
@@ -11,6 +11,8 @@
. lib/inittest
+test -e LOCAL_LVMPOLLD && skip
+
aux prepare_pvs 2
vgcreate $vg1 "$dev1" "$dev2" --test
diff --git a/test/shell/lvmetad-warning.sh b/test/shell/lvmetad-warning.sh
index 52bd885..44edb12 100644
--- a/test/shell/lvmetad-warning.sh
+++ b/test/shell/lvmetad-warning.sh
@@ -12,6 +12,8 @@
. lib/inittest
test -e LOCAL_LVMETAD || skip
+test -e LOCAL_LVMPOLLD && skip
+
aux prepare_pvs 2
vgcreate $vg1 "$dev1" "$dev2"
diff --git a/test/shell/lvresize-mirror.sh b/test/shell/lvresize-mirror.sh
index 0b9f526..423c9ed 100644
--- a/test/shell/lvresize-mirror.sh
+++ b/test/shell/lvresize-mirror.sh
@@ -11,6 +11,8 @@
. lib/inittest
+test -e LOCAL_LVMPOLLD && skip
+
aux prepare_vg 5
for deactivate in true false; do
diff --git a/test/shell/lvresize-raid.sh b/test/shell/lvresize-raid.sh
index 8c7d909..1a1a75f 100644
--- a/test/shell/lvresize-raid.sh
+++ b/test/shell/lvresize-raid.sh
@@ -11,6 +11,8 @@
. lib/inittest
+test -e LOCAL_LVMPOLLD && skip
+
aux have_raid 1 3 0 || skip
aux prepare_pvs 6 80
diff --git a/test/shell/lvresize-raid10.sh b/test/shell/lvresize-raid10.sh
index aead385..4fe49f6 100644
--- a/test/shell/lvresize-raid10.sh
+++ b/test/shell/lvresize-raid10.sh
@@ -11,6 +11,8 @@
. lib/inittest
+test -e LOCAL_LVMPOLLD && skip
+
aux have_raid 1 3 0 || skip
aux prepare_vg 5
diff --git a/test/shell/lvresize-rounding.sh b/test/shell/lvresize-rounding.sh
index 5c30539..398740e 100644
--- a/test/shell/lvresize-rounding.sh
+++ b/test/shell/lvresize-rounding.sh
@@ -11,6 +11,8 @@
. lib/inittest
+test -e LOCAL_LVMPOLLD && skip
+
aux prepare_pvs 3 22
vgcreate -s 32K $vg $(cat DEVICES)
diff --git a/test/shell/lvresize-thin-external-origin.sh b/test/shell/lvresize-thin-external-origin.sh
index e4463e2..82b7f8b 100644
--- a/test/shell/lvresize-thin-external-origin.sh
+++ b/test/shell/lvresize-thin-external-origin.sh
@@ -12,6 +12,8 @@
# Test resize of thin volume with external origin
. lib/inittest
+test -e LOCAL_LVMPOLLD && skip
+
aux have_thin 1 2 0 || skip
# Pretend we miss the external_origin_extend feature
diff --git a/test/shell/lvresize-thin-metadata.sh b/test/shell/lvresize-thin-metadata.sh
index 9e2ae4d..4416b67 100644
--- a/test/shell/lvresize-thin-metadata.sh
+++ b/test/shell/lvresize-thin-metadata.sh
@@ -11,6 +11,8 @@
. lib/inittest
+test -e LOCAL_LVMPOLLD && skip
+
aux have_thin 1 10 0 || skip
aux prepare_pvs 3 1256
diff --git a/test/shell/lvresize-usage.sh b/test/shell/lvresize-usage.sh
index a3ba2cf..00bae14 100644
--- a/test/shell/lvresize-usage.sh
+++ b/test/shell/lvresize-usage.sh
@@ -11,6 +11,8 @@
. lib/inittest
+test -e LOCAL_LVMPOLLD && skip
+
aux prepare_vg 2 80
lvcreate -L 10M -n lv -i2 $vg
diff --git a/test/shell/lvs-cache.sh b/test/shell/lvs-cache.sh
index 08e83bd..73706b7 100644
--- a/test/shell/lvs-cache.sh
+++ b/test/shell/lvs-cache.sh
@@ -16,6 +16,8 @@
. lib/inittest
+test -e LOCAL_LVMPOLLD && skip
+
aux have_cache 1 3 0 || skip
aux prepare_vg 5 8000
diff --git a/test/shell/mda-rollback.sh b/test/shell/mda-rollback.sh
index fa8e376..5f348fb 100644
--- a/test/shell/mda-rollback.sh
+++ b/test/shell/mda-rollback.sh
@@ -11,6 +11,8 @@
. lib/inittest
+test -e LOCAL_LVMPOLLD && skip
+
aux prepare_devs 3
vgcreate --metadatasize 128k $vg1 "$dev1" "$dev2" "$dev3"
diff --git a/test/shell/mdata-strings.sh b/test/shell/mdata-strings.sh
index a1598ad..529e599 100644
--- a/test/shell/mdata-strings.sh
+++ b/test/shell/mdata-strings.sh
@@ -13,6 +13,8 @@
. lib/inittest
+test -e LOCAL_LVMPOLLD && skip
+
# For udev impossible to create
test "$LVM_TEST_DEVDIR" = "/dev" && skip
diff --git a/test/shell/metadata-balance.sh b/test/shell/metadata-balance.sh
index 5ee0eba..869297e 100644
--- a/test/shell/metadata-balance.sh
+++ b/test/shell/metadata-balance.sh
@@ -11,6 +11,8 @@
. lib/inittest
+test -e LOCAL_LVMPOLLD && skip
+
aux prepare_devs 6
echo Make sure we can ignore / un-ignore mdas on a per-PV basis
diff --git a/test/shell/metadata-dirs.sh b/test/shell/metadata-dirs.sh
index f4a41bc..eed6512 100644
--- a/test/shell/metadata-dirs.sh
+++ b/test/shell/metadata-dirs.sh
@@ -11,6 +11,8 @@
. lib/inittest
+test -e LOCAL_LVMPOLLD && skip
+
aux prepare_devs 3
pvcreate --metadatacopies 0 $(cat DEVICES)
diff --git a/test/shell/metadata.sh b/test/shell/metadata.sh
index 251942f..8e3503f 100644
--- a/test/shell/metadata.sh
+++ b/test/shell/metadata.sh
@@ -11,6 +11,8 @@
. lib/inittest
+test -e LOCAL_LVMPOLLD && skip
+
aux prepare_devs 5
pvcreate "$dev1"
diff --git a/test/shell/mirror-names.sh b/test/shell/mirror-names.sh
index aa640c2..22372e1 100644
--- a/test/shell/mirror-names.sh
+++ b/test/shell/mirror-names.sh
@@ -42,6 +42,22 @@ lv_convert_lv_() {
get lv_field $1 convert_lv
}
+enable_devs() {
+ aux enable_dev "$dev1"
+ aux enable_dev "$dev2"
+ aux enable_dev "$dev3"
+ aux enable_dev "$dev4"
+ aux enable_dev "$dev5"
+}
+
+delay_devs() {
+ aux delay_dev "$dev1" 0 1000 $(get first_extent_sector "$dev1"):
+ aux delay_dev "$dev2" 0 1000 $(get first_extent_sector "$dev2"):
+ aux delay_dev "$dev3" 0 1000 $(get first_extent_sector "$dev3"):
+ aux delay_dev "$dev4" 0 1000 $(get first_extent_sector "$dev4"):
+ aux delay_dev "$dev5" 0 1000 $(get first_extent_sector "$dev5"):
+}
+
# ---------------------------------------------------------------------
# Common environment setup/cleanup for each sub testcases
@@ -101,12 +117,14 @@ check_and_cleanup_lvs_
#COMM "converting mirror names is ${lv1}_mimagetmp_2"
lvcreate -aey -l2 --type mirror -m1 -n $lv1 $vg
+delay_devs
LVM_TEST_TAG="kill_me_$PREFIX" lvconvert -m+1 -i+40 -b $vg/$lv1
convlv=$(lv_convert_lv_ $vg/$lv1)
test $convlv = ${lv1}_mimagetmp_2
lv_devices_ $vg/$lv1 $convlv ${lv1}_mimage_2
lv_devices_ $vg/$convlv ${lv1}_mimage_0 ${lv1}_mimage_1
lv_mirror_log_ $vg/$convlv ${lv1}_mlog
+enable_devs
#COMM "mirror log name after re-adding is ${lv1}_mlog" \
lvconvert -f --mirrorlog core $vg/$lv1
diff --git a/test/shell/mirror-vgreduce-removemissing.sh b/test/shell/mirror-vgreduce-removemissing.sh
index e4791f8..40a6503 100644
--- a/test/shell/mirror-vgreduce-removemissing.sh
+++ b/test/shell/mirror-vgreduce-removemissing.sh
@@ -17,6 +17,8 @@ export LVM_TEST_LVMETAD_DEBUG_OPTS=${LVM_TEST_LVMETAD_DEBUG_OPTS-}
. lib/inittest
+test -e LOCAL_LVMPOLLD && skip
+
lv_is_on_ ()
{
local lv=$vg/$1
diff --git a/test/shell/name-mangling.sh b/test/shell/name-mangling.sh
index ee34994..6bdf4a1 100644
--- a/test/shell/name-mangling.sh
+++ b/test/shell/name-mangling.sh
@@ -15,6 +15,7 @@
# so skip duplicate CLMVD and lvmetad test
test -e LOCAL_CLVMD && skip
test -e LOCAL_LVMETAD && skip
+test -e LOCAL_LVMPOLLD && skip
CHARACTER_WHITELIST="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789#+-.:=@_"
FAIL_MIXED_STR="contains mixed mangled and unmangled characters"
diff --git a/test/shell/nomda-missing.sh b/test/shell/nomda-missing.sh
index 7de458b..39c2ac9 100644
--- a/test/shell/nomda-missing.sh
+++ b/test/shell/nomda-missing.sh
@@ -12,6 +12,8 @@
. lib/inittest
+test -e LOCAL_LVMPOLLD && skip
+
aux prepare_devs 4
pvcreate "$dev1" "$dev2"
pvcreate --metadatacopies 0 "$dev3" "$dev4"
diff --git a/test/shell/nomda-restoremissing.sh b/test/shell/nomda-restoremissing.sh
index 01a77d0..9380c8d 100644
--- a/test/shell/nomda-restoremissing.sh
+++ b/test/shell/nomda-restoremissing.sh
@@ -11,6 +11,8 @@
. lib/inittest
+test -e LOCAL_LVMPOLLD && skip
+
aux prepare_vg 3
pvchange --metadataignore y "$dev1"
diff --git a/test/shell/orphan-ondisk.sh b/test/shell/orphan-ondisk.sh
index 8395073..f4e18f4 100644
--- a/test/shell/orphan-ondisk.sh
+++ b/test/shell/orphan-ondisk.sh
@@ -11,5 +11,7 @@
. lib/inittest
+test -e LOCAL_LVMPOLLD && skip
+
aux prepare_vg 2
vgreduce $vg "$dev1" 2>&1 | not grep -i 'parse error'
diff --git a/test/shell/pool-labels.sh b/test/shell/pool-labels.sh
index a2163e8..70d5a64 100644
--- a/test/shell/pool-labels.sh
+++ b/test/shell/pool-labels.sh
@@ -13,6 +13,7 @@
# lvmetad does not handle pool labels so skip test.
test ! -e LOCAL_LVMETAD || skip
+test -e LOCAL_LVMPOLLD && skip
env printf "" || skip # skip if printf is not available
diff --git a/test/shell/process-each-duplicate-vgnames.sh b/test/shell/process-each-duplicate-vgnames.sh
index 9b1f807..f2b4765 100644
--- a/test/shell/process-each-duplicate-vgnames.sh
+++ b/test/shell/process-each-duplicate-vgnames.sh
@@ -9,6 +9,8 @@ test_description='Test vgs with duplicate vg names'
. lib/inittest
+test -e LOCAL_LVMPOLLD && skip
+
aux prepare_devs 2
pvcreate "$dev1"
diff --git a/test/shell/process-each-lv.sh b/test/shell/process-each-lv.sh
index bd9e042..78eb14e 100644
--- a/test/shell/process-each-lv.sh
+++ b/test/shell/process-each-lv.sh
@@ -16,6 +16,8 @@ export LVM_TEST_LVMETAD_DEBUG_OPTS=${LVM_TEST_LVMETAD_DEBUG_OPTS-}
. lib/inittest
+test -e LOCAL_LVMPOLLD && skip
+
aux prepare_devs 10
#
diff --git a/test/shell/process-each-pv-nomda-all.sh b/test/shell/process-each-pv-nomda-all.sh
index 44cde5a..1a2af58 100644
--- a/test/shell/process-each-pv-nomda-all.sh
+++ b/test/shell/process-each-pv-nomda-all.sh
@@ -13,6 +13,8 @@ test_description='Test process_each_pv with zero mda'
. lib/inittest
+test -e LOCAL_LVMPOLLD && skip
+
aux prepare_devs 14
# for vg1
diff --git a/test/shell/process-each-pv-nomda.sh b/test/shell/process-each-pv-nomda.sh
index 82e6bc4..642f2e4 100644
--- a/test/shell/process-each-pv-nomda.sh
+++ b/test/shell/process-each-pv-nomda.sh
@@ -13,6 +13,8 @@ test_description='Test process_each_pv with zero mda'
. lib/inittest
+test -e LOCAL_LVMPOLLD && skip
+
aux prepare_devs 2
pvcreate "$dev1" --metadatacopies 0
diff --git a/test/shell/process-each-pv.sh b/test/shell/process-each-pv.sh
index d3a1863..f4b8fd1 100644
--- a/test/shell/process-each-pv.sh
+++ b/test/shell/process-each-pv.sh
@@ -13,6 +13,8 @@ test_description='Exercise toollib process_each_pv'
. lib/inittest
+test -e LOCAL_LVMPOLLD && skip
+
aux prepare_devs 14
#
diff --git a/test/shell/process-each-pvresize.sh b/test/shell/process-each-pvresize.sh
index 02fe081..493c24b 100644
--- a/test/shell/process-each-pvresize.sh
+++ b/test/shell/process-each-pvresize.sh
@@ -13,6 +13,8 @@ test_description='Exercise toollib process_each_pv'
. lib/inittest
+test -e LOCAL_LVMPOLLD && skip
+
aux prepare_devs 14
#
diff --git a/test/shell/process-each-vg.sh b/test/shell/process-each-vg.sh
index e8690f5..f93acda 100644
--- a/test/shell/process-each-vg.sh
+++ b/test/shell/process-each-vg.sh
@@ -13,6 +13,8 @@ test_description='Exercise toollib process_each_vg'
. lib/inittest
+test -e LOCAL_LVMPOLLD && skip
+
aux prepare_devs 6
#
diff --git a/test/shell/profiles-thin.sh b/test/shell/profiles-thin.sh
index d3e282a..9578ed1 100644
--- a/test/shell/profiles-thin.sh
+++ b/test/shell/profiles-thin.sh
@@ -15,6 +15,8 @@
. lib/inittest
+test -e LOCAL_LVMPOLLD && skip
+
DEV_SIZE=32
# check we have thinp support compiled in
diff --git a/test/shell/profiles.sh b/test/shell/profiles.sh
index e054c88..8187129 100644
--- a/test/shell/profiles.sh
+++ b/test/shell/profiles.sh
@@ -15,6 +15,8 @@
. lib/inittest
+test -e LOCAL_LVMPOLLD && skip
+
MSG_FAILED_TO_APPLY_CMD_PROFILE="Failed to apply command profile"
MSG_IGNORING_INVALID_CMD_PROFILE="Ignoring invalid command profile"
MSG_FAILED_TO_APPLY_MDA_PROFILE="Failed to apply metadata profile"
diff --git a/test/shell/pv-duplicate-uuid.sh b/test/shell/pv-duplicate-uuid.sh
index 1763142..cc98384 100644
--- a/test/shell/pv-duplicate-uuid.sh
+++ b/test/shell/pv-duplicate-uuid.sh
@@ -12,6 +12,8 @@
# Test 'Found duplicate' is shown
. lib/inittest
+test -e LOCAL_LVMPOLLD && skip
+
aux prepare_devs 3
pvcreate "$dev1"
diff --git a/test/shell/pv-duplicate.sh b/test/shell/pv-duplicate.sh
index 9b218e6..ecd6125 100644
--- a/test/shell/pv-duplicate.sh
+++ b/test/shell/pv-duplicate.sh
@@ -13,6 +13,8 @@
. lib/inittest
+test -e LOCAL_LVMPOLLD && skip
+
aux prepare_devs 3
pvcreate "$dev1"
diff --git a/test/shell/pv-min-size.sh b/test/shell/pv-min-size.sh
index d29e94c..eb62c73 100644
--- a/test/shell/pv-min-size.sh
+++ b/test/shell/pv-min-size.sh
@@ -11,6 +11,8 @@
. lib/inittest
+test -e LOCAL_LVMPOLLD && skip
+
# use small default size - 512KB
aux lvmconf 'devices/pv_min_size = 512'
diff --git a/test/shell/pvchange-usage.sh b/test/shell/pvchange-usage.sh
index e5695b6..8cffb06 100644
--- a/test/shell/pvchange-usage.sh
+++ b/test/shell/pvchange-usage.sh
@@ -13,6 +13,8 @@
. lib/inittest
+test -e LOCAL_LVMPOLLD && skip
+
check_changed_uuid_() {
test "$1" != "$(get pv_field "$2" uuid)" || die "UUID has not changed!"
}
diff --git a/test/shell/pvcreate-bootloaderarea.sh b/test/shell/pvcreate-bootloaderarea.sh
index 6dd45f5..68c0882 100644
--- a/test/shell/pvcreate-bootloaderarea.sh
+++ b/test/shell/pvcreate-bootloaderarea.sh
@@ -13,6 +13,8 @@ test_description='Test pvcreate bootloader area support'
. lib/inittest
+test -e LOCAL_LVMPOLLD && skip
+
aux prepare_devs 1
aux lvmconf 'global/suffix=0' 'global/units="b"'
diff --git a/test/shell/pvcreate-ff.sh b/test/shell/pvcreate-ff.sh
index 1cbf0ff..4ac5a61 100644
--- a/test/shell/pvcreate-ff.sh
+++ b/test/shell/pvcreate-ff.sh
@@ -11,6 +11,8 @@
. lib/inittest
+test -e LOCAL_LVMPOLLD && skip
+
aux prepare_devs 2
pvcreate "$dev1"
vgcreate foo "$dev1"
diff --git a/test/shell/pvcreate-metadata0.sh b/test/shell/pvcreate-metadata0.sh
index 263bd88..48ebc83 100644
--- a/test/shell/pvcreate-metadata0.sh
+++ b/test/shell/pvcreate-metadata0.sh
@@ -17,6 +17,8 @@
. lib/inittest
+test -e LOCAL_LVMPOLLD && skip
+
aux prepare_devs 2 128
#lv_snap=$lv2
diff --git a/test/shell/pvcreate-operation-md.sh b/test/shell/pvcreate-operation-md.sh
index 8291215..db53216 100644
--- a/test/shell/pvcreate-operation-md.sh
+++ b/test/shell/pvcreate-operation-md.sh
@@ -11,6 +11,8 @@
. lib/inittest
+test -e LOCAL_LVMPOLLD && skip
+
# skip this test if mdadm or sfdisk (or others) aren't available
which sfdisk || skip
diff --git a/test/shell/pvcreate-operation.sh b/test/shell/pvcreate-operation.sh
index e72f2b9..6593877 100644
--- a/test/shell/pvcreate-operation.sh
+++ b/test/shell/pvcreate-operation.sh
@@ -10,6 +10,8 @@
. lib/inittest
+test -e LOCAL_LVMPOLLD && skip
+
aux lvmconf 'devices/md_component_detection = 1'
aux prepare_devs 4
diff --git a/test/shell/pvcreate-usage.sh b/test/shell/pvcreate-usage.sh
index 5e916c3..ed3b4f4 100644
--- a/test/shell/pvcreate-usage.sh
+++ b/test/shell/pvcreate-usage.sh
@@ -14,6 +14,8 @@ PAGESIZE=$(getconf PAGESIZE)
. lib/inittest
+test -e LOCAL_LVMPOLLD && skip
+
aux prepare_devs 4
#COMM 'pvcreate rejects negative setphysicalvolumesize'
diff --git a/test/shell/pvmove-restart.sh b/test/shell/pvmove-restart.sh
index 1ef9a24..4f93983 100644
--- a/test/shell/pvmove-restart.sh
+++ b/test/shell/pvmove-restart.sh
@@ -32,12 +32,16 @@ lvextend -l+10 $vg/$lv1 "$dev2"
lvextend -l+5 $vg/$lv1 "$dev1"
lvextend -l+10 $vg/$lv1 "$dev2"
-pvmove -i0 -n $vg/$lv1 "$dev1" "$dev3" $mode &
+pvmove -i10 -n $vg/$lv1 "$dev1" "$dev3" $mode &
PVMOVE=$!
# Let's wait a bit till pvmove starts and kill it
aux wait_pvmove_lv_ready "$vg-pvmove0"
-
kill -9 $PVMOVE
+
+if test -e LOCAL_LVMPOLLD; then
+ aux prepare_lvmpolld
+fi
+
wait
# Simulate reboot - forcibly remove related devices
diff --git a/test/shell/pvmove-resume-1.sh b/test/shell/pvmove-resume-1.sh
index acf35ee..e8564fa 100644
--- a/test/shell/pvmove-resume-1.sh
+++ b/test/shell/pvmove-resume-1.sh
@@ -107,26 +107,50 @@ lvchange_single() {
LVM_TEST_TAG="kill_me_$PREFIX" lvchange -aey $vg/$lv1
LVM_TEST_TAG="kill_me_$PREFIX" lvchange -aey $vg1/$lv1
- test $(aux count_processes_with_tag) -eq $1
+ if test -e LOCAL_LVMPOLLD; then
+ aux lvmpolld_dump | tee lvmpolld_dump.txt
+ aux check_lvmpolld_init_rq_count 1 "$vg/pvmove0"
+ aux check_lvmpolld_init_rq_count 1 "$vg1/pvmove0"
+ else
+ check_spawned_bg_procs_count $1
+ fi
}
lvchange_all() {
LVM_TEST_TAG="kill_me_$PREFIX" lvchange -aey $vg/$lv1 $vg1/$lv1
- test $(aux count_processes_with_tag) -eq $1
+ if test -e LOCAL_LVMPOLLD; then
+ aux lvmpolld_dump | tee lvmpolld_dump.txt
+ aux check_lvmpolld_init_rq_count 1 "$vg/pvmove0"
+ aux check_lvmpolld_init_rq_count 1 "$vg1/pvmove0"
+ else
+ test $(aux count_processes_with_tag) -eq $1
+ fi
}
vgchange_single() {
LVM_TEST_TAG="kill_me_$PREFIX" vgchange -aey $vg
LVM_TEST_TAG="kill_me_$PREFIX" vgchange -aey $vg1
- test $(aux count_processes_with_tag) -eq $1
+ if test -e LOCAL_LVMPOLLD; then
+ aux lvmpolld_dump | tee lvmpolld_dump.txt
+ aux check_lvmpolld_init_rq_count 1 "$vg/pvmove0"
+ aux check_lvmpolld_init_rq_count 1 "$vg1/pvmove0"
+ else
+ test $(aux count_processes_with_tag) -eq $1
+ fi
}
vgchange_all() {
LVM_TEST_TAG="kill_me_$PREFIX" vgchange -aey $vg $vg1
- test $(aux count_processes_with_tag) -eq $1
+ if test -e LOCAL_LVMPOLLD; then
+ aux lvmpolld_dump | tee lvmpolld_dump.txt
+ aux check_lvmpolld_init_rq_count 1 "$vg/pvmove0"
+ aux check_lvmpolld_init_rq_count 1 "$vg1/pvmove0"
+ else
+ test $(aux count_processes_with_tag) -eq $1
+ fi
}
pvmove_fg() {
@@ -134,7 +158,13 @@ pvmove_fg() {
LVM_TEST_TAG="kill_me_$PREFIX" vgchange --config 'activation{polling_interval=10}' -aey --poll n $vg $vg1
# ...also vgchange --poll n must not spawn any bg processes...
- test $(aux count_processes_with_tag) -eq 0
+ if test -e LOCAL_LVMPOLLD; then
+ aux lvmpolld_dump | tee lvmpolld_dump.txt
+ aux check_lvmpolld_init_rq_count 0 "$vg/pvmove0"
+ aux check_lvmpolld_init_rq_count 0 "$vg1/pvmove0"
+ else
+ test $(aux count_processes_with_tag) -eq 0
+ fi
# ...thus finish polling
get lv_field $vg name -a | grep "^\[pvmove0\]"
@@ -153,7 +183,13 @@ pvmove_bg() {
LVM_TEST_TAG="kill_me_$PREFIX" vgchange --config 'activation{polling_interval=10}' -aey --poll n $vg $vg1
# ...also vgchange --poll n must not spawn any bg processes...
- test $(aux count_processes_with_tag) -eq 0
+ if test -e LOCAL_LVMPOLLD; then
+ aux lvmpolld_dump | tee lvmpolld_dump.txt
+ aux check_lvmpolld_init_rq_count 0 "$vg/pvmove0"
+ aux check_lvmpolld_init_rq_count 0 "$vg1/pvmove0"
+ else
+ test $(aux count_processes_with_tag) -eq 0
+ fi
# ...thus finish polling
get lv_field $vg name -a | grep "^\[pvmove0\]"
@@ -167,7 +203,13 @@ pvmove_fg_single() {
LVM_TEST_TAG="kill_me_$PREFIX" vgchange --config 'activation{polling_interval=10}' -aey --poll n $vg
# ...also vgchange --poll n must not spawn any bg processes...
- test $(aux count_processes_with_tag) -eq 0
+ if test -e LOCAL_LVMPOLLD; then
+ aux lvmpolld_dump | tee lvmpolld_dump.txt
+ aux check_lvmpolld_init_rq_count 0 "$vg/pvmove0"
+ aux check_lvmpolld_init_rq_count 0 "$vg1/pvmove0"
+ else
+ test $(aux count_processes_with_tag) -eq 0
+ fi
# ...thus finish polling
get lv_field $vg name -a | grep "^\[pvmove0\]"
@@ -187,7 +229,13 @@ pvmove_bg_single() {
LVM_TEST_TAG="kill_me_$PREFIX" vgchange --config 'activation{polling_interval=10}' -aey --poll n $vg
# ...also vgchange --poll n must not spawn any bg processes...
- test $(aux count_processes_with_tag) -eq 0
+ if test -e LOCAL_LVMPOLLD; then
+ aux lvmpolld_dump | tee lvmpolld_dump.txt
+ aux check_lvmpolld_init_rq_count 0 "$vg/pvmove0"
+ aux check_lvmpolld_init_rq_count 0 "$vg1/pvmove0"
+ else
+ test $(aux count_processes_with_tag) -eq 0
+ fi
# ...thus finish polling
get lv_field $vg name -a | grep "^\[pvmove0\]"
diff --git a/test/shell/pvmove-resume-2.sh b/test/shell/pvmove-resume-2.sh
index 37a552d..5bdfd7d 100644
--- a/test/shell/pvmove-resume-2.sh
+++ b/test/shell/pvmove-resume-2.sh
@@ -95,13 +95,23 @@ lvchange_all() {
LVM_TEST_TAG="kill_me_$PREFIX" lvchange -vvvv -aey $vg/$lv1 $vg/$lv2
# we don't want to spawn more than $1 background pollings
- test $(aux count_processes_with_tag) -eq $1 || should false
+ if test -e LOCAL_LVMPOLLD; then
+ aux lvmpolld_dump | tee lvmpolld_dump.txt
+ aux check_lvmpolld_init_rq_count 1 "$vg/pvmove0" || should false
+ else
+ test $(aux count_processes_with_tag) -eq $1 || should false
+ fi
}
vgchange_single() {
LVM_TEST_TAG="kill_me_$PREFIX" vgchange -aey $vg
- test $(aux count_processes_with_tag) -eq $1
+ if test -e LOCAL_LVMPOLLD; then
+ aux lvmpolld_dump | tee lvmpolld_dump.txt
+ aux check_lvmpolld_init_rq_count 1 "$vg/pvmove0"
+ else
+ test $(aux count_processes_with_tag) -eq $1
+ fi
}
pvmove_fg() {
@@ -109,7 +119,12 @@ pvmove_fg() {
LVM_TEST_TAG="kill_me_$PREFIX" vgchange --config 'activation{polling_interval=10}' -aey --poll n $vg
# ...also vgchange --poll n must not spawn any bg processes
- test $(aux count_processes_with_tag) -eq 0
+ if test -e LOCAL_LVMPOLLD; then
+ aux lvmpolld_dump | tee lvmpolld_dump.txt
+ aux check_lvmpolld_init_rq_count 0 "$vg/pvmove0"
+ else
+ test $(aux count_processes_with_tag) -eq 0
+ fi
# ...thus finish polling
get lv_field $vg name -a | grep "^\[pvmove0\]"
@@ -124,7 +139,12 @@ pvmove_bg() {
LVM_TEST_TAG="kill_me_$PREFIX" vgchange --config 'activation{polling_interval=10}' -aey --poll n $vg
# ...also vgchange --poll n must not spawn any bg processes
- test $(aux count_processes_with_tag) -eq 0
+ if test -e LOCAL_LVMPOLLD; then
+ aux lvmpolld_dump | tee lvmpolld_dump.txt
+ aux check_lvmpolld_init_rq_count 0 "$vg/pvmove0"
+ else
+ test $(aux count_processes_with_tag) -eq 0
+ fi
# ...thus finish polling
get lv_field $vg name -a | grep "^\[pvmove0\]"
@@ -137,7 +157,12 @@ pvmove_fg_single() {
LVM_TEST_TAG="kill_me_$PREFIX" vgchange --config 'activation{polling_interval=10}' -aey --poll n $vg
# ...also vgchange --poll n must not spawn any bg processes
- test $(aux count_processes_with_tag) -eq 0
+ if test -e LOCAL_LVMPOLLD; then
+ aux lvmpolld_dump | tee lvmpolld_dump.txt
+ aux check_lvmpolld_init_rq_count 0 "$vg/pvmove0"
+ else
+ test $(aux count_processes_with_tag) -eq 0
+ fi
# ...thus finish polling
get lv_field $vg name -a | grep "^\[pvmove0\]"
@@ -152,7 +177,12 @@ pvmove_bg_single() {
LVM_TEST_TAG="kill_me_$PREFIX" vgchange --config 'activation{polling_interval=10}' -aey --poll n $vg
# ...also vgchange --poll n must not spawn any bg processes...
- test $(aux count_processes_with_tag) -eq 0
+ if test -e LOCAL_LVMPOLLD; then
+ aux lvmpolld_dump | tee lvmpolld_dump.txt
+ aux check_lvmpolld_init_rq_count 0 "$vg/pvmove0"
+ else
+ test $(aux count_processes_with_tag) -eq 0
+ fi
# ...thus finish polling
get lv_field $vg name -a | grep "^\[pvmove0\]"
diff --git a/test/shell/pvmove-resume-multiseg.sh b/test/shell/pvmove-resume-multiseg.sh
index be21d56..713534f 100644
--- a/test/shell/pvmove-resume-multiseg.sh
+++ b/test/shell/pvmove-resume-multiseg.sh
@@ -106,13 +106,25 @@ lvchange_all() {
LVM_TEST_TAG="kill_me_$PREFIX" lvchange -aey $vg/$lv1 $vg/$lv2
# we don't want to spawn more than $1 background pollings
- test $(aux count_processes_with_tag) -eq $1
+ if test -e LOCAL_LVMPOLLD; then
+ aux lvmpolld_dump | tee lvmpolld_dump.txt
+ aux check_lvmpolld_init_rq_count 1 "$vg/pvmove0"
+ aux check_lvmpolld_init_rq_count 1 "$vg/pvmove1"
+ else
+ test $(aux count_processes_with_tag) -eq $1
+ fi
}
vgchange_single() {
LVM_TEST_TAG="kill_me_$PREFIX" vgchange -aey $vg
- test $(aux count_processes_with_tag) -eq $1
+ if test -e LOCAL_LVMPOLLD; then
+ aux lvmpolld_dump | tee lvmpolld_dump.txt
+ aux check_lvmpolld_init_rq_count 1 "$vg/pvmove0"
+ aux check_lvmpolld_init_rq_count 1 "$vg/pvmove1"
+ else
+ test $(aux count_processes_with_tag) -eq $1
+ fi
}
pvmove_fg() {
@@ -120,7 +132,13 @@ pvmove_fg() {
LVM_TEST_TAG="kill_me_$PREFIX" vgchange --config 'activation{polling_interval=10}' -aey --poll n $vg
# ...also vgchange --poll n must not spawn any bg processes...
- test $(aux count_processes_with_tag) -eq 0
+ if test -e LOCAL_LVMPOLLD; then
+ aux lvmpolld_dump | tee lvmpolld_dump.txt
+ aux check_lvmpolld_init_rq_count 0 "$vg/pvmove0"
+ aux check_lvmpolld_init_rq_count 0 "$vg/pvmove1"
+ else
+ test $(aux count_processes_with_tag) -eq 0
+ fi
# ...thus finish polling
get lv_field $vg name -a | grep "^\[pvmove0\]"
@@ -139,7 +157,13 @@ pvmove_bg() {
LVM_TEST_TAG="kill_me_$PREFIX" vgchange --config 'activation{polling_interval=10}' -aey --poll n $vg
# ...also vgchange --poll n must not spawn any bg processes...
- test $(aux count_processes_with_tag) -eq 0
+ if test -e LOCAL_LVMPOLLD; then
+ aux lvmpolld_dump | tee lvmpolld_dump.txt
+ aux check_lvmpolld_init_rq_count 0 "$vg/pvmove0"
+ aux check_lvmpolld_init_rq_count 0 "$vg/pvmove1"
+ else
+ test $(aux count_processes_with_tag) -eq 0
+ fi
# ...thus finish polling
get lv_field $vg name -a | grep "^\[pvmove0\]"
@@ -153,7 +177,13 @@ pvmove_fg_single() {
LVM_TEST_TAG="kill_me_$PREFIX" vgchange --config 'activation{polling_interval=10}' -aey --poll n $vg
# ...also vgchange --poll n must not spawn any bg processes...
- test $(aux count_processes_with_tag) -eq 0
+ if test -e LOCAL_LVMPOLLD; then
+ aux lvmpolld_dump | tee lvmpolld_dump.txt
+ aux check_lvmpolld_init_rq_count 0 "$vg/pvmove0"
+ aux check_lvmpolld_init_rq_count 0 "$vg/pvmove1"
+ else
+ test $(aux count_processes_with_tag) -eq 0
+ fi
# ...thus finish polling
get lv_field $vg name -a | grep "^\[pvmove0\]"
@@ -173,7 +203,13 @@ pvmove_bg_single() {
LVM_TEST_TAG="kill_me_$PREFIX" vgchange --config 'activation{polling_interval=10}' -aey --poll n $vg
# ...also vgchange --poll n must not spawn any bg processes...
- test $(aux count_processes_with_tag) -eq 0
+ if test -e LOCAL_LVMPOLLD; then
+ aux lvmpolld_dump | tee lvmpolld_dump.txt
+ aux check_lvmpolld_init_rq_count 0 "$vg/pvmove0"
+ aux check_lvmpolld_init_rq_count 0 "$vg/pvmove1"
+ else
+ test $(aux count_processes_with_tag) -eq 0
+ fi
# ...thus finish polling
get lv_field $vg name -a | grep "^\[pvmove0\]"
diff --git a/test/shell/pvremove-thin.sh b/test/shell/pvremove-thin.sh
index 5bfb880..2400ac5 100644
--- a/test/shell/pvremove-thin.sh
+++ b/test/shell/pvremove-thin.sh
@@ -14,6 +14,8 @@
. lib/inittest
+test -e LOCAL_LVMPOLLD && skip
+
aux prepare_vg
aux have_thin 1 8 0 || skip
diff --git a/test/shell/pvremove-usage.sh b/test/shell/pvremove-usage.sh
index 52d26a6..5c55839 100644
--- a/test/shell/pvremove-usage.sh
+++ b/test/shell/pvremove-usage.sh
@@ -11,6 +11,8 @@
. lib/inittest
+test -e LOCAL_LVMPOLLD && skip
+
aux prepare_devs 3
pvcreate "$dev1"
pvcreate --metadatacopies 0 "$dev2"
diff --git a/test/shell/pvremove-warnings.sh b/test/shell/pvremove-warnings.sh
index c561483..f7ac95b 100644
--- a/test/shell/pvremove-warnings.sh
+++ b/test/shell/pvremove-warnings.sh
@@ -10,6 +10,8 @@
. lib/inittest
+test -e LOCAL_LVMPOLLD && skip
+
aux prepare_devs 2
pvcreate "$dev1" "$dev2"
pvremove "$dev1" "$dev2" 2>&1 | tee pvremove.txt
diff --git a/test/shell/read-ahead.sh b/test/shell/read-ahead.sh
index 764bef1..322a527 100644
--- a/test/shell/read-ahead.sh
+++ b/test/shell/read-ahead.sh
@@ -17,6 +17,8 @@ test_description='Test read-ahead functionality'
. lib/inittest
+test -e LOCAL_LVMPOLLD && skip
+
aux prepare_vg 5
#COMM "test various read ahead settings (bz450922)"
diff --git a/test/shell/select-report.sh b/test/shell/select-report.sh
index f56aa21..a79457e 100644
--- a/test/shell/select-report.sh
+++ b/test/shell/select-report.sh
@@ -11,6 +11,8 @@
. lib/inittest
+test -e LOCAL_LVMPOLLD && skip
+
aux prepare_pvs 6 16
# !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
diff --git a/test/shell/select-tools-thin.sh b/test/shell/select-tools-thin.sh
index f4d49eb..37c4856 100644
--- a/test/shell/select-tools-thin.sh
+++ b/test/shell/select-tools-thin.sh
@@ -11,6 +11,8 @@
. lib/inittest
+test -e LOCAL_LVMPOLLD && skip
+
aux have_thin 1 0 0 || skip
aux prepare_pvs 1 16
diff --git a/test/shell/select-tools.sh b/test/shell/select-tools.sh
index b9e4b2f..631c637 100644
--- a/test/shell/select-tools.sh
+++ b/test/shell/select-tools.sh
@@ -11,6 +11,8 @@
. lib/inittest
+test -e LOCAL_LVMPOLLD && skip
+
aux prepare_pvs 4 12
vgcreate -s 4m $vg1 "$dev1" "$dev2"
diff --git a/test/shell/snapshot-autoumount-dmeventd.sh b/test/shell/snapshot-autoumount-dmeventd.sh
index 860d170..d369dac 100644
--- a/test/shell/snapshot-autoumount-dmeventd.sh
+++ b/test/shell/snapshot-autoumount-dmeventd.sh
@@ -13,6 +13,8 @@
. lib/inittest
+test -e LOCAL_LVMPOLLD && skip
+
which mkfs.ext2 || skip
aux lvmconf "activation/snapshot_autoextend_percent = 0" \
diff --git a/test/shell/snapshot-cluster.sh b/test/shell/snapshot-cluster.sh
index 051c165..47c8d2e 100644
--- a/test/shell/snapshot-cluster.sh
+++ b/test/shell/snapshot-cluster.sh
@@ -14,6 +14,8 @@
. lib/inittest
+test -e LOCAL_LVMPOLLD && skip
+
aux prepare_vg 1
lvcreate -aey -L1 -n $lv1 $vg
diff --git a/test/shell/snapshot-lvm1.sh b/test/shell/snapshot-lvm1.sh
index f6afe14..0abba0c 100644
--- a/test/shell/snapshot-lvm1.sh
+++ b/test/shell/snapshot-lvm1.sh
@@ -14,6 +14,8 @@
. lib/inittest
+test -e LOCAL_LVMPOLLD && skip
+
aux prepare_devs 2
vgcreate --metadatatype 1 $vg $(cat DEVICES)
diff --git a/test/shell/snapshot-maxsize.sh b/test/shell/snapshot-maxsize.sh
index 3949f19..e24f965 100644
--- a/test/shell/snapshot-maxsize.sh
+++ b/test/shell/snapshot-maxsize.sh
@@ -14,6 +14,8 @@
. lib/inittest
+test -e LOCAL_LVMPOLLD && skip
+
aux prepare_pvs 1
vgcreate -s 1K $vg $(cat DEVICES)
diff --git a/test/shell/snapshot-reactivate.sh b/test/shell/snapshot-reactivate.sh
index 0fbdc62..978f7c0 100644
--- a/test/shell/snapshot-reactivate.sh
+++ b/test/shell/snapshot-reactivate.sh
@@ -17,6 +17,8 @@
#
. lib/inittest
+test -e LOCAL_LVMPOLLD && skip
+
# Snapshot should remain unmodified
check_s_() {
check dev_md5sum $vg s
diff --git a/test/shell/snapshot-rename.sh b/test/shell/snapshot-rename.sh
index 8d1eefb..47bf213 100644
--- a/test/shell/snapshot-rename.sh
+++ b/test/shell/snapshot-rename.sh
@@ -14,6 +14,8 @@
. lib/inittest
+test -e LOCAL_LVMPOLLD && skip
+
aux prepare_vg 1
lvcreate -aey -L1 -n $lv1 $vg
diff --git a/test/shell/snapshot-usage-exa.sh b/test/shell/snapshot-usage-exa.sh
index ae5ca6d..133014b 100644
--- a/test/shell/snapshot-usage-exa.sh
+++ b/test/shell/snapshot-usage-exa.sh
@@ -14,6 +14,8 @@
. lib/inittest
+test -e LOCAL_LVMPOLLD && skip
+
aux can_use_16T || skip
aux prepare_pvs 1
diff --git a/test/shell/snapshot-usage.sh b/test/shell/snapshot-usage.sh
index e3db1fb..68396aa 100644
--- a/test/shell/snapshot-usage.sh
+++ b/test/shell/snapshot-usage.sh
@@ -13,6 +13,8 @@
. lib/inittest
+test -e LOCAL_LVMPOLLD && skip
+
MKFS=mkfs.ext2
which $MKFS || skip
diff --git a/test/shell/stray-device-node.sh b/test/shell/stray-device-node.sh
index 0ff4796..09d9e75 100644
--- a/test/shell/stray-device-node.sh
+++ b/test/shell/stray-device-node.sh
@@ -11,6 +11,8 @@
. lib/inittest
+test -e LOCAL_LVMPOLLD && skip
+
aux prepare_devs 3
cp -r "$dev1" "$DM_DEV_DIR/stray"
diff --git a/test/shell/system_id.sh b/test/shell/system_id.sh
index ff03e14..78067e9 100644
--- a/test/shell/system_id.sh
+++ b/test/shell/system_id.sh
@@ -13,6 +13,8 @@ test_description='Test system_id'
. lib/inittest
+test -e LOCAL_LVMPOLLD && skip
+
aux prepare_devs 1
# with clvm enabled, vgcreate with no -c option creates a clustered vg,
diff --git a/test/shell/tags.sh b/test/shell/tags.sh
index bc66d15..37d738f 100644
--- a/test/shell/tags.sh
+++ b/test/shell/tags.sh
@@ -11,6 +11,8 @@
. lib/inittest
+test -e LOCAL_LVMPOLLD && skip
+
aux prepare_pvs 4
# vgcreate with --addtag
diff --git a/test/shell/test-partition.sh b/test/shell/test-partition.sh
index f68d572..0cdaa87 100644
--- a/test/shell/test-partition.sh
+++ b/test/shell/test-partition.sh
@@ -19,6 +19,8 @@ LVM_TEST_CONFIG_DEVICES="types = [\"device-mapper\", 142]"
. lib/inittest
+test -e LOCAL_LVMPOLLD && skip
+
which sfdisk || skip
aux prepare_pvs 1 30
diff --git a/test/shell/thin-autoumount-dmeventd.sh b/test/shell/thin-autoumount-dmeventd.sh
index a77ad08..00ea859 100644
--- a/test/shell/thin-autoumount-dmeventd.sh
+++ b/test/shell/thin-autoumount-dmeventd.sh
@@ -18,6 +18,8 @@ is_dir_mounted_()
. lib/inittest
+test -e LOCAL_LVMPOLLD && skip
+
#
# Main
#
diff --git a/test/shell/thin-defaults.sh b/test/shell/thin-defaults.sh
index 3a681a1..4341899 100644
--- a/test/shell/thin-defaults.sh
+++ b/test/shell/thin-defaults.sh
@@ -13,6 +13,8 @@
. lib/inittest
+test -e LOCAL_LVMPOLLD && skip
+
#
# Main
#
diff --git a/test/shell/thin-restore.sh b/test/shell/thin-restore.sh
index fd4118f..1ac4f66 100644
--- a/test/shell/thin-restore.sh
+++ b/test/shell/thin-restore.sh
@@ -13,6 +13,8 @@
. lib/inittest
+test -e LOCAL_LVMPOLLD && skip
+
#
# Main
#
diff --git a/test/shell/thin-volume-list.sh b/test/shell/thin-volume-list.sh
index 32d13b8..e173d87 100644
--- a/test/shell/thin-volume-list.sh
+++ b/test/shell/thin-volume-list.sh
@@ -13,6 +13,8 @@
. lib/inittest
+test -e LOCAL_LVMPOLLD && skip
+
#
# Main
#
diff --git a/test/shell/topology-support.sh b/test/shell/topology-support.sh
index f1e42a8..ebb7220 100644
--- a/test/shell/topology-support.sh
+++ b/test/shell/topology-support.sh
@@ -11,6 +11,8 @@
. lib/inittest
+test -e LOCAL_LVMPOLLD && skip
+
which mkfs.ext3 || skip
lvdev_() {
diff --git a/test/shell/unknown-segment.sh b/test/shell/unknown-segment.sh
index b07e1b5..a1d3696 100644
--- a/test/shell/unknown-segment.sh
+++ b/test/shell/unknown-segment.sh
@@ -11,6 +11,8 @@
. lib/inittest
+test -e LOCAL_LVMPOLLD && skip
+
aux prepare_vg 4
lvcreate -an -Zn -l 1 -n $lv1 $vg
diff --git a/test/shell/unlost-pv.sh b/test/shell/unlost-pv.sh
index 980c451..09de21a 100644
--- a/test/shell/unlost-pv.sh
+++ b/test/shell/unlost-pv.sh
@@ -11,6 +11,8 @@
. lib/inittest
+test -e LOCAL_LVMPOLLD && skip
+
check_() {
# vgscan needs --cache option for direct scan if lvmetad is used
test -e LOCAL_LVMETAD && cache="--cache"
diff --git a/test/shell/vg-name-from-env.sh b/test/shell/vg-name-from-env.sh
index 67ad5c5..a3d1b9a 100644
--- a/test/shell/vg-name-from-env.sh
+++ b/test/shell/vg-name-from-env.sh
@@ -9,6 +9,8 @@ test_description='Test the vg name for an lv from env var'
. lib/inittest
+test -e LOCAL_LVMPOLLD && skip
+
aux prepare_devs 2
pvcreate "$dev1"
diff --git a/test/shell/vgcfgbackup-usage.sh b/test/shell/vgcfgbackup-usage.sh
index eb36983..b0faf38 100644
--- a/test/shell/vgcfgbackup-usage.sh
+++ b/test/shell/vgcfgbackup-usage.sh
@@ -11,6 +11,8 @@
. lib/inittest
+test -e LOCAL_LVMPOLLD && skip
+
aux prepare_pvs 4
pvcreate --metadatacopies 0 "$dev4"
diff --git a/test/shell/vgchange-many.sh b/test/shell/vgchange-many.sh
index cbb4363..7b3d557 100644
--- a/test/shell/vgchange-many.sh
+++ b/test/shell/vgchange-many.sh
@@ -12,6 +12,8 @@
# Check perfomance of activation and deactivation
. lib/inittest
+test -e LOCAL_LVMPOLLD && skip
+
# FIXME: lvmetad fails with i.e. 1500 device on memory failure...
# Number of LVs to create
diff --git a/test/shell/vgchange-maxlv.sh b/test/shell/vgchange-maxlv.sh
index 35ce5d6..613d985 100644
--- a/test/shell/vgchange-maxlv.sh
+++ b/test/shell/vgchange-maxlv.sh
@@ -11,6 +11,8 @@
. lib/inittest
+test -e LOCAL_LVMPOLLD && skip
+
aux prepare_dmeventd
aux prepare_pvs 3
diff --git a/test/shell/vgchange-partial.sh b/test/shell/vgchange-partial.sh
index 7fd9840..f9c3ac0 100644
--- a/test/shell/vgchange-partial.sh
+++ b/test/shell/vgchange-partial.sh
@@ -11,6 +11,8 @@
. lib/inittest
+test -e LOCAL_LVMPOLLD && skip
+
aux prepare_vg 2
aux disable_dev "$dev1"
diff --git a/test/shell/vgchange-sysinit.sh b/test/shell/vgchange-sysinit.sh
index 4debf42..8450d63 100644
--- a/test/shell/vgchange-sysinit.sh
+++ b/test/shell/vgchange-sysinit.sh
@@ -12,6 +12,7 @@
. lib/inittest
test -e LOCAL_CLVMD && skip
+test -e LOCAL_LVMPOLLD && skip
which mkfs.ext3 || skip
diff --git a/test/shell/vgchange-usage.sh b/test/shell/vgchange-usage.sh
index e564337..7ee42a9 100644
--- a/test/shell/vgchange-usage.sh
+++ b/test/shell/vgchange-usage.sh
@@ -13,6 +13,8 @@ test_description='Exercise some vgchange diagnostics'
. lib/inittest
+test -e LOCAL_LVMPOLLD && skip
+
aux prepare_pvs 4
pvcreate --metadatacopies 0 "$dev1"
diff --git a/test/shell/vgck.sh b/test/shell/vgck.sh
index 629b6e7..a4930aa 100644
--- a/test/shell/vgck.sh
+++ b/test/shell/vgck.sh
@@ -11,6 +11,8 @@
. lib/inittest
+test -e LOCAL_LVMPOLLD && skip
+
aux prepare_vg 3
lvcreate -n blabla -L 1 $vg
diff --git a/test/shell/vgcreate-many-pvs.sh b/test/shell/vgcreate-many-pvs.sh
index c6d3852..bb78caf 100644
--- a/test/shell/vgcreate-many-pvs.sh
+++ b/test/shell/vgcreate-many-pvs.sh
@@ -11,6 +11,8 @@
. lib/inittest
+test -e LOCAL_LVMPOLLD && skip
+
#
# Test to exercise larger number of PVs in a VG
# Related to https://bugzilla.redhat.com/show_bug.cgi?id=736027
diff --git a/test/shell/vgcreate-usage.sh b/test/shell/vgcreate-usage.sh
index a1d178d..df0094c 100644
--- a/test/shell/vgcreate-usage.sh
+++ b/test/shell/vgcreate-usage.sh
@@ -13,6 +13,8 @@ test_description='Exercise some vgcreate diagnostics'
. lib/inittest
+test -e LOCAL_LVMPOLLD && skip
+
aux prepare_devs 3
pvcreate "$dev1" "$dev2"
pvcreate --metadatacopies 0 "$dev3"
diff --git a/test/shell/vgextend-restoremissing.sh b/test/shell/vgextend-restoremissing.sh
index 7b7748f..5af5520 100644
--- a/test/shell/vgextend-restoremissing.sh
+++ b/test/shell/vgextend-restoremissing.sh
@@ -11,6 +11,8 @@
. lib/inittest
+test -e LOCAL_LVMPOLLD && skip
+
aux prepare_vg 3
lvcreate -an -Zn --type mirror -m 1 -l 1 -n mirror $vg
diff --git a/test/shell/vgextend-usage.sh b/test/shell/vgextend-usage.sh
index 93401f0..65665bc 100644
--- a/test/shell/vgextend-usage.sh
+++ b/test/shell/vgextend-usage.sh
@@ -15,6 +15,8 @@
. lib/inittest
+test -e LOCAL_LVMPOLLD && skip
+
aux prepare_devs 5
for mdatype in 1 2
diff --git a/test/shell/vgimportclone.sh b/test/shell/vgimportclone.sh
index c3d7e52..0b1af38 100644
--- a/test/shell/vgimportclone.sh
+++ b/test/shell/vgimportclone.sh
@@ -11,6 +11,8 @@
. lib/inittest
+test -e LOCAL_LVMPOLLD && skip
+
aux prepare_devs 2
vgcreate --metadatasize 128k $vg1 "$dev1"
diff --git a/test/shell/vgmerge-operation.sh b/test/shell/vgmerge-operation.sh
index 261953e..42976c2 100644
--- a/test/shell/vgmerge-operation.sh
+++ b/test/shell/vgmerge-operation.sh
@@ -13,6 +13,8 @@ test_description='Test vgmerge operation'
. lib/inittest
+test -e LOCAL_LVMPOLLD && skip
+
aux prepare_pvs 4 64
# 'vgmerge succeeds with single linear LV in source VG'
diff --git a/test/shell/vgmerge-usage.sh b/test/shell/vgmerge-usage.sh
index d8fa09c..981a964 100644
--- a/test/shell/vgmerge-usage.sh
+++ b/test/shell/vgmerge-usage.sh
@@ -13,6 +13,8 @@
. lib/inittest
+test -e LOCAL_LVMPOLLD && skip
+
aux prepare_pvs 4
# 'vgmerge normal operation'
diff --git a/test/shell/vgreduce-usage.sh b/test/shell/vgreduce-usage.sh
index 52c5f36..9f55395 100644
--- a/test/shell/vgreduce-usage.sh
+++ b/test/shell/vgreduce-usage.sh
@@ -11,6 +11,8 @@
. lib/inittest
+test -e LOCAL_LVMPOLLD && skip
+
aux prepare_devs 4
for mdatype in 1 2
diff --git a/test/shell/vgremove-corrupt-vg.sh b/test/shell/vgremove-corrupt-vg.sh
index f709e4e..dc3c9db 100644
--- a/test/shell/vgremove-corrupt-vg.sh
+++ b/test/shell/vgremove-corrupt-vg.sh
@@ -11,6 +11,8 @@
. lib/inittest
+test -e LOCAL_LVMPOLLD && skip
+
aux prepare_vg 3
lvcreate -n blabla -L 1 $vg -an --zero n
diff --git a/test/shell/vgrename-usage.sh b/test/shell/vgrename-usage.sh
index de1b933..59c3397 100644
--- a/test/shell/vgrename-usage.sh
+++ b/test/shell/vgrename-usage.sh
@@ -11,6 +11,8 @@
. lib/inittest
+test -e LOCAL_LVMPOLLD && skip
+
aux prepare_devs 4
pvcreate "$dev1" "$dev2"
pvcreate --metadatacopies 0 "$dev3" "$dev4"
diff --git a/test/shell/vgsplit-operation.sh b/test/shell/vgsplit-operation.sh
index 91cdcdc..975e873 100644
--- a/test/shell/vgsplit-operation.sh
+++ b/test/shell/vgsplit-operation.sh
@@ -16,6 +16,8 @@ export LVM_TEST_LVMETAD_DEBUG_OPTS=${LVM_TEST_LVMETAD_DEBUG_OPTS-}
. lib/inittest
+test -e LOCAL_LVMPOLLD && skip
+
COMM() {
LAST_TEST="$@"
}
diff --git a/test/shell/vgsplit-raid.sh b/test/shell/vgsplit-raid.sh
index a7c9687..2fe734f 100644
--- a/test/shell/vgsplit-raid.sh
+++ b/test/shell/vgsplit-raid.sh
@@ -13,6 +13,8 @@
. lib/inittest
+test -e LOCAL_LVMPOLLD && skip
+
COMM() {
LAST_TEST="$@"
}
diff --git a/test/shell/vgsplit-stacked.sh b/test/shell/vgsplit-stacked.sh
index 42010fc..6a04f07 100644
--- a/test/shell/vgsplit-stacked.sh
+++ b/test/shell/vgsplit-stacked.sh
@@ -11,6 +11,8 @@
. lib/inittest
+test -e LOCAL_LVMPOLLD && skip
+
aux extend_filter_LVMTEST
aux prepare_pvs 3
diff --git a/test/shell/vgsplit-thin.sh b/test/shell/vgsplit-thin.sh
index 7b06132..0f6b427 100644
--- a/test/shell/vgsplit-thin.sh
+++ b/test/shell/vgsplit-thin.sh
@@ -13,6 +13,8 @@
. lib/inittest
+test -e LOCAL_LVMPOLLD && skip
+
aux have_thin 1 0 0 || skip
aux prepare_devs 5
diff --git a/test/shell/vgsplit-usage.sh b/test/shell/vgsplit-usage.sh
index fe999f9..b0422d5 100644
--- a/test/shell/vgsplit-usage.sh
+++ b/test/shell/vgsplit-usage.sh
@@ -13,6 +13,8 @@
. lib/inittest
+test -e LOCAL_LVMPOLLD && skip
+
aux prepare_devs 5
for mdatype in 1 2
diff --git a/test/shell/zero-usage.sh b/test/shell/zero-usage.sh
index 046b3f5..df90529 100644
--- a/test/shell/zero-usage.sh
+++ b/test/shell/zero-usage.sh
@@ -13,6 +13,8 @@
. lib/inittest
+test -e LOCAL_LVMPOLLD && skip
+
which md5sum || skip
aux prepare_pvs 1
diff --git a/tools/Makefile.in b/tools/Makefile.in
index 861ae82..20c988d 100644
--- a/tools/Makefile.in
+++ b/tools/Makefile.in
@@ -59,6 +59,7 @@ SOURCES =\
vgimport.c \
vgmerge.c \
vgmknodes.c \
+ lvpoll.c \
vgreduce.c \
vgremove.c \
vgrename.c \
@@ -168,7 +169,7 @@ liblvm2cmd.$(LIB_SUFFIX).$(LIB_VERSION): liblvm2cmd.$(LIB_SUFFIX)
.commands: $(srcdir)/commands.h $(srcdir)/cmdnames.h Makefile
$(CC) -E -P $(srcdir)/cmdnames.h 2> /dev/null | \
- egrep -v '^ *(|#.*|config|devtypes|dumpconfig|formats|help|pvdata|segtypes|systemid|tags|version) *$$' > .commands
+ egrep -v '^ *(|#.*|config|devtypes|dumpconfig|formats|help|lvpoll|pvdata|segtypes|systemid|tags|version) *$$' > .commands
ifneq ("$(CFLOW_CMD)", "")
CFLOW_SOURCES = $(addprefix $(srcdir)/, $(SOURCES))
diff --git a/tools/args.h b/tools/args.h
index 791aa4e..7b715f5 100644
--- a/tools/args.h
+++ b/tools/args.h
@@ -42,6 +42,7 @@ arg(driverloaded_ARG, '\0', "driverloaded", yes_no_arg, 0)
arg(errorwhenfull_ARG, '\0', "errorwhenfull", yes_no_arg, 0)
arg(force_long_ARG, '\0', "force", NULL, ARG_COUNTABLE)
arg(foreign_ARG, '\0', "foreign", NULL, 0)
+arg(handlemissingpvs_ARG, '\0', "handlemissingpvs", NULL, 0)
arg(ignoreadvanced_ARG, '\0', "ignoreadvanced", NULL, 0)
arg(ignorelocal_ARG, '\0', "ignorelocal", NULL, 0)
arg(ignorelockingfailure_ARG, '\0', "ignorelockingfailure", NULL, 0)
@@ -72,6 +73,7 @@ arg(noudevsync_ARG, '\0', "noudevsync", NULL, 0)
arg(originname_ARG, '\0', "originname", string_arg, 0)
arg(physicalvolumesize_ARG, '\0', "setphysicalvolumesize", size_mb_arg, 0)
arg(poll_ARG, '\0', "poll", yes_no_arg, 0)
+arg(polloperation_ARG, '\0', "polloperation", string_arg, 0)
arg(pooldatasize_ARG, '\0', "pooldatasize", size_mb_arg, 0)
arg(poolmetadata_ARG, '\0', "poolmetadata", string_arg, 0)
arg(poolmetadatasize_ARG, '\0', "poolmetadatasize", size_mb_arg, 0)
diff --git a/tools/commands.h b/tools/commands.h
index f2878ab..2e53d8f 100644
--- a/tools/commands.h
+++ b/tools/commands.h
@@ -880,6 +880,22 @@ xx(pvmove,
abort_ARG, alloc_ARG, atomic_ARG, autobackup_ARG, background_ARG,
interval_ARG, name_ARG, noudevsync_ARG, test_ARG)
+xx(lvpoll,
+ "Continue already initiated poll operation on a logical volume",
+ 0,
+ "\t[--abort]\n"
+ "\t[--handlemissingpvs]\n"
+ "\t[--polloperation\n"
+ "\t[-d|--debug]\n "
+ "\t[-h|-?|--help]\n"
+ "\t[-i|--interval seconds]\n"
+ "\t[-t|--test]\n "
+ "\t[-v|--verbose]\n "
+ "\t[--version]\n",
+
+ abort_ARG, handlemissingpvs_ARG, interval_ARG, polloperation_ARG,
+ test_ARG)
+
xx(pvremove,
"Remove LVM label(s) from physical volume(s)",
0,
diff --git a/tools/lvpoll.c b/tools/lvpoll.c
new file mode 100644
index 0000000..6db0ade
--- /dev/null
+++ b/tools/lvpoll.c
@@ -0,0 +1,115 @@
+/*
+ * Copyright (C) 2014-2015 Red Hat, Inc. All rights reserved.
+ *
+ * This file is part of LVM2.
+ *
+ * This copyrighted material is made available to anyone wishing to use,
+ * modify, copy, or redistribute it subject to the terms and conditions
+ * of the GNU Lesser General Public License v.2.1.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include "tools.h"
+#include "polldaemon.h"
+#include "pvmove_poll.h"
+#include "lvconvert_poll.h"
+#include "polling_ops.h"
+
+static struct poll_functions _pvmove_fns = {
+ .get_copy_lv = poll_get_copy_lv,
+ .get_copy_vg = poll_get_copy_vg,
+ .poll_progress = poll_mirror_progress,
+ .update_metadata = pvmove_update_metadata,
+ .finish_copy = pvmove_finish
+};
+
+static struct poll_functions _convert_fns = {
+ .get_copy_lv = poll_get_copy_lv,
+ .get_copy_vg = poll_get_copy_vg,
+ .poll_progress = poll_mirror_progress,
+ .finish_copy = lvconvert_mirror_finish
+};
+
+static struct poll_functions _merge_fns = {
+ .get_copy_lv = poll_get_copy_lv,
+ .get_copy_vg = poll_get_copy_vg,
+ .poll_progress = poll_merge_progress,
+ .finish_copy = lvconvert_merge_finish
+};
+
+static struct poll_functions _thin_merge_fns = {
+ .get_copy_lv = poll_get_copy_lv,
+ .get_copy_vg = poll_get_copy_vg,
+ .poll_progress = poll_thin_merge_progress,
+ .finish_copy = lvconvert_merge_finish
+};
+
+static int _set_daemon_parms(struct cmd_context *cmd, struct daemon_parms *parms)
+{
+ const char *poll_oper = arg_str_value(cmd, polloperation_ARG, "");
+
+ parms->interval = arg_uint_value(cmd, interval_ARG, 0);
+ parms->aborting = arg_count(cmd, abort_ARG);
+ parms->progress_display = 1;
+ parms->wait_before_testing = (arg_sign_value(cmd, interval_ARG, SIGN_NONE) == SIGN_PLUS);
+
+ if (!strcmp(poll_oper, PVMOVE_POLL)) {
+ parms->progress_title = "Moved";
+ parms->lv_type = PVMOVE;
+ parms->poll_fns = &_pvmove_fns;
+ } else if (!strcmp(poll_oper, CONVERT_POLL)) {
+ parms->progress_title = "Converted";
+ parms->poll_fns = &_convert_fns;
+ } else if (!strcmp(poll_oper, MERGE_POLL)) {
+ parms->progress_title = "Merged";
+ parms->poll_fns = &_merge_fns;
+ } else if (!strcmp(poll_oper, MERGE_THIN_POLL)) {
+ parms->progress_title = "Merged";
+ parms->poll_fns = &_thin_merge_fns;
+ } else {
+ log_error("Unknown polling operation %s", poll_oper);
+ return 0;
+ }
+
+ cmd->handles_missing_pvs = arg_count(cmd, handlemissingpvs_ARG);
+
+ return 1;
+}
+
+static int poll_lv(struct cmd_context *cmd, const char *lv_name)
+{
+ struct daemon_parms parms = { 0 };
+ struct poll_operation_id id = {
+ .vg_name = extract_vgname(cmd, lv_name),
+ .lv_name = strchr(lv_name, '/') + 1,
+ .display_name = lv_name
+ };
+
+ if (!_set_daemon_parms(cmd, &parms))
+ return_EINVALID_CMD_LINE;
+
+ return wait_for_single_lv(cmd, &id, &parms) ? ECMD_PROCESSED : ECMD_FAILED;
+}
+
+int lvpoll(struct cmd_context *cmd, int argc, char **argv)
+{
+ if (!arg_count(cmd, polloperation_ARG)) {
+ log_error("--polloperation parameter is mandatory");
+ return EINVALID_CMD_LINE;
+ }
+
+ if (arg_sign_value(cmd, interval_ARG, SIGN_NONE) == SIGN_MINUS) {
+ log_error("Argument to --interval cannot be negative");
+ return EINVALID_CMD_LINE;
+ }
+
+ if (!argc || !strchr(argv[0], '/')) {
+ log_error("Provide full VG/LV name");
+ return EINVALID_CMD_LINE;
+ }
+
+ return poll_lv(cmd, argv[0]);
+}
diff --git a/tools/polldaemon.c b/tools/polldaemon.c
index 9c62ebf..83497b0 100644
--- a/tools/polldaemon.c
+++ b/tools/polldaemon.c
@@ -18,6 +18,7 @@
#include "tools.h"
#include "polldaemon.h"
#include "lvm2cmdline.h"
+#include "lvmpolld-client.h"
#define WAIT_AT_LEAST_NANOSECS 100000
@@ -182,7 +183,7 @@ int wait_for_single_lv(struct cmd_context *cmd, struct poll_operation_id *id,
lv = parms->poll_fns->get_copy_lv(cmd, vg, id->lv_name, id->uuid, parms->lv_type);
if (!lv && parms->lv_type == PVMOVE) {
- log_print_unless_silent("%s: no pvmove in progress - already finished or aborted.",
+ log_print_unless_silent("%s: No pvmove in progress - already finished or aborted.",
id->display_name);
unlock_and_release_vg(cmd, vg, vg->name);
return 1;
@@ -365,6 +366,174 @@ static void _poll_for_all_vgs(struct cmd_context *cmd,
}
}
+#ifdef LVMPOLLD_SUPPORT
+typedef struct {
+ struct daemon_parms *parms;
+ struct dm_list idls;
+} lvmpolld_parms_t;
+
+static int report_progress(struct cmd_context *cmd, struct poll_operation_id *id,
+ struct daemon_parms *parms)
+{
+ struct volume_group *vg;
+ struct logical_volume *lv;
+
+ vg = parms->poll_fns->get_copy_vg(cmd, id->vg_name, NULL, 0);
+ if (vg_read_error(vg)) {
+ release_vg(vg);
+ log_error("Can't reread VG for %s", id->display_name);
+ return 0;
+ }
+
+ lv = parms->poll_fns->get_copy_lv(cmd, vg, id->lv_name, id->uuid, parms->lv_type);
+ if (!lv && parms->lv_type == PVMOVE) {
+ log_print_unless_silent("%s: No pvmove in progress - already finished or aborted.",
+ id->display_name);
+ unlock_and_release_vg(cmd, vg, vg->name);
+ return 1;
+ }
+
+ if (!lv) {
+ log_warn("Can't find LV in %s for %s. Already finished or removed.",
+ vg->name, id->display_name);
+ unlock_and_release_vg(cmd, vg, vg->name);
+ return 1;
+ }
+
+ if (!lv_is_active_locally(lv)) {
+ log_print_unless_silent("%s: Interrupted: No longer active.", id->display_name);
+ unlock_and_release_vg(cmd, vg, vg->name);
+ return 1;
+ }
+
+ if (parms->poll_fns->poll_progress(cmd, lv, id->display_name, parms) == PROGRESS_CHECK_FAILED) {
+ unlock_and_release_vg(cmd, vg, vg->name);
+ return_0;
+ }
+
+ unlock_and_release_vg(cmd, vg, vg->name);
+
+ return 1;
+}
+
+static int _lvmpolld_init_poll_vg(struct cmd_context *cmd, const char *vgname,
+ struct volume_group *vg, struct processing_handle *handle)
+{
+ int r;
+ struct lv_list *lvl;
+ struct logical_volume *lv;
+ struct poll_id_list *idl;
+ struct poll_operation_id id;
+ lvmpolld_parms_t *lpdp = (lvmpolld_parms_t *) handle->custom_handle;
+
+ dm_list_iterate_items(lvl, &vg->lvs) {
+ lv = lvl->lv;
+ if (!(lv->status & lpdp->parms->lv_type))
+ continue;
+
+ id.display_name = lpdp->parms->poll_fns->get_copy_name_from_lv(lv);
+ if (!id.display_name && !lpdp->parms->aborting)
+ continue;
+
+ if (!lv->lvid.s) {
+ log_print_unless_silent("Missing LV uuid within: %s/%s", id.vg_name, id.lv_name);
+ continue;
+ }
+
+ id.vg_name = lv->vg->name;
+ id.lv_name = lv->name;
+ id.uuid = lv->lvid.s;
+
+ r = lvmpolld_poll_init(cmd, &id, lpdp->parms);
+
+ if (r && !lpdp->parms->background) {
+ if (!(idl = poll_id_list_create(cmd->mem, &id)))
+ return ECMD_FAILED;
+
+ dm_list_add(&lpdp->idls, &idl->list);
+ }
+ }
+
+ return ECMD_PROCESSED;
+}
+
+static void _lvmpolld_poll_for_all_vgs(struct cmd_context *cmd,
+ struct daemon_parms *parms,
+ struct processing_handle *handle)
+{
+ int r;
+ struct dm_list *first;
+ struct poll_id_list *idl, *tlv;
+ unsigned finished;
+ lvmpolld_parms_t lpdp = {
+ .parms = parms
+ };
+
+ dm_list_init(&lpdp.idls);
+
+ handle->custom_handle = &lpdp;
+
+ process_each_vg(cmd, 0, NULL, 0, handle, _lvmpolld_init_poll_vg);
+
+ first = dm_list_first(&lpdp.idls);
+
+ while (!dm_list_empty(&lpdp.idls)) {
+ dm_list_iterate_items_safe(idl, tlv, &lpdp.idls) {
+ r = lvmpolld_request_info(idl->id, lpdp.parms,
+ &finished);
+ if (!r || finished)
+ dm_list_del(&idl->list);
+ else if (!parms->aborting)
+ report_progress(cmd, idl->id, lpdp.parms);
+ }
+
+ _nanosleep(lpdp.parms->interval, 0);
+ }
+
+ if (first)
+ dm_pool_free(cmd->mem, dm_list_item(first, struct poll_id_list));
+}
+
+static int _lvmpoll_daemon(struct cmd_context *cmd, struct poll_operation_id *id,
+ struct daemon_parms *parms)
+{
+ int r;
+ struct processing_handle *handle = NULL;
+ unsigned finished = 0;
+
+ if (parms->aborting)
+ parms->interval = 0;
+
+ if (id) {
+ r = lvmpolld_poll_init(cmd, id, parms);
+ if (r && !parms->background) {
+ while (1) {
+ if (!(r = lvmpolld_request_info(id, parms, &finished)) ||
+ finished ||
+ (!parms->aborting && !(r = report_progress(cmd, id, parms))))
+ break;
+
+ _nanosleep(parms->interval, 0);
+ }
+ }
+
+ return r ? ECMD_PROCESSED : ECMD_FAILED;
+ } else {
+ /* process all in-flight operations */
+ if (!(handle = init_processing_handle(cmd))) {
+ log_error("Failed to initialize processing handle.");
+ return ECMD_FAILED;
+ } else {
+ _lvmpolld_poll_for_all_vgs(cmd, parms, handle);
+ destroy_processing_handle(cmd, handle);
+ return ECMD_PROCESSED;
+ }
+ }
+}
+#else
+# define _lvmpoll_daemon(cmd, id, parms) (ECMD_FAILED)
+#endif /* LVMPOLLD_SUPPORT */
+
/*
* Only allow *one* return from poll_daemon() (the parent).
* If there is a child it must exit (ignoring the memory leak messages).
@@ -463,7 +632,11 @@ int poll_daemon(struct cmd_context *cmd, unsigned background,
if (!_daemon_parms_init(cmd, &parms, background, poll_fns, progress_title, lv_type))
return_EINVALID_CMD_LINE;
- /* classical polling allows only PMVOVE or 0 values */
- parms.lv_type &= PVMOVE;
- return _poll_daemon(cmd, id, &parms);
+ if (lvmpolld_use())
+ return _lvmpoll_daemon(cmd, id, &parms);
+ else {
+ /* classical polling allows only PMVOVE or 0 values */
+ parms.lv_type &= PVMOVE;
+ return _poll_daemon(cmd, id, &parms);
+ }
}
diff --git a/tools/polldaemon.h b/tools/polldaemon.h
deleted file mode 100644
index 6309a5f..0000000
--- a/tools/polldaemon.h
+++ /dev/null
@@ -1,93 +0,0 @@
-/*
- * Copyright (C) 2003-2004 Sistina Software, Inc. All rights reserved.
- * Copyright (C) 2004-2015 Red Hat, Inc. All rights reserved.
- *
- * This file is part of LVM2.
- *
- * This copyrighted material is made available to anyone wishing to use,
- * modify, copy, or redistribute it subject to the terms and conditions
- * of the GNU Lesser General Public License v.2.1.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#ifndef _LVM_TOOL_POLLDAEMON_H
-#define _LVM_TOOL_POLLDAEMON_H
-
-#include "metadata-exported.h"
-
-typedef enum {
- PROGRESS_CHECK_FAILED = 0,
- PROGRESS_UNFINISHED = 1,
- PROGRESS_FINISHED_SEGMENT = 2,
- PROGRESS_FINISHED_ALL = 3
-} progress_t;
-
-struct daemon_parms;
-
-struct poll_functions {
- const char *(*get_copy_name_from_lv) (const struct logical_volume *lv);
- struct volume_group *(*get_copy_vg) (struct cmd_context *cmd,
- const char *name,
- const char *uuid,
- uint32_t flags);
- struct logical_volume *(*get_copy_lv) (struct cmd_context *cmd,
- struct volume_group *vg,
- const char *name,
- const char *uuid,
- uint64_t lv_type);
- progress_t (*poll_progress)(struct cmd_context *cmd,
- struct logical_volume *lv,
- const char *name,
- struct daemon_parms *parms);
- int (*update_metadata) (struct cmd_context *cmd,
- struct volume_group *vg,
- struct logical_volume *lv,
- struct dm_list *lvs_changed, unsigned flags);
- int (*finish_copy) (struct cmd_context *cmd,
- struct volume_group *vg,
- struct logical_volume *lv,
- struct dm_list *lvs_changed);
-};
-
-struct poll_operation_id {
- const char *vg_name;
- const char *lv_name;
- const char *display_name;
- const char *uuid;
-};
-
-struct daemon_parms {
- unsigned interval;
- unsigned wait_before_testing;
- unsigned aborting;
- unsigned background;
- unsigned outstanding_count;
- unsigned progress_display;
- const char *progress_title;
- uint64_t lv_type;
- struct poll_functions *poll_fns;
-};
-
-int poll_daemon(struct cmd_context *cmd, unsigned background,
- uint64_t lv_type, struct poll_functions *poll_fns,
- const char *progress_title, struct poll_operation_id *id);
-
-progress_t poll_mirror_progress(struct cmd_context *cmd,
- struct logical_volume *lv, const char *name,
- struct daemon_parms *parms);
-
-struct volume_group *poll_get_copy_vg(struct cmd_context *cmd, const char *name,
- const char *uuid, uint32_t flags);
-
-struct logical_volume *poll_get_copy_lv(struct cmd_context *cmd,
- struct volume_group *vg,
- const char *name, const char *uuid,
- uint64_t lv_type);
-
-int wait_for_single_lv(struct cmd_context *cmd, struct poll_operation_id *id,
- struct daemon_parms *parms);
-
-#endif
diff --git a/tools/pvmove.c b/tools/pvmove.c
index 70fba99..202c87c 100644
--- a/tools/pvmove.c
+++ b/tools/pvmove.c
@@ -728,7 +728,7 @@ static int _read_poll_id_from_pvname(struct cmd_context *cmd, const char *pv_nam
}
if (!(lv = find_pvmove_lv(vg, pv_dev(pv), PVMOVE))) {
- log_print_unless_silent("%s: no pvmove in progress - already finished or aborted.",
+ log_print_unless_silent("%s: No pvmove in progress - already finished or aborted.",
pv_name);
ret = 1;
*in_progress = 0;
9 years
master - lvmcache: set device in label when switching devs V2
by David Teigland
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=be23fae488b7df...
Commit: be23fae488b7df19147259d3e8505fc8301076cd
Parent: ca67cf84df6015c990618de3dc45c0b87eee75ce
Author: David Teigland <teigland(a)redhat.com>
AuthorDate: Fri May 8 17:10:53 2015 -0500
Committer: David Teigland <teigland(a)redhat.com>
CommitterDate: Fri May 8 17:10:53 2015 -0500
lvmcache: set device in label when switching devs V2
This is an alternative/equivalent to commit
ca67cf84df6015c990618de3dc45c0b87eee75ce
The problem (wrong label->dev after a new preferred
duplicate device is chosen) was isolated to the lvmetad
case (non-lvmetad worked fine), and this fixes the problem
by setting the new label->dev in the lvmetad-specific
code rather than in the general lvmcache code.
---
lib/cache/lvmcache.c | 1 -
lib/cache/lvmetad.c | 1 +
2 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/lib/cache/lvmcache.c b/lib/cache/lvmcache.c
index ad58115..d44f9d4 100644
--- a/lib/cache/lvmcache.c
+++ b/lib/cache/lvmcache.c
@@ -1880,7 +1880,6 @@ struct lvmcache_info *lvmcache_add(struct labeller *labeller, const char *pvid,
info->label->info = info;
}
label = info->label;
- label->dev = dev;
}
info->fmt = labeller->fmt;
diff --git a/lib/cache/lvmetad.c b/lib/cache/lvmetad.c
index 0a79c50..a66f915 100644
--- a/lib/cache/lvmetad.c
+++ b/lib/cache/lvmetad.c
@@ -372,6 +372,7 @@ static int _pv_populate_lvmcache(struct cmd_context *cmd,
vgname, (const char *)&vgid, 0))) {
dev_alternate_cache = dev_alternate;
info = info_alternate;
+ lvmcache_get_label(info)->dev = dev_alternate;
}
} else {
log_warn("Duplicate of PV %s dev %s exists on unknown device %"PRId64 ":%" PRId64,
9 years
master - lvmcache: set device in label when switching devs
by David Teigland
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=ca67cf84df6015...
Commit: ca67cf84df6015c990618de3dc45c0b87eee75ce
Parent: 53aff9322e6be8f805688445fb7d7d8825d53692
Author: David Teigland <teigland(a)redhat.com>
AuthorDate: Fri May 8 14:38:26 2015 -0500
Committer: David Teigland <teigland(a)redhat.com>
CommitterDate: Fri May 8 14:41:05 2015 -0500
lvmcache: set device in label when switching devs
When using lvmetad, the reporter code was not reporting
the new preferred device because the new preferred dev
was not being set in the label struct.
---
lib/cache/lvmcache.c | 1 +
1 files changed, 1 insertions(+), 0 deletions(-)
diff --git a/lib/cache/lvmcache.c b/lib/cache/lvmcache.c
index d44f9d4..ad58115 100644
--- a/lib/cache/lvmcache.c
+++ b/lib/cache/lvmcache.c
@@ -1880,6 +1880,7 @@ struct lvmcache_info *lvmcache_add(struct labeller *labeller, const char *pvid,
info->label->info = info;
}
label = info->label;
+ label->dev = dev;
}
info->fmt = labeller->fmt;
9 years
master - tests: better filter
by Zdenek Kabelac
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=53aff9322e6be8...
Commit: 53aff9322e6be8f805688445fb7d7d8825d53692
Parent: 1d832aef09c8a96308441750b475ca96b7c91cc3
Author: Zdenek Kabelac <zkabelac(a)redhat.com>
AuthorDate: Fri May 8 20:44:43 2015 +0200
Committer: Zdenek Kabelac <zkabelac(a)redhat.com>
CommitterDate: Fri May 8 21:00:10 2015 +0200
tests: better filter
Filter $PREFIX rather then just LVMTEST.
---
test/lib/aux.sh | 4 ++--
test/lib/utils.sh | 2 +-
2 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/test/lib/aux.sh b/test/lib/aux.sh
index 80792f5..d1d38f8 100644
--- a/test/lib/aux.sh
+++ b/test/lib/aux.sh
@@ -95,7 +95,7 @@ prepare_lvmetad() {
kill_sleep_kill_ LOCAL_LVMETAD ${LVM_VALGRIND_LVMETAD:-0}
# Avoid reconfiguring, if already set to use_lvmetad
- (grep use_lvmetad CONFIG_VALUES 2>/dev/null | tail -1 | grep -q 1) || \
+ (grep use_lvmetad CONFIG_VALUES 2>/dev/null | tail -n 1 | grep -q 1) || \
aux lvmconf "global/use_lvmetad = 1" "devices/md_component_detection = 0"
# Default debug is "-l all" and could be override
# by setting LVM_TEST_LVMETAD_DEBUG_OPTS before calling inittest.
@@ -735,7 +735,7 @@ extend_filter() {
}
extend_filter_LVMTEST() {
- extend_filter "a|$DM_DEV_DIR/LVMTEST|"
+ extend_filter "a|$DM_DEV_DIR/$PREFIX|"
}
hide_dev() {
diff --git a/test/lib/utils.sh b/test/lib/utils.sh
index ba3ba34..fe7ccd3 100644
--- a/test/lib/utils.sh
+++ b/test/lib/utils.sh
@@ -166,7 +166,7 @@ STACKTRACE() {
"$DM_DEV_DIR" | sed -e "s,^,## LSLR: ,"
echo "<======== Udev DB content ========>"
for i in /sys/block/dm-* /sys/block/loop* ; do
- udevadm info --query=all --path "$i" || true
+ udevadm info --query=all --path "$i" 2>/dev/null || true
done | sed -e "s,^,## UDEV: ,"
fi
echo "<======== Script file \"$(< TESTNAME)\" ========>"
9 years
master - tests: missing vg
by Zdenek Kabelac
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=1d832aef09c8a9...
Commit: 1d832aef09c8a96308441750b475ca96b7c91cc3
Parent: 8e509b5dd50bff30e5017f572e54f4f384830a58
Author: Zdenek Kabelac <zkabelac(a)redhat.com>
AuthorDate: Fri May 8 19:17:00 2015 +0200
Committer: Zdenek Kabelac <zkabelac(a)redhat.com>
CommitterDate: Fri May 8 21:00:10 2015 +0200
tests: missing vg
---
test/shell/lvconvert-repair-transient.sh | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/test/shell/lvconvert-repair-transient.sh b/test/shell/lvconvert-repair-transient.sh
index 9bf6a9d..c9253f4 100644
--- a/test/shell/lvconvert-repair-transient.sh
+++ b/test/shell/lvconvert-repair-transient.sh
@@ -25,7 +25,7 @@ dmsetup status
echo n | lvconvert --repair $vg/4way 2>&1 | tee 4way.out
aux enable_dev --silent "$dev2" "$dev4"
-lvs -a -o +devices | tee out
+lvs -a -o +devices $vg | tee out
not grep unknown out
vgreduce --removemissing $vg
check mirror $vg 4way
9 years
master - toollib: avoid repeated lvmetad vg_lookup
by David Teigland
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=8e509b5dd50bff...
Commit: 8e509b5dd50bff30e5017f572e54f4f384830a58
Parent: f25132b354b110994b9da8dc3edf39cf4db37657
Author: David Teigland <teigland(a)redhat.com>
AuthorDate: Tue May 5 16:24:50 2015 -0500
Committer: David Teigland <teigland(a)redhat.com>
CommitterDate: Fri May 8 11:44:55 2015 -0500
toollib: avoid repeated lvmetad vg_lookup
In process_each_{vg,lv,pv} when no vgname args are given,
the first step is to get a list of all vgid/vgname on the
system. This is exactly what lvmetad returns from a
vg_list request. The current code is doing a vg_lookup
on each VG after the vg_list and populating lvmcache with
the info for each VG. These preliminary vg_lookup's are
unnecessary, because they will be done again when the
processing functions call vg_read. This patch eliminates
the initial round of vg_lookup's, which can roughly cut in
half the number of lvmetad requests and save a lot of extra work.
---
lib/cache/lvmcache.c | 31 +++++++++++++
lib/cache/lvmcache.h | 3 +
lib/cache/lvmetad.c | 50 +++++++++++++++++++++
lib/cache/lvmetad.h | 6 +++
lib/metadata/metadata-exported.h | 8 +++
lib/metadata/metadata.c | 48 ++++++++++++++++++++
tools/toollib.c | 91 +++++++-------------------------------
7 files changed, 162 insertions(+), 75 deletions(-)
diff --git a/lib/cache/lvmcache.c b/lib/cache/lvmcache.c
index 1586f30..d44f9d4 100644
--- a/lib/cache/lvmcache.c
+++ b/lib/cache/lvmcache.c
@@ -905,6 +905,37 @@ int lvmcache_vginfo_holders_dec_and_test_for_zero(struct lvmcache_vginfo *vginfo
}
// #endif
+int lvmcache_get_vgnameids(struct cmd_context *cmd, int include_internal,
+ struct dm_list *vgnameids)
+{
+ struct vgnameid_list *vgnl;
+ struct lvmcache_vginfo *vginfo;
+
+ lvmcache_label_scan(cmd, 0);
+
+ dm_list_iterate_items(vginfo, &_vginfos) {
+ if (!include_internal && is_orphan_vg(vginfo->vgname))
+ continue;
+
+ if (!(vgnl = dm_pool_alloc(cmd->mem, sizeof(*vgnl)))) {
+ log_error("vgnameid_list allocation failed.");
+ return 0;
+ }
+
+ vgnl->vgid = dm_pool_strdup(cmd->mem, vginfo->vgid);
+ vgnl->vg_name = dm_pool_strdup(cmd->mem, vginfo->vgname);
+
+ if (!vgnl->vgid || !vgnl->vg_name) {
+ log_error("vgnameid_list member allocation failed.");
+ return 0;
+ }
+
+ dm_list_add(vgnameids, &vgnl->list);
+ }
+
+ return 1;
+}
+
struct dm_list *lvmcache_get_vgids(struct cmd_context *cmd,
int include_internal)
{
diff --git a/lib/cache/lvmcache.h b/lib/cache/lvmcache.h
index 6a43204..780325a 100644
--- a/lib/cache/lvmcache.h
+++ b/lib/cache/lvmcache.h
@@ -107,6 +107,9 @@ struct dm_list *lvmcache_get_vgnames(struct cmd_context *cmd,
struct dm_list *lvmcache_get_vgids(struct cmd_context *cmd,
int include_internal);
+int lvmcache_get_vgnameids(struct cmd_context *cmd, int include_internal,
+ struct dm_list *vgnameids);
+
/* Returns list of struct dm_str_list containing pool-allocated copy of pvids */
struct dm_list *lvmcache_get_pvids(struct cmd_context *cmd, const char *vgname,
const char *vgid);
diff --git a/lib/cache/lvmetad.c b/lib/cache/lvmetad.c
index fd0630f..0a79c50 100644
--- a/lib/cache/lvmetad.c
+++ b/lib/cache/lvmetad.c
@@ -673,6 +673,56 @@ int lvmetad_pv_list_to_lvmcache(struct cmd_context *cmd)
return 1;
}
+int lvmetad_get_vgnameids(struct cmd_context *cmd, struct dm_list *vgnameids)
+{
+ struct vgnameid_list *vgnl;
+ struct id vgid;
+ const char *vgid_txt;
+ const char *vg_name;
+ daemon_reply reply;
+ struct dm_config_node *cn;
+
+ log_debug_lvmetad("Asking lvmetad for complete list of known VG ids/names");
+ reply = _lvmetad_send("vg_list", NULL);
+ if (!_lvmetad_handle_reply(reply, "list VGs", "", NULL)) {
+ daemon_reply_destroy(reply);
+ return_0;
+ }
+
+ if ((cn = dm_config_find_node(reply.cft->root, "volume_groups"))) {
+ for (cn = cn->child; cn; cn = cn->sib) {
+ vgid_txt = cn->key;
+ if (!id_read_format(&vgid, vgid_txt)) {
+ stack;
+ continue;
+ }
+
+ if (!(vgnl = dm_pool_alloc(cmd->mem, sizeof(*vgnl)))) {
+ log_error("vgnameid_list allocation failed.");
+ return 0;
+ }
+
+ if (!(vg_name = dm_config_find_str(cn->child, "name", NULL))) {
+ log_error("vg_list no name found.");
+ return 0;
+ }
+
+ vgnl->vgid = dm_pool_strdup(cmd->mem, (char *)&vgid);
+ vgnl->vg_name = dm_pool_strdup(cmd->mem, vg_name);
+
+ if (!vgnl->vgid || !vgnl->vg_name) {
+ log_error("vgnameid_list member allocation failed.");
+ return 0;
+ }
+
+ dm_list_add(vgnameids, &vgnl->list);
+ }
+ }
+
+ daemon_reply_destroy(reply);
+ return 1;
+}
+
int lvmetad_vg_list_to_lvmcache(struct cmd_context *cmd)
{
struct volume_group *tmp;
diff --git a/lib/cache/lvmetad.h b/lib/cache/lvmetad.h
index b5bac69..4ee07bb 100644
--- a/lib/cache/lvmetad.h
+++ b/lib/cache/lvmetad.h
@@ -143,6 +143,12 @@ int lvmetad_pv_lookup_by_dev(struct cmd_context *cmd, struct device *dev, int *f
int lvmetad_vg_list_to_lvmcache(struct cmd_context *cmd);
/*
+ * Request a list of vgid/vgname pairs for all VGs known to lvmetad.
+ * Does not do vg_lookup's on each VG, and does not populate lvmcache.
+ */
+int lvmetad_get_vgnameids(struct cmd_context *cmd, struct dm_list *vgnameids);
+
+/*
* Find a VG by its ID or its name in the lvmetad cache. Gives NULL if the VG is
* not found.
*/
diff --git a/lib/metadata/metadata-exported.h b/lib/metadata/metadata-exported.h
index 47fb9ae..0e52153 100644
--- a/lib/metadata/metadata-exported.h
+++ b/lib/metadata/metadata-exported.h
@@ -494,6 +494,12 @@ struct vg_list {
struct volume_group *vg;
};
+struct vgnameid_list {
+ struct dm_list list;
+ const char *vg_name;
+ const char *vgid;
+};
+
#define PV_PE_START_CALC ((uint64_t) -1) /* Calculate pe_start value */
struct pvcreate_restorable_params {
@@ -606,6 +612,8 @@ 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 get_vgnameids(struct cmd_context *cmd, struct dm_list *vgnameids,
+ const char *only_this_vgname, int include_internal);
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);
diff --git a/lib/metadata/metadata.c b/lib/metadata/metadata.c
index 2a5be7d..19741ba 100644
--- a/lib/metadata/metadata.c
+++ b/lib/metadata/metadata.c
@@ -4017,6 +4017,54 @@ struct dm_list *get_vgids(struct cmd_context *cmd, int include_internal)
return lvmcache_get_vgids(cmd, include_internal);
}
+int get_vgnameids(struct cmd_context *cmd, struct dm_list *vgnameids,
+ const char *only_this_vgname, int include_internal)
+{
+ struct vgnameid_list *vgnl;
+ struct format_type *fmt;
+
+ if (only_this_vgname) {
+ if (!(vgnl = dm_pool_alloc(cmd->mem, sizeof(*vgnl)))) {
+ log_error("vgnameid_list allocation failed.");
+ return 0;
+ }
+
+ vgnl->vg_name = dm_pool_strdup(cmd->mem, only_this_vgname);
+ vgnl->vgid = NULL;
+ dm_list_add(vgnameids, &vgnl->list);
+ return 1;
+ }
+
+ if (lvmetad_active()) {
+ /*
+ * This just gets the list of names/ids from lvmetad
+ * and does not populate lvmcache.
+ */
+ lvmetad_get_vgnameids(cmd, vgnameids);
+
+ if (include_internal) {
+ dm_list_iterate_items(fmt, &cmd->formats) {
+ if (!(vgnl = dm_pool_alloc(cmd->mem, sizeof(*vgnl)))) {
+ log_error("vgnameid_list allocation failed.");
+ return 0;
+ }
+
+ vgnl->vg_name = dm_pool_strdup(cmd->mem, fmt->orphan_vg_name);
+ vgnl->vgid = NULL;
+ dm_list_add(vgnameids, &vgnl->list);
+ }
+ }
+ } else {
+ /*
+ * The non-lvmetad case. This function begins by calling
+ * lvmcache_label_scan() to populate lvmcache.
+ */
+ lvmcache_get_vgnameids(cmd, include_internal, vgnameids);
+ }
+
+ return 1;
+}
+
static int _get_pvs(struct cmd_context *cmd, uint32_t warn_flags,
struct dm_list *pvslist, struct dm_list *vgslist)
{
diff --git a/tools/toollib.c b/tools/toollib.c
index e6c3cdb..ae48e7b 100644
--- a/tools/toollib.c
+++ b/tools/toollib.c
@@ -1515,12 +1515,6 @@ int validate_restricted_lvname_param(struct cmd_context *cmd, const char **vg_na
return -1;
}
-struct vgnameid_list {
- struct dm_list list;
- const char *vg_name;
- const char *vgid;
-};
-
/*
* Extract list of VG names and list of tags from command line arguments.
*/
@@ -1584,67 +1578,6 @@ static int _get_arg_vgnames(struct cmd_context *cmd,
return ret_max;
}
-/*
- * FIXME Add arg to include (or not) entries with duplicate vg names?
- *
- * 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,
- 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))
- stack;
-
- /*
- * Start with complete vgid list because multiple VGs might have same name.
- */
- vgids = get_vgids(cmd, include_internal);
- if (!vgids || dm_list_empty(vgids)) {
- stack;
- return ECMD_PROCESSED;
- }
-
- /* FIXME get_vgids() should provide these pairings directly */
- dm_list_iterate_items(sl, vgids) {
- if (!(vgid = sl->str))
- continue;
-
- if (!(vgnl = dm_pool_alloc(cmd->mem, sizeof(*vgnl)))) {
- log_error("vgnameid_list allocation failed.");
- return ECMD_FAILED;
- }
-
- vgnl->vgid = dm_pool_strdup(cmd->mem, vgid);
- vgnl->vg_name = lvmcache_vgname_from_vgid(cmd->mem, vgid);
-
- dm_list_add(vgnameids_on_system, &vgnl->list);
- }
-
- return ECMD_PROCESSED;
-}
-
struct processing_handle *init_processing_handle(struct cmd_context *cmd)
{
struct processing_handle *handle;
@@ -1903,7 +1836,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, NULL, 0)) != ECMD_PROCESSED))
+ !get_vgnameids(cmd, &vgnameids_on_system, NULL, 0))
goto_out;
if (dm_list_empty(&arg_vgnames) && dm_list_empty(&vgnameids_on_system)) {
@@ -2304,6 +2237,7 @@ int process_each_lv(struct cmd_context *cmd, int argc, char **argv, uint32_t fla
struct dm_list vgnameids_to_process; /* vgnameid_list */
int enable_all_vgs = (cmd->command->flags & ALL_VGS_IS_DEFAULT);
+ int need_vgnameids = 0;
int ret;
cmd->error_foreign_vgs = 0;
@@ -2330,11 +2264,17 @@ int process_each_lv(struct cmd_context *cmd, int argc, char **argv, uint32_t fla
/*
* Obtain the complete list of VGs present on the system if it is needed because:
* any tags were supplied and need resolving; or
+ * no VG names were given and the select option needs resolving; or
* no VG names were given and the command defaults to processing all VGs.
*/
- if (((dm_list_empty(&arg_vgnames) && (enable_all_vgs ||
- handle->internal_report_for_select)) || !dm_list_empty(&arg_tags)) &&
- (ret = _get_vgnameids_on_system(cmd, &vgnameids_on_system, NULL, 0) != ECMD_PROCESSED))
+ if (!dm_list_empty(&arg_tags))
+ need_vgnameids = 1;
+ else if (dm_list_empty(&arg_vgnames) && enable_all_vgs)
+ need_vgnameids = 1;
+ else if (dm_list_empty(&arg_vgnames) && handle->internal_report_for_select)
+ need_vgnameids = 1;
+
+ if (need_vgnameids && !get_vgnameids(cmd, &vgnameids_on_system, NULL, 0))
goto_out;
if (dm_list_empty(&arg_vgnames) && dm_list_empty(&vgnameids_on_system)) {
@@ -2822,11 +2762,12 @@ int process_each_pv(struct cmd_context *cmd,
arg_count(cmd, all_ARG);
/*
- * Read all the vgs here because this has the effect of initializing
- * device/lvmcache info so that dev->pvid is available when creating
- * a list of devices.
+ * Need pvid's set on all PVs before processing so that pvid's
+ * can be compared to find duplicates while processing.
*/
- if ((ret = _get_vgnameids_on_system(cmd, &all_vgnameids, only_this_vgname, 1) != ECMD_PROCESSED)) {
+ lvmcache_seed_infos_from_lvmetad(cmd);
+
+ if (!get_vgnameids(cmd, &all_vgnameids, only_this_vgname, 1)) {
stack;
return ret;
}
9 years
master - lvmcache: choose preferred device once
by David Teigland
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=f25132b354b110...
Commit: f25132b354b110994b9da8dc3edf39cf4db37657
Parent: 1dfedcc179b6f7caee1069974ab34ddd111ef01d
Author: David Teigland <teigland(a)redhat.com>
AuthorDate: Wed May 6 14:49:44 2015 -0500
Committer: David Teigland <teigland(a)redhat.com>
CommitterDate: Fri May 8 11:44:49 2015 -0500
lvmcache: choose preferred device once
Once the preferred duplicate devices have been set in
lvmcache, don't attempt to pick preferred duplicates
again.
---
lib/cache/lvmcache.c | 58 ++++++++++++++++++++++++++++++++++++++++++++++++-
lib/cache/lvmcache.h | 2 +
lib/cache/lvmetad.c | 19 ++++++++-------
3 files changed, 68 insertions(+), 11 deletions(-)
diff --git a/lib/cache/lvmcache.c b/lib/cache/lvmcache.c
index 0d13c16..1586f30 100644
--- a/lib/cache/lvmcache.c
+++ b/lib/cache/lvmcache.c
@@ -67,6 +67,7 @@ struct lvmcache_vginfo {
unsigned vg_use_count; /* Counter of vg reusage */
unsigned precommitted; /* Is vgmetadata live or precommitted? */
unsigned cached_vg_invalidated; /* Signal to regenerate cached_vg */
+ unsigned preferred_duplicates; /* preferred duplicate pvs have been set */
};
static struct dm_hash_table *_pvid_hash = NULL;
@@ -115,6 +116,47 @@ int lvmcache_init(void)
return 1;
}
+/*
+ * Once PV info has been populated in lvmcache and
+ * lvmcache has chosen preferred duplicate devices,
+ * set this flag so that lvmcache will not try to
+ * compare and choose preferred duplicate devices
+ * again (which may result in different preferred
+ * devices.) PV info can be populated in lvmcache
+ * multiple times, each time causing lvmcache to
+ * compare the duplicate devices, so we need to
+ * record that the comparison/preferences have
+ * already been done, so the preferrences from the
+ * first time through are not changed.
+ *
+ * This is something of a hack to work around the
+ * fact that the code isn't really designed to
+ * handle duplicate PVs, and the fact that lvmetad
+ * has its own way of picking a preferred duplicate
+ * and lvmcache has another way based on having
+ * more information than lvmetad does.
+ *
+ * If we come up with a better overall method to
+ * handle duplicate PVs, then this can probably be
+ * removed.
+ *
+ * FIXME: if we want to make lvmetad work with clvmd,
+ * then this may need to be changed to set
+ * preferred_duplicates back to 0.
+ */
+
+void lvmcache_set_preferred_duplicates(const char *vgid)
+{
+ struct lvmcache_vginfo *vginfo;
+
+ if (!(vginfo = lvmcache_vginfo_from_vgid(vgid))) {
+ stack;
+ return;
+ }
+
+ vginfo->preferred_duplicates = 1;
+}
+
void lvmcache_seed_infos_from_lvmetad(struct cmd_context *cmd)
{
if (!lvmetad_active() || _has_scanned)
@@ -1689,6 +1731,18 @@ struct lvmcache_info *lvmcache_add(struct labeller *labeller, const char *pvid,
dev_name(dev));
}
+ if (existing->vginfo->preferred_duplicates) {
+ /*
+ * The preferred duplicate devs have already
+ * been chosen during a previous populating of
+ * lvmcache, so just use the existing preferences.
+ */
+ log_verbose("Found duplicate PV %s: using existing dev %s",
+ pvid_s,
+ dev_name(existing->dev));
+ return NULL;
+ }
+
if (old_in_subsystem && !new_in_subsystem) {
/* Use old, ignore new. */
log_warn("Found duplicate PV %s: using %s not %s",
@@ -1741,7 +1795,7 @@ struct lvmcache_info *lvmcache_add(struct labeller *labeller, const char *pvid,
pvid_s,
dev_name(dev),
dev_name(existing->dev));
- log_warn("Using duplicate PV %s which is more recent, replacing %s",
+ log_warn("Using duplicate PV %s which is last seen, replacing %s",
dev_name(dev),
dev_name(existing->dev));
@@ -1754,7 +1808,7 @@ struct lvmcache_info *lvmcache_add(struct labeller *labeller, const char *pvid,
pvid_s,
dev_name(dev),
dev_name(existing->dev));
- log_warn("Using duplicate PV %s which is more recent, replacing %s",
+ log_warn("Using duplicate PV %s which is last seen, replacing %s",
dev_name(dev),
dev_name(existing->dev));
}
diff --git a/lib/cache/lvmcache.h b/lib/cache/lvmcache.h
index 6c4c927..6a43204 100644
--- a/lib/cache/lvmcache.h
+++ b/lib/cache/lvmcache.h
@@ -171,4 +171,6 @@ void lvmcache_replace_dev(struct cmd_context *cmd, struct physical_volume *pv,
int lvmcache_found_duplicate_pvs(void);
+void lvmcache_set_preferred_duplicates(const char *vgid);
+
#endif
diff --git a/lib/cache/lvmetad.c b/lib/cache/lvmetad.c
index 00a84b5..fd0630f 100644
--- a/lib/cache/lvmetad.c
+++ b/lib/cache/lvmetad.c
@@ -265,9 +265,9 @@ static int _read_mda(struct lvmcache_info *info,
return 0;
}
-static struct lvmcache_info *_pv_populate_lvmcache(struct cmd_context *cmd,
- struct dm_config_node *cn,
- struct format_type *fmt, dev_t fallback)
+static int _pv_populate_lvmcache(struct cmd_context *cmd,
+ struct dm_config_node *cn,
+ struct format_type *fmt, dev_t fallback)
{
struct device *dev, *dev_alternate, *dev_alternate_cache = NULL;
struct label *label;
@@ -293,7 +293,7 @@ static struct lvmcache_info *_pv_populate_lvmcache(struct cmd_context *cmd,
if (!fmt) {
log_error("PV %s not recognised. Is the device missing?", pvid_txt);
- return NULL;
+ return 0;
}
dev = dev_cache_get_by_devt(devt, cmd->filter);
@@ -302,17 +302,17 @@ static struct lvmcache_info *_pv_populate_lvmcache(struct cmd_context *cmd,
if (!dev) {
log_warn("WARNING: Device for PV %s not found or rejected by a filter.", pvid_txt);
- return NULL;
+ return 0;
}
if (!pvid_txt || !id_read_format(&pvid, pvid_txt)) {
log_error("Missing or ill-formatted PVID for PV: %s.", pvid_txt);
- return NULL;
+ return 0;
}
if (vgid_txt) {
if (!id_read_format(&vgid, vgid_txt))
- return_NULL;
+ return_0;
} else
strcpy((char*)&vgid, fmt->orphan_vg_name);
@@ -321,7 +321,7 @@ static struct lvmcache_info *_pv_populate_lvmcache(struct cmd_context *cmd,
if (!(info = lvmcache_add(fmt->labeller, (const char *)&pvid, dev,
vgname, (const char *)&vgid, 0)))
- return_NULL;
+ return_0;
lvmcache_get_label(info)->sector = label_sector;
lvmcache_get_label(info)->dev = dev;
@@ -390,7 +390,8 @@ static struct lvmcache_info *_pv_populate_lvmcache(struct cmd_context *cmd,
}
}
- return info;
+ lvmcache_set_preferred_duplicates((const char *)&vgid);
+ return 1;
}
struct volume_group *lvmetad_vg_lookup(struct cmd_context *cmd, const char *vgname, const char *vgid)
9 years