From aa57177db0bc4014f5d0f77e844429b2a778e377f3432068ef294ec925e29b75 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=96=9F=E9=85=8C=20=E9=B5=AC=E5=85=84?= Date: Mon, 27 Apr 2026 23:58:56 +0800 Subject: [PATCH] Ensure loop ready --- README.md | 14 +++++++++++ alpine/build-rootfs.sh | 4 +++ alpine/utils.sh | 57 ++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 75 insertions(+) create mode 100755 alpine/utils.sh diff --git a/README.md b/README.md index 3c2ef7c..3b6c36a 100644 --- a/README.md +++ b/README.md @@ -59,6 +59,20 @@ Prerequisites make release ``` +### Common issues +If you have encounter this error during build +``` +chroot: failed to run command '/bin/sh': Exec format error +``` + +You need to install support for amd64 emulation + +For Debian +``bash +apt-get install -y qemu-user-static binfmt-support +``` + +### cluster-config The default configuration will boot as a first time control-plane. For control-plane diff --git a/alpine/build-rootfs.sh b/alpine/build-rootfs.sh index db78031..734efa6 100755 --- a/alpine/build-rootfs.sh +++ b/alpine/build-rootfs.sh @@ -2,6 +2,8 @@ set -euo pipefail +source /utils.sh + /preload-k8s-images.sh || exit 1 export CTL_BIN_LAYER=$( skopeo inspect docker-daemon:localhost/monok8s/node-control:dev | jq -r '.Layers[0] | sub("^sha256:"; "")' ) @@ -197,6 +199,8 @@ sgdisk -o "$IMG" \ -n 3:0:+2560M -t 3:8300 -c 3:rootfsB \ -n 4:0:0 -t 4:8300 -c 4:data +ensure_loop_ready + losetup -D LOOP=$(losetup --find --show -P "$IMG") /sync-loop.sh "$LOOP" diff --git a/alpine/utils.sh b/alpine/utils.sh new file mode 100755 index 0000000..6d98989 --- /dev/null +++ b/alpine/utils.sh @@ -0,0 +1,57 @@ +#!/bin/bash + +ensure_loop_ready() { + # The loop kernel module is host-side. This only works if the container + # has permission and modprobe exists; otherwise the host must load it. + if ! grep -qw loop /proc/modules 2>/dev/null; then + modprobe loop 2>/dev/null || true + fi + + # /dev/loop-control: char device 10:237 + if [ ! -e /dev/loop-control ]; then + echo "Creating missing /dev/loop-control" >&2 + mknod /dev/loop-control c 10 237 || { + echo "ERROR: cannot create /dev/loop-control" >&2 + echo "Run container with --privileged, or pass --device=/dev/loop-control and loop devices." >&2 + exit 1 + } + chmod 600 /dev/loop-control || true + fi + + if [ ! -c /dev/loop-control ]; then + echo "ERROR: /dev/loop-control exists but is not a character device" >&2 + ls -l /dev/loop-control >&2 || true + exit 1 + fi + + # Create a reasonable pool of loop block devices. + # loopN block devices are major 7, minor N. + for i in $(seq 0 31); do + if [ ! -e "/dev/loop$i" ]; then + echo "Creating missing /dev/loop$i" >&2 + mknod "/dev/loop$i" b 7 "$i" || { + echo "ERROR: cannot create /dev/loop$i" >&2 + echo "Run container with --privileged, or pre-create/pass loop devices." >&2 + exit 1 + } + chmod 660 "/dev/loop$i" || true + fi + + if [ ! -b "/dev/loop$i" ]; then + echo "ERROR: /dev/loop$i exists but is not a block device" >&2 + ls -l "/dev/loop$i" >&2 || true + exit 1 + fi + done + + # Smoke test: ask losetup for a free loop device. + if ! losetup -f >/dev/null 2>&1; then + echo "ERROR: losetup cannot find/use a loop device" >&2 + echo "Debug info:" >&2 + ls -l /dev/loop-control /dev/loop* >&2 || true + grep -w loop /proc/modules >&2 || true + echo >&2 + echo "Docker likely needs --privileged, or at minimum CAP_SYS_ADMIN plus loop devices." >&2 + exit 1 + fi +}