Skip to content

Commit

Permalink
alpine: avoid wiping out writable host mounts under /home, etc.
Browse files Browse the repository at this point in the history
A host directory could be wiped out when all the following conditions are met:
- The directory is mounted to Lima via virtiofs, or, potentially 9p
- The mount is writable
- The mount point in the guest is under one of: /etc /home /root /usr/local /var/lib
- The guest OS is Alpine Linux

Fix issue 2221
Fix rancher-sandbox/rancher-desktop issue 6582

Signed-off-by: Akihiro Suda <akihiro.suda.cz@hco.ntt.co.jp>
  • Loading branch information
AkihiroSuda committed Mar 9, 2024
1 parent 1ac49b3 commit 8781f6d
Showing 1 changed file with 23 additions and 7 deletions.
30 changes: 23 additions & 7 deletions pkg/cidata/cidata.TEMPLATE.d/boot/04-persistent-data-volume.sh
Original file line number Diff line number Diff line change
Expand Up @@ -61,21 +61,37 @@ if [ "$(awk '$2 == "/" {print $3}' /proc/mounts)" == "tmpfs" ]; then
PART=$(lsblk --list /dev/"${DISK}" --noheadings --output name,type | awk '$2 == "part" {print $1}')
mkfs.ext4 -L data-volume /dev/"${PART}"
mount -t ext4 /dev/disk/by-label/data-volume /mnt/data
# Unmount all mount points under /tmp so we can move it to the data volume:
# "mount1 on /tmp/lima type 9p (rw,dirsync,relatime,mmap,access=client,trans=virtio)"
for MP in $(mount | awk '$3 ~ /^\/tmp\// {print $3}'); do
umount "${MP}"
done
# setup apk package cache
mkdir -p /mnt/data/apk/cache
mkdir -p /etc/apk
ln -s /mnt/data/apk/cache /etc/apk/cache
# Prepare mnt.sh (used for restoring mounts later)
echo "#!/bin/sh" >/mnt/data/mnt.sh
echo "set -eux" >>/mnt/data/mnt.sh
# Move all persisted directories to the data volume
for DIR in ${DATADIRS}; do
DEST="/mnt/data$(dirname "${DIR}")"
mkdir -p "${DIR}" "${DEST}"
while IFS= read -r LINE; do
[ -z "$LINE" ] && continue
MNTDEV="$(echo "${LINE}" | awk '{print $1}')"
# unmangle " \t\n\\#"
# https://github.com/torvalds/linux/blob/v6.6/fs/proc_namespace.c#L89
MNTPNT="$(echo "${LINE}" | awk '{print $2}' | sed -e 's/\\040/ /g; s/\\011/\t/g; s/\\012/\n/g; s/\\134/\\/g; s/\\043/#/g')"
# This comparison needs [[, not [
[[ "${MNTPNT}" != "${DIR}*" ]] && continue
MNTTYPE="$(echo "${LINE}" | awk '{print $3}')"
[ "${MNTTYPE}" = "ext4" ] && continue
[ "${MNTTYPE}" = "tmpfs" ] && continue
MNTOPTS="$(echo "${LINE}" | awk '{print $4}')"
echo "mount -t ${MNTTYPE} -o ${MNTOPTS} ${MNTDEV} ${MNTPNT}" >>/mnt.tmp.sh
# Before mv, unmount filesystems (virtiofs, 9p, etc.) below "${DIR}", otherwise host mounts will be wiped out
# https://github.com/rancher-sandbox/rancher-desktop/issues/6582
umount "${MNTPNT}" || exit 1
done </proc/mounts
mv "${DIR}" "${DEST}"
done
chmod +x /mnt/data/mnt.sh
# Make sure all data moved to the persistent volume has been committed to disk
sync
break
Expand All @@ -88,8 +104,8 @@ if [ "$(awk '$2 == "/" {print $3}' /proc/mounts)" == "tmpfs" ]; then
mount --bind /mnt/data"${DIR}" "${DIR}"
fi
done
# Make sure to re-mount any mount points under /tmp
mount -a
# Remount submounts on top of the new ${DIR}
/mnt.tmp.sh
# Reinstall packages from /mnt/data/apk/cache into the RAM disk
apk fix --no-network
fi

0 comments on commit 8781f6d

Please sign in to comment.