From aadab51541736fbf17c12c9c0113e6c11a67a121 Mon Sep 17 00:00:00 2001 From: "Daniel P. Berrange" Date: Wed, 23 Sep 2009 16:51:10 +0100 Subject: [PATCH] Add API for issuing 'getfd' and 'closefd' monitor commands * src/qemu/qemu_monitor.c, src/qemu/qemu_monitor.h: Add new qemuMonitorCloseFileHandle and qemuMonitorSendFileHandle APIs for processing file handles * src/qemu/qemu_driver.c: Convert NIC hotplug method over to use qemuMonitorCloseFileHandle and qemuMonitorSendFileHandle --- src/qemu/qemu_driver.c | 40 +++--------------- src/qemu/qemu_monitor_text.c | 78 ++++++++++++++++++++++++++++++++++++ src/qemu/qemu_monitor_text.h | 6 +++ 3 files changed, 90 insertions(+), 34 deletions(-) diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c index 5a061a4652..11e689c617 100644 --- a/src/qemu/qemu_driver.c +++ b/src/qemu/qemu_driver.c @@ -4619,7 +4619,7 @@ static int qemudDomainAttachNetDevice(virConnectPtr conn, { virDomainNetDefPtr net = dev->data.net; char *cmd = NULL, *reply = NULL, *remove_cmd = NULL; - char *tapfd_name = NULL, *tapfd_close = NULL; + char *tapfd_name = NULL; int i, tapfd = -1; unsigned domain, bus, slot; @@ -4662,32 +4662,8 @@ static int qemudDomainAttachNetDevice(virConnectPtr conn, if (virAsprintf(&tapfd_name, "fd-%s", net->hostnet_name) < 0) goto no_memory; - if (virAsprintf(&tapfd_close, "closefd %s", tapfd_name) < 0) - goto no_memory; - - if (virAsprintf(&cmd, "getfd %s", tapfd_name) < 0) - goto no_memory; - - if (qemudMonitorCommandWithFd(vm, cmd, tapfd, &reply) < 0) { - qemudReportError(conn, dom, NULL, VIR_ERR_OPERATION_FAILED, - _("failed to pass fd to qemu with '%s'"), cmd); + if (qemuMonitorSendFileHandle(vm, tapfd_name, tapfd) < 0) goto cleanup; - } - - DEBUG("%s: getfd reply: %s", vm->def->name, reply); - - /* If the command isn't supported then qemu prints: - * unknown command: getfd" */ - if (strstr(reply, "unknown command:")) { - qemudReportError(conn, dom, NULL, VIR_ERR_NO_SUPPORT, - "%s", - _("bridge/network interface attach not supported: " - "qemu 'getfd' monitor command not available")); - goto cleanup; - } - - VIR_FREE(reply); - VIR_FREE(cmd); } if (qemuBuildHostNetStr(conn, net, "host_net_add ", ' ', @@ -4713,7 +4689,6 @@ static int qemudDomainAttachNetDevice(virConnectPtr conn, VIR_FREE(reply); VIR_FREE(cmd); VIR_FREE(tapfd_name); - VIR_FREE(tapfd_close); if (tapfd != -1) close(tapfd); tapfd = -1; @@ -4760,12 +4735,10 @@ try_remove: try_tapfd_close: VIR_FREE(reply); - if (tapfd_close) { - if (qemudMonitorCommand(vm, tapfd_close, &reply) < 0) - VIR_WARN(_("Failed to close tapfd with '%s'\n"), tapfd_close); - else - VIR_DEBUG("%s: closefd: %s\n", vm->def->name, reply); - } + if (tapfd_name && + qemuMonitorCloseFileHandle(vm, tapfd_name) < 0) + VIR_WARN(_("Failed to close tapfd with '%s'\n"), tapfd_name); + goto cleanup; no_memory: @@ -4774,7 +4747,6 @@ cleanup: VIR_FREE(cmd); VIR_FREE(reply); VIR_FREE(remove_cmd); - VIR_FREE(tapfd_close); VIR_FREE(tapfd_name); if (tapfd != -1) close(tapfd); diff --git a/src/qemu/qemu_monitor_text.c b/src/qemu/qemu_monitor_text.c index 7dd9ac37d8..ae584686cd 100644 --- a/src/qemu/qemu_monitor_text.c +++ b/src/qemu/qemu_monitor_text.c @@ -1552,3 +1552,81 @@ cleanup: VIR_FREE(reply); return ret; } + + +int qemuMonitorSendFileHandle(const virDomainObjPtr vm, + const char *fdname, + int fd) +{ + char *cmd; + char *reply = NULL; + int ret = -1; + + if (virAsprintf(&cmd, "getfd %s", fdname) < 0) { + virReportOOMError(NULL); + return -1; + } + + if (qemudMonitorCommandWithFd(vm, cmd, fd, &reply) < 0) { + qemudReportError(NULL, NULL, NULL, VIR_ERR_OPERATION_FAILED, + _("failed to pass fd to qemu with '%s'"), cmd); + goto cleanup; + } + + DEBUG("%s: getfd reply: %s", vm->def->name, reply); + + /* If the command isn't supported then qemu prints: + * unknown command: getfd" */ + if (strstr(reply, "unknown command:")) { + qemudReportError(NULL, NULL, NULL, VIR_ERR_NO_SUPPORT, + _("qemu does not support sending of file handles: %s"), + reply); + goto cleanup; + } + + ret = 0; + +cleanup: + VIR_FREE(cmd); + VIR_FREE(reply); + return ret; +} + + +int qemuMonitorCloseFileHandle(const virDomainObjPtr vm, + const char *fdname) +{ + char *cmd; + char *reply = NULL; + int ret = -1; + + if (virAsprintf(&cmd, "closefd %s", fdname) < 0) { + virReportOOMError(NULL); + return -1; + } + + if (qemudMonitorCommand(vm, cmd, &reply) < 0) { + qemudReportError(NULL, NULL, NULL, VIR_ERR_OPERATION_FAILED, + _("failed to close fd in qemu with '%s'"), cmd); + goto cleanup; + } + + DEBUG("%s: closefd reply: %s", vm->def->name, reply); + + /* If the command isn't supported then qemu prints: + * unknown command: getfd" */ + if (strstr(reply, "unknown command:")) { + qemudReportError(NULL, NULL, NULL, VIR_ERR_NO_SUPPORT, + _("qemu does not support closing of file handles: %s"), + reply); + goto cleanup; + } + + ret = 0; + +cleanup: + VIR_FREE(cmd); + VIR_FREE(reply); + return ret; +} + diff --git a/src/qemu/qemu_monitor_text.h b/src/qemu/qemu_monitor_text.h index 188d3cb9ee..7fe5285ca7 100644 --- a/src/qemu/qemu_monitor_text.h +++ b/src/qemu/qemu_monitor_text.h @@ -176,5 +176,11 @@ int qemuMonitorRemovePCIDevice(const virDomainObjPtr vm, unsigned guestSlot); +int qemuMonitorSendFileHandle(const virDomainObjPtr vm, + const char *fdname, + int fd); + +int qemuMonitorCloseFileHandle(const virDomainObjPtr vm, + const char *fdname); #endif /* QEMU_MONITOR_TEXT_H */ -- GitLab