提交 900c58b7 编写于 作者: P Pavel Hrdina

vircgroup: extract virCgroupV1(Set|Get)Memory*Limit

They all need virCgroupV1GetMemoryUnlimitedKB() so it's easier to
move them in one commit.
Reviewed-by: NFabiano Fidêncio <fidencio@redhat.com>
Reviewed-by: NJán Tomko <jtomko@redhat.com>
Signed-off-by: NPavel Hrdina <phrdina@redhat.com>
上级 e92f8bad
...@@ -630,7 +630,7 @@ virCgroupMakeGroup(virCgroupPtr parent, ...@@ -630,7 +630,7 @@ virCgroupMakeGroup(virCgroupPtr parent,
* *
* Returns 0 on success, -1 on error * Returns 0 on success, -1 on error
*/ */
static int int
virCgroupNew(pid_t pid, virCgroupNew(pid_t pid,
const char *path, const char *path,
virCgroupPtr parent, virCgroupPtr parent,
...@@ -1533,51 +1533,6 @@ virCgroupGetBlkioDeviceWeight(virCgroupPtr group, ...@@ -1533,51 +1533,6 @@ virCgroupGetBlkioDeviceWeight(virCgroupPtr group,
} }
/*
* Retrieve the "memory.limit_in_bytes" value from the memory controller
* root dir. This value cannot be modified by userspace and therefore
* is the maximum limit value supported by cgroups on the local system.
* Returns this value scaled to KB or falls back to the original
* VIR_DOMAIN_MEMORY_PARAM_UNLIMITED. Either way, remember the return
* value to avoid unnecessary cgroup filesystem access.
*/
static unsigned long long int virCgroupMemoryUnlimitedKB;
static virOnceControl virCgroupMemoryOnce = VIR_ONCE_CONTROL_INITIALIZER;
static void
virCgroupMemoryOnceInit(void)
{
virCgroupPtr group;
unsigned long long int mem_unlimited = 0ULL;
if (virCgroupNew(-1, "/", NULL, -1, &group) < 0)
goto cleanup;
if (!virCgroupHasController(group, VIR_CGROUP_CONTROLLER_MEMORY))
goto cleanup;
ignore_value(virCgroupGetValueU64(group,
VIR_CGROUP_CONTROLLER_MEMORY,
"memory.limit_in_bytes",
&mem_unlimited));
cleanup:
virCgroupFree(&group);
virCgroupMemoryUnlimitedKB = mem_unlimited >> 10;
}
static unsigned long long int
virCgroupGetMemoryUnlimitedKB(void)
{
if (virOnce(&virCgroupMemoryOnce, virCgroupMemoryOnceInit) < 0)
VIR_DEBUG("Init failed, will fall back to defaults.");
if (virCgroupMemoryUnlimitedKB)
return virCgroupMemoryUnlimitedKB;
else
return VIR_DOMAIN_MEMORY_PARAM_UNLIMITED;
}
/** /**
* virCgroupSetMemory: * virCgroupSetMemory:
* *
...@@ -1648,7 +1603,7 @@ virCgroupGetMemoryUsage(virCgroupPtr group, unsigned long *kb) ...@@ -1648,7 +1603,7 @@ virCgroupGetMemoryUsage(virCgroupPtr group, unsigned long *kb)
int int
virCgroupSetMemoryHardLimit(virCgroupPtr group, unsigned long long kb) virCgroupSetMemoryHardLimit(virCgroupPtr group, unsigned long long kb)
{ {
return virCgroupSetMemory(group, kb); VIR_CGROUP_BACKEND_CALL(group, setMemoryHardLimit, -1, kb);
} }
...@@ -1663,18 +1618,7 @@ virCgroupSetMemoryHardLimit(virCgroupPtr group, unsigned long long kb) ...@@ -1663,18 +1618,7 @@ virCgroupSetMemoryHardLimit(virCgroupPtr group, unsigned long long kb)
int int
virCgroupGetMemoryHardLimit(virCgroupPtr group, unsigned long long *kb) virCgroupGetMemoryHardLimit(virCgroupPtr group, unsigned long long *kb)
{ {
long long unsigned int limit_in_bytes; VIR_CGROUP_BACKEND_CALL(group, getMemoryHardLimit, -1, kb);
if (virCgroupGetValueU64(group,
VIR_CGROUP_CONTROLLER_MEMORY,
"memory.limit_in_bytes", &limit_in_bytes) < 0)
return -1;
*kb = limit_in_bytes >> 10;
if (*kb >= virCgroupGetMemoryUnlimitedKB())
*kb = VIR_DOMAIN_MEMORY_PARAM_UNLIMITED;
return 0;
} }
...@@ -1689,25 +1633,7 @@ virCgroupGetMemoryHardLimit(virCgroupPtr group, unsigned long long *kb) ...@@ -1689,25 +1633,7 @@ virCgroupGetMemoryHardLimit(virCgroupPtr group, unsigned long long *kb)
int int
virCgroupSetMemorySoftLimit(virCgroupPtr group, unsigned long long kb) virCgroupSetMemorySoftLimit(virCgroupPtr group, unsigned long long kb)
{ {
unsigned long long maxkb = VIR_DOMAIN_MEMORY_PARAM_UNLIMITED; VIR_CGROUP_BACKEND_CALL(group, setMemorySoftLimit, -1, kb);
if (kb > maxkb) {
virReportError(VIR_ERR_INVALID_ARG,
_("Memory '%llu' must be less than %llu"),
kb, maxkb);
return -1;
}
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);
} }
...@@ -1722,18 +1648,7 @@ virCgroupSetMemorySoftLimit(virCgroupPtr group, unsigned long long kb) ...@@ -1722,18 +1648,7 @@ virCgroupSetMemorySoftLimit(virCgroupPtr group, unsigned long long kb)
int int
virCgroupGetMemorySoftLimit(virCgroupPtr group, unsigned long long *kb) virCgroupGetMemorySoftLimit(virCgroupPtr group, unsigned long long *kb)
{ {
long long unsigned int limit_in_bytes; VIR_CGROUP_BACKEND_CALL(group, getMemorySoftLimit, -1, kb);
if (virCgroupGetValueU64(group,
VIR_CGROUP_CONTROLLER_MEMORY,
"memory.soft_limit_in_bytes", &limit_in_bytes) < 0)
return -1;
*kb = limit_in_bytes >> 10;
if (*kb >= virCgroupGetMemoryUnlimitedKB())
*kb = VIR_DOMAIN_MEMORY_PARAM_UNLIMITED;
return 0;
} }
...@@ -1748,25 +1663,7 @@ virCgroupGetMemorySoftLimit(virCgroupPtr group, unsigned long long *kb) ...@@ -1748,25 +1663,7 @@ virCgroupGetMemorySoftLimit(virCgroupPtr group, unsigned long long *kb)
int int
virCgroupSetMemSwapHardLimit(virCgroupPtr group, unsigned long long kb) virCgroupSetMemSwapHardLimit(virCgroupPtr group, unsigned long long kb)
{ {
unsigned long long maxkb = VIR_DOMAIN_MEMORY_PARAM_UNLIMITED; VIR_CGROUP_BACKEND_CALL(group, setMemSwapHardLimit, -1, kb);
if (kb > maxkb) {
virReportError(VIR_ERR_INVALID_ARG,
_("Memory '%llu' must be less than %llu"),
kb, maxkb);
return -1;
}
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);
} }
...@@ -1781,18 +1678,7 @@ virCgroupSetMemSwapHardLimit(virCgroupPtr group, unsigned long long kb) ...@@ -1781,18 +1678,7 @@ virCgroupSetMemSwapHardLimit(virCgroupPtr group, unsigned long long kb)
int int
virCgroupGetMemSwapHardLimit(virCgroupPtr group, unsigned long long *kb) virCgroupGetMemSwapHardLimit(virCgroupPtr group, unsigned long long *kb)
{ {
long long unsigned int limit_in_bytes; VIR_CGROUP_BACKEND_CALL(group, getMemSwapHardLimit, -1, kb);
if (virCgroupGetValueU64(group,
VIR_CGROUP_CONTROLLER_MEMORY,
"memory.memsw.limit_in_bytes", &limit_in_bytes) < 0)
return -1;
*kb = limit_in_bytes >> 10;
if (*kb >= virCgroupGetMemoryUnlimitedKB())
*kb = VIR_DOMAIN_MEMORY_PARAM_UNLIMITED;
return 0;
} }
......
...@@ -227,6 +227,30 @@ typedef int ...@@ -227,6 +227,30 @@ typedef int
(*virCgroupGetMemoryUsageCB)(virCgroupPtr group, (*virCgroupGetMemoryUsageCB)(virCgroupPtr group,
unsigned long *kb); unsigned long *kb);
typedef int
(*virCgroupSetMemoryHardLimitCB)(virCgroupPtr group,
unsigned long long kb);
typedef int
(*virCgroupGetMemoryHardLimitCB)(virCgroupPtr group,
unsigned long long *kb);
typedef int
(*virCgroupSetMemorySoftLimitCB)(virCgroupPtr group,
unsigned long long kb);
typedef int
(*virCgroupGetMemorySoftLimitCB)(virCgroupPtr group,
unsigned long long *kb);
typedef int
(*virCgroupSetMemSwapHardLimitCB)(virCgroupPtr group,
unsigned long long kb);
typedef int
(*virCgroupGetMemSwapHardLimitCB)(virCgroupPtr group,
unsigned long long *kb);
struct _virCgroupBackend { struct _virCgroupBackend {
virCgroupBackendType type; virCgroupBackendType type;
...@@ -269,6 +293,12 @@ struct _virCgroupBackend { ...@@ -269,6 +293,12 @@ struct _virCgroupBackend {
virCgroupSetMemoryCB setMemory; virCgroupSetMemoryCB setMemory;
virCgroupGetMemoryStatCB getMemoryStat; virCgroupGetMemoryStatCB getMemoryStat;
virCgroupGetMemoryUsageCB getMemoryUsage; virCgroupGetMemoryUsageCB getMemoryUsage;
virCgroupSetMemoryHardLimitCB setMemoryHardLimit;
virCgroupGetMemoryHardLimitCB getMemoryHardLimit;
virCgroupSetMemorySoftLimitCB setMemorySoftLimit;
virCgroupGetMemorySoftLimitCB getMemorySoftLimit;
virCgroupSetMemSwapHardLimitCB setMemSwapHardLimit;
virCgroupGetMemSwapHardLimitCB getMemSwapHardLimit;
}; };
typedef struct _virCgroupBackend virCgroupBackend; typedef struct _virCgroupBackend virCgroupBackend;
typedef virCgroupBackend *virCgroupBackendPtr; typedef virCgroupBackend *virCgroupBackendPtr;
......
...@@ -88,6 +88,12 @@ int virCgroupGetValueForBlkDev(virCgroupPtr group, ...@@ -88,6 +88,12 @@ int virCgroupGetValueForBlkDev(virCgroupPtr group,
const char *path, const char *path,
char **value); char **value);
int virCgroupNew(pid_t pid,
const char *path,
virCgroupPtr parent,
int controllers,
virCgroupPtr *group);
int virCgroupNewPartition(const char *path, int virCgroupNewPartition(const char *path,
bool create, bool create,
int controllers, int controllers,
......
...@@ -1377,6 +1377,51 @@ virCgroupV1GetBlkioDeviceWriteBps(virCgroupPtr group, ...@@ -1377,6 +1377,51 @@ virCgroupV1GetBlkioDeviceWriteBps(virCgroupPtr group,
} }
/*
* Retrieve the "memory.limit_in_bytes" value from the memory controller
* root dir. This value cannot be modified by userspace and therefore
* is the maximum limit value supported by cgroups on the local system.
* Returns this value scaled to KB or falls back to the original
* VIR_DOMAIN_MEMORY_PARAM_UNLIMITED. Either way, remember the return
* value to avoid unnecessary cgroup filesystem access.
*/
static unsigned long long int virCgroupV1MemoryUnlimitedKB;
static virOnceControl virCgroupV1MemoryOnce = VIR_ONCE_CONTROL_INITIALIZER;
static void
virCgroupV1MemoryOnceInit(void)
{
virCgroupPtr group;
unsigned long long int mem_unlimited = 0ULL;
if (virCgroupNew(-1, "/", NULL, -1, &group) < 0)
goto cleanup;
if (!virCgroupV1HasController(group, VIR_CGROUP_CONTROLLER_MEMORY))
goto cleanup;
ignore_value(virCgroupGetValueU64(group,
VIR_CGROUP_CONTROLLER_MEMORY,
"memory.limit_in_bytes",
&mem_unlimited));
cleanup:
virCgroupFree(&group);
virCgroupV1MemoryUnlimitedKB = mem_unlimited >> 10;
}
static unsigned long long int
virCgroupV1GetMemoryUnlimitedKB(void)
{
if (virOnce(&virCgroupV1MemoryOnce, virCgroupV1MemoryOnceInit) < 0)
VIR_DEBUG("Init failed, will fall back to defaults.");
if (virCgroupV1MemoryUnlimitedKB)
return virCgroupV1MemoryUnlimitedKB;
else
return VIR_DOMAIN_MEMORY_PARAM_UNLIMITED;
}
static int static int
virCgroupV1SetMemory(virCgroupPtr group, virCgroupV1SetMemory(virCgroupPtr group,
unsigned long long kb) unsigned long long kb)
...@@ -1493,6 +1538,123 @@ virCgroupV1GetMemoryUsage(virCgroupPtr group, ...@@ -1493,6 +1538,123 @@ virCgroupV1GetMemoryUsage(virCgroupPtr group,
} }
static int
virCgroupV1SetMemoryHardLimit(virCgroupPtr group,
unsigned long long kb)
{
return virCgroupV1SetMemory(group, kb);
}
static int
virCgroupV1GetMemoryHardLimit(virCgroupPtr group,
unsigned long long *kb)
{
long long unsigned int limit_in_bytes;
if (virCgroupGetValueU64(group,
VIR_CGROUP_CONTROLLER_MEMORY,
"memory.limit_in_bytes", &limit_in_bytes) < 0)
return -1;
*kb = limit_in_bytes >> 10;
if (*kb >= virCgroupV1GetMemoryUnlimitedKB())
*kb = VIR_DOMAIN_MEMORY_PARAM_UNLIMITED;
return 0;
}
static int
virCgroupV1SetMemorySoftLimit(virCgroupPtr group,
unsigned long long kb)
{
unsigned long long maxkb = VIR_DOMAIN_MEMORY_PARAM_UNLIMITED;
if (kb > maxkb) {
virReportError(VIR_ERR_INVALID_ARG,
_("Memory '%llu' must be less than %llu"),
kb, maxkb);
return -1;
}
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);
}
static int
virCgroupV1GetMemorySoftLimit(virCgroupPtr group,
unsigned long long *kb)
{
long long unsigned int limit_in_bytes;
if (virCgroupGetValueU64(group,
VIR_CGROUP_CONTROLLER_MEMORY,
"memory.soft_limit_in_bytes", &limit_in_bytes) < 0)
return -1;
*kb = limit_in_bytes >> 10;
if (*kb >= virCgroupV1GetMemoryUnlimitedKB())
*kb = VIR_DOMAIN_MEMORY_PARAM_UNLIMITED;
return 0;
}
static int
virCgroupV1SetMemSwapHardLimit(virCgroupPtr group,
unsigned long long kb)
{
unsigned long long maxkb = VIR_DOMAIN_MEMORY_PARAM_UNLIMITED;
if (kb > maxkb) {
virReportError(VIR_ERR_INVALID_ARG,
_("Memory '%llu' must be less than %llu"),
kb, maxkb);
return -1;
}
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);
}
static int
virCgroupV1GetMemSwapHardLimit(virCgroupPtr group,
unsigned long long *kb)
{
long long unsigned int limit_in_bytes;
if (virCgroupGetValueU64(group,
VIR_CGROUP_CONTROLLER_MEMORY,
"memory.memsw.limit_in_bytes", &limit_in_bytes) < 0)
return -1;
*kb = limit_in_bytes >> 10;
if (*kb >= virCgroupV1GetMemoryUnlimitedKB())
*kb = VIR_DOMAIN_MEMORY_PARAM_UNLIMITED;
return 0;
}
virCgroupBackend virCgroupV1Backend = { virCgroupBackend virCgroupV1Backend = {
.type = VIR_CGROUP_BACKEND_TYPE_V1, .type = VIR_CGROUP_BACKEND_TYPE_V1,
...@@ -1533,6 +1695,12 @@ virCgroupBackend virCgroupV1Backend = { ...@@ -1533,6 +1695,12 @@ virCgroupBackend virCgroupV1Backend = {
.setMemory = virCgroupV1SetMemory, .setMemory = virCgroupV1SetMemory,
.getMemoryStat = virCgroupV1GetMemoryStat, .getMemoryStat = virCgroupV1GetMemoryStat,
.getMemoryUsage = virCgroupV1GetMemoryUsage, .getMemoryUsage = virCgroupV1GetMemoryUsage,
.setMemoryHardLimit = virCgroupV1SetMemoryHardLimit,
.getMemoryHardLimit = virCgroupV1GetMemoryHardLimit,
.setMemorySoftLimit = virCgroupV1SetMemorySoftLimit,
.getMemorySoftLimit = virCgroupV1GetMemorySoftLimit,
.setMemSwapHardLimit = virCgroupV1SetMemSwapHardLimit,
.getMemSwapHardLimit = virCgroupV1GetMemSwapHardLimit,
}; };
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册