xref: /freebsd/libexec/rc/rc.d/growfs (revision 8c2dd68caa963f1900a8228b0732b04f5d530ffa)
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