xref: /qemu/dump/dump-hmp-cmds.c (revision 73b49878)
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 && raw) {
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