qemu

FORK: QEMU emulator
git clone https://git.neptards.moe/neptards/qemu.git
Log | Files | Refs | Submodules | LICENSE

char.c (33714B)


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