summaryrefslogtreecommitdiff
path: root/init
blob: d45798ed294d26ecc09c9c8092c69cd2d4390111 (plain)
    1 #!/bin/bash
    2 
    3 DEBUG=0
    4 ROOTDEV=''
    5 
    6 function screen_init {
    7   # Clear screen
    8   clear
    9 
   10   # Output message file if it exists
   11   [[ -f /etc/msg ]] && cat /etc/msg
   12 }
   13 
   14 
   15 #
   16 # Mounts the fakeroot from the kernel "root" param
   17 #
   18 function mount_fakeroot {
   19   local rootdev=${1}
   20   local fakeroot=${2}
   21 
   22   mount -o ro ${rootdev} ${fakeroot}
   23 }
   24 
   25 
   26 function log {
   27   local msg="${1}"
   28   echo -e "${msg}"
   29   if [[ ${DEBUG} -ne 0 ]]; then
   30     echo "Press enter to continue"
   31     read
   32   fi
   33 }
   34  
   35  
   36 #
   37 # Resolves the path to the root device from the cmdline root= syntax.
   38 # Currently handles UUID syntax and /dev/sdx syntax
   39 #
   40 function parse_cmdline {
   41   local cmdline=${1}
   42 
   43   dev=''
   44   for i in ${cmdline[@]}; do
   45     case "${i}" in
   46       root=*)
   47         if [[ ${i:5:4} == 'UUID' ]]; then
   48           #mount by uuid
   49           ROOTDEV="/dev/disk/by-uuid/$(echo ${i} | cut -d '=' -f 3)"
   50         else
   51           # mount by dev
   52           ROOTDEV="$(echo ${i} | cut -d '=' -f 2)"
   53         fi
   54       ;;
   55       initdebug)
   56         # Enable debug mode (this is gonna be slow
   57         DEBUG=1
   58       ;;
   59     esac
   60   done
   61 }
   62  
   63  
   64 #
   65 # Returns type of partition. If part is LUKS encrypted, returns 'luks'. If
   66 # anything else, returns 'fs'.
   67 #
   68 # Most installations of the mount command don't require specification of the
   69 # filesystem, but won't automatically detect luks partitions and prompt for a
   70 # password. This allows the script to be smarter about encrypted partitions.
   71 #
   72 function get_part_type {
   73   path=${1}
   74   typestr=$(blkid -s TYPE ${path})
   75   if [[ $(echo ${typestr} | grep 'crypto_LUKS') ]]; then
   76     echo 'luks'
   77   else
   78     echo 'fs'
   79   fi
   80 }
   81 
   82 
   83 #
   84 # Takes an encrypted device path and executes cryptsetup luksOpen. Returns path
   85 # to the new decrypted block device. This path takes the rough form of
   86 # /dev/mapper/_dev_sdx
   87 #
   88 function setup_encrypted {
   89   path=${1}
   90   name=$(echo ${path} | tr / _)
   91 
   92   # Decrypted block dev path is /dev/mapper/${name}
   93   cryptsetup luksOpen ${path} ${name}
   94 
   95   # Notify user and wait for input on failure
   96   if [[ $? -gt 0 ]]; then
   97     echo "An error was detected mounting the encrypted root." >&2
   98     echo "Pausing. Press enter to continue." >&2
   99     read
  100   fi
  101 
  102   # Success. Return the path of the decrypted root device
  103   echo "/dev/mapper/${name}"
  104 }
  105 
  106 
  107 #
  108 # Main function to keep the main operations code nicely separated from the
  109 # rest.
  110 #
  111 function main {
  112   # display fanciful boot image
  113   screen_init
  114 
  115   # Mount the /proc and /sys filesystems.
  116   mount -t devtmpfs none /dev
  117   mount -t proc     none /proc
  118   mount -t tmpfs    none /run
  119   mount -t sysfs    none /sys
  120 
  121   local fakeroot='/mnt/root'
  122 
  123   if [[ ! -d ${fakeroot} ]]; then
  124     log "Fake root location ${fakeroot} does not exist. Creating."
  125     mkdir ${fakeroot}
  126   fi
  127 
  128   log "Parsing cmdline arguments"
  129 
  130   parse_cmdline "$(cat /proc/cmdline)"
  131 
  132   log "Root device: ${ROOTDEV}"
  133 
  134   if [[ $(get_part_type ${ROOTDEV}) == 'luks' ]]; then
  135     # Set new rootdev location (/dev/mapper/something). This will update it to
  136     # the decrypted block device path.
  137     log "Root device ${ROOTDEV} is encrypted."
  138     ROOTDEV=$(setup_encrypted ${ROOTDEV})
  139     log "New rootdev: ${ROOTDEV}"
  140   fi
  141   
  142   # Mount the fakeroot.
  143   log "Mounting fakeroot"
  144   mount_fakeroot ${ROOTDEV} ${fakeroot}
  145 
  146   # Clean up.
  147   # We actually don't do this because switch_root does this for us
  148   umount /proc
  149   umount /sys
  150   umount /run
  151 
  152   # Boot the real McCoy
  153   exec switch_root ${fakeroot} /sbin/init
  154   if [[ $? -gt 0 ]]; then
  155     log "There was an error performing switch_root to ${fakeroot}."
  156     log "Starting recovery shell."
  157     /bin/bash
  158   fi
  159 }
  160 
  161 main ${@}

Generated by cgit