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
hmp_dump_guest_memory(Monitor * mon,const QDict * qdict)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
hmp_info_dump(Monitor * mon,const QDict * qdict)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