The following pull request was submitted through Github.
It can be accessed and reviewed at: https://github.com/lxc/lxc/pull/3413

This e-mail was sent by the LXC bot, direct replies will not reach the author
unless they happen to be subscribed to this list.

=== Description (from pull-request) ===

From 9d1c51d19e4db3ea0ae2f7b1dfc9024e3e6b6d4d Mon Sep 17 00:00:00 2001
From: Wolfgang Bumiller <w.bumil...@proxmox.com>
Date: Fri, 15 May 2020 15:06:38 +0200
Subject: [PATCH 1/3] mainloop: add lxc_mainloop_add_handler_events

in order to be able to listen for EPOLLPRI

Signed-off-by: Wolfgang Bumiller <w.bumil...@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 6d4c5935ae..d5ae2a67a0 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 8afac60d35..e6ab9a6d9e 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);

From 443be56560ee9b3c80d35d995520825e3c4c5672 Mon Sep 17 00:00:00 2001
From: Wolfgang Bumiller <w.bumil...@proxmox.com>
Date: Fri, 15 May 2020 15:07:07 +0200
Subject: [PATCH 2/3] cgfsng: deduplicate freeze code

Signed-off-by: Wolfgang Bumiller <w.bumil...@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 892fd915bb..7136d27a87 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)

From 385e58e8a8664d43175f64b8d44900ff651cec0f Mon Sep 17 00:00:00 2001
From: Wolfgang Bumiller <w.bumil...@proxmox.com>
Date: Fri, 15 May 2020 15:07:35 +0200
Subject: [PATCH 3/3] cgfsng: use EPOLLPRI when polling cgroup.events

EPOLLIN will always be true and therefore end up
busy-looping

Signed-off-by: Wolfgang Bumiller <w.bumil...@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 7136d27a87..f7af7c0a50 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");
        }
_______________________________________________
lxc-devel mailing list
lxc-devel@lists.linuxcontainers.org
http://lists.linuxcontainers.org/listinfo/lxc-devel

Reply via email to