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

Generated by cgit