]> Git Repo - qemu.git/blob - qdev-monitor.c
hw: move qdev-monitor.o to toplevel directory
[qemu.git] / qdev-monitor.c
1 /*
2  *  Dynamic device configuration and creation.
3  *
4  *  Copyright (c) 2009 CodeSourcery
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this library; if not, see <http://www.gnu.org/licenses/>.
18  */
19
20 #include "hw/qdev.h"
21 #include "monitor/monitor.h"
22 #include "monitor/qdev.h"
23 #include "qmp-commands.h"
24 #include "sysemu/arch_init.h"
25 #include "qemu/config-file.h"
26
27 /*
28  * Aliases were a bad idea from the start.  Let's keep them
29  * from spreading further.
30  */
31 typedef struct QDevAlias
32 {
33     const char *typename;
34     const char *alias;
35     uint32_t arch_mask;
36 } QDevAlias;
37
38 static const QDevAlias qdev_alias_table[] = {
39     { "virtio-blk-pci", "virtio-blk", QEMU_ARCH_ALL & ~QEMU_ARCH_S390X },
40     { "virtio-net-pci", "virtio-net", QEMU_ARCH_ALL & ~QEMU_ARCH_S390X },
41     { "virtio-serial-pci", "virtio-serial", QEMU_ARCH_ALL & ~QEMU_ARCH_S390X },
42     { "virtio-balloon-pci", "virtio-balloon",
43             QEMU_ARCH_ALL & ~QEMU_ARCH_S390X },
44     { "virtio-blk-s390", "virtio-blk", QEMU_ARCH_S390X },
45     { "virtio-net-s390", "virtio-net", QEMU_ARCH_S390X },
46     { "virtio-serial-s390", "virtio-serial", QEMU_ARCH_S390X },
47     { "lsi53c895a", "lsi" },
48     { "ich9-ahci", "ahci" },
49     { "kvm-pci-assign", "pci-assign" },
50     { }
51 };
52
53 static const char *qdev_class_get_alias(DeviceClass *dc)
54 {
55     const char *typename = object_class_get_name(OBJECT_CLASS(dc));
56     int i;
57
58     for (i = 0; qdev_alias_table[i].typename; i++) {
59         if (qdev_alias_table[i].arch_mask &&
60             !(qdev_alias_table[i].arch_mask & arch_type)) {
61             continue;
62         }
63
64         if (strcmp(qdev_alias_table[i].typename, typename) == 0) {
65             return qdev_alias_table[i].alias;
66         }
67     }
68
69     return NULL;
70 }
71
72 static bool qdev_class_has_alias(DeviceClass *dc)
73 {
74     return (qdev_class_get_alias(dc) != NULL);
75 }
76
77 static void qdev_print_devinfo(ObjectClass *klass, void *opaque)
78 {
79     DeviceClass *dc;
80     bool *show_no_user = opaque;
81
82     dc = (DeviceClass *)object_class_dynamic_cast(klass, TYPE_DEVICE);
83
84     if (!dc || (show_no_user && !*show_no_user && dc->no_user)) {
85         return;
86     }
87
88     error_printf("name \"%s\"", object_class_get_name(klass));
89     if (dc->bus_type) {
90         error_printf(", bus %s", dc->bus_type);
91     }
92     if (qdev_class_has_alias(dc)) {
93         error_printf(", alias \"%s\"", qdev_class_get_alias(dc));
94     }
95     if (dc->desc) {
96         error_printf(", desc \"%s\"", dc->desc);
97     }
98     if (dc->no_user) {
99         error_printf(", no-user");
100     }
101     error_printf("\n");
102 }
103
104 static int set_property(const char *name, const char *value, void *opaque)
105 {
106     DeviceState *dev = opaque;
107
108     if (strcmp(name, "driver") == 0)
109         return 0;
110     if (strcmp(name, "bus") == 0)
111         return 0;
112
113     if (qdev_prop_parse(dev, name, value) == -1) {
114         return -1;
115     }
116     return 0;
117 }
118
119 static const char *find_typename_by_alias(const char *alias)
120 {
121     int i;
122
123     for (i = 0; qdev_alias_table[i].alias; i++) {
124         if (qdev_alias_table[i].arch_mask &&
125             !(qdev_alias_table[i].arch_mask & arch_type)) {
126             continue;
127         }
128
129         if (strcmp(qdev_alias_table[i].alias, alias) == 0) {
130             return qdev_alias_table[i].typename;
131         }
132     }
133
134     return NULL;
135 }
136
137 int qdev_device_help(QemuOpts *opts)
138 {
139     const char *driver;
140     Property *prop;
141     ObjectClass *klass;
142
143     driver = qemu_opt_get(opts, "driver");
144     if (driver && is_help_option(driver)) {
145         bool show_no_user = false;
146         object_class_foreach(qdev_print_devinfo, TYPE_DEVICE, false, &show_no_user);
147         return 1;
148     }
149
150     if (!driver || !qemu_opt_has_help_opt(opts)) {
151         return 0;
152     }
153
154     klass = object_class_by_name(driver);
155     if (!klass) {
156         const char *typename = find_typename_by_alias(driver);
157
158         if (typename) {
159             driver = typename;
160             klass = object_class_by_name(driver);
161         }
162     }
163
164     if (!klass) {
165         return 0;
166     }
167     do {
168         for (prop = DEVICE_CLASS(klass)->props; prop && prop->name; prop++) {
169             /*
170              * TODO Properties without a parser are just for dirty hacks.
171              * qdev_prop_ptr is the only such PropertyInfo.  It's marked
172              * for removal.  This conditional should be removed along with
173              * it.
174              */
175             if (!prop->info->set) {
176                 continue;           /* no way to set it, don't show */
177             }
178             error_printf("%s.%s=%s\n", driver, prop->name,
179                          prop->info->legacy_name ?: prop->info->name);
180         }
181         klass = object_class_get_parent(klass);
182     } while (klass != object_class_by_name(TYPE_DEVICE));
183     return 1;
184 }
185
186 static Object *qdev_get_peripheral(void)
187 {
188     static Object *dev;
189
190     if (dev == NULL) {
191         dev = container_get(qdev_get_machine(), "/peripheral");
192     }
193
194     return dev;
195 }
196
197 static Object *qdev_get_peripheral_anon(void)
198 {
199     static Object *dev;
200
201     if (dev == NULL) {
202         dev = container_get(qdev_get_machine(), "/peripheral-anon");
203     }
204
205     return dev;
206 }
207
208 static void qbus_list_bus(DeviceState *dev)
209 {
210     BusState *child;
211     const char *sep = " ";
212
213     error_printf("child busses at \"%s\":",
214                  dev->id ? dev->id : object_get_typename(OBJECT(dev)));
215     QLIST_FOREACH(child, &dev->child_bus, sibling) {
216         error_printf("%s\"%s\"", sep, child->name);
217         sep = ", ";
218     }
219     error_printf("\n");
220 }
221
222 static void qbus_list_dev(BusState *bus)
223 {
224     BusChild *kid;
225     const char *sep = " ";
226
227     error_printf("devices at \"%s\":", bus->name);
228     QTAILQ_FOREACH(kid, &bus->children, sibling) {
229         DeviceState *dev = kid->child;
230         error_printf("%s\"%s\"", sep, object_get_typename(OBJECT(dev)));
231         if (dev->id)
232             error_printf("/\"%s\"", dev->id);
233         sep = ", ";
234     }
235     error_printf("\n");
236 }
237
238 static BusState *qbus_find_bus(DeviceState *dev, char *elem)
239 {
240     BusState *child;
241
242     QLIST_FOREACH(child, &dev->child_bus, sibling) {
243         if (strcmp(child->name, elem) == 0) {
244             return child;
245         }
246     }
247     return NULL;
248 }
249
250 static DeviceState *qbus_find_dev(BusState *bus, char *elem)
251 {
252     BusChild *kid;
253
254     /*
255      * try to match in order:
256      *   (1) instance id, if present
257      *   (2) driver name
258      *   (3) driver alias, if present
259      */
260     QTAILQ_FOREACH(kid, &bus->children, sibling) {
261         DeviceState *dev = kid->child;
262         if (dev->id  &&  strcmp(dev->id, elem) == 0) {
263             return dev;
264         }
265     }
266     QTAILQ_FOREACH(kid, &bus->children, sibling) {
267         DeviceState *dev = kid->child;
268         if (strcmp(object_get_typename(OBJECT(dev)), elem) == 0) {
269             return dev;
270         }
271     }
272     QTAILQ_FOREACH(kid, &bus->children, sibling) {
273         DeviceState *dev = kid->child;
274         DeviceClass *dc = DEVICE_GET_CLASS(dev);
275
276         if (qdev_class_has_alias(dc) &&
277             strcmp(qdev_class_get_alias(dc), elem) == 0) {
278             return dev;
279         }
280     }
281     return NULL;
282 }
283
284 static BusState *qbus_find_recursive(BusState *bus, const char *name,
285                                      const char *bus_typename)
286 {
287     BusClass *bus_class = BUS_GET_CLASS(bus);
288     BusChild *kid;
289     BusState *child, *ret;
290     int match = 1;
291
292     if (name && (strcmp(bus->name, name) != 0)) {
293         match = 0;
294     }
295     if (bus_typename && !object_dynamic_cast(OBJECT(bus), bus_typename)) {
296         match = 0;
297     }
298     if ((bus_class->max_dev != 0) && (bus_class->max_dev <= bus->max_index)) {
299         if (name != NULL) {
300             /* bus was explicitly specified: return an error. */
301             qerror_report(ERROR_CLASS_GENERIC_ERROR, "Bus '%s' is full",
302                           bus->name);
303             return NULL;
304         } else {
305             /* bus was not specified: try to find another one. */
306             match = 0;
307         }
308     }
309     if (match) {
310         return bus;
311     }
312
313     QTAILQ_FOREACH(kid, &bus->children, sibling) {
314         DeviceState *dev = kid->child;
315         QLIST_FOREACH(child, &dev->child_bus, sibling) {
316             ret = qbus_find_recursive(child, name, bus_typename);
317             if (ret) {
318                 return ret;
319             }
320         }
321     }
322     return NULL;
323 }
324
325 static BusState *qbus_find(const char *path)
326 {
327     DeviceState *dev;
328     BusState *bus;
329     char elem[128];
330     int pos, len;
331
332     /* find start element */
333     if (path[0] == '/') {
334         bus = sysbus_get_default();
335         pos = 0;
336     } else {
337         if (sscanf(path, "%127[^/]%n", elem, &len) != 1) {
338             assert(!path[0]);
339             elem[0] = len = 0;
340         }
341         bus = qbus_find_recursive(sysbus_get_default(), elem, NULL);
342         if (!bus) {
343             qerror_report(QERR_BUS_NOT_FOUND, elem);
344             return NULL;
345         }
346         pos = len;
347     }
348
349     for (;;) {
350         assert(path[pos] == '/' || !path[pos]);
351         while (path[pos] == '/') {
352             pos++;
353         }
354         if (path[pos] == '\0') {
355             return bus;
356         }
357
358         /* find device */
359         if (sscanf(path+pos, "%127[^/]%n", elem, &len) != 1) {
360             assert(0);
361             elem[0] = len = 0;
362         }
363         pos += len;
364         dev = qbus_find_dev(bus, elem);
365         if (!dev) {
366             qerror_report(QERR_DEVICE_NOT_FOUND, elem);
367             if (!monitor_cur_is_qmp()) {
368                 qbus_list_dev(bus);
369             }
370             return NULL;
371         }
372
373         assert(path[pos] == '/' || !path[pos]);
374         while (path[pos] == '/') {
375             pos++;
376         }
377         if (path[pos] == '\0') {
378             /* last specified element is a device.  If it has exactly
379              * one child bus accept it nevertheless */
380             switch (dev->num_child_bus) {
381             case 0:
382                 qerror_report(QERR_DEVICE_NO_BUS, elem);
383                 return NULL;
384             case 1:
385                 return QLIST_FIRST(&dev->child_bus);
386             default:
387                 qerror_report(QERR_DEVICE_MULTIPLE_BUSSES, elem);
388                 if (!monitor_cur_is_qmp()) {
389                     qbus_list_bus(dev);
390                 }
391                 return NULL;
392             }
393         }
394
395         /* find bus */
396         if (sscanf(path+pos, "%127[^/]%n", elem, &len) != 1) {
397             assert(0);
398             elem[0] = len = 0;
399         }
400         pos += len;
401         bus = qbus_find_bus(dev, elem);
402         if (!bus) {
403             qerror_report(QERR_BUS_NOT_FOUND, elem);
404             if (!monitor_cur_is_qmp()) {
405                 qbus_list_bus(dev);
406             }
407             return NULL;
408         }
409     }
410 }
411
412 DeviceState *qdev_device_add(QemuOpts *opts)
413 {
414     ObjectClass *obj;
415     DeviceClass *k;
416     const char *driver, *path, *id;
417     DeviceState *qdev;
418     BusState *bus;
419
420     driver = qemu_opt_get(opts, "driver");
421     if (!driver) {
422         qerror_report(QERR_MISSING_PARAMETER, "driver");
423         return NULL;
424     }
425
426     /* find driver */
427     obj = object_class_by_name(driver);
428     if (!obj) {
429         const char *typename = find_typename_by_alias(driver);
430
431         if (typename) {
432             driver = typename;
433             obj = object_class_by_name(driver);
434         }
435     }
436
437     if (!obj) {
438         qerror_report(QERR_INVALID_PARAMETER_VALUE, "driver", "device type");
439         return NULL;
440     }
441
442     k = DEVICE_CLASS(obj);
443
444     /* find bus */
445     path = qemu_opt_get(opts, "bus");
446     if (path != NULL) {
447         bus = qbus_find(path);
448         if (!bus) {
449             return NULL;
450         }
451         if (!object_dynamic_cast(OBJECT(bus), k->bus_type)) {
452             qerror_report(QERR_BAD_BUS_FOR_DEVICE,
453                           driver, object_get_typename(OBJECT(bus)));
454             return NULL;
455         }
456     } else {
457         bus = qbus_find_recursive(sysbus_get_default(), NULL, k->bus_type);
458         if (!bus) {
459             qerror_report(QERR_NO_BUS_FOR_DEVICE,
460                           k->bus_type, driver);
461             return NULL;
462         }
463     }
464     if (qdev_hotplug && !bus->allow_hotplug) {
465         qerror_report(QERR_BUS_NO_HOTPLUG, bus->name);
466         return NULL;
467     }
468
469     if (!bus) {
470         bus = sysbus_get_default();
471     }
472
473     /* create device, set properties */
474     qdev = DEVICE(object_new(driver));
475     qdev_set_parent_bus(qdev, bus);
476
477     id = qemu_opts_id(opts);
478     if (id) {
479         qdev->id = id;
480     }
481     if (qemu_opt_foreach(opts, set_property, qdev, 1) != 0) {
482         qdev_free(qdev);
483         return NULL;
484     }
485     if (qdev->id) {
486         object_property_add_child(qdev_get_peripheral(), qdev->id,
487                                   OBJECT(qdev), NULL);
488     } else {
489         static int anon_count;
490         gchar *name = g_strdup_printf("device[%d]", anon_count++);
491         object_property_add_child(qdev_get_peripheral_anon(), name,
492                                   OBJECT(qdev), NULL);
493         g_free(name);
494     }        
495     if (qdev_init(qdev) < 0) {
496         qerror_report(QERR_DEVICE_INIT_FAILED, driver);
497         return NULL;
498     }
499     qdev->opts = opts;
500     return qdev;
501 }
502
503
504 #define qdev_printf(fmt, ...) monitor_printf(mon, "%*s" fmt, indent, "", ## __VA_ARGS__)
505 static void qbus_print(Monitor *mon, BusState *bus, int indent);
506
507 static void qdev_print_props(Monitor *mon, DeviceState *dev, Property *props,
508                              int indent)
509 {
510     if (!props)
511         return;
512     for (; props->name; props++) {
513         Error *err = NULL;
514         char *value;
515         char *legacy_name = g_strdup_printf("legacy-%s", props->name);
516         if (object_property_get_type(OBJECT(dev), legacy_name, NULL)) {
517             value = object_property_get_str(OBJECT(dev), legacy_name, &err);
518         } else {
519             value = object_property_print(OBJECT(dev), props->name, &err);
520         }
521         g_free(legacy_name);
522
523         if (err) {
524             error_free(err);
525             continue;
526         }
527         qdev_printf("%s = %s\n", props->name,
528                     value && *value ? value : "<null>");
529         g_free(value);
530     }
531 }
532
533 static void bus_print_dev(BusState *bus, Monitor *mon, DeviceState *dev, int indent)
534 {
535     BusClass *bc = BUS_GET_CLASS(bus);
536
537     if (bc->print_dev) {
538         bc->print_dev(mon, dev, indent);
539     }
540 }
541
542 static void qdev_print(Monitor *mon, DeviceState *dev, int indent)
543 {
544     ObjectClass *class;
545     BusState *child;
546     qdev_printf("dev: %s, id \"%s\"\n", object_get_typename(OBJECT(dev)),
547                 dev->id ? dev->id : "");
548     indent += 2;
549     if (dev->num_gpio_in) {
550         qdev_printf("gpio-in %d\n", dev->num_gpio_in);
551     }
552     if (dev->num_gpio_out) {
553         qdev_printf("gpio-out %d\n", dev->num_gpio_out);
554     }
555     class = object_get_class(OBJECT(dev));
556     do {
557         qdev_print_props(mon, dev, DEVICE_CLASS(class)->props, indent);
558         class = object_class_get_parent(class);
559     } while (class != object_class_by_name(TYPE_DEVICE));
560     bus_print_dev(dev->parent_bus, mon, dev, indent);
561     QLIST_FOREACH(child, &dev->child_bus, sibling) {
562         qbus_print(mon, child, indent);
563     }
564 }
565
566 static void qbus_print(Monitor *mon, BusState *bus, int indent)
567 {
568     BusChild *kid;
569
570     qdev_printf("bus: %s\n", bus->name);
571     indent += 2;
572     qdev_printf("type %s\n", object_get_typename(OBJECT(bus)));
573     QTAILQ_FOREACH(kid, &bus->children, sibling) {
574         DeviceState *dev = kid->child;
575         qdev_print(mon, dev, indent);
576     }
577 }
578 #undef qdev_printf
579
580 void do_info_qtree(Monitor *mon, const QDict *qdict)
581 {
582     if (sysbus_get_default())
583         qbus_print(mon, sysbus_get_default(), 0);
584 }
585
586 void do_info_qdm(Monitor *mon, const QDict *qdict)
587 {
588     object_class_foreach(qdev_print_devinfo, TYPE_DEVICE, false, NULL);
589 }
590
591 int do_device_add(Monitor *mon, const QDict *qdict, QObject **ret_data)
592 {
593     Error *local_err = NULL;
594     QemuOpts *opts;
595     DeviceState *dev;
596
597     opts = qemu_opts_from_qdict(qemu_find_opts("device"), qdict, &local_err);
598     if (error_is_set(&local_err)) {
599         qerror_report_err(local_err);
600         error_free(local_err);
601         return -1;
602     }
603     if (!monitor_cur_is_qmp() && qdev_device_help(opts)) {
604         qemu_opts_del(opts);
605         return 0;
606     }
607     dev = qdev_device_add(opts);
608     if (!dev) {
609         qemu_opts_del(opts);
610         return -1;
611     }
612     object_unref(OBJECT(dev));
613     return 0;
614 }
615
616 void qmp_device_del(const char *id, Error **errp)
617 {
618     DeviceState *dev;
619
620     dev = qdev_find_recursive(sysbus_get_default(), id);
621     if (NULL == dev) {
622         error_set(errp, QERR_DEVICE_NOT_FOUND, id);
623         return;
624     }
625
626     qdev_unplug(dev, errp);
627 }
628
629 void qdev_machine_init(void)
630 {
631     qdev_get_peripheral_anon();
632     qdev_get_peripheral();
633 }
634
635 QemuOptsList qemu_device_opts = {
636     .name = "device",
637     .implied_opt_name = "driver",
638     .head = QTAILQ_HEAD_INITIALIZER(qemu_device_opts.head),
639     .desc = {
640         /*
641          * no elements => accept any
642          * sanity checking will happen later
643          * when setting device properties
644          */
645         { /* end of list */ }
646     },
647 };
648
649 QemuOptsList qemu_global_opts = {
650     .name = "global",
651     .head = QTAILQ_HEAD_INITIALIZER(qemu_global_opts.head),
652     .desc = {
653         {
654             .name = "driver",
655             .type = QEMU_OPT_STRING,
656         },{
657             .name = "property",
658             .type = QEMU_OPT_STRING,
659         },{
660             .name = "value",
661             .type = QEMU_OPT_STRING,
662         },
663         { /* end of list */ }
664     },
665 };
666
667 int qemu_global_option(const char *str)
668 {
669     char driver[64], property[64];
670     QemuOpts *opts;
671     int rc, offset;
672
673     rc = sscanf(str, "%63[^.].%63[^=]%n", driver, property, &offset);
674     if (rc < 2 || str[offset] != '=') {
675         error_report("can't parse: \"%s\"", str);
676         return -1;
677     }
678
679     opts = qemu_opts_create_nofail(&qemu_global_opts);
680     qemu_opt_set(opts, "driver", driver);
681     qemu_opt_set(opts, "property", property);
682     qemu_opt_set(opts, "value", str+offset+1);
683     return 0;
684 }
This page took 0.063515 seconds and 4 git commands to generate.