* [Qemu-devel] [PATCH 0/3] chardev hotplug patch series @ 2012-10-17 10:09 Gerd Hoffmann 2012-10-17 10:09 ` [Qemu-devel] [PATCH 1/3] chardev: add error reporting for qemu_chr_new_from_opts Gerd Hoffmann ` (2 more replies) 0 siblings, 3 replies; 13+ messages in thread From: Gerd Hoffmann @ 2012-10-17 10:09 UTC (permalink / raw) To: qemu-devel; +Cc: Gerd Hoffmann Hi, Here comes the updated chardev hotplug patch series. Addressed most review comments. It's chardev-add and chardev-remove now. Parameters have been added to the schema. Little nits and spell fixes here and there. Making 'backend' an enum is tricky given that the actual implementation just turns the qdict into a QemuOpts, then goes piggyback on qemu_chr_new_from_opts(). Not rebased (yet) on top of the qom queue as I expect more discussions. please review, Gerd Gerd Hoffmann (3): chardev: add error reporting for qemu_chr_new_from_opts chardev: fix QemuOpts lifecycle chardev: add hotplug support. hmp-commands.hx | 32 +++++++++++++++++++++ hmp.c | 23 +++++++++++++++ hmp.h | 2 + qapi-schema.json | 47 ++++++++++++++++++++++++++++++ qemu-char.c | 83 ++++++++++++++++++++++++++++++++++++++++++++--------- qemu-char.h | 5 ++- qmp-commands.hx | 61 +++++++++++++++++++++++++++++++++++++++ vl.c | 8 ++++- 8 files changed, 244 insertions(+), 17 deletions(-) ^ permalink raw reply [flat|nested] 13+ messages in thread
* [Qemu-devel] [PATCH 1/3] chardev: add error reporting for qemu_chr_new_from_opts 2012-10-17 10:09 [Qemu-devel] [PATCH 0/3] chardev hotplug patch series Gerd Hoffmann @ 2012-10-17 10:09 ` Gerd Hoffmann 2012-10-17 16:22 ` Luiz Capitulino 2012-10-17 10:09 ` [Qemu-devel] [PATCH 2/3] chardev: fix QemuOpts lifecycle Gerd Hoffmann 2012-10-17 10:09 ` [Qemu-devel] [PATCH 3/3] chardev: add hotplug support Gerd Hoffmann 2 siblings, 1 reply; 13+ messages in thread From: Gerd Hoffmann @ 2012-10-17 10:09 UTC (permalink / raw) To: qemu-devel; +Cc: Gerd Hoffmann Signed-off-by: Gerd Hoffmann <kraxel@redhat.com> --- qemu-char.c | 24 +++++++++++++++--------- qemu-char.h | 3 ++- vl.c | 8 ++++++-- 3 files changed, 23 insertions(+), 12 deletions(-) diff --git a/qemu-char.c b/qemu-char.c index b082bae..e2e1da8 100644 --- a/qemu-char.c +++ b/qemu-char.c @@ -2755,19 +2755,20 @@ static const struct { }; CharDriverState *qemu_chr_new_from_opts(QemuOpts *opts, - void (*init)(struct CharDriverState *s)) + void (*init)(struct CharDriverState *s), + Error **errp) { CharDriverState *chr; int i; if (qemu_opts_id(opts) == NULL) { - fprintf(stderr, "chardev: no id specified\n"); + error_setg(errp, "chardev: no id specified\n"); return NULL; } if (qemu_opt_get(opts, "backend") == NULL) { - fprintf(stderr, "chardev: \"%s\" missing backend\n", - qemu_opts_id(opts)); + error_setg(errp, "chardev: \"%s\" missing backend\n", + qemu_opts_id(opts)); return NULL; } for (i = 0; i < ARRAY_SIZE(backend_table); i++) { @@ -2775,15 +2776,15 @@ CharDriverState *qemu_chr_new_from_opts(QemuOpts *opts, break; } if (i == ARRAY_SIZE(backend_table)) { - fprintf(stderr, "chardev: backend \"%s\" not found\n", - qemu_opt_get(opts, "backend")); + error_setg(errp, "chardev: backend \"%s\" not found\n", + qemu_opt_get(opts, "backend")); return NULL; } chr = backend_table[i].open(opts); if (!chr) { - fprintf(stderr, "chardev: opening backend \"%s\" failed\n", - qemu_opt_get(opts, "backend")); + error_setg(errp, "chardev: opening backend \"%s\" failed\n", + qemu_opt_get(opts, "backend")); return NULL; } @@ -2813,6 +2814,7 @@ CharDriverState *qemu_chr_new(const char *label, const char *filename, void (*in const char *p; CharDriverState *chr; QemuOpts *opts; + Error *err = NULL; if (strstart(filename, "chardev:", &p)) { return qemu_chr_find(p); @@ -2822,7 +2824,11 @@ CharDriverState *qemu_chr_new(const char *label, const char *filename, void (*in if (!opts) return NULL; - chr = qemu_chr_new_from_opts(opts, init); + chr = qemu_chr_new_from_opts(opts, init, &err); + if (error_is_set(&err)) { + fprintf(stderr, "%s\n", error_get_pretty(err)); + error_free(err); + } if (chr && qemu_opt_get_bool(opts, "mux", 0)) { monitor_init(chr, MONITOR_USE_READLINE); } diff --git a/qemu-char.h b/qemu-char.h index 486644b..adae13e 100644 --- a/qemu-char.h +++ b/qemu-char.h @@ -88,7 +88,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: diff --git a/vl.c b/vl.c index 5b357a3..d2f1c10 100644 --- a/vl.c +++ b/vl.c @@ -1940,10 +1940,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) + 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; } -- 1.7.1 ^ permalink raw reply related [flat|nested] 13+ messages in thread
* Re: [Qemu-devel] [PATCH 1/3] chardev: add error reporting for qemu_chr_new_from_opts 2012-10-17 10:09 ` [Qemu-devel] [PATCH 1/3] chardev: add error reporting for qemu_chr_new_from_opts Gerd Hoffmann @ 2012-10-17 16:22 ` Luiz Capitulino 0 siblings, 0 replies; 13+ messages in thread From: Luiz Capitulino @ 2012-10-17 16:22 UTC (permalink / raw) To: Gerd Hoffmann; +Cc: qemu-devel On Wed, 17 Oct 2012 12:09:53 +0200 Gerd Hoffmann <kraxel@redhat.com> wrote: > Signed-off-by: Gerd Hoffmann <kraxel@redhat.com> Reviewed-by: Luiz Capitulino <lcapitulino@redhat.com> > --- > qemu-char.c | 24 +++++++++++++++--------- > qemu-char.h | 3 ++- > vl.c | 8 ++++++-- > 3 files changed, 23 insertions(+), 12 deletions(-) > > diff --git a/qemu-char.c b/qemu-char.c > index b082bae..e2e1da8 100644 > --- a/qemu-char.c > +++ b/qemu-char.c > @@ -2755,19 +2755,20 @@ static const struct { > }; > > CharDriverState *qemu_chr_new_from_opts(QemuOpts *opts, > - void (*init)(struct CharDriverState *s)) > + void (*init)(struct CharDriverState *s), > + Error **errp) > { > CharDriverState *chr; > int i; > > if (qemu_opts_id(opts) == NULL) { > - fprintf(stderr, "chardev: no id specified\n"); > + error_setg(errp, "chardev: no id specified\n"); > return NULL; > } > > if (qemu_opt_get(opts, "backend") == NULL) { > - fprintf(stderr, "chardev: \"%s\" missing backend\n", > - qemu_opts_id(opts)); > + error_setg(errp, "chardev: \"%s\" missing backend\n", > + qemu_opts_id(opts)); > return NULL; > } > for (i = 0; i < ARRAY_SIZE(backend_table); i++) { > @@ -2775,15 +2776,15 @@ CharDriverState *qemu_chr_new_from_opts(QemuOpts *opts, > break; > } > if (i == ARRAY_SIZE(backend_table)) { > - fprintf(stderr, "chardev: backend \"%s\" not found\n", > - qemu_opt_get(opts, "backend")); > + error_setg(errp, "chardev: backend \"%s\" not found\n", > + qemu_opt_get(opts, "backend")); > return NULL; > } > > chr = backend_table[i].open(opts); > if (!chr) { > - fprintf(stderr, "chardev: opening backend \"%s\" failed\n", > - qemu_opt_get(opts, "backend")); > + error_setg(errp, "chardev: opening backend \"%s\" failed\n", > + qemu_opt_get(opts, "backend")); > return NULL; > } > > @@ -2813,6 +2814,7 @@ CharDriverState *qemu_chr_new(const char *label, const char *filename, void (*in > const char *p; > CharDriverState *chr; > QemuOpts *opts; > + Error *err = NULL; > > if (strstart(filename, "chardev:", &p)) { > return qemu_chr_find(p); > @@ -2822,7 +2824,11 @@ CharDriverState *qemu_chr_new(const char *label, const char *filename, void (*in > if (!opts) > return NULL; > > - chr = qemu_chr_new_from_opts(opts, init); > + chr = qemu_chr_new_from_opts(opts, init, &err); > + if (error_is_set(&err)) { > + fprintf(stderr, "%s\n", error_get_pretty(err)); > + error_free(err); > + } > if (chr && qemu_opt_get_bool(opts, "mux", 0)) { > monitor_init(chr, MONITOR_USE_READLINE); > } > diff --git a/qemu-char.h b/qemu-char.h > index 486644b..adae13e 100644 > --- a/qemu-char.h > +++ b/qemu-char.h > @@ -88,7 +88,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: > diff --git a/vl.c b/vl.c > index 5b357a3..d2f1c10 100644 > --- a/vl.c > +++ b/vl.c > @@ -1940,10 +1940,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) > + 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; > } > ^ permalink raw reply [flat|nested] 13+ messages in thread
* [Qemu-devel] [PATCH 2/3] chardev: fix QemuOpts lifecycle 2012-10-17 10:09 [Qemu-devel] [PATCH 0/3] chardev hotplug patch series Gerd Hoffmann 2012-10-17 10:09 ` [Qemu-devel] [PATCH 1/3] chardev: add error reporting for qemu_chr_new_from_opts Gerd Hoffmann @ 2012-10-17 10:09 ` Gerd Hoffmann 2012-10-17 16:40 ` Luiz Capitulino 2012-10-17 10:09 ` [Qemu-devel] [PATCH 3/3] chardev: add hotplug support Gerd Hoffmann 2 siblings, 1 reply; 13+ messages in thread From: Gerd Hoffmann @ 2012-10-17 10:09 UTC (permalink / raw) To: qemu-devel; +Cc: Gerd Hoffmann qemu_chr_new_from_opts handles QemuOpts release now, so callers don't have to worry. It will either be saved in CharDriverState, then released in qemu_chr_delete, or in the error case released instantly. Signed-off-by: Gerd Hoffmann <kraxel@redhat.com> --- qemu-char.c | 15 ++++++++++----- qemu-char.h | 1 + 2 files changed, 11 insertions(+), 5 deletions(-) diff --git a/qemu-char.c b/qemu-char.c index e2e1da8..be4ec61 100644 --- a/qemu-char.c +++ b/qemu-char.c @@ -2763,13 +2763,13 @@ CharDriverState *qemu_chr_new_from_opts(QemuOpts *opts, if (qemu_opts_id(opts) == NULL) { error_setg(errp, "chardev: no id specified\n"); - return NULL; + goto err; } if (qemu_opt_get(opts, "backend") == NULL) { error_setg(errp, "chardev: \"%s\" missing backend\n", qemu_opts_id(opts)); - return NULL; + goto err; } for (i = 0; i < ARRAY_SIZE(backend_table); i++) { if (strcmp(backend_table[i].name, qemu_opt_get(opts, "backend")) == 0) @@ -2778,14 +2778,14 @@ CharDriverState *qemu_chr_new_from_opts(QemuOpts *opts, if (i == ARRAY_SIZE(backend_table)) { error_setg(errp, "chardev: backend \"%s\" not found\n", qemu_opt_get(opts, "backend")); - return NULL; + goto err; } chr = backend_table[i].open(opts); if (!chr) { error_setg(errp, "chardev: opening backend \"%s\" failed\n", qemu_opt_get(opts, "backend")); - return NULL; + goto err; } if (!chr->filename) @@ -2806,7 +2806,12 @@ CharDriverState *qemu_chr_new_from_opts(QemuOpts *opts, chr->avail_connections = 1; } chr->label = g_strdup(qemu_opts_id(opts)); + chr->opts = opts; return chr; + +err: + qemu_opts_del(opts); + return NULL; } CharDriverState *qemu_chr_new(const char *label, const char *filename, void (*init)(struct CharDriverState *s)) @@ -2832,7 +2837,6 @@ CharDriverState *qemu_chr_new(const char *label, const char *filename, void (*in if (chr && qemu_opt_get_bool(opts, "mux", 0)) { monitor_init(chr, MONITOR_USE_READLINE); } - qemu_opts_del(opts); return chr; } @@ -2864,6 +2868,7 @@ void qemu_chr_delete(CharDriverState *chr) chr->chr_close(chr); g_free(chr->filename); g_free(chr->label); + qemu_opts_del(chr->opts); g_free(chr); } diff --git a/qemu-char.h b/qemu-char.h index adae13e..99bc132 100644 --- a/qemu-char.h +++ b/qemu-char.h @@ -74,6 +74,7 @@ struct CharDriverState { char *filename; int opened; int avail_connections; + QemuOpts *opts; QTAILQ_ENTRY(CharDriverState) next; }; -- 1.7.1 ^ permalink raw reply related [flat|nested] 13+ messages in thread
* Re: [Qemu-devel] [PATCH 2/3] chardev: fix QemuOpts lifecycle 2012-10-17 10:09 ` [Qemu-devel] [PATCH 2/3] chardev: fix QemuOpts lifecycle Gerd Hoffmann @ 2012-10-17 16:40 ` Luiz Capitulino 2012-10-18 9:26 ` Gerd Hoffmann 0 siblings, 1 reply; 13+ messages in thread From: Luiz Capitulino @ 2012-10-17 16:40 UTC (permalink / raw) To: Gerd Hoffmann; +Cc: qemu-devel On Wed, 17 Oct 2012 12:09:54 +0200 Gerd Hoffmann <kraxel@redhat.com> wrote: > qemu_chr_new_from_opts handles QemuOpts release now, so callers don't > have to worry. It will either be saved in CharDriverState, then > released in qemu_chr_delete, or in the error case released instantly. > > Signed-off-by: Gerd Hoffmann <kraxel@redhat.com> > --- > qemu-char.c | 15 ++++++++++----- > qemu-char.h | 1 + > 2 files changed, 11 insertions(+), 5 deletions(-) > > diff --git a/qemu-char.c b/qemu-char.c > index e2e1da8..be4ec61 100644 > --- a/qemu-char.c > +++ b/qemu-char.c > @@ -2763,13 +2763,13 @@ CharDriverState *qemu_chr_new_from_opts(QemuOpts *opts, > > if (qemu_opts_id(opts) == NULL) { > error_setg(errp, "chardev: no id specified\n"); > - return NULL; > + goto err; > } > > if (qemu_opt_get(opts, "backend") == NULL) { > error_setg(errp, "chardev: \"%s\" missing backend\n", > qemu_opts_id(opts)); > - return NULL; > + goto err; > } > for (i = 0; i < ARRAY_SIZE(backend_table); i++) { > if (strcmp(backend_table[i].name, qemu_opt_get(opts, "backend")) == 0) > @@ -2778,14 +2778,14 @@ CharDriverState *qemu_chr_new_from_opts(QemuOpts *opts, > if (i == ARRAY_SIZE(backend_table)) { > error_setg(errp, "chardev: backend \"%s\" not found\n", > qemu_opt_get(opts, "backend")); > - return NULL; > + goto err; > } > > chr = backend_table[i].open(opts); > if (!chr) { > error_setg(errp, "chardev: opening backend \"%s\" failed\n", > qemu_opt_get(opts, "backend")); > - return NULL; > + goto err; > } > > if (!chr->filename) > @@ -2806,7 +2806,12 @@ CharDriverState *qemu_chr_new_from_opts(QemuOpts *opts, > chr->avail_connections = 1; > } > chr->label = g_strdup(qemu_opts_id(opts)); > + chr->opts = opts; > return chr; > + > +err: > + qemu_opts_del(opts); > + return NULL; > } > > CharDriverState *qemu_chr_new(const char *label, const char *filename, void (*init)(struct CharDriverState *s)) > @@ -2832,7 +2837,6 @@ CharDriverState *qemu_chr_new(const char *label, const char *filename, void (*in > if (chr && qemu_opt_get_bool(opts, "mux", 0)) { > monitor_init(chr, MONITOR_USE_READLINE); > } > - qemu_opts_del(opts); > return chr; > } > > @@ -2864,6 +2868,7 @@ void qemu_chr_delete(CharDriverState *chr) > chr->chr_close(chr); > g_free(chr->filename); > g_free(chr->label); > + qemu_opts_del(chr->opts); > g_free(chr); > } Didn't consider this in my first review, but is chardev_init_func() fine with this? Basically, if we chardev_remove a device created by it (is this possible?) then the opts will be freed but it will remain inserted in its QemuOptsList. > > diff --git a/qemu-char.h b/qemu-char.h > index adae13e..99bc132 100644 > --- a/qemu-char.h > +++ b/qemu-char.h > @@ -74,6 +74,7 @@ struct CharDriverState { > char *filename; > int opened; > int avail_connections; > + QemuOpts *opts; > QTAILQ_ENTRY(CharDriverState) next; > }; > ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [Qemu-devel] [PATCH 2/3] chardev: fix QemuOpts lifecycle 2012-10-17 16:40 ` Luiz Capitulino @ 2012-10-18 9:26 ` Gerd Hoffmann 2012-10-18 13:30 ` Luiz Capitulino 0 siblings, 1 reply; 13+ messages in thread From: Gerd Hoffmann @ 2012-10-18 9:26 UTC (permalink / raw) To: Luiz Capitulino; +Cc: qemu-devel Hi, >> @@ -2864,6 +2868,7 @@ void qemu_chr_delete(CharDriverState *chr) >> chr->chr_close(chr); >> g_free(chr->filename); >> g_free(chr->label); >> + qemu_opts_del(chr->opts); >> g_free(chr); >> } > > Didn't consider this in my first review, but is chardev_init_func() fine > with this? Basically, if we chardev_remove a device created by it (is this > possible?) then the opts will be freed but it will remain inserted in its > QemuOptsList. Hmm? Don't see your issue here. qemu_opts_del will also unlink from QemuOptsList ... cheers, Gerd ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [Qemu-devel] [PATCH 2/3] chardev: fix QemuOpts lifecycle 2012-10-18 9:26 ` Gerd Hoffmann @ 2012-10-18 13:30 ` Luiz Capitulino 0 siblings, 0 replies; 13+ messages in thread From: Luiz Capitulino @ 2012-10-18 13:30 UTC (permalink / raw) To: Gerd Hoffmann; +Cc: qemu-devel On Thu, 18 Oct 2012 11:26:39 +0200 Gerd Hoffmann <kraxel@redhat.com> wrote: > Hi, > > >> @@ -2864,6 +2868,7 @@ void qemu_chr_delete(CharDriverState *chr) > >> chr->chr_close(chr); > >> g_free(chr->filename); > >> g_free(chr->label); > >> + qemu_opts_del(chr->opts); > >> g_free(chr); > >> } > > > > Didn't consider this in my first review, but is chardev_init_func() fine > > with this? Basically, if we chardev_remove a device created by it (is this > > possible?) then the opts will be freed but it will remain inserted in its > > QemuOptsList. > > Hmm? Don't see your issue here. > qemu_opts_del will also unlink from QemuOptsList ... Missed that fact, thanks for clarifying: Reviewed-by: Luiz Capitulino <lcapitulino@redhat.com> ^ permalink raw reply [flat|nested] 13+ messages in thread
* [Qemu-devel] [PATCH 3/3] chardev: add hotplug support. 2012-10-17 10:09 [Qemu-devel] [PATCH 0/3] chardev hotplug patch series Gerd Hoffmann 2012-10-17 10:09 ` [Qemu-devel] [PATCH 1/3] chardev: add error reporting for qemu_chr_new_from_opts Gerd Hoffmann 2012-10-17 10:09 ` [Qemu-devel] [PATCH 2/3] chardev: fix QemuOpts lifecycle Gerd Hoffmann @ 2012-10-17 10:09 ` Gerd Hoffmann 2012-10-17 15:26 ` Eric Blake 2012-10-18 10:03 ` Gerd Hoffmann 2 siblings, 2 replies; 13+ messages in thread From: Gerd Hoffmann @ 2012-10-17 10:09 UTC (permalink / raw) To: qemu-devel; +Cc: Gerd Hoffmann This patch adds chardev_add and chardev_remove monitor commands. They work similar to the netdev_{add,del} commands. The hmp version of chardev_add accepts like the -chardev command line option does. The qmp version expects the arguments being passed as named parameters. chardev_del just takes an id argument and zaps the chardev specified. Signed-off-by: Gerd Hoffmann <kraxel@redhat.com> --- hmp-commands.hx | 32 ++++++++++++++++++++++++++++ hmp.c | 23 ++++++++++++++++++++ hmp.h | 2 + qapi-schema.json | 47 +++++++++++++++++++++++++++++++++++++++++ qemu-char.c | 44 ++++++++++++++++++++++++++++++++++++++ qemu-char.h | 1 + qmp-commands.hx | 61 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 7 files changed, 210 insertions(+), 0 deletions(-) diff --git a/hmp-commands.hx b/hmp-commands.hx index e0b537d..5207383 100644 --- a/hmp-commands.hx +++ b/hmp-commands.hx @@ -1404,6 +1404,38 @@ passed since 1970, i.e. unix epoch. 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 + + { .name = "info", .args_type = "item:s?", .params = "[subcommand]", diff --git a/hmp.c b/hmp.c index 70bdec2..fc9d7bc 100644 --- a/hmp.c +++ b/hmp.c @@ -1209,3 +1209,26 @@ void hmp_screen_dump(Monitor *mon, const QDict *qdict) qmp_screendump(filename, &err); hmp_handle_error(mon, &err); } + +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 *err = NULL; + qmp_chardev_remove(qdict_get_str(qdict, "id"), + &err); + hmp_handle_error(mon, &err); +} diff --git a/hmp.h b/hmp.h index 71ea384..cabe944 100644 --- a/hmp.h +++ b/hmp.h @@ -75,5 +75,7 @@ void hmp_getfd(Monitor *mon, const QDict *qdict); void hmp_closefd(Monitor *mon, const QDict *qdict); void hmp_send_key(Monitor *mon, const QDict *qdict); void hmp_screen_dump(Monitor *mon, const QDict *qdict); +void hmp_chardev_add(Monitor *mon, const QDict *qdict); +void hmp_chardev_remove(Monitor *mon, const QDict *qdict); #endif diff --git a/qapi-schema.json b/qapi-schema.json index f9dbdae..fab6bbc 100644 --- a/qapi-schema.json +++ b/qapi-schema.json @@ -2796,3 +2796,50 @@ # Since: 0.14.0 ## { 'command': 'screendump', 'data': {'filename': 'str'} } + +## +# @chardev-add: +# +# Add a chardev +# +# @id: the chardev's ID, must be unique +# @backend: the chardev backend: "file", "socket", ... +# @path: file / device / unix socket path +# @name: spice channel name +# @host: host name +# @port: port number +# @server: create socket in server mode +# @wait: wait for connect +# @ipv4: force ipv4-only +# @ipv6: force ipv6-only +# @telnet: telnet negotiation +# +# Returns: Nothing on success +# +# Since: 1.3.0 +## +{ 'command': 'chardev-add', 'data': {'id' : 'str', + 'backend' : 'str', + '*path' : 'str', + '*name' : 'str', + '*host' : 'str', + '*port' : 'str', + '*server' : 'bool', + '*wait' : 'bool', + '*ipv4' : 'bool', + '*ipv6' : 'bool', + '*telnet' : 'bool' }, + 'gen': 'no' } + +## +# @chardev-remove: +# +# Remove a chardev +# +# @id: the chardev's ID, must exist and not be in use +# +# Returns: Nothing on success +# +# Since: 1.3.0 +## +{ 'command': 'chardev-remove', 'data': {'id': 'str'} } diff --git a/qemu-char.c b/qemu-char.c index be4ec61..cbfa24e 100644 --- a/qemu-char.c +++ b/qemu-char.c @@ -2911,3 +2911,47 @@ CharDriverState *qemu_char_get_next_serial(void) return serial_hds[next_serial++]; } +int qmp_chardev_add(Monitor *mon, const QDict *qdict, QObject **ret) +{ + Error *err = NULL; + QemuOptsList *opts_list; + QemuOpts *opts; + + opts_list = qemu_find_opts_err("chardev", &err); + if (error_is_set(&err)) { + goto exit_err; + } + + opts = qemu_opts_from_qdict(opts_list, qdict, &err); + if (error_is_set(&err)) { + goto exit_err; + } + + qemu_chr_new_from_opts(opts, NULL, &err); + if (error_is_set(&err)) { + goto exit_err; + } + return 0; + +exit_err: + qerror_report_err(err); + error_free(err); + return -1; +} + +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\n", id); + return; + } + if (chr->chr_can_read || chr->chr_read || + chr->chr_event || chr->handler_opaque) { + error_setg(errp, "Chardev '%s' is busy\n", id); + return; + } + qemu_chr_delete(chr); +} diff --git a/qemu-char.h b/qemu-char.h index 99bc132..407e0fe 100644 --- a/qemu-char.h +++ b/qemu-char.h @@ -238,6 +238,7 @@ void qemu_chr_info(Monitor *mon, QObject **ret_data); CharDriverState *qemu_chr_find(const char *name); QemuOpts *qemu_chr_parse_compat(const char *label, const char *filename); +int qmp_chardev_add(Monitor *mon, const QDict *qdict, QObject **ret); /* add an eventfd to the qemu devices that are polled */ CharDriverState *qemu_chr_open_eventfd(int eventfd); diff --git a/qmp-commands.hx b/qmp-commands.hx index 2f8477e..ea5fc71 100644 --- a/qmp-commands.hx +++ b/qmp-commands.hx @@ -2576,3 +2576,64 @@ EQMP .args_type = "", .mhandler.cmd_new = qmp_marshal_input_query_target, }, + + { + .name = "chardev-add", + .args_type = "", + .mhandler.cmd_new = qmp_chardev_add, + }, + +SQMP +chardev-add +----------- + +Add a chardev. + +Arguments: + +- "id": the chardev's ID, must be unique (json-string) +- "backend": the chardev backend: "file", "socket", ... (json-string) +- "path": file / device / unix socket path (json-string, optional) +- "name": spice channel name (json-string, optional) +- "host": host name (json-string, optional) +- "port": port number (json-string, optional) +- "server": create socket in server mode (json-bool, optional) +- "wait": wait for connect (json-bool, optional) +- "ipv4": force ipv4-only (json-bool, optional) +- "ipv6": force ipv6-only (json-bool, optional) +- "telnet": telnet negotiation (json-bool, optional) + +Example: + +-> { "execute": "chardev-add", "arguments": { "id" : "foo", + "backend" : "socket", + "path" : "/tmp/foo", + "server" : true, + "wait" : false } } +<- { "return": {} } + +EQMP + + { + .name = "chardev-remove", + .args_type = "", + .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 -- 1.7.1 ^ permalink raw reply related [flat|nested] 13+ messages in thread
* Re: [Qemu-devel] [PATCH 3/3] chardev: add hotplug support. 2012-10-17 10:09 ` [Qemu-devel] [PATCH 3/3] chardev: add hotplug support Gerd Hoffmann @ 2012-10-17 15:26 ` Eric Blake 2012-10-17 16:28 ` Paolo Bonzini 2012-10-18 10:03 ` Gerd Hoffmann 1 sibling, 1 reply; 13+ messages in thread From: Eric Blake @ 2012-10-17 15:26 UTC (permalink / raw) To: Gerd Hoffmann; +Cc: qemu-devel [-- Attachment #1: Type: text/plain, Size: 1110 bytes --] On 10/17/2012 04:09 AM, Gerd Hoffmann wrote: > This patch adds chardev_add and chardev_remove monitor commands. > > They work similar to the netdev_{add,del} commands. The hmp version of > chardev_add accepts like the -chardev command line option does. The qmp > version expects the arguments being passed as named parameters. > > chardev_del just takes an id argument and zaps the chardev specified. > > Signed-off-by: Gerd Hoffmann <kraxel@redhat.com> > --- > +## > +# @chardev-add: > +# > +# Add a chardev > +# > +# @id: the chardev's ID, must be unique > +# @backend: the chardev backend: "file", "socket", ... This still needs to be an enum. > +# @path: file / device / unix socket path > +# @name: spice channel name > +# @host: host name > +# @port: port number > +# @server: create socket in server mode > +# @wait: wait for connect > +# @ipv4: force ipv4-only > +# @ipv6: force ipv6-only > +# @telnet: telnet negotiation But this part looks nicer. -- Eric Blake eblake@redhat.com +1-919-301-3266 Libvirt virtualization library http://libvirt.org [-- Attachment #2: OpenPGP digital signature --] [-- Type: application/pgp-signature, Size: 617 bytes --] ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [Qemu-devel] [PATCH 3/3] chardev: add hotplug support. 2012-10-17 15:26 ` Eric Blake @ 2012-10-17 16:28 ` Paolo Bonzini 0 siblings, 0 replies; 13+ messages in thread From: Paolo Bonzini @ 2012-10-17 16:28 UTC (permalink / raw) To: Eric Blake; +Cc: Gerd Hoffmann, qemu-devel Il 17/10/2012 17:26, Eric Blake ha scritto: > On 10/17/2012 04:09 AM, Gerd Hoffmann wrote: >> This patch adds chardev_add and chardev_remove monitor commands. >> >> They work similar to the netdev_{add,del} commands. The hmp version of >> chardev_add accepts like the -chardev command line option does. The qmp >> version expects the arguments being passed as named parameters. >> >> chardev_del just takes an id argument and zaps the chardev specified. >> >> Signed-off-by: Gerd Hoffmann <kraxel@redhat.com> >> --- > >> +## >> +# @chardev-add: >> +# >> +# Add a chardev >> +# >> +# @id: the chardev's ID, must be unique >> +# @backend: the chardev backend: "file", "socket", ... > > This still needs to be an enum. > >> +# @path: file / device / unix socket path >> +# @name: spice channel name >> +# @host: host name >> +# @port: port number >> +# @server: create socket in server mode >> +# @wait: wait for connect >> +# @ipv4: force ipv4-only >> +# @ipv6: force ipv6-only >> +# @telnet: telnet negotiation > > But this part looks nicer. Note that this schema is just for documentation. It is not used at QEMU build time. Paolo ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [Qemu-devel] [PATCH 3/3] chardev: add hotplug support. 2012-10-17 10:09 ` [Qemu-devel] [PATCH 3/3] chardev: add hotplug support Gerd Hoffmann 2012-10-17 15:26 ` Eric Blake @ 2012-10-18 10:03 ` Gerd Hoffmann 2012-10-18 18:44 ` Paolo Bonzini 1 sibling, 1 reply; 13+ messages in thread From: Gerd Hoffmann @ 2012-10-18 10:03 UTC (permalink / raw) To: Gerd Hoffmann; +Cc: qemu-devel [-- Attachment #1: Type: text/plain, Size: 890 bytes --] On 10/17/12 12:09, Gerd Hoffmann wrote: > This patch adds chardev_add and chardev_remove monitor commands. > > They work similar to the netdev_{add,del} commands. The hmp version of > chardev_add accepts like the -chardev command line option does. The qmp > version expects the arguments being passed as named parameters. Trying another approach, see attached patch. This adds backend-specific qemu commands to add chardevs, with just the parameters needed for the specific backend. Starting with file and tty, both accepting a path. 'file' is nice for testing, 'tty' very useful when hotplugging serial devices on the host. Others can be added as needed. We probably don't need all of them. For example hotplugging the 'stdio' chardev doesn't make much sense. Advantage #1: Cleaner API. Advantage #2: No legacy syntax headache when qomifying chardevs. Comments? cheers, Gerd [-- Attachment #2: 0001-chardev-add-hotplug-support.patch --] [-- Type: text/plain, Size: 8216 bytes --] From 7f80af55530c9a448e4aed5a41c76a8e9514a27c Mon Sep 17 00:00:00 2001 From: Gerd Hoffmann <kraxel@redhat.com> Date: Thu, 11 Oct 2012 14:53:00 +0200 Subject: [PATCH] chardev: add hotplug support. This patch adds chardev_add_file, chardev_add_tty and chardev_remove monitor commands. chardev_add_file and chardev_add_tty expect an id and a path, they create a file/tty chardev. chardev_del just takes an id argument and zaps the chardev specified. Signed-off-by: Gerd Hoffmann <kraxel@redhat.com> --- hmp-commands.hx | 44 +++++++++++++++++++++++++++++++ hmp.c | 29 ++++++++++++++++++++ hmp.h | 3 ++ qapi-schema.json | 43 ++++++++++++++++++++++++++++++ qemu-char.c | 41 +++++++++++++++++++++++++++++ qemu-char.h | 2 + qmp-commands.hx | 76 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 7 files changed, 238 insertions(+), 0 deletions(-) diff --git a/hmp-commands.hx b/hmp-commands.hx index e0b537d..ecfc497 100644 --- a/hmp-commands.hx +++ b/hmp-commands.hx @@ -1404,6 +1404,50 @@ passed since 1970, i.e. unix epoch. ETEXI { + .name = "chardev_add_file", + .args_type = "id:s,path:s", + .params = "id path ", + .help = "add file chardev", + .mhandler.cmd = hmp_chardev_add_file, + }, + +STEXI +@item chardev_add_file id path +@findex chardev_add_file + +ETEXI + + { + .name = "chardev_add_tty", + .args_type = "id:s,path:s", + .params = "id path ", + .help = "add tty chardev", + .mhandler.cmd = hmp_chardev_add_tty, + }, + +STEXI +@item chardev_add_tty id path +@findex chardev_add_tty + +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 + + { .name = "info", .args_type = "item:s?", .params = "[subcommand]", diff --git a/hmp.c b/hmp.c index 70bdec2..346dd29 100644 --- a/hmp.c +++ b/hmp.c @@ -1209,3 +1209,32 @@ void hmp_screen_dump(Monitor *mon, const QDict *qdict) qmp_screendump(filename, &err); hmp_handle_error(mon, &err); } + +static void hmp_chardev_add_path(Monitor *mon, const QDict *qdict, + const char *backend) +{ + const char *id = qdict_get_str(qdict, "args"); + const char *path = qdict_get_str(qdict, "path"); + Error *local_err = NULL; + + qmp_chardev_add_path(id, path, backend, &local_err); + hmp_handle_error(mon, &local_err); +} + +void hmp_chardev_add_file(Monitor *mon, const QDict *qdict) +{ + hmp_chardev_add_path(mon, qdict, "file"); +} + +void hmp_chardev_add_tty(Monitor *mon, const QDict *qdict) +{ + hmp_chardev_add_path(mon, qdict, "tty"); +} + +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); +} diff --git a/hmp.h b/hmp.h index 71ea384..107941d 100644 --- a/hmp.h +++ b/hmp.h @@ -75,5 +75,8 @@ void hmp_getfd(Monitor *mon, const QDict *qdict); void hmp_closefd(Monitor *mon, const QDict *qdict); void hmp_send_key(Monitor *mon, const QDict *qdict); void hmp_screen_dump(Monitor *mon, const QDict *qdict); +void hmp_chardev_add_file(Monitor *mon, const QDict *qdict); +void hmp_chardev_add_tty(Monitor *mon, const QDict *qdict); +void hmp_chardev_remove(Monitor *mon, const QDict *qdict); #endif diff --git a/qapi-schema.json b/qapi-schema.json index f9dbdae..76e765b 100644 --- a/qapi-schema.json +++ b/qapi-schema.json @@ -2796,3 +2796,46 @@ # Since: 0.14.0 ## { 'command': 'screendump', 'data': {'filename': 'str'} } + +## +# @chardev-add-file: +# +# Add a file chardev +# +# @id: the chardev's ID, must be unique +# @path: file path +# +# Returns: Nothing on success +# +# Since: 1.3.0 +## +{ 'command': 'chardev-add-file', 'data': {'id' : 'str', + 'path' : 'str' } } + +## +# @chardev-add-tty: +# +# Add a terminal chardev +# +# @id: the chardev's ID, must be unique +# @path: device path +# +# Returns: Nothing on success +# +# Since: 1.3.0 +## +{ 'command': 'chardev-add-tty', 'data': {'id' : 'str', + 'path' : 'str' } } + +## +# @chardev-remove: +# +# Remove a chardev +# +# @id: the chardev's ID, must exist and not be in use +# +# Returns: Nothing on success +# +# Since: 1.3.0 +## +{ 'command': 'chardev-remove', 'data': {'id': 'str'} } diff --git a/qemu-char.c b/qemu-char.c index be4ec61..76c3396 100644 --- a/qemu-char.c +++ b/qemu-char.c @@ -2911,3 +2911,44 @@ CharDriverState *qemu_char_get_next_serial(void) return serial_hds[next_serial++]; } +void qmp_chardev_add_path(const char *id, const char *path, + const char *backend, Error **errp) +{ + QemuOpts *opts; + + opts = qemu_opts_create(qemu_find_opts("chardev"), id, 1, errp); + if (error_is_set(errp)) { + return; + } + + qemu_opt_set(opts, "path", path); + qemu_opt_set(opts, "backend", backend); + qemu_chr_new_from_opts(opts, NULL, errp); +} + +void qmp_chardev_add_file(const char *id, const char *path, Error **errp) +{ + qmp_chardev_add_path(id, path, "file", errp); +} + +void qmp_chardev_add_tty(const char *id, const char *path, Error **errp) +{ + qmp_chardev_add_path(id, path, "tty", errp); +} + +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\n", id); + return; + } + if (chr->chr_can_read || chr->chr_read || + chr->chr_event || chr->handler_opaque) { + error_setg(errp, "Chardev '%s' is busy\n", id); + return; + } + qemu_chr_delete(chr); +} diff --git a/qemu-char.h b/qemu-char.h index 99bc132..ffe4c79 100644 --- a/qemu-char.h +++ b/qemu-char.h @@ -238,6 +238,8 @@ void qemu_chr_info(Monitor *mon, QObject **ret_data); CharDriverState *qemu_chr_find(const char *name); QemuOpts *qemu_chr_parse_compat(const char *label, const char *filename); +void qmp_chardev_add_path(const char *id, const char *path, + const char *backend, Error **errp); /* add an eventfd to the qemu devices that are polled */ CharDriverState *qemu_chr_open_eventfd(int eventfd); diff --git a/qmp-commands.hx b/qmp-commands.hx index 2f8477e..73c02ed 100644 --- a/qmp-commands.hx +++ b/qmp-commands.hx @@ -2576,3 +2576,79 @@ EQMP .args_type = "", .mhandler.cmd_new = qmp_marshal_input_query_target, }, + + { + .name = "chardev-add-file", + .args_type = "", + .mhandler.cmd_new = qmp_marshal_input_chardev_add_file, + }, + +SQMP +chardev-add-file +---------------- + +Add a file chardev. + +Arguments: + +- "id": the chardev's ID, must be unique (json-string) +- "path": file path (json-string) + +Example: + +-> { "execute" : "chardev-add-file", + "arguments" : { "id" : "foo", + "path" : "/tmp/foo" } } +<- { "return": {} } + +EQMP + + { + .name = "chardev-add-tty", + .args_type = "", + .mhandler.cmd_new = qmp_marshal_input_chardev_add_tty, + }, + +SQMP +chardev-add-tty +--------------- + +Add a terminal chardev. + +Arguments: + +- "id": the chardev's ID, must be unique (json-string) +- "path": device path (json-string) + +Example: + +-> { "execute" : "chardev-add-tty", + "arguments" : { "id" : "serial", + "path" : "/dev/ttyS0" } } +<- { "return": {} } + +EQMP + + { + .name = "chardev-remove", + .args_type = "", + .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 -- 1.7.1 ^ permalink raw reply related [flat|nested] 13+ messages in thread
* Re: [Qemu-devel] [PATCH 3/3] chardev: add hotplug support. 2012-10-18 10:03 ` Gerd Hoffmann @ 2012-10-18 18:44 ` Paolo Bonzini 0 siblings, 0 replies; 13+ messages in thread From: Paolo Bonzini @ 2012-10-18 18:44 UTC (permalink / raw) To: Gerd Hoffmann; +Cc: qemu-devel Il 18/10/2012 12:03, Gerd Hoffmann ha scritto: > Trying another approach, see attached patch. This adds backend-specific > qemu commands to add chardevs, with just the parameters needed for the > specific backend. Starting with file and tty, both accepting a path. > 'file' is nice for testing, 'tty' very useful when hotplugging serial > devices on the host. Others can be added as needed. We probably don't > need all of them. For example hotplugging the 'stdio' chardev doesn't > make much sense. > > Advantage #1: Cleaner API. > Advantage #2: No legacy syntax headache when qomifying chardevs. Disadvantage #1: Harder to extend, more code Disadvantage #2: Different from all other kinds of host devices. I still prefer the other one. Paolo ^ permalink raw reply [flat|nested] 13+ messages in thread
* [Qemu-devel] [PATCH RESENT 0/3] chardev hotplug patch series @ 2012-12-14 9:38 Gerd Hoffmann 2012-12-14 9:38 ` [Qemu-devel] [PATCH 2/3] chardev: fix QemuOpts lifecycle Gerd Hoffmann 0 siblings, 1 reply; 13+ messages in thread From: Gerd Hoffmann @ 2012-12-14 9:38 UTC (permalink / raw) To: qemu-devel; +Cc: Gerd Hoffmann Hi, Got stuck in discussions & 1.3 freeze. Resending series to resume merge effort, almost unmodified, only rebased & trivial conflicts resolved. please review & comment, Gerd Gerd Hoffmann (3): chardev: add error reporting for qemu_chr_new_from_opts chardev: fix QemuOpts lifecycle chardev: add hotplug support. hmp-commands.hx | 44 +++++++++++++++++++++++++++++ hmp.c | 29 +++++++++++++++++++ hmp.h | 3 ++ qapi-schema.json | 43 +++++++++++++++++++++++++++++ qemu-char.c | 80 ++++++++++++++++++++++++++++++++++++++++++++--------- qemu-char.h | 6 +++- qmp-commands.hx | 76 +++++++++++++++++++++++++++++++++++++++++++++++++++ vl.c | 9 ++++-- 8 files changed, 272 insertions(+), 18 deletions(-) ^ permalink raw reply [flat|nested] 13+ messages in thread
* [Qemu-devel] [PATCH 2/3] chardev: fix QemuOpts lifecycle 2012-12-14 9:38 [Qemu-devel] [PATCH RESENT 0/3] chardev hotplug patch series Gerd Hoffmann @ 2012-12-14 9:38 ` Gerd Hoffmann 0 siblings, 0 replies; 13+ messages in thread From: Gerd Hoffmann @ 2012-12-14 9:38 UTC (permalink / raw) To: qemu-devel; +Cc: Gerd Hoffmann qemu_chr_new_from_opts handles QemuOpts release now, so callers don't have to worry. It will either be saved in CharDriverState, then released in qemu_chr_delete, or in the error case released instantly. Signed-off-by: Gerd Hoffmann <kraxel@redhat.com> --- qemu-char.c | 15 ++++++++++----- qemu-char.h | 1 + 2 files changed, 11 insertions(+), 5 deletions(-) diff --git a/qemu-char.c b/qemu-char.c index 5b91228..876714f 100644 --- a/qemu-char.c +++ b/qemu-char.c @@ -2774,13 +2774,13 @@ CharDriverState *qemu_chr_new_from_opts(QemuOpts *opts, if (qemu_opts_id(opts) == NULL) { error_setg(errp, "chardev: no id specified\n"); - return NULL; + goto err; } if (qemu_opt_get(opts, "backend") == NULL) { error_setg(errp, "chardev: \"%s\" missing backend\n", qemu_opts_id(opts)); - return NULL; + goto err; } for (i = 0; i < ARRAY_SIZE(backend_table); i++) { if (strcmp(backend_table[i].name, qemu_opt_get(opts, "backend")) == 0) @@ -2789,14 +2789,14 @@ CharDriverState *qemu_chr_new_from_opts(QemuOpts *opts, if (i == ARRAY_SIZE(backend_table)) { error_setg(errp, "chardev: backend \"%s\" not found\n", qemu_opt_get(opts, "backend")); - return NULL; + goto err; } chr = backend_table[i].open(opts); if (!chr) { error_setg(errp, "chardev: opening backend \"%s\" failed\n", qemu_opt_get(opts, "backend")); - return NULL; + goto err; } if (!chr->filename) @@ -2817,7 +2817,12 @@ CharDriverState *qemu_chr_new_from_opts(QemuOpts *opts, chr->avail_connections = 1; } chr->label = g_strdup(qemu_opts_id(opts)); + chr->opts = opts; return chr; + +err: + qemu_opts_del(opts); + return NULL; } CharDriverState *qemu_chr_new(const char *label, const char *filename, void (*init)(struct CharDriverState *s)) @@ -2843,7 +2848,6 @@ CharDriverState *qemu_chr_new(const char *label, const char *filename, void (*in if (chr && qemu_opt_get_bool(opts, "mux", 0)) { monitor_init(chr, MONITOR_USE_READLINE); } - qemu_opts_del(opts); return chr; } @@ -2875,6 +2879,7 @@ void qemu_chr_delete(CharDriverState *chr) chr->chr_close(chr); g_free(chr->filename); g_free(chr->label); + qemu_opts_del(chr->opts); g_free(chr); } diff --git a/qemu-char.h b/qemu-char.h index d7eed34..f984071 100644 --- a/qemu-char.h +++ b/qemu-char.h @@ -75,6 +75,7 @@ struct CharDriverState { char *filename; int opened; int avail_connections; + QemuOpts *opts; QTAILQ_ENTRY(CharDriverState) next; }; -- 1.7.1 ^ permalink raw reply related [flat|nested] 13+ messages in thread
end of thread, other threads:[~2012-12-14 9:38 UTC | newest] Thread overview: 13+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2012-10-17 10:09 [Qemu-devel] [PATCH 0/3] chardev hotplug patch series Gerd Hoffmann 2012-10-17 10:09 ` [Qemu-devel] [PATCH 1/3] chardev: add error reporting for qemu_chr_new_from_opts Gerd Hoffmann 2012-10-17 16:22 ` Luiz Capitulino 2012-10-17 10:09 ` [Qemu-devel] [PATCH 2/3] chardev: fix QemuOpts lifecycle Gerd Hoffmann 2012-10-17 16:40 ` Luiz Capitulino 2012-10-18 9:26 ` Gerd Hoffmann 2012-10-18 13:30 ` Luiz Capitulino 2012-10-17 10:09 ` [Qemu-devel] [PATCH 3/3] chardev: add hotplug support Gerd Hoffmann 2012-10-17 15:26 ` Eric Blake 2012-10-17 16:28 ` Paolo Bonzini 2012-10-18 10:03 ` Gerd Hoffmann 2012-10-18 18:44 ` Paolo Bonzini -- strict thread matches above, loose matches on Subject: below -- 2012-12-14 9:38 [Qemu-devel] [PATCH RESENT 0/3] chardev hotplug patch series Gerd Hoffmann 2012-12-14 9:38 ` [Qemu-devel] [PATCH 2/3] chardev: fix QemuOpts lifecycle Gerd Hoffmann
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for NNTP newsgroup(s).