xref: /kvmtool/builtin-stat.c (revision 8d2ff5da21a87617d8c0646914293b47f333cbc4)
1 #include <kvm/util.h>
2 #include <kvm/kvm-cmd.h>
3 #include <kvm/builtin-stat.h>
4 #include <kvm/kvm.h>
5 #include <kvm/parse-options.h>
6 #include <kvm/kvm-ipc.h>
7 
8 #include <sys/select.h>
9 #include <stdio.h>
10 #include <string.h>
11 #include <signal.h>
12 
13 #include <linux/virtio_balloon.h>
14 
15 struct stat_cmd {
16 	u32 type;
17 	u32 len;
18 };
19 
20 static bool mem;
21 static bool all;
22 static int instance;
23 static const char *instance_name;
24 
25 static const char * const stat_usage[] = {
26 	"lkvm stat [command] [--all] [-n name]",
27 	NULL
28 };
29 
30 static const struct option stat_options[] = {
31 	OPT_GROUP("Commands options:"),
32 	OPT_BOOLEAN('m', "memory", &mem, "Display memory statistics"),
33 	OPT_GROUP("Instance options:"),
34 	OPT_BOOLEAN('a', "all", &all, "All instances"),
35 	OPT_STRING('n', "name", &instance_name, "name", "Instance name"),
36 	OPT_END()
37 };
38 
39 static void parse_stat_options(int argc, const char **argv)
40 {
41 	while (argc != 0) {
42 		argc = parse_options(argc, argv, stat_options, stat_usage,
43 				PARSE_OPT_STOP_AT_NON_OPTION);
44 		if (argc != 0)
45 			kvm_stat_help();
46 	}
47 }
48 
49 void kvm_stat_help(void)
50 {
51 	usage_with_options(stat_usage, stat_options);
52 }
53 
54 static int do_memstat(const char *name, int sock)
55 {
56 	struct stat_cmd cmd = {KVM_IPC_STAT, 0};
57 	struct virtio_balloon_stat stats[VIRTIO_BALLOON_S_NR];
58 	fd_set fdset;
59 	struct timeval t = { .tv_sec = 1 };
60 	int r;
61 	u8 i;
62 
63 	FD_ZERO(&fdset);
64 	FD_SET(sock, &fdset);
65 	r = write(sock, &cmd, sizeof(cmd));
66 	if (r < 0)
67 		return r;
68 
69 	r = select(1, &fdset, NULL, NULL, &t);
70 	if (r < 0) {
71 		pr_err("Could not retrieve mem stats from %s", name);
72 		return r;
73 	}
74 	r = read(sock, &stats, sizeof(stats));
75 	if (r < 0)
76 		return r;
77 
78 	printf("\n\n\t*** Guest memory statistics ***\n\n");
79 	for (i = 0; i < VIRTIO_BALLOON_S_NR; i++) {
80 		switch (stats[i].tag) {
81 		case VIRTIO_BALLOON_S_SWAP_IN:
82 			printf("The amount of memory that has been swapped in (in bytes):");
83 			break;
84 		case VIRTIO_BALLOON_S_SWAP_OUT:
85 			printf("The amount of memory that has been swapped out to disk (in bytes):");
86 			break;
87 		case VIRTIO_BALLOON_S_MAJFLT:
88 			printf("The number of major page faults that have occurred:");
89 			break;
90 		case VIRTIO_BALLOON_S_MINFLT:
91 			printf("The number of minor page faults that have occurred:");
92 			break;
93 		case VIRTIO_BALLOON_S_MEMFREE:
94 			printf("The amount of memory not being used for any purpose (in bytes):");
95 			break;
96 		case VIRTIO_BALLOON_S_MEMTOT:
97 			printf("The total amount of memory available (in bytes):");
98 			break;
99 		}
100 		printf("%llu\n", stats[i].val);
101 	}
102 	printf("\n");
103 
104 	return 0;
105 }
106 
107 int kvm_cmd_stat(int argc, const char **argv, const char *prefix)
108 {
109 	parse_stat_options(argc, argv);
110 
111 	if (!mem)
112 		usage_with_options(stat_usage, stat_options);
113 
114 	if (mem && all)
115 		return kvm__enumerate_instances(do_memstat);
116 
117 	if (instance_name == NULL &&
118 	    instance == 0)
119 		kvm_stat_help();
120 
121 	if (instance_name)
122 		instance = kvm__get_sock_by_instance(instance_name);
123 
124 	if (instance <= 0)
125 		die("Failed locating instance");
126 
127 	if (mem)
128 		return do_memstat(instance_name, instance);
129 
130 	return 0;
131 }
132