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 "sysemu/sysemu.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, 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, 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->has_logfile) {
 245        int flags = O_WRONLY | O_CREAT;
 246        if (common->has_logappend &&
 247            common->logappend) {
 248            flags |= O_APPEND;
 249        } else {
 250            flags |= O_TRUNC;
 251        }
 252        chr->logfd = qemu_open_old(common->logfile, flags, 0666);
 253        if (chr->logfd < 0) {
 254            error_setg_errno(errp, errno,
 255                             "Unable to open logfile %s",
 256                             common->logfile);
 257            return;
 258        }
 259    }
 260
 261    if (cc->open) {
 262        cc->open(chr, backend, be_opened, errp);
 263    }
 264}
 265
 266static void char_init(Object *obj)
 267{
 268    Chardev *chr = CHARDEV(obj);
 269
 270    chr->handover_yank_instance = false;
 271    chr->logfd = -1;
 272    qemu_mutex_init(&chr->chr_write_lock);
 273
 274    /*
 275     * Assume if chr_update_read_handler is implemented it will
 276     * take the updated gcontext into account.
 277     */
 278    if (CHARDEV_GET_CLASS(chr)->chr_update_read_handler) {
 279        qemu_chr_set_feature(chr, QEMU_CHAR_FEATURE_GCONTEXT);
 280    }
 281
 282}
 283
 284static int null_chr_write(Chardev *chr, const uint8_t *buf, int len)
 285{
 286    return len;
 287}
 288
 289static void char_class_init(ObjectClass *oc, void *data)
 290{
 291    ChardevClass *cc = CHARDEV_CLASS(oc);
 292
 293    cc->chr_write = null_chr_write;
 294    cc->chr_be_event = chr_be_event;
 295}
 296
 297static void char_finalize(Object *obj)
 298{
 299    Chardev *chr = CHARDEV(obj);
 300
 301    if (chr->be) {
 302        chr->be->chr = NULL;
 303    }
 304    g_free(chr->filename);
 305    g_free(chr->label);
 306    if (chr->logfd != -1) {
 307        close(chr->logfd);
 308    }
 309    qemu_mutex_destroy(&chr->chr_write_lock);
 310}
 311
 312static const TypeInfo char_type_info = {
 313    .name = TYPE_CHARDEV,
 314    .parent = TYPE_OBJECT,
 315    .instance_size = sizeof(Chardev),
 316    .instance_init = char_init,
 317    .instance_finalize = char_finalize,
 318    .abstract = true,
 319    .class_size = sizeof(ChardevClass),
 320    .class_init = char_class_init,
 321};
 322
 323static bool qemu_chr_is_busy(Chardev *s)
 324{
 325    if (CHARDEV_IS_MUX(s)) {
 326        MuxChardev *d = MUX_CHARDEV(s);
 327        return d->mux_cnt >= 0;
 328    } else {
 329        return s->be != NULL;
 330    }
 331}
 332
 333int qemu_chr_wait_connected(Chardev *chr, Error **errp)
 334{
 335    ChardevClass *cc = CHARDEV_GET_CLASS(chr);
 336
 337    if (cc->chr_wait_connected) {
 338        return cc->chr_wait_connected(chr, errp);
 339    }
 340
 341    return 0;
 342}
 343
 344QemuOpts *qemu_chr_parse_compat(const char *label, const char *filename,
 345                                bool permit_mux_mon)
 346{
 347    char host[65], port[33], width[8], height[8];
 348    int pos;
 349    const char *p;
 350    QemuOpts *opts;
 351    Error *local_err = NULL;
 352
 353    opts = qemu_opts_create(qemu_find_opts("chardev"), label, 1, &local_err);
 354    if (local_err) {
 355        error_report_err(local_err);
 356        return NULL;
 357    }
 358
 359    if (strstart(filename, "mon:", &p)) {
 360        if (!permit_mux_mon) {
 361            error_report("mon: isn't supported in this context");
 362            return NULL;
 363        }
 364        filename = p;
 365        qemu_opt_set(opts, "mux", "on", &error_abort);
 366        if (strcmp(filename, "stdio") == 0) {
 367            /* Monitor is muxed to stdio: do not exit on Ctrl+C by default
 368             * but pass it to the guest.  Handle this only for compat syntax,
 369             * for -chardev syntax we have special option for this.
 370             * This is what -nographic did, redirecting+muxing serial+monitor
 371             * to stdio causing Ctrl+C to be passed to guest. */
 372            qemu_opt_set(opts, "signal", "off", &error_abort);
 373        }
 374    }
 375
 376    if (strcmp(filename, "null")    == 0 ||
 377        strcmp(filename, "pty")     == 0 ||
 378        strcmp(filename, "msmouse") == 0 ||
 379        strcmp(filename, "wctablet") == 0 ||
 380        strcmp(filename, "braille") == 0 ||
 381        strcmp(filename, "testdev") == 0 ||
 382        strcmp(filename, "stdio")   == 0) {
 383        qemu_opt_set(opts, "backend", filename, &error_abort);
 384        return opts;
 385    }
 386    if (strstart(filename, "vc", &p)) {
 387        qemu_opt_set(opts, "backend", "vc", &error_abort);
 388        if (*p == ':') {
 389            if (sscanf(p+1, "%7[0-9]x%7[0-9]", width, height) == 2) {
 390                /* pixels */
 391                qemu_opt_set(opts, "width", width, &error_abort);
 392                qemu_opt_set(opts, "height", height, &error_abort);
 393            } else if (sscanf(p+1, "%7[0-9]Cx%7[0-9]C", width, height) == 2) {
 394                /* chars */
 395                qemu_opt_set(opts, "cols", width, &error_abort);
 396                qemu_opt_set(opts, "rows", height, &error_abort);
 397            } else {
 398                goto fail;
 399            }
 400        }
 401        return opts;
 402    }
 403    if (strcmp(filename, "con:") == 0) {
 404        qemu_opt_set(opts, "backend", "console", &error_abort);
 405        return opts;
 406    }
 407    if (strstart(filename, "COM", NULL)) {
 408        qemu_opt_set(opts, "backend", "serial", &error_abort);
 409        qemu_opt_set(opts, "path", filename, &error_abort);
 410        return opts;
 411    }
 412    if (strstart(filename, "file:", &p)) {
 413        qemu_opt_set(opts, "backend", "file", &error_abort);
 414        qemu_opt_set(opts, "path", p, &error_abort);
 415        return opts;
 416    }
 417    if (strstart(filename, "pipe:", &p)) {
 418        qemu_opt_set(opts, "backend", "pipe", &error_abort);
 419        qemu_opt_set(opts, "path", p, &error_abort);
 420        return opts;
 421    }
 422    if (strstart(filename, "tcp:", &p) ||
 423        strstart(filename, "telnet:", &p) ||
 424        strstart(filename, "tn3270:", &p) ||
 425        strstart(filename, "websocket:", &p)) {
 426        if (sscanf(p, "%64[^:]:%32[^,]%n", host, port, &pos) < 2) {
 427            host[0] = 0;
 428            if (sscanf(p, ":%32[^,]%n", port, &pos) < 1)
 429                goto fail;
 430        }
 431        qemu_opt_set(opts, "backend", "socket", &error_abort);
 432        qemu_opt_set(opts, "host", host, &error_abort);
 433        qemu_opt_set(opts, "port", port, &error_abort);
 434        if (p[pos] == ',') {
 435            if (!qemu_opts_do_parse(opts, p + pos + 1, NULL, &local_err)) {
 436                error_report_err(local_err);
 437                goto fail;
 438            }
 439        }
 440        if (strstart(filename, "telnet:", &p)) {
 441            qemu_opt_set(opts, "telnet", "on", &error_abort);
 442        } else if (strstart(filename, "tn3270:", &p)) {
 443            qemu_opt_set(opts, "tn3270", "on", &error_abort);
 444        } else if (strstart(filename, "websocket:", &p)) {
 445            qemu_opt_set(opts, "websocket", "on", &error_abort);
 446        }
 447        return opts;
 448    }
 449    if (strstart(filename, "udp:", &p)) {
 450        qemu_opt_set(opts, "backend", "udp", &error_abort);
 451        if (sscanf(p, "%64[^:]:%32[^@,]%n", host, port, &pos) < 2) {
 452            host[0] = 0;
 453            if (sscanf(p, ":%32[^@,]%n", port, &pos) < 1) {
 454                goto fail;
 455            }
 456        }
 457        qemu_opt_set(opts, "host", host, &error_abort);
 458        qemu_opt_set(opts, "port", port, &error_abort);
 459        if (p[pos] == '@') {
 460            p += pos + 1;
 461            if (sscanf(p, "%64[^:]:%32[^,]%n", host, port, &pos) < 2) {
 462                host[0] = 0;
 463                if (sscanf(p, ":%32[^,]%n", port, &pos) < 1) {
 464                    goto fail;
 465                }
 466            }
 467            qemu_opt_set(opts, "localaddr", host, &error_abort);
 468            qemu_opt_set(opts, "localport", port, &error_abort);
 469        }
 470        return opts;
 471    }
 472    if (strstart(filename, "unix:", &p)) {
 473        qemu_opt_set(opts, "backend", "socket", &error_abort);
 474        if (!qemu_opts_do_parse(opts, p, "path", &local_err)) {
 475            error_report_err(local_err);
 476            goto fail;
 477        }
 478        return opts;
 479    }
 480    if (strstart(filename, "/dev/parport", NULL) ||
 481        strstart(filename, "/dev/ppi", NULL)) {
 482        qemu_opt_set(opts, "backend", "parallel", &error_abort);
 483        qemu_opt_set(opts, "path", filename, &error_abort);
 484        return opts;
 485    }
 486    if (strstart(filename, "/dev/", NULL)) {
 487        qemu_opt_set(opts, "backend", "serial", &error_abort);
 488        qemu_opt_set(opts, "path", filename, &error_abort);
 489        return opts;
 490    }
 491
 492    error_report("'%s' is not a valid char driver", filename);
 493
 494fail:
 495    qemu_opts_del(opts);
 496    return NULL;
 497}
 498
 499void qemu_chr_parse_common(QemuOpts *opts, ChardevCommon *backend)
 500{
 501    const char *logfile = qemu_opt_get(opts, "logfile");
 502
 503    backend->has_logfile = logfile != NULL;
 504    backend->logfile = g_strdup(logfile);
 505
 506    backend->has_logappend = true;
 507    backend->logappend = qemu_opt_get_bool(opts, "logappend", false);
 508}
 509
 510static const ChardevClass *char_get_class(const char *driver, Error **errp)
 511{
 512    ObjectClass *oc;
 513    const ChardevClass *cc;
 514    char *typename = g_strdup_printf("chardev-%s", driver);
 515
 516    oc = module_object_class_by_name(typename);
 517    g_free(typename);
 518
 519    if (!object_class_dynamic_cast(oc, TYPE_CHARDEV)) {
 520        error_setg(errp, "'%s' is not a valid char driver name", driver);
 521        return NULL;
 522    }
 523
 524    if (object_class_is_abstract(oc)) {
 525        error_setg(errp, QERR_INVALID_PARAMETER_VALUE, "driver",
 526                   "an abstract device type");
 527        return NULL;
 528    }
 529
 530    cc = CHARDEV_CLASS(oc);
 531    if (cc->internal) {
 532        error_setg(errp, "'%s' is not a valid char driver name", driver);
 533        return NULL;
 534    }
 535
 536    return cc;
 537}
 538
 539static struct ChardevAlias {
 540    const char *typename;
 541    const char *alias;
 542    bool deprecation_warning_printed;
 543} chardev_alias_table[] = {
 544#ifdef HAVE_CHARDEV_PARPORT
 545    { "parallel", "parport" },
 546#endif
 547#ifdef HAVE_CHARDEV_SERIAL
 548    { "serial", "tty" },
 549#endif
 550};
 551
 552typedef struct ChadevClassFE {
 553    void (*fn)(const char *name, void *opaque);
 554    void *opaque;
 555} ChadevClassFE;
 556
 557static void
 558chardev_class_foreach(ObjectClass *klass, void *opaque)
 559{
 560    ChadevClassFE *fe = opaque;
 561
 562    assert(g_str_has_prefix(object_class_get_name(klass), "chardev-"));
 563    if (CHARDEV_CLASS(klass)->internal) {
 564        return;
 565    }
 566
 567    fe->fn(object_class_get_name(klass) + 8, fe->opaque);
 568}
 569
 570static void
 571chardev_name_foreach(void (*fn)(const char *name, void *opaque),
 572                     void *opaque)
 573{
 574    ChadevClassFE fe = { .fn = fn, .opaque = opaque };
 575
 576    object_class_foreach(chardev_class_foreach, TYPE_CHARDEV, false, &fe);
 577}
 578
 579static void
 580help_string_append(const char *name, void *opaque)
 581{
 582    GString *str = opaque;
 583
 584    g_string_append_printf(str, "\n  %s", name);
 585}
 586
 587static const char *chardev_alias_translate(const char *name)
 588{
 589    int i;
 590    for (i = 0; i < (int)ARRAY_SIZE(chardev_alias_table); i++) {
 591        if (g_strcmp0(chardev_alias_table[i].alias, name) == 0) {
 592            if (!chardev_alias_table[i].deprecation_warning_printed) {
 593                warn_report("The alias '%s' is deprecated, use '%s' instead",
 594                            name, chardev_alias_table[i].typename);
 595                chardev_alias_table[i].deprecation_warning_printed = true;
 596            }
 597            return chardev_alias_table[i].typename;
 598        }
 599    }
 600    return name;
 601}
 602
 603ChardevBackend *qemu_chr_parse_opts(QemuOpts *opts, Error **errp)
 604{
 605    Error *local_err = NULL;
 606    const ChardevClass *cc;
 607    ChardevBackend *backend = NULL;
 608    const char *name = chardev_alias_translate(qemu_opt_get(opts, "backend"));
 609
 610    if (name == NULL) {
 611        error_setg(errp, "chardev: \"%s\" missing backend",
 612                   qemu_opts_id(opts));
 613        return NULL;
 614    }
 615
 616    cc = char_get_class(name, errp);
 617    if (cc == NULL) {
 618        return NULL;
 619    }
 620
 621    backend = g_new0(ChardevBackend, 1);
 622    backend->type = CHARDEV_BACKEND_KIND_NULL;
 623
 624    if (cc->parse) {
 625        cc->parse(opts, backend, &local_err);
 626        if (local_err) {
 627            error_propagate(errp, local_err);
 628            qapi_free_ChardevBackend(backend);
 629            return NULL;
 630        }
 631    } else {
 632        ChardevCommon *ccom = g_new0(ChardevCommon, 1);
 633        qemu_chr_parse_common(opts, ccom);
 634        backend->u.null.data = ccom; /* Any ChardevCommon member would work */
 635    }
 636
 637    return backend;
 638}
 639
 640Chardev *qemu_chr_new_from_opts(QemuOpts *opts, GMainContext *context,
 641                                Error **errp)
 642{
 643    const ChardevClass *cc;
 644    Chardev *chr = NULL;
 645    ChardevBackend *backend = NULL;
 646    const char *name = chardev_alias_translate(qemu_opt_get(opts, "backend"));
 647    const char *id = qemu_opts_id(opts);
 648    char *bid = NULL;
 649
 650    if (name && is_help_option(name)) {
 651        GString *str = g_string_new("");
 652
 653        chardev_name_foreach(help_string_append, str);
 654
 655        qemu_printf("Available chardev backend types: %s\n", str->str);
 656        g_string_free(str, true);
 657        return NULL;
 658    }
 659
 660    if (id == NULL) {
 661        error_setg(errp, "chardev: no id specified");
 662        return NULL;
 663    }
 664
 665    backend = qemu_chr_parse_opts(opts, errp);
 666    if (backend == NULL) {
 667        return NULL;
 668    }
 669
 670    cc = char_get_class(name, errp);
 671    if (cc == NULL) {
 672        goto out;
 673    }
 674
 675    if (qemu_opt_get_bool(opts, "mux", 0)) {
 676        bid = g_strdup_printf("%s-base", id);
 677    }
 678
 679    chr = qemu_chardev_new(bid ? bid : id,
 680                           object_class_get_name(OBJECT_CLASS(cc)),
 681                           backend, context, errp);
 682
 683    if (chr == NULL) {
 684        goto out;
 685    }
 686
 687    if (bid) {
 688        Chardev *mux;
 689        qapi_free_ChardevBackend(backend);
 690        backend = g_new0(ChardevBackend, 1);
 691        backend->type = CHARDEV_BACKEND_KIND_MUX;
 692        backend->u.mux.data = g_new0(ChardevMux, 1);
 693        backend->u.mux.data->chardev = g_strdup(bid);
 694        mux = qemu_chardev_new(id, TYPE_CHARDEV_MUX, backend, context, errp);
 695        if (mux == NULL) {
 696            object_unparent(OBJECT(chr));
 697            chr = NULL;
 698            goto out;
 699        }
 700        chr = mux;
 701    }
 702
 703out:
 704    qapi_free_ChardevBackend(backend);
 705    g_free(bid);
 706    return chr;
 707}
 708
 709Chardev *qemu_chr_new_noreplay(const char *label, const char *filename,
 710                               bool permit_mux_mon, GMainContext *context)
 711{
 712    const char *p;
 713    Chardev *chr;
 714    QemuOpts *opts;
 715    Error *err = NULL;
 716
 717    if (strstart(filename, "chardev:", &p)) {
 718        return qemu_chr_find(p);
 719    }
 720
 721    opts = qemu_chr_parse_compat(label, filename, permit_mux_mon);
 722    if (!opts)
 723        return NULL;
 724
 725    chr = qemu_chr_new_from_opts(opts, context, &err);
 726    if (!chr) {
 727        error_report_err(err);
 728        goto out;
 729    }
 730
 731    if (qemu_opt_get_bool(opts, "mux", 0)) {
 732        assert(permit_mux_mon);
 733        monitor_init_hmp(chr, true, &err);
 734        if (err) {
 735            error_report_err(err);
 736            object_unparent(OBJECT(chr));
 737            chr = NULL;
 738            goto out;
 739        }
 740    }
 741
 742out:
 743    qemu_opts_del(opts);
 744    return chr;
 745}
 746
 747static Chardev *qemu_chr_new_permit_mux_mon(const char *label,
 748                                          const char *filename,
 749                                          bool permit_mux_mon,
 750                                          GMainContext *context)
 751{
 752    Chardev *chr;
 753    chr = qemu_chr_new_noreplay(label, filename, permit_mux_mon, context);
 754    if (chr) {
 755        if (replay_mode != REPLAY_MODE_NONE) {
 756            qemu_chr_set_feature(chr, QEMU_CHAR_FEATURE_REPLAY);
 757        }
 758        if (qemu_chr_replay(chr) && CHARDEV_GET_CLASS(chr)->chr_ioctl) {
 759            error_report("Replay: ioctl is not supported "
 760                         "for serial devices yet");
 761        }
 762        replay_register_char_driver(chr);
 763    }
 764    return chr;
 765}
 766
 767Chardev *qemu_chr_new(const char *label, const char *filename,
 768                      GMainContext *context)
 769{
 770    return qemu_chr_new_permit_mux_mon(label, filename, false, context);
 771}
 772
 773Chardev *qemu_chr_new_mux_mon(const char *label, const char *filename,
 774                              GMainContext *context)
 775{
 776    return qemu_chr_new_permit_mux_mon(label, filename, true, context);
 777}
 778
 779static int qmp_query_chardev_foreach(Object *obj, void *data)
 780{
 781    Chardev *chr = CHARDEV(obj);
 782    ChardevInfoList **list = data;
 783    ChardevInfo *value = g_malloc0(sizeof(*value));
 784
 785    value->label = g_strdup(chr->label);
 786    value->filename = g_strdup(chr->filename);
 787    value->frontend_open = chr->be && chr->be->fe_open;
 788
 789    QAPI_LIST_PREPEND(*list, value);
 790
 791    return 0;
 792}
 793
 794ChardevInfoList *qmp_query_chardev(Error **errp)
 795{
 796    ChardevInfoList *chr_list = NULL;
 797
 798    object_child_foreach(get_chardevs_root(),
 799                         qmp_query_chardev_foreach, &chr_list);
 800
 801    return chr_list;
 802}
 803
 804static void
 805qmp_prepend_backend(const char *name, void *opaque)
 806{
 807    ChardevBackendInfoList **list = opaque;
 808    ChardevBackendInfo *value;
 809
 810    value = g_new0(ChardevBackendInfo, 1);
 811    value->name = g_strdup(name);
 812    QAPI_LIST_PREPEND(*list, value);
 813}
 814
 815ChardevBackendInfoList *qmp_query_chardev_backends(Error **errp)
 816{
 817    ChardevBackendInfoList *backend_list = NULL;
 818
 819    chardev_name_foreach(qmp_prepend_backend, &backend_list);
 820
 821    return backend_list;
 822}
 823
 824Chardev *qemu_chr_find(const char *name)
 825{
 826    Object *obj = object_resolve_path_component(get_chardevs_root(), name);
 827
 828    return obj ? CHARDEV(obj) : NULL;
 829}
 830
 831QemuOptsList qemu_chardev_opts = {
 832    .name = "chardev",
 833    .implied_opt_name = "backend",
 834    .head = QTAILQ_HEAD_INITIALIZER(qemu_chardev_opts.head),
 835    .desc = {
 836        {
 837            .name = "backend",
 838            .type = QEMU_OPT_STRING,
 839        },{
 840            .name = "path",
 841            .type = QEMU_OPT_STRING,
 842        },{
 843            .name = "host",
 844            .type = QEMU_OPT_STRING,
 845        },{
 846            .name = "port",
 847            .type = QEMU_OPT_STRING,
 848        },{
 849            .name = "fd",
 850            .type = QEMU_OPT_STRING,
 851        },{
 852            .name = "localaddr",
 853            .type = QEMU_OPT_STRING,
 854        },{
 855            .name = "localport",
 856            .type = QEMU_OPT_STRING,
 857        },{
 858            .name = "to",
 859            .type = QEMU_OPT_NUMBER,
 860        },{
 861            .name = "ipv4",
 862            .type = QEMU_OPT_BOOL,
 863        },{
 864            .name = "ipv6",
 865            .type = QEMU_OPT_BOOL,
 866        },{
 867            .name = "wait",
 868            .type = QEMU_OPT_BOOL,
 869        },{
 870            .name = "server",
 871            .type = QEMU_OPT_BOOL,
 872        },{
 873            .name = "delay",
 874            .type = QEMU_OPT_BOOL,
 875        },{
 876            .name = "nodelay",
 877            .type = QEMU_OPT_BOOL,
 878        },{
 879            .name = "reconnect",
 880            .type = QEMU_OPT_NUMBER,
 881        },{
 882            .name = "telnet",
 883            .type = QEMU_OPT_BOOL,
 884        },{
 885            .name = "tn3270",
 886            .type = QEMU_OPT_BOOL,
 887        },{
 888            .name = "tls-creds",
 889            .type = QEMU_OPT_STRING,
 890        },{
 891            .name = "tls-authz",
 892            .type = QEMU_OPT_STRING,
 893        },{
 894            .name = "websocket",
 895            .type = QEMU_OPT_BOOL,
 896        },{
 897            .name = "width",
 898            .type = QEMU_OPT_NUMBER,
 899        },{
 900            .name = "height",
 901            .type = QEMU_OPT_NUMBER,
 902        },{
 903            .name = "cols",
 904            .type = QEMU_OPT_NUMBER,
 905        },{
 906            .name = "rows",
 907            .type = QEMU_OPT_NUMBER,
 908        },{
 909            .name = "mux",
 910            .type = QEMU_OPT_BOOL,
 911        },{
 912            .name = "signal",
 913            .type = QEMU_OPT_BOOL,
 914        },{
 915            .name = "name",
 916            .type = QEMU_OPT_STRING,
 917        },{
 918            .name = "debug",
 919            .type = QEMU_OPT_NUMBER,
 920        },{
 921            .name = "size",
 922            .type = QEMU_OPT_SIZE,
 923        },{
 924            .name = "chardev",
 925            .type = QEMU_OPT_STRING,
 926        },{
 927            .name = "append",
 928            .type = QEMU_OPT_BOOL,
 929        },{
 930            .name = "logfile",
 931            .type = QEMU_OPT_STRING,
 932        },{
 933            .name = "logappend",
 934            .type = QEMU_OPT_BOOL,
 935#ifdef CONFIG_LINUX
 936        },{
 937            .name = "tight",
 938            .type = QEMU_OPT_BOOL,
 939            .def_value_str = "on",
 940        },{
 941            .name = "abstract",
 942            .type = QEMU_OPT_BOOL,
 943#endif
 944        },
 945        { /* end of list */ }
 946    },
 947};
 948
 949bool qemu_chr_has_feature(Chardev *chr,
 950                          ChardevFeature feature)
 951{
 952    return test_bit(feature, chr->features);
 953}
 954
 955void qemu_chr_set_feature(Chardev *chr,
 956                           ChardevFeature feature)
 957{
 958    return set_bit(feature, chr->features);
 959}
 960
 961static Chardev *chardev_new(const char *id, const char *typename,
 962                            ChardevBackend *backend,
 963                            GMainContext *gcontext,
 964                            bool handover_yank_instance,
 965                            Error **errp)
 966{
 967    Object *obj;
 968    Chardev *chr = NULL;
 969    Error *local_err = NULL;
 970    bool be_opened = true;
 971
 972    assert(g_str_has_prefix(typename, "chardev-"));
 973    assert(id);
 974
 975    obj = object_new(typename);
 976    chr = CHARDEV(obj);
 977    chr->handover_yank_instance = handover_yank_instance;
 978    chr->label = g_strdup(id);
 979    chr->gcontext = gcontext;
 980
 981    qemu_char_open(chr, backend, &be_opened, &local_err);
 982    if (local_err) {
 983        error_propagate(errp, local_err);
 984        object_unref(obj);
 985        return NULL;
 986    }
 987
 988    if (!chr->filename) {
 989        chr->filename = g_strdup(typename + 8);
 990    }
 991    if (be_opened) {
 992        qemu_chr_be_event(chr, CHR_EVENT_OPENED);
 993    }
 994
 995    return chr;
 996}
 997
 998Chardev *qemu_chardev_new(const char *id, const char *typename,
 999                          ChardevBackend *backend,
1000                          GMainContext *gcontext,
1001                          Error **errp)
1002{
1003    Chardev *chr;
1004    g_autofree char *genid = NULL;
1005
1006    if (!id) {
1007        genid = id_generate(ID_CHR);
1008        id = genid;
1009    }
1010
1011    chr = chardev_new(id, typename, backend, gcontext, false, errp);
1012    if (!chr) {
1013        return NULL;
1014    }
1015
1016    if (!object_property_try_add_child(get_chardevs_root(), id, OBJECT(chr),
1017                                       errp)) {
1018        object_unref(OBJECT(chr));
1019        return NULL;
1020    }
1021    object_unref(OBJECT(chr));
1022
1023    return chr;
1024}
1025
1026ChardevReturn *qmp_chardev_add(const char *id, ChardevBackend *backend,
1027                               Error **errp)
1028{
1029    const ChardevClass *cc;
1030    ChardevReturn *ret;
1031    Chardev *chr;
1032
1033    cc = char_get_class(ChardevBackendKind_str(backend->type), errp);
1034    if (!cc) {
1035        return NULL;
1036    }
1037
1038    chr = chardev_new(id, object_class_get_name(OBJECT_CLASS(cc)),
1039                      backend, NULL, false, errp);
1040    if (!chr) {
1041        return NULL;
1042    }
1043
1044    if (!object_property_try_add_child(get_chardevs_root(), id, OBJECT(chr),
1045                                       errp)) {
1046        object_unref(OBJECT(chr));
1047        return NULL;
1048    }
1049    object_unref(OBJECT(chr));
1050
1051    ret = g_new0(ChardevReturn, 1);
1052    if (CHARDEV_IS_PTY(chr)) {
1053        ret->pty = g_strdup(chr->filename + 4);
1054        ret->has_pty = true;
1055    }
1056
1057    return ret;
1058}
1059
1060ChardevReturn *qmp_chardev_change(const char *id, ChardevBackend *backend,
1061                                  Error **errp)
1062{
1063    CharBackend *be;
1064    const ChardevClass *cc, *cc_new;
1065    Chardev *chr, *chr_new;
1066    bool closed_sent = false;
1067    bool handover_yank_instance;
1068    ChardevReturn *ret;
1069
1070    chr = qemu_chr_find(id);
1071    if (!chr) {
1072        error_setg(errp, "Chardev '%s' does not exist", id);
1073        return NULL;
1074    }
1075
1076    if (CHARDEV_IS_MUX(chr)) {
1077        error_setg(errp, "Mux device hotswap not supported yet");
1078        return NULL;
1079    }
1080
1081    if (qemu_chr_replay(chr)) {
1082        error_setg(errp,
1083            "Chardev '%s' cannot be changed in record/replay mode", id);
1084        return NULL;
1085    }
1086
1087    be = chr->be;
1088    if (!be) {
1089        /* easy case */
1090        object_unparent(OBJECT(chr));
1091        return qmp_chardev_add(id, backend, errp);
1092    }
1093
1094    if (!be->chr_be_change) {
1095        error_setg(errp, "Chardev user does not support chardev hotswap");
1096        return NULL;
1097    }
1098
1099    cc = CHARDEV_GET_CLASS(chr);
1100    cc_new = char_get_class(ChardevBackendKind_str(backend->type), errp);
1101    if (!cc_new) {
1102        return NULL;
1103    }
1104
1105    /*
1106     * The new chardev should not register a yank instance if the current
1107     * chardev has registered one already.
1108     */
1109    handover_yank_instance = cc->supports_yank && cc_new->supports_yank;
1110
1111    chr_new = chardev_new(id, object_class_get_name(OBJECT_CLASS(cc_new)),
1112                          backend, chr->gcontext, handover_yank_instance, errp);
1113    if (!chr_new) {
1114        return NULL;
1115    }
1116
1117    if (chr->be_open && !chr_new->be_open) {
1118        qemu_chr_be_event(chr, CHR_EVENT_CLOSED);
1119        closed_sent = true;
1120    }
1121
1122    chr->be = NULL;
1123    qemu_chr_fe_init(be, chr_new, &error_abort);
1124
1125    if (be->chr_be_change(be->opaque) < 0) {
1126        error_setg(errp, "Chardev '%s' change failed", chr_new->label);
1127        chr_new->be = NULL;
1128        qemu_chr_fe_init(be, chr, &error_abort);
1129        if (closed_sent) {
1130            qemu_chr_be_event(chr, CHR_EVENT_OPENED);
1131        }
1132        object_unref(OBJECT(chr_new));
1133        return NULL;
1134    }
1135
1136    /* change successfull, clean up */
1137    chr_new->handover_yank_instance = false;
1138
1139    /*
1140     * When the old chardev is freed, it should not unregister the yank
1141     * instance if the new chardev needs it.
1142     */
1143    chr->handover_yank_instance = handover_yank_instance;
1144
1145    object_unparent(OBJECT(chr));
1146    object_property_add_child(get_chardevs_root(), chr_new->label,
1147                              OBJECT(chr_new));
1148    object_unref(OBJECT(chr_new));
1149
1150    ret = g_new0(ChardevReturn, 1);
1151    if (CHARDEV_IS_PTY(chr_new)) {
1152        ret->pty = g_strdup(chr_new->filename + 4);
1153        ret->has_pty = true;
1154    }
1155
1156    return ret;
1157}
1158
1159void qmp_chardev_remove(const char *id, Error **errp)
1160{
1161    Chardev *chr;
1162
1163    chr = qemu_chr_find(id);
1164    if (chr == NULL) {
1165        error_setg(errp, "Chardev '%s' not found", id);
1166        return;
1167    }
1168    if (qemu_chr_is_busy(chr)) {
1169        error_setg(errp, "Chardev '%s' is busy", id);
1170        return;
1171    }
1172    if (qemu_chr_replay(chr)) {
1173        error_setg(errp,
1174            "Chardev '%s' cannot be unplugged in record/replay mode", id);
1175        return;
1176    }
1177    object_unparent(OBJECT(chr));
1178}
1179
1180void qmp_chardev_send_break(const char *id, Error **errp)
1181{
1182    Chardev *chr;
1183
1184    chr = qemu_chr_find(id);
1185    if (chr == NULL) {
1186        error_setg(errp, "Chardev '%s' not found", id);
1187        return;
1188    }
1189    qemu_chr_be_event(chr, CHR_EVENT_BREAK);
1190}
1191
1192/*
1193 * Add a timeout callback for the chardev (in milliseconds), return
1194 * the GSource object created. Please use this to add timeout hook for
1195 * chardev instead of g_timeout_add() and g_timeout_add_seconds(), to
1196 * make sure the gcontext that the task bound to is correct.
1197 */
1198GSource *qemu_chr_timeout_add_ms(Chardev *chr, guint ms,
1199                                 GSourceFunc func, void *private)
1200{
1201    GSource *source = g_timeout_source_new(ms);
1202
1203    assert(func);
1204    g_source_set_callback(source, func, private, NULL);
1205    g_source_attach(source, chr->gcontext);
1206
1207    return source;
1208}
1209
1210void qemu_chr_cleanup(void)
1211{
1212    object_unparent(get_chardevs_root());
1213}
1214
1215static void register_types(void)
1216{
1217    type_register_static(&char_type_info);
1218}
1219
1220type_init(register_types);
1221