sonic-buildimage/files/initramfs-tools/union-mount.j2
Saikrishna Arcot 26079ac8f9 Specify the filesystem type when mounting to /host (#10169)
When mounting the partition that contains `/host` during initramfs, the
mount binary available there (coming from busybox) tries each filesystem
in `/proc/filesystems` and sees which one succeeds. During this time,
there may be some error messages logged into dmesg because some of the
incorrect filesystems failed to mount the partition.

Specify the filesystem type explicitly so that initramfs knows it's that
type, and we know what filesystem will always get used there.

Fixes #9998

Signed-off-by: Saikrishna Arcot <sarcot@microsoft.com>
2022-03-20 15:26:06 -07:00

192 lines
6.4 KiB
Django/Jinja

#!/bin/sh -e
PREREQS="varlog"
prereqs() { echo "$PREREQS"; }
case $1 in
prereqs)
prereqs
exit 0
;;
esac
docker_inram=false
logs_inram=false
secureboot=false
bootloader=generic
in_kdump=false
varlog_size=0
# Extract kernel parameters
for x in $(cat /proc/cmdline); do
case "$x" in
Aboot=*)
bootloader=aboot
;;
docker_inram=on)
docker_inram=true
;;
logs_inram=on)
logs_inram=true
;;
varlog_size=*)
varlog_size="${x#varlog_size=}"
;;
secure_boot_enable=[y1])
secureboot=true
docker_inram=true
;;
platform=*)
platform_flag="${x#platform=}"
;;
systemd.unit=kdump-tools.service)
in_kdump=true
;;
esac
done
set_tmpfs_log_partition_size()
{
if [ $varlog_size -gt 0 ]; then
# Use the varlog_size passed in from command line
varlogsize=$varlog_size
else
varlogsize=128
# set varlogsize to existing var-log.ext4 size
if [ -f ${rootmnt}/host/disk-img/var-log.ext4 ]; then
varlogsize=$(ls -l ${rootmnt}/host/disk-img/var-log.ext4 | awk '{print $5}')
varlogsize=$(($varlogsize/1024/1024))
fi
fi
# make sure varlogsize is between 5% to 10% of total memory size
memkb=$(grep MemTotal /proc/meminfo | awk '{print $2}')
memmb=$(($memkb/1024))
minsize=$(($memmb*5/100))
maxsize=$(($memmb*10/100))
if [ $minsize -ge $varlogsize ]; then
varlogsize=$minsize
fi
if [ $maxsize -le $varlogsize ]; then
varlogsize=$maxsize
fi
}
remove_not_in_allowlist_files()
{
local allowlist_file="$1"
local targeted_dir="$2"
local allowlist_pattern_file=/tmp/allowlist_paths.pattern
# Return if the allowlist file does not exist
if ! test -f "${allowlist_file}"; then
echo "The file ${allowlist_file} is missing, failed to mount rw folder." 1>&2
exit 1
fi
# Set the grep pattern file, remove the blank line in config file
awk -v rw_dir="$targeted_dir" 'NF {print rw_dir"/"$0"$"}' ${allowlist_file} > $allowlist_pattern_file
# Find the files in the rw folder, and remove the files not in the allowlist
find ${targeted_dir} -type f | grep -v -f $allowlist_pattern_file | xargs /bin/rm -f
rm -f $allowlist_pattern_file
}
## Mount the overlay file system: rw layer over squashfs
image_dir=$(cat /proc/cmdline | sed -e 's/.*loop=\(\S*\)\/.*/\1/')
rw_dir=${rootmnt}/host/$image_dir/rw
work_dir=${rootmnt}/host/$image_dir/work
mkdir -p "$rw_dir"
mkdir -p "$work_dir"
## Remove the files not in allowlist in the rw folder
if [ "$secureboot" = true ] && [ "$in_kdump" = false ]; then
if [ "$bootloader" = "aboot" ]; then
swi_path="${rootmnt}/host/$(sed -E 's/.*loop=([^ ]+).*/\1/' /proc/cmdline)"
unzip -q "$swi_path" allowlist_paths.conf -d /tmp
allowlist_file=/tmp/allowlist_paths.conf
else
allowlist_file=${rootmnt}/host/$image_dir/allowlist_paths.conf
fi
remove_not_in_allowlist_files "$allowlist_file" "$rw_dir"
## Remove the executable permission for all the files in rw folder except home folder
find ${rw_dir} -type f -not -path ${rw_dir}/home -exec chmod a-x {} +
fi
mount -n -o lowerdir=${rootmnt},upperdir=${rw_dir},workdir=${work_dir} -t overlay root-overlay ${rootmnt}
## Check if the root block device is still there
[ -b ${ROOT} ] || mdev -s
case "${ROOT}" in
ubi*)
mtd=$(cat /proc/cmdline | sed -e 's/.*ubi.mtd=\([0-9]\) .*/\1/')
if [ ! -f /dev/${ROOT}_0 ]; then
ubiattach /dev/ubi_ctrl -m $mtd 2>dev/null || true
fi
mount -t ubifs /dev/${ROOT}_0 ${rootmnt}/host
;;
*)
## Mount the raw partition again
mount -t ext4 ${ROOT} ${rootmnt}/host
;;
esac
mkdir -p ${rootmnt}/var/lib/docker
if [ "$in_kdump" = false ]; then
if [ "$secureboot" = true ]; then
mount -t tmpfs -o rw,nodev,size={{ DOCKER_RAMFS_SIZE }} tmpfs ${rootmnt}/var/lib/docker
if [ "$bootloader" = "aboot" ]; then
unzip -qp "$swi_path" dockerfs.tar.gz | tar xz --numeric-owner -C ${rootmnt}/var/lib/docker
## Boot folder is not extracted during secureboot since content would inherently become unsafe
mkdir -p ${rootmnt}/host/$image_dir/boot
else
echo "secureboot unsupported for bootloader $bootloader" 1>&2
exit 1
fi
elif [ -f ${rootmnt}/host/$image_dir/{{ FILESYSTEM_DOCKERFS }} ]; then
## mount tmpfs and extract docker into it
mount -t tmpfs -o rw,nodev,size={{ DOCKER_RAMFS_SIZE }} tmpfs ${rootmnt}/var/lib/docker
tar xz --numeric-owner -f ${rootmnt}/host/$image_dir/{{ FILESYSTEM_DOCKERFS }} -C ${rootmnt}/var/lib/docker
else
## Mount the working directory of docker engine in the raw partition, bypass the overlay
mount --bind ${rootmnt}/host/$image_dir/{{ DOCKERFS_DIR }} ${rootmnt}/var/lib/docker
fi
fi
## Mount the boot directory in the raw partition, bypass the overlay
mkdir -p ${rootmnt}/boot
mount --bind ${rootmnt}/host/$image_dir/boot ${rootmnt}/boot
## Mount loop device or tmpfs for /var/log
if $logs_inram; then
# NOTE: some platforms, when reaching initramfs stage, have a small
# limit of mounting tmpfs partition, potentially due to amount
# of RAM available in this stage. Therefore limiting the size
# set for tmpfs partitions.
#
# Another reason for using tmpfs /var/log partition is:
# Some platforms have a small flash and therefore the log partition takes valuable space.
# To improve the longevity of these devices storing the logs in memory will permit more
# SONiC image growth before being bottlenecked.
set_tmpfs_log_partition_size
mount -t tmpfs -o rw,nosuid,nodev,size=${varlogsize}M tmpfs ${rootmnt}/var/log
if [ -f ${rootmnt}/host/disk-img/var-log.ext4 ]; then
rm -rf ${rootmnt}/host/disk-img/var-log.ext4
fi
else
if [ -f ${rootmnt}/host/disk-img/var-log.ext4 ]; then
fsck.ext4 -v -p ${rootmnt}/host/disk-img/var-log.ext4 2>&1 | gzip -c >> /tmp/fsck.log.gz
mount -t ext4 -o loop,rw ${rootmnt}/host/disk-img/var-log.ext4 ${rootmnt}/var/log
fi
fi
## fscklog file: /tmp will be lost when overlayfs is mounted
if [ -f /tmp/fsck.log.gz ]; then
mv /tmp/fsck.log.gz ${rootmnt}/var/log
fi