mirror of
				https://github.com/libretro/Lakka-LibreELEC.git
				synced 2025-11-04 00:59:00 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			1182 lines
		
	
	
		
			32 KiB
		
	
	
	
		
			Bash
		
	
	
		
			Executable File
		
	
	
	
	
			
		
		
	
	
			1182 lines
		
	
	
		
			32 KiB
		
	
	
	
		
			Bash
		
	
	
		
			Executable File
		
	
	
	
	
#!/bin/sh
 | 
						|
 | 
						|
# SPDX-License-Identifier: GPL-2.0-or-later
 | 
						|
# Copyright (C) 2010-2011 Roman Weber (roman@openelec.tv)
 | 
						|
# Copyright (C) 2012 Yann Cézard (eesprit@free.fr)
 | 
						|
# Copyright (C) 2009-2014 Stephan Raue (stephan@openelec.tv)
 | 
						|
# Copyright (C) 2016-present Team LibreELEC (https://libreelec.tv)
 | 
						|
 | 
						|
# create directories
 | 
						|
/usr/bin/busybox mkdir -p /dev
 | 
						|
/usr/bin/busybox mkdir -p /proc
 | 
						|
/usr/bin/busybox mkdir -p /sys
 | 
						|
/usr/bin/busybox mkdir -p /tmp
 | 
						|
/usr/bin/busybox mkdir -p /flash
 | 
						|
/usr/bin/busybox mkdir -p /sysroot
 | 
						|
/usr/bin/busybox mkdir -p /storage
 | 
						|
/usr/bin/busybox mkdir -p /run
 | 
						|
 | 
						|
# temp mountpoint for updates
 | 
						|
/usr/bin/busybox mkdir -p /update
 | 
						|
 | 
						|
# mount all needed special filesystems
 | 
						|
/usr/bin/busybox mount -t devtmpfs devtmpfs /dev
 | 
						|
/usr/bin/busybox mount -t proc proc /proc
 | 
						|
/usr/bin/busybox mount -t sysfs sysfs /sys
 | 
						|
# /run options have to match what systemd uses by default
 | 
						|
/usr/bin/busybox mount -t tmpfs -o mode=755,size=20%,nr_inodes=800k,nosuid,nodev,strictatime tmpfs /run
 | 
						|
 | 
						|
UPDATE_ROOT=/storage/.update
 | 
						|
UPDATE_DIR="$UPDATE_ROOT"
 | 
						|
 | 
						|
UPDATE_KERNEL="KERNEL"
 | 
						|
UPDATE_SYSTEM="SYSTEM"
 | 
						|
IMAGE_KERNEL="@KERNEL_NAME@"
 | 
						|
IMAGE_SYSTEM="SYSTEM"
 | 
						|
 | 
						|
BOOT_STEP="start"
 | 
						|
MD5_FAILED="0"
 | 
						|
RUN_FSCK="yes"
 | 
						|
RUN_FSCK_DISKS=""
 | 
						|
SYSLINUX_DEFAULT=""
 | 
						|
GRUB_DEFAULT=""
 | 
						|
 | 
						|
NBD_DEVS="0"
 | 
						|
FLASH_FREE_MIN="5"
 | 
						|
 | 
						|
LIVE="no"
 | 
						|
 | 
						|
BREAK_TRIPPED="no"
 | 
						|
 | 
						|
BIGFONT="1080"
 | 
						|
 | 
						|
# Get a serial number if present (eg. RPi) otherwise use MAC address from eth0
 | 
						|
MACHINE_UID="$(awk '/^Serial/{s='0000000' $3; print substr(s, length(s) - 7)}' /proc/cpuinfo)"
 | 
						|
[ -z "$MACHINE_UID" ] && MACHINE_UID="$(cat /sys/class/net/eth0/address 2>/dev/null | tr -d :)"
 | 
						|
 | 
						|
# common functions
 | 
						|
. /functions
 | 
						|
 | 
						|
# script functions
 | 
						|
progress() {
 | 
						|
  if test "$PROGRESS" = "yes"; then
 | 
						|
    echo "### $1 ###" >&2
 | 
						|
  fi
 | 
						|
}
 | 
						|
 | 
						|
debug_msg() {
 | 
						|
  echo "$1" >&$SILENT_OUT
 | 
						|
}
 | 
						|
 | 
						|
debug_shell() {
 | 
						|
  echo "### Starting debugging shell for boot step: $BOOT_STEP... type  exit  to quit ###"
 | 
						|
 | 
						|
  showcursor
 | 
						|
 | 
						|
  setsid cttyhack sh
 | 
						|
}
 | 
						|
 | 
						|
error() {
 | 
						|
  # Display fatal error message
 | 
						|
  # $1:action which caused error, $2:message
 | 
						|
  # Send debug_shell output to stderr, in case caller is redirecting/consuming stdout
 | 
						|
  # Return exitcode=1 so that called may detect when an error has occurred
 | 
						|
  echo "*** Error in $BOOT_STEP: $1: $2 ***" >&2
 | 
						|
  debug_shell >&2
 | 
						|
  return 1
 | 
						|
}
 | 
						|
 | 
						|
break_after() {
 | 
						|
  # Start debug shell after boot step $1, and all subsequent steps
 | 
						|
  if [ $BREAK_TRIPPED == yes ]; then
 | 
						|
    debug_shell
 | 
						|
  else
 | 
						|
    case $BREAK in
 | 
						|
      all|*$1*)
 | 
						|
        BREAK_TRIPPED=yes
 | 
						|
        debug_shell
 | 
						|
        ;;
 | 
						|
    esac
 | 
						|
  fi
 | 
						|
}
 | 
						|
 | 
						|
# Mount handlers
 | 
						|
# All handlers take the following parameters:
 | 
						|
# $1:target, $2:mountpoint, $3:mount options, [$4:fs type]
 | 
						|
mount_common() {
 | 
						|
  # Common mount handler, handles block devices and filesystem images
 | 
						|
  MOUNT_OPTIONS="-o $3"
 | 
						|
  [ -n "$4" ] && MOUNT_OPTIONS="-t $4 $MOUNT_OPTIONS"
 | 
						|
 | 
						|
  for i in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15; do
 | 
						|
    ERR_ENV=1
 | 
						|
 | 
						|
    mount $MOUNT_OPTIONS $1 $2 >&$SILENT_OUT 2>&1
 | 
						|
    [ "$?" -eq "0" ] && ERR_ENV=0 && break
 | 
						|
 | 
						|
    usleep 1000000
 | 
						|
  done
 | 
						|
  [ "$ERR_ENV" -eq "0" ] && return 0
 | 
						|
  error "mount_common" "Could not mount $1"
 | 
						|
}
 | 
						|
 | 
						|
get_iscsistart_options() {
 | 
						|
  # Convert kernel commandline ISCSI= options to iscsistart options
 | 
						|
  IFS_SAVE="$IFS"
 | 
						|
  IFS=,
 | 
						|
 | 
						|
  for arg in $1; do
 | 
						|
    val="${arg#*=}"
 | 
						|
    case "$arg" in
 | 
						|
      iscsi_initiator=*)
 | 
						|
        option="-i"
 | 
						|
        ;;
 | 
						|
      iscsi_target_name=*)
 | 
						|
        option="-t"
 | 
						|
        ;;
 | 
						|
      iscsi_target_ip=*)
 | 
						|
        option="-a"
 | 
						|
        ;;
 | 
						|
      iscsi_target_port=*)
 | 
						|
        option="-p"
 | 
						|
        ;;
 | 
						|
      iscsi_target_group=*)
 | 
						|
        option="-g"
 | 
						|
        ;;
 | 
						|
      iscsi_username=*)
 | 
						|
        option="-u"
 | 
						|
        ;;
 | 
						|
      iscsi_password=*)
 | 
						|
        option="-w"
 | 
						|
        ;;
 | 
						|
      iscsi_in_username=*)
 | 
						|
        option="-U"
 | 
						|
        ;;
 | 
						|
      iscsi_in_password=*)
 | 
						|
        option="-W"
 | 
						|
        ;;
 | 
						|
    esac
 | 
						|
    echo "$option $val"
 | 
						|
  done
 | 
						|
 | 
						|
  IFS="$IFS_SAVE"
 | 
						|
}
 | 
						|
 | 
						|
