1 /* 2 * Human Monitor Interface commands 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 "monitor/hmp.h" 18 #include "qemu/help_option.h" 19 #include "monitor/monitor.h" 20 #include "qapi/error.h" 21 #include "qapi/qapi-commands-control.h" 22 #include "qapi/qapi-commands-misc.h" 23 #include "qapi/qmp/qdict.h" 24 #include "qapi/qmp/qerror.h" 25 #include "qemu/cutils.h" 26 #include "hw/intc/intc.h" 27 28 bool hmp_handle_error(Monitor *mon, Error *err) 29 { 30 if (err) { 31 error_reportf_err(err, "Error: "); 32 return true; 33 } 34 return false; 35 } 36 37 /* 38 * Split @str at comma. 39 * A null @str defaults to "". 40 */ 41 strList *hmp_split_at_comma(const char *str) 42 { 43 char **split = g_strsplit(str ?: "", ",", -1); 44 strList *res = NULL; 45 strList **tail = &res; 46 int i; 47 48 for (i = 0; split[i]; i++) { 49 QAPI_LIST_APPEND(tail, split[i]); 50 } 51 52 g_free(split); 53 return res; 54 } 55 56 void hmp_info_name(Monitor *mon, const QDict *qdict) 57 { 58 NameInfo *info; 59 60 info = qmp_query_name(NULL); 61 if (info->name) { 62 monitor_printf(mon, "%s\n", info->name); 63 } 64 qapi_free_NameInfo(info); 65 } 66 67 void hmp_info_version(Monitor *mon, const QDict *qdict) 68 { 69 VersionInfo *info; 70 71 info = qmp_query_version(NULL); 72 73 monitor_printf(mon, "%" PRId64 ".%" PRId64 ".%" PRId64 "%s\n", 74 info->qemu->major, info->qemu->minor, info->qemu->micro, 75 info->package); 76 77 qapi_free_VersionInfo(info); 78 } 79 80 static int hmp_info_pic_foreach(Object *obj, void *opaque) 81 { 82 InterruptStatsProvider *intc; 83 InterruptStatsProviderClass *k; 84 Monitor *mon = opaque; 85 86 if (object_dynamic_cast(obj, TYPE_INTERRUPT_STATS_PROVIDER)) { 87 intc = INTERRUPT_STATS_PROVIDER(obj); 88 k = INTERRUPT_STATS_PROVIDER_GET_CLASS(obj); 89 if (k->print_info) { 90 k->print_info(intc, mon); 91 } else { 92 monitor_printf(mon, "Interrupt controller information not available for %s.\n", 93 object_get_typename(obj)); 94 } 95 } 96 97 return 0; 98 } 99 100 void hmp_info_pic(Monitor *mon, const QDict *qdict) 101 { 102 object_child_foreach_recursive(object_get_root(), 103 hmp_info_pic_foreach, mon); 104 } 105 106 void hmp_quit(Monitor *mon, const QDict *qdict) 107 { 108 monitor_suspend(mon); 109 qmp_quit(NULL); 110 } 111 112 void hmp_stop(Monitor *mon, const QDict *qdict) 113 { 114 qmp_stop(NULL); 115 } 116 117 void hmp_sync_profile(Monitor *mon, const QDict *qdict) 118 { 119 const char *op = qdict_get_try_str(qdict, "op"); 120 121 if (op == NULL) { 122 bool on = qsp_is_enabled(); 123 124 monitor_printf(mon, "sync-profile is %s\n", on ? "on" : "off"); 125 return; 126 } 127 if (!strcmp(op, "on")) { 128 qsp_enable(); 129 } else if (!strcmp(op, "off")) { 130 qsp_disable(); 131 } else if (!strcmp(op, "reset")) { 132 qsp_reset(); 133 } else { 134 Error *err = NULL; 135 136 error_setg(&err, QERR_INVALID_PARAMETER, op); 137 hmp_handle_error(mon, err); 138 } 139 } 140 141 void hmp_exit_preconfig(Monitor *mon, const QDict *qdict) 142 { 143 Error *err = NULL; 144 145 qmp_x_exit_preconfig(&err); 146 hmp_handle_error(mon, err); 147 } 148 149 void hmp_cpu(Monitor *mon, const QDict *qdict) 150 { 151 int64_t cpu_index; 152 153 /* XXX: drop the monitor_set_cpu() usage when all HMP commands that 154 use it are converted to the QAPI */ 155 cpu_index = qdict_get_int(qdict, "index"); 156 if (monitor_set_cpu(mon, cpu_index) < 0) { 157 monitor_printf(mon, "invalid CPU index\n"); 158 } 159 } 160 161 void hmp_cont(Monitor *mon, const QDict *qdict) 162 { 163 Error *err = NULL; 164 165 qmp_cont(&err); 166 hmp_handle_error(mon, err); 167 } 168 169 void hmp_change(Monitor *mon, const QDict *qdict) 170 { 171 const char *device = qdict_get_str(qdict, "device"); 172 const char *target = qdict_get_str(qdict, "target"); 173 const char *arg = qdict_get_try_str(qdict, "arg"); 174 const char *read_only = qdict_get_try_str(qdict, "read-only-mode"); 175 bool force = qdict_get_try_bool(qdict, "force", false); 176 Error *err = NULL; 177 178 #ifdef CONFIG_VNC 179 if (strcmp(device, "vnc") == 0) { 180 hmp_change_vnc(mon, device, target, arg, read_only, force, &err); 181 } else 182 #endif 183 { 184 hmp_change_medium(mon, device, target, arg, read_only, force, &err); 185 } 186 187 hmp_handle_error(mon, err); 188 } 189 190 void hmp_getfd(Monitor *mon, const QDict *qdict) 191 { 192 const char *fdname = qdict_get_str(qdict, "fdname"); 193 Error *err = NULL; 194 195 qmp_getfd(fdname, &err); 196 hmp_handle_error(mon, err); 197 } 198 199 void hmp_closefd(Monitor *mon, const QDict *qdict) 200 { 201 const char *fdname = qdict_get_str(qdict, "fdname"); 202 Error *err = NULL; 203 204 qmp_closefd(fdname, &err); 205 hmp_handle_error(mon, err); 206 } 207 208 void hmp_info_iothreads(Monitor *mon, const QDict *qdict) 209 { 210 IOThreadInfoList *info_list = qmp_query_iothreads(NULL); 211 IOThreadInfoList *info; 212 IOThreadInfo *value; 213 214 for (info = info_list; info; info = info->next) { 215 value = info->value; 216 monitor_printf(mon, "%s:\n", value->id); 217 monitor_printf(mon, " thread_id=%" PRId64 "\n", value->thread_id); 218 monitor_printf(mon, " poll-max-ns=%" PRId64 "\n", value->poll_max_ns); 219 monitor_printf(mon, " poll-grow=%" PRId64 "\n", value->poll_grow); 220 monitor_printf(mon, " poll-shrink=%" PRId64 "\n", value->poll_shrink); 221 monitor_printf(mon, " aio-max-batch=%" PRId64 "\n", 222 value->aio_max_batch); 223 } 224 225 qapi_free_IOThreadInfoList(info_list); 226 } 227