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 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[] = { 26*8d2ff5daSWanlong Gao "lkvm 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}; 57498746b9SSasha Levin struct virtio_balloon_stat stats[VIRTIO_BALLOON_S_NR]; 58498746b9SSasha Levin fd_set fdset; 59498746b9SSasha Levin struct timeval t = { .tv_sec = 1 }; 604b1addaeSSasha Levin int r; 61498746b9SSasha Levin u8 i; 624b1addaeSSasha Levin 63498746b9SSasha Levin FD_ZERO(&fdset); 64498746b9SSasha Levin FD_SET(sock, &fdset); 654b1addaeSSasha Levin r = write(sock, &cmd, sizeof(cmd)); 664b1addaeSSasha Levin if (r < 0) 674b1addaeSSasha Levin return r; 684b1addaeSSasha Levin 69498746b9SSasha Levin r = select(1, &fdset, NULL, NULL, &t); 70498746b9SSasha Levin if (r < 0) { 71599ed2a8SCyrill Gorcunov pr_err("Could not retrieve mem stats from %s", name); 72498746b9SSasha Levin return r; 73498746b9SSasha Levin } 74498746b9SSasha Levin r = read(sock, &stats, sizeof(stats)); 75498746b9SSasha Levin if (r < 0) 76498746b9SSasha Levin return r; 77498746b9SSasha Levin 78498746b9SSasha Levin printf("\n\n\t*** Guest memory statistics ***\n\n"); 79498746b9SSasha Levin for (i = 0; i < VIRTIO_BALLOON_S_NR; i++) { 80498746b9SSasha Levin switch (stats[i].tag) { 81498746b9SSasha Levin case VIRTIO_BALLOON_S_SWAP_IN: 82498746b9SSasha Levin printf("The amount of memory that has been swapped in (in bytes):"); 83498746b9SSasha Levin break; 84498746b9SSasha Levin case VIRTIO_BALLOON_S_SWAP_OUT: 85498746b9SSasha Levin printf("The amount of memory that has been swapped out to disk (in bytes):"); 86498746b9SSasha Levin break; 87498746b9SSasha Levin case VIRTIO_BALLOON_S_MAJFLT: 88498746b9SSasha Levin printf("The number of major page faults that have occurred:"); 89498746b9SSasha Levin break; 90498746b9SSasha Levin case VIRTIO_BALLOON_S_MINFLT: 91498746b9SSasha Levin printf("The number of minor page faults that have occurred:"); 92498746b9SSasha Levin break; 93498746b9SSasha Levin case VIRTIO_BALLOON_S_MEMFREE: 94498746b9SSasha Levin printf("The amount of memory not being used for any purpose (in bytes):"); 95498746b9SSasha Levin break; 96498746b9SSasha Levin case VIRTIO_BALLOON_S_MEMTOT: 97498746b9SSasha Levin printf("The total amount of memory available (in bytes):"); 98498746b9SSasha Levin break; 99498746b9SSasha Levin } 100498746b9SSasha Levin printf("%llu\n", stats[i].val); 101498746b9SSasha Levin } 102498746b9SSasha Levin printf("\n"); 103498746b9SSasha 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