mount_iscsi() {
 | 
						|
  # Mount iSCSI target
 | 
						|
  ISCSI_DEV="${1##*,}"
 | 
						|
  ISCSI_OPTIONS="${1%,*}"
 | 
						|
 | 
						|
  if [ ! -f "/usr/sbin/iscsistart" ]; then
 | 
						|
    error "iscsistart" "iSCSI support not available"
 | 
						|
  fi
 | 
						|
 | 
						|
  if [ "$ISCSI_OPTIONS" = "auto" ]; then
 | 
						|
    progress "Network configuration based on iBFT"
 | 
						|
    /usr/sbin/iscsistart -N >&$SILENT_OUT 2>&1 || error "iscsistart" "Unable to configure network"
 | 
						|
    progress "iSCSI auto connect based on iBFT"
 | 
						|
    /usr/sbin/iscsistart -b >&$SILENT_OUT 2>&1 || error "iscsistart" "Unable to auto connect"
 | 
						|
  else
 | 
						|
    /usr/sbin/iscsistart $(get_iscsistart_options "$ISCSI_OPTIONS") >&$SILENT_OUT 2>&1 || error "iscsistart" "Unable to connect to ISCSI target"
 | 
						|
  fi
 | 
						|
 | 
						|
  mount_common "$ISCSI_DEV" "$2" "$3" "$4"
 | 
						|
}
 | 
						|
 | 
						|
mount_nbd() {
 | 
						|
# Mount NBD device
 | 
						|
  NBD_SERVER="${1%%:*}"
 | 
						|
  NBD_PORT="${1#*:}"
 | 
						|
  NBD_DEV="/dev/nbd$NBD_DEVS"
 | 
						|
 | 
						|
  nbd-client $NBD_SERVER $NBD_PORT $NBD_DEV >&$SILENT_OUT 2>&1 || error "nbd-client" "Could not connect to NBD server $1"
 | 
						|
 | 
						|
  mount_common "$NBD_DEV" "$2" "$3" "$4"
 | 
						|
 | 
						|
  NBD_DEVS=$(( NBD_DEVS + 1 ))
 | 
						|
}
 | 
						|
 | 
						|
mount_nfs() {
 | 
						|
  # Mount NFS export
 | 
						|
  NFS_EXPORT="${1%%,*}"
 | 
						|
  NFS_OPTIONS="${1#*,}"
 | 
						|
 | 
						|
  [ "$NFS_OPTIONS" = "$1" ] && NFS_OPTIONS=
 | 
						|
 | 
						|
  mount_common "$NFS_EXPORT" "$2" "$3,nolock,rsize=32768,wsize=32768,$NFS_OPTIONS" "nfs"
 | 
						|
}
 | 
						|
 | 
						|
mount_ubifs() {
 | 
						|
  mount_common "$1" "$2" "$3" "ubifs"
 | 
						|
}
 | 
						|
 | 
						|
