From nobody Sun Dec 11 13:26:46 2022 X-Original-To: dev-commits-src-all@mlmmj.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mlmmj.nyi.freebsd.org (Postfix) with ESMTP id 4NVQX96df7z4kXWg; Sun, 11 Dec 2022 13:26:49 +0000 (UTC) (envelope-from mike@karels.net) Received: from mail.karels.net (mail.karels.net [216.160.39.52]) by mx1.freebsd.org (Postfix) with ESMTP id 4NVQX86LRgz4HBg; Sun, 11 Dec 2022 13:26:48 +0000 (UTC) (envelope-from mike@karels.net) Authentication-Results: mx1.freebsd.org; none Received: from mail.karels.net (localhost [127.0.0.1]) by mail.karels.net (8.16.1/8.16.1) with ESMTP id 2BBDQlwB076186; Sun, 11 Dec 2022 07:26:47 -0600 (CST) (envelope-from mike@karels.net) Received: from [10.0.2.130] ([10.0.1.1]) by mail.karels.net with ESMTPSA id H0UKBJfalWOYKQEA4+wvSQ (envelope-from ); Sun, 11 Dec 2022 07:26:47 -0600 From: Mike Karels To: Gordon Bergling Cc: Mike Karels , src-committers@freebsd.org, dev-commits-src-all@freebsd.org, dev-commits-src-main@freebsd.org Subject: Re: git: 4a30d7bb373c - main - growfs script: add swap partition as well as growing root Date: Sun, 11 Dec 2022 07:26:46 -0600 X-Mailer: MailMate (1.14r5921) Message-ID: <219B1ADF-9000-4E68-9740-2D1888AAA234@karels.net> In-Reply-To: References: <202212101941.2BAJfDx0085242@gitrepo.freebsd.org> List-Id: Commit messages for all branches of the src repository List-Archive: https://lists.freebsd.org/archives/dev-commits-src-all List-Help: List-Post: List-Subscribe: List-Unsubscribe: Sender: owner-dev-commits-src-all@freebsd.org X-BeenThere: dev-commits-src-all@freebsd.org MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: quoted-printable X-Rspamd-Queue-Id: 4NVQX86LRgz4HBg X-Spamd-Bar: ---- X-Spamd-Result: default: False [-4.00 / 15.00]; REPLY(-4.00)[]; ASN(0.00)[asn:209, ipnet:216.160.36.0/22, country:US] X-Rspamd-Pre-Result: action=no action; module=replies; Message is reply to one we originated X-ThisMailContainsUnwantedMimeParts: N On 11 Dec 2022, at 4:09, Gordon Bergling wrote: > Hi Mike, > > thanks for implementation. After the MFC and the new -STABLE snapshots > I am really looking forward to try this out an my RPi4B. You are welcome, but I hadn=E2=80=99t decided yet whether this should be = MFC=E2=80=99d. That depends in part on how it seems to work out, but I am interested in opinions on that. Mike > --Gordon > > On Sat, Dec 10, 2022 at 07:41:13PM +0000, Mike Karels wrote: >> The branch main has been updated by karels: >> >> URL: https://cgit.FreeBSD.org/src/commit/?id=3D4a30d7bb373c08f42f953b9= cd1e793e236b4cd92 >> >> commit 4a30d7bb373c08f42f953b9cd1e793e236b4cd92 >> Author: Mike Karels >> AuthorDate: 2022-12-10 19:38:36 +0000 >> Commit: Mike Karels >> CommitDate: 2022-12-10 19:38:36 +0000 >> >> growfs script: add swap partition as well as growing root >> >> Add the ability to create a swap partition in the course of growin= g >> the root file system on first boot, enabling by default. The defa= ult >> rules are: add swap if the disk is at least 15 GB (decimal), and t= he >> existing root is less than 40% of the disk. The default size is 1= 0% >> of the disk, but is limited by the memory size. The limit is twic= e >> memory size up to 4 GB, 8 GB up to 8 GB memory, and memory size ov= er >> 8 GB memory. Swap size is clamped at vm.swap_maxpages/2 as well. >> The new swap partition is labeled as "growfs_swap". >> >> The default behavior can be overridden by setting growfs_swap_size= in >> /etc/rc.conf or in the kernel environment, with kenv taking priori= ty. >> A value of 0 inhibits the addition of swap, an empty value specifi= es >> the default, and other values indicate a swap size in bytes. >> >> By default, addition of swap is inhibited if a swap partition is f= ound >> in the output of the sysctl kern.geom.conftxt before the current r= oot >> partition, usually meaning that there is another disk present. >> Swap space is not added if one is already present in /etc/fstab. >> >> The root partition is read-only when growfs runs, so /etc/fstab ca= n >> not be modified. That step is handled by a new growfs_fstab scrip= t, >> added in a separate commit. Set the value "growfs_swap_pdev" in k= env >> to indicate that this should be done, as well as for internal use.= >> >> There is optional verbose output meant for debugging; it can only = be >> enabled by modifying the script (in two places, for sh and awk). >> This should be removed before release, after testing on -current. >> >> Discussed with: cperciva >> Reviewed by: imp (previous version) >> Differential Revision: https://reviews.freebsd.org/D37462 >> --- >> libexec/rc/rc.d/growfs | 178 ++++++++++++++++++++++++++++++++++++++++= +++++++-- >> 1 file changed, 172 insertions(+), 6 deletions(-) >> >> diff --git a/libexec/rc/rc.d/growfs b/libexec/rc/rc.d/growfs >> index 5402bd442279..3c48a7dca6b2 100755 >> --- a/libexec/rc/rc.d/growfs >> +++ b/libexec/rc/rc.d/growfs >> @@ -1,5 +1,6 @@ >> #!/bin/sh >> # >> +# Copyright 2022 Michael J. Karels >> # Copyright 2014 John-Mark Gurney >> # All rights reserved. >> # >> @@ -32,8 +33,9 @@ >> # BEFORE: root >> # KEYWORD: firstboot >> >> -# This allows us to distribute an image >> -# and have it work on essentially any size drive. >> +# Grow root partition to fill available space, optionally adding a sw= ap >> +# partition at the end. This allows us to distribute an image and >> +# have it work on essentially any size drive. >> >> # Note that this uses awk(1), and thus will not work if /usr is on a = separate >> # filesystem. We need to run early, because there might be not enoug= h free >> @@ -48,7 +50,7 @@ start_cmd=3D"growfs_start" >> stop_cmd=3D":" >> rcvar=3D"growfs_enable" >> >> -growfs_get_diskdev () >> +growfs_get_diskdev() >> { >> local _search=3D${1} >> sysctl -b kern.geom.conftxt | >> @@ -61,8 +63,51 @@ growfs_get_diskdev () >> done >> } >> >> -growfs_start () >> +# Compute upper bound on swap partition size (if added), based on phy= smem >> +# and vm.swap_maxpages / 2 (the limit that elicits a warning). >> +# Rule for swap size based on memory size: >> +# up to 4 GB twice memory size >> +# 4 GB - 8 GB 8 GB >> +# over 8 GB memory size >> +growfs_swap_max() >> { >> + memsize=3D$(sysctl -n hw.physmem) >> + memsizeMB=3D$(($memsize / (1024 * 1024))) >> + >> + if [ $memsizeMB -lt 4096 ] >> + then >> + swapmax=3D$(($memsize * 2)) >> + elif [ $memsizeMB -lt 8192 ] >> + then >> + swapmax=3D$((8192 * 1024 * 1024)) >> + else >> + swapmax=3D$memsize >> + fi >> + >> + pagesize=3D$(sysctl -n hw.pagesize) >> + vm_swap_max=3D$(($(sysctl -n vm.swap_maxpages) / 2 * $pagesize)) >> + >> + if [ $swapmax -gt $vm_swap_max ] >> + then >> + $swapmax=3D$vm_swap_max >> + fi >> + echo -n "$swapmax" >> +} >> + >> +# Find newly-added swap partition on parent device ($1). >> +growfs_last_swap() >> +{ >> + swapdev=3D$(gpart list $1 | awk ' >> + $2 =3D=3D "Name:" { dev =3D $3 } >> + $1 =3D=3D "type:" && $2 =3D=3D "freebsd-swap" { swapdev =3D dev } >> + END { print swapdev } >> + ') >> + echo -n $swapdev >> +} >> + >> +growfs_start() >> +{ >> + verbose=3D0 >> echo "Growing root partition to fill device" >> FSTYPE=3D$(mount -p | awk '{ if ( $2 =3D=3D "/") { print $3 }}') >> FSDEV=3D$(mount -p | awk '{ if ( $2 =3D=3D "/") { print $1 }}') >> @@ -100,19 +145,126 @@ growfs_start () >> diskdev=3D${rootdev} >> fi >> >> + # Check kenv for growfs_swap_size; if not present, >> + # check $growfs_swap_size from /etc/rc.conf. >> + # A value of 0 suppresses swap addition, >> + # "" (or unset) specifies the default; >> + # other values indicate the size in bytes. >> + # If default, check whether swap is already in fstab; >> + # if so, don't add another. >> + addswap=3D1 >> + swapsize=3D"$(kenv -q growfs_swap_size 2>/dev/null)" >> + case "$swapsize" in >> + "0") addswap=3D0 >> + ;; >> + "") case "$growfs_swap_size" in >> + "0") addswap=3D0 >> + ;; >> + "") >> + if ! awk ' >> + /^#/ { next } >> + $3 =3D=3D "swap" { exit 1 } >> + ' < /etc/fstab >> + then >> + addswap=3D0 >> + fi >> + ;; >> + *) swapsize=3D"$growfs_swap_size" >> + ;; >> + esac >> + ;; >> + *) ;; >> + esac >> + >> + swaplim=3D$(growfs_swap_max) >> + >> + [ $verbose -eq 1 ] && { >> + echo "diskdev is $diskdev" >> + echo "search is $search" >> + echo "swapsize is $swapsize" >> + echo "swaplim is $swaplim" >> + } >> + >> sysctl -b kern.geom.conftxt | awk ' >> { >> + verbose =3D 0 >> lvl=3D$1 >> device[lvl] =3D $3 >> type[lvl] =3D $2 >> idx[lvl] =3D $7 >> + offset[lvl] =3D $9 >> parttype[lvl] =3D $13 >> + size[lvl] =3D $4 >> + if (verbose) print lvl, type[lvl], $3 >> + if (type[lvl] =3D=3D "DISK") { >> + disksize =3D size[lvl] >> + if (verbose) >> + print "disksize ", disksize >> + # Don't add swap on disks under 15 GB (decimal) by default. >> + if (addswap =3D=3D 1 && (size[lvl] > 15000000000 || swapsize > 0)) >> + doing_swap =3D 1 >> + else >> + doing_swap =3D 0 >> + } else if (type[lvl] =3D=3D "PART" && $11 =3D=3D "freebsd-swap" && \= >> + int(swapsize) =3D=3D 0) { >> + # This finds swap only if it precedes root, e.g. preceding disk. >> + addswap =3D 0 >> + doing_swap =3D 0 >> + print "swap device exists, not adding swap" >> + } >> if (dev =3D=3D $3) { >> for (i =3D 1; i <=3D lvl; i++) { >> # resize >> if (type[i] =3D=3D "PART") { >> pdev =3D device[i - 1] >> - cmd[i] =3D "gpart resize -i " idx[i] " " pdev >> + if (verbose) >> + print i, pdev, addswap, disksize, \ >> + doing_swap >> + swapcmd =3D "" >> + # Allow swap if current root is < 40% of disk. >> + if (parttype[i] !=3D "MBR" && doing_swap =3D=3D 1 && \ >> + (size[i] / disksize < 0.4 || \ >> + swapsize > 0)) { >> + print "Adding swap partition" >> + if (int(swapsize) =3D=3D 0) { >> + swapsize =3D int(disksize / 10) >> + if (swapsize > swaplim) >> + swapsize =3D swaplim >> + } >> + sector =3D $5 >> + swapsize /=3D sector >> + if (verbose) >> + print "swapsize sectors", >> + swapsize >> + align =3D 4 * 1024 * 1024 / sector >> + >> + # Estimate offset for swap; let >> + # gpart compute actual start and size. >> + # Assume expansion all goes into this >> + # partition for MBR case. >> + if (parttype[i - 1] =3D=3D "MBR") { >> + if (verbose) >> + print "sz ", size[i - 1], \ >> + " off ", offset[i - 1] >> + expand =3D size[0] - \ >> + (size[i - 1] + offset[i - 1]) >> + } else { >> + if (verbose) >> + print "sz ", size[i], \ >> + " off ", offset[i] >> + expand =3D size[0] - \ >> + (size[i] + offset[i]) >> + } >> + if (verbose) >> + print "expand ", expand, \ >> + " sz ", size[i] >> + swapbase =3D (expand + size[i]) / sector >> + swapbase -=3D swapsize + align >> + swapcmd =3D "gpart add -t freebsd-swap -a " align " -b " swapbas= e " " pdev "; kenv growfs_swap_pdev=3D" pdev " >/dev/null; " >> + if (verbose) >> + swapcmd =3D "set -x; " swapcmd >> + } >> + cmd[i] =3D swapcmd "gpart resize -i " idx[i] " " pdev >> if (parttype[i] =3D=3D "GPT") >> cmd[i] =3D "gpart recover " pdev " ; " cmd[i] >> } else if (type[i] =3D=3D "LABEL") { >> @@ -128,7 +280,7 @@ growfs_start () >> } >> exit 0 >> } >> -}' dev=3D"$search" >> +}' dev=3D"$search" addswap=3D"$addswap" swapsize=3D"$swapsize" swapli= m=3D"$swaplim" >> gpart commit "$diskdev" 2> /dev/null >> case "$FSTYPE" in >> ufs) >> @@ -138,6 +290,20 @@ growfs_start () >> zpool online -e $pool $rootdev >> ;; >> esac >> + >> + # Get parent device of swap partition if one was added; >> + # if so, find swap device and label it. >> + pdev=3D$(kenv -q growfs_swap_pdev) >> + if [ -n "$pdev" ] >> + then >> + dev=3D$(growfs_last_swap "$pdev") >> + if [ -z "$dev" ] >> + then >> + echo "Swap partition not found on $pdev" >> + exit 0 >> + fi >> + glabel label -v growfs_swap $dev >> + fi >> } >> >> load_rc_config $name >> > > --