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

Merge remote-tracking branch 'remotes/cody/tags/block-pull-request' into staging



# gpg: Signature made Tue 01 Nov 2016 12:47:36 GMT
# gpg:                using RSA key 0xBDBE7B27C0DE3057
# gpg: Good signature from "Jeffrey Cody <jcody@redhat.com>"
# gpg:                 aka "Jeffrey Cody <jeff@codyprime.org>"
# gpg:                 aka "Jeffrey Cody <codyprime@gmail.com>"
# Primary key fingerprint: 9957 4B4D 3474 90E7 9D98  D624 BDBE 7B27 C0DE 3057

* remotes/cody/tags/block-pull-request:
  blockjobs: fix documentation
  blockjobs: split interface into public/private, Part 1
  Blockjobs: Internalize user_pause logic
  blockjob: centralize QMP event emissions
  Replication/Blockjobs: Create replication jobs as internal
  blockjobs: Allow creating internal jobs
  blockjobs: hide internal jobs from management API
  block/gluster: fix port type in the QAPI options list
  block/gluster: improve defense over string to int conversion
  block: Turn on "unmap" in active commit
  block/gluster: memory usage: use one glfs instance per volume
  block: add gluster ifdef guard checks for SEEK_DATA/SEEK_HOLE support
  rbd: make the code more readable
  qapi: add release designator to gluster logfile option

Signed-off-by: default avatarPeter Maydell <peter.maydell@linaro.org>
parents 39542105 d8996368
Loading
Loading
Loading
Loading
+3 −2
Original line number Diff line number Diff line
@@ -16,7 +16,7 @@
#include "trace.h"
#include "block/block.h"
#include "block/block_int.h"
#include "block/blockjob.h"
#include "block/blockjob_int.h"
#include "block/block_backup.h"
#include "qapi/error.h"
#include "qapi/qmp/qerror.h"
@@ -543,6 +543,7 @@ void backup_start(const char *job_id, BlockDriverState *bs,
                  bool compress,
                  BlockdevOnError on_source_error,
                  BlockdevOnError on_target_error,
                  int creation_flags,
                  BlockCompletionFunc *cb, void *opaque,
                  BlockJobTxn *txn, Error **errp)
{
@@ -612,7 +613,7 @@ void backup_start(const char *job_id, BlockDriverState *bs,
    }

    job = block_job_create(job_id, &backup_job_driver, bs, speed,
                           cb, opaque, errp);
                           creation_flags, cb, opaque, errp);
    if (!job) {
        goto error;
    }
+5 −5
Original line number Diff line number Diff line
@@ -15,7 +15,7 @@
#include "qemu/osdep.h"
#include "trace.h"
#include "block/block_int.h"
#include "block/blockjob.h"
#include "block/blockjob_int.h"
#include "qapi/error.h"
#include "qapi/qmp/qerror.h"
#include "qemu/ratelimit.h"
@@ -209,8 +209,8 @@ static const BlockJobDriver commit_job_driver = {

void commit_start(const char *job_id, BlockDriverState *bs,
                  BlockDriverState *base, BlockDriverState *top, int64_t speed,
                  BlockdevOnError on_error, BlockCompletionFunc *cb,
                  void *opaque, const char *backing_file_str, Error **errp)
                  BlockdevOnError on_error, const char *backing_file_str,
                  Error **errp)
{
    CommitBlockJob *s;
    BlockReopenQueue *reopen_queue = NULL;
@@ -234,7 +234,7 @@ void commit_start(const char *job_id, BlockDriverState *bs,
    }

    s = block_job_create(job_id, &commit_job_driver, bs, speed,
                         cb, opaque, errp);
                         BLOCK_JOB_DEFAULT, NULL, NULL, errp);
    if (!s) {
        return;
    }
@@ -290,7 +290,7 @@ void commit_start(const char *job_id, BlockDriverState *bs,
    s->on_error = on_error;
    s->common.co = qemu_coroutine_create(commit_run, s);

    trace_commit_start(bs, base, top, s, s->common.co, opaque);
    trace_commit_start(bs, base, top, s, s->common.co);
    qemu_coroutine_enter(s->common.co);
}

+105 −19
Original line number Diff line number Diff line
@@ -14,6 +14,7 @@
#include "qapi/qmp/qerror.h"
#include "qemu/uri.h"
#include "qemu/error-report.h"
#include "qemu/cutils.h"

