From ea3facd2db82275eac36a6d8c4f3e667c54347b1 Mon Sep 17 00:00:00 2001 From: Franco Fichtner Date: Wed, 16 Feb 2022 15:15:54 +0100 Subject: [PATCH] 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. --- src/etc/rc | 76 ++++++++++++++++++++++++++++++++++++++++++------------ 1 file changed, 59 insertions(+), 17 deletions(-) diff --git a/src/etc/rc b/src/etc/rc index 50cfe6c1d..0ee395f52 100755 --- a/src/etc/rc +++ b/src/etc/rc @@ -1,6 +1,6 @@ #!/bin/sh -# Copyright (c) 2014-2019 Franco Fichtner +# Copyright (c) 2014-2022 Franco Fichtner # Copyright (c) 2004-2010 Scott Ullrich # Copyright (c) 2003-2004 Manuel Kasper # 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