Re: [Qemu-devel] [PATCH 21/21] block: add spice block device backend

2013-11-20 Thread Marc-André Lureau
/note to self:
- add failing case where nbd channel isn't connected before and after
migration (do not wait for nbd init or disconnection)

On Mon, Nov 18, 2013 at 1:25 PM, Marc-André Lureau
marcandre.lur...@gmail.com wrote:
 From: Marc-André Lureau marcandre.lur...@redhat.com

 Signed-off-by: Marc-André Lureau marcandre.lur...@redhat.com
 ---
  block/Makefile.objs |   1 +
  block/spicebd.c | 536 
 
  2 files changed, 537 insertions(+)
  create mode 100644 block/spicebd.c

 diff --git a/block/Makefile.objs b/block/Makefile.objs
 index 4e8c91e..f49b7c3 100644
 --- a/block/Makefile.objs
 +++ b/block/Makefile.objs
 @@ -16,6 +16,7 @@ block-obj-$(CONFIG_CURL) += curl.o
  block-obj-$(CONFIG_RBD) += rbd.o
  block-obj-$(CONFIG_GLUSTERFS) += gluster.o
  block-obj-$(CONFIG_LIBSSH2) += ssh.o
 +common-obj-$(CONFIG_SPICE) += spicebd.o
  endif

  common-obj-y += stream.o
 diff --git a/block/spicebd.c b/block/spicebd.c
 new file mode 100644
 index 000..6b23b61
 --- /dev/null
 +++ b/block/spicebd.c
 @@ -0,0 +1,536 @@
 +/*
 + * Spice block backend for QEMU.
 + *
 + * Copyright (C) 2013 Red Hat, Inc.
 + * Author: Marc-André Lureau marcandre.lur...@redhat.com
 + *
 + * Permission is hereby granted, free of charge, to any person obtaining a 
 copy
 + * of this software and associated documentation files (the Software), to 
 deal
 + * in the Software without restriction, including without limitation the 
 rights
 + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 + * copies of the Software, and to permit persons to whom the Software is
 + * furnished to do so, subject to the following conditions:
 + *
 + * The above copyright notice and this permission notice shall be included in
 + * all copies or substantial portions of the Software.
 + *
 + * THE SOFTWARE IS PROVIDED AS IS, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
 + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 
 FROM,
 + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 + * THE SOFTWARE.
 + */
 +
 +#include stdio.h
 +#include stdlib.h
 +#include stdarg.h
 +#include spice/protocol.h
 +
 +#include nbd-client.h
 +#include ui/qemu-spice.h
 +#include block/block_int.h
 +#include qemu/sockets.h
 +#include qemu/uri.h
 +#include qapi/qmp/qint.h
 +#include sysemu/sysemu.h
 +#include sysemu/char.h
 +#include qmp-commands.h
 +#include sysemu/blockdev.h
 +#include migration/migration.h
 +
 +#ifndef DEBUG_SPICE
 +#define DEBUG_SPICE   0
 +#endif
 +
 +#define SOCKET_CHR 0
 +#define SOCKET_NBD 1
 +
 +#define DPRINTF(fmt, ...)   \
 +do {\
 +if (DEBUG_SPICE) {  \
 +fprintf(stderr, spicebd: %-15s  fmt \n, \
 +__func__, ##__VA_ARGS__);   \
 +}   \
 +} while (0)
 +
 +typedef struct Buffer {
 +uint8_t data[4096];
 +uint8_t *p;
 +char left;
 +} Buffer;
 +
 +typedef struct BDRVSpiceState {
 +BlockDriverState *bs;
 +QEMUBH *bh;
 +NbdClientSession client;
 +
 +/* our spicechr-fd pipe */
 +int sv[2];
 +Buffer readb;
 +Buffer writeb;
 +
 +int aio_count;
 +CharDriverState *chr;
 +guint chr_watch;
 +
 +Coroutine *coroutine;
 +bool need_read;
 +bool need_write;
 +bool opened;
 +bool inmigrate;
 +} BDRVSpiceState;
 +
 +static void nbd_read_handler(void *opaque);
 +static void update_chr_handlers(BDRVSpiceState *s);
 +
 +static int parse_uri(const char *filename, QDict *options, Error **errp)
 +{
 +URI *uri = NULL;
 +
 +uri = uri_parse(filename);
 +if (!uri) {
 +return -EINVAL;
 +}
 +
 +if (strcmp(uri-scheme, spicebd) != 0) {
 +error_setg(errp, URI scheme must be 'spicebd');
 +goto err;
 +}
 +
 +uri_free(uri);
 +return 0;
 +
 + err:
 +if (uri) {
 +uri_free(uri);
 +}
 +return -EINVAL;
 +}
 +
 +static void spice_parse_filename(const char *filename, QDict *options,
 + Error **errp)
 +{
 +parse_uri(filename, options, errp);
 +}
 +
 +static void co_restart(void *opaque)
 +{
 +BDRVSpiceState *s = opaque;
 +
 +qemu_coroutine_enter(s-coroutine, NULL);
 +}
 +
 +static void close_socketpair(BDRVSpiceState *s)
 +{
 +if (!s-opened) {
 +return;
 +}
 +
 +DPRINTF();
 +nbd_client_session_close(s-client);
 +
 +if (s-sv[SOCKET_NBD] = 0) {
 +qemu_aio_set_fd_handler(s-sv[SOCKET_NBD], NULL, NULL, NULL);
 +closesocket(s-sv[SOCKET_NBD]);
 +s-sv[SOCKET_NBD] = -1;
 +}
 +
 +if (s-sv[SOCKET_CHR] = 0) {
 

[Qemu-devel] [PATCH 21/21] block: add spice block device backend

2013-11-18 Thread Marc-André Lureau
From: Marc-André Lureau marcandre.lur...@redhat.com

Signed-off-by: Marc-André Lureau marcandre.lur...@redhat.com
---
 block/Makefile.objs |   1 +
 block/spicebd.c | 536 
 2 files changed, 537 insertions(+)
 create mode 100644 block/spicebd.c

diff --git a/block/Makefile.objs b/block/Makefile.objs
index 4e8c91e..f49b7c3 100644
--- a/block/Makefile.objs
+++ b/block/Makefile.objs
@@ -16,6 +16,7 @@ block-obj-$(CONFIG_CURL) += curl.o
 block-obj-$(CONFIG_RBD) += rbd.o
 block-obj-$(CONFIG_GLUSTERFS) += gluster.o
 block-obj-$(CONFIG_LIBSSH2) += ssh.o
+common-obj-$(CONFIG_SPICE) += spicebd.o
 endif
 
 common-obj-y += stream.o
diff --git a/block/spicebd.c b/block/spicebd.c
new file mode 100644
index 000..6b23b61
--- /dev/null
+++ b/block/spicebd.c
@@ -0,0 +1,536 @@
+/*
+ * Spice block backend for QEMU.
+ *
+ * Copyright (C) 2013 Red Hat, Inc.
+ * Author: Marc-André Lureau marcandre.lur...@redhat.com
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the Software), to 
deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED AS IS, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 
FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#include stdio.h
+#include stdlib.h
+#include stdarg.h
+#include spice/protocol.h
+
+#include nbd-client.h
+#include ui/qemu-spice.h
+#include block/block_int.h
+#include qemu/sockets.h
+#include qemu/uri.h
+#include qapi/qmp/qint.h
+#include sysemu/sysemu.h
+#include sysemu/char.h
+#include qmp-commands.h
+#include sysemu/blockdev.h
+#include migration/migration.h
+
+#ifndef DEBUG_SPICE
+#define DEBUG_SPICE   0
+#endif
+
+#define SOCKET_CHR 0
+#define SOCKET_NBD 1
+
+#define DPRINTF(fmt, ...)   \
+do {\
+if (DEBUG_SPICE) {  \
+fprintf(stderr, spicebd: %-15s  fmt \n, \
+__func__, ##__VA_ARGS__);   \
+}   \
+} while (0)
+
+typedef struct Buffer {
+uint8_t data[4096];
+uint8_t *p;
+char left;
+} Buffer;
+
+typedef struct BDRVSpiceState {
+BlockDriverState *bs;
+QEMUBH *bh;
+NbdClientSession client;
+
+/* our spicechr-fd pipe */
+int sv[2];
+Buffer readb;
+Buffer writeb;
+
+int aio_count;
+CharDriverState *chr;
+guint chr_watch;
+
+Coroutine *coroutine;
+bool need_read;
+bool need_write;
+bool opened;
+bool inmigrate;
+} BDRVSpiceState;
+
+static void nbd_read_handler(void *opaque);
+static void update_chr_handlers(BDRVSpiceState *s);
+
+static int parse_uri(const char *filename, QDict *options, Error **errp)
+{
+URI *uri = NULL;
+
+uri = uri_parse(filename);
+if (!uri) {
+return -EINVAL;
+}
+
+if (strcmp(uri-scheme, spicebd) != 0) {
+error_setg(errp, URI scheme must be 'spicebd');
+goto err;
+}
+
+uri_free(uri);
+return 0;
+
+ err:
+if (uri) {
+uri_free(uri);
+}
+return -EINVAL;
+}
+
+static void spice_parse_filename(const char *filename, QDict *options,
+ Error **errp)
+{
+parse_uri(filename, options, errp);
+}
+
+static void co_restart(void *opaque)
+{
+BDRVSpiceState *s = opaque;
+
+qemu_coroutine_enter(s-coroutine, NULL);
+}
+
+static void close_socketpair(BDRVSpiceState *s)
+{
+if (!s-opened) {
+return;
+}
+
+DPRINTF();
+nbd_client_session_close(s-client);
+
+if (s-sv[SOCKET_NBD] = 0) {
+qemu_aio_set_fd_handler(s-sv[SOCKET_NBD], NULL, NULL, NULL);
+closesocket(s-sv[SOCKET_NBD]);
+s-sv[SOCKET_NBD] = -1;
+}
+
+if (s-sv[SOCKET_CHR] = 0) {
+qemu_aio_set_fd_handler(s-sv[SOCKET_CHR], NULL, NULL, NULL);
+closesocket(s-sv[SOCKET_CHR]);
+s-sv[SOCKET_CHR] = -1;
+}
+
+if (s-inmigrate) {
+vm_start_release();
+s-inmigrate = false;
+}
+
+s-opened = FALSE;
+if (s-coroutine  s-coroutine != qemu_coroutine_self()) {
+co_restart(s);
+}
+}
+
+static int