diff --git a/.github/workflows/build-test.sh b/.github/workflows/build-test.sh index 4693382c20..c683ca2de2 100755 --- a/.github/workflows/build-test.sh +++ b/.github/workflows/build-test.sh @@ -124,10 +124,15 @@ fi # This is added by default, and it is often broken, but we don't need anything from it sudo rm -f /etc/apt/sources.list.d/microsoft-prod.{list,sources} -# add-apt-repository --enable-source does not work on deb822 style sources. -for f in /etc/apt/sources.list.d/*.sources; do - sudo sed -i "s/Types: deb/Types: deb deb-src/g" "$f" -done +if grep -q 'VERSION_CODENAME=jammy' /usr/lib/os-release; then + sudo add-apt-repository -y --no-update ppa:upstream-systemd-ci/systemd-ci + sudo add-apt-repository -y --no-update --enable-source +else + # add-apt-repository --enable-source does not work on deb822 style sources. + for f in /etc/apt/sources.list.d/*.sources; do + sudo sed -i "s/Types: deb/Types: deb deb-src/g" "$f" + done +fi sudo apt-get -y update sudo apt-get -y build-dep systemd sudo apt-get -y install "${PACKAGES[@]}" @@ -138,6 +143,11 @@ sudo apt-get -y install "${PACKAGES[@]}" pip3 install --user -r .github/workflows/requirements.txt --require-hashes --break-system-packages export PATH="$HOME/.local/bin:$PATH" +if [[ -n "$CUSTOM_PYTHON" ]]; then + # If CUSTOM_PYTHON is set we need to pull jinja2 from pip, as a local interpreter is used + pip3 install --user --break-system-packages jinja2 +fi + $CC --version meson --version ninja --version diff --git a/.github/workflows/build-test.yml b/.github/workflows/build-test.yml index 1232773e3a..9e76c7920f 100644 --- a/.github/workflows/build-test.yml +++ b/.github/workflows/build-test.yml @@ -19,12 +19,13 @@ jobs: build: runs-on: ${{ matrix.runner }} concurrency: - group: ${{ github.workflow }}-${{ toJSON(matrix.env) }}-${{ github.ref }}-${{ matrix.runner }} + group: ${{ github.workflow }}-${{ toJSON(matrix.env) }}-${{ github.ref }}-${{ matrix.runner }}-${{ matrix.python-version }} cancel-in-progress: true strategy: fail-fast: false matrix: runner: [ ubuntu-24.04 ] + python-version: [ '' ] env: - { COMPILER: "gcc", COMPILER_VERSION: "11", LINKER: "bfd" } - { COMPILER: "gcc", COMPILER_VERSION: "13", LINKER: "mold" } @@ -34,13 +35,26 @@ jobs: include: - env: { COMPILER: "gcc", COMPILER_VERSION: "11", LINKER: "bfd" } runner: [ ubuntu-24.04-ppc64le ] + python-version: '' - env: { COMPILER: "gcc", COMPILER_VERSION: "13", LINKER: "mold" } runner: [ ubuntu-24.04-arm ] + python-version: '' - env: { COMPILER: "clang", COMPILER_VERSION: "18", LINKER: "lld" } runner: [ ubuntu-24.04-s390x ] + python-version: '' + # Do one run with the oldest supported python version to ensure there are no regressions + # It is only available on Jammy, which is useful as it will also provide a build check for + # older glibc + - env: { COMPILER: "gcc", COMPILER_VERSION: "12", LINKER: "bfd", CUSTOM_PYTHON: "1" } + runner: [ ubuntu-22.04 ] + python-version: '3.7' env: ${{ matrix.env }} steps: - name: Repository checkout uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 + - name: Setup python + uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 + with: + python-version: ${{ matrix.python-version }} - name: Build check run: .github/workflows/build-test.sh diff --git a/meson.build b/meson.build index c416bb4b60..f3d0a4b515 100644 --- a/meson.build +++ b/meson.build @@ -1958,6 +1958,8 @@ endif conf.set10('HAVE_VMLINUX_H', use_provided_vmlinux_h or use_generated_vmlinux_h) +conf.set10('ENABLE_SYSCTL_BPF', conf.get('HAVE_VMLINUX_H') == 1 and libbpf.version().version_compare('>= 0.7')) + ##################################################################### check_version_history_py = files('tools/check-version-history.py') diff --git a/src/basic/filesystem-sets.py b/src/basic/filesystem-sets.py index 6520f45b89..7fc2b7a515 100755 --- a/src/basic/filesystem-sets.py +++ b/src/basic/filesystem-sets.py @@ -307,8 +307,7 @@ def generate_fs_in_group(): print(' switch (fs_group) {') for name, _, *filesystems in FILESYSTEM_SETS: - magics = sorted(set(sum((NAME_TO_MAGIC[fs] for fs in filesystems), - start=[]))) + magics = sorted(set(sum((NAME_TO_MAGIC[fs] for fs in filesystems), []))) enum = 'FILESYSTEM_SET_' + name[1:].upper().replace('-', '_') print(f' case {enum}:') opts = '\n || '.join(f'F_TYPE_EQUAL(st->f_type, {magic})' @@ -355,7 +354,7 @@ def magic_defines(): def check(): kernel_magics = set(magic_defines()) - our_magics = set(sum(NAME_TO_MAGIC.values(), start=[])) + our_magics = set(sum(NAME_TO_MAGIC.values(), [])) extra = kernel_magics - our_magics if extra: sys.exit(f"kernel knows additional filesystem magics: {', '.join(sorted(extra))}") diff --git a/src/network/bpf/sysctl-monitor/meson.build b/src/network/bpf/sysctl-monitor/meson.build index 2cd385736a..8b0de88674 100644 --- a/src/network/bpf/sysctl-monitor/meson.build +++ b/src/network/bpf/sysctl-monitor/meson.build @@ -1,6 +1,6 @@ # SPDX-License-Identifier: LGPL-2.1-or-later -if conf.get('HAVE_VMLINUX_H') != 1 +if conf.get('ENABLE_SYSCTL_BPF') != 1 subdir_done() endif diff --git a/src/network/meson.build b/src/network/meson.build index c6a323c929..78a0e72b3a 100644 --- a/src/network/meson.build +++ b/src/network/meson.build @@ -140,7 +140,7 @@ networkctl_sources = files( networkd_network_gperf_gperf = files('networkd-network-gperf.gperf') networkd_netdev_gperf_gperf = files('netdev/netdev-gperf.gperf') -if conf.get('HAVE_VMLINUX_H') == 1 +if conf.get('ENABLE_SYSCTL_BPF') == 1 systemd_networkd_extract_sources += sysctl_monitor_skel_h endif diff --git a/src/network/networkd-manager.c b/src/network/networkd-manager.c index e7acf6d126..ef61a90fcb 100644 --- a/src/network/networkd-manager.c +++ b/src/network/networkd-manager.c @@ -646,7 +646,7 @@ int manager_new(Manager **ret, bool test_mode) { .dhcp_server_persist_leases = DHCP_SERVER_PERSIST_LEASES_YES, .serialization_fd = -EBADF, .ip_forwarding = { -1, -1, }, -#if HAVE_VMLINUX_H +#if ENABLE_SYSCTL_BPF .cgroup_fd = -EBADF, #endif }; diff --git a/src/network/networkd-manager.h b/src/network/networkd-manager.h index d0897e76ad..ad3d815b0c 100644 --- a/src/network/networkd-manager.h +++ b/src/network/networkd-manager.h @@ -117,7 +117,7 @@ typedef struct Manager { /* sysctl */ int ip_forwarding[2]; -#if HAVE_VMLINUX_H +#if ENABLE_SYSCTL_BPF Hashmap *sysctl_shadow; sd_event_source *sysctl_event_source; struct ring_buffer *sysctl_buffer; @@ -148,7 +148,7 @@ int manager_set_timezone(Manager *m, const char *timezone); int manager_reload(Manager *m, sd_bus_message *message); static inline Hashmap** manager_get_sysctl_shadow(Manager *manager) { -#if HAVE_VMLINUX_H +#if ENABLE_SYSCTL_BPF return &ASSERT_PTR(manager)->sysctl_shadow; #else return NULL; diff --git a/src/network/networkd-sysctl.c b/src/network/networkd-sysctl.c index 4f9b6522d7..6433a77a5e 100644 --- a/src/network/networkd-sysctl.c +++ b/src/network/networkd-sysctl.c @@ -26,7 +26,7 @@ #include "string-util.h" #include "sysctl-util.h" -#if HAVE_VMLINUX_H +#if ENABLE_SYSCTL_BPF #include "bpf-link.h" #include "bpf/sysctl-monitor/sysctl-monitor-skel.h" diff --git a/src/network/networkd-sysctl.h b/src/network/networkd-sysctl.h index dac7a72324..5cf8636312 100644 --- a/src/network/networkd-sysctl.h +++ b/src/network/networkd-sysctl.h @@ -22,7 +22,7 @@ typedef enum IPReversePathFilter { _IP_REVERSE_PATH_FILTER_INVALID = -EINVAL, } IPReversePathFilter; -#if HAVE_VMLINUX_H +#if ENABLE_SYSCTL_BPF int manager_install_sysctl_monitor(Manager *manager); void manager_remove_sysctl_monitor(Manager *manager); int link_clear_sysctl_shadows(Link *link); diff --git a/src/oom/test-oomd-util.c b/src/oom/test-oomd-util.c index b6f5fe25a5..abb5c2ccd8 100644 --- a/src/oom/test-oomd-util.c +++ b/src/oom/test-oomd-util.c @@ -68,6 +68,8 @@ TEST(oomd_cgroup_kill) { /* Create another cgroup below this one for the pids we forked off. We need this to be managed * by the test so that pid1 doesn't delete it before we can read the xattrs. */ ASSERT_NOT_NULL(subcgroup = path_join(cgroup, "oomdkilltest")); + /* Always start clean, in case of repeated runs and failures */ + ASSERT_OK(cg_trim(subcgroup, /* delete_root */ true)); ASSERT_OK(cg_create(subcgroup)); /* If we don't have permissions to set xattrs we're likely in a userns or missing capabilities */ @@ -106,6 +108,8 @@ TEST(oomd_cgroup_kill) { ASSERT_OK(cg_get_xattr(subcgroup, "user.oomd_kill", &v, /* ret_size= */ NULL)); ASSERT_STREQ(v, i == 0 ? "2" : "4"); } + + ASSERT_OK(cg_trim(subcgroup, /* delete_root */ true)); } TEST(oomd_cgroup_context_acquire_and_insert) { diff --git a/src/shared/seccomp-util.c b/src/shared/seccomp-util.c index 53d18dada5..f5bd64f8d3 100644 --- a/src/shared/seccomp-util.c +++ b/src/shared/seccomp-util.c @@ -1,5 +1,9 @@ /* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* This needs to be included before the seccomp headers, otherwise missing syscalls will be defined in this + * file and pass the ifdef, but they won't be defined in the seccomp headers so things like + * SCMP_SYS(fchmodat2) will resolve as empty and fail the build with older glibc/libseccomp. */ +#include #include #include #include diff --git a/src/test/test-bpf-token.c b/src/test/test-bpf-token.c index 3d6127182e..ffdf822b8b 100644 --- a/src/test/test-bpf-token.c +++ b/src/test/test-bpf-token.c @@ -7,7 +7,7 @@ #include "tests.h" static int intro(void) { -#if __LIBBPF_CURRENT_VERSION_GEQ(1, 5) +#if defined(LIBBPF_MAJOR_VERSION) && (LIBBPF_MAJOR_VERSION > 1 || (LIBBPF_MAJOR_VERSION == 1 && LIBBPF_MINOR_VERSION >= 5)) _cleanup_close_ int bpffs_fd = open("/sys/fs/bpf", O_RDONLY); if (bpffs_fd < 0) return log_error_errno(errno, "Failed to open '/sys/fs/bpf': %m"); diff --git a/src/test/test-cgroup.c b/src/test/test-cgroup.c index d32b119d26..e67887a004 100644 --- a/src/test/test-cgroup.c +++ b/src/test/test-cgroup.c @@ -51,10 +51,12 @@ TEST(cg_create) { _cleanup_free_ char *here = NULL; ASSERT_OK(cg_pid_get_path_shifted(0, NULL, &here)); - _cleanup_free_ char *test_a = ASSERT_NOT_NULL(path_join(here, "/test-a")), - *test_b = ASSERT_NOT_NULL(path_join(here, "/test-b")), - *test_c = ASSERT_NOT_NULL(path_join(here, "/test-b/test-c")), - *test_d = ASSERT_NOT_NULL(path_join(here, "/test-b/test-d")); + /* cg_* will use path_simplify(), so use it here too otherwise when running in a container at the + * root it asserts with "/test-b != //test-b" */ + _cleanup_free_ char *test_a = ASSERT_NOT_NULL(path_simplify(path_join(here, "/test-a"))), + *test_b = ASSERT_NOT_NULL(path_simplify(path_join(here, "/test-b"))), + *test_c = ASSERT_NOT_NULL(path_simplify(path_join(here, "/test-b/test-c"))), + *test_d = ASSERT_NOT_NULL(path_simplify(path_join(here, "/test-b/test-d"))); char *path; log_info("Paths for test:\n%s\n%s", test_a, test_b);