#!/bin/sh
#
# $Id: cdroot_initdisk,v 1.6 2002/08/04 20:56:04 bsd Exp $
#
# Copyright 2001, 2002 Brian S. Dean <bsd@bsdhome.com>
# All Rights Reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
#
# 1. Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# 2. Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
#
# THIS SOFTWARE IS PROVIDED BY BRIAN S. DEAN ``AS IS'' AND ANY
# EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BRIAN S. DEAN BE LIABLE
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
# OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
# BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
# LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
# USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
# DAMAGE.
#
# Author : Brian Dean
# Date : 14 April, 2001
#
# Initialize the specified disk for use as local disk space for a mostly
# diskless client system.
#
#
# $1 = disk, i.e., ad0
#
# $2 .. $N = partitions name:slice:size (in MB), i.e., var:e:128
# if size=0, then use all remaining space (must be last entry)
#
#
# Example:
#
# root_initdisk ad0 root:a:128 swap:b:1024 var:e:1024 usr:f:0
#
# If there is a global system configuration file, suck it in.
#
if [ -r /etc/defaults/rc.conf ]; then
. /etc/defaults/rc.conf
source_rc_confs
elif [ -r /etc/rc.conf ]; then
. /etc/rc.conf
fi
usage() {
cat <<EOF
Usage: $0 [options] <DISK> <SLICE1> [<SLICE2> ... <SLICEN>]
Where:
<DISK> = disk drive to operate on, e.g., ad0
<SLICEx> = slice specification of the form:
mp:slice:size
mp = mount point, root=/, swap=swap, var=/var, etc
slice = slice letter, e.g., "a", "b", etc.
size = size in MB, 0 = use all remaining space
One option is accepted:
-F = force disk initialization even if there is an existing
label
DANGER: This program is intended to be run by the '/etc/inst' script
that is installed by 'mkcdroot' onto a live CD-Rom bootable
FreeBSD CD for the purposes of installing FreeBSD. It DOES
NOT ask for confirmation before wiping out the specified
disk.
Use this program with EXTREME CAUTION.
Example:
$0 -F ad0 root:a:128 swap:b:1024 var:e:1024 usr:f:0
EOF
}
args=`getopt F $*`
if [ "$?" -ne 0 ]; then
usage
exit 1
fi
set -- $args
for i; do
case "$i" in
-F)
cdroot_force_diskinit=YES
shift
;;
--)
shift;
break;
;;
esac
done
#while [[ "$1" = +(-*) ]]; do
# case $1 in
# -force)
# cdroot_force_diskinit=YES;
# shift
# ;;
# *)
# echo "$0: unknown option $1"
# usage
# exit 1
# ;;
# esac
#done
if [ "$#" -lt 2 ]; then
echo
echo "$0: must specify a disk and at least one slice specification."
usage
exit 1
fi
DISK=$1
shift
#
# make sure the needed device nodes are in /dev
#
if [ ! -c /dev/${DISK} ]; then
(cd /dev && sh MAKEDEV ${DISK})
fi
if [ ! -c /dev/${DISK}s1 ]; then
(cd /dev && sh MAKEDEV ${DISK}s1)
fi
if [ ! -c /dev/${DISK}s1a ]; then
(cd /dev && sh MAKEDEV ${DISK}s1a)
fi
if [ ! -c /dev/$DISK ]; then
echo
echo "$0: /dev/$DISK does not exist or is not a disk device"
echo
exit 1
fi
n=$#
i=0
while [ "$i" -ne "$n" ]; do
sln=`echo $1 | cut -f1 -d:`
sla=`echo $1 | cut -f2 -d:`
slz=`echo $1 | cut -f3 -d:`
eval slname_${i}="$sln"
eval slsize_${i}="$slz"
eval slslic_${i}="$sla"
shift;
i=`expr $i + 1`
done
N_SLICES=$n
i=0
while [ $i -ne $N_SLICES ]; do
eval echo "\${slname_${i}} \${slsize_${i}} MB on /dev/${DISK}s1\${slslic_${i}}"
i=`expr $i + 1`
done
if [ -z "$DISK" ]; then
echo "Usage: $0 Disk"
exit 1
fi
if [ "$cdroot_force_diskinit" != "YES" ]; then
/sbin/disklabel -r ${DISK}s1 > /dev/null 2>&1
if [ "$?" -eq 0 ]; then
echo "Disk already has a label"
exit 0
fi
fi
echo "Preparing to operate on /dev/$DISK"
case "$DISK" in
ar*)
echo "Disk is IDE raid, not zeroing"
;;
*)
echo "Zero front of disk"
/bin/dd if=/dev/zero of=/dev/$DISK count=128
;;
esac
echo "Install partition"
/sbin/fdisk -I $DISK
echo "Initialize label"
/sbin/disklabel -rw ${DISK}s1 auto
echo "Install boot0 boot manager"
/usr/sbin/boot0cfg -B ${DISK}
echo "Compute slice sizes"
DISK_S=`/sbin/disklabel -r ${DISK}s1 | /usr/bin/tr -s ' ' | \
/usr/bin/sed 's/^ //g' | /usr/bin/grep '^c: ' | \
/usr/bin/cut -f2 -d' '`
echo "Disk size = $DISK_S blocks"
NEXT_OFFSET=0
REMAINING=$DISK_S
i=0
while [ "$i" -lt $N_SLICES ]; do
eval s="\${slsize_${i}}"
if [ "$s" -eq 0 ]; then
eval slblks_${i}=$REMAINING
else
eval slblks_${i}=`expr ${s} \* 1024 \* 2`
fi
eval echo "next size = \${slblks_${i}}, remaining is $REMAINING"
eval b="\${slblks_${i}}"
if [ "${b}" -gt "$REMAINING" ]; then
echo
echo "$0: ERROR: disk size exceeded, must abort"
echo
exit 1
fi
REMAINING=`expr $REMAINING - ${b}`
eval sloffs_${i}=$NEXT_OFFSET
NEXT_OFFSET=`expr $NEXT_OFFSET + ${b}`
eval echo "$i: \${slslic_${i}}: \${slblks_${i}} \${sloffs_${i}} \${slname_${i}}"
i=`expr $i + 1`
done
echo "Generate prototype label"
PROTO=/tmp/label.proto
/sbin/disklabel -r ${DISK}s1 > $PROTO
i=0
while [ "$i" -lt $N_SLICES ]; do
eval n="\${slname_${i}}"
if [ "${n}" = "swap" ]; then
fstype="swap"
else
fstype="4.2BSD 0 0 0"
fi
eval echo "\${slslic_${i}}: \${slblks_${i}} \${sloffs_${i}} $fstype" >> $PROTO
i=`expr $i + 1`
done
echo "Install new label"
/sbin/disklabel -R -B ${DISK}s1 $PROTO
echo "Initialize disk filesystems"
i=0
while [ "$i" -lt $N_SLICES ]; do
eval n="\${slname_${i}}"
if [ "${n}" != "swap" ]; then
eval /sbin/newfs /dev/${DISK}s1\${slslic_${i}}
if [ "${n}" != "root" ]; then
eval /sbin/tunefs -n enable /dev/${DISK}s1\${slslic_${i}}
fi
fi
i=`expr $i + 1`
done
echo "Done initializing disk"
syntax highlighted by Code2HTML, v. 0.9.1