From: "Daniel P. Berrange" <berrange(a)redhat.com>
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(a)redhat.com>
---
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