Merge remote-tracking branch 'kraxel/chardev.1' into staging

# By Gerd Hoffmann
# Via Gerd Hoffmann
* kraxel/chardev.1:
  chardev: add pty chardev support to chardev-add (qmp)
  chardev: add socket chardev support to chardev-add (qmp)
  chardev: add parallel chardev support to chardev-add (qmp)
  chardev: add serial chardev support to chardev-add (qmp)
  chardev: add file chardev support to chardev-add (qmp)
  chardev: add hmp hotplug commands
  chardev: add qmp hotplug commands, with null chardev support
  chardev: reduce chardev ifdef mess a bit
  chardev: fix QemuOpts lifecycle
  chardev: add error reporting for qemu_chr_new_from_opts
This commit is contained in:
Anthony Liguori
2013-01-16 15:20:05 -06:00
9 changed files with 600 additions and 112 deletions
+32
View File
@@ -1482,6 +1482,38 @@ Password is invalidated at the given time. @var{nsec} are the seconds
passed since 1970, i.e. unix epoch.
@end table
ETEXI
{
.name = "chardev-add",
.args_type = "args:s",
.params = "args",
.help = "add chardev",
.mhandler.cmd = hmp_chardev_add,
},
STEXI
@item chardev_add args
@findex chardev_add
chardev_add accepts the same parameters as the -chardev command line switch.
ETEXI
{
.name = "chardev-remove",
.args_type = "id:s",
.params = "id",
.help = "remove chardev",
.mhandler.cmd = hmp_chardev_remove,
},
STEXI
@item chardev_remove id
@findex chardev_remove
Removes the chardev @var{id}.
ETEXI
{
+23
View File
@@ -1336,3 +1336,26 @@ void hmp_nbd_server_stop(Monitor *mon, const QDict *qdict)
qmp_nbd_server_stop(&errp);
hmp_handle_error(mon, &errp);
}
void hmp_chardev_add(Monitor *mon, const QDict *qdict)
{
const char *args = qdict_get_str(qdict, "args");
Error *err = NULL;
QemuOpts *opts;
opts = qemu_opts_parse(qemu_find_opts("chardev"), args, 1);
if (opts == NULL) {
error_setg(&err, "Parsing chardev args failed\n");
} else {
qemu_chr_new_from_opts(opts, NULL, &err);
}
hmp_handle_error(mon, &err);
}
void hmp_chardev_remove(Monitor *mon, const QDict *qdict)
{
Error *local_err = NULL;
qmp_chardev_remove(qdict_get_str(qdict, "id"), &local_err);
hmp_handle_error(mon, &local_err);
}
+2
View File
@@ -80,5 +80,7 @@ void hmp_screen_dump(Monitor *mon, const QDict *qdict);
void hmp_nbd_server_start(Monitor *mon, const QDict *qdict);
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);
#endif
+3 -1
View File
@@ -75,6 +75,7 @@ struct CharDriverState {
char *filename;
int opened;
int avail_connections;
QemuOpts *opts;
QTAILQ_ENTRY(CharDriverState) next;
};
@@ -89,7 +90,8 @@ struct CharDriverState {
* Returns: a new character backend
*/
CharDriverState *qemu_chr_new_from_opts(QemuOpts *opts,
void (*init)(struct CharDriverState *s));
void (*init)(struct CharDriverState *s),
Error **errp);
/**
* @qemu_chr_new:
+104
View File
@@ -3017,3 +3017,107 @@
# Since: 1.3.0
##
{ 'command': 'nbd-server-stop' }
##
# @ChardevFile:
#
# Configuration info for file chardevs.
#
# @in: #optional The name of the input file
# @out: The name of the output file
#
# Since: 1.4
##
{ 'type': 'ChardevFile', 'data': { '*in' : 'str',
'out' : 'str' } }
##
# @ChardevPort:
#
# Configuration info for device chardevs.
#
# @device: The name of the special file for the device,
# i.e. /dev/ttyS0 on Unix or COM1: on Windows
# @type: What kind of device this is.
#
# Since: 1.4
##
{ 'enum': 'ChardevPortKind', 'data': [ 'serial',
'parallel' ] }
{ 'type': 'ChardevPort', 'data': { 'device' : 'str',
'type' : 'ChardevPortKind'} }
##
# @ChardevSocket:
#
# Configuration info for socket chardevs.
#
# @addr: socket address to listen on (server=true)
# or connect to (server=false)
# @server: #optional create server socket (default: true)
# @wait: #optional wait for connect (not used for server
# sockets, default: false)
# @nodelay: #optional set TCP_NODELAY socket option (default: false)
# @telnet: #optional enable telnet protocol (default: false)
#
# Since: 1.4
##
{ 'type': 'ChardevSocket', 'data': { 'addr' : 'SocketAddress',
'*server' : 'bool',
'*wait' : 'bool',
'*nodelay' : 'bool',
'*telnet' : 'bool' } }
##
# @ChardevBackend:
#
# Configuration info for the new chardev backend.
#
# Since: 1.4
##
{ 'type': 'ChardevDummy', 'data': { } }
{ 'union': 'ChardevBackend', 'data': { 'file' : 'ChardevFile',
'port' : 'ChardevPort',
'socket' : 'ChardevSocket',
'pty' : 'ChardevDummy',
'null' : 'ChardevDummy' } }
##
# @ChardevReturn:
#
# Return info about the chardev backend just created.
#
# Since: 1.4
##
{ 'type' : 'ChardevReturn', 'data': { '*pty' : 'str' } }
##
# @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'} }
+361 -102
View File
File diff suppressed because it is too large Load Diff
+8 -6
View File
@@ -1742,9 +1742,11 @@ DEF("chardev", HAS_ARG, QEMU_OPTION_chardev,
#endif
#if defined(__linux__) || defined(__sun__) || defined(__FreeBSD__) \
|| defined(__NetBSD__) || defined(__OpenBSD__) || defined(__DragonFly__)
"-chardev serial,id=id,path=path[,mux=on|off]\n"
"-chardev tty,id=id,path=path[,mux=on|off]\n"
#endif
#if defined(__linux__) || defined(__FreeBSD__) || defined(__DragonFly__)
"-chardev parallel,id=id,path=path[,mux=on|off]\n"
"-chardev parport,id=id,path=path[,mux=on|off]\n"
#endif
#if defined(CONFIG_SPICE)
@@ -1775,6 +1777,7 @@ Backend is one of:
@option{stdio},
@option{braille},
@option{tty},
@option{parallel},
@option{parport},
@option{spicevmc}.
@option{spiceport}.
@@ -1910,8 +1913,8 @@ take any options.
Send traffic from the guest to a serial device on the host.
@option{serial} is
only available on Windows hosts.
On Unix hosts serial will actually accept any tty device,
not only serial lines.
@option{path} specifies the name of the serial device to open.
@@ -1937,16 +1940,15 @@ Connect to a local BrlAPI server. @option{braille} does not take any options.
@item -chardev tty ,id=@var{id} ,path=@var{path}
Connect to a local tty device.
@option{tty} is only available on Linux, Sun, FreeBSD, NetBSD, OpenBSD and
DragonFlyBSD hosts.
DragonFlyBSD hosts. It is an alias for -serial.
@option{path} specifies the path to the tty. @option{path} is required.
@item -chardev parallel ,id=@var{id} ,path=@var{path}
@item -chardev parport ,id=@var{id} ,path=@var{path}
@option{parport} is only available on Linux, FreeBSD and DragonFlyBSD hosts.
@option{parallel} is only available on Linux, FreeBSD and DragonFlyBSD hosts.
Connect to a local parallel port.
+61
View File
@@ -2654,3 +2654,64 @@ 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
Examples:
-> { "execute" : "chardev-add",
"arguments" : { "id" : "foo",
"backend" : { "type" : "null", "data" : {} } } }
<- { "return": {} }
-> { "execute" : "chardev-add",
"arguments" : { "id" : "bar",
"backend" : { "type" : "file",
"data" : { "out" : "/tmp/bar.log" } } } }
<- { "return": {} }
-> { "execute" : "chardev-add",
"arguments" : { "id" : "baz",
"backend" : { "type" : "pty", "data" : {} } } }
<- { "return": { "pty" : "/dev/pty/42" } }
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
+6 -3
View File
@@ -2238,11 +2238,14 @@ static int device_init_func(QemuOpts *opts, void *opaque)
static int chardev_init_func(QemuOpts *opts, void *opaque)
{
CharDriverState *chr;
Error *local_err = NULL;
chr = qemu_chr_new_from_opts(opts, NULL);
if (!chr)
qemu_chr_new_from_opts(opts, NULL, &local_err);
if (error_is_set(&local_err)) {
fprintf(stderr, "%s\n", error_get_pretty(local_err));
error_free(local_err);
return -1;
}
return 0;
}