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