]> Git Repo - qemu.git/blob - qdev-monitor.c
Merge remote-tracking branch 'remotes/awilliam/tags/vfio-update-20150609.0' into...
[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-s390", "virtio-blk", QEMU_ARCH_S390X },
46     { "virtio-net-s390", "virtio-net", QEMU_ARCH_S390X },
47     { "virtio-serial-s390", "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         qerror_report_err(err);
160         error_free(err);
161         return -1;
162     }
163     return 0;
164 }
165
166 static const char *find_typename_by_alias(const char *alias)
167 {
168     int i;
169
170     for (i = 0; qdev_alias_table[i].alias; i++) {
171         if (qdev_alias_table[i].arch_mask &&
172             !(qdev_alias_table[i].arch_mask & arch_type)) {
173             continue;
174         }
175
176         if (strcmp(qdev_alias_table[i].alias, alias) == 0) {
177             return qdev_alias_table[i].typename;
178         }
179     }
180
181     return NULL;
182 }
183
184 static DeviceClass *qdev_get_device_class(const char **driver, Error **errp)
185 {
186     ObjectClass *oc;
187     DeviceClass *dc;
188
189     oc = object_class_by_name(*driver);
190     if (!oc) {
191         const char *typename = find_typename_by_alias(*driver);
192
193         if (typename) {
194             *driver = typename;
195             oc = object_class_by_name(*driver);
196         }
197     }
198
199     if (!object_class_dynamic_cast(oc, TYPE_DEVICE)) {
200         error_setg(errp, "'%s' is not a valid device model name", *driver);
201         return NULL;
202     }
203
204     if (object_class_is_abstract(oc)) {
205         error_set(errp, QERR_INVALID_PARAMETER_VALUE, "driver",
206                   "non-abstract device type");
207         return NULL;
208     }
209
210     dc = DEVICE_CLASS(oc);
211     if (dc->cannot_instantiate_with_device_add_yet ||
212         (qdev_hotplug && !dc->hotpluggable)) {
213         error_set(errp, QERR_INVALID_PARAMETER_VALUE, "driver",
214                   "pluggable device type");
215         return NULL;
216     }
217
218     return dc;
219 }
220
221
222 int qdev_device_help(QemuOpts *opts)
223 {
224     Error *local_err = NULL;
225     const char *driver;
226     DevicePropertyInfoList *prop_list;
227     DevicePropertyInfoList *prop;
228
229     driver = qemu_opt_get(opts, "driver");
230     if (driver && is_help_option(driver)) {
231         qdev_print_devinfos(false);
232         return 1;
233     }
234
235     if (!driver || !qemu_opt_has_help_opt(opts)) {
236         return 0;
237     }
238
239     qdev_get_device_class(&driver, &local_err);
240     if (local_err) {
241         goto error;
242     }
243
244     prop_list = qmp_device_list_properties(driver, &local_err);
245     if (local_err) {
246         goto error;
247     }
248
249     for (prop = prop_list; prop; prop = prop->next) {
250         error_printf("%s.%s=%s", driver,
251                      prop->value->name,
252                      prop->value->type);
253         if (prop->value->has_description) {
254             error_printf(" (%s)\n", prop->value->description);
255         } else {
256             error_printf("\n");
257         }
258     }
259
260     qapi_free_DevicePropertyInfoList(prop_list);
261     return 1;
262
263 error:
264     error_printf("%s\n", error_get_pretty(local_err));
265     error_free(local_err);
266     return 1;
267 }
268
269 static Object *qdev_get_peripheral(void)
270 {
271     static Object *dev;
272
273     if (dev == NULL) {
274         dev = container_get(qdev_get_machine(), "/peripheral");
275     }
276
277     return dev;
278 }
279
280 static Object *qdev_get_peripheral_anon(void)
281 {
282     static Object *dev;
283
284     if (dev == NULL) {
285         dev = container_get(qdev_get_machine(), "/peripheral-anon");
286     }
287
288     return dev;
289 }
290
291 static void qbus_list_bus(DeviceState *dev)
292 {
293     BusState *child;
294     const char *sep = " ";
295
296     error_printf("child busses 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
321 static BusState *qbus_find_bus(DeviceState *dev, char *elem)
322 {
323     BusState *child;
324
325     QLIST_FOREACH(child, &dev->child_bus, sibling) {
326         if (strcmp(child->name, elem) == 0) {
327             return child;
328         }
329     }
330     return NULL;
331 }
332
333 static DeviceState *qbus_find_dev(BusState *bus, char *elem)
334 {
335     BusChild *kid;
336
337     /*
338      * try to match in order:
339      *   (1) instance id, if present
340      *   (2) driver name
341      *   (3) driver alias, if present
342      */
343     QTAILQ_FOREACH(kid, &bus->children, sibling) {
344         DeviceState *dev = kid->child;
345         if (dev->id  &&  strcmp(dev->id, elem) == 0) {
346             return dev;
347         }
348     }
349     QTAILQ_FOREACH(kid, &bus->children, sibling) {
350         DeviceState *dev = kid->child;
351         if (strcmp(object_get_typename(OBJECT(dev)), elem) == 0) {
352             return dev;
353         }
354     }
355     QTAILQ_FOREACH(kid, &bus->children, sibling) {
356         DeviceState *dev = kid->child;
357         DeviceClass *dc = DEVICE_GET_CLASS(dev);
358
359         if (qdev_class_has_alias(dc) &&
360             strcmp(qdev_class_get_alias(dc), elem) == 0) {
361             return dev;
362         }
363     }
364     return NULL;
365 }
366
367 static BusState *qbus_find_recursive(BusState *bus, const char *name,
368                                      const char *bus_typename)
369 {
370     BusClass *bus_class = BUS_GET_CLASS(bus);
371     BusChild *kid;
372     BusState *child, *ret;
373     int match = 1;
374
375     if (name && (strcmp(bus->name, name) != 0)) {
376         match = 0;
377     } else if (bus_typename && !object_dynamic_cast(OBJECT(bus), bus_typename)) {
378         match = 0;
379     } else if ((bus_class->max_dev != 0) && (bus_class->max_dev <= bus->max_index)) {
380         if (name != NULL) {
381             /* bus was explicitly specified: return an error. */
382             qerror_report(ERROR_CLASS_GENERIC_ERROR, "Bus '%s' is full",
383                           bus->name);
384             return NULL;
385         } else {
386             /* bus was not specified: try to find another one. */
387             match = 0;
388         }
389     }
390     if (match) {
391         return bus;
392     }
393
394     QTAILQ_FOREACH(kid, &bus->children, sibling) {
395         DeviceState *dev = kid->child;
396         QLIST_FOREACH(child, &dev->child_bus, sibling) {
397             ret = qbus_find_recursive(child, name, bus_typename);
398             if (ret) {
399                 return ret;
400             }
401         }
402     }
403     return NULL;
404 }
405
406 static BusState *qbus_find(const char *path)
407 {
408     DeviceState *dev;
409     BusState *bus;
410     char elem[128];
411     int pos, len;
412
413     /* find start element */
414     if (path[0] == '/') {
415         bus = sysbus_get_default();
416         pos = 0;
417     } else {
418         if (sscanf(path, "%127[^/]%n", elem, &len) != 1) {
419             assert(!path[0]);
420             elem[0] = len = 0;
421         }
422         bus = qbus_find_recursive(sysbus_get_default(), elem, NULL);
423         if (!bus) {
424             qerror_report(QERR_BUS_NOT_FOUND, elem);
425             return NULL;
426         }
427         pos = len;
428     }
429
430     for (;;) {
431         assert(path[pos] == '/' || !path[pos]);
432         while (path[pos] == '/') {
433             pos++;
434         }
435         if (path[pos] == '\0') {
436             return bus;
437         }
438
439         /* find device */
440         if (sscanf(path+pos, "%127[^/]%n", elem, &len) != 1) {
441             g_assert_not_reached();
442             elem[0] = len = 0;
443         }
444         pos += len;
445         dev = qbus_find_dev(bus, elem);
446         if (!dev) {
447             qerror_report(QERR_DEVICE_NOT_FOUND, elem);
448             if (!monitor_cur_is_qmp()) {
449                 qbus_list_dev(bus);
450             }
451             return NULL;
452         }
453
454         assert(path[pos] == '/' || !path[pos]);
455         while (path[pos] == '/') {
456             pos++;
457         }
458         if (path[pos] == '\0') {
459             /* last specified element is a device.  If it has exactly
460              * one child bus accept it nevertheless */
461             switch (dev->num_child_bus) {
462             case 0:
463                 qerror_report(ERROR_CLASS_GENERIC_ERROR,
464                               "Device '%s' has no child bus", elem);
465                 return NULL;
466             case 1:
467                 return QLIST_FIRST(&dev->child_bus);
468             default:
469                 qerror_report(ERROR_CLASS_GENERIC_ERROR,
470                               "Device '%s' has multiple child busses", elem);
471                 if (!monitor_cur_is_qmp()) {
472                     qbus_list_bus(dev);
473                 }
474                 return NULL;
475             }
476         }
477
478         /* find bus */
479         if (sscanf(path+pos, "%127[^/]%n", elem, &len) != 1) {
480             g_assert_not_reached();
481             elem[0] = len = 0;
482         }
483         pos += len;
484         bus = qbus_find_bus(dev, elem);
485         if (!bus) {
486             qerror_report(QERR_BUS_NOT_FOUND, elem);
487             if (!monitor_cur_is_qmp()) {
488                 qbus_list_bus(dev);
489             }
490             return NULL;
491         }
492     }
493 }
494
495 DeviceState *qdev_device_add(QemuOpts *opts)
496 {
497     DeviceClass *dc;
498     const char *driver, *path, *id;
499     DeviceState *dev;
500     BusState *bus = NULL;
501     Error *err = NULL;
502
503     driver = qemu_opt_get(opts, "driver");
504     if (!driver) {
505         qerror_report(QERR_MISSING_PARAMETER, "driver");
506         return NULL;
507     }
508
509     /* find driver */
510     dc = qdev_get_device_class(&driver, &err);
511     if (err) {
512         qerror_report_err(err);
513         error_free(err);
514         return NULL;
515     }
516
517     /* find bus */
518     path = qemu_opt_get(opts, "bus");
519     if (path != NULL) {
520         bus = qbus_find(path);
521         if (!bus) {
522             return NULL;
523         }
524         if (!object_dynamic_cast(OBJECT(bus), dc->bus_type)) {
525             qerror_report(ERROR_CLASS_GENERIC_ERROR,
526                           "Device '%s' can't go on a %s bus",
527                           driver, object_get_typename(OBJECT(bus)));
528             return NULL;
529         }
530     } else if (dc->bus_type != NULL) {
531         bus = qbus_find_recursive(sysbus_get_default(), NULL, dc->bus_type);
532         if (!bus) {
533             qerror_report(ERROR_CLASS_GENERIC_ERROR,
534                           "No '%s' bus found for device '%s'",
535                           dc->bus_type, driver);
536             return NULL;
537         }
538     }
539     if (qdev_hotplug && bus && !qbus_is_hotpluggable(bus)) {
540         qerror_report(QERR_BUS_NO_HOTPLUG, bus->name);
541         return NULL;
542     }
543
544     /* create device */
545     dev = DEVICE(object_new(driver));
546
547     if (bus) {
548         qdev_set_parent_bus(dev, bus);
549     }
550
551     id = qemu_opts_id(opts);
552     if (id) {
553         dev->id = id;
554     }
555
556     if (dev->id) {
557         object_property_add_child(qdev_get_peripheral(), dev->id,
558                                   OBJECT(dev), NULL);
559     } else {
560         static int anon_count;
561         gchar *name = g_strdup_printf("device[%d]", anon_count++);
562         object_property_add_child(qdev_get_peripheral_anon(), name,
563                                   OBJECT(dev), NULL);
564         g_free(name);
565     }
566
567     /* set properties */
568     if (qemu_opt_foreach(opts, set_property, dev, NULL)) {
569         object_unparent(OBJECT(dev));
570         object_unref(OBJECT(dev));
571         return NULL;
572     }
573
574     dev->opts = opts;
575     object_property_set_bool(OBJECT(dev), true, "realized", &err);
576     if (err != NULL) {
577         qerror_report_err(err);
578         error_free(err);
579         dev->opts = NULL;
580         object_unparent(OBJECT(dev));
581         object_unref(OBJECT(dev));
582         qerror_report(QERR_DEVICE_INIT_FAILED, driver);
583         return NULL;
584     }
585     return dev;
586 }
587
588
589 #define qdev_printf(fmt, ...) monitor_printf(mon, "%*s" fmt, indent, "", ## __VA_ARGS__)
590 static void qbus_print(Monitor *mon, BusState *bus, int indent);
591
592 static void qdev_print_props(Monitor *mon, DeviceState *dev, Property *props,
593                              int indent)
594 {
595     if (!props)
596         return;
597     for (; props->name; props++) {
598         Error *err = NULL;
599         char *value;
600         char *legacy_name = g_strdup_printf("legacy-%s", props->name);
601         if (object_property_get_type(OBJECT(dev), legacy_name, NULL)) {
602             value = object_property_get_str(OBJECT(dev), legacy_name, &err);
603         } else {
604             value = object_property_print(OBJECT(dev), props->name, true, &err);
605         }
606         g_free(legacy_name);
607
608         if (err) {
609             error_free(err);
610             continue;
611         }
612         qdev_printf("%s = %s\n", props->name,
613                     value && *value ? value : "<null>");
614         g_free(value);
615     }
616 }
617
618 static void bus_print_dev(BusState *bus, Monitor *mon, DeviceState *dev, int indent)
619 {
620     BusClass *bc = BUS_GET_CLASS(bus);
621
622     if (bc->print_dev) {
623         bc->print_dev(mon, dev, indent);
624     }
625 }
626
627 static void qdev_print(Monitor *mon, DeviceState *dev, int indent)
628 {
629     ObjectClass *class;
630     BusState *child;
631     NamedGPIOList *ngl;
632
633     qdev_printf("dev: %s, id \"%s\"\n", object_get_typename(OBJECT(dev)),
634                 dev->id ? dev->id : "");
635     indent += 2;
636     QLIST_FOREACH(ngl, &dev->gpios, node) {
637         if (ngl->num_in) {
638             qdev_printf("gpio-in \"%s\" %d\n", ngl->name ? ngl->name : "",
639                         ngl->num_in);
640         }
641         if (ngl->num_out) {
642             qdev_printf("gpio-out \"%s\" %d\n", ngl->name ? ngl->name : "",
643                         ngl->num_out);
644         }
645     }
646     class = object_get_class(OBJECT(dev));
647     do {
648         qdev_print_props(mon, dev, DEVICE_CLASS(class)->props, indent);
649         class = object_class_get_parent(class);
650     } while (class != object_class_by_name(TYPE_DEVICE));
651     bus_print_dev(dev->parent_bus, mon, dev, indent);
652     QLIST_FOREACH(child, &dev->child_bus, sibling) {
653         qbus_print(mon, child, indent);
654     }
655 }
656
657 static void qbus_print(Monitor *mon, BusState *bus, int indent)
658 {
659     BusChild *kid;
660
661     qdev_printf("bus: %s\n", bus->name);
662     indent += 2;
663     qdev_printf("type %s\n", object_get_typename(OBJECT(bus)));
664     QTAILQ_FOREACH(kid, &bus->children, sibling) {
665         DeviceState *dev = kid->child;
666         qdev_print(mon, dev, indent);
667     }
668 }
669 #undef qdev_printf
670
671 void hmp_info_qtree(Monitor *mon, const QDict *qdict)
672 {
673     if (sysbus_get_default())
674         qbus_print(mon, sysbus_get_default(), 0);
675 }
676
677 void hmp_info_qdm(Monitor *mon, const QDict *qdict)
678 {
679     qdev_print_devinfos(true);
680 }
681
682 typedef struct QOMCompositionState {
683     Monitor *mon;
684     int indent;
685 } QOMCompositionState;
686
687 static void print_qom_composition(Monitor *mon, Object *obj, int indent);
688
689 static int print_qom_composition_child(Object *obj, void *opaque)
690 {
691     QOMCompositionState *s = opaque;
692
693     print_qom_composition(s->mon, obj, s->indent);
694
695     return 0;
696 }
697
698 static void print_qom_composition(Monitor *mon, Object *obj, int indent)
699 {
700     QOMCompositionState s = {
701         .mon = mon,
702         .indent = indent + 2,
703     };
704     char *name;
705
706     if (obj == object_get_root()) {
707         name = g_strdup("");
708     } else {
709         name = object_get_canonical_path_component(obj);
710     }
711     monitor_printf(mon, "%*s/%s (%s)\n", indent, "", name,
712                    object_get_typename(obj));
713     g_free(name);
714     object_child_foreach(obj, print_qom_composition_child, &s);
715 }
716
717 void hmp_info_qom_tree(Monitor *mon, const QDict *dict)
718 {
719     const char *path = qdict_get_try_str(dict, "path");
720     Object *obj;
721     bool ambiguous = false;
722
723     if (path) {
724         obj = object_resolve_path(path, &ambiguous);
725         if (!obj) {
726             monitor_printf(mon, "Path '%s' could not be resolved.\n", path);
727             return;
728         }
729         if (ambiguous) {
730             monitor_printf(mon, "Warning: Path '%s' is ambiguous.\n", path);
731             return;
732         }
733     } else {
734         obj = qdev_get_machine();
735     }
736     print_qom_composition(mon, obj, 0);
737 }
738
739 int do_device_add(Monitor *mon, const QDict *qdict, QObject **ret_data)
740 {
741     Error *local_err = NULL;
742     QemuOpts *opts;
743     DeviceState *dev;
744
745     opts = qemu_opts_from_qdict(qemu_find_opts("device"), qdict, &local_err);
746     if (local_err) {
747         qerror_report_err(local_err);
748         error_free(local_err);
749         return -1;
750     }
751     if (!monitor_cur_is_qmp() && qdev_device_help(opts)) {
752         qemu_opts_del(opts);
753         return 0;
754     }
755     dev = qdev_device_add(opts);
756     if (!dev) {
757         qemu_opts_del(opts);
758         return -1;
759     }
760     object_unref(OBJECT(dev));
761     return 0;
762 }
763
764 void qmp_device_del(const char *id, Error **errp)
765 {
766     Object *obj;
767     char *root_path = object_get_canonical_path(qdev_get_peripheral());
768     char *path = g_strdup_printf("%s/%s", root_path, id);
769
770     g_free(root_path);
771     obj = object_resolve_path_type(path, TYPE_DEVICE, NULL);
772     g_free(path);
773
774     if (!obj) {
775         error_set(errp, QERR_DEVICE_NOT_FOUND, id);
776         return;
777     }
778
779     qdev_unplug(DEVICE(obj), errp);
780 }
781
782 void qdev_machine_init(void)
783 {
784     qdev_get_peripheral_anon();
785     qdev_get_peripheral();
786 }
787
788 QemuOptsList qemu_device_opts = {
789     .name = "device",
790     .implied_opt_name = "driver",
791     .head = QTAILQ_HEAD_INITIALIZER(qemu_device_opts.head),
792     .desc = {
793         /*
794          * no elements => accept any
795          * sanity checking will happen later
796          * when setting device properties
797          */
798         { /* end of list */ }
799     },
800 };
801
802 QemuOptsList qemu_global_opts = {
803     .name = "global",
804     .head = QTAILQ_HEAD_INITIALIZER(qemu_global_opts.head),
805     .desc = {
806         {
807             .name = "driver",
808             .type = QEMU_OPT_STRING,
809         },{
810             .name = "property",
811             .type = QEMU_OPT_STRING,
812         },{
813             .name = "value",
814             .type = QEMU_OPT_STRING,
815         },
816         { /* end of list */ }
817     },
818 };
819
820 int qemu_global_option(const char *str)
821 {
822     char driver[64], property[64];
823     QemuOpts *opts;
824     int rc, offset;
825
826     rc = sscanf(str, "%63[^.=].%63[^=]%n", driver, property, &offset);
827     if (rc == 2 && str[offset] == '=') {
828         opts = qemu_opts_create(&qemu_global_opts, NULL, 0, &error_abort);
829         qemu_opt_set(opts, "driver", driver, &error_abort);
830         qemu_opt_set(opts, "property", property, &error_abort);
831         qemu_opt_set(opts, "value", str + offset + 1, &error_abort);
832         return 0;
833     }
834
835     opts = qemu_opts_parse(&qemu_global_opts, str, false);
836     if (!opts) {
837         return -1;
838     }
839
840     return 0;
841 }
This page took 0.068978 seconds and 4 git commands to generate.