commit:     9eb9b28d3e3b6725559fb38101ae869c1e4530ce
Author:     William Hubbs <w.d.hubbs <AT> gmail <DOT> com>
AuthorDate: Fri Jun 20 21:01:47 2014 +0000
Commit:     William Hubbs <williamh <AT> gentoo <DOT> org>
CommitDate: Fri Jun 20 21:01:47 2014 +0000
URL:        
http://git.overlays.gentoo.org/gitweb/?p=proj/openrc.git;a=commit;h=9eb9b28d

librc: filter out container processes on OpenVZ host

Thanks to info and testing done by Daniel Robbins <drobbins <AT> 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

---
 src/librc/librc-daemon.c | 46 ++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 46 insertions(+)

diff --git a/src/librc/librc-daemon.c b/src/librc/librc-daemon.c
index e98b02c..a53e6e1 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;
 }

Reply via email to