Guest User

Untitled

a guest
Jul 19th, 2018
164
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 28.76 KB | None | 0 0
  1. #!/bin/bash
  2. # Convert a live CD iso so that it's bootable off of a USB stick
  3. # Copyright 2007 Red Hat, Inc.
  4. # Jeremy Katz <katzj@redhat.com>
  5. #
  6. # overlay/persistence enhancements by Douglas McClendon <dmc@viros.org>
  7. # GPT+MBR hybrid enhancements by Stewart Adam <s.adam@diffingo.com>
  8. #
  9. # This program is free software; you can redistribute it and/or modify
  10. # it under the terms of the GNU General Public License as published by
  11. # the Free Software Foundation; version 2 of the License.
  12. #
  13. # This program is distributed in the hope that it will be useful,
  14. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  15. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  16. # GNU Library General Public License for more details.
  17. #
  18. # You should have received a copy of the GNU General Public License
  19. # along with this program; if not, write to the Free Software
  20. # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  21.  
  22.  
  23. export PATH=/sbin:/usr/sbin:$PATH
  24.  
  25. usage() {
  26. echo "$0 [--timeout <time>] [--totaltimeout <time>] [--format] [--reset-mbr] [--noverify] [--overlay-size-mb <size>] [--home-size-mb <size>] [--unencrypted-home] [--skipcopy] [--efi] <isopath> <usbstick device>"
  27. exit 1
  28. }
  29.  
  30. cleanup() {
  31. sleep 2
  32. [ -d "$CDMNT" ] && umount $CDMNT && rmdir $CDMNT
  33. [ -d "$USBMNT" ] && umount $USBMNT && rmdir $USBMNT
  34. }
  35.  
  36. exitclean() {
  37. echo "Cleaning up to exit..."
  38. cleanup
  39. exit 1
  40. }
  41.  
  42. isdevloop() {
  43. [ x"${1#/dev/loop}" != x"$1" ]
  44. }
  45.  
  46. getdisk() {
  47. DEV=$1
  48.  
  49. if isdevloop "$DEV"; then
  50. device="$DEV"
  51. return
  52. fi
  53.  
  54. p=$(udevadm info -q path -n $DEV)
  55. if [ -e /sys/$p/device ]; then
  56. device=$(basename /sys/$p)
  57. else
  58. device=$(basename $(readlink -f /sys/$p/../))
  59. fi
  60. if [ ! -e /sys/block/$device -o ! -e /dev/$device ]; then
  61. echo "Error finding block device of $DEV. Aborting!"
  62. exitclean
  63. fi
  64.  
  65. device="/dev/$device"
  66. # FIXME: weird dev names could mess this up I guess
  67. p=/dev/$(basename $p)
  68. partnum=${p##$device}
  69. }
  70.  
  71. getpartition() {
  72. DEV=$1
  73. pa=$( < /proc/partitions )
  74. pa=${pa##*$DEV}
  75. partnum=${pa%% *}
  76. }
  77.  
  78. resetMBR() {
  79. if isdevloop "$DEV"; then
  80. return
  81. fi
  82. getdisk $1
  83. # if efi, we need to use the hybrid MBR
  84. if [ -n "$efi" ]; then
  85. if [ -f /usr/lib/syslinux/gptmbr.bin ]; then
  86. gptmbr='/usr/lib/syslinux/gptmbr.bin'
  87. elif [ -f /usr/share/syslinux/gptmbr.bin ]; then
  88. gptmbr='/usr/share/syslinux/gptmbr.bin'
  89. else
  90. echo "Could not find gptmbr.bin (syslinux)"
  91. exitclean
  92. fi
  93. # our magic number is LBA-2, offset 16 - (512+512+16)/$bs
  94. dd if=$device bs=16 skip=65 count=1 | cat $gptmbr - > $device
  95. else
  96. if [ -f /usr/lib/syslinux/mbr.bin ]; then
  97. cat /usr/lib/syslinux/mbr.bin > $device
  98. elif [ -f /usr/share/syslinux/mbr.bin ]; then
  99. cat /usr/share/syslinux/mbr.bin > $device
  100. else
  101. echo "Could not find mbr.bin (syslinux)"
  102. exitclean
  103. fi
  104. fi
  105. }
  106.  
  107. checkMBR() {
  108. if isdevloop "$DEV"; then
  109. return 0
  110. fi
  111. getdisk $1
  112.  
  113. bs=$(mktemp /tmp/bs.XXXXXX)
  114. dd if=$device of=$bs bs=512 count=1 2>/dev/null || exit 2
  115.  
  116. mbrword=$(hexdump -n 2 $bs |head -n 1|awk {'print $2;'})
  117. rm -f $bs
  118. if [ "$mbrword" = "0000" ]; then
  119. echo "MBR appears to be blank."
  120. echo "Do you want to replace the MBR on this device?"
  121. echo "Press Enter to continue or ctrl-c to abort"
  122. read
  123. resetMBR $1
  124. fi
  125.  
  126. return 0
  127. }
  128.  
  129. checkPartActive() {
  130. dev=$1
  131. getdisk $dev
  132.  
  133. # if we're installing to whole-disk and not a partition, then we
  134. # don't need to worry about being active
  135. if [ "$dev" = "$device" ]; then
  136. return
  137. fi
  138. if isdevloop "$DEV"; then
  139. return
  140. fi
  141.  
  142. if [ "$(/sbin/fdisk -l $device 2>/dev/null |grep $dev |awk {'print $2;'})" != "*" ]; then
  143. echo "Partition isn't marked bootable!"
  144. echo "You can mark the partition as bootable with "
  145. echo " # /sbin/parted $device"
  146. echo " (parted) toggle N boot"
  147. echo " (parted) quit"
  148. exitclean
  149. fi
  150. }
  151.  
  152. checkLVM() {
  153. dev=$1
  154.  
  155. if [ -x /sbin/pvs -a \
  156. "$(/sbin/pvs -o vg_name --noheadings $dev* 2>/dev/null)" ]; then
  157. echo "Device, $dev, contains a volume group and cannot be formated!"
  158. echo "You can remove the volume group using vgremove."
  159. exitclean
  160. fi
  161. return 0
  162. }
  163.  
  164. createGPTLayout() {
  165. dev=$1
  166. getdisk $dev
  167.  
  168. echo "WARNING: THIS WILL DESTROY ANY DATA ON $device!!!"
  169. echo "Press Enter to continue or ctrl-c to abort"
  170. read
  171. umount ${device}* &> /dev/null
  172. /sbin/parted --script $device mklabel gpt
  173. partinfo=$(LC_ALL=C /sbin/parted --script -m $device "unit b print" |grep ^$device:)
  174. size=$(echo $partinfo |cut -d : -f 2 |sed -e 's/B$//')
  175. /sbin/parted --script $device unit b mkpart '"EFI System Partition"' fat32 17408 $(($size - 17408)) set 1 boot on
  176. # Sometimes automount can be _really_ annoying.
  177. echo "Waiting for devices to settle..."
  178. /sbin/udevadm settle
  179. sleep 5
  180. getpartition ${device#/dev/}
  181. USBDEV=${device}${partnum}
  182. umount $USBDEV &> /dev/null
  183. /sbin/mkdosfs -n LIVE $USBDEV
  184. USBLABEL="UUID=$(/sbin/blkid -s UUID -o value $USBDEV)"
  185. }
  186.  
  187. createMSDOSLayout() {
  188. dev=$1
  189. getdisk $dev
  190.  
  191. echo "WARNING: THIS WILL DESTROY ANY DATA ON $device!!!"
  192. echo "Press Enter to continue or ctrl-c to abort"
  193. read
  194. umount ${device}* &> /dev/null
  195. /sbin/parted --script $device mklabel msdos
  196. partinfo=$(LC_ALL=C /sbin/parted --script -m $device "unit b print" |grep ^$device:)
  197. size=$(echo $partinfo |cut -d : -f 2 |sed -e 's/B$//')
  198. /sbin/parted --script $device unit b mkpart primary fat32 17408 $(($size - 17408)) set 1 boot on
  199. # Sometimes automount can be _really_ annoying.
  200. echo "Waiting for devices to settle..."
  201. /sbin/udevadm settle
  202. sleep 5
  203. if ! isdevloop "$DEV"; then
  204. getpartition ${device#/dev/}
  205. USBDEV=${device}${partnum}
  206. else
  207. USBDEV=${device}
  208. fi
  209. umount $USBDEV &> /dev/null
  210. /sbin/mkdosfs -n LIVE $USBDEV
  211. USBLABEL="UUID=$(/sbin/blkid -s UUID -o value $USBDEV)"
  212. }
  213.  
  214. createEXTFSLayout() {
  215. dev=$1
  216. getdisk $dev
  217.  
  218. echo "WARNING: THIS WILL DESTROY ANY DATA ON $device!!!"
  219. echo "Press Enter to continue or ctrl-c to abort"
  220. read
  221. umount ${device}* &> /dev/null
  222. /sbin/parted --script $device mklabel msdos
  223. partinfo=$(LC_ALL=C /sbin/parted --script -m $device "unit b print" |grep ^$device:)
  224. size=$(echo $partinfo |cut -d : -f 2 |sed -e 's/B$//')
  225. /sbin/parted --script $device unit b mkpart primary ext2 17408 $(($size - 17408)) set 1 boot on
  226. # Sometimes automount can be _really_ annoying.
  227. echo "Waiting for devices to settle..."
  228. /sbin/udevadm settle
  229. sleep 5
  230. getpartition ${device#/dev/}
  231. USBDEV=${device}${partnum}
  232. umount $USBDEV &> /dev/null
  233. /sbin/mkfs.ext4 -L LIVE $USBDEV
  234. USBLABEL="UUID=$(/sbin/blkid -s UUID -o value $USBDEV)"
  235. }
  236.  
  237. checkGPT() {
  238. dev=$1
  239. getdisk $dev
  240.  
  241. if [ "$(/sbin/fdisk -l $device 2>/dev/null |grep -c GPT)" -eq "0" ]; then
  242. echo "EFI boot requires a GPT partition table."
  243. echo "This can be done manually or you can run with --format"
  244. exitclean
  245. fi
  246.  
  247. partinfo=$(LC_ALL=C /sbin/parted --script -m $device "print" |grep ^$partnum:)
  248. volname=$(echo $partinfo |cut -d : -f 6)
  249. flags=$(echo $partinfo |cut -d : -f 7)
  250. if [ "$volname" != "EFI System Partition" ]; then
  251. echo "Partition name must be 'EFI System Partition'"
  252. echo "This can be set in parted or you can run with --reset-mbr"
  253. exitclean
  254. fi
  255. if [ "$(echo $flags |grep -c boot)" = "0" ]; then
  256. echo "Partition isn't marked bootable!"
  257. echo "You can mark the partition as bootable with "
  258. echo " # /sbin/parted $device"
  259. echo " (parted) toggle N boot"
  260. echo " (parted) quit"
  261. exitclean
  262. fi
  263. }
  264.  
  265. checkFilesystem() {
  266. dev=$1
  267.  
  268. USBFS=$(/sbin/blkid -s TYPE -o value $dev)
  269. if [ "$USBFS" != "vfat" ] && [ "$USBFS" != "msdos" ]; then
  270. if [ "$USBFS" != "ext2" ] && [ "$USBFS" != "ext3" ] && [ "$USBFS" != "ext4" ] && [ "$USBFS" != "btrfs" ]; then
  271. echo "USB filesystem must be vfat, ext[234] or btrfs"
  272. exitclean
  273. fi
  274. fi
  275.  
  276.  
  277. USBLABEL=$(/sbin/blkid -s UUID -o value $dev)
  278. if [ -n "$USBLABEL" ]; then
  279. USBLABEL="UUID=$USBLABEL"
  280. else
  281. USBLABEL=$(/sbin/blkid -s LABEL -o value $dev)
  282. if [ -n "$USBLABEL" ]; then
  283. USBLABEL="LABEL=$USBLABEL"
  284. else
  285. echo "Need to have a filesystem label or UUID for your USB device"
  286. if [ "$USBFS" = "vfat" -o "$USBFS" = "msdos" ]; then
  287. echo "Label can be set with /sbin/dosfslabel"
  288. elif [ "$USBFS" = "ext2" -o "$USBFS" = "ext3" -o "$USBFS" = "ext4" ]; then
  289. echo "Label can be set with /sbin/e2label"
  290. elif [ "$USBFS" = "btrfs" ]; then
  291. echo "Eventually you'll be able to use /sbin/btrfs filesystem label to add a label."
  292. fi
  293. exitclean
  294. fi
  295. fi
  296.  
  297. if [ "$USBFS" = "vfat" -o "$USBFS" = "msdos" ]; then
  298. mountopts="-o shortname=winnt,umask=0077"
  299. fi
  300. }
  301.  
  302. checkSyslinuxVersion() {
  303. if [ ! -x /usr/bin/syslinux ]; then
  304. echo "You need to have syslinux installed to run this script"
  305. exit 1
  306. fi
  307. if ! syslinux 2>&1 | grep -qe -d; then
  308. SYSLINUXPATH=""
  309. elif [ -n "$multi" ]; then
  310. SYSLINUXPATH="$LIVEOS/syslinux"
  311. else
  312. SYSLINUXPATH="syslinux"
  313. fi
  314. }
  315.  
  316. checkMounted() {
  317. dev=$1
  318. if grep -q "^$dev " /proc/mounts ; then
  319. echo "$dev is mounted, please unmount for safety"
  320. exitclean
  321. fi
  322. if grep -q "^$dev " /proc/swaps; then
  323. echo "$dev is in use as a swap device, please disable swap"
  324. exitclean
  325. fi
  326. }
  327.  
  328. checkint() {
  329. if ! test $1 -gt 0 2>/dev/null ; then
  330. usage
  331. fi
  332. }
  333.  
  334. if [ $(id -u) != 0 ]; then
  335. echo "You need to be root to run this script"
  336. exit 1
  337. fi
  338.  
  339. detectisotype() {
  340. if [ -e $CDMNT/LiveOS/squashfs.img ]; then
  341. isotype=live
  342. return
  343. fi
  344. if [ -e $CDMNT/images/install.img ]; then
  345. if [ -e $CDMNT/Packages ]; then
  346. isotype=installer
  347. return
  348. else
  349. isotype=netinst
  350. return
  351. fi
  352. fi
  353. echo "ERROR: $ISO does not appear to be a Live image or DVD installer."
  354. exitclean
  355. }
  356.  
  357. cp_p() {
  358. strace -q -ewrite cp -- "${1}" "${2}" 2>&1 \
  359. | awk '{
  360. count += $NF
  361. if (count % 10 == 0) {
  362. percent = count / total_size * 100
  363. printf "%3d%% [", percent
  364. for (i=0;i<=percent;i++)
  365. printf "="
  366. printf ">"
  367. for (i=percent;i<100;i++)
  368. printf " "
  369. printf "]\r"
  370. }
  371. }
  372. END { print "" }' total_size=$(stat -c '%s' "${1}") count=0
  373. }
  374.  
  375. copyFile() {
  376. if [ -x /usr/bin/gvfs-copy ]; then
  377. gvfs-copy -p "$1" "$2"
  378. return
  379. fi
  380. if [ -x /usr/bin/strace -a -x /bin/awk ]; then
  381. cp_p "$1" "$2"
  382. return
  383. fi
  384. cp "$1" "$2"
  385. }
  386.  
  387. cryptedhome=1
  388. keephome=1
  389. homesizemb=0
  390. swapsizemb=0
  391. overlaysizemb=0
  392. isotype=
  393. LIVEOS=LiveOS
  394.  
  395. HOMEFILE="home.img"
  396. while [ $# -gt 2 ]; do
  397. case $1 in
  398. --overlay-size-mb)
  399. checkint $2
  400. overlaysizemb=$2
  401. shift
  402. ;;
  403. --home-size-mb)
  404. checkint $2
  405. homesizemb=$2
  406. shift
  407. ;;
  408. --swap-size-mb)
  409. checkint $2
  410. swapsizemb=$2
  411. shift
  412. ;;
  413. --crypted-home)
  414. cryptedhome=1
  415. ;;
  416. --unencrypted-home)
  417. cryptedhome=""
  418. ;;
  419. --delete-home)
  420. keephome=""
  421. ;;
  422. --noverify)
  423. noverify=1
  424. ;;
  425. --reset-mbr|--resetmbr)
  426. resetmbr=1
  427. ;;
  428. --efi|--mactel)
  429. efi=1
  430. ;;
  431. --format)
  432. format=1
  433. ;;
  434. --skipcopy)
  435. skipcopy=1
  436. ;;
  437. --xo)
  438. xo=1
  439. skipcompress=1
  440. ;;
  441. --xo-no-home)
  442. xonohome=1
  443. ;;
  444. --compress)
  445. skipcompress=""
  446. ;;
  447. --skipcompress)
  448. skipcompress=1
  449. ;;
  450. --extra-kernel-args)
  451. kernelargs=$2
  452. shift
  453. ;;
  454. --force)
  455. force=1
  456. ;;
  457. --livedir)
  458. LIVEOS=$2
  459. shift
  460. ;;
  461. --multi)
  462. multi=1
  463. ;;
  464. --timeout)
  465. checkint $2
  466. timeout=$2
  467. shift
  468. ;;
  469. --totaltimeout)
  470. checkint $2
  471. totaltimeout=$2
  472. shift
  473. ;;
  474. *)
  475. echo "invalid arg -- $1"
  476. usage
  477. ;;
  478. esac
  479. shift
  480. done
  481.  
  482. ISO=$(readlink -f "$1")
  483. USBDEV=$(readlink -f "$2")
  484.  
  485. if [ -z "$ISO" ]; then
  486. usage
  487. fi
  488.  
  489. if [ ! -b "$ISO" -a ! -f "$ISO" ]; then
  490. usage
  491. fi
  492.  
  493. # FIXME: If --format is given, we shouldn't care and just use /dev/foo1
  494. if [ -z "$USBDEV" -o ! -b "$USBDEV" ]; then
  495. usage
  496. fi
  497.  
  498. if [ -z "$noverify" ]; then
  499. # verify the image
  500. echo "Verifying image..."
  501. checkisomd5 --verbose "$ISO"
  502. if [ $? -ne 0 ]; then
  503. echo "Are you SURE you want to continue?"
  504. echo "Press Enter to continue or ctrl-c to abort"
  505. read
  506. fi
  507. fi
  508.  
  509. #checkFilesystem $USBDEV
  510. # do some basic sanity checks.
  511. checkMounted $USBDEV
  512. if [ -n "$format" -a -z "$skipcopy" ]; then
  513. checkLVM $USBDEV
  514. # checks for a valid filesystem
  515. if [ -n "$efi" ]; then
  516. createGPTLayout $USBDEV
  517. elif [ "$USBFS" == "vfat" -o "$USBFS" == "msdos" ]; then
  518. createMSDOSLayout $USBDEV
  519. else
  520. createEXTFSLayout $USBDEV
  521. fi
  522. fi
  523.  
  524. checkFilesystem $USBDEV
  525. if [ -n "$efi" ]; then
  526. checkGPT $USBDEV
  527. fi
  528.  
  529. checkSyslinuxVersion
  530. # Because we can't set boot flag for EFI Protective on msdos partition tables
  531. [ -z "$efi" ] && checkPartActive $USBDEV
  532. [ -n "$resetmbr" ] && resetMBR $USBDEV
  533. checkMBR $USBDEV
  534.  
  535.  
  536. if [ "$overlaysizemb" -gt 0 -a "$USBFS" = "vfat" ]; then
  537. if [ "$overlaysizemb" -gt 2047 ]; then
  538. echo "Can't have an overlay of 2048MB or greater on VFAT"
  539. exitclean
  540. fi
  541. fi
  542.  
  543. if [ "$homesizemb" -gt 0 -a "$USBFS" = "vfat" ]; then
  544. if [ "$homesizemb" -gt 2047 ]; then
  545. echo "Can't have a home overlay greater than 2048MB on VFAT"
  546. exitclean
  547. fi
  548. fi
  549.  
  550. if [ "$swapsizemb" -gt 0 -a "$USBFS" = "vfat" ]; then
  551. if [ "$swapsizemb" -gt 2047 ]; then
  552. echo "Can't have a swap file greater than 2048MB on VFAT"
  553. exitclean
  554. fi
  555. fi
  556.  
  557. # FIXME: would be better if we had better mountpoints
  558. CDMNT=$(mktemp -d /media/cdtmp.XXXXXX)
  559. mount -o loop,ro "$ISO" $CDMNT || exitclean
  560. USBMNT=$(mktemp -d /media/usbdev.XXXXXX)
  561. mount $mountopts $USBDEV $USBMNT || exitclean
  562.  
  563. trap exitclean SIGINT SIGTERM
  564.  
  565. detectisotype
  566.  
  567. if [ -f "$USBMNT/$LIVEOS/$HOMEFILE" -a -n "$keephome" -a "$homesizemb" -gt 0 ]; then
  568. echo "ERROR: Requested keeping existing /home and specified a size for /home"
  569. echo "Please either don't specify a size or specify --delete-home"
  570. exitclean
  571. fi
  572.  
  573. if [ -n "$efi" -a ! -d $CDMNT/EFI/boot ]; then
  574. echo "ERROR: This live image does not support EFI booting"
  575. exitclean
  576. fi
  577.  
  578. # let's try to make sure there's enough room on the stick
  579. if [ -d $CDMNT/LiveOS ]; then
  580. check=$CDMNT/LiveOS
  581. else
  582. check=$CDMNT
  583. fi
  584. if [[ -d $USBMNT/$LIVEOS ]]; then
  585. tbd=($(du -B 1M $USBMNT/$LIVEOS))
  586. [[ -s $USBMNT/$LIVEOS/$HOMEFILE ]] && \
  587. homesize=($(du -B 1M $USBMNT/$LIVEOS/$HOMEFILE))
  588. ((homesize > 0)) && [[ -n $keephome ]] && ((tbd -= homesize))
  589. else
  590. tbd=0
  591. fi
  592. targets="$USBMNT/$SYSLINUXPATH"
  593. if [[ -n $efi ]]; then
  594. targets+=" $USBMNT/EFI/boot"
  595. fi
  596. duTable=($(du -c -B 1M $targets 2> /dev/null))
  597. ((tbd += ${duTable[*]: -2:1}))
  598.  
  599. sources="$CDMNT/isolinux"
  600. [[ -n $efi ]] && sources+=" $CDMNT/EFI/boot"
  601. if [[ -n $skipcompress ]]; then
  602. if [[ -s $CDMNT/LiveOS/squashfs.img ]]; then
  603. if mount -o loop $CDMNT/LiveOS/squashfs.img $CDMNT; then
  604. livesize=($(du -B 1M --apparent-size $CDMNT/LiveOS/ext3fs.img))
  605. umount $CDMNT
  606. else
  607. echo "WARNING: --skipcompress or --xo was specified but the currently"
  608. echo "running kernel can not mount the squashfs from the ISO file to extract"
  609. echo "it. The compressed squashfs will be copied to the USB stick."
  610. skipcompress=""
  611. fi
  612. fi
  613. duTable=($(du -c -B 1M $sources 2> /dev/null))
  614. ((livesize += ${duTable[*]: -2:1}))
  615. else
  616. sources+=" $check/osmin.img $check/squashfs.img"
  617. duTable=($(du -c -B 1M $sources 2> /dev/null))
  618. livesize=${duTable[*]: -2:1}
  619. fi
  620.  
  621. freespace=($(df -B 1M --total $USBDEV))
  622. freespace=${freespace[*]: -2:1}
  623.  
  624. if [ "$isotype" = "live" ]; then
  625. tba=$((overlaysizemb + homesizemb + livesize + swapsizemb))
  626. if ((tba > freespace + tbd)); then
  627. needed=$((tba - freespace - tbd))
  628. printf "\n The live image + overlay, home, & swap space, if requested,
  629. \r will NOT fit in the space available on the target device.\n
  630. \r + Size of live image: %10s MiB\n" $livesize
  631. (($overlaysizemb > 0)) && \
  632. printf " + Overlay size: %16s\n" $overlaysizemb
  633. (($homesizemb > 0)) && \
  634. printf " + Home directory size: %9s\n" $homesizemb
  635. (($swapsizemb > 0)) && \
  636. printf " + Swap overlay size: %11s\n" $swapsizemb
  637. printf " = Total requested space: %6s MiB\n" $tba
  638. printf " - Space available: %12s\n" $((freespace + tbd))
  639. printf " ==============================\n"
  640. printf " Space needed: %15s MiB\n\n" $needed
  641. printf " To fit the installation on this device,
  642. \r free space on the target, or decrease the
  643. \r requested size total by: %s MiB\n\n" $needed
  644. exitclean
  645. fi
  646. fi
  647.  
  648. # Verify available space for DVD installer
  649. if [ "$isotype" = "installer" ]; then
  650. isosize=$(du -s -B 1M $ISO | awk {'print $1;'})
  651. installimgsize=$(du -s -B 1M $CDMNT/images/install.img | awk {'print $1;'})
  652. tbd=0
  653. if [ -e $USBMNT/images/install.img ]; then
  654. tbd=$(du -s -B 1M $USBMNT/images/install.img | awk {'print $1;'})
  655. fi
  656. if [ -e $USBMNT/$(basename $ISO) ]; then
  657. tbd=$(($tbd + $(du -s -B 1M $USBMNT/$(basename $ISO) | awk {'print $1;'})))
  658. fi
  659. echo "Size of DVD image: $isosize"
  660. echo "Size of install.img: $installimgsize"
  661. echo "Available space: $((freespace + tbd))"
  662. if (( ((isosize + installimgsize)) > ((freespace + tbd)) )); then
  663. echo "ERROR: Unable to fit DVD image + install.img on available space on USB stick"
  664. exitclean
  665. fi
  666. fi
  667.  
  668. if [ -z "$skipcopy" ] && [ "$isotype" = "live" ]; then
  669. if [ -d $USBMNT/$LIVEOS -a -z "$force" ]; then
  670. echo "Already set up as live image."
  671. if [ -z "$keephome" -a -e $USBMNT/$LIVEOS/$HOMEFILE ]; then
  672. echo "WARNING: Persistent /home will be deleted!!!"
  673. echo "Press Enter to continue or ctrl-c to abort"
  674. read
  675. else
  676. echo "Deleting old OS in fifteen seconds..."
  677. sleep 15
  678.  
  679. [ -e "$USBMNT/$LIVEOS/$HOMEFILE" -a -n "$keephome" ] && mv $USBMNT/$LIVEOS/$HOMEFILE $USBMNT/$HOMEFILE
  680. fi
  681.  
  682. rm -rf $USBMNT/$LIVEOS
  683. fi
  684. fi
  685.  
  686. # Bootloader is always reconfigured, so keep these out of the if skipcopy stuff.
  687. [ ! -d $USBMNT/$SYSLINUXPATH ] && mkdir -p $USBMNT/$SYSLINUXPATH
  688. [ -n "$efi" -a ! -d $USBMNT/EFI/boot ] && mkdir -p $USBMNT/EFI/boot
  689.  
  690. # Live image copy
  691. set -o pipefail
  692. if [ "$isotype" = "live" -a -z "$skipcopy" ]; then
  693. echo "Copying live image to USB stick"
  694. [ ! -d $USBMNT/$LIVEOS ] && mkdir $USBMNT/$LIVEOS
  695. [ -n "$keephome" -a -f "$USBMNT/$HOMEFILE" ] && mv $USBMNT/$HOMEFILE $USBMNT/$LIVEOS/$HOMEFILE
  696. if [ -n "$skipcompress" -a -f $CDMNT/LiveOS/squashfs.img ]; then
  697. mount -o loop $CDMNT/LiveOS/squashfs.img $CDMNT || exitclean
  698. copyFile $CDMNT/LiveOS/ext3fs.img $USBMNT/$LIVEOS/ext3fs.img || {
  699. umount $CDMNT ; exitclean ; }
  700. umount $CDMNT
  701. elif [ -f $CDMNT/LiveOS/squashfs.img ]; then
  702. copyFile $CDMNT/LiveOS/squashfs.img $USBMNT/$LIVEOS/squashfs.img || exitclean
  703. elif [ -f $CDMNT/LiveOS/ext3fs.img ]; then
  704. copyFile $CDMNT/LiveOS/ext3fs.img $USBMNT/$LIVEOS/ext3fs.img || exitclean
  705. fi
  706. if [ -f $CDMNT/LiveOS/osmin.img ]; then
  707. copyFile $CDMNT/LiveOS/osmin.img $USBMNT/$LIVEOS/osmin.img || exitclean
  708. fi
  709. sync
  710. fi
  711.  
  712. # DVD installer copy
  713. if [ \( "$isotype" = "installer" -o "$isotype" = "netinst" \) -a -z "$skipcopy" ]; then
  714. echo "Copying DVD image to USB stick"
  715. mkdir -p $USBMNT/images/
  716. copyFile $CDMNT/images/install.img $USBMNT/images/install.img || exitclean
  717. if [ "$isotype" = "installer" ]; then
  718. cp $ISO $USBMNT/
  719. fi
  720. sync
  721. fi
  722.  
  723. cp $CDMNT/isolinux/* $USBMNT/$SYSLINUXPATH
  724. BOOTCONFIG=$USBMNT/$SYSLINUXPATH/isolinux.cfg
  725. # Set this to nothing so sed doesn't care
  726. BOOTCONFIG_EFI=
  727. if [ -n "$efi" ]; then
  728. cp $CDMNT/EFI/boot/* $USBMNT/EFI/boot
  729.  
  730. # this is a little ugly, but it gets the "interesting" named config file
  731. BOOTCONFIG_EFI=$USBMNT/EFI/boot/boot?*.conf
  732. rm -f $USBMNT/EFI/boot/grub.conf
  733. fi
  734.  
  735. echo "Updating boot config file"
  736. # adjust label and fstype
  737. if [ -n "$LANG" ]; then
  738. kernelargs="$kernelargs LANG=$LANG"
  739. fi
  740. sed -i -e "s/CDLABEL=[^ ]*/$USBLABEL/" -e "s/rootfstype=[^ ]*/rootfstype=$USBFS/" -e "s/LABEL=[^ ]*/$USBLABEL/" $BOOTCONFIG $BOOTCONFIG_EFI
  741. if [ -n "$kernelargs" ]; then
  742. sed -i -e "s/liveimg/liveimg ${kernelargs}/" $BOOTCONFIG $BOOTCONFIG_EFI
  743. fi
  744. if [ "$LIVEOS" != "LiveOS" ]; then
  745. sed -i -e "s;liveimg;liveimg live_dir=$LIVEOS;" $BOOTCONFIG $BOOTCONFIG_EFI
  746. fi
  747.  
  748. # DVD Installer
  749. if [ "$isotype" = "installer" ]; then
  750. sed -i -e "s;initrd=initrd.img;initrd=initrd.img ${LANG:+LANG=$LANG} repo=hd:$USBLABEL:/;g" $BOOTCONFIG $BOOTCONFIG_EFI
  751. sed -i -e "s;stage2=\S*;;g" $BOOTCONFIG $BOOTCONFIG_EFI
  752. fi
  753.  
  754. # DVD Installer for netinst
  755. if [ "$isotype" = "netinst" ]; then
  756. sed -i -e "s;stage2=\S*;stage2=hd:$USBLABEL:/images/install.img;g" $BOOTCONFIG $BOOTCONFIG_EFI
  757. fi
  758.  
  759. # Adjust the boot timeouts
  760. if [ -n "$timeout" ]; then
  761. sed -i -e "s/^timeout.*$/timeout\ $timeout/" $BOOTCONFIG
  762. fi
  763. if [ -n "$totaltimeout" ]; then
  764. sed -i -e "/^timeout.*$/a\totaltimeout\ $totaltimeout" $BOOTCONFIG
  765. fi
  766.  
  767. # Use repo if the .iso has the repository on it, otherwise use stage2 which
  768. # will default to using the network mirror
  769. if [ -e "$CDMNT/.discinfo" ]; then
  770. METHODSTR=repo
  771. else
  772. METHODSTR=stage2
  773. fi
  774.  
  775. if [ "$overlaysizemb" -gt 0 ]; then
  776. echo "Initializing persistent overlay file"
  777. OVERFILE="overlay-$( /sbin/blkid -s LABEL -o value $USBDEV )-$( /sbin/blkid -s UUID -o value $USBDEV )"
  778. if [ -z "$skipcopy" ]; then
  779. if [ "$USBFS" = "vfat" ]; then
  780. # vfat can't handle sparse files
  781. dd if=/dev/zero of=$USBMNT/$LIVEOS/$OVERFILE count=$overlaysizemb bs=1M
  782. else
  783. dd if=/dev/null of=$USBMNT/$LIVEOS/$OVERFILE count=1 bs=1M seek=$overlaysizemb
  784. fi
  785. fi
  786. sed -i -e "s/liveimg/liveimg overlay=${USBLABEL}/" $BOOTCONFIG $BOOTCONFIG_EFI
  787. sed -i -e "s/\ ro\ /\ rw\ /" $BOOTCONFIG $BOOTCONFIG_EFI
  788. fi
  789.  
  790. if [ "$swapsizemb" -gt 0 -a -z "$skipcopy" ]; then
  791. echo "Initializing swap file"
  792. dd if=/dev/zero of=$USBMNT/$LIVEOS/swap.img count=$swapsizemb bs=1M
  793. mkswap -f $USBMNT/$LIVEOS/swap.img
  794. fi
  795.  
  796. if [ "$homesizemb" -gt 0 -a -z "$skipcopy" ]; then
  797. echo "Initializing persistent /home"
  798. homesource=/dev/zero
  799. [ -n "$cryptedhome" ] && homesource=/dev/urandom
  800. if [ "$USBFS" = "vfat" ]; then
  801. # vfat can't handle sparse files
  802. dd if=${homesource} of=$USBMNT/$LIVEOS/$HOMEFILE count=$homesizemb bs=1M
  803. else
  804. dd if=/dev/null of=$USBMNT/$LIVEOS/$HOMEFILE count=1 bs=1M seek=$homesizemb
  805. fi
  806. if [ -n "$cryptedhome" ]; then
  807. loop=$(losetup -f)
  808. losetup $loop $USBMNT/$LIVEOS/$HOMEFILE
  809. setupworked=1
  810. until [ ${setupworked} == 0 ]; do
  811. echo "Encrypting persistent /home"
  812. cryptsetup luksFormat -y -q $loop
  813. setupworked=$?
  814. done
  815. setupworked=1
  816. until [ ${setupworked} == 0 ]; do
  817. echo "Please enter the password again to unlock the device"
  818. cryptsetup luksOpen $loop EncHomeFoo
  819. setupworked=$?
  820. done
  821. mke2fs -j /dev/mapper/EncHomeFoo
  822. tune2fs -c0 -i0 -ouser_xattr,acl /dev/mapper/EncHomeFoo
  823. sleep 2
  824. cryptsetup luksClose EncHomeFoo
  825. losetup -d $loop
  826. else
  827. echo "Formatting unencrypted /home"
  828. mke2fs -F -j $USBMNT/$LIVEOS/$HOMEFILE
  829. tune2fs -c0 -i0 -ouser_xattr,acl $USBMNT/$LIVEOS/$HOMEFILE
  830. fi
  831. fi
  832.  
  833. # create the forth files for booting on the XO if requested
  834. # we'd do this unconditionally, but you have to have a kernel that will
  835. # boot on the XO anyway.
  836. if [ -n "$xo" ]; then
  837. echo "Setting up /boot/olpc.fth file"
  838. args=$(grep "^ *append" $USBMNT/$SYSLINUXPATH/isolinux.cfg |head -n1 |sed -e 's/.*initrd=[^ ]*//')
  839. if [ -z "$xonohome" -a ! -f $USBMNT/$LIVEOS/$HOMEFILE ]; then
  840. args="$args persistenthome=mtd0"
  841. fi
  842. args="$args reset_overlay"
  843. xosyspath=$(echo $SYSLINUXPATH | sed -e 's;/;\\;')
  844. if [ ! -d $USBMNT/boot ]; then
  845. mkdir -p $USBMNT/boot
  846. fi
  847. cat > $USBMNT/boot/olpc.fth <<EOF
  848. \ Boot script for USB boot
  849. hex rom-pa fffc7 + 4 \$number drop h# 2e19 < [if]
  850. patch 2drop erase claim-params
  851. : high-ramdisk ( -- )
  852. cv-load-ramdisk
  853. h# 22c +lp l@ 1+ memory-limit umin /ramdisk - ffff.f000 and ( new-ramdisk-adr )
  854. ramdisk-adr over /ramdisk move ( new-ramdisk-adr )
  855. to ramdisk-adr
  856. ;
  857. ' high-ramdisk to load-ramdisk
  858. [then]
  859.  
  860. : set-bootpath-dev ( -- )
  861. " /chosen" find-package if ( phandle )
  862. " bootpath" rot get-package-property 0= if ( propval$ )
  863. get-encoded-string ( bootpath$ )
  864. [char] \ left-parse-string 2nip ( dn$ )
  865. dn-buf place ( )
  866. then
  867. then
  868.  
  869. " /sd" dn-buf count sindex 0>= if
  870. " sd:"
  871. else
  872. " u:"
  873. then
  874. " BOOTPATHDEV" \$set-macro
  875. ;
  876.  
  877. set-bootpath-dev
  878. " $args" to boot-file
  879. " \${BOOTPATHDEV}$xosyspath\initrd0.img" expand$ to ramdisk
  880. " \${BOOTPATHDEV}$xosyspath\vmlinuz0" expand$ to boot-device
  881. unfreeze
  882. boot
  883. EOF
  884.  
  885. fi
  886.  
  887. if [ -z "$multi" ]; then
  888. echo "Installing boot loader"
  889. if [ -n "$efi" ]; then
  890. # replace the ia32 hack
  891. if [ -f "$USBMNT/EFI/boot/boot.conf" ]; then
  892. cp -f $USBMNT/EFI/boot/bootia32.conf $USBMNT/EFI/boot/boot.conf
  893. fi
  894. fi
  895.  
  896. # this is a bit of a kludge, but syslinux doesn't guarantee the API for its com32 modules :/
  897. if [ -f $USBMNT/$SYSLINUXPATH/vesamenu.c32 -a -f /usr/share/syslinux/vesamenu.c32 ]; then
  898. cp /usr/share/syslinux/vesamenu.c32 $USBMNT/$SYSLINUXPATH/vesamenu.c32
  899. elif [ -f $USBMNT/$SYSLINUXPATH/vesamenu.c32 -a -f /usr/lib/syslinux/vesamenu.c32 ]; then
  900. cp /usr/lib/syslinux/vesamenu.c32 $USBMNT/$SYSLINUXPATH/vesamenu.c32
  901. elif [ -f $USBMNT/$SYSLINUXPATH/menu.c32 -a -f /usr/share/syslinux/menu.c32 ]; then
  902. cp /usr/share/syslinux/menu.c32 $USBMNT/$SYSLINUXPATH/menu.c32
  903. elif [ -f $USBMNT/$SYSLINUXPATH/menu.c32 -a -f /usr/lib/syslinux/menu.c32 ]; then
  904. cp /usr/lib/syslinux/menu.c32 $USBMNT/$SYSLINUXPATH/menu.c32
  905. fi
  906.  
  907. if [ "$USBFS" == "vfat" -o "$USBFS" == "msdos" ]; then
  908. # syslinux expects the config to be named syslinux.cfg
  909. # and has to run with the file system unmounted
  910. mv $USBMNT/$SYSLINUXPATH/isolinux.cfg $USBMNT/$SYSLINUXPATH/syslinux.cfg
  911. # deal with mtools complaining about ldlinux.sys
  912. if [ -f $USBMNT/$SYSLINUXPATH/ldlinux.sys ]; then
  913. rm -f $USBMNT/$SYSLINUXPATH/ldlinux.sys
  914. fi
  915. cleanup
  916. if [ -n "$SYSLINUXPATH" ]; then
  917. syslinux -d $SYSLINUXPATH $USBDEV
  918. else
  919. syslinux $USBDEV
  920. fi
  921. elif [ "$USBFS" == "ext2" -o "$USBFS" == "ext3" -o "$USBFS" == "ext4" -o "$USBFS" == "btrfs" ]; then
  922. # extlinux expects the config to be named extlinux.conf
  923. # and has to be run with the file system mounted
  924. mv $USBMNT/$SYSLINUXPATH/isolinux.cfg $USBMNT/$SYSLINUXPATH/extlinux.conf
  925. extlinux -i $USBMNT/$SYSLINUXPATH
  926. # Starting with syslinux 4 ldlinux.sys is used on all file systems.
  927. if [ -f "$USBMNT/$SYSLINUXPATH/extlinux.sys" ]; then
  928. chattr -i $USBMNT/$SYSLINUXPATH/extlinux.sys
  929. elif [ -f "$USBMNT/$SYSLINUXPATH/ldlinux.sys" ]; then
  930. chattr -i $USBMNT/$SYSLINUXPATH/ldlinux.sys
  931. fi
  932. cleanup
  933. fi
  934. else
  935. # we need to do some more config file tweaks for multi-image mode
  936. sed -i -e "s;kernel vm;kernel /$LIVEOS/syslinux/vm;" $USBMNT/$SYSLINUXPATH/isolinux.cfg
  937. sed -i -e "s;initrd=i;initrd=/$LIVEOS/syslinux/i;" $USBMNT/$SYSLINUXPATH/isolinux.cfg
  938. mv $USBMNT/$SYSLINUXPATH/isolinux.cfg $USBMNT/$SYSLINUXPATH/syslinux.cfg
  939. cleanup
  940. fi
  941.  
  942. echo "USB stick set up as live image!"
Add Comment
Please, Sign In to add comment