Browse Source

Use associative array to hold partitions' sizes

Instead of passing mutable number of parameters related to
number of partitions for raw disk images, a single array
will be used to keep these values.

Issues: MEN-2207

Changelog: None

Signed-off-by: Adam Podogrocki <a.podogrocki@gmail.com>
1.1.x
Adam Podogrocki 6 years ago
parent
commit
36674a0e1e
  1. 63
      mender-convert
  2. 277
      mender-convert-functions.sh

63
mender-convert

@ -148,17 +148,8 @@ tool_dir="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
# Default sector size # Default sector size
sector_size= sector_size=
# Boot partition start in sectors (512 bytes per sector).
pboot_start=
# Default 'boot' partition size in sectors: 16MB
# (i.e 16777216 bytes, equals to 'partition_alignment' * 2)
pboot_size=
# Default 'data' partition size in MiB. # Default 'data' partition size in MiB.
data_part_size_mb=128 data_part_size_mb=128
# Data partition size in sectors.
pdata_size=
# Exemplary values for Beaglebone: 9.3: 4521984 9.4: 4423680
prootfs_size=
mender_disk_image= mender_disk_image=
raw_disk_image= raw_disk_image=
@ -296,35 +287,40 @@ do_raw_disk_image_create_partitions() {
mender_disk_image=$output_dir/mender-${device_type}-${artifact_name}.sdimg mender_disk_image=$output_dir/mender-${device_type}-${artifact_name}.sdimg
fi fi
set_boot_part_alignment $device_type partition_alignment vfat_storage_offset set_mender_disk_alignment $device_type partition_alignment vfat_storage_offset
analyse_raw_disk_image ${raw_disk_image} ${partition_alignment} ${vfat_storage_offset} \ get_raw_disk_sizes ${raw_disk_image} raw_disk_counts sector_size raw_disk_sizes
pboot_start pboot_size prootfs_size sector_size raw_disk_counts rc=$?
[ $rc -eq 0 ] || { return 1; }
[ -z "${prootfs_size}" ] && \ set_mender_disk_sizes ${raw_disk_counts} ${sector_size} \
{ log "root filesystem size not set. Aborting."; return 1; } ${partition_alignment} ${vfat_storage_offset} \
${data_part_size_mb} raw_disk_sizes mender_disk_sizes
log "\tDetected raw disk image with $raw_disk_counts partition(s)." log "\tDetected raw disk image with $raw_disk_counts partition(s)."
local mender_disk_image_size= local mender_disk_image_size=
calculate_mender_disk_size $pboot_start $pboot_size \ calculate_mender_disk_size $sector_size ${partition_alignment} \
$prootfs_size $data_part_size_mb \ mender_disk_sizes mender_disk_image_size
$sector_size pdata_size mender_disk_image_size
log "\tCreating Mender disk image:\ log "\tCreating Mender disk image:\
\n\t\timage size: ${mender_disk_image_size} bytes\ \n\t\timage size: ${mender_disk_image_size} bytes\
\n\t\tboot partition size: $((${pboot_size} * $sector_size)) bytes\ \n\t\tboot partition size: $((${mender_disk_sizes[pboot_size]} * $sector_size)) bytes\
\n\t\troot filesystem size: $((${prootfs_size} * $sector_size)) bytes\ \n\t\troot filesystem size: $((${mender_disk_sizes[prootfs_size]} * $sector_size)) bytes\
\n\t\tdata partition size: $(($pdata_size * $sector_size)) bytes" \n\t\tdata partition size: $((${mender_disk_sizes[pdata_size]} * $sector_size)) bytes"
create_test_config_file $device_type $partition_alignment $pboot_start \ create_test_config_file $device_type $partition_alignment $mender_disk_image_size \
$pboot_size $prootfs_size $pdata_size $mender_disk_image_size \ $sector_size mender_disk_sizes
$sector_size
create_mender_disk $mender_disk_image $mender_disk_image_size create_mender_disk $mender_disk_image $mender_disk_image_size
format_mender_disk $mender_disk_image $mender_disk_image_size $pboot_start \ format_mender_disk $mender_disk_image $mender_disk_image_size $sector_size \
$pboot_size $prootfs_size $pdata_size $sector_size $partition_alignment mender_disk_sizes mender_disk_counts
verify_mender_disk $mender_disk_image mender_disk_counts rc=$?
[ $rc -eq 0 ] || { return 1; }
verify_mender_disk $mender_disk_image $mender_disk_counts
rc=$?
[ $rc -eq 0 ] || { return 1; }
create_device_maps $mender_disk_image mender_disk_mappings create_device_maps $mender_disk_image mender_disk_mappings
@ -558,14 +554,15 @@ do_mender_disk_image_to_artifact() {
[[ $inarray -eq 0 ]] && \ [[ $inarray -eq 0 ]] && \
{ log "Error: invalid rootfs partition id provided. Aborting."; return 1; } { log "Error: invalid rootfs partition id provided. Aborting."; return 1; }
local count= local count=0
local bootstart= local prootfs_start=0
local rootfs_a_start= local prootfs_size=0
local rootfs_a_size= local rootfs_a_start=0
local rootfs_b_start= local rootfs_a_size=0
local rootfs_b_size= local rootfs_b_start=0
local rootfs_b_size=0
local rootfs_path= local rootfs_path=
local sdimg_device_type= local mender_device_type=
get_mender_disk_info $mender_disk_image count sector_size rootfs_a_start \ get_mender_disk_info $mender_disk_image count sector_size rootfs_a_start \
rootfs_a_size rootfs_b_start rootfs_b_size rootfs_a_size rootfs_b_start rootfs_b_size

277
mender-convert-functions.sh

@ -16,6 +16,9 @@ declare -i -r sectors=63
declare -a mender_disk_partitions=("boot" "primary" "secondary" "data") declare -a mender_disk_partitions=("boot" "primary" "secondary" "data")
declare -a raw_disk_partitions=("boot" "rootfs") declare -a raw_disk_partitions=("boot" "rootfs")
declare -A raw_disk_sizes
declare -A mender_disk_sizes
tool_dir="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" tool_dir="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
files_dir=${tool_dir}/files files_dir=${tool_dir}/files
output_dir=${tool_dir}/output output_dir=${tool_dir}/output
@ -126,62 +129,52 @@ EOF
# Calculates following values: # Calculates following values:
# #
# $2 - number of partitions # $2 - number of partitions
# $3 - size of the sector (in bytes) # $3 - sector size
# $4 - boot partition start offset (in sectors) # $4 - array of partitions' sizes for raw disk
# $5 - boot partition size (in sectors) #
# $6 - root filesystem partition start offset (in sectors) get_raw_disk_sizes() {
# $7 - root filesystem partition size (in sectors)
# $8 - boot flag
get_image_info() {
local limage=$1 local limage=$1
local rvar_count=$2 local rvar_count=$2
local rvar_sectorsize=$3 local rvar_sectorsize=$3
local rvar_bootstart=$4 shift 3
local rvar_bootsize=$5 local rvar_array=($@)
local rvar_rootfsstart=$6
local rvar_rootfssize=$7
local rvar_bootflag=$8
local lbootsize=0 local lsubname=${limage:0:10}
local lsubname=${limage:0:8}
local lfdisk="$(fdisk -u -l ${limage})" local lfdisk="$(fdisk -u -l ${limage})"
local lparts=($(echo "${lfdisk}" | grep "^${lsubname}" | cut -d' ' -f1)) local lparts=($(echo "${lfdisk}" | grep "^${lsubname}" | cut -d' ' -f1))
local lcount=${#lparts[@]} local lcount=${#lparts[@]}
if [[ $lcount -gt 2 ]]; then
log "\tError: invalid/unsupported raw disk image. Aborting."
return 1
fi
local lsectorsize=($(echo "${lfdisk}" | grep '^Sector' | cut -d' ' -f4)) local lsectorsize=($(echo "${lfdisk}" | grep '^Sector' | cut -d' ' -f4))
local lfirstpartinfo="$(echo "${lfdisk}" | grep "^${lparts[0]}")" local idx_start=2
local idx_size=4
idx_start=2 local lfirstpartinfo="$(echo "${lfdisk}" | grep "^${lparts[0]}")"
idx_size=4
if [[ $lcount -gt 1 ]]; then if [[ $lcount -gt 1 ]]; then
local lsecondpartinfo="$(echo "${lfdisk}" | grep "^${lparts[1]}")" local lsecondpartinfo="$(echo "${lfdisk}" | grep "^${lparts[1]}")"
local lsecondpartstart=($(echo "${lsecondpartinfo}" | tr -s ' ' | cut -d' ' -f${idx_start})) eval $rvar_array[prootfs_start]="'$(echo "${lsecondpartinfo}" | tr -s ' ' | cut -d' ' -f${idx_start})'"
local lsecondpartsize=($(echo "${lsecondpartinfo}" | tr -s ' ' | cut -d' ' -f${idx_size})) eval $rvar_array[prootfs_size]="'$(echo "${lsecondpartinfo}" | tr -s ' ' | cut -d' ' -f${idx_size})'"
fi fi
eval $rvar_bootflag="0" # Check is first partition is marked as bootable.
if [[ "$lfirstpartinfo" =~ .*\*.* ]]; then if [[ "$lfirstpartinfo" =~ .*\*.* ]]; then
eval $rvar_bootflag="1"
((idx_start+=1)) ((idx_start+=1))
((idx_size+=1)) ((idx_size+=1))
fi fi
lfirstpartsize=($(echo "${lfirstpartinfo}" | tr -s ' ' | cut -d' ' -f${idx_size})) eval $rvar_array[pboot_start]="'$(echo "${lfirstpartinfo}" | tr -s ' ' | cut -d' ' -f${idx_start})'"
lfirstpartstart=($(echo "${lfirstpartinfo}" | tr -s ' ' | cut -d' ' -f${idx_start})) eval $rvar_array[pboot_size]="'$(echo "${lfirstpartinfo}" | tr -s ' ' | cut -d' ' -f${idx_size})'"
eval $rvar_count="'$lcount'" eval $rvar_count="'$lcount'"
eval $rvar_sectorsize="'$lsectorsize'" eval $rvar_sectorsize="'$lsectorsize'"
eval $rvar_bootstart="'$lfirstpartstart'"
eval $rvar_bootsize="'$lfirstpartsize'" return 0
eval $rvar_rootfsstart="'$lsecondpartstart'"
eval $rvar_rootfssize="'$lsecondpartsize'"
[[ $lcount -gt 2 ]] && \
{ log "Unsupported type of source image. Aborting."; return 1; } || \
{ return 0; }
} }
# Takes the following argument # Takes the following argument
@ -191,7 +184,7 @@ get_image_info() {
# $2 - partition alignment # $2 - partition alignment
# $3 - vfat storage offset # $3 - vfat storage offset
set_boot_part_alignment() { set_mender_disk_alignment() {
local rvar_partition_alignment=$2 local rvar_partition_alignment=$2
local rvar_vfat_storage_offset=$3 local rvar_vfat_storage_offset=$3
@ -290,83 +283,76 @@ align_partition_size() {
# Takes following arguments: # Takes following arguments:
# #
# $1 - raw_disk image # $1 - number of partition of the raw disk image
# $2 - partition alignment # $2 - sector size of the raw disk image
# $3 - vfat storage offset # $3 - mender image partition alignment
# $4 - mender image's boot partition offset
# $5 - data partition size (in MB)
# $6 - array of partitions' sizes for raw image
# #
# Returns: # Returns:
# #
# $4 - boot partition start offset (in sectors) # $7 - array of partitions' sizes for Mender image
# $5 - boot partition size (in sectors) #
# $6 - root filesystem partition size (in sectors) set_mender_disk_sizes() {
# $7 - sector size (in bytes) local count=$1
# $8 - number of detected partitions local sectorsize=$2
analyse_raw_disk_image() { local alignment=$3
local image=$1 local offset=$4
local alignment=$2 local datasize=$(( ($5 * 1024 * 1024) / $2 ))
local offset=$3 local _raw_sizes=$(declare -p $6)
local count= eval "declare -A raw_sizes="${_raw_sizes#*=}
local sectorsize= shift 6
local rvar_array=($@)
local bootstart= local bootstart=
local bootsize= local bootsize=
local rootfsstart= local rootfsstart=
local rootfssize= local rootfssize=
local bootflag= local bootflag=
local rvar_bootstart=$4
local rvar_bootsize=$5
local rvar_rootfssize=$6
local rvar_sectorsize=$7
local rvar_partitions=$8
get_image_info $image count sectorsize bootstart bootsize rootfsstart \
rootfssize bootflag
[[ $? -ne 0 ]] && \
{ log "Error: invalid/unsupported raw disk image. Aborting."; exit 1; }
if [[ $count -eq 1 ]]; then if [[ $count -eq 1 ]]; then
rootfssize=$bootsize
# Default size of the boot partition: 16MiB. # Default size of the boot partition: 16MiB.
bootsize=$(( (${alignment} * 2) / ${sectorsize} )) bootsize=$(( (${alignment} * 2) / ${sectorsize} ))
# Root filesystem size is determined by the size of the single partition.
rootfssize=${raw_sizes[pboot_size]}
else
bootsize=${raw_sizes[pboot_size]}
rootfssize=${raw_sizes[prootfs_size]}
fi fi
# Boot partition storage offset is defined from the top down. # Boot partition storage offset is defined from the top down.
bootstart=$(( ${offset} / ${sectorsize} )) bootstart=$(( ${offset} / ${sectorsize} ))
align_partition_size bootsize $sectorsize align_partition_size bootsize $sectorsize
align_partition_size rootfssize $sectorsize align_partition_size rootfssize $sectorsize
align_partition_size datasize $sectorsize
eval $rvar_bootstart="'$bootstart'" eval $rvar_array[pboot_start]="'$bootstart'"
eval $rvar_bootsize="'$bootsize'" eval $rvar_array[pboot_size]="'$bootsize'"
eval $rvar_rootfssize="'$rootfssize'" eval $rvar_array[prootfs_size]="'$rootfssize'"
eval $rvar_sectorsize="'$sectorsize'" eval $rvar_array[pdata_size]="'$datasize'"
eval $rvar_partitions="'$count'"
} }
# Takes following arguments: # Takes following arguments:
# #
# $1 - boot partition start offset (in sectors) # $1 - sector size (in bytes)
# $2 - boot partition size (in sectors) # $2 - partition alignment
# $3 - root filesystem partition size (in sectors) # $3 - array of partitions' sizes for Mender image
# $4 - data partition size (in MB)
# $5 - sector size (in bytes)
# #
# Returns: # Returns:
# #
# $6 - aligned data partition size (in sectors) # $4 - final Mender disk image size (in bytes)
# $7 - final .sdimg file size (in bytes) #
calculate_mender_disk_size() { calculate_mender_disk_size() {
local rvar_datasize=$6 local _mender_sizes=$(declare -p $3)
local rvar_sdimgsize=$7 eval "declare -A mender_sizes="${_mender_sizes#*=}
local rvar_sdimgsize=$4
local datasize=$(( ($4 * 1024 * 1024) / $5 ))
align_partition_size datasize $5 local sdimgsize=$(( (${mender_sizes[pboot_start]} + ${mender_sizes[pboot_size]} + \
2 * ${mender_sizes[prootfs_size]} + \
${mender_sizes[pdata_size]}) * $1 ))
local sdimgsize=$(( ($1 + $2 + 2 * ${3} + $datasize) * $5 ))
eval $rvar_datasize="'$datasize'"
eval $rvar_sdimgsize="'$sdimgsize'" eval $rvar_sdimgsize="'$sdimgsize'"
} }
@ -396,35 +382,44 @@ create_mender_disk() {
# Takes following arguments: # Takes following arguments:
# #
# $1 - raw disk image path # $1 - Mender disk image path
# $2 - raw disk image size # $2 - Mender disk image size
# $3 - boot partition start offset # $3 - sector size in bytes
# $4 - boot partition size # $4 - partition alignment
# $5 - root filesystem partiotion size # $5 - array of partitions' sizes for Mender image
# $6 - data partition size #
# $7 - sector size # Returns:
#
# $6 - number of partitions of the Mender disk image
#
format_mender_disk() { format_mender_disk() {
local lfile=$1 local lfile=$1
local lsize=$2 local lsize=$2
local sectorsize=$3
local alignment=$(($4 / ${sectorsize}))
local rc=0
local _mender_sizes=$(declare -p $5)
eval "declare -A mender_sizes="${_mender_sizes#*=}
local rvar_counts=$6
cylinders=$(( ${lsize} / ${heads} / ${sectors} / ${sectorsize} ))
pboot_start=${mender_sizes[pboot_start]}
pboot_size=${mender_sizes[pboot_size]}
pboot_end=$((${pboot_start} + ${pboot_size} - 1))
# if [ -z "$3" ]; then prootfs_size=${mender_sizes[prootfs_size]}
# echo "Error: no root filesystem size provided"
# exit 1 prootfsa_start=$((${pboot_end} + 1))
# fi prootfsa_end=$((${prootfsa_start} + ${prootfs_size} - 1))
# if [ -z "$2" ]; then prootfsb_start=$((${prootfsa_end} + 1))
# size=$(sudo blockdev --getsize64 ${sdimg_file}) prootfsb_end=$((${prootfsb_start} + ${prootfs_size} - 1))
# else
# size=$2 pdata_start=$((${prootfsb_end} + 1))
# fi pdata_size=${mender_sizes[pdata_size]}
pdata_end=$((${pdata_start} + ${pdata_size} - 1))
cylinders=$(( ${lsize} / ${heads} / ${sectors} / ${7} ))
rootfs_size=$(( $5 - 1 ))
pboot_offset=$(( ${4} - 1 ))
primary_start=$(( ${3} + ${pboot_offset} + 1 ))
secondary_start=$(( ${primary_start} + ${rootfs_size} + 1 ))
data_start=$(( ${secondary_start} + ${rootfs_size} + 1 ))
data_offset=$(( ${6} - 1 ))
sed -e 's/\s*\([\+0-9a-zA-Z]*\).*/\1/' << EOF | sudo fdisk ${lfile} &> /dev/null sed -e 's/\s*\([\+0-9a-zA-Z]*\).*/\1/' << EOF | sudo fdisk ${lfile} &> /dev/null
o # clear the in memory partition table o # clear the in memory partition table
@ -436,56 +431,41 @@ format_mender_disk() {
c c
${cylinders} ${cylinders}
r r
n # new partition
p # primary partition
1 # partition number 1
${3} # default - start at beginning of disk
+${pboot_offset} # 16 MB boot parttion
t
c
a
n # new partition
p # primary partition
2 # partion number 2
${primary_start} # start immediately after preceding partition
+${rootfs_size}
n # new partition
p # primary partition
3 # partion number 3
${secondary_start} # start immediately after preceding partition
+${rootfs_size}
n # new partition
p # primary partition
${data_start} # start immediately after preceding partition
+${data_offset}
p # print the in-memory partition table
w # write the partition table w # write the partition table
q # and we're done q # and we're done
EOF EOF
log "\tChanges in partition table applied."
# Create partition table
sudo parted -s ${lfile} mklabel msdos || rc=$?
sudo parted -s ${lfile} unit s mkpart primary fat32 ${pboot_start} ${pboot_end} || rc=$?
sudo parted -s ${lfile} set 1 boot on || rc=$?
sudo parted -s ${lfile} -- unit s mkpart primary ext4 ${prootfsa_start} ${prootfsa_end} || rc=$?
sudo parted -s ${lfile} -- unit s mkpart primary ext4 ${prootfsb_start} ${prootfsb_end} || rc=$?
sudo parted -s ${lfile} -- unit s mkpart primary ext4 ${pdata_start} ${pdata_end} || rc=$?
eval $rvar_counts="'4'"
[[ $rc -eq 0 ]] && { log "\tChanges in partition table applied."; }
return $rc
} }
# Takes following arguments: # Takes following arguments:
# #
# $1 - raw disk file # $1 - raw disk file
# #
# Returns:
#
# $2 - number of detected partitions
verify_mender_disk() { verify_mender_disk() {
local lfile=$1 local lfile=$1
local rvar_no_of_parts=$2 local lcounts=$2
local limage=$(basename $lfile) local limage=$(basename $lfile)
local partitions=($(fdisk -l -u ${limage} | cut -d' ' -f1 | grep 'sdimg[1-9]\{1\}$')) local partitions=($(fdisk -l -u ${limage} | cut -d' ' -f1 | grep 'sdimg[1-9]\{1\}$'))
local no_of_parts=${#partitions[@]} local no_of_parts=${#partitions[@]}
[[ $no_of_parts -eq 4 ]] || \ [[ $no_of_parts -eq $lcounts ]] || \
{ log "Error: incorrect number of partitions: $no_of_parts. Aborting."; return 1; } { log "Error: incorrect number of partitions: $no_of_parts. Aborting."; return 1; }
eval $rvar_no_of_parts=="'$no_of_parts='"
return 0 return 0
} }
@ -653,21 +633,20 @@ extract_file_from_image() {
# #
# $1 - device type # $1 - device type
# $2 - partition alignment in bytes # $2 - partition alignment in bytes
# $3 - boot partition storage offset in bytes # $3 - total size in bytes
# $4 - boot partition size in sectors # $4 - sector size in bytes
# $5 - rootfs partition size in sectors # $5 - array of partitions' sizes for Mender image
# $6 - data partition size in sectors #
# $7 - complete image size in bytes
# $8 - sector size in bytes
create_test_config_file() { create_test_config_file() {
local device_type=$1 local device_type=$1
local alignment=$2 local alignment=$2
local boot_offset=$3 local mender_image_size_mb=$(( (($3 / 1024) / 1024) ))
local boot_size_mb=$(( ((($4 * $8) / 1024) / 1024) )) local _mender_sizes=$(declare -p $5)
local rootfs_size_mb=$(( ((($5 * $8) / 1024) / 1024) )) eval "declare -A mender_sizes="${_mender_sizes#*=}
local data_size_mb=$(( ((($6 * $8) / 1024) / 1024) )) local boot_offset=$(( (${mender_sizes[pboot_start]} * $4) ))
local mender_image_size_mb=$(( (($7 / 1024) / 1024) )) local boot_size_mb=$(( (((${mender_sizes[pboot_size]} * $4) / 1024) / 1024) ))
local rootfs_size_mb=$(( (((${mender_sizes[prootfs_size]} * $4) / 1024) / 1024) ))
local data_size_mb=$(( (((${mender_sizes[pdata_size]} * $4) / 1024) / 1024) ))
cp ${files_dir}/variables.template ${output_dir}/${device_type}_variables.cfg cp ${files_dir}/variables.template ${output_dir}/${device_type}_variables.cfg

Loading…
Cancel
Save