[libvirt] PATCH: Another attempt to fix vbox driver open
by Daniel P. Berrange
The patches we just applied for the VirtualBox open method still were
not quite right. It would return VIR_DRV_OPEN_DECLINED when uri==NULL,
but before doing so it would have set conn->uri to vbox:///session. So
even though it declined the connection, all the later drivers would now
ignore it. Also, it now returns DECLINED for some real errors that
should be reported to the user.
Here's an alternative idea I've had for trying to address this. Some
goals:
- If the user gives a URI with a vbox:/// prefix, we should always
handle it, unless a 'server' is set when we leave it to the remote
driver
- If an invalid path is given we must give back a real error code
- If after deciding the URI is for us, any initialization fails
we must raise an error.
- If the vbox glue layer is missing, we should still raise errors
for requested URIs, so user knows their URI is correct.
To do this, I've taken the approach of registering a dummy vbox driver
if the glue layer is missing. This just parses the URI and always returns
an error for any vbox:// URIs that would otherwise work
Daniel
Index: src/vbox/vbox_driver.c
===================================================================
RCS file: /data/cvs/libvirt/src/vbox/vbox_driver.c,v
retrieving revision 1.2
diff -u -p -r1.2 vbox_driver.c
--- src/vbox/vbox_driver.c 6 May 2009 13:51:19 -0000 1.2
+++ src/vbox/vbox_driver.c 8 May 2009 16:35:57 -0000
@@ -34,6 +34,7 @@
#include "logging.h"
#include "vbox_driver.h"
#include "vbox_XPCOMCGlue.h"
+#include "virterror_internal.h"
#define VIR_FROM_THIS VIR_FROM_VBOX
@@ -43,15 +44,25 @@ extern virDriver vbox22Driver;
extern virDriver vbox25Driver;
#endif
+static virDriver vboxDriverDummy;
+
+#define VIR_FROM_THIS VIR_FROM_VBOX
+
+#define vboxError(conn, code, fmt...) \
+ virReportErrorHelper(conn, VIR_FROM_VBOX, code, __FILE__, \
+ __FUNCTION__, __LINE__, fmt)
int vboxRegister(void) {
virDriverPtr driver;
uint32_t uVersion;
- /* vboxRegister() shouldn't fail as that will render libvirt unless.
- * So, we use the v2.2 driver as a fallback/dummy.
+ /*
+ * If the glue layer won' initialize, we register a driver
+ * with a dummy open method, so we can report nicer errors
+ * if the user requests a vbox:// URI which we know won't
+ * ever work
*/
- driver = &vbox22Driver;
+ driver = &vboxDriverDummy;
/* Init the glue and get the API version. */
if (VBoxCGlueInit() == 0) {
@@ -79,7 +90,7 @@ int vboxRegister(void) {
}
} else {
- DEBUG0("VBoxCGlueInit failed");
+ DEBUG0("VBoxCGlueInit failed, using dummy driver");
}
if (virRegisterDriver(driver) < 0)
@@ -87,3 +98,46 @@ int vboxRegister(void) {
return 0;
}
+
+static virDrvOpenStatus vboxOpenDummy(virConnectPtr conn,
+ virConnectAuthPtr auth ATTRIBUTE_UNUSED,
+ int flags ATTRIBUTE_UNUSED) {
+ uid_t uid = getuid();
+
+ if (conn->uri == NULL ||
+ conn->uri->scheme == NULL ||
+ STRNEQ (conn->uri->scheme, "vbox") ||
+ conn->uri->server != NULL)
+ return VIR_DRV_OPEN_DECLINED;
+
+ if (conn->uri->path == NULL || STREQ(conn->uri->path, "")) {
+ vboxError(conn, VIR_ERR_INTERNAL_ERROR, "%s",
+ _("no VirtualBox drviver path specified (try vbox:///session)"));
+ return VIR_DRV_OPEN_ERROR;
+ }
+
+ if (uid != 0) {
+ if (STRNEQ (conn->uri->path, "/session")) {
+ vboxError(conn, VIR_ERR_INTERNAL_ERROR,
+ _("unknown driver path '%s' specified (try vbox:///session)"), conn->uri->path);
+ return VIR_DRV_OPEN_ERROR;
+ }
+ } else { /* root */
+ if (STRNEQ (conn->uri->path, "/system") &&
+ STRNEQ (conn->uri->path, "/session")) {
+ vboxError(conn, VIR_ERR_INTERNAL_ERROR,
+ _("unknown driver path '%s' specified (try vbox:///system)"), conn->uri->path);
+ return VIR_DRV_OPEN_ERROR;
+ }
+ }
+
+ vboxError(conn, VIR_ERR_INTERNAL_ERROR, "%s",
+ _("unable to initialize VirtualBox driver API"));
+ return VIR_DRV_OPEN_ERROR;
+}
+
+static virDriver vboxDriverDummy = {
+ VIR_DRV_VBOX,
+ "VBOX",
+ .open = vboxOpenDummy,
+};
Index: src/vbox/vbox_tmpl.c
===================================================================
RCS file: /data/cvs/libvirt/src/vbox/vbox_tmpl.c,v
retrieving revision 1.5
diff -u -p -r1.5 vbox_tmpl.c
--- src/vbox/vbox_tmpl.c 8 May 2009 10:18:26 -0000 1.5
+++ src/vbox/vbox_tmpl.c 8 May 2009 16:35:57 -0000
@@ -216,16 +216,6 @@ no_memory:
}
static int vboxInitialize(virConnectPtr conn, vboxGlobalData *data) {
-
- if (VBoxCGlueInit() != 0) {
- vboxError(conn, VIR_ERR_INTERNAL_ERROR, "Can't Initialize VirtualBox, VBoxCGlueInit failed.");
- goto cleanup;
- }
-
- /* This is for when glue init failed and we're serving as dummy driver. */
- if (g_pfnGetFunctions == NULL)
- goto cleanup;
-
/* Get the API table for out version, g_pVBoxFuncs is for the oldest
version of the API that we support so we cannot use that. */
data->pFuncs = g_pfnGetFunctions(VBOX_XPCOMC_VERSION);
@@ -291,13 +281,13 @@ static int vboxExtractVersion(virConnect
}
static void vboxUninitialize(vboxGlobalData *data) {
+ if (!data)
+ return;
+
if (data->pFuncs)
data->pFuncs->pfnComUninitialize();
VBoxCGlueTerm();
- if (!data)
- return;
-
virDomainObjListFree(&data->domains);
virCapabilitiesFree(data->caps);
VIR_FREE(data);
@@ -306,52 +296,62 @@ static void vboxUninitialize(vboxGlobalD
static virDrvOpenStatus vboxOpen(virConnectPtr conn,
virConnectAuthPtr auth ATTRIBUTE_UNUSED,
int flags ATTRIBUTE_UNUSED) {
- vboxGlobalData *data;
+ vboxGlobalData *data = NULL;
uid_t uid = getuid();
if (conn->uri == NULL) {
conn->uri = xmlParseURI(uid ? "vbox:///session" : "vbox:///system");
if (conn->uri == NULL) {
+ virReportOOMError(conn);
return VIR_DRV_OPEN_ERROR;
}
- } else if (conn->uri->scheme == NULL ||
- conn->uri->path == NULL ) {
- return VIR_DRV_OPEN_DECLINED;
}
- if (STRNEQ (conn->uri->scheme, "vbox"))
+ if (conn->uri->scheme == NULL ||
+ STRNEQ (conn->uri->scheme, "vbox"))
+ return VIR_DRV_OPEN_DECLINED;
+
+ /* Leave for remote driver */
+ if (conn->uri->server != NULL)
return VIR_DRV_OPEN_DECLINED;
+ if (conn->uri->path == NULL || STREQ(conn->uri->path, "")) {
+ vboxError(conn, VIR_ERR_INTERNAL_ERROR, "%s",
+ _("no VirtualBox drviver path specified (try vbox:///session)"));
+ return VIR_DRV_OPEN_ERROR;
+ }
+
if (uid != 0) {
- if (STRNEQ (conn->uri->path, "/session"))
- return VIR_DRV_OPEN_DECLINED;
+ if (STRNEQ (conn->uri->path, "/session")) {
+ vboxError(conn, VIR_ERR_INTERNAL_ERROR,
+ _("unknown driver path '%s' specified (try vbox:///session)"), conn->uri->path);
+ return VIR_DRV_OPEN_ERROR;
+ }
} else { /* root */
if (STRNEQ (conn->uri->path, "/system") &&
- STRNEQ (conn->uri->path, "/session"))
- return VIR_DRV_OPEN_DECLINED;
+ STRNEQ (conn->uri->path, "/session")) {
+ vboxError(conn, VIR_ERR_INTERNAL_ERROR,
+ _("unknown driver path '%s' specified (try vbox:///system)"), conn->uri->path);
+ return VIR_DRV_OPEN_ERROR;
+ }
}
if (VIR_ALLOC(data) < 0) {
virReportOOMError(conn);
- goto cleanup;
+ return VIR_DRV_OPEN_ERROR;
}
- if (!(data->caps = vboxCapsInit()))
- goto cleanup;
-
- if (vboxInitialize(conn, data) < 0)
- goto cleanup;
-
- if (vboxExtractVersion(conn, data) < 0)
- goto cleanup;
+ if (!(data->caps = vboxCapsInit()) ||
+ vboxInitialize(conn, data) < 0 ||
+ vboxExtractVersion(conn, data) < 0) {
+ vboxUninitialize(data);
+ return VIR_DRV_OPEN_ERROR;
+ }
conn->privateData = data;
DEBUG0("in vboxOpen");
return VIR_DRV_OPEN_SUCCESS;
-cleanup:
- vboxUninitialize(data);
- return VIR_DRV_OPEN_DECLINED;
}
static int vboxClose(virConnectPtr conn) {
--
|: Red Hat, Engineering, London -o- http://people.redhat.com/berrange/ :|
|: http://libvirt.org -o- http://virt-manager.org -o- http://ovirt.org :|
|: http://autobuild.org -o- http://search.cpan.org/~danberr/ :|
|: GnuPG: 7D3B9505 -o- F3C9 553F A1DA 4AC2 5648 23C1 B3DF F742 7D3B 9505 :|
15 years, 6 months
[libvirt] [PATCH] also enable bridges without IP address
by Ludwig Nussel
Bridges that are not up won't forward packets
Signed-off-by: Ludwig Nussel <ludwig.nussel(a)suse.de>
cu
Ludwig
---
src/network_driver.c | 9 +++------
1 files changed, 3 insertions(+), 6 deletions(-)
diff --git a/src/network_driver.c b/src/network_driver.c
index a17a769..a163b15 100644
--- a/src/network_driver.c
+++ b/src/network_driver.c
@@ -836,8 +836,7 @@ static int networkStartNetworkDaemon(virConnectPtr conn,
goto err_delbr;
}
- if (network->def->ipAddress &&
- (err = brSetInterfaceUp(driver->brctl, network->def->bridge, 1))) {
+ if ((err = brSetInterfaceUp(driver->brctl, network->def->bridge, 1))) {
virReportSystemError(conn, err,
_("failed to bring the bridge '%s' up"),
network->def->bridge);
@@ -878,8 +877,7 @@ static int networkStartNetworkDaemon(virConnectPtr conn,
networkRemoveIptablesRules(driver, network);
err_delbr1:
- if (network->def->ipAddress &&
- (err = brSetInterfaceUp(driver->brctl, network->def->bridge, 0))) {
+ if ((err = brSetInterfaceUp(driver->brctl, network->def->bridge, 0))) {
char ebuf[1024];
networkLog(NETWORK_WARN, _("Failed to bring down bridge '%s' : %s\n"),
network->def->bridge, virStrerror(err, ebuf, sizeof ebuf));
@@ -920,8 +918,7 @@ static int networkShutdownNetworkDaemon(virConnectPtr conn,
networkRemoveIptablesRules(driver, network);
char ebuf[1024];
- if (network->def->ipAddress &&
- (err = brSetInterfaceUp(driver->brctl, network->def->bridge, 0))) {
+ if ((err = brSetInterfaceUp(driver->brctl, network->def->bridge, 0))) {
networkLog(NETWORK_WARN, _("Failed to bring down bridge '%s' : %s\n"),
network->def->bridge, virStrerror(err, ebuf, sizeof ebuf));
}
--
1.6.2.1
15 years, 6 months
[libvirt] PATCH: ALlow for quiet build
by Daniel P. Berrange
This is a simpler version of
http://www.redhat.com/archives/libvir-list/2009-April/msg00523.html
just overriding the LIBTOOL variable in configure.in, instead of in each
Makefile.am
As before you still need 'make -s' to get full effect
Daniel
diff -r f94c0624da5c configure.in
--- a/configure.in Fri May 08 11:41:29 2009 +0100
+++ b/configure.in Mon May 11 16:46:08 2009 +0100
@@ -57,6 +57,9 @@ dnl Support building Win32 DLLs (must ap
AC_LIBTOOL_WIN32_DLL
AM_PROG_LIBTOOL
+dnl Override normal libtool in favour of our quiet version
+LIBTOOL='$(SHELL) $(top_srcdir)/mylibtool'
+AC_SUBST([LIBTOOL])
AM_PROG_CC_C_O
diff -r f94c0624da5c mylibtool
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/mylibtool Mon May 11 16:46:08 2009 +0100
@@ -0,0 +1,58 @@
+#!/bin/sh
+
+mode=libtool
+cfiles=""
+ofiles=""
+afiles=""
+
+wantnext=0
+for v in "$@"
+do
+ case $v
+ in
+ --mode=compile)
+ mode=CC
+ ;;
+ --mode=link)
+ mode=LD
+ ;;
+ esac
+
+ case $v
+ in
+ *.c)
+ cfiles="$cfiles $v"
+ ;;
+ *.o)
+ if [ "$mode" = "LD" -o "$wantnext" = "1" ]; then
+ ofiles="$ofiles $v"
+ fi
+ ;;
+ *.lo)
+ if [ "$mode" = "LD" -o "$wantnext" = "1" ]; then
+ ofiles="$ofiles $v"
+ fi
+ ;;
+ esac
+
+ if [ "$mode" = "LD" -a "$wantnext" = "1" ]; then
+ afiles="$afiles $v"
+ fi
+
+ if [ "$v" = "-o" ]; then
+ wantnext=1
+ else
+ wantnext=0
+ fi
+done
+
+args=""
+test -n "$afiles" && args="$args -o$afiles"
+test -n "$ofiles" -a "$mode" = "CC" && args="$args -o"
+test -n "$ofiles" && args="$args$ofiles"
+test -n "$cfiles" && args="$args$cfiles"
+
+echo "($mode)$args"
+
+here=`dirname $0`
+exec $here/libtool --silent "$@"
--
|: Red Hat, Engineering, London -o- http://people.redhat.com/berrange/ :|
|: http://libvirt.org -o- http://virt-manager.org -o- http://ovirt.org :|
|: http://autobuild.org -o- http://search.cpan.org/~danberr/ :|
|: GnuPG: 7D3B9505 -o- F3C9 553F A1DA 4AC2 5648 23C1 B3DF F742 7D3B 9505 :|
15 years, 6 months
[libvirt] Java binding
by Zvi Dubitzky
Who is the contact for libvirt Java binding ?
In a late mail I said that the Java binding crashes upon live migrate
when the dname=null .
It does not crash if dname = source domain name even though works slow.
The C code of libvirt / libvirt.c /virDomainMigrate () says in its header
that :
"If a hypervisor supports renaming domains during migration,
* then you may set the dname parameter to the new name (otherwise
* it keeps the same name). If this is not supported by the
* hypervisor, dname must be NULL or else you will get an error."
So in the kvm case dname = NULL works for the C binding but not for the
JAVA binding as it should .
Any idea ?
thanks
Zvi Dubitzky
Virtualization and System Architecture Email:dubi@il.ibm.com
IBM Haifa Research Laboratory Phone: +972-4-8296182
Haifa, 31905, ISRAEL
15 years, 6 months
[libvirt] PATCH: 0/4: Fix the event loop (again) no really, this time its fixed.
by Daniel P. Berrange
Back in March I attempted to fix the event loop handling of deleted file
handles
http://www.redhat.com/archives/libvir-list/2009-March/msg00246.html
but have merely succeeded in screwing it up in a different fun & exciting
way. That patch fixed a case where there was a deleted file handle in the
list at the time virEventRunOnce() starts. Which was nice. Not nice, though
was that it then breaks the case where a file handle is deleted during the
course of dispatching events afer poll(). Investigating this also identified
that when we were marking a file handle as deleted, we were forgetting to
run virEventInterrupt(), which meant that in some cases the main thread
would not be woken up until the next event triggers. Not very critical,
but at the same time, not good because it delays cleanup & release of
resources.
This series of patches fixes the problems, and more importantly, adds a
unit test which cover these nasty edge cases.
Daniel
--
|: Red Hat, Engineering, London -o- http://people.redhat.com/berrange/ :|
|: http://libvirt.org -o- http://virt-manager.org -o- http://ovirt.org :|
|: http://autobuild.org -o- http://search.cpan.org/~danberr/ :|
|: GnuPG: 7D3B9505 -o- F3C9 553F A1DA 4AC2 5648 23C1 B3DF F742 7D3B 9505 :|
15 years, 6 months
[libvirt] QEMU/KVM auto-detection bug
by Chris Lalancette
All,
Even with Guido/Pritesh's recent changes to the vbox open routine, the
auto-detection in libvirt is currently broken. What happens is that in
src/libvirt.c:do_open(), at the start of the loop to auto-detect drivers,
ret->uri is NULL. As each driver declines, it remains NULL. However, the very
first thing the vboxOpen() routine does is:
if (conn->uri == NULL) {
conn->uri = xmlParseURI(uid ? "vbox:///session" : "vbox:///system");
if (conn->uri == NULL) {
return VIR_DRV_OPEN_ERROR;
}
So, any driver that is trying to auto-probe after vboxOpen sees a conn->uri with
a scheme of vbox and a path of system/session, and they all fail (including
Qemu, which is what I'm mostly concerned with at the moment).
In point of fact, this whole auto-detection thing is fragile. We got away with
it before because the qemuOpen() routine bombs out before doing the whole
conn->uri == NULL check, but in general, it's very easy for one buggy driver to
mess up auto-detection for all drivers.
Any thoughts about where to go here? We should obviously fix the vboxOpen()
routine to not mess with the URI if it's going to fail. Additionally, I was
thinking that maybe we should reset conn->uri to NULL in each iteration of the
auto-detection loop. While that might leak memory for buggy drivers, it should
at least make this whole thing less fragile.
Thoughts?
--
Chris Lalancette
15 years, 6 months
[libvirt] [PATCH 1/6] Allow multiple monitor devices (v2)
by Anthony Liguori
Right now only one monitor device can be enabled at a time. In order to support
asynchronous notification of events, I would like to introduce a 'wait' command
that waits for an event to occur. This implies that we need an additional
monitor session to allow commands to still be executed while waiting for an
asynchronous notification.
Signed-off-by: Anthony Liguori <aliguori(a)us.ibm.com>
diff --git a/vl.c b/vl.c
index 4bd173f..f78cabb 100644
--- a/vl.c
+++ b/vl.c
@@ -184,6 +184,9 @@ int main(int argc, char **argv)
/* Max number of bluetooth switches on the commandline. */
#define MAX_BT_CMDLINE 10
+/* Maximum number of monitor devices */
+#define MAX_MONITOR_DEVICES 10
+
/* XXX: use a two level table to limit memory usage */
#define MAX_IOPORTS 65536
@@ -4252,8 +4255,9 @@ int main(int argc, char **argv, char **envp)
int hda_index;
int optind;
const char *r, *optarg;
- CharDriverState *monitor_hd = NULL;
- const char *monitor_device;
+ CharDriverState *monitor_hds[MAX_MONITOR_DEVICES];
+ const char *monitor_devices[MAX_MONITOR_DEVICES];
+ int monitor_device_index;
const char *serial_devices[MAX_SERIAL_PORTS];
int serial_device_index;
const char *parallel_devices[MAX_PARALLEL_PORTS];
@@ -4324,7 +4328,6 @@ int main(int argc, char **argv, char **envp)
kernel_cmdline = "";
cyls = heads = secs = 0;
translation = BIOS_ATA_TRANSLATION_AUTO;
- monitor_device = "vc:80Cx24C";
serial_devices[0] = "vc:80Cx24C";
for(i = 1; i < MAX_SERIAL_PORTS; i++)
@@ -4340,6 +4343,11 @@ int main(int argc, char **argv, char **envp)
virtio_consoles[i] = NULL;
virtio_console_index = 0;
+ monitor_devices[0] = "vc:80Cx24C";
+ for (i = 1; i < MAX_MONITOR_DEVICES; i++)
+ monitor_devices[i] = NULL;
+ monitor_device_index = 0;
+
usb_devices_index = 0;
nb_net_clients = 0;
@@ -4723,7 +4731,12 @@ int main(int argc, char **argv, char **envp)
break;
}
case QEMU_OPTION_monitor:
- monitor_device = optarg;
+ if (monitor_device_index >= MAX_MONITOR_DEVICES) {
+ fprintf(stderr, "qemu: too many monitor devices\n");
+ exit(1);
+ }
+ monitor_devices[monitor_device_index] = optarg;
+ monitor_device_index++;
break;
case QEMU_OPTION_serial:
if (serial_device_index >= MAX_SERIAL_PORTS) {
@@ -4974,8 +4987,8 @@ int main(int argc, char **argv, char **envp)
serial_devices[0] = "stdio";
if (parallel_device_index == 0)
parallel_devices[0] = "null";
- if (strncmp(monitor_device, "vc", 2) == 0)
- monitor_device = "stdio";
+ if (strncmp(monitor_devices[0], "vc", 2) == 0)
+ monitor_devices[0] = "stdio";
}
#ifndef _WIN32
@@ -5184,14 +5197,14 @@ int main(int argc, char **argv, char **envp)
#endif
/* Maintain compatibility with multiple stdio monitors */
- if (!strcmp(monitor_device,"stdio")) {
+ if (!strcmp(monitor_devices[0],"stdio")) {
for (i = 0; i < MAX_SERIAL_PORTS; i++) {
const char *devname = serial_devices[i];
if (devname && !strcmp(devname,"mon:stdio")) {
- monitor_device = NULL;
+ monitor_devices[0] = NULL;
break;
} else if (devname && !strcmp(devname,"stdio")) {
- monitor_device = NULL;
+ monitor_devices[0] = NULL;
serial_devices[i] = "mon:stdio";
break;
}
@@ -5208,11 +5221,20 @@ int main(int argc, char **argv, char **envp)
}
}
- if (monitor_device) {
- monitor_hd = qemu_chr_open("monitor", monitor_device, NULL);
- if (!monitor_hd) {
- fprintf(stderr, "qemu: could not open monitor device '%s'\n", monitor_device);
- exit(1);
+ for (i = 0; i < MAX_MONITOR_DEVICES; i++) {
+ const char *devname = monitor_devices[i];
+ if (devname && strcmp(devname, "none")) {
+ char label[32];
+ if (i == 0)
+ snprintf(label, sizeof(label), "monitor");
+ else
+ snprintf(label, sizeof(label), "monitor%d", i);
+ monitor_hds[i] = qemu_chr_open(label, devname, NULL);
+ if (!monitor_hds[i]) {
+ fprintf(stderr, "qemu: could not open monitor device '%s'\n",
+ devname);
+ exit(1);
+ }
}
}
@@ -5335,8 +5357,13 @@ int main(int argc, char **argv, char **envp)
text_consoles_set_display(display_state);
qemu_chr_initial_reset();
- if (monitor_device && monitor_hd)
- monitor_init(monitor_hd, MONITOR_USE_READLINE | MONITOR_IS_DEFAULT);
+ for (i = 0; i < MAX_MONITOR_DEVICES; i++) {
+ if (monitor_devices[i] && monitor_hds[i]) {
+ monitor_init(monitor_hds[i],
+ MONITOR_USE_READLINE |
+ ((i == 0) ? MONITOR_IS_DEFAULT : 0));
+ }
+ }
for(i = 0; i < MAX_SERIAL_PORTS; i++) {
const char *devname = serial_devices[i];
15 years, 6 months
[libvirt] PATCH: Fix QEMU arg detection for kvm >= 85
by Daniel P. Berrange
The -help output from KVM >= 85 is now large than we expected. This patch
increases the buffer from 8k to 64k when reading help. It also provides
more detailed error messages should something go wrong in the future.
Two examples of improved error reporting
# virsh -c qemu:///system start VirtTest
error: Failed to start domain VirtTest
error: Unable to read QEMU help output: Value too large for defined data type
# virsh -c qemu:///system start VirtTest
error: Failed to start domain VirtTest
error: internal error cannot parse QEMU version number in 'QEMU PC emulator version 0.9.1 (kvm-79), Copyright (c) 2003-2008 Fabrice Bellard'
Daniel
Index: src/qemu_conf.c
===================================================================
RCS file: /data/cvs/libvirt/src/qemu_conf.c,v
retrieving revision 1.145
diff -u -p -r1.145 qemu_conf.c
--- src/qemu_conf.c 8 May 2009 10:07:16 -0000 1.145
+++ src/qemu_conf.c 8 May 2009 10:37:22 -0000
@@ -431,18 +431,28 @@ int qemudExtractVersionInfo(const char *
return -1;
char *help = NULL;
- enum { MAX_HELP_OUTPUT_SIZE = 8192 };
+ enum { MAX_HELP_OUTPUT_SIZE = 1024*64 };
int len = virFileReadLimFD(newstdout, MAX_HELP_OUTPUT_SIZE, &help);
- if (len < 0)
+ if (len < 0) {
+ virReportSystemError(NULL, errno, "%s",
+ _("Unable to read QEMU help output"));
goto cleanup2;
+ }
if (sscanf(help, "QEMU PC emulator version %u.%u.%u (kvm-%u)",
&major, &minor, µ, &kvm_version) != 4)
kvm_version = 0;
- if (!kvm_version && sscanf(help, "QEMU PC emulator version %u.%u.%u",
- &major, &minor, µ) != 3)
+ if (!kvm_version &&
+ sscanf(help, "QEMU PC emulator version %u.%u.%u",
+ &major, &minor, µ) != 3) {
+ char *eol = strchr(help, '\n');
+ if (eol) *eol = '\0';
+ qemudReportError(NULL, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
+ _("cannot parse QEMU version number in '%s'"),
+ help);
goto cleanup2;
+ }
version = (major * 1000 * 1000) + (minor * 1000) + micro;
Index: src/qemu_driver.c
===================================================================
RCS file: /data/cvs/libvirt/src/qemu_driver.c,v
retrieving revision 1.236
diff -u -p -r1.236 qemu_driver.c
--- src/qemu_driver.c 8 May 2009 10:11:14 -0000 1.236
+++ src/qemu_driver.c 8 May 2009 10:37:22 -0000
@@ -1379,12 +1379,8 @@ static int qemudStartVMDaemon(virConnect
if (qemudExtractVersionInfo(emulator,
NULL,
- &qemuCmdFlags) < 0) {
- qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
- _("Cannot determine QEMU argv syntax %s"),
- emulator);
+ &qemuCmdFlags) < 0)
goto cleanup;
- }
if (qemuPrepareHostDevices(conn, vm->def) < 0)
goto cleanup;
@@ -3703,12 +3699,8 @@ static int qemudDomainChangeEjectableMed
if (qemudExtractVersionInfo(vm->def->emulator,
NULL,
- &qemuCmdFlags) < 0) {
- qemudReportError(conn, dom, NULL, VIR_ERR_INTERNAL_ERROR,
- _("Cannot determine QEMU argv syntax %s"),
- vm->def->emulator);
+ &qemuCmdFlags) < 0)
return -1;
- }
if (qemuCmdFlags & QEMUD_CMD_FLAG_DRIVE) {
if (!(devname = qemudDiskDeviceName(conn, newdisk)))
--
|: Red Hat, Engineering, London -o- http://people.redhat.com/berrange/ :|
|: http://libvirt.org -o- http://virt-manager.org -o- http://ovirt.org :|
|: http://autobuild.org -o- http://search.cpan.org/~danberr/ :|
|: GnuPG: 7D3B9505 -o- F3C9 553F A1DA 4AC2 5648 23C1 B3DF F742 7D3B 9505 :|
15 years, 6 months
[libvirt] [PATCH v2 0/4] Improve QEMU process startup error
by Cole Robinson
Error reporting for failed QEMU processes isn't too great at the moment.
A couple cases I have hit:
- Trying to start a VM with a cdrom pointing to a nonexistent file. The
svirt hook function choked on this and indicated as much in the domain
log, but I still had to wait for the pidfile timeout (10 seconds), and
the only error reported was 'Domain did not show up'.
- QEMU dies quickly at startup. Happened with the pulse audio issue, or
if we build cli args incorrectly. The reporting here varies: if QEMU dies
before writing out the pidfile, the above case applies. If the pidfile is
written, we timeout in ReadLogOutput, and it's hit or miss whether we even
report the logfile output to the user.
The following patches improve the above cases by ensuring we never have to
wait for a timeout, and that the logfile output is always reported in the
error message.
Changes since v1:
Drop patch 1 + 2 (applied separately)
Patch 7 is pretty isolated, so was resent to list separately.
Don't waitpid in virExecDaemonize if virExec fails.
Remove needless pidfile loop in qemudStartVMDaemon.
Thanks,
Cole
Cole Robinson (4):
Add helper function virExecDaemonize
Report qemu log data if we fail to daemonize the process.
Add pidfile argument to __virExec
Check that QEMU is still alive while reading startup output.
src/libvirt_private.syms | 2 +-
src/proxy_internal.c | 16 +---
src/qemu_conf.c | 7 --
src/qemu_driver.c | 89 +++++++++++--------
src/remote_internal.c | 15 +---
src/uml_driver.c | 11 +--
src/util.c | 90 +++++++++++++++++---
src/util.h | 15 +++-
.../qemuxml2argvdata/qemuxml2argv-boot-cdrom.args | 2 +-
.../qemuxml2argvdata/qemuxml2argv-boot-floppy.args | 2 +-
.../qemuxml2argv-boot-network.args | 2 +-
.../qemuxml2argvdata/qemuxml2argv-bootloader.args | 2 +-
.../qemuxml2argv-clock-localtime.args | 2 +-
tests/qemuxml2argvdata/qemuxml2argv-clock-utc.args | 2 +-
.../qemuxml2argv-console-compat.args | 2 +-
.../qemuxml2argv-disk-cdrom-empty.args | 2 +-
.../qemuxml2argvdata/qemuxml2argv-disk-cdrom.args | 2 +-
.../qemuxml2argv-disk-drive-boot-cdrom.args | 2 +-
.../qemuxml2argv-disk-drive-boot-disk.args | 2 +-
.../qemuxml2argv-disk-drive-cache-v1-none.args | 2 +-
.../qemuxml2argv-disk-drive-cache-v1-wb.args | 2 +-
.../qemuxml2argv-disk-drive-cache-v1-wt.args | 2 +-
.../qemuxml2argv-disk-drive-cache-v2-none.args | 2 +-
.../qemuxml2argv-disk-drive-cache-v2-wb.args | 2 +-
.../qemuxml2argv-disk-drive-cache-v2-wt.args | 2 +-
.../qemuxml2argv-disk-drive-fmt-qcow.args | 2 +-
.../qemuxml2argv-disk-drive-shared.args | 2 +-
.../qemuxml2argvdata/qemuxml2argv-disk-floppy.args | 2 +-
tests/qemuxml2argvdata/qemuxml2argv-disk-many.args | 2 +-
tests/qemuxml2argvdata/qemuxml2argv-disk-usb.args | 2 +-
.../qemuxml2argvdata/qemuxml2argv-disk-virtio.args | 2 +-
.../qemuxml2argvdata/qemuxml2argv-disk-xenvbd.args | 2 +-
.../qemuxml2argv-graphics-sdl-fullscreen.args | 2 +-
.../qemuxml2argv-graphics-sdl.args | 2 +-
.../qemuxml2argv-graphics-vnc-sasl.args | 2 +-
.../qemuxml2argv-graphics-vnc-tls.args | 2 +-
.../qemuxml2argv-graphics-vnc.args | 2 +-
.../qemuxml2argv-hostdev-pci-address.args | 2 +-
.../qemuxml2argv-hostdev-usb-address.args | 2 +-
.../qemuxml2argv-hostdev-usb-product.args | 2 +-
.../qemuxml2argv-input-usbmouse.args | 2 +-
.../qemuxml2argv-input-usbtablet.args | 2 +-
tests/qemuxml2argvdata/qemuxml2argv-input-xen.args | 2 +-
tests/qemuxml2argvdata/qemuxml2argv-migrate.args | 2 +-
tests/qemuxml2argvdata/qemuxml2argv-minimal.args | 2 +-
tests/qemuxml2argvdata/qemuxml2argv-misc-acpi.args | 2 +-
.../qemuxml2argv-misc-no-reboot.args | 2 +-
tests/qemuxml2argvdata/qemuxml2argv-misc-uuid.args | 2 +-
.../qemuxml2argv-net-eth-ifname.args | 2 +-
tests/qemuxml2argvdata/qemuxml2argv-net-eth.args | 2 +-
tests/qemuxml2argvdata/qemuxml2argv-net-user.args | 2 +-
.../qemuxml2argvdata/qemuxml2argv-net-virtio.args | 2 +-
.../qemuxml2argv-parallel-tcp.args | 2 +-
.../qemuxml2argvdata/qemuxml2argv-restore-v1.args | 2 +-
.../qemuxml2argvdata/qemuxml2argv-restore-v2.args | 2 +-
.../qemuxml2argvdata/qemuxml2argv-serial-dev.args | 2 +-
.../qemuxml2argvdata/qemuxml2argv-serial-file.args | 2 +-
.../qemuxml2argvdata/qemuxml2argv-serial-many.args | 2 +-
.../qemuxml2argvdata/qemuxml2argv-serial-pty.args | 2 +-
.../qemuxml2argv-serial-tcp-telnet.args | 2 +-
.../qemuxml2argvdata/qemuxml2argv-serial-tcp.args | 2 +-
.../qemuxml2argvdata/qemuxml2argv-serial-udp.args | 2 +-
.../qemuxml2argvdata/qemuxml2argv-serial-unix.args | 2 +-
tests/qemuxml2argvdata/qemuxml2argv-serial-vc.args | 2 +-
tests/qemuxml2argvdata/qemuxml2argv-sound.args | 2 +-
65 files changed, 211 insertions(+), 148 deletions(-)
15 years, 6 months