zbyszek / rpms / lvm2

Forked from rpms/lvm2 4 years ago
Clone
Blob Blame History Raw
 WHATS_NEW                                          |   10 ++
 WHATS_NEW_DM                                       |   10 ++
 configure                                          |  144 +++++++++++++++-----
 configure.in                                       |   81 ++++++++---
 daemons/dmeventd/dmeventd.h                        |    4 +-
 daemons/lvmetad/lvmetad-core.c                     |    2 +-
 doc/example.conf.in                                |    9 ++
 lib/activate/activate.c                            |   24 +++-
 lib/activate/activate.h                            |    5 +
 lib/cache/lvmetad.c                                |   39 ++++--
 lib/cache/lvmetad.h                                |   19 +--
 lib/device/dev-io.c                                |    2 +-
 lib/metadata/lv_manip.c                            |    9 ++
 lib/metadata/metadata-exported.h                   |   11 +-
 lib/metadata/metadata.c                            |    3 +-
 lib/misc/configure.h.in                            |   11 +-
 man/lvchange.8.in                                  |   12 +-
 man/lvcreate.8.in                                  |   16 ++-
 man/lvm.conf.5.in                                  |   11 ++
 man/pvscan.8.in                                    |    8 ++
 man/vgchange.8.in                                  |   11 +-
 scripts/Makefile.in                                |    8 +-
 scripts/dm_event_systemd_red_hat.service.in        |    1 +
 scripts/dm_event_systemd_red_hat.socket            |   11 --
 scripts/dm_event_systemd_red_hat.socket.in         |   12 ++
 scripts/lvm2_lvmetad_init_red_hat.in               |    2 +-
 scripts/lvm2_lvmetad_systemd_red_hat.service.in    |    3 +-
 scripts/lvm2_lvmetad_systemd_red_hat.socket.in     |    1 +
 scripts/lvm2_monitoring_systemd_red_hat.service.in |    1 +
 tools/args.h                                       |    3 +-
 tools/commands.h                                   |   44 +++---
 tools/lvchange.c                                   |   31 +++--
 tools/lvcreate.c                                   |   10 +-
 tools/lvmcmdline.c                                 |   11 +-
 tools/pvremove.c                                   |    2 +-
 tools/pvscan.c                                     |   40 +++++-
 tools/toollib.c                                    |    2 +-
 tools/tools.h                                      |    5 +-
 tools/vgchange.c                                   |   51 +++----
 udev/10-dm.rules.in                                |   12 +-
 udev/11-dm-lvm.rules                               |   37 -----
 udev/11-dm-lvm.rules.in                            |   37 +++++
 udev/69-dm-lvm-metad.rules                         |   30 ----
 udev/69-dm-lvm-metad.rules.in                      |   26 ++++
 udev/95-dm-notify.rules                            |   12 --
 udev/95-dm-notify.rules.in                         |   12 ++
 udev/Makefile.in                                   |   33 +++--
 47 files changed, 590 insertions(+), 288 deletions(-)

diff --git a/WHATS_NEW b/WHATS_NEW
index 89e26b5..d779fda 100644
--- a/WHATS_NEW
+++ b/WHATS_NEW
@@ -1,3 +1,13 @@
+Version 2.02.97 - 
+===============================
+  Update man pages with --activate ay option and auto_activation_volume_list.
+  Use vgchange -aay instead of vgchange -ay in clmvd init script.
+  Add activation/auto_activation_volume_list to lvm.conf.
+  Add --activate ay to lvcreate, lvchange, pvscan and vgchange.
+  Add support for volume autoactivation using lvmetad.
+  Add --activate synonym for --available arg and prefer --activate.
+  Open device read-only to obtain readahead value.
+
 Version 2.02.96 - 8th June 2012
 ===============================
   Upstream source repo now fedorahosted.org git not sources.redhat.com CVS.
diff --git a/WHATS_NEW_DM b/WHATS_NEW_DM
index 1246f19..52f9142 100644
--- a/WHATS_NEW_DM
+++ b/WHATS_NEW_DM
@@ -1,3 +1,13 @@
+Version 1.02.76 - 
+===============================
+  Add configure --enable-udev-rule-exec-detection to detect exec path in rules.
+  Use sbindir in udev rules by default and remove executable path detection.
+  Remove hard-coded paths for dmeventd fifos and use default-dm-run-dir.
+  Add configure --with-lvmetad-pidfile to remove hard-coded value.
+  Add configure --with-default-pid-dir for common directory with pid files.
+  Add configure --with-default-dm-run-dir to set run directory for dm tools.
+  Add documentation references in systemd units.
+
 Version 1.02.75 - 8th June 2012
 ===============================
   Upstream source repo now fedorahosted.org git not sources.redhat.com CVS.
diff --git a/configure b/configure
index a7907a6..fc54774 100755
--- a/configure
+++ b/configure
@@ -605,9 +605,11 @@ kernelvsn
 missingkernel
 kerneldir
 interface
+LVMETAD_PIDFILE
 DMEVENTD_PIDFILE
 WRITE_INSTALL
 UDEV_HAS_BUILTIN_BLKID
+UDEV_RULE_EXEC_DETECTION
 UDEV_SYNC
 UDEV_RULES
 UDEV_PC
@@ -659,6 +661,7 @@ DMEVENTD
 DL_LIBS
 DEVMAPPER
 DEFAULT_RUN_DIR
+DEFAULT_DM_RUN_DIR
 DEFAULT_LOCK_DIR
 DEFAULT_DATA_ALIGNMENT
 DEFAULT_CACHE_SUBDIR
@@ -821,6 +824,9 @@ enable_readline
 enable_realtime
 enable_ocf
 with_ocfdir
+with_default_pid_dir
+with_default_dm_run_dir
+with_default_run_dir
 with_clvmd
 with_clvmd_pidfile
 enable_cmirrord
@@ -832,8 +838,10 @@ enable_testing
 enable_valgrind_pool
 enable_devmapper
 enable_lvmetad
+with_lvmetad_pidfile
 enable_udev_sync
 enable_udev_rules
+enable_udev_rule_exec_detection
 enable_compat
 enable_units_compat
 enable_ioctl
@@ -858,7 +866,6 @@ with_systemdsystemunitdir
 with_tmpfilesdir
 with_dmeventd_pidfile
 with_dmeventd_path
-with_default_run_dir
 with_default_system_dir
 with_default_archive_subdir
 with_default_backup_subdir
@@ -1537,6 +1544,8 @@ Optional Features:
   --enable-lvmetad        enable the LVM Metadata Daemon
   --enable-udev_sync      enable synchronisation with udev processing
   --enable-udev_rules     install rule files needed for udev synchronisation
+  --enable-udev-rule-exec-detection
+                          enable executable path detection in udev rules
   --enable-compat         enable support for old device-mapper versions
   --enable-units-compat   enable output compatibility with old versions that
                           that do not use KiB-style unit suffixes
@@ -1583,6 +1592,12 @@ Optional Packages:
   --with-thin-check=PATH  thin_check tool: [[autodetect]]
   --with-ocfdir=DIR       install OCF files in DIR
                           [[PREFIX/lib/ocf/resource.d/lvm2]]
+  --with-default-pid-dir=PID_DIR
+                          Default directory to keep PID files in. [[/var/run]]
+  --with-default-dm-run-dir=DM_RUN_DIR
+                          Default DM run directory. [[/var/run]]
+  --with-default-run-dir=RUN_DIR
+                          Default LVM run directory. [[/var/run/lvm]]
   --with-clvmd=TYPE       build cluster LVM Daemon
                           The following cluster manager combinations are valid:
                            * cman                  (RHEL5 or equivalent)
@@ -1592,11 +1607,13 @@ Optional Packages:
                            * none                  (disable build)
                           [TYPE=none]
   --with-clvmd-pidfile=PATH
-                          clvmd pidfile [[/var/run/clvmd.pid]]
+                          clvmd pidfile [[PID_DIR/clvmd.pid]]
   --with-cmirrord-pidfile=PATH
-                          cmirrord pidfile [[/var/run/cmirrord.pid]]
+                          cmirrord pidfile [[PID_DIR/cmirrord.pid]]
   --with-optimisation=OPT C optimisation flag [[OPT=-O2]]
   --with-veritysetup=TYPE build veritysetup using openssl/nss/gcrypt
+  --with-lvmetad-pidfile=PATH
+                          lvmetad pidfile [[PID_DIR/lvmetad.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]]
@@ -1611,10 +1628,9 @@ Optional Packages:
                           volatile files and directories in DIR
                           [[SYSCONFDIR/tmpfiles.d]]
   --with-dmeventd-pidfile=PATH
-                          dmeventd pidfile [[/var/run/dmeventd.pid]]
+                          dmeventd pidfile [[PID_DIR/dmeventd.pid]]
   --with-dmeventd-path=PATH
                           dmeventd path [[EPREFIX/sbin/dmeventd]]
-  --with-default-run-dir=DIR       Default run directory [/var/run/lvm]
   --with-default-system-dir=DIR
                           default LVM system directory [[/etc/lvm]]
   --with-default-archive-subdir=SUBDIR
@@ -7336,6 +7352,52 @@ fi
 }
 
 ################################################################################
+
+
+# Check whether --with-default-pid-dir was given.
+if test "${with_default_pid_dir+set}" = set; then :
+  withval=$with_default_pid_dir; DEFAULT_PID_DIR="$withval"
+else
+  DEFAULT_PID_DIR="/var/run"
+fi
+
+
+cat >>confdefs.h <<_ACEOF
+#define DEFAULT_PID_DIR "$DEFAULT_PID_DIR"
+_ACEOF
+
+
+
+
+# Check whether --with-default-dm-run-dir was given.
+if test "${with_default_dm_run_dir+set}" = set; then :
+  withval=$with_default_dm_run_dir; DEFAULT_DM_RUN_DIR="$withval"
+else
+  DEFAULT_DM_RUN_DIR="/var/run"
+fi
+
+
+cat >>confdefs.h <<_ACEOF
+#define DEFAULT_DM_RUN_DIR "$DEFAULT_DM_RUN_DIR"
+_ACEOF
+
+
+
+
+# Check whether --with-default-run-dir was given.
+if test "${with_default_run_dir+set}" = set; then :
+  withval=$with_default_run_dir; DEFAULT_RUN_DIR="$withval"
+else
+  DEFAULT_RUN_DIR="/var/run/lvm"
+fi
+
+
+cat >>confdefs.h <<_ACEOF
+#define DEFAULT_RUN_DIR "$DEFAULT_RUN_DIR"
+_ACEOF
+
+
+################################################################################
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to build cluster LVM daemon" >&5
 $as_echo_n "checking whether to build cluster LVM daemon... " >&6; }
 
@@ -8238,7 +8300,7 @@ if test "x$CLVMD" != xnone; then
 if test "${with_clvmd_pidfile+set}" = set; then :
   withval=$with_clvmd_pidfile; CLVMD_PIDFILE=$withval
 else
-  CLVMD_PIDFILE="/var/run/clvmd.pid"
+  CLVMD_PIDFILE="$DEFAULT_PID_DIR/clvmd.pid"
 fi
 
 
@@ -8270,7 +8332,7 @@ if test "x$BUILD_CMIRRORD" = xyes; then
 if test "${with_cmirrord_pidfile+set}" = set; then :
   withval=$with_cmirrord_pidfile; CMIRRORD_PIDFILE=$withval
 else
-  CMIRRORD_PIDFILE="/var/run/cmirrord.pid"
+  CMIRRORD_PIDFILE="$DEFAULT_PID_DIR/cmirrord.pid"
 fi
 
 
@@ -8822,6 +8884,20 @@ if test x$BUILD_LVMETAD = xyes; then
 
 $as_echo "#define LVMETAD_SUPPORT 1" >>confdefs.h
 
+
+
+# Check whether --with-lvmetad-pidfile was given.
+if test "${with_lvmetad_pidfile+set}" = set; then :
+  withval=$with_lvmetad_pidfile; LVMETAD_PIDFILE=$withval
+else
+  LVMETAD_PIDFILE="$DEFAULT_PID_DIR/lvmetad.pid"
+fi
+
+
+cat >>confdefs.h <<_ACEOF
+#define LVMETAD_PIDFILE "$LVMETAD_PIDFILE"
+_ACEOF
+
 fi
 
 ################################################################################
@@ -8949,18 +9025,28 @@ fi
 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $UDEV_RULES" >&5
 $as_echo "$UDEV_RULES" >&6; }
 
