QemuOpts: Wean off qerror_report_err()
[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 "hw/sysbus.h"
22 #include "monitor/monitor.h"
23 #include "monitor/qdev.h"
24 #include "qmp-commands.h"
25 #include "sysemu/arch_init.h"
26 #include "qemu/config-file.h"
27
28 /*
29  * Aliases were a bad idea from the start.  Let's keep them
30  * from spreading further.
31  */
32 typedef struct QDevAlias
33 {
34     const char *typename;
35     const char *alias;
36     uint32_t arch_mask;
37 } QDevAlias;
38
39 static const QDevAlias qdev_alias_table[] = {
40     { "virtio-blk-pci", "virtio-blk", QEMU_ARCH_ALL & ~QEMU_ARCH_S390X },
41     { "virtio-net-pci", "virtio-net", QEMU_ARCH_ALL & ~QEMU_ARCH_S390X },
42     { "virtio-serial-pci", "virtio-serial", QEMU_ARCH_ALL & ~QEMU_ARCH_S390X },
43     { "virtio-balloon-pci", "virtio-balloon",
44             QEMU_ARCH_ALL & ~QEMU_ARCH_S390X },
45     { "virtio-blk-ccw", "virtio-blk", QEMU_ARCH_S390X },
46     { "virtio-net-ccw", "virtio-net", QEMU_ARCH_S390X },
47     { "virtio-serial-ccw", "virtio-serial", QEMU_ARCH_S390X },
48     { "lsi53c895a", "lsi" },
49     { "ich9-ahci", "ahci" },
50     { "kvm-pci-assign", "pci-assign" },
51     { }
52 };
53
54 static const char *qdev_class_get_alias(DeviceClass *dc)
55 {
56     const char *typename = object_class_get_name(OBJECT_CLASS(dc));
57     int i;
58
59     for (i = 0; qdev_alias_table[i].typename; i++) {
60         if (qdev_alias_table[i].arch_mask &&
61             !(qdev_alias_table[i].arch_mask & arch_type)) {
62             continue;
63         }
64
65         if (strcmp(qdev_alias_table[i].typename, typename) == 0) {
66             return qdev_alias_table[i].alias;
67         }
68     }
69
70     return NULL;
71 }
72
73 static bool qdev_class_has_alias(DeviceClass *dc)
74 {
75     return (qdev_class_get_alias(dc) != NULL);
76 }
77
78 static void qdev_print_devinfo(DeviceClass *dc)
79 {
80     error_printf("name \"%s\"", object_class_get_name(OBJECT_CLASS(dc)));
81     if (dc->bus_type) {
82         error_printf(", bus %s", dc->bus_type);
83     }
84     if (qdev_class_has_alias(dc)) {
85         error_printf(", alias \"%s\"", qdev_class_get_alias(dc));
86     }
87     if (dc->desc) {
88         error_printf(", desc \"%s\"", dc->desc);
89     }
90     if (dc->cannot_instantiate_with_device_add_yet) {
91         error_printf(", no-user");
92     }
93     error_printf("\n");
94 }
95
96 static gint devinfo_cmp(gconstpointer a, gconstpointer b)
97 {
98     return strcasecmp(object_class_get_name((ObjectClass *)a),
99                       object_class_get_name((ObjectClass *)b));
100 }
101
102 static void qdev_print_devinfos(bool show_no_user)
103 {
104     static const char *cat_name[DEVICE_CATEGORY_MAX + 1] = {
105         [DEVICE_CATEGORY_BRIDGE]  = "Controller/Bridge/Hub",
106         [DEVICE_CATEGORY_USB]     = "USB",
107         [DEVICE_CATEGORY_STORAGE] = "Storage",
108         [DEVICE_CATEGORY_NETWORK] = "Network",
109         [DEVICE_CATEGORY_INPUT]   = "Input",
110         [DEVICE_CATEGORY_DISPLAY] = "Display",
111         [DEVICE_CATEGORY_SOUND]   = "Sound",
112         [DEVICE_CATEGORY_MISC]    = "Misc",
113         [DEVICE_CATEGORY_MAX]     = "Uncategorized",
114     };
115     GSList *list, *elt;
116     int i;
117     bool cat_printed;
118
119     list = g_slist_sort(object_class_get_list(TYPE_DEVICE, false),
120                         devinfo_cmp);
121
122     for (i = 0; i <= DEVICE_CATEGORY_MAX; i++) {
123         cat_printed = false;
124         for (elt = list; elt; elt = elt->next) {
125             DeviceClass *dc = OBJECT_CLASS_CHECK(DeviceClass, elt->data,
126                                                  TYPE_DEVICE);
127             if ((i < DEVICE_CATEGORY_MAX
128                  ? !test_bit(i, dc->categories)
129                  : !bitmap_empty(dc->categories, DEVICE_CATEGORY_MAX))
130                 || (!show_no_user
131                     && dc->cannot_instantiate_with_device_add_yet)) {
132                 continue;
133             }
134             if (!cat_printed) {
135                 error_printf("%s%s devices:\n", i ? "\n" : "",
136                              cat_name[i]);
137                 cat_printed = true;
138             }
139             qdev_print_devinfo(dc);
140         }
141     }
142
143     g_slist_free(list);
144 }
145
146 static int set_property(void *opaque, const char *name, const char *value,
147                         Error **errp)
148 {
149     Object *obj = opaque;
150     Error *err = NULL;
151
152     if (strcmp(name, "driver") == 0)
153         return 0;
154     if (strcmp(name, "bus") == 0)
155         return 0;
156
157     object_property_parse(obj, value, name, &err);
158     if (err != NULL) {
159         error_propagate(errp, err);
160         return -1;
161     }
162     return 0;
163 }
164
165 static const char *find_typename_by_alias(const char *alias)
166 {
167     int i;
168
169     for (i = 0; qdev_alias_table[i].alias; i++) {
170         if (qdev_alias_table[i].arch_mask &&
171             !(qdev_alias_table[i].arch_mask & arch_type)) {
172             continue;
173         }
174
175         if (strcmp(qdev_alias_table[i].alias, alias) == 0) {
176             return qdev_alias_table[i].typename;
177         }
178     }
179
180     return NULL;
181 }
182
183 static DeviceClass *qdev_get_device_class(const char **driver, Error **errp)
184 {
185     ObjectClass *oc;
186     DeviceClass *dc;
187
188     oc = object_class_by_name(*driver);
189     if (!oc) {
190         const char *typename = find_typename_by_alias(*driver);
191
192         if (typename) {
193             *driver = typename;
194             oc = object_class_by_name(*driver);
195         }
196     }
197
198     if (!object_class_dynamic_cast(oc, TYPE_DEVICE)) {
199         error_setg(errp, "'%s' is not a valid device model name", *driver);
200         return NULL;
201     }
202
203     if (object_class_is_abstract(oc)) {
204         error_set(errp, QERR_INVALID_PARAMETER_VALUE, "driver",
205                   "non-abstract device type");
206         return NULL;
207     }
208
209     dc = DEVICE_CLASS(oc);
210     if (dc->cannot_instantiate_with_device_add_yet ||
211         (qdev_hotplug && !dc->hotpluggable)) {
212         error_set(errp, QERR_INVALID_PARAMETER_VALUE, "driver",
213                   "pluggable device type");
214         return NULL;
215     }
216
217     return dc;
218 }
219
220
221 int qdev_device_help(QemuOpts *opts)
222 {
223     Error *local_err = NULL;
224     const char *driver;
225     DevicePropertyInfoList *prop_list;
226     DevicePropertyInfoList *prop;
227
228     driver = qemu_opt_get(opts, "driver");
229     if (driver && is_help_option(driver)) {
230         qdev_print_devinfos(false);
231         return 1;
232     }
233
234     if (!driver || !qemu_opt_has_help_opt(opts)) {
235         return 0;
236     }
237
238     qdev_get_device_class(&driver, &local_err);
239     if (local_err) {
240         goto error;
241     }
242
243     prop_list = qmp_device_list_properties(driver, &local_err);
244     if (local_err) {
245         goto error;
246     }
247
248     for (prop = prop_list; prop; prop = prop->next) {
249         error_printf("%s.%s=%s", driver,
250                      prop->value->name,
251                      prop->value->type);
252         if (prop->value->has_description) {
253             error_printf(" (%s)\n", prop->value->description);
254         } else {
255             error_printf("\n");
256         }
257     }
258
259     qapi_free_DevicePropertyInfoList(prop_list);
260     return 1;
261
262 error:
263     error_printf("%s\n", error_get_pretty(local_err));
264     error_free(local_err);
265     return 1;
266 }
267
268 static Object *qdev_get_peripheral(void)
269 {
270     static Object *dev;
271
272     if (dev == NULL) {
273         dev = container_get(qdev_get_machine(), "/peripheral");
274     }
275
276     return dev;
277 }
278
279 static Object *qdev_get_peripheral_anon(void)
280 {
281     static Object *dev;
282
283     if (dev == NULL) {
284         dev = container_get(qdev_get_machine(), "/peripheral-anon");
285     }
286
287     return dev;
288 }
289
290 #if 0 /* conversion from qerror_report() to error_set() broke their use */
291 static void qbus_list_bus(DeviceState *dev)
292 {
293     BusState *child;
294     const char *sep = " ";
295
296     error_printf("child buses at \"%s\":",
297                  dev->id ? dev->id : object_get_typename(OBJECT(dev)));
298     QLIST_FOREACH(child, &dev->child_bus, sibling) {
299         error_printf("%s\"%s\"", sep, child->name);
300         sep = ", ";
301     }
302     error_printf("\n");
303 }
304
305 static void qbus_list_dev(BusState *bus)
306 {
307     BusChild *kid;
308     const char *sep = " ";
309
310     error_printf("devices at \"%s\":", bus->name);
311     QTAILQ_FOREACH(kid, &bus->children, sibling) {
312         DeviceState *dev = kid->child;
313         error_printf("%s\"%s\"", sep, object_get_typename(OBJECT(dev)));
314         if (dev->id)
315             error_printf("/\"%s\"", dev->id);
316         sep = ", ";
317     }
318     error_printf("\n");
319 }
320 #endif
321
322 static BusState *qbus_find_bus(DeviceState *dev, char *elem)
323 {
324     BusState *child;
325
326     QLIST_FOREACH(child, &dev->child_bus, sibling) {
327         if (strcmp(child->name, elem) == 0) {
328             return child;
329         }
330     }
331     return NULL;
332 }
333
334 static DeviceState *qbus_find_dev(BusState *bus, char *elem)
335 {
336     BusChild *kid;
337
338     /*
339      * try to match in order:
340      *   (1) instance id, if present
341      *   (2) driver name
342      *   (3) driver alias, if present
343      */
344     QTAILQ_FOREACH(kid, &bus->children, sibling) {
345         DeviceState *dev = kid->child;
346         if (dev->id  &&  strcmp(dev->id, elem) == 0) {
347             return dev;
348         }
349     }
350     QTAILQ_FOREACH(kid, &bus->children, sibling) {
351         DeviceState *dev = kid->child;
352         if (strcmp(object_get_typename(OBJECT(dev)), elem) == 0) {
353             return dev;
354         }
355     }
356     QTAILQ_FOREACH(kid, &bus->children, sibling) {
357         DeviceState *dev = kid->child;
358         DeviceClass *dc = DEVICE_GET_CLASS(dev);
359
360         if (qdev_class_has_alias(dc) &&
361             strcmp(qdev_class_get_alias(dc), elem) == 0) {
362             return dev;
363         }
364     }
365     return NULL;
366 }
367
368 static inline bool qbus_is_full(BusState *bus)
369 {
370     BusClass *bus_class = BUS_GET_CLASS(bus);
371     return bus_class->max_dev && bus->max_index >= bus_class->max_dev;
372 }
373
374 /*
375  * Search the tree rooted at @bus for a bus.
376  * If @name, search for a bus with that name.  Note that bus names
377  * need not be unique.  Yes, that's screwed up.
378  * Else search for a bus that is a subtype of @bus_typename.
379  * If more than one exists, prefer one that can take another device.
380  * Return the bus if found, else %NULL.
381  */
382 static BusState *qbus_find_recursive(BusState *bus, const char *name,
383                                      const char *bus_typename)
384 {
385     BusChild *kid;
386     BusState *pick, *child, *ret;
387     bool match;
388
389     assert(name || bus_typename);
390     if (name) {
391         match = !strcmp(bus->name, name);
392     } else {
393         match = !!object_dynamic_cast(OBJECT(bus), bus_typename);
394     }
395
396     if (match && !qbus_is_full(bus)) {
397         return bus;             /* root matches and isn't full */
398     }
399
400     pick = match ? bus : NULL;
401
402     QTAILQ_FOREACH(kid, &bus->children, sibling) {
403         DeviceState *dev = kid->child;
404         QLIST_FOREACH(child, &dev->child_bus, sibling) {
405             ret = qbus_find_recursive(child, name, bus_typename);
406             if (ret && !qbus_is_full(ret)) {
407                 return ret;     /* a descendant matches and isn't full */
408             }
409             if (ret && !pick) {
410                 pick = ret;
411             }
412         }
413     }
414
415     /* root or a descendant matches, but is full */
416     return pick;
417 }
418
419 static BusState *qbus_find(const char *path, Error **errp)
420 {
421     DeviceState *dev;
422     BusState *bus;
423     char elem[128];
424     int pos, len;
425
426     /* find start element */
427     if (path[0] == '/') {
428         bus = sysbus_get_default();
429         pos = 0;
430     } else {
431         if (sscanf(path, "%127[^/]%n", elem, &len) != 1) {
432             assert(!path[0]);
433             elem[0] = len = 0;
434         }
435         bus = qbus_find_recursive(sysbus_get_default(), elem, NULL);
436         if (!bus) {
437             error_setg(errp, "Bus '%s' not found", elem);
438             return NULL;
439         }
440         pos = len;
441     }
442
443     for (;;) {
444         assert(path[pos] == '/' || !path[pos]);
445         while (path[pos] == '/') {
446             pos++;
447         }
448         if (path[pos] == '\0') {
449             break;
450         }
451
452         /* find device */
453         if (sscanf(path+pos, "%127[^/]%n", elem, &len) != 1) {
454             g_assert_not_reached();
455             elem[0] = len = 0;
456         }
457         pos += len;
458         dev = qbus_find_dev(bus, elem);
459         if (!dev) {
460             error_set(errp, QERR_DEVICE_NOT_FOUND, elem);
461 #if 0 /* conversion from qerror_report() to error_set() broke this: */
462             if (!monitor_cur_is_qmp()) {
463                 qbus_list_dev(bus);
464             }
465 #endif
466             return NULL;
467         }
468
469         assert(path[pos] == '/' || !path[pos]);
470         while (path[pos] == '/') {
471             pos++;
472         }
473         if (path[pos] == '\0') {
474             /* last specified element is a device.  If it has exactly
475              * one child bus accept it nevertheless */
476             if (dev->num_child_bus == 1) {
477                 bus = QLIST_FIRST(&dev->child_bus);
478                 break;
479             }
480             if (dev->num_child_bus) {
481                 error_setg(errp, "Device '%s' has multiple child buses",
482                            elem);
483 #if 0 /* conversion from qerror_report() to error_set() broke this: */
484                 if (!monitor_cur_is_qmp()) {
485                     qbus_list_bus(dev);
486                 }
487 #endif
488             } else {
489                 error_setg(errp, "Device '%s' has no child bus", elem);
490             }
491             return NULL;
492         }
493
494         /* find bus */
495         if (sscanf(path+pos, "%127[^/]%n", elem, &len) != 1) {
496             g_assert_not_reached();
497             elem[0] = len = 0;
498         }
499         pos += len;
500         bus = qbus_find_bus(dev, elem);
501         if (!bus) {
502             error_setg(errp, "Bus '%s' not found", elem);
503 #if 0 /* conversion from qerror_report() to error_set() broke this: */
504             if (!monitor_cur_is_qmp()) {
505                 qbus_list_bus(dev);
506             }
507 #endif
508             return NULL;
509         }
510     }
511
512     if (qbus_is_full(bus)) {
513         error_setg(errp, "Bus '%s' is full", path);
514         return NULL;
515     }
516     return bus;
517 }
518
519 DeviceState *qdev_device_add(QemuOpts *opts, Error **errp)
520 {
521     DeviceClass *dc;
522     const char *driver, *path, *id;
523     DeviceState *dev;
524     BusState *bus = NULL;
525     Error *err = NULL;
526
527     driver = qemu_opt_get(opts, "driver");
528     if (!driver) {
529         error_set(errp, QERR_MISSING_PARAMETER, "driver");
530         return NULL;
531     }
532
533     /* find driver */
534     dc = qdev_get_device_class(&driver, errp);
535     if (!dc) {
536         return NULL;
537     }
538
539     /* find bus */
540     path = qemu_opt_get(opts, "bus");
541     if (path != NULL) {
542         bus = qbus_find(path, errp);
543         if (!bus) {
544             return NULL;
545         }
546         if (!object_dynamic_cast(OBJECT(bus), dc->bus_type)) {
547             error_setg(errp, "Device '%s' can't go on %s bus",
548                        driver, object_get_typename(OBJECT(bus)));
549             return NULL;
550         }
551     } else if (dc->bus_type != NULL) {
552         bus = qbus_find_recursive(sysbus_get_default(), NULL, dc->bus_type);
553         if (!bus || qbus_is_full(bus)) {
554             error_setg(errp, "No '%s' bus found for device '%s'",
555                        dc->bus_type, driver);
556             return NULL;
557         }
558     }
559     if (qdev_hotplug && bus && !qbus_is_hotpluggable(bus)) {
560         error_set(errp, QERR_BUS_NO_HOTPLUG, bus->name);
561         return NULL;
562     }
563
564     /* create device */
565     dev = DEVICE(object_new(driver));
566
567     if (bus) {
568         qdev_set_parent_bus(dev, bus);
569     }
570
571     id = qemu_opts_id(opts);
572     if (id) {
573         dev->id = id;
574     }
575
576     if (dev->id) {
577         object_property_add_child(qdev_get_peripheral(), dev->id,
578                                   OBJECT(dev), NULL);
579     } else {
580         static int anon_count;
581         gchar *name = g_strdup_printf("device[%d]", anon_count++);
582         object_property_add_child(qdev_get_peripheral_anon(), name,
583                                   OBJECT(dev), NULL);
584         g_free(name);
585     }
586
587     /* set properties */
588     if (qemu_opt_foreach(opts, set_property, dev, &err)) {
589         error_propagate(errp, err);
590         object_unparent(OBJECT(dev));
591         object_unref(OBJECT(dev));
592         return NULL;
593     }
594
595     dev->opts = opts;
596     object_property_set_bool(OBJECT(dev), true, "realized", &err);
597     if (err != NULL) {
598         error_propagate(errp, err);
599         dev->opts = NULL;
600         object_unparent(OBJECT(dev));
601         object_unref(OBJECT(dev));
602         return NULL;
603     }
604     return dev;
605 }
606
607
608 #define qdev_printf(fmt, ...) monitor_printf(mon, "%*s" fmt, indent, "", ## __VA_ARGS__)
609 static void qbus_print(Monitor *mon, BusState *bus, int indent);
610
611 static void qdev_print_props(Monitor *mon, DeviceState *dev, Property *props,
612                              int indent)
613 {
614     if (!props)
615         return;
616     for (; props->name; props++) {
617         Error *err = NULL;
618         char *value;
619         char *legacy_name = g_strdup_printf("legacy-%s", props->name);
620         if (object_property_get_type(OBJECT(dev), legacy_name, NULL)) {
621             value = object_property_get_str(OBJECT(dev), legacy_name, &err);
622         } else {
623             value = object_property_print(OBJECT(dev), props->name, true, &err);
624         }
625         g_free(legacy_name);
626
627         if (err) {
628             error_free(err);
629             continue;
630         }
631         qdev_printf("%s = %s\n", props->name,
632                     value && *value ? value : "<null>");
633         g_free(value);
634     }
635 }
636
637 static void bus_print_dev(BusState *bus, Monitor *mon, DeviceState *dev, int indent)
638 {
639     BusClass *bc = BUS_GET_CLASS(bus);
640
641     if (bc->print_dev) {
642         bc->print_dev(mon, dev, indent);
643     }
644 }
645
646 static void qdev_print(Monitor *mon, DeviceState *dev, int indent)
647 {
648     ObjectClass *class;
649     BusState *child;
650     NamedGPIOList *ngl;
651
652     qdev_printf("dev: %s, id \"%s\"\n", object_get_typename(OBJECT(dev)),
653                 dev->id ? dev->id : "");
654     indent += 2;
655     QLIST_FOREACH(ngl, &dev->gpios, node) {
656         if (ngl->num_in) {
657             qdev_printf("gpio-in \"%s\" %d\n", ngl->name ? ngl->name : "",
658                         ngl->num_in);
659         }
660         if (ngl->num_out) {
661             qdev_printf("gpio-out \"%s\" %d\n", ngl->name ? ngl->name : "",
662                         ngl->num_out);
663         }
664     }
665     class = object_get_class(OBJECT(dev));
666     do {
667         qdev_print_props(mon, dev, DEVICE_CLASS(class)->props, indent);
668         class = object_class_get_parent(class);
669     } while (class != object_class_by_name(TYPE_DEVICE));
670     bus_print_dev(dev->parent_bus, mon, dev, indent);
671     QLIST_FOREACH(child, &dev->child_bus, sibling) {
672         qbus_print(mon, child, indent);
673     }
674 }
675
676 static void qbus_print(Monitor *mon, BusState *bus, int indent)
677 {
678     BusChild *kid;
679
680     qdev_printf("bus: %s\n", bus->name);
681     indent += 2;
682     qdev_printf("type %s\n", object_get_typename(OBJECT(bus)));
683     QTAILQ_FOREACH(kid, &bus->children, sibling) {
684         DeviceState *dev = kid->child;
685         qdev_print(mon, dev, indent);
686     }
687 }
688 #undef qdev_printf
689
690 void hmp_info_qtree(Monitor *mon, const QDict *qdict)
691 {
692     if (sysbus_get_default())
693         qbus_print(mon, sysbus_get_default(), 0);
694 }
695
696 void hmp_info_qdm(Monitor *mon, const QDict *qdict)
697 {
698     qdev_print_devinfos(true);
699 }
700
701 typedef struct QOMCompositionState {
702     Monitor *mon;
703     int indent;
704 } QOMCompositionState;
705
706 static void print_qom_composition(Monitor *mon, Object *obj, int indent);
707
708 static int print_qom_composition_child(Object *obj, void *opaque)
709 {
710     QOMCompositionState *s = opaque;
711
712     print_qom_composition(s->mon, obj, s->indent);
713
714     return 0;
715 }
716
717 static void print_qom_composition(Monitor *mon, Object *obj, int indent)
718 {
719     QOMCompositionState s = {
720         .mon = mon,
721         .indent = indent + 2,
722     };
723     char *name;
724
725     if (obj == object_get_root()) {
726         name = g_strdup("");
727     } else {
728         name = object_get_canonical_path_component(obj);
729     }
730     monitor_printf(mon, "%*s/%s (%s)\n", indent, "", name,
731                    object_get_typename(obj));
732     g_free(name);
733     object_child_foreach(obj, print_qom_composition_child, &s);
734 }
735
736 void hmp_info_qom_tree(Monitor *mon, const QDict *dict)
737 {
738     const char *path = qdict_get_try_str(dict, "path");
739     Object *obj;
740     bool ambiguous = false;
741
742     if (path) {
743         obj = object_resolve_path(path, &ambiguous);
744         if (!obj) {
745             monitor_printf(mon, "Path '%s' could not be resolved.\n", path);
746             return;
747         }
748         if (ambiguous) {
749             monitor_printf(mon, "Warning: Path '%s' is ambiguous.\n", path);
750             return;
751         }
752     } else {
753         obj = qdev_get_machine();
754     }
755     print_qom_composition(mon, obj, 0);
756 }
757
758 int do_device_add(Monitor *mon, const QDict *qdict, QObject **ret_data)
759 {
760     Error *local_err = NULL;
761     QemuOpts *opts;
762     DeviceState *dev;
763
764     opts = qemu_opts_from_qdict(qemu_find_opts("device"), qdict, &local_err);
765     if (local_err) {
766         qerror_report_err(local_err);
767         error_free(local_err);
768         return -1;
769     }
770     if (!monitor_cur_is_qmp() && qdev_device_help(opts)) {
771         qemu_opts_del(opts);
772         return 0;
773     }
774     dev = qdev_device_add(opts, &local_err);
775     if (!dev) {
776         qerror_report_err(local_err);
777         error_free(local_err);
778         qemu_opts_del(opts);
779         return -1;
780     }
781     object_unref(OBJECT(dev));
782     return 0;
783 }
784
785 void qmp_device_del(const char *id, Error **errp)
786 {
787     Object *obj;
788     char *root_path = object_get_canonical_path(qdev_get_peripheral());
789     char *path = g_strdup_printf("%s/%s", root_path, id);
790
791     g_free(root_path);
792     obj = object_resolve_path_type(path, TYPE_DEVICE, NULL);
793     g_free(path);
794
795     if (!obj) {
796         error_set(errp, QERR_DEVICE_NOT_FOUND, id);
797         return;
798     }
799
800     qdev_unplug(DEVICE(obj), errp);
801 }
802
803 void qdev_machine_init(void)
804 {
805     qdev_get_peripheral_anon();
806     qdev_get_peripheral();
807 }
808
809 QemuOptsList qemu_device_opts = {
810     .name = "device",
811     .implied_opt_name = "driver",
812     .head = QTAILQ_HEAD_INITIALIZER(qemu_device_opts.head),
813     .desc = {
814         /*
815          * no elements => accept any
816          * sanity checking will happen later
817          * when setting device properties
818          */
819         { /* end of list */ }
820     },
821 };
822
823 QemuOptsList qemu_global_opts = {
824     .name = "global",
825     .head = QTAILQ_HEAD_INITIALIZER(qemu_global_opts.head),
826     .desc = {
827         {
828             .name = "driver",
829             .type = QEMU_OPT_STRING,
830         },{
831             .name = "property",
832             .type = QEMU_OPT_STRING,
833         },{
834             .name = "value",
835             .type = QEMU_OPT_STRING,
836         },
837         { /* end of list */ }
838     },
839 };
840
841 int qemu_global_option(const char *str)
842 {
843     char driver[64], property[64];
844     QemuOpts *opts;
845     int rc, offset;
846
847     rc = sscanf(str, "%63[^.=].%63[^=]%n", driver, property, &offset);
848     if (rc == 2 && str[offset] == '=') {
849         opts = qemu_opts_create(&qemu_global_opts, NULL, 0, &error_abort);
850         qemu_opt_set(opts, "driver", driver, &error_abort);
851         qemu_opt_set(opts, "property", property, &error_abort);
852         qemu_opt_set(opts, "value", str + offset + 1, &error_abort);
853         return 0;
854     }
855
856     opts = qemu_opts_parse_noisily(&qemu_global_opts, str, false);
857     if (!opts) {
858         return -1;
859     }
860
861     return 0;
862 }
This page took 0.071028 seconds and 4 git commands to generate.