make-disk-image: Get proper size for automatic size
On some filesystems, `du` without `--apparent-size` will not give the actual size for a file. Using `--apparent-size` will give us the actual file size. Though, this is not actually correct still. 1000 × 1 bytes is not 1000 bytes. It is 1000 × ceil(filesize/blockSize)*blockSize. So instead of adding up the actual file sizes. We are adding up the block sizes. Note that this also changes the builder to work with *bytes*, rather than with any other units. Doing maths on bytes is less likely to go awry than doing it on other units.
This commit is contained in:
parent
0ca4f6b739
commit
05c13a03e2
@ -163,6 +163,8 @@ let format' = format; in let
|
||||
|
||||
closureInfo = pkgs.closureInfo { rootPaths = [ config.system.build.toplevel channelSources ]; };
|
||||
|
||||
blockSize = toString (4 * 1024); # ext4fs block size (not block device sector size)
|
||||
|
||||
prepareImage = ''
|
||||
export PATH=${binPath}
|
||||
|
||||
@ -175,6 +177,15 @@ let format' = format; in let
|
||||
echo $(( "$1" * 512 ))
|
||||
}
|
||||
|
||||
# Given lines of numbers, adds them together
|
||||
sum_lines() {
|
||||
local acc=0
|
||||
while read -r number; do
|
||||
acc=$((acc+number))
|
||||
done
|
||||
echo "$acc"
|
||||
}
|
||||
|
||||
mkdir $out
|
||||
|
||||
root="$PWD/root"
|
||||
@ -235,12 +246,23 @@ let format' = format; in let
|
||||
|
||||
${if diskSize == "auto" then ''
|
||||
${if partitionTableType == "efi" || partitionTableType == "hybrid" then ''
|
||||
additionalSpace=$(( ($(numfmt --from=iec '${additionalSpace}') + $(numfmt --from=iec '${bootSize}')) / 1000 ))
|
||||
additionalSpace=$(( ($(numfmt --from=iec '${additionalSpace}') + $(numfmt --from=iec '${bootSize}')) ))
|
||||
'' else ''
|
||||
additionalSpace=$(( $(numfmt --from=iec '${additionalSpace}') / 1000 ))
|
||||
additionalSpace=$(( $(numfmt --from=iec '${additionalSpace}') ))
|
||||
''}
|
||||
diskSize=$(( $(set -- $(du -d0 $root); echo "$1") + $additionalSpace ))
|
||||
truncate -s "$diskSize"K $diskImage
|
||||
|
||||
# Compute required space in filesystem blocks
|
||||
requiredSpace=$(find . ! -type d -exec 'du' '--apparent-size' '--block-size' "${blockSize}" '{}' ';' | cut -f1 | sum_lines)
|
||||
# Convert to bytes
|
||||
requiredSpace=$(( requiredSpace * ${blockSize} ))
|
||||
|
||||
diskSize=$(( requiredSpace + additionalSpace ))
|
||||
truncate -s "$diskSize" $diskImage
|
||||
|
||||
printf "Automatic disk size...\n"
|
||||
printf " Space needed: %d bytes\n" $requiredSpace
|
||||
printf " Additional space: %d bytes\n" $additionalSpace
|
||||
printf " Disk image size: %d bytes\n" $diskSize
|
||||
'' else ''
|
||||
truncate -s ${toString diskSize}M $diskImage
|
||||
''}
|
||||
@ -251,9 +273,9 @@ let format' = format; in let
|
||||
# Get start & length of the root partition in sectors to $START and $SECTORS.
|
||||
eval $(partx $diskImage -o START,SECTORS --nr ${rootPartition} --pairs)
|
||||
|
||||
mkfs.${fsType} -F -L ${label} $diskImage -E offset=$(sectorsToBytes $START) $(sectorsToKilobytes $SECTORS)K
|
||||
mkfs.${fsType} -b ${blockSize} -F -L ${label} $diskImage -E offset=$(sectorsToBytes $START) $(sectorsToKilobytes $SECTORS)K
|
||||
'' else ''
|
||||
mkfs.${fsType} -F -L ${label} $diskImage
|
||||
mkfs.${fsType} -b ${blockSize} -F -L ${label} $diskImage
|
||||
''}
|
||||
|
||||
echo "copying staging root to image..."
|
||||
|
Loading…
Reference in New Issue
Block a user