-if test x$UDEV_RULES = xyes; then
-	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether udev supports builtin blkid" >&5
-$as_echo_n "checking whether udev supports builtin blkid... " >&6; }
-	udev_version=$(udevadm info --version 2>/dev/null)
-	if test -n "$udev_version" && test "$udev_version" -ge 176; then
-		UDEV_HAS_BUILTIN_BLKID=yes
-	else
-		UDEV_HAS_BUILTIN_BLKID=no
-	fi
-	{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $UDEV_HAS_BUILTIN_BLKID" >&5
-$as_echo "$UDEV_HAS_BUILTIN_BLKID" >&6; }
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to enable executable path detection in udev rules" >&5
+$as_echo_n "checking whether to enable executable path detection in udev rules... " >&6; }
+# Check whether --enable-udev_rule_exec_detection was given.
+if test "${enable_udev_rule_exec_detection+set}" = set; then :
+  enableval=$enable_udev_rule_exec_detection; UDEV_RULE_EXEC_DETECTION=$enableval
+else
+  UDEV_RULE_EXEC_DETECTION=no
+fi
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $UDEV_RULE_EXEC_DETECTION" >&5
+$as_echo "$UDEV_RULE_EXEC_DETECTION" >&6; }
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether udev supports built-in blkid" >&5
+$as_echo_n "checking whether udev supports built-in blkid... " >&6; }
+test x$PKGCONFIG_INIT != x1 && pkg_config_init
+if $($PKG_CONFIG --atleast-version=176 libudev); then
+	UDEV_HAS_BUILTIN_BLKID=yes
+else
+	UDEV_HAS_BUILTIN_BLKID=no
 fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $UDEV_HAS_BUILTIN_BLKID" >&5
+$as_echo "$UDEV_HAS_BUILTIN_BLKID" >&6; }
 
 ################################################################################
 # Check whether --enable-compat was given.
@@ -10633,7 +10719,7 @@ if test "$BUILD_DMEVENTD" = yes; then
 if test "${with_dmeventd_pidfile+set}" = set; then :
   withval=$with_dmeventd_pidfile; DMEVENTD_PIDFILE=$withval
 else
-  DMEVENTD_PIDFILE="/var/run/dmeventd.pid"
+  DMEVENTD_PIDFILE="$DEFAULT_PID_DIR/dmeventd.pid"
 fi
 
 
@@ -10659,20 +10745,6 @@ _ACEOF
 
 fi
 
-
-
-# Check whether --with-default-run-dir was given.
-if test "${with_default_run_dir+set}" = set; then :
-  withval=$with_default_run_dir;  DEFAULT_RUN_DIR="$withval"
-else
-   DEFAULT_RUN_DIR="/var/run/lvm"
-fi
-
-cat >>confdefs.h <<_ACEOF
-#define DEFAULT_RUN_DIR "$DEFAULT_RUN_DIR"
-_ACEOF
-
-
 ################################################################################
 
 # Check whether --with-default-system-dir was given.
@@ -10913,8 +10985,11 @@ 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 doc/Makefile doc/example.conf 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 libdaemon/Makefile libdaemon/client/Makefile libdaemon/server/Makefile libdm/Makefile libdm/libdevmapper.pc liblvm/Makefile liblvm/liblvm2app.pc man/Makefile po/Makefile scripts/clvmd_init_red_hat scripts/cmirrord_init_red_hat scripts/lvm2_lvmetad_init_red_hat scripts/lvm2_lvmetad_systemd_red_hat.socket scripts/lvm2_lvmetad_systemd_red_hat.service scripts/lvm2_monitoring_init_red_hat scripts/dm_event_systemd_red_hat.service scripts/lvm2_monitoring_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 verity/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 doc/Makefile doc/example.conf 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 libdaemon/Makefile libdaemon/client/Makefile libdaemon/server/Makefile libdm/Makefile libdm/libdevmapper.pc liblvm/Makefile liblvm/liblvm2app.pc man/Makefile po/Makefile scripts/clvmd_init_red_hat scripts/cmirrord_init_red_hat scripts/lvm2_lvmetad_init_red_hat scripts/lvm2_lvmetad_systemd_red_hat.socket scripts/lvm2_lvmetad_systemd_red_hat.service scripts/lvm2_monitoring_init_red_hat scripts/dm_event_systemd_red_hat.socket scripts/dm_event_systemd_red_hat.service scripts/lvm2_monitoring_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 verity/Makefile"
 
 cat >confcache <<\_ACEOF
 # This file is a shell script that caches the results of configure
@@ -11646,6 +11721,7 @@ do
     "scripts/lvm2_lvmetad_systemd_red_hat.socket") CONFIG_FILES="$CONFIG_FILES scripts/lvm2_lvmetad_systemd_red_hat.socket" ;;
     "scripts/lvm2_lvmetad_systemd_red_hat.service") CONFIG_FILES="$CONFIG_FILES scripts/lvm2_lvmetad_systemd_red_hat.service" ;;
     "scripts/lvm2_monitoring_init_red_hat") CONFIG_FILES="$CONFIG_FILES scripts/lvm2_monitoring_init_red_hat" ;;
+    "scripts/dm_event_systemd_red_hat.socket") CONFIG_FILES="$CONFIG_FILES scripts/dm_event_systemd_red_hat.socket" ;;
     "scripts/dm_event_systemd_red_hat.service") CONFIG_FILES="$CONFIG_FILES scripts/dm_event_systemd_red_hat.service" ;;
     "scripts/lvm2_monitoring_systemd_red_hat.service") CONFIG_FILES="$CONFIG_FILES scripts/lvm2_monitoring_systemd_red_hat.service" ;;
     "scripts/lvm2_tmpfiles_red_hat.conf") CONFIG_FILES="$CONFIG_FILES scripts/lvm2_tmpfiles_red_hat.conf" ;;
diff --git a/configure.in b/configure.in
index 5e8c6f9..dec23dc 100644
--- a/configure.in
+++ b/configure.in
@@ -472,6 +472,32 @@ pkg_config_init() {
 }
 
 ################################################################################
+dnl -- Set up pidfile and run directory
+AH_TEMPLATE(DEFAULT_PID_DIR)
+AC_ARG_WITH(default-pid-dir,
+	    AC_HELP_STRING([--with-default-pid-dir=PID_DIR],
+			   [Default directory to keep PID files in. [[/var/run]]]),
+	    DEFAULT_PID_DIR="$withval", DEFAULT_PID_DIR="/var/run")
+AC_DEFINE_UNQUOTED(DEFAULT_PID_DIR, ["$DEFAULT_PID_DIR"],
+		   [Default directory to keep PID files in.])
+
+AH_TEMPLATE(DEFAULT_DM_RUN_DIR, [Name of default DM run directory.])
+AC_ARG_WITH(default-dm-run-dir,
+	    AC_HELP_STRING([--with-default-dm-run-dir=DM_RUN_DIR],
+			   [ Default DM run directory. [[/var/run]]]),
+	    DEFAULT_DM_RUN_DIR="$withval", DEFAULT_DM_RUN_DIR="/var/run")
+AC_DEFINE_UNQUOTED(DEFAULT_DM_RUN_DIR, ["$DEFAULT_DM_RUN_DIR"],
+		   [Default DM run directory.])
+
+AH_TEMPLATE(DEFAULT_RUN_DIR, [Name of default LVM run directory.])
+AC_ARG_WITH(default-run-dir,
+	    AC_HELP_STRING([--with-default-run-dir=RUN_DIR],
+			   [Default LVM run directory. [[/var/run/lvm]]]),
+	    DEFAULT_RUN_DIR="$withval", DEFAULT_RUN_DIR="/var/run/lvm")
+AC_DEFINE_UNQUOTED(DEFAULT_RUN_DIR, ["$DEFAULT_RUN_DIR"],
+		   [Default LVM run directory.])
+
+################################################################################
 dnl -- Build cluster LVM daemon
 AC_MSG_CHECKING(whether to build cluster LVM daemon)
 AC_ARG_WITH(clvmd,
@@ -723,9 +749,9 @@ dnl -- clvmd pidfile
 if test "x$CLVMD" != xnone; then
 	AC_ARG_WITH(clvmd-pidfile,
 		    AC_HELP_STRING([--with-clvmd-pidfile=PATH],
-				   [clvmd pidfile [[/var/run/clvmd.pid]]]),
+				   [clvmd pidfile [[PID_DIR/clvmd.pid]]]),
 		    CLVMD_PIDFILE=$withval,
-		    CLVMD_PIDFILE="/var/run/clvmd.pid")
+		    CLVMD_PIDFILE="$DEFAULT_PID_DIR/clvmd.pid")
 	AC_DEFINE_UNQUOTED(CLVMD_PIDFILE, ["$CLVMD_PIDFILE"],
 			   [Path to clvmd pidfile.])
 fi
@@ -746,9 +772,9 @@ dnl -- cmirrord pidfile
 if test "x$BUILD_CMIRRORD" = xyes; then
 	AC_ARG_WITH(cmirrord-pidfile,
 		    AC_HELP_STRING([--with-cmirrord-pidfile=PATH],
-				   [cmirrord pidfile [[/var/run/cmirrord.pid]]]),
+				   [cmirrord pidfile [[PID_DIR/cmirrord.pid]]]),
 		    CMIRRORD_PIDFILE=$withval,
-		    CMIRRORD_PIDFILE="/var/run/cmirrord.pid")
+		    CMIRRORD_PIDFILE="$DEFAULT_PID_DIR/cmirrord.pid")
 	AC_DEFINE_UNQUOTED(CMIRRORD_PIDFILE, ["$CMIRRORD_PIDFILE"],
 			   [Path to cmirrord pidfile.])
 fi
@@ -874,6 +900,14 @@ BUILD_LVMETAD=$LVMETAD
 
 if test x$BUILD_LVMETAD = xyes; then
 	AC_DEFINE([LVMETAD_SUPPORT], 1, [Define to 1 to include code that uses lvmetad.])
+
+	AC_ARG_WITH(lvmetad-pidfile,
+		    AC_HELP_STRING([--with-lvmetad-pidfile=PATH],
+				   [lvmetad pidfile [[PID_DIR/lvmetad.pid]]]),
+		    LVMETAD_PIDFILE=$withval,
+		    LVMETAD_PIDFILE="$DEFAULT_PID_DIR/lvmetad.pid")
+	AC_DEFINE_UNQUOTED(LVMETAD_PIDFILE, ["$LVMETAD_PIDFILE"],
+			   [Path to lvmetad pidfile.])
 fi
 
 ################################################################################
@@ -902,16 +936,22 @@ AC_ARG_ENABLE(udev_rules,
 	      UDEV_RULES=$enableval, UDEV_RULES=$UDEV_SYNC)
 AC_MSG_RESULT($UDEV_RULES)
 
-if test x$UDEV_RULES = xyes; then
-	AC_MSG_CHECKING(whether udev supports builtin blkid)
-	udev_version=$(udevadm info --version 2>/dev/null)
-	if test -n "$udev_version" && test "$udev_version" -ge 176; then
-		UDEV_HAS_BUILTIN_BLKID=yes
-	else
-		UDEV_HAS_BUILTIN_BLKID=no
-	fi
-	AC_MSG_RESULT($UDEV_HAS_BUILTIN_BLKID)
+AC_MSG_CHECKING(whether to enable executable path detection in udev rules)
+AC_ARG_ENABLE(udev_rule_exec_detection,
+	      AC_HELP_STRING([--enable-udev-rule-exec-detection],
+			     [enable executable path detection in udev rules]),
+	      UDEV_RULE_EXEC_DETECTION=$enableval, UDEV_RULE_EXEC_DETECTION=no)
+AC_MSG_RESULT($UDEV_RULE_EXEC_DETECTION)
+
+dnl -- Check support for built-in blkid against target udev version
+AC_MSG_CHECKING(whether udev supports built-in blkid)
+test x$PKGCONFIG_INIT != x1 && pkg_config_init
+if $($PKG_CONFIG --atleast-version=176 libudev); then
+	UDEV_HAS_BUILTIN_BLKID=yes
+else
+	UDEV_HAS_BUILTIN_BLKID=no
 fi
+AC_MSG_RESULT($UDEV_HAS_BUILTIN_BLKID)
 
 ################################################################################
 dnl -- Compatibility mode
@@ -1369,9 +1409,9 @@ dnl -- dmeventd pidfile and executable path
 if test "$BUILD_DMEVENTD" = yes; then
 	AC_ARG_WITH(dmeventd-pidfile,
 		    AC_HELP_STRING([--with-dmeventd-pidfile=PATH],
-				   [dmeventd pidfile [[/var/run/dmeventd.pid]]]),
+				   [dmeventd pidfile [[PID_DIR/dmeventd.pid]]]),
 		    DMEVENTD_PIDFILE=$withval,
-		    DMEVENTD_PIDFILE="/var/run/dmeventd.pid")
+		    DMEVENTD_PIDFILE="$DEFAULT_PID_DIR/dmeventd.pid")
 	AC_DEFINE_UNQUOTED(DMEVENTD_PIDFILE, ["$DMEVENTD_PIDFILE"],
 			   [Path to dmeventd pidfile.])
 fi
@@ -1386,13 +1426,6 @@ if test "$BUILD_DMEVENTD" = yes; then
 			   [Path to dmeventd binary.])
 fi
 
