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