Skip to content

Commit

Permalink
Merge remote-tracking branch 'remotes/kevin/tags/for-upstream' into s…
Browse files Browse the repository at this point in the history
…taging

Block layer patches and object-add QAPIfication

- QAPIfy object-add and --object for tools (keyval and JSON support)
- Add vhost-user-blk-test
- stream: Fail gracefully if permission is denied
- storage-daemon: Fix crash on quit when job is still running
- curl: Fix use after free
- char: Deprecate backend aliases, fix QMP query-chardev-backends
- Fix image creation option defaults that exist in both the format and
  the protocol layer (e.g. 'cluster_size' in qcow2 and rbd; the qcow2
  default was incorrectly applied to the rbd layer)

# gpg: Signature made Mon 15 Mar 2021 12:27:38 GMT
# gpg:                using RSA key DC3DEB159A9AF95D3D7456FE7F09B272C88F2FD6
# gpg:                issuer "kwolf@redhat.com"
# gpg: Good signature from "Kevin Wolf <kwolf@redhat.com>" [full]
# Primary key fingerprint: DC3D EB15 9A9A F95D 3D74  56FE 7F09 B272 C88F 2FD6

* remotes/kevin/tags/for-upstream: (42 commits)
  qom: Support JSON in HMP object_add and tools --object
  char: Simplify chardev_name_foreach()
  char: Deprecate backend aliases 'tty' and 'parport'
  char: Skip CLI aliases in query-chardev-backends
  qom: Add user_creatable_parse_str()
  hmp: QAPIfy object_add
  qemu-img: Use user_creatable_process_cmdline() for --object
  qom: Add user_creatable_add_from_str()
  qemu-nbd: Use user_creatable_process_cmdline() for --object
  qemu-io: Use user_creatable_process_cmdline() for --object
  qom: Factor out user_creatable_process_cmdline()
  qom: Remove user_creatable_add_dict()
  qemu-storage-daemon: Implement --object with qmp_object_add()
  qom: Make "object" QemuOptsList optional
  qapi/qom: QAPIfy object-add
  qapi/qom: Add ObjectOptions for x-remote-object
  qapi/qom: Add ObjectOptions for input-*
  qapi/qom: Add ObjectOptions for confidential-guest-support
  qapi/qom: Add ObjectOptions for pr-manager-helper
  qapi/qom: Add ObjectOptions for filter-*
  ...

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
  • Loading branch information
pm215 committed Mar 16, 2021
2 parents 6e31b3a + 078ee48 commit 0f8247d
Show file tree
Hide file tree
Showing 39 changed files with 2,581 additions and 558 deletions.
2 changes: 2 additions & 0 deletions MAINTAINERS
Expand Up @@ -3232,6 +3232,8 @@ F: block/export/vhost-user-blk-server.c
F: block/export/vhost-user-blk-server.h
F: include/qemu/vhost-user-server.h
F: tests/qtest/libqos/vhost-user-blk.c
F: tests/qtest/libqos/vhost-user-blk.h
F: tests/qtest/vhost-user-blk-test.c
F: util/vhost-user-server.c

