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