]> git.proxmox.com Git - lxc.git/commitdiff
merge fix for busy-looping on cgroup events
authorWolfgang Bumiller <w.bumiller@proxmox.com>
Thu, 30 Jul 2020 13:08:35 +0000 (15:08 +0200)
committerWolfgang Bumiller <w.bumiller@proxmox.com>
Thu, 30 Jul 2020 13:08:35 +0000 (15:08 +0200)
Signed-off-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
debian/patches/extra/0001-mainloop-add-lxc_mainloop_add_handler_events.patch [new file with mode: 0644]
debian/patches/extra/0002-cgfsng-deduplicate-freeze-code.patch [new file with mode: 0644]
debian/patches/extra/0003-cgfsng-use-EPOLLPRI-when-polling-cgroup.events.patch [new file with mode: 0644]
debian/patches/series

diff --git a/debian/patches/extra/0001-mainloop-add-lxc_mainloop_add_handler_events.patch b/debian/patches/extra/0001-mainloop-add-lxc_mainloop_add_handler_events.patch
new file mode 100644 (file)
index 0000000..7e58fe9
--- /dev/null
@@ -0,0 +1,68 @@
+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);
diff --git a/debian/patches/extra/0002-cgfsng-deduplicate-freeze-code.patch b/debian/patches/extra/0002-cgfsng-deduplicate-freeze-code.patch
new file mode 100644 (file)
index 0000000..1427cad
--- /dev/null
@@ -0,0 +1,116 @@
+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)
diff --git a/debian/patches/extra/0003-cgfsng-use-EPOLLPRI-when-polling-cgroup.events.patch b/debian/patches/extra/0003-cgfsng-use-EPOLLPRI-when-polling-cgroup.events.patch
new file mode 100644 (file)
index 0000000..7b31b6f
--- /dev/null
@@ -0,0 +1,34 @@
+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");
+       }
index f58808190809b98709a55791b1287300968374d1..6524ca0a66323094168f92021e9d74fdca83adc8 100644 (file)
@@ -2,3 +2,6 @@ pve/0001-PVE-Config-lxc.service-start-after-a-potential-syslo.patch
 pve/0002-PVE-Config-deny-rw-mounting-of-sys-and-proc.patch
 pve/0003-PVE-Config-attach-always-use-getent.patch
 pve/0004-apparmor-Allow-ro-remount-of-boot_id.patch
+extra/0001-mainloop-add-lxc_mainloop_add_handler_events.patch
+extra/0002-cgfsng-deduplicate-freeze-code.patch
+extra/0003-cgfsng-use-EPOLLPRI-when-polling-cgroup.events.patch