qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Qemu-devel] [PATCH 08/17] add unix_msgfd_lookup() to callback get_b


From: Lei Li
Subject: Re: [Qemu-devel] [PATCH 08/17] add unix_msgfd_lookup() to callback get_buffer
Date: Tue, 26 Nov 2013 19:30:30 +0800
User-agent: Mozilla/5.0 (X11; Linux x86_64; rv:17.0) Gecko/17.0 Thunderbird/17.0

On 11/21/2013 05:11 PM, Lei Li wrote:
The control message for exchange of pipe file descriptor should
be received by recvmsg, and it might be eaten to stream file by
qemu_recv() when receiving by two callbacks. So this patch adds
unix_msgfd_lookup() to callback get_buffer as the only one receiver,
where the pipe file descriptor would be caughted.

Signed-off-by: Lei Li <address@hidden>
---
  migration-local.c |   68 ++++++++++++++++++++++++++++++++++++++++++++++++++--
  1 files changed, 65 insertions(+), 3 deletions(-)

diff --git a/migration-local.c b/migration-local.c
index e028beb..0f0896b 100644
--- a/migration-local.c
+++ b/migration-local.c
@@ -50,6 +50,8 @@ typedef struct QEMUFileLocal {
      bool unix_page_flipping;
  } QEMUFileLocal;

+static bool pipefd_passed;
+
  static int qemu_local_get_sockfd(void *opaque)
  {
      QEMUFileLocal *s = opaque;
@@ -57,16 +59,76 @@ static int qemu_local_get_sockfd(void *opaque)
      return s->sockfd;
  }

+static int unix_msgfd_lookup(void *opaque, struct msghdr *msg)
+{
+    QEMUFileLocal *s = opaque;
+    struct cmsghdr *cmsg;
+    bool found = false;
+
+    for (cmsg = CMSG_FIRSTHDR(msg); cmsg; cmsg = CMSG_NXTHDR(msg, cmsg)) {
+        if (cmsg->cmsg_len != CMSG_LEN(sizeof(int)) ||
+            cmsg->cmsg_level != SOL_SOCKET ||
+            cmsg->cmsg_type != SCM_RIGHTS)
+            continue;
+
+        /* PIPE file descriptor to be received */
+        s->pipefd[0] = *((int *)CMSG_DATA(cmsg));
+    }
+
+    if (s->pipefd[0] <= 0) {

And this should be if (s->pipefd[0] < 0)..

+        fprintf(stderr, "no pipe fd can be received\n");
+        return found;
+    }
+
+    DPRINTF("pipefd successfully received\n");
+    return s->pipefd[0];
+}
+
  static int qemu_local_get_buffer(void *opaque, uint8_t *buf,
                                   int64_t pos, int size)
  {
      QEMUFileLocal *s = opaque;
      ssize_t len;
+    struct msghdr msg = { NULL, };
+    struct iovec iov[1];
+    union {
+        struct cmsghdr cmsg;
+        char control[CMSG_SPACE(sizeof(int))];
+    } msg_control;
+
+    iov[0].iov_base = buf;
+    iov[0].iov_len = size;
+
+    msg.msg_iov = iov;
+    msg.msg_iovlen = 1;
+    msg.msg_control = &msg_control;
+    msg.msg_controllen = sizeof(msg_control);

      for (;;) {
-        len = qemu_recv(s->sockfd, buf, size, 0);
-        if (len != -1) {
-            break;
+        if (!pipefd_passed) {
+            /*
+             * recvmsg is called here to catch the control message for
+             * the exchange of PIPE file descriptor until it is received.
+             */
+            len = recvmsg(s->sockfd, &msg, 0);
+            if (len != -1) {
+                if (unix_msgfd_lookup(s, &msg) > 0) {
+                    pipefd_passed = 1;
+                    /*
+                     * Do not count one byte taken by the PIPE file
+                     * descriptor.
+                     */
+                    len--;
+                } else {
+                    len = -1;
+                }

Just found that this 'else' should go away as it will break the normal
Unix migration since pipefd_passed will always be 0 for it. I have
fixed this in my code, seems I mis-send it for some reason, sorry
for this...:-[
+                break;
+            }
+        } else {
+            len = qemu_recv(s->sockfd, buf, size, 0);
+            if (len != -1) {
+                break;
+            }
          }

          if (socket_error() == EAGAIN) {


--
Lei




reply via email to

[Prev in Thread] Current Thread [Next in Thread]