]> sourceware.org Git - lvm2.git/commitdiff
Various small cleanups and fixes related to monitoring.
authorAlasdair Kergon <agk@redhat.com>
Mon, 16 Aug 2010 22:54:35 +0000 (22:54 +0000)
committerAlasdair Kergon <agk@redhat.com>
Mon, 16 Aug 2010 22:54:35 +0000 (22:54 +0000)
17 files changed:
WHATS_NEW
WHATS_NEW_DM
configure
configure.in
daemons/dmeventd/.exported_symbols
daemons/dmeventd/Makefile.in
daemons/dmeventd/libdevmapper-event.c
daemons/dmeventd/libdevmapper-event.h
doc/example.conf.in
lib/activate/activate.c
lib/activate/activate.h
lib/config/defaults.h
lib/mirror/mirrored.c
lib/misc/configure.h.in
lib/snapshot/snapshot.c
tools/lvchange.c
tools/vgchange.c

index e518d1e2eabc07339a1a128ab22f0ffa680acc93..05b19e098899516bf7a02c0dda6686ba315ee27a 100644 (file)
--- a/WHATS_NEW
+++ b/WHATS_NEW
@@ -1,5 +1,8 @@
 Version 2.02.73 - 
 ================================
+  Fix some exit statuses when starting/stopping monitoring fails.
+  Enable snapshot monitoring by default when dmeventd is enabled.
+  Move cloned libdevmapper-event client code from segments into lib/activate.
   Fix 'lvconvert --splitmirrors' in cluster operation.
   Fix clvmd init script exit code when executed as non-root user.
   Change default alignment of pe_start to 1MB.
index 3c652f59b6560bc2ac297884afe7aa7b7a7fc357..b91e019fd20977fbecd9417ba20f480e83a6db34 100644 (file)
@@ -1,5 +1,8 @@
 Version 1.02.54 - 
 ================================
+  Add dmeventd/executable to lvm.conf to test alternative dmeventd.
+  Export dm_event_handler_set_dmeventd_path to override built-in dmeventd path.
+  Generate libdevmapper-event exported symbols.
   Remove superfluous NULL pointer tests before dm_free from dmeventd.
   Assume dm-mod autoloading support is in kernel 2.6.36 and higher, not 2.6.35.
   Fix udev rules to support udev database content generated by older rules.
index 05d07ca37949fde41e7bfd2ecc25ef3355ce991e..5ecb76806d289451f68403f48f385392f0aea2b6 100755 (executable)
--- a/configure
+++ b/configure
@@ -688,6 +688,7 @@ DM_DEVICE_UID
 DM_DEVICE_MODE
 DM_DEVICE_GID
 DM_COMPAT
+DMEVENTD_PATH
 DMEVENTD
 DL_LIBS
 DEVMAPPER
@@ -840,6 +841,7 @@ enable_debug
 with_optimisation
 enable_profiling
 enable_testing
+enable_valgrind_pool
 enable_devmapper
 enable_udev_sync
 enable_udev_rules
@@ -1538,6 +1540,7 @@ Optional Features:
   --enable-debug          enable debugging
   --enable-profiling      gather gcov profiling data
   --enable-testing        enable testing targets in the makefile
+  --enable-valgrind-pool  enable valgrind awareness of pools
   --disable-devmapper     disable LVM2 device-mapper interaction
   --enable-udev_sync      enable synchronisation with udev processing
   --enable-udev_rules     install rule files needed for udev synchronisation
@@ -14406,6 +14409,177 @@ $as_echo "$as_me: error: ruby1.9 and valgrind are required for testing" >&2;}
    fi
 fi
 