mount_part() {
 | 
						|
  # Mount a local or network filesystem
 | 
						|
  # $1:[TYPE=]target, $2:mountpoint, $3:mount options, [$4:fs type]
 | 
						|
  progress "mount filesystem $1 ..."
 | 
						|
 | 
						|
  MOUNT_TARGET="${1#*=}"
 | 
						|
  case $1 in
 | 
						|
    /dev/ubi*)
 | 
						|
      MOUNT_CMD="mount_ubifs"
 | 
						|
      MOUNT_TARGET="$1"
 | 
						|
      RUN_FSCK="no"
 | 
						|
      ;;
 | 
						|
    LABEL=*|UUID=*|/*)
 | 
						|
      MOUNT_CMD="mount_common"
 | 
						|
      MOUNT_TARGET="$1"
 | 
						|
      ;;
 | 
						|
    ISCSI=*)
 | 
						|
      MOUNT_CMD="mount_iscsi"
 | 
						|
      ;;
 | 
						|
    NBD=*)
 | 
						|
      MOUNT_CMD="mount_nbd"
 | 
						|
      ;;
 | 
						|
    NFS=*)
 | 
						|
      MOUNT_CMD="mount_nfs"
 | 
						|
      ;;
 | 
						|
    *)
 | 
						|
      error "mount_part" "Unknown filesystem $1"
 | 
						|
      ;;
 | 
						|
  esac
 | 
						|
 | 
						|
  # Substitute unique identifier if available or remove placeholder
 | 
						|
  MOUNT_TARGET="${MOUNT_TARGET//@UID@/$MACHINE_UID}"
 | 
						|
 | 
						|
  $MOUNT_CMD "$MOUNT_TARGET" "$2" "$3" "$4"
 | 
						|
}
 | 
						|
 | 
						|
mount_sysroot() {
 | 
						|
  if [ "$SYSTEM_TORAM" = "yes" ]; then
 | 
						|
    cp /flash/$IMAGE_SYSTEM /dev/$IMAGE_SYSTEM
 | 
						|
    mount_part "/dev/$IMAGE_SYSTEM" "/sysroot" "ro,loop"
 | 
						|
  else
 | 
						|
    mount_part "/flash/$IMAGE_SYSTEM" "/sysroot" "ro,loop"
 | 
						|
  fi
 | 
						|
 | 
						|
  if [ -f /flash/post-sysroot.sh ]; then
 | 
						|
    . /flash/post-sysroot.sh
 | 
						|
  fi
 | 
						|
}
 | 
						|
 | 
						|
# mount the specified SYSTEM file and output arch from /etc/os-release
 | 
						|
get_project_arch() {
 | 
						|
  if [ -f ${1}/etc/os-release ]; then
 | 
						|
    . ${1}/etc/os-release
 | 
						|
    echo "${LIBREELEC_ARCH}"
 | 
						|
  fi
 | 
						|
}
 | 
						|
 | 
						|
# If the project/arch of current matches the update, then it is considered compatible.
 | 
						|
# Otherwise, mount the update SYSTEM partition and, if canupdate.sh is available,
 | 
						|
# call the script to determine if the current update file can be applied on to the
 | 
						|
# current system - 0 means it is compatible, non-zero that it is not compatible.
 | 
						|
is_compatible() {
 | 
						|
  local result=1
 | 
						|
 | 
						|
  if [ "${1}" = "${2}" ]; then
 | 
						|
    result=0
 | 
						|
  else
 | 
						|
    if [ -f /update/usr/share/bootloader/canupdate.sh ]; then
 | 
						|
      sh /update/usr/share/bootloader/canupdate.sh "${1}" "${2}" && result=0
 | 
						|
    fi
 | 
						|
  fi
 | 
						|
 | 
						|
  return ${result}
 | 
						|
}
 | 
						|
 | 
						|
# determine if the new SYSTEM file is compatible with the current SYSTEM file
 | 
						|
check_is_compatible() {
 | 
						|
  local update_filename="${1}"
 | 
						|
  local old_project_arch new_project_arch
 | 
						|
 | 
						|
  old_project_arch="$(get_project_arch "/sysroot")" || return
 | 
						|
  new_project_arch="$(get_project_arch "/update")" || return
 | 
						|
 | 
						|
  # If old or new project/arch isn't available then could be very old (pre-/etc/os-release) build - have to trust it
 | 
						|
  if [ -n "${old_project_arch}" -a -n "${new_project_arch}" ]; then
 | 
						|
    # If the old project/arch is not compatible with the new project/arch then abort...
 | 
						|
    if ! is_compatible "${old_project_arch}" "${new_project_arch}"; then
 | 
						|
      echo ""
 | 
						|
      echo "ERROR: $(basename "${update_filename}") is not compatible with ${old_project_arch} hardware - update cancelled."
 | 
						|
      echo ""
 | 
						|
      echo "Current system: ${old_project_arch}"
 | 
						|
      echo "Update  system: ${new_project_arch}"
 | 
						|
      echo ""
 | 
						|
      echo "Create $UPDATE_ROOT/.nocompat to disable compatibility checks and risk a non-booting system."
 | 
						|
      echo ""
 | 
						|
      return 1
 | 
						|
    fi
 | 
						|
  fi
 | 
						|
 | 
						|
  return 0
 | 
						|
}
 | 
						|
 | 
						|
update_file() {
 | 
						|
  if [ -f "$UPDATE_DIR/$2" -a -f "$3" ]; then
 | 
						|
    if [ ! "$FAT32_BOOT" = "yes" ]; then
 | 
						|
      mount -o remount,rw /flash
 | 
						|
    fi
 | 
						|
    rm -f "$3"
 | 
						|
    StartProgress percent "Updating $1... " "$3" $(stat -t "$UPDATE_DIR/$2" | awk '{print $2}')
 | 
						|
      # use dd here with conv=fsync so that all writes are non-buffered
 | 
						|
      # ensuring accurate progress - take the sync hit during the
 | 
						|
      # transfer, rather than when flushing file buffers after the progress
 | 
						|
      # meter declares the transfer already complete
 | 
						|
      dd if=$UPDATE_DIR/$2 of=$3 bs=1M conv=fsync 2>/dev/null
 | 
						|
      StopProgress
 | 
						|
 | 
						|
    # loopback file needs writable /flash all the time
 | 
						|
    if [ ! "$FAT32_BOOT" = "yes" ]; then
 | 
						|
      if [ "${disk%%=*}" != "FILE" ]; then
 | 
						|
        mount -o remount,ro /flash
 | 
						|
      fi
 | 
						|
    fi
 | 
						|
    sync
 | 
						|
  fi
 | 
						|
}
 | 
						|
 | 
						|
update_partition() {
 | 
						|
  local result
 | 
						|
 | 
						|
  if [ -f "$UPDATE_DIR/$2" -a -b "$3" ]; then
 | 
						|
    StartProgress spinner "Updating $1... "
 | 
						|
      result="$(dd if="$UPDATE_DIR/$2" of="$3" 2>&1)"
 | 
						|
      StopProgress "done"
 | 
						|
    echo "${result}"
 | 
						|
  fi
 | 
						|
}
 | 
						|
 | 
						|
update_bootloader() {
 | 
						|
  local result
 | 
						|
 | 
						|
  export BOOT_ROOT="/flash"
 | 
						|
  export SYSTEM_ROOT="/update"
 | 
						|
 | 
						|
  if [ -f $SYSTEM_ROOT/usr/share/bootloader/update.sh ]; then
 | 
						|
    StartProgress spinner "Updating Boot Files... "
 | 
						|
      result="$(sh $SYSTEM_ROOT/usr/share/bootloader/update.sh 2>&1)"
 | 
						|
      sync
 | 
						|
      StopProgress "done"
 | 
						|
    [ -n "${result}" ] && echo "${result}"
 | 
						|
  fi
 | 
						|
}
 | 
						|
 | 
						|
set_consolefont() {
 | 
						|
  local vres
 | 
						|
 | 
						|
  progress "Set console font"
 | 
						|
  if [ -e /dev/fb0 ]; then
 | 
						|
    vres="$(fbset 2>/dev/null | awk '/geometry/ { print $3 }')"
 | 
						|
    if [ $vres -gt "$BIGFONT" ]; then
 | 
						|
      setfont -C /dev/tty0 ter-v32b.psf
 | 
						|
    fi
 | 
						|
  fi
 | 
						|
}
 | 
						|
 | 
						|
load_splash() {
 | 
						|
  local set_default_res=no
 | 
						|
  local vres
 | 
						|
 | 
						|
  if [ ! "$SPLASH" = "no" ]; then
 | 
						|
    progress "Loading bootsplash"
 | 
						|
 | 
						|
    if [ -e /dev/fb0 ]; then
 | 
						|
      # Set framebuffer to a custom resolution and/or fallback to default resolution (1024x768-32), if required.
 | 
						|
      if [ ! "$SWITCH_FRAMEBUFFER" = "no" ]; then
 | 
						|
        if [ "$SWITCH_FRAMEBUFFER" = "1080" ]; then
 | 
						|
          SWITCH_FRAMEBUFFER="1920 1080 1920 1080 32"
 | 
						|
        elif [ "$SWITCH_FRAMEBUFFER" = "720" ]; then
 | 
						|
          SWITCH_FRAMEBUFFER="1280 720 1280 720 32"
 | 
						|
        fi
 | 
						|
 | 
						|
        # Try setting a custom framebuffer resolution
 | 
						|
        if [ ! "${SWITCH_FRAMEBUFFER:-yes}" = "yes" ]; then
 | 
						|
          fbset -g $SWITCH_FRAMEBUFFER 2>/dev/null && set_default_res=no
 | 
						|
        fi
 | 
						|
 | 
						|
        # Set a default resolution if required
 | 
						|
        if [ "$set_default_res" = "yes" ]; then
 | 
						|
          fbset -g 1024 768 1024 768 32
 | 
						|
        fi
 | 
						|
      fi
 | 
						|
 | 
						|
      # load splash
 | 
						|
      if [ -f /splash/splash.conf ]; then
 | 
						|
        . /splash/splash.conf
 | 
						|
      fi
 | 
						|
 | 
						|
      # Select splash image based on current native resolution
 | 
						|
      if [ -z "$SPLASHIMAGE" ]; then
 | 
						|
        vres="$(fbset 2>/dev/null | awk '/geometry/ { print $3 }')"
 | 
						|
 | 
						|
        for s in /flash/oemsplash-${vres}.png \
 | 
						|
                 /flash/oemsplash-1080.png \
 | 
						|
                 /flash/oemsplash.png \
 | 
						|
                 /splash/splash-${vres}.png \
 | 
						|
                 /splash/splash-1080.png \
 | 
						|
                 ; do
 | 
						|
          if [ -f "${s}" ]; then
 | 
						|
            SPLASHIMAGE="${s}"
 | 
						|
            break
 | 
						|
          fi
 | 
						|
        done
 | 
						|
      fi
 | 
						|
 | 
						|
      if [ -n "$SPLASHIMAGE" -a -f "$SPLASHIMAGE" ]; then
 | 
						|
        ply-image $SPLASHIMAGE > /dev/null 2>&1
 | 
						|
      fi
 | 
						|
 | 
						|
      debug_msg "Framebuffer vertical res: $vres"
 | 
						|
      debug_msg "Framebuffer splash image: $SPLASHIMAGE"
 | 
						|
    fi
 | 
						|
  fi
 | 
						|
}
 | 
						|
 | 
						|
do_reboot() {
 | 
						|
  echo "System reboots now..."
 | 
						|
 | 
						|
  # syncing filesystem
 | 
						|
  sync
 | 
						|
 | 
						|
  # unmount filesystems
 | 
						|
  if /usr/bin/busybox mountpoint -q /flash ; then
 | 
						|
    /usr/bin/busybox umount /flash
 | 
						|
  fi
 | 
						|
 | 
						|
  if /usr/bin/busybox mountpoint -q /storage ; then
 | 
						|
    /usr/bin/busybox umount /storage
 | 
						|
  fi
 | 
						|
 | 
						|
  usleep 2000000
 | 
						|
  /usr/bin/busybox reboot
 | 
						|
}
 | 
						|
 | 
						|
force_fsck() {
 | 
						|
  echo "Filesystem corruption has been detected!"
 | 
						|
  echo "To prevent an automatic repair attempt continuing,"
 | 
						|
  echo "press any key or power off your system within the next 120 seconds"
 | 
						|
  echo ""
 | 
						|
  read -t120 -n1
 | 
						|
  # The exit status is 0 if input is available
 | 
						|
  # The exit status is greater than 128 if the timeout is exceeded
 | 
						|
  if [ $? -ne 0 -o $? -gt 128 ]; then
 | 
						|
    echo "Repairing filesystem..."
 | 
						|
    echo ""
 | 
						|
    /usr/sbin/fsck -T -M -y $RUN_FSCK_DISKS
 | 
						|
    FSCK_RET=$?
 | 
						|
    if [ $(( $FSCK_RET & 8 )) -eq 8 ]; then
 | 
						|
      # fubar
 | 
						|
      echo "Forced fsck failed. Your system is broken beyond repair"
 | 
						|
      echo "Please re-install @DISTRONAME@"
 | 
						|
      echo ""
 | 
						|
      echo "Press enter to shutdown now"
 | 
						|
      echo ""
 | 
						|
      read fubar
 | 
						|
      poweroff
 | 
						|
    fi
 | 
						|
    do_reboot
 | 
						|
  else
 | 
						|
    echo "Shutting down..."
 | 
						|
    sleep 5
 | 
						|
    sync
 | 
						|
    poweroff
 | 
						|
  fi
 | 
						|
}
 | 
						|
 | 
						|
check_disks() {
 | 
						|
  if [ "$RUN_FSCK" = "yes" -a -n "$RUN_FSCK_DISKS" ]; then
 | 
						|
    progress "Checking disk(s): $RUN_FSCK_DISKS"
 | 
						|
    echo "Checking disk(s): $RUN_FSCK_DISKS" >/dev/kmsg
 | 
						|
    for i in 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0; do
 | 
						|
      /usr/sbin/fsck -T -M -p -a $RUN_FSCK_DISKS >/dev/fsck.latest 2>&1
 | 
						|
      FSCK_RET=$?
 | 
						|
      cat /dev/fsck.latest >>/dev/fsck.log
 | 
						|
 | 
						|
      # FSCK_RET is the bit-wise OR of the exit codes for each filesystem that is checked.
 | 
						|
      if [ $FSCK_RET -ge 16 ]; then
 | 
						|
        progress "General error, continuing..."
 | 
						|
        break
 | 
						|
      elif [ $(( $FSCK_RET & 8 )) -eq 8 ]; then
 | 
						|
        # device not found
 | 
						|
        if [ $i -eq 0 ]; then
 | 
						|
          progress "Device not found, continuing..."
 | 
						|
        else
 | 
						|
          usleep 500000
 | 
						|
        fi
 | 
						|
      elif [ $(( $FSCK_RET & 4 )) -eq 4 ]; then
 | 
						|
        # errors left
 | 
						|
        force_fsck
 | 
						|
      elif [ $(( $FSCK_RET & 2 )) -eq 2 ]; then
 | 
						|
        # reboot needed
 | 
						|
        echo "Filesystem repaired, reboot needed..."
 | 
						|
        do_reboot
 | 
						|
      elif [ $(( $FSCK_RET & 1 )) -eq 1 ]; then
 | 
						|
        # filesystem errors corrected
 | 
						|
        progress "Filesystem errors corrected , continuing..."
 | 
						|
        break
 | 
						|
      elif [ $FSCK_RET -eq 0 ]; then
 | 
						|
        # no errors found
 | 
						|
        progress "No filesystem errors found, continuing..."
 | 
						|
        break
 | 
						|
      fi
 | 
						|
    done
 | 
						|
    while read line; do
 | 
						|
      [ -n "$line" ] && echo "fsck: ${line::160}" >/dev/kmsg
 | 
						|
    done </dev/fsck.latest
 | 
						|
    rm -f /dev/fsck.latest
 | 
						|
  fi
 | 
						|
}
 | 
						|
 | 
						|
wakeonlan() {
 | 
						|
  if [ "$STORAGE_NETBOOT" = "yes" ]; then
 | 
						|
    wol_ip=${disk%:*}
 | 
						|
    wol_ip=${wol_ip#*=}
 | 
						|
  elif [ "$FLASH_NETBOOT" = "yes" ]; then
 | 
						|
    wol_ip=${boot%:*}
 | 
						|
    wol_ip=${wol_ip#*=}
 | 
						|
  else
 | 
						|
    return 0
 | 
						|
  fi
 | 
						|
 | 
						|
  if [ -n "$wol_ip" -a -n "$wol_mac" -a -n "$wol_wait" ]; then
 | 
						|
    progress "Sending Magic Packet (WOL) if needed"
 | 
						|
 | 
						|
    if ! ping -q -c 2 "$wol_ip" &>/dev/null; then
 | 
						|
      ether-wake "$wol_mac"
 | 
						|
      StartProgress countdown "WOL magic packet sent to $wol_ip, waiting $wol_wait seconds... " $wol_wait "done"
 | 
						|
    fi
 | 
						|
  fi
 | 
						|
}
 | 
						|
 | 
						|
mount_flash() {
 | 
						|
  progress "Mounting flash"
 | 
						|
 | 
						|
  wakeonlan
 | 
						|
 | 
						|
  if [ ! "$FAT32_BOOT" = "yes" ]; then
 | 
						|
    mount_part "$boot" "/flash" "ro,noatime"
 | 
						|
  else
 | 
						|
    mount_part "$boot" "/flash" "rw,noatime,umask=0000"
 | 
						|
  fi
 | 
						|
 | 
						|
  if [ -f /flash/post-flash.sh ]; then
 | 
						|
    . /flash/post-flash.sh
 | 
						|
  fi
 | 
						|
}
 | 
						|
 | 
						|
cleanup_flash() {
 | 
						|
  progress "Cleaning up flash (if required)"
 | 
						|
 | 
						|
  if [ -f /flash/pieeprom.bin -o -f /flash/pieeprom.upd -o -f /flash/vl805.bin ]; then
 | 
						|
    mount -o remount,rw /flash
 | 
						|
 | 
						|
    rm -f /flash/pieeprom.bin /flash/pieeprom.upd /flash/pieeprom.sig
 | 
						|
    rm -f /flash/vl805.bin /flash/vl805.sig
 | 
						|
    rm -f /flash/recovery.bin /flash/recovery.[0-9][0-9][0-9] /flash/RECOVERY.[0-9][0-9][0-9]
 | 
						|
 | 
						|
    mount -o remount,ro /flash
 | 
						|
  fi
 | 
						|
}
 | 
						|
 | 
						|
mount_storage() {
 | 
						|
  progress "Mounting storage"
 | 
						|
 | 
						|
  if [ "$LIVE" = "yes" ]; then
 | 
						|
    # mount tmpfs and exit early. disk=xx is not allowed in live mode
 | 
						|
    mount -t tmpfs none /storage
 | 
						|
    return
 | 
						|
  fi
 | 
						|
 | 
						|
  wakeonlan
 | 
						|
 | 
						|
  if [ "$FAT32_BOOT" = "yes" ]; then
 | 
						|
    DISTRO=${IMAGE_SYSTEM%'/'*}
 | 
						|
    mkdir -p /flash/$DISTRO/storage
 | 
						|
    mount --bind /flash/$DISTRO/storage /storage
 | 
						|
  elif [ -n "$disk" ]; then
 | 
						|
    if [ -n "$OVERLAY" ]; then
 | 
						|
      OVERLAY_DIR=$(cat /sys/class/net/eth0/address | tr -d :)
 | 
						|
 | 
						|
      mount_part "$disk" "/storage" "rw,noatime"
 | 
						|
      mkdir -p /storage/$OVERLAY_DIR
 | 
						|
      umount /storage
 | 
						|
 | 
						|
      # split $disk into $target,$options so we can append $OVERLAY_DIR
 | 
						|
      options="${disk#*,}"
 | 
						|
      target="${disk%%,*}"
 | 
						|
      if [ "$options" = "$disk" ]; then
 | 
						|
        disk="$target/$OVERLAY_DIR"
 | 
						|
      else
 | 
						|
        disk="$target/$OVERLAY_DIR,$options"
 | 
						|
      fi
 | 
						|
    fi
 | 
						|
 | 
						|
    if [ -f /flash/mount-storage.sh ]; then
 | 
						|
      . /flash/mount-storage.sh
 | 
						|
    else
 | 
						|
      mount_part "$disk" "/storage" "rw,noatime"
 | 
						|
    fi
 | 
						|
  else
 | 
						|
    # /storage should always be writable
 | 
						|
    mount -t tmpfs none /storage
 | 
						|
  fi
 | 
						|
}
 | 
						|
 | 
						|
# Make last bootloader label (installer, live, run etc.) as the new default
 | 
						|
update_bootmenu() {
 | 
						|
  local crnt_default
 | 
						|
 | 
						|
  if [ -n "$SYSLINUX_DEFAULT" -a -f /flash/syslinux.cfg ]; then
 | 
						|
    if grep -q "^LABEL $SYSLINUX_DEFAULT\$" /flash/syslinux.cfg; then
 | 
						|
      crnt_default="$(awk '/^DEFAULT/ {print $2}' /flash/syslinux.cfg)"
 | 
						|
      if [ ! "$crnt_default" = "$SYSLINUX_DEFAULT" ]; then
 | 
						|
        progress "Updating /flash/syslinux.cfg [$crnt_default -> $SYSLINUX_DEFAULT]"
 | 
						|
 | 
						|
        mount -o remount,rw /flash
 | 
						|
        sed -e "s/^SAY Wait for .* mode/SAY Wait for ${SYSLINUX_DEFAULT} mode/" -i /flash/syslinux.cfg
 | 
						|
        sed -e "s/^DEFAULT .*/DEFAULT $SYSLINUX_DEFAULT/" -i /flash/syslinux.cfg
 | 
						|
        rm -f /flash/EFI/BOOT/syslinux.cfg
 | 
						|
        mount -o remount,ro /flash
 | 
						|
      fi
 | 
						|
    fi
 | 
						|
  fi
 | 
						|
 | 
						|
  if [ -n "$GRUB_DEFAULT" -a -f /flash/EFI/BOOT/grub.cfg ]; then
 | 
						|
    if grep -q "^menuentry \"$GRUB_DEFAULT\"" /flash/EFI/BOOT/grub.cfg; then
 | 
						|
      crnt_default="$(awk '/^set default/ {print substr($2,9,19)}' /flash/EFI/BOOT/grub.cfg)"
 | 
						|
      if [ ! "$crnt_default" = "\"$GRUB_DEFAULT\"" ]; then
 | 
						|
        progress "Updating /flash/EFI/BOOT/grub.cfg [$crnt_default -> \"$GRUB_DEFAULT\"]"
 | 
						|
 | 
						|
        mount -o remount,rw /flash
 | 
						|
        sed -e "s/^set default=.*/set default=\"$GRUB_DEFAULT\"/" -i /flash/EFI/BOOT/grub.cfg
 | 
						|
        rm -f /flash/grub.cfg
 | 
						|
        mount -o remount,ro /flash
 | 
						|
      fi
 | 
						|
    fi
 | 
						|
  fi
 | 
						|
}
 | 
						|
 | 
						|
