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