+################################################################################
+{ $as_echo "$as_me:$LINENO: checking whether to enable valgrind awareness of pools" >&5
+$as_echo_n "checking whether to enable valgrind awareness of pools... " >&6; }
+# Check whether --enable-valgrind_pool was given.
+if test "${enable_valgrind_pool+set}" = set; then
+  enableval=$enable_valgrind_pool; VALGRIND_POOL=$enableval
+else
+  VALGRIND_POOL=no
+fi
+
+{ $as_echo "$as_me:$LINENO: result: $VALGRIND_POOL" >&5
+$as_echo "$VALGRIND_POOL" >&6; }
+
+if test "$VALGRIND_POOL" = yes; then
+
+for ac_header in valgrind/memcheck.h
+do
+as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh`
+if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
+  { $as_echo "$as_me:$LINENO: checking for $ac_header" >&5
+$as_echo_n "checking for $ac_header... " >&6; }
+if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
+  $as_echo_n "(cached) " >&6
+fi
+ac_res=`eval 'as_val=${'$as_ac_Header'}
+                $as_echo "$as_val"'`
+              { $as_echo "$as_me:$LINENO: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+else
+  # Is the header compilable?
+{ $as_echo "$as_me:$LINENO: checking $ac_header usability" >&5
+$as_echo_n "checking $ac_header usability... " >&6; }
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+#include <$ac_header>
+_ACEOF
+rm -f conftest.$ac_objext
+if { (ac_try="$ac_compile"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\""
+$as_echo "$ac_try_echo") >&5
+  (eval "$ac_compile") 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } && {
+        test -z "$ac_c_werror_flag" ||
+        test ! -s conftest.err
+       } && test -s conftest.$ac_objext; then
+  ac_header_compiler=yes
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+       ac_header_compiler=no
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+{ $as_echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
+$as_echo "$ac_header_compiler" >&6; }
+
+# Is the header present?
+{ $as_echo "$as_me:$LINENO: checking $ac_header presence" >&5
+$as_echo_n "checking $ac_header presence... " >&6; }
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <$ac_header>
+_ACEOF
+if { (ac_try="$ac_cpp conftest.$ac_ext"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\""
+$as_echo "$ac_try_echo") >&5
+  (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } >/dev/null && {
+        test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" ||
+        test ! -s conftest.err
+       }; then
+  ac_header_preproc=yes
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+  ac_header_preproc=no
+fi
+
+rm -f conftest.err conftest.$ac_ext
+{ $as_echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
+$as_echo "$ac_header_preproc" >&6; }
+
+# So?  What about this header?
+case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in
+  yes:no: )
+    { $as_echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5
+$as_echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;}
+    { $as_echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5
+$as_echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;}
+    ac_header_preproc=yes
+    ;;
+  no:yes:* )
+    { $as_echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5
+$as_echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;}
+    { $as_echo "$as_me:$LINENO: WARNING: $ac_header:     check for missing prerequisite headers?" >&5
+$as_echo "$as_me: WARNING: $ac_header:     check for missing prerequisite headers?" >&2;}
+    { $as_echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5
+$as_echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;}
+    { $as_echo "$as_me:$LINENO: WARNING: $ac_header:     section \"Present But Cannot Be Compiled\"" >&5
+$as_echo "$as_me: WARNING: $ac_header:     section \"Present But Cannot Be Compiled\"" >&2;}
+    { $as_echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5
+$as_echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;}
+    { $as_echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5
+$as_echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;}
+
+    ;;
+esac
+{ $as_echo "$as_me:$LINENO: checking for $ac_header" >&5
+$as_echo_n "checking for $ac_header... " >&6; }
+if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
+  $as_echo_n "(cached) " >&6
+else
+  eval "$as_ac_Header=\$ac_header_preproc"
+fi
+ac_res=`eval 'as_val=${'$as_ac_Header'}
+                $as_echo "$as_val"'`
+              { $as_echo "$as_me:$LINENO: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+
+fi
+as_val=`eval 'as_val=${'$as_ac_Header'}
+                $as_echo "$as_val"'`
+   if test "x$as_val" = x""yes; then
+  cat >>confdefs.h <<_ACEOF
+#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1
+_ACEOF
+
+else
+  { { $as_echo "$as_me:$LINENO: error: bailing out" >&5
+$as_echo "$as_me: error: bailing out" >&2;}
+   { (exit 1); exit 1; }; }
+fi
+
+done
+
+
+cat >>confdefs.h <<\_ACEOF
+#define VALGRIND_POOL 1
+_ACEOF
+
+fi
+
 ################################################################################
 { $as_echo "$as_me:$LINENO: checking whether to use device-mapper" >&5
 $as_echo_n "checking whether to use device-mapper... " >&6; }
@@ -18043,10 +18217,11 @@ LVM_LIBAPI=`echo "$VER" | $AWK -F '[()]' '{print $2}'`
 
 
 
+
 
 
 ################################################################################
-ac_config_files="$ac_config_files Makefile make.tmpl daemons/Makefile daemons/clvmd/Makefile daemons/cmirrord/Makefile daemons/dmeventd/Makefile daemons/dmeventd/libdevmapper-event.pc daemons/dmeventd/plugins/Makefile daemons/dmeventd/plugins/lvm2/Makefile daemons/dmeventd/plugins/mirror/Makefile daemons/dmeventd/plugins/snapshot/Makefile doc/Makefile doc/example.conf include/.symlinks include/Makefile lib/Makefile lib/format1/Makefile lib/format_pool/Makefile lib/locking/Makefile lib/mirror/Makefile lib/replicator/Makefile lib/misc/lvm-version.h lib/snapshot/Makefile libdm/Makefile libdm/libdevmapper.pc liblvm/Makefile liblvm/liblvm2app.pc man/Makefile po/Makefile scripts/clvmd_init_red_hat scripts/cmirrord_init_red_hat scripts/lvm2_monitoring_init_red_hat scripts/Makefile test/Makefile test/api/Makefile tools/Makefile udev/Makefile unit-tests/datastruct/Makefile unit-tests/regex/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/mirror/Makefile daemons/dmeventd/plugins/snapshot/Makefile doc/Makefile doc/example.conf include/.symlinks include/Makefile lib/Makefile lib/format1/Makefile lib/format_pool/Makefile lib/locking/Makefile lib/mirror/Makefile lib/replicator/Makefile lib/misc/lvm-version.h lib/snapshot/Makefile libdm/Makefile libdm/libdevmapper.pc liblvm/Makefile liblvm/liblvm2app.pc man/Makefile po/Makefile scripts/clvmd_init_red_hat scripts/cmirrord_init_red_hat scripts/lvm2_monitoring_init_red_hat scripts/Makefile test/Makefile test/api/Makefile tools/Makefile udev/Makefile unit-tests/datastruct/Makefile unit-tests/regex/Makefile unit-tests/mm/Makefile"
 
 cat >confcache <<\_ACEOF
 # This file is a shell script that caches the results of configure
@@ -18684,6 +18859,7 @@ do
     "udev/Makefile") CONFIG_FILES="$CONFIG_FILES udev/Makefile" ;;
     "unit-tests/datastruct/Makefile") CONFIG_FILES="$CONFIG_FILES unit-tests/datastruct/Makefile" ;;
     "unit-tests/regex/Makefile") CONFIG_FILES="$CONFIG_FILES unit-tests/regex/Makefile" ;;
