mirror of
https://github.com/izzy2lost/xemu.git
synced 2026-07-06 00:20:22 -07:00
Merge remote-tracking branch 'mreitz/tags/pull-block-2019-02-25' into queue-block
Block patches: - Fix various issues with bdrv_refresh_filename() - Fix various iotests - Include LUKS overhead in qemu-img measure for qcow2 - A fix for vmdk's image creation interface # gpg: Signature made Mon Feb 25 15:13:43 2019 CET # gpg: using RSA key F407DB0061D5CF40 # gpg: Good signature from "Max Reitz <mreitz@redhat.com>" # Primary key fingerprint: 91BE B60A 30DB 3E88 57D1 1829 F407 DB00 61D5 CF40 * mreitz/tags/pull-block-2019-02-25: (45 commits) iotests: Skip 211 on insufficient memory vmdk: false positive of compat6 with hwversion not set iotests: add LUKS payload overhead to 178 qemu-img measure test qcow2: include LUKS payload overhead in qemu-img measure iotests.py: s/_/-/g on keys in qmp_log() iotests: Let 045 be run concurrently iotests: Filter SSH paths iotests.py: Filter filename in any string value iotests.py: Add is_str() iotests: Fix 207 to use QMP filters for qmp_log iotests: Fix 232 for LUKS iotests: Remove superfluous rm from 232 iotests: Fix 237 for Python 2.x iotests: Re-add filename filters iotests: Test json:{} filenames of internal BDSs block: BDS options may lack the "driver" option block/null: Generate filename even with latency-ns block/curl: Implement bdrv_refresh_filename() block/curl: Harmonize option defaults block/nvme: Fix bdrv_refresh_filename() ... Signed-off-by: Kevin Wolf <kwolf@redhat.com>
This commit is contained in:
+36
-34
@@ -811,51 +811,37 @@ static int64_t blkdebug_getlength(BlockDriverState *bs)
|
||||
return bdrv_getlength(bs->file->bs);
|
||||
}
|
||||
|
||||
static void blkdebug_refresh_filename(BlockDriverState *bs, QDict *options)
|
||||
static void blkdebug_refresh_filename(BlockDriverState *bs)
|
||||
{
|
||||
BDRVBlkdebugState *s = bs->opaque;
|
||||
QDict *opts;
|
||||
const QDictEntry *e;
|
||||
bool force_json = false;
|
||||
int ret;
|
||||
|
||||
for (e = qdict_first(options); e; e = qdict_next(options, e)) {
|
||||
if (strcmp(qdict_entry_key(e), "config") &&
|
||||
strcmp(qdict_entry_key(e), "x-image"))
|
||||
{
|
||||
force_json = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (force_json && !bs->file->bs->full_open_options) {
|
||||
/* The config file cannot be recreated, so creating a plain filename
|
||||
* is impossible */
|
||||
if (!bs->file->bs->exact_filename[0]) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!force_json && bs->file->bs->exact_filename[0]) {
|
||||
int ret = snprintf(bs->exact_filename, sizeof(bs->exact_filename),
|
||||
"blkdebug:%s:%s", s->config_file ?: "",
|
||||
bs->file->bs->exact_filename);
|
||||
if (ret >= sizeof(bs->exact_filename)) {
|
||||
/* An overflow makes the filename unusable, so do not report any */
|
||||
bs->exact_filename[0] = 0;
|
||||
for (e = qdict_first(bs->full_open_options); e;
|
||||
e = qdict_next(bs->full_open_options, e))
|
||||
{
|
||||
/* Real child options are under "image", but "x-image" may
|
||||
* contain a filename */
|
||||
if (strcmp(qdict_entry_key(e), "config") &&
|
||||
strcmp(qdict_entry_key(e), "image") &&
|
||||
strcmp(qdict_entry_key(e), "x-image") &&
|
||||
strcmp(qdict_entry_key(e), "driver"))
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
opts = qdict_new();
|
||||
qdict_put_str(opts, "driver", "blkdebug");
|
||||
|
||||
qdict_put(opts, "image", qobject_ref(bs->file->bs->full_open_options));
|
||||
|
||||
for (e = qdict_first(options); e; e = qdict_next(options, e)) {
|
||||
if (strcmp(qdict_entry_key(e), "x-image")) {
|
||||
qdict_put_obj(opts, qdict_entry_key(e),
|
||||
qobject_ref(qdict_entry_value(e)));
|
||||
}
|
||||
ret = snprintf(bs->exact_filename, sizeof(bs->exact_filename),
|
||||
"blkdebug:%s:%s",
|
||||
s->config_file ?: "", bs->file->bs->exact_filename);
|
||||
if (ret >= sizeof(bs->exact_filename)) {
|
||||
/* An overflow makes the filename unusable, so do not report any */
|
||||
bs->exact_filename[0] = 0;
|
||||
}
|
||||
|
||||
bs->full_open_options = opts;
|
||||
}
|
||||
|
||||
static void blkdebug_refresh_limits(BlockDriverState *bs, Error **errp)
|
||||
@@ -888,6 +874,20 @@ static int blkdebug_reopen_prepare(BDRVReopenState *reopen_state,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const char *const blkdebug_strong_runtime_opts[] = {
|
||||
"config",
|
||||
"inject-error.",
|
||||
"set-state.",
|
||||
"align",
|
||||
"max-transfer",
|
||||
"opt-write-zero",
|
||||
"max-write-zero",
|
||||
"opt-discard",
|
||||
"max-discard",
|
||||
|
||||
NULL
|
||||
};
|
||||
|
||||
static BlockDriver bdrv_blkdebug = {
|
||||
.format_name = "blkdebug",
|
||||
.protocol_name = "blkdebug",
|
||||
@@ -917,6 +917,8 @@ static BlockDriver bdrv_blkdebug = {
|
||||
= blkdebug_debug_remove_breakpoint,
|
||||
.bdrv_debug_resume = blkdebug_debug_resume,
|
||||
.bdrv_debug_is_suspended = blkdebug_debug_is_suspended,
|
||||
|
||||
.strong_runtime_opts = blkdebug_strong_runtime_opts,
|
||||
};
|
||||
|
||||
static void bdrv_blkdebug_init(void)
|
||||
|
||||
+8
-25
@@ -280,30 +280,6 @@ static int64_t blk_log_writes_getlength(BlockDriverState *bs)
|
||||
return bdrv_getlength(bs->file->bs);
|
||||
}
|
||||
|
||||
static void blk_log_writes_refresh_filename(BlockDriverState *bs,
|
||||
QDict *options)
|
||||
{
|
||||
BDRVBlkLogWritesState *s = bs->opaque;
|
||||
|
||||
/* bs->file->bs has already been refreshed */
|
||||
bdrv_refresh_filename(s->log_file->bs);
|
||||
|
||||
if (bs->file->bs->full_open_options
|
||||
&& s->log_file->bs->full_open_options)
|
||||
{
|
||||
QDict *opts = qdict_new();
|
||||
qdict_put_str(opts, "driver", "blklogwrites");
|
||||
|
||||
qobject_ref(bs->file->bs->full_open_options);
|
||||
qdict_put(opts, "file", bs->file->bs->full_open_options);
|
||||
qobject_ref(s->log_file->bs->full_open_options);
|
||||
qdict_put(opts, "log", s->log_file->bs->full_open_options);
|
||||
qdict_put_int(opts, "log-sector-size", s->sectorsize);
|
||||
|
||||
bs->full_open_options = opts;
|
||||
}
|
||||
}
|
||||
|
||||
static void blk_log_writes_child_perm(BlockDriverState *bs, BdrvChild *c,
|
||||
const BdrvChildRole *role,
|
||||
BlockReopenQueue *ro_q,
|
||||
@@ -520,6 +496,13 @@ blk_log_writes_co_pdiscard(BlockDriverState *bs, int64_t offset, int count)
|
||||
LOG_DISCARD_FLAG, false);
|
||||
}
|
||||
|
||||
static const char *const blk_log_writes_strong_runtime_opts[] = {
|
||||
"log-append",
|
||||
"log-sector-size",
|
||||
|
||||
NULL
|
||||
};
|
||||
|
||||
static BlockDriver bdrv_blk_log_writes = {
|
||||
.format_name = "blklogwrites",
|
||||
.instance_size = sizeof(BDRVBlkLogWritesState),
|
||||
@@ -527,7 +510,6 @@ static BlockDriver bdrv_blk_log_writes = {
|
||||
.bdrv_open = blk_log_writes_open,
|
||||
.bdrv_close = blk_log_writes_close,
|
||||
.bdrv_getlength = blk_log_writes_getlength,
|
||||
.bdrv_refresh_filename = blk_log_writes_refresh_filename,
|
||||
.bdrv_child_perm = blk_log_writes_child_perm,
|
||||
.bdrv_refresh_limits = blk_log_writes_refresh_limits,
|
||||
|
||||
@@ -539,6 +521,7 @@ static BlockDriver bdrv_blk_log_writes = {
|
||||
.bdrv_co_block_status = bdrv_co_block_status_from_file,
|
||||
|
||||
.is_filter = true,
|
||||
.strong_runtime_opts = blk_log_writes_strong_runtime_opts,
|
||||
};
|
||||
|
||||
static void bdrv_blk_log_writes_init(void)
|
||||
|
||||
+11
-18
@@ -281,27 +281,10 @@ static bool blkverify_recurse_is_first_non_filter(BlockDriverState *bs,
|
||||
return bdrv_recurse_is_first_non_filter(s->test_file->bs, candidate);
|
||||
}
|
||||
|
||||
static void blkverify_refresh_filename(BlockDriverState *bs, QDict *options)
|
||||
static void blkverify_refresh_filename(BlockDriverState *bs)
|
||||
{
|
||||
BDRVBlkverifyState *s = bs->opaque;
|
||||
|
||||
/* bs->file->bs has already been refreshed */
|
||||
bdrv_refresh_filename(s->test_file->bs);
|
||||
|
||||
if (bs->file->bs->full_open_options
|
||||
&& s->test_file->bs->full_open_options)
|
||||
{
|
||||
QDict *opts = qdict_new();
|
||||
qdict_put_str(opts, "driver", "blkverify");
|
||||
|
||||
qdict_put(opts, "raw",
|
||||
qobject_ref(bs->file->bs->full_open_options));
|
||||
qdict_put(opts, "test",
|
||||
qobject_ref(s->test_file->bs->full_open_options));
|
||||
|
||||
bs->full_open_options = opts;
|
||||
}
|
||||
|
||||
if (bs->file->bs->exact_filename[0]
|
||||
&& s->test_file->bs->exact_filename[0])
|
||||
{
|
||||
@@ -316,6 +299,15 @@ static void blkverify_refresh_filename(BlockDriverState *bs, QDict *options)
|
||||
}
|
||||
}
|
||||
|
||||
static char *blkverify_dirname(BlockDriverState *bs, Error **errp)
|
||||
{
|
||||
/* In general, there are two BDSs with different dirnames below this one;
|
||||
* so there is no unique dirname we could return (unless both are equal by
|
||||
* chance). Therefore, to be consistent, just always return NULL. */
|
||||
error_setg(errp, "Cannot generate a base directory for blkverify nodes");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static BlockDriver bdrv_blkverify = {
|
||||
.format_name = "blkverify",
|
||||
.protocol_name = "blkverify",
|
||||
@@ -327,6 +319,7 @@ static BlockDriver bdrv_blkverify = {
|
||||
.bdrv_child_perm = bdrv_filter_default_perms,
|
||||
.bdrv_getlength = blkverify_getlength,
|
||||
.bdrv_refresh_filename = blkverify_refresh_filename,
|
||||
.bdrv_dirname = blkverify_dirname,
|
||||
|
||||
.bdrv_co_preadv = blkverify_co_preadv,
|
||||
.bdrv_co_pwritev = blkverify_co_pwritev,
|
||||
|
||||
+1
-2
@@ -230,9 +230,8 @@ static int coroutine_fn bdrv_commit_top_preadv(BlockDriverState *bs,
|
||||
return bdrv_co_preadv(bs->backing, offset, bytes, qiov, flags);
|
||||
}
|
||||
|
||||
static void bdrv_commit_top_refresh_filename(BlockDriverState *bs, QDict *opts)
|
||||
static void bdrv_commit_top_refresh_filename(BlockDriverState *bs)
|
||||
{
|
||||
bdrv_refresh_filename(bs->backing->bs);
|
||||
pstrcpy(bs->exact_filename, sizeof(bs->exact_filename),
|
||||
bs->backing->bs->filename);
|
||||
}
|
||||
|
||||
@@ -619,6 +619,12 @@ block_crypto_get_specific_info_luks(BlockDriverState *bs, Error **errp)
|
||||
return spec_info;
|
||||
}
|
||||
|
||||
static const char *const block_crypto_strong_runtime_opts[] = {
|
||||
BLOCK_CRYPTO_OPT_LUKS_KEY_SECRET,
|
||||
|
||||
NULL
|
||||
};
|
||||
|
||||
BlockDriver bdrv_crypto_luks = {
|
||||
.format_name = "luks",
|
||||
.instance_size = sizeof(BlockCrypto),
|
||||
@@ -640,6 +646,8 @@ BlockDriver bdrv_crypto_luks = {
|
||||
.bdrv_getlength = block_crypto_getlength,
|
||||
.bdrv_get_info = block_crypto_get_info_luks,
|
||||
.bdrv_get_specific_info = block_crypto_get_specific_info_luks,
|
||||
|
||||
.strong_runtime_opts = block_crypto_strong_runtime_opts,
|
||||
};
|
||||
|
||||
static void block_crypto_init(void)
|
||||
|
||||
+50
-5
@@ -61,8 +61,6 @@ static CURLMcode __curl_multi_socket_action(CURLM *multi_handle,
|
||||
|
||||
#define CURL_NUM_STATES 8
|
||||
#define CURL_NUM_ACB 8
|
||||
#define READ_AHEAD_DEFAULT (256 * 1024)
|
||||
#define CURL_TIMEOUT_DEFAULT 5
|
||||
#define CURL_TIMEOUT_MAX 10000
|
||||
|
||||
#define CURL_BLOCK_OPT_URL "url"
|
||||
@@ -76,6 +74,10 @@ static CURLMcode __curl_multi_socket_action(CURLM *multi_handle,
|
||||
#define CURL_BLOCK_OPT_PROXY_USERNAME "proxy-username"
|
||||
#define CURL_BLOCK_OPT_PROXY_PASSWORD_SECRET "proxy-password-secret"
|
||||
|
||||
#define CURL_BLOCK_OPT_READAHEAD_DEFAULT (256 * 1024)
|
||||
#define CURL_BLOCK_OPT_SSLVERIFY_DEFAULT true
|
||||
#define CURL_BLOCK_OPT_TIMEOUT_DEFAULT 5
|
||||
|
||||
struct BDRVCURLState;
|
||||
|
||||
static bool libcurl_initialized;
|
||||
@@ -696,7 +698,7 @@ static int curl_open(BlockDriverState *bs, QDict *options, int flags,
|
||||
}
|
||||
|
||||
s->readahead_size = qemu_opt_get_size(opts, CURL_BLOCK_OPT_READAHEAD,
|
||||
READ_AHEAD_DEFAULT);
|
||||
CURL_BLOCK_OPT_READAHEAD_DEFAULT);
|
||||
if ((s->readahead_size & 0x1ff) != 0) {
|
||||
error_setg(errp, "HTTP_READAHEAD_SIZE %zd is not a multiple of 512",
|
||||
s->readahead_size);
|
||||
@@ -704,13 +706,14 @@ static int curl_open(BlockDriverState *bs, QDict *options, int flags,
|
||||
}
|
||||
|
||||
s->timeout = qemu_opt_get_number(opts, CURL_BLOCK_OPT_TIMEOUT,
|
||||
CURL_TIMEOUT_DEFAULT);
|
||||
CURL_BLOCK_OPT_TIMEOUT_DEFAULT);
|
||||
if (s->timeout > CURL_TIMEOUT_MAX) {
|
||||
error_setg(errp, "timeout parameter is too large or negative");
|
||||
goto out_noclean;
|
||||
}
|
||||
|
||||
s->sslverify = qemu_opt_get_bool(opts, CURL_BLOCK_OPT_SSLVERIFY, true);
|
||||
s->sslverify = qemu_opt_get_bool(opts, CURL_BLOCK_OPT_SSLVERIFY,
|
||||
CURL_BLOCK_OPT_SSLVERIFY_DEFAULT);
|
||||
|
||||
cookie = qemu_opt_get(opts, CURL_BLOCK_OPT_COOKIE);
|
||||
cookie_secret = qemu_opt_get(opts, CURL_BLOCK_OPT_COOKIE_SECRET);
|
||||
@@ -947,6 +950,36 @@ static int64_t curl_getlength(BlockDriverState *bs)
|
||||
return s->len;
|
||||
}
|
||||
|
||||
static void curl_refresh_filename(BlockDriverState *bs)
|
||||
{
|
||||
BDRVCURLState *s = bs->opaque;
|
||||
|
||||
/* "readahead" and "timeout" do not change the guest-visible data,
|
||||
* so ignore them */
|
||||
if (s->sslverify != CURL_BLOCK_OPT_SSLVERIFY_DEFAULT ||
|
||||
s->cookie || s->username || s->password || s->proxyusername ||
|
||||
s->proxypassword)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
pstrcpy(bs->exact_filename, sizeof(bs->exact_filename), s->url);
|
||||
}
|
||||
|
||||
|
||||
static const char *const curl_strong_runtime_opts[] = {
|
||||
CURL_BLOCK_OPT_URL,
|
||||
CURL_BLOCK_OPT_SSLVERIFY,
|
||||
CURL_BLOCK_OPT_COOKIE,
|
||||
CURL_BLOCK_OPT_COOKIE_SECRET,
|
||||
CURL_BLOCK_OPT_USERNAME,
|
||||
CURL_BLOCK_OPT_PASSWORD_SECRET,
|
||||
CURL_BLOCK_OPT_PROXY_USERNAME,
|
||||
CURL_BLOCK_OPT_PROXY_PASSWORD_SECRET,
|
||||
|
||||
NULL
|
||||
};
|
||||
|
||||
static BlockDriver bdrv_http = {
|
||||
.format_name = "http",
|
||||
.protocol_name = "http",
|
||||
@@ -961,6 +994,9 @@ static BlockDriver bdrv_http = {
|
||||
|
||||
.bdrv_detach_aio_context = curl_detach_aio_context,
|
||||
.bdrv_attach_aio_context = curl_attach_aio_context,
|
||||
|
||||
.bdrv_refresh_filename = curl_refresh_filename,
|
||||
.strong_runtime_opts = curl_strong_runtime_opts,
|
||||
};
|
||||
|
||||
static BlockDriver bdrv_https = {
|
||||
@@ -977,6 +1013,9 @@ static BlockDriver bdrv_https = {
|
||||
|
||||
.bdrv_detach_aio_context = curl_detach_aio_context,
|
||||
.bdrv_attach_aio_context = curl_attach_aio_context,
|
||||
|
||||
.bdrv_refresh_filename = curl_refresh_filename,
|
||||
.strong_runtime_opts = curl_strong_runtime_opts,
|
||||
};
|
||||
|
||||
static BlockDriver bdrv_ftp = {
|
||||
@@ -993,6 +1032,9 @@ static BlockDriver bdrv_ftp = {
|
||||
|
||||
.bdrv_detach_aio_context = curl_detach_aio_context,
|
||||
.bdrv_attach_aio_context = curl_attach_aio_context,
|
||||
|
||||
.bdrv_refresh_filename = curl_refresh_filename,
|
||||
.strong_runtime_opts = curl_strong_runtime_opts,
|
||||
};
|
||||
|
||||
static BlockDriver bdrv_ftps = {
|
||||
@@ -1009,6 +1051,9 @@ static BlockDriver bdrv_ftps = {
|
||||
|
||||
.bdrv_detach_aio_context = curl_detach_aio_context,
|
||||
.bdrv_attach_aio_context = curl_attach_aio_context,
|
||||
|
||||
.bdrv_refresh_filename = curl_refresh_filename,
|
||||
.strong_runtime_opts = curl_strong_runtime_opts,
|
||||
};
|
||||
|
||||
static void curl_block_init(void)
|
||||
|
||||
@@ -1495,6 +1495,21 @@ static int coroutine_fn qemu_gluster_co_block_status(BlockDriverState *bs,
|
||||
}
|
||||
|
||||
|
||||
static const char *const gluster_strong_open_opts[] = {
|
||||
GLUSTER_OPT_VOLUME,
|
||||
GLUSTER_OPT_PATH,
|
||||
GLUSTER_OPT_TYPE,
|
||||
GLUSTER_OPT_SERVER_PATTERN,
|
||||
GLUSTER_OPT_HOST,
|
||||
GLUSTER_OPT_PORT,
|
||||
GLUSTER_OPT_TO,
|
||||
GLUSTER_OPT_IPV4,
|
||||
GLUSTER_OPT_IPV6,
|
||||
GLUSTER_OPT_SOCKET,
|
||||
|
||||
NULL
|
||||
};
|
||||
|
||||
static BlockDriver bdrv_gluster = {
|
||||
.format_name = "gluster",
|
||||
.protocol_name = "gluster",
|
||||
@@ -1522,6 +1537,7 @@ static BlockDriver bdrv_gluster = {
|
||||
#endif
|
||||
.bdrv_co_block_status = qemu_gluster_co_block_status,
|
||||
.create_opts = &qemu_gluster_create_opts,
|
||||
.strong_runtime_opts = gluster_strong_open_opts,
|
||||
};
|
||||
|
||||
static BlockDriver bdrv_gluster_tcp = {
|
||||
@@ -1551,6 +1567,7 @@ static BlockDriver bdrv_gluster_tcp = {
|
||||
#endif
|
||||
.bdrv_co_block_status = qemu_gluster_co_block_status,
|
||||
.create_opts = &qemu_gluster_create_opts,
|
||||
.strong_runtime_opts = gluster_strong_open_opts,
|
||||
};
|
||||
|
||||
static BlockDriver bdrv_gluster_unix = {
|
||||
@@ -1580,6 +1597,7 @@ static BlockDriver bdrv_gluster_unix = {
|
||||
#endif
|
||||
.bdrv_co_block_status = qemu_gluster_co_block_status,
|
||||
.create_opts = &qemu_gluster_create_opts,
|
||||
.strong_runtime_opts = gluster_strong_open_opts,
|
||||
};
|
||||
|
||||
/* rdma is deprecated (actually never supported for volfile fetch).
|
||||
@@ -1615,6 +1633,7 @@ static BlockDriver bdrv_gluster_rdma = {
|
||||
#endif
|
||||
.bdrv_co_block_status = qemu_gluster_co_block_status,
|
||||
.create_opts = &qemu_gluster_create_opts,
|
||||
.strong_runtime_opts = gluster_strong_open_opts,
|
||||
};
|
||||
|
||||
static void bdrv_gluster_init(void)
|
||||
|
||||
@@ -2448,6 +2448,20 @@ static QemuOptsList iscsi_create_opts = {
|
||||
}
|
||||
};
|
||||
|
||||
static const char *const iscsi_strong_runtime_opts[] = {
|
||||
"transport",
|
||||
"portal",
|
||||
"target",
|
||||
"user",
|
||||
"password",
|
||||
"password-secret",
|
||||
"lun",
|
||||
"initiator-name",
|
||||
"header-digest",
|
||||
|
||||
NULL
|
||||
};
|
||||
|
||||
static BlockDriver bdrv_iscsi = {
|
||||
.format_name = "iscsi",
|
||||
.protocol_name = "iscsi",
|
||||
@@ -2482,6 +2496,8 @@ static BlockDriver bdrv_iscsi = {
|
||||
|
||||
.bdrv_detach_aio_context = iscsi_detach_aio_context,
|
||||
.bdrv_attach_aio_context = iscsi_attach_aio_context,
|
||||
|
||||
.strong_runtime_opts = iscsi_strong_runtime_opts,
|
||||
};
|
||||
|
||||
#if LIBISCSI_API_VERSION >= (20160603)
|
||||
@@ -2519,6 +2535,8 @@ static BlockDriver bdrv_iser = {
|
||||
|
||||
.bdrv_detach_aio_context = iscsi_detach_aio_context,
|
||||
.bdrv_attach_aio_context = iscsi_attach_aio_context,
|
||||
|
||||
.strong_runtime_opts = iscsi_strong_runtime_opts,
|
||||
};
|
||||
#endif
|
||||
|
||||
|
||||
+1
-2
@@ -1431,14 +1431,13 @@ static int coroutine_fn bdrv_mirror_top_pdiscard(BlockDriverState *bs,
|
||||
NULL, 0);
|
||||
}
|
||||
|
||||
static void bdrv_mirror_top_refresh_filename(BlockDriverState *bs, QDict *opts)
|
||||
static void bdrv_mirror_top_refresh_filename(BlockDriverState *bs)
|
||||
{
|
||||
if (bs->backing == NULL) {
|
||||
/* we can be here after failed bdrv_attach_child in
|
||||
* bdrv_set_backing_hd */
|
||||
return;
|
||||
}
|
||||
bdrv_refresh_filename(bs->backing->bs);
|
||||
pstrcpy(bs->exact_filename, sizeof(bs->exact_filename),
|
||||
bs->backing->bs->filename);
|
||||
}
|
||||
|
||||
+28
-22
@@ -477,12 +477,9 @@ static void nbd_attach_aio_context(BlockDriverState *bs,
|
||||
nbd_client_attach_aio_context(bs, new_context);
|
||||
}
|
||||
|
||||
static void nbd_refresh_filename(BlockDriverState *bs, QDict *options)
|
||||
static void nbd_refresh_filename(BlockDriverState *bs)
|
||||
{
|
||||
BDRVNBDState *s = bs->opaque;
|
||||
QDict *opts = qdict_new();
|
||||
QObject *saddr_qdict;
|
||||
Visitor *ov;
|
||||
const char *host = NULL, *port = NULL, *path = NULL;
|
||||
|
||||
if (s->saddr->type == SOCKET_ADDRESS_TYPE_INET) {
|
||||
@@ -495,8 +492,6 @@ static void nbd_refresh_filename(BlockDriverState *bs, QDict *options)
|
||||
path = s->saddr->u.q_unix.path;
|
||||
} /* else can't represent as pseudo-filename */
|
||||
|
||||
qdict_put_str(opts, "driver", "nbd");
|
||||
|
||||
if (path && s->export) {
|
||||
snprintf(bs->exact_filename, sizeof(bs->exact_filename),
|
||||
"nbd+unix:///%s?socket=%s", s->export, path);
|
||||
@@ -510,24 +505,29 @@ static void nbd_refresh_filename(BlockDriverState *bs, QDict *options)
|
||||
snprintf(bs->exact_filename, sizeof(bs->exact_filename),
|
||||
"nbd://%s:%s", host, port);
|
||||
}
|
||||
|
||||
ov = qobject_output_visitor_new(&saddr_qdict);
|
||||
visit_type_SocketAddress(ov, NULL, &s->saddr, &error_abort);
|
||||
visit_complete(ov, &saddr_qdict);
|
||||
visit_free(ov);
|
||||
qdict_put_obj(opts, "server", saddr_qdict);
|
||||
|
||||
if (s->export) {
|
||||
qdict_put_str(opts, "export", s->export);
|
||||
}
|
||||
if (s->tlscredsid) {
|
||||
qdict_put_str(opts, "tls-creds", s->tlscredsid);
|
||||
}
|
||||
|
||||
qdict_flatten(opts);
|
||||
bs->full_open_options = opts;
|
||||
}
|
||||
|
||||
static char *nbd_dirname(BlockDriverState *bs, Error **errp)
|
||||
{
|
||||
/* The generic bdrv_dirname() implementation is able to work out some
|
||||
* directory name for NBD nodes, but that would be wrong. So far there is no
|
||||
* specification for how "export paths" would work, so NBD does not have
|
||||
* directory names. */
|
||||
error_setg(errp, "Cannot generate a base directory for NBD nodes");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static const char *const nbd_strong_runtime_opts[] = {
|
||||
"path",
|
||||
"host",
|
||||
"port",
|
||||
"export",
|
||||
"tls-creds",
|
||||
"server.",
|
||||
|
||||
NULL
|
||||
};
|
||||
|
||||
static BlockDriver bdrv_nbd = {
|
||||
.format_name = "nbd",
|
||||
.protocol_name = "nbd",
|
||||
@@ -546,6 +546,8 @@ static BlockDriver bdrv_nbd = {
|
||||
.bdrv_attach_aio_context = nbd_attach_aio_context,
|
||||
.bdrv_refresh_filename = nbd_refresh_filename,
|
||||
.bdrv_co_block_status = nbd_client_co_block_status,
|
||||
.bdrv_dirname = nbd_dirname,
|
||||
.strong_runtime_opts = nbd_strong_runtime_opts,
|
||||
};
|
||||
|
||||
static BlockDriver bdrv_nbd_tcp = {
|
||||
@@ -566,6 +568,8 @@ static BlockDriver bdrv_nbd_tcp = {
|
||||
.bdrv_attach_aio_context = nbd_attach_aio_context,
|
||||
.bdrv_refresh_filename = nbd_refresh_filename,
|
||||
.bdrv_co_block_status = nbd_client_co_block_status,
|
||||
.bdrv_dirname = nbd_dirname,
|
||||
.strong_runtime_opts = nbd_strong_runtime_opts,
|
||||
};
|
||||
|
||||
static BlockDriver bdrv_nbd_unix = {
|
||||
@@ -586,6 +590,8 @@ static BlockDriver bdrv_nbd_unix = {
|
||||
.bdrv_attach_aio_context = nbd_attach_aio_context,
|
||||
.bdrv_refresh_filename = nbd_refresh_filename,
|
||||
.bdrv_co_block_status = nbd_client_co_block_status,
|
||||
.bdrv_dirname = nbd_dirname,
|
||||
.strong_runtime_opts = nbd_strong_runtime_opts,
|
||||
};
|
||||
|
||||
static void bdrv_nbd_init(void)
|
||||
|
||||
+23
-31
@@ -799,14 +799,9 @@ static int nfs_reopen_prepare(BDRVReopenState *state,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void nfs_refresh_filename(BlockDriverState *bs, QDict *options)
|
||||
static void nfs_refresh_filename(BlockDriverState *bs)
|
||||
{
|
||||
NFSClient *client = bs->opaque;
|
||||
QDict *opts = qdict_new();
|
||||
QObject *server_qdict;
|
||||
Visitor *ov;
|
||||
|
||||
qdict_put_str(opts, "driver", "nfs");
|
||||
|
||||
if (client->uid && !client->gid) {
|
||||
snprintf(bs->exact_filename, sizeof(bs->exact_filename),
|
||||
@@ -824,35 +819,20 @@ static void nfs_refresh_filename(BlockDriverState *bs, QDict *options)
|
||||
snprintf(bs->exact_filename, sizeof(bs->exact_filename),
|
||||
"nfs://%s%s", client->server->host, client->path);
|
||||
}
|
||||
}
|
||||
|
||||
ov = qobject_output_visitor_new(&server_qdict);
|
||||
visit_type_NFSServer(ov, NULL, &client->server, &error_abort);
|
||||
visit_complete(ov, &server_qdict);
|
||||
qdict_put_obj(opts, "server", server_qdict);
|
||||
qdict_put_str(opts, "path", client->path);
|
||||
static char *nfs_dirname(BlockDriverState *bs, Error **errp)
|
||||
{
|
||||
NFSClient *client = bs->opaque;
|
||||
|
||||
if (client->uid) {
|
||||
qdict_put_int(opts, "user", client->uid);
|
||||
}
|
||||
if (client->gid) {
|
||||
qdict_put_int(opts, "group", client->gid);
|
||||
}
|
||||
if (client->tcp_syncnt) {
|
||||
qdict_put_int(opts, "tcp-syn-cnt", client->tcp_syncnt);
|
||||
}
|
||||
if (client->readahead) {
|
||||
qdict_put_int(opts, "readahead-size", client->readahead);
|
||||
}
|
||||
if (client->pagecache) {
|
||||
qdict_put_int(opts, "page-cache-size", client->pagecache);
|
||||
}
|
||||
if (client->debug) {
|
||||
qdict_put_int(opts, "debug", client->debug);
|
||||
if (client->uid || client->gid) {
|
||||
bdrv_refresh_filename(bs);
|
||||
error_setg(errp, "Cannot generate a base directory for NFS node '%s'",
|
||||
bs->filename);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
visit_free(ov);
|
||||
qdict_flatten(opts);
|
||||
bs->full_open_options = opts;
|
||||
return g_strdup_printf("nfs://%s%s/", client->server->host, client->path);
|
||||
}
|
||||
|
||||
#ifdef LIBNFS_FEATURE_PAGECACHE
|
||||
@@ -864,6 +844,15 @@ static void coroutine_fn nfs_co_invalidate_cache(BlockDriverState *bs,
|
||||
}
|
||||
#endif
|
||||
|
||||
static const char *nfs_strong_runtime_opts[] = {
|
||||
"path",
|
||||
"user",
|
||||
"group",
|
||||
"server.",
|
||||
|
||||
NULL
|
||||
};
|
||||
|
||||
static BlockDriver bdrv_nfs = {
|
||||
.format_name = "nfs",
|
||||
.protocol_name = "nfs",
|
||||
@@ -889,6 +878,9 @@ static BlockDriver bdrv_nfs = {
|
||||
.bdrv_detach_aio_context = nfs_detach_aio_context,
|
||||
.bdrv_attach_aio_context = nfs_attach_aio_context,
|
||||
.bdrv_refresh_filename = nfs_refresh_filename,
|
||||
.bdrv_dirname = nfs_dirname,
|
||||
|
||||
.strong_runtime_opts = nfs_strong_runtime_opts,
|
||||
|
||||
#ifdef LIBNFS_FEATURE_PAGECACHE
|
||||
.bdrv_co_invalidate_cache = nfs_co_invalidate_cache,
|
||||
|
||||
+23
-7
@@ -239,19 +239,33 @@ static int coroutine_fn null_co_block_status(BlockDriverState *bs,
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void null_refresh_filename(BlockDriverState *bs, QDict *opts)
|
||||
static void null_refresh_filename(BlockDriverState *bs)
|
||||
{
|
||||
qdict_del(opts, "filename");
|
||||
const QDictEntry *e;
|
||||
|
||||
if (!qdict_size(opts)) {
|
||||
snprintf(bs->exact_filename, sizeof(bs->exact_filename), "%s://",
|
||||
bs->drv->format_name);
|
||||
for (e = qdict_first(bs->full_open_options); e;
|
||||
e = qdict_next(bs->full_open_options, e))
|
||||
{
|
||||
/* These options can be ignored */
|
||||
if (strcmp(qdict_entry_key(e), "filename") &&
|
||||
strcmp(qdict_entry_key(e), "driver") &&
|
||||
strcmp(qdict_entry_key(e), NULL_OPT_LATENCY))
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
qdict_put_str(opts, "driver", bs->drv->format_name);
|
||||
bs->full_open_options = qobject_ref(opts);
|
||||
snprintf(bs->exact_filename, sizeof(bs->exact_filename), "%s://",
|
||||
bs->drv->format_name);
|
||||
}
|
||||
|
||||
static const char *const null_strong_runtime_opts[] = {
|
||||
BLOCK_OPT_SIZE,
|
||||
NULL_OPT_ZEROES,
|
||||
|
||||
NULL
|
||||
};
|
||||
|
||||
static BlockDriver bdrv_null_co = {
|
||||
.format_name = "null-co",
|
||||
.protocol_name = "null-co",
|
||||
@@ -269,6 +283,7 @@ static BlockDriver bdrv_null_co = {
|
||||
.bdrv_co_block_status = null_co_block_status,
|
||||
|
||||
.bdrv_refresh_filename = null_refresh_filename,
|
||||
.strong_runtime_opts = null_strong_runtime_opts,
|
||||
};
|
||||
|
||||
static BlockDriver bdrv_null_aio = {
|
||||
@@ -288,6 +303,7 @@ static BlockDriver bdrv_null_aio = {
|
||||
.bdrv_co_block_status = null_co_block_status,
|
||||
|
||||
.bdrv_refresh_filename = null_refresh_filename,
|
||||
.strong_runtime_opts = null_strong_runtime_opts,
|
||||
};
|
||||
|
||||
static void bdrv_null_init(void)
|
||||
|
||||
+18
-9
@@ -111,6 +111,9 @@ typedef struct {
|
||||
|
||||
/* Total size of mapped qiov, accessed under dma_map_lock */
|
||||
int dma_map_count;
|
||||
|
||||
/* PCI address (required for nvme_refresh_filename()) */
|
||||
char *device;
|
||||
} BDRVNVMeState;
|
||||
|
||||
#define NVME_BLOCK_OPT_DEVICE "device"
|
||||
@@ -557,6 +560,7 @@ static int nvme_init(BlockDriverState *bs, const char *device, int namespace,
|
||||
|
||||
qemu_co_mutex_init(&s->dma_map_lock);
|
||||
qemu_co_queue_init(&s->dma_flush_queue);
|
||||
s->device = g_strdup(device);
|
||||
s->nsid = namespace;
|
||||
s->aio_context = bdrv_get_aio_context(bs);
|
||||
ret = event_notifier_init(&s->irq_notifier, 0);
|
||||
@@ -729,6 +733,8 @@ static void nvme_close(BlockDriverState *bs)
|
||||
event_notifier_cleanup(&s->irq_notifier);
|
||||
qemu_vfio_pci_unmap_bar(s->vfio, 0, (void *)s->regs, 0, NVME_BAR_SIZE);
|
||||
qemu_vfio_close(s->vfio);
|
||||
|
||||
g_free(s->device);
|
||||
}
|
||||
|
||||
static int nvme_file_open(BlockDriverState *bs, QDict *options, int flags,
|
||||
@@ -1053,17 +1059,12 @@ static int nvme_reopen_prepare(BDRVReopenState *reopen_state,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void nvme_refresh_filename(BlockDriverState *bs, QDict *opts)
|
||||
static void nvme_refresh_filename(BlockDriverState *bs)
|
||||
{
|
||||
qdict_del(opts, "filename");
|
||||
BDRVNVMeState *s = bs->opaque;
|
||||
|
||||
if (!qdict_size(opts)) {
|
||||
snprintf(bs->exact_filename, sizeof(bs->exact_filename), "%s://",
|
||||
bs->drv->format_name);
|
||||
}
|
||||
|
||||
qdict_put_str(opts, "driver", bs->drv->format_name);
|
||||
bs->full_open_options = qobject_ref(opts);
|
||||
snprintf(bs->exact_filename, sizeof(bs->exact_filename), "nvme://%s/%i",
|
||||
s->device, s->nsid);
|
||||
}
|
||||
|
||||
static void nvme_refresh_limits(BlockDriverState *bs, Error **errp)
|
||||
@@ -1136,6 +1137,13 @@ static void nvme_unregister_buf(BlockDriverState *bs, void *host)
|
||||
qemu_vfio_dma_unmap(s->vfio, host);
|
||||
}
|
||||
|
||||
static const char *const nvme_strong_runtime_opts[] = {
|
||||
NVME_BLOCK_OPT_DEVICE,
|
||||
NVME_BLOCK_OPT_NAMESPACE,
|
||||
|
||||
NULL
|
||||
};
|
||||
|
||||
static BlockDriver bdrv_nvme = {
|
||||
.format_name = "nvme",
|
||||
.protocol_name = "nvme",
|
||||
@@ -1153,6 +1161,7 @@ static BlockDriver bdrv_nvme = {
|
||||
|
||||
.bdrv_refresh_filename = nvme_refresh_filename,
|
||||
.bdrv_refresh_limits = nvme_refresh_limits,
|
||||
.strong_runtime_opts = nvme_strong_runtime_opts,
|
||||
|
||||
.bdrv_detach_aio_context = nvme_detach_aio_context,
|
||||
.bdrv_attach_aio_context = nvme_attach_aio_context,
|
||||
|
||||
+6
-10
@@ -51,6 +51,8 @@ BlockDeviceInfo *bdrv_block_device_info(BlockBackend *blk,
|
||||
return NULL;
|
||||
}
|
||||
|
||||
bdrv_refresh_filename(bs);
|
||||
|
||||
info = g_malloc0(sizeof(*info));
|
||||
info->file = g_strdup(bs->filename);
|
||||
info->ro = bs->read_only;
|
||||
@@ -264,6 +266,8 @@ void bdrv_query_image_info(BlockDriverState *bs,
|
||||
goto out;
|
||||
}
|
||||
|
||||
bdrv_refresh_filename(bs);
|
||||
|
||||
info = g_new0(ImageInfo, 1);
|
||||
info->filename = g_strdup(bs->filename);
|
||||
info->format = g_strdup(bdrv_get_format_name(bs));
|
||||
@@ -292,18 +296,10 @@ void bdrv_query_image_info(BlockDriverState *bs,
|
||||
|
||||
backing_filename = bs->backing_file;
|
||||
if (backing_filename[0] != '\0') {
|
||||
char *backing_filename2 = g_malloc0(PATH_MAX);
|
||||
char *backing_filename2;
|
||||
info->backing_filename = g_strdup(backing_filename);
|
||||
info->has_backing_filename = true;
|
||||
bdrv_get_full_backing_filename(bs, backing_filename2, PATH_MAX, &err);
|
||||
if (err) {
|
||||
/* Can't reconstruct the full backing filename, so we must omit
|
||||
* this field and apply a Best Effort to this query. */
|
||||
g_free(backing_filename2);
|
||||
backing_filename2 = NULL;
|
||||
error_free(err);
|
||||
err = NULL;
|
||||
}
|
||||
backing_filename2 = bdrv_get_full_backing_filename(bs, NULL);
|
||||
|
||||
/* Always report the full_backing_filename if present, even if it's the
|
||||
* same as backing_filename. That they are same is useful info. */
|
||||
|
||||
+12
-2
@@ -31,6 +31,7 @@
|
||||
#include "qemu/module.h"
|
||||
#include "qemu/option.h"
|
||||
#include "qemu/bswap.h"
|
||||
#include "qemu/cutils.h"
|
||||
#include <zlib.h>
|
||||
#include "qapi/qmp/qdict.h"
|
||||
#include "qapi/qmp/qstring.h"
|
||||
@@ -295,11 +296,13 @@ static int qcow_open(BlockDriverState *bs, QDict *options, int flags,
|
||||
goto fail;
|
||||
}
|
||||
ret = bdrv_pread(bs->file, header.backing_file_offset,
|
||||
bs->backing_file, len);
|
||||
bs->auto_backing_file, len);
|
||||
if (ret < 0) {
|
||||
goto fail;
|
||||
}
|
||||
bs->backing_file[len] = '\0';
|
||||
bs->auto_backing_file[len] = '\0';
|
||||
pstrcpy(bs->backing_file, sizeof(bs->backing_file),
|
||||
bs->auto_backing_file);
|
||||
}
|
||||
|
||||
/* Disable migration when qcow images are used */
|
||||
@@ -1183,6 +1186,12 @@ static QemuOptsList qcow_create_opts = {
|
||||
}
|
||||
};
|
||||
|
||||
static const char *const qcow_strong_runtime_opts[] = {
|
||||
"encrypt." BLOCK_CRYPTO_OPT_QCOW_KEY_SECRET,
|
||||
|
||||
NULL
|
||||
};
|
||||
|
||||
static BlockDriver bdrv_qcow = {
|
||||
.format_name = "qcow",
|
||||
.instance_size = sizeof(BDRVQcowState),
|
||||
@@ -1206,6 +1215,7 @@ static BlockDriver bdrv_qcow = {
|
||||
.bdrv_get_info = qcow_get_info,
|
||||
|
||||
.create_opts = &qcow_create_opts,
|
||||
.strong_runtime_opts = qcow_strong_runtime_opts,
|
||||
};
|
||||
|
||||
static void bdrv_qcow_init(void)
|
||||
|
||||
+85
-4
@@ -1474,13 +1474,15 @@ static int coroutine_fn qcow2_do_open(BlockDriverState *bs, QDict *options,
|
||||
goto fail;
|
||||
}
|
||||
ret = bdrv_pread(bs->file, header.backing_file_offset,
|
||||
bs->backing_file, len);
|
||||
bs->auto_backing_file, len);
|
||||
if (ret < 0) {
|
||||
error_setg_errno(errp, -ret, "Could not read backing file name");
|
||||
goto fail;
|
||||
}
|
||||
bs->backing_file[len] = '\0';
|
||||
s->image_backing_file = g_strdup(bs->backing_file);
|
||||
bs->auto_backing_file[len] = '\0';
|
||||
pstrcpy(bs->backing_file, sizeof(bs->backing_file),
|
||||
bs->auto_backing_file);
|
||||
s->image_backing_file = g_strdup(bs->auto_backing_file);
|
||||
}
|
||||
|
||||
/* Internal snapshots */
|
||||
@@ -2518,6 +2520,8 @@ static int qcow2_change_backing_file(BlockDriverState *bs,
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
pstrcpy(bs->auto_backing_file, sizeof(bs->auto_backing_file),
|
||||
backing_file ?: "");
|
||||
pstrcpy(bs->backing_file, sizeof(bs->backing_file), backing_file ?: "");
|
||||
pstrcpy(bs->backing_format, sizeof(bs->backing_format), backing_fmt ?: "");
|
||||
|
||||
@@ -4232,6 +4236,60 @@ static coroutine_fn int qcow2_co_flush_to_os(BlockDriverState *bs)
|
||||
return ret;
|
||||
}
|
||||
|
||||
static ssize_t qcow2_measure_crypto_hdr_init_func(QCryptoBlock *block,
|
||||
size_t headerlen, void *opaque, Error **errp)
|
||||
{
|
||||
size_t *headerlenp = opaque;
|
||||
|
||||
/* Stash away the payload size */
|
||||
*headerlenp = headerlen;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static ssize_t qcow2_measure_crypto_hdr_write_func(QCryptoBlock *block,
|
||||
size_t offset, const uint8_t *buf, size_t buflen,
|
||||
void *opaque, Error **errp)
|
||||
{
|
||||
/* Discard the bytes, we're not actually writing to an image */
|
||||
return buflen;
|
||||
}
|
||||
|
||||
/* Determine the number of bytes for the LUKS payload */
|
||||
static bool qcow2_measure_luks_headerlen(QemuOpts *opts, size_t *len,
|
||||
Error **errp)
|
||||
{
|
||||
QDict *opts_qdict;
|
||||
QDict *cryptoopts_qdict;
|
||||
QCryptoBlockCreateOptions *cryptoopts;
|
||||
QCryptoBlock *crypto;
|
||||
|
||||
/* Extract "encrypt." options into a qdict */
|
||||
opts_qdict = qemu_opts_to_qdict(opts, NULL);
|
||||
qdict_extract_subqdict(opts_qdict, &cryptoopts_qdict, "encrypt.");
|
||||
qobject_unref(opts_qdict);
|
||||
|
||||
/* Build QCryptoBlockCreateOptions object from qdict */
|
||||
qdict_put_str(cryptoopts_qdict, "format", "luks");
|
||||
cryptoopts = block_crypto_create_opts_init(cryptoopts_qdict, errp);
|
||||
qobject_unref(cryptoopts_qdict);
|
||||
if (!cryptoopts) {
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Fake LUKS creation in order to determine the payload size */
|
||||
crypto = qcrypto_block_create(cryptoopts, "encrypt.",
|
||||
qcow2_measure_crypto_hdr_init_func,
|
||||
qcow2_measure_crypto_hdr_write_func,
|
||||
len, errp);
|
||||
qapi_free_QCryptoBlockCreateOptions(cryptoopts);
|
||||
if (!crypto) {
|
||||
return false;
|
||||
}
|
||||
|
||||
qcrypto_block_free(crypto);
|
||||
return true;
|
||||
}
|
||||
|
||||
static BlockMeasureInfo *qcow2_measure(QemuOpts *opts, BlockDriverState *in_bs,
|
||||
Error **errp)
|
||||
{
|
||||
@@ -4241,11 +4299,13 @@ static BlockMeasureInfo *qcow2_measure(QemuOpts *opts, BlockDriverState *in_bs,
|
||||
uint64_t virtual_size; /* disk size as seen by guest */
|
||||
uint64_t refcount_bits;
|
||||
uint64_t l2_tables;
|
||||
uint64_t luks_payload_size = 0;
|
||||
size_t cluster_size;
|
||||
int version;
|
||||
char *optstr;
|
||||
PreallocMode prealloc;
|
||||
bool has_backing_file;
|
||||
bool has_luks;
|
||||
|
||||
/* Parse image creation options */
|
||||
cluster_size = qcow2_opt_get_cluster_size_del(opts, &local_err);
|
||||
@@ -4275,6 +4335,20 @@ static BlockMeasureInfo *qcow2_measure(QemuOpts *opts, BlockDriverState *in_bs,
|
||||
has_backing_file = !!optstr;
|
||||
g_free(optstr);
|
||||
|
||||
optstr = qemu_opt_get_del(opts, BLOCK_OPT_ENCRYPT_FORMAT);
|
||||
has_luks = optstr && strcmp(optstr, "luks") == 0;
|
||||
g_free(optstr);
|
||||
|
||||
if (has_luks) {
|
||||
size_t headerlen;
|
||||
|
||||
if (!qcow2_measure_luks_headerlen(opts, &headerlen, &local_err)) {
|
||||
goto err;
|
||||
}
|
||||
|
||||
luks_payload_size = ROUND_UP(headerlen, cluster_size);
|
||||
}
|
||||
|
||||
virtual_size = qemu_opt_get_size_del(opts, BLOCK_OPT_SIZE, 0);
|
||||
virtual_size = ROUND_UP(virtual_size, cluster_size);
|
||||
|
||||
@@ -4345,7 +4419,7 @@ static BlockMeasureInfo *qcow2_measure(QemuOpts *opts, BlockDriverState *in_bs,
|
||||
info = g_new(BlockMeasureInfo, 1);
|
||||
info->fully_allocated =
|
||||
qcow2_calc_prealloc_size(virtual_size, cluster_size,
|
||||
ctz32(refcount_bits));
|
||||
ctz32(refcount_bits)) + luks_payload_size;
|
||||
|
||||
/* Remove data clusters that are not required. This overestimates the
|
||||
* required size because metadata needed for the fully allocated file is
|
||||
@@ -4932,6 +5006,12 @@ static QemuOptsList qcow2_create_opts = {
|
||||
}
|
||||
};
|
||||
|
||||
static const char *const qcow2_strong_runtime_opts[] = {
|
||||
"encrypt." BLOCK_CRYPTO_OPT_QCOW_KEY_SECRET,
|
||||
|
||||
NULL
|
||||
};
|
||||
|
||||
BlockDriver bdrv_qcow2 = {
|
||||
.format_name = "qcow2",
|
||||
.instance_size = sizeof(BDRVQcow2State),
|
||||
@@ -4980,6 +5060,7 @@ BlockDriver bdrv_qcow2 = {
|
||||
.bdrv_inactivate = qcow2_inactivate,
|
||||
|
||||
.create_opts = &qcow2_create_opts,
|
||||
.strong_runtime_opts = qcow2_strong_runtime_opts,
|
||||
.bdrv_co_check = qcow2_co_check,
|
||||
.bdrv_amend_options = qcow2_amend_options,
|
||||
|
||||
|
||||
+5
-2
@@ -454,11 +454,14 @@ static int coroutine_fn bdrv_qed_do_open(BlockDriverState *bs, QDict *options,
|
||||
}
|
||||
|
||||
ret = qed_read_string(bs->file, s->header.backing_filename_offset,
|
||||
s->header.backing_filename_size, bs->backing_file,
|
||||
sizeof(bs->backing_file));
|
||||
s->header.backing_filename_size,
|
||||
bs->auto_backing_file,
|
||||
sizeof(bs->auto_backing_file));
|
||||
if (ret < 0) {
|
||||
return ret;
|
||||
}
|
||||
pstrcpy(bs->backing_file, sizeof(bs->backing_file),
|
||||
bs->auto_backing_file);
|
||||
|
||||
if (s->header.features & QED_F_BACKING_FORMAT_NO_PROBE) {
|
||||
pstrcpy(bs->backing_format, sizeof(bs->backing_format), "raw");
|
||||
|
||||
+52
-21
@@ -1065,36 +1065,64 @@ static void quorum_del_child(BlockDriverState *bs, BdrvChild *child,
|
||||
bdrv_drained_end(bs);
|
||||
}
|
||||
|
||||
static void quorum_refresh_filename(BlockDriverState *bs, QDict *options)
|
||||
static void quorum_gather_child_options(BlockDriverState *bs, QDict *target,
|
||||
bool backing_overridden)
|
||||
{
|
||||
BDRVQuorumState *s = bs->opaque;
|
||||
QDict *opts;
|
||||
QList *children;
|
||||
QList *children_list;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < s->num_children; i++) {
|
||||
bdrv_refresh_filename(s->children[i]->bs);
|
||||
if (!s->children[i]->bs->full_open_options) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
/*
|
||||
* The generic implementation for gathering child options in
|
||||
* bdrv_refresh_filename() would use the names of the children
|
||||
* as specified for bdrv_open_child() or bdrv_attach_child(),
|
||||
* which is "children.%u" with %u being a value
|
||||
* (s->next_child_index) that is incremented each time a new child
|
||||
* is added (and never decremented). Since children can be
|
||||
* deleted at runtime, there may be gaps in that enumeration.
|
||||
* When creating a new quorum BDS and specifying the children for
|
||||
* it through runtime options, the enumeration used there may not
|
||||
* have any gaps, though.
|
||||
*
|
||||
* Therefore, we have to create a new gap-less enumeration here
|
||||
* (which we can achieve by simply putting all of the children's
|
||||
* full_open_options into a QList).
|
||||
*
|
||||
* XXX: Note that there are issues with the current child option
|
||||
* structure quorum uses (such as the fact that children do
|
||||
* not really have unique permanent names). Therefore, this
|
||||
* is going to have to change in the future and ideally we
|
||||
* want quorum to be covered by the generic implementation.
|
||||
*/
|
||||
|
||||
children_list = qlist_new();
|
||||
qdict_put(target, "children", children_list);
|
||||
|
||||
children = qlist_new();
|
||||
for (i = 0; i < s->num_children; i++) {
|
||||
qlist_append(children,
|
||||
qlist_append(children_list,
|
||||
qobject_ref(s->children[i]->bs->full_open_options));
|
||||
}
|
||||
|
||||
opts = qdict_new();
|
||||
qdict_put_str(opts, "driver", "quorum");
|
||||
qdict_put_int(opts, QUORUM_OPT_VOTE_THRESHOLD, s->threshold);
|
||||
qdict_put_bool(opts, QUORUM_OPT_BLKVERIFY, s->is_blkverify);
|
||||
qdict_put_bool(opts, QUORUM_OPT_REWRITE, s->rewrite_corrupted);
|
||||
qdict_put(opts, "children", children);
|
||||
|
||||
bs->full_open_options = opts;
|
||||
}
|
||||
|
||||
static char *quorum_dirname(BlockDriverState *bs, Error **errp)
|
||||
{
|
||||
/* In general, there are multiple BDSs with different dirnames below this
|
||||
* one; so there is no unique dirname we could return (unless all are equal
|
||||
* by chance, or there is only one). Therefore, to be consistent, just
|
||||
* always return NULL. */
|
||||
error_setg(errp, "Cannot generate a base directory for quorum nodes");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static const char *const quorum_strong_runtime_opts[] = {
|
||||
QUORUM_OPT_VOTE_THRESHOLD,
|
||||
QUORUM_OPT_BLKVERIFY,
|
||||
QUORUM_OPT_REWRITE,
|
||||
QUORUM_OPT_READ_PATTERN,
|
||||
|
||||
NULL
|
||||
};
|
||||
|
||||
static BlockDriver bdrv_quorum = {
|
||||
.format_name = "quorum",
|
||||
|
||||
@@ -1102,7 +1130,8 @@ static BlockDriver bdrv_quorum = {
|
||||
|
||||
.bdrv_open = quorum_open,
|
||||
.bdrv_close = quorum_close,
|
||||
.bdrv_refresh_filename = quorum_refresh_filename,
|
||||
.bdrv_gather_child_options = quorum_gather_child_options,
|
||||
.bdrv_dirname = quorum_dirname,
|
||||
|
||||
.bdrv_co_flush_to_disk = quorum_co_flush,
|
||||
|
||||
@@ -1118,6 +1147,8 @@ static BlockDriver bdrv_quorum = {
|
||||
|
||||
.is_filter = true,
|
||||
.bdrv_recurse_is_first_non_filter = quorum_recurse_is_first_non_filter,
|
||||
|
||||
.strong_runtime_opts = quorum_strong_runtime_opts,
|
||||
};
|
||||
|
||||
static void bdrv_quorum_init(void)
|
||||
|
||||
+10
-1
@@ -436,6 +436,7 @@ static int raw_open(BlockDriverState *bs, QDict *options, int flags,
|
||||
bs->file->bs->supported_zero_flags);
|
||||
|
||||
if (bs->probed && !bdrv_is_read_only(bs)) {
|
||||
bdrv_refresh_filename(bs->file->bs);
|
||||
fprintf(stderr,
|
||||
"WARNING: Image format was not specified for '%s' and probing "
|
||||
"guessed raw.\n"
|
||||
@@ -531,6 +532,13 @@ static int coroutine_fn raw_co_copy_range_to(BlockDriverState *bs,
|
||||
read_flags, write_flags);
|
||||
}
|
||||
|
||||
static const char *const raw_strong_runtime_opts[] = {
|
||||
"offset",
|
||||
"size",
|
||||
|
||||
NULL
|
||||
};
|
||||
|
||||
BlockDriver bdrv_raw = {
|
||||
.format_name = "raw",
|
||||
.instance_size = sizeof(BDRVRawState),
|
||||
@@ -560,7 +568,8 @@ BlockDriver bdrv_raw = {
|
||||
.bdrv_lock_medium = &raw_lock_medium,
|
||||
.bdrv_co_ioctl = &raw_co_ioctl,
|
||||
.create_opts = &raw_create_opts,
|
||||
.bdrv_has_zero_init = &raw_has_zero_init
|
||||
.bdrv_has_zero_init = &raw_has_zero_init,
|
||||
.strong_runtime_opts = raw_strong_runtime_opts,
|
||||
};
|
||||
|
||||
static void bdrv_raw_init(void)
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user