LINUX.ORG.RU

Systemd в кастомном initramfs падает с «Failed to mount API filesystems»

 


0

1

Приветствую! Занимаюсь разработкой своего дистрибутива (RorkOS) Суть проблемы: ядро успешно стартует, BusyBox-скрипт /init подготавливает окружение (монтирует proc, sys, dev, tmpfs на /run). Но при вызове exec /usr/lib/systemd/systemd всё падает. В логах выше проскакивают такие ошибки монтирования:

  • Failed to mangle mount options mode=01777,usrquota: Operation not supported
  • Failed to mangle mount options nsdelegate,memory_recursiveprot: Operation not supported

Параметры загрузки в GRUB: linux /boot/vmlinuz root=/dev/ram0 rw init=/init loglevel=7 systemd.unified_cgroup_hierarchy=0 cgroup_no_v1=all selinux=0

Ядро собрано с поддержкой CGROUPS, TMPFS, DEVTMPFS. Библиотеки (ld-linux, libc) в образе присутствуют, линковщик настроен.

build.sh:

#!/bin/bash
set -e

BASE_DIR="/home/rorka/rorkos"
SRC_DIR="$BASE_DIR/src"
ROOTFS="$SRC_DIR/rorkos_rootfs"
KERNEL_BUILD_DIR="$SRC_DIR/linux-6.18.2"
ISO_DIR="$SRC_DIR/iso_build"

sudo rm -rf "$ROOTFS" "$ISO_DIR"
mkdir -p "$ROOTFS"/{proc,sys,dev,run,tmp,etc,root,home,var/lib,var/log}
mkdir -p "$ROOTFS"/usr/{bin,lib,lib64,sbin}
mkdir -p "$ROOTFS"/usr/lib/systemd/system
mkdir -p "$ROOTFS"/etc/systemd/system/{multi-user.target.wants,sockets.target.wants,sysinit.target.wants}

ln -sf usr/bin "$ROOTFS/bin"
ln -sf usr/bin "$ROOTFS/sbin"
ln -sf usr/lib "$ROOTFS/lib"
ln -sf usr/lib "$ROOTFS/lib64"

cp -p /usr/lib/systemd/systemd "$ROOTFS/usr/lib/systemd/"
cp -p /usr/lib/systemd/systemd-* "$ROOTFS/usr/lib/systemd/" 2>/dev/null || true

sudo bash -c "cat > $ROOTFS/init" <<'EOF'
#!/usr/bin/busybox sh
/usr/bin/busybox --install -s /usr/bin
mount -t proc proc /proc
mount -t sysfs sysfs /sys
mount -t devtmpfs devtmpfs /dev
mkdir -p /run /tmp
mount -t tmpfs -o mode=0755,nodev,nosuid tmpfs /run
exec /usr/lib/systemd/systemd
EOF
chmod +x "$ROOTFS/init"

cp /bin/busybox "$ROOTFS/usr/bin/busybox"
chmod +x "$ROOTFS/usr/bin/busybox"
for tool in sh ls cat echo ps mount ip grep awk sed mkdir rm mv cp agetty login; do
    ln -sf busybox "$ROOTFS/usr/bin/$tool"
done

copy_libs() {
    local b="$1"
    [ ! -f "$b" ] && return
    ldd "$b" 2>/dev/null | grep "=>" | awk '{print $3}' | while read -r lib; do
        if [[ "$lib" == /* ]] && [ -f "$lib" ]; then
            dest_dir="$ROOTFS$(dirname "$lib")"
            mkdir -p "$dest_dir"
            cp -Ln "$lib" "$dest_dir/" 2>/dev/null || true
        fi
    done
}

cp -L /lib64/ld-linux-x86-64.so.2 "$ROOTFS/usr/lib/"
find "$ROOTFS/usr/bin" -type f -executable | while read -r b; do copy_libs "$b"; done
find "$ROOTFS/usr/lib/systemd" -type f -executable | while read -r b; do copy_libs "$b"; done
copy_libs "$ROOTFS/init"

mkdir -p "$ROOTFS/lib64"
cp -L /lib64/ld-linux-x86-64.so.2 "$ROOTFS/lib64/"

for service in systemd-networkd.service systemd-resolved.service systemd-udevd.service systemd-udev-trigger.service; do
    [ -f "/usr/lib/systemd/system/$service" ] && cp "/usr/lib/systemd/system/$service" "$ROOTFS/usr/lib/systemd/system/"
done

echo "rorkos" > "$ROOTFS/etc/hostname"
echo "root:x:0:0:root:/root:/bin/sh" > "$ROOTFS/etc/passwd"
echo "root:x:0:" > "$ROOTFS/etc/group"
echo "NAME=RorkOS" > "$ROOTFS/etc/os-release"

cd "$ROOTFS"
find . -print0 | cpio --null --quiet -ov -H newc | gzip -9 > "$SRC_DIR/initrd.img"

mkdir -p "$ISO_DIR/boot/grub"
cp "${KERNEL_BUILD_DIR}/arch/x86/boot/bzImage" "$ISO_DIR/boot/vmlinuz"
cp "$SRC_DIR/initrd.img" "$ISO_DIR/boot/initrd.img"

cat <<EOF > "$ISO_DIR/boot/grub/grub.cfg"
set timeout=0
menuentry "RorkOS" {
    linux /boot/vmlinuz root=/dev/ram0 rw init=/init loglevel=7 systemd.unified_cgroup_hierarchy=0 cgroup_no_v1=all selinux=0
    initrd /boot/initrd.img
}
EOF

grub-mkrescue -o "$BASE_DIR/rorkos.iso" "$ISO_DIR" -- -volid "RORKOS"