mirror of
git://sourceware.org/git/lvm2.git
synced 2024-12-21 13:34:40 +03:00
lvmpolld: Add standalone polldaemon.
See doc/lvmpolld_overview.txt
This commit is contained in:
parent
be23fae488
commit
e587b0677b
@ -1,5 +1,7 @@
|
|||||||
Version 2.02.120 -
|
Version 2.02.120 -
|
||||||
===============================
|
===============================
|
||||||
|
Add lvpoll for cmdline communication with lvmpolld.
|
||||||
|
Add lvmpolld acting as a free-standing version of polldaemon.
|
||||||
Properly validate PV size for pvcreate --restorefile.
|
Properly validate PV size for pvcreate --restorefile.
|
||||||
Fix check if pvcreate wiped device (2.02.117).
|
Fix check if pvcreate wiped device (2.02.117).
|
||||||
Fix storing of vgid when caching metadata (2.02.118).
|
Fix storing of vgid when caching metadata (2.02.118).
|
||||||
|
@ -938,6 +938,16 @@ global {
|
|||||||
# Comments starting with the character # are ignored.
|
# Comments starting with the character # are ignored.
|
||||||
# This configuration option does not have a default value defined.
|
# This configuration option does not have a default value defined.
|
||||||
# system_id_file = ""
|
# system_id_file = ""
|
||||||
|
|
||||||
|
# Indicates whether to use lvmpolld instead of classical polldaemon (a process
|
||||||
|
# forked off an initiating lvm command) or not. When set to 1 and native systemd
|
||||||
|
# service is installed in the system lvm starts using lvmpolld. lvmpolld gets
|
||||||
|
# auto-activated by systemd when a message lands on the respective lvmpolld socket.
|
||||||
|
# All commands that would require polling of in-progress operation are therefore
|
||||||
|
# spawned in lvmpolld's service cgroup.
|
||||||
|
#
|
||||||
|
# When set to 0 lvm falls back to classical polling.
|
||||||
|
use_lvmpolld = 0
|
||||||
}
|
}
|
||||||
|
|
||||||
# Configuration section activation.
|
# Configuration section activation.
|
||||||
|
49
configure
vendored
49
configure
vendored
@ -636,6 +636,7 @@ kerneldir
|
|||||||
interface
|
interface
|
||||||
CMIRRORD_PIDFILE
|
CMIRRORD_PIDFILE
|
||||||
CLVMD_PIDFILE
|
CLVMD_PIDFILE
|
||||||
|
LVMPOLLD_PIDFILE
|
||||||
LVMETAD_PIDFILE
|
LVMETAD_PIDFILE
|
||||||
DMEVENTD_PIDFILE
|
DMEVENTD_PIDFILE
|
||||||
WRITE_INSTALL
|
WRITE_INSTALL
|
||||||
@ -724,6 +725,7 @@ CLDWHOLEARCHIVE
|
|||||||
CLDNOWHOLEARCHIVE
|
CLDNOWHOLEARCHIVE
|
||||||
CLDFLAGS
|
CLDFLAGS
|
||||||
CACHE
|
CACHE
|
||||||
|
BUILD_LVMPOLLD
|
||||||
BUILD_LVMETAD
|
BUILD_LVMETAD
|
||||||
BUILD_DMEVENTD
|
BUILD_DMEVENTD
|
||||||
BUILD_CMIRRORD
|
BUILD_CMIRRORD
|
||||||
@ -914,6 +916,8 @@ enable_valgrind_pool
|
|||||||
enable_devmapper
|
enable_devmapper
|
||||||
enable_lvmetad
|
enable_lvmetad
|
||||||
with_lvmetad_pidfile
|
with_lvmetad_pidfile
|
||||||
|
enable_lvmpolld
|
||||||
|
with_lvmpolld_pidfile
|
||||||
enable_blkid_wiping
|
enable_blkid_wiping
|
||||||
enable_udev_systemd_background_jobs
|
enable_udev_systemd_background_jobs
|
||||||
enable_udev_sync
|
enable_udev_sync
|
||||||
@ -1627,6 +1631,7 @@ Optional Features:
|
|||||||
--enable-valgrind-pool enable valgrind awareness of pools
|
--enable-valgrind-pool enable valgrind awareness of pools
|
||||||
--disable-devmapper disable LVM2 device-mapper interaction
|
--disable-devmapper disable LVM2 device-mapper interaction
|
||||||
--enable-lvmetad enable the LVM Metadata Daemon
|
--enable-lvmetad enable the LVM Metadata Daemon
|
||||||
|
--enable-lvmpolld enable the LVM Polling Daemon
|
||||||
--disable-blkid_wiping disable libblkid detection of signatures when wiping
|
--disable-blkid_wiping disable libblkid detection of signatures when wiping
|
||||||
and use native code instead
|
and use native code instead
|
||||||
--disable-udev-systemd-background-jobs
|
--disable-udev-systemd-background-jobs
|
||||||
@ -1718,6 +1723,8 @@ Optional Packages:
|
|||||||
--with-optimisation=OPT C optimisation flag [OPT=-O2]
|
--with-optimisation=OPT C optimisation flag [OPT=-O2]
|
||||||
--with-lvmetad-pidfile=PATH
|
--with-lvmetad-pidfile=PATH
|
||||||
lvmetad pidfile [PID_DIR/lvmetad.pid]
|
lvmetad pidfile [PID_DIR/lvmetad.pid]
|
||||||
|
--with-lvmpolld-pidfile=PATH
|
||||||
|
lvmpolld pidfile [PID_DIR/lvmpolld.pid]
|
||||||
--with-localedir=DIR translation files in DIR [PREFIX/share/locale]
|
--with-localedir=DIR translation files in DIR [PREFIX/share/locale]
|
||||||
--with-confdir=DIR configuration files in DIR [/etc]
|
--with-confdir=DIR configuration files in DIR [/etc]
|
||||||
--with-staticdir=DIR static binaries in DIR [EPREFIX/sbin]
|
--with-staticdir=DIR static binaries in DIR [EPREFIX/sbin]
|
||||||
@ -3033,6 +3040,7 @@ case "$host_os" in
|
|||||||
LIB_SUFFIX=so
|
LIB_SUFFIX=so
|
||||||
DEVMAPPER=yes
|
DEVMAPPER=yes
|
||||||
LVMETAD=no
|
LVMETAD=no
|
||||||
|
LVMPOLLD=no
|
||||||
ODIRECT=yes
|
ODIRECT=yes
|
||||||
DM_IOCTLS=yes
|
DM_IOCTLS=yes
|
||||||
SELINUX=yes
|
SELINUX=yes
|
||||||
@ -10855,6 +10863,39 @@ _ACEOF
|
|||||||
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
################################################################################
|
||||||
|
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to build lvmpolld" >&5
|
||||||
|
$as_echo_n "checking whether to build lvmpolld... " >&6; }
|
||||||
|
# Check whether --enable-lvmpolld was given.
|
||||||
|
if test "${enable_lvmpolld+set}" = set; then :
|
||||||
|
enableval=$enable_lvmpolld; LVMPOLLD=$enableval
|
||||||
|
fi
|
||||||
|
|
||||||
|
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $LVMPOLLD" >&5
|
||||||
|
$as_echo "$LVMPOLLD" >&6; }
|
||||||
|
|
||||||
|
BUILD_LVMPOLLD=$LVMPOLLD
|
||||||
|
|
||||||
|
if test "$BUILD_LVMPOLLD" = yes; then
|
||||||
|
|
||||||
|
$as_echo "#define LVMPOLLD_SUPPORT 1" >>confdefs.h
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# Check whether --with-lvmpolld-pidfile was given.
|
||||||
|
if test "${with_lvmpolld_pidfile+set}" = set; then :
|
||||||
|
withval=$with_lvmpolld_pidfile; LVMPOLLD_PIDFILE=$withval
|
||||||
|
else
|
||||||
|
LVMPOLLD_PIDFILE="$DEFAULT_PID_DIR/lvmpolld.pid"
|
||||||
|
fi
|
||||||
|
|
||||||
|
|
||||||
|
cat >>confdefs.h <<_ACEOF
|
||||||
|
#define LVMPOLLD_PIDFILE "$LVMPOLLD_PIDFILE"
|
||||||
|
_ACEOF
|
||||||
|
|
||||||
|
fi
|
||||||
|
|
||||||
################################################################################
|
################################################################################
|
||||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to enable libblkid detection of signatures when wiping" >&5
|
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to enable libblkid detection of signatures when wiping" >&5
|
||||||
$as_echo_n "checking whether to enable libblkid detection of signatures when wiping... " >&6; }
|
$as_echo_n "checking whether to enable libblkid detection of signatures when wiping... " >&6; }
|
||||||
@ -13144,11 +13185,13 @@ LVM_LIBAPI=`echo "$VER" | $AWK -F '[()]' '{print $2}'`
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
################################################################################
|
################################################################################
|
||||||
ac_config_files="$ac_config_files Makefile make.tmpl daemons/Makefile daemons/clvmd/Makefile daemons/cmirrord/Makefile daemons/dmeventd/Makefile daemons/dmeventd/libdevmapper-event.pc daemons/dmeventd/plugins/Makefile daemons/dmeventd/plugins/lvm2/Makefile daemons/dmeventd/plugins/raid/Makefile daemons/dmeventd/plugins/mirror/Makefile daemons/dmeventd/plugins/snapshot/Makefile daemons/dmeventd/plugins/thin/Makefile daemons/lvmetad/Makefile conf/Makefile conf/example.conf conf/lvmlocal.conf conf/command_profile_template.profile conf/metadata_profile_template.profile include/.symlinks include/Makefile lib/Makefile lib/format1/Makefile lib/format_pool/Makefile lib/locking/Makefile lib/mirror/Makefile lib/replicator/Makefile lib/misc/lvm-version.h lib/raid/Makefile lib/snapshot/Makefile lib/thin/Makefile lib/cache_segtype/Makefile libdaemon/Makefile libdaemon/client/Makefile libdaemon/server/Makefile libdm/Makefile libdm/libdevmapper.pc liblvm/Makefile liblvm/liblvm2app.pc man/Makefile po/Makefile python/Makefile python/setup.py scripts/blkdeactivate.sh scripts/blk_availability_init_red_hat scripts/blk_availability_systemd_red_hat.service scripts/clvmd_init_red_hat scripts/cmirrord_init_red_hat scripts/dm_event_systemd_red_hat.service scripts/dm_event_systemd_red_hat.socket scripts/lvm2_cluster_activation_red_hat.sh scripts/lvm2_cluster_activation_systemd_red_hat.service scripts/lvm2_clvmd_systemd_red_hat.service scripts/lvm2_cmirrord_systemd_red_hat.service scripts/lvm2_lvmetad_init_red_hat scripts/lvm2_lvmetad_systemd_red_hat.service scripts/lvm2_lvmetad_systemd_red_hat.socket scripts/lvm2_monitoring_init_red_hat scripts/lvm2_monitoring_systemd_red_hat.service scripts/lvm2_pvscan_systemd_red_hat@.service scripts/lvm2_tmpfiles_red_hat.conf scripts/Makefile test/Makefile test/api/Makefile test/unit/Makefile tools/Makefile udev/Makefile unit-tests/datastruct/Makefile unit-tests/regex/Makefile unit-tests/mm/Makefile"
|
ac_config_files="$ac_config_files Makefile make.tmpl daemons/Makefile daemons/clvmd/Makefile daemons/cmirrord/Makefile daemons/dmeventd/Makefile daemons/dmeventd/libdevmapper-event.pc daemons/dmeventd/plugins/Makefile daemons/dmeventd/plugins/lvm2/Makefile daemons/dmeventd/plugins/raid/Makefile daemons/dmeventd/plugins/mirror/Makefile daemons/dmeventd/plugins/snapshot/Makefile daemons/dmeventd/plugins/thin/Makefile daemons/lvmetad/Makefile daemons/lvmpolld/Makefile conf/Makefile conf/example.conf conf/lvmlocal.conf conf/command_profile_template.profile conf/metadata_profile_template.profile include/.symlinks include/Makefile lib/Makefile lib/format1/Makefile lib/format_pool/Makefile lib/locking/Makefile lib/mirror/Makefile lib/replicator/Makefile lib/misc/lvm-version.h lib/raid/Makefile lib/snapshot/Makefile lib/thin/Makefile lib/cache_segtype/Makefile libdaemon/Makefile libdaemon/client/Makefile libdaemon/server/Makefile libdm/Makefile libdm/libdevmapper.pc liblvm/Makefile liblvm/liblvm2app.pc man/Makefile po/Makefile python/Makefile python/setup.py scripts/blkdeactivate.sh scripts/blk_availability_init_red_hat scripts/blk_availability_systemd_red_hat.service scripts/clvmd_init_red_hat scripts/cmirrord_init_red_hat scripts/dm_event_systemd_red_hat.service scripts/dm_event_systemd_red_hat.socket scripts/lvm2_cluster_activation_red_hat.sh scripts/lvm2_cluster_activation_systemd_red_hat.service scripts/lvm2_clvmd_systemd_red_hat.service scripts/lvm2_cmirrord_systemd_red_hat.service scripts/lvm2_lvmetad_init_red_hat scripts/lvm2_lvmetad_systemd_red_hat.service scripts/lvm2_lvmetad_systemd_red_hat.socket scripts/lvm2_lvmpolld_init_red_hat scripts/lvm2_lvmpolld_systemd_red_hat.service scripts/lvm2_lvmpolld_systemd_red_hat.socket scripts/lvm2_monitoring_init_red_hat scripts/lvm2_monitoring_systemd_red_hat.service scripts/lvm2_pvscan_systemd_red_hat@.service scripts/lvm2_tmpfiles_red_hat.conf scripts/Makefile test/Makefile test/api/Makefile test/unit/Makefile tools/Makefile udev/Makefile unit-tests/datastruct/Makefile unit-tests/regex/Makefile unit-tests/mm/Makefile"
|
||||||
|
|
||||||
cat >confcache <<\_ACEOF
|
cat >confcache <<\_ACEOF
|
||||||
# This file is a shell script that caches the results of configure
|
# This file is a shell script that caches the results of configure
|
||||||
@ -13857,6 +13900,7 @@ do
|
|||||||
"daemons/dmeventd/plugins/snapshot/Makefile") CONFIG_FILES="$CONFIG_FILES daemons/dmeventd/plugins/snapshot/Makefile" ;;
|
"daemons/dmeventd/plugins/snapshot/Makefile") CONFIG_FILES="$CONFIG_FILES daemons/dmeventd/plugins/snapshot/Makefile" ;;
|
||||||
"daemons/dmeventd/plugins/thin/Makefile") CONFIG_FILES="$CONFIG_FILES daemons/dmeventd/plugins/thin/Makefile" ;;
|
"daemons/dmeventd/plugins/thin/Makefile") CONFIG_FILES="$CONFIG_FILES daemons/dmeventd/plugins/thin/Makefile" ;;
|
||||||
"daemons/lvmetad/Makefile") CONFIG_FILES="$CONFIG_FILES daemons/lvmetad/Makefile" ;;
|
"daemons/lvmetad/Makefile") CONFIG_FILES="$CONFIG_FILES daemons/lvmetad/Makefile" ;;
|
||||||
|
"daemons/lvmpolld/Makefile") CONFIG_FILES="$CONFIG_FILES daemons/lvmpolld/Makefile" ;;
|
||||||
"conf/Makefile") CONFIG_FILES="$CONFIG_FILES conf/Makefile" ;;
|
"conf/Makefile") CONFIG_FILES="$CONFIG_FILES conf/Makefile" ;;
|
||||||
"conf/example.conf") CONFIG_FILES="$CONFIG_FILES conf/example.conf" ;;
|
"conf/example.conf") CONFIG_FILES="$CONFIG_FILES conf/example.conf" ;;
|
||||||
"conf/lvmlocal.conf") CONFIG_FILES="$CONFIG_FILES conf/lvmlocal.conf" ;;
|
"conf/lvmlocal.conf") CONFIG_FILES="$CONFIG_FILES conf/lvmlocal.conf" ;;
|
||||||
@ -13900,6 +13944,9 @@ do
|
|||||||
"scripts/lvm2_lvmetad_init_red_hat") CONFIG_FILES="$CONFIG_FILES scripts/lvm2_lvmetad_init_red_hat" ;;
|
"scripts/lvm2_lvmetad_init_red_hat") CONFIG_FILES="$CONFIG_FILES scripts/lvm2_lvmetad_init_red_hat" ;;
|
||||||
"scripts/lvm2_lvmetad_systemd_red_hat.service") CONFIG_FILES="$CONFIG_FILES scripts/lvm2_lvmetad_systemd_red_hat.service" ;;
|
"scripts/lvm2_lvmetad_systemd_red_hat.service") CONFIG_FILES="$CONFIG_FILES scripts/lvm2_lvmetad_systemd_red_hat.service" ;;
|
||||||
"scripts/lvm2_lvmetad_systemd_red_hat.socket") CONFIG_FILES="$CONFIG_FILES scripts/lvm2_lvmetad_systemd_red_hat.socket" ;;
|
"scripts/lvm2_lvmetad_systemd_red_hat.socket") CONFIG_FILES="$CONFIG_FILES scripts/lvm2_lvmetad_systemd_red_hat.socket" ;;
|
||||||
|
"scripts/lvm2_lvmpolld_init_red_hat") CONFIG_FILES="$CONFIG_FILES scripts/lvm2_lvmpolld_init_red_hat" ;;
|
||||||
|
"scripts/lvm2_lvmpolld_systemd_red_hat.service") CONFIG_FILES="$CONFIG_FILES scripts/lvm2_lvmpolld_systemd_red_hat.service" ;;
|
||||||
|
"scripts/lvm2_lvmpolld_systemd_red_hat.socket") CONFIG_FILES="$CONFIG_FILES scripts/lvm2_lvmpolld_systemd_red_hat.socket" ;;
|
||||||
"scripts/lvm2_monitoring_init_red_hat") CONFIG_FILES="$CONFIG_FILES scripts/lvm2_monitoring_init_red_hat" ;;
|
"scripts/lvm2_monitoring_init_red_hat") CONFIG_FILES="$CONFIG_FILES scripts/lvm2_monitoring_init_red_hat" ;;
|
||||||
"scripts/lvm2_monitoring_systemd_red_hat.service") CONFIG_FILES="$CONFIG_FILES scripts/lvm2_monitoring_systemd_red_hat.service" ;;
|
"scripts/lvm2_monitoring_systemd_red_hat.service") CONFIG_FILES="$CONFIG_FILES scripts/lvm2_monitoring_systemd_red_hat.service" ;;
|
||||||
"scripts/lvm2_pvscan_systemd_red_hat@.service") CONFIG_FILES="$CONFIG_FILES scripts/lvm2_pvscan_systemd_red_hat@.service" ;;
|
"scripts/lvm2_pvscan_systemd_red_hat@.service") CONFIG_FILES="$CONFIG_FILES scripts/lvm2_pvscan_systemd_red_hat@.service" ;;
|
||||||
|
30
configure.in
30
configure.in
@ -39,6 +39,7 @@ case "$host_os" in
|
|||||||
LIB_SUFFIX=so
|
LIB_SUFFIX=so
|
||||||
DEVMAPPER=yes
|
DEVMAPPER=yes
|
||||||
LVMETAD=no
|
LVMETAD=no
|
||||||
|
LVMPOLLD=no
|
||||||
ODIRECT=yes
|
ODIRECT=yes
|
||||||
DM_IOCTLS=yes
|
DM_IOCTLS=yes
|
||||||
SELINUX=yes
|
SELINUX=yes
|
||||||
@ -1077,6 +1078,29 @@ if test "$BUILD_LVMETAD" = yes; then
|
|||||||
[Path to lvmetad pidfile.])
|
[Path to lvmetad pidfile.])
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
################################################################################
|
||||||
|
dnl -- Build lvmpolld
|
||||||
|
AC_MSG_CHECKING(whether to build lvmpolld)
|
||||||
|
AC_ARG_ENABLE(lvmpolld,
|
||||||
|
AC_HELP_STRING([--enable-lvmpolld],
|
||||||
|
[enable the LVM Polling Daemon]),
|
||||||
|
LVMPOLLD=$enableval)
|
||||||
|
AC_MSG_RESULT($LVMPOLLD)
|
||||||
|
|
||||||
|
BUILD_LVMPOLLD=$LVMPOLLD
|
||||||
|
|
||||||
|
if test "$BUILD_LVMPOLLD" = yes; then
|
||||||
|
AC_DEFINE([LVMPOLLD_SUPPORT], 1, [Define to 1 to include code that uses lvmpolld.])
|
||||||
|
|
||||||
|
AC_ARG_WITH(lvmpolld-pidfile,
|
||||||
|
AC_HELP_STRING([--with-lvmpolld-pidfile=PATH],
|
||||||
|
[lvmpolld pidfile [PID_DIR/lvmpolld.pid]]),
|
||||||
|
LVMPOLLD_PIDFILE=$withval,
|
||||||
|
LVMPOLLD_PIDFILE="$DEFAULT_PID_DIR/lvmpolld.pid")
|
||||||
|
AC_DEFINE_UNQUOTED(LVMPOLLD_PIDFILE, ["$LVMPOLLD_PIDFILE"],
|
||||||
|
[Path to lvmpolld pidfile.])
|
||||||
|
fi
|
||||||
|
|
||||||
################################################################################
|
################################################################################
|
||||||
dnl -- Enable blkid wiping functionality
|
dnl -- Enable blkid wiping functionality
|
||||||
AC_MSG_CHECKING(whether to enable libblkid detection of signatures when wiping)
|
AC_MSG_CHECKING(whether to enable libblkid detection of signatures when wiping)
|
||||||
@ -1687,6 +1711,7 @@ AC_SUBST(BLKID_WIPING)
|
|||||||
AC_SUBST(BUILD_CMIRRORD)
|
AC_SUBST(BUILD_CMIRRORD)
|
||||||
AC_SUBST(BUILD_DMEVENTD)
|
AC_SUBST(BUILD_DMEVENTD)
|
||||||
AC_SUBST(BUILD_LVMETAD)
|
AC_SUBST(BUILD_LVMETAD)
|
||||||
|
AC_SUBST(BUILD_LVMPOLLD)
|
||||||
AC_SUBST(CACHE)
|
AC_SUBST(CACHE)
|
||||||
AC_SUBST(CFLAGS)
|
AC_SUBST(CFLAGS)
|
||||||
AC_SUBST(CFLOW_CMD)
|
AC_SUBST(CFLOW_CMD)
|
||||||
@ -1805,6 +1830,7 @@ AC_SUBST(VALGRIND_POOL)
|
|||||||
AC_SUBST(WRITE_INSTALL)
|
AC_SUBST(WRITE_INSTALL)
|
||||||
AC_SUBST(DMEVENTD_PIDFILE)
|
AC_SUBST(DMEVENTD_PIDFILE)
|
||||||
AC_SUBST(LVMETAD_PIDFILE)
|
AC_SUBST(LVMETAD_PIDFILE)
|
||||||
|
AC_SUBST(LVMPOLLD_PIDFILE)
|
||||||
AC_SUBST(CLVMD_PIDFILE)
|
AC_SUBST(CLVMD_PIDFILE)
|
||||||
AC_SUBST(CMIRRORD_PIDFILE)
|
AC_SUBST(CMIRRORD_PIDFILE)
|
||||||
AC_SUBST(interface)
|
AC_SUBST(interface)
|
||||||
@ -1838,6 +1864,7 @@ daemons/dmeventd/plugins/mirror/Makefile
|
|||||||
daemons/dmeventd/plugins/snapshot/Makefile
|
daemons/dmeventd/plugins/snapshot/Makefile
|
||||||
daemons/dmeventd/plugins/thin/Makefile
|
daemons/dmeventd/plugins/thin/Makefile
|
||||||
daemons/lvmetad/Makefile
|
daemons/lvmetad/Makefile
|
||||||
|
daemons/lvmpolld/Makefile
|
||||||
conf/Makefile
|
conf/Makefile
|
||||||
conf/example.conf
|
conf/example.conf
|
||||||
conf/lvmlocal.conf
|
conf/lvmlocal.conf
|
||||||
@ -1881,6 +1908,9 @@ scripts/lvm2_cmirrord_systemd_red_hat.service
|
|||||||
scripts/lvm2_lvmetad_init_red_hat
|
scripts/lvm2_lvmetad_init_red_hat
|
||||||
scripts/lvm2_lvmetad_systemd_red_hat.service
|
scripts/lvm2_lvmetad_systemd_red_hat.service
|
||||||
scripts/lvm2_lvmetad_systemd_red_hat.socket
|
scripts/lvm2_lvmetad_systemd_red_hat.socket
|
||||||
|
scripts/lvm2_lvmpolld_init_red_hat
|
||||||
|
scripts/lvm2_lvmpolld_systemd_red_hat.service
|
||||||
|
scripts/lvm2_lvmpolld_systemd_red_hat.socket
|
||||||
scripts/lvm2_monitoring_init_red_hat
|
scripts/lvm2_monitoring_init_red_hat
|
||||||
scripts/lvm2_monitoring_systemd_red_hat.service
|
scripts/lvm2_monitoring_systemd_red_hat.service
|
||||||
scripts/lvm2_pvscan_systemd_red_hat@.service
|
scripts/lvm2_pvscan_systemd_red_hat@.service
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
#
|
#
|
||||||
# Copyright (C) 2004-2011 Red Hat, Inc. All rights reserved.
|
# Copyright (C) 2004-2015 Red Hat, Inc. All rights reserved.
|
||||||
#
|
#
|
||||||
# This file is part of LVM2.
|
# This file is part of LVM2.
|
||||||
#
|
#
|
||||||
@ -15,7 +15,7 @@ srcdir = @srcdir@
|
|||||||
top_srcdir = @top_srcdir@
|
top_srcdir = @top_srcdir@
|
||||||
top_builddir = @top_builddir@
|
top_builddir = @top_builddir@
|
||||||
|
|
||||||
.PHONY: dmeventd clvmd cmirrord lvmetad
|
.PHONY: dmeventd clvmd cmirrord lvmetad lvmpolld
|
||||||
|
|
||||||
ifneq ("@CLVMD@", "none")
|
ifneq ("@CLVMD@", "none")
|
||||||
SUBDIRS += clvmd
|
SUBDIRS += clvmd
|
||||||
@ -36,8 +36,12 @@ ifeq ("@BUILD_LVMETAD@", "yes")
|
|||||||
SUBDIRS += lvmetad
|
SUBDIRS += lvmetad
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
ifeq ("@BUILD_LVMPOLLD@", "yes")
|
||||||
|
SUBDIRS += lvmpolld
|
||||||
|
endif
|
||||||
|
|
||||||
ifeq ($(MAKECMDGOALS),distclean)
|
ifeq ($(MAKECMDGOALS),distclean)
|
||||||
SUBDIRS = clvmd cmirrord dmeventd lvmetad
|
SUBDIRS = clvmd cmirrord dmeventd lvmetad lvmpolld
|
||||||
endif
|
endif
|
||||||
|
|
||||||
include $(top_builddir)/make.tmpl
|
include $(top_builddir)/make.tmpl
|
||||||
|
49
daemons/lvmpolld/Makefile.in
Normal file
49
daemons/lvmpolld/Makefile.in
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
#
|
||||||
|
# Copyright (C) 2014-2015 Red Hat, Inc.
|
||||||
|
#
|
||||||
|
# This file is part of LVM2.
|
||||||
|
#
|
||||||
|
# This copyrighted material is made available to anyone wishing to use,
|
||||||
|
# modify, copy, or redistribute it subject to the terms and conditions
|
||||||
|
# of the GNU Lesser General Public License v.2.1.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU Lesser General Public License
|
||||||
|
# along with this program; if not, write to the Free Software Foundation,
|
||||||
|
# Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
|
|
||||||
|
srcdir = @srcdir@
|
||||||
|
top_srcdir = @top_srcdir@
|
||||||
|
top_builddir = @top_builddir@
|
||||||
|
|
||||||
|
SOURCES = lvmpolld-core.c lvmpolld-data-utils.c lvmpolld-cmd-utils.c
|
||||||
|
|
||||||
|
TARGETS = lvmpolld
|
||||||
|
|
||||||
|
.PHONY: install_lvmpolld
|
||||||
|
|
||||||
|
CFLOW_LIST = $(SOURCES)
|
||||||
|
CFLOW_LIST_TARGET = $(LIB_NAME).cflow
|
||||||
|
CFLOW_TARGET = lvmpolld
|
||||||
|
|
||||||
|
include $(top_builddir)/make.tmpl
|
||||||
|
|
||||||
|
INCLUDES += -I$(top_srcdir)/libdaemon/server
|
||||||
|
LVMLIBS = -ldaemonserver $(LVMINTERNAL_LIBS) -ldevmapper
|
||||||
|
|
||||||
|
LIBS += $(PTHREAD_LIBS)
|
||||||
|
|
||||||
|
LDFLAGS += -L$(top_builddir)/libdaemon/server $(DAEMON_LDFLAGS)
|
||||||
|
CLDFLAGS += -L$(top_builddir)/libdaemon/server
|
||||||
|
CFLAGS += $(DAEMON_CFLAGS)
|
||||||
|
|
||||||
|
lvmpolld: $(OBJECTS) $(top_builddir)/libdaemon/client/libdaemonclient.a \
|
||||||
|
$(top_builddir)/libdaemon/server/libdaemonserver.a
|
||||||
|
$(CC) $(CFLAGS) $(LDFLAGS) -o $@ $(OBJECTS) \
|
||||||
|
$(DL_LIBS) $(LVMLIBS) $(LIBS)
|
||||||
|
|
||||||
|
install_lvmpolld: lvmpolld
|
||||||
|
$(INSTALL_PROGRAM) -D $< $(sbindir)/$(<F)
|
||||||
|
|
||||||
|
install_lvm2: install_lvmpolld
|
||||||
|
|
||||||
|
install: install_lvm2
|
140
daemons/lvmpolld/lvmpolld-cmd-utils.c
Normal file
140
daemons/lvmpolld/lvmpolld-cmd-utils.c
Normal file
@ -0,0 +1,140 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2015 Red Hat, Inc.
|
||||||
|
*
|
||||||
|
* This file is part of LVM2.
|
||||||
|
*
|
||||||
|
* This copyrighted material is made available to anyone wishing to use,
|
||||||
|
* modify, copy, or redistribute it subject to the terms and conditions
|
||||||
|
* of the GNU Lesser General Public License v.2.1.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public License
|
||||||
|
* along with this program; if not, write to the Free Software Foundation,
|
||||||
|
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "lvmpolld-common.h"
|
||||||
|
|
||||||
|
/* extract this info from autoconf/automake files */
|
||||||
|
#define LVPOLL_CMD "lvpoll"
|
||||||
|
|
||||||
|
#define MIN_ARGV_SIZE 8
|
||||||
|
|
||||||
|
static const char *const const polling_ops[] = { [PVMOVE] = LVMPD_REQ_PVMOVE,
|
||||||
|
[CONVERT] = LVMPD_REQ_CONVERT,
|
||||||
|
[MERGE] = LVMPD_REQ_MERGE,
|
||||||
|
[MERGE_THIN] = LVMPD_REQ_MERGE_THIN };
|
||||||
|
|
||||||
|
const char *polling_op(enum poll_type type)
|
||||||
|
{
|
||||||
|
return type < POLL_TYPE_MAX ? polling_ops[type] : "<undefined>";
|
||||||
|
}
|
||||||
|
|
||||||
|
static int add_to_cmd_arr(const char ***cmdargv, const char *str, unsigned *ind)
|
||||||
|
{
|
||||||
|
const char **newargv = *cmdargv;
|
||||||
|
|
||||||
|
if (*ind && !(*ind % MIN_ARGV_SIZE)) {
|
||||||
|
newargv = dm_realloc(*cmdargv, (*ind / MIN_ARGV_SIZE + 1) * MIN_ARGV_SIZE * sizeof(char *));
|
||||||
|
if (!newargv)
|
||||||
|
return 0;
|
||||||
|
*cmdargv = newargv;
|
||||||
|
}
|
||||||
|
|
||||||
|
*(*cmdargv + (*ind)++) = str;
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
const char **cmdargv_ctr(const struct lvmpolld_lv *pdlv, const char *lvm_binary, unsigned abort_polling, unsigned handle_missing_pvs)
|
||||||
|
{
|
||||||
|
unsigned i = 0;
|
||||||
|
const char **cmd_argv = dm_malloc(MIN_ARGV_SIZE * sizeof(char *));
|
||||||
|
|
||||||
|
if (!cmd_argv)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
/* path to lvm2 binary */
|
||||||
|
if (!add_to_cmd_arr(&cmd_argv, lvm_binary, &i))
|
||||||
|
goto err;
|
||||||
|
|
||||||
|
/* cmd to execute */
|
||||||
|
if (!add_to_cmd_arr(&cmd_argv, LVPOLL_CMD, &i))
|
||||||
|
goto err;
|
||||||
|
|
||||||
|
/* transfer internal polling interval */
|
||||||
|
if (pdlv->sinterval &&
|
||||||
|
(!add_to_cmd_arr(&cmd_argv, "--interval", &i) ||
|
||||||
|
!add_to_cmd_arr(&cmd_argv, pdlv->sinterval, &i)))
|
||||||
|
goto err;
|
||||||
|
|
||||||
|
/* pass abort param */
|
||||||
|
if (abort_polling &&
|
||||||
|
!add_to_cmd_arr(&cmd_argv, "--abort", &i))
|
||||||
|
goto err;
|
||||||
|
|
||||||
|
/* pass handle-missing-pvs. used by mirror polling operation */
|
||||||
|
if (handle_missing_pvs &&
|
||||||
|
!add_to_cmd_arr(&cmd_argv, "--handlemissingpvs", &i))
|
||||||
|
goto err;
|
||||||
|
|
||||||
|
/* one of: "convert", "pvmove", "merge", "merge_thin" */
|
||||||
|
if (!add_to_cmd_arr(&cmd_argv, "--polloperation", &i) ||
|
||||||
|
!add_to_cmd_arr(&cmd_argv, polling_ops[pdlv->type], &i))
|
||||||
|
goto err;
|
||||||
|
|
||||||
|
/* vg/lv name */
|
||||||
|
if (!add_to_cmd_arr(&cmd_argv, pdlv->lvname, &i))
|
||||||
|
goto err;
|
||||||
|
|
||||||
|
/* terminating NULL */
|
||||||
|
if (!add_to_cmd_arr(&cmd_argv, NULL, &i))
|
||||||
|
goto err;
|
||||||
|
|
||||||
|
return cmd_argv;
|
||||||
|
err:
|
||||||
|
dm_free(cmd_argv);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* FIXME: in fact exclude should be va list */
|
||||||
|
static int copy_env(const char ***cmd_envp, unsigned *i, const char *exclude)
|
||||||
|
{
|
||||||
|
const char * const* tmp = (const char * const*) environ;
|
||||||
|
|
||||||
|
if (!tmp)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
while (*tmp) {
|
||||||
|
if (strncmp(*tmp, exclude, strlen(exclude)) && !add_to_cmd_arr(cmd_envp, *tmp, i))
|
||||||
|
return 0;
|
||||||
|
tmp++;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
const char **cmdenvp_ctr(const struct lvmpolld_lv *pdlv)
|
||||||
|
{
|
||||||
|
unsigned i = 0;
|
||||||
|
const char **cmd_envp = dm_malloc(MIN_ARGV_SIZE * sizeof(char *));
|
||||||
|
|
||||||
|
if (!cmd_envp)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
/* copy whole environment from lvmpolld, exclude LVM_SYSTEM_DIR if set */
|
||||||
|
if (!copy_env(&cmd_envp, &i, "LVM_SYSTEM_DIR="))
|
||||||
|
goto err;
|
||||||
|
|
||||||
|
/* Add per client LVM_SYSTEM_DIR variable if set */
|
||||||
|
if (*pdlv->lvm_system_dir_env && !add_to_cmd_arr(&cmd_envp, pdlv->lvm_system_dir_env, &i))
|
||||||
|
goto err;
|
||||||
|
|
||||||
|
/* terminating NULL */
|
||||||
|
if (!add_to_cmd_arr(&cmd_envp, NULL, &i))
|
||||||
|
goto err;
|
||||||
|
|
||||||
|
return cmd_envp;
|
||||||
|
err:
|
||||||
|
dm_free(cmd_envp);
|
||||||
|
return NULL;
|
||||||
|
}
|
25
daemons/lvmpolld/lvmpolld-cmd-utils.h
Normal file
25
daemons/lvmpolld/lvmpolld-cmd-utils.h
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2015 Red Hat, Inc.
|
||||||
|
*
|
||||||
|
* This file is part of LVM2.
|
||||||
|
*
|
||||||
|
* This copyrighted material is made available to anyone wishing to use,
|
||||||
|
* modify, copy, or redistribute it subject to the terms and conditions
|
||||||
|
* of the GNU Lesser General Public License v.2.1.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public License
|
||||||
|
* along with this program; if not, write to the Free Software Foundation,
|
||||||
|
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _LVM_LVMPOLLD_CMD_UTILS_H
|
||||||
|
#define _LVM_LVMPOLLD_CMD_UTILS_H
|
||||||
|
|
||||||
|
#include "lvmpolld-data-utils.h"
|
||||||
|
|
||||||
|
const char **cmdargv_ctr(const struct lvmpolld_lv *pdlv, const char *lvm_binary, unsigned abort, unsigned handle_missing_pvs);
|
||||||
|
const char **cmdenvp_ctr(const struct lvmpolld_lv *pdlv);
|
||||||
|
|
||||||
|
const char *polling_op(enum poll_type);
|
||||||
|
|
||||||
|
#endif /* _LVM_LVMPOLLD_CMD_UTILS_H */
|
36
daemons/lvmpolld/lvmpolld-common.h
Normal file
36
daemons/lvmpolld/lvmpolld-common.h
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2010-2015 Red Hat, Inc. All rights reserved.
|
||||||
|
*
|
||||||
|
* This file is part of LVM2.
|
||||||
|
*
|
||||||
|
* This copyrighted material is made available to anyone wishing to use,
|
||||||
|
* modify, copy, or redistribute it subject to the terms and conditions
|
||||||
|
* of the GNU Lesser General Public License v.2.1.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public License
|
||||||
|
* along with this program; if not, write to the Free Software Foundation,
|
||||||
|
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file must be included first by every lvmpolld source file.
|
||||||
|
*/
|
||||||
|
#ifndef _LVM_LVMPOLLD_COMMON_H
|
||||||
|
#define _LVM_LVMPOLLD_COMMON_H
|
||||||
|
|
||||||
|
#include "configure.h"
|
||||||
|
|
||||||
|
#define _REENTRANT
|
||||||
|
#define _GNU_SOURCE
|
||||||
|
#define _FILE_OFFSET_BITS 64
|
||||||
|
|
||||||
|
#include "libdevmapper.h"
|
||||||
|
|
||||||
|
#include "lvmpolld-cmd-utils.h"
|
||||||
|
#include "lvmpolld-protocol.h"
|
||||||
|
|
||||||
|
#include <assert.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
#endif /* _LVM_LVMPOLLD_COMMON_H */
|
817
daemons/lvmpolld/lvmpolld-core.c
Normal file
817
daemons/lvmpolld/lvmpolld-core.c
Normal file
@ -0,0 +1,817 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2014-2015 Red Hat, Inc.
|
||||||
|
*
|
||||||
|
* This file is part of LVM2.
|
||||||
|
*
|
||||||
|
* This copyrighted material is made available to anyone wishing to use,
|
||||||
|
* modify, copy, or redistribute it subject to the terms and conditions
|
||||||
|
* of the GNU Lesser General Public License v.2.1.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public License
|
||||||
|
* along with this program; if not, write to the Free Software Foundation,
|
||||||
|
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "lvmpolld-common.h"
|
||||||
|
|
||||||
|
#include "lvm-version.h"
|
||||||
|
#include "daemon-server.h"
|
||||||
|
#include "daemon-log.h"
|
||||||
|
|
||||||
|
#include <poll.h>
|
||||||
|
#include <wait.h>
|
||||||
|
|
||||||
|
#define LVMPOLLD_SOCKET DEFAULT_RUN_DIR "/lvmpolld.socket"
|
||||||
|
|
||||||
|
#define PD_LOG_PREFIX "LVMPOLLD"
|
||||||
|
#define LVM2_LOG_PREFIX "\tLVPOLL"
|
||||||
|
|
||||||
|
/* predefined reason for response = "failed" case */
|
||||||
|
#define REASON_REQ_NOT_IMPLEMENTED "request not implemented"
|
||||||
|
#define REASON_MISSING_LVID "request requires lvid set"
|
||||||
|
#define REASON_MISSING_LVNAME "request requires lvname set"
|
||||||
|
#define REASON_MISSING_VGNAME "request requires vgname set"
|
||||||
|
#define REASON_POLLING_FAILED "polling of lvm command failed"
|
||||||
|
#define REASON_ILLEGAL_ABORT_REQUEST "abort only supported with PVMOVE polling operation"
|
||||||
|
#define REASON_DIFFERENT_OPERATION_IN_PROGRESS "Different operation on LV already in progress"
|
||||||
|
#define REASON_INVALID_INTERVAL "request requires interval set"
|
||||||
|
#define REASON_ENOMEM "not enough memory"
|
||||||
|
|
||||||
|
struct lvmpolld_state {
|
||||||
|
daemon_idle *idle;
|
||||||
|
log_state *log;
|
||||||
|
const char *log_config;
|
||||||
|
const char *lvm_binary;
|
||||||
|
|
||||||
|
struct lvmpolld_store *id_to_pdlv_abort;
|
||||||
|
struct lvmpolld_store *id_to_pdlv_poll;
|
||||||
|
};
|
||||||
|
|
||||||
|
static pthread_key_t key;
|
||||||
|
|
||||||
|
static const char *_strerror_r(int errnum, struct lvmpolld_thread_data *data)
|
||||||
|
{
|
||||||
|
#ifdef _GNU_SOURCE
|
||||||
|
return strerror_r(errnum, data->buf, sizeof(data->buf)); /* never returns NULL */
|
||||||
|
#elif (_POSIX_C_SOURCE >= 200112L || _XOPEN_SOURCE >= 600)
|
||||||
|
return strerror_r(errnum, data->buf, sizeof(data->buf)) ? "" : data->buf;
|
||||||
|
#else
|
||||||
|
# warning "Can't decide proper strerror_r implementation. lvmpolld will not issue specific system error messages"
|
||||||
|
return "";
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
static void usage(const char *prog, FILE *file)
|
||||||
|
{
|
||||||
|
fprintf(file, "Usage:\n"
|
||||||
|
"%s [-V] [-h] [-f] [-l {all|wire|debug}] [-s path]\n\n"
|
||||||
|
" -V Show version info\n"
|
||||||
|
" -h Show this help information\n"
|
||||||
|
" -f Don't fork, run in the foreground\n"
|
||||||
|
" -l Logging message level (-l {all|wire|debug})\n"
|
||||||
|
" -p Set path to the pidfile\n"
|
||||||
|
" -s Set path to the socket to listen on\n"
|
||||||
|
" -B Path to lvm2 binary\n"
|
||||||
|
" -t Time to wait in seconds before shutdown on idle (missing or 0 = inifinite)\n\n", prog);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int init(struct daemon_state *s)
|
||||||
|
{
|
||||||
|
struct lvmpolld_state *ls = s->private;
|
||||||
|
ls->log = s->log;
|
||||||
|
|
||||||
|
if (!daemon_log_parse(ls->log, DAEMON_LOG_OUTLET_STDERR, ls->log_config, 1))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if (pthread_key_create(&key, lvmpolld_thread_data_destroy)) {
|
||||||
|
FATAL(ls, "%s: %s", PD_LOG_PREFIX, "Failed to create pthread key");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
ls->id_to_pdlv_poll = pdst_init("polling");
|
||||||
|
ls->id_to_pdlv_abort = pdst_init("abort");
|
||||||
|
|
||||||
|
if (!ls->id_to_pdlv_poll || !ls->id_to_pdlv_abort) {
|
||||||
|
FATAL(ls, "%s: %s", PD_LOG_PREFIX, "Failed to allocate internal data structures");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
ls->lvm_binary = ls->lvm_binary ?: LVM_PATH;
|
||||||
|
|
||||||
|
if (access(ls->lvm_binary, X_OK)) {
|
||||||
|
FATAL(ls, "%s: %s %s", PD_LOG_PREFIX, "Execute access rights denied on", ls->lvm_binary);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ls->idle)
|
||||||
|
ls->idle->is_idle = 1;
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void lvmpolld_stores_lock(struct lvmpolld_state *ls)
|
||||||
|
{
|
||||||
|
pdst_lock(ls->id_to_pdlv_poll);
|
||||||
|
pdst_lock(ls->id_to_pdlv_abort);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void lvmpolld_stores_unlock(struct lvmpolld_state *ls)
|
||||||
|
{
|
||||||
|
pdst_unlock(ls->id_to_pdlv_abort);
|
||||||
|
pdst_unlock(ls->id_to_pdlv_poll);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void lvmpolld_global_lock(struct lvmpolld_state *ls)
|
||||||
|
{
|
||||||
|
lvmpolld_stores_lock(ls);
|
||||||
|
|
||||||
|
pdst_locked_lock_all_pdlvs(ls->id_to_pdlv_poll);
|
||||||
|
pdst_locked_lock_all_pdlvs(ls->id_to_pdlv_abort);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void lvmpolld_global_unlock(struct lvmpolld_state *ls)
|
||||||
|
{
|
||||||
|
pdst_locked_unlock_all_pdlvs(ls->id_to_pdlv_abort);
|
||||||
|
pdst_locked_unlock_all_pdlvs(ls->id_to_pdlv_poll);
|
||||||
|
|
||||||
|
lvmpolld_stores_unlock(ls);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int fini(struct daemon_state *s)
|
||||||
|
{
|
||||||
|
int done;
|
||||||
|
const struct timespec t = { .tv_nsec = 250000000 }; /* .25 sec */
|
||||||
|
struct lvmpolld_state *ls = s->private;
|
||||||
|
|
||||||
|
DEBUGLOG(s, "fini");
|
||||||
|
|
||||||
|
DEBUGLOG(s, "sending cancel requests");
|
||||||
|
|
||||||
|
lvmpolld_global_lock(ls);
|
||||||
|
pdst_locked_send_cancel(ls->id_to_pdlv_poll);
|
||||||
|
pdst_locked_send_cancel(ls->id_to_pdlv_abort);
|
||||||
|
lvmpolld_global_unlock(ls);
|
||||||
|
|
||||||
|
DEBUGLOG(s, "waiting for background threads to finish");
|
||||||
|
|
||||||
|
while(1) {
|
||||||
|
lvmpolld_stores_lock(ls);
|
||||||
|
done = !pdst_locked_get_active_count(ls->id_to_pdlv_poll) &&
|
||||||
|
!pdst_locked_get_active_count(ls->id_to_pdlv_abort);
|
||||||
|
lvmpolld_stores_unlock(ls);
|
||||||
|
if (done)
|
||||||
|
break;
|
||||||
|
nanosleep(&t, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
DEBUGLOG(s, "destroying internal data structures");
|
||||||
|
|
||||||
|
lvmpolld_stores_lock(ls);
|
||||||
|
pdst_locked_destroy_all_pdlvs(ls->id_to_pdlv_poll);
|
||||||
|
pdst_locked_destroy_all_pdlvs(ls->id_to_pdlv_abort);
|
||||||
|
lvmpolld_stores_unlock(ls);
|
||||||
|
|
||||||
|
pdst_destroy(ls->id_to_pdlv_poll);
|
||||||
|
pdst_destroy(ls->id_to_pdlv_abort);
|
||||||
|
|
||||||
|
pthread_key_delete(key);
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static response reply(const char *res, const char *reason)
|
||||||
|
{
|
||||||
|
return daemon_reply_simple(res, "reason = %s", reason, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int read_single_line(struct lvmpolld_thread_data *data, int err)
|
||||||
|
{
|
||||||
|
ssize_t r = getline(&data->line, &data->line_size, err ? data->ferr : data->fout);
|
||||||
|
|
||||||
|
if (r > 0 && *(data->line + r - 1) == '\n')
|
||||||
|
*(data->line + r - 1) = '\0';
|
||||||
|
|
||||||
|
return (r > 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void update_idle_state(struct lvmpolld_state *ls)
|
||||||
|
{
|
||||||
|
if (!ls->idle)
|
||||||
|
return;
|
||||||
|
|
||||||
|
lvmpolld_stores_lock(ls);
|
||||||
|
|
||||||
|
ls->idle->is_idle = !pdst_locked_get_active_count(ls->id_to_pdlv_poll) &&
|
||||||
|
!pdst_locked_get_active_count(ls->id_to_pdlv_abort);
|
||||||
|
|
||||||
|
lvmpolld_stores_unlock(ls);
|
||||||
|
|
||||||
|
DEBUGLOG(ls, "%s: %s %s%s", PD_LOG_PREFIX, "daemon is", ls->idle->is_idle ? "" : "not ", "idle");
|
||||||
|
}
|
||||||
|
|
||||||
|
/* make this configurable */
|
||||||
|
#define MAX_TIMEOUT 2
|
||||||
|
|
||||||
|
static int poll_for_output(struct lvmpolld_lv *pdlv, struct lvmpolld_thread_data *data)
|
||||||
|
{
|
||||||
|
int ch_stat, r, err = 1, fds_count = 2, timeout = 0;
|
||||||
|
pid_t pid;
|
||||||
|
struct lvmpolld_cmd_stat cmd_state = { .retcode = -1, .signal = 0 };
|
||||||
|
struct pollfd fds[] = { { .fd = data->outpipe[0], .events = POLLIN },
|
||||||
|
{ .fd = data->errpipe[0], .events = POLLIN } };
|
||||||
|
|
||||||
|
if (!(data->fout = fdopen(data->outpipe[0], "r")) || !(data->ferr = fdopen(data->errpipe[0], "r"))) {
|
||||||
|
ERROR(pdlv->ls, "%s: %s: (%d) %s", PD_LOG_PREFIX, "failed to open file stream",
|
||||||
|
errno, _strerror_r(errno, data));
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (1) {
|
||||||
|
do {
|
||||||
|
r = poll(fds, 2, pdlv_get_timeout(pdlv) * 1000);
|
||||||
|
} while (r < 0 && errno == EINTR);
|
||||||
|
|
||||||
|
DEBUGLOG(pdlv->ls, "%s: %s %d", PD_LOG_PREFIX, "poll() returned", r);
|
||||||
|
if (r < 0) {
|
||||||
|
ERROR(pdlv->ls, "%s: %s (PID %d) failed: (%d) %s",
|
||||||
|
PD_LOG_PREFIX, "poll() for LVM2 cmd", pdlv->cmd_pid,
|
||||||
|
errno, _strerror_r(errno, data));
|
||||||
|
goto out;
|
||||||
|
} else if (!r) {
|
||||||
|
timeout++;
|
||||||
|
|
||||||
|
WARN(pdlv->ls, "%s: %s (PID %d) %s", PD_LOG_PREFIX,
|
||||||
|
"polling for output of the lvm cmd", pdlv->cmd_pid,
|
||||||
|
"has timed out");
|
||||||
|
|
||||||
|
if (timeout > MAX_TIMEOUT) {
|
||||||
|
ERROR(pdlv->ls, "%s: %s (PID %d) (no output for %d seconds)",
|
||||||
|
PD_LOG_PREFIX,
|
||||||
|
"LVM2 cmd is unresponsive too long",
|
||||||
|
pdlv->cmd_pid,
|
||||||
|
timeout * pdlv_get_timeout(pdlv));
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
continue; /* while(1) */
|
||||||
|
}
|
||||||
|
|
||||||
|
timeout = 0;
|
||||||
|
|
||||||
|
/* handle the command's STDOUT */
|
||||||
|
if (fds[0].revents & POLLIN) {
|
||||||
|
DEBUGLOG(pdlv->ls, "%s: %s", PD_LOG_PREFIX, "caught input data in STDOUT");
|
||||||
|
|
||||||
|
assert(read_single_line(data, 0)); /* may block indef. anyway */
|
||||||
|
INFO(pdlv->ls, "%s: PID %d: %s: '%s'", LVM2_LOG_PREFIX,
|
||||||
|
pdlv->cmd_pid, "STDOUT", data->line);
|
||||||
|
} else if (fds[0].revents) {
|
||||||
|
if (fds[0].revents & POLLHUP)
|
||||||
|
DEBUGLOG(pdlv->ls, "%s: %s", PD_LOG_PREFIX, "caught POLLHUP");
|
||||||
|
else
|
||||||
|
WARN(pdlv->ls, "%s: %s", PD_LOG_PREFIX, "poll for command's STDOUT failed");
|
||||||
|
|
||||||
|
fds[0].fd = -1;
|
||||||
|
fds_count--;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* handle the command's STDERR */
|
||||||
|
if (fds[1].revents & POLLIN) {
|
||||||
|
DEBUGLOG(pdlv->ls, "%s: %s", PD_LOG_PREFIX,
|
||||||
|
"caught input data in STDERR");
|
||||||
|
|
||||||
|
assert(read_single_line(data, 1)); /* may block indef. anyway */
|
||||||
|
INFO(pdlv->ls, "%s: PID %d: %s: '%s'", LVM2_LOG_PREFIX,
|
||||||
|
pdlv->cmd_pid, "STDERR", data->line);
|
||||||
|
} else if (fds[1].revents) {
|
||||||
|
if (fds[1].revents & POLLHUP)
|
||||||
|
DEBUGLOG(pdlv->ls, "%s: %s", PD_LOG_PREFIX, "caught err POLLHUP");
|
||||||
|
else
|
||||||
|
WARN(pdlv->ls, "%s: %s", PD_LOG_PREFIX, "poll for command's STDOUT failed");
|
||||||
|
|
||||||
|
fds[1].fd = -1;
|
||||||
|
fds_count--;
|
||||||
|
}
|
||||||
|
|
||||||
|
do {
|
||||||
|
/*
|
||||||
|
* fds_count == 0 means polling reached EOF
|
||||||
|
* or received error on both descriptors.
|
||||||
|
* In such case, just wait for command to finish
|
||||||
|
*/
|
||||||
|
pid = waitpid(pdlv->cmd_pid, &ch_stat, fds_count ? WNOHANG : 0);
|
||||||
|
} while (pid < 0 && errno == EINTR);
|
||||||
|
|
||||||
|
if (pid) {
|
||||||
|
if (pid < 0) {
|
||||||
|
ERROR(pdlv->ls, "%s: %s (PID %d) failed: (%d) %s",
|
||||||
|
PD_LOG_PREFIX, "waitpid() for lvm2 cmd",
|
||||||
|
pdlv->cmd_pid, errno,
|
||||||
|
_strerror_r(errno, data));
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
DEBUGLOG(pdlv->ls, "%s: %s", PD_LOG_PREFIX, "child exited");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} /* while(1) */
|
||||||
|
|
||||||
|
DEBUGLOG(pdlv->ls, "%s: %s", PD_LOG_PREFIX, "about to collect remaining lines");
|
||||||
|
if (fds[0].fd >= 0)
|
||||||
|
while (read_single_line(data, 0)) {
|
||||||
|
assert(r > 0);
|
||||||
|
INFO(pdlv->ls, "%s: PID %d: %s: %s", LVM2_LOG_PREFIX, pdlv->cmd_pid, "STDOUT", data->line);
|
||||||
|
}
|
||||||
|
if (fds[1].fd >= 0)
|
||||||
|
while (read_single_line(data, 1)) {
|
||||||
|
assert(r > 0);
|
||||||
|
INFO(pdlv->ls, "%s: PID %d: %s: %s", LVM2_LOG_PREFIX, pdlv->cmd_pid, "STDERR", data->line);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (WIFEXITED(ch_stat)) {
|
||||||
|
INFO(pdlv->ls, "%s: %s (PID %d) %s (%d)", PD_LOG_PREFIX,
|
||||||
|
"lvm2 cmd", pdlv->cmd_pid, "exited with", WEXITSTATUS(ch_stat));
|
||||||
|
cmd_state.retcode = WEXITSTATUS(ch_stat);
|
||||||
|
} else if (WIFSIGNALED(ch_stat)) {
|
||||||
|
WARN(pdlv->ls, "%s: %s (PID %d) %s (%d)", PD_LOG_PREFIX,
|
||||||
|
"lvm2 cmd", pdlv->cmd_pid, "got terminated by signal",
|
||||||
|
WTERMSIG(ch_stat));
|
||||||
|
cmd_state.signal = WTERMSIG(ch_stat);
|
||||||
|
}
|
||||||
|
|
||||||
|
err = 0;
|
||||||
|
out:
|
||||||
|
if (!err)
|
||||||
|
pdlv_set_cmd_state(pdlv, &cmd_state);
|
||||||
|
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void debug_print(struct lvmpolld_state *ls, const char * const* ptr)
|
||||||
|
{
|
||||||
|
const char * const* tmp = ptr;
|
||||||
|
|
||||||
|
if (!tmp)
|
||||||
|
return;
|
||||||
|
|
||||||
|
while (*tmp) {
|
||||||
|
DEBUGLOG(ls, "%s: %s", PD_LOG_PREFIX, *tmp);
|
||||||
|
tmp++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void *fork_and_poll(void *args)
|
||||||
|
{
|
||||||
|
int outfd, errfd, state;
|
||||||
|
struct lvmpolld_thread_data *data;
|
||||||
|
pid_t r;
|
||||||
|
|
||||||
|
int error = 1;
|
||||||
|
struct lvmpolld_lv *pdlv = (struct lvmpolld_lv *) args;
|
||||||
|
struct lvmpolld_state *ls = pdlv->ls;
|
||||||
|
|
||||||
|
pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &state);
|
||||||
|
data = lvmpolld_thread_data_constructor(pdlv);
|
||||||
|
pthread_setspecific(key, data);
|
||||||
|
pthread_setcancelstate(state, &state);
|
||||||
|
|
||||||
|
if (!data) {
|
||||||
|
ERROR(ls, "%s: %s", PD_LOG_PREFIX, "Failed to initialize per-thread data");
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
|
||||||
|
DEBUGLOG(ls, "%s: %s", PD_LOG_PREFIX, "cmd line arguments:");
|
||||||
|
debug_print(ls, pdlv->cmdargv);
|
||||||
|
DEBUGLOG(ls, "%s: %s", PD_LOG_PREFIX, "---end---");
|
||||||
|
|
||||||
|
DEBUGLOG(ls, "%s: %s", PD_LOG_PREFIX, "cmd environment variables:");
|
||||||
|
debug_print(ls, pdlv->cmdenvp);
|
||||||
|
DEBUGLOG(ls, "%s: %s", PD_LOG_PREFIX, "---end---");
|
||||||
|
|
||||||
|
outfd = data->outpipe[1];
|
||||||
|
errfd = data->errpipe[1];
|
||||||
|
|
||||||
|
r = fork();
|
||||||
|
if (!r) {
|
||||||
|
/* child */
|
||||||
|
/* !!! Do not touch any posix thread primitives !!! */
|
||||||
|
|
||||||
|
if ((dup2(outfd, STDOUT_FILENO ) != STDOUT_FILENO) ||
|
||||||
|
(dup2(errfd, STDERR_FILENO ) != STDERR_FILENO))
|
||||||
|
_exit(100);
|
||||||
|
|
||||||
|
execve(*(pdlv->cmdargv), (char *const *)pdlv->cmdargv, (char *const *)pdlv->cmdenvp);
|
||||||
|
|
||||||
|
_exit(101);
|
||||||
|
} else {
|
||||||
|
/* parent */
|
||||||
|
if (r == -1) {
|
||||||
|
ERROR(ls, "%s: %s: (%d) %s", PD_LOG_PREFIX, "fork failed",
|
||||||
|
errno, _strerror_r(errno, data));
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
|
||||||
|
INFO(ls, "%s: LVM2 cmd \"%s\" (PID: %d)", PD_LOG_PREFIX, *(pdlv->cmdargv), r);
|
||||||
|
|
||||||
|
pdlv->cmd_pid = r;
|
||||||
|
|
||||||
|
/* failure to close write end of any pipe will result in broken polling */
|
||||||
|
if (close(data->outpipe[1])) {
|
||||||
|
ERROR(ls, "%s: %s: (%d) %s", PD_LOG_PREFIX, "failed to close write end of pipe",
|
||||||
|
errno, _strerror_r(errno, data));
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
data->outpipe[1] = -1;
|
||||||
|
|
||||||
|
if (close(data->errpipe[1])) {
|
||||||
|
ERROR(ls, "%s: %s: (%d) %s", PD_LOG_PREFIX, "failed to close write end of err pipe",
|
||||||
|
errno, _strerror_r(errno, data));
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
data->errpipe[1] = -1;
|
||||||
|
|
||||||
|
error = poll_for_output(pdlv, data);
|
||||||
|
DEBUGLOG(ls, "%s: %s", PD_LOG_PREFIX, "polling for lvpoll output has finished");
|
||||||
|
}
|
||||||
|
|
||||||
|
err:
|
||||||
|
r = 0;
|
||||||
|
|
||||||
|
pdst_lock(pdlv->pdst);
|
||||||
|
|
||||||
|
if (error) {
|
||||||
|
/* last reader is responsible for pdlv cleanup */
|
||||||
|
r = pdlv->cmd_pid;
|
||||||
|
pdlv_set_error(pdlv, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
pdlv_set_polling_finished(pdlv, 1);
|
||||||
|
if (data)
|
||||||
|
data->pdlv = NULL;
|
||||||
|
|
||||||
|
pdst_locked_dec(pdlv->pdst);
|
||||||
|
|
||||||
|
pdst_unlock(pdlv->pdst);
|
||||||
|
|
||||||
|
pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &state);
|
||||||
|
lvmpolld_thread_data_destroy(data);
|
||||||
|
pthread_setspecific(key, NULL);
|
||||||
|
pthread_setcancelstate(state, &state);
|
||||||
|
|
||||||
|
update_idle_state(ls);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This is unfortunate case where we
|
||||||
|
* know nothing about state of lvm cmd and
|
||||||
|
* (eventually) ongoing progress.
|
||||||
|
*
|
||||||
|
* harvest zombies
|
||||||
|
*/
|
||||||
|
if (r)
|
||||||
|
while(waitpid(r, NULL, 0) < 0 && errno == EINTR);
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static response progress_info(client_handle h, struct lvmpolld_state *ls, request req)
|
||||||
|
{
|
||||||
|
char *id;
|
||||||
|
struct lvmpolld_lv *pdlv;
|
||||||
|
struct lvmpolld_store *pdst;
|
||||||
|
struct lvmpolld_lv_state st;
|
||||||
|
response r;
|
||||||
|
const char *lvid = daemon_request_str(req, LVMPD_PARM_LVID, NULL);
|
||||||
|
const char *sysdir = daemon_request_str(req, LVMPD_PARM_SYSDIR, NULL);
|
||||||
|
unsigned abort_polling = daemon_request_int(req, LVMPD_PARM_ABORT, 0);
|
||||||
|
|
||||||
|
if (!lvid)
|
||||||
|
return reply(LVMPD_RESP_FAILED, REASON_MISSING_LVID);
|
||||||
|
|
||||||
|
id = construct_id(sysdir, lvid);
|
||||||
|
if (!id) {
|
||||||
|
ERROR(ls, "%s: %s", PD_LOG_PREFIX, "progress_info request failed to construct ID.");
|
||||||
|
return reply(LVMPD_RESP_FAILED, REASON_ENOMEM);
|
||||||
|
}
|
||||||
|
|
||||||
|
DEBUGLOG(ls, "%s: %s: %s", PD_LOG_PREFIX, "ID", id);
|
||||||
|
|
||||||
|
pdst = abort_polling ? ls->id_to_pdlv_abort : ls->id_to_pdlv_poll;
|
||||||
|
|
||||||
|
pdst_lock(pdst);
|
||||||
|
|
||||||
|
pdlv = pdst_locked_lookup(pdst, id);
|
||||||
|
if (pdlv) {
|
||||||
|
/*
|
||||||
|
* with store lock held, I'm the only reader accessing the pdlv
|
||||||
|
*/
|
||||||
|
st = pdlv_get_status(pdlv);
|
||||||
|
|
||||||
|
if (st.error || st.polling_finished) {
|
||||||
|
INFO(ls, "%s: %s %s", PD_LOG_PREFIX,
|
||||||
|
"Polling finished. Removing related data structure for LV",
|
||||||
|
lvid);
|
||||||
|
pdst_locked_remove(pdst, id);
|
||||||
|
pdlv_destroy(pdlv);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/* pdlv must not be dereferenced from now on */
|
||||||
|
|
||||||
|
pdst_unlock(pdst);
|
||||||
|
|
||||||
|
dm_free(id);
|
||||||
|
|
||||||
|
if (pdlv) {
|
||||||
|
if (st.error)
|
||||||
|
return reply(LVMPD_RESP_FAILED, REASON_POLLING_FAILED);
|
||||||
|
|
||||||
|
if (st.polling_finished)
|
||||||
|
r = daemon_reply_simple(LVMPD_RESP_FINISHED,
|
||||||
|
"reason = %s", st.cmd_state.signal ? LVMPD_REAS_SIGNAL : LVMPD_REAS_RETCODE,
|
||||||
|
LVMPD_PARM_VALUE " = %d", st.cmd_state.signal ?: st.cmd_state.retcode,
|
||||||
|
NULL);
|
||||||
|
else
|
||||||
|
r = daemon_reply_simple(LVMPD_RESP_IN_PROGRESS, NULL);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
r = daemon_reply_simple(LVMPD_RESP_NOT_FOUND, NULL);
|
||||||
|
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct lvmpolld_lv *construct_pdlv(request req, struct lvmpolld_state *ls,
|
||||||
|
struct lvmpolld_store *pdst,
|
||||||
|
const char *interval, const char *id,
|
||||||
|
const char *vgname, const char *lvname,
|
||||||
|
const char *sysdir, enum poll_type type,
|
||||||
|
unsigned abort_polling, unsigned uinterval)
|
||||||
|
{
|
||||||
|
const char **cmdargv, **cmdenvp;
|
||||||
|
struct lvmpolld_lv *pdlv;
|
||||||
|
unsigned handle_missing_pvs = daemon_request_int(req, LVMPD_PARM_HANDLE_MISSING_PVS, 0);
|
||||||
|
|
||||||
|
pdlv = pdlv_create(ls, id, vgname, lvname, sysdir, type,
|
||||||
|
interval, uinterval, pdst);
|
||||||
|
|
||||||
|
if (!pdlv) {
|
||||||
|
ERROR(ls, "%s: %s", PD_LOG_PREFIX, "failed to create internal LV data structure.");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
cmdargv = cmdargv_ctr(pdlv, pdlv->ls->lvm_binary, abort_polling, handle_missing_pvs);
|
||||||
|
if (!cmdargv) {
|
||||||
|
pdlv_destroy(pdlv);
|
||||||
|
ERROR(ls, "%s: %s", PD_LOG_PREFIX, "failed to construct cmd arguments for lvpoll command");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
cmdenvp = cmdenvp_ctr(pdlv);
|
||||||
|
if (!cmdenvp) {
|
||||||
|
pdlv_destroy(pdlv);
|
||||||
|
ERROR(ls, "%s: %s", PD_LOG_PREFIX, "failed to construct cmd environment for lvpoll command");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
pdlv->cmdargv = cmdargv;
|
||||||
|
pdlv->cmdenvp = cmdenvp;
|
||||||
|
|
||||||
|
return pdlv;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int spawn_detached_thread(struct lvmpolld_lv *pdlv)
|
||||||
|
{
|
||||||
|
int r;
|
||||||
|
pthread_attr_t attr;
|
||||||
|
|
||||||
|
pthread_attr_init(&attr);
|
||||||
|
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
|
||||||
|
|
||||||
|
r = pthread_create(&pdlv->tid, &attr, fork_and_poll, (void *)pdlv);
|
||||||
|
|
||||||
|
pthread_attr_destroy(&attr);
|
||||||
|
|
||||||
|
return !r;
|
||||||
|
}
|
||||||
|
|
||||||
|
static response poll_init(client_handle h, struct lvmpolld_state *ls, request req, enum poll_type type)
|
||||||
|
{
|
||||||
|
char *id;
|
||||||
|
struct lvmpolld_lv *pdlv;
|
||||||
|
struct lvmpolld_store *pdst;
|
||||||
|
unsigned uinterval;
|
||||||
|
|
||||||
|
const char *interval = daemon_request_str(req, LVMPD_PARM_INTERVAL, NULL);
|
||||||
|
const char *lvid = daemon_request_str(req, LVMPD_PARM_LVID, NULL);
|
||||||
|
const char *lvname = daemon_request_str(req, LVMPD_PARM_LVNAME, NULL);
|
||||||
|
const char *vgname = daemon_request_str(req, LVMPD_PARM_VGNAME, NULL);
|
||||||
|
const char *sysdir = daemon_request_str(req, LVMPD_PARM_SYSDIR, NULL);
|
||||||
|
unsigned abort_polling = daemon_request_int(req, LVMPD_PARM_ABORT, 0);
|
||||||
|
|
||||||
|
assert(type < POLL_TYPE_MAX);
|
||||||
|
|
||||||
|
if (abort_polling && type != PVMOVE)
|
||||||
|
return reply(LVMPD_RESP_EINVAL, REASON_ILLEGAL_ABORT_REQUEST);
|
||||||
|
|
||||||
|
if (!interval || strpbrk(interval, "-") || sscanf(interval, "%u", &uinterval) != 1)
|
||||||
|
return reply(LVMPD_RESP_EINVAL, REASON_INVALID_INTERVAL);
|
||||||
|
|
||||||
|
if (!lvname)
|
||||||
|
return reply(LVMPD_RESP_FAILED, REASON_MISSING_LVNAME);
|
||||||
|
|
||||||
|
if (!lvid)
|
||||||
|
return reply(LVMPD_RESP_FAILED, REASON_MISSING_LVID);
|
||||||
|
|
||||||
|
if (!vgname)
|
||||||
|
return reply(LVMPD_RESP_FAILED, REASON_MISSING_VGNAME);
|
||||||
|
|
||||||
|
id = construct_id(sysdir, lvid);
|
||||||
|
if (!id) {
|
||||||
|
ERROR(ls, "%s: %s", PD_LOG_PREFIX, "poll_init request failed to construct ID.");
|
||||||
|
return reply(LVMPD_RESP_FAILED, REASON_ENOMEM);
|
||||||
|
}
|
||||||
|
|
||||||
|
DEBUGLOG(ls, "%s: %s=%s", PD_LOG_PREFIX, "ID", id);
|
||||||
|
|
||||||
|
pdst = abort_polling ? ls->id_to_pdlv_abort : ls->id_to_pdlv_poll;
|
||||||
|
|
||||||
|
pdst_lock(pdst);
|
||||||
|
|
||||||
|
pdlv = pdst_locked_lookup(pdst, id);
|
||||||
|
if (pdlv && pdlv_get_polling_finished(pdlv)) {
|
||||||
|
WARN(ls, "%s: %s %s", PD_LOG_PREFIX, "Force removal of uncollected info for LV",
|
||||||
|
lvid);
|
||||||
|
/*
|
||||||
|
* lvmpolld has to remove uncollected results in this case.
|
||||||
|
* otherwise it would have to refuse request for new polling
|
||||||
|
* lv with same id.
|
||||||
|
*/
|
||||||
|
pdst_locked_remove(pdst, id);
|
||||||
|
pdlv_destroy(pdlv);
|
||||||
|
pdlv = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pdlv) {
|
||||||
|
if (!pdlv_is_type(pdlv, type)) {
|
||||||
|
pdst_unlock(pdst);
|
||||||
|
ERROR(ls, "%s: %s '%s': expected: %s, requested: %s",
|
||||||
|
PD_LOG_PREFIX, "poll operation type mismatch on LV identified by",
|
||||||
|
id,
|
||||||
|
polling_op(pdlv_get_type(pdlv)), polling_op(type));
|
||||||
|
dm_free(id);
|
||||||
|
return reply(LVMPD_RESP_EINVAL,
|
||||||
|
REASON_DIFFERENT_OPERATION_IN_PROGRESS);
|
||||||
|
}
|
||||||
|
pdlv->init_rq_count++; /* safe. protected by store lock */
|
||||||
|
} else {
|
||||||
|
pdlv = construct_pdlv(req, ls, pdst, interval, id, vgname,
|
||||||
|
lvname, sysdir, type, abort_polling, 2 * uinterval);
|
||||||
|
if (!pdlv) {
|
||||||
|
pdst_unlock(pdst);
|
||||||
|
dm_free(id);
|
||||||
|
return reply(LVMPD_RESP_FAILED, REASON_ENOMEM);
|
||||||
|
}
|
||||||
|
if (!pdst_locked_insert(pdst, id, pdlv)) {
|
||||||
|
pdlv_destroy(pdlv);
|
||||||
|
pdst_unlock(pdst);
|
||||||
|
ERROR(ls, "%s: %s", PD_LOG_PREFIX, "couldn't store internal LV data structure");
|
||||||
|
dm_free(id);
|
||||||
|
return reply(LVMPD_RESP_FAILED, REASON_ENOMEM);
|
||||||
|
}
|
||||||
|
if (!spawn_detached_thread(pdlv)) {
|
||||||
|
ERROR(ls, "%s: %s", PD_LOG_PREFIX, "failed to spawn detached monitoring thread");
|
||||||
|
pdst_locked_remove(pdst, id);
|
||||||
|
pdlv_destroy(pdlv);
|
||||||
|
pdst_unlock(pdst);
|
||||||
|
dm_free(id);
|
||||||
|
return reply(LVMPD_RESP_FAILED, REASON_ENOMEM);
|
||||||
|
}
|
||||||
|
|
||||||
|
pdst_locked_inc(pdst);
|
||||||
|
if (ls->idle)
|
||||||
|
ls->idle->is_idle = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
pdst_unlock(pdst);
|
||||||
|
|
||||||
|
dm_free(id);
|
||||||
|
|
||||||
|
return daemon_reply_simple(LVMPD_RESP_OK, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
static response dump_state(client_handle h, struct lvmpolld_state *ls, request r)
|
||||||
|
{
|
||||||
|
response res = { 0 };
|
||||||
|
struct buffer *b = &res.buffer;
|
||||||
|
|
||||||
|
buffer_init(b);
|
||||||
|
|
||||||
|
lvmpolld_global_lock(ls);
|
||||||
|
|
||||||
|
buffer_append(b, "# Registered polling operations\n\n");
|
||||||
|
buffer_append(b, "poll {\n");
|
||||||
|
pdst_locked_dump(ls->id_to_pdlv_poll, b);
|
||||||
|
buffer_append(b, "}\n\n");
|
||||||
|
|
||||||
|
buffer_append(b, "# Registered abort operations\n\n");
|
||||||
|
buffer_append(b, "abort {\n");
|
||||||
|
pdst_locked_dump(ls->id_to_pdlv_abort, b);
|
||||||
|
buffer_append(b, "}\n\n");
|
||||||
|
|
||||||
|
lvmpolld_global_unlock(ls);
|
||||||
|
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
static response handler(struct daemon_state s, client_handle h, request r)
|
||||||
|
{
|
||||||
|
struct lvmpolld_state *ls = s.private;
|
||||||
|
const char *rq = daemon_request_str(r, "request", "NONE");
|
||||||
|
|
||||||
|
if (!strcmp(rq, LVMPD_REQ_PVMOVE))
|
||||||
|
return poll_init(h, ls, r, PVMOVE);
|
||||||
|
else if (!strcmp(rq, LVMPD_REQ_CONVERT))
|
||||||
|
return poll_init(h, ls, r, CONVERT);
|
||||||
|
else if (!strcmp(rq, LVMPD_REQ_MERGE))
|
||||||
|
return poll_init(h, ls, r, MERGE);
|
||||||
|
else if (!strcmp(rq, LVMPD_REQ_MERGE_THIN))
|
||||||
|
return poll_init(h, ls, r, MERGE_THIN);
|
||||||
|
else if (!strcmp(rq, LVMPD_REQ_PROGRESS))
|
||||||
|
return progress_info(h, ls, r);
|
||||||
|
else if (!strcmp(rq, LVMPD_REQ_DUMP))
|
||||||
|
return dump_state(h, ls, r);
|
||||||
|
else
|
||||||
|
return reply(LVMPD_RESP_EINVAL, REASON_REQ_NOT_IMPLEMENTED);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int process_timeout_arg(const char *str, unsigned *max_timeouts)
|
||||||
|
{
|
||||||
|
char *endptr;
|
||||||
|
unsigned long l;
|
||||||
|
|
||||||
|
l = strtoul(str, &endptr, 10);
|
||||||
|
if (errno || *endptr || l >= UINT_MAX)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
*max_timeouts = (unsigned) l;
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(int argc, char *argv[])
|
||||||
|
{
|
||||||
|
signed char opt;
|
||||||
|
struct timeval timeout;
|
||||||
|
daemon_idle di = { .ptimeout = &timeout };
|
||||||
|
struct lvmpolld_state ls = { .log_config = "" };
|
||||||
|
daemon_state s = {
|
||||||
|
.daemon_fini = fini,
|
||||||
|
.daemon_init = init,
|
||||||
|
.handler = handler,
|
||||||
|
.name = "lvmpolld",
|
||||||
|
.pidfile = getenv("LVM_LVMPOLLD_PIDFILE") ?: LVMPOLLD_PIDFILE,
|
||||||
|
.private = &ls,
|
||||||
|
.protocol = LVMPOLLD_PROTOCOL,
|
||||||
|
.protocol_version = LVMPOLLD_PROTOCOL_VERSION,
|
||||||
|
.socket_path = getenv("LVM_LVMPOLLD_SOCKET") ?: LVMPOLLD_SOCKET,
|
||||||
|
};
|
||||||
|
|
||||||
|
while ((opt = getopt(argc, argv, "?fhVl:p:s:B:t:")) != EOF) {
|
||||||
|
switch (opt) {
|
||||||
|
case '?':
|
||||||
|
usage(argv[0], stderr);
|
||||||
|
exit(0);
|
||||||
|
case 'B': /* --binary */
|
||||||
|
ls.lvm_binary = optarg;
|
||||||
|
break;
|
||||||
|
case 'V':
|
||||||
|
printf("lvmpolld version: " LVM_VERSION "\n");
|
||||||
|
exit(1);
|
||||||
|
case 'f':
|
||||||
|
s.foreground = 1;
|
||||||
|
break;
|
||||||
|
case 'h':
|
||||||
|
usage(argv[0], stdout);
|
||||||
|
exit(0);
|
||||||
|
case 'l':
|
||||||
|
ls.log_config = optarg;
|
||||||
|
break;
|
||||||
|
case 'p':
|
||||||
|
s.pidfile = optarg;
|
||||||
|
break;
|
||||||
|
case 's': /* --socket */
|
||||||
|
s.socket_path = optarg;
|
||||||
|
break;
|
||||||
|
case 't': /* --timeout in seconds */
|
||||||
|
if (!process_timeout_arg(optarg, &di.max_timeouts)) {
|
||||||
|
fprintf(stderr, "Invalid value of timeout parameter");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
/* 0 equals to wait indefinitely */
|
||||||
|
if (di.max_timeouts)
|
||||||
|
s.idle = ls.idle = &di;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
daemon_start(s);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
388
daemons/lvmpolld/lvmpolld-data-utils.c
Normal file
388
daemons/lvmpolld/lvmpolld-data-utils.c
Normal file
@ -0,0 +1,388 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2014-2015 Red Hat, Inc.
|
||||||
|
*
|
||||||
|
* This file is part of LVM2.
|
||||||
|
*
|
||||||
|
* This copyrighted material is made available to anyone wishing to use,
|
||||||
|
* modify, copy, or redistribute it subject to the terms and conditions
|
||||||
|
* of the GNU Lesser General Public License v.2.1.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public License
|
||||||
|
* along with this program; if not, write to the Free Software Foundation,
|
||||||
|
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "lvmpolld-common.h"
|
||||||
|
|
||||||
|
#include "config-util.h"
|
||||||
|
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <signal.h>
|
||||||
|
|
||||||
|
static char *_construct_full_lvname(const char *vgname, const char *lvname)
|
||||||
|
{
|
||||||
|
char *name;
|
||||||
|
size_t l;
|
||||||
|
|
||||||
|
l = strlen(vgname) + strlen(lvname) + 2; /* vg/lv and \0 */
|
||||||
|
name = (char *) dm_malloc(l * sizeof(char));
|
||||||
|
if (!name)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
if (dm_snprintf(name, l, "%s/%s", vgname, lvname) < 0) {
|
||||||
|
dm_free(name);
|
||||||
|
name = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
static char *_construct_lvm_system_dir_env(const char *sysdir)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* Store either "LVM_SYSTEM_DIR=/path/to..."
|
||||||
|
* - or -
|
||||||
|
* just single char to store NULL byte
|
||||||
|
*/
|
||||||
|
size_t l = sysdir ? strlen(sysdir) + 16 : 1;
|
||||||
|
char *env = (char *) dm_malloc(l * sizeof(char));
|
||||||
|
|
||||||
|
if (!env)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
*env = '\0';
|
||||||
|
|
||||||
|
if (sysdir && dm_snprintf(env, l, "LVM_SYSTEM_DIR=%s", sysdir) < 0) {
|
||||||
|
dm_free(env);
|
||||||
|
env = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return env;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const char *_get_lvid(const char *lvmpolld_id, const char *sysdir)
|
||||||
|
{
|
||||||
|
return lvmpolld_id ? (lvmpolld_id + (sysdir ? strlen(sysdir) : 0)) : NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
char *construct_id(const char *sysdir, const char *uuid)
|
||||||
|
{
|
||||||
|
char *id;
|
||||||
|
int r;
|
||||||
|
size_t l;
|
||||||
|
|
||||||
|
l = strlen(uuid) + (sysdir ? strlen(sysdir) : 0) + 1;
|
||||||
|
id = (char *) dm_malloc(l * sizeof(char));
|
||||||
|
if (!id)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
r = sysdir ? dm_snprintf(id, l, "%s%s", sysdir, uuid) :
|
||||||
|
dm_snprintf(id, l, "%s", uuid);
|
||||||
|
|
||||||
|
if (r < 0) {
|
||||||
|
dm_free(id);
|
||||||
|
id = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct lvmpolld_lv *pdlv_create(struct lvmpolld_state *ls, const char *id,
|
||||||
|
const char *vgname, const char *lvname,
|
||||||
|
const char *sysdir, enum poll_type type,
|
||||||
|
const char *sinterval, unsigned pdtimeout,
|
||||||
|
struct lvmpolld_store *pdst)
|
||||||
|
{
|
||||||
|
char *lvmpolld_id = dm_strdup(id), /* copy */
|
||||||
|
*full_lvname = _construct_full_lvname(vgname, lvname), /* copy */
|
||||||
|
*lvm_system_dir_env = _construct_lvm_system_dir_env(sysdir); /* copy */
|
||||||
|
|
||||||
|
struct lvmpolld_lv tmp = {
|
||||||
|
.ls = ls,
|
||||||
|
.type = type,
|
||||||
|
.lvmpolld_id = lvmpolld_id,
|
||||||
|
.lvid = _get_lvid(lvmpolld_id, sysdir),
|
||||||
|
.lvname = full_lvname,
|
||||||
|
.lvm_system_dir_env = lvm_system_dir_env,
|
||||||
|
.sinterval = dm_strdup(sinterval), /* copy */
|
||||||
|
.pdtimeout = pdtimeout < MIN_POLLING_TIMEOUT ? MIN_POLLING_TIMEOUT : pdtimeout,
|
||||||
|
.cmd_state = { .retcode = -1, .signal = 0 },
|
||||||
|
.pdst = pdst,
|
||||||
|
.init_rq_count = 1
|
||||||
|
}, *pdlv = (struct lvmpolld_lv *) dm_malloc(sizeof(struct lvmpolld_lv));
|
||||||
|
|
||||||
|
if (!pdlv || !tmp.lvid || !tmp.lvname || !tmp.lvm_system_dir_env || !tmp.sinterval)
|
||||||
|
goto err;
|
||||||
|
|
||||||
|
memcpy(pdlv, &tmp, sizeof(*pdlv));
|
||||||
|
|
||||||
|
if (pthread_mutex_init(&pdlv->lock, NULL))
|
||||||
|
goto err;
|
||||||
|
|
||||||
|
return pdlv;
|
||||||
|
|
||||||
|
err:
|
||||||
|
dm_free((void *)full_lvname);
|
||||||
|
dm_free((void *)lvmpolld_id);
|
||||||
|
dm_free((void *)lvm_system_dir_env);
|
||||||
|
dm_free((void *)tmp.sinterval);
|
||||||
|
dm_free((void *)pdlv);
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
void pdlv_destroy(struct lvmpolld_lv *pdlv)
|
||||||
|
{
|
||||||
|
dm_free((void *)pdlv->lvmpolld_id);
|
||||||
|
dm_free((void *)pdlv->lvname);
|
||||||
|
dm_free((void *)pdlv->sinterval);
|
||||||
|
dm_free((void *)pdlv->lvm_system_dir_env);
|
||||||
|
dm_free((void *)pdlv->cmdargv);
|
||||||
|
dm_free((void *)pdlv->cmdenvp);
|
||||||
|
|
||||||
|
pthread_mutex_destroy(&pdlv->lock);
|
||||||
|
|
||||||
|
dm_free((void *)pdlv);
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned pdlv_get_polling_finished(struct lvmpolld_lv *pdlv)
|
||||||
|
{
|
||||||
|
unsigned ret;
|
||||||
|
|
||||||
|
pdlv_lock(pdlv);
|
||||||
|
ret = pdlv->polling_finished;
|
||||||
|
pdlv_unlock(pdlv);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct lvmpolld_lv_state pdlv_get_status(struct lvmpolld_lv *pdlv)
|
||||||
|
{
|
||||||
|
struct lvmpolld_lv_state r;
|
||||||
|
|
||||||
|
pdlv_lock(pdlv);
|
||||||
|
r.error = pdlv_locked_error(pdlv);
|
||||||
|
r.polling_finished = pdlv_locked_polling_finished(pdlv);
|
||||||
|
r.cmd_state = pdlv_locked_cmd_state(pdlv);
|
||||||
|
pdlv_unlock(pdlv);
|
||||||
|
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
void pdlv_set_cmd_state(struct lvmpolld_lv *pdlv, const struct lvmpolld_cmd_stat *cmd_state)
|
||||||
|
{
|
||||||
|
pdlv_lock(pdlv);
|
||||||
|
pdlv->cmd_state = *cmd_state;
|
||||||
|
pdlv_unlock(pdlv);
|
||||||
|
}
|
||||||
|
|
||||||
|
void pdlv_set_error(struct lvmpolld_lv *pdlv, unsigned error)
|
||||||
|
{
|
||||||
|
pdlv_lock(pdlv);
|
||||||
|
pdlv->error = error;
|
||||||
|
pdlv_unlock(pdlv);
|
||||||
|
}
|
||||||
|
|
||||||
|
void pdlv_set_polling_finished(struct lvmpolld_lv *pdlv, unsigned finished)
|
||||||
|
{
|
||||||
|
pdlv_lock(pdlv);
|
||||||
|
pdlv->polling_finished = finished;
|
||||||
|
pdlv_unlock(pdlv);
|
||||||
|
}
|
||||||
|
|
||||||
|
struct lvmpolld_store *pdst_init(const char *name)
|
||||||
|
{
|
||||||
|
struct lvmpolld_store *pdst = (struct lvmpolld_store *) dm_malloc(sizeof(struct lvmpolld_store));
|
||||||
|
if (!pdst)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
pdst->store = dm_hash_create(32);
|
||||||
|
if (!pdst->store)
|
||||||
|
goto err_hash;
|
||||||
|
if (pthread_mutex_init(&pdst->lock, NULL))
|
||||||
|
goto err_mutex;
|
||||||
|
|
||||||
|
pdst->name = name;
|
||||||
|
|
||||||
|
return pdst;
|
||||||
|
|
||||||
|
err_mutex:
|
||||||
|
dm_hash_destroy(pdst->store);
|
||||||
|
err_hash:
|
||||||
|
dm_free(pdst);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
void pdst_destroy(struct lvmpolld_store *pdst)
|
||||||
|
{
|
||||||
|
if (!pdst)
|
||||||
|
return;
|
||||||
|
|
||||||
|
dm_hash_destroy(pdst->store);
|
||||||
|
pthread_mutex_destroy(&pdst->lock);
|
||||||
|
dm_free(pdst);
|
||||||
|
}
|
||||||
|
|
||||||
|
void pdst_locked_lock_all_pdlvs(const struct lvmpolld_store *pdst)
|
||||||
|
{
|
||||||
|
struct dm_hash_node *n;
|
||||||
|
|
||||||
|
dm_hash_iterate(n, pdst->store)
|
||||||
|
pdlv_lock(dm_hash_get_data(pdst->store, n));
|
||||||
|
}
|
||||||
|
|
||||||
|
void pdst_locked_unlock_all_pdlvs(const struct lvmpolld_store *pdst)
|
||||||
|
{
|
||||||
|
struct dm_hash_node *n;
|
||||||
|
|
||||||
|
dm_hash_iterate(n, pdst->store)
|
||||||
|
pdlv_unlock(dm_hash_get_data(pdst->store, n));
|
||||||
|
}
|
||||||
|
|
||||||
|
static void _pdlv_locked_dump(struct buffer *buff, const struct lvmpolld_lv *pdlv)
|
||||||
|
{
|
||||||
|
char tmp[1024];
|
||||||
|
const struct lvmpolld_cmd_stat *cmd_state = &pdlv->cmd_state;
|
||||||
|
|
||||||
|
/* pdlv-section { */
|
||||||
|
if (dm_snprintf(tmp, sizeof(tmp), "\t%s {\n", pdlv->lvmpolld_id) > 0)
|
||||||
|
buffer_append(buff, tmp);
|
||||||
|
|
||||||
|
if (dm_snprintf(tmp, sizeof(tmp), "\t\tlvid=\"%s\"\n", pdlv->lvid) > 0)
|
||||||
|
buffer_append(buff, tmp);
|
||||||
|
if (dm_snprintf(tmp, sizeof(tmp), "\t\ttype=\"%s\"\n", polling_op(pdlv->type)) > 0)
|
||||||
|
buffer_append(buff, tmp);
|
||||||
|
if (dm_snprintf(tmp, sizeof(tmp), "\t\tlvname=\"%s\"\n", pdlv->lvname) > 0)
|
||||||
|
buffer_append(buff, tmp);
|
||||||
|
if (dm_snprintf(tmp, sizeof(tmp), "\t\tlvmpolld_internal_timeout=%d\n", pdlv->pdtimeout) > 0)
|
||||||
|
buffer_append(buff, tmp);
|
||||||
|
if (dm_snprintf(tmp, sizeof(tmp), "\t\tlvm_command_interval=\"%s\"\n", pdlv->sinterval ?: "<undefined>") > 0)
|
||||||
|
buffer_append(buff, tmp);
|
||||||
|
if (dm_snprintf(tmp, sizeof(tmp), "\t\tLVM_SYSTEM_DIR=\"%s\"\n",
|
||||||
|
(*pdlv->lvm_system_dir_env ? (pdlv->lvm_system_dir_env + strlen("LVM_SYSTEM_DIR=")) : "<undefined>")) > 0)
|
||||||
|
buffer_append(buff, tmp);
|
||||||
|
if (dm_snprintf(tmp, sizeof(tmp), "\t\tlvm_command_pid=%d\n", pdlv->cmd_pid) > 0)
|
||||||
|
buffer_append(buff, tmp);
|
||||||
|
if (dm_snprintf(tmp, sizeof(tmp), "\t\tpolling_finished=%d\n", pdlv->polling_finished) > 0)
|
||||||
|
buffer_append(buff, tmp);
|
||||||
|
if (dm_snprintf(tmp, sizeof(tmp), "\t\terror_occured=%d\n", pdlv->error) > 0)
|
||||||
|
buffer_append(buff, tmp);
|
||||||
|
if (dm_snprintf(tmp, sizeof(tmp), "\t\tinit_requests_count=%d\n", pdlv->init_rq_count) > 0)
|
||||||
|
buffer_append(buff, tmp);
|
||||||
|
|
||||||
|
/* lvm_commmand-section { */
|
||||||
|
buffer_append(buff, "\t\tlvm_command {\n");
|
||||||
|
if (cmd_state->retcode == -1 && !cmd_state->signal)
|
||||||
|
buffer_append(buff, "\t\t\tstate=\"" LVMPD_RESP_IN_PROGRESS "\"\n");
|
||||||
|
else {
|
||||||
|
buffer_append(buff, "\t\t\tstate=\"" LVMPD_RESP_FINISHED "\"\n");
|
||||||
|
if (dm_snprintf(tmp, sizeof(tmp), "\t\t\treason=\"%s\"\n\t\t\tvalue=%d\n",
|
||||||
|
(cmd_state->signal ? LVMPD_REAS_SIGNAL : LVMPD_REAS_RETCODE),
|
||||||
|
(cmd_state->signal ?: cmd_state->retcode)) > 0)
|
||||||
|
buffer_append(buff, tmp);
|
||||||
|
}
|
||||||
|
buffer_append(buff, "\t\t}\n");
|
||||||
|
/* } lvm_commmand-section */
|
||||||
|
|
||||||
|
buffer_append(buff, "\t}\n");
|
||||||
|
/* } pdlv-section */
|
||||||
|
}
|
||||||
|
|
||||||
|
void pdst_locked_dump(const struct lvmpolld_store *pdst, struct buffer *buff)
|
||||||
|
{
|
||||||
|
struct dm_hash_node *n;
|
||||||
|
|
||||||
|
dm_hash_iterate(n, pdst->store)
|
||||||
|
_pdlv_locked_dump(buff, dm_hash_get_data(pdst->store, n));
|
||||||
|
}
|
||||||
|
|
||||||
|
void pdst_locked_send_cancel(const struct lvmpolld_store *pdst)
|
||||||
|
{
|
||||||
|
struct lvmpolld_lv *pdlv;
|
||||||
|
struct dm_hash_node *n;
|
||||||
|
|
||||||
|
dm_hash_iterate(n, pdst->store) {
|
||||||
|
pdlv = dm_hash_get_data(pdst->store, n);
|
||||||
|
if (!pdlv_locked_polling_finished(pdlv))
|
||||||
|
pthread_cancel(pdlv->tid);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void pdst_locked_destroy_all_pdlvs(const struct lvmpolld_store *pdst)
|
||||||
|
{
|
||||||
|
struct dm_hash_node *n;
|
||||||
|
|
||||||
|
dm_hash_iterate(n, pdst->store)
|
||||||
|
pdlv_destroy(dm_hash_get_data(pdst->store, n));
|
||||||
|
}
|
||||||
|
|
||||||
|
struct lvmpolld_thread_data *lvmpolld_thread_data_constructor(struct lvmpolld_lv *pdlv)
|
||||||
|
{
|
||||||
|
struct lvmpolld_thread_data *data = (struct lvmpolld_thread_data *) dm_malloc(sizeof(struct lvmpolld_thread_data));
|
||||||
|
if (!data)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
data->pdlv = NULL;
|
||||||
|
data->line = NULL;
|
||||||
|
data->fout = data->ferr = NULL;
|
||||||
|
data->outpipe[0] = data->outpipe[1] = data->errpipe[0] = data->errpipe[1] = -1;
|
||||||
|
|
||||||
|
if (pipe(data->outpipe) || pipe(data->errpipe)) {
|
||||||
|
lvmpolld_thread_data_destroy(data);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fcntl(data->outpipe[0], F_SETFD, FD_CLOEXEC) ||
|
||||||
|
fcntl(data->outpipe[1], F_SETFD, FD_CLOEXEC) ||
|
||||||
|
fcntl(data->errpipe[0], F_SETFD, FD_CLOEXEC) ||
|
||||||
|
fcntl(data->errpipe[1], F_SETFD, FD_CLOEXEC)) {
|
||||||
|
lvmpolld_thread_data_destroy(data);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
data->pdlv = pdlv;
|
||||||
|
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
|
void lvmpolld_thread_data_destroy(void *thread_private)
|
||||||
|
{
|
||||||
|
struct lvmpolld_thread_data *data = (struct lvmpolld_thread_data *) thread_private;
|
||||||
|
if (!data)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (data->pdlv) {
|
||||||
|
pdst_lock(data->pdlv->pdst);
|
||||||
|
/*
|
||||||
|
* FIXME: skip this step if lvmpolld is activated
|
||||||
|
* by systemd.
|
||||||
|
*/
|
||||||
|
if (!pdlv_get_polling_finished(data->pdlv))
|
||||||
|
kill(data->pdlv->cmd_pid, SIGTERM);
|
||||||
|
pdlv_set_polling_finished(data->pdlv, 1);
|
||||||
|
pdst_locked_dec(data->pdlv->pdst);
|
||||||
|
pdst_unlock(data->pdlv->pdst);
|
||||||
|
}
|
||||||
|
|
||||||
|
dm_free(data->line);
|
||||||
|
|
||||||
|
if (data->fout && !fclose(data->fout))
|
||||||
|
data->outpipe[0] = -1;
|
||||||
|
|
||||||
|
if (data->ferr && !fclose(data->ferr))
|
||||||
|
data->errpipe[0] = -1;
|
||||||
|
|
||||||
|
if (data->outpipe[0] >= 0)
|
||||||
|
close(data->outpipe[0]);
|
||||||
|
|
||||||
|
if (data->outpipe[1] >= 0)
|
||||||
|
close(data->outpipe[1]);
|
||||||
|
|
||||||
|
if (data->errpipe[0] >= 0)
|
||||||
|
close(data->errpipe[0]);
|
||||||
|
|
||||||
|
if (data->errpipe[1] >= 0)
|
||||||
|
close(data->errpipe[1]);
|
||||||
|
|
||||||
|
dm_free(data);
|
||||||
|
}
|
215
daemons/lvmpolld/lvmpolld-data-utils.h
Normal file
215
daemons/lvmpolld/lvmpolld-data-utils.h
Normal file
@ -0,0 +1,215 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2014-2015 Red Hat, Inc.
|
||||||
|
*
|
||||||
|
* This file is part of LVM2.
|
||||||
|
*
|
||||||
|
* This copyrighted material is made available to anyone wishing to use,
|
||||||
|
* modify, copy, or redistribute it subject to the terms and conditions
|
||||||
|
* of the GNU Lesser General Public License v.2.1.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public License
|
||||||
|
* along with this program; if not, write to the Free Software Foundation,
|
||||||
|
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _LVM_LVMPOLLD_DATA_UTILS_H
|
||||||
|
#define _LVM_LVMPOLLD_DATA_UTILS_H
|
||||||
|
|
||||||
|
#include <pthread.h>
|
||||||
|
|
||||||
|
struct buffer;
|
||||||
|
struct lvmpolld_state;
|
||||||
|
|
||||||
|
enum poll_type {
|
||||||
|
PVMOVE = 0,
|
||||||
|
CONVERT,
|
||||||
|
MERGE,
|
||||||
|
MERGE_THIN,
|
||||||
|
POLL_TYPE_MAX
|
||||||
|
};
|
||||||
|
|
||||||
|
struct lvmpolld_cmd_stat {
|
||||||
|
int retcode;
|
||||||
|
int signal;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct lvmpolld_store {
|
||||||
|
pthread_mutex_t lock;
|
||||||
|
void *store;
|
||||||
|
const char *name;
|
||||||
|
unsigned active_polling_count;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct lvmpolld_lv {
|
||||||
|
/*
|
||||||
|
* accessing following vars doesn't
|
||||||
|
* require struct lvmpolld_lv lock
|
||||||
|
*/
|
||||||
|
struct lvmpolld_state *const ls;
|
||||||
|
const enum poll_type type;
|
||||||
|
const char *const lvid;
|
||||||
|
const char *const lvmpolld_id;
|
||||||
|
const char *const lvname; /* full vg/lv name */
|
||||||
|
const unsigned pdtimeout; /* in seconds */
|
||||||
|
const char *const sinterval;
|
||||||
|
const char *const lvm_system_dir_env;
|
||||||
|
struct lvmpolld_store *const pdst;
|
||||||
|
const char *const *cmdargv;
|
||||||
|
const char *const *cmdenvp;
|
||||||
|
|
||||||
|
/* only used by write */
|
||||||
|
pid_t cmd_pid;
|
||||||
|
pthread_t tid;
|
||||||
|
|
||||||
|
pthread_mutex_t lock;
|
||||||
|
|
||||||
|
/* block of shared variables protected by lock */
|
||||||
|
struct lvmpolld_cmd_stat cmd_state;
|
||||||
|
unsigned init_rq_count; /* for debuging purposes only */
|
||||||
|
unsigned polling_finished:1; /* no more updates */
|
||||||
|
unsigned error:1; /* unrecoverable error occured in lvmpolld */
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef void (*lvmpolld_parse_output_fn_t) (struct lvmpolld_lv *pdlv, const char *line);
|
||||||
|
|
||||||
|
/* TODO: replace with configuration option */
|
||||||
|
#define MIN_POLLING_TIMEOUT 60
|
||||||
|
|
||||||
|
struct lvmpolld_lv_state {
|
||||||
|
unsigned error:1;
|
||||||
|
unsigned polling_finished:1;
|
||||||
|
struct lvmpolld_cmd_stat cmd_state;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct lvmpolld_thread_data {
|
||||||
|
char *line;
|
||||||
|
size_t line_size;
|
||||||
|
int outpipe[2];
|
||||||
|
int errpipe[2];
|
||||||
|
FILE *fout;
|
||||||
|
FILE *ferr;
|
||||||
|
char buf[1024];
|
||||||
|
struct lvmpolld_lv *pdlv;
|
||||||
|
};
|
||||||
|
|
||||||
|
char *construct_id(const char *sysdir, const char *lvid);
|
||||||
|
|
||||||
|
/* LVMPOLLD_LV_T section */
|
||||||
|
|
||||||
|
/* only call with appropriate struct lvmpolld_store lock held */
|
||||||
|
struct lvmpolld_lv *pdlv_create(struct lvmpolld_state *ls, const char *id,
|
||||||
|
const char *vgname, const char *lvname,
|
||||||
|
const char *sysdir, enum poll_type type,
|
||||||
|
const char *sinterval, unsigned pdtimeout,
|
||||||
|
struct lvmpolld_store *pdst);
|
||||||
|
|
||||||
|
/* only call with appropriate struct lvmpolld_store lock held */
|
||||||
|
void pdlv_destroy(struct lvmpolld_lv *pdlv);
|
||||||
|
|
||||||
|
static inline void pdlv_lock(struct lvmpolld_lv *pdlv)
|
||||||
|
{
|
||||||
|
pthread_mutex_lock(&pdlv->lock);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void pdlv_unlock(struct lvmpolld_lv *pdlv)
|
||||||
|
{
|
||||||
|
pthread_mutex_unlock(&pdlv->lock);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* no struct lvmpolld_lv lock required section
|
||||||
|
*/
|
||||||
|
static inline int pdlv_is_type(const struct lvmpolld_lv *pdlv, enum poll_type type)
|
||||||
|
{
|
||||||
|
return pdlv->type == type;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline unsigned pdlv_get_timeout(const struct lvmpolld_lv *pdlv)
|
||||||
|
{
|
||||||
|
return pdlv->pdtimeout;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline enum poll_type pdlv_get_type(const struct lvmpolld_lv *pdlv)
|
||||||
|
{
|
||||||
|
return pdlv->type;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned pdlv_get_polling_finished(struct lvmpolld_lv *pdlv);
|
||||||
|
struct lvmpolld_lv_state pdlv_get_status(struct lvmpolld_lv *pdlv);
|
||||||
|
void pdlv_set_cmd_state(struct lvmpolld_lv *pdlv, const struct lvmpolld_cmd_stat *cmd_state);
|
||||||
|
void pdlv_set_error(struct lvmpolld_lv *pdlv, unsigned error);
|
||||||
|
void pdlv_set_polling_finished(struct lvmpolld_lv *pdlv, unsigned finished);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* struct lvmpolld_lv lock required section
|
||||||
|
*/
|
||||||
|
static inline struct lvmpolld_cmd_stat pdlv_locked_cmd_state(const struct lvmpolld_lv *pdlv)
|
||||||
|
{
|
||||||
|
return pdlv->cmd_state;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline int pdlv_locked_polling_finished(const struct lvmpolld_lv *pdlv)
|
||||||
|
{
|
||||||
|
return pdlv->polling_finished;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline unsigned pdlv_locked_error(const struct lvmpolld_lv *pdlv)
|
||||||
|
{
|
||||||
|
return pdlv->error;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* struct lvmpolld_store manipulation routines */
|
||||||
|
|
||||||
|
struct lvmpolld_store *pdst_init(const char *name);
|
||||||
|
void pdst_destroy(struct lvmpolld_store *pdst);
|
||||||
|
|
||||||
|
void pdst_locked_dump(const struct lvmpolld_store *pdst, struct buffer *buff);
|
||||||
|
void pdst_locked_lock_all_pdlvs(const struct lvmpolld_store *pdst);
|
||||||
|
void pdst_locked_unlock_all_pdlvs(const struct lvmpolld_store *pdst);
|
||||||
|
void pdst_locked_destroy_all_pdlvs(const struct lvmpolld_store *pdst);
|
||||||
|
void pdst_locked_send_cancel(const struct lvmpolld_store *pdst);
|
||||||
|
|
||||||
|
static inline void pdst_lock(struct lvmpolld_store *pdst)
|
||||||
|
{
|
||||||
|
pthread_mutex_lock(&pdst->lock);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void pdst_unlock(struct lvmpolld_store *pdst)
|
||||||
|
{
|
||||||
|
pthread_mutex_unlock(&pdst->lock);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void pdst_locked_inc(struct lvmpolld_store *pdst)
|
||||||
|
{
|
||||||
|
pdst->active_polling_count++;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void pdst_locked_dec(struct lvmpolld_store *pdst)
|
||||||
|
{
|
||||||
|
pdst->active_polling_count--;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline unsigned pdst_locked_get_active_count(const struct lvmpolld_store *pdst)
|
||||||
|
{
|
||||||
|
return pdst->active_polling_count;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline int pdst_locked_insert(struct lvmpolld_store *pdst, const char *key, struct lvmpolld_lv *pdlv)
|
||||||
|
{
|
||||||
|
return dm_hash_insert(pdst->store, key, pdlv);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline struct lvmpolld_lv *pdst_locked_lookup(struct lvmpolld_store *pdst, const char *key)
|
||||||
|
{
|
||||||
|
return dm_hash_lookup(pdst->store, key);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void pdst_locked_remove(struct lvmpolld_store *pdst, const char *key)
|
||||||
|
{
|
||||||
|
dm_hash_remove(pdst->store, key);
|
||||||
|
}
|
||||||
|
|
||||||
|
struct lvmpolld_thread_data *lvmpolld_thread_data_constructor(struct lvmpolld_lv *pdlv);
|
||||||
|
void lvmpolld_thread_data_destroy(void *thread_private);
|
||||||
|
|
||||||
|
#endif /* _LVM_LVMPOLLD_DATA_UTILS_H */
|
49
daemons/lvmpolld/lvmpolld-protocol.h
Normal file
49
daemons/lvmpolld/lvmpolld-protocol.h
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2015 Red Hat, Inc.
|
||||||
|
*
|
||||||
|
* This file is part of LVM2.
|
||||||
|
*
|
||||||
|
* This copyrighted material is made available to anyone wishing to use,
|
||||||
|
* modify, copy, or redistribute it subject to the terms and conditions
|
||||||
|
* of the GNU Lesser General Public License v.2.1.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public License
|
||||||
|
* along with this program; if not, write to the Free Software Foundation,
|
||||||
|
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _LVM_LVMPOLLD_PROTOCOL_H
|
||||||
|
#define _LVM_LVMPOLLD_PROTOCOL_H
|
||||||
|
|
||||||
|
#include "polling_ops.h"
|
||||||
|
|
||||||
|
#define LVMPOLLD_PROTOCOL "lvmpolld"
|
||||||
|
#define LVMPOLLD_PROTOCOL_VERSION 1
|
||||||
|
|
||||||
|
#define LVMPD_REQ_CONVERT CONVERT_POLL
|
||||||
|
#define LVMPD_REQ_DUMP "dump"
|
||||||
|
#define LVMPD_REQ_MERGE MERGE_POLL
|
||||||
|
#define LVMPD_REQ_MERGE_THIN MERGE_THIN_POLL
|
||||||
|
#define LVMPD_REQ_PROGRESS "progress_info"
|
||||||
|
#define LVMPD_REQ_PVMOVE PVMOVE_POLL
|
||||||
|
|
||||||
|
#define LVMPD_PARM_ABORT "abort"
|
||||||
|
#define LVMPD_PARM_HANDLE_MISSING_PVS "handle_missing_pvs"
|
||||||
|
#define LVMPD_PARM_INTERVAL "interval"
|
||||||
|
#define LVMPD_PARM_LVID "lvid"
|
||||||
|
#define LVMPD_PARM_LVNAME "lvname"
|
||||||
|
#define LVMPD_PARM_SYSDIR "sysdir"
|
||||||
|
#define LVMPD_PARM_VALUE "value" /* either retcode or signal value */
|
||||||
|
#define LVMPD_PARM_VGNAME "vgname"
|
||||||
|
|
||||||
|
#define LVMPD_RESP_FAILED "failed"
|
||||||
|
#define LVMPD_RESP_FINISHED "finished"
|
||||||
|
#define LVMPD_RESP_IN_PROGRESS "in_progress"
|
||||||
|
#define LVMPD_RESP_EINVAL "invalid"
|
||||||
|
#define LVMPD_RESP_NOT_FOUND "not_found"
|
||||||
|
#define LVMPD_RESP_OK "OK"
|
||||||
|
|
||||||
|
#define LVMPD_REAS_RETCODE "retcode" /* lvm cmd ret code */
|
||||||
|
#define LVMPD_REAS_SIGNAL "signal" /* lvm cmd terminating singal */
|
||||||
|
|
||||||
|
#endif /* _LVM_LVMPOLLD_PROTOCOL_H */
|
25
daemons/lvmpolld/polling_ops.h
Normal file
25
daemons/lvmpolld/polling_ops.h
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2014-2015 Red Hat, Inc. All rights reserved.
|
||||||
|
*
|
||||||
|
* This file is part of LVM2.
|
||||||
|
*
|
||||||
|
* This copyrighted material is made available to anyone wishing to use,
|
||||||
|
* modify, copy, or redistribute it subject to the terms and conditions
|
||||||
|
* of the GNU Lesser General Public License v.2.1.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public License
|
||||||
|
* along with this program; if not, write to the Free Software Foundation,
|
||||||
|
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _LVM_TOOL_POLLING_OPS_H
|
||||||
|
#define _LVM_TOOL_POLLING_OPS_H
|
||||||
|
|
||||||
|
/* this file is also part of lvmpolld protocol */
|
||||||
|
|
||||||
|
#define PVMOVE_POLL "pvmove"
|
||||||
|
#define CONVERT_POLL "convert"
|
||||||
|
#define MERGE_POLL "merge"
|
||||||
|
#define MERGE_THIN_POLL "merge_thin"
|
||||||
|
|
||||||
|
#endif /* _LVM_TOOL_POLLING_OPS_H */
|
81
doc/lvmpolld_overview.txt
Normal file
81
doc/lvmpolld_overview.txt
Normal file
@ -0,0 +1,81 @@
|
|||||||
|
LVM poll daemon overview
|
||||||
|
========================
|
||||||
|
|
||||||
|
(last updated: 2015-05-09)
|
||||||
|
|
||||||
|
LVM poll daemon (lvmpolld) is the alternative for lvm2 classical polling
|
||||||
|
mechanisms. The motivation behind new lvmpolld was to create persistent
|
||||||
|
system service that would be more durable and transparent. It's suited
|
||||||
|
particularly for any systemd enabled distribution.
|
||||||
|
|
||||||
|
Before lvmpolld any background polling process originating in a lvm2 command
|
||||||
|
initiated inside cgroup of a systemd service could get killed if the main
|
||||||
|
process (service) exited in such cgroup. That could lead to premature termination
|
||||||
|
of such lvm2 polling process.
|
||||||
|
|
||||||
|
Also without lvmpolld there were no means to detect a particular polling process
|
||||||
|
suited for monitoring of specific operation is already in-progress and therefore
|
||||||
|
it's not desirable to start next one with exactly same task. lvmpolld is able to
|
||||||
|
detect such duplicate requests and not spawn such redundant process.
|
||||||
|
|
||||||
|
lvmpolld is primarily targeted for systems with systemd as init process. For systems
|
||||||
|
without systemd there's no need to install lvmpolld because there is no issue
|
||||||
|
with observation described in second paragraph. You can still benefit from
|
||||||
|
avoiding duplicate polling process being spawned, but without systemd lvmpolld
|
||||||
|
can't easily be run on-demand (activated by a socket maintained by systemd).
|
||||||
|
|
||||||
|
lvmpolld implement shutdown on idle and can shutdown automatically when idle
|
||||||
|
for requested time. 60 second is recommended default here. This behaviour can be
|
||||||
|
turned off if found useless.
|
||||||
|
|
||||||
|
Data structures
|
||||||
|
---------------
|
||||||
|
|
||||||
|
a) Logical Volume (struct lvmpolld_lv)
|
||||||
|
|
||||||
|
Each operation is identified by LV. Internal identifier within lvmpolld
|
||||||
|
is full LV uuid (vg_uuid+lv_uuid) prefixed with LVM_SYSTEM_DIR if set by client.
|
||||||
|
|
||||||
|
such full identifier may look like:
|
||||||
|
|
||||||
|
"/etc/lvm/lvm.confWFd2dU67S8Av29IcJCnYzqQirdfElnxzhCdzEh7EJrfCn9R1TIQjIj58weUZDre4"
|
||||||
|
|
||||||
|
or without LVM_SYSTEM_DIR being set explicitly:
|
||||||
|
|
||||||
|
"WFd2dU67S8Av29IcJCnYzqQirdfElnxzhCdzEh7EJrfCn9R1TIQjIj58weUZDre4"
|
||||||
|
|
||||||
|
|
||||||
|
LV carries various metadata about polling operation. The most significant are:
|
||||||
|
|
||||||
|
VG name
|
||||||
|
LV name
|
||||||
|
polling interval (usually --interval passed to lvm2 command or default from lvm2
|
||||||
|
configuration)
|
||||||
|
operation type (one of: pvmove, convert, merge, thin_merge)
|
||||||
|
LVM_SYSTEM_DIR (if set, this is also passed among environment variables of lvpoll
|
||||||
|
command spawned by lvmpolld)
|
||||||
|
|
||||||
|
b) LV stores (struct lvmpolld_store)
|
||||||
|
|
||||||
|
lvmpolld uses two stores for Logical volumes (struct lvmpolld_lv). One store for polling
|
||||||
|
operations in-progress. These operations are as of now: PV move, mirror up-conversion,
|
||||||
|
classical snapshot merge, thin snapshot merge.
|
||||||
|
|
||||||
|
The second store is suited only for pvmove --abort operations in-progress. Both
|
||||||
|
stores are independent and identical LVs (pvmove /dev/sda3 and pvmove --abort /dev/sda3)
|
||||||
|
can be run concurently from lvmpolld point of view (on lvm2 side the consistency is
|
||||||
|
guaranteed by lvm2 locking mechanism).
|
||||||
|
|
||||||
|
Locking order
|
||||||
|
-------------
|
||||||
|
|
||||||
|
There are two types of locks in lvmpolld. Each store has own store lock and each LV has
|
||||||
|
own lv lock.
|
||||||
|
|
||||||
|
Locking order is:
|
||||||
|
1) store lock
|
||||||
|
2) LV lock
|
||||||
|
|
||||||
|
Each LV has to be inside a store. When daemon requires to take both locks it has
|
||||||
|
to take a store lock first and LV lock has to be taken afterwards (after the
|
||||||
|
appropriate store lock where the LV is being stored :))
|
@ -1,6 +1,8 @@
|
|||||||
@top_srcdir@/daemons/clvmd/clvm.h
|
@top_srcdir@/daemons/clvmd/clvm.h
|
||||||
@top_srcdir@/daemons/dmeventd/libdevmapper-event.h
|
@top_srcdir@/daemons/dmeventd/libdevmapper-event.h
|
||||||
@top_srcdir@/daemons/lvmetad/lvmetad-client.h
|
@top_srcdir@/daemons/lvmetad/lvmetad-client.h
|
||||||
|
@top_srcdir@/daemons/lvmpolld/lvmpolld-protocol.h
|
||||||
|
@top_srcdir@/daemons/lvmpolld/polling_ops.h
|
||||||
@top_srcdir@/liblvm/lvm2app.h
|
@top_srcdir@/liblvm/lvm2app.h
|
||||||
@top_srcdir@/lib/activate/activate.h
|
@top_srcdir@/lib/activate/activate.h
|
||||||
@top_srcdir@/lib/activate/targets.h
|
@top_srcdir@/lib/activate/targets.h
|
||||||
@ -29,6 +31,8 @@
|
|||||||
@top_srcdir@/lib/locking/locking.h
|
@top_srcdir@/lib/locking/locking.h
|
||||||
@top_srcdir@/lib/log/log.h
|
@top_srcdir@/lib/log/log.h
|
||||||
@top_srcdir@/lib/log/lvm-logging.h
|
@top_srcdir@/lib/log/lvm-logging.h
|
||||||
|
@top_srcdir@/lib/lvmpolld/lvmpolld-client.h
|
||||||
|
@top_srcdir@/lib/lvmpolld/polldaemon.h
|
||||||
@top_srcdir@/lib/metadata/lv.h
|
@top_srcdir@/lib/metadata/lv.h
|
||||||
@top_srcdir@/lib/metadata/lv_alloc.h
|
@top_srcdir@/lib/metadata/lv_alloc.h
|
||||||
@top_srcdir@/lib/metadata/metadata.h
|
@top_srcdir@/lib/metadata/metadata.h
|
||||||
|
@ -196,6 +196,11 @@ ifeq ("@BUILD_LVMETAD@", "yes")
|
|||||||
cache/lvmetad.c
|
cache/lvmetad.c
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
ifeq ("@BUILD_LVMPOLLD@", "yes")
|
||||||
|
SOURCES +=\
|
||||||
|
lvmpolld/lvmpolld-client.c
|
||||||
|
endif
|
||||||
|
|
||||||
ifeq ("@DMEVENTD@", "yes")
|
ifeq ("@DMEVENTD@", "yes")
|
||||||
CLDFLAGS += -L$(top_builddir)/daemons/dmeventd
|
CLDFLAGS += -L$(top_builddir)/daemons/dmeventd
|
||||||
LIBS += -ldevmapper-event
|
LIBS += -ldevmapper-event
|
||||||
|
@ -30,6 +30,7 @@
|
|||||||
#include "lvmcache.h"
|
#include "lvmcache.h"
|
||||||
#include "lvmetad.h"
|
#include "lvmetad.h"
|
||||||
#include "archiver.h"
|
#include "archiver.h"
|
||||||
|
#include "lvmpolld-client.h"
|
||||||
|
|
||||||
#ifdef HAVE_LIBDL
|
#ifdef HAVE_LIBDL
|
||||||
#include "sharedlib.h"
|
#include "sharedlib.h"
|
||||||
@ -475,6 +476,7 @@ static int _process_config(struct cmd_context *cmd)
|
|||||||
const struct dm_config_value *cv;
|
const struct dm_config_value *cv;
|
||||||
int64_t pv_min_kb;
|
int64_t pv_min_kb;
|
||||||
const char *lvmetad_socket;
|
const char *lvmetad_socket;
|
||||||
|
const char *lvmpolld_socket;
|
||||||
int udev_disabled = 0;
|
int udev_disabled = 0;
|
||||||
char sysfs_dir[PATH_MAX];
|
char sysfs_dir[PATH_MAX];
|
||||||
|
|
||||||
@ -618,6 +620,7 @@ static int _process_config(struct cmd_context *cmd)
|
|||||||
(find_config_tree_bool(cmd, global_detect_internal_vg_cache_corruption_CFG, NULL));
|
(find_config_tree_bool(cmd, global_detect_internal_vg_cache_corruption_CFG, NULL));
|
||||||
|
|
||||||
lvmetad_disconnect();
|
lvmetad_disconnect();
|
||||||
|
lvmpolld_disconnect();
|
||||||
|
|
||||||
lvmetad_socket = getenv("LVM_LVMETAD_SOCKET");
|
lvmetad_socket = getenv("LVM_LVMETAD_SOCKET");
|
||||||
if (!lvmetad_socket)
|
if (!lvmetad_socket)
|
||||||
@ -644,6 +647,13 @@ static int _process_config(struct cmd_context *cmd)
|
|||||||
if (!_init_system_id(cmd))
|
if (!_init_system_id(cmd))
|
||||||
return_0;
|
return_0;
|
||||||
|
|
||||||
|
lvmpolld_socket = getenv("LVM_LVMPOLLD_SOCKET");
|
||||||
|
if (!lvmpolld_socket)
|
||||||
|
lvmpolld_socket = DEFAULT_RUN_DIR "/lvmpolld.socket";
|
||||||
|
lvmpolld_set_socket(lvmpolld_socket);
|
||||||
|
|
||||||
|
lvmpolld_set_active(find_config_tree_bool(cmd, global_use_lvmpolld_CFG, NULL));
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2065,6 +2075,7 @@ void destroy_toolcontext(struct cmd_context *cmd)
|
|||||||
|
|
||||||
lvmetad_release_token();
|
lvmetad_release_token();
|
||||||
lvmetad_disconnect();
|
lvmetad_disconnect();
|
||||||
|
lvmpolld_disconnect();
|
||||||
|
|
||||||
release_log_memory();
|
release_log_memory();
|
||||||
activation_exit();
|
activation_exit();
|
||||||
|
@ -920,6 +920,15 @@ cfg(activation_checks_CFG, "checks", activation_CFG_SECTION, 0, CFG_TYPE_BOOL, D
|
|||||||
"Some of the checks may be expensive, so it's best to use\n"
|
"Some of the checks may be expensive, so it's best to use\n"
|
||||||
"this only when there seems to be a problem.\n")
|
"this only when there seems to be a problem.\n")
|
||||||
|
|
||||||
|
cfg(global_use_lvmpolld_CFG, "use_lvmpolld", global_CFG_SECTION, 0, CFG_TYPE_BOOL, 0, vsn(2, 2, 120), NULL, 0, NULL,
|
||||||
|
"Indicates whether to use lvmpolld instead of classical polldaemon (a process\n"
|
||||||
|
"forked off an initiating lvm command) or not. When set to 1 and native systemd\n"
|
||||||
|
"service is installed in the system lvm starts using lvmpolld. lvmpolld gets\n"
|
||||||
|
"auto-activated by systemd when a message lands on the respective lvmpolld socket.\n"
|
||||||
|
"All commands that would require polling of in-progress operation are therefore\n"
|
||||||
|
"spawned in lvmpolld's service cgroup.\n"
|
||||||
|
"When set to 0 lvm falls back to classical polling.\n")
|
||||||
|
|
||||||
cfg(activation_udev_sync_CFG, "udev_sync", activation_CFG_SECTION, 0, CFG_TYPE_BOOL, DEFAULT_UDEV_SYNC, vsn(2, 2, 51), NULL, 0, NULL,
|
cfg(activation_udev_sync_CFG, "udev_sync", activation_CFG_SECTION, 0, CFG_TYPE_BOOL, DEFAULT_UDEV_SYNC, vsn(2, 2, 51), NULL, 0, NULL,
|
||||||
"Use udev notifications to synchronize udev and LVM.\n"
|
"Use udev notifications to synchronize udev and LVM.\n"
|
||||||
"When disabled, LVM commands will not wait for notifications\n"
|
"When disabled, LVM commands will not wait for notifications\n"
|
||||||
|
311
lib/lvmpolld/lvmpolld-client.c
Normal file
311
lib/lvmpolld/lvmpolld-client.c
Normal file
@ -0,0 +1,311 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2015 Red Hat, Inc.
|
||||||
|
*
|
||||||
|
* This file is part of LVM2.
|
||||||
|
*
|
||||||
|
* This copyrighted material is made available to anyone wishing to use,
|
||||||
|
* modify, copy, or redistribute it subject to the terms and conditions
|
||||||
|
* of the GNU Lesser General Public License v.2.1.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public License
|
||||||
|
* along with this program; if not, write to the Free Software Foundation,
|
||||||
|
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "lib.h"
|
||||||
|
|
||||||
|
#include "daemon-io.h"
|
||||||
|
#include "lvmpolld-client.h"
|
||||||
|
#include "lvmpolld-protocol.h"
|
||||||
|
#include "metadata-exported.h"
|
||||||
|
#include "polldaemon.h"
|
||||||
|
#include "toolcontext.h"
|
||||||
|
|
||||||
|
struct progress_info {
|
||||||
|
unsigned error:1;
|
||||||
|
unsigned finished:1;
|
||||||
|
int cmd_signal;
|
||||||
|
int cmd_retcode;
|
||||||
|
};
|
||||||
|
|
||||||
|
static int _lvmpolld_use;
|
||||||
|
static int _lvmpolld_connected;
|
||||||
|
static const char* _lvmpolld_socket;
|
||||||
|
|
||||||
|
static daemon_handle _lvmpolld = { .error = 0 };
|
||||||
|
|
||||||
|
static daemon_handle _lvmpolld_connect(const char *socket)
|
||||||
|
{
|
||||||
|
daemon_info lvmpolld_info = {
|
||||||
|
.path = "lvmpolld",
|
||||||
|
.socket = socket ?: LVMPOLLD_SOCKET,
|
||||||
|
.protocol = LVMPOLLD_PROTOCOL,
|
||||||
|
.protocol_version = LVMPOLLD_PROTOCOL_VERSION
|
||||||
|
};
|
||||||
|
|
||||||
|
return daemon_open(lvmpolld_info);
|
||||||
|
}
|
||||||
|
|
||||||
|
void lvmpolld_set_active(int active)
|
||||||
|
{
|
||||||
|
_lvmpolld_use = active;
|
||||||
|
}
|
||||||
|
|
||||||
|
void lvmpolld_set_socket(const char *socket)
|
||||||
|
{
|
||||||
|
_lvmpolld_socket = socket;
|
||||||
|
}
|
||||||
|
|
||||||
|
int lvmpolld_use(void)
|
||||||
|
{
|
||||||
|
if (!_lvmpolld_use)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if (!_lvmpolld_connected && !_lvmpolld.error) {
|
||||||
|
_lvmpolld = _lvmpolld_connect(_lvmpolld_socket);
|
||||||
|
_lvmpolld_connected = _lvmpolld.socket_fd >= 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return _lvmpolld_connected;
|
||||||
|
}
|
||||||
|
|
||||||
|
void lvmpolld_disconnect(void)
|
||||||
|
{
|
||||||
|
if (_lvmpolld_connected) {
|
||||||
|
daemon_close(_lvmpolld);
|
||||||
|
_lvmpolld_connected = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void _process_error_response(daemon_reply rep)
|
||||||
|
{
|
||||||
|
if (!strcmp(daemon_reply_str(rep, "response", ""), LVMPD_RESP_FAILED))
|
||||||
|
log_error("lvmpolld failed to process a request. The reason was: %s.",
|
||||||
|
daemon_reply_str(rep, "reason", "<empty>"));
|
||||||
|
else if (!strcmp(daemon_reply_str(rep, "response", ""), LVMPD_RESP_EINVAL))
|
||||||
|
log_error("lvmpolld couldn't handle a request. "
|
||||||
|
"It might be due to daemon internal state. The reason was: %s.",
|
||||||
|
daemon_reply_str(rep, "reason", "<empty>"));
|
||||||
|
else
|
||||||
|
log_error("Unexpected response %s. The reason: %s.",
|
||||||
|
daemon_reply_str(rep, "response", "<empty>"),
|
||||||
|
daemon_reply_str(rep, "reason", "<empty>"));
|
||||||
|
|
||||||
|
log_print_unless_silent("For more detailed information see lvmpolld log file.");
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct progress_info _request_progress_info(const char *uuid, unsigned abort_polling)
|
||||||
|
{
|
||||||
|
daemon_reply rep;
|
||||||
|
const char *e = getenv("LVM_SYSTEM_DIR");
|
||||||
|
struct progress_info ret = { .error = 1, .finished = 1 };
|
||||||
|
daemon_request req = daemon_request_make(LVMPD_REQ_PROGRESS);
|
||||||
|
|
||||||
|
if (!daemon_request_extend(req, LVMPD_PARM_LVID " = %s", uuid, NULL)) {
|
||||||
|
log_error("Failed to create " LVMPD_REQ_PROGRESS " request.");
|
||||||
|
goto out_req;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (abort_polling &&
|
||||||
|
!daemon_request_extend(req, LVMPD_PARM_ABORT " = %d", abort_polling, NULL)) {
|
||||||
|
log_error("Failed to create " LVMPD_REQ_PROGRESS " request.");
|
||||||
|
goto out_req;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (e &&
|
||||||
|
!(daemon_request_extend(req, LVMPD_PARM_SYSDIR " = %s",
|
||||||
|
e, NULL))) {
|
||||||
|
log_error("Failed to create " LVMPD_REQ_PROGRESS " request.");
|
||||||
|
goto out_req;
|
||||||
|
}
|
||||||
|
|
||||||
|
rep = daemon_send(_lvmpolld, req);
|
||||||
|
if (rep.error) {
|
||||||
|
log_error("Failed to process request with error %s (errno: %d).",
|
||||||
|
strerror(rep.error), rep.error);
|
||||||
|
goto out_rep;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!strcmp(daemon_reply_str(rep, "response", ""), LVMPD_RESP_IN_PROGRESS)) {
|
||||||
|
ret.finished = 0;
|
||||||
|
ret.error = 0;
|
||||||
|
} else if (!strcmp(daemon_reply_str(rep, "response", ""), LVMPD_RESP_FINISHED)) {
|
||||||
|
if (!strcmp(daemon_reply_str(rep, "reason", ""), LVMPD_REAS_SIGNAL))
|
||||||
|
ret.cmd_signal = daemon_reply_int(rep, LVMPD_PARM_VALUE, 0);
|
||||||
|
else
|
||||||
|
ret.cmd_retcode = daemon_reply_int(rep, LVMPD_PARM_VALUE, -1);
|
||||||
|
ret.error = 0;
|
||||||
|
} else if (!strcmp(daemon_reply_str(rep, "response", ""), LVMPD_RESP_NOT_FOUND)) {
|
||||||
|
log_verbose("No polling operation in progress regarding LV %s.", uuid);
|
||||||
|
ret.error = 0;
|
||||||
|
} else {
|
||||||
|
_process_error_response(rep);
|
||||||
|
stack;
|
||||||
|
}
|
||||||
|
|
||||||
|
out_rep:
|
||||||
|
daemon_reply_destroy(rep);
|
||||||
|
out_req:
|
||||||
|
daemon_request_destroy(req);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* interval in seconds long
|
||||||
|
* enough for more than a year
|
||||||
|
* of waiting
|
||||||
|
*/
|
||||||
|
#define INTERV_SIZE 10
|
||||||
|
|
||||||
|
static int _process_poll_init(const struct cmd_context *cmd, const char *poll_type,
|
||||||
|
const struct poll_operation_id *id, const struct daemon_parms *parms)
|
||||||
|
{
|
||||||
|
char *str;
|
||||||
|
daemon_reply rep;
|
||||||
|
daemon_request req;
|
||||||
|
const char *e = getenv("LVM_SYSTEM_DIR");
|
||||||
|
int r = 0;
|
||||||
|
|
||||||
|
str = dm_malloc(INTERV_SIZE * sizeof(char));
|
||||||
|
if (!str)
|
||||||
|
return r;
|
||||||
|
|
||||||
|
if (snprintf(str, INTERV_SIZE, "%u", parms->interval) >= INTERV_SIZE) {
|
||||||
|
log_warn("Interval string conversion got truncated.");
|
||||||
|
str[INTERV_SIZE - 1] = '\0';
|
||||||
|
}
|
||||||
|
|
||||||
|
req = daemon_request_make(poll_type);
|
||||||
|
if (!daemon_request_extend(req, LVMPD_PARM_LVID " = %s", id->uuid,
|
||||||
|
LVMPD_PARM_VGNAME " = %s", id->vg_name,
|
||||||
|
LVMPD_PARM_LVNAME " = %s", id->lv_name,
|
||||||
|
LVMPD_PARM_INTERVAL " = %s", str,
|
||||||
|
"cmdline = %s", cmd->cmd_line, /* FIXME: debug param only */
|
||||||
|
NULL)) {
|
||||||
|
log_error("Failed to create %s request.", poll_type);
|
||||||
|
goto out_req;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (parms->aborting &&
|
||||||
|
!(daemon_request_extend(req, LVMPD_PARM_ABORT " = %d", parms->aborting, NULL))) {
|
||||||
|
log_error("Failed to create %s request." , poll_type);
|
||||||
|
goto out_req;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cmd->handles_missing_pvs &&
|
||||||
|
!(daemon_request_extend(req, LVMPD_PARM_HANDLE_MISSING_PVS " = %d",
|
||||||
|
cmd->handles_missing_pvs, NULL))) {
|
||||||
|
log_error("Failed to create %s request." , poll_type);
|
||||||
|
goto out_req;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (e &&
|
||||||
|
!(daemon_request_extend(req, LVMPD_PARM_SYSDIR " = %s",
|
||||||
|
e, NULL))) {
|
||||||
|
log_error("Failed to create %s request." , poll_type);
|
||||||
|
goto out_req;
|
||||||
|
}
|
||||||
|
|
||||||
|
rep = daemon_send(_lvmpolld, req);
|
||||||
|
|
||||||
|
if (rep.error) {
|
||||||
|
log_error("Failed to process request with error %s (errno: %d).",
|
||||||
|
strerror(rep.error), rep.error);
|
||||||
|
goto out_rep;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!strcmp(daemon_reply_str(rep, "response", ""), LVMPD_RESP_OK))
|
||||||
|
r = 1;
|
||||||
|
else {
|
||||||
|
_process_error_response(rep);
|
||||||
|
stack;
|
||||||
|
}
|
||||||
|
|
||||||
|
out_rep:
|
||||||
|
daemon_reply_destroy(rep);
|
||||||
|
out_req:
|
||||||
|
daemon_request_destroy(req);
|
||||||
|
dm_free(str);
|
||||||
|
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
int lvmpolld_poll_init(const struct cmd_context *cmd, const struct poll_operation_id *id,
|
||||||
|
const struct daemon_parms *parms)
|
||||||
|
{
|
||||||
|
int r = 0;
|
||||||
|
|
||||||
|
if (!id->uuid) {
|
||||||
|
log_error(INTERNAL_ERROR "Use of lvmpolld requires uuid set");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!id->vg_name) {
|
||||||
|
log_error(INTERNAL_ERROR "Use of lvmpolld requires vgname set");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!id->lv_name) {
|
||||||
|
log_error(INTERNAL_ERROR "Use of lvmpolld requires lvname set");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (parms->lv_type & PVMOVE) {
|
||||||
|
log_verbose("lvmpolld: Requesting pvmove%s", parms->aborting ? " abort." : ".");
|
||||||
|
r = _process_poll_init(cmd, LVMPD_REQ_PVMOVE, id, parms);
|
||||||
|
} else if (parms->lv_type & CONVERTING) {
|
||||||
|
log_verbose("lvmpolld: Requesting convert mirror.");
|
||||||
|
r = _process_poll_init(cmd, LVMPD_REQ_CONVERT, id, parms);
|
||||||
|
} else if (parms->lv_type & MERGING) {
|
||||||
|
if (parms->lv_type & SNAPSHOT) {
|
||||||
|
log_verbose("lvmpolld: Requesting snapshot merge.");
|
||||||
|
r = _process_poll_init(cmd, LVMPD_REQ_MERGE, id, parms);
|
||||||
|
}
|
||||||
|
else if (parms->lv_type & THIN_VOLUME) {
|
||||||
|
log_verbose("lvmpolld: Thin snapshot merge.");
|
||||||
|
r = _process_poll_init(cmd, LVMPD_REQ_MERGE_THIN, id, parms);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
log_error(INTERNAL_ERROR "Unsupported poll operation.");
|
||||||
|
}
|
||||||
|
} else
|
||||||
|
log_error(INTERNAL_ERROR "Unsupported poll operation");
|
||||||
|
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
int lvmpolld_request_info(const struct poll_operation_id *id, const struct daemon_parms *parms, unsigned *finished)
|
||||||
|
{
|
||||||
|
struct progress_info info;
|
||||||
|
int ret = 0;
|
||||||
|
|
||||||
|
*finished = 1;
|
||||||
|
|
||||||
|
if (!id->uuid) {
|
||||||
|
log_error(INTERNAL_ERROR "use of lvmpolld requires uuid being set");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
info = _request_progress_info(id->uuid, parms->aborting);
|
||||||
|
*finished = info.finished;
|
||||||
|
|
||||||
|
if (info.error)
|
||||||
|
return_0;
|
||||||
|
|
||||||
|
if (info.finished) {
|
||||||
|
if (info.cmd_signal)
|
||||||
|
log_error("Polling command got terminated by signal (%d).",
|
||||||
|
info.cmd_signal);
|
||||||
|
else if (info.cmd_retcode)
|
||||||
|
log_error("Polling command exited with return code: %d.",
|
||||||
|
info.cmd_retcode);
|
||||||
|
else {
|
||||||
|
log_verbose("Polling finished successfully.");
|
||||||
|
ret = 1;
|
||||||
|
}
|
||||||
|
} else
|
||||||
|
ret = 1;
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
52
lib/lvmpolld/lvmpolld-client.h
Normal file
52
lib/lvmpolld/lvmpolld-client.h
Normal file
@ -0,0 +1,52 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2014-2015 Red Hat, Inc.
|
||||||
|
*
|
||||||
|
* This file is part of LVM2.
|
||||||
|
*
|
||||||
|
* This copyrighted material is made available to anyone wishing to use,
|
||||||
|
* modify, copy, or redistribute it subject to the terms and conditions
|
||||||
|
* of the GNU Lesser General Public License v.2.1.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public License
|
||||||
|
* along with this program; if not, write to the Free Software Foundation,
|
||||||
|
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _LVM_LVMPOLLD_CLIENT_H
|
||||||
|
#define _LVM_LVMPOLLD_CLIENT_H
|
||||||
|
# ifdef LVMPOLLD_SUPPORT
|
||||||
|
|
||||||
|
# include "daemon-client.h"
|
||||||
|
|
||||||
|
# define LVMPOLLD_SOCKET DEFAULT_RUN_DIR "/lvmpolld.socket"
|
||||||
|
|
||||||
|
struct cmd_context;
|
||||||
|
struct poll_operation_id;
|
||||||
|
struct daemon_parms;
|
||||||
|
|
||||||
|
void lvmpolld_disconnect(void);
|
||||||
|
|
||||||
|
int lvmpolld_poll_init(const struct cmd_context *cmd, const struct poll_operation_id *id,
|
||||||
|
const struct daemon_parms *parms);
|
||||||
|
|
||||||
|
int lvmpolld_request_info(const struct poll_operation_id *id, const struct daemon_parms *parms,
|
||||||
|
unsigned *finished);
|
||||||
|
|
||||||
|
int lvmpolld_use(void);
|
||||||
|
|
||||||
|
void lvmpolld_set_active(int active);
|
||||||
|
|
||||||
|
void lvmpolld_set_socket(const char *socket);
|
||||||
|
|
||||||
|
# else
|
||||||
|
|
||||||
|
# define lvmpolld_disconnect() do {} while (0)
|
||||||
|
# define lvmpolld_poll_init(cmd, id, parms) (0)
|
||||||
|
# define lvmpolld_request_info(id, parms, finished) (0)
|
||||||
|
# define lvmpolld_use() (0)
|
||||||
|
# define lvmpolld_set_active(active) do {} while (0)
|
||||||
|
# define lvmpolld_set_socket(socket) do {} while (0)
|
||||||
|
|
||||||
|
# endif /* LVMPOLLD_SUPPORT */
|
||||||
|
|
||||||
|
#endif /* _LVM_LVMPOLLD_CLIENT_H */
|
@ -500,6 +500,12 @@
|
|||||||
/* Define to 1 to include code that uses lvmetad. */
|
/* Define to 1 to include code that uses lvmetad. */
|
||||||
#undef LVMETAD_SUPPORT
|
#undef LVMETAD_SUPPORT
|
||||||
|
|
||||||
|
/* Path to lvmpolld pidfile. */
|
||||||
|
#undef LVMPOLLD_PIDFILE
|
||||||
|
|
||||||
|
/* Define to 1 to include code that uses lvmpolld. */
|
||||||
|
#undef LVMPOLLD_SUPPORT
|
||||||
|
|
||||||
/* Path to lvm binary. */
|
/* Path to lvm binary. */
|
||||||
#undef LVM_PATH
|
#undef LVM_PATH
|
||||||
|
|
||||||
|
@ -19,7 +19,7 @@ top_builddir = @top_builddir@
|
|||||||
|
|
||||||
SUBDIRS += client
|
SUBDIRS += client
|
||||||
|
|
||||||
ifeq ("@BUILD_LVMETAD@", "yes")
|
ifeq (yes, $(shell test @BUILD_LVMETAD@ == yes -o @BUILD_LVMPOLLD@ == yes && echo yes))
|
||||||
SUBDIRS += server
|
SUBDIRS += server
|
||||||
server: client
|
server: client
|
||||||
endif
|
endif
|
||||||
|
@ -491,7 +491,7 @@ distclean: cleandir $(SUBDIRS.distclean)
|
|||||||
echo " local:"; echo " *;"; echo "};") > $@
|
echo " local:"; echo " *;"; echo "};") > $@
|
||||||
|
|
||||||
ifeq (,$(findstring $(MAKECMDGOALS),cscope.out cflow clean distclean lcov \
|
ifeq (,$(findstring $(MAKECMDGOALS),cscope.out cflow clean distclean lcov \
|
||||||
help check check_local check_cluster check_lvmetad))
|
help check check_local check_cluster check_lvmetad check_lvmpolld))
|
||||||
ifdef SOURCES
|
ifdef SOURCES
|
||||||
-include $(SOURCES:.c=.d) $(CXXSOURCES:.cpp=.d)
|
-include $(SOURCES:.c=.d) $(CXXSOURCES:.cpp=.d)
|
||||||
endif
|
endif
|
||||||
|
@ -40,6 +40,12 @@ else
|
|||||||
LVMETAD =
|
LVMETAD =
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
ifeq ("@BUILD_LVMPOLLD@", "yes")
|
||||||
|
LVMPOLLD = lvmpolld.8
|
||||||
|
else
|
||||||
|
LVMPOLLD =
|
||||||
|
endif
|
||||||
|
|
||||||
MAN5=lvm.conf.5
|
MAN5=lvm.conf.5
|
||||||
MAN7=lvmsystemid.7
|
MAN7=lvmsystemid.7
|
||||||
MAN8=lvm-config.8 lvm-dumpconfig.8 \
|
MAN8=lvm-config.8 lvm-dumpconfig.8 \
|
||||||
@ -50,7 +56,7 @@ MAN8=lvm-config.8 lvm-dumpconfig.8 \
|
|||||||
pvresize.8 pvs.8 pvscan.8 vgcfgbackup.8 vgcfgrestore.8 vgchange.8 \
|
pvresize.8 pvs.8 pvscan.8 vgcfgbackup.8 vgcfgrestore.8 vgchange.8 \
|
||||||
vgck.8 vgcreate.8 vgconvert.8 vgdisplay.8 vgexport.8 vgextend.8 \
|
vgck.8 vgcreate.8 vgconvert.8 vgdisplay.8 vgexport.8 vgextend.8 \
|
||||||
vgimport.8 vgimportclone.8 vgmerge.8 vgmknodes.8 vgreduce.8 vgremove.8 \
|
vgimport.8 vgimportclone.8 vgmerge.8 vgmknodes.8 vgreduce.8 vgremove.8 \
|
||||||
vgrename.8 vgs.8 vgscan.8 vgsplit.8 $(FSADMMAN) $(LVMETAD)
|
vgrename.8 vgs.8 vgscan.8 vgsplit.8 $(FSADMMAN) $(LVMETAD) $(LVMPOLLD)
|
||||||
|
|
||||||
ifneq ("@CLVMD@", "none")
|
ifneq ("@CLVMD@", "none")
|
||||||
MAN8CLUSTER=clvmd.8
|
MAN8CLUSTER=clvmd.8
|
||||||
|
@ -525,6 +525,12 @@ Path for the lvmetad pid file.
|
|||||||
.TP
|
.TP
|
||||||
.B LVM_LVMETAD_SOCKET
|
.B LVM_LVMETAD_SOCKET
|
||||||
Path for the lvmetad socket file.
|
Path for the lvmetad socket file.
|
||||||
|
.TP
|
||||||
|
.B LVM_LVMPOLLD_PIDFILE
|
||||||
|
Path for the lvmpolld pid file.
|
||||||
|
.TP
|
||||||
|
.B LVM_LVMPOLLD_SOCKET
|
||||||
|
Path for the lvmpolld socket file.
|
||||||
.SH FILES
|
.SH FILES
|
||||||
.I #DEFAULT_SYS_DIR#/lvm.conf
|
.I #DEFAULT_SYS_DIR#/lvm.conf
|
||||||
.br
|
.br
|
||||||
|
86
man/lvmpolld.8.in
Normal file
86
man/lvmpolld.8.in
Normal file
@ -0,0 +1,86 @@
|
|||||||
|
.TH LVMETAD 8 "LVM TOOLS #VERSION#" "Red Hat Inc" \" -*- nroff -*-
|
||||||
|
.SH NAME
|
||||||
|
lvmpolld \(em LVM poll daemon
|
||||||
|
.SH SYNOPSIS
|
||||||
|
.B lvmpolld
|
||||||
|
.RB [ \-l
|
||||||
|
.RI { all | wire | debug }]
|
||||||
|
.RB [ \-p
|
||||||
|
.IR pidfile_path ]
|
||||||
|
.RB [ \-s
|
||||||
|
.IR socket_path ]
|
||||||
|
.RB [ \-B
|
||||||
|
.IR lvm_binary_path ]
|
||||||
|
.RB [ \-t
|
||||||
|
.IR timeout_value ]
|
||||||
|
.RB [ \-f ]
|
||||||
|
.RB [ \-h ]
|
||||||
|
.RB [ \-V ]
|
||||||
|
.RB [ \-? ]
|
||||||
|
.SH DESCRIPTION
|
||||||
|
lvmpolld is polling daemon for LVM. The daemon receives requests for polling
|
||||||
|
of already initialised operations originating in LVM2 command line tool.
|
||||||
|
The requests for polling originates in \fBlvconvert\fP, \fBpvmove\fP,
|
||||||
|
\fBlvchange\fP or \fBvgchange\fP LVM2 command.
|
||||||
|
|
||||||
|
The purpose of lvmpolld is to reduce the number of spawned background processes
|
||||||
|
per otherwise unique polling operation. There should be only one. It also eliminates
|
||||||
|
the possibility of unsolicited termination of background process by external factors.
|
||||||
|
|
||||||
|
lvmpolld is used by LVM only if it is enabled in \fBlvm.conf\fP(5) by specifying the
|
||||||
|
\fBglobal/use_lvmpolld\fP setting. If this is not defined in the LVM configuration
|
||||||
|
explicitly then default setting is used instead (see the output of
|
||||||
|
\fBlvmconfig \-\-type default global/use_lvmpolld\fP command).
|
||||||
|
.SH OPTIONS
|
||||||
|
|
||||||
|
To run the daemon in a test environment both the pidfile_path and the
|
||||||
|
socket_path should be changed from the defaults.
|
||||||
|
.TP
|
||||||
|
.B \-f
|
||||||
|
Don't fork, but run in the foreground.
|
||||||
|
.TP
|
||||||
|
.BR \-h ", " \-?
|
||||||
|
Show help information.
|
||||||
|
.TP
|
||||||
|
.IR \fB\-l " {" all | wire | debug }
|
||||||
|
Select the type of log messages to generate.
|
||||||
|
Messages are logged by syslog.
|
||||||
|
Additionally, when \-f is given they are also sent to standard error.
|
||||||
|
There are two classes of messages: wire and debug. Selecting 'all' supplies both
|
||||||
|
and is equivalent to a comma-separated list \-l wire,debug.
|
||||||
|
.TP
|
||||||
|
.B \-p \fIpidfile_path
|
||||||
|
Path to the pidfile. This overrides both the built-in default
|
||||||
|
(#DEFAULT_PID_DIR#/lvmpolld.pid) and the environment variable
|
||||||
|
\fBLVM_LVMPOLLD_PIDFILE\fP. This file is used to prevent more
|
||||||
|
than one instance of the daemon running simultaneously.
|
||||||
|
.TP
|
||||||
|
.B \-s \fIsocket_path
|
||||||
|
Path to the socket file. This overrides both the built-in default
|
||||||
|
(#DEFAULT_RUN_DIR#/lvmpolld.socket) and the environment variable
|
||||||
|
\fBLVM_LVMPOLLD_SOCKET\fP.
|
||||||
|
.TP
|
||||||
|
.B \-t \fItimeout_value
|
||||||
|
When runs as native systemd service daemon may shutdown after being
|
||||||
|
idle for the given time (in seconds). When the option is omitted or
|
||||||
|
the value given is zero the daemon never shutdowns on idle. When
|
||||||
|
the daemon doesn't run as native systemd service the timeout is
|
||||||
|
ignored and never shutdowns on idle.
|
||||||
|
.TP
|
||||||
|
.B \-B \fIlvm_binary_path
|
||||||
|
Optional path to alternative LVM binary (default: #LVM_PATH#). Use for
|
||||||
|
testing purposes only.
|
||||||
|
.TP
|
||||||
|
.B \-V
|
||||||
|
Display the version of lvmpolld daemon.
|
||||||
|
.SH ENVIRONMENT VARIABLES
|
||||||
|
.TP
|
||||||
|
.B LVM_LVMPOLLD_PIDFILE
|
||||||
|
Path for the pid file.
|
||||||
|
.TP
|
||||||
|
.B LVM_LVMPOLLD_SOCKET
|
||||||
|
Path for the socket file.
|
||||||
|
|
||||||
|
.SH SEE ALSO
|
||||||
|
.BR lvm (8),
|
||||||
|
.BR lvm.conf (5)
|
3
scripts/.gitignore
vendored
3
scripts/.gitignore
vendored
@ -4,6 +4,9 @@ dm_event_systemd_red_hat.service
|
|||||||
lvm2_lvmetad_init_red_hat
|
lvm2_lvmetad_init_red_hat
|
||||||
lvm2_lvmetad_systemd_red_hat.service
|
lvm2_lvmetad_systemd_red_hat.service
|
||||||
lvm2_lvmetad_systemd_red_hat.socket
|
lvm2_lvmetad_systemd_red_hat.socket
|
||||||
|
lvm2_lvmpolld_init_red_hat
|
||||||
|
lvm2_lvmpolld_systemd_red_hat.service
|
||||||
|
lvm2_lvmpolld_systemd_red_hat.socket
|
||||||
lvm2_monitoring_init_red_hat
|
lvm2_monitoring_init_red_hat
|
||||||
lvm2_monitoring_systemd_red_hat.service
|
lvm2_monitoring_systemd_red_hat.service
|
||||||
lvm2_tmpfiles_red_hat.conf
|
lvm2_tmpfiles_red_hat.conf
|
||||||
|
@ -75,6 +75,9 @@ endif
|
|||||||
ifeq ("@BUILD_LVMETAD@", "yes")
|
ifeq ("@BUILD_LVMETAD@", "yes")
|
||||||
$(INSTALL_SCRIPT) lvm2_lvmetad_init_red_hat $(initdir)/lvm2-lvmetad
|
$(INSTALL_SCRIPT) lvm2_lvmetad_init_red_hat $(initdir)/lvm2-lvmetad
|
||||||
endif
|
endif
|
||||||
|
ifeq ("@BUILD_LVMPOLLD@", "yes")
|
||||||
|
$(INSTALL_SCRIPT) lvm2_lvmpolld_init_red_hat $(initdir)/lvm2-lvmpolld
|
||||||
|
endif
|
||||||
ifneq ("@CLVMD@", "none")
|
ifneq ("@CLVMD@", "none")
|
||||||
$(INSTALL_SCRIPT) clvmd_init_red_hat $(initdir)/clvmd
|
$(INSTALL_SCRIPT) clvmd_init_red_hat $(initdir)/clvmd
|
||||||
endif
|
endif
|
||||||
@ -114,6 +117,10 @@ ifeq ("@BUILD_LVMETAD@", "yes")
|
|||||||
$(INSTALL_DATA) lvm2_lvmetad_systemd_red_hat.service $(systemd_unit_dir)/lvm2-lvmetad.service
|
$(INSTALL_DATA) lvm2_lvmetad_systemd_red_hat.service $(systemd_unit_dir)/lvm2-lvmetad.service
|
||||||
$(INSTALL_DATA) lvm2_pvscan_systemd_red_hat@.service $(systemd_unit_dir)/lvm2-pvscan@.service
|
$(INSTALL_DATA) lvm2_pvscan_systemd_red_hat@.service $(systemd_unit_dir)/lvm2-pvscan@.service
|
||||||
endif
|
endif
|
||||||
|
ifeq ("@BUILD_LVMPOLLD@", "yes")
|
||||||
|
$(INSTALL_DATA) lvm2_lvmpolld_systemd_red_hat.socket $(systemd_unit_dir)/lvm2-lvmpolld.socket
|
||||||
|
$(INSTALL_DATA) lvm2_lvmpolld_systemd_red_hat.service $(systemd_unit_dir)/lvm2-lvmpolld.service
|
||||||
|
endif
|
||||||
ifneq ("@CLVMD@", "none")
|
ifneq ("@CLVMD@", "none")
|
||||||
$(INSTALL_DATA) lvm2_clvmd_systemd_red_hat.service $(systemd_unit_dir)/lvm2-clvmd.service
|
$(INSTALL_DATA) lvm2_clvmd_systemd_red_hat.service $(systemd_unit_dir)/lvm2-clvmd.service
|
||||||
$(INSTALL_DATA) lvm2_cluster_activation_systemd_red_hat.service $(systemd_unit_dir)/lvm2-cluster-activation.service
|
$(INSTALL_DATA) lvm2_cluster_activation_systemd_red_hat.service $(systemd_unit_dir)/lvm2-cluster-activation.service
|
||||||
@ -142,6 +149,8 @@ DISTCLEAN_TARGETS += \
|
|||||||
lvm2_lvmetad_init_red_hat \
|
lvm2_lvmetad_init_red_hat \
|
||||||
lvm2_lvmetad_systemd_red_hat.service \
|
lvm2_lvmetad_systemd_red_hat.service \
|
||||||
lvm2_lvmetad_systemd_red_hat.socket \
|
lvm2_lvmetad_systemd_red_hat.socket \
|
||||||
|
lvm2_lvmpolld_systemd_red_hat.service \
|
||||||
|
lvm2_lvmpolld_systemd_red_hat.socket \
|
||||||
lvm2_monitoring_init_red_hat \
|
lvm2_monitoring_init_red_hat \
|
||||||
lvm2_monitoring_systemd_red_hat.service \
|
lvm2_monitoring_systemd_red_hat.service \
|
||||||
lvm2_pvscan_systemd_red_hat@.service \
|
lvm2_pvscan_systemd_red_hat@.service \
|
||||||
|
114
scripts/lvm2_lvmpolld_init_red_hat.in
Normal file
114
scripts/lvm2_lvmpolld_init_red_hat.in
Normal file
@ -0,0 +1,114 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
#
|
||||||
|
# Copyright (C) 2015 Red Hat, Inc. All rights reserved.
|
||||||
|
#
|
||||||
|
# This copyrighted material is made available to anyone wishing to use,
|
||||||
|
# modify, copy, or redistribute it subject to the terms and conditions
|
||||||
|
# of the GNU General Public License v.2.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with this program; if not, write to the Free Software Foundation,
|
||||||
|
# Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
|
#
|
||||||
|
# This file is part of LVM2.
|
||||||
|
# It is required for the proper handling of failures of LVM2 mirror
|
||||||
|
# devices that were created using the -m option of lvcreate.
|
||||||
|
#
|
||||||
|
#
|
||||||
|
# chkconfig: 12345 02 99
|
||||||
|
# description: Starts and stops LVM poll daemon
|
||||||
|
#
|
||||||
|
# For Red-Hat-based distributions such as Fedora, RHEL, CentOS.
|
||||||
|
#
|
||||||
|
### BEGIN INIT INFO
|
||||||
|
# Provides: lvm2-lvmpolld
|
||||||
|
# Required-Start: $local_fs
|
||||||
|
# Required-Stop: $local_fs
|
||||||
|
# Default-Start: 1 2 3 4 5
|
||||||
|
# Default-Stop: 0 6
|
||||||
|
# Short-Description: A daemon that is responsible for monitoring in-progress
|
||||||
|
# and possibly longer term operations on logical volumes.
|
||||||
|
# It helps to reduce the number of spawned processes if same
|
||||||
|
# logical volume is requested to get monitored multiple times.
|
||||||
|
# Also avoids unsolicited termination due to external factors.
|
||||||
|
### END INIT INFO
|
||||||
|
|
||||||
|
. /etc/init.d/functions
|
||||||
|
|
||||||
|
DAEMON=lvmpolld
|
||||||
|
|
||||||
|
exec_prefix=@exec_prefix@
|
||||||
|
sbindir=@sbindir@
|
||||||
|
|
||||||
|
LOCK_FILE="/var/lock/subsys/$DAEMON"
|
||||||
|
PID_FILE="@LVMPOLLD_PIDFILE@"
|
||||||
|
|
||||||
|
rh_status() {
|
||||||
|
status -p $PID_FILE $DAEMON
|
||||||
|
}
|
||||||
|
|
||||||
|
rh_status_q() {
|
||||||
|
rh_status >/dev/null 2>&1
|
||||||
|
}
|
||||||
|
|
||||||
|
start()
|
||||||
|
{
|
||||||
|
ret=0
|
||||||
|
action "Starting LVM poll daemon:" $DAEMON || ret=$?
|
||||||
|
return $ret
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
stop()
|
||||||
|
{
|
||||||
|
ret=0
|
||||||
|
action "Signaling LVM poll daemon to exit:" killproc -p $PID_FILE $DAEMON -TERM || ret=$?
|
||||||
|
return $ret
|
||||||
|
}
|
||||||
|
|
||||||
|
rtrn=1
|
||||||
|
|
||||||
|
# See how we were called.
|
||||||
|
case "$1" in
|
||||||
|
start)
|
||||||
|
rh_status_q && exit 0
|
||||||
|
start
|
||||||
|
rtrn=$?
|
||||||
|
[ $rtrn = 0 ] && touch $LOCK_FILE
|
||||||
|
;;
|
||||||
|
|
||||||
|
stop|force-stop)
|
||||||
|
rh_status_q || exit 0
|
||||||
|
stop
|
||||||
|
rtrn=$?
|
||||||
|
[ $rtrn = 0 ] && rm -f $LOCK_FILE
|
||||||
|
;;
|
||||||
|
|
||||||
|
restart)
|
||||||
|
if stop
|
||||||
|
then
|
||||||
|
start
|
||||||
|
fi
|
||||||
|
rtrn=$?
|
||||||
|
;;
|
||||||
|
|
||||||
|
condrestart|try-restart)
|
||||||
|
rh_status_q || exit 0
|
||||||
|
if stop
|
||||||
|
then
|
||||||
|
start
|
||||||
|
fi
|
||||||
|
rtrn=$?
|
||||||
|
;;
|
||||||
|
|
||||||
|
status)
|
||||||
|
rh_status
|
||||||
|
rtrn=$?
|
||||||
|
;;
|
||||||
|
|
||||||
|
*)
|
||||||
|
echo $"Usage: $0 {start|stop|force-stop|restart|condrestart|try-restart|status}"
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
exit $rtrn
|
17
scripts/lvm2_lvmpolld_systemd_red_hat.service.in
Normal file
17
scripts/lvm2_lvmpolld_systemd_red_hat.service.in
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
[Unit]
|
||||||
|
Description=LVM2 poll daemon
|
||||||
|
Documentation=man:lvmpolld(8)
|
||||||
|
Requires=lvm2-lvmpolld.socket
|
||||||
|
After=lvm2-lvmpolld.socket
|
||||||
|
DefaultDependencies=no
|
||||||
|
Conflicts=shutdown.target
|
||||||
|
|
||||||
|
[Service]
|
||||||
|
Type=simple
|
||||||
|
NonBlocking=true
|
||||||
|
ExecStart=@sbindir@/lvmpolld -t 60 -f
|
||||||
|
Environment=SD_ACTIVATION=1
|
||||||
|
PIDFile=@LVMPOLLD_PIDFILE@
|
||||||
|
|
||||||
|
[Install]
|
||||||
|
WantedBy=sysinit.target
|
12
scripts/lvm2_lvmpolld_systemd_red_hat.socket.in
Normal file
12
scripts/lvm2_lvmpolld_systemd_red_hat.socket.in
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
[Unit]
|
||||||
|
Description=LVM2 poll daemon socket
|
||||||
|
Documentation=man:lvmpolld(8)
|
||||||
|
DefaultDependencies=no
|
||||||
|
|
||||||
|
[Socket]
|
||||||
|
ListenStream=@DEFAULT_RUN_DIR@/lvmpolld.socket
|
||||||
|
SocketMode=0600
|
||||||
|
RemoveOnStop=true
|
||||||
|
|
||||||
|
[Install]
|
||||||
|
WantedBy=sysinit.target
|
@ -1,7 +1,7 @@
|
|||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
# We use some bash-isms (getopts?)
|
# We use some bash-isms (getopts?)
|
||||||
|
|
||||||
# Copyright (C) 2007-2010 Red Hat, Inc. All rights reserved.
|
# Copyright (C) 2007-2015 Red Hat, Inc. All rights reserved.
|
||||||
#
|
#
|
||||||
# This file is part of LVM2.
|
# This file is part of LVM2.
|
||||||
#
|
#
|
||||||
@ -41,6 +41,7 @@ NC=nc
|
|||||||
LVM=${LVM_BINARY-lvm}
|
LVM=${LVM_BINARY-lvm}
|
||||||
DMSETUP=${DMSETUP_BINARY-dmsetup}
|
DMSETUP=${DMSETUP_BINARY-dmsetup}
|
||||||
LVMETAD_SOCKET=${LVM_LVMETAD_SOCKET-/var/run/lvm/lvmetad.socket}
|
LVMETAD_SOCKET=${LVM_LVMETAD_SOCKET-/var/run/lvm/lvmetad.socket}
|
||||||
|
LVMPOLLD_SOCKET=${LVM_LVMPOLLD_SOCKET-/var/run/lvm/lvmpolld.socket}
|
||||||
|
|
||||||
die() {
|
die() {
|
||||||
code=$1; shift
|
code=$1; shift
|
||||||
@ -59,6 +60,7 @@ function usage {
|
|||||||
echo " -c if running clvmd, gather cluster data as well"
|
echo " -c if running clvmd, gather cluster data as well"
|
||||||
echo " -d <directory> dump into a directory instead of tarball"
|
echo " -d <directory> dump into a directory instead of tarball"
|
||||||
echo " -l gather lvmetad state if running"
|
echo " -l gather lvmetad state if running"
|
||||||
|
echo " -p gather lvmpolld state if running"
|
||||||
echo " -m gather LVM metadata from the PVs"
|
echo " -m gather LVM metadata from the PVs"
|
||||||
echo " -s gather system info and context"
|
echo " -s gather system info and context"
|
||||||
echo " -u gather udev info and context"
|
echo " -u gather udev info and context"
|
||||||
@ -72,13 +74,14 @@ clustered=0
|
|||||||
metadata=0
|
metadata=0
|
||||||
sysreport=0
|
sysreport=0
|
||||||
udev=0
|
udev=0
|
||||||
while getopts :acd:hlmus opt; do
|
while getopts :acd:hlpmus opt; do
|
||||||
case $opt in
|
case $opt in
|
||||||
a) advanced=1 ;;
|
a) advanced=1 ;;
|
||||||
c) clustered=1 ;;
|
c) clustered=1 ;;
|
||||||
d) userdir=$OPTARG ;;
|
d) userdir=$OPTARG ;;
|
||||||
h) usage ;;
|
h) usage ;;
|
||||||
l) lvmetad=1 ;;
|
l) lvmetad=1 ;;
|
||||||
|
p) lvmpolld=1 ;;
|
||||||
m) metadata=1 ;;
|
m) metadata=1 ;;
|
||||||
s) sysreport=1 ;;
|
s) sysreport=1 ;;
|
||||||
u) udev=1 ;;
|
u) udev=1 ;;
|
||||||
@ -236,6 +239,7 @@ if (( $metadata )); then
|
|||||||
done
|
done
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
# FIXME: add lvmpolld.service here
|
||||||
if (( $sysreport )); then
|
if (( $sysreport )); then
|
||||||
myecho "Gathering system info..."
|
myecho "Gathering system info..."
|
||||||
|
|
||||||
@ -296,6 +300,22 @@ if (( $lvmetad )); then
|
|||||||
} > "$dir/lvmetad.txt"
|
} > "$dir/lvmetad.txt"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
if (( $lvmpolld )); then
|
||||||
|
(echo 'request="dump"'; echo '##') | {
|
||||||
|
if type -p $SOCAT >& /dev/null; then
|
||||||
|
echo "$SOCAT unix-connect:$LVMPOLLD_SOCKET -" >> "$log"
|
||||||
|
$SOCAT "unix-connect:$LVMPOLLD_SOCKET" - 2>> "$log"
|
||||||
|
elif echo | $NC -U "$LVMPOLLD_SOCKET"; then
|
||||||
|
echo "$NC -U $LVMPOLLD_SOCKET" >> "$log"
|
||||||
|
$NC -U "$LVMPOLLD_SOCKET" 2>> "$log"
|
||||||
|
else
|
||||||
|
myecho "WARNING: Neither socat nor nc -U seems to be available." 1>&2
|
||||||
|
echo "# DUMP FAILED"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
} > "$dir/lvmpolld.txt"
|
||||||
|
fi
|
||||||
|
|
||||||
if test -z "$userdir"; then
|
if test -z "$userdir"; then
|
||||||
lvm_dump="$dirbase.tgz"
|
lvm_dump="$dirbase.tgz"
|
||||||
myecho "Creating report tarball in $HOME/$lvm_dump..."
|
myecho "Creating report tarball in $HOME/$lvm_dump..."
|
||||||
|
@ -56,6 +56,11 @@ LVMETAD_NDEV_FLAVOUR = ,ndev-lvmetad
|
|||||||
LVMETAD_UDEV_FLAVOUR = ,udev-lvmetad
|
LVMETAD_UDEV_FLAVOUR = ,udev-lvmetad
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
ifeq ("@BUILD_LVMPOLLD@", "yes")
|
||||||
|
LVMPOLLD_RUN_BASE = $(RUN_BASE)
|
||||||
|
LVMPOLLD_NDEV_FLAVOUR = ,ndev-lvmpolld,ndev-cluster-lvmpolld,ndev-lvmetad-lvmpolld
|
||||||
|
LVMPOLLD_UDEV_FLAVOUR = ,udev-lvmpolld,udev-cluster-lvmpolld,udev-lvmetad-lvmpolld
|
||||||
|
endif
|
||||||
|
|
||||||
# Shell quote;
|
# Shell quote;
|
||||||
SHELL_PATH_SQ = $(subst ','\'',$(SHELL_PATH))
|
SHELL_PATH_SQ = $(subst ','\'',$(SHELL_PATH))
|
||||||
@ -73,6 +78,7 @@ help:
|
|||||||
@echo " check_local Run tests without clvmd and lvmetad."
|
@echo " check_local Run tests without clvmd and lvmetad."
|
||||||
@echo " check_cluster Run tests with cluster daemon."
|
@echo " check_cluster Run tests with cluster daemon."
|
||||||
@echo " check_lvmetad Run tests with lvmetad daemon."
|
@echo " check_lvmetad Run tests with lvmetad daemon."
|
||||||
|
@echo " check_lvmpolld Run tests with lvmpolld daemon."
|
||||||
@echo " clean Clean dir."
|
@echo " clean Clean dir."
|
||||||
@echo " help Display callable targets."
|
@echo " help Display callable targets."
|
||||||
@echo -e "\nSupported variables:"
|
@echo -e "\nSupported variables:"
|
||||||
@ -83,6 +89,7 @@ help:
|
|||||||
@echo " LVM_TEST_LOCKING Normal (1), Cluster (3)."
|
@echo " LVM_TEST_LOCKING Normal (1), Cluster (3)."
|
||||||
@echo " LVM_TEST_LVMETAD Start lvmetad (1)."
|
@echo " LVM_TEST_LVMETAD Start lvmetad (1)."
|
||||||
@echo " LVM_TEST_LVMETAD_DEBUG_OPTS Allows to override debug opts [-l all]."
|
@echo " LVM_TEST_LVMETAD_DEBUG_OPTS Allows to override debug opts [-l all]."
|
||||||
|
@echo " LVM_TEST_LVMPOLLD Start lvmpolld"
|
||||||
@echo " LVM_TEST_NODEBUG Do not debug lvm commands."
|
@echo " LVM_TEST_NODEBUG Do not debug lvm commands."
|
||||||
@echo " LVM_TEST_PARALLEL May skip agresive wipe of LVMTEST resources."
|
@echo " LVM_TEST_PARALLEL May skip agresive wipe of LVMTEST resources."
|
||||||
@echo " LVM_TEST_RESULTS Where to create result files [results]."
|
@echo " LVM_TEST_RESULTS Where to create result files [results]."
|
||||||
@ -109,12 +116,12 @@ help:
|
|||||||
check: .tests-stamp
|
check: .tests-stamp
|
||||||
VERBOSE=$(VERBOSE) ./lib/runner \
|
VERBOSE=$(VERBOSE) ./lib/runner \
|
||||||
--testdir . --outdir $(LVM_TEST_RESULTS) \
|
--testdir . --outdir $(LVM_TEST_RESULTS) \
|
||||||
--flavours ndev-vanilla,ndev-cluster$(LVMETAD_NDEV_FLAVOUR) --only $(T) --skip $(S)
|
--flavours ndev-vanilla,ndev-cluster$(LVMETAD_NDEV_FLAVOUR)$(LVMPOLLD_NDEV_FLAVOUR) --only $(T) --skip $(S)
|
||||||
|
|
||||||
check_system: .tests-stamp
|
check_system: .tests-stamp
|
||||||
VERBOSE=$(VERBOSE) ./lib/runner \
|
VERBOSE=$(VERBOSE) ./lib/runner \
|
||||||
--testdir . --outdir $(LVM_TEST_RESULTS) \
|
--testdir . --outdir $(LVM_TEST_RESULTS) \
|
||||||
--flavours udev-vanilla,udev-cluster$(LVMETAD_UDEV_FLAVOUR) --only $(T) --skip $(S)
|
--flavours udev-vanilla,udev-cluster$(LVMETAD_UDEV_FLAVOUR)$(LVMPOLLD_UDEV_FLAVOUR) --only $(T) --skip $(S)
|
||||||
|
|
||||||
check_cluster: .tests-stamp
|
check_cluster: .tests-stamp
|
||||||
VERBOSE=$(VERBOSE) ./lib/runner \
|
VERBOSE=$(VERBOSE) ./lib/runner \
|
||||||
@ -133,11 +140,21 @@ check_lvmetad: .tests-stamp
|
|||||||
--flavours ndev-lvmetad --only $(T) --skip $(S)
|
--flavours ndev-lvmetad --only $(T) --skip $(S)
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
ifeq ("@BUILD_LVMPOLLD@", "yes")
|
||||||
|
check_lvmpolld: .tests-stamp
|
||||||
|
VERBOSE=$(VERBOSE) ./lib/runner \
|
||||||
|
--testdir . --outdir results \
|
||||||
|
--flavours udev-lvmpolld,udev-cluster-lvmpolld,udev-lvmetad-lvmpolld --only $(T) --skip $(S)
|
||||||
|
endif
|
||||||
|
|
||||||
DATADIR = $(datadir)/lvm2-testsuite
|
DATADIR = $(datadir)/lvm2-testsuite
|
||||||
EXECDIR = $(libexecdir)/lvm2-testsuite
|
EXECDIR = $(libexecdir)/lvm2-testsuite
|
||||||
|
|
||||||
LIB_FLAVOURS = lib/flavour-ndev-vanilla lib/flavour-ndev-cluster lib/flavour-ndev-lvmetad \
|
LIB_FLAVOURS = lib/flavour-ndev-vanilla lib/flavour-ndev-cluster lib/flavour-ndev-lvmetad \
|
||||||
lib/flavour-udev-vanilla lib/flavour-udev-cluster lib/flavour-udev-lvmetad
|
lib/flavour-udev-vanilla lib/flavour-udev-cluster lib/flavour-udev-lvmetad \
|
||||||
|
lib/flavour-udev-lvmpolld lib/flavour-ndev-lvmpolld lib/flavour-ndev-cluster-lvmpolld \
|
||||||
|
lib/flavour-ndev-lvmetad-lvmpolld lib/flavour-udev-lvmpolld lib/flavour-udev-cluster-lvmpolld \
|
||||||
|
lib/flavour-udev-lvmetad-lvmpolld
|
||||||
|
|
||||||
LIB_LOCAL = lib/paths lib/runner
|
LIB_LOCAL = lib/paths lib/runner
|
||||||
LIB_EXEC = lib/not lib/invalid lib/fail lib/should
|
LIB_EXEC = lib/not lib/invalid lib/fail lib/should
|
||||||
@ -190,6 +207,7 @@ lib/paths-common: $(srcdir)/Makefile.in .lib-dir-stamp Makefile
|
|||||||
echo 'export RAID=@RAID@' >> $@-t
|
echo 'export RAID=@RAID@' >> $@-t
|
||||||
echo 'export CACHE=@CACHE@' >> $@-t
|
echo 'export CACHE=@CACHE@' >> $@-t
|
||||||
echo 'export LVMETAD_PIDFILE="@LVMETAD_PIDFILE@"' >> $@-t
|
echo 'export LVMETAD_PIDFILE="@LVMETAD_PIDFILE@"' >> $@-t
|
||||||
|
echo 'export LVMPOLLD_PIDFILE="@LVMPOLLD_PIDFILE@"' >> $@-t
|
||||||
echo 'export DMEVENTD_PIDFILE="@DMEVENTD_PIDFILE@"' >> $@-t
|
echo 'export DMEVENTD_PIDFILE="@DMEVENTD_PIDFILE@"' >> $@-t
|
||||||
echo 'export CLVMD_PIDFILE="@CLVMD_PIDFILE@"' >> $@-t
|
echo 'export CLVMD_PIDFILE="@CLVMD_PIDFILE@"' >> $@-t
|
||||||
echo 'export LVM_TEST_THIN_CHECK_CMD=$${LVM_TEST_THIN_CHECK_CMD-@THIN_CHECK_CMD@}' >> $@-t
|
echo 'export LVM_TEST_THIN_CHECK_CMD=$${LVM_TEST_THIN_CHECK_CMD-@THIN_CHECK_CMD@}' >> $@-t
|
||||||
@ -240,6 +258,7 @@ LIB = $(LIB_SHARED) $(LIB_LOCAL) $(LIB_EXEC) $(LIB_FLAVOURS)
|
|||||||
ln -fs $(abs_top_builddir)/daemons/clvmd/clvmd lib/clvmd
|
ln -fs $(abs_top_builddir)/daemons/clvmd/clvmd lib/clvmd
|
||||||
ln -fs $(abs_top_builddir)/daemons/dmeventd/dmeventd lib/dmeventd
|
ln -fs $(abs_top_builddir)/daemons/dmeventd/dmeventd lib/dmeventd
|
||||||
ln -fs $(abs_top_builddir)/daemons/lvmetad/lvmetad lib/lvmetad
|
ln -fs $(abs_top_builddir)/daemons/lvmetad/lvmetad lib/lvmetad
|
||||||
|
ln -fs $(abs_top_builddir)/daemons/lvmpolld/lvmpolld lib/lvmpolld
|
||||||
ln -fs $(abs_top_srcdir)/scripts/vgimportclone.sh lib/vgimportclone
|
ln -fs $(abs_top_srcdir)/scripts/vgimportclone.sh lib/vgimportclone
|
||||||
ln -fs $(abs_top_srcdir)/scripts/fsadm.sh lib/fsadm
|
ln -fs $(abs_top_srcdir)/scripts/fsadm.sh lib/fsadm
|
||||||
ln -fs $(abs_top_srcdir)/conf/thin-performance.profile lib/thin-performance.profile
|
ln -fs $(abs_top_srcdir)/conf/thin-performance.profile lib/thin-performance.profile
|
||||||
@ -256,7 +275,8 @@ CLEAN_TARGETS += .lib-dir-stamp .tests-stamp $(LIB) $(addprefix lib/,$(CMDS)) \
|
|||||||
lib/clvmd lib/dmeventd lib/dmsetup lib/lvmetad lib/fsadm lib/vgimportclone \
|
lib/clvmd lib/dmeventd lib/dmsetup lib/lvmetad lib/fsadm lib/vgimportclone \
|
||||||
lib/thin-performance.profile lib/harness \
|
lib/thin-performance.profile lib/harness \
|
||||||
lib/paths-installed lib/paths-installed-t \
|
lib/paths-installed lib/paths-installed-t \
|
||||||
lib/paths-common lib/paths-common-t
|
lib/paths-common lib/paths-common-t \
|
||||||
|
lib/lvmpolld
|
||||||
|
|
||||||
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
|
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
|
||||||
cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@
|
cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@
|
||||||
|
@ -136,6 +136,47 @@ notify_lvmetad() {
|
|||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
|
prepare_lvmpolld() {
|
||||||
|
set -x
|
||||||
|
rm -f debug.log
|
||||||
|
# skip if we don't have our own lvmpolld...
|
||||||
|
(which lvmpolld 2>/dev/null | grep "$abs_builddir") || skip
|
||||||
|
|
||||||
|
lvmconf "global/use_lvmpolld = 1"
|
||||||
|
|
||||||
|
local run_valgrind=
|
||||||
|
test "${LVM_VALGRIND_LVMPOLLD:-0}" -eq 0 || run_valgrind="run_valgrind"
|
||||||
|
|
||||||
|
kill_sleep_kill_ LOCAL_LVMPOLLD ${LVM_VALGRIND_LVMPOLLD:-0}
|
||||||
|
|
||||||
|
echo "preparing lvmpolld..."
|
||||||
|
$run_valgrind lvmpolld -f "$@" -s "$TESTDIR/lvmpolld.socket" -B "$TESTDIR/lib/lvm" -l all &
|
||||||
|
echo $! > LOCAL_LVMPOLLD
|
||||||
|
while ! test -e "$TESTDIR/lvmpolld.socket"; do echo -n .; sleep .1; done # wait for the socket
|
||||||
|
echo ok
|
||||||
|
}
|
||||||
|
|
||||||
|
lvmpolld_talk() {
|
||||||
|
local use=nc
|
||||||
|
if type -p socat >& /dev/null; then
|
||||||
|
use=socat
|
||||||
|
elif echo | not nc -U "$TESTDIR/lvmpolld.socket" ; then
|
||||||
|
echo "WARNING: Neither socat nor nc -U seems to be available." 1>&2
|
||||||
|
echo "# failed to contact lvmpolld"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if test "$use" = nc ; then
|
||||||
|
nc -U "$TESTDIR/lvmpolld.socket"
|
||||||
|
else
|
||||||
|
socat "unix-connect:$TESTDIR/lvmpolld.socket" -
|
||||||
|
fi | tee -a lvmpolld-talk.txt
|
||||||
|
}
|
||||||
|
|
||||||
|
lvmpolld_dump() {
|
||||||
|
(echo 'request="dump"'; echo '##') | lvmpolld_talk "$@"
|
||||||
|
}
|
||||||
|
|
||||||
teardown_devs_prefixed() {
|
teardown_devs_prefixed() {
|
||||||
local prefix=$1
|
local prefix=$1
|
||||||
local stray=${2:-0}
|
local stray=${2:-0}
|
||||||
@ -286,6 +327,10 @@ teardown() {
|
|||||||
$vg $vg1 $vg2 $vg3 $vg4 &>/dev/null || rm -f debug.log strace.log
|
$vg $vg1 $vg2 $vg3 $vg4 &>/dev/null || rm -f debug.log strace.log
|
||||||
}
|
}
|
||||||
|
|
||||||
|
kill_sleep_kill_ LOCAL_LVMPOLLD ${LVM_VALGRIND_LVMPOLLD:-0}
|
||||||
|
|
||||||
|
echo -n .
|
||||||
|
|
||||||
kill_sleep_kill_ LOCAL_CLVMD ${LVM_VALGRIND_CLVMD:-0}
|
kill_sleep_kill_ LOCAL_CLVMD ${LVM_VALGRIND_CLVMD:-0}
|
||||||
|
|
||||||
echo -n .
|
echo -n .
|
||||||
@ -1094,9 +1139,49 @@ dmsetup_wrapped() {
|
|||||||
dmsetup "$@"
|
dmsetup "$@"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
awk_parse_init_count_in_lvmpolld_dump() {
|
||||||
|
printf '%s' \
|
||||||
|
\
|
||||||
|
$'BEGINFILE { x=0; answ=0; FS="="; key="[[:space:]]*"vkey }' \
|
||||||
|
$'{' \
|
||||||
|
$'if (/.*{$/) { x++ }' \
|
||||||
|
$'else if (/.*}$/) { x-- }' \
|
||||||
|
$'else if ( x == 2 && $1 ~ key) { value=substr($2, 2); value=substr(value, 1, length(value) - 1); }' \
|
||||||
|
$'if ( x == 2 && value == vvalue && $1 ~ /[[:space:]]*init_requests_count/) { answ=$2 }' \
|
||||||
|
$'if (answ > 0) { exit 0 }' \
|
||||||
|
$'}' \
|
||||||
|
$'END { printf "%d", answ }'
|
||||||
|
}
|
||||||
|
|
||||||
|
check_lvmpolld_init_rq_count() {
|
||||||
|
local ret=$(awk -v vvalue="$2" -v vkey=${3:-lvname} "$(awk_parse_init_count_in_lvmpolld_dump)" lvmpolld_dump.txt)
|
||||||
|
test $ret -eq $1 || {
|
||||||
|
echo "check_lvmpolld_init_rq_count failed. Expected $1, got $ret"
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
wait_pvmove_lv_ready() {
|
wait_pvmove_lv_ready() {
|
||||||
# given sleep .1 this is about 60 secs of waiting
|
# given sleep .1 this is about 60 secs of waiting
|
||||||
local retries=${2:-300}
|
local retries=${2:-300}
|
||||||
|
|
||||||
|
if [ -e LOCAL_LVMPOLLD ]; then
|
||||||
|
local lvid
|
||||||
|
while : ; do
|
||||||
|
test $retries -le 0 && die "Waiting for lvmpolld timed out"
|
||||||
|
test -n "$lvid" || {
|
||||||
|
lvid=$(get lv_field ${1//-/\/} vg_uuid,lv_uuid -a 2>/dev/null)
|
||||||
|
lvid=${lvid//\ /}
|
||||||
|
lvid=${lvid//-/}
|
||||||
|
}
|
||||||
|
test -z "$lvid" || {
|
||||||
|
lvmpolld_dump > lvmpolld_dump.txt
|
||||||
|
! check_lvmpolld_init_rq_count 1 $lvid lvid || break;
|
||||||
|
}
|
||||||
|
sleep .1
|
||||||
|
retries=$((retries-1))
|
||||||
|
done
|
||||||
|
else
|
||||||
while : ; do
|
while : ; do
|
||||||
test $retries -le 0 && die "Waiting for pvmove LV to get activated has timed out"
|
test $retries -le 0 && die "Waiting for pvmove LV to get activated has timed out"
|
||||||
dmsetup info -c -o tables_loaded $1 > out 2>/dev/null|| true;
|
dmsetup info -c -o tables_loaded $1 > out 2>/dev/null|| true;
|
||||||
@ -1104,6 +1189,7 @@ wait_pvmove_lv_ready() {
|
|||||||
sleep .1
|
sleep .1
|
||||||
retries=$((retries-1))
|
retries=$((retries-1))
|
||||||
done
|
done
|
||||||
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
# return total memory size in kB units
|
# return total memory size in kB units
|
||||||
|
2
test/lib/flavour-ndev-cluster-lvmpolld.sh
Normal file
2
test/lib/flavour-ndev-cluster-lvmpolld.sh
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
export LVM_TEST_LOCKING=3
|
||||||
|
export LVM_TEST_LVMPOLLD=1
|
3
test/lib/flavour-ndev-lvmetad-lvmpolld.sh
Normal file
3
test/lib/flavour-ndev-lvmetad-lvmpolld.sh
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
export LVM_TEST_LOCKING=1
|
||||||
|
export LVM_TEST_LVMETAD=1
|
||||||
|
export LVM_TEST_LVMPOLLD=1
|
2
test/lib/flavour-ndev-lvmpolld.sh
Normal file
2
test/lib/flavour-ndev-lvmpolld.sh
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
export LVM_TEST_LOCKING=1
|
||||||
|
export LVM_TEST_LVMPOLLD=1
|
3
test/lib/flavour-udev-cluster-lvmpolld.sh
Normal file
3
test/lib/flavour-udev-cluster-lvmpolld.sh
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
export LVM_TEST_LOCKING=3
|
||||||
|
export LVM_TEST_LVMPOLLD=1
|
||||||
|
export LVM_TEST_DEVDIR=/dev
|
4
test/lib/flavour-udev-lvmetad-lvmpolld.sh
Normal file
4
test/lib/flavour-udev-lvmetad-lvmpolld.sh
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
export LVM_TEST_LOCKING=1
|
||||||
|
export LVM_TEST_LVMETAD=1
|
||||||
|
export LVM_TEST_LVMPOLLD=1
|
||||||
|
export LVM_TEST_DEVDIR=/dev
|
3
test/lib/flavour-udev-lvmpolld.sh
Normal file
3
test/lib/flavour-udev-lvmpolld.sh
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
export LVM_TEST_LOCKING=1
|
||||||
|
export LVM_TEST_LVMPOLLD=1
|
||||||
|
export LVM_TEST_DEVDIR=/dev
|
@ -100,6 +100,13 @@ else
|
|||||||
aux prepare_clvmd
|
aux prepare_clvmd
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
echo "LVM_TEST_LVMPOLLD=$LVM_TEST_LVMPOLLD"
|
||||||
|
test -n "$LVM_TEST_LVMPOLLD" && {
|
||||||
|
export LVM_LVMPOLLD_SOCKET="$TESTDIR/lvmpolld.socket"
|
||||||
|
export LVM_LVMPOLLD_PIDFILE="$TESTDIR/lvmpolld.pid"
|
||||||
|
aux prepare_lvmpolld
|
||||||
|
}
|
||||||
|
|
||||||
echo "<======== Processing test: \"$TESTNAME\" ========>"
|
echo "<======== Processing test: \"$TESTNAME\" ========>"
|
||||||
|
|
||||||
set -vx
|
set -vx
|
||||||
|
@ -11,6 +11,8 @@
|
|||||||
|
|
||||||
. lib/inittest
|
. lib/inittest
|
||||||
|
|
||||||
|
test -e LOCAL_LVMPOLLD && skip
|
||||||
|
|
||||||
lvm version
|
lvm version
|
||||||
|
|
||||||
test -n "$abs_top_builddir" || skip
|
test -n "$abs_top_builddir" || skip
|
||||||
|
@ -14,6 +14,7 @@
|
|||||||
# Just skip this test if minor is already in use...
|
# Just skip this test if minor is already in use...
|
||||||
dmsetup info | tee info
|
dmsetup info | tee info
|
||||||
egrep "^Major, minor: *[0-9]+, 123" info && skip
|
egrep "^Major, minor: *[0-9]+, 123" info && skip
|
||||||
|
test -e LOCAL_LVMPOLLD && skip
|
||||||
|
|
||||||
aux prepare_vg 2
|
aux prepare_vg 2
|
||||||
lvcreate -a n --zero n -l 1 -n foo $vg
|
lvcreate -a n --zero n -l 1 -n foo $vg
|
||||||
|
@ -18,6 +18,8 @@
|
|||||||
|
|
||||||
. lib/inittest
|
. lib/inittest
|
||||||
|
|
||||||
|
test -e LOCAL_LVMPOLLD && skip
|
||||||
|
|
||||||
aux prepare_vg 2
|
aux prepare_vg 2
|
||||||
|
|
||||||
lvcreate -l100%FREE -n span $vg
|
lvcreate -l100%FREE -n span $vg
|
||||||
|
@ -18,6 +18,8 @@
|
|||||||
|
|
||||||
. lib/inittest
|
. lib/inittest
|
||||||
|
|
||||||
|
test -e LOCAL_LVMPOLLD && skip
|
||||||
|
|
||||||
aux prepare_vg 4
|
aux prepare_vg 4
|
||||||
|
|
||||||
lvcreate -l1 -n linear1 $vg "$dev1"
|
lvcreate -l1 -n linear1 $vg "$dev1"
|
||||||
|
@ -11,6 +11,8 @@
|
|||||||
|
|
||||||
. lib/inittest
|
. lib/inittest
|
||||||
|
|
||||||
|
test -e LOCAL_LVMPOLLD && skip
|
||||||
|
|
||||||
aux prepare_vg 3
|
aux prepare_vg 3
|
||||||
|
|
||||||
lvcreate -aey --type mirror -m 1 -l 1 --nosync -n mirror $vg
|
lvcreate -aey --type mirror -m 1 -l 1 --nosync -n mirror $vg
|
||||||
|
@ -11,6 +11,8 @@
|
|||||||
|
|
||||||
. lib/inittest
|
. lib/inittest
|
||||||
|
|
||||||
|
test -e LOCAL_LVMPOLLD && skip
|
||||||
|
|
||||||
# Test skip activation flag -k|--setactivationskip
|
# Test skip activation flag -k|--setactivationskip
|
||||||
|
|
||||||
aux prepare_vg
|
aux prepare_vg
|
||||||
|
@ -16,6 +16,7 @@ export LVM_BINARY=lvm
|
|||||||
. lib/inittest
|
. lib/inittest
|
||||||
|
|
||||||
# only clvmd based test, skip otherwise
|
# only clvmd based test, skip otherwise
|
||||||
|
test -e LOCAL_LVMPOLLD && skip
|
||||||
test -e LOCAL_CLVMD || skip
|
test -e LOCAL_CLVMD || skip
|
||||||
read LOCAL_CLVMD < LOCAL_CLVMD
|
read LOCAL_CLVMD < LOCAL_CLVMD
|
||||||
|
|
||||||
|
@ -16,6 +16,8 @@
|
|||||||
|
|
||||||
. lib/inittest
|
. lib/inittest
|
||||||
|
|
||||||
|
test -e LOCAL_LVMPOLLD && skip
|
||||||
|
|
||||||
aux prepare_pvs 5
|
aux prepare_pvs 5
|
||||||
get_devs
|
get_devs
|
||||||
|
|
||||||
|
@ -15,6 +15,8 @@
|
|||||||
|
|
||||||
. lib/inittest
|
. lib/inittest
|
||||||
|
|
||||||
|
test -e LOCAL_LVMPOLLD && skip
|
||||||
|
|
||||||
#
|
#
|
||||||
# Main
|
# Main
|
||||||
#
|
#
|
||||||
|
@ -11,6 +11,8 @@
|
|||||||
|
|
||||||
. lib/inittest
|
. lib/inittest
|
||||||
|
|
||||||
|
test -e LOCAL_LVMPOLLD && skip
|
||||||
|
|
||||||
aux prepare_dmeventd
|
aux prepare_dmeventd
|
||||||
|
|
||||||
aux prepare_vg 5
|
aux prepare_vg 5
|
||||||
|
@ -11,6 +11,8 @@
|
|||||||
|
|
||||||
. lib/inittest
|
. lib/inittest
|
||||||
|
|
||||||
|
test -e LOCAL_LVMPOLLD && skip
|
||||||
|
|
||||||
flatten() {
|
flatten() {
|
||||||
cat > flatten.config
|
cat > flatten.config
|
||||||
for s in `egrep '^[a-z]+ {$' flatten.config | sed -e s,{$,,`; do
|
for s in `egrep '^[a-z]+ {$' flatten.config | sed -e s,{$,,`; do
|
||||||
|
@ -13,6 +13,8 @@
|
|||||||
|
|
||||||
. lib/inittest
|
. lib/inittest
|
||||||
|
|
||||||
|
test -e LOCAL_LVMPOLLD && skip
|
||||||
|
|
||||||
which md5sum || skip
|
which md5sum || skip
|
||||||
|
|
||||||
aux prepare_pvs 1
|
aux prepare_pvs 1
|
||||||
|
@ -13,6 +13,8 @@ test_description='Exercise fsadm filesystem resize'
|
|||||||
|
|
||||||
. lib/inittest
|
. lib/inittest
|
||||||
|
|
||||||
|
test -e LOCAL_LVMPOLLD && skip
|
||||||
|
|
||||||
aux prepare_vg 1 100
|
aux prepare_vg 1 100
|
||||||
|
|
||||||
# set to "skip" to avoid testing given fs and test warning result
|
# set to "skip" to avoid testing given fs and test warning result
|
||||||
|
@ -11,6 +11,8 @@
|
|||||||
|
|
||||||
. lib/inittest
|
. lib/inittest
|
||||||
|
|
||||||
|
test -e LOCAL_LVMPOLLD && skip
|
||||||
|
|
||||||
aux prepare_vg 3 12
|
aux prepare_vg 3 12
|
||||||
|
|
||||||
lvcreate -aye --type mirror -m 1 -l 1 -n mirror $vg
|
lvcreate -aye --type mirror -m 1 -l 1 -n mirror $vg
|
||||||
|
@ -15,6 +15,8 @@
|
|||||||
|
|
||||||
. lib/inittest
|
. lib/inittest
|
||||||
|
|
||||||
|
test -e LOCAL_LVMPOLLD && skip
|
||||||
|
|
||||||
aux prepare_devs 5
|
aux prepare_devs 5
|
||||||
get_devs
|
get_devs
|
||||||
|
|
||||||
|
@ -13,8 +13,10 @@ test_description='test some blocking / non-blocking multi-vg operations'
|
|||||||
|
|
||||||
. lib/inittest
|
. lib/inittest
|
||||||
|
|
||||||
aux prepare_devs 3
|
test -e LOCAL_LVMPOLLD && skip
|
||||||
test -e LOCAL_CLVMD && skip
|
test -e LOCAL_CLVMD && skip
|
||||||
|
|
||||||
|
aux prepare_devs 3
|
||||||
pvcreate "$dev1" "$dev2"
|
pvcreate "$dev1" "$dev2"
|
||||||
vgcreate $vg "$dev1" "$dev2"
|
vgcreate $vg "$dev1" "$dev2"
|
||||||
|
|
||||||
|
@ -14,6 +14,8 @@
|
|||||||
|
|
||||||
. lib/inittest
|
. lib/inittest
|
||||||
|
|
||||||
|
test -e LOCAL_LVMPOLLD && skip
|
||||||
|
|
||||||
which mkfs.ext3 || skip
|
which mkfs.ext3 || skip
|
||||||
which fsck || skip
|
which fsck || skip
|
||||||
|
|
||||||
|
@ -11,6 +11,8 @@
|
|||||||
|
|
||||||
. lib/inittest
|
. lib/inittest
|
||||||
|
|
||||||
|
test -e LOCAL_LVMPOLLD && skip
|
||||||
|
|
||||||
aux have_cache 1 3 0 || skip
|
aux have_cache 1 3 0 || skip
|
||||||
aux prepare_vg 3
|
aux prepare_vg 3
|
||||||
|
|
||||||
|
@ -11,6 +11,8 @@
|
|||||||
|
|
||||||
. lib/inittest
|
. lib/inittest
|
||||||
|
|
||||||
|
test -e LOCAL_LVMPOLLD && skip
|
||||||
|
|
||||||
# FIXME RESYNC doesn't work in cluster with exclusive activation
|
# FIXME RESYNC doesn't work in cluster with exclusive activation
|
||||||
# seriously broken!
|
# seriously broken!
|
||||||
test -e LOCAL_CLVMD && skip
|
test -e LOCAL_CLVMD && skip
|
||||||
|
@ -11,6 +11,8 @@
|
|||||||
|
|
||||||
. lib/inittest
|
. lib/inittest
|
||||||
|
|
||||||
|
test -e LOCAL_LVMPOLLD && skip
|
||||||
|
|
||||||
aux have_raid 1 3 2 || skip
|
aux have_raid 1 3 2 || skip
|
||||||
|
|
||||||
aux prepare_vg 4
|
aux prepare_vg 4
|
||||||
|
@ -11,6 +11,7 @@
|
|||||||
|
|
||||||
. lib/inittest
|
. lib/inittest
|
||||||
|
|
||||||
|
test -e LOCAL_LVMPOLLD && skip
|
||||||
|
|
||||||
aux prepare_vg 4
|
aux prepare_vg 4
|
||||||
|
|
||||||
|
@ -13,6 +13,8 @@ TEST_RAID=raid10
|
|||||||
|
|
||||||
. shell/lvchange-raid.sh
|
. shell/lvchange-raid.sh
|
||||||
|
|
||||||
|
test -e LOCAL_LVMPOLLD && skip
|
||||||
|
|
||||||
aux have_raid 1 5 2 || skip
|
aux have_raid 1 5 2 || skip
|
||||||
|
|
||||||
run_types raid10 -m 1 -i 2 "$dev1" "$dev2" "$dev3" "$dev4"
|
run_types raid10 -m 1 -i 2 "$dev1" "$dev2" "$dev3" "$dev4"
|
||||||
|
@ -13,6 +13,8 @@ TEST_RAID=raid456
|
|||||||
|
|
||||||
. shell/lvchange-raid.sh
|
. shell/lvchange-raid.sh
|
||||||
|
|
||||||
|
test -e LOCAL_LVMPOLLD && skip
|
||||||
|
|
||||||
aux raid456_replace_works || skip
|
aux raid456_replace_works || skip
|
||||||
aux have_raid 1 5 2 || skip
|
aux have_raid 1 5 2 || skip
|
||||||
|
|
||||||
|
@ -13,6 +13,8 @@
|
|||||||
|
|
||||||
. lib/inittest
|
. lib/inittest
|
||||||
|
|
||||||
|
test -e LOCAL_LVMPOLLD && skip
|
||||||
|
|
||||||
# Proper mismatch count 1.5.2+ upstream, 1.3.5 < x < 1.4.0 in RHEL6
|
# Proper mismatch count 1.5.2+ upstream, 1.3.5 < x < 1.4.0 in RHEL6
|
||||||
aux have_raid 1 3 5 &&
|
aux have_raid 1 3 5 &&
|
||||||
! aux have_raid 1 4 0 ||
|
! aux have_raid 1 4 0 ||
|
||||||
|
@ -11,6 +11,8 @@
|
|||||||
|
|
||||||
. lib/inittest
|
. lib/inittest
|
||||||
|
|
||||||
|
test -e LOCAL_LVMPOLLD && skip
|
||||||
|
|
||||||
aux have_thin 1 0 0 || skip
|
aux have_thin 1 0 0 || skip
|
||||||
|
|
||||||
aux prepare_pvs 3
|
aux prepare_pvs 3
|
||||||
|
@ -13,6 +13,8 @@
|
|||||||
|
|
||||||
. lib/inittest
|
. lib/inittest
|
||||||
|
|
||||||
|
test -e LOCAL_LVMPOLLD && skip
|
||||||
|
|
||||||
aux have_cache 1 3 0 || skip
|
aux have_cache 1 3 0 || skip
|
||||||
aux have_raid 1 0 0 || skip
|
aux have_raid 1 0 0 || skip
|
||||||
|
|
||||||
|
@ -13,6 +13,8 @@
|
|||||||
|
|
||||||
. lib/inittest
|
. lib/inittest
|
||||||
|
|
||||||
|
test -e LOCAL_LVMPOLLD && skip
|
||||||
|
|
||||||
aux have_cache 1 3 0 || skip
|
aux have_cache 1 3 0 || skip
|
||||||
aux have_thin 1 0 0 || skip
|
aux have_thin 1 0 0 || skip
|
||||||
|
|
||||||
|
@ -13,6 +13,8 @@
|
|||||||
|
|
||||||
. lib/inittest
|
. lib/inittest
|
||||||
|
|
||||||
|
test -e LOCAL_LVMPOLLD && skip
|
||||||
|
|
||||||
aux have_cache 1 3 0 || skip
|
aux have_cache 1 3 0 || skip
|
||||||
|
|
||||||
aux prepare_vg 5 80
|
aux prepare_vg 5 80
|
||||||
|
@ -11,6 +11,8 @@
|
|||||||
|
|
||||||
. lib/inittest
|
. lib/inittest
|
||||||
|
|
||||||
|
test -e LOCAL_LVMPOLLD && skip
|
||||||
|
|
||||||
aux have_raid 1 3 0 || skip
|
aux have_raid 1 3 0 || skip
|
||||||
|
|
||||||
aux prepare_pvs 5
|
aux prepare_pvs 5
|
||||||
|
@ -14,6 +14,8 @@ export LVM_TEST_LVMETAD_DEBUG_OPTS=${LVM_TEST_LVMETAD_DEBUG_OPTS-}
|
|||||||
|
|
||||||
. lib/inittest
|
. lib/inittest
|
||||||
|
|
||||||
|
test -e LOCAL_LVMPOLLD && skip
|
||||||
|
|
||||||
get_image_pvs() {
|
get_image_pvs() {
|
||||||
local d
|
local d
|
||||||
local images
|
local images
|
||||||
|
@ -11,6 +11,8 @@
|
|||||||
|
|
||||||
. lib/inittest
|
. lib/inittest
|
||||||
|
|
||||||
|
test -e LOCAL_LVMPOLLD && skip
|
||||||
|
|
||||||
get_image_pvs() {
|
get_image_pvs() {
|
||||||
local d
|
local d
|
||||||
local images
|
local images
|
||||||
|
@ -11,6 +11,8 @@
|
|||||||
|
|
||||||
. lib/inittest
|
. lib/inittest
|
||||||
|
|
||||||
|
test -e LOCAL_LVMPOLLD && skip
|
||||||
|
|
||||||
get_image_pvs() {
|
get_image_pvs() {
|
||||||
local d
|
local d
|
||||||
local images
|
local images
|
||||||
|
@ -11,6 +11,8 @@
|
|||||||
|
|
||||||
. lib/inittest
|
. lib/inittest
|
||||||
|
|
||||||
|
test -e LOCAL_LVMPOLLD && skip
|
||||||
|
|
||||||
which mkfs.ext2 || skip
|
which mkfs.ext2 || skip
|
||||||
aux mirror_recovery_works || skip
|
aux mirror_recovery_works || skip
|
||||||
|
|
||||||
|
@ -11,6 +11,8 @@
|
|||||||
|
|
||||||
. lib/inittest
|
. lib/inittest
|
||||||
|
|
||||||
|
test -e LOCAL_LVMPOLLD && skip
|
||||||
|
|
||||||
which mkfs.ext3 || skip
|
which mkfs.ext3 || skip
|
||||||
aux have_raid 1 3 0 || skip
|
aux have_raid 1 3 0 || skip
|
||||||
|
|
||||||
|
@ -11,6 +11,8 @@
|
|||||||
|
|
||||||
. lib/inittest
|
. lib/inittest
|
||||||
|
|
||||||
|
test -e LOCAL_LVMPOLLD && skip
|
||||||
|
|
||||||
aux have_raid 1 3 0 || skip
|
aux have_raid 1 3 0 || skip
|
||||||
aux raid456_replace_works || skip
|
aux raid456_replace_works || skip
|
||||||
|
|
||||||
|
@ -11,6 +11,8 @@
|
|||||||
|
|
||||||
. lib/inittest
|
. lib/inittest
|
||||||
|
|
||||||
|
test -e LOCAL_LVMPOLLD && skip
|
||||||
|
|
||||||
aux prepare_vg 5
|
aux prepare_vg 5
|
||||||
aux lvmconf 'allocation/maximise_cling = 0' \
|
aux lvmconf 'allocation/maximise_cling = 0' \
|
||||||
'allocation/mirror_logs_require_separate_pvs = 1'
|
'allocation/mirror_logs_require_separate_pvs = 1'
|
||||||
|
@ -14,6 +14,8 @@
|
|||||||
|
|
||||||
. lib/inittest
|
. lib/inittest
|
||||||
|
|
||||||
|
test -e LOCAL_LVMPOLLD && skip
|
||||||
|
|
||||||
which mkfs.ext2 || skip
|
which mkfs.ext2 || skip
|
||||||
|
|
||||||
#
|
#
|
||||||
|
@ -11,6 +11,8 @@
|
|||||||
|
|
||||||
. lib/inittest
|
. lib/inittest
|
||||||
|
|
||||||
|
test -e LOCAL_LVMPOLLD && skip
|
||||||
|
|
||||||
aux prepare_dmeventd
|
aux prepare_dmeventd
|
||||||
aux mirror_recovery_works || skip
|
aux mirror_recovery_works || skip
|
||||||
aux prepare_vg 5
|
aux prepare_vg 5
|
||||||
|
@ -11,6 +11,8 @@
|
|||||||
|
|
||||||
. lib/inittest
|
. lib/inittest
|
||||||
|
|
||||||
|
test -e LOCAL_LVMPOLLD && skip
|
||||||
|
|
||||||
aux mirror_recovery_works || skip
|
aux mirror_recovery_works || skip
|
||||||
aux prepare_vg 5
|
aux prepare_vg 5
|
||||||
|
|
||||||
|
@ -14,6 +14,8 @@
|
|||||||
|
|
||||||
. lib/inittest
|
. lib/inittest
|
||||||
|
|
||||||
|
test -e LOCAL_LVMPOLLD && skip
|
||||||
|
|
||||||
aux prepare_pvs 1
|
aux prepare_pvs 1
|
||||||
|
|
||||||
vgcreate -s 1k $vg $(cat DEVICES)
|
vgcreate -s 1k $vg $(cat DEVICES)
|
||||||
|
@ -14,6 +14,8 @@
|
|||||||
|
|
||||||
. lib/inittest
|
. lib/inittest
|
||||||
|
|
||||||
|
test -e LOCAL_LVMPOLLD && skip
|
||||||
|
|
||||||
which mkfs.ext2 || skip
|
which mkfs.ext2 || skip
|
||||||
which fsck || skip
|
which fsck || skip
|
||||||
|
|
||||||
|
@ -12,6 +12,8 @@
|
|||||||
|
|
||||||
. lib/inittest
|
. lib/inittest
|
||||||
|
|
||||||
|
test -e LOCAL_LVMPOLLD && skip
|
||||||
|
|
||||||
aux have_thin 1 0 0 || skip
|
aux have_thin 1 0 0 || skip
|
||||||
aux have_raid 1 4 0 || skip
|
aux have_raid 1 4 0 || skip
|
||||||
|
|
||||||
|
@ -12,6 +12,8 @@
|
|||||||
|
|
||||||
. lib/inittest
|
. lib/inittest
|
||||||
|
|
||||||
|
test -e LOCAL_LVMPOLLD && skip
|
||||||
|
|
||||||
prepare_lvs() {
|
prepare_lvs() {
|
||||||
lvremove -f $vg
|
lvremove -f $vg
|
||||||
lvcreate -L10M -n $lv1 $vg
|
lvcreate -L10M -n $lv1 $vg
|
||||||
|
@ -16,6 +16,8 @@
|
|||||||
|
|
||||||
. lib/inittest
|
. lib/inittest
|
||||||
|
|
||||||
|
test -e LOCAL_LVMPOLLD && skip
|
||||||
|
|
||||||
aux have_cache 1 3 0 || skip
|
aux have_cache 1 3 0 || skip
|
||||||
|
|
||||||
# FIXME: parallel cache metadata allocator is crashing when used value 8000!
|
# FIXME: parallel cache metadata allocator is crashing when used value 8000!
|
||||||
|
@ -13,6 +13,8 @@
|
|||||||
|
|
||||||
. lib/inittest
|
. lib/inittest
|
||||||
|
|
||||||
|
test -e LOCAL_LVMPOLLD && skip
|
||||||
|
|
||||||
# FIXME update test to make something useful on <16T
|
# FIXME update test to make something useful on <16T
|
||||||
aux can_use_16T || skip
|
aux can_use_16T || skip
|
||||||
|
|
||||||
|
@ -13,6 +13,8 @@
|
|||||||
|
|
||||||
. lib/inittest
|
. lib/inittest
|
||||||
|
|
||||||
|
test -e LOCAL_LVMPOLLD && skip
|
||||||
|
|
||||||
# FIXME update test to make something useful on <16T
|
# FIXME update test to make something useful on <16T
|
||||||
aux can_use_16T || skip
|
aux can_use_16T || skip
|
||||||
|
|
||||||
|
@ -13,6 +13,8 @@
|
|||||||
|
|
||||||
. lib/inittest
|
. lib/inittest
|
||||||
|
|
||||||
|
test -e LOCAL_LVMPOLLD && skip
|
||||||
|
|
||||||
# FIXME update test to make something useful on <16T
|
# FIXME update test to make something useful on <16T
|
||||||
aux can_use_16T || skip
|
aux can_use_16T || skip
|
||||||
|
|
||||||
|
@ -10,6 +10,9 @@
|
|||||||
# Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
# Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
|
|
||||||
. lib/inittest
|
. lib/inittest
|
||||||
|
|
||||||
|
test -e LOCAL_LVMPOLLD && skip
|
||||||
|
|
||||||
aux prepare_vg 5 80
|
aux prepare_vg 5 80
|
||||||
aux lvmconf 'allocation/maximise_cling = 0' \
|
aux lvmconf 'allocation/maximise_cling = 0' \
|
||||||
'allocation/mirror_logs_require_separate_pvs = 1'
|
'allocation/mirror_logs_require_separate_pvs = 1'
|
||||||
|
@ -11,6 +11,8 @@
|
|||||||
|
|
||||||
. lib/inittest
|
. lib/inittest
|
||||||
|
|
||||||
|
test -e LOCAL_LVMPOLLD && skip
|
||||||
|
|
||||||
aux prepare_vg 2
|
aux prepare_vg 2
|
||||||
|
|
||||||
aux disable_dev "$dev1"
|
aux disable_dev "$dev1"
|
||||||
|
@ -13,6 +13,8 @@
|
|||||||
|
|
||||||
. lib/inittest
|
. lib/inittest
|
||||||
|
|
||||||
|
test -e LOCAL_LVMPOLLD && skip
|
||||||
|
|
||||||
cleanup_lvs() {
|
cleanup_lvs() {
|
||||||
lvremove -ff $vg
|
lvremove -ff $vg
|
||||||
(dm_table | not grep $vg) || \
|
(dm_table | not grep $vg) || \
|
||||||
|
@ -11,6 +11,8 @@
|
|||||||
|
|
||||||
. lib/inittest
|
. lib/inittest
|
||||||
|
|
||||||
|
test -e LOCAL_LVMPOLLD && skip
|
||||||
|
|
||||||
aux prepare_pvs 3
|
aux prepare_pvs 3
|
||||||
aux lvmconf 'allocation/maximise_cling = 0' \
|
aux lvmconf 'allocation/maximise_cling = 0' \
|
||||||
'allocation/mirror_logs_require_separate_pvs = 1'
|
'allocation/mirror_logs_require_separate_pvs = 1'
|
||||||
|
@ -11,6 +11,8 @@
|
|||||||
|
|
||||||
. lib/inittest
|
. lib/inittest
|
||||||
|
|
||||||
|
test -e LOCAL_LVMPOLLD && skip
|
||||||
|
|
||||||
lv_devices() {
|
lv_devices() {
|
||||||
test $3 -eq $(get lv_devices $1/$2 | wc -w)
|
test $3 -eq $(get lv_devices $1/$2 | wc -w)
|
||||||
}
|
}
|
||||||
|
@ -11,6 +11,8 @@
|
|||||||
|
|
||||||
. lib/inittest
|
. lib/inittest
|
||||||
|
|
||||||
|
test -e LOCAL_LVMPOLLD && skip
|
||||||
|
|
||||||
lv_devices() {
|
lv_devices() {
|
||||||
test $3 -eq $(get lv_devices $1/$2 | wc -w)
|
test $3 -eq $(get lv_devices $1/$2 | wc -w)
|
||||||
}
|
}
|
||||||
|
@ -11,6 +11,8 @@
|
|||||||
|
|
||||||
. lib/inittest
|
. lib/inittest
|
||||||
|
|
||||||
|
test -e LOCAL_LVMPOLLD && skip
|
||||||
|
|
||||||
aux prepare_vg 3
|
aux prepare_vg 3
|
||||||
|
|
||||||
# fail multiple devices
|
# fail multiple devices
|
||||||
|
@ -13,6 +13,8 @@
|
|||||||
|
|
||||||
. lib/inittest
|
. lib/inittest
|
||||||
|
|
||||||
|
test -e LOCAL_LVMPOLLD && skip
|
||||||
|
|
||||||
init_lv_() {
|
init_lv_() {
|
||||||
mkswap "$DM_DEV_DIR/$vg/$lv1"
|
mkswap "$DM_DEV_DIR/$vg/$lv1"
|
||||||
}
|
}
|
||||||
|
@ -11,6 +11,8 @@
|
|||||||
|
|
||||||
. lib/inittest
|
. lib/inittest
|
||||||
|
|
||||||
|
test -e LOCAL_LVMPOLLD && skip
|
||||||
|
|
||||||
aux prepare_pvs
|
aux prepare_pvs
|
||||||
|
|
||||||
vgcreate -s 1k $vg $(cat DEVICES)
|
vgcreate -s 1k $vg $(cat DEVICES)
|
||||||
|
@ -11,6 +11,8 @@
|
|||||||
|
|
||||||
. lib/inittest
|
. lib/inittest
|
||||||
|
|
||||||
|
test -e LOCAL_LVMPOLLD && skip
|
||||||
|
|
||||||
aux prepare_vg 9
|
aux prepare_vg 9
|
||||||
|
|
||||||
lvcreate -aey --nosync -i2 -l2 --type mirror -m1 --mirrorlog core -n $lv1 $vg 2>&1 | tee log
|
lvcreate -aey --nosync -i2 -l2 --type mirror -m1 --mirrorlog core -n $lv1 $vg 2>&1 | tee log
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user