1 #include <kvm/util.h> 2 #include <kvm/kvm-cmd.h> 3 #include <kvm/builtin-list.h> 4 #include <kvm/kvm.h> 5 #include <kvm/parse-options.h> 6 #include <kvm/kvm-ipc.h> 7 8 #include <dirent.h> 9 #include <stdio.h> 10 #include <string.h> 11 #include <signal.h> 12 #include <fcntl.h> 13 14 struct pid_cmd { 15 u32 type; 16 u32 len; 17 }; 18 19 struct vmstate_cmd { 20 u32 type; 21 u32 len; 22 }; 23 24 static bool run; 25 static bool rootfs; 26 27 static const char * const list_usage[] = { 28 "lkvm list", 29 NULL 30 }; 31 32 static const struct option list_options[] = { 33 OPT_GROUP("General options:"), 34 OPT_BOOLEAN('i', "run", &run, "List running instances"), 35 OPT_BOOLEAN('r', "rootfs", &rootfs, "List rootfs instances"), 36 OPT_END() 37 }; 38 39 #define KVM_INSTANCE_RUNNING "running" 40 #define KVM_INSTANCE_PAUSED "paused" 41 #define KVM_INSTANCE_SHUTOFF "shut off" 42 43 void kvm_list_help(void) 44 { 45 usage_with_options(list_usage, list_options); 46 } 47 48 static pid_t get_pid(int sock) 49 { 50 struct pid_cmd cmd = {KVM_IPC_PID, 0}; 51 int r; 52 pid_t pid; 53 54 r = write(sock, &cmd, sizeof(cmd)); 55 if (r < 0) 56 return r; 57 58 r = read(sock, &pid, sizeof(pid)); 59 if (r < 0) 60 return r; 61 62 return pid; 63 } 64 65 static int get_vmstate(int sock) 66 { 67 struct vmstate_cmd cmd = {KVM_IPC_VMSTATE, 0}; 68 int r; 69 int vmstate; 70 71 r = write(sock, &cmd, sizeof(cmd)); 72 if (r < 0) 73 return r; 74 75 r = read(sock, &vmstate, sizeof(vmstate)); 76 if (r < 0) 77 return r; 78 79 return vmstate; 80 81 } 82 83 static int print_guest(const char *name, int sock) 84 { 85 char proc_name[PATH_MAX]; 86 char *comm = NULL; 87 FILE *fd; 88 pid_t pid; 89 int vmstate; 90 91 pid = get_pid(sock); 92 vmstate = get_vmstate(sock); 93 94 sprintf(proc_name, "/proc/%d/stat", pid); 95 fd = fopen(proc_name, "r"); 96 if (fd == NULL) 97 goto cleanup; 98 if (fscanf(fd, "%*u (%as)", &comm) == 0) 99 goto cleanup; 100 101 if (vmstate == KVM_VMSTATE_PAUSED) 102 printf("%5d %-20s %s\n", pid, name, KVM_INSTANCE_PAUSED); 103 else 104 printf("%5d %-20s %s\n", pid, name, KVM_INSTANCE_RUNNING); 105 106 free(comm); 107 108 fclose(fd); 109 110 return 0; 111 112 cleanup: 113 if (fd) 114 fclose(fd); 115 if (comm) 116 free(comm); 117 118 kvm__remove_socket(name); 119 return 0; 120 } 121 122 static int kvm_list_running_instances(void) 123 { 124 return kvm__enumerate_instances(print_guest); 125 } 126 127 static int kvm_list_rootfs(void) 128 { 129 DIR *dir; 130 struct dirent *dirent; 131 132 dir = opendir(kvm__get_dir()); 133 if (dir == NULL) 134 return -1; 135 136 while ((dirent = readdir(dir))) { 137 if (dirent->d_type == DT_DIR && 138 strcmp(dirent->d_name, ".") && 139 strcmp(dirent->d_name, "..")) 140 printf("%5s %-20s %s\n", "", dirent->d_name, KVM_INSTANCE_SHUTOFF); 141 } 142 143 return 0; 144 } 145 146 static void parse_setup_options(int argc, const char **argv) 147 { 148 while (argc != 0) { 149 argc = parse_options(argc, argv, list_options, list_usage, 150 PARSE_OPT_STOP_AT_NON_OPTION); 151 if (argc != 0) 152 kvm_list_help(); 153 } 154 } 155 156 int kvm_cmd_list(int argc, const char **argv, const char *prefix) 157 { 158 int r; 159 160 parse_setup_options(argc, argv); 161 162 if (!run && !rootfs) 163 run = rootfs = true; 164 165 printf("%6s %-20s %s\n", "PID", "NAME", "STATE"); 166 printf("------------------------------------\n"); 167 168 if (run) { 169 r = kvm_list_running_instances(); 170 if (r < 0) 171 perror("Error listing instances"); 172 } 173 174 if (rootfs) { 175 r = kvm_list_rootfs(); 176 if (r < 0) 177 perror("Error listing rootfs"); 178 } 179 180 return 0; 181 } 182