]> xenbits.xensource.com Git - libvirt.git/commitdiff
Add support for -drive QEMU syntax, and virtio bus / disk type
authorDaniel P. Berrange <berrange@redhat.com>
Fri, 9 May 2008 16:41:19 +0000 (16:41 +0000)
committerDaniel P. Berrange <berrange@redhat.com>
Fri, 9 May 2008 16:41:19 +0000 (16:41 +0000)
46 files changed:
ChangeLog
bootstrap
gnulib/lib/.cvsignore
gnulib/lib/Makefile.am
gnulib/lib/c-ctype.c
gnulib/lib/c-ctype.h
gnulib/lib/verify.h
gnulib/m4/gnulib-cache.m4
gnulib/m4/gnulib-comp.m4
gnulib/tests/Makefile.am
gnulib/tests/verify.h [deleted file]
src/qemu_conf.c
src/qemu_conf.h
src/util.c
src/util.h
tests/qemuxml2argvdata/qemuxml2argv-boot-cdrom.xml
tests/qemuxml2argvdata/qemuxml2argv-boot-floppy.xml
tests/qemuxml2argvdata/qemuxml2argv-boot-network.xml
tests/qemuxml2argvdata/qemuxml2argv-clock-localtime.xml
tests/qemuxml2argvdata/qemuxml2argv-clock-utc.xml
tests/qemuxml2argvdata/qemuxml2argv-console-compat.xml
tests/qemuxml2argvdata/qemuxml2argv-disk-cdrom.xml
tests/qemuxml2argvdata/qemuxml2argv-disk-floppy.xml
tests/qemuxml2argvdata/qemuxml2argv-disk-many.xml
tests/qemuxml2argvdata/qemuxml2argv-disk-virtio.args [new file with mode: 0644]
tests/qemuxml2argvdata/qemuxml2argv-disk-virtio.xml [new file with mode: 0644]
tests/qemuxml2argvdata/qemuxml2argv-graphics-sdl.xml
tests/qemuxml2argvdata/qemuxml2argv-graphics-vnc.xml
tests/qemuxml2argvdata/qemuxml2argv-input-usbmouse.xml
tests/qemuxml2argvdata/qemuxml2argv-input-usbtablet.xml
tests/qemuxml2argvdata/qemuxml2argv-minimal.xml
tests/qemuxml2argvdata/qemuxml2argv-misc-acpi.xml
tests/qemuxml2argvdata/qemuxml2argv-misc-no-reboot.xml
tests/qemuxml2argvdata/qemuxml2argv-net-user.xml
tests/qemuxml2argvdata/qemuxml2argv-net-virtio.xml
tests/qemuxml2argvdata/qemuxml2argv-parallel-tcp.xml
tests/qemuxml2argvdata/qemuxml2argv-serial-dev.xml
tests/qemuxml2argvdata/qemuxml2argv-serial-file.xml
tests/qemuxml2argvdata/qemuxml2argv-serial-many.xml
tests/qemuxml2argvdata/qemuxml2argv-serial-pty.xml
tests/qemuxml2argvdata/qemuxml2argv-serial-tcp-telnet.xml
tests/qemuxml2argvdata/qemuxml2argv-serial-tcp.xml
tests/qemuxml2argvdata/qemuxml2argv-serial-udp.xml
tests/qemuxml2argvdata/qemuxml2argv-serial-unix.xml
tests/qemuxml2argvdata/qemuxml2argv-serial-vc.xml
tests/qemuxml2argvtest.c

index 4820a102edeabacdf4aaf00fe81884ecb92f2808..cd0409f7cc24a112d94848604deccefda173d15c 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,18 @@
+Thu May  9 12:40:11 EST 2008 Daniel P. Berrange <berrange@redhat.com>
+
+       * 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 <meyering@redhat.com>
 
        Add new files from gnulib.
index acce4e86cf661dcd45d77ae31dcfa468797d0d04..bc1c352a1e599a3092f63e89dae66bcaa583587d 100755 (executable)
--- a/bootstrap
+++ b/bootstrap
@@ -78,6 +78,7 @@ strsep
 sys_stat
 useless-if-before-free
 vasprintf
