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