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