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_get_diskdev () 52{ 53 local _search=${1} 54 sysctl -b kern.geom.conftxt | 55 while read x1 _type _dev line 56 do 57 if [ "${_type}" = "DISK" -a -n "$(echo ${_search} | grep ${_dev})" ]; then 58 echo -n ${_dev} 59 break 60 fi 61 done 62} 63 64growfs_start () 65{ 66 echo "Growing root partition to fill device" 67 FSTYPE=$(mount -p | awk '{ if ( $2 == "/") { print $3 }}') 68 FSDEV=$(mount -p | awk '{ if ( $2 == "/") { print $1 }}') 69 case "$FSTYPE" in 70 ufs) 71 rootdev=${FSDEV#/dev/} 72 ;; 73 zfs) 74 pool=${FSDEV%%/*} 75 rootdev=$(zpool list -v $pool | awk 'END { print $1 }') 76 ;; 77 *) 78 echo "Don't know how to grow root filesystem type: $FSTYPE" 79 return 80 esac 81 if [ x"$rootdev" = x"${rootdev%/*}" ]; then 82 # raw device 83 rawdev="$rootdev" 84 else 85 rawdev=$(glabel status | awk -v rootdev=$rootdev 'index(rootdev, $1) { print $3; }') 86 if [ x"$rawdev" = x"" ]; then 87 echo "Can't figure out device for: $rootdev" 88 return 89 fi 90 fi 91 92 if [ x"diskid" = x"${rootdev%/*}" ]; then 93 search=$rootdev 94 else 95 search=$rawdev 96 fi 97 98 diskdev=$(growfs_get_diskdev ${search}) 99 if [ -z "${diskdev}" ]; then 100 diskdev=${rootdev} 101 fi 102 103 sysctl -b kern.geom.conftxt | awk ' 104{ 105 lvl=$1 106 device[lvl] = $3 107 type[lvl] = $2 108 idx[lvl] = $7 109 parttype[lvl] = $13 110 if (dev == $3) { 111 for (i = 1; i <= lvl; i++) { 112 # resize 113 if (type[i] == "PART") { 114 pdev = device[i - 1] 115 cmd[i] = "gpart resize -i " idx[i] " " pdev 116 if (parttype[i] == "GPT") 117 cmd[i] = "gpart recover " pdev " ; " cmd[i] 118 } else if (type[i] == "LABEL") { 119 continue 120 } else { 121 print "unhandled type: " type[i] 122 exit 1 123 } 124 } 125 for (i = 1; i <= lvl; i++) { 126 if (cmd[i]) 127 system(cmd[i]) 128 } 129 exit 0 130 } 131}' dev="$search" 132 gpart commit "$diskdev" 2> /dev/null 133 case "$FSTYPE" in 134 ufs) 135 growfs -y /dev/"$rootdev" 136 ;; 137 zfs) 138 zpool online -e $pool $rootdev 139 ;; 140 esac 141} 142 143load_rc_config $name 144run_rc_command "$1" 145