This is an automated email from the git hooks/post-receive script.
tbordaz pushed a commit to branch 389-ds-base-1.4.2
in repository 389-ds-base.
The following commit(s) were added to refs/heads/389-ds-base-1.4.2 by this push:
new 1c3db9c Ticket 50618 - support cgroupv2
1c3db9c is described below
commit 1c3db9c847b355cae1a9ca604564884f23eaae1e
Author: William Brown <william(a)blackhats.net.au>
AuthorDate: Thu Feb 6 14:13:49 2020 +1000
Ticket 50618 - support cgroupv2
Bug Description: fedora 31 changes to cgroup v2 and I expect suse
to do the same soon. We should support this natively as part of
the memory limit detection.
Fix Description: Add support for cgroup v2
https://pagure.io/389-ds-base/issue/50618
Author: William Brown <william(a)blackhats.net.au>
Review by: tbordaz (Thanks!)
---
ldap/servers/slapd/slapi_pal.c | 133 +++++++++++++++++++++++++++++++++++------
1 file changed, 116 insertions(+), 17 deletions(-)
diff --git a/ldap/servers/slapd/slapi_pal.c b/ldap/servers/slapd/slapi_pal.c
index 600d03d..3ae7d12 100644
--- a/ldap/servers/slapd/slapi_pal.c
+++ b/ldap/servers/slapd/slapi_pal.c
@@ -27,6 +27,9 @@
#include <sys/time.h>
#include <sys/resource.h>
+/* directory check */
+#include <dirent.h>
+
#ifdef OS_solaris
#include <sys/procfs.h>
#endif
@@ -35,6 +38,14 @@
#include <sys/pstat.h>
#endif
+#include <sys/param.h>
+
+/* This warns if we have less than 128M avail */
+#define SPAL_WARN_MIN_BYTES 134217728
+
+#define CG2_HEADER_FORMAT "0::"
+#define CG2_HEADER_LEN strlen(CG2_HEADER_FORMAT)
+
static int_fast32_t
_spal_rlimit_get(int resource, uint64_t *soft_limit, uint64_t *hard_limit)
{
@@ -101,6 +112,48 @@ _spal_uint64_t_file_get(char *name, char *prefix, uint64_t *dest)
return retval;
}
+static int_fast32_t
+_spal_dir_exist(char *path)
+{
+ DIR* dir = opendir(path);
+ if (dir) {
+ closedir(dir);
+ return 1;
+ }
+ return 0;
+}
+
+static char *
+_spal_cgroupv2_path() {
+ FILE *f;
+ char s[256] = {0};
+ char *res = NULL;
+ /* We discover our path by looking at /proc/self/cgroup */
+ f = fopen("/proc/self/cgroup", "r");
+ if (!f) {
+ int errsrv = errno;
+ slapi_log_err(SLAPI_LOG_ERR, "_spal_get_uint64_t_file", "Unable to
open file \"/proc/self/cgroup\". errno=%d\n", errsrv);
+ return NULL;
+ }
+
+ if (feof(f) == 0) {
+ if (fgets(s, MAXPATHLEN, f) != NULL) {
+ /* we now have a path in s, and the last byte must be NULL */
+ if ((strlen(s) >= CG2_HEADER_LEN) && strncmp(s, CG2_HEADER_FORMAT,
CG2_HEADER_LEN) == 0) {
+ res = slapi_ch_calloc(1, MAXPATHLEN + 17);
+ snprintf(res, MAXPATHLEN + 16, "/sys/fs/cgroup%s", s +
CG2_HEADER_LEN);
+ /* This always has a new line, so replace it if possible. */
+ size_t nl = strlen(res) - 1;
+ res[nl] = '\0';
+ }
+ }
+ }
+ /* Will return something like
/sys/fs/cgroup/system.slice/system-dirsrv.slice/dirsrv(a)standalone1.service */
+
+ fclose(f);
+ return res;
+}
+
slapi_pal_meminfo *
spal_meminfo_get()
@@ -172,34 +225,73 @@ spal_meminfo_get()
uint64_t cg_mem_usage = 0;
uint64_t cg_mem_soft_avail = 0;
- char *f_cg_soft = "/sys/fs/cgroup/memory/memory.soft_limit_in_bytes";
- char *f_cg_hard = "/sys/fs/cgroup/memory/memory.limit_in_bytes";
- char *f_cg_usage = "/sys/fs/cgroup/memory/memory.usage_in_bytes";
+ /* We have cgroup v1, so attempt to use it. */
+ if (_spal_dir_exist("/sys/fs/cgroup/memory")) {
+ char *f_cg_soft = "/sys/fs/cgroup/memory/memory.soft_limit_in_bytes";
+ char *f_cg_hard = "/sys/fs/cgroup/memory/memory.limit_in_bytes";
+ char *f_cg_usage = "/sys/fs/cgroup/memory/memory.usage_in_bytes";
+ slapi_log_err(SLAPI_LOG_INFO, "spal_meminfo_get", "Found cgroup
v1\n");
- if (_spal_uint64_t_file_get(f_cg_soft, NULL, &cg_mem_soft)) {
- slapi_log_err(SLAPI_LOG_WARNING, "spal_meminfo_get", "Unable to
retrieve %s. There may be no cgroup support on this platform\n", f_cg_soft);
- }
+ if (_spal_uint64_t_file_get(f_cg_soft, NULL, &cg_mem_soft)) {
+ slapi_log_err(SLAPI_LOG_WARNING, "spal_meminfo_get", "Unable
to retrieve %s. There may be no cgroup support on this platform\n", f_cg_soft);
+ }
- if (_spal_uint64_t_file_get(f_cg_hard, NULL, &cg_mem_hard)) {
- slapi_log_err(SLAPI_LOG_WARNING, "spal_meminfo_get", "Unable to
retrieve %s. There may be no cgroup support on this platform\n", f_cg_hard);
- }
+ if (_spal_uint64_t_file_get(f_cg_hard, NULL, &cg_mem_hard)) {
+ slapi_log_err(SLAPI_LOG_WARNING, "spal_meminfo_get", "Unable
to retrieve %s. There may be no cgroup support on this platform\n", f_cg_hard);
+ }
- if (_spal_uint64_t_file_get(f_cg_usage, NULL, &cg_mem_usage)) {
- slapi_log_err(SLAPI_LOG_WARNING, "spal_meminfo_get", "Unable to
retrieve %s. There may be no cgroup support on this platform\n", f_cg_hard);
+ if (_spal_uint64_t_file_get(f_cg_usage, NULL, &cg_mem_usage)) {
+ slapi_log_err(SLAPI_LOG_WARNING, "spal_meminfo_get", "Unable
to retrieve %s. There may be no cgroup support on this platform\n", f_cg_usage);
+ }
+
+ } else {
+ /* We might have cgroup v2. Attempt to get the controller path ... */
+ char *ctrlpath = _spal_cgroupv2_path();
+ if (ctrlpath != NULL) {
+
+ char s[MAXPATHLEN + 33] = {0};
+ slapi_log_err(SLAPI_LOG_INFO, "spal_meminfo_get", "Found
cgroup v2 -> %s\n", ctrlpath);
+ /* There are now three files we care about - memory.current, memory.high and
memory.max */
+ /* For simplicity we re-use soft and hard */
+ /* If _spal_uint64_t_file_get() hit's "max" then these remain
at 0 */
+ snprintf(s, MAXPATHLEN + 32, "%s/memory.current", ctrlpath);
+ if (_spal_uint64_t_file_get(s, NULL, &cg_mem_usage)) {
+ slapi_log_err(SLAPI_LOG_WARNING, "spal_meminfo_get",
"Unable to retrieve %s. There may be no cgroup support on this platform\n", s);
+ }
+
+ snprintf(s, MAXPATHLEN + 32, "%s/memory.high", ctrlpath);
+ if (_spal_uint64_t_file_get(s, NULL, &cg_mem_soft)) {
+ slapi_log_err(SLAPI_LOG_WARNING, "spal_meminfo_get",
"Unable to retrieve %s. There may be no cgroup support on this platform\n", s);
+ }
+
+ snprintf(s, MAXPATHLEN + 32, "%s/memory.max", ctrlpath);
+ if (_spal_uint64_t_file_get(s, NULL, &cg_mem_hard)) {
+ slapi_log_err(SLAPI_LOG_WARNING, "spal_meminfo_get",
"Unable to retrieve %s. There may be no cgroup support on this platform\n", s);
+ }
+
+ slapi_ch_free_string(&ctrlpath);
+ } else {
+ slapi_log_err(SLAPI_LOG_WARNING, "spal_meminfo_get", "cgroups
v1 or v2 unable to be read - may not be on this platform ...\n");
+ }
}
/*
* In some conditions, like docker, we only have a *hard* limit set.
* This obviously breaks our logic, so we need to make sure we correct this
*/
-
- if (cg_mem_hard != 0 && cg_mem_soft != 0 && cg_mem_hard <
cg_mem_soft) {
- /* Right, we only have a hard limit. Impose a 10% watermark. */
- cg_mem_soft = cg_mem_hard * 0.9;
+ if ((cg_mem_hard != 0 && cg_mem_soft == 0) || (cg_mem_hard < cg_mem_soft))
{
+ /* Right, we only have a hard limit. Impose a 20% watermark. */
+ cg_mem_soft = cg_mem_hard * 0.8;
}
- if (cg_mem_soft != 0 && cg_mem_usage != 0 && cg_mem_soft >
cg_mem_usage) {
- cg_mem_soft_avail = cg_mem_soft - cg_mem_usage;
+ if (cg_mem_usage != 0 && (cg_mem_soft != 0 || cg_mem_hard != 0)) {
+ if (cg_mem_soft > cg_mem_usage) {
+ cg_mem_soft_avail = cg_mem_soft - cg_mem_usage;
+ } else if (cg_mem_hard > cg_mem_usage) {
+ cg_mem_soft_avail = cg_mem_hard - cg_mem_usage;
+ } else {
+ slapi_log_err(SLAPI_LOG_CRIT, "spal_meminfo_get", "Your cgroup
memory usage exceeds your hard limit?");
+ }
}
@@ -253,6 +345,13 @@ spal_meminfo_get()
return NULL;
}
+ if (mi->system_available_bytes < SPAL_WARN_MIN_BYTES) {
+ slapi_log_err(SLAPI_LOG_CRIT, "spal_meminfo_get", "Your system is
reporting %" PRIu64" bytes available, which is less than the minimum recommended
%" PRIu64 " bytes\n",
+ mi->system_available_bytes, SPAL_WARN_MIN_BYTES);
+ slapi_log_err(SLAPI_LOG_CRIT, "spal_meminfo_get", "This indicates
heavy memory pressure or incorrect system resource allocation\n");
+ slapi_log_err(SLAPI_LOG_CRIT, "spal_meminfo_get", "Directory
Server *may* crash as a result!!!\n");
+ }
+
slapi_log_err(SLAPI_LOG_TRACE, "spal_meminfo_get", "{pagesize_bytes =
%" PRIu64 ", system_total_pages = %" PRIu64 ", system_total_bytes =
%" PRIu64 ", process_consumed_pages = %" PRIu64 ",
process_consumed_bytes = %" PRIu64 ", system_available_pages = %" PRIu64
", system_available_bytes = %" PRIu64 "},\n",
mi->pagesize_bytes, mi->system_total_pages,
mi->system_total_bytes, mi->process_consumed_pages, mi->process_consumed_bytes,
mi->system_available_pages, mi->system_available_bytes);
--
To stop receiving notification emails like this one, please contact
the administrator of this repository.