2016-02-22 18:42:03 +03:00
/*
* 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 .
*/
2018-05-14 12:30:20 +03:00
# include "lib/misc/lib.h"
# include "lib/commands/toolcontext.h"
# include "lib/notify/lvmnotify.h"
2016-02-22 18:42:03 +03:00
# define LVM_DBUS_DESTINATION "com.redhat.lvmdbus1"
# define LVM_DBUS_PATH " / com / redhat / lvmdbus1 / Manager"
# define LVM_DBUS_INTERFACE "com.redhat.lvmdbus1.Manager"
2022-10-19 20:46:45 +03:00
# define LVM_DBUS_LOCK_FILE " / var / lock / lvm / lvmdbusd"
# define LVM_DBUS_LOCK_FILE_ENV_KEY "LVM_DBUSD_LOCKFILE"
2016-11-15 12:09:11 +03:00
# define SD_BUS_SYSTEMD_NO_SUCH_UNIT_ERROR "org.freedesktop.systemd1.NoSuchUnit"
# define SD_BUS_DBUS_SERVICE_UNKNOWN_ERROR "org.freedesktop.DBus.Error.ServiceUnknown"
2016-02-22 18:42:03 +03:00
# ifdef NOTIFYDBUS_SUPPORT
# include <systemd/sd-bus.h>
2022-10-19 20:46:45 +03:00
# include <fcntl.h>
# include <stdlib.h>
# include <unistd.h>
# include <errno.h>
2016-02-22 18:42:03 +03:00
2016-03-07 19:50:45 +03:00
int lvmnotify_is_supported ( void )
{
return 1 ;
}
2022-10-19 20:46:45 +03:00
static int lvmdbusd_running ( void )
{
int fd = 0 ;
int rc = 0 ;
int errno_cpy = 0 ;
int running = 0 ;
const char * lockfile = NULL ;
/*
* lvm dbusd uses a lock file with a lock on it , thus to determine if the daemon is running
* requires that you attempt to lock the file as well . Thus the existence of the file does
* not mean it ' s running , but the absence of the file does indicate it ' s not running .
*
* See lvmdbusd for more details .
*/
lockfile = getenv ( LVM_DBUS_LOCK_FILE_ENV_KEY ) ;
if ( ! lockfile ) {
lockfile = LVM_DBUS_LOCK_FILE ;
}
errno = 0 ;
fd = open ( lockfile , O_RDWR ) ;
if ( - 1 = = fd ) {
errno_cpy = errno ;
if ( errno_cpy = = ENOENT ) {
return 0 ;
} else {
/* Safest option is to return running when we encounter unexpected errors */
log_debug_dbus ( " Unexpected errno: %d on lockfile open, returning running " , errno_cpy ) ;
return 1 ;
}
}
/* Need to ensure we close lock FD now */
errno = 0 ;
rc = lockf ( fd , F_TLOCK | F_TEST , 0 ) ;
if ( - 1 ! = rc ) {
/* Not locked, thus not running */
running = 0 ;
} else {
errno_cpy = errno ;
if ( errno_cpy = = EACCES | | errno_cpy = = EAGAIN ) {
/* Locked, so daemon is running */
running = 1 ;
} else {
log_debug_dbus ( " Unexpected errno: %d on lockf, returning running " , errno_cpy ) ;
running = 1 ;
}
}
2023-08-31 19:47:42 +03:00
if ( close ( fd ) )
log_sys_debug ( " close " , lockfile ) ;
2022-10-19 20:46:45 +03:00
return running ;
}
2016-02-22 18:42:03 +03:00
void lvmnotify_send ( struct cmd_context * cmd )
{
2016-11-14 16:46:44 +03:00
static const char _dbus_notification_failed_msg [ ] = " D-Bus notification failed " ;
2016-02-22 18:42:03 +03:00
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 ;
2022-10-19 20:46:45 +03:00
/* If lvmdbusd isn't running, don't notify as you will start it as it will auto activate */
if ( ! lvmdbusd_running ( ) ) {
log_debug_dbus ( " dbus damon not running, not notifying " ) ;
return ;
}
2016-02-22 18:42:03 +03:00
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 ) {
2016-11-15 12:09:11 +03:00
if ( sd_bus_error_has_name ( & error , SD_BUS_SYSTEMD_NO_SUCH_UNIT_ERROR ) | |
sd_bus_error_has_name ( & error , SD_BUS_DBUS_SERVICE_UNKNOWN_ERROR ) )
2016-11-14 16:46:44 +03:00
log_debug_dbus ( " %s: %s " , _dbus_notification_failed_msg , error . message ) ;
else
log_warn ( " WARNING: %s: %s " , _dbus_notification_failed_msg , error . message ) ;
2016-02-22 18:42:03 +03:00
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 ) ;
2016-08-12 22:31:06 +03:00
sd_bus_flush_close_unref ( bus ) ;
2016-02-22 18:42:03 +03:00
}
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
2016-03-07 19:50:45 +03:00
int lvmnotify_is_supported ( void )
{
return 0 ;
}
2016-02-22 18:42:03 +03:00
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