system: rework growfs and allow ZFS grow; closes #5576

Enhances scope beyond nano images and can extend all devices of
a ZFS pool but for now we settle for testing a single device pool.
This commit is contained in:
Franco Fichtner 2022-02-16 15:15:54 +01:00
parent 8a2c3d81a3
commit ea3facd2db

View File

@ -1,6 +1,6 @@
#!/bin/sh
# Copyright (c) 2014-2019 Franco Fichtner <franco@opnsense.org>
# Copyright (c) 2014-2022 Franco Fichtner <franco@opnsense.org>
# Copyright (c) 2004-2010 Scott Ullrich <sullrich@gmail.com>
# Copyright (c) 2003-2004 Manuel Kasper <mk@neon1.net>
# All rights reserved.
@ -43,11 +43,36 @@ export HOME PATH REQUESTS_CA_BUNDLE
echo "Mounting filesystems..."
grow_partition()
{
local DEV=$(echo "${1}" | awk 'match($0, /^[a-z]+[0-9]+/) { print substr( $0, RSTART, RLENGTH )}')
local IDX=${1##"${DEV}p"}
if [ "${IDX}" = "${1}" ]; then
# assume schema ada0a used by nano images
IDX=1
fi
if [ -n "${DEV}" -a "${DEV}" != "${1}" -a \
-n "${IDX}" -a "${IDX}" != "${1}" ]; then
gpart recover ${DEV}
gpart resize -i ${IDX} ${DEV}
fi
}
# tunefs may refuse otherwise
mount -fr / 2> /dev/null
GROWFS_MARKER=/.probe.for.growfs.nano
ROOT_IS_UFS=
ROOT_IS_ZFS=$(
df -hT | while read FS TYPE SIZE USED AVAIL CAP MOUNT MORE; do
if [ "${TYPE}" = "zfs" -a "${MOUNT}" = "/" ]; then
echo ${FS%%/*}
return
fi
done
)
while read FS_PART FS_MNT FS_TYPE FS_MORE; do
# only tune our own file systems
@ -55,9 +80,17 @@ while read FS_PART FS_MNT FS_TYPE FS_MORE; do
continue;
fi
# marker for running fsck in a bit
if [ "${FS_MNT}" = "/" ]; then
ROOT_IS_UFS=yes
# translate labels into devices names
FS_LABEL=$(echo ${FS_PART} | awk 'match($0, /^\/dev\/(gpt|ufs)\/.+$/) { print substr( $0, RSTART + 5, RLENGTH - 5 )}')
if [ -n "${FS_LABEL}" ]; then
FS_PART=$(glabel status -as | grep ${FS_LABEL} | awk '{ print $3 }')
FS_DEV=$(echo ${FS_PART} | awk 'match($0, /^[a-z]+[0-9]+/) { print substr( $0, RSTART, RLENGTH )}')
fi
# normalize devices names
if [ -z "${FS_DEV}" ]; then
FS_PART=${FS_PART##/dev/}
FS_DEV=$(echo ${FS_PART} | awk 'match($0, /^[a-z]+[0-9]+/) { print substr( $0, RSTART, RLENGTH )}')
fi
if echo "${FS_MORE}" | grep -iq nosoft; then
@ -69,19 +102,7 @@ while read FS_PART FS_MNT FS_TYPE FS_MORE; do
tunefs -n enable ${FS_MNT}
fi
FS_DEV=$(echo ${FS_PART} | awk 'match($0, /^\/dev\/(gpt|ufs)\/.+$/) { print substr( $0, RSTART + 5, RLENGTH - 5 )}')
if [ -n "${FS_DEV}" ]; then
FS_DEV=$(glabel status -as | grep ${FS_DEV} | awk 'match($3, /^[a-z]+[0-9]+/) { print substr( $3, RSTART, RLENGTH )}')
if [ "${FS_MNT}" = "/" -a -f ${GROWFS_MARKER} ]; then
# hammertime!
gpart recover ${FS_DEV}
gpart resize -i 1 ${FS_DEV}
growfs -y ${FS_MNT}
fi
fi
if [ -z "${FS_DEV}" ]; then
FS_DEV=$(echo ${FS_PART} | awk 'match($0, /^\/dev\/[a-z]+[0-9]+/) { print substr( $0, RSTART + 5, RLENGTH - 5 )}')
fi
# trim fun if possible
if [ -n "${FS_DEV}" ]; then
FS_TRIM=$(camcontrol identify ${FS_DEV} | grep TRIM | awk '{ print $5; }')
if [ "${FS_TRIM}" = "yes" ]; then
@ -95,8 +116,29 @@ while read FS_PART FS_MNT FS_TYPE FS_MORE; do
fi
fi
fi
# marker for running fsck or growfs in a bit
if [ "${FS_MNT}" = "/" ]; then
ROOT_IS_UFS=${FS_PART}
fi
done < /etc/fstab
if [ -f ${GROWFS_MARKER} ]; then
# hammertime!
if [ -n "${ROOT_IS_UFS}" ]; then
grow_partition ${ROOT_IS_UFS}
growfs -y "/"
elif [ -n "${ROOT_IS_ZFS}" ]; then
zpool list -Hv ${ROOT_IS_ZFS} | while read NAME MORE; do
if [ "${NAME}" != "${ROOT_IS_ZFS}" ]; then
grow_partition ${NAME}
zpool online -e ${ROOT_IS_ZFS} ${NAME}
fi
done
fi
fi
attempts=0
while [ ${attempts} -lt 3 ]; do
if [ -n "${ROOT_IS_UFS}" ]; then