tools/livecd-iso-to-disk.sh | 248 ++++++++++++++++++++++++++++++--------------
1 file changed, 171 insertions(+), 77 deletions(-)
New commits:
commit d97c367698d6f43f6a354f7077cbda8373384427
Author: Brian C. Lane <bcl(a)redhat.com>
Date: Tue Feb 21 14:55:51 2012 -0800
livecd-iso-to-disk: create partition for iso
In Fedora 17 the installer runs from the squashfs.img on the install
media. This means that the installer environment doesn't have direct
access to the install media, and it cannot mount it.
In order to support writing DVD's to USB sticks we now need to create a
second partition just for the .iso image and direct the installer to it
using the repo=UUID=... command
This patch adds creating the 2nd partition if needed and also cleans up
some of the bootloader config editing code.
diff --git a/tools/livecd-iso-to-disk.sh b/tools/livecd-iso-to-disk.sh
index 2db2903..3ae88a2 100755
--- a/tools/livecd-iso-to-disk.sh
+++ b/tools/livecd-iso-to-disk.sh
@@ -1,7 +1,9 @@
#!/bin/bash
# Transfer a Live image so that it's bootable off of a USB/SD device.
-# Copyright 2007 Red Hat, Inc.
+# Copyright 2007-2012 Red Hat, Inc.
+#
# Jeremy Katz <katzj(a)redhat.com>
+# Brian C. Lane <bcl(a)redhat.com>
#
# overlay/persistence enhancements by Douglas McClendon <dmc(a)viros.org>
# GPT+MBR hybrid enhancements by Stewart Adam <s.adam(a)diffingo.com>
@@ -274,11 +276,14 @@ cleanup() {
sleep 2
[ -d "$SRCMNT" ] && umount $SRCMNT && rmdir $SRCMNT
[ -d "$TGTMNT" ] && umount $TGTMNT && rmdir $TGTMNT
+ if [ -n "$REPOMNT" ]; then
+ [ -d "$REPOMNT" ] && umount $REPOMNT && rmdir $REPOMNT
+ fi
}
exitclean() {
RETVAL=$?
- if [ -d "$SRCMNT" ] || [ -d "$TGTMNT" ];
+ if [ -d "$SRCMNT" ] || [ -d "$TGTMNT" ] || [ -n
"$REPOMNT" ];
then
[ "$RETVAL" = 0 ] || echo "Cleaning up to exit..."
cleanup
@@ -319,13 +324,6 @@ getdisk() {
partnum=${p##$device}
}
-getpartition() {
- DEV=$1
- pa=$( < /proc/partitions )
- pa=${pa##*$DEV}
- partnum=${pa%% *}
-}
-
resetMBR() {
if isdevloop "$DEV"; then
return
@@ -423,18 +421,47 @@ createGPTLayout() {
umount ${device}* &> /dev/null || :
wipefs -a ${device}
/sbin/parted --script $device mklabel gpt
- partinfo=$(LC_ALL=C /sbin/parted --script -m $device "unit b print" |grep
^$device:)
- size=$(echo $partinfo |cut -d : -f 2 |sed -e 's/B$//')
- /sbin/parted --script $device unit b mkpart '"EFI System
Partition"' fat32 1048576 $(($size - 1048576)) set 1 boot on
+ partinfo=$(LC_ALL=C /sbin/parted --script -m $device "unit MB print" |grep
^$device:)
+ dev_size=$(echo $partinfo |cut -d : -f 2 |sed -e 's/MB$//')
+
+ # Is a 2nd partition needed for package iso?
+ if [ -n "$packages" ]; then
+ src_size=$(du -s -B 1MB "$SRC" | awk {'print $1;'})
+ # iso size + 7% of slop for filesystem metadata
+ p2_size=$(($src_size * 107 / 100))
+ else
+ p2_size=0
+ fi
+ p1_size=$(($dev_size - 1 - $p2_size))
+
+ if [ $p1_size -le 0 ]; then
+ echo "Your device isn't big enough to hold $SRC"
+ echo "It is $(($p1_size * -1)) MB too small"
+ exitclean
+ fi
+ p1_start=1
+ p1_end=$(($p1_size + 1))
+ /sbin/parted -s $device u MB mkpart '"EFI System Partition"' fat32
$p1_start $p1_end set 1 boot on
+ if [ $p2_size -gt 0 ]; then
+ p2_start=$p1_end
+ p2_end=$(($p2_size + $p2_start))
+ /sbin/parted -s $device u MB mkpart '"LIVE REPO"' fat32
$p2_start $p2_end
+ fi
# Sometimes automount can be _really_ annoying.
echo "Waiting for devices to settle..."
/sbin/udevadm settle
sleep 5
- getpartition ${device#/dev/}
- TGTDEV=${device}${partnum}
+ TGTDEV=${device}1
umount $TGTDEV &> /dev/null || :
/sbin/mkdosfs -n LIVE $TGTDEV
TGTLABEL="UUID=$(/sbin/blkid -s UUID -o value $TGTDEV)"
+
+ if [ $p2_size -gt 0 ]; then
+ REPODEV=${device}2
+ umount $REPODEV &> /dev/null || :
+ /sbin/mkdosfs -n LIVE-REPO $REPODEV
+ REPOLABEL="UUID=$(/sbin/blkid -s UUID -o value $REPODEV)"
+ fi
}
createMSDOSLayout() {
@@ -447,22 +474,51 @@ createMSDOSLayout() {
umount ${device}* &> /dev/null || :
wipefs -a ${device}
/sbin/parted --script $device mklabel msdos
- partinfo=$(LC_ALL=C /sbin/parted --script -m $device "unit b print" |grep
^$device:)
- size=$(echo $partinfo |cut -d : -f 2 |sed -e 's/B$//')
- /sbin/parted --script $device unit b mkpart primary fat32 1048576 $(($size -
1048576)) set 1 boot on
+ partinfo=$(LC_ALL=C /sbin/parted --script -m $device "unit MB print" |grep
^$device:)
+ dev_size=$(echo $partinfo |cut -d : -f 2 |sed -e 's/MB$//')
+
+ # Is a 2nd partition needed for package iso?
+ if [ -n "$packages" ]; then
+ src_size=$(du -s -B 1MB "$SRC" | awk {'print $1;'})
+ # iso size + 7% of slop for filesystem metadata
+ p2_size=$(($src_size * 107 / 100))
+ else
+ p2_size=0
+ fi
+ p1_size=$(($dev_size - 1 - $p2_size))
+
+ if [ $p1_size -le 0 ]; then
+ echo "Your device isn't big enough to hold $SRC"
+ echo "It is $(($p1_size * -1)) MB too small"
+ exitclean
+ fi
+ p1_start=1
+ p1_end=$(($p1_size + 1))
+ /sbin/parted -s $device u MB mkpart primary fat32 $p1_start $p1_end set 1 boot on
+ if [ $p2_size -gt 0 ]; then
+ p2_start=$p1_end
+ p2_end=$(($p2_size + $p2_start))
+ /sbin/parted -s $device u MB mkpart primary fat32 $p2_start $p2_end
+ fi
# Sometimes automount can be _really_ annoying.
echo "Waiting for devices to settle..."
/sbin/udevadm settle
sleep 5
if ! isdevloop "$DEV"; then
- getpartition ${device#/dev/}
- TGTDEV=${device}${partnum}
+ TGTDEV=${device}1
else
TGTDEV=${device}
fi
umount $TGTDEV &> /dev/null || :
/sbin/mkdosfs -n LIVE $TGTDEV
TGTLABEL="UUID=$(/sbin/blkid -s UUID -o value $TGTDEV)"
+
+ if [ $p2_size -gt 0 ]; then
+ REPODEV=${device}2
+ umount $REPODEV &> /dev/null || :
+ /sbin/mkdosfs -n LIVE-REPO $REPODEV
+ REPOLABEL="UUID=$(/sbin/blkid -s UUID -o value $REPODEV)"
+ fi
}
createEXTFSLayout() {
@@ -474,25 +530,55 @@ createEXTFSLayout() {
read
umount ${device}* &> /dev/null || :
wipefs -a ${device}
- /sbin/parted --script $device mklabel msdos
- partinfo=$(LC_ALL=C /sbin/parted --script -m $device "unit b print" |grep
^$device:)
- size=$(echo $partinfo |cut -d : -f 2 |sed -e 's/B$//')
- /sbin/parted --script $device unit b mkpart primary ext2 1048576 $(($size - 1048576))
set 1 boot on
+ /sbin/parted -s $device mklabel msdos
+ partinfo=$(LC_ALL=C /sbin/parted -s -m $device "u MB print" |grep
^$device:)
+ dev_size=$(echo $partinfo |cut -d : -f 2 |sed -e 's/MB$//')
+
+ # Is a 2nd partition needed for package iso?
+ if [ -n "$packages" ]; then
+ src_size=$(du -s -B 1MB "$SRC" | awk {'print $1;'})
+ # iso size + 7% of slop for filesystem metadata
+ p2_size=$(($src_size * 107 / 100))
+ else
+ p2_size=0
+ fi
+ p1_size=$(($dev_size - 1 - $p2_size))
+
+ if [ $p1_size -le 0 ]; then
+ echo "Your device isn't big enough to hold $SRC"
+ echo "It is $(($p1_size * -1)) MB too small"
+ exitclean
+ fi
+ p1_start=1
+ p1_end=$(($p1_size + 1))
+ /sbin/parted -s $device u MB mkpart primary ext2 $p1_start $p1_end set 1 boot on
+ if [ $p2_size -gt 0 ]; then
+ p2_start=$p1_end
+ p2_end=$(($p2_size + $p2_start))
+ /sbin/parted -s $device u MB mkpart primary ext2 $p2_start $p2_end
+ fi
# Sometimes automount can be _really_ annoying.
echo "Waiting for devices to settle..."
/sbin/udevadm settle
sleep 5
- getpartition ${device#/dev/}
- TGTDEV=${device}${partnum}
+ TGTDEV=${device}1
umount $TGTDEV &> /dev/null || :
# Check extlinux version
if extlinux -v 2>&1 | grep -q 'extlinux 3'; then
- /sbin/mkfs.ext3 -L LIVE $TGTDEV
+ mkfs=/sbin/mkfs.ext3
else
- /sbin/mkfs.ext4 -L LIVE $TGTDEV
+ mkfs=/sbin/mkfs.ext4
fi
+ $mkfs -L LIVE $TGTDEV
TGTLABEL="UUID=$(/sbin/blkid -s UUID -o value $TGTDEV)"
+
+ if [ $p2_size -gt 0 ]; then
+ REPODEV=${device}2
+ umount $REPODEV &> /dev/null || :
+ $mkfs -L LIVE-REPO $REPODEV
+ REPOLABEL="UUID=$(/sbin/blkid -s UUID -o value $REPODEV)"
+ fi
}
checkGPT() {
@@ -607,17 +693,24 @@ if [ $(id -u) != 0 ]; then
fi
detectsrctype() {
- if [[ -e $SRCMNT/LiveOS/squashfs.img ]]; then
+ if [[ -e "$SRCMNT/Packages" ]]; then
+ # This will cause the source .iso to be copied to a second partiton
+ # on the target and the boot args to have repo=... pointing to the iso
+ echo "/Packages found, will copy source .iso to target"
+ packages=1
+ fi
+ if [[ -e "$SRCMNT/LiveOS/squashfs.img" ]]; then
+ # LiveOS style boot image
srctype=live
return
fi
if [ -e $SRCMNT/images/install.img -o $SRCMNT/isolinux/initrd.img ]; then
- imgtype=install
- if [ -e $SRCMNT/Packages ]; then
+ if [ -n "$packages" ]; then
srctype=installer
else
srctype=netinst
fi
+ imgtype=install
if [ ! -e $SRCMNT/images/install.img ]; then
echo "$SRC uses initrd.img w/o install.img"
imgtype=initrd
@@ -674,6 +767,7 @@ swapsizemb=0
overlaysizemb=0
srctype=
imgtype=
+packages=
LIVEOS=LiveOS
HOMEFILE="home.img"
@@ -813,6 +907,19 @@ fi
# do some basic sanity checks.
checkMounted $TGTDEV
+# FIXME: would be better if we had better mountpoints
+SRCMNT=$(mktemp -d /media/srctmp.XXXXXX)
+if [ -b "$SRC" ]; then
+ mount -o ro "$SRC" $SRCMNT || exitclean
+elif [ -f "$SRC" ]; then
+ mount -o loop,ro "$SRC" $SRCMNT || exitclean
+else
+ echo "$SRC is not a file or block device."
+ exitclean
+fi
+# Figure out what needs to be done based on the source image
+detectsrctype
+
# Format the device
if [ -n "$format" -a -z "$skipcopy" ]; then
checkLVM $TGTDEV
@@ -865,23 +972,15 @@ if [ "$swapsizemb" -gt 0 -a "$TGTFS" =
"vfat" ]; then
fi
fi
-# FIXME: would be better if we had better mountpoints
-SRCMNT=$(mktemp -d /media/srctmp.XXXXXX)
-if [ -b "$SRC" ]; then
- mount -o ro "$SRC" $SRCMNT || exitclean
-elif [ -f "$SRC" ]; then
- mount -o loop,ro "$SRC" $SRCMNT || exitclean
-else
- echo "$SRC is not a file or block device."
- exitclean
-fi
TGTMNT=$(mktemp -d /media/tgttmp.XXXXXX)
mount $mountopts $TGTDEV $TGTMNT || exitclean
+if [ -n "$REPODEV" ]; then
+ REPOMNT=$(mktemp -d /media/repotmp.XXXXXX)
+ mount $mountopts $REPODEV $REPOMNT || exitclean
+fi
trap exitclean SIGINT SIGTERM
-detectsrctype
-
if [ -f "$TGTMNT/$LIVEOS/$HOMEFILE" -a -n "$keephome" -a
"$homesizemb" -gt 0 ]; then
echo "ERROR: Requested keeping existing /home and specified a size for
/home"
echo "Please either don't specify a size or specify --delete-home"
@@ -979,11 +1078,6 @@ fi
# Verify available space for DVD installer
if [ "$srctype" = "installer" ]; then
- if [ -z "$skipcopy" ]; then
- srcsize=$(du -s -B 1M "$SRC" | awk {'print $1;'})
- else
- srcsize=0
- fi
if [ "$imgtype" = "install" ]; then
imgpath=images/install.img
else
@@ -998,10 +1092,9 @@ if [ "$srctype" = "installer" ]; then
if [ -e $TGTMNT/$(basename "$SRC") ]; then
tbd=$(($tbd + $(du -s -B 1M $TGTMNT/$(basename "$SRC") | awk
{'print $1;'})))
fi
- echo "Size of DVD image: $srcsize"
echo "Size of $imgpath: $installimgsize"
echo "Available space: $((freespace + tbd))"
- if (( ((srcsize + installimgsize)) > ((freespace + tbd)) )); then
+ if (( installimgsize > ((freespace + tbd)) )); then
echo "ERROR: Unable to fit DVD image + install.img on available space on the
target device."
exitclean
fi
@@ -1051,6 +1144,7 @@ if [ "$srctype" = "live" -a -z
"$skipcopy" ]; then
fi
# DVD installer copy
+# Also copies over the source .iso if the image is a new-style LiveOS DVD (F17+)
if [ \( "$srctype" = "installer" -o "$srctype" =
"netinst" \) ]; then
echo "Copying DVD image to target device."
mkdir -p $TGTMNT/images/
@@ -1061,9 +1155,12 @@ if [ \( "$srctype" = "installer" -o
"$srctype" = "netinst" \) ]; then
fi
done
fi
- if [ "$srctype" = "installer" -a -z "$skipcopy" ];
then
- copyFile "$SRC" $TGTMNT/
- fi
+fi
+
+# Copy source .iso to repo partition
+if [ -n "$packages" -a -z "$skipcopy" ]; then
+ echo "Copying $SRC"
+ copyFile "$SRC" $REPOMNT/
sync
fi
@@ -1139,40 +1236,45 @@ if [[ live == $srctype ]]; then
-e "/^totaltimeout.*$/d" $BOOTCONFIG
fi
fi
+
+
echo "Updating boot config file"
# adjust label and fstype
-if [ -n "$LANG" ]; then
- kernelargs="$kernelargs LANG=$LANG"
-fi
sed -i -e "s/CDLABEL=[^ ]*/$TGTLABEL/" -e "s/rootfstype=[^
]*/rootfstype=$TGTFS/" -e "s/LABEL=[^ ]*/$TGTLABEL/" $BOOTCONFIG
$BOOTCONFIG_EFI
if [ -n "$kernelargs" ]; then
- sed -i -e "s/liveimg/liveimg ${kernelargs}/" $BOOTCONFIG $BOOTCONFIG_EFI
+ sed -i -e "s;initrd.img;initrd.img ${kernelargs};" $BOOTCONFIG
+ if [ -n "$efi" ]; then
+ sed -i -e "s;vmlinuz;vmlinuz ${kernelargs};" $BOOTCONFIG_EFI
+ fi
fi
if [ "$LIVEOS" != "LiveOS" ]; then
sed -i -e "s;liveimg;liveimg live_dir=$LIVEOS;" $BOOTCONFIG
$BOOTCONFIG_EFI
fi
-# DVD Installer
-if [ "$srctype" = "installer" ]; then
- sed -i -e "s;initrd=initrd.img;initrd=initrd.img ${LANG:+LANG=$LANG}
repo=hd:$TGTLABEL:/;g" $BOOTCONFIG
- sed -i -e "s;stage2=\S*;;g" $BOOTCONFIG
+# EFI images are in $SYSLINUXPATH now
+if [ -n "$efi" ]; then
+ sed -i -e "s;/images/pxeboot/;/$SYSLINUXPATH/;g" $BOOTCONFIG_EFI
+ sed -i -e "s;findiso;;g" $BOOTCONFIG_EFI
+fi
+
+# Add repo= to point to the source .iso with the packages
+if [[ -n "$packages" ]]; then
+ sed -i -e "s;initrd.img;initrd.img repo=hd:$REPOLABEL:/;g" $BOOTCONFIG
if [ -n "$efi" ]; then
- # Images are in $SYSLINUXPATH now
- sed -i -e "s;/images/pxeboot/;/$SYSLINUXPATH/;g" -e
"s;vmlinuz;vmlinuz ${LANG:+LANG=$LANG} repo=hd:$TGTLABEL:/;g" $BOOTCONFIG_EFI
+ sed -i -e "s;vmlinuz;vmlinuz repo=hd:$REPOLABEL:/;g" $BOOTCONFIG_EFI
fi
fi
# DVD Installer for netinst
-if [ "$srctype" = "netinst" ]; then
+if [ "$srctype" != "live" ]; then
if [ "$imgtype" = "install" ]; then
- sed -i -e "s;stage2=\S*;stage2=hd:$TGTLABEL:/images/install.img;g"
$BOOTCONFIG
+ sed -i -e "s;initrd.img;initrd.img
stage2=hd:$TGTLABEL:/images/install.img;g" $BOOTCONFIG
+ if [ -n "$efi" ]; then
+ sed -i -e "s;vmlinuz;vmlinuz
stage2=hd:$TGTLABEL:/images/install.img;g" $BOOTCONFIG_EFI
+ fi
else
# The initrd has everything, so no stage2
- sed -i -e "s;stage2=\S*;;g" $BOOTCONFIG
- fi
- if [ -n "$efi" ]; then
- # Images are in $SYSLINUXPATH now
- sed -ie "s;/images/pxeboot/;/$SYSLINUXPATH/;g" $BOOTCONFIG_EFI
+ sed -i -e "s;stage2=\S*;;g" $BOOTCONFIG $BOOTCONFIG_EFI
fi
fi
@@ -1184,14 +1286,6 @@ if [ -n "$totaltimeout" ]; then
sed -i -e "/^timeout.*$/a\totaltimeout\ $totaltimeout" $BOOTCONFIG
fi
-# Use repo if the .iso has the repository on it, otherwise use stage2 which
-# will default to using the network mirror
-if [ -e "$SRCMNT/.discinfo" ]; then
- METHODSTR=repo
-else
- METHODSTR=stage2
-fi
-
if [ "$overlaysizemb" -gt 0 ]; then
echo "Initializing persistent overlay file"
OVERFILE="overlay-$( /sbin/blkid -s LABEL -o value $TGTDEV )-$( /sbin/blkid -s
UUID -o value $TGTDEV )"