+verify
 vc-list-files
 '
 
index 2849ca97d0212fc31b009aefe282269b51205e02..554c9fd0e29c9046adedd3e5d365d3c9fd29aa50 100644 (file)
@@ -1,18 +1,18 @@
-*.la
-*.lo
+alloca.h
+arpa_inet.h
 .deps
+float.h
+*.la
 .libs
+*.lo
 Makefile
 Makefile.in
-alloca.h
-arpa_inet.h
-float.h
 netinet_in.h
 poll.h
 stdbool.h
 stdint.h
-stdio-impl.h
 stdio.h
+stdio-impl.h
 stdlib.h
 string.h
 sys_select.h
index 1390c05286be56a40848361930050fcc1190bdf6..8706bcb87aaa06f6ddd696f1f51802a9a687a7ad 100644 (file)
@@ -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)
index 36569b818e3b7cb25878e1795b325f4874c26b00..1c685c549d99665807a8b835ca1748aa595d8c72 100644 (file)
@@ -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.  */
 
index b26eccfb3d1df818013f7b62562cc20a393f9798..1bd76a0f054d43b80b23cb67548ae351c9919d37 100644 (file)
@@ -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.  */
 
index e82fa02d9f49c9ef2b9fb792b7ca735627d08265..c1e1c3f10b7a08bed664c8a709f200b1d70a78f3 100644 (file)
@@ -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,
index 3c817e033837b86fa74e2b0177e173ca922fcffb..04b349891206b44e898b54d31091bb190c1055b7 100644 (file)
 
 
 # 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])
index d3a9ffcc6501f45ff9217056e51bdb0e8bef7314..6341bc2438154600e81ef661d0098bd73b4cf3c4 100644 (file)
@@ -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
 ])
index c52f3733fa279223b691f486174e6960cd6ac3cb..6692c7f47ed0e84f34c27bcbc8504c607f0fe741 100644 (file)
@@ -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 (file)
index fac53f6..0000000
+++ /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 <http://www.gnu.org/licenses/>.  */
-
-/* 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 <int w>
-  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
index 643832bddd495c5df190a8adc8dfed6f95854418..2a29382e43794e735672aa01dc9e95c8d0f1f78a 100644 (file)
@@ -49,6 +49,7 @@
 #include "buf.h"
 #include "conf.h"
 #include "util.h"
+#include <verify.h>
 
 #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  <console tty='/dev/pts/5'/> syntax */
     if (STREQ(type, "console") &&
@@ -3722,7 +3852,8 @@ char *qemudGenerateXML(virConnectPtr conn,
             virBufferVSprintf(&buf, "      <source %s='%s'/>\n",
                               typeAttrs[disk->type], disk->src);
 
-        virBufferVSprintf(&buf, "      <target dev='%s'/>\n", disk->dst);
+        virBufferVSprintf(&buf, "      <target dev='%s' bus='%s'/>\n",
+                          disk->dst, qemudBusIdToName(disk->bus, 0));
 
         if (disk->readonly)
             virBufferAddLit(&buf, "      <readonly/>\n");
index 4745b074367d1ea9887d717f8cafce2750cc7b3f..2c416288d2309436c8ca17384c530de027254dc3 100644 (file)
@@ -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),
 };
 
 
index f354a48e0edc4f449e718c9b46d6ae05e5a06c8f..39a1e2af9f827d98a0d86838c4b22e6f1b5d63fa 100644 (file)
@@ -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;
+}
+
index 25165046821efdebcb854862a5ed7256c5a66a3f..fde35f4bd628d3284389a87cdcf723640adda4ea 100644 (file)
@@ -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__ */
index 26eeb393307a57619f74033d65b50c51dd1a1085..5211d0ce4cf84c70ba39ebfd1aa54eb68d85fb59 100644 (file)
@@ -16,7 +16,7 @@
     <emulator>/usr/bin/qemu</emulator>
     <disk type='block' device='cdrom'>
       <source dev='/dev/cdrom'/>
