"Fossies" - the Fresh Open Source Software Archive  

Source code changes of the file "chardev/char.c" between
qemu-6.0.0-rc1.tar.xz and qemu-6.0.0-rc2.tar.xz

About: QEMU is a generic machine/processor emulator and virtualizer. Release candidate.

char.c  (qemu-6.0.0-rc1.tar.xz):char.c  (qemu-6.0.0-rc2.tar.xz)
skipping to change at line 42 skipping to change at line 42
#include "chardev/char.h" #include "chardev/char.h"
#include "qapi/error.h" #include "qapi/error.h"
#include "qapi/qapi-commands-char.h" #include "qapi/qapi-commands-char.h"
#include "qapi/qmp/qerror.h" #include "qapi/qmp/qerror.h"
#include "sysemu/replay.h" #include "sysemu/replay.h"
#include "qemu/help_option.h" #include "qemu/help_option.h"
#include "qemu/module.h" #include "qemu/module.h"
#include "qemu/option.h" #include "qemu/option.h"
#include "qemu/id.h" #include "qemu/id.h"
#include "qemu/coroutine.h" #include "qemu/coroutine.h"
#include "qemu/yank.h"
#include "chardev-internal.h" #include "chardev-internal.h"
/***********************************************************/ /***********************************************************/
/* character device */ /* character device */
Object *get_chardevs_root(void) Object *get_chardevs_root(void)
{ {
return container_get(object_get_root(), "/chardevs"); return container_get(object_get_root(), "/chardevs");
} }
skipping to change at line 269 skipping to change at line 270
if (cc->open) { if (cc->open) {
cc->open(chr, backend, be_opened, errp); cc->open(chr, backend, be_opened, errp);
} }
} }
static void char_init(Object *obj) static void char_init(Object *obj)
{ {
Chardev *chr = CHARDEV(obj); Chardev *chr = CHARDEV(obj);
chr->handover_yank_instance = false;
chr->logfd = -1; chr->logfd = -1;
qemu_mutex_init(&chr->chr_write_lock); qemu_mutex_init(&chr->chr_write_lock);
/* /*
* Assume if chr_update_read_handler is implemented it will * Assume if chr_update_read_handler is implemented it will
* take the updated gcontext into account. * take the updated gcontext into account.
*/ */
if (CHARDEV_GET_CLASS(chr)->chr_update_read_handler) { if (CHARDEV_GET_CLASS(chr)->chr_update_read_handler) {
qemu_chr_set_feature(chr, QEMU_CHAR_FEATURE_GCONTEXT); qemu_chr_set_feature(chr, QEMU_CHAR_FEATURE_GCONTEXT);
} }
skipping to change at line 962 skipping to change at line 964
void qemu_chr_set_feature(Chardev *chr, void qemu_chr_set_feature(Chardev *chr,
ChardevFeature feature) ChardevFeature feature)
{ {
return set_bit(feature, chr->features); return set_bit(feature, chr->features);
} }
static Chardev *chardev_new(const char *id, const char *typename, static Chardev *chardev_new(const char *id, const char *typename,
ChardevBackend *backend, ChardevBackend *backend,
GMainContext *gcontext, GMainContext *gcontext,
bool handover_yank_instance,
Error **errp) Error **errp)
{ {
Object *obj; Object *obj;
Chardev *chr = NULL; Chardev *chr = NULL;
Error *local_err = NULL; Error *local_err = NULL;
bool be_opened = true; bool be_opened = true;
assert(g_str_has_prefix(typename, "chardev-")); assert(g_str_has_prefix(typename, "chardev-"));
assert(id);
obj = object_new(typename); obj = object_new(typename);
chr = CHARDEV(obj); chr = CHARDEV(obj);
chr->handover_yank_instance = handover_yank_instance;
chr->label = g_strdup(id); chr->label = g_strdup(id);
chr->gcontext = gcontext; chr->gcontext = gcontext;
qemu_char_open(chr, backend, &be_opened, &local_err); qemu_char_open(chr, backend, &be_opened, &local_err);
if (local_err) { if (local_err) {
goto end; error_propagate(errp, local_err);
object_unref(obj);
return NULL;
} }
if (!chr->filename) { if (!chr->filename) {
chr->filename = g_strdup(typename + 8); chr->filename = g_strdup(typename + 8);
} }
if (be_opened) { if (be_opened) {
qemu_chr_be_event(chr, CHR_EVENT_OPENED); qemu_chr_be_event(chr, CHR_EVENT_OPENED);
} }
if (id) {
object_property_try_add_child(get_chardevs_root(), id, obj,
&local_err);
if (local_err) {
goto end;
}
object_unref(obj);
}
end:
if (local_err) {
error_propagate(errp, local_err);
object_unref(obj);
return NULL;
}
return chr; return chr;
} }
Chardev *qemu_chardev_new(const char *id, const char *typename, Chardev *qemu_chardev_new(const char *id, const char *typename,
ChardevBackend *backend, ChardevBackend *backend,
GMainContext *gcontext, GMainContext *gcontext,
Error **errp) Error **errp)
{ {
Chardev *chr;
g_autofree char *genid = NULL; g_autofree char *genid = NULL;
if (!id) { if (!id) {
genid = id_generate(ID_CHR); genid = id_generate(ID_CHR);
id = genid; id = genid;
} }
return chardev_new(id, typename, backend, gcontext, errp); chr = chardev_new(id, typename, backend, gcontext, false, errp);
if (!chr) {
return NULL;
}
if (!object_property_try_add_child(get_chardevs_root(), id, OBJECT(chr),
errp)) {
object_unref(OBJECT(chr));
return NULL;
}
object_unref(OBJECT(chr));
return chr;
} }
ChardevReturn *qmp_chardev_add(const char *id, ChardevBackend *backend, ChardevReturn *qmp_chardev_add(const char *id, ChardevBackend *backend,
Error **errp) Error **errp)
{ {
const ChardevClass *cc; const ChardevClass *cc;
ChardevReturn *ret; ChardevReturn *ret;
Chardev *chr; Chardev *chr;
cc = char_get_class(ChardevBackendKind_str(backend->type), errp); cc = char_get_class(ChardevBackendKind_str(backend->type), errp);
if (!cc) { if (!cc) {
return NULL; return NULL;
} }
chr = chardev_new(id, object_class_get_name(OBJECT_CLASS(cc)), chr = chardev_new(id, object_class_get_name(OBJECT_CLASS(cc)),
backend, NULL, errp); backend, NULL, false, errp);
if (!chr) { if (!chr) {
return NULL; return NULL;
} }
if (!object_property_try_add_child(get_chardevs_root(), id, OBJECT(chr),
errp)) {
object_unref(OBJECT(chr));
return NULL;
}
object_unref(OBJECT(chr));
ret = g_new0(ChardevReturn, 1); ret = g_new0(ChardevReturn, 1);
if (CHARDEV_IS_PTY(chr)) { if (CHARDEV_IS_PTY(chr)) {
ret->pty = g_strdup(chr->filename + 4); ret->pty = g_strdup(chr->filename + 4);
ret->has_pty = true; ret->has_pty = true;
} }
return ret; return ret;
} }
ChardevReturn *qmp_chardev_change(const char *id, ChardevBackend *backend, ChardevReturn *qmp_chardev_change(const char *id, ChardevBackend *backend,
Error **errp) Error **errp)
{ {
CharBackend *be; CharBackend *be;
const ChardevClass *cc; const ChardevClass *cc, *cc_new;
Chardev *chr, *chr_new; Chardev *chr, *chr_new;
bool closed_sent = false; bool closed_sent = false;
bool handover_yank_instance;
ChardevReturn *ret; ChardevReturn *ret;
chr = qemu_chr_find(id); chr = qemu_chr_find(id);
if (!chr) { if (!chr) {
error_setg(errp, "Chardev '%s' does not exist", id); error_setg(errp, "Chardev '%s' does not exist", id);
return NULL; return NULL;
} }
if (CHARDEV_IS_MUX(chr)) { if (CHARDEV_IS_MUX(chr)) {
error_setg(errp, "Mux device hotswap not supported yet"); error_setg(errp, "Mux device hotswap not supported yet");
skipping to change at line 1087 skipping to change at line 1099
/* easy case */ /* easy case */
object_unparent(OBJECT(chr)); object_unparent(OBJECT(chr));
return qmp_chardev_add(id, backend, errp); return qmp_chardev_add(id, backend, errp);
} }
if (!be->chr_be_change) { if (!be->chr_be_change) {
error_setg(errp, "Chardev user does not support chardev hotswap"); error_setg(errp, "Chardev user does not support chardev hotswap");
return NULL; return NULL;
} }
cc = char_get_class(ChardevBackendKind_str(backend->type), errp); cc = CHARDEV_GET_CLASS(chr);
if (!cc) { cc_new = char_get_class(ChardevBackendKind_str(backend->type), errp);
if (!cc_new) {
return NULL; return NULL;
} }
chr_new = chardev_new(NULL, object_class_get_name(OBJECT_CLASS(cc)), /*
backend, chr->gcontext, errp); * The new chardev should not register a yank instance if the current
* chardev has registered one already.
*/
handover_yank_instance = cc->supports_yank && cc_new->supports_yank;
chr_new = chardev_new(id, object_class_get_name(OBJECT_CLASS(cc_new)),
backend, chr->gcontext, handover_yank_instance, errp);
if (!chr_new) { if (!chr_new) {
return NULL; return NULL;
} }
chr_new->label = g_strdup(id);
if (chr->be_open && !chr_new->be_open) { if (chr->be_open && !chr_new->be_open) {
qemu_chr_be_event(chr, CHR_EVENT_CLOSED); qemu_chr_be_event(chr, CHR_EVENT_CLOSED);
closed_sent = true; closed_sent = true;
} }
chr->be = NULL; chr->be = NULL;
qemu_chr_fe_init(be, chr_new, &error_abort); qemu_chr_fe_init(be, chr_new, &error_abort);
if (be->chr_be_change(be->opaque) < 0) { if (be->chr_be_change(be->opaque) < 0) {
error_setg(errp, "Chardev '%s' change failed", chr_new->label); error_setg(errp, "Chardev '%s' change failed", chr_new->label);
chr_new->be = NULL; chr_new->be = NULL;
qemu_chr_fe_init(be, chr, &error_abort); qemu_chr_fe_init(be, chr, &error_abort);
if (closed_sent) { if (closed_sent) {
qemu_chr_be_event(chr, CHR_EVENT_OPENED); qemu_chr_be_event(chr, CHR_EVENT_OPENED);
} }
object_unref(OBJECT(chr_new)); object_unref(OBJECT(chr_new));
return NULL; return NULL;
} }
/* change successfull, clean up */
chr_new->handover_yank_instance = false;
/*
* When the old chardev is freed, it should not unregister the yank
* instance if the new chardev needs it.
*/
chr->handover_yank_instance = handover_yank_instance;
object_unparent(OBJECT(chr)); object_unparent(OBJECT(chr));
object_property_add_child(get_chardevs_root(), chr_new->label, object_property_add_child(get_chardevs_root(), chr_new->label,
OBJECT(chr_new)); OBJECT(chr_new));
object_unref(OBJECT(chr_new)); object_unref(OBJECT(chr_new));
ret = g_new0(ChardevReturn, 1); ret = g_new0(ChardevReturn, 1);
if (CHARDEV_IS_PTY(chr_new)) { if (CHARDEV_IS_PTY(chr_new)) {
ret->pty = g_strdup(chr_new->filename + 4); ret->pty = g_strdup(chr_new->filename + 4);
ret->has_pty = true; ret->has_pty = true;
} }
 End of changes. 17 change blocks. 
25 lines changed or deleted 52 lines changed or added

Home  |  About  |  Features  |  All  |  Newest  |  Dox  |  Diffs  |  RSS Feeds  |  Screenshots  |  Comments  |  Imprint  |  Privacy  |  HTTP(S)