#!/bin/bash # Compatibility shims for systemd 259.1 against the Pagan native rootfs headers. set -euo pipefail # systemd ships missing kernel UAPI bits under src/include/override and # src/include/uapi. Meson adds those as -isystem, but pkg-config injects # -I$PAGAN_ROOT/usr/include which wins and hides the overrides. Flip them # to regular -I so MQUEUE_MAGIC, EXT4_IOC_RESIZE_FS, key_serial_t, etc. work. if [[ -f meson.build ]]; then python3 - <<'PY' from pathlib import Path p = Path("meson.build") t = p.read_text() t = t.replace("is_system : true", "is_system : false") for kind in ("override", "uapi"): t = t.replace( f"'-isystem', meson.project_build_root() / 'src/include/{kind}'", f"'-I', meson.project_build_root() / 'src/include/{kind}'", ) t = t.replace( f"'-isystem', meson.project_source_root() / 'src/include/{kind}'", f"'-I', meson.project_source_root() / 'src/include/{kind}'", ) # Inject missing MAGIC macros via -imacros after config.h. marker = "userspace_c_args += ['-include', 'config.h']" inject = ( marker + "\nuserspace_c_args += ['-imacros', meson.project_source_root() / 'src/include/override/pagan-compat.h']" ) if marker in t and "pagan-compat.h" not in t: t = t.replace(marker, inject, 1) p.write_text(t) print("patched meson.build: systemd override headers now use -I") PY fi # keyctl.c provides missing_keyctl/missing_add_key/missing_request_key syscall # wrappers (required at link time). We removed the keyutils.h injection that # caused the old header conflict, so the file is safe to keep. if [[ -f src/libc/meson.build ]] && ! grep -q "'keyctl.c'" src/libc/meson.build; then sed -i "/'xattr.c',/a\ 'keyctl.c'," src/libc/meson.build fi # linux/keyctl.h on the target does not declare key_serial_t. if [[ -f src/include/override/sys/keyctl.h ]]; then if ! grep -q 'KEY_SERIAL_T_DEFINED' src/include/override/sys/keyctl.h; then sed -i '1i #include \n#ifndef KEY_SERIAL_T_DEFINED\n#define KEY_SERIAL_T_DEFINED\ntypedef int32_t key_serial_t;\n#endif' \ src/include/override/sys/keyctl.h fi fi # Include libc networking headers before Linux netfilter headers. if [[ -f src/shared/firewall-util.c ]]; then sed -i \ -e '/^#include /d' \ -e '/^#include /d' \ -e '/^#include /d' \ -e '/^#include /d' \ -e '/^#include $/a #include \n#include \n#include \n#include ' \ src/shared/firewall-util.c fi # TASK_COMM_LEN is not exported by the target kernel headers. if [[ -f src/shared/nsresource.c ]] && ! grep -q 'TASK_COMM_LEN 16' src/shared/nsresource.c; then sed -i '1i #ifndef TASK_COMM_LEN\n#define TASK_COMM_LEN 16\n#endif' src/shared/nsresource.c fi # EXT4_IOC_RESIZE_FS lives in linux/ext4.h, not linux/fs.h. if [[ -f src/shared/resize-fs.c ]] && ! grep -q 'linux/ext4.h' src/shared/resize-fs.c; then sed -i '/#include /a #include ' src/shared/resize-fs.c fi # The target sysroot linux/keyctl.h lacks the KEY_POS/KEY_USR/KEY_GRP/KEY_OTH # keyring permission masks. systemd's override/linux/keyctl.h has them but is # shadowed by uapi/linux/keyctl.h (uapi comes first in -I order). Inject the # block into the uapi header that keyring code actually includes. Safe: the # udev keyboard generator only includes , so it never sees them. if [[ -f src/include/uapi/linux/keyctl.h ]] && ! grep -q 'define KEY_POS_VIEW' src/include/uapi/linux/keyctl.h; then python3 - <<'PY' from pathlib import Path p = Path("src/include/uapi/linux/keyctl.h") t = p.read_text() block = ''' #ifndef KEY_POS_VIEW #define KEY_POS_VIEW 0x01000000 #define KEY_POS_READ 0x02000000 #define KEY_POS_WRITE 0x04000000 #define KEY_POS_SEARCH 0x08000000 #define KEY_POS_LINK 0x10000000 #define KEY_POS_SETATTR 0x20000000 #define KEY_POS_ALL 0x3f000000 #define KEY_USR_VIEW 0x00010000 #define KEY_USR_READ 0x00020000 #define KEY_USR_WRITE 0x00040000 #define KEY_USR_SEARCH 0x00080000 #define KEY_USR_LINK 0x00100000 #define KEY_USR_SETATTR 0x00200000 #define KEY_USR_ALL 0x003f0000 #define KEY_GRP_VIEW 0x00000100 #define KEY_GRP_READ 0x00000200 #define KEY_GRP_WRITE 0x00000400 #define KEY_GRP_SEARCH 0x00000800 #define KEY_GRP_LINK 0x00001000 #define KEY_GRP_SETATTR 0x00002000 #define KEY_GRP_ALL 0x00003f00 #define KEY_OTH_VIEW 0x00000001 #define KEY_OTH_READ 0x00000002 #define KEY_OTH_WRITE 0x00000004 #define KEY_OTH_SEARCH 0x00000008 #define KEY_OTH_LINK 0x00000010 #define KEY_OTH_SETATTR 0x00000020 #define KEY_OTH_ALL 0x0000003f #endif ''' import re as _re m = _re.search(r'#endif\s*/\*.*?_LINUX_KEYCTL_H.*?\*/', t, _re.S) if m: t = t[:m.start()] + block + '\n' + m.group(0) else: idx = t.rstrip().rfind('\n#endif') t = t.rstrip()[:idx] + block + '\n#endif\n' p.write_text(t) print("patched uapi/linux/keyctl.h with keyring permission masks") PY fi # Force-include remaining kernel constants that systemd's override headers # also provide, in case some translation unit still misses them. compat_h="src/include/override/pagan-compat.h" cat > "$compat_h" <<'EOF' /* SPDX-License-Identifier: LGPL-2.1-or-later */ /* Macros only. Safe with -imacros: no includes, no typedefs. */ #ifndef _GNU_SOURCE #define _GNU_SOURCE 1 #endif #ifndef TASK_COMM_LEN #define TASK_COMM_LEN 16 #endif #ifndef MQUEUE_MAGIC #define MQUEUE_MAGIC 0x19800202 #endif #ifndef BALLOON_KVM_MAGIC #define BALLOON_KVM_MAGIC 0x13661366 #endif #ifndef ZSMALLOC_MAGIC #define ZSMALLOC_MAGIC 0x58295829 #endif #ifndef Z3FOLD_MAGIC #define Z3FOLD_MAGIC 0x33 #endif #ifndef PPC_CMM_MAGIC #define PPC_CMM_MAGIC 0xc7571590 #endif #ifndef SHIFTFS_MAGIC #define SHIFTFS_MAGIC 0x6a656a62 #endif #ifndef FUSE_CTL_SUPER_MAGIC #define FUSE_CTL_SUPER_MAGIC 0x65735543 #endif #ifndef ORANGEFS_DEVREQ_MAGIC #define ORANGEFS_DEVREQ_MAGIC 0x20030529 #endif #ifndef GFS2_MAGIC #define GFS2_MAGIC 0x01161970 #endif #ifndef CONFIGFS_MAGIC #define CONFIGFS_MAGIC 0x62656570 #endif #ifndef VBOXSF_SUPER_MAGIC #define VBOXSF_SUPER_MAGIC 0x786f4256 #endif #ifndef RPC_PIPEFS_SUPER_MAGIC #define RPC_PIPEFS_SUPER_MAGIC 0x67596969 #endif #ifndef NTFS_SB_MAGIC #define NTFS_SB_MAGIC 0x5346544e #endif #ifndef NTFS3_SUPER_MAGIC #define NTFS3_SUPER_MAGIC 0x7366746e #endif #ifndef EXT4_IOC_RESIZE_FS #define EXT4_IOC_RESIZE_FS _IOW('f', 16, unsigned long long) #endif #ifndef FILEID_KERNFS #define FILEID_KERNFS 0xfe #endif /* NOTE: do NOT force-define the KEY_POS / KEY_USR keyring permission * masks here. They are provided by systemd's override linux/keyctl.h * (which now wins because overrides use -I). Injecting them globally * would pollute the udev keyboard key list (compiled through our * -imacros) and overflow its unsigned-short key code field. */ /* Unconditional BPF jump (from linux/filter.h). Function-like macro, so it * only expands at call sites where struct bpf_insn / BPF_JMP / BPF_JA are * already declared. */ #ifndef BPF_JMP_A #define BPF_JMP_A(OFF) \ ((struct bpf_insn) { .code = BPF_JMP | BPF_JA, .dst_reg = 0, .src_reg = 0, .off = (OFF), .imm = 0 }) #endif #ifndef O_LARGEFILE #define O_LARGEFILE 0 #endif #ifndef O_NOATIME #define O_NOATIME 01000000 #endif #ifndef MFD_ALLOW_SEALING #define MFD_ALLOW_SEALING 2U #endif EOF # -imacros injects the macros without changing include search order # and without parsing the file as a translation-unit include. export CFLAGS="${CFLAGS:-} -D_GNU_SOURCE -imacros ${PWD}/${compat_h}" export CXXFLAGS="${CXXFLAGS:-} -D_GNU_SOURCE -imacros ${PWD}/${compat_h}"