====== rootfs ======
===== 1 =====
#!/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))
# === Установка stretch_limited в initramfs ===
mkdir -p "$TARGET_DIR/etc/initramfs-tools/scripts/init-premount"
cat > "$TARGET_DIR$INITRD_SCRIPT" <>/stretch_limiter.log 2>&1
set -eux
echo "[initramfs] stretch_limited: запуск"
DEV="/dev/mmcblk0"
PART="\${DEV}p2"
FLAG_FILE="/etc/.stretch_done"
MAX_MB=$MAX_MB
if [ -f "\$FLAG_FILE" ]; then
echo "Файл stretch_done найден. Выход."
exit 0
fi
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 ))
echo "Текущий размер: \$CURRENT_MB MB, лимит: \$MAX_MB MB"
if [ "\$CURRENT_MB" -le "\$MAX_MB" ]; then
echo "Уже в пределах лимита."
touch "\$FLAG_FILE"
exit 0
fi
echo "Изменение раздела..."
parted -s "\$DEV" resizepart 2 "\${MAX_MB}MB"
partprobe "\$DEV"
sleep 2
resize2fs "\$PART"
touch "\$FLAG_FILE"
echo "✅ Готово"
EOF
chmod +x "$TARGET_DIR$INITRD_SCRIPT"
chroot "$TARGET_DIR" update-initramfs -u
ln -sf /boot/initrd.img-$(uname -r) "$TARGET_DIR/boot/initrd.img"
echo "✅ stretch_limited установлен в initramfs и образ. Будет выполнен при загрузке до монтирования rootfs."
===== 2 =====
Проверка
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 /