qemu/chardev/char.c
<<
>>
Prefs
   1/*
   2 * QEMU System Emulator
   3 *
   4 * Copyright (c) 2003-2008 Fabrice Bellard
   5 *
   6 * Permission is hereby granted, free of charge, to any person obtaining a copy
   7 * of this software and associated documentation files (the "Software"), to deal
   8 * in the Software without restriction, including without limitation the rights
   9 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  10 * copies of the Software, and to permit persons to whom the Software is
  11 * furnished to do so, subject to the following conditions:
  12 *
  13 * The above copyright notice and this permission notice shall be included in
  14 * all copies or substantial portions of the Software.
  15 *
  16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
  19 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  21 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  22 * THE SOFTWARE.
  23 */
  24
  25#include "qemu/osdep.h"
  26#include "qemu/cutils.h"
  27#include "monitor/monitor.h"
  28#include "monitor/qmp-helpers.h"
  29#include "qemu/config-file.h"
  30#include "qemu/error-report.h"
  31#include "qemu/qemu-print.h"
  32#include "chardev/char.h"
  33#include "qapi/error.h"
  34#include "qapi/qapi-commands-char.h"
  35#include "qapi/qmp/qerror.h"
  36#include "sysemu/replay.h"
  37#include "qemu/help_option.h"
  38#include "qemu/module.h"
  39#include "qemu/option.h"
  40#include "qemu/id.h"
  41#include "qemu/coroutine.h"
  42#include "qemu/yank.h"
  43
  44#include "chardev-internal.h"
  45
  46/***********************************************************/
  47/* character device */
  48
  49Object *get_chardevs_root(void)
  50{
  51    return container_get(object_get_root(), "/chardevs");
  52}
  53
  54static void chr_be_event(Chardev *s, QEMUChrEvent event)
  55{
  56    CharBackend *be = s->be;
  57
  58    if (!be || !be->chr_event) {
  59        return;
  60    }
  61
  62    be->chr_event(be->opaque, event);
  63}
  64
  65void qemu_chr_be_event(Chardev *s, QEMUChrEvent event)
  66{
  67    /* Keep track if the char device is open */
  68    switch (event) {
  69        case CHR_EVENT_OPENED:
  70            s->be_open = 1;
  71            break;
  72        case CHR_EVENT_CLOSED:
  73            s->be_open = 0;
  74            break;
  75    case CHR_EVENT_BREAK:
  76    case CHR_EVENT_MUX_IN:
  77    case CHR_EVENT_MUX_OUT:
  78        /* Ignore */
  79        break;
  80    }
  81
  82    CHARDEV_GET_CLASS(s)->chr_be_event(s, event);
  83}
  84
  85/* Not reporting errors from writing to logfile, as logs are
  86 * defined to be "best effort" only */
  87static void qemu_chr_write_log(Chardev *s, const uint8_t *buf, size_t len)
  88{
  89    size_t done = 0;
  90    ssize_t ret;
  91
  92    if (s->logfd < 0) {
  93        return;
  94    }
  95
  96    while (done < len) {
  97    retry:
  98        ret = write(s->logfd, buf + done, len - done);
  99        if (ret == -1 && errno == EAGAIN) {
 100            g_usleep(100);
 101            goto retry;
 102        }
 103
 104        if (ret <= 0) {
 105            return;
 106        }
 107        done += ret;
 108    }
 109}
 110
 111static int qemu_chr_write_buffer(Chardev *s,
 112                                 const uint8_t *buf, int len,
 113                                 int *offset, bool write_all)
 114{
 115    ChardevClass *cc = CHARDEV_GET_CLASS(s);
 116    int res = 0;
 117    *offset = 0;
 118
 119    qemu_mutex_lock(&s->chr_write_lock);
 120    while (*offset < len) {
 121    retry:
 122        res = cc->chr_write(s, buf + *offset, len - *offset);
 123        if (res < 0 && errno == EAGAIN && write_all) {
 124            if (qemu_in_coroutine()) {
 125                qemu_co_sleep_ns(QEMU_CLOCK_REALTIME, 100000);
 126            } else {
 127                g_usleep(100);
 128            }
 129            goto retry;
 130        }
 131
 132        if (res <= 0) {
 133            break;
 134        }
 135
 136        *offset += res;
 137        if (!write_all) {
 138            break;
 139        }
 140    }
 141    if (*offset > 0) {
 142        /*
 143         * If some data was written by backend, we should
 144         * only log what was actually written. This method
 145         * may be invoked again to write the remaining
 146         * method, thus we'll log the remainder at that time.
 147         */
 148        qemu_chr_write_log(s, buf, *offset);
 149    } else if (res < 0) {
 150        /*
 151         * If a fatal error was reported by the backend,
 152         * assume this method won't be invoked again with
 153         * this buffer, so log it all right away.
 154         */
 155        qemu_chr_write_log(s, buf, len);
 156    }
 157    qemu_mutex_unlock(&s->chr_write_lock);
 158
 159    return res;
 160}
 161
 162int qemu_chr_write(Chardev *s, const uint8_t *buf, int len, bool write_all)
 163{
 164    int offset = 0;
 165    int res;
 166
 167    if (qemu_chr_replay(s) && replay_mode == REPLAY_MODE_PLAY) {
 168        replay_char_write_event_load(&res, &offset);
 169        assert(offset <= len);
 170        qemu_chr_write_buffer(s, buf, offset, &offset, true);
 171        return res;
 172    }
 173
 174    res = qemu_chr_write_buffer(s, buf, len, &offset, write_all);
 175
 176    if (qemu_chr_replay(s) && replay_mode == REPLAY_MODE_RECORD) {
 177        replay_char_write_event_save(res, offset);
 178    }
 179
 180    if (res < 0) {
 181        return res;
 182    }
 183    return offset;
 184}
 185
 186int qemu_chr_be_can_write(Chardev *s)
 187{
 188    CharBackend *be = s->be;
 189
 190    if (!be || !be->chr_can_read) {
 191        return 0;
 192    }
 193
 194    return be->chr_can_read(be->opaque);
 195}
 196
 197void qemu_chr_be_write_impl(Chardev *s, const uint8_t *buf, int len)
 198{
 199    CharBackend *be = s->be;
 200
 201    if (be && be->chr_read) {
 202        be->chr_read(be->opaque, buf, len);
 203    }
 204}
 205
 206void qemu_chr_be_write(Chardev *s, const uint8_t *buf, int len)
 207{
 208    if (qemu_chr_replay(s)) {
 209        if (replay_mode == REPLAY_MODE_PLAY) {
 210            return;
 211        }
 212        replay_chr_be_write(s, buf, len);
 213    } else {
 214        qemu_chr_be_write_impl(s, buf, len);
 215    }
 216}
 217
 218void qemu_chr_be_update_read_handlers(Chardev *s,
 219                                      GMainContext *context)
 220{
 221    ChardevClass *cc = CHARDEV_GET_CLASS(s);
 222
 223    assert(qemu_chr_has_feature(s, QEMU_CHAR_FEATURE_GCONTEXT)
 224           || !context);
 225    s->gcontext = context;
 226    if (cc->chr_update_read_handler) {
 227        cc->chr_update_read_handler(s);
 228    }
 229}
 230
 231int qemu_chr_add_client(Chardev *s, int fd)
 232{
 233    return CHARDEV_GET_CLASS(s)->chr_add_client ?
 234        CHARDEV_GET_CLASS(s)->chr_add_client(s, fd) : -1;
 235}
 236
 237static void qemu_char_open(Chardev *chr, ChardevBackend *backend,
 238                           bool *be_opened, Error **errp)
 239{
 240    ChardevClass *cc = CHARDEV_GET_CLASS(chr);
 241    /* Any ChardevCommon member would work */
 242    ChardevCommon *common = backend ? backend->u.null.data : NULL;
 243
 244    if (common && common->logfile) {
 245        int flags = O_WRONLY;
 246        if (common->has_logappend &&
 247            common->logappend) {
 248            flags |= O_APPEND;
 249        } else {
 250            flags |= O_TRUNC;
 251        }
 252        chr->logfd = qemu_create(common->logfile, flags, 0666, errp);
 253        if (chr->logfd < 0) {
 254            return;
 255        }
 256    }
 257
 258    if (cc->open) {
 259        cc->open(chr, backend, be_opened, errp);
 260    }
 261}
 262
 263static void char_init(Object *obj)
 264{
 265    Chardev *chr = CHARDEV(obj);
 266
 267    chr->handover_yank_instance = false;
 268    chr->logfd = -1;
 269    qemu_mutex_init(&chr->chr_write_lock);
 270
 271    /*
 272     * Assume if chr_update_read_handler is implemented it will
 273     * take the updated gcontext into account.
 274     */
 275    if (CHARDEV_GET_CLASS(chr)->chr_update_read_handler) {
 276        qemu_chr_set_feature(chr, QEMU_CHAR_FEATURE_GCONTEXT);
 277    }
 278
 279}
 280
 281static int null_chr_write(Chardev *chr, const uint8_t *buf, int len)
 282{
 283    return len;
 284}
 285
 286static void char_class_init(ObjectClass *oc, void *data)
 287{
 288    ChardevClass *cc = CHARDEV_CLASS(oc);
 289
 290    cc->chr_write = null_chr_write;
 291    cc->chr_be_event = chr_be_event;
 292}
 293
 294static void char_finalize(Object *obj)
 295{
 296    Chardev *chr = CHARDEV(obj);
 297
 298    if (chr->be) {
 299        chr->be->chr = NULL;
 300    }
 301    g_free(chr->filename);
 302    g_free(chr->label);
 303    if (chr->logfd != -1) {
 304        close(chr->logfd);
 305    }
 306    qemu_mutex_destroy(&chr->chr_write_lock);
 307}
 308
 309static const TypeInfo char_type_info = {
 310    .name = TYPE_CHARDEV,
 311    .parent = TYPE_OBJECT,
 312    .instance_size = sizeof(Chardev),
 313    .instance_init = char_init,
 314    .instance_finalize = char_finalize,
 315    .abstract = true,
 316    .class_size = sizeof(ChardevClass),
 317    .class_init = char_class_init,
 318};
 319
 320static bool qemu_chr_is_busy(Chardev *s)
 321{
 322    if (CHARDEV_IS_MUX(s)) {
 323        MuxChardev *d = MUX_CHARDEV(s);
 324        return d->mux_cnt >= 0;
 325    } else {
 326        return s->be != NULL;
 327    }
 328}
 329
 330int qemu_chr_wait_connected(Chardev *chr, Error **errp)
 331{
 332    ChardevClass *cc = CHARDEV_GET_CLASS(chr);
 333
 334    if (cc->chr_wait_connected) {
 335        return cc->chr_wait_connected(chr, errp);
 336    }
 337
 338    return 0;
 339}
 340
 341QemuOpts *qemu_chr_parse_compat(const char *label, const char *filename,
 342                                bool permit_mux_mon)
 343{
 344    char host[65], port[33], width[8], height[8];
 345    int pos;
 346    const char *p;
 347    QemuOpts *opts;
 348    Error *local_err = NULL;
 349
 350    opts = qemu_opts_create(qemu_find_opts("chardev"), label, 1, &local_err);
 351    if (local_err) {
 352        error_report_err(local_err);
 353        return NULL;
 354    }
 355
 356    if (strstart(filename, "mon:", &p)) {
 357        if (!permit_mux_mon) {
 358            error_report("mon: isn't supported in this context");
 359            return NULL;
 360        }
 361        filename = p;
 362        qemu_opt_set(opts, "mux", "on", &error_abort);
 363        if (strcmp(filename, "stdio") == 0) {
 364            /* Monitor is muxed to stdio: do not exit on Ctrl+C by default
 365             * but pass it to the guest.  Handle this only for compat syntax,
 366             * for -chardev syntax we have special option for this.
 367             * This is what -nographic did, redirecting+muxing serial+monitor
 368             * to stdio causing Ctrl+C to be passed to guest. */
 369            qemu_opt_set(opts, "signal", "off", &error_abort);
 370        }
 371    }
 372
 373    if (strcmp(filename, "null")    == 0 ||
 374        strcmp(filename, "pty")     == 0 ||
 375        strcmp(filename, "msmouse") == 0 ||
 376        strcmp(filename, "wctablet") == 0 ||
 377        strcmp(filename, "braille") == 0 ||
 378        strcmp(filename, "testdev") == 0 ||
 379        strcmp(filename, "stdio")   == 0) {
 380        qemu_opt_set(opts, "backend", filename, &error_abort);
 381        return opts;
 382    }
 383    if (strstart(filename, "vc", &p)) {
 384        qemu_opt_set(opts, "backend", "vc", &error_abort);
 385        if (*p == ':') {
 386            if (sscanf(p+1, "%7[0-9]x%7[0-9]", width, height) == 2) {
 387                /* pixels */
 388                qemu_opt_set(opts, "width", width, &error_abort);
 389                qemu_opt_set(opts, "height", height, &error_abort);
 390            } else if (sscanf(p+1, "%7[0-9]Cx%7[0-9]C", width, height) == 2) {
 391                /* chars */
 392                qemu_opt_set(opts, "cols", width, &error_abort);
 393                qemu_opt_set(opts, "rows", height, &error_abort);
 394            } else {
 395                goto fail;
 396            }
 397        }
 398        return opts;
 399    }
 400    if (strcmp(filename, "con:") == 0) {
 401        qemu_opt_set(opts, "backend", "console", &error_abort);
 402        return opts;
 403    }
 404    if (strstart(filename, "COM", NULL)) {
 405        qemu_opt_set(opts, "backend", "serial", &error_abort);
 406        qemu_opt_set(opts, "path", filename, &error_abort);
 407        return opts;
 408    }
 409    if (strstart(filename, "file:", &p)) {
 410        qemu_opt_set(opts, "backend", "file", &error_abort);
 411        qemu_opt_set(opts, "path", p, &error_abort);
 412        return opts;
 413    }
 414    if (strstart(filename, "pipe:", &p)) {
 415        qemu_opt_set(opts, "backend", "pipe", &error_abort);
 416        qemu_opt_set(opts, "path", p, &error_abort);
 417        return opts;
 418    }
 419    if (strstart(filename, "tcp:", &p) ||
 420        strstart(filename, "telnet:", &p) ||
 421        strstart(filename, "tn3270:", &p) ||
 422        strstart(filename, "websocket:", &p)) {
 423        if (sscanf(p, "%64[^:]:%32[^,]%n", host, port, &pos) < 2) {
 424            host[0] = 0;
 425            if (sscanf(p, ":%32[^,]%n", port, &pos) < 1)
 426                goto fail;
 427        }
 428        qemu_opt_set(opts, "backend", "socket", &error_abort);
 429        qemu_opt_set(opts, "host", host, &error_abort);
 430        qemu_opt_set(opts, "port", port, &error_abort);
 431        if (p[pos] == ',') {
 432            if (!qemu_opts_do_parse(opts, p + pos + 1, NULL, &local_err)) {
 433                error_report_err(local_err);
 434                goto fail;
 435            }
 436        }
 437        if (strstart(filename, "telnet:", &p)) {
 438            qemu_opt_set(opts, "telnet", "on", &error_abort);
 439        } else if (strstart(filename, "tn3270:", &p)) {
 440            qemu_opt_set(opts, "tn3270", "on", &error_abort);
 441        } else if (strstart(filename, "websocket:", &p)) {
 442            qemu_opt_set(opts, "websocket", "on", &error_abort);
 443        }
 444        return opts;
 445    }
 446    if (strstart(filename, "udp:", &p)) {
 447        qemu_opt_set(opts, "backend", "udp", &error_abort);
 448        if (sscanf(p, "%64[^:]:%32[^@,]%n", host, port, &pos) < 2) {
 449            host[0] = 0;
 450            if (sscanf(p, ":%32[^@,]%n", port, &pos) < 1) {
 451                goto fail;
 452            }
 453        }
 454        qemu_opt_set(opts, "host", host, &error_abort);
 455        qemu_opt_set(opts, "port", port, &error_abort);
 456        if (p[pos] == '@') {
 457            p += pos + 1;
 458            if (sscanf(p, "%64[^:]:%32[^,]%n", host, port, &pos) < 2) {
 459                host[0] = 0;
 460                if (sscanf(p, ":%32[^,]%n", port, &pos) < 1) {
 461                    goto fail;
 462                }
 463            }
 464            qemu_opt_set(opts, "localaddr", host, &error_abort);
 465            qemu_opt_set(opts, "localport", port, &error_abort);
 466        }
 467        return opts;
 468    }
 469    if (strstart(filename, "unix:", &p)) {
 470        qemu_opt_set(opts, "backend", "socket", &error_abort);
 471        if (!qemu_opts_do_parse(opts, p, "path", &local_err)) {
 472            error_report_err(local_err);
 473            goto fail;
 474        }
 475        return opts;
 476    }
 477    if (strstart(filename, "/dev/parport", NULL) ||
 478        strstart(filename, "/dev/ppi", NULL)) {
 479        qemu_opt_set(opts, "backend", "parallel", &error_abort);
 480        qemu_opt_set(opts, "path", filename, &error_abort);
 481        return opts;
 482    }
 483    if (strstart(filename, "/dev/", NULL)) {
 484        qemu_opt_set(opts, "backend", "serial", &error_abort);
 485        qemu_opt_set(opts, "path", filename, &error_abort);
 486        return opts;
 487    }
 488
 489    error_report("'%s' is not a valid char driver", filename);
 490
 491fail:
 492    qemu_opts_del(opts);
 493    return NULL;
 494}
 495
 496void qemu_chr_parse_common(QemuOpts *opts, ChardevCommon *backend)
 497{
 498    const char *logfile = qemu_opt_get(opts, "logfile");
 499
 500    backend->logfile = g_strdup(logfile);
 501    backend->has_logappend = true;
 502    backend->logappend = qemu_opt_get_bool(opts, "logappend", false);
 503}
 504
 505static const ChardevClass *char_get_class(const char *driver, Error **errp)
 506{
 507    ObjectClass *oc;
 508    const ChardevClass *cc;
 509    char *typename = g_strdup_printf("chardev-%s", driver);
 510
 511    oc = module_object_class_by_name(typename);
 512    g_free(typename);
 513
 514    if (!object_class_dynamic_cast(oc, TYPE_CHARDEV)) {
 515        error_setg(errp, "'%s' is not a valid char driver name", driver);
 516        return NULL;
 517    }
 518
 519    if (object_class_is_abstract(oc)) {
 520        error_setg(errp, QERR_INVALID_PARAMETER_VALUE, "driver",
 521                   "an abstract device type");
 522        return NULL;
 523    }
 524
 525    cc = CHARDEV_CLASS(oc);
 526    if (cc->internal) {
 527        error_setg(errp, "'%s' is not a valid char driver name", driver);
 528        return NULL;
 529    }
 530
 531    return cc;
 532}
 533
 534typedef struct ChadevClassFE {
 535    void (*fn)(const char *name, void *opaque);
 536    void *opaque;
 537} ChadevClassFE;
 538
 539static void
 540chardev_class_foreach(ObjectClass *klass, void *opaque)
 541{
 542    ChadevClassFE *fe = opaque;
 543
 544    assert(g_str_has_prefix(object_class_get_name(klass), "chardev-"));
 545    if (CHARDEV_CLASS(klass)->internal) {
 546        return;
 547    }
 548
 549    fe->fn(object_class_get_name(klass) + 8, fe->opaque);
 550}
 551
 552static void
 553chardev_name_foreach(void (*fn)(const char *name, void *opaque),
 554                     void *opaque)
 555{
 556    ChadevClassFE fe = { .fn = fn, .opaque = opaque };
 557
 558    object_class_foreach(chardev_class_foreach, TYPE_CHARDEV, false, &fe);
 559}
 560
 561static void
 562help_string_append(const char *name, void *opaque)
 563{
 564    GString *str = opaque;
 565
 566    g_string_append_printf(str, "\n  %s", name);
 567}
 568
 569ChardevBackend *qemu_chr_parse_opts(QemuOpts *opts, Error **errp)
 570{
 571    Error *local_err = NULL;
 572    const ChardevClass *cc;
 573    ChardevBackend *backend = NULL;
 574    const char *name = qemu_opt_get(opts, "backend");
 575
 576    if (name == NULL) {
 577        error_setg(errp, "chardev: \"%s\" missing backend",
 578                   qemu_opts_id(opts));
 579        return NULL;
 580    }
 581
 582    cc = char_get_class(name, errp);
 583    if (cc == NULL) {
 584        return NULL;
 585    }
 586
 587    backend = g_new0(ChardevBackend, 1);
 588    backend->type = CHARDEV_BACKEND_KIND_NULL;
 589
 590    if (cc->parse) {
 591        cc->parse(opts, backend, &local_err);
 592        if (local_err) {
 593            error_propagate(errp, local_err);
 594            qapi_free_ChardevBackend(backend);
 595            return NULL;
 596        }
 597    } else {
 598        ChardevCommon *ccom = g_new0(ChardevCommon, 1);
 599        qemu_chr_parse_common(opts, ccom);
 600        backend->u.null.data = ccom; /* Any ChardevCommon member would work */
 601    }
 602
 603    return backend;
 604}
 605
 606Chardev *qemu_chr_new_from_opts(QemuOpts *opts, GMainContext *context,
 607                                Error **errp)
 608{
 609    const ChardevClass *cc;
 610    Chardev *chr = NULL;
 611    ChardevBackend *backend = NULL;
 612    const char *name = qemu_opt_get(opts, "backend");
 613    const char *id = qemu_opts_id(opts);
 614    char *bid = NULL;
 615
 616    if (name && is_help_option(name)) {
 617        GString *str = g_string_new("");
 618
 619        chardev_name_foreach(help_string_append, str);
 620
 621        qemu_printf("Available chardev backend types: %s\n", str->str);
 622        g_string_free(str, true);
 623        return NULL;
 624    }
 625
 626    if (id == NULL) {
 627        error_setg(errp, "chardev: no id specified");
 628        return NULL;
 629    }
 630
 631    backend = qemu_chr_parse_opts(opts, errp);
 632    if (backend == NULL) {
 633        return NULL;
 634    }
 635
 636    cc = char_get_class(name, errp);
 637    if (cc == NULL) {
 638        goto out;
 639    }
 640
 641    if (qemu_opt_get_bool(opts, "mux", 0)) {
 642        bid = g_strdup_printf("%s-base", id);
 643    }
 644
 645    chr = qemu_chardev_new(bid ? bid : id,
 646                           object_class_get_name(OBJECT_CLASS(cc)),
 647                           backend, context, errp);
 648
 649    if (chr == NULL) {
 650        goto out;
 651    }
 652
 653    if (bid) {
 654        Chardev *mux;
 655        qapi_free_ChardevBackend(backend);
 656        backend = g_new0(ChardevBackend, 1);
 657        backend->type = CHARDEV_BACKEND_KIND_MUX;
 658        backend->u.mux.data = g_new0(ChardevMux, 1);
 659        backend->u.mux.data->chardev = g_strdup(bid);
 660        mux = qemu_chardev_new(id, TYPE_CHARDEV_MUX, backend, context, errp);
 661        if (mux == NULL) {
 662            object_unparent(OBJECT(chr));
 663            chr = NULL;
 664            goto out;
 665        }
 666        chr = mux;
 667    }
 668
 669out:
 670    qapi_free_ChardevBackend(backend);
 671    g_free(bid);
 672    return chr;
 673}
 674
 675Chardev *qemu_chr_new_noreplay(const char *label, const char *filename,
 676                               bool permit_mux_mon, GMainContext *context)
 677{
 678    const char *p;
 679    Chardev *chr;
 680    QemuOpts *opts;
 681    Error *err = NULL;
 682
 683    if (strstart(filename, "chardev:", &p)) {
 684        return qemu_chr_find(p);
 685    }
 686
 687    opts = qemu_chr_parse_compat(label, filename, permit_mux_mon);
 688    if (!opts)
 689        return NULL;
 690
 691    chr = qemu_chr_new_from_opts(opts, context, &err);
 692    if (!chr) {
 693        error_report_err(err);
 694        goto out;
 695    }
 696
 697    if (qemu_opt_get_bool(opts, "mux", 0)) {
 698        assert(permit_mux_mon);
 699        monitor_init_hmp(chr, true, &err);
 700        if (err) {
 701            error_report_err(err);
 702            object_unparent(OBJECT(chr));
 703            chr = NULL;
 704            goto out;
 705        }
 706    }
 707
 708out:
 709    qemu_opts_del(opts);
 710    return chr;
 711}
 712
 713static Chardev *qemu_chr_new_permit_mux_mon(const char *label,
 714                                          const char *filename,
 715                                          bool permit_mux_mon,
 716                                          GMainContext *context)
 717{
 718    Chardev *chr;
 719    chr = qemu_chr_new_noreplay(label, filename, permit_mux_mon, context);
 720    if (chr) {
 721        if (replay_mode != REPLAY_MODE_NONE) {
 722            qemu_chr_set_feature(chr, QEMU_CHAR_FEATURE_REPLAY);
 723        }
 724        if (qemu_chr_replay(chr) && CHARDEV_GET_CLASS(chr)->chr_ioctl) {
 725            error_report("Replay: ioctl is not supported "
 726                         "for serial devices yet");
 727        }
 728        replay_register_char_driver(chr);
 729    }
 730    return chr;
 731}
 732
 733Chardev *qemu_chr_new(const char *label, const char *filename,
 734                      GMainContext *context)
 735{
 736    return qemu_chr_new_permit_mux_mon(label, filename, false, context);
 737}
 738
 739Chardev *qemu_chr_new_mux_mon(const char *label, const char *filename,
 740                              GMainContext *context)
 741{
 742    return qemu_chr_new_permit_mux_mon(label, filename, true, context);
 743}
 744
 745static int qmp_query_chardev_foreach(Object *obj, void *data)
 746{
 747    Chardev *chr = CHARDEV(obj);
 748    ChardevInfoList **list = data;
 749    ChardevInfo *value = g_malloc0(sizeof(*value));
 750
 751    value->label = g_strdup(chr->label);
 752    value->filename = g_strdup(chr->filename);
 753    value->frontend_open = chr->be && chr->be->fe_open;
 754
 755    QAPI_LIST_PREPEND(*list, value);
 756
 757    return 0;
 758}
 759
 760ChardevInfoList *qmp_query_chardev(Error **errp)
 761{
 762    ChardevInfoList *chr_list = NULL;
 763
 764    object_child_foreach(get_chardevs_root(),
 765                         qmp_query_chardev_foreach, &chr_list);
 766
 767    return chr_list;
 768}
 769
 770static void
 771qmp_prepend_backend(const char *name, void *opaque)
 772{
 773    ChardevBackendInfoList **list = opaque;
 774    ChardevBackendInfo *value;
 775
 776    value = g_new0(ChardevBackendInfo, 1);
 777    value->name = g_strdup(name);
 778    QAPI_LIST_PREPEND(*list, value);
 779}
 780
 781ChardevBackendInfoList *qmp_query_chardev_backends(Error **errp)
 782{
 783    ChardevBackendInfoList *backend_list = NULL;
 784
 785    chardev_name_foreach(qmp_prepend_backend, &backend_list);
 786
 787    return backend_list;
 788}
 789
 790Chardev *qemu_chr_find(const char *name)
 791{
 792    Object *obj = object_resolve_path_component(get_chardevs_root(), name);
 793
 794    return obj ? CHARDEV(obj) : NULL;
 795}
 796
 797QemuOptsList qemu_chardev_opts = {
 798    .name = "chardev",
 799    .implied_opt_name = "backend",
 800    .head = QTAILQ_HEAD_INITIALIZER(qemu_chardev_opts.head),
 801    .desc = {
 802        {
 803            .name = "backend",
 804            .type = QEMU_OPT_STRING,
 805        },{
 806            .name = "path",
 807            .type = QEMU_OPT_STRING,
 808        },{
 809            .name = "input-path",
 810            .type = QEMU_OPT_STRING,
 811        },{
 812            .name = "host",
 813            .type = QEMU_OPT_STRING,
 814        },{
 815            .name = "port",
 816            .type = QEMU_OPT_STRING,
 817        },{
 818            .name = "fd",
 819            .type = QEMU_OPT_STRING,
 820        },{
 821            .name = "localaddr",
 822            .type = QEMU_OPT_STRING,
 823        },{
 824            .name = "localport",
 825            .type = QEMU_OPT_STRING,
 826        },{
 827            .name = "to",
 828            .type = QEMU_OPT_NUMBER,
 829        },{
 830            .name = "ipv4",
 831            .type = QEMU_OPT_BOOL,
 832        },{
 833            .name = "ipv6",
 834            .type = QEMU_OPT_BOOL,
 835        },{
 836            .name = "wait",
 837            .type = QEMU_OPT_BOOL,
 838        },{
 839            .name = "server",
 840            .type = QEMU_OPT_BOOL,
 841        },{
 842            .name = "delay",
 843            .type = QEMU_OPT_BOOL,
 844        },{
 845            .name = "nodelay",
 846            .type = QEMU_OPT_BOOL,
 847        },{
 848            .name = "reconnect",
 849            .type = QEMU_OPT_NUMBER,
 850        },{
 851            .name = "telnet",
 852            .type = QEMU_OPT_BOOL,
 853        },{
 854            .name = "tn3270",
 855            .type = QEMU_OPT_BOOL,
 856        },{
 857            .name = "tls-creds",
 858            .type = QEMU_OPT_STRING,
 859        },{
 860            .name = "tls-authz",
 861            .type = QEMU_OPT_STRING,
 862        },{
 863            .name = "websocket",
 864            .type = QEMU_OPT_BOOL,
 865        },{
 866            .name = "width",
 867            .type = QEMU_OPT_NUMBER,
 868        },{
 869            .name = "height",
 870            .type = QEMU_OPT_NUMBER,
 871        },{
 872            .name = "cols",
 873            .type = QEMU_OPT_NUMBER,
 874        },{
 875            .name = "rows",
 876            .type = QEMU_OPT_NUMBER,
 877        },{
 878            .name = "mux",
 879            .type = QEMU_OPT_BOOL,
 880        },{
 881            .name = "signal",
 882            .type = QEMU_OPT_BOOL,
 883        },{
 884            .name = "name",
 885            .type = QEMU_OPT_STRING,
 886        },{
 887            .name = "debug",
 888            .type = QEMU_OPT_NUMBER,
 889        },{
 890            .name = "size",
 891            .type = QEMU_OPT_SIZE,
 892        },{
 893            .name = "chardev",
 894            .type = QEMU_OPT_STRING,
 895        },{
 896            .name = "append",
 897            .type = QEMU_OPT_BOOL,
 898        },{
 899            .name = "logfile",
 900            .type = QEMU_OPT_STRING,
 901        },{
 902            .name = "logappend",
 903            .type = QEMU_OPT_BOOL,
 904        },{
 905            .name = "mouse",
 906            .type = QEMU_OPT_BOOL,
 907        },{
 908            .name = "clipboard",
 909            .type = QEMU_OPT_BOOL,
 910#ifdef CONFIG_LINUX
 911        },{
 912            .name = "tight",
 913            .type = QEMU_OPT_BOOL,
 914            .def_value_str = "on",
 915        },{
 916            .name = "abstract",
 917            .type = QEMU_OPT_BOOL,
 918#endif
 919        },
 920        { /* end of list */ }
 921    },
 922};
 923
 924bool qemu_chr_has_feature(Chardev *chr,
 925                          ChardevFeature feature)
 926{
 927    return test_bit(feature, chr->features);
 928}
 929
 930void qemu_chr_set_feature(Chardev *chr,
 931                           ChardevFeature feature)
 932{
 933    return set_bit(feature, chr->features);
 934}
 935
 936static Chardev *chardev_new(const char *id, const char *typename,
 937                            ChardevBackend *backend,
 938                            GMainContext *gcontext,
 939                            bool handover_yank_instance,
 940                            Error **errp)
 941{
 942    Object *obj;
 943    Chardev *chr = NULL;
 944    Error *local_err = NULL;
 945    bool be_opened = true;
 946
 947    assert(g_str_has_prefix(typename, "chardev-"));
 948    assert(id);
 949
 950    obj = object_new(typename);
 951    chr = CHARDEV(obj);
 952    chr->handover_yank_instance = handover_yank_instance;
 953    chr->label = g_strdup(id);
 954    chr->gcontext = gcontext;
 955
 956    qemu_char_open(chr, backend, &be_opened, &local_err);
 957    if (local_err) {
 958        error_propagate(errp, local_err);
 959        object_unref(obj);
 960        return NULL;
 961    }
 962
 963    if (!chr->filename) {
 964        chr->filename = g_strdup(typename + 8);
 965    }
 966    if (be_opened) {
 967        qemu_chr_be_event(chr, CHR_EVENT_OPENED);
 968    }
 969
 970    return chr;
 971}
 972
 973Chardev *qemu_chardev_new(const char *id, const char *typename,
 974                          ChardevBackend *backend,
 975                          GMainContext *gcontext,
 976                          Error **errp)
 977{
 978    Chardev *chr;
 979    g_autofree char *genid = NULL;
 980
 981    if (!id) {
 982        genid = id_generate(ID_CHR);
 983        id = genid;
 984    }
 985
 986    chr = chardev_new(id, typename, backend, gcontext, false, errp);
 987    if (!chr) {
 988        return NULL;
 989    }
 990
 991    if (!object_property_try_add_child(get_chardevs_root(), id, OBJECT(chr),
 992                                       errp)) {
 993        object_unref(OBJECT(chr));
 994        return NULL;
 995    }
 996    object_unref(OBJECT(chr));
 997
 998    return chr;
 999}
