1#!/bin/sh 2# 3# Copyright 2014 John-Mark Gurney 4# All rights reserved. 5# 6# Redistribution and use in source and binary forms, with or without 7# modification, are permitted provided that the following conditions 8# are met: 9# 1. Redistributions of source code must retain the above copyright 10# notice, this list of conditions and the following disclaimer. 11# 2. Redistributions in binary form must reproduce the above copyright 12# notice, this list of conditions and the following disclaimer in the 13# documentation and/or other materials provided with the distribution. 14# 15# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 16# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 17# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 18# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 19# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 20# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 21# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 22# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 23# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 24# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 25# SUCH DAMAGE. 26# 27# $FreeBSD$ 28# 29 30# PROVIDE: growfs 31# REQUIRE: fsck 32# BEFORE: root 33# KEYWORD: firstboot 34 35# This allows us to distribute an image 36# and have it work on essentially any size drive. 37 38# Note that this uses awk(1), and thus will not work if /usr is on a separate 39# filesystem. We need to run early, because there might be not enough free 40# space on rootfs for the boot to succeed, and on images we ship - which are 41# the primary purpose of this script - there is no separate /usr anyway. 42 43. /etc/rc.subr 44 45name="growfs" 46desc="Grow root partition to fill device" 47start_cmd="growfs_start" 48stop_cmd=":" 49rcvar="growfs_enable" 50 51growfs_start () 52{ 53 echo "Growing root partition to fill device" 54 FSTYPE=$(mount -p | awk '{ if ( $2 == "/") { print $3 }}') 55 FSDEV=$(mount -p | awk '{ if ( $2 == "/") { print $1 }}') 56 case "$FSTYPE" in 57 ufs) 58 rootdev=${FSDEV#/dev/} 59 ;; 60 zfs) 61 pool=${FSDEV%%/*} 62 rootdev=$(zpool list -v $pool | awk 'END { print $1 }') 63 ;; 64 *) 65 echo "Don't know how to grow root filesystem type: $FSTYPE" 66 return 67 esac 68 if [ x"$rootdev" = x"${rootdev%/*}" ]; then 69 # raw device 70 rawdev="$rootdev" 71 else 72 rawdev=$(glabel status | awk '$1 == "'"$rootdev"'" { print $3 }') 73 if [ x"$rawdev" = x"" ]; then 74 echo "Can't figure out device for: $rootdev" 75 return 76 fi 77 fi 78 79 sysctl -b kern.geom.conftxt | awk ' 80{ 81 lvl=$1 82 device[lvl] = $3 83 type[lvl] = $2 84 idx[lvl] = $7 85 parttype[lvl] = $13 86 if (dev == $3) { 87 for (i = 1; i <= lvl; i++) { 88 # resize 89 if (type[i] == "PART") { 90 pdev = device[i - 1] 91 cmd[i] = "gpart resize -i " idx[i] " " pdev 92 if (parttype[i] == "GPT") 93 cmd[i] = "gpart recover " pdev " ; " cmd[i] 94 } else if (type[i] == "LABEL") { 95 continue 96 } else { 97 print "unhandled type: " type[i] 98 exit 1 99 } 100 } 101 for (i = 1; i <= lvl; i++) { 102 if (cmd[i]) 103 system(cmd[i]) 104 } 105 exit 0 106 } 107}' dev="$rawdev" 108 gpart commit "$rootdev" 109 case "$FSTYPE" in 110 ufs) 111 growfs -y /dev/"$rootdev" 112 ;; 113 zfs) 114 zpool online -e $pool $rootdev 115 ;; 116 esac 117} 118 119load_rc_config $name 120run_rc_command "$1" 121