check_out_of_space() {
 | 
						|
  if [ "$(df /storage | awk '/[0-9]%/{print $4}')" -eq "0" ]; then
 | 
						|
    echo ""
 | 
						|
    echo "The $1 is corrupt, or there is not enough"
 | 
						|
    echo "free space on /storage to complete the update!"
 | 
						|
    echo ""
 | 
						|
    echo "Please free up space on your /storage partition"
 | 
						|
    echo "by deleting unecessary files, then try again."
 | 
						|
    echo ""
 | 
						|
    return 0
 | 
						|
  else
 | 
						|
    echo ""
 | 
						|
    echo "The $1 is corrupt/invalid!"
 | 
						|
    echo ""
 | 
						|
    return 1
 | 
						|
  fi
 | 
						|
}
 | 
						|
 | 
						|
do_cleanup() {
 | 
						|
  StartProgress spinner "Cleaning up... "
 | 
						|
 | 
						|
  if mountpoint -q /update; then
 | 
						|
    umount /update
 | 
						|
  fi
 | 
						|
 | 
						|
  if [ -d $UPDATE_ROOT/.tmp/mnt ]; then
 | 
						|
    if mountpoint -q $UPDATE_ROOT/.tmp/mnt ; then
 | 
						|
      # busybox umount deletes loop device automatically
 | 
						|
      umount $UPDATE_ROOT/.tmp/mnt
 | 
						|
    fi
 | 
						|
 | 
						|
    [ -n $LOOP ] && losetup -d $LOOP &>/dev/null
 | 
						|
  fi
 | 
						|
 | 
						|
  [ -f "$UPDATE_TAR" ] && rm -f "$UPDATE_TAR" &>/dev/null
 | 
						|
  [ -f "$UPDATE_IMG_GZ" ] && rm -f "$UPDATE_IMG_GZ" &>/dev/null
 | 
						|
  [ -f "$UPDATE_IMG" ] && rm -f "$UPDATE_IMG" &>/dev/null
 | 
						|
 | 
						|
  rm -rf $UPDATE_ROOT/.tmp &>/dev/null
 | 
						|
  rm -rf $UPDATE_ROOT/[0-9a-zA-Z]* &>/dev/null
 | 
						|
  rm -f  $UPDATE_ROOT/.nocheck $UPDATE_ROOT/.nocompat &>/dev/null
 | 
						|
 | 
						|
  sync
 | 
						|
 | 
						|
  StopProgress "done"
 | 
						|
}
 | 
						|
 | 
						|
