Add support for -drive QEMU syntax, and virtio bus / disk type

This commit is contained in:
Daniel P. Berrange 2008-05-09 16:41:19 +00:00
parent 7967662a52
commit 098ba1a433
46 changed files with 386 additions and 275 deletions

View File

@ -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> Fri May 9 15:45:39 CEST 2008 Jim Meyering <meyering@redhat.com>
Add new files from gnulib. Add new files from gnulib.

View File

@ -78,6 +78,7 @@ strsep
sys_stat sys_stat
useless-if-before-free useless-if-before-free
vasprintf vasprintf
verify
vc-list-files vc-list-files
' '

View File

@ -1,18 +1,18 @@
*.la
*.lo
.deps
.libs
Makefile
Makefile.in
alloca.h alloca.h
arpa_inet.h arpa_inet.h
.deps
float.h float.h
*.la
.libs
*.lo
Makefile
Makefile.in
netinet_in.h netinet_in.h
poll.h poll.h
stdbool.h stdbool.h
stdint.h stdint.h
stdio-impl.h
stdio.h stdio.h
stdio-impl.h
stdlib.h stdlib.h
string.h string.h
sys_select.h sys_select.h

View File

@ -9,7 +9,7 @@
# the same distribution terms as the rest of that program. # the same distribution terms as the rest of that program.
# #
# Generated by gnulib-tool. # 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 AUTOMAKE_OPTIONS = 1.5 gnits
@ -769,6 +769,12 @@ EXTRA_DIST += $(top_srcdir)/build-aux/vc-list-files
## end gnulib module 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 ## begin gnulib module wchar
BUILT_SOURCES += $(WCHAR_H) BUILT_SOURCES += $(WCHAR_H)

View File

@ -3,16 +3,16 @@
Copyright 2000-2003, 2006 Free Software Foundation, Inc. Copyright 2000-2003, 2006 Free Software Foundation, Inc.
This program is free software; you can redistribute it and/or modify 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 it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 2 of the License, or the Free Software Foundation; either version 2.1 of the License, or
(at your option) any later version. (at your option) any later version.
This program is distributed in the hope that it will be useful, This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 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, along with this program; if not, write to the Free Software Foundation,
Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */

View File

@ -8,16 +8,16 @@
Copyright (C) 2000-2003, 2006 Free Software Foundation, Inc. Copyright (C) 2000-2003, 2006 Free Software Foundation, Inc.
This program is free software; you can redistribute it and/or modify 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 it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 2 of the License, or the Free Software Foundation; either version 2.1 of the License, or
(at your option) any later version. (at your option) any later version.
This program is distributed in the hope that it will be useful, This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 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, along with this program; if not, write to the Free Software Foundation,
Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */

View File

@ -4,7 +4,7 @@
This program is free software: you can redistribute it and/or modify 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 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. (at your option) any later version.
This program is distributed in the hope that it will be useful, This program is distributed in the hope that it will be useful,

View File

@ -15,11 +15,11 @@
# Specification in the form of a command-line invocation: # 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: # Specification in the form of a few gnulib-tool.m4 macro invocations:
gl_LOCAL_DIR([]) 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_AVOID([])
gl_SOURCE_BASE([gnulib/lib]) gl_SOURCE_BASE([gnulib/lib])
gl_M4_BASE([gnulib/m4]) gl_M4_BASE([gnulib/m4])

View File

@ -286,6 +286,7 @@ AC_DEFUN([gl_FILE_LIST], [
lib/vasnprintf.c lib/vasnprintf.c
lib/vasnprintf.h lib/vasnprintf.h
lib/vasprintf.c lib/vasprintf.c
lib/verify.h
lib/wchar.in.h lib/wchar.in.h
lib/xsize.h lib/xsize.h
m4/alloca.m4 m4/alloca.m4
@ -391,5 +392,4 @@ AC_DEFUN([gl_FILE_LIST], [
tests/test-wchar.c tests/test-wchar.c
tests=lib/dummy.c tests=lib/dummy.c
tests=lib/intprops.h tests=lib/intprops.h
tests=lib/verify.h
]) ])

View 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 ## 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 ## begin gnulib module wchar-tests
TESTS += test-wchar TESTS += test-wchar

View File

@ -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

View File

