chardev: Allow setting file chardev input file on the command line

Our 'file' chardev backend supports both "output from this chardev
is written to a file" and "input from this chardev should be read
from a file" (except on Windows). However, you can only set up
the input file if you're using the QMP interface -- there is no
command line syntax to do it.

Add command line syntax to allow specifying an input file
as well as an output file, using a new 'input-path' suboption.

The specific use case I have is that I'd like to be able to
feed fuzzer reproducer input into qtest without having to use
'-qtest stdio' and put the input onto stdin. Being able to
use a file chardev like this:
 -chardev file,id=repro,path=/dev/null,input-path=repro.txt -qtest chardev:repro
means that stdio is free for use by gdb.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Message-Id: <20230413150724.404304-3-peter.maydell@linaro.org>
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com>
[thuth: Replace "input-file=" typo with "input-path="]
Signed-off-by: Thomas Huth <thuth@redhat.com>
This commit is contained in:
Peter Maydell 2023-04-13 16:07:24 +01:00 committed by Thomas Huth
parent 537a1388e6
commit 5b18a6bf44
3 changed files with 19 additions and 2 deletions

View File

@ -100,6 +100,7 @@ static void qemu_chr_parse_file_out(QemuOpts *opts, ChardevBackend *backend,
Error **errp) Error **errp)
{ {
const char *path = qemu_opt_get(opts, "path"); const char *path = qemu_opt_get(opts, "path");
const char *inpath = qemu_opt_get(opts, "input-path");
ChardevFile *file; ChardevFile *file;
backend->type = CHARDEV_BACKEND_KIND_FILE; backend->type = CHARDEV_BACKEND_KIND_FILE;
@ -107,9 +108,16 @@ static void qemu_chr_parse_file_out(QemuOpts *opts, ChardevBackend *backend,
error_setg(errp, "chardev: file: no filename given"); error_setg(errp, "chardev: file: no filename given");
return; return;
} }
#ifdef _WIN32
if (inpath) {
error_setg(errp, "chardev: file: input-path not supported on Windows");
return;
}
#endif
file = backend->u.file.data = g_new0(ChardevFile, 1); file = backend->u.file.data = g_new0(ChardevFile, 1);
qemu_chr_parse_common(opts, qapi_ChardevFile_base(file)); qemu_chr_parse_common(opts, qapi_ChardevFile_base(file));
file->out = g_strdup(path); file->out = g_strdup(path);
file->in = g_strdup(inpath);
file->has_append = true; file->has_append = true;
file->append = qemu_opt_get_bool(opts, "append", false); file->append = qemu_opt_get_bool(opts, "append", false);

View File

@ -805,6 +805,9 @@ QemuOptsList qemu_chardev_opts = {
},{ },{
.name = "path", .name = "path",
.type = QEMU_OPT_STRING, .type = QEMU_OPT_STRING,
},{
.name = "input-path",
.type = QEMU_OPT_STRING,
},{ },{
.name = "host", .name = "host",
.type = QEMU_OPT_STRING, .type = QEMU_OPT_STRING,

View File

@ -3360,7 +3360,7 @@ DEF("chardev", HAS_ARG, QEMU_OPTION_chardev,
"-chardev vc,id=id[[,width=width][,height=height]][[,cols=cols][,rows=rows]]\n" "-chardev vc,id=id[[,width=width][,height=height]][[,cols=cols][,rows=rows]]\n"
" [,mux=on|off][,logfile=PATH][,logappend=on|off]\n" " [,mux=on|off][,logfile=PATH][,logappend=on|off]\n"
"-chardev ringbuf,id=id[,size=size][,logfile=PATH][,logappend=on|off]\n" "-chardev ringbuf,id=id[,size=size][,logfile=PATH][,logappend=on|off]\n"
"-chardev file,id=id,path=path[,mux=on|off][,logfile=PATH][,logappend=on|off]\n" "-chardev file,id=id,path=path[,input-path=input-file][,mux=on|off][,logfile=PATH][,logappend=on|off]\n"
"-chardev pipe,id=id,path=path[,mux=on|off][,logfile=PATH][,logappend=on|off]\n" "-chardev pipe,id=id,path=path[,mux=on|off][,logfile=PATH][,logappend=on|off]\n"
#ifdef _WIN32 #ifdef _WIN32
"-chardev console,id=id[,mux=on|off][,logfile=PATH][,logappend=on|off]\n" "-chardev console,id=id[,mux=on|off][,logfile=PATH][,logappend=on|off]\n"
@ -3563,13 +3563,19 @@ The available backends are:
Create a ring buffer with fixed size ``size``. size must be a power Create a ring buffer with fixed size ``size``. size must be a power
of two and defaults to ``64K``. of two and defaults to ``64K``.
``-chardev file,id=id,path=path`` ``-chardev file,id=id,path=path[,input-path=input-path]``
Log all traffic received from the guest to a file. Log all traffic received from the guest to a file.
``path`` specifies the path of the file to be opened. This file will ``path`` specifies the path of the file to be opened. This file will
be created if it does not already exist, and overwritten if it does. be created if it does not already exist, and overwritten if it does.
``path`` is required. ``path`` is required.
If ``input-path`` is specified, this is the path of a second file
which will be used for input. If ``input-path`` is not specified,
no input will be available from the chardev.
Note that ``input-path`` is not supported on Windows hosts.
``-chardev pipe,id=id,path=path`` ``-chardev pipe,id=id,path=path``
Create a two-way connection to the guest. The behaviour differs Create a two-way connection to the guest. The behaviour differs
slightly between Windows hosts and other hosts: slightly between Windows hosts and other hosts: