Commit f1a1a356 authored by Gerd Hoffmann's avatar Gerd Hoffmann
Browse files

chardev: add qmp hotplug commands, with null chardev support



Add chardev-add and chardev-remove qmp commands.  Hotplugging
a null chardev is supported for now, more will be added later.

Signed-off-by: default avatarGerd Hoffmann <kraxel@redhat.com>
parent e551498e
Loading
Loading
Loading
Loading
+49 −0
Original line number Diff line number Diff line
@@ -3017,3 +3017,52 @@
# Since: 1.3.0
##
{ 'command': 'nbd-server-stop' }

##
# @ChardevBackend:
#
# Configuration info for the new chardev backend.
#
# Since: 1.4
##
{ 'type': 'ChardevDummy', 'data': { } }

{ 'union': 'ChardevBackend', 'data': { 'null' : 'ChardevDummy' } }

##
# @ChardevReturn:
#
# Return info about the chardev backend just created.
#
# Since: 1.4
##
{ 'type' : 'ChardevReturn', 'data': { } }

##
# @chardev-add:
#
# Add a file chardev
#
# @id: the chardev's ID, must be unique
# @backend: backend type and parameters
#
# Returns: chardev info.
#
# Since: 1.4
##
{ 'command': 'chardev-add', 'data': {'id'      : 'str',
                                     'backend' : 'ChardevBackend' },
  'returns': 'ChardevReturn' }

##
# @chardev-remove:
#
# Remove a chardev
#
# @id: the chardev's ID, must exist and not be in use
#
# Returns: Nothing on success
#
# Since: 1.4
##
{ 'command': 'chardev-remove', 'data': {'id': 'str'} }
+53 −0
Original line number Diff line number Diff line
@@ -3010,3 +3010,56 @@ QemuOptsList qemu_chardev_opts = {
        { /* end of list */ }
    },
};

ChardevReturn *qmp_chardev_add(const char *id, ChardevBackend *backend,
                               Error **errp)
{
    ChardevReturn *ret = g_new0(ChardevReturn, 1);
    CharDriverState *chr = NULL;

    chr = qemu_chr_find(id);
    if (chr) {
        error_setg(errp, "Chardev '%s' already exists", id);
        g_free(ret);
        return NULL;
    }

    switch (backend->kind) {
    case CHARDEV_BACKEND_KIND_NULL:
        chr = qemu_chr_open_null(NULL);
        break;
    default:
        error_setg(errp, "unknown chardev backend (%d)", backend->kind);
        break;
    }

    if (chr == NULL && !error_is_set(errp)) {
        error_setg(errp, "Failed to create chardev");
    }
    if (chr) {
        chr->label = g_strdup(id);
        chr->avail_connections = 1;
        QTAILQ_INSERT_TAIL(&chardevs, chr, next);
        return ret;
    } else {
        g_free(ret);
        return NULL;
    }
}

void qmp_chardev_remove(const char *id, Error **errp)
{
    CharDriverState *chr;

    chr = qemu_chr_find(id);
    if (NULL == chr) {
        error_setg(errp, "Chardev '%s' not found", id);
        return;
    }
    if (chr->chr_can_read || chr->chr_read ||
        chr->chr_event || chr->handler_opaque) {
        error_setg(errp, "Chardev '%s' is busy", id);
        return;
    }
    qemu_chr_delete(chr);
}
+50 −0
Original line number Diff line number Diff line
@@ -2654,3 +2654,53 @@ EQMP
        .args_type  = "",
        .mhandler.cmd_new = qmp_marshal_input_query_target,
    },

    {
        .name       = "chardev-add",
        .args_type  = "id:s,backend:q",
        .mhandler.cmd_new = qmp_marshal_input_chardev_add,
    },

SQMP
chardev-add
----------------

Add a chardev.

Arguments:

- "id": the chardev's ID, must be unique (json-string)
- "backend": chardev backend type + parameters

Example:

-> { "execute" : "chardev-add",
     "arguments" : { "id" : "foo",
                     "backend" : { "type" : "null", "data" : {} } } }
<- { "return": {} }

EQMP

    {
        .name       = "chardev-remove",
        .args_type  = "id:s",
        .mhandler.cmd_new = qmp_marshal_input_chardev_remove,
    },


SQMP
chardev-remove
--------------

Remove a chardev.

Arguments:

- "id": the chardev's ID, must exist and not be in use (json-string)

Example:

-> { "execute": "chardev-remove", "arguments": { "id" : "foo" } }
<- { "return": {} }

EQMP