qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
From: Mark McLoughlin <markmc@redhat.com>
To: qemu-devel <qemu-devel@nongnu.org>
Subject: [Qemu-devel] [PATCH 2/3] Add SCM_RIGHTS support to unix socket character devices
Date: Mon, 06 Jul 2009 18:31:35 +0100	[thread overview]
Message-ID: <1246901495.12086.22.camel@blaa> (raw)
In-Reply-To: <1246901456.12086.21.camel@blaa>

If a file descriptor is passed via a message with SCM_RIGHTS ancillary
data on a unix socket, store the file descriptor for use in the
chr_read() handler. Close the file descriptor if it was not used.

The qemu_chr_get_msgfd() and monitor_get_msgfd() APIs provide access
to any passed descriptor.

Signed-off-by: Mark McLoughlin <markmc@redhat.com>
---
 monitor.c   |    5 +++++
 monitor.h   |    1 +
 qemu-char.c |   50 ++++++++++++++++++++++++++++++++++++++++++++++++++
 qemu-char.h |    2 ++
 4 files changed, 58 insertions(+), 0 deletions(-)

diff --git a/monitor.c b/monitor.c
index bad79fe..f61f43d 100644
--- a/monitor.c
+++ b/monitor.c
@@ -2981,6 +2981,11 @@ static void monitor_read(void *opaque, const uint8_t *buf, int size)
     cur_mon = old_mon;
 }
 
+int monitor_get_msgfd(Monitor *mon)
+{
+    return qemu_chr_get_msgfd(mon->chr);
+}
+
 static void monitor_command_cb(Monitor *mon, const char *cmdline, void *opaque)
 {
     monitor_suspend(mon);
diff --git a/monitor.h b/monitor.h
index 13e8cc7..af97a86 100644
--- a/monitor.h
+++ b/monitor.h
@@ -19,6 +19,7 @@ void monitor_resume(Monitor *mon);
 void monitor_read_bdrv_key_start(Monitor *mon, BlockDriverState *bs,
                                  BlockDriverCompletionFunc *completion_cb,
                                  void *opaque);
+int monitor_get_msgfd(Monitor *mon);
 
 void monitor_vprintf(Monitor *mon, const char *fmt, va_list ap);
 void monitor_printf(Monitor *mon, const char *fmt, ...)
diff --git a/qemu-char.c b/qemu-char.c
index e0d7220..f06a614 100644
--- a/qemu-char.c
+++ b/qemu-char.c
@@ -168,6 +168,11 @@ void qemu_chr_read(CharDriverState *s, uint8_t *buf, int len)
     s->chr_read(s->handler_opaque, buf, len);
 }
 
+int qemu_chr_get_msgfd(CharDriverState *s)
+{
+    return s->get_msgfd ? s->get_msgfd(s) : -1;
+}
+
 void qemu_chr_accept_input(CharDriverState *s)
 {
     if (s->chr_accept_input)
@@ -1832,6 +1837,7 @@ typedef struct {
     int do_telnetopt;
     int do_nodelay;
     int is_unix;
+    int msgfd;
 } TCPCharDriver;
 
 static void tcp_chr_accept(void *opaque);
@@ -1907,12 +1913,46 @@ static void tcp_chr_process_IAC_bytes(CharDriverState *chr,
     *size = j;
 }
 
+static int tcp_get_msgfd(CharDriverState *chr)
+{
+    TCPCharDriver *s = chr->opaque;
+
+    return s->msgfd;
+}
+
+static void unix_process_msgfd(CharDriverState *chr, struct msghdr *msg)
+{
+    TCPCharDriver *s = chr->opaque;
+    struct cmsghdr *cmsg;
+
+    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;
+
+        if (s->msgfd != -1)
+            close(s->msgfd);
+        s->msgfd = fd;
+    }
+}
+
 static void tcp_chr_read(void *opaque)
 {
     CharDriverState *chr = opaque;
     TCPCharDriver *s = chr->opaque;
     struct msghdr msg = { 0, };
     struct iovec iov[1];
+    union {
+        struct cmsghdr cmsg;
+        char control[CMSG_SPACE(sizeof(int))];
+    } msg_control;
     uint8_t buf[1024];
     int len, size;
 
@@ -1928,6 +1968,8 @@ static void tcp_chr_read(void *opaque)
 
     msg.msg_iov = iov;
     msg.msg_iovlen = 1;
+    msg.msg_control = &msg_control;
+    msg.msg_controllen = sizeof(msg_control);
 
     size = recvmsg(s->fd, &msg, 0);
     if (size == 0) {
@@ -1940,10 +1982,16 @@ static void tcp_chr_read(void *opaque)
         closesocket(s->fd);
         s->fd = -1;
     } else if (size > 0) {
+        if (s->is_unix)
+            unix_process_msgfd(chr, &msg);
         if (s->do_telnetopt)
             tcp_chr_process_IAC_bytes(chr, s, buf, &size);
         if (size > 0)
             qemu_chr_read(chr, buf, size);
+        if (s->msgfd != -1) {
+            close(s->msgfd);
+            s->msgfd = -1;
+        }
     }
 }
 
