ssh: Support .bdrv_co_create
This adds the .bdrv_co_create driver callback to ssh, 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
375f0b9266
commit
4906da7e4d
91
block/ssh.c
91
block/ssh.c
@ -854,59 +854,71 @@ static QemuOptsList ssh_create_opts = {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
static int coroutine_fn ssh_co_create_opts(const char *filename, QemuOpts *opts,
|
static int ssh_co_create(BlockdevCreateOptions *options, Error **errp)
|
||||||
Error **errp)
|
|
||||||
{
|
{
|
||||||
int r, ret;
|
BlockdevCreateOptionsSsh *opts = &options->u.ssh;
|
||||||
int64_t total_size = 0;
|
|
||||||
QDict *uri_options = NULL;
|
|
||||||
BlockdevOptionsSsh *ssh_opts = NULL;
|
|
||||||
BDRVSSHState s;
|
BDRVSSHState s;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
assert(options->driver == BLOCKDEV_DRIVER_SSH);
|
||||||
|
|
||||||
ssh_state_init(&s);
|
ssh_state_init(&s);
|
||||||
|
|
||||||
/* Get desired file size. */
|
ret = connect_to_ssh(&s, opts->location,
|
||||||
total_size = ROUND_UP(qemu_opt_get_size_del(opts, BLOCK_OPT_SIZE, 0),
|
LIBSSH2_FXF_READ|LIBSSH2_FXF_WRITE|
|
||||||
BDRV_SECTOR_SIZE);
|
LIBSSH2_FXF_CREAT|LIBSSH2_FXF_TRUNC,
|
||||||
DPRINTF("total_size=%" PRIi64, total_size);
|
0644, errp);
|
||||||
|
if (ret < 0) {
|
||||||
uri_options = qdict_new();
|
goto fail;
|
||||||
r = parse_uri(filename, uri_options, errp);
|
|
||||||
if (r < 0) {
|
|
||||||
ret = r;
|
|
||||||
goto out;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ssh_opts = ssh_parse_options(uri_options, errp);
|
if (opts->size > 0) {
|
||||||
if (ssh_opts == NULL) {
|
ret = ssh_grow_file(&s, opts->size, errp);
|
||||||
ret = -EINVAL;
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
|
|
||||||
r = connect_to_ssh(&s, ssh_opts,
|
|
||||||
LIBSSH2_FXF_READ|LIBSSH2_FXF_WRITE|
|
|
||||||
LIBSSH2_FXF_CREAT|LIBSSH2_FXF_TRUNC,
|
|
||||||
0644, errp);
|
|
||||||
if (r < 0) {
|
|
||||||
ret = r;
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (total_size > 0) {
|
|
||||||
ret = ssh_grow_file(&s, total_size, errp);
|
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
goto out;
|
goto fail;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = 0;
|
ret = 0;
|
||||||
|
fail:
|
||||||
|
ssh_state_free(&s);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int coroutine_fn ssh_co_create_opts(const char *filename, QemuOpts *opts,
|
||||||
|
Error **errp)
|
||||||
|
{
|
||||||
|
BlockdevCreateOptions *create_options;
|
||||||
|
BlockdevCreateOptionsSsh *ssh_opts;
|
||||||
|
int ret;
|
||||||
|
QDict *uri_options = NULL;
|
||||||
|
|
||||||
|
create_options = g_new0(BlockdevCreateOptions, 1);
|
||||||
|
create_options->driver = BLOCKDEV_DRIVER_SSH;
|
||||||
|
ssh_opts = &create_options->u.ssh;
|
||||||
|
|
||||||
|
/* Get desired file size. */
|
||||||
|
ssh_opts->size = ROUND_UP(qemu_opt_get_size_del(opts, BLOCK_OPT_SIZE, 0),
|
||||||
|
BDRV_SECTOR_SIZE);
|
||||||
|
DPRINTF("total_size=%" PRIi64, ssh_opts->size);
|
||||||
|
|
||||||
|
uri_options = qdict_new();
|
||||||
|
ret = parse_uri(filename, uri_options, errp);
|
||||||
|
if (ret < 0) {
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
ssh_opts->location = ssh_parse_options(uri_options, errp);
|
||||||
|
if (ssh_opts->location == NULL) {
|
||||||
|
ret = -EINVAL;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = ssh_co_create(create_options, errp);
|
||||||
|
|
||||||
out:
|
out:
|
||||||
ssh_state_free(&s);
|
QDECREF(uri_options);
|
||||||
if (uri_options != NULL) {
|
qapi_free_BlockdevCreateOptions(create_options);
|
||||||
QDECREF(uri_options);
|
|
||||||
}
|
|
||||||
qapi_free_BlockdevOptionsSsh(ssh_opts);
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1268,6 +1280,7 @@ static BlockDriver bdrv_ssh = {
|
|||||||
.instance_size = sizeof(BDRVSSHState),
|
.instance_size = sizeof(BDRVSSHState),
|
||||||
.bdrv_parse_filename = ssh_parse_filename,
|
.bdrv_parse_filename = ssh_parse_filename,
|
||||||
.bdrv_file_open = ssh_file_open,
|
.bdrv_file_open = ssh_file_open,
|
||||||
|
.bdrv_co_create = ssh_co_create,
|
||||||
.bdrv_co_create_opts = ssh_co_create_opts,
|
.bdrv_co_create_opts = ssh_co_create_opts,
|
||||||
.bdrv_close = ssh_close,
|
.bdrv_close = ssh_close,
|
||||||
.bdrv_has_zero_init = ssh_has_zero_init,
|
.bdrv_has_zero_init = ssh_has_zero_init,
|
||||||
|
@ -3592,6 +3592,20 @@
|
|||||||
'*redundancy': 'SheepdogRedundancy',
|
'*redundancy': 'SheepdogRedundancy',
|
||||||
'*object-size': 'size' } }
|
'*object-size': 'size' } }
|
||||||
|
|
||||||
|
##
|
||||||
|
# @BlockdevCreateOptionsSsh:
|
||||||
|
#
|
||||||
|
# Driver specific image creation options for SSH.
|
||||||
|
#
|
||||||
|
# @location Where to store the new image file
|
||||||
|
# @size Size of the virtual disk in bytes
|
||||||
|
#
|
||||||
|
# Since: 2.12
|
||||||
|
##
|
||||||
|
{ 'struct': 'BlockdevCreateOptionsSsh',
|
||||||
|
'data': { 'location': 'BlockdevOptionsSsh',
|
||||||
|
'size': 'size' } }
|
||||||
|
|
||||||
##
|
##
|
||||||
# @BlockdevCreateNotSupported:
|
# @BlockdevCreateNotSupported:
|
||||||
#
|
#
|
||||||
@ -3644,7 +3658,7 @@
|
|||||||
'rbd': 'BlockdevCreateOptionsRbd',
|
'rbd': 'BlockdevCreateOptionsRbd',
|
||||||
'replication': 'BlockdevCreateNotSupported',
|
'replication': 'BlockdevCreateNotSupported',
|
||||||
'sheepdog': 'BlockdevCreateOptionsSheepdog',
|
'sheepdog': 'BlockdevCreateOptionsSheepdog',
|
||||||
'ssh': 'BlockdevCreateNotSupported',
|
'ssh': 'BlockdevCreateOptionsSsh',
|
||||||
'throttle': 'BlockdevCreateNotSupported',
|
'throttle': 'BlockdevCreateNotSupported',
|
||||||
'vdi': 'BlockdevCreateNotSupported',
|
'vdi': 'BlockdevCreateNotSupported',
|
||||||
'vhdx': 'BlockdevCreateNotSupported',
|
'vhdx': 'BlockdevCreateNotSupported',
|
||||||
|
Loading…
Reference in New Issue
Block a user