[libvirt] [PATCH 1/2] add --crash support to "virsh dump"
by Paolo Bonzini
This patch adds the --crash option (already present in "xm dump-core")
to "virsh dump". virDomainCoreDump already has a flags argument, so
the API/ABI is untouched.
* include/libvirt/libvirt.h.in (virDomainCoreDumpFlags): New.
* src/test/test_driver.c (testDomainCoreDump): Do not crash
after dump unless VIR_DUMP_CRASH is given.
* src/qemu/qemu_driver.c (qemudDomainCoreDump): Shutdown the domain
instead of restarting it if --crash is passed.
* src/xen/xend_internal.c (xenDaemonDomainCoreDump): Support --crash.
* tools/virsh.c (opts_dump): Add --crash.
(cmdDump): Map it to flags for virDomainCoreDump and pass them.
---
include/libvirt/libvirt.h.in | 5 +++++
src/qemu/qemu_driver.c | 17 ++++++++++++++++-
src/test/test_driver.c | 19 ++++++++++---------
src/xen/xend_internal.c | 6 ++++--
tools/virsh.c | 7 ++++++-
5 files changed, 41 insertions(+), 13 deletions(-)
diff --git a/include/libvirt/libvirt.h.in b/include/libvirt/libvirt.h.in
index 5bc7694..c04b552 100644
--- a/include/libvirt/libvirt.h.in
+++ b/include/libvirt/libvirt.h.in
@@ -334,6 +334,11 @@ struct _virDomainInterfaceStats {
typedef virDomainInterfaceStatsStruct *virDomainInterfaceStatsPtr;
+/* Domain core dump flags. */
+typedef enum {
+ VIR_DUMP_CRASH = (1 << 0), /* crash after dump */
+} virDomainCoreDumpFlags;
+
/* Domain migration flags. */
typedef enum {
VIR_MIGRATE_LIVE = (1 << 0), /* live migration */
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index 92d4629..8e80144 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -3543,6 +3543,7 @@ static int qemudDomainCoreDump(virDomainPtr dom,
virDomainObjPtr vm;
int resume = 0, paused = 0;
int ret = -1, fd = -1;
+ virDomainEventPtr event = NULL;
const char *args[] = {
"cat",
NULL,
@@ -3633,10 +3634,17 @@ static int qemudDomainCoreDump(virDomainPtr dom,
goto endjob;
endjob:
+ if ((ret == 0) && (flags & VIR_DUMP_CRASH)) {
+ qemudShutdownVMDaemon(dom->conn, driver, vm);
+ event = virDomainEventNewFromObj(vm,
+ VIR_DOMAIN_EVENT_STOPPED,
+ VIR_DOMAIN_EVENT_STOPPED_CRASHED);
+ }
+
/* Since the monitor is always attached to a pty for libvirt, it
will support synchronous operations so we always get here after
the migration is complete. */
- if (resume && paused) {
+ else if (resume && paused) {
qemuDomainObjEnterMonitor(vm);
if (qemuMonitorStartCPUs(priv->mon, dom->conn) < 0) {
if (virGetLastError() == NULL)
@@ -3647,12 +3655,19 @@ endjob:
}
qemuDomainObjEndJob(vm);
+ if ((ret == 0) && (flags & VIR_DUMP_CRASH) && !vm->persistent) {
+ virDomainRemoveInactive(&driver->domains,
+ vm);
+ vm = NULL;
+ }
cleanup:
if (ret != 0)
unlink(path);
if (vm)
virDomainObjUnlock(vm);
+ if (event)
+ qemuDomainEventQueue(driver, event);
return ret;
}
diff --git a/src/test/test_driver.c b/src/test/test_driver.c
index 35f7571..7db9a4c 100644
--- a/src/test/test_driver.c
+++ b/src/test/test_driver.c
@@ -1911,15 +1911,16 @@ static int testDomainCoreDump(virDomainPtr domain,
goto cleanup;
}
- testDomainShutdownState(domain, privdom);
- event = virDomainEventNewFromObj(privdom,
- VIR_DOMAIN_EVENT_STOPPED,
- VIR_DOMAIN_EVENT_STOPPED_CRASHED);
-
- if (!privdom->persistent) {
- virDomainRemoveInactive(&privconn->domains,
- privdom);
- privdom = NULL;
+ if (flags & VIR_DUMP_CRASH) {
+ testDomainShutdownState(domain, privdom);
+ event = virDomainEventNewFromObj(privdom,
+ VIR_DOMAIN_EVENT_STOPPED,
+ VIR_DOMAIN_EVENT_STOPPED_CRASHED);
+ if (!privdom->persistent) {
+ virDomainRemoveInactive(&privconn->domains,
+ privdom);
+ privdom = NULL;
+ }
}
ret = 0;
diff --git a/src/xen/xend_internal.c b/src/xen/xend_internal.c
index 66d2e7f..360390d 100644
--- a/src/xen/xend_internal.c
+++ b/src/xen/xend_internal.c
@@ -3243,8 +3243,10 @@ xenDaemonDomainCoreDump(virDomainPtr domain, const char *filename,
return(-1);
}
- return xend_op(domain->conn, domain->name, "op", "dump", "file", filename,
- "live", "0", "crash", "0", NULL);
+ return xend_op(domain->conn, domain->name,
+ "op", "dump", "file", filename, "live", "0",
+ "crash", (flags & VIR_DUMP_CRASH ? "1" : "0"),
+ NULL);
}
/**
diff --git a/tools/virsh.c b/tools/virsh.c
index 9faac35..65eaa3b 100644
--- a/tools/virsh.c
+++ b/tools/virsh.c
@@ -1431,6 +1431,7 @@ static const vshCmdInfo info_dump[] = {
};
static const vshCmdOptDef opts_dump[] = {
+ {"crash", VSH_OT_BOOL, 0, gettext_noop("crash the domain after core dump")},
{"domain", VSH_OT_DATA, VSH_OFLAG_REQ, gettext_noop("domain name, id or uuid")},
{"file", VSH_OT_DATA, VSH_OFLAG_REQ, gettext_noop("where to dump the core")},
{NULL, 0, 0, NULL}
@@ -1443,6 +1444,7 @@ cmdDump(vshControl *ctl, const vshCmd *cmd)
char *name;
char *to;
int ret = TRUE;
+ int flags = 0;
if (!vshConnectionUsability(ctl, ctl->conn, TRUE))
return FALSE;
@@ -1453,7 +1455,10 @@ cmdDump(vshControl *ctl, const vshCmd *cmd)
if (!(dom = vshCommandOptDomain(ctl, cmd, &name)))
return FALSE;
- if (virDomainCoreDump(dom, to, 0) == 0) {
+ if (vshCommandOptBool (cmd, "crash"))
+ flags |= VIR_DUMP_CRASH;
+
+ if (virDomainCoreDump(dom, to, flags) == 0) {
vshPrint(ctl, _("Domain %s dumped to %s\n"), name, to);
} else {
vshError(ctl, _("Failed to core dump domain %s to %s"), name, to);
--
1.6.5.2
15 years
[libvirt] [PATCH] fix various breakages in qemu "virsh dump"
by Paolo Bonzini
1) qemuMigrateToCommand uses ">>" so we have to truncate the file
before starting the migration;
2) the command wasn't updated to chown the driver and set/restore
the security lavels;
3) the VM does not have to be resumed if migration fails;
4) the file is not removed when migration fails.
* src/qemu/qemu_driver.c (qemuDomainCoreDump): Truncate file before
dumping, set/restore ownership and security labels for the file.
---
src/qemu/qemu_driver.c | 48 +++++++++++++++++++++++++++++++++++++++++++++---
1 files changed, 45 insertions(+), 3 deletions(-)
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index c9b5ac2..92d4629 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -3542,7 +3542,7 @@ static int qemudDomainCoreDump(virDomainPtr dom,
struct qemud_driver *driver = dom->conn->privateData;
virDomainObjPtr vm;
int resume = 0, paused = 0;
- int ret = -1;
+ int ret = -1, fd = -1;
const char *args[] = {
"cat",
NULL,
@@ -3569,6 +3569,33 @@ static int qemudDomainCoreDump(virDomainPtr dom,
goto endjob;
}
+ /* Create an empty file with appropriate ownership. */
+ if ((fd = open(path, O_CREAT|O_TRUNC|O_WRONLY, S_IRUSR|S_IWUSR)) < 0) {
+ qemudReportError(dom->conn, dom, NULL, VIR_ERR_OPERATION_FAILED,
+ _("failed to create '%s'"), path);
+ goto endjob;
+ }
+
+ if (close(fd) < 0) {
+ virReportSystemError(dom->conn, errno,
+ _("unable to save file %s"),
+ path);
+ goto endjob;
+ }
+
+ if (driver->privileged &&
+ chown(path, driver->user, driver->group) < 0) {
+ virReportSystemError(NULL, errno,
+ _("unable to set ownership of '%s' to user %d:%d"),
+ path, driver->user, driver->group);
+ goto endjob;
+ }
+
+ if (driver->securityDriver &&
+ driver->securityDriver->domainSetSavedStateLabel &&
+ driver->securityDriver->domainSetSavedStateLabel(dom->conn, vm, path) == -1)
+ goto endjob;
+
/* Migrate will always stop the VM, so once we support live dumping
the resume condition will stay the same, independent of whether
the stop command is issued. */
@@ -3590,8 +3617,22 @@ static int qemudDomainCoreDump(virDomainPtr dom,
qemuDomainObjEnterMonitor(vm);
ret = qemuMonitorMigrateToCommand(priv->mon, 0, args, path);
qemuDomainObjExitMonitor(vm);
- paused = 1;
+ paused |= (ret == 0);
+
+ if (driver->privileged &&
+ chown(path, 0, 0) < 0) {
+ virReportSystemError(NULL, errno,
+ _("unable to set ownership of '%s' to user %d:%d"),
+ path, 0, 0);
+ goto endjob;
+ }
+ if (driver->securityDriver &&
+ driver->securityDriver->domainRestoreSavedStateLabel &&
+ driver->securityDriver->domainRestoreSavedStateLabel(dom->conn, path) == -1)
+ goto endjob;
+
+endjob:
/* Since the monitor is always attached to a pty for libvirt, it
will support synchronous operations so we always get here after
the migration is complete. */
@@ -3605,10 +3646,11 @@ static int qemudDomainCoreDump(virDomainPtr dom,
qemuDomainObjExitMonitor(vm);
}
-endjob:
qemuDomainObjEndJob(vm);
cleanup:
+ if (ret != 0)
+ unlink(path);
if (vm)
virDomainObjUnlock(vm);
return ret;
--
1.6.5.2
15 years
[libvirt] Improve the reliability of pty path parsing
by Matthew Booth
The following are improve the reliability of libvirt's mapping of character
devices to pty paths.
When qemu starts up it will output one or more lines of the form:
char device redirected to /dev/pts/5
Note that the character device this refers to is not indicated, so the only way
to match this up is by knowing the order they're written in. This is not a
well-defined interface, and is therefore voodoo-magic.
The current code works against current versions of QEMU. However, when using the
-chardev syntax of newer QEMU, the output order changes (putting chardev first).
The first patch works by making all character devices use -chardev if it's
available. As well as being a better syntax, this makes the output of the
redirection lines again match the order they're specified on the command line.
The second patch uses this ordering to parse the ptys for channel devices from
the log output.
The third patch (almost) obsoletes the log output parsing method. If QEMU's
monitor supports 'info chardev', this gives structured information about
character devices, including pty mappings. The log output parsing method is
still required because QEMU may not support info chardev, and because the
monitor itself can be on a pty. The danger of the third patch is that it will
fix errors in the log output parsing code, which may then bitrot.
Matt
15 years
[libvirt] [PATCH 1/3] Make QEMU driver use -chardev everywhere when it's available
by Matthew Booth
Change -monitor, -serial and -parallel output to use -chardev if it is
available.
* src/qemu/qemu_conf.c: Update qemudBuildCommandLine to use -chardev where
available.
* tests/qemuxml2argvtest.c tests/qemuxml2argvdata/: Add -chardev equivalents for
all current serial and parallel tests.
---
src/qemu/qemu_conf.c | 108 +++++++++++++++++---
.../qemuxml2argv-channel-guestfwd.args | 2 +-
.../qemuxml2argv-console-compat-chardev.args | 1 +
.../qemuxml2argv-console-compat-chardev.xml | 28 +++++
.../qemuxml2argv-parallel-tcp-chardev.args | 1 +
.../qemuxml2argv-parallel-tcp-chardev.xml | 27 +++++
.../qemuxml2argv-serial-dev-chardev.args | 1 +
.../qemuxml2argv-serial-dev-chardev.xml | 30 ++++++
.../qemuxml2argv-serial-file-chardev.args | 1 +
.../qemuxml2argv-serial-file-chardev.xml | 30 ++++++
.../qemuxml2argv-serial-many-chardev.args | 1 +
.../qemuxml2argv-serial-many-chardev.xml | 32 ++++++
.../qemuxml2argv-serial-pty-chardev.args | 1 +
.../qemuxml2argv-serial-pty-chardev.xml | 28 +++++
.../qemuxml2argv-serial-tcp-chardev.args | 1 +
.../qemuxml2argv-serial-tcp-chardev.xml | 32 ++++++
.../qemuxml2argv-serial-tcp-telnet-chardev.args | 1 +
.../qemuxml2argv-serial-tcp-telnet-chardev.xml | 32 ++++++
.../qemuxml2argv-serial-udp-chardev.args | 1 +
.../qemuxml2argv-serial-udp-chardev.xml | 32 ++++++
.../qemuxml2argv-serial-unix-chardev.args | 1 +
.../qemuxml2argv-serial-unix-chardev.xml | 30 ++++++
.../qemuxml2argv-serial-vc-chardev.args | 1 +
.../qemuxml2argv-serial-vc-chardev.xml | 28 +++++
tests/qemuxml2argvtest.c | 12 ++
25 files changed, 445 insertions(+), 17 deletions(-)
create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-console-compat-chardev.args
create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-console-compat-chardev.xml
create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-parallel-tcp-chardev.args
create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-parallel-tcp-chardev.xml
create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-serial-dev-chardev.args
create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-serial-dev-chardev.xml
create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-serial-file-chardev.args
create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-serial-file-chardev.xml
create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-serial-many-chardev.args
create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-serial-many-chardev.xml
create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-serial-pty-chardev.args
create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-serial-pty-chardev.xml
create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-serial-tcp-chardev.args
create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-serial-tcp-chardev.xml
create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-serial-tcp-telnet-chardev.args
create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-serial-tcp-telnet-chardev.xml
create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-serial-udp-chardev.args
create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-serial-udp-chardev.xml
create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-serial-unix-chardev.args
create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-serial-unix-chardev.xml
create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-serial-vc-chardev.args
create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-serial-vc-chardev.xml
diff --git a/src/qemu/qemu_conf.c b/src/qemu/qemu_conf.c
index a25fac6..86172c6 100644
--- a/src/qemu/qemu_conf.c
+++ b/src/qemu/qemu_conf.c
@@ -1863,17 +1863,37 @@ int qemudBuildCommandLine(virConnectPtr conn,
if (monitor_chr) {
virBuffer buf = VIR_BUFFER_INITIALIZER;
- if (monitor_json)
- virBufferAddLit(&buf, "control,");
+ /* Use -chardev if it's available */
+ if (qemuCmdFlags & QEMUD_CMD_FLAG_CHARDEV) {
+ qemudBuildCommandLineChrDevChardevStr(monitor_chr, "monitor", &buf);
+ if (virBufferError(&buf)) {
+ virBufferFreeAndReset(&buf);
+ goto no_memory;
+ }
+
+ ADD_ARG_LIT("-chardev");
+ ADD_ARG(virBufferContentAndReset(&buf));
+
+ if (monitor_json)
+ virBufferAddLit(&buf, "control,");
+
+ virBufferAddLit(&buf, "chardev:monitor");
+ }
+
+ else {
+ if (monitor_json)
+ virBufferAddLit(&buf, "control,");
+
+ qemudBuildCommandLineChrDevStr(monitor_chr, &buf);
+ }
- qemudBuildCommandLineChrDevStr(monitor_chr, &buf);
if (virBufferError(&buf)) {
virBufferFreeAndReset(&buf);
goto no_memory;
}
ADD_ARG_LIT("-monitor");
- ADD_ARG(virBufferContentAndReset(&buf));
+ ADD_ARG_LIT(virBufferContentAndReset(&buf));
}
if (def->localtime)
@@ -2199,14 +2219,42 @@ int qemudBuildCommandLine(virConnectPtr conn,
virBuffer buf = VIR_BUFFER_INITIALIZER;
virDomainChrDefPtr serial = def->serials[i];
- qemudBuildCommandLineChrDevStr(serial, &buf);
- if (virBufferError(&buf)) {
- virBufferFreeAndReset(&buf);
- goto no_memory;
+ /* Use -chardev if it's available */
+ if (qemuCmdFlags & QEMUD_CMD_FLAG_CHARDEV) {
+ char id[16];
+
+ if (snprintf(id, sizeof(id), "serial%i", i) > sizeof(id))
+ goto error;
+
+ qemudBuildCommandLineChrDevChardevStr(serial, id, &buf);
+ if (virBufferError(&buf)) {
+ virBufferFreeAndReset(&buf);
+ goto no_memory;
+ }
+
+ ADD_ARG_LIT("-chardev");
+ ADD_ARG(virBufferContentAndReset(&buf));
+
+ virBufferVSprintf(&buf, "chardev:%s", id);
+ if (virBufferError(&buf)) {
+ virBufferFreeAndReset(&buf);
+ goto no_memory;
+ }
+
+ ADD_ARG_LIT("-serial");
+ ADD_ARG(virBufferContentAndReset(&buf));
}
- ADD_ARG_LIT("-serial");
- ADD_ARG(virBufferContentAndReset(&buf));
+ else {
+ qemudBuildCommandLineChrDevStr(serial, &buf);
+ if (virBufferError(&buf)) {
+ virBufferFreeAndReset(&buf);
+ goto no_memory;
+ }
+
+ ADD_ARG_LIT("-serial");
+ ADD_ARG(virBufferContentAndReset(&buf));
+ }
}
}
@@ -2218,14 +2266,42 @@ int qemudBuildCommandLine(virConnectPtr conn,
virBuffer buf = VIR_BUFFER_INITIALIZER;
virDomainChrDefPtr parallel = def->parallels[i];
- qemudBuildCommandLineChrDevStr(parallel, &buf);
- if (virBufferError(&buf)) {
- virBufferFreeAndReset(&buf);
- goto no_memory;
+ /* Use -chardev if it's available */
+ if (qemuCmdFlags & QEMUD_CMD_FLAG_CHARDEV) {
+ char id[16];
+
+ if (snprintf(id, sizeof(id), "parallel%i", i) > sizeof(id))
+ goto error;
+
+ qemudBuildCommandLineChrDevChardevStr(parallel, id, &buf);
+ if (virBufferError(&buf)) {
+ virBufferFreeAndReset(&buf);
+ goto no_memory;
+ }
+
+ ADD_ARG_LIT("-chardev");
+ ADD_ARG(virBufferContentAndReset(&buf));
+
+ virBufferVSprintf(&buf, "chardev:%s", id);
+ if (virBufferError(&buf)) {
+ virBufferFreeAndReset(&buf);
+ goto no_memory;
+ }
+
+ ADD_ARG_LIT("-parallel");
+ ADD_ARG(virBufferContentAndReset(&buf));
}
- ADD_ARG_LIT("-parallel");
- ADD_ARG(virBufferContentAndReset(&buf));
+ else {
+ qemudBuildCommandLineChrDevStr(parallel, &buf);
+ if (virBufferError(&buf)) {
+ virBufferFreeAndReset(&buf);
+ goto no_memory;
+ }
+
+ ADD_ARG_LIT("-parallel");
+ ADD_ARG(virBufferContentAndReset(&buf));
+ }
}
}
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-channel-guestfwd.args b/tests/qemuxml2argvdata/qemuxml2argv-channel-guestfwd.args
index b5bb46d..deaff92 100644
--- a/tests/qemuxml2argvdata/qemuxml2argv-channel-guestfwd.args
+++ b/tests/qemuxml2argvdata/qemuxml2argv-channel-guestfwd.args
@@ -1 +1 @@
-LC_ALL=C PATH=/bin HOME=/home/test USER=test LOGNAME=test /usr/bin/qemu -S -M pc -m 214 -smp 1 -nographic -monitor unix:/tmp/test-monitor,server,nowait -no-acpi -boot c -hda /dev/HostVG/QEMUGuest1 -net none -serial none -parallel none -chardev pipe,id=channel0,path=/tmp/guestfwd -net user,guestfwd=tcp:10.0.2.1:4600-chardev:channel0 -usb
+LC_ALL=C PATH=/bin HOME=/home/test USER=test LOGNAME=test /usr/bin/qemu -S -M pc -m 214 -smp 1 -nographic -chardev socket,id=monitor,path=/tmp/test-monitor,server,nowait -monitor chardev:monitor -no-acpi -boot c -hda /dev/HostVG/QEMUGuest1 -net none -serial none -parallel none -chardev pipe,id=channel0,path=/tmp/guestfwd -net user,guestfwd=tcp:10.0.2.1:4600-chardev:channel0 -usb
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-console-compat-chardev.args b/tests/qemuxml2argvdata/qemuxml2argv-console-compat-chardev.args
new file mode 100644
index 0000000..fbb94f4
--- /dev/null
+++ b/tests/qemuxml2argvdata/qemuxml2argv-console-compat-chardev.args
@@ -0,0 +1 @@
+LC_ALL=C PATH=/bin HOME=/home/test USER=test LOGNAME=test /usr/bin/qemu -S -M pc -m 214 -smp 1 -nographic -chardev socket,id=monitor,path=/tmp/test-monitor,server,nowait -monitor chardev:monitor -no-acpi -boot c -hda /dev/HostVG/QEMUGuest1 -net none -chardev pty,id=serial0 -serial chardev:serial0 -parallel none -usb
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-console-compat-chardev.xml b/tests/qemuxml2argvdata/qemuxml2argv-console-compat-chardev.xml
new file mode 100644
index 0000000..c16ae07
--- /dev/null
+++ b/tests/qemuxml2argvdata/qemuxml2argv-console-compat-chardev.xml
@@ -0,0 +1,28 @@
+<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>
+ <serial type='pty'>
+ <target port='0'/>
+ </serial>
+ <console type='pty'>
+ <target port='0'/>
+ </console>
+ </devices>
+</domain>
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-parallel-tcp-chardev.args b/tests/qemuxml2argvdata/qemuxml2argv-parallel-tcp-chardev.args
new file mode 100644
index 0000000..45d1759
--- /dev/null
+++ b/tests/qemuxml2argvdata/qemuxml2argv-parallel-tcp-chardev.args
@@ -0,0 +1 @@
+LC_ALL=C PATH=/bin HOME=/home/test USER=test LOGNAME=test /usr/bin/qemu -S -M pc -m 214 -smp 1 -nographic -chardev socket,id=monitor,path=/tmp/test-monitor,server,nowait -monitor chardev:monitor -no-acpi -boot c -hda /dev/HostVG/QEMUGuest1 -net none -serial none -chardev socket,id=parallel0,host=127.0.0.1,port=9999,server,nowait -parallel chardev:parallel0 -usb
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-parallel-tcp-chardev.xml b/tests/qemuxml2argvdata/qemuxml2argv-parallel-tcp-chardev.xml
new file mode 100644
index 0000000..08176f1
--- /dev/null
+++ b/tests/qemuxml2argvdata/qemuxml2argv-parallel-tcp-chardev.xml
@@ -0,0 +1,27 @@
+<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>
+ <parallel type='tcp'>
+ <source mode='bind' host='127.0.0.1' service='9999'/>
+ <protocol type='raw'/>
+ <target port='0'/>
+ </parallel>
+ </devices>
+</domain>
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-serial-dev-chardev.args b/tests/qemuxml2argvdata/qemuxml2argv-serial-dev-chardev.args
new file mode 100644
index 0000000..3036f13
--- /dev/null
+++ b/tests/qemuxml2argvdata/qemuxml2argv-serial-dev-chardev.args
@@ -0,0 +1 @@
+LC_ALL=C PATH=/bin HOME=/home/test USER=test LOGNAME=test /usr/bin/qemu -S -M pc -m 214 -smp 1 -nographic -chardev socket,id=monitor,path=/tmp/test-monitor,server,nowait -monitor chardev:monitor -no-acpi -boot c -hda /dev/HostVG/QEMUGuest1 -net none -chardev tty,id=serial0,path=/dev/ttyS2 -serial chardev:serial0 -parallel none -usb
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-serial-dev-chardev.xml b/tests/qemuxml2argvdata/qemuxml2argv-serial-dev-chardev.xml
new file mode 100644
index 0000000..2b8ef5a
--- /dev/null
+++ b/tests/qemuxml2argvdata/qemuxml2argv-serial-dev-chardev.xml
@@ -0,0 +1,30 @@
+<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>
+ <serial type='dev'>
+ <source path='/dev/ttyS2'/>
+ <target port='0'/>
+ </serial>
+ <console type='dev'>
+ <source path='/dev/ttyS2'/>
+ <target port='0'/>
+ </console>
+ </devices>
+</domain>
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-serial-file-chardev.args b/tests/qemuxml2argvdata/qemuxml2argv-serial-file-chardev.args
new file mode 100644
index 0000000..1dcec2b
--- /dev/null
+++ b/tests/qemuxml2argvdata/qemuxml2argv-serial-file-chardev.args
@@ -0,0 +1 @@
+LC_ALL=C PATH=/bin HOME=/home/test USER=test LOGNAME=test /usr/bin/qemu -S -M pc -m 214 -smp 1 -nographic -chardev socket,id=monitor,path=/tmp/test-monitor,server,nowait -monitor chardev:monitor -no-acpi -boot c -hda /dev/HostVG/QEMUGuest1 -net none -chardev file,id=serial0,path=/tmp/serial.log -serial chardev:serial0 -parallel none -usb
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-serial-file-chardev.xml b/tests/qemuxml2argvdata/qemuxml2argv-serial-file-chardev.xml
new file mode 100644
index 0000000..3726816
--- /dev/null
+++ b/tests/qemuxml2argvdata/qemuxml2argv-serial-file-chardev.xml
@@ -0,0 +1,30 @@
+<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>
+ <serial type='file'>
+ <source path='/tmp/serial.log'/>
+ <target port='0'/>
+ </serial>
+ <console type='file'>
+ <source path='/tmp/serial.log'/>
+ <target port='0'/>
+ </console>
+ </devices>
+</domain>
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-serial-many-chardev.args b/tests/qemuxml2argvdata/qemuxml2argv-serial-many-chardev.args
new file mode 100644
index 0000000..dd98fcb
--- /dev/null
+++ b/tests/qemuxml2argvdata/qemuxml2argv-serial-many-chardev.args
@@ -0,0 +1 @@
+LC_ALL=C PATH=/bin HOME=/home/test USER=test LOGNAME=test /usr/bin/qemu -S -M pc -m 214 -smp 1 -nographic -chardev socket,id=monitor,path=/tmp/test-monitor,server,nowait -monitor chardev:monitor -no-acpi -boot c -hda /dev/HostVG/QEMUGuest1 -net none -chardev pty,id=serial0 -serial chardev:serial0 -chardev file,id=serial1,path=/tmp/serial.log -serial chardev:serial1 -parallel none -usb
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-serial-many-chardev.xml b/tests/qemuxml2argvdata/qemuxml2argv-serial-many-chardev.xml
new file mode 100644
index 0000000..444e85b
--- /dev/null
+++ b/tests/qemuxml2argvdata/qemuxml2argv-serial-many-chardev.xml
@@ -0,0 +1,32 @@
+<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>
+ <serial type='pty'>
+ <target port='0'/>
+ </serial>
+ <serial type='file'>
+ <source path='/tmp/serial.log'/>
+ <target port='1'/>
+ </serial>
+ <console type='pty'>
+ <target port='0'/>
+ </console>
+ </devices>
+</domain>
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-serial-pty-chardev.args b/tests/qemuxml2argvdata/qemuxml2argv-serial-pty-chardev.args
new file mode 100644
index 0000000..fbb94f4
--- /dev/null
+++ b/tests/qemuxml2argvdata/qemuxml2argv-serial-pty-chardev.args
@@ -0,0 +1 @@
+LC_ALL=C PATH=/bin HOME=/home/test USER=test LOGNAME=test /usr/bin/qemu -S -M pc -m 214 -smp 1 -nographic -chardev socket,id=monitor,path=/tmp/test-monitor,server,nowait -monitor chardev:monitor -no-acpi -boot c -hda /dev/HostVG/QEMUGuest1 -net none -chardev pty,id=serial0 -serial chardev:serial0 -parallel none -usb
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-serial-pty-chardev.xml b/tests/qemuxml2argvdata/qemuxml2argv-serial-pty-chardev.xml
new file mode 100644
index 0000000..c16ae07
--- /dev/null
+++ b/tests/qemuxml2argvdata/qemuxml2argv-serial-pty-chardev.xml
@@ -0,0 +1,28 @@
+<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>
+ <serial type='pty'>
+ <target port='0'/>
+ </serial>
+ <console type='pty'>
+ <target port='0'/>
+ </console>
+ </devices>
+</domain>
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-serial-tcp-chardev.args b/tests/qemuxml2argvdata/qemuxml2argv-serial-tcp-chardev.args
new file mode 100644
index 0000000..50cfeb0
--- /dev/null
+++ b/tests/qemuxml2argvdata/qemuxml2argv-serial-tcp-chardev.args
@@ -0,0 +1 @@
+LC_ALL=C PATH=/bin HOME=/home/test USER=test LOGNAME=test /usr/bin/qemu -S -M pc -m 214 -smp 1 -nographic -chardev socket,id=monitor,path=/tmp/test-monitor,server,nowait -monitor chardev:monitor -no-acpi -boot c -hda /dev/HostVG/QEMUGuest1 -net none -chardev socket,id=serial0,host=127.0.0.1,port=9999 -serial chardev:serial0 -parallel none -usb
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-serial-tcp-chardev.xml b/tests/qemuxml2argvdata/qemuxml2argv-serial-tcp-chardev.xml
new file mode 100644
index 0000000..3bcf62d
--- /dev/null
+++ b/tests/qemuxml2argvdata/qemuxml2argv-serial-tcp-chardev.xml
@@ -0,0 +1,32 @@
+<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>
+ <serial type='tcp'>
+ <source mode='connect' host='127.0.0.1' service='9999'/>
+ <protocol type='raw'/>
+ <target port='0'/>
+ </serial>
+ <console type='tcp'>
+ <source mode='connect' host='127.0.0.1' service='9999'/>
+ <protocol type='raw'/>
+ <target port='0'/>
+ </console>
+ </devices>
+</domain>
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-serial-tcp-telnet-chardev.args b/tests/qemuxml2argvdata/qemuxml2argv-serial-tcp-telnet-chardev.args
new file mode 100644
index 0000000..86fa8af
--- /dev/null
+++ b/tests/qemuxml2argvdata/qemuxml2argv-serial-tcp-telnet-chardev.args
@@ -0,0 +1 @@
+LC_ALL=C PATH=/bin HOME=/home/test USER=test LOGNAME=test /usr/bin/qemu -S -M pc -m 214 -smp 1 -nographic -chardev socket,id=monitor,path=/tmp/test-monitor,server,nowait -monitor chardev:monitor -no-acpi -boot c -hda /dev/HostVG/QEMUGuest1 -net none -chardev socket,id=serial0,host=127.0.0.1,port=9999,telnet,server,nowait -serial chardev:serial0 -parallel none -usb
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-serial-tcp-telnet-chardev.xml b/tests/qemuxml2argvdata/qemuxml2argv-serial-tcp-telnet-chardev.xml
new file mode 100644
index 0000000..bea4306
--- /dev/null
+++ b/tests/qemuxml2argvdata/qemuxml2argv-serial-tcp-telnet-chardev.xml
@@ -0,0 +1,32 @@
+<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>
+ <serial type='tcp'>
+ <source mode='bind' host='127.0.0.1' service='9999'/>
+ <protocol type='telnet'/>
+ <target port='0'/>
+ </serial>
+ <console type='tcp'>
+ <source mode='bind' host='127.0.0.1' service='9999'/>
+ <protocol type='telnet'/>
+ <target port='0'/>
+ </console>
+ </devices>
+</domain>
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-serial-udp-chardev.args b/tests/qemuxml2argvdata/qemuxml2argv-serial-udp-chardev.args
new file mode 100644
index 0000000..45421a4
--- /dev/null
+++ b/tests/qemuxml2argvdata/qemuxml2argv-serial-udp-chardev.args
@@ -0,0 +1 @@
+LC_ALL=C PATH=/bin HOME=/home/test USER=test LOGNAME=test /usr/bin/qemu -S -M pc -m 214 -smp 1 -nographic -chardev socket,id=monitor,path=/tmp/test-monitor,server,nowait -monitor chardev:monitor -no-acpi -boot c -hda /dev/HostVG/QEMUGuest1 -net none -chardev udp,id=serial0,host=127.0.0.1,port=9998,localaddr=127.0.0.1,localport=9999 -serial chardev:serial0 -parallel none -usb
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-serial-udp-chardev.xml b/tests/qemuxml2argvdata/qemuxml2argv-serial-udp-chardev.xml
new file mode 100644
index 0000000..115166d
--- /dev/null
+++ b/tests/qemuxml2argvdata/qemuxml2argv-serial-udp-chardev.xml
@@ -0,0 +1,32 @@
+<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>
+ <serial type='udp'>
+ <source mode='bind' host='127.0.0.1' service='9999'/>
+ <source mode='connect' host='127.0.0.1' service='9998'/>
+ <target port='0'/>
+ </serial>
+ <console type='udp'>
+ <source mode='bind' host='127.0.0.1' service='9999'/>
+ <source mode='connect' host='127.0.0.1' service='9998'/>
+ <target port='0'/>
+ </console>
+ </devices>
+</domain>
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-serial-unix-chardev.args b/tests/qemuxml2argvdata/qemuxml2argv-serial-unix-chardev.args
new file mode 100644
index 0000000..f291156
--- /dev/null
+++ b/tests/qemuxml2argvdata/qemuxml2argv-serial-unix-chardev.args
@@ -0,0 +1 @@
+LC_ALL=C PATH=/bin HOME=/home/test USER=test LOGNAME=test /usr/bin/qemu -S -M pc -m 214 -smp 1 -nographic -chardev socket,id=monitor,path=/tmp/test-monitor,server,nowait -monitor chardev:monitor -no-acpi -boot c -hda /dev/HostVG/QEMUGuest1 -net none -chardev socket,id=serial0,path=/tmp/serial.sock -serial chardev:serial0 -parallel none -usb
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-serial-unix-chardev.xml b/tests/qemuxml2argvdata/qemuxml2argv-serial-unix-chardev.xml
new file mode 100644
index 0000000..4236b4c
--- /dev/null
+++ b/tests/qemuxml2argvdata/qemuxml2argv-serial-unix-chardev.xml
@@ -0,0 +1,30 @@
+<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>
+ <serial type='unix'>
+ <source mode='connect' path='/tmp/serial.sock'/>
+ <target port='0'/>
+ </serial>
+ <console type='unix'>
+ <source mode='connect' path='/tmp/serial.sock'/>
+ <target port='0'/>
+ </console>
+ </devices>
+</domain>
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-serial-vc-chardev.args b/tests/qemuxml2argvdata/qemuxml2argv-serial-vc-chardev.args
new file mode 100644
index 0000000..a200225
--- /dev/null
+++ b/tests/qemuxml2argvdata/qemuxml2argv-serial-vc-chardev.args
@@ -0,0 +1 @@
+LC_ALL=C PATH=/bin HOME=/home/test USER=test LOGNAME=test /usr/bin/qemu -S -M pc -m 214 -smp 1 -nographic -chardev socket,id=monitor,path=/tmp/test-monitor,server,nowait -monitor chardev:monitor -no-acpi -boot c -hda /dev/HostVG/QEMUGuest1 -net none -chardev vc,id=serial0 -serial chardev:serial0 -parallel none -usb
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-serial-vc-chardev.xml b/tests/qemuxml2argvdata/qemuxml2argv-serial-vc-chardev.xml
new file mode 100644
index 0000000..1e5de8f
--- /dev/null
+++ b/tests/qemuxml2argvdata/qemuxml2argv-serial-vc-chardev.xml
@@ -0,0 +1,28 @@
+<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>
+ <serial type='vc'>
+ <target port='0'/>
+ </serial>
+ <console type='vc'>
+ <target port='0'/>
+ </console>
+ </devices>
+</domain>
diff --git a/tests/qemuxml2argvtest.c b/tests/qemuxml2argvtest.c
index c39cbbc..3b0aa2b 100644
--- a/tests/qemuxml2argvtest.c
+++ b/tests/qemuxml2argvtest.c
@@ -273,6 +273,18 @@ mymain(int argc, char **argv)
DO_TEST("parallel-tcp", 0);
DO_TEST("console-compat", 0);
+ DO_TEST("serial-vc-chardev", QEMUD_CMD_FLAG_CHARDEV);
+ DO_TEST("serial-pty-chardev", QEMUD_CMD_FLAG_CHARDEV);
+ DO_TEST("serial-dev-chardev", QEMUD_CMD_FLAG_CHARDEV);
+ DO_TEST("serial-file-chardev", QEMUD_CMD_FLAG_CHARDEV);
+ DO_TEST("serial-unix-chardev", QEMUD_CMD_FLAG_CHARDEV);
+ DO_TEST("serial-tcp-chardev", QEMUD_CMD_FLAG_CHARDEV);
+ DO_TEST("serial-udp-chardev", QEMUD_CMD_FLAG_CHARDEV);
+ DO_TEST("serial-tcp-telnet-chardev", QEMUD_CMD_FLAG_CHARDEV);
+ DO_TEST("serial-many-chardev", QEMUD_CMD_FLAG_CHARDEV);
+ DO_TEST("parallel-tcp-chardev", QEMUD_CMD_FLAG_CHARDEV);
+ DO_TEST("console-compat-chardev", QEMUD_CMD_FLAG_CHARDEV);
+
DO_TEST("channel-guestfwd", QEMUD_CMD_FLAG_CHARDEV);
DO_TEST("sound", 0);
--
1.6.5.2
15 years
[libvirt] [PATCH] Suppress cgroup error message on sucess in qemudStartVMDaemon
by Ryota Ozaki
Even if qemudStartVMDaemon suceeds, an error is logged such as
'qemuRemoveCgroup:1778 : internal error Unable to find cgroup for'.
This is because qemudStartVMDaemon calls qemuRemoveCgroup to
ensure that old cgroup does not remain. This workaround makes
sense but leaving an error message may confuse users.
This patch simply adds an option to suppress the error
log if not needed.
---
src/qemu/qemu_driver.c | 16 +++++++++-------
1 files changed, 9 insertions(+), 7 deletions(-)
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index a4a87ac..84ee942 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -1763,7 +1763,8 @@ cleanup:
static int qemuRemoveCgroup(virConnectPtr conn,
struct qemud_driver *driver,
- virDomainObjPtr vm)
+ virDomainObjPtr vm,
+ int quiet)
{
virCgroupPtr cgroup;
int rc;
@@ -1773,9 +1774,10 @@ static int qemuRemoveCgroup(virConnectPtr conn,
rc = virCgroupForDomain(driver->cgroup, vm->def->name, &cgroup, 0);
if (rc != 0) {
- qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
- _("Unable to find cgroup for %s\n"),
- vm->def->name);
+ if (!quiet)
+ qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
+ _("Unable to find cgroup for %s\n"),
+ vm->def->name);
return rc;
}
@@ -2142,7 +2144,7 @@ static int qemudStartVMDaemon(virConnectPtr conn,
return -1;
/* Ensure no historical cgroup for this VM is lieing around bogus settings */
- qemuRemoveCgroup(conn, driver, vm);
+ qemuRemoveCgroup(conn, driver, vm, 1);
if ((vm->def->ngraphics == 1) &&
vm->def->graphics[0]->type == VIR_DOMAIN_GRAPHICS_TYPE_VNC &&
@@ -2327,7 +2329,7 @@ cleanup:
VIR_FREE(vm->def->seclabel.label);
VIR_FREE(vm->def->seclabel.imagelabel);
}
- qemuRemoveCgroup(conn, driver, vm);
+ qemuRemoveCgroup(conn, driver, vm, 0);
if ((vm->def->ngraphics == 1) &&
vm->def->graphics[0]->type == VIR_DOMAIN_GRAPHICS_TYPE_VNC &&
vm->def->graphics[0]->data.vnc.autoport)
@@ -2416,7 +2418,7 @@ static void qemudShutdownVMDaemon(virConnectPtr conn,
qemuDomainReAttachHostDevices(conn, driver, vm->def);
retry:
- if ((ret = qemuRemoveCgroup(conn, driver, vm)) < 0) {
+ if ((ret = qemuRemoveCgroup(conn, driver, vm, 0)) < 0) {
if (ret == -EBUSY && (retries++ < 5)) {
usleep(200*1000);
goto retry;
--
1.6.5.2
15 years
[libvirt] Having some issue with : virConnectRef
by anuj rampal
Hi,
Im trying to call libvirt functions from a widows machine.
The client version i'm using is 0.6.1.
My application is a multi-Threaded application.
This is the way my application works:
1. I connect to Libvirt using "virConnectOpen". (this done only once when my
application starts).
2. For funther interaction with libvirt i just call "virConnectRef" and then
i call some other function like "virNodeGetInfo".
3. Then i call "virConnectClose".
Now my understanding is for every "virConnectRef" call there has to be a
corrosponding "virConnectClose".
In my application call to number of calls to "virConnectClose" is always
equal to "virConnectRef".
and "virConnectClose" corrosponding to "virConnectOpen" is called when the
application is closed.
So connection to libvirt should always be there till the time my application
is running.
But what is happening is, even if i call "virConnectRef" twice, a single
call to "virConnectClose" closes the connection with libvirt.
Is there anything that im doing wrong here...??
Regards
Anuj
15 years
[libvirt] Toward the next 0.7.5 release
by Daniel Veillard
The last release was 0.7.4 on Nov 20, so if we try to keep with the
one month release cycle, we would end up with a release on Friday 25,
but I really plan on celebrating Chrismas with my familly that day
instead of spending time in front of a computer (I plan to roast a
pig and that requires all my attention :-)
I would prefer to not wait too much, as there were some serious locking
bugs in 0.7.4, and I would rather not wait until the end of the
vacations either.
So I'm tempted to push on Wed 23, with possibly a smaller timeframe
for the bug fixes only window. We didn't (yet!) introduce major changes
inside (except maybe for the VirtualBox driver and early bug have been
reported) and Matthias has been debugging seriously with the TCK so
things should be in relatively good shape out of git.
So my plan right nw would be to enter freeze, next Friday the 18th
and push the release 0f 0.7.5 on the 23rd.
So send those patches along and if we forgot to ACK patches please
raise our attention about them, thanks !
Daniel
--
Daniel Veillard | libxml Gnome XML XSLT toolkit http://xmlsoft.org/
daniel(a)veillard.com | Rpmfind RPM search engine http://rpmfind.net/
http://veillard.com/ | virtualization library http://libvirt.org/
15 years
[libvirt] Out of band channels
by Matthew Booth
A libvirt client can connect to libvirt on a remote host. However, on
its own this doesn't give the client a usable level of access. The
reason for this is that libvirt doesn't expose some critical management
interfaces. For QEMU this amounts to pretty much anything provided
directly by the QEMU process, including:
* VNC console [1]
* Any character device [2]
I'm undecided as to whether access to underlying storage falls into this
bucket. It would certainly be convenient in certain circumstances.
This means, for example that I need out of band access to:
* See a graphical console
* Connect to a serial console
* Connect to a guest channel
As these are fairly fundamental operations, I wonder if there has been
any thought towards creating tunnels over a libvirt connection.
In the first instance, I think this would require a generic method to
multiplex multiple streams over a single remote connection. This would
obviously be a significant protocol change. Would a messaging protocol,
AMQP for instance, be a good candidate here?
Secondly, I think interfaces which currently create local resources
should have a default which is managed by libvirt itself. So you'd have:
<serial>
<target port='0'/>
</serial>
or
<serial type='managed'>
<target port='0'/>
</serial>
This would cause libvirt to create whichever host-side chardev is most
convenient to it and connect itself. The API would then expose read and
write APIs for the named connection. e.g:
virDomainFoo foo;[3]
if = virDomainGetFoo(domain, "serial0");
bytesIn = virDomainFooRead(foo, &buf, sizeof(buf));
A client application could expose this in a variety of ways locally.
Matt
[1] There's an open RFE for this one:
https://bugzilla.redhat.com/show_bug.cgi?id=526953
[2] e.g.
virsh # console RHEL3.FV.64.IDE
error: Cannot connect to a remote console device
[3] What would you call it?
--
Matthew Booth, RHCA, RHCSS
Red Hat Engineering, Virtualisation Team
M: +44 (0)7977 267231
GPG ID: D33C3490
GPG FPR: 3733 612D 2D05 5458 8A8A 1600 3441 EA19 D33C 3490
15 years