summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Teigland <teigland@redhat.com>2016-02-22 09:42:03 -0600
committerDavid Teigland <teigland@redhat.com>2016-03-07 10:06:09 -0600
commit2d5dc6512e10924ab68e6a139081d7121bc3f7d6 (patch)
treed2c193c84be87fb97d9bae009ae7af79dcc1b927
parent18cf5e8e6758db59c9413bd9c9abcc183c49293d (diff)
downloadlvm2-2d5dc6512e10924ab68e6a139081d7121bc3f7d6.tar.gz
dbus: add notification from commands
When a command modifies a PV or VG, or changes the activation state of an LV, it will send a dbus notification when the command is finished. This can be enabled/disabled with a config setting.
-rw-r--r--WHATS_NEW1
-rw-r--r--configure.in23
-rw-r--r--include/.symlinks.in1
-rw-r--r--lib/Makefile.in2
-rw-r--r--lib/commands/toolcontext.c2
-rw-r--r--lib/commands/toolcontext.h3
-rw-r--r--lib/config/config_settings.h7
-rw-r--r--lib/config/defaults.h1
-rw-r--r--lib/log/log.h2
-rw-r--r--lib/metadata/metadata.c5
-rw-r--r--lib/notify/lvmnotify.c109
-rw-r--r--lib/notify/lvmnotify.h20
-rw-r--r--tools/lvmcmdline.c3
-rw-r--r--tools/pvchange.c2
-rw-r--r--tools/pvresize.c2
-rw-r--r--tools/toollib.c4
-rw-r--r--tools/tools.h1
17 files changed, 187 insertions, 1 deletions
diff --git a/WHATS_NEW b/WHATS_NEW
index f29250e76..e2e946295 100644
--- a/WHATS_NEW
+++ b/WHATS_NEW
@@ -1,5 +1,6 @@
Version 2.02.146 -
=================================
+ Add dbus notification from commands after a PV/VG/LV changes state.
Version 2.02.145 - 4th March 2016
=================================
diff --git a/configure.in b/configure.in
index e8723f4da..33cd0fece 100644
--- a/configure.in
+++ b/configure.in
@@ -1269,6 +1269,28 @@ AC_DEFINE_UNQUOTED(DEFAULT_USE_LVMPOLLD, [$DEFAULT_USE_LVMPOLLD],
[Use lvmpolld by default.])
################################################################################
+dnl -- Build notifydbus
+AC_MSG_CHECKING(whether to build notifydbus)
+AC_ARG_ENABLE(notify-dbus,
+ AC_HELP_STRING([--enable-notify-dbus],
+ [enable LVM notification using dbus]),
+ NOTIFYDBUS=$enableval)
+AC_MSG_RESULT($NOTIFYDBUS)
+
+BUILD_NOTIFYDBUS=$NOTIFYDBUS
+
+if test "$BUILD_NOTIFYDBUS" = yes; then
+ AC_DEFINE([NOTIFYDBUS_SUPPORT], 1, [Define to 1 to include code that uses dbus notification.])
+ LIBS="-lsystemd $LIBS"
+fi
+
+################################################################################
+dnl -- Look for dbus libraries
+if test "$BUILD_NOTIFYDBUS" = yes; then
+ PKG_CHECK_MODULES(NOTIFY_DBUS, systemd >= 221, [HAVE_NOTIFY_DBUS=yes], $bailout)
+fi
+
+################################################################################
dnl -- Enable blkid wiping functionality
AC_MSG_CHECKING(whether to enable libblkid detection of signatures when wiping)
@@ -1965,6 +1987,7 @@ AC_SUBST(BUILD_LVMPOLLD)
AC_SUBST(BUILD_LVMLOCKD)
AC_SUBST(BUILD_LOCKDSANLOCK)
AC_SUBST(BUILD_LOCKDDLM)
+AC_SUBST(BUILD_NOTIFYDBUS)
AC_SUBST(CACHE)
AC_SUBST(CFLAGS)
AC_SUBST(CFLOW_CMD)
diff --git a/include/.symlinks.in b/include/.symlinks.in
index 98d680483..d1cc8268f 100644
--- a/include/.symlinks.in
+++ b/include/.symlinks.in
@@ -58,6 +58,7 @@
@top_srcdir@/lib/misc/util.h
@top_srcdir@/lib/mm/memlock.h
@top_srcdir@/lib/mm/xlate.h
+@top_srcdir@/lib/notify/lvmnotify.h
@top_srcdir@/lib/properties/prop_common.h
@top_srcdir@/lib/report/properties.h
@top_srcdir@/lib/report/report.h
diff --git a/lib/Makefile.in b/lib/Makefile.in
index ece9b1068..467ef9077 100644
--- a/lib/Makefile.in
+++ b/lib/Makefile.in
@@ -116,6 +116,7 @@ SOURCES =\
misc/lvm-wrappers.c \
misc/lvm-percent.c \
mm/memlock.c \
+ notify/lvmnotify.c \
properties/prop_common.c \
report/properties.c \
report/report.c \
@@ -215,6 +216,7 @@ ifeq ($(MAKECMDGOALS),distclean)
format_pool \
snapshot \
mirror \
+ notify \
raid \
replicator \
thin \
diff --git a/lib/commands/toolcontext.c b/lib/commands/toolcontext.c
index 7f6eee447..08e857c2f 100644
--- a/lib/commands/toolcontext.c
+++ b/lib/commands/toolcontext.c
@@ -278,6 +278,8 @@ static int _parse_debug_classes(struct cmd_context *cmd)
debug_classes |= LOG_CLASS_LOCKING;
else if (!strcasecmp(cv->v.str, "lvmpolld"))
debug_classes |= LOG_CLASS_LVMPOLLD;
+ else if (!strcasecmp(cv->v.str, "dbus"))
+ debug_classes |= LOG_CLASS_DBUS;
else
log_verbose("Unrecognised value for log/debug_classes: %s", cv->v.str);
}
diff --git a/lib/commands/toolcontext.h b/lib/commands/toolcontext.h
index 6a6267d1d..c3b9b2ea5 100644
--- a/lib/commands/toolcontext.h
+++ b/lib/commands/toolcontext.h
@@ -141,6 +141,9 @@ struct cmd_context {
unsigned lockd_vg_rescan:1;
unsigned lockd_vg_default_sh:1;
unsigned lockd_vg_enforce_sh:1;
+ unsigned vg_notify:1;
+ unsigned lv_notify:1;
+ unsigned pv_notify:1;
/*
* Filtering.
diff --git a/lib/config/config_settings.h b/lib/config/config_settings.h
index 12911091c..d58b7a4aa 100644
--- a/lib/config/config_settings.h
+++ b/lib/config/config_settings.h
@@ -581,7 +581,7 @@ cfg(log_activation_CFG, "activation", log_CFG_SECTION, 0, CFG_TYPE_BOOL, 0, vsn(
cfg(log_activate_file_CFG, "activate_file", log_CFG_SECTION, CFG_DEFAULT_UNDEFINED | CFG_UNSUPPORTED, CFG_TYPE_STRING, NULL, vsn(1, 0, 0), NULL, 0, NULL, NULL)
-cfg_array(log_debug_classes_CFG, "debug_classes", log_CFG_SECTION, CFG_ALLOW_EMPTY, CFG_TYPE_STRING, "#Smemory#Sdevices#Sactivation#Sallocation#Slvmetad#Smetadata#Scache#Slocking#Slvmpolld", vsn(2, 2, 99), NULL, 0, NULL,
+cfg_array(log_debug_classes_CFG, "debug_classes", log_CFG_SECTION, CFG_ALLOW_EMPTY, CFG_TYPE_STRING, "#Smemory#Sdevices#Sactivation#Sallocation#Slvmetad#Smetadata#Scache#Slocking#Slvmpolld#Sdbus", vsn(2, 2, 99), NULL, 0, NULL,
"Select log messages by class.\n"
"Some debugging messages are assigned to a class and only appear in\n"
"debug output if the class is listed here. Classes currently\n"
@@ -995,6 +995,11 @@ cfg(global_use_lvmpolld_CFG, "use_lvmpolld", global_CFG_SECTION, 0, CFG_TYPE_BOO
"and to use its own control group. When this option is disabled, LVM\n"
"commands will supervise long running operations by forking themselves.\n")
+cfg(global_notify_dbus_CFG, "notify_dbus", global_CFG_SECTION, 0, CFG_TYPE_BOOL, DEFAULT_NOTIFY_DBUS, vsn(2, 2, 145), NULL, 0, NULL,
+ "Enable D-Bus notification from LVM commands.\n"
+ "When enabled, an LVM command that changes PVs, changes VG metadata,\n"
+ "or changes the activation state of an LV will send a notification.\n")
+
cfg(activation_udev_sync_CFG, "udev_sync", activation_CFG_SECTION, 0, CFG_TYPE_BOOL, DEFAULT_UDEV_SYNC, vsn(2, 2, 51), NULL, 0, NULL,
"Use udev notifications to synchronize udev and LVM.\n"
"The --nodevsync option overrides this setting.\n"
diff --git a/lib/config/defaults.h b/lib/config/defaults.h
index fd7986c35..51fd01d5b 100644
--- a/lib/config/defaults.h
+++ b/lib/config/defaults.h
@@ -138,6 +138,7 @@
#define DEFAULT_READ_AHEAD "auto"
#define DEFAULT_UDEV_RULES 1
#define DEFAULT_UDEV_SYNC 1
+#define DEFAULT_NOTIFY_DBUS 1
#define DEFAULT_VERIFY_UDEV_OPERATIONS 0
#define DEFAULT_RETRY_DEACTIVATION 1
#define DEFAULT_ACTIVATION_CHECKS 0
diff --git a/lib/log/log.h b/lib/log/log.h
index b7ba044fa..222a1adba 100644
--- a/lib/log/log.h
+++ b/lib/log/log.h
@@ -66,6 +66,7 @@
#define LOG_CLASS_CACHE 0x0040 /* "cache" */
#define LOG_CLASS_LOCKING 0x0080 /* "locking" */
#define LOG_CLASS_LVMPOLLD 0x0100 /* "lvmpolld" */
+#define LOG_CLASS_DBUS 0x0200 /* "dbus" */
#define log_debug(x...) LOG_LINE(_LOG_DEBUG, x)
#define log_debug_mem(x...) LOG_LINE_WITH_CLASS(_LOG_DEBUG, LOG_CLASS_MEM, x)
@@ -77,6 +78,7 @@
#define log_debug_cache(x...) LOG_LINE_WITH_CLASS(_LOG_DEBUG, LOG_CLASS_CACHE, x)
#define log_debug_locking(x...) LOG_LINE_WITH_CLASS(_LOG_DEBUG, LOG_CLASS_LOCKING, x)
#define log_debug_lvmpolld(x...) LOG_LINE_WITH_CLASS(_LOG_DEBUG, LOG_CLASS_LVMPOLLD, x)
+#define log_debug_dbus(x...) LOG_LINE_WITH_CLASS(_LOG_DEBUG, LOG_CLASS_DBUS, x)
#define log_info(x...) LOG_LINE(_LOG_INFO, x)
#define log_notice(x...) LOG_LINE(_LOG_NOTICE, x)
diff --git a/lib/metadata/metadata.c b/lib/metadata/metadata.c
index 9700e7324..1330cc019 100644
--- a/lib/metadata/metadata.c
+++ b/lib/metadata/metadata.c
@@ -33,6 +33,7 @@
#include "defaults.h"
#include "lvmlockd.h"
#include "time.h"
+#include "lvmnotify.h"
#include <math.h>
#include <sys/param.h>
@@ -604,6 +605,8 @@ int vg_remove_direct(struct volume_group *vg)
lockd_vg_update(vg);
+ set_vg_notify(vg->cmd);
+
if (!backup_remove(vg->cmd, vg->name))
stack;
@@ -3591,6 +3594,8 @@ int vg_commit(struct volume_group *vg)
cache_updated = _vg_commit_mdas(vg);
+ set_vg_notify(vg->cmd);
+
if (cache_updated) {
/* Instruct remote nodes to upgrade cached metadata. */
if (!remote_commit_cached_metadata(vg))
diff --git a/lib/notify/lvmnotify.c b/lib/notify/lvmnotify.c
new file mode 100644
index 000000000..0b04ee4ba
--- /dev/null
+++ b/lib/notify/lvmnotify.c
@@ -0,0 +1,109 @@
+/*
+ * 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.
+ */
+
+#include "lib.h"
+#include "toolcontext.h"
+#include "metadata.h"
+#include "lvmnotify.h"
+
+#define LVM_DBUS_DESTINATION "com.redhat.lvmdbus1"
+#define LVM_DBUS_PATH "/com/redhat/lvmdbus1/Manager"
+#define LVM_DBUS_INTERFACE "com.redhat.lvmdbus1.Manager"
+
+#ifdef NOTIFYDBUS_SUPPORT
+#include <systemd/sd-bus.h>
+
+void lvmnotify_send(struct cmd_context *cmd)
+{
+ sd_bus *bus = NULL;
+ sd_bus_message *m = NULL;
+ sd_bus_error error = SD_BUS_ERROR_NULL;
+ const char *cmd_name;
+ int ret;
+ int result = 0;
+
+ if (!cmd->vg_notify && !cmd->lv_notify && !cmd->pv_notify)
+ return;
+
+ cmd->vg_notify = 0;
+ cmd->lv_notify = 0;
+ cmd->pv_notify = 0;
+
+ cmd_name = get_cmd_name();
+
+ ret = sd_bus_open_system(&bus);
+ if (ret < 0) {
+ log_debug_dbus("Failed to connect to dbus: %d", ret);
+ return;
+ }
+
+ log_debug_dbus("Nofify dbus at %s.", LVM_DBUS_DESTINATION);
+
+ ret = sd_bus_call_method(bus,
+ LVM_DBUS_DESTINATION,
+ LVM_DBUS_PATH,
+ LVM_DBUS_INTERFACE,
+ "ExternalEvent",
+ &error,
+ &m,
+ "s",
+ cmd_name);
+
+ if (ret < 0) {
+ log_warn("WARNING: D-Bus notification failed: %s", error.message);
+ goto out;
+ }
+
+ ret = sd_bus_message_read(m, "i", &result);
+ if (ret < 0)
+ log_debug_dbus("Failed to parse dbus response message: %d", ret);
+ if (result)
+ log_debug_dbus("Bad return value from dbus service: %d", result);
+out:
+ sd_bus_error_free(&error);
+ sd_bus_message_unref(m);
+ sd_bus_unref(bus);
+}
+
+void set_vg_notify(struct cmd_context *cmd)
+{
+ cmd->vg_notify = 1;
+}
+
+void set_lv_notify(struct cmd_context *cmd)
+{
+ cmd->lv_notify = 1;
+}
+
+void set_pv_notify(struct cmd_context *cmd)
+{
+ cmd->pv_notify = 1;
+}
+
+#else
+
+void lvmnotify_send(struct cmd_context *cmd)
+{
+}
+
+void set_vg_notify(struct cmd_context *cmd)
+{
+}
+
+void set_lv_notify(struct cmd_context *cmd)
+{
+}
+
+void set_pv_notify(struct cmd_context *cmd)
+{
+}
+
+#endif
+
diff --git a/lib/notify/lvmnotify.h b/lib/notify/lvmnotify.h
new file mode 100644
index 000000000..43fffd0da
--- /dev/null
+++ b/lib/notify/lvmnotify.h
@@ -0,0 +1,20 @@
+/*
+ * 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.
+ */
+
+#ifndef _LVMNOTIFY_H
+#define _LVMNOTIFY_H
+
+void lvmnotify_send(struct cmd_context *cmd);
+void set_vg_notify(struct cmd_context *cmd);
+void set_lv_notify(struct cmd_context *cmd);
+void set_pv_notify(struct cmd_context *cmd);
+
+#endif
+
diff --git a/tools/lvmcmdline.c b/tools/lvmcmdline.c
index 72570f7df..2ee54e8ff 100644
--- a/tools/lvmcmdline.c
+++ b/tools/lvmcmdline.c
@@ -1660,6 +1660,9 @@ int lvm_run_command(struct cmd_context *cmd, int argc, char **argv)
lvmlockd_disconnect();
fin_locking();
+ if (!_cmd_no_meta_proc(cmd) && find_config_tree_bool(cmd, global_notify_dbus_CFG, NULL))
+ lvmnotify_send(cmd);
+
out:
if (test_mode()) {
log_verbose("Test mode: Wiping internal cache");
diff --git a/tools/pvchange.c b/tools/pvchange.c
index 86c4ac4f0..5f9901687 100644
--- a/tools/pvchange.c
+++ b/tools/pvchange.c
@@ -228,6 +228,8 @@ int pvchange(struct cmd_context *cmd, int argc, char **argv)
}
}
+ set_pv_notify(cmd);
+
ret = process_each_pv(cmd, argc, argv, NULL, 0, READ_FOR_UPDATE, handle, _pvchange_single);
if (!argc)
diff --git a/tools/pvresize.c b/tools/pvresize.c
index b79098ca9..13122907e 100644
--- a/tools/pvresize.c
+++ b/tools/pvresize.c
@@ -79,6 +79,8 @@ int pvresize(struct cmd_context *cmd, int argc, char **argv)
params.done = 0;
params.total = 0;
+ set_pv_notify(cmd);
+
if (!(handle = init_processing_handle(cmd))) {
log_error("Failed to initialize processing handle.");
ret = ECMD_FAILED;
diff --git a/tools/toollib.c b/tools/toollib.c
index 9e866d6f4..14aca1503 100644
--- a/tools/toollib.c
+++ b/tools/toollib.c
@@ -1069,6 +1069,8 @@ int lv_change_activate(struct cmd_context *cmd, struct logical_volume *lv,
if (!lv_active_change(cmd, lv, activate, 0))
return_0;
+ set_lv_notify(lv->vg->cmd);
+
return r;
}
@@ -4179,6 +4181,8 @@ int pvcreate_each_device(struct cmd_context *cmd,
int found;
int i;
+ set_pv_notify(cmd);
+
dm_list_init(&arg_sort);
handle->custom_handle = pp;
diff --git a/tools/tools.h b/tools/tools.h
index 5875376ba..3762e8eed 100644
--- a/tools/tools.h
+++ b/tools/tools.h
@@ -42,6 +42,7 @@
#include "str_list.h"
#include "toolcontext.h"
#include "toollib.h"
+#include "lvmnotify.h"
#include <ctype.h>
#include <sys/types.h>