--- /dev/null
+From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
+From: Wolfgang Bumiller <w.bumiller@proxmox.com>
+Date: Fri, 15 May 2020 15:06:38 +0200
+Subject: [PATCH] mainloop: add lxc_mainloop_add_handler_events
+
+in order to be able to listen for EPOLLPRI
+
+Signed-off-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
+---
+ src/lxc/mainloop.c | 15 ++++++++++++---
+ src/lxc/mainloop.h | 4 ++++
+ 2 files changed, 16 insertions(+), 3 deletions(-)
+
+diff --git a/src/lxc/mainloop.c b/src/lxc/mainloop.c
+index 6d4c5935a..d5ae2a67a 100644
+--- a/src/lxc/mainloop.c
++++ b/src/lxc/mainloop.c
+@@ -59,8 +59,10 @@ int lxc_mainloop(struct lxc_epoll_descr *descr, int timeout_ms)
+ }
+ }
+
+-int lxc_mainloop_add_handler(struct lxc_epoll_descr *descr, int fd,
+- lxc_mainloop_callback_t callback, void *data)
++int lxc_mainloop_add_handler_events(struct lxc_epoll_descr *descr, int fd,
++ int events,
++ lxc_mainloop_callback_t callback,
++ void *data)
+ {
+ __do_free struct mainloop_handler *handler = NULL;
+ __do_free struct lxc_list *item = NULL;
+@@ -77,7 +79,7 @@ int lxc_mainloop_add_handler(struct lxc_epoll_descr *descr, int fd,
+ handler->fd = fd;
+ handler->data = data;
+
+- ev.events = EPOLLIN;
++ ev.events = events;
+ ev.data.ptr = handler;
+
+ if (epoll_ctl(descr->epfd, EPOLL_CTL_ADD, fd, &ev) < 0)
+@@ -92,6 +94,13 @@ int lxc_mainloop_add_handler(struct lxc_epoll_descr *descr, int fd,
+ return 0;
+ }
+
++int lxc_mainloop_add_handler(struct lxc_epoll_descr *descr, int fd,
++ lxc_mainloop_callback_t callback, void *data)
++{
++ return lxc_mainloop_add_handler_events(descr, fd, EPOLLIN, callback,
++ data);
++}
++
+ int lxc_mainloop_del_handler(struct lxc_epoll_descr *descr, int fd)
+ {
+ struct mainloop_handler *handler;
+diff --git a/src/lxc/mainloop.h b/src/lxc/mainloop.h
+index 8afac60d3..e6ab9a6d9 100644
+--- a/src/lxc/mainloop.h
++++ b/src/lxc/mainloop.h
+@@ -22,6 +22,10 @@ typedef int (*lxc_mainloop_callback_t)(int fd, uint32_t event, void *data,
+
+ extern int lxc_mainloop(struct lxc_epoll_descr *descr, int timeout_ms);
+
++extern int lxc_mainloop_add_handler_events(struct lxc_epoll_descr *descr,
++ int fd, int events,
++ lxc_mainloop_callback_t callback,
++ void *data);
+ extern int lxc_mainloop_add_handler(struct lxc_epoll_descr *descr, int fd,
+ lxc_mainloop_callback_t callback,
+ void *data);
--- /dev/null
+From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
+From: Wolfgang Bumiller <w.bumiller@proxmox.com>
+Date: Fri, 15 May 2020 15:07:07 +0200
+Subject: [PATCH] cgfsng: deduplicate freeze code
+
+Signed-off-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
+---
+ src/lxc/cgroups/cgfsng.c | 65 ++++++++++++----------------------------
+ 1 file changed, 19 insertions(+), 46 deletions(-)
+
+diff --git a/src/lxc/cgroups/cgfsng.c b/src/lxc/cgroups/cgfsng.c
+index 892fd915b..7136d27a8 100644
+--- a/src/lxc/cgroups/cgfsng.c
++++ b/src/lxc/cgroups/cgfsng.c
+@@ -2042,7 +2042,11 @@ static int freezer_cgroup_events_cb(int fd, uint32_t events, void *cbdata,
+ return LXC_MAINLOOP_CONTINUE;
+ }
+
+-static int cg_unified_freeze(struct cgroup_ops *ops, int timeout)
++static int cg_unified_freeze_do(struct cgroup_ops *ops, int timeout,
++ const char *state_string,
++ int state_num,
++ const char *epoll_error,
++ const char *wait_error)
+ {
+ __do_close int fd = -EBADF;
+ call_cleaner(lxc_mainloop_close) struct lxc_epoll_descr *descr_ptr = NULL;
+@@ -2067,26 +2071,33 @@ static int cg_unified_freeze(struct cgroup_ops *ops, int timeout)
+
+ ret = lxc_mainloop_open(&descr);
+ if (ret)
+- return log_error_errno(-1, errno, "Failed to create epoll instance to wait for container freeze");
++ return log_error_errno(-1, errno, "%s", epoll_error);
+
+ /* automatically cleaned up now */
+ descr_ptr = &descr;
+
+- ret = lxc_mainloop_add_handler(&descr, fd, freezer_cgroup_events_cb, INT_TO_PTR((int){1}));
++ ret = lxc_mainloop_add_handler(&descr, fd, freezer_cgroup_events_cb, INT_TO_PTR(state_num));
+ if (ret < 0)
+ return log_error_errno(-1, errno, "Failed to add cgroup.events fd handler to mainloop");
+ }
+
+- ret = lxc_write_openat(h->container_full_path, "cgroup.freeze", "1", 1);
++ ret = lxc_write_openat(h->container_full_path, "cgroup.freeze", state_string, 1);
+ if (ret < 0)
+ return log_error_errno(-1, errno, "Failed to open cgroup.freeze file");
+
+ if (timeout != 0 && lxc_mainloop(&descr, timeout))
+- return log_error_errno(-1, errno, "Failed to wait for container to be frozen");
++ return log_error_errno(-1, errno, "%s", wait_error);
+
+ return 0;
+ }
+
++static int cg_unified_freeze(struct cgroup_ops *ops, int timeout)
++{
++ return cg_unified_freeze_do(ops, timeout, "1", 1,
++ "Failed to create epoll instance to wait for container freeze",
++ "Failed to wait for container to be frozen");
++}
++
+ __cgfsng_ops static int cgfsng_freeze(struct cgroup_ops *ops, int timeout)
+ {
+ if (!ops->hierarchies)
+@@ -2112,47 +2123,9 @@ static int cg_legacy_unfreeze(struct cgroup_ops *ops)
+
+ static int cg_unified_unfreeze(struct cgroup_ops *ops, int timeout)
+ {
+- __do_close int fd = -EBADF;
+- call_cleaner(lxc_mainloop_close)struct lxc_epoll_descr *descr_ptr = NULL;
+- int ret;
+- struct lxc_epoll_descr descr;
+- struct hierarchy *h;
+-
+- h = ops->unified;
+- if (!h)
+- return ret_set_errno(-1, ENOENT);
+-
+- if (!h->container_full_path)
+- return ret_set_errno(-1, EEXIST);
+-
+- if (timeout != 0) {
+- __do_free char *events_file = NULL;
+-
+- events_file = must_make_path(h->container_full_path, "cgroup.events", NULL);
+- fd = open(events_file, O_RDONLY | O_CLOEXEC);
+- if (fd < 0)
+- return log_error_errno(-1, errno, "Failed to open cgroup.events file");
+-
+- ret = lxc_mainloop_open(&descr);
+- if (ret)
+- return log_error_errno(-1, errno, "Failed to create epoll instance to wait for container unfreeze");
+-
+- /* automatically cleaned up now */
+- descr_ptr = &descr;
+-
+- ret = lxc_mainloop_add_handler(&descr, fd, freezer_cgroup_events_cb, INT_TO_PTR((int){0}));
+- if (ret < 0)
+- return log_error_errno(-1, errno, "Failed to add cgroup.events fd handler to mainloop");
+- }
+-
+- ret = lxc_write_openat(h->container_full_path, "cgroup.freeze", "0", 1);
+- if (ret < 0)
+- return log_error_errno(-1, errno, "Failed to open cgroup.freeze file");
+-
+- if (timeout != 0 && lxc_mainloop(&descr, timeout))
+- return log_error_errno(-1, errno, "Failed to wait for container to be unfrozen");
+-
+- return 0;
++ return cg_unified_freeze_do(ops, timeout, "0", 0,
++ "Failed to create epoll instance to wait for container unfreeze",
++ "Failed to wait for container to be unfrozen");
+ }
+
+ __cgfsng_ops static int cgfsng_unfreeze(struct cgroup_ops *ops, int timeout)
--- /dev/null
+From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
+From: Wolfgang Bumiller <w.bumiller@proxmox.com>
+Date: Fri, 15 May 2020 15:07:35 +0200
+Subject: [PATCH] cgfsng: use EPOLLPRI when polling cgroup.events
+
+EPOLLIN will always be true and therefore end up
+busy-looping
+
+Signed-off-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
+---
+ src/lxc/cgroups/cgfsng.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/src/lxc/cgroups/cgfsng.c b/src/lxc/cgroups/cgfsng.c
+index 7136d27a8..f7af7c0a5 100644
+--- a/src/lxc/cgroups/cgfsng.c
++++ b/src/lxc/cgroups/cgfsng.c
+@@ -27,6 +27,7 @@
+ #include <stdio.h>
+ #include <stdlib.h>
+ #include <string.h>
++#include <sys/epoll.h>
+ #include <sys/types.h>
+ #include <unistd.h>
+
+@@ -2076,7 +2077,7 @@ static int cg_unified_freeze_do(struct cgroup_ops *ops, int timeout,
+ /* automatically cleaned up now */
+ descr_ptr = &descr;
+
+- ret = lxc_mainloop_add_handler(&descr, fd, freezer_cgroup_events_cb, INT_TO_PTR(state_num));
++ ret = lxc_mainloop_add_handler_events(&descr, fd, EPOLLPRI, freezer_cgroup_events_cb, INT_TO_PTR(state_num));
+ if (ret < 0)
+ return log_error_errno(-1, errno, "Failed to add cgroup.events fd handler to mainloop");
+ }