1#!/bin/sh
2#
3# $FreeBSD$
4#
5
6set -ex
7
8export BLOCKSIZE=512
9
10DISKLABEL=$1; shift
11MACHINE=${1:+"-m $1"}; shift
12FSIMG=$1; shift
13RD=$1 ; shift
14MNT=$1 ; shift
15FSSIZE=$1 ; shift
16FSPROTO=$1 ; shift
17FSINODE=$1 ; shift
18FSLABEL=$1 ; shift
19
20#
21# If we've been told to, compute the required file system size
22# and average inode size automatically.
23#
24if [ ${FSSIZE} -eq 0 -a ${FSLABEL} = "auto" ]; then
25	roundup() echo $((($1+$2-1)-($1+$2-1)%$2))
26	nf=$(find ${FSPROTO} |wc -l)
27	sk=$(du -sk ${FSPROTO} |cut -f1)
28	FSINODE=$(roundup $(($sk*1024/$nf)) ${FSINODE})
29	FSSIZE=$(roundup $(($sk*12/10)) 1024)
30fi
31
32dofs_vn () {
33	if [ "x$VNDEVICE" = "x" ] ; then
34		VNDEVICE=vn0
35	fi
36	u=`expr $VNDEVICE : 'vn\([0-9]*\)' || true`
37	VNDEVICE=vnn$u
38
39	rm -f /dev/*vnn*
40	mknod /dev/rvnn${u} c 43 `expr 65538 + $u '*' 8`
41	mknod /dev/rvnn${u}c c 43 `expr 2 + $u '*' 8`
42	mknod /dev/vnn${u} b 15 `expr 65538 + $u '*' 8`
43	mknod /dev/vnn${u}c b 15 `expr 2 + $u '*' 8`
44
45	umount /dev/${VNDEVICE} 2>/dev/null || true
46	umount ${MNT} 2>/dev/null || true
47	vnconfig -u /dev/r${VNDEVICE} 2>/dev/null || true
48
49	vnconfig -s labels -c /dev/r${VNDEVICE} ${FSIMG}
50
51	trap "umount ${MNT}; vnconfig -u /dev/r${VNDEVICE}; rm -f /dev/*vnn*" EXIT
52
53	disklabel -w ${BOOT} ${VNDEVICE} ${FSLABEL}
54	newfs -i ${FSINODE} -o space -m 0 /dev/r${VNDEVICE}c
55
56	mount /dev/${VNDEVICE}c ${MNT}
57}
58
59dofs_md () {
60	if [ "x${MDDEVICE}" != "x" ] ; then
61		umount /dev/${MDDEVICE} 2>/dev/null || true
62		umount ${MNT} 2>/dev/null || true
63		mdconfig -d -u ${MDDEVICE} 2>/dev/null || true
64	fi
65
66	MDDEVICE=`mdconfig -a -t vnode -f ${FSIMG}`
67	if [ ! -c /dev/${MDDEVICE} ] ; then
68		echo "No /dev/$MDDEVICE" 1>&2
69		exit 1
70	fi
71
72	trap "umount ${MNT}; mdconfig -d -u ${MDDEVICE}" EXIT
73
74	if [ "x${DISKLABEL}" != "x" ] ; then
75		${DISKLABEL} ${MACHINE} -w ${BOOT} ${MDDEVICE} ${FSLABEL}
76	fi
77	newfs -O1 -b 4096 -f 512 -i ${FSINODE} -o space -m 0 /dev/${MDDEVICE}
78	mount /dev/${MDDEVICE} ${MNT}
79}
80
81rm -f ${FSIMG}
82dd of=${FSIMG} if=/dev/zero count=${FSSIZE} bs=1k 2>/dev/null
83
84#
85# We don't have any bootblocks on ia64. Note that -B implies -r,
86# so we have to specifically specify -r when we don't have -B.
87# bsdlabel fails otherwise.
88#
89case `uname -r` in
904.*)
91	if [ -f "${RD}/trees/base/boot/boot1" ]; then
92		BOOT="-B -b ${RD}/trees/base/boot/boot1"
93		if [ -f "${RD}/trees/base/boot/boot2" ]; then
94			BOOT="${BOOT} -s ${RD}/trees/base/boot/boot2"
95		fi
96	else
97		BOOT="-r"
98	fi
99	dofs_vn
100	;;
101*)
102	if [ -f "${RD}/trees/base/boot/boot" ]; then
103		BOOT="-B -b ${RD}/trees/base/boot/boot"
104	else
105		BOOT="-r"
106	fi
107	dofs_md
108	;;
109esac
110
111if [ -d ${FSPROTO} ]; then
112	(set -e && cd ${FSPROTO} && find . -print | cpio -dump ${MNT})
113else
114	cp -p ${FSPROTO} ${MNT}
115fi
116
117df -ki ${MNT}
118
119set `df -ki ${MNT} | tail -1`
120
121echo "*** File system is ${FSSIZE} K, $4 left"
122echo "***     ${FSINODE} bytes/inode, $7 left"
123