#define GLUSTER_OPT_FILENAME        "filename"
#define GLUSTER_OPT_VOLUME          "volume"
@@ -56,6 +57,19 @@ typedef struct BDRVGlusterReopenState {
} BDRVGlusterReopenState;


typedef struct GlfsPreopened {
    char *volume;
    glfs_t *fs;
    int ref;
} GlfsPreopened;

typedef struct ListElement {
    QLIST_ENTRY(ListElement) list;
    GlfsPreopened saved;
} ListElement;

static QLIST_HEAD(glfs_list, ListElement) glfs_list;

static QemuOptsList qemu_gluster_create_opts = {
    .name = "qemu-gluster-create-opts",
    .head = QTAILQ_HEAD_INITIALIZER(qemu_gluster_create_opts.head),
@@ -172,7 +186,7 @@ static QemuOptsList runtime_tcp_opts = {
        },
        {
            .name = GLUSTER_OPT_PORT,
            .type = QEMU_OPT_NUMBER,
            .type = QEMU_OPT_STRING,
            .help = "port number on which glusterd is listening (default 24007)",
        },
        {
@@ -194,6 +208,57 @@ static QemuOptsList runtime_tcp_opts = {
    },
};

static void glfs_set_preopened(const char *volume, glfs_t *fs)
{
    ListElement *entry = NULL;

    entry = g_new(ListElement, 1);

    entry->saved.volume = g_strdup(volume);

    entry->saved.fs = fs;
    entry->saved.ref = 1;

    QLIST_INSERT_HEAD(&glfs_list, entry, list);
}

static glfs_t *glfs_find_preopened(const char *volume)
{
    ListElement *entry = NULL;

     QLIST_FOREACH(entry, &glfs_list, list) {
        if (strcmp(entry->saved.volume, volume) == 0) {
            entry->saved.ref++;
            return entry->saved.fs;
        }
     }

    return NULL;
}

static void glfs_clear_preopened(glfs_t *fs)
{
    ListElement *entry = NULL;

    if (fs == NULL) {
        return;
    }

    QLIST_FOREACH(entry, &glfs_list, list) {
        if (entry->saved.fs == fs) {
            if (--entry->saved.ref) {
                return;
            }

            QLIST_REMOVE(entry, list);

            glfs_fini(entry->saved.fs);
            g_free(entry->saved.volume);
            g_free(entry);
        }
    }
}

static int parse_volume_options(BlockdevOptionsGluster *gconf, char *path)
{
    char *p, *q;
@@ -330,22 +395,37 @@ static struct glfs *qemu_gluster_glfs_init(BlockdevOptionsGluster *gconf,
    int ret;
    int old_errno;
    GlusterServerList *server;
    unsigned long long port;

    glfs = glfs_find_preopened(gconf->volume);
    if (glfs) {
        return glfs;
    }

    glfs = glfs_new(gconf->volume);
    if (!glfs) {
        goto out;
    }

    glfs_set_preopened(gconf->volume, glfs);

    for (server = gconf->server; server; server = server->next) {
        if (server->value->type  == GLUSTER_TRANSPORT_UNIX) {
            ret = glfs_set_volfile_server(glfs,
                                   GlusterTransport_lookup[server->value->type],
                                   server->value->u.q_unix.path, 0);
        } else {
            if (parse_uint_full(server->value->u.tcp.port, &port, 10) < 0 ||
                port > 65535) {
                error_setg(errp, "'%s' is not a valid port number",
                           server->value->u.tcp.port);
                errno = EINVAL;
                goto out;
            }
            ret = glfs_set_volfile_server(glfs,
                                   GlusterTransport_lookup[server->value->type],
                                   server->value->u.tcp.host,
                                   atoi(server->value->u.tcp.port));
                                   (int)port);
        }

        if (ret < 0) {
@@ -387,7 +467,7 @@ static struct glfs *qemu_gluster_glfs_init(BlockdevOptionsGluster *gconf,
out:
    if (glfs) {
        old_errno = errno;
        glfs_fini(glfs);
        glfs_clear_preopened(glfs);
        errno = old_errno;
    }
    return NULL;
@@ -668,7 +748,10 @@ static void qemu_gluster_parse_flags(int bdrv_flags, int *open_flags)
 */
static bool qemu_gluster_test_seek(struct glfs_fd *fd)
{
    off_t ret, eof;
    off_t ret = 0;

#if defined SEEK_HOLE && defined SEEK_DATA
    off_t eof;

    eof = glfs_lseek(fd, 0, SEEK_END);
    if (eof < 0) {
@@ -678,6 +761,8 @@ static bool qemu_gluster_test_seek(struct glfs_fd *fd)

    /* this should always fail with ENXIO if SEEK_DATA is supported */
    ret = glfs_lseek(fd, eof, SEEK_DATA);
#endif

    return (ret < 0) && (errno == ENXIO);
}

@@ -762,9 +847,9 @@ out:
    if (s->fd) {
        glfs_close(s->fd);
    }
    if (s->glfs) {
        glfs_fini(s->glfs);
    }

    glfs_clear_preopened(s->glfs);

    return ret;
}

@@ -831,9 +916,8 @@ static void qemu_gluster_reopen_commit(BDRVReopenState *state)
    if (s->fd) {
        glfs_close(s->fd);
    }
    if (s->glfs) {
        glfs_fini(s->glfs);
    }

    glfs_clear_preopened(s->glfs);

    /* use the newly opened image / connection */
    s->fd         = reop_s->fd;
@@ -858,9 +942,7 @@ static void qemu_gluster_reopen_abort(BDRVReopenState *state)
        glfs_close(reop_s->fd);
    }

    if (reop_s->glfs) {
        glfs_fini(reop_s->glfs);
    }
    glfs_clear_preopened(reop_s->glfs);

    g_free(state->opaque);
    state->opaque = NULL;
@@ -984,9 +1066,7 @@ static int qemu_gluster_create(const char *filename,
out:
    g_free(tmp);
    qapi_free_BlockdevOptionsGluster(gconf);
    if (glfs) {
        glfs_fini(glfs);
    }
    glfs_clear_preopened(glfs);
    return ret;
}

@@ -1059,7 +1139,7 @@ static void qemu_gluster_close(BlockDriverState *bs)
        glfs_close(s->fd);
        s->fd = NULL;
    }
    glfs_fini(s->glfs);
    glfs_clear_preopened(s->glfs);
}

static coroutine_fn int qemu_gluster_co_flush_to_disk(BlockDriverState *bs)
@@ -1178,12 +1258,14 @@ static int find_allocation(BlockDriverState *bs, off_t start,
                           off_t *data, off_t *hole)
{
    BDRVGlusterState *s = bs->opaque;
    off_t offs;

    if (!s->supports_seek_data) {
        return -ENOTSUP;
        goto exit;
    }

#if defined SEEK_HOLE && defined SEEK_DATA
    off_t offs;

    /*
     * SEEK_DATA cases:
     * D1. offs == start: start is in data
@@ -1247,6 +1329,10 @@ static int find_allocation(BlockDriverState *bs, off_t start,

    /* D1 and H1 */
    return -EBUSY;
#endif

exit:
    return -ENOTSUP;
}

/*
+14 −16
Original line number Diff line number Diff line
@@ -13,7 +13,7 @@

#include "qemu/osdep.h"
#include "trace.h"
#include "block/blockjob.h"
#include "block/blockjob_int.h"
#include "block/block_int.h"
#include "sysemu/block-backend.h"
#include "qapi/error.h"
@@ -937,9 +937,9 @@ static const BlockJobDriver commit_active_job_driver = {
};

static void mirror_start_job(const char *job_id, BlockDriverState *bs,
                             BlockDriverState *target, const char *replaces,
                             int64_t speed, uint32_t granularity,
                             int64_t buf_size,
                             int creation_flags, BlockDriverState *target,
                             const char *replaces, int64_t speed,
                             uint32_t granularity, int64_t buf_size,
                             BlockMirrorBackingMode backing_mode,
                             BlockdevOnError on_source_error,
                             BlockdevOnError on_target_error,
@@ -967,7 +967,8 @@ static void mirror_start_job(const char *job_id, BlockDriverState *bs,
        buf_size = DEFAULT_MIRROR_BUF_SIZE;
    }

    s = block_job_create(job_id, driver, bs, speed, cb, opaque, errp);
    s = block_job_create(job_id, driver, bs, speed, creation_flags,
                         cb, opaque, errp);
    if (!s) {
        return;
    }
@@ -1017,9 +1018,7 @@ void mirror_start(const char *job_id, BlockDriverState *bs,
                  MirrorSyncMode mode, BlockMirrorBackingMode backing_mode,
                  BlockdevOnError on_source_error,
                  BlockdevOnError on_target_error,
                  bool unmap,
                  BlockCompletionFunc *cb,
                  void *opaque, Error **errp)
                  bool unmap, Error **errp)
{
    bool is_none_mode;
    BlockDriverState *base;
@@ -1030,17 +1029,16 @@ void mirror_start(const char *job_id, BlockDriverState *bs,
    }
    is_none_mode = mode == MIRROR_SYNC_MODE_NONE;
    base = mode == MIRROR_SYNC_MODE_TOP ? backing_bs(bs) : NULL;
    mirror_start_job(job_id, bs, target, replaces,
    mirror_start_job(job_id, bs, BLOCK_JOB_DEFAULT, target, replaces,
                     speed, granularity, buf_size, backing_mode,
                     on_source_error, on_target_error, unmap, cb, opaque, errp,
                     on_source_error, on_target_error, unmap, NULL, NULL, errp,
                     &mirror_job_driver, is_none_mode, base, false);
}

void commit_active_start(const char *job_id, BlockDriverState *bs,
                         BlockDriverState *base, int64_t speed,
                         BlockdevOnError on_error,
                         BlockCompletionFunc *cb,
                         void *opaque, Error **errp,
                         BlockDriverState *base, int creation_flags,
                         int64_t speed, BlockdevOnError on_error,
                         BlockCompletionFunc *cb, void *opaque, Error **errp,
                         bool auto_complete)
{
    int64_t length, base_length;
@@ -1079,9 +1077,9 @@ void commit_active_start(const char *job_id, BlockDriverState *bs,
        }
    }

    mirror_start_job(job_id, bs, base, NULL, speed, 0, 0,
    mirror_start_job(job_id, bs, creation_flags, base, NULL, speed, 0, 0,
                     MIRROR_LEAVE_BACKING_CHAIN,
                     on_error, on_error, false, cb, opaque, &local_err,
                     on_error, on_error, true, cb, opaque, &local_err,
                     &commit_active_job_driver, false, base, auto_complete);
    if (local_err) {
        error_propagate(errp, local_err);
+12 −13
Original line number Diff line number Diff line
@@ -365,45 +365,44 @@ static int qemu_rbd_create(const char *filename, QemuOpts *opts, Error **errp)
        rados_conf_read_file(cluster, NULL);
    } else if (conf[0] != '\0' &&
               qemu_rbd_set_conf(cluster, conf, true, &local_err) < 0) {
        rados_shutdown(cluster);
        error_propagate(errp, local_err);
        return -EIO;
        ret = -EIO;
        goto shutdown;
    }

    if (conf[0] != '\0' &&
        qemu_rbd_set_conf(cluster, conf, false, &local_err) < 0) {
        rados_shutdown(cluster);
        error_propagate(errp, local_err);
        return -EIO;
        ret = -EIO;
        goto shutdown;
    }

    if (qemu_rbd_set_auth(cluster, secretid, errp) < 0) {
        rados_shutdown(cluster);
        return -EIO;
        ret = -EIO;
        goto shutdown;
    }

    ret = rados_connect(cluster);
    if (ret < 0) {
        error_setg_errno(errp, -ret, "error connecting");
        rados_shutdown(cluster);
        return ret;
        goto shutdown;
    }

    ret = rados_ioctx_create(cluster, pool, &io_ctx);
    if (ret < 0) {
        error_setg_errno(errp, -ret, "error opening pool %s", pool);
        rados_shutdown(cluster);
        return ret;
        goto shutdown;
    }

    ret = rbd_create(io_ctx, name, bytes, &obj_order);
    rados_ioctx_destroy(io_ctx);
    rados_shutdown(cluster);
    if (ret < 0) {
        error_setg_errno(errp, -ret, "error rbd create");
        return ret;
    }

    rados_ioctx_destroy(io_ctx);

shutdown:
    rados_shutdown(cluster);
    return ret;
}

Loading