Commit b1a419ec authored by Peter Maydell's avatar Peter Maydell
Browse files

Merge remote-tracking branch 'remotes/maxreitz/tags/pull-block-2017-04-03' into staging



Block patches for 2.9-rc3

# gpg: Signature made Mon 03 Apr 2017 16:29:49 BST
# gpg:                using RSA key 0xF407DB0061D5CF40
# gpg: Good signature from "Max Reitz <mreitz@redhat.com>"
# Primary key fingerprint: 91BE B60A 30DB 3E88 57D1  1829 F407 DB00 61D5 CF40

* remotes/maxreitz/tags/pull-block-2017-04-03:
  block/parallels: Avoid overflows
  iotests: Improve image-clear tests on non-aligned image
  qcow2: Discard unaligned tail when wiping image
  iotests: fix 097 when run with qcow
  qemu-io-cmds: Assert that global and nofile commands don't use ct->perms
  sheepdog: Fix blockdev-add
  nbd: Tidy up blockdev-add interface
  sockets: New helper socket_address_crumple()
  qapi-schema: SocketAddressFlat variants 'vsock' and 'fd'
  gluster: Prepare for SocketAddressFlat extension
  block: Document -drive problematic code and bugs
  io vnc sockets: Clean up SocketAddressKind switches
  char: Fix socket with "type": "vsock" address
  nbd sockets vnc: Mark problematic address family tests TODO
  block: add missed aio_context_acquire into release_drive

