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
8498746b9SSasha Levin #include <sys/select.h>
9bc10d2c1SSasha Levin #include <stdio.h>
10bc10d2c1SSasha Levin #include <string.h>
11bc10d2c1SSasha Levin #include <signal.h>
12bc10d2c1SSasha Levin
13498746b9SSasha Levin #include <linux/virtio_balloon.h>
14498746b9SSasha Levin
15bc10d2c1SSasha Levin static bool mem;
16bc10d2c1SSasha Levin static bool all;
17bc10d2c1SSasha Levin static const char *instance_name;
18bc10d2c1SSasha Levin
19bc10d2c1SSasha Levin static const char * const stat_usage[] = {
208d2ff5daSWanlong Gao "lkvm stat [command] [--all] [-n name]",
21bc10d2c1SSasha Levin NULL
22bc10d2c1SSasha Levin };
23bc10d2c1SSasha Levin
24bc10d2c1SSasha Levin static const struct option stat_options[] = {
25bc10d2c1SSasha Levin OPT_GROUP("Commands options:"),
26bc10d2c1SSasha Levin OPT_BOOLEAN('m', "memory", &mem, "Display memory statistics"),
27bc10d2c1SSasha Levin OPT_GROUP("Instance options:"),
28bc10d2c1SSasha Levin OPT_BOOLEAN('a', "all", &all, "All instances"),
29bc10d2c1SSasha Levin OPT_STRING('n', "name", &instance_name, "name", "Instance name"),
30bc10d2c1SSasha Levin OPT_END()
31bc10d2c1SSasha Levin };
32bc10d2c1SSasha Levin
parse_stat_options(int argc,const char ** argv)33bc10d2c1SSasha Levin static void parse_stat_options(int argc, const char **argv)
34bc10d2c1SSasha Levin {
35bc10d2c1SSasha Levin while (argc != 0) {
36bc10d2c1SSasha Levin argc = parse_options(argc, argv, stat_options, stat_usage,
37bc10d2c1SSasha Levin PARSE_OPT_STOP_AT_NON_OPTION);
38bc10d2c1SSasha Levin if (argc != 0)
39bc10d2c1SSasha Levin kvm_stat_help();
40bc10d2c1SSasha Levin }
41bc10d2c1SSasha Levin }
42bc10d2c1SSasha Levin
kvm_stat_help(void)43bc10d2c1SSasha Levin void kvm_stat_help(void)
44bc10d2c1SSasha Levin {
45bc10d2c1SSasha Levin usage_with_options(stat_usage, stat_options);
46bc10d2c1SSasha Levin }
47bc10d2c1SSasha Levin
do_memstat(const char * name,int sock)484b1addaeSSasha Levin static int do_memstat(const char *name, int sock)
49bc10d2c1SSasha Levin {
50498746b9SSasha Levin struct virtio_balloon_stat stats[VIRTIO_BALLOON_S_NR];
51498746b9SSasha Levin fd_set fdset;
52498746b9SSasha Levin struct timeval t = { .tv_sec = 1 };
534b1addaeSSasha Levin int r;
54498746b9SSasha Levin u8 i;
554b1addaeSSasha Levin
56498746b9SSasha Levin FD_ZERO(&fdset);
57498746b9SSasha Levin FD_SET(sock, &fdset);
58d0dc85a8SLai Jiangshan r = kvm_ipc__send(sock, KVM_IPC_STAT);
594b1addaeSSasha Levin if (r < 0)
604b1addaeSSasha Levin return r;
614b1addaeSSasha Levin
62498746b9SSasha Levin r = select(1, &fdset, NULL, NULL, &t);
63498746b9SSasha Levin if (r < 0) {
64599ed2a8SCyrill Gorcunov pr_err("Could not retrieve mem stats from %s", name);
65498746b9SSasha Levin return r;
66498746b9SSasha Levin }
67498746b9SSasha Levin r = read(sock, &stats, sizeof(stats));
68498746b9SSasha Levin if (r < 0)
69498746b9SSasha Levin return r;
70498746b9SSasha Levin
71498746b9SSasha Levin printf("\n\n\t*** Guest memory statistics ***\n\n");
72498746b9SSasha Levin for (i = 0; i < VIRTIO_BALLOON_S_NR; i++) {
73498746b9SSasha Levin switch (stats[i].tag) {
74498746b9SSasha Levin case VIRTIO_BALLOON_S_SWAP_IN:
75498746b9SSasha Levin printf("The amount of memory that has been swapped in (in bytes):");
76498746b9SSasha Levin break;
77498746b9SSasha Levin case VIRTIO_BALLOON_S_SWAP_OUT:
78498746b9SSasha Levin printf("The amount of memory that has been swapped out to disk (in bytes):");
79498746b9SSasha Levin break;
80498746b9SSasha Levin case VIRTIO_BALLOON_S_MAJFLT:
81498746b9SSasha Levin printf("The number of major page faults that have occurred:");
82498746b9SSasha Levin break;
83498746b9SSasha Levin case VIRTIO_BALLOON_S_MINFLT:
84498746b9SSasha Levin printf("The number of minor page faults that have occurred:");
85498746b9SSasha Levin break;
86*bc77bf49SKeir Fraser case VIRTIO_BALLOON_S_HTLB_PGALLOC:
87*bc77bf49SKeir Fraser printf("The number of successful HugeTLB allocations:");
88*bc77bf49SKeir Fraser break;
89*bc77bf49SKeir Fraser case VIRTIO_BALLOON_S_HTLB_PGFAIL:
90*bc77bf49SKeir Fraser printf("The number of failed HugeTLB allocations:");
91*bc77bf49SKeir Fraser break;
92498746b9SSasha Levin case VIRTIO_BALLOON_S_MEMFREE:
93498746b9SSasha Levin printf("The amount of memory not being used for any purpose (in bytes):");
94498746b9SSasha Levin break;
95498746b9SSasha Levin case VIRTIO_BALLOON_S_MEMTOT:
96*bc77bf49SKeir Fraser printf("The total amount of memory (in bytes):");
97*bc77bf49SKeir Fraser break;
98*bc77bf49SKeir Fraser case VIRTIO_BALLOON_S_AVAIL:
99*bc77bf49SKeir Fraser printf("The estimated available memory (in bytes):");
100*bc77bf49SKeir Fraser break;
101*bc77bf49SKeir Fraser case VIRTIO_BALLOON_S_CACHES:
102*bc77bf49SKeir Fraser printf("The amount of memory in use for file caching (in bytes):");
103*bc77bf49SKeir Fraser break;
104*bc77bf49SKeir Fraser default:
105*bc77bf49SKeir Fraser printf("Unknown memory statistic (ID %u): ", stats[i].tag);
106498746b9SSasha Levin break;
107498746b9SSasha Levin }
10869f50425SAndreas Herrmann printf("%llu\n", (unsigned long long)stats[i].val);
109498746b9SSasha Levin }
110498746b9SSasha Levin printf("\n");
111498746b9SSasha Levin
1124b1addaeSSasha Levin return 0;
113bc10d2c1SSasha Levin }
114bc10d2c1SSasha Levin
kvm_cmd_stat(int argc,const char ** argv,const char * prefix)115bc10d2c1SSasha Levin int kvm_cmd_stat(int argc, const char **argv, const char *prefix)
116bc10d2c1SSasha Levin {
11728aadb17SLai Jiangshan int instance;
11828aadb17SLai Jiangshan int r = 0;
11928aadb17SLai Jiangshan
120bc10d2c1SSasha Levin parse_stat_options(argc, argv);
121bc10d2c1SSasha Levin
122bc10d2c1SSasha Levin if (!mem)
123bc10d2c1SSasha Levin usage_with_options(stat_usage, stat_options);
124bc10d2c1SSasha Levin
125bc10d2c1SSasha Levin if (mem && all)
126bc10d2c1SSasha Levin return kvm__enumerate_instances(do_memstat);
127bc10d2c1SSasha Levin
12828aadb17SLai Jiangshan if (instance_name == NULL)
129bc10d2c1SSasha Levin kvm_stat_help();
130bc10d2c1SSasha Levin
1314b1addaeSSasha Levin instance = kvm__get_sock_by_instance(instance_name);
132bc10d2c1SSasha Levin
1334b1addaeSSasha Levin if (instance <= 0)
134bc10d2c1SSasha Levin die("Failed locating instance");
135bc10d2c1SSasha Levin
1364b1addaeSSasha Levin if (mem)
13728aadb17SLai Jiangshan r = do_memstat(instance_name, instance);
138bc10d2c1SSasha Levin
13928aadb17SLai Jiangshan close(instance);
14028aadb17SLai Jiangshan
14128aadb17SLai Jiangshan return r;
142bc10d2c1SSasha Levin }
143