]> code.delx.au - refind/blobdiff - install.sh
Added ability to boot the previously-booted loader if
[refind] / install.sh
index d00c6a891b88c417f786581194b0b5c743fe8cc1..67df9ee3e5c851ec6bfab490214ddcee0d73db1a 100755 (executable)
@@ -35,6 +35,9 @@
 #
 # Revision history:
 #
+# 0.7.9   -- Fixed bug that caused errors if dmraid utility not installed
+# 0.7.7   -- Fixed bug that created mangled refind_linux.conf file; added ability
+#            to locate and mount ESP on Linux, if it's not mounted
 # 0.7.6   -- Added --ownhfs {device-filename} option
 # 0.7.5   -- Fixed bug when installing to ESP on recent versions of OS X
 # 0.7.2   -- Fixed code that could be confused by use of autofs to mount the ESP
@@ -246,13 +249,16 @@ CopyKeys() {
 # honoring the $InstallDrivers condition. Must be passed a suitable
 # architecture code (ia32 or x64).
 CopyDrivers() {
+   local Blkid
+
+   Blkid=`which blkid 2> /dev/null`
    if [[ $InstallDrivers == "all" ]] ; then
       mkdir -p "$InstallDir/$TargetDir/drivers_$1"
       cp "$ThisDir"/drivers_$1/*_$1.efi "$InstallDir/$TargetDir/drivers_$1/" 2> /dev/null
       cp "$RefindDir"/drivers_$1/*_$1.efi "$InstallDir/$TargetDir/drivers_$1/" 2> /dev/null
-   elif [[ "$InstallDrivers" == "boot" && -x `which blkid` ]] ; then
+   elif [[ "$InstallDrivers" == "boot" && -x "$Blkid" ]] ; then
       BootPart=`df /boot | grep dev | cut -f 1 -d " "`
-      BootFS=`blkid -o export $BootPart 2> /dev/null | grep TYPE= | cut -f 2 -d =`
+      BootFS=`$Blkid -o export $BootPart 2> /dev/null | grep TYPE= | cut -f 2 -d =`
       DriverType=""
       case $BootFS in
          ext2 | ext3) DriverType="ext2"
@@ -440,7 +446,27 @@ MountDefaultTarget() {
 MountOSXESP() {
    # Identify the ESP. Note: This returns the FIRST ESP found;
    # if the system has multiple disks, this could be wrong!
-   Temp=`diskutil list | grep " EFI " | grep -o 'disk.*'`
+   Temp=$(mount | sed -n -E "/^(\/dev\/disk[0-9]+s[0-9]+) on \/ \(.*$/s//\1/p")
+   if [ $Temp ]; then
+      Temp=$(diskutil list $Temp | sed -n -E '/^ *[0-9]+:[ ]+EFI EFI[ ]+[0-9.]+ [A-Z]+[ ]+(disk[0-9]+s[0-9]+)$/ { s//\1/p
+             q
+         }' )
+      if [ -z $Temp ]; then
+         echo "Warning: root device doesn't have an EFI partition"
+      fi
+   else
+      echo "Warning: root device could not be found"
+   fi
+   if [ -z $Temp ]; then
+      Temp=$(diskutil list | sed -n -E '/^ *[0-9]+:[ ]+EFI EFI[ ]+[0-9.]+ [A-Z]+[ ]+(disk[0-9]+s[0-9]+)$/ { s//\1/p
+             q
+         }' )
+
+      if [ -z $Temp ]; then
+         echo "Could not find an EFI partition. Aborting!"
+         exit 1
+      fi
+   fi
    Esp=/dev/`echo $Temp`
    # If the ESP is mounted, use its current mount point....
    Temp=`df -P | grep "$Esp"`
@@ -468,7 +494,6 @@ SetupMacHfs() {
    cp -n "$InstallDir/$TargetDir/boot.efi" "$InstallDir/$TargetDir/boot.efi-backup" &> /dev/null
    ln -f "$InstallDir/$TargetDir/$1" "$InstallDir/$TargetDir/boot.efi"
    touch "$InstallDir/mach_kernel"
-   cp -n "$RefindDir/icons/os_refind.icns" "$InstallDir/.VolumeIcon.icns" &> /dev/null
    rm "$InstallDir/$TargetDir/SystemVersion.plist" &> /dev/null
    cat - << ENDOFHERE >> "$InstallDir/$TargetDir/SystemVersion.plist"
 <xml version="1.0" encoding="UTF-8"?>
@@ -683,32 +708,80 @@ ReSignBinaries() {
    IFS=$SaveIFS
    RefindDir="$TempDir"
    DeleteRefindDir=1
-}
+} # ReSignBinaries()
+
+# Locate and mount an ESP, if possible, based on parted output.
+# Should be called only if /boot/efi is NOT an acceptable ESP.
+# Sets InstallDir to the mounted ESP's path ($RootDir/boot/efi)
+# and EspFilesystem the filesystem (always "vfat")
+FindLinuxESP() {
+   echo "The ESP doesn't seem to be mounted! Trying to find it...."
+   local Drive
+   local PartNum
+   local TableType
+   local DmStatus
+   local SkipIt
+   local Dmraid
+   for Drive in `ls /dev/[sh]d?` ; do
+      SkipIt=0
+      Dmraid=`which dmraid 2> /dev/null`
+      if [ -x "$Dmraid" ] ; then
+         DmStatus=`dmraid -r | grep $Drive`
+         if [ -n "$DmStatus" ] ; then
+            echo "$Drive seems to be part of a RAID array; skipping!"
+            SkipIt=1
+         fi
+      fi
+      TableType=`parted $Drive print -m -s 2>/dev/null | awk -F: '$1 == "'$Drive'" { print $6 }'`
+      if [[ $TableType == 'gpt' && $SkipIt == 0 ]] ; then # read only GPT disks that aren't part of dmraid array
+         PartNum=`LANG=C parted $Drive print -m -s 2>/dev/null | awk -F: '$7 ~ "(^boot| boot)" { print $1 }' | head -n 1`
+         if [ "$PartNum" -eq "$PartNum" ] 2> /dev/null ; then
+            InstallDir="$RootDir/boot/efi"
+            mkdir -p $InstallDir
+            mount $Drive$PartNum $InstallDir
+            EspFilesystem=`grep "$Drive$PartNum.*/boot/efi" /etc/mtab | uniq | grep -v autofs | cut -d " " -f 3`
+            if [[ $EspFilesystem != 'vfat' ]] ; then
+               umount $InstallDir
+            else
+               echo "Mounting ESP at $InstallDir"
+               break;
+            fi
+         fi # $PartNum -eq $PartNum
+      fi # TableType
+   done
+} # FindLinuxESP()
 
 # Identifies the ESP's location (/boot or /boot/efi, or these locations under
 # the directory specified by --root); aborts if the ESP isn't mounted at
 # either location.
 # Sets InstallDir to the ESP mount point.
-FindLinuxESP() {
+FindMountedESP() {
+   mount /boot &> /dev/null
+   mount /boot/efi &> /dev/null
    EspLine=`df "$RootDir/boot/efi" 2> /dev/null | grep boot/efi`
    if [[ ! -n "$EspLine" ]] ; then
       EspLine=`df "$RootDir"/boot | grep boot`
    fi
    InstallDir=`echo $EspLine | cut -d " " -f 6`
+
    if [[ -n "$InstallDir" ]] ; then
       EspFilesystem=`grep "$InstallDir" /etc/mtab | uniq | grep -v autofs | cut -d " " -f 3`
    fi
    if [[ $EspFilesystem != 'vfat' ]] ; then
-      echo "$RootDir/boot/efi doesn't seem to be on a VFAT filesystem. The ESP must be"
+      FindLinuxESP
+   fi
+   if [[ $EspFilesystem != 'vfat' ]] ; then
+      echo "$RootDir/$InstallDir doesn't seem to be on a VFAT filesystem. The ESP must be"
       echo "mounted at $RootDir/boot or $RootDir/boot/efi and it must be VFAT! Aborting!"
       exit 1
    fi
    echo "ESP was found at $InstallDir using $EspFilesystem"
-} # FindLinuxESP
+} # FindMountedESP
 
 # Uses efibootmgr to add an entry for rEFInd to the EFI's NVRAM.
 # If this fails, sets Problems=1
 AddBootEntry() {
+   local PartNum
    InstallIt="0"
    Efibootmgr=`which efibootmgr 2> /dev/null`
    if [[ "$Efibootmgr" ]] ; then
@@ -774,15 +847,15 @@ GenerateRefindLinuxConf() {
       StartOfDevname=`echo "$RootFS" | cut -b 1-7`
       if [[ "$StartOfDevname" == "/dev/sd" || "$StartOfDevName" == "/dev/hd" ]] ; then
          # Identify root filesystem by UUID rather than by device node, if possible
-         Uuid=`blkid -o export "$RootFS" 2> /dev/null | grep UUID=`
+         Uuid=`blkid -o export -s UUID "$RootFS" 2> /dev/null | grep UUID=`
          if [[ -n $Uuid ]] ; then
             RootFS="$Uuid"
          fi
       fi
       DefaultOptions="$GRUB_CMDLINE_LINUX $GRUB_CMDLINE_LINUX_DEFAULT"
-      echo "\"Boot with standard options\" \"ro root=$RootFS $DefaultOptions \"" > $RLConfFile
-      echo "\"Boot to single-user mode\"   \"ro root=$RootFS $DefaultOptions single\"" >> $RLConfFile
-      echo "\"Boot with minimal options\"  \"ro root=$RootFS\"" >> $RLConfFile
+      echo "\"Boot with standard options\"        \"ro root=$RootFS $DefaultOptions \"" > $RLConfFile
+      echo "\"Boot to single-user mode\"          \"ro root=$RootFS $DefaultOptions single\"" >> $RLConfFile
+      echo "\"Boot with minimal options\"         \"ro root=$RootFS\"" >> $RLConfFile
    fi
 }
 
@@ -901,7 +974,7 @@ InstallOnLinux() {
    if [[ $TargetDir == "/EFI/BOOT" ]] ; then
       MountDefaultTarget
    else
-      FindLinuxESP
+      FindMountedESP
       DetermineTargetDir
    fi
    CpuType=`uname -m`