qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
* [Qemu-devel] [PATCH RFC 1/2] Allow recvmsg for qemu char devices
@ 2009-07-30 16:28 Cam Macdonell
  2009-07-30 18:28 ` [Qemu-devel] " Anthony Liguori
  0 siblings, 1 reply; 2+ messages in thread
From: Cam Macdonell @ 2009-07-30 16:28 UTC (permalink / raw)
  To: kvm; +Cc: Cam Macdonell, qemu-devel

This patch allows switching from the standard recv to recvmsg for a qemu char
device.  Switching allows file descriptors to be passed with SCM_RIGHTS to a
qemu process.  Instead of receiving a buffer of data the recvmsg call back is
passed a 'struct msghdr'.

The patch also adds a function to add an eventfd as qemu char device.  Perhaps
this should be a separate patch.

This is not an elegant solution to supporting recvmsg so suggestions are
especially welcome.

---
 qemu-char.c |   72 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 qemu-char.h |    8 ++++++
 2 files changed, 80 insertions(+), 0 deletions(-)

diff --git a/qemu-char.c b/qemu-char.c
index 287e0cd..c1620c2 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);
 }
 
+void qemu_chr_recvmsg(CharDriverState *s, struct msghdr *msg, int flags)
+{
+    s->chr_read(s->handler_opaque, msg, flags);
+}
+
 void qemu_chr_accept_input(CharDriverState *s)
 {
     if (s->chr_accept_input)
@@ -1652,6 +1657,7 @@ static CharDriverState *qemu_chr_open_win_pipe(const char *filename)
     WinCharState *s;
 
     chr = qemu_mallocz(sizeof(CharDriverState));
+
     s = qemu_mallocz(sizeof(WinCharState));
     chr->opaque = s;
     chr->chr_write = win_chr_write;
@@ -1937,6 +1943,72 @@ static void tcp_chr_read(void *opaque)
     }
 }
 
+/* this is a new function that will replace tcp_chr_read (which calls recv)
+ * with this one that calls recvmsg instead when we want to use recvmsg */
+static void tcp_chr_recvmsg(void *opaque)
+{
+    CharDriverState *chr = opaque;
+    TCPCharDriver *s = chr->opaque;
+    struct msghdr msg;
+    uint8_t buf[1024];
+    int len, size;
+    char control[CMSG_SPACE(RECVMSG_MAX)];
+    struct iovec iov[8];
+
+    printf("inside tcp_chr_recvmsg\n");
+    msg.msg_name = 0;
+    msg.msg_namelen = 0;
+    msg.msg_control = control;
+    msg.msg_controllen = sizeof(control);
+    msg.msg_flags = 0;
+    msg.msg_iov = iov;
+    msg.msg_iovlen = 1;
+
+    iov[0].iov_base = buf;
+    iov[0].iov_len = 1024;
+
+    if (!s->connected || s->max_size <= 0)
+        return;
+    len = sizeof(control);
+    if (len > s->max_size)
+        len = s->max_size;
+//    size = recv(s->fd, buf, len, 0);
+    printf("calling recvmsg\n");
+    size = recvmsg(s->fd, &msg, 0);
+    if (size == 0) {
+        /* connection closed */
+        s->connected = 0;
+        if (s->listen_fd >= 0) {
+            qemu_set_fd_handler(s->listen_fd, tcp_chr_accept, NULL, chr);
+        }
+        qemu_set_fd_handler(s->fd, NULL, NULL, NULL);
+        closesocket(s->fd);
+        s->fd = -1;
+    } else if (size > 0) {
+        if (s->do_telnetopt)
+            tcp_chr_process_IAC_bytes(chr, s, buf, &size);
+        if (size > 0)
+            qemu_chr_recvmsg(chr, &msg, 0);
+    }
+
+
+}
+
+void tcp_switch_to_recvmsg_handlers(void *opaque)
+{
+    CharDriverState *chr = opaque;
+    TCPCharDriver *s = chr->opaque;
+
+    qemu_set_fd_handler2(s->fd, tcp_chr_read_poll,
+                         tcp_chr_recvmsg, NULL, chr);
+}
+
+CharDriverState *qemu_chr_open_eventfd(int eventfd){
+
+    return qemu_chr_open_fd(eventfd, eventfd);
+
+}
+
 static void tcp_chr_connect(void *opaque)
 {
     CharDriverState *chr = opaque;
diff --git a/qemu-char.h b/qemu-char.h
index e1aa8db..5fe6c43 100644
--- a/qemu-char.h
+++ b/qemu-char.h
@@ -44,6 +44,8 @@ typedef struct {
 #define CHR_TIOCM_DTR	0x002
 #define CHR_TIOCM_RTS	0x004
 
+#define RECVMSG_MAX    1024
+
 typedef void IOEventHandler(void *opaque, int event);
 
 struct CharDriverState {
@@ -84,6 +86,12 @@ void qemu_chr_read(CharDriverState *s, uint8_t *buf, int len);
 void qemu_chr_accept_input(CharDriverState *s);
 void qemu_chr_info(Monitor *mon);
 
+/* function to change tcp_chr_read to tcp_chr_recvmsg */
+void tcp_switch_to_recvmsg_handlers(void *opaque);
+
+/* add an eventfd to the qemu devices that are polled */
+CharDriverState *qemu_chr_open_eventfd(int eventfd);
+
 extern int term_escape_char;
 
 /* async I/O support */
-- 
1.6.0.6

^ permalink raw reply related	[flat|nested] 2+ messages in thread

* [Qemu-devel] Re: [PATCH RFC 1/2] Allow recvmsg for qemu char devices
  2009-07-30 16:28 [Qemu-devel] [PATCH RFC 1/2] Allow recvmsg for qemu char devices Cam Macdonell
@ 2009-07-30 18:28 ` Anthony Liguori
  0 siblings, 0 replies; 2+ messages in thread
From: Anthony Liguori @ 2009-07-30 18:28 UTC (permalink / raw)
  To: Cam Macdonell; +Cc: qemu-devel, kvm

Cam Macdonell wrote:
> This patch allows switching from the standard recv to recvmsg for a qemu char
> device.  Switching allows file descriptors to be passed with SCM_RIGHTS to a
> qemu process.  Instead of receiving a buffer of data the recvmsg call back is
> passed a 'struct msghdr'.
>
> The patch also adds a function to add an eventfd as qemu char device.  Perhaps
> this should be a separate patch.
>
> This is not an elegant solution to supporting recvmsg so suggestions are
> especially welcome.
>   

Use the sendfd/closefd commands that Mark introduced.

Regards,

Anthony Liguori

^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2009-07-30 18:29 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2009-07-30 16:28 [Qemu-devel] [PATCH RFC 1/2] Allow recvmsg for qemu char devices Cam Macdonell
2009-07-30 18:28 ` [Qemu-devel] " Anthony Liguori

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).