[libvirt] USB node devices info
by Daniel Berteaud
Hi there.
I have a problem with USB host device enumeration with libvirt.
I'm running libvirt 0.7.0 on a fully updated CentOS 5.3 (libvirt was
rebuilt unmodified from
http://libvirt.org/sources/libvirt-0.7.0-1.fc11.src.rpm)
I want to pas an USB key to one of my guest. lsusb see it just fine:
(I want to pass the device 13fe:1d23)
Bus 005 Device 001: ID 0000:0000
Bus 005 Device 002: ID 046b:ff10 American Megatrends, Inc.
Bus 004 Device 001: ID 0000:0000
Bus 007 Device 001: ID 0000:0000
Bus 006 Device 001: ID 0000:0000
Bus 008 Device 001: ID 0000:0000
Bus 002 Device 006: ID 13fe:1d23 Kingston Technology Company Inc.
Bus 002 Device 001: ID 0000:0000
Bus 001 Device 001: ID 0000:0000
Bus 003 Device 001: ID 0000:0000
Bus 003 Device 002: ID 413c:2003 Dell Computer Corp. Keyboard
If I create a XML file for this device, I can attach it to my guest with virsh attach-device, no problem here.
The problem is that libvirt cannot access the devices informations like pretty name,
vendorID and productID, so for example, virt-manager only see devices with name "USB Raw Device Access"
with 0000 as vendorID and productID.
For example, for this particular USB key:
virsh nodedev-dumpxml usb_device_13fe_1d23_07780BA646FD_0_usbraw
<device>
<name>usb_device_13fe_1d23_07780BA646FD_0_usbraw</name>
<parent>usb_device_13fe_1d23_07780BA646FD_0</parent>
<capability type='usb_device'>
<bus>0</bus>
<device>0</device>
<product id='0x0000'>USB Raw Device Access</product>
<vendor id='0x0000' />
</capability>
</device>
SELinux is in permissive mode.
Anybody have an idea ? Where does libvirt get the info about host device ? (/sys ?)
Regards, Daniel
--
Daniel Berteaud
FIREWALL-SERVICES SARL.
Société de Services en Logiciels Libres
Technopôle Montesquieu
33650 MARTILLAC
Tel : 05 56 64 15 32
Fax : 05 56 64 15 32
Mail: daniel(a)firewall-services.com
Web : http://www.firewall-services.com
15 years, 1 month
[libvirt] regarding libvirtd start
by santosh gandham
Hi,
I have installed libvirt 0.7.0. in fedora 11. When I start libvirt by using
#libvirtd start , it is not showing any status message like libvirtd has
started. The command line stuck up there itself. What is the problem? What
should I do to run the libvirtd successfully?
Thank you.
--
Gandham Santhosh
15 years, 1 month
[libvirt] [PATCH 0/5] test: Add node device driver
by Cole Robinson
The following patches implement a basic node device driver for the
test hypervisor driver. This is useful for unit tests in libvirt users
(particularly virtinst).
Cole Robinson (5):
nodedev: Add locking in nodeNumOfDevices
nodedev: Break out virNodeDeviceHasCap to node_conf
test: Implement node device driver.
node conf: Make parsing routines consistent with other drivers
test: Support loading node device info from file/XML
examples/xml/test/testdev.xml | 16 ++
examples/xml/test/testnode.xml | 1 +
examples/xml/test/testnodeinline.xml | 19 +++
src/conf/node_device_conf.c | 57 ++++++-
src/conf/node_device_conf.h | 11 ++
src/libvirt_private.syms | 1 +
src/node_device/node_device_driver.c | 22 +--
src/test/test_driver.c | 291 +++++++++++++++++++++++++++++++++-
8 files changed, 396 insertions(+), 22 deletions(-)
create mode 100644 examples/xml/test/testdev.xml
15 years, 1 month
[libvirt] [PATCH] test: Throw a proper error in GetBridgeName
by Cole Robinson
Throw error in GetBridgeName if net has no bridge.
Signed-off-by: Cole Robinson <crobinso(a)redhat.com>
---
src/test/test_driver.c | 10 ++++++++--
1 files changed, 8 insertions(+), 2 deletions(-)
diff --git a/src/test/test_driver.c b/src/test/test_driver.c
index f57c92a..30014fc 100644
--- a/src/test/test_driver.c
+++ b/src/test/test_driver.c
@@ -2546,8 +2546,14 @@ static char *testNetworkGetBridgeName(virNetworkPtr network) {
goto cleanup;
}
- if (privnet->def->bridge &&
- !(bridge = strdup(privnet->def->bridge))) {
+ if (!(privnet->def->bridge)) {
+ testError(network->conn, VIR_ERR_INTERNAL_ERROR,
+ _("network '%s' does not have a bridge name."),
+ privnet->def->name);
+ goto cleanup;
+ }
+
+ if (!(bridge = strdup(privnet->def->bridge))) {
virReportOOMError(network->conn);
goto cleanup;
}
--
1.6.5.rc2
15 years, 1 month
[libvirt] [PATCHv2 0/8] Python related fixes
by Cole Robinson
The following series fixes various issues related to the python bindings.
Cole Robinson (8):
configure: Add explict --with-python option.
python: Remove FastParser from generator.
python: Remove use of xmllib in generator.py
python: Don't generate conflicting conn.createXML functions.
python: Don't generate bindings for vir*Ref
python: Use a pure python implementation of 'vir*GetConnect'
python: Fix generated virInterface method names
python: Add a newline after custom classes
configure.in | 6 ++-
python/generator.py | 117 ++++++++++++++++++++++-----------------------------
2 files changed, 55 insertions(+), 68 deletions(-)
15 years, 1 month
[libvirt] A first look at the node device libudev backend
by Dave Allan
Hi all,
Here is a first cut at the node device backend. The only devices
implemented are part of storage and PCI devices, but it's conceptually
finished. The remaining work is implementing the other device
properties and types. Before I go do that, I'd like to get feedback on
my approach. Since libudev doesn't have the concept of capabilities the
way HAL does, Chris Lalancette and I thought it made more sense and
rendered much more readable code to implement each device type in a
single function and avoid the indirection created by the caps_tbl
structure containing a function pointer.
Monitoring of libudev for new devices is not implemented, but I'm not
too concerned about that at this point. As Dan Berrange suggested on
IRC, putting a call in the main loop to poll the monitor file descriptor
will do the job.
Dave
>From 34fa8bf6ce1b72276dc73f292ae12a9dd1ab2433 Mon Sep 17 00:00:00 2001
From: David Allan <dallan(a)redhat.com>
Date: Fri, 25 Sep 2009 10:59:28 -0400
Subject: [PATCH 1/1] A first look at the libudev node device backend.
Thanks to Jiri for the build system changes and to Chris Lalancette for his code and suggestions on how this backend should be implemented. Storage device properties are partly populated and PCI devices are discovered, but all other devices are as yet unimplemented.
---
configure.in | 47 ++-
daemon/libvirtd.c | 3 +-
src/Makefile.am | 16 +-
src/node_device/node_device_driver.c | 3 +
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 | 627 ++++++++++++++++++++
src/node_device/node_device_udev.h | 27 +
src/util/util.c | 46 ++
src/util/util.h | 4 +
11 files changed, 788 insertions(+), 26 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 cb5ce55..356abb7 100644
--- a/configure.in
+++ b/configure.in
@@ -1560,7 +1560,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=
@@ -1654,8 +1654,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])
@@ -1815,6 +1853,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 2bae782..c60a09f 100644
--- a/daemon/libvirtd.c
+++ b/daemon/libvirtd.c
@@ -832,8 +832,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/src/Makefile.am b/src/Makefile.am
index 9cbec47..b4328d6 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -237,16 +237,20 @@ SECURITY_DRIVER_SELINUX_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
+
#########################
#
@@ -626,6 +630,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
@@ -667,6 +676,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) \
$(SECRET_DRIVER_SOURCES) \
$(VBOX_DRIVER_EXTRA_DIST)
diff --git a/src/node_device/node_device_driver.c b/src/node_device/node_device_driver.c
index 93ca28c..3d06ed1 100644
--- a/src/node_device/node_device_driver.c
+++ b/src/node_device/node_device_driver.c
@@ -760,5 +760,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..22669ff
--- /dev/null
+++ b/src/node_device/node_device_udev.c
@@ -0,0 +1,627 @@
+/*
+ * 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 <regex.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 "uuid.h"
+#include "logging.h"
+#include "memory.h"
+#include "util.h"
+
+#define VIR_FROM_THIS VIR_FROM_NODEDEV
+
+static virDeviceMonitorStatePtr driverState = NULL;
+
+static struct udev *udevGetUdev(void)
+{
+ return udev_monitor_get_udev(DRV_STATE_UDEV_MONITOR(driverState));
+}
+
+
+static int udevGetSysfsData(char **data, const char *path)
+{
+ char *tmp = NULL;
+ FILE *fp = NULL;
+ int ret = -1;
+
+ if (VIR_ALLOC_N(tmp, SYSFS_DATA_SIZE) != 0) {
+ goto out;
+ }
+
+ memset(tmp, 0, SYSFS_DATA_SIZE);
+
+ fp = fopen(path, "r");
+ if (fp == NULL) {
+ goto out;
+ }
+
+ if (fread(tmp, SYSFS_DATA_SIZE, 1, fp) == SYSFS_DATA_SIZE) {
+ goto out;
+ }
+
+ /* strip off the trailing \n */
+ tmp[strlen(tmp) - 1] = '\0';
+
+ /* return a block of memory containing only what was read;
+ * otherwise we will consume vast amounts of largely unused memory
+ * on systems with large numbers of devices. */
+ *data = strdup(tmp);
+ if (*data == NULL) {
+ goto out;
+ }
+
+ ret = 0;
+
+out:
+ VIR_FREE(tmp);
+ fclose(fp);
+
+ return ret;
+}
+
+
+static int udevGetPCI(unsigned int *data,
+ const char *devpath,
+ const char *field)
+{
+ const char *syspath = NULL;
+ char *path = NULL, *tmp = NULL;
+ char *dummy;
+ int ret = 0;
+
+ syspath = udev_get_sys_path(udevGetUdev());
+
+ if (virBuildPath(&path, syspath, devpath, field) != 0) {
+ goto out;
+ }
+
+ if (udevGetSysfsData(&tmp, path) == 0) {
+ ret = virStrToLong_ui(tmp, &dummy, 16, data);
+ }
+
+out:
+ VIR_FREE(path);
+ return ret;
+}
+
+
+static int udevGetDMIData(char **data,
+ const char *field)
+{
+ const char *syspath = NULL;
+ char *path = NULL;
+ int ret = -1;
+
+ syspath = udev_get_sys_path(udevGetUdev());
+
+ if (virBuildPath(&path, syspath, "class/dmi/id", field) == 0) {
+ ret = udevGetSysfsData(data, path);
+ VIR_FREE(path);
+ }
+
+ return ret;
+}
+
+
+/* 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 = -1;
+
+ udev_value = udev_device_get_property_value(udev_device, property_key);
+ if (udev_value == NULL) {
+ VIR_ERROR(_("udev reports property '%s' does not exist"),
+ property_key);
+ 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));
+ goto out;
+ }
+
+ ret = 0;
+
+out:
+ if (ret != 0) {
+ VIR_ERROR(_("Failed to get udev property '%s' for device '%s'"),
+ property_key, udev_device_get_sysname(udev_device));
+ }
+
+ 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)
+{
+ char *udev_value = NULL;
+ int ret = 0;
+
+ ret = udevGetDeviceProperty(udev_device, property_key, &udev_value);
+
+ if (ret == 0) {
+ ret = virStrToLong_i(udev_value, NULL, 0, value);
+ }
+
+ return ret;
+}
+
+
+static int udevGetUint64Property(struct udev_device *udev_device,
+ const char *property_key,
+ uint64_t *value)
+{
+ char *udev_value = NULL;
+ int ret = 0;
+
+ ret = udevGetDeviceProperty(udev_device, property_key, &udev_value);
+
+ if (ret == 0) {
+ ret = virStrToLong_ull(udev_value, NULL, 0, value);
+ }
+
+ 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 void virUdevGetDeviceProperties(struct udev *udev, const char *name)
+{
+ struct udev_device *device = NULL;
+ struct udev_list_entry *list_entry = NULL;
+
+ device = udev_device_new_from_syspath(udev, name);
+
+ udev_list_entry_foreach(list_entry,
+ udev_device_get_properties_list_entry(device)) {
+
+ VIR_ERROR(" name: '%s' value: '%s'\n",
+ udev_list_entry_get_name(list_entry),
+ udev_list_entry_get_value(list_entry));
+ }
+
+ udev_device_unref(device);
+
+ return;
+}
+
+
+static int udevProcessPCI(struct udev_device *device,
+ virNodeDeviceDefPtr def)
+{
+ const char *devpath = NULL, *syspath = NULL;
+ int ret = -1;
+
+ devpath = udev_device_get_devpath(device);
+ syspath = udev_device_get_syspath(device);
+
+ if (VIR_ALLOC(def->caps) != 0) {
+ goto out;
+ }
+
+ def->caps->type = VIR_NODE_DEV_CAP_PCI_DEV;
+
+ char *p = strrchr(devpath, '/');
+ if (p) {
+ virStrToLong_ui(p+1, &p, 16, &def->caps->data.pci_dev.domain);
+ virStrToLong_ui(p+1, &p, 16, &def->caps->data.pci_dev.bus);
+ virStrToLong_ui(p+1, &p, 16, &def->caps->data.pci_dev.slot);
+ virStrToLong_ui(p+1, &p, 16, &def->caps->data.pci_dev.function);
+ }
+
+ if (udevGetPCI(&def->caps->data.pci_dev.vendor, devpath, "vendor") ||
+ udevGetPCI(&def->caps->data.pci_dev.product, devpath, "device")) {
+ 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 udevProcessStorage(struct udev_device *device,
+ virNodeDeviceDefPtr def)
+{
+ const char *devpath = NULL;
+ struct udev_list_entry *list_entry = NULL;
+ int ret = -1;
+
+ devpath = udev_device_get_devpath(device);
+
+ /* Can we get libudev to add device subtypes? */
+ if (STRPREFIX(devpath, "/devices/virtual/block")) {
+ goto out;
+ }
+
+ if (VIR_ALLOC(def->caps) != 0) {
+ goto out;
+ }
+
+ def->caps->type = VIR_NODE_DEV_CAP_STORAGE;
+
+ def->caps->data.storage.block = strdup(udev_device_get_devnode(device));
+ /* Can we get libudev to add subtypes? */
+ def->caps->data.storage.drive_type = strdup("disk");
+
+ udev_list_entry_foreach(list_entry, udev_device_get_devlinks_list_entry(device)) {
+ if (STREQ(udev_list_entry_get_name(list_entry), "/dev/cdrom")) {
+ VIR_FREE(def->caps->data.storage.drive_type);
+ def->caps->data.storage.drive_type = strdup("cdrom");
+ }
+ }
+
+ /* These lines are somewhat more than 80 col, but I think the code
+ * is more readable if they aren't broken up. */
+ if (udevGetStringProperty(device, "DEVNAME", &def->caps->data.storage.block)) {
+ /* None of these properties are available through libudev...
+ udevGetStringProperty(device, "ID_MODEL", &def->caps->data.storage.model) ||
+ udevGetStringProperty(device, "ID_VENDOR", &def->caps->data.storage.vendor) ||
+ udevGetStringProperty(device, "ID_SERIAL", &def->caps->data.storage.serial)) {
+ */
+ goto out;
+ }
+ ret = 0;
+
+out:
+ return ret;
+}
+
+
+static int udevProcessOneDevice(struct udev_device *device,
+ virNodeDeviceDefPtr def)
+{
+ virNodeDeviceObjPtr dev = NULL;
+ const char *devtype = NULL, *devpath = NULL;
+ regex_t pci_rec;
+ int ret = -1;
+
+ /* How to handle parent devices? Shall we change the meaning of
+ * the parent pointer for the udev backend? What does client code
+ * use the parent relationship for? We really want to preserve
+ * the behavior of the HAL backend, but that may be difficult in
+ * practice. */
+ //parent = udev_device_get_parent(device);
+
+ devtype = udev_device_get_devtype(device);
+ devpath = udev_device_get_devpath(device);
+
+ regcomp(&pci_rec,
+ "^/devices/pci[0-9]{4}:[0-9]{2}/[0-9]{4}:[0-9]{2}:[0-9]{2}.[0-9]$",
+ REG_EXTENDED | REG_NOSUB);
+
+ if (devtype != NULL && STREQ(devtype, "disk")) {
+ ret = udevProcessStorage(device, def);
+ } else if (regexec(&pci_rec, devpath, 0, NULL, 0) == 0) {
+ /* This is puzzling...why isn't there a devtype for pci in libudev? */
+ ret = udevProcessPCI(device, def);
+ }
+
+ if (ret == 0) {
+ dev = virNodeDeviceAssignDef(NULL, &driverState->devs, def);
+ virNodeDeviceObjUnlock(dev);
+ }
+
+ return ret;
+}
+
+
+static int udevProcessDeviceListEntry(struct udev *udev,
+ struct udev_list_entry *list_entry)
+{
+ struct udev_device *device;
+ virNodeDeviceDefPtr def = NULL;
+ const char *name = NULL;
+ int ret = -1;
+
+ name = udev_list_entry_get_name(list_entry);
+
+ if (VIR_ALLOC(def) != 0) {
+ goto out;
+ }
+
+ def->name = strdup(name);
+ if (def->name == NULL) {
+ goto out;
+ }
+
+ device = udev_device_new_from_syspath(udev, name);
+ if (device != NULL) {
+ udevProcessOneDevice(device, def);
+ udev_device_unref(device);
+ ret = 0;
+ }
+
+out:
+ 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);
+ virUdevGetDeviceProperties(udev, name);
+ }
+
+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 int udevSetupSystemDev(void)
+{
+ virNodeDeviceDefPtr def = NULL;
+ virNodeDeviceObjPtr dev = NULL;
+ char *tmp = NULL;
+ int ret = -1;
+
+ if (VIR_ALLOC(def) != 0) {
+ goto out;
+ }
+
+ def->name = strdup("system");
+ if (def->name == NULL) {
+ goto out;
+ }
+
+ if (VIR_ALLOC(def->caps) != 0) {
+ goto out;
+ }
+
+ /* These lines are somewhat more than 80 col, but I think the code
+ * is more readable if they aren't broken up. */
+ if (udevGetDMIData(&def->caps->data.system.product_name, "product_name") ||
+ udevGetDMIData(&def->caps->data.system.hardware.vendor_name, "sys_vendor") ||
+ udevGetDMIData(&def->caps->data.system.hardware.version, "product_version") ||
+ udevGetDMIData(&def->caps->data.system.hardware.serial, "product_serial")) {
+ goto out;
+ }
+
+ udevGetDMIData(&tmp, "product_uuid");
+ virUUIDParse(tmp, def->caps->data.system.hardware.uuid);
+ VIR_FREE(tmp);
+
+ if (udevGetDMIData(&def->caps->data.system.firmware.vendor_name, "bios_vendor") ||
+ udevGetDMIData(&def->caps->data.system.firmware.version, "bios_version") ||
+ udevGetDMIData(&def->caps->data.system.firmware.release_date, "bios_date")) {
+ goto out;
+ }
+
+ 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 can be retrieved from udev_monitor */
+ driverState->privateData = udev_monitor;
+ nodeDeviceUnlock(driverState);
+
+ /* Populate with known devices */
+
+ if (udevSetupSystemDev() != 0) {
+ ret = -1;
+ goto out;
+ }
+
+ 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..bac628d
--- /dev/null
+++ b/src/node_device/node_device_udev.h
@@ -0,0 +1,27 @@
+/*
+ * 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))
diff --git a/src/util/util.c b/src/util/util.c
index ef07a6a..a1fe0d5 100644
--- a/src/util/util.c
+++ b/src/util/util.c
@@ -2088,3 +2088,49 @@ void virFileWaitForDevices(virConnectPtr conn)
void virFileWaitForDevices(virConnectPtr conn ATTRIBUTE_UNUSED) {}
#endif
#endif
+
+/* Don't call this function directly, call virBuildPath instead. */
+int virBuildPathInternal(char **path, ...)
+{
+ char *path_component = NULL;
+ va_list ap;
+ size_t used = 0;
+ int ret = 0;
+
+ if (VIR_ALLOC_N(*path, PATH_MAX) != 0) {
+ ret = -1;
+ goto out;
+ }
+
+ va_start(ap, *path);
+
+ while ((path_component = va_arg(ap, char *)) != NULL)
+ {
+ used += snprintf(*path + used, PATH_MAX - used, "%s/", path_component);
+
+ /* From the snprintf man page:
+
+ The functions snprintf() and vsnprintf() do not write more
+ than size bytes (including the trailing '\0'). If the
+ output was truncated due to this limit then the return
+ value is the number of characters (not including the
+ trailing '\0') which would have been written to the final
+ string if enough space had been available. Thus, a return
+ value of size or more means that the output was truncated.
+
+ We therefore set used to the size of the buffer to avoid
+ the size being passed to snprintf from becoming negative.
+ */
+
+ if (used > PATH_MAX) {
+ used = PATH_MAX;
+ }
+ }
+
+ va_end(ap);
+
+ *(*path + used - 1) = '\0'; /* kill trailing slash */
+
+out:
+ return ret;
+}
diff --git a/src/util/util.h b/src/util/util.h
index dbfdc45..aa466af 100644
--- a/src/util/util.h
+++ b/src/util/util.h
@@ -244,4 +244,8 @@ char *virFileFindMountPoint(const char *type);
void virFileWaitForDevices(virConnectPtr conn);
+#define virBuildPath(path, ...) virBuildPathInternal(path, __VA_ARGS__, NULL)
+/* Don't call virBuildPathInternal directly, use virBuildPath */
+int virBuildPathInternal(char **path, ...);
+
#endif /* __VIR_UTIL_H__ */
--
1.6.4.4
15 years, 1 month
[libvirt] cann't connect kvm hypervisor
by Liu, Zhentao
Hello,
I'm new of Opennebula. I have installed KVM im my remote node. But when I
want to check the KVM in the node, I can't connect to the hypervisor.
--------------------------------------------------------------------
root@forest:/var/run/libvirt# virsh -c qemu:///localhost/system list
Connecting to uri: qemu:///system
error: failed to connect to the hypervisor
--------------------------------------------------------------------
Can somebody tell me why virsh doesn't work? And how I can fix it?
I think that it's maybe the problem of libvirt.
Any helps would be very appreciated?
Thanks
Zhentao
-----Original Message-----
From: tinova79(a)gmail.com on behalf of Tino Vazquez
Sent: Mon 10/5/2009 4:33 PM
To: Shi Jin
Cc: Liu, Zhentao; users(a)lists.opennebula.org
Subject: Re: [one-users] cann't connect kvm hypervisor
Hi there,
I would suggest forwarding this question to the libvirt mailing list,
other people there may know the best procedure to deal with this.
Regards,
-Tino
--
Constantino Vázquez, Grid Technology Engineer/Researcher:
http://www.dsa-research.org/tinova
DSA Research Group: http://dsa-research.org
Globus GridWay Metascheduler: http://www.GridWay.org
OpenNebula Virtual Infrastructure Engine: http://www.OpenNebula.org
On Mon, Oct 5, 2009 at 4:30 PM, Shi Jin <jinzishuai(a)gmail.com> wrote:
> I had similar problems earlier.
> The only solution I found without rebooting the machine is to killall
> kvm on the node.
> I would also appreciate any suggestion to better handle this problem.
> Thanks.
>
> Shi
>
> On Mon, Oct 5, 2009 at 5:56 AM, Liu, Zhentao
> <Zhentao.Liu(a)fokus.fraunhofer.de> wrote:
>> Hi Tino
>>
>> I have checked that libvirtd deaemon is running. I have also restarted
>> libvirtd deaemon, but I can't still connect to kvm hypervisor.
>> -----------------------------------------------------------
>> root@forest:/var/run/libvirt# /etc/init.d/libvirt-bin start
>> * Starting libvirt management daemon libvirtd [
>> OK ]
>> root@forest:/var/run/libvirt# virsh -c qemu:///system list
>>
>> Connecting to uri: qemu:///system
>> error: failed to connect to the hypervisor
>> -------------------------------------------------------------
>>
>> other ideas?
>>
>> Thanks
>>
>> Zhentao
>>
>> -----Original Message-----
>> From: tinova79(a)gmail.com on behalf of Tino Vazquez
>> Sent: Mon 10/5/2009 1:43 PM
>> To: Liu, Zhentao
>> Cc: users(a)lists.opennebula.org
>> Subject: Re: [one-users] cann't connect kvm hypervisor
>>
>> Hi Zhentao,
>>
>> Can you check that the libvirtd deaemon is running in the remote node?
>>
>> Regards,
>>
>> -Tino
>>
>> --
>> Constantino Vázquez, Grid Technology Engineer/Researcher:
>> http://www.dsa-research.org/tinova
>> DSA Research Group: http://dsa-research.org
>> Globus GridWay Metascheduler: http://www.GridWay.org
>> OpenNebula Virtual Infrastructure Engine: http://www.OpenNebula.org
>>
>>
>>
>> On Mon, Oct 5, 2009 at 1:30 PM, Liu, Zhentao
>> <Zhentao.Liu(a)fokus.fraunhofer.de> wrote:
>>> Hello,
>>>
>>> I'm new of Opennebula. I have installed KVM im my remote node. But when I
>>> want to check the KVM in the node, I can't connect to the hypervisor.
>>>
>>> --------------------------------------------------------------------
>>> root@forest:/var/run/libvirt# virsh -c qemu:///localhost/system list
>>> Connecting to uri: qemu:///system
>>> error: failed to connect to the hypervisor
>>> --------------------------------------------------------------------
>>>
>>> Can somebody tell me why virsh doesn't work? And how I can fix it?
>>>
>>> Any helps would be very appreciated?
>>>
>>> Thanks
>>>
>>> Zhentao
>>>
>>> _______________________________________________
>>> Users mailing list
>>> Users(a)lists.opennebula.org
>>> http://lists.opennebula.org/listinfo.cgi/users-opennebula.org
>>>
>>>
>>
>>
>> _______________________________________________
>> Users mailing list
>> Users(a)lists.opennebula.org
>> http://lists.opennebula.org/listinfo.cgi/users-opennebula.org
>>
>>
>
>
>
> --
> Shi Jin, Ph.D.
>
15 years, 1 month
Re: [libvirt] Creating Guest OS in Virtual Box
by Pritesh Kothari
> >>
> >> <os>
> >> <type>hvm</type>
> >> <boot dev='hd'/>
> >> </os>
> >>
> >> <memory>542720</memory>
> >> <vcpu>1</vcpu>
> >>
> >> <devices>
> >> <disk type='file' device='disk'>
> >> <source file='/home/santhosh/Desktop/ubuntu9.vdi'/>
> >> <target dev='hdd'/>
ok the actual error is not in the code and the patch failed cause you are
using the git HEAD which already has it.
The error actually is that you forgot to specify the target type, i.e the
target tag should be:
<target dev='hdd' bus='ide'/>
and not the one which you specified. the documents on the libvirt.org are
pretty much old i guess and someone should update them someday ;).
Regards,
Pritesh
15 years, 1 month
[libvirt] getting notified of events
by Dan Kenigsberg
I am trying to understand how to use the virEvent* API.
I've built latest libvirt (with "Fix emission of domain events messages"
commit) and run the domain-events example.
events-c gives me mostly silence. nothing is printed when a domain
changes state.
events-python is more bizarre: it prints a line on every event - except
for the first one, where "Updating Timeout 0 0
Poll sleep 1" is printed. Only when the second event occurs, does the
callback for the first event gets executed.
What am I missing?
Could someone more familiar take a look?
Regards,
Dan.
15 years, 1 month
[libvirt] Safe? /etc/libvirt/qemu on shared storage?
by James Brackinshaw
Hello,
I have a directory /mnt/shared-storage where the disk files for kvm
live. Live migration works well, but I have a problem: after a
migration I see two guests, one on the original host "shutoff" and one
on the new host "running".
I'd like to see the guest only on the host it is running on.
Would it be safe/recommended to put the /etc/libvirt/qemu directory on
shared storage? What would the best way of doing this be?
Is this lock safe?
Thanks
JB
15 years, 1 month