+    "unit-tests/mm/Makefile") CONFIG_FILES="$CONFIG_FILES unit-tests/mm/Makefile" ;;
 
   *) { { $as_echo "$as_me:$LINENO: error: invalid argument: $ac_config_target" >&5
 $as_echo "$as_me: error: invalid argument: $ac_config_target" >&2;}
index 70c6fa1f47c0e4354bc3367840846a23cfe92801..3c39151158af086b8dc24f389cc2c3e1fe6db923 100644 (file)
@@ -1251,6 +1251,7 @@ AC_SUBST(DLM_CFLAGS)
 AC_SUBST(DLM_LIBS)
 AC_SUBST(DL_LIBS)
 AC_SUBST(DMEVENTD)
+AC_SUBST(DMEVENTD_PATH)
 AC_SUBST(DM_COMPAT)
 AC_SUBST(DM_DEVICE_GID)
 AC_SUBST(DM_DEVICE_MODE)
index 6c892d302a4ece650fe795ccfa6116e549c564b7..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 100644 (file)
@@ -1,19 +0,0 @@
-dm_event_handler_create
-dm_event_handler_destroy
-dm_event_handler_set_dso
-dm_event_handler_set_dev_name
-dm_event_handler_set_uuid
-dm_event_handler_set_major
-dm_event_handler_set_minor
-dm_event_handler_set_event_mask
-dm_event_handler_get_dso
-dm_event_handler_get_devname
-dm_event_handler_get_uuid
-dm_event_handler_get_major
-dm_event_handler_get_minor
-dm_event_handler_get_event_mask
-dm_event_register_handler
-dm_event_unregister_handler
-dm_event_get_registered_device
-dm_event_handler_set_timeout
-dm_event_handler_get_timeout
index 326f86664d35915c881adef1dfcd2c9df44dafc0..e99e089bc296dc7e1ee9c49e5e551c7a56eea17d 100644 (file)
@@ -48,6 +48,9 @@ CFLOW_LIST = $(SOURCES)
 CFLOW_LIST_TARGET = $(LIB_NAME).cflow
 CFLOW_TARGET = dmeventd
 
+EXPORTED_HEADER = $(srcdir)/libdevmapper-event.h
+EXPORTED_FN_PREFIX = dm_event
+
 include $(top_builddir)/make.tmpl
 
 all: device-mapper
@@ -102,4 +105,4 @@ install: install_include install_lib install_dmeventd
 
 install_device-mapper: install_include install_lib install_dmeventd
 
-DISTCLEAN_TARGETS += libdevmapper-event.pc
+DISTCLEAN_TARGETS += libdevmapper-event.pc .exported_symbols_generated
index 242e02a8bf9d1c7e54448427344a847c8c40b886..61ca340c000d51379415785e0dcafa4102cc46ff 100644 (file)
@@ -35,6 +35,8 @@ static int _sequence_nr = 0;
 struct dm_event_handler {
        char *dso;
 
+       char *dmeventd_path;
+
        char *dev_name;
 
        char *uuid;
@@ -60,6 +62,7 @@ struct dm_event_handler *dm_event_handler_create(void)
        if (!(dmevh = dm_malloc(sizeof(*dmevh))))
                return NULL;
 
+       dmevh->dmeventd_path = NULL;
        dmevh->dso = dmevh->dev_name = dmevh->uuid = NULL;
        dmevh->major = dmevh->minor = 0;
        dmevh->mask = 0;
@@ -72,9 +75,24 @@ void dm_event_handler_destroy(struct dm_event_handler *dmevh)
 {
        _dm_event_handler_clear_dev_info(dmevh);
        dm_free(dmevh->dso);
+       dm_free(dmevh->dmeventd_path);
        dm_free(dmevh);
 }
 
+int dm_event_handler_set_dmeventd_path(struct dm_event_handler *dmevh, const char *dmeventd_path)
+{
+       if (!dmeventd_path) /* noop */
+               return 0;
+
+       dm_free(dmevh->dmeventd_path);
+
+       dmevh->dmeventd_path = dm_strdup(dmeventd_path);
+       if (!dmevh->dmeventd_path)
+               return -ENOMEM;
+
+       return 0;
+}
+
 int dm_event_handler_set_dso(struct dm_event_handler *dmevh, const char *path)
 {
        if (!path) /* noop */
@@ -387,13 +405,13 @@ static int _daemon_talk(struct dm_event_fifos *fifos,
  *
  * Returns: 1 on success, 0 otherwise
  */
-static int _start_daemon(struct dm_event_fifos *fifos)
+static int _start_daemon(char *dmeventd_path, struct dm_event_fifos *fifos)
 {
        int pid, ret = 0;
        int status;
        struct stat statbuf;
-       char dmeventdpath[] = DMEVENTD_PATH; /* const type for execvp */
-       char * const args[] = { dmeventdpath, NULL };
+       char default_dmeventd_path[] = DMEVENTD_PATH;
+       char *args[] = { dmeventd_path ? : default_dmeventd_path, NULL };
 
        if (stat(fifos->client_path, &statbuf))
                goto start_server;
@@ -449,17 +467,19 @@ static int _start_daemon(struct dm_event_fifos *fifos)
 }
 
 /* Initialize client. */
-static int _init_client(struct dm_event_fifos *fifos)
+static int _init_client(char *dmeventd_path, struct dm_event_fifos *fifos)
 {
        /* FIXME? Is fifo the most suitable method? Why not share
           comms/daemon code with something else e.g. multipath? */
 
        /* init fifos */
        memset(fifos, 0, sizeof(*fifos));
+
+       /* FIXME Make these either configurable or depend directly on dmeventd_path */
        fifos->client_path = DM_EVENT_FIFO_CLIENT;
        fifos->server_path = DM_EVENT_FIFO_SERVER;
 
-       if (!_start_daemon(fifos)) {
+       if (!_start_daemon(dmeventd_path, fifos)) {
                stack;
                return 0;
        }
@@ -544,14 +564,14 @@ failed:
 }
 
 /* Handle the event (de)registration call and return negative error codes. */
-static int _do_event(int cmd, struct dm_event_daemon_message *msg,
+static int _do_event(int cmd, char *dmeventd_path, struct dm_event_daemon_message *msg,
                     const char *dso_name, const char *dev_name,
                     enum dm_event_mask evmask, uint32_t timeout)
 {
        int ret;
        struct dm_event_fifos fifos;
 
-       if (!_init_client(&fifos)) {
+       if (!_init_client(dmeventd_path, &fifos)) {
                stack;
                return -ESRCH;
        }
@@ -585,7 +605,7 @@ int dm_event_register_handler(const struct dm_event_handler *dmevh)
 
        uuid = dm_task_get_uuid(dmt);
 
-       if ((err = _do_event(DM_EVENT_CMD_REGISTER_FOR_EVENT, &msg,
+       if ((err = _do_event(DM_EVENT_CMD_REGISTER_FOR_EVENT, dmevh->dmeventd_path, &msg,
                             dmevh->dso, uuid, dmevh->mask, dmevh->timeout)) < 0) {
                log_error("%s: event registration failed: %s",
                          dm_task_get_name(dmt),
@@ -614,7 +634,7 @@ int dm_event_unregister_handler(const struct dm_event_handler *dmevh)
 
        uuid = dm_task_get_uuid(dmt);
 
-       if ((err = _do_event(DM_EVENT_CMD_UNREGISTER_FOR_EVENT, &msg,
+       if ((err = _do_event(DM_EVENT_CMD_UNREGISTER_FOR_EVENT, dmevh->dmeventd_path, &msg,
                            dmevh->dso, uuid, dmevh->mask, dmevh->timeout)) < 0) {
                log_error("%s: event deregistration failed: %s",
                          dm_task_get_name(dmt),
@@ -689,7 +709,7 @@ int dm_event_get_registered_device(struct dm_event_handler *dmevh, int next)
        uuid = dm_task_get_uuid(dmt);
 
        if (!(ret = _do_event(next ? DM_EVENT_CMD_GET_NEXT_REGISTERED_DEVICE :
-                            DM_EVENT_CMD_GET_REGISTERED_DEVICE,
+                            DM_EVENT_CMD_GET_REGISTERED_DEVICE, dmevh->dmeventd_path,
                              &msg, dmevh->dso, uuid, dmevh->mask, 0))) {
                /* FIXME this will probably horribly break if we get
                   ill-formatted reply */
index 25f5152ada098806b084dd3efe6b3e07583d21b6..0de20c145ffd8751269f36fc892ef21bf857b7b1 100644 (file)
@@ -55,12 +55,17 @@ void dm_event_handler_destroy(struct dm_event_handler *dmevh);
 /*
  * Path of shared library to handle events.
  *
- * All of dso, device_name and uuid strings are duplicated, you do not
- * need to keep the pointers valid after the call succeeds. Thes may
- * return -ENOMEM though.
+ * All of dmeventd, dso, device_name and uuid strings are duplicated so
+ * you do not need to keep the pointers valid after the call succeeds.
+ * They may return -ENOMEM though.
  */
 int dm_event_handler_set_dso(struct dm_event_handler *dmevh, const char *path);
 
+/*
+ * Path of dmeventd binary.
+ */
+int dm_event_handler_set_dmeventd_path(struct dm_event_handler *dmevh, const char *dmeventd_path);
+
 /*
  * Identify the device to monitor by exactly one of device_name, uuid or
  * device number. String arguments are duplicated, see above.
index a107d2bfa621a4b60bcdd5cdc55af5e41bafba1f..7edae715387586e2bffc22e70b0537b0453de96a 100644 (file)
@@ -509,9 +509,13 @@ dmeventd {
     # snapshot_library is the library used when monitoring a snapshot device.
     #
     # "libdevmapper-event-lvm2snapshot.so" monitors the filling of
-    # snapshots and emits a warning through syslog, when the use of
-    # snapshot exceedes 80%. The warning is repeated when 85%, 90% and
-    # 95% of the snapshot are filled.
+    # snapshots and emits a warning through syslog when the use of
+    # the snapshot exceeds 80%. The warning is repeated when 85%, 90% and
+    # 95% of the snapshot is filled.
 
     snapshot_library = "libdevmapper-event-lvm2snapshot.so"
+
+    # Full path of the dmeventd binary.
+    #
+    # executable = "@DMEVENTD_PATH@"
 }
index c3ed89eb730c22869742b428c9557c690cea8959..0e0bd8b8bd305cba0453d27ff4b272b183efabfe 100644 (file)
@@ -28,6 +28,7 @@
 #include "config.h"
 #include "filter.h"
 #include "segtype.h"
+#include "sharedlib.h"
 
 #include <limits.h>
 #include <fcntl.h>
@@ -727,6 +728,112 @@ int lv_is_active(struct logical_volume *lv)
        return 1;
 }
 
+#ifdef DMEVENTD
+static struct dm_event_handler *_create_dm_event_handler(struct cmd_context *cmd, const char *dmuuid, const char *dso,
+                                                        const int timeout, enum dm_event_mask mask)
+{
+       struct dm_event_handler *dmevh;
+
+       if (!(dmevh = dm_event_handler_create()))
+               return_NULL;
+
+       if (dm_event_handler_set_dmeventd_path(dmevh, find_config_tree_str(cmd, "dmeventd/executable", NULL)))
+               goto_bad;
+
+       if (dm_event_handler_set_dso(dmevh, dso))
+               goto_bad;
+
+       if (dm_event_handler_set_uuid(dmevh, dmuuid))
+               goto_bad;
+
+       dm_event_handler_set_timeout(dmevh, timeout);
+       dm_event_handler_set_event_mask(dmevh, mask);
+
+       return dmevh;
+
+bad:
+       dm_event_handler_destroy(dmevh);
+       return NULL;
+}
+
+char *get_monitor_dso_path(struct cmd_context *cmd, const char *libpath)
+{
+       char *path;
+
+       if (!(path = dm_pool_alloc(cmd->mem, PATH_MAX))) {
+               log_error("Failed to allocate dmeventd library path.");
+               return NULL;
+       }
+
+       get_shared_library_path(cmd, libpath, path, PATH_MAX);
+
+       return path;
+}
+
+int target_registered_with_dmeventd(struct cmd_context *cmd, const char *dso, const char *lvid, int *pending)
+{
+       char *uuid;
+       enum dm_event_mask evmask = 0;
+       struct dm_event_handler *dmevh;
+
+       *pending = 0;
+
+       if (!dso)
+               return_0;
+
+       if (!(uuid = build_dm_uuid(cmd->mem, lvid, NULL)))
+               return_0;
+
+       if (!(dmevh = _create_dm_event_handler(cmd, uuid, dso, 0, DM_EVENT_ALL_ERRORS)))
+               return_0;
+
+       if (dm_event_get_registered_device(dmevh, 0)) {
+               dm_event_handler_destroy(dmevh);
+               return 0;
+       }
+
+       evmask = dm_event_handler_get_event_mask(dmevh);
+       if (evmask & DM_EVENT_REGISTRATION_PENDING) {
+               *pending = 1;
+               evmask &= ~DM_EVENT_REGISTRATION_PENDING;
+       }
+
+       dm_event_handler_destroy(dmevh);
+
+       return evmask;
+}
+
+int target_register_events(struct cmd_context *cmd, const char *dso, const char *lvid,
+                           int evmask __attribute__((unused)), int set, int timeout)
+{
+       char *uuid;
+       struct dm_event_handler *dmevh;
+       int r;
+
+       if (!dso)
+               return_0;
+
+       if (!(uuid = build_dm_uuid(cmd->mem, lvid, NULL)))
+               return_0;
+
+       if (!(dmevh = _create_dm_event_handler(cmd, uuid, dso, timeout,
+                                              DM_EVENT_ALL_ERRORS | (timeout ? DM_EVENT_TIMEOUT : 0))))
+               return_0;
+
+       r = set ? dm_event_register_handler(dmevh) : dm_event_unregister_handler(dmevh);
+
+       dm_event_handler_destroy(dmevh);
+
+       if (!r)
+               return_0;
+
+       log_info("%s %s for events", set ? "Monitored" : "Unmonitored", uuid);
+
+       return 1;
+}
+
+#endif
+
 /*
  * Returns 0 if an attempt to (un)monitor the device failed.
  * Returns 1 otherwise.
index 6a668fe80e11785e172ac2cec65ee9a892ce20f3..d908eefd612aef4736adf511f6477c0b21a1cff9 100644 (file)
@@ -44,7 +44,7 @@ int module_present(struct cmd_context *cmd, const char *target_name);
 int target_present(struct cmd_context *cmd, const char *target_name,
                   int use_modprobe);
 int target_version(const char *target_name, uint32_t *maj,
-                   uint32_t *min, uint32_t *patchlevel);
+                  uint32_t *min, uint32_t *patchlevel);
 int list_segment_modules(struct dm_pool *mem, const struct lv_segment *seg,
                         struct dm_list *modules);
 int list_lv_modules(struct dm_pool *mem, const struct logical_volume *lv,
@@ -102,6 +102,14 @@ int lv_has_target_type(struct dm_pool *mem, struct logical_volume *lv,
 int monitor_dev_for_events(struct cmd_context *cmd,
                            struct logical_volume *lv, int do_reg);
 
+#ifdef DMEVENTD
+#  include "libdevmapper-event.h"
+char *get_monitor_dso_path(struct cmd_context *cmd, const char *libpath);
+int target_registered_with_dmeventd(struct cmd_context *cmd, const char *libpath, const char *lvid, int *pending);
+int target_register_events(struct cmd_context *cmd, const char *dso, const char *lvid,
+                           int evmask __attribute__((unused)), int set, int timeout);
+#endif
+
 /*
  * Returns 1 if PV has a dependency tree that uses anything in VG.
  */
index 4a5feb28e1ca6b28d633e4a8b6efa2a289ba47bd..b6308f45439b1fbb2aabae6f1634296c8f1545b4 100644 (file)
@@ -48,6 +48,7 @@
 #define DEFAULT_MIRROR_IMAGE_FAULT_POLICY "remove"
 #define DEFAULT_MIRROR_MAX_IMAGES 8 /* limited by kernel DM_KCOPYD_MAX_REGIONS */
 #define DEFAULT_DMEVENTD_MIRROR_LIB "libdevmapper-event-lvm2mirror.so"
+#define DEFAULT_DMEVENTD_SNAPSHOT_LIB "libdevmapper-event-lvm2snapshot.so"
 #define DEFAULT_DMEVENTD_MONITOR 1
 #define DEFAULT_BACKGROUND_POLLING 1
 
index 07658b007d7fd73e31a1c695ded80dde10d0dc4a..9b89ca28b1d201a39a134ad124585fe2ab78b674 100644 (file)
 
 #include <sys/utsname.h>
 
-#ifdef DMEVENTD
-#  include "libdevmapper-event.h"
-#endif
-
 static int _block_on_error_available = 0;
 static unsigned _mirror_attributes = 0;
 
@@ -520,19 +516,19 @@ static int _mirrored_target_present(struct cmd_context *cmd,
                        } else if (module_present(cmd, "log-userspace"))
                                _mirror_attributes |= MIRROR_LOG_CLUSTERED;
 
-                        if (!(_mirror_attributes & MIRROR_LOG_CLUSTERED))
-                                log_verbose("Cluster mirror log module is not available");
+                       if (!(_mirror_attributes & MIRROR_LOG_CLUSTERED))
+                               log_verbose("Cluster mirror log module is not available");
 
-                        /*
-                         * The cluster mirror log daemon must be running,
-                         * otherwise, the kernel module will fail to make
-                         * contact.
-                         */
+                       /*
+                        * The cluster mirror log daemon must be running,
+                        * otherwise, the kernel module will fail to make
+                        * contact.
+                        */
 #ifdef CMIRRORD_PIDFILE
-                        if (!dm_daemon_is_running(CMIRRORD_PIDFILE)) {
-                                log_verbose("Cluster mirror log daemon is not running");
-                                _mirror_attributes &= ~MIRROR_LOG_CLUSTERED;
-                        }
+                       if (!dm_daemon_is_running(CMIRRORD_PIDFILE)) {
+                               log_verbose("Cluster mirror log daemon is not running");
+                               _mirror_attributes &= ~MIRROR_LOG_CLUSTERED;
+                       }
 #else
                        log_verbose("Cluster mirror log daemon not included in build");
                        _mirror_attributes &= ~MIRROR_LOG_CLUSTERED;
@@ -546,116 +542,23 @@ static int _mirrored_target_present(struct cmd_context *cmd,
 }
 
 #ifdef DMEVENTD
-static int _get_mirror_dso_path(struct cmd_context *cmd, char **dso)
+static const char *_get_mirror_dso_path(struct cmd_context *cmd)
 {
-       char *path;
-       const char *libpath;
-
-       if (!(path = dm_pool_alloc(cmd->mem, PATH_MAX))) {
-               log_error("Failed to allocate dmeventd library path.");
-               return 0;
-       }
-
-       libpath = find_config_tree_str(cmd, "dmeventd/mirror_library",
-                                      DEFAULT_DMEVENTD_MIRROR_LIB);
-
-       get_shared_library_path(cmd, libpath, path, PATH_MAX);
-
-       *dso = path;
-
-       return 1;
+       return get_monitor_dso_path(cmd, find_config_tree_str(cmd, "dmeventd/mirror_library",
+                                                             DEFAULT_DMEVENTD_MIRROR_LIB));
 }
 
-static struct dm_event_handler *_create_dm_event_handler(const char *dmuuid,
-                                                        const char *dso,
-                                                        enum dm_event_mask mask)
+static int _target_registered(struct lv_segment *seg, int *pending)
 {
-       struct dm_event_handler *dmevh;
-
-       if (!(dmevh = dm_event_handler_create()))
-               return_0;
-
-       if (dm_event_handler_set_dso(dmevh, dso))
-               goto fail;
-
-       if (dm_event_handler_set_uuid(dmevh, dmuuid))
-               goto fail;
-
-       dm_event_handler_set_event_mask(dmevh, mask);
-       return dmevh;
-
-fail:
-       dm_event_handler_destroy(dmevh);
-       return NULL;
-}
-
-static int _target_monitored(struct lv_segment *seg, int *pending)
-{
-       char *dso, *uuid;
-       struct logical_volume *lv;
-       struct volume_group *vg;
-       enum dm_event_mask evmask = 0;
-       struct dm_event_handler *dmevh;
-
-       lv = seg->lv;
-       vg = lv->vg;
-
-       *pending = 0;
-       if (!_get_mirror_dso_path(vg->cmd, &dso))
-               return_0;
-
-       if (!(uuid = build_dm_uuid(vg->cmd->mem, lv->lvid.s, NULL)))
-               return_0;
-
-       if (!(dmevh = _create_dm_event_handler(uuid, dso, DM_EVENT_ALL_ERRORS)))
-               return_0;
-
-       if (dm_event_get_registered_device(dmevh, 0)) {
-               dm_event_handler_destroy(dmevh);
-               return 0;
-       }
-
-       evmask = dm_event_handler_get_event_mask(dmevh);
-       if (evmask & DM_EVENT_REGISTRATION_PENDING) {
-               *pending = 1;
-               evmask &= ~DM_EVENT_REGISTRATION_PENDING;
-       }
-
-       dm_event_handler_destroy(dmevh);
-
-       return evmask;
+       return target_registered_with_dmeventd(seg->lv->vg->cmd, _get_mirror_dso_path(seg->lv->vg->cmd),
+                                              seg->lv->lvid.s, pending);
 }
 
 /* FIXME This gets run while suspended and performs banned operations. */
-static int _target_set_events(struct lv_segment *seg,
-                             int evmask __attribute__((unused)), int set)
+static int _target_set_events(struct lv_segment *seg, int evmask, int set)
 {
-       char *dso, *uuid;
-       struct logical_volume *lv;
-       struct volume_group *vg;
-       struct dm_event_handler *dmevh;
-       int r;
-
-       lv = seg->lv;
-       vg = lv->vg;
-
-       if (!_get_mirror_dso_path(vg->cmd, &dso))
-               return_0;
-
-       if (!(uuid = build_dm_uuid(vg->cmd->mem, lv->lvid.s, NULL)))
-               return_0;
-
-       if (!(dmevh = _create_dm_event_handler(uuid, dso, DM_EVENT_ALL_ERRORS)))
-               return_0;
-
-       r = set ? dm_event_register_handler(dmevh) : dm_event_unregister_handler(dmevh);
-       dm_event_handler_destroy(dmevh);
-       if (!r)
-               return_0;
-
-       log_info("%s %s for events", set ? "Monitored" : "Unmonitored", uuid);
-
-       return 1;
+       return target_register_events(seg->lv->vg->cmd, _get_mirror_dso_path(seg->lv->vg->cmd),
+                                     seg->lv->lvid.s, evmask, set, 0);
 }
 
 static int _target_monitor_events(struct lv_segment *seg, int events)
@@ -710,7 +613,7 @@ static struct segtype_handler _mirrored_ops = {
        .target_present = _mirrored_target_present,
        .check_transient_status = _mirrored_transient_status,
 #ifdef DMEVENTD
-       .target_monitored = _target_monitored,
+       .target_monitored = _target_registered,
        .target_monitor_events = _target_monitor_events,
        .target_unmonitor_events = _target_unmonitor_events,
 #endif
@@ -735,7 +638,12 @@ struct segment_type *init_segtype(struct cmd_context *cmd)
        segtype->ops = &_mirrored_ops;
        segtype->name = "mirror";
        segtype->private = NULL;
-       segtype->flags = SEG_AREAS_MIRRORED | SEG_MONITORED;
+       segtype->flags = SEG_AREAS_MIRRORED;
+
+#ifdef DMEVENTD
+       if (_get_mirror_dso_path(cmd))
+               segtype->flags |= SEG_MONITORED;
+#endif
 
        log_very_verbose("Initialised segtype: %s", segtype->name);
 
index 3a3767895ba7c2bab55b7ad4108a5748774d9046..016147171d31a500ee428bad8253b04ba6225cae 100644 (file)
 /* Define to 1 if you have the <utmpx.h> header file. */
 #undef HAVE_UTMPX_H
 
+/* Define to 1 if you have the <valgrind/memcheck.h> header file. */
+#undef HAVE_VALGRIND_MEMCHECK_H
+
 /* Define to 1 if you have the `vfork' function. */
 #undef HAVE_VFORK
 
 /* Define to 1 to enable synchronisation with udev processing. */
 #undef UDEV_SYNC_SUPPORT
 
+/* Enable a valgrind aware build of pool */
+#undef VALGRIND_POOL
+
 /* Define for Solaris 2.5.1 so the uint32_t typedef from <sys/synch.h>,
    <pthread.h>, or <semaphore.h> is not used. If the typedef were allowed, the
    #define below would cause a syntax error. */
index dda0bc7ae9ec7cee1b2c51ab8887f021437f4e1d..0dcd800c641d61a0aa960c3b10a129b329ce17fa 100644 (file)
 #include "config.h"
 #include "activate.h"
 #include "str_list.h"
-#ifdef DMEVENTD
-#  include "sharedlib.h"
-#  include "libdevmapper-event.h"
-#endif
+#include "defaults.h"
 
 static const char *_snap_name(const struct lv_segment *seg)
 {
@@ -164,117 +161,25 @@ static int _snap_target_present(struct cmd_context *cmd,
 }
 
 #ifdef DMEVENTD
-static int _get_snapshot_dso_path(struct cmd_context *cmd, char **dso)
-{
-       char *path;
-       const char *libpath;
-
-       if (!(path = dm_pool_alloc(cmd->mem, PATH_MAX))) {
-               log_error("Failed to allocate dmeventd library path.");
-               return 0;
-       }
-
-       libpath = find_config_tree_str(cmd, "dmeventd/snapshot_library", NULL);
-       if (!libpath)
-               return 0;
-
-       get_shared_library_path(cmd, libpath, path, PATH_MAX);
-
-       *dso = path;
 
-       return 1;
-}
-
-static struct dm_event_handler *_create_dm_event_handler(const char *dmuuid,
-                                                        const char *dso,
-                                                        const int timeout,
-                                                        enum dm_event_mask mask)
+static const char *_get_snapshot_dso_path(struct cmd_context *cmd)
 {
-       struct dm_event_handler *dmevh;
-
-       if (!(dmevh = dm_event_handler_create()))
-               return_0;
-
-       if (dm_event_handler_set_dso(dmevh, dso))
-               goto fail;
-
-       if (dm_event_handler_set_uuid(dmevh, dmuuid))
-               goto fail;
-
-       dm_event_handler_set_timeout(dmevh, timeout);
-       dm_event_handler_set_event_mask(dmevh, mask);
-       return dmevh;
-
-fail:
-       dm_event_handler_destroy(dmevh);
-       return NULL;
+       return get_monitor_dso_path(cmd, find_config_tree_str(cmd, "dmeventd/snapshot_library",
+                                                             DEFAULT_DMEVENTD_SNAPSHOT_LIB));
 }
 
 static int _target_registered(struct lv_segment *seg, int *pending)
 {
-       char *dso, *uuid;
-       struct logical_volume *lv;
-       struct volume_group *vg;
-       enum dm_event_mask evmask = 0;
-       struct dm_event_handler *dmevh;
-
-       lv = seg->lv;
-       vg = lv->vg;
-
-       *pending = 0;
-       if (!_get_snapshot_dso_path(vg->cmd, &dso))
-               return_0;
-
-       if (!(uuid = build_dm_uuid(vg->cmd->mem, seg->cow->lvid.s, NULL)))
-               return_0;
-
-       if (!(dmevh = _create_dm_event_handler(uuid, dso, 0, DM_EVENT_ALL_ERRORS)))
-               return_0;
-
-       if (dm_event_get_registered_device(dmevh, 0)) {
-               dm_event_handler_destroy(dmevh);
-               return 0;
-       }
-
-       evmask = dm_event_handler_get_event_mask(dmevh);
-       if (evmask & DM_EVENT_REGISTRATION_PENDING) {
-               *pending = 1;
-               evmask &= ~DM_EVENT_REGISTRATION_PENDING;
-       }
-
-       dm_event_handler_destroy(dmevh);
-
-       return evmask;
+       return target_registered_with_dmeventd(seg->lv->vg->cmd, _get_snapshot_dso_path(seg->lv->vg->cmd),
+                                              seg->cow->lvid.s, pending);
 }
 
 /* FIXME This gets run while suspended and performs banned operations. */
-static int _target_set_events(struct lv_segment *seg,
-                             int events __attribute__((unused)), int set)
+static int _target_set_events(struct lv_segment *seg, int evmask, int set)
 {
-       char *dso, *uuid;
-       struct volume_group *vg = seg->lv->vg;
-       struct dm_event_handler *dmevh;
-       int r;
-
-       if (!_get_snapshot_dso_path(vg->cmd, &dso))
-               return_0;
-
-       if (!(uuid = build_dm_uuid(vg->cmd->mem, seg->cow->lvid.s, NULL)))
-               return_0;
-
-       /* FIXME: make timeout configurable */
-       if (!(dmevh = _create_dm_event_handler(uuid, dso, 10,
-               DM_EVENT_ALL_ERRORS|DM_EVENT_TIMEOUT)))
-               return_0;
-
-       r = set ? dm_event_register_handler(dmevh) : dm_event_unregister_handler(dmevh);
-       dm_event_handler_destroy(dmevh);
-       if (!r)
-               return_0;
-
-       log_info("%s %s for events", set ? "Registered" : "Unregistered", uuid);
-
-       return 1;
+       /* FIXME Make timeout (10) configurable */
+       return target_register_events(seg->lv->vg->cmd, _get_snapshot_dso_path(seg->lv->vg->cmd),
+                                     seg->cow->lvid.s, evmask, set, 10);
 }
 
 static int _target_register_events(struct lv_segment *seg,
@@ -335,9 +240,6 @@ struct segment_type *init_segtype(struct cmd_context *cmd)
 #endif
 {
        struct segment_type *segtype = dm_malloc(sizeof(*segtype));
-#ifdef DMEVENTD
-       char *dso;
-#endif
 
        if (!segtype)
                return_NULL;
@@ -349,7 +251,7 @@ struct segment_type *init_segtype(struct cmd_context *cmd)
        segtype->flags = SEG_SNAPSHOT;
 
 #ifdef DMEVENTD
-       if (_get_snapshot_dso_path(cmd, &dso))
+       if (_get_snapshot_dso_path(cmd))
                segtype->flags |= SEG_MONITORED;
 #endif
        log_very_verbose("Initialised segtype: %s", segtype->name);
index 4186b53cae79cdeb9b4078ba6eaf670902954a8f..97c6044f4045454b764604f290393dd11e92f084 100644 (file)
@@ -97,7 +97,7 @@ static int lvchange_monitoring(struct cmd_context *cmd,
 
        if ((dmeventd_monitor_mode() != DMEVENTD_MONITOR_IGNORE) &&
            !monitor_dev_for_events(cmd, lv, dmeventd_monitor_mode()))
-               stack;
+               return_0;
 
        return 1;
 }
index 960d8ddf7e93c8df29c2faba68dc0dd2a6663290..fbd403f2ebb9ce03a87f176fcb0d08da641e876a 100644 (file)
 
 #include "tools.h"
 
+/*
+ * Increments *count by the number of _new_ monitored devices.
+ */
 static int _monitor_lvs_in_vg(struct cmd_context *cmd,
-                              struct volume_group *vg, int reg)
+                             struct volume_group *vg, int reg, int *count)
 {
        struct lv_list *lvl;
        struct logical_volume *lv;
        struct lvinfo info;
        int lv_active;
-       int count = 0;
+       int r = ECMD_PROCESSED;
 
        dm_list_iterate_items(lvl, &vg->lvs) {
                lv = lvl->lv;
@@ -39,16 +42,13 @@ static int _monitor_lvs_in_vg(struct cmd_context *cmd,
                        continue;
 
                if (!monitor_dev_for_events(cmd, lv, reg)) {
+                       r = ECMD_FAILED;
                        continue;
                } else
-                       count++;
+                       (*count)++;
        }
 
-       /*
-        * returns the number of _new_ monitored devices
-        */
-
-       return count;
+       return r;
 }
 
 static int _poll_lvs_in_vg(struct cmd_context *cmd,
@@ -160,17 +160,18 @@ static int _activate_lvs_in_vg(struct cmd_context *cmd,
 
 static int _vgchange_monitoring(struct cmd_context *cmd, struct volume_group *vg)
 {
-       int monitored;
+       int ret_max = ECMD_PROCESSED;
+       int monitored = 0;
 
        if (lvs_in_vg_activated(vg) &&
            dmeventd_monitor_mode() != DMEVENTD_MONITOR_IGNORE) {
-               monitored = _monitor_lvs_in_vg(cmd, vg, dmeventd_monitor_mode());
+               ret_max = max(ret_max, _monitor_lvs_in_vg(cmd, vg, dmeventd_monitor_mode(), &monitored));
                log_print("%d logical volume(s) in volume group "
                            "\"%s\" %smonitored",
                            monitored, vg->name, (dmeventd_monitor_mode()) ? "" : "un");
        }
 
-       return ECMD_PROCESSED;
+       return ret_max;
 }
 
 static int _vgchange_background_polling(struct cmd_context *cmd, struct volume_group *vg)
@@ -190,7 +191,7 @@ static int _vgchange_background_polling(struct cmd_context *cmd, struct volume_g
 static int _vgchange_available(struct cmd_context *cmd, struct volume_group *vg)
 {
        int lv_open, active, monitored;
-       int available, ret;
+       int available, ret_max = ECMD_PROCESSED;
        int activate = 1;
 
        /*
@@ -219,7 +220,7 @@ static int _vgchange_available(struct cmd_context *cmd, struct volume_group *vg)
                log_verbose("%d logical volume(s) in volume group \"%s\" "
                            "already active", active, vg->name);
                if (dmeventd_monitor_mode() != DMEVENTD_MONITOR_IGNORE) {
-                       monitored = _monitor_lvs_in_vg(cmd, vg, dmeventd_monitor_mode());
+                       ret_max = max(ret_max, _monitor_lvs_in_vg(cmd, vg, dmeventd_monitor_mode(), &monitored));
                        log_verbose("%d existing logical volume(s) in volume "
                                    "group \"%s\" %smonitored",
                                    monitored, vg->name,
@@ -227,13 +228,13 @@ static int _vgchange_available(struct cmd_context *cmd, struct volume_group *vg)
                }
        }
 
-       ret = _activate_lvs_in_vg(cmd, vg, available);
+       ret_max = max(ret_max, _activate_lvs_in_vg(cmd, vg, available));
 
        /* Print message only if there was not found a missing VG */
        if (!vg->cmd_missing_vgs)
                log_print("%d logical volume(s) in volume group \"%s\" now active",
                          lvs_in_vg_activated(vg), vg->name);
-       return ret;
+       return ret_max;
 }
 
 static int _vgchange_alloc(struct cmd_context *cmd, struct volume_group *vg)
This page took 0.087634 seconds and 5 git commands to generate.