From 098ba1a433b8e61b75f4e41d216c55eec705b89c Mon Sep 17 00:00:00 2001 From: "Daniel P. Berrange" Date: Fri, 9 May 2008 16:41:19 +0000 Subject: [PATCH] Add support for -drive QEMU syntax, and virtio bus / disk type --- ChangeLog | 15 ++ bootstrap | 1 + gnulib/lib/.cvsignore | 14 +- gnulib/lib/Makefile.am | 8 +- gnulib/lib/c-ctype.c | 8 +- gnulib/lib/c-ctype.h | 8 +- gnulib/lib/verify.h | 2 +- gnulib/m4/gnulib-cache.m4 | 4 +- gnulib/m4/gnulib-comp.m4 | 2 +- gnulib/tests/Makefile.am | 6 - gnulib/tests/verify.h | 140 ------------ src/qemu_conf.c | 199 +++++++++++++++--- src/qemu_conf.h | 18 +- src/util.c | 41 ++++ src/util.h | 2 + .../qemuxml2argv-boot-cdrom.xml | 2 +- .../qemuxml2argv-boot-floppy.xml | 4 +- .../qemuxml2argv-boot-network.xml | 2 +- .../qemuxml2argv-clock-localtime.xml | 2 +- .../qemuxml2argv-clock-utc.xml | 2 +- .../qemuxml2argv-console-compat.xml | 2 +- .../qemuxml2argv-disk-cdrom.xml | 4 +- .../qemuxml2argv-disk-floppy.xml | 6 +- .../qemuxml2argv-disk-many.xml | 8 +- .../qemuxml2argv-disk-virtio.args | 1 + .../qemuxml2argv-disk-virtio.xml | 34 +++ .../qemuxml2argv-graphics-sdl.xml | 2 +- .../qemuxml2argv-graphics-vnc.xml | 2 +- .../qemuxml2argv-input-usbmouse.xml | 2 +- .../qemuxml2argv-input-usbtablet.xml | 2 +- .../qemuxml2argvdata/qemuxml2argv-minimal.xml | 2 +- .../qemuxml2argv-misc-acpi.xml | 2 +- .../qemuxml2argv-misc-no-reboot.xml | 2 +- .../qemuxml2argv-net-user.xml | 2 +- .../qemuxml2argv-net-virtio.xml | 2 +- .../qemuxml2argv-parallel-tcp.xml | 2 +- .../qemuxml2argv-serial-dev.xml | 2 +- .../qemuxml2argv-serial-file.xml | 2 +- .../qemuxml2argv-serial-many.xml | 2 +- .../qemuxml2argv-serial-pty.xml | 2 +- .../qemuxml2argv-serial-tcp-telnet.xml | 2 +- .../qemuxml2argv-serial-tcp.xml | 2 +- .../qemuxml2argv-serial-udp.xml | 2 +- .../qemuxml2argv-serial-unix.xml | 2 +- .../qemuxml2argv-serial-vc.xml | 2 +- tests/qemuxml2argvtest.c | 88 ++++---- 46 files changed, 386 insertions(+), 275 deletions(-) delete mode 100644 gnulib/tests/verify.h create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-disk-virtio.args create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-disk-virtio.xml diff --git a/ChangeLog b/ChangeLog index 4820a102ed..cd0409f7cc 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,18 @@ +Thu May 9 12:40:11 EST 2008 Daniel P. Berrange + + * bootstrap: Added verify module + * gnulib/lib/.cvsignore, gnulib/lib/Makefile.am: New verify module + * gnulib/lib/c-ctype.c, gnulib/lib/c-ctype.h: Refreshed + * gnulib/lib/verify.h: Refreshed upstream + * gnulib/m4/gnulib-cache.m4, gnulib/m4/gnulib-comp.m4, + gnulib/tests/Makefile.am: Refreshed with upstream + * gnulib/tests/verify.h: Removed + * src/qemu_conf.c, src/qemu_conf.h: Support -drive syntax and + support virtio, and add bus attribute + * src/util.c, src/util.h: helper for drive name to index convertor + * tests/qemuxml2argvtest.c: Added virtio test + * tests/qemuxml2argvdata/*.xml: Updated with bus attribute + Fri May 9 15:45:39 CEST 2008 Jim Meyering Add new files from gnulib. diff --git a/bootstrap b/bootstrap index acce4e86cf..bc1c352a1e 100755 --- a/bootstrap +++ b/bootstrap @@ -78,6 +78,7 @@ strsep sys_stat useless-if-before-free vasprintf +verify vc-list-files ' diff --git a/gnulib/lib/.cvsignore b/gnulib/lib/.cvsignore index 2849ca97d0..554c9fd0e2 100644 --- a/gnulib/lib/.cvsignore +++ b/gnulib/lib/.cvsignore @@ -1,18 +1,18 @@ -*.la -*.lo -.deps -.libs -Makefile -Makefile.in alloca.h arpa_inet.h +.deps float.h +*.la +.libs +*.lo +Makefile +Makefile.in netinet_in.h poll.h stdbool.h stdint.h -stdio-impl.h stdio.h +stdio-impl.h stdlib.h string.h sys_select.h diff --git a/gnulib/lib/Makefile.am b/gnulib/lib/Makefile.am index 1390c05286..8706bcb87a 100644 --- a/gnulib/lib/Makefile.am +++ b/gnulib/lib/Makefile.am @@ -9,7 +9,7 @@ # the same distribution terms as the rest of that program. # # Generated by gnulib-tool. -# Reproduce by: gnulib-tool --import --dir=. --lib=libgnu --source-base=gnulib/lib --m4-base=gnulib/m4 --doc-base=doc --aux-dir=build-aux --with-tests --lgpl=2 --libtool --macro-prefix=gl c-ctype getaddrinfo getpass gettext mktempd physmem poll posix-shell strndup strsep sys_stat useless-if-before-free vasprintf vc-list-files +# Reproduce by: gnulib-tool --import --dir=. --lib=libgnu --source-base=gnulib/lib --m4-base=gnulib/m4 --doc-base=doc --aux-dir=build-aux --with-tests --lgpl=2 --libtool --macro-prefix=gl c-ctype getaddrinfo getpass gettext mktempd physmem poll posix-shell strndup strsep sys_stat useless-if-before-free vasprintf vc-list-files verify AUTOMAKE_OPTIONS = 1.5 gnits @@ -769,6 +769,12 @@ EXTRA_DIST += $(top_srcdir)/build-aux/vc-list-files ## end gnulib module vc-list-files +## begin gnulib module verify + +libgnu_la_SOURCES += verify.h + +## end gnulib module verify + ## begin gnulib module wchar BUILT_SOURCES += $(WCHAR_H) diff --git a/gnulib/lib/c-ctype.c b/gnulib/lib/c-ctype.c index 36569b818e..1c685c549d 100644 --- a/gnulib/lib/c-ctype.c +++ b/gnulib/lib/c-ctype.c @@ -3,16 +3,16 @@ Copyright 2000-2003, 2006 Free Software Foundation, Inc. This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2 of the License, or +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 program 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 General Public License for more details. +GNU Lesser General Public License for more details. -You should have received a copy of the GNU General Public License +You should have received a copy of the GNU Lesser General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ diff --git a/gnulib/lib/c-ctype.h b/gnulib/lib/c-ctype.h index b26eccfb3d..1bd76a0f05 100644 --- a/gnulib/lib/c-ctype.h +++ b/gnulib/lib/c-ctype.h @@ -8,16 +8,16 @@ Copyright (C) 2000-2003, 2006 Free Software Foundation, Inc. This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2 of the License, or +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 program 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 General Public License for more details. +GNU Lesser General Public License for more details. -You should have received a copy of the GNU General Public License +You should have received a copy of the GNU Lesser General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ diff --git a/gnulib/lib/verify.h b/gnulib/lib/verify.h index e82fa02d9f..c1e1c3f10b 100644 --- a/gnulib/lib/verify.h +++ b/gnulib/lib/verify.h @@ -4,7 +4,7 @@ This program 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 3 of the License, or + the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, diff --git a/gnulib/m4/gnulib-cache.m4 b/gnulib/m4/gnulib-cache.m4 index 3c817e0338..04b3498912 100644 --- a/gnulib/m4/gnulib-cache.m4 +++ b/gnulib/m4/gnulib-cache.m4 @@ -15,11 +15,11 @@ # Specification in the form of a command-line invocation: -# gnulib-tool --import --dir=. --lib=libgnu --source-base=gnulib/lib --m4-base=gnulib/m4 --doc-base=doc --aux-dir=build-aux --with-tests --lgpl=2 --libtool --macro-prefix=gl c-ctype getaddrinfo getpass gettext mktempd physmem poll posix-shell strndup strsep sys_stat useless-if-before-free vasprintf vc-list-files +# gnulib-tool --import --dir=. --lib=libgnu --source-base=gnulib/lib --m4-base=gnulib/m4 --doc-base=doc --aux-dir=build-aux --with-tests --lgpl=2 --libtool --macro-prefix=gl c-ctype getaddrinfo getpass gettext mktempd physmem poll posix-shell strndup strsep sys_stat useless-if-before-free vasprintf vc-list-files verify # Specification in the form of a few gnulib-tool.m4 macro invocations: gl_LOCAL_DIR([]) -gl_MODULES([c-ctype getaddrinfo getpass gettext mktempd physmem poll posix-shell strndup strsep sys_stat useless-if-before-free vasprintf vc-list-files]) +gl_MODULES([c-ctype getaddrinfo getpass gettext mktempd physmem poll posix-shell strndup strsep sys_stat useless-if-before-free vasprintf vc-list-files verify]) gl_AVOID([]) gl_SOURCE_BASE([gnulib/lib]) gl_M4_BASE([gnulib/m4]) diff --git a/gnulib/m4/gnulib-comp.m4 b/gnulib/m4/gnulib-comp.m4 index d3a9ffcc65..6341bc2438 100644 --- a/gnulib/m4/gnulib-comp.m4 +++ b/gnulib/m4/gnulib-comp.m4 @@ -286,6 +286,7 @@ AC_DEFUN([gl_FILE_LIST], [ lib/vasnprintf.c lib/vasnprintf.h lib/vasprintf.c + lib/verify.h lib/wchar.in.h lib/xsize.h m4/alloca.m4 @@ -391,5 +392,4 @@ AC_DEFUN([gl_FILE_LIST], [ tests/test-wchar.c tests=lib/dummy.c tests=lib/intprops.h - tests=lib/verify.h ]) diff --git a/gnulib/tests/Makefile.am b/gnulib/tests/Makefile.am index c52f3733fa..6692c7f47e 100644 --- a/gnulib/tests/Makefile.am +++ b/gnulib/tests/Makefile.am @@ -265,12 +265,6 @@ EXTRA_DIST += test-vc-list-files-git.sh test-vc-list-files-cvs.sh ## end gnulib module vc-list-files-tests -## begin gnulib module verify - -libtests_a_SOURCES += verify.h - -## end gnulib module verify - ## begin gnulib module wchar-tests TESTS += test-wchar diff --git a/gnulib/tests/verify.h b/gnulib/tests/verify.h deleted file mode 100644 index fac53f6fc4..0000000000 --- a/gnulib/tests/verify.h +++ /dev/null @@ -1,140 +0,0 @@ -/* Compile-time assert-like macros. - - Copyright (C) 2005, 2006 Free Software Foundation, Inc. - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program 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 General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . */ - -/* Written by Paul Eggert, Bruno Haible, and Jim Meyering. */ - -#ifndef VERIFY_H -# define VERIFY_H 1 - -/* Each of these macros verifies that its argument R is nonzero. To - be portable, R should be an integer constant expression. Unlike - assert (R), there is no run-time overhead. - - There are two macros, since no single macro can be used in all - contexts in C. verify_true (R) is for scalar contexts, including - integer constant expression contexts. verify (R) is for declaration - contexts, e.g., the top level. - - Symbols ending in "__" are private to this header. - - The code below uses several ideas. - - * The first step is ((R) ? 1 : -1). Given an expression R, of - integral or boolean or floating-point type, this yields an - expression of integral type, whose value is later verified to be - constant and nonnegative. - - * Next this expression W is wrapped in a type - struct verify_type__ { unsigned int verify_error_if_negative_size__: W; }. - If W is negative, this yields a compile-time error. No compiler can - deal with a bit-field of negative size. - - One might think that an array size check would have the same - effect, that is, that the type struct { unsigned int dummy[W]; } - would work as well. However, inside a function, some compilers - (such as C++ compilers and GNU C) allow local parameters and - variables inside array size expressions. With these compilers, - an array size check would not properly diagnose this misuse of - the verify macro: - - void function (int n) { verify (n < 0); } - - * For the verify macro, the struct verify_type__ will need to - somehow be embedded into a declaration. To be portable, this - declaration must declare an object, a constant, a function, or a - typedef name. If the declared entity uses the type directly, - such as in - - struct dummy {...}; - typedef struct {...} dummy; - extern struct {...} *dummy; - extern void dummy (struct {...} *); - extern struct {...} *dummy (void); - - two uses of the verify macro would yield colliding declarations - if the entity names are not disambiguated. A workaround is to - attach the current line number to the entity name: - - #define GL_CONCAT0(x, y) x##y - #define GL_CONCAT(x, y) GL_CONCAT0 (x, y) - extern struct {...} * GL_CONCAT(dummy,__LINE__); - - But this has the problem that two invocations of verify from - within the same macro would collide, since the __LINE__ value - would be the same for both invocations. - - A solution is to use the sizeof operator. It yields a number, - getting rid of the identity of the type. Declarations like - - extern int dummy [sizeof (struct {...})]; - extern void dummy (int [sizeof (struct {...})]); - extern int (*dummy (void)) [sizeof (struct {...})]; - - can be repeated. - - * Should the implementation use a named struct or an unnamed struct? - Which of the following alternatives can be used? - - extern int dummy [sizeof (struct {...})]; - extern int dummy [sizeof (struct verify_type__ {...})]; - extern void dummy (int [sizeof (struct {...})]); - extern void dummy (int [sizeof (struct verify_type__ {...})]); - extern int (*dummy (void)) [sizeof (struct {...})]; - extern int (*dummy (void)) [sizeof (struct verify_type__ {...})]; - - In the second and sixth case, the struct type is exported to the - outer scope; two such declarations therefore collide. GCC warns - about the first, third, and fourth cases. So the only remaining - possibility is the fifth case: - - extern int (*dummy (void)) [sizeof (struct {...})]; - - * This implementation exploits the fact that GCC does not warn about - the last declaration mentioned above. If a future version of GCC - introduces a warning for this, the problem could be worked around - by using code specialized to GCC, e.g.,: - - #if 4 <= __GNUC__ - # define verify(R) \ - extern int (* verify_function__ (void)) \ - [__builtin_constant_p (R) && (R) ? 1 : -1] - #endif - - * In C++, any struct definition inside sizeof is invalid. - Use a template type to work around the problem. */ - - -/* Verify requirement R at compile-time, as an integer constant expression. - Return 1. */ - -# ifdef __cplusplus -template - struct verify_type__ { unsigned int verify_error_if_negative_size__: w; }; -# define verify_true(R) \ - (!!sizeof (verify_type__<(R) ? 1 : -1>)) -# else -# define verify_true(R) \ - (!!sizeof \ - (struct { unsigned int verify_error_if_negative_size__: (R) ? 1 : -1; })) -# endif - -/* Verify requirement R at compile-time, as a declaration without a - trailing ';'. */ - -# define verify(R) extern int (* verify_function__ (void)) [verify_true (R)] - -#endif diff --git a/src/qemu_conf.c b/src/qemu_conf.c index 643832bddd..2a29382e43 100644 --- a/src/qemu_conf.c +++ b/src/qemu_conf.c @@ -49,6 +49,7 @@ #include "buf.h" #include "conf.h" #include "util.h" +#include #define qemudLog(level, msg...) fprintf(stderr, msg) @@ -491,6 +492,10 @@ static int qemudExtractVersionInfo(const char *qemu, int *version, int *flags) { *flags |= QEMUD_CMD_FLAG_KQEMU; if (strstr(help, "-no-reboot")) *flags |= QEMUD_CMD_FLAG_NO_REBOOT; + if (strstr(help, "\n-drive")) + *flags |= QEMUD_CMD_FLAG_DRIVE_OPT; + if (strstr(help, "boot=on")) + *flags |= QEMUD_CMD_FLAG_DRIVE_BOOT_OPT; if (*version >= 9000) *flags |= QEMUD_CMD_FLAG_VNC_COLON; ret = 0; @@ -583,6 +588,7 @@ static int qemudParseDiskXML(virConnectPtr conn, xmlChar *source = NULL; xmlChar *target = NULL; xmlChar *type = NULL; + xmlChar *bus = NULL; int typ = 0; type = xmlGetProp(node, BAD_CAST "type"); @@ -613,6 +619,7 @@ static int qemudParseDiskXML(virConnectPtr conn, } else if ((target == NULL) && (xmlStrEqual(cur->name, BAD_CAST "target"))) { target = xmlGetProp(cur, BAD_CAST "dev"); + bus = xmlGetProp(cur, BAD_CAST "bus"); } else if (xmlStrEqual(cur->name, BAD_CAST "readonly")) { disk->readonly = 1; } @@ -658,10 +665,9 @@ static int qemudParseDiskXML(virConnectPtr conn, disk->readonly = 1; if ((!device || !strcmp((const char *)device, "disk")) && - strcmp((const char *)target, "hda") && - strcmp((const char *)target, "hdb") && - strcmp((const char *)target, "hdc") && - strcmp((const char *)target, "hdd")) { + strncmp((const char *)target, "hd", 2) && + strncmp((const char *)target, "sd", 2) && + strncmp((const char *)target, "vd", 2)) { qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR, _("Invalid harddisk device name: %s"), target); goto error; @@ -688,13 +694,41 @@ static int qemudParseDiskXML(virConnectPtr conn, goto error; } + if (!bus) { + if (disk->device == QEMUD_DISK_FLOPPY) + disk->bus = QEMUD_DISK_BUS_FDC; + 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")) + disk->bus = QEMUD_DISK_BUS_FDC; + else if (STREQ((const char *)bus, "scsi")) + disk->bus = QEMUD_DISK_BUS_SCSI; + else if (STREQ((const char *)bus, "virtio")) + disk->bus = QEMUD_DISK_BUS_VIRTIO; + else { + qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR, + _("Invalid bus type: %s"), bus); + goto error; + } + + if (disk->device == QEMUD_DISK_FLOPPY && + disk->bus != QEMUD_DISK_BUS_FDC) { + qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR, + _("Invalid bus type '%s' for floppy disk"), bus); + goto error; + } + xmlFree(device); xmlFree(target); xmlFree(source); + xmlFree(bus); return 0; error: + xmlFree(bus); xmlFree(type); xmlFree(target); xmlFree(source); @@ -1388,6 +1422,25 @@ static int qemudParseInputXML(virConnectPtr conn, return -1; } +static int qemudDiskCompare(const void *aptr, const void *bptr) { + struct qemud_vm_disk_def *a = (struct qemud_vm_disk_def *) aptr; + struct qemud_vm_disk_def *b = (struct qemud_vm_disk_def *) bptr; + if (a->bus == b->bus) + return virDiskNameToIndex(a->dst) - virDiskNameToIndex(b->dst); + else + return a->bus - b->bus; +} + +static const char *qemudBusIdToName(int busId, int qemuIF) { + const char *busnames[] = { "ide", + (qemuIF ? "floppy" : "fdc"), + "scsi", + "virtio" }; + verify_true(ARRAY_CARDINALITY(busnames) == QEMUD_DISK_BUS_LAST); + + return busnames[busId]; +} + /* Sound device helper functions */ static int qemudSoundModelFromString(const char *model) { if (STREQ(model, "sb16")) { @@ -1440,7 +1493,6 @@ static int qemudParseSoundXML(virConnectPtr conn, return err; } - /* * Parses a libvirt XML definition of a guest, and populates the * the qemud_vm struct with matching data about the guests config @@ -1832,7 +1884,6 @@ static struct qemud_vm_def *qemudParseXML(virConnectPtr conn, obj = xmlXPathEval(BAD_CAST "/domain/devices/disk", ctxt); if ((obj != NULL) && (obj->type == XPATH_NODESET) && (obj->nodesetval != NULL) && (obj->nodesetval->nodeNr >= 0)) { - struct qemud_vm_disk_def *prev = NULL; for (i = 0; i < obj->nodesetval->nodeNr; i++) { struct qemud_vm_disk_def *disk = calloc(1, sizeof(*disk)); if (!disk) { @@ -1845,13 +1896,20 @@ static struct qemud_vm_def *qemudParseXML(virConnectPtr conn, goto error; } def->ndisks++; - disk->next = NULL; if (i == 0) { + disk->next = NULL; def->disks = disk; } else { - prev->next = disk; + struct qemud_vm_disk_def *ptr = def->disks; + while (ptr) { + if (!ptr->next || qemudDiskCompare(disk, ptr->next) < 0) { + disk->next = ptr->next; + ptr->next = disk; + break; + } + ptr = ptr->next; + } } - prev = disk; } } xmlXPathFreeObject(obj); @@ -2292,7 +2350,7 @@ int qemudBuildCommandLine(virConnectPtr conn, snprintf(memory, sizeof(memory), "%lu", vm->def->memory/1024); snprintf(vcpus, sizeof(vcpus), "%d", vm->def->vcpus); - if (!(*argv = malloc(sizeof(**argv) * (len+1)))) + if (!(*argv = calloc(len+1, sizeof(**argv)))) goto no_memory; if (!((*argv)[++n] = strdup(vm->def->os.binary))) goto no_memory; @@ -2390,28 +2448,102 @@ int qemudBuildCommandLine(virConnectPtr conn, goto no_memory; } - while (disk) { - char dev[NAME_MAX]; - char file[PATH_MAX]; - if (!strcmp(disk->dst, "hdc") && - disk->device == QEMUD_DISK_CDROM) { - if (disk->src[0]) - snprintf(dev, NAME_MAX, "-%s", "cdrom"); - else { - /* Don't put anything on the cmdline for an empty cdrom*/ - disk = disk->next; - continue; + /* If QEMU supports -drive param instead of old -hda, -hdb, -cdrom .. */ + if (vm->qemuCmdFlags & QEMUD_CMD_FLAG_DRIVE_OPT) { + int bootCD = 0, bootFloppy = 0, bootDisk = 0; + + /* If QEMU supports boot=on for -drive param... */ + if (vm->qemuCmdFlags & QEMUD_CMD_FLAG_DRIVE_BOOT_OPT) { + for (i = 0 ; i < vm->def->os.nBootDevs ; i++) { + switch (vm->def->os.bootDevs[i]) { + case QEMUD_BOOT_CDROM: + bootCD = 1; + break; + case QEMUD_BOOT_FLOPPY: + bootFloppy = 1; + break; + case QEMUD_BOOT_DISK: + bootDisk = 1; + break; + } } - } else - snprintf(dev, NAME_MAX, "-%s", disk->dst); - snprintf(file, PATH_MAX, "%s", disk->src); + } - if (!((*argv)[++n] = strdup(dev))) - goto no_memory; - if (!((*argv)[++n] = strdup(file))) - goto no_memory; + while (disk) { + char opt[PATH_MAX]; + const char *media = NULL; + int bootable = 0; + int idx = virDiskNameToIndex(disk->dst); + if (!((*argv)[++n] = strdup("-drive"))) + goto no_memory; - disk = disk->next; + if (idx < 0) { + qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR, + _("unsupported disk type '%s'"), disk->dst); + goto error; + } + + if (disk->device == QEMUD_DISK_CDROM) + media = "media=cdrom,"; + + switch (disk->device) { + case QEMUD_DISK_CDROM: + bootable = bootCD; + bootCD = 0; + break; + case QEMUD_DISK_FLOPPY: + bootable = bootFloppy; + bootFloppy = 0; + break; + case QEMUD_DISK_DISK: + bootable = bootDisk; + bootDisk = 0; + break; + } + + snprintf(opt, PATH_MAX, "file=%s,if=%s,%sindex=%d%s", + disk->src, qemudBusIdToName(disk->bus, 1), + media ? media : "", + idx, + bootable ? ",boot=on" : ""); + + if (!((*argv)[++n] = strdup(opt))) + goto no_memory; + disk = disk->next; + } + } else { + while (disk) { + char dev[NAME_MAX]; + char file[PATH_MAX]; + + if (STREQ(disk->dst, "hdc") && + disk->device == QEMUD_DISK_CDROM) { + if (disk->src[0]) { + snprintf(dev, NAME_MAX, "-%s", "cdrom"); + } else { + disk = disk->next; + continue; + } + } else { + if (STRPREFIX(disk->dst, "hd") || + STRPREFIX(disk->dst, "fd")) { + snprintf(dev, NAME_MAX, "-%s", disk->dst); + } else { + qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR, + _("unsupported disk type '%s'"), disk->dst); + goto error; + } + } + + snprintf(file, PATH_MAX, "%s", disk->src); + + if (!((*argv)[++n] = strdup(dev))) + goto no_memory; + if (!((*argv)[++n] = strdup(file))) + goto no_memory; + + disk = disk->next; + } } if (!net) { @@ -2661,6 +2793,7 @@ int qemudBuildCommandLine(virConnectPtr conn, for (i = 0 ; i < n ; i++) free((*argv)[i]); free(*argv); + *argv = NULL; } return -1; } @@ -3518,10 +3651,7 @@ static int qemudGenerateXMLChar(virBufferPtr buf, "tcp", "unix" }; - /*verify(ARRAY_CARDINALITY(types) == QEMUD_CHR_SRC_TYPE_LAST);*/ - - if (dev->srcType < 0 || dev->srcType >= QEMUD_CHR_SRC_TYPE_LAST) - return -1; + verify_true(ARRAY_CARDINALITY(types) == QEMUD_CHR_SRC_TYPE_LAST); /* Compat with legacy syntax */ if (STREQ(type, "console") && @@ -3722,7 +3852,8 @@ char *qemudGenerateXML(virConnectPtr conn, virBufferVSprintf(&buf, " \n", typeAttrs[disk->type], disk->src); - virBufferVSprintf(&buf, " \n", disk->dst); + virBufferVSprintf(&buf, " \n", + disk->dst, qemudBusIdToName(disk->bus, 0)); if (disk->readonly) virBufferAddLit(&buf, " \n"); diff --git a/src/qemu_conf.h b/src/qemu_conf.h index 4745b07436..2c416288d2 100644 --- a/src/qemu_conf.h +++ b/src/qemu_conf.h @@ -56,10 +56,20 @@ enum qemud_vm_disk_device { QEMUD_DISK_FLOPPY, }; +enum qemud_vm_disk_bus { + QEMUD_DISK_BUS_IDE, + QEMUD_DISK_BUS_FDC, + QEMUD_DISK_BUS_SCSI, + QEMUD_DISK_BUS_VIRTIO, + + QEMUD_DISK_BUS_LAST +}; + /* Stores the virtual disk configuration */ struct qemud_vm_disk_def { int type; int device; + int bus; char src[PATH_MAX]; char dst[NAME_MAX]; int readonly; @@ -234,9 +244,11 @@ enum qemud_vm_graphics_type { /* Internal flags to keep track of qemu command line capabilities */ enum qemud_cmd_flags { - QEMUD_CMD_FLAG_KQEMU = 1, - QEMUD_CMD_FLAG_VNC_COLON = 2, - QEMUD_CMD_FLAG_NO_REBOOT = 4, + QEMUD_CMD_FLAG_KQEMU = (1 << 0), + QEMUD_CMD_FLAG_VNC_COLON = (1 << 1), + QEMUD_CMD_FLAG_NO_REBOOT = (1 << 2), + QEMUD_CMD_FLAG_DRIVE_OPT = (1 << 3), + QEMUD_CMD_FLAG_DRIVE_BOOT_OPT = (1 << 4), }; diff --git a/src/util.c b/src/util.c index f354a48e0e..39a1e2af9f 100644 --- a/src/util.c +++ b/src/util.c @@ -769,3 +769,44 @@ virParseMacAddr(const char* str, unsigned char *addr) return -1; } + +/* Translates a device name of the form (regex) "[fhv]d[a-z]+" into + * the corresponding index (e.g. sda => 1, hdz => 26, vdaa => 27) + * @param name The name of the device + * @return name's index, or -1 on failure + */ +int virDiskNameToIndex(const char *name) { + const char *ptr = NULL; + int idx = 0; + + if (strlen(name) < 3) + 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; + + while (*ptr) { + idx = idx * 26; + + if ('a' > *ptr || 'z' < *ptr) + return -1; + + idx += *ptr - 'a'; + ptr++; + } + + return idx; +} + diff --git a/src/util.h b/src/util.h index 2516504682..fde35f4bd6 100644 --- a/src/util.h +++ b/src/util.h @@ -87,4 +87,6 @@ int virParseNumber(const char **str); int virParseMacAddr(const char* str, unsigned char *addr); +int virDiskNameToIndex(const char* str); + #endif /* __VIR_UTIL_H__ */ diff --git a/tests/qemuxml2argvdata/qemuxml2argv-boot-cdrom.xml b/tests/qemuxml2argvdata/qemuxml2argv-boot-cdrom.xml index 26eeb39330..5211d0ce4c 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-boot-cdrom.xml +++ b/tests/qemuxml2argvdata/qemuxml2argv-boot-cdrom.xml @@ -16,7 +16,7 @@ /usr/bin/qemu - + diff --git a/tests/qemuxml2argvdata/qemuxml2argv-boot-floppy.xml b/tests/qemuxml2argvdata/qemuxml2argv-boot-floppy.xml index ed00c666dd..ad33b536ff 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-boot-floppy.xml +++ b/tests/qemuxml2argvdata/qemuxml2argv-boot-floppy.xml @@ -16,11 +16,11 @@ /usr/bin/qemu - + - + diff --git a/tests/qemuxml2argvdata/qemuxml2argv-boot-network.xml b/tests/qemuxml2argvdata/qemuxml2argv-boot-network.xml index 7ee75257a9..8d510a9fd5 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-boot-network.xml +++ b/tests/qemuxml2argvdata/qemuxml2argv-boot-network.xml @@ -16,7 +16,7 @@ /usr/bin/qemu - + diff --git a/tests/qemuxml2argvdata/qemuxml2argv-clock-localtime.xml b/tests/qemuxml2argvdata/qemuxml2argv-clock-localtime.xml index 351779da1d..dc1ae32fb2 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-clock-localtime.xml +++ b/tests/qemuxml2argvdata/qemuxml2argv-clock-localtime.xml @@ -16,7 +16,7 @@ /usr/bin/qemu - + diff --git a/tests/qemuxml2argvdata/qemuxml2argv-clock-utc.xml b/tests/qemuxml2argvdata/qemuxml2argv-clock-utc.xml index 816b16138c..26c9b25943 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-clock-utc.xml +++ b/tests/qemuxml2argvdata/qemuxml2argv-clock-utc.xml @@ -16,7 +16,7 @@ /usr/bin/qemu - + diff --git a/tests/qemuxml2argvdata/qemuxml2argv-console-compat.xml b/tests/qemuxml2argvdata/qemuxml2argv-console-compat.xml index 7752c02357..c16ae07f3a 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-console-compat.xml +++ b/tests/qemuxml2argvdata/qemuxml2argv-console-compat.xml @@ -16,7 +16,7 @@ /usr/bin/qemu - + diff --git a/tests/qemuxml2argvdata/qemuxml2argv-disk-cdrom.xml b/tests/qemuxml2argvdata/qemuxml2argv-disk-cdrom.xml index e3e5fbf51e..550136db18 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-disk-cdrom.xml +++ b/tests/qemuxml2argvdata/qemuxml2argv-disk-cdrom.xml @@ -16,11 +16,11 @@ /usr/bin/qemu - + - + diff --git a/tests/qemuxml2argvdata/qemuxml2argv-disk-floppy.xml b/tests/qemuxml2argvdata/qemuxml2argv-disk-floppy.xml index 37f1433416..9debdf4fcf 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-disk-floppy.xml +++ b/tests/qemuxml2argvdata/qemuxml2argv-disk-floppy.xml @@ -16,15 +16,15 @@ /usr/bin/qemu - + - + - + diff --git a/tests/qemuxml2argvdata/qemuxml2argv-disk-many.xml b/tests/qemuxml2argvdata/qemuxml2argv-disk-many.xml index 1ff0aa20d4..4abe88348b 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-disk-many.xml +++ b/tests/qemuxml2argvdata/qemuxml2argv-disk-many.xml @@ -16,19 +16,19 @@ /usr/bin/qemu - + - + - + - + diff --git a/tests/qemuxml2argvdata/qemuxml2argv-disk-virtio.args b/tests/qemuxml2argvdata/qemuxml2argv-disk-virtio.args new file mode 100644 index 0000000000..1edb6f84f5 --- /dev/null +++ b/tests/qemuxml2argvdata/qemuxml2argv-disk-virtio.args @@ -0,0 +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=virtio,index=0 -drive file=/tmp/logs.img,if=virtio,index=6 -net none -serial none -parallel none -usb \ No newline at end of file diff --git a/tests/qemuxml2argvdata/qemuxml2argv-disk-virtio.xml b/tests/qemuxml2argvdata/qemuxml2argv-disk-virtio.xml new file mode 100644 index 0000000000..bda44552a7 --- /dev/null +++ b/tests/qemuxml2argvdata/qemuxml2argv-disk-virtio.xml @@ -0,0 +1,34 @@ + + QEMUGuest1 + c7a5fdbd-edaf-9455-926a-d65c16db1809 + 219200 + 219200 + 1 + + hvm + + + + destroy + restart + destroy + + /usr/bin/qemu + + + + + + + + + + + + + + + + + + diff --git a/tests/qemuxml2argvdata/qemuxml2argv-graphics-sdl.xml b/tests/qemuxml2argvdata/qemuxml2argv-graphics-sdl.xml index 8c795d9cd0..87817c342c 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-graphics-sdl.xml +++ b/tests/qemuxml2argvdata/qemuxml2argv-graphics-sdl.xml @@ -16,7 +16,7 @@ /usr/bin/qemu - + diff --git a/tests/qemuxml2argvdata/qemuxml2argv-graphics-vnc.xml b/tests/qemuxml2argvdata/qemuxml2argv-graphics-vnc.xml index 2528a0e8c1..994433c319 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-graphics-vnc.xml +++ b/tests/qemuxml2argvdata/qemuxml2argv-graphics-vnc.xml @@ -16,7 +16,7 @@ /usr/bin/qemu - + diff --git a/tests/qemuxml2argvdata/qemuxml2argv-input-usbmouse.xml b/tests/qemuxml2argvdata/qemuxml2argv-input-usbmouse.xml index 1bbf890078..573015b4b8 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-input-usbmouse.xml +++ b/tests/qemuxml2argvdata/qemuxml2argv-input-usbmouse.xml @@ -16,7 +16,7 @@ /usr/bin/qemu - + diff --git a/tests/qemuxml2argvdata/qemuxml2argv-input-usbtablet.xml b/tests/qemuxml2argvdata/qemuxml2argv-input-usbtablet.xml index 2cfc174010..ea5769ad95 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-input-usbtablet.xml +++ b/tests/qemuxml2argvdata/qemuxml2argv-input-usbtablet.xml @@ -16,7 +16,7 @@ /usr/bin/qemu - + diff --git a/tests/qemuxml2argvdata/qemuxml2argv-minimal.xml b/tests/qemuxml2argvdata/qemuxml2argv-minimal.xml index 816b16138c..26c9b25943 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-minimal.xml +++ b/tests/qemuxml2argvdata/qemuxml2argv-minimal.xml @@ -16,7 +16,7 @@ /usr/bin/qemu - + diff --git a/tests/qemuxml2argvdata/qemuxml2argv-misc-acpi.xml b/tests/qemuxml2argvdata/qemuxml2argv-misc-acpi.xml index 759b6cf8f3..1b37bdc6f2 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-misc-acpi.xml +++ b/tests/qemuxml2argvdata/qemuxml2argv-misc-acpi.xml @@ -19,7 +19,7 @@ /usr/bin/qemu - + diff --git a/tests/qemuxml2argvdata/qemuxml2argv-misc-no-reboot.xml b/tests/qemuxml2argvdata/qemuxml2argv-misc-no-reboot.xml index 8d1d4b4e22..dc6193dd8e 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-misc-no-reboot.xml +++ b/tests/qemuxml2argvdata/qemuxml2argv-misc-no-reboot.xml @@ -16,7 +16,7 @@ /usr/bin/qemu - + diff --git a/tests/qemuxml2argvdata/qemuxml2argv-net-user.xml b/tests/qemuxml2argvdata/qemuxml2argv-net-user.xml index 6a2d256d50..630673a768 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-net-user.xml +++ b/tests/qemuxml2argvdata/qemuxml2argv-net-user.xml @@ -16,7 +16,7 @@ /usr/bin/qemu - + diff --git a/tests/qemuxml2argvdata/qemuxml2argv-net-virtio.xml b/tests/qemuxml2argvdata/qemuxml2argv-net-virtio.xml index 9c398ecae3..5d34bd492c 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-net-virtio.xml +++ b/tests/qemuxml2argvdata/qemuxml2argv-net-virtio.xml @@ -16,7 +16,7 @@ /usr/bin/qemu - + diff --git a/tests/qemuxml2argvdata/qemuxml2argv-parallel-tcp.xml b/tests/qemuxml2argvdata/qemuxml2argv-parallel-tcp.xml index e0fd51383e..08176f1c65 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-parallel-tcp.xml +++ b/tests/qemuxml2argvdata/qemuxml2argv-parallel-tcp.xml @@ -16,7 +16,7 @@ /usr/bin/qemu - + diff --git a/tests/qemuxml2argvdata/qemuxml2argv-serial-dev.xml b/tests/qemuxml2argvdata/qemuxml2argv-serial-dev.xml index fa371cc0ee..2b8ef5afb1 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-serial-dev.xml +++ b/tests/qemuxml2argvdata/qemuxml2argv-serial-dev.xml @@ -16,7 +16,7 @@ /usr/bin/qemu - + diff --git a/tests/qemuxml2argvdata/qemuxml2argv-serial-file.xml b/tests/qemuxml2argvdata/qemuxml2argv-serial-file.xml index 4a1bdc5df4..3726816bde 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-serial-file.xml +++ b/tests/qemuxml2argvdata/qemuxml2argv-serial-file.xml @@ -16,7 +16,7 @@ /usr/bin/qemu - + diff --git a/tests/qemuxml2argvdata/qemuxml2argv-serial-many.xml b/tests/qemuxml2argvdata/qemuxml2argv-serial-many.xml index 3b9f124d2f..444e85b56d 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-serial-many.xml +++ b/tests/qemuxml2argvdata/qemuxml2argv-serial-many.xml @@ -16,7 +16,7 @@ /usr/bin/qemu - + diff --git a/tests/qemuxml2argvdata/qemuxml2argv-serial-pty.xml b/tests/qemuxml2argvdata/qemuxml2argv-serial-pty.xml index 7752c02357..c16ae07f3a 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-serial-pty.xml +++ b/tests/qemuxml2argvdata/qemuxml2argv-serial-pty.xml @@ -16,7 +16,7 @@ /usr/bin/qemu - + diff --git a/tests/qemuxml2argvdata/qemuxml2argv-serial-tcp-telnet.xml b/tests/qemuxml2argvdata/qemuxml2argv-serial-tcp-telnet.xml index 77ac6a3f65..bea4306edc 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-serial-tcp-telnet.xml +++ b/tests/qemuxml2argvdata/qemuxml2argv-serial-tcp-telnet.xml @@ -16,7 +16,7 @@ /usr/bin/qemu - + diff --git a/tests/qemuxml2argvdata/qemuxml2argv-serial-tcp.xml b/tests/qemuxml2argvdata/qemuxml2argv-serial-tcp.xml index fe80d2d481..3bcf62da9a 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-serial-tcp.xml +++ b/tests/qemuxml2argvdata/qemuxml2argv-serial-tcp.xml @@ -16,7 +16,7 @@ /usr/bin/qemu - + diff --git a/tests/qemuxml2argvdata/qemuxml2argv-serial-udp.xml b/tests/qemuxml2argvdata/qemuxml2argv-serial-udp.xml index bdab917bbd..115166d4c8 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-serial-udp.xml +++ b/tests/qemuxml2argvdata/qemuxml2argv-serial-udp.xml @@ -16,7 +16,7 @@ /usr/bin/qemu - + diff --git a/tests/qemuxml2argvdata/qemuxml2argv-serial-unix.xml b/tests/qemuxml2argvdata/qemuxml2argv-serial-unix.xml index cc9626998b..4236b4c9ed 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-serial-unix.xml +++ b/tests/qemuxml2argvdata/qemuxml2argv-serial-unix.xml @@ -16,7 +16,7 @@ /usr/bin/qemu - + diff --git a/tests/qemuxml2argvdata/qemuxml2argv-serial-vc.xml b/tests/qemuxml2argvdata/qemuxml2argv-serial-vc.xml index b5d6d178d8..1e5de8f125 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-serial-vc.xml +++ b/tests/qemuxml2argvdata/qemuxml2argv-serial-vc.xml @@ -16,7 +16,7 @@ /usr/bin/qemu - + diff --git a/tests/qemuxml2argvtest.c b/tests/qemuxml2argvtest.c index 63abebeae8..2dabae7027 100644 --- a/tests/qemuxml2argvtest.c +++ b/tests/qemuxml2argvtest.c @@ -20,7 +20,7 @@ static struct qemud_driver driver; #define MAX_FILE 4096 -static int testCompareXMLToArgvFiles(const char *xml, const char *cmd) { +static int testCompareXMLToArgvFiles(const char *xml, const char *cmd, int driveFlag) { char xmlData[MAX_FILE]; char argvData[MAX_FILE]; char *xmlPtr = &(xmlData[0]); @@ -47,6 +47,10 @@ static int testCompareXMLToArgvFiles(const char *xml, const char *cmd) { vm.qemuVersion = 0 * 1000 * 100 + (8 * 1000) + 1; vm.qemuCmdFlags = QEMUD_CMD_FLAG_VNC_COLON | QEMUD_CMD_FLAG_NO_REBOOT; + if (driveFlag) { + vm.qemuCmdFlags |= QEMUD_CMD_FLAG_DRIVE_OPT; + vm.qemuCmdFlags |= QEMUD_CMD_FLAG_DRIVE_BOOT_OPT; + } vm.migrateFrom[0] = '\0'; vmdef->vncActivePort = vmdef->vncPort; @@ -94,14 +98,20 @@ static int testCompareXMLToArgvFiles(const char *xml, const char *cmd) { } +struct testInfo { + const char *name; + int driveFlag; +}; + static int testCompareXMLToArgvHelper(const void *data) { + const struct testInfo *info = data; char xml[PATH_MAX]; char args[PATH_MAX]; snprintf(xml, PATH_MAX, "%s/qemuxml2argvdata/qemuxml2argv-%s.xml", - abs_srcdir, (const char*)data); + abs_srcdir, info->name); snprintf(args, PATH_MAX, "%s/qemuxml2argvdata/qemuxml2argv-%s.args", - abs_srcdir, (const char*)data); - return testCompareXMLToArgvFiles(xml, args); + abs_srcdir, info->name); + return testCompareXMLToArgvFiles(xml, args, info->driveFlag); } @@ -125,41 +135,45 @@ main(int argc, char **argv) driver.caps = qemudCapsInit(); -#define DO_TEST(name) \ - if (virtTestRun("QEMU XML-2-ARGV " name, \ - 1, testCompareXMLToArgvHelper, (name)) < 0) \ - ret = -1 +#define DO_TEST(name, driveFlag) \ + do { \ + struct testInfo info = { name, driveFlag }; \ + if (virtTestRun("QEMU XML-2-ARGV " name, \ + 1, testCompareXMLToArgvHelper, &info) < 0) \ + ret = -1; \ + } while (0) - DO_TEST("minimal"); - DO_TEST("boot-cdrom"); - DO_TEST("boot-network"); - DO_TEST("boot-floppy"); - DO_TEST("clock-utc"); - DO_TEST("clock-localtime"); - DO_TEST("disk-cdrom"); - DO_TEST("disk-floppy"); - DO_TEST("disk-many"); - DO_TEST("graphics-vnc"); - DO_TEST("graphics-sdl"); - DO_TEST("input-usbmouse"); - DO_TEST("input-usbtablet"); - DO_TEST("misc-acpi"); - DO_TEST("misc-no-reboot"); - DO_TEST("net-user"); - DO_TEST("net-virtio"); + DO_TEST("minimal", 0); + DO_TEST("boot-cdrom", 0); + DO_TEST("boot-network", 0); + DO_TEST("boot-floppy", 0); + DO_TEST("clock-utc", 0); + DO_TEST("clock-localtime", 0); + DO_TEST("disk-cdrom", 0); + DO_TEST("disk-floppy", 0); + DO_TEST("disk-many", 0); + DO_TEST("disk-virtio", 1); + DO_TEST("graphics-vnc", 0); + DO_TEST("graphics-sdl", 0); + DO_TEST("input-usbmouse", 0); + DO_TEST("input-usbtablet", 0); + DO_TEST("misc-acpi", 0); + DO_TEST("misc-no-reboot", 0); + DO_TEST("net-user", 0); + DO_TEST("net-virtio", 0); - DO_TEST("serial-vc"); - DO_TEST("serial-pty"); - DO_TEST("serial-dev"); - DO_TEST("serial-file"); - DO_TEST("serial-unix"); - DO_TEST("serial-tcp"); - DO_TEST("serial-udp"); - DO_TEST("serial-tcp-telnet"); - DO_TEST("serial-many"); - DO_TEST("parallel-tcp"); - DO_TEST("console-compat"); - DO_TEST("sound"); + DO_TEST("serial-vc", 0); + DO_TEST("serial-pty", 0); + DO_TEST("serial-dev", 0); + DO_TEST("serial-file", 0); + DO_TEST("serial-unix", 0); + DO_TEST("serial-tcp", 0); + DO_TEST("serial-udp", 0); + DO_TEST("serial-tcp-telnet", 0); + DO_TEST("serial-many", 0); + DO_TEST("parallel-tcp", 0); + DO_TEST("console-compat", 0); + DO_TEST("sound", 0); virCapabilitiesFree(driver.caps);