Page MenuHomeFreeBSD

D58582.diff
No OneTemporary

D58582.diff

diff --git a/libexec/rc/rc.conf b/libexec/rc/rc.conf
--- a/libexec/rc/rc.conf
+++ b/libexec/rc/rc.conf
@@ -122,6 +122,9 @@
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).
diff --git a/libexec/rc/rc.d/Makefile b/libexec/rc/rc.d/Makefile
--- a/libexec/rc/rc.d/Makefile
+++ b/libexec/rc/rc.d/Makefile
@@ -24,6 +24,7 @@
fsck \
growfs \
growfs_fstab \
+ growfs_postboot \
hostid \
hostid_save \
hostname \
diff --git a/libexec/rc/rc.d/growfs_postboot b/libexec/rc/rc.d/growfs_postboot
new file mode 100755
--- /dev/null
+++ b/libexec/rc/rc.d/growfs_postboot
@@ -0,0 +1,114 @@
+#!/bin/sh
+#
+# SPDX-License-Identifier: BSD-2-Clause
+# Copyright 2026 Colin Percival
+
+# 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"
+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 "$@"
diff --git a/sbin/devd/Makefile b/sbin/devd/Makefile
--- a/sbin/devd/Makefile
+++ b/sbin/devd/Makefile
@@ -5,6 +5,7 @@
CONFGROUPS= CONFS DEVD
CONFS= devd.conf
DEVD= devmatch.conf
+DEVD+= growfs_postboot.conf
DEVDDIR= /etc/devd
.if ${MK_ACPI} != "no"
DEVD+= asus.conf
diff --git a/sbin/devd/growfs_postboot.conf b/sbin/devd/growfs_postboot.conf
new file mode 100644
--- /dev/null
+++ b/sbin/devd/growfs_postboot.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 &";
+};
diff --git a/share/man/man5/rc.conf.5 b/share/man/man5/rc.conf.5
--- a/share/man/man5/rc.conf.5
+++ b/share/man/man5/rc.conf.5
@@ -5159,6 +5159,7 @@
.Xr pf.conf 5 ,
.Xr firewall 7 ,
.Xr growfs 7 ,
+.Xr growfs_postboot 7 ,
.Xr security 7 ,
.Xr tuning 7 ,
.Xr accton 8 ,
diff --git a/share/man/man7/Makefile b/share/man/man7/Makefile
--- a/share/man/man7/Makefile
+++ b/share/man/man7/Makefile
@@ -16,6 +16,7 @@
firewall.7 \
groups.7 \
growfs.7 \
+ growfs_postboot.7 \
hier.7 \
hostname.7 \
intro.7 \
diff --git a/share/man/man7/growfs.7 b/share/man/man7/growfs.7
--- a/share/man/man7/growfs.7
+++ b/share/man/man7/growfs.7
@@ -124,6 +124,7 @@
.Sh SEE ALSO
.Xr fstab 5 ,
.Xr rc.conf 5 ,
+.Xr growfs_postboot 7 ,
.Xr growfs 8 ,
.Xr zpool 8
.Sh HISTORY
diff --git a/share/man/man7/growfs_postboot.7 b/share/man/man7/growfs_postboot.7
new file mode 100644
--- /dev/null
+++ b/share/man/man7/growfs_postboot.7
@@ -0,0 +1,88 @@
+.\" Copyright 2026 Colin Percival
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.Dd July 31, 2026
+.Dt GROWFS_POSTBOOT 7
+.Os
+.Sh NAME
+.Nm growfs_postboot
+.Nd script to automatically grow file systems after booting
+.Sh DESCRIPTION
+The
+.Nm
+script is run automatically 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 ".Va 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
+The man page and script were written by
+.An Colin Percival Aq Mt cperciva@FreeBSD.org .
+.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.

File Metadata

Mime Type
text/plain
Expires
Tue, Aug 4, 6:38 AM (3 h, 8 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
35936968
Default Alt Text
D58582.diff (8 KB)

Event Timeline