The policy kit and HAL node device drivers both require a

DBus connection. The HAL device code further requires that
the DBus connection is integrated with the event loop and
provides such glue logic itself.

The forthcoming FirewallD integration also requires a
dbus connection with event loop integration. Thus we need
to pull the current event loop glue out of the HAL driver.

Thus we create src/util/virdbus.{c,h} files. This contains
just one method virDBusGetSystemBus() which obtains a handle
to the single shared system bus instance, with event glue
automagically setup.
This commit is contained in:
Daniel P. Berrange 2012-04-19 15:34:35 +01:00 committed by Daniel Berrange
parent 7c26343bc3
commit 2223ea984c
15 changed files with 300 additions and 204 deletions

View File

@ -74,6 +74,7 @@ LIBPCAP_REQUIRED="1.0.0"
LIBNL_REQUIRED="1.1"
LIBSSH2_REQUIRED="1.0"
LIBBLKID_REQUIRED="2.17"
DBUS_REQUIRED="1.0.0"
dnl Checks for C compiler.
AC_PROG_CC
@ -1099,6 +1100,36 @@ AC_SUBST([SANLOCK_CFLAGS])
AC_SUBST([SANLOCK_LIBS])
dnl DBus library
DBUS_CFLAGS=
DBUS_LIBS=
AC_ARG_WITH([dbus],
AC_HELP_STRING([--with-dbus], [enable communication with DBus @<:@default=check@:>@]),
[],
[with_dbus=check])
if test "$with_dbus" = "yes" || test "$with_dbus" = "check" ; then
PKG_CHECK_MODULES(DBUS, dbus-1 >= $DBUS_REQUIRED,
[with_dbus=yes], [
if test "$with_dbus" = "check" ; then
with_dbus=no
else
AC_MSG_ERROR([You must install DBus >= $DBUS_REQUIRED to compile libvirt])
fi])
fi
if test "$with_dbus" = "yes" ; then
AC_DEFINE_UNQUOTED([HAVE_DBUS], 1, [enable communication with DBus])
save_LIBS="$LIBS"
save_CFLAGS="$CFLAGS"
LIBS="$LIBS $DBUS_LIBS"
CFLAGS="$CFLAGS $DBUS_CFLAGS"
AC_CHECK_FUNCS([dbus_watch_get_unix_fd])
LIBS="$save_LIBS"
CFLAGS="$save_CFLAGS"
fi
dnl PolicyKit library
POLKIT_CFLAGS=
POLKIT_LIBS=
@ -1109,7 +1140,6 @@ AC_ARG_WITH([polkit],
[with_polkit=check])
with_polkit0=no
with_dbus=no
with_polkit1=no
if test "x$with_polkit" = "xyes" || test "x$with_polkit" = "xcheck"; then
dnl Check for new polkit first - just a binary
@ -1138,8 +1168,6 @@ if test "x$with_polkit" = "xyes" || test "x$with_polkit" = "xcheck"; then
[use PolicyKit for UNIX socket access checks])
AC_DEFINE_UNQUOTED([HAVE_POLKIT0], 1,
[use PolicyKit for UNIX socket access checks])
AC_DEFINE_UNQUOTED([HAVE_DBUS], 1,
[use DBus for PolicyKit])
old_CFLAGS=$CFLAGS
old_LIBS=$LIBS
@ -1154,13 +1182,11 @@ if test "x$with_polkit" = "xyes" || test "x$with_polkit" = "xcheck"; then
AC_DEFINE_UNQUOTED([POLKIT_AUTH],["$POLKIT_AUTH"],[Location of polkit-auth program])
fi
with_polkit0="yes"
with_dbus="yes"
fi
fi
fi
AM_CONDITIONAL([HAVE_POLKIT], [test "x$with_polkit" = "xyes"])
AM_CONDITIONAL([HAVE_POLKIT0], [test "x$with_polkit0" = "xyes"])
AM_CONDITIONAL([HAVE_DBUS], [test "x$with_dbus" = "xyes"])
AM_CONDITIONAL([HAVE_POLKIT1], [test "x$with_polkit1" = "xyes"])
AC_SUBST([POLKIT_CFLAGS])
AC_SUBST([POLKIT_LIBS])
@ -2413,7 +2439,6 @@ if test "x$with_hal" = "xyes" || test "x$with_hal" = "xcheck"; then
CFLAGS="$CFLAGS $HAL_CFLAGS"
LIBS="$LIBS $HAL_LIBS"
AC_CHECK_FUNCS([libhal_get_all_devices],,[with_hal=no])
AC_CHECK_FUNCS([dbus_watch_get_unix_fd])
CFLAGS="$old_CFLAGS"
LIBS="$old_LIBS"
fi

