1
0
mirror of git://sourceware.org/git/lvm2.git synced 2025-12-04 20:23:49 +03:00

Compare commits

..

24 Commits

Author SHA1 Message Date
David Teigland
a7de7a7bc0 add activation services
New systemd services for startup:

lvm-devices-wait.service
  Used in place of systemd-udev-settle, this service waits
  for udev+pvscan to process PVs listed in system.devices.
  It runs the command "lvmdevices --wait pvsonline".
  This only waits for PVs that can be matched to a device in
  sysfs, so it only waits for devices attached to the system.
  It waits specifically for the /run/lvm/pvs_online/<pvid>
  files to be created by pvscan.  It quits waiting after a
  configurable number of seconds.  This service gives the
  first activation service a chance to activate VGs from
  PVs that are available immediately at startup.  If this
  service quits waiting before all the expected pvid files
  appear, then the VG associated with those PVs will most
  likely be activated by the -last service rather than the
  initial -main service.  If those PVs are even slower to
  complete processing than the -last service, then the VG
  will be activated by event activation whenever they are
  finally complete.

lvm-activate-vgs-main.service
  Calls "vgchange -aay", after lvm-devices-wait, to activate
  complete VGs.  It only considers PVs that have been
  processed by udev+pvscan and have pvs_online files.
  This is expected to activate VGs from basic devices
  (not virtual device types) that are present at startup.

lvm-activate-vgs-last.service
  Calls "vgchange -aay", after multipathd has started, to
  activate VGs that became available after virtual device
  services were started, e.g. VGs on multipath devices.
  Like -main, it only looks at PVs that have been processed
  by pvscan.

This vgchange in the -last service enables event activation
by creating the /run/lvm/event-activation-on file.  Event
activation will activate any further VGs that appear on the
system (or complete udev processing) after the -last service.
In the case of event activation, the udev rule will run
vgchange -aay <vgname> via a transient service
lvm-activate-<vgname>.service.  This vgchange only scans
PVs in the VG being activated, also based on the pvs_online
files from pvscan.

When there are many VGs that need activation during system
startup, the two fixed services can activate them all much
faster than activating each VG individually via events.

lvm.conf auto_activation_settings can be used to configure
the behavior (default ["service_and_event", "pvscan_hints"]).

"service_and_event" - the behavior described above, where
activation services are used first, and event activation
is used afterward.

"service_only" - only lvm-activate-vgs-* are used, and
no event-based activation occurs after the services finish.
(Equivalent to setting lvm.conf event_activation=0.)

"event_only" - the lvm-activate-vgs* services are skipped,
and all VGs are activated individually with event-based
activation.

"pvscan_hints" - the vgchange autoactivation commands
use pvs_online files created by pvscan.  This optimization
limits the devices scanned by the vgchange command to only
PVs that have been processed by pvscan.
2021-10-29 16:29:42 -05:00
David Teigland
f056bf8f94 hints: new pvs_online type
A new form of hints to use in autoactivation commands
during startup to reduce device scanning.  Using these
hints, vgchange will read only the devices for the VG
it is activating.

Standard hints allow a command with a named VG arg to scan
only the PVs in the named VG, rather than scanning all
available PVs.  Standard hints are useful with a stable set
of system devices.  When new devices are arriving, as occurs
during system startup, the hints are repeatedly invalidated,
which makes standard hints unhelpful while devices are
regularly appearing.  This is the situation in which
vgchange -aay is used, so standard hints are not generally
helpful for autoactivation.

In the context of system startup, pvscan --cache is keeping
track of available PVs using the pvs_online files, similar
to what the hints file does for a running system.  Given this,
a new hint mode, hints = "pvs_online", is added which derives
an equivalent to standard hints, based on pvs_online files
that are being created by udev-run pvscans.  This hint mode
is useful while devices are appearing, e.g. during system
startup, and vgchange -aay can benefit from it.

pvscan --cache -aay autoactivation already has a similar
optimization (the "quick" activation case) that is based
on the pvs_online file, but it is not implemented as a
form of hints.

This new form of hints is mainly useful in the context of
event based autoactivation, during which standard hints are
not useful.  Once the system is in a steady state after startup
(devices are not regularly appearing), the standard hints are
most useful.  The pvs_online hint method could be used on a
running system, but would be no better than standard hints,
and may be inferior because pvs_online files are not rigidly
updated after system startup.
2021-10-29 15:55:48 -05:00
David Teigland
a3467564a4 lvmdevices: increase open file limit 2021-10-29 15:55:48 -05:00
David Teigland
b65a2c3f3a vgimportdevices: skip lvmlockd locking
Help bootstrapping existing shared vgs into the devices file.
Reading the vg in vgimportdevices would require locking to be
started, but vgchange lockstart won't see the vg if it's not
in the devices file.  The lvmlockd locks are not protecting
vg modifications so skipping them here won't be a problem.
2021-10-25 12:11:17 -05:00
Christian Hesse
221e75316f The path is known anyway and should be the bullet proof option.
Signed-off-by: Christian Hesse <mail@eworm.de>
2021-10-21 16:33:23 -05:00
David Teigland
ae355ffc3f pvscan: fix messages from coverity changes 2021-10-20 16:12:55 -05:00
Marian Csontos
819a35cc91 post-release 2021-10-20 11:13:28 +02:00
Marian Csontos
ef4521831d pre-release 2021-10-20 11:12:39 +02:00
Marian Csontos
36be4d68f6 WHATS_NEW: update 2021-10-20 11:10:37 +02:00
David Teigland
33e47182f7 pvscan: only add device args to dev cache
Optimize the common pvscan --cache command by only adding
the necessary devs to dev-cache.
2021-10-19 17:13:57 -05:00
Zdenek Kabelac
60dc44b707 dev-cache: enhance dir scan also for non-udev build 2021-10-18 21:50:56 +02:00
Zdenek Kabelac
88e0d68909 dev-cache: better detection of filesystem
It appear on some systems the first found dev might not be actually for
the filesytem - so use a better way through _cache.st_dev.
2021-10-18 21:16:53 +02:00
Zdenek Kabelac
c60bac4661 configure: update 2021-10-18 19:17:27 +02:00
Zdenek Kabelac
1b104ddb55 configure.ac: remove unused part
As we are not using 'enable-compat' for anything, remove this section.
Also remove duplicated check for blkid.
Move setting of some AC_ARG_ENABLE defaults into the macro so it's always
defined.
2021-10-18 19:17:27 +02:00
Zdenek Kabelac
a172a02a9a cleanup: use const char buffer 2021-10-18 19:17:27 +02:00
Zdenek Kabelac
9cf4eac250 dev-cache: skip different filesystems on dir scan
When scanning configured  /dev dir, avoid entring
directories with different filesystem.

This minimizes risk we will block on i.e. entring
directory with mount point.
2021-10-18 19:17:26 +02:00
Zdenek Kabelac
bae1083472 cov: check device_ids_write return code
At least 'stack' failure code path as the
function device_id_update_vg_uuid() is void.
2021-10-15 23:40:56 +02:00
Zdenek Kabelac
c2be6c38d5 cov: ensure id is always initialize
Always resed sd_id128_t id and report warning in case
sd_id128_get_machine_app_specific() does not exit with 0.
2021-10-15 23:40:56 +02:00
Zdenek Kabelac
882141eb8c cov: check pointer before dereferencing
Check pv2 is non-null before trying to deref its tags.
2021-10-15 23:40:56 +02:00
Zdenek Kabelac
65ba4964df cov: do not drop already known error state
Do not try to 'discover' another error state, when ENOMEM
is already detected.
2021-10-15 23:40:56 +02:00
Zdenek Kabelac
e7b5f490c5 cov: ignore close result 2021-10-15 23:40:29 +02:00
Zdenek Kabelac
6668d6409a cov: validate subcommand existance
Before dereference of subcommand pointer, check it's not NULL
as  coverity believes there exists theoretical path for this...
2021-10-15 23:39:25 +02:00
Zdenek Kabelac
2779830a06 cov: avoid using NULL info
Check lvmcache info exists before calling lvmcache_del_save_bad_mda().
2021-10-15 23:36:22 +02:00
Zdenek Kabelac
8aefd97252 configure: fix use of withval
Newly added option --with-default-use-devices-file needs to use withval.
2021-10-15 23:35:05 +02:00
38 changed files with 574 additions and 366 deletions

View File

@@ -1 +1 @@
2.03.14(2)-git (2021-08-11)
2.03.15(2)-git (2021-10-20)

View File

@@ -1 +1 @@
1.02.181-git (2021-08-11)
1.02.183-git (2021-10-20)

View File

@@ -1,5 +1,9 @@
Version 2.03.14 -
==================================
Version 2.03.15 -
===================================
Version 2.03.14 - 20th October 2021
===================================
Device scanning is skipping directories on different filesystems.
Print info message with too many or too large archived files.
Reduce metadata readings during scanning phase.
Optimize computation of crc32 check sum with multiple PVs.
@@ -7,7 +11,7 @@ Version 2.03.14 -
Filter out unsupported MQ/SMQ cache policy setting.
Fix memleak in mpath filter.
Support newer location for VDO statistics.
Add support for VDO async-unsage write policy.
Add support for VDO async-unsafe write policy.
Improve lvm_import_vdo script.
Support VDO LV with lvcreate -ky.
Fix lvconvert for VDO LV bigger then 2T.

View File

@@ -1,5 +1,8 @@
Version 1.02.181 -
===================================
Version 1.02.183 -
====================================
Version 1.02.181 - 20th October 2021
====================================
Add IMA support with 'dmsetup measure' command.
Add defines DM_NAME_LIST_FLAG_HAS_UUID, DM_NAME_LIST_FLAG_DOESNT_HAVE_UUID.
Enhance tracking of activated devices when preloading dm tree.

117
configure vendored
View File

