xref: /kvmtool/builtin-stop.c (revision 715bbf8b0b527557493900c34abf497db6be62d4)
1daf4cb5aSSasha Levin #include <kvm/util.h>
2daf4cb5aSSasha Levin #include <kvm/kvm-cmd.h>
3daf4cb5aSSasha Levin #include <kvm/builtin-stop.h>
4daf4cb5aSSasha Levin #include <kvm/kvm.h>
5c9cba791SPekka Enberg #include <kvm/parse-options.h>
64b1addaeSSasha Levin #include <kvm/kvm-ipc.h>
7daf4cb5aSSasha Levin 
8daf4cb5aSSasha Levin #include <stdio.h>
9daf4cb5aSSasha Levin #include <string.h>
10daf4cb5aSSasha Levin #include <signal.h>
11daf4cb5aSSasha Levin 
124b1addaeSSasha Levin struct stop_cmd {
134b1addaeSSasha Levin 	u32 type;
144b1addaeSSasha Levin 	u32 len;
154b1addaeSSasha Levin };
164b1addaeSSasha Levin 
1709af335bSSasha Levin static bool all;
1809af335bSSasha Levin static const char *instance_name;
1909af335bSSasha Levin 
20c9cba791SPekka Enberg static const char * const stop_usage[] = {
218d2ff5daSWanlong Gao 	"lkvm stop [--all] [-n name]",
22c9cba791SPekka Enberg 	NULL
23c9cba791SPekka Enberg };
24c9cba791SPekka Enberg 
25c9cba791SPekka Enberg static const struct option stop_options[] = {
2609af335bSSasha Levin 	OPT_GROUP("General options:"),
2709af335bSSasha Levin 	OPT_BOOLEAN('a', "all", &all, "Stop all instances"),
2809af335bSSasha Levin 	OPT_STRING('n', "name", &instance_name, "name", "Instance name"),
29c9cba791SPekka Enberg 	OPT_END()
30c9cba791SPekka Enberg };
31c9cba791SPekka Enberg 
3209af335bSSasha Levin static void parse_stop_options(int argc, const char **argv)
3309af335bSSasha Levin {
3409af335bSSasha Levin 	while (argc != 0) {
3509af335bSSasha Levin 		argc = parse_options(argc, argv, stop_options, stop_usage,
3609af335bSSasha Levin 				PARSE_OPT_STOP_AT_NON_OPTION);
3709af335bSSasha Levin 		if (argc != 0)
3809af335bSSasha Levin 			kvm_stop_help();
3909af335bSSasha Levin 	}
4009af335bSSasha Levin }
4109af335bSSasha Levin 
420725673aSSasha Levin void kvm_stop_help(void)
430725673aSSasha Levin {
440725673aSSasha Levin 	usage_with_options(stop_usage, stop_options);
450725673aSSasha Levin }
460725673aSSasha Levin 
474b1addaeSSasha Levin static int do_stop(const char *name, int sock)
48daf4cb5aSSasha Levin {
494b1addaeSSasha Levin 	struct stop_cmd cmd = {KVM_IPC_STOP, 0};
504b1addaeSSasha Levin 	int r;
514b1addaeSSasha Levin 
524b1addaeSSasha Levin 	r = write(sock, &cmd, sizeof(cmd));
534b1addaeSSasha Levin 	if (r < 0)
544b1addaeSSasha Levin 		return r;
554b1addaeSSasha Levin 
564b1addaeSSasha Levin 	return 0;
57daf4cb5aSSasha Levin }
58daf4cb5aSSasha Levin 
59daf4cb5aSSasha Levin int kvm_cmd_stop(int argc, const char **argv, const char *prefix)
60daf4cb5aSSasha Levin {
61*715bbf8bSLai Jiangshan 	int instance;
62*715bbf8bSLai Jiangshan 	int r;
63*715bbf8bSLai Jiangshan 
6409af335bSSasha Levin 	parse_stop_options(argc, argv);
65daf4cb5aSSasha Levin 
6609af335bSSasha Levin 	if (all)
6709af335bSSasha Levin 		return kvm__enumerate_instances(do_stop);
6809af335bSSasha Levin 
69*715bbf8bSLai Jiangshan 	if (instance_name == NULL)
700725673aSSasha Levin 		kvm_stop_help();
71daf4cb5aSSasha Levin 
724b1addaeSSasha Levin 	instance = kvm__get_sock_by_instance(instance_name);
73daf4cb5aSSasha Levin 
744b1addaeSSasha Levin 	if (instance <= 0)
7509af335bSSasha Levin 		die("Failed locating instance");
76daf4cb5aSSasha Levin 
77*715bbf8bSLai Jiangshan 	r = do_stop(instance_name, instance);
78*715bbf8bSLai Jiangshan 
79*715bbf8bSLai Jiangshan 	close(instance);
80*715bbf8bSLai Jiangshan 
81*715bbf8bSLai Jiangshan 	return r;
82daf4cb5aSSasha Levin }
83