check_update() {
 | 
						|
  progress "Checking for updates"
 | 
						|
  UPDATE_TAR=$(ls -1 "$UPDATE_DIR"/*.tar 2>/dev/null | head -n 1)
 | 
						|
  UPDATE_IMG_GZ=$(ls -1 "$UPDATE_DIR"/*.img.gz 2>/dev/null | head -n 1)
 | 
						|
  UPDATE_IMG=$(ls -1 "$UPDATE_DIR"/*.img 2>/dev/null | head -n 1)
 | 
						|
 | 
						|
  if ! [ -f "$UPDATE_DIR/$UPDATE_KERNEL" -a -f "$UPDATE_DIR/$UPDATE_SYSTEM" ] &&
 | 
						|
     ! [ -f "$UPDATE_TAR" -o -f "$UPDATE_IMG_GZ" -o -f "$UPDATE_IMG" ]; then
 | 
						|
    return 0
 | 
						|
  fi
 | 
						|
 | 
						|
  if [ "$UPDATE_DISABLED" = "yes" ]; then
 | 
						|
    echo "Updating is not supported on netboot"
 | 
						|
    do_cleanup
 | 
						|
    StartProgress countdown "Normal startup in 10s... " 10 "NOW"
 | 
						|
    return 0
 | 
						|
  fi
 | 
						|
 | 
						|
  if [ -d $UPDATE_DIR/.tmp ]; then
 | 
						|
    echo "Failed update detected - performing recovery."
 | 
						|
    echo ""
 | 
						|
    do_cleanup
 | 
						|
    StartProgress countdown "Normal startup in 10s... " 10 "NOW"
 | 
						|
    return 0
 | 
						|
  fi
 | 
						|
 | 
						|
  mkdir -p $UPDATE_DIR/.tmp &>/dev/null
 | 
						|
  sync
 | 
						|
 | 
						|
  echo "UPDATE IN PROGRESS"
 | 
						|
  echo ""
 | 
						|
  echo "Please do not reboot or turn off your @DISTRONAME@ device!"
 | 
						|
  echo ""
 | 
						|
 | 
						|
  if [ -f "$UPDATE_TAR" ]; then
 | 
						|
    TARRESULT="0"
 | 
						|
 | 
						|
    echo "Found new .tar archive"
 | 
						|
    UPDATE_FILENAME="$UPDATE_TAR"
 | 
						|
    StartProgress spinner "Extracting contents of archive... "
 | 
						|
      tar -xf "$UPDATE_TAR" -C $UPDATE_DIR/.tmp 1>/dev/null 2>/tmp/tarresult.txt || TARRESULT="1"
 | 
						|
 | 
						|
    if [ "${TARRESULT}" -eq "0" ]; then
 | 
						|
      if [ "$FAT32_BOOT" = "yes" ]; then
 | 
						|
        mv $UPDATE_DIR/.tmp/* $UPDATE_DIR &>/dev/null
 | 
						|
        UPDATE_DIR=${UPDATE_TAR%.*}
 | 
						|
      else
 | 
						|
        mv $UPDATE_DIR/.tmp/*/target/* $UPDATE_DIR &>/dev/null
 | 
						|
      fi
 | 
						|
      sync
 | 
						|
      StopProgress "done"
 | 
						|
    else
 | 
						|
      StopProgress "FAILED"
 | 
						|
 | 
						|
      echo "Failed to extract contents of archive file!"
 | 
						|
      echo "tar result: '$(cat /tmp/tarresult.txt)'"
 | 
						|
 | 
						|
      check_out_of_space "archive"
 | 
						|
 | 
						|
      do_cleanup
 | 
						|
      StartProgress countdown "Normal startup in 30s... " 30 "NOW"
 | 
						|
      return 0
 | 
						|
    fi
 | 
						|
  elif [ -f "$UPDATE_IMG_GZ" -o -f "$UPDATE_IMG" ]; then
 | 
						|
    mkdir -p $UPDATE_DIR/.tmp/mnt &>/dev/null
 | 
						|
    IMG_FILE="$UPDATE_DIR/.tmp/update.img"
 | 
						|
    GZRESULT="0"
 | 
						|
 | 
						|
    if [ -f "$UPDATE_IMG_GZ" ]; then
 | 
						|
      echo "Found new compressed image file"
 | 
						|
      UPDATE_FILENAME="$UPDATE_IMG_GZ"
 | 
						|
      StartProgress spinner "Decompressing image file... "
 | 
						|
        gunzip -d -c "$UPDATE_IMG_GZ" 1>$IMG_FILE 2>/tmp/gzresult.txt || GZRESULT="1"
 | 
						|
        sync
 | 
						|
        [ "${GZRESULT}" -eq "0" ] && StopProgress "OK" || StopProgress "FAILED"
 | 
						|
 | 
						|
      if [ "${GZRESULT}" -eq "1" ]; then
 | 
						|
        echo "Failed to decompress image file!"
 | 
						|
        echo "gunzip result: '$(cat /tmp/gzresult.txt)'"
 | 
						|
 | 
						|
        check_out_of_space "compressed image"
 | 
						|
 | 
						|
        do_cleanup
 | 
						|
        StartProgress countdown "Normal startup in 30s... " 30 "NOW"
 | 
						|
        return 0
 | 
						|
      fi
 | 
						|
    else
 | 
						|
      echo "Found new image file"
 | 
						|
      UPDATE_FILENAME="$UPDATE_IMG"
 | 
						|
      mv "$UPDATE_IMG" $IMG_FILE
 | 
						|
    fi
 | 
						|
 | 
						|
    LOOP=$(losetup -f)
 | 
						|
    LOOP_NUM=$(echo $LOOP | sed 's|/dev/loop||')
 | 
						|
    mknod $LOOP b 7 $LOOP_NUM &>/dev/null
 | 
						|
    losetup $LOOP $IMG_FILE
 | 
						|
 | 
						|
    # check for MBR partititon
 | 
						|
    OFFSET=$(fdisk -u -l $LOOP 2>/dev/null | awk '/^[ ]*Device/{part=1; next}; part{if ($2 == "*") {print $5} else {print $4} ; exit}')
 | 
						|
    if [ -z "$OFFSET" ]; then
 | 
						|
      # check for GPT partititon
 | 
						|
      OFFSET=$(fdisk -u -l $LOOP 2>/dev/null | awk '/^Number/{part=1; next}; part{print $2; exit}')
 | 
						|
      if [ -z "$OFFSET" ]; then
 | 
						|
        echo "Could not find a valid system partition in image file!"
 | 
						|
        do_cleanup
 | 
						|
        StartProgress countdown "Normal startup in 10s... " 10 "NOW"
 | 
						|
        return 0
 | 
						|
      fi
 | 
						|
    fi
 | 
						|
 | 
						|
    SECTOR_SIZE=$(cat /sys/devices/virtual/block/loop${LOOP_NUM}/queue/hw_sector_size)
 | 
						|
    losetup -d $LOOP
 | 
						|
    sync
 | 
						|
 | 
						|
    OFFSET=$(($OFFSET * $SECTOR_SIZE))
 | 
						|
 | 
						|
    # use losetup because busybox mount does not support the -o offset option
 | 
						|
    echo "Mounting system partition..."
 | 
						|
    losetup -o $OFFSET $LOOP $IMG_FILE
 | 
						|
    mount -o ro,loop $LOOP $UPDATE_DIR/.tmp/mnt
 | 
						|
 | 
						|
    # don't make temporary files but instead copy
 | 
						|
    # directly from mountpoint to /flash
 | 
						|
    UPDATE_DIR=$UPDATE_ROOT/.tmp/mnt
 | 
						|
    UPDATE_KERNEL="@KERNEL_NAME@"
 | 
						|
  else
 | 
						|
    UPDATE_FILENAME="$UPDATE_DIR/$UPDATE_SYSTEM"
 | 
						|
  fi
 | 
						|
 | 
						|
  sync
 | 
						|
  if [ ! "$FAT32_BOOT" = "yes" ]; then
 | 
						|
    if [ ! -b "/$IMAGE_KERNEL" -a ! -f "/flash/$IMAGE_KERNEL" ] || [ ! -f "/flash/$IMAGE_SYSTEM" ]; then
 | 
						|
      echo "Missing (target) ${IMAGE_KERNEL} or ${IMAGE_SYSTEM}!"
 | 
						|
      do_cleanup
 | 
						|
      StartProgress countdown "Normal startup in 30s... " 30 "NOW"
 | 
						|
      return 0
 | 
						|
    fi
 | 
						|
  else
 | 
						|
    if [ ! -f "/flash/$IMAGE_KERNEL" ] || [ ! -f "/flash/$IMAGE_SYSTEM" ]; then
 | 
						|
      echo "Missing (target) ${IMAGE_KERNEL} or ${IMAGE_SYSTEM}!"
 | 
						|
      do_cleanup
 | 
						|
      StartProgress countdown "Normal startup in 30s... " 30 "NOW"
 | 
						|
      return 0
 | 
						|
    fi
 | 
						|
  fi
 | 
						|
 | 
						|
  if [ "$FAT32_BOOT" = "yes" ]; then
 | 
						|
    UPDATE_KERNEL=$IMAGE_KERNEL
 | 
						|
    UPDATE_SYSTEM=$IMAGE_SYSTEM
 | 
						|
  fi
 | 
						|
 | 
						|
  if [ ! -f "$UPDATE_DIR/$UPDATE_KERNEL" -o ! -f "$UPDATE_DIR/$UPDATE_SYSTEM" ]; then
 | 
						|
    echo "Missing (source) ${UPDATE_KERNEL} or ${UPDATE_SYSTEM}!"
 | 
						|
    do_cleanup
 | 
						|
    StartProgress countdown "Normal startup in 30s... " 30 "NOW"
 | 
						|
    return 0
 | 
						|
  fi
 | 
						|
 | 
						|
  # check md5 sums if .nocheck doesn't exist
 | 
						|
  if [ ! -f "$UPDATE_ROOT/.nocheck" -a ! "$FAT32_BOOT" = "yes" ]; then
 | 
						|
    if [ -f "$UPDATE_DIR/${UPDATE_KERNEL}.md5" -a -f "$UPDATE_DIR/${UPDATE_SYSTEM}.md5" ]; then
 | 
						|
      # *.md5 size-check
 | 
						|
      if [ ! -s "$UPDATE_DIR/${UPDATE_KERNEL}.md5" -o ! -s "$UPDATE_DIR/${UPDATE_SYSTEM}.md5" ]; then
 | 
						|
        echo "Zero-sized .md5 file!"
 | 
						|
        MD5_FAILED="1"
 | 
						|
      else
 | 
						|
        sed "s#target/KERNEL#$UPDATE_DIR/$UPDATE_KERNEL#g" "$UPDATE_DIR/${UPDATE_KERNEL}.md5" >"$UPDATE_ROOT/${UPDATE_KERNEL}.check.md5"
 | 
						|
        sed "s#target#$UPDATE_DIR#g" "$UPDATE_DIR/${UPDATE_SYSTEM}.md5" >"$UPDATE_ROOT/${UPDATE_SYSTEM}.check.md5"
 | 
						|
 | 
						|
        StartProgress spinner "Checking ${UPDATE_KERNEL}.md5... "
 | 
						|
          if md5sum -sc "$UPDATE_ROOT/${UPDATE_KERNEL}.check.md5"; then
 | 
						|
            StopProgress "OK"
 | 
						|
          else
 | 
						|
            StopProgress "FAILED"
 | 
						|
            MD5_FAILED="1"
 | 
						|
          fi
 | 
						|
 | 
						|
        StartProgress spinner "Checking ${UPDATE_SYSTEM}.md5... "
 | 
						|
          if md5sum -sc "$UPDATE_ROOT/${UPDATE_SYSTEM}.check.md5"; then
 | 
						|
            StopProgress "OK"
 | 
						|
          else
 | 
						|
            StopProgress "FAILED"
 | 
						|
            MD5_FAILED="1"
 | 
						|
          fi
 | 
						|
      fi
 | 
						|
    else
 | 
						|
      echo "Missing ${UPDATE_KERNEL}.md5 or ${UPDATE_SYSTEM}.md5!"
 | 
						|
      MD5_FAILED="1"
 | 
						|
    fi
 | 
						|
 | 
						|
    if [ "$MD5_FAILED" -eq "1" ]; then
 | 
						|
      echo "md5 check failed!"
 | 
						|
      do_cleanup
 | 
						|
      StartProgress countdown "Normal startup in 30s... " 30 "NOW"
 | 
						|
      return 0
 | 
						|
    fi
 | 
						|
  fi
 | 
						|
 | 
						|
  mount_part "$UPDATE_DIR/$UPDATE_SYSTEM" "/update" "ro,loop"
 | 
						|
 | 
						|
  # Verify that the new update is compatible with the current system - this should avoid creating
 | 
						|
  # non-booting systems after (for example) an RPi tar is incorrectly applied to an RPi2 system.
 | 
						|
  if [ ! -f "$UPDATE_ROOT/.nocompat" ]; then
 | 
						|
    if ! check_is_compatible "$UPDATE_FILENAME"; then
 | 
						|
      do_cleanup
 | 
						|
      StartProgress countdown "Normal startup in 60s... " 60 "NOW"
 | 
						|
      return 0
 | 
						|
    fi
 | 
						|
  fi
 | 
						|
 | 
						|
  # get sizes
 | 
						|
  FLASH_FREE=$(df /flash/ | awk '/[0-9]%/{print $4}')
 | 
						|
  FLASH_FREE=$(( $FLASH_FREE * 1024 ))
 | 
						|
 | 
						|
  # Disregard kernel size if it's a a block device
 | 
						|
  if [ ! -b "/$IMAGE_KERNEL" ]; then
 | 
						|
    OLD_KERNEL=$(stat -t "/flash/$IMAGE_KERNEL" | awk '{print $2}')
 | 
						|
  else
 | 
						|
    OLD_KERNEL="0"
 | 
						|
  fi
 | 
						|
 | 
						|
  OLD_SYSTEM=$(stat -t "/flash/$IMAGE_SYSTEM" | awk '{print $2}')
 | 
						|
  NEW_KERNEL=$(stat -t "$UPDATE_DIR/$UPDATE_KERNEL" | awk '{print $2}')
 | 
						|
  NEW_SYSTEM=$(stat -t "$UPDATE_DIR/$UPDATE_SYSTEM" | awk '{print $2}')
 | 
						|
 | 
						|
  # old KERNEL+SYSTEM+free space - new KERNEL+SYSTEM must be higher than 5MB
 | 
						|
  # at least 5MB free after update
 | 
						|
 | 
						|
  TMP_SIZE=$((OLD_KERNEL + OLD_SYSTEM + FLASH_FREE - NEW_KERNEL - NEW_SYSTEM))
 | 
						|
  FLASH_FREE_MIN=$((FLASH_FREE_MIN * 1024 * 1024))
 | 
						|
 | 
						|
  if [ $TMP_SIZE -ge $FLASH_FREE_MIN ]; then
 | 
						|
    echo "Checking size: OK"
 | 
						|
  else
 | 
						|
    echo "Checking size: FAILED"
 | 
						|
    echo ""
 | 
						|
    echo "Your System (FAT) partition is too small for this update,"
 | 
						|
    echo "and there is not enough space for the update to be installed!"
 | 
						|
    echo ""
 | 
						|
    echo "You must re-install your system using the disk image of a"
 | 
						|
    echo "current release, or you must re-size your existing partitions"
 | 
						|
    echo "so that the System (FAT) partition is at least @SYSTEM_SIZE@MB in size."
 | 
						|
    echo ""
 | 
						|
    do_cleanup
 | 
						|
    StartProgress countdown "Normal startup in 60s... " 60 "NOW"
 | 
						|
    return 0
 | 
						|
  fi
 | 
						|
 | 
						|
  # all ok, update
 | 
						|
  if [ -b "/$IMAGE_KERNEL" ]; then
 | 
						|
    update_partition "Kernel" "$UPDATE_KERNEL" "/$IMAGE_KERNEL"
 | 
						|
  else
 | 
						|
    update_file "Kernel" "$UPDATE_KERNEL" "/flash/$IMAGE_KERNEL"
 | 
						|
  fi
 | 
						|
  umount /sysroot
 | 
						|
  update_file "System" "$UPDATE_SYSTEM" "/flash/$IMAGE_SYSTEM"
 | 
						|
  update_bootloader
 | 
						|
  do_cleanup
 | 
						|
  do_reboot
 | 
						|
}
 | 
						|
 | 
						|
prepare_sysroot() {
 | 
						|
  progress "Preparing system"
 | 
						|
 | 
						|
  mount --move /flash /sysroot/flash
 | 
						|
  mount --move /storage /sysroot/storage
 | 
						|
 | 
						|
  if [ ! "$FAT32_BOOT" = "yes" ]; then
 | 
						|
    if [ ! -d "/sysroot/usr/lib/kernel-overlays/base/lib/modules/$(uname -r)/" -a -f "/sysroot/usr/lib/systemd/systemd" ]; then
 | 
						|
      echo ""
 | 
						|
      echo "NEVER TOUCH boot= in syslinux.conf / cmdline.txt!"
 | 
						|
      echo "If you don't know what you are doing,"
 | 
						|
      echo "your installation is now broken."
 | 
						|
      echo ""
 | 
						|
      StartProgress countdown "Normal startup in 60s... " 60 "NOW"
 | 
						|
    fi
 | 
						|
  fi
 | 
						|
 | 
						|
  [ -f "/sysroot/usr/lib/systemd/systemd" ] || error "final_check" "Could not find systemd!"
 | 
						|
}
 | 
						|
 | 
						|
# Do init tasks to bring up system
 | 
						|
 | 
						|
if [ ! "$(cat /proc/cmdline | grep -s show_kernel_messages)" ]; then
 | 
						|
  # hide kernel log messages on console
 | 
						|
  echo '1 4 1 7' > /proc/sys/kernel/printk
 | 
						|
fi
 | 
						|
 | 
						|
# run platform_init script if exists
 | 
						|
if [ -f "./platform_init" ]; then
 | 
						|
  ./platform_init
 | 
						|
fi
 | 
						|
 | 
						|
if [ ! "$(cat /proc/cmdline | grep -s odin-workaround)" ]; then
 | 
						|
  # clear screen and hide cursor
 | 
						|
  clear
 | 
						|
  hidecursor
 | 
						|
fi
 | 
						|
 | 
						|
# parse command line arguments
 | 
						|
for arg in $(cat /proc/cmdline); do
 | 
						|
  case $arg in
 | 
						|
    BOOT_IMAGE=*)
 | 
						|
      IMAGE_KERNEL="${arg#*=}"
 | 
						|
      [ "${IMAGE_KERNEL:0:1}" = "/" ] && IMAGE_KERNEL="${IMAGE_KERNEL:1}"
 | 
						|
      ;;
 | 
						|
    SYSTEM_IMAGE=*)
 | 
						|
      IMAGE_SYSTEM="${arg#*=}"
 | 
						|
      [ "${IMAGE_SYSTEM:0:1}" = "/" ] && IMAGE_SYSTEM="${IMAGE_SYSTEM:1}"
 | 
						|
     ;;
 | 
						|
    boot=*)
 | 
						|
      boot="${arg#*=}"
 | 
						|
      case $boot in
 | 
						|
        ISCSI=*|NBD=*|NFS=*)
 | 
						|
          UPDATE_DISABLED=yes
 | 
						|
          FLASH_NETBOOT=yes
 | 
						|
          ;;
 | 
						|
        /dev/*|LABEL=*|UUID=*)
 | 
						|
          RUN_FSCK_DISKS="$RUN_FSCK_DISKS $boot"
 | 
						|
          ;;
 | 
						|
      esac
 | 
						|
      ;;
 | 
						|
    disk=*)
 | 
						|
      disk="${arg#*=}"
 | 
						|
      case $disk in
 | 
						|
        ISCSI=*|NBD=*|NFS=*)
 | 
						|
          STORAGE_NETBOOT=yes
 | 
						|
          ;;
 | 
						|
        /dev/*|LABEL=*|UUID=*)
 | 
						|
          RUN_FSCK_DISKS="$RUN_FSCK_DISKS $disk"
 | 
						|
          ;;
 | 
						|
      esac
 | 
						|
      ;;
 | 
						|
    wol_mac=*)
 | 
						|
      wol_mac="${arg#*=}"
 | 
						|
      ;;
 | 
						|
    wol_wait=*)
 | 
						|
      wol_wait="${arg#*=}"
 | 
						|
      ;;
 | 
						|
    installer)
 | 
						|
      SYSLINUX_DEFAULT="installer"
 | 
						|
      ;;
 | 
						|
    debugging)
 | 
						|
      DEBUG=yes
 | 
						|
      ;;
 | 
						|
    progress)
 | 
						|
      PROGRESS=yes
 | 
						|
      INIT_ARGS="$INIT_ARGS --show-status=1"
 | 
						|
      ;;
 | 
						|
    nofsck)
 | 
						|
      RUN_FSCK=no
 | 
						|
      ;;
 | 
						|
    nosplash)
 | 
						|
      SPLASH=no
 | 
						|
      ;;
 | 
						|
    toram)
 | 
						|
      SYSTEM_TORAM=yes
 | 
						|
      ;;
 | 
						|
    live)
 | 
						|
      LIVE=yes
 | 
						|
      SYSLINUX_DEFAULT="live"
 | 
						|
      ;;
 | 
						|
    portable)
 | 
						|
      SYSLINUX_DEFAULT="run"
 | 
						|
      ;;
 | 
						|
    grub_live)
 | 
						|
      LIVE=yes
 | 
						|
      GRUB_DEFAULT="Live"
 | 
						|
      ;;
 | 
						|
    grub_portable)
 | 
						|
      GRUB_DEFAULT="Run"
 | 
						|
      ;;
 | 
						|
    overlay)
 | 
						|
      OVERLAY=yes
 | 
						|
      ;;
 | 
						|
    setfbres=*)
 | 
						|
      SWITCH_FRAMEBUFFER="${arg#*=}"
 | 
						|
      SWITCH_FRAMEBUFFER="${SWITCH_FRAMEBUFFER//,/ }"
 | 
						|
      ;;
 | 
						|
    break=*)
 | 
						|
      BREAK="${arg#*=}"
 | 
						|
      ;;
 | 
						|
    bigfont=*)
 | 
						|
      BIGFONT="${arg#*=}"
 | 
						|
      ;;
 | 
						|
    ip=*)
 | 
						|
      KERNEL_IPCONFIG="yes"
 | 
						|
      ;;
 | 
						|
    fat32-boot)
 | 
						|
      FAT32_BOOT="yes"
 | 
						|
      ;;
 | 
						|
  esac
 | 
						|
done
 | 
						|
 | 
						|
if test "$DEBUG" = "yes"; then
 | 
						|
  exec 3>&1
 | 
						|
else
 | 
						|
  exec 3>/dev/null
 | 
						|
fi
 | 
						|
SILENT_OUT=3
 | 
						|
 | 
						|
# If the network is up (due to the use of the "ip" kernel parameter) and a DNS
 | 
						|
# server is known, allow the libc resolver to use it
 | 
						|
grep '^\(nameserver\|domain\) ' /proc/net/pnp | grep -v '^nameserver 0\.0\.0\.0$' > /etc/resolv.conf
 | 
						|
 | 
						|
if [ "${boot%%=*}" = "FILE" ]; then
 | 
						|
  error "check arguments" "boot argument can't be FILE type..."
 | 
						|
fi
 | 
						|
 | 
						|
debug_msg "Unique identifier for this client: ${MACHINE_UID:-NOT AVAILABLE}"
 | 
						|
 | 
						|
# main boot sequence
 | 
						|
for BOOT_STEP in \
 | 
						|
    set_consolefont \
 | 
						|
    check_disks \
 | 
						|
    mount_flash \
 | 
						|
    cleanup_flash \
 | 
						|
    update_bootmenu \
 | 
						|
    load_splash \
 | 
						|
    mount_sysroot \
 | 
						|
    mount_storage \
 | 
						|
    check_update \
 | 
						|
    prepare_sysroot; do
 | 
						|
  $BOOT_STEP
 | 
						|
  [ -n "$DEBUG" ] && break_after $BOOT_STEP
 | 
						|
done
 | 
						|
 | 
						|
BOOT_STEP=final
 | 
						|
 | 
						|
# log if booting from usb / removable storage
 | 
						|
STORAGE=$(cat /proc/mounts | grep " /sysroot/storage " | awk '{print $1}' | awk -F '/' '{print $3}')
 | 
						|
FLASH=$(cat /proc/mounts | grep " /sysroot/flash " | awk '{print $1}' | awk -F '/' '{print $3}')
 | 
						|
for i in $STORAGE $FLASH ; do
 | 
						|
  if [ -n "$i" ]; then
 | 
						|
    removable="/sys/class/block/*/$i/../removable"
 | 
						|
    if [ -e $removable ]; then
 | 
						|
      if [ "$(cat $removable 2>/dev/null)" = "1" ]; then
 | 
						|
        echo "### BIG FAT WARNING" > /dev/kmsg
 | 
						|
        echo "### $i is removable. suspend/resume may not work" > /dev/kmsg
 | 
						|
      fi
 | 
						|
    fi
 | 
						|
  fi
 | 
						|
done
 | 
						|
# move some special filesystems
 | 
						|
/usr/bin/busybox mount --move /dev /sysroot/dev
 | 
						|
/usr/bin/busybox mount --move /proc /sysroot/proc
 | 
						|
/usr/bin/busybox mount --move /sys /sysroot/sys
 | 
						|
/usr/bin/busybox mount --move /run /sysroot/run
 | 
						|
/usr/bin/busybox rm -fr /tmp
 | 
						|
 | 
						|
# setup kernel overlays
 | 
						|
/usr/bin/busybox chroot /sysroot /usr/sbin/kernel-overlays-setup
 | 
						|
 | 
						|
# tell OE settings addon to disable updates
 | 
						|
if [ "$UPDATE_DISABLED" = "yes" ]; then
 | 
						|
  echo "" > /sysroot/dev/.update_disabled
 | 
						|
fi
 | 
						|
 | 
						|
if [ "$FLASH_NETBOOT" = "yes" ]; then
 | 
						|
  echo "" > /sysroot/dev/.flash_netboot
 | 
						|
fi
 | 
						|
 | 
						|
if [ "$KERNEL_IPCONFIG" = "yes" ]; then
 | 
						|
  echo "" > /sysroot/dev/.kernel_ipconfig
 | 
						|
fi
 | 
						|
 | 
						|
# swap can not be used over nfs.(see scripts/mount-swap)
 | 
						|
if [ "$STORAGE_NETBOOT" = "yes" ]; then
 | 
						|
  echo "" > /sysroot/dev/.storage_netboot
 | 
						|
fi
 | 
						|
 | 
						|
# switch to new sysroot and start real init
 | 
						|
exec /usr/bin/busybox switch_root /sysroot /usr/lib/systemd/systemd $INIT_ARGS
 | 
						|
 | 
						|
error "switch_root" "Error in initramfs. Could not switch to new root"
 |