mirror of
https://github.com/freebsd/freebsd-src.git
synced 2026-10-28 11:25:21 +01:00
rc+devd: Add growfs_postboot
In VM and cloud environments it is often possible to enlarge virtual disks; this can be useful, for example, if a system is launched with a small root disk and it later becomes clear that more space is needed. On kernels which support run-time resizing of disks (for NVMe, this was added in November 2025; some other disk types have supported this for longer) a SIZECHANGE notification is sent to userland via devd. Add a "nostart" rc.d script (runnable manually but not automatically at boot time) and a devd script which invokes it when a notification arrives. The rc.d script enlarges the "final partition" on partitioned geoms, or the UFS filesystem or zpool device when triggered on a disk containing either of those. Reviewed by: imp, ziaee MFC after: 2 weeks Relnotes: Disk partitions and filesystems can be enlarged automatically when disks grow by setting growfs_postboot_enable=YES in /etc/rc.conf. Sponsored by: Amazon Differential Revision: https://reviews.freebsd.org/D58582
This commit is contained in:
1 parent
aefd61a1de
commit
5a31987d4c
9 files changed
+201
No files matched your search
@@ -122,6 +122,9 @@ background_fsck_delay="60" # Time to wait (seconds) before starting the fsck.
|
||||
growfs_enable="NO" # Set to YES to attempt to grow the root filesystem on boot
|
||||
growfs_swap_size="" # Set to 0 to disable growfs swap, "" to default size,
|
||||
# size in bytes to specify swap size.
|
||||
growfs_postboot_enable="NO" # Set to YES to attempt to grow partitions and
|
||||
# filesystems when devd notifies about disks growing
|
||||
# after the system boots.
|
||||
netfs_types="nfs:NFS smbfs:SMB" # Net filesystems.
|
||||
extra_netfs_types="NO" # List of network extra filesystem types for delayed
|
||||
# mount at startup (or NO).
|
||||
|
||||
@@ -24,6 +24,7 @@ CONFS= DAEMON \
|
||||
fsck \
|
||||
growfs \
|
||||
growfs_fstab \
|
||||
growfs_postboot \
|
||||
hostid \
|
||||
hostid_save \
|
||||
hostname \
|
||||
|
||||
Executable
+116
@@ -0,0 +1,116 @@
|
||||
#!/bin/sh
|
||||
#
|
||||
# Copyright 2026 Colin Percival
|
||||
#
|
||||
# SPDX-License-Identifier: BSD-2-Clause
|
||||
#
|
||||
# PROVIDE: growfs_postboot
|
||||
# KEYWORD: nostart
|
||||
|
||||
# Triggered by /etc/devd/growfs_postboot.conf: When a disk grows, enlarge the
|
||||
# final partition to fill the available space (if the disk is partitioned) or
|
||||
# enlarge the UFS filesystem or ZFS zpool (if in use for one of those). Note
|
||||
# that in the common case of "a disk is partitioned and one of the partitions
|
||||
# contains a filesystem" this script is invoked twice -- the repartitioning
|
||||
# done on the first call generates a new devd event which triggers the second
|
||||
# invocation.
|
||||
#
|
||||
# Enable by setting
|
||||
# growfs_postboot_enable=YES
|
||||
# in /etc/rc.conf. Note that on systems with growfs_enable=YES, it will often
|
||||
# be necessary to set growfs_swap_size=0 in order to disable swap creation;
|
||||
# otherwise the "final partition" is the swap space, not the filesystem and
|
||||
# growing the disk will not cause the most likely desired results.
|
||||
|
||||
. /etc/rc.subr
|
||||
|
||||
name="growfs_postboot"
|
||||
desc="automatically grow file systems during runtime"
|
||||
rcvar="growfs_postboot_enable"
|
||||
start_cmd="growfs_postboot_start"
|
||||
|
||||
disktype() {
|
||||
sysctl -n kern.geom.conftxt | awk -v dev="$1" '
|
||||
BEGIN {
|
||||
partitioned=0
|
||||
indev=0
|
||||
}
|
||||
{
|
||||
if (dev == $3) {
|
||||
indev=1
|
||||
devlevel=$1
|
||||
} else if (devlevel >= $1) {
|
||||
indev=0
|
||||
} else if (indev == 1) {
|
||||
if ($2 == "PART") {
|
||||
partitioned=1
|
||||
}
|
||||
}
|
||||
}
|
||||
END {
|
||||
if (partitioned == 1) {
|
||||
print "partitioned"
|
||||
} else {
|
||||
print "unpartitioned"
|
||||
}
|
||||
}'
|
||||
}
|
||||
|
||||
growpart() {
|
||||
# Run 'gpart recover' if GPT
|
||||
if gpart list "$1" | grep -qi 'scheme: GPT'; then
|
||||
gpart recover "$1" || true
|
||||
fi
|
||||
|
||||
# Find the index of the last partition; note that we need to compare
|
||||
# the starting sectors in case partitions are not numbered sensibly.
|
||||
idx=$(gpart backup "$1" | awk '
|
||||
NR == 1 { next }
|
||||
$3 + 0 > start { start = $3 + 0; idx = $1 }
|
||||
END { print idx }')
|
||||
if [ -z "$idx" ]; then
|
||||
echo "Error finding final partition of $1"
|
||||
return 1
|
||||
fi
|
||||
|
||||
# Expand that partition
|
||||
gpart resize -i "$idx" "$1"
|
||||
}
|
||||
|
||||
growfilesystem() {
|
||||
case $(fstyp -u "/dev/$1" 2>/dev/null) in
|
||||
ufs) growfs -y "/dev/$1"
|
||||
;;
|
||||
zfs) zpool list -H -o name |
|
||||
while read -r pool; do
|
||||
zpool list -vH -o name "$pool" |
|
||||
grep "^[[:space:]]" |
|
||||
while read -r dev; do
|
||||
if [ "$dev" = "$1" ]; then
|
||||
zpool online -e "$pool" "$1"
|
||||
fi
|
||||
done
|
||||
done
|
||||
;;
|
||||
"") # Nothing to grow here
|
||||
;;
|
||||
*) echo "Don't know how to grow filesystem on /dev/$1"
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
growfs_postboot_start() {
|
||||
# Run either growpart or growfilesystem depending on whether this is
|
||||
# something which is partitioned or not.
|
||||
case $(disktype "$1") in
|
||||
partitioned)
|
||||
growpart "$1"
|
||||
;;
|
||||
unpartitioned)
|
||||
growfilesystem "$1"
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
load_rc_config $name
|
||||
run_rc_command "$@"
|
||||
@@ -5,6 +5,7 @@ PACKAGE=devd
|
||||
CONFGROUPS= CONFS DEVD
|
||||
CONFS= devd.conf
|
||||
DEVD= devmatch.conf
|
||||
DEVD+= growfs_postboot.conf
|
||||
DEVDDIR= /etc/devd
|
||||
.if ${MK_ACPI} != "no"
|
||||
DEVD+= asus.conf
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
# Trigger growfs on GEOM size changes.
|
||||
|
||||
notify 200 {
|
||||
match "system" "GEOM";
|
||||
match "subsystem" "DEV";
|
||||
match "type" "SIZECHANGE";
|
||||
action "lockf -k /var/run/growfs_postboot.lock /etc/rc.d/growfs_postboot quietstart $cdev 2>&1 | logger -t growfs_postboot &";
|
||||
};
|
||||
@@ -5159,6 +5159,7 @@ to
|
||||
.Xr pf.conf 5 ,
|
||||
.Xr firewall 7 ,
|
||||
.Xr growfs 7 ,
|
||||
.Xr growfs_postboot 7 ,
|
||||
.Xr security 7 ,
|
||||
.Xr tuning 7 ,
|
||||
.Xr accton 8 ,
|
||||
|
||||
@@ -16,6 +16,7 @@ MAN= arch.7 \
|
||||
firewall.7 \
|
||||
groups.7 \
|
||||
growfs.7 \
|
||||
growfs_postboot.7 \
|
||||
hier.7 \
|
||||
hostname.7 \
|
||||
intro.7 \
|
||||
|
||||
@@ -124,6 +124,7 @@ must be available prior to running the script.
|
||||
.Sh SEE ALSO
|
||||
.Xr fstab 5 ,
|
||||
.Xr rc.conf 5 ,
|
||||
.Xr growfs_postboot 7 ,
|
||||
.Xr growfs 8 ,
|
||||
.Xr zpool 8
|
||||
.Sh HISTORY
|
||||
|
||||
@@ -0,0 +1,69 @@
|
||||
.\"
|
||||
.\" Copyright 2026 Colin Percival
|
||||
.\"
|
||||
.\" SPDX-License-Identifier: BSD-2-Clause
|
||||
.\"
|
||||
.Dd July 31, 2026
|
||||
.Dt GROWFS_POSTBOOT 7
|
||||
.Os
|
||||
.Sh NAME
|
||||
.Nm growfs_postboot
|
||||
.Nd automatically grow file systems during runtime
|
||||
.Sh DESCRIPTION
|
||||
The
|
||||
.Nm
|
||||
script expands filesystems automatically.
|
||||
Typically it is run via
|
||||
.Xr devd 8
|
||||
in response to a SIZECHANGE notification.
|
||||
It will enlarge the final partition of a partitioned disk; expand a UFS
|
||||
file system; or expand a zpool device, as appropriate.
|
||||
.Pp
|
||||
The following option in
|
||||
.Pa /etc/rc.conf
|
||||
controls the behavior of
|
||||
.Nm :
|
||||
.Bl -tag -width "growfs_postboot_enable" -offset indent
|
||||
.It Va growfs_postboot_enable
|
||||
.Pq Dq Li NO
|
||||
If set to
|
||||
.Dq Li YES ,
|
||||
the script will enlarge partitions and file systems when disks expand.
|
||||
.El
|
||||
.Pp
|
||||
Note that the
|
||||
.Xr growfs 7
|
||||
startup script will normally place a swap partition at the end of the disk
|
||||
containing the root file system, which will prevent the file system growing
|
||||
further; as such, in most cases it will be advisable to set
|
||||
.Va growfs_swap_size
|
||||
to
|
||||
.Dq Li 0
|
||||
in virtual machine images if
|
||||
.Nm
|
||||
is being enabled.
|
||||
If the system has already booted without that setting, a swap partition may
|
||||
have already been created, in which case it must be removed before this script
|
||||
can grow the root file system.
|
||||
.Sh FILES
|
||||
.Bl -tag -compact -width Pa
|
||||
.It Pa /etc/rc.conf
|
||||
.El
|
||||
.Sh EXIT STATUS
|
||||
.Ex -std
|
||||
.Sh SEE ALSO
|
||||
.Xr rc.conf 5 ,
|
||||
.Xr growfs 7 ,
|
||||
.Xr devd 8 ,
|
||||
.Xr growfs 8 ,
|
||||
.Xr zpool 8
|
||||
.Sh HISTORY
|
||||
The
|
||||
.Nm
|
||||
script first appeared in
|
||||
.Fx 16.0 .
|
||||
.Sh AUTHORS
|
||||
.An Colin Percival Aq Mt [email protected]
|
||||
.Sh CAVEATS
|
||||
I/O may be paused while file systems grow, so this functionality should be used
|
||||
with care on systems with strict latency requirements.
|
||||
Reference in new issue
Block a user