Signed-off-by: default avatarPeter Maydell <peter.maydell@linaro.org>
parents 102a3d84 86d1bd70
Loading
Loading
Loading
Loading
+45 −3
Original line number Diff line number Diff line
@@ -1157,6 +1157,13 @@ static int bdrv_open_common(BlockDriverState *bs, BlockBackend *file,
    if (file != NULL) {
        filename = blk_bs(file)->filename;
    } else {
        /*
         * Caution: while qdict_get_try_str() is fine, getting
         * non-string types would require more care.  When @options
         * come from -blockdev or blockdev_add, its members are typed
         * according to the QAPI schema, but when they come from
         * -drive, they're all QString.
         */
        filename = qdict_get_try_str(options, "filename");
    }

@@ -1324,6 +1331,13 @@ static int bdrv_fill_options(QDict **options, const char *filename,
    BlockDriver *drv = NULL;
    Error *local_err = NULL;

    /*
     * Caution: while qdict_get_try_str() is fine, getting non-string
     * types would require more care.  When @options come from
     * -blockdev or blockdev_add, its members are typed according to
     * the QAPI schema, but when they come from -drive, they're all
     * QString.
     */
    drvname = qdict_get_try_str(*options, "driver");
    if (drvname) {
        drv = bdrv_find_format(drvname);
@@ -1358,6 +1372,7 @@ static int bdrv_fill_options(QDict **options, const char *filename,
    }

    /* Find the right block driver */
    /* See cautionary note on accessing @options above */
    filename = qdict_get_try_str(*options, "filename");

    if (!drvname && protocol) {
@@ -1987,6 +2002,13 @@ int bdrv_open_backing_file(BlockDriverState *bs, QDict *parent_options,
    qdict_extract_subqdict(parent_options, &options, bdref_key_dot);
    g_free(bdref_key_dot);

    /*
     * Caution: while qdict_get_try_str() is fine, getting non-string
     * types would require more care.  When @parent_options come from
     * -blockdev or blockdev_add, its members are typed according to
     * the QAPI schema, but when they come from -drive, they're all
     * QString.
     */
    reference = qdict_get_try_str(parent_options, bdref_key);
    if (reference || qdict_haskey(options, "file.filename")) {
        backing_filename[0] = '\0';
@@ -2059,6 +2081,13 @@ bdrv_open_child_bs(const char *filename, QDict *options, const char *bdref_key,
    qdict_extract_subqdict(options, &image_options, bdref_key_dot);
    g_free(bdref_key_dot);

    /*
     * Caution: while qdict_get_try_str() is fine, getting non-string
     * types would require more care.  When @options come from
     * -blockdev or blockdev_add, its members are typed according to
     * the QAPI schema, but when they come from -drive, they're all
     * QString.
     */
    reference = qdict_get_try_str(options, bdref_key);
    if (!filename && !reference && !qdict_size(image_options)) {
        if (!allow_none) {
@@ -2274,9 +2303,13 @@ static BlockDriverState *bdrv_open_inherit(const char *filename,
        goto fail;
    }

    /* Set the BDRV_O_RDWR and BDRV_O_ALLOW_RDWR flags.
     * FIXME: we're parsing the QDict to avoid having to create a
     * QemuOpts just for this, but neither option is optimal. */
    /*
     * Set the BDRV_O_RDWR and BDRV_O_ALLOW_RDWR flags.
     * Caution: getting a boolean member of @options requires care.
     * When @options come from -blockdev or blockdev_add, members are
     * typed according to the QAPI schema, but when they come from
     * -drive, they're all QString.
     */
    if (g_strcmp0(qdict_get_try_str(options, BDRV_OPT_READ_ONLY), "on") &&
        !qdict_get_try_bool(options, BDRV_OPT_READ_ONLY, false)) {
        flags |= (BDRV_O_RDWR | BDRV_O_ALLOW_RDWR);
@@ -2298,6 +2331,7 @@ static BlockDriverState *bdrv_open_inherit(const char *filename,
    options = qdict_clone_shallow(options);

    /* Find the right image format driver */
    /* See cautionary note on accessing @options above */
    drvname = qdict_get_try_str(options, "driver");
    if (drvname) {
        drv = bdrv_find_format(drvname);
@@ -2309,6 +2343,7 @@ static BlockDriverState *bdrv_open_inherit(const char *filename,

    assert(drvname || !(flags & BDRV_O_PROTOCOL));

    /* See cautionary note on accessing @options above */
    backing = qdict_get_try_str(options, "backing");
    if (backing && *backing == '\0') {
        flags |= BDRV_O_NO_BACKING;
@@ -2787,6 +2822,13 @@ int bdrv_reopen_prepare(BDRVReopenState *reopen_state, BlockReopenQueue *queue,
        do {
            QString *new_obj = qobject_to_qstring(entry->value);
            const char *new = qstring_get_str(new_obj);
            /*
             * Caution: while qdict_get_try_str() is fine, getting
             * non-string types would require more care.  When
             * bs->options come from -blockdev or blockdev_add, its
             * members are typed according to the QAPI schema, but
             * when they come from -drive, they're all QString.
             */
            const char *old = qdict_get_try_str(reopen_state->bs->options,
                                                entry->key);

+6 −0
Original line number Diff line number Diff line
@@ -2193,6 +2193,12 @@ static int hdev_open(BlockDriverState *bs, QDict *options, int flags,
    int ret;

#if defined(__APPLE__) && defined(__MACH__)
    /*
     * Caution: while qdict_get_str() is fine, getting non-string types
     * would require more care.  When @options come from -blockdev or
     * blockdev_add, its members are typed according to the QAPI
     * schema, but when they come from -drive, they're all QString.
     */
    const char *filename = qdict_get_str(options, "filename");
    char bsd_path[MAXPATHLEN] = "";
    bool error_occurred = false;
+18 −10
Original line number Diff line number Diff line
@@ -412,10 +412,12 @@ static struct glfs *qemu_gluster_glfs_init(BlockdevOptionsGluster *gconf,
    glfs_set_preopened(gconf->volume, glfs);

    for (server = gconf->server; server; server = server->next) {
        if (server->value->type  == SOCKET_ADDRESS_FLAT_TYPE_UNIX) {
        switch (server->value->type) {
        case SOCKET_ADDRESS_FLAT_TYPE_UNIX:
            ret = glfs_set_volfile_server(glfs, "unix",
                                   server->value->u.q_unix.path, 0);
        } else {
            break;
        case SOCKET_ADDRESS_FLAT_TYPE_INET:
            if (parse_uint_full(server->value->u.inet.port, &port, 10) < 0 ||
                port > 65535) {
                error_setg(errp, "'%s' is not a valid port number",
@@ -426,6 +428,11 @@ static struct glfs *qemu_gluster_glfs_init(BlockdevOptionsGluster *gconf,
            ret = glfs_set_volfile_server(glfs, "tcp",
                                   server->value->u.inet.host,
                                   (int)port);
            break;
        case SOCKET_ADDRESS_FLAT_TYPE_VSOCK:
        case SOCKET_ADDRESS_FLAT_TYPE_FD:
        default:
            abort();
        }

        if (ret < 0) {
@@ -487,7 +494,7 @@ static int qemu_gluster_parse_json(BlockdevOptionsGluster *gconf,
    char *str = NULL;
    const char *ptr;
    size_t num_servers;
    int i;
    int i, type;

    /* create opts info from runtime_json_opts list */
    opts = qemu_opts_create(&runtime_json_opts, NULL, 0, &error_abort);
@@ -539,16 +546,17 @@ static int qemu_gluster_parse_json(BlockdevOptionsGluster *gconf,
        if (!strcmp(ptr, "tcp")) {
            ptr = "inet";       /* accept legacy "tcp" */
        }
        gsconf->type = qapi_enum_parse(SocketAddressFlatType_lookup, ptr,
                                       SOCKET_ADDRESS_FLAT_TYPE__MAX, -1,
                                       &local_err);
        if (local_err) {
            error_append_hint(&local_err,
                              "Parameter '%s' may be 'inet' or 'unix'\n",
        type = qapi_enum_parse(SocketAddressFlatType_lookup, ptr,
                               SOCKET_ADDRESS_FLAT_TYPE__MAX, -1, NULL);
        if (type != SOCKET_ADDRESS_FLAT_TYPE_INET
            && type != SOCKET_ADDRESS_FLAT_TYPE_UNIX) {
            error_setg(&local_err,
                       "Parameter '%s' may be 'inet' or 'unix'",
                       GLUSTER_OPT_TYPE);
            error_append_hint(&local_err, GERR_INDEX_HINT, i);
            goto out;
        }
        gsconf->type = type;
        qemu_opts_del(opts);

        if (gsconf->type == SOCKET_ADDRESS_FLAT_TYPE_INET) {
+37 −25
Original line number Diff line number Diff line
@@ -47,7 +47,7 @@ typedef struct BDRVNBDState {
    NBDClientSession client;

    /* For nbd_refresh_filename() */
    SocketAddress *saddr;
    SocketAddressFlat *saddr;
    char *export, *tlscredsid;
} BDRVNBDState;

@@ -95,7 +95,7 @@ static int nbd_parse_uri(const char *filename, QDict *options)
            goto out;
        }
        qdict_put(options, "server.type", qstring_from_str("unix"));
        qdict_put(options, "server.data.path",
        qdict_put(options, "server.path",
                  qstring_from_str(qp->p[0].value));
    } else {
        QString *host;
@@ -116,10 +116,10 @@ static int nbd_parse_uri(const char *filename, QDict *options)
        }

        qdict_put(options, "server.type", qstring_from_str("inet"));
        qdict_put(options, "server.data.host", host);
        qdict_put(options, "server.host", host);

        port_str = g_strdup_printf("%d", uri->port ?: NBD_DEFAULT_PORT);
        qdict_put(options, "server.data.port", qstring_from_str(port_str));
        qdict_put(options, "server.port", qstring_from_str(port_str));
        g_free(port_str);
    }

@@ -197,7 +197,7 @@ static void nbd_parse_filename(const char *filename, QDict *options,
    /* are we a UNIX or TCP socket? */
    if (strstart(host_spec, "unix:", &unixpath)) {
        qdict_put(options, "server.type", qstring_from_str("unix"));
        qdict_put(options, "server.data.path", qstring_from_str(unixpath));
        qdict_put(options, "server.path", qstring_from_str(unixpath));
    } else {
        InetSocketAddress *addr = NULL;

@@ -207,8 +207,8 @@ static void nbd_parse_filename(const char *filename, QDict *options,
        }

        qdict_put(options, "server.type", qstring_from_str("inet"));
        qdict_put(options, "server.data.host", qstring_from_str(addr->host));
        qdict_put(options, "server.data.port", qstring_from_str(addr->port));
        qdict_put(options, "server.host", qstring_from_str(addr->host));
        qdict_put(options, "server.port", qstring_from_str(addr->port));
        qapi_free_InetSocketAddress(addr);
    }

@@ -248,20 +248,21 @@ static bool nbd_process_legacy_socket_options(QDict *output_options,
        }

        qdict_put(output_options, "server.type", qstring_from_str("unix"));
        qdict_put(output_options, "server.data.path", qstring_from_str(path));
        qdict_put(output_options, "server.path", qstring_from_str(path));
    } else if (host) {
        qdict_put(output_options, "server.type", qstring_from_str("inet"));
        qdict_put(output_options, "server.data.host", qstring_from_str(host));
        qdict_put(output_options, "server.data.port",
        qdict_put(output_options, "server.host", qstring_from_str(host));
        qdict_put(output_options, "server.port",
                  qstring_from_str(port ?: stringify(NBD_DEFAULT_PORT)));
    }

    return true;
}

static SocketAddress *nbd_config(BDRVNBDState *s, QDict *options, Error **errp)
static SocketAddressFlat *nbd_config(BDRVNBDState *s, QDict *options,
                                     Error **errp)
{
    SocketAddress *saddr = NULL;
    SocketAddressFlat *saddr = NULL;
    QDict *addr = NULL;
    QObject *crumpled_addr = NULL;
    Visitor *iv = NULL;
@@ -278,8 +279,16 @@ static SocketAddress *nbd_config(BDRVNBDState *s, QDict *options, Error **errp)
        goto done;
    }

    /*
     * FIXME .numeric, .to, .ipv4 or .ipv6 don't work with -drive
     * server.type=inet.  .to doesn't matter, it's ignored anyway.
     * That's because when @options come from -blockdev or
     * blockdev_add, members are typed according to the QAPI schema,
     * but when they come from -drive, they're all QString.  The
     * visitor expects the former.
     */
    iv = qobject_input_visitor_new(crumpled_addr);
    visit_type_SocketAddress(iv, NULL, &saddr, &local_err);
    visit_type_SocketAddressFlat(iv, NULL, &saddr, &local_err);
    if (local_err) {
        error_propagate(errp, local_err);
        goto done;
@@ -298,9 +307,10 @@ NBDClientSession *nbd_get_client_session(BlockDriverState *bs)
    return &s->client;
}

static QIOChannelSocket *nbd_establish_connection(SocketAddress *saddr,
static QIOChannelSocket *nbd_establish_connection(SocketAddressFlat *saddr_flat,
                                                  Error **errp)
{
    SocketAddress *saddr = socket_address_crumple(saddr_flat);
    QIOChannelSocket *sioc;
    Error *local_err = NULL;

@@ -310,6 +320,7 @@ static QIOChannelSocket *nbd_establish_connection(SocketAddress *saddr,
    qio_channel_socket_connect_sync(sioc,
                                    saddr,
                                    &local_err);
    qapi_free_SocketAddress(saddr);
    if (local_err) {
        error_propagate(errp, local_err);
        return NULL;
@@ -401,7 +412,7 @@ static int nbd_open(BlockDriverState *bs, QDict *options, int flags,
        goto error;
    }

    /* Translate @host, @port, and @path to a SocketAddress */
    /* Translate @host, @port, and @path to a SocketAddressFlat */
    if (!nbd_process_legacy_socket_options(options, opts, errp)) {
        goto error;
    }
@@ -421,11 +432,12 @@ static int nbd_open(BlockDriverState *bs, QDict *options, int flags,
            goto error;
        }

        if (s->saddr->type != SOCKET_ADDRESS_KIND_INET) {
        /* TODO SOCKET_ADDRESS_KIND_FD where fd has AF_INET or AF_INET6 */
        if (s->saddr->type != SOCKET_ADDRESS_FLAT_TYPE_INET) {
            error_setg(errp, "TLS only supported over IP sockets");
            goto error;
        }
        hostname = s->saddr->u.inet.data->host;
        hostname = s->saddr->u.inet.host;
    }

    /* establish TCP connection, return error if it fails
@@ -448,7 +460,7 @@ static int nbd_open(BlockDriverState *bs, QDict *options, int flags,
        object_unref(OBJECT(tlscreds));
    }
    if (ret < 0) {
        qapi_free_SocketAddress(s->saddr);
        qapi_free_SocketAddressFlat(s->saddr);
        g_free(s->export);
        g_free(s->tlscredsid);
    }
@@ -474,7 +486,7 @@ static void nbd_close(BlockDriverState *bs)

    nbd_client_close(bs);

    qapi_free_SocketAddress(s->saddr);
    qapi_free_SocketAddressFlat(s->saddr);
    g_free(s->export);
    g_free(s->tlscredsid);
}
@@ -505,15 +517,15 @@ static void nbd_refresh_filename(BlockDriverState *bs, QDict *options)
    Visitor *ov;
    const char *host = NULL, *port = NULL, *path = NULL;

    if (s->saddr->type == SOCKET_ADDRESS_KIND_INET) {
        const InetSocketAddress *inet = s->saddr->u.inet.data;
    if (s->saddr->type == SOCKET_ADDRESS_FLAT_TYPE_INET) {
        const InetSocketAddress *inet = &s->saddr->u.inet;
        if (!inet->has_ipv4 && !inet->has_ipv6 && !inet->has_to) {
            host = inet->host;
            port = inet->port;
        }
    } else if (s->saddr->type == SOCKET_ADDRESS_KIND_UNIX) {
        path = s->saddr->u.q_unix.data->path;
    }
    } else if (s->saddr->type == SOCKET_ADDRESS_FLAT_TYPE_UNIX) {
        path = s->saddr->u.q_unix.path;
    } /* else can't represent as pseudo-filename */

    qdict_put(opts, "driver", qstring_from_str("nbd"));

@@ -532,7 +544,7 @@ static void nbd_refresh_filename(BlockDriverState *bs, QDict *options)
    }

    ov = qobject_output_visitor_new(&saddr_qdict);
    visit_type_SocketAddress(ov, NULL, &s->saddr, &error_abort);
    visit_type_SocketAddressFlat(ov, NULL, &s->saddr, &error_abort);
    visit_complete(ov, &saddr_qdict);
    visit_free(ov);
    qdict_put_obj(opts, "server", saddr_qdict);
+7 −0
Original line number Diff line number Diff line
@@ -474,6 +474,13 @@ static NFSServer *nfs_config(QDict *options, Error **errp)
        goto out;
    }

    /*
     * Caution: this works only because all scalar members of
     * NFSServer are QString in @crumpled_addr.  The visitor expects
     * @crumpled_addr to be typed according to the QAPI schema.  It
     * is when @options come from -blockdev or blockdev_add.  But when
     * they come from -drive, they're all QString.
     */
    iv = qobject_input_visitor_new(crumpled_addr);
    visit_type_NFSServer(iv, NULL, &server, &local_error);
    if (local_error) {
Loading