+++ /dev/null
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: Wolfgang Bumiller <w.bumiller@proxmox.com>
-Date: Thu, 8 Jul 2021 12:54:01 +0200
-Subject: [PATCH lxcfs] delay check for swap accounting
-
-Signed-off-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
----
- src/bindings.c | 20 ++++++++++----------
- src/bindings.h | 2 +-
- src/cgroups/cgfsng.c | 13 ++++++++++---
- src/cgroups/cgroup.h | 2 +-
- src/proc_fuse.c | 8 ++++++--
- 5 files changed, 28 insertions(+), 17 deletions(-)
-
-diff --git a/src/bindings.c b/src/bindings.c
-index 6f395fb..b169af4 100644
---- a/src/bindings.c
-+++ b/src/bindings.c
-@@ -57,7 +57,8 @@
- #include "utils.h"
-
- static bool can_use_pidfd;
--static bool can_use_swap;
-+static int can_use_swap = -1;
-+struct cgroup_ops *cgroup_ops;
-
- static volatile sig_atomic_t reload_successful;
-
-@@ -66,8 +67,15 @@ bool liblxcfs_functional(void)
- return reload_successful != 0;
- }
-
--bool liblxcfs_can_use_swap(void)
-+bool liblxcfs_can_use_swap(const char *cgroup)
- {
-+ if (can_use_swap < 0) {
-+ can_use_swap = cgroup_ops->can_use_swap(cgroup_ops, cgroup);
-+ if (can_use_swap > 0)
-+ lxcfs_info("Kernel supports swap accounting");
-+ else if (can_use_swap == 0)
-+ lxcfs_info("Kernel does not support swap accounting");
-+ }
- return can_use_swap;
- }
-
-@@ -120,8 +128,6 @@ static void mutex_lock(pthread_mutex_t *l)
- log_exit("%s - returned %d\n", strerror(ret), ret);
- }
-
--struct cgroup_ops *cgroup_ops;
--
- static void mutex_unlock(pthread_mutex_t *l)
- {
- int ret;
-@@ -892,12 +898,6 @@ static void __attribute__((constructor)) lxcfs_init(void)
- lxcfs_info("Kernel supports pidfds");
- }
-
-- can_use_swap = cgroup_ops->can_use_swap(cgroup_ops);
-- if (can_use_swap)
-- lxcfs_info("Kernel supports swap accounting");
-- else
-- lxcfs_info("Kernel does not support swap accounting");
--
- lxcfs_info("api_extensions:");
- for (i = 0; i < nr_api_extensions; i++)
- lxcfs_info("- %s", api_extensions[i]);
-diff --git a/src/bindings.h b/src/bindings.h
-index e260902..a334947 100644
---- a/src/bindings.h
-+++ b/src/bindings.h
-@@ -91,7 +91,7 @@ extern pid_t lookup_initpid_in_store(pid_t qpid);
- 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_can_use_swap(const char *cgroup);
-
- static inline int install_signal_handler(int signo,
- void (*handler)(int, siginfo_t *, void *))
-diff --git a/src/cgroups/cgfsng.c b/src/cgroups/cgfsng.c
-index d772f25..8072017 100644
---- a/src/cgroups/cgfsng.c
-+++ b/src/cgroups/cgfsng.c
-@@ -632,7 +632,7 @@ static int cgfsng_get_memory_swap_max(struct cgroup_ops *ops,
- return cgfsng_get_memory(ops, cgroup, "memory.swap.max", value);
- }
-
--static bool cgfsng_can_use_swap(struct cgroup_ops *ops)
-+static bool cgfsng_can_use_swap(struct cgroup_ops *ops, const char *cgroup)
- {
- bool has_swap = false;
- struct hierarchy *h;
-@@ -642,10 +642,17 @@ static bool cgfsng_can_use_swap(struct cgroup_ops *ops)
- return false;
-
- if (is_unified_hierarchy(h)) {
-- if (faccessat(h->fd, "memory.swap.max", F_OK, 0))
-+ __do_free char *path = must_make_path_relative(cgroup, NULL);
-+ __do_close int cgroup_fd = openat_safe(h->fd, path);
-+ if (cgroup_fd < 0) {
-+ lxcfs_error("failed to check for swap accounting, disabling");
-+ return false;
-+ }
-+
-+ if (faccessat(cgroup_fd, "memory.swap.max", F_OK, 0))
- return false;
-
-- if (faccessat(h->fd, "memory.swap.current", F_OK, 0))
-+ if (faccessat(cgroup_fd, "memory.swap.current", F_OK, 0))
- return false;
-
- has_swap = true;
-diff --git a/src/cgroups/cgroup.h b/src/cgroups/cgroup.h
-index f4b5d19..330f37c 100644
---- a/src/cgroups/cgroup.h
-+++ b/src/cgroups/cgroup.h
-@@ -155,7 +155,7 @@ struct cgroup_ops {
- char **value);
- int (*get_memory_swap_max)(struct cgroup_ops *ops, const char *cgroup,
- char **value);
-- bool (*can_use_swap)(struct cgroup_ops *ops);
-+ bool (*can_use_swap)(struct cgroup_ops *ops, const char *cgroup);
-
- /* cpuset */
- int (*get_cpuset_cpus)(struct cgroup_ops *ops, const char *cgroup,
-diff --git a/src/proc_fuse.c b/src/proc_fuse.c
-index 06ec2d9..9a5915c 100644
---- a/src/proc_fuse.c
-+++ b/src/proc_fuse.c
-@@ -322,7 +322,6 @@ static int proc_swaps_read(char *buf, size_t size, off_t offset,
- *memswusage_str = NULL, *memswpriority_str = NULL;
- struct fuse_context *fc = fuse_get_context();
- struct lxcfs_opts *opts = (struct lxcfs_opts *)fuse_get_context()->private_data;
-- bool wants_swap = opts && !opts->swap_off && liblxcfs_can_use_swap();
- struct file_info *d = INTTYPE_TO_PTR(fi->fh);
- uint64_t memswlimit = 0, memlimit = 0, memusage = 0, memswusage = 0,
- swtotal = 0, swusage = 0, memswpriority = 1,
-@@ -330,6 +329,7 @@ static int proc_swaps_read(char *buf, size_t size, off_t offset,
- ssize_t total_len = 0;
- ssize_t l = 0;
- char *cache = d->buf;
-+ bool wants_swap;
- int ret;
- __do_free char *line = NULL;
- __do_free void *fopen_cache = NULL;
-@@ -359,6 +359,9 @@ static int proc_swaps_read(char *buf, size_t size, off_t offset,
- cgroup = get_pid_cgroup(initpid, "memory");
- if (!cgroup)
- return read_file_fuse("/proc/swaps", buf, size, d);
-+
-+ wants_swap = opts && !opts->swap_off && liblxcfs_can_use_swap(cgroup);
-+
- prune_init_slice(cgroup);
-
- memlimit = get_min_memlimit(cgroup, false);
-@@ -1158,13 +1161,13 @@ static int proc_meminfo_read(char *buf, size_t size, off_t offset,
- __do_fclose FILE *f = NULL;
- struct fuse_context *fc = fuse_get_context();
- struct lxcfs_opts *opts = (struct lxcfs_opts *)fuse_get_context()->private_data;
-- bool wants_swap = opts && !opts->swap_off && liblxcfs_can_use_swap();
- struct file_info *d = INTTYPE_TO_PTR(fi->fh);
- uint64_t memlimit = 0, memusage = 0, memswlimit = 0, memswusage = 0,
- hosttotal = 0, swfree = 0, swusage = 0, swtotal = 0,
- memswpriority = 1;
- struct memory_stat mstat = {};
- size_t linelen = 0, total_len = 0;
-+ bool wants_swap;
- char *cache = d->buf;
- size_t cache_size = d->buflen;
- int ret;
-@@ -1192,6 +1195,7 @@ static int proc_meminfo_read(char *buf, size_t size, off_t offset,
- cgroup = get_pid_cgroup(initpid, "memory");
- if (!cgroup)
- return read_file_fuse("/proc/meminfo", buf, size, d);
-+ wants_swap = opts && !opts->swap_off && liblxcfs_can_use_swap(cgroup);
-
- prune_init_slice(cgroup);
-
+++ /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 b169af4..d4da43e 100644
---- a/src/bindings.c
-+++ b/src/bindings.c
-@@ -59,6 +59,7 @@
- static bool can_use_pidfd;
- static int can_use_swap = -1;
- struct cgroup_ops *cgroup_ops;
-+static bool memory_is_cgroupv2;
-
- static volatile sig_atomic_t reload_successful;
-
-@@ -79,6 +80,11 @@ bool liblxcfs_can_use_swap(const char *cgroup)
- return can_use_swap;
- }
-
-+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)
-@@ -847,6 +853,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__);
-
-@@ -898,6 +905,9 @@ static void __attribute__((constructor)) lxcfs_init(void)
- lxcfs_info("Kernel supports pidfds");
- }
-
-+ hierarchy = cgroup_ops->get_hierarchy(cgroup_ops, "memory");
-+ memory_is_cgroupv2 = hierarchy && is_unified_hierarchy(hierarchy);
-+
- lxcfs_info("api_extensions:");
- for (i = 0; i < nr_api_extensions; i++)
- lxcfs_info("- %s", api_extensions[i]);
-diff --git a/src/bindings.h b/src/bindings.h
-index a334947..9ab989a 100644
---- a/src/bindings.h
-+++ b/src/bindings.h
-@@ -92,6 +92,7 @@ extern void prune_init_slice(char *cg);
- extern bool supports_pidfd(void);
- extern bool liblxcfs_functional(void);
- extern bool liblxcfs_can_use_swap(const char *cgroup);
-+extern bool liblxcfs_memory_is_cgroupv2(void);
-
- static inline int install_signal_handler(int signo,
- void (*handler)(int, siginfo_t *, void *))
-diff --git a/src/proc_fuse.c b/src/proc_fuse.c
-index 9a5915c..6371b2c 100644
---- a/src/proc_fuse.c
-+++ b/src/proc_fuse.c
-@@ -315,6 +315,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)
- {
-@@ -323,7 +360,7 @@ static int proc_swaps_read(char *buf, size_t size, off_t offset,
- struct fuse_context *fc = fuse_get_context();
- struct lxcfs_opts *opts = (struct lxcfs_opts *)fuse_get_context()->private_data;
- 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;
-@@ -373,26 +410,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");
-
-@@ -1162,7 +1181,7 @@ static int proc_meminfo_read(char *buf, size_t size, off_t offset,
- struct fuse_context *fc = fuse_get_context();
- struct lxcfs_opts *opts = (struct lxcfs_opts *)fuse_get_context()->private_data;
- 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 = {};
-@@ -1216,26 +1235,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)
-@@ -1274,7 +1275,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;
- }
--- /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;
+ }
--- /dev/null
+From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
+From: Wolfgang Bumiller <w.bumiller@proxmox.com>
+Date: Thu, 2 Dec 2021 13:05:28 +0100
+Subject: [PATCH lxcfs] cgv2: assume swap is supported
+
+because this is just wrong and fixing it is annoying
+
+Signed-off-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
+---
+ src/cgroups/cgfsng.c | 10 ++++------
+ 1 file changed, 4 insertions(+), 6 deletions(-)
+
+diff --git a/src/cgroups/cgfsng.c b/src/cgroups/cgfsng.c
+index 3eb4227..fed7911 100644
+--- a/src/cgroups/cgfsng.c
++++ b/src/cgroups/cgfsng.c
+@@ -626,12 +626,10 @@ static bool cgfsng_can_use_swap(struct cgroup_ops *ops)
+ return false;
+
+ if (is_unified_hierarchy(h)) {
+- if (faccessat(h->fd, "memory.swap.max", F_OK, 0))
+- return false;
+-
+- if (faccessat(h->fd, "memory.swap.current", F_OK, 0))
+- return false;
+-
++ /* the files to check for don't exist at the root cgroup
++ * directory so let's assume yes, other kernel configs are
++ * simply not supported on pve
++ */
+ has_swap = true;
+ } else {
+ if (faccessat(h->fd, "memory.memsw.limit_in_bytes", F_OK, 0))
do-not-start-without-lxcfs.patch
-./0001-delay-check-for-swap-accounting.patch
-./0002-make-meminfo-and-swaps-cgroupv2-aware.patch
+extra/0001-make-meminfo-and-swaps-cgroupv2-aware.patch
+extra/0002-cgv2-assume-swap-is-supported.patch