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