OSDN Git Service

qemu-img.texi: Clean up parameter list
[qmiga/qemu.git] / qmp.c
1 /*
2  * QEMU Management Protocol
3  *
4  * Copyright IBM, Corp. 2011
5  *
6  * Authors:
7  *  Anthony Liguori   <aliguori@us.ibm.com>
8  *
9  * This work is licensed under the terms of the GNU GPL, version 2.  See
10  * the COPYING file in the top-level directory.
11  *
12  * Contributions after 2012-01-13 are licensed under the terms of the
13  * GNU GPL, version 2 or (at your option) any later version.
14  */
15
16 #include "qemu/osdep.h"
17 #include "qemu-version.h"
18 #include "qemu/cutils.h"
19 #include "qemu/option.h"
20 #include "monitor/monitor.h"
21 #include "sysemu/sysemu.h"
22 #include "qemu/config-file.h"
23 #include "qemu/uuid.h"
24 #include "qmp-commands.h"
25 #include "chardev/char.h"
26 #include "ui/qemu-spice.h"
27 #include "ui/vnc.h"
28 #include "sysemu/kvm.h"
29 #include "sysemu/arch_init.h"
30 #include "hw/qdev.h"
31 #include "sysemu/blockdev.h"
32 #include "sysemu/block-backend.h"
33 #include "qom/qom-qobject.h"
34 #include "qapi/error.h"
35 #include "qapi/qmp/qdict.h"
36 #include "qapi/qmp/qerror.h"
37 #include "qapi/qobject-input-visitor.h"
38 #include "hw/boards.h"
39 #include "qom/object_interfaces.h"
40 #include "hw/mem/pc-dimm.h"
41 #include "hw/acpi/acpi_dev_interface.h"
42
43 NameInfo *qmp_query_name(Error **errp)
44 {
45     NameInfo *info = g_malloc0(sizeof(*info));
46
47     if (qemu_name) {
48         info->has_name = true;
49         info->name = g_strdup(qemu_name);
50     }
51
52     return info;
53 }
54
55 VersionInfo *qmp_query_version(Error **errp)
56 {
57     VersionInfo *info = g_new0(VersionInfo, 1);
58
59     info->qemu = g_new0(VersionTriple, 1);
60     info->qemu->major = QEMU_VERSION_MAJOR;
61     info->qemu->minor = QEMU_VERSION_MINOR;
62     info->qemu->micro = QEMU_VERSION_MICRO;
63     info->package = g_strdup(QEMU_PKGVERSION);
64
65     return info;
66 }
67
68 KvmInfo *qmp_query_kvm(Error **errp)
69 {
70     KvmInfo *info = g_malloc0(sizeof(*info));
71
72     info->enabled = kvm_enabled();
73     info->present = kvm_available();
74
75     return info;
76 }
77
78 UuidInfo *qmp_query_uuid(Error **errp)
79 {
80     UuidInfo *info = g_malloc0(sizeof(*info));
81
82     info->UUID = qemu_uuid_unparse_strdup(&qemu_uuid);
83     return info;
84 }
85
86 void qmp_quit(Error **errp)
87 {
88     no_shutdown = 0;
89     qemu_system_shutdown_request(SHUTDOWN_CAUSE_HOST_QMP);
90 }
91
92 void qmp_stop(Error **errp)
93 {
94     /* if there is a dump in background, we should wait until the dump
95      * finished */
96     if (dump_in_progress()) {
97         error_setg(errp, "There is a dump in process, please wait.");
98         return;
99     }
100
101     if (runstate_check(RUN_STATE_INMIGRATE)) {
102         autostart = 0;
103     } else {
104         vm_stop(RUN_STATE_PAUSED);
105     }
106 }
107
108 void qmp_system_reset(Error **errp)
109 {
110     qemu_system_reset_request(SHUTDOWN_CAUSE_HOST_QMP);
111 }
112
113 void qmp_system_powerdown(Error **erp)
114 {
115     qemu_system_powerdown_request();
116 }
117
118 void qmp_cpu_add(int64_t id, Error **errp)
119 {
120     MachineClass *mc;
121
122     mc = MACHINE_GET_CLASS(current_machine);
123     if (mc->hot_add_cpu) {
124         mc->hot_add_cpu(id, errp);
125     } else {
126         error_setg(errp, "Not supported");
127     }
128 }
129
130 #ifndef CONFIG_VNC
131 /* If VNC support is enabled, the "true" query-vnc command is
132    defined in the VNC subsystem */
133 VncInfo *qmp_query_vnc(Error **errp)
134 {
135     error_setg(errp, QERR_FEATURE_DISABLED, "vnc");
136     return NULL;
137 };
138
139 VncInfo2List *qmp_query_vnc_servers(Error **errp)
140 {
141     error_setg(errp, QERR_FEATURE_DISABLED, "vnc");
142     return NULL;
143 };
144 #endif
145
146 #ifndef CONFIG_SPICE
147 /*
148  * qmp-commands.hx ensures that QMP command query-spice exists only
149  * #ifdef CONFIG_SPICE.  Necessary for an accurate query-commands
150  * result.  However, the QAPI schema is blissfully unaware of that,
151  * and the QAPI code generator happily generates a dead
152  * qmp_marshal_query_spice() that calls qmp_query_spice().  Provide it
153  * one, or else linking fails.  FIXME Educate the QAPI schema on
154  * CONFIG_SPICE.
155  */
156 SpiceInfo *qmp_query_spice(Error **errp)
157 {
158     abort();
159 };
160 #endif
161
162 void qmp_cont(Error **errp)
163 {
164     BlockBackend *blk;
165     Error *local_err = NULL;
166
167     /* if there is a dump in background, we should wait until the dump
168      * finished */
169     if (dump_in_progress()) {
170         error_setg(errp, "There is a dump in process, please wait.");
171         return;
172     }
173
174     if (runstate_needs_reset()) {
175         error_setg(errp, "Resetting the Virtual Machine is required");
176         return;
177     } else if (runstate_check(RUN_STATE_SUSPENDED)) {
178         return;
179     }
180
181     for (blk = blk_next(NULL); blk; blk = blk_next(blk)) {
182         blk_iostatus_reset(blk);
183     }
184
185     /* Continuing after completed migration. Images have been inactivated to
186      * allow the destination to take control. Need to get control back now.
187      *
188      * If there are no inactive block nodes (e.g. because the VM was just
189      * paused rather than completing a migration), bdrv_inactivate_all() simply
190      * doesn't do anything. */
191     bdrv_invalidate_cache_all(&local_err);
192     if (local_err) {
193         error_propagate(errp, local_err);
194         return;
195     }
196
197     if (runstate_check(RUN_STATE_INMIGRATE)) {
198         autostart = 1;
199     } else {
200         vm_start();
201     }
202 }
203
204 void qmp_system_wakeup(Error **errp)
205 {
206     qemu_system_wakeup_request(QEMU_WAKEUP_REASON_OTHER);
207 }
208
209 ObjectPropertyInfoList *qmp_qom_list(const char *path, Error **errp)
210 {
211     Object *obj;
212     bool ambiguous = false;
213     ObjectPropertyInfoList *props = NULL;
214     ObjectProperty *prop;
215     ObjectPropertyIterator iter;
216
217     obj = object_resolve_path(path, &ambiguous);
218     if (obj == NULL) {
219         if (ambiguous) {
220             error_setg(errp, "Path '%s' is ambiguous", path);
221         } else {
222             error_set(errp, ERROR_CLASS_DEVICE_NOT_FOUND,
223                       "Device '%s' not found", path);
224         }
225         return NULL;
226     }
227
228     object_property_iter_init(&iter, obj);
229     while ((prop = object_property_iter_next(&iter))) {
230         ObjectPropertyInfoList *entry = g_malloc0(sizeof(*entry));
231
232         entry->value = g_malloc0(sizeof(ObjectPropertyInfo));
233         entry->next = props;
234         props = entry;
235
236         entry->value->name = g_strdup(prop->name);
237         entry->value->type = g_strdup(prop->type);
238     }
239
240     return props;
241 }
242
243 void qmp_qom_set(const char *path, const char *property, QObject *value,
244                  Error **errp)
245 {
246     Object *obj;
247
248     obj = object_resolve_path(path, NULL);
249     if (!obj) {
250         error_set(errp, ERROR_CLASS_DEVICE_NOT_FOUND,
251                   "Device '%s' not found", path);
252         return;
253     }
254
255     object_property_set_qobject(obj, value, property, errp);
256 }
257
258 QObject *qmp_qom_get(const char *path, const char *property, Error **errp)
259 {
260     Object *obj;
261
262     obj = object_resolve_path(path, NULL);
263     if (!obj) {
264         error_set(errp, ERROR_CLASS_DEVICE_NOT_FOUND,
265                   "Device '%s' not found", path);
266         return NULL;
267     }
268
269     return object_property_get_qobject(obj, property, errp);
270 }
271
272 void qmp_set_password(const char *protocol, const char *password,
273                       bool has_connected, const char *connected, Error **errp)
274 {
275     int disconnect_if_connected = 0;
276     int fail_if_connected = 0;
277     int rc;
278
279     if (has_connected) {
280         if (strcmp(connected, "fail") == 0) {
281             fail_if_connected = 1;
282         } else if (strcmp(connected, "disconnect") == 0) {
283             disconnect_if_connected = 1;
284         } else if (strcmp(connected, "keep") == 0) {
285             /* nothing */
286         } else {
287             error_setg(errp, QERR_INVALID_PARAMETER, "connected");
288             return;
289         }
290     }
291
292     if (strcmp(protocol, "spice") == 0) {
293         if (!qemu_using_spice(errp)) {
294             return;
295         }
296         rc = qemu_spice_set_passwd(password, fail_if_connected,
297                                    disconnect_if_connected);
298         if (rc != 0) {
299             error_setg(errp, QERR_SET_PASSWD_FAILED);
300         }
301         return;
302     }
303
304     if (strcmp(protocol, "vnc") == 0) {
305         if (fail_if_connected || disconnect_if_connected) {
306             /* vnc supports "connected=keep" only */
307             error_setg(errp, QERR_INVALID_PARAMETER, "connected");
308             return;
309         }
310         /* Note that setting an empty password will not disable login through
311          * this interface. */
312         rc = vnc_display_password(NULL, password);
313         if (rc < 0) {
314             error_setg(errp, QERR_SET_PASSWD_FAILED);
315         }
316         return;
317     }
318
319     error_setg(errp, QERR_INVALID_PARAMETER, "protocol");
320 }
321
322 void qmp_expire_password(const char *protocol, const char *whenstr,
323                          Error **errp)
324 {
325     time_t when;
326     int rc;
327
328     if (strcmp(whenstr, "now") == 0) {
329         when = 0;
330     } else if (strcmp(whenstr, "never") == 0) {
331         when = TIME_MAX;
332     } else if (whenstr[0] == '+') {
333         when = time(NULL) + strtoull(whenstr+1, NULL, 10);
334     } else {
335         when = strtoull(whenstr, NULL, 10);
336     }
337
338     if (strcmp(protocol, "spice") == 0) {
339         if (!qemu_using_spice(errp)) {
340             return;
341         }
342         rc = qemu_spice_set_pw_expire(when);
343         if (rc != 0) {
344             error_setg(errp, QERR_SET_PASSWD_FAILED);
345         }
346         return;
347     }
348
349     if (strcmp(protocol, "vnc") == 0) {
350         rc = vnc_display_pw_expire(NULL, when);
351         if (rc != 0) {
352             error_setg(errp, QERR_SET_PASSWD_FAILED);
353         }
354         return;
355     }
356
357     error_setg(errp, QERR_INVALID_PARAMETER, "protocol");
358 }
359
360 #ifdef CONFIG_VNC
361 void qmp_change_vnc_password(const char *password, Error **errp)
362 {
363     if (vnc_display_password(NULL, password) < 0) {
364         error_setg(errp, QERR_SET_PASSWD_FAILED);
365     }
366 }
367
368 static void qmp_change_vnc_listen(const char *target, Error **errp)
369 {
370     QemuOptsList *olist = qemu_find_opts("vnc");
371     QemuOpts *opts;
372
373     if (strstr(target, "id=")) {
374         error_setg(errp, "id not supported");
375         return;
376     }
377
378     opts = qemu_opts_find(olist, "default");
379     if (opts) {
380         qemu_opts_del(opts);
381     }
382     opts = vnc_parse(target, errp);
383     if (!opts) {
384         return;
385     }
386
387     vnc_display_open("default", errp);
388 }
389
390 static void qmp_change_vnc(const char *target, bool has_arg, const char *arg,
391                            Error **errp)
392 {
393     if (strcmp(target, "passwd") == 0 || strcmp(target, "password") == 0) {
394         if (!has_arg) {
395             error_setg(errp, QERR_MISSING_PARAMETER, "password");
396         } else {
397             qmp_change_vnc_password(arg, errp);
398         }
399     } else {
400         qmp_change_vnc_listen(target, errp);
401     }
402 }
403 #else
404 void qmp_change_vnc_password(const char *password, Error **errp)
405 {
406     error_setg(errp, QERR_FEATURE_DISABLED, "vnc");
407 }
408 static void qmp_change_vnc(const char *target, bool has_arg, const char *arg,
409                            Error **errp)
410 {
411     error_setg(errp, QERR_FEATURE_DISABLED, "vnc");
412 }
413 #endif /* !CONFIG_VNC */
414
415 void qmp_change(const char *device, const char *target,
416                 bool has_arg, const char *arg, Error **errp)
417 {
418     if (strcmp(device, "vnc") == 0) {
419         qmp_change_vnc(target, has_arg, arg, errp);
420     } else {
421         qmp_blockdev_change_medium(true, device, false, NULL, target,
422                                    has_arg, arg, false, 0, errp);
423     }
424 }
425
426 static void qom_list_types_tramp(ObjectClass *klass, void *data)
427 {
428     ObjectTypeInfoList *e, **pret = data;
429     ObjectTypeInfo *info;
430     ObjectClass *parent = object_class_get_parent(klass);
431
432     info = g_malloc0(sizeof(*info));
433     info->name = g_strdup(object_class_get_name(klass));
434     info->has_abstract = info->abstract = object_class_is_abstract(klass);
435     if (parent) {
436         info->has_parent = true;
437         info->parent = g_strdup(object_class_get_name(parent));
438     }
439
440     e = g_malloc0(sizeof(*e));
441     e->value = info;
442     e->next = *pret;
443     *pret = e;
444 }
445
446 ObjectTypeInfoList *qmp_qom_list_types(bool has_implements,
447                                        const char *implements,
448                                        bool has_abstract,
449                                        bool abstract,
450                                        Error **errp)
451 {
452     ObjectTypeInfoList *ret = NULL;
453
454     object_class_foreach(qom_list_types_tramp, implements, abstract, &ret);
455
456     return ret;
457 }
458
459 /* Return a DevicePropertyInfo for a qdev property.
460  *
461  * If a qdev property with the given name does not exist, use the given default
462  * type.  If the qdev property info should not be shown, return NULL.
463  *
464  * The caller must free the return value.
465  */
466 static DevicePropertyInfo *make_device_property_info(ObjectClass *klass,
467                                                      const char *name,
468                                                      const char *default_type,
469                                                      const char *description)
470 {
471     DevicePropertyInfo *info;
472     Property *prop;
473
474     do {
475         for (prop = DEVICE_CLASS(klass)->props; prop && prop->name; prop++) {
476             if (strcmp(name, prop->name) != 0) {
477                 continue;
478             }
479
480             /*
481              * TODO Properties without a parser are just for dirty hacks.
482              * qdev_prop_ptr is the only such PropertyInfo.  It's marked
483              * for removal.  This conditional should be removed along with
484              * it.
485              */
486             if (!prop->info->set && !prop->info->create) {
487                 return NULL;           /* no way to set it, don't show */
488             }
489
490             info = g_malloc0(sizeof(*info));
491             info->name = g_strdup(prop->name);
492             info->type = default_type ? g_strdup(default_type)
493                                       : g_strdup(prop->info->name);
494             info->has_description = !!prop->info->description;
495             info->description = g_strdup(prop->info->description);
496             return info;
497         }
498         klass = object_class_get_parent(klass);
499     } while (klass != object_class_by_name(TYPE_DEVICE));
500
501     /* Not a qdev property, use the default type */
502     info = g_malloc0(sizeof(*info));
503     info->name = g_strdup(name);
504     info->type = g_strdup(default_type);
505     info->has_description = !!description;
506     info->description = g_strdup(description);
507
508     return info;
509 }
510
511 DevicePropertyInfoList *qmp_device_list_properties(const char *typename,
512                                                    Error **errp)
513 {
514     ObjectClass *klass;
515     Object *obj;
516     ObjectProperty *prop;
517     ObjectPropertyIterator iter;
518     DevicePropertyInfoList *prop_list = NULL;
519
520     klass = object_class_by_name(typename);
521     if (klass == NULL) {
522         error_set(errp, ERROR_CLASS_DEVICE_NOT_FOUND,
523                   "Device '%s' not found", typename);
524         return NULL;
525     }
526
527     klass = object_class_dynamic_cast(klass, TYPE_DEVICE);
528     if (klass == NULL) {
529         error_setg(errp, QERR_INVALID_PARAMETER_VALUE, "typename", TYPE_DEVICE);
530         return NULL;
531     }
532
533     if (object_class_is_abstract(klass)) {
534         error_setg(errp, QERR_INVALID_PARAMETER_VALUE, "typename",
535                    "non-abstract device type");
536         return NULL;
537     }
538
539     obj = object_new(typename);
540
541     object_property_iter_init(&iter, obj);
542     while ((prop = object_property_iter_next(&iter))) {
543         DevicePropertyInfo *info;
544         DevicePropertyInfoList *entry;
545
546         /* Skip Object and DeviceState properties */
547         if (strcmp(prop->name, "type") == 0 ||
548             strcmp(prop->name, "realized") == 0 ||
549             strcmp(prop->name, "hotpluggable") == 0 ||
550             strcmp(prop->name, "hotplugged") == 0 ||
551             strcmp(prop->name, "parent_bus") == 0) {
552             continue;
553         }
554
555         /* Skip legacy properties since they are just string versions of
556          * properties that we already list.
557          */
558         if (strstart(prop->name, "legacy-", NULL)) {
559             continue;
560         }
561
562         info = make_device_property_info(klass, prop->name, prop->type,
563                                          prop->description);
564         if (!info) {
565             continue;
566         }
567
568         entry = g_malloc0(sizeof(*entry));
569         entry->value = info;
570         entry->next = prop_list;
571         prop_list = entry;
572     }
573
574     object_unref(obj);
575
576     return prop_list;
577 }
578
579 CpuDefinitionInfoList *qmp_query_cpu_definitions(Error **errp)
580 {
581     return arch_query_cpu_definitions(errp);
582 }
583
584 CpuModelExpansionInfo *qmp_query_cpu_model_expansion(CpuModelExpansionType type,
585                                                      CpuModelInfo *model,
586                                                      Error **errp)
587 {
588     return arch_query_cpu_model_expansion(type, model, errp);
589 }
590
591 CpuModelCompareInfo *qmp_query_cpu_model_comparison(CpuModelInfo *modela,
592                                                     CpuModelInfo *modelb,
593                                                     Error **errp)
594 {
595     return arch_query_cpu_model_comparison(modela, modelb, errp);
596 }
597
598 CpuModelBaselineInfo *qmp_query_cpu_model_baseline(CpuModelInfo *modela,
599                                                    CpuModelInfo *modelb,
600                                                    Error **errp)
601 {
602     return arch_query_cpu_model_baseline(modela, modelb, errp);
603 }
604
605 void qmp_add_client(const char *protocol, const char *fdname,
606                     bool has_skipauth, bool skipauth, bool has_tls, bool tls,
607                     Error **errp)
608 {
609     Chardev *s;
610     int fd;
611
612     fd = monitor_get_fd(cur_mon, fdname, errp);
613     if (fd < 0) {
614         return;
615     }
616
617     if (strcmp(protocol, "spice") == 0) {
618         if (!qemu_using_spice(errp)) {
619             close(fd);
620             return;
621         }
622         skipauth = has_skipauth ? skipauth : false;
623         tls = has_tls ? tls : false;
624         if (qemu_spice_display_add_client(fd, skipauth, tls) < 0) {
625             error_setg(errp, "spice failed to add client");
626             close(fd);
627         }
628         return;
629 #ifdef CONFIG_VNC
630     } else if (strcmp(protocol, "vnc") == 0) {
631         skipauth = has_skipauth ? skipauth : false;
632         vnc_display_add_client(NULL, fd, skipauth);
633         return;
634 #endif
635     } else if ((s = qemu_chr_find(protocol)) != NULL) {
636         if (qemu_chr_add_client(s, fd) < 0) {
637             error_setg(errp, "failed to add client");
638             close(fd);
639             return;
640         }
641         return;
642     }
643
644     error_setg(errp, "protocol '%s' is invalid", protocol);
645     close(fd);
646 }
647
648
649 void qmp_object_add(const char *type, const char *id,
650                     bool has_props, QObject *props, Error **errp)
651 {
652     QDict *pdict;
653     Visitor *v;
654     Object *obj;
655
656     if (props) {
657         pdict = qobject_to_qdict(props);
658         if (!pdict) {
659             error_setg(errp, QERR_INVALID_PARAMETER_TYPE, "props", "dict");
660             return;
661         }
662         QINCREF(pdict);
663     } else {
664         pdict = qdict_new();
665     }
666
667     v = qobject_input_visitor_new(QOBJECT(pdict));
668     obj = user_creatable_add_type(type, id, pdict, v, errp);
669     visit_free(v);
670     if (obj) {
671         object_unref(obj);
672     }
673     QDECREF(pdict);
674 }
675
676 void qmp_object_del(const char *id, Error **errp)
677 {
678     user_creatable_del(id, errp);
679 }
680
681 MemoryDeviceInfoList *qmp_query_memory_devices(Error **errp)
682 {
683     MemoryDeviceInfoList *head = NULL;
684     MemoryDeviceInfoList **prev = &head;
685
686     qmp_pc_dimm_device_list(qdev_get_machine(), &prev);
687
688     return head;
689 }
690
691 ACPIOSTInfoList *qmp_query_acpi_ospm_status(Error **errp)
692 {
693     bool ambig;
694     ACPIOSTInfoList *head = NULL;
695     ACPIOSTInfoList **prev = &head;
696     Object *obj = object_resolve_path_type("", TYPE_ACPI_DEVICE_IF, &ambig);
697
698     if (obj) {
699         AcpiDeviceIfClass *adevc = ACPI_DEVICE_IF_GET_CLASS(obj);
700         AcpiDeviceIf *adev = ACPI_DEVICE_IF(obj);
701
702         adevc->ospm_status(adev, &prev);
703     } else {
704         error_setg(errp, "command is not supported, missing ACPI device");
705     }
706
707     return head;
708 }
709
710 MemoryInfo *qmp_query_memory_size_summary(Error **errp)
711 {
712     MemoryInfo *mem_info = g_malloc0(sizeof(MemoryInfo));
713
714     mem_info->base_memory = ram_size;
715
716     mem_info->plugged_memory = get_plugged_memory_size();
717     mem_info->has_plugged_memory =
718         mem_info->plugged_memory != (uint64_t)-1;
719
720     return mem_info;
721 }