10Sstevel@tonic-gate#!/bin/ksh -p 20Sstevel@tonic-gate# 30Sstevel@tonic-gate# CDDL HEADER START 40Sstevel@tonic-gate# 50Sstevel@tonic-gate# The contents of this file are subject to the terms of the 62334Ssetje# Common Development and Distribution License (the "License"). 72334Ssetje# You may not use this file except in compliance with the License. 80Sstevel@tonic-gate# 90Sstevel@tonic-gate# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 100Sstevel@tonic-gate# or http://www.opensolaris.org/os/licensing. 110Sstevel@tonic-gate# See the License for the specific language governing permissions 120Sstevel@tonic-gate# and limitations under the License. 130Sstevel@tonic-gate# 140Sstevel@tonic-gate# When distributing Covered Code, include this CDDL HEADER in each 150Sstevel@tonic-gate# file and include the License file at usr/src/OPENSOLARIS.LICENSE. 160Sstevel@tonic-gate# If applicable, add the following below this CDDL HEADER, with the 170Sstevel@tonic-gate# fields enclosed by brackets "[]" replaced with your own identifying 180Sstevel@tonic-gate# information: Portions Copyright [yyyy] [name of copyright owner] 190Sstevel@tonic-gate# 200Sstevel@tonic-gate# CDDL HEADER END 210Sstevel@tonic-gate# 220Sstevel@tonic-gate 232334Ssetje# Copyright 2006 Sun Microsystems, Inc. All rights reserved. 240Sstevel@tonic-gate# Use is subject to license terms. 250Sstevel@tonic-gate 262334Ssetje# ident "%Z%%M% %I% %E% SMI" 27174Sjg 280Sstevel@tonic-gateformat=ufs 290Sstevel@tonic-gateALT_ROOT= 300Sstevel@tonic-gateNO_AMD64= 310Sstevel@tonic-gate 320Sstevel@tonic-gateBOOT_ARCHIVE=platform/i86pc/boot_archive 330Sstevel@tonic-gate 342334Ssetjeexport PATH=$PATH:/usr/sbin:/usr/bin:/sbin 350Sstevel@tonic-gate 360Sstevel@tonic-gate# 370Sstevel@tonic-gate# Parse options 380Sstevel@tonic-gate# 390Sstevel@tonic-gatewhile getopts R: OPT 2> /dev/null 400Sstevel@tonic-gatedo 410Sstevel@tonic-gate case $OPT in 420Sstevel@tonic-gate R) ALT_ROOT="$OPTARG" 430Sstevel@tonic-gate if [ "$ALT_ROOT" != "/" ]; then 442334Ssetje echo "Creating ram disk for $ALT_ROOT" 450Sstevel@tonic-gate fi 460Sstevel@tonic-gate ;; 470Sstevel@tonic-gate ?) echo Usage: ${0##*/}: [-R \<root\>] 480Sstevel@tonic-gate exit ;; 490Sstevel@tonic-gate esac 500Sstevel@tonic-gatedone 510Sstevel@tonic-gate 520Sstevel@tonic-gateif [ -x /usr/bin/mkisofs -o -x /tmp/bfubin/mkisofs ] ; then 530Sstevel@tonic-gate format=isofs 540Sstevel@tonic-gatefi 550Sstevel@tonic-gate 56621Svikram# 57621Svikram# mkisofs on s8 doesn't support functionality used by GRUB boot. 58621Svikram# Use ufs format for boot archive instead. 59621Svikram# 60621Svikramrelease=`uname -r` 61621Svikramif [ "$release" = "5.8" ]; then 62621Svikram format=ufs 63621Svikramfi 64621Svikram 650Sstevel@tonic-gateshift `expr $OPTIND - 1` 660Sstevel@tonic-gate 670Sstevel@tonic-gateif [ $# -eq 1 ]; then 682334Ssetje ALT_ROOT="$1" 692334Ssetje echo "Creating ram disk for $ALT_ROOT" 700Sstevel@tonic-gatefi 710Sstevel@tonic-gate 722334Ssetjefunction cleanup 732334Ssetje{ 742334Ssetje umount -f "$rdmnt" 2>/dev/null 752334Ssetje lofiadm -d "$rdfile" 2>/dev/null 762334Ssetje rm -fr "$rddir" 2> /dev/null 770Sstevel@tonic-gate} 780Sstevel@tonic-gate 792334Ssetjefunction getsize 802334Ssetje{ 81*2851Sjongkis # should we exclude amd64 binaries? 82*2851Sjongkis [ $is_amd64 -eq 0 ] && NO_AMD64="-type d -name amd64 -prune -o" 83*2851Sjongkis 842511Sjongkis # Estimate image size and add %10 overhead for ufs stuff. 852511Sjongkis # Note, we can't use du here in case we're on a filesystem, e.g. zfs, 862511Sjongkis # in which the disk usage is less than the sum of the file sizes. 872511Sjongkis # The nawk code 882511Sjongkis # 892511Sjongkis # {t += ($7 % 1024) ? (int($7 / 1024) + 1) * 1024 : $7} 902511Sjongkis # 912511Sjongkis # below rounds up the size of a file/directory, in bytes, to the 922511Sjongkis # next multiple of 1024. This mimics the behavior of ufs especially 932511Sjongkis # with directories. This results in a total size that's slightly 942511Sjongkis # bigger than if du was called on a ufs directory. 95*2851Sjongkis total_size=$(cd "/$ALT_ROOT" 96*2851Sjongkis find $filelist $NO_AMD64 -ls 2>/dev/null | nawk ' 97*2851Sjongkis {t += ($7 % 1024) ? (int($7 / 1024) + 1) * 1024 : $7} 98*2851Sjongkis END {print int(t * 1.10 / 1024)}') 990Sstevel@tonic-gate} 1000Sstevel@tonic-gate 1010Sstevel@tonic-gatefunction create_ufs 1020Sstevel@tonic-gate{ 1030Sstevel@tonic-gate # should we exclude amd64 binaries? 104*2851Sjongkis [ $is_amd64 -eq 0 ] && NO_AMD64="-type d -name amd64 -prune -o" 1050Sstevel@tonic-gate 1062334Ssetje mkfile ${total_size}k "$rdfile" 1072334Ssetje lofidev=`lofiadm -a "$rdfile"` 1082334Ssetje newfs $lofidev < /dev/null 2> /dev/null 1092334Ssetje mkdir "$rdmnt" 1100Sstevel@tonic-gate mount -F mntfs mnttab /etc/mnttab > /dev/null 2>&1 1112334Ssetje mount -o nologging $lofidev "$rdmnt" 1120Sstevel@tonic-gate 1130Sstevel@tonic-gate # do the actual copy 1142334Ssetje cd "/$ALT_ROOT" 1152334Ssetje 116*2851Sjongkis find $filelist $NO_AMD64 -print 2> /dev/null | \ 1172334Ssetje cpio -pdum "$rdmnt" 2> /dev/null 1182334Ssetje umount "$rdmnt" 1192334Ssetje lofiadm -d "$rdfile" 1202334Ssetje rmdir "$rdmnt" 1212334Ssetje 1222334Ssetje # Check if gzip exists in /usr/bin, so we only try to run gzip 1232334Ssetje # on systems that have gzip. Then run gzip out of the patch to 1242334Ssetje # pick it up from bfubin or something like that if needed. 1252334Ssetje # 1262334Ssetje if [ -x /usr/bin/gzip ] ; then 1272334Ssetje gzip -c "$rdfile" > "$ALT_ROOT/$BOOT_ARCHIVE-new" 1282334Ssetje else 1292334Ssetje cat "$rdfile" > "$ALT_ROOT/$BOOT_ARCHIVE-new" 1302334Ssetje fi 1310Sstevel@tonic-gate} 1320Sstevel@tonic-gate 1330Sstevel@tonic-gatefunction create_isofs 1340Sstevel@tonic-gate{ 1350Sstevel@tonic-gate # should we exclude amd64 binaries? 1360Sstevel@tonic-gate [ $is_amd64 = 0 ] && NO_AMD64="-m amd64" 1370Sstevel@tonic-gate 1380Sstevel@tonic-gate # create image directory seed with graft points 1392334Ssetje mkdir "$rdmnt" 1400Sstevel@tonic-gate files= 1412334Ssetje isocmd="mkisofs -quiet -graft-points -dlrDJN -relaxed-filenames $NO_AMD64" 1420Sstevel@tonic-gate for path in $filelist 1430Sstevel@tonic-gate do 1442334Ssetje if [ -d "$ALT_ROOT/$path" ]; then 1452334Ssetje isocmd="$isocmd $path/=\"$ALT_ROOT/$path\"" 1462334Ssetje mkdir -p "$rdmnt/$path" 1472334Ssetje elif [ -f "$ALT_ROOT/$path" ]; then 1480Sstevel@tonic-gate files="$files $path" 1490Sstevel@tonic-gate fi 1500Sstevel@tonic-gate done 1512334Ssetje cd "/$ALT_ROOT" 1522334Ssetje find $files 2> /dev/null | cpio -pdum "$rdmnt" 2> /dev/null 1532334Ssetje isocmd="$isocmd \"$rdmnt\"" 1542334Ssetje rm -f "$errlog" 1552334Ssetje 1562334Ssetje # Check if gzip exists in /usr/bin, so we only try to run gzip 1572334Ssetje # on systems that have gzip. Then run gzip out of the patch to 1582334Ssetje # pick it up from bfubin or something like that if needed. 1592334Ssetje # 1602334Ssetje if [ -x /usr/bin/gzip ] ; then 1612334Ssetje ksh -c "$isocmd" 2> "$errlog" | \ 1622334Ssetje gzip > "$ALT_ROOT/$BOOT_ARCHIVE-new" 1632334Ssetje else 1642334Ssetje ksh -c "$isocmd" 2> "$errlog" > "$ALT_ROOT/$BOOT_ARCHIVE-new" 1652334Ssetje fi 1662334Ssetje 1672334Ssetje if [ -s "$errlog" ]; then 1682334Ssetje grep Error: "$errlog" >/dev/null 2>&1 169174Sjg if [ $? -eq 0 ]; then 1702334Ssetje grep Error: "$errlog" 1712334Ssetje rm -f "$ALT_ROOT/$BOOT_ARCHIVE-new" 172174Sjg fi 173174Sjg fi 1742334Ssetje rm -f "$errlog" 1750Sstevel@tonic-gate} 1760Sstevel@tonic-gate 1770Sstevel@tonic-gate# 1780Sstevel@tonic-gate# get filelist 1790Sstevel@tonic-gate# 180*2851Sjongkisfiles=$(ls "$ALT_ROOT/boot/solaris/filelist.ramdisk" \ 181*2851Sjongkis "$ALT_ROOT/etc/boot/solaris/filelist.ramdisk" 2>/dev/null) 182*2851Sjongkisif [[ -z "$files" ]] 183*2851Sjongkisthen 184*2851Sjongkis print -u2 "Can't find filelist.ramdisk" 185*2851Sjongkis exit 1 1860Sstevel@tonic-gatefi 187*2851Sjongkisfilelist=$(sort -u $files) 1880Sstevel@tonic-gate 1890Sstevel@tonic-gate# 1900Sstevel@tonic-gate# decide if cpu is amd64 capable 1910Sstevel@tonic-gate# 1920Sstevel@tonic-gateprtconf -v /devices | grep CPU_not_amd64 > /dev/null 2>&1 1930Sstevel@tonic-gateis_amd64=$? 1940Sstevel@tonic-gate 1952334Ssetjescratch=tmp 1962334Ssetje 1972334Ssetjeif [ $format = ufs ] ; then 1982334Ssetje # calculate image size 1992334Ssetje getsize 2002334Ssetje 2012334Ssetje # check to see if there is sufficient space in tmpfs 2022334Ssetje # 2032334Ssetje tmp_free=`df -b /tmp | tail -1 | awk '{ printf ($2) }'` 2042334Ssetje (( tmp_free = tmp_free / 2 )) 2052334Ssetje 2062334Ssetje if [ $total_size -gt $tmp_free ] ; then 2072334Ssetje # assumes we have enough scratch space on $ALT_ROOT 2082334Ssetje scratch="$ALT_ROOT" 2092334Ssetje fi 2102334Ssetjefi 2112334Ssetje 2122334Ssetjerddir="/$scratch/create_ramdisk.$$.tmp" 2132334Ssetjerdfile="$rddir/rd.file" 2142334Ssetjerdmnt="$rddir/rd.mount" 2152334Ssetjeerrlog="$rddir/rd.errlog" 2162334Ssetje 2172334Ssetje# make directory for temp files safely 2182334Ssetjerm -rf "$rddir" 2192334Ssetjemkdir "$rddir" 2202334Ssetje 2212334Ssetje# Clean up upon exit. 2222334Ssetjetrap 'cleanup' EXIT 2232334Ssetje 2242334Ssetjeecho "updating $ALT_ROOT/$BOOT_ARCHIVE...this may take a minute" 2250Sstevel@tonic-gate 2260Sstevel@tonic-gateif [ $format = "ufs" ]; then 2270Sstevel@tonic-gate create_ufs 2280Sstevel@tonic-gateelse 2290Sstevel@tonic-gate create_isofs 2300Sstevel@tonic-gatefi 2310Sstevel@tonic-gate 232*2851Sjongkis# Make sure $BOOT_ARCHIVE-new created by either create_ufs or creat_isofs 233*2851Sjongkis# above is flushed to the backing store before we do anything with it. 234*2851Sjongkislockfs -f "/$ALT_ROOT" 235*2851Sjongkis 2362334Ssetje# sanity check the archive before moving it into place 2372334Ssetje# the file type check also establishes that the file exists at all 2382334Ssetje# 2392511SjongkisARCHIVE_SIZE=$(/bin/ls -l "$ALT_ROOT/$BOOT_ARCHIVE-new" | 2402511Sjongkis nawk '{print int($5 / 1024)}') 2412334Ssetjefile "$ALT_ROOT/$BOOT_ARCHIVE-new" | grep gzip > /dev/null 2422334Ssetje 2432334Ssetjeif [ $? = 1 ] && [ -x /usr/bin/gzip ] || [ $ARCHIVE_SIZE -lt 5000 ]; then 2442334Ssetje echo "update of $ALT_ROOT/$BOOT_ARCHIVE failed" 2452334Ssetje rm -rf "$rddir" 246174Sjg exit 1 247174Sjgfi 248174Sjg 2490Sstevel@tonic-gate# 2500Sstevel@tonic-gate# For the diskless case, hardlink archive to /boot to make it 2510Sstevel@tonic-gate# visible via tftp. /boot is lofs mounted under /tftpboot/<hostname>. 2520Sstevel@tonic-gate# NOTE: this script must work on both client and server 2530Sstevel@tonic-gate# 2542334Ssetjegrep "[ ]/[ ]*nfs[ ]" "$ALT_ROOT/etc/vfstab" > /dev/null 2550Sstevel@tonic-gateif [ $? = 0 ]; then 2562334Ssetje mv "$ALT_ROOT/$BOOT_ARCHIVE-new" "$ALT_ROOT/$BOOT_ARCHIVE" 2572334Ssetje rm -f "$ALT_ROOT/boot/boot_archive" 2582334Ssetje ln "$ALT_ROOT/$BOOT_ARCHIVE" "$ALT_ROOT/boot/boot_archive" 2592334Ssetje rm -rf "$rddir" 2600Sstevel@tonic-gate exit 2610Sstevel@tonic-gatefi 2620Sstevel@tonic-gate 2632334Ssetjemv "$ALT_ROOT/$BOOT_ARCHIVE-new" "$ALT_ROOT/$BOOT_ARCHIVE" 2642334Ssetjelockfs -f "/$ALT_ROOT" 265174Sjg 2662334Ssetjerm -rf "$rddir" 267