2 # Project page: http://www.sysresccd.org/
3 # (C) 2008 Francois Dupoux
4 # This scipt is available under the GPL-2 license
6 # it may also be interesting to reset the MBR
7 # dd if=/usr/lib/syslinux/mbr.bin of=/dev/sdf
9 ## HELP AND BASIC ARGUMENT PROCESSING
10 #####################################
13 ISODIR="/livemnt/boot"
14 USBDIR="/mnt/usbstick"
17 cdfiles=('sysrcd.dat' 'sysrcd.md5' 'version' 'isolinux/initram.igz'
18 'isolinux/rescuecd' 'isolinux/rescue64' 'isolinux/f1boot.msg'
19 'isolinux/isolinux.bin' 'isolinux/isolinux.cfg')
24 sysresccd-usbstick: SystemRescueCd installation script for USB-sticks
25 Syntax: sysresccd-usbstick <command> ...
27 Please, read the manual for help about how to use this script.
28 http://www.sysresccd.org/Online-Manual-EN
29 This script must be executed outside of the chroot environment.
31 Commands (execute in that order):
32 1) listdev Show the list of removable media
33 2) writembr <devname> Recreate the MBR + partition table on the stick
34 3) format <partname> Format the USB-stick device (overwrites its data)
35 4) copyfiles <partname> Copy all the files from the cdrom to the USB-stick
36 5) syslinux <partname> Make the device bootable
38 -h|--help Display this screen
39 -i ISODIR Set the mount directory for the stock SysRescCD iso ($ISODIR)
40 -u USBDIR Set the directory for mounting the USB stick ($USBDIR)
41 -m SYSLINUX Set the syslinux program ($SYSLINUX)
42 -s MINSIZEMB Minimal size required for SysRescCD in mega-bytes
43 dialog Dialog to make SystemRescueCD-USB-Sticks
45 Distributed under the GNU Public License version 2 - http://www.sysresccd.org
49 ## MISC FUNCTIONS: Many utilities functions
50 ###########################################
52 # show the error message ($1 = first line of the message)
56 echo "Please, read the manual for more help about this script"
57 echo "Web: http://www.sysresccd.org"
62 #####################################
68 echo "${PROG}: error: $1"
70 echo "${PROG}: aborting."
75 ## MISC FUNCTIONS: Many utilities functions
76 ###########################################
78 # check that there is one partition and one only on block-device $1
79 find_first_partition()
82 if [ -z "${devname}" ] || [ ! -d "/sys/block/$(basename ${devname})" ]
84 die "${devname} is not a valid device name"
91 partname="${devname}${i}"
92 if [ -b "${partname}" ]
94 [ "${firstpart}" = '0' ] && firstpart="$i"
95 partcnt=$((partcnt+1))
99 if [ "${partcnt}" = '1' ]
107 # check $1 is a valid partition name
108 check_valid_partname()
110 if [ -z "${partname}" ]
112 die "you have to provide a valid partition device-name as argument of this command"
115 if [ -z "${partname}" ] || [ ! -b "${partname}" ]
117 die "${partname} is not a valid partition name"
120 if ! echo "${partname}" | grep -qE '^/dev/[a-z]*[1-4]+$'
122 die "device [${partname}] is not a valid partition. Expect something like [/dev/sdf1]"
125 if is_dev_mounted "${partname}"
127 die "${partname} is already mounted, cannot continue"
133 # check $1 is a valid block device name
134 check_valid_blkdevname()
136 if [ -z "${devname}" ]
138 die "you have to provide a valid device name as argument of this command"
141 if [ ! -b "${devname}" ] || [ ! -d "/sys/block/$(basename ${devname})" ]
143 die "${devname} is not a valid device name"
146 if is_dev_mounted "${devname}"
148 die "${devname} is already mounted, cannot continue"
154 check_sysresccd_files()
157 [ -z "${rootdir}" ] && rootdir="${ISODIR}"
158 for curfile in ${cdfiles[*]}
160 curcheck="${rootdir}/${curfile}"
161 if [ ! -f ${curcheck} ]
163 die "Cannot find ${curcheck}, cannot continue"
169 # returns 0 if the device is big enough
174 if [ -z "${devname}" ]
176 die "check_sizeof_dev(): devname is empty"
179 if [ -z "$(which blockdev)" ]
181 echo "blockdev not found, assuming the size is ok"
185 secsizeofdev="$(blockdev --getsz ${devname})"
186 mbsizeofdev="$((secsizeofdev/2048))"
187 if [ "${mbsizeofdev}" -lt "${MINSIZEMB}" ]
189 die "The device [${devname}] is only ${mbsizeofdev} MB. It is too small to copy all the files, an USB-stick of at least ${MINSIZEMB}MB is recommended"
191 echo "The device [${devname}] seems to be big enough: ${mbsizeofdev} MB."
196 # say how much freespace there is on a mounted device
197 check_disk_freespace()
199 freespace=$(\df -m -P ${1} | grep " ${1}$" | tail -n 1 | awk '{print $4}')
200 echo "Free space on ${1} is ${freespace}MB"
201 if [ "${freespace}" -lt "${MINSIZEMB}" ]
203 die "There is not enough free space on the USB-stick to copy the SystemRescuecd files."
208 # check that device $1 is an USB-stick
213 remfile="/sys/block/${curdev}/removable"
214 vendor="$(cat /sys/block/${curdev}/device/vendor 2>/dev/null)"
215 model="$(cat /sys/block/${curdev}/device/model 2>/dev/null)"
216 if [ -f "${remfile}" ] && cat ${remfile} 2>/dev/null | grep -qF '1' \
217 && cat /sys/block/${curdev}/device/uevent 2>/dev/null | grep -qF 'DRIVER=sd'
228 shortname="$(echo ${devname} | sed -e 's!/dev/!!g')"
230 check_valid_blkdevname "${devname}"
231 if ! is_dev_usb_stick "${shortname}"
233 die "Device [${devname}] does not seem to be an usb-stick. Cannot continue."
236 check_sizeof_dev "${devname}"
238 if [ -z "$(which install-mbr)" ] || [ -z "$(which parted)" ]
240 die "install-mbr and parted must be installed, check these programs first."
243 cmd="install-mbr ${devname} --force"
247 die "${cmd} --> failed"
250 cmd="parted -s ${devname} mklabel msdos"
252 if ! ${cmd} 2>/dev/null
254 die "${cmd} --> failed"
257 cmd="parted -s ${devname} mkpartfs primary fat32 0 100%"
259 if ! ${cmd} 2>/dev/null
261 die "${cmd} --> failed"
264 cmd="parted -s ${devname} set 1 boot on"
266 if ! ${cmd} 2>/dev/null
268 die "${cmd} --> failed"
275 check_valid_partname "${partname}"
277 check_sizeof_dev "${partname}"
279 if [ -z "$(which mkfs.vfat)" ]
281 die "mkfs.vfat not found on your system, please install dosfstools first."
284 if mkfs.vfat -F 32 -n SYSRESC ${partname}
286 echo "Partition ${partname} has been successfully formatted"
289 echo "Partition ${partname} cannot be formatted"
297 check_valid_partname "${partname}"
299 # check the important files are available in ${ISODIR}
300 check_sysresccd_files "${ISODIR}"
302 check_sizeof_dev "${partname}"
304 mkdir -p ${USBDIR} 2>/dev/null
305 if ! mount -t vfat ${partname} ${USBDIR}
307 die "cannot mount ${partname} on ${USBDIR}"
309 echo "${partname} successfully mounted on ${USBDIR}"
311 check_disk_freespace "${USBDIR}"
313 if cp -r --remove-destination ${ISODIR}/* ${USBDIR}/ && sync
315 echo "Files have been successfully copied to ${partname}"
317 echo "Cannot copy files to ${partname}"
320 for curfile in '${USBDIR}/isolinux/isolinux.cfg'
322 if [ ! -f "${curfile}" ]
325 die "${curfile} not found, cannot continue"
329 # check the important files have been copied
330 check_sysresccd_files "${USBDIR}"
332 # move isolinux files to syslinux files
333 rm -rf ${USBDIR}/syslinux
334 if ! mv ${USBDIR}/isolinux/isolinux.cfg ${USBDIR}/isolinux/syslinux.cfg \
335 || ! mv ${USBDIR}/isolinux ${USBDIR}/syslinux
338 die "cannot move isolinux to syslinux, failed"
341 # remove the last lines which produces error messages 'bad keyword' with syslinux
342 sed -i -e '/label disk[1-2]$/d' -e '/label floppy$/d' -e '/label nextboot$/d' -e '/localboot/d' ${USBDIR}/syslinux/syslinux.cfg
344 # add scandelay option which allows the usb devices to be detected
345 sed -i -e 's!initrd=initram.igz!initrd=initram.igz scandelay=5!g' ${USBDIR}/syslinux/syslinux.cfg
353 check_valid_partname "${partname}"
355 if [ -z "$(which ${SYSLINUX})" ]
357 die "${SYSLINUX} not found on your system, please install syslinux first."
360 if ${SYSLINUX} ${partname} && sync
362 echo "${SYSLINUX} has successfully prepared ${partname}"
364 echo "${SYSLINUX} failed to prepare ${partname}"
372 if cat /proc/mounts | grep -q "^${curdev}"
382 lwselection="`mktemp /tmp/lwselection.XXXX`"
383 selection='dialog --backtitle "Select USB-Stick" --checklist "Select USB-Stick" 20 61 5'
385 for curpath in /sys/block/*
387 curdev="$(basename ${curpath})"
388 devname="/dev/${curdev}"
389 if is_dev_usb_stick ${curdev}
391 if [ -n "$(which blockdev)" ]
393 secsizeofdev="$(blockdev --getsz /dev/${curdev})"
394 mbsizeofdev="$((secsizeofdev/2048))"
395 sizemsg=" and size=${mbsizeofdev}MB"
397 echo "Device [${devname}] detected as [${vendor} ${model}] is removable${sizemsg}"
398 if is_dev_mounted "${devname}"
400 echo "Device [${devname}] is mounted"
402 echo "Device [${devname}] is not mounted"
404 find_first_partition ${devname}
406 if [ "${firstpart}" != '0' ]
408 echo "Device [${devname}] has one partition: ${devname}${firstpart}"
409 selection="$selection \"${devname}\" \"\" off"
411 echo "Cannot identify which partition to use on ${devname}"
416 if [ "${devcnt}" = '0' ]
418 echo "No USB-stick has been detected."
420 eval $selection 2>$lwselection
421 if test -s $lwselection; then
422 for devname2 in `cat $lwselection | tr -d \" | sort`; do
423 do_writembr ${devname2}
425 find_first_partition ${devname2}
426 devname2="${devname2}$?"
427 do_format ${devname2}
428 do_copyfiles ${devname2}
429 do_syslinux ${devname2}
440 for curpath in /sys/block/*
442 curdev="$(basename ${curpath})"
443 devname="/dev/${curdev}"
444 if is_dev_usb_stick ${curdev}
446 if [ -n "$(which blockdev)" ]
448 secsizeofdev="$(blockdev --getsz /dev/${curdev})"
449 mbsizeofdev="$((secsizeofdev/2048))"
450 sizemsg=" and size=${mbsizeofdev}MB"
452 echo "Device [${devname}] detected as [${vendor} ${model}] is removable${sizemsg}"
453 if is_dev_mounted "${devname}"
455 echo "Device [${devname}] is mounted"
457 echo "Device [${devname}] is not mounted"
459 find_first_partition ${devname}
461 if [ "${firstpart}" != '0' ]
463 echo "Device [${devname}] has one partition: ${devname}${firstpart}"
465 echo "Cannot identify which partition to use on ${devname}"
470 if [ "${devcnt}" = '0' ]
472 echo "No USB-stick has been detected."
476 ## MAIN SHELL FUNCTION
477 ########################################################
479 if [ $# -eq 0 ] # Script invoked with no command-line args?
485 while getopts ":ui:r:w:m:" Option
488 i ) ISODIR="$OPTARG";;
489 r ) ROOTDIR="$OPTARG";;
490 w ) WORKDIR="$OPTARG";;
491 * ) usage; exit 1;; # Default, handles -h
494 shift $(($OPTIND - 1))
499 if [ "$(whoami)" != "root" ]
501 help_readman "$0: This script requires root privileges to operate."
504 if ! cat /proc/mounts | awk '{print $2}' | grep -q -F '/memory'
506 help_readman "$0: This script must be executed from SystemRescueCd"