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
kvm_list_help(void)33 void kvm_list_help(void)
34 {
35 usage_with_options(list_usage, list_options);
36 }
37
get_pid(int sock)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
get_vmstate(int sock)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
print_guest(const char * name,int sock)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 return -1;
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
kvm_list_running_instances(void)90 static int kvm_list_running_instances(void)
91 {
92 return kvm__enumerate_instances(print_guest);
93 }
94
kvm_list_rootfs(void)95 static int kvm_list_rootfs(void)
96 {
97 DIR *dir;
98 struct dirent *dirent;
99
100 dir = opendir(kvm__get_dir());
101 if (dir == NULL)
102 return -1;
103
104 while ((dirent = readdir(dir))) {
105 if (dirent->d_type == DT_DIR &&
106 strcmp(dirent->d_name, ".") &&
107 strcmp(dirent->d_name, ".."))
108 printf("%5s %-20s %s\n", "", dirent->d_name, KVM_INSTANCE_SHUTOFF);
109 }
110
111 return 0;
112 }
113
parse_setup_options(int argc,const char ** argv)114 static void parse_setup_options(int argc, const char **argv)
115 {
116 while (argc != 0) {
117 argc = parse_options(argc, argv, list_options, list_usage,
118 PARSE_OPT_STOP_AT_NON_OPTION);
119 if (argc != 0)
120 kvm_list_help();
121 }
122 }
123
kvm_cmd_list(int argc,const char ** argv,const char * prefix)124 int kvm_cmd_list(int argc, const char **argv, const char *prefix)
125 {
126 int status, r;
127
128 parse_setup_options(argc, argv);
129
130 if (!run && !rootfs)
131 run = rootfs = true;
132
133 printf("%6s %-20s %s\n", "PID", "NAME", "STATE");
134 printf("------------------------------------\n");
135
136 status = 0;
137
138 if (run) {
139 r = kvm_list_running_instances();
140 if (r < 0)
141 perror("Error listing instances");
142
143 status |= r;
144 }
145
146 if (rootfs) {
147 r = kvm_list_rootfs();
148 if (r < 0)
149 perror("Error listing rootfs");
150
151 status |= r;
152 }
153
154 return status;
155 }
156