xref: /kvmtool/builtin-debug.c (revision 226e727b202ae046608da36ed7cd05ec15751e33)
1 #include <kvm/util.h>
2 #include <kvm/kvm-cmd.h>
3 #include <kvm/builtin-debug.h>
4 #include <kvm/kvm.h>
5 #include <kvm/parse-options.h>
6 #include <kvm/kvm-ipc.h>
7 #include <kvm/read-write.h>
8 
9 #include <stdio.h>
10 #include <string.h>
11 #include <signal.h>
12 
13 #define BUFFER_SIZE 100
14 
15 static bool all;
16 static int nmi = -1;
17 static bool dump;
18 static const char *instance_name;
19 static const char *sysrq;
20 
21 static const char * const debug_usage[] = {
22 	"lkvm debug [--all] [-n name] [-d] [-m vcpu]",
23 	NULL
24 };
25 
26 static const struct option debug_options[] = {
27 	OPT_GROUP("General options:"),
28 	OPT_BOOLEAN('d', "dump", &dump, "Generate a debug dump from guest"),
29 	OPT_INTEGER('m', "nmi", &nmi, "Generate NMI on VCPU"),
30 	OPT_STRING('s', "sysrq", &sysrq, "sysrq", "Inject a sysrq"),
31 	OPT_GROUP("Instance options:"),
32 	OPT_BOOLEAN('a', "all", &all, "Debug all instances"),
33 	OPT_STRING('n', "name", &instance_name, "name", "Instance name"),
34 	OPT_END()
35 };
36 
parse_debug_options(int argc,const char ** argv)37 static void parse_debug_options(int argc, const char **argv)
38 {
39 	while (argc != 0) {
40 		argc = parse_options(argc, argv, debug_options, debug_usage,
41 				PARSE_OPT_STOP_AT_NON_OPTION);
42 		if (argc != 0)
43 			kvm_debug_help();
44 	}
45 }
46 
kvm_debug_help(void)47 void kvm_debug_help(void)
48 {
49 	usage_with_options(debug_usage, debug_options);
50 }
51 
do_debug(const char * name,int sock)52 static int do_debug(const char *name, int sock)
53 {
54 	char buff[BUFFER_SIZE];
55 	struct debug_cmd_params cmd = {.dbg_type = 0};
56 	int r;
57 
58 	if (dump)
59 		cmd.dbg_type |= KVM_DEBUG_CMD_TYPE_DUMP;
60 
61 	if (nmi != -1) {
62 		cmd.dbg_type |= KVM_DEBUG_CMD_TYPE_NMI;
63 		cmd.cpu = nmi;
64 	}
65 
66 	if (sysrq) {
67 		cmd.dbg_type |= KVM_DEBUG_CMD_TYPE_SYSRQ;
68 		cmd.sysrq = sysrq[0];
69 	}
70 
71 	r = kvm_ipc__send_msg(sock, KVM_IPC_DEBUG, sizeof(cmd), (u8 *)&cmd);
72 	if (r < 0)
73 		return r;
74 
75 	if (!dump)
76 		return 0;
77 
78 	do {
79 		r = xread(sock, buff, BUFFER_SIZE);
80 		if (r < 0)
81 			return 0;
82 		printf("%.*s", r, buff);
83 	} while (r > 0);
84 
85 	return 0;
86 }
87 
kvm_cmd_debug(int argc,const char ** argv,const char * prefix)88 int kvm_cmd_debug(int argc, const char **argv, const char *prefix)
89 {
90 	parse_debug_options(argc, argv);
91 	int instance;
92 	int r;
93 
94 	if (all)
95 		return kvm__enumerate_instances(do_debug);
96 
97 	if (instance_name == NULL)
98 		kvm_debug_help();
99 
100 	instance = kvm__get_sock_by_instance(instance_name);
101 
102 	if (instance <= 0)
103 		die("Failed locating instance");
104 
105 	r = do_debug(instance_name, instance);
106 
107 	close(instance);
108 
109 	return r;
110 }
111