Re: [Qemu-devel] [PATCH 21/21] block: add spice block device backend
/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
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