View File

@ -94,7 +94,7 @@ libvirtd_SOURCES = $(DAEMON_SOURCES)
#-D_XOPEN_SOURCE=600 -D_XOPEN_SOURCE_EXTENDED=1 -D_POSIX_C_SOURCE=199506L
libvirtd_CFLAGS = \
$(LIBXML_CFLAGS) $(GNUTLS_CFLAGS) $(SASL_CFLAGS) \
$(XDR_CFLAGS) $(POLKIT_CFLAGS) \
$(XDR_CFLAGS) $(POLKIT_CFLAGS) $(DBUS_CFLAGS) \
$(WARN_CFLAGS) \
$(COVERAGE_CFLAGS) \
-DQEMUD_PID_FILE="\"$(QEMUD_PID_FILE)\"" \
@ -108,6 +108,7 @@ libvirtd_LDADD = \
$(LIBXML_LIBS) \
$(GNUTLS_LIBS) \
$(SASL_LIBS) \
$(DBUS_LIBS) \
$(POLKIT_LIBS)
if WITH_DTRACE_PROBES

View File

@ -812,7 +812,6 @@ int main(int argc, char **argv) {
struct daemonConfig *config;
bool privileged = geteuid() == 0 ? true : false;
bool implicit_conf = false;
bool use_polkit_dbus;
char *run_dir = NULL;
mode_t old_umask;
@ -1008,8 +1007,6 @@ int main(int argc, char **argv) {
goto cleanup;
}
use_polkit_dbus = config->auth_unix_rw == REMOTE_AUTH_POLKIT ||
config->auth_unix_ro == REMOTE_AUTH_POLKIT;
if (!(srv = virNetServerNew(config->min_workers,
config->max_workers,
config->prio_workers,
@ -1018,7 +1015,6 @@ int main(int argc, char **argv) {
config->keepalive_count,
!!config->keepalive_required,
config->mdns_adv ? config->mdns_name : NULL,
use_polkit_dbus,
remoteClientInitHook))) {
ret = VIR_DAEMON_ERR_INIT;
goto cleanup;

View File

@ -45,7 +45,7 @@
#include "virnetserver.h"
#include "virfile.h"
#include "virtypedparam.h"
#include "virdbus.h"
#include "remote_protocol.h"
#include "qemu_protocol.h"
@ -2672,6 +2672,7 @@ remoteDispatchAuthPolkit(virNetServerPtr server,
char *ident = NULL;
struct daemonClientPrivate *priv =
virNetServerClientGetPrivateData(client);
DBusConnection *sysbus;
virMutexLock(&priv->lock);
@ -2697,10 +2698,13 @@ remoteDispatchAuthPolkit(virNetServerPtr server,
goto authfail;
}
if (!(sysbus = virDBusGetSystemBus()))
goto authfail;
VIR_INFO("Checking PID %lld running as %d",
(long long) callerPid, callerUid);
dbus_error_init(&err);
if (!(pkcaller = polkit_caller_new_from_pid(virNetServerGetDBusConn(server),
if (!(pkcaller = polkit_caller_new_from_pid(sysbus,
callerPid, &err))) {
VIR_ERROR(_("Failed to lookup policy kit caller: %s"), err.message);
dbus_error_free(&err);

View File

@ -87,6 +87,7 @@ typedef enum {
VIR_FROM_CAPABILITIES = 44, /* Error from capabilities */
VIR_FROM_URI = 45, /* Error from URI handling */
VIR_FROM_AUTH = 46, /* Error from auth handling */
VIR_FROM_DBUS = 47, /* Error from DBus */
} virErrorDomain;

View File

@ -128,6 +128,7 @@ src/util/util.c
src/util/viraudit.c
src/util/virauth.c
src/util/virauthconfig.c
src/util/virdbus.c
src/util/virfile.c
src/util/virhash.c
src/util/virkeyfile.c

View File

@ -88,6 +88,7 @@ UTIL_SOURCES = \
util/virtypedparam.c util/virtypedparam.h \
util/xml.c util/xml.h \
util/virterror.c util/virterror_internal.h \
util/virdbus.c util/virdbus.h \
util/virhash.c util/virhash.h \
util/virhashcode.c util/virhashcode.h \
util/virkeycode.c util/virkeycode.h \
@ -574,10 +575,11 @@ libvirt_la_BUILT_LIBADD = libvirt_util.la
libvirt_util_la_SOURCES = \
$(UTIL_SOURCES)
libvirt_util_la_CFLAGS = $(CAPNG_CFLAGS) $(YAJL_CFLAGS) $(LIBNL_CFLAGS) \
$(AM_CFLAGS) $(AUDIT_CFLAGS) $(DEVMAPPER_CFLAGS)
$(AM_CFLAGS) $(AUDIT_CFLAGS) $(DEVMAPPER_CFLAGS) \
$(DBUS_CFLAGS)
libvirt_util_la_LIBADD = $(CAPNG_LIBS) $(YAJL_LIBS) $(LIBNL_LIBS) \
$(THREAD_LIBS) $(AUDIT_LIBS) $(DEVMAPPER_LIBS) \
$(RT_LIBS)
$(RT_LIBS) $(DBUS_LIBS)
noinst_LTLIBRARIES += libvirt_conf.la
@ -1198,10 +1200,6 @@ if WITH_LINUX
USED_SYM_FILES += libvirt_linux.syms
endif
if HAVE_DBUS
USED_SYM_FILES += libvirt_dbus.syms
endif
if WITH_LIBVIRTD
USED_SYM_FILES += libvirt_daemon.syms
endif
@ -1525,7 +1523,7 @@ libvirt_lxc_LDFLAGS = $(WARN_CFLAGS) $(AM_LDFLAGS)
libvirt_lxc_LDADD = $(CAPNG_LIBS) $(YAJL_LIBS) \
$(LIBXML_LIBS) $(NUMACTL_LIBS) $(THREAD_LIBS) \
$(LIBNL_LIBS) $(AUDIT_LIBS) $(DEVMAPPER_LIBS) \
$(RT_LIBS) \
$(RT_LIBS) $(DBUS_LIBS) \
../gnulib/lib/libgnu.la
if WITH_DTRACE_PROBES
libvirt_lxc_LDADD += probes.o
@ -1542,6 +1540,7 @@ libvirt_lxc_CFLAGS = \
$(CAPNG_CFLAGS) \
$(YAJL_CFLAGS) \
$(AUDIT_CFLAGS) \
$(DBUS_CFLAGS) \
-I$(top_srcdir)/src/conf \
$(AM_CFLAGS)
if HAVE_LIBBLKID

View File

@ -1,2 +0,0 @@
# virnetserver.h
virNetServerGetDBusConn;

View File

@ -1195,6 +1195,10 @@ virConsoleFree;
virConsoleOpen;
# virdbus.h
virDBusGetSystemBus;
# virfile.h
virFileClose;
virFileDirectFdFlag;

View File

@ -39,6 +39,7 @@
#include "logging.h"
#include "node_device_driver.h"
#include "ignore-value.h"
#include "virdbus.h"
#define VIR_FROM_THIS VIR_FROM_NODEDEV
@ -586,124 +587,16 @@ static void device_prop_modified(LibHalContext *ctx ATTRIBUTE_UNUSED,
}
static void dbus_watch_callback(int fdatch ATTRIBUTE_UNUSED,
int fd ATTRIBUTE_UNUSED,
int events, void *opaque)
{
DBusWatch *watch = opaque;
LibHalContext *hal_ctx;
DBusConnection *dbus_conn;
int dbus_flags = 0;
if (events & VIR_EVENT_HANDLE_READABLE)
dbus_flags |= DBUS_WATCH_READABLE;
if (events & VIR_EVENT_HANDLE_WRITABLE)
dbus_flags |= DBUS_WATCH_WRITABLE;
if (events & VIR_EVENT_HANDLE_ERROR)
dbus_flags |= DBUS_WATCH_ERROR;
if (events & VIR_EVENT_HANDLE_HANGUP)
dbus_flags |= DBUS_WATCH_HANGUP;
(void)dbus_watch_handle(watch, dbus_flags);
nodeDeviceLock(driverState);
hal_ctx = DRV_STATE_HAL_CTX(driverState);
dbus_conn = libhal_ctx_get_dbus_connection(hal_ctx);
nodeDeviceUnlock(driverState);
while (dbus_connection_dispatch(dbus_conn) == DBUS_DISPATCH_DATA_REMAINS)
/* keep dispatching while data remains */;
}
static int xlate_dbus_watch_flags(int dbus_flags)
{
unsigned int flags = 0;
if (dbus_flags & DBUS_WATCH_READABLE)
flags |= VIR_EVENT_HANDLE_READABLE;
if (dbus_flags & DBUS_WATCH_WRITABLE)
flags |= VIR_EVENT_HANDLE_WRITABLE;
if (dbus_flags & DBUS_WATCH_ERROR)
flags |= VIR_EVENT_HANDLE_ERROR;
if (dbus_flags & DBUS_WATCH_HANGUP)
flags |= VIR_EVENT_HANDLE_HANGUP;
return flags;
}
struct nodeDeviceWatchInfo
{
int watch;
};
static void nodeDeviceWatchFree(void *data) {
struct nodeDeviceWatchInfo *info = data;
VIR_FREE(info);
}
static dbus_bool_t add_dbus_watch(DBusWatch *watch,
void *data ATTRIBUTE_UNUSED)
{
int flags = 0;
int fd;
struct nodeDeviceWatchInfo *info;
if (VIR_ALLOC(info) < 0)
return 0;
if (dbus_watch_get_enabled(watch))
flags = xlate_dbus_watch_flags(dbus_watch_get_flags(watch));
#if HAVE_DBUS_WATCH_GET_UNIX_FD
fd = dbus_watch_get_unix_fd(watch);
#else
fd = dbus_watch_get_fd(watch);
#endif
info->watch = virEventAddHandle(fd, flags, dbus_watch_callback,
watch, NULL);
if (info->watch < 0) {
VIR_FREE(info);
return 0;
}
dbus_watch_set_data(watch, info, nodeDeviceWatchFree);
return 1;
}
static void remove_dbus_watch(DBusWatch *watch,
void *data ATTRIBUTE_UNUSED)
{
struct nodeDeviceWatchInfo *info;
info = dbus_watch_get_data(watch);
(void)virEventRemoveHandle(info->watch);
}
static void toggle_dbus_watch(DBusWatch *watch,
void *data ATTRIBUTE_UNUSED)
{
int flags = 0;
struct nodeDeviceWatchInfo *info;
if (dbus_watch_get_enabled(watch))
flags = xlate_dbus_watch_flags(dbus_watch_get_flags(watch));
info = dbus_watch_get_data(watch);
(void)virEventUpdateHandle(info->watch, flags);
}
static int halDeviceMonitorStartup(int privileged ATTRIBUTE_UNUSED)
{
LibHalContext *hal_ctx = NULL;
DBusConnection *dbus_conn = NULL;
DBusError err;
char **udi = NULL;
int num_devs, i;
int ret = -1;
DBusConnection *sysbus;
DBusError err;
/* Ensure caps_tbl is sorted by capability name */
qsort(caps_tbl, ARRAY_CARDINALITY(caps_tbl), sizeof(caps_tbl[0]),
@ -718,9 +611,13 @@ static int halDeviceMonitorStartup(int privileged ATTRIBUTE_UNUSED)
}
nodeDeviceLock(driverState);
/* Allocate and initialize a new HAL context */
dbus_connection_set_change_sigpipe(FALSE);
dbus_threads_init_default();
if (!(sysbus = virDBusGetSystemBus())) {
virErrorPtr verr = virGetLastError();
VIR_ERROR(_("DBus not available, disabling HAL driver: %s"),
verr->message);
ret = 0;
goto failure;
}
dbus_error_init(&err);
hal_ctx = libhal_ctx_new();
@ -728,18 +625,8 @@ static int halDeviceMonitorStartup(int privileged ATTRIBUTE_UNUSED)
VIR_ERROR(_("libhal_ctx_new returned NULL"));
goto failure;
}
dbus_conn = dbus_bus_get(DBUS_BUS_SYSTEM, &err);
if (dbus_conn == NULL) {
VIR_ERROR(_("dbus_bus_get failed"));
/* We don't want to show a fatal error here,
otherwise entire libvirtd shuts down when
D-Bus isn't running */
ret = 0;
goto failure;
}
dbus_connection_set_exit_on_disconnect(dbus_conn, FALSE);
if (!libhal_ctx_set_dbus_connection(hal_ctx, dbus_conn)) {
if (!libhal_ctx_set_dbus_connection(hal_ctx, sysbus)) {
VIR_ERROR(_("libhal_ctx_set_dbus_connection failed"));
goto failure;
}
@ -752,16 +639,6 @@ static int halDeviceMonitorStartup(int privileged ATTRIBUTE_UNUSED)
goto failure;
}
/* Register dbus watch callbacks */
if (!dbus_connection_set_watch_functions(dbus_conn,
add_dbus_watch,
remove_dbus_watch,
toggle_dbus_watch,
NULL, NULL)) {
VIR_ERROR(_("dbus_connection_set_watch_functions failed"));
goto failure;
}
/* Populate with known devices */
driverState->privateData = hal_ctx;

View File

@ -39,9 +39,6 @@
#if HAVE_AVAHI
# include "virnetservermdns.h"
#endif
#if HAVE_DBUS
# include <dbus/dbus.h>
#endif
#define VIR_FROM_THIS VIR_FROM_RPC
#define virNetError(code, ...) \
@ -88,10 +85,6 @@ struct _virNetServer {
virNetServerMDNSGroupPtr mdnsGroup;
#endif
#if HAVE_DBUS
DBusConnection *sysbus;
#endif
size_t nservices;
virNetServerServicePtr *services;
@ -311,7 +304,6 @@ virNetServerPtr virNetServerNew(size_t min_workers,
unsigned int keepaliveCount,
bool keepaliveRequired,
const char *mdnsGroupName,
bool connectDBus ATTRIBUTE_UNUSED,
virNetServerClientInitHook clientInitHook)
{
virNetServerPtr srv;
@ -353,25 +345,6 @@ virNetServerPtr virNetServerNew(size_t min_workers,
}
#endif
#if HAVE_DBUS
if (connectDBus) {
DBusError derr;
dbus_connection_set_change_sigpipe(FALSE);
dbus_threads_init_default();
dbus_error_init(&derr);
srv->sysbus = dbus_bus_get(DBUS_BUS_SYSTEM, &derr);
if (!(srv->sysbus)) {
VIR_ERROR(_("Failed to connect to system bus for PolicyKit auth: %s"),
derr.message);
dbus_error_free(&derr);
goto error;
}
dbus_connection_set_exit_on_disconnect(srv->sysbus, FALSE);
}
#endif
if (virMutexInit(&srv->lock) < 0) {
virNetError(VIR_ERR_INTERNAL_ERROR, "%s",
_("cannot initialize mutex"));
@ -429,14 +402,6 @@ bool virNetServerIsPrivileged(virNetServerPtr srv)
}
#if HAVE_DBUS
DBusConnection* virNetServerGetDBusConn(virNetServerPtr srv)
{
return srv->sysbus;
}
#endif
void virNetServerAutoShutdown(virNetServerPtr srv,
unsigned int timeout,
virNetServerAutoShutdownFunc func,
@ -828,11 +793,6 @@ void virNetServerFree(virNetServerPtr srv)
virNetServerMDNSFree(srv->mdns);
#endif
#if HAVE_DBUS
if (srv->sysbus)
dbus_connection_unref(srv->sysbus);
#endif
virNetServerUnlock(srv);
virMutexDestroy(&srv->lock);
VIR_FREE(srv);

View File

@ -25,9 +25,6 @@
# define __VIR_NET_SERVER_H__
# include <signal.h>
# if HAVE_DBUS
# include <dbus/dbus.h>
# endif
# include "virnettlscontext.h"
# include "virnetserverprogram.h"
@ -45,7 +42,6 @@ virNetServerPtr virNetServerNew(size_t min_workers,
unsigned int keepaliveCount,
bool keepaliveRequired,
const char *mdnsGroupName,
bool connectDBus,
virNetServerClientInitHook clientInitHook);
typedef int (*virNetServerAutoShutdownFunc)(virNetServerPtr srv, void *opaque);
@ -54,10 +50,6 @@ void virNetServerRef(virNetServerPtr srv);
bool virNetServerIsPrivileged(virNetServerPtr srv);
# if HAVE_DBUS
DBusConnection* virNetServerGetDBusConn(virNetServerPtr srv);
# endif
void virNetServerAutoShutdown(virNetServerPtr srv,
unsigned int timeout,
virNetServerAutoShutdownFunc func,

201
src/util/virdbus.c Normal file
View File

@ -0,0 +1,201 @@
/*
* virdbus.c: helper for using DBus
*
* Copyright (C) 2012 Red Hat, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*/
#include <config.h>
#include "virdbus.h"
#include "memory.h"
#include "virterror_internal.h"
#include "logging.h"
#include "threads.h"
#define VIR_FROM_THIS VIR_FROM_DBUS
#define virDBusReportError(code, ...) \
virReportErrorHelper(VIR_FROM_THIS, code, __FILE__, \
__FUNCTION__, __LINE__, __VA_ARGS__)
#ifdef HAVE_DBUS
static DBusConnection *systembus = NULL;
static virOnceControl once = VIR_ONCE_CONTROL_INITIALIZER;
static DBusError dbuserr;
static dbus_bool_t virDBusAddWatch(DBusWatch *watch, void *data);
static void virDBusRemoveWatch(DBusWatch *watch, void *data);
static void virDBusToggleWatch(DBusWatch *watch, void *data);
static void virDBusSystemBusInit(void)
{
/* Allocate and initialize a new HAL context */
dbus_connection_set_change_sigpipe(FALSE);
dbus_threads_init_default();
dbus_error_init(&dbuserr);
if (!(systembus = dbus_bus_get(DBUS_BUS_SYSTEM, &dbuserr)))
return;
dbus_connection_set_exit_on_disconnect(systembus, FALSE);
/* Register dbus watch callbacks */
if (!dbus_connection_set_watch_functions(systembus,
virDBusAddWatch,
virDBusRemoveWatch,
virDBusToggleWatch,
NULL, NULL)) {
systembus = NULL;
return;
}
}
DBusConnection *virDBusGetSystemBus(void)
{
if (virOnce(&once, virDBusSystemBusInit) < 0) {
virDBusReportError(VIR_ERR_INTERNAL_ERROR, "%s",
_("Unable to run one time DBus initializer"));
return NULL;
}
if (!systembus) {
virDBusReportError(VIR_ERR_INTERNAL_ERROR,
_("Unable to get DBus system bus connection: %s"),
dbuserr.message ? dbuserr.message : "watch setup failed");
return NULL;
}
return systembus;
}
static void virDBusWatchCallback(int fdatch ATTRIBUTE_UNUSED,
int fd ATTRIBUTE_UNUSED,
int events, void *opaque)
{
DBusWatch *watch = opaque;
int dbus_flags = 0;
if (events & VIR_EVENT_HANDLE_READABLE)
dbus_flags |= DBUS_WATCH_READABLE;
if (events & VIR_EVENT_HANDLE_WRITABLE)
dbus_flags |= DBUS_WATCH_WRITABLE;
if (events & VIR_EVENT_HANDLE_ERROR)
dbus_flags |= DBUS_WATCH_ERROR;
if (events & VIR_EVENT_HANDLE_HANGUP)
dbus_flags |= DBUS_WATCH_HANGUP;
(void)dbus_watch_handle(watch, dbus_flags);
while (dbus_connection_dispatch(systembus) == DBUS_DISPATCH_DATA_REMAINS)
/* keep dispatching while data remains */;
}
static int virDBusTranslateWatchFlags(int dbus_flags)
{
unsigned int flags = 0;
if (dbus_flags & DBUS_WATCH_READABLE)
flags |= VIR_EVENT_HANDLE_READABLE;
if (dbus_flags & DBUS_WATCH_WRITABLE)
flags |= VIR_EVENT_HANDLE_WRITABLE;
if (dbus_flags & DBUS_WATCH_ERROR)
flags |= VIR_EVENT_HANDLE_ERROR;
if (dbus_flags & DBUS_WATCH_HANGUP)
flags |= VIR_EVENT_HANDLE_HANGUP;
return flags;
}
struct virDBusWatch
{
int watch;
};
static void virDBusWatchFree(void *data) {
struct virDBusWatch *info = data;
VIR_FREE(info);
}
static dbus_bool_t virDBusAddWatch(DBusWatch *watch,
void *data ATTRIBUTE_UNUSED)
{
int flags = 0;
int fd;
struct virDBusWatch *info;
if (VIR_ALLOC(info) < 0)
return 0;
if (dbus_watch_get_enabled(watch))
flags = virDBusTranslateWatchFlags(dbus_watch_get_flags(watch));
# if HAVE_DBUS_WATCH_GET_UNIX_FD
fd = dbus_watch_get_unix_fd(watch);
# else
fd = dbus_watch_get_fd(watch);
# endif
info->watch = virEventAddHandle(fd, flags,
virDBusWatchCallback,
watch, NULL);
if (info->watch < 0) {
VIR_FREE(info);
return 0;
}
dbus_watch_set_data(watch, info, virDBusWatchFree);
return 1;
}
static void virDBusRemoveWatch(DBusWatch *watch,
void *data ATTRIBUTE_UNUSED)
{
struct virDBusWatch *info;
info = dbus_watch_get_data(watch);
(void)virEventRemoveHandle(info->watch);
}
static void virDBusToggleWatch(DBusWatch *watch,
void *data ATTRIBUTE_UNUSED)
{
int flags = 0;
struct virDBusWatch *info;
if (dbus_watch_get_enabled(watch))
flags = virDBusTranslateWatchFlags(dbus_watch_get_flags(watch));
info = dbus_watch_get_data(watch);
(void)virEventUpdateHandle(info->watch, flags);
}
#else /* ! HAVE_DBUS */
DBusConnection *virDBusGetSystemBus(void)
{
virDBusReportError(VIR_ERR_INTERNAL_ERROR,
"%s", _("DBus support not compiled into this binary"));
return NULL;
}
#endif /* ! HAVE_DBUS */

34
src/util/virdbus.h Normal file
View File

@ -0,0 +1,34 @@
/*
* virdbus.h: helper for using DBus
*
* Copyright (C) 2012 Red Hat, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*/
#ifndef __VIR_DBUS_H__
# define __VIR_DBUS_H__
# ifdef HAVE_DBUS
# include <dbus/dbus.h>
# else
# define DBusConnection void
# endif
# include "internal.h"
DBusConnection *virDBusGetSystemBus(void);
#endif /* __VIR_DBUS_H__ */

View File

@ -184,6 +184,9 @@ static const char *virErrorDomainName(virErrorDomain domain) {
case VIR_FROM_AUTH:
dom = "Auth ";
break;
case VIR_FROM_DBUS:
dom = "DBus ";
break;
}
return dom;
}