This patch fixes console corruption, that happens if two concurrent sessions are opened for a single console on a domain. Result of this corruption was, that each of the console streams did recieve just a part of the data written to the pipe so every console rendered unusable. New helper function for safe console handling is used to establis the console stream connection. This function ensurest that no other libvirt client is using the console (with the ability to disconnect consoles of libvirt clients) and that no UUCP style lockfile is placed on the PTY device. * src/qemu/qemu_domain.h - add data structure to domain's private data dealing with console connections * src/qemu/qemu_domain.c: - allocate/free domain's console data structure * src/qemu/qemu_driver.c - use the new helper function for console handling --- src/qemu/qemu_domain.c | 5 +++++ src/qemu/qemu_domain.h | 3 +++ src/qemu/qemu_driver.c | 21 ++++++++++++++++----- 3 files changed, 24 insertions(+), 5 deletions(-) diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c index b28c734..08d30ab 100644 --- a/src/qemu/qemu_domain.c +++ b/src/qemu/qemu_domain.c @@ -217,6 +217,9 @@ static void *qemuDomainObjPrivateAlloc(void) if (qemuDomainObjInitJob(priv) < 0) goto error; + if (!(priv->cons = virDomainSafeConsoleAlloc())) + goto error; + priv->migMaxBandwidth = QEMU_DOMAIN_DEFAULT_MIG_BANDWIDTH_MAX; return priv; @@ -239,6 +242,8 @@ static void qemuDomainObjPrivateFree(void *data) VIR_FREE(priv->lockState); VIR_FREE(priv->origname); + virDomainSafeConsoleFree(priv->cons); + /* This should never be non-NULL if we get here, but just in case... */ if (priv->mon) { VIR_ERROR(_("Unexpected QEMU monitor still active during domain deletion")); diff --git a/src/qemu/qemu_domain.h b/src/qemu/qemu_domain.h index e8bcab3..88ddb2f 100644 --- a/src/qemu/qemu_domain.h +++ b/src/qemu/qemu_domain.h @@ -29,6 +29,7 @@ # include "qemu_monitor.h" # include "qemu_conf.h" # include "bitmap.h" +# include "domain_safe_console.h" # define QEMU_EXPECTED_VIRT_TYPES \ ((1 << VIR_DOMAIN_VIRT_QEMU) | \ @@ -127,6 +128,8 @@ struct _qemuDomainObjPrivate { unsigned long migMaxBandwidth; char *origname; + + virDomainSafeConsolesPtr cons; }; struct qemuDomainWatchdogEvent diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c index 1e5ed9a..608a2ca 100644 --- a/src/qemu/qemu_driver.c +++ b/src/qemu/qemu_driver.c @@ -10847,8 +10847,10 @@ qemuDomainOpenConsole(virDomainPtr dom, int ret = -1; int i; virDomainChrDefPtr chr = NULL; + qemuDomainObjPrivatePtr priv; - virCheckFlags(0, -1); + virCheckFlags(VIR_DOMAIN_CONSOLE_TRY | + VIR_DOMAIN_CONSOLE_FORCE, -1); qemuDriverLock(driver); virUUIDFormat(dom->uuid, uuidstr); @@ -10865,6 +10867,8 @@ qemuDomainOpenConsole(virDomainPtr dom, goto cleanup; } + priv = vm->privateData; + if (dev_name) { for (i = 0 ; !chr && i < vm->def->nconsoles ; i++) { if (vm->def->consoles[i]->info.alias && @@ -10900,11 +10904,18 @@ qemuDomainOpenConsole(virDomainPtr dom, goto cleanup; } - if (virFDStreamOpenFile(st, chr->source.data.file.path, - 0, 0, O_RDWR) < 0) - goto cleanup; + /* handle mutualy exclusive access to console devices */ + ret = virDomainSafeConsoleOpen(priv->cons, + chr->source.data.file.path, + st, + (flags & VIR_DOMAIN_CONSOLE_FORCE) != 0); + + if (ret == 1) { + qemuReportError(VIR_ERR_OPERATION_FAILED, + _("Active console session exists for this domain")); + ret = -1; + } - ret = 0; cleanup: if (vm) virDomainObjUnlock(vm); -- 1.7.3.4 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list