diff options
Diffstat (limited to 'usb-and-pxe-installers/usbimg2disk.sh')
-rw-r--r-- | usb-and-pxe-installers/usbimg2disk.sh | 140 |
1 files changed, 105 insertions, 35 deletions
diff --git a/usb-and-pxe-installers/usbimg2disk.sh b/usb-and-pxe-installers/usbimg2disk.sh index aed32c51..f806c5ed 100644 --- a/usb-and-pxe-installers/usbimg2disk.sh +++ b/usb-and-pxe-installers/usbimg2disk.sh @@ -1,7 +1,7 @@ -#!/bin/sh -# $Id: usbimg2disk.sh,v 1.9 2010/04/24 18:21:53 eha Exp eha $ +#!/bin/bash +# $Id: usbimg2disk.sh,v 1.20 2011/04/16 19:11:27 eha Exp eha $ # -# Copyright 2009, 2010 Eric Hameleers, Eindhoven, NL +# Copyright 2009, 2010, 2011 Eric Hameleers, Eindhoven, NL # All rights reserved. # # Redistribution and use of this script, with or without modification, is @@ -24,15 +24,19 @@ # Paranoid as usual: set -e +# Define some variables ahead of time, so that cleanup knows about them: +MNTDIR1="" +MNTDIR2="" +MNTDIR3="" + # Clean up in case of failure: cleanup() { # Clean up by unmounting our loopmounts, deleting tempfiles: echo "--- Cleaning up the staging area..." sync - umount -f ${MNTDIR1} 2>/dev/null || true - umount -f ${MNTDIR2} 2>/dev/null || true - rm -rf ${MNTDIR3} - rmdir $MNTDIR1 $MNTDIR2 + [ ! -z "${MNTDIR1}" ] && ( umount -f ${MNTDIR1} ; rmdir $MNTDIR1 ) + [ ! -z "${MNTDIR2}" ] && ( umount -f ${MNTDIR2} ; rmdir $MNTDIR2 ) + [ ! -z "${MNTDIR3}" ] && rm -rf ${MNTDIR3} || true } trap "echo \"*** $0 FAILED at line $LINENO ***\"; cleanup; exit 1" ERR INT TERM @@ -60,7 +64,7 @@ showhelp() { echo "# -o|--outdev <filename> The device name of your USB drive" echo "# -s|--slackdir <dir> Use 'dir' as the root of Slackware tree" echo "# -u|--unattended Do not ask any questions" - echo "# -L|--label FAT label when formatting the USB drive" + echo "# -L|--label <labelname> FAT label when formatting the USB drive" echo "# " echo "# Examples:" @@ -90,6 +94,9 @@ reformat() { # Wipe the MBR: dd if=/dev/zero of=$TOWIPE bs=512 count=1 + # Temporarily accept errors (so that we can examine them): + set +e + # create a FAT32 partition (type 'b') /sbin/fdisk $TOWIPE <<EOF n @@ -102,6 +109,27 @@ b w EOF + # Check if fdisk gave an error (like "error closing file"). + # Some desktop environments auto-mount the partition on sight...: + if [ $? -ne 0 ]; then + echo "*** The fdisk command had an error." + echo "*** Some desktop environments (KDE, GNOME) may automatically mount" + echo "*** the new FAT partition on your USB drive, causing the fdisk error." + if [ $UNATTENDED -eq 0 ]; then + # if we are running interactively, allow to chicken out now: + echo "*** Perhaps you want to format the device '$TOWIPE' yourself first?" + read -p "*** Press ENTER to continue anyway or Ctrl-C to quit now: " JUNK + fi + fi + + # Fail on errors again: + set -e + + if mount | grep -q ${TOWIPE}1 ; then + echo "--- Un-mounting ${TOWIPE}1 because your desktop auto-mounted it..." + umount -f ${TOWIPE}1 + fi + # We set the fat label to '$THELABEL' when formatting. # It will enable the installer to mount the fat partition automatically # and pre-fill the correct pathname for the "SOURCE" dialog. @@ -115,14 +143,12 @@ makebootable() { # Sanity checks: if [ ! -b $USBDRV ]; then - echo "Not a block device: '$USBDRV' !" + echo "*** Not a block device: '$USBDRV' !" exit 1 fi - # Set the bootable flag for the first (and only...) partition: - /sbin/sfdisk $USBDRV -N1 <<EOF -,,,* -EOF + # Set the bootable flag for the first partition: + /sbin/sfdisk -A $USBDRV 1 } # Parse the commandline parameters: @@ -154,7 +180,7 @@ while [ ! -z "$1" ]; do shift 2 ;; -s|--slackdir) - REPOSROOT="$(cd $(dirname $2); pwd)/$(basename $2)" + REPODIR="$2" FULLINSTALLER="yes" shift 2 ;; @@ -163,11 +189,11 @@ while [ ! -z "$1" ]; do shift ;; -L|--label) - FATLABEL="$2" + CUSTOMLABEL="$2" shift 2 ;; *) - echo "Unknown parameter '$1'!" + echo "*** Unknown parameter '$1'!" exit 1 ;; esac @@ -176,18 +202,32 @@ done # Before we start: [ -x /bin/id ] && CMD_ID="/bin/id" || CMD_ID="/usr/bin/id" if [ "$($CMD_ID -u)" != "0" ]; then - echo "You need to be root to run $(basename $0)." + echo "*** You need to be root to run $(basename $0)." exit 1 fi +# Check existence of the package repository if that was passed as a parameter: +if [ -n "$REPODIR" ]; then + if [ ! -d "$REPODIR" ]; then + echo "*** This is not a directory: '$REPODIR' !" + exit 1 + else + # This also takes care of stripping a trailing '/', which is required + # for the rsync command to work as intended: + REPOSROOT="$(cd $(dirname $REPODIR); pwd)/$(basename $REPODIR)" + fi +fi + # Check FAT label: -if [ -n "${FATLABEL}" ]; then - if [ "x$(echo '${FATLABEL}'| tr -d '[:alnum:]_-.')" != "x" ]; then - echo "FAT label '${FATLABEL}' is not an acceptible name!" +if [ -n "${CUSTOMLABEL}" ]; then + if [ "x$(echo "${CUSTOMLABEL}"| tr -d '[:alnum:]._-')" != "x" ]; then + echo "*** FAT label '${CUSTOMLABEL}' is not an acceptible name!" exit 1 - elif [ ${#FATLABEL} gt 11 ]; then - echo "FAT label '${FATLABEL}' must be less than 12 characters!" + elif [ ${#CUSTOMLABEL} -gt 11 ]; then + echo "*** FAT label '${CUSTOMLABEL}' must be less than 12 characters!" exit 1 + else + FATLABEL="${CUSTOMLABEL}" fi else FATLABEL="USBSLACKINS" @@ -230,17 +270,15 @@ if [ ! -f $USBIMG ]; then exit 1 fi -if [ $REFORMAT -eq 0 ]; then +if [ ! -b $TARGET ]; then + echo "*** Not a block device: '$TARGET' !" + exit 1 +elif [ $REFORMAT -eq 0 ]; then if ! /sbin/blkid -t TYPE=vfat $TARGETPART 1>/dev/null 2>/dev/null ; then echo "*** I fail to find a 'vfat' partition: '$TARGETPART' !" echo "*** If you want to format the USB thumb drive, add the '-f' parameter" exit 1 fi -else - if [ ! -b $TARGET ]; then - echo "*** Not a block device: '$TARGET' !" - exit 1 - fi fi if mount | grep -q $TARGETPART ; then @@ -267,6 +305,11 @@ if [ $UNATTENDED -eq 0 ]; then echo "" echo "# We are going to ${DOFRMT}use this device - '$TARGET':" + echo "# Vendor : $(cat /sys/block/$(basename $TARGET)/device/vendor)" + echo "# Model : $(cat /sys/block/$(basename $TARGET)/device/model)" + echo "# Size : $(( $(cat /sys/block/$(basename $TARGET)/size) / 2048)) MB" + echo "# " + echo "# FDISK OUTPUT:" /sbin/fdisk -l $TARGET | while read LINE ; do echo "# $LINE" ; done echo "" @@ -283,12 +326,37 @@ cat /dev/null > $LOGFILE # If we need to format the USB drive, do it now: if [ $REFORMAT -eq 1 ]; then - echo "--- Formatting $TARGET and creating VFAT partition..." + echo "--- Formatting $TARGET with VFAT partition label '${FATLABEL}'..." if [ $UNATTENDED -eq 0 ]; then echo "--- Last chance! Press CTRL-C to abort!" read -p "Or press ENTER to continue: " JUNK fi ( reformat $TARGET ${FATLABEL} ) 1>>$LOGFILE 2>&1 +else + # We do not format the drive, but apply a FAT label if required. + + # Prepare for using mlabel to change the FAT label: + MTOOLSRCFILE=$(mktemp -p /tmp -t mtoolsrc.XXXXXX) + echo "drive s: file=\"$TARGETPART\"" > $MTOOLSRCFILE + + if [ -n "$CUSTOMLABEL" ]; then + # User gave us a FAT label to use, so we will force that upon the drive: + echo "--- Setting FAT partition label to '$FATLABEL'" + MTOOLSRC=$MTOOLSRCFILE mlabel s:${FATLABEL} + elif [ -n "$(/sbin/blkid -t TYPE=vfat -s LABEL -o export $TARGETPART)" ] ; then + # User did not care, but the USB stick has a FAT label that we will use: + eval $(/sbin/blkid -t TYPE=vfat -s LABEL -o export $TARGETPART) + FATLABEL=$LABEL + echo "--- Using current FAT partition label '$FATLABEL'" + unset LABEL + else + # No user-supplied label, nor a drive label present. We apply our default: + echo "--- Setting FAT partition label to '$FATLABEL'" + MTOOLSRC=$MTOOLSRCFILE mlabel s:${FATLABEL} + fi + + # Cleanup: + rm -f $MTOOLSRCFILE fi # Create a temporary mount point for the image file: @@ -298,7 +366,7 @@ if [ ! -d $MNTDIR1 ]; then echo "*** Failed to create a temporary mount point for the image!" exit 1 else - chmod 700 $MNTDIR1 + chmod 711 $MNTDIR1 fi # Create a temporary mount point for the USB thumb drive partition: @@ -307,7 +375,7 @@ if [ ! -d $MNTDIR2 ]; then echo "*** Failed to create a temporary mount point for the usb thumb drive!" exit 1 else - chmod 700 $MNTDIR2 + chmod 711 $MNTDIR2 fi # Create a temporary directory to extract the initrd if needed: @@ -316,7 +384,7 @@ if [ ! -d $MNTDIR3 ]; then echo "*** Failed to create a temporary directory to extract the initrd!" exit 1 else - chmod 700 $MNTDIR3 + chmod 711 $MNTDIR3 fi # Mount the image file: @@ -369,7 +437,7 @@ fi # Copy boot image files to the USB disk in its own subdirectory '/syslinux': echo "--- Copying boot files to the USB drive..." mkdir -p $MNTDIR2/syslinux -cp -a $MNTDIR1/* $MNTDIR2/syslinux/ +cp -R $MNTDIR1/* $MNTDIR2/syslinux/ rm -f $MNTDIR2/syslinux/ldlinux.sys # If we are creating a full Slackware installer, there is a lot more to do: @@ -389,10 +457,13 @@ if [ "$FULLINSTALLER" = "yes" ]; then # Adapt the dialogs so that pressing [OK] will be all there is to it: sed -i -e 's# --menu# --default-item 6 --menu#' usr/lib/setup/SeTmedia sed -i -e "s# 2> \$TMP/sourcedir# /usbinstall/$(basename $REPOSROOT)/$PKGDIR 2> \$TMP/sourcedir#" usr/lib/setup/INSdir + FIXF=$(find usr/lib/setup -name SeTp*media) + sed -i -e 's# --menu# --default-item 3 --menu#' $FIXF ) 2>>$LOGFILE # Recreate the initrd: echo "--- Gzipping the initrd image again:" + chmod 0755 ${MNTDIR3} ( cd ${MNTDIR3}/ find . |cpio -o -H newc |gzip > ${MNTDIR2}/syslinux/initrd.img ) 2>>$LOGFILE @@ -400,11 +471,10 @@ if [ "$FULLINSTALLER" = "yes" ]; then # Copy Slackware package tree (no sources) to the USB disk - # we already made sure that ${REPOSROOT} does not end with a '/' echo "--- Copying Slackware package tree to the USB drive..." - rsync -rptHDL $EXCLUDES $REPOSROOT $MNTDIR2/ + rsync -rpthDL --delete $EXCLUDES $REPOSROOT $MNTDIR2/ fi # Unmount/remove stuff: -sync cleanup # Run syslinux and write a good MBR: |