1 /* 2 * Generic Balloon handlers and management 3 * 4 * Copyright (c) 2003-2008 Fabrice Bellard 5 * Copyright (C) 2011 Red Hat, Inc. 6 * Copyright (C) 2011 Amit Shah <amit.shah@redhat.com> 7 * 8 * Permission is hereby granted, free of charge, to any person obtaining a copy 9 * of this software and associated documentation files (the "Software"), to deal 10 * in the Software without restriction, including without limitation the rights 11 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 12 * copies of the Software, and to permit persons to whom the Software is 13 * furnished to do so, subject to the following conditions: 14 * 15 * The above copyright notice and this permission notice shall be included in 16 * all copies or substantial portions of the Software. 17 * 18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 19 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 20 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 21 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 22 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 23 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 24 * THE SOFTWARE. 25 */ 26 27 #include "qemu/osdep.h" 28 #include "qemu/atomic.h" 29 #include "sysemu/kvm.h" 30 #include "sysemu/balloon.h" 31 #include "qapi/error.h" 32 #include "qapi/qapi-commands-machine.h" 33 #include "qapi/qmp/qerror.h" 34 #include "trace.h" 35 36 static QEMUBalloonEvent *balloon_event_fn; 37 static QEMUBalloonStatus *balloon_stat_fn; 38 static void *balloon_opaque; 39 40 static bool have_balloon(Error **errp) 41 { 42 if (kvm_enabled() && !kvm_has_sync_mmu()) { 43 error_set(errp, ERROR_CLASS_KVM_MISSING_CAP, 44 "Using KVM without synchronous MMU, balloon unavailable"); 45 return false; 46 } 47 if (!balloon_event_fn) { 48 error_set(errp, ERROR_CLASS_DEVICE_NOT_ACTIVE, 49 "No balloon device has been activated"); 50 return false; 51 } 52 return true; 53 } 54 55 int qemu_add_balloon_handler(QEMUBalloonEvent *event_func, 56 QEMUBalloonStatus *stat_func, void *opaque) 57 { 58 if (balloon_event_fn || balloon_stat_fn || balloon_opaque) { 59 /* We're already registered one balloon handler. How many can 60 * a guest really have? 61 */ 62 return -1; 63 } 64 balloon_event_fn = event_func; 65 balloon_stat_fn = stat_func; 66 balloon_opaque = opaque; 67 return 0; 68 } 69 70 void qemu_remove_balloon_handler(void *opaque) 71 { 72 if (balloon_opaque != opaque) { 73 return; 74 } 75 balloon_event_fn = NULL; 76 balloon_stat_fn = NULL; 77 balloon_opaque = NULL; 78 } 79 80 BalloonInfo *qmp_query_balloon(Error **errp) 81 { 82 BalloonInfo *info; 83 84 if (!have_balloon(errp)) { 85 return NULL; 86 } 87 88 info = g_malloc0(sizeof(*info)); 89 balloon_stat_fn(balloon_opaque, info); 90 return info; 91 } 92 93 void qmp_balloon(int64_t target, Error **errp) 94 { 95 if (!have_balloon(errp)) { 96 return; 97 } 98 99 if (target <= 0) { 100 error_setg(errp, QERR_INVALID_PARAMETER_VALUE, "target", "a size"); 101 return; 102 } 103 104 trace_balloon_event(balloon_opaque, target); 105 balloon_event_fn(balloon_opaque, target); 106 } 107