summaryrefslogtreecommitdiffstats
path: root/balloon.c
diff options
context:
space:
mode:
Diffstat (limited to 'balloon.c')
-rw-r--r--balloon.c61
1 files changed, 39 insertions, 22 deletions
diff --git a/balloon.c b/balloon.c
index 248c1b50a9..f56fdc1c4b 100644
--- a/balloon.c
+++ b/balloon.c
@@ -1,7 +1,9 @@
/*
- * QEMU System Emulator
+ * Generic Balloon handlers and management
*
* Copyright (c) 2003-2008 Fabrice Bellard
+ * Copyright (C) 2011 Red Hat, Inc.
+ * Copyright (C) 2011 Amit Shah <amit.shah@redhat.com>
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
@@ -30,44 +32,53 @@
#include "balloon.h"
#include "trace.h"
+static QEMUBalloonEvent *balloon_event_fn;
+static QEMUBalloonStatus *balloon_stat_fn;
+static void *balloon_opaque;
-static QEMUBalloonEvent *qemu_balloon_event;
-void *qemu_balloon_event_opaque;
-
-void qemu_add_balloon_handler(QEMUBalloonEvent *func, void *opaque)
+int qemu_add_balloon_handler(QEMUBalloonEvent *event_func,
+ QEMUBalloonStatus *stat_func, void *opaque)
{
- qemu_balloon_event = func;
- qemu_balloon_event_opaque = opaque;
+ if (balloon_event_fn || balloon_stat_fn || balloon_opaque) {
+ /* We're already registered one balloon handler. How many can
+ * a guest really have?
+ */
+ error_report("Another balloon device already registered");
+ return -1;
+ }
+ balloon_event_fn = event_func;
+ balloon_stat_fn = stat_func;
+ balloon_opaque = opaque;
+ return 0;
}
-int qemu_balloon(ram_addr_t target, MonitorCompletion cb, void *opaque)
+static int qemu_balloon(ram_addr_t target)
{
- if (qemu_balloon_event) {
- trace_balloon_event(qemu_balloon_event_opaque, target);
- qemu_balloon_event(qemu_balloon_event_opaque, target, cb, opaque);
- return 1;
- } else {
+ if (!balloon_event_fn) {
return 0;
}
+ trace_balloon_event(balloon_opaque, target);
+ balloon_event_fn(balloon_opaque, target);
+ return 1;
}
-int qemu_balloon_status(MonitorCompletion cb, void *opaque)
+static int qemu_balloon_status(MonitorCompletion cb, void *opaque)
{
- if (qemu_balloon_event) {
- qemu_balloon_event(qemu_balloon_event_opaque, 0, cb, opaque);
- return 1;
- } else {
+ if (!balloon_stat_fn) {
return 0;
}
+ balloon_stat_fn(balloon_opaque, cb, opaque);
+ return 1;
}
static void print_balloon_stat(const char *key, QObject *obj, void *opaque)
{
Monitor *mon = opaque;
- if (strcmp(key, "actual"))
+ if (strcmp(key, "actual")) {
monitor_printf(mon, ",%s=%" PRId64, key,
qint_get_int(qobject_to_qint(obj)));
+ }
}
void monitor_print_balloon(Monitor *mon, const QObject *data)
@@ -75,9 +86,9 @@ void monitor_print_balloon(Monitor *mon, const QObject *data)
QDict *qdict;
qdict = qobject_to_qdict(data);
- if (!qdict_haskey(qdict, "actual"))
+ if (!qdict_haskey(qdict, "actual")) {
return;
-
+ }
monitor_printf(mon, "balloon: actual=%" PRId64,
qdict_get_int(qdict, "actual") >> 20);
qdict_iter(qdict, print_balloon_stat, mon);
@@ -129,6 +140,7 @@ int do_info_balloon(Monitor *mon, MonitorCompletion cb, void *opaque)
int do_balloon(Monitor *mon, const QDict *params,
MonitorCompletion cb, void *opaque)
{
+ int64_t target;
int ret;
if (kvm_enabled() && !kvm_has_sync_mmu()) {
@@ -136,7 +148,12 @@ int do_balloon(Monitor *mon, const QDict *params,
return -1;
}
- ret = qemu_balloon(qdict_get_int(params, "value"), cb, opaque);
+ target = qdict_get_int(params, "value");
+ if (target <= 0) {
+ qerror_report(QERR_INVALID_PARAMETER_VALUE, "target", "a size");
+ return -1;
+ }
+ ret = qemu_balloon(target);
if (ret == 0) {
qerror_report(QERR_DEVICE_NOT_ACTIVE, "balloon");
return -1;