qed: Support .bdrv_co_create
This adds the .bdrv_co_create driver callback to qed, which enables image creation over QMP. Signed-off-by: Kevin Wolf <kwolf@redhat.com> Reviewed-by: Max Reitz <mreitz@redhat.com>
This commit is contained in:
		
							parent
							
								
									42a3e1ab36
								
							
						
					
					
						commit
						959355a476
					
				
							
								
								
									
										206
									
								
								block/qed.c
									
									
									
									
									
								
							
							
						
						
									
										206
									
								
								block/qed.c
									
									
									
									
									
								
							@ -20,6 +20,11 @@
 | 
				
			|||||||
#include "trace.h"
 | 
					#include "trace.h"
 | 
				
			||||||
#include "qed.h"
 | 
					#include "qed.h"
 | 
				
			||||||
#include "sysemu/block-backend.h"
 | 
					#include "sysemu/block-backend.h"
 | 
				
			||||||
 | 
					#include "qapi/qmp/qdict.h"
 | 
				
			||||||
 | 
					#include "qapi/qobject-input-visitor.h"
 | 
				
			||||||
 | 
					#include "qapi/qapi-visit-block-core.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static QemuOptsList qed_create_opts;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int bdrv_qed_probe(const uint8_t *buf, int buf_size,
 | 
					static int bdrv_qed_probe(const uint8_t *buf, int buf_size,
 | 
				
			||||||
                          const char *filename)
 | 
					                          const char *filename)
 | 
				
			||||||
