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