Statistics
| Branch: | Revision:

root / balloon.c @ 8af7a3ab

History | View | Annotate | Download (4.3 kB)

1
/*
2
 * QEMU System Emulator
3
 *
4
 * Copyright (c) 2003-2008 Fabrice Bellard
5
 *
6
 * Permission is hereby granted, free of charge, to any person obtaining a copy
7
 * of this software and associated documentation files (the "Software"), to deal
8
 * in the Software without restriction, including without limitation the rights
9
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10
 * copies of the Software, and to permit persons to whom the Software is
11
 * furnished to do so, subject to the following conditions:
12
 *
13
 * The above copyright notice and this permission notice shall be included in
14
 * all copies or substantial portions of the Software.
15
 *
16
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22
 * THE SOFTWARE.
23
 */
24

    
25
#include "sysemu.h"
26
#include "monitor.h"
27
#include "qjson.h"
28
#include "qint.h"
29
#include "cpu-common.h"
30
#include "kvm.h"
31
#include "balloon.h"
32
#include "trace.h"
33

    
34

    
35
static QEMUBalloonEvent *qemu_balloon_event;
36
void *qemu_balloon_event_opaque;
37

    
38
void qemu_add_balloon_handler(QEMUBalloonEvent *func, void *opaque)
39
{
40
    qemu_balloon_event = func;
41
    qemu_balloon_event_opaque = opaque;
42
}
43

    
44
int qemu_balloon(ram_addr_t target, MonitorCompletion cb, void *opaque)
45
{
46
    if (qemu_balloon_event) {
47
        trace_balloon_event(qemu_balloon_event_opaque, target);
48
        qemu_balloon_event(qemu_balloon_event_opaque, target, cb, opaque);
49
        return 1;
50
    } else {
51
        return 0;
52
    }
53
}
54

    
55
int qemu_balloon_status(MonitorCompletion cb, void *opaque)
56
{
57
    if (qemu_balloon_event) {
58
        qemu_balloon_event(qemu_balloon_event_opaque, 0, cb, opaque);
59
        return 1;
60
    } else {
61
        return 0;
62
    }
63
}
64

    
65
static void print_balloon_stat(const char *key, QObject *obj, void *opaque)
66
{
67
    Monitor *mon = opaque;
68

    
69
    if (strcmp(key, "actual"))
70
        monitor_printf(mon, ",%s=%" PRId64, key,
71
                       qint_get_int(qobject_to_qint(obj)));
72
}
73

    
74
void monitor_print_balloon(Monitor *mon, const QObject *data)
75
{
76
    QDict *qdict;
77

    
78
    qdict = qobject_to_qdict(data);
79
    if (!qdict_haskey(qdict, "actual"))
80
        return;
81

    
82
    monitor_printf(mon, "balloon: actual=%" PRId64,
83
                   qdict_get_int(qdict, "actual") >> 20);
84
    qdict_iter(qdict, print_balloon_stat, mon);
85
    monitor_printf(mon, "\n");
86
}
87

    
88
/**
89
 * do_info_balloon(): Balloon information
90
 *
91
 * Make an asynchronous request for balloon info.  When the request completes
92
 * a QDict will be returned according to the following specification:
93
 *
94
 * - "actual": current balloon value in bytes
95
 * The following fields may or may not be present:
96
 * - "mem_swapped_in": Amount of memory swapped in (bytes)
97
 * - "mem_swapped_out": Amount of memory swapped out (bytes)
98
 * - "major_page_faults": Number of major faults
99
 * - "minor_page_faults": Number of minor faults
100
 * - "free_mem": Total amount of free and unused memory (bytes)
101
 * - "total_mem": Total amount of available memory (bytes)
102
 *
103
 * Example:
104
 *
105
 * { "actual": 1073741824, "mem_swapped_in": 0, "mem_swapped_out": 0,
106
 *   "major_page_faults": 142, "minor_page_faults": 239245,
107
 *   "free_mem": 1014185984, "total_mem": 1044668416 }
108
 */
109
int do_info_balloon(Monitor *mon, MonitorCompletion cb, void *opaque)
110
{
111
    int ret;
112

    
113
    if (kvm_enabled() && !kvm_has_sync_mmu()) {
114
        qerror_report(QERR_KVM_MISSING_CAP, "synchronous MMU", "balloon");
115
        return -1;
116
    }
117

    
118
    ret = qemu_balloon_status(cb, opaque);
119
    if (!ret) {
120
        qerror_report(QERR_DEVICE_NOT_ACTIVE, "balloon");
121
        return -1;
122
    }
123

    
124
    return 0;
125
}
126

    
127
/**
128
 * do_balloon(): Request VM to change its memory allocation
129
 */
130
int do_balloon(Monitor *mon, const QDict *params,
131
               MonitorCompletion cb, void *opaque)
132
{
133
    int ret;
134

    
135
    if (kvm_enabled() && !kvm_has_sync_mmu()) {
136
        qerror_report(QERR_KVM_MISSING_CAP, "synchronous MMU", "balloon");
137
        return -1;
138
    }
139

    
140
    ret = qemu_balloon(qdict_get_int(params, "value"), cb, opaque);
141
    if (ret == 0) {
142
        qerror_report(QERR_DEVICE_NOT_ACTIVE, "balloon");
143
        return -1;
144
    }
145

    
146
    cb(opaque, NULL);
147
    return 0;
148
}