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]
25 # Copyright 2008 Sun Microsystems, Inc. All rights reserved.
26 # Use is subject to license terms.
30 # Generate USB image from iso
33 # Solaris needs /usr/xpg4/bin/ because the tools in /usr/bin are not
35 export PATH
=/usr
/xpg
4/bin
:/bin
:/usr
/bin
:/usr
/sbin
37 # Make sure all math stuff runs in the "C" locale to avoid problems
38 # with alternative # radix point representations (e.g. ',' instead of
39 # '.' in de_DE.*-locales). This needs to be set _before_ any
40 # floating-point constants are defined in this script).
41 if [[ "${LC_ALL}" != "" ]] ; then
43 LC_MONETARY
="${LC_ALL}" \
44 LC_MESSAGES
="${LC_ALL}" \
45 LC_COLLATE
="${LC_ALL}" \
51 #######################################################################
53 # Print the usage message.
57 #######################################################################
61 print
-u2 "${progname} iso_file usb_image tmpdir"
62 print
-u2 "iso_file : The path to an existing iso file."
63 print
-u2 "usb_image : The path to usb image to be created."
64 print
-u2 "tmpdir : Temporary directy used during usb image " \
67 print
-u2 "If tmpdir does not exist it will be created. If " \
68 "it or subdirectories under tmpdir can not be created " \
69 " an error is generated and this script exits."
73 #######################################################################
75 # Get filesize for the file argv[2] and return it to the
76 # variable defined by argv[1].
78 # $1 - variable to return filesize in
82 # $1 - variable to return filesize in
84 # -1 if file does not exist
86 # A non-zero exit code only for internal errors and success
89 #######################################################################
93 nameref filesize_ret
="$1" # return filesize into this varable
94 typeset filename
="$2" # file to query
95 integer filesize
=-1 # temporary integer for "read" below
96 typeset dummy
# dummy string
98 if [[ -f "${filename}" ]] ; then
99 ls -lb "${filename}" | \
100 grep "${filename}" | \
101 read dummy dummy dummy dummy filesize dummy
104 (( filesize_ret
=filesize
))
110 #######################################################################
112 # This function attempst to clean up any resources this script
113 # could generate. Depending on where in the script this function
114 # is involked some resouces may not be there to cleanup, but
115 # that will not adversely effect anything.
117 # This function is not defined using the function keyword
118 # to avoid an exit loop.
123 #######################################################################
131 # unmounting, and uninstalling the lofi'ed devices and
132 # cleanup temporary files.
135 typeset mount_output
="$(mount)"
137 [[ "${mount_output}" == ~
(E
).
*"${usb_path}".
* ]] && \
140 [[ "${mount_output}" == ~
(E
).
*"${iso_path}".
* ]] && \
143 lofiadm
"${usb_file}" && \
144 lofiadm
-d "${usb_file}"
146 lofiadm
"${iso_file}" && \
147 lofiadm
-d "${iso_file}"
149 if [[ -d "${iso_path}" ]] ; then
153 if [[ -d "${usb_path}" ]] ; then
158 # If the tmpdir did not exist this script could
159 # have created it, so remove it here.
161 if ! ${tmpdir_existed} ; then
168 #######################################################################
170 # The error_handler for this script. Will cleanup the usb image
171 # that could have been partially created. Then invoke cleanup
172 # to clean up any temporary resouces.
174 # This function is not defined using the function keyword
175 # to avoid an exit loop.
180 #######################################################################
186 print
-u2 "\nError:\n"
187 print
-u2 -r -- "${progname}: $*"
191 # If an error was encountered while attempting to create
192 # the new usb image file don't leave a possibley partially
193 # constructed one around.
195 if [[ -f "${usb_file}" ]] ; then
196 rm -rf "${usb_file}" > /dev
/null
2>&1
203 #######################################################################
207 # iso_file : The path to an existing iso file.
208 # usb_image : The path to usb image to be created.
209 # tmpdir : Temporary directroy used during usb image creation.
211 # If tmpdir does not exist it will be created. If it can not be
212 # created an error is generated and this script exits.
214 # This script must be run as root"
217 # Set up error handling.
218 # Confirm input arguments.
219 # Create temporary directories.
220 # Mount up the existing ISO image file.
221 # Compute the size for the new USB image.
222 # Create and mount an empty new USB image.
223 # Copy the contents of the ISO file to the new USB image.
224 # Remove GRUB entries from the USB image which apply only to ISO.
225 # Set the file protections for the new USB image.
231 #######################################################################
238 typeset
-r progname
="$0"
239 typeset
-r iso_file
="$1"
240 typeset
-r tmpdir
="$3"
241 typeset tmpdir_existed
=true
242 typeset
-r iso_path
="${tmpdir}/iso"
244 typeset
-r usb_file
="$2"
245 typeset
-r usb_path
="${tmpdir}/usb"
246 float usb_size
# need floating-point for the calculations below
256 # Confirm input arguments.
258 if [[ $
(id
) != ~
(E
).
*uid
=0\
(root\
).
* ]]; then
259 print
-u2 "Error:\nYou must run this script as root"
264 if (( $# != 3 )) ; then
265 print
-u2 "Error:\nImproper arguments"
271 # Set up error handling.
272 # Use set -o errexit to trap errors. However, where possible,
273 # explicitly check command return status for errors.
275 trap "error_handler Error or interrupt encountered. Exiting" ERR INT
279 # Create temporary directories.
281 [[ ! -d $tmpdir ]] && tmpdir_existed
=false
282 mkdir
-p "${iso_path}"
283 if [[ ! -d "${iso_path}" ]] ; then
284 error_handler
"Unable to create or access tmpdir ${iso_path}"
287 mkdir
-p "${usb_path}"
288 if [[ ! -d "${usb_path}" ]] ; then
289 error_handler
"Unable to create or access tmpdir ${usb_path}"
293 # Mount up the existing ISO image file.
295 isodev
="$(lofiadm -a "${iso_file}")" || \
296 error_handler
"Failed to lofiadm ${iso_file}"
298 mount
-F hsfs
"${isodev}" "${iso_path}" || \
299 error_handler
"Failed to mount ${isodev} on ${iso_path}"
303 # Compute the size for the new USB image.
304 # Use ISO file size + 20% to account for smaller block size on UFS
305 # and the log. Round to nearest kbyte plus 512
306 # plus 4MB for MBR+SMI label
308 get_filesize
"usb_size" "${iso_file}"
309 if (( usb_size
== -1 )) ; then
310 error_handler
"Failed to get size of file ${iso_file}"
312 (( usb_size
=((int
( (usb_size
* 1.2) / 1024.
) * 1024.
) + 512) + 4194304 ))
315 # Create and mount an empty new USB image.
317 mkfile
-n ${usb_size} "${usb_file}" || \
318 error_handler
"Failed to create file ${usb_file}"
320 devs
="$(lofiadm -la "${usb_file}")" || \
321 error_handler
"Failed to lofiadm file ${usb_file}"
324 # Set rdevs by replacing dsk with rdsk in devs
326 rdevs
="${devs/dsk/rdsk}"
328 s0devs
="${devs/p0/s0}"
329 # for newfs and installboot
330 rs0devs
="${rdevs/p0/s0}"
331 # for prtvtoc | fmthard
332 rs2devs
="${rdevs/p0/s2}"
335 # create Solaris2 partition
338 prtvtoc
"${rs2devs}" | nawk
'
339 /^[^\*]/ { r = $1; for(n = 1; n <= NF; n++) vtoc[r,n] = $n }
344 vtoc[0,4] = vtoc[8,6] + 1;
345 vtoc[0,5] = vtoc[2,6] - vtoc[8,6];
346 vtoc[0,6] = vtoc[2,6];
347 printf("\t%d\t%d\t%02d\t%d\t%d\t%d\n",
348 vtoc[0,1], vtoc[0,2], vtoc[0,3], vtoc[0,4], vtoc[0,5], vtoc[0,6]);
349 printf("\t%d\t%d\t%02d\t%d\t%d\t%d\n",
350 vtoc[2,1], vtoc[2,2], vtoc[2,3], vtoc[2,4], vtoc[2,5], vtoc[2,6]);
351 printf("\t%d\t%d\t%02d\t%d\t%d\t%d\n",
352 vtoc[8,1], vtoc[8,2], vtoc[8,3], vtoc[8,4], vtoc[8,5], vtoc[8,6]);
353 }' | fmthard
-s- "${rs2devs}"
355 # newfs doesn't ask questions if stdin isn't a tty.
356 newfs
"${rs0devs}" </dev
/null || \
357 error_handler
"Failed to construct the UFS file system ${rs0devs}"
359 mount
-o nologging
"${s0devs}" "${usb_path}" || \
360 error_handler
"Failed to mount construct the UFS file system ${rs0devs}"
363 # Copy the contents of the ISO file to the new USB image.
365 print
"Copying ISO contents to USB image..."
366 (cd "${iso_path}"; find .
-print |
cpio -pmudV "${usb_path}")
371 installboot
-mf "${usb_path}/boot/pmbr" "${usb_path}/boot/gptzfsboot" \
374 # If we get an error hereforth in menu.lst modifications, proceed with a warning
379 # Remove "Hard Disk" GRUB entries from the USB image as they apply only to ISO.
383 /^title.*Hard Disk$/ { inhard=1 }
384 /^title/ { if (index($0,"Hard Disk") == 0) inhard=0 }
386 ' ${usb_path}/boot
/grub
/menu.lst
> ${usb_path}/boot
/grub
/menu2.lst
387 if [[ $?
== 0 ]] ; then
388 mv ${usb_path}/boot
/grub
/menu2.lst
${usb_path}/boot
/grub
/menu.lst
390 print
-u2 "Warning: Could not remove \"Hard Disk\" entry from boot menu"
394 # Set the file protections for the new USB image.
396 chmod 444 "${usb_file}"
399 # unmounting, and uninstalling the lofi'ed devices
403 printf "=== %s completed at %s\n\n" "$0" "$(date)"