Hi, For avoiding the deadlock, protect cdgroup_change_cgroup_uid_gid_flags() by blocking SIGUSR2 signal.
A cgrulesengd daemon needs a lock of rl_lock in cgroup_change_cgroup_uid_ ~gid_flags() for referring configuration buffer. On the other way, the daemon reloads configuration file when receiving SIGUSR2 signal, and it needs the same lock in cgroup_parse_rules(). So cgroup_change_cgroup_uid_ gid_flags() should be protected from SIGUSR2 signal for avoiding the deadlock. This patch is similar to the one([PATCH] Fix the deadlock of vsyslog() call), but they fix the different problem. So I think both of them are necessary. Reference: [PATCH] Fix the deadlock of vsyslog() call: http://sourceforge.net/mailarchive/forum.php?thread_name=4A0D2820.6050706%40mxs.nes.nec.co.jp&forum_name=libcg-devel Thanks Ken'ichi Ohmichi Signed-off-by: Ken'ichi Ohmichi <[email protected]> --- src/daemon/cgrulesengd.c | 33 ++++++++++++++++++++++++++------- 1 files changed, 26 insertions(+), 7 deletions(-) diff --git a/src/daemon/cgrulesengd.c b/src/daemon/cgrulesengd.c index 1a61476..fb757c1 100644 --- a/src/daemon/cgrulesengd.c +++ b/src/daemon/cgrulesengd.c @@ -271,6 +271,27 @@ static int cgre_was_parent_changed_when_forking(const struct proc_event *ev) return 0; } +static int cgre_change_cgroup_uid_gid(const uid_t uid, const gid_t gid, + const pid_t pid) +{ + int ret; + sigset_t sigset; + + /* + * For avoiding the deadlock, protect cdgroup_change_cgroup_ + * ~uid_gid_flags() by blocking SIGUSR2 signal. + */ + sigemptyset(&sigset); + sigaddset(&sigset, SIGUSR2); + sigprocmask(SIG_BLOCK, &sigset, NULL); + + ret = cgroup_change_cgroup_uid_gid_flags(uid, gid, pid, + CGFLAG_USECACHE); + sigprocmask(SIG_UNBLOCK, &sigset, NULL); + + return ret; +} + /** * Process an event from the kernel, and determine the correct UID/GID/PID to * pass to libcgroup. Then, libcgroup will decide the cgroup to move the PID @@ -318,22 +339,20 @@ int cgre_process_event(const struct proc_event *ev, const int type) case PROC_EVENT_UID: log_uid = ev->event_data.id.e.euid; log_gid = egid; - ret = cgroup_change_cgroup_uid_gid_flags( + ret = cgre_change_cgroup_uid_gid( ev->event_data.id.e.euid, - egid, pid, CGFLAG_USECACHE); + egid, pid); break; case PROC_EVENT_GID: log_uid = euid; log_gid = ev->event_data.id.e.egid; - ret = cgroup_change_cgroup_uid_gid_flags(euid, - ev->event_data.id.e.egid, - pid, CGFLAG_USECACHE); + ret = cgre_change_cgroup_uid_gid(euid, + ev->event_data.id.e.egid, pid); break; case PROC_EVENT_FORK: log_uid = euid; log_gid = egid; - ret = cgroup_change_cgroup_uid_gid_flags(euid, - egid, pid, CGFLAG_USECACHE); + ret = cgre_change_cgroup_uid_gid(euid, egid, pid); break; default: break; ------------------------------------------------------------------------------ Crystal Reports - New Free Runtime and 30 Day Trial Check out the new simplified licensing option that enables unlimited royalty-free distribution of the report engine for externally facing server and web deployment. http://p.sf.net/sfu/businessobjects _______________________________________________ Libcg-devel mailing list [email protected] https://lists.sourceforge.net/lists/listinfo/libcg-devel