-AH_TEMPLATE(DEFAULT_RUN_DIR, [Name of default run directory.])
-AC_ARG_WITH(default-run-dir,
-	    [  --with-default-run-dir=DIR       Default run directory [[/var/run/lvm]] ],
-	    [ DEFAULT_RUN_DIR="$withval" ],
-	    [ DEFAULT_RUN_DIR="/var/run/lvm" ])
-AC_DEFINE_UNQUOTED(DEFAULT_RUN_DIR,["$DEFAULT_RUN_DIR"] )
-
 ################################################################################
 dnl -- various defaults
 AC_ARG_WITH(default-system-dir,
@@ -1504,6 +1537,7 @@ AC_SUBST(DEFAULT_BACKUP_SUBDIR)
 AC_SUBST(DEFAULT_CACHE_SUBDIR)
 AC_SUBST(DEFAULT_DATA_ALIGNMENT)
 AC_SUBST(DEFAULT_LOCK_DIR)
+AC_SUBST(DEFAULT_DM_RUN_DIR)
 AC_SUBST(DEFAULT_RUN_DIR)
 AC_SUBST(DEVMAPPER)
 AC_SUBST(DLM_CFLAGS)
@@ -1567,11 +1601,13 @@ AC_SUBST(UDEV_LIBS)
 AC_SUBST(UDEV_PC)
 AC_SUBST(UDEV_RULES)
 AC_SUBST(UDEV_SYNC)
+AC_SUBST(UDEV_RULE_EXEC_DETECTION)
 AC_SUBST(UDEV_HAS_BUILTIN_BLKID)
 AC_SUBST(CUNIT_LIBS)
 AC_SUBST(CUNIT_CFLAGS)
 AC_SUBST(WRITE_INSTALL)
 AC_SUBST(DMEVENTD_PIDFILE)
+AC_SUBST(LVMETAD_PIDFILE)
 AC_SUBST(interface)
 AC_SUBST(kerneldir)
 AC_SUBST(missingkernel)
@@ -1631,6 +1667,7 @@ scripts/lvm2_lvmetad_init_red_hat
 scripts/lvm2_lvmetad_systemd_red_hat.socket
 scripts/lvm2_lvmetad_systemd_red_hat.service
 scripts/lvm2_monitoring_init_red_hat
+scripts/dm_event_systemd_red_hat.socket
 scripts/dm_event_systemd_red_hat.service
 scripts/lvm2_monitoring_systemd_red_hat.service
 scripts/lvm2_tmpfiles_red_hat.conf
diff --git a/daemons/dmeventd/dmeventd.h b/daemons/dmeventd/dmeventd.h
index 81056e9..e21cf45 100644
--- a/daemons/dmeventd/dmeventd.h
+++ b/daemons/dmeventd/dmeventd.h
@@ -17,8 +17,8 @@
 
 /* FIXME This stuff must be configurable. */
 
-#define	DM_EVENT_FIFO_CLIENT	"/var/run/dmeventd-client"
-#define	DM_EVENT_FIFO_SERVER	"/var/run/dmeventd-server"
+#define	DM_EVENT_FIFO_CLIENT	DEFAULT_DM_RUN_DIR "/dmeventd-client"
+#define	DM_EVENT_FIFO_SERVER	DEFAULT_DM_RUN_DIR "/dmeventd-server"
 
 #define DM_EVENT_DEFAULT_TIMEOUT 10
 
diff --git a/daemons/lvmetad/lvmetad-core.c b/daemons/lvmetad/lvmetad-core.c
index 5b34e21..d41a905 100644
--- a/daemons/lvmetad/lvmetad-core.c
+++ b/daemons/lvmetad/lvmetad-core.c
@@ -1094,7 +1094,7 @@ int main(int argc, char *argv[])
 	s.socket_path = getenv("LVM_LVMETAD_SOCKET");
 	if (!s.socket_path)
 		s.socket_path = DEFAULT_RUN_DIR "/lvmetad.socket";
-	s.pidfile = DEFAULT_RUN_DIR "/lvmetad.pid";
+	s.pidfile = LVMETAD_PIDFILE;
         s.log_level = 0;
 	s.protocol = "lvmetad";
 	s.protocol_version = 1;
diff --git a/doc/example.conf.in b/doc/example.conf.in
index 9092e32..fbb9271 100644
--- a/doc/example.conf.in
+++ b/doc/example.conf.in
@@ -550,6 +550,15 @@ activation {
     #
     # volume_list = [ "vg1", "vg2/lvol1", "@tag1", "@*" ]
 
+    # If auto_activation_volume_list is defined, each LV that is to be
+    # activated is checked against the list while using the autoactivation
+    # option (--activate ay/-a ay), and if it matches, it is activated.
+    #   "vgname" and "vgname/lvname" are matched exactly.
+    #   "@tag" matches any tag set in the LV or VG.
+    #   "@*" matches if any tag defined on the host is also set in the LV or VG
+    #
+    # auto_activation_volume_list = [ "vg1", "vg2/lvol1", "@tag1", "@*" ]
+
     # If read_only_volume_list is defined, each LV that is to be activated 
     # is checked against the list, and if it matches, it as activated
     # in read-only mode.  (This overrides '--permission rw' stored in the
diff --git a/lib/activate/activate.c b/lib/activate/activate.c
index d2cc5bf..1205e58 100644
--- a/lib/activate/activate.c
+++ b/lib/activate/activate.c
@@ -328,10 +328,8 @@ int activation(void)
 	return _activation;
 }
 
-static int _passes_volumes_filter(struct cmd_context *cmd,
-				  struct logical_volume *lv,
-				  const struct dm_config_node *cn,
-				  const char *config_path)
+static int _lv_passes_volumes_filter(struct cmd_context *cmd, struct logical_volume *lv,
+				     const struct dm_config_node *cn, const char *config_path)
 {
 	const struct dm_config_value *cv;
 	const char *str;
@@ -429,7 +427,7 @@ static int _passes_activation_filter(struct cmd_context *cmd,
 		return 0;
 	}
 
-	return _passes_volumes_filter(cmd, lv, cn, "activation/volume_list");
+	return _lv_passes_volumes_filter(cmd, lv, cn, "activation/volume_list");
 }
 
 static int _passes_readonly_filter(struct cmd_context *cmd,
@@ -440,7 +438,21 @@ static int _passes_readonly_filter(struct cmd_context *cmd,
 	if (!(cn = find_config_tree_node(cmd, "activation/read_only_volume_list")))
 		return 0;
 
-	return _passes_volumes_filter(cmd, lv, cn, "activation/read_only_volume_list");
+	return _lv_passes_volumes_filter(cmd, lv, cn, "activation/read_only_volume_list");
+}
+
+
+int lv_passes_auto_activation_filter(struct cmd_context *cmd, struct logical_volume *lv)
+{
+	const struct dm_config_node *cn;
+
+	if (!(cn = find_config_tree_node(cmd, "activation/auto_activation_volume_list"))) {
+		log_verbose("activation/auto_activation_volume_list configuration setting "
+			    "not defined: All logical volumes will be auto-activated.");
+		return 1;
+	}
+
+	return _lv_passes_volumes_filter(cmd, lv, cn, "activation/auto_activation_volume_list");
 }
 
 int library_version(char *version, size_t size)
diff --git a/lib/activate/activate.h b/lib/activate/activate.h
index 2b90a7b..f473a11 100644
--- a/lib/activate/activate.h
+++ b/lib/activate/activate.h
@@ -93,6 +93,11 @@ int lv_check_not_in_use(struct cmd_context *cmd, struct logical_volume *lv,
  */
 int lv_activation_filter(struct cmd_context *cmd, const char *lvid_s,
 			 int *activate_lv);
+/*
+ * Checks against the auto_activation_volume_list and
+ * returns 1 if the LV should be activated, 0 otherwise.
+ */
+int lv_passes_auto_activation_filter(struct cmd_context *cmd, struct logical_volume *lv);
 
 int lv_check_transient(struct logical_volume *lv);
 /*
diff --git a/lib/cache/lvmetad.c b/lib/cache/lvmetad.c
index f2bb8eb..31cda0b 100644
--- a/lib/cache/lvmetad.c
+++ b/lib/cache/lvmetad.c
@@ -322,7 +322,7 @@ int lvmetad_vg_update(struct volume_group *vg)
 		/* NB. the PV fmt pointer is sometimes wrong during vgconvert */
 		if (pvl->pv->dev && !lvmetad_pv_found(pvl->pv->id, pvl->pv->dev,
 						      vg->fid ? vg->fid->fmt : pvl->pv->fmt,
-						      pvl->pv->label_sector, NULL))
+						      pvl->pv->label_sector, NULL, NULL))
 			return 0;
 	}
 
@@ -536,7 +536,7 @@ static const char *_print_mdas(struct lvmcache_info *info)
 }
 
 int lvmetad_pv_found(struct id pvid, struct device *device, const struct format_type *fmt,
-		     uint64_t label_sector, struct volume_group *vg)
+		     uint64_t label_sector, struct volume_group *vg, activation_handler handler)
 {
 	char uuid[64];
 	daemon_reply reply;
@@ -544,6 +544,7 @@ int lvmetad_pv_found(struct id pvid, struct device *device, const struct format_
 	const char *mdas = NULL;
 	char *pvmeta;
 	char *buf = NULL;
+	const char *status;
 	int result;
 
 	if (!_using_lvmetad)
@@ -603,12 +604,26 @@ int lvmetad_pv_found(struct id pvid, struct device *device, const struct format_
 	dm_free(pvmeta);
 
 	result = _lvmetad_handle_reply(reply, "update PV", uuid, NULL);
+
+	if (result && handler) {
+		status = daemon_reply_str(reply, "status", "<missing>");
+		if (!strcmp(status, "partial"))
+			handler(vg, 1, CHANGE_AAY);
+		else if (!strcmp(status, "complete"))
+			handler(vg, 0, CHANGE_AAY);
+		else if (!strcmp(status, "orphan"))
+			;
+		else
+			log_error("Request to %s %s in lvmetad gave status %s.",
+			  "update PV", uuid, status);
+	}
+
 	daemon_reply_destroy(reply);
 
 	return result;
 }
 
-int lvmetad_pv_gone(dev_t device, const char *pv_name)
+int lvmetad_pv_gone(dev_t device, const char *pv_name, activation_handler handler)
 {
 	daemon_reply reply;
 	int result;
@@ -617,6 +632,13 @@ int lvmetad_pv_gone(dev_t device, const char *pv_name)
 	if (!_using_lvmetad)
 		return 1;
 
+	/*
+         *  TODO: automatic volume deactivation takes place here *before*
+         *        all cached info is gone - call handler. Also, consider
+         *        integrating existing deactivation script  that deactivates
+         *        the whole stack from top to bottom (not yet upstream).
+         */
+
 	reply = daemon_send_simple(_lvmetad, "pv_gone", "device = %d", device, NULL);
 
 	result = _lvmetad_handle_reply(reply, "drop PV", pv_name, &found);
@@ -627,9 +649,9 @@ int lvmetad_pv_gone(dev_t device, const char *pv_name)
 	return result;
 }
 
-int lvmetad_pv_gone_by_dev(struct device *dev)
+int lvmetad_pv_gone_by_dev(struct device *dev, activation_handler handler)
 {
-	return lvmetad_pv_gone(dev->dev, dev_name(dev));
+	return lvmetad_pv_gone(dev->dev, dev_name(dev), handler);
 }
 
 int lvmetad_active(void)
@@ -665,7 +687,8 @@ static int _pvscan_lvmetad_single(struct metadata_area *mda, void *baton)
 	return 1;
 }
 
-int pvscan_lvmetad_single(struct cmd_context *cmd, struct device *dev)
+int pvscan_lvmetad_single(struct cmd_context *cmd, struct device *dev,
+			  activation_handler handler)
 {
 	struct label *label;
 	struct lvmcache_info *info;
@@ -681,7 +704,7 @@ int pvscan_lvmetad_single(struct cmd_context *cmd, struct device *dev)
 
 	if (!label_read(dev, &label, 0)) {
 		log_print("No PV label found on %s.", dev_name(dev));
-		if (!lvmetad_pv_gone_by_dev(dev))
+		if (!lvmetad_pv_gone_by_dev(dev, handler))
 			goto_bad;
 		return 1;
 	}
@@ -703,7 +726,7 @@ int pvscan_lvmetad_single(struct cmd_context *cmd, struct device *dev)
 	 * sync needs to be killed.
 	 */
 	if (!lvmetad_pv_found(*(struct id *)dev->pvid, dev, lvmcache_fmt(info),
-			      label->sector, baton.vg)) {
+			      label->sector, baton.vg, handler)) {
 		release_vg(baton.vg);
 		goto_bad;
 	}
diff --git a/lib/cache/lvmetad.h b/lib/cache/lvmetad.h
index 091ff5e..713c5a3 100644
--- a/lib/cache/lvmetad.h
+++ b/lib/cache/lvmetad.h
@@ -19,6 +19,8 @@ struct volume_group;
 struct cmd_context;
 struct dm_config_tree;
 
+typedef int (*activation_handler) (struct volume_group *vg, int partial, int activate);
+
 #ifdef LVMETAD_SUPPORT
 /*
  * Initialise the communication with lvmetad. Normally called by
@@ -64,13 +66,13 @@ int lvmetad_vg_remove(struct volume_group *vg);
  */
 int lvmetad_pv_found(struct id pvid, struct device *device,
 		     const struct format_type *fmt, uint64_t label_sector,
-		     struct volume_group *vg);
+		     struct volume_group *vg, activation_handler handler);
 
 /*
  * Inform the daemon that the device no longer exists.
  */
