xref: /kvmtool/builtin-list.c (revision 076e946ec2bc56a346e87b255693e37c582b0299)
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 
7*076e946eSSasha 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 
15*076e946eSSasha Levin static bool run;
16*076e946eSSasha Levin static bool rootfs;
17*076e946eSSasha 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[] = {
24*076e946eSSasha Levin 	OPT_GROUP("General options:"),
25*076e946eSSasha Levin 	OPT_BOOLEAN('i', "run", &run, "List running instances"),
26*076e946eSSasha 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 
68*076e946eSSasha 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 }
74*076e946eSSasha Levin 
75*076e946eSSasha Levin static int kvm_list_rootfs(void)
76*076e946eSSasha Levin {
77*076e946eSSasha Levin 	char name[PATH_MAX];
78*076e946eSSasha Levin 	DIR *dir;
79*076e946eSSasha Levin 	struct dirent *dirent;
80*076e946eSSasha Levin 
81*076e946eSSasha Levin 	snprintf(name, PATH_MAX, "%s%s", HOME_DIR, KVM_PID_FILE_PATH);
82*076e946eSSasha Levin 	dir = opendir(name);
83*076e946eSSasha Levin 	if (dir == NULL)
84*076e946eSSasha Levin 		return -1;
85*076e946eSSasha Levin 
86*076e946eSSasha Levin 	printf("  ROOTFS\n");
87*076e946eSSasha Levin 
88*076e946eSSasha Levin 	while ((dirent = readdir(dir))) {
89*076e946eSSasha Levin 		if (dirent->d_type == DT_DIR &&
90*076e946eSSasha Levin 			strcmp(dirent->d_name, ".") &&
91*076e946eSSasha Levin 			strcmp(dirent->d_name, ".."))
92*076e946eSSasha Levin 			printf("%s\n", dirent->d_name);
93*076e946eSSasha Levin 	}
94*076e946eSSasha Levin 
95*076e946eSSasha Levin 	return 0;
96*076e946eSSasha Levin }
97*076e946eSSasha Levin 
98*076e946eSSasha Levin static void parse_setup_options(int argc, const char **argv)
99*076e946eSSasha Levin {
100*076e946eSSasha Levin 	while (argc != 0) {
101*076e946eSSasha Levin 		argc = parse_options(argc, argv, list_options, list_usage,
102*076e946eSSasha Levin 				PARSE_OPT_STOP_AT_NON_OPTION);
103*076e946eSSasha Levin 		if (argc != 0)
104*076e946eSSasha Levin 			kvm_list_help();
105*076e946eSSasha Levin 	}
106*076e946eSSasha Levin }
107*076e946eSSasha Levin 
108*076e946eSSasha Levin int kvm_cmd_list(int argc, const char **argv, const char *prefix)
109*076e946eSSasha Levin {
110*076e946eSSasha Levin 	int r;
111*076e946eSSasha Levin 
112*076e946eSSasha Levin 	parse_setup_options(argc, argv);
113*076e946eSSasha Levin 
114*076e946eSSasha Levin 	if (!run && !rootfs)
115*076e946eSSasha Levin 		kvm_list_help();
116*076e946eSSasha Levin 
117*076e946eSSasha Levin 	if (run) {
118*076e946eSSasha Levin 		r = kvm_list_running_instances();
119*076e946eSSasha Levin 		if (r < 0)
120*076e946eSSasha Levin 			perror("Error listing instances");
121*076e946eSSasha Levin 	}
122*076e946eSSasha Levin 
123*076e946eSSasha Levin 	if (rootfs) {
124*076e946eSSasha Levin 		r = kvm_list_rootfs();
125*076e946eSSasha Levin 		if (r < 0)
126*076e946eSSasha Levin 			perror("Error listing rootfs");
127*076e946eSSasha Levin 	}
128*076e946eSSasha Levin 
129*076e946eSSasha Levin 	return 0;
130*076e946eSSasha Levin }
131