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