-int lvmetad_pv_gone(dev_t devno, const char *pv_name);
-int lvmetad_pv_gone_by_dev(struct device *dev);
+int lvmetad_pv_gone(dev_t devno, const char *pv_name, activation_handler handler);
+int lvmetad_pv_gone_by_dev(struct device *dev, activation_handler handler);
 
 /*
  * Request a list of all PVs available to lvmetad. If requested, this will also
@@ -102,7 +104,8 @@ struct volume_group *lvmetad_vg_lookup(struct cmd_context *cmd,
 /*
  * Scan a single device and update lvmetad with the result(s).
  */
-int pvscan_lvmetad_single(struct cmd_context *cmd, struct device *dev);
+int pvscan_lvmetad_single(struct cmd_context *cmd, struct device *dev,
+			  activation_handler handler);
 
 #  else		/* LVMETAD_SUPPORT */
 
@@ -111,15 +114,15 @@ int pvscan_lvmetad_single(struct cmd_context *cmd, struct device *dev);
 #    define lvmetad_active()	(0)
 #    define lvmetad_vg_update(vg)	(1)
 #    define lvmetad_vg_remove(vg)	(1)
-#    define lvmetad_pv_found(pvid, device, fmt, label_sector, vg)	(1)
-#    define lvmetad_pv_gone(devno, pv_name)	(1)
-#    define lvmetad_pv_gone_by_dev(dev)	(1)
+#    define lvmetad_pv_found(pvid, device, fmt, label_sector, vg, handler)	(1)
+#    define lvmetad_pv_gone(devno, pv_name, handler)	(1)
+#    define lvmetad_pv_gone_by_dev(dev, handler)	(1)
 #    define lvmetad_pv_list_to_lvmcache(cmd)	(1)
 #    define lvmetad_pv_lookup(cmd, pvid, found)	(0)
 #    define lvmetad_pv_lookup_by_dev(cmd, dev, found)	(0)
 #    define lvmetad_vg_list_to_lvmcache(cmd)	(1)
 #    define lvmetad_vg_lookup(cmd, vgname, vgid)	(NULL)
-#    define pvscan_lvmetad_single(cmd, dev)	(0)
+#    define pvscan_lvmetad_single(cmd, dev, handler)	(0)
 
 #  endif	/* LVMETAD_SUPPORT */
 
diff --git a/lib/device/dev-io.c b/lib/device/dev-io.c
index eecc759..3bb9d65 100644
--- a/lib/device/dev-io.c
+++ b/lib/device/dev-io.c
@@ -282,7 +282,7 @@ static int _dev_read_ahead_dev(struct device *dev, uint32_t *read_ahead)
 		return 1;
 	}
 
-	if (!dev_open(dev))
+	if (!dev_open_readonly(dev))
 		return_0;
 
 	if (ioctl(dev->fd, BLKRAGET, &read_ahead_long) < 0) {
diff --git a/lib/metadata/lv_manip.c b/lib/metadata/lv_manip.c
index 3913680..fb36b59 100644
--- a/lib/metadata/lv_manip.c
+++ b/lib/metadata/lv_manip.c
@@ -4411,6 +4411,15 @@ static struct logical_volume *_lv_create_an_lv(struct volume_group *vg, struct l
 
 	backup(vg);
 
+	/*
+	 * Check for autoactivation.
+	 * If the LV passes the auto activation filter, activate
+	 * it just as if CHANGE_AY was used, CHANGE_AN otherwise.
+	 */
+	if (lp->activate == CHANGE_AAY)
+		lp->activate = lv_passes_auto_activation_filter(cmd, lv) ?
+				CHANGE_ALY : CHANGE_ALN;
+
 	if (test_mode()) {
 		log_verbose("Test mode: Skipping activation and zeroing.");
 		goto out;
diff --git a/lib/metadata/metadata-exported.h b/lib/metadata/metadata-exported.h
index f42ec33..8c655c7 100644
--- a/lib/metadata/metadata-exported.h
+++ b/lib/metadata/metadata-exported.h
@@ -563,11 +563,12 @@ int update_pool_lv(struct logical_volume *lv, int activate);
  * Activation options
  */
 typedef enum {
-	CHANGE_AY = 0,
-	CHANGE_AN = 1,
-	CHANGE_AE = 2,
-	CHANGE_ALY = 3,
-	CHANGE_ALN = 4
+	CHANGE_AY = 0,  /* activate */
+	CHANGE_AN = 1,  /* deactivate */
+	CHANGE_AE = 2,  /* activate exclusively */
+	CHANGE_ALY = 3, /* activate locally */
+	CHANGE_ALN = 4, /* deactivate locally */
+	CHANGE_AAY = 5  /* automatic activation */
 } activation_change_t;
 
 /* FIXME: refactor and reduce the size of this struct! */
diff --git a/lib/metadata/metadata.c b/lib/metadata/metadata.c
index 7c22785..c14125a 100644
--- a/lib/metadata/metadata.c
+++ b/lib/metadata/metadata.c
@@ -3800,7 +3800,8 @@ int pv_write(struct cmd_context *cmd __attribute__((unused)),
 	if (!pv->fmt->ops->pv_write(pv->fmt, pv))
 		return_0;
 
-	if (!lvmetad_pv_found(pv->id, pv->dev, pv->fmt, pv->label_sector, NULL))
+	if (!lvmetad_pv_found(pv->id, pv->dev, pv->fmt, pv->label_sector,
+			      NULL, NULL))
 		return_0;
 
 	return 1;
diff --git a/lib/misc/configure.h.in b/lib/misc/configure.h.in
index dc6a260..06a5855 100644
--- a/lib/misc/configure.h.in
+++ b/lib/misc/configure.h.in
@@ -53,10 +53,16 @@
 /* Define default name mangling behaviour */
 #undef DEFAULT_DM_NAME_MANGLING
 
+/* Default DM run directory. */
+#undef DEFAULT_DM_RUN_DIR
+
 /* Name of default locking directory. */
 #undef DEFAULT_LOCK_DIR
 
-/* Name of default run directory. */
+/* Default directory to keep PID files in. */
+#undef DEFAULT_PID_DIR
+
+/* Default LVM run directory. */
 #undef DEFAULT_RUN_DIR
 
 /* Define to 0 to reinstate the pre-2.02.54 handling of unit suffixes. */
@@ -464,6 +470,9 @@
 /* Define to 1 to include built-in support for LVM1 metadata. */
 #undef LVM1_INTERNAL
 
+/* Path to lvmetad pidfile. */
+#undef LVMETAD_PIDFILE
+
 /* Define to 1 to include code that uses lvmetad. */
 #undef LVMETAD_SUPPORT
 
diff --git a/man/lvchange.8.in b/man/lvchange.8.in
index 927be25..c7507d4 100644
--- a/man/lvchange.8.in
+++ b/man/lvchange.8.in
@@ -7,8 +7,8 @@ lvchange \- change attributes of a logical volume
 .IR Tag ]
 .RB [ \-A | \-\-autobackup
 .RI { y | n }]
-.RB [ \-a | \-\-available
-.RI [ e | l ]{ y | n }]
+.RB [ \-a | \-\-activate
+.RI [ a | e | l ]{ y | n }]
 .RB [ \-\-alloc
 .IR AllocationPolicy ]
 .RB [ \-C | \-\-contiguous
@@ -46,11 +46,15 @@ including making them known to the kernel ready for use.
 .SH OPTIONS
 See \fBlvm\fP(8) for common options.
 .TP
-.BR \-a ", " \-\-available " [" \fIe | \fIl ]{ \fIy | \fIn }
+.BR \-a ", " \-\-activate " [" \fIa | \fIe | \fIl ]{ \fIy | \fIn }
 Controls the availability of the logical volumes for use.
 Communicates with the kernel device-mapper driver via
 libdevmapper to activate (\-ay) or deactivate (\-an) the
-logical volumes.
+logical volumes. If autoactivation option is used (\-aay),
+the logical volume is activated only if it matches an item in
+the activation/auto_activation_volume_list set in lvm.conf.
+Autoactivation is not yet supported for logical volumes that
+are part of partial or clustered volume groups.
 .IP
 If clustered locking is enabled, -aey will activate exclusively
 on one node and -aly will activate only on the local node.
diff --git a/man/lvcreate.8.in b/man/lvcreate.8.in
index 97fe624..2917775 100644
--- a/man/lvcreate.8.in
+++ b/man/lvcreate.8.in
@@ -7,8 +7,8 @@ lvcreate \- create a logical volume in an existing volume group
 .IR Tag ]
 .RB [ \-\-alloc
 .IR AllocationPolicy ]
-.RB [ \-a | \-\-available
-.RI [ e | l ]{ y | n }]
+.RB [ \-a | \-\-activate
+.RI [ a | e | l ]{ y | n }]
 .RB [ \-A | \-\-autobackup
 .RI { y | n }]
 .RB [ \-C | \-\-contiguous
@@ -107,17 +107,21 @@ See
 .BR lvm (8)
 for common options.
 .TP
-.IR \fB\-a ", " \fB\-\-available " {" y | n | ey | en | ly | ln }
+.IR \fB\-a ", " \fB\-\-activate " {" y | ay | n | ey | en | ly | ln }
 Controls the availability of the Logical Volumes for immediate use after
 the command finishes running.
-By default, new Logical Volumes are activated automatically (\fB-a\fIy\fR).
+By default, new Logical Volumes are activated (\fB-a\fIy\fR).
 If it is possible technically, \fB-a\fIn\fR will leave the new Logical
 Volume inactive. But for example, snapshots can only be created
 in the active state so \fB\-a\fIn\fR cannot be used with \fB\-\-snapshot\fP.
 Normally the \fB\-\-zero n\fP argument has to be supplied too because
 zeroing (the default behaviour) also requires activation.
-If clustered locking is enabled, \fB\-a\fIey\fR will activate exclusively
-on one node and \fB\-a\fIly\fR will activate only on the local node.
+If autoactivation option is used (\fB\-a\fIay\fR), the logical volume is
+activated only if it matches an item in the activation/auto_activation_volume_list
+set in lvm.conf. For autoactivated logical volumes, \fB\-\-zero n\fP is
+always assumed and it can't be overridden. If clustered locking is enabled,
+\fB\-a\fIey\fR will activate exclusively on one node and \fB\-a\fIly\fR will
+activate only on the local node.
 .TP
 .BR \-c ", " \-\-chunksize " " \fIChunkSize
 Gives the size of chunk for snapshot and thin pool logical volumes.
diff --git a/man/lvm.conf.5.in b/man/lvm.conf.5.in
index 6de7419..47ee9f1 100644
--- a/man/lvm.conf.5.in
+++ b/man/lvm.conf.5.in
@@ -424,6 +424,17 @@ metadata for a match.
 Logical volume and volume groups can also be included in the list
 by name e.g. vg00, vg00/lvol1.
 .IP
