diff options
author | William Hubbs <w.d.hubbs@gmail.com> | 2014-06-20 16:01:47 -0500 |
---|---|---|
committer | William Hubbs <w.d.hubbs@gmail.com> | 2014-06-20 16:01:47 -0500 |
commit | 9eb9b28d3e3b6725559fb38101ae869c1e4530ce (patch) | |
tree | c39a52c13d3c2a1e23c599c45394b77761afae82 | |
parent | a817915632f7f2162e7c3740d204989f6cfde554 (diff) |
librc: filter out container processes on OpenVZ host
Thanks to info and testing done by Daniel Robbins <drobbins@funtoo.org>,
there is now a fix for this. Below is his description of the steps
OpenRC needed to use.
1) See if /proc/<pid>/status exists
2) If it does, see if it has a "envID:" field
3) If it does, see if "envID:" is set to "0"
4) If so, then it's one of the host's processes and should be a
candidate for the list. Otherwise, it is one of the container's
processes and should be ignored.
This should fix the bug and allow start-stop-daemon to work properly on
OpenVZ hosts.
X-Gentoo-Bug: 376817
X-Gentoo-Bug-URL: https://bugs.gentoo.org/show_bug.cgi?id=376817
-rw-r--r-- | src/librc/librc-daemon.c | 46 |
1 files changed, 46 insertions, 0 deletions
diff --git a/src/librc/librc-daemon.c b/src/librc/librc-daemon.c index e98b02c8..a53e6e16 100644 --- a/src/librc/librc-daemon.c +++ b/src/librc/librc-daemon.c @@ -90,6 +90,11 @@ rc_find_pids(const char *exec, const char *const *argv, uid_t uid, pid_t pid) { DIR *procdir; struct dirent *entry; + FILE *fp; + bool container_pid = false; + bool openvz_host = false; + char *line = NULL; + size_t len = 0; pid_t p; char buffer[PATH_MAX]; struct stat sb; @@ -117,6 +122,26 @@ rc_find_pids(const char *exec, const char *const *argv, uid_t uid, pid_t pid) runscript_pid = 0; } + /* + If /proc/self/status contains EnvID: 0, then we are an OpenVZ host, + and we will need to filter out processes that are inside containers + from our list of pids. + */ + + if (exists("/proc/self/status")) { + fp = fopen("/proc/self/status", "r"); + if (fp) { + while(! feof(fp)) { + rc_getline(&line, &len, fp); + if (strncmp(line, "envID:\t0", 8) == 0) { + openvz_host = true; + break; + } + } + fclose(fp); + } + } + while ((entry = readdir(procdir)) != NULL) { if (sscanf(entry->d_name, "%d", &p) != 1) continue; @@ -134,6 +159,25 @@ rc_find_pids(const char *exec, const char *const *argv, uid_t uid, pid_t pid) if (argv && !pid_is_argv(p, (const char *const *)argv)) continue; + /* If this is an OpenVZ host, filter out container processes */ + if (openvz_host) { + snprintf(buffer, sizeof(buffer), "/proc/%d/status", p); + if (exists(buffer)) { + fp = fopen(buffer, "r"); + if (! fp) + continue; + while (! feof(fp)) { + rc_getline(&line, &len, fp); + if (strncmp(line, "envID:", 6) == 0) { + container_pid = ! (strncmp(line, "envID:\t0", 8) == 0); + break; + } + } + fclose(fp); + } + } + if (container_pid) + continue; if (!pids) { pids = xmalloc(sizeof(*pids)); LIST_INIT(pids); @@ -142,6 +186,8 @@ rc_find_pids(const char *exec, const char *const *argv, uid_t uid, pid_t pid) pi->pid = p; LIST_INSERT_HEAD(pids, pi, entries); } + if (line != NULL) + free(line); closedir(procdir); return pids; } |