1 |
commit: 9eb9b28d3e3b6725559fb38101ae869c1e4530ce |
2 |
Author: William Hubbs <w.d.hubbs <AT> gmail <DOT> com> |
3 |
AuthorDate: Fri Jun 20 21:01:47 2014 +0000 |
4 |
Commit: William Hubbs <williamh <AT> gentoo <DOT> org> |
5 |
CommitDate: Fri Jun 20 21:01:47 2014 +0000 |
6 |
URL: http://git.overlays.gentoo.org/gitweb/?p=proj/openrc.git;a=commit;h=9eb9b28d |
7 |
|
8 |
librc: filter out container processes on OpenVZ host |
9 |
|
10 |
Thanks to info and testing done by Daniel Robbins <drobbins <AT> funtoo.org>, |
11 |
there is now a fix for this. Below is his description of the steps |
12 |
OpenRC needed to use. |
13 |
|
14 |
1) See if /proc/<pid>/status exists |
15 |
2) If it does, see if it has a "envID:" field |
16 |
3) If it does, see if "envID:" is set to "0" |
17 |
4) If so, then it's one of the host's processes and should be a |
18 |
candidate for the list. Otherwise, it is one of the container's |
19 |
processes and should be ignored. |
20 |
|
21 |
This should fix the bug and allow start-stop-daemon to work properly on |
22 |
OpenVZ hosts. |
23 |
|
24 |
X-Gentoo-Bug: 376817 |
25 |
X-Gentoo-Bug-URL: https://bugs.gentoo.org/show_bug.cgi?id=376817 |
26 |
|
27 |
--- |
28 |
src/librc/librc-daemon.c | 46 ++++++++++++++++++++++++++++++++++++++++++++++ |
29 |
1 file changed, 46 insertions(+) |
30 |
|
31 |
diff --git a/src/librc/librc-daemon.c b/src/librc/librc-daemon.c |
32 |
index e98b02c..a53e6e1 100644 |
33 |
--- a/src/librc/librc-daemon.c |
34 |
+++ b/src/librc/librc-daemon.c |
35 |
@@ -90,6 +90,11 @@ rc_find_pids(const char *exec, const char *const *argv, uid_t uid, pid_t pid) |
36 |
{ |
37 |
DIR *procdir; |
38 |
struct dirent *entry; |
39 |
+ FILE *fp; |
40 |
+ bool container_pid = false; |
41 |
+ bool openvz_host = false; |
42 |
+ char *line = NULL; |
43 |
+ size_t len = 0; |
44 |
pid_t p; |
45 |
char buffer[PATH_MAX]; |
46 |
struct stat sb; |
47 |
@@ -117,6 +122,26 @@ rc_find_pids(const char *exec, const char *const *argv, uid_t uid, pid_t pid) |
48 |
runscript_pid = 0; |
49 |
} |
50 |
|
51 |
+ /* |
52 |
+ If /proc/self/status contains EnvID: 0, then we are an OpenVZ host, |
53 |
+ and we will need to filter out processes that are inside containers |
54 |
+ from our list of pids. |
55 |
+ */ |
56 |
+ |
57 |
+ if (exists("/proc/self/status")) { |
58 |
+ fp = fopen("/proc/self/status", "r"); |
59 |
+ if (fp) { |
60 |
+ while(! feof(fp)) { |
61 |
+ rc_getline(&line, &len, fp); |
62 |
+ if (strncmp(line, "envID:\t0", 8) == 0) { |
63 |
+ openvz_host = true; |
64 |
+ break; |
65 |
+ } |
66 |
+ } |
67 |
+ fclose(fp); |
68 |
+ } |
69 |
+ } |
70 |
+ |
71 |
while ((entry = readdir(procdir)) != NULL) { |
72 |
if (sscanf(entry->d_name, "%d", &p) != 1) |
73 |
continue; |
74 |
@@ -134,6 +159,25 @@ rc_find_pids(const char *exec, const char *const *argv, uid_t uid, pid_t pid) |
75 |
if (argv && |
76 |
!pid_is_argv(p, (const char *const *)argv)) |
77 |
continue; |
78 |
+ /* If this is an OpenVZ host, filter out container processes */ |
79 |
+ if (openvz_host) { |
80 |
+ snprintf(buffer, sizeof(buffer), "/proc/%d/status", p); |
81 |
+ if (exists(buffer)) { |
82 |
+ fp = fopen(buffer, "r"); |
83 |
+ if (! fp) |
84 |
+ continue; |
85 |
+ while (! feof(fp)) { |
86 |
+ rc_getline(&line, &len, fp); |
87 |
+ if (strncmp(line, "envID:", 6) == 0) { |
88 |
+ container_pid = ! (strncmp(line, "envID:\t0", 8) == 0); |
89 |
+ break; |
90 |
+ } |
91 |
+ } |
92 |
+ fclose(fp); |
93 |
+ } |
94 |
+ } |
95 |
+ if (container_pid) |
96 |
+ continue; |
97 |
if (!pids) { |
98 |
pids = xmalloc(sizeof(*pids)); |
99 |
LIST_INIT(pids); |
100 |
@@ -142,6 +186,8 @@ rc_find_pids(const char *exec, const char *const *argv, uid_t uid, pid_t pid) |
101 |
pi->pid = p; |
102 |
LIST_INSERT_HEAD(pids, pi, entries); |
103 |
} |
104 |
+ if (line != NULL) |
105 |
+ free(line); |
106 |
closedir(procdir); |
107 |
return pids; |
108 |
} |