@ -49,6 +49,7 @@
#include "buf.h" #include "buf.h"
#include "conf.h" #include "conf.h"
#include "util.h" #include "util.h"
#include <verify.h>
#define qemudLog(level, msg...) fprintf(stderr, msg) #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; *flags |= QEMUD_CMD_FLAG_KQEMU;
if (strstr(help, "-no-reboot")) if (strstr(help, "-no-reboot"))
*flags |= QEMUD_CMD_FLAG_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) if (*version >= 9000)
*flags |= QEMUD_CMD_FLAG_VNC_COLON; *flags |= QEMUD_CMD_FLAG_VNC_COLON;
ret = 0; ret = 0;
@ -583,6 +588,7 @@ static int qemudParseDiskXML(virConnectPtr conn,
xmlChar *source = NULL; xmlChar *source = NULL;
xmlChar *target = NULL; xmlChar *target = NULL;
xmlChar *type = NULL; xmlChar *type = NULL;
xmlChar *bus = NULL;
int typ = 0; int typ = 0;
type = xmlGetProp(node, BAD_CAST "type"); type = xmlGetProp(node, BAD_CAST "type");
@ -613,6 +619,7 @@ static int qemudParseDiskXML(virConnectPtr conn,
} else if ((target == NULL) && } else if ((target == NULL) &&
(xmlStrEqual(cur->name, BAD_CAST "target"))) { (xmlStrEqual(cur->name, BAD_CAST "target"))) {
target = xmlGetProp(cur, BAD_CAST "dev"); target = xmlGetProp(cur, BAD_CAST "dev");
bus = xmlGetProp(cur, BAD_CAST "bus");
} else if (xmlStrEqual(cur->name, BAD_CAST "readonly")) { } else if (xmlStrEqual(cur->name, BAD_CAST "readonly")) {
disk->readonly = 1; disk->readonly = 1;
} }
@ -658,10 +665,9 @@ static int qemudParseDiskXML(virConnectPtr conn,
disk->readonly = 1; disk->readonly = 1;
if ((!device || !strcmp((const char *)device, "disk")) && if ((!device || !strcmp((const char *)device, "disk")) &&
strcmp((const char *)target, "hda") && strncmp((const char *)target, "hd", 2) &&
strcmp((const char *)target, "hdb") && strncmp((const char *)target, "sd", 2) &&
strcmp((const char *)target, "hdc") && strncmp((const char *)target, "vd", 2)) {
strcmp((const char *)target, "hdd")) {
qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR, qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
_("Invalid harddisk device name: %s"), target); _("Invalid harddisk device name: %s"), target);
goto error; goto error;
@ -688,13 +694,41 @@ static int qemudParseDiskXML(virConnectPtr conn,
goto error; 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(device);
xmlFree(target); xmlFree(target);
xmlFree(source); xmlFree(source);
xmlFree(bus);
return 0; return 0;
error: error:
xmlFree(bus);
xmlFree(type); xmlFree(type);
xmlFree(target); xmlFree(target);
xmlFree(source); xmlFree(source);
@ -1388,6 +1422,25 @@ static int qemudParseInputXML(virConnectPtr conn,
return -1; 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 */ /* Sound device helper functions */
static int qemudSoundModelFromString(const char *model) { static int qemudSoundModelFromString(const char *model) {
if (STREQ(model, "sb16")) { if (STREQ(model, "sb16")) {
@ -1440,7 +1493,6 @@ static int qemudParseSoundXML(virConnectPtr conn,
return err; return err;
} }
/* /*
* Parses a libvirt XML definition of a guest, and populates the * Parses a libvirt XML definition of a guest, and populates the
* the qemud_vm struct with matching data about the guests config * 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); obj = xmlXPathEval(BAD_CAST "/domain/devices/disk", ctxt);
if ((obj != NULL) && (obj->type == XPATH_NODESET) && if ((obj != NULL) && (obj->type == XPATH_NODESET) &&
(obj->nodesetval != NULL) && (obj->nodesetval->nodeNr >= 0)) { (obj->nodesetval != NULL) && (obj->nodesetval->nodeNr >= 0)) {
struct qemud_vm_disk_def *prev = NULL;
for (i = 0; i < obj->nodesetval->nodeNr; i++) { for (i = 0; i < obj->nodesetval->nodeNr; i++) {
struct qemud_vm_disk_def *disk = calloc(1, sizeof(*disk)); struct qemud_vm_disk_def *disk = calloc(1, sizeof(*disk));
if (!disk) { if (!disk) {
@ -1845,13 +1896,20 @@ static struct qemud_vm_def *qemudParseXML(virConnectPtr conn,
goto error; goto error;
} }
def->ndisks++; def->ndisks++;
disk->next = NULL;
if (i == 0) { if (i == 0) {
disk->next = NULL;
def->disks = disk; def->disks = disk;
} else { } 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); xmlXPathFreeObject(obj);
@ -2292,7 +2350,7 @@ int qemudBuildCommandLine(virConnectPtr conn,
snprintf(memory, sizeof(memory), "%lu", vm->def->memory/1024); snprintf(memory, sizeof(memory), "%lu", vm->def->memory/1024);
snprintf(vcpus, sizeof(vcpus), "%d", vm->def->vcpus); 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; goto no_memory;
if (!((*argv)[++n] = strdup(vm->def->os.binary))) if (!((*argv)[++n] = strdup(vm->def->os.binary)))
goto no_memory; goto no_memory;
@ -2390,28 +2448,102 @@ int qemudBuildCommandLine(virConnectPtr conn,
goto no_memory; goto no_memory;
} }
while (disk) { /* If QEMU supports -drive param instead of old -hda, -hdb, -cdrom .. */
char dev[NAME_MAX]; if (vm->qemuCmdFlags & QEMUD_CMD_FLAG_DRIVE_OPT) {
char file[PATH_MAX]; int bootCD = 0, bootFloppy = 0, bootDisk = 0;
if (!strcmp(disk->dst, "hdc") &&
disk->device == QEMUD_DISK_CDROM) { /* If QEMU supports boot=on for -drive param... */
if (disk->src[0]) if (vm->qemuCmdFlags & QEMUD_CMD_FLAG_DRIVE_BOOT_OPT) {
snprintf(dev, NAME_MAX, "-%s", "cdrom"); for (i = 0 ; i < vm->def->os.nBootDevs ; i++) {
else { switch (vm->def->os.bootDevs[i]) {
/* Don't put anything on the cmdline for an empty cdrom*/ case QEMUD_BOOT_CDROM:
disk = disk->next; bootCD = 1;
continue; 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))) while (disk) {
goto no_memory; char opt[PATH_MAX];
if (!((*argv)[++n] = strdup(file))) const char *media = NULL;
goto no_memory; 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) { if (!net) {
@ -2661,6 +2793,7 @@ int qemudBuildCommandLine(virConnectPtr conn,
for (i = 0 ; i < n ; i++) for (i = 0 ; i < n ; i++)
free((*argv)[i]); free((*argv)[i]);
free(*argv); free(*argv);
*argv = NULL;
} }
return -1; return -1;
} }
@ -3518,10 +3651,7 @@ static int qemudGenerateXMLChar(virBufferPtr buf,
"tcp", "tcp",
"unix" "unix"
}; };
/*verify(ARRAY_CARDINALITY(types) == QEMUD_CHR_SRC_TYPE_LAST);*/ verify_true(ARRAY_CARDINALITY(types) == QEMUD_CHR_SRC_TYPE_LAST);
if (dev->srcType < 0 || dev->srcType >= QEMUD_CHR_SRC_TYPE_LAST)
return -1;
/* Compat with legacy <console tty='/dev/pts/5'/> syntax */ /* Compat with legacy <console tty='/dev/pts/5'/> syntax */
if (STREQ(type, "console") && if (STREQ(type, "console") &&
@ -3722,7 +3852,8 @@ char *qemudGenerateXML(virConnectPtr conn,
virBufferVSprintf(&buf, " <source %s='%s'/>\n", virBufferVSprintf(&buf, " <source %s='%s'/>\n",
typeAttrs[disk->type], disk->src); 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) if (disk->readonly)
virBufferAddLit(&buf, " <readonly/>\n"); virBufferAddLit(&buf, " <readonly/>\n");

View File

@ -56,10 +56,20 @@ enum qemud_vm_disk_device {
QEMUD_DISK_FLOPPY, 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 */ /* Stores the virtual disk configuration */
struct qemud_vm_disk_def { struct qemud_vm_disk_def {
int type; int type;
int device; int device;
int bus;
char src[PATH_MAX]; char src[PATH_MAX];
char dst[NAME_MAX]; char dst[NAME_MAX];
int readonly; int readonly;
@ -234,9 +244,11 @@ enum qemud_vm_graphics_type {
/* Internal flags to keep track of qemu command line capabilities */ /* Internal flags to keep track of qemu command line capabilities */
enum qemud_cmd_flags { enum qemud_cmd_flags {
QEMUD_CMD_FLAG_KQEMU = 1, QEMUD_CMD_FLAG_KQEMU = (1 << 0),
QEMUD_CMD_FLAG_VNC_COLON = 2, QEMUD_CMD_FLAG_VNC_COLON = (1 << 1),
QEMUD_CMD_FLAG_NO_REBOOT = 4, QEMUD_CMD_FLAG_NO_REBOOT = (1 << 2),
QEMUD_CMD_FLAG_DRIVE_OPT = (1 << 3),
QEMUD_CMD_FLAG_DRIVE_BOOT_OPT = (1 << 4),
}; };

View File

@ -769,3 +769,44 @@ virParseMacAddr(const char* str, unsigned char *addr)
return -1; 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;
}

View File

@ -87,4 +87,6 @@ int virParseNumber(const char **str);
int virParseMacAddr(const char* str, unsigned char *addr); int virParseMacAddr(const char* str, unsigned char *addr);
int virDiskNameToIndex(const char* str);
#endif /* __VIR_UTIL_H__ */ #endif /* __VIR_UTIL_H__ */

View File

@ -16,7 +16,7 @@
<emulator>/usr/bin/qemu</emulator> <emulator>/usr/bin/qemu</emulator>
<disk type='block' device='cdrom'> <disk type='block' device='cdrom'>
<source dev='/dev/cdrom'/> <source dev='/dev/cdrom'/>
<target dev='hdc'/> <target dev='hdc' bus='ide'/>
<readonly/> <readonly/>
</disk> </disk>
</devices> </devices>

View File

@ -16,11 +16,11 @@
<emulator>/usr/bin/qemu</emulator> <emulator>/usr/bin/qemu</emulator>
<disk type='block' device='disk'> <disk type='block' device='disk'>
<source dev='/dev/HostVG/QEMUGuest1'/> <source dev='/dev/HostVG/QEMUGuest1'/>
<target dev='hda'/> <target dev='hda' bus='ide'/>
</disk> </disk>
<disk type='file' device='floppy'> <disk type='file' device='floppy'>
<source file='/tmp/firmware.img'/> <source file='/tmp/firmware.img'/>
<target dev='fda'/> <target dev='fda' bus='fdc'/>
</disk> </disk>
</devices> </devices>
</domain> </domain>

View File

@ -16,7 +16,7 @@
<emulator>/usr/bin/qemu</emulator> <emulator>/usr/bin/qemu</emulator>
<disk type='block' device='disk'> <disk type='block' device='disk'>
<source dev='/dev/HostVG/QEMUGuest1'/> <source dev='/dev/HostVG/QEMUGuest1'/>
<target dev='hda'/> <target dev='hda' bus='ide'/>
</disk> </disk>
</devices> </devices>
</domain> </domain>

View File

@ -16,7 +16,7 @@
<emulator>/usr/bin/qemu</emulator> <emulator>/usr/bin/qemu</emulator>
<disk type='block' device='disk'> <disk type='block' device='disk'>
<source dev='/dev/HostVG/QEMUGuest1'/> <source dev='/dev/HostVG/QEMUGuest1'/>
<target dev='hda'/> <target dev='hda' bus='ide'/>
</disk> </disk>
</devices> </devices>
</domain> </domain>

View File

@ -16,7 +16,7 @@
<emulator>/usr/bin/qemu</emulator> <emulator>/usr/bin/qemu</emulator>
<disk type='block' device='disk'> <disk type='block' device='disk'>
<source dev='/dev/HostVG/QEMUGuest1'/> <source dev='/dev/HostVG/QEMUGuest1'/>
<target dev='hda'/> <target dev='hda' bus='ide'/>
</disk> </disk>
</devices> </devices>
</domain> </domain>

View File

@ -16,7 +16,7 @@
<emulator>/usr/bin/qemu</emulator> <emulator>/usr/bin/qemu</emulator>
<disk type='block' device='disk'> <disk type='block' device='disk'>
<source dev='/dev/HostVG/QEMUGuest1'/> <source dev='/dev/HostVG/QEMUGuest1'/>
<target dev='hda'/> <target dev='hda' bus='ide'/>
</disk> </disk>
<serial type='pty'> <serial type='pty'>
<target port='0'/> <target port='0'/>

View File

@ -16,11 +16,11 @@
<emulator>/usr/bin/qemu</emulator> <emulator>/usr/bin/qemu</emulator>
<disk type='block' device='disk'> <disk type='block' device='disk'>
<source dev='/dev/HostVG/QEMUGuest1'/> <source dev='/dev/HostVG/QEMUGuest1'/>
<target dev='hda'/> <target dev='hda' bus='ide'/>
</disk> </disk>
<disk type='file' device='cdrom'> <disk type='file' device='cdrom'>
<source file='/root/boot.iso'/> <source file='/root/boot.iso'/>
<target dev='hdc'/> <target dev='hdc' bus='ide'/>
<readonly/> <readonly/>
</disk> </disk>
</devices> </devices>

View File

@ -16,15 +16,15 @@
<emulator>/usr/bin/qemu</emulator> <emulator>/usr/bin/qemu</emulator>
<disk type='block' device='disk'> <disk type='block' device='disk'>
<source dev='/dev/HostVG/QEMUGuest1'/> <source dev='/dev/HostVG/QEMUGuest1'/>
<target dev='hda'/> <target dev='hda' bus='ide'/>
</disk> </disk>
<disk type='block' device='floppy'> <disk type='block' device='floppy'>
<source dev='/dev/fd0'/> <source dev='/dev/fd0'/>
<target dev='fda'/> <target dev='fda' bus='fdc'/>
</disk> </disk>
<disk type='file' device='floppy'> <disk type='file' device='floppy'>
<source file='/tmp/firmware.img'/> <source file='/tmp/firmware.img'/>
<target dev='fdb'/> <target dev='fdb' bus='fdc'/>
</disk> </disk>
</devices> </devices>
</domain> </domain>

View File

@ -16,19 +16,19 @@
<emulator>/usr/bin/qemu</emulator> <emulator>/usr/bin/qemu</emulator>
<disk type='block' device='disk'> <disk type='block' device='disk'>
<source dev='/dev/HostVG/QEMUGuest1'/> <source dev='/dev/HostVG/QEMUGuest1'/>
<target dev='hda'/> <target dev='hda' bus='ide'/>
</disk> </disk>
<disk type='block' device='disk'> <disk type='block' device='disk'>
<source dev='/dev/HostVG/QEMUGuest2'/> <source dev='/dev/HostVG/QEMUGuest2'/>
<target dev='hdb'/> <target dev='hdb' bus='ide'/>
</disk> </disk>
<disk type='file' device='disk'> <disk type='file' device='disk'>
<source file='/tmp/data.img'/> <source file='/tmp/data.img'/>
<target dev='hdc'/> <target dev='hdc' bus='ide'/>
</disk> </disk>
<disk type='file' device='disk'> <disk type='file' device='disk'>
<source file='/tmp/logs.img'/> <source file='/tmp/logs.img'/>
<target dev='hdd'/> <target dev='hdd' bus='ide'/>
</disk> </disk>
</devices> </devices>
</domain> </domain>

View File

@ -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

View File

@ -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>

View File

@ -16,7 +16,7 @@
<emulator>/usr/bin/qemu</emulator> <emulator>/usr/bin/qemu</emulator>
<disk type='block' device='disk'> <disk type='block' device='disk'>
<source dev='/dev/HostVG/QEMUGuest1'/> <source dev='/dev/HostVG/QEMUGuest1'/>
<target dev='hda'/> <target dev='hda' bus='ide'/>
</disk> </disk>
<input type='mouse' bus='ps2'/> <input type='mouse' bus='ps2'/>
<graphics type='sdl'/> <graphics type='sdl'/>

View File

@ -16,7 +16,7 @@
<emulator>/usr/bin/qemu</emulator> <emulator>/usr/bin/qemu</emulator>
<disk type='block' device='disk'> <disk type='block' device='disk'>
<source dev='/dev/HostVG/QEMUGuest1'/> <source dev='/dev/HostVG/QEMUGuest1'/>
<target dev='hda'/> <target dev='hda' bus='ide'/>
</disk> </disk>
<input type='mouse' bus='ps2'/> <input type='mouse' bus='ps2'/>
<graphics type='vnc' port='5903' listen='127.0.0.1'/> <graphics type='vnc' port='5903' listen='127.0.0.1'/>

View File

@ -16,7 +16,7 @@
<emulator>/usr/bin/qemu</emulator> <emulator>/usr/bin/qemu</emulator>
<disk type='block' device='disk'> <disk type='block' device='disk'>
<source dev='/dev/HostVG/QEMUGuest1'/> <source dev='/dev/HostVG/QEMUGuest1'/>
<target dev='hda'/> <target dev='hda' bus='ide'/>
</disk> </disk>
<input type='mouse' bus='usb'/> <input type='mouse' bus='usb'/>
</devices> </devices>

View File

@ -16,7 +16,7 @@
<emulator>/usr/bin/qemu</emulator> <emulator>/usr/bin/qemu</emulator>
<disk type='block' device='disk'> <disk type='block' device='disk'>
<source dev='/dev/HostVG/QEMUGuest1'/> <source dev='/dev/HostVG/QEMUGuest1'/>
<target dev='hda'/> <target dev='hda' bus='ide'/>
</disk> </disk>
<input type='tablet' bus='usb'/> <input type='tablet' bus='usb'/>
</devices> </devices>

View File

@ -16,7 +16,7 @@
<emulator>/usr/bin/qemu</emulator> <emulator>/usr/bin/qemu</emulator>
<disk type='block' device='disk'> <disk type='block' device='disk'>
<source dev='/dev/HostVG/QEMUGuest1'/> <source dev='/dev/HostVG/QEMUGuest1'/>
<target dev='hda'/> <target dev='hda' bus='ide'/>
</disk> </disk>
</devices> </devices>
</domain> </domain>

View File

@ -19,7 +19,7 @@
<emulator>/usr/bin/qemu</emulator> <emulator>/usr/bin/qemu</emulator>
<disk type='block' device='disk'> <disk type='block' device='disk'>
<source dev='/dev/HostVG/QEMUGuest1'/> <source dev='/dev/HostVG/QEMUGuest1'/>
<target dev='hda'/> <target dev='hda' bus='ide'/>
</disk> </disk>
</devices> </devices>
</domain> </domain>

View File

@ -16,7 +16,7 @@
<emulator>/usr/bin/qemu</emulator> <emulator>/usr/bin/qemu</emulator>
<disk type='block' device='disk'> <disk type='block' device='disk'>
<source dev='/dev/HostVG/QEMUGuest1'/> <source dev='/dev/HostVG/QEMUGuest1'/>
<target dev='hda'/> <target dev='hda' bus='ide'/>
</disk> </disk>
</devices> </devices>
</domain> </domain>

View File

@ -16,7 +16,7 @@
<emulator>/usr/bin/qemu</emulator> <emulator>/usr/bin/qemu</emulator>
<disk type='block' device='disk'> <disk type='block' device='disk'>
<source dev='/dev/HostVG/QEMUGuest1'/> <source dev='/dev/HostVG/QEMUGuest1'/>
<target dev='hda'/> <target dev='hda' bus='ide'/>
</disk> </disk>
<interface type='user'> <interface type='user'>
<mac address='00:11:22:33:44:55'/> <mac address='00:11:22:33:44:55'/>

View File

@ -16,7 +16,7 @@
<emulator>/usr/bin/qemu</emulator> <emulator>/usr/bin/qemu</emulator>
<disk type='block' device='disk'> <disk type='block' device='disk'>
<source dev='/dev/HostVG/QEMUGuest1'/> <source dev='/dev/HostVG/QEMUGuest1'/>
<target dev='hda'/> <target dev='hda' bus='ide'/>
</disk> </disk>
<interface type='user'> <interface type='user'>
<mac address='00:11:22:33:44:55'/> <mac address='00:11:22:33:44:55'/>

View File

@ -16,7 +16,7 @@
<emulator>/usr/bin/qemu</emulator> <emulator>/usr/bin/qemu</emulator>
<disk type='block' device='disk'> <disk type='block' device='disk'>
<source dev='/dev/HostVG/QEMUGuest1'/> <source dev='/dev/HostVG/QEMUGuest1'/>
<target dev='hda'/> <target dev='hda' bus='ide'/>
</disk> </disk>
<parallel type='tcp'> <parallel type='tcp'>
<source mode='bind' host='127.0.0.1' service='9999'/> <source mode='bind' host='127.0.0.1' service='9999'/>

View File

@ -16,7 +16,7 @@
<emulator>/usr/bin/qemu</emulator> <emulator>/usr/bin/qemu</emulator>
<disk type='block' device='disk'> <disk type='block' device='disk'>
<source dev='/dev/HostVG/QEMUGuest1'/> <source dev='/dev/HostVG/QEMUGuest1'/>
<target dev='hda'/> <target dev='hda' bus='ide'/>
</disk> </disk>
<serial type='dev'> <serial type='dev'>
<source path='/dev/ttyS2'/> <source path='/dev/ttyS2'/>

View File

@ -16,7 +16,7 @@
<emulator>/usr/bin/qemu</emulator> <emulator>/usr/bin/qemu</emulator>
<disk type='block' device='disk'> <disk type='block' device='disk'>
<source dev='/dev/HostVG/QEMUGuest1'/> <source dev='/dev/HostVG/QEMUGuest1'/>
<target dev='hda'/> <target dev='hda' bus='ide'/>
</disk> </disk>
<serial type='file'> <serial type='file'>
<source path='/tmp/serial.log'/> <source path='/tmp/serial.log'/>

View File

@ -16,7 +16,7 @@
<emulator>/usr/bin/qemu</emulator> <emulator>/usr/bin/qemu</emulator>
<disk type='block' device='disk'> <disk type='block' device='disk'>
<source dev='/dev/HostVG/QEMUGuest1'/> <source dev='/dev/HostVG/QEMUGuest1'/>
<target dev='hda'/> <target dev='hda' bus='ide'/>
</disk> </disk>
<serial type='pty'> <serial type='pty'>
<target port='0'/> <target port='0'/>

View File

@ -16,7 +16,7 @@
<emulator>/usr/bin/qemu</emulator> <emulator>/usr/bin/qemu</emulator>
<disk type='block' device='disk'> <disk type='block' device='disk'>
<source dev='/dev/HostVG/QEMUGuest1'/> <source dev='/dev/HostVG/QEMUGuest1'/>
<target dev='hda'/> <target dev='hda' bus='ide'/>
</disk> </disk>
<serial type='pty'> <serial type='pty'>
<target port='0'/> <target port='0'/>

View File

@ -16,7 +16,7 @@
<emulator>/usr/bin/qemu</emulator> <emulator>/usr/bin/qemu</emulator>
<disk type='block' device='disk'> <disk type='block' device='disk'>
<source dev='/dev/HostVG/QEMUGuest1'/> <source dev='/dev/HostVG/QEMUGuest1'/>
<target dev='hda'/> <target dev='hda' bus='ide'/>
</disk> </disk>
<serial type='tcp'> <serial type='tcp'>
<source mode='bind' host='127.0.0.1' service='9999'/> <source mode='bind' host='127.0.0.1' service='9999'/>

View File

@ -16,7 +16,7 @@
<emulator>/usr/bin/qemu</emulator> <emulator>/usr/bin/qemu</emulator>
<disk type='block' device='disk'> <disk type='block' device='disk'>
<source dev='/dev/HostVG/QEMUGuest1'/> <source dev='/dev/HostVG/QEMUGuest1'/>
<target dev='hda'/> <target dev='hda' bus='ide'/>
</disk> </disk>
<serial type='tcp'> <serial type='tcp'>
<source mode='connect' host='127.0.0.1' service='9999'/> <source mode='connect' host='127.0.0.1' service='9999'/>

View File

@ -16,7 +16,7 @@
<emulator>/usr/bin/qemu</emulator> <emulator>/usr/bin/qemu</emulator>
<disk type='block' device='disk'> <disk type='block' device='disk'>
<source dev='/dev/HostVG/QEMUGuest1'/> <source dev='/dev/HostVG/QEMUGuest1'/>
<target dev='hda'/> <target dev='hda' bus='ide'/>
</disk> </disk>
<serial type='udp'> <serial type='udp'>
<source mode='bind' host='127.0.0.1' service='9999'/> <source mode='bind' host='127.0.0.1' service='9999'/>

View File

@ -16,7 +16,7 @@
<emulator>/usr/bin/qemu</emulator> <emulator>/usr/bin/qemu</emulator>
<disk type='block' device='disk'> <disk type='block' device='disk'>
<source dev='/dev/HostVG/QEMUGuest1'/> <source dev='/dev/HostVG/QEMUGuest1'/>
<target dev='hda'/> <target dev='hda' bus='ide'/>
</disk> </disk>
<serial type='unix'> <serial type='unix'>
<source mode='connect' path='/tmp/serial.sock'/> <source mode='connect' path='/tmp/serial.sock'/>

View File

@ -16,7 +16,7 @@
<emulator>/usr/bin/qemu</emulator> <emulator>/usr/bin/qemu</emulator>
<disk type='block' device='disk'> <disk type='block' device='disk'>
<source dev='/dev/HostVG/QEMUGuest1'/> <source dev='/dev/HostVG/QEMUGuest1'/>
<target dev='hda'/> <target dev='hda' bus='ide'/>
</disk> </disk>
<serial type='vc'> <serial type='vc'>
<target port='0'/> <target port='0'/>

View File

@ -20,7 +20,7 @@ static struct qemud_driver driver;
#define MAX_FILE 4096 #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 xmlData[MAX_FILE];
char argvData[MAX_FILE]; char argvData[MAX_FILE];
char *xmlPtr = &(xmlData[0]); 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.qemuVersion = 0 * 1000 * 100 + (8 * 1000) + 1;
vm.qemuCmdFlags = QEMUD_CMD_FLAG_VNC_COLON | vm.qemuCmdFlags = QEMUD_CMD_FLAG_VNC_COLON |
QEMUD_CMD_FLAG_NO_REBOOT; 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'; vm.migrateFrom[0] = '\0';
vmdef->vncActivePort = vmdef->vncPort; 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) { static int testCompareXMLToArgvHelper(const void *data) {
const struct testInfo *info = data;
char xml[PATH_MAX]; char xml[PATH_MAX];
char args[PATH_MAX]; char args[PATH_MAX];
snprintf(xml, PATH_MAX, "%s/qemuxml2argvdata/qemuxml2argv-%s.xml", 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", snprintf(args, PATH_MAX, "%s/qemuxml2argvdata/qemuxml2argv-%s.args",
abs_srcdir, (const char*)data); abs_srcdir, info->name);
return testCompareXMLToArgvFiles(xml, args); return testCompareXMLToArgvFiles(xml, args, info->driveFlag);
} }
@ -125,41 +135,45 @@ main(int argc, char **argv)
driver.caps = qemudCapsInit(); driver.caps = qemudCapsInit();
#define DO_TEST(name) \ #define DO_TEST(name, driveFlag) \
if (virtTestRun("QEMU XML-2-ARGV " name, \ do { \
1, testCompareXMLToArgvHelper, (name)) < 0) \ struct testInfo info = { name, driveFlag }; \
ret = -1 if (virtTestRun("QEMU XML-2-ARGV " name, \
1, testCompareXMLToArgvHelper, &info) < 0) \
ret = -1; \
} while (0)
DO_TEST("minimal"); DO_TEST("minimal", 0);
DO_TEST("boot-cdrom"); DO_TEST("boot-cdrom", 0);
DO_TEST("boot-network"); DO_TEST("boot-network", 0);
DO_TEST("boot-floppy"); DO_TEST("boot-floppy", 0);
DO_TEST("clock-utc"); DO_TEST("clock-utc", 0);
DO_TEST("clock-localtime"); DO_TEST("clock-localtime", 0);
DO_TEST("disk-cdrom"); DO_TEST("disk-cdrom", 0);
DO_TEST("disk-floppy"); DO_TEST("disk-floppy", 0);
DO_TEST("disk-many"); DO_TEST("disk-many", 0);
DO_TEST("graphics-vnc"); DO_TEST("disk-virtio", 1);
DO_TEST("graphics-sdl"); DO_TEST("graphics-vnc", 0);
DO_TEST("input-usbmouse"); DO_TEST("graphics-sdl", 0);
DO_TEST("input-usbtablet"); DO_TEST("input-usbmouse", 0);
DO_TEST("misc-acpi"); DO_TEST("input-usbtablet", 0);
DO_TEST("misc-no-reboot"); DO_TEST("misc-acpi", 0);
DO_TEST("net-user"); DO_TEST("misc-no-reboot", 0);
DO_TEST("net-virtio"); DO_TEST("net-user", 0);
DO_TEST("net-virtio", 0);
DO_TEST("serial-vc"); DO_TEST("serial-vc", 0);
DO_TEST("serial-pty"); DO_TEST("serial-pty", 0);
DO_TEST("serial-dev"); DO_TEST("serial-dev", 0);
DO_TEST("serial-file"); DO_TEST("serial-file", 0);
DO_TEST("serial-unix"); DO_TEST("serial-unix", 0);
DO_TEST("serial-tcp"); DO_TEST("serial-tcp", 0);
DO_TEST("serial-udp"); DO_TEST("serial-udp", 0);
DO_TEST("serial-tcp-telnet"); DO_TEST("serial-tcp-telnet", 0);
DO_TEST("serial-many"); DO_TEST("serial-many", 0);
DO_TEST("parallel-tcp"); DO_TEST("parallel-tcp", 0);
DO_TEST("console-compat"); DO_TEST("console-compat", 0);
DO_TEST("sound"); DO_TEST("sound", 0);
virCapabilitiesFree(driver.caps); virCapabilitiesFree(driver.caps);