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"
-

Reply via email to