Compare commits

...

2 Commits

Author SHA1 Message Date
Luca Boccassi 8a5201a0f8 detect-virt: check the inode number of the pid namespace
The indoe number of root pid namespace is hardcoded in the kernel to
0xEFFFFFFC since 3.8, so check the inode number of our pid namespace
if all else fails. If it's not 0xEFFFFFFC then we are in a pid
namespace, hence a container environment.

Fixes https://github.com/systemd/systemd/issues/35249
2024-11-21 09:52:53 +00:00
Luca Boccassi c5d5c74671 test: run TEST-74-AUX-UTILS in VM in legacy shell setup too
This was switched for the mkosi-based jobs, but not for the shell
based jobs. Switch the shell jobs too for consistency, otherwise
some tests will work in mkosi and fail in shell, and viceversa.

Follow-up for f4faac2073
2024-11-21 09:52:03 +00:00
3 changed files with 28 additions and 0 deletions

View File

@ -24,6 +24,10 @@
#include "uid-range.h" #include "uid-range.h"
#include "virt.h" #include "virt.h"
/* Root namespace inode number, as per include/linux/proc_ns.h in the kernel source tree, since v3.8:
* https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=98f842e675f96ffac96e6c50315790912b2812be */
#define PROC_PID_INIT_INO UINT64_C(0xEFFFFFFC)
enum { enum {
SMBIOS_VM_BIT_SET, SMBIOS_VM_BIT_SET,
SMBIOS_VM_BIT_UNSET, SMBIOS_VM_BIT_UNSET,
@ -645,6 +649,20 @@ static int running_in_cgroupns(void) {
} }
} }
static int running_in_pidns(void) {
_cleanup_close_ int pidns_fd = -EBADF;
struct stat st;
pidns_fd = namespace_open_by_type(NAMESPACE_PID);
if (pidns_fd < 0)
return log_debug_errno(pidns_fd, "Failed to open PID namespace, ignoring: %m");
if (fstat(pidns_fd, &st) < 0)
return log_debug_errno(errno, "Failed to fstat pid namespace fd, ignoring: %m");
return (uint64_t) st.st_ino != PROC_PID_INIT_INO;
}
static Virtualization detect_container_files(void) { static Virtualization detect_container_files(void) {
static const struct { static const struct {
const char *file_path; const char *file_path;
@ -796,6 +814,13 @@ check_files:
if (r < 0) if (r < 0)
log_debug_errno(r, "Failed to detect cgroup namespace: %m"); log_debug_errno(r, "Failed to detect cgroup namespace: %m");
/* Finally, the root pid namespace has an hardcoded inode number of 0xEFFFFFFC since kernel 3.8, so
* if all else fails we can check the inode number of our pid namespace and compare it. */
if (running_in_pidns() > 0) {
v = VIRTUALIZATION_CONTAINER_OTHER;
goto finish;
}
/* If none of that worked, give up, assume no container manager. */ /* If none of that worked, give up, assume no container manager. */
v = VIRTUALIZATION_NONE; v = VIRTUALIZATION_NONE;
goto finish; goto finish;

View File

@ -4,6 +4,7 @@ set -e
TEST_DESCRIPTION="Tests for auxiliary utilities" TEST_DESCRIPTION="Tests for auxiliary utilities"
NSPAWN_ARGUMENTS="--private-network" NSPAWN_ARGUMENTS="--private-network"
TEST_NO_NSPAWN=1
# shellcheck source=test/test-functions # shellcheck source=test/test-functions
. "${TEST_BASE_DIR:?}/test-functions" . "${TEST_BASE_DIR:?}/test-functions"

View File

@ -5,3 +5,5 @@ set -o pipefail
SYSTEMD_IN_CHROOT=1 systemd-detect-virt --chroot SYSTEMD_IN_CHROOT=1 systemd-detect-virt --chroot
(! SYSTEMD_IN_CHROOT=0 systemd-detect-virt --chroot) (! SYSTEMD_IN_CHROOT=0 systemd-detect-virt --chroot)
unshare --mount-proc --fork --user --pid systemd-detect-virt --container