-      <target dev='hdc'/>
+      <target dev='hdc' bus='ide'/>
       <readonly/>
     </disk>
   </devices>
index ed00c666dd4c9e4a604539e995d5bfed5cd67813..ad33b536ffd82374129f98a835ff9b54f3790efb 100644 (file)
     <emulator>/usr/bin/qemu</emulator>
     <disk type='block' device='disk'>
       <source dev='/dev/HostVG/QEMUGuest1'/>
-      <target dev='hda'/>
+      <target dev='hda' bus='ide'/>
     </disk>
     <disk type='file' device='floppy'>
       <source file='/tmp/firmware.img'/>
-      <target dev='fda'/>
+      <target dev='fda' bus='fdc'/>
     </disk>
   </devices>
 </domain>
index 7ee75257a9b3cffa15131877fd9e482722670ec8..8d510a9fd54c9093c4f84b477ed8eff3f57506d1 100644 (file)
@@ -16,7 +16,7 @@
     <emulator>/usr/bin/qemu</emulator>
     <disk type='block' device='disk'>
       <source dev='/dev/HostVG/QEMUGuest1'/>
-      <target dev='hda'/>
+      <target dev='hda' bus='ide'/>
     </disk>
   </devices>
 </domain>
index 351779da1dbe55f90793d062832b402d2f4ea0f2..dc1ae32fb24e543973fb841f43b1086f117c0ec8 100644 (file)
@@ -16,7 +16,7 @@
     <emulator>/usr/bin/qemu</emulator>
     <disk type='block' device='disk'>
       <source dev='/dev/HostVG/QEMUGuest1'/>
-      <target dev='hda'/>
+      <target dev='hda' bus='ide'/>
     </disk>
   </devices>
 </domain>
index 816b16138c3a3e86d37a296634df06b522e01bff..26c9b259431d75a0720cc8b2f1b2e3056ac72965 100644 (file)
@@ -16,7 +16,7 @@
     <emulator>/usr/bin/qemu</emulator>
     <disk type='block' device='disk'>
       <source dev='/dev/HostVG/QEMUGuest1'/>
-      <target dev='hda'/>
+      <target dev='hda' bus='ide'/>
     </disk>
   </devices>
 </domain>
index 7752c023579a3d051d5336ac0bcabb86952e48d7..c16ae07f3af50aeb7dd766f889a748554901bff8 100644 (file)
@@ -16,7 +16,7 @@
     <emulator>/usr/bin/qemu</emulator>
     <disk type='block' device='disk'>
       <source dev='/dev/HostVG/QEMUGuest1'/>
-      <target dev='hda'/>
+      <target dev='hda' bus='ide'/>
     </disk>
     <serial type='pty'>
       <target port='0'/>
index e3e5fbf51e0f1f8b01746eab11cb714fa3742ac5..550136db1858978961c98e90c45e015c152c24a9 100644 (file)
     <emulator>/usr/bin/qemu</emulator>
     <disk type='block' device='disk'>
       <source dev='/dev/HostVG/QEMUGuest1'/>
-      <target dev='hda'/>
+      <target dev='hda' bus='ide'/>
     </disk>
     <disk type='file' device='cdrom'>
       <source file='/root/boot.iso'/>
-      <target dev='hdc'/>
+      <target dev='hdc' bus='ide'/>
       <readonly/>
     </disk>
   </devices>
index 37f1433416475748b345ff9fd7f72fe2ba84be3f..9debdf4fcf8659f2e22068829bbf0aa3166394c9 100644 (file)
     <emulator>/usr/bin/qemu</emulator>
     <disk type='block' device='disk'>
       <source dev='/dev/HostVG/QEMUGuest1'/>
-      <target dev='hda'/>
+      <target dev='hda' bus='ide'/>
     </disk>
     <disk type='block' device='floppy'>
       <source dev='/dev/fd0'/>
-      <target dev='fda'/>
+      <target dev='fda' bus='fdc'/>
     </disk>
     <disk type='file' device='floppy'>
       <source file='/tmp/firmware.img'/>
