install gawk by default (required for gcc49 build)
[unleashed-kayak.git] / usbgen.sh
blob283b650f642df4b42585d98c267640dd737ba55b
1 #!/usr/bin/ksh93
4 # CDDL HEADER START
6 # The contents of this file are subject to the terms of the
7 # Common Development and Distribution License (the "License").
8 # You may not use this file except in compliance with the License.
10 # You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
11 # or http://www.opensolaris.org/os/licensing.
12 # See the License for the specific language governing permissions
13 # and limitations under the License.
15 # When distributing Covered Code, include this CDDL HEADER in each
16 # file and include the License file at usr/src/OPENSOLARIS.LICENSE.
17 # If applicable, add the following below this CDDL HEADER, with the
18 # fields enclosed by brackets "[]" replaced with your own identifying
19 # information: Portions Copyright [yyyy] [name of copyright owner]
21 # CDDL HEADER END
25 # Copyright 2008 Sun Microsystems, Inc. All rights reserved.
26 # Use is subject to license terms.
30 # Generate USB image from iso
31 # Originally from slim_install, modified by Toomas Soome.
34 # Solaris needs /usr/xpg4/bin/ because the tools in /usr/bin are not
35 # POSIX-conformant
36 export PATH=/usr/xpg4/bin:/bin:/usr/bin:/usr/sbin
38 # Make sure all math stuff runs in the "C" locale to avoid problems
39 # with alternative # radix point representations (e.g. ',' instead of
40 # '.' in de_DE.*-locales). This needs to be set _before_ any
41 # floating-point constants are defined in this script).
42 if [[ "${LC_ALL}" != "" ]] ; then
43 export \
44 LC_MONETARY="${LC_ALL}" \
45 LC_MESSAGES="${LC_ALL}" \
46 LC_COLLATE="${LC_ALL}" \
47 LC_CTYPE="${LC_ALL}"
48 unset LC_ALL
50 export LC_NUMERIC=C
52 #######################################################################
53 # usage
54 # Print the usage message.
55 # Input: none
56 # Returns: none
58 #######################################################################
59 function usage
61 print -u2 "\nUsage: "
62 print -u2 "${progname} iso_file usb_image tmpdir"
63 print -u2 "iso_file : The path to an existing iso file."
64 print -u2 "usb_image : The path to usb image to be created."
65 print -u2 "tmpdir : Temporary directy used during usb image " \
66 "creation.\n"
68 print -u2 "If tmpdir does not exist it will be created. If " \
69 "it or subdirectories under tmpdir can not be created " \
70 " an error is generated and this script exits."
74 #######################################################################
75 # get_filesize
76 # Get filesize for the file argv[2] and return it to the
77 # variable defined by argv[1].
78 # Input:
79 # $1 - variable to return filesize in
80 # $2 - file to query
82 # Returns:
83 # $1 - variable to return filesize in
85 # -1 if file does not exist
87 # A non-zero exit code only for internal errors and success
88 # in all other cases
90 #######################################################################
91 function get_filesize
93 set -o errexit
94 nameref filesize_ret="$1" # return filesize into this varable
95 typeset filename="$2" # file to query
96 integer filesize=-1 # temporary integer for "read" below
97 typeset dummy # dummy string
99 if [[ -f "${filename}" ]] ; then
100 ls -lb "${filename}" | \
101 grep "${filename}" | \
102 read dummy dummy dummy dummy filesize dummy
105 (( filesize_ret=filesize ))
106 return 0
111 #######################################################################
112 # cleanup
113 # This function attempst to clean up any resources this script
114 # could generate. Depending on where in the script this function
115 # is involked some resouces may not be there to cleanup, but
116 # that will not adversely effect anything.
118 # This function is not defined using the function keyword
119 # to avoid an exit loop.
121 # Input: none
122 # Returns: none
124 #######################################################################
125 cleanup ()
129 trap "" ERR INT
130 set +o errexit
132 # unmounting, and uninstalling the lofi'ed devices and
133 # cleanup temporary files.
134 IFS=''
136 typeset mount_output="$(mount)"
138 [[ "${mount_output}" == ~(E).*"${usb_path}".* ]] && \
139 umount "${usb_path}"
141 [[ "${mount_output}" == ~(E).*"${iso_path}".* ]] && \
142 umount "${iso_path}"
144 lofiadm "${usb_file}" && \
145 lofiadm -d "${usb_file}"
147 lofiadm "${iso_file}" && \
148 lofiadm -d "${iso_file}"
150 if [[ -d "${iso_path}" ]] ; then
151 rm -rf "${iso_path}"
154 if [[ -d "${usb_path}" ]] ; then
155 rm -rf "${usb_path}"
159 # If the tmpdir did not exist this script could
160 # have created it, so remove it here.
162 if ! ${tmpdir_existed} ; then
163 rm -rf "${tmpdir}"
165 } > /dev/null 2>&1
169 #######################################################################
170 # error_handler
171 # The error_handler for this script. Will cleanup the usb image
172 # that could have been partially created. Then invoke cleanup
173 # to clean up any temporary resouces.
175 # This function is not defined using the function keyword
176 # to avoid an exit loop.
178 # Input: none
179 # Returns: none
181 #######################################################################
182 error_handler ()
184 trap "" ERR INT
185 set +o errexit
187 print -u2 "\nError:\n"
188 print -u2 -r -- "${progname}: $*"
189 cleanup
192 # If an error was encountered while attempting to create
193 # the new usb image file don't leave a possibley partially
194 # constructed one around.
196 if [[ -f "${usb_file}" ]] ; then
197 rm -rf "${usb_file}" > /dev/null 2>&1
200 exit 1
203 # main
204 #######################################################################
205 # main
207 # Input:
208 # iso_file : The path to an existing iso file.
209 # usb_image : The path to usb image to be created.
210 # tmpdir : Temporary directroy used during usb image creation.
212 # If tmpdir does not exist it will be created. If it can not be
213 # created an error is generated and this script exits.
215 # This script must be run as root"
217 # Logic Flow:
218 # Set up error handling.
219 # Confirm input arguments.
220 # Create temporary directories.
221 # Mount up the existing ISO image file.
222 # Compute the size for the new USB image.
223 # Create and mount an empty new USB image.
224 # Copy the contents of the ISO file to the new USB image.
225 # Remove GRUB entries from the USB image which apply only to ISO.
226 # Set the file protections for the new USB image.
228 # Returns:
229 # 1 on failure
230 # 0 on success
232 #######################################################################
233 builtin chmod
234 builtin cp
235 builtin mkdir
236 builtin mv
237 builtin rm
239 typeset -r progname="$0"
240 typeset -r iso_file="$1"
241 typeset -r tmpdir="$3"
242 typeset tmpdir_existed=true
243 typeset -r iso_path="${tmpdir}/iso"
245 typeset -r usb_file="$2"
246 typeset -r usb_path="${tmpdir}/usb"
247 float usb_size # need floating-point for the calculations below
249 typeset isodev
250 typeset devs
251 typeset rdevs
252 typeset s0devs
253 typeset rs0devs
254 typeset rs2devs
257 # Confirm input arguments.
259 if [[ $(id) != ~(E).*uid=0\(root\).* ]]; then
260 print -u2 "Error:\nYou must run this script as root"
261 usage
262 exit 1
265 if (( $# != 3 )) ; then
266 print -u2 "Error:\nImproper arguments"
267 usage
268 exit 1
272 # Set up error handling.
273 # Use set -o errexit to trap errors. However, where possible,
274 # explicitly check command return status for errors.
276 trap "error_handler Error or interrupt encountered. Exiting" ERR INT
277 set -o errexit
280 # Create temporary directories.
282 [[ ! -d $tmpdir ]] && tmpdir_existed=false
283 mkdir -p "${iso_path}"
284 if [[ ! -d "${iso_path}" ]] ; then
285 error_handler "Unable to create or access tmpdir ${iso_path}"
288 mkdir -p "${usb_path}"
289 if [[ ! -d "${usb_path}" ]] ; then
290 error_handler "Unable to create or access tmpdir ${usb_path}"
294 # Mount up the existing ISO image file.
296 isodev="$(lofiadm -a "${iso_file}")" || \
297 error_handler "Failed to lofiadm ${iso_file}"
299 mount -F hsfs "${isodev}" "${iso_path}" || \
300 error_handler "Failed to mount ${isodev} on ${iso_path}"
304 # Compute the size for the new USB image.
305 # Use ISO file size + 20% to account for smaller block size on UFS
306 # and the log. Round to nearest kbyte plus 512
307 # plus 4MB for MBR+SMI label
309 get_filesize "usb_size" "${iso_file}"
310 if (( usb_size == -1 )) ; then
311 error_handler "Failed to get size of file ${iso_file}"
313 (( usb_size=((int( (usb_size * 1.2) / 1024.) * 1024.) + 512) + 4194304 ))
316 # Create and mount an empty new USB image.
318 mkfile -n ${usb_size} "${usb_file}" || \
319 error_handler "Failed to create file ${usb_file}"
321 devs="$(lofiadm -la "${usb_file}")" || \
322 error_handler "Failed to lofiadm file ${usb_file}"
325 # Set rdevs by replacing dsk with rdsk in devs
327 rdevs="${devs/dsk/rdsk}"
328 # for mount
329 s0devs="${devs/p0/s0}"
330 # for newfs and installboot
331 rs0devs="${rdevs/p0/s0}"
332 # for prtvtoc | fmthard
333 rs2devs="${rdevs/p0/s2}"
336 # create Solaris2 partition
338 fdisk -B "${rdevs}"
339 prtvtoc "${rs2devs}" | nawk '
340 /^[^\*]/ { r = $1; for(n = 1; n <= NF; n++) vtoc[r,n] = $n }
341 END {
342 vtoc[0,1] = 0;
343 vtoc[0,2] = 2;
344 vtoc[0,3] = 00;
345 vtoc[0,4] = vtoc[8,6] + 1;
346 vtoc[0,5] = vtoc[2,6] - vtoc[8,6];
347 vtoc[0,6] = vtoc[2,6];
348 printf("\t%d\t%d\t%02d\t%d\t%d\t%d\n",
349 vtoc[0,1], vtoc[0,2], vtoc[0,3], vtoc[0,4], vtoc[0,5], vtoc[0,6]);
350 printf("\t%d\t%d\t%02d\t%d\t%d\t%d\n",
351 vtoc[2,1], vtoc[2,2], vtoc[2,3], vtoc[2,4], vtoc[2,5], vtoc[2,6]);
352 printf("\t%d\t%d\t%02d\t%d\t%d\t%d\n",
353 vtoc[8,1], vtoc[8,2], vtoc[8,3], vtoc[8,4], vtoc[8,5], vtoc[8,6]);
354 }' | fmthard -s- "${rs2devs}"
356 # newfs doesn't ask questions if stdin isn't a tty.
357 newfs "${rs0devs}" </dev/null || \
358 error_handler "Failed to construct the UFS file system ${rs0devs}"
360 mount -o nologging "${s0devs}" "${usb_path}" || \
361 error_handler "Failed to mount construct the UFS file system ${rs0devs}"
364 # Copy the contents of the ISO file to the new USB image.
366 print "Copying ISO contents to USB image..."
367 (cd "${iso_path}"; find . -print | cpio -pmudV "${usb_path}")
370 # install bootblocks
372 installboot -mf "${usb_path}/boot/pmbr" "${usb_path}/boot/gptzfsboot" \
373 "${rs0devs}"
376 # Set the file protections for the new USB image.
378 chmod 444 "${usb_file}"
381 # unmounting, and uninstalling the lofi'ed devices
383 cleanup
385 printf "=== %s completed at %s\n\n" "$0" "$(date)"
387 exit 0