+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.
sys_stat
useless-if-before-free
vasprintf
+verify
vc-list-files
'
-*.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
# 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
## 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)
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. */
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. */
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,
# 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])
lib/vasnprintf.c
lib/vasnprintf.h
lib/vasprintf.c
+ lib/verify.h
lib/wchar.in.h
lib/xsize.h
m4/alloca.m4
tests/test-wchar.c
tests=lib/dummy.c
tests=lib/intprops.h
- tests=lib/verify.h
])
## 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
+++ /dev/null
-/* 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
#include "buf.h"
#include "conf.h"
#include "util.h"
+#include <verify.h>
#define qemudLog(level, msg...) fprintf(stderr, msg)
*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;
xmlChar *source = NULL;
xmlChar *target = NULL;
xmlChar *type = NULL;
+ xmlChar *bus = NULL;
int typ = 0;
type = xmlGetProp(node, BAD_CAST "type");
} 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;
}
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;
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);
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")) {
return err;
}
-
/*
* Parses a libvirt XML definition of a guest, and populates the
* the qemud_vm struct with matching data about the guests config
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) {
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);
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;
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) {
for (i = 0 ; i < n ; i++)
free((*argv)[i]);
free(*argv);
+ *argv = NULL;
}
return -1;
}
"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") &&
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");
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;
/* 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),
};
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;
+}
+
int virParseMacAddr(const char* str, unsigned char *addr);
+int virDiskNameToIndex(const char* str);
+
#endif /* __VIR_UTIL_H__ */
<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>
<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>
<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>
<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>
<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>
<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'/>
<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>
<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>
<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>
--- /dev/null
+/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
--- /dev/null
+<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>
<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'/>
<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'/>
<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>
<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>
<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>
<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>
<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>
<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'/>
<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'/>
<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'/>
<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'/>
<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'/>
<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'/>
<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'/>
<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'/>
<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'/>
<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'/>
<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'/>
<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'/>
#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]);
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;
}
+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);
}
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);