+++ /dev/null
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: Wolfgang Bumiller <w.bumiller@proxmox.com>
-Date: Thu, 8 Jul 2021 12:04:05 +0200
-Subject: [PATCH lxcfs] make meminfo and swaps cgroupv2 aware
-
-and deduplicate the corresponding code
-
-Signed-off-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
----
- src/bindings.c | 10 ++++++
- src/bindings.h | 1 +
- src/proc_fuse.c | 89 +++++++++++++++++++++++++------------------------
- 3 files changed, 57 insertions(+), 43 deletions(-)
-
-diff --git a/src/bindings.c b/src/bindings.c
-index eb62ddb..e417a13 100644
---- a/src/bindings.c
-+++ b/src/bindings.c
-@@ -44,6 +44,7 @@ static bool can_use_pidfd;
- static bool can_use_swap;
- static bool can_use_sys_cpu;
- static bool has_versioned_opts;
-+static bool memory_is_cgroupv2;
-
- static volatile sig_atomic_t reload_successful;
-
-@@ -67,6 +68,11 @@ bool liblxcfs_has_versioned_opts(void)
- return has_versioned_opts;
- }
-
-+bool liblxcfs_memory_is_cgroupv2(void)
-+{
-+ return memory_is_cgroupv2;
-+}
-+
- /* Define pivot_root() if missing from the C library */
- #ifndef HAVE_PIVOT_ROOT
- static int pivot_root(const char *new_root, const char *put_old)
-@@ -837,6 +843,7 @@ static void __attribute__((constructor)) lxcfs_init(void)
- pidfd = -EBADF;
- int i = 0;
- pid_t pid;
-+ struct hierarchy *hierarchy;
-
- lxcfs_info("Running constructor %s to reload liblxcfs", __func__);
-
-@@ -894,6 +901,9 @@ static void __attribute__((constructor)) lxcfs_init(void)
- else
- lxcfs_info("Kernel does not support swap accounting");
-
-+ hierarchy = cgroup_ops->get_hierarchy(cgroup_ops, "memory");
-+ memory_is_cgroupv2 = hierarchy && is_unified_hierarchy(hierarchy);
-+
- lxcfs_info("api_extensions:");
- for (size_t nr = 0; nr < nr_api_extensions; nr++)
- lxcfs_info("- %s", api_extensions[nr]);
-diff --git a/src/bindings.h b/src/bindings.h
-index cd7d466..2b7c8f4 100644
---- a/src/bindings.h
-+++ b/src/bindings.h
-@@ -98,6 +98,7 @@ extern void prune_init_slice(char *cg);
- extern bool supports_pidfd(void);
- extern bool liblxcfs_functional(void);
- extern bool liblxcfs_can_use_swap(void);
-+extern bool liblxcfs_memory_is_cgroupv2(void);
- extern bool liblxcfs_can_use_sys_cpu(void);
- extern bool liblxcfs_has_versioned_opts(void);
-
-diff --git a/src/proc_fuse.c b/src/proc_fuse.c
-index 94168c9..a07e8d6 100644
---- a/src/proc_fuse.c
-+++ b/src/proc_fuse.c
-@@ -299,6 +299,43 @@ static inline bool startswith(const char *line, const char *pref)
- return strncmp(line, pref, strlen(pref)) == 0;
- }
-
-+static void get_swap_info(const char *cgroup, uint64_t memlimit,
-+ uint64_t memusage, uint64_t *swtotal,
-+ uint64_t *swusage, uint64_t *memswpriority)
-+{
-+ __do_free char *memswusage_str = NULL, *memswpriority_str = NULL;
-+ size_t memswlimit = 0, memswusage = 0;
-+ int ret;
-+
-+ *swtotal = *swusage = 0;
-+ *memswpriority = 1;
-+
-+ memswlimit = get_min_memlimit(cgroup, true);
-+ if (memswlimit > 0) {
-+ ret = cgroup_ops->get_memory_swap_current(cgroup_ops, cgroup, &memswusage_str);
-+ if (ret < 0 || safe_uint64(memswusage_str, &memswusage, 10) != 0)
-+ return;
-+
-+ if (liblxcfs_memory_is_cgroupv2()) {
-+ *swtotal = memswlimit / 1024;
-+ *swusage = memswusage / 1024;
-+ } else {
-+ if (memlimit > memswlimit)
-+ *swtotal = 0;
-+ else
-+ *swtotal = (memswlimit - memlimit) / 1024;
-+ if (memusage > memswusage || swtotal == 0)
-+ *swusage = 0;
-+ else
-+ *swusage = (memswusage - memusage) / 1024;
-+ }
-+
-+ ret = cgroup_ops->get_memory_swappiness(cgroup_ops, cgroup, &memswpriority_str);
-+ if (ret >= 0)
-+ safe_uint64(memswpriority_str, memswpriority, 10);
-+ }
-+}
-+
- static int proc_swaps_read(char *buf, size_t size, off_t offset,
- struct fuse_file_info *fi)
- {
-@@ -307,7 +344,7 @@ static int proc_swaps_read(char *buf, size_t size, off_t offset,
- struct fuse_context *fc = fuse_get_context();
- bool wants_swap = lxcfs_has_opt(fuse_get_context()->private_data, LXCFS_SWAP_ON);
- struct file_info *d = INTTYPE_TO_PTR(fi->fh);
-- uint64_t memswlimit = 0, memlimit = 0, memusage = 0, memswusage = 0,
-+ uint64_t memlimit = 0, memusage = 0,
- swtotal = 0, swusage = 0, memswpriority = 1,
- hostswtotal = 0, hostswfree = 0;
- ssize_t total_len = 0;
-@@ -353,26 +390,8 @@ static int proc_swaps_read(char *buf, size_t size, off_t offset,
- if (safe_uint64(memusage_str, &memusage, 10) < 0)
- lxcfs_error("Failed to convert memusage %s", memusage_str);
-
-- if (wants_swap) {
-- memswlimit = get_min_memlimit(cgroup, true);
-- if (memswlimit > 0) {
-- ret = cgroup_ops->get_memory_swap_current(cgroup_ops, cgroup, &memswusage_str);
-- if (ret >= 0 && safe_uint64(memswusage_str, &memswusage, 10) == 0) {
-- if (memlimit > memswlimit)
-- swtotal = 0;
-- else
-- swtotal = (memswlimit - memlimit) / 1024;
-- if (memusage > memswusage || swtotal == 0)
-- swusage = 0;
-- else
-- swusage = (memswusage - memusage) / 1024;
-- }
--
-- ret = cgroup_ops->get_memory_swappiness(cgroup_ops, cgroup, &memswpriority_str);
-- if (ret >= 0)
-- safe_uint64(memswpriority_str, &memswpriority, 10);
-- }
-- }
-+ if (wants_swap)
-+ get_swap_info(cgroup, memlimit, memusage, &swtotal, &swusage, &memswpriority);
-
- total_len = snprintf(d->buf, d->size, "Filename\t\t\t\tType\t\tSize\tUsed\tPriority\n");
-
-@@ -1141,7 +1160,7 @@ static int proc_meminfo_read(char *buf, size_t size, off_t offset,
- struct fuse_context *fc = fuse_get_context();
- bool wants_swap = lxcfs_has_opt(fuse_get_context()->private_data, LXCFS_SWAP_ON);
- struct file_info *d = INTTYPE_TO_PTR(fi->fh);
-- uint64_t memlimit = 0, memusage = 0, memswlimit = 0, memswusage = 0,
-+ uint64_t memlimit = 0, memusage = 0,
- hosttotal = 0, swfree = 0, swusage = 0, swtotal = 0,
- memswpriority = 1;
- struct memory_stat mstat = {};
-@@ -1193,26 +1212,8 @@ static int proc_meminfo_read(char *buf, size_t size, off_t offset,
- * Following values are allowed to fail, because swapaccount might be
- * turned off for current kernel.
- */
-- if (wants_swap) {
-- memswlimit = get_min_memlimit(cgroup, true);
-- if (memswlimit > 0) {
-- ret = cgroup_ops->get_memory_swap_current(cgroup_ops, cgroup, &memswusage_str);
-- if (ret >= 0 && safe_uint64(memswusage_str, &memswusage, 10) == 0) {
-- if (memlimit > memswlimit)
-- swtotal = 0;
-- else
-- swtotal = (memswlimit - memlimit) / 1024;
-- if (memusage > memswusage || swtotal == 0)
-- swusage = 0;
-- else
-- swusage = (memswusage - memusage) / 1024;
-- }
-- }
--
-- ret = cgroup_ops->get_memory_swappiness(cgroup_ops, cgroup, &memswpriority_str);
-- if (ret >= 0)
-- safe_uint64(memswpriority_str, &memswpriority, 10);
-- }
-+ if (wants_swap)
-+ get_swap_info(cgroup, memlimit, memusage, &swtotal, &swusage, &memswpriority);
-
- f = fopen_cached("/proc/meminfo", "re", &fopen_cache);
- if (!f)
-@@ -1251,7 +1252,9 @@ static int proc_meminfo_read(char *buf, size_t size, off_t offset,
- This is because the kernel can swap as much as it
- wants and not only up to swtotal. */
-
-- swtotal = memlimit + swtotal;
-+ if (!liblxcfs_memory_is_cgroupv2())
-+ swtotal += memlimit;
-+
- if (hostswtotal < swtotal) {
- swtotal = hostswtotal;
- }