Attached is a patch for my changes to usbcopy. Let me know what I need
to do in order to have it applied to the master tree. Thanks.
--Bill
-------------- next part --------------
comparing with ssh://anon at hg.opensolaris.org/hg/caiman/distro_constructor
searching for changes
changeset: 87:671e91c72d63
tag: tip
user: billm at localhost
date: Wed May 28 16:28:02 2008 -0700
summary: 1934 verify option for usbcopy
diff -r f2e55695997b -r 671e91c72d63 tools/usbcopy
--- a/tools/usbcopy Tue May 27 21:58:10 2008 -0700
+++ b/tools/usbcopy Wed May 28 16:28:02 2008 -0700
@@ -22,9 +22,9 @@
# Copyright 2007 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
-# Script to install Belenix onto a Bootable LiveUSB
-# By Anil Gulecha
-#
+
+# Make sure we get the right versions of the commands
+PATH=/usr/sbin:/usr/bin
if [ $# != 1 ]; then
echo "Usage: $0 <USB image path>"
@@ -32,64 +32,51 @@ fi
fi
img=$1
-if [ ! -f $img ] && [ ! -c $img ]; then
+if [ ! -r $img ] && [ ! -c $img ]; then
echo "Error: $img does not exist."
exit 1
fi
+# Image size (in MB)
+ibytes=$(stat -Lc %s $img)
+isz=$((ibytes >> 20))
-let i=0
-
-#nawk script to o/p the details of plugged in USB drives
-rmformat 2>/dev/null | nawk 'BEGIN {
- FS = ":";
- lnode=0;
- physdev="";
- node = "";
- devname = "";
- bus = "";
- size = 0;
- bustype = "USB";
-} {
- if (lnode == 1 && match($1, "Logical Node")) {
- if (match(bus, bustype))
- printf("%s\t%s\t%s\t%s\n", physdev, node, size, devname);
- node = $2;
- } else {
- if (match($1, "Logical Node")) {
- lnode = 1;
- node = $2;
- } else if (match($1, "Bus")) {
- bus=$2
- } else if (match($1, "Connected Device")) {
- devname = $2;
- } else if (match($1, "Size")) {
- size = $2;
- } else if (match($1, "Physical Node")) {
- physdev=$2
- }
- }
-} END {
- if (lnode == 1) {
- if (match(bus, bustype))
- printf("%s\t%s\t%s\t%s\n", physdev, node, size,
devname);
- }
-}' >/tmp/ulst
-
+#nawk script to output the details of plugged in USB drives
+i=0
while read p l s m d; do
phys[$i]=$p
log[$i]=$l
size[$i]=$s
mult[$i]=$m
desc[$i]=$d
- let i=$i+1
-done </tmp/ulst
-rm /tmp/ulst
+ ((i++))
+done < <(rmformat 2>/dev/null | nawk 'BEGIN {
+ FS = ":";
+ bustype = "USB";
+}
+/Logical Node/ {
+ lnode = 1;
+ node = $2;
+}
+/Physical Node/ {
+ physdev = $2
+}
+/Connected Device/ {
+ devname = $2
+}
+/Bus/ {
+ bus = $2;
+}
+/Size/ && lnode && bus ~ bustype {
+ size = $2;
+ printf("%s\t%s\t%s\t%s\n", physdev, node, size, devname);
+ lnode = 0;
+}')
echo Found the following USB devices:
-let j=0
+j=0
while [ $j -lt $i ]; do
echo "$j: ${log[$j]} ${size[$j]} ${mult[$j]} ${desc[$j]}"
- let j=$j+1
+ ((j++))
done
while read -p "Enter the number of your choice: " choice; do
if [ -z "${choice}" ]; then
@@ -103,8 +90,8 @@ done
done
dev=${log[$choice]}
-s0cdev=`echo $dev|sed -e 's/p0/s0/'`
-s0bdev=`echo $s0cdev|sed -e 's/rdsk/dsk/'`
+s0cdev=${dev/p0/s0}
+s0bdev=${s0cdev/rdsk/dsk}
if [ ! -b $s0bdev ] || [ ! -c $s0cdev ]; then
echo "Missing device nodes for $dev"
exit 1
@@ -118,15 +105,11 @@ sz=${size[$choice]}
sz=${size[$choice]}
multiplier=${mult[$choice]}
-if [ "$multiplier" = "GB" ]; then
- lvalue=`echo $sz | cut -f1 -d"."`
- rvalue=`echo $sz | cut -f2 -d"."`
- lvalue=`expr $lvalue \* 1000`
- rvalue=`expr $rvalue \* 100`
- sz=`expr $lvalue + $rvalue`
-else
- sz=`echo $sz | cut -f1 -d"."`
-fi
+case "$multiplier" in
+ GB) sz=$(( ${sz%%.*} * 1000 + ${sz##*.} * 100 ));;
+ MB) sz=${sz%%.*};;
+ *) echo "Unknown capacity indicator: '$multiplier'"; exit 1;;
+esac
while true;
do
@@ -134,20 +117,31 @@ do
echo WARNING: All data on your USB storage will be lost.
echo Are you sure you want to install to
echo -n ${desc[$choice]}, $sz MB at $dev ?
- read -p "(y/n) " yn
+ read -p " (y/n) " yn
case $yn in
- y* | Y* )
+ [yY]* )
+ if [ ! -w $dev ]; then
+ echo "Device $dev is not writable"
+ echo "Installation aborted"
+ exit 1
+ fi
+ if [ $sz -lt $isz ]; then
+ echo "Image ($isz MB) is larger than the device ($sz MB)"
+ echo "Installation aborted"
+ exit 1
+ fi
break ;;
[nN]* )
echo "Installation aborted"
exit 0 ;;
* )
- echo Invalid choice.. Exiting ;exit 0;;
+ echo Invalid choice.. Exiting
+ exit 0 ;;
esac
done
# Ensure we have things unmounted
-umount -f $s0bdev
+umount -f $s0bdev > /dev/null 2>&1
# Install fdisk table with Solaris using entire disk, default VTOC
fdisk -B $dev
@@ -155,10 +149,10 @@ fdisk -B $dev
# Now create root partition. We want to find number of cylinders in backup
# partition from label created by fdisk -B and then generate root partition
# using whole disk minus cylinder 1
-acyls=`prtvtoc $dev | grep accessible | awk '{ print $2 }'`
-cyls=`expr ${acyls} - 1`
+acyls=$(prtvtoc $dev | awk '/accessible/{print $2}')
+cyls=$((acyls - 1))
format -e $dev >/dev/null <<EOF
-pa
+partition
0
root
wm
@@ -169,18 +163,66 @@ y
y
EOF
-# Copy image to USB. 16k blocks seem to be about as fast as anything
-echo "Copying image to USB device"
-time dd if=$img of=$s0cdev bs=16384
+# Copy image to USB.
+echo "Copying and verifying image to USB device"
+SECONDS=0
+# For now, copy in 16k chunks, 4MB at a time
+# NOTE: To avoid problems, cmb should be >= 1 and bs should evenly
+# divide into csz.
+bs=$((16 << 10))
+cmb=4
+
+csz=$((cmb << 20))
+bcnt=$((csz / bs))
+icnt=$((isz / cmb))
+
+maxt=3
+i=0
+retries=0
+
+while [[ $i -le $icnt ]]; do
+ tries=0
+ pcnt="($((i * 100 / icnt))%)"
+ s=$((i * bcnt))
+
+ echo -ne "R $i / $icnt $pcnt \\r"
+ imgsum=$(dd bs=$bs count=$bcnt conv=sync \
+ iseek=$s if=$img 2>/dev/null | md5sum)
+ [[ $? -ne 0 ]] && { echo Read from image failed. ; exit 1; }
+
+ while [[ $((tries++)) -lt $maxt ]]; do
+ echo -ne "W $i / $icnt $pcnt \\r"
+ recs=$(dd bs=$bs count=$bcnt conv=sync iseek=$s oseek=$s \
+ if=$img of=$s0cdev 2>&1 | awk -F+ '/records out/{print $1}')
+ [[ $? -ne 0 ]] && { echo Write to device failed. ; exit 1; }
+
+ echo -ne "V $i / $icnt $pcnt \\r"
+ devsum=$(dd bs=$bs count=$recs iseek=$s if=$s0cdev 2>/dev/null | md5sum)
+ [[ $? -ne 0 ]] && { echo Read from device failed. ; exit 1; }
+
+ [[ "$imgsum" = "$devsum" ]] && break;
+ done
+ [[ $tries -gt 1 ]] && ((retries++))
+
+ if [[ $tries -gt $maxt ]]; then
+ echo "Verification failed after $maxt attempts on block $i"
+ exit 1
+ fi
+
+ ((i++))
+done
+
+speed="$((isz / SECONDS)).$((isz * 10 / SECONDS % 10))MB/s"
+echo "Finished $isz MB in $SECONDS seconds ($speed)"
+echo "$retries block(s) re-written due to verification failure"
# Mount image
mnt=/tmp/usb.$$
mkdir $mnt
-mount $s0bdev $mnt
+mount -o ro $s0bdev $mnt
# Install grub stages to usb
echo Installing grub to USB device $s0cdev
installgrub -mf $mnt/boot/grub/stage1 $mnt/boot/grub/stage2 $s0cdev > /dev/null
umount $mnt
rmdir $mnt
echo "Completed copy to USB"
-