[libvirt] [PATCH 6/7] Add SCM_RIGHTS support to QEMU monitor code

Mark McLoughlin markmc at redhat.com
Wed Jul 22 21:57:35 UTC 2009


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




More information about the libvir-list mailing list