qdev-monitor.c 18 KB

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