
스크립팅/만들기/자동화에 적합한 코드로 디스크 이미지(UEFI/Syslinux USB Linux 부팅[OS 설치 프로그램]을 위한 두 개의 파티션, FAT 파일 시스템 및 ext4 파일 시스템, 프로덕션 환경에서 절대 변경되지 않음)을 구성해야 합니다. 임의 크기의 파일 세트를 정확히(또는 매우 유사하게) 보유하는 크기입니다. 즉, 빌드된 파일 세트가 주어지면 FAT 및 ext4 파일 시스템 이미지를 생성하는 방법과 이를 보관하기 위해 분할된 디스크 이미지, 즉 합리적으로 0에 가까운 여유 공간을 확보하도록 계산된 크기를 갖는 디스크 이미지를 알아야 합니다. 가지다. 약간의 여유 공간이 있는 측면에서 실수를 하는 것은 괜찮지만 지금으로부터 2년 후에 누군가가 파일에 N+1 바이트를 추가할 때 실패하는 것은 괜찮지 않습니다. 이것은 메이크파일에 적합해야 합니다. 즉, 시행착오로는 이를 잘라낼 수 없습니다(비록 최악의 상황이 발생하면 임계값이 있는 반복 솔루션이 작동할 수 있다고 가정하지만). 이는 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에는 약간의 퍼지가 필요했지만 ext에는 엄청난 양의 네거티브 퍼지가 필요했습니다. ext4에 대한 퍼지 팩터가 0이므로 여유 공간이 충분했습니다(21M 이상). 나는 ext2로 전환했고(누가 더러운 저널이 필요한가?!) 블록 크기를 늘리고 필요한 inode 수를 주의 깊게 세어 더 많은 MB의 여유 공간을 확보했습니다. 나는 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