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