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
This commit is contained in:
parent
a817915632
commit
9eb9b28d3e
@ -90,6 +90,11 @@ rc_find_pids(const char *exec, const char *const *argv, uid_t uid, pid_t pid)
|
|||||||
{
|
{
|
||||||
DIR *procdir;
|
DIR *procdir;
|
||||||
struct dirent *entry;
|
struct dirent *entry;
|
||||||
|
FILE *fp;
|
||||||
|
bool container_pid = false;
|
||||||
|
bool openvz_host = false;
|
||||||
|
char *line = NULL;
|
||||||
|
size_t len = 0;
|
||||||
pid_t p;
|
pid_t p;
|
||||||
char buffer[PATH_MAX];
|
char buffer[PATH_MAX];
|
||||||
struct stat sb;
|
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;
|
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) {
|
while ((entry = readdir(procdir)) != NULL) {
|
||||||
if (sscanf(entry->d_name, "%d", &p) != 1)
|
if (sscanf(entry->d_name, "%d", &p) != 1)
|
||||||
continue;
|
continue;
|
||||||
@ -134,6 +159,25 @@ rc_find_pids(const char *exec, const char *const *argv, uid_t uid, pid_t pid)
|
|||||||
if (argv &&
|
if (argv &&
|
||||||
!pid_is_argv(p, (const char *const *)argv))
|
!pid_is_argv(p, (const char *const *)argv))
|
||||||
continue;
|
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) {
|
if (!pids) {
|
||||||
pids = xmalloc(sizeof(*pids));
|
pids = xmalloc(sizeof(*pids));
|
||||||
LIST_INIT(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;
|
pi->pid = p;
|
||||||
LIST_INSERT_HEAD(pids, pi, entries);
|
LIST_INSERT_HEAD(pids, pi, entries);
|
||||||
}
|
}
|
||||||
|
if (line != NULL)
|
||||||
|
free(line);
|
||||||
closedir(procdir);
|
closedir(procdir);
|
||||||
return pids;
|
return pids;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user