This patch adds recv_pipefd() to receive the pipe file descriptor that passed by source process.
Signed-off-by: Lei Li <li...@linux.vnet.ibm.com> --- include/migration/qemu-file.h | 1 + migration-local.c | 56 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 57 insertions(+), 0 deletions(-) diff --git a/include/migration/qemu-file.h b/include/migration/qemu-file.h index 5fad65f..e4df258 100644 --- a/include/migration/qemu-file.h +++ b/include/migration/qemu-file.h @@ -102,6 +102,7 @@ QEMUFile *qemu_popen_cmd(const char *command, const char *mode); QEMUFile *qemu_fopen_pipe(int sockfd, const char *mode); int send_pipefd(int sockfd, int pipefd); +int recv_pipefd(int sockfd); int qemu_get_fd(QEMUFile *f); int qemu_fclose(QEMUFile *f); int64_t qemu_ftell(QEMUFile *f); diff --git a/migration-local.c b/migration-local.c index 3875b27..40b8f34 100644 --- a/migration-local.c +++ b/migration-local.c @@ -189,3 +189,59 @@ int send_pipefd(int sockfd, int pipefd) } return 0; } + +/* + * Receive a pipe file descriptor from a source process + * via unix socket. + * + * Return negative value if there has been an recvmsg error or + * no fd to be reveived. Return 0 if the connection closed by + * source. Return file descriptor on success. + * + */ +int recv_pipefd(int sockfd) +{ + int pipefd; + struct cmsghdr *cmsg; + struct msghdr msg; + struct iovec iov[1]; + char req[1]; + int ret; + union MsgControl msg_control; + + iov[0].iov_base = req; + iov[0].iov_len = sizeof(req); + + memset(&msg, 0, sizeof(msg)); + msg.msg_iov = iov; + msg.msg_iovlen = 1; + msg.msg_control = &msg_control; + msg.msg_controllen = sizeof(msg_control); + + do { + ret = recvmsg(sockfd, &msg, 0); + } while (ret < 0 && errno == EINTR); + if (ret <= 0) { + return ret; + } + + /* req 0x01 means there is a file descriptor to receive */ + if (req[0] != 0x01) { + return -1; + } + + cmsg = CMSG_FIRSTHDR(&msg); + while (cmsg) { + if (cmsg->cmsg_level == SOL_SOCKET && + cmsg->cmsg_type == SCM_RIGHTS && + cmsg->cmsg_len == CMSG_LEN(sizeof(int))) { + + /* The file descriptor to be received */ + memcpy(&pipefd, CMSG_DATA(cmsg), sizeof(pipefd)); + return pipefd; + } + cmsg = CMSG_NXTHDR(&msg, cmsg); + } + + return -1; +} -- 1.7.7.6