The last vestige of the inaccurate 'kilobytes' when we meant 1024 is
now gone. And virsh is now useful for setting memory in units other
than KiB.
* tools/virsh.c (cmdSetmem, cmdSetmaxmem): Use new helper routine,
allow passing bogus arguments on to hypervisor to test driver
sanity checking, and fix leak on parse error.
(cmdMemtuneGetSize): New helper.
(cmdMemtune): Use it.
* tools/virsh.pod (setmem, setmaxmem, memtune): Document this.
---
v2: new
tools/virsh.c | 110 +--
tools/virsh.pod | 48
2 files changed, 90 insertions(+), 68 deletions(-)
diff --git a/tools/virsh.c b/tools/virsh.c
index d5cc46b..b93706f 100644
--- a/tools/virsh.c
+++ b/tools/virsh.c
@@ -5668,7 +5668,7 @@ cleanup:
}
/*
- * setmemory command
+ * setmem command
*/
static const vshCmdInfo info_setmem[] = {
{help, N_(change memory allocation)},
@@ -5678,7 +5678,9 @@ static const vshCmdInfo info_setmem[] = {
static const vshCmdOptDef opts_setmem[] = {
{domain, VSH_OT_DATA, VSH_OFLAG_REQ, N_(domain name, id or uuid)},
-{kilobytes, VSH_OT_INT, VSH_OFLAG_REQ, N_(number of kilobytes of
memory)},
+{kilobytes, VSH_OT_ALIAS, 0, size},
+{size, VSH_OT_INT, VSH_OFLAG_REQ,
+ N_(new memory size, as scaled integer (default KiB))},
{config, VSH_OT_BOOL, 0, N_(affect next boot)},
{live, VSH_OT_BOOL, 0, N_(affect running domain)},
{current, VSH_OT_BOOL, 0, N_(affect current domain)},
@@ -5689,8 +5691,9 @@ static bool
cmdSetmem(vshControl *ctl, const vshCmd *cmd)
{
virDomainPtr dom;
-virDomainInfo info;
-unsigned long kilobytes = 0;
+unsigned long long bytes = 0;
+unsigned long long max;
+unsigned long kibibytes = 0;
bool ret = true;
int config = vshCommandOptBool(cmd, config);
int live = vshCommandOptBool(cmd, live);
@@ -5719,36 +5722,25 @@ cmdSetmem(vshControl *ctl, const vshCmd *cmd)
if (!(dom = vshCommandOptDomain(ctl, cmd, NULL)))
return false;
-if (vshCommandOptUL(cmd, kilobytes, kilobytes) 0) {
+/* The API expects 'unsigned long' KiB, so depending on whether we
+ * are 32-bit or 64-bit determines the maximum we can use. */
+if (sizeof(kibibytes) sizeof(max))
+max = 1024ull * ULONG_MAX;
+else
+max = ULONG_MAX;
+if (vshCommandOptScaledInt(cmd, size, bytes, 1024, max) 0) {
vshError(ctl, %s, _(memory size has to be a number));
-return false;
-}
-
-if (kilobytes = 0) {
-virDomainFree(dom);
-vshError(ctl, _(Invalid value of %lu for memory size), kilobytes);
-return false;
-}
-
-if (virDomainGetInfo(dom, info) != 0) {
virDomainFree(dom);
-vshError(ctl, %s, _(Unable to verify MaxMemorySize));
-return false;
-}
-
-if (kilobytes info.maxMem) {
-virDomainFree(dom);
-vshError(ctl, _(Requested memory size %lu kb is larger than maximum
of %lu kb),
- kilobytes, info.maxMem);
return false;
}
+kibibytes = VIR_DIV_UP(bytes, 1024);
if (flags == -1) {
-if (virDomainSetMemory(dom, kilobytes) != 0) {
+if (virDomainSetMemory(dom, kibibytes) != 0) {
ret = false;
}
} else {
-if (virDomainSetMemoryFlags(dom, kilobytes, flags) 0) {
+if (virDomainSetMemoryFlags(dom, kibibytes, flags) 0) {
ret = false;
}
}
@@ -5768,7 +5760,9 @@ static const vshCmdInfo info_setmaxmem[] = {
static const vshCmdOptDef opts_setmaxmem[] = {
{domain, VSH_OT_DATA, VSH_OFLAG_REQ, N_(domain name, id or uuid)},
-{kilobytes, VSH_OT_INT, VSH_OFLAG_REQ, N_(maximum memory limit in
kilobytes)},
+{kilobytes, VSH_OT_ALIAS, 0, size},
+{size, VSH_OT_INT, VSH_OFLAG_REQ,
+ N_(new maximum memory size, as scaled integer (default KiB))},
{config, VSH_OT_BOOL, 0, N_(affect next boot)},
{live, VSH_OT_BOOL, 0, N_(affect running domain)},
{current, VSH_OT_BOOL, 0, N_(affect current domain)},
@@ -5779,7 +5773,9 @@ static bool
cmdSetmaxmem(vshControl *ctl, const vshCmd *cmd)
{
virDomainPtr dom;
-int kilobytes = 0;
+unsigned long long bytes = 0;
+unsigned long long max;
+unsigned long kibibytes = 0;
bool ret = true;
int config = vshCommandOptBool(cmd, config);
int live = vshCommandOptBool(cmd, live);
@@ -5807,24 +5803,26 @@ cmdSetmaxmem(vshControl *ctl, const vshCmd *cmd)
if (!(dom = vshCommandOptDomain(ctl, cmd, NULL)))
return false;
-if (vshCommandOptInt(cmd, kilobytes, kilobytes) 0) {
+/* The API expects 'unsigned long' KiB, so depending on whether we
+ * are 32-bit or 64-bit determines the maximum we can use. */
+if (sizeof(kibibytes) sizeof(max))
+max = 1024ull * ULONG_MAX;
+else
+max = ULONG_MAX;
+if (vshCommandOptScaledInt(cmd, size, bytes, 1024, max) 0) {
vshError(ctl, %s, _(memory size has to be a number));
-