Browse Source

Merge pull request #220 from dellgreen/dpg/MEN-3725/partuuidSupport

Partition UUID support added for gpt/dos partition tables for deterministic booting
revert-252-rm-only-tag-2.2.x
Kristian Amlie 5 years ago
committed by GitHub
parent
commit
adebaf675d
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 7
      Dockerfile
  2. 15
      configs/mender_convert_config
  3. 38
      mender-convert-modify
  4. 43
      mender-convert-package
  5. 7
      modules/config.sh
  6. 183
      modules/disk.sh

7
Dockerfile

@ -21,8 +21,9 @@ RUN apt-get update && env DEBIAN_FRONTEND=noninteractive apt-get install -y \
file \ file \
# to copy files between rootfs directories # to copy files between rootfs directories
rsync \ rsync \
# to generate partition table # to generate partition table and alter partitions
parted \ parted \
gdisk \
# mkfs.ext4 and family # mkfs.ext4 and family
e2fsprogs \ e2fsprogs \
# mkfs.xfs and family # mkfs.xfs and family
@ -48,7 +49,9 @@ RUN apt-get update && env DEBIAN_FRONTEND=noninteractive apt-get install -y \
libgomp1 \ libgomp1 \
# zip and unzip archive # zip and unzip archive
zip \ zip \
unzip unzip \
# manipulate binary and hex
xxd
COPY --from=build /root/pxz/pxz /usr/bin/pxz COPY --from=build /root/pxz/pxz /usr/bin/pxz

15
configs/mender_convert_config

@ -122,6 +122,21 @@ MENDER_ROOTFS_PART_B_NUMBER="3"
# Partition number of persistent data partition # Partition number of persistent data partition
MENDER_DATA_PART_NUMBER="4" MENDER_DATA_PART_NUMBER="4"
# Use partition uuids rather than device and partition numbers
MENDER_ENABLE_PARTUUID="n"
# Partition used as the boot partition.
MENDER_BOOT_PART=""
# Partition used as the first (A) rootfs partition.
MENDER_ROOTFS_PART_A=""
# Partition used as the first (B) rootfs partition.
MENDER_ROOTFS_PART_B=""
# Partition used as the persistent data partition.
MENDER_DATA_PART=""
# Basename of DTB that should be loaded by the bootloader. # Basename of DTB that should be loaded by the bootloader.
MENDER_DTB_NAME=kernel.dtb MENDER_DTB_NAME=kernel.dtb

38
mender-convert-modify

