#!/bin/sh -x
#
# Builds minimal FreeBSD on gjournal on GPT (via gpart) on gmirror
#
# Jeff Kletsky -- 2009
#
# Thanks to:
#
# http://m8d.de/news/freebsd-on-gpt.php
# http://www.freebsd.org/doc/en/books/handbook/geom-mirror.html
# http://www.freebsd.org/doc/en/books/handbook/geom-gjournal.html
# http://www.freebsd.org/doc/en_US.ISO8859-1/articles/gjournal-desktop/
# http://lists.freebsd.org/pipermail/freebsd-stable/2008-May/042415.html
# http://lists.freebsd.org/pipermail/freebsd-hackers/2007-January/019276.html
#
#
# once mirror is up and running with the second drive, remember to
#
# # gmirror configure -F <mirror_name>
#
# c.f.,
# http://lists.freebsd.org/pipermail/freebsd-hackers/2007-January/019276.html
#
#
# Decision was to mirror entire drive to make it easier when
# adding additional partitions. Some suggestions were read
# that this configuration also makes it if/when one of the
# underlying drives need to be replaced.
#
# Downside is that swap space is mirrored, possibly slowing performance
# As these machines have 2GB and aren't generally doing anything memory
# intensive, it is unlikely that swap will be heavily used
#
#
# Configured for buiding my "jailserver" box, others may be ok as well
#
DEVICE=${DEVICE:-'ad0'}
MIRROR=${MIRROR:-'gm0'}
VERSION=${releaseName:-'7.2-RELEASE'}
#
# Begin from Fixit prompt off DVD
# Expects distribution to be mounted at /dist (default)
#
#
# To do it...
#
# Fixit# mkdir /usbstick
# Fixit# mount_msdosfs /dev/da0s1 /usbstick
# Fixit# sh -x /usbstick/install_script.sh
#
# 'mount -t msdosfs' will not work, apparently due to paths under Fixit
#
# redirection or script command can be used to capture output
#
export DESTDIR='/install_mnt'
#
# Because gpart is rather rough from a user standpoint:
#
M=$((2*1024))
G=$((2*1024*1024))
# Function to return the first free starting sector in the last free space
# (handles free space in among partitions in a "safe" way)
next_free ( ) {
gpart show $1 | fgrep -e '- free -' | tail -n 1 | awk '{ print $1; }'
}
# 'gpart destroy' will not remove a populated GPT table
# Note also that 'gpart -f <args>' is *not* force
remove_partitions ( ) {
for index in `gpart show $1 | fgrep -v '=>' | fgrep -ve '- free -' | \
awk '{ if ( $3 ~ /[0-9]+/ ) print $3 ; }' | sort -n | uniq | \
awk '{ PARTS=PARTS" "$1 ; } END { print PARTS ; }'`
do gpart delete -i $index $1
done
}
# Enable "shoot yourself in the foot mode" for geom
# Probably only needed if you need to get rid of existing labels
# or have mounted one of the partitions this boot
sysctl kern.geom.debugflags=16
# Load the needed kernel modules
kldload /dist/boot/kernel/geom_mirror.ko
kldload /dist/boot/kernel/geom_journal.ko
# Make sure things are unlabeled and "fresh"
gmirror remove ${MIRROR} ${DEVICE}
gmirror clear ${DEVICE}
gmirror forget ${MIRROR} ${DEVICE}
gmirror clear ${MIRROR}
remove_partitions ${DEVICE}
gpart destroy ${DEVICE}
# Just to be safe, though doesn't handle end-of-disk GPT sectors
dd if=/dev/zero of=/dev/${DEVICE} bs=512 count=1k
#
# Start creating the new providers and filesystems
#
# Create the mirror at the device level
gmirror label -vb round-robin ${MIRROR} ${DEVICE}
# Create a new partition table
gpart create -s GPT mirror/${MIRROR}
# Now install the bootcode 1st stage
gpart bootcode -b /dist/boot/pmbr mirror/${MIRROR}
# Boot and root partitions I have read must be first two
# Worth checking on later, but let's get this working
# boot - 1
gpart add -b `next_free mirror/${MIRROR}` -s 128 -t freebsd-boot \
mirror/${MIRROR}
# with the 2nd-stage boot code
gpart bootcode -p /dist/boot/gptboot -i 1 mirror/${MIRROR}
# root - 2
gpart add -b `next_free mirror/${MIRROR}` -s $((1*$G)) -t freebsd-ufs \
mirror/${MIRROR}
# Swap next, so root can expand later if it needs to
# swap - 3
gpart add -b `next_free mirror/${MIRROR}` -s $((4*$G)) -t freebsd-swap \
mirror/${MIRROR}
# Now the rest of the partitions
# var - 4
gpart add -b `next_free mirror/${MIRROR}` -s $((11*$G)) -t freebsd-ufs \
mirror/${MIRROR}
# tmp - 5
gpart add -b `next_free mirror/${MIRROR}` -s $((11*$G)) -t freebsd-ufs \
mirror/${MIRROR}
#usr - 6
gpart add -b `next_free mirror/${MIRROR}` -s $((11*$G)) -t freebsd-ufs \
mirror/${MIRROR}
#var/tmp - 7
gpart add -b `next_free mirror/${MIRROR}` -s $((21*$G)) -t freebsd-ufs \
mirror/${MIRROR}
gpart show mirror/${MIRROR}
# Set up journals
# '-f' needed here in case previously used disk
gjournal label -f mirror/${MIRROR}p4
gjournal label -f mirror/${MIRROR}p5
gjournal label -f mirror/${MIRROR}p6
gjournal label -f mirror/${MIRROR}p7
gjournal show
# newfs and labels
newfs -L root mirror/${MIRROR}p2
glabel create swap mirror/${MIRROR}p3
newfs -JL var mirror/${MIRROR}p4.journal
newfs -JL tmp mirror/${MIRROR}p5.journal
newfs -JL usr mirror/${MIRROR}p6.journal
newfs -JL vartmp mirror/${MIRROR}p7.journal
glabel show
# mount the new filesystem
mkdir ${DESTDIR}
mount /dev/mirror/${MIRROR}p2 ${DESTDIR}
# Could use '-o async' for these
cd ${DESTDIR}
mkdir var tmp usr
mount /dev/mirror/${MIRROR}p4.journal var
mount /dev/mirror/${MIRROR}p5.journal tmp
mount /dev/mirror/${MIRROR}p6.journal usr
mkdir var/tmp
mount /dev/mirror/${MIRROR}p7.journal var/tmp
df -h
# Prep and install a minimal system
# base
cd /dist/${VERSION}/base
./install.sh
# GENERIC
cd ../kernels
./install.sh GENERIC
cd ${DESTDIR}/boot
# also needs to be in /boot/kernel
cp -rp GENERIC/ kernel
diff -r GENERIC kernel
df -h
# Ready system for reboot
# loader.conf
cat >> ${DESTDIR}/boot/loader.conf <<EOF
geom_mirror_load="YES"
geom_journal_load="YES"
EOF
# fstab
cat > ${DESTDIR}/etc/fstab.dev <<EOF
# Device Mountpoint FStype Options Dump Pass#
/dev/mirror/${MIRROR}p3 none swap sw 0 0
/dev/mirror/${MIRROR}p2 / ufs rw 1 1
/dev/mirror/${MIRROR}p5.journal /tmp ufs rw,async 2 2
/dev/mirror/${MIRROR}p6.journal /usr ufs rw,async 2 2
/dev/mirror/${MIRROR}p4.journal /var ufs rw,async 2 2
/dev/mirror/${MIRROR}p7.journal /var/tmp ufs rw,async 2 2
/dev/acd0 /cdrom cd9660 ro,noauto 0 0
EOF
cat > ${DESTDIR}/etc/fstab.label <<EOF
# Device Mountpoint FStype Options Dump Pass#
/dev/label/swap none swap sw 0 0
/dev/label/root / ufs rw 1 1
/dev/label/tmp /tmp ufs rw,async 2 2
/dev/label/usr /usr ufs rw,async 2 2
/dev/label/var /var ufs rw,async 2 2
/dev/label/vartmp /var/tmp ufs rw,async 2 2
/dev/acd0 /cdrom cd9660 ro,noauto 0 0
EOF
# Could probably do this with a symlink,
# but this preserves the original in the case of an edit
cp ${DESTDIR}/etc/fstab.dev ${DESTDIR}/etc/fstab
#
# This would be a good place to chroot and do things like
# setting the root password
#
# c.f., http://m8d.de/news/freebsd-on-gpt.php
#
# THIS SOFTWARE IS PROVIDED BY ``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 THE FREEBSD PROJECT OR CONTRIBUTORS 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.