diff --git a/build_image.sh b/build_image.sh index 251a159240..06005372db 100755 --- a/build_image.sh +++ b/build_image.sh @@ -148,7 +148,7 @@ if [ ! -e /etc/mtab ]; then sudo touch /etc/mtab fi UUID=`uuidgen` -DISK_LABEL=C-$CHROMEOS_VERSION_STRING +DISK_LABEL=C-ROOT LOOP_DEV=`sudo losetup -f` sudo losetup "$LOOP_DEV" "$ROOT_FS_IMG" sudo mkfs.ext3 "$LOOP_DEV" diff --git a/file_copy.py b/file_copy.py new file mode 100755 index 0000000000..33a693b2f9 --- /dev/null +++ b/file_copy.py @@ -0,0 +1,100 @@ +#!/usr/bin/env python + +# This program operates much like dd, but with two important differences: +# 1. Many features lacking +# 2. seek_bytes= param can specify seek offset in bytes, not block size + +import os +import sys +import time + +def parseNumber(numstr): + if numstr.endswith("GB"): + return int(numstr[:-2]) * 1000 * 1000 * 1000 + if numstr.endswith("MB"): + return int(numstr[:-2]) * 1000 * 1000 + if numstr.endswith("kB"): + return int(numstr[:-2]) * 1000 + if numstr.endswith("G"): + return int(numstr[:-1]) * 1024 * 1024 * 1024 + if numstr.endswith("M"): + return int(numstr[:-1]) * 1024 * 1024 + if numstr.endswith("K"): + return int(numstr[:-1]) * 1024 + if numstr.endswith("b"): + return int(numstr[:-1]) * 512 + if numstr.endswith("w"): + return int(numstr[:-1]) * 2 + if numstr.endswith("c"): + return int(numstr[:-1]) + if not numstr.isdigit(): + print >> sys.stderr, "Don't know how to parse number", numstr + sys.exit(1) + return int(numstr) + +def main(argv): + arg_if = "" + arg_of = "" + arg_bs = 512 + arg_seek = -1 + arg_seek_bytes = -1 + + for i in argv: + if i.startswith("if="): + arg_if=i[3:] + elif i.startswith("of="): + arg_of=i[3:] + elif i.startswith("bs="): + arg_bs=parseNumber(i[3:]) + elif i.startswith("seek="): + arg_seek=int(i[5:]) + elif i.startswith("seek_bytes="): + arg_seek_bytes=parseNumber(i[11:]) + + if arg_seek >= 0 and arg_seek_bytes >= 0: + print >> sys.stderr, "you can't specify seek= and seek_bytes=" + sys.exit(1) + + seek_bytes = 0 + if arg_seek >= 0: + seek_bytes = arg_seek * arg_bs + elif arg_seek_bytes >= 0: + seek_bytes = arg_seek_bytes + + if_fd = 0 + of_fd = 1 + if len(arg_if) != 0: + print >> sys.stderr, "opening for read", arg_if + if_fd = os.open(arg_if, os.O_RDONLY) + if len(arg_of) != 0: + print >> sys.stderr, "opening for write", arg_of + of_fd = os.open(arg_of, os.O_WRONLY | os.O_TRUNC | os.O_CREAT) + + if arg_seek_bytes > 0: + print >> sys.stderr, "seeking to", seek_bytes, "bytes in output file" + os.lseek(of_fd, seek_bytes, os.SEEK_SET) + + bytes_copied = 0 + + t1 = time.time() + + buf = os.read(if_fd, arg_bs) + while len(buf) > 0: + bytes_written = 0 + while bytes_written < len(buf): + bytes_written += os.write(of_fd, buf[bytes_written:]) + bytes_copied += bytes_written + buf = os.read(if_fd, arg_bs) + + t2 = time.time() + + os.close(if_fd) + os.close(of_fd) + + # print timing info + print >> sys.stderr, 'copy %d bytes took %0.3f s' % (bytes_copied, t2 - t1) + print >> sys.stderr, 'speed: %0.1f MB/s' % \ + ((bytes_copied / 1000000) / (t2 - t1)) + +if __name__ == '__main__': + main(sys.argv) diff --git a/image_to_usb.sh b/image_to_usb.sh index 83b31e9ad6..660575369c 100755 --- a/image_to_usb.sh +++ b/image_to_usb.sh @@ -45,6 +45,10 @@ set -e FLAGS_from=`eval readlink -f $FLAGS_from` FLAGS_to=`eval readlink -f $FLAGS_to` +function do_cleanup { + sudo losetup -d "$LOOP_DEV" +} + # Copy MBR and rootfs to output image if [ -b "$FLAGS_to" ] then @@ -65,15 +69,40 @@ then fi fi - STATE_PART="$FLAGS_to"1 - ROOT_PART="$FLAGS_to"3 + echo "attempting to unmount any mounts on the USB device" + for i in "$FLAGS_to"* + do + ! sudo umount "$i" + done + sleep 3 + + PART_SIZE=$(stat -c%s "${FLAGS_from}/rootfs.image") # Bytes - sudo dd if="${FLAGS_from}/mbr.image" of="$FLAGS_to" + echo "Copying root fs..." + sudo ./file_copy.py if="${FLAGS_from}/rootfs.image" of="$FLAGS_to" bs=4M \ + seek_bytes=$(( ($PART_SIZE * 2) + 512 )) + + # Set up loop device + LOOP_DEV=$(sudo losetup -f) + if [ -z "$LOOP_DEV" ] + then + echo "No free loop device. Free up a loop device or reboot. exiting." + exit 1 + fi + + trap do_cleanup EXIT + + echo "Creating stateful partition..." + sudo losetup -o 512 "$LOOP_DEV" "$FLAGS_to" + sudo mkfs.ext3 -F -b 4096 -L C-STATE "$LOOP_DEV" $(( $PART_SIZE / 4096 )) sync - sudo partprobe "$FLAGS_to" + sudo losetup -d "$LOOP_DEV" sync - sudo dd if="${FLAGS_from}/rootfs.image" of="$ROOT_PART" bs=4M - sudo mkfs.ext3 -F -L C-STATE "$STATE_PART" + + trap - EXIT + + echo "Copying MBR..." + sudo ./file_copy.py if="${FLAGS_from}/mbr.image" of="$FLAGS_to" sync echo "Done." else