1
0
mirror of git://sourceware.org/git/lvm2.git synced 2024-12-21 13:34:40 +03:00

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.
This commit is contained in:
David Teigland 2016-02-22 09:42:03 -06:00
parent 18cf5e8e67
commit 2d5dc6512e
17 changed files with 187 additions and 1 deletions

View File

@ -1,5 +1,6 @@
Version 2.02.146 - Version 2.02.146 -
================================= =================================
Add dbus notification from commands after a PV/VG/LV changes state.
Version 2.02.145 - 4th March 2016 Version 2.02.145 - 4th March 2016
================================= =================================

View File

@ -1268,6 +1268,28 @@ fi
AC_DEFINE_UNQUOTED(DEFAULT_USE_LVMPOLLD, [$DEFAULT_USE_LVMPOLLD], AC_DEFINE_UNQUOTED(DEFAULT_USE_LVMPOLLD, [$DEFAULT_USE_LVMPOLLD],
[Use lvmpolld by default.]) [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 dnl -- Enable blkid wiping functionality
@ -1965,6 +1987,7 @@ AC_SUBST(BUILD_LVMPOLLD)
AC_SUBST(BUILD_LVMLOCKD) AC_SUBST(BUILD_LVMLOCKD)
AC_SUBST(BUILD_LOCKDSANLOCK) AC_SUBST(BUILD_LOCKDSANLOCK)
AC_SUBST(BUILD_LOCKDDLM) AC_SUBST(BUILD_LOCKDDLM)
AC_SUBST(BUILD_NOTIFYDBUS)
AC_SUBST(CACHE) AC_SUBST(CACHE)
AC_SUBST(CFLAGS) AC_SUBST(CFLAGS)
AC_SUBST(CFLOW_CMD) AC_SUBST(CFLOW_CMD)

View File

@ -58,6 +58,7 @@
@top_srcdir@/lib/misc/util.h @top_srcdir@/lib/misc/util.h
@top_srcdir@/lib/mm/memlock.h @top_srcdir@/lib/mm/memlock.h
@top_srcdir@/lib/mm/xlate.h @top_srcdir@/lib/mm/xlate.h
@top_srcdir@/lib/notify/lvmnotify.h
@top_srcdir@/lib/properties/prop_common.h @top_srcdir@/lib/properties/prop_common.h
@top_srcdir@/lib/report/properties.h @top_srcdir@/lib/report/properties.h
@top_srcdir@/lib/report/report.h @top_srcdir@/lib/report/report.h

View File

@ -116,6 +116,7 @@ SOURCES =\
misc/lvm-wrappers.c \ misc/lvm-wrappers.c \
misc/lvm-percent.c \ misc/lvm-percent.c \
mm/memlock.c \ mm/memlock.c \
notify/lvmnotify.c \
properties/prop_common.c \ properties/prop_common.c \
report/properties.c \ report/properties.c \
report/report.c \ report/report.c \
@ -215,6 +216,7 @@ ifeq ($(MAKECMDGOALS),distclean)
format_pool \ format_pool \
snapshot \ snapshot \
mirror \ mirror \
notify \
raid \ raid \
replicator \ replicator \
thin \ thin \

View File

@ -278,6 +278,8 @@ static int _parse_debug_classes(struct cmd_context *cmd)
debug_classes |= LOG_CLASS_LOCKING; debug_classes |= LOG_CLASS_LOCKING;
else if (!strcasecmp(cv->v.str, "lvmpolld")) else if (!strcasecmp(cv->v.str, "lvmpolld"))
debug_classes |= LOG_CLASS_LVMPOLLD; debug_classes |= LOG_CLASS_LVMPOLLD;
else if (!strcasecmp(cv->v.str, "dbus"))
debug_classes |= LOG_CLASS_DBUS;
else else
log_verbose("Unrecognised value for log/debug_classes: %s", cv->v.str); log_verbose("Unrecognised value for log/debug_classes: %s", cv->v.str);
} }

View File

