#!/bin/sh # # $Id: cdroot_initdisk,v 1.6 2002/08/04 20:56:04 bsd Exp $ # # Copyright 2001, 2002 Brian S. Dean # 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 < [ ... ] Where: = disk drive to operate on, e.g., ad0 = 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"