diff --git a/src/qemu_conf.c b/src/qemu_conf.c
index 1efd9e9..4f5e96e 100644
--- a/src/qemu_conf.c
+++ b/src/qemu_conf.c
@@ -1373,6 +1373,58 @@ static int qemudParseInputXML(virConnectPtr conn,
return -1;
}
+/* Sound device helper functions */
+static int qemudSoundModelFromString(const char *model) {
+ if (STREQ(model, "sb16")) {
+ return QEMU_SOUND_SB16;
+ } else if (STREQ(model, "es1370")) {
+ return QEMU_SOUND_ES1370;
+ } else if (STREQ(model, "pcspk")) {
+ return QEMU_SOUND_PCSPK;
+ }
+
+ return -1;
+}
+
+static const char *qemudSoundModelToString(const int model) {
+
+ if (model == QEMU_SOUND_SB16) {
+ return "sb16";
+ } else if (model == QEMU_SOUND_ES1370) {
+ return "es1370";
+ } else if (model == QEMU_SOUND_PCSPK) {
+ return "pcspk";
+ }
+
+ return NULL;
+}
+
+
+static int qemudParseSoundXML(virConnectPtr conn,
+ struct qemud_vm_sound_def *sound,
+ const xmlNodePtr node) {
+
+ int err = -1;
+ xmlChar *model = NULL;
+ model = xmlGetProp(node, BAD_CAST "model");
+
+ if (!model) {
+ qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
+ "%s", _("missing sound model"));
+ goto error;
+ }
+ if ((sound->model = qemudSoundModelFromString((char *) model)) < 0) {
+ qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
+ _("invalid sound model '%s'"), (char *) model);
+ goto error;
+ }
+
+ err = 0;
+ error:
+ xmlFree(model);
+ return err;
+}
+
/*
* Parses a libvirt XML definition of a guest, and populates the
@@ -1887,6 +1939,50 @@ static struct qemud_vm_def *qemudParseXML(virConnectPtr conn,
}
}
xmlXPathFreeObject(obj);
+
+ /* Parse sound driver xml */
+ obj = xmlXPathEval(BAD_CAST "/domain/devices/sound", ctxt);
+ if ((obj != NULL) && (obj->type == XPATH_NODESET) &&
+ (obj->nodesetval != NULL) && (obj->nodesetval->nodeNr >= 0)) {
+ struct qemud_vm_sound_def *prev = NULL;
+ for (i = 0; i < obj->nodesetval->nodeNr; i++) {
+
+ struct qemud_vm_sound_def *sound = calloc(1, sizeof(*sound));
+ struct qemud_vm_sound_def *check = def->sounds;
+ int collision = 0;
+ if (!sound) {
+ qemudReportError(conn, NULL, NULL, VIR_ERR_NO_MEMORY,
+ "%s", _("failed to allocate space for sound dev"));
+ goto error;
+ }
+ if (qemudParseSoundXML(conn, sound,
+ obj->nodesetval->nodeTab[i]) < 0) {
+ free(sound);
+ goto error;
+ }
+
+ // Check that model type isn't already present in sound dev list
+ while(check) {
+ if (check->model == sound->model) {
+ collision = 1;
+ break;
+ }
+ check = check->next;
+ }
+ if (collision)
+ continue;
+
+ def->nsounds++;
+ sound->next = NULL;
+ if (def->sounds == NULL) {
+ def->sounds = sound;
+ } else {
+ prev->next = sound;
+ }
+ prev = sound;
+ }
+ }
+ xmlXPathFreeObject(obj);
obj = NULL;
/* If graphics are enabled, there's an implicit PS2 mouse */
@@ -2106,6 +2202,7 @@ int qemudBuildCommandLine(virConnectPtr conn,
struct qemud_vm_disk_def *disk = vm->def->disks;
struct qemud_vm_net_def *net = vm->def->nets;
struct qemud_vm_input_def *input = vm->def->inputs;
+ struct qemud_vm_sound_def *sound = vm->def->sounds;
struct qemud_vm_chr_def *serial = vm->def->serials;
struct qemud_vm_chr_def *parallel = vm->def->parallels;
struct utsname ut;
@@ -2156,6 +2253,7 @@ int qemudBuildCommandLine(virConnectPtr conn,
(vm->def->nnets > 0 ? (4 * vm->def->nnets) : 2) + /* networks */
1 + /* usb */
2 * vm->def->ninputs + /* input devices */
+ ((vm->def->nsounds > 0) ? 2 : 0) + /* sound */
(vm->def->nserials > 0 ? (2 * vm->def->nserials) : 2) + /* character devices */
(vm->def->nparallels > 0 ? (2 * vm->def->nparallels) : 2) + /* character devices */
2 + /* memory*/
@@ -2491,6 +2589,32 @@ int qemudBuildCommandLine(virConnectPtr conn,
/* SDL is the default. no args needed */
}
+ /* Add sound hardware */
+ if (sound) {
+ int size = 100;
+ char *modstr = calloc(1, size+1);
+ if (!modstr)
+ goto no_memory;
+ if (!((*argv)[++n] = strdup("-soundhw")))
+ goto no_memory;
+
+ while(sound && size > 0) {
+ const char *model = qemudSoundModelToString(sound->model);
+ if (!model) {
+ qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
+ _("invalid sound model"));
+ goto error;
+ }
+ strncat(modstr, model, size);
+ size -= strlen(model);
+ sound = sound->next;
+ if (sound)
+ strncat(modstr, ",", size--);
+ }
+ if (!((*argv)[++n] = modstr))
+ goto no_memory;
+ }
+
if (vm->migrateFrom[0]) {
if (!((*argv)[++n] = strdup("-S")))
goto no_memory;
@@ -2602,6 +2726,9 @@ qemudParseVMDeviceDef(virConnectPtr conn,
} else if (xmlStrEqual(node->name, BAD_CAST "input")) {
dev->type = QEMUD_DEVICE_DISK;
qemudParseInputXML(conn, &(dev->data.input), node);
+ } else if (xmlStrEqual(node->name, BAD_CAST "sound")) {
+ dev->type = QEMUD_DEVICE_SOUND;
+ qemudParseSoundXML(conn, &(dev->data.sound), node);
} else {
qemudReportError(conn, NULL, NULL, VIR_ERR_XML_ERROR,
"%s", _("unknown device type"));
@@ -3475,6 +3602,7 @@ char *qemudGenerateXML(virConnectPtr conn,
const struct qemud_vm_disk_def *disk;
const struct qemud_vm_net_def *net;
const struct qemud_vm_input_def *input;
+ const struct qemud_vm_sound_def *sound;
const struct qemud_vm_chr_def *chr;
const char *type = NULL;
int n;
@@ -3717,6 +3845,18 @@ char *qemudGenerateXML(virConnectPtr conn,
break;
}
+ sound = def->sounds;
+ while(sound) {
+ const char *model = qemudSoundModelToString(sound->model);
+ if (!model) {
+ qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
+ _("invalid sound model"));
+ goto cleanup;
+ }
+ virBufferVSprintf(&buf, " \n", model);
+ sound = sound->next;
+ }
+
virBufferAddLit(&buf, " \n");
virBufferAddLit(&buf, "\n");
diff --git a/src/qemu_conf.h b/src/qemu_conf.h
index bd8d8b2..46c6fb7 100644
--- a/src/qemu_conf.h
+++ b/src/qemu_conf.h
@@ -186,11 +186,24 @@ struct qemud_vm_input_def {
struct qemud_vm_input_def *next;
};
+enum qemu_vm_sound_model {
+ QEMU_SOUND_NONE = 0,
+ QEMU_SOUND_SB16,
+ QEMU_SOUND_ES1370,
+ QEMU_SOUND_PCSPK,
+};
+
+struct qemud_vm_sound_def {
+ int model;
+ struct qemud_vm_sound_def *next;
+};
+
/* Flags for the 'type' field in next struct */
enum qemud_vm_device_type {
QEMUD_DEVICE_DISK,
QEMUD_DEVICE_NET,
QEMUD_DEVICE_INPUT,
+ QEMUD_DEVICE_SOUND,
};
struct qemud_vm_device_def {
@@ -199,6 +212,7 @@ struct qemud_vm_device_def {
struct qemud_vm_disk_def disk;
struct qemud_vm_net_def net;
struct qemud_vm_input_def input;
+ struct qemud_vm_sound_def sound;
} data;
};
@@ -274,6 +288,9 @@ struct qemud_vm_def {
unsigned int ninputs;
struct qemud_vm_input_def *inputs;
+ unsigned int nsounds;
+ struct qemud_vm_sound_def *sounds;
+
unsigned int nserials;
struct qemud_vm_chr_def *serials;
diff --git a/src/xend_internal.c b/src/xend_internal.c
index 29a16dd..0817b7d 100644
--- a/src/xend_internal.c
+++ b/src/xend_internal.c
@@ -851,6 +851,107 @@ urlencode(const char *string)
return buffer;
}
+
+/* Applicable sound models */
+const char *sound_models[] = { "sb16", "es1370" };
+
+/**
+ * is_sound_model_valid:
+ * @model : model string to check against whitelist
+ *
+ * checks passed model string against whitelist of acceptable models
+ *
+ * Returns 0 if invalid, 1 otherwise
+ */
+int is_sound_model_valid(const char *model) {
+ int i;
+
+ for (i = 0; i < sizeof(sound_models)/sizeof(*sound_models); ++i) {
+ if (STREQ(model, sound_models[i])) {
+ return 1;
+ }
+ }
+ return 0;
+}
+
+/**
+ * is_sound_model_conflict:
+ * @model : model string to look for duplicates of
+ * @soundstr : soundhw string for the form m1,m2,m3 ...
+ *
+ * Returns 0 if no conflict, 1 otherwise
+ */
+int is_sound_model_conflict(const char *model, const char *soundstr) {
+
+ char *dupe;
+ char *cur = (char *) soundstr;
+ while ((dupe = strstr(cur, model))) {
+ if (( (dupe == cur) || // (Start of line |
+ (*(dupe - 1) == ',') ) && // Preceded by comma) &
+ ( (dupe[strlen(model)] == ',') || // (Ends with comma |
+ (dupe[strlen(model)] == '\0') )) // Ends whole string)
+ return 1;
+ else
+ cur = dupe + strlen(model);
+ }
+ return 0;
+}
+
+/**
+ * sound_string_to_xml:
+ * @soundstr : soundhw string for the form m1,m2,m3 ...
+ *
+ * Parses the passed string and returns a heap allocated string containing
+ * the valid libvirt soundxml. Must be free'd by caller.
+ *
+ * Returns NULL on fail, xml string on success (can be the empty string).
+ */
+char *sound_string_to_xml(const char *sound) {
+
+ virBuffer buf = VIR_BUFFER_INITIALIZER;
+
+ while (sound) {
+ int modelsize, valid, collision = 0;
+ char *model = NULL;
+ char *model_end = strchr(sound, ',');
+ modelsize = (model_end ? (model_end - sound) : strlen(sound));
+
+ if(!(model = strndup(sound, modelsize)))
+ goto error;
+
+ if (!(valid = is_sound_model_valid(model))) {
+ // Check for magic 'all' model. If found, throw out current xml
+ // and build with all available models
+ if (STREQ(model, "all")) {
+ int i;
+ free(virBufferContentAndReset(&buf));
+
+ for (i=0; i < sizeof(sound_models)/sizeof(*sound_models); ++i)
+ virBufferVSprintf(&buf, " \n",
+ sound_models[i]);
+ free(model);
+ break;
+ }
+ }
+
+ if (valid && model_end)
+ collision = is_sound_model_conflict(model, model_end);
+ if (valid && !collision)
+ virBufferVSprintf(&buf, " \n", model);
+
+ sound = (model_end ? ++model_end : NULL);
+ free(model);
+ }
+
+ if (virBufferError(&buf))
+ goto error;
+ return virBufferContentAndReset(&buf);
+
+ error:
+ free(virBufferContentAndReset(&buf));
+ return NULL;
+}
+
#endif /* ! PROXY */
/* PUBLIC FUNCTIONS */
@@ -2079,6 +2180,23 @@ xend_parse_sexp_desc(virConnectPtr conn, struct sexpr *root,
}
free(tty);
+ if (hvm) {
+ if (sexpr_node(root, "domain/image/hvm/soundhw")) {
+ char *soundxml;
+ tmp = sexpr_node(root, "domain/image/hvm/soundhw");
+ if (tmp && *tmp) {
+ if ((soundxml = sound_string_to_xml(tmp))) {
+ virBufferVSprintf(&buf, "%s", soundxml);
+ free(soundxml);
+ } else {
+ virXendError(conn, VIR_ERR_INTERNAL_ERROR,
+ _("parsing soundhw string failed."));
+ goto error;
+ }
+ }
+ }
+ }
+
virBufferAddLit(&buf, " \n");
virBufferAddLit(&buf, "\n");
diff --git a/src/xend_internal.h b/src/xend_internal.h
index d56d73d..80ef4f6 100644
--- a/src/xend_internal.h
+++ b/src/xend_internal.h
@@ -189,6 +189,11 @@ char *xenDaemonDomainDumpXMLByName(virConnectPtr xend,
char *xend_parse_domain_sexp(virConnectPtr conn, char *root, int xendConfigVersion);
+ int is_sound_model_valid(const char *model);
+ int is_sound_model_conflict(const char *model, const char *soundstr);
+ char *sound_string_to_xml(const char *sound);
+
+
/* refactored ones */
int xenDaemonOpen(virConnectPtr conn, xmlURIPtr uri, virConnectAuthPtr auth, int flags);
int xenDaemonClose(virConnectPtr conn);
diff --git a/src/xm_internal.c b/src/xm_internal.c
index 815f08b..c820c53 100644
--- a/src/xm_internal.c
+++ b/src/xm_internal.c
@@ -1050,16 +1050,34 @@ char *xenXMDomainFormatXML(virConnectPtr conn, virConfPtr conf) {
virBufferAddLit(&buf, " \n");
}
+ if (hvm) {
+ if ((xenXMConfigGetString(conf, "soundhw", &str) == 0) && str) {
+ char *soundxml;
+ if ((soundxml = sound_string_to_xml(str))) {
+ virBufferVSprintf(&buf, "%s", soundxml);
+ free(soundxml);
+ } else {
+ xenXMError(conn, VIR_ERR_INTERNAL_ERROR,
+ _("parsing soundhw string failed."));
+ goto error;
+ }
+ }
+ }
+
virBufferAddLit(&buf, " \n");
virBufferAddLit(&buf, "\n");
if (virBufferError(&buf)) {
xenXMError(conn, VIR_ERR_NO_MEMORY, _("allocate buffer"));
- return NULL;
+ goto error;
}
return virBufferContentAndReset(&buf);
+
+ error:
+ free(virBufferContentAndReset(&buf));
+ return NULL;
}
@@ -2311,6 +2329,17 @@ virConfPtr xenXMParseXMLToConfig(virConnectPtr conn, const char *xml) {
goto error;
}
}
+
+ if (virXPathNode("/domain/devices/sound", ctxt)) {
+ char *soundstr;
+ if (!(soundstr = virBuildSoundStringFromXML(conn, ctxt)))
+ goto error;
+ if (xenXMConfigSetString(conf, "soundhw", soundstr) < 0) {
+ free(soundstr);
+ goto error;
+ }
+ free(soundstr);
+ }
}
xmlFreeDoc(doc);
diff --git a/src/xml.c b/src/xml.c
index 5381cb1..e9e2e64 100644
--- a/src/xml.c
+++ b/src/xml.c
@@ -29,6 +29,7 @@
#include "util.h"
#include "xs_internal.h" /* for xenStoreDomainGetNetworkID */
#include "xen_unified.h"
+#include "xend_internal.h" /* for is_sound_* functions */
/**
* virXMLError:
@@ -288,6 +289,78 @@ virConvertCpuSet(virConnectPtr conn, const char *str, int maxcpu) {
free(cpuset);
return (res);
}
+
+/**
+ * virBuildSoundStringFromXML
+ * @sound buffer to populate
+ * @len size of preallocated buffer 'sound'
+ * @ctxt xml context to pull sound info from
+ *
+ * Builds a string of the form m1,m2,m3 from the different sound models
+ * in the xml. String must be free'd by caller.
+ *
+ * Returns string on success, NULL on error
+ */
+char * virBuildSoundStringFromXML(virConnectPtr conn,
+ xmlXPathContextPtr ctxt) {
+
+ int nb_nodes, size = 256;
+ char *sound;
+ xmlNodePtr *nodes = NULL;
+
+ if (!(sound = calloc(1, size+1))) {
+ virXMLError(conn, VIR_ERR_NO_MEMORY,
+ _("failed to allocate sound string"), 0);
+ return NULL;
+ }
+
+ nb_nodes = virXPathNodeSet("/domain/devices/sound", ctxt, &nodes);
+ if (nb_nodes > 0) {
+ int i;
+ for (i = 0; i < nb_nodes && size > 0; i++) {
+ char *model = NULL;
+ int collision = 0;
+
+ model = (char *) xmlGetProp(nodes[i], (xmlChar *) "model");
+ if (!model) {
+ virXMLError(conn, VIR_ERR_XML_ERROR,
+ _("no model for sound device"), 0);
+ goto error;
+ }
+
+ if (!is_sound_model_valid(model)) {
+ virXMLError(conn, VIR_ERR_XML_ERROR,
+ _("unknown sound model type"), 0);
+ free(model);
+ goto error;
+ }
+
+ // Check for duplicates in currently built string
+ if (*sound)
+ collision = is_sound_model_conflict(model, sound);
+
+ // If no collision, add to string
+ if (!collision) {
+ if (*sound && (size >= (strlen(model) + 1))) {
+ strncat(sound, ",", size--);
+ } else if (*sound || size < strlen(model)) {
+ free(model);
+ continue;
+ }
+ strncat(sound, model, size);
+ size -= strlen(model);
+ }
+
+ free(model);
+ }
+ }
+ free(nodes);
+ return sound;
+
+ error:
+ free(nodes);
+ return NULL;
+}
#endif /* WITH_XEN */
#ifndef PROXY
@@ -969,7 +1042,6 @@ virDomainParseXMLOSDescHVM(virConnectPtr conn, xmlNodePtr node,
}
}
-
/* get the cdrom device file */
/* Only XenD <= 3.0.2 wants cdrom config here */
if (xendConfigVersion == 1) {
@@ -1077,6 +1149,15 @@ virDomainParseXMLOSDescHVM(virConnectPtr conn, xmlNodePtr node,
}
}
+ cur = virXPathNode("/domain/devices/sound", ctxt);
+ if (cur) {
+ char *soundstr;
+ if (!(soundstr = virBuildSoundStringFromXML(conn, ctxt)))
+ goto error;
+ virBufferVSprintf(buf, "(soundhw '%s')", soundstr);
+ free(soundstr);
+ }
+
str = virXPathString("string(/domain/clock/@offset)", ctxt);
if (str != NULL && STREQ(str, "localtime")) {
virBufferAddLit(buf, "(localtime 1)");
diff --git a/src/xml.h b/src/xml.h
index d91a1b0..e5f2103 100644
--- a/src/xml.h
+++ b/src/xml.h
@@ -61,6 +61,8 @@ int virDomainXMLDevID(virDomainPtr domain,
char *class,
char *ref,
int ref_len);
+char * virBuildSoundStringFromXML(virConnectPtr conn,
+ xmlXPathContextPtr ctxt);
#endif
#ifdef __cplusplus
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-sound.args b/tests/qemuxml2argvdata/qemuxml2argv-sound.args
new file mode 100644
index 0000000..b8d7533
--- /dev/null
+++ b/tests/qemuxml2argvdata/qemuxml2argv-sound.args
@@ -0,0 +1 @@
+/usr/bin/qemu -M pc -m 214 -smp 1 -nographic -monitor pty -no-acpi -boot c -hda /dev/HostVG/QEMUGuest1 -net none -serial none -parallel none -usb -soundhw pcspk,es1370,sb16
\ No newline at end of file
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-sound.xml b/tests/qemuxml2argvdata/qemuxml2argv-sound.xml
new file mode 100644
index 0000000..a351f8d
--- /dev/null
+++ b/tests/qemuxml2argvdata/qemuxml2argv-sound.xml
@@ -0,0 +1,30 @@
+
+ QEMUGuest1
+ c7a5fdbd-edaf-9455-926a-d65c16db1809
+ 219200
+ 219200
+ 1
+
+ hvm
+
+
+
+ destroy
+ restart
+ destroy
+
+ /usr/bin/qemu
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/tests/qemuxml2argvtest.c b/tests/qemuxml2argvtest.c
index e7f6021..63abebe 100644
--- a/tests/qemuxml2argvtest.c
+++ b/tests/qemuxml2argvtest.c
@@ -159,6 +159,7 @@ main(int argc, char **argv)
DO_TEST("serial-many");
DO_TEST("parallel-tcp");
DO_TEST("console-compat");
+ DO_TEST("sound");
virCapabilitiesFree(driver.caps);
diff --git a/tests/sexpr2xmldata/sexpr2xml-fv-sound-all.sexpr b/tests/sexpr2xmldata/sexpr2xml-fv-sound-all.sexpr
new file mode 100644
index 0000000..415fb7b
--- /dev/null
+++ b/tests/sexpr2xmldata/sexpr2xml-fv-sound-all.sexpr
@@ -0,0 +1 @@
+(domain (domid 3)(name 'fvtest')(memory 400)(maxmem 400)(vcpus 1)(uuid 'b5d70dd275cdaca517769660b059d8bc')(on_poweroff 'destroy')(on_reboot 'restart')(on_crash 'restart')(image (hvm (kernel '/usr/lib/xen/boot/hvmloader')(device_model '/usr/lib64/xen/bin/qemu-dm')(boot c)(cdrom '/root/boot.iso')(acpi 1)(vnc 1)(keymap ja)(soundhw 'idontexit,es1370,all')))(device (vbd (dev 'ioemu:hda')(uname 'file:/root/foo.img')(mode 'w')))(device (vif (mac '00:16:3e:1b:b1:47')(bridge 'xenbr0')(script 'vif-bridge')(type ioemu))))
diff --git a/tests/sexpr2xmldata/sexpr2xml-fv-sound-all.xml b/tests/sexpr2xmldata/sexpr2xml-fv-sound-all.xml
new file mode 100644
index 0000000..e316a85
--- /dev/null
+++ b/tests/sexpr2xmldata/sexpr2xml-fv-sound-all.xml
@@ -0,0 +1,42 @@
+
+ fvtest
+ b5d70dd2-75cd-aca5-1776-9660b059d8bc
+
+ hvm
+ /usr/lib/xen/boot/hvmloader
+
+
+ 409600
+ 1
+ destroy
+ restart
+ restart
+
+
+
+
+
+ /usr/lib64/xen/bin/qemu-dm
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/tests/sexpr2xmldata/sexpr2xml-fv-sound.sexpr b/tests/sexpr2xmldata/sexpr2xml-fv-sound.sexpr
new file mode 100644
index 0000000..ab21c09
--- /dev/null
+++ b/tests/sexpr2xmldata/sexpr2xml-fv-sound.sexpr
@@ -0,0 +1 @@
+(domain (domid 3)(name 'fvtest')(memory 400)(maxmem 400)(vcpus 1)(uuid 'b5d70dd275cdaca517769660b059d8bc')(on_poweroff 'destroy')(on_reboot 'restart')(on_crash 'restart')(image (hvm (kernel '/usr/lib/xen/boot/hvmloader')(device_model '/usr/lib64/xen/bin/qemu-dm')(boot c)(cdrom '/root/boot.iso')(acpi 1)(vnc 1)(keymap ja)(soundhw 'sb16,es1370,idontexist,es1370more')))(device (vbd (dev 'ioemu:hda')(uname 'file:/root/foo.img')(mode 'w')))(device (vif (mac '00:16:3e:1b:b1:47')(bridge 'xenbr0')(script 'vif-bridge')(type ioemu))))
diff --git a/tests/sexpr2xmldata/sexpr2xml-fv-sound.xml b/tests/sexpr2xmldata/sexpr2xml-fv-sound.xml
new file mode 100644
index 0000000..e316a85
--- /dev/null
+++ b/tests/sexpr2xmldata/sexpr2xml-fv-sound.xml
@@ -0,0 +1,42 @@
+
+ fvtest
+ b5d70dd2-75cd-aca5-1776-9660b059d8bc
+
+ hvm
+ /usr/lib/xen/boot/hvmloader
+
+
+ 409600
+ 1
+ destroy
+ restart
+ restart
+
+
+
+
+
+ /usr/lib64/xen/bin/qemu-dm
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/tests/sexpr2xmltest.c b/tests/sexpr2xmltest.c
index b7103d6..6a27b40 100644
--- a/tests/sexpr2xmltest.c
+++ b/tests/sexpr2xmltest.c
@@ -136,6 +136,9 @@ main(int argc, char **argv)
DO_TEST("fv-serial-unix", "fv-serial-unix", 1);
DO_TEST("fv-parallel-tcp", "fv-parallel-tcp", 1);
+ DO_TEST("fv-sound", "fv-sound", 1);
+ DO_TEST("fv-sound-all", "fv-sound-all", 1);
+
exit(ret==0 ? EXIT_SUCCESS : EXIT_FAILURE);
}
#else /* WITHOUT_XEN */
diff --git a/tests/xmconfigdata/test-fullvirt-sound.cfg b/tests/xmconfigdata/test-fullvirt-sound.cfg
new file mode 100755
index 0000000..7d77f94
--- /dev/null
+++ b/tests/xmconfigdata/test-fullvirt-sound.cfg
@@ -0,0 +1,26 @@
+name = "XenGuest2"
+uuid = "c7a5fdb2-cdaf-9455-926a-d65c16db1809"
+maxmem = 579
+memory = 394
+vcpus = 1
+builder = "hvm"
+kernel = "/usr/lib/xen/boot/hvmloader"
+boot = "d"
+pae = 1
+acpi = 1
+apic = 1
+localtime = 0
+on_poweroff = "destroy"
+on_reboot = "restart"
+on_crash = "restart"
+device_model = "/usr/lib/xen/bin/qemu-dm"
+sdl = 0
+vnc = 1
+vncunused = 1
+vnclisten = "127.0.0.1"
+vncpasswd = "123poi"
+disk = [ "phy:/dev/HostVG/XenGuest2,hda,w", "file:/root/boot.iso,hdc:cdrom,r" ]
+vif = [ "mac=00:16:3E:66:92:9C,bridge=xenbr1,type=ioemu" ]
+parallel = "none"
+serial = "none"
+soundhw = "sb16,es1370"
diff --git a/tests/xmconfigdata/test-fullvirt-sound.xml b/tests/xmconfigdata/test-fullvirt-sound.xml
new file mode 100644
index 0000000..5ecf955
--- /dev/null
+++ b/tests/xmconfigdata/test-fullvirt-sound.xml
@@ -0,0 +1,43 @@
+
+ XenGuest2
+ c7a5fdb2-cdaf-9455-926a-d65c16db1809
+
+ hvm
+ /usr/lib/xen/boot/hvmloader
+
+
+ 403456
+ 592896
+ 1
+ destroy
+ restart
+ restart
+
+
+
+
+
+
+
+ /usr/lib/xen/bin/qemu-dm
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/tests/xmconfigtest.c b/tests/xmconfigtest.c
index de446aa..3725ae5 100644
--- a/tests/xmconfigtest.c
+++ b/tests/xmconfigtest.c
@@ -221,6 +221,8 @@ main(int argc, char **argv)
DO_TEST("fullvirt-parallel-tcp", 2);
+ DO_TEST("fullvirt-sound", 2);
+
exit(ret==0 ? EXIT_SUCCESS : EXIT_FAILURE);
}
#else /* WITHOUT_XEN */
diff --git a/tests/xml2sexprdata/xml2sexpr-fv-sound.sexpr b/tests/xml2sexprdata/xml2sexpr-fv-sound.sexpr
new file mode 100644
index 0000000..71f0a62
--- /dev/null
+++ b/tests/xml2sexprdata/xml2sexpr-fv-sound.sexpr
@@ -0,0 +1 @@
+(vm (name 'fvtest')(memory 400)(maxmem 400)(vcpus 1)(uuid 'b5d70dd275cdaca517769660b059d8bc')(on_poweroff 'destroy')(on_reboot 'restart')(on_crash 'restart')(image (hvm (kernel '/usr/lib/xen/boot/hvmloader')(vcpus 1)(boot c)(cdrom '/root/boot.iso')(acpi 1)(usb 1)(parallel none)(serial none)(soundhw 'sb16,es1370')(device_model '/usr/lib64/xen/bin/qemu-dm')(vnc 1)))(device (vbd (dev 'ioemu:hda')(uname 'file:/root/foo.img')(mode 'w')))(device (vif (mac '00:16:3e:1b:b1:47')(bridge 'xenbr0')(script 'vif-bridge')(type ioemu))))
\ No newline at end of file
diff --git a/tests/xml2sexprdata/xml2sexpr-fv-sound.xml b/tests/xml2sexprdata/xml2sexpr-fv-sound.xml
new file mode 100644
index 0000000..863659c
--- /dev/null
+++ b/tests/xml2sexprdata/xml2sexpr-fv-sound.xml
@@ -0,0 +1,41 @@
+
+ fvtest
+ b5d70dd275cdaca517769660b059d8bc
+
+ hvm
+ /usr/lib/xen/boot/hvmloader
+
+
+ 409600
+ 1
+ destroy
+ restart
+ restart
+
+
+
+
+ /usr/lib64/xen/bin/qemu-dm
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/tests/xml2sexprtest.c b/tests/xml2sexprtest.c
index d04233a..547c66f 100644
--- a/tests/xml2sexprtest.c
+++ b/tests/xml2sexprtest.c
@@ -143,6 +143,8 @@ main(int argc, char **argv)
DO_TEST("fv-serial-unix", "fv-serial-unix", "fvtest", 1);
DO_TEST("fv-parallel-tcp", "fv-parallel-tcp", "fvtest", 1);
+ DO_TEST("fv-sound", "fv-sound", "fvtest", 1);
+
exit(ret==0 ? EXIT_SUCCESS : EXIT_FAILURE);
}