@ -141,6 +141,9 @@ struct cmd_context {
unsigned lockd_vg_rescan:1; unsigned lockd_vg_rescan:1;
unsigned lockd_vg_default_sh:1; unsigned lockd_vg_default_sh:1;
unsigned lockd_vg_enforce_sh:1; unsigned lockd_vg_enforce_sh:1;
unsigned vg_notify:1;
unsigned lv_notify:1;
unsigned pv_notify:1;
/* /*
* Filtering. * Filtering.

View File

@ -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(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" "Select log messages by class.\n"
"Some debugging messages are assigned to a class and only appear in\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" "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" "and to use its own control group. When this option is disabled, LVM\n"
"commands will supervise long running operations by forking themselves.\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, 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"
"The --nodevsync option overrides this setting.\n" "The --nodevsync option overrides this setting.\n"

View File

@ -138,6 +138,7 @@
#define DEFAULT_READ_AHEAD "auto" #define DEFAULT_READ_AHEAD "auto"
#define DEFAULT_UDEV_RULES 1 #define DEFAULT_UDEV_RULES 1
#define DEFAULT_UDEV_SYNC 1 #define DEFAULT_UDEV_SYNC 1
#define DEFAULT_NOTIFY_DBUS 1
#define DEFAULT_VERIFY_UDEV_OPERATIONS 0 #define DEFAULT_VERIFY_UDEV_OPERATIONS 0
#define DEFAULT_RETRY_DEACTIVATION 1 #define DEFAULT_RETRY_DEACTIVATION 1
#define DEFAULT_ACTIVATION_CHECKS 0 #define DEFAULT_ACTIVATION_CHECKS 0

View File

@ -66,6 +66,7 @@
#define LOG_CLASS_CACHE 0x0040 /* "cache" */ #define LOG_CLASS_CACHE 0x0040 /* "cache" */
#define LOG_CLASS_LOCKING 0x0080 /* "locking" */ #define LOG_CLASS_LOCKING 0x0080 /* "locking" */
#define LOG_CLASS_LVMPOLLD 0x0100 /* "lvmpolld" */ #define LOG_CLASS_LVMPOLLD 0x0100 /* "lvmpolld" */
#define LOG_CLASS_DBUS 0x0200 /* "dbus" */
#define log_debug(x...) LOG_LINE(_LOG_DEBUG, x) #define log_debug(x...) LOG_LINE(_LOG_DEBUG, x)
#define log_debug_mem(x...) LOG_LINE_WITH_CLASS(_LOG_DEBUG, LOG_CLASS_MEM, 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_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_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_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_info(x...) LOG_LINE(_LOG_INFO, x)
#define log_notice(x...) LOG_LINE(_LOG_NOTICE, x) #define log_notice(x...) LOG_LINE(_LOG_NOTICE, x)

View File

@ -33,6 +33,7 @@
#include "defaults.h" #include "defaults.h"
#include "lvmlockd.h" #include "lvmlockd.h"
#include "time.h" #include "time.h"
#include "lvmnotify.h"
#include <math.h> #include <math.h>
#include <sys/param.h> #include <sys/param.h>
@ -604,6 +605,8 @@ int vg_remove_direct(struct volume_group *vg)
lockd_vg_update(vg); lockd_vg_update(vg);
set_vg_notify(vg->cmd);
if (!backup_remove(vg->cmd, vg->name)) if (!backup_remove(vg->cmd, vg->name))
stack; stack;
@ -3591,6 +3594,8 @@ int vg_commit(struct volume_group *vg)
cache_updated = _vg_commit_mdas(vg); cache_updated = _vg_commit_mdas(vg);
set_vg_notify(vg->cmd);
if (cache_updated) { if (cache_updated) {
/* Instruct remote nodes to upgrade cached metadata. */ /* Instruct remote nodes to upgrade cached metadata. */
if (!remote_commit_cached_metadata(vg)) if (!remote_commit_cached_metadata(vg))

109
lib/notify/lvmnotify.c Normal file
View File

@ -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

20
lib/notify/lvmnotify.h Normal file
View File

@ -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

View File

@ -1660,6 +1660,9 @@ int lvm_run_command(struct cmd_context *cmd, int argc, char **argv)
lvmlockd_disconnect(); lvmlockd_disconnect();
fin_locking(); fin_locking();
if (!_cmd_no_meta_proc(cmd) && find_config_tree_bool(cmd, global_notify_dbus_CFG, NULL))
lvmnotify_send(cmd);
out: out:
if (test_mode()) { if (test_mode()) {
log_verbose("Test mode: Wiping internal cache"); log_verbose("Test mode: Wiping internal cache");

View File

@ -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); ret = process_each_pv(cmd, argc, argv, NULL, 0, READ_FOR_UPDATE, handle, _pvchange_single);
if (!argc) if (!argc)

View File

@ -79,6 +79,8 @@ int pvresize(struct cmd_context *cmd, int argc, char **argv)
params.done = 0; params.done = 0;
params.total = 0; params.total = 0;
set_pv_notify(cmd);
if (!(handle = init_processing_handle(cmd))) { if (!(handle = init_processing_handle(cmd))) {
log_error("Failed to initialize processing handle."); log_error("Failed to initialize processing handle.");
ret = ECMD_FAILED; ret = ECMD_FAILED;

View File

@ -1069,6 +1069,8 @@ int lv_change_activate(struct cmd_context *cmd, struct logical_volume *lv,
if (!lv_active_change(cmd, lv, activate, 0)) if (!lv_active_change(cmd, lv, activate, 0))
return_0; return_0;
set_lv_notify(lv->vg->cmd);
return r; return r;
} }
@ -4179,6 +4181,8 @@ int pvcreate_each_device(struct cmd_context *cmd,
int found; int found;
int i; int i;
set_pv_notify(cmd);
dm_list_init(&arg_sort); dm_list_init(&arg_sort);
handle->custom_handle = pp; handle->custom_handle = pp;

View File

@ -42,6 +42,7 @@
#include "str_list.h" #include "str_list.h"
#include "toolcontext.h" #include "toolcontext.h"
#include "toollib.h" #include "toollib.h"
#include "lvmnotify.h"
#include <ctype.h> #include <ctype.h>
#include <sys/types.h> #include <sys/types.h>