[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PATCH 08/17] add unix_msgfd_lookup() to callback get_buffe
From: |
Lei Li |
Subject: |
[Qemu-devel] [PATCH 08/17] add unix_msgfd_lookup() to callback get_buffer |
Date: |
Thu, 21 Nov 2013 17:11:31 +0800 |
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) {
+ 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;
+ }
+ break;
+ }
+ } else {
+ len = qemu_recv(s->sockfd, buf, size, 0);
+ if (len != -1) {
+ break;
+ }
}
if (socket_error() == EAGAIN) {
--
1.7.7.6
- [Qemu-devel] [PATCH 0/17 v3] Localhost migration with side channel for ram, Lei Li, 2013/11/21
- [Qemu-devel] [PATCH 02/17] migration: add migrate_unix_page_flipping(), Lei Li, 2013/11/21
- [Qemu-devel] [PATCH 03/17] qmp-command.hx: add missing docs for migration capabilites, Lei Li, 2013/11/21
- [Qemu-devel] [PATCH 01/17] QAPI: introduce migration capability unix_page_flipping, Lei Li, 2013/11/21
- [Qemu-devel] [PATCH 04/17] migration-local: add QEMUFileLocal with socket based QEMUFile, Lei Li, 2013/11/21
- [Qemu-devel] [PATCH 05/17] migration-local: introduce qemu_fopen_socket_local(), Lei Li, 2013/11/21
- [Qemu-devel] [PATCH 06/17] migration-local: add send_pipefd(), Lei Li, 2013/11/21
- [Qemu-devel] [PATCH 07/17] migration-local: override before_ram_iterate to send pipefd, Lei Li, 2013/11/21
- [Qemu-devel] [PATCH 08/17] add unix_msgfd_lookup() to callback get_buffer,
Lei Li <=
- [Qemu-devel] [PATCH 10/17] migration-local: override save_page for page transmit, Lei Li, 2013/11/21
- [Qemu-devel] [PATCH 11/17] savevm: adjust ram_control_save_page for page flipping, Lei Li, 2013/11/21
- [Qemu-devel] [PATCH 12/17] migration-local: override hook_ram_load, Lei Li, 2013/11/21