12608b3dfSMarkus Armbruster /* 2ac978771SPhilippe Mathieu-Daudé * Windows crashdump (Human Monitor Interface commands) 32608b3dfSMarkus Armbruster * 42608b3dfSMarkus Armbruster * This work is licensed under the terms of the GNU GPL, version 2 or later. 52608b3dfSMarkus Armbruster * See the COPYING file in the top-level directory. 62608b3dfSMarkus Armbruster */ 72608b3dfSMarkus Armbruster 82608b3dfSMarkus Armbruster #include "qemu/osdep.h" 92608b3dfSMarkus Armbruster #include "monitor/hmp.h" 102608b3dfSMarkus Armbruster #include "monitor/monitor.h" 112608b3dfSMarkus Armbruster #include "qapi/error.h" 122608b3dfSMarkus Armbruster #include "qapi/qapi-commands-dump.h" 132608b3dfSMarkus Armbruster #include "qapi/qmp/qdict.h" 142608b3dfSMarkus Armbruster 152608b3dfSMarkus Armbruster void hmp_dump_guest_memory(Monitor *mon, const QDict *qdict) 162608b3dfSMarkus Armbruster { 172608b3dfSMarkus Armbruster Error *err = NULL; 182608b3dfSMarkus Armbruster bool win_dmp = qdict_get_try_bool(qdict, "windmp", false); 192608b3dfSMarkus Armbruster bool paging = qdict_get_try_bool(qdict, "paging", false); 202608b3dfSMarkus Armbruster bool zlib = qdict_get_try_bool(qdict, "zlib", false); 212608b3dfSMarkus Armbruster bool lzo = qdict_get_try_bool(qdict, "lzo", false); 22e6549197SStephen Brennan bool raw = qdict_get_try_bool(qdict, "raw", false); 232608b3dfSMarkus Armbruster bool snappy = qdict_get_try_bool(qdict, "snappy", false); 242608b3dfSMarkus Armbruster const char *file = qdict_get_str(qdict, "filename"); 252608b3dfSMarkus Armbruster bool has_begin = qdict_haskey(qdict, "begin"); 262608b3dfSMarkus Armbruster bool has_length = qdict_haskey(qdict, "length"); 272608b3dfSMarkus Armbruster bool has_detach = qdict_haskey(qdict, "detach"); 282608b3dfSMarkus Armbruster int64_t begin = 0; 292608b3dfSMarkus Armbruster int64_t length = 0; 302608b3dfSMarkus Armbruster bool detach = false; 312608b3dfSMarkus Armbruster enum DumpGuestMemoryFormat dump_format = DUMP_GUEST_MEMORY_FORMAT_ELF; 322608b3dfSMarkus Armbruster char *prot; 332608b3dfSMarkus Armbruster 342608b3dfSMarkus Armbruster if (zlib + lzo + snappy + win_dmp > 1) { 352608b3dfSMarkus Armbruster error_setg(&err, "only one of '-z|-l|-s|-w' can be set"); 36187c6147SVladimir Sementsov-Ogievskiy hmp_handle_error(mon, err); 372608b3dfSMarkus Armbruster return; 382608b3dfSMarkus Armbruster } 392608b3dfSMarkus Armbruster 402608b3dfSMarkus Armbruster if (win_dmp) { 412608b3dfSMarkus Armbruster dump_format = DUMP_GUEST_MEMORY_FORMAT_WIN_DMP; 422608b3dfSMarkus Armbruster } 432608b3dfSMarkus Armbruster 44*e999bea8SMarkus Armbruster if (zlib) { 45e6549197SStephen Brennan if (raw) { 46e6549197SStephen Brennan dump_format = DUMP_GUEST_MEMORY_FORMAT_KDUMP_RAW_ZLIB; 47e6549197SStephen Brennan } else { 482608b3dfSMarkus Armbruster dump_format = DUMP_GUEST_MEMORY_FORMAT_KDUMP_ZLIB; 492608b3dfSMarkus Armbruster } 50e6549197SStephen Brennan } 512608b3dfSMarkus Armbruster 522608b3dfSMarkus Armbruster if (lzo) { 53e6549197SStephen Brennan if (raw) { 54e6549197SStephen Brennan dump_format = DUMP_GUEST_MEMORY_FORMAT_KDUMP_RAW_LZO; 55e6549197SStephen Brennan } else { 562608b3dfSMarkus Armbruster dump_format = DUMP_GUEST_MEMORY_FORMAT_KDUMP_LZO; 572608b3dfSMarkus Armbruster } 58e6549197SStephen Brennan } 592608b3dfSMarkus Armbruster 602608b3dfSMarkus Armbruster if (snappy) { 61e6549197SStephen Brennan if (raw) { 62e6549197SStephen Brennan dump_format = DUMP_GUEST_MEMORY_FORMAT_KDUMP_RAW_SNAPPY; 63e6549197SStephen Brennan } else { 642608b3dfSMarkus Armbruster dump_format = DUMP_GUEST_MEMORY_FORMAT_KDUMP_SNAPPY; 652608b3dfSMarkus Armbruster } 66e6549197SStephen Brennan } 672608b3dfSMarkus Armbruster 682608b3dfSMarkus Armbruster if (has_begin) { 692608b3dfSMarkus Armbruster begin = qdict_get_int(qdict, "begin"); 702608b3dfSMarkus Armbruster } 712608b3dfSMarkus Armbruster if (has_length) { 722608b3dfSMarkus Armbruster length = qdict_get_int(qdict, "length"); 732608b3dfSMarkus Armbruster } 742608b3dfSMarkus Armbruster if (has_detach) { 752608b3dfSMarkus Armbruster detach = qdict_get_bool(qdict, "detach"); 762608b3dfSMarkus Armbruster } 772608b3dfSMarkus Armbruster 782608b3dfSMarkus Armbruster prot = g_strconcat("file:", file, NULL); 792608b3dfSMarkus Armbruster 802608b3dfSMarkus Armbruster qmp_dump_guest_memory(paging, prot, true, detach, has_begin, begin, 812608b3dfSMarkus Armbruster has_length, length, true, dump_format, &err); 82187c6147SVladimir Sementsov-Ogievskiy hmp_handle_error(mon, err); 832608b3dfSMarkus Armbruster g_free(prot); 842608b3dfSMarkus Armbruster } 852608b3dfSMarkus Armbruster 862608b3dfSMarkus Armbruster void hmp_info_dump(Monitor *mon, const QDict *qdict) 872608b3dfSMarkus Armbruster { 882608b3dfSMarkus Armbruster DumpQueryResult *result = qmp_query_dump(NULL); 892608b3dfSMarkus Armbruster 902608b3dfSMarkus Armbruster assert(result && result->status < DUMP_STATUS__MAX); 912608b3dfSMarkus Armbruster monitor_printf(mon, "Status: %s\n", DumpStatus_str(result->status)); 922608b3dfSMarkus Armbruster 932608b3dfSMarkus Armbruster if (result->status == DUMP_STATUS_ACTIVE) { 942608b3dfSMarkus Armbruster float percent = 0; 952608b3dfSMarkus Armbruster assert(result->total != 0); 962608b3dfSMarkus Armbruster percent = 100.0 * result->completed / result->total; 972608b3dfSMarkus Armbruster monitor_printf(mon, "Finished: %.2f %%\n", percent); 982608b3dfSMarkus Armbruster } 992608b3dfSMarkus Armbruster 1002608b3dfSMarkus Armbruster qapi_free_DumpQueryResult(result); 1012608b3dfSMarkus Armbruster } 102