@ -77,6 +77,12 @@ source modules/config.sh $(printf "%q " "${configs[@]}")
boot_part=$(disk_boot_part) boot_part=$(disk_boot_part)
root_part=$(disk_root_part) root_part=$(disk_root_part)
# Sysfs device paths
boot_part_device=$(disk_boot_part_device)
data_part_device=$(disk_data_part_device)
root_part_a_device=$(disk_root_part_a_device)
root_part_b_device=$(disk_root_part_b_device)
# Create mount points # Create mount points
mkdir -p work/boot mkdir -p work/boot
mkdir -p work/rootfs mkdir -p work/rootfs
@ -126,12 +132,27 @@ if [ "${MENDER_GRUB_EFI_INTEGRATION}" == "y" ]; then
cat <<- EOF > work/grub-mender-grubenv-${MENDER_GRUBENV_VERSION}/mender_grubenv_defines cat <<- EOF > work/grub-mender-grubenv-${MENDER_GRUBENV_VERSION}/mender_grubenv_defines
mender_rootfsa_part=${MENDER_ROOTFS_PART_A_NUMBER} mender_rootfsa_part=${MENDER_ROOTFS_PART_A_NUMBER}
mender_rootfsb_part=${MENDER_ROOTFS_PART_B_NUMBER} mender_rootfsb_part=${MENDER_ROOTFS_PART_B_NUMBER}
mender_kernel_root_base=${MENDER_STORAGE_DEVICE_BASE}
mender_grub_storage_device=${MENDER_GRUB_STORAGE_DEVICE} mender_grub_storage_device=${MENDER_GRUB_STORAGE_DEVICE}
kernel_imagetype=${kernel_imagetype} kernel_imagetype=${kernel_imagetype}
initrd_imagetype=${initrd_imagetype} initrd_imagetype=${initrd_imagetype}
EOF EOF
# For partuuid support grub.cfg expects dedicated variables to be added
if [ "${MENDER_ENABLE_PARTUUID}" == "y" ]; then
rootfsa_partuuid=$(disk_get_partuuid_from_device "${root_part_a_device}")
rootfsb_partuuid=$(disk_get_partuuid_from_device "${root_part_b_device}")
log_info "Using root partition A partuuid in grubenv: $rootfsa_partuuid"
log_info "Using root partition B partuuid in grubenv: $rootfsb_partuuid"
cat <<- EOF >> work/grub-mender-grubenv-${MENDER_GRUBENV_VERSION}/mender_grubenv_defines
mender_rootfsa_uuid=${rootfsa_partuuid}
mender_rootfsb_uuid=${rootfsb_partuuid}
EOF
else
cat <<- EOF >> work/grub-mender-grubenv-${MENDER_GRUBENV_VERSION}/mender_grubenv_defines
mender_kernel_root_base=${MENDER_STORAGE_DEVICE_BASE}
EOF
fi
if [ -n "${MENDER_GRUB_KERNEL_BOOT_ARGS}" ]; then if [ -n "${MENDER_GRUB_KERNEL_BOOT_ARGS}" ]; then
cat <<- EOF > work/grub-mender-grubenv-${MENDER_GRUBENV_VERSION}/11_bootargs_grub.cfg cat <<- EOF > work/grub-mender-grubenv-${MENDER_GRUBENV_VERSION}/11_bootargs_grub.cfg
set bootargs="${MENDER_GRUB_KERNEL_BOOT_ARGS}" set bootargs="${MENDER_GRUB_KERNEL_BOOT_ARGS}"
@ -185,10 +206,13 @@ fi
run_and_log_cmd "sudo mkdir -p work/rootfs/data/mender" run_and_log_cmd "sudo mkdir -p work/rootfs/data/mender"
run_and_log_cmd "sudo ln -sf /data/mender work/rootfs/var/lib/mender" run_and_log_cmd "sudo ln -sf /data/mender work/rootfs/var/lib/mender"
log_info "Using root device A in mender.conf: $root_part_a_device"
log_info "Using root device B in mender.conf: $root_part_b_device"
cat <<- EOF > work/mender.conf.data cat <<- EOF > work/mender.conf.data
{ {
"RootfsPartA": "${MENDER_STORAGE_DEVICE_BASE}${MENDER_ROOTFS_PART_A_NUMBER}", "RootfsPartA": "${root_part_a_device}",
"RootfsPartB": "${MENDER_STORAGE_DEVICE_BASE}${MENDER_ROOTFS_PART_B_NUMBER}" "RootfsPartB": "${root_part_b_device}"
} }
EOF EOF
@ -233,13 +257,17 @@ if [ "${MENDER_DATA_PART_GROWFS}" == "y" ]; then
MENDER_DATA_PART_FSTAB_OPTS="${MENDER_DATA_PART_FSTAB_OPTS},x-systemd.growfs" MENDER_DATA_PART_FSTAB_OPTS="${MENDER_DATA_PART_FSTAB_OPTS},x-systemd.growfs"
fi fi
log_info "Using boot partition device in fstab: $boot_part_device"
log_info "Using data partition device in fstab: $data_part_device"
sudo bash -c "cat <<- EOF > work/rootfs/etc/fstab sudo bash -c "cat <<- EOF > work/rootfs/etc/fstab
# stock fstab - you probably want to override this with a machine specific one # stock fstab - you probably want to override this with a machine specific one
/dev/root / auto defaults 1 1 /dev/root / auto defaults 1 1
proc /proc proc defaults 0 0 proc /proc proc defaults 0 0
${MENDER_STORAGE_DEVICE_BASE}${MENDER_BOOT_PART_NUMBER} ${boot_part_mountpoint} auto defaults,sync 0 0 ${boot_part_device} ${boot_part_mountpoint} auto defaults,sync 0 0
${MENDER_STORAGE_DEVICE_BASE}${MENDER_DATA_PART_NUMBER} /data auto ${MENDER_DATA_PART_FSTAB_OPTS} 0 0 ${data_part_device} /data auto ${MENDER_DATA_PART_FSTAB_OPTS} 0 0
EOF" EOF"
log_info "Performing platform specific modifications (if any)" log_info "Performing platform specific modifications (if any)"

43
mender-convert-package

