On Thu, 13 Jan 2011 09:24:09 +0100, Matthias Bolte <matthias.bolte(a)googlemail.com>
wrote:
2011/1/13 Nikunj A. Dadhania <nikunj(a)linux.vnet.ibm.com>:
[snip]
> diff --git a/include/libvirt/libvirt.h.in
b/include/libvirt/libvirt.h.in
> index 3c6a54a..3ee47b9 100644
> --- a/include/libvirt/libvirt.h.in
> +++ b/include/libvirt/libvirt.h.in
> @@ -696,6 +696,7 @@ typedef enum {
> */
>
> #define VIR_DOMAIN_MEMORY_FIELD_LENGTH 80
> +#define VIR_DOMAIN_MEMORY_PARAM_UNLIMITED INT64_MAX
[snip]
First add a define VIR_DOMAIN_MEMORY_PARAM_UNLIMITED for the magic
value INT64_MAX>>10, but stick to this value, because changing it
could break existing applications.
Second make virsh memtune detect VIR_DOMAIN_MEMORY_PARAM_UNLIMITED and
print "unlimited" in that case instead of the actual numeric value.
Third make virsh memtune accept -1 as unlimited and translate it to
VIR_DOMAIN_MEMORY_PARAM_UNLIMITED.
You already addressed the second and third point in your patch so
we're close to a proper workaround.
Here is one more spin and guess we would be finally there :)
From: Nikunj A. Dadhania <nikunj(a)linux.vnet.ibm.com>
Display or set unlimited values for memory paramters. Unlimited is
represented by INT64_MAX in memory cgroup.
v5: return back to max as (INT64_MAX >> 10) for backward portablity.
v4: Fix handling of setting unlimited values
v3: Make virCgroupSet memory call ull
Signed-off-by: Nikunj A. Dadhania <nikunj(a)linux.vnet.ibm.com>
Reported-by: Justin Clift <jclift(a)redhat.com>
---
include/libvirt/libvirt.h.in | 1 +
src/lxc/lxc_driver.c | 2 +
src/qemu/qemu_driver.c | 2 +
src/util/cgroup.c | 78 +++++++++++++++++++++++++++++-------------
src/util/cgroup.h | 14 ++++----
tools/virsh.c | 13 ++++++-
6 files changed, 75 insertions(+), 35 deletions(-)
diff --git a/include/libvirt/libvirt.h.in b/include/libvirt/libvirt.h.in
index 3c6a54a..055eb2e 100644
--- a/include/libvirt/libvirt.h.in
+++ b/include/libvirt/libvirt.h.in
@@ -696,6 +696,7 @@ typedef enum {
*/
#define VIR_DOMAIN_MEMORY_FIELD_LENGTH 80
+#define VIR_DOMAIN_MEMORY_PARAM_UNLIMITED (INT64_MAX >> 10)
/**
* VIR_DOMAIN_MEMORY_HARD_LIMIT:
diff --git a/src/lxc/lxc_driver.c b/src/lxc/lxc_driver.c
index eb58086..2db9954 100644
--- a/src/lxc/lxc_driver.c
+++ b/src/lxc/lxc_driver.c
@@ -815,7 +815,7 @@ static int lxcDomainGetMemoryParameters(virDomainPtr dom,
int i;
virCgroupPtr cgroup = NULL;
virDomainObjPtr vm = NULL;
- unsigned long val;
+ unsigned long long val;
int ret = -1;
int rc;
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index e915705..6648c6a 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -7077,7 +7077,7 @@ static int qemuDomainGetMemoryParameters(virDomainPtr dom,
int i;
virCgroupPtr group = NULL;
virDomainObjPtr vm = NULL;
- unsigned long val;
+ unsigned long long val;
int ret = -1;
int rc;
diff --git a/src/util/cgroup.c b/src/util/cgroup.c
index 3ba6325..cd9caba 100644
--- a/src/util/cgroup.c
+++ b/src/util/cgroup.c
@@ -355,8 +355,6 @@ static int virCgroupSetValueU64(virCgroupPtr group,
}
-#if 0
-/* This is included for completeness, but not yet used */
static int virCgroupSetValueI64(virCgroupPtr group,
int controller,
@@ -376,6 +374,8 @@ static int virCgroupSetValueI64(virCgroupPtr group,
return rc;
}
+#if 0
+/* This is included for completeness, but not yet used */
static int virCgroupGetValueI64(virCgroupPtr group,
int controller,
const char *key,
@@ -858,12 +858,22 @@ int virCgroupForDomain(virCgroupPtr driver ATTRIBUTE_UNUSED,
*
* Returns: 0 on success
*/
-int virCgroupSetMemory(virCgroupPtr group, unsigned long kb)
+int virCgroupSetMemory(virCgroupPtr group, unsigned long long kb)
{
- return virCgroupSetValueU64(group,
- VIR_CGROUP_CONTROLLER_MEMORY,
- "memory.limit_in_bytes",
- kb << 10);
+ unsigned long long maxkb = VIR_DOMAIN_MEMORY_PARAM_UNLIMITED;
+
+ if (kb > maxkb)
+ return -EINVAL;
+ else if (kb == maxkb)
+ return virCgroupSetValueI64(group,
+ VIR_CGROUP_CONTROLLER_MEMORY,
+ "memory.limit_in_bytes",
+ -1);
+ else
+ return virCgroupSetValueU64(group,
+ VIR_CGROUP_CONTROLLER_MEMORY,
+ "memory.limit_in_bytes",
+ kb << 10);
}
/**
@@ -894,7 +904,7 @@ int virCgroupGetMemoryUsage(virCgroupPtr group, unsigned long *kb)
*
* Returns: 0 on success
*/
-int virCgroupSetMemoryHardLimit(virCgroupPtr group, unsigned long kb)
+int virCgroupSetMemoryHardLimit(virCgroupPtr group, unsigned long long kb)
{
return virCgroupSetMemory(group, kb);
}
@@ -907,7 +917,7 @@ int virCgroupSetMemoryHardLimit(virCgroupPtr group, unsigned long kb)
*
* Returns: 0 on success
*/
-int virCgroupGetMemoryHardLimit(virCgroupPtr group, unsigned long *kb)
+int virCgroupGetMemoryHardLimit(virCgroupPtr group, unsigned long long *kb)
{
long long unsigned int limit_in_bytes;
int ret;
@@ -915,7 +925,7 @@ int virCgroupGetMemoryHardLimit(virCgroupPtr group, unsigned long
*kb)
VIR_CGROUP_CONTROLLER_MEMORY,
"memory.limit_in_bytes", &limit_in_bytes);
if (ret == 0)
- *kb = (unsigned long) limit_in_bytes >> 10;
+ *kb = limit_in_bytes >> 10;
return ret;
}
@@ -927,12 +937,22 @@ int virCgroupGetMemoryHardLimit(virCgroupPtr group, unsigned long
*kb)
*
* Returns: 0 on success
*/
-int virCgroupSetMemorySoftLimit(virCgroupPtr group, unsigned long kb)
+int virCgroupSetMemorySoftLimit(virCgroupPtr group, unsigned long long kb)
{
- return virCgroupSetValueU64(group,
- VIR_CGROUP_CONTROLLER_MEMORY,
- "memory.soft_limit_in_bytes",
- kb << 10);
+ unsigned long long maxkb = VIR_DOMAIN_MEMORY_PARAM_UNLIMITED;
+
+ if (kb > maxkb)
+ return -EINVAL;
+ else if (kb == maxkb)
+ return virCgroupSetValueI64(group,
+ VIR_CGROUP_CONTROLLER_MEMORY,
+ "memory.soft_limit_in_bytes",
+ -1);
+ else
+ return virCgroupSetValueU64(group,
+ VIR_CGROUP_CONTROLLER_MEMORY,
+ "memory.soft_limit_in_bytes",
+ kb << 10);
}
@@ -944,7 +964,7 @@ int virCgroupSetMemorySoftLimit(virCgroupPtr group, unsigned long kb)
*
* Returns: 0 on success
*/
-int virCgroupGetMemorySoftLimit(virCgroupPtr group, unsigned long *kb)
+int virCgroupGetMemorySoftLimit(virCgroupPtr group, unsigned long long *kb)
{
long long unsigned int limit_in_bytes;
int ret;
@@ -952,7 +972,7 @@ int virCgroupGetMemorySoftLimit(virCgroupPtr group, unsigned long
*kb)
VIR_CGROUP_CONTROLLER_MEMORY,
"memory.soft_limit_in_bytes",
&limit_in_bytes);
if (ret == 0)
- *kb = (unsigned long) limit_in_bytes >> 10;
+ *kb = limit_in_bytes >> 10;
return ret;
}
@@ -964,12 +984,22 @@ int virCgroupGetMemorySoftLimit(virCgroupPtr group, unsigned long
*kb)
*
* Returns: 0 on success
*/
-int virCgroupSetSwapHardLimit(virCgroupPtr group, unsigned long kb)
+int virCgroupSetSwapHardLimit(virCgroupPtr group, unsigned long long kb)
{
- return virCgroupSetValueU64(group,
- VIR_CGROUP_CONTROLLER_MEMORY,
- "memory.memsw.limit_in_bytes",
- kb << 10);
+ unsigned long long maxkb = VIR_DOMAIN_MEMORY_PARAM_UNLIMITED;
+
+ if (kb > maxkb)
+ return -EINVAL;
+ else if (kb == maxkb)
+ return virCgroupSetValueI64(group,
+ VIR_CGROUP_CONTROLLER_MEMORY,
+ "memory.memsw.limit_in_bytes",
+ -1);
+ else
+ return virCgroupSetValueU64(group,
+ VIR_CGROUP_CONTROLLER_MEMORY,
+ "memory.memsw.limit_in_bytes",
+ kb << 10);
}
/**
@@ -980,7 +1010,7 @@ int virCgroupSetSwapHardLimit(virCgroupPtr group, unsigned long kb)
*
* Returns: 0 on success
*/
-int virCgroupGetSwapHardLimit(virCgroupPtr group, unsigned long *kb)
+int virCgroupGetSwapHardLimit(virCgroupPtr group, unsigned long long *kb)
{
long long unsigned int limit_in_bytes;
int ret;
@@ -988,7 +1018,7 @@ int virCgroupGetSwapHardLimit(virCgroupPtr group, unsigned long *kb)
VIR_CGROUP_CONTROLLER_MEMORY,
"memory.memsw.limit_in_bytes",
&limit_in_bytes);
if (ret == 0)
- *kb = (unsigned long) limit_in_bytes >> 10;
+ *kb = limit_in_bytes >> 10;
return ret;
}
diff --git a/src/util/cgroup.h b/src/util/cgroup.h
index 9e1c61f..964da7a 100644
--- a/src/util/cgroup.h
+++ b/src/util/cgroup.h
@@ -40,15 +40,15 @@ int virCgroupForDomain(virCgroupPtr driver,
int virCgroupAddTask(virCgroupPtr group, pid_t pid);
-int virCgroupSetMemory(virCgroupPtr group, unsigned long kb);
+int virCgroupSetMemory(virCgroupPtr group, unsigned long long kb);
int virCgroupGetMemoryUsage(virCgroupPtr group, unsigned long *kb);
-int virCgroupSetMemoryHardLimit(virCgroupPtr group, unsigned long kb);
-int virCgroupGetMemoryHardLimit(virCgroupPtr group, unsigned long *kb);
-int virCgroupSetMemorySoftLimit(virCgroupPtr group, unsigned long kb);
-int virCgroupGetMemorySoftLimit(virCgroupPtr group, unsigned long *kb);
-int virCgroupSetSwapHardLimit(virCgroupPtr group, unsigned long kb);
-int virCgroupGetSwapHardLimit(virCgroupPtr group, unsigned long *kb);
+int virCgroupSetMemoryHardLimit(virCgroupPtr group, unsigned long long kb);
+int virCgroupGetMemoryHardLimit(virCgroupPtr group, unsigned long long *kb);
+int virCgroupSetMemorySoftLimit(virCgroupPtr group, unsigned long long kb);
+int virCgroupGetMemorySoftLimit(virCgroupPtr group, unsigned long long *kb);
+int virCgroupSetSwapHardLimit(virCgroupPtr group, unsigned long long kb);
+int virCgroupGetSwapHardLimit(virCgroupPtr group, unsigned long long *kb);
int virCgroupDenyAllDevices(virCgroupPtr group);
diff --git a/tools/virsh.c b/tools/virsh.c
index 55e2a68..f4a0aea 100644
--- a/tools/virsh.c
+++ b/tools/virsh.c
@@ -2987,9 +2987,14 @@ cmdMemtune(vshControl * ctl, const vshCmd * cmd)
params[i].value.l);
break;
case VIR_DOMAIN_MEMORY_PARAM_ULLONG:
- vshPrint(ctl, "%-15s: %llu\n", params[i].field,
- params[i].value.ul);
+ {
+ if (params[i].value.ul == VIR_DOMAIN_MEMORY_PARAM_UNLIMITED)
+ vshPrint(ctl, "%-15s: unlimited\n", params[i].field);
+ else
+ vshPrint(ctl, "%-15s: %llu kB\n", params[i].field,
+ params[i].value.ul);
break;
+ }
case VIR_DOMAIN_MEMORY_PARAM_DOUBLE:
vshPrint(ctl, "%-15s: %f\n", params[i].field,
params[i].value.d);
@@ -3039,6 +3044,10 @@ cmdMemtune(vshControl * ctl, const vshCmd * cmd)
sizeof(temp->field));
min_guarantee = 0;
}
+
+ /* If the user has passed -1, we interpret it as unlimited */
+ if(temp->value.ul == -1)
+ temp->value.ul = VIR_DOMAIN_MEMORY_PARAM_UNLIMITED;
}
if (virDomainSetMemoryParameters(dom, params, nparams, 0) != 0)
vshError(ctl, "%s", _("Unable to change memory
parameters"));