Re: [Qemu-devel] [PATCH 1/1] backend: multi-client-socket

2016-04-08 Thread Baptiste Reynal
I wasn't aware of this new framework when I started the development of
this socket. For sure I'll have a deeper look and see what can be
shared for the next version.

On Thu, Mar 31, 2016 at 11:08 AM, Stefan Hajnoczi  wrote:
> On Fri, Mar 18, 2016 at 10:12:46AM +0100, Baptiste Reynal wrote:
>> This patch introduces a new socket for QEMU, called multi-client-socket. This
>> socket allows multiple QEMU instances to communicate by sharing messages
>> and file descriptors.
>>
>> A socket can be instantiated with the following parameters:
>> -object multi-socket-backend,id=,path=,listen=
>>
>> If listen is set, the socket will act as a listener and register new
>> clients.
>>
>> This patch is a follow-up to "[RFC PATCH 0/8] Towards an Heterogeneous QEMU":
>> https://lists.gnu.org/archive/html/qemu-devel/2015-10/msg00171.html
>>
>> This work has been sponsored by Huawei Technologies Duesseldorf GmbH.
>>
>> Signed-off-by: Baptiste Reynal 
>> ---
>>  backends/Makefile.objs  |   2 +
>>  backends/multi-socket.c | 355 
>> 
>>  include/qemu/multi-socket.h | 124 
>>  3 files changed, 481 insertions(+)
>>  create mode 100644 backends/multi-socket.c
>>  create mode 100644 include/qemu/multi-socket.h
>
> Is it possible to reuse QEMU's UNIX domain socket and fd passing code?
> For example, take a look at io/channel-socket.c.



Re: [Qemu-devel] [PATCH 1/1] backend: multi-client-socket

2016-03-31 Thread Stefan Hajnoczi
On Fri, Mar 18, 2016 at 10:12:46AM +0100, Baptiste Reynal wrote:
> This patch introduces a new socket for QEMU, called multi-client-socket. This
> socket allows multiple QEMU instances to communicate by sharing messages
> and file descriptors.
> 
> A socket can be instantiated with the following parameters:
> -object multi-socket-backend,id=,path=,listen=
> 
> If listen is set, the socket will act as a listener and register new
> clients.
> 
> This patch is a follow-up to "[RFC PATCH 0/8] Towards an Heterogeneous QEMU":
> https://lists.gnu.org/archive/html/qemu-devel/2015-10/msg00171.html
> 
> This work has been sponsored by Huawei Technologies Duesseldorf GmbH.
> 
> Signed-off-by: Baptiste Reynal 
> ---
>  backends/Makefile.objs  |   2 +
>  backends/multi-socket.c | 355 
> 
>  include/qemu/multi-socket.h | 124 
>  3 files changed, 481 insertions(+)
>  create mode 100644 backends/multi-socket.c
>  create mode 100644 include/qemu/multi-socket.h

Is it possible to reuse QEMU's UNIX domain socket and fd passing code?
For example, take a look at io/channel-socket.c.


signature.asc
Description: PGP signature


[Qemu-devel] [PATCH 1/1] backend: multi-client-socket

2016-03-19 Thread Baptiste Reynal
This patch introduces a new socket for QEMU, called multi-client-socket. This
socket allows multiple QEMU instances to communicate by sharing messages
and file descriptors.

A socket can be instantiated with the following parameters:
-object multi-socket-backend,id=,path=,listen=

If listen is set, the socket will act as a listener and register new
clients.

This patch is a follow-up to "[RFC PATCH 0/8] Towards an Heterogeneous QEMU":
https://lists.gnu.org/archive/html/qemu-devel/2015-10/msg00171.html

This work has been sponsored by Huawei Technologies Duesseldorf GmbH.

Signed-off-by: Baptiste Reynal 
---
 backends/Makefile.objs  |   2 +
 backends/multi-socket.c | 355 
 include/qemu/multi-socket.h | 124 
 3 files changed, 481 insertions(+)
 create mode 100644 backends/multi-socket.c
 create mode 100644 include/qemu/multi-socket.h

diff --git a/backends/Makefile.objs b/backends/Makefile.objs
index 31a3a89..689eac3 100644
--- a/backends/Makefile.objs
+++ b/backends/Makefile.objs
@@ -9,3 +9,5 @@ common-obj-$(CONFIG_TPM) += tpm.o
 
 common-obj-y += hostmem.o hostmem-ram.o
 common-obj-$(CONFIG_LINUX) += hostmem-file.o