@ -78,6 +78,12 @@ output_dir=work
boot_part=$(disk_boot_part) boot_part=$(disk_boot_part)
root_part=$(disk_root_part) root_part=$(disk_root_part)
# Sysfs device paths
boot_part_device=$(disk_boot_part_device)
data_part_device=$(disk_data_part_device)
root_part_a_device=$(disk_root_part_a_device)
root_part_b_device=$(disk_root_part_b_device)
# Final output # Final output
mkdir -p deploy mkdir -p deploy
@ -249,6 +255,27 @@ run_and_log_cmd "${PARTED} -s ${img_path} -- unit s mkpart primary ext2 ${rootfs
run_and_log_cmd "${PARTED} -s ${img_path} -- unit s mkpart primary ext2 ${data_start} ${data_end}" run_and_log_cmd "${PARTED} -s ${img_path} -- unit s mkpart primary ext2 ${data_start} ${data_end}"
run_and_log_cmd "${PARTED} -s ${img_path} print" run_and_log_cmd "${PARTED} -s ${img_path} print"
# Update partition uuids if required
if [ "${MENDER_ENABLE_PARTUUID}" == "y" ]; then
boot_partuuid=$(disk_get_partuuid_from_device "${boot_part_device}")
rootfsa_partuuid=$(disk_get_partuuid_from_device "${root_part_a_device}")
rootfsb_partuuid=$(disk_get_partuuid_from_device "${root_part_b_device}")
data_partuuid=$(disk_get_partuuid_from_device "${data_part_device}")
if [ "${partition_scheme}" == "gpt" ]; then
log_info "Updating GPT partition uuids in image: '${img_path}'"
run_and_log_cmd "sgdisk -u ${MENDER_BOOT_PART_NUMBER}:${boot_partuuid} '${img_path}'"
run_and_log_cmd "sgdisk -u ${MENDER_ROOTFS_PART_A_NUMBER}:${rootfsa_partuuid} '${img_path}'"
run_and_log_cmd "sgdisk -u ${MENDER_ROOTFS_PART_B_NUMBER}:${rootfsb_partuuid} '${img_path}'"
run_and_log_cmd "sgdisk -u ${MENDER_DATA_PART_NUMBER}:${data_partuuid} '${img_path}'"
else
diskid=$(disk_get_partuuid_dos_diskid_from_device "${root_part_a_device}")
log_info "Updating MBR disk identifier for partition uuid support to: '0x${diskid}'"
run_and_log_cmd "xxd -r -p <<< '${diskid}' | LC_ALL=C rev | dd of='${img_path}' bs=1 seek=440 count=4 conv=notrunc"
fi
fi
# Write boot-gap # Write boot-gap
if [ "${MENDER_COPY_BOOT_GAP}" == "y" ]; then if [ "${MENDER_COPY_BOOT_GAP}" == "y" ]; then
log_info "Writing boot gap of size: ${boot_part_sectors} (sectors)" log_info "Writing boot gap of size: ${boot_part_sectors} (sectors)"
@ -324,16 +351,16 @@ fi
distro_feature="${distro_feature} mender-convert" distro_feature="${distro_feature} mender-convert"
cat <<- EOF > deploy/${image_name}.cfg cat <<- EOF > deploy/${image_name}.cfg
MENDER_BOOT_PART="${MENDER_STORAGE_DEVICE_BASE}${MENDER_BOOT_PART_NUMBER}" MENDER_BOOT_PART="${boot_part_device}"
MENDER_ROOTFS_PART_A="${MENDER_STORAGE_DEVICE_BASE}${MENDER_ROOTFS_PART_A_NUMBER}" MENDER_ROOTFS_PART_A="${root_part_a_device}"
MENDER_ROOTFS_PART_B="${MENDER_STORAGE_DEVICE_BASE}${MENDER_ROOTFS_PART_B_NUMBER}" MENDER_ROOTFS_PART_B="${root_part_b_device}"
MENDER_DATA_PART="${data_part_device}"
MENDER_BOOT_PART_MOUNT_LOCATION="${boot_part_mountpoint}" MENDER_BOOT_PART_MOUNT_LOCATION="${boot_part_mountpoint}"
MENDER_BOOT_PART_SIZE_MB="$(disk_sectors_to_mb ${boot_part_sectors})" MENDER_BOOT_PART_SIZE_MB="$(disk_sectors_to_mb ${boot_part_sectors})"
MENDER_DATA_PART_SIZE_MB="${MENDER_DATA_PART_SIZE_MB}" MENDER_DATA_PART_SIZE_MB="${MENDER_DATA_PART_SIZE_MB}"
MENDER_DEVICE_TYPE="${device_type}" MENDER_DEVICE_TYPE="${device_type}"
MENDER_PARTITIONING_OVERHEAD_KB="$(( (${overhead_sectors} * 512) / 1024 ))" MENDER_PARTITIONING_OVERHEAD_KB="$(( (${overhead_sectors} * 512) / 1024 ))"
MENDER_PARTITION_ALIGNMENT="${MENDER_PARTITION_ALIGNMENT}" MENDER_PARTITION_ALIGNMENT="${MENDER_PARTITION_ALIGNMENT}"
MENDER_STORAGE_DEVICE_BASE="${MENDER_STORAGE_DEVICE_BASE}"
MENDER_STORAGE_TOTAL_SIZE_MB="${MENDER_STORAGE_TOTAL_SIZE_MB}" MENDER_STORAGE_TOTAL_SIZE_MB="${MENDER_STORAGE_TOTAL_SIZE_MB}"
MENDER_UBOOT_ENV_STORAGE_DEVICE_OFFSET="12582912" MENDER_UBOOT_ENV_STORAGE_DEVICE_OFFSET="12582912"
MENDER_ARTIFACT_NAME="${artifact_name}" MENDER_ARTIFACT_NAME="${artifact_name}"
@ -342,6 +369,14 @@ DEPLOY_DIR_IMAGE="${PWD}/deploy"
MENDER_MACHINE="${device_type}" MENDER_MACHINE="${device_type}"
EOF EOF
# Outputting device base only relevant for some configurations
if [ "${MENDER_ENABLE_PARTUUID}" != "y" ]; then
cat <<- EOF >> deploy/${image_name}.cfg
MENDER_STORAGE_DEVICE_BASE="${MENDER_STORAGE_DEVICE_BASE}"
EOF
fi
# Something that the tests expect to be defined (originally from Yocto) # Something that the tests expect to be defined (originally from Yocto)
cat <<- EOF >> deploy/${image_name}.cfg cat <<- EOF >> deploy/${image_name}.cfg
IMAGE_FSTYPES="${image_fs_type} mender sdimg" IMAGE_FSTYPES="${image_fs_type} mender sdimg"

