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 7 #include <dirent.h> 8 #include <stdio.h> 9 #include <string.h> 10 #include <signal.h> 11 #include <fcntl.h> 12 13 #define PROCESS_NAME "kvm" 14 15 static bool run; 16 static bool rootfs; 17 18 static const char * const list_usage[] = { 19 "kvm list", 20 NULL 21 }; 22 23 static const struct option list_options[] = { 24 OPT_GROUP("General options:"), 25 OPT_BOOLEAN('i', "run", &run, "List running instances"), 26 OPT_BOOLEAN('r', "rootfs", &rootfs, "List rootfs instances"), 27 OPT_END() 28 }; 29 30 void kvm_list_help(void) 31 { 32 usage_with_options(list_usage, list_options); 33 } 34 35 static int print_guest(const char *name, int pid) 36 { 37 char proc_name[PATH_MAX]; 38 char *comm = NULL; 39 FILE *fd; 40 41 sprintf(proc_name, "/proc/%d/stat", pid); 42 fd = fopen(proc_name, "r"); 43 if (fd == NULL) 44 goto cleanup; 45 if (fscanf(fd, "%*u (%as)", &comm) == 0) 46 goto cleanup; 47 if (strncmp(comm, PROCESS_NAME, strlen(PROCESS_NAME))) 48 goto cleanup; 49 50 printf("%5d %s\n", pid, name); 51 52 free(comm); 53 54 fclose(fd); 55 56 return 0; 57 58 cleanup: 59 if (fd) 60 fclose(fd); 61 if (comm) 62 free(comm); 63 64 kvm__remove_pidfile(name); 65 return 0; 66 } 67 68 static int kvm_list_running_instances(void) 69 { 70 printf(" PID GUEST\n"); 71 72 return kvm__enumerate_instances(print_guest); 73 } 74 75 static int kvm_list_rootfs(void) 76 { 77 char name[PATH_MAX]; 78 DIR *dir; 79 struct dirent *dirent; 80 81 snprintf(name, PATH_MAX, "%s", kvm__get_dir()); 82 dir = opendir(name); 83 if (dir == NULL) 84 return -1; 85 86 printf(" ROOTFS\n"); 87 88 while ((dirent = readdir(dir))) { 89 if (dirent->d_type == DT_DIR && 90 strcmp(dirent->d_name, ".") && 91 strcmp(dirent->d_name, "..")) 92 printf("%s\n", dirent->d_name); 93 } 94 95 return 0; 96 } 97 98 static void parse_setup_options(int argc, const char **argv) 99 { 100 while (argc != 0) { 101 argc = parse_options(argc, argv, list_options, list_usage, 102 PARSE_OPT_STOP_AT_NON_OPTION); 103 if (argc != 0) 104 kvm_list_help(); 105 } 106 } 107 108 int kvm_cmd_list(int argc, const char **argv, const char *prefix) 109 { 110 int r; 111 112 parse_setup_options(argc, argv); 113 114 if (!run && !rootfs) 115 kvm_list_help(); 116 117 if (run) { 118 r = kvm_list_running_instances(); 119 if (r < 0) 120 perror("Error listing instances"); 121 } 122 123 if (rootfs) { 124 r = kvm_list_rootfs(); 125 if (r < 0) 126 perror("Error listing rootfs"); 127 } 128 129 return 0; 130 } 131