[libvirt] new qemu tests require xen support
by Jim Meyering
Hi Dan,
On a system with stock rawhide kernel (not the xen one), I get two
new test failures because virCapabilitiesSupportsGuestOSType(caps, "xen")
returns 0.
$ ./qemuxml2xmltest
1) QEMU XML-2-XML minimal ... OK
2) QEMU XML-2-XML boot-cdrom ... OK
3) QEMU XML-2-XML boot-network ... OK
4) QEMU XML-2-XML boot-floppy ... OK
5) QEMU XML-2-XML bootloader ... libvir: QEMU error : unknown OS type xen
FAILED
6) QEMU XML-2-XML clock-utc ... OK
7) QEMU XML-2-XML clock-localtime ... OK
8) QEMU XML-2-XML disk-cdrom ... OK
9) QEMU XML-2-XML disk-floppy ... OK
10) QEMU XML-2-XML disk-many ... OK
11) QEMU XML-2-XML disk-xenvbd ... OK
12) QEMU XML-2-XML graphics-vnc ... OK
13) QEMU XML-2-XML graphics-sdl ... OK
14) QEMU XML-2-XML input-usbmouse ... OK
15) QEMU XML-2-XML input-usbtablet ... OK
16) QEMU XML-2-XML input-xen ... libvir: QEMU error : unknown OS type xen
FAILED
17) QEMU XML-2-XML misc-acpi ... OK
18) QEMU XML-2-XML misc-no-reboot ... OK
19) QEMU XML-2-XML net-user ... OK
20) QEMU XML-2-XML net-virtio ... OK
21) QEMU XML-2-XML serial-vc ... OK
22) QEMU XML-2-XML serial-pty ... OK
23) QEMU XML-2-XML serial-dev ... OK
24) QEMU XML-2-XML serial-file ... OK
25) QEMU XML-2-XML serial-unix ... OK
26) QEMU XML-2-XML serial-tcp ... OK
27) QEMU XML-2-XML serial-udp ... OK
28) QEMU XML-2-XML serial-tcp-telnet ... OK
29) QEMU XML-2-XML serial-many ... OK
30) QEMU XML-2-XML parallel-tcp ... OK
31) QEMU XML-2-XML console-compat ... OK
[Exit 1]
qemuxml2argvtest fails the same way.
16 years, 6 months
[libvirt] [PATCH] start using c-ctype functions
by Jim Meyering
>From db0ed598dfc045f3937a3629a432d2d703449f50 Mon Sep 17 00:00:00 2001
From: Jim Meyering <meyering(a)redhat.com>
Date: Wed, 14 May 2008 23:06:15 +0200
Subject: [PATCH] start using c-ctype functions
Up to now, we've been avoiding ctype functions like isspace, isdigit, etc.
Now that we have the c-ctype functions, we can start using them to make
the code more readable with changes like these:
- /* This may not work on EBCDIC. */
- if ((*p >= 'a' && *p <= 'z') ||
- (*p >= 'A' && *p <= 'Z') ||
- (*p >= '0' && *p <= '9'))
+ if (c_isalnum(*p))
- while ((*cur >= '0') && (*cur <= '9')) {
+ while (c_isdigit(*cur)) {
Also, some macros in conf.c used names that conflicted with
standard meaning of "BLANK" and "SPACE", so I've adjusted them
to be in line with the definition of e.g., isblank.
In addition, I've wrapped those statement macros with do {...} while (0),
so that we can't forget the ";" after a use. There was one like that
already (fixed below). The missing semicolon would mess up automatic
indenting.
* src/buf.c (virBufferURIEncodeString):
* src/conf.c (IS_EOL, SKIP_BLANKS_AND_EOL, SKIP_BLANKS)
(virConfParseLong, virConfParseValue, virConfParseName)
(virConfParseSeparator, virConfParseStatement, IS_BLANK, IS_CHAR)
(IS_DIGIT, IS_SPACE, SKIP_SPACES):
* src/nodeinfo.c:
* src/qemu_conf.c (qemudParseInterfaceXML):
* src/qemu_driver.c (qemudDomainBlockStats):
* src/sexpr.c:
* src/stats_linux.c:
* src/util.c (virParseNumber, virDiskNameToIndex):
* src/uuid.c (hextobin, virUUIDParse):
* src/virsh.c:
* src/xml.c (parseCpuNumber, virParseCpuSet):
---
src/buf.c | 11 ++-------
src/conf.c | 56 +++++++++++++++++++++++++---------------------------
src/nodeinfo.c | 2 +-
src/qemu_conf.c | 10 +++-----
src/qemu_driver.c | 6 ++--
src/sexpr.c | 2 +-
src/stats_linux.c | 2 +-
src/util.c | 6 ++--
src/uuid.c | 35 +++++++++++++++++++-------------
src/virsh.c | 2 +-
src/xml.c | 6 ++--
11 files changed, 68 insertions(+), 70 deletions(-)
diff --git a/src/buf.c b/src/buf.c
index b56a9c1..16afaca 100644
--- a/src/buf.c
+++ b/src/buf.c
@@ -16,6 +16,7 @@
#include <stdlib.h>
#include <string.h>
#include <stdarg.h>
+#include "c-ctype.h"
#define __VIR_BUFFER_C__
@@ -349,10 +350,7 @@ virBufferURIEncodeString (virBufferPtr buf, const char *str)
return;
for (p = str; *p; ++p) {
- /* This may not work on EBCDIC. */
- if ((*p >= 'a' && *p <= 'z') ||
- (*p >= 'A' && *p <= 'Z') ||
- (*p >= '0' && *p <= '9'))
+ if (c_isalnum(*p))
grow_size++;
else
grow_size += 3; /* %ab */
@@ -362,10 +360,7 @@ virBufferURIEncodeString (virBufferPtr buf, const char *str)
return;
for (p = str; *p; ++p) {
- /* This may not work on EBCDIC. */
- if ((*p >= 'a' && *p <= 'z') ||
- (*p >= 'A' && *p <= 'Z') ||
- (*p >= '0' && *p <= '9'))
+ if (c_isalnum(*p))
buf->content[buf->use++] = *p;
else {
uc = (unsigned char) *p;
diff --git a/src/conf.c b/src/conf.c
index e52d8d1..6ac480a 100644
--- a/src/conf.c
+++ b/src/conf.c
@@ -22,6 +22,7 @@
#include "buf.h"
#include "conf.h"
#include "util.h"
+#include "c-ctype.h"
/************************************************************************
* *
@@ -45,17 +46,14 @@ struct _virConfParserCtxt {
#define CUR (*ctxt->cur)
#define NEXT if (ctxt->cur < ctxt->end) ctxt->cur++;
#define IS_EOL(c) (((c) == '\n') || ((c) == '\r'))
-#define IS_BLANK(c) (((c) == ' ') || ((c) == '\n') || ((c) == '\r') || \
- ((c) == '\t'))
-#define SKIP_BLANKS {while ((ctxt->cur < ctxt->end) && (IS_BLANK(CUR))){\
- if (CUR == '\n') ctxt->line++; \
- ctxt->cur++;}}
-#define IS_SPACE(c) (((c) == ' ') || ((c) == '\t'))
-#define SKIP_SPACES {while ((ctxt->cur < ctxt->end) && (IS_SPACE(CUR))) \
- ctxt->cur++;}
-#define IS_CHAR(c) ((((c) >= 'a') && ((c) <= 'z')) || \
- (((c) >= 'A') && ((c) <= 'Z')))
-#define IS_DIGIT(c) (((c) >= '0') && ((c) <= '9'))
+
+#define SKIP_BLANKS_AND_EOL \
+ do { while ((ctxt->cur < ctxt->end) && (c_isblank(CUR) || IS_EOL(CUR))) { \
+ if (CUR == '\n') ctxt->line++; \
+ ctxt->cur++;}} while (0)
+#define SKIP_BLANKS \
+ do { while ((ctxt->cur < ctxt->end) && (c_isblank(CUR))) \
+ ctxt->cur++; } while (0)
/************************************************************************
* *
@@ -338,12 +336,12 @@ virConfParseLong(virConfParserCtxtPtr ctxt, long *val)
} else if (CUR == '+') {
NEXT;
}
- if ((ctxt->cur >= ctxt->end) || (!IS_DIGIT(CUR))) {
+ if ((ctxt->cur >= ctxt->end) || (!c_isdigit(CUR))) {
virConfError(NULL, VIR_ERR_CONF_SYNTAX, _("unterminated number"),
ctxt->line);
return(-1);
}
- while ((ctxt->cur < ctxt->end) && (IS_DIGIT(CUR))) {
+ while ((ctxt->cur < ctxt->end) && (c_isdigit(CUR))) {
l = l * 10 + (CUR - '0');
NEXT;
}
@@ -428,7 +426,7 @@ virConfParseValue(virConfParserCtxtPtr ctxt)
char *str = NULL;
long l = 0;
- SKIP_SPACES;
+ SKIP_BLANKS;
if (ctxt->cur >= ctxt->end) {
virConfError(NULL, VIR_ERR_CONF_SYNTAX, _("expecting a value"),
ctxt->line);
@@ -442,10 +440,10 @@ virConfParseValue(virConfParserCtxtPtr ctxt)
} else if (CUR == '[') {
type = VIR_CONF_LIST;
NEXT;
- SKIP_BLANKS;
+ SKIP_BLANKS_AND_EOL;
if ((ctxt->cur < ctxt->end) && (CUR != ']')) {
lst = virConfParseValue(ctxt);
- SKIP_BLANKS;
+ SKIP_BLANKS_AND_EOL;
}
while ((ctxt->cur < ctxt->end) && (CUR != ']')) {
if (CUR != ',') {
@@ -455,7 +453,7 @@ virConfParseValue(virConfParserCtxtPtr ctxt)
return(NULL);
}
NEXT;
- SKIP_BLANKS;
+ SKIP_BLANKS_AND_EOL;
if (CUR == ']') {
break;
}
@@ -467,7 +465,7 @@ virConfParseValue(virConfParserCtxtPtr ctxt)
prev = lst;
while (prev->next != NULL) prev = prev->next;
prev->next = tmp;
- SKIP_BLANKS;
+ SKIP_BLANKS_AND_EOL;
}
if (CUR == ']') {
NEXT;
@@ -477,7 +475,7 @@ virConfParseValue(virConfParserCtxtPtr ctxt)
virConfFreeList(lst);
return(NULL);
}
- } else if (IS_DIGIT(CUR) || (CUR == '-') || (CUR == '+')) {
+ } else if (c_isdigit(CUR) || (CUR == '-') || (CUR == '+')) {
if (virConfParseLong(ctxt, &l) < 0) {
return(NULL);
}
@@ -514,14 +512,14 @@ virConfParseName(virConfParserCtxtPtr ctxt)
const char *base;
char *ret;
- SKIP_SPACES;
+ SKIP_BLANKS;
base = ctxt->cur;
/* TODO: probably need encoding support and UTF-8 parsing ! */
- if (!IS_CHAR(CUR)) {
+ if (!c_isalpha(CUR)) {
virConfError(NULL, VIR_ERR_CONF_SYNTAX, _("expecting a name"), ctxt->line);
return(NULL);
}
- while ((ctxt->cur < ctxt->end) && ((IS_CHAR(CUR)) || (IS_DIGIT(CUR)) || (CUR == '_')))
+ while ((ctxt->cur < ctxt->end) && (c_isalnum(CUR) || (CUR == '_')))
NEXT;
ret = strndup(base, ctxt->cur - base);
if (ret == NULL) {
@@ -572,14 +570,14 @@ virConfParseComment(virConfParserCtxtPtr ctxt)
static int
virConfParseSeparator(virConfParserCtxtPtr ctxt)
{
- SKIP_SPACES;
+ SKIP_BLANKS;
if (ctxt->cur >= ctxt->end)
return(0);
if (IS_EOL(CUR)) {
- SKIP_BLANKS
+ SKIP_BLANKS_AND_EOL;
} else if (CUR == ';') {
NEXT;
- SKIP_BLANKS;
+ SKIP_BLANKS_AND_EOL;
} else {
virConfError(NULL, VIR_ERR_CONF_SYNTAX, _("expecting a separator"),
ctxt->line);
@@ -604,27 +602,27 @@ virConfParseStatement(virConfParserCtxtPtr ctxt)
virConfValuePtr value;
char *comm = NULL;
- SKIP_BLANKS;
+ SKIP_BLANKS_AND_EOL;
if (CUR == '#') {
return(virConfParseComment(ctxt));
}
name = virConfParseName(ctxt);
if (name == NULL)
return(-1);
- SKIP_SPACES;
+ SKIP_BLANKS;
if (CUR != '=') {
virConfError(NULL, VIR_ERR_CONF_SYNTAX, _("expecting an assignment"),
ctxt->line);
return(-1);
}
NEXT;
- SKIP_SPACES;
+ SKIP_BLANKS;
value = virConfParseValue(ctxt);
if (value == NULL) {
free(name);
return(-1);
}
- SKIP_SPACES;
+ SKIP_BLANKS;
if (CUR == '#') {
NEXT;
base = ctxt->cur;
diff --git a/src/nodeinfo.c b/src/nodeinfo.c
index b2ef6ee..6c303ed 100644
--- a/src/nodeinfo.c
+++ b/src/nodeinfo.c
@@ -27,7 +27,7 @@
#include <string.h>
#include <stdlib.h>
#include <errno.h>
-#include <c-ctype.h>
+#include "c-ctype.h"
#ifdef HAVE_SYS_UTSNAME_H
#include <sys/utsname.h>
diff --git a/src/qemu_conf.c b/src/qemu_conf.c
index 8ae0960..db6c24f 100644
--- a/src/qemu_conf.c
+++ b/src/qemu_conf.c
@@ -49,7 +49,8 @@
#include "buf.h"
#include "conf.h"
#include "util.h"
-#include <verify.h>
+#include "verify.h"
+#include "c-ctype.h"
#define qemudLog(level, msg...) fprintf(stderr, msg)
@@ -992,7 +993,7 @@ static int qemudParseInterfaceXML(virConnectPtr conn,
* i82551 i82557b i82559er ne2k_pci pcnet rtl8139 e1000 virtio
*/
if (model != NULL) {
- int i, len, char_ok;
+ int i, len;
len = xmlStrlen (model);
if (len >= QEMUD_MODEL_MAX_LEN) {
@@ -1001,10 +1002,7 @@ static int qemudParseInterfaceXML(virConnectPtr conn,
goto error;
}
for (i = 0; i < len; ++i) {
- char_ok =
- (model[i] >= '0' && model[i] <= '9') ||
- (model[i] >= 'a' && model[i] <= 'z') ||
- (model[i] >= 'A' && model[i] <= 'Z') || model[i] == '_';
+ int char_ok = c_isalnum(model[i]) || model[i] == '_';
if (!char_ok) {
qemudReportError (conn, NULL, NULL, VIR_ERR_INVALID_ARG, "%s",
_("Model name contains invalid characters"));
diff --git a/src/qemu_driver.c b/src/qemu_driver.c
index 6ba6179..a56845b 100644
--- a/src/qemu_driver.c
+++ b/src/qemu_driver.c
@@ -41,7 +41,6 @@
#include <fcntl.h>
#include <signal.h>
#include <paths.h>
-#include <c-ctype.h>
#include <pwd.h>
#include <stdio.h>
#include <sys/wait.h>
@@ -49,6 +48,7 @@
#include "libvirt/virterror.h"
+#include "c-ctype.h"
#include "event.h"
#include "buf.h"
#include "util.h"
@@ -2650,12 +2650,12 @@ qemudDomainBlockStats (virDomainPtr dom,
* cdrom to ide1-cd0
* fd[a-] to floppy[0-]
*/
- if (STRPREFIX (path, "hd") && path[2] >= 'a' && path[2] <= 'z')
+ if (STRPREFIX (path, "hd") && c_islower(path[2]))
snprintf (qemu_dev_name, sizeof (qemu_dev_name),
"ide0-hd%d", path[2] - 'a');
else if (STREQ (path, "cdrom"))
strcpy (qemu_dev_name, "ide1-cd0");
- else if (STRPREFIX (path, "fd") && path[2] >= 'a' && path[2] <= 'z')
+ else if (STRPREFIX (path, "fd") && c_islower(path[2]))
snprintf (qemu_dev_name, sizeof (qemu_dev_name),
"floppy%d", path[2] - 'a');
else {
diff --git a/src/sexpr.c b/src/sexpr.c
index c275ee2..44d9c74 100644
--- a/src/sexpr.c
+++ b/src/sexpr.c
@@ -15,7 +15,7 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
-#include <c-ctype.h>
+#include "c-ctype.h"
#include <errno.h>
#include "internal.h"
diff --git a/src/stats_linux.c b/src/stats_linux.c
index 30a4990..4f32d65 100644
--- a/src/stats_linux.c
+++ b/src/stats_linux.c
@@ -18,7 +18,7 @@
#include <fcntl.h>
#include <string.h>
#include <unistd.h>
-#include <c-ctype.h>
+#include "c-ctype.h"
#ifdef WITH_XEN
#include <xs.h>
diff --git a/src/util.c b/src/util.c
index bdb6dea..a075962 100644
--- a/src/util.c
+++ b/src/util.c
@@ -37,7 +37,7 @@
#include <sys/wait.h>
#endif
#include <string.h>
-#include <c-ctype.h>
+#include "c-ctype.h"
#ifdef HAVE_PATHS_H
#include <paths.h>
@@ -681,7 +681,7 @@ virParseNumber(const char **str)
if ((*cur < '0') || (*cur > '9'))
return (-1);
- while ((*cur >= '0') && (*cur <= '9')) {
+ while (c_isdigit(*cur)) {
unsigned int c = *cur - '0';
if ((ret > INT_MAX / 10) ||
@@ -800,7 +800,7 @@ int virDiskNameToIndex(const char *name) {
while (*ptr) {
idx = idx * 26;
- if ('a' > *ptr || 'z' < *ptr)
+ if (!c_islower(*ptr))
return -1;
idx += *ptr - 'a';
diff --git a/src/uuid.c b/src/uuid.c
index fea1764..301479b 100644
--- a/src/uuid.c
+++ b/src/uuid.c
@@ -32,6 +32,7 @@
#include <time.h>
#include <unistd.h>
+#include "c-ctype.h"
#include "internal.h"
#define qemudLog(level, msg...) fprintf(stderr, msg)
@@ -105,6 +106,22 @@ virUUIDGenerate(unsigned char *uuid)
return virUUIDGeneratePseudoRandomBytes(uuid, VIR_UUID_BUFLEN);
}
+/* Convert C from hexadecimal character to integer. */
+static int
+hextobin (unsigned char c)
+{
+ switch (c)
+ {
+ default: return c - '0';
+ case 'a': case 'A': return 10;
+ case 'b': case 'B': return 11;
+ case 'c': case 'C': return 12;
+ case 'd': case 'D': return 13;
+ case 'e': case 'E': return 14;
+ case 'f': case 'F': return 15;
+ }
+}
+
/**
* virUUIDParse:
* @uuidstr: zero terminated string representation of the UUID
@@ -136,26 +153,16 @@ virUUIDParse(const char *uuidstr, unsigned char *uuid) {
cur++;
continue;
}
- if ((*cur >= '0') && (*cur <= '9'))
- uuid[i] = *cur - '0';
- else if ((*cur >= 'a') && (*cur <= 'f'))
- uuid[i] = *cur - 'a' + 10;
- else if ((*cur >= 'A') && (*cur <= 'F'))
- uuid[i] = *cur - 'A' + 10;
- else
+ if (!c_isxdigit(*cur))
goto error;
+ uuid[i] = hextobin(*cur);
uuid[i] *= 16;
cur++;
if (*cur == 0)
goto error;
- if ((*cur >= '0') && (*cur <= '9'))
- uuid[i] += *cur - '0';
- else if ((*cur >= 'a') && (*cur <= 'f'))
- uuid[i] += *cur - 'a' + 10;
- else if ((*cur >= 'A') && (*cur <= 'F'))
- uuid[i] += *cur - 'A' + 10;
- else
+ if (!c_isxdigit(*cur))
goto error;
+ uuid[i] += hextobin(*cur);
i++;
cur++;
}
diff --git a/src/virsh.c b/src/virsh.c
index af2f1a4..45af630 100644
--- a/src/virsh.c
+++ b/src/virsh.c
@@ -26,7 +26,7 @@
#include <getopt.h>
#include <sys/types.h>
#include <sys/time.h>
-#include <c-ctype.h>
+#include "c-ctype.h"
#include <fcntl.h>
#include <locale.h>
#include <time.h>
diff --git a/src/xml.c b/src/xml.c
index 22dc211..14b8b70 100644
--- a/src/xml.c
+++ b/src/xml.c
@@ -76,10 +76,10 @@ parseCpuNumber(const char **str, int maxcpu)
int ret = 0;
const char *cur = *str;
- if ((*cur < '0') || (*cur > '9'))
+ if (!c_isdigit(*cur))
return (-1);
- while ((*cur >= '0') && (*cur <= '9')) {
+ while (c_isdigit(*cur)) {
ret = ret * 10 + (*cur - '0');
if (ret >= maxcpu)
return (-1);
@@ -197,7 +197,7 @@ virParseCpuSet(virConnectPtr conn, const char **str, char sep,
neg = 1;
}
- if ((*cur < '0') || (*cur > '9'))
+ if (!c_isdigit(*cur))
goto parse_error;
start = parseCpuNumber(&cur, maxcpu);
if (start < 0)
--
1.5.5.1.148.gbc1be
16 years, 6 months
[libvirt] avoid double free
by Jim Meyering
I noticed a new test failure on rawhide,
ran valgrind ./qemuxml2xmltest and got this:
==14847== Invalid free() / delete / delete[]
==14847== at 0x4A0609F: free (vg_replace_malloc.c:323)
==14847== by 0x409DF8: qemudParseXML (qemu_conf.c:2149)
==14847== by 0x40CBE0: qemudParseVMDef (qemu_conf.c:2982)
==14847== by 0x4021CD: testCompareXMLToXMLFiles (qemuxml2xmltest.c:35)
==14847== by 0x4022EA: testCompareXMLToXMLHelper (qemuxml2xmltest.c:68)
==14847== by 0x40291B: virtTestRun (testutils.c:79)
==14847== by 0x402436: main (qemuxml2xmltest.c:100)
==14847== Address 0x4cd3d68 is 0 bytes inside a block of size 72 free'd
==14847== at 0x4A0609F: free (vg_replace_malloc.c:323)
==14847== by 0x408731: qemudParseXML (qemu_conf.c:1738)
==14847== by 0x40CBE0: qemudParseVMDef (qemu_conf.c:2982)
==14847== by 0x4021CD: testCompareXMLToXMLFiles (qemuxml2xmltest.c:35)
==14847== by 0x4022EA: testCompareXMLToXMLHelper (qemuxml2xmltest.c:68)
==14847== by 0x40291B: virtTestRun (testutils.c:79)
==14847== by 0x402436: main (qemuxml2xmltest.c:100)
Here's the fix:
>From 777e199f2d680ec302b7604e030a41da2c62cb49 Mon Sep 17 00:00:00 2001
From: Jim Meyering <meyering(a)redhat.com>
Date: Fri, 16 May 2008 08:18:31 +0200
Subject: [PATCH] avoid a double-free bug
* src/qemu_conf.c (qemudParseXML): Ensure that "obj" is either
NULL or a valid malloc'd pointer before we might "goto error"
where it is freed.
---
diff --git a/src/qemu_conf.c b/src/qemu_conf.c
index 458f5df..1a7ab46 100644
--- a/src/qemu_conf.c
+++ b/src/qemu_conf.c
@@ -1736,6 +1736,7 @@ static struct qemud_vm_def *qemudParseXML(virConnectPtr conn,
} else {
strcpy(def->os.type, (const char *)obj->stringval);
xmlXPathFreeObject(obj);
+ obj = NULL;
}
if (!virCapabilitiesSupportsGuestOSType(driver->caps, def->os.type)) {
--
1.5.5.1.249.g26848
16 years, 6 months
[libvirt] [ANNOUNCE] virt-df 2.1.0 - a 'df' tool for virtual guests
by Richard W.M. Jones
I'm pleased to announce the most recent release of virt-df (2.1.0).
Virt-df is 'df' for virtual guests. Run the program on the host / dom0
to display disk space used and available on all partitions on all
guests. You don't need to run any sort of program/agent within the
guest.
Home page: http://et.redhat.com/~rjones/virt-df/
Source/binaries: http://et.redhat.com/~rjones/virt-df/files/
Developer repository:
http://hg.et.redhat.com/virt/applications/virt-df--devel
This version supports most common filesystems and partitioning
schemes, including:
- Linux ext2/3
- DOS FAT32
- Windows NTFS
- Linux LVM2 (volume groups and logical volumes)
- Primary and extended disk partitions
- Linux swap
- Linux suspend partition
You can run it in your host / dom0 to display guest filesystems:
# virt-df -c qemu:///system -h
Filesystem Size Used Available Type
rhel51x32kvm:hda1 96.8 MiB 14.6 MiB 82.2 MiB Linux ext2/3
rhel51x32kvm:VolGroup00/LogVol00 6.4 GiB 3.6 GiB 2.8 GiB Linux ext2/3
rhel51x32kvm:VolGroup00/LogVol01 992.0 MiB Linux swap
You can also run it on general disk images, or disk devices:
# virt-df -t /dev/sda
Filesystem 1K-blocks Used Available Type
/dev/sda:hda1 25599996 11309448 14290552 Windows NTFS
/dev/sda:hda2 992016 93772 898244 Linux ext2/3
/dev/sda:F9VG/F9Root 23316072 7818164 15497908 Linux ext2/3
/dev/sda:F9VG/F9Swap 1015808 Linux swap
/dev/sda:RHEL51VG/RHEL51Root 22382184 7796640 14585544 Linux ext2/3
/dev/sda:RHEL51VG/RHEL51Swap 2031616 Linux swap
/dev/sda:VolGroup/FAT32Test 916736 4 914676 DOS/Windows
You can write the output to a CSV file (use --csv option) in order to
import the data easily into spreadsheets and databases.
Included also is an experimental command line tool called 'diskzip'
which intelligently compresses disk images by leaving out the bits
which aren't actually used in the filesystems / partitions / volume
groups contained within.
Rich.
--
Richard Jones, Emerging Technologies, Red Hat http://et.redhat.com/~rjones
virt-p2v converts physical machines to virtual machines. Boot with a
live CD or over the network (PXE) and turn machines into Xen guests.
http://et.redhat.com/~rjones/virt-p2v
16 years, 6 months
[libvirt] [PATCH] Extract kvm version from qemu-kvm
by Cole Robinson
The patch below provides a way to check the kvm version by parsing
the output of qemu-kvm, similar to how the qemu version is parsed.
The qemu-kvm binary help info starts with the line:
"QEMU PC emulator version major.minor.micro (KVM-ver)"
The patch is kind of ugly, with renamed functions and code
movement. The gist of it is:
- Moved the general run-a-command-and-grab-output into its own
function qemudExtractCommandOutput
- Created qemudExtract{Qemu,KVM}VersionInfo which call the above
function and scrape the output
- Use qemudExtractVersion to find the default binaries and call
the *VersionInfo functions
If there is a parsing error, or kvm support isn't found, the new
kvmVersion in the qemud_driver struct is just set to zero. I also
added a call to fill in the qemu and kvm versions on driver init.
The patch also fills in the previously discussed max vcpus piece,
which is dependent on the kvm version.
Any comments appreciated.
Thanks,
Cole
diff --git a/src/qemu_conf.c b/src/qemu_conf.c
index b17d0c8..3d45669 100644
--- a/src/qemu_conf.c
+++ b/src/qemu_conf.c
@@ -428,13 +428,16 @@ virCapsPtr qemudCapsInit(void) {
return NULL;
}
-
-static int qemudExtractVersionInfo(const char *qemu, int *version, int *flags) {
+static int qemudExtractCommandOutput(const char *app, char *buf, size_t size) {
pid_t child;
int newstdout[2];
+ struct stat sb;
- *flags = 0;
- *version = 0;
+ if (stat(app, &sb) < 0) {
+ qemudLog(QEMUD_ERR, _("Cannot find binary %s: %s"), app,
+ strerror(errno));
+ return -1;
+ }
if (pipe(newstdout) < 0) {
return -1;
@@ -458,21 +461,19 @@ static int qemudExtractVersionInfo(const char *qemu, int *version, int *flags) {
/* Just in case QEMU is translated someday.. */
setenv("LANG", "C", 1);
- execl(qemu, qemu, (char*)NULL);
+ execl(app, app, (char *) NULL);
cleanup1:
_exit(-1); /* Just in case */
} else { /* Parent */
- char help[8192]; /* Ought to be enough to hold QEMU help screen */
- int got = 0, ret = -1;
- int major, minor, micro;
+ int got = 0, ret = -1;
if (close(newstdout[1]) < 0)
goto cleanup2;
- while (got < (sizeof(help)-1)) {
+ while (got < size-1) {
int len;
- if ((len = read(newstdout[0], help+got, sizeof(help)-got-1)) <= 0) {
+ if ((len = read(newstdout[0], buf+got, size-got-1)) <= 0) {
if (!len)
break;
if (errno == EINTR)
@@ -481,30 +482,9 @@ static int qemudExtractVersionInfo(const char *qemu, int *version, int *flags) {
}
got += len;
}
- help[got] = '\0';
-
- if (sscanf(help, "QEMU PC emulator version %d.%d.%d", &major,&minor, µ) != 3) {
- goto cleanup2;
- }
-
- *version = (major * 1000 * 1000) + (minor * 1000) + micro;
- if (strstr(help, "-no-kqemu"))
- *flags |= QEMUD_CMD_FLAG_KQEMU;
- if (strstr(help, "-no-reboot"))
- *flags |= QEMUD_CMD_FLAG_NO_REBOOT;
- if (strstr(help, "-name"))
- *flags |= QEMUD_CMD_FLAG_NAME;
- if (strstr(help, "-drive"))
- *flags |= QEMUD_CMD_FLAG_DRIVE;
- if (strstr(help, "boot=on"))
- *flags |= QEMUD_CMD_FLAG_DRIVE_BOOT;
- if (*version >= 9000)
- *flags |= QEMUD_CMD_FLAG_VNC_COLON;
+ buf[got] = '\0';
ret = 0;
- qemudDebug("Version %d %d %d Cooked version: %d, with flags ? %d",
- major, minor, micro, *version, *flags);
-
cleanup2:
if (close(newstdout[0]) < 0)
ret = -1;
@@ -515,8 +495,8 @@ static int qemudExtractVersionInfo(const char *qemu, int *version, int *flags) {
goto rewait;
}
qemudLog(QEMUD_ERR,
- _("Unexpected exit status from qemu %d pid %lu"),
- got, (unsigned long)child);
+ _("Unexpected exit status from app %s, exit %d: pid %lu"),
+ app, got, (unsigned long)child);
ret = -1;
}
/* Check & log unexpected exit status, but don't fail,
@@ -524,38 +504,119 @@ static int qemudExtractVersionInfo(const char *qemu, int *version, int *flags) {
* actually read a valid version number above */
if (WEXITSTATUS(got) != 1) {
qemudLog(QEMUD_WARN,
- _("Unexpected exit status '%d', qemu probably failed"),
- got);
+ _("Unexpected exit status '%d', app '%s' probably failed"),
+ got, app);
}
return ret;
}
}
-int qemudExtractVersion(virConnectPtr conn,
- struct qemud_driver *driver) {
+static int qemudExtractQemuVersionInfo(const char *app, int *version,
+ int *flags) {
+
+ char help[8192]; /* Ought to be enough to hold QEMU help screen */
+ int major, minor, micro;
+ int ret = -1;
+
+ *flags = 0;
+ *version = 0;
+
+ if (qemudExtractCommandOutput(app, help, sizeof(help)) < 0) {
+ qemudReportError(NULL, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
+ _("Failed to extract KVM output."));
+ goto error;
+ }
+
+ if (sscanf(help, "QEMU PC emulator version %d.%d.%d", &major, &minor,
+ µ) != 3) {
+ qemudReportError(NULL, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
+ _("Failed to parse QEMU version."));
+ goto error;
+ }
+
+ *version = (major * 1000 * 1000) + (minor * 1000) + micro;
+ if (strstr(help, "-no-kqemu"))
+ *flags |= QEMUD_CMD_FLAG_KQEMU;
+ if (strstr(help, "-no-reboot"))
+ *flags |= QEMUD_CMD_FLAG_NO_REBOOT;
+ if (strstr(help, "-name"))
+ *flags |= QEMUD_CMD_FLAG_NAME;
+ if (strstr(help, "-drive"))
+ *flags |= QEMUD_CMD_FLAG_DRIVE;
+ if (strstr(help, "boot=on"))
+ *flags |= QEMUD_CMD_FLAG_DRIVE_BOOT;
+ if (*version >= 9000)
+ *flags |= QEMUD_CMD_FLAG_VNC_COLON;
+
+ qemudDebug("Version %d %d %d Cooked version: %d, with flags ? %d",
+ major, minor, micro, *version, *flags);
+
+ ret = 0;
+ error:
+ return ret;
+}
+
+static int qemudExtractKVMVersionInfo(const char *app, int *version) {
+
+ char buf[8192]; /* Ought to be enough to hold QEMU help screen */
+ char ignore[50] = "\0";
+ int ret = -1;
+
+ *version = 0;
+
+ if (qemudExtractCommandOutput(app, buf, sizeof(buf)) < 0) {
+ qemudReportError(NULL, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
+ _("Failed to extract KVM output."));
+ goto error;
+ }
+
+ // Format = "QEMU PC emulator version major.minor.micro(-cvs) (KVM-ver)"
+ if (sscanf(buf, "QEMU PC emulator version %s (kvm-%d", ignore,
+ version) != 2) {
+ qemudReportError(NULL, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
+ _("Failed to parse KVM version."));
+ goto error;
+ }
+
+ qemudDebug("KVM version: %d", *version);
+
+ ret = 0;
+ error:
+ return ret;
+}
+
+int qemudExtractVersion(struct qemud_driver *driver) {
const char *binary;
- struct stat sb;
int ignored;
+ struct utsname utsname;
- if (driver->qemuVersion > 0)
- return 0;
+ uname(&utsname);
- if ((binary = virCapabilitiesDefaultGuestEmulator(driver->caps,
- "hvm",
- "i686",
- "qemu")) == NULL)
- return -1;
+ if (driver->qemuVersion <= 0) {
- if (stat(binary, &sb) < 0) {
- qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
- _("Cannot find QEMU binary %s: %s"), binary,
- strerror(errno));
- return -1;
+ if ((binary = virCapabilitiesDefaultGuestEmulator(driver->caps,
+ "hvm",
+ "i686",
+ "qemu")) == NULL)
+ return -1;
+
+ if (qemudExtractQemuVersionInfo(binary, &driver->qemuVersion,
+ &ignored) < 0)
+ return -1;
}
- if (qemudExtractVersionInfo(binary, &driver->qemuVersion, &ignored) < 0) {
- return -1;
+ if (driver->kvmVersion <= 0) {
+ // If kvm isn't supported, don't return error since kvm is optional
+ if ((binary = virCapabilitiesDefaultGuestEmulator(driver->caps,
+ "hvm",
+ utsname.machine,
+ "kvm")) == NULL)
+ return 0;
+
+ if (qemudExtractKVMVersionInfo(binary, &driver->kvmVersion) < 0) {
+ return -1;
+ }
}
return 0;
@@ -2324,9 +2385,9 @@ int qemudBuildCommandLine(virConnectPtr conn,
}
if (vm->qemuVersion == 0) {
- if (qemudExtractVersionInfo(vm->def->os.binary,
- &(vm->qemuVersion),
- &(vm->qemuCmdFlags)) < 0)
+ if (qemudExtractQemuVersionInfo(vm->def->os.binary,
+ &(vm->qemuVersion),
+ &(vm->qemuCmdFlags)) < 0)
return -1;
}
diff --git a/src/qemu_conf.h b/src/qemu_conf.h
index 5d07c89..914d418 100644
--- a/src/qemu_conf.h
+++ b/src/qemu_conf.h
@@ -392,6 +392,7 @@ struct qemud_network {
/* Main driver state */
struct qemud_driver {
int qemuVersion;
+ int kvmVersion;
int nactivevms;
int ninactivevms;
struct qemud_vm *vms;
@@ -451,8 +452,7 @@ struct qemud_network *qemudFindNetworkByName(const struct qemud_driver *driver,
virCapsPtr qemudCapsInit (void);
-int qemudExtractVersion (virConnectPtr conn,
- struct qemud_driver *driver);
+int qemudExtractVersion (struct qemud_driver *driver);
int qemudBuildCommandLine (virConnectPtr conn,
struct qemud_driver *driver,
struct qemud_vm *vm,
diff --git a/src/qemu_driver.c b/src/qemu_driver.c
index 34193bd..4df9d59 100644
--- a/src/qemu_driver.c
+++ b/src/qemu_driver.c
@@ -222,6 +222,12 @@ qemudStartup(void) {
if ((qemu_driver->caps = qemudCapsInit()) == NULL)
goto out_of_memory;
+ // Dependent on capabilities being initialized
+ if (qemudExtractVersion(qemu_driver) < 0) {
+ qemudShutdown();
+ return -1;
+ }
+
if (qemudLoadDriverConfig(qemu_driver, driverConf) < 0) {
qemudShutdown();
return -1;
@@ -1566,16 +1572,24 @@ static const char *qemudGetType(virConnectPtr conn ATTRIBUTE_UNUSED) {
}
static int qemudGetMaxVCPUs(virConnectPtr conn, const char *type) {
+ struct qemud_driver *driver = (struct qemud_driver *)conn->privateData;
+
if (!type)
return 16;
if (STRCASEEQ(type, "qemu"))
return 16;
- /* XXX future KVM will support SMP. Need to probe
- kernel to figure out KVM module version i guess */
- if (STRCASEEQ(type, "kvm"))
- return 1;
+ if (STRCASEEQ(type, "kvm")) {
+ // KVM-30 added support for up to 4 vcpus
+ // KVM-62 raised this to 16
+ if (driver->kvmVersion < 30)
+ return 1;
+ else if (driver->kvmVersion < 62)
+ return 4;
+ else
+ return 16;
+ }
if (STRCASEEQ(type, "kqemu"))
return 1;
@@ -1690,7 +1704,7 @@ static virDomainPtr qemudDomainLookupByName(virConnectPtr conn,
static int qemudGetVersion(virConnectPtr conn, unsigned long *version) {
struct qemud_driver *driver = (struct qemud_driver *)conn->privateData;
- if (qemudExtractVersion(conn, driver) < 0)
+ if (qemudExtractVersion(driver) < 0)
return -1;
*version = qemu_driver->qemuVersion;
16 years, 6 months
[libvirt] [RFC] Publishing utilisation on mDNS
by Stefan de Konink
After playing around with Avahi, I have now a server that is able to query
all hosts on the network and their VMs, I think it would be interesting to
publish utilisation statistics in the Txt record of the service.
Of course one could login to a host and fetch the info, but I think it
would be (managementwise) interesting if the hosts would announce this
information.
The implication for libvirtd would be a thread that updates
lets say, per minute the avarage cpu load / free memory.
I might even go further and publish all resource statistics over mDNS.
Maybe people have ideas about this too, securitywise i'm not really
interested in the implications since I'm publishing it on a management
LAN.
Stefan
16 years, 6 months
[libvirt] PATCH: Support bootloaders in QEMU driver
by Daniel P. Berrange
The QEMU driver supports booting Xen guests via the Xenner hypervisor. For
such paravirtualized guests there is no regular BIOS, so the bootloader has
to be run on the host. Xenner defaults to pygrub, but since libvirt has a
generic syntax for bootloaders, we should use it. So this patch adds support
for the <bootloader> syntax in the QEMU drive, and passes this to Xenner via
the -bootloader arg.
The patch is overly large, because when we have a bootloader we need to skip
the kernel/initrd/cmdline/boot elements & thus caused alot of intrusive code
re-indentation .
b/tests/qemuxml2argvdata/qemuxml2argv-bootloader.args | 1
b/tests/qemuxml2argvdata/qemuxml2argv-bootloader.xml | 23 +
src/qemu_conf.c | 318 +++++++++---------
src/qemu_conf.h | 1
tests/qemuxml2argvtest.c | 1
tests/qemuxml2xmltest.c | 1
6 files changed, 200 insertions(+), 145 deletions(-)
Dan.
diff -r f6b693192cb2 src/qemu_conf.c
--- a/src/qemu_conf.c Mon May 12 09:51:07 2008 -0400
+++ b/src/qemu_conf.c Mon May 12 10:16:21 2008 -0400
@@ -1702,22 +1702,37 @@
xmlXPathFreeObject(obj);
+ /* Extract bootloader */
+ obj = xmlXPathEval(BAD_CAST "string(/domain/bootloader)", ctxt);
+ if ((obj != NULL) && (obj->type == XPATH_STRING) &&
+ (obj->stringval != NULL) && (obj->stringval[0] != 0)) {
+ strncpy(def->os.bootloader, (const char*)obj->stringval, sizeof(def->os.bootloader));
+ NUL_TERMINATE(def->os.bootloader);
+ xmlXPathFreeObject(obj);
+
+ /* Set a default OS type, since <type> is optional with bootloader */
+ strcpy(def->os.type, "xen");
+ }
+
/* Extract OS type info */
obj = xmlXPathEval(BAD_CAST "string(/domain/os/type[1])", ctxt);
if ((obj == NULL) || (obj->type != XPATH_STRING) ||
(obj->stringval == NULL) || (obj->stringval[0] == 0)) {
+ if (!def->os.type[0]) {
+ qemudReportError(conn, NULL, NULL, VIR_ERR_OS_TYPE,
+ "%s", _("no OS type"));
+ goto error;
+ }
+ } else {
+ strcpy(def->os.type, (const char *)obj->stringval);
+ xmlXPathFreeObject(obj);
+ }
+
+ if (!virCapabilitiesSupportsGuestOSType(driver->caps, def->os.type)) {
qemudReportError(conn, NULL, NULL, VIR_ERR_OS_TYPE,
- "%s", _("no OS type"));
- goto error;
- }
- if (!virCapabilitiesSupportsGuestOSType(driver->caps, (const char*)obj->stringval)) {
- qemudReportError(conn, NULL, NULL, VIR_ERR_OS_TYPE,
- "%s", obj->stringval);
- goto error;
- }
- strcpy(def->os.type, (const char *)obj->stringval);
- xmlXPathFreeObject(obj);
-
+ "%s", def->os.type);
+ goto error;
+ }
obj = xmlXPathEval(BAD_CAST "string(/domain/os/type[1]/@arch)", ctxt);
if ((obj == NULL) || (obj->type != XPATH_STRING) ||
@@ -1772,75 +1787,76 @@
xmlXPathFreeObject(obj);
- obj = xmlXPathEval(BAD_CAST "string(/domain/os/kernel[1])", ctxt);
- if ((obj != NULL) && (obj->type == XPATH_STRING) &&
- (obj->stringval != NULL) && (obj->stringval[0] != 0)) {
- if (strlen((const char *)obj->stringval) >= (PATH_MAX-1)) {
- qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
- "%s", _("kernel path too long"));
- goto error;
- }
- strcpy(def->os.kernel, (const char *)obj->stringval);
- }
- xmlXPathFreeObject(obj);
-
-
- obj = xmlXPathEval(BAD_CAST "string(/domain/os/initrd[1])", ctxt);
- if ((obj != NULL) && (obj->type == XPATH_STRING) &&
- (obj->stringval != NULL) && (obj->stringval[0] != 0)) {
- if (strlen((const char *)obj->stringval) >= (PATH_MAX-1)) {
- qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
- "%s", _("initrd path too long"));
- goto error;
- }
- strcpy(def->os.initrd, (const char *)obj->stringval);
- }
- xmlXPathFreeObject(obj);
-
-
- obj = xmlXPathEval(BAD_CAST "string(/domain/os/cmdline[1])", ctxt);
- if ((obj != NULL) && (obj->type == XPATH_STRING) &&
- (obj->stringval != NULL) && (obj->stringval[0] != 0)) {
- if (strlen((const char *)obj->stringval) >= (PATH_MAX-1)) {
- qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
- "%s", _("cmdline arguments too long"));
- goto error;
- }
- strcpy(def->os.cmdline, (const char *)obj->stringval);
- }
- xmlXPathFreeObject(obj);
-
-
- /* analysis of the disk devices */
- obj = xmlXPathEval(BAD_CAST "/domain/os/boot", ctxt);
- if ((obj != NULL) && (obj->type == XPATH_NODESET) &&
- (obj->nodesetval != NULL) && (obj->nodesetval->nodeNr >= 0)) {
- for (i = 0; i < obj->nodesetval->nodeNr && i < QEMUD_MAX_BOOT_DEVS ; i++) {
- if (!(prop = xmlGetProp(obj->nodesetval->nodeTab[i], BAD_CAST "dev")))
- continue;
- if (STREQ((char *)prop, "hd")) {
- def->os.bootDevs[def->os.nBootDevs++] = QEMUD_BOOT_DISK;
- } else if (STREQ((char *)prop, "fd")) {
- def->os.bootDevs[def->os.nBootDevs++] = QEMUD_BOOT_FLOPPY;
- } else if (STREQ((char *)prop, "cdrom")) {
- def->os.bootDevs[def->os.nBootDevs++] = QEMUD_BOOT_CDROM;
- } else if (STREQ((char *)prop, "network")) {
- def->os.bootDevs[def->os.nBootDevs++] = QEMUD_BOOT_NET;
- } else {
- qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
- _("unknown boot device \'%s\'"), (char*)prop);
- goto error;
- }
- xmlFree(prop);
- prop = NULL;
- }
- }
- xmlXPathFreeObject(obj);
- if (def->os.nBootDevs == 0) {
- def->os.nBootDevs = 1;
- def->os.bootDevs[0] = QEMUD_BOOT_DISK;
- }
-
+ if (!def->os.bootloader[0]) {
+ obj = xmlXPathEval(BAD_CAST "string(/domain/os/kernel[1])", ctxt);
+ if ((obj != NULL) && (obj->type == XPATH_STRING) &&
+ (obj->stringval != NULL) && (obj->stringval[0] != 0)) {
+ if (strlen((const char *)obj->stringval) >= (PATH_MAX-1)) {
+ qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
+ "%s", _("kernel path too long"));
+ goto error;
+ }
+ strcpy(def->os.kernel, (const char *)obj->stringval);
+ }
+ xmlXPathFreeObject(obj);
+
+
+ obj = xmlXPathEval(BAD_CAST "string(/domain/os/initrd[1])", ctxt);
+ if ((obj != NULL) && (obj->type == XPATH_STRING) &&
+ (obj->stringval != NULL) && (obj->stringval[0] != 0)) {
+ if (strlen((const char *)obj->stringval) >= (PATH_MAX-1)) {
+ qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
+ "%s", _("initrd path too long"));
+ goto error;
+ }
+ strcpy(def->os.initrd, (const char *)obj->stringval);
+ }
+ xmlXPathFreeObject(obj);
+
+
+ obj = xmlXPathEval(BAD_CAST "string(/domain/os/cmdline[1])", ctxt);
+ if ((obj != NULL) && (obj->type == XPATH_STRING) &&
+ (obj->stringval != NULL) && (obj->stringval[0] != 0)) {
+ if (strlen((const char *)obj->stringval) >= (PATH_MAX-1)) {
+ qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
+ "%s", _("cmdline arguments too long"));
+ goto error;
+ }
+ strcpy(def->os.cmdline, (const char *)obj->stringval);
+ }
+ xmlXPathFreeObject(obj);
+
+
+ /* analysis of the disk devices */
+ obj = xmlXPathEval(BAD_CAST "/domain/os/boot", ctxt);
+ if ((obj != NULL) && (obj->type == XPATH_NODESET) &&
+ (obj->nodesetval != NULL) && (obj->nodesetval->nodeNr >= 0)) {
+ for (i = 0; i < obj->nodesetval->nodeNr && i < QEMUD_MAX_BOOT_DEVS ; i++) {
+ if (!(prop = xmlGetProp(obj->nodesetval->nodeTab[i], BAD_CAST "dev")))
+ continue;
+ if (STREQ((char *)prop, "hd")) {
+ def->os.bootDevs[def->os.nBootDevs++] = QEMUD_BOOT_DISK;
+ } else if (STREQ((char *)prop, "fd")) {
+ def->os.bootDevs[def->os.nBootDevs++] = QEMUD_BOOT_FLOPPY;
+ } else if (STREQ((char *)prop, "cdrom")) {
+ def->os.bootDevs[def->os.nBootDevs++] = QEMUD_BOOT_CDROM;
+ } else if (STREQ((char *)prop, "network")) {
+ def->os.bootDevs[def->os.nBootDevs++] = QEMUD_BOOT_NET;
+ } else {
+ qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
+ _("unknown boot device \'%s\'"), (char*)prop);
+ goto error;
+ }
+ xmlFree(prop);
+ prop = NULL;
+ }
+ }
+ xmlXPathFreeObject(obj);
+ if (def->os.nBootDevs == 0) {
+ def->os.nBootDevs = 1;
+ def->os.bootDevs[0] = QEMUD_BOOT_DISK;
+ }
+ }
obj = xmlXPathEval(BAD_CAST "string(/domain/devices/emulator[1])", ctxt);
if ((obj == NULL) || (obj->type != XPATH_STRING) ||
@@ -2371,6 +2387,7 @@
(vm->def->os.kernel[0] ? 2 : 0) + /* kernel */
(vm->def->os.initrd[0] ? 2 : 0) + /* initrd */
(vm->def->os.cmdline[0] ? 2 : 0) + /* cmdline */
+ (vm->def->os.bootloader[0] ? 2 : 0) + /* bootloader */
(vm->def->graphicsType == QEMUD_GRAPHICS_VNC ? 2 :
(vm->def->graphicsType == QEMUD_GRAPHICS_SDL ? 0 : 1)) + /* graphics */
(vm->migrateFrom[0] ? 3 : 0); /* migrateFrom */
@@ -2438,47 +2455,54 @@
goto no_memory;
}
- for (i = 0 ; i < vm->def->os.nBootDevs ; i++) {
- switch (vm->def->os.bootDevs[i]) {
- case QEMUD_BOOT_CDROM:
- boot[i] = 'd';
- break;
- case QEMUD_BOOT_FLOPPY:
- boot[i] = 'a';
- break;
- case QEMUD_BOOT_DISK:
- boot[i] = 'c';
- break;
- case QEMUD_BOOT_NET:
- boot[i] = 'n';
- break;
- default:
- boot[i] = 'c';
- break;
- }
- }
- boot[vm->def->os.nBootDevs] = '\0';
- if (!((*argv)[++n] = strdup("-boot")))
- goto no_memory;
- if (!((*argv)[++n] = strdup(boot)))
- goto no_memory;
-
- if (vm->def->os.kernel[0]) {
- if (!((*argv)[++n] = strdup("-kernel")))
- goto no_memory;
- if (!((*argv)[++n] = strdup(vm->def->os.kernel)))
- goto no_memory;
- }
- if (vm->def->os.initrd[0]) {
- if (!((*argv)[++n] = strdup("-initrd")))
- goto no_memory;
- if (!((*argv)[++n] = strdup(vm->def->os.initrd)))
- goto no_memory;
- }
- if (vm->def->os.cmdline[0]) {
- if (!((*argv)[++n] = strdup("-append")))
- goto no_memory;
- if (!((*argv)[++n] = strdup(vm->def->os.cmdline)))
+ if (!vm->def->os.bootloader[0]) {
+ for (i = 0 ; i < vm->def->os.nBootDevs ; i++) {
+ switch (vm->def->os.bootDevs[i]) {
+ case QEMUD_BOOT_CDROM:
+ boot[i] = 'd';
+ break;
+ case QEMUD_BOOT_FLOPPY:
+ boot[i] = 'a';
+ break;
+ case QEMUD_BOOT_DISK:
+ boot[i] = 'c';
+ break;
+ case QEMUD_BOOT_NET:
+ boot[i] = 'n';
+ break;
+ default:
+ boot[i] = 'c';
+ break;
+ }
+ }
+ boot[vm->def->os.nBootDevs] = '\0';
+ if (!((*argv)[++n] = strdup("-boot")))
+ goto no_memory;
+ if (!((*argv)[++n] = strdup(boot)))
+ goto no_memory;
+
+ if (vm->def->os.kernel[0]) {
+ if (!((*argv)[++n] = strdup("-kernel")))
+ goto no_memory;
+ if (!((*argv)[++n] = strdup(vm->def->os.kernel)))
+ goto no_memory;
+ }
+ if (vm->def->os.initrd[0]) {
+ if (!((*argv)[++n] = strdup("-initrd")))
+ goto no_memory;
+ if (!((*argv)[++n] = strdup(vm->def->os.initrd)))
+ goto no_memory;
+ }
+ if (vm->def->os.cmdline[0]) {
+ if (!((*argv)[++n] = strdup("-append")))
+ goto no_memory;
+ if (!((*argv)[++n] = strdup(vm->def->os.cmdline)))
+ goto no_memory;
+ }
+ } else {
+ if (!((*argv)[++n] = strdup("-bootloader")))
+ goto no_memory;
+ if (!((*argv)[++n] = strdup(vm->def->os.bootloader)))
goto no_memory;
}
@@ -3809,6 +3833,8 @@
virBufferVSprintf(&buf, " <memory>%lu</memory>\n", def->maxmem);
virBufferVSprintf(&buf, " <currentMemory>%lu</currentMemory>\n", def->memory);
virBufferVSprintf(&buf, " <vcpu>%d</vcpu>\n", def->vcpus);
+ if (def->os.bootloader[0])
+ virBufferVSprintf(&buf, " <bootloader>%s</bootloader>\n", def->os.bootloader);
virBufferAddLit(&buf, " <os>\n");
if (def->virtType == QEMUD_VIRT_QEMU)
@@ -3817,30 +3843,32 @@
else
virBufferVSprintf(&buf, " <type>%s</type>\n", def->os.type);
- if (def->os.kernel[0])
- virBufferVSprintf(&buf, " <kernel>%s</kernel>\n", def->os.kernel);
- if (def->os.initrd[0])
- virBufferVSprintf(&buf, " <initrd>%s</initrd>\n", def->os.initrd);
- if (def->os.cmdline[0])
- virBufferVSprintf(&buf, " <cmdline>%s</cmdline>\n", def->os.cmdline);
-
- for (n = 0 ; n < def->os.nBootDevs ; n++) {
- const char *boottype = "hd";
- switch (def->os.bootDevs[n]) {
- case QEMUD_BOOT_FLOPPY:
- boottype = "fd";
- break;
- case QEMUD_BOOT_DISK:
- boottype = "hd";
- break;
- case QEMUD_BOOT_CDROM:
- boottype = "cdrom";
- break;
- case QEMUD_BOOT_NET:
- boottype = "network";
- break;
- }
- virBufferVSprintf(&buf, " <boot dev='%s'/>\n", boottype);
+ if (!def->os.bootloader[0]) {
+ if (def->os.kernel[0])
+ virBufferVSprintf(&buf, " <kernel>%s</kernel>\n", def->os.kernel);
+ if (def->os.initrd[0])
+ virBufferVSprintf(&buf, " <initrd>%s</initrd>\n", def->os.initrd);
+ if (def->os.cmdline[0])
+ virBufferVSprintf(&buf, " <cmdline>%s</cmdline>\n", def->os.cmdline);
+
+ for (n = 0 ; n < def->os.nBootDevs ; n++) {
+ const char *boottype = "hd";
+ switch (def->os.bootDevs[n]) {
+ case QEMUD_BOOT_FLOPPY:
+ boottype = "fd";
+ break;
+ case QEMUD_BOOT_DISK:
+ boottype = "hd";
+ break;
+ case QEMUD_BOOT_CDROM:
+ boottype = "cdrom";
+ break;
+ case QEMUD_BOOT_NET:
+ boottype = "network";
+ break;
+ }
+ virBufferVSprintf(&buf, " <boot dev='%s'/>\n", boottype);
+ }
}
virBufferAddLit(&buf, " </os>\n");
diff -r f6b693192cb2 src/qemu_conf.h
--- a/src/qemu_conf.h Mon May 12 09:51:07 2008 -0400
+++ b/src/qemu_conf.h Mon May 12 10:16:21 2008 -0400
@@ -270,6 +270,7 @@
char initrd[PATH_MAX];
char cmdline[PATH_MAX];
char binary[PATH_MAX];
+ char bootloader[PATH_MAX];
};
/* Guest VM main configuration */
diff -r f6b693192cb2 tests/qemuxml2argvdata/qemuxml2argv-bootloader.args
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/qemuxml2argvdata/qemuxml2argv-bootloader.args Mon May 12 10:16:21 2008 -0400
@@ -0,0 +1,1 @@
+/usr/bin/qemu-kvm -M xenner -m 214 -smp 1 -nographic -monitor pty -no-acpi -bootloader /usr/bin/pygrub -cdrom /dev/cdrom -net none -serial none -parallel none -usb
\ No newline at end of file
diff -r f6b693192cb2 tests/qemuxml2argvdata/qemuxml2argv-bootloader.xml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/qemuxml2argvdata/qemuxml2argv-bootloader.xml Mon May 12 10:16:21 2008 -0400
@@ -0,0 +1,23 @@
+<domain type='kvm'>
+ <name>QEMUGuest1</name>
+ <uuid>c7a5fdbd-edaf-9455-926a-d65c16db1809</uuid>
+ <memory>219200</memory>
+ <currentMemory>219200</currentMemory>
+ <vcpu>1</vcpu>
+ <bootloader>/usr/bin/pygrub</bootloader>
+ <os>
+ <type>xen</type>
+ </os>
+ <clock offset='utc'/>
+ <on_poweroff>destroy</on_poweroff>
+ <on_reboot>restart</on_reboot>
+ <on_crash>destroy</on_crash>
+ <devices>
+ <emulator>/usr/bin/qemu-kvm</emulator>
+ <disk type='block' device='cdrom'>
+ <source dev='/dev/cdrom'/>
+ <target dev='hdc' bus='ide'/>
+ <readonly/>
+ </disk>
+ </devices>
+</domain>
diff -r f6b693192cb2 tests/qemuxml2argvtest.c
--- a/tests/qemuxml2argvtest.c Mon May 12 09:51:07 2008 -0400
+++ b/tests/qemuxml2argvtest.c Mon May 12 10:16:21 2008 -0400
@@ -144,6 +144,7 @@
DO_TEST("boot-cdrom", 0);
DO_TEST("boot-network", 0);
DO_TEST("boot-floppy", 0);
+ DO_TEST("bootloader", 0);
DO_TEST("clock-utc", 0);
DO_TEST("clock-localtime", 0);
DO_TEST("disk-cdrom", 0);
diff -r f6b693192cb2 tests/qemuxml2xmltest.c
--- a/tests/qemuxml2xmltest.c Mon May 12 09:51:07 2008 -0400
+++ b/tests/qemuxml2xmltest.c Mon May 12 10:16:21 2008 -0400
@@ -97,6 +97,7 @@
DO_TEST("boot-cdrom");
DO_TEST("boot-network");
DO_TEST("boot-floppy");
+ DO_TEST("bootloader");
DO_TEST("clock-utc");
DO_TEST("clock-localtime");
DO_TEST("disk-cdrom");
--
|: Red Hat, Engineering, Boston -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 :|
16 years, 6 months
[libvirt] PATCH: Allow xen bus type for disks in QEMU driver
by Daniel P. Berrange
With the recent work to support -drive arg, the QEMU driver now supports
many types of bus for disks attached to VMs - ide, scsi, virtio. This patches
adds another type 'xen' for the Xen blkfront driver.
b/tests/qemuxml2argvdata/qemuxml2argv-disk-xenvbd.args | 1
b/tests/qemuxml2argvdata/qemuxml2argv-disk-xenvbd.xml | 35 +++++++++++++++++
src/qemu_conf.c | 8 ++-
src/qemu_conf.h | 1
src/util.c | 24 ++++-------
tests/qemuxml2xmltest.c | 1
6 files changed, 53 insertions(+), 17 deletions(-)
Dan.
diff -r f6b47c9986b9 src/qemu_conf.c
--- a/src/qemu_conf.c Sat May 10 12:57:20 2008 -0400
+++ b/src/qemu_conf.c Sat May 10 12:57:46 2008 -0400
@@ -667,7 +667,8 @@
if ((!device || STREQ((const char *)device, "disk")) &&
!STRPREFIX((const char *)target, "hd") &&
!STRPREFIX((const char *)target, "sd") &&
- !STRPREFIX((const char *)target, "vd")) {
+ !STRPREFIX((const char *)target, "vd") &&
+ !STRPREFIX((const char *)target, "xvd")) {
qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
_("Invalid harddisk device name: %s"), target);
goto error;
@@ -707,6 +708,8 @@
disk->bus = QEMUD_DISK_BUS_SCSI;
else if (STREQ((const char *)bus, "virtio"))
disk->bus = QEMUD_DISK_BUS_VIRTIO;
+ else if (STREQ((const char *)bus, "xen"))
+ disk->bus = QEMUD_DISK_BUS_XEN;
else {
qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
_("Invalid bus type: %s"), bus);
@@ -1435,7 +1438,8 @@
const char *busnames[] = { "ide",
(qemuIF ? "floppy" : "fdc"),
"scsi",
- "virtio" };
+ "virtio",
+ "xen"};
verify_true(ARRAY_CARDINALITY(busnames) == QEMUD_DISK_BUS_LAST);
return busnames[busId];
diff -r f6b47c9986b9 src/qemu_conf.h
--- a/src/qemu_conf.h Sat May 10 12:57:20 2008 -0400
+++ b/src/qemu_conf.h Sat May 10 12:57:46 2008 -0400
@@ -61,6 +61,7 @@
QEMUD_DISK_BUS_FDC,
QEMUD_DISK_BUS_SCSI,
QEMUD_DISK_BUS_VIRTIO,
+ QEMUD_DISK_BUS_XEN,
QEMUD_DISK_BUS_LAST
};
diff -r f6b47c9986b9 src/util.c
--- a/src/util.c Sat May 10 12:57:20 2008 -0400
+++ b/src/util.c Sat May 10 12:57:46 2008 -0400
@@ -779,23 +779,17 @@
const char *ptr = NULL;
int idx = 0;
- if (strlen(name) < 3)
+ if (!STRPREFIX(name, "fd") &&
+ !STRPREFIX(name, "hd") &&
+ !STRPREFIX(name, "vd") &&
+ !STRPREFIX(name, "sd") &&
+ !STRPREFIX(name, "xvd"))
return -1;
- switch (*name) {
- case 'f':
- case 'h':
- case 'v':
- case 's':
- break;
- default:
- return 0;
- }
-
- if (*(name + 1) != 'd')
- return -1;
-
- ptr = name+2;
+ if (STRPREFIX(name, "xvd"))
+ ptr = name+3;
+ else
+ ptr = name+2;
while (*ptr) {
idx = idx * 26;
diff -r f6b47c9986b9 tests/qemuxml2argvdata/qemuxml2argv-disk-xenvbd.args
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/qemuxml2argvdata/qemuxml2argv-disk-xenvbd.args Sat May 10 12:57:47 2008 -0400
@@ -0,0 +1,1 @@
+/usr/bin/qemu -M pc -m 214 -smp 1 -nographic -monitor pty -no-acpi -boot c -drive file=/dev/HostVG/QEMUGuest1,if=ide,index=0,boot=on -drive file=/dev/HostVG/QEMUGuest2,if=ide,media=cdrom,index=2 -drive file=/tmp/data.img,if=xen,index=0 -drive file=/tmp/logs.img,if=xen,index=6 -net none -serial none -parallel none -usb
\ No newline at end of file
diff -r f6b47c9986b9 tests/qemuxml2argvdata/qemuxml2argv-disk-xenvbd.xml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/qemuxml2argvdata/qemuxml2argv-disk-xenvbd.xml Sat May 10 12:57:47 2008 -0400
@@ -0,0 +1,35 @@
+<domain type='qemu'>
+ <name>QEMUGuest1</name>
+ <uuid>c7a5fdbd-edaf-9455-926a-d65c16db1809</uuid>
+ <memory>219200</memory>
+ <currentMemory>219200</currentMemory>
+ <vcpu>1</vcpu>
+ <os>
+ <type arch='i686' machine='pc'>hvm</type>
+ <boot dev='hd'/>
+ </os>
+ <clock offset='utc'/>
+ <on_poweroff>destroy</on_poweroff>
+ <on_reboot>restart</on_reboot>
+ <on_crash>destroy</on_crash>
+ <devices>
+ <emulator>/usr/bin/qemu</emulator>
+ <disk type='block' device='disk'>
+ <source dev='/dev/HostVG/QEMUGuest1'/>
+ <target dev='hda' bus='ide'/>
+ </disk>
+ <disk type='block' device='cdrom'>
+ <source dev='/dev/HostVG/QEMUGuest2'/>
+ <target dev='hdc' bus='ide'/>
+ <readonly/>
+ </disk>
+ <disk type='file' device='disk'>
+ <source file='/tmp/data.img'/>
+ <target dev='xvda' bus='xen'/>
+ </disk>
+ <disk type='file' device='disk'>
+ <source file='/tmp/logs.img'/>
+ <target dev='xvdg' bus='xen'/>
+ </disk>
+ </devices>
+</domain>
diff -r f6b47c9986b9 tests/qemuxml2xmltest.c
--- a/tests/qemuxml2xmltest.c Sat May 10 12:57:20 2008 -0400
+++ b/tests/qemuxml2xmltest.c Sat May 10 12:57:47 2008 -0400
@@ -102,6 +102,7 @@
DO_TEST("disk-cdrom");
DO_TEST("disk-floppy");
DO_TEST("disk-many");
+ DO_TEST("disk-xenvbd");
DO_TEST("graphics-vnc");
DO_TEST("graphics-sdl");
DO_TEST("input-usbmouse");
--
|: Red Hat, Engineering, Boston -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 :|
16 years, 6 months
[libvirt] PATCH: Allow Xen bus type for input devices in QEMU driver
by Daniel P. Berrange
The Xenner virtual machine supportes a bus type of 'xen' for input devices,
corresponding to the paravirtualized mouse device. QEMU currently rejects
any bus type which isn't ps2 or usb. This patch makes it allow 'xen' as a
valid bus type for Xenner guests.
b/tests/qemuxml2argvdata/qemuxml2argv-input-xen.args | 1
b/tests/qemuxml2argvdata/qemuxml2argv-input-xen.xml | 24 ++++++
src/qemu_conf.c | 72 ++++++++++++-------
src/qemu_conf.h | 3
src/qemu_driver.c | 2
tests/qemuxml2argvtest.c | 2
tests/qemuxml2xmltest.c | 1
7 files changed, 78 insertions(+), 27 deletions(-)
Dan.
diff -r f00771a60241 src/qemu_conf.c
--- a/src/qemu_conf.c Sat May 10 12:57:47 2008 -0400
+++ b/src/qemu_conf.c Sat May 10 13:00:01 2008 -0400
@@ -1365,6 +1365,7 @@
/* Parse the XML definition for a network interface */
static int qemudParseInputXML(virConnectPtr conn,
+ struct qemud_vm_def *vm,
struct qemud_vm_input_def *input,
xmlNodePtr node) {
xmlChar *type = NULL;
@@ -1391,26 +1392,46 @@
}
if (bus) {
- if (STREQ((const char*)bus, "ps2")) { /* Only allow mouse */
- if (input->type == QEMU_INPUT_TYPE_TABLET) {
- qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
- _("ps2 bus does not support %s input device"),
- (const char*)type);
- goto error;
- }
- input->bus = QEMU_INPUT_BUS_PS2;
- } else if (STREQ((const char *)bus, "usb")) { /* Allow mouse & keyboard */
- input->bus = QEMU_INPUT_BUS_USB;
- } else {
- qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
- _("unsupported input bus %s"), (const char*)bus);
- goto error;
- }
- } else {
- if (input->type == QEMU_INPUT_TYPE_MOUSE)
- input->bus = QEMU_INPUT_BUS_PS2;
- else
- input->bus = QEMU_INPUT_BUS_USB;
+ if (STREQ(vm->os.type, "hvm")) {
+ if (STREQ((const char*)bus, "ps2")) { /* Only allow mouse */
+ if (input->type == QEMU_INPUT_TYPE_TABLET) {
+ qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
+ _("ps2 bus does not support %s input device"),
+ (const char*)type);
+ goto error;
+ }
+ input->bus = QEMU_INPUT_BUS_PS2;
+ } else if (STREQ((const char *)bus, "usb")) { /* Allow mouse & tablet */
+ input->bus = QEMU_INPUT_BUS_USB;
+ } else {
+ qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
+ _("unsupported input bus %s"), (const char*)bus);
+ goto error;
+ }
+ } else {
+ if (STREQ((const char *)bus, "xen")) { /* Allow mouse only */
+ input->bus = QEMU_INPUT_BUS_XEN;
+ if (input->type == QEMU_INPUT_TYPE_TABLET) {
+ qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
+ _("xen bus does not support %s input device"),
+ (const char*)type);
+ goto error;
+ }
+ } else {
+ qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
+ _("unsupported input bus %s"), (const char*)bus);
+ goto error;
+ }
+ }
+ } else {
+ if (!strcmp(vm->os.type, "hvm")) {
+ if (input->type == QEMU_INPUT_TYPE_MOUSE)
+ input->bus = QEMU_INPUT_BUS_PS2;
+ else
+ input->bus = QEMU_INPUT_BUS_USB;
+ } else {
+ input->bus = QEMU_INPUT_BUS_XEN;
+ }
}
xmlFree(type);
@@ -1998,7 +2019,7 @@
"%s", _("failed to allocate space for input string"));
goto error;
}
- if (qemudParseInputXML(conn, input, obj->nodesetval->nodeTab[i]) < 0) {
+ if (qemudParseInputXML(conn, def, input, obj->nodesetval->nodeTab[i]) < 0) {
free(input);
goto error;
}
@@ -2852,7 +2873,7 @@
struct qemud_vm_device_def *
qemudParseVMDeviceDef(virConnectPtr conn,
- struct qemud_driver *driver ATTRIBUTE_UNUSED,
+ struct qemud_vm_def *def,
const char *xmlStr)
{
xmlDocPtr xml;
@@ -2880,7 +2901,7 @@
qemudParseInterfaceXML(conn, &(dev->data.net), node);
} else if (xmlStrEqual(node->name, BAD_CAST "input")) {
dev->type = QEMUD_DEVICE_DISK;
- qemudParseInputXML(conn, &(dev->data.input), node);
+ qemudParseInputXML(conn, def, &(dev->data.input), node);
} else if (xmlStrEqual(node->name, BAD_CAST "sound")) {
dev->type = QEMUD_DEVICE_SOUND;
qemudParseSoundXML(conn, &(dev->data.sound), node);
@@ -3950,14 +3971,15 @@
input = def->inputs;
while (input) {
- if (input->bus != QEMU_INPUT_BUS_PS2)
+ if (input->bus == QEMU_INPUT_BUS_USB)
virBufferVSprintf(&buf, " <input type='%s' bus='usb'/>\n",
input->type == QEMU_INPUT_TYPE_MOUSE ? "mouse" : "tablet");
input = input->next;
}
/* If graphics is enable, add implicit mouse */
if (def->graphicsType != QEMUD_GRAPHICS_NONE)
- virBufferAddLit(&buf, " <input type='mouse' bus='ps2'/>\n");
+ virBufferVSprintf(&buf, " <input type='mouse' bus='%s'/>\n",
+ STREQ(def->os.type, "hvm") ? "ps2" : "xen");
switch (def->graphicsType) {
case QEMUD_GRAPHICS_VNC:
diff -r f00771a60241 src/qemu_conf.h
--- a/src/qemu_conf.h Sat May 10 12:57:47 2008 -0400
+++ b/src/qemu_conf.h Sat May 10 13:00:01 2008 -0400
@@ -189,6 +189,7 @@
enum qemu_vm_input_bus {
QEMU_INPUT_BUS_PS2,
QEMU_INPUT_BUS_USB,
+ QEMU_INPUT_BUS_XEN,
};
struct qemud_vm_input_def {
@@ -474,7 +475,7 @@
struct qemud_vm_device_def *
qemudParseVMDeviceDef (virConnectPtr conn,
- struct qemud_driver *driver,
+ struct qemud_vm_def *def,
const char *xmlStr);
struct qemud_vm_def *
diff -r f00771a60241 src/qemu_driver.c
--- a/src/qemu_driver.c Sat May 10 12:57:47 2008 -0400
+++ b/src/qemu_driver.c Sat May 10 13:00:01 2008 -0400
@@ -2516,7 +2516,7 @@
return -1;
}
- dev = qemudParseVMDeviceDef(dom->conn, driver, xml);
+ dev = qemudParseVMDeviceDef(dom->conn, vm->def, xml);
if (dev == NULL) {
return -1;
}
diff -r f00771a60241 tests/qemuxml2argvdata/qemuxml2argv-input-xen.args
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/qemuxml2argvdata/qemuxml2argv-input-xen.args Sat May 10 13:00:01 2008 -0400
@@ -0,0 +1,1 @@
+/usr/bin/xenner -M xenner -m 214 -smp 1 -monitor pty -no-acpi -boot c -hda /dev/HostVG/QEMUGuest1 -net none -serial none -parallel none -usb -vnc :-5901
\ No newline at end of file
diff -r f00771a60241 tests/qemuxml2argvdata/qemuxml2argv-input-xen.xml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/qemuxml2argvdata/qemuxml2argv-input-xen.xml Sat May 10 13:00:01 2008 -0400
@@ -0,0 +1,24 @@
+<domain type='kvm'>
+ <name>QEMUGuest1</name>
+ <uuid>c7a5fdbd-edaf-9455-926a-d65c16db1809</uuid>
+ <memory>219200</memory>
+ <currentMemory>219200</currentMemory>
+ <vcpu>1</vcpu>
+ <os>
+ <type>xen</type>
+ <boot dev='hd'/>
+ </os>
+ <clock offset='utc'/>
+ <on_poweroff>destroy</on_poweroff>
+ <on_reboot>restart</on_reboot>
+ <on_crash>destroy</on_crash>
+ <devices>
+ <emulator>/usr/bin/xenner</emulator>
+ <disk type='block' device='disk'>
+ <source dev='/dev/HostVG/QEMUGuest1'/>
+ <target dev='hda' bus='ide'/>
+ </disk>
+ <input type='mouse' bus='xen'/>
+ <graphics type='vnc' port='-1'/>
+ </devices>
+</domain>
diff -r f00771a60241 tests/qemuxml2argvtest.c
--- a/tests/qemuxml2argvtest.c Sat May 10 12:57:47 2008 -0400
+++ b/tests/qemuxml2argvtest.c Sat May 10 13:00:01 2008 -0400
@@ -153,10 +153,12 @@
DO_TEST("disk-floppy", 0);
DO_TEST("disk-many", 0);
DO_TEST("disk-virtio", 1);
+ DO_TEST("disk-xenvbd", 1);
DO_TEST("graphics-vnc", 0);
DO_TEST("graphics-sdl", 0);
DO_TEST("input-usbmouse", 0);
DO_TEST("input-usbtablet", 0);
+ DO_TEST("input-xen", 0);
DO_TEST("misc-acpi", 0);
DO_TEST("misc-no-reboot", 0);
DO_TEST("net-user", 0);
diff -r f00771a60241 tests/qemuxml2xmltest.c
--- a/tests/qemuxml2xmltest.c Sat May 10 12:57:47 2008 -0400
+++ b/tests/qemuxml2xmltest.c Sat May 10 13:00:01 2008 -0400
@@ -107,6 +107,7 @@
DO_TEST("graphics-sdl");
DO_TEST("input-usbmouse");
DO_TEST("input-usbtablet");
+ DO_TEST("input-xen");
DO_TEST("misc-acpi");
DO_TEST("misc-no-reboot");
DO_TEST("net-user");
--
|: Red Hat, Engineering, Boston -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 :|
16 years, 6 months
[libvirt] PATCH: Fix default bus type selection for disks
by Daniel P. Berrange
We recently added a new bus type attribute to disks to select between IDE,
SCSI, etc. This attribute is optional and many tools won't set it. In such
cases we default to IDE, which is clearly wrong. This patch updates it to
pick the default bus based on the prefix of the disk target name, so that
it DWIM, eg hdXXX == IDE, sdXXX == SCSI, xvdXXX == Xen, etc.
qemu_conf.c | 16 +++++++++++++---
1 file changed, 13 insertions(+), 3 deletions(-)
Dan
diff -r 68901592c1ce src/qemu_conf.c
--- a/src/qemu_conf.c Sat May 10 13:18:35 2008 -0400
+++ b/src/qemu_conf.c Sat May 10 13:55:59 2008 -0400
@@ -698,10 +698,20 @@
}
if (!bus) {
- if (disk->device == QEMUD_DISK_FLOPPY)
+ if (disk->device == QEMUD_DISK_FLOPPY) {
disk->bus = QEMUD_DISK_BUS_FDC;
- else
- disk->bus = QEMUD_DISK_BUS_IDE;
+ } else {
+ if (STRPREFIX((const char *)target, "hd"))
+ disk->bus = QEMUD_DISK_BUS_IDE;
+ else if (STRPREFIX((const char *)target, "sd"))
+ disk->bus = QEMUD_DISK_BUS_SCSI;
+ else if (STRPREFIX((const char *)target, "vd"))
+ disk->bus = QEMUD_DISK_BUS_VIRTIO;
+ else if (STRPREFIX((const char *)target, "xvd"))
+ disk->bus = QEMUD_DISK_BUS_XEN;
+ else
+ disk->bus = QEMUD_DISK_BUS_IDE;
+ }
} else if (STREQ((const char *)bus, "ide"))
disk->bus = QEMUD_DISK_BUS_IDE;
else if (STREQ((const char *)bus, "fdc"))
--
|: Red Hat, Engineering, Boston -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 :|
16 years, 6 months