1000
1001ChardevReturn *qmp_chardev_add(const char *id, ChardevBackend *backend,
1002                               Error **errp)
1003{
1004    ERRP_GUARD();
1005    const ChardevClass *cc;
1006    ChardevReturn *ret;
1007    g_autoptr(Chardev) chr = NULL;
1008
1009    if (qemu_chr_find(id)) {
1010        error_setg(errp, "Chardev with id '%s' already exists", id);
1011        return NULL;
1012    }
1013
1014    cc = char_get_class(ChardevBackendKind_str(backend->type), errp);
1015    if (!cc) {
1016        goto err;
1017    }
1018
1019    chr = chardev_new(id, object_class_get_name(OBJECT_CLASS(cc)),
1020                      backend, NULL, false, errp);
1021    if (!chr) {
1022        goto err;
1023    }
1024
1025    if (!object_property_try_add_child(get_chardevs_root(), id, OBJECT(chr),
1026                                       errp)) {
1027        goto err;
1028    }
1029
1030    ret = g_new0(ChardevReturn, 1);
1031    if (CHARDEV_IS_PTY(chr)) {
1032        ret->pty = g_strdup(chr->filename + 4);
1033    }
1034
1035    return ret;
1036
1037err:
1038    error_prepend(errp, "Failed to add chardev '%s': ", id);
1039    return NULL;
1040}
1041
1042ChardevReturn *qmp_chardev_change(const char *id, ChardevBackend *backend,
1043                                  Error **errp)
1044{
1045    CharBackend *be;
1046    const ChardevClass *cc, *cc_new;
1047    Chardev *chr, *chr_new;
1048    bool closed_sent = false;
1049    bool handover_yank_instance;
1050    ChardevReturn *ret;
1051
1052    chr = qemu_chr_find(id);
1053    if (!chr) {
1054        error_setg(errp, "Chardev '%s' does not exist", id);
1055        return NULL;
1056    }
1057
1058    if (CHARDEV_IS_MUX(chr)) {
1059        error_setg(errp, "Mux device hotswap not supported yet");
1060        return NULL;
1061    }
1062
1063    if (qemu_chr_replay(chr)) {
1064        error_setg(errp,
1065            "Chardev '%s' cannot be changed in record/replay mode", id);
1066        return NULL;
1067    }
1068
1069    be = chr->be;
1070    if (!be) {
1071        /* easy case */
1072        object_unparent(OBJECT(chr));
1073        return qmp_chardev_add(id, backend, errp);
1074    }
1075
1076    if (!be->chr_be_change) {
1077        error_setg(errp, "Chardev user does not support chardev hotswap");
1078        return NULL;
1079    }
1080
1081    cc = CHARDEV_GET_CLASS(chr);
1082    cc_new = char_get_class(ChardevBackendKind_str(backend->type), errp);
1083    if (!cc_new) {
1084        return NULL;
1085    }
1086
1087    /*
1088     * The new chardev should not register a yank instance if the current
1089     * chardev has registered one already.
1090     */
1091    handover_yank_instance = cc->supports_yank && cc_new->supports_yank;
1092
1093    chr_new = chardev_new(id, object_class_get_name(OBJECT_CLASS(cc_new)),
1094                          backend, chr->gcontext, handover_yank_instance, errp);
1095    if (!chr_new) {
1096        return NULL;
1097    }
1098
1099    if (chr->be_open && !chr_new->be_open) {
1100        qemu_chr_be_event(chr, CHR_EVENT_CLOSED);
1101        closed_sent = true;
1102    }
1103
1104    chr->be = NULL;
1105    qemu_chr_fe_init(be, chr_new, &error_abort);
1106
1107    if (be->chr_be_change(be->opaque) < 0) {
1108        error_setg(errp, "Chardev '%s' change failed", chr_new->label);
1109        chr_new->be = NULL;
1110        qemu_chr_fe_init(be, chr, &error_abort);
1111        if (closed_sent) {
1112            qemu_chr_be_event(chr, CHR_EVENT_OPENED);
1113        }
1114        object_unref(OBJECT(chr_new));
1115        return NULL;
1116    }
1117
1118    /* change successfull, clean up */
1119    chr_new->handover_yank_instance = false;
1120
1121    /*
1122     * When the old chardev is freed, it should not unregister the yank
1123     * instance if the new chardev needs it.
1124     */
1125    chr->handover_yank_instance = handover_yank_instance;
1126
1127    object_unparent(OBJECT(chr));
1128    object_property_add_child(get_chardevs_root(), chr_new->label,
1129                              OBJECT(chr_new));
1130    object_unref(OBJECT(chr_new));
1131
1132    ret = g_new0(ChardevReturn, 1);
1133    if (CHARDEV_IS_PTY(chr_new)) {
1134        ret->pty = g_strdup(chr_new->filename + 4);
1135    }
1136
1137    return ret;
1138}
1139
1140void qmp_chardev_remove(const char *id, Error **errp)
1141{
1142    Chardev *chr;
1143
1144    chr = qemu_chr_find(id);
1145    if (chr == NULL) {
1146        error_setg(errp, "Chardev '%s' not found", id);
1147        return;
1148    }
1149    if (qemu_chr_is_busy(chr)) {
1150        error_setg(errp, "Chardev '%s' is busy", id);
1151        return;
1152    }
1153    if (qemu_chr_replay(chr)) {
1154        error_setg(errp,
1155            "Chardev '%s' cannot be unplugged in record/replay mode", id);
1156        return;
1157    }
1158    object_unparent(OBJECT(chr));
1159}
1160
1161void qmp_chardev_send_break(const char *id, Error **errp)
1162{
1163    Chardev *chr;
1164
1165    chr = qemu_chr_find(id);
1166    if (chr == NULL) {
1167        error_setg(errp, "Chardev '%s' not found", id);
1168        return;
1169    }
1170    qemu_chr_be_event(chr, CHR_EVENT_BREAK);
1171}
1172
1173bool qmp_add_client_char(int fd, bool has_skipauth, bool skipauth,
1174                         bool has_tls, bool tls, const char *protocol,
1175                         Error **errp)
1176{
1177    Chardev *s = qemu_chr_find(protocol);
1178
1179    if (!s) {
1180        error_setg(errp, "protocol '%s' is invalid", protocol);
1181        return false;
1182    }
1183    if (qemu_chr_add_client(s, fd) < 0) {
1184        error_setg(errp, "failed to add client");
1185        return false;
1186    }
1187    return true;
1188}
1189
1190/*
1191 * Add a timeout callback for the chardev (in milliseconds), return
1192 * the GSource object created. Please use this to add timeout hook for
1193 * chardev instead of g_timeout_add() and g_timeout_add_seconds(), to
1194 * make sure the gcontext that the task bound to is correct.
1195 */
1196GSource *qemu_chr_timeout_add_ms(Chardev *chr, guint ms,
1197                                 GSourceFunc func, void *private)
1198{
1199    GSource *source = g_timeout_source_new(ms);
1200
1201    assert(func);
1202    g_source_set_callback(source, func, private, NULL);
1203    g_source_attach(source, chr->gcontext);
1204
1205    return source;
1206}
1207
1208void qemu_chr_cleanup(void)
1209{
1210    object_unparent(get_chardevs_root());
1211}
1212
1213static void register_types(void)
1214{
1215    type_register_static(&char_type_info);
1216}
1217
1218type_init(register_types);
1219