Home | History | Annotate | Line # | Download | only in embedded
mkimage revision 1.8
      1 #! /bin/sh
      2 
      3 # $NetBSD: mkimage,v 1.8 2013/01/14 12:12:19 jmcneill Exp $
      4 
      5 # Copyright (c) 2012 Alistair Crooks <agc (at] NetBSD.org>
      6 # All rights reserved.
      7 #
      8 # Redistribution and use in source and binary forms, with or without
      9 # modification, are permitted provided that the following conditions
     10 # are met:
     11 # 1. Redistributions of source code must retain the above copyright
     12 #    notice, this list of conditions and the following disclaimer.
     13 # 2. Redistributions in binary form must reproduce the above copyright
     14 #    notice, this list of conditions and the following disclaimer in the
     15 #    documentation and/or other materials provided with the distribution.
     16 #
     17 # THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
     18 # IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
     19 # OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
     20 # IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
     21 # INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
     22 # NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
     23 # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
     24 # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     25 # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
     26 # THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     27 #
     28 
     29 # find next available vnd, from kre
     30 next_avail ()
     31 {
     32 	local dev="$1"
     33 	local N=$(( ${#dev} + 1 ))
     34 	local unit units
     35 
     36 	units=$(
     37 		sysctl -n hw.disknames		|
     38 			tr ' ' '\012'		|
     39 			grep '^'"${dev}"'[0-9]'	|
     40 			sort -n -k 1.$N			)
     41 
     42 	test -z "${units}" && {
     43 		test -e "/dev/${dev}0a" || {
     44 			echo >&2 "No ${dev}s available!"
     45 			return 1
     46 		}
     47 		echo "${dev}0"
     48 		return
     49 	}
     50 
     51 	N=0
     52 	for unit in ${units}
     53 	do
     54 		if [ "${unit}" = "${dev}${N}" ]
     55 		then
     56 			N=$(( N + 1 ))
     57 		else
     58 			echo "${dev}${N}"
     59 			return
     60 		fi
     61 	done
     62 
     63 	test -e /dev/"${dev}${N}a" || {
     64 		echo >&2 "All ${dev}s in use"
     65 		return 1
     66 	}
     67 
     68 	echo "${dev}${N}"
     69 }
     70 
     71 # find the size of the gzipped files in a .tgz archive
     72 sizeone() {
     73 	if [ ! -f "$1" ]
     74 	then
     75 		echo "$PROG: Missing set $1" 1>&2
     76 		echo 0
     77 		return;
     78 	fi
     79         case "$1" in 
     80         *.tgz|*.tar.gz)
     81                 tar tvzf "$1" | awk '{ tot += $5 } END { print tot }'
     82                 ;;
     83         *.tbz|*.tar.bz2)
     84                 tar tvjf "$1" | awk '{ tot += $5 } END { print tot }' 
     85                 ;;
     86         *)
     87                 echo 0
     88                 ;; 
     89         esac
     90 }
     91 
     92 usage() {
     93 	cat << EOF 1>&2
     94 Usage: $PROG [-S <setsdir>] [-c <custom-files-dir>] [-h <host-arch>] [-s <size>]
     95 EOF
     96 exit 1
     97 }
     98 
     99 finish() {
    100     cleanup
    101     ${sudo} umount ${mnt}
    102     ${sudo} vnconfig -u ${vnddev}
    103 }
    104 
    105 DIR="$(dirname "$0")"
    106 PROG="$(basename "$0")"
    107 bar="==="
    108 sudo=
    109 mnt="${TMPDIR:-/tmp}/image.$$"
    110 src="/usr/src"
    111 obj="/usr/obj"
    112 
    113 # First pass for options to get the host
    114 OPTS="S:c:h:s:x"
    115 while getopts "$OPTS" f
    116 do
    117 	case $f in
    118 	h)	h="$OPTARG";;
    119 	*)	;;
    120 	esac
    121 done
    122 
    123 if [ -z "$h" ]
    124 then
    125 	usage
    126 fi
    127 
    128 if [ ! -f "${DIR}/conf/${h}.conf" ]
    129 then
    130 	echo $PROG: ${DIR}/conf/${h}.conf is not present 1>&2
    131 	exit 1
    132 fi
    133 
    134 . "${DIR}/conf/${h}.conf"
    135 
    136 OPTIND=1
    137 while getopts "$OPTS" f
    138 do
    139 	case $f in
    140 	S)	setsdir="$OPTARG";;
    141 	c)	custom="$OPTARG";;
    142 	h)	;;
    143 	s)	size="$OPTARG";;
    144 	x)	set -x;;
    145 	*)	usage;;
    146 	esac
    147 done
    148 
    149 trap finish 0 1 2 3 15
    150 
    151 shift $(( "$OPTIND" - 1 ))
    152 if [ -n "$1" ]; then
    153 	# take the next argument as being the image name
    154 	image="$1"
    155 	shift
    156 fi
    157 
    158 total=0
    159 for s in ${sets}; do
    160 	one="$(sizeone ${setsdir}/${s}.tgz)"
    161 	total=$(( ${total} +  ${one} ))
    162 done
    163 # calculate size of custom files
    164 custsize=0
    165 if [ -d "${custom}" ]; then
    166 	custsize=$(ls -lR "${custom}" | awk 'NF == 9 { tot += $5 } END { print tot }')
    167 fi
    168 total=$(( ( ( ${total} + ${custsize} ) / 1000000 ) + ${overhead} ))
    169 if [ $size -eq 0 ]; then
    170         # auto-size the pkgs fs
    171         size=${total}
    172 else
    173         # check that we've been given enough space
    174         if [ ${total} -gt ${size} ]; then
    175                 echo "$PROG: Given size is ${size} MB, but we need ${total} MB" >&2
    176                 exit 1
    177         fi
    178 fi
    179 
    180 echo "${bar} making a new ${size} MB image in ${image} ${bar}"
    181 dd if=/dev/zero of=${image} bs=1m count=${size} conv=sparse
    182 
    183 vnddev=$(next_avail vnd)
    184 echo "${bar} mounting image via vnd ${vnddev} ${bar}"
    185 ${sudo} vnconfig ${vnddev} ${image}
    186 ${sudo} mkdir -p ${mnt}
    187 make_filesystems
    188 
    189 ${sudo} mkdir -p ${mnt}/etc ${mnt}/dev
    190 
    191 echo "${bar} installing sets ${bar}"
    192 (cd ${mnt} &&
    193 	for s in ${sets}; do
    194 		if [ -f "${s}" ]; then
    195 			echo ${s}
    196 			${sudo} tar xpzf ${setsdir}/${s}.tgz
    197 		fi
    198 	done
    199 )
    200 
    201 echo "${bar} performing customisations ${bar}"
    202 
    203 make_fstab
    204 
    205 ${sudo} cat > ${mnt}/etc/rc.conf << EOF
    206 #
    207 # see rc.conf(5) for more information.
    208 #
    209 # Use program=YES to enable program, NO to disable it. program_flags are
    210 # passed to the program on the command line.
    211 #
    212 
    213 # Load the defaults in from /etc/defaults/rc.conf (if it's readable).
    214 # These can be overridden below.
    215 #
    216 if [ -r /etc/defaults/rc.conf ]; then
    217         . /etc/defaults/rc.conf
    218 fi
    219 
    220 # If this is not set to YES, the system will drop into single-user mode.
    221 #
    222 rc_configured=YES
    223 
    224 hostname=${h}
    225 
    226 EOF
    227 
    228 customize
    229 
    230 for d in ${specialdirs}; do
    231 	${sudo} mkdir -p ${mnt}/${d}
    232 done
    233 
    234 if [ \( -n "${custom}" \) -a \( -d "${custom}" \) ]; then
    235 	echo "${bar} user customisations from files in ${custom} ${bar}"
    236 	(cd ${custom} && ${sudo} pax -rwpe . ${mnt})
    237 fi
    238 
    239 exit 0
    240