스크립팅/메이크/자동화에 적합한 코드를 사용하여 디스크 이미지(UEFI/Syslinux USB Linux 부팅 [OS 설치 프로그램]용 파티션 2개, FAT 파일 시스템 1개 및 ext4 파일 시스템 1개)를 빌드해야 합니다. 프로덕션에서는 절대로 변경되지 않습니다). 임의 크기의 파일 집합 크기에 매우 가깝습니다. 즉, 빌드 파일 세트가 주어지면 FAT 및 ext4 파일 시스템 이미지를 생성하는 방법과 이를 보관하기 위해 분할된 디스크 이미지를 생성하는 방법을 알아야 하며, 크기는 가능한 한 0에 가까운 여유 공간이 되도록 계산됩니다. 공간을 조금 더 확보하여 실수를 해도 괜찮지만, 2년 후 누군가가 파일에 N+1바이트를 추가하면 실패해도 괜찮습니다. 이는 makefile에 맞아야 합니다. 즉, 시행착오로는 문제가 해결되지 않습니다(비록 상황이 더 악화되면 임계값이 있는 반복 솔루션이 작동할 수 있다고 가정합니다). 이는 ISO-9660 이미지(이전 프로젝트에서 사용되었지만 Syslinux는 UEFI에서 ISO-9660 이미지를 지원하지 않음)와 유사합니다.
나는 dd
(디스크 이미지 할당), parted
( dd
FAT 파일 시스템 할당), mkfs.vfat
( dd
ext4의 경우), mkfs.ext4
( kpartx
매핑된 파티션), dd
(FAT 파티션에 쓰기), dd
(ext4 파티션에 쓰기)를 사용하고 있으며 마지막으로 dd
부팅할 USB에 디스크 이미지를 씁니다. 실제 하드웨어.
현재 내 생각은 du
파일이 빌드 디스크에서 차지하는 공간을 결정한 다음 추가 파일 시스템 및 파티션 오버헤드와 오류 한계에 대한 여유를 추가하는 것입니다. 그래서 dd
주어진 각 출력에 대한 블록 수를 알아야 합니다 du
.
또 다른 옵션은 큰 고정 크기 이미지를 만들고 파일을 작성한 다음 FAT, ext4 및 파티션의 크기를 최소 크기로 조정하는 것입니다. ext4 파일 시스템은 축소될 수 있으며 FAT 파일 시스템도 축소될 수 있다는 것을 확인했습니다. 그러나 여전히 규모를 얼마나 줄여야 할지 계산하는 문제에 직면해 있습니다. 이전에 이 작업을 수행해 본 적이 있고 구체적인 아이디어(또는 예제 코드)를 갖고 있는 사람이 있는지 궁금합니다.
답변1
나는 퍼지 요소와 반복적 접근 방식(안전 장치로서)의 조합을 사용하게 되었습니다. 원래 생각했던 것만큼 복잡할 필요는 없습니다. 현재 FAT에는 퍼지가 거의 필요하지 않지만 ext4에는 퍼지 계수가 0이므로 여유 공간이 충분합니다(21M 이상). 나는 ext2로 변환하고(누가 냄새나는 로그가 필요합니까?!) 블록 크기를 늘리고 필요한 inode 수를 신중하게 계산하여 더 많은 여유 공간을 얻었습니다. du에서 "실제 크기"를 가져와 거기에서 계산할 수 있다고 가정하지만, 파일 시스템이 다르더라도 계산 오버헤드가 더 가까운 근사치가 될 것이라고 생각합니다.
# Estimated filesystem overhead, in 512-byte blocks
FS_ESP_FUDGE=256
FS_ISO_FUDGE=-80000 # Wow!
FS_FUDGE_INCR=1024
...
read ESP_RSIZE d < <(du --summarize --block-size=512 $ESP)
read ISO_RSIZE d < <(du --summarize --block-size=512 $ISO)
success=false
until $success; do
let ESP_SIZE=ESP_RSIZE+FS_ESP_FUDGE
let ISO_SIZE=ISO_RSIZE+FS_ISO_FUDGE
let ESP_START=2048
let IMG_SIZE=ESP_SIZE+ISO_SIZE+ESP_START
let ESP_END=ESP_START+ESP_SIZE-1
let ISO_START=ESP_END+1
success=true
...
sudo /sbin/mkfs.vfat /dev/mapper/$p1 -F 16 \
|| error_exit "mkfs.vfat failed" 5
# -N: Count the inodes (all files, plus . and .. for each directory,
# which I can't get "find" to include).
sudo /sbin/mke2fs -b 4096 -N $(( $(find $ISO | wc -l ) + 2 * $(find $ISO -type d | wc -l))) -m 0 -q /dev/mapper/$p2 \
|| error_exit "mke2fs failed" 6
...
if ! tar -C $ESP -c --exclude-vcs --exclude-backups . | \
sudo tar -C mnt/esp -x; then
{
read
read fs onek used avail use rest
} < <(df mnt/esp)
# Are we out of disk space? If not, bail, else increase margin, retry
[[ $onek -ne $used || $avail -ne 0 || $use != "100%" ]] && \
error_exit "esp tar failed" 9
let FS_ESP_FUDGE=FS_ESP_FUDGE+FS_FUDGE_INCR
success=false
fi
if ! tar -C $ISO -c --exclude-vcs --exclude-backups . | \
sudo tar -C mnt/iso --owner=root --group=root -x ; then
{
read
read fs onek used avail use rest
} < <(df mnt/iso)
# Are we out of disk space? If not, bail, else increase margin, retry
[[ $onek -ne $used || $avail -ne 0 || $use != "100%" ]] && \
error_exit "iso tar failed" 10
let FS_ISO_FUDGE=FS_ISO_FUDGE+FS_FUDGE_INCR
success=false
fi
$success || echo "Whoops, I guessed too small; please adjust fudge factor. Retrying ..."
...
done