On Wed, 12 Jan 2011 10:21:04 -0700, Eric Blake <eblake(a)redhat.com> wrote:
On 01/12/2011 12:56 AM, Nikunj A. Dadhania wrote:
> Here is the patch, now the set calls are also ull.
>
> Still virCgroupGetMemoryUsage is not changed, this will require changes
> in virDomainInfoPtr (info->memory). I am not sure if I should have them
> in this patch.
It can be a separate patch, if desired, but it is probably still needed.
virCgroupGetMemoryUsage is called only from lxcDomainGetInfo, that is
the reason I thought that this change may not be needed.
> +++ 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\n", params[i].field,
> + params[i].value.ul);
Do we want any back-compat considerations? That is, if a newer virsh is
talking to an older server, which still answered INT64_MAX>>10 instead
of the new VIR_DOMAIN_MEMORY_PARAM_UNLIMITED, should we recognize that
situation as another reason to print "unlimited"?
As Mattias suggested in the other mail, this adds more complications. My
take is to have VIR_DOMAIN_MEMORY_PARAM_UNLIMITED as the max value.
Here is the patch which adds setting as well as displaying the
"unlimited" values. Now in virsh to specify "unlimited" the user
would
need to pass "-1"
for example:
virsh # memtune lxcbb1 --hard-limit -1
From: Nikunj A. Dadhania <nikunj(a)linux.vnet.ibm.com>
Display and set unlimited when the memory cgroup settings. Unlimited is
represented by INT64_MAX in memory cgroup.
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 | 93 +++++++++++++++++++++++++++++++-----------
src/util/cgroup.h | 14 +++---
tools/virsh.c | 13 +++++-
6 files changed, 90 insertions(+), 35 deletions(-)
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
/**
* 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..03a1263 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 >> 10;
+
+ 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,12 @@ 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;
+ {
+ if (limit_in_bytes != INT64_MAX)
+ *kb = (unsigned long long) limit_in_bytes >> 10;
+ else
+ *kb = VIR_DOMAIN_MEMORY_PARAM_UNLIMITED;
+ }
return ret;
}
@@ -927,12 +942,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 >> 10;
+
+ 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 +969,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 +977,12 @@ 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;
+ {
+ if (limit_in_bytes != INT64_MAX)
+ *kb = (unsigned long long) limit_in_bytes >> 10;
+ else
+ *kb = VIR_DOMAIN_MEMORY_PARAM_UNLIMITED;
+ }
return ret;
}
@@ -964,12 +994,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 >> 10;
+
+ 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 +1020,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 +1028,12 @@ 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;
+ {
+ if (limit_in_bytes != INT64_MAX)
+ *kb = (unsigned long long) limit_in_bytes >> 10;
+ else
+ *kb = VIR_DOMAIN_MEMORY_PARAM_UNLIMITED;
+ }
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..e855d1d 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 >> 10;
}
if (virDomainSetMemoryParameters(dom, params, nparams, 0) != 0)
vshError(ctl, "%s", _("Unable to change memory
parameters"));