mirror of
https://github.com/izzy2lost/xemu.git
synced 2026-07-06 00:20:22 -07:00
Merge remote-tracking branch 'remotes/kevin/tags/for-upstream' into staging
Block layer patches and object-add QAPIfication - QAPIfy object-add and --object - 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 Fri 19 Mar 2021 09:18:22 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) vl: allow passing JSON to -object qom: move user_creatable_add_opts logic to vl.c and QAPIfy it tests: convert check-qom-proplist to keyval 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-* ... Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
@@ -670,14 +670,48 @@ out:
|
||||
|
||||
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)
|
||||
|
||||
+28
-22
@@ -78,8 +78,7 @@ typedef struct CURLAIOCB {
|
||||
|
||||
typedef struct CURLSocket {
|
||||
int fd;
|
||||
struct CURLState *state;
|
||||
QLIST_ENTRY(CURLSocket) next;
|
||||
struct BDRVCURLState *s;
|
||||
} CURLSocket;
|
||||
|
||||
typedef struct CURLState
|
||||
@@ -87,7 +86,6 @@ 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;
|
||||
@@ -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;
|
||||
@@ -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)
|
||||
{
|
||||
@@ -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);
|
||||
@@ -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;
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
@@ -498,7 +507,6 @@ static int curl_init_state(BDRVCURLState *s, CURLState *state)
|
||||
#endif
|
||||
}
|
||||
|
||||
QLIST_INIT(&state->sockets);
|
||||
state->s = s;
|
||||
|
||||
return 0;
|
||||
@@ -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);
|
||||
@@ -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]);
|
||||
@@ -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);
|
||||
@@ -818,6 +821,8 @@ out_noclean:
|
||||
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;
|
||||
}
|
||||
@@ -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);
|
||||
|
||||
@@ -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
|
||||
|
||||
+11
-4
@@ -206,7 +206,7 @@ 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;
|
||||
@@ -214,6 +214,7 @@ void stream_start(const char *job_id, BlockDriverState *bs,
|
||||
BlockDriverState *cor_filter_bs = NULL;
|
||||
BlockDriverState *above_base;
|
||||
QDict *opts;
|
||||
int ret;
|
||||
|
||||
assert(!(base && bottom));
|
||||
assert(!(backing_file_str && bottom));
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
+11
-8
@@ -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" },
|
||||
@@ -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
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -46,6 +46,12 @@ needs two devices (``-device intel-hda -device hda-duplex``) and
|
||||
``pcspk`` which can be activated using ``-machine
|
||||
pcspk-audiodev=<name>``.
|
||||
|
||||
``-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)
|
||||
''''''''''''''''''''''''''''
|
||||
|
||||
@@ -153,6 +159,26 @@ the process listing. This is replaced by the new ``password-secret``
|
||||
option which lets the password be securely provided on the command
|
||||
line using a ``secret`` object instance.
|
||||
|
||||
``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
|
||||
------------------------------------
|
||||
|
||||
@@ -186,11 +212,6 @@ Use argument value ``null`` 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.
|
||||
|
||||
``nbd-server-add`` and ``nbd-server-remove`` (since 5.2)
|
||||
''''''''''''''''''''''''''''''''''''''''''''''''''''''''
|
||||
|
||||
|
||||
@@ -143,6 +143,11 @@ field of the ``BlockDeviceInfo`` struct should be used instead, which is the
|
||||
type of the ``inserted`` field in query-block replies, as well as the
|
||||
type of array items in query-named-block-nodes.
|
||||
|
||||
``object-add`` option ``props`` (removed in 6.0)
|
||||
''''''''''''''''''''''''''''''''''''''''''''''''
|
||||
|
||||
Specify the properties for the object as top-level arguments instead.
|
||||
|
||||
Human Monitor Protocol (HMP) commands
|
||||
-------------------------------------
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
+1
-1
@@ -1292,7 +1292,7 @@ ERST
|
||||
|
||||
{
|
||||
.name = "object_add",
|
||||
.args_type = "object:O",
|
||||
.args_type = "object:S",
|
||||
.params = "[qom-type=]type,id=str[,prop=value][,...]",
|
||||
.help = "create QOM object",
|
||||
.cmd = hmp_object_add,
|
||||
|
||||
@@ -836,17 +836,17 @@ static XenBlockIOThread *xen_block_iothread_create(const char *id,
|
||||
{
|
||||
ERRP_GUARD();
|
||||
XenBlockIOThread *iothread = g_new(XenBlockIOThread, 1);
|
||||
QDict *opts;
|
||||
QObject *ret_data = NULL;
|
||||
ObjectOptions *opts;
|
||||
|
||||
iothread->id = g_strdup(id);
|
||||
|
||||
opts = qdict_new();
|
||||
qdict_put_str(opts, "qom-type", TYPE_IOTHREAD);
|
||||
qdict_put_str(opts, "id", id);
|
||||
qmp_object_add(opts, &ret_data, errp);
|
||||
qobject_unref(opts);
|
||||
qobject_unref(ret_data);
|
||||
opts = g_new(ObjectOptions, 1);
|
||||
*opts = (ObjectOptions) {
|
||||
.qom_type = OBJECT_TYPE_IOTHREAD,
|
||||
.id = g_strdup(id),
|
||||
};
|
||||
qmp_object_add(opts, errp);
|
||||
qapi_free_ObjectOptions(opts);
|
||||
|
||||
if (*errp) {
|
||||
g_free(iothread->id);
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
#define OBJECT_INTERFACES_H
|
||||
|
||||
#include "qom/object.h"
|
||||
#include "qapi/qapi-types-qom.h"
|
||||
#include "qapi/visitor.h"
|
||||
|
||||
#define TYPE_USER_CREATABLE "user-creatable"
|
||||
@@ -87,67 +88,60 @@ Object *user_creatable_add_type(const char *type, const char *id,
|
||||
Visitor *v, Error **errp);
|
||||
|
||||
/**
|
||||
* user_creatable_add_dict:
|
||||
* @qdict: the object definition
|
||||
* @keyval: if true, use a keyval visitor for processing @qdict (i.e.
|
||||
* assume that all @qdict values are strings); otherwise, use
|
||||
* the normal QObject visitor (i.e. assume all @qdict values
|
||||
* have the QType expected by the QOM object type)
|
||||
* user_creatable_add_qapi:
|
||||
* @options: the object definition
|
||||
* @errp: if an error occurs, a pointer to an area to store the error
|
||||
*
|
||||
* Create an instance of the user creatable object that is defined by
|
||||
* @qdict. The object type is taken from the QDict key 'qom-type', its
|
||||
* ID from the key 'id'. The remaining entries in @qdict are used to
|
||||
* initialize the object properties.
|
||||
*
|
||||
* Returns: %true on success, %false on failure.
|
||||
* Create an instance of the user creatable object according to the
|
||||
* options passed in @opts as described in the QAPI schema documentation.
|
||||
*/
|
||||
bool user_creatable_add_dict(QDict *qdict, bool keyval, Error **errp);
|
||||
void user_creatable_add_qapi(ObjectOptions *options, Error **errp);
|
||||
|
||||
/**
|
||||
* user_creatable_add_opts:
|
||||
* @opts: the object definition
|
||||
* user_creatable_parse_str:
|
||||
* @optarg: the object definition string as passed on the command line
|
||||
* @errp: if an error occurs, a pointer to an area to store the error
|
||||
*
|
||||
* Create an instance of the user creatable object whose type
|
||||
* is defined in @opts by the 'qom-type' option, placing it
|
||||
* in the object composition tree with name provided by the
|
||||
* 'id' field. The remaining options in @opts are used to
|
||||
* initialize the object properties.
|
||||
* Parses the option for the user creatable object with a keyval parser and
|
||||
* implicit key 'qom-type', converting the result to ObjectOptions.
|
||||
*
|
||||
* Returns: the newly created object or NULL on error
|
||||
* If a help option is given, print help instead.
|
||||
*
|
||||
* Returns: ObjectOptions on success, NULL when an error occurred (*errp is set
|
||||
* then) or help was printed (*errp is not set).
|
||||
*/
|
||||
Object *user_creatable_add_opts(QemuOpts *opts, Error **errp);
|
||||
|
||||
ObjectOptions *user_creatable_parse_str(const char *optarg, Error **errp);
|
||||
|
||||
/**
|
||||
* user_creatable_add_opts_predicate:
|
||||
* @type: the QOM type to be added
|
||||
* user_creatable_add_from_str:
|
||||
* @optarg: the object definition string as passed on the command line
|
||||
* @errp: if an error occurs, a pointer to an area to store the error
|
||||
*
|
||||
* A callback function to determine whether an object
|
||||
* of type @type should be created. Instances of this
|
||||
* callback should be passed to user_creatable_add_opts_foreach
|
||||
* Create an instance of the user creatable object by parsing optarg
|
||||
* with a keyval parser and implicit key 'qom-type', converting the
|
||||
* result to ObjectOptions and calling into qmp_object_add().
|
||||
*
|
||||
* If a help option is given, print help instead.
|
||||
*
|
||||
* Returns: true when an object was successfully created, false when an error
|
||||
* occurred (*errp is set then) or help was printed (*errp is not set).
|
||||
*/
|
||||
typedef bool (*user_creatable_add_opts_predicate)(const char *type);
|
||||
bool user_creatable_add_from_str(const char *optarg, Error **errp);
|
||||
|
||||
/**
|
||||
* user_creatable_add_opts_foreach:
|
||||
* @opaque: a user_creatable_add_opts_predicate callback or NULL
|
||||
* @opts: options to create
|
||||
* @errp: unused
|
||||
* user_creatable_process_cmdline:
|
||||
* @optarg: the object definition string as passed on the command line
|
||||
*
|
||||
* An iterator callback to be used in conjunction with
|
||||
* the qemu_opts_foreach() method for creating a list of
|
||||
* objects from a set of QemuOpts
|
||||
* Create an instance of the user creatable object by parsing optarg
|
||||
* with a keyval parser and implicit key 'qom-type', converting the
|
||||
* result to ObjectOptions and calling into qmp_object_add().
|
||||
*
|
||||
* The @opaque parameter can be passed a user_creatable_add_opts_predicate
|
||||
* callback to filter which types of object are created during iteration.
|
||||
* When it fails, report the error.
|
||||
* If a help option is given, print help instead and exit.
|
||||
*
|
||||
* Returns: 0 on success, -1 when an error was reported.
|
||||
* This function is only meant to be called during command line parsing.
|
||||
* It exits the process on failure or after printing help.
|
||||
*/
|
||||
int user_creatable_add_opts_foreach(void *opaque,
|
||||
QemuOpts *opts, Error **errp);
|
||||
void user_creatable_process_cmdline(const char *optarg);
|
||||
|
||||
/**
|
||||
* user_creatable_print_help:
|
||||
@@ -163,19 +157,6 @@ int user_creatable_add_opts_foreach(void *opaque,
|
||||
*/
|
||||
bool user_creatable_print_help(const char *type, QemuOpts *opts);
|
||||
|
||||
/**
|
||||
* user_creatable_print_help_from_qdict:
|
||||
* @args: options to create
|
||||
*
|
||||
* Prints help considering the other options given in @args (if "qom-type" is
|
||||
* given and valid, print properties for the type, otherwise print valid types)
|
||||
*
|
||||
* In contrast to user_creatable_print_help(), this function can't return that
|
||||
* no help was requested. It should only be called if we know that help is
|
||||
* requested and it will always print some help.
|
||||
*/
|
||||
void user_creatable_print_help_from_qdict(QDict *args);
|
||||
|
||||
/**
|
||||
* user_creatable_del:
|
||||
* @id: the unique ID for the object
|
||||
@@ -196,11 +177,4 @@ bool user_creatable_del(const char *id, Error **errp);
|
||||
*/
|
||||
void user_creatable_cleanup(void);
|
||||
|
||||
/**
|
||||
* qmp_object_add:
|
||||
*
|
||||
* QMP command handler for object-add. See the QAPI schema for documentation.
|
||||
*/
|
||||
void qmp_object_add(QDict *qdict, QObject **ret_data, Error **errp);
|
||||
|
||||
#endif
|
||||
|
||||
+2
-15
@@ -1636,24 +1636,11 @@ void hmp_netdev_del(Monitor *mon, const QDict *qdict)
|
||||
|
||||
void hmp_object_add(Monitor *mon, const QDict *qdict)
|
||||
{
|
||||
const char *options = qdict_get_str(qdict, "object");
|
||||
Error *err = NULL;
|
||||
QemuOpts *opts;
|
||||
Object *obj = NULL;
|
||||
|
||||
opts = qemu_opts_from_qdict(qemu_find_opts("object"), qdict, &err);
|
||||
if (err) {
|
||||
goto end;
|
||||
}
|
||||
|
||||
obj = user_creatable_add_opts(opts, &err);
|
||||
qemu_opts_del(opts);
|
||||
|
||||
end:
|
||||
user_creatable_add_from_str(options, &err);
|
||||
hmp_handle_error(mon, err);
|
||||
|
||||
if (obj) {
|
||||
object_unref(obj);
|
||||
}
|
||||
}
|
||||
|
||||
void hmp_getfd(Monitor *mon, const QDict *qdict)
|
||||
|
||||
@@ -235,8 +235,6 @@ static void monitor_init_qmp_commands(void)
|
||||
qmp_query_qmp_schema, QCO_ALLOW_PRECONFIG);
|
||||
qmp_register_command(&qmp_commands, "device_add", qmp_device_add,
|
||||
QCO_NO_OPTIONS);
|
||||
qmp_register_command(&qmp_commands, "object-add", qmp_object_add,
|
||||
QCO_NO_OPTIONS);
|
||||
|
||||
QTAILQ_INIT(&qmp_cap_negotiation_commands);
|
||||
qmp_register_command(&qmp_cap_negotiation_commands, "qmp_capabilities",
|
||||
|
||||
+56
-5
@@ -50,12 +50,63 @@
|
||||
'*format': 'QAuthZListFormat'}}
|
||||
|
||||
##
|
||||
# @QAuthZListRuleListHack:
|
||||
# @AuthZListProperties:
|
||||
#
|
||||
# Not exposed via QMP; hack to generate QAuthZListRuleList
|
||||
# for use internally by the code.
|
||||
# Properties for authz-list objects.
|
||||
#
|
||||
# @policy: Default policy to apply when no rule matches (default: deny)
|
||||
#
|
||||
# @rules: Authorization rules based on matching user
|
||||
#
|
||||
# Since: 4.0
|
||||
##
|
||||
{ 'struct': 'QAuthZListRuleListHack',
|
||||
'data': { 'unused': ['QAuthZListRule'] } }
|
||||
{ 'struct': 'AuthZListProperties',
|
||||
'data': { '*policy': 'QAuthZListPolicy',
|
||||
'*rules': ['QAuthZListRule'] } }
|
||||
|
||||
##
|
||||
# @AuthZListFileProperties:
|
||||
#
|
||||
# Properties for authz-listfile objects.
|
||||
#
|
||||
# @filename: File name to load the configuration from. The file must
|
||||
# contain valid JSON for AuthZListProperties.
|
||||
#
|
||||
# @refresh: If true, inotify is used to monitor the file, automatically
|
||||
# reloading changes. If an error occurs during reloading, all
|
||||
# authorizations will fail until the file is next successfully
|
||||
# loaded. (default: true if the binary was built with
|
||||
# CONFIG_INOTIFY1, false otherwise)
|
||||
#
|
||||
# Since: 4.0
|
||||
##
|
||||
{ 'struct': 'AuthZListFileProperties',
|
||||
'data': { 'filename': 'str',
|
||||
'*refresh': 'bool' } }
|
||||
|
||||
##
|
||||
# @AuthZPAMProperties:
|
||||
#
|
||||
# Properties for authz-pam objects.
|
||||
#
|
||||
# @service: PAM service name to use for authorization
|
||||
#
|
||||
# Since: 4.0
|
||||
##
|
||||
{ 'struct': 'AuthZPAMProperties',
|
||||
'data': { 'service': 'str' } }
|
||||
|
||||
##
|
||||
# @AuthZSimpleProperties:
|
||||
#
|
||||
# Properties for authz-simple objects.
|
||||
#
|
||||
# @identity: Identifies the allowed user. Its format depends on the network
|
||||
# service that authorization object is associated with. For
|
||||
# authorizing based on TLS x509 certificates, the identity must be
|
||||
# the x509 distinguished name.
|
||||
#
|
||||
# Since: 4.0
|
||||
##
|
||||
{ 'struct': 'AuthZSimpleProperties',
|
||||
'data': { 'identity': 'str' } }
|
||||
|
||||
@@ -2442,6 +2442,33 @@
|
||||
'*bps-write-max' : 'int', '*bps-write-max-length' : 'int',
|
||||
'*iops-size' : 'int' } }
|
||||
|
||||
##
|
||||
# @ThrottleGroupProperties:
|
||||
#
|
||||
# Properties for throttle-group objects.
|
||||
#
|
||||
# The options starting with x- are aliases for the same key without x- in
|
||||
# the @limits object. As indicated by the x- prefix, this is not a stable
|
||||
# interface and may be removed or changed incompatibly in the future. Use
|
||||
# @limits for a supported stable interface.
|
||||
#
|
||||
# @limits: limits to apply for this throttle group
|
||||
#
|
||||
# Since: 2.11
|
||||
##
|
||||
{ 'struct': 'ThrottleGroupProperties',
|
||||
'data': { '*limits': 'ThrottleLimits',
|
||||
'*x-iops-total' : 'int', '*x-iops-total-max' : 'int',
|
||||
'*x-iops-total-max-length' : 'int', '*x-iops-read' : 'int',
|
||||
'*x-iops-read-max' : 'int', '*x-iops-read-max-length' : 'int',
|
||||
'*x-iops-write' : 'int', '*x-iops-write-max' : 'int',
|
||||
'*x-iops-write-max-length' : 'int', '*x-bps-total' : 'int',
|
||||
'*x-bps-total-max' : 'int', '*x-bps-total-max-length' : 'int',
|
||||
'*x-bps-read' : 'int', '*x-bps-read-max' : 'int',
|
||||
'*x-bps-read-max-length' : 'int', '*x-bps-write' : 'int',
|
||||
'*x-bps-write-max' : 'int', '*x-bps-write-max-length' : 'int',
|
||||
'*x-iops-size' : 'int' } }
|
||||
|
||||
##
|
||||
# @block-stream:
|
||||
#
|
||||
|
||||
@@ -145,3 +145,55 @@
|
||||
##
|
||||
{ 'enum': 'PCIELinkWidth',
|
||||
'data': [ '1', '2', '4', '8', '12', '16', '32' ] }
|
||||
|
||||
##
|
||||
# @HostMemPolicy:
|
||||
#
|
||||
# Host memory policy types
|
||||
#
|
||||
# @default: restore default policy, remove any nondefault policy
|
||||
#
|
||||
# @preferred: set the preferred host nodes for allocation
|
||||
#
|
||||
# @bind: a strict policy that restricts memory allocation to the
|
||||
# host nodes specified
|
||||
#
|
||||
# @interleave: memory allocations are interleaved across the set
|
||||
# of host nodes specified
|
||||
#
|
||||
# Since: 2.1
|
||||
##
|
||||
{ 'enum': 'HostMemPolicy',
|
||||
'data': [ 'default', 'preferred', 'bind', 'interleave' ] }
|
||||
|
||||
##
|
||||
# @NetFilterDirection:
|
||||
#
|
||||
# Indicates whether a netfilter is attached to a netdev's transmit queue or
|
||||
# receive queue or both.
|
||||
#
|
||||
# @all: the filter is attached both to the receive and the transmit
|
||||
# queue of the netdev (default).
|
||||
#
|
||||
# @rx: the filter is attached to the receive queue of the netdev,
|
||||
# where it will receive packets sent to the netdev.
|
||||
#
|
||||
# @tx: the filter is attached to the transmit queue of the netdev,
|
||||
# where it will receive packets sent by the netdev.
|
||||
#
|
||||
# Since: 2.5
|
||||
##
|
||||
{ 'enum': 'NetFilterDirection',
|
||||
'data': [ 'all', 'rx', 'tx' ] }
|
||||
|
||||
##
|
||||
# @GrabToggleKeys:
|
||||
#
|
||||
# Keys to toggle input-linux between host and guest.
|
||||
#
|
||||
# Since: 4.0
|
||||
#
|
||||
##
|
||||
{ 'enum': 'GrabToggleKeys',
|
||||
'data': [ 'ctrl-ctrl', 'alt-alt', 'shift-shift','meta-meta', 'scrolllock',
|
||||
'ctrl-scrolllock' ] }
|
||||
|
||||
@@ -381,3 +381,162 @@
|
||||
'discriminator': 'format',
|
||||
'data': {
|
||||
'luks': 'QCryptoBlockAmendOptionsLUKS' } }
|
||||
|
||||
##
|
||||
# @SecretCommonProperties:
|
||||
#
|
||||
# Properties for objects of classes derived from secret-common.
|
||||
#
|
||||
# @loaded: if true, the secret is loaded immediately when applying this option
|
||||
# and will probably fail when processing the next option. Don't use;
|
||||
# only provided for compatibility. (default: false)
|
||||
#
|
||||
# @format: the data format that the secret is provided in (default: raw)
|
||||
#
|
||||
# @keyid: the name of another secret that should be used to decrypt the
|
||||
# provided data. If not present, the data is assumed to be unencrypted.
|
||||
#
|
||||
# @iv: the random initialization vector used for encryption of this particular
|
||||
# secret. Should be a base64 encrypted string of the 16-byte IV. Mandatory
|
||||
# if @keyid is given. Ignored if @keyid is absent.
|
||||
#
|
||||
# Features:
|
||||
# @deprecated: Member @loaded is deprecated. Setting true doesn't make sense,
|
||||
# and false is already the default.
|
||||
#
|
||||
# Since: 2.6
|
||||
##
|
||||
{ 'struct': 'SecretCommonProperties',
|
||||
'data': { '*loaded': { 'type': 'bool', 'features': ['deprecated'] },
|
||||
'*format': 'QCryptoSecretFormat',
|
||||
'*keyid': 'str',
|
||||
'*iv': 'str' } }
|
||||
|
||||
##
|
||||
# @SecretProperties:
|
||||
#
|
||||
# Properties for secret objects.
|
||||
#
|
||||
# Either @data or @file must be provided, but not both.
|
||||
#
|
||||
# @data: the associated with the secret from
|
||||
#
|
||||
# @file: the filename to load the data associated with the secret from
|
||||
#
|
||||
# Since: 2.6
|
||||
##
|
||||
{ 'struct': 'SecretProperties',
|
||||
'base': 'SecretCommonProperties',
|
||||
'data': { '*data': 'str',
|
||||
'*file': 'str' } }
|
||||
|
||||
##
|
||||
# @SecretKeyringProperties:
|
||||
#
|
||||
# Properties for secret_keyring objects.
|
||||
#
|
||||
# @serial: serial number that identifies a key to get from the kernel
|
||||
#
|
||||
# Since: 5.1
|
||||
##
|
||||
{ 'struct': 'SecretKeyringProperties',
|
||||
'base': 'SecretCommonProperties',
|
||||
'data': { 'serial': 'int32' } }
|
||||
|
||||
##
|
||||
# @TlsCredsProperties:
|
||||
#
|
||||
# Properties for objects of classes derived from tls-creds.
|
||||
#
|
||||
# @verify-peer: if true the peer credentials will be verified once the
|
||||
# handshake is completed. This is a no-op for anonymous
|
||||
# credentials. (default: true)
|
||||
#
|
||||
# @dir: the path of the directory that contains the credential files
|
||||
#
|
||||
# @endpoint: whether the QEMU network backend that uses the credentials will be
|
||||
# acting as a client or as a server (default: client)
|
||||
#
|
||||
# @priority: a gnutls priority string as described at
|
||||
# https://gnutls.org/manual/html_node/Priority-Strings.html
|
||||
#
|
||||
# Since: 2.5
|
||||
##
|
||||
{ 'struct': 'TlsCredsProperties',
|
||||
'data': { '*verify-peer': 'bool',
|
||||
'*dir': 'str',
|
||||
'*endpoint': 'QCryptoTLSCredsEndpoint',
|
||||
'*priority': 'str' } }
|
||||
|
||||
##
|
||||
# @TlsCredsAnonProperties:
|
||||
#
|
||||
# Properties for tls-creds-anon objects.
|
||||
#
|
||||
# @loaded: if true, the credentials are loaded immediately when applying this
|
||||
# option and will ignore options that are processed later. Don't use;
|
||||
# only provided for compatibility. (default: false)
|
||||
#
|
||||
# Features:
|
||||
# @deprecated: Member @loaded is deprecated. Setting true doesn't make sense,
|
||||
# and false is already the default.
|
||||
#
|
||||
# Since: 2.5
|
||||
##
|
||||
{ 'struct': 'TlsCredsAnonProperties',
|
||||
'base': 'TlsCredsProperties',
|
||||
'data': { '*loaded': { 'type': 'bool', 'features': ['deprecated'] } } }
|
||||
|
||||
##
|
||||
# @TlsCredsPskProperties:
|
||||
#
|
||||
# Properties for tls-creds-psk objects.
|
||||
#
|
||||
# @loaded: if true, the credentials are loaded immediately when applying this
|
||||
# option and will ignore options that are processed later. Don't use;
|
||||
# only provided for compatibility. (default: false)
|
||||
#
|
||||
# @username: the username which will be sent to the server. For clients only.
|
||||
# If absent, "qemu" is sent and the property will read back as an
|
||||
# empty string.
|
||||
#
|
||||
# Features:
|
||||
# @deprecated: Member @loaded is deprecated. Setting true doesn't make sense,
|
||||
# and false is already the default.
|
||||
#
|
||||
# Since: 3.0
|
||||
##
|
||||
{ 'struct': 'TlsCredsPskProperties',
|
||||
'base': 'TlsCredsProperties',
|
||||
'data': { '*loaded': { 'type': 'bool', 'features': ['deprecated'] },
|
||||
'*username': 'str' } }
|
||||
|
||||
##
|
||||
# @TlsCredsX509Properties:
|
||||
#
|
||||
# Properties for tls-creds-x509 objects.
|
||||
#
|
||||
# @loaded: if true, the credentials are loaded immediately when applying this
|
||||
# option and will ignore options that are processed later. Don't use;
|
||||
# only provided for compatibility. (default: false)
|
||||
#
|
||||
# @sanity-check: if true, perform some sanity checks before using the
|
||||
# credentials (default: true)
|
||||
#
|
||||
# @passwordid: For the server-key.pem and client-key.pem files which contain
|
||||
# sensitive private keys, it is possible to use an encrypted
|
||||
# version by providing the @passwordid parameter. This provides
|
||||
# the ID of a previously created secret object containing the
|
||||
# password for decryption.
|
||||
#
|
||||
# Features:
|
||||
# @deprecated: Member @loaded is deprecated. Setting true doesn't make sense,
|
||||
# and false is already the default.
|
||||
#
|
||||
# Since: 2.5
|
||||
##
|
||||
{ 'struct': 'TlsCredsX509Properties',
|
||||
'base': 'TlsCredsProperties',
|
||||
'data': { '*loaded': { 'type': 'bool', 'features': ['deprecated'] },
|
||||
'*sanity-check': 'bool',
|
||||
'*passwordid': 'str' } }
|
||||
|
||||
+2
-20
@@ -8,6 +8,8 @@
|
||||
# = Machines
|
||||
##
|
||||
|
||||
{ 'include': 'common.json' }
|
||||
|
||||
##
|
||||
# @SysEmuTarget:
|
||||
#
|
||||
@@ -718,26 +720,6 @@
|
||||
'policy': 'HmatCacheWritePolicy',
|
||||
'line': 'uint16' }}
|
||||
|
||||
##
|
||||
# @HostMemPolicy:
|
||||
#
|
||||
# Host memory policy types
|
||||
#
|
||||
# @default: restore default policy, remove any nondefault policy
|
||||
#
|
||||
# @preferred: set the preferred host nodes for allocation
|
||||
#
|
||||
# @bind: a strict policy that restricts memory allocation to the
|
||||
# host nodes specified
|
||||
#
|
||||
# @interleave: memory allocations are interleaved across the set
|
||||
# of host nodes specified
|
||||
#
|
||||
# Since: 2.1
|
||||
##
|
||||
{ 'enum': 'HostMemPolicy',
|
||||
'data': [ 'default', 'preferred', 'bind', 'interleave' ] }
|
||||
|
||||
##
|
||||
# @memsave:
|
||||
#
|
||||
|
||||
@@ -492,26 +492,6 @@
|
||||
'vhost-user': 'NetdevVhostUserOptions',
|
||||
'vhost-vdpa': 'NetdevVhostVDPAOptions' } }
|
||||
|
||||
##
|
||||
# @NetFilterDirection:
|
||||
#
|
||||
# Indicates whether a netfilter is attached to a netdev's transmit queue or
|
||||
# receive queue or both.
|
||||
#
|
||||
# @all: the filter is attached both to the receive and the transmit
|
||||
# queue of the netdev (default).
|
||||
#
|
||||
# @rx: the filter is attached to the receive queue of the netdev,
|
||||
# where it will receive packets sent to the netdev.
|
||||
#
|
||||
# @tx: the filter is attached to the transmit queue of the netdev,
|
||||
# where it will receive packets sent by the netdev.
|
||||
#
|
||||
# Since: 2.5
|
||||
##
|
||||
{ 'enum': 'NetFilterDirection',
|
||||
'data': [ 'all', 'rx', 'tx' ] }
|
||||
|
||||
##
|
||||
# @RxState:
|
||||
#
|
||||
|
||||
+636
-10
File diff suppressed because it is too large
Load Diff
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user