xref: /kvmtool/builtin-balloon.c (revision 4b1addaeed6f8c717b2b818e3f867829849d8e86)
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>
10*4b1addaeSSasha Levin #include <kvm/kvm-ipc.h>
115cac5d9cSSasha Levin 
12*4b1addaeSSasha Levin static int instance;
13790142ecSSasha Levin static const char *instance_name;
14790142ecSSasha Levin static u64 inflate;
15790142ecSSasha Levin static u64 deflate;
16790142ecSSasha Levin 
17*4b1addaeSSasha Levin struct balloon_cmd {
18*4b1addaeSSasha Levin 	u32 type;
19*4b1addaeSSasha Levin 	u32 len;
20*4b1addaeSSasha Levin 	int amount;
21*4b1addaeSSasha Levin };
22*4b1addaeSSasha Levin 
23c9cba791SPekka Enberg static const char * const balloon_usage[] = {
24790142ecSSasha Levin 	"kvm 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 {
54*4b1addaeSSasha Levin 	struct balloon_cmd cmd;
55*4b1addaeSSasha 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 &&
63*4b1addaeSSasha Levin 	    instance == 0)
64790142ecSSasha Levin 		kvm_balloon_help();
655cac5d9cSSasha Levin 
66790142ecSSasha Levin 	if (instance_name)
67*4b1addaeSSasha Levin 		instance = kvm__get_sock_by_instance(instance_name);
685cac5d9cSSasha Levin 
69*4b1addaeSSasha Levin 	if (instance <= 0)
70790142ecSSasha Levin 		die("Failed locating instance");
715cac5d9cSSasha Levin 
72*4b1addaeSSasha Levin 	cmd.type = KVM_IPC_BALLOON;
73*4b1addaeSSasha Levin 	cmd.len = sizeof(cmd.amount);
74*4b1addaeSSasha Levin 
75790142ecSSasha Levin 	if (inflate)
76*4b1addaeSSasha Levin 		cmd.amount = inflate;
77790142ecSSasha Levin 	else if (deflate)
78*4b1addaeSSasha Levin 		cmd.amount = -deflate;
79790142ecSSasha Levin 	else
80790142ecSSasha Levin 		kvm_balloon_help();
815cac5d9cSSasha Levin 
82*4b1addaeSSasha Levin 	r = write(instance, &cmd, sizeof(cmd));
83*4b1addaeSSasha Levin 
84*4b1addaeSSasha Levin 	close(instance);
85*4b1addaeSSasha Levin 
86*4b1addaeSSasha Levin 	if (r < 0)
87*4b1addaeSSasha Levin 		return -1;
88*4b1addaeSSasha Levin 
895cac5d9cSSasha Levin 	return 0;
905cac5d9cSSasha Levin }
91