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