qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
From: Stefan Hajnoczi <stefanha@linux.vnet.ibm.com>
To: qemu-devel@nongnu.org
Cc: Kevin Wolf <kwolf@redhat.com>,
	Anthony Liguori <aliguori@us.ibm.com>,
	Stefan Hajnoczi <stefanha@linux.vnet.ibm.com>,
	libvir-list@redhat.com, Corey Bryant <coreyb@linux.vnet.ibm.com>
Subject: [Qemu-devel] [RFC 3/5] block: plumb up open-hook-fd option
Date: Tue,  1 May 2012 16:31:45 +0100	[thread overview]
Message-ID: <1335886307-27586-4-git-send-email-stefanha@linux.vnet.ibm.com> (raw)
In-Reply-To: <1335886307-27586-1-git-send-email-stefanha@linux.vnet.ibm.com>

From: Anthony Liguori <aliguori@us.ibm.com>

Implement the open hook UNIX domain socket protocol and accept passed
file descriptors.

Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
Signed-off-by: Stefan Hajnoczi <stefanha@linux.vnet.ibm.com>
---
 block.c           |  107 ++++++++++++++++++++++++++++++++++++++++++++++++++++-
 block.h           |    2 +
 block/raw-posix.c |    2 +-
 qemu-options.hx   |    4 +-
 vl.c              |    3 ++
 5 files changed, 114 insertions(+), 4 deletions(-)

diff --git a/block.c b/block.c
index f9c4633..d3bf443 100644
--- a/block.c
+++ b/block.c
@@ -31,6 +31,7 @@
 #include "qemu-coroutine.h"
 #include "qmp-commands.h"
 #include "qemu-timer.h"
+#include "qemu_socket.h"
 
 #ifdef CONFIG_BSD
 #include <sys/types.h>
@@ -102,9 +103,113 @@ static BlockDriverState *bs_snapshots;
 /* If non-zero, use only whitelisted block drivers */
 static int use_bdrv_whitelist;
 
+static int remote_file_fd = -1;
+
+void remote_file_open_init(int fd)
+{
+    remote_file_fd = fd;
+}
+
+typedef struct OpenRequest
+{
+    uint32_t message_len;
+    uint32_t type;
+    uint32_t flags;
+    uint32_t mode;
+    uint32_t filename_len;
+    uint8_t filename[0];
+} OpenRequest;
+
+typedef struct OpenResponse
+{
+    uint32_t message_len;
+    uint32_t type;
+    int32_t result;
+} OpenResponse;
+
 int file_open(const char *filename, int flags, mode_t mode)
 {
-    return open(filename, flags, mode);
+#ifdef _WIN32
+    return qemu_open(filename, flags, mode);
+#else
+    struct msghdr msg = { NULL, };
+    struct cmsghdr *cmsg;
+    struct iovec iov[1];
+    union {
+        struct cmsghdr cmsg;
+        char control[CMSG_SPACE(sizeof(int))];
+    } msg_control;
+    ssize_t ret;
+    uint8_t buffer[1024];
+    OpenRequest *req = (void *)buffer;
+    OpenResponse *rsp = (void *)buffer;
+
+    if (remote_file_fd == -1) {
+        return qemu_open(filename, flags, mode);
+    }
+
+    req->filename_len = strlen(filename);
+    req->message_len = sizeof(OpenRequest) + req->filename_len;
+    req->type = 1; /* OpenRequest */
+    req->flags = flags;
+    req->mode = mode;
+
+    if (req->message_len > sizeof(buffer)) {
+        errno = EFAULT;
+        return -1;
+    }
+    memcpy(req->filename, filename, req->filename_len);
+
+    do {
+        ret = send(remote_file_fd, req, req->message_len, 0);
+    } while (ret == -1 && errno == EINTR);
+    if (ret != req->message_len) {
+        errno = EPIPE;
+        return -1;
+    }
+
+    iov[0].iov_base = buffer;
+    iov[0].iov_len = sizeof(buffer);
+
+    msg.msg_iov = iov;
+    msg.msg_iovlen = 1;
+    msg.msg_control = &msg_control;
+    msg.msg_controllen = sizeof(msg_control);
+
+    do {
+        ret = recvmsg(remote_file_fd, &msg, 0);
+    } while (ret == -1 && errno == EINTR);
+    if (ret != sizeof(OpenResponse)) {
+        errno = EPIPE;
+        return -1;
+    }
+
+    rsp = (void *)buffer;
+    if (rsp->result < 0) {
+        errno = -rsp->result;
+        return -1;
+    }
+
+    for (cmsg = CMSG_FIRSTHDR(&msg); cmsg; cmsg = CMSG_NXTHDR(&msg, cmsg)) {
+        int fd;
+
+        if (cmsg->cmsg_len != CMSG_LEN(sizeof(int)) ||
+            cmsg->cmsg_level != SOL_SOCKET ||
+            cmsg->cmsg_type != SCM_RIGHTS) {
+            continue;
+        }
+
+        fd = *((int *)CMSG_DATA(cmsg));
+        if (fd < 0) {
+            continue;
+        }
+
+        return fd;
+    }
+
+    errno = ENOENT;
+    return -1;
+#endif
 }
 
 #ifdef _WIN32
