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 static bool run; 15 static bool rootfs; 16 17 static const char * const list_usage[] = { 18 "lkvm list", 19 NULL 20 }; 21 22 static const struct option list_options[] = { 23 OPT_GROUP("General options:"), 24 OPT_BOOLEAN('i', "run", &run, "List running instances"), 25 OPT_BOOLEAN('r', "rootfs", &rootfs, "List rootfs instances"), 26 OPT_END() 27 }; 28 29 #define KVM_INSTANCE_RUNNING "running" 30 #define KVM_INSTANCE_PAUSED "paused" 31 #define KVM_INSTANCE_SHUTOFF "shut off" 32 33 void kvm_list_help(void) 34 { 35 usage_with_options(list_usage, list_options); 36 } 37 38 static pid_t get_pid(int sock) 39 { 40 pid_t pid; 41 int r; 42 43 r = kvm_ipc__send(sock, KVM_IPC_PID); 44 if (r < 0) 45 return r; 46 47 r = read(sock, &pid, sizeof(pid)); 48 if (r < 0) 49 return r; 50 51 return pid; 52 } 53 54 int get_vmstate(int sock) 55 { 56 int vmstate; 57 int r; 58 59 r = kvm_ipc__send(sock, KVM_IPC_VMSTATE); 60 if (r < 0) 61 return r; 62 63 r = read(sock, &vmstate, sizeof(vmstate)); 64 if (r < 0) 65 return r; 66 67 return vmstate; 68 69 } 70 71 static int print_guest(const char *name, int sock) 72 { 73 pid_t pid; 74 int vmstate; 75 76 pid = get_pid(sock); 77 vmstate = get_vmstate(sock); 78 79 if ((int)pid < 0 || vmstate < 0) 80 goto cleanup; 81 82 if (vmstate == KVM_VMSTATE_PAUSED) 83 printf("%5d %-20s %s\n", pid, name, KVM_INSTANCE_PAUSED); 84 else 85 printf("%5d %-20s %s\n", pid, name, KVM_INSTANCE_RUNNING); 86 87 return 0; 88 89 cleanup: 90 kvm__remove_socket(name); 91 return -1; 92 } 93 94 static int kvm_list_running_instances(void) 95 { 96 return kvm__enumerate_instances(print_guest); 97 } 98 99 static int kvm_list_rootfs(void) 100 { 101 DIR *dir; 102 struct dirent *dirent; 103 104 dir = opendir(kvm__get_dir()); 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("%5s %-20s %s\n", "", dirent->d_name, KVM_INSTANCE_SHUTOFF); 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("%6s %-20s %s\n", "PID", "NAME", "STATE"); 138 printf("------------------------------------\n"); 139 140 if (run) { 141 r = kvm_list_running_instances(); 142 if (r < 0) 143 perror("Error listing instances"); 144 } 145 146 if (rootfs) { 147 r = kvm_list_rootfs(); 148 if (r < 0) 149 perror("Error listing rootfs"); 150 } 151 152 return 0; 153 } 154