diff options
author | Stefan Fritsch <sf@sfritsch.de> | 2017-06-11 09:48:17 +0200 |
---|---|---|
committer | Dr. David Alan Gilbert <dgilbert@redhat.com> | 2017-06-29 17:14:11 +0100 |
commit | bd1d5ad9f9a1347d6f4338f294253617c565c89a (patch) | |
tree | 0c6c05f44eae0cca3dae76962669e524a3d5125f | |
parent | 18f0828278c62bf5b50ec24a012073cd79535481 (diff) |
Add chardev-send-break monitor command
Sending a break on a serial console can be useful for debugging the
guest. But not all chardev backends support sending breaks (only telnet
and mux do). The chardev-send-break command allows to send a break even
if using other backends.
Signed-off-by: Stefan Fritsch <sf@sfritsch.de>
Acked-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
Message-Id: <20170611074817.13621-1-sf@sfritsch.de>
Reviewed-by: Eric Blake <eblake@redhat.com>
Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Signed-off-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
Use 'send a break' in all 3 pieces of text as suggested by eblake
-rw-r--r-- | chardev/char.c | 12 | ||||
-rw-r--r-- | hmp-commands.hx | 16 | ||||
-rw-r--r-- | hmp.c | 8 | ||||
-rw-r--r-- | hmp.h | 1 | ||||
-rw-r--r-- | qapi-schema.json | 20 | ||||
-rw-r--r-- | tests/test-char.c | 12 | ||||
-rw-r--r-- | tests/test-hmp.c | 1 |
7 files changed, 68 insertions, 2 deletions
diff --git a/chardev/char.c b/chardev/char.c index bcfc065d16..2b679a2295 100644 --- a/chardev/char.c +++ b/chardev/char.c @@ -951,6 +951,18 @@ void qmp_chardev_remove(const char *id, Error **errp) object_unparent(OBJECT(chr)); } +void qmp_chardev_send_break(const char *id, Error **errp) +{ + Chardev *chr; + + chr = qemu_chr_find(id); + if (chr == NULL) { + error_setg(errp, "Chardev '%s' not found", id); + return; + } + qemu_chr_be_event(chr, CHR_EVENT_BREAK); +} + void qemu_chr_cleanup(void) { object_unparent(get_chardevs_root()); diff --git a/hmp-commands.hx b/hmp-commands.hx index e763606fe5..275ccdfbc7 100644 --- a/hmp-commands.hx +++ b/hmp-commands.hx @@ -1745,6 +1745,22 @@ Removes the chardev @var{id}. ETEXI { + .name = "chardev-send-break", + .args_type = "id:s", + .params = "id", + .help = "send a break on chardev", + .cmd = hmp_chardev_send_break, + .command_completion = chardev_remove_completion, + }, + +STEXI +@item chardev-send-break id +@findex chardev-send-break +Send a break on the chardev @var{id}. + +ETEXI + + { .name = "qemu-io", .args_type = "device:B,command:s", .params = "[device] \"[command]\"", @@ -2236,6 +2236,14 @@ void hmp_chardev_remove(Monitor *mon, const QDict *qdict) hmp_handle_error(mon, &local_err); } +void hmp_chardev_send_break(Monitor *mon, const QDict *qdict) +{ + Error *local_err = NULL; + + qmp_chardev_send_break(qdict_get_str(qdict, "id"), &local_err); + hmp_handle_error(mon, &local_err); +} + void hmp_qemu_io(Monitor *mon, const QDict *qdict) { BlockBackend *blk; @@ -103,6 +103,7 @@ void hmp_nbd_server_add(Monitor *mon, const QDict *qdict); void hmp_nbd_server_stop(Monitor *mon, const QDict *qdict); void hmp_chardev_add(Monitor *mon, const QDict *qdict); void hmp_chardev_remove(Monitor *mon, const QDict *qdict); +void hmp_chardev_send_break(Monitor *mon, const QDict *qdict); void hmp_qemu_io(Monitor *mon, const QDict *qdict); void hmp_cpu_add(Monitor *mon, const QDict *qdict); void hmp_object_add(Monitor *mon, const QDict *qdict); diff --git a/qapi-schema.json b/qapi-schema.json index 9e34cf71f3..37c4b95aad 100644 --- a/qapi-schema.json +++ b/qapi-schema.json @@ -5117,6 +5117,26 @@ { 'command': 'chardev-remove', 'data': {'id': 'str'} } ## +# @chardev-send-break: +# +# Send a break to a character device +# +# @id: the chardev's ID, must exist +# +# Returns: Nothing on success +# +# Since: 2.10 +# +# Example: +# +# -> { "execute": "chardev-send-break", "arguments": { "id" : "foo" } } +# <- { "return": {} } +# +## +{ 'command': 'chardev-send-break', 'data': {'id': 'str'} } + + +## # @TpmModel: # # An enumeration of TPM models diff --git a/tests/test-char.c b/tests/test-char.c index 9e361c8d09..87c724c5c2 100644 --- a/tests/test-char.c +++ b/tests/test-char.c @@ -53,7 +53,9 @@ static void fe_event(void *opaque, int event) FeHandler *h = opaque; h->last_event = event; - quit = true; + if (event != CHR_EVENT_BREAK) { + quit = true; + } } #ifdef CONFIG_HAS_GLIB_SUBPROCESS_TESTS @@ -517,7 +519,7 @@ static void char_file_test(void) file.in = fifo; file.has_in = true; - chr = qemu_chardev_new(NULL, TYPE_CHARDEV_FILE, &backend, + chr = qemu_chardev_new("label-file", TYPE_CHARDEV_FILE, &backend, &error_abort); qemu_chr_fe_init(&be, chr, &error_abort); @@ -527,6 +529,12 @@ static void char_file_test(void) fe_event, &fe, NULL, true); + g_assert_cmpint(fe.last_event, !=, CHR_EVENT_BREAK); + qmp_chardev_send_break("label-foo", NULL); + g_assert_cmpint(fe.last_event, !=, CHR_EVENT_BREAK); + qmp_chardev_send_break("label-file", NULL); + g_assert_cmpint(fe.last_event, ==, CHR_EVENT_BREAK); + main_loop(); close(fd); diff --git a/tests/test-hmp.c b/tests/test-hmp.c index 99e35ec15a..6dfa0c36e2 100644 --- a/tests/test-hmp.c +++ b/tests/test-hmp.c @@ -22,6 +22,7 @@ static int verbose; static const char *hmp_cmds[] = { "boot_set ndc", "chardev-add null,id=testchardev1", + "chardev-send-break testchardev2", "chardev-remove testchardev1", "commit all", "cpu-add 1", |