+\fBauto_activation_volume_list\fP \(em This acts as a filter through
+which all requests to autoactivate a logical volume on this machine
+are passed. A logical volume is autoactivated if it matches
+an item in the list. Volumes must also pass the \fBvolume_list\fP
+filter, if present. Tags must be preceded by @ and are checked against
+all tags defined in the logical volume and volume group metadata for
+a match. @* is short-hand to check every tag set on the host machine
+(see \fBtags\fP above).
+Logical volume and volume groups can also be included in the list
+by name e.g. vg00, vg00/lvol1.
+.IP
 \fBread_only_volume_list\fP \(em This acts as a filter through
 which all requests to activate a logical volume on this machine
 are passed.  A logical volume is activated in read-only mode (instead
diff --git a/man/pvscan.8.in b/man/pvscan.8.in
index b75773b..1be3109 100644
--- a/man/pvscan.8.in
+++ b/man/pvscan.8.in
@@ -18,6 +18,7 @@ pvscan \- scan all disks for physical volumes
 .RB [ \-d | \-\-debug ]
 .RB [ \-h | \-\-help ]
 .B \-\-cache
+.RB [ \-a | \-\-activate " " \fIay ]
 .RB [ \-\-major
 .I major
 .B \-\-minor
@@ -42,6 +43,13 @@ Short listing format.
 .BR \-u ", " \-\-uuid
 Show UUIDs (Uniform Unique Identifiers) in addition to device special names.
 .TP
+.BR \-a ", " \-\-activate " " \fIay
+Together with the information already cached in lvmetad, automatically activate
+any logical volumes that become activatable after the scan done on one or more devices.
+The logical volume to autoactivate is matched against the
+activation/auto_activation_volume_list set in lvm.conf. Autoactivation is not yet
+supported on logical volumes that are part of partial or clustered volume groups.
+.TP
 .BR \-\-cache " [" \-\-major " " \fImajor " " \-\-minor " " \fIminor " | " \fIDevicePath " ]..."
 Scan one or more devices and instruct the lvmetad daemon to update its cached
 state accordingly.  Called internally by udev rules.
diff --git a/man/vgchange.8.in b/man/vgchange.8.in
index d43f79a..28e2623 100644
--- a/man/vgchange.8.in
+++ b/man/vgchange.8.in
@@ -9,8 +9,8 @@ vgchange \- change attributes of a volume group
 .IR AllocationPolicy ]
 .RB [ \-A | \-\-autobackup
 .RI { y | n }]
-.RB [ \-a | \-\-available
-.RI [ e | l ]
+.RB [ \-a | \-\-activate
+.RI [ a | e | l ]
 .RI { y | n }]
 .RB [ \-\-monitor
 .RI { y | n }]
@@ -64,10 +64,15 @@ Controls automatic backup of metadata after the change.  See
 .BR vgcfgbackup (8).
 Default is yes.
 .TP
-.BR \-a ", " \-\-available " [" \fIe | \fIl ]{ \fIy | \fIn }
+.BR \-a ", " \-\-activate " [" \fIa | \fIe | \fIl ]{ \fIy | \fIn }
 Controls the availability of the logical volumes in the volume
 group for input/output.
 In other words, makes the logical volumes known/unknown to the kernel.
+If autoactivation option is used (\-aay), each logical volume in
+the volume group is activated only if it matches an item in the
+activation/auto_activation_volume_list set in lvm.conf.
+Autoactivation is not yet supported for partial or clustered
+volume groups.
 .IP
 If clustered locking is enabled, add 'e' to activate/deactivate
 exclusively on one node or 'l' to activate/deactivate only
diff --git a/scripts/Makefile.in b/scripts/Makefile.in
index be012d6..53c85f5 100644
--- a/scripts/Makefile.in
+++ b/scripts/Makefile.in
@@ -75,7 +75,9 @@ install_tmpfiles_configuration:
 	$(INSTALL_DIR) $(tmpfiles_dir)
 	$(INSTALL_DATA) lvm2_tmpfiles_red_hat.conf $(tmpfiles_dir)/lvm2.conf
 
-DISTCLEAN_TARGETS += clvmd_init_red_hat cmirrord_init_red_hat lvm2_monitoring_init_red_hat \
-		     dm_event_systemd_red_hat.service lvm2_monitoring_systemd_red_hat.service \
+DISTCLEAN_TARGETS += clvmd_init_red_hat cmirrord_init_red_hat \
+		     lvm2_monitoring_init_red_hat lvm2_lvmetad_init_red_hat \
+		     dm_event_systemd_red_hat.socket dm_event_systemd_red_hat.service \
+		     lvm2_monitoring_systemd_red_hat.service \
 		     lvm2_lvmetad_systemd_red_hat.socket lvm2_lvmetad_systemd_red_hat.service \
-		     lvm2_lvmetad_init_red_hat lvm2_tmpfiles_red_hat.conf
+		     lvm2_tmpfiles_red_hat.conf
diff --git a/scripts/dm_event_systemd_red_hat.service.in b/scripts/dm_event_systemd_red_hat.service.in
index 02a24c6..96c5225 100644
--- a/scripts/dm_event_systemd_red_hat.service.in
+++ b/scripts/dm_event_systemd_red_hat.service.in
@@ -1,5 +1,6 @@
 [Unit]
 Description=Device-mapper event daemon
+Documentation=man:dmeventd(8)
 Requires=dm-event.socket
 After=dm-event.socket
 Before=local-fs.target
diff --git a/scripts/dm_event_systemd_red_hat.socket b/scripts/dm_event_systemd_red_hat.socket
deleted file mode 100644
index c580555..0000000
--- a/scripts/dm_event_systemd_red_hat.socket
+++ /dev/null
@@ -1,11 +0,0 @@
-[Unit]
-Description=Device-mapper event daemon FIFOs
-DefaultDependencies=no
-
-[Socket]
-ListenFIFO=/var/run/dmeventd-server
-ListenFIFO=/var/run/dmeventd-client
-SocketMode=0600
-
-[Install]
-WantedBy=sockets.target
diff --git a/scripts/dm_event_systemd_red_hat.socket.in b/scripts/dm_event_systemd_red_hat.socket.in
new file mode 100644
index 0000000..b27c68d
--- /dev/null
+++ b/scripts/dm_event_systemd_red_hat.socket.in
@@ -0,0 +1,12 @@
+[Unit]
+Description=Device-mapper event daemon FIFOs
+Documentation=man:dmeventd(8)
+DefaultDependencies=no
+
+[Socket]
+ListenFIFO=@DEFAULT_DM_RUN_DIR@/dmeventd-server
+ListenFIFO=@DEFAULT_DM_RUN_DIR@/dmeventd-client
+SocketMode=0600
+
+[Install]
+WantedBy=sockets.target
diff --git a/scripts/lvm2_lvmetad_init_red_hat.in b/scripts/lvm2_lvmetad_init_red_hat.in
index 886944e..888c730 100644
--- a/scripts/lvm2_lvmetad_init_red_hat.in
+++ b/scripts/lvm2_lvmetad_init_red_hat.in
@@ -41,7 +41,7 @@ sbindir=@sbindir@
 lvm_pvscan="${sbindir}/lvm pvscan --cache"
 
 LOCK_FILE="/var/lock/subsys/$DAEMON"
-PID_FILE="@DEFAULT_RUN_DIR@/${DAEMON}.pid"
+PID_FILE="@LVMETAD_PIDFILE@"
 
 
 rh_status() {
diff --git a/scripts/lvm2_lvmetad_systemd_red_hat.service.in b/scripts/lvm2_lvmetad_systemd_red_hat.service.in
index e32c8a1..e527369 100644
--- a/scripts/lvm2_lvmetad_systemd_red_hat.service.in
+++ b/scripts/lvm2_lvmetad_systemd_red_hat.service.in
@@ -1,5 +1,6 @@
 [Unit]
 Description=LVM2 metadata daemon
+Documentation=man:lvmetad(8)
 Requires=lvm2-lvmetad.socket
 After=lvm2-lvmetad.socket
 DefaultDependencies=no
@@ -13,7 +14,7 @@ ExecStartPost=@sbindir@/lvm pvscan --cache
 ExecReload=@sbindir@/lvmetad -R
 Environment=SD_ACTIVATION=1
 Restart=on-abort
-PIDFile=@DEFAULT_RUN_DIR@/lvmetad.pid
+PIDFile=@LVMETAD_PIDFILE@
 
 [Install]
 WantedBy=sysinit.target
diff --git a/scripts/lvm2_lvmetad_systemd_red_hat.socket.in b/scripts/lvm2_lvmetad_systemd_red_hat.socket.in
index f4c82a5..9a46f50 100644
--- a/scripts/lvm2_lvmetad_systemd_red_hat.socket.in
+++ b/scripts/lvm2_lvmetad_systemd_red_hat.socket.in
@@ -1,5 +1,6 @@
 [Unit]
 Description=LVM2 metadata daemon socket
+Documentation=man:lvmetad(8)
 DefaultDependencies=no
 
 [Socket]
diff --git a/scripts/lvm2_monitoring_systemd_red_hat.service.in b/scripts/lvm2_monitoring_systemd_red_hat.service.in
index e93414d..a8d5183 100644
--- a/scripts/lvm2_monitoring_systemd_red_hat.service.in
+++ b/scripts/lvm2_monitoring_systemd_red_hat.service.in
@@ -1,5 +1,6 @@
 [Unit]
 Description=Monitoring of LVM2 mirrors, snapshots etc. using dmeventd or progress polling
+Documentation=man:dmeventd(8) man:lvcreate(8) man:lvchange(8) man:vgchange(8)
 Requires=dm-event.socket
 After=dm-event.socket fedora-storage-init.service fedora-storage-init-late.service
 Before=local-fs.target
diff --git a/tools/args.h b/tools/args.h
index f2fa14b..2ce3c36 100644
--- a/tools/args.h
+++ b/tools/args.h
@@ -79,11 +79,12 @@ arg(thinpool_ARG, '\0', "thinpool", string_arg, 0)
 /* Allow some variations */
 arg(resizable_ARG, '\0', "resizable", yes_no_arg, 0)
 arg(allocation_ARG, '\0', "allocation", yes_no_arg, 0)
+arg(available_ARG, '\0', "available", activation_arg, 0)
 
 /*
  * ... and now the short args.
  */
-arg(available_ARG, 'a', "available", yes_no_excl_arg, 0)
+arg(activate_ARG, 'a', "activate", activation_arg, 0)
 arg(all_ARG, 'a', "all", NULL, 0)
 arg(autobackup_ARG, 'A', "autobackup", yes_no_arg, 0)
 arg(activevolumegroups_ARG, 'A', "activevolumegroups", NULL, 0)
diff --git a/tools/commands.h b/tools/commands.h
index a008a7b..3454951 100644
--- a/tools/commands.h
+++ b/tools/commands.h
@@ -61,7 +61,7 @@ xx(lvchange,
    CACHE_VGMETADATA | PERMITTED_READ_ONLY,
    "lvchange\n"
    "\t[-A|--autobackup y|n]\n"
-   "\t[-a|--available [e|l]y|n]\n"
+   "\t[-a|--activate [a|e|l]{y|n}]\n"
    "\t[--addtag Tag]\n"
    "\t[--alloc AllocationPolicy]\n"
    "\t[-C|--contiguous y|n]\n"
@@ -87,11 +87,11 @@ xx(lvchange,
    "\t[--version]" "\n"
    "\tLogicalVolume[Path] [LogicalVolume[Path]...]\n",
 
-   alloc_ARG, autobackup_ARG, available_ARG, contiguous_ARG, force_ARG,
-   ignorelockingfailure_ARG, ignoremonitoring_ARG, major_ARG, minor_ARG,
-   monitor_ARG, noudevsync_ARG, partial_ARG, permission_ARG, persistent_ARG,
-   poll_ARG, readahead_ARG, resync_ARG, refresh_ARG, addtag_ARG, deltag_ARG,
-   sysinit_ARG, test_ARG, yes_ARG)
+   alloc_ARG, autobackup_ARG, activate_ARG, available_ARG, contiguous_ARG,
+   force_ARG, ignorelockingfailure_ARG, ignoremonitoring_ARG, major_ARG,
+   minor_ARG, monitor_ARG, noudevsync_ARG, partial_ARG, permission_ARG,
+   persistent_ARG, poll_ARG, readahead_ARG, resync_ARG, refresh_ARG,
+   addtag_ARG, deltag_ARG, sysinit_ARG, test_ARG, yes_ARG)
 
 xx(lvconvert,
    "Change logical volume layout",
@@ -159,7 +159,7 @@ xx(lvcreate,
    0,
    "lvcreate " "\n"
    "\t[-A|--autobackup {y|n}]\n"
-   "\t[-a|--available [e|l]y|n]\n"
+   "\t[-a|--activate [a|e|l]{y|n}]\n"
    "\t[--addtag Tag]\n"
    "\t[--alloc AllocationPolicy]\n"
    "\t[-C|--contiguous {y|n}]\n"
@@ -214,13 +214,13 @@ xx(lvcreate,
 
    "\t[PhysicalVolumePath...]\n\n",
 
-   addtag_ARG, alloc_ARG, autobackup_ARG, available_ARG, chunksize_ARG,
-   contiguous_ARG, corelog_ARG, extents_ARG, ignoremonitoring_ARG, major_ARG,
-   minor_ARG, mirrorlog_ARG, mirrors_ARG, monitor_ARG, name_ARG, nosync_ARG,
-   noudevsync_ARG, permission_ARG, persistent_ARG, readahead_ARG,
-   regionsize_ARG, size_ARG, snapshot_ARG, stripes_ARG, stripesize_ARG,
-   test_ARG, thin_ARG, thinpool_ARG, type_ARG, virtualoriginsize_ARG,
-   poolmetadatasize_ARG, virtualsize_ARG, zero_ARG)
+   addtag_ARG, alloc_ARG, autobackup_ARG, activate_ARG, available_ARG,
+   chunksize_ARG, contiguous_ARG, corelog_ARG, extents_ARG,
+   ignoremonitoring_ARG, major_ARG, minor_ARG, mirrorlog_ARG, mirrors_ARG,
+   monitor_ARG, name_ARG, nosync_ARG, noudevsync_ARG, permission_ARG,
+   persistent_ARG, readahead_ARG, regionsize_ARG, size_ARG, snapshot_ARG,
+   stripes_ARG, stripesize_ARG, test_ARG, thin_ARG, thinpool_ARG, type_ARG,
+   virtualoriginsize_ARG, poolmetadatasize_ARG, virtualsize_ARG, zero_ARG)
 
 xx(lvdisplay,
    "Display information about a logical volume",
@@ -671,6 +671,7 @@ xx(pvscan,
    "List all physical volumes",
    PERMITTED_READ_ONLY,
    "pvscan " "\n"
+   "\t[-a|--activate ay]\n"
    "\t[--cache [ DevicePath | --major major --minor minor]...]\n"
    "\t[-d|--debug] " "\n"
    "\t{-e|--exported | -n|--novolumegroup} " "\n"
@@ -682,7 +683,8 @@ xx(pvscan,
    "\t[-v|--verbose] " "\n"
    "\t[--version]\n",
 
-   cache_ARG, exported_ARG, ignorelockingfailure_ARG, major_ARG, minor_ARG,
+   activate_ARG, available_ARG, cache_ARG, exported_ARG,
+   ignorelockingfailure_ARG, major_ARG, minor_ARG,
    novolumegroup_ARG, partial_ARG, short_ARG, uuid_ARG)
 
 xx(segtypes,
@@ -742,7 +744,7 @@ xx(vgchange,
    "\t[-u|--uuid] " "\n"
    "\t[-v|--verbose] " "\n"
    "\t[--version]" "\n"
-   "\t{-a|--available [e|l]{y|n}  |" "\n"
+   "\t{-a|--activate [a|e|l]{y|n}  |" "\n"
    "\t -c|--clustered {y|n} |" "\n"
    "\t -x|--resizeable {y|n} |" "\n"
    "\t -l|--logicalvolume MaxLogicalVolumes |" "\n"
@@ -752,11 +754,11 @@ xx(vgchange,
    "\t --deltag Tag}\n"
    "\t[VolumeGroupName...]\n",
 
-   addtag_ARG, alloc_ARG, allocation_ARG, autobackup_ARG, available_ARG,
-   clustered_ARG, deltag_ARG, ignorelockingfailure_ARG, ignoremonitoring_ARG,
-   logicalvolume_ARG, maxphysicalvolumes_ARG, monitor_ARG, noudevsync_ARG,
-   metadatacopies_ARG, vgmetadatacopies_ARG, partial_ARG,
-   physicalextentsize_ARG, poll_ARG, refresh_ARG, resizeable_ARG,
+   addtag_ARG, alloc_ARG, allocation_ARG, autobackup_ARG, activate_ARG,
+   available_ARG, clustered_ARG, deltag_ARG, ignorelockingfailure_ARG,
+   ignoremonitoring_ARG, logicalvolume_ARG, maxphysicalvolumes_ARG,
+   monitor_ARG, noudevsync_ARG, metadatacopies_ARG, vgmetadatacopies_ARG,
+   partial_ARG, physicalextentsize_ARG, poll_ARG, refresh_ARG, resizeable_ARG,
    resizable_ARG, sysinit_ARG, test_ARG, uuid_ARG)
 
 xx(vgck,
diff --git a/tools/lvchange.c b/tools/lvchange.c
index 2ed8c16..9876847 100644
--- a/tools/lvchange.c
+++ b/tools/lvchange.c
@@ -127,16 +127,21 @@ static int lvchange_background_polling(struct cmd_context *cmd,
 	return 1;
 }
 
-static int lvchange_availability(struct cmd_context *cmd,
-				 struct logical_volume *lv)
+static int _lvchange_activate(struct cmd_context *cmd, struct logical_volume *lv)
 {
 	int activate;
 
-	activate = arg_uint_value(cmd, available_ARG, 0);
+	activate = arg_uint_value(cmd, activate_ARG, 0);
 
 	if (lv_is_cow(lv) && !lv_is_virtual_origin(origin_from_cow(lv)))
 		lv = origin_from_cow(lv);
 
+	if (activate == CHANGE_AAY) {
+		if (!lv_passes_auto_activation_filter(cmd, lv))
+			return 1;
+		activate = CHANGE_ALY;
+	}
+
 	if (activate == CHANGE_ALN) {
 		log_verbose("Deactivating logical volume \"%s\" locally",
 			    lv->name);
@@ -556,7 +561,7 @@ static int lvchange_single(struct cmd_context *cmd, struct logical_volume *lv,
 	}
 
 	if (lv_is_cow(lv) && !lv_is_virtual_origin(origin = origin_from_cow(lv)) &&
-	    arg_count(cmd, available_ARG)) {
+	    arg_count(cmd, activate_ARG)) {
 		if (origin->origin_count < 2)
 			snaps_msg[0] = '\0';
 		else if (dm_snprintf(snaps_msg, sizeof(snaps_msg),
@@ -577,7 +582,7 @@ static int lvchange_single(struct cmd_context *cmd, struct logical_volume *lv,
 
 	if (lv->status & PVMOVE) {
 		log_error("Unable to change pvmove LV %s", lv->name);
-		if (arg_count(cmd, available_ARG))
+		if (arg_count(cmd, activate_ARG))
 			log_error("Use 'pvmove --abort' to abandon a pvmove");
 		return ECMD_FAILED;
 	}
@@ -594,7 +599,7 @@ static int lvchange_single(struct cmd_context *cmd, struct logical_volume *lv,
 	}
 
 	/* If LV is sparse, activate origin instead */
-	if (arg_count(cmd, available_ARG) && lv_is_cow(lv) &&
+	if (arg_count(cmd, activate_ARG) && lv_is_cow(lv) &&
 	    lv_is_virtual_origin(origin = origin_from_cow(lv)))
 		lv = origin;
 
@@ -696,9 +701,9 @@ static int lvchange_single(struct cmd_context *cmd, struct logical_volume *lv,
 			return ECMD_FAILED;
 		}
 
-	/* availability change */
-	if (arg_count(cmd, available_ARG)) {
-		if (!lvchange_availability(cmd, lv)) {
+	/* activation change */
+	if (arg_count(cmd, activate_ARG)) {
+		if (!_lvchange_activate(cmd, lv)) {
 			stack;
 			return ECMD_FAILED;
 		}
@@ -710,7 +715,7 @@ static int lvchange_single(struct cmd_context *cmd, struct logical_volume *lv,
 			return ECMD_FAILED;
 		}
 
-	if (!arg_count(cmd, available_ARG) &&
+	if (!arg_count(cmd, activate_ARG) &&
 	    !arg_count(cmd, refresh_ARG) &&
 	    arg_count(cmd, monitor_ARG)) {
 		if (!lvchange_monitoring(cmd, lv)) {
@@ -719,7 +724,7 @@ static int lvchange_single(struct cmd_context *cmd, struct logical_volume *lv,
 		}
 	}
 
-	if (!arg_count(cmd, available_ARG) &&
+	if (!arg_count(cmd, activate_ARG) &&
 	    !arg_count(cmd, refresh_ARG) &&
 	    arg_count(cmd, poll_ARG)) {
 		if (!lvchange_background_polling(cmd, lv)) {
@@ -745,7 +750,7 @@ int lvchange(struct cmd_context *cmd, int argc, char **argv)
 		arg_count(cmd, resync_ARG) || arg_count(cmd, alloc_ARG);
 
 	if (!update &&
-            !arg_count(cmd, available_ARG) && !arg_count(cmd, refresh_ARG) &&
+            !arg_count(cmd, activate_ARG) && !arg_count(cmd, refresh_ARG) &&
             !arg_count(cmd, monitor_ARG) && !arg_count(cmd, poll_ARG)) {
 		log_error("Need 1 or more of -a, -C, -M, -p, -r, "
 			  "--resync, --refresh, --alloc, --addtag, --deltag, "
@@ -753,7 +758,7 @@ int lvchange(struct cmd_context *cmd, int argc, char **argv)
 		return EINVALID_CMD_LINE;
 	}
 
-	if (arg_count(cmd, available_ARG) && arg_count(cmd, refresh_ARG)) {
+	if (arg_count(cmd, activate_ARG) && arg_count(cmd, refresh_ARG)) {
 		log_error("Only one of -a and --refresh permitted.");
 		return EINVALID_CMD_LINE;
 	}
diff --git a/tools/lvcreate.c b/tools/lvcreate.c
index 28d4dbf..ab217cf 100644
--- a/tools/lvcreate.c
+++ b/tools/lvcreate.c
@@ -560,13 +560,19 @@ static int _read_activation_params(struct lvcreate_params *lp, struct cmd_contex
 	unsigned pagesize;
 
 	lp->activate = (activation_change_t)
-		arg_uint_value(cmd, available_ARG, CHANGE_AY);
+		arg_uint_value(cmd, activate_ARG, CHANGE_AY);
 
 	if (lp->activate == CHANGE_AN || lp->activate == CHANGE_ALN) {
 		if (lp->zero && !seg_is_thin(lp)) {
-			log_error("--available n requires --zero n");
+			log_error("--activate n requires --zero n");
 			return 0;
 		}
+	} else if (lp->activate == CHANGE_AAY) {
+		if (arg_count(cmd, zero_ARG)) {
+			log_error("-Z is incompatible with --activate a");
+			return 0;
+		}
+		lp->zero = 0;
 	}
 
 	/*
diff --git a/tools/lvmcmdline.c b/tools/lvmcmdline.c
index 2c3bb39..16e15a1 100644
--- a/tools/lvmcmdline.c
+++ b/tools/lvmcmdline.c
@@ -172,7 +172,7 @@ int yes_no_arg(struct cmd_context *cmd __attribute__((unused)), struct arg_value
 	return 1;
 }
 
-int yes_no_excl_arg(struct cmd_context *cmd __attribute__((unused)), struct arg_values *av)
+int activation_arg(struct cmd_context *cmd __attribute__((unused)), struct arg_values *av)
 {
 	av->sign = SIGN_NONE;
 	av->percent = PERCENT_NONE;
@@ -188,6 +188,12 @@ int yes_no_excl_arg(struct cmd_context *cmd __attribute__((unused)), struct arg_
 		av->ui_value = CHANGE_AY;
 	}
 
+	else if (!strcmp(av->value, "a") || !strcmp(av->value, "ay") ||
+		 !strcmp(av->value, "ya")) {
+		av->i_value = CHANGE_AAY;
+		av->ui_value = CHANGE_AAY;
+	}
+
 	else if (!strcmp(av->value, "n") || !strcmp(av->value, "en") ||
 		 !strcmp(av->value, "ne")) {
 		av->i_value = CHANGE_AN;
@@ -889,7 +895,8 @@ static int _get_settings(struct cmd_context *cmd)
 	if (!_merge_synonym(cmd, resizable_ARG, resizeable_ARG) ||
 	    !_merge_synonym(cmd, allocation_ARG, allocatable_ARG) ||
 	    !_merge_synonym(cmd, allocation_ARG, resizeable_ARG) ||
-	    !_merge_synonym(cmd, virtualoriginsize_ARG, virtualsize_ARG))
+	    !_merge_synonym(cmd, virtualoriginsize_ARG, virtualsize_ARG) ||
+	    !_merge_synonym(cmd, available_ARG, activate_ARG))
 		return EINVALID_CMD_LINE;
 
 	if ((!strncmp(cmd->command->name, "pv", 2) &&
diff --git a/tools/pvremove.c b/tools/pvremove.c
index 0c06c7f..7d05758 100644
--- a/tools/pvremove.c
+++ b/tools/pvremove.c
@@ -128,7 +128,7 @@ static int pvremove_single(struct cmd_context *cmd, const char *pv_name,
 		goto out;
 	}
 
-	if (!lvmetad_pv_gone_by_dev(dev))
+	if (!lvmetad_pv_gone_by_dev(dev, NULL))
 		goto_out;
 
 	log_print("Labels on physical volume \"%s\" successfully wiped",
diff --git a/tools/pvscan.c b/tools/pvscan.c
index f0e7408..b0e172d 100644
--- a/tools/pvscan.c
+++ b/tools/pvscan.c
@@ -99,7 +99,21 @@ static void _pvscan_display_single(struct cmd_context *cmd,
 					   pv_pe_size(pv)));
 }
 
-static int _pvscan_lvmetad_all_devs(struct cmd_context *cmd)
+static int _auto_activation_handler(struct volume_group *vg, int partial, int activate)
+{
+	/* TODO: add support for partial and clustered VGs */
+	if (partial || vg_is_clustered(vg))
+		return 1;
+
+	if (!vgchange_activate(vg->cmd, vg, activate)) {
+		log_error("%s: autoactivation failed.", vg->name);
+		return 0;
+	}
+
+	return 1;
+}
+
+static int _pvscan_lvmetad_all_devs(struct cmd_context *cmd, activation_handler handler)
 {
 	struct dev_iter *iter;
 	struct device *dev;
@@ -111,7 +125,7 @@ static int _pvscan_lvmetad_all_devs(struct cmd_context *cmd)
 	}
 
 	while ((dev = dev_iter_get(iter))) {
-		if (!pvscan_lvmetad_single(cmd, dev)) {
+		if (!pvscan_lvmetad_single(cmd, dev, handler)) {
 			r = 0;
 			break;
 		}
@@ -136,6 +150,15 @@ static int _pvscan_lvmetad(struct cmd_context *cmd, int argc, char **argv)
 	struct arg_value_group_list *current_group;
 	dev_t devno;
 	char *buf;
+	activation_handler handler = NULL;
+
+	if (arg_count(cmd, activate_ARG)) {
+		if (arg_uint_value(cmd, activate_ARG, CHANGE_AAY) != CHANGE_AAY) {
+			log_error("Only --activate ay allowed with pvscan.");
+			return 0;
+		}
+		handler = _auto_activation_handler;
+	}
 
 	if (arg_count(cmd, major_ARG) + arg_count(cmd, minor_ARG))
 		devno_args = 1;
@@ -152,7 +175,7 @@ static int _pvscan_lvmetad(struct cmd_context *cmd, int argc, char **argv)
 
 	/* Scan everything? */
 	if (!argc && !devno_args) {
-		if (!_pvscan_lvmetad_all_devs(cmd))
+		if (!_pvscan_lvmetad_all_devs(cmd, handler))
 			ret = ECMD_FAILED;
 		goto out;
 	}
@@ -169,7 +192,7 @@ static int _pvscan_lvmetad(struct cmd_context *cmd, int argc, char **argv)
 			continue;
 		}
 
-		if (!pvscan_lvmetad_single(cmd, dev)) {
+		if (!pvscan_lvmetad_single(cmd, dev, handler)) {
 			ret = ECMD_FAILED;
 			break;
 		}
@@ -194,7 +217,7 @@ static int _pvscan_lvmetad(struct cmd_context *cmd, int argc, char **argv)
 			if (!dm_asprintf(&buf, "%" PRIi32 ":%" PRIi32, major, minor))
 				stack;
 			/* FIXME Filters? */
-			if (!lvmetad_pv_gone(devno, buf ? : "")) {
+			if (!lvmetad_pv_gone(devno, buf ? : "", handler)) {
 				ret = ECMD_FAILED;
 				if (buf)
 					dm_free(buf);
@@ -208,7 +231,7 @@ static int _pvscan_lvmetad(struct cmd_context *cmd, int argc, char **argv)
 			continue;
 		}
 
-		if (!pvscan_lvmetad_single(cmd, dev)) {
+		if (!pvscan_lvmetad_single(cmd, dev, handler)) {
 			ret = ECMD_FAILED;
 			break;
 		}
@@ -242,6 +265,11 @@ int pvscan(struct cmd_context *cmd, int argc, char **argv)
 	if (arg_count(cmd, cache_ARG))
 		return _pvscan_lvmetad(cmd, argc, argv);
 
+	if (arg_count(cmd, activate_ARG)) {
+		log_error("--activate is only valid with --cache.");
+		return EINVALID_CMD_LINE;
+	}
+
 	if (arg_count(cmd, major_ARG) + arg_count(cmd, minor_ARG)) {
 		log_error("--major and --minor are only valid with --cache.");
 		return EINVALID_CMD_LINE;
diff --git a/tools/toollib.c b/tools/toollib.c
index d5ad805..3df0ef0 100644
--- a/tools/toollib.c
+++ b/tools/toollib.c
@@ -129,7 +129,7 @@ int process_each_lv_in_vg(struct cmd_context *cmd,
 
 		/* Skip availability change for non-virt snaps when processing all LVs */
 		/* FIXME: pass process_all to process_single_lv() */
-		if (process_all && arg_count(cmd, available_ARG) &&
+		if (process_all && arg_count(cmd, activate_ARG) &&
 		    lv_is_cow(lvl->lv) && !lv_is_virtual_origin(origin_from_cow(lvl->lv)))
 			continue;
 
diff --git a/tools/tools.h b/tools/tools.h
index b467e4b..7a44651 100644
--- a/tools/tools.h
+++ b/tools/tools.h
@@ -138,7 +138,7 @@ void usage(const char *name);
 
 /* the argument verify/normalise functions */
 int yes_no_arg(struct cmd_context *cmd, struct arg_values *av);
-int yes_no_excl_arg(struct cmd_context *cmd, struct arg_values *av);
+int activation_arg(struct cmd_context *cmd, struct arg_values *av);
 int size_kb_arg(struct cmd_context *cmd, struct arg_values *av);
 int size_mb_arg(struct cmd_context *cmd, struct arg_values *av);
 int int_arg(struct cmd_context *cmd, struct arg_values *av);
@@ -185,4 +185,7 @@ int mirror_remove_missing(struct cmd_context *cmd,
 			  struct logical_volume *lv, int force);
 
 uint32_t percent_of_extents(uint32_t percents, uint32_t count, int roundup);
+
+int vgchange_activate(struct cmd_context *cmd, struct volume_group *vg,
+		       activation_change_t activate);
 #endif
diff --git a/tools/vgchange.c b/tools/vgchange.c
index dc06ac9..ebabb08 100644
--- a/tools/vgchange.c
+++ b/tools/vgchange.c
@@ -81,8 +81,8 @@ static int _poll_lvs_in_vg(struct cmd_context *cmd,
 	return count;
 }
 
-static int _activate_lvs_in_vg(struct cmd_context *cmd,
-			       struct volume_group *vg, int activate)
+static int _activate_lvs_in_vg(struct cmd_context *cmd, struct volume_group *vg,
+			       activation_change_t activate)
 {
 	struct lv_list *lvl;
 	struct logical_volume *lv;
@@ -131,6 +131,12 @@ static int _activate_lvs_in_vg(struct cmd_context *cmd,
 			continue;
 		}
 
+		if (activate == CHANGE_AAY) {
+			if (!lv_passes_auto_activation_filter(cmd, lv))
+				continue;
+			activate = CHANGE_ALY;
+		}
+
 		expected_count++;
 
 		if (activate == CHANGE_AN) {
@@ -211,35 +217,32 @@ static int _vgchange_background_polling(struct cmd_context *cmd, struct volume_g
 	return 1;
 }
 
-static int _vgchange_available(struct cmd_context *cmd, struct volume_group *vg)
+int vgchange_activate(struct cmd_context *cmd, struct volume_group *vg,
+		      activation_change_t activate)
 {
-	int lv_open, active, monitored = 0;
-	int available, r = 1;
-	int activate = 1;
+	int lv_open, active, monitored = 0, r = 1, do_activate = 1;
+
+	if ((activate == CHANGE_AN) || (activate == CHANGE_ALN))
+		do_activate = 0;
 
 	/*
 	 * Safe, since we never write out new metadata here. Required for
 	 * partial activation to work.
 	 */
-	cmd->handles_missing_pvs = 1;
-
-	available = arg_uint_value(cmd, available_ARG, 0);
-
-	if ((available == CHANGE_AN) || (available == CHANGE_ALN))
-		activate = 0;
+        cmd->handles_missing_pvs = 1;
 
 	/* FIXME: Force argument to deactivate them? */
-	if (!activate && (lv_open = lvs_in_vg_opened(vg))) {
+	if (!do_activate && (lv_open = lvs_in_vg_opened(vg))) {
 		log_error("Can't deactivate volume group \"%s\" with %d open "
 			  "logical volume(s)", vg->name, lv_open);
 		return 0;
 	}
 
 	/* FIXME Move into library where clvmd can use it */
-	if (activate)
+	if (do_activate)
 		check_current_backup(vg);
 
-	if (activate && (active = lvs_in_vg_activated(vg))) {
+	if (do_activate && (active = lvs_in_vg_activated(vg))) {
 		log_verbose("%d logical volume(s) in volume group \"%s\" "
 			    "already active", active, vg->name);
 		if (dmeventd_monitor_mode() != DMEVENTD_MONITOR_IGNORE) {
@@ -252,7 +255,7 @@ static int _vgchange_available(struct cmd_context *cmd, struct volume_group *vg)
 		}
 	}
 
-	if (!_activate_lvs_in_vg(cmd, vg, available))
+	if (!_activate_lvs_in_vg(cmd, vg, activate))
 		r = 0;
 
 	/* Print message only if there was not found a missing VG */
@@ -508,8 +511,8 @@ static int vgchange_single(struct cmd_context *cmd, const char *vg_name,
 		log_print("Volume group \"%s\" successfully changed", vg->name);
 	}
 
-	if (arg_count(cmd, available_ARG)) {
-		if (!_vgchange_available(cmd, vg))
+	if (arg_count(cmd, activate_ARG)) {
+		if (!vgchange_activate(cmd, vg, arg_uint_value(cmd, activate_ARG, CHANGE_AY)))
 			return ECMD_FAILED;
 	}
 
@@ -519,7 +522,7 @@ static int vgchange_single(struct cmd_context *cmd, const char *vg_name,
 			return ECMD_FAILED;
 	}
 
-	if (!arg_count(cmd, available_ARG) &&
+	if (!arg_count(cmd, activate_ARG) &&
 	    !arg_count(cmd, refresh_ARG) &&
 	    arg_count(cmd, monitor_ARG)) {
 		/* -ay* will have already done monitoring changes */
@@ -551,7 +554,7 @@ int vgchange(struct cmd_context *cmd, int argc, char **argv)
 		arg_count(cmd, vgmetadatacopies_ARG);
 
 	if (!update &&
-	    !arg_count(cmd, available_ARG) &&
+	    !arg_count(cmd, activate_ARG) &&
 	    !arg_count(cmd, monitor_ARG) &&
 	    !arg_count(cmd, poll_ARG) &&
 	    !arg_count(cmd, refresh_ARG)) {
@@ -562,7 +565,7 @@ int vgchange(struct cmd_context *cmd, int argc, char **argv)
 		return EINVALID_CMD_LINE;
 	}
 
-	if (arg_count(cmd, available_ARG) && arg_count(cmd, refresh_ARG)) {
+	if (arg_count(cmd, activate_ARG) && arg_count(cmd, refresh_ARG)) {
 		log_error("Only one of -a and --refresh permitted.");
 		return EINVALID_CMD_LINE;
 	}
@@ -573,9 +576,9 @@ int vgchange(struct cmd_context *cmd, int argc, char **argv)
 		return EINVALID_CMD_LINE;
 	}
 
-	if (arg_count(cmd, available_ARG) &&
+	if (arg_count(cmd, activate_ARG) &&
 	    (arg_count(cmd, monitor_ARG) || arg_count(cmd, poll_ARG))) {
-		int activate = arg_uint_value(cmd, available_ARG, 0);
+		int activate = arg_uint_value(cmd, activate_ARG, 0);
 		if (activate == CHANGE_AN || activate == CHANGE_ALN) {
 			log_error("Only -ay* allowed with --monitor or --poll.");
 			return EINVALID_CMD_LINE;
@@ -587,7 +590,7 @@ int vgchange(struct cmd_context *cmd, int argc, char **argv)
 		return EINVALID_CMD_LINE;
 	}
 
-	if (arg_count(cmd, available_ARG) == 1
+	if (arg_count(cmd, activate_ARG) == 1
 	    && arg_count(cmd, autobackup_ARG)) {
 		log_error("-A option not necessary with -a option");
 		return EINVALID_CMD_LINE;
diff --git a/udev/10-dm.rules.in b/udev/10-dm.rules.in
index 605e088..29af467 100644
--- a/udev/10-dm.rules.in
+++ b/udev/10-dm.rules.in
@@ -18,11 +18,7 @@ KERNEL=="device-mapper", NAME="(DM_DIR)/control"
 
 SUBSYSTEM!="block", GOTO="dm_end"
 KERNEL!="dm-[0-9]*", GOTO="dm_end"
-
-# Set proper sbin path, /sbin has higher priority than /usr/sbin.
-ENV{DM_SBIN_PATH}="/sbin"
-TEST!="$env{DM_SBIN_PATH}/dmsetup", ENV{DM_SBIN_PATH}="/usr/sbin"
-TEST!="$env{DM_SBIN_PATH}/dmsetup", GOTO="dm_end"
+(DM_EXEC_RULE)
 
 # Device created, major and minor number assigned - "add" event generated.
 # Table loaded - no event generated.
@@ -40,7 +36,7 @@ ACTION!="add|change", GOTO="dm_end"
 # These flags are encoded in DM_COOKIE variable that was introduced in
 # kernel version 2.6.31. Therefore, we can use this feature with
 # kernels >= 2.6.31 only. Cookie is not decoded for remove event.
-ENV{DM_COOKIE}=="?*", IMPORT{program}="$env{DM_SBIN_PATH}/dmsetup udevflags $env{DM_COOKIE}"
+ENV{DM_COOKIE}=="?*", IMPORT{program}="(DM_EXEC)/dmsetup udevflags $env{DM_COOKIE}"
 
 # Rule out easy-to-detect inappropriate events first.
 ENV{DISK_RO}=="1", GOTO="dm_disable"
@@ -91,8 +87,8 @@ ACTION=="add", ENV{DM_UDEV_RULES_VSN}!="1", ENV{DM_UDEV_PRIMARY_SOURCE_FLAG}!="1
 # so we also have to call dmsetup if the kernel version used
 # is in between these releases.
 TEST=="dm", ENV{DM_NAME}="$attr{dm/name}", ENV{DM_UUID}="$attr{dm/uuid}", ENV{DM_SUSPENDED}="$attr{dm/suspended}"
-TEST!="dm", IMPORT{program}="$env{DM_SBIN_PATH}/dmsetup info -j %M -m %m -c --nameprefixes --noheadings --rows -o name,uuid,suspended"
-ENV{DM_SUSPENDED}!="?*", IMPORT{program}="$env{DM_SBIN_PATH}/dmsetup info -j %M -m %m -c --nameprefixes --noheadings --rows -o suspended"
+TEST!="dm", IMPORT{program}="(DM_EXEC)/dmsetup info -j %M -m %m -c --nameprefixes --noheadings --rows -o name,uuid,suspended"
+ENV{DM_SUSPENDED}!="?*", IMPORT{program}="(DM_EXEC)/dmsetup info -j %M -m %m -c --nameprefixes --noheadings --rows -o suspended"
 
 # dmsetup tool provides suspended state information in textual
 # form with values "Suspended"/"Active". We translate it to
diff --git a/udev/11-dm-lvm.rules b/udev/11-dm-lvm.rules
deleted file mode 100644
index 8244464..0000000
--- a/udev/11-dm-lvm.rules
+++ /dev/null
@@ -1,37 +0,0 @@
-# Copyright (C) 2009 Red Hat, Inc. All rights reserved.
-#
-# This file is part of LVM2.
-
-# Udev rules for LVM.
-#
-# These rules create symlinks for LVM logical volumes in
-# /dev/VG directory (VG is an actual VG name). Some udev
-# environment variables are set (they can be used in later
-# rules as well):
-#   DM_LV_NAME - logical volume name
-#   DM_VG_NAME - volume group name
-#   DM_LV_LAYER - logical volume layer (blank if not set)
-
-# "add" event is processed on coldplug only!
-ACTION!="add|change", GOTO="lvm_end"
-ENV{DM_UDEV_RULES_VSN}!="?*", GOTO="lvm_end"
-ENV{DM_UUID}!="LVM-?*", GOTO="lvm_end"
-
-# Use DM name and split it up into its VG/LV/layer constituents.
-IMPORT{program}="$env{DM_SBIN_PATH}/dmsetup splitname --nameprefixes --noheadings --rows $env{DM_NAME}"
-
-ENV{DM_UDEV_DISABLE_SUBSYSTEM_RULES_FLAG}=="1", GOTO="lvm_end"
-
-# Do not create symlinks for inappropriate subdevices.
-ENV{DM_LV_NAME}=="pvmove?*|?*_vorigin", GOTO="lvm_disable"
-ENV{DM_LV_LAYER}=="?*", GOTO="lvm_disable"
-
-# Create symlinks for top-level devices only.
-ENV{DM_VG_NAME}=="?*", ENV{DM_LV_NAME}=="?*", SYMLINK+="$env{DM_VG_NAME}/$env{DM_LV_NAME}", GOTO="lvm_end"
-
-LABEL="lvm_disable"
-ENV{DM_UDEV_DISABLE_DISK_RULES_FLAG}="1"
-ENV{DM_UDEV_DISABLE_OTHER_RULES_FLAG}="1"
-OPTIONS:="nowatch"
-
-LABEL="lvm_end"
diff --git a/udev/11-dm-lvm.rules.in b/udev/11-dm-lvm.rules.in
new file mode 100644
index 0000000..58ef210
--- /dev/null
+++ b/udev/11-dm-lvm.rules.in
@@ -0,0 +1,37 @@
+# Copyright (C) 2009 Red Hat, Inc. All rights reserved.
+#
+# This file is part of LVM2.
+
+# Udev rules for LVM.
+#
+# These rules create symlinks for LVM logical volumes in
+# /dev/VG directory (VG is an actual VG name). Some udev
+# environment variables are set (they can be used in later
+# rules as well):
+#   DM_LV_NAME - logical volume name
+#   DM_VG_NAME - volume group name
+#   DM_LV_LAYER - logical volume layer (blank if not set)
+
+# "add" event is processed on coldplug only!
+ACTION!="add|change", GOTO="lvm_end"
+ENV{DM_UDEV_RULES_VSN}!="?*", GOTO="lvm_end"
+ENV{DM_UUID}!="LVM-?*", GOTO="lvm_end"
+
+# Use DM name and split it up into its VG/LV/layer constituents.
+IMPORT{program}="(DM_EXEC)/dmsetup splitname --nameprefixes --noheadings --rows $env{DM_NAME}"
+
+ENV{DM_UDEV_DISABLE_SUBSYSTEM_RULES_FLAG}=="1", GOTO="lvm_end"
+
+# Do not create symlinks for inappropriate subdevices.
+ENV{DM_LV_NAME}=="pvmove?*|?*_vorigin", GOTO="lvm_disable"
+ENV{DM_LV_LAYER}=="?*", GOTO="lvm_disable"
+
+# Create symlinks for top-level devices only.
+ENV{DM_VG_NAME}=="?*", ENV{DM_LV_NAME}=="?*", SYMLINK+="$env{DM_VG_NAME}/$env{DM_LV_NAME}", GOTO="lvm_end"
+
+LABEL="lvm_disable"
+ENV{DM_UDEV_DISABLE_DISK_RULES_FLAG}="1"
+ENV{DM_UDEV_DISABLE_OTHER_RULES_FLAG}="1"
+OPTIONS:="nowatch"
+
+LABEL="lvm_end"
diff --git a/udev/69-dm-lvm-metad.rules b/udev/69-dm-lvm-metad.rules
deleted file mode 100644
index d272e6e..0000000
--- a/udev/69-dm-lvm-metad.rules
+++ /dev/null
@@ -1,30 +0,0 @@
-# Copyright (C) 2012 Red Hat, Inc. All rights reserved.
-#
-# This file is part of LVM2.
-
-# Udev rules for LVM.
-#
-# Scan all block devices having a PV label for LVM metadata.
-# Store this information in LVMetaD (the LVM metadata daemon) and maintain LVM
-# metadata state for improved performance by avoiding further scans while
-# running subsequent LVM commands or while using lvm2app library.
-# Also, notify LVMetaD about any relevant block device removal.
-#
-# This rule is essential for having the information in LVMetaD up-to-date.
-# It also requires blkid to be called on block devices before so only devices
-# used as LVM PVs are processed (ID_FS_TYPE="LVM2_member" or "LVM1_member").
-
-SUBSYSTEM!="block", GOTO="lvm_end"
-
-# Device-mapper devices are processed only on change event or on supported synthesized event.
-KERNEL=="dm-[0-9]*", ENV{DM_UDEV_RULES_VSN}!="?*", GOTO="lvm_end"
-
-# Set proper sbin path, /sbin has higher priority than /usr/sbin.
-ENV{LVM_SBIN_PATH}="/sbin"
-TEST!="$env{LVM_SBIN_PATH}/lvm", ENV{LVM_SBIN_PATH}="/usr/sbin"
-TEST!="$env{LVM_SBIN_PATH}/lvm", GOTO="lvm_end"
-
-# Only process devices already marked as a PV - this requires blkid to be called before.
-ENV{ID_FS_TYPE}=="LVM2_member|LVM1_member", RUN+="$env{LVM_SBIN_PATH}/lvm pvscan --cache --major $major --minor $minor"
-
-LABEL="lvm_end"
diff --git a/udev/69-dm-lvm-metad.rules.in b/udev/69-dm-lvm-metad.rules.in
new file mode 100644
index 0000000..706c03b
--- /dev/null
+++ b/udev/69-dm-lvm-metad.rules.in
@@ -0,0 +1,26 @@
+# Copyright (C) 2012 Red Hat, Inc. All rights reserved.
+#
+# This file is part of LVM2.
+
+# Udev rules for LVM.
+#
+# Scan all block devices having a PV label for LVM metadata.
+# Store this information in LVMetaD (the LVM metadata daemon) and maintain LVM
+# metadata state for improved performance by avoiding further scans while
+# running subsequent LVM commands or while using lvm2app library.
+# Also, notify LVMetaD about any relevant block device removal.
+#
+# This rule is essential for having the information in LVMetaD up-to-date.
+# It also requires blkid to be called on block devices before so only devices
+# used as LVM PVs are processed (ID_FS_TYPE="LVM2_member" or "LVM1_member").
+
+SUBSYSTEM!="block", GOTO="lvm_end"
+(LVM_EXEC_RULE)
+
+# Device-mapper devices are processed only on change event or on supported synthesized event.
+KERNEL=="dm-[0-9]*", ENV{DM_UDEV_RULES_VSN}!="?*", GOTO="lvm_end"
+
+# Only process devices already marked as a PV - this requires blkid to be called before.
+ENV{ID_FS_TYPE}=="LVM2_member|LVM1_member", RUN+="(LVM_EXEC)/lvm pvscan --cache --activate ay --major $major --minor $minor"
+
+LABEL="lvm_end"
diff --git a/udev/95-dm-notify.rules b/udev/95-dm-notify.rules
deleted file mode 100644
index 72cc609..0000000
--- a/udev/95-dm-notify.rules
+++ /dev/null
@@ -1,12 +0,0 @@
-# Copyright (C) 2009 Red Hat, Inc. All rights reserved.
-#
-# This file is part of LVM2.
-
-# Udev rules for device-mapper devices.
-#
-# These rules are responsible for sending a notification to a process
-# waiting for completion of udev rules. The process is identified by
-# a cookie value sent within "change" and "remove" events (the cookie
-# value is set before by that process for every action requested).
-
-ENV{DM_COOKIE}=="?*", RUN+="$env{DM_SBIN_PATH}/dmsetup udevcomplete $env{DM_COOKIE}"
diff --git a/udev/95-dm-notify.rules.in b/udev/95-dm-notify.rules.in
new file mode 100644
index 0000000..80d59d3
--- /dev/null
+++ b/udev/95-dm-notify.rules.in
@@ -0,0 +1,12 @@
+# Copyright (C) 2009 Red Hat, Inc. All rights reserved.
+#
+# This file is part of LVM2.
+
+# Udev rules for device-mapper devices.
+#
+# These rules are responsible for sending a notification to a process
+# waiting for completion of udev rules. The process is identified by
+# a cookie value sent within "change" and "remove" events (the cookie
+# value is set before by that process for every action requested).
+
+ENV{DM_COOKIE}=="?*", RUN+="(DM_EXEC)/dmsetup udevcomplete $env{DM_COOKIE}"
diff --git a/udev/Makefile.in b/udev/Makefile.in
index 4ace910..5c15bdb 100644
--- a/udev/Makefile.in
+++ b/udev/Makefile.in
@@ -15,28 +15,39 @@ srcdir = @srcdir@
 top_srcdir = @top_srcdir@
 top_builddir = @top_builddir@
 
+include $(top_builddir)/make.tmpl
+vpath %.rules $(srcdir)
+
 DM_RULES=10-dm.rules 13-dm-disk.rules 95-dm-notify.rules
 LVM_RULES=11-dm-lvm.rules
-DM_DIR=$(shell grep "\#define DM_DIR" $(top_srcdir)/libdm/misc/dm-ioctl.h | awk '{print $$3}')
-
 ifeq ("@BUILD_LVMETAD@", "yes")
 LVM_RULES+=69-dm-lvm-metad.rules
 endif
 
-ifeq ("@UDEV_HAS_BUILTIN_BLKID@", "yes")
-	BLKID_RULE=IMPORT{builtin}=\"blkid\"
+DM_DIR=$(shell grep "\#define DM_DIR" $(top_srcdir)/libdm/misc/dm-ioctl.h | awk '{print $$3}')
+
+ifeq ("@UDEV_RULE_EXEC_DETECTION@", "yes")
+SBIN=\$$env{DM_SBIN_PATH}
+DM_EXEC_RULE=ENV{DM_SBIN_PATH}=\"\/sbin\"\\nTEST!=\"\$$env{DM_SBIN_PATH}\/dmsetup\", ENV{DM_SBIN_PATH}=\"\/usr\/sbin\"
+DM_EXEC=\$$env{DM_SBIN_PATH}
+LVM_EXEC_RULE=ENV{LVM_SBIN_PATH}=\"\/sbin\"\\nTEST!=\"\$$env{LVM_SBIN_PATH}\/lvm\", ENV{LVM_SBIN_PATH}=\"\/usr\/sbin\"
+LVM_EXEC=\$$env{LVM_SBIN_PATH}
 else
-	BLKID_RULE=IMPORT{program}=\"\$$env{DM_SBIN_PATH}\/blkid -o udev -p \$$tempnode\"
+SBIN="@sbindir@"
+DM_EXEC_RULE=""
+DM_EXEC=${SBIN}
+LVM_EXEC_RULE=""
+LVM_EXEC=${SBIN}
 endif
 
-CLEAN_TARGETS = 10-dm.rules 13-dm-disk.rules
-
-include $(top_builddir)/make.tmpl
-
-vpath %.rules $(srcdir)
+ifeq ("@UDEV_HAS_BUILTIN_BLKID@", "yes")
+BLKID_RULE=IMPORT{builtin}=\"blkid\"
+else
+BLKID_RULE=IMPORT{program}=\"${SBIN}\/blkid -o udev -p \$$tempnode\"
+endif
 
 %.rules: %.rules.in
-	$(SED) -e "s/(DM_DIR)/$(DM_DIR)/" -e "s/(BLKID_RULE)/$(BLKID_RULE)/" $< >$@
+	$(SED) -e "s+(DM_DIR)+$(DM_DIR)+;s+(BLKID_RULE)+$(BLKID_RULE)+;s+(DM_EXEC_RULE)+$(DM_EXEC_RULE)+;s+(DM_EXEC)+$(DM_EXEC)+;s+(LVM_EXEC_RULE)+$(LVM_EXEC_RULE)+;s+(LVM_EXEC)+$(LVM_EXEC)+;" $< >$@
 
 %_install: %.rules
 	$(INSTALL_DATA) -D $< $(udevdir)/$(<F)