@ -594,66 +599,104 @@ static void bdrv_qed_close(BlockDriverState *bs)
 | 
				
			|||||||
    qemu_vfree(s->l1_table);
 | 
					    qemu_vfree(s->l1_table);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int qed_create(const char *filename, uint32_t cluster_size,
 | 
					static int coroutine_fn bdrv_qed_co_create(BlockdevCreateOptions *opts,
 | 
				
			||||||
                      uint64_t image_size, uint32_t table_size,
 | 
					                                           Error **errp)
 | 
				
			||||||
                      const char *backing_file, const char *backing_fmt,
 | 
					 | 
				
			||||||
                      QemuOpts *opts, Error **errp)
 | 
					 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    QEDHeader header = {
 | 
					    BlockdevCreateOptionsQed *qed_opts;
 | 
				
			||||||
        .magic = QED_MAGIC,
 | 
					    BlockBackend *blk = NULL;
 | 
				
			||||||
        .cluster_size = cluster_size,
 | 
					    BlockDriverState *bs = NULL;
 | 
				
			||||||
        .table_size = table_size,
 | 
					
 | 
				
			||||||
        .header_size = 1,
 | 
					    QEDHeader header;
 | 
				
			||||||
        .features = 0,
 | 
					 | 
				
			||||||
        .compat_features = 0,
 | 
					 | 
				
			||||||
        .l1_table_offset = cluster_size,
 | 
					 | 
				
			||||||
        .image_size = image_size,
 | 
					 | 
				
			||||||
    };
 | 
					 | 
				
			||||||
    QEDHeader le_header;
 | 
					    QEDHeader le_header;
 | 
				
			||||||
    uint8_t *l1_table = NULL;
 | 
					    uint8_t *l1_table = NULL;
 | 
				
			||||||
    size_t l1_size = header.cluster_size * header.table_size;
 | 
					    size_t l1_size;
 | 
				
			||||||
    Error *local_err = NULL;
 | 
					 | 
				
			||||||
    int ret = 0;
 | 
					    int ret = 0;
 | 
				
			||||||
    BlockBackend *blk;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    ret = bdrv_create_file(filename, opts, &local_err);
 | 
					    assert(opts->driver == BLOCKDEV_DRIVER_QED);
 | 
				
			||||||
    if (ret < 0) {
 | 
					    qed_opts = &opts->u.qed;
 | 
				
			||||||
        error_propagate(errp, local_err);
 | 
					
 | 
				
			||||||
        return ret;
 | 
					    /* Validate options and set default values */
 | 
				
			||||||
 | 
					    if (!qed_opts->has_cluster_size) {
 | 
				
			||||||
 | 
					        qed_opts->cluster_size = QED_DEFAULT_CLUSTER_SIZE;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    if (!qed_opts->has_table_size) {
 | 
				
			||||||
 | 
					        qed_opts->table_size = QED_DEFAULT_TABLE_SIZE;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    blk = blk_new_open(filename, NULL, NULL,
 | 
					    if (!qed_is_cluster_size_valid(qed_opts->cluster_size)) {
 | 
				
			||||||
                       BDRV_O_RDWR | BDRV_O_RESIZE | BDRV_O_PROTOCOL,
 | 
					        error_setg(errp, "QED cluster size must be within range [%u, %u] "
 | 
				
			||||||
                       &local_err);
 | 
					                         "and power of 2",
 | 
				
			||||||
    if (blk == NULL) {
 | 
					                   QED_MIN_CLUSTER_SIZE, QED_MAX_CLUSTER_SIZE);
 | 
				
			||||||
        error_propagate(errp, local_err);
 | 
					        return -EINVAL;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    if (!qed_is_table_size_valid(qed_opts->table_size)) {
 | 
				
			||||||
 | 
					        error_setg(errp, "QED table size must be within range [%u, %u] "
 | 
				
			||||||
 | 
					                         "and power of 2",
 | 
				
			||||||
 | 
					                   QED_MIN_TABLE_SIZE, QED_MAX_TABLE_SIZE);
 | 
				
			||||||
 | 
					        return -EINVAL;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    if (!qed_is_image_size_valid(qed_opts->size, qed_opts->cluster_size,
 | 
				
			||||||
 | 
					                                 qed_opts->table_size))
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        error_setg(errp, "QED image size must be a non-zero multiple of "
 | 
				
			||||||
 | 
					                         "cluster size and less than %" PRIu64 " bytes",
 | 
				
			||||||
 | 
					                   qed_max_image_size(qed_opts->cluster_size,
 | 
				
			||||||
 | 
					                                      qed_opts->table_size));
 | 
				
			||||||
 | 
					        return -EINVAL;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /* Create BlockBackend to write to the image */
 | 
				
			||||||
 | 
					    bs = bdrv_open_blockdev_ref(qed_opts->file, errp);
 | 
				
			||||||
 | 
					    if (bs == NULL) {
 | 
				
			||||||
        return -EIO;
 | 
					        return -EIO;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    blk = blk_new(BLK_PERM_WRITE | BLK_PERM_RESIZE, BLK_PERM_ALL);
 | 
				
			||||||
 | 
					    ret = blk_insert_bs(blk, bs, errp);
 | 
				
			||||||
 | 
					    if (ret < 0) {
 | 
				
			||||||
 | 
					        goto out;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
    blk_set_allow_write_beyond_eof(blk, true);
 | 
					    blk_set_allow_write_beyond_eof(blk, true);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /* Prepare image format */
 | 
				
			||||||
 | 
					    header = (QEDHeader) {
 | 
				
			||||||
 | 
					        .magic = QED_MAGIC,
 | 
				
			||||||
 | 
					        .cluster_size = qed_opts->cluster_size,
 | 
				
			||||||
 | 
					        .table_size = qed_opts->table_size,
 | 
				
			||||||
 | 
					        .header_size = 1,
 | 
				
			||||||
 | 
					        .features = 0,
 | 
				
			||||||
 | 
					        .compat_features = 0,
 | 
				
			||||||
 | 
					        .l1_table_offset = qed_opts->cluster_size,
 | 
				
			||||||
 | 
					        .image_size = qed_opts->size,
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    l1_size = header.cluster_size * header.table_size;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /* File must start empty and grow, check truncate is supported */
 | 
					    /* File must start empty and grow, check truncate is supported */
 | 
				
			||||||
    ret = blk_truncate(blk, 0, PREALLOC_MODE_OFF, errp);
 | 
					    ret = blk_truncate(blk, 0, PREALLOC_MODE_OFF, errp);
 | 
				
			||||||
    if (ret < 0) {
 | 
					    if (ret < 0) {
 | 
				
			||||||
        goto out;
 | 
					        goto out;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (backing_file) {
 | 
					    if (qed_opts->has_backing_file) {
 | 
				
			||||||
        header.features |= QED_F_BACKING_FILE;
 | 
					        header.features |= QED_F_BACKING_FILE;
 | 
				
			||||||
        header.backing_filename_offset = sizeof(le_header);
 | 
					        header.backing_filename_offset = sizeof(le_header);
 | 
				
			||||||
        header.backing_filename_size = strlen(backing_file);
 | 
					        header.backing_filename_size = strlen(qed_opts->backing_file);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if (qed_opts->has_backing_fmt) {
 | 
				
			||||||
 | 
					            const char *backing_fmt = BlockdevDriver_str(qed_opts->backing_fmt);
 | 
				
			||||||
            if (qed_fmt_is_raw(backing_fmt)) {
 | 
					            if (qed_fmt_is_raw(backing_fmt)) {
 | 
				
			||||||
                header.features |= QED_F_BACKING_FORMAT_NO_PROBE;
 | 
					                header.features |= QED_F_BACKING_FORMAT_NO_PROBE;
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    qed_header_cpu_to_le(&header, &le_header);
 | 
					    qed_header_cpu_to_le(&header, &le_header);
 | 
				
			||||||
    ret = blk_pwrite(blk, 0, &le_header, sizeof(le_header), 0);
 | 
					    ret = blk_pwrite(blk, 0, &le_header, sizeof(le_header), 0);
 | 
				
			||||||
    if (ret < 0) {
 | 
					    if (ret < 0) {
 | 
				
			||||||
        goto out;
 | 
					        goto out;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    ret = blk_pwrite(blk, sizeof(le_header), backing_file,
 | 
					    ret = blk_pwrite(blk, sizeof(le_header), qed_opts->backing_file,
 | 
				
			||||||
                     header.backing_filename_size, 0);
 | 
					                     header.backing_filename_size, 0);
 | 
				
			||||||
    if (ret < 0) {
 | 
					    if (ret < 0) {
 | 
				
			||||||
        goto out;
 | 
					        goto out;
 | 
				
			||||||
@ -669,6 +712,7 @@ static int qed_create(const char *filename, uint32_t cluster_size,
 | 
				
			|||||||
out:
 | 
					out:
 | 
				
			||||||
    g_free(l1_table);
 | 
					    g_free(l1_table);
 | 
				
			||||||
    blk_unref(blk);
 | 
					    blk_unref(blk);
 | 
				
			||||||
 | 
					    bdrv_unref(bs);
 | 
				
			||||||
    return ret;
 | 
					    return ret;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -676,51 +720,78 @@ static int coroutine_fn bdrv_qed_co_create_opts(const char *filename,
 | 
				
			|||||||
                                                QemuOpts *opts,
 | 
					                                                QemuOpts *opts,
 | 
				
			||||||
                                                Error **errp)
 | 
					                                                Error **errp)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    uint64_t image_size = 0;
 | 
					    BlockdevCreateOptions *create_options = NULL;
 | 
				
			||||||
    uint32_t cluster_size = QED_DEFAULT_CLUSTER_SIZE;
 | 
					    QDict *qdict = NULL;
 | 
				
			||||||
    uint32_t table_size = QED_DEFAULT_TABLE_SIZE;
 | 
					    QObject *qobj;
 | 
				
			||||||
    char *backing_file = NULL;
 | 
					    Visitor *v;
 | 
				
			||||||
    char *backing_fmt = NULL;
 | 
					    BlockDriverState *bs = NULL;
 | 
				
			||||||
 | 
					    Error *local_err = NULL;
 | 
				
			||||||
    int ret;
 | 
					    int ret;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    image_size = ROUND_UP(qemu_opt_get_size_del(opts, BLOCK_OPT_SIZE, 0),
 | 
					    static const QDictRenames opt_renames[] = {
 | 
				
			||||||
                          BDRV_SECTOR_SIZE);
 | 
					        { BLOCK_OPT_BACKING_FILE,       "backing-file" },
 | 
				
			||||||
    backing_file = qemu_opt_get_del(opts, BLOCK_OPT_BACKING_FILE);
 | 
					        { BLOCK_OPT_BACKING_FMT,        "backing-fmt" },
 | 
				
			||||||
    backing_fmt = qemu_opt_get_del(opts, BLOCK_OPT_BACKING_FMT);
 | 
					        { BLOCK_OPT_CLUSTER_SIZE,       "cluster-size" },
 | 
				
			||||||
    cluster_size = qemu_opt_get_size_del(opts,
 | 
					        { BLOCK_OPT_TABLE_SIZE,         "table-size" },
 | 
				
			||||||
                                         BLOCK_OPT_CLUSTER_SIZE,
 | 
					        { NULL, NULL },
 | 
				
			||||||
                                         QED_DEFAULT_CLUSTER_SIZE);
 | 
					    };
 | 
				
			||||||
    table_size = qemu_opt_get_size_del(opts, BLOCK_OPT_TABLE_SIZE,
 | 
					 | 
				
			||||||
                                       QED_DEFAULT_TABLE_SIZE);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (!qed_is_cluster_size_valid(cluster_size)) {
 | 
					    /* Parse options and convert legacy syntax */
 | 
				
			||||||
        error_setg(errp, "QED cluster size must be within range [%u, %u] "
 | 
					    qdict = qemu_opts_to_qdict_filtered(opts, NULL, &qed_create_opts, true);
 | 
				
			||||||
                         "and power of 2",
 | 
					
 | 
				
			||||||
                   QED_MIN_CLUSTER_SIZE, QED_MAX_CLUSTER_SIZE);
 | 
					    if (!qdict_rename_keys(qdict, opt_renames, errp)) {
 | 
				
			||||||
        ret = -EINVAL;
 | 
					        ret = -EINVAL;
 | 
				
			||||||
        goto finish;
 | 
					        goto fail;
 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    if (!qed_is_table_size_valid(table_size)) {
 | 
					 | 
				
			||||||
        error_setg(errp, "QED table size must be within range [%u, %u] "
 | 
					 | 
				
			||||||
                         "and power of 2",
 | 
					 | 
				
			||||||
                   QED_MIN_TABLE_SIZE, QED_MAX_TABLE_SIZE);
 | 
					 | 
				
			||||||
        ret = -EINVAL;
 | 
					 | 
				
			||||||
        goto finish;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    if (!qed_is_image_size_valid(image_size, cluster_size, table_size)) {
 | 
					 | 
				
			||||||
        error_setg(errp, "QED image size must be a non-zero multiple of "
 | 
					 | 
				
			||||||
                         "cluster size and less than %" PRIu64 " bytes",
 | 
					 | 
				
			||||||
                   qed_max_image_size(cluster_size, table_size));
 | 
					 | 
				
			||||||
        ret = -EINVAL;
 | 
					 | 
				
			||||||
        goto finish;
 | 
					 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    ret = qed_create(filename, cluster_size, image_size, table_size,
 | 
					    /* Create and open the file (protocol layer) */
 | 
				
			||||||
                     backing_file, backing_fmt, opts, errp);
 | 
					    ret = bdrv_create_file(filename, opts, &local_err);
 | 
				
			||||||
 | 
					    if (ret < 0) {
 | 
				
			||||||
 | 
					        error_propagate(errp, local_err);
 | 
				
			||||||
 | 
					        goto fail;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
finish:
 | 
					    bs = bdrv_open(filename, NULL, NULL,
 | 
				
			||||||
    g_free(backing_file);
 | 
					                   BDRV_O_RDWR | BDRV_O_RESIZE | BDRV_O_PROTOCOL, errp);
 | 
				
			||||||
    g_free(backing_fmt);
 | 
					    if (bs == NULL) {
 | 
				
			||||||
 | 
					        ret = -EIO;
 | 
				
			||||||
 | 
					        goto fail;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /* Now get the QAPI type BlockdevCreateOptions */
 | 
				
			||||||
 | 
					    qdict_put_str(qdict, "driver", "qed");
 | 
				
			||||||
 | 
					    qdict_put_str(qdict, "file", bs->node_name);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    qobj = qdict_crumple(qdict, errp);
 | 
				
			||||||
 | 
					    QDECREF(qdict);
 | 
				
			||||||
 | 
					    qdict = qobject_to_qdict(qobj);
 | 
				
			||||||
 | 
					    if (qdict == NULL) {
 | 
				
			||||||
 | 
					        ret = -EINVAL;
 | 
				
			||||||
 | 
					        goto fail;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    v = qobject_input_visitor_new_keyval(QOBJECT(qdict));
 | 
				
			||||||
 | 
					    visit_type_BlockdevCreateOptions(v, NULL, &create_options, &local_err);
 | 
				
			||||||
 | 
					    visit_free(v);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (local_err) {
 | 
				
			||||||
 | 
					        error_propagate(errp, local_err);
 | 
				
			||||||
 | 
					        ret = -EINVAL;
 | 
				
			||||||
 | 
					        goto fail;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /* Silently round up size */
 | 
				
			||||||
 | 
					    assert(create_options->driver == BLOCKDEV_DRIVER_QED);
 | 
				
			||||||
 | 
					    create_options->u.qed.size =
 | 
				
			||||||
 | 
					        ROUND_UP(create_options->u.qed.size, BDRV_SECTOR_SIZE);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /* Create the qed image (format layer) */
 | 
				
			||||||
 | 
					    ret = bdrv_qed_co_create(create_options, errp);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					fail:
 | 
				
			||||||
 | 
					    QDECREF(qdict);
 | 
				
			||||||
 | 
					    bdrv_unref(bs);
 | 
				
			||||||
 | 
					    qapi_free_BlockdevCreateOptions(create_options);
 | 
				
			||||||
    return ret;
 | 
					    return ret;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -1602,6 +1673,7 @@ static BlockDriver bdrv_qed = {
 | 
				
			|||||||
    .bdrv_close               = bdrv_qed_close,
 | 
					    .bdrv_close               = bdrv_qed_close,
 | 
				
			||||||
    .bdrv_reopen_prepare      = bdrv_qed_reopen_prepare,
 | 
					    .bdrv_reopen_prepare      = bdrv_qed_reopen_prepare,
 | 
				
			||||||
    .bdrv_child_perm          = bdrv_format_default_perms,
 | 
					    .bdrv_child_perm          = bdrv_format_default_perms,
 | 
				
			||||||
 | 
					    .bdrv_co_create           = bdrv_qed_co_create,
 | 
				
			||||||
    .bdrv_co_create_opts      = bdrv_qed_co_create_opts,
 | 
					    .bdrv_co_create_opts      = bdrv_qed_co_create_opts,
 | 
				
			||||||
    .bdrv_has_zero_init       = bdrv_has_zero_init_1,
 | 
					    .bdrv_has_zero_init       = bdrv_has_zero_init_1,
 | 
				
			||||||
    .bdrv_co_block_status     = bdrv_qed_co_block_status,
 | 
					    .bdrv_co_block_status     = bdrv_qed_co_block_status,
 | 
				
			||||||
 | 
				
			|||||||
@ -3705,6 +3705,29 @@
 | 
				
			|||||||
            '*lazy-refcounts':  'bool',
 | 
					            '*lazy-refcounts':  'bool',
 | 
				
			||||||
            '*refcount-bits':   'int' } }
 | 
					            '*refcount-bits':   'int' } }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					##
 | 
				
			||||||
 | 
					# @BlockdevCreateOptionsQed:
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					# Driver specific image creation options for qed.
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					# @file             Node to create the image format on
 | 
				
			||||||
 | 
					# @size             Size of the virtual disk in bytes
 | 
				
			||||||
 | 
					# @backing-file     File name of the backing file if a backing file
 | 
				
			||||||
 | 
					#                   should be used
 | 
				
			||||||
 | 
					# @backing-fmt      Name of the block driver to use for the backing file
 | 
				
			||||||
 | 
					# @cluster-size     Cluster size in bytes (default: 65536)
 | 
				
			||||||
 | 
					# @table-size       L1/L2 table size (in clusters)
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					# Since: 2.12
 | 
				
			||||||
 | 
					##
 | 
				
			||||||
 | 
					{ 'struct': 'BlockdevCreateOptionsQed',
 | 
				
			||||||
 | 
					  'data': { 'file':             'BlockdevRef',
 | 
				
			||||||
 | 
					            'size':             'size',
 | 
				
			||||||
 | 
					            '*backing-file':    'str',
 | 
				
			||||||
 | 
					            '*backing-fmt':     'BlockdevDriver',
 | 
				
			||||||
 | 
					            '*cluster-size':    'size',
 | 
				
			||||||
 | 
					            '*table-size':      'int' } }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
##
 | 
					##
 | 
				
			||||||
# @BlockdevCreateOptionsRbd:
 | 
					# @BlockdevCreateOptionsRbd:
 | 
				
			||||||
#
 | 
					#
 | 
				
			||||||
@ -3867,7 +3890,7 @@
 | 
				
			|||||||
      'parallels':      'BlockdevCreateOptionsParallels',
 | 
					      'parallels':      'BlockdevCreateOptionsParallels',
 | 
				
			||||||
      'qcow':           'BlockdevCreateOptionsQcow',
 | 
					      'qcow':           'BlockdevCreateOptionsQcow',
 | 
				
			||||||
      'qcow2':          'BlockdevCreateOptionsQcow2',
 | 
					      'qcow2':          'BlockdevCreateOptionsQcow2',
 | 
				
			||||||
      'qed':            'BlockdevCreateNotSupported',
 | 
					      'qed':            'BlockdevCreateOptionsQed',
 | 
				
			||||||
      'quorum':         'BlockdevCreateNotSupported',
 | 
					      'quorum':         'BlockdevCreateNotSupported',
 | 
				
			||||||
      'raw':            'BlockdevCreateNotSupported',
 | 
					      'raw':            'BlockdevCreateNotSupported',
 | 
				
			||||||
      'rbd':            'BlockdevCreateOptionsRbd',
 | 
					      'rbd':            'BlockdevCreateOptionsRbd',
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user