mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2025-01-03 11:35:19 +00:00
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:
parent
7c26343bc3
commit
2223ea984c
37
configure.ac
37
configure.ac
@ -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
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
||||
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -1,2 +0,0 @@
|
||||
# virnetserver.h
|
||||
virNetServerGetDBusConn;
|
@ -1195,6 +1195,10 @@ virConsoleFree;
|
||||
virConsoleOpen;
|
||||
|
||||
|
||||
# virdbus.h
|
||||
virDBusGetSystemBus;
|
||||
|
||||
|
||||
# virfile.h
|
||||
virFileClose;
|
||||
virFileDirectFdFlag;
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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
201
src/util/virdbus.c
Normal 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
34
src/util/virdbus.h
Normal 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__ */
|
@ -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;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user