summaryrefslogtreecommitdiff
path: root/src/basic/virt.c
diff options
context:
space:
mode:
authorLennart Poettering <lennart@poettering.net>2016-11-24 17:42:19 +0100
committerSven Eden <yamakuzure@gmx.net>2017-07-17 17:58:35 +0200
commited280b715fc427a925d418adc8ec0cfaa395f526 (patch)
tree60b6fc65e6779ece5f5dbda8d6bac18081e483a8 /src/basic/virt.c
parentd3c92fb53bb92ec00914aa4b51bd21d88e887128 (diff)
util: Fine tune running_in_chroot() a bit
Let's be a bit more careful when detecting chroot() environments, so that we can discern them from namespaced environments. Previously this would simply check if the root directory of PID 1 matches our own root directory. With this commit, we also check whether the namespaces of PID 1 and ourselves are the same. If not we assume we are running inside of a namespaced environment instead of a chroot() environment. This has the benefit that systemctl (which uses running_in_chroot()) will work as usual when invoked in a namespaced service.
Diffstat (limited to 'src/basic/virt.c')
-rw-r--r--src/basic/virt.c24
1 files changed, 19 insertions, 5 deletions
diff --git a/src/basic/virt.c b/src/basic/virt.c
index c935c534b..3957a5a8c 100644
--- a/src/basic/virt.c
+++ b/src/basic/virt.c
@@ -559,18 +559,32 @@ int running_in_userns(void) {
#endif // 0
int running_in_chroot(void) {
- int ret;
+ _cleanup_free_ char *self_mnt = NULL, *pid1_mnt = NULL;
+ int r;
+
+ /* Try to detect whether we are running in a chroot() environment. Specifically, check whether we have a
+ * different root directory than PID 1, even though we live in the same mount namespace as it. */
#if 0 /// elogind does not allow to ignore chroots, we are never init!
if (getenv_bool("SYSTEMD_IGNORE_CHROOT") > 0)
return 0;
#endif // 0
- ret = files_same("/proc/1/root", "/");
- if (ret < 0)
- return ret;
+ r = files_same("/proc/1/root", "/");
+ if (r < 0)
+ return r;
+ if (r > 0)
+ return 0;
+
+ r = readlink_malloc("/proc/self/ns/mnt", &self_mnt);
+ if (r < 0)
+ return r;
+
+ r = readlink_malloc("/proc/1/ns/mnt", &pid1_mnt);
+ if (r < 0)
+ return r;
- return ret == 0;
+ return streq(self_mnt, pid1_mnt); /* Only if we live in the same namespace! */
}
static const char *const virtualization_table[_VIRTUALIZATION_MAX] = {