aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorWilliam Hubbs <w.d.hubbs@gmail.com>2014-06-20 16:01:47 -0500
committerWilliam Hubbs <w.d.hubbs@gmail.com>2014-06-20 16:01:47 -0500
commit9eb9b28d3e3b6725559fb38101ae869c1e4530ce (patch)
treec39a52c13d3c2a1e23c599c45394b77761afae82
parenta817915632f7f2162e7c3740d204989f6cfde554 (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.c46
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;
}