| #include <kvm/util.h> |
| #include <kvm/kvm-cmd.h> |
| #include <kvm/builtin-list.h> |
| #include <kvm/kvm.h> |
| #include <kvm/parse-options.h> |
| #include <kvm/kvm-ipc.h> |
| |
| #include <dirent.h> |
| #include <stdio.h> |
| #include <string.h> |
| #include <signal.h> |
| #include <fcntl.h> |
| |
| static bool run; |
| static bool rootfs; |
| |
| static const char * const list_usage[] = { |
| "lkvm list", |
| NULL |
| }; |
| |
| static const struct option list_options[] = { |
| OPT_GROUP("General options:"), |
| OPT_BOOLEAN('i', "run", &run, "List running instances"), |
| OPT_BOOLEAN('r', "rootfs", &rootfs, "List rootfs instances"), |
| OPT_END() |
| }; |
| |
| #define KVM_INSTANCE_RUNNING "running" |
| #define KVM_INSTANCE_PAUSED "paused" |
| #define KVM_INSTANCE_SHUTOFF "shut off" |
| |
| void kvm_list_help(void) |
| { |
| usage_with_options(list_usage, list_options); |
| } |
| |
| static pid_t get_pid(int sock) |
| { |
| pid_t pid; |
| int r; |
| |
| r = kvm_ipc__send(sock, KVM_IPC_PID); |
| if (r < 0) |
| return r; |
| |
| r = read(sock, &pid, sizeof(pid)); |
| if (r < 0) |
| return r; |
| |
| return pid; |
| } |
| |
| int get_vmstate(int sock) |
| { |
| int vmstate; |
| int r; |
| |
| r = kvm_ipc__send(sock, KVM_IPC_VMSTATE); |
| if (r < 0) |
| return r; |
| |
| r = read(sock, &vmstate, sizeof(vmstate)); |
| if (r < 0) |
| return r; |
| |
| return vmstate; |
| |
| } |
| |
| static int print_guest(const char *name, int sock) |
| { |
| pid_t pid; |
| int vmstate; |
| |
| pid = get_pid(sock); |
| vmstate = get_vmstate(sock); |
| |
| if ((int)pid < 0 || vmstate < 0) |
| return -1; |
| |
| if (vmstate == KVM_VMSTATE_PAUSED) |
| printf("%5d %-20s %s\n", pid, name, KVM_INSTANCE_PAUSED); |
| else |
| printf("%5d %-20s %s\n", pid, name, KVM_INSTANCE_RUNNING); |
| |
| return 0; |
| } |
| |
| static int kvm_list_running_instances(void) |
| { |
| return kvm__enumerate_instances(print_guest); |
| } |
| |
| static int kvm_list_rootfs(void) |
| { |
| DIR *dir; |
| struct dirent *dirent; |
| |
| dir = opendir(kvm__get_dir()); |
| if (dir == NULL) |
| return -1; |
| |
| while ((dirent = readdir(dir))) { |
| if (dirent->d_type == DT_DIR && |
| strcmp(dirent->d_name, ".") && |
| strcmp(dirent->d_name, "..")) |
| printf("%5s %-20s %s\n", "", dirent->d_name, KVM_INSTANCE_SHUTOFF); |
| } |
| |
| return 0; |
| } |
| |
| static void parse_setup_options(int argc, const char **argv) |
| { |
| while (argc != 0) { |
| argc = parse_options(argc, argv, list_options, list_usage, |
| PARSE_OPT_STOP_AT_NON_OPTION); |
| if (argc != 0) |
| kvm_list_help(); |
| } |
| } |
| |
| int kvm_cmd_list(int argc, const char **argv, const char *prefix) |
| { |
| int status, r; |
| |
| parse_setup_options(argc, argv); |
| |
| if (!run && !rootfs) |
| run = rootfs = true; |
| |
| printf("%6s %-20s %s\n", "PID", "NAME", "STATE"); |
| printf("------------------------------------\n"); |
| |
| status = 0; |
| |
| if (run) { |
| r = kvm_list_running_instances(); |
| if (r < 0) |
| perror("Error listing instances"); |
| |
| status |= r; |
| } |
| |
| if (rootfs) { |
| r = kvm_list_rootfs(); |
| if (r < 0) |
| perror("Error listing rootfs"); |
| |
| status |= r; |
| } |
| |
| return status; |
| } |