-      <target dev='fdb'/>
+      <target dev='fdb' bus='fdc'/>
     </disk>
   </devices>
 </domain>
index 1ff0aa20d471931dc5176cdd38930c5627153f99..4abe88348bb5d647fb96a6526eeb31ad7d1be140 100644 (file)
     <emulator>/usr/bin/qemu</emulator>
     <disk type='block' device='disk'>
       <source dev='/dev/HostVG/QEMUGuest1'/>
-      <target dev='hda'/>
+      <target dev='hda' bus='ide'/>
     </disk>
     <disk type='block' device='disk'>
       <source dev='/dev/HostVG/QEMUGuest2'/>
-      <target dev='hdb'/>
+      <target dev='hdb' bus='ide'/>
     </disk>
     <disk type='file' device='disk'>
       <source file='/tmp/data.img'/>
-      <target dev='hdc'/>
+      <target dev='hdc' bus='ide'/>
     </disk>
     <disk type='file' device='disk'>
       <source file='/tmp/logs.img'/>
-      <target dev='hdd'/>
+      <target dev='hdd' bus='ide'/>
     </disk>
   </devices>
 </domain>
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-disk-virtio.args b/tests/qemuxml2argvdata/qemuxml2argv-disk-virtio.args
new file mode 100644 (file)
index 0000000..1edb6f8
--- /dev/null
@@ -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 (file)
index 0000000..bda4455
--- /dev/null
@@ -0,0 +1,34 @@
+<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'/>
+    </disk>
+    <disk type='file' device='disk'>
+      <source file='/tmp/data.img'/>
+      <target dev='vda' bus='virtio'/>
+    </disk>
+    <disk type='file' device='disk'>
+      <source file='/tmp/logs.img'/>
+      <target dev='vdg' bus='virtio'/>
+    </disk>
+  </devices>
+</domain>
index 8c795d9cd04acfc51357db57aee3e013dfc7a4b4..87817c342c8b66c681124381476d21edc272b816 100644 (file)
@@ -16,7 +16,7 @@
     <emulator>/usr/bin/qemu</emulator>
     <disk type='block' device='disk'>
       <source dev='/dev/HostVG/QEMUGuest1'/>
-      <target dev='hda'/>
+      <target dev='hda' bus='ide'/>
     </disk>
     <input type='mouse' bus='ps2'/>
     <graphics type='sdl'/>
index 2528a0e8c1f9ca54d8114f9abf8d369d00b128f0..994433c3199d3c4e10de5c74b92961c54f386761 100644 (file)
@@ -16,7 +16,7 @@
     <emulator>/usr/bin/qemu</emulator>
     <disk type='block' device='disk'>
       <source dev='/dev/HostVG/QEMUGuest1'/>
-      <target dev='hda'/>
+      <target dev='hda' bus='ide'/>
     </disk>
     <input type='mouse' bus='ps2'/>
     <graphics type='vnc' port='5903' listen='127.0.0.1'/>
index 1bbf890078985dda6e222fee60334fdb343a3cad..573015b4b84dedc2ca5fec5e2dbf0ce1817f43e4 100644 (file)
@@ -16,7 +16,7 @@
     <emulator>/usr/bin/qemu</emulator>
     <disk type='block' device='disk'>
       <source dev='/dev/HostVG/QEMUGuest1'/>
-      <target dev='hda'/>
+      <target dev='hda' bus='ide'/>
     </disk>
     <input type='mouse' bus='usb'/>
   </devices>
index 2cfc17401021781d1e596bfb0792c2e4776052c0..ea5769ad9584d56f280557e1cbabc609ea48cf3c 100644 (file)
@@ -16,7 +16,7 @@
     <emulator>/usr/bin/qemu</emulator>
     <disk type='block' device='disk'>
       <source dev='/dev/HostVG/QEMUGuest1'/>
-      <target dev='hda'/>
+      <target dev='hda' bus='ide'/>
     </disk>
     <input type='tablet' bus='usb'/>
   </devices>
