From eff29c8b287f95962ae86ab97d9db8bd815bf748 Mon Sep 17 00:00:00 2001 From: "Daniel P. Berrange" Date: Wed, 23 Sep 2009 12:35:10 +0100 Subject: [PATCH] Add API for issuing 'balloon' monitor command * src/qemu/qemu_monitor.c, src/qemu/qemu_monitor.h: Add new qemuMonitorSetBalloon() based on existing code in qemudDomainSetMemoryBalloon * src/qemu/qemu_driver.c: Remove use of qemudDomainSetMemoryBalloon() in favour of qemuMonitorSetBalloon(). Fix error code when balloon is not supported --- src/qemu/qemu_driver.c | 56 ++++-------------------------------- src/qemu/qemu_monitor_text.c | 47 ++++++++++++++++++++++++++++++ src/qemu/qemu_monitor_text.h | 2 ++ 3 files changed, 55 insertions(+), 50 deletions(-) diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c index 8e09e0c839..a625583a7a 100644 --- a/src/qemu/qemu_driver.c +++ b/src/qemu/qemu_driver.c @@ -107,9 +107,6 @@ static void qemudShutdownVMDaemon(virConnectPtr conn, static int qemudDomainGetMaxVcpus(virDomainPtr dom); -static int qemudDomainSetMemoryBalloon(virConnectPtr conn, - virDomainObjPtr vm, - unsigned long newmem); static int qemuDetectVcpuPIDs(virConnectPtr conn, virDomainObjPtr vm); @@ -2137,7 +2134,7 @@ static int qemudStartVMDaemon(virConnectPtr conn, (qemuDetectVcpuPIDs(conn, vm) < 0) || (qemudInitCpus(conn, vm, migrateFrom) < 0) || (qemuInitPasswords(driver, vm) < 0) || - (qemudDomainSetMemoryBalloon(conn, vm, vm->def->memory) < 0) || + (qemuMonitorSetBalloon(vm, vm->def->memory) < 0) || (virDomainSaveStatus(conn, driver->stateDir, vm) < 0)) { qemudShutdownVMDaemon(conn, driver, vm); ret = -1; @@ -2999,50 +2996,6 @@ cleanup: } -/* - * Returns: 0 if balloon not supported, +1 if balloon query worked - * or -1 on failure - */ -static int qemudDomainSetMemoryBalloon(virConnectPtr conn, - virDomainObjPtr vm, - unsigned long newmem) { - char *cmd; - char *reply = NULL; - int ret = -1; - - /* - * 'newmem' is in KB, QEMU monitor works in MB, and we all wish - * we just worked in bytes with unsigned long long everywhere. - */ - if (virAsprintf(&cmd, "balloon %lu", (newmem / 1024)) < 0) { - virReportOOMError(conn); - goto cleanup; - } - - if (qemudMonitorCommand(vm, cmd, &reply) < 0) { - qemudReportError(conn, dom, NULL, VIR_ERR_OPERATION_FAILED, - "%s", _("could not balloon memory allocation")); - VIR_FREE(cmd); - goto cleanup; - } - VIR_FREE(cmd); - - /* If the command failed qemu prints: 'unknown command' - * No message is printed on success it seems */ - DEBUG ("%s: balloon reply: %s",vm->def->name, reply); - if (strstr(reply, "\nunknown command:")) { - /* Don't set error - it is expected memory balloon fails on many qemu */ - ret = 0; - } else { - ret = 1; - } - -cleanup: - VIR_FREE(reply); - return ret; -} - - static int qemudDomainSetMemory(virDomainPtr dom, unsigned long newmem) { struct qemud_driver *driver = dom->conn->privateData; virDomainObjPtr vm; @@ -3066,10 +3019,13 @@ static int qemudDomainSetMemory(virDomainPtr dom, unsigned long newmem) { } if (virDomainIsActive(vm)) { - ret = qemudDomainSetMemoryBalloon(dom->conn, vm, newmem); - if (ret == 0) + ret = qemuMonitorSetBalloon(vm, newmem); + /* Turn lack of balloon support into a fatal error */ + if (ret == 0) { qemudReportError(dom->conn, dom, NULL, VIR_ERR_NO_SUPPORT, "%s", _("cannot set memory of an active domain")); + ret = -1; + } } else { vm->def->memory = newmem; ret = 0; diff --git a/src/qemu/qemu_monitor_text.c b/src/qemu/qemu_monitor_text.c index 518b7c826a..2bca58fae7 100644 --- a/src/qemu/qemu_monitor_text.c +++ b/src/qemu/qemu_monitor_text.c @@ -551,6 +551,10 @@ error: /* The reply from QEMU contains 'ballon: actual=421' where value is in MB */ #define BALLOON_PREFIX "balloon: actual=" +/* + * Returns: 0 if balloon not supported, +1 if balloon query worked + * or -1 on failure + */ int qemuMonitorGetBalloonInfo(const virDomainObjPtr vm, unsigned long *currmem) { @@ -604,3 +608,46 @@ int qemuMonitorSetVNCPassword(const virDomainObjPtr vm, VIR_FREE(info); return 0; } + +/* + * Returns: 0 if balloon not supported, +1 if balloon adjust worked + * or -1 on failure + */ +int qemuMonitorSetBalloon(const virDomainObjPtr vm, + unsigned long newmem) +{ + char *cmd; + char *reply = NULL; + int ret = -1; + + /* + * 'newmem' is in KB, QEMU monitor works in MB, and we all wish + * we just worked in bytes with unsigned long long everywhere. + */ + if (virAsprintf(&cmd, "balloon %lu", (newmem / 1024)) < 0) { + virReportOOMError(NULL); + return -1; + } + + if (qemudMonitorCommand(vm, cmd, &reply) < 0) { + qemudReportError(NULL, NULL, NULL, VIR_ERR_OPERATION_FAILED, + "%s", _("could not balloon memory allocation")); + VIR_FREE(cmd); + return -1; + } + VIR_FREE(cmd); + + /* If the command failed qemu prints: 'unknown command' + * No message is printed on success it seems */ + DEBUG ("%s: balloon reply: %s", vm->def->name, reply); + if (strstr(reply, "\nunknown command:")) { + /* Don't set error - it is expected memory balloon fails on many qemu */ + ret = 0; + } else { + ret = 1; + } + + VIR_FREE(reply); + return ret; +} + diff --git a/src/qemu/qemu_monitor_text.h b/src/qemu/qemu_monitor_text.h index 30a69cf9f1..6328fbbba7 100644 --- a/src/qemu/qemu_monitor_text.h +++ b/src/qemu/qemu_monitor_text.h @@ -78,5 +78,7 @@ int qemuMonitorGetBalloonInfo(const virDomainObjPtr vm, int qemuMonitorSetVNCPassword(const virDomainObjPtr vm, const char *password); +int qemuMonitorSetBalloon(const virDomainObjPtr vm, + unsigned long newmem); #endif /* QEMU_MONITOR_TEXT_H */ -- GitLab