7
modules/config.sh

@ -20,3 +20,10 @@ for config in "${configs[@]}"; do
log_info "Using configuration file: ${config}" log_info "Using configuration file: ${config}"
source "${config}" source "${config}"
done done
# Fine grained partition variables override device/number variables where applicable
disk_override_partition_variable "MENDER_BOOT_PART_NUMBER" "${MENDER_BOOT_PART}"
disk_override_partition_variable "MENDER_ROOTFS_PART_A_NUMBER" "${MENDER_ROOTFS_PART_A}"
disk_override_partition_variable "MENDER_ROOTFS_PART_B_NUMBER" "${MENDER_ROOTFS_PART_B}"
disk_override_partition_variable "MENDER_DATA_PART_NUMBER" "${MENDER_DATA_PART}"

183
modules/disk.sh

@ -178,3 +178,186 @@ disk_root_part() {
fi fi
echo "${root_part}" echo "${root_part}"
} }
# Check if supplied argument is valid partuuid device path.
# Supports both dos and gpt paths
#
# $1 - partuuid device path
disk_is_valid_partuuid_device() {
disk_is_valid_partuuid_gpt_device "$1" || disk_is_valid_partuuid_dos_device "$1"
}
# Check if supplied argument is valid gpt partuuid device path.
#
# Example: /dev/disk/by-partuuid/26445670-f37c-408b-be2c-3ef419866620
#
# $1 - gpt partuuid device path
disk_is_valid_partuuid_gpt_device() {
echo "${1}" | grep -qE '^/dev/disk/by-partuuid/([0-9a-f]{8}(-[0-9a-f]{4}){3}-[0-9a-f]{12})$'
}
# Check if supplied argument is valid dos partuuid device path.
#
# Example: /dev/disk/by-partuuid/26445670-01
#
# $1 - dos partuuid device path
disk_is_valid_partuuid_dos_device() {
echo "${1}" | grep -qE '^/dev/disk/by-partuuid/[0-9a-f]{8}-[0-9a-f]{2}$'
}
# Get partuuid from supplied device path.
# Supports both dos and gpt paths
#
# $1 - partuuid device path
disk_get_partuuid_from_device() {
if ! disk_is_valid_partuuid_device "${1}"; then
log_fatal "Invalid partuuid device: '${1}'"
fi
echo "${1}" | sed "s:/dev/disk/by-partuuid/::"
}
# Get dos disk identifier from supplied device path.
#
# $1 - dos compatible partuuid device path
disk_get_partuuid_dos_diskid_from_device() {
if ! disk_is_valid_partuuid_dos_device "${1}"; then
log_fatal "Invalid dos partuuid device: '${1}'"
fi
partuuid=$(disk_get_partuuid_from_device "${1}")
echo "$partuuid" | cut -d- -f1
}
# Get dos partuuid number from supplied device path.
#
# $1 - dos compatible partuuid device path
disk_get_partuuid_dos_part_number() {
if ! disk_is_valid_partuuid_dos_device "${1}"; then
log_fatal "Invalid dos partuuid device: '${1}'"
fi
partuuid=$(disk_get_partuuid_from_device "${1}")
echo "$partuuid" | cut -d- -f2
}
# Get correct device path for current configuration.
# Unrecognized or unsupported device paths will generate an error
#
# $1 - partition number to use if fine grained variable not set
# $2 - fine grained device part variable name
disk_get_part_device() {
part="${!2}"
if [ "${MENDER_ENABLE_PARTUUID}" == "y" ]; then
if ! disk_is_valid_partuuid_device "${part}"; then
log_fatal "Invalid partuuid device for ${2}: '${part}'"
fi
else
part="${MENDER_STORAGE_DEVICE_BASE}${1}"
fi
echo "${part}"
}
disk_boot_part_device() {
disk_get_part_device "${MENDER_BOOT_PART_NUMBER}" "MENDER_BOOT_PART"
}
disk_data_part_device() {
disk_get_part_device "${MENDER_DATA_PART_NUMBER}" "MENDER_DATA_PART"
}
disk_root_part_a_device() {
disk_get_part_device "${MENDER_ROOTFS_PART_A_NUMBER}" "MENDER_ROOTFS_PART_A"
}
disk_root_part_b_device() {
disk_get_part_device "${MENDER_ROOTFS_PART_B_NUMBER}" "MENDER_ROOTFS_PART_B"
}
# Get device partition number from device path.
# Unrecognized or unsupported device paths will generate an error
#
# $1 - device path
disk_get_device_part_number() {
dev_part="unknown"
case "$1" in
/dev/nvme*n*p* )
dev_part=$(echo $1 | cut -dp -f2)
;;
/dev/mmcblk*p* )
dev_part=$(echo $1 | cut -dp -f2)
;;
/dev/[sh]d[a-z][1-9]* )
dev_part=${1##*d[a-z]}
;;
ubi*_* )
dev_part=$(echo $1 | cut -d_ -f2)
;;
/dev/disk/by-partuuid/* )
if disk_is_valid_partuuid_dos_device "$1";then
dev_part=$(disk_get_partuuid_dos_part_number "$1")
dev_part=$((16#${dev_part}))
else
log_fatal "partition number does not exist for GPT partuuid: '$1'"
fi
;;
esac
part=$(printf "%d" $dev_part 2>/dev/null)
if [ $? = 1 ]; then
log_fatal "Could not determine partition number from '${1}'"
else
echo "$part"
fi
}
# Get device base path without partition number from argument.
# Unrecognized or unsupported device paths will generate an error
#
# $1 - device path
disk_get_device_base() {
dev_base=""
case "$1" in
/dev/nvme*n*p* )
dev_base=$(echo $1 | cut -dp -f1)
;;
/dev/mmcblk*p* )
dev_base=$(echo $1 | cut -dp -f1)
;;
/dev/[sh]d[a-z][1-9]* )
dev_base=${1%%[1-9]*}
;;
ubi*_* )
dev_base=$(echo $1 | cut -d_ -f1)
;;
/dev/disk/by-partuuid/* )
log_fatal "device base does not exist for GPT partuuid: '$1'"
;;
esac
if [ -z "$dev_base" ]; then
log_fatal "Could not determine device base from '${1}'"
else
echo $dev_base
fi
}
# Conditionally redefine partition number/device if fine grained variable set.
#
# $1 - variable name
# $2 - variable value
disk_override_partition_variable() {
if [ "${MENDER_ENABLE_PARTUUID}" == "y" ]; then
if disk_is_valid_partuuid_dos_device "${2}";then
eval "${1}"=$(disk_get_device_part_number "${2}")
fi
else
if [ -n "${2}" ];then
eval "${1}"=$(disk_get_device_part_number "${2}")
MENDER_STORAGE_DEVICE_BASE=$(disk_get_device_base "${2}")
fi
fi
}
Loading…
Cancel
Save