FUSE block device exports
Expand Down
36 changes: 35 additions & 1 deletion block.c
Expand Up @@ -670,14 +670,48 @@ int coroutine_fn bdrv_co_create_opts_simple(BlockDriver *drv,

int bdrv_create_file(const char *filename, QemuOpts *opts, Error **errp)
{
QemuOpts *protocol_opts;
BlockDriver *drv;
QDict *qdict;
int ret;

drv = bdrv_find_protocol(filename, true, errp);
if (drv == NULL) {
return -ENOENT;
}

return bdrv_create(drv, filename, opts, errp);
if (!drv->create_opts) {
error_setg(errp, "Driver '%s' does not support image creation",
drv->format_name);
return -ENOTSUP;
}

/*
* 'opts' contains a QemuOptsList with a combination of format and protocol
* default values.
*
* The format properly removes its options, but the default values remain
* in 'opts->list'. So if the protocol has options with the same name
* (e.g. rbd has 'cluster_size' as qcow2), it will see the default values
* of the format, since for overlapping options, the format wins.
*
* To avoid this issue, lets convert QemuOpts to QDict, in this way we take
* only the set options, and then convert it back to QemuOpts, using the
* create_opts of the protocol. So the new QemuOpts, will contain only the
* protocol defaults.
*/
qdict = qemu_opts_to_qdict(opts, NULL);
protocol_opts = qemu_opts_from_qdict(drv->create_opts, qdict, errp);
if (protocol_opts == NULL) {
ret = -EINVAL;
goto out;
}

ret = bdrv_create(drv, filename, protocol_opts, errp);
out:
qemu_opts_del(protocol_opts);
qobject_unref(qdict);
return ret;
}

int coroutine_fn bdrv_co_delete_file(BlockDriverState *bs, Error **errp)
Expand Down
50 changes: 28 additions & 22 deletions block/curl.c
Expand Up @@ -78,16 +78,14 @@ typedef struct CURLAIOCB {

typedef struct CURLSocket {
int fd;
struct CURLState *state;
QLIST_ENTRY(CURLSocket) next;
struct BDRVCURLState *s;
} CURLSocket;

typedef struct CURLState
{
struct BDRVCURLState *s;
CURLAIOCB *acb[CURL_NUM_ACB];
CURL *curl;
QLIST_HEAD(, CURLSocket) sockets;
char *orig_buf;
uint64_t buf_start;
size_t buf_off;
Expand All @@ -102,6 +100,7 @@ typedef struct BDRVCURLState {
QEMUTimer timer;
uint64_t len;
CURLState states[CURL_NUM_STATES];
GHashTable *sockets; /* GINT_TO_POINTER(fd) -> socket */
char *url;
size_t readahead_size;
bool sslverify;
Expand All @@ -120,6 +119,21 @@ typedef struct BDRVCURLState {
static void curl_clean_state(CURLState *s);
static void curl_multi_do(void *arg);

static gboolean curl_drop_socket(void *key, void *value, void *opaque)
{
CURLSocket *socket = value;
BDRVCURLState *s = socket->s;

aio_set_fd_handler(s->aio_context, socket->fd, false,
NULL, NULL, NULL, NULL);
return true;
}

static void curl_drop_all_sockets(GHashTable *sockets)
{
g_hash_table_foreach_remove(sockets, curl_drop_socket, NULL);
}

/* Called from curl_multi_do_locked, with s->mutex held. */
static int curl_timer_cb(CURLM *multi, long timeout_ms, void *opaque)
{
Expand Down Expand Up @@ -147,16 +161,12 @@ static int curl_sock_cb(CURL *curl, curl_socket_t fd, int action,
curl_easy_getinfo(curl, CURLINFO_PRIVATE, (char **)&state);
s = state->s;

QLIST_FOREACH(socket, &state->sockets, next) {
if (socket->fd == fd) {
break;
}
}
socket = g_hash_table_lookup(s->sockets, GINT_TO_POINTER(fd));
if (!socket) {
socket = g_new0(CURLSocket, 1);
socket->fd = fd;
socket->state = state;
QLIST_INSERT_HEAD(&state->sockets, socket, next);
socket->s = s;
g_hash_table_insert(s->sockets, GINT_TO_POINTER(fd), socket);
}

trace_curl_sock_cb(action, (int)fd);
Expand All @@ -180,8 +190,7 @@ static int curl_sock_cb(CURL *curl, curl_socket_t fd, int action,
}

if (action == CURL_POLL_REMOVE) {
QLIST_REMOVE(socket, next);
g_free(socket);
g_hash_table_remove(s->sockets, GINT_TO_POINTER(fd));
}

return 0;
Expand Down Expand Up @@ -385,7 +394,7 @@ static void curl_multi_check_completion(BDRVCURLState *s)
/* Called with s->mutex held. */
static void curl_multi_do_locked(CURLSocket *socket)
{
BDRVCURLState *s = socket->state->s;
BDRVCURLState *s = socket->s;
int running;
int r;

Expand All @@ -401,7 +410,7 @@ static void curl_multi_do_locked(CURLSocket *socket)
static void curl_multi_do(void *arg)
{
CURLSocket *socket = arg;
BDRVCURLState *s = socket->state->s;
BDRVCURLState *s = socket->s;

qemu_mutex_lock(&s->mutex);
curl_multi_do_locked(socket);
Expand Down Expand Up @@ -498,7 +507,6 @@ static int curl_init_state(BDRVCURLState *s, CURLState *state)
#endif
}

QLIST_INIT(&state->sockets);
state->s = s;

return 0;
Expand All @@ -515,13 +523,6 @@ static void curl_clean_state(CURLState *s)
if (s->s->multi)
curl_multi_remove_handle(s->s->multi, s->curl);

while (!QLIST_EMPTY(&s->sockets)) {
CURLSocket *socket = QLIST_FIRST(&s->sockets);

QLIST_REMOVE(socket, next);
g_free(socket);
}

s->in_use = 0;

qemu_co_enter_next(&s->s->free_state_waitq, &s->s->mutex);
Expand All @@ -539,6 +540,7 @@ static void curl_detach_aio_context(BlockDriverState *bs)
int i;

WITH_QEMU_LOCK_GUARD(&s->mutex) {
curl_drop_all_sockets(s->sockets);
for (i = 0; i < CURL_NUM_STATES; i++) {
if (s->states[i].in_use) {
curl_clean_state(&s->states[i]);
Expand Down Expand Up @@ -745,6 +747,7 @@ static int curl_open(BlockDriverState *bs, QDict *options, int flags,
qemu_co_queue_init(&s->free_state_waitq);
s->aio_context = bdrv_get_aio_context(bs);
s->url = g_strdup(file);
s->sockets = g_hash_table_new_full(NULL, NULL, NULL, g_free);
qemu_mutex_lock(&s->mutex);
state = curl_find_state(s);
qemu_mutex_unlock(&s->mutex);
Expand Down Expand Up @@ -818,6 +821,8 @@ static int curl_open(BlockDriverState *bs, QDict *options, int flags,
g_free(s->username);
g_free(s->proxyusername);
g_free(s->proxypassword);
curl_drop_all_sockets(s->sockets);
g_hash_table_destroy(s->sockets);
qemu_opts_del(opts);
return -EINVAL;
}
Expand Down Expand Up @@ -916,6 +921,7 @@ static void curl_close(BlockDriverState *bs)
curl_detach_aio_context(bs);
qemu_mutex_destroy(&s->mutex);

g_hash_table_destroy(s->sockets);
g_free(s->cookie);
g_free(s->url);
g_free(s->username);
Expand Down
3 changes: 1 addition & 2 deletions block/export/vhost-user-blk-server.c
Expand Up @@ -345,8 +345,7 @@ static uint64_t vu_blk_get_features(VuDev *dev)

static uint64_t vu_blk_get_protocol_features(VuDev *dev)
{
return 1ull << VHOST_USER_PROTOCOL_F_CONFIG |
1ull << VHOST_USER_PROTOCOL_F_INFLIGHT_SHMFD;
return 1ull << VHOST_USER_PROTOCOL_F_CONFIG;
}

static int
Expand Down
15 changes: 11 additions & 4 deletions block/stream.c
Expand Up @@ -206,14 +206,15 @@ void stream_start(const char *job_id, BlockDriverState *bs,
const char *filter_node_name,
Error **errp)
{
StreamBlockJob *s;
StreamBlockJob *s = NULL;
BlockDriverState *iter;
bool bs_read_only;
int basic_flags = BLK_PERM_CONSISTENT_READ | BLK_PERM_WRITE_UNCHANGED;
BlockDriverState *base_overlay;
BlockDriverState *cor_filter_bs = NULL;
BlockDriverState *above_base;
QDict *opts;
int ret;

assert(!(base && bottom));
assert(!(backing_file_str && bottom));
Expand Down Expand Up @@ -303,7 +304,7 @@ void stream_start(const char *job_id, BlockDriverState *bs,
* queried only at the job start and then cached.
*/
if (block_job_add_bdrv(&s->common, "active node", bs, 0,
basic_flags | BLK_PERM_WRITE, &error_abort)) {
basic_flags | BLK_PERM_WRITE, errp)) {
goto fail;
}

Expand All @@ -320,8 +321,11 @@ void stream_start(const char *job_id, BlockDriverState *bs,
for (iter = bdrv_filter_or_cow_bs(bs); iter != base;
iter = bdrv_filter_or_cow_bs(iter))
{
block_job_add_bdrv(&s->common, "intermediate node", iter, 0,
basic_flags, &error_abort);
ret = block_job_add_bdrv(&s->common, "intermediate node", iter, 0,
basic_flags, errp);
if (ret < 0) {
goto fail;
}
}

s->base_overlay = base_overlay;
Expand All @@ -337,6 +341,9 @@ void stream_start(const char *job_id, BlockDriverState *bs,
return;

fail:
if (s) {
job_early_fail(&s->common.job);
}
if (cor_filter_bs) {
bdrv_cor_filter_drop(cor_filter_bs);
}
Expand Down
19 changes: 11 additions & 8 deletions chardev/char.c
Expand Up @@ -534,9 +534,10 @@ static const ChardevClass *char_get_class(const char *driver, Error **errp)
return cc;
}

static const struct ChardevAlias {
static struct ChardevAlias {
const char *typename;
const char *alias;
bool deprecation_warning_printed;
} chardev_alias_table[] = {
#ifdef HAVE_CHARDEV_PARPORT
{ "parallel", "parport" },
Expand Down Expand Up @@ -565,16 +566,12 @@ chardev_class_foreach(ObjectClass *klass, void *opaque)
}

static void
chardev_name_foreach(void (*fn)(const char *name, void *opaque), void *opaque)
chardev_name_foreach(void (*fn)(const char *name, void *opaque),
void *opaque)
{
ChadevClassFE fe = { .fn = fn, .opaque = opaque };
int i;

object_class_foreach(chardev_class_foreach, TYPE_CHARDEV, false, &fe);

for (i = 0; i < (int)ARRAY_SIZE(chardev_alias_table); i++) {
fn(chardev_alias_table[i].alias, opaque);
}
}

static void
Expand All @@ -590,6 +587,11 @@ static const char *chardev_alias_translate(const char *name)
int i;
for (i = 0; i < (int)ARRAY_SIZE(chardev_alias_table); i++) {
if (g_strcmp0(chardev_alias_table[i].alias, name) == 0) {
if (!chardev_alias_table[i].deprecation_warning_printed) {
warn_report("The alias '%s' is deprecated, use '%s' instead",
name, chardev_alias_table[i].typename);
chardev_alias_table[i].deprecation_warning_printed = true;
}
return chardev_alias_table[i].typename;
}
}
Expand Down Expand Up @@ -801,8 +803,9 @@ static void
qmp_prepend_backend(const char *name, void *opaque)
{
ChardevBackendInfoList **list = opaque;
ChardevBackendInfo *value = g_new0(ChardevBackendInfo, 1);
ChardevBackendInfo *value;

value = g_new0(ChardevBackendInfo, 1);
value->name = g_strdup(name);
QAPI_LIST_PREPEND(*list, value);
}
Expand Down
31 changes: 26 additions & 5 deletions docs/system/deprecated.rst
Expand Up @@ -75,6 +75,12 @@ The ``pretty=on|off`` switch has no effect for HMP monitors, but is
silently ignored. Using the switch with HMP monitors will become an
error in the future.

``-chardev`` backend aliases ``tty`` and ``parport`` (since 6.0)
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''

``tty`` and ``parport`` are aliases that will be removed. Instead, the
actual backend names ``serial`` and ``parallel`` should be used.

RISC-V ``-bios`` (since 5.1)
''''''''''''''''''''''''''''

Expand Down Expand Up @@ -174,6 +180,26 @@ Input parameters that take a size value should only use a size suffix
the value is hexadecimal. That is, '0x20M' is deprecated, and should
be written either as '32M' or as '0x2000000'.

``opened`` property of ``rng-*`` objects (since 6.0.0)
''''''''''''''''''''''''''''''''''''''''''''''''''''''

The only effect of specifying ``opened=on`` in the command line or QMP
``object-add`` is that the device is opened immediately, possibly before all
other options have been processed. This will either have no effect (if
``opened`` was the last option) or cause errors. The property is therefore
useless and should not be specified.

``loaded`` property of ``secret`` and ``secret_keyring`` objects (since 6.0.0)
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''

The only effect of specifying ``loaded=on`` in the command line or QMP
``object-add`` is that the secret is loaded immediately, possibly before all
other options have been processed. This will either have no effect (if
``loaded`` was the last option) or cause options to be effectively ignored as
if they were not given. The property is therefore useless and should not be
specified.


QEMU Machine Protocol (QMP) commands
------------------------------------

Expand Down Expand Up @@ -227,11 +253,6 @@ Use ``migrate-set-parameters`` and ``query-migrate-parameters`` instead.

Use arguments ``base-node`` and ``top-node`` instead.

``object-add`` option ``props`` (since 5.0)
'''''''''''''''''''''''''''''''''''''''''''

Specify the properties for the object as top-level arguments instead.

``query-named-block-nodes`` and ``query-block`` result dirty-bitmaps[i].status (since 4.0)
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''

Expand Down
5 changes: 5 additions & 0 deletions docs/system/removed-features.rst
Expand Up @@ -58,6 +58,11 @@ documentation of ``query-hotpluggable-cpus`` for additional details.

Use ``blockdev-change-medium`` or ``change-vnc-password`` instead.

``object-add`` option ``props`` (removed in 6.0)
''''''''''''''''''''''''''''''''''''''''''''''''

Specify the properties for the object as top-level arguments instead.

Human Monitor Protocol (HMP) commands
-------------------------------------

Expand Down
2 changes: 1 addition & 1 deletion docs/tools/qemu-img.rst
Expand Up @@ -404,7 +404,7 @@ Command description:
The following table sumarizes all exit codes of the compare subcommand:

0
Images are identical
Images are identical (or requested help was printed)
1
Images differ
2
Expand Down

0 comments on commit 0f8247d

Please sign in to comment.