From: "Daniel P. Berrange" <berrange@xxxxxxxxxx> Currently qemuMonitorOpen() requires an address of the QEMU monitor. When doing QMP based capabilities detection it is easier if a pre-opened FD can be provided, since then the monitor can be run on the STDIO console. Add a new API qemuMonitorOpenFD() for such usage Signed-off-by: Daniel P. Berrange <berrange@xxxxxxxxxx> --- src/qemu/qemu_monitor.c | 81 ++++++++++++++++++++++++++++++++++--------------- src/qemu/qemu_monitor.h | 5 +++ 2 files changed, 61 insertions(+), 25 deletions(-) diff --git a/src/qemu/qemu_monitor.c b/src/qemu/qemu_monitor.c index fb67b9a..543b6cd 100644 --- a/src/qemu/qemu_monitor.c +++ b/src/qemu/qemu_monitor.c @@ -680,11 +680,12 @@ qemuMonitorIO(int watch, int fd, int events, void *opaque) { } -qemuMonitorPtr -qemuMonitorOpen(virDomainObjPtr vm, - virDomainChrSourceDefPtr config, - int json, - qemuMonitorCallbacksPtr cb) +static qemuMonitorPtr +qemuMonitorOpenInternal(virDomainObjPtr vm, + int fd, + bool hasSendFD, + int json, + qemuMonitorCallbacksPtr cb) { qemuMonitorPtr mon; @@ -718,7 +719,8 @@ qemuMonitorOpen(virDomainObjPtr vm, VIR_FREE(mon); return NULL; } - mon->fd = -1; + mon->fd = fd; + mon->hasSendFD = hasSendFD; mon->vm = vm; mon->json = json; if (json) @@ -726,25 +728,6 @@ qemuMonitorOpen(virDomainObjPtr vm, mon->cb = cb; qemuMonitorLock(mon); - switch (config->type) { - case VIR_DOMAIN_CHR_TYPE_UNIX: - mon->hasSendFD = 1; - mon->fd = qemuMonitorOpenUnix(config->data.nix.path, vm->pid); - break; - - case VIR_DOMAIN_CHR_TYPE_PTY: - mon->fd = qemuMonitorOpenPty(config->data.file.path); - break; - - default: - virReportError(VIR_ERR_INTERNAL_ERROR, - _("unable to handle monitor type: %s"), - virDomainChrTypeToString(config->type)); - goto cleanup; - } - - if (mon->fd == -1) goto cleanup; - if (virSetCloseExec(mon->fd) < 0) { virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("Unable to set monitor close-on-exec flag")); @@ -785,10 +768,58 @@ cleanup: */ mon->cb = NULL; qemuMonitorUnlock(mon); + /* The caller owns 'fd' on failure */ + mon->fd = -1; + if (mon->watch) + virEventRemoveHandle(mon->watch); qemuMonitorClose(mon); return NULL; } +qemuMonitorPtr +qemuMonitorOpen(virDomainObjPtr vm, + virDomainChrSourceDefPtr config, + int json, + qemuMonitorCallbacksPtr cb) +{ + int fd; + bool hasSendFD = false; + qemuMonitorPtr ret; + + switch (config->type) { + case VIR_DOMAIN_CHR_TYPE_UNIX: + hasSendFD = true; + if ((fd = qemuMonitorOpenUnix(config->data.nix.path, vm->pid)) < 0) + return NULL; + break; + + case VIR_DOMAIN_CHR_TYPE_PTY: + if ((fd = qemuMonitorOpenPty(config->data.file.path)) < 0) + return NULL; + break; + + default: + virReportError(VIR_ERR_INTERNAL_ERROR, + _("unable to handle monitor type: %s"), + virDomainChrTypeToString(config->type)); + return NULL; + } + + ret = qemuMonitorOpenInternal(vm, fd, hasSendFD, json, cb); + if (!ret) + VIR_FORCE_CLOSE(fd); + return ret; +} + + +qemuMonitorPtr qemuMonitorOpenFD(virDomainObjPtr vm, + int sockfd, + int json, + qemuMonitorCallbacksPtr cb) +{ + return qemuMonitorOpenInternal(vm, sockfd, true, json, cb); +} + void qemuMonitorClose(qemuMonitorPtr mon) { diff --git a/src/qemu/qemu_monitor.h b/src/qemu/qemu_monitor.h index 2033473..0f7ca2d 100644 --- a/src/qemu/qemu_monitor.h +++ b/src/qemu/qemu_monitor.h @@ -147,6 +147,11 @@ qemuMonitorPtr qemuMonitorOpen(virDomainObjPtr vm, int json, qemuMonitorCallbacksPtr cb) ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_NONNULL(4); +qemuMonitorPtr qemuMonitorOpenFD(virDomainObjPtr vm, + int sockfd, + int json, + qemuMonitorCallbacksPtr cb) + ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(4); void qemuMonitorClose(qemuMonitorPtr mon); -- 1.7.11.4 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list