index 816b16138c3a3e86d37a296634df06b522e01bff..26c9b259431d75a0720cc8b2f1b2e3056ac72965 100644 (file)
@@ -16,7 +16,7 @@
     <emulator>/usr/bin/qemu</emulator>
     <disk type='block' device='disk'>
       <source dev='/dev/HostVG/QEMUGuest1'/>
-      <target dev='hda'/>
+      <target dev='hda' bus='ide'/>
     </disk>
   </devices>
 </domain>
index 759b6cf8f337809a03fda51e66dc50f969e79b10..1b37bdc6f21614e3de543280e89163d023caf633 100644 (file)
@@ -19,7 +19,7 @@
     <emulator>/usr/bin/qemu</emulator>
     <disk type='block' device='disk'>
       <source dev='/dev/HostVG/QEMUGuest1'/>
-      <target dev='hda'/>
+      <target dev='hda' bus='ide'/>
     </disk>
   </devices>
 </domain>
index 8d1d4b4e22390fc590f38f660b144db1a54881c1..dc6193dd8e322013a8203a26d767c34793c97260 100644 (file)
@@ -16,7 +16,7 @@
     <emulator>/usr/bin/qemu</emulator>
     <disk type='block' device='disk'>
       <source dev='/dev/HostVG/QEMUGuest1'/>
-      <target dev='hda'/>
+      <target dev='hda' bus='ide'/>
     </disk>
   </devices>
 </domain>
index 6a2d256d50fe60684854f42bcf4b16daba7448ce..630673a7681341d6ea97db3b0f98c9c92952e217 100644 (file)
@@ -16,7 +16,7 @@
     <emulator>/usr/bin/qemu</emulator>
     <disk type='block' device='disk'>
       <source dev='/dev/HostVG/QEMUGuest1'/>
-      <target dev='hda'/>
+      <target dev='hda' bus='ide'/>
     </disk>
     <interface type='user'>
       <mac address='00:11:22:33:44:55'/>
index 9c398ecae36f559b43249479e317fc4dee74bff9..5d34bd492c73df8625a6f15fb728c5702fbd6dfe 100644 (file)
@@ -16,7 +16,7 @@
     <emulator>/usr/bin/qemu</emulator>
     <disk type='block' device='disk'>
       <source dev='/dev/HostVG/QEMUGuest1'/>
-      <target dev='hda'/>
+      <target dev='hda' bus='ide'/>
     </disk>
     <interface type='user'>
       <mac address='00:11:22:33:44:55'/>
index e0fd51383ef424214a229891caa3eac0776346cb..08176f1c6536b30f17c38d9538d2dc3c1484e266 100644 (file)
@@ -16,7 +16,7 @@
     <emulator>/usr/bin/qemu</emulator>
     <disk type='block' device='disk'>
       <source dev='/dev/HostVG/QEMUGuest1'/>
-      <target dev='hda'/>
+      <target dev='hda' bus='ide'/>
     </disk>
     <parallel type='tcp'>
       <source mode='bind' host='127.0.0.1' service='9999'/>
index fa371cc0ee92d1f17518fe6e623be8213f1fc0ca..2b8ef5afb1cea16087f16f3ee21e1a8e90f95658 100644 (file)
@@ -16,7 +16,7 @@
     <emulator>/usr/bin/qemu</emulator>
     <disk type='block' device='disk'>
       <source dev='/dev/HostVG/QEMUGuest1'/>
-      <target dev='hda'/>
+      <target dev='hda' bus='ide'/>
     </disk>
     <serial type='dev'>
       <source path='/dev/ttyS2'/>
index 4a1bdc5df472e5a7fba79a025a326f92d6d1307a..3726816bde59f44e915322faeb8a8557f49d0078 100644 (file)
@@ -16,7 +16,7 @@
     <emulator>/usr/bin/qemu</emulator>
     <disk type='block' device='disk'>
       <source dev='/dev/HostVG/QEMUGuest1'/>
-      <target dev='hda'/>
+      <target dev='hda' bus='ide'/>
     </disk>
     <serial type='file'>
       <source path='/tmp/serial.log'/>
