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