@@ -773,10 +773,10 @@ PYTHON
LVM2CMD_LIB
UDEV_LIBS
UDEV_CFLAGS
SYSTEMD_LIBS
SYSTEMD_CFLAGS
BLKID_LIBS
BLKID_CFLAGS
SYSTEMD_LIBS
SYSTEMD_CFLAGS
LOCKD_IDM_LIBS
LOCKD_IDM_CFLAGS
LOCKD_DLM_CONTROL_LIBS
@@ -964,7 +964,6 @@ enable_udev_systemd_background_jobs
enable_udev_sync
enable_udev_rules
enable_udev_rule_exec_detection
enable_compat
enable_units_compat
enable_ioctl
enable_o_direct
@@ -1029,10 +1028,10 @@ LOCKD_DLM_CONTROL_CFLAGS
LOCKD_DLM_CONTROL_LIBS
LOCKD_IDM_CFLAGS
LOCKD_IDM_LIBS
BLKID_CFLAGS
BLKID_LIBS
SYSTEMD_CFLAGS
SYSTEMD_LIBS
BLKID_CFLAGS
BLKID_LIBS
UDEV_CFLAGS
UDEV_LIBS
PYTHON
@@ -1705,7 +1704,6 @@ Optional Features:
--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
--disable-ioctl disable ioctl calls to device-mapper in the kernel
@@ -1853,13 +1851,13 @@ Some influential environment variables:
C compiler flags for LOCKD_IDM, overriding pkg-config
LOCKD_IDM_LIBS
linker flags for LOCKD_IDM, overriding pkg-config
BLKID_CFLAGS
C compiler flags for BLKID, overriding pkg-config
BLKID_LIBS linker flags for BLKID, overriding pkg-config
SYSTEMD_CFLAGS
C compiler flags for SYSTEMD, overriding pkg-config
SYSTEMD_LIBS
linker flags for SYSTEMD, overriding pkg-config
BLKID_CFLAGS
C compiler flags for BLKID, overriding pkg-config
BLKID_LIBS linker flags for BLKID, overriding pkg-config
UDEV_CFLAGS C compiler flags for UDEV, overriding pkg-config
UDEV_LIBS linker flags for UDEV, overriding pkg-config
PYTHON the Python interpreter
@@ -3142,10 +3140,6 @@ case "$host_os" in
LIB_SUFFIX=so
DEVMAPPER=yes
BUILD_LVMPOLLD=no
LOCKDSANLOCK=no
LOCKDDLM=no
LOCKDDLM_CONTROL=no
LOCKDIDM=no
ODIRECT=yes
DM_IOCTLS=yes
SELINUX=yes
@@ -8467,7 +8461,7 @@ $as_echo_n "checking default for use_devicesfile... " >&6; }
# Check whether --with-default-use-devices-file was given.
if test "${with_default_use_devices_file+set}" = set; then :
withval=$with_default_use_devices_file; DEFAULT_USE_DEVICES_FILE=$enableval
withval=$with_default_use_devices_file; DEFAULT_USE_DEVICES_FILE=$withval
else
DEFAULT_USE_DEVICES_FILE=0
fi
@@ -11001,6 +10995,8 @@ $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
else
LVMPOLLD=no
fi
test -n "$LVMPOLLD" && BUILD_LVMPOLLD=$LVMPOLLD
@@ -11015,6 +11011,8 @@ $as_echo_n "checking whether to build lvmlockdsanlock... " >&6; }
# Check whether --enable-lvmlockd-sanlock was given.
if test "${enable_lvmlockd_sanlock+set}" = set; then :
enableval=$enable_lvmlockd_sanlock; LOCKDSANLOCK=$enableval
else
LOCKDSANLOCK=no
fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $LOCKDSANLOCK" >&5
@@ -11106,6 +11104,8 @@ $as_echo_n "checking whether to build lvmlockddlm... " >&6; }
# Check whether --enable-lvmlockd-dlm was given.
if test "${enable_lvmlockd_dlm+set}" = set; then :
enableval=$enable_lvmlockd_dlm; LOCKDDLM=$enableval
else
LOCKDDLM=no
fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $LOCKDDLM" >&5
@@ -11197,6 +11197,8 @@ $as_echo_n "checking whether to build lvmlockddlmcontrol... " >&6; }
# Check whether --enable-lvmlockd-dlmcontrol was given.
if test "${enable_lvmlockd_dlmcontrol+set}" = set; then :
enableval=$enable_lvmlockd_dlmcontrol; LOCKDDLM_CONTROL=$enableval
else
LOCKDDLM_CONTROL=no
fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $LOCKDDLM_CONTROL" >&5
@@ -11288,6 +11290,8 @@ $as_echo_n "checking whether to build lvmlockdidm... " >&6; }
# Check whether --enable-lvmlockd-idm was given.
if test "${enable_lvmlockd_idm+set}" = set; then :
enableval=$enable_lvmlockd_idm; LOCKDIDM=$enableval
else
LOCKDIDM=no
fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $LOCKDIDM" >&5
@@ -11367,76 +11371,15 @@ else
$as_echo "yes" >&6; }
HAVE_LOCKD_IDM=yes
fi
pkg_failed=no
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for BLKID" >&5
$as_echo_n "checking for BLKID... " >&6; }
if test -n "$BLKID_CFLAGS"; then
pkg_cv_BLKID_CFLAGS="$BLKID_CFLAGS"
elif test -n "$PKG_CONFIG"; then
if test -n "$PKG_CONFIG" && \
if test -n "$PKG_CONFIG" && \
{ { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"blkid >= 2.24\""; } >&5
($PKG_CONFIG --exists --print-errors "blkid >= 2.24") 2>&5
ac_status=$?
$as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
test $ac_status = 0; }; then
pkg_cv_BLKID_CFLAGS=`$PKG_CONFIG --cflags "blkid >= 2.24" 2>/dev/null`
test "x$?" != "x0" && pkg_failed=yes
HAVE_LOCKD_IDM=yes
else
pkg_failed=yes
fi
else
pkg_failed=untried
fi
if test -n "$BLKID_LIBS"; then
pkg_cv_BLKID_LIBS="$BLKID_LIBS"
elif test -n "$PKG_CONFIG"; then
if test -n "$PKG_CONFIG" && \
{ { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"blkid >= 2.24\""; } >&5
($PKG_CONFIG --exists --print-errors "blkid >= 2.24") 2>&5
ac_status=$?
$as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
test $ac_status = 0; }; then
pkg_cv_BLKID_LIBS=`$PKG_CONFIG --libs "blkid >= 2.24" 2>/dev/null`
test "x$?" != "x0" && pkg_failed=yes
else
pkg_failed=yes
fi
else
pkg_failed=untried
fi
if test $pkg_failed = yes; then
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
$as_echo "no" >&6; }
if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then
_pkg_short_errors_supported=yes
else
_pkg_short_errors_supported=no
fi
if test $_pkg_short_errors_supported = yes; then
BLKID_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "blkid >= 2.24" 2>&1`
else
BLKID_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "blkid >= 2.24" 2>&1`
fi
# Put the nasty error message in config.log where it belongs
echo "$BLKID_PKG_ERRORS" >&5
$bailout
elif test $pkg_failed = untried; then
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
$as_echo "no" >&6; }
$bailout
else
BLKID_CFLAGS=$pkg_cv_BLKID_CFLAGS
BLKID_LIBS=$pkg_cv_BLKID_LIBS
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
$as_echo "yes" >&6; }
HAVE_LOCKD_IDM=yes
$bailout
fi
$as_echo "#define LOCKDIDM_SUPPORT 1" >>confdefs.h
@@ -12086,24 +12029,6 @@ $as_echo_n "checking whether udev supports built-in blkid... " >&6; }
$as_echo "$UDEV_HAS_BUILTIN_BLKID" >&6; }
fi
################################################################################
# Check whether --enable-compat was given.
if test "${enable_compat+set}" = set; then :
enableval=$enable_compat; DM_COMPAT=$enableval
else
DM_COMPAT=no
fi
if test "$DM_COMPAT" = yes; then :
$as_echo "#define DM_COMPAT 1" >>confdefs.h
as_fn_error $? "--enable-compat is not currently supported.
Since device-mapper version 1.02.66, only one version (4) of the device-mapper
ioctl protocol is supported." "$LINENO" 5
fi
################################################################################
# Check whether --enable-units-compat was given.
if test "${enable_units_compat+set}" = set; then :

View File

