xref: /kvmtool/builtin-list.c (revision 9667701c38a1f3c6a962e3aa8ec77ff8aafe2864)
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