mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2024-12-22 13:45:38 +00:00
Implement a node device backend using libudev
* configure.in: add new --with-udev, disabled by default, and requiring libudev > 145 * src/node_device/node_device_udev.c src/node_device/node_device_udev.h: the new node device backend * src/node_device/node_device_linux_sysfs.c: moved node_device_hal_linux.c to a better file name * src/conf/node_device_conf.c src/conf/node_device_conf.h: add a couple of fields in node device definitions, and an API to look them up, remove a couple of unused fields from previous patch. * src/node_device/node_device_driver.c src/node_device/node_device_driver.h: plug the new driver * po/POTFILES.in src/Makefile.am src/libvirt_private.syms: add the new files and symbols * src/util/util.h src/util/util.c: add a new convenience macro virBuildPath and virBuildPathInternal() function
This commit is contained in:
parent
fe2af45bb2
commit
3ad6dcf3dc
47
configure.in
47
configure.in
@ -1654,7 +1654,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=
|
||||
@ -1748,8 +1748,46 @@ AM_CONDITIONAL([HAVE_DEVKIT], [test "x$with_devkit" = "xyes"])
|
||||
AC_SUBST([DEVKIT_CFLAGS])
|
||||
AC_SUBST([DEVKIT_LIBS])
|
||||
|
||||
UDEV_REQUIRED=145
|
||||
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 libudev-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])
|
||||
@ -1914,6 +1952,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
|
||||
|
@ -877,8 +877,7 @@ static struct qemud_server *qemudInitialize(void) {
|
||||
#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();
|
||||
|
@ -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
|
||||
|
@ -259,16 +259,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
|
||||
|
||||
|
||||
#########################
|
||||
#
|
||||
@ -647,6 +651,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
|
||||
@ -696,6 +705,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) \
|
||||
|
@ -91,6 +91,26 @@ int virNodeDeviceHasCap(const virNodeDeviceObjPtr dev, const char *cap)
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
virNodeDeviceObjPtr
|
||||
virNodeDeviceFindBySysfsPath(const virNodeDeviceObjListPtr devs,
|
||||
const char *sysfs_path)
|
||||
{
|
||||
unsigned int i;
|
||||
|
||||
for (i = 0; i < devs->count; i++) {
|
||||
virNodeDeviceObjLock(devs->objs[i]);
|
||||
if ((devs->objs[i]->def->sysfs_path != NULL) &&
|
||||
(STREQ(devs->objs[i]->def->sysfs_path, sysfs_path))) {
|
||||
return devs->objs[i];
|
||||
}
|
||||
virNodeDeviceObjUnlock(devs->objs[i]);
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
virNodeDeviceObjPtr virNodeDeviceFindByName(const virNodeDeviceObjListPtr devs,
|
||||
const char *name)
|
||||
{
|
||||
@ -117,6 +137,8 @@ void virNodeDeviceDefFree(virNodeDeviceDefPtr def)
|
||||
VIR_FREE(def->name);
|
||||
VIR_FREE(def->parent);
|
||||
VIR_FREE(def->driver);
|
||||
VIR_FREE(def->sysfs_path);
|
||||
VIR_FREE(def->parent_sysfs_path);
|
||||
|
||||
caps = def->caps;
|
||||
while (caps) {
|
||||
@ -228,9 +250,17 @@ char *virNodeDeviceDefFormat(virConnectPtr conn,
|
||||
|
||||
virBufferAddLit(&buf, "<device>\n");
|
||||
virBufferEscapeString(&buf, " <name>%s</name>\n", def->name);
|
||||
|
||||
if (def->parent)
|
||||
if (def->sysfs_path != NULL) {
|
||||
virBufferEscapeString(&buf, " <sysfs_path>%s</sysfs_path>\n",
|
||||
def->sysfs_path);
|
||||
}
|
||||
if (def->parent) {
|
||||
virBufferEscapeString(&buf, " <parent>%s</parent>\n", def->parent);
|
||||
}
|
||||
if (def->parent_sysfs_path != NULL) {
|
||||
virBufferEscapeString(&buf, " <parent_sysfs_path>%s</parent_sysfs_path>\n",
|
||||
def->parent_sysfs_path);
|
||||
}
|
||||
if (def->driver) {
|
||||
virBufferAddLit(&buf, " <driver>\n");
|
||||
virBufferEscapeString(&buf, " <name>%s</name>\n", def->driver);
|
||||
@ -248,12 +278,6 @@ 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",
|
||||
@ -331,9 +355,6 @@ 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);
|
||||
@ -1340,8 +1361,6 @@ 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);
|
||||
@ -1358,7 +1377,6 @@ 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:
|
||||
|
@ -82,8 +82,6 @@ struct _virNodeDevCapsDef {
|
||||
union _virNodeDevCapData {
|
||||
struct {
|
||||
char *product_name;
|
||||
char *description;
|
||||
char *dmi_devpath;
|
||||
struct {
|
||||
char *vendor_name;
|
||||
char *version;
|
||||
@ -120,7 +118,6 @@ struct _virNodeDevCapsDef {
|
||||
unsigned _class; /* "class" is reserved in C */
|
||||
unsigned subclass;
|
||||
unsigned protocol;
|
||||
char *interface_name;
|
||||
char *description;
|
||||
} usb_if;
|
||||
struct {
|
||||
@ -164,7 +161,9 @@ typedef struct _virNodeDeviceDef virNodeDeviceDef;
|
||||
typedef virNodeDeviceDef *virNodeDeviceDefPtr;
|
||||
struct _virNodeDeviceDef {
|
||||
char *name; /* device name (unique on node) */
|
||||
char *sysfs_path; /* udev name/sysfs path */
|
||||
char *parent; /* optional parent device name */
|
||||
char *parent_sysfs_path; /* udev parent name/sysfs path */
|
||||
char *driver; /* optional driver name */
|
||||
virNodeDevCapsDefPtr caps; /* optional device capabilities */
|
||||
};
|
||||
@ -206,6 +205,9 @@ int virNodeDeviceHasCap(const virNodeDeviceObjPtr dev, const char *cap);
|
||||
|
||||
virNodeDeviceObjPtr virNodeDeviceFindByName(const virNodeDeviceObjListPtr devs,
|
||||
const char *name);
|
||||
virNodeDeviceObjPtr
|
||||
virNodeDeviceFindBySysfsPath(const virNodeDeviceObjListPtr devs,
|
||||
const char *sysfs_path);
|
||||
|
||||
virNodeDeviceObjPtr virNodeDeviceAssignDef(virConnectPtr conn,
|
||||
virNodeDeviceObjListPtr devs,
|
||||
|
@ -341,6 +341,7 @@ virNodeDeviceHasCap;
|
||||
virNodeDeviceObjRemove;
|
||||
virNodeDevCapTypeToString;
|
||||
virNodeDeviceFindByName;
|
||||
virNodeDeviceFindBySysfsPath;
|
||||
virNodeDeviceObjListFree;
|
||||
virNodeDeviceDefFree;
|
||||
virNodeDevCapsDefFree;
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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__ */
|
||||
|
@ -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__ */
|
||||
|
1519
src/node_device/node_device_udev.c
Normal file
1519
src/node_device/node_device_udev.c
Normal file
File diff suppressed because it is too large
Load Diff
31
src/node_device/node_device_udev.h
Normal file
31
src/node_device/node_device_udev.h
Normal file
@ -0,0 +1,31 @@
|
||||
/*
|
||||
* 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@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 PROPERTY_FOUND 0
|
||||
#define PROPERTY_MISSING 1
|
||||
#define PROPERTY_ERROR -1
|
@ -2128,3 +2128,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;
|
||||
}
|
||||
|
@ -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__ */
|
||||
|
Loading…
Reference in New Issue
Block a user