@@ -38,10 +38,6 @@ case "$host_os" in
LIB_SUFFIX=so
DEVMAPPER=yes
BUILD_LVMPOLLD=no
LOCKDSANLOCK=no
LOCKDDLM=no
LOCKDDLM_CONTROL=no
LOCKDIDM=no
ODIRECT=yes
DM_IOCTLS=yes
SELINUX=yes
@@ -290,7 +286,7 @@ dnl -- Default settings for lvm.conf { devices/use_devicesfile }
AC_MSG_CHECKING(default for use_devicesfile)
AC_ARG_WITH(default-use-devices-file,
AS_HELP_STRING([--with-default-use-devices-file], [default for lvm.conf devices/use_devicesfile = [0]]),
DEFAULT_USE_DEVICES_FILE=$enableval, DEFAULT_USE_DEVICES_FILE=0)
DEFAULT_USE_DEVICES_FILE=$withval, DEFAULT_USE_DEVICES_FILE=0)
case "$DEFAULT_USE_DEVICES_FILE" in
0|1);;
*) AC_MSG_ERROR([--with-default-use-devices-file parameter invalid]);;
@@ -913,7 +909,7 @@ AC_MSG_CHECKING(whether to build lvmpolld)
AC_ARG_ENABLE(lvmpolld,
AS_HELP_STRING([--enable-lvmpolld],
[enable the LVM Polling Daemon]),
LVMPOLLD=$enableval)
LVMPOLLD=$enableval, LVMPOLLD=no)
test -n "$LVMPOLLD" && BUILD_LVMPOLLD=$LVMPOLLD
AC_MSG_RESULT($BUILD_LVMPOLLD)
@@ -925,7 +921,7 @@ AC_MSG_CHECKING(whether to build lvmlockdsanlock)
AC_ARG_ENABLE(lvmlockd-sanlock,
AS_HELP_STRING([--enable-lvmlockd-sanlock],
[enable the LVM lock daemon using sanlock]),
LOCKDSANLOCK=$enableval)
LOCKDSANLOCK=$enableval, LOCKDSANLOCK=no)
AC_MSG_RESULT($LOCKDSANLOCK)
BUILD_LOCKDSANLOCK=$LOCKDSANLOCK
@@ -943,7 +939,7 @@ AC_MSG_CHECKING(whether to build lvmlockddlm)
AC_ARG_ENABLE(lvmlockd-dlm,
AS_HELP_STRING([--enable-lvmlockd-dlm],
[enable the LVM lock daemon using dlm]),
LOCKDDLM=$enableval)
LOCKDDLM=$enableval, LOCKDDLM=no)
AC_MSG_RESULT($LOCKDDLM)
BUILD_LOCKDDLM=$LOCKDDLM
@@ -961,7 +957,7 @@ AC_MSG_CHECKING(whether to build lvmlockddlmcontrol)
AC_ARG_ENABLE(lvmlockd-dlmcontrol,
AS_HELP_STRING([--enable-lvmlockd-dlmcontrol],
[enable lvmlockd remote refresh using libdlmcontrol]),
LOCKDDLM_CONTROL=$enableval)
LOCKDDLM_CONTROL=$enableval, LOCKDDLM_CONTROL=no)
AC_MSG_RESULT($LOCKDDLM_CONTROL)
BUILD_LOCKDDLM_CONTROL=$LOCKDDLM_CONTROL
@@ -979,7 +975,7 @@ AC_MSG_CHECKING(whether to build lvmlockdidm)
AC_ARG_ENABLE(lvmlockd-idm,
AS_HELP_STRING([--enable-lvmlockd-idm],
[enable the LVM lock daemon using idm]),
LOCKDIDM=$enableval)
LOCKDIDM=$enableval, LOCKDIDM=no)
AC_MSG_RESULT($LOCKDIDM)
BUILD_LOCKDIDM=$LOCKDIDM
@@ -987,7 +983,7 @@ BUILD_LOCKDIDM=$LOCKDIDM
dnl -- Look for Seagate IDM libraries
if test "$BUILD_LOCKDIDM" = yes; then
PKG_CHECK_MODULES(LOCKD_IDM, libseagate_ilm >= 0.1.0, [HAVE_LOCKD_IDM=yes], $bailout)
PKG_CHECK_MODULES(BLKID, blkid >= 2.24, [HAVE_LOCKD_IDM=yes], $bailout)
PKG_CHECK_EXISTS(blkid >= 2.24, [HAVE_LOCKD_IDM=yes], $bailout)
AC_DEFINE([LOCKDIDM_SUPPORT], 1, [Define to 1 to include code that uses lvmlockd IDM option.])
BUILD_LVMLOCKD=yes
fi
@@ -1218,19 +1214,6 @@ if test "$UDEV_RULE" != no ; then
AC_MSG_RESULT($UDEV_HAS_BUILTIN_BLKID)
fi
################################################################################
dnl -- Compatibility mode
AC_ARG_ENABLE(compat,
AS_HELP_STRING([--enable-compat],
[enable support for old device-mapper versions]),
DM_COMPAT=$enableval, DM_COMPAT=no)
AS_IF([test "$DM_COMPAT" = yes],
[AC_DEFINE([DM_COMPAT], 1, [Define to enable compat protocol])
AC_MSG_ERROR([--enable-compat is not currently supported.
Since device-mapper version 1.02.66, only one version (4) of the device-mapper
ioctl protocol is supported.])])
################################################################################
dnl -- Compatible units suffix mode
AC_ARG_ENABLE(units-compat,
@@ -2002,6 +1985,7 @@ po/Makefile
scripts/lvm2-pvscan.service
scripts/lvm-activate-vgs-main.service
scripts/lvm-activate-vgs-last.service
scripts/lvm-devices-wait.service
scripts/blkdeactivate.sh
scripts/blk_availability_init_red_hat
scripts/blk_availability_systemd_red_hat.service

View File

@@ -3016,9 +3016,7 @@ static int add_lockspace_thread(const char *ls_name,
!alloc_and_copy_pvs_path(&ls2->pvs, &ls->pvs)) {
log_debug("add_lockspace_thread %s fails to allocate pvs", ls->name);
rv = -ENOMEM;
}
if (ls2->thread_stop) {
} else if (ls2->thread_stop) {
log_debug("add_lockspace_thread %s exists and stopping", ls->name);
rv = -EAGAIN;
} else if (!ls2->create_fail && !ls2->create_done) {

View File

@@ -114,9 +114,6 @@
/* Define to 1 to enable the device-mapper filemap daemon. */
#undef DMFILEMAPD
/* Define to enable compat protocol */
#undef DM_COMPAT
/* Define default group for device node */
#undef DM_DEVICE_GID

View File

@@ -159,9 +159,11 @@ static const char *_system_id_from_source(struct cmd_context *cmd, const char *s
#ifdef APP_MACHINEID_SUPPORT
if (!strcasecmp(source, "appmachineid")) {
sd_id128_t id;
sd_id128_t id = { 0 };
sd_id128_get_machine_app_specific(LVM_APPLICATION_ID, &id);
if (sd_id128_get_machine_app_specific(LVM_APPLICATION_ID, &id) != 0)
log_warn("WARNING: sd_id128_get_machine_app_specific() failed %s (%d).",
strerror(errno), errno);
if (dm_snprintf(buf, PATH_MAX, SD_ID128_FORMAT_STR, SD_ID128_FORMAT_VAL(id)) < 0)
stack;

View File

@@ -174,7 +174,7 @@ struct cmd_context {
unsigned activate_component:1; /* command activates component LV */
unsigned process_component_lvs:1; /* command processes also component LVs */
unsigned mirror_warn_printed:1; /* command already printed warning about non-monitored mirrors */
unsigned pvscan_cache_single:1;
unsigned expect_missing_vg_device:1; /* when reading a vg it's expected that a dev for a pv isn't found */
unsigned can_use_one_scan:1;
unsigned is_clvmd:1;
unsigned md_component_detection:1;

View File

@@ -257,6 +257,9 @@ cfg(devices_hints_CFG, "hints", devices_CFG_SECTION, CFG_DEFAULT_COMMENTED, CFG_
" Use no hints.\n"
"#\n")
cfg(devices_lvmdevices_wait_seconds_CFG, "lvmdevices_wait_seconds", devices_CFG_SECTION, CFG_DEFAULT_COMMENTED, CFG_TYPE_INT, DEFAULT_LVMDEVICES_WAIT_SECONDS, vsn(2, 3, 14), NULL, 0, NULL,
"Max number of seconds the lvmdevices --wait command should wait.\n")
cfg_array(devices_preferred_names_CFG, "preferred_names", devices_CFG_SECTION, CFG_ALLOW_EMPTY | CFG_DEFAULT_UNDEFINED , CFG_TYPE_STRING, NULL, vsn(1, 2, 19), NULL, 0, NULL,
"Select which path name to display for a block device.\n"
"If multiple path names exist for a block device, and LVM needs to\n"
@@ -1121,27 +1124,11 @@ cfg(global_lvdisplay_shows_full_device_path_CFG, "lvdisplay_shows_full_device_pa
cfg(global_event_activation_CFG, "event_activation", global_CFG_SECTION, CFG_DEFAULT_COMMENTED, CFG_TYPE_BOOL, 1, vsn(2, 3, 1), 0, 0, NULL,
"Activate LVs based on system-generated device events.\n"
"When a PV appears on the system, a system-generated uevent triggers\n"
"the lvm2-pvscan service which runs the pvscan --cache -aay command.\n"
"If the new PV completes a VG, pvscan autoactivates LVs in the VG.\n"
"When event_activation is disabled, the lvm2-activation services are\n"
"generated and run at fixed points during system startup. These\n"
"services run vgchange -aay to autoactivate LVs in VGs that happen\n"
"to be present at that point in time.\n"
"the pvscan command, and autoactivation when all PVs for a VG are online.\n"
"Also see auto_activation_settings.\n"
"See the --setautoactivation option or the auto_activation_volume_list\n"
"setting to configure autoactivation for specific VGs or LVs.\n")
cfg_array(global_event_activation_options_CFG, "event_activation_options", global_CFG_SECTION, CFG_ALLOW_EMPTY | CFG_DEFAULT_COMMENTED, CFG_TYPE_STRING, DEFAULT_EVENT_ACTIVATION_OPTIONS, vsn(2, 3, 14), NULL, 0, NULL,
"Set event activation options.\n"
"service_to_event: begin with fixed activation services,\n"
"then switch to event based activation.\n"
"event_only: only use event based activation.\n"
"service_only: only use fixed activation services.\n"
"(This is equivalent to event_activation=0.)\n"
"Autoactivation commands should set --eventactivation service|event\n"
"to indicate if they are performing service or event activation.\n"
"An autoactivation command may then be skipped according to the\n"
"value of this setting.\n")
cfg(global_use_lvmetad_CFG, "use_lvmetad", global_CFG_SECTION, CFG_DEFAULT_COMMENTED, CFG_TYPE_BOOL, 0, vsn(2, 2, 93), 0, vsn(2, 3, 0), NULL,
NULL)
@@ -1421,6 +1408,21 @@ cfg_array(activation_volume_list_CFG, "volume_list", activation_CFG_SECTION, CFG
"volume_list = [ \"vg1\", \"vg2/lvol1\", \"@tag1\", \"@*\" ]\n"
"#\n")
cfg_array(activation_auto_activation_settings_CFG, "auto_activation_settings", global_CFG_SECTION, CFG_ALLOW_EMPTY | CFG_DEFAULT_COMMENTED, CFG_TYPE_STRING, DEFAULT_AUTOACTIVATION_SETTINGS, vsn(2, 3, 14), NULL, 0, NULL,
"Configure autoactivation behavior.\n"
"service_and_event: use fixed activation services, then switch to event activation\n."
"(Only used when event_activation=1.)\n"
"event_only: use only event activation\n"
"(Only used when event_activation=1.)\n"
"service_only: use only fixed activation services\n"
"(Effectively the equivalent of event_activation=0.)\n"
"pvscan_hints: autoactivation commands will use PVs that\n"
"that have been processed by pvscan (from udev rule.)\n"
"Without pvscan_hints, pvscan only be used when it is needed\n"
"to perform event activation.\n"
"Autoactivation commands should set --autoactivation service|event\n"
"to indicate if they are performing service or event activation.\n")
cfg_array(activation_auto_activation_volume_list_CFG, "auto_activation_volume_list", activation_CFG_SECTION, CFG_ALLOW_EMPTY | CFG_DEFAULT_UNDEFINED, CFG_TYPE_STRING, NULL, vsn(2, 2, 97), NULL, 0, NULL,
"A list of VGs or LVs that should be autoactivated.\n"
"Autoactivation is an activation command run with -aay,\n"

View File

@@ -328,11 +328,14 @@
#define DEFAULT_WWIDS_FILE "/etc/multipath/wwids"
#define DEFAULT_EVENT_ACTIVATION_OPTION1 "service_to_event"
#define DEFAULT_EVENT_ACTIVATION_OPTIONS "#S" DEFAULT_EVENT_ACTIVATION_OPTION1
#define PVS_ONLINE_DIR DEFAULT_RUN_DIR "/pvs_online"
#define VGS_ONLINE_DIR DEFAULT_RUN_DIR "/vgs_online"
#define PVS_LOOKUP_DIR DEFAULT_RUN_DIR "/pvs_lookup"
#define DEFAULT_AUTOACTIVATION_SETTING1 "service_and_event"
#define DEFAULT_AUTOACTIVATION_SETTING2 "pvscan_hints"
#define DEFAULT_AUTOACTIVATION_SETTINGS "#S" DEFAULT_AUTOACTIVATION_SETTING1 "#S" DEFAULT_AUTOACTIVATION_SETTING2
#define DEFAULT_LVMDEVICES_WAIT_SECONDS 10
#endif /* _LVM_DEFAULTS_H */

View File

@@ -53,6 +53,7 @@ static struct {
const char *dev_dir;
int has_scanned;
long st_dev;
struct dm_list dirs;
struct dm_list files;
@@ -1064,11 +1065,18 @@ static void _insert_dirs(struct dm_list *dirs)
struct dir_list *dl;
struct udev *udev = NULL;
int with_udev;
struct stat tinfo;
with_udev = obtain_device_list_from_udev() &&
(udev = udev_get_library_context());
dm_list_iterate_items(dl, &_cache.dirs) {
if (stat(dl->dir, &tinfo) < 0) {
log_warn("WARNING: Cannot use dir %s, %s.",
dl->dir, strerror(errno));
continue;
}
_cache.st_dev = tinfo.st_dev;
if (with_udev) {
if (!_insert_udev_dir(udev, dl->dir))
log_debug_devs("%s: Failed to insert devices from "
@@ -1091,9 +1099,17 @@ static int _device_in_udev_db(const dev_t d)
static void _insert_dirs(struct dm_list *dirs)
{
struct dir_list *dl;
struct stat tinfo;
dm_list_iterate_items(dl, &_cache.dirs)
dm_list_iterate_items(dl, &_cache.dirs) {
if (stat(dl->dir, &tinfo) < 0) {
log_warn("WARNING: Cannot use dir %s, %s.",
dl->dir, strerror(errno));
continue;
}
_cache.st_dev = tinfo.st_dev;
_insert_dir(dl->dir);
}
}
#endif /* UDEV_SYNC_SUPPORT */
@@ -1128,6 +1144,11 @@ static int _insert(const char *path, const struct stat *info,
return 1;
}
if (info->st_dev != _cache.st_dev) {
log_debug_devs("%s: Different filesystem in directory", path);
return 1;
}
if (rec && !_insert_dir(path))
return 0;
} else { /* add a device */

View File

@@ -779,7 +779,7 @@ static void _device_ids_update_try(struct cmd_context *cmd)
int held = 0;
/* Defer updates to non-pvscan-cache commands. */
if (cmd->pvscan_cache_single) {
if (cmd->expect_missing_vg_device) {
log_print("pvscan[%d] skip updating devices file.", getpid());
return;
}
@@ -1351,8 +1351,9 @@ void device_id_update_vg_uuid(struct cmd_context *cmd, struct volume_group *vg,
}
}
if (update)
device_ids_write(cmd);
if (update &&
!device_ids_write(cmd))
stack;
out:
unlock_devices_file(cmd);
}

View File

@@ -465,7 +465,7 @@ static struct volume_group *_vg_read_raw(struct cmd_context *cmd,
vg = _vg_read_raw_area(cmd, fid, vgname, &mdac->area, vg_fmtdata, use_previous_vg, 0, mda_is_primary(mda));
if (!vg && !*use_previous_vg) {
if (!vg && use_previous_vg && !*use_previous_vg) {
/*
* This condition (corrupt metadata text) is often seen in the
* label_scan()/_text_read() phase, where this code corresponds to
@@ -477,8 +477,12 @@ static struct volume_group *_vg_read_raw(struct cmd_context *cmd,
struct lvmcache_info *info = lvmcache_info_from_pvid(dev->pvid, dev, 0);
log_warn("WARNING: reading %s mda%d failed to read metadata.", dev_name(dev), mda_is_primary(mda)?1:2);
log_warn("WARNING: repair VG metadata on %s with vgck --updatemetadata.", dev_name(dev));
/* remove mda from lvmcache, saving it in info->bad_mdas for possible repair with updatemetadata */
lvmcache_del_save_bad_mda(info, mda->mda_num, BAD_MDA_TEXT);
if (info)
/* remove mda from lvmcache, saving it in info->bad_mdas for possible repair with updatemetadata */
lvmcache_del_save_bad_mda(info, mda->mda_num, BAD_MDA_TEXT);
else
log_warn("WARNING: No cache info for %s", dev_name(dev));
/* remove mda from fid */
fid_remove_mda(fid, mda, NULL, 0, 0);
}

View File

@@ -156,6 +156,7 @@
#include <sys/file.h>
#include <sys/sysmacros.h>
/* FIXME: move online pv functions to pvs_online.c */
int online_pvid_file_read(char *path, int *major, int *minor, char *vgname);
static const char *_hints_file = DEFAULT_RUN_DIR "/hints";
@@ -1406,7 +1407,7 @@ int get_hints(struct cmd_context *cmd, struct dm_list *hints_out, int *newhints,
*newhints = NEWHINTS_NONE;
/* No commands are using hints. */
if (!cmd->enable_hints)
if (!cmd->enable_hints && !cmd->hints_pvs_online)
return 0;
/*
@@ -1426,7 +1427,11 @@ int get_hints(struct cmd_context *cmd, struct dm_list *hints_out, int *newhints,
if (!cmd->use_hints)
return 0;
/* hints = "pvs_online" */
/*
* enable_hints is 0 for the special hints=pvs_online
* and by lvm.conf hints="none" does not disable hints=pvs_online.
* hints=pvs_online can be disabled with --nohints.
*/
if (cmd->hints_pvs_online) {
if (!_get_hints_from_pvs_online(cmd, &hints_list, devs_in, devs_out)) {
log_debug("get_hints: pvs_online failed");

View File

@@ -891,7 +891,7 @@ static int _setup_bcache(void)
#define BASE_FD_COUNT 32 /* Number of open files we want apart from devs */
static void _prepare_open_file_limit(struct cmd_context *cmd, unsigned int num_devs)
void prepare_open_file_limit(struct cmd_context *cmd, unsigned int num_devs)
{
#ifdef HAVE_PRLIMIT
struct rlimit old = { 0 }, new;
@@ -1168,7 +1168,7 @@ int label_scan(struct cmd_context *cmd)
* which we want to keep open) is higher than the current
* soft limit.
*/
_prepare_open_file_limit(cmd, dm_list_size(&scan_devs));
prepare_open_file_limit(cmd, dm_list_size(&scan_devs));
/*
* Do the main scan.

View File

@@ -134,4 +134,6 @@ void dev_invalidate(struct device *dev);
void dev_set_last_byte(struct device *dev, uint64_t offset);
void dev_unset_last_byte(struct device *dev);
void prepare_open_file_limit(struct cmd_context *cmd, unsigned int num_devs);
#endif

View File

@@ -503,7 +503,7 @@ static int _create_sanlock_lv(struct cmd_context *cmd, struct volume_group *vg,
.read_ahead = DM_READ_AHEAD_NONE,
.stripes = 1,
.vg_name = vg->name,
.lv_name = dm_pool_strdup(cmd->mem, lock_lv_name),
.lv_name = lock_lv_name,
.zero = 1,
};

View File

@@ -2354,7 +2354,7 @@ static int _match_pv_tags(const struct dm_config_node *cling_tag_list_cn,
const struct dm_config_value *cv;
const char *str;
const char *tag_matched;
struct dm_list *tags_to_match = mem ? NULL : pv_tags ? : &pv2->tags;
struct dm_list *tags_to_match = mem ? NULL : pv_tags ? : ((pv2) ? &pv2->tags : NULL);
struct dm_str_list *sl;
unsigned first_tag = 1;
@@ -2409,7 +2409,7 @@ static int _match_pv_tags(const struct dm_config_node *cling_tag_list_cn,
continue;
}
if (!str_list_match_list(&pv1->tags, tags_to_match, &tag_matched))
if (tags_to_match && !str_list_match_list(&pv1->tags, tags_to_match, &tag_matched))
continue;
if (!pv_tags) {

View File

@@ -3558,7 +3558,7 @@ static void _set_pv_device(struct format_instance *fid,
if (!id_write_format(&pv->id, buffer, sizeof(buffer)))
buffer[0] = '\0';
if (cmd && !cmd->pvscan_cache_single &&
if (cmd && !cmd->expect_missing_vg_device &&
(!vg_is_foreign(vg) && !cmd->include_foreign_vgs))
log_warn("WARNING: Couldn't find device with uuid %s.", buffer);
else
@@ -5084,7 +5084,7 @@ struct volume_group *vg_read(struct cmd_context *cmd, const char *vg_name, const
if (!pvl->pv->dev) {
/* The obvious and common case of a missing device. */
if (vg_is_foreign(vg) && !cmd->include_foreign_vgs)
if ((vg_is_foreign(vg) && !cmd->include_foreign_vgs) || cmd->expect_missing_vg_device)
log_debug("VG %s is missing PV %s (last written to %s)", vg_name, uuidstr, pvl->pv->device_hint ?: "na");
else if (pvl->pv->device_hint)
log_warn("WARNING: VG %s is missing PV %s (last written to %s).", vg_name, uuidstr, pvl->pv->device_hint);

View File

@@ -5846,12 +5846,12 @@ static int _stats_report(CMD_ARGS)
if (_switches[ALL_PROGRAMS_ARG])
_program_id = "";
if (_switches[VERBOSE_ARG] && !strcmp(subcommand, "list"))
if (_switches[VERBOSE_ARG] && subcommand && !strcmp(subcommand, "list"))
_statstype |= (DM_STATS_WALK_ALL
| DM_STATS_WALK_SKIP_SINGLE_AREA);
/* suppress duplicates unless the user has requested all regions */
if (!strcmp(subcommand, "report") && !objtype_args)
if (subcommand && !objtype_args && !strcmp(subcommand, "report"))
/* suppress duplicate rows of output */
_statstype |= (DM_STATS_WALK_ALL
| DM_STATS_WALK_SKIP_SINGLE_AREA);

View File

@@ -1,21 +1,23 @@
[Unit]
Description=Activate LVM Volume Groups (last)
Documentation=man:vgchange(8)
Wants=systemd-udev-settle.service
After=lvm-activate-vgs-main.service systemd-udev-settle.service multipathd.service cryptsetup.target
After=lvm-activate-vgs-main.service multipathd.service cryptsetup.target dm-event.socket dm-event.service
Before=local-fs-pre.target shutdown.target
DefaultDependencies=no
Conflicts=shutdown.target
# "--eventactivation service" tells vgchange it is being called
# "--autoactivation service" tells vgchange it is being called
# from an activation service, so it will do nothing if
# lvm.conf event_activation_options = "event_only".
# "--eventactivation on" tells vgchange to enable event-based
# pvscan activations by creating /run/lvm/event-activation-on.
# lvm.conf autoactivation_settings has "event_only".
# "--autoactivation event_enable" tells vgchange to enable
# event-based pvscan activations by creating /run/lvm/event-activation-on.
# By default this vgchange will use device hints from pvs_online
# files, so it will only look at PVs that have finished being
# processed by udev and pvscan --cache.
[Service]
Type=oneshot
ExecStart=@SBINDIR@/lvm vgchange -aay --nohints --vgonline --eventactivation service,on
ExecStart=@SBINDIR@/lvm vgchange -aay --vgonline --autoactivation service,event_enable
RemainAfterExit=yes
[Install]

View File

@@ -1,18 +1,21 @@
[Unit]
Description=Activate LVM Volume Groups
Documentation=man:vgchange(8)
After=dm-event.socket dm-event.service
After=dm-event.socket dm-event.service lvm-devices-wait.service
Before=local-fs-pre.target shutdown.target
DefaultDependencies=no
Conflicts=shutdown.target
# "--eventactivation service" tells vgchange it is being called
# from an activation service, so it will do nothing if
# lvm.conf event_activation_options = "event_only".
# "--autoactivation service" tells vgchange it is being called
# from an autoactivation service, so it will do nothing if
# lvm.conf autoactivation_settings has "event_only".
# By default this vgchange will use device hints from pvs_online
# files, so it will only look at PVs that have finished being
# processed by udev and pvscan --cache.
[Service]
Type=oneshot
ExecStart=@SBINDIR@/lvm vgchange -aay --nohints --vgonline --eventactivation service
ExecStart=@SBINDIR@/lvm vgchange -aay --vgonline --autoactivation service
RemainAfterExit=yes
[Install]

View File

@@ -0,0 +1,21 @@
[Unit]
Description=Wait for LVM devices to be ready
Documentation=man:lvmdevices(8)
After=systemd-udev-trigger.service
Before=lvm-activate-vgs-main.service lvm-activate-vgs-last.service
DefaultDependencies=no
Conflicts=shutdown.target
# Waits for entries in /etc/lvm/devices/system.devices to be processed
# by udev and pvscan --cache. Only device entries that are found in
# sysfs are waited for. See lvm.conf devices_wait_service "timeout=N"
# to configure the number of seconds that this service will wait.
[Service]
Type=oneshot
ExecStart=@SBINDIR@/lvmdevices --wait pvsonline
RemainAfterExit=yes
[Install]
WantedBy=sysinit.target

View File

@@ -283,7 +283,7 @@ not ls "$RUNDIR/lvm/pvs_online/$PVID3"
# arg in devices list
_clear_online_files
pvscan --devices "$dev3" --cache -aay "$dev3"
pvscan --devices "$dev4" --cache -aay "$dev4"
pvscan --devices "$dev4","$dev3" --cache -aay "$dev4"
check lv_field $vg2/$lv2 lv_active "active"
vgchange -an $vg2

View File

@@ -86,7 +86,7 @@ static void *_fix_init(struct io_engine *engine)
}
if (!_runs_is_tmpfs) {
close(f->fd);
(void) close(f->fd);
// reopen with O_DIRECT
f->fd = open(f->fname, O_RDWR | O_DIRECT);
T_ASSERT(f->fd >= 0);

View File

@@ -87,6 +87,11 @@ arg(atversion_ARG, '\0', "atversion", string_VAL, 0, 0,
"which does not contain any newer settings for which LVM would\n"
"issue a warning message when checking the configuration.\n")
arg(autoactivation_ARG, '\0', "autoactivation", string_VAL, 0, 0,
"Specify if the command is running autoactivation from an event\n"
"or a service. lvm.conf autoactivation_settings determine if\n"
"activation commands from services or events are used.\n")
arg(setautoactivation_ARG, '\0', "setautoactivation", bool_VAL, 0, 0,
"Set the autoactivation property on a VG or LV.\n"
"Display the property with vgs or lvs \"-o autoactivation\".\n"
@@ -278,11 +283,6 @@ arg(errorwhenfull_ARG, '\0', "errorwhenfull", bool_VAL, 0, 0,
"(Also see dm-thin-pool kernel module option no_space_timeout.)\n"
"See \\fBlvmthin\\fP(7) for more information.\n")
arg(eventactivation_ARG, '\0', "eventactivation", string_VAL, 0, 0,
"Specify if the command is running autoactivation from an event\n"
"or a fixed service. The lvm.conf event_activation_options setting\n"
"determines if event or service based activation commands are used.\n")
arg(force_long_ARG, '\0', "force", 0, ARG_COUNTABLE, 0,
"Force metadata restore even with thin pool LVs.\n"
"Use with extreme caution. Most changes to thin metadata\n"
@@ -925,6 +925,10 @@ arg(vgonline_ARG, '\0', "vgonline", 0, 0, 0,
"The first command to see a complete VG will report it uniquely.\n"
"Other commands to see the complete VG will report it differently.\n")
arg(wait_ARG, '\0', "wait", string_VAL, 0, 0,
"pvsonline: wait for /run/lvm/pvs_online files to exist\n"
"for all devices file entries matched to a system device.\n")
arg(withsummary_ARG, '\0', "withsummary", 0, 0, 0,
"Display a one line comment for each configuration node.\n")

View File

@@ -1447,6 +1447,10 @@ lvmdevices --delpvid String
ID: lvmdevices_edit
DESC: Remove the devices file entry for the given PVID.
lvmdevices --wait String
ID: lvmdevices_wait
DESC: Wait for matched PV entries to be online.
---
lvreduce --size NSizeMB LV
@@ -1642,7 +1646,7 @@ DESC: Record that a PV is online or offline.
pvscan --cache_long --activate ay
OO: --ignorelockingfailure, --reportformat ReportFmt,
--major Number, --minor Number, --noudevsync, --eventactivation String
--major Number, --minor Number, --noudevsync, --autoactivation String
OP: PV|String ...
IO: --background
ID: pvscan_cache
@@ -1650,7 +1654,7 @@ DESC: Record that a PV is online and autoactivate the VG if complete.
pvscan --cache_long --listvg PV
OO: --ignorelockingfailure, --checkcomplete, --vgonline, --udevoutput,
--eventactivation String
--autoactivation String
ID: pvscan_cache
DESC: Record that a PV is online and list the VG using the PV.
@@ -1749,7 +1753,7 @@ DESC: Start or stop processing LV conversions.
vgchange --activate Active
OO: --activationmode ActivationMode, --ignoreactivationskip, --partial, --sysinit,
--readonly, --ignorelockingfailure, --monitor Bool, --poll Bool,
--vgonline, --eventactivation String, OO_VGCHANGE
--vgonline, --autoactivation String, OO_VGCHANGE
OP: VG|Tag|Select ...
IO: --ignoreskippedcluster
ID: vgchange_activate

View File

@@ -19,6 +19,7 @@
/* coverity[unnecessary_header] needed for MuslC */
#include <sys/file.h>
#include <time.h>
static void _search_devs_for_pvids(struct cmd_context *cmd, struct dm_list *search_pvids, struct dm_list *found_devs)
{
@@ -119,18 +120,37 @@ static void _search_devs_for_pvids(struct cmd_context *cmd, struct dm_list *sear
}
}
static int _all_pvids_online(struct cmd_context *cmd, struct dm_list *wait_pvids)
{
struct device_id_list *dil, *dil2;
int notfound = 0;
dm_list_iterate_items_safe(dil, dil2, wait_pvids) {
if (online_pvid_file_exists(dil->pvid))
dm_list_del(&dil->list);
else
notfound++;
}
return notfound ? 0 : 1;
}
int lvmdevices(struct cmd_context *cmd, int argc, char **argv)
{
struct dm_list search_pvids;
struct dm_list wait_pvids;
struct dm_list found_devs;
struct device_id_list *dil;
struct device_list *devl;
struct device *dev;
struct dev_use *du, *du2;
const char *deviceidtype;
time_t begin;
int wait_sec;
int changes = 0;
dm_list_init(&search_pvids);
dm_list_init(&wait_pvids);
dm_list_init(&found_devs);
if (!setup_devices_file(cmd))
@@ -141,6 +161,9 @@ int lvmdevices(struct cmd_context *cmd, int argc, char **argv)
return ECMD_FAILED;
}
if (arg_is_set(cmd, wait_ARG))
cmd->print_device_id_not_found = 0;
if (arg_is_set(cmd, update_ARG) ||
arg_is_set(cmd, adddev_ARG) || arg_is_set(cmd, deldev_ARG) ||
arg_is_set(cmd, addpvid_ARG) || arg_is_set(cmd, delpvid_ARG)) {
@@ -176,6 +199,9 @@ int lvmdevices(struct cmd_context *cmd, int argc, char **argv)
log_error("Failed to read the devices file.");
return ECMD_FAILED;
}
prepare_open_file_limit(cmd, dm_list_size(&cmd->use_devices));
dev_cache_scan(cmd);
device_ids_match(cmd);
@@ -454,6 +480,62 @@ int lvmdevices(struct cmd_context *cmd, int argc, char **argv)
goto out;
}
if (arg_is_set(cmd, wait_ARG)) {
if (strcmp("pvsonline", arg_str_value(cmd, wait_ARG, ""))) {
log_error("wait option invalid.");
goto bad;
}
/* TODO: lvm.conf lvmdevices_wait_settings "disabled" do nothing */
/* TODO: lvm.conf auto_activation_settings "event_only" do nothing */
/* TODO: if no devices file exists, what should this do?
do a udev-settle? do nothing and cause more event-based activations? */
/* for each du, if du->wwid matched, wait for /run/lvm/pvs_online/du->pvid */
dm_list_iterate_items(du, &cmd->use_devices) {
if (!du->dev)
continue;
if (!(dil = dm_pool_zalloc(cmd->mem, sizeof(*dil))))
continue;
dil->dev = du->dev;
memcpy(dil->pvid, du->pvid, ID_LEN);
dm_list_add(&wait_pvids, &dil->list);
}
log_print("Waiting for PVs online for %u matched devices file entries.", dm_list_size(&wait_pvids));
wait_sec = find_config_tree_int(cmd, devices_lvmdevices_wait_seconds_CFG, 0);
begin = time(NULL);
while (1) {
if (_all_pvids_online(cmd, &wait_pvids)) {
log_print("Found all PVs online");
goto out;
}
log_print("Waiting for PVs online for %u devices.", dm_list_size(&wait_pvids));
/* TODO: lvm.conf lvmdevices_wait_ids "sys_wwid=111", "sys_wwid=222" etc
waits for the specifically named devices even if the devices do not exist. */
if (!wait_sec || (time(NULL) - begin >= wait_sec)) {
log_print("Time out waiting for PVs online:");
dm_list_iterate_items(dil, &wait_pvids)
log_print("Need PVID %s on %s", dil->pvid, dev_name(dil->dev));
break;
}
if (dm_list_size(&wait_pvids) > 10) {
if (interruptible_usleep(1000000)) /* 1 sec */
break;
} else {
if (interruptible_usleep(500000)) /* .5 sec */
break;
}
}
goto out;
}
/* If no options, print use_devices list */
dm_list_iterate_items(du, &cmd->use_devices) {

View File

@@ -21,7 +21,19 @@
#include <dirent.h>
int online_pvid_file_read(char *path, int *major, int *minor, char *vgname);
struct aa_settings {
/* from lvm.conf */
int event_activation;
int service_only;
int event_only;
int service_and_event;
int pvscan_hints;
/* from --autoactivation */
int opt_service;
int opt_event;
int opt_event_enable;
};
struct pvscan_params {
int new_pvs_found;
@@ -185,56 +197,52 @@ out:
/*
* Event based activation
* lvm.conf event_activation_options = "event_only"
* lvm.conf auto_activation_settings = "event_only"
* . all events are used for activation
* . no fixed services are used for activation
* . lvm.conf event_activation=1 required
*
* vgchange -aay --eventactivation service
* vgchange -aay --autoactivation service
* . does nothing
* vgchange -aay --eventactivation event
* vgchange -aay --autoactivation event
* . does activation
* pvscan --eventactivation event
* pvscan --autoactivation event
* . does activation
*
* ---
*
* Non-event based activation
* lvm.conf event_activation_options = "service_only"
* lvm.conf event_activaion=0 or
* lvm.conf event_activaion=1 and auto_activation_settings = "service_only"
* . fixed services are used for activation
* . no events are used for activation
* . lvm.conf event_activation=0 is equivalent to
* event_activation=1 event_activation_options="service_only"
*
* vgchange -aay --eventactivation service
* vgchange -aay --autoactivation service
* . does activation
* vgchange -aay --eventactivation event
* . does nothing
* pvscan --eventactivation event
* vgchange -aay --autoactivation event
* . does nothing
* pvscan --autoactivation event
* . does not trigger activation
* . may still create pvs_online for hints
*
* ---
*
* Mix of event and non-event based activation
* lvm.conf event_activation_options = "service_to_event"
* Mix of event and service based activation
* lvm.conf auto_activation_settings = "service_and_event"
* . both services and events are used for activation
* . fixed services are used for activation initially,
* and last service enables event based activation
* and the last service enables event based activation
* by creating the event-activation-on file
*
* vgchange -aay --eventactivation service
* vgchange -aay --autoactivation service
* . does activation only if event-activation-on does not exist
* vgchange -aay --eventactivation event
* vgchange -aay --autoactivation event
* . does activation only if event-activation-on exists
* vgchange -aay --eventactivation service,on
* vgchange -aay --autoactivation service,event_enable
* . does activation only if event-activation-on does not exist
* . creates event-activation-on to enable event-based activation
* vgchange --eventactivation on|off
* . create or remove event-activation-on to enable|disable
* event-based activation
* pvscan --eventactivation event
* . does activation only if event-activation-on exists
*
* pvscan --autoactivation event
* . triggers activation only if event-activation-on exists
*/
int event_activation_enable(struct cmd_context *cmd)
@@ -553,7 +561,7 @@ check_duplicate:
return 0;
}
static int _online_pvid_file_exists(const char *pvid)
int online_pvid_file_exists(const char *pvid)
{
char path[PATH_MAX] = { 0 };
struct stat buf;
@@ -639,7 +647,7 @@ static void _lookup_file_count_pvid_files(FILE *fp, const char *vgname, int *pvs
continue;
}
if (_online_pvid_file_exists((const char *)pvid))
if (online_pvid_file_exists((const char *)pvid))
(*pvs_online)++;
else
(*pvs_offline)++;
@@ -811,7 +819,7 @@ static void _count_pvid_files(struct volume_group *vg, int *pvs_online, int *pvs
dm_list_iterate_items(pvl, &vg->pvs) {
memcpy(pvid, &pvl->pv->id.uuid, ID_LEN);
if (_online_pvid_file_exists(pvid))
if (online_pvid_file_exists(pvid))
(*pvs_online)++;
else
(*pvs_offline)++;
@@ -1195,17 +1203,11 @@ static int _pvscan_aa(struct cmd_context *cmd, struct pvscan_aa_params *pp,
* PROCESS_SKIP_SCAN: we have already done lvmcache_label_scan
* so tell process_each to skip it.
*/
if (do_all)
read_flags |= PROCESS_SKIP_SCAN;
/*
* When the command is processing specific devs (not all), it
* has done setup_devices_no_file_match() to avoid matching ids
* fo all devs unnecessarily, but now that we're falling back
* to process_each_vg() we need to complete the id matching.
*/
if (!do_all)
device_ids_match(cmd);
lvmcache_label_scan(cmd);
read_flags |= PROCESS_SKIP_SCAN;
ret = process_each_vg(cmd, 0, NULL, NULL, vgnames, read_flags, 0, handle, _pvscan_aa_single);
}
@@ -1332,7 +1334,7 @@ static void _set_pv_devices_online(struct cmd_context *cmd, struct volume_group
continue;
}
if (!_online_pvid_file_exists(pvid)) {
if (!online_pvid_file_exists(pvid)) {
log_debug("set_pv_devices_online vg %s pv %s no online file",
vg->name, pvid);
pvl->pv->status |= MISSING_PV;
@@ -1372,7 +1374,7 @@ static void _set_pv_devices_online(struct cmd_context *cmd, struct volume_group
}
static int _online_devs(struct cmd_context *cmd, int do_all, struct dm_list *pvscan_devs,
int *pv_count, struct dm_list *complete_vgnames)
int *pv_count, struct dm_list *complete_vgnames, struct aa_settings *set)
{
struct device_list *devl, *devl2;
struct device *dev;
@@ -1454,7 +1456,7 @@ static int _online_devs(struct cmd_context *cmd, int do_all, struct dm_list *pvs
devsize = dev->size;
if (!devsize &&
!dev_get_size(dev, &devsize)) {
log_print("pvscan[%d] PV %s can get device size.", getpid(), dev_name(dev));
log_print_pvscan(cmd, "PV %s missing device size.", dev_name(dev));
release_vg(vg);
continue;
}
@@ -1528,6 +1530,20 @@ static int _online_devs(struct cmd_context *cmd, int do_all, struct dm_list *pvs
continue;
}
/*
* A fixed activation service will create event-activation-on
* after which this pvscan will do the steps to trigger
* event based activation. We get to this point because the
* fixed activation service uses pvscan_hints which requires
* this pvscan to create the pvs_online file. The online
* file has now been created so the command is done.
*/
if (set && set->service_and_event && !event_activation_is_on(cmd)) {
log_print_pvscan(cmd, "PV %s online before event activation.", dev_name(dev));
release_vg(vg);
continue;
}
/*
* Check if all the PVs for this VG are online. If the arrival
* of this dev completes the VG, then save the vgname in
@@ -1750,13 +1766,14 @@ static int _pvscan_cache_all(struct cmd_context *cmd, int argc, char **argv,
}
dev_iter_destroy(iter);
_online_devs(cmd, 1, &pvscan_devs, &pv_count, complete_vgnames);
_online_devs(cmd, 1, &pvscan_devs, &pv_count, complete_vgnames, NULL);
return 1;
}
static int _pvscan_cache_args(struct cmd_context *cmd, int argc, char **argv,
struct dm_list *complete_vgnames)
struct dm_list *complete_vgnames,
struct aa_settings *settings)
{
struct dm_list pvscan_args; /* struct pvscan_arg */
struct dm_list pvscan_devs; /* struct device_list */
@@ -1769,7 +1786,7 @@ static int _pvscan_cache_args(struct cmd_context *cmd, int argc, char **argv,
dm_list_init(&pvscan_args);
dm_list_init(&pvscan_devs);
cmd->pvscan_cache_single = 1;
cmd->expect_missing_vg_device = 1;
/*
* Special pvscan-specific setup steps to avoid looking
@@ -1892,7 +1909,7 @@ static int _pvscan_cache_args(struct cmd_context *cmd, int argc, char **argv,
int has_pvid;
if (!label_read_pvid(devl->dev, &has_pvid)) {
log_print("pvscan[%d] %s cannot read.", getpid(), dev_name(devl->dev));
log_print_pvscan(cmd, "%s cannot read label.", dev_name(devl->dev));
dm_list_del(&devl->list);
continue;
}
@@ -1942,7 +1959,7 @@ static int _pvscan_cache_args(struct cmd_context *cmd, int argc, char **argv,
*/
label_scan_devs_cached(cmd, NULL, &pvscan_devs);
ret = _online_devs(cmd, 0, &pvscan_devs, &pv_count, complete_vgnames);
ret = _online_devs(cmd, 0, &pvscan_devs, &pv_count, complete_vgnames, settings);
/*
* When a new PV appears, the system runs pvscan --cache dev.
@@ -1959,13 +1976,126 @@ static int _pvscan_cache_args(struct cmd_context *cmd, int argc, char **argv,
return ret;
}
/*
event_activation=1 service_and_event=1 pvscan_hints=1
services, then events
pvscan --cache creates pvs_online for all PVs
lvm-activate-vgs* used first
lvm-activate-<vgname> used later
vgchanges use hints=pvs_online from services and events
event_activation=1 event_only=1 pvscan_hints=1
only event activations
pvscan --cache creates pvs_online for all PVs
lvm-activate-vgs* skipped
lvm-activate-<vgname> used
vgchanges use hints=pvs_online from events
event_activation=1 service_only=1 pvscan_hints=1
only service activations
pvscan --cache creates pvs_online for all PVs
lvm-activate-vgs* used first
lvm-activate-<vgname> skipped
vgchanges use hints=pvs_online from services
(pvscan --cache could be skipped after services finish)
event_activation=1 service_and_event=1 pvscan_hints=0
services, then events
pvscan --cache skipped in service mode
pvscan --cache creates pvs_online in event mode
vgchange when enabling event mode must create pvs_online for existing PVs
lvm-activate-vgs* used first
lvm-activate-<vgname> used later
vgchanges scan all PVs from services and events
event_activation=1 event_only=1 pvscan_hints=0
only event activations
pvscan --cache creates pvs_online for all PVs
lvm-activate-vgs* skipped
lvm-activate-<vgname> used
vgchanges scan all PVs from events
event_activation=1 service_only=1 pvscan_hints=0
only service activations
pvscan --cache always skipped
lvm-activate-vgs* used first
lvm-activate-<vgname> skipped
vgchanges scan all PVs from services
event_activation=0
only service activations
ignores service_and_events=1 or events_only=1
. for pvscan_hints=1
pvscan --cache creates pvs_online for all PVs
lvm-activate-vgs* used first
lvm-activate-<vgname> skipped
vgchanges use hints=pvs_online from services
(pvscan --cache could be skipped after services finish)
. for pvscan_hints=0
pvscan --cache always skipped
lvm-activate-vgs* used first
lvm-activate-<vgname> skipped
vgchanges scan all PVs from services
*/
static int _get_autoactivation(struct cmd_context *cmd,
struct aa_settings *set,
int *skip_command)
{
const char *aa_str;
/*
* The lvm.conf settings only apply when the command uses --autoactivation
* which says if the command is used for event or service activation.
*/
if (!(aa_str = arg_str_value(cmd, autoactivation_ARG, NULL)))
return 1;
if (!get_autoactivation_config_settings(cmd, &set->service_only, &set->event_only, &set->service_and_event, &set->pvscan_hints))
return 0;
if (!get_autoactivation_command_options(cmd, aa_str, &set->opt_service, &set->opt_event, &set->opt_event_enable))
return 0;
if (!set->opt_event) {
log_print_pvscan(cmd, "Skip pvscan without autoactivation=event.");
*skip_command = 1;
return 1;
}
if (!set->event_activation && !set->pvscan_hints) {
log_print_pvscan(cmd, "Skip pvscan with event_activation=0.");
*skip_command = 1;
return 1;
}
if (set->service_only && !set->pvscan_hints) {
log_print_pvscan(cmd, "Skip pvscan with service_only.");
*skip_command = 1;
return 1;
}
if (set->service_and_event && !set->pvscan_hints && !event_activation_is_on(cmd)) {
/*
* Note that when vgchange enables events, it needs to compensate for this
* skipped pvscan by creating pvs_online files for all existing PVs.
*/
log_print_pvscan(cmd, "Skip pvscan without event-activation-on.");
*skip_command = 1;
return 1;
}
return 1;
}
int pvscan_cache_cmd(struct cmd_context *cmd, int argc, char **argv)
{
struct pvscan_aa_params pp = { 0 };
struct dm_list complete_vgnames;
const char *ea;
struct aa_settings settings = { 0 };
int do_activate = arg_is_set(cmd, activate_ARG);
int event_activation;
int skip_command = 0;
int devno_args = 0;
int do_all;
int ret;
@@ -1979,6 +2109,7 @@ int pvscan_cache_cmd(struct cmd_context *cmd, int argc, char **argv)
cmd->ignore_device_name_mismatch = 1;
event_activation = find_config_tree_bool(cmd, global_event_activation_CFG, NULL);
settings.event_activation = event_activation;
if (do_activate && !event_activation) {
log_verbose("Ignoring pvscan --cache -aay because event_activation is disabled.");
@@ -2038,36 +2169,13 @@ int pvscan_cache_cmd(struct cmd_context *cmd, int argc, char **argv)
return ECMD_PROCESSED;
}
if (!_get_autoactivation(cmd, &settings, &skip_command))
return_ECMD_FAILED;
if ((ea = arg_str_value(cmd, eventactivation_ARG, NULL))) {
int service_only = 0, event_only = 0, service_to_event = 0;
int ea_service = 0, ea_event = 0, ea_on = 0;
if (skip_command)
return ECMD_PROCESSED;
if (!get_event_activation_config_settings(cmd, &service_only, &event_only, &service_to_event))
return ECMD_FAILED;
if (!get_event_activation_command_options(cmd, ea, &ea_service, &ea_event, &ea_on))
return ECMD_FAILED;
if (ea_event) {
if (!event_activation) {
log_print("Skip pvscan for event and event_activation=0.");
return ECMD_PROCESSED;
}
if (service_only) {
log_print("Skip pvscan for event and event_activation_options service_only.");
return ECMD_PROCESSED;
}
if (service_to_event && !event_activation_is_on(cmd)) {
log_print("Skip pvscan for event and no event-activation-on.");
return ECMD_PROCESSED;
}
} else {
log_error("Option --eventactivation %s is not used by pvscan.", ea);
return ECMD_FAILED;
}
}
if (!_pvscan_cache_args(cmd, argc, argv, &complete_vgnames))
if (!_pvscan_cache_args(cmd, argc, argv, &complete_vgnames, &settings))
return ECMD_FAILED;
}

View File

@@ -5715,14 +5715,14 @@ out:
return 0;
}
int get_event_activation_config_settings(struct cmd_context *cmd,
int *service_only, int *event_only, int *service_to_event)
int get_autoactivation_config_settings(struct cmd_context *cmd,
int *service_only, int *event_only, int *service_and_event, int *pvscan_hints)
{
const struct dm_config_node *cn;
const struct dm_config_value *cv;
int eo = 0, so = 0, se = 0;
int eo = 0, so = 0, se = 0, ph = 0;
if (!(cn = find_config_tree_array(cmd, global_event_activation_options_CFG, NULL)))
if (!(cn = find_config_tree_array(cmd, activation_auto_activation_settings_CFG, NULL)))
return 1;
for (cv = cn->v; cv; cv = cv->next) {
@@ -5732,69 +5732,75 @@ int get_event_activation_config_settings(struct cmd_context *cmd,
so = 1;
else if (!strcmp(cv->v.str, "event_only"))
eo = 1;
else if (!strcmp(cv->v.str, "service_to_event"))
else if (!strcmp(cv->v.str, "service_and_event"))
se = 1;
else if (!strcmp(cv->v.str, "pvscan_hints"))
ph = 1;
else if (strlen(cv->v.str) > 0)
log_warn("WARNING: ignoring unrecognized event_activation_options value %s.", cv->v.str);
log_warn("WARNING: ignoring unrecognized autoactivation_settings value %s.", cv->v.str);
}
if (se && (so || eo)) {
log_warn("WARNING: ignoring incompatible event_activation_options, using service_to_event.");
*service_to_event = 1;
log_warn("WARNING: ignoring incompatible autoactivation_settings, using service_and_event.");
*service_and_event = 1;
} else if (so && eo) {
log_warn("WARNING: ignoring incompatible event_activation_options, using event_only.");
log_warn("WARNING: ignoring incompatible autoactivation_settings, using event_only.");
*event_only = 1;
} else if (se) {
*service_to_event = 1;
*service_and_event = 1;
} else if (so) {
*service_only = 1;
} else if (eo) {
*event_only = 1;
} else {
*service_to_event = 1;
*service_and_event = 1;
}
if (ph)
*pvscan_hints = 1;
return 1;
}
static int _ea_option_value(const char *val, int *ea_service, int *ea_event, int *ea_on)
static int _aa_option_value(const char *val, int *opt_service, int *opt_event, int *opt_event_enable)
{
if (!strcmp(val, "service"))
*ea_service = 1;
*opt_service = 1;
else if (!strcmp(val, "event"))
*ea_event = 1;
else if (!strcmp(val, "on"))
*ea_on = 1;
*opt_event = 1;
else if (!strcmp(val, "event_enable"))
*opt_event_enable = 1;
else {
log_error("Unknown --eventactivation value.");
log_error("Unknown --autoactivation value.");
return 0;
}
return 1;
}
int get_event_activation_command_options(struct cmd_context *cmd, const char *ea, int *ea_service, int *ea_event, int *ea_on)
int get_autoactivation_command_options(struct cmd_context *cmd, const char *aa, int *opt_service, int *opt_event, int *opt_event_enable)
{
char ea_vals[128] = {0};
char vals[128] = { 0 };
char *val1, *val2;
strncpy(ea_vals, ea, 127);
strncpy(vals, aa, 127);
/* Currently only two values can be used together. */
/* Currently only two values can be used at once. */
val1 = ea_vals;
val1 = vals;
if ((val2 = strchr(ea_vals, ','))) {
if ((val2 = strchr(vals, ','))) {
*val2 = '\0';
val2++;
}
if (val1 && !_ea_option_value(val1, ea_service, ea_event, ea_on))
if (val1 && !_aa_option_value(val1, opt_service, opt_event, opt_event_enable))
return 0;
if (val2 && !_ea_option_value(val2, ea_service, ea_event, ea_on))
if (val2 && !_aa_option_value(val2, opt_service, opt_event, opt_event_enable))
return 0;
if (*ea_service && *ea_event) {
log_error("Invalid --eventactivation options, service and event are incompatible.");
if (*opt_service && *opt_event) {
log_error("Invalid --autoactivation options, service and event are incompatible.");
return 0;
}

View File

@@ -237,9 +237,9 @@ int lvremove_single(struct cmd_context *cmd, struct logical_volume *lv,
int get_lvt_enum(struct logical_volume *lv);
int get_event_activation_config_settings(struct cmd_context *cmd,
int *service_only, int *event_only, int *service_to_event);
int get_event_activation_command_options(struct cmd_context *cmd,
const char *ea, int *ea_service, int *ea_event, int *ea_on);
int get_autoactivation_config_settings(struct cmd_context *cmd, int *service_only,
int *event_only, int *service_and_event, int *pvscan_hints);
int get_autoactivation_command_options(struct cmd_context *cmd, const char *aa,
int *opt_service, int *opt_event, int *opt_event_enable);
#endif

View File

@@ -294,8 +294,10 @@ int lvconvert_cachevol_attach_single(struct cmd_context *cmd,
struct logical_volume *lv,
struct processing_handle *handle);
int online_pvid_file_read(char *path, int *major, int *minor, char *vgname);
int online_pvid_file_create(struct cmd_context *cmd, struct device *dev, const char *vgname, int ignore_existing, int *exists);
void online_vg_file_remove(const char *vgname);
int online_pvid_file_exists(const char *pvid);
int online_vg_file_create(struct cmd_context *cmd, const char *vgname);
void online_dir_setup(struct cmd_context *cmd);
int event_activation_enable(struct cmd_context *cmd);

View File

@@ -256,11 +256,6 @@ int vgchange_activate(struct cmd_context *cmd, struct volume_group *vg,
return 1;
}
if (arg_is_set(cmd, vgonline_ARG) && !online_vg_file_create(cmd, vg->name)) {
log_print("VG %s already online", vg->name);
return 1;
}
if (do_activate && vg_complete_to_activate) {
dm_list_iterate_items(pvl, &vg->pvs) {
if (!pvl->pv->dev) {
@@ -270,6 +265,11 @@ int vgchange_activate(struct cmd_context *cmd, struct volume_group *vg,
}
}
if (arg_is_set(cmd, vgonline_ARG) && !online_vg_file_create(cmd, vg->name)) {
log_print("VG %s already online", vg->name);
return 1;
}
/*
* Safe, since we never write out new metadata here. Required for
* partial activation to work.
@@ -777,61 +777,62 @@ static int _vgchange_single(struct cmd_context *cmd, const char *vg_name,
return ret;
}
static int _check_event_activation(struct cmd_context *cmd, struct vgchange_params *vp, int *skip_command, int *enable_events)
static int _check_autoactivation(struct cmd_context *cmd, struct vgchange_params *vp, int *skip_command, int *enable_events,
int *create_pvs_online)
{
const char *ea;
int service_only = 0, event_only = 0, service_to_event = 0;
int ea_service = 0, ea_event = 0, ea_on = 0;
const char *aa;
int service_only = 0, event_only = 0, service_and_event = 0, pvscan_hints = 0;
int opt_service = 0, opt_event = 0, opt_event_enable = 0;
int on_file_exists;
int event_activation;
if (!(ea = arg_str_value(cmd, eventactivation_ARG, NULL))) {
log_error("No eventactivation value.");
if (!(aa = arg_str_value(cmd, autoactivation_ARG, NULL))) {
log_error("No autoactivation value.");
return 0;
}
/* lvm.conf event_activation_options */
if (!get_event_activation_config_settings(cmd, &service_only, &event_only, &service_to_event))
/* lvm.conf auto_activation_settings */
if (!get_autoactivation_config_settings(cmd, &service_only, &event_only, &service_and_event, &pvscan_hints))
return_0;
/* --eventactivation values */
if (!get_event_activation_command_options(cmd, ea, &ea_service, &ea_event, &ea_on))
/* --autoactivation values */
if (!get_autoactivation_command_options(cmd, aa, &opt_service, &opt_event, &opt_event_enable))
return_0;
event_activation = find_config_tree_bool(cmd, global_event_activation_CFG, NULL);
/*
* The combination of lvm.conf event_activation/event_activation_options
* and the --eventactivation service|event value determines if this
* The combination of lvm.conf event_activation/auto_activation_settings
* and the --autoactivation service|event value determines if this
* command should do anything or be skipped, along with the existence of
* the /run/lvm/event-activation-on file in case of service_to_event.
* the /run/lvm/event-activation-on file in case of service_and_event.
*/
if (!event_activation) {
if (ea_event) {
if (opt_event) {
log_print("Skip vgchange for event and event_activation=0.");
*skip_command = 1;
return 1;
}
} else {
if (event_only && ea_service) {
log_print("Skip vgchange for service and event_activation_options event_only.");
if (event_only && opt_service) {
log_print("Skip vgchange for service and autoactivation_settings event_only.");
*skip_command = 1;
return 1;
}
if (service_only && ea_event) {
log_print("Skip vgchange for event and event_activation_options service_only.");
if (service_only && opt_event) {
log_print("Skip vgchange for event and autoactivation_settings service_only.");
*skip_command = 1;
return 1;
}
on_file_exists = event_activation_is_on(cmd);
if (service_to_event && ea_service && on_file_exists) {
if (service_and_event && opt_service && on_file_exists) {
log_print("Skip vgchange for service and event-activation-on.");
*skip_command = 1;
return 1;
}
if (service_to_event && ea_event && !on_file_exists) {
if (service_and_event && opt_event && !on_file_exists) {
log_print("Skip vgchange for event and no event-activation-on.");
*skip_command = 1;
return 1;
@@ -841,43 +842,61 @@ static int _check_event_activation(struct cmd_context *cmd, struct vgchange_para
/*
* Switch from service activation to event activation when:
* lvm.conf event_activation=1,
* event_activation_options=service_to_event,
* and --eventactivation service,on.
* auto_activation_settings=service_and_event,
* and --autoactivation service,event_enable
*
* When enabling event-based activation, first create the
* /run/lvm/event-activation-on file to tell other commands
* to begin responding to PV events and doing activation
* for newly completed VGs. It also needs to create online
* files for existing PVs because some VGs may be incomplete
* at this point, and future pvscan commands need to
* find online files for PVs that have already appeared.
* The label scan provides info to know which PVs are
* present and should have pvid online files created.
* for newly completed VGs.
*
* process_each_vg() usually begins with lock_global() and
* lvmcache_label_scan(), and then processes each VG.
* In this case, lock_global/lvmcache_label_scan are done
* before calling process_each_vg. This allows a special
* step to be inserted between the label scan and processing
* vgs. That step creates the pvid online files, which
* requires label scan info. The lock_global and
* lvmcache_label_scan will be skipped by process_each_vg
* since they are already done here.
* When no pvscan_hints are used, pvscan --cache has not been
* creating pvs_online files during service mode, so now
* we need to create pvs_online files for all existing PVs
* to make up for that.
*/
if (event_activation && service_to_event && ea_service && ea_on) {
if (event_activation && service_and_event && opt_service && opt_event_enable) {
if (!event_activation_enable(cmd))
log_warn("WARNING: Failed to create event-activation-on.");
*enable_events = 1;
if (!pvscan_hints)
*create_pvs_online = 1;
}
/*
* lvm.conf service_to_event, and vgchange -aay --eventactivation service,
* lvm.conf service_and_event, and vgchange -aay --autoactivation service,
* then only activate LVs if the VG is complete.
* A later event will complete the VG and activate it.
*/
if (event_activation && service_to_event && ea_service)
if (event_activation && service_and_event && opt_service)
vp->vg_complete_to_activate = 1;
/*
* vgchange -aay --autoactivation service, and lvm.conf
* autoactivation_settings with pvscan_hints means the vgchange
* should use the special hints=pvs_online.
* Otherwise, the vgchange uses the equivalent of --nohints.
* If --nohints is on the vgchange command line, that overrides
* and disables autoactivation_settings pvscan_hints.
* hints=pvs_online means the command will only use devices that
* have been processed by pvscan --cache (which have a pvid file
* created under /run/lvm/pvs_online.)
*/
if (!arg_is_set(cmd, nohints_ARG) && pvscan_hints)
cmd->hints_pvs_online = 1;
else
cmd->use_hints = 0;
/*
* An activation service will just run "vgchange -aay" and activate
* whichever VGs it finds are complete. It's expected that some
* VGs may not yet be complete and will be activated later when
* more PVs appear, so don't print warnings.
*/
if (opt_service)
cmd->expect_missing_vg_device = 1;
return 1;
}
@@ -997,21 +1016,23 @@ int vgchange(struct cmd_context *cmd, int argc, char **argv)
cmd->lockd_vg_enforce_sh = 1;
}
if (arg_is_set(cmd, eventactivation_ARG)) {
int skip_command = 0, enable_events = 0;
if (!_check_event_activation(cmd, &vp, &skip_command, &enable_events))
if (arg_is_set(cmd, autoactivation_ARG)) {
int skip_command = 0, enable_events = 0, create_pvs_online = 0;
if (!_check_autoactivation(cmd, &vp, &skip_command, &enable_events, &create_pvs_online))
return ECMD_FAILED;
if (skip_command)
return ECMD_PROCESSED;
if (enable_events) {
if (!event_activation_enable(cmd))
log_warn("WARNING: Failed to create event-activation-on.");
/* The process_each_vg lock_global/lvmcache_label_scan will be skipped. */
if (!lock_global(cmd, "sh"))
return ECMD_FAILED;
lvmcache_label_scan(cmd);
_online_pvid_file_create_all(cmd);
flags |= PROCESS_SKIP_SCAN;
if (create_pvs_online) {
/* The process_each_vg lock_global/lvmcache_label_scan will be skipped. */
if (!lock_global(cmd, "sh"))
return ECMD_FAILED;
lvmcache_label_scan(cmd);
_online_pvid_file_create_all(cmd);
flags |= PROCESS_SKIP_SCAN;
}
}
}

View File

@@ -172,6 +172,17 @@ int vgimportdevices(struct cmd_context *cmd, int argc, char **argv)
cmd->filter_regex_with_devices_file = 1;
cmd->create_edit_devices_file = 1;
/*
* This helps a user bootstrap existing shared VGs into the devices
* file. Reading the vg to import devices requires locking, but
* lockstart won't find the vg before it's in the devices file.
* So, allow importing devices without an lvmlockd lock (in a
* a shared vg the vg metadata won't be updated with device ids,
* so the lvmlockd lock isn't protecting vg modification.)
*/
cmd->lockd_gl_disable = 1;
cmd->lockd_vg_disable = 1;
/*
* For each VG:
* device_id_add() each PV in the VG

View File

@@ -121,6 +121,6 @@ LABEL="direct_pvscan"
# MD | | X | X* | |
# loop | | X | X* | |
# other | X | | X | | X
RUN+="(LVM_EXEC)/lvm pvscan --cache -aay --eventactivation event --major $major --minor $minor", ENV{LVM_SCANNED}="1"
RUN+="(LVM_EXEC)/lvm pvscan --cache -aay --autoactivation event --major $major --minor $minor", ENV{LVM_SCANNED}="1"
LABEL="lvm_end"

View File

@@ -79,18 +79,11 @@ ENV{SYSTEMD_READY}="1"
# TODO: adjust the output of vgchange -aay so that
# it's better suited to appearing in the journal.
#
# "--eventactivation event" used with pvscan or vgchange
# "--autoactivation event" used with pvscan or vgchange
# tells the command that it is being run from an event.
# The command does nothing if lvm.conf event_activation=0.
# The command does nothing if lvm.conf event_activation=1,
# and lvm.conf event_activation_options="service_only".
# The command goes ahead if event_activation_options="event_only",
# or if event_activation_options="service_to_event" and the
# event-activation-on file exists.
#
IMPORT{program}="(LVM_EXEC)/lvm pvscan --cache --listvg --checkcomplete --vgonline --eventactivation event --udevoutput --journal=output $env{DEVNAME}"
ENV{LVM_VG_NAME_COMPLETE}=="?*", RUN+="/usr/bin/systemd-run -r --no-block --property DefaultDependencies=no --unit lvm-activate-$env{LVM_VG_NAME_COMPLETE} lvm vgchange -aay --config devices/hints=pvs_online --eventactivation event $env{LVM_VG_NAME_COMPLETE}"
IMPORT{program}="(LVM_EXEC)/lvm pvscan --cache --listvg --checkcomplete --vgonline --autoactivation event --udevoutput --journal=output $env{DEVNAME}"
ENV{LVM_VG_NAME_COMPLETE}=="?*", RUN+="/usr/bin/systemd-run -r --no-block --property DefaultDependencies=no --unit lvm-activate-$env{LVM_VG_NAME_COMPLETE} (LVM_EXEC)/lvm vgchange -aay --autoactivation event $env{LVM_VG_NAME_COMPLETE}"
GOTO="lvm_end"
LABEL="lvm_end"