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

#include "sysemu.h"
#include "monitor.h"
#include "qjson.h"
#include "qint.h"
#include "cpu-common.h"
#include "kvm.h"
#include "balloon.h"
#include "trace.h"


static QEMUBalloonEvent *qemu_balloon_event;
void *qemu_balloon_event_opaque;

void qemu_add_balloon_handler(QEMUBalloonEvent *func, void *opaque)
{
    qemu_balloon_event = func;
    qemu_balloon_event_opaque = opaque;
}

int qemu_balloon(ram_addr_t target, MonitorCompletion cb, void *opaque)
{
    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 {
        return 0;
    }
}

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 {
        return 0;
    }
}

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

    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)
{
    QDict *qdict;

    qdict = qobject_to_qdict(data);
    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);
    monitor_printf(mon, "\n");
}

/**
 * do_info_balloon(): Balloon information
 *
 * Make an asynchronous request for balloon info.  When the request completes
 * a QDict will be returned according to the following specification:
 *
 * - "actual": current balloon value in bytes
 * The following fields may or may not be present:
 * - "mem_swapped_in": Amount of memory swapped in (bytes)
 * - "mem_swapped_out": Amount of memory swapped out (bytes)
 * - "major_page_faults": Number of major faults
 * - "minor_page_faults": Number of minor faults
 * - "free_mem": Total amount of free and unused memory (bytes)
 * - "total_mem": Total amount of available memory (bytes)
 *
 * Example:
 *
 * { "actual": 1073741824, "mem_swapped_in": 0, "mem_swapped_out": 0,
 *   "major_page_faults": 142, "minor_page_faults": 239245,
 *   "free_mem": 1014185984, "total_mem": 1044668416 }
 */
int do_info_balloon(Monitor *mon, MonitorCompletion cb, void *opaque)
{
    int ret;

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

    ret = qemu_balloon_status(cb, opaque);
    if (!ret) {
        qerror_report(QERR_DEVICE_NOT_ACTIVE, "balloon");
        return -1;
    }

    return 0;
}

/**
 * do_balloon(): Request VM to change its memory allocation
 */
int do_balloon(Monitor *mon, const QDict *params,
	       MonitorCompletion cb, void *opaque)
{
    int ret;

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

    ret = qemu_balloon(qdict_get_int(params, "value"), cb, opaque);
    if (ret == 0) {
        qerror_report(QERR_DEVICE_NOT_ACTIVE, "balloon");
        return -1;
    }

    cb(opaque, NULL);
    return 0;
}
