xref: /kvmtool/builtin-list.c (revision 9667701c38a1f3c6a962e3aa8ec77ff8aafe2864)
19dba6721SSasha Levin #include <kvm/util.h>
29dba6721SSasha Levin #include <kvm/kvm-cmd.h>
32a24f96dSSasha Levin #include <kvm/builtin-list.h>
49dba6721SSasha Levin #include <kvm/kvm.h>
50725673aSSasha Levin #include <kvm/parse-options.h>
69dba6721SSasha Levin 
7076e946eSSasha Levin #include <dirent.h>
89dba6721SSasha Levin #include <stdio.h>
99dba6721SSasha Levin #include <string.h>
109dba6721SSasha Levin #include <signal.h>
111b1577dcSSasha Levin #include <fcntl.h>
121b1577dcSSasha Levin 
131b1577dcSSasha Levin #define PROCESS_NAME "kvm"
149dba6721SSasha Levin 
15076e946eSSasha Levin static bool run;
16076e946eSSasha Levin static bool rootfs;
17076e946eSSasha Levin 
180725673aSSasha Levin static const char * const list_usage[] = {
190725673aSSasha Levin 	"kvm list",
200725673aSSasha Levin 	NULL
210725673aSSasha Levin };
220725673aSSasha Levin 
230725673aSSasha Levin static const struct option list_options[] = {
24076e946eSSasha Levin 	OPT_GROUP("General options:"),
25076e946eSSasha Levin 	OPT_BOOLEAN('i', "run", &run, "List running instances"),
26076e946eSSasha Levin 	OPT_BOOLEAN('r', "rootfs", &rootfs, "List rootfs instances"),
270725673aSSasha Levin 	OPT_END()
280725673aSSasha Levin };
290725673aSSasha Levin 
300725673aSSasha Levin void kvm_list_help(void)
310725673aSSasha Levin {
320725673aSSasha Levin 	usage_with_options(list_usage, list_options);
330725673aSSasha Levin }
340725673aSSasha Levin 
35886af5f2SLiming Wang static int print_guest(const char *name, int pid)
369dba6721SSasha Levin {
371b1577dcSSasha Levin 	char proc_name[PATH_MAX];
38ebc49f06SSasha Levin 	char *comm = NULL;
39ebc49f06SSasha Levin 	FILE *fd;
401b1577dcSSasha Levin 
41ebc49f06SSasha Levin 	sprintf(proc_name, "/proc/%d/stat", pid);
42ebc49f06SSasha Levin 	fd = fopen(proc_name, "r");
43ebc49f06SSasha Levin 	if (fd == NULL)
441b1577dcSSasha Levin 		goto cleanup;
45ebc49f06SSasha Levin 	if (fscanf(fd, "%*u (%as)", &comm) == 0)
461b1577dcSSasha Levin 		goto cleanup;
471b1577dcSSasha Levin 	if (strncmp(comm, PROCESS_NAME, strlen(PROCESS_NAME)))
481b1577dcSSasha Levin 		goto cleanup;
491b1577dcSSasha Levin 
508a09361dSPekka Enberg 	printf("%5d %s\n", pid, name);
511b1577dcSSasha Levin 
52ebc49f06SSasha Levin 	free(comm);
53ebc49f06SSasha Levin 
54ebc49f06SSasha Levin 	fclose(fd);
551a0ef251SSasha Levin 
56886af5f2SLiming Wang 	return 0;
571b1577dcSSasha Levin 
581b1577dcSSasha Levin cleanup:
59ebc49f06SSasha Levin 	if (fd)
60ebc49f06SSasha Levin 		fclose(fd);
61ebc49f06SSasha Levin 	if (comm)
62ebc49f06SSasha Levin 		free(comm);
63ebc49f06SSasha Levin 
641b1577dcSSasha Levin 	kvm__remove_pidfile(name);
65886af5f2SLiming Wang 	return 0;
669dba6721SSasha Levin }
679dba6721SSasha Levin 
68076e946eSSasha Levin static int kvm_list_running_instances(void)
699dba6721SSasha Levin {
708a09361dSPekka Enberg 	printf("  PID GUEST\n");
718a09361dSPekka Enberg 
72886af5f2SLiming Wang 	return kvm__enumerate_instances(print_guest);
739dba6721SSasha Levin }
74076e946eSSasha Levin 
75076e946eSSasha Levin static int kvm_list_rootfs(void)
76076e946eSSasha Levin {
77076e946eSSasha Levin 	char name[PATH_MAX];
78076e946eSSasha Levin 	DIR *dir;
79076e946eSSasha Levin 	struct dirent *dirent;
80076e946eSSasha Levin 
81*9667701cSPekka Enberg 	snprintf(name, PATH_MAX, "%s", kvm__get_dir());
82076e946eSSasha Levin 	dir = opendir(name);
83076e946eSSasha Levin 	if (dir == NULL)
84076e946eSSasha Levin 		return -1;
85076e946eSSasha Levin 
86076e946eSSasha Levin 	printf("  ROOTFS\n");
87076e946eSSasha Levin 
88076e946eSSasha Levin 	while ((dirent = readdir(dir))) {
89076e946eSSasha Levin 		if (dirent->d_type == DT_DIR &&
90076e946eSSasha Levin 			strcmp(dirent->d_name, ".") &&
91076e946eSSasha Levin 			strcmp(dirent->d_name, ".."))
92076e946eSSasha Levin 			printf("%s\n", dirent->d_name);
93076e946eSSasha Levin 	}
94076e946eSSasha Levin 
95076e946eSSasha Levin 	return 0;
96076e946eSSasha Levin }
97076e946eSSasha Levin 
98076e946eSSasha Levin static void parse_setup_options(int argc, const char **argv)
99076e946eSSasha Levin {
100076e946eSSasha Levin 	while (argc != 0) {
101076e946eSSasha Levin 		argc = parse_options(argc, argv, list_options, list_usage,
102076e946eSSasha Levin 				PARSE_OPT_STOP_AT_NON_OPTION);
103076e946eSSasha Levin 		if (argc != 0)
104076e946eSSasha Levin 			kvm_list_help();
105076e946eSSasha Levin 	}
106076e946eSSasha Levin }
107076e946eSSasha Levin 
108076e946eSSasha Levin int kvm_cmd_list(int argc, const char **argv, const char *prefix)
109076e946eSSasha Levin {
110076e946eSSasha Levin 	int r;
111076e946eSSasha Levin 
112076e946eSSasha Levin 	parse_setup_options(argc, argv);
113076e946eSSasha Levin 
114076e946eSSasha Levin 	if (!run && !rootfs)
115076e946eSSasha Levin 		kvm_list_help();
116076e946eSSasha Levin 
117076e946eSSasha Levin 	if (run) {
118076e946eSSasha Levin 		r = kvm_list_running_instances();
119076e946eSSasha Levin 		if (r < 0)
120076e946eSSasha Levin 			perror("Error listing instances");
121076e946eSSasha Levin 	}
122076e946eSSasha Levin 
123076e946eSSasha Levin 	if (rootfs) {
124076e946eSSasha Levin 		r = kvm_list_rootfs();
125076e946eSSasha Levin 		if (r < 0)
126076e946eSSasha Levin 			perror("Error listing rootfs");
127076e946eSSasha Levin 	}
128076e946eSSasha Levin 
129076e946eSSasha Levin 	return 0;
130076e946eSSasha Levin }
131