Hi,
this is the patch to add support for multiple serial ports to the
libvirt Xen driver. It support both old style (serial = "pty") and
new style (serial = [ "/dev/ttyS0", "/dev/ttyS1" ]) definition and
tests for xml2sexpr, sexpr2xml and xmconfig have been added as well.
Written and tested on RHEL-5 Xen dom0 and working as designed but
the Xen version have to have patch for RHBZ #614004 but this patch
is for upstream version of libvirt.
Also, this patch is addressing issue described in RHBZ #670789.
Differences between v2 and v3:
* Fixed serial port handling if we have definition of device in non-zero port number
* Added second test for first port undefined (i.e. port value > 0 for just one
serial port)
This between v3 and v4 (this one):
* Traversal lookup to ensure the right order of the serial ports has
been implemented
* Parsing and finding new available port number for parallel port has
been added as well
Michal
Signed-off-by: Michal Novotny <minovotn(a)redhat.com>
---
src/conf/domain_conf.c | 2 +-
src/xenxs/xen_sxpr.c | 92 ++++++++++--
src/xenxs/xen_xm.c | 148 +++++++++++++++++---
.../sexpr2xml-fv-serial-dev-2-ports.sexpr | 1 +
.../sexpr2xml-fv-serial-dev-2-ports.xml | 53 +++++++
.../sexpr2xml-fv-serial-dev-2nd-port.sexpr | 1 +
.../sexpr2xml-fv-serial-dev-2nd-port.xml | 49 +++++++
tests/sexpr2xmltest.c | 2 +
.../test-fullvirt-serial-dev-2-ports.cfg | 25 ++++
.../test-fullvirt-serial-dev-2-ports.xml | 55 +++++++
.../test-fullvirt-serial-dev-2nd-port.cfg | 25 ++++
.../test-fullvirt-serial-dev-2nd-port.xml | 53 +++++++
tests/xmconfigtest.c | 2 +
.../xml2sexpr-fv-serial-dev-2-ports.sexpr | 1 +
.../xml2sexpr-fv-serial-dev-2-ports.xml | 44 ++++++
.../xml2sexpr-fv-serial-dev-2nd-port.sexpr | 1 +
.../xml2sexpr-fv-serial-dev-2nd-port.xml | 40 ++++++
tests/xml2sexprtest.c | 2 +
18 files changed, 558 insertions(+), 38 deletions(-)
create mode 100644 tests/sexpr2xmldata/sexpr2xml-fv-serial-dev-2-ports.sexpr
create mode 100644 tests/sexpr2xmldata/sexpr2xml-fv-serial-dev-2-ports.xml
create mode 100644 tests/sexpr2xmldata/sexpr2xml-fv-serial-dev-2nd-port.sexpr
create mode 100644 tests/sexpr2xmldata/sexpr2xml-fv-serial-dev-2nd-port.xml
create mode 100644 tests/xmconfigdata/test-fullvirt-serial-dev-2-ports.cfg
create mode 100644 tests/xmconfigdata/test-fullvirt-serial-dev-2-ports.xml
create mode 100644 tests/xmconfigdata/test-fullvirt-serial-dev-2nd-port.cfg
create mode 100644 tests/xmconfigdata/test-fullvirt-serial-dev-2nd-port.xml
create mode 100644 tests/xml2sexprdata/xml2sexpr-fv-serial-dev-2-ports.sexpr
create mode 100644 tests/xml2sexprdata/xml2sexpr-fv-serial-dev-2-ports.xml
create mode 100644 tests/xml2sexprdata/xml2sexpr-fv-serial-dev-2nd-port.sexpr
create mode 100644 tests/xml2sexprdata/xml2sexpr-fv-serial-dev-2nd-port.xml
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index 0e68160..6432b74 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -5555,7 +5555,7 @@ static virDomainDefPtr virDomainDefParseXML(virCapsPtr caps,
for (j = 0 ; j < i ; j++) {
if (def->parallels[j]->target.port > maxport)
maxport = def->parallels[j]->target.port;
- }
+ }
chr->target.port = maxport + 1;
}
def->parallels[def->nparallels++] = chr;
diff --git a/src/xenxs/xen_sxpr.c b/src/xenxs/xen_sxpr.c
index aac2585..520265d 100644
--- a/src/xenxs/xen_sxpr.c
+++ b/src/xenxs/xen_sxpr.c
@@ -177,6 +177,9 @@ xenParseSxprChar(const char *value,
if (value[0] == '/') {
def->source.type = VIR_DOMAIN_CHR_TYPE_DEV;
+ def->source.data.file.path = strdup(value);
+ if (!def->source.data.file.path)
+ goto no_memory;
} else {
if ((tmp = strchr(value, ':')) != NULL) {
*tmp = '\0';
@@ -1280,18 +1283,55 @@ xenParseSxpr(const struct sexpr *root,
/* Character device config */
if (hvm) {
- tmp = sexpr_node(root, "domain/image/hvm/serial");
- if (tmp && STRNEQ(tmp, "none")) {
- virDomainChrDefPtr chr;
- if ((chr = xenParseSxprChar(tmp, tty)) == NULL)
- goto error;
- if (VIR_REALLOC_N(def->serials, def->nserials+1) < 0) {
- virDomainChrDefFree(chr);
- goto no_memory;
+ const struct sexpr *serial_root;
+ bool have_multiple_serials = false;
+
+ serial_root = sexpr_lookup(root, "domain/image/hvm/serial");
+ if (serial_root) {
+ const struct sexpr *cur, *node, *cur2;
+ int ports_skipped = 0;
+
+ for (cur = serial_root; cur->kind == SEXPR_CONS; cur = cur->u.s.cdr) {
+ node = cur->u.s.car;
+
+ for (cur2 = node; cur2->kind == SEXPR_CONS; cur2 = cur2->u.s.cdr)
{
+ tmp = cur2->u.s.car->u.value;
+
+ if (tmp && STRNEQ(tmp, "none")) {
+ virDomainChrDefPtr chr;
+ if ((chr = xenParseSxprChar(tmp, tty)) == NULL)
+ goto error;
+ if (VIR_REALLOC_N(def->serials, def->nserials+1) < 0) {
+ virDomainChrDefFree(chr);
+ goto no_memory;
+ }
+ chr->deviceType = VIR_DOMAIN_CHR_DEVICE_TYPE_SERIAL;
+ chr->target.port = def->nserials + ports_skipped;
+ def->serials[def->nserials++] = chr;
+ }
+ else
+ ports_skipped++;
+
+ have_multiple_serials = true;
+ }
}
- chr->deviceType = VIR_DOMAIN_CHR_DEVICE_TYPE_SERIAL;
- def->serials[def->nserials++] = chr;
}
+
+ if (!have_multiple_serials) {
+ tmp = sexpr_node(root, "domain/image/hvm/serial");
+ if (tmp && STRNEQ(tmp, "none")) {
+ virDomainChrDefPtr chr;
+ if ((chr = xenParseSxprChar(tmp, tty)) == NULL)
+ goto error;
+ if (VIR_REALLOC_N(def->serials, def->nserials+1) < 0) {
+ virDomainChrDefFree(chr);
+ goto no_memory;
+ }
+ chr->deviceType = VIR_DOMAIN_CHR_DEVICE_TYPE_SERIAL;
+ def->serials[def->nserials++] = chr;
+ }
+ }
+
tmp = sexpr_node(root, "domain/image/hvm/parallel");
if (tmp && STRNEQ(tmp, "none")) {
virDomainChrDefPtr chr;
@@ -2121,10 +2161,34 @@ xenFormatSxpr(virConnectPtr conn,
virBufferAddLit(&buf, "(parallel none)");
}
if (def->serials) {
- virBufferAddLit(&buf, "(serial ");
- if (xenFormatSxprChr(def->serials[0], &buf) < 0)
- goto error;
- virBufferAddLit(&buf, ")");
+ if ((def->nserials > 1) || (def->serials[0]->target.port !=
0)) {
+ int maxport = -1;
+ int j = 0;
+
+ virBufferAddLit(&buf, "(serial (");
+ for (i = 0; i < def->nserials; i++)
+ if (def->serials[i]->target.port > maxport)
+ maxport = def->serials[i]->target.port;
+
+ for (i = 0; i <= maxport; i++) {
+ for (j = 0; j < def->nserials; j++) {
+ if (def->serials[j]->target.port == i) {
+ if (xenFormatSxprChr(def->serials[j], &buf) <
0)
+ goto error;
+ if (j < def->nserials - 1)
+ virBufferAddLit(&buf, " ");
+ continue;
+ }
+ }
+ }
+ virBufferAddLit(&buf, "))");
+ }
+ else {
+ virBufferAddLit(&buf, "(serial ");
+ if (xenFormatSxprChr(def->serials[0], &buf) < 0)
+ goto error;
+ virBufferAddLit(&buf, ")");
+ }
} else {
virBufferAddLit(&buf, "(serial none)");
}
diff --git a/src/xenxs/xen_xm.c b/src/xenxs/xen_xm.c
index ce590b9..e4499fc 100644
--- a/src/xenxs/xen_xm.c
+++ b/src/xenxs/xen_xm.c
@@ -965,20 +965,50 @@ xenParseXM(virConfPtr conf, int xendConfigVersion,
chr = NULL;
}
- if (xenXMConfigGetString(conf, "serial", &str, NULL) < 0)
- goto cleanup;
- if (str && STRNEQ(str, "none") &&
- !(chr = xenParseSxprChar(str, NULL)))
- goto cleanup;
+ /* Try to get the list of values to support multiple serial ports */
+ list = virConfGetValue(conf, "serial");
+ if (list && list->type == VIR_CONF_LIST) {
+ list = list->list;
+ while (list) {
+ char *port = NULL;
+
+ if ((list->type != VIR_CONF_STRING) || (list->str == NULL))
+ goto cleanup;
- if (chr) {
- if (VIR_ALLOC_N(def->serials, 1) < 0) {
- virDomainChrDefFree(chr);
- goto no_memory;
+ port = list->str;
+ if (VIR_ALLOC(chr) < 0)
+ goto no_memory;
+ if (port && STRNEQ(port, "none") &&
+ !(chr = xenParseSxprChar(port, NULL)))
+ goto cleanup;
+
+ if (VIR_REALLOC_N(def->serials, def->nserials+1) < 0)
+ goto no_memory;
+
+ chr->deviceType = VIR_DOMAIN_CHR_DEVICE_TYPE_SERIAL;
+ chr->target.port = def->nserials;
+
+ def->serials[def->nserials++] = chr;
+ chr = NULL;
+
+ list = list->next;
+ }
+ } else {
+ /* If domain is not using multiple serial ports we parse data old way */
+ if (xenXMConfigGetString(conf, "serial", &str, NULL) < 0)
+ goto cleanup;
+ if (str && STRNEQ(str, "none") &&
+ !(chr = xenParseSxprChar(str, NULL)))
+ goto cleanup;
+ if (chr) {
+ if (VIR_ALLOC_N(def->serials, 1) < 0) {
+ virDomainChrDefFree(chr);
+ goto no_memory;
+ }
+ chr->deviceType = VIR_DOMAIN_CHR_DEVICE_TYPE_SERIAL;
+ def->serials[0] = chr;
+ def->nserials++;
}
- chr->deviceType = VIR_DOMAIN_CHR_DEVICE_TYPE_SERIAL;
- def->serials[0] = chr;
- def->nserials++;
}
} else {
if (!(def->console = xenParseSxprChar("pty", NULL)))
@@ -1120,6 +1150,45 @@ cleanup:
return -1;
}
+static int xenFormatXMSerial(virConfValuePtr list,
+ virDomainChrDefPtr serial)
+{
+ virBuffer buf = VIR_BUFFER_INITIALIZER;
+ virConfValuePtr val, tmp;
+ int ret;
+
+ ret = xenFormatSxprChr(serial, &buf);
+ if (ret < 0) {
+ virReportOOMError();
+ goto cleanup;
+ }
+ if (virBufferError(&buf)) {
+ virReportOOMError();
+ goto cleanup;
+ }
+
+ if (VIR_ALLOC(val) < 0) {
+ virReportOOMError();
+ goto cleanup;
+ }
+
+ val->type = VIR_CONF_STRING;
+ val->str = virBufferContentAndReset(&buf);
+ tmp = list->list;
+ while (tmp && tmp->next)
+ tmp = tmp->next;
+ if (tmp)
+ tmp->next = val;
+ else
+ list->list = val;
+
+ return 0;
+
+cleanup:
+ virBufferFreeAndReset(&buf);
+ return -1;
+}
+
static int xenFormatXMNet(virConnectPtr conn,
virConfValuePtr list,
virDomainNetDefPtr net,
@@ -1678,17 +1747,50 @@ virConfPtr xenFormatXM(virConnectPtr conn,
}
if (def->nserials) {
- virBuffer buf = VIR_BUFFER_INITIALIZER;
- char *str;
- int ret;
+ if ((def->nserials == 1) && (def->serials[0]->target.port ==
0)) {
+ virBuffer buf = VIR_BUFFER_INITIALIZER;
+ char *str;
+ int ret;
+
+ ret = xenFormatSxprChr(def->serials[0], &buf);
+ str = virBufferContentAndReset(&buf);
+ if (ret == 0)
+ ret = xenXMConfigSetString(conf, "serial", str);
+ VIR_FREE(str);
+ if (ret < 0)
+ goto no_memory;
+ } else {
+ int j = 0;
+ int maxport = -1;
+ virConfValuePtr serialVal = NULL;
- ret = xenFormatSxprChr(def->serials[0], &buf);
- str = virBufferContentAndReset(&buf);
- if (ret == 0)
- ret = xenXMConfigSetString(conf, "serial", str);
- VIR_FREE(str);
- if (ret < 0)
- goto no_memory;
+ if (VIR_ALLOC(serialVal) < 0)
+ goto no_memory;
+ serialVal->type = VIR_CONF_LIST;
+ serialVal->list = NULL;
+
+ for (i = 0; i < def->nserials; i++)
+ if (def->serials[i]->target.port > maxport)
+ maxport = def->serials[i]->target.port;
+
+ for (i = 0; i <= maxport; i++) {
+ for (j = 0; j < def->nserials; j++) {
+ if (def->serials[j]->target.port == i) {
+ if (xenFormatXMSerial(serialVal, def->serials[j]) < 0)
+ goto cleanup;
+ continue;
+ }
+ }
+ }
+
+ if (serialVal->list != NULL) {
+ int ret = virConfSetValue(conf, "serial", serialVal);
+ serialVal = NULL;
+ if (ret < 0)
+ goto no_memory;
+ }
+ VIR_FREE(serialVal);
+ }
} else {
if (xenXMConfigSetString(conf, "serial", "none") < 0)
goto no_memory;
@@ -1721,4 +1823,4 @@ cleanup:
if (conf)
virConfFree(conf);
return (NULL);
-}
\ No newline at end of file
+}
diff --git a/tests/sexpr2xmldata/sexpr2xml-fv-serial-dev-2-ports.sexpr
b/tests/sexpr2xmldata/sexpr2xml-fv-serial-dev-2-ports.sexpr
new file mode 100644
index 0000000..e709eb0
--- /dev/null
+++ b/tests/sexpr2xmldata/sexpr2xml-fv-serial-dev-2-ports.sexpr
@@ -0,0 +1 @@
+(domain (domid 1)(name 'fvtest')(memory 400)(maxmem 400)(vcpus 1)(uuid
'b5d70dd275cdaca517769660b059d8ff')(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 (/dev/ttyS0
/dev/ttyS1))(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))))
diff --git a/tests/sexpr2xmldata/sexpr2xml-fv-serial-dev-2-ports.xml
b/tests/sexpr2xmldata/sexpr2xml-fv-serial-dev-2-ports.xml
new file mode 100644
index 0000000..5e085f9
--- /dev/null
+++ b/tests/sexpr2xmldata/sexpr2xml-fv-serial-dev-2-ports.xml
@@ -0,0 +1,53 @@
+<domain type='xen' id='1'>
+ <name>fvtest</name>
+ <uuid>b5d70dd2-75cd-aca5-1776-9660b059d8ff</uuid>
+ <memory>409600</memory>
+ <currentMemory>409600</currentMemory>
+ <vcpu>1</vcpu>
+ <os>
+ <type>hvm</type>
+ <loader>/usr/lib/xen/boot/hvmloader</loader>
+ <boot dev='hd'/>
+ </os>
+ <features>
+ <acpi/>
+ </features>
+ <clock offset='utc'/>
+ <on_poweroff>destroy</on_poweroff>
+ <on_reboot>restart</on_reboot>
+ <on_crash>restart</on_crash>
+ <devices>
+ <emulator>/usr/lib64/xen/bin/qemu-dm</emulator>
+ <disk type='file' device='disk'>
+ <driver name='file'/>
+ <source file='/root/foo.img'/>
+ <target dev='hda' bus='ide'/>
+ </disk>
+ <disk type='file' device='cdrom'>
+ <driver name='file'/>
+ <source file='/root/boot.iso'/>
+ <target dev='hdc' bus='ide'/>
+ <readonly/>
+ </disk>
+ <interface type='bridge'>
+ <mac address='00:16:3e:1b:b1:47'/>
+ <source bridge='xenbr0'/>
+ <script path='vif-bridge'/>
+ <target dev='vif1.0'/>
+ </interface>
+ <serial type='dev'>
+ <source path='/dev/ttyS0'/>
+ <target port='0'/>
+ </serial>
+ <serial type='dev'>
+ <source path='/dev/ttyS1'/>
+ <target port='1'/>
+ </serial>
+ <console type='dev'>
+ <source path='/dev/ttyS0'/>
+ <target type='serial' port='0'/>
+ </console>
+ <input type='mouse' bus='ps2'/>
+ <graphics type='vnc' port='5901' autoport='no'/>
+ </devices>
+</domain>
diff --git a/tests/sexpr2xmldata/sexpr2xml-fv-serial-dev-2nd-port.sexpr
b/tests/sexpr2xmldata/sexpr2xml-fv-serial-dev-2nd-port.sexpr
new file mode 100644
index 0000000..3a14cf9
--- /dev/null
+++ b/tests/sexpr2xmldata/sexpr2xml-fv-serial-dev-2nd-port.sexpr
@@ -0,0 +1 @@
+(domain (domid 1)(name 'fvtest')(memory 400)(maxmem 400)(vcpus 1)(uuid
'b5d70dd275cdaca517769660b059d8ff')(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
/dev/ttyS1))(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))))
diff --git a/tests/sexpr2xmldata/sexpr2xml-fv-serial-dev-2nd-port.xml
b/tests/sexpr2xmldata/sexpr2xml-fv-serial-dev-2nd-port.xml
new file mode 100644
index 0000000..5619376
--- /dev/null
+++ b/tests/sexpr2xmldata/sexpr2xml-fv-serial-dev-2nd-port.xml
@@ -0,0 +1,49 @@
+<domain type='xen' id='1'>
+ <name>fvtest</name>
+ <uuid>b5d70dd2-75cd-aca5-1776-9660b059d8ff</uuid>
+ <memory>409600</memory>
+ <currentMemory>409600</currentMemory>
+ <vcpu>1</vcpu>
+ <os>
+ <type>hvm</type>
+ <loader>/usr/lib/xen/boot/hvmloader</loader>
+ <boot dev='hd'/>
+ </os>
+ <features>
+ <acpi/>
+ </features>
+ <clock offset='utc'/>
+ <on_poweroff>destroy</on_poweroff>
+ <on_reboot>restart</on_reboot>
+ <on_crash>restart</on_crash>
+ <devices>
+ <emulator>/usr/lib64/xen/bin/qemu-dm</emulator>
+ <disk type='file' device='disk'>
+ <driver name='file'/>
+ <source file='/root/foo.img'/>
+ <target dev='hda' bus='ide'/>
+ </disk>
+ <disk type='file' device='cdrom'>
+ <driver name='file'/>
+ <source file='/root/boot.iso'/>
+ <target dev='hdc' bus='ide'/>
+ <readonly/>
+ </disk>
+ <interface type='bridge'>
+ <mac address='00:16:3e:1b:b1:47'/>
+ <source bridge='xenbr0'/>
+ <script path='vif-bridge'/>
+ <target dev='vif1.0'/>
+ </interface>
+ <serial type='dev'>
+ <source path='/dev/ttyS1'/>
+ <target port='1'/>
+ </serial>
+ <console type='dev'>
+ <source path='/dev/ttyS1'/>
+ <target type='serial' port='1'/>
+ </console>
+ <input type='mouse' bus='ps2'/>
+ <graphics type='vnc' port='5901' autoport='no'/>
+ </devices>
+</domain>
diff --git a/tests/sexpr2xmltest.c b/tests/sexpr2xmltest.c
index 9995ec4..9f74ece 100644
--- a/tests/sexpr2xmltest.c
+++ b/tests/sexpr2xmltest.c
@@ -168,6 +168,8 @@ mymain(int argc, char **argv)
DO_TEST("fv-serial-null", "fv-serial-null", 1);
DO_TEST("fv-serial-file", "fv-serial-file", 1);
+ DO_TEST("fv-serial-dev-2-ports", "fv-serial-dev-2-ports", 1);
+ DO_TEST("fv-serial-dev-2nd-port", "fv-serial-dev-2nd-port", 1);
DO_TEST("fv-serial-stdio", "fv-serial-stdio", 1);
DO_TEST("fv-serial-pty", "fv-serial-pty", 1);
DO_TEST("fv-serial-pipe", "fv-serial-pipe", 1);
diff --git a/tests/xmconfigdata/test-fullvirt-serial-dev-2-ports.cfg
b/tests/xmconfigdata/test-fullvirt-serial-dev-2-ports.cfg
new file mode 100644
index 0000000..86e7998
--- /dev/null
+++ b/tests/xmconfigdata/test-fullvirt-serial-dev-2-ports.cfg
@@ -0,0 +1,25 @@
+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,script=vif-bridge,model=e1000,type=ioemu"
]
+parallel = "none"
+serial = [ "/dev/ttyS0", "/dev/ttyS1" ]
diff --git a/tests/xmconfigdata/test-fullvirt-serial-dev-2-ports.xml
b/tests/xmconfigdata/test-fullvirt-serial-dev-2-ports.xml
new file mode 100644
index 0000000..be5f8ee
--- /dev/null
+++ b/tests/xmconfigdata/test-fullvirt-serial-dev-2-ports.xml
@@ -0,0 +1,55 @@
+<domain type='xen'>
+ <name>XenGuest2</name>
+ <uuid>c7a5fdb2-cdaf-9455-926a-d65c16db1809</uuid>
+ <memory>592896</memory>
+ <currentMemory>403456</currentMemory>
+ <vcpu>1</vcpu>
+ <os>
+ <type arch='i686' machine='xenfv'>hvm</type>
+ <loader>/usr/lib/xen/boot/hvmloader</loader>
+ <boot dev='cdrom'/>
+ </os>
+ <features>
+ <acpi/>
+ <apic/>
+ <pae/>
+ </features>
+ <clock offset='utc'/>
+ <on_poweroff>destroy</on_poweroff>
+ <on_reboot>restart</on_reboot>
+ <on_crash>restart</on_crash>
+ <devices>
+ <emulator>/usr/lib/xen/bin/qemu-dm</emulator>
+ <disk type='block' device='disk'>
+ <driver name='phy'/>
+ <source dev='/dev/HostVG/XenGuest2'/>
+ <target dev='hda' bus='ide'/>
+ </disk>
+ <disk type='file' device='cdrom'>
+ <driver name='file'/>
+ <source file='/root/boot.iso'/>
+ <target dev='hdc' bus='ide'/>
+ <readonly/>
+ </disk>
+ <interface type='bridge'>
+ <mac address='00:16:3e:66:92:9c'/>
+ <source bridge='xenbr1'/>
+ <script path='vif-bridge'/>
+ <model type='e1000'/>
+ </interface>
+ <serial type='dev'>
+ <source path='/dev/ttyS0'/>
+ <target port='0'/>
+ </serial>
+ <serial type='dev'>
+ <source path='/dev/ttyS1'/>
+ <target port='1'/>
+ </serial>
+ <console type='dev'>
+ <source path='/dev/ttyS0'/>
+ <target type='serial' port='0'/>
+ </console>
+ <input type='mouse' bus='ps2'/>
+ <graphics type='vnc' port='-1' autoport='yes'
listen='127.0.0.1' passwd='123poi'/>
+ </devices>
+</domain>
diff --git a/tests/xmconfigdata/test-fullvirt-serial-dev-2nd-port.cfg
b/tests/xmconfigdata/test-fullvirt-serial-dev-2nd-port.cfg
new file mode 100644
index 0000000..47f0ad6
--- /dev/null
+++ b/tests/xmconfigdata/test-fullvirt-serial-dev-2nd-port.cfg
@@ -0,0 +1,25 @@
+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,script=vif-bridge,model=e1000,type=ioemu"
]
+parallel = "none"
+serial = [ "null", "/dev/ttyS1" ]
diff --git a/tests/xmconfigdata/test-fullvirt-serial-dev-2nd-port.xml
b/tests/xmconfigdata/test-fullvirt-serial-dev-2nd-port.xml
new file mode 100644
index 0000000..7c37879
--- /dev/null
+++ b/tests/xmconfigdata/test-fullvirt-serial-dev-2nd-port.xml
@@ -0,0 +1,53 @@
+<domain type='xen'>
+ <name>XenGuest2</name>
+ <uuid>c7a5fdb2-cdaf-9455-926a-d65c16db1809</uuid>
+ <memory>592896</memory>
+ <currentMemory>403456</currentMemory>
+ <vcpu>1</vcpu>
+ <os>
+ <type arch='i686' machine='xenfv'>hvm</type>
+ <loader>/usr/lib/xen/boot/hvmloader</loader>
+ <boot dev='cdrom'/>
+ </os>
+ <features>
+ <acpi/>
+ <apic/>
+ <pae/>
+ </features>
+ <clock offset='utc'/>
+ <on_poweroff>destroy</on_poweroff>
+ <on_reboot>restart</on_reboot>
+ <on_crash>restart</on_crash>
+ <devices>
+ <emulator>/usr/lib/xen/bin/qemu-dm</emulator>
+ <disk type='block' device='disk'>
+ <driver name='phy'/>
+ <source dev='/dev/HostVG/XenGuest2'/>
+ <target dev='hda' bus='ide'/>
+ </disk>
+ <disk type='file' device='cdrom'>
+ <driver name='file'/>
+ <source file='/root/boot.iso'/>
+ <target dev='hdc' bus='ide'/>
+ <readonly/>
+ </disk>
+ <interface type='bridge'>
+ <mac address='00:16:3e:66:92:9c'/>
+ <source bridge='xenbr1'/>
+ <script path='vif-bridge'/>
+ <model type='e1000'/>
+ </interface>
+ <serial type='null'>
+ <target port='0'/>
+ </serial>
+ <serial type='dev'>
+ <source path='/dev/ttyS1'/>
+ <target port='1'/>
+ </serial>
+ <console type='null'>
+ <target type='serial' port='0'/>
+ </console>
+ <input type='mouse' bus='ps2'/>
+ <graphics type='vnc' port='-1' autoport='yes'
listen='127.0.0.1' passwd='123poi'/>
+ </devices>
+</domain>
diff --git a/tests/xmconfigtest.c b/tests/xmconfigtest.c
index c4c3014..7d418a5 100644
--- a/tests/xmconfigtest.c
+++ b/tests/xmconfigtest.c
@@ -219,6 +219,8 @@ mymain(int argc, char **argv)
DO_TEST("fullvirt-usbtablet", 2);
DO_TEST("fullvirt-usbmouse", 2);
DO_TEST("fullvirt-serial-file", 2);
+ DO_TEST("fullvirt-serial-dev-2-ports", 2);
+ DO_TEST("fullvirt-serial-dev-2nd-port", 2);
DO_TEST("fullvirt-serial-null", 2);
DO_TEST("fullvirt-serial-pipe", 2);
DO_TEST("fullvirt-serial-pty", 2);
diff --git a/tests/xml2sexprdata/xml2sexpr-fv-serial-dev-2-ports.sexpr
b/tests/xml2sexprdata/xml2sexpr-fv-serial-dev-2-ports.sexpr
new file mode 100644
index 0000000..2048159
--- /dev/null
+++ b/tests/xml2sexprdata/xml2sexpr-fv-serial-dev-2-ports.sexpr
@@ -0,0 +1 @@
+(vm (name 'fvtest')(memory 400)(maxmem 400)(vcpus 1)(uuid
'b5d70dd2-75cd-aca5-1776-9660b059d8bc')(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 (/dev/ttyS0
/dev/ttyS1))(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')(model 'e1000')(type ioemu))))
\ No newline at end of file
diff --git a/tests/xml2sexprdata/xml2sexpr-fv-serial-dev-2-ports.xml
b/tests/xml2sexprdata/xml2sexpr-fv-serial-dev-2-ports.xml
new file mode 100644
index 0000000..e5d1817
--- /dev/null
+++ b/tests/xml2sexprdata/xml2sexpr-fv-serial-dev-2-ports.xml
@@ -0,0 +1,44 @@
+<domain type='xen'>
+ <name>fvtest</name>
+ <uuid>b5d70dd275cdaca517769660b059d8bc</uuid>
+ <os>
+ <type>hvm</type>
+ <loader>/usr/lib/xen/boot/hvmloader</loader>
+ <boot dev='hd'/>
+ </os>
+ <memory>409600</memory>
+ <vcpu>1</vcpu>
+ <on_poweroff>destroy</on_poweroff>
+ <on_reboot>restart</on_reboot>
+ <on_crash>restart</on_crash>
+ <features>
+ <acpi/>
+ </features>
+ <devices>
+ <emulator>/usr/lib64/xen/bin/qemu-dm</emulator>
+ <interface type='bridge'>
+ <source bridge='xenbr0'/>
+ <mac address='00:16:3e:1b:b1:47'/>
+ <script path='vif-bridge'/>
+ <model type='e1000'/>
+ </interface>
+ <disk type='file' device='cdrom'>
+ <source file='/root/boot.iso'/>
+ <target dev='hdc'/>
+ <readonly/>
+ </disk>
+ <disk type='file'>
+ <source file='/root/foo.img'/>
+ <target dev='ioemu:hda'/>
+ </disk>
+ <serial type='dev'>
+ <source path='/dev/ttyS0'/>
+ <target port='0'/>
+ </serial>
+ <serial type='dev'>
+ <source path='/dev/ttyS1'/>
+ <target port='1'/>
+ </serial>
+ <graphics type='vnc' port='5917' keymap='ja'/>
+ </devices>
+</domain>
diff --git a/tests/xml2sexprdata/xml2sexpr-fv-serial-dev-2nd-port.sexpr
b/tests/xml2sexprdata/xml2sexpr-fv-serial-dev-2nd-port.sexpr
new file mode 100644
index 0000000..2b33126
--- /dev/null
+++ b/tests/xml2sexprdata/xml2sexpr-fv-serial-dev-2nd-port.sexpr
@@ -0,0 +1 @@
+(vm (name 'fvtest')(memory 400)(maxmem 400)(vcpus 1)(uuid
'b5d70dd2-75cd-aca5-1776-9660b059d8bc')(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 (/dev/ttyS1))(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')(model
'e1000')(type ioemu))))
\ No newline at end of file
diff --git a/tests/xml2sexprdata/xml2sexpr-fv-serial-dev-2nd-port.xml
b/tests/xml2sexprdata/xml2sexpr-fv-serial-dev-2nd-port.xml
new file mode 100644
index 0000000..a310e5d
--- /dev/null
+++ b/tests/xml2sexprdata/xml2sexpr-fv-serial-dev-2nd-port.xml
@@ -0,0 +1,40 @@
+<domain type='xen'>
+ <name>fvtest</name>
+ <uuid>b5d70dd275cdaca517769660b059d8bc</uuid>
+ <os>
+ <type>hvm</type>
+ <loader>/usr/lib/xen/boot/hvmloader</loader>
+ <boot dev='hd'/>
+ </os>
+ <memory>409600</memory>
+ <vcpu>1</vcpu>
+ <on_poweroff>destroy</on_poweroff>
+ <on_reboot>restart</on_reboot>
+ <on_crash>restart</on_crash>
+ <features>
+ <acpi/>
+ </features>
+ <devices>
+ <emulator>/usr/lib64/xen/bin/qemu-dm</emulator>
+ <interface type='bridge'>
+ <source bridge='xenbr0'/>
+ <mac address='00:16:3e:1b:b1:47'/>
+ <script path='vif-bridge'/>
+ <model type='e1000'/>
+ </interface>
+ <disk type='file' device='cdrom'>
+ <source file='/root/boot.iso'/>
+ <target dev='hdc'/>
+ <readonly/>
+ </disk>
+ <disk type='file'>
+ <source file='/root/foo.img'/>
+ <target dev='ioemu:hda'/>
+ </disk>
+ <serial type='dev'>
+ <source path='/dev/ttyS1'/>
+ <target port='1'/>
+ </serial>
+ <graphics type='vnc' port='5917' keymap='ja'/>
+ </devices>
+</domain>
diff --git a/tests/xml2sexprtest.c b/tests/xml2sexprtest.c
index 0b46faa..cf530b6 100644
--- a/tests/xml2sexprtest.c
+++ b/tests/xml2sexprtest.c
@@ -149,6 +149,8 @@ mymain(int argc, char **argv)
DO_TEST("fv-serial-null", "fv-serial-null", "fvtest",
1);
DO_TEST("fv-serial-file", "fv-serial-file", "fvtest",
1);
+ DO_TEST("fv-serial-dev-2-ports", "fv-serial-dev-2-ports",
"fvtest", 1);
+ DO_TEST("fv-serial-dev-2nd-port", "fv-serial-dev-2nd-port",
"fvtest", 1);
DO_TEST("fv-serial-stdio", "fv-serial-stdio", "fvtest",
1);
DO_TEST("fv-serial-pty", "fv-serial-pty", "fvtest",
1);
DO_TEST("fv-serial-pipe", "fv-serial-pipe", "fvtest",
1);
--
1.7.3.2