Loading block/sheepdog.c +169 −74 Original line number Diff line number Diff line Loading @@ -15,8 +15,10 @@ #include "qemu/osdep.h" #include "qapi/error.h" #include "qapi/qapi-visit-sockets.h" #include "qapi/qapi-visit-block-core.h" #include "qapi/qmp/qdict.h" #include "qapi/qobject-input-visitor.h" #include "qapi/qobject-output-visitor.h" #include "qemu/uri.h" #include "qemu/error-report.h" #include "qemu/option.h" Loading Loading @@ -533,23 +535,6 @@ static void sd_aio_setup(SheepdogAIOCB *acb, BDRVSheepdogState *s, qemu_co_mutex_unlock(&s->queue_lock); } static SocketAddress *sd_socket_address(const char *path, const char *host, const char *port) { SocketAddress *addr = g_new0(SocketAddress, 1); if (path) { addr->type = SOCKET_ADDRESS_TYPE_UNIX; addr->u.q_unix.path = g_strdup(path); } else { addr->type = SOCKET_ADDRESS_TYPE_INET; addr->u.inet.host = g_strdup(host ?: SD_DEFAULT_ADDR); addr->u.inet.port = g_strdup(port ?: stringify(SD_DEFAULT_PORT)); } return addr; } static SocketAddress *sd_server_config(QDict *options, Error **errp) { QDict *server = NULL; Loading Loading @@ -1882,6 +1867,44 @@ out_with_err_set: return ret; } static int sd_create_prealloc(BlockdevOptionsSheepdog *location, int64_t size, Error **errp) { BlockDriverState *bs; Visitor *v; QObject *obj = NULL; QDict *qdict; Error *local_err = NULL; int ret; v = qobject_output_visitor_new(&obj); visit_type_BlockdevOptionsSheepdog(v, NULL, &location, &local_err); visit_free(v); if (local_err) { error_propagate(errp, local_err); qobject_decref(obj); return -EINVAL; } qdict = qobject_to_qdict(obj); qdict_flatten(qdict); qdict_put_str(qdict, "driver", "sheepdog"); bs = bdrv_open(NULL, NULL, qdict, BDRV_O_PROTOCOL | BDRV_O_RDWR, errp); if (bs == NULL) { ret = -EIO; goto fail; } ret = sd_prealloc(bs, 0, size, errp); fail: bdrv_unref(bs); QDECREF(qdict); return ret; } static int parse_redundancy(BDRVSheepdogState *s, SheepdogRedundancy *opt) { struct SheepdogInode *inode = &s->inode; Loading Loading @@ -1934,9 +1957,9 @@ static int parse_redundancy(BDRVSheepdogState *s, SheepdogRedundancy *opt) * # create a erasure coded vdi with x data strips and y parity strips * -o redundancy=x:y (x must be one of {2,4,8,16} and 1 <= y < SD_EC_MAX_STRIP) */ static int parse_redundancy_str(BDRVSheepdogState *s, const char *opt) static SheepdogRedundancy *parse_redundancy_str(const char *opt) { struct SheepdogRedundancy redundancy; SheepdogRedundancy *redundancy; const char *n1, *n2; long copy, parity; char p[10]; Loading @@ -1947,26 +1970,27 @@ static int parse_redundancy_str(BDRVSheepdogState *s, const char *opt) n2 = strtok(NULL, ":"); if (!n1) { return -EINVAL; return NULL; } ret = qemu_strtol(n1, NULL, 10, ©); if (ret < 0) { return ret; return NULL; } redundancy = g_new0(SheepdogRedundancy, 1); if (!n2) { redundancy = (SheepdogRedundancy) { *redundancy = (SheepdogRedundancy) { .type = SHEEPDOG_REDUNDANCY_TYPE_FULL, .u.full.copies = copy, }; } else { ret = qemu_strtol(n2, NULL, 10, &parity); if (ret < 0) { return ret; return NULL; } redundancy = (SheepdogRedundancy) { *redundancy = (SheepdogRedundancy) { .type = SHEEPDOG_REDUNDANCY_TYPE_ERASURE_CODED, .u.erasure_coded = { .data_strips = copy, Loading @@ -1975,17 +1999,19 @@ static int parse_redundancy_str(BDRVSheepdogState *s, const char *opt) }; } return parse_redundancy(s, &redundancy); return redundancy; } static int parse_block_size_shift(BDRVSheepdogState *s, QemuOpts *opt) static int parse_block_size_shift(BDRVSheepdogState *s, BlockdevCreateOptionsSheepdog *opts) { struct SheepdogInode *inode = &s->inode; uint64_t object_size; int obj_order; object_size = qemu_opt_get_size_del(opt, BLOCK_OPT_OBJECT_SIZE, 0); if (object_size) { if (opts->has_object_size) { object_size = opts->object_size; if ((object_size - 1) & object_size) { /* not a power of 2? */ return -EINVAL; } Loading @@ -1999,57 +2025,55 @@ static int parse_block_size_shift(BDRVSheepdogState *s, QemuOpts *opt) return 0; } static int coroutine_fn sd_co_create_opts(const char *filename, QemuOpts *opts, Error **errp) static int sd_co_create(BlockdevCreateOptions *options, Error **errp) { Error *err = NULL; BlockdevCreateOptionsSheepdog *opts = &options->u.sheepdog; int ret = 0; uint32_t vid = 0; char *backing_file = NULL; char *buf = NULL; BDRVSheepdogState *s; SheepdogConfig cfg; uint64_t max_vdi_size; bool prealloc = false; assert(options->driver == BLOCKDEV_DRIVER_SHEEPDOG); s = g_new0(BDRVSheepdogState, 1); if (strstr(filename, "://")) { sd_parse_uri(&cfg, filename, &err); } else { parse_vdiname(&cfg, filename, &err); } if (err) { error_propagate(errp, err); /* Steal SocketAddress from QAPI, set NULL to prevent double free */ s->addr = opts->location->server; opts->location->server = NULL; if (strlen(opts->location->vdi) >= sizeof(s->name)) { error_setg(errp, "'vdi' string too long"); ret = -EINVAL; goto out; } pstrcpy(s->name, sizeof(s->name), opts->location->vdi); buf = cfg.port ? g_strdup_printf("%d", cfg.port) : NULL; s->addr = sd_socket_address(cfg.path, cfg.host, buf); g_free(buf); strcpy(s->name, cfg.vdi); sd_config_done(&cfg); s->inode.vdi_size = opts->size; backing_file = opts->backing_file; s->inode.vdi_size = ROUND_UP(qemu_opt_get_size_del(opts, BLOCK_OPT_SIZE, 0), BDRV_SECTOR_SIZE); backing_file = qemu_opt_get_del(opts, BLOCK_OPT_BACKING_FILE); buf = qemu_opt_get_del(opts, BLOCK_OPT_PREALLOC); if (!buf || !strcmp(buf, "off")) { if (!opts->has_preallocation) { opts->preallocation = PREALLOC_MODE_OFF; } switch (opts->preallocation) { case PREALLOC_MODE_OFF: prealloc = false; } else if (!strcmp(buf, "full")) { break; case PREALLOC_MODE_FULL: prealloc = true; } else { error_setg(errp, "Invalid preallocation mode: '%s'", buf); break; default: error_setg(errp, "Preallocation mode not supported for Sheepdog"); ret = -EINVAL; goto out; } g_free(buf); buf = qemu_opt_get_del(opts, BLOCK_OPT_REDUNDANCY); if (buf) { ret = parse_redundancy_str(s, buf); if (opts->has_redundancy) { ret = parse_redundancy(s, opts->redundancy); if (ret < 0) { error_setg(errp, "Invalid redundancy mode: '%s'", buf); error_setg(errp, "Invalid redundancy mode"); goto out; } } Loading @@ -2061,20 +2085,20 @@ static int coroutine_fn sd_co_create_opts(const char *filename, QemuOpts *opts, goto out; } if (backing_file) { if (opts->has_backing_file) { BlockBackend *blk; BDRVSheepdogState *base; BlockDriver *drv; /* Currently, only Sheepdog backing image is supported. */ drv = bdrv_find_protocol(backing_file, true, NULL); drv = bdrv_find_protocol(opts->backing_file, true, NULL); if (!drv || strcmp(drv->protocol_name, "sheepdog") != 0) { error_setg(errp, "backing_file must be a sheepdog image"); ret = -EINVAL; goto out; } blk = blk_new_open(backing_file, NULL, NULL, blk = blk_new_open(opts->backing_file, NULL, NULL, BDRV_O_PROTOCOL, errp); if (blk == NULL) { ret = -EIO; Loading Loading @@ -2142,28 +2166,96 @@ static int coroutine_fn sd_co_create_opts(const char *filename, QemuOpts *opts, } if (prealloc) { BlockDriverState *bs; QDict *opts; opts = qdict_new(); qdict_put_str(opts, "driver", "sheepdog"); bs = bdrv_open(filename, NULL, opts, BDRV_O_PROTOCOL | BDRV_O_RDWR, errp); if (!bs) { goto out; } ret = sd_prealloc(bs, 0, s->inode.vdi_size, errp); bdrv_unref(bs); ret = sd_create_prealloc(opts->location, opts->size, errp); } out: g_free(backing_file); g_free(buf); g_free(s->addr); g_free(s); return ret; } static int coroutine_fn sd_co_create_opts(const char *filename, QemuOpts *opts, Error **errp) { BlockdevCreateOptions *create_options = NULL; QDict *qdict, *location_qdict; QObject *crumpled; Visitor *v; const char *redundancy; Error *local_err = NULL; int ret; redundancy = qemu_opt_get_del(opts, BLOCK_OPT_REDUNDANCY); qdict = qemu_opts_to_qdict(opts, NULL); qdict_put_str(qdict, "driver", "sheepdog"); location_qdict = qdict_new(); qdict_put(qdict, "location", location_qdict); sd_parse_filename(filename, location_qdict, &local_err); if (local_err) { error_propagate(errp, local_err); ret = -EINVAL; goto fail; } qdict_flatten(qdict); /* Change legacy command line options into QMP ones */ static const QDictRenames opt_renames[] = { { BLOCK_OPT_BACKING_FILE, "backing-file" }, { BLOCK_OPT_OBJECT_SIZE, "object-size" }, { NULL, NULL }, }; if (!qdict_rename_keys(qdict, opt_renames, errp)) { ret = -EINVAL; goto fail; } /* Get the QAPI object */ crumpled = qdict_crumple(qdict, errp); if (crumpled == NULL) { ret = -EINVAL; goto fail; } v = qobject_input_visitor_new_keyval(crumpled); visit_type_BlockdevCreateOptions(v, NULL, &create_options, &local_err); visit_free(v); qobject_decref(crumpled); if (local_err) { error_propagate(errp, local_err); ret = -EINVAL; goto fail; } assert(create_options->driver == BLOCKDEV_DRIVER_SHEEPDOG); create_options->u.sheepdog.size = ROUND_UP(create_options->u.sheepdog.size, BDRV_SECTOR_SIZE); if (redundancy) { create_options->u.sheepdog.has_redundancy = true; create_options->u.sheepdog.redundancy = parse_redundancy_str(redundancy); if (create_options->u.sheepdog.redundancy == NULL) { error_setg(errp, "Invalid redundancy mode"); ret = -EINVAL; goto fail; } } ret = sd_co_create(create_options, errp); fail: qapi_free_BlockdevCreateOptions(create_options); QDECREF(qdict); return ret; } static void sd_close(BlockDriverState *bs) { Error *local_err = NULL; Loading Loading @@ -3143,6 +3235,7 @@ static BlockDriver bdrv_sheepdog = { .bdrv_reopen_commit = sd_reopen_commit, .bdrv_reopen_abort = sd_reopen_abort, .bdrv_close = sd_close, .bdrv_co_create = sd_co_create, .bdrv_co_create_opts = sd_co_create_opts, .bdrv_has_zero_init = bdrv_has_zero_init_1, .bdrv_getlength = sd_getlength, Loading Loading @@ -3179,6 +3272,7 @@ static BlockDriver bdrv_sheepdog_tcp = { .bdrv_reopen_commit = sd_reopen_commit, .bdrv_reopen_abort = sd_reopen_abort, .bdrv_close = sd_close, .bdrv_co_create = sd_co_create, .bdrv_co_create_opts = sd_co_create_opts, .bdrv_has_zero_init = bdrv_has_zero_init_1, .bdrv_getlength = sd_getlength, Loading Loading @@ -3215,6 +3309,7 @@ static BlockDriver bdrv_sheepdog_unix = { .bdrv_reopen_commit = sd_reopen_commit, .bdrv_reopen_abort = sd_reopen_abort, .bdrv_close = sd_close, .bdrv_co_create = sd_co_create, .bdrv_co_create_opts = sd_co_create_opts, .bdrv_has_zero_init = bdrv_has_zero_init_1, .bdrv_getlength = sd_getlength, Loading qapi/block-core.json +23 −1 Original line number Diff line number Diff line Loading @@ -3511,6 +3511,28 @@ 'data': { 'full': 'SheepdogRedundancyFull', 'erasure-coded': 'SheepdogRedundancyErasureCoded' } } ## # @BlockdevCreateOptionsSheepdog: # # Driver specific image creation options for Sheepdog. # # @location Where to store the new image file # @size Size of the virtual disk in bytes # @backing-file File name of a base image # @preallocation Preallocation mode (allowed values: off, full) # @redundancy Redundancy of the image # @object-size Object size of the image # # Since: 2.12 ## { 'struct': 'BlockdevCreateOptionsSheepdog', 'data': { 'location': 'BlockdevOptionsSheepdog', 'size': 'size', '*backing-file': 'str', '*preallocation': 'PreallocMode', '*redundancy': 'SheepdogRedundancy', '*object-size': 'size' } } ## # @BlockdevCreateNotSupported: # Loading Loading @@ -3562,7 +3584,7 @@ 'raw': 'BlockdevCreateNotSupported', 'rbd': 'BlockdevCreateOptionsRbd', 'replication': 'BlockdevCreateNotSupported', 'sheepdog': 'BlockdevCreateNotSupported', 'sheepdog': 'BlockdevCreateOptionsSheepdog', 'ssh': 'BlockdevCreateNotSupported', 'throttle': 'BlockdevCreateNotSupported', 'vdi': 'BlockdevCreateNotSupported', Loading Loading
block/sheepdog.c +169 −74 Original line number Diff line number Diff line Loading @@ -15,8 +15,10 @@ #include "qemu/osdep.h" #include "qapi/error.h" #include "qapi/qapi-visit-sockets.h" #include "qapi/qapi-visit-block-core.h" #include "qapi/qmp/qdict.h" #include "qapi/qobject-input-visitor.h" #include "qapi/qobject-output-visitor.h" #include "qemu/uri.h" #include "qemu/error-report.h" #include "qemu/option.h" Loading Loading @@ -533,23 +535,6 @@ static void sd_aio_setup(SheepdogAIOCB *acb, BDRVSheepdogState *s, qemu_co_mutex_unlock(&s->queue_lock); } static SocketAddress *sd_socket_address(const char *path, const char *host, const char *port) { SocketAddress *addr = g_new0(SocketAddress, 1); if (path) { addr->type = SOCKET_ADDRESS_TYPE_UNIX; addr->u.q_unix.path = g_strdup(path); } else { addr->type = SOCKET_ADDRESS_TYPE_INET; addr->u.inet.host = g_strdup(host ?: SD_DEFAULT_ADDR); addr->u.inet.port = g_strdup(port ?: stringify(SD_DEFAULT_PORT)); } return addr; } static SocketAddress *sd_server_config(QDict *options, Error **errp) { QDict *server = NULL; Loading Loading @@ -1882,6 +1867,44 @@ out_with_err_set: return ret; } static int sd_create_prealloc(BlockdevOptionsSheepdog *location, int64_t size, Error **errp) { BlockDriverState *bs; Visitor *v; QObject *obj = NULL; QDict *qdict; Error *local_err = NULL; int ret; v = qobject_output_visitor_new(&obj); visit_type_BlockdevOptionsSheepdog(v, NULL, &location, &local_err); visit_free(v); if (local_err) { error_propagate(errp, local_err); qobject_decref(obj); return -EINVAL; } qdict = qobject_to_qdict(obj); qdict_flatten(qdict); qdict_put_str(qdict, "driver", "sheepdog"); bs = bdrv_open(NULL, NULL, qdict, BDRV_O_PROTOCOL | BDRV_O_RDWR, errp); if (bs == NULL) { ret = -EIO; goto fail; } ret = sd_prealloc(bs, 0, size, errp); fail: bdrv_unref(bs); QDECREF(qdict); return ret; } static int parse_redundancy(BDRVSheepdogState *s, SheepdogRedundancy *opt) { struct SheepdogInode *inode = &s->inode; Loading Loading @@ -1934,9 +1957,9 @@ static int parse_redundancy(BDRVSheepdogState *s, SheepdogRedundancy *opt) * # create a erasure coded vdi with x data strips and y parity strips * -o redundancy=x:y (x must be one of {2,4,8,16} and 1 <= y < SD_EC_MAX_STRIP) */ static int parse_redundancy_str(BDRVSheepdogState *s, const char *opt) static SheepdogRedundancy *parse_redundancy_str(const char *opt) { struct SheepdogRedundancy redundancy; SheepdogRedundancy *redundancy; const char *n1, *n2; long copy, parity; char p[10]; Loading @@ -1947,26 +1970,27 @@ static int parse_redundancy_str(BDRVSheepdogState *s, const char *opt) n2 = strtok(NULL, ":"); if (!n1) { return -EINVAL; return NULL; } ret = qemu_strtol(n1, NULL, 10, ©); if (ret < 0) { return ret; return NULL; } redundancy = g_new0(SheepdogRedundancy, 1); if (!n2) { redundancy = (SheepdogRedundancy) { *redundancy = (SheepdogRedundancy) { .type = SHEEPDOG_REDUNDANCY_TYPE_FULL, .u.full.copies = copy, }; } else { ret = qemu_strtol(n2, NULL, 10, &parity); if (ret < 0) { return ret; return NULL; } redundancy = (SheepdogRedundancy) { *redundancy = (SheepdogRedundancy) { .type = SHEEPDOG_REDUNDANCY_TYPE_ERASURE_CODED, .u.erasure_coded = { .data_strips = copy, Loading @@ -1975,17 +1999,19 @@ static int parse_redundancy_str(BDRVSheepdogState *s, const char *opt) }; } return parse_redundancy(s, &redundancy); return redundancy; } static int parse_block_size_shift(BDRVSheepdogState *s, QemuOpts *opt) static int parse_block_size_shift(BDRVSheepdogState *s, BlockdevCreateOptionsSheepdog *opts) { struct SheepdogInode *inode = &s->inode; uint64_t object_size; int obj_order; object_size = qemu_opt_get_size_del(opt, BLOCK_OPT_OBJECT_SIZE, 0); if (object_size) { if (opts->has_object_size) { object_size = opts->object_size; if ((object_size - 1) & object_size) { /* not a power of 2? */ return -EINVAL; } Loading @@ -1999,57 +2025,55 @@ static int parse_block_size_shift(BDRVSheepdogState *s, QemuOpts *opt) return 0; } static int coroutine_fn sd_co_create_opts(const char *filename, QemuOpts *opts, Error **errp) static int sd_co_create(BlockdevCreateOptions *options, Error **errp) { Error *err = NULL; BlockdevCreateOptionsSheepdog *opts = &options->u.sheepdog; int ret = 0; uint32_t vid = 0; char *backing_file = NULL; char *buf = NULL; BDRVSheepdogState *s; SheepdogConfig cfg; uint64_t max_vdi_size; bool prealloc = false; assert(options->driver == BLOCKDEV_DRIVER_SHEEPDOG); s = g_new0(BDRVSheepdogState, 1); if (strstr(filename, "://")) { sd_parse_uri(&cfg, filename, &err); } else { parse_vdiname(&cfg, filename, &err); } if (err) { error_propagate(errp, err); /* Steal SocketAddress from QAPI, set NULL to prevent double free */ s->addr = opts->location->server; opts->location->server = NULL; if (strlen(opts->location->vdi) >= sizeof(s->name)) { error_setg(errp, "'vdi' string too long"); ret = -EINVAL; goto out; } pstrcpy(s->name, sizeof(s->name), opts->location->vdi); buf = cfg.port ? g_strdup_printf("%d", cfg.port) : NULL; s->addr = sd_socket_address(cfg.path, cfg.host, buf); g_free(buf); strcpy(s->name, cfg.vdi); sd_config_done(&cfg); s->inode.vdi_size = opts->size; backing_file = opts->backing_file; s->inode.vdi_size = ROUND_UP(qemu_opt_get_size_del(opts, BLOCK_OPT_SIZE, 0), BDRV_SECTOR_SIZE); backing_file = qemu_opt_get_del(opts, BLOCK_OPT_BACKING_FILE); buf = qemu_opt_get_del(opts, BLOCK_OPT_PREALLOC); if (!buf || !strcmp(buf, "off")) { if (!opts->has_preallocation) { opts->preallocation = PREALLOC_MODE_OFF; } switch (opts->preallocation) { case PREALLOC_MODE_OFF: prealloc = false; } else if (!strcmp(buf, "full")) { break; case PREALLOC_MODE_FULL: prealloc = true; } else { error_setg(errp, "Invalid preallocation mode: '%s'", buf); break; default: error_setg(errp, "Preallocation mode not supported for Sheepdog"); ret = -EINVAL; goto out; } g_free(buf); buf = qemu_opt_get_del(opts, BLOCK_OPT_REDUNDANCY); if (buf) { ret = parse_redundancy_str(s, buf); if (opts->has_redundancy) { ret = parse_redundancy(s, opts->redundancy); if (ret < 0) { error_setg(errp, "Invalid redundancy mode: '%s'", buf); error_setg(errp, "Invalid redundancy mode"); goto out; } } Loading @@ -2061,20 +2085,20 @@ static int coroutine_fn sd_co_create_opts(const char *filename, QemuOpts *opts, goto out; } if (backing_file) { if (opts->has_backing_file) { BlockBackend *blk; BDRVSheepdogState *base; BlockDriver *drv; /* Currently, only Sheepdog backing image is supported. */ drv = bdrv_find_protocol(backing_file, true, NULL); drv = bdrv_find_protocol(opts->backing_file, true, NULL); if (!drv || strcmp(drv->protocol_name, "sheepdog") != 0) { error_setg(errp, "backing_file must be a sheepdog image"); ret = -EINVAL; goto out; } blk = blk_new_open(backing_file, NULL, NULL, blk = blk_new_open(opts->backing_file, NULL, NULL, BDRV_O_PROTOCOL, errp); if (blk == NULL) { ret = -EIO; Loading Loading @@ -2142,28 +2166,96 @@ static int coroutine_fn sd_co_create_opts(const char *filename, QemuOpts *opts, } if (prealloc) { BlockDriverState *bs; QDict *opts; opts = qdict_new(); qdict_put_str(opts, "driver", "sheepdog"); bs = bdrv_open(filename, NULL, opts, BDRV_O_PROTOCOL | BDRV_O_RDWR, errp); if (!bs) { goto out; } ret = sd_prealloc(bs, 0, s->inode.vdi_size, errp); bdrv_unref(bs); ret = sd_create_prealloc(opts->location, opts->size, errp); } out: g_free(backing_file); g_free(buf); g_free(s->addr); g_free(s); return ret; } static int coroutine_fn sd_co_create_opts(const char *filename, QemuOpts *opts, Error **errp) { BlockdevCreateOptions *create_options = NULL; QDict *qdict, *location_qdict; QObject *crumpled; Visitor *v; const char *redundancy; Error *local_err = NULL; int ret; redundancy = qemu_opt_get_del(opts, BLOCK_OPT_REDUNDANCY); qdict = qemu_opts_to_qdict(opts, NULL); qdict_put_str(qdict, "driver", "sheepdog"); location_qdict = qdict_new(); qdict_put(qdict, "location", location_qdict); sd_parse_filename(filename, location_qdict, &local_err); if (local_err) { error_propagate(errp, local_err); ret = -EINVAL; goto fail; } qdict_flatten(qdict); /* Change legacy command line options into QMP ones */ static const QDictRenames opt_renames[] = { { BLOCK_OPT_BACKING_FILE, "backing-file" }, { BLOCK_OPT_OBJECT_SIZE, "object-size" }, { NULL, NULL }, }; if (!qdict_rename_keys(qdict, opt_renames, errp)) { ret = -EINVAL; goto fail; } /* Get the QAPI object */ crumpled = qdict_crumple(qdict, errp); if (crumpled == NULL) { ret = -EINVAL; goto fail; } v = qobject_input_visitor_new_keyval(crumpled); visit_type_BlockdevCreateOptions(v, NULL, &create_options, &local_err); visit_free(v); qobject_decref(crumpled); if (local_err) { error_propagate(errp, local_err); ret = -EINVAL; goto fail; } assert(create_options->driver == BLOCKDEV_DRIVER_SHEEPDOG); create_options->u.sheepdog.size = ROUND_UP(create_options->u.sheepdog.size, BDRV_SECTOR_SIZE); if (redundancy) { create_options->u.sheepdog.has_redundancy = true; create_options->u.sheepdog.redundancy = parse_redundancy_str(redundancy); if (create_options->u.sheepdog.redundancy == NULL) { error_setg(errp, "Invalid redundancy mode"); ret = -EINVAL; goto fail; } } ret = sd_co_create(create_options, errp); fail: qapi_free_BlockdevCreateOptions(create_options); QDECREF(qdict); return ret; } static void sd_close(BlockDriverState *bs) { Error *local_err = NULL; Loading Loading @@ -3143,6 +3235,7 @@ static BlockDriver bdrv_sheepdog = { .bdrv_reopen_commit = sd_reopen_commit, .bdrv_reopen_abort = sd_reopen_abort, .bdrv_close = sd_close, .bdrv_co_create = sd_co_create, .bdrv_co_create_opts = sd_co_create_opts, .bdrv_has_zero_init = bdrv_has_zero_init_1, .bdrv_getlength = sd_getlength, Loading Loading @@ -3179,6 +3272,7 @@ static BlockDriver bdrv_sheepdog_tcp = { .bdrv_reopen_commit = sd_reopen_commit, .bdrv_reopen_abort = sd_reopen_abort, .bdrv_close = sd_close, .bdrv_co_create = sd_co_create, .bdrv_co_create_opts = sd_co_create_opts, .bdrv_has_zero_init = bdrv_has_zero_init_1, .bdrv_getlength = sd_getlength, Loading Loading @@ -3215,6 +3309,7 @@ static BlockDriver bdrv_sheepdog_unix = { .bdrv_reopen_commit = sd_reopen_commit, .bdrv_reopen_abort = sd_reopen_abort, .bdrv_close = sd_close, .bdrv_co_create = sd_co_create, .bdrv_co_create_opts = sd_co_create_opts, .bdrv_has_zero_init = bdrv_has_zero_init_1, .bdrv_getlength = sd_getlength, Loading
qapi/block-core.json +23 −1 Original line number Diff line number Diff line Loading @@ -3511,6 +3511,28 @@ 'data': { 'full': 'SheepdogRedundancyFull', 'erasure-coded': 'SheepdogRedundancyErasureCoded' } } ## # @BlockdevCreateOptionsSheepdog: # # Driver specific image creation options for Sheepdog. # # @location Where to store the new image file # @size Size of the virtual disk in bytes # @backing-file File name of a base image # @preallocation Preallocation mode (allowed values: off, full) # @redundancy Redundancy of the image # @object-size Object size of the image # # Since: 2.12 ## { 'struct': 'BlockdevCreateOptionsSheepdog', 'data': { 'location': 'BlockdevOptionsSheepdog', 'size': 'size', '*backing-file': 'str', '*preallocation': 'PreallocMode', '*redundancy': 'SheepdogRedundancy', '*object-size': 'size' } } ## # @BlockdevCreateNotSupported: # Loading Loading @@ -3562,7 +3584,7 @@ 'raw': 'BlockdevCreateNotSupported', 'rbd': 'BlockdevCreateOptionsRbd', 'replication': 'BlockdevCreateNotSupported', 'sheepdog': 'BlockdevCreateNotSupported', 'sheepdog': 'BlockdevCreateOptionsSheepdog', 'ssh': 'BlockdevCreateNotSupported', 'throttle': 'BlockdevCreateNotSupported', 'vdi': 'BlockdevCreateNotSupported', Loading