Attached is a fully functional version of the node device udev based
backend, incorporating all the feedback from earlier revisions. I broke
the new capability fields out into a separate patch per Dan's
suggestion, and I have also included a patch removing the DevKit backend.
Dave
From e95f0c84ff50c4d8736750e93b70b901c7a246ad Mon Sep 17 00:00:00 2001
From: David Allan <dallan(a)redhat.com>
Date: Fri, 16 Oct 2009 16:52:40 -0400
Subject: [PATCH 1/3] Add several fields to node device capabilities
---
src/conf/node_device_conf.c | 22 ++++++++++++++++++++++
src/conf/node_device_conf.h | 7 +++++++
2 files changed, 29 insertions(+), 0 deletions(-)
diff --git a/src/conf/node_device_conf.c b/src/conf/node_device_conf.c
index c2c5a44..87f441d 100644
--- a/src/conf/node_device_conf.c
+++ b/src/conf/node_device_conf.c
@@ -248,6 +248,12 @@ char *virNodeDeviceDefFormat(virConnectPtr conn,
if (data->system.product_name)
virBufferEscapeString(&buf, "
<product>%s</product>\n",
data->system.product_name);
+ if (data->system.dmi_devpath)
+ virBufferEscapeString(&buf, "
<dmi_devpath>%s</dmi_devpath>\n",
+ data->system.dmi_devpath);
+ if (data->system.description)
+ virBufferEscapeString(&buf, "
<description>%s</description>\n",
+ data->system.description);
virBufferAddLit(&buf, " <hardware>\n");
if (data->system.hardware.vendor_name)
virBufferEscapeString(&buf, "
<vendor>%s</vendor>\n",
@@ -325,6 +331,9 @@ char *virNodeDeviceDefFormat(virConnectPtr conn,
data->usb_if.subclass);
virBufferVSprintf(&buf, "
<protocol>%d</protocol>\n",
data->usb_if.protocol);
+ if (data->usb_if.interface_name)
+ virBufferVSprintf(&buf, "
<interface_name>%s</interface_name>\n",
+ data->usb_if.interface_name);
if (data->usb_if.description)
virBufferVSprintf(&buf, "
<description>%s</description>\n",
data->usb_if.description);
@@ -394,10 +403,20 @@ char *virNodeDeviceDefFormat(virConnectPtr conn,
"</media_available>\n", avl ? 1 : 0);
virBufferVSprintf(&buf, "
<media_size>%llu</media_size>\n",
data->storage.removable_media_size);
+ virBufferVSprintf(&buf, "
<logical_block_size>%llu"
+ "</logical_block_size>\n",
+ data->storage.logical_block_size);
+ virBufferVSprintf(&buf, "
<num_blocks>%llu</num_blocks>\n",
+ data->storage.num_blocks);
virBufferAddLit(&buf, " </capability>\n");
} else {
virBufferVSprintf(&buf, "
<size>%llu</size>\n",
data->storage.size);
+ virBufferVSprintf(&buf, "
<logical_block_size>%llu"
+ "</logical_block_size>\n",
+ data->storage.logical_block_size);
+ virBufferVSprintf(&buf, "
<num_blocks>%llu</num_blocks>\n",
+ data->storage.num_blocks);
}
if (data->storage.flags & VIR_NODE_DEV_CAP_STORAGE_HOTPLUGGABLE)
virBufferAddLit(&buf,
@@ -1310,6 +1329,8 @@ void virNodeDevCapsDefFree(virNodeDevCapsDefPtr caps)
switch (caps->type) {
case VIR_NODE_DEV_CAP_SYSTEM:
VIR_FREE(data->system.product_name);
+ VIR_FREE(data->system.dmi_devpath);
+ VIR_FREE(data->system.description);
VIR_FREE(data->system.hardware.vendor_name);
VIR_FREE(data->system.hardware.version);
VIR_FREE(data->system.hardware.serial);
@@ -1326,6 +1347,7 @@ void virNodeDevCapsDefFree(virNodeDevCapsDefPtr caps)
VIR_FREE(data->usb_dev.vendor_name);
break;
case VIR_NODE_DEV_CAP_USB_INTERFACE:
+ VIR_FREE(data->usb_if.interface_name);
VIR_FREE(data->usb_if.description);
break;
case VIR_NODE_DEV_CAP_NET:
diff --git a/src/conf/node_device_conf.h b/src/conf/node_device_conf.h
index a7bb6c6..f70184d 100644
--- a/src/conf/node_device_conf.h
+++ b/src/conf/node_device_conf.h
@@ -82,6 +82,8 @@ struct _virNodeDevCapsDef {
union _virNodeDevCapData {
struct {
char *product_name;
+ char *description;
+ char *dmi_devpath;
struct {
char *vendor_name;
char *version;
@@ -101,6 +103,7 @@ struct _virNodeDevCapsDef {
unsigned function;
unsigned product;
unsigned vendor;
+ unsigned class;
char *product_name;
char *vendor_name;
} pci_dev;
@@ -117,10 +120,12 @@ struct _virNodeDevCapsDef {
unsigned _class; /* "class" is reserved in C */
unsigned subclass;
unsigned protocol;
+ char *interface_name;
char *description;
} usb_if;
struct {
char *address;
+ unsigned address_len;
char *ifname;
enum virNodeDevNetCapType subtype; /* LAST -> no subtype */
} net;
@@ -139,6 +144,8 @@ struct _virNodeDevCapsDef {
} scsi;
struct {
unsigned long long size;
+ unsigned long long num_blocks;
+ unsigned long long logical_block_size;
unsigned long long removable_media_size;
char *block;
char *bus;
--
1.6.4.4
From d8f4ac6806a8f55e4f9fa9c4af3e0c89aa4d0074 Mon Sep 17 00:00:00 2001
From: David Allan <dallan(a)redhat.com>
Date: Fri, 16 Oct 2009 10:09:01 -0400
Subject: [PATCH 2/3] Implement a node device backend using libudev.
Monitoring for addition and removal of devices is implemented.
There is a lot of detail work in this code, so we should try to get people running it on a
wide variety of hardware so we can shake out the differences in implementation between the
HAL and libudev backends.
I have moved the new fields in the node device capabilities to a separate patch.
This version contains changes per all the feedback I've received on earlier versions.
---
configure.in | 47 +-
daemon/libvirtd.c | 3 +-
po/POTFILES.in | 3 +-
src/Makefile.am | 16 +-
src/node_device/node_device_driver.c | 12 +-
src/node_device/node_device_driver.h | 22 +
src/node_device/node_device_hal.h | 19 -
...evice_hal_linux.c => node_device_linux_sysfs.c} | 0
src/node_device/node_device_udev.c | 1142 ++++++++++++++++++++
src/node_device/node_device_udev.h | 32 +
src/util/util.c | 28 +
src/util/util.h | 3 +
tools/virsh.c | 10 +-
13 files changed, 1306 insertions(+), 31 deletions(-)
rename src/node_device/{node_device_hal_linux.c => node_device_linux_sysfs.c} (100%)
create mode 100644 src/node_device/node_device_udev.c
create mode 100644 src/node_device/node_device_udev.h
diff --git a/configure.in b/configure.in
index 2f9db72..25ed55f 100644
--- a/configure.in
+++ b/configure.in
@@ -1640,7 +1640,7 @@ test "$enable_shared" = no && lt_cv_objdir=.
LV_LIBTOOL_OBJDIR=${lt_cv_objdir-.}
AC_SUBST([LV_LIBTOOL_OBJDIR])
-dnl HAL or DeviceKit library for host device enumeration
+dnl HAL, DeviceKit, or libudev library for host device enumeration
HAL_REQUIRED=0.0
HAL_CFLAGS=
HAL_LIBS=
@@ -1734,8 +1734,46 @@ AM_CONDITIONAL([HAVE_DEVKIT], [test "x$with_devkit" =
"xyes"])
AC_SUBST([DEVKIT_CFLAGS])
AC_SUBST([DEVKIT_LIBS])
+UDEV_REQUIRED=143
+UDEV_CFLAGS=
+UDEV_LIBS=
+AC_ARG_WITH([udev],
+ [ --with-udev use libudev for host device enumeration],
+ [],
+ [with_udev=check])
+
+if test "$with_libvirtd" = "no" ; then
+ with_udev=no
+fi
+if test "x$with_udev" = "xyes" -o "x$with_udev" =
"xcheck"; then
+ PKG_CHECK_MODULES(UDEV, libudev >= $UDEV_REQUIRED,
+ [with_udev=yes], [
+ if test "x$with_udev" = "xcheck" ; then
+ with_udev=no
+ else
+ AC_MSG_ERROR(
+ [You must install udev-devel >= $UDEV_REQUIRED to compile libvirt])
+ fi
+ ])
+ if test "x$with_udev" = "xyes" ; then
+ AC_DEFINE_UNQUOTED([HAVE_UDEV], 1,
+ [use UDEV for host device enumeration])
+
+ old_CFLAGS=$CFLAGS
+ old_LDFLAGS=$LDFLAGS
+ CFLAGS="$CFLAGS $UDEV_CFLAGS"
+ LDFLAGS="$LDFLAGS $UDEV_LIBS"
+ AC_CHECK_FUNCS([udev_new],,[with_udev=no])
+ CFLAGS="$old_CFLAGS"
+ LDFLAGS="$old_LDFLAGS"
+ fi
+fi
+AM_CONDITIONAL([HAVE_UDEV], [test "x$with_udev" = "xyes"])
+AC_SUBST([UDEV_CFLAGS])
+AC_SUBST([UDEV_LIBS])
+
with_nodedev=no;
-if test "$with_devkit" = "yes" -o "$with_hal" =
"yes";
+if test "$with_devkit" = "yes" -o "$with_hal" =
"yes" -o "$with_udev" = "yes";
then
with_nodedev=yes
AC_DEFINE_UNQUOTED([WITH_NODE_DEVICES], 1, [with node device driver])
@@ -1900,6 +1938,11 @@ AC_MSG_NOTICE([ devkit: $DEVKIT_CFLAGS $DEVKIT_LIBS])
else
AC_MSG_NOTICE([ devkit: no])
fi
+if test "$with_udev" = "yes" ; then
+AC_MSG_NOTICE([ udev: $UDEV_CFLAGS $UDEV_LIBS])
+else
+AC_MSG_NOTICE([ udev: no])
+fi
if test "$with_netcf" = "yes" ; then
AC_MSG_NOTICE([ netcf: $NETCF_CFLAGS $NETCF_LIBS])
else
diff --git a/daemon/libvirtd.c b/daemon/libvirtd.c
index 02bd287..d8d6c00 100644
--- a/daemon/libvirtd.c
+++ b/daemon/libvirtd.c
@@ -833,8 +833,7 @@ static struct qemud_server *qemudInitialize(int sigread) {
#ifdef WITH_STORAGE_DIR
storageRegister();
#endif
-#if defined(WITH_NODE_DEVICES) && \
- (defined(HAVE_HAL) || defined(HAVE_DEVKIT))
+#if defined(WITH_NODE_DEVICES)
nodedevRegister();
#endif
secretRegister();
diff --git a/po/POTFILES.in b/po/POTFILES.in
index 1a12a39..4561e55 100644
--- a/po/POTFILES.in
+++ b/po/POTFILES.in
@@ -17,7 +17,8 @@ src/lxc/lxc_controller.c
src/lxc/lxc_driver.c
src/network/bridge_driver.c
src/node_device/node_device_driver.c
-src/node_device/node_device_hal_linux.c
+src/node_device/node_device_linux_sysfs.c
+src/node_device/node_device_udev.c
src/nodeinfo.c
src/opennebula/one_conf.c
src/opennebula/one_driver.c
diff --git a/src/Makefile.am b/src/Makefile.am
index 8e27ea7..11da07b 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -254,16 +254,20 @@ SECURITY_DRIVER_APPARMOR_SOURCES = \
NODE_DEVICE_DRIVER_SOURCES = \
- node_device/node_device_driver.c node_device/node_device_driver.h
+ node_device/node_device_driver.c \
+ node_device/node_device_driver.h \
+ node_device/node_device_linux_sysfs.c
NODE_DEVICE_DRIVER_HAL_SOURCES = \
node_device/node_device_hal.c \
- node_device/node_device_hal.h \
- node_device/node_device_hal_linux.c
+ node_device/node_device_hal.h
NODE_DEVICE_DRIVER_DEVKIT_SOURCES = \
node_device/node_device_devkit.c
+NODE_DEVICE_DRIVER_UDEV_SOURCES = \
+ node_device/node_device_udev.c
+
#########################
#
@@ -642,6 +646,11 @@ libvirt_driver_nodedev_la_SOURCES +=
$(NODE_DEVICE_DRIVER_DEVKIT_SOURCES)
libvirt_driver_nodedev_la_CFLAGS += $(DEVKIT_CFLAGS)
libvirt_driver_nodedev_la_LDFLAGS += $(DEVKIT_LIBS)
endif
+if HAVE_UDEV
+libvirt_driver_nodedev_la_SOURCES += $(NODE_DEVICE_DRIVER_UDEV_SOURCES)
+libvirt_driver_nodedev_la_CFLAGS += $(UDEV_CFLAGS)
+libvirt_driver_nodedev_la_LDFLAGS += $(UDEV_LIBS)
+endif
if WITH_DRIVER_MODULES
libvirt_driver_nodedev_la_LDFLAGS += -module -avoid-version
@@ -691,6 +700,7 @@ EXTRA_DIST += \
$(NODE_DEVICE_DRIVER_SOURCES) \
$(NODE_DEVICE_DRIVER_HAL_SOURCES) \
$(NODE_DEVICE_DRIVER_DEVKIT_SOURCES) \
+ $(NODE_DEVICE_DRIVER_UDEV_SOURCES) \
$(SECURITY_DRIVER_SELINUX_SOURCES) \
$(SECURITY_DRIVER_APPARMOR_SOURCES) \
$(SECRET_DRIVER_SOURCES) \
diff --git a/src/node_device/node_device_driver.c b/src/node_device/node_device_driver.c
index f33ff48..c139907 100644
--- a/src/node_device/node_device_driver.c
+++ b/src/node_device/node_device_driver.c
@@ -70,7 +70,10 @@ static int update_caps(virNodeDeviceObjPtr dev)
}
-#ifdef __linux__
+#if defined (__linux__) && defined (HAVE_HAL)
+/* Under libudev changes to the driver name should be picked up as
+ * "change" events, so we don't call update driver name unless we're
+ * using the HAL backend. */
static int update_driver_name(virConnectPtr conn,
virNodeDeviceObjPtr dev)
{
@@ -658,10 +661,10 @@ void registerCommonNodeFuncs(virDeviceMonitorPtr driver)
int nodedevRegister(void) {
-#if defined(HAVE_HAL) && defined(HAVE_DEVKIT)
+#if defined(HAVE_HAL) && defined(HAVE_UDEV)
/* Register only one of these two - they conflict */
if (halNodeRegister() == -1)
- return devkitNodeRegister();
+ return udevNodeRegister();
return 0;
#else
#ifdef HAVE_HAL
@@ -670,5 +673,8 @@ int nodedevRegister(void) {
#ifdef HAVE_DEVKIT
return devkitNodeRegister();
#endif
+#ifdef HAVE_UDEV
+ return udevNodeRegister();
+#endif
#endif
}
diff --git a/src/node_device/node_device_driver.h b/src/node_device/node_device_driver.h
index db01624..5be0781 100644
--- a/src/node_device/node_device_driver.h
+++ b/src/node_device/node_device_driver.h
@@ -45,6 +45,9 @@ int halNodeRegister(void);
#ifdef HAVE_DEVKIT
int devkitNodeRegister(void);
#endif
+#ifdef HAVE_UDEV
+int udevNodeRegister(void);
+#endif
void nodeDeviceLock(virDeviceMonitorStatePtr driver);
void nodeDeviceUnlock(virDeviceMonitorStatePtr driver);
@@ -53,4 +56,23 @@ void registerCommonNodeFuncs(virDeviceMonitorPtr mon);
int nodedevRegister(void);
+#ifdef __linux__
+
+#define check_fc_host(d) check_fc_host_linux(d)
+int check_fc_host_linux(union _virNodeDevCapData *d);
+
+#define check_vport_capable(d) check_vport_capable_linux(d)
+int check_vport_capable_linux(union _virNodeDevCapData *d);
+
+#define read_wwn(host, file, wwn) read_wwn_linux(host, file, wwn)
+int read_wwn_linux(int host, const char *file, char **wwn);
+
+#else /* __linux__ */
+
+#define check_fc_host(d)
+#define check_vport_capable(d)
+#define read_wwn(host, file, wwn)
+
+#endif /* __linux__ */
+
#endif /* __VIR_NODE_DEVICE_H__ */
diff --git a/src/node_device/node_device_hal.h b/src/node_device/node_device_hal.h
index c859fe3..8ac8a35 100644
--- a/src/node_device/node_device_hal.h
+++ b/src/node_device/node_device_hal.h
@@ -22,23 +22,4 @@
#ifndef __VIR_NODE_DEVICE_HAL_H__
#define __VIR_NODE_DEVICE_HAL_H__
-#ifdef __linux__
-
-#define check_fc_host(d) check_fc_host_linux(d)
-int check_fc_host_linux(union _virNodeDevCapData *d);
-
-#define check_vport_capable(d) check_vport_capable_linux(d)
-int check_vport_capable_linux(union _virNodeDevCapData *d);
-
-#define read_wwn(host, file, wwn) read_wwn_linux(host, file, wwn)
-int read_wwn_linux(int host, const char *file, char **wwn);
-
-#else /* __linux__ */
-
-#define check_fc_host(d)
-#define check_vport_capable(d)
-#define read_wwn(host, file, wwn)
-
-#endif /* __linux__ */
-
#endif /* __VIR_NODE_DEVICE_HAL_H__ */
diff --git a/src/node_device/node_device_hal_linux.c
b/src/node_device/node_device_linux_sysfs.c
similarity index 100%
rename from src/node_device/node_device_hal_linux.c
rename to src/node_device/node_device_linux_sysfs.c
diff --git a/src/node_device/node_device_udev.c b/src/node_device/node_device_udev.c
new file mode 100644
index 0000000..10f45aa
--- /dev/null
+++ b/src/node_device/node_device_udev.c
@@ -0,0 +1,1142 @@
+/*
+ * node_device_udev.c: node device enumeration - libudev implementation
+ *
+ * Copyright (C) 2009 Red Hat
+ *
+ * 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
+ *
+ * Author: Dave Allan <dallan(a)redhat.com>
+ */
+
+#include <config.h>
+#include <libudev.h>
+
+#include "node_device_udev.h"
+#include "virterror_internal.h"
+#include "node_device_conf.h"
+#include "node_device_driver.h"
+#include "driver.h"
+#include "datatypes.h"
+#include "logging.h"
+#include "memory.h"
+#include "uuid.h"
+#include "util.h"
+#include "buf.h"
+#include "daemon/event.h"
+
+#define VIR_FROM_THIS VIR_FROM_NODEDEV
+
+static virDeviceMonitorStatePtr driverState = NULL;
+
+/* This function allocates memory from the heap for the property
+ * value. That memory must be later freed by some other code. */
+static int udevGetDeviceProperty(struct udev_device *udev_device,
+ const char *property_key,
+ char **property_value)
+{
+ const char *udev_value = NULL;
+ int ret = PROPERTY_FOUND;
+
+ udev_value = udev_device_get_property_value(udev_device, property_key);
+ if (udev_value == NULL) {
+ VIR_INFO(_("udev reports device '%s' does not have property
'%s'"),
+ udev_device_get_sysname(udev_device), property_key);
+ ret = PROPERTY_MISSING;
+ goto out;
+ }
+
+ /* If this allocation is changed, the comment at the beginning
+ * of the function must also be changed. */
+ *property_value = strdup(udev_value);
+ if (*property_value == NULL) {
+ VIR_ERROR(_("Failed to allocate memory for "
+ "property '%s' on device '%s'"),
+ property_key, udev_device_get_sysname(udev_device));
+ virReportOOMError(NULL);
+ ret = PROPERTY_ERROR;
+ }
+
+out:
+ return ret;
+}
+
+
+static int udevGetStringProperty(struct udev_device *udev_device,
+ const char *property_key,
+ char **value)
+{
+ return udevGetDeviceProperty(udev_device, property_key, value);
+}
+
+
+static int udevGetIntProperty(struct udev_device *udev_device,
+ const char *property_key,
+ int *value,
+ int base)
+{
+ char *udev_value = NULL;
+ int ret = PROPERTY_FOUND;
+
+ ret = udevGetDeviceProperty(udev_device, property_key, &udev_value);
+
+ if (ret == PROPERTY_FOUND) {
+ if (virStrToLong_i(udev_value, NULL, base, value) != 0) {
+ ret = PROPERTY_ERROR;
+ }
+ }
+
+ VIR_FREE(udev_value);
+ return ret;
+}
+
+
+static int udevGetUintProperty(struct udev_device *udev_device,
+ const char *property_key,
+ unsigned int *value,
+ int base)
+{
+ char *udev_value = NULL;
+ int ret = PROPERTY_FOUND;
+
+ ret = udevGetDeviceProperty(udev_device, property_key, &udev_value);
+
+ if (ret == PROPERTY_FOUND) {
+ if (virStrToLong_ui(udev_value, NULL, base, value) != 0) {
+ ret = PROPERTY_ERROR;
+ }
+ }
+
+ VIR_FREE(udev_value);
+ return ret;
+}
+
+
+/* This function allocates memory from the heap for the attr value.
+ * That memory must be later freed by some other code. */
+static int udevGetStringSysfsAttr(struct udev_device *udev_device,
+ const char *attr_name,
+ char **value)
+{
+ const char *udev_value = NULL;
+ int ret = PROPERTY_FOUND;
+
+ udev_value = udev_device_get_sysattr_value(udev_device, attr_name);
+
+ if (udev_value != NULL) {
+ *value = strdup(udev_value);
+ if (*value == NULL) {
+ VIR_ERROR(_("Failed to allocate memory for "
+ "attribute '%s' on device '%s'"),
+ attr_name, udev_device_get_sysname(udev_device));
+ virReportOOMError(NULL);
+ ret = PROPERTY_ERROR;
+ }
+ } else {
+ ret = PROPERTY_MISSING;
+ }
+
+ return ret;
+}
+
+
+static int udevGetIntSysfsAttr(struct udev_device *udev_device,
+ const char *attr_name,
+ int *value,
+ int base)
+{
+ const char *udev_value = NULL;
+ int ret = PROPERTY_FOUND;
+
+ udev_value = udev_device_get_sysattr_value(udev_device, attr_name);
+
+ if (udev_value != NULL) {
+ if (virStrToLong_i(udev_value, NULL, base, value) != 0) {
+ ret = PROPERTY_ERROR;
+ }
+ } else {
+ ret = PROPERTY_MISSING;
+ }
+
+ return ret;
+}
+
+
+static int udevGetUintSysfsAttr(struct udev_device *udev_device,
+ const char *attr_name,
+ unsigned int *value,
+ int base)
+{
+ const char *udev_value = NULL;
+ int ret = PROPERTY_FOUND;
+
+ udev_value = udev_device_get_sysattr_value(udev_device, attr_name);
+
+ if (udev_value != NULL) {
+ if (virStrToLong_ui(udev_value, NULL, base, value) != 0) {
+ ret = PROPERTY_ERROR;
+ }
+ } else {
+ ret = PROPERTY_MISSING;
+ }
+
+ return ret;
+}
+
+
+static int udevGetUint64SysfsAttr(struct udev_device *udev_device,
+ const char *attr_name,
+ uint64_t *value)
+{
+ const char *udev_value = NULL;
+ int ret = PROPERTY_FOUND;
+
+ udev_value = udev_device_get_sysattr_value(udev_device, attr_name);
+
+ if (udev_value != NULL) {
+ if (virStrToLong_ull(udev_value, NULL, 0, value) != 0) {
+ ret = PROPERTY_ERROR;
+ }
+ } else {
+ ret = PROPERTY_MISSING;
+ }
+
+ return ret;
+}
+
+
+static void udevLogFunction(struct udev *udev ATTRIBUTE_UNUSED,
+ int priority ATTRIBUTE_UNUSED,
+ const char *file,
+ int line,
+ const char *fn,
+ const char *fmt,
+ va_list args)
+{
+ VIR_ERROR_INT(file, fn, line, fmt, args);
+}
+
+
+static int udevProcessPCI(struct udev_device *device,
+ virNodeDeviceDefPtr def)
+{
+ const char *devpath = NULL;
+ union _virNodeDevCapData *data = &def->caps->data;
+ int ret = -1;
+
+ devpath = udev_device_get_devpath(device);
+
+ char *p = strrchr(devpath, '/');
+
+ if ((p == NULL) || (virStrToLong_ui(p+1,
+ &p,
+ 16,
+ &data->pci_dev.domain) == -1)) {
+ goto out;
+ }
+
+ if ((p == NULL) || (virStrToLong_ui(p+1,
+ &p,
+ 16,
+ &data->pci_dev.bus) == -1)) {
+ goto out;
+ }
+
+ if ((p == NULL) || (virStrToLong_ui(p+1,
+ &p,
+ 16,
+ &data->pci_dev.slot) == -1)) {
+ goto out;
+ }
+
+ if ((p == NULL) || (virStrToLong_ui(p+1,
+ &p,
+ 16,
+ &data->pci_dev.function) == -1)) {
+ goto out;
+ }
+
+ if (udevGetUintSysfsAttr(device,
+ "vendor",
+ &data->pci_dev.vendor,
+ 0) == PROPERTY_ERROR) {
+ goto out;
+ }
+
+ if (udevGetUintSysfsAttr(device, "product", &data->pci_dev.product,
0)
+ == PROPERTY_ERROR) {
+ goto out;
+ }
+
+ /* FIXME: to do the vendor name and product name, we have to
+ * parse /usr/share/hwdata/pci.ids. Look in hal/hald/ids.c
+ */
+
+ ret = 0;
+
+out:
+ return ret;
+}
+
+
+static int udevProcessUSBDevice(struct udev_device *device,
+ virNodeDeviceDefPtr def)
+{
+ union _virNodeDevCapData *data = &def->caps->data;
+ int ret = 0;
+
+ if (udevGetUintProperty(device,
+ "BUSNUM",
+ &data->usb_dev.bus,
+ 0) == PROPERTY_ERROR) {
+ goto out;
+ }
+
+ if (udevGetUintProperty(device,
+ "DEVNUM",
+ &data->usb_dev.device,
+ 0) == PROPERTY_ERROR) {
+ goto out;
+ }
+
+ if (udevGetUintProperty(device,
+ "ID_VENDOR_ID",
+ &data->usb_dev.vendor,
+ 16) == PROPERTY_ERROR) {
+ goto out;
+ }
+
+ if (udevGetStringProperty(device,
+ "ID_VENDOR",
+ &data->usb_dev.vendor_name) == PROPERTY_ERROR) {
+ goto out;
+ }
+
+ if (udevGetUintProperty(device,
+ "ID_MODEL_ID",
+ &data->usb_dev.product,
+ 0) == PROPERTY_ERROR) {
+ goto out;
+ }
+
+ if (udevGetStringProperty(device,
+ "ID_MODEL",
+ &data->usb_dev.product_name) == PROPERTY_ERROR) {
+ goto out;
+ }
+
+out:
+ return ret;
+}
+
+
+/* XXX Is 10 the correct base for the Number/Class/SubClass/Protocol
+ * conversions? */
+static int udevProcessUSBInterface(struct udev_device *device,
+ virNodeDeviceDefPtr def)
+{
+ int ret = 0;
+ union _virNodeDevCapData *data = &def->caps->data;
+
+ if (udevGetStringProperty(device,
+ "INTERFACE",
+ &data->usb_if.interface_name) == PROPERTY_ERROR) {
+ goto out;
+ }
+
+ if (udevGetUintSysfsAttr(device,
+ "bInterfaceNumber",
+ &data->usb_if.number,
+ 10) == PROPERTY_ERROR) {
+ goto out;
+ }
+
+ if (udevGetUintSysfsAttr(device,
+ "bInterfaceClass",
+ &data->usb_if._class,
+ 10) == PROPERTY_ERROR) {
+ goto out;
+ }
+
+ if (udevGetUintSysfsAttr(device,
+ "bInterfaceSubClass",
+ &data->usb_if.subclass,
+ 10) == PROPERTY_ERROR) {
+ goto out;
+ }
+
+ if (udevGetUintSysfsAttr(device,
+ "bInterfaceProtocol",
+ &data->usb_if.protocol,
+ 10) == PROPERTY_ERROR) {
+ goto out;
+ }
+
+ ret = 0;
+
+out:
+ return ret;
+}
+
+
+static int udevProcessNetworkInterface(struct udev_device *device,
+ virNodeDeviceDefPtr def)
+{
+ union _virNodeDevCapData *data = &def->caps->data;
+ int ret = 0;
+
+ if (udevGetStringSysfsAttr(device,
+ "address",
+ &data->net.address) == PROPERTY_ERROR) {
+ goto out;
+ }
+ if (udevGetUintSysfsAttr(device,
+ "addr_len",
+ &data->net.address_len,
+ 0) == PROPERTY_ERROR) {
+ goto out;
+ }
+
+out:
+ return ret;
+}
+
+
+static int udevProcessSCSIHost(struct udev_device *device ATTRIBUTE_UNUSED,
+ virNodeDeviceDefPtr def)
+{
+ int ret = 0;
+ union _virNodeDevCapData *data = &def->caps->data;
+ char *filename = NULL;
+
+ filename = basename(def->name);
+
+ if (STRPREFIX(filename, "host")) {
+ /* XXX There's really no better way to get the host #? */
+ ret = virStrToLong_ui(filename + strlen("host"),
+ NULL,
+ 0,
+ &data->scsi_host.host);
+ check_fc_host(&def->caps->data);
+ check_vport_capable(&def->caps->data);
+ }
+
+ return ret;
+}
+
+
+static int udevProcessSCSIDevice(struct udev_device *device ATTRIBUTE_UNUSED,
+ virNodeDeviceDefPtr def)
+{
+ int ret = 0;
+ union _virNodeDevCapData *data = &def->caps->data;
+ char *filename = NULL, *p = NULL;
+
+ filename = basename(def->name);
+
+ virStrToLong_ui(filename, &p, 10, &data->scsi.host);
+ virStrToLong_ui(p+1, &p, 10, &data->scsi.bus);
+ virStrToLong_ui(p+1, &p, 10, &data->scsi.target);
+ virStrToLong_ui(p+1, &p, 10, &data->scsi.lun);
+
+ return ret;
+}
+
+
+static int udevProcessDisk(struct udev_device *device,
+ virNodeDeviceDefPtr def)
+{
+ union _virNodeDevCapData *data = &def->caps->data;
+ int ret = 0;
+
+ data->storage.drive_type = strdup("disk");
+ if (data->storage.drive_type == NULL) {
+ ret = -1;
+ goto out;
+ }
+
+ if (udevGetUint64SysfsAttr(device,
+ "size",
+ &data->storage.num_blocks) == PROPERTY_ERROR) {
+ goto out;
+ }
+
+ if (udevGetUint64SysfsAttr(device,
+ "queue/logical_block_size",
+ &data->storage.logical_block_size)
+ == PROPERTY_ERROR) {
+ goto out;
+ }
+
+
+ data->storage.size = data->storage.num_blocks *
+ data->storage.logical_block_size;
+
+out:
+ return ret;
+}
+
+
+static int udevProcessCDROM(struct udev_device *device,
+ virNodeDeviceDefPtr def)
+{
+ union _virNodeDevCapData *data = &def->caps->data;
+ int tmp_int = 0, ret = 0;
+
+ if ((udevGetIntSysfsAttr(device, "removable", &tmp_int, 0) ==
PROPERTY_FOUND) &&
+ (tmp_int == 1)) {
+ def->caps->data.storage.flags |= VIR_NODE_DEV_CAP_STORAGE_REMOVABLE;
+ }
+
+ if ((udevGetIntProperty(device, "ID_CDROM_MEDIA", &tmp_int, 0)
+ == PROPERTY_FOUND) && (tmp_int == 1)) {
+
+ def->caps->data.storage.flags |=
+ VIR_NODE_DEV_CAP_STORAGE_REMOVABLE_MEDIA_AVAILABLE;
+
+ if (udevGetUint64SysfsAttr(device,
+ "size",
+ &data->storage.num_blocks) == PROPERTY_ERROR)
{
+ goto out;
+ }
+
+ if (udevGetUint64SysfsAttr(device,
+ "queue/logical_block_size",
+ &data->storage.logical_block_size) ==
PROPERTY_ERROR) {
+ goto out;
+ }
+
+ /* XXX This calculation is wrong for the qemu virtual cdrom
+ * which reports the size in 512 byte blocks, but the logical
+ * block size as 2048. I don't have a physical cdrom on a
+ * devel system to see how they behave. */
+ def->caps->data.storage.removable_media_size =
+ def->caps->data.storage.num_blocks *
+ def->caps->data.storage.logical_block_size;
+ }
+
+out:
+ return ret;
+}
+
+
+/* This function exists to deal with the case in which a driver does
+ * not provide a device type in the usual place, but udev told us it's
+ * a storage device, and we can make a good guess at what kind of
+ * storage device it is from other information that is provided. */
+static int udevKludgeStorageType(virNodeDeviceDefPtr def)
+{
+ int ret = -1;
+
+ if (STRPREFIX(def->caps->data.storage.block, "/dev/vd")) {
+ /* virtio disk */
+ def->caps->data.storage.drive_type = strdup("disk");
+ if (def->caps->data.storage.drive_type != NULL) {
+ ret = 0;
+ }
+ }
+
+ return ret;
+}
+
+
+static void udevStripSpaces(char *s)
+{
+ if (s == NULL) {
+ return;
+ }
+
+ while (virFileStripSuffix(s, " ")) {
+ /* do nothing */
+ ;
+ }
+
+ return;
+}
+
+
+static int udevProcessStorage(struct udev_device *device,
+ virNodeDeviceDefPtr def)
+{
+ union _virNodeDevCapData *data = &def->caps->data;
+ int ret = -1;
+
+ data->storage.block = strdup(udev_device_get_devnode(device));
+ if (udevGetStringProperty(device,
+ "DEVNAME",
+ &data->storage.block) == PROPERTY_ERROR) {
+ goto out;
+ }
+ if (udevGetStringProperty(device,
+ "ID_BUS",
+ &data->storage.bus) == PROPERTY_ERROR) {
+ goto out;
+ }
+ if (udevGetStringProperty(device,
+ "ID_SERIAL",
+ &data->storage.serial) == PROPERTY_ERROR) {
+ goto out;
+ }
+ if (udevGetStringSysfsAttr(device,
+ "device/vendor",
+ &data->storage.vendor) == PROPERTY_ERROR) {
+ goto out;
+ }
+ udevStripSpaces(def->caps->data.storage.vendor);
+ if (udevGetStringSysfsAttr(device,
+ "device/model",
+ &data->storage.model) == PROPERTY_ERROR) {
+ goto out;
+ }
+ udevStripSpaces(def->caps->data.storage.model);
+ /* There is no equivalent of the hotpluggable property in libudev,
+ * but storage is going toward a world in which hotpluggable is
+ * expected, so I don't see a problem with not having a property
+ * for it. */
+
+ if (udevGetStringProperty(device,
+ "ID_TYPE",
+ &data->storage.drive_type) != 0) {
+ /* If udev doesn't have it, perhaps we can guess it. */
+ if (udevKludgeStorageType(def) != 0) {
+ goto out;
+ }
+ }
+
+ /* NB: drive_type has changed from HAL; now it's "cd" instead of
"cdrom" */
+ if (STREQ(def->caps->data.storage.drive_type, "cd")) {
+ ret = udevProcessCDROM(device, def);
+ } else if (STREQ(def->caps->data.storage.drive_type, "disk")) {
+ ret = udevProcessDisk(device, def);
+ } else {
+ goto out;
+ }
+
+out:
+ return ret;
+}
+
+
+static int udevSetDeviceType(struct udev_device *device,
+ virNodeDeviceDefPtr def)
+{
+ union _virNodeDevCapData *data = NULL;
+ const char *devtype = NULL;
+ int ret = 0;
+
+ if (VIR_ALLOC(def->caps) != 0) {
+ ret = -1;
+ goto out;
+ }
+
+ data = &def->caps->data;
+
+ devtype = udev_device_get_devtype(device);
+
+ if (udevGetUintProperty(device,
+ "PCI_CLASS",
+ &data->pci_dev.class,
+ 0) == PROPERTY_FOUND) {
+ def->caps->type = VIR_NODE_DEV_CAP_PCI_DEV;
+ goto out;
+ }
+
+ if (devtype != NULL && STREQ(devtype, "usb_device")) {
+ def->caps->type = VIR_NODE_DEV_CAP_USB_DEV;
+ goto out;
+ }
+
+ if (devtype != NULL && STREQ(devtype, "usb_interface")) {
+ def->caps->type = VIR_NODE_DEV_CAP_USB_INTERFACE;
+ goto out;
+ }
+
+ /* XXX Do some network interfaces set the device type property? */
+ if (udevGetStringProperty(device,
+ "INTERFACE",
+ &data->net.ifname) == PROPERTY_FOUND) {
+ def->caps->type = VIR_NODE_DEV_CAP_NET;
+ goto out;
+ }
+
+ if (devtype != NULL && STREQ(devtype, "scsi_host")) {
+ def->caps->type = VIR_NODE_DEV_CAP_SCSI_HOST;
+ goto out;
+ }
+
+ if (devtype != NULL && STREQ(devtype, "scsi_device")) {
+ def->caps->type = VIR_NODE_DEV_CAP_SCSI;
+ goto out;
+ }
+
+ if (devtype != NULL && STREQ(devtype, "disk")) {
+ def->caps->type = VIR_NODE_DEV_CAP_STORAGE;
+ goto out;
+ }
+
+ ret = -1;
+
+out:
+ return ret;
+}
+
+
+static int udevGetDeviceDetails(struct udev_device *device,
+ virNodeDeviceDefPtr def)
+{
+ int ret = 0;
+
+ switch (def->caps->type) {
+ case VIR_NODE_DEV_CAP_SYSTEM:
+ /* There's no libudev equivalent of system, so ignore it. */
+ break;
+ case VIR_NODE_DEV_CAP_PCI_DEV:
+ ret = udevProcessPCI(device, def);
+ break;
+ case VIR_NODE_DEV_CAP_USB_DEV:
+ ret = udevProcessUSBDevice(device, def);
+ break;
+ case VIR_NODE_DEV_CAP_USB_INTERFACE:
+ ret = udevProcessUSBInterface(device, def);
+ break;
+ case VIR_NODE_DEV_CAP_NET:
+ ret = udevProcessNetworkInterface(device, def);
+ break;
+ case VIR_NODE_DEV_CAP_SCSI_HOST:
+ ret = udevProcessSCSIHost(device, def);
+ break;
+ case VIR_NODE_DEV_CAP_SCSI:
+ ret = udevProcessSCSIDevice(device, def);
+ break;
+ case VIR_NODE_DEV_CAP_STORAGE:
+ ret = udevProcessStorage(device, def);
+ break;
+ default:
+ ret = -1;
+ break;
+ }
+
+ return ret;
+}
+
+
+static int udevRemoveOneDevice(struct udev_device *device)
+{
+ virNodeDeviceObjPtr dev = NULL;
+ const char *name = NULL;
+ int ret = 0;
+
+ name = udev_device_get_syspath(device);
+
+ dev = virNodeDeviceFindByName(&driverState->devs, name);
+ if (dev != NULL) {
+ virNodeDeviceObjRemove(&driverState->devs, dev);
+ } else {
+ ret = -1;
+ }
+
+ return ret;
+}
+
+
+static int udevAddOneDevice(struct udev_device *device)
+{
+ virNodeDeviceDefPtr def = NULL;
+ struct udev_device *parent = NULL;
+ virNodeDeviceObjPtr dev = NULL;
+ const char *parent_name = NULL;
+ int ret = -1;
+
+ if (VIR_ALLOC(def) != 0) {
+ goto out;
+ }
+
+ def->name = strdup(udev_device_get_syspath(device));
+ if (udevGetStringProperty(device,
+ "DRIVER",
+ &def->driver) == PROPERTY_ERROR) {
+ goto out;
+ }
+
+ parent = udev_device_get_parent(device);
+ if (parent != NULL) {
+ parent_name = udev_device_get_syspath(parent);
+ if (parent_name != NULL) {
+ def->parent = strdup(parent_name);
+ }
+ }
+
+ if (udevSetDeviceType(device, def) == 0) {
+ ret = udevGetDeviceDetails(device, def);
+ }
+
+ if (ret == 0) {
+ dev = virNodeDeviceAssignDef(NULL, &driverState->devs, def);
+ dev->devicePath = strdup(udev_device_get_devpath(device));
+ virNodeDeviceObjUnlock(dev);
+ } else {
+ virNodeDeviceDefFree(def);
+ }
+
+out:
+ return ret;
+}
+
+
+static int udevProcessDeviceListEntry(struct udev *udev,
+ struct udev_list_entry *list_entry)
+{
+ struct udev_device *device;
+ const char *name = NULL;
+ int ret = -1;
+
+ name = udev_list_entry_get_name(list_entry);
+
+ device = udev_device_new_from_syspath(udev, name);
+ if (device != NULL) {
+ udevAddOneDevice(device);
+ udev_device_unref(device);
+ ret = 0;
+ }
+
+ return ret;
+}
+
+
+static int udevEnumerateDevices(struct udev *udev)
+{
+ struct udev_enumerate *udev_enumerate = NULL;
+ struct udev_list_entry *list_entry = NULL;
+ const char *name = NULL;
+ int ret = 0;
+
+ udev_enumerate = udev_enumerate_new(udev);
+
+ ret = udev_enumerate_scan_devices(udev_enumerate);
+ if (0 != ret) {
+ VIR_ERROR("udev scan devices returned %d\n", ret);
+ goto out;
+ }
+
+ udev_list_entry_foreach(list_entry,
+ udev_enumerate_get_list_entry(udev_enumerate)) {
+
+ udevProcessDeviceListEntry(udev, list_entry);
+ name = udev_list_entry_get_name(list_entry);
+ }
+
+out:
+ udev_enumerate_unref(udev_enumerate);
+ return ret;
+}
+
+
+static int udevDeviceMonitorShutdown(void)
+{
+ int ret = 0;
+
+ struct udev_monitor *udev_monitor = NULL;
+ struct udev *udev = NULL;
+
+ if (driverState) {
+
+ nodeDeviceLock(driverState);
+ udev_monitor = DRV_STATE_UDEV_MONITOR(driverState);
+
+ if (udev_monitor != NULL) {
+ udev = udev_monitor_get_udev(udev_monitor);
+ udev_monitor_unref(udev_monitor);
+ }
+
+ if (udev != NULL) {
+ udev_unref(udev);
+ }
+
+ virNodeDeviceObjListFree(&driverState->devs);
+ nodeDeviceUnlock(driverState);
+ virMutexDestroy(&driverState->lock);
+ VIR_FREE(driverState);
+
+ } else {
+ ret = -1;
+ }
+
+ return ret;
+}
+
+
+static void udevEventHandleCallback(int watch ATTRIBUTE_UNUSED,
+ int fd,
+ int events ATTRIBUTE_UNUSED,
+ void *data ATTRIBUTE_UNUSED)
+{
+ struct udev_device *device = NULL;
+ struct udev_monitor *udev_monitor = DRV_STATE_UDEV_MONITOR(driverState);
+ const char *action = NULL;
+
+ if (fd != udev_monitor_get_fd(udev_monitor)) {
+ goto out;
+ }
+
+ device = udev_monitor_receive_device(udev_monitor);
+ if (device == NULL) {
+ goto out;
+ }
+
+ action = udev_device_get_action(device);
+
+ if (STREQ(action, "add") || STREQ(action, "change")) {
+ udevAddOneDevice(device);
+ goto out;
+ }
+
+ if (STREQ(action, "remove")) {
+ udevRemoveOneDevice(device);
+ goto out;
+ }
+
+out:
+ return;
+}
+
+
+static int udevSetupSystemDev(void)
+{
+ virNodeDeviceDefPtr def = NULL;
+ virNodeDeviceObjPtr dev = NULL;
+ struct udev *udev = NULL;
+ struct udev_device *device = NULL;
+ union _virNodeDevCapData *data = NULL;
+ char *tmp = NULL;
+ int ret = -1;
+
+ if (VIR_ALLOC(def) != 0) {
+ goto out;
+ }
+
+ def->name = strdup("computer");
+ if (def->name == NULL) {
+ goto out;
+ }
+
+ if (VIR_ALLOC(def->caps) != 0) {
+ goto out;
+ }
+
+ udev = udev_monitor_get_udev(DRV_STATE_UDEV_MONITOR(driverState));
+ device = udev_device_new_from_syspath(udev, DMI_DEVPATH);
+ if (device == NULL) {
+ goto out;
+ }
+
+ data = &def->caps->data;
+
+ data->system.dmi_devpath = strdup(DMI_DEVPATH);
+ data->system.description = strdup(SYSTEM_DESCRIPTION);
+
+ if (udevGetStringSysfsAttr(device,
+ "product_name",
+ &data->system.product_name) == PROPERTY_ERROR) {
+ goto out;
+ }
+ if (udevGetStringSysfsAttr(device,
+ "sys_vendor",
+ &data->system.hardware.vendor_name)
+ == PROPERTY_ERROR) {
+ goto out;
+ }
+ if (udevGetStringSysfsAttr(device,
+ "product_version",
+ &data->system.hardware.version)
+ == PROPERTY_ERROR) {
+ goto out;
+ }
+ if (udevGetStringSysfsAttr(device,
+ "product_serial",
+ &data->system.hardware.serial)
+ == PROPERTY_ERROR) {
+ goto out;
+ }
+
+ if (udevGetStringSysfsAttr(device,
+ "product_uuid",
+ &tmp) == PROPERTY_ERROR) {
+ goto out;
+ }
+ virUUIDParse(tmp, def->caps->data.system.hardware.uuid);
+ VIR_FREE(tmp);
+
+ if (udevGetStringSysfsAttr(device,
+ "bios_vendor",
+ &data->system.firmware.vendor_name)
+ == PROPERTY_ERROR) {
+ goto out;
+ }
+ if (udevGetStringSysfsAttr(device,
+ "bios_version",
+ &data->system.firmware.version)
+ == PROPERTY_ERROR) {
+ goto out;
+ }
+ if (udevGetStringSysfsAttr(device,
+ "bios_date",
+ &data->system.firmware.release_date)
+ == PROPERTY_ERROR) {
+ goto out;
+ }
+
+ udev_device_unref(device);
+
+ dev = virNodeDeviceAssignDef(NULL, &driverState->devs, def);
+ virNodeDeviceObjUnlock(dev);
+
+ ret = 0;
+
+out:
+ return ret;
+}
+
+static int udevDeviceMonitorStartup(int privileged ATTRIBUTE_UNUSED)
+{
+ struct udev *udev = NULL;
+ struct udev_monitor *udev_monitor = NULL;
+ int ret = 0;
+
+ if (VIR_ALLOC(driverState) < 0) {
+ ret = -1;
+ goto out;
+ }
+
+ if (virMutexInit(&driverState->lock) < 0) {
+ VIR_FREE(driverState);
+ ret = -1;
+ goto out;
+ }
+
+ nodeDeviceLock(driverState);
+
+ /*
+ *
http://www.kernel.org/pub/linux/utils/kernel/hotplug/libudev/libudev-udev...
+ *
+ * indicates no return value other than success, so we don't check
+ * its return value.
+ */
+ udev = udev_new();
+ udev_set_log_fn(udev, udevLogFunction);
+
+ udev_monitor = udev_monitor_new_from_netlink(udev, "udev");
+ if (udev_monitor == NULL) {
+ ret = -1;
+ goto out;
+ }
+
+ udev_monitor_enable_receiving(udev_monitor);
+
+ /* udev can be retrieved from udev_monitor */
+ driverState->privateData = udev_monitor;
+ nodeDeviceUnlock(driverState);
+
+ /* We register the monitor with the event callback so we are
+ * notified by udev of device changes before we enumerate existing
+ * devices because libvirt will simply recreate the device if we
+ * try to register it twice, i.e., if the device appears between
+ * the time we register the callback and the time we begin
+ * enumeration. The alternative is to register the callback after
+ * we enumerate, in which case we will fail to create any devices
+ * that appear while the enumeration is taking place. */
+ if (virEventAddHandleImpl(udev_monitor_get_fd(udev_monitor),
+ VIR_EVENT_HANDLE_READABLE,
+ udevEventHandleCallback,
+ NULL, NULL) == -1) {
+ ret = -1;
+ goto out;
+ }
+
+ /* Create a fictional 'computer' device to root the device tree. */
+ if (udevSetupSystemDev() != 0) {
+ ret = -1;
+ goto out;
+ }
+
+ /* Populate with known devices */
+
+ if (udevEnumerateDevices(udev) != 0) {
+ ret = -1;
+ goto out;
+ }
+
+out:
+ if (ret == -1) {
+ udevDeviceMonitorShutdown();
+ }
+ return ret;
+}
+
+
+static int udevDeviceMonitorReload(void)
+{
+ return 0;
+}
+
+
+static int udevDeviceMonitorActive(void)
+{
+ /* Always ready to deal with a shutdown */
+ return 0;
+}
+
+
+static virDrvOpenStatus udevNodeDrvOpen(virConnectPtr conn,
+ virConnectAuthPtr auth ATTRIBUTE_UNUSED,
+ int flags ATTRIBUTE_UNUSED)
+{
+ if (driverState == NULL) {
+ return VIR_DRV_OPEN_DECLINED;
+ }
+
+ conn->devMonPrivateData = driverState;
+
+ return VIR_DRV_OPEN_SUCCESS;
+}
+
+static int udevNodeDrvClose(virConnectPtr conn)
+{
+ conn->devMonPrivateData = NULL;
+ return 0;
+}
+
+static virDeviceMonitor udevDeviceMonitor = {
+ .name = "udevDeviceMonitor",
+ .open = udevNodeDrvOpen,
+ .close = udevNodeDrvClose,
+};
+
+static virStateDriver udevStateDriver = {
+ .initialize = udevDeviceMonitorStartup,
+ .cleanup = udevDeviceMonitorShutdown,
+ .reload = udevDeviceMonitorReload,
+ .active = udevDeviceMonitorActive,
+};
+
+int udevNodeRegister(void)
+{
+ VIR_ERROR0("Registering udev node device backend\n");
+
+ registerCommonNodeFuncs(&udevDeviceMonitor);
+ if (virRegisterDeviceMonitor(&udevDeviceMonitor) < 0) {
+ return -1;
+ }
+
+ return virRegisterStateDriver(&udevStateDriver);
+}
diff --git a/src/node_device/node_device_udev.h b/src/node_device/node_device_udev.h
new file mode 100644
index 0000000..d950106
--- /dev/null
+++ b/src/node_device/node_device_udev.h
@@ -0,0 +1,32 @@
+/*
+ * node_device_udev.h: node device enumeration - libudev implementation
+ *
+ * Copyright (C) 2009 Red Hat
+ *
+ * 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
+ *
+ * Author: Dave Allan <dallan(a)redhat.com>
+ */
+
+#include <libudev.h>
+#include <stdint.h>
+
+#define SYSFS_DATA_SIZE 4096
+#define DRV_STATE_UDEV_MONITOR(ds) ((struct udev_monitor *)((ds)->privateData))
+#define DMI_DEVPATH "/sys/devices/virtual/dmi/id"
+#define SYSTEM_DESCRIPTION "fictional device to root the node device tree"
+#define PROPERTY_FOUND 0
+#define PROPERTY_MISSING 1
+#define PROPERTY_ERROR -1
diff --git a/src/util/util.c b/src/util/util.c
index 98f8a14..f63bd39 100644
--- a/src/util/util.c
+++ b/src/util/util.c
@@ -2114,3 +2114,31 @@ void virFileWaitForDevices(virConnectPtr conn)
void virFileWaitForDevices(virConnectPtr conn ATTRIBUTE_UNUSED) {}
#endif
#endif
+
+int virBuildPathInternal(char **path, ...)
+{
+ char *path_component = NULL;
+ virBuffer buf = VIR_BUFFER_INITIALIZER;
+ va_list ap;
+ int ret = 0;
+
+ va_start(ap, *path);
+
+ path_component = va_arg(ap, char *);
+ virBufferAdd(&buf, path_component, -1);
+
+ while ((path_component = va_arg(ap, char *)) != NULL)
+ {
+ virBufferAddChar(&buf, '/');
+ virBufferAdd(&buf, path_component, -1);
+ }
+
+ va_end(ap);
+
+ *path = virBufferContentAndReset(&buf);
+ if (*path == NULL) {
+ ret = -1;
+ }
+
+ return ret;
+}
diff --git a/src/util/util.h b/src/util/util.h
index 8679636..da410e1 100644
--- a/src/util/util.h
+++ b/src/util/util.h
@@ -248,4 +248,7 @@ char *virFileFindMountPoint(const char *type);
void virFileWaitForDevices(virConnectPtr conn);
+#define virBuildPath(path, ...) virBuildPathInternal(path, __VA_ARGS__, NULL)
+int virBuildPathInternal(char **path, ...) __attribute__ ((sentinel));
+
#endif /* __VIR_UTIL_H__ */
diff --git a/tools/virsh.c b/tools/virsh.c
index 6b93405..19a2eb1 100644
--- a/tools/virsh.c
+++ b/tools/virsh.c
@@ -5790,9 +5790,17 @@ cmdNodeListDevices (vshControl *ctl, const vshCmd *cmd
ATTRIBUTE_UNUSED)
char **parents = vshMalloc(ctl, sizeof(char *) * num_devices);
for (i = 0; i < num_devices; i++) {
virNodeDevicePtr dev = virNodeDeviceLookupByName(ctl->conn, devices[i]);
+ virNodeDevicePtr parent_dev = NULL;
+
if (dev && STRNEQ(devices[i], "computer")) {
const char *parent = virNodeDeviceGetParent(dev);
- parents[i] = parent ? strdup(parent) : NULL;
+ parent_dev = virNodeDeviceLookupByName(ctl->conn, parent);
+ if (parent_dev) {
+ parents[i] = strdup(parent);
+ } else {
+ parents[i] = strdup("computer");
+ }
+ virNodeDeviceFree(parent_dev);
} else {
parents[i] = NULL;
}
--
1.6.4.4
From cc3644b71d042ff394c9540a9f364752484f63a8 Mon Sep 17 00:00:00 2001
From: David Allan <dallan(a)redhat.com>
Date: Fri, 16 Oct 2009 14:36:07 -0400
Subject: [PATCH 3/3] Remove DevKit node device backend
---
configure.in | 61 +-----
src/Makefile.am | 9 -
src/node_device/node_device_devkit.c | 446 ----------------------------------
src/node_device/node_device_driver.c | 3 -
src/node_device/node_device_driver.h | 3 -
5 files changed, 1 insertions(+), 521 deletions(-)
delete mode 100644 src/node_device/node_device_devkit.c
diff --git a/configure.in b/configure.in
index 25ed55f..3d05d9b 100644
--- a/configure.in
+++ b/configure.in
@@ -1680,60 +1680,6 @@ AM_CONDITIONAL([HAVE_HAL], [test "x$with_hal" =
"xyes"])
AC_SUBST([HAL_CFLAGS])
AC_SUBST([HAL_LIBS])
-DEVKIT_REQUIRED=0.0
-DEVKIT_CFLAGS=
-DEVKIT_LIBS=
-AC_ARG_WITH([devkit],
- [ --with-devkit use DeviceKit for host device enumeration],
- [],
- [with_devkit=no])
-
-if test "$with_libvirtd" = "no" ; then
- with_devkit=no
-fi
-
-dnl Extra check needed while devkit pkg-config info missing glib2 dependency
-PKG_CHECK_MODULES(GLIB2, glib-2.0 >= 0.0,,[
- if test "x$with_devkit" = "xcheck"; then
- with_devkit=no
- elif test "x$with_devkit" = "xyes"; then
- AC_MSG_ERROR([required package DeviceKit requires package glib-2.0])
- fi])
-
-if test "x$with_devkit" = "xyes" -o "x$with_devkit" =
"xcheck"; then
- PKG_CHECK_MODULES(DEVKIT, devkit-gobject >= $DEVKIT_REQUIRED,
- [with_devkit=yes], [
- if test "x$with_devkit" = "xcheck" ; then
- with_devkit=no
- else
- AC_MSG_ERROR(
- [You must install DeviceKit-devel >= $DEVKIT_REQUIRED to compile libvirt])
- fi
- ])
- if test "x$with_devkit" = "xyes" ; then
- AC_DEFINE_UNQUOTED([HAVE_DEVKIT], 1,
- [use DeviceKit for host device enumeration])
-
- dnl Add glib2 flags explicitly while devkit pkg-config info missing glib2 dependency
- DEVKIT_CFLAGS="$GLIB2_CFLAGS $DEVKIT_CFLAGS"
- DEVKIT_LIBS="$GLIB2_LIBS $DEVKIT_LIBS"
-
- dnl Add more flags apparently required for devkit to work properly
- DEVKIT_CFLAGS="$DEVKIT_CFLAGS -D_POSIX_PTHREAD_SEMANTICS -D_REENTRANT"
-
- old_CFLAGS=$CFLAGS
- old_LDFLAGS=$LDFLAGS
- CFLAGS="$CFLAGS $DEVKIT_CFLAGS"
- LDFLAGS="$LDFLAGS $DEVKIT_LIBS"
- AC_CHECK_FUNCS([devkit_client_connect],,[with_devkit=no])
- CFLAGS="$old_CFLAGS"
- LDFLAGS="$old_LDFLAGS"
- fi
-fi
-AM_CONDITIONAL([HAVE_DEVKIT], [test "x$with_devkit" = "xyes"])
-AC_SUBST([DEVKIT_CFLAGS])
-AC_SUBST([DEVKIT_LIBS])
-
UDEV_REQUIRED=143
UDEV_CFLAGS=
UDEV_LIBS=
@@ -1773,7 +1719,7 @@ AC_SUBST([UDEV_CFLAGS])
AC_SUBST([UDEV_LIBS])
with_nodedev=no;
-if test "$with_devkit" = "yes" -o "$with_hal" =
"yes" -o "$with_udev" = "yes";
+if test "$with_hal" = "yes" -o "$with_udev" =
"yes";
then
with_nodedev=yes
AC_DEFINE_UNQUOTED([WITH_NODE_DEVICES], 1, [with node device driver])
@@ -1933,11 +1879,6 @@ AC_MSG_NOTICE([ hal: $HAL_CFLAGS $HAL_LIBS])
else
AC_MSG_NOTICE([ hal: no])
fi
-if test "$with_devkit" = "yes" ; then
-AC_MSG_NOTICE([ devkit: $DEVKIT_CFLAGS $DEVKIT_LIBS])
-else
-AC_MSG_NOTICE([ devkit: no])
-fi
if test "$with_udev" = "yes" ; then
AC_MSG_NOTICE([ udev: $UDEV_CFLAGS $UDEV_LIBS])
else
diff --git a/src/Makefile.am b/src/Makefile.am
index 11da07b..cd05c28 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -262,9 +262,6 @@ NODE_DEVICE_DRIVER_HAL_SOURCES = \
node_device/node_device_hal.c \
node_device/node_device_hal.h
-NODE_DEVICE_DRIVER_DEVKIT_SOURCES = \
- node_device/node_device_devkit.c
-
NODE_DEVICE_DRIVER_UDEV_SOURCES = \
node_device/node_device_udev.c
@@ -641,11 +638,6 @@ libvirt_driver_nodedev_la_SOURCES +=
$(NODE_DEVICE_DRIVER_HAL_SOURCES)
libvirt_driver_nodedev_la_CFLAGS += $(HAL_CFLAGS)
libvirt_driver_nodedev_la_LDFLAGS += $(HAL_LIBS)
endif
-if HAVE_DEVKIT
-libvirt_driver_nodedev_la_SOURCES += $(NODE_DEVICE_DRIVER_DEVKIT_SOURCES)
-libvirt_driver_nodedev_la_CFLAGS += $(DEVKIT_CFLAGS)
-libvirt_driver_nodedev_la_LDFLAGS += $(DEVKIT_LIBS)
-endif
if HAVE_UDEV
libvirt_driver_nodedev_la_SOURCES += $(NODE_DEVICE_DRIVER_UDEV_SOURCES)
libvirt_driver_nodedev_la_CFLAGS += $(UDEV_CFLAGS)
@@ -699,7 +691,6 @@ EXTRA_DIST += \
$(STORAGE_DRIVER_DISK_SOURCES) \
$(NODE_DEVICE_DRIVER_SOURCES) \
$(NODE_DEVICE_DRIVER_HAL_SOURCES) \
- $(NODE_DEVICE_DRIVER_DEVKIT_SOURCES) \
$(NODE_DEVICE_DRIVER_UDEV_SOURCES) \
$(SECURITY_DRIVER_SELINUX_SOURCES) \
$(SECURITY_DRIVER_APPARMOR_SOURCES) \
diff --git a/src/node_device/node_device_devkit.c b/src/node_device/node_device_devkit.c
deleted file mode 100644
index a6c7941..0000000
--- a/src/node_device/node_device_devkit.c
+++ /dev/null
@@ -1,446 +0,0 @@
-/*
- * node_device_devkit.c: node device enumeration - DeviceKit-based implementation
- *
- * Copyright (C) 2008 Virtual Iron Software, Inc.
- * Copyright (C) 2008 David F. Lively
- *
- * 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
- *
- * Author: David F. Lively <dlively(a)virtualiron.com>
- */
-
-#include <config.h>
-#include <devkit-gobject.h>
-
-#include "node_device_conf.h"
-#include "virterror_internal.h"
-#include "driver.h"
-#include "datatypes.h"
-#include "event.h"
-#include "memory.h"
-#include "uuid.h"
-#include "logging.h"
-
-#include "node_device.h"
-
-/*
- * Host device enumeration (DeviceKit implementation)
- */
-
-static virDeviceMonitorStatePtr driverState;
-
-#define CONN_DRV_STATE(conn) \
- ((virDeviceMonitorStatePtr)((conn)->devMonPrivateData))
-#define DRV_STATE_DKCLIENT(ds) ((DevkitClient *)((ds)->privateData))
-#define CONN_DKCLIENT(conn) DRV_STATE_DKCLIENT(CONN_DRV_STATE(conn))
-
-#define NODE_DEV_DKDEV(obj) ((DevkitDevice *)((obj)->privateData)
-
-static int get_str_prop(DevkitDevice *dkdev, const char *prop, char **val_p)
-{
- char *val = devkit_device_dup_property_as_str(dkdev, prop);
-
- if (val) {
- if (*val) {
- *val_p = val;
- return 0;
- } else {
- /* Treat empty strings as NULL values */
- VIR_FREE(val);
- }
- }
-
- return -1;
-}
-
-#if 0
-static int get_int_prop(DevkitDevice *dkdev, const char *prop, int *val_p)
-{
- if (! devkit_device_has_property(dkdev, prop))
- return -1;
- *val_p = devkit_device_get_property_as_int(dkdev, prop);
- return 0;
-}
-
-static int get_uint64_prop(DevkitDevice *dkdev, const char *prop,
- unsigned long long *val_p)
-{
- if (! devkit_device_has_property(dkdev, prop))
- return -1;
- *val_p = devkit_device_get_property_as_uint64(dkdev, prop);
- return 0;
-}
-#endif
-
-static int gather_pci_cap(DevkitDevice *dkdev,
- union _virNodeDevCapData *d)
-{
- const char *sysfs_path = devkit_device_get_native_path(dkdev);
-
- if (sysfs_path != NULL) {
- char *p = strrchr(sysfs_path, '/');
- if (p) {
- (void)virStrToLong_ui(p+1, &p, 16, &d->pci_dev.domain);
- (void)virStrToLong_ui(p+1, &p, 16, &d->pci_dev.bus);
- (void)virStrToLong_ui(p+1, &p, 16, &d->pci_dev.slot);
- (void)virStrToLong_ui(p+1, &p, 16, &d->pci_dev.function);
- }
- }
- return 0;
-}
-
-
-static int gather_usb_cap(DevkitDevice *dkdev,
- union _virNodeDevCapData *d)
-{
- (void)get_str_prop(dkdev, "ID_VENDOR", &d->usb_dev.vendor_name);
- (void)get_str_prop(dkdev, "ID_MODEL", &d->usb_dev.product_name);
- return 0;
-}
-
-
-static int gather_net_cap(DevkitDevice *dkdev,
- union _virNodeDevCapData *d)
-{
- const char *sysfs_path = devkit_device_get_native_path(dkdev);
- const char *ifname;
-
- if (sysfs_path == NULL)
- return -1;
- ifname = strrchr(sysfs_path, '/');
- if (!ifname || !*ifname || !*(++ifname))
- return -1;
- if ((d->net.ifname = strdup(ifname)) == NULL)
- return -1;
-
- d->net.subtype = VIR_NODE_DEV_CAP_NET_LAST;
-
- return 0;
-}
-
-
-static int gather_storage_cap(DevkitDevice *dkdev,
- union _virNodeDevCapData *d)
-{
- const char *device = devkit_device_get_device_file(dkdev);
-
- if (device && ((d->storage.block = strdup(device)) == NULL))
- return -1;
-
- return 0;
-}
-
-
-struct _caps_tbl_entry {
- const char *cap_name;
- enum virNodeDevCapType type;
- int (*gather_fn)(DevkitDevice *dkdev,
- union _virNodeDevCapData *data);
-};
-
-typedef struct _caps_tbl_entry caps_tbl_entry;
-
-static caps_tbl_entry caps_tbl[] = {
- { "pci", VIR_NODE_DEV_CAP_PCI_DEV, gather_pci_cap },
- { "usb", VIR_NODE_DEV_CAP_USB_DEV, gather_usb_cap },
- { "net", VIR_NODE_DEV_CAP_NET, gather_net_cap },
- { "block", VIR_NODE_DEV_CAP_STORAGE, gather_storage_cap },
- // TODO: more caps!
-};
-
-
-/* qsort/bsearch string comparator */
-static int cmpstringp(const void *p1, const void *p2)
-{
- /* from man 3 qsort */
- return strcmp(* (char * const *) p1, * (char * const *) p2);
-}
-
-
-static int gather_capability(DevkitDevice *dkdev,
- const char *cap_name,
- virNodeDevCapsDefPtr *caps_p)
-{
- size_t caps_tbl_len = sizeof(caps_tbl) / sizeof(caps_tbl[0]);
- caps_tbl_entry *entry;
-
- entry = bsearch(&cap_name, caps_tbl, caps_tbl_len,
- sizeof(caps_tbl[0]), cmpstringp);
-
- if (entry) {
- virNodeDevCapsDefPtr caps;
- if (VIR_ALLOC(caps) < 0)
- return ENOMEM;
- caps->type = entry->type;
- if (entry->gather_fn) {
- int rv = (*entry->gather_fn)(dkdev, &caps->data);
- if (rv != 0) {
- virNodeDevCapsDefFree(caps);
- return rv;
- }
- }
- caps->next = *caps_p;
- *caps_p = caps;
- }
-
- return 0;
-}
-
-
-static int gather_capabilities(DevkitDevice *dkdev,
- virNodeDevCapsDefPtr *caps_p)
-{
- const char *subsys = devkit_device_get_subsystem(dkdev);
- const char *bus_name = devkit_device_get_property(dkdev, "ID_BUS");
- virNodeDevCapsDefPtr caps = NULL;
- int rv;
-
- if (subsys) {
- rv = gather_capability(dkdev, subsys, &caps);
- if (rv != 0) goto failure;
- }
-
- if (bus_name && (subsys == NULL || !STREQ(bus_name, subsys))) {
- rv = gather_capability(dkdev, bus_name, &caps);
- if (rv != 0) goto failure;
- }
-
- *caps_p = caps;
- return 0;
-
- failure:
- while (caps) {
- virNodeDevCapsDefPtr next = caps->next;
- virNodeDevCapsDefFree(caps);
- caps = next;
- }
- return rv;
-}
-
-static void dev_create(void *_dkdev, void *_dkclient ATTRIBUTE_UNUSED)
-{
- DevkitDevice *dkdev = _dkdev;
- const char *sysfs_path = devkit_device_get_native_path(dkdev);
- virNodeDeviceObjPtr dev = NULL;
- virNodeDeviceDefPtr def = NULL;
- const char *name;
- int rv;
-
- if (sysfs_path == NULL)
- /* Currently using basename(sysfs_path) as device name (key) */
- return;
-
- name = strrchr(sysfs_path, '/');
- if (name == NULL)
- name = sysfs_path;
- else
- ++name;
-
- if (VIR_ALLOC(def) < 0)
- goto failure;
-
- if ((def->name = strdup(name)) == NULL)
- goto failure;
-
- // TODO: Find device parent, if any
-
- rv = gather_capabilities(dkdev, &def->caps);
- if (rv != 0) goto failure;
-
- nodeDeviceLock(driverState);
- dev = virNodeDeviceAssignDef(NULL,
- &driverState->devs,
- def);
-
- if (!dev) {
- nodeDeviceUnlock(driverState);
- goto failure;
- }
-
- dev->privateData = dkdev;
- dev->privateFree = NULL; /* XXX some free func needed ? */
- virNodeDeviceObjUnlock(dev);
-
- nodeDeviceUnlock(driverState);
-
- return;
-
- failure:
- DEBUG("FAILED TO ADD dev %s", name);
- if (def)
- virNodeDeviceDefFree(def);
-}
-
-
-static int devkitDeviceMonitorStartup(int privileged ATTRIBUTE_UNUSED)
-{
- size_t caps_tbl_len = sizeof(caps_tbl) / sizeof(caps_tbl[0]);
- DevkitClient *devkit_client = NULL;
- GError *err = NULL;
- GList *devs;
- int i;
-
- /* Ensure caps_tbl is sorted by capability name */
- qsort(caps_tbl, caps_tbl_len, sizeof(caps_tbl[0]), cmpstringp);
-
- if (VIR_ALLOC(driverState) < 0)
- return -1;
-
- if (virMutexInit(&driverState->lock) < 0) {
- VIR_FREE(driverState);
- return -1;
- }
-
- g_type_init();
-
- /* Get new devkit_client and connect to daemon */
- devkit_client = devkit_client_new(NULL);
- if (devkit_client == NULL) {
- DEBUG0("devkit_client_new returned NULL");
- goto failure;
- }
- if (!devkit_client_connect(devkit_client, &err)) {
- DEBUG0("devkit_client_connect failed");
- goto failure;
- }
-
- /* Populate with known devices.
- *
- * This really should be:
- devs = devkit_client_enumerate_by_subsystem(devkit_client, NULL, &err);
- if (err) {
- DEBUG0("devkit_client_enumerate_by_subsystem failed");
- devs = NULL;
- goto failure;
- }
- g_list_foreach(devs, dev_create, devkit_client);
- * but devkit_client_enumerate_by_subsystem currently fails when the second
- * arg is null (contrary to the API documentation). So the following code
- * (from Dan B) works around this by listing devices per handled subsystem.
- */
-
- for (i = 0 ; i < ARRAY_CARDINALITY(caps_tbl) ; i++) {
- const char *caps[] = { caps_tbl[i].cap_name, NULL };
- devs = devkit_client_enumerate_by_subsystem(devkit_client,
- caps,
- &err);
- if (err) {
- DEBUG0("devkit_client_enumerate_by_subsystem failed");
- devs = NULL;
- goto failure;
- }
- g_list_foreach(devs, dev_create, devkit_client);
- }
-
- driverState->privateData = devkit_client;
-
- // TODO: Register to get DeviceKit events on device changes and
- // coordinate updates with queries and other operations.
-
- return 0;
-
- failure:
- if (err) {
- DEBUG("\terror[%d]: %s", err->code, err->message);
- g_error_free(err);
- }
- if (devs) {
- g_list_foreach(devs, (GFunc)g_object_unref, NULL);
- g_list_free(devs);
- }
- if (devkit_client)
- g_object_unref(devkit_client);
- VIR_FREE(driverState);
-
- return -1;
-}
-
-
-static int devkitDeviceMonitorShutdown(void)
-{
- if (driverState) {
- DevkitClient *devkit_client;
-
- nodeDeviceLock(driverState);
- devkit_client = DRV_STATE_DKCLIENT(driverState);
- virNodeDeviceObjListFree(&driverState->devs);
- if (devkit_client)
- g_object_unref(devkit_client);
- nodeDeviceUnlock(driverState);
- virMutexDestroy(&driveState->lock);
- VIR_FREE(driverState);
- return 0;
- }
- return -1;
-}
-
-
-static int devkitDeviceMonitorReload(void)
-{
- /* XXX This isn't thread safe because its free'ing the thing
- * we're locking */
- (void)devkitDeviceMonitorShutdown();
- return devkitDeviceMonitorStartup();
-}
-
-
-static int devkitDeviceMonitorActive(void)
-{
- /* Always ready to deal with a shutdown */
- return 0;
-}
-
-
-static virDrvOpenStatus
-devkitNodeDrvOpen(virConnectPtr conn,
- virConnectAuthPtr auth ATTRIBUTE_UNUSED,
- int flags ATTRIBUTE_UNUSED)
-{
- if (driverState == NULL)
- return VIR_DRV_OPEN_DECLINED;
-
- conn->devMonPrivateData = driverState;
-
- return VIR_DRV_OPEN_SUCCESS;
-}
-
-static int devkitNodeDrvClose(virConnectPtr conn ATTRIBUTE_UNUSED)
-{
- conn->devMonPrivateData = NULL;
- return 0;
-}
-
-
-static virDeviceMonitor devkitDeviceMonitor = {
- .name = "devkitDeviceMonitor",
- .open = devkitNodeDrvOpen,
- .close = devkitNodeDrvClose,
-};
-
-
-static virStateDriver devkitStateDriver = {
- .initialize = devkitDeviceMonitorStartup,
- .cleanup = devkitDeviceMonitorShutdown,
- .reload = devkitDeviceMonitorReload,
- .active = devkitDeviceMonitorActive,
-};
-
-int devkitNodeRegister(void)
-{
- registerCommonNodeFuncs(&devkitDeviceMonitor);
- if (virRegisterDeviceMonitor(&devkitDeviceMonitor) < 0)
- return -1;
- return virRegisterStateDriver(&devkitStateDriver);
-}
diff --git a/src/node_device/node_device_driver.c b/src/node_device/node_device_driver.c
index c139907..cddd994 100644
--- a/src/node_device/node_device_driver.c
+++ b/src/node_device/node_device_driver.c
@@ -670,9 +670,6 @@ int nodedevRegister(void) {
#ifdef HAVE_HAL
return halNodeRegister();
#endif
-#ifdef HAVE_DEVKIT
- return devkitNodeRegister();
-#endif
#ifdef HAVE_UDEV
return udevNodeRegister();
#endif
diff --git a/src/node_device/node_device_driver.h b/src/node_device/node_device_driver.h
index 5be0781..4f0822c 100644
--- a/src/node_device/node_device_driver.h
+++ b/src/node_device/node_device_driver.h
@@ -42,9 +42,6 @@
#ifdef HAVE_HAL
int halNodeRegister(void);
#endif
-#ifdef HAVE_DEVKIT
-int devkitNodeRegister(void);
-#endif
#ifdef HAVE_UDEV
int udevNodeRegister(void);
#endif
--
1.6.4.4