Annotation of qemu/balloon.c, revision 1.1.1.3

1.1       root        1: /*
1.1.1.3 ! root        2:  * Generic Balloon handlers and management
1.1       root        3:  *
                      4:  * Copyright (c) 2003-2008 Fabrice Bellard
1.1.1.3 ! root        5:  * Copyright (C) 2011 Red Hat, Inc.
        !             6:  * Copyright (C) 2011 Amit Shah <amit.shah@redhat.com>
1.1       root        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 "monitor.h"
                     28: #include "qjson.h"
                     29: #include "qint.h"
                     30: #include "cpu-common.h"
                     31: #include "kvm.h"
                     32: #include "balloon.h"
1.1.1.2   root       33: #include "trace.h"
1.1       root       34: 
1.1.1.3 ! root       35: static QEMUBalloonEvent *balloon_event_fn;
        !            36: static QEMUBalloonStatus *balloon_stat_fn;
        !            37: static void *balloon_opaque;
        !            38: 
        !            39: int qemu_add_balloon_handler(QEMUBalloonEvent *event_func,
        !            40:                              QEMUBalloonStatus *stat_func, void *opaque)
        !            41: {
        !            42:     if (balloon_event_fn || balloon_stat_fn || balloon_opaque) {
        !            43:         /* We're already registered one balloon handler.  How many can
        !            44:          * a guest really have?
        !            45:          */
        !            46:         error_report("Another balloon device already registered");
        !            47:         return -1;
        !            48:     }
        !            49:     balloon_event_fn = event_func;
        !            50:     balloon_stat_fn = stat_func;
        !            51:     balloon_opaque = opaque;
        !            52:     return 0;
1.1       root       53: }
                     54: 
1.1.1.3 ! root       55: static int qemu_balloon(ram_addr_t target)
1.1       root       56: {
1.1.1.3 ! root       57:     if (!balloon_event_fn) {
1.1       root       58:         return 0;
                     59:     }
1.1.1.3 ! root       60:     trace_balloon_event(balloon_opaque, target);
        !            61:     balloon_event_fn(balloon_opaque, target);
        !            62:     return 1;
1.1       root       63: }
                     64: 
1.1.1.3 ! root       65: static int qemu_balloon_status(MonitorCompletion cb, void *opaque)
1.1       root       66: {
1.1.1.3 ! root       67:     if (!balloon_stat_fn) {
1.1       root       68:         return 0;
                     69:     }
1.1.1.3 ! root       70:     balloon_stat_fn(balloon_opaque, cb, opaque);
        !            71:     return 1;
1.1       root       72: }
                     73: 
                     74: static void print_balloon_stat(const char *key, QObject *obj, void *opaque)
                     75: {
                     76:     Monitor *mon = opaque;
                     77: 
1.1.1.3 ! root       78:     if (strcmp(key, "actual")) {
1.1       root       79:         monitor_printf(mon, ",%s=%" PRId64, key,
                     80:                        qint_get_int(qobject_to_qint(obj)));
1.1.1.3 ! root       81:     }
1.1       root       82: }
                     83: 
                     84: void monitor_print_balloon(Monitor *mon, const QObject *data)
                     85: {
                     86:     QDict *qdict;
                     87: 
                     88:     qdict = qobject_to_qdict(data);
1.1.1.3 ! root       89:     if (!qdict_haskey(qdict, "actual")) {
1.1       root       90:         return;
1.1.1.3 ! root       91:     }
1.1       root       92:     monitor_printf(mon, "balloon: actual=%" PRId64,
                     93:                    qdict_get_int(qdict, "actual") >> 20);
                     94:     qdict_iter(qdict, print_balloon_stat, mon);
                     95:     monitor_printf(mon, "\n");
                     96: }
                     97: 
                     98: /**
                     99:  * do_info_balloon(): Balloon information
                    100:  *
                    101:  * Make an asynchronous request for balloon info.  When the request completes
                    102:  * a QDict will be returned according to the following specification:
                    103:  *
                    104:  * - "actual": current balloon value in bytes
                    105:  * The following fields may or may not be present:
                    106:  * - "mem_swapped_in": Amount of memory swapped in (bytes)
                    107:  * - "mem_swapped_out": Amount of memory swapped out (bytes)
                    108:  * - "major_page_faults": Number of major faults
                    109:  * - "minor_page_faults": Number of minor faults
                    110:  * - "free_mem": Total amount of free and unused memory (bytes)
                    111:  * - "total_mem": Total amount of available memory (bytes)
                    112:  *
                    113:  * Example:
                    114:  *
                    115:  * { "actual": 1073741824, "mem_swapped_in": 0, "mem_swapped_out": 0,
                    116:  *   "major_page_faults": 142, "minor_page_faults": 239245,
                    117:  *   "free_mem": 1014185984, "total_mem": 1044668416 }
                    118:  */
                    119: int do_info_balloon(Monitor *mon, MonitorCompletion cb, void *opaque)
                    120: {
                    121:     int ret;
                    122: 
                    123:     if (kvm_enabled() && !kvm_has_sync_mmu()) {
                    124:         qerror_report(QERR_KVM_MISSING_CAP, "synchronous MMU", "balloon");
                    125:         return -1;
                    126:     }
                    127: 
                    128:     ret = qemu_balloon_status(cb, opaque);
                    129:     if (!ret) {
                    130:         qerror_report(QERR_DEVICE_NOT_ACTIVE, "balloon");
                    131:         return -1;
                    132:     }
                    133: 
                    134:     return 0;
                    135: }
                    136: 
                    137: /**
                    138:  * do_balloon(): Request VM to change its memory allocation
                    139:  */
                    140: int do_balloon(Monitor *mon, const QDict *params,
                    141:               MonitorCompletion cb, void *opaque)
                    142: {
1.1.1.3 ! root      143:     int64_t target;
1.1       root      144:     int ret;
                    145: 
                    146:     if (kvm_enabled() && !kvm_has_sync_mmu()) {
                    147:         qerror_report(QERR_KVM_MISSING_CAP, "synchronous MMU", "balloon");
                    148:         return -1;
                    149:     }
                    150: 
1.1.1.3 ! root      151:     target = qdict_get_int(params, "value");
        !           152:     if (target <= 0) {
        !           153:         qerror_report(QERR_INVALID_PARAMETER_VALUE, "target", "a size");
        !           154:         return -1;
        !           155:     }
        !           156:     ret = qemu_balloon(target);
1.1       root      157:     if (ret == 0) {
                    158:         qerror_report(QERR_DEVICE_NOT_ACTIVE, "balloon");
                    159:         return -1;
                    160:     }
                    161: 
                    162:     cb(opaque, NULL);
                    163:     return 0;
                    164: }

unix.superglobalmegacorp.com