xref: /kvmtool/builtin-balloon.c (revision a4670ad1d0c02c1033c69255cbe3d5918e3bb22f)
15cac5d9cSSasha Levin #include <stdio.h>
25cac5d9cSSasha Levin #include <string.h>
35cac5d9cSSasha Levin #include <signal.h>
45cac5d9cSSasha Levin 
55cac5d9cSSasha Levin #include <kvm/util.h>
65cac5d9cSSasha Levin #include <kvm/kvm-cmd.h>
72a24f96dSSasha Levin #include <kvm/builtin-balloon.h>
8c9cba791SPekka Enberg #include <kvm/parse-options.h>
95cac5d9cSSasha Levin #include <kvm/kvm.h>
104b1addaeSSasha Levin #include <kvm/kvm-ipc.h>
115cac5d9cSSasha Levin 
12790142ecSSasha Levin static const char *instance_name;
13790142ecSSasha Levin static u64 inflate;
14790142ecSSasha Levin static u64 deflate;
15790142ecSSasha Levin 
164b1addaeSSasha Levin struct balloon_cmd {
174b1addaeSSasha Levin 	u32 type;
184b1addaeSSasha Levin 	u32 len;
194b1addaeSSasha Levin 	int amount;
204b1addaeSSasha Levin };
214b1addaeSSasha Levin 
22c9cba791SPekka Enberg static const char * const balloon_usage[] = {
238d2ff5daSWanlong Gao 	"lkvm balloon [-n name] [-p pid] [-i amount] [-d amount]",
24790142ecSSasha Levin 	NULL
25790142ecSSasha Levin };
26790142ecSSasha Levin 
27c9cba791SPekka Enberg static const struct option balloon_options[] = {
28790142ecSSasha Levin 	OPT_GROUP("Instance options:"),
29790142ecSSasha Levin 	OPT_STRING('n', "name", &instance_name, "name", "Instance name"),
30790142ecSSasha Levin 	OPT_GROUP("Balloon options:"),
31790142ecSSasha Levin 	OPT_U64('i', "inflate", &inflate, "Amount to inflate"),
32790142ecSSasha Levin 	OPT_U64('d', "deflate", &deflate, "Amount to deflate"),
33790142ecSSasha Levin 	OPT_END(),
34c9cba791SPekka Enberg };
35c9cba791SPekka Enberg 
360725673aSSasha Levin void kvm_balloon_help(void)
370725673aSSasha Levin {
380725673aSSasha Levin 	usage_with_options(balloon_usage, balloon_options);
390725673aSSasha Levin }
400725673aSSasha Levin 
41790142ecSSasha Levin static void parse_balloon_options(int argc, const char **argv)
42790142ecSSasha Levin {
43790142ecSSasha Levin 	while (argc != 0) {
44790142ecSSasha Levin 		argc = parse_options(argc, argv, balloon_options, balloon_usage,
45790142ecSSasha Levin 				PARSE_OPT_STOP_AT_NON_OPTION);
46790142ecSSasha Levin 		if (argc != 0)
47790142ecSSasha Levin 			kvm_balloon_help();
48790142ecSSasha Levin 	}
49790142ecSSasha Levin }
50790142ecSSasha Levin 
515cac5d9cSSasha Levin int kvm_cmd_balloon(int argc, const char **argv, const char *prefix)
525cac5d9cSSasha Levin {
534b1addaeSSasha Levin 	struct balloon_cmd cmd;
54*a4670ad1SLai Jiangshan 	int instance;
554b1addaeSSasha Levin 	int r;
565cac5d9cSSasha Levin 
57790142ecSSasha Levin 	parse_balloon_options(argc, argv);
58790142ecSSasha Levin 
59790142ecSSasha Levin 	if (inflate == 0 && deflate == 0)
600725673aSSasha Levin 		kvm_balloon_help();
615cac5d9cSSasha Levin 
62*a4670ad1SLai Jiangshan 	if (instance_name == NULL)
63790142ecSSasha Levin 		kvm_balloon_help();
645cac5d9cSSasha Levin 
654b1addaeSSasha Levin 	instance = kvm__get_sock_by_instance(instance_name);
665cac5d9cSSasha Levin 
674b1addaeSSasha Levin 	if (instance <= 0)
68790142ecSSasha Levin 		die("Failed locating instance");
695cac5d9cSSasha Levin 
704b1addaeSSasha Levin 	cmd.type = KVM_IPC_BALLOON;
714b1addaeSSasha Levin 	cmd.len = sizeof(cmd.amount);
724b1addaeSSasha Levin 
73790142ecSSasha Levin 	if (inflate)
744b1addaeSSasha Levin 		cmd.amount = inflate;
75790142ecSSasha Levin 	else if (deflate)
764b1addaeSSasha Levin 		cmd.amount = -deflate;
77790142ecSSasha Levin 	else
78790142ecSSasha Levin 		kvm_balloon_help();
795cac5d9cSSasha Levin 
804b1addaeSSasha Levin 	r = write(instance, &cmd, sizeof(cmd));
814b1addaeSSasha Levin 
824b1addaeSSasha Levin 	close(instance);
834b1addaeSSasha Levin 
844b1addaeSSasha Levin 	if (r < 0)
854b1addaeSSasha Levin 		return -1;
864b1addaeSSasha Levin 
875cac5d9cSSasha Levin 	return 0;
885cac5d9cSSasha Levin }
89