diff --git a/block.h b/block.h
index f163e54..b8b78c7 100644
--- a/block.h
+++ b/block.h
@@ -336,6 +336,8 @@ int bdrv_img_create(const char *filename, const char *fmt,
 void bdrv_set_buffer_alignment(BlockDriverState *bs, int align);
 void *qemu_blockalign(BlockDriverState *bs, size_t size);
 
+void remote_file_open_init(int fd);
+
 #define BDRV_SECTORS_PER_DIRTY_CHUNK 2048
 
 void bdrv_set_dirty_tracking(BlockDriverState *bs, int enable);
diff --git a/block/raw-posix.c b/block/raw-posix.c
index b6bc6bc..9946e5f 100644
--- a/block/raw-posix.c
+++ b/block/raw-posix.c
@@ -208,7 +208,7 @@ static int raw_open_common(BlockDriverState *bs, const char *filename,
         s->open_flags |= O_DSYNC;
 
     s->fd = -1;
-    fd = qemu_open(filename, s->open_flags, 0644);
+    fd = file_open(filename, s->open_flags, 0644);
     if (fd < 0) {
         ret = -errno;
         if (ret == -EROFS)
diff --git a/qemu-options.hx b/qemu-options.hx
index ccf4d1d..0c54cd5 100644
--- a/qemu-options.hx
+++ b/qemu-options.hx
@@ -2730,8 +2730,8 @@ DEF("open-hook-fd", HAS_ARG, QEMU_OPTION_open_hook_fd,
 STEXI
 @item -open-hook-fd @var{fd}
 @findex -open-hook-fd
-Delegates open()s to an external process using @var<fd> to communicate commands.
-@var<fd> should be an open Unix Domain socket pipe that file descriptors can be
+Delegates open()s to an external process using @var{fd} to communicate commands.
+@var{fd} should be an open Unix Domain socket pipe that file descriptors can be
 received from.  The protocol the socket uses is a simple request/response initiated
 by the client.  All integers are in host byte order.  It is assumed that this protocol
 is only ever used on the same physical machine.  It is currently defined as:
diff --git a/vl.c b/vl.c
index ae91a8a..b418865 100644
--- a/vl.c
+++ b/vl.c
@@ -3191,6 +3191,9 @@ int main(int argc, char **argv, char **envp)
             case QEMU_OPTION_qtest_log:
                 qtest_log = optarg;
                 break;
+            case QEMU_OPTION_open_hook_fd:
+                remote_file_open_init(atoi(optarg));
+                break;
             default:
                 os_parse_cmd_args(popt->index, optarg);
             }
-- 
1.7.10

  parent reply	other threads:[~2012-05-01 15:45 UTC|newest]

Thread overview: 37+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2012-05-01 15:31 [Qemu-devel] [RFC 0/5] block: File descriptor passing using -open-hook-fd Stefan Hajnoczi
2012-05-01 15:31 ` [Qemu-devel] [RFC 1/5] block: add open() wrapper that can be hooked by libvirt Stefan Hajnoczi
2012-05-01 15:31 ` [Qemu-devel] [RFC 2/5] block: add new command line parameter that and protocol description Stefan Hajnoczi
2012-05-02  8:58   ` Daniel P. Berrange
2012-05-02  9:03   ` Daniel P. Berrange
2012-05-01 15:31 ` Stefan Hajnoczi [this message]
2012-05-01 15:31 ` [Qemu-devel] [RFC 4/5] osdep: add qemu_recvmsg() wrapper Stefan Hajnoczi
2012-05-01 15:31 ` [Qemu-devel] [RFC 5/5] Example -open-hook-fd server Stefan Hajnoczi
2012-05-01 16:04   ` [Qemu-devel] [libvirt] " Stefan Hajnoczi
2012-05-01 20:25 ` [Qemu-devel] [RFC 0/5] block: File descriptor passing using -open-hook-fd Anthony Liguori
2012-05-01 20:56   ` [Qemu-devel] [libvirt] " Eric Blake
2012-05-01 21:52     ` Anthony Liguori
2012-05-02 16:40     ` Paolo Bonzini
2012-05-01 21:45   ` [Qemu-devel] " Corey Bryant
2012-05-01 21:53     ` Anthony Liguori
2012-05-01 22:15       ` [Qemu-devel] [libvirt] " Eric Blake
2012-05-01 22:21         ` Anthony Liguori
2012-05-07 16:10         ` Corey Bryant
2012-05-02  8:20   ` [Qemu-devel] " Kevin Wolf
2012-05-02  8:27     ` Stefan Hajnoczi
2012-05-02  9:38       ` Kevin Wolf
2012-05-02  8:53     ` [Qemu-devel] [libvirt] " Daniel P. Berrange
2012-05-02  9:45       ` Kevin Wolf
2012-05-02  9:56         ` Daniel P. Berrange
2012-05-02 19:25           ` Paolo Bonzini
2012-05-03 19:19         ` Anthony Liguori
2012-05-02  9:01 ` [Qemu-devel] " Daniel P. Berrange
2012-05-04  3:28 ` [Qemu-devel] [libvirt] " Zhi Yong Wu
2012-05-17 13:42   ` Stefan Hajnoczi
2012-05-17 13:57     ` Zhi Yong Wu
2012-05-17 14:02     ` Zhi Yong Wu
2012-05-18 10:38       ` Stefan Hajnoczi
2012-05-17 14:14     ` Eric Blake
2012-05-18 10:38       ` Stefan Hajnoczi
2012-07-09 20:00       ` Anthony Liguori
2012-07-09 20:29         ` Eric Blake
2012-07-09 20:46           ` Anthony Liguori

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1335886307-27586-4-git-send-email-stefanha@linux.vnet.ibm.com \
    --to=stefanha@linux.vnet.ibm.com \
    --cc=aliguori@us.ibm.com \
    --cc=coreyb@linux.vnet.ibm.com \
    --cc=kwolf@redhat.com \
    --cc=libvir-list@redhat.com \
    --cc=qemu-devel@nongnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).