1 /* 2 * Windows crashdump (Human Monitor Interface commands) 3 * 4 * This work is licensed under the terms of the GNU GPL, version 2 or later. 5 * See the COPYING file in the top-level directory. 6 */ 7 8 #include "qemu/osdep.h" 9 #include "monitor/hmp.h" 10 #include "monitor/monitor.h" 11 #include "qapi/error.h" 12 #include "qapi/qapi-commands-dump.h" 13 #include "qapi/qmp/qdict.h" 14 15 void hmp_dump_guest_memory(Monitor *mon, const QDict *qdict) 16 { 17 Error *err = NULL; 18 bool win_dmp = qdict_get_try_bool(qdict, "windmp", false); 19 bool paging = qdict_get_try_bool(qdict, "paging", false); 20 bool zlib = qdict_get_try_bool(qdict, "zlib", false); 21 bool lzo = qdict_get_try_bool(qdict, "lzo", false); 22 bool raw = qdict_get_try_bool(qdict, "raw", false); 23 bool snappy = qdict_get_try_bool(qdict, "snappy", false); 24 const char *file = qdict_get_str(qdict, "filename"); 25 bool has_begin = qdict_haskey(qdict, "begin"); 26 bool has_length = qdict_haskey(qdict, "length"); 27 bool has_detach = qdict_haskey(qdict, "detach"); 28 int64_t begin = 0; 29 int64_t length = 0; 30 bool detach = false; 31 enum DumpGuestMemoryFormat dump_format = DUMP_GUEST_MEMORY_FORMAT_ELF; 32 char *prot; 33 34 if (zlib + lzo + snappy + win_dmp > 1) { 35 error_setg(&err, "only one of '-z|-l|-s|-w' can be set"); 36 hmp_handle_error(mon, err); 37 return; 38 } 39 40 if (win_dmp) { 41 dump_format = DUMP_GUEST_MEMORY_FORMAT_WIN_DMP; 42 } 43 44 if (zlib) { 45 if (raw) { 46 dump_format = DUMP_GUEST_MEMORY_FORMAT_KDUMP_RAW_ZLIB; 47 } else { 48 dump_format = DUMP_GUEST_MEMORY_FORMAT_KDUMP_ZLIB; 49 } 50 } 51 52 if (lzo) { 53 if (raw) { 54 dump_format = DUMP_GUEST_MEMORY_FORMAT_KDUMP_RAW_LZO; 55 } else { 56 dump_format = DUMP_GUEST_MEMORY_FORMAT_KDUMP_LZO; 57 } 58 } 59 60 if (snappy) { 61 if (raw) { 62 dump_format = DUMP_GUEST_MEMORY_FORMAT_KDUMP_RAW_SNAPPY; 63 } else { 64 dump_format = DUMP_GUEST_MEMORY_FORMAT_KDUMP_SNAPPY; 65 } 66 } 67 68 if (has_begin) { 69 begin = qdict_get_int(qdict, "begin"); 70 } 71 if (has_length) { 72 length = qdict_get_int(qdict, "length"); 73 } 74 if (has_detach) { 75 detach = qdict_get_bool(qdict, "detach"); 76 } 77 78 prot = g_strconcat("file:", file, NULL); 79 80 qmp_dump_guest_memory(paging, prot, true, detach, has_begin, begin, 81 has_length, length, true, dump_format, &err); 82 hmp_handle_error(mon, err); 83 g_free(prot); 84 } 85 86 void hmp_info_dump(Monitor *mon, const QDict *qdict) 87 { 88 DumpQueryResult *result = qmp_query_dump(NULL); 89 90 assert(result && result->status < DUMP_STATUS__MAX); 91 monitor_printf(mon, "Status: %s\n", DumpStatus_str(result->status)); 92 93 if (result->status == DUMP_STATUS_ACTIVE) { 94 float percent = 0; 95 assert(result->total != 0); 96 percent = 100.0 * result->completed / result->total; 97 monitor_printf(mon, "Finished: %.2f %%\n", percent); 98 } 99 100 qapi_free_DumpQueryResult(result); 101 } 102