diff --git a/convert-stage-3.sh b/convert-stage-3.sh index fa6328f..6587356 100755 --- a/convert-stage-3.sh +++ b/convert-stage-3.sh @@ -9,6 +9,7 @@ build_log=$output_dir/build.log sudo dd if=${output_dir}/rootfs.img of=/dev/mapper/${rootfs_mapping} bs=8M conv=sparse >> "$build_log" 2>&1 sync +sudo resize2fs /dev/mapper/${rootfs_mapping} >> "$build_log" 2>&1 # Check Linux ext4 file system just in case. sudo fsck.ext4 -fp /dev/mapper/${rootfs_mapping} >> "$build_log" 2>&1 # Make sure the rootfs partition's label follows Mender naming convention. diff --git a/mender-convert b/mender-convert index 37be5b9..8d8f19f 100755 --- a/mender-convert +++ b/mender-convert @@ -35,27 +35,29 @@ Expert commands: Options: [-r|--raw-disk-image | -m|--mender-disk-image | -s|--data-part-size-mb | -d|--device-type | -p|--rootfs-partition-id | -i|--demo-host-ip | -c|--server-cert | -u|--server-url | -t|--tenant-token | - -g|--mender-client -b|--bootloader-toolchain | -a|--artifact-name | - -k|--keep | -v|--version] - - raw-disk-image - raw disk embedded Linux (Debian, Raspbian, - Ubuntu, etc.) image path - mender-disk-image - Mender disk image name where the script writes to - should have "sdimg" suffix - data-part-size-mb - data partition size in MB; default value 128MB - device-type - target device identification used to build - Mender image - rootfs-partition-id - selects root filesystem (primary|secondary) - as the source filesystem for an artifact - demo-host-ip - server demo ip used for testing purposes - server-cert - server certificate file - server-url - production server url - tenant-token - Mender tenant token - mender-client - Mender client binary - bootloader-toolchain - GNU Arm Embedded Toolchain - artifact-name - Mender artifact name - keep - keep intermediate files in output directory - version - print the version + -g|--mender-client | -b|--bootloader-toolchain | -a|--artifact-name | + -e|--storage-total-size-mb | -k|--keep | -v|--version] + + raw-disk-image - raw disk embedded Linux (Debian, Raspbian, + Ubuntu, etc.) image path + mender-disk-image - Mender disk image name where the script writes to + should have "sdimg" suffix + data-part-size-mb - data partition size in MB; default value 128MB + device-type - target device identification used to build + Mender image + rootfs-partition-id - selects root filesystem (primary|secondary) + as the source filesystem for an artifact + demo-host-ip - server demo ip used for testing purposes + server-cert - server certificate file + server-url - production server url + tenant-token - Mender tenant token + mender-client - Mender client binary + bootloader-toolchain - GNU Arm Embedded Toolchain + artifact-name - Mender artifact name + storage-total-size-mb - total storage size in MB; default value 8000MB; + it is used to calculate the rootfs final size + keep - keep intermediate files in output directory + version - print the version Note: root filesystem size used in Mender image creation can be found as an output from 'raw-disk-image-shrink-rootfs' command or, in case @@ -146,9 +148,6 @@ fi tool_dir="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" -# Default 'data' partition size in MiB. -data_part_size_mb=128 - mender_disk_image= raw_disk_image= device_type= @@ -282,6 +281,12 @@ do_raw_disk_image_create_partitions() { calculate_mender_disk_size ${partition_alignment} mender_disk_sizes \ mender_disk_counts mender_disk_image_size + mender_image_size_to_total_storage_size ${mender_disk_counts} \ + mender_disk_image_size ${storage_total_size_mb} \ + mender_disk_sizes + rc=$? + [ $rc -eq 0 ] || { return 1; } + if [[ ${raw_disk_counts} -gt 1 ]]; then log "\tExtracting boot partition from raw disk image." @@ -744,6 +749,10 @@ while (( "$#" )); do tenant_token=$2 shift 2 ;; + -e | --storage-total-size-mb) + storage_total_size_mb=$2 + shift 2 + ;; -k | --keep) keep="-k" shift 1 @@ -772,7 +781,11 @@ while (( "$#" )); do done [ -z "${data_part_size_mb}" ] && \ - { log "Default 'data' partition size set to 128MB"; data_part_size_mb=128; } + { log "*** Data partition size set to default value: 128MB ***"; \ + data_part_size_mb=$DATA_PART_SIZE_MB; } +[ -z "${storage_total_size_mb}" ] && \ + { log "*** Total storage size set to default value: 8GB ***"; \ + storage_total_size_mb=$STORAGE_TOTAL_SIZE_MB; } eval set -- "$PARAMS" diff --git a/mender-convert-functions.sh b/mender-convert-functions.sh index 67fd2bb..25479ce 100755 --- a/mender-convert-functions.sh +++ b/mender-convert-functions.sh @@ -8,6 +8,14 @@ declare -i vfat_storage_offset PART_ALIGN_4MB=4194304 PART_ALIGN_8MB=8388608 +# Default 'data' partition size in MiB. +declare -i data_part_size_mb +# Default total storage size in MiB. +declare -i storage_total_size_mb + +DATA_PART_SIZE_MB=128 +STORAGE_TOTAL_SIZE_MB=8000 + # Number of required heads in a final image. declare -i -r heads=255 # Number of required sectors in a final image. @@ -384,6 +392,77 @@ calculate_mender_disk_size() { eval $rvar_sdimgsize="'$sdimgsize'" } +# Takes following arguments: +# +# $1 - number of partition of the Mender image +# $2 - calculated total size of the Mender image in bytes +# $3 - expected total size of the Mender image in mb +# $4 - array of partitions' sizes for Mender image +# +# Returns: +# +# Size of the rootfs partition updated and adjusted to total storage size +# +mender_image_size_to_total_storage_size() { + local count=$1 + local rvar_image_size=$2 + local -n image_size_bytes=$2 + local storage_size_mb=$3 + + local _mender_sizes=$(declare -p $4) + eval "declare -A mender_sizes="${_mender_sizes#*=} + + shift 3 + local rvar_array=($@) + + local image_size_mb=$(( (($image_size_bytes / 1024) / 1024) )) + + log "\tAdjust Mender disk image size to the total storage size (${storage_size_mb}MB)." + + if [ $image_size_mb -gt $storage_size_mb ]; then + log "\tDefined total storage size of ${3}MB is too small." + log "\tMinimal required storage is ${image_size_mb}MB. Aborting." + return 1 + elif [ $image_size_mb -eq $storage_size_mb ]; then + # Simply continue. + log "\tCalculated Mender image size exactly fits the defined total storage." + return 0 + fi + + # Get spare space for rootfs a/b partitions (in sectors). + local sector_size=${mender_sizes[sector_size]} + local image_size_s=$(( $image_size_bytes / $sector_size )) + local storage_size_bytes=$(( ($storage_size_mb * 1024 * 1024) )) + local storage_size_s=$(( $storage_size_bytes / $sector_size )) + local rootfs_overplus_bytes=0 + + local spare_storage_bytes=$(( $storage_size_bytes - $image_size_bytes )) + + if [ $(($spare_storage_bytes % 2)) -ne 0 ]; then + log "\tAdditional space for rootfs partitions not divisible by 2.\ + \n\tFinal image will be smaller than ${storage_size_mb}MB" + fi + rootfs_overplus_bytes=$(( $spare_storage_bytes / 2 )) + + local reminder=$(( ${rootfs_overplus_bytes} % ${partition_alignment} )) + if [ $reminder -ne 0 ]; then + log "\tAdditional space for rootfs partitions not aligned.\ + \n\tFinal image will be smaller than ${storage_size_mb}MB" + fi + rootfs_overplus_bytes=$(($rootfs_overplus_bytes - $reminder)) + rootfs_overplus_s=$(( $rootfs_overplus_bytes / $sector_size )) + + local prootfs_size=${mender_sizes[prootfs_size]} + prootfs_size=$(( $prootfs_size + $rootfs_overplus_s )) + + image_size_bytes=$(( $image_size_bytes + 2 * $rootfs_overplus_bytes )) + + eval $rvar_array[prootfs_size]="'$prootfs_size'" + eval $rvar_image_size="'$image_size_bytes'" + + return 0 +} + # Takes following arguments: # # $1 - raw disk image