@@ -2105,12 +2153,14 @@ static CharDriverState *qemu_chr_open_tcp(const char *host_str,
     s->connected = 0;
     s->fd = -1;
     s->listen_fd = -1;
+    s->msgfd = -1;
     s->is_unix = is_unix;
     s->do_nodelay = do_nodelay && !is_unix;
 
     chr->opaque = s;
     chr->chr_write = tcp_chr_write;
     chr->chr_close = tcp_chr_close;
+    chr->get_msgfd = tcp_get_msgfd;
 
     if (is_listen) {
         s->listen_fd = fd;
diff --git a/qemu-char.h b/qemu-char.h
index e1aa8db..77d4eda 100644
--- a/qemu-char.h
+++ b/qemu-char.h
@@ -51,6 +51,7 @@ struct CharDriverState {
     int (*chr_write)(struct CharDriverState *s, const uint8_t *buf, int len);
     void (*chr_update_read_handler)(struct CharDriverState *s);
     int (*chr_ioctl)(struct CharDriverState *s, int cmd, void *arg);
+    int (*get_msgfd)(struct CharDriverState *s);
     IOEventHandler *chr_event;
     IOCanRWHandler *chr_can_read;
     IOReadHandler *chr_read;
@@ -81,6 +82,7 @@ void qemu_chr_reset(CharDriverState *s);
 void qemu_chr_initial_reset(void);
 int qemu_chr_can_read(CharDriverState *s);
 void qemu_chr_read(CharDriverState *s, uint8_t *buf, int len);
+int qemu_chr_get_msgfd(CharDriverState *s);
 void qemu_chr_accept_input(CharDriverState *s);
 void qemu_chr_info(Monitor *mon);
 
-- 
1.6.2.5

  reply	other threads:[~2009-07-06 17:31 UTC|newest]

Thread overview: 53+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2009-07-06 17:30 [Qemu-devel] [PATCH 0/3] Allow host_net_add monitor command accept file descriptors Mark McLoughlin
2009-07-06 17:30 ` [Qemu-devel] [PATCH 1/3] Make tcp_chr_read() use recvmsg() Mark McLoughlin
2009-07-06 17:31   ` Mark McLoughlin [this message]
2009-07-06 17:32     ` [Qemu-devel] [PATCH 3/3] Add support for fd=msgfd for tap and socket networking Mark McLoughlin
2009-07-07  5:28 ` [Qemu-devel] [PATCH 0/3] Allow host_net_add monitor command accept file descriptors Avi Kivity
2009-07-07  7:43   ` Mark McLoughlin
2009-07-07  7:52     ` Avi Kivity
2009-07-07  8:13       ` Mark McLoughlin
2009-07-07  9:03         ` Avi Kivity
2009-07-07 10:06           ` Daniel P. Berrange
2009-07-08 14:56             ` Mark McLoughlin
2009-07-08 14:57               ` [Qemu-devel] [PATCH 1/5] Make tcp_chr_read() use recvmsg() Mark McLoughlin
2009-07-08 14:57                 ` [Qemu-devel] [PATCH 2/5] Add SCM_RIGHTS support to unix socket character devices Mark McLoughlin
2009-07-08 14:57                   ` [Qemu-devel] [PATCH 3/5] Add getfd and closefd monitor commands Mark McLoughlin
2009-07-08 14:57                     ` [Qemu-devel] [PATCH 4/5] Add monitor_get_fd() command for fetching named fds Mark McLoughlin
2009-07-08 14:57                       ` [Qemu-devel] [PATCH 5/5] Add support for fd=name to tap and socket networking Mark McLoughlin
2009-07-08 15:26                     ` [Qemu-devel] [PATCH 3/5] Add getfd and closefd monitor commands Avi Kivity
2009-07-08 16:03                       ` Mark McLoughlin
2009-07-08 16:15                         ` Avi Kivity
2009-07-08 18:08                           ` Anthony Liguori
2009-07-08 18:11                             ` Avi Kivity
2009-07-08 18:21                               ` Anthony Liguori
2009-07-08 18:32                                 ` Avi Kivity
2009-07-08 18:50                                   ` Anthony Liguori
2009-07-08 19:52                                     ` Avi Kivity
2009-07-11  1:12                                       ` Jamie Lokier
2009-07-21 16:40                                       ` Mark McLoughlin
2009-07-21 16:53                                         ` [Qemu-devel] [PATCH] Make tcp_chr_read() use recvmsg() Mark McLoughlin
2009-07-21 17:13                                           ` Blue Swirl
2009-07-22  0:00                                             ` Jamie Lokier
2009-07-22  8:10                                             ` Mark McLoughlin
2009-07-22  8:11                                               ` [Qemu-devel] [PATCH 1/5] " Mark McLoughlin
2009-07-22  8:11                                               ` [Qemu-devel] [PATCH 2/5] Add SCM_RIGHTS support to unix socket character devices Mark McLoughlin
2009-08-13 16:20                                                 ` Cam Macdonell
2009-08-14  6:38                                                   ` Mark McLoughlin
2009-07-22  8:11                                               ` [Qemu-devel] [PATCH 3/5] Add getfd and closefd monitor commands Mark McLoughlin
2009-07-22  8:11                                               ` [Qemu-devel] [PATCH 4/5] Add monitor_get_fd() command for fetching named fds Mark McLoughlin
2009-07-22  8:11                                               ` [Qemu-devel] [PATCH 5/5] Add support for fd=name to tap and socket networking Mark McLoughlin
2009-07-23 13:37                                                 ` Mark McLoughlin
2009-07-21 16:53                                         ` [Qemu-devel] [PATCH] Add SCM_RIGHTS support to unix socket character devices Mark McLoughlin
2009-07-21 16:53                                         ` [Qemu-devel] [PATCH] Add getfd and closefd monitor commands Mark McLoughlin
2009-07-21 16:53                                         ` [Qemu-devel] [PATCH] Add monitor_get_fd() command for fetching named fds Mark McLoughlin
2009-07-21 16:53                                         ` [Qemu-devel] [PATCH] Add support for fd=name to tap and socket networking Mark McLoughlin
2009-07-22  2:20                                         ` [Qemu-devel] [PATCH 3/5] Add getfd and closefd monitor commands Anthony Liguori
2009-07-22  8:09                                           ` Mark McLoughlin
2009-07-23  7:00                                             ` [Qemu-devel] " Jan Kiszka
2009-07-23  7:51                                               ` Mark McLoughlin
2009-07-08 15:25                   ` [Qemu-devel] [PATCH 2/5] Add SCM_RIGHTS support to unix socket character devices Avi Kivity
2009-07-08 16:04                     ` Mark McLoughlin
2009-07-08 16:17                       ` Avi Kivity
2009-07-08 18:11                       ` Anthony Liguori
2009-07-08 18:17                         ` Avi Kivity
2009-07-11  1:15                           ` Jamie Lokier

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=1246901495.12086.22.camel@blaa \
    --to=markmc@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).