Add qemudMonitorCommandWithFd() which allows a file descriptor to be sent to qemu over a unix monitor socket using SCM_RIGHTS. See the unix(7) and cmsg(3) man pages. * src/qemu_conf.c: add a scm_fd param to qemudMonitorCommandExtra(), add qemudMonitorCommandWithFd(), implement SCM_RIGHTS support in qemudMonitorSendUnix() --- src/qemu_driver.c | 46 +++++++++++++++++++++++++++++++++++++--------- 1 files changed, 37 insertions(+), 9 deletions(-) diff --git a/src/qemu_driver.c b/src/qemu_driver.c index e6e6786..a7861be 100644 --- a/src/qemu_driver.c +++ b/src/qemu_driver.c @@ -111,10 +111,15 @@ static int qemudDomainGetMaxVcpus(virDomainPtr dom); static int qemudMonitorCommand(const virDomainObjPtr vm, const char *cmd, char **reply); +static int qemudMonitorCommandWithFd(const virDomainObjPtr vm, + const char *cmd, + int scm_fd, + char **reply); static int qemudMonitorCommandExtra(const virDomainObjPtr vm, const char *cmd, const char *extra, const char *extraPrompt, + int scm_fd, char **reply); static int qemudDomainSetMemoryBalloon(virConnectPtr conn, virDomainObjPtr vm, @@ -1256,7 +1261,7 @@ qemudInitPasswords(virConnectPtr conn, vm->def->graphics[0]->data.vnc.passwd : driver->vncPassword, QEMU_PASSWD_PROMPT, - &info) < 0) { + -1, &info) < 0) { qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR, "%s", _("setting VNC password failed")); return -1; @@ -2015,7 +2020,8 @@ qemuMonitorDiscardPendingData(virDomainObjPtr vm) { static int qemudMonitorSendUnix(const virDomainObjPtr vm, const char *cmd, - size_t cmdlen) + size_t cmdlen, + int scm_fd) { struct msghdr msg; struct iovec iov[1]; @@ -2029,6 +2035,20 @@ qemudMonitorSendUnix(const virDomainObjPtr vm, msg.msg_iov = iov; msg.msg_iovlen = 1; + if (scm_fd != -1) { + char control[CMSG_SPACE(sizeof(int))]; + struct cmsghdr *cmsg; + + msg.msg_control = control; + msg.msg_controllen = sizeof(control); + + cmsg = CMSG_FIRSTHDR(&msg); + cmsg->cmsg_len = CMSG_LEN(sizeof(int)); + cmsg->cmsg_level = SOL_SOCKET; + cmsg->cmsg_type = SCM_RIGHTS; + memcpy(CMSG_DATA(cmsg), &scm_fd, sizeof(int)); + } + do { ret = sendmsg(vm->monitor, &msg, 0); } while (ret < 0 && errno == EINTR); @@ -2038,7 +2058,8 @@ qemudMonitorSendUnix(const virDomainObjPtr vm, static int qemudMonitorSend(const virDomainObjPtr vm, - const char *cmd) + const char *cmd, + int scm_fd) { char *full; size_t len; @@ -2051,7 +2072,7 @@ qemudMonitorSend(const virDomainObjPtr vm, switch (vm->monitor_chr->type) { case VIR_DOMAIN_CHR_TYPE_UNIX: - if (qemudMonitorSendUnix(vm, full, len) < 0) + if (qemudMonitorSendUnix(vm, full, len, scm_fd) < 0) goto out; break; default: @@ -2072,13 +2093,14 @@ qemudMonitorCommandExtra(const virDomainObjPtr vm, const char *cmd, const char *extra, const char *extraPrompt, + int scm_fd, char **reply) { int size = 0; char *buf = NULL; qemuMonitorDiscardPendingData(vm); - if (qemudMonitorSend(vm, cmd) < 0) + if (qemudMonitorSend(vm, cmd, scm_fd) < 0) return -1; *reply = NULL; @@ -2113,7 +2135,7 @@ qemudMonitorCommandExtra(const virDomainObjPtr vm, if (buf) { if (extra) { if (strstr(buf, extraPrompt) != NULL) { - if (qemudMonitorSend(vm, extra) < 0) + if (qemudMonitorSend(vm, extra, -1) < 0) return -1; extra = NULL; } @@ -2154,14 +2176,20 @@ qemudMonitorCommandExtra(const virDomainObjPtr vm, } static int +qemudMonitorCommandWithFd(const virDomainObjPtr vm, + const char *cmd, + int scm_fd, + char **reply) { + return qemudMonitorCommandExtra(vm, cmd, NULL, NULL, scm_fd, reply); +} + +static int qemudMonitorCommand(const virDomainObjPtr vm, const char *cmd, char **reply) { - return qemudMonitorCommandExtra(vm, cmd, NULL, NULL, reply); + return qemudMonitorCommandWithFd(vm, cmd, -1, reply); } - - static virDrvOpenStatus qemudOpen(virConnectPtr conn, virConnectAuthPtr auth ATTRIBUTE_UNUSED, int flags ATTRIBUTE_UNUSED) { -- 1.6.2.5 -- Libvir-list mailing list Libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list