projects:temp
Это старая версия документа!
rootfs
#!/bin/bash export LANG=en_US.UTF-8 export LC_ALL=en_US.UTF-8 # 06_patch_img_stretch.sh — внедрение stretch_limited в initramfs и образ .img с проверками и подтверждением set -euo pipefail [[ $EUID -ne 0 ]] && exec sudo "$0" "$@" MOUNT_DIR="/mnt/imgroot" INITRD_SCRIPT="/etc/initramfs-tools/scripts/init-premount/stretch_limited" # === 📁 Поиск и выбор устройств === mapfile -t DEVICES < <(lsblk -nrpo NAME,SIZE,MOUNTPOINT | grep -E "/dev/sd|/dev/nvme" | awk '{print $1":"$2":"$3}') if [[ ${#DEVICES[@]} -eq 0 ]]; then echo "❌ Нет доступных устройств." exit 1 fi echo "📍 Выбери куда подключён образ .img:" i=1 for dev in "${DEVICES[@]}"; do IFS=":" read -r name size mnt <<< "$dev" status="" [[ -z "$mnt" ]] && status="🔌 не примонтировано" echo " $i - $name ($size) $mnt $status" ((i++)) done read -rp "🔀 Выбор: " choice [[ "$choice" == "0" || -z "$choice" ]] && echo "❎ Отменено." && exit 0 SEL_DEV="${DEVICES[$((choice-1))]}" IFS=":" read -r DEV_NAME DEV_SIZE DEV_MNT <<< "$SEL_DEV" if [[ -z "$DEV_MNT" ]]; then MNT_PATH="/mnt/rpi_target0" mkdir -p "$MNT_PATH" mount "$DEV_NAME" "$MNT_PATH" TARGET_DIR="$MNT_PATH" else TARGET_DIR="$DEV_MNT" fi # === 📂 Поиск образов === mapfile -t IMG_LIST < <(find "$TARGET_DIR" -maxdepth 1 -type f -name "*.img") if [[ ${#IMG_LIST[@]} -eq 0 ]]; then echo "❌ Образы .img не найдены в $TARGET_DIR" exit 1 fi echo "📂 Образы:" i=1 for img in "${IMG_LIST[@]}"; do echo " $i - $img" ((i++)) done read -rp "🔀 Выбор образа: " img_choice [[ "$img_choice" == "0" || -z "$img_choice" ]] && echo "❎ Отменено." && exit 0 IMGFILE="${IMG_LIST[$((img_choice-1))]}" # === Запрос лимита === while true; do read -rp "📆 Укажи лимит размера rootfs в ГБ (0 = до конца диска, по умолчанию 30): " input_limit if [[ -z "$input_limit" ]]; then read -rp "🔁 Установить 30 ГБ? [Y/n] " confirm if [[ "$confirm" =~ ^[Nn]$ ]]; then continue; else LIMIT_GB=30; break; fi elif [[ "$input_limit" =~ ^[0-9]+$ ]]; then LIMIT_GB="$input_limit" break else echo "⛔ Только целые числа, пожалуйста." fi done MAX_MB=$((LIMIT_GB * 1024)) # === 🔄 Подключение loop === LOOP_DEV=$(losetup --show -Pf "$IMGFILE") mkdir -p "$MOUNT_DIR" mount "${LOOP_DEV}p2" "$MOUNT_DIR" # === Удаление авторасширения === rm -f "$MOUNT_DIR/etc/init.d/resize2fs_once" rm -f "$MOUNT_DIR/etc/systemd/system/resize2fs_once.service" rm -f "$MOUNT_DIR/etc/rc*.d/*resize2fs_once" sed -i 's@ init=/usr/lib/raspi-config/init_resize.sh@@' "$MOUNT_DIR/boot/cmdline.txt" # === Установка stretch_limited в initramfs === mkdir -p "$MOUNT_DIR/etc/initramfs-tools/scripts/init-premount" cat <<EOF > "$MOUNT_DIR$INITRD_SCRIPT" #!/bin/sh PREREQ="" prereqs() { echo "\$PREREQ"; } case "\$1" in prereqs) prereqs; exit 0;; esac . /scripts/functions FLAG_FILE="/etc/.stretch_done" DEV="/dev/mmcblk0" PART="\${DEV}p2" MAX_MB=__MAX_MB__ LOGFILE="/boot/stretch_limiter.log" log() { echo "[\$(date +%F\ %T)] \$1" >> "\$LOGFILE"; } [ -f "\$FLAG_FILE" ] && log "Флаг уже есть, выход" && exit 0 log "📉 Минимизация rootfs (resize2fs -M)..." resize2fs -M "\$PART" 2>>"\$LOGFILE" log "📐 Ограничиваем rootfs до \$MAX_MB МБ" START=\$(fdisk -l "\$DEV" | awk '/mmcblk0p2/ {print \$2}') END=\$(fdisk -l "\$DEV" | awk '/mmcblk0p2/ {print \$3}') SECTOR_SIZE=\$(blockdev --getss "\$DEV") CURRENT_MB=\$(( (END - START + 1) * SECTOR_SIZE / 1024 / 1024 )) if [ "\$CURRENT_MB" -le "\$MAX_MB" ]; then log "✅ Размер уже в пределах" else parted -s "\$DEV" resizepart 2 "\${MAX_MB}MB" partprobe "\$DEV" sleep 1 resize2fs "\$PART" log "✅ rootfs ограничен до \$MAX_MB МБ" fi touch "\$FLAG_FILE" EOF sed -i "s/__MAX_MB__/$MAX_MB/" "$MOUNT_DIR$INITRD_SCRIPT" chmod +x "$MOUNT_DIR$INITRD_SCRIPT" # === Монтируем окружение для chroot === mount --bind /dev "$MOUNT_DIR/dev" mount --bind /sys "$MOUNT_DIR/sys" mount --bind /proc "$MOUNT_DIR/proc" # === Установка локали и initramfs === chroot "$MOUNT_DIR" apt-get update chroot "$MOUNT_DIR" apt-get install -y locales initramfs-tools chroot "$MOUNT_DIR" locale-gen en_US.UTF-8 || true chroot "$MOUNT_DIR" update-initramfs -c -k all # === Отмонтирование окружения === umount "$MOUNT_DIR/proc" umount "$MOUNT_DIR/sys" umount "$MOUNT_DIR/dev" # === Обновление config.txt и initrd.img === sed -i '/^initramfs /d' "$MOUNT_DIR/boot/config.txt" kver=$(chroot "$MOUNT_DIR" uname -r) ln -sf "initrd.img-$kver" "$MOUNT_DIR/boot/initrd.img" echo "initramfs initrd.img followkernel" >> "$MOUNT_DIR/boot/config.txt" umount "$MOUNT_DIR" losetup -d "$LOOP_DEV" echo "✅ stretch_limited установлен в initramfs и образ. Будет выполнен при загрузке до монтирования rootfs."
Проверка
lsinitramfs /boot/initrd.img-$(uname -r) | grep stretch_limited
lsinitramfs /boot/initrd.img-$(uname -r) -l | grep stretch_limited && lsinitramfs /boot/initrd.img-$(uname -r) | grep -q "stretch_limited" && echo "✅ Есть в initramfs"
cat /boot/stretch_limiter.log df -h /
projects/temp.1743615213.txt.gz · Последнее изменение: 2025/04/02 20:33 —