+
+common-obj-y += multi-socket.o
diff --git a/backends/multi-socket.c b/backends/multi-socket.c
new file mode 100644
index 000..2cfbb50
--- /dev/null
+++ b/backends/multi-socket.c
@@ -0,0 +1,355 @@
+/*
+ * QEMU Multi Client socket
+ *
+ * Copyright (C) 2015 - Virtual Open Systems
+ *
+ * Author: Baptiste Reynal 
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2.  See
+ * the COPYING file in the top-level directory.
+ */
+
+#include "qemu/multi-socket.h"
+#include "qemu/error-report.h"
+
+typedef struct MSHandler MSHandler;
+typedef struct MSRegHandler MSRegHandler;
+
+struct MSHandler {
+char *name;
+void (*read)(MSClient *client, const char *message, void *opaque);
+void *opaque;
+
+QLIST_ENTRY(MSHandler) next;
+};
+
+struct MSRegHandler {
+void (*reg)(MSClient *client, void *opaque);
+void *opaque;
+
+QLIST_ENTRY(MSRegHandler) next;
+};
+
+static void multi_socket_get_fds(MSClient *client, struct msghdr msg)
+{
+struct cmsghdr *cmsg;
+
+/* process fds */
+for (cmsg = CMSG_FIRSTHDR(); cmsg; cmsg = CMSG_NXTHDR(, cmsg)) {
+int fd_size;
+
+if (cmsg->cmsg_len < CMSG_LEN(sizeof(int)) ||
+cmsg->cmsg_level != SOL_SOCKET ||
+cmsg->cmsg_type != SCM_RIGHTS) {
+continue;
+}
+
+fd_size = cmsg->cmsg_len - CMSG_LEN(0);
+
+if (!fd_size) {
+continue;
+}
+
+g_free(client->rcvfds);
+
+client->rcvfds_num = fd_size / sizeof(int);
+client->rcvfds = g_malloc(fd_size);
+memcpy(client->rcvfds, CMSG_DATA(cmsg), fd_size);
+}
+}
+
+static gboolean
+multi_socket_read_handler(GIOChannel *channel, GIOCondition cond, void *opaque)
+{
+MSClient *client = (MSClient *) opaque;
+MSBackend *backend = client->backend;
+
+char message[BUFFER_SIZE];
+struct MSHandler *h;
+
+struct msghdr msg = { NULL, };
+struct iovec iov[1];
+union {
+struct cmsghdr cmsg;
+char control[CMSG_SPACE(sizeof(int) * MAX_FDS)];
+} msg_control;
+int flags = 0;
+ssize_t ret;
+
+iov[0].iov_base = message;
+iov[0].iov_len = BUFFER_SIZE;
+
+msg.msg_iov = iov;
+msg.msg_iovlen = 1;
+msg.msg_control = _control;
+msg.msg_controllen = sizeof(msg_control);
+
+ret = recvmsg(client->fd, , flags);
+
+if (ret > 0) {
+multi_socket_get_fds(client, msg);
+
+/* handler callback */
+QLIST_FOREACH(h, >handlers, next) {
+if (!strncmp(h->name, message, strlen(h->name))) {
+h->read(client, message + strlen(h->name) + 1, h->opaque);
+return TRUE;
+}
+}
+error_report("Unrecognized message: %s", message);
+}
+
+return FALSE;
+}
+
+void multi_socket_add_reg_handler(MSBackend *backend,
+void (*reg)(MSClient *client, void *opaque), void *opaque)
+{
+struct MSRegHandler *h;
+
+h = g_malloc(sizeof(struct MSRegHandler));
+
+h->reg = reg;
+h->opaque = opaque;
+
+QLIST_INSERT_HEAD(>reg_handlers, h, next);
+}
+
+void multi_socket_add_handler(MSBackend *backend,
+const char *name,
+void (*read)(MSClient *c, const char *message, void *opaque),
+void *opaque)
+{
+struct MSHandler *h;
+
+/* check that the handler name is not taken */
+QLIST_FOREACH(h, >handlers, next) {
+if (!strcmp(h->name, name)) {
+error_report("Handler %s already exists", name);
+return;
+}
+}
+
+h = g_malloc(sizeof(struct MSHandler));
+
+h->name = g_strdup(name);
+h->read = read;
+h->opaque = opaque;
+
+QLIST_INSERT_HEAD(>handlers, h, next);
+}
+
+static void