index 3b9f124d2f2220f24e5bd02f5ba4ef7ab8a75110..444e85b56dadba8f53128fddf6e79e8444a4cb37 100644 (file)
@@ -16,7 +16,7 @@
     <emulator>/usr/bin/qemu</emulator>
     <disk type='block' device='disk'>
       <source dev='/dev/HostVG/QEMUGuest1'/>
-      <target dev='hda'/>
+      <target dev='hda' bus='ide'/>
     </disk>
     <serial type='pty'>
       <target port='0'/>
index 7752c023579a3d051d5336ac0bcabb86952e48d7..c16ae07f3af50aeb7dd766f889a748554901bff8 100644 (file)
@@ -16,7 +16,7 @@
     <emulator>/usr/bin/qemu</emulator>
     <disk type='block' device='disk'>
       <source dev='/dev/HostVG/QEMUGuest1'/>
-      <target dev='hda'/>
+      <target dev='hda' bus='ide'/>
     </disk>
     <serial type='pty'>
       <target port='0'/>
index 77ac6a3f65e3338859127bf96dddcd13cd251c41..bea4306edcd5dabc4c1036609d05309b6f6f46fa 100644 (file)
@@ -16,7 +16,7 @@
     <emulator>/usr/bin/qemu</emulator>
     <disk type='block' device='disk'>
       <source dev='/dev/HostVG/QEMUGuest1'/>
-      <target dev='hda'/>
+      <target dev='hda' bus='ide'/>
     </disk>
     <serial type='tcp'>
       <source mode='bind' host='127.0.0.1' service='9999'/>
index fe80d2d4814e6c1db9f5e2b94fa3bc4a3dcec8a2..3bcf62da9a94c525a1a01211c5c91b538f712e34 100644 (file)
@@ -16,7 +16,7 @@
     <emulator>/usr/bin/qemu</emulator>
     <disk type='block' device='disk'>
       <source dev='/dev/HostVG/QEMUGuest1'/>
-      <target dev='hda'/>
+      <target dev='hda' bus='ide'/>
     </disk>
     <serial type='tcp'>
       <source mode='connect' host='127.0.0.1' service='9999'/>
index bdab917bbd1309021908afa8c36725ddc5b4efa9..115166d4c8c14b68e3134f038c194d099da29793 100644 (file)
@@ -16,7 +16,7 @@
     <emulator>/usr/bin/qemu</emulator>
     <disk type='block' device='disk'>
       <source dev='/dev/HostVG/QEMUGuest1'/>
-      <target dev='hda'/>
+      <target dev='hda' bus='ide'/>
     </disk>
     <serial type='udp'>
       <source mode='bind' host='127.0.0.1' service='9999'/>
index cc9626998be5e9631917de586415085e512860ff..4236b4c9ed345b6eb2c1f03a0a6d40c2742f2bbe 100644 (file)
@@ -16,7 +16,7 @@
     <emulator>/usr/bin/qemu</emulator>
     <disk type='block' device='disk'>
       <source dev='/dev/HostVG/QEMUGuest1'/>
-      <target dev='hda'/>
+      <target dev='hda' bus='ide'/>
     </disk>
     <serial type='unix'>
       <source mode='connect' path='/tmp/serial.sock'/>
index b5d6d178d88443207bf428cc720ecfa69fb3e596..1e5de8f125d41742ea53e8fa3647f47c583b0e61 100644 (file)
@@ -16,7 +16,7 @@
     <emulator>/usr/bin/qemu</emulator>
     <disk type='block' device='disk'>
       <source dev='/dev/HostVG/QEMUGuest1'/>
-      <target dev='hda'/>
+      <target dev='hda' bus='ide'/>
     </disk>
     <serial type='vc'>
       <target port='0'/>
index 63abebeae8a3df40a6ce6d643a033f65169c3530..2dabae7027214b7a53a3a864126c9b4eddf2ba93 100644 (file)
@@ -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
-
-    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("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");
+#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", 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", 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);