chardev: add support for qapi-based chardev initialization
This patch add support for a new way to initialize chardev devices. Instead of calling a initialization function with a QemuOpts we will now create a (qapi) ChardevBackend, optionally call a function to fill ChardevBackend from QemuOpts, then go create the chardev using the new qapi code path which is also used by chardev-add. Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
This commit is contained in:
parent
8ca761f661
commit
2c5f488293
@ -245,6 +245,8 @@ CharDriverState *qemu_chr_find(const char *name);
|
|||||||
QemuOpts *qemu_chr_parse_compat(const char *label, const char *filename);
|
QemuOpts *qemu_chr_parse_compat(const char *label, const char *filename);
|
||||||
|
|
||||||
void register_char_driver(const char *name, CharDriverState *(*open)(QemuOpts *));
|
void register_char_driver(const char *name, CharDriverState *(*open)(QemuOpts *));
|
||||||
|
void register_char_driver_qapi(const char *name, int kind,
|
||||||
|
void (*parse)(QemuOpts *opts, ChardevBackend *backend, Error **errp));
|
||||||
|
|
||||||
/* add an eventfd to the qemu devices that are polled */
|
/* add an eventfd to the qemu devices that are polled */
|
||||||
CharDriverState *qemu_chr_open_eventfd(int eventfd);
|
CharDriverState *qemu_chr_open_eventfd(int eventfd);
|
||||||
|
43
qemu-char.c
43
qemu-char.c
@ -3204,7 +3204,11 @@ static CharDriverState *qemu_chr_open_pp(QemuOpts *opts)
|
|||||||
|
|
||||||
typedef struct CharDriver {
|
typedef struct CharDriver {
|
||||||
const char *name;
|
const char *name;
|
||||||
|
/* old, pre qapi */
|
||||||
CharDriverState *(*open)(QemuOpts *opts);
|
CharDriverState *(*open)(QemuOpts *opts);
|
||||||
|
/* new, qapi-based */
|
||||||
|
int kind;
|
||||||
|
void (*parse)(QemuOpts *opts, ChardevBackend *backend, Error **errp);
|
||||||
} CharDriver;
|
} CharDriver;
|
||||||
|
|
||||||
static GSList *backends;
|
static GSList *backends;
|
||||||
@ -3220,6 +3224,19 @@ void register_char_driver(const char *name, CharDriverState *(*open)(QemuOpts *)
|
|||||||
backends = g_slist_append(backends, s);
|
backends = g_slist_append(backends, s);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void register_char_driver_qapi(const char *name, int kind,
|
||||||
|
void (*parse)(QemuOpts *opts, ChardevBackend *backend, Error **errp))
|
||||||
|
{
|
||||||
|
CharDriver *s;
|
||||||
|
|
||||||
|
s = g_malloc0(sizeof(*s));
|
||||||
|
s->name = g_strdup(name);
|
||||||
|
s->kind = kind;
|
||||||
|
s->parse = parse;
|
||||||
|
|
||||||
|
backends = g_slist_append(backends, s);
|
||||||
|
}
|
||||||
|
|
||||||
CharDriverState *qemu_chr_new_from_opts(QemuOpts *opts,
|
CharDriverState *qemu_chr_new_from_opts(QemuOpts *opts,
|
||||||
void (*init)(struct CharDriverState *s),
|
void (*init)(struct CharDriverState *s),
|
||||||
Error **errp)
|
Error **errp)
|
||||||
@ -3251,6 +3268,32 @@ CharDriverState *qemu_chr_new_from_opts(QemuOpts *opts,
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!cd->open) {
|
||||||
|
/* using new, qapi init */
|
||||||
|
ChardevBackend *backend = g_new0(ChardevBackend, 1);
|
||||||
|
ChardevReturn *ret = NULL;
|
||||||
|
const char *id = qemu_opts_id(opts);
|
||||||
|
|
||||||
|
chr = NULL;
|
||||||
|
backend->kind = cd->kind;
|
||||||
|
if (cd->parse) {
|
||||||
|
cd->parse(opts, backend, errp);
|
||||||
|
if (error_is_set(errp)) {
|
||||||
|
goto qapi_out;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ret = qmp_chardev_add(qemu_opts_id(opts), backend, errp);
|
||||||
|
if (error_is_set(errp)) {
|
||||||
|
goto qapi_out;
|
||||||
|
}
|
||||||
|
chr = qemu_chr_find(id);
|
||||||
|
|
||||||
|
qapi_out:
|
||||||
|
qapi_free_ChardevBackend(backend);
|
||||||
|
qapi_free_ChardevReturn(ret);
|
||||||
|
return chr;
|
||||||
|
}
|
||||||
|
|
||||||
chr = cd->open(opts);
|
chr = cd->open(opts);
|
||||||
if (!chr) {
|
if (!chr) {
|
||||||
error_setg(errp, "chardev: opening backend \"%s\" failed",
|
error_setg(errp, "chardev: opening backend \"%s\" failed",
|
||||||
|
Loading…
Reference in New Issue
Block a user