xref: /kvmtool/builtin-balloon.c (revision 8d2ff5da21a87617d8c0646914293b47f333cbc4)
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 
124b1addaeSSasha Levin static int instance;
13790142ecSSasha Levin static const char *instance_name;
14790142ecSSasha Levin static u64 inflate;
15790142ecSSasha Levin static u64 deflate;
16790142ecSSasha Levin 
174b1addaeSSasha Levin struct balloon_cmd {
184b1addaeSSasha Levin 	u32 type;
194b1addaeSSasha Levin 	u32 len;
204b1addaeSSasha Levin 	int amount;
214b1addaeSSasha Levin };
224b1addaeSSasha Levin 
23c9cba791SPekka Enberg static const char * const balloon_usage[] = {
24*8d2ff5daSWanlong Gao 	"lkvm balloon [-n name] [-p pid] [-i amount] [-d amount]",
25790142ecSSasha Levin 	NULL
26790142ecSSasha Levin };
27790142ecSSasha Levin 
28c9cba791SPekka Enberg static const struct option balloon_options[] = {
29790142ecSSasha Levin 	OPT_GROUP("Instance options:"),
30790142ecSSasha Levin 	OPT_STRING('n', "name", &instance_name, "name", "Instance name"),
31790142ecSSasha Levin 	OPT_GROUP("Balloon options:"),
32790142ecSSasha Levin 	OPT_U64('i', "inflate", &inflate, "Amount to inflate"),
33790142ecSSasha Levin 	OPT_U64('d', "deflate", &deflate, "Amount to deflate"),
34790142ecSSasha Levin 	OPT_END(),
35c9cba791SPekka Enberg };
36c9cba791SPekka Enberg 
370725673aSSasha Levin void kvm_balloon_help(void)
380725673aSSasha Levin {
390725673aSSasha Levin 	usage_with_options(balloon_usage, balloon_options);
400725673aSSasha Levin }
410725673aSSasha Levin 
42790142ecSSasha Levin static void parse_balloon_options(int argc, const char **argv)
43790142ecSSasha Levin {
44790142ecSSasha Levin 	while (argc != 0) {
45790142ecSSasha Levin 		argc = parse_options(argc, argv, balloon_options, balloon_usage,
46790142ecSSasha Levin 				PARSE_OPT_STOP_AT_NON_OPTION);
47790142ecSSasha Levin 		if (argc != 0)
48790142ecSSasha Levin 			kvm_balloon_help();
49790142ecSSasha Levin 	}
50790142ecSSasha Levin }
51790142ecSSasha Levin 
525cac5d9cSSasha Levin int kvm_cmd_balloon(int argc, const char **argv, const char *prefix)
535cac5d9cSSasha Levin {
544b1addaeSSasha Levin 	struct balloon_cmd cmd;
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 
62790142ecSSasha Levin 	if (instance_name == NULL &&
634b1addaeSSasha Levin 	    instance == 0)
64790142ecSSasha Levin 		kvm_balloon_help();
655cac5d9cSSasha Levin 
66790142ecSSasha Levin 	if (instance_name)
674b1addaeSSasha Levin 		instance = kvm__get_sock_by_instance(instance_name);
685cac5d9cSSasha Levin 
694b1addaeSSasha Levin 	if (instance <= 0)
70790142ecSSasha Levin 		die("Failed locating instance");
715cac5d9cSSasha Levin 
724b1addaeSSasha Levin 	cmd.type = KVM_IPC_BALLOON;
734b1addaeSSasha Levin 	cmd.len = sizeof(cmd.amount);
744b1addaeSSasha Levin 
75790142ecSSasha Levin 	if (inflate)
764b1addaeSSasha Levin 		cmd.amount = inflate;
77790142ecSSasha Levin 	else if (deflate)
784b1addaeSSasha Levin 		cmd.amount = -deflate;
79790142ecSSasha Levin 	else
80790142ecSSasha Levin 		kvm_balloon_help();
815cac5d9cSSasha Levin 
824b1addaeSSasha Levin 	r = write(instance, &cmd, sizeof(cmd));
834b1addaeSSasha Levin 
844b1addaeSSasha Levin 	close(instance);
854b1addaeSSasha Levin 
864b1addaeSSasha Levin 	if (r < 0)
874b1addaeSSasha Levin 		return -1;
884b1addaeSSasha Levin 
895cac5d9cSSasha Levin 	return 0;
905cac5d9cSSasha Levin }
91