Cleaning up existing machine id files by deleting them causes an interactive session to be started by systemd This is something we don't want. As the consequences of touching the machine id files seems to be too critical the method has been turned into a hook caller. This allows the user to make use of it on their own purpose and by default doesn't mess with the machine id files
9677 lines
305 KiB
Bash
9677 lines
305 KiB
Bash
#================
|
||
# FILE : functions.sh
|
||
#----------------
|
||
# PROJECT : openSUSE Build-Service
|
||
# COPYRIGHT : (c) 2006 SUSE LINUX Products GmbH, Germany
|
||
# :
|
||
# AUTHOR : Marcus Schaefer <ms@suse.de>
|
||
# :
|
||
# BELONGS TO : Operating System images
|
||
# :
|
||
# DESCRIPTION : This module contains common used functions
|
||
# : for the suse linuxrc and preinit boot image
|
||
# : files
|
||
# :
|
||
# :
|
||
# STATUS : Development
|
||
#----------------
|
||
#======================================
|
||
# Exports (General)
|
||
#--------------------------------------
|
||
export BOOTABLE_FLAG="$(echo -ne '\x80')"
|
||
export ELOG_FILE=/var/log/boot.kiwi
|
||
export TRANSFER_ERRORS_FILE=/tmp/transfer.errors
|
||
export UFONT=/usr/share/fbiterm/fonts/b16.pcf.gz
|
||
export CONSOLE_FONT=/usr/share/kbd/consolefonts/default8x16.gz
|
||
export HYBRID_PERSISTENT_FILENAME="Live OS's persistent storage.fs"
|
||
export HYBRID_PERSISTENT_FS=btrfs
|
||
export HYBRID_PERSISTENT_ID=83
|
||
export HYBRID_PERSISTENT_DIR=/read-write
|
||
export UTIMER_INFO=/dev/utimer
|
||
export bootLoaderOK=0
|
||
export enablePlymouth=1
|
||
export IFS_ORIG=$IFS
|
||
export MEDIACHECK_OK_TIMER=5
|
||
export partitionerWriteStatus=0
|
||
|
||
#======================================
|
||
# lookup
|
||
#--------------------------------------
|
||
function lookup {
|
||
bash -c "PATH=$PATH:/sbin:/usr/sbin:/bin:/usr/bin type -p $1"
|
||
}
|
||
|
||
#======================================
|
||
# Exports (hybrid filesystem options)
|
||
#--------------------------------------
|
||
# Optimized for 512kB erase block size
|
||
export HYBRID_EXT4_OPTS="-b 4096 -O ^has_journal -E stride=128,stripe-width=128"
|
||
|
||
#======================================
|
||
# Exports (console)
|
||
#--------------------------------------
|
||
test -z "$ELOG_BOOTSHELL" && export ELOG_BOOTSHELL=/dev/tty2
|
||
test -z "$ELOG_EXCEPTION" && export ELOG_EXCEPTION=/dev/console
|
||
|
||
#======================================
|
||
# Exports (General)
|
||
#--------------------------------------
|
||
test -z "$RECOVERY_THEME" && export RECOVERY_THEME=openSUSE
|
||
test -z "$arch" && export arch=$(uname -m)
|
||
test -z "$haveDASD" && export haveDASD=0
|
||
test -z "$haveZFCP" && export haveZFCP=0
|
||
test -z "$ELOG_STOPPED" && export ELOG_STOPPED=0
|
||
test -z "$PARTITIONER" && export PARTITIONER=parted
|
||
test -z "$DEFAULT_VGA" && export DEFAULT_VGA=0x314
|
||
test -z "$HAVE_MODULES_ORDER" && export HAVE_MODULES_ORDER=1
|
||
test -z "$DIALOG_LANG" && export DIALOG_LANG=ask
|
||
test -z "$TERM" && export TERM=linux
|
||
test -z "$LANG" && export LANG=en_US.utf8
|
||
test -z "$UTIMER" && export UTIMER=0
|
||
test -z "$PARTED_HAVE_ALIGN" && export PARTED_HAVE_ALIGN=0
|
||
test -z "$PARTED_HAVE_MACHINE"&& export PARTED_HAVE_MACHINE=0
|
||
test -z "$DHCPCD_HAVE_PERSIST"&& export DHCPCD_HAVE_PERSIST=1
|
||
if lookup parted &>/dev/null;then
|
||
if parted -h | grep -q '\-\-align';then
|
||
export PARTED_HAVE_ALIGN=1
|
||
fi
|
||
if parted -h | grep -q '\-\-machine';then
|
||
export PARTED_HAVE_MACHINE=1
|
||
fi
|
||
if [ $PARTED_HAVE_MACHINE -eq 0 ];then
|
||
export PARTITIONER=unsupported
|
||
fi
|
||
fi
|
||
if lookup dhcpcd &>/dev/null;then
|
||
if dhcpcd -p 2>&1 | grep -q 'Usage';then
|
||
export DHCPCD_HAVE_PERSIST=0
|
||
fi
|
||
fi
|
||
|
||
#======================================
|
||
# Exports (arch specific)
|
||
#--------------------------------------
|
||
if [[ $arch =~ ppc64 ]];then
|
||
test -z "$loader" && export loader=grub2
|
||
elif [[ $arch =~ arm ]];then
|
||
test -z "$loader" && export loader=grub2
|
||
elif [[ $arch =~ s390 ]];then
|
||
test -z "$loader" && export loader=zipl
|
||
else
|
||
test -z "$loader" && export loader=grub2
|
||
fi
|
||
|
||
#======================================
|
||
# Exports boot options
|
||
#--------------------------------------
|
||
failsafe="ide=nodma apm=off noresume edd=off"
|
||
failsafe="$failsafe powersaved=off nohz=off"
|
||
failsafe="$failsafe highres=off processsor.max+cstate=1"
|
||
failsafe="$failsafe nomodeset x11failsafe"
|
||
|
||
#======================================
|
||
# hideSplash
|
||
#--------------------------------------
|
||
function hideSplash {
|
||
# /.../
|
||
# Hides the splash screen for to allow interactive
|
||
# dialog sessions on this console. Also, the user can
|
||
# control a custom behavior using the handleSplash
|
||
# hook called at the end of this function
|
||
# ----
|
||
local IFS=$IFS_ORIG
|
||
test -e /proc/splash && echo verbose > /proc/splash
|
||
if lookup plymouthd &>/dev/null;then
|
||
plymouth hide-splash
|
||
# reset tty after plymouth messed with it
|
||
consoleInit
|
||
fi
|
||
runHook handleSplash "$@"
|
||
}
|
||
#======================================
|
||
# Debug
|
||
#--------------------------------------
|
||
function Debug {
|
||
# /.../
|
||
# print message if variable DEBUG is set to 1
|
||
# -----
|
||
local IFS=$IFS_ORIG
|
||
if test "$DEBUG" = 1;then
|
||
echo "+++++> $1"
|
||
fi
|
||
}
|
||
#======================================
|
||
# Echo
|
||
#--------------------------------------
|
||
function Echo {
|
||
# /.../
|
||
# print a message to the controling terminal
|
||
# ----
|
||
local IFS=$IFS_ORIG
|
||
if [ $ELOG_STOPPED = 0 ];then
|
||
set +x
|
||
fi
|
||
if [ ! $UTIMER = 0 ] && kill -0 $UTIMER &>/dev/null;then
|
||
kill -HUP $UTIMER
|
||
local prefix=$(cat $UTIMER_INFO)
|
||
else
|
||
local prefix="===>"
|
||
fi
|
||
local option=""
|
||
local optn=""
|
||
local opte=""
|
||
while getopts "bne" option;do
|
||
case $option in
|
||
b) prefix=" " ;;
|
||
n) optn="-n" ;;
|
||
e) opte="-e" ;;
|
||
*) echo "Invalid argument: $option" ;;
|
||
esac
|
||
done
|
||
shift $(($OPTIND - 1))
|
||
if [ $ELOG_STOPPED = 0 ];then
|
||
set -x
|
||
fi
|
||
echo $optn $opte "$prefix $1"
|
||
if [ $ELOG_STOPPED = 0 ];then
|
||
set +x
|
||
fi
|
||
OPTIND=1
|
||
if [ $ELOG_STOPPED = 0 ];then
|
||
set -x
|
||
fi
|
||
}
|
||
#======================================
|
||
# WaitKey
|
||
#--------------------------------------
|
||
function WaitKey {
|
||
# /.../
|
||
# if DEBUG is set wait for ENTER to continue
|
||
# ----
|
||
local IFS=$IFS_ORIG
|
||
if test "$DEBUG" = 1;then
|
||
Echo -n "Press ENTER to continue..."
|
||
read
|
||
fi
|
||
}
|
||
#======================================
|
||
# importFile
|
||
#--------------------------------------
|
||
function importFile {
|
||
# /.../
|
||
# import the config.<MAC> style format. the function
|
||
# will export each entry of the file as variable into
|
||
# the current shell environment
|
||
# ----
|
||
local IFS=$IFS_ORIG
|
||
local prefix=$1
|
||
# create clean input, no empty lines and comments
|
||
cat - | grep -v '^$' | grep -v '^[ \t]*#' > /tmp/srcme
|
||
# remove start/stop quoting from values
|
||
sed -i -e s"#\(^[a-zA-Z0-9_]\+\)=[\"']\(.*\)[\"']#\1=\2#" /tmp/srcme
|
||
# remove backslash quotes if any
|
||
sed -i -e s"#\\\\\(.\)#\1#g" /tmp/srcme
|
||
# quote simple quotation marks
|
||
sed -i -e s"#'\+#'\\\\''#g" /tmp/srcme
|
||
# add '...' quoting to values
|
||
sed -i -e s"#\(^[a-zA-Z0-9_]\+\)=\(.*\)#$prefix\1='\2'#" /tmp/srcme
|
||
source /tmp/srcme &>/dev/null
|
||
while read line;do
|
||
key=$(echo "$line" | cut -d '=' -f1)
|
||
eval "export $key" &>/dev/null
|
||
done < /tmp/srcme
|
||
if [ ! -z "$ERROR_INTERRUPT" ];then
|
||
Echo -e "$ERROR_INTERRUPT"
|
||
systemException "*** interrupted ****" "shell"
|
||
fi
|
||
}
|
||
#======================================
|
||
# unsetFile
|
||
#--------------------------------------
|
||
function unsetFile {
|
||
# /.../
|
||
# unset variables specified within the given file.
|
||
# the file must be in the config.<MAC> style format
|
||
# ----
|
||
local IFS="
|
||
"
|
||
local prefix=$1 #change name of key with a prefix
|
||
while read line;do
|
||
echo $line | grep -qi "^#" && continue
|
||
key=`echo "$line" | cut -d '=' -f1`
|
||
if [ -z "$key" ];then
|
||
continue
|
||
fi
|
||
Debug "unset $prefix$key"
|
||
eval unset "$prefix$key"
|
||
done
|
||
}
|
||
#======================================
|
||
# condenseConfigData
|
||
#--------------------------------------
|
||
function condenseConfigData {
|
||
# /.../
|
||
# if multiple same config files (config files with same deployment path)
|
||
# are present on the CONF line,
|
||
# only last one will be kept (this preserves compatibility)
|
||
# ----
|
||
local IFS=","
|
||
local conf=( $1 )
|
||
local cconf
|
||
local sep=''
|
||
for (( i=0; i<${#conf[@]}; i++ ));do
|
||
local configDest=`echo "${conf[$i]}" | cut -d ';' -f 2`
|
||
if test ! -z $configDest;then
|
||
local copythis=1
|
||
for (( j=i+1; j<${#conf[@]}; j++ ));do
|
||
local cmpconfigDest=`echo "${conf[$j]}" | cut -d ';' -f 2`
|
||
if [ "$cmpconfigDest" = "$configDest" ];then
|
||
copythis=0
|
||
break
|
||
fi
|
||
done
|
||
[ $copythis -eq '1' ] && cconf="${cconf}${sep}${conf[$i]}"
|
||
sep=$IFS
|
||
fi
|
||
done
|
||
echo "$cconf"
|
||
}
|
||
#======================================
|
||
# systemException
|
||
#--------------------------------------
|
||
function systemException {
|
||
# /.../
|
||
# print a message to the controling terminal followed
|
||
# by an action. Possible actions are reboot, wait, shutdown,
|
||
# and opening a shell
|
||
# ----
|
||
local IFS=$IFS_ORIG
|
||
set +x
|
||
local what=$2
|
||
local nuldev=/dev/null
|
||
local ttydev=$ELOG_EXCEPTION
|
||
local prefix=/mnt
|
||
for dev in $nuldev $prefix/$nuldev; do
|
||
if [ -e $dev ];then
|
||
nuldev=$dev; break
|
||
fi
|
||
done
|
||
for dev in $ttydev $prefix/$ttydev; do
|
||
if [ -e $dev ];then
|
||
ttydev=$dev; break
|
||
fi
|
||
done
|
||
hideSplash
|
||
if lookup plymouthd &>/dev/null && [ $enablePlymouth -eq 1 ]; then
|
||
plymouth quit
|
||
fi
|
||
if [ $what = "reboot" ];then
|
||
if cat /proc/cmdline 2>/dev/null | grep -qi "kiwidebug=1";then
|
||
what="shell"
|
||
fi
|
||
fi
|
||
runHook preException "$@"
|
||
Echo -e "$1"
|
||
case "$what" in
|
||
"reboot")
|
||
# in order to see all log information in case of a reboot exception
|
||
# we print the current log contents to the console. On systems like
|
||
# public clouds the console information is stored and provided to
|
||
# the user. Thus it makes sense to be verbose here
|
||
cat $ELOG_FILE
|
||
Echo "rebootException: reboot in 120 sec..."; sleep 120
|
||
/sbin/reboot -f -i >$nuldev
|
||
;;
|
||
"wait")
|
||
Echo "waitException: waiting for ever..."
|
||
while true;do sleep 100;done
|
||
;;
|
||
"waitkey")
|
||
Echo "waitException: Press any key to continue: "
|
||
read
|
||
;;
|
||
"shell")
|
||
if [ ! -z "$DROPBEAR_PID" ] && [ ! -z "$IPADDR" ];then
|
||
Echo "You can connect via ssh to this system"
|
||
Echo "ssh root@${IPADDR}"
|
||
fi
|
||
echo reset > /root/.bashrc
|
||
sulogin -e -p $ttydev
|
||
;;
|
||
"user_reboot")
|
||
Echo "reboot triggered by user"
|
||
Echo "reboot in 30 sec..."; sleep 30
|
||
/sbin/reboot -f -i >$nuldev
|
||
;;
|
||
*)
|
||
Echo "unknownException..."
|
||
;;
|
||
esac
|
||
}
|
||
#======================================
|
||
# copyDevices
|
||
#--------------------------------------
|
||
function copyDeviceNodes {
|
||
local IFS=$IFS_ORIG
|
||
local search=$1
|
||
local prefix=$2
|
||
local dtype
|
||
local major
|
||
local minor
|
||
local perms
|
||
if [ -z "$search" ];then
|
||
search=/dev
|
||
fi
|
||
pushd $search >/dev/null
|
||
for i in *;do
|
||
if [ -e $prefix/$i ];then
|
||
continue
|
||
fi
|
||
if [ -b $i ];then
|
||
dtype=b
|
||
elif [ -c $i ];then
|
||
dtype=c
|
||
elif [ -p $i ];then
|
||
dtype=p
|
||
else
|
||
continue
|
||
fi
|
||
info=`stat $i -c "0%a:0x%t:0x%T"`
|
||
major=`echo $info | cut -f2 -d:`
|
||
minor=`echo $info | cut -f3 -d:`
|
||
perms=`echo $info | cut -f1 -d:`
|
||
if [ $dtype = "p" ];then
|
||
mknod -m $perms $prefix/$i $dtype
|
||
else
|
||
mknod -m $perms $prefix/$i $dtype $major $minor
|
||
fi
|
||
done
|
||
popd >/dev/null
|
||
}
|
||
#======================================
|
||
# createInitialDevices
|
||
#--------------------------------------
|
||
function createInitialDevices {
|
||
local IFS=$IFS_ORIG
|
||
local prefix=$1
|
||
#======================================
|
||
# create master dev dir
|
||
#--------------------------------------
|
||
mkdir -p $prefix
|
||
if [ ! -d $prefix ];then
|
||
return
|
||
fi
|
||
#======================================
|
||
# mount devtmpfs or tmpfs
|
||
#--------------------------------------
|
||
if mount -t devtmpfs -o mode=0755,nr_inodes=0 devtmpfs $prefix; then
|
||
export have_devtmpfs=true
|
||
else
|
||
export have_devtmpfs=false
|
||
mount -t tmpfs -o mode=0755,nr_inodes=0 udev $prefix
|
||
mknod -m 0666 $prefix/tty c 5 0
|
||
mknod -m 0600 $prefix/console c 5 1
|
||
mknod -m 0666 $prefix/ptmx c 5 2
|
||
mknod -m 0666 $prefix/null c 1 3
|
||
mknod -m 0600 $prefix/kmsg c 1 11
|
||
mknod -m 0660 $prefix/snapshot c 10 231
|
||
mknod -m 0666 $prefix/random c 1 8
|
||
mknod -m 0644 $prefix/urandom c 1 9
|
||
fi
|
||
#======================================
|
||
# mount shared mem tmpfs
|
||
#--------------------------------------
|
||
mkdir -m 1777 $prefix/shm
|
||
mount -t tmpfs -o mode=1777 tmpfs $prefix/shm
|
||
#======================================
|
||
# mount udev db tmpfs
|
||
#--------------------------------------
|
||
mkdir -p -m 0755 /run
|
||
mkdir -p -m 0755 /var/run
|
||
if [[ ! $kiwi_initrdname =~ SLE.11 ]] && \
|
||
[[ ! $kiwi_initrdname =~ "rhel-06" ]]
|
||
then
|
||
mount -t tmpfs -o mode=0755,nodev,nosuid tmpfs /run
|
||
mount --bind /run /var/run
|
||
fi
|
||
#======================================
|
||
# mount devpts tmpfs
|
||
#--------------------------------------
|
||
mkdir -m 0755 $prefix/pts
|
||
mount -t devpts -o mode=0620,gid=5 devpts $prefix/pts
|
||
#======================================
|
||
# link default descriptors
|
||
#--------------------------------------
|
||
ln -s /proc/self/fd $prefix/fd
|
||
ln -s fd/0 $prefix/stdin
|
||
ln -s fd/1 $prefix/stdout
|
||
ln -s fd/2 $prefix/stderr
|
||
#======================================
|
||
# create directories in /run
|
||
#--------------------------------------
|
||
mkdir -p -m 0755 /run/lock
|
||
mkdir -p -m 0755 /run/log
|
||
}
|
||
#======================================
|
||
# mount_rpc_pipefs
|
||
#--------------------------------------
|
||
function mount_rpc_pipefs {
|
||
local IFS=$IFS_ORIG
|
||
# See if the file system is there yet
|
||
if [ ! -e /var/lib/nfs/rpc_pipefs ];then
|
||
return 0
|
||
fi
|
||
case `stat -c "%t" -f /var/lib/nfs/rpc_pipefs 2>/dev/null` in
|
||
*67596969*)
|
||
return 0;;
|
||
esac
|
||
mount -t rpc_pipefs rpc_pipefs /var/lib/nfs/rpc_pipefs
|
||
}
|
||
#======================================
|
||
# umount_rpc_pipefs
|
||
#--------------------------------------
|
||
function umount_rpc_pipefs {
|
||
local IFS=$IFS_ORIG
|
||
# See if the file system is there
|
||
case `stat -c "%t" -f /var/lib/nfs/rpc_pipefs 2>/dev/null` in
|
||
*67596969*)
|
||
umount /var/lib/nfs/rpc_pipefs
|
||
esac
|
||
}
|
||
#======================================
|
||
# setupNFSServices
|
||
#--------------------------------------
|
||
function setupNFSServices {
|
||
local IFS=$IFS_ORIG
|
||
mount_rpc_pipefs
|
||
if [ -x /sbin/rpcbind ];then
|
||
startproc /sbin/rpcbind
|
||
fi
|
||
if [ -x /usr/sbin/rpc.statd ];then
|
||
startproc /usr/sbin/rpc.statd --no-notify
|
||
fi
|
||
if [ -x /usr/sbin/rpc.idmapd ];then
|
||
startproc /usr/sbin/rpc.idmapd
|
||
fi
|
||
}
|
||
#======================================
|
||
# mountSystemFilesystems
|
||
#--------------------------------------
|
||
function mountSystemFilesystems {
|
||
local IFS=$IFS_ORIG
|
||
if [ ! -e /proc/cmdline ];then
|
||
mount -t proc proc /proc
|
||
fi
|
||
if [ ! -e /sys/kernel ];then
|
||
mount -t sysfs sysfs /sys
|
||
fi
|
||
if [ -e /run/initramfs/shutdown ];then
|
||
chmod u+x /run/initramfs/shutdown
|
||
fi
|
||
updateMTAB
|
||
}
|
||
#======================================
|
||
# umountSystemFilesystems
|
||
#--------------------------------------
|
||
function umountSystemFilesystems {
|
||
local IFS=$IFS_ORIG
|
||
umount_rpc_pipefs
|
||
umount /dev/pts &>/dev/null
|
||
umount /sys &>/dev/null
|
||
umount /proc &>/dev/null
|
||
}
|
||
#======================================
|
||
# createFramebufferDevices
|
||
#--------------------------------------
|
||
function createFramebufferDevices {
|
||
local IFS=$IFS_ORIG
|
||
if [ -f /proc/fb ]; then
|
||
while read fbnum fbtype; do
|
||
if [ $(($fbnum < 32)) ] ; then
|
||
if [ ! -c /dev/fb$fbnum ];then
|
||
Echo "Creating framebuffer device: /dev/fb$fbnum"
|
||
mknod -m 0660 /dev/fb$fbnum c 29 $fbnum
|
||
fi
|
||
fi
|
||
done < /proc/fb
|
||
fi
|
||
}
|
||
#======================================
|
||
# errorLogStop
|
||
#--------------------------------------
|
||
function errorLogStop {
|
||
local IFS=$IFS_ORIG
|
||
set +x
|
||
export ELOG_STOPPED=1
|
||
exec < $ELOG_EXCEPTION &> $ELOG_EXCEPTION
|
||
}
|
||
#======================================
|
||
# errorLogContinue
|
||
#--------------------------------------
|
||
function errorLogContinue {
|
||
local IFS=$IFS_ORIG
|
||
exec 2>>$ELOG_FILE
|
||
exec < $ELOG_EXCEPTION > $ELOG_EXCEPTION
|
||
export ELOG_STOPPED=0
|
||
set -x
|
||
}
|
||
#======================================
|
||
# errorLogStart
|
||
#--------------------------------------
|
||
function errorLogStart {
|
||
# /.../
|
||
# Log all errors and the debug information to the
|
||
# file set in ELOG_FILE.
|
||
# ----
|
||
local IFS=$IFS_ORIG
|
||
local umountProc=0
|
||
if [ ! -f $ELOG_FILE ];then
|
||
#======================================
|
||
# Header for main stage log
|
||
#--------------------------------------
|
||
echo "KIWI Log:" >> $ELOG_FILE
|
||
else
|
||
#======================================
|
||
# Header for pre-init stage log
|
||
#--------------------------------------
|
||
startUtimer
|
||
echo "KIWI PreInit Log" >> $ELOG_FILE
|
||
fi
|
||
#======================================
|
||
# Contents of .profile environment
|
||
#--------------------------------------
|
||
if [ -f .profile ];then
|
||
echo "KIWI .profile contents:" >> $ELOG_FILE
|
||
cat .profile >> $ELOG_FILE
|
||
fi
|
||
#======================================
|
||
# Redirect stderr to ELOG_FILE
|
||
#--------------------------------------
|
||
exec 2>>$ELOG_FILE
|
||
#======================================
|
||
# Mount proc for cmdline quiet check
|
||
#--------------------------------------
|
||
if [ ! -e /proc/cmdline ];then
|
||
mount -t proc proc /proc
|
||
umountProc=1
|
||
fi
|
||
if cat /proc/cmdline | grep -qi "quiet";then
|
||
#======================================
|
||
# Redirect/Clean stdout if quiet is set
|
||
#--------------------------------------
|
||
if [ -x /usr/bin/setterm ];then
|
||
setterm -clear all
|
||
setterm -background black
|
||
fi
|
||
exec >/dev/null
|
||
else
|
||
#======================================
|
||
# Redirect stdout to console
|
||
#--------------------------------------
|
||
exec < $ELOG_EXCEPTION > $ELOG_EXCEPTION
|
||
fi
|
||
#======================================
|
||
# Clean proc
|
||
#--------------------------------------
|
||
if [ $umountProc -eq 1 ];then
|
||
umount /proc &>/dev/null
|
||
fi
|
||
#======================================
|
||
# Enable shell debugging
|
||
#--------------------------------------
|
||
set -x
|
||
}
|
||
#======================================
|
||
# udevPending
|
||
#--------------------------------------
|
||
function udevPending {
|
||
local IFS=$IFS_ORIG
|
||
local umountProc=0
|
||
if [ ! -e /proc/cmdline ];then
|
||
mount -t proc proc /proc
|
||
umountProc=1
|
||
fi
|
||
local timeout=30
|
||
local udevadmExec=$(lookup udevadm 2>/dev/null)
|
||
if [ -x $udevadmExec ];then
|
||
$udevadmExec settle --timeout=$timeout
|
||
else
|
||
# udevsettle exists on old distros and is not
|
||
# affected by the move from sbin to usr
|
||
/sbin/udevsettle --timeout=$timeout
|
||
fi
|
||
if [ $umountProc -eq 1 ];then
|
||
umount /proc
|
||
fi
|
||
}
|
||
#======================================
|
||
# udevTrigger
|
||
#--------------------------------------
|
||
function udevTrigger {
|
||
local IFS=$IFS_ORIG
|
||
local udevadmExec=$(lookup udevadm 2>/dev/null)
|
||
if [ -x $udevadmExec ];then
|
||
$udevadmExec trigger
|
||
else
|
||
/sbin/udevtrigger
|
||
fi
|
||
}
|
||
#======================================
|
||
# udevSystemStart
|
||
#--------------------------------------
|
||
function udevSystemStart {
|
||
# /.../
|
||
# start udev daemon
|
||
# ----
|
||
local IFS=$IFS_ORIG
|
||
local udev_bin=/usr/lib/systemd/systemd-udevd
|
||
if [ ! -x $udev_bin ];then
|
||
udev_bin=/sbin/udevd
|
||
fi
|
||
if [ ! -x $udev_bin ];then
|
||
udev_bin=/lib/udev/udevd
|
||
fi
|
||
if [ ! -x $udev_bin ];then
|
||
udev_bin=/lib/systemd/systemd-udevd
|
||
fi
|
||
if [ ! -x $udev_bin ];then
|
||
systemException \
|
||
"Can't find udev daemon" \
|
||
"reboot"
|
||
fi
|
||
$udev_bin --daemon
|
||
export UDEVD_PID=$(pidof $udev_bin | tr ' ' ,)
|
||
}
|
||
#======================================
|
||
# udevSystemStop
|
||
#--------------------------------------
|
||
function udevSystemStop {
|
||
# /.../
|
||
# stop udev while in pre-init phase.
|
||
# ----
|
||
local IFS=$IFS_ORIG
|
||
local udevadmExec=$(lookup udevadm 2>/dev/null)
|
||
local umountProc=0
|
||
if [ ! -e "/proc/mounts" ];then
|
||
mount -t proc proc /proc
|
||
umountProc=1
|
||
fi
|
||
if [ -x $udevadmExec ];then
|
||
# ignore error messages here, because if the process is not
|
||
# stopped properly here, it will be killed the hard way a few
|
||
# lines down
|
||
$udevadmExec control --exit &>/dev/null
|
||
fi
|
||
if [ -z "$UDEVD_PID" ];then
|
||
. /iprocs
|
||
fi
|
||
local IFS=,
|
||
for p in $UDEVD_PID; do
|
||
if kill -0 $p &>/dev/null;then
|
||
udevPending
|
||
kill $p
|
||
fi
|
||
done
|
||
if [ $umountProc -eq 1 ];then
|
||
umount /proc
|
||
fi
|
||
}
|
||
#======================================
|
||
# udevStart
|
||
#--------------------------------------
|
||
function udevStart {
|
||
# /.../
|
||
# start the udev daemon.
|
||
# ----
|
||
local IFS=$IFS_ORIG
|
||
local enableFips=0
|
||
#======================================
|
||
# Check time according to build day
|
||
#--------------------------------------
|
||
if [ -f /build_day ];then
|
||
importFile < /build_day
|
||
current_day="$(LC_ALL=C date -u '+%Y%m%d')"
|
||
if [ "$current_day" -lt "$build_day" ] ; then
|
||
LC_ALL=C date -us "$build_day"
|
||
sleep 3
|
||
export SYSTEM_TIME_INCORRECT=$current_day
|
||
fi
|
||
fi
|
||
#======================================
|
||
# Check for modules.order
|
||
#--------------------------------------
|
||
if ! ls /lib/modules/*/modules.order &>/dev/null;then
|
||
# /.../
|
||
# without modules.order in place we prevent udev from loading
|
||
# the storage modules because it does not make a propper
|
||
# choice if there are multiple possible modules available.
|
||
# Example:
|
||
# udev prefers ata_generic over ata_piix but the hwinfo
|
||
# order is ata_piix first which also seems to make more
|
||
# sense.
|
||
# -----
|
||
rm -f /etc/udev/rules.d/*-drivers.rules
|
||
rm -f /lib/udev/rules.d/*-drivers.rules
|
||
HAVE_MODULES_ORDER=0
|
||
fi
|
||
#======================================
|
||
# Start the daemon
|
||
#--------------------------------------
|
||
# static nodes
|
||
createInitialDevices /dev
|
||
# load modules required before udev
|
||
moduleLoadBeforeUdev
|
||
# start the udev daemon
|
||
udevSystemStart
|
||
echo UDEVD_PID=$UDEVD_PID >> /iprocs
|
||
# trigger events for all devices
|
||
udevTrigger
|
||
# wait for events to finish
|
||
udevPending
|
||
# init console
|
||
consoleInit
|
||
# start plymouth if it exists and enabled
|
||
for o in $(cat /proc/cmdline) ; do
|
||
case "$o" in
|
||
plymouth.enable=0*|rd.plymouth=0*)
|
||
enablePlymouth=0
|
||
;;
|
||
fips=1*)
|
||
enableFips=1
|
||
;;
|
||
esac
|
||
done
|
||
if [ $enablePlymouth -eq 1 ]; then
|
||
startPlymouth
|
||
fi
|
||
if [ $enableFips -eq 1 ];then
|
||
startHaveged
|
||
fi
|
||
}
|
||
#======================================
|
||
# moduleLoadBeforeUdev
|
||
#--------------------------------------
|
||
function moduleLoadBeforeUdev {
|
||
# /.../
|
||
# load modules which have to be loaded before the
|
||
# udev daemon is started in this function
|
||
# ----
|
||
loadAGPModules
|
||
}
|
||
#======================================
|
||
# loadAGPModules
|
||
#--------------------------------------
|
||
function loadAGPModules {
|
||
local IFS=$IFS_ORIG
|
||
local krunning=$(uname -r)
|
||
for i in /lib/modules/$krunning/kernel/drivers/char/agp/*; do
|
||
test -e $i || continue
|
||
modprobe $(echo $i | sed "s#.*\\/\\([^\\/]\\+\\).ko#\\1#")
|
||
done
|
||
}
|
||
#======================================
|
||
# udevKill
|
||
#--------------------------------------
|
||
function udevKill {
|
||
local IFS=$IFS_ORIG
|
||
udevSystemStop
|
||
}
|
||
#======================================
|
||
# activeConsoles
|
||
#--------------------------------------
|
||
function activeConsoles {
|
||
local IFS=$IFS_ORIG
|
||
for i in $(cat /sys/class/tty/console/active 2>/dev/null);do
|
||
echo $i
|
||
done | wc -l
|
||
}
|
||
#======================================
|
||
# consoleInit
|
||
#--------------------------------------
|
||
function consoleInit {
|
||
local IFS=$IFS_ORIG
|
||
local udev_console=/lib/udev/console_init
|
||
if [ ! -x $udev_console ];then
|
||
udev_console=/lib/udev/console-setup-tty
|
||
fi
|
||
local systemd_console=/usr/lib/systemd/systemd-vconsole-setup
|
||
if [ -x $udev_console ];then
|
||
$udev_console /dev/console
|
||
elif [ -x $systemd_console ];then
|
||
$systemd_console
|
||
fi
|
||
}
|
||
#======================================
|
||
# startPlymouth
|
||
#--------------------------------------
|
||
function startPlymouth {
|
||
local IFS=$IFS_ORIG
|
||
local consoledev
|
||
if lookup plymouthd &>/dev/null;then
|
||
# first trigger graphics subsystem
|
||
udevadm trigger --action=add --attr-match=class=0x030000 &>/dev/null
|
||
# next trigger graphics and tty subsystem
|
||
udevadm trigger --action=add --subsystem-match=graphics \
|
||
--subsystem-match=drm --subsystem-match=tty &>/dev/null
|
||
udevadm settle --timeout=30
|
||
mkdir --mode 755 /run/plymouth
|
||
consoleInit
|
||
plymouth-set-default-theme $kiwi_splash_theme &>/dev/null
|
||
plymouthd --attach-to-session --pid-file /run/plymouth/pid &>/dev/null
|
||
plymouth show-splash &>/dev/null
|
||
# reset tty after plymouth messed with it
|
||
consoleInit
|
||
fi
|
||
}
|
||
#======================================
|
||
# startHaveged
|
||
#--------------------------------------
|
||
function startHaveged {
|
||
if ! lookup haveged &>/dev/null; then
|
||
systemException \
|
||
"haveged is missing but required for fips" \
|
||
"reboot"
|
||
fi
|
||
|
||
if ! haveged; then
|
||
systemException \
|
||
"Failed to start haveged required for fips" \
|
||
"reboot"
|
||
fi
|
||
}
|
||
#======================================
|
||
# startDropBear
|
||
#--------------------------------------
|
||
function startDropBear {
|
||
# /.../
|
||
# start dropbear ssh server if installed
|
||
# ---
|
||
local IFS=$IFS_ORIG
|
||
local auth_keys="/root/.ssh/authorized_keys"
|
||
if [ -z "$kiwidebug" ];then
|
||
return
|
||
fi
|
||
if lookup dropbear &>/dev/null;then
|
||
mkdir -p /root/.ssh
|
||
fetchFile KIWI/debug_ssh.pub $auth_keys
|
||
if [ ! -e $auth_keys ]; then
|
||
return
|
||
fi
|
||
mkdir -p /etc/dropbear
|
||
if [ ! -f /etc/dropbear/dropbear_dss_host_key ];then
|
||
dropbearkey -t dss -f /etc/dropbear/dropbear_dss_host_key
|
||
fi
|
||
if [ ! -f /etc/dropbear/dropbear_rsa_host_key ];then
|
||
dropbearkey -t rsa -f /etc/dropbear/dropbear_rsa_host_key
|
||
fi
|
||
Echo "Starting dropbear ssh server"
|
||
dropbear
|
||
export DROPBEAR_PID=$(pidof /usr/sbin/dropbear)
|
||
echo DROPBEAR_PID=$DROPBEAR_PID >> /iprocs
|
||
fi
|
||
}
|
||
#======================================
|
||
# readVolumeSetup
|
||
#--------------------------------------
|
||
function readVolumeSetup {
|
||
# /.../
|
||
# read the volume setup from the profile file and return
|
||
# a list with the following values:
|
||
#
|
||
# volume_name,resize_mode,requested_size,mount_point ...
|
||
# ----
|
||
local profile=$1
|
||
local skip_all_free_volume=$2
|
||
local volume
|
||
local name
|
||
local mode
|
||
local size
|
||
local mpoint
|
||
local result
|
||
for i in $(cat $profile | grep -E "kiwi_Volume_");do
|
||
volume=$(echo $i | cut -f2 -d= | tr -d \' | tr -d \")
|
||
size=$(echo $volume | cut -f2 -d\| | cut -f2 -d:)
|
||
if [ $size = "all" ] && [ ! -z "$skip_all_free_volume" ];then
|
||
continue
|
||
fi
|
||
mode=$(echo $volume | cut -f2 -d\| | cut -f1 -d:)
|
||
name=$(echo $volume | cut -f1 -d\|)
|
||
mpoint=$(echo $volume | cut -f3 -d\|)
|
||
if [ -z "$mpoint" ];then
|
||
mpoint='noop'
|
||
fi
|
||
if [ -z "$result" ];then
|
||
result="$name,$mode,$size,$mpoint"
|
||
else
|
||
result="$result $name,$mode,$size,$mpoint"
|
||
fi
|
||
done
|
||
echo $result
|
||
}
|
||
#======================================
|
||
# readVolumeSetupAllFree
|
||
#--------------------------------------
|
||
function readVolumeSetupAllFree {
|
||
# /.../
|
||
# read the volume setup for kiwi_allFreeVolume from the profile
|
||
# file and return a list with the following values:
|
||
#
|
||
# volume_name,mount_point
|
||
#
|
||
# If no kiwi_allFreeVolume was configured only the default
|
||
# volume_name which takes the rest space is returned
|
||
# ----
|
||
local profile=$1
|
||
local size
|
||
local volume
|
||
local name
|
||
local mpoint
|
||
for i in $(cat $profile | grep -E "kiwi_Volume_");do
|
||
volume=$(echo $i | cut -f2 -d= | tr -d \' | tr -d \")
|
||
size=$(echo $volume | cut -f2 -d\| | cut -f2 -d:)
|
||
if [ $size = "all" ];then
|
||
name=$(echo $volume | cut -f1 -d\|)
|
||
mpoint=$(echo $volume | cut -f3 -d\|)
|
||
echo "$name,$mpoint"
|
||
return
|
||
fi
|
||
done
|
||
echo LVRoot,
|
||
}
|
||
#======================================
|
||
# getVolumeName
|
||
#--------------------------------------
|
||
function getVolumeName {
|
||
echo $1 | cut -f1 -d,
|
||
}
|
||
#======================================
|
||
# getVolumeMountPoint
|
||
#--------------------------------------
|
||
function getVolumeMountPoint {
|
||
echo $1 | cut -f4 -d,
|
||
}
|
||
#======================================
|
||
# getVolumeSizeMode
|
||
#--------------------------------------
|
||
function getVolumeSizeMode {
|
||
echo $1 | cut -f2 -d,
|
||
}
|
||
#======================================
|
||
# getVolumeSize
|
||
#--------------------------------------
|
||
function getVolumeSize {
|
||
echo $1 | cut -f3 -d,
|
||
}
|
||
#======================================
|
||
# installBootLoader
|
||
#--------------------------------------
|
||
function installBootLoader {
|
||
# /.../
|
||
# generic function to install the boot loader.
|
||
# The selection of the bootloader happens according to
|
||
# the architecture of the system
|
||
# ----
|
||
local IFS=$IFS_ORIG
|
||
local arch=$(uname -m)
|
||
runHook preInstallBootLoader
|
||
case $arch-$loader in
|
||
i*86-grub2) installBootLoaderGrub2 ;;
|
||
s390*-grub2) installBootLoaderGrub2 ;;
|
||
x86_64-grub2) installBootLoaderGrub2 ;;
|
||
ppc64*-grub2) installBootLoaderGrub2 ;;
|
||
s390-zipl) installBootLoaderS390 ;;
|
||
s390x-zipl) installBootLoaderS390 ;;
|
||
s390x-grub2_s390x_emu) installBootLoaderS390Grub ;;
|
||
aarch64-grub2) installBootLoaderGrub2 ;;
|
||
*)
|
||
systemException \
|
||
"*** boot loader install for $arch-$loader not implemented ***" \
|
||
"reboot"
|
||
esac
|
||
#
|
||
# Warning message is disabled because sometimes the message
|
||
# can't be displayed on the console which leads to a stopped
|
||
# system but the user has no clue why
|
||
#
|
||
#if [ ! $? = 0 ];then
|
||
# if lookup dialog &>/dev/null;then
|
||
# Dialog \
|
||
# --backtitle \"$TEXT_BOOT_SETUP_FAILED\" \
|
||
# --msgbox "\"$TEXT_BOOT_SETUP_FAILED_INFO\"" 10 70
|
||
# else
|
||
# systemException \
|
||
# "$TEXT_BOOT_SETUP_FAILED\n\n$TEXT_BOOT_SETUP_FAILED_INFO" \
|
||
# "waitkey"
|
||
# fi
|
||
#fi
|
||
case $arch in
|
||
i*386|x86_64)
|
||
masterBootID=$(printf 0x%04x%04x $RANDOM $RANDOM)
|
||
Echo "writing new MBR ID to master boot record: $masterBootID"
|
||
echo $masterBootID > /boot/mbrid
|
||
masterBootIDHex=$(echo $masterBootID |\
|
||
sed 's/^0x\(..\)\(..\)\(..\)\(..\)$/\\x\4\\x\3\\x\2\\x\1/')
|
||
echo -e -n $masterBootIDHex | dd of=$imageDiskDevice \
|
||
bs=1 count=4 seek=$((0x1b8))
|
||
;;
|
||
*)
|
||
echo "skiped writing MBR ID for $arch"
|
||
;;
|
||
esac
|
||
runHook postInstallBootLoader
|
||
}
|
||
#======================================
|
||
# installBootLoaderRecovery
|
||
#--------------------------------------
|
||
function installBootLoaderRecovery {
|
||
# /.../
|
||
# generic function to install the boot loader into
|
||
# the recovery partition. The selection of the bootloader
|
||
# happens according to the architecture of the system
|
||
# ----
|
||
local IFS=$IFS_ORIG
|
||
local arch=$(uname -m)
|
||
case $arch-$loader in
|
||
i*86-grub2) installBootLoaderGrub2Recovery ;;
|
||
x86_64-grub2) installBootLoaderGrub2Recovery ;;
|
||
s390*-grub2) installBootLoaderGrub2Recovery ;;
|
||
s390-zipl) installBootLoaderS390Recovery ;;
|
||
s390x-zipl) installBootLoaderS390Recovery ;;
|
||
*)
|
||
systemException \
|
||
"*** boot loader setup for $arch-$loader not implemented ***" \
|
||
"reboot"
|
||
esac
|
||
}
|
||
#======================================
|
||
# installBootLoaderS390Grub
|
||
#--------------------------------------
|
||
function installBootLoaderS390Grub {
|
||
# /.../
|
||
# Create/Delete
|
||
# - create active_devices.txt
|
||
# - delete kiwi initrd/kernel .vmx files
|
||
# Run grub2-mkconfig
|
||
# - create new boot/grub2/grub.cfg
|
||
# Run grub2-install
|
||
# - creates a new boot/zipl/config
|
||
# - creates zipl initrd which loads grub2/kexec
|
||
# - install zipl
|
||
# ----
|
||
local IFS=$IFS_ORIG
|
||
local confTool=grub2-mkconfig
|
||
local instTool=grub2-install
|
||
local confFile_grub=/boot/grub2/grub.cfg
|
||
local active_devs=/boot/zipl/active_devices.txt
|
||
local deviceID=$(cat /sys/firmware/ipl/device)
|
||
local instTooOptions
|
||
if [ "$kiwi_target_removable" = "true" ];then
|
||
instTooOptions="--removable"
|
||
fi
|
||
#======================================
|
||
# mount zipl EFI partition
|
||
#--------------------------------------
|
||
if [ ! -z "$kiwi_EfiPart" ];then
|
||
local jdev=$(ddn $imageDiskDevice $kiwi_EfiPart)
|
||
local label=$(blkid $jdev -s LABEL -o value)
|
||
if [ "$label" = "ZIPL" ];then
|
||
mkdir -p /boot/zipl
|
||
if ! mount $jdev /boot/zipl;then
|
||
Echo "Failed to mount zipl boot partition"
|
||
return 1
|
||
fi
|
||
fi
|
||
fi
|
||
#======================================
|
||
# Create active devices information
|
||
#--------------------------------------
|
||
echo $deviceID > $active_devs
|
||
#======================================
|
||
# create grub2 configuration
|
||
#--------------------------------------
|
||
if ! lookup $confTool &>/dev/null;then
|
||
Echo "System image doesn't provide $confTool"
|
||
Echo "Can't create bootloader configuration"
|
||
return 1
|
||
fi
|
||
$confTool > $confFile_grub
|
||
if [ ! $? = 0 ];then
|
||
Echo "Failed to create grub2 boot configuration"
|
||
return 1
|
||
fi
|
||
#======================================
|
||
# Run grub2-install
|
||
#--------------------------------------
|
||
if ! lookup $instTool &>/dev/null;then
|
||
Echo "System image doesn't provide $instTool"
|
||
Echo "Can't install bootloader"
|
||
return 1
|
||
fi
|
||
if ! $instTool $instTooOptions;then
|
||
Echo "Failed to install bootloader"
|
||
return 1
|
||
fi
|
||
#======================================
|
||
# Delete kiwi initrd files
|
||
#--------------------------------------
|
||
rm -f /boot/zipl/*.vmx
|
||
#======================================
|
||
# umount zipl boot partition
|
||
#--------------------------------------
|
||
mountpoint -q /boot/zipl && umount /boot/zipl
|
||
return 0
|
||
}
|
||
#======================================
|
||
# installBootLoaderS390
|
||
#--------------------------------------
|
||
function installBootLoaderS390 {
|
||
local IFS=$IFS_ORIG
|
||
if [ -x /sbin/zipl ];then
|
||
Echo "Installing boot loader..."
|
||
zipl -c /etc/zipl.conf 1>&2
|
||
if [ ! $? = 0 ];then
|
||
Echo "Failed to install boot loader"
|
||
return 1
|
||
fi
|
||
else
|
||
Echo "Image doesn't have zipl installed"
|
||
Echo "Can't install boot loader"
|
||
return 1
|
||
fi
|
||
return 0
|
||
}
|
||
#======================================
|
||
# installBootLoaderGrub2
|
||
#--------------------------------------
|
||
function installBootLoaderGrub2 {
|
||
# /.../
|
||
# configure and install grub2 according to the
|
||
# contents of /boot/grub2/grub.cfg
|
||
# ----
|
||
local IFS=$IFS_ORIG
|
||
local confTool=grub2-mkconfig
|
||
local instTool=grub2-install
|
||
local confFile_grub_bios=/boot/grub2/grub.cfg
|
||
local confFile_uefi=/boot/efi/EFI/BOOT/grub.cfg
|
||
local confFile_grub=$confFile_grub_bios
|
||
local bios_grub=/boot/grub2/i386-pc
|
||
local product=/etc/products.d/baseproduct
|
||
local grub_efi=/boot/efi/EFI/BOOT/grub.efi
|
||
local isEFI=0
|
||
local instTooOptions
|
||
if [ "$kiwi_target_removable" = "true" ];then
|
||
instTooOptions="--removable"
|
||
fi
|
||
#======================================
|
||
# check for EFI and mount EFI partition
|
||
#--------------------------------------
|
||
if [ ! -z "$kiwi_EfiPart" ];then
|
||
local jdev=$(ddn $imageDiskDevice $kiwi_EfiPart)
|
||
local label=$(blkid $jdev -s LABEL -o value)
|
||
if [ "$label" = "EFI" ];then
|
||
mkdir -p /boot/efi
|
||
if ! mount $jdev /boot/efi;then
|
||
Echo "Failed to mount EFI boot partition"
|
||
return 1
|
||
fi
|
||
isEFI=1
|
||
fi
|
||
fi
|
||
if ! lookup $confTool &>/dev/null;then
|
||
Echo "Image doesn't have grub2 installed"
|
||
Echo "Can't install boot loader"
|
||
return 1
|
||
fi
|
||
#======================================
|
||
# create grub2 configuration
|
||
#--------------------------------------
|
||
$confTool > $confFile_grub
|
||
if [ ! $? = 0 ];then
|
||
Echo "Failed to create grub2 boot configuration"
|
||
return 1
|
||
fi
|
||
if [ -e $confFile_grub_bios ];then
|
||
cp $confFile_grub $confFile_grub_bios
|
||
fi
|
||
if [ $isEFI -eq 1 ] && [ -e $confFile_uefi ];then
|
||
cp $confFile_grub $confFile_uefi
|
||
umount /boot/efi
|
||
fi
|
||
#======================================
|
||
# install grub2 in BIOS mode
|
||
#--------------------------------------
|
||
if [ ! -z "$kiwi_PrepPart" ];then
|
||
local prepdev=$(ddn $imageDiskDevice $kiwi_PrepPart)
|
||
# install powerpc grub2
|
||
$instTool $instTooOptions $prepdev 1>&2
|
||
if [ ! $? = 0 ];then
|
||
Echo "Failed to install boot loader"
|
||
return 1
|
||
fi
|
||
elif [ $isEFI -eq 0 ];then
|
||
# use plain grub2-install in standard bios mode
|
||
$instTool $instTooOptions $imageDiskDevice 1>&2
|
||
if [ ! $? = 0 ];then
|
||
Echo "Failed to install boot loader"
|
||
return 1
|
||
fi
|
||
elif [ ! -z "$kiwi_BiosGrub" ] && [ -d $bios_grub ];then
|
||
# force install of bios grub2 in efi legacy mode
|
||
$instTool $instTooOptions --force --target i386-pc $imageDiskDevice 1>&2
|
||
if [ ! $? = 0 ];then
|
||
Echo "Failed to install legacy boot loader"
|
||
return 1
|
||
fi
|
||
else
|
||
Echo "No bootloader installation required"
|
||
fi
|
||
return 0
|
||
}
|
||
#======================================
|
||
# installBootLoaderS390Recovery
|
||
#--------------------------------------
|
||
function installBootLoaderS390Recovery {
|
||
local IFS=$IFS_ORIG
|
||
Echo "*** zipl: recovery boot not implemented ***"
|
||
return 1
|
||
}
|
||
#======================================
|
||
# installBootLoaderGrub2Recovery
|
||
#--------------------------------------
|
||
function installBootLoaderGrub2Recovery {
|
||
# /.../
|
||
# install grub2 into the recovery partition
|
||
# By design the recovery partition is always the
|
||
# last primary partition of the disk
|
||
# ----
|
||
local IFS=$IFS_ORIG
|
||
local confTool=grub2-mkconfig
|
||
local confFile_grub_bios=/boot/grub2/grub.cfg
|
||
local confFile_uefi=/boot/efi/EFI/BOOT/grub.cfg
|
||
local confFile_grub=$confFile_grub_bios
|
||
local bios_grub=/reco-save/boot/grub2/i386-pc
|
||
local isEFI=0
|
||
#======================================
|
||
# check for EFI and mount EFI partition
|
||
#--------------------------------------
|
||
if [ ! -z "$kiwi_EfiPart" ];then
|
||
local jdev=$(ddn $imageDiskDevice $kiwi_EfiPart)
|
||
local label=$(blkid $jdev -s LABEL -o value)
|
||
if [ "$label" = "EFI" ];then
|
||
mkdir -p /boot/efi
|
||
if ! mount $jdev /boot/efi;then
|
||
Echo "Failed to mount EFI boot partition"
|
||
return 1
|
||
fi
|
||
isEFI=1
|
||
fi
|
||
fi
|
||
#======================================
|
||
# check tool status
|
||
#--------------------------------------
|
||
if ! lookup $confTool &>/dev/null;then
|
||
Echo "Image doesn't have grub2 installed"
|
||
Echo "Can't install recovery boot loader"
|
||
mountpoint -q /boot/efi && umount /boot/efi
|
||
return 1
|
||
fi
|
||
#======================================
|
||
# install grub2 into partition
|
||
#--------------------------------------
|
||
# this allows a bios to directly jump there, e.g with a function key
|
||
grub2-bios-setup -f -d $bios_grub $imageRecoveryDevice 1>&2
|
||
if [ ! $? = 0 ];then
|
||
Echo "Failed to install recovery boot loader"
|
||
fi
|
||
#======================================
|
||
# create custom recovery entry
|
||
#--------------------------------------
|
||
cat > /etc/grub.d/40_custom << DONE
|
||
#!/bin/bash
|
||
cat << EOF
|
||
menuentry 'Recovery' --class os {
|
||
search --no-floppy --fs-uuid --set=root $reco_uuid
|
||
configfile /boot/grub2/grub.cfg
|
||
}
|
||
EOF
|
||
DONE
|
||
#======================================
|
||
# create grub2 config file
|
||
#--------------------------------------
|
||
$confTool > $confFile_grub
|
||
if [ ! $? = 0 ];then
|
||
Echo "Failed to create recovery grub2 boot configuration"
|
||
mountpoint -q /boot/efi && umount /boot/efi
|
||
return 1
|
||
fi
|
||
if [ $isEFI -eq 1 ] && [ -e $confFile_uefi ];then
|
||
cp $confFile_grub $confFile_uefi
|
||
fi
|
||
mountpoint -q /boot/efi && umount /boot/efi
|
||
return 0
|
||
}
|
||
#======================================
|
||
# updateModuleDependencies
|
||
#--------------------------------------
|
||
function updateModuleDependencies {
|
||
# /.../
|
||
# update the kernel module dependencies list
|
||
# ---
|
||
local IFS=$IFS_ORIG
|
||
local depmodExec=$(lookup depmod 2>/dev/null)
|
||
if [ ! -x "$depmodExec" ];then
|
||
Echo "Could not find depmod executable"
|
||
Echo "Skipping module dependency update"
|
||
systemIntegrity=unknown
|
||
return
|
||
fi
|
||
if ! $depmodExec -a;then
|
||
Echo "Module dependency update failed."
|
||
systemIntegrity=unknown
|
||
fi
|
||
}
|
||
|
||
#======================================
|
||
# setupInitrd
|
||
#--------------------------------------
|
||
function setupInitrd {
|
||
# /.../
|
||
# call initrd creation tool to create the distro initrd
|
||
# ----
|
||
local IFS=$IFS_ORIG
|
||
bootLoaderOK=1
|
||
local umountProc=0
|
||
local umountSys=0
|
||
local systemMap=0
|
||
local dracutExec=$(lookup dracut 2>/dev/null)
|
||
local params
|
||
local running
|
||
local rlinux
|
||
local rinitrd
|
||
local kernel_version=$(uname -r)
|
||
for i in $(find /boot/ -name "System.map*");do
|
||
systemMap=1
|
||
done
|
||
setupDefaultTheme
|
||
if [ $systemMap -eq 1 ];then
|
||
#======================================
|
||
# Cleanup
|
||
#--------------------------------------
|
||
rm -f /boot/initrd-*.img
|
||
#======================================
|
||
# Prepare for tool call
|
||
#--------------------------------------
|
||
if [ ! -e /proc/mounts ];then
|
||
mount -t proc proc /proc
|
||
umountProc=1
|
||
fi
|
||
if [ ! -e /sys/block ];then
|
||
mount -t sysfs sysfs /sys
|
||
umountSys=1
|
||
fi
|
||
modprobe dm-mod &>/dev/null
|
||
updateModuleDependencies
|
||
#======================================
|
||
# Call initrd creation tool
|
||
#--------------------------------------
|
||
if [ -x "$dracutExec" ]; then
|
||
params=" --force"
|
||
Echo "Creating dracut based initrd"
|
||
if ! $dracutExec $params;then
|
||
Echo "Can't create initrd with dracut"
|
||
systemIntegrity=unknown
|
||
bootLoaderOK=0
|
||
fi
|
||
else
|
||
# no tool found
|
||
Echo "Coudn't find a tool to create initrd image"
|
||
systemIntegrity=unknown
|
||
bootLoaderOK=0
|
||
fi
|
||
#======================================
|
||
# Cleanup kiwi firstboot initrd
|
||
#--------------------------------------
|
||
if [ $bootLoaderOK = "1" ];then
|
||
if [ -f /boot/initrd.vmx ];then
|
||
rm -f /boot/initrd.vmx
|
||
fi
|
||
if [ -f /boot/linux.vmx ];then
|
||
rm -f /boot/linux.vmx
|
||
fi
|
||
fi
|
||
#======================================
|
||
# Cleanup mounts
|
||
#--------------------------------------
|
||
rmmod dm-mod &>/dev/null
|
||
if [ $umountSys -eq 1 ];then
|
||
umount /sys
|
||
fi
|
||
if [ $umountProc -eq 1 ];then
|
||
umount /proc
|
||
fi
|
||
else
|
||
Echo "Image doesn't include kernel system map"
|
||
Echo "Can't create initrd"
|
||
systemIntegrity=unknown
|
||
bootLoaderOK=0
|
||
fi
|
||
}
|
||
#======================================
|
||
# setupDefaultTheme
|
||
#--------------------------------------
|
||
function setupDefaultTheme {
|
||
local IFS=$IFS_ORIG
|
||
if lookup plymouthd &>/dev/null;then
|
||
plymouth-set-default-theme $kiwi_splash_theme &>/dev/null
|
||
fi
|
||
}
|
||
#======================================
|
||
# setupBootLoader
|
||
#--------------------------------------
|
||
function setupBootLoader {
|
||
# /.../
|
||
# generic function to setup the boot loader configuration.
|
||
# The selection of the bootloader happens according to
|
||
# the architecture of the system
|
||
# ----
|
||
local IFS=$IFS_ORIG
|
||
local arch=`uname -m`
|
||
local para=""
|
||
while [ $# -gt 0 ];do
|
||
# quote simple quotation marks
|
||
arg=$(echo $1 | sed -e s"#'#'\\\\''#g")
|
||
para="$para '$arg'"
|
||
shift
|
||
done
|
||
runHook preSetupBootLoader
|
||
case $arch-$loader in
|
||
i*86-grub2) eval setupBootLoaderGrub2 $para ;;
|
||
x86_64-grub2) eval setupBootLoaderGrub2 $para ;;
|
||
ppc64*-grub2) eval setupBootLoaderGrub2 $para ;;
|
||
s390*-grub2) eval setupBootLoaderGrub2 $para ;;
|
||
s390x-grub2_s390x_emu) eval setupBootLoaderS390Grub $para ;;
|
||
aarch64-grub2) eval setupBootLoaderGrub2 $para ;;
|
||
arm*-grub2) eval setupBootLoaderGrub2 $para ;;
|
||
*)
|
||
systemException \
|
||
"*** boot loader setup for $arch-$loader not implemented ***" \
|
||
"reboot"
|
||
esac
|
||
setupBootThemes "/config"
|
||
runHook postSetupBootLoader
|
||
}
|
||
#======================================
|
||
# setupBootThemes
|
||
#--------------------------------------
|
||
function setupBootThemes {
|
||
local IFS=$IFS_ORIG
|
||
local destprefix=$1
|
||
local prefix=$2
|
||
if [ -z "$prefix" ];then
|
||
prefix=/mnt
|
||
fi
|
||
#======================================
|
||
# Splash theme setup
|
||
#--------------------------------------
|
||
if [ ! -z "$kiwi_splash_theme" ];then
|
||
local theme=$kiwi_splash_theme
|
||
#======================================
|
||
# gfxboot default setup
|
||
#--------------------------------------
|
||
local orig_bootsplash=$prefix/etc/sysconfig/bootsplash
|
||
local inst_bootsplash=$destprefix/etc/sysconfig/bootsplash
|
||
mkdir -p $destprefix/etc/sysconfig
|
||
touch $inst_bootsplash
|
||
#======================================
|
||
# check for bootsplash config in sysimg
|
||
#--------------------------------------
|
||
if [ -f $orig_bootsplash ];then
|
||
cp $orig_bootsplash $inst_bootsplash
|
||
fi
|
||
#======================================
|
||
# change/create bootsplash config
|
||
#--------------------------------------
|
||
if cat $inst_bootsplash | grep -q -E "^THEME"; then
|
||
sed -i "s/^THEME=.*/THEME=\"$theme\"/" $inst_bootsplash
|
||
else
|
||
echo "THEME=\"$theme\"" >> $inst_bootsplash
|
||
fi
|
||
#======================================
|
||
# plymouth splash
|
||
#--------------------------------------
|
||
if lookup plymouthd &>/dev/null;then
|
||
local orig_plymouthconf=$prefix/etc/plymouth/plymouth.conf
|
||
local inst_plymouthconf=$destprefix/etc/plymouth/plymouth.conf
|
||
mkdir -p $destprefix/etc/plymouth
|
||
touch $inst_plymouthconf
|
||
#======================================
|
||
# check for plymouth config in sysimg
|
||
#--------------------------------------
|
||
if [ -f $orig_plymouthconf ];then
|
||
cp $orig_plymouthconf $inst_plymouthconf
|
||
fi
|
||
#======================================
|
||
# change/create plymouth config
|
||
#--------------------------------------
|
||
if cat $inst_plymouthconf | grep -q -E "^Theme"; then
|
||
sed -i "s/^Theme=.*/Theme=\"$theme\"/" $inst_plymouthconf
|
||
else
|
||
echo "[Daemon]" > $inst_plymouthconf
|
||
echo "Theme=\"$theme\"" >> $inst_plymouthconf
|
||
fi
|
||
fi
|
||
fi
|
||
}
|
||
#======================================
|
||
# setupBootLoaderRecovery
|
||
#--------------------------------------
|
||
function setupBootLoaderRecovery {
|
||
# /.../
|
||
# generic function to setup the boot loader configuration
|
||
# for the recovery partition. The selection of the bootloader
|
||
# happens according to the architecture of the system
|
||
# ----
|
||
local IFS=$IFS_ORIG
|
||
local arch=$(uname -m)
|
||
local para=""
|
||
while [ $# -gt 0 ];do
|
||
# quote simple quotation marks
|
||
arg=$(echo $1 | sed -e s"#'#'\\\\''#g")
|
||
para="$para '$arg'"
|
||
shift
|
||
done
|
||
case $arch-$loader in
|
||
i*86-grub2) eval setupBootLoaderGrub2Recovery $para ;;
|
||
x86_64-grub2) eval setupBootLoaderGrub2Recovery $para ;;
|
||
*)
|
||
systemException \
|
||
"*** boot loader setup for $arch-$loader not implemented ***" \
|
||
"reboot"
|
||
esac
|
||
}
|
||
#======================================
|
||
# setupBootLoaderGrub2Recovery
|
||
#--------------------------------------
|
||
function setupBootLoaderGrub2Recovery {
|
||
# /.../
|
||
# create grub.cfg file for the recovery boot system
|
||
# ----
|
||
local IFS=$IFS_ORIG
|
||
local mountPrefix=$1 # mount path of the image
|
||
local destsPrefix=$2 # base dir for the config files
|
||
local gfix=$3 # grub title
|
||
local kernel=vmlinuz # this is a copy of the kiwi linux.vmx file
|
||
local initrd=initrd # this is a copy of the kiwi initrd.vmx file
|
||
local conf=$destsPrefix/boot/grub2/grub.cfg
|
||
local theme=$RECOVERY_THEME
|
||
#======================================
|
||
# setup ID device names
|
||
#--------------------------------------
|
||
local rootByID=$(getDiskID $imageRootDevice)
|
||
local diskByID=$(getDiskID $imageDiskDevice)
|
||
#======================================
|
||
# operate only in recovery mode
|
||
#--------------------------------------
|
||
if [ -z "$kiwi_oemrecovery" ];then
|
||
return
|
||
fi
|
||
#======================================
|
||
# import grub2 modules into recovery
|
||
#--------------------------------------
|
||
mkdir -p $destsPrefix/boot
|
||
cp -a $mountPrefix/boot/grub2 $destsPrefix/boot/
|
||
rm -f $destsPrefix/boot/grub2/grub.cfg
|
||
rm -f $destsPrefix/boot/grub2/bootpart.cfg
|
||
#======================================
|
||
# check for kernel options
|
||
#--------------------------------------
|
||
local cmdline="KIWI_RECOVERY=$recoid"
|
||
if [ ! -z "$KIWI_KERNEL_OPTIONS" ];then
|
||
cmdline="$cmdline $KIWI_KERNEL_OPTIONS"
|
||
fi
|
||
if [ ! -z "$KIWI_INITRD_PARAMS" ];then
|
||
cmdline="$cmdline $KIWI_INITRD_PARAMS";
|
||
fi
|
||
if [ ! -z "$rootByID" ];then
|
||
cmdline="$cmdline root=$rootByID"
|
||
fi
|
||
if [ ! -z "$diskByID" ];then
|
||
cmdline="$cmdline disk=$diskByID"
|
||
fi
|
||
if [ -e /dev/xvc0 ];then
|
||
cmdline="$cmdline console=xvc console=tty"
|
||
elif [ -e /dev/hvc0 ];then
|
||
cmdline="$cmdline console=hvc console=tty"
|
||
fi
|
||
#======================================
|
||
# create recovery grub.cfg
|
||
#--------------------------------------
|
||
cat > $conf << EOF
|
||
insmod ext2
|
||
insmod gettext
|
||
insmod part_msdos
|
||
insmod chain
|
||
insmod png
|
||
insmod vbe
|
||
insmod vga
|
||
insmod gzio
|
||
set default=0
|
||
search --no-floppy --fs-uuid --set=root $reco_uuid
|
||
set font=/boot/unicode.pf2
|
||
if loadfont \$font ;then
|
||
set gfxmode=auto
|
||
insmod gfxterm
|
||
insmod gfxmenu
|
||
terminal_input gfxterm
|
||
if terminal_output gfxterm; then true; else
|
||
terminal gfxterm
|
||
fi
|
||
fi
|
||
if loadfont /boot/grub2/themes/$theme/ascii.pf2;then
|
||
loadfont /boot/grub2/themes/$theme/DejaVuSans-Bold14.pf2
|
||
loadfont /boot/grub2/themes/$theme/DejaVuSans10.pf2
|
||
loadfont /boot/grub2/themes/$theme/DejaVuSans12.pf2
|
||
loadfont /boot/grub2/themes/$theme/ascii.pf2
|
||
set theme=/boot/grub2/themes/$theme/theme.txt
|
||
set bgimg=/boot/grub2/themes/$theme/background.png
|
||
background_image -m stretch \$bgimg
|
||
fi
|
||
if [ \$grub_platform = "efi" ]; then
|
||
set linux=linuxefi
|
||
set initrd=initrdefi
|
||
else
|
||
set linux=linux
|
||
set initrd=initrd
|
||
fi
|
||
set timeout=30
|
||
EOF
|
||
if xenServer $kernel $mountPrefix;then
|
||
cat >> $conf << EOF
|
||
menuentry 'Recover/Repair System' --class os {
|
||
search --no-floppy --fs-uuid --set=root $reco_uuid
|
||
echo Loading Xen...
|
||
multiboot /boot/xen.gz dummy
|
||
echo Loading $kernel...
|
||
set gfxpayload=keep
|
||
module /boot/$kernel dummy $cmdline $kiwi_cmdline showopts
|
||
echo Loading $initrd...
|
||
module /boot/$initrd dummy
|
||
}
|
||
menuentry 'Restore Factory System' --class os {
|
||
search --no-floppy --fs-uuid --set=root $reco_uuid
|
||
echo Loading Xen...
|
||
multiboot /boot/xen.gz dummy
|
||
echo Loading $kernel...
|
||
set gfxpayload=keep
|
||
module /boot/$kernel dummy $cmdline $kiwi_cmdline RESTORE=1 showopts
|
||
echo Loading $initrd...
|
||
module /boot/$initrd dummy
|
||
}
|
||
EOF
|
||
else
|
||
cat >> $conf << EOF
|
||
menuentry 'Recover/Repair System' --class os {
|
||
search --no-floppy --fs-uuid --set=root $reco_uuid
|
||
echo Loading $kernel...
|
||
set gfxpayload=keep
|
||
\$linux /boot/$kernel $cmdline $kiwi_cmdline showopts
|
||
echo Loading $initrd...
|
||
\$initrd /boot/$initrd
|
||
}
|
||
menuentry 'Restore Factory System' --class os {
|
||
search --no-floppy --fs-uuid --set=root $reco_uuid
|
||
echo Loading $kernel...
|
||
set gfxpayload=keep
|
||
\$linux /boot/$kernel $cmdline $kiwi_cmdline RESTORE=1 showopts
|
||
echo Loading $initrd...
|
||
\$initrd /boot/$initrd
|
||
}
|
||
EOF
|
||
fi
|
||
}
|
||
#======================================
|
||
# setupBootLoaderS390Grub
|
||
#--------------------------------------
|
||
function setupBootLoaderS390Grub {
|
||
# /.../
|
||
# create grub2 configuration for s390
|
||
# ----
|
||
local IFS=$IFS_ORIG
|
||
#======================================
|
||
# function paramters
|
||
#--------------------------------------
|
||
local mountPrefix=$1 # mount path of the image
|
||
local destsPrefix=$2 # base dir for the config files
|
||
local gnum=$3 # grub boot partition ID
|
||
local rdev=$4 # grub root partition
|
||
local gfix=$5 # grub title postfix
|
||
local swap=$6 # optional swap partition
|
||
#======================================
|
||
# local variables
|
||
#--------------------------------------
|
||
local kname=$(uname -r)
|
||
local loader_type=grub2
|
||
local timeout=10
|
||
local title
|
||
local cmdline
|
||
local vesa
|
||
local fstype=$(probeFileSystem $rdev)
|
||
#======================================
|
||
# setup path names
|
||
#--------------------------------------
|
||
local inst_default_grub=$destsPrefix/etc/default/grub
|
||
local inst_default_grubdev=$destsPrefix/etc/default/grub_installdevice
|
||
local inst_default_grubmap=$destsPrefix/boot/grub2/device.map
|
||
local inst_sysb=$destsPrefix/etc/sysconfig/bootloader
|
||
#======================================
|
||
# setup ID device names
|
||
#--------------------------------------
|
||
local rootByID=$(getDiskID $rdev)
|
||
local swapByID=$(getDiskID $swap swap)
|
||
local diskByID=$(getDiskID $imageDiskDevice)
|
||
#======================================
|
||
# setup title name
|
||
#--------------------------------------
|
||
if [ -z "$gfix" ];then
|
||
gfix="unknown"
|
||
fi
|
||
if [ -z "$kiwi_oemtitle" ] && [ ! -z "$kiwi_displayname" ];then
|
||
kiwi_oemtitle=$kiwi_displayname
|
||
fi
|
||
if ! echo $gfix | grep -E -q "OEM|USB|VMX|NET|unknown";then
|
||
title=$(makeLabel "$gfix")
|
||
elif [ -z "$kiwi_oemtitle" ];then
|
||
title=$(makeLabel "$kname [ $gfix ]")
|
||
else
|
||
title=$(makeLabel "$kiwi_oemtitle [ $gfix ]")
|
||
fi
|
||
#======================================
|
||
# check for kernel options
|
||
#--------------------------------------
|
||
if [ ! -z "$rootByID" ];then
|
||
cmdline="$cmdline root=$rootByID"
|
||
fi
|
||
if [ ! -z "$diskByID" ];then
|
||
cmdline="$cmdline disk=$diskByID"
|
||
fi
|
||
if [ ! -z "$swapByID" ];then
|
||
cmdline="$cmdline resume=$swapByID"
|
||
fi
|
||
if [ ! -z "$kiwi_cmdline" ];then
|
||
cmdline="$cmdline $kiwi_cmdline"
|
||
fi
|
||
if [[ ! $cmdline =~ quiet ]];then
|
||
cmdline="$cmdline quiet"
|
||
fi
|
||
#======================================
|
||
# check for boot TIMEOUT
|
||
#--------------------------------------
|
||
if [ ! -z "$kiwi_boot_timeout" ];then
|
||
timeout=$kiwi_boot_timeout
|
||
fi
|
||
#======================================
|
||
# write etc/default/grub
|
||
#--------------------------------------
|
||
mkdir -p $destsPrefix/etc/default
|
||
cat > $inst_default_grub << EOF
|
||
GRUB_DISTRIBUTOR=$(printf %q "$title")
|
||
GRUB_DEFAULT=0
|
||
GRUB_HIDDEN_TIMEOUT=0
|
||
GRUB_HIDDEN_TIMEOUT_QUIET=true
|
||
GRUB_TIMEOUT=$timeout
|
||
GRUB_CMDLINE_LINUX="$cmdline"
|
||
GRUB_TERMINAL=console
|
||
EOF
|
||
#======================================
|
||
# enable rollback capability
|
||
#--------------------------------------
|
||
if [ "$fstype" = "btrfs" ];then
|
||
echo "SUSE_BTRFS_SNAPSHOT_BOOTING=true" >> $inst_default_grub
|
||
fi
|
||
#======================================
|
||
# write etc/default/grub_installdevice
|
||
#--------------------------------------
|
||
cat > $inst_default_grubdev << EOF
|
||
$diskByID
|
||
EOF
|
||
#======================================
|
||
# write boot/grub2/device.map
|
||
#--------------------------------------
|
||
mkdir -p $destsPrefix/boot/grub2
|
||
cat > $inst_default_grubmap << EOF
|
||
(hd0) $diskByID
|
||
EOF
|
||
#======================================
|
||
# write sysconfig/bootloader
|
||
#--------------------------------------
|
||
mkdir -p $destsPrefix/etc/sysconfig
|
||
cat > $inst_sysb << EOF
|
||
LOADER_TYPE="$loader_type"
|
||
DEFAULT_APPEND="$cmdline"
|
||
FAILSAFE_APPEND="$failsafe $cmdline"
|
||
EOF
|
||
}
|
||
#======================================
|
||
# setupBootLoaderGrub2
|
||
#--------------------------------------
|
||
function setupBootLoaderGrub2 {
|
||
# /.../
|
||
# create/update default grub2 configuration
|
||
# ----
|
||
local IFS=$IFS_ORIG
|
||
#======================================
|
||
# function paramters
|
||
#--------------------------------------
|
||
local mountPrefix=$1 # mount path of the image
|
||
local destsPrefix=$2 # base dir for the config files
|
||
local gnum=$3 # grub boot partition ID
|
||
local rdev=$4 # grub root partition
|
||
local gfix=$5 # grub title postfix
|
||
local swap=$6 # optional swap partition
|
||
#======================================
|
||
# local variables
|
||
#--------------------------------------
|
||
local kname=$(uname -r)
|
||
local title
|
||
local cmdline
|
||
local timeout
|
||
local vesa
|
||
local loader_type="grub2"
|
||
local fstype=$(probeFileSystem $rdev)
|
||
#======================================
|
||
# vesa hex => resolution table
|
||
#--------------------------------------
|
||
vesa[0x301]="640x480"
|
||
vesa[0x310]="640x480"
|
||
vesa[0x311]="640x480"
|
||
vesa[0x312]="640x480"
|
||
vesa[0x303]="800x600"
|
||
vesa[0x313]="800x600"
|
||
vesa[0x314]="800x600"
|
||
vesa[0x315]="800x600"
|
||
vesa[0x305]="1024x768"
|
||
vesa[0x316]="1024x768"
|
||
vesa[0x317]="1024x768"
|
||
vesa[0x318]="1024x768"
|
||
vesa[0x307]="1280x1024"
|
||
vesa[0x319]="1280x1024"
|
||
vesa[0x31a]="1280x1024"
|
||
vesa[0x31b]="1280x1024"
|
||
#======================================
|
||
# setup ID device names
|
||
#--------------------------------------
|
||
local rootByID=$(getDiskID $rdev)
|
||
local swapByID=$(getDiskID $swap swap)
|
||
local diskByID=$(getDiskID $imageDiskDevice)
|
||
#======================================
|
||
# setup path names
|
||
#--------------------------------------
|
||
local inst_default_grub=$destsPrefix/etc/default/grub
|
||
local inst_default_grubdev=$destsPrefix/etc/default/grub_installdevice
|
||
local inst_default_grubmap=$destsPrefix/boot/grub2/device.map
|
||
local unifont=$mountPrefix/usr/share/grub2/unicode.pf2
|
||
#======================================
|
||
# setup title name
|
||
#--------------------------------------
|
||
if [ -z "$gfix" ];then
|
||
gfix="unknown"
|
||
fi
|
||
if [ -z "$kiwi_oemtitle" ] && [ ! -z "$kiwi_displayname" ];then
|
||
kiwi_oemtitle=$kiwi_displayname
|
||
fi
|
||
if ! echo $gfix | grep -E -q "OEM|USB|VMX|NET|unknown";then
|
||
title=$(makeLabel "$gfix")
|
||
elif [ -z "$kiwi_oemtitle" ];then
|
||
title=$(makeLabel "$kname [ $gfix ]")
|
||
else
|
||
title=$(makeLabel "$kiwi_oemtitle [ $gfix ]")
|
||
fi
|
||
#======================================
|
||
# check for kernel options
|
||
#--------------------------------------
|
||
if [ ! -z "$KIWI_KERNEL_OPTIONS" ];then
|
||
cmdline="$cmdline $KIWI_KERNEL_OPTIONS"
|
||
fi
|
||
if [ ! -z "$KIWI_INITRD_PARAMS" ];then
|
||
cmdline="$cmdline $KIWI_INITRD_PARAMS";
|
||
fi
|
||
if [ ! -z "$rootByID" ];then
|
||
cmdline="$cmdline root=$rootByID"
|
||
fi
|
||
if [ ! -z "$diskByID" ];then
|
||
cmdline="$cmdline disk=$diskByID"
|
||
fi
|
||
if [ ! -z "$swapByID" ];then
|
||
cmdline="$cmdline resume=$swapByID"
|
||
fi
|
||
if [ ! -z "$kiwi_cmdline" ];then
|
||
cmdline="$cmdline $kiwi_cmdline"
|
||
fi
|
||
if [ -e /dev/xvc0 ];then
|
||
cmdline="$cmdline console=xvc console=tty"
|
||
elif [ -e /dev/hvc0 ];then
|
||
cmdline="$cmdline console=hvc console=tty"
|
||
fi
|
||
if [[ ! $cmdline =~ quiet ]];then
|
||
cmdline="$cmdline quiet"
|
||
fi
|
||
#======================================
|
||
# check for boot TIMEOUT
|
||
#--------------------------------------
|
||
if [ -z "$kiwi_boot_timeout" ];then
|
||
timeout=10;
|
||
fi
|
||
#======================================
|
||
# write etc/default/grub
|
||
#--------------------------------------
|
||
mkdir -p $destsPrefix/etc/default
|
||
cat > $inst_default_grub << EOF
|
||
GRUB_DISTRIBUTOR=$(printf %q "$title")
|
||
GRUB_DEFAULT=0
|
||
GRUB_HIDDEN_TIMEOUT=0
|
||
GRUB_HIDDEN_TIMEOUT_QUIET=true
|
||
GRUB_TIMEOUT=$timeout
|
||
GRUB_CMDLINE_LINUX="$cmdline"
|
||
EOF
|
||
#======================================
|
||
# set terminal mode
|
||
#--------------------------------------
|
||
if [ -z "$kiwi_bootloader_console" ];then
|
||
kiwi_bootloader_console=gfxterm
|
||
fi
|
||
echo "GRUB_TERMINAL=$kiwi_bootloader_console" >> $inst_default_grub
|
||
if [ "$kiwi_bootloader_console" = "serial" ];then
|
||
local serial
|
||
serial="serial --speed=38400 --unit=0 --word=8 --parity=no --stop=1"
|
||
echo "GRUB_SERIAL_COMMAND=\"$serial\"" >> $inst_default_grub
|
||
fi
|
||
#======================================
|
||
# write etc/default/grub_installdevice
|
||
#--------------------------------------
|
||
local grub_install_device=$diskByID
|
||
if [ ! -z "$kiwi_OfwGrub" ];then
|
||
grub_install_device=$(ddn $imageDiskDevice $kiwi_OfwGrub)
|
||
fi
|
||
cat > $inst_default_grubdev << EOF
|
||
$grub_install_device
|
||
EOF
|
||
#======================================
|
||
# write boot/grub2/device.map
|
||
#--------------------------------------
|
||
mkdir -p $destsPrefix/boot/grub2
|
||
cat > $inst_default_grubmap << EOF
|
||
(hd0) $diskByID
|
||
EOF
|
||
#======================================
|
||
# Use linuxefi/initrdefi if needed
|
||
#--------------------------------------
|
||
if [ "$kiwi_firmware" = "uefi" ] || [ "$kiwi_firmware" = "efi" ];then
|
||
case $arch in
|
||
i?86|x86_64)
|
||
echo "GRUB_USE_LINUXEFI=true" >> $inst_default_grub
|
||
echo "GRUB_USE_INITRDEFI=true" >> $inst_default_grub
|
||
;;
|
||
esac
|
||
loader_type="grub2-efi"
|
||
fi
|
||
#======================================
|
||
# write vesa vga setup
|
||
#--------------------------------------
|
||
if [ ! -z "$kiwi_vga" ] && [ ! -z "${vesa[$kiwi_vga]}" ];then
|
||
echo "GRUB_GFXMODE=${vesa[$kiwi_vga]}" >> $inst_default_grub
|
||
echo "GRUB_GFXPAYLOAD_LINUX=${vesa[$kiwi_vga]}" >> $inst_default_grub
|
||
else
|
||
echo "GRUB_GFXMODE=${vesa[$DEFAULT_VGA]}" >> $inst_default_grub
|
||
echo "GRUB_GFXPAYLOAD_LINUX=keep" >> $inst_default_grub
|
||
fi
|
||
#======================================
|
||
# write bootloader theme setup
|
||
#--------------------------------------
|
||
if [ ! -z "$kiwi_loader_theme" ];then
|
||
local theme=/boot/grub2/themes/$kiwi_loader_theme/theme.txt
|
||
local bgpng=/boot/grub2/themes/$kiwi_loader_theme/background.png
|
||
echo "GRUB_THEME=\"$theme\"" >> $inst_default_grub
|
||
echo "GRUB_BACKGROUND=\"$bgpng\"" >> $inst_default_grub
|
||
fi
|
||
#======================================
|
||
# write bootloader timeout setup
|
||
#--------------------------------------
|
||
if [ ! -z "$kiwi_boot_timeout" ];then
|
||
echo "GRUB_TIMEOUT=\"$kiwi_boot_timeout\"" >> $inst_default_grub
|
||
fi
|
||
#======================================
|
||
# enable rollback capability
|
||
#--------------------------------------
|
||
if [ "$fstype" = "btrfs" ];then
|
||
echo "SUSE_BTRFS_SNAPSHOT_BOOTING=true" >> $inst_default_grub
|
||
fi
|
||
#======================================
|
||
# create sysconfig/bootloader
|
||
#--------------------------------------
|
||
mkdir -p $destsPrefix/etc/sysconfig
|
||
local sysb=$destsPrefix/etc/sysconfig/bootloader
|
||
echo "LOADER_TYPE=\"$loader_type\"" > $sysb
|
||
echo "LOADER_LOCATION=\"mbr\"" >> $sysb
|
||
echo "DEFAULT_APPEND=\"$cmdline\"" >> $sysb
|
||
echo "FAILSAFE_APPEND=\"$failsafe $cmdline\"" >> $sysb
|
||
}
|
||
#======================================
|
||
# setupDefaultPXENetwork
|
||
#--------------------------------------
|
||
function setupDefaultPXENetwork {
|
||
# /.../
|
||
# create the /sysconfig/network file according to the PXE
|
||
# boot interface.
|
||
# ----
|
||
local IFS=$IFS_ORIG
|
||
if [ -z "$PXE_IFACE" ];then
|
||
return
|
||
fi
|
||
local prefix=$1
|
||
local niface=$prefix/etc/sysconfig/network/ifcfg-$PXE_IFACE
|
||
mkdir -p $prefix/etc/sysconfig/network
|
||
cat > $niface < /dev/null
|
||
echo "BOOTPROTO='dhcp'" >> $niface
|
||
echo "STARTMODE='ifplugd'" >> $niface
|
||
echo "USERCONTROL='no'" >> $niface
|
||
}
|
||
#======================================
|
||
# getBtrfsSubVolumes
|
||
#--------------------------------------
|
||
function getBtrfsSubVolumes {
|
||
local IFS=$IFS_ORIG
|
||
local prefix=$1
|
||
btrfs subvol list $prefix | \
|
||
grep -v .snapshots/ | grep -v @$ | cut -f9 -d ' '
|
||
}
|
||
#======================================
|
||
# mountBtrfsSubVolumes
|
||
#--------------------------------------
|
||
function mountBtrfsSubVolumes {
|
||
local IFS=$IFS_ORIG
|
||
local mountDevice=$1
|
||
local prefix=$2
|
||
local syspath
|
||
for subvol in $(getBtrfsSubVolumes "$prefix"); do
|
||
syspath=$(echo $subvol | tr -d @)
|
||
mount $mountDevice $prefix/$syspath -o subvol=$subvol
|
||
done
|
||
}
|
||
#======================================
|
||
# setupDefaultFstab
|
||
#--------------------------------------
|
||
function setupDefaultFstab {
|
||
# /.../
|
||
# Update or create new /etc/fstab file with default entries
|
||
# ----
|
||
# systemd handles all of the kernel filesystems at the moment
|
||
# If this is going to change add the missing entries here
|
||
# ----
|
||
local IFS=$IFS_ORIG
|
||
local prefix=/mnt
|
||
local config_tmp=$1
|
||
local nfstab=$config_tmp/etc/fstab
|
||
mkdir -p $config_tmp/etc
|
||
if [ -e "$prefix/etc/fstab" ];then
|
||
cp $prefix/etc/fstab $config_tmp/etc
|
||
else
|
||
touch $config_tmp/etc/fstab
|
||
fi
|
||
}
|
||
#======================================
|
||
# updateRootDeviceFstab
|
||
#--------------------------------------
|
||
function updateRootDeviceFstab {
|
||
# /.../
|
||
# add one line to the fstab file for the root device
|
||
# if the root filesystem is a remote filesystem. the
|
||
# rootfs entry is normally done by the image build
|
||
# process
|
||
# ----
|
||
local IFS=$IFS_ORIG
|
||
local prefix=/mnt
|
||
local config_tmp=$1
|
||
local rdev=$2
|
||
local nfstab=$config_tmp/etc/fstab
|
||
#======================================
|
||
# check for NFSROOT
|
||
#--------------------------------------
|
||
if [ ! -z "$NFSROOT" ];then
|
||
local server=$(echo $rdev | cut -f3 -d" ")
|
||
local option=$(echo $rdev | cut -f2 -d" ")
|
||
echo "$server / nfs $option 0 0" >> $nfstab
|
||
return
|
||
fi
|
||
#======================================
|
||
# check for device by ID
|
||
#--------------------------------------
|
||
if [ ! -z "$UNIONFS_CONFIG" ]; then
|
||
echo "/dev/root / auto defaults 1 1" >> $nfstab
|
||
fi
|
||
}
|
||
#======================================
|
||
# updateSwapDeviceFstab
|
||
#--------------------------------------
|
||
function updateSwapDeviceFstab {
|
||
# /.../
|
||
# add one line to the fstab file for the swap device
|
||
# which is created at boot time
|
||
# ----
|
||
local IFS=$IFS_ORIG
|
||
local prefix=$1
|
||
local sdev=$2
|
||
local nfstab=$prefix/etc/fstab
|
||
local devicepersistency="by-uuid"
|
||
if [ ! -z "$kiwi_devicepersistency" ];then
|
||
devicepersistency=$kiwi_devicepersistency
|
||
fi
|
||
if [ $devicepersistency = "by-label" ];then
|
||
local device="LABEL=$(blkid $sdev -s LABEL -o value)"
|
||
else
|
||
local device="UUID=$(blkid $sdev -s UUID -o value)"
|
||
fi
|
||
echo "$device swap swap defaults 0 0" >> $nfstab
|
||
}
|
||
#======================================
|
||
# updateBootDeviceFstab
|
||
#--------------------------------------
|
||
function updateBootDeviceFstab {
|
||
# /.../
|
||
# add temporary bind mounted boot entry to fstab
|
||
# This entry is deleted later on in resetBootBind
|
||
# The standard boot entry is created by the build
|
||
# process
|
||
# ----
|
||
local IFS=$IFS_ORIG
|
||
local config_tmp=$1
|
||
local sdev=$2
|
||
local nfstab=$config_tmp/etc/fstab
|
||
local mount=boot_bind
|
||
local prefix=/mnt
|
||
local devicepersistency="by-uuid"
|
||
if [ ! -z "$kiwi_devicepersistency" ];then
|
||
devicepersistency=$kiwi_devicepersistency
|
||
fi
|
||
local tmp_fstab=$config_tmp/etc/fstab.tmp
|
||
local fstype
|
||
#======================================
|
||
# Store boot_bind entry
|
||
#--------------------------------------
|
||
if [ -e $prefix/$mount ];then
|
||
fstype=$(probeFileSystem $sdev)
|
||
if [ "$fstype" = "unknown" ];then
|
||
fstype=auto
|
||
fi
|
||
# delete existing /boot entry if present
|
||
grep -v '/boot ' $nfstab > ${nfstab}.new
|
||
mv ${nfstab}.new $nfstab
|
||
# add boot entry mounted to boot_bind
|
||
if [ $devicepersistency = "by-label" ];then
|
||
local device="LABEL=$(blkid $sdev -s LABEL -o value)"
|
||
else
|
||
local device="UUID=$(blkid $sdev -s UUID -o value)"
|
||
fi
|
||
echo "$device /$mount $fstype defaults 1 2" >> $tmp_fstab
|
||
# add bind mount entry from boot_bind to boot
|
||
echo "/$mount/boot /boot none bind 0 0" >> $tmp_fstab
|
||
# add existing fstab entries
|
||
cat $nfstab >> $tmp_fstab
|
||
# move result as new fstab
|
||
mv $tmp_fstab $nfstab
|
||
fi
|
||
}
|
||
#======================================
|
||
# updateOtherDeviceFstab
|
||
#--------------------------------------
|
||
function updateOtherDeviceFstab {
|
||
# /.../
|
||
# check the contents of the $PART variable and
|
||
# add one line to the fstab file for each partition
|
||
# which has a mount point defined. This is only
|
||
# relevant for netboot images configured by a
|
||
# config.MAC setup
|
||
# ----
|
||
local IFS=$IFS_ORIG
|
||
local prefix=$1
|
||
local nfstab=$prefix/etc/fstab
|
||
local index=0
|
||
local field=0
|
||
local count=0
|
||
local sdev
|
||
local diskByID
|
||
local fstype
|
||
local devicepersistency="by-uuid"
|
||
if [ ! -z "$kiwi_devicepersistency" ];then
|
||
devicepersistency=$kiwi_devicepersistency
|
||
fi
|
||
local IFS=","
|
||
if [ -z "$prefix" ];then
|
||
prefix=/mnt
|
||
fi
|
||
for i in $PART;do
|
||
field=0
|
||
count=$((count + 1))
|
||
IFS=";" ; for n in $i;do
|
||
case $field in
|
||
0) partSize=$n ; field=1 ;;
|
||
1) partID=$n ; field=2 ;;
|
||
2) partMount=$n;
|
||
esac
|
||
done
|
||
if \
|
||
[ ! -z "$partMount" ] && \
|
||
[ ! "$partMount" = "x" ] && \
|
||
[ ! "$partMount" = "swap" ] && \
|
||
[ ! "$partMount" = "/" ]
|
||
then
|
||
if [ ! -z "$RAID" ];then
|
||
sdev=/dev/md$((count - 1))
|
||
else
|
||
sdev=$(ddn $DISK $count)
|
||
fi
|
||
fstype=$(probeFileSystem $sdev)
|
||
if [ ! "$fstype" = "luks" ] && [ ! "$fstype" = "unknown" ];then
|
||
if [ ! -d $prefix/$partMount ];then
|
||
mkdir -p $prefix/$partMount
|
||
fi
|
||
if [ $devicepersistency = "by-label" ];then
|
||
local device="LABEL=$(blkid $sdev -s LABEL -o value)"
|
||
else
|
||
local device="UUID=$(blkid $sdev -s UUID -o value)"
|
||
fi
|
||
echo "$device $partMount $fstype defaults 0 0" >> $nfstab
|
||
fi
|
||
fi
|
||
done
|
||
}
|
||
#======================================
|
||
# setupKernelModules
|
||
#--------------------------------------
|
||
function setupKernelModules {
|
||
# /.../
|
||
# placeholder for custom kernel module setup
|
||
# used by the distribution initrd tool
|
||
:
|
||
}
|
||
#======================================
|
||
# probeFileSystem
|
||
#--------------------------------------
|
||
function probeFileSystem {
|
||
# /.../
|
||
# probe for the filesystem type. The function uses the
|
||
# result from blkid. If blkid could not detect the
|
||
# filesystem type the first 128 kB of the given device
|
||
# are read and checked for a known signature
|
||
# ----
|
||
local IFS=$IFS_ORIG
|
||
local fstype
|
||
fstype=$(blkid $1 -s TYPE -o value)
|
||
if [ -z "$fstype" ];then
|
||
fstype=unknown
|
||
fi
|
||
if [ "$fstype" = "crypto_LUKS" ];then
|
||
fstype=luks
|
||
fi
|
||
if [ $fstype = "unknown" ];then
|
||
dd if=$1 of=/tmp/filesystem-$$ bs=128k count=1 >/dev/null
|
||
if grep -q ^CLIC /tmp/filesystem-$$;then
|
||
fstype=clicfs
|
||
fi
|
||
if grep -q ^hsqs /tmp/filesystem-$$;then
|
||
fstype=squashfs
|
||
fi
|
||
fi
|
||
echo $fstype
|
||
}
|
||
#======================================
|
||
# getSystemIntegrity
|
||
#--------------------------------------
|
||
function getSystemIntegrity {
|
||
# /.../
|
||
# check the variable SYSTEM_INTEGRITY which contains
|
||
# information about the status of all image portions
|
||
# per partition. If a number is given as parameter only
|
||
# the information from the image assigned to this partition
|
||
# is returned
|
||
# ----
|
||
local IFS=$IFS_ORIG
|
||
if [ -z "$SYSTEM_INTEGRITY" ];then
|
||
echo "clean"
|
||
else
|
||
echo $SYSTEM_INTEGRITY | cut -f$1 -d:
|
||
fi
|
||
}
|
||
#======================================
|
||
# getSystemMD5Status
|
||
#--------------------------------------
|
||
function getSystemMD5Status {
|
||
# /.../
|
||
# return the md5 status of the given image number.
|
||
# the function works similar to getSystemIntegrity
|
||
# ----
|
||
local IFS=$IFS_ORIG
|
||
echo $SYSTEM_MD5STATUS | cut -f$1 -d:
|
||
}
|
||
#======================================
|
||
# waitForIdleEventQueue
|
||
#--------------------------------------
|
||
function waitForIdleEventQueue {
|
||
local IFS=$IFS_ORIG
|
||
local devs=0
|
||
local p_devs=1
|
||
local timeout=5
|
||
Echo -n "Waiting for devices to settle..."
|
||
while true;do
|
||
udevPending
|
||
devs=$(ls -1 /dev | wc -l)
|
||
if [ $devs -eq $p_devs ];then
|
||
break
|
||
fi
|
||
p_devs=$devs
|
||
sleep $timeout
|
||
echo -n .
|
||
done
|
||
echo
|
||
}
|
||
#======================================
|
||
# probeUSB
|
||
#--------------------------------------
|
||
function probeUSB {
|
||
local IFS=$IFS_ORIG
|
||
local module=""
|
||
local stdevs=""
|
||
local hwicmd="/usr/sbin/hwinfo"
|
||
if [ $HAVE_MODULES_ORDER = 0 ];then
|
||
#======================================
|
||
# load host controller modules
|
||
#--------------------------------------
|
||
IFS="%"
|
||
for i in \
|
||
`$hwicmd --usb | grep "Driver [IA]" |
|
||
sed -es"@modprobe\(.*\)\"@\1%@" | tr -d "\n"`
|
||
do
|
||
if echo $i | grep -q "#0";then
|
||
module=`echo $i | cut -f2 -d"\"" | tr -d " "`
|
||
module=`echo $module | sed -es"@modprobe@@g"`
|
||
IFS=";"
|
||
for m in $module;do
|
||
if ! echo $stdevs | grep -q $m;then
|
||
stdevs="$stdevs $m"
|
||
fi
|
||
done
|
||
fi
|
||
done
|
||
for i in \
|
||
`$hwicmd --usb-ctrl | grep "Driver [IA]" |
|
||
sed -es"@modprobe\(.*\)\"@\1%@" | tr -d "\n"`
|
||
do
|
||
if echo $i | grep -q "#0";then
|
||
module=`echo $i | cut -f2 -d"\"" | tr -d " "`
|
||
module=`echo $module | sed -es"@modprobe@@g"`
|
||
IFS=";"
|
||
for m in $module;do
|
||
if ! echo $stdevs | grep -q $m;then
|
||
stdevs="$stdevs $m"
|
||
fi
|
||
done
|
||
fi
|
||
done
|
||
IFS=$IFS_ORIG
|
||
stdevs=`echo $stdevs`
|
||
for module in $stdevs;do
|
||
Echo "Probing module: $module"
|
||
modprobe $module >/dev/null
|
||
done
|
||
#======================================
|
||
# check load status for host controller
|
||
#--------------------------------------
|
||
if [ -z "$stdevs" ];then
|
||
return
|
||
fi
|
||
#======================================
|
||
# manually load storage/input drivers
|
||
#--------------------------------------
|
||
for i in usbhid usb-storage;do
|
||
modprobe $i &>/dev/null
|
||
done
|
||
fi
|
||
}
|
||
#======================================
|
||
# probeDevices
|
||
#--------------------------------------
|
||
function probeDevices {
|
||
local IFS=$IFS_ORIG
|
||
local skipUSB=$1
|
||
udevPending
|
||
if [ $HAVE_MODULES_ORDER = 0 ];then
|
||
waitForIdleEventQueue
|
||
fi
|
||
#======================================
|
||
# probe USB devices and load modules
|
||
#--------------------------------------
|
||
if [ -z "$skipUSB" ];then
|
||
probeUSB
|
||
fi
|
||
#======================================
|
||
# probe Disk devices and load modules
|
||
#--------------------------------------
|
||
if [ $HAVE_MODULES_ORDER = 0 ];then
|
||
Echo "Including required kernel modules..."
|
||
IFS="%"
|
||
local module=""
|
||
local stdevs=""
|
||
local hwicmd="/usr/sbin/hwinfo"
|
||
for i in \
|
||
`$hwicmd --storage | grep "Driver [IA]" |
|
||
sed -es"@modprobe\(.*\)\"@\1%@" | tr -d "\n"`
|
||
do
|
||
if echo $i | grep -q "#0";then
|
||
module=`echo $i | cut -f2 -d"\"" | tr -d " "`
|
||
module=`echo $module | sed -es"@modprobe@@g"`
|
||
IFS=";"
|
||
for m in $module;do
|
||
if ! echo $stdevs | grep -q $m;then
|
||
stdevs="$stdevs $m"
|
||
fi
|
||
done
|
||
fi
|
||
done
|
||
IFS=$IFS_ORIG
|
||
stdevs=`echo $stdevs`
|
||
if [ ! -z "$kiwikernelmodule" ];then
|
||
for module in $kiwikernelmodule;do
|
||
Echo "Probing module (cmdline): $module"
|
||
INITRD_MODULES="$INITRD_MODULES $module"
|
||
modprobe $module >/dev/null
|
||
done
|
||
fi
|
||
for module in $stdevs;do
|
||
loadok=1
|
||
for broken in $kiwibrokenmodule;do
|
||
if [ $broken = $module ];then
|
||
Echo "Prevent loading module: $module"
|
||
loadok=0; break
|
||
fi
|
||
done
|
||
if [ $loadok = 1 ];then
|
||
Echo "Probing module: $module"
|
||
INITRD_MODULES="$INITRD_MODULES $module"
|
||
modprobe $module >/dev/null
|
||
fi
|
||
done
|
||
hwinfo --block &>/dev/null
|
||
# /.../
|
||
# older systems require ide-disk to be present at any time
|
||
# for details on this crappy call see bug: #250241
|
||
# ----
|
||
modprobe ide-disk &>/dev/null
|
||
else
|
||
if [ ! -z "$kiwikernelmodule" ];then
|
||
for module in $kiwikernelmodule;do
|
||
Echo "Probing module (cmdline): $module"
|
||
INITRD_MODULES="$INITRD_MODULES $module"
|
||
modprobe $module >/dev/null
|
||
done
|
||
fi
|
||
fi
|
||
#======================================
|
||
# Manual loading of modules
|
||
#--------------------------------------
|
||
for i in rd brd edd dm-mod xen:vif xen:vbd virtio_blk loop squashfs fuse;do
|
||
modprobe $i &>/dev/null
|
||
done
|
||
udevPending
|
||
if [ $HAVE_MODULES_ORDER = 0 ];then
|
||
waitForIdleEventQueue
|
||
fi
|
||
}
|
||
#======================================
|
||
# USBStickDevice
|
||
#--------------------------------------
|
||
function USBStickDevice {
|
||
local IFS=$IFS_ORIG
|
||
stickFound=0
|
||
local mode=$1
|
||
local prefix=/mnt
|
||
#======================================
|
||
# search for USB removable devices
|
||
#--------------------------------------
|
||
for device in /sys/bus/usb/drivers/usb-storage/*;do
|
||
if [ ! -L $device ];then
|
||
continue
|
||
fi
|
||
descriptions=$device/host*/target*/*/block*
|
||
for description in $descriptions;do
|
||
if [ ! -d $description ];then
|
||
continue
|
||
fi
|
||
isremovable=$description/removable
|
||
storageID=$(echo $description | cut -f1 -d: | xargs basename)
|
||
devicebID=$(basename $description | cut -f2 -d:)
|
||
if [ $devicebID = "block" ];then
|
||
devicebID=`ls -1 $description`
|
||
isremovable=$description/$devicebID/removable
|
||
fi
|
||
serial="/sys/bus/usb/devices/$storageID/serial"
|
||
device="/dev/$devicebID"
|
||
if [ ! -b $device ];then
|
||
continue;
|
||
fi
|
||
if [ ! -f $isremovable ];then
|
||
continue;
|
||
fi
|
||
if ! partitionSize $device >/dev/null;then
|
||
continue;
|
||
fi
|
||
if [ ! -f $serial ];then
|
||
serial="USB Stick (unknown type)"
|
||
else
|
||
serial=`cat $serial`
|
||
fi
|
||
removable=`cat $isremovable`
|
||
# /.../
|
||
# don't check the removable flag, it could be wrong
|
||
# especially for USB hard disks connected via a
|
||
# USB caddy, details in bug: 535113
|
||
# ----
|
||
removable=1
|
||
if [ $removable -eq 1 ];then
|
||
stickRoot=$device
|
||
stickDevice=$(ddn $device 1)
|
||
for devnr in 1 2;do
|
||
dev=$(ddn $stickRoot $devnr)
|
||
if ! kiwiMount "$dev" "$prefix" "-o ro";then
|
||
continue
|
||
fi
|
||
if [ "$mode" = "install" ];then
|
||
# /.../
|
||
# USB stick search for install media
|
||
# created with kiwi
|
||
# ----
|
||
if \
|
||
[ ! -e $prefix/config.isoclient ] && \
|
||
[ ! -e $prefix/config.usbclient ]
|
||
then
|
||
umountSystem
|
||
continue
|
||
fi
|
||
elif [ "$mode" = "kexec" ];then
|
||
# /.../
|
||
# USB stick search for hotfix media
|
||
# with kernel/initrd for later kexec
|
||
# ----
|
||
if \
|
||
[ ! -e $prefix/linux.kexec ] && \
|
||
[ ! -e $prefix/initrd.kexec ]
|
||
then
|
||
umountSystem
|
||
continue
|
||
fi
|
||
else
|
||
# /.../
|
||
# USB stick search for Linux system tree
|
||
# created with kiwi
|
||
# ----
|
||
if [ ! -e $prefix/etc/ImageVersion ]; then
|
||
umountSystem
|
||
continue
|
||
fi
|
||
fi
|
||
stickFound=1
|
||
umountSystem
|
||
break
|
||
done
|
||
if [ "$stickFound" = 0 ];then
|
||
continue
|
||
fi
|
||
stickSerial=$serial
|
||
return
|
||
fi
|
||
done
|
||
done
|
||
}
|
||
#======================================
|
||
# CDMountOption
|
||
#--------------------------------------
|
||
function CDMountOption {
|
||
# /.../
|
||
# checks for the ISO 9660 extension and prints the
|
||
# mount option required to mount the device in full
|
||
# speed mode
|
||
# ----
|
||
local IFS=$IFS_ORIG
|
||
local id=$(blkid -o value -s TYPE $1)
|
||
if [ "$id" = "iso9660" ];then
|
||
echo "-t iso9660"
|
||
fi
|
||
if [ "$id" = "udf" ]; then
|
||
echo "-t udf"
|
||
fi
|
||
}
|
||
#======================================
|
||
# searchImageISODevice
|
||
#--------------------------------------
|
||
function searchImageISODevice {
|
||
# /.../
|
||
# search all devices for the MBR ID stored in the
|
||
# iso header. This function is called to identify the
|
||
# live media and/or install media
|
||
# ----
|
||
local IFS=$IFS_ORIG
|
||
local mbrVID
|
||
local mbrIID
|
||
local count=0
|
||
local isoinfo=/usr/bin/isoinfo
|
||
mkdir -p /cdrom
|
||
if [ ! -x $isoinfo ]; then
|
||
isoinfo=/usr/lib/genisoimage/isoinfo
|
||
fi
|
||
if [ ! -x $isoinfo ];then
|
||
systemException \
|
||
"Can't find isoinfo tool in initrd" \
|
||
"reboot"
|
||
fi
|
||
if [ ! -f /boot/mbrid ];then
|
||
systemException \
|
||
"Can't find MBR id file in initrd" \
|
||
"reboot"
|
||
fi
|
||
mbrIID=$(cat /boot/mbrid)
|
||
udevPending
|
||
#======================================
|
||
# Check for ISO file on storage media
|
||
#--------------------------------------
|
||
if [ ! -z "$isofrom_device" ] && [ ! -z "$isofrom_system" ];then
|
||
Echo "Looking up ISO on $isofrom_device..."
|
||
mkdir /isofrom
|
||
if [[ $isofrom_device =~ nfs: ]];then
|
||
setupNetwork
|
||
isofrom_device=$(echo $isofrom_device | cut -c 5-)
|
||
mount -t nfs -o nolock $isofrom_device /isofrom
|
||
else
|
||
waitForStorageDevice $isofrom_device
|
||
mount $isofrom_device /isofrom
|
||
fi
|
||
if [ ! $? = 0 ];then
|
||
systemException \
|
||
"Failed to mount ISO storage device !" \
|
||
"reboot"
|
||
fi
|
||
biosBootDevice=$(loop_setup /isofrom/$isofrom_system)
|
||
if [ ! $? = 0 ];then
|
||
systemException \
|
||
"Failed to loop setup ISO system !" \
|
||
"reboot"
|
||
fi
|
||
return 0
|
||
fi
|
||
#======================================
|
||
# Search ISO header in device list
|
||
#--------------------------------------
|
||
Echo -n "Searching for boot device in Application ID..."
|
||
while true;do
|
||
for i in /dev/*;do
|
||
if [ ! -b $i ];then
|
||
continue
|
||
fi
|
||
mbrVID=$(
|
||
$isoinfo -d -i $i 2>/dev/null|grep "Application id:"|cut -f2 -d:
|
||
)
|
||
mbrVID=$(echo $mbrVID)
|
||
if [ "$mbrVID" = "$mbrIID" ];then
|
||
# /.../
|
||
# found ISO header on a device, now check if there is
|
||
# also a partition for this device with the same
|
||
# information and prefer that device if it exists
|
||
# ----
|
||
biosBootDevice=$i
|
||
for n in 1 2;do
|
||
local pdev=$(ddn $i $n)
|
||
if [ -e $pdev ];then
|
||
mbrVID=$(
|
||
$isoinfo -d -i $pdev 2>/dev/null |\
|
||
grep "Application id:"|cut -f2 -d:
|
||
)
|
||
mbrVID=$(echo $mbrVID)
|
||
if [ "$mbrVID" = "$mbrIID" ];then
|
||
biosBootDevice=$pdev
|
||
echo; return 0
|
||
fi
|
||
fi
|
||
done
|
||
echo; return 0
|
||
fi
|
||
done
|
||
if [ $count -eq 30 ];then
|
||
systemException \
|
||
"Failed to find MBR identifier !" \
|
||
"reboot"
|
||
fi
|
||
count=$(($count + 1))
|
||
echo -n .
|
||
sleep 1
|
||
done
|
||
}
|
||
#======================================
|
||
# runMediaCheck
|
||
#--------------------------------------
|
||
function runMediaCheck {
|
||
# /.../
|
||
# run checkmedia program on the specified device
|
||
# ----
|
||
local IFS=$IFS_ORIG
|
||
local device_iso=$biosBootDevice
|
||
local device_sdx=$(dn $biosBootDevice)
|
||
if [ -e "$device_sdx" ];then
|
||
device_iso=$device_sdx
|
||
fi
|
||
if ! checkmedia $device_iso;then
|
||
systemException \
|
||
"ISO check failed, you have been warned" \
|
||
"waitkey"
|
||
else
|
||
Echo "ISO check passed"
|
||
Echo "Press any key to continue (waiting $MEDIACHECK_OK_TIMER sec...)"
|
||
read -s -n 1 -t $MEDIACHECK_OK_TIMER
|
||
fi
|
||
}
|
||
#======================================
|
||
# setupHybridFeatures
|
||
#--------------------------------------
|
||
function setupHybridPersistent {
|
||
# /.../
|
||
# create a write partition for hybrid images if requested
|
||
# and store the device name in HYBRID_RW
|
||
# ----
|
||
local IFS=$IFS_ORIG
|
||
if [ ! "$kiwi_hybridpersistent" = "true" ];then
|
||
return
|
||
fi
|
||
local diskDevice=$(dn $biosBootDevice)
|
||
#======================================
|
||
# create write partition for hybrid
|
||
#--------------------------------------
|
||
if [ -z "$kiwi_cowdevice" ] && [ -z "$kiwi_cowsystem" ];then
|
||
#======================================
|
||
# try to create a write partition
|
||
#--------------------------------------
|
||
createHybridPersistent $diskDevice
|
||
else
|
||
#======================================
|
||
# use given cow device
|
||
#--------------------------------------
|
||
createCustomHybridPersistent
|
||
fi
|
||
#======================================
|
||
# check hybrid write partition device
|
||
#--------------------------------------
|
||
if [ ! -e "$HYBRID_RW" ]; then
|
||
# /.../
|
||
# failed to create read-write partition
|
||
# disable persistent writing
|
||
# ----
|
||
unset HYBRID_RW
|
||
unset kiwi_hybridpersistent
|
||
export skipSetupBootPartition=1
|
||
fi
|
||
}
|
||
#======================================
|
||
# CDUmount
|
||
#--------------------------------------
|
||
function CDUmount {
|
||
# /.../
|
||
# umount the CD device
|
||
# ----
|
||
local IFS=$IFS_ORIG
|
||
umount $biosBootDevice
|
||
}
|
||
#======================================
|
||
# CDEject
|
||
#--------------------------------------
|
||
function CDEject {
|
||
local IFS=$IFS_ORIG
|
||
eject $biosBootDevice
|
||
}
|
||
#======================================
|
||
# searchOFBootDevice
|
||
#--------------------------------------
|
||
function searchOFBootDevice {
|
||
# /.../
|
||
# search for the device with the OF PROM id
|
||
# this is required for the ppc boot architecture
|
||
# as we don't have a BIOS and a MBR here
|
||
# ----
|
||
local IFS=$IFS_ORIG
|
||
local ofdev=`cat /proc/device-tree/chosen/bootpath|cut -f1 -d:`
|
||
local h=/usr/sbin/ofpathname
|
||
local ddevs=`$h -l $ofdev`
|
||
#======================================
|
||
# Store device with PROM id
|
||
#--------------------------------------
|
||
for curd in $ddevs;do
|
||
if [ $curd = "sda" -o $curd = "vda" ];then
|
||
export biosBootDevice="/dev/$curd"
|
||
return 0
|
||
fi
|
||
done
|
||
export biosBootDevice="Can't find OF boot device"
|
||
return 1
|
||
}
|
||
#======================================
|
||
# searchBusIDBootDevice
|
||
#--------------------------------------
|
||
function searchBusIDBootDevice {
|
||
# /.../
|
||
# check for a DASD or ZFCP devices
|
||
# like they exist on the s390 architecture. If found the
|
||
# device is set online and the biosBootDevice variable
|
||
# is set to this device for further processing
|
||
# ----
|
||
local IFS=$IFS_ORIG
|
||
local dpath=/dev/disk/by-path
|
||
local ipl_type=$(cat /sys/firmware/ipl/ipl_type)
|
||
local deviceID=$(cat /sys/firmware/ipl/device)
|
||
local dev_type=$(cat /sys/bus/ccw/devices/$deviceID/devtype)
|
||
local wwpn
|
||
local slun
|
||
#======================================
|
||
# check for custom device init command
|
||
#--------------------------------------
|
||
if [ ! -z "$DEVICE_INIT" ];then
|
||
if ! eval $DEVICE_INIT;then
|
||
export biosBootDevice="Failed to call: $DEVICE_INIT"
|
||
return 1
|
||
fi
|
||
export biosBootDevice=$DISK
|
||
return 0
|
||
fi
|
||
#======================================
|
||
# determine device type: dasd or zfcp
|
||
#--------------------------------------
|
||
if [ -z "$deviceID" ];then
|
||
systemException \
|
||
"Can't find IPL device" \
|
||
"reboot"
|
||
fi
|
||
if [ "$ipl_type" = "fcp" ];then
|
||
# plain FCP device 512b blocksize
|
||
haveZFCP=1
|
||
elif [ "$ipl_type" = "ccw" ];then
|
||
if [[ "$dev_type" =~ "3390" ]];then
|
||
# plain DASD device 4k blocksize
|
||
haveDASD=1
|
||
elif [[ "$dev_type" =~ "9336" ]];then
|
||
# emulated DASD device 512b blocksize, handled as FCP device
|
||
# but don't configure host and disk as required for plain
|
||
# FCP devices
|
||
haveZFCP=1
|
||
else
|
||
systemException \
|
||
"Unknown Device type: $dev_type" \
|
||
"reboot"
|
||
fi
|
||
else
|
||
systemException \
|
||
"Unknown IPL type: $ipl_type" \
|
||
"reboot"
|
||
fi
|
||
#======================================
|
||
# check if we can find the device
|
||
#--------------------------------------
|
||
if [ ! -e /sys/bus/ccw/devices/$deviceID ];then
|
||
systemException \
|
||
"Can't find disk with ID: $deviceID" \
|
||
"reboot"
|
||
fi
|
||
#======================================
|
||
# DASD real in CDL / LDL mode
|
||
#--------------------------------------
|
||
if [ $haveDASD -eq 1 ];then
|
||
dasd_configure $deviceID 1 0
|
||
biosBootDevice="$dpath/ccw-$deviceID"
|
||
fi
|
||
#======================================
|
||
# DASD emulated in FBA mode
|
||
#--------------------------------------
|
||
if [ $haveZFCP -eq 1 ] && [ "$ipl_type" = "ccw" ];then
|
||
dasd_configure $deviceID 1 0
|
||
biosBootDevice="$dpath/ccw-$deviceID"
|
||
fi
|
||
#======================================
|
||
# ZFCP real in SCSI mode
|
||
#--------------------------------------
|
||
if [ $haveZFCP -eq 1 ] && [ "$ipl_type" = "fcp" ];then
|
||
wwpn=$(cat /sys/firmware/ipl/wwpn)
|
||
slun=$(cat /sys/firmware/ipl/lun)
|
||
zfcp_host_configure $deviceID 1
|
||
zfcp_disk_configure $deviceID $wwpn $slun 1
|
||
biosBootDevice="$dpath/ccw-$deviceID-zfcp-$wwpn:$slun"
|
||
fi
|
||
#======================================
|
||
# setup boot device variable
|
||
#--------------------------------------
|
||
waitForStorageDevice $biosBootDevice
|
||
if [ ! -e $biosBootDevice ];then
|
||
export biosBootDevice="Failed to set disk $deviceID online"
|
||
return 1
|
||
fi
|
||
export biosBootDevice=$(getDiskDevice $biosBootDevice)
|
||
return 0
|
||
}
|
||
#======================================
|
||
# setupBootDeviceIfMultipath
|
||
#--------------------------------------
|
||
function setupBootDeviceIfMultipath {
|
||
local IFS=$IFS_ORIG
|
||
local disk
|
||
local found_multipath_device=0
|
||
if startMultipathd; then
|
||
for wwn in $(multipath -l -v1 $biosBootDevice);do
|
||
disk=/dev/mapper/$wwn
|
||
if [ -e $disk ];then
|
||
biosBootDevice=$disk
|
||
found_multipath_device=1
|
||
break
|
||
fi
|
||
done
|
||
if [ ! $found_multipath_device = 1 ];then
|
||
stopMultipathd
|
||
fi
|
||
fi
|
||
}
|
||
#======================================
|
||
# lookupDiskDevices
|
||
#--------------------------------------
|
||
function lookupDiskDevices {
|
||
# /.../
|
||
# use hwinfo to search for disk device nodes
|
||
# ----
|
||
local IFS=$IFS_ORIG
|
||
local h=/usr/sbin/hwinfo
|
||
local c="Device File:|BIOS id"
|
||
udevPending
|
||
diskDevices=$($h --disk | \
|
||
grep -E "$c" | sed -e"s@(.*)@@" | cut -f2 -d: | tr -d " ")
|
||
}
|
||
#======================================
|
||
# lookupBiosBootDevice
|
||
#--------------------------------------
|
||
function lookupBiosBootDevice {
|
||
# /.../
|
||
# check for devices which have 0x80 bios flag assigned
|
||
# ----
|
||
local IFS=$IFS_ORIG
|
||
local curd
|
||
local pred
|
||
for curd in $diskDevices;do
|
||
if [ $curd = "0x80" ];then
|
||
bios=$pred
|
||
return
|
||
fi
|
||
pred=$curd
|
||
done
|
||
}
|
||
#======================================
|
||
# searchBIOSBootDevice
|
||
#--------------------------------------
|
||
function searchBIOSBootDevice {
|
||
# /.../
|
||
# search for the boot device. The edd 0x80 information
|
||
# is used here but not trusted. Trusted is the MBR disk
|
||
# disk label which is compared with the kiwi written
|
||
# mbrid file in /boot/grub/ of the system image
|
||
# If we got a root device set via cmdline this value
|
||
# takes precedence over everything else though
|
||
# ----
|
||
local IFS=$IFS_ORIG
|
||
local file=/boot/mbrid
|
||
local ifix
|
||
local match_count
|
||
local matched
|
||
local curd
|
||
local mbrML
|
||
local mbrMB
|
||
local mbrI
|
||
local try_count=0
|
||
#======================================
|
||
# Check root variable
|
||
#--------------------------------------
|
||
if [ ! -z "$root" ];then
|
||
if [[ $root =~ "UUID=" ]];then
|
||
root=/dev/disk/by-uuid/$(echo $root | cut -f2 -d=)
|
||
elif [[ $root =~ "LABEL=" ]];then
|
||
root=/dev/disk/by-label/$(echo $root | cut -f2 -d=)
|
||
fi
|
||
if ! waitForStorageDevice $root;then
|
||
Echo "Specified root device $root not found. Found devices:"
|
||
hwinfo --disk
|
||
systemException \
|
||
"root device not found... fatal !" \
|
||
"reboot"
|
||
fi
|
||
export biosBootDevice=$(dn $root)
|
||
if [ ! -e /config.partids ];then
|
||
echo "kiwi_RootPart=1" > /config.partids
|
||
fi
|
||
return 0
|
||
fi
|
||
#======================================
|
||
# Read mbrid from initrd
|
||
#--------------------------------------
|
||
if [ ! -e $file ];then
|
||
export biosBootDevice="Failed to find MBR identifier !"
|
||
return 1
|
||
fi
|
||
read mbrI < $file
|
||
#======================================
|
||
# Lookup until found
|
||
#--------------------------------------
|
||
while true;do
|
||
#======================================
|
||
# initialize variables
|
||
#--------------------------------------
|
||
ifix=0
|
||
match_count=0
|
||
try_count=$((try_count + 1))
|
||
#======================================
|
||
# stop after a long time of retry
|
||
#--------------------------------------
|
||
if [ $try_count -eq 15 ];then
|
||
export biosBootDevice="Failed to find boot device !"
|
||
return 1
|
||
fi
|
||
#======================================
|
||
# create device list
|
||
#--------------------------------------
|
||
lookupDiskDevices
|
||
lookupBiosBootDevice
|
||
#======================================
|
||
# Compare ID with MBR entry
|
||
#--------------------------------------
|
||
for curd in $diskDevices;do
|
||
if [ ! -b $curd ];then
|
||
continue
|
||
fi
|
||
mbrML=$(dd if=$curd bs=1 count=4 skip=$((0x1b8)) | \
|
||
hexdump -n4 -e '"0x%08x"')
|
||
mbrMB=$(echo $mbrML | \
|
||
sed 's/^0x\(..\)\(..\)\(..\)\(..\)$/0x\4\3\2\1/')
|
||
if [ "$mbrML" = "$mbrI" ] || [ "$mbrMB" = "$mbrI" ];then
|
||
ifix=1
|
||
matched=$curd
|
||
match_count=$(($match_count + 1))
|
||
if [ "$mbrML" = "$mbrI" ];then
|
||
export masterBootID=$mbrML
|
||
fi
|
||
if [ "$mbrMB" = "$mbrI" ];then
|
||
export masterBootID=$mbrMB
|
||
fi
|
||
if [ "$curd" = "$bios" ];then
|
||
export biosBootDevice=$curd
|
||
return 0
|
||
fi
|
||
fi
|
||
done
|
||
#======================================
|
||
# Multiple matches are bad
|
||
#--------------------------------------
|
||
if [ $match_count -gt 1 ];then
|
||
export biosBootDevice="multiple devices matches same MBR ID: $mbrI"
|
||
return 2
|
||
fi
|
||
#======================================
|
||
# Found it...
|
||
#--------------------------------------
|
||
if [ $ifix -eq 1 ];then
|
||
export biosBootDevice=$matched
|
||
return 0
|
||
fi
|
||
export biosBootDevice="No devices matches MBR ID: $mbrI !"
|
||
sleep 1
|
||
done
|
||
}
|
||
#======================================
|
||
# searchVolumeGroup
|
||
#--------------------------------------
|
||
function searchVolumeGroup {
|
||
# /.../
|
||
# search for a volume group named $kiwi_lvmgroup and if it can be
|
||
# found activate it while creating appropriate device nodes:
|
||
# /dev/$kiwi_lvmgroup/LVRoot
|
||
# return zero on success
|
||
# ----
|
||
local IFS=$IFS_ORIG
|
||
local vg_count=0
|
||
local vg_found
|
||
local fstype
|
||
if [ ! "$kiwi_lvm" = "true" ];then
|
||
return 1
|
||
fi
|
||
local rootdevice=$(ddn $imageDiskDevice $kiwi_RootPart)
|
||
fstype=$(probeFileSystem $rootdevice)
|
||
if [ "$fstype" = "luks" ];then
|
||
luksOpen $rootdevice
|
||
export haveLuks=yes
|
||
fi
|
||
for i in $(vgs --noheadings -o vg_name 2>/dev/null);do
|
||
vg_found=$(echo $i)
|
||
if [ "$vg_found" = "$kiwi_lvmgroup" ];then
|
||
vg_count=$((vg_count + 1))
|
||
fi
|
||
done
|
||
if [ $vg_count -gt 1 ];then
|
||
Echo "Duplicate VolumeGroup name $kiwi_lvmgroup found !"
|
||
Echo "$vg_count versions of this volume group exists"
|
||
Echo "The volume group name must be unique"
|
||
Echo "Please check your disks and rename/remove the duplicates"
|
||
systemException \
|
||
"VolumeGroup $kiwi_lvmgroup not unique !" \
|
||
"reboot"
|
||
fi
|
||
Echo "Activating $kiwi_lvmgroup volume group..."
|
||
vgchange -a y $kiwi_lvmgroup
|
||
}
|
||
#======================================
|
||
# deactivateVolumeGroup
|
||
#--------------------------------------
|
||
function deactivateVolumeGroup {
|
||
# /.../
|
||
# as signals/ioctls from earlier operations may
|
||
# not have been processed by the kernel or udev
|
||
# we may require a moment before 'vgchange -a n'
|
||
# return zero on success
|
||
# ----
|
||
local IFS=$IFS_ORIG
|
||
if [ ! "$kiwi_lvm" = "true" ];then
|
||
return 1
|
||
fi
|
||
udevPending
|
||
Echo "Deactivating $kiwi_lvmgroup volume group..."
|
||
vgchange -a n $kiwi_lvmgroup
|
||
udevPending
|
||
}
|
||
#======================================
|
||
# activateVolumeGroup
|
||
#--------------------------------------
|
||
function activateVolumeGroup {
|
||
# /.../
|
||
# activate volume group if LVM is present
|
||
# ----
|
||
local IFS=$IFS_ORIG
|
||
if [ ! "$kiwi_lvm" = "true" ];then
|
||
return 1
|
||
fi
|
||
udevPending
|
||
Echo "Activating $kiwi_lvmgroup volume group..."
|
||
vgchange -a y $kiwi_lvmgroup
|
||
udevPending
|
||
}
|
||
#======================================
|
||
# activateMDRaid
|
||
#--------------------------------------
|
||
function activateMDRaid {
|
||
local IFS=$IFS_ORIG
|
||
if [ ! -z "$kiwi_RaidDev" ];then
|
||
udevPending
|
||
Echo "Activating $kiwi_RaidDev mdraid array..."
|
||
mdadm --assemble --scan
|
||
waitForStorageDevice $kiwi_RaidDev
|
||
fi
|
||
}
|
||
#======================================
|
||
# resizeMDRaid
|
||
#--------------------------------------
|
||
function resizeMDRaid {
|
||
local IFS=$IFS_ORIG
|
||
if [ ! -z "$kiwi_RaidDev" ];then
|
||
udevPending
|
||
Echo "Resizing $kiwi_RaidDev mdraid array..."
|
||
mdadm --grow --size=max $kiwi_RaidDev
|
||
fi
|
||
}
|
||
#======================================
|
||
# resizeLVMPVs
|
||
#--------------------------------------
|
||
function resizeLVMPVs {
|
||
local IFS=$IFS_ORIG
|
||
local extendID=$1
|
||
local device=$(ddn $imageDiskDevice $extendID)
|
||
if [ ! -z "$kiwi_RaidDev" ];then
|
||
device=$kiwi_RaidDev
|
||
fi
|
||
if [ ! -z "$luksDeviceOpened" ];then
|
||
device=$luksDeviceOpened
|
||
fi
|
||
local unixDevice=$(getDiskDevice $device)
|
||
pvresize $unixDevice
|
||
}
|
||
#======================================
|
||
# deactivateMDRaid
|
||
#--------------------------------------
|
||
function deactivateMDRaid {
|
||
local IFS=$IFS_ORIG
|
||
if [ ! -z "$kiwi_RaidDev" ] && [ -e $kiwi_RaidDev ];then
|
||
udevPending
|
||
Echo "Deactivating $kiwi_RaidDev mdraid array..."
|
||
mdadm --stop $kiwi_RaidDev
|
||
fi
|
||
}
|
||
#======================================
|
||
# zeroMDRaidSuperBlock
|
||
#--------------------------------------
|
||
function zeroMDRaidSuperBlock {
|
||
local IFS=$IFS_ORIG
|
||
if [ ! -z "$kiwi_RaidDev" ] && [ -e $kiwi_RaidDev ];then
|
||
local diskDevice=$1
|
||
for i in /dev/md*;do
|
||
test -b $i && mdadm --stop $i &>/dev/null
|
||
done
|
||
mdadm --zero-superblock $diskDevice &>/dev/null
|
||
fi
|
||
}
|
||
#======================================
|
||
# searchSwapSpace
|
||
#--------------------------------------
|
||
function searchSwapSpace {
|
||
# /.../
|
||
# search for a type=82 swap partition
|
||
# ----
|
||
local IFS=$IFS_ORIG
|
||
if [ ! -z $kiwinoswapsearch ];then
|
||
return
|
||
fi
|
||
local hwapp=/usr/sbin/hwinfo
|
||
local diskdevs=`$hwapp --disk | grep "Device File:" | cut -f2 -d:`
|
||
diskdevs=`echo $diskdevs | sed -e "s@(.*)@@"`
|
||
for diskdev in $diskdevs;do
|
||
for disknr in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15;do
|
||
id=$(partitionID $diskdev $disknr)
|
||
if [ "$id" = "82" ];then
|
||
echo $diskdev$disknr
|
||
return
|
||
fi
|
||
done
|
||
done
|
||
}
|
||
#======================================
|
||
# updateMTAB
|
||
#--------------------------------------
|
||
function updateMTAB {
|
||
local IFS=$IFS_ORIG
|
||
local prefix=$1
|
||
local umount=0
|
||
if [ ! -e /proc/mounts ];then
|
||
mount -t proc proc /proc
|
||
umount=1
|
||
fi
|
||
if [ -e /proc/self/mounts ];then
|
||
pushd $prefix/etc >/dev/null
|
||
rm -f mtab && ln -s /proc/self/mounts mtab
|
||
popd >/dev/null
|
||
fi
|
||
if [ $umount -eq 1 ];then
|
||
umount /proc
|
||
fi
|
||
}
|
||
#======================================
|
||
# getNicNames
|
||
#--------------------------------------
|
||
function getNicNames {
|
||
local IFS=$IFS_ORIG
|
||
for nic in $(ip -4 -o link | cut -f2 -d:);do
|
||
if [ ! $nic = 'lo' ];then
|
||
echo $nic
|
||
fi
|
||
done
|
||
}
|
||
#======================================
|
||
# getHWAddress
|
||
#--------------------------------------
|
||
function getHWAddress {
|
||
local IFS=$IFS_ORIG
|
||
local iface=$1
|
||
ip addr show dev $iface |\
|
||
grep 'link\/ether ' | cut -f6 -d ' '
|
||
}
|
||
#======================================
|
||
# setupNic
|
||
#--------------------------------------
|
||
function setupNic {
|
||
local IFS=$IFS_ORIG
|
||
local iface=$1
|
||
local address=$2
|
||
local netmask=$3
|
||
ip addr flush dev $iface
|
||
# ignore netmask if address is already cidr
|
||
if [[ $address =~ / ]] ; then
|
||
ip addr add $address dev $iface
|
||
else
|
||
ip addr add $address/$netmask dev $iface
|
||
fi
|
||
ip link set dev $iface up
|
||
}
|
||
#======================================
|
||
# deleteNic
|
||
#--------------------------------------
|
||
function deleteNic {
|
||
local IFS=$IFS_ORIG
|
||
local iface=$1
|
||
local address=$2
|
||
local netmask=$3
|
||
# ignore netmask if address is already cidr
|
||
if [[ $address =~ / ]] ; then
|
||
ip addr del $address dev $iface
|
||
else
|
||
ip addr del $address/$netmask dev $iface
|
||
fi
|
||
}
|
||
#======================================
|
||
# probeNetworkCard
|
||
#--------------------------------------
|
||
function probeNetworkCard {
|
||
# /.../
|
||
# use hwinfo to probe for all network devices. The
|
||
# function will check for the driver which is needed
|
||
# to support the card and returns the information in
|
||
# the networkModule variable
|
||
# ----
|
||
local IFS="%"
|
||
local module=""
|
||
local hwicmd="/usr/sbin/hwinfo"
|
||
for i in \
|
||
`$hwicmd --netcard | grep "Driver [IA]" |
|
||
sed -es"@modprobe\(.*\)\"@\1%@" | tr -d "\n"`
|
||
do
|
||
if echo $i | grep -q "#0";then
|
||
module=`echo $i | cut -f2 -d"\"" | tr -d " "`
|
||
module=`echo $module | sed -es"@modprobe@@g"`
|
||
IFS=";"
|
||
for m in $module;do
|
||
if ! echo $networkModule | grep -q $m;then
|
||
if [ ! -z "$networkModule" ];then
|
||
networkModule="$networkModule:$m"
|
||
else
|
||
networkModule=$m
|
||
fi
|
||
fi
|
||
done
|
||
fi
|
||
done
|
||
networkModule=`echo $networkModule`
|
||
}
|
||
#======================================
|
||
# loadNetworkCard
|
||
#--------------------------------------
|
||
function loadNetworkCard {
|
||
# /.../
|
||
# load network module found by probeNetworkCard()
|
||
# ----
|
||
local IFS=$IFS_ORIG
|
||
local loaded=0
|
||
probeNetworkCard
|
||
IFS=":" ; for i in $networkModule;do
|
||
if [ ! -z "$i" ];then
|
||
modprobe $i 2>/dev/null
|
||
if [ $? = 0 ];then
|
||
loaded=1
|
||
fi
|
||
fi
|
||
done
|
||
}
|
||
#======================================
|
||
# loadNetworkCardS390
|
||
#--------------------------------------
|
||
function loadNetworkCardS390 {
|
||
# /.../
|
||
# search and include parameters from a parm file
|
||
# provided on the specified dasd id
|
||
# ----
|
||
local IFS=$IFS_ORIG
|
||
local host=$1
|
||
local skip="/etc/deactivate_s390_network_config_from_dasd"
|
||
local hostdev=/dev/disk/by-path/ccw-${host}
|
||
local parmfile_name=PARM-S11
|
||
if [ ! -z "$kiwi_oemvmcp_parmfile" ];then
|
||
parmfile_name=$kiwi_oemvmcp_parmfile
|
||
fi
|
||
Echo "Trying parm file lookup on DASD id: ${host}"
|
||
#======================================
|
||
# check if we got stopped
|
||
#--------------------------------------
|
||
if [ -e $skip ];then
|
||
Echo "Processing skipped by $skip"
|
||
rm -f $skip
|
||
return 1
|
||
fi
|
||
#======================================
|
||
# check for required tools
|
||
#--------------------------------------
|
||
if [ ! lookup cmsfscat &>/dev/null ];then
|
||
Echo "Can't find cmsfscat program required for loading"
|
||
return 1
|
||
fi
|
||
#======================================
|
||
# check for required kernel support
|
||
#--------------------------------------
|
||
# If loading vmcp fails we assume the support for it has been
|
||
# compiled into the kernel. If this is not the case we will run
|
||
# into an exception on 'vmcp query' which is the intended way
|
||
# to handle the error condition
|
||
modprobe vmcp &>/dev/null
|
||
#======================================
|
||
# bring host online
|
||
#--------------------------------------
|
||
if [ ! -b $hostdev ];then
|
||
dasd_configure ${host} 1 0
|
||
udevPending
|
||
if [ ! -b $hostdev ];then
|
||
Echo "Failed to activate DASD id: ${host}"
|
||
return 1
|
||
fi
|
||
fi
|
||
#======================================
|
||
# load parm file using cmsfscat
|
||
#--------------------------------------
|
||
Echo "Loading configuration file <UID>.${parmfile_name} from ${host}..."
|
||
local parmfile="$(vmcp query userid | cut -d ' ' -f 1).$parmfile_name"
|
||
if ! cmsfscat -d $hostdev -a "$parmfile" > /tmp/"$parmfile";then
|
||
Echo "Can't create /tmp/${parmfile} on DASD id: ${host}"
|
||
return 1
|
||
fi
|
||
#======================================
|
||
# import data into environment
|
||
#--------------------------------------
|
||
includeKernelParametersLowerCase "/tmp/$parmfile"
|
||
#======================================
|
||
# unbind host and cleanup
|
||
#--------------------------------------
|
||
rm -f "/tmp/$parmfile"
|
||
dasd_configure ${host} 0 0
|
||
return 0
|
||
}
|
||
#======================================
|
||
# dhclientImportInfo
|
||
#-------------------------------------
|
||
function dhclientImportInfo {
|
||
# /.../
|
||
# Import and export the information form the
|
||
# dhclient.lease file into the enviroment.
|
||
# ----
|
||
local IFS=$IFS_ORIG
|
||
if [ ! -n $1 ]; then
|
||
Echo "NULL argument passed to dhclientImportInfo"
|
||
return
|
||
fi
|
||
local lease=/var/lib/dhclient/$1.lease
|
||
export IPADDR=$(
|
||
cat $lease | grep 'fixed-address'|\
|
||
awk '{print $2}' | tr -d ';'
|
||
)
|
||
export NETMASK=$(
|
||
cat $lease | grep 'subnet-mask'|\
|
||
awk '{print $3}' | tr -d ';'
|
||
)
|
||
export GATEWAYS=$(
|
||
cat $lease | grep 'routers ' |\
|
||
awk '{print $3}' |tr -d ';'
|
||
)
|
||
export DOMAIN=$(
|
||
cat $lease | grep 'domain-name' | grep -v 'domain-name-server' |\
|
||
awk '{print $3}'| tr -d ';'
|
||
)
|
||
export DNSSERVERS=$(
|
||
cat $lease | grep 'domain-name-servers'|\
|
||
awk '{print $3}'| tr -d ';' | tr ',' ' '
|
||
)
|
||
export DHCPSIADDR=$(
|
||
cat $lease | grep 'dhcp-server-identifier'|\
|
||
awk '{print $3}'| tr -d ';' | tr ',' ' '
|
||
)
|
||
export DNS=$DNSSERVERS
|
||
export DHCPCHADDR=$(
|
||
ip link show $1 | grep link | awk '{print $2}' | tr a-z A-Z
|
||
)
|
||
}
|
||
#======================================
|
||
# setupNetworkWicked
|
||
#--------------------------------------
|
||
function setupNetworkWicked {
|
||
# /.../
|
||
# assign DHCP IP address by using the wicked tool
|
||
# ----
|
||
local IFS=$IFS_ORIG
|
||
local nic_config
|
||
local dhcp_info
|
||
local wicked_request
|
||
local wicked_dhcp4=/usr/lib/wicked/bin/wickedd-dhcp4
|
||
for try_iface in ${dev_list[*]}; do
|
||
# try DHCP_DISCOVER on all interfaces
|
||
if setIPLinkUp $try_iface; then
|
||
dhcp_info=/var/run/wicked/wicked-${try_iface}.info
|
||
$wicked_dhcp4 --debug all \
|
||
--test --test-output $dhcp_info $try_iface
|
||
if [ $? = 0 ] && [ -s $dhcp_info ];then
|
||
DHCPCD_STARTED="$DHCPCD_STARTED $try_iface"
|
||
fi
|
||
fi
|
||
done
|
||
if [ -z "$DHCPCD_STARTED" ];then
|
||
if [ -e "$root" ];then
|
||
Echo "Failed to setup DHCP network interface !"
|
||
Echo "Try fallback to local boot on: $root"
|
||
LOCAL_BOOT=yes
|
||
return
|
||
else
|
||
systemException \
|
||
"Failed to setup DHCP network interface !" \
|
||
"reboot"
|
||
fi
|
||
fi
|
||
#======================================
|
||
# wait for any preferred interface(s)
|
||
#--------------------------------------
|
||
for repeat_dhcp_on_discovered in 1 2 ;do
|
||
for try_iface in ${prefer_iface[*]} ; do
|
||
dhcp_info=/var/run/wicked/wicked-${try_iface}.info
|
||
if waitForDHCPInterfaceNegotiation $dhcp_info; then
|
||
break 2
|
||
fi
|
||
done
|
||
sleep 2
|
||
# /.../
|
||
# we are behind the wicked dhcp timeout 20s so the only thing
|
||
# we can do now is to try again on discovered interfaces
|
||
# ----
|
||
for try_iface in $DHCPCD_STARTED; do
|
||
dhcp_info=/var/run/wicked/wicked-${try_iface}.info
|
||
$wicked_dhcp4 --debug all \
|
||
--test --test-output $dhcp_info $try_iface
|
||
done
|
||
sleep 2
|
||
done
|
||
#============================================
|
||
# select interface from discovered devices
|
||
#--------------------------------------------
|
||
for try_iface in ${prefer_iface[*]} $DHCPCD_STARTED; do
|
||
dhcp_info=/var/run/wicked/wicked-${try_iface}.info
|
||
if [ -s $dhcp_info ] && grep -q "^IPADDR=" $dhcp_info; then
|
||
wicked_request='<request type="lease">'
|
||
wicked_request="$wicked_request<lease-time>3600</lease-time>"
|
||
wicked_request="$wicked_request</request>"
|
||
echo $wicked_request |\
|
||
wicked test dhcp4 --request - -- $try_iface > $dhcp_info
|
||
if [ $? = 0 ];then
|
||
export PXE_IFACE=$try_iface
|
||
break
|
||
fi
|
||
fi
|
||
done
|
||
#======================================
|
||
# fallback to local boot if possible
|
||
#--------------------------------------
|
||
if [ -z "$PXE_IFACE" ];then
|
||
if [ -e "$root" ];then
|
||
Echo "Can't get DHCP reply on any interface !"
|
||
Echo "Try fallback to local boot on: $root"
|
||
LOCAL_BOOT=yes
|
||
return
|
||
else
|
||
systemException \
|
||
"Can't get DHCP reply on any interface !" \
|
||
"reboot"
|
||
fi
|
||
fi
|
||
#======================================
|
||
# setup selected interface
|
||
#--------------------------------------
|
||
dhcp_info=/var/run/wicked/wicked-${PXE_IFACE}.info
|
||
if [ -s $dhcp_info ]; then
|
||
waitForDHCPInterfaceNegotiation $dhcp_info
|
||
importFile < $dhcp_info
|
||
IPADDR=$(echo $IPADDR | cut -f1 -d/)
|
||
if setupNic $PXE_IFACE $IPADDR $NETMASK; then
|
||
if ip route add default dev $PXE_IFACE; then
|
||
if [ ! -z "$GATEWAYS" ];then
|
||
# Use first entry as primary gateway
|
||
local gw=$(echo $GATEWAYS | cut -f1 -d " ")
|
||
if ! ip route change default via $gw dev $PXE_IFACE; then
|
||
systemException \
|
||
"Failed to change default GW on $PXE_IFACE !" \
|
||
"reboot"
|
||
fi
|
||
fi
|
||
else
|
||
systemException \
|
||
"Failed to setup default route on $PXE_IFACE !" \
|
||
"reboot"
|
||
fi
|
||
else
|
||
systemException \
|
||
"Failed to setup IP address on $PXE_IFACE !" \
|
||
"reboot"
|
||
fi
|
||
fi
|
||
}
|
||
#======================================
|
||
# setupNetworkDHCPCD
|
||
#--------------------------------------
|
||
function setupNetworkDHCPCD {
|
||
# /.../
|
||
# assign DHCP IP address by using the dhcpcd tool
|
||
# ----
|
||
local IFS=$IFS_ORIG
|
||
if [ $DHCPCD_HAVE_PERSIST -eq 0 ];then
|
||
# /.../
|
||
# older version of dhcpd which doesn't have the
|
||
# options we want to pass
|
||
# ----
|
||
unset opts
|
||
fi
|
||
mkdir -p /var/lib/dhcpcd
|
||
for try_iface in ${dev_list[*]}; do
|
||
# try DHCP_DISCOVER on all interfaces
|
||
dhcpcd $opts -T $try_iface > /var/lib/dhcpcd/dhcpcd-$try_iface.info &
|
||
DHCPCD_STARTED="$DHCPCD_STARTED $try_iface"
|
||
done
|
||
if [ -z "$DHCPCD_STARTED" ];then
|
||
if [ -e "$root" ];then
|
||
Echo "Failed to setup DHCP network interface !"
|
||
Echo "Try fallback to local boot on: $root"
|
||
LOCAL_BOOT=yes
|
||
return
|
||
else
|
||
systemException \
|
||
"Failed to setup DHCP network interface !" \
|
||
"reboot"
|
||
fi
|
||
fi
|
||
#======================================
|
||
# wait for any preferred interface(s)
|
||
#--------------------------------------
|
||
for j in 1 2 ;do
|
||
for i in 1 2 3 4 5 6 7 8 9 10 11;do
|
||
for try_iface in ${prefer_iface[*]} ; do
|
||
if [ -s /var/lib/dhcpcd/dhcpcd-$try_iface.info ] &&
|
||
grep -q "^IPADDR=" /var/lib/dhcpcd/dhcpcd-$try_iface.info
|
||
then
|
||
break 3
|
||
fi
|
||
done
|
||
sleep 2
|
||
done
|
||
# /.../
|
||
# we are behind the dhcpcd timeout 20s so the only thing
|
||
# we can do now is to try again
|
||
# ----
|
||
for try_iface in $DHCPCD_STARTED; do
|
||
dhcpcd $opts -T $try_iface \
|
||
> /var/lib/dhcpcd/dhcpcd-$try_iface.info &
|
||
done
|
||
sleep 2
|
||
done
|
||
#======================================
|
||
# select interface from preferred list
|
||
#--------------------------------------
|
||
for try_iface in ${prefer_iface[*]} $DHCPCD_STARTED; do
|
||
if [ -s /var/lib/dhcpcd/dhcpcd-$try_iface.info ] &&
|
||
grep -q "^IPADDR=" /var/lib/dhcpcd/dhcpcd-$try_iface.info
|
||
then
|
||
export PXE_IFACE=$try_iface
|
||
eval `grep "^IPADDR=" /var/lib/dhcpcd/dhcpcd-$try_iface.info`
|
||
rm /var/lib/dhcpcd/dhcpcd-$try_iface.info
|
||
# continue with the DHCP protocol on the selected interface
|
||
if [ -e /var/run/dhcpcd-$PXE_IFACE.pid ];then
|
||
rm -f /var/run/dhcpcd-$PXE_IFACE.pid
|
||
fi
|
||
if [ $DHCPCD_HAVE_PERSIST -eq 0 ];then
|
||
# /.../
|
||
# older version of dhcpd which doesn't provide
|
||
# an option to request a specific IP address
|
||
# ----
|
||
dhcpcd $opts $PXE_IFACE 2>&1
|
||
else
|
||
dhcpcd $opts -r $IPADDR $PXE_IFACE 2>&1
|
||
fi
|
||
break
|
||
fi
|
||
done
|
||
#======================================
|
||
# fallback to local boot if possible
|
||
#--------------------------------------
|
||
if [ -z "$PXE_IFACE" ];then
|
||
if [ -e "$root" ];then
|
||
Echo "Can't get DHCP reply on any interface !"
|
||
Echo "Try fallback to local boot on: $root"
|
||
LOCAL_BOOT=yes
|
||
return
|
||
else
|
||
systemException \
|
||
"Can't get DHCP reply on any interface !" \
|
||
"reboot"
|
||
fi
|
||
fi
|
||
#======================================
|
||
# wait for iface to finish negotiation
|
||
#--------------------------------------
|
||
for i in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20;do
|
||
if [ -s /var/lib/dhcpcd/dhcpcd-$PXE_IFACE.info ] &&
|
||
grep -q "^IPADDR=" /var/lib/dhcpcd/dhcpcd-$PXE_IFACE.info
|
||
then
|
||
break
|
||
fi
|
||
sleep 2
|
||
done
|
||
#======================================
|
||
# setup selected interface
|
||
#--------------------------------------
|
||
setupNic lo 127.0.0.1/8 255.0.0.0
|
||
if [ -s /var/lib/dhcpcd/dhcpcd-$PXE_IFACE.info ] &&
|
||
grep -q "^IPADDR=" /var/lib/dhcpcd/dhcpcd-$PXE_IFACE.info; then
|
||
importFile < /var/lib/dhcpcd/dhcpcd-$PXE_IFACE.info
|
||
fi
|
||
}
|
||
#======================================
|
||
# setupNetworkDHCLIENT
|
||
#--------------------------------------
|
||
function setupNetworkDHCLIENT {
|
||
# /.../
|
||
# assign DHCP IP address by using the dhclient tool
|
||
# ----
|
||
local IFS=$IFS_ORIG
|
||
local dhclient_opts=" -4 -1 -q"
|
||
mkdir -p /var/lib/dhclient
|
||
mkdir -p /var/run
|
||
for try_iface in ${dev_list[*]}; do
|
||
# try DHCP_DISCOVER on all interfaces
|
||
dhclient $dhclient_opts \
|
||
-lf /var/lib/dhclient/${try_iface}.lease \
|
||
-pf /var/run/dhclient-${try_iface}.pid ${try_iface}
|
||
DHCPCD_STARTED="$DHCPCD_STARTED $try_iface"
|
||
done
|
||
if [ -z "$DHCPCD_STARTED" ];then
|
||
if [ -e "$root" ];then
|
||
Echo "Failed to setup DHCP network interface !"
|
||
Echo "Try fallback to local boot on: $root"
|
||
LOCAL_BOOT=yes
|
||
return
|
||
else
|
||
systemException \
|
||
"Failed to setup DHCP network interface !" \
|
||
"reboot"
|
||
fi
|
||
fi
|
||
#======================================
|
||
# wait for any preferred interface(s)
|
||
#--------------------------------------
|
||
for j in 1 2 ;do
|
||
for i in 1 2 3 4 5 6 7 8 9 10 11;do
|
||
for try_iface in ${prefer_iface[*]} ; do
|
||
if [ -f /var/lib/dhclient/${try_iface}.lease ] &&
|
||
grep -q "fixed-address" /var/lib/dhclient/${try_iface}.lease
|
||
then
|
||
break 3
|
||
fi
|
||
done
|
||
sleep 2
|
||
done
|
||
# /.../
|
||
# we are behind the dhclient timeout 20s so the only thing
|
||
# we can do now is to try again
|
||
# ----
|
||
for try_iface in $DHCPCD_STARTED; do
|
||
dhclient $dhclient_opts \
|
||
-lf /var/lib/dhclient/${try_iface}.lease \
|
||
-pf /var/run/dhclient-${try_iface}.pid ${try_iface}
|
||
done
|
||
sleep 2
|
||
done
|
||
#======================================
|
||
# select interface from preferred list
|
||
#--------------------------------------
|
||
for try_iface in ${prefer_iface[*]} $DHCPCD_STARTED; do
|
||
if [ -f /var/lib/dhclient/${try_iface}.lease ] &&
|
||
grep -q "fixed-address" /var/lib/dhclient/${try_iface}.lease
|
||
then
|
||
export PXE_IFACE=$try_iface
|
||
export IPADDR=$(
|
||
cat /var/lib/dhclient/${try_iface}.lease |\
|
||
grep 'fixed-address'| awk '{print $2}' | tr -d ';'
|
||
)
|
||
break
|
||
fi
|
||
done
|
||
#======================================
|
||
# setup selected interface
|
||
#--------------------------------------
|
||
setupNic lo 127.0.0.1/8 255.0.0.0
|
||
if [ -f /var/lib/dhclient/$PXE_IFACE.lease ] &&
|
||
grep -q "fixed-address" /var/lib/dhclient/$PXE_IFACE.lease; then
|
||
dhclientImportInfo "$PXE_IFACE"
|
||
fi
|
||
}
|
||
#======================================
|
||
# setupNetwork
|
||
#--------------------------------------
|
||
function setupNetwork {
|
||
# /.../
|
||
# probe for the existing network interface names and
|
||
# hardware addresses. Match the BOOTIF address from PXE
|
||
# to the correct linux interface name. Setup the network
|
||
# interface using a dhcp request. On success the dhcp
|
||
# info file is imported into the current shell environment
|
||
# and the nameserver information is written to
|
||
# /etc/resolv.conf
|
||
# ----
|
||
local IFS=$IFS_ORIG
|
||
#======================================
|
||
# local variable setup
|
||
#--------------------------------------
|
||
local MAC=0
|
||
local DEV=0
|
||
local mac_list=0
|
||
local dev_list=0
|
||
local index=0
|
||
local hwicmd=/usr/sbin/hwinfo
|
||
local opts="--noipv4ll -p"
|
||
local try_iface
|
||
export DHCPCD_STARTED=""
|
||
#======================================
|
||
# detect iface and HWaddr
|
||
#--------------------------------------
|
||
for DEV in $(getNicNames);do
|
||
MAC=$(getHWAddress $DEV)
|
||
mac_list[$index]=$MAC
|
||
dev_list[$index]=$DEV
|
||
index=$((index + 1))
|
||
done
|
||
if [ $index = 0 ];then
|
||
systemException \
|
||
"No network interfaces found" \
|
||
"reboot"
|
||
fi
|
||
#======================================
|
||
# preselect first nic as a start
|
||
#--------------------------------------
|
||
export prefer_iface=${dev_list[0]}
|
||
#======================================
|
||
# continue to be smarter in nic check
|
||
#--------------------------------------
|
||
if [ -z "$BOOTIF" ];then
|
||
# /.../
|
||
# there is no PXE boot interface information. We will use
|
||
# the first interface that responds to dhcp
|
||
# ----
|
||
prefer_iface=${dev_list[*]}
|
||
else
|
||
# /.../
|
||
# evaluate the information from the PXE boot interface
|
||
# if we found the MAC in the list the appropriate interface
|
||
# name is assigned.
|
||
# ----
|
||
index=0
|
||
BOOTIF=$(echo $BOOTIF | cut -f2- -d - | tr "-" ":")
|
||
for i in ${mac_list[*]};do
|
||
list_iface=$(echo $i | tr [:upper:] [:lower:])
|
||
if [ $list_iface = $BOOTIF ];then
|
||
prefer_iface=${dev_list[$index]}
|
||
fi
|
||
index=$((index + 1))
|
||
done
|
||
fi
|
||
#======================================
|
||
# ask for an address
|
||
#--------------------------------------
|
||
if lookup wicked &>/dev/null; then
|
||
setupNetworkWicked
|
||
elif lookup dhcpcd &>/dev/null; then
|
||
setupNetworkDHCPCD
|
||
elif lookup dhclient &>/dev/null; then
|
||
setupNetworkDHCLIENT
|
||
else
|
||
Echo "No supported DHCP client tool found (dhcpcd/dhclient)"
|
||
return 1
|
||
fi
|
||
#======================================
|
||
# check if we got an address
|
||
#--------------------------------------
|
||
if [ -z "$IPADDR" ];then
|
||
if [ -e "$root" ];then
|
||
Echo "Can't assign IP addr via dhcp info: dhcpcd-$PXE_IFACE.info !"
|
||
Echo "Try fallback to local boot on: $root"
|
||
LOCAL_BOOT=yes
|
||
return
|
||
else
|
||
systemException \
|
||
"Can't assign IP addr via dhcp info: dhcpcd-$PXE_IFACE.info !" \
|
||
"reboot"
|
||
fi
|
||
fi
|
||
if [ -z "$DOMAIN" ] && [ -n "$DNSDOMAIN" ];then
|
||
export DOMAIN=$DNSDOMAIN
|
||
fi
|
||
echo "search $DOMAIN" > /etc/resolv.conf
|
||
if [ -z "$DNS" ] && [ -n "$DNSSERVERS" ];then
|
||
export DNS=$DNSSERVERS
|
||
fi
|
||
IFS=", " ; for i in $DNS;do
|
||
echo "nameserver $i" >> /etc/resolv.conf
|
||
done
|
||
export DHCPCHADDR=$(
|
||
ip link show dev $PXE_IFACE | grep link | awk '{print $2}' | tr a-z A-Z
|
||
)
|
||
}
|
||
#======================================
|
||
# releaseNetwork
|
||
#--------------------------------------
|
||
function releaseNetwork {
|
||
# /.../
|
||
# clean network setup and free the lease. If no tool could
|
||
# be found to communicate with the dhcp server in order to
|
||
# free the lease, the default behavior will just clean the
|
||
# network. The method will only be effective if the root
|
||
# device of the system is a _non_ network root device
|
||
# ----
|
||
local IFS=$IFS_ORIG
|
||
if [ -z "$NFSROOT" ] && [ -z "$NBDROOT" ] && [ -z "$AOEROOT" ];then
|
||
if lookup dhcpcd &>/dev/null; then
|
||
#======================================
|
||
# unset dhcp info variables
|
||
#--------------------------------------
|
||
unsetFile < /var/lib/dhcpcd/dhcpcd-$PXE_IFACE.info
|
||
#======================================
|
||
# free the lease and the cache
|
||
#--------------------------------------
|
||
dhcpcd -k $PXE_IFACE
|
||
elif lookup dhclient &>/dev/null; then
|
||
#======================================
|
||
# unset dhclient info variables
|
||
#--------------------------------------
|
||
unset IPADDR
|
||
unset GATEWAYS
|
||
unset DNSSERVERS
|
||
unset NETMASK
|
||
unset DOMAIN
|
||
unset DNSSERVERS
|
||
unset DNS
|
||
unset DHCPCHADDR
|
||
#======================================
|
||
# free the lease and the cache
|
||
#--------------------------------------
|
||
kill -9 $(cat /var/run/dhclient-$PXE_IFACE.pid )
|
||
dhclient -r \
|
||
-lf /var/lib/dhclient/$PXE_IFACE.lease $PXE_IFACE
|
||
else
|
||
deleteNic $PXE_IFACE $IPADDR $NETMASK
|
||
fi
|
||
#======================================
|
||
# remove sysconfig state information
|
||
#--------------------------------------
|
||
rm -rf /dev/.sysconfig/network
|
||
#======================================
|
||
# unset host information
|
||
#--------------------------------------
|
||
unset HOSTNAME
|
||
fi
|
||
}
|
||
#======================================
|
||
# setupNetworkInterfaceS390
|
||
#--------------------------------------
|
||
function setupNetworkInterfaceS390 {
|
||
# /.../
|
||
# bring up the network card according to the parm file
|
||
# parameters and create the correspondent udev rules
|
||
# needs includeKernelParametersLowerCase to be run
|
||
# because parm file parameters are case insensitive
|
||
# ----
|
||
local IFS=$IFS_ORIG
|
||
case "$instnetdev" in
|
||
"osa"|"hsi")
|
||
local qeth_cmd="/sbin/qeth_configure"
|
||
if [ "$layer2" = "1" ];then
|
||
qeth_cmd="$qeth_cmd -l"
|
||
fi
|
||
if [ -n "$portname" ];then
|
||
qeth_cmd="$qeth_cmd -p $portname"
|
||
fi
|
||
if [ -n "$portno" ];then
|
||
qeth_cmd="$qeth_cmd -n $portno"
|
||
fi
|
||
qeth_cmd="$qeth_cmd $readchannel $writechannel"
|
||
if [ -n "$datachannel" ];then
|
||
qeth_cmd="$qeth_cmd $datachannel"
|
||
fi
|
||
eval $qeth_cmd 1
|
||
;;
|
||
"ctc")
|
||
/sbin/ctc_configure $readchannel $writechannel 1 $ctcprotocol
|
||
;;
|
||
"iucv")
|
||
/sbin/iucv_configure $iucvpeer 1
|
||
;;
|
||
*)
|
||
if [ -e "$root" ];then
|
||
Echo "Unknown s390 network type: $instnetdev"
|
||
Echo "Try fallback to local boot on: $root"
|
||
LOCAL_BOOT=yes
|
||
return
|
||
else
|
||
systemException \
|
||
"Unknown s390 network type: $instnetdev" \
|
||
"reboot"
|
||
fi
|
||
;;
|
||
esac
|
||
if [ ! $? = 0 ];then
|
||
if [ -e "$root" ];then
|
||
Echo "Failed to bring up the network: $instnetdev"
|
||
Echo "Try fallback to local boot on: $root"
|
||
LOCAL_BOOT=yes
|
||
return
|
||
else
|
||
systemException \
|
||
"Failed to bring up the network: $instnetdev" \
|
||
"reboot"
|
||
fi
|
||
fi
|
||
udevPending
|
||
}
|
||
#======================================
|
||
# convertCIDRToNetmask
|
||
#--------------------------------------
|
||
function convertCIDRToNetmask {
|
||
# /.../
|
||
# convert the CIDR part to a useable netmask
|
||
# ----
|
||
local IFS=$IFS_ORIG
|
||
local cidr=$1
|
||
local count=0
|
||
for count in `seq 1 4`;do
|
||
if [ $((cidr / 8)) -gt 0 ];then
|
||
echo -n 255
|
||
else
|
||
local remainder=$((cidr % 8))
|
||
if [ $remainder -gt 0 ];then
|
||
echo -n $(( value = 256 - (256 >> remainder)))
|
||
else
|
||
echo -n 0
|
||
fi
|
||
fi
|
||
cidr=$((cidr - 8))
|
||
if [ $count -lt 4 ];then
|
||
echo -n .
|
||
fi
|
||
done
|
||
echo
|
||
}
|
||
#======================================
|
||
# setupNetworkStatic
|
||
#--------------------------------------
|
||
function setupNetworkStatic {
|
||
# /.../
|
||
# configure static network either bring it up manually
|
||
# or save the configuration depending on 'up' parameter
|
||
# ----
|
||
local IFS=$IFS_ORIG
|
||
local up=$1
|
||
if [[ $hostip =~ / ]];then
|
||
#======================================
|
||
# convert CIDR to netmask
|
||
#--------------------------------------
|
||
netmask=$(convertCIDRToNetmask $(echo $hostip | cut -f2 -d/))
|
||
fi
|
||
if [ "$up" = "1" ];then
|
||
#======================================
|
||
# activate network
|
||
#--------------------------------------
|
||
# Please note: It is assumed the last interface in the list is the
|
||
# one which should receive the interface config. While the loopback
|
||
# interface is skipped this could still result in an unexpected
|
||
# behavior.
|
||
local iface=$(
|
||
cat /proc/net/dev|grep -v lo:|tail -n1|cut -d':' -f1|sed 's/ //g'
|
||
)
|
||
if ! setupNic $iface $hostip $netmask;then
|
||
if [ -e "$root" ];then
|
||
Echo "Failed to set up the network: $iface"
|
||
Echo "Try fallback to local boot on: $root"
|
||
LOCAL_BOOT=yes
|
||
return
|
||
else
|
||
systemException \
|
||
"Failed to set up the network: $iface" \
|
||
"reboot"
|
||
fi
|
||
fi
|
||
export iface_static=$iface
|
||
elif [ ! -z $iface_static ];then
|
||
#======================================
|
||
# write network setup
|
||
#--------------------------------------
|
||
local netFile="/etc/sysconfig/network/ifcfg-$iface_static"
|
||
echo "BOOTPROTO='static'" > $netFile
|
||
echo "STARTMODE='auto'" >> $netFile
|
||
echo "IPADDR='$hostip'" >> $netFile
|
||
echo "NETMASK='$netmask'" >> $netFile
|
||
if [ -n "$broadcast" ];then
|
||
echo "BROADCAST='$broadcast'" >> $netFile
|
||
fi
|
||
if [ -n "$pointopoint" ];then
|
||
echo "REMOTE_IPADDR='$pointopoint'" >> $netFile
|
||
fi
|
||
fi
|
||
setupDefaultGateway $up
|
||
setupDNS
|
||
}
|
||
#======================================
|
||
# setupDefaultGateway
|
||
#--------------------------------------
|
||
function setupDefaultGateway {
|
||
# /.../
|
||
# setup default gateway. either set the route or save
|
||
# the configuration depending on 'up' parameter
|
||
# ----
|
||
local IFS=$IFS_ORIG
|
||
local up=$1
|
||
if [ "$up" == "1" ];then
|
||
#======================================
|
||
# activate GW route
|
||
#--------------------------------------
|
||
ip route add default via $gateway
|
||
else
|
||
#======================================
|
||
# write GW configuration
|
||
#--------------------------------------
|
||
echo "default $gateway - -" > "/etc/sysconfig/network/routes"
|
||
fi
|
||
}
|
||
#======================================
|
||
# setupDNS
|
||
#--------------------------------------
|
||
function setupDNS {
|
||
# /.../
|
||
# setup DNS. write data to resolv.conf
|
||
# ----
|
||
local IFS=$IFS_ORIG
|
||
local file="/etc/resolv.conf"
|
||
if [ -n "$domain" ];then
|
||
export DOMAIN=$domain
|
||
local line="search $domain"
|
||
if ! grep -q $line $file;then
|
||
echo "$line" >> "$file"
|
||
fi
|
||
fi
|
||
if [ -n "$nameserver" ];then
|
||
export DNS=$nameserver
|
||
IFS=", " ; for i in $nameserver;do
|
||
local line="nameserver $i"
|
||
if ! grep -q $line $file;then
|
||
echo "$line" >> "$file"
|
||
fi
|
||
done
|
||
fi
|
||
}
|
||
#======================================
|
||
# fetchImageMD5
|
||
#--------------------------------------
|
||
function fetchImageMD5 {
|
||
# /.../
|
||
# download image.md5 file either from the network
|
||
# or from a local cache directory if specified by
|
||
# KIWI_LOCAL_CACHE_DIR.
|
||
# ----
|
||
local IFS=$IFS_ORIG
|
||
local imageMD5s="image/$1-$2.md5"
|
||
local imageServer=$3
|
||
local imageBlkSize=$4
|
||
local error=0
|
||
[ -z "$imageServer" ] && imageServer=$SERVER
|
||
[ -z "$imageBlkSize" ] && imageBlkSize=8192
|
||
#======================================
|
||
# Check for MD5 in the local cache
|
||
#--------------------------------------
|
||
if [ -n "$KIWI_LOCAL_CACHE_DIR" ];then
|
||
local cached_md5="$KIWI_LOCAL_CACHE_DIR/$imageMD5s"
|
||
if [ -f "$cached_md5" ];then
|
||
read sum_local blocks blocksize zblocks zblocksize < "$cached_md5"
|
||
fi
|
||
fi
|
||
#======================================
|
||
# Download latest MD5 from the network
|
||
#--------------------------------------
|
||
fetchFile $imageMD5s /etc/image.md5 uncompressed $imageServer
|
||
#======================================
|
||
# Check results if download failed
|
||
#--------------------------------------
|
||
if test $loadCode != 0 || ! loadOK "$loadStatus"; then
|
||
Echo "Download of $imageMD5s failed: $loadStatus"
|
||
if [ -z "$sum_local" ]; then
|
||
Echo "Fatal: No cache copy available"
|
||
error=1
|
||
else
|
||
Echo "Using cache copy: $KIWI_LOCAL_CACHE_DIR/$imageMD5s"
|
||
cp "$KIWI_LOCAL_CACHE_DIR/$imageMD5s" /etc/image.md5
|
||
error=0
|
||
fi
|
||
fi
|
||
#======================================
|
||
# Check error state
|
||
#--------------------------------------
|
||
# failed MD5 download and no cache copy is fatal
|
||
if [ $error -eq 1 ];then
|
||
systemException \
|
||
"Failed to provide image MD5 data" \
|
||
"reboot"
|
||
fi
|
||
#======================================
|
||
# Read in provided MD5 data
|
||
#--------------------------------------
|
||
read sum1 blocks blocksize zblocks zblocksize < /etc/image.md5
|
||
}
|
||
|
||
#======================================
|
||
# updateNeeded
|
||
#--------------------------------------
|
||
function updateNeeded {
|
||
# /.../
|
||
# check the contents of the IMAGE key and compare the
|
||
# image version file as well as the md5 sum of the installed
|
||
# and the available image on the tftp server
|
||
# ----
|
||
#======================================
|
||
# Local variables
|
||
#--------------------------------------
|
||
local IFS=$IFS_ORIG
|
||
local count=0
|
||
local sum2
|
||
local installed
|
||
local field
|
||
local atversion
|
||
local versionFile
|
||
local imageName
|
||
local imageVersion
|
||
local imageServer
|
||
local imageBlkSize
|
||
local imageZipped
|
||
local prefix=/mnt
|
||
#======================================
|
||
# Global variables
|
||
#--------------------------------------
|
||
SYSTEM_INTEGRITY=""
|
||
SYSTEM_MD5STATUS=""
|
||
#======================================
|
||
# Check system update status via md5
|
||
#--------------------------------------
|
||
IFS="," ; for i in $IMAGE;do
|
||
field=0
|
||
IFS=";" ; for n in $i;do
|
||
case $field in
|
||
0) field=1 ;;
|
||
1) imageName=$n ; field=2 ;;
|
||
2) imageVersion=$n; field=3 ;;
|
||
3) imageServer=$n ; field=4 ;;
|
||
4) imageBlkSize=$n; field=5 ;;
|
||
5) imageZipped=$n ;
|
||
esac
|
||
done
|
||
atversion="$imageName-$imageVersion"
|
||
versionFile="$prefix/etc/ImageVersion-$atversion"
|
||
IFS=" "
|
||
if [ -f "$versionFile" ];then
|
||
read installed sum2 < $versionFile
|
||
fi
|
||
fetchImageMD5 \
|
||
"$imageName" "$imageVersion" \
|
||
"$imageServer" "$imageBlkSize"
|
||
if [ ! -z "$sum1" ];then
|
||
SYSTEM_MD5STATUS="$SYSTEM_MD5STATUS:$sum1"
|
||
else
|
||
SYSTEM_MD5STATUS="$SYSTEM_MD5STATUS:none"
|
||
fi
|
||
if [ ! -z "$1" ];then
|
||
continue
|
||
fi
|
||
if test "$count" = 1;then
|
||
if test "$SYSTEM_INTEGRITY" = ":clean";then
|
||
Echo "Main OS image update needed"
|
||
Echo -b "Forcing download for multi image session"
|
||
RELOAD_IMAGE="yes"
|
||
fi
|
||
fi
|
||
count=$(($count + 1))
|
||
Echo "Checking update status for image: $imageName"
|
||
if test ! -z $RELOAD_IMAGE;then
|
||
Echo -b "Update forced via RELOAD_IMAGE..."
|
||
Echo -b "Update status: Clean"
|
||
SYSTEM_INTEGRITY="$SYSTEM_INTEGRITY:clean"
|
||
continue
|
||
fi
|
||
if test ! -f $versionFile;then
|
||
Echo -b "Update forced: /etc/ImageVersion-$atversion not found"
|
||
Echo -b "Update status: Clean"
|
||
SYSTEM_INTEGRITY="$SYSTEM_INTEGRITY:clean"
|
||
RELOAD_IMAGE="yes"
|
||
continue
|
||
fi
|
||
Echo -b "Current: $atversion Installed: $installed"
|
||
if test "$atversion" = "$installed";then
|
||
if test "$sum1" = "$sum2";then
|
||
Echo -b "Update status: Fine"
|
||
SYSTEM_INTEGRITY="$SYSTEM_INTEGRITY:fine"
|
||
continue
|
||
fi
|
||
Echo -b "Image Update for image [ $imageName ] needed"
|
||
Echo -b "Image version equals but md5 checksum failed"
|
||
Echo -b "This means the contents of the new image differ"
|
||
RELOAD_IMAGE="yes"
|
||
else
|
||
Echo -b "Image Update for image [ $imageName ] needed"
|
||
Echo -b "Name and/or image version differ"
|
||
RELOAD_IMAGE="yes"
|
||
fi
|
||
Echo -b "Update status: Clean"
|
||
SYSTEM_INTEGRITY="$SYSTEM_INTEGRITY:clean"
|
||
done
|
||
SYSTEM_INTEGRITY=`echo $SYSTEM_INTEGRITY | cut -f2- -d:`
|
||
SYSTEM_MD5STATUS=`echo $SYSTEM_MD5STATUS | cut -f2- -d:`
|
||
}
|
||
#======================================
|
||
# cleanSweep
|
||
#--------------------------------------
|
||
function cleanSweep {
|
||
# /.../
|
||
# zero out a the given disk device
|
||
# ----
|
||
local IFS=$IFS_ORIG
|
||
local diskDevice=$1
|
||
dd if=/dev/zero of=$diskDevice bs=32M >/dev/null
|
||
}
|
||
#======================================
|
||
# fdasdGetPartitionID
|
||
#--------------------------------------
|
||
function fdasdGetPartitionID {
|
||
local IFS=$IFS_ORIG
|
||
local device=$1
|
||
local partid=$2
|
||
local count=1
|
||
for i in $(fdasd -s -p $device | grep -E '^[ ]+\/' |\
|
||
awk -v OFS=":" '$1=$1' | cut -f7 -d:)
|
||
do
|
||
if [ $count -eq $partid ];then
|
||
if [ $i = "native" ];then
|
||
echo 83
|
||
elif [ $i = "swap" ];then
|
||
echo 82
|
||
else
|
||
# /.../
|
||
# don't know this partition information
|
||
# assume it's a linux partition
|
||
# ----
|
||
echo 83
|
||
fi
|
||
return
|
||
fi
|
||
count=$((count + 1))
|
||
done
|
||
}
|
||
#======================================
|
||
# partedGetPartitionID
|
||
#--------------------------------------
|
||
function partedGetPartitionID {
|
||
# /.../
|
||
# prints the partition ID for the given device and number
|
||
# In case of a GPT map to the GUID code from the sgdisk
|
||
# utility. If sgdisk is not available map to the kiwi
|
||
# fdisk compatible hex id's which uses ee for any kind
|
||
# of unknown GPT partition entry
|
||
# ----
|
||
local IFS=$IFS_ORIG
|
||
local parted=$(parted -m -s $1 print | grep -v Warning:)
|
||
local diskhd=$(echo $parted | head -n 3 | tail -n 2 | head -n 1)
|
||
local plabel=$(echo $diskhd | cut -f6 -d:)
|
||
if [ -z "$plabel" ];then
|
||
# can't find a partition label for this disk
|
||
echo xx
|
||
return
|
||
fi
|
||
if [[ $plabel =~ gpt ]];then
|
||
plabel=gpt
|
||
fi
|
||
if [ ! $plabel = "gpt" ];then
|
||
parted -m -s $1 print | grep ^$2: | cut -f2 -d= |\
|
||
sed -e 's@[,; ]@@g' | tr -d 0
|
||
else
|
||
local name=$(parted -m -s $1 print | grep ^$2: | cut -f6 -d:)
|
||
if lookup sgdisk &>/dev/null;then
|
||
# map to short gdisk code
|
||
echo $(sgdisk -p $1 | grep -E "^ $2") | cut -f6 -d ' '
|
||
elif [ "$name" = "lxroot" ];then
|
||
# map lxroot to MBR type 83 (linux)
|
||
echo 83
|
||
elif [ "$name" = "lxswap" ];then
|
||
# map lxswap to MBR type 82 (linux swap)
|
||
echo 82
|
||
elif [ "$name" = "lxlvm" ];then
|
||
# map lxlvm to MBR type 8e (linux LVM)
|
||
echo 8e
|
||
elif [ "$name" = "UEFI" ];then
|
||
# map UEFI to MBR type 6 (fat 16)
|
||
echo 6
|
||
elif [ "$name" = "legacy" ];then
|
||
# map bios grub legacy partition to MBR type ef (EFI)
|
||
echo ef
|
||
else
|
||
# map anything else to ee (GPT)
|
||
echo ee
|
||
fi
|
||
fi
|
||
}
|
||
#======================================
|
||
# partitionID
|
||
#--------------------------------------
|
||
function partitionID {
|
||
local IFS=$IFS_ORIG
|
||
local diskDevice=$1
|
||
local diskNumber=$2
|
||
if [ $PARTITIONER = "fdasd" ];then
|
||
fdasdGetPartitionID $diskDevice $diskNumber
|
||
else
|
||
partedGetPartitionID $diskDevice $diskNumber
|
||
fi
|
||
}
|
||
#======================================
|
||
# partitionSize
|
||
#--------------------------------------
|
||
function partitionSize {
|
||
local IFS=$IFS_ORIG
|
||
local diskDevice=$1
|
||
local psizeBytes
|
||
local psizeKBytes
|
||
if [ -z "$diskDevice" ] || [ ! -e "$diskDevice" ];then
|
||
echo 0 ; return 1
|
||
fi
|
||
psizeBytes=$(blockdev --getsize64 $diskDevice)
|
||
psizeKBytes=$((psizeBytes / 1024))
|
||
echo $psizeKBytes
|
||
}
|
||
#======================================
|
||
# kernelList
|
||
#--------------------------------------
|
||
function kernelList {
|
||
# /.../
|
||
# check for all installed kernels whether there are valid
|
||
# links to the initrd and kernel files. The function will
|
||
# save the valid linknames in the variable KERNEL_LIST
|
||
# ----
|
||
local IFS=$IFS_ORIG
|
||
local prefix=$1
|
||
local kcount=1
|
||
local kname=""
|
||
local kernel=""
|
||
local initrd=""
|
||
local kpair=""
|
||
local krunning=`uname -r`
|
||
KERNEL_LIST=""
|
||
KERNEL_NAME=""
|
||
KERNEL_PAIR=""
|
||
#======================================
|
||
# search running kernel first
|
||
#--------------------------------------
|
||
if [ -d $prefix/lib/modules/$krunning ];then
|
||
for name in vmlinux vmlinuz image uImage;do
|
||
if [ -f $prefix/boot/$name-$krunning ];then
|
||
kernel=$name-$krunning
|
||
initrd=initrd-$krunning
|
||
break
|
||
fi
|
||
done
|
||
if [ ! -z "$kernel" ];then
|
||
KERNEL_PAIR=$kernel:$initrd
|
||
KERNEL_NAME[$kcount]=$krunning
|
||
KERNEL_LIST=$KERNEL_PAIR
|
||
kcount=$((kcount+1))
|
||
fi
|
||
fi
|
||
#======================================
|
||
# search for other kernels
|
||
#--------------------------------------
|
||
for i in $prefix/lib/modules/*;do
|
||
if [ ! -d $i ];then
|
||
continue
|
||
fi
|
||
unset kernel
|
||
unset initrd
|
||
kname=$(basename "$i")
|
||
if [ "$kname" = $krunning ];then
|
||
continue
|
||
fi
|
||
for name in vmlinux vmlinuz image uImage;do
|
||
for k in $prefix/boot/$name-${i##*/}; do
|
||
if [ -f $k ];then
|
||
kernel=${k##*/}
|
||
initrd=initrd-${i##*/}
|
||
break 2
|
||
fi
|
||
done
|
||
done
|
||
if [ ! -z "$kernel" ];then
|
||
kpair=$kernel:$initrd
|
||
KERNEL_NAME[$kcount]=$kname
|
||
KERNEL_LIST=$KERNEL_LIST,$kpair
|
||
kcount=$((kcount+1))
|
||
fi
|
||
done
|
||
#======================================
|
||
# what if no kernel was found...
|
||
#--------------------------------------
|
||
if [ -z "$KERNEL_LIST" ];then
|
||
# /.../
|
||
# the system image doesn't provide the kernel and initrd but
|
||
# if there is a downloaded kernel and initrd from the KIWI_INITRD
|
||
# setup. the kernelList function won't find initrds that gets
|
||
# downloaded over tftp so make sure the vmlinu[zx]/initrd combo
|
||
# gets added as well as the linux.vmx/initrd.vmx combo
|
||
# ----
|
||
if [ -e $prefix/boot/vmlinuz ];then
|
||
KERNEL_LIST="vmlinuz:initrd"
|
||
KERNEL_NAME[1]=vmlinuz
|
||
fi
|
||
if [ -e $prefix/boot/vmlinux ];then
|
||
KERNEL_LIST="vmlinux:initrd"
|
||
KERNEL_NAME[1]=vmlinux
|
||
fi
|
||
if [ -e $prefix/boot/linux.vmx ];then
|
||
KERNEL_LIST="vmlinux:initrd"
|
||
KERNEL_NAME[1]="vmlinux"
|
||
fi
|
||
fi
|
||
KERNEL_LIST=$(echo $KERNEL_LIST | sed -e s@^,@@)
|
||
export KERNEL_LIST
|
||
export KERNEL_NAME
|
||
export KERNEL_PAIR
|
||
}
|
||
#======================================
|
||
# validateSize
|
||
#--------------------------------------
|
||
function validateSize {
|
||
# /.../
|
||
# check if the image fits into the requested partition.
|
||
# An information about the sizes is printed out
|
||
# ----
|
||
local IFS=$IFS_ORIG
|
||
haveBytes=$(partitionSize $imageDevice)
|
||
haveBytes=$((haveBytes * 1024))
|
||
haveMByte=$((haveBytes / 1048576))
|
||
needBytes=$((blocks * blocksize))
|
||
needMByte=$((needBytes / 1048576))
|
||
Echo "Have size: $imageDevice -> $haveBytes Bytes [ $haveMByte MB ]"
|
||
Echo "Need size: $needBytes Bytes [ $needMByte MB ]"
|
||
if test $haveBytes -gt $needBytes;then
|
||
return 0
|
||
fi
|
||
return 1
|
||
}
|
||
#======================================
|
||
# validateBlockSize
|
||
#--------------------------------------
|
||
function validateBlockSize {
|
||
# /.../
|
||
# check the block size value. atftp limits to a maximum of
|
||
# 65535 blocks, so the block size must be checked according
|
||
# to the size of the image. The block size itself is also
|
||
# limited to 65464 bytes
|
||
# ----
|
||
local IFS=$IFS_ORIG
|
||
local blkTest
|
||
local nBlk
|
||
if [ -z "$zblocks" ] && [ -z "$blocks" ];then
|
||
# md5 file not yet read in... skip
|
||
return
|
||
fi
|
||
if [ ! -z "$zblocks" ];then
|
||
isize=$((zblocks * zblocksize))
|
||
else
|
||
isize=$((blocks * blocksize))
|
||
fi
|
||
local IFS=' '
|
||
testBlkSizes="32768 61440 65464"
|
||
if [ "$imageBlkSize" -gt 0 ]; then
|
||
testBlkSizes="$imageBlkSize $testBlkSizes"
|
||
fi
|
||
for blkTest in $testBlkSizes ; do
|
||
nBlk=$((isize / blkTest))
|
||
if [ $nBlk -lt 65535 ] ; then
|
||
imageBlkSize=$blkTest
|
||
return
|
||
fi
|
||
done
|
||
systemException \
|
||
"Maximum blocksize for atftp protocol exceeded" \
|
||
"reboot"
|
||
}
|
||
#======================================
|
||
# loadOK
|
||
#--------------------------------------
|
||
function loadOK {
|
||
# /.../
|
||
# check the output of the atftp command, unfortunately
|
||
# there is no useful return code to check so we have to
|
||
# check the output of the command
|
||
# ----
|
||
local IFS=$IFS_ORIG
|
||
for i in "File not found" "aborting" "no option named" "unknown host" ; do
|
||
if echo "$1" | grep -q "$i" ; then
|
||
return 1
|
||
fi
|
||
done
|
||
return 0
|
||
}
|
||
#======================================
|
||
# includeKernelParameters
|
||
#--------------------------------------
|
||
function includeKernelParameters {
|
||
# /.../
|
||
# include the parameters from /proc/cmdline into
|
||
# the current shell environment
|
||
# ----
|
||
local IFS=$IFS_ORIG
|
||
local file=$1
|
||
local translate=$2
|
||
if [ -z "$file" ];then
|
||
file=/proc/cmdline
|
||
fi
|
||
local cmdline=$(
|
||
awk -F\" '{OFS="\"";for(i=2;i<NF;i+=2)gsub(/ /,"\030",$i);print}' <$file
|
||
)
|
||
for i in $cmdline;do
|
||
if ! echo $i | grep -q "=";then
|
||
continue
|
||
fi
|
||
kernelKey=$(echo $i | cut -f1 -d=)
|
||
#======================================
|
||
# convert parameters to lowercase if required
|
||
#--------------------------------------
|
||
if [ "$translate" = "lowercase" ];then
|
||
kernelKey=`echo $kernelKey | tr [:upper:] [:lower:]`
|
||
fi
|
||
kernelVal=$(echo $i | cut -f2- -d=)
|
||
kernelVal=$(echo $kernelVal | sed -e 's/\o30/ /g')
|
||
eval export $kernelKey=$kernelVal
|
||
done
|
||
if [ ! -z "$kiwikernelmodule" ];then
|
||
kiwikernelmodule=`echo $kiwikernelmodule | tr , " "`
|
||
fi
|
||
if [ ! -z "$kiwibrokenmodule" ];then
|
||
kiwibrokenmodule=`echo $kiwibrokenmodule | tr , " "`
|
||
fi
|
||
if [ ! -z "$ramdisk_size" ];then
|
||
local modfile=/etc/modprobe.d/99-local.conf
|
||
if [ ! -f $modfile ];then
|
||
modfile=/etc/modprobe.conf.local
|
||
fi
|
||
if [ -f $modfile ];then
|
||
if grep -q rd_size $modfile;then
|
||
sed -i -e s"@rd_size=.*@rd_size=$ramdisk_size@" $modfile
|
||
else
|
||
echo "options brd rd_size=$ramdisk_size" >> $modfile
|
||
fi
|
||
fi
|
||
fi
|
||
if [ ! -z "$lang" ];then
|
||
# lang set on the commandline, e.g by the boot theme
|
||
export DIALOG_LANG=$lang
|
||
elif [ ! -z "$kiwi_language" ];then
|
||
# lang set from the XML data, first item is the primary language
|
||
export DIALOG_LANG=$(echo $kiwi_language | cut -f1 -d,)
|
||
fi
|
||
}
|
||
#======================================
|
||
# includeKernelParametersLowerCase
|
||
#--------------------------------------
|
||
function includeKernelParametersLowerCase {
|
||
includeKernelParameters "$1" "lowercase"
|
||
}
|
||
#======================================
|
||
# umountSystem
|
||
#--------------------------------------
|
||
function umountSystem {
|
||
local IFS=$IFS_ORIG
|
||
local retval=0
|
||
local mountList="/mnt /read-only /read-write"
|
||
#======================================
|
||
# umount boot device
|
||
#--------------------------------------
|
||
if [ ! -z "$imageBootDevice" ];then
|
||
umount $imageBootDevice 1>&2
|
||
fi
|
||
#======================================
|
||
# umount mounted mountList paths
|
||
#--------------------------------------
|
||
for mpath in $(cat /proc/mounts | cut -f2 -d " ");do
|
||
for umount in $mountList;do
|
||
if [ "$mpath" = "$umount" ];then
|
||
if ! umount $mpath >/dev/null;then
|
||
if ! umount -l $mpath >/dev/null;then
|
||
retval=1
|
||
fi
|
||
fi
|
||
fi
|
||
done
|
||
done
|
||
#======================================
|
||
# remove mount points
|
||
#--------------------------------------
|
||
for dir in "/read-only" "/read-write" "/xino";do
|
||
test -d $dir && rmdir $dir 1>&2
|
||
done
|
||
return $retval
|
||
}
|
||
#======================================
|
||
# kiwiMount
|
||
#--------------------------------------
|
||
function kiwiMount {
|
||
local IFS=$IFS_ORIG
|
||
local src=$1
|
||
local dst=$2
|
||
local opt=$3
|
||
local lop=$4
|
||
local fstype
|
||
#======================================
|
||
# load not autoloadable fs modules
|
||
#--------------------------------------
|
||
modprobe squashfs &>/dev/null
|
||
#======================================
|
||
# decide for a mount method
|
||
#--------------------------------------
|
||
if [ ! -z "$lop" ];then
|
||
src=$(loop_setup $lop)
|
||
if [ ! -e $src ]; then
|
||
return 1
|
||
fi
|
||
# /.../
|
||
# for iso images the root device name is set via
|
||
# config.isoclient. But in case of a filename the
|
||
# root device must be loop mounted and the loop
|
||
# setup creates the root device which is stored
|
||
# in imageDevice for the isoboot code
|
||
# ----
|
||
imageDevice=$src
|
||
fi
|
||
#======================================
|
||
# probe filesystem
|
||
#--------------------------------------
|
||
if [ ! -z "$NFSROOT" ];then
|
||
fstype=nfs
|
||
else
|
||
fstype=$(probeFileSystem $src)
|
||
fi
|
||
if [ "$fstyoe" = "unknown" ];then
|
||
fstype="auto"
|
||
fi
|
||
if ! mount -t $fstype $opt $src $dst >/dev/null;then
|
||
return 1
|
||
fi
|
||
return 0
|
||
}
|
||
#======================================
|
||
# setupReadWrite
|
||
#--------------------------------------
|
||
function setupReadWrite {
|
||
# /.../
|
||
# check/create read-write filesystem used for
|
||
# overlay data
|
||
# ----
|
||
local IFS=$IFS_ORIG
|
||
local rwDir=/read-write
|
||
local rwDevice=$(echo $UNIONFS_CONFIG | cut -d , -f 1)
|
||
local fstype=$(blkid $rwDevice -s TYPE -o value)
|
||
local hybrid_fs=$HYBRID_PERSISTENT_FS
|
||
local create_hybrid="no"
|
||
local fs_opts
|
||
mkdir -p $rwDir
|
||
if [ $hybrid_fs = "ext4" ];then
|
||
fs_opts="$HYBRID_EXT4_OPTS"
|
||
fi
|
||
if [ ! -z "$kiwi_hybridpersistent_filesystem" ];then
|
||
hybrid_fs=$kiwi_hybridpersistent_filesystem
|
||
fi
|
||
if [ $LOCAL_BOOT = "yes" ] || [ ! $systemIntegrity = "clean" ];then
|
||
# no further action on a standard boot/reboot or in unclean state
|
||
return 0
|
||
fi
|
||
if [ ! -z "$fstype" ];then
|
||
Echo "Checking filesystem for RW data on $rwDevice..."
|
||
checkFilesystem $rwDevice &>/dev/null
|
||
fi
|
||
if [ "$RELOAD_IMAGE" = "yes" ]; then
|
||
# create rw fs explicitly activated
|
||
create_hybrid="yes"
|
||
elif ! mount -o ro $rwDevice $rwDir &>/dev/null; then
|
||
# still failing after check, trigger creation of new rw fs
|
||
create_hybrid="yes"
|
||
fi
|
||
mountpoint -q $rwDir && umount $rwDevice
|
||
if [ "$create_hybrid" = "yes" ];then
|
||
Echo "Creating filesystem for RW data on $rwDevice..."
|
||
if ! createFilesystem \
|
||
"$rwDevice" "$hybrid_fs" "" "" "hybrid" "false" "$fs_opts"
|
||
then
|
||
Echo "Failed to create ${hybrid_fs} filesystem"
|
||
return 1
|
||
fi
|
||
fi
|
||
return 0
|
||
}
|
||
#======================================
|
||
# mountSystemSeedBtrFS
|
||
#--------------------------------------
|
||
function mountSystemSeedBtrFS {
|
||
local IFS=$IFS_ORIG
|
||
local loopf=$1
|
||
local rwDevice=`echo $UNIONFS_CONFIG | cut -d , -f 1`
|
||
local roDevice=`echo $UNIONFS_CONFIG | cut -d , -f 2`
|
||
local prefix=/mnt
|
||
#======================================
|
||
# check read/only device location
|
||
#--------------------------------------
|
||
if [ ! -z "$NFSROOT" ];then
|
||
roDevice="$imageRootDevice"
|
||
fi
|
||
#======================================
|
||
# check read/write device location
|
||
#--------------------------------------
|
||
if [ ! -e $rwDevice ];then
|
||
rwDevice=/dev/ram1
|
||
fi
|
||
#======================================
|
||
# mount/check btrfs file
|
||
#--------------------------------------
|
||
if [ ! -z "$NFSROOT" ];then
|
||
#======================================
|
||
# btrfs exported via NFS
|
||
#--------------------------------------
|
||
if ! kiwiMount "$roDevice" "$prefix" "" $loopf;then
|
||
Echo "Failed to mount NFS filesystem"
|
||
return 1
|
||
fi
|
||
else
|
||
#======================================
|
||
# mount btrfs container
|
||
#--------------------------------------
|
||
if [ -z "$loopf" ];then
|
||
loopf=$roDevice
|
||
fi
|
||
if ! mount -o loop,$kiwi_fsmountoptions $loopf $prefix; then
|
||
Echo "Failed to mount btrfs filesystem"
|
||
return 1
|
||
fi
|
||
fi
|
||
#======================================
|
||
# add seed device
|
||
#--------------------------------------
|
||
if ! btrfs device add $rwDevice $prefix; then
|
||
Echo "Failed to attach btrfs seed device"
|
||
return 1
|
||
fi
|
||
if ! mount -o remount,rw $prefix; then
|
||
Echo "Failed to remount read-write"
|
||
return 1
|
||
fi
|
||
return 0
|
||
}
|
||
#======================================
|
||
# mountSystemUnionFS
|
||
#--------------------------------------
|
||
function mountSystemUnionFS {
|
||
local IFS=$IFS_ORIG
|
||
local loopf=$1
|
||
local roDir=/read-only
|
||
local rwDir=/read-write
|
||
local rwDevice=`echo $UNIONFS_CONFIG | cut -d , -f 1`
|
||
local roDevice=`echo $UNIONFS_CONFIG | cut -d , -f 2`
|
||
local unionFST=`echo $UNIONFS_CONFIG | cut -d , -f 3`
|
||
local prefix=/mnt
|
||
local mount_options
|
||
#======================================
|
||
# load fuse module
|
||
#--------------------------------------
|
||
modprobe fuse &>/dev/null
|
||
#======================================
|
||
# create overlay mount points
|
||
#--------------------------------------
|
||
mkdir -p $roDir
|
||
mkdir -p $rwDir
|
||
#======================================
|
||
# check read/only device location
|
||
#--------------------------------------
|
||
if [ ! -z "$NFSROOT" ];then
|
||
roDevice="$imageRootDevice"
|
||
fi
|
||
#======================================
|
||
# mount read only device
|
||
#--------------------------------------
|
||
if ! kiwiMount "$roDevice" "$roDir" "" $loopf;then
|
||
Echo "Failed to mount read only filesystem"
|
||
return 1
|
||
fi
|
||
#======================================
|
||
# check read/write device location
|
||
#--------------------------------------
|
||
if [ ! -z "$kiwi_ramonly" ];then
|
||
rwDevice=tmpfs
|
||
fi
|
||
if [ "$rwDevice" = "tmpfs" ];then
|
||
#======================================
|
||
# write into tmpfs
|
||
#--------------------------------------
|
||
if ! mount -t tmpfs tmpfs $rwDir >/dev/null;then
|
||
Echo "Failed to mount tmpfs read/write filesystem"
|
||
return 1
|
||
fi
|
||
else
|
||
#======================================
|
||
# write to another device
|
||
#--------------------------------------
|
||
if [ "$roDevice" = "nfs" ];then
|
||
rwDevice="-o nolock,rw $nfsRootServer:$rwDevice"
|
||
fi
|
||
if [ ! "$roDevice" = "nfs" ] && ! setupReadWrite; then
|
||
return 1
|
||
fi
|
||
if [ "$kiwi_hybridpersistent" = "true" ];then
|
||
# When using an overlay writing to a block device safety has
|
||
# less priority over speed. If this does not match your use
|
||
# case please report an issue on the kiwi github
|
||
mount_options="-o defaults,async,relatime,nodiratime"
|
||
fi
|
||
if ! kiwiMount "$rwDevice" "$rwDir" "$mount_options";then
|
||
Echo "Failed to mount read/write filesystem"
|
||
return 1
|
||
fi
|
||
fi
|
||
#======================================
|
||
# overlay mount the locations
|
||
#--------------------------------------
|
||
if [ "$unionFST" = "overlay" ];then
|
||
#======================================
|
||
# setup overlayfs mount
|
||
#--------------------------------------
|
||
# overlayfs in version >= v22 behaves differently
|
||
# + renamed from overlayfs to overlay
|
||
# + requires a workdir to become mounted
|
||
# + requires workdir and upperdir to reside under the same mount
|
||
# + requires workdir and upperdir to be in separate subdirs
|
||
# try new mode first, if that fails then fallback to old style
|
||
mkdir -p $rwDir/work
|
||
mkdir -p $rwDir/rw
|
||
local opts="rw,lowerdir=$roDir,upperdir=$rwDir/rw,workdir=$rwDir/work"
|
||
if ! mount -t overlay -o $opts overlay $prefix;then
|
||
# overlayfs in version < v22 fallback/compat mode
|
||
# + does not require a workdir
|
||
rm -rf $rwDir/work
|
||
rm -rf $rwDir/rw
|
||
opts="rw,lowerdir=$roDir,upperdir=$rwDir"
|
||
if ! mount -t overlayfs -o $opts overlayfs $prefix;then
|
||
Echo "Failed to mount root via overlayfs"
|
||
return 1
|
||
fi
|
||
fi
|
||
elif [ "$unionFST" = "unionfs" ];then
|
||
#======================================
|
||
# setup fuse union mount
|
||
#--------------------------------------
|
||
local opts="cow,max_files=65000,allow_other,use_ino,suid,dev,nonempty"
|
||
if ! unionfs -o $opts $rwDir=RW:$roDir=RO $prefix;then
|
||
Echo "Failed to mount root via unionfs"
|
||
return 1
|
||
fi
|
||
fi
|
||
export haveUnionFS=yes
|
||
return 0
|
||
}
|
||
#======================================
|
||
# mountSystemClicFS
|
||
#--------------------------------------
|
||
function mountSystemClicFS {
|
||
local IFS=$IFS_ORIG
|
||
local loopf=$1
|
||
local roDir=/read-only
|
||
local rwDevice=`echo $UNIONFS_CONFIG | cut -d , -f 1`
|
||
local roDevice=`echo $UNIONFS_CONFIG | cut -d , -f 2`
|
||
local clic_cmd=clicfs
|
||
local resetReadWrite=0
|
||
local ramOnly=0
|
||
local haveBytes
|
||
local haveKByte
|
||
local haveMByte
|
||
local wantCowFS
|
||
local size
|
||
local prefix=/mnt
|
||
#======================================
|
||
# load fuse module
|
||
#--------------------------------------
|
||
modprobe fuse &>/dev/null
|
||
#======================================
|
||
# create read only mount point
|
||
#--------------------------------------
|
||
mkdir -p $roDir
|
||
#======================================
|
||
# check read/only device location
|
||
#--------------------------------------
|
||
if [ ! -z "$NFSROOT" ];then
|
||
roDevice="$imageRootDevice"
|
||
fi
|
||
#======================================
|
||
# check kernel command line for log file
|
||
#--------------------------------------
|
||
if [ -n "$cliclog" ]; then
|
||
clic_cmd="$clic_cmd -l $cliclog"
|
||
fi
|
||
#======================================
|
||
# check read/write device location
|
||
#--------------------------------------
|
||
if [ ! -z "$kiwi_ramonly" ];then
|
||
ramOnly=1
|
||
elif [ ! -e $rwDevice ];then
|
||
ramOnly=1
|
||
elif getDiskDevice $rwDevice | grep -q ram;then
|
||
ramOnly=1
|
||
fi
|
||
if [ $ramOnly = 1 ];then
|
||
haveKByte=`cat /proc/meminfo | grep MemFree | cut -f2 -d:| cut -f1 -dk`
|
||
haveMByte=$((haveKByte / 1024))
|
||
haveMByte=$((haveMByte * 7 / 10))
|
||
clic_cmd="$clic_cmd -m $haveMByte"
|
||
else
|
||
haveBytes=$(blockdev --getsize64 $rwDevice)
|
||
haveMByte=$((haveBytes / 1024 / 1024))
|
||
wantCowFS=0
|
||
if \
|
||
[ "$kiwi_hybrid" = "true" ] && \
|
||
[ "$kiwi_hybridpersistent" = "true" ]
|
||
then
|
||
# write into a cow file on a filesystem, for hybrid iso's
|
||
wantCowFS=1
|
||
fi
|
||
if [ $wantCowFS = 1 ];then
|
||
# write into a cow file on a filesystem
|
||
mkdir -p $HYBRID_PERSISTENT_DIR
|
||
if [ $LOCAL_BOOT = "no" ] && [ $systemIntegrity = "clean" ];then
|
||
resetReadWrite=1
|
||
elif ! mount $rwDevice $HYBRID_PERSISTENT_DIR;then
|
||
resetReadWrite=1
|
||
elif [ ! -z "$wipecow" ];then
|
||
resetReadWrite=1
|
||
fi
|
||
if [ $resetReadWrite = 1 ];then
|
||
if ! setupReadWrite; then
|
||
Echo "Failed to setup read-write filesystem"
|
||
return 1
|
||
fi
|
||
if ! mount $rwDevice $HYBRID_PERSISTENT_DIR;then
|
||
Echo "Failed to mount read/write filesystem"
|
||
return 1
|
||
fi
|
||
fi
|
||
clic_cmd="$clic_cmd -m $haveMByte"
|
||
clic_cmd="$clic_cmd -c $HYBRID_PERSISTENT_DIR/.clicfs_COW"
|
||
else
|
||
# write into a device directly
|
||
clic_cmd="$clic_cmd -m $haveMByte -c $rwDevice --ignore-cow-errors"
|
||
fi
|
||
fi
|
||
#======================================
|
||
# mount/check clic file
|
||
#--------------------------------------
|
||
if [ ! -z "$NFSROOT" ];then
|
||
#======================================
|
||
# clic exported via NFS
|
||
#--------------------------------------
|
||
if ! kiwiMount "$roDevice" "$roDir" "" $loopf;then
|
||
Echo "Failed to mount NFS filesystem"
|
||
return 1
|
||
fi
|
||
if [ ! -e "$roDir/fsdata.ext4" ];then
|
||
Echo "Can't find clic fsdata.ext4 in NFS export"
|
||
return 1
|
||
fi
|
||
else
|
||
#======================================
|
||
# mount clic container
|
||
#--------------------------------------
|
||
if [ -z "$loopf" ];then
|
||
loopf=$roDevice
|
||
fi
|
||
if ! $clic_cmd $loopf $roDir; then
|
||
Echo "Failed to mount clic filesystem"
|
||
return 1
|
||
fi
|
||
fi
|
||
#======================================
|
||
# mount root over clic
|
||
#--------------------------------------
|
||
size=$(stat -c %s $roDir/fsdata.ext4)
|
||
size=$((size/512))
|
||
# we don't want reserved blocks...
|
||
tune2fs -m 0 $roDir/fsdata.ext4 >/dev/null
|
||
# we don't want automatic filesystem check...
|
||
tune2fs -i 0 $roDir/fsdata.ext4 >/dev/null
|
||
if [ ! $LOCAL_BOOT = "no" ];then
|
||
e2fsck -p $roDir/fsdata.ext4
|
||
fi
|
||
if [ $LOCAL_BOOT = "no" ] || [ $ramOnly = 1 ];then
|
||
resize2fs $roDir/fsdata.ext4 $size"s"
|
||
fi
|
||
mount -o loop,noatime,nodiratime,errors=remount-ro,barrier=0 \
|
||
$roDir/fsdata.ext4 $prefix
|
||
if [ ! $? = 0 ];then
|
||
Echo "Failed to mount ext4 clic container"
|
||
return 1
|
||
fi
|
||
# Give fuse enough time to settle for I/O in the ext4 container
|
||
# Unconditional waiting is never a good idea however I couldn't
|
||
# find a good solution to this problem because a lookup on read
|
||
# or write could cause an ro remount of the ext4 container
|
||
# Thus we just sleep a while before proceeding
|
||
sleep 5
|
||
export haveClicFS=yes
|
||
return 0
|
||
}
|
||
#======================================
|
||
# mountSystemStandard
|
||
#--------------------------------------
|
||
function mountSystemStandard {
|
||
local IFS=$IFS_ORIG
|
||
local mountDevice=$1
|
||
local variable
|
||
local volume
|
||
local content
|
||
local volpath
|
||
local mpoint
|
||
local mppath
|
||
local prefix=/mnt
|
||
local fstype=$(probeFileSystem $mountDevice)
|
||
if [ ! $fstype = "unknown" ]; then
|
||
kiwiMount "$mountDevice" "$prefix"
|
||
else
|
||
mount $mountDevice $prefix >/dev/null
|
||
fi
|
||
if [ "$haveLVM" = "yes" ];then
|
||
local volume_name
|
||
local mount_device
|
||
local mount_point
|
||
for i in $(readVolumeSetup "/.profile");do
|
||
volume_name=$(getVolumeName $i)
|
||
if [ $volume_name = "LVRoot" ]; then
|
||
continue
|
||
fi
|
||
mount_point=$(getVolumeMountPoint $i)
|
||
mount_device="/dev/$kiwi_lvmgroup/$volume_name"
|
||
mkdir -p $prefix/$mount_point
|
||
kiwiMount "$mount_device" "$prefix/$mount_point"
|
||
done
|
||
elif [ "$fstype" = "btrfs" ];then
|
||
if [ "$kiwi_btrfs_root_is_snapshot" = "true" ];then
|
||
mountBtrfsSubVolumes $mountDevice $prefix
|
||
fi
|
||
fi
|
||
return $?
|
||
}
|
||
#======================================
|
||
# mountSystem
|
||
#--------------------------------------
|
||
function mountSystem {
|
||
local IFS=$IFS_ORIG
|
||
local retval=0
|
||
#======================================
|
||
# set primary mount device
|
||
#--------------------------------------
|
||
local mountDevice="$imageRootDevice"
|
||
if [ ! -z "$1" ];then
|
||
mountDevice="$1"
|
||
fi
|
||
#======================================
|
||
# wait for storage device to appear
|
||
#--------------------------------------
|
||
if ! echo $mountDevice | grep -qE "loop|vers=";then
|
||
waitForStorageDevice $mountDevice
|
||
fi
|
||
#======================================
|
||
# check root tree type
|
||
#--------------------------------------
|
||
if [ ! -z "$UNIONFS_CONFIG" ];then
|
||
local unionFST=`echo $UNIONFS_CONFIG | cut -d , -f 3`
|
||
if [ "$unionFST" = "clicfs" ];then
|
||
mountSystemClicFS $2
|
||
elif [ "$unionFST" = "seed" ];then
|
||
mountSystemSeedBtrFS $2
|
||
elif [ "$unionFST" = "overlay" ];then
|
||
mountSystemUnionFS $2
|
||
elif [ "$unionFST" = "unionfs" ];then
|
||
mountSystemUnionFS $2
|
||
else
|
||
systemException \
|
||
"Unknown overlay mount method: $unionFST" \
|
||
"reboot"
|
||
fi
|
||
retval=$?
|
||
else
|
||
mountSystemStandard "$mountDevice"
|
||
retval=$?
|
||
fi
|
||
#======================================
|
||
# setup boot partition
|
||
#--------------------------------------
|
||
if \
|
||
[ -z "$skipSetupBootPartition" ] && \
|
||
[ "$LOCAL_BOOT" = "no" ] && \
|
||
[ ! "$systemIntegrity" = "fine" ] && \
|
||
[ $retval = 0 ] && \
|
||
[ -z "$RESTORE" ]
|
||
then
|
||
if [[ $kiwi_initrdname =~ netboot ]];then
|
||
setupBootPartitionPXE
|
||
else
|
||
setupBootPartition
|
||
fi
|
||
fi
|
||
#======================================
|
||
# reset mount counter
|
||
#--------------------------------------
|
||
resetMountCounter
|
||
return $retval
|
||
}
|
||
#======================================
|
||
# mountOrCopyLiveCD
|
||
#--------------------------------------
|
||
function mountOrCopyLiveCD {
|
||
local SIZE
|
||
if [ ! -z "$TORAM" ]; then
|
||
Echo "Copying CD system into tmpfs"
|
||
mkdir -p ${LIVECD}R $LIVECD && \
|
||
eval mount $cdopt $biosBootDevice ${LIVECD}R
|
||
SIZE="$(du -s /${LIVECD}R | gawk '{print int($1*1.1)}')"
|
||
mount -t tmpfs -o size=${SIZE}k tmpfs $LIVECD
|
||
if ! cp -ar ${LIVECD}R/* $LIVECD; then
|
||
systemException \
|
||
"Copying CD contents to tmpfs failed" \
|
||
"reboot"
|
||
fi
|
||
umount ${LIVECD}R
|
||
rmdir ${LIVECD}R
|
||
else
|
||
mkdir -p $LIVECD && eval mount $cdopt $biosBootDevice $LIVECD
|
||
fi
|
||
}
|
||
#======================================
|
||
# cleanDirectory
|
||
#--------------------------------------
|
||
function cleanDirectory {
|
||
local IFS=$IFS_ORIG
|
||
local directory=$1
|
||
shift 1
|
||
local save=$@
|
||
local tmpdir=`mktemp -d`
|
||
for saveItem in $save;do
|
||
mv $directory/$saveItem $tmpdir >/dev/null
|
||
done
|
||
rm -rf $directory/*
|
||
mv $tmpdir/* $directory
|
||
rm -rf $tmpdir
|
||
}
|
||
#======================================
|
||
# searchGroupConfig
|
||
#--------------------------------------
|
||
function searchGroupConfig {
|
||
local IFS=$IFS_ORIG
|
||
local localhwaddr=$DHCPCHADDR
|
||
local GROUPCONFIG=/etc/config.group
|
||
local list_var
|
||
local mac_list
|
||
#======================================
|
||
# Load group file if it exists
|
||
#--------------------------------------
|
||
Echo "Checking for config file: config.group";
|
||
fetchFile KIWI/config.group $GROUPCONFIG
|
||
if [ ! -s $GROUPCONFIG ]; then
|
||
return
|
||
fi
|
||
Echo "Found config.group, determining available groups";
|
||
importFile < $GROUPCONFIG
|
||
Debug "KIWI_GROUP = '$KIWI_GROUP'"
|
||
#======================================
|
||
# Parse group file
|
||
#--------------------------------------
|
||
if [ -z "$KIWI_GROUP" ] ; then
|
||
systemException \
|
||
"No groups defined in $GROUPCONFIG" \
|
||
"reboot"
|
||
fi
|
||
for i in `echo "$KIWI_GROUP" | sed 's/,/ /g' | sed 's/[ \t]+/ /g'`; do
|
||
Echo "Lookup MAC address: $localhwaddr in ${i}_KIWI_MAC_LIST"
|
||
eval list_var="${i}_KIWI_MAC_LIST"
|
||
eval mac_list=\$$list_var
|
||
searchGroupHardwareAddress $i "$mac_list"
|
||
if [ -s $CONFIG ]; then
|
||
break
|
||
fi
|
||
unset list_var
|
||
unset mac_list
|
||
done
|
||
}
|
||
#======================================
|
||
# searchGroupHardwareAddress
|
||
#--------------------------------------
|
||
function searchGroupHardwareAddress {
|
||
# /.../
|
||
# function to check the existance of the hosts
|
||
# hardware address within the defined "mac_list".
|
||
# If the hardware address is found, load the config file.
|
||
# ----
|
||
local IFS=$IFS_ORIG
|
||
local localhwaddr=$DHCPCHADDR
|
||
local local_group=$1
|
||
local mac_list=$2
|
||
for j in `echo "$mac_list" | sed 's/,/ /g' | sed 's/[ \t]+/ /g'`; do
|
||
if [ "$localhwaddr" = "$j" ] ; then
|
||
Echo "MAC address $localhwaddr found in group $local_group"
|
||
Echo "Checking for config file: config.$local_group"
|
||
fetchFile KIWI/config.$local_group $CONFIG
|
||
if [ ! -s $CONFIG ]; then
|
||
systemException \
|
||
"No configuration found for $j" \
|
||
"reboot"
|
||
fi
|
||
break
|
||
fi
|
||
done
|
||
}
|
||
#======================================
|
||
# searchAlternativeConfig
|
||
#--------------------------------------
|
||
function searchAlternativeConfig {
|
||
local IFS=$IFS_ORIG
|
||
# Check config.IP in Hex (pxelinux style)
|
||
localip=$IPADDR
|
||
hexip1=`echo $localip | cut -f1 -d'.'`
|
||
hexip2=`echo $localip | cut -f2 -d'.'`
|
||
hexip3=`echo $localip | cut -f3 -d'.'`
|
||
hexip4=`echo $localip | cut -f4 -d'.'`
|
||
hexip=`printf "%02X" $hexip1 $hexip2 $hexip3 $hexip4`
|
||
STEP=8
|
||
while [ $STEP -gt 0 ]; do
|
||
hexippart=`echo $hexip | cut -b -$STEP`
|
||
Echo "Checking for config file: config.$hexippart"
|
||
fetchFile KIWI/config.$hexippart $CONFIG
|
||
if test -s $CONFIG;then
|
||
break
|
||
fi
|
||
let STEP=STEP-1
|
||
done
|
||
# Check config.default if no hex config was found
|
||
if test ! -s $CONFIG;then
|
||
Echo "Checking for config file: config.default"
|
||
fetchFile KIWI/config.default $CONFIG
|
||
fi
|
||
}
|
||
#======================================
|
||
# searchHardwareMapConfig
|
||
#--------------------------------------
|
||
function searchHardwareMapConfig {
|
||
local IFS=$IFS_ORIG
|
||
local list_var
|
||
local mac_list
|
||
#======================================
|
||
# return if no map was specified
|
||
#--------------------------------------
|
||
if [ -z "$HARDWARE_MAP" ];then
|
||
return
|
||
fi
|
||
Echo "Found hardware/vendor map configuration variable"
|
||
#===========================================
|
||
# Evaluate the MAP list, and test for hwaddr
|
||
#-------------------------------------------
|
||
for i in `echo "$HARDWARE_MAP" | sed 's/,/ /g' | sed 's/[ \t]+/ /g'`; do
|
||
Echo "Lookup MAC address: $localhwaddr in ${i}_HARDWARE_MAP"
|
||
eval list_var="${i}_HARDWARE_MAP"
|
||
eval mac_list=\$$list_var
|
||
Debug "${i}_HARDWARE_MAP = '$mac_list'"
|
||
searchHardwareMapHardwareAddress $i "$mac_list"
|
||
if [ -s $CONFIG ]; then
|
||
break
|
||
fi
|
||
unset list_var
|
||
unset mac_list
|
||
done
|
||
}
|
||
#======================================
|
||
# searchHardwareMapHardwareAddress
|
||
#--------------------------------------
|
||
function searchHardwareMapHardwareAddress {
|
||
local IFS=$IFS_ORIG
|
||
local HARDWARE_CONFIG=/etc/config.hardware
|
||
local localhwaddr=$DHCPCHADDR
|
||
local hardware_group=$1
|
||
local mac_list=$2
|
||
Debug "hardware_group = '$hardware_group'"
|
||
Debug "mac_list = '$mac_list'"
|
||
for j in `echo "$mac_list" | sed 's/,/ /g' | sed 's/[ \t]+/ /g'`; do
|
||
if [ "$localhwaddr" = "$j" ] ; then
|
||
Echo "MAC address $localhwaddr found in group $hardware_group"
|
||
Echo "Checking for config file: hardware_config.$hardware_group"
|
||
fetchFile KIWI/hardware_config.$hardware_group $HARDWARE_CONFIG
|
||
if [ ! -s $HARDWARE_CONFIG ]; then
|
||
systemException \
|
||
"No configuration found for $j" \
|
||
"reboot"
|
||
fi
|
||
importFile < $HARDWARE_CONFIG
|
||
break
|
||
fi
|
||
done
|
||
}
|
||
#======================================
|
||
# runHook
|
||
#--------------------------------------
|
||
function runHook {
|
||
local IFS=$IFS_ORIG
|
||
#======================================
|
||
# Check for execution permission
|
||
#--------------------------------------
|
||
if [ ! -z "$KIWI_FORBID_HOOKS" ];then
|
||
Echo "Hook script execution is forbidden by KIWI_FORBID_HOOKS"
|
||
return
|
||
fi
|
||
#======================================
|
||
# Init custom post hook commands
|
||
#--------------------------------------
|
||
# a) switch post command execution off, can be activated by hook script
|
||
export eval KIWI_ALLOW_HOOK_CMD_$1=0
|
||
#======================================
|
||
# Search and execute hook script
|
||
#--------------------------------------
|
||
HOOK="/kiwi-hooks/$1.sh"
|
||
if [ ! -e $HOOK ];then
|
||
HOOK="/lib/kiwi/hooks/$1.sh"
|
||
fi
|
||
if [ -e $HOOK ]; then
|
||
. $HOOK "$@"
|
||
fi
|
||
#======================================
|
||
# Run custom post hook commands
|
||
#--------------------------------------
|
||
# b) check permisson and state of command list
|
||
if [ ! -z "$KIWI_FORBID_HOOK_CMDS" ];then
|
||
Echo "Post-Hook command execution is forbidden by KIWI_FORBID_HOOK_CMDS"
|
||
return
|
||
fi
|
||
eval local call_cmd=\$KIWI_ALLOW_HOOK_CMD_$1
|
||
if [ "$call_cmd" -eq 1 ]; then
|
||
eval local call=\$KIWI_HOOK_CMD_$1
|
||
eval $call
|
||
fi
|
||
}
|
||
#======================================
|
||
# getNextPartition
|
||
#--------------------------------------
|
||
function getNextPartition {
|
||
local IFS=$IFS_ORIG
|
||
part=$1
|
||
nextPart=`echo $part | sed -e "s/\(.*\)[0-9]/\1/"`
|
||
nextPartNum=`echo $part | sed -e "s/.*\([0-9]\)/\1/"`
|
||
nextPartNum=$((nextPartNum + 1))
|
||
nextPart="${nextPart}${nextPartNum}"
|
||
echo $nextPart
|
||
}
|
||
#======================================
|
||
# startShell
|
||
#--------------------------------------
|
||
function startShell {
|
||
# /.../
|
||
# start a debugging shell on ELOG_BOOTSHELL
|
||
# ----
|
||
local IFS=$IFS_ORIG
|
||
if [ ! -z $kiwidebug ];then
|
||
if [ ! -e $ELOG_BOOTSHELL ];then
|
||
Echo "No terminal $ELOG_BOOTSHELL available for debug shell"
|
||
return
|
||
fi
|
||
Echo "Starting boot shell on $ELOG_BOOTSHELL"
|
||
sulogin -e -p $ELOG_BOOTSHELL &
|
||
sleep 2
|
||
ELOGSHELL_PID=$(fuser $ELOG_BOOTSHELL | tr -d " ")
|
||
echo ELOGSHELL_PID=$ELOGSHELL_PID >> /iprocs
|
||
fi
|
||
}
|
||
#======================================
|
||
# killShell
|
||
#--------------------------------------
|
||
function killShell {
|
||
# /.../
|
||
# kill debugging shell on ELOG_BOOTSHELL
|
||
# ----
|
||
local IFS=$IFS_ORIG
|
||
local umountProc=0
|
||
if [ ! -e /proc/mounts ];then
|
||
mount -t proc proc /proc
|
||
umountProc=1
|
||
fi
|
||
if [ ! -z "$ELOGSHELL_PID" ];then
|
||
Echo "Stopping boot shell"
|
||
kill $ELOGSHELL_PID &>/dev/null
|
||
fi
|
||
if [ $umountProc -eq 1 ];then
|
||
umount /proc
|
||
fi
|
||
}
|
||
#======================================
|
||
# waitForStorageDevice
|
||
#--------------------------------------
|
||
function waitForStorageDevice {
|
||
# /.../
|
||
# function to check access on a storage device which could be
|
||
# a whole disk or a partition. The function will wait until
|
||
# the size of the storage device could be obtained and is
|
||
# greater than zero or the timeout is reached. Default timeout
|
||
# is set to 60 seconds, however it can be set to different
|
||
# value by setting the DEVICE_TIMEOUT variable on the kernel
|
||
# command line.
|
||
# ----
|
||
local IFS=$IFS_ORIG
|
||
local device=$1
|
||
local check=0
|
||
local limit=30
|
||
local storage_size=0
|
||
if [[ $DEVICE_TIMEOUT =~ ^[0-9]+$ ]]; then
|
||
limit=$(((DEVICE_TIMEOUT + 1)/ 2))
|
||
fi
|
||
udevPending
|
||
while true;do
|
||
storage_size=$(partitionSize $device)
|
||
if [ $storage_size -gt 0 ]; then
|
||
sleep 1; return 0
|
||
fi
|
||
if [ $check -eq $limit ]; then
|
||
return 1
|
||
fi
|
||
Echo "Waiting for storage device $device to settle..."
|
||
check=$((check + 1))
|
||
sleep 2
|
||
done
|
||
}
|
||
#======================================
|
||
# waitForLinkUp
|
||
#--------------------------------------
|
||
function waitForLinkUp {
|
||
# /.../
|
||
# wait for the network link to enter UP state
|
||
# ----
|
||
local IFS=$IFS_ORIG
|
||
local dev=$1
|
||
local check=0
|
||
local linkstatus
|
||
local linkgrep
|
||
while true;do
|
||
if lookup ifplugstatus &>/dev/null;then
|
||
linkstatus=ifplugstatus
|
||
 linkgrep="link beat detected"
|
||
else
|
||
linkstatus="ip link ls"
|
||
linkgrep="state UP"
|
||
fi
|
||
$linkstatus $dev | grep -qi "$linkgrep"
|
||
if [ $? = 0 ];then
|
||
sleep 1; return 0
|
||
fi
|
||
if [ $check -eq 30 ];then
|
||
return 1
|
||
fi
|
||
Echo "Waiting for link up on ${dev}..."
|
||
check=$((check + 1))
|
||
sleep 2
|
||
done
|
||
}
|
||
#======================================
|
||
# setIPLinkUp
|
||
#--------------------------------------
|
||
function setIPLinkUp {
|
||
local IFS=$IFS_ORIG
|
||
local try_iface=$1
|
||
if ip link set dev $try_iface up;then
|
||
if [ ! $try_iface = "lo" ];then
|
||
waitForLinkUp $try_iface
|
||
fi
|
||
# success
|
||
return 0
|
||
fi
|
||
# error on ip call, failed state
|
||
return 1
|
||
}
|
||
#======================================
|
||
# waitForDHCPInterfaceNegotiation
|
||
#--------------------------------------
|
||
function waitForDHCPInterfaceNegotiation {
|
||
local IFS=$IFS_ORIG
|
||
local dhcp_info=$1
|
||
for i in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20;do
|
||
if [ -s $dhcp_info ] &&
|
||
grep -q "^IPADDR=" $dhcp_info
|
||
then
|
||
# success
|
||
return 0
|
||
fi
|
||
sleep 2
|
||
done
|
||
# timeout reached, failed state
|
||
return 1
|
||
}
|
||
#======================================
|
||
# waitForBlockDevice
|
||
#--------------------------------------
|
||
function waitForBlockDevice {
|
||
# /.../
|
||
# function to check if the given block device
|
||
# exists. If not the function will wait until the
|
||
# device appears or the check counter equals 4
|
||
# ----
|
||
local IFS=$IFS_ORIG
|
||
local device=$1
|
||
local check=0
|
||
udevPending
|
||
while true;do
|
||
if [ -b $device ] || [ $check -eq 4 ];then
|
||
break
|
||
fi
|
||
Echo "Waiting for block device $device to settle..."
|
||
check=$((check + 1))
|
||
sleep 2
|
||
done
|
||
}
|
||
|
||
#======================================
|
||
# atftpProgress
|
||
#--------------------------------------
|
||
function atftpProgress {
|
||
# /.../
|
||
# atftp doesn't use a stream based download and sometimes
|
||
# seek back and forth which makes it hard to use pipes for
|
||
# progress indication. Therefore we watch the trace output
|
||
# ----
|
||
local IFS=$IFS_ORIG
|
||
local imgsize=$1 # image size in MB
|
||
local prefix=$2 # line prefix text
|
||
local file=$3 # file with progress data
|
||
local blocksize=$4 # blocksize use for download
|
||
local bytes=0 # log lines multiplied by blocksize
|
||
local lines=0 # log lines
|
||
local percent=0 # in percent of all
|
||
local all=$((imgsize * 1024 * 1024))
|
||
local line
|
||
local step=0
|
||
# number of cycles for approx. 2% steps
|
||
local max_step=$(($all / $blocksize / 25))
|
||
cat < dev/null > $file.tmp
|
||
#======================================
|
||
# print progress information
|
||
#--------------------------------------
|
||
while read line ;do
|
||
echo "$line" >> $file.tmp
|
||
let step=step+1
|
||
if [ $step -lt $max_step ]; then
|
||
continue
|
||
fi
|
||
step=0
|
||
# /.../
|
||
# the trace logs two lines indicating one download block of
|
||
# blocksize bytes. We assume only full blocks. At the end
|
||
# it might happen that only a part of blocksize bytes is
|
||
# required. The function does not precisely calculate them
|
||
# and assumes blocksize bytes. imho that's ok for the progress
|
||
# bar. In order to be exact the function would have to sum
|
||
# up all bytes from the trace log for each iteration which
|
||
# would cause the download to pause because it has to wait
|
||
# for the progress bar to get ready
|
||
# ----
|
||
# the same block can be transferred multiple times
|
||
lines=$(grep "^sent ACK" $file.tmp | sort -u | wc -l)
|
||
bytes=$((lines * $blocksize))
|
||
percent=$(echo "scale=2; $bytes * 100" | bc)
|
||
percent=$(echo "scale=0; $percent / $all" | bc)
|
||
echo -en "$prefix ( $percent%)\r"
|
||
done
|
||
grep -v "^\(received \)\|\(sent \)" $file.tmp > $file
|
||
rm $file.tmp
|
||
echo
|
||
}
|
||
|
||
#======================================
|
||
# encodeURL
|
||
#--------------------------------------
|
||
function encodeURL {
|
||
# /.../
|
||
# encode special characters in URL's to correctly
|
||
# serve as input for fetchFile and putFile
|
||
# ----
|
||
local IFS=$IFS_ORIG
|
||
local STR
|
||
local CH
|
||
STR="$@"
|
||
echo -n "$STR" | while read -n1 CH; do
|
||
[[ $CH =~ [-_A-Za-z0-9./] ]] && printf "$CH" || printf "%%%x" \'"$CH"
|
||
done
|
||
}
|
||
|
||
#======================================
|
||
# fetchFile
|
||
#--------------------------------------
|
||
function fetchFile {
|
||
# /.../
|
||
# the generic fetcher which is able to use different protocols
|
||
# tftp,ftp, http, https. fetchFile is used in the netboot linuxrc
|
||
# and uses curl and atftp to download files from the network
|
||
# ----
|
||
local IFS=$IFS_ORIG
|
||
local path=$1
|
||
local dest=$2
|
||
local izip=$3
|
||
local host=$4
|
||
local type=$5
|
||
local chunk=$6
|
||
local encoded_path
|
||
local dump
|
||
local call
|
||
local call_pid
|
||
local unzip
|
||
#======================================
|
||
# source path is required
|
||
#--------------------------------------
|
||
if [ -z "$path" ]; then
|
||
systemException "No source path specified" "reboot"
|
||
fi
|
||
#======================================
|
||
# destination path is required
|
||
#--------------------------------------
|
||
if [ -z "$dest" ];then
|
||
systemException "No destination path specified" "reboot"
|
||
fi
|
||
#======================================
|
||
# source host is required
|
||
#--------------------------------------
|
||
if [ ! -z $kiwiserver ];then
|
||
host=$kiwiserver
|
||
fi
|
||
if [ -z "$host" ]; then
|
||
systemException "No source server specified" "reboot"
|
||
fi
|
||
#======================================
|
||
# set default chunk size
|
||
#--------------------------------------
|
||
if [ -z "$chunk" ];then
|
||
chunk=4k
|
||
fi
|
||
#======================================
|
||
# set default service type
|
||
#--------------------------------------
|
||
if [ ! -z $kiwiservertype ]; then
|
||
type=$kiwiservertype
|
||
fi
|
||
if [ -z "$type" ]; then
|
||
type="tftp"
|
||
fi
|
||
#======================================
|
||
# set source path + tool if compressed
|
||
#--------------------------------------
|
||
if [ ! -z "$izip" ] && [[ ! "$izip" =~ ^uncomp ]];then
|
||
if [ $izip = "compressed" ] || [ "$izip" = "compressed-gzip" ]; then
|
||
unzip="gzip -d"
|
||
path=$(echo "$path" | sed -e s@\\.gz@@)
|
||
path="$path.gz"
|
||
elif [ $izip = "compressed-xz" ];then
|
||
unzip="xz -d"
|
||
path=$(echo "$path" | sed -e s@\\.xz@@)
|
||
path="$path.xz"
|
||
else
|
||
systemException "Unknown compression mode: $izip" "reboot"
|
||
fi
|
||
else
|
||
unset izip
|
||
fi
|
||
#======================================
|
||
# encode special URL characters
|
||
#--------------------------------------
|
||
encoded_path=$(encodeURL "$path")
|
||
#======================================
|
||
# setup progress meta information
|
||
#--------------------------------------
|
||
dump="dd bs=$chunk of=\"$dest\""
|
||
showProgress=0
|
||
if \
|
||
[ -x /usr/bin/dcounter ] && \
|
||
[ -f /etc/image.md5 ] && \
|
||
[ -b "$dest" ] && \
|
||
[ -z "$disableProgressInfo" ]
|
||
then
|
||
showProgress=1
|
||
hideSplash
|
||
read sum1 blocks blocksize zblocks zblocksize < /etc/image.md5
|
||
needBytes=$((blocks * blocksize))
|
||
needMByte=$((needBytes / 1048576))
|
||
if [ ! -z "$zblocks" ];then
|
||
needZBytes=$((zblocks * zblocksize))
|
||
needZMByte=$((needZBytes / 1048576))
|
||
fi
|
||
progressBaseName=$(basename "$path")
|
||
TEXT_LOAD=$(getText "Loading %1" "$progressBaseName")
|
||
TEXT_COMP=$(getText "Uncompressing %1" "$progressBaseName")
|
||
dump="dcounter -s $needMByte -l \"$TEXT_LOAD \" 2>/progress | $dump"
|
||
fi
|
||
#======================================
|
||
# build download command
|
||
#--------------------------------------
|
||
case "$type" in
|
||
"local")
|
||
if [ ! -z "$izip" ];then
|
||
call="$unzip < $host/$path \
|
||
2>$TRANSFER_ERRORS_FILE | $dump"
|
||
else
|
||
call="dd if=$host/$path bs=$chunk |\
|
||
$dump"
|
||
fi
|
||
;;
|
||
"http")
|
||
if [ ! -z "$izip" ];then
|
||
call="curl -f http://$host/$encoded_path \
|
||
2>$TRANSFER_ERRORS_FILE |\
|
||
$unzip 2>>$TRANSFER_ERRORS_FILE | $dump"
|
||
else
|
||
call="curl -f http://$host/$encoded_path \
|
||
2>$TRANSFER_ERRORS_FILE |\
|
||
$dump"
|
||
fi
|
||
;;
|
||
"https")
|
||
if [ ! -z "$izip" ];then
|
||
call="curl -f -k https://$host/$encoded_path \
|
||
2>$TRANSFER_ERRORS_FILE |\
|
||
$unzip 2>>$TRANSFER_ERRORS_FILE | $dump"
|
||
else
|
||
call="curl -f -k https://$host/$encoded_path \
|
||
2>$TRANSFER_ERRORS_FILE |\
|
||
$dump"
|
||
fi
|
||
;;
|
||
"ftp")
|
||
if [ ! -z "$izip" ];then
|
||
call="curl ftp://$host/$encoded_path \
|
||
2>$TRANSFER_ERRORS_FILE |\
|
||
$unzip 2>>$TRANSFER_ERRORS_FILE | $dump"
|
||
else
|
||
call="curl ftp://$host/$encoded_path \
|
||
2>$TRANSFER_ERRORS_FILE |\
|
||
$dump"
|
||
fi
|
||
;;
|
||
"tftp")
|
||
validateBlockSize
|
||
# /.../
|
||
# atftp activates multicast by '--option "multicast"'
|
||
# and deactivates it again by '--option "disable multicast"'
|
||
# ----
|
||
if [ -f /etc/image.md5 ] && [ -b "$dest" ];then
|
||
# enable multicast for system image and transfer to block device
|
||
multicast_atftp="multicast"
|
||
else
|
||
# disable multicast for any other transfer
|
||
multicast_atftp="disable multicast"
|
||
fi
|
||
havetemp_dir=1
|
||
if [ -z "$FETCH_FILE_TEMP_DIR" ];then
|
||
# we don't have a tmp dir available for downloading
|
||
havetemp_dir=0
|
||
elif [ -e "$FETCH_FILE_TEMP_DIR/${path##*/}" ];then
|
||
# temporary download data already exists
|
||
havetemp_dir=0
|
||
else
|
||
# prepare use of temp files for compressed download
|
||
FETCH_FILE_TEMP_FILE="$FETCH_FILE_TEMP_DIR/${path##*/}"
|
||
export FETCH_FILE_TEMP_FILE
|
||
fi
|
||
if [ ! -z "$izip" ];then
|
||
if [ $havetemp_dir -eq 0 ];then
|
||
# /.../
|
||
# operate without temp files, standard case
|
||
# ----
|
||
call="busybox tftp \
|
||
-b $imageBlkSize -g -r \"$path\" \
|
||
-l >($unzip 2>>$TRANSFER_ERRORS_FILE | $dump) \
|
||
$host 2>>$TRANSFER_ERRORS_FILE"
|
||
else
|
||
# /.../
|
||
# operate using temp files
|
||
# export the path to allow temp file management in a hook
|
||
# ----
|
||
if [ $showProgress -eq 1 ];then
|
||
call="(atftp \
|
||
--trace \
|
||
--option \"$multicast_atftp\" \
|
||
--option \"blksize $imageBlkSize\" \
|
||
-g -r \"$path\" -l \"$FETCH_FILE_TEMP_FILE\" \
|
||
$host 2>&1 | \
|
||
atftpProgress \
|
||
$needZMByte \"$TEXT_LOAD\" \
|
||
$TRANSFER_ERRORS_FILE $imageBlkSize \
|
||
>&2 ; \
|
||
$unzip < \"$FETCH_FILE_TEMP_FILE\" | \
|
||
dcounter -s $needMByte -l \"$TEXT_COMP \" | \
|
||
dd bs=$chunk of=\"$dest\" ) 2>/progress "
|
||
else
|
||
call="atftp \
|
||
--option \"$multicast_atftp\" \
|
||
--option \"blksize $imageBlkSize\" \
|
||
-g -r \"$path\" -l \"$FETCH_FILE_TEMP_FILE\" $host \
|
||
&> $TRANSFER_ERRORS_FILE ; \
|
||
$unzip < \"$FETCH_FILE_TEMP_FILE\" | \
|
||
dd bs=$chunk of=\"$dest\" "
|
||
fi
|
||
fi
|
||
else
|
||
if [ $showProgress -eq 1 ];then
|
||
call="atftp \
|
||
--trace \
|
||
--option \"$multicast_atftp\" \
|
||
--option \"blksize $imageBlkSize\" \
|
||
-g -r \"$path\" -l \"$dest\" $host 2>&1 | \
|
||
atftpProgress \
|
||
$needMByte \"$TEXT_LOAD\" \
|
||
$TRANSFER_ERRORS_FILE $imageBlkSize \
|
||
> /progress"
|
||
else
|
||
call="atftp \
|
||
--option \"$multicast_atftp\" \
|
||
--option \"blksize $imageBlkSize\" \
|
||
-g -r \"$path\" -l \"$dest\" $host \
|
||
&> $TRANSFER_ERRORS_FILE"
|
||
fi
|
||
fi
|
||
;;
|
||
*)
|
||
systemException "Unknown download type: $type" "reboot"
|
||
;;
|
||
esac
|
||
#======================================
|
||
# run the download
|
||
#--------------------------------------
|
||
if [ $showProgress -eq 1 ];then
|
||
test -e /progress || mkfifo /progress
|
||
test -e /tmp/load_code && rm -f /tmp/load_code
|
||
errorLogStop
|
||
(
|
||
eval $call \; 'echo ${PIPESTATUS[0]} > /tmp/load_code' &>/dev/null
|
||
)&
|
||
call_pid=$!
|
||
echo "cat /progress | dialog \
|
||
--backtitle \"$TEXT_INSTALLTITLE\" \
|
||
--progressbox 3 65
|
||
" > /tmp/progress.sh
|
||
if FBOK;then
|
||
fbiterm -m $UFONT -- bash -e /tmp/progress.sh
|
||
else
|
||
bash -e /tmp/progress.sh
|
||
fi
|
||
clear
|
||
wait $call_pid
|
||
loadCode=`cat /tmp/load_code`
|
||
if [ -z "$loadCode" ]; then
|
||
systemException \
|
||
"Failed to get the download process return value" \
|
||
"reboot"
|
||
fi
|
||
else
|
||
eval $call \; 'loadCode=${PIPESTATUS[0]}'
|
||
fi
|
||
if [ $showProgress -eq 1 ];then
|
||
errorLogContinue
|
||
fi
|
||
loadStatus=`cat $TRANSFER_ERRORS_FILE`
|
||
return $loadCode
|
||
}
|
||
|
||
#======================================
|
||
# fetchFileLocal
|
||
#--------------------------------------
|
||
function fetchFileLocal {
|
||
# /.../
|
||
# ----
|
||
fetchFile "$1" "$2" "$3" "$KIWI_LOCAL_CACHE_DIR" "local"
|
||
}
|
||
|
||
#======================================
|
||
# putFile
|
||
#--------------------------------------
|
||
function putFile {
|
||
# /.../
|
||
# the generic putFile function is used to upload boot data on
|
||
# a server. Supported protocols are tftp, ftp, http, https
|
||
# ----
|
||
local IFS=$IFS_ORIG
|
||
local path=$1
|
||
local dest=$2
|
||
local host=$3
|
||
local type=$4
|
||
local encoded_dest
|
||
if test -z "$path"; then
|
||
systemException "No path specified" "reboot"
|
||
fi
|
||
if [ ! -z $kiwiserver ];then
|
||
host=$kiwiserver
|
||
fi
|
||
if test -z "$host"; then
|
||
systemException "No server specified" "reboot"
|
||
fi
|
||
if [ ! -z $kiwiservertype ]; then
|
||
type=$kiwiservertype
|
||
fi
|
||
if test -z "$type"; then
|
||
type="tftp"
|
||
fi
|
||
encoded_dest=$(encodeURL "$dest")
|
||
case "$type" in
|
||
"local")
|
||
cp -f "$path" "$host/$dest" > $TRANSFER_ERRORS_FILE 2>&1
|
||
return $?
|
||
;;
|
||
"http")
|
||
curl -f -T "$path" http://$host/$encoded_dest \
|
||
> $TRANSFER_ERRORS_FILE 2>&1
|
||
return $?
|
||
;;
|
||
"https")
|
||
curl -f -T "$path" https://$host/$encoded_dest \
|
||
> $TRANSFER_ERRORS_FILE 2>&1
|
||
return $?
|
||
;;
|
||
"ftp")
|
||
curl -T "$path" ftp://$host/$encoded_dest \
|
||
> $TRANSFER_ERRORS_FILE 2>&1
|
||
return $?
|
||
;;
|
||
"tftp")
|
||
atftp -p -l "$path" -r "$dest" $host >/dev/null 2>&1
|
||
return $?
|
||
;;
|
||
*)
|
||
systemException "Unknown download type: $type" "reboot"
|
||
;;
|
||
esac
|
||
}
|
||
|
||
#======================================
|
||
# validateRootTree
|
||
#--------------------------------------
|
||
function validateRootTree {
|
||
# /.../
|
||
# after the root of the system image has been mounted we should
|
||
# check whether that mount is a valid system tree or not. Therefore
|
||
# some sanity checks are made here
|
||
# ----
|
||
local IFS=$IFS_ORIG
|
||
local prefix=/mnt
|
||
if [ ! -x $prefix/sbin/init -a ! -L $prefix/sbin/init ];then
|
||
systemException "/sbin/init no such file or not executable" "reboot"
|
||
fi
|
||
}
|
||
|
||
#======================================
|
||
# getDiskID
|
||
#--------------------------------------
|
||
function getDiskID {
|
||
# /.../
|
||
# this function is able to turn a given standard device
|
||
# name into the udev ID based representation
|
||
# ----
|
||
local IFS=$IFS_ORIG
|
||
local device=$1
|
||
local swap=$2
|
||
local prefix=by-id
|
||
if [ -z "$device" ];then
|
||
return
|
||
fi
|
||
if [ ! -z "$kiwi_lvmgroup" ] && echo $device | grep -q "$kiwi_lvmgroup";then
|
||
echo $device
|
||
return
|
||
fi
|
||
if [ -z "$swap" ] && [[ $device =~ ^/dev/md ]];then
|
||
echo $device
|
||
return
|
||
fi
|
||
if [ ! -z "$NON_PERSISTENT_DEVICE_NAMES" ]; then
|
||
echo $device
|
||
return
|
||
fi
|
||
if [[ $device =~ ^/dev/dm- ]];then
|
||
for i in /dev/mapper/*;do
|
||
if [ ! -L $i ];then
|
||
continue
|
||
fi
|
||
local dev=$(readlink $i)
|
||
dev=/dev/$(basename "$dev")
|
||
if [ $dev = $device ];then
|
||
echo $i
|
||
return
|
||
fi
|
||
done
|
||
fi
|
||
if [ ! -z "$kiwi_devicepersistency" ];then
|
||
prefix=$kiwi_devicepersistency
|
||
fi
|
||
for i in /dev/disk/$prefix/*;do
|
||
if [ -z "$i" ];then
|
||
continue
|
||
fi
|
||
if echo $i | grep -q edd-;then
|
||
continue
|
||
fi
|
||
local dev=$(readlink $i)
|
||
dev=/dev/$(basename "$dev")
|
||
if [ $dev = $device ];then
|
||
echo $i
|
||
return
|
||
fi
|
||
done
|
||
echo $device
|
||
}
|
||
#======================================
|
||
# getDiskDevice
|
||
#--------------------------------------
|
||
function getDiskDevice {
|
||
# /.../
|
||
# this function is able to turn the given udev disk
|
||
# ID label into the /dev/ device name
|
||
# ----
|
||
local IFS=$IFS_ORIG
|
||
local device=$(readlink $1)
|
||
if [ -z "$device" ];then
|
||
echo $1
|
||
return
|
||
fi
|
||
device=$(basename $device)
|
||
device=/dev/$device
|
||
echo $device
|
||
}
|
||
#======================================
|
||
# getDiskModel
|
||
#--------------------------------------
|
||
function getDiskModels {
|
||
# /.../
|
||
# this function returns the disk identifier as
|
||
# registered in the sysfs layer
|
||
# ----
|
||
local IFS=$IFS_ORIG
|
||
local models=`cat /sys/block/*/device/model 2>/dev/null`
|
||
if [ ! -z "$models" ];then
|
||
echo $models; return
|
||
fi
|
||
echo "unknown"
|
||
}
|
||
#======================================
|
||
# setupInittab
|
||
#--------------------------------------
|
||
function setupInittab {
|
||
# /.../
|
||
# setup default runlevel according to /proc/cmdline
|
||
# information. If textmode is set to 1 we will boot into
|
||
# runlevel 3
|
||
# ----
|
||
local IFS=$IFS_ORIG
|
||
local prefix=$1
|
||
if cat /proc/cmdline | grep -qi "textmode=1";then
|
||
sed -i -e s"@id:.*:initdefault:@id:3:initdefault:@" $prefix/etc/inittab
|
||
fi
|
||
}
|
||
#======================================
|
||
# setupConfigFiles
|
||
#--------------------------------------
|
||
function setupConfigFiles {
|
||
# /.../
|
||
# all files created below /config inside the initrd are
|
||
# now copied into the system image
|
||
# ----
|
||
local IFS=$IFS_ORIG
|
||
local file
|
||
local dir
|
||
local prefix=/mnt
|
||
cd /config
|
||
find . -type f | while read file;do
|
||
dir=$(dirname $file)
|
||
if [ ! -d $prefix/$dir ];then
|
||
mkdir -p $prefix/$dir
|
||
fi
|
||
if ! canWrite $prefix/$dir;then
|
||
Echo "Can't write to $dir, read-only filesystem... skipped"
|
||
continue
|
||
fi
|
||
cp $file $prefix/$file
|
||
done
|
||
cd /
|
||
rm -rf /config
|
||
}
|
||
#======================================
|
||
# setupMachineID
|
||
#--------------------------------------
|
||
function setupMachineID {
|
||
# /.../
|
||
# This method can be used to handle the machine ID
|
||
# in /etc/machine-id and/or /var/lib/dbus/machine-id
|
||
# It is actually implemented as a custom hook script
|
||
# ----
|
||
runHook handleMachineID "$@"
|
||
}
|
||
#======================================
|
||
# activateImage
|
||
#--------------------------------------
|
||
function activateImage {
|
||
# /.../
|
||
# move the udev created nodes from the initrd into
|
||
# the system root tree call the pre-init phase which
|
||
# already runs in the new tree and finaly switch the
|
||
# new tree to be the new root (/)
|
||
# ----
|
||
local IFS=$IFS_ORIG
|
||
local prefix=/mnt
|
||
#======================================
|
||
# setup image name
|
||
#--------------------------------------
|
||
local name
|
||
if [ ! -z "$stickSerial" ];then
|
||
name="$stickSerial on -> $stickDevice"
|
||
elif [ ! -z "$imageName" ];then
|
||
name=$imageName
|
||
elif [ ! -z "$imageRootName" ];then
|
||
name=$imageRootName
|
||
elif [ ! -z "$imageRootDevice" ];then
|
||
name=$imageRootDevice
|
||
elif [ ! -z "$imageDiskDevice" ];then
|
||
name=$imageDiskDevice
|
||
else
|
||
name="unknown"
|
||
fi
|
||
#======================================
|
||
# move union mount points to system
|
||
#--------------------------------------
|
||
local roDir=read-only
|
||
local rwDir=read-write
|
||
local xiDir=xino
|
||
if [ -z "$NFSROOT" ];then
|
||
if [ -d $roDir ];then
|
||
mkdir -p $prefix/$roDir && mount --move /$roDir $prefix/$roDir
|
||
fi
|
||
if [ -d $rwDir ];then
|
||
mkdir -p $prefix/$rwDir && mount --move /$rwDir $prefix/$rwDir
|
||
fi
|
||
if [ -d $xiDir ];then
|
||
mkdir -p $prefix/$xiDir && mount --move /$xiDir $prefix/$xiDir
|
||
fi
|
||
fi
|
||
#======================================
|
||
# move live CD mount points to system
|
||
#--------------------------------------
|
||
local cdDir=/livecd
|
||
if [ -d $cdDir ];then
|
||
mkdir -p $prefix/$cdDir && mount --move /$cdDir $prefix/$cdDir
|
||
rm -r $cdDir && ln -s $prefix/$cdDir $cdDir
|
||
if [ -d /cow ];then
|
||
mkdir -p $prefix/cow && mount --move /cow $prefix/cow
|
||
fi
|
||
if [ -d /isofrom ];then
|
||
mkdir -p $prefix/isofrom && mount --move /isofrom $prefix/isofrom
|
||
fi
|
||
fi
|
||
#======================================
|
||
# move device nodes
|
||
#--------------------------------------
|
||
Echo "Activating Image: [$name]"
|
||
udevPending
|
||
mkdir -p $prefix/run
|
||
mkdir -p $prefix/dev
|
||
mkdir -p $prefix/var/run
|
||
mount --move /dev $prefix/dev
|
||
if [[ ! $kiwi_initrdname =~ SLE.11 ]];then
|
||
mount --move /run $prefix/run
|
||
if [ ! -L $prefix/var/run ];then
|
||
mount --move /var/run $prefix/var/run
|
||
fi
|
||
fi
|
||
udevKill
|
||
#======================================
|
||
# run preinit stage
|
||
#--------------------------------------
|
||
Echo "Preparing preinit phase..."
|
||
if ! cp /iprocs $prefix;then
|
||
systemException "Failed to copy: iprocs" "reboot"
|
||
fi
|
||
if ! cp /preinit $prefix;then
|
||
systemException "Failed to copy: preinit" "reboot"
|
||
fi
|
||
if ! cp /include $prefix;then
|
||
systemException "Failed to copy: include" "reboot"
|
||
fi
|
||
local utimer=$(lookup utimer)
|
||
if [ -e "$utimer" ];then
|
||
cp $utimer $prefix
|
||
fi
|
||
local killall5=$(lookup killall5)
|
||
if [ ! -e $prefix/$killall5 ]; then
|
||
touch $prefix/killall5.from-initrd
|
||
fi
|
||
if touch $(dirname $prefix/$killall5); then
|
||
if ! cp -f -a $killall5 $prefix/$killall5; then
|
||
systemException "Failed to copy: killall5" "reboot"
|
||
fi
|
||
fi
|
||
local pidof=$(lookup pidof)
|
||
if [ ! -e $prefix/$pidof ];then
|
||
touch $prefix/pidof.from-initrd
|
||
fi
|
||
if touch $(dirname $prefix/$pidof); then
|
||
if ! cp -f -a $pidof $prefix/$pidof;then
|
||
systemException "Failed to copy: pidof" "reboot"
|
||
fi
|
||
fi
|
||
stopMultipathd
|
||
}
|
||
#======================================
|
||
# cleanImage
|
||
#--------------------------------------
|
||
function cleanImage {
|
||
# /.../
|
||
# remove preinit code from system image before
|
||
# real init is called. this function runs already
|
||
# inside the system root directory via chroot
|
||
# ----
|
||
local IFS=$IFS_ORIG
|
||
local bootdir=boot_bind
|
||
#======================================
|
||
# setup logging in this mode
|
||
#--------------------------------------
|
||
exec 2>>$ELOG_FILE
|
||
set -x
|
||
#======================================
|
||
# kill second utimer and tail
|
||
#--------------------------------------
|
||
. /iprocs
|
||
test -n "$UTIMER_PID" && kill $UTIMER_PID &>/dev/null
|
||
#======================================
|
||
# remove preinit code from system image
|
||
#--------------------------------------
|
||
rm -f /tmp/utimer
|
||
rm -f /dev/utimer
|
||
rm -f /utimer
|
||
rm -f /iprocs
|
||
rm -f /preinit
|
||
rm -f /include
|
||
rm -f /.kconfig
|
||
rm -f /.profile
|
||
rm -rf /image
|
||
if [ -e /pidof.from-initrd ];then
|
||
rm -f /pidof.from-initrd
|
||
rm -f $(lookup pidof)
|
||
fi
|
||
if [ -e /killall5.from-initrd ];then
|
||
rm -f /killall5.from-initrd
|
||
rm -f $(lookup killall5)
|
||
fi
|
||
#======================================
|
||
# return early for special types
|
||
#--------------------------------------
|
||
if \
|
||
[ "$haveClicFS" = "yes" ] || \
|
||
[ ! -z "$NFSROOT" ] || \
|
||
[ ! -z "$NBDROOT" ] || \
|
||
[ ! -z "$AOEROOT" ]
|
||
then
|
||
return
|
||
fi
|
||
#======================================
|
||
# return early for systemd
|
||
#--------------------------------------
|
||
if [ $init = "/bin/systemd" ];then
|
||
return
|
||
fi
|
||
#======================================
|
||
# umount LVM root parts
|
||
#--------------------------------------
|
||
local volume_name
|
||
local mount_point
|
||
for i in $(readVolumeSetup "/.profile");do
|
||
volume_name=$(getVolumeName $i)
|
||
if [ $volume_name = "LVRoot" ]; then
|
||
continue
|
||
fi
|
||
mount_point=$(getVolumeMountPoint $i)
|
||
umount /$mount_point 1>&2
|
||
done
|
||
#======================================
|
||
# umount image boot partition if any
|
||
#--------------------------------------
|
||
if [ -e /$bootdir ];then
|
||
umount /$bootdir 1>&2
|
||
fi
|
||
umount /boot 1>&2
|
||
#======================================
|
||
# turn off swap
|
||
#--------------------------------------
|
||
mount -t proc proc /proc
|
||
swapoff -a 1>&2
|
||
umount /proc 1>&2
|
||
}
|
||
#======================================
|
||
# bootImage
|
||
#--------------------------------------
|
||
function bootImage {
|
||
# /.../
|
||
# call the system image init process and therefore
|
||
# boot into the operating system
|
||
# ----
|
||
local IFS=$IFS_ORIG
|
||
local reboot=no
|
||
local option=${kernel_cmdline[@]}
|
||
local prefix=/mnt
|
||
#======================================
|
||
# Set active console to default font
|
||
#--------------------------------------
|
||
setupConsoleFont
|
||
#======================================
|
||
# check for init kernel option
|
||
#--------------------------------------
|
||
if [ -z "$init" ];then
|
||
if [ -e $prefix/bin/systemd ];then
|
||
export init=/bin/systemd
|
||
else
|
||
export init=/sbin/init
|
||
fi
|
||
fi
|
||
#======================================
|
||
# turn runlevel 4 to 5 if found
|
||
#--------------------------------------
|
||
option=$(echo $@ | sed -e s@4@5@)
|
||
echo && Echo "Booting System: $option"
|
||
#======================================
|
||
# check for reboot request
|
||
#--------------------------------------
|
||
if [ "$LOCAL_BOOT" = "no" ];then
|
||
if [ -z "$KIWI_RECOVERY" ];then
|
||
if [ ! -z "$kiwi_oemreboot" ] || [ ! -z "$REBOOT_IMAGE" ];then
|
||
reboot=yes
|
||
fi
|
||
if [ ! -z "$kiwi_oemrebootinteractive" ];then
|
||
rebootinter=yes
|
||
fi
|
||
if [ ! -z "$kiwi_oemshutdown" ];then
|
||
shutdown=yes
|
||
fi
|
||
if [ ! -z "$kiwi_oemshutdowninteractive" ];then
|
||
shutdowninter=yes
|
||
fi
|
||
fi
|
||
fi
|
||
#======================================
|
||
# run resetBootBind
|
||
#--------------------------------------
|
||
if [ -z "$NETBOOT_ONLY" ];then
|
||
resetBootBind $prefix
|
||
fi
|
||
#======================================
|
||
# kill initial tail and utimer
|
||
#--------------------------------------
|
||
. /iprocs
|
||
test -n "$UTIMER_PID" && kill $UTIMER_PID &>/dev/null
|
||
#======================================
|
||
# copy boot log file into system image
|
||
#--------------------------------------
|
||
mkdir -p $prefix/var/log
|
||
rm -f $prefix/boot/mbrid
|
||
if [ -e $prefix/dev/shm/initrd.msg ];then
|
||
cp -f $prefix/dev/shm/initrd.msg $prefix/var/log/boot.msg
|
||
fi
|
||
if [ -e $ELOG_FILE ];then
|
||
cp -f $ELOG_FILE $prefix/$ELOG_FILE
|
||
fi
|
||
if [ ! -d $prefix/var/log/ConsoleKit ];then
|
||
mkdir -p $prefix/var/log/ConsoleKit
|
||
fi
|
||
#======================================
|
||
# umount proc
|
||
#--------------------------------------
|
||
umount proc &>/dev/null && \
|
||
umount proc &>/dev/null
|
||
#======================================
|
||
# run preinit and cleanImage
|
||
#--------------------------------------
|
||
chroot $prefix /bin/bash -c \
|
||
"/preinit"
|
||
chroot $prefix /bin/bash -c \
|
||
". /include ; exec 2>>$ELOG_FILE ; set -x ; cleanImage"
|
||
cd $prefix
|
||
#======================================
|
||
# tell logging the new root fs
|
||
#--------------------------------------
|
||
exec 2>>$prefix/$ELOG_FILE
|
||
set -x
|
||
#======================================
|
||
# tell plymouth the new root fs
|
||
#--------------------------------------
|
||
if lookup plymouthd &>/dev/null;then
|
||
plymouth update-root-fs --new-root-dir=$prefix
|
||
#======================================
|
||
# stop if not installed in system image
|
||
#--------------------------------------
|
||
if [ ! -e $prefix/usr/bin/plymouth ];then
|
||
plymouth quit
|
||
fi
|
||
fi
|
||
#======================================
|
||
# export root block device
|
||
#--------------------------------------
|
||
if [ -b "$imageRootDevice" ];then
|
||
export ROOTFS_BLKDEV=$imageRootDevice
|
||
fi
|
||
#======================================
|
||
# rootfs is clean, skip check
|
||
#--------------------------------------
|
||
export ROOTFS_FSCK="0"
|
||
#======================================
|
||
# stop dropbear ssh server
|
||
#--------------------------------------
|
||
if [ ! -z "$DROPBEAR_PID" ];then
|
||
kill $DROPBEAR_PID
|
||
fi
|
||
#======================================
|
||
# hand over control to init
|
||
#--------------------------------------
|
||
if [ $reboot = "yes" ];then
|
||
Echo "Reboot requested... rebooting after preinit"
|
||
exec chroot . /sbin/reboot -f -i
|
||
fi
|
||
if [ "$rebootinter" = "yes" ];then
|
||
Echo "Reboot requested... rebooting after preinit"
|
||
if [ "$OEMInstallType" = "CD" ];then
|
||
TEXT_DUMP=$TEXT_CDPULL
|
||
else
|
||
TEXT_DUMP=$TEXT_USBPULL
|
||
fi
|
||
Dialog \
|
||
--backtitle \"$TEXT_INSTALLTITLE\" \
|
||
--msgbox "\"$TEXT_DUMP\"" 5 70
|
||
clear
|
||
Echo "Prepare for reboot"
|
||
exec chroot . /sbin/reboot -f -i
|
||
fi
|
||
if [ "$shutdown" = "yes" ];then
|
||
Echo "Shutdown requested... system shutdown after preinit"
|
||
exec chroot . /sbin/halt -fihp
|
||
fi
|
||
if [ "$shutdowninter" = "yes" ];then
|
||
Echo "Shutdown requested... system shutdown after preinit"
|
||
if [ "$OEMInstallType" = "CD" ];then
|
||
TEXT_DUMP=$TEXT_CDPULL_SDOWN
|
||
else
|
||
TEXT_DUMP=$TEXT_USBPULL_SDOWN
|
||
fi
|
||
Dialog \
|
||
--backtitle \"$TEXT_INSTALLTITLE\" \
|
||
--msgbox "\"$TEXT_DUMP\"" 5 70
|
||
clear
|
||
Echo "Prepare for shutdown"
|
||
exec chroot . /sbin/halt -fihp
|
||
fi
|
||
if lookup switch_root &>/dev/null;then
|
||
exec switch_root . $init $option &>/dev/null
|
||
else
|
||
if lookup pivot_root &>/dev/null;then
|
||
pivot_root . run/initramfs &>/dev/null
|
||
fi
|
||
exec chroot . $init $option
|
||
fi
|
||
}
|
||
#======================================
|
||
# setupUnionFS
|
||
#--------------------------------------
|
||
function setupUnionFS {
|
||
# /.../
|
||
# export the UNIONFS_CONFIG environment variable
|
||
# which contains a three part coma separated list of the
|
||
# following style: rwDevice,roDevice,unionType. The
|
||
# devices are stores by disk ID if possible
|
||
# ----
|
||
local IFS=$IFS_ORIG
|
||
local rwDevice=$(getDiskID $1)
|
||
local roDevice=$(getDiskID $2)
|
||
local unionFST=$3
|
||
if [[ "$roDevice" =~ aoe|nbd ]]; then
|
||
roDevice=$imageRootDevice
|
||
fi
|
||
if [ -e "$rwDevice" ]; then
|
||
luksOpen $rwDevice luksReadWrite
|
||
rwDeviceLuks=$luksDeviceOpened
|
||
fi
|
||
if [ -e "$roDevice" ]; then
|
||
luksOpen $roDevice luksReadOnly
|
||
roDeviceLuks=$luksDeviceOpened
|
||
fi
|
||
if [ ! -z "$rwDeviceLuks" ] && [ ! "$rwDeviceLuks" = "$rwDevice" ];then
|
||
rwDevice=$rwDeviceLuks
|
||
export haveLuks="yes"
|
||
fi
|
||
if [ ! -z "$roDeviceLuks" ] && [ ! "$roDeviceLuks" = "$roDevice" ];then
|
||
roDevice=$roDeviceLuks
|
||
export haveLuks="yes"
|
||
fi
|
||
if [ ! -z "$rwDevice" ] && [ ! -z "$roDevice" ];then
|
||
export UNIONFS_CONFIG="$rwDevice,$roDevice,$unionFST"
|
||
fi
|
||
}
|
||
#======================================
|
||
# canWrite
|
||
#--------------------------------------
|
||
function canWrite {
|
||
# /.../
|
||
# check if we can write to the given location
|
||
# returns zero on success.
|
||
# ---
|
||
local IFS=$IFS_ORIG
|
||
local prefix=$1
|
||
if [ -z "$prefix" ];then
|
||
prefix=/mnt
|
||
fi
|
||
if [ ! -d $prefix ];then
|
||
return 1
|
||
fi
|
||
if touch $prefix/can-write &>/dev/null;then
|
||
rm $prefix/can-write
|
||
return 0
|
||
fi
|
||
return 1
|
||
}
|
||
#======================================
|
||
# xenServer
|
||
#--------------------------------------
|
||
function xenServer {
|
||
# /.../
|
||
# check if the given kernel is a xen kernel and if so
|
||
# check if a dom0 or a domU setup was requested
|
||
# ----
|
||
local IFS=$IFS_ORIG
|
||
local kname=$1
|
||
local mountPrefix=$2
|
||
local sysmap="$mountPrefix/boot/System.map-$kname"
|
||
local isxen
|
||
if [ ! -e $sysmap ]; then
|
||
sysmap="$mountPrefix/boot/System.map"
|
||
fi
|
||
if [ ! -e $sysmap ]; then
|
||
Echo "No system map for kernel $kname found"
|
||
return 1
|
||
fi
|
||
isxen=$(grep -c "xen_base" $sysmap)
|
||
if [ $isxen -eq 0 ]; then
|
||
# not a xen kernel
|
||
return 1
|
||
fi
|
||
if [ -z "$kiwi_xendomain" ];then
|
||
# no xen domain set, assume domU
|
||
return 1
|
||
fi
|
||
if [ $kiwi_xendomain = "dom0" ];then
|
||
# xen dom0 requested
|
||
return 0
|
||
fi
|
||
return 1
|
||
}
|
||
#======================================
|
||
# makeLabel
|
||
#--------------------------------------
|
||
function makeLabel {
|
||
# /.../
|
||
# create boot label and replace all spaces with
|
||
# underscores. current bootloaders show the
|
||
# underscore sign as as space in the boot menu
|
||
# ---
|
||
local IFS=$IFS_ORIG
|
||
if [ ! $loader = "grub2" ]; then
|
||
echo $1 | tr " " "_"
|
||
else
|
||
echo $1
|
||
fi
|
||
}
|
||
#======================================
|
||
# waitForX
|
||
#--------------------------------------
|
||
function waitForX {
|
||
# /.../
|
||
# wait for the X-Server with PID $xserver_pid to
|
||
# become read for client calls
|
||
# ----
|
||
local IFS=$IFS_ORIG
|
||
local xserver_pid=$1
|
||
local testx=/usr/sbin/testX
|
||
local err=1
|
||
while kill -0 $xserver_pid 2>/dev/null ; do
|
||
sleep 1
|
||
if test -e /tmp/.X11-unix/X0 && test -x $testx ; then
|
||
$testx 16 2>/dev/null
|
||
err=$?
|
||
# exit code 1 -> XOpenDisplay failed...
|
||
if test $err = 1;then
|
||
Echo "TestX: XOpenDisplay failed"
|
||
return 1
|
||
fi
|
||
# exit code 2 -> color or dimensions doesn't fit...
|
||
if test $err = 2;then
|
||
Echo "TestX: color or dimensions doesn't fit"
|
||
kill $xserver_pid
|
||
return 1
|
||
fi
|
||
# server is running, detach oom-killer from it
|
||
echo -n '-17' > /proc/$xserver_pid/oom_adj
|
||
return 0
|
||
fi
|
||
done
|
||
return 1
|
||
}
|
||
#======================================
|
||
# startX
|
||
#--------------------------------------
|
||
function startX {
|
||
# /.../
|
||
# start X-Server and wait for it to become ready
|
||
# ----
|
||
local IFS=$IFS_ORIG
|
||
export DISPLAY=:0
|
||
local XServer=/usr/bin/Xorg
|
||
if [ -x /usr/X11R6/bin/Xorg ];then
|
||
XServer=/usr/X11R6/bin/Xorg
|
||
fi
|
||
$XServer -deferglyphs 16 vt07 &
|
||
export XServerPID=$!
|
||
if ! waitForX $XServerPID;then
|
||
Echo "Failed to start X-Server"
|
||
return 1
|
||
fi
|
||
return 0
|
||
}
|
||
#======================================
|
||
# stoppX
|
||
#--------------------------------------
|
||
function stoppX {
|
||
local IFS=$IFS_ORIG
|
||
if [ -z "$XServerPID" ];then
|
||
return
|
||
fi
|
||
if kill -0 $XServerPID 2>/dev/null; then
|
||
sleep 1 && kill $XServerPID
|
||
while kill -0 $XServerPID 2>/dev/null; do
|
||
sleep 1
|
||
done
|
||
fi
|
||
}
|
||
#======================================
|
||
# luksOpen
|
||
#--------------------------------------
|
||
function luksOpen {
|
||
# /.../
|
||
# check given device if it uses the LUKS extension
|
||
# if yes open the device and return the new
|
||
# /dev/mapper/ device name
|
||
# ----
|
||
local IFS=$IFS_ORIG
|
||
local ldev=$1
|
||
local name=$2
|
||
local retry=1
|
||
local info
|
||
if [ -z "$ldev" ];then
|
||
ldev=$(ddn $imageDiskDevice $kiwi_RootPart)
|
||
fi
|
||
#======================================
|
||
# check device for luks extension
|
||
#--------------------------------------
|
||
if ! cryptsetup isLuks $ldev &>/dev/null;then
|
||
return
|
||
fi
|
||
#======================================
|
||
# no map name set, build it from device
|
||
#--------------------------------------
|
||
if [ -z "$name" ];then
|
||
name=luks
|
||
fi
|
||
#======================================
|
||
# luks map already exists, return
|
||
#--------------------------------------
|
||
if [ -e /dev/mapper/$name ];then
|
||
export luksDeviceOpened=/dev/mapper/$name
|
||
return
|
||
fi
|
||
#======================================
|
||
# ask for passphrase if not cached
|
||
#--------------------------------------
|
||
while true;do
|
||
if [ -z "$luks_pass" ];then
|
||
Echo "Try: $retry"
|
||
errorLogStop
|
||
Dialog \
|
||
--insecure --passwordbox "\"$TEXT_LUKS\"" 10 60
|
||
luks_pass=$(DialogResult)
|
||
errorLogContinue
|
||
fi
|
||
if echo "$luks_pass" | cryptsetup luksOpen $ldev $name;then
|
||
break
|
||
fi
|
||
unset luks_pass
|
||
if [ -n "$luks_open_can_fail" ]; then
|
||
unset luksDeviceOpened
|
||
return 1
|
||
fi
|
||
if [ $retry -eq 3 ];then
|
||
systemException \
|
||
"Max retries reached... reboot" \
|
||
"reboot"
|
||
fi
|
||
retry=$(($retry + 1))
|
||
done
|
||
#======================================
|
||
# wait for the luks map to appear
|
||
#--------------------------------------
|
||
if ! waitForStorageDevice /dev/mapper/$name &>/dev/null;then
|
||
systemException \
|
||
"LUKS map /dev/mapper/$name doesn't appear... fatal !" \
|
||
"reboot"
|
||
fi
|
||
#======================================
|
||
# store luks device and return
|
||
#--------------------------------------
|
||
export luksDeviceOpened=/dev/mapper/$name
|
||
return 0
|
||
}
|
||
#======================================
|
||
# luksResize
|
||
#--------------------------------------
|
||
function luksResize {
|
||
# /.../
|
||
# check if luksDeviceOpened is defined and
|
||
# run cryptsetup resize on the mapper name
|
||
# ----
|
||
local IFS=$IFS_ORIG
|
||
if [ ! -z "$luksDeviceOpened" ] && [ -e $luksDeviceOpened ];then
|
||
cryptsetup resize $luksDeviceOpened
|
||
udevPending
|
||
fi
|
||
}
|
||
#======================================
|
||
# luksClose
|
||
#--------------------------------------
|
||
function luksClose {
|
||
# /.../
|
||
# close all open LUKS mappings
|
||
# ----
|
||
local IFS=$IFS_ORIG
|
||
local name=$1
|
||
#======================================
|
||
# close specified name if set
|
||
#--------------------------------------
|
||
if [ -n "$1" ]; then
|
||
name=$(basename $1)
|
||
cryptsetup luksClose $name
|
||
return
|
||
fi
|
||
#======================================
|
||
# close all luks* map names
|
||
#--------------------------------------
|
||
for i in /dev/mapper/luks*;do
|
||
name=$(basename "$i")
|
||
cryptsetup luksClose $name
|
||
done
|
||
}
|
||
#======================================
|
||
# importText
|
||
#--------------------------------------
|
||
function importText {
|
||
# /.../
|
||
# read in all texts from the catalog
|
||
# ----
|
||
local IFS=$IFS_ORIG
|
||
export TEXT_TIMEOUT=$(
|
||
getText "Boot continues in 10 sec...")
|
||
export TEXT_OK=$(
|
||
getText "OK")
|
||
export TEXT_CANCEL=$(
|
||
getText "Cancel")
|
||
export TEXT_YES=$(
|
||
getText "Yes")
|
||
export TEXT_NO=$(
|
||
getText "No")
|
||
export TEXT_EXIT=$(
|
||
getText "Exit")
|
||
export TEXT_LUKS=$(
|
||
getText "Enter LUKS passphrase")
|
||
export TEXT_LICENSE=$(
|
||
getText "Do you accept the license agreement ?")
|
||
export TEXT_RESTORE=$(
|
||
getText "Do you want to start the System-Restore ?")
|
||
export TEXT_REPAIR=$(
|
||
getText "Do you want to start the System-Recovery ?")
|
||
export TEXT_RECOVERYTITLE=$(
|
||
getText "Restoring base operating system...")
|
||
export TEXT_INSTALLTITLE=$(
|
||
getText "Installation...")
|
||
export TEXT_CDPULL=$(
|
||
getText "Please remove the CD/DVD before reboot")
|
||
export TEXT_USBPULL=$(
|
||
getText "Please unplug the USB stick before reboot")
|
||
export TEXT_CDPULL_SDOWN=$(
|
||
getText "Please remove the CD/DVD before shutdown")
|
||
export TEXT_USBPULL_SDOWN=$(
|
||
getText "System will be shutdown. Remove USB stick before power on")
|
||
export TEXT_SELECT=$(
|
||
getText "Select disk for installation:")
|
||
export TEXT_BOOT_SETUP_FAILED=$(
|
||
getText "Bootloader installation has failed")
|
||
export TEXT_BOOT_SETUP_FAILED_INFO=$(
|
||
getText "The system will not be able to reboot. Please make sure to fixup and install the bootloader before next reboot. Check $ELOG_FILE for details")
|
||
}
|
||
#======================================
|
||
# selectLanguage
|
||
#--------------------------------------
|
||
function selectLanguage {
|
||
# /.../
|
||
# select language if not yet done. The value is
|
||
# used for all dialog windows with i18n support
|
||
# ----
|
||
local IFS=$IFS_ORIG
|
||
local title="\"Select Language\""
|
||
local list="en_US \"[ English ]\" on"
|
||
local list_orig=$list
|
||
local zh_CN=Chinese
|
||
local zh_TW=Taiwanese
|
||
local ru_RU=Russian
|
||
local de_DE=German
|
||
local ar_AR=Arabic
|
||
local cs_CZ=Czech
|
||
local el_GR=Greek
|
||
local es_ES=Spanish
|
||
local fi_FI=Finnish
|
||
local fr_FR=French
|
||
local hu_HU=Hungarian
|
||
local it_IT=Italian
|
||
local ja_JP=Japanese
|
||
local ko_KR=Korean
|
||
local nl_NL=Dutch
|
||
local pl_PL=Polish
|
||
local pt_BR=Portuguese
|
||
local sv_SE=Swedish
|
||
local tr_TR=Turkish
|
||
local nb_NO=Norwegian
|
||
local da_DK=Danish
|
||
local pt_PT=Portuguese
|
||
local en_GB=English
|
||
local code
|
||
local lang
|
||
#======================================
|
||
# Exports (Texts), default language
|
||
#--------------------------------------
|
||
importText
|
||
#======================================
|
||
# Check language environment
|
||
#--------------------------------------
|
||
if [ ! -z "$kiwi_oemunattended" ] && [ "$DIALOG_LANG" = "ask" ];then
|
||
# answer the language question in unatteneded mode
|
||
DIALOG_LANG=en_US
|
||
fi
|
||
if [ "$DIALOG_LANG" = "ask" ];then
|
||
for code in $(echo $kiwi_language | tr "," " ");do
|
||
if [ $code = "en_US" ];then
|
||
continue
|
||
fi
|
||
eval lang=\$$code
|
||
list="$list $code \"[ $lang ]\" off"
|
||
done
|
||
if [ "$list" = "$list_orig" ];then
|
||
DIALOG_LANG=en_US
|
||
else
|
||
Dialog \
|
||
--timeout 10 --no-cancel \
|
||
--backtitle \"$TEXT_TIMEOUT\" \
|
||
--radiolist \"$title\" 20 40 10 $list
|
||
DIALOG_LANG=$(DialogResult)
|
||
fi
|
||
fi
|
||
export LANG=$DIALOG_LANG.utf8
|
||
#======================================
|
||
# Exports (Texts), selected language
|
||
#--------------------------------------
|
||
importText
|
||
}
|
||
#======================================
|
||
# getText
|
||
#--------------------------------------
|
||
function getText {
|
||
# /.../
|
||
# return translated text
|
||
# ----
|
||
local IFS=$IFS_ORIG
|
||
local text=$(gettext kiwi "$1")
|
||
if [ ! -z "$2" ];then
|
||
text=$(echo $text | sed -e s"@%1@$2@")
|
||
fi
|
||
if [ ! -z "$3" ];then
|
||
text=$(echo $text | sed -e s"@%2@$3@")
|
||
fi
|
||
echo "$text"
|
||
}
|
||
#======================================
|
||
# displayEULA
|
||
#--------------------------------------
|
||
function displayEULA {
|
||
# /.../
|
||
# display in a dialog window the text part of the
|
||
# selected language file(s). The files are searched
|
||
# by the names in kiwi_showlicense
|
||
# ----
|
||
local IFS=$IFS_ORIG
|
||
local code=$(echo $DIALOG_LANG | cut -f1 -d_)
|
||
if [ -z "$kiwi_showlicense" ];then
|
||
Echo "No license name(s) configured"
|
||
return
|
||
fi
|
||
for name in $kiwi_showlicense;do
|
||
#======================================
|
||
# select license file by name
|
||
#--------------------------------------
|
||
code=/$name.$code.txt
|
||
if [ ! -f $code ];then
|
||
code=/$name.txt
|
||
fi
|
||
if [ ! -f $code ];then
|
||
code=/etc/YaST2/licenses/base/$name.$code.txt
|
||
fi
|
||
if [ ! -f $code ];then
|
||
code=/etc/YaST2/licenses/base/$name.txt
|
||
fi
|
||
if [ ! -f $code ];then
|
||
code=/etc/YaST2/licenses/base/$name
|
||
fi
|
||
if [ ! -f $code ];then
|
||
Echo "License with basename $name not found... skipped"
|
||
continue
|
||
fi
|
||
#======================================
|
||
# show license until accepted
|
||
#--------------------------------------
|
||
while true;do
|
||
Dialog --textbox $code 20 70 \
|
||
--and-widget --extra-button \
|
||
--extra-label "$TEXT_NO" \
|
||
--ok-label "$TEXT_YES" \
|
||
--cancel-label "$TEXT_CANCEL" \
|
||
--yesno "\"$TEXT_LICENSE\"" \
|
||
5 45
|
||
case $? in
|
||
0 ) break
|
||
;;
|
||
1 ) continue
|
||
;;
|
||
* ) systemException \
|
||
"License not accepted... reboot" \
|
||
"reboot"
|
||
;;
|
||
esac
|
||
done
|
||
done
|
||
}
|
||
#======================================
|
||
# ddn
|
||
#--------------------------------------
|
||
function ddn {
|
||
# /.../
|
||
# print disk device name (node name) according to the
|
||
# linux device node specs: If the last character of the
|
||
# device is a letter, attach the partition number. If the
|
||
# last character is a number, attach a 'p' and then the
|
||
# partition number. Exceptions:
|
||
# a) If the device name starts with /dev/disk
|
||
# the /dev/disk/<name>[-_]partN schema is used exclusively
|
||
# b) If the device name starts with /dev/ram
|
||
# the /dev/mapper/<name>pN schema is used exclusively
|
||
# c) If the device name starts with /dev/mapper
|
||
# the /dev/mapper/<name>_partN schema is checked optionally
|
||
# if it does not exist the default device node specs applies
|
||
# ----
|
||
local IFS=$IFS_ORIG
|
||
if echo $1 | grep -q "^\/dev\/disk\/" ; then
|
||
if [ -e $1"_part"$2 ]; then
|
||
echo $1"_part"$2
|
||
return
|
||
fi
|
||
echo $1"-part"$2
|
||
return
|
||
elif echo $1 | grep -q "^\/dev\/mapper\/" ; then
|
||
if [ -e $1"_part"$2 ]; then
|
||
echo $1"_part"$2
|
||
return
|
||
fi
|
||
elif echo $1 | grep -q "^\/dev\/ram";then
|
||
name=$(echo $1 | tr -d /dev)
|
||
echo /dev/mapper/${name}p$2
|
||
return
|
||
fi
|
||
local lastc=$(echo $1 | sed -e 's@\(^.*\)\(.$\)@\2@')
|
||
if echo $lastc | grep -qP "^\d+$";then
|
||
echo $1"p"$2
|
||
return
|
||
fi
|
||
echo $1$2
|
||
}
|
||
#======================================
|
||
# dn
|
||
#--------------------------------------
|
||
function dn {
|
||
# /.../
|
||
# print disk name (device name) according to the
|
||
# linux device node specs: If the device matches "p"
|
||
# followed by a number remove pX else remove
|
||
# the last number. Exceptions:
|
||
# loop devices
|
||
# ----
|
||
local IFS=$IFS_ORIG
|
||
local part=$(getDiskDevice $1)
|
||
if [[ $part =~ dev/loop[0-9] ]];then
|
||
echo $part
|
||
return
|
||
fi
|
||
if [[ $part =~ mapper/loop ]];then
|
||
part=$(echo $part | sed -e s@/mapper@@)
|
||
fi
|
||
local part_new=$(echo $part | sed -e 's@\(^.*\)\(p[0-9].*$\)@\1@')
|
||
if [ $part = $part_new ];then
|
||
part_new=$(echo $part | sed -e 's@\(^.*\)\([0-9].*$\)@\1@')
|
||
fi
|
||
echo $part_new
|
||
}
|
||
#======================================
|
||
# nd
|
||
#--------------------------------------
|
||
function nd {
|
||
# /.../
|
||
# print the number of the disk device according to the
|
||
# device node name.
|
||
# ----
|
||
local IFS=$IFS_ORIG
|
||
local part=$(getDiskDevice $1)
|
||
local part_new=$(echo $part | sed -e 's@\(^.*\)p\([0-9].*$\)@\2@')
|
||
if [ $part = $part_new ];then
|
||
part_new=$(echo $part | sed -e 's@\(^.*\)\([0-9].*$\)@\2@')
|
||
fi
|
||
echo $part_new
|
||
}
|
||
#======================================
|
||
# Dialog
|
||
#--------------------------------------
|
||
function Dialog {
|
||
# /.../
|
||
# run dialog in a bash inside an fbiterm or directly
|
||
# on the running terminal. Make the terminal the controlling
|
||
# tty first. The output of the dialog call and its exit code
|
||
# is stored in files
|
||
# ----
|
||
local IFS=$IFS_ORIG
|
||
local dialog_call=/tmp/dialog_call
|
||
local dialog_result=/tmp/dialog_result
|
||
local dialog_code=/tmp/dialog_code
|
||
hideSplash
|
||
cat > $dialog_call <<- EOF
|
||
dialog \
|
||
--ok-label "$TEXT_OK" \
|
||
--cancel-label "$TEXT_CANCEL" \
|
||
--yes-label "$TEXT_YES" \
|
||
--no-label "$TEXT_NO" \
|
||
--exit-label "$TEXT_EXIT" \
|
||
$@ 2>$dialog_result
|
||
echo -n \$? >$dialog_code
|
||
EOF
|
||
if FBOK;then
|
||
setsid -c -w fbiterm -m $UFONT -- bash -i $dialog_call
|
||
else
|
||
setsid -c -w bash -i $dialog_call
|
||
fi
|
||
local code=$(cat $dialog_code)
|
||
return $code
|
||
}
|
||
#======================================
|
||
# DialogResult
|
||
#--------------------------------------
|
||
function DialogResult {
|
||
local dialog_result=/tmp/dialog_result
|
||
test -e "$dialog_result" && cat $dialog_result && rm $dialog_result
|
||
}
|
||
#======================================
|
||
# DialogExitCode
|
||
#--------------------------------------
|
||
function DialogExitCode {
|
||
local dialog_code=/tmp/dialog_code
|
||
test -e "$dialog_code" && cat $dialog_code
|
||
}
|
||
#======================================
|
||
# createCustomHybridPersistent
|
||
#--------------------------------------
|
||
function createCustomHybridPersistent {
|
||
# /.../
|
||
# import the write space for the hybrid according to
|
||
# the information given by kiwi_cowdevice and kiwi_cowsystem
|
||
# ----
|
||
local IFS=$IFS_ORIG
|
||
#======================================
|
||
# check for custom cow location
|
||
#--------------------------------------
|
||
if [ -z "$kiwi_cowdevice" ];then
|
||
return
|
||
fi
|
||
if [ -z "$kiwi_cowsystem" ];then
|
||
return
|
||
fi
|
||
Echo "Using custom cow file: $kiwi_cowdevice:$kiwi_cowsystem"
|
||
#======================================
|
||
# got custom cow location
|
||
#--------------------------------------
|
||
waitForStorageDevice $kiwi_cowdevice
|
||
#======================================
|
||
# mount cow device
|
||
#--------------------------------------
|
||
mkdir /cow
|
||
if ! mount $kiwi_cowdevice /cow;then
|
||
systemException \
|
||
"Failed to mount cow device !" \
|
||
"reboot"
|
||
fi
|
||
#======================================
|
||
# does the cow file exist
|
||
#--------------------------------------
|
||
if [ ! -f /cow/$kiwi_cowsystem ];then
|
||
Echo "Can't find cow file on write partition... deactivated"
|
||
unset kiwi_hybridpersistent
|
||
umount /cow
|
||
rmdir /cow
|
||
return
|
||
fi
|
||
#======================================
|
||
# loop setup cow space
|
||
#--------------------------------------
|
||
kiwi_cowdevice=$(loop_setup /cow/$kiwi_cowsystem)
|
||
if [ ! -e $kiwi_cowdevice ];then
|
||
systemException \
|
||
"Failed to loop setup cow file !" \
|
||
"reboot"
|
||
fi
|
||
#======================================
|
||
# export read-write device name
|
||
#--------------------------------------
|
||
export skipSetupBootPartition=1
|
||
export HYBRID_RW=$kiwi_cowdevice
|
||
}
|
||
#======================================
|
||
# createHybridPersistent
|
||
#--------------------------------------
|
||
function createHybridPersistent {
|
||
# /.../
|
||
# create a new partition to handle the copy-on-write actions
|
||
# by the clicfs live mount. A new partition with a filesystem
|
||
# inside labeled as 'hybrid' is created for this purpose
|
||
# ----
|
||
local IFS=$IFS_ORIG
|
||
local device=$1
|
||
local input=/part.input
|
||
local pID
|
||
rm -f $input
|
||
#======================================
|
||
# check for custom cow location
|
||
#--------------------------------------
|
||
if [ ! -z "$kiwi_cowdevice" ] || [ ! -z "$kiwi_cowsystem" ];then
|
||
return
|
||
fi
|
||
#======================================
|
||
# check persistent write partition
|
||
#--------------------------------------
|
||
local hybrid_fs=$HYBRID_PERSISTENT_FS
|
||
if [ ! -z "$kiwi_hybridpersistent_filesystem" ];then
|
||
hybrid_fs=$kiwi_hybridpersistent_filesystem
|
||
fi
|
||
for pID in 4 3 2 1;do
|
||
local partd=$(ddn $device $pID)
|
||
local label=$(blkid $partd -s LABEL -o value)
|
||
if [ "$label" = "hybrid" ];then
|
||
Echo "Existing persistent hybrid partition found"
|
||
if [ "$hybrid_fs" = "fat" ] || [ "$hybrid_fs" = "exfat" ];then
|
||
if ! setupHybridCowDevice;then
|
||
Echo "Failed to setup hybrid cow device"
|
||
Echo "Persistent writing deactivated"
|
||
unset kiwi_hybridpersistent
|
||
return
|
||
fi
|
||
else
|
||
export HYBRID_RW=$partd
|
||
fi
|
||
export skipSetupBootPartition=1
|
||
return
|
||
fi
|
||
done
|
||
#======================================
|
||
# create persistent write partition
|
||
#--------------------------------------
|
||
Echo "Creating hybrid persistent partition for COW data"
|
||
export imageDiskDevice=$device
|
||
if [ ! -e "$imageDiskDevice" ];then
|
||
Echo "Disk device $device does not exist, most likely not a disk"
|
||
Echo "Persistent writing deactivated"
|
||
unset kiwi_hybridpersistent
|
||
return
|
||
fi
|
||
# Check if device is writable
|
||
# Please note, this checks if the device is a read only device.
|
||
# It does not check if the media given to the device is a read
|
||
# only media. Example: hybrid live iso on readonly CD booted
|
||
# from a CD/DVD RW device. An additional media check might be
|
||
# required in the future
|
||
local ro_device_class=/sys/class/block/$(basename $device)/ro
|
||
if [ -e $ro_device_class ] && [ $(cat $ro_device_class) = 1 ];then
|
||
Echo "Device $device is marked readonly"
|
||
Echo "Persistent writing deactivated"
|
||
unset kiwi_hybridpersistent
|
||
return
|
||
fi
|
||
# Find partition ID we could use to create a new write partition
|
||
for pID in 1 2 3 4;do
|
||
local partd=$(ddn $device $pID)
|
||
if [ ! -e "$partd" ];then
|
||
Echo "Creating write partition at ID: $pID"
|
||
break
|
||
fi
|
||
done
|
||
if [ "$kiwi_firmware" = "bios" ];then
|
||
# we support creation of partitions which are not in ascending order
|
||
# in bios mode. The partition table created via isohybrid starts at
|
||
# the second partition to allow the creation of the write partition
|
||
# as first partition. Reason for this is to support Windows systems
|
||
# with a fat partition as write space which has to be the first
|
||
# partition otherwise Windows can't cope with it.
|
||
#
|
||
# Such a write partition can be created using fdisk, however for
|
||
# EFI capable hybrid ISO images the GPT table is used which fdisk
|
||
# can't handle.
|
||
#
|
||
# Therefore we use fdisk for bios firmware images and parted for
|
||
# efi|uefi firmware images.
|
||
#
|
||
# This also means we don't support fat
|
||
# based persistent write partitions to be created as first partition
|
||
# on efi|uefi ISO hybrid images
|
||
echo -e "n\np\n$pID\n\n\nw\nq" | fdisk $imageDiskDevice
|
||
partitionerWriteStatus=$?
|
||
blockdev --rereadpt $imageDiskDevice
|
||
else
|
||
createPartitionerInput \
|
||
n p:lxrw $pID . . t $pID $HYBRID_PERSISTENT_ID
|
||
callPartitioner $input
|
||
fi
|
||
#======================================
|
||
# check partition device node
|
||
#--------------------------------------
|
||
if [ $partitionerWriteStatus != 0 ];then
|
||
Echo "Partition creation failed for device $device"
|
||
Echo "Persistent writing deactivated"
|
||
unset kiwi_hybridpersistent
|
||
return
|
||
fi
|
||
if ! waitForStorageDevice $(ddn $device $pID);then
|
||
Echo "Partition $pID on $device doesn't appear... fatal !"
|
||
Echo "Persistent writing deactivated"
|
||
unset kiwi_hybridpersistent
|
||
return
|
||
fi
|
||
#======================================
|
||
# create filesystem on write partition
|
||
#--------------------------------------
|
||
local hybrid_device=$(ddn $device $pID)
|
||
local fs_opts
|
||
if [ "$hybrid_fs" = "ext4" ];then
|
||
fs_opts="$HYBRID_EXT4_OPTS"
|
||
fi
|
||
if ! createFilesystem \
|
||
$hybrid_device "$hybrid_fs" "" "" "hybrid" "false" "$fs_opts"
|
||
then
|
||
Echo "Failed to create hybrid persistent filesystem"
|
||
Echo "Persistent writing deactivated"
|
||
unset kiwi_hybridpersistent
|
||
return
|
||
fi
|
||
#======================================
|
||
# export read-write device name
|
||
#--------------------------------------
|
||
if [ "$hybrid_fs" = "fat" ] || [ "$hybrid_fs" = "exfat" ];then
|
||
# The fat filesystem is not really suitable to be used as rootfs
|
||
# for linux. Therefore we create a btrfs based file which we store
|
||
# on the fat filesystem and loop setup it. The size of the file
|
||
# is set to half the size of the fat device
|
||
if ! setupHybridCowDevice $hybrid_device;then
|
||
Echo "Failed to setup hybrid cow device"
|
||
Echo "Persistent writing deactivated"
|
||
unset kiwi_hybridpersistent
|
||
return
|
||
fi
|
||
else
|
||
export HYBRID_RW=$(ddn $device $pID)
|
||
fi
|
||
#======================================
|
||
# skip boot partition setup on overlay
|
||
#--------------------------------------
|
||
export skipSetupBootPartition=1
|
||
}
|
||
#======================================
|
||
# setupHybridCowDevice
|
||
#--------------------------------------
|
||
function setupHybridCowDevice {
|
||
local IFS=$IFS_ORIG
|
||
local hybrid_device=$1
|
||
mkdir -p /cow
|
||
for i in 1 2 3;do
|
||
if [ "$hybrid_fs" = "exfat" ]; then
|
||
mount $hybrid_device /cow ||\
|
||
mount.exfat $hybrid_device /cow && break || sleep 2
|
||
else
|
||
mount -L hybrid /cow && break || sleep 2
|
||
fi
|
||
done
|
||
if ! mountpoint -q /cow; then
|
||
Echo "Failed to mount hybrid persistent filesystem !"
|
||
return 1
|
||
fi
|
||
local hybrid_cow_filename="/cow/${HYBRID_PERSISTENT_FILENAME}"
|
||
if [ ! -z "$kiwi_hybridpersistent_cow_filename" ];then
|
||
hybrid_cow_filename="/cow/${kiwi_hybridpersistent_cow_filename}"
|
||
fi
|
||
if [ ! -e "$hybrid_cow_filename" ];then
|
||
# default cow filesize is half of partition's capacity
|
||
local cowsize="$(($(blockdev --getsize64 $hybrid_device) / 2))"
|
||
# but not for FAT due to the 4G file size limit
|
||
if [ "$hybrid_fs" = "fat" ] && [ "$cowsize" -gt 4294967295 ];then
|
||
cowsize=4294967295
|
||
fi
|
||
if [ ! -z "$kiwi_hybridpersistent_filesize" ];then
|
||
cowsize=$kiwi_hybridpersistent_filesize
|
||
fi
|
||
qemu-img create "$hybrid_cow_filename" "$cowsize"
|
||
if ! createFilesystem \
|
||
"$hybrid_cow_filename" "ext4" "" "" "" "false" "$HYBRID_EXT4_OPTS"
|
||
then
|
||
Echo "Failed to create hybrid persistent cow filesystem"
|
||
return 1
|
||
fi
|
||
fi
|
||
export HYBRID_RW=$(loop_setup "$hybrid_cow_filename")
|
||
if [ ! -e "$HYBRID_RW" ];then
|
||
Echo "Failed to loop setup hybrid cow file !"
|
||
return 1
|
||
fi
|
||
return 0
|
||
}
|
||
#======================================
|
||
# callPartitioner
|
||
#--------------------------------------
|
||
function callPartitioner {
|
||
local IFS=$IFS_ORIG
|
||
local input=$1
|
||
if [ $PARTITIONER = "fdasd" ];then
|
||
Echo "Partition the disk according to real geometry [ fdasd ]"
|
||
echo "w" >> $input
|
||
echo "q" >> $input
|
||
fdasd $imageDiskDevice < $input 1>&2
|
||
export partitionerWriteStatus=$?
|
||
if test $partitionerWriteStatus != 0; then
|
||
systemException "Failed to create partition table" "reboot"
|
||
fi
|
||
udevPending
|
||
blockdev --rereadpt $imageDiskDevice
|
||
else
|
||
# /.../
|
||
# nothing to do for parted here as we write
|
||
# imediately with parted and don't create a
|
||
# command input file as for fdasd but we re-read
|
||
# the disk so that the new table will be used
|
||
# ----
|
||
udevPending
|
||
blockdev --rereadpt $imageDiskDevice
|
||
fi
|
||
}
|
||
#======================================
|
||
# createPartitionerInput
|
||
#--------------------------------------
|
||
function createPartitionerInput {
|
||
local IFS=$IFS_ORIG
|
||
if isDASDDevice; then
|
||
PARTITIONER=fdasd
|
||
fi
|
||
if [ $PARTITIONER = "fdasd" ];then
|
||
createFDasdInput $@
|
||
else
|
||
Echo "Partition the disk according to real geometry [ parted ]"
|
||
partedInit $imageDiskDevice
|
||
partedSectorInit $imageDiskDevice
|
||
createPartedInput $imageDiskDevice $@
|
||
fi
|
||
}
|
||
#======================================
|
||
# createFDasdInput
|
||
#--------------------------------------
|
||
function createFDasdInput {
|
||
local IFS=$IFS_ORIG
|
||
local input=/part.input
|
||
local ignore_once=0
|
||
local ignore=0
|
||
normalizeRepartInput $*
|
||
for cmd in ${pcmds[*]};do
|
||
if [ $ignore = 1 ] && echo $cmd | grep -qE '[dntwq]';then
|
||
ignore=0
|
||
elif [ $ignore = 1 ];then
|
||
continue
|
||
fi
|
||
if [ $ignore_once = "1" ];then
|
||
ignore_once=0
|
||
continue
|
||
fi
|
||
if [ $cmd = "a" ];then
|
||
ignore=1
|
||
continue
|
||
fi
|
||
if [[ $cmd =~ ^p: ]];then
|
||
ignore_once=1
|
||
continue
|
||
fi
|
||
if [ $cmd = "83" ] || [ $cmd = "8e" ];then
|
||
cmd=1
|
||
fi
|
||
if [ $cmd = "82" ];then
|
||
cmd=2
|
||
fi
|
||
if [ $cmd = "." ];then
|
||
echo >> $input
|
||
continue
|
||
fi
|
||
echo $cmd >> $input
|
||
done
|
||
}
|
||
#======================================
|
||
# partedInit
|
||
#--------------------------------------
|
||
function partedInit {
|
||
# /.../
|
||
# initialize current partition table output
|
||
# as well as the number of cylinders and the
|
||
# cyliner size in kB for this disk
|
||
# ----
|
||
local IFS=$IFS_ORIG
|
||
local devname=$1
|
||
local device=$(getDiskDevice $devname)
|
||
IFS=""
|
||
local parted=$(parted -m -s $device unit cyl print | grep -v Warning:)
|
||
local header=$(echo $parted | head -n 3 | tail -n 1)
|
||
local ccount=$(echo $parted | grep ^$device | cut -f 2 -d: | tr -d cyl)
|
||
local cksize=$(echo $header | cut -f4 -d: | cut -f1 -dk)
|
||
local diskhd=$(echo $parted | head -n 3 | tail -n 2 | head -n 1)
|
||
local plabel=$(echo $diskhd | cut -f6 -d:)
|
||
if [[ $plabel =~ gpt ]];then
|
||
plabel=gpt
|
||
fi
|
||
export partedTableType=$plabel
|
||
export partedOutput=$parted
|
||
export partedCylCount=$ccount
|
||
export partedCylKSize=$cksize
|
||
}
|
||
#======================================
|
||
# partedWrite
|
||
#--------------------------------------
|
||
function partedWrite {
|
||
# /.../
|
||
# call parted with current command queue.
|
||
# This will immediately change the partition table
|
||
# ----
|
||
local IFS=$IFS_ORIG
|
||
local device=$1
|
||
local cmds=$2
|
||
local opts
|
||
if [ $PARTED_HAVE_ALIGN -eq 1 ];then
|
||
opts="-a cyl"
|
||
fi
|
||
parted $opts -m -s $device unit cyl $cmds
|
||
export partitionerWriteStatus=$?
|
||
if [ $partitionerWriteStatus != 0 ];then
|
||
if [ ! -z "$kiwi_hybridpersistent" ];then
|
||
# /.../
|
||
# in case of a iso hybrid table don't stop with a fatal reboot
|
||
# exception on error. In this case we want to proceed with the
|
||
# boot process but deactivate the persistent write feature
|
||
# ----
|
||
return 1
|
||
fi
|
||
systemException "Failed to create partition table" "reboot"
|
||
fi
|
||
partedInit $device
|
||
}
|
||
#======================================
|
||
# partedSectorInit
|
||
#--------------------------------------
|
||
function partedSectorInit {
|
||
# /.../
|
||
# return aligned start/end sectors of current table.
|
||
# ----
|
||
local IFS=$IFS_ORIG
|
||
local disk=$1
|
||
local s_start
|
||
local s_stopp
|
||
unset startSectors
|
||
unset endSectors
|
||
local align=$((kiwi_align / kiwi_sectorsize))
|
||
for i in $(
|
||
parted -m -s $disk unit s print |\
|
||
grep -E ^[1-9]+:| cut -f2-3 -d: | tr -d s
|
||
);do
|
||
s_start=$(echo $i | cut -f1 -d:)
|
||
s_stopp=$(echo $i | cut -f2 -d:)
|
||
if [ -z "$startSectors" ];then
|
||
startSectors=${s_start}s
|
||
else
|
||
startSectors=${startSectors}:${s_start}s
|
||
fi
|
||
if [ -z "$endSectors" ];then
|
||
endSectors=$((s_stopp/align*align+align))s
|
||
else
|
||
endSectors=$endSectors:$((s_stopp/align*align+align))s
|
||
fi
|
||
done
|
||
# /.../
|
||
# in case of an empty disk we use the default start sector
|
||
# ----
|
||
if [ -z "$startSectors" ];then
|
||
startSectors=${kiwi_startsector}s
|
||
fi
|
||
}
|
||
#======================================
|
||
# partedEndCylinder
|
||
#--------------------------------------
|
||
function partedEndCylinder {
|
||
# /.../
|
||
# return end cylinder of given partition, next
|
||
# partition must start at return value plus 1
|
||
# ----
|
||
local IFS=$IFS_ORIG
|
||
local part=$(($1 + 3))
|
||
IFS=""
|
||
local header=$(echo $partedOutput | head -n $part | tail -n 1)
|
||
local ccount=$(echo $header | cut -f3 -d: | tr -d cyl)
|
||
echo $ccount
|
||
}
|
||
#======================================
|
||
# partedMBToCylinder
|
||
#--------------------------------------
|
||
function partedMBToCylinder {
|
||
# /.../
|
||
# convert size given in MB to cylinder count
|
||
# ----
|
||
local IFS=$IFS_ORIG
|
||
local sizeBytes=$(($1 * 1048576))
|
||
# bc truncates to zero decimal places, which results in a partition that
|
||
# is slightly smaller than the requested size. Add one cylinder to compensate.
|
||
local cylreq=$(echo "scale=0; $sizeBytes / ($partedCylKSize * 1000) + 1" | bc)
|
||
echo $cylreq
|
||
}
|
||
#======================================
|
||
# createPartedInput
|
||
#--------------------------------------
|
||
function createPartedInput {
|
||
# /.../
|
||
# evaluate partition instructions and turn them
|
||
# into a parted command line queue. As soon as the
|
||
# geometry data would be changed according to the
|
||
# last partedInit() call the command queue is processed
|
||
# and the partedInit() will be called afterwards
|
||
# ----
|
||
local IFS=$IFS_ORIG
|
||
local disk=$1
|
||
shift
|
||
local index=0
|
||
local partid
|
||
local partnm
|
||
local pstart
|
||
local pstopp
|
||
local value
|
||
local cmdq
|
||
#======================================
|
||
# normalize commands
|
||
#--------------------------------------
|
||
normalizeRepartInput $*
|
||
for cmd in ${pcmds[*]};do
|
||
case $cmd in
|
||
#======================================
|
||
# delete partition
|
||
#--------------------------------------
|
||
"d")
|
||
partid=${pcmds[$index + 1]}
|
||
partid=$(($partid / 1))
|
||
cmdq="$cmdq rm $partid"
|
||
partedWrite "$disk" "$cmdq"
|
||
cmdq=""
|
||
;;
|
||
#======================================
|
||
# create new partition
|
||
#--------------------------------------
|
||
"n")
|
||
partnm=${pcmds[$index + 1]}
|
||
partid=${pcmds[$index + 2]}
|
||
partid=$(($partid / 1))
|
||
pstart=${pcmds[$index + 3]}
|
||
if [ ! "$partedTableType" = "gpt" ];then
|
||
partnm=primary
|
||
else
|
||
partnm=$(echo $partnm | cut -f2 -d:)
|
||
fi
|
||
if [ "$pstart" = "1" ];then
|
||
pstart=$(echo $startSectors | cut -f $partid -d:)
|
||
fi
|
||
if [ $pstart = "." ];then
|
||
# start is next sector according to previous partition
|
||
pstart=$(($partid - 1))
|
||
if [ $pstart -gt 0 ];then
|
||
pstart=$(echo $endSectors | cut -f $pstart -d:)
|
||
else
|
||
pstart=$(echo $startSectors | cut -f $partid -d:)
|
||
fi
|
||
fi
|
||
pstopp=${pcmds[$index + 4]}
|
||
if [ $pstopp = "." ];then
|
||
# use rest of the disk for partition end
|
||
pstopp=$partedCylCount
|
||
elif echo $pstopp | grep -qi M;then
|
||
# calculate stopp cylinder from size
|
||
pstopp=$(($partid - 1))
|
||
if [ $pstopp -gt 0 ];then
|
||
pstopp=$(partedEndCylinder $pstopp)
|
||
fi
|
||
value=$(echo ${pcmds[$index + 4]} | cut -f1 -dM | tr -d +)
|
||
value=$(partedMBToCylinder $value)
|
||
pstopp=$((1 + $pstopp + $value))
|
||
if [ $pstopp -gt $partedCylCount ];then
|
||
# given size is out of bounds, reduce to end of disk
|
||
pstopp=$partedCylCount
|
||
fi
|
||
fi
|
||
cmdq="$cmdq mkpart $partnm $pstart $pstopp"
|
||
partedWrite "$disk" "$cmdq"
|
||
partedSectorInit $imageDiskDevice
|
||
cmdq=""
|
||
;;
|
||
#======================================
|
||
# change partition ID
|
||
#--------------------------------------
|
||
"t")
|
||
ptypex=${pcmds[$index + 2]}
|
||
partid=${pcmds[$index + 1]}
|
||
flagok=1
|
||
if [ "$ptypex" = "82" ];then
|
||
if [[ $kiwi_initrdname =~ boot-suse ]];then
|
||
# /.../
|
||
# suse parted is not able to set swap flag. I consider
|
||
# this as a bug in the suse parted tool. In order to
|
||
# proceed here kiwi uses suse parted 'type' command
|
||
# extension.
|
||
#
|
||
cmdq="$cmdq set $partid type 0x$ptypex"
|
||
elif [[ $kiwi_initrdname =~ boot-rhel ]];then
|
||
# /.../
|
||
# parted on RHEL is not able to set swap flag. I don't
|
||
# have a good solution for this thus we skip the flag
|
||
# setup in this case
|
||
#
|
||
flagok=0
|
||
else
|
||
cmdq="$cmdq set $partid swap on"
|
||
fi
|
||
elif [ "$ptypex" = "fd" ];then
|
||
cmdq="$cmdq set $partid raid on"
|
||
elif [ "$ptypex" = "8e" ];then
|
||
cmdq="$cmdq set $partid lvm on"
|
||
elif [ "$ptypex" = "83" ];then
|
||
# default partition type set by parted is linux(83)
|
||
flagok=0
|
||
else
|
||
# be careful, this is a suse parted extension
|
||
cmdq="$cmdq set $partid type 0x$ptypex"
|
||
fi
|
||
if [ ! "$partedTableType" = "gpt" ] && [ $flagok = 1 ];then
|
||
partedWrite "$disk" "$cmdq"
|
||
fi
|
||
cmdq=""
|
||
;;
|
||
esac
|
||
index=$(($index + 1))
|
||
done
|
||
}
|
||
#======================================
|
||
# normalizeRepartInput
|
||
#--------------------------------------
|
||
function normalizeRepartInput {
|
||
local IFS=$IFS_ORIG
|
||
local pcmds_fix
|
||
local index=0
|
||
local index_fix=0
|
||
local partid
|
||
local cmd
|
||
#======================================
|
||
# create list of commands
|
||
#--------------------------------------
|
||
unset pcmds
|
||
for cmd in $*;do
|
||
pcmds[$index]=$cmd
|
||
index=$(($index + 1))
|
||
done
|
||
index=0
|
||
#======================================
|
||
# fix list of commands
|
||
#--------------------------------------
|
||
while [ ! -z "${pcmds[$index]}" ];do
|
||
cmd=${pcmds[$index]}
|
||
pcmds_fix[$index_fix]=$cmd
|
||
case $cmd in
|
||
"d")
|
||
partid=${pcmds[$index + 1]}
|
||
if ! echo $partid | grep -q -E "^[0-9]+$";then
|
||
# make sure there is a ID set for the deletion
|
||
index_fix=$(($index_fix + 1))
|
||
pcmds_fix[$index_fix]=1
|
||
fi
|
||
;;
|
||
"n")
|
||
partid=${pcmds[$index + 2]}
|
||
if [ ! "$PARTITIONER" = "fdasd" ];then
|
||
if ! echo $partid | grep -q -E "^[0-9]+$";then
|
||
# make sure there is a ID set for the creation
|
||
index_fix=$(($index_fix + 1))
|
||
pcmds_fix[$index_fix]=${pcmds[$index + 1]}
|
||
index_fix=$(($index_fix + 1))
|
||
pcmds_fix[$index_fix]=4
|
||
index=$(($index + 1))
|
||
fi
|
||
fi
|
||
;;
|
||
"t")
|
||
partid=${pcmds[$index + 1]}
|
||
if ! echo $partid | grep -q -E "^[0-9]+$";then
|
||
# make sure there is a ID set for the type
|
||
index_fix=$(($index_fix + 1))
|
||
pcmds_fix[$index_fix]=1
|
||
fi
|
||
;;
|
||
esac
|
||
index=$(($index + 1))
|
||
index_fix=$(($index_fix + 1))
|
||
done
|
||
#======================================
|
||
# use fixed list and print log info
|
||
#--------------------------------------
|
||
unset pcmds
|
||
pcmds=(${pcmds_fix[*]})
|
||
unset pcmds_fix
|
||
echo "Normalized Repartition input: ${pcmds[*]}" 1>&2
|
||
}
|
||
#======================================
|
||
# reloadKernel
|
||
#--------------------------------------
|
||
function reloadKernel {
|
||
# /.../
|
||
# reload the given kernel and initrd. This function
|
||
# checks USB stick devices for a kernel and initrd
|
||
# and shows them in a dialog window. The selected kernel
|
||
# and initrd is loaded via kexec.
|
||
# ----
|
||
local IFS=$IFS_ORIG
|
||
local prefix=/mnt
|
||
#======================================
|
||
# check proc/cmdline
|
||
#--------------------------------------
|
||
ldconfig
|
||
mountSystemFilesystems &>/dev/null
|
||
if ! cat /proc/cmdline | grep -qi "hotfix=1";then
|
||
umountSystemFilesystems
|
||
return
|
||
fi
|
||
#======================================
|
||
# check for kexec
|
||
#--------------------------------------
|
||
if [ ! -x /sbin/kexec ];then
|
||
systemException "Can't find kexec" "reboot"
|
||
fi
|
||
#======================================
|
||
# start udev
|
||
#--------------------------------------
|
||
touch /etc/modules.conf
|
||
touch /lib/modules/*/modules.dep
|
||
udevStart
|
||
errorLogStart
|
||
probeDevices
|
||
#======================================
|
||
# search hotfix stick
|
||
#--------------------------------------
|
||
USBStickDevice kexec
|
||
if [ $stickFound = 0 ];then
|
||
systemException "No hotfix USB stick found" "reboot"
|
||
fi
|
||
#======================================
|
||
# mount stick
|
||
#--------------------------------------
|
||
if ! mount -o ro $stickDevice $prefix;then
|
||
systemException "Failed to mount hotfix stick" "reboot"
|
||
fi
|
||
#======================================
|
||
# load kernel
|
||
#--------------------------------------
|
||
kexec -l $prefix/linux.kexec --initrd=$prefix/initrd.kexec \
|
||
--append="$(cat /proc/cmdline | sed -e s"@hotfix=1@@")"
|
||
if [ ! $? = 0 ];then
|
||
systemException "Failed to load hotfix kernel" "reboot"
|
||
fi
|
||
#======================================
|
||
# go for gold
|
||
#--------------------------------------
|
||
exec kexec -e
|
||
}
|
||
#======================================
|
||
# checkFilesystem
|
||
#--------------------------------------
|
||
function checkFilesystem {
|
||
local device=$1
|
||
local fstype=$(probeFileSystem $device)
|
||
case $fstype in
|
||
ext2|ext3|ext4)
|
||
e2fsck -p -f $device
|
||
;;
|
||
btrfs)
|
||
btrfsck $device
|
||
;;
|
||
xfs)
|
||
xfs_repair -n $device
|
||
;;
|
||
*)
|
||
# don't know how to check this filesystem
|
||
Echo "Don't know how to check ${fstype}... skip it"
|
||
;;
|
||
esac
|
||
}
|
||
#======================================
|
||
# resizeFilesystem
|
||
#--------------------------------------
|
||
function resizeFilesystem {
|
||
local IFS=$IFS_ORIG
|
||
local deviceResize=$1
|
||
local callme=$2
|
||
local ramdisk=0
|
||
local resize_fs
|
||
local check
|
||
local mpoint=/fs-resize
|
||
udevPending
|
||
local fstype=$(probeFileSystem $deviceResize)
|
||
mkdir -p $mpoint
|
||
if echo $deviceResize | grep -qi "/dev/ram";then
|
||
ramdisk=1
|
||
fi
|
||
case $fstype in
|
||
ext2|ext3|ext4)
|
||
resize_fs="resize2fs -f -p $deviceResize"
|
||
if [ $ramdisk -eq 1 ];then
|
||
resize_fs="resize2fs -f $deviceResize"
|
||
fi
|
||
;;
|
||
btrfs)
|
||
resize_fs="mount $deviceResize $mpoint &&"
|
||
if lookup btrfs &>/dev/null;then
|
||
resize_fs="$resize_fs btrfs filesystem resize max $mpoint"
|
||
resize_fs="$resize_fs;umount $mpoint"
|
||
else
|
||
resize_fs="$resize_fs btrfsctl -r max $mpoint;umount $mpoint"
|
||
fi
|
||
;;
|
||
xfs)
|
||
resize_fs="mount $deviceResize $mpoint &&"
|
||
resize_fs="$resize_fs xfs_growfs $mpoint;umount $mpoint"
|
||
;;
|
||
*)
|
||
# don't know how to resize this filesystem
|
||
Echo "Don't know how to resize ${fstype}... skip it"
|
||
return
|
||
;;
|
||
esac
|
||
if [ -z "$callme" ];then
|
||
if [ $ramdisk -eq 0 ]; then
|
||
Echo "Checking $fstype filesystem on ${deviceResize}..."
|
||
checkFilesystem $deviceResize
|
||
fi
|
||
Echo "Resizing $fstype filesystem on ${deviceResize}..."
|
||
eval $resize_fs
|
||
if [ ! $? = 0 ];then
|
||
systemException \
|
||
"Failed to resize/check filesystem" \
|
||
"reboot"
|
||
fi
|
||
else
|
||
echo $resize_fs
|
||
fi
|
||
}
|
||
#======================================
|
||
# resetMountCounter
|
||
#--------------------------------------
|
||
function resetMountCounter {
|
||
local IFS=$IFS_ORIG
|
||
local fstype
|
||
local command
|
||
for device in \
|
||
$imageRootDevice $imageBootDevice \
|
||
$imageRecoveryDevice
|
||
do
|
||
if [ ! -e $device ];then
|
||
continue
|
||
fi
|
||
fstype=$(probeFileSystem $device)
|
||
case $fstype in
|
||
ext2|ext3|ext4)
|
||
command="tune2fs -c -1 -i 0"
|
||
;;
|
||
*)
|
||
# nothing to do here...
|
||
continue
|
||
;;
|
||
esac
|
||
eval $command $device 1>&2
|
||
done
|
||
}
|
||
#======================================
|
||
# createFilesystem
|
||
#--------------------------------------
|
||
function createFilesystem {
|
||
local IFS=$IFS_ORIG
|
||
local deviceCreate=$1
|
||
local filesystem=$2
|
||
local blocks=$3
|
||
local uuid=$4
|
||
local label=$5
|
||
local exception_handling=$6
|
||
local opts=$7
|
||
if [ -z "$exception_handling" ];then
|
||
exception_handling="true"
|
||
else
|
||
exception_handling="false"
|
||
fi
|
||
if [[ "$filesystem" =~ ext ]];then
|
||
opts="$opts -F"
|
||
if [ ! -z "$uuid" ];then
|
||
opts="$opts -U $uuid"
|
||
fi
|
||
if [ ! -z "$label" ];then
|
||
opts="$opts -L $label"
|
||
fi
|
||
elif [ "$filesystem" = "btrfs" ];then
|
||
opts="$opts -f"
|
||
if [ ! -z "$uuid" ];then
|
||
opts="$opts -U $uuid"
|
||
fi
|
||
if [ ! -z "$label" ];then
|
||
opts="$opts -L $label"
|
||
fi
|
||
if [ ! -z "$blocks" ];then
|
||
local bytes=$((blocks * 4096))
|
||
opts="$opts -b $bytes"
|
||
fi
|
||
elif [ "$filesystem" = "fat" ];then
|
||
if [ ! -z "$label" ];then
|
||
opts="$opts -n $label"
|
||
fi
|
||
elif [ "$filesystem" = "xfs" ];then
|
||
if [ ! -z "$label" ];then
|
||
opts="$opts -L $label"
|
||
fi
|
||
elif [ "$filesystem" = "ntfs" ];then
|
||
if [ ! -z "$label" ];then
|
||
opts="$opts -L $label"
|
||
fi
|
||
elif [ "$filesystem" = "exfat" ];then
|
||
if [ ! -z "$label" ];then
|
||
opts="$opts -n $label"
|
||
fi
|
||
fi
|
||
if [ "$filesystem" = "ext2" ];then
|
||
mkfs.ext2 $opts "$deviceCreate" $blocks 1>&2
|
||
elif [ "$filesystem" = "ext3" ];then
|
||
mkfs.ext3 $opts "$deviceCreate" $blocks 1>&2
|
||
elif [ "$filesystem" = "ext4" ];then
|
||
mkfs.ext4 $opts "$deviceCreate" $blocks 1>&2
|
||
elif [ "$filesystem" = "btrfs" ];then
|
||
# delete potentially existing btrfs on the device because even
|
||
# with the force option enabled mkfs.btrfs refuses to create a
|
||
# filesystem if the existing metadata contains the same UUID
|
||
dd if=/dev/zero of="$deviceCreate" bs=1M count=1 conv=notrunc
|
||
mkfs.btrfs $opts "$deviceCreate"
|
||
elif [ "$filesystem" = "xfs" ];then
|
||
mkfs.xfs $opts -f "$deviceCreate"
|
||
if [ ! -z "$uuid" ];then
|
||
xfs_admin -U $uuid "$deviceCreate"
|
||
fi
|
||
elif [ "$filesystem" = "fat" ];then
|
||
mkfs.fat $opts "$deviceCreate" $blocks 1>&2
|
||
elif [ "$filesystem" = "ntfs" ];then
|
||
mkfs.ntfs $opts "$deviceCreate" $blocks 1>&2
|
||
elif [ "$filesystem" = "exfat" ];then
|
||
mkfs.exfat $opts "$deviceCreate" 1>&2
|
||
else
|
||
# use ext3 by default
|
||
mkfs.ext3 $opts "$deviceCreate" $blocks 1>&2
|
||
fi
|
||
if [ $exception_handling = "false" ];then
|
||
return $?
|
||
fi
|
||
if [ ! $? = 0 ];then
|
||
systemException \
|
||
"Failed to create filesystem" \
|
||
"reboot"
|
||
fi
|
||
}
|
||
#======================================
|
||
# restoreBtrfsSubVolumes
|
||
#--------------------------------------
|
||
function restoreBtrfsSubVolumes {
|
||
local IFS=$IFS_ORIG
|
||
local root=$1
|
||
local top=@
|
||
btrfs subvolume create $root/@ || return
|
||
if [ "$kiwi_btrfs_root_is_snapshot" = "true" ];then
|
||
btrfs subvolume create $root/.snapshots
|
||
btrfs subvolume create $root/.snapshots/1
|
||
btrfs subvolume snapshot $root/@ $root/.snapshots/1/snapshot
|
||
top=.snapshots/1/snapshot
|
||
fi
|
||
local rootid=$(btrfs subvolume list $root | grep $top | cut -f2 -d ' ')
|
||
btrfs subvolume set-default $rootid $root || return
|
||
local mount_point
|
||
local volume_toplevel
|
||
for i in $(readVolumeSetup "/.profile");do
|
||
mount_point=$(getVolumeMountPoint $i)
|
||
volume_toplevel="$root/@/$(dirname $mount_point)"
|
||
if [ ! -d $volume_toplevel ];then
|
||
mkdir -p $volume_toplevel
|
||
fi
|
||
btrfs subvolume create $root/@/$mount_point || return
|
||
done
|
||
umount $root && mount $imageRootDevice $root
|
||
if [ "$kiwi_btrfs_root_is_snapshot" = "true" ];then
|
||
mountBtrfsSubVolumes $imageRootDevice $root
|
||
fi
|
||
}
|
||
#======================================
|
||
# restoreLVMMetadata
|
||
#--------------------------------------
|
||
function restoreLVMPhysicalVolumes {
|
||
# /.../
|
||
# restore the pysical volumes by the given restore file
|
||
# created from vgcfgbackup. It's important to create them
|
||
# with the same uuid's compared to the restore file
|
||
# ----
|
||
local IFS=$IFS_ORIG
|
||
local restorefile=$1
|
||
cat $restorefile | grep -A2 -E 'pv[0-9] {' | while read line;do
|
||
if [ -z "$uuid" ];then
|
||
uuid=$(echo $line | grep 'id =' |\
|
||
cut -f2 -d= | tr -d \")
|
||
fi
|
||
if [ -z "$pdev" ];then
|
||
pdev=$(echo $line|grep 'device =' |\
|
||
cut -f2 -d\" | cut -f1 -d\")
|
||
fi
|
||
if [ ! -z "$pdev" ];then
|
||
pvcreate -u $uuid $pdev
|
||
unset uuid
|
||
unset pdev
|
||
fi
|
||
done
|
||
}
|
||
#======================================
|
||
# pxeCheckServer
|
||
#--------------------------------------
|
||
function pxeCheckServer {
|
||
# /.../
|
||
# check the kernel commandline parameter kiwiserver.
|
||
# If it exists its contents will be used as
|
||
# server address stored in the SERVER variabe
|
||
# ----
|
||
local IFS=$IFS_ORIG
|
||
if [ ! -z $kiwiserver ];then
|
||
Echo "Found server in kernel cmdline"
|
||
SERVER=$kiwiserver
|
||
fi
|
||
if [ ! -z $kiwiservertype ]; then
|
||
Echo "Found server type in kernel cmdline"
|
||
SERVERTYPE=$kiwiservertype
|
||
else
|
||
SERVERTYPE=tftp
|
||
fi
|
||
}
|
||
#======================================
|
||
# pxeSetupDownloadServer
|
||
#--------------------------------------
|
||
function pxeSetupDownloadServer {
|
||
# /.../
|
||
# the pxe image system requires a server which stores
|
||
# the image files. This function setup the SERVER variable
|
||
# pointing to that server using the following heuristic:
|
||
# ----
|
||
# 1) check for $kiwiserver from cmdline
|
||
# 2) try tftp.$DOMAIN whereas $DOMAIN is from dhcpcd-info
|
||
# 3) try address of DHCP server if no servertype or tftp is used
|
||
# 4) fail if no location was found
|
||
# ----
|
||
local IFS=$IFS_ORIG
|
||
pxeCheckServer
|
||
if [ -z "$SERVER" ];then
|
||
if [ ! -z "$ip" ];then
|
||
Echo "Found PXE download server IP in kernel cmdline"
|
||
SERVER=$(echo $ip | awk -F ':' '{ print $2 }')
|
||
else
|
||
Echo "No PXE download server configured, trying: tftp.$DOMAIN"
|
||
SERVER=tftp.$DOMAIN
|
||
fi
|
||
fi
|
||
Echo "Checking connectivity of PXE download server: $SERVER"
|
||
if ! ping -c 1 -w 30 $SERVER >/dev/null 2>&1;then
|
||
Echo "PXE download server: $SERVER not found"
|
||
if [ -z "$SERVERTYPE" ] || [ "$SERVERTYPE" = "tftp" ]; then
|
||
if [ ! -z "$DHCPSIADDR" ];then
|
||
Echo "Using: $DHCPSIADDR from DHCP info"
|
||
SERVER=$DHCPSIADDR
|
||
elif [ ! -z "$DHCPSID" ];then
|
||
Echo "Using: $DHCPSID from DHCP info"
|
||
SERVER=$DHCPSID
|
||
elif [ ! -z "$SERVERID" ];then
|
||
Echo "Using: $SERVERID from DHCP info"
|
||
SERVER=$SERVERID
|
||
else
|
||
systemException \
|
||
"Can't find responding PXE download server... fatal !" \
|
||
"reboot"
|
||
fi
|
||
fi
|
||
fi
|
||
}
|
||
#======================================
|
||
# pxeSetupSystemAliasName
|
||
#--------------------------------------
|
||
function pxeSetupSystemAliasName {
|
||
# /.../
|
||
# Ask for an alias name if NAME from config.<MAC>
|
||
# contains a number. If the number is -1 the system will
|
||
# ask for ever for this name otherwhise the number sets
|
||
# a timeout how long to wait for input of this data
|
||
# ----
|
||
local IFS=$IFS_ORIG
|
||
if test $NAME -ne 0;then
|
||
if test $NAME -eq -1;then
|
||
Echo -n "Enter Alias Name for this system: " && \
|
||
read SYSALIAS
|
||
else
|
||
Echo -n "Enter Alias Name [timeout in $NAME sec]: " && \
|
||
read -t $NAME SYSALIAS
|
||
fi
|
||
fi
|
||
}
|
||
#======================================
|
||
# pxeSetupSystemHWInfoFile
|
||
#--------------------------------------
|
||
function pxeSetupSystemHWInfoFile {
|
||
# /.../
|
||
# calls hwinfo and stores the information into a file
|
||
# suffixed by the hardware address of the network card
|
||
# NOTE: it's required to have the dhcp info file sourced
|
||
# before this function is called
|
||
# ----
|
||
local IFS=$IFS_ORIG
|
||
hwinfo --all --log=hwinfo.$DHCPCHADDR >/dev/null
|
||
}
|
||
#======================================
|
||
# pxeSetupSystemHWTypeFile
|
||
#--------------------------------------
|
||
function pxeSetupSystemHWTypeFile {
|
||
# /.../
|
||
# collects information about the alias name the
|
||
# architecture and more and stores that into a
|
||
# file suffixed by the hardware address of the
|
||
# network card.
|
||
# ----
|
||
local IFS=$IFS_ORIG
|
||
echo "NCNAME=$SYSALIAS" >> hwtype.$DHCPCHADDR
|
||
echo "CRNAME=$SYSALIAS" >> hwtype.$DHCPCHADDR
|
||
echo "IPADDR=$IPADDR" >> hwtype.$DHCPCHADDR
|
||
echo "ARCHITECTURE=$ARCH" >> hwtype.$DHCPCHADDR
|
||
}
|
||
#======================================
|
||
# pxeSizeToMB
|
||
#--------------------------------------
|
||
function pxeSizeToMB {
|
||
local IFS=$IFS_ORIG
|
||
local size=$1
|
||
if [ "$size" = "x" ];then
|
||
echo . ; return
|
||
fi
|
||
local lastc=$(echo $size | sed -e 's@\(^.*\)\(.$\)@\2@')
|
||
local value=$(echo $size | sed -e 's@\(^.*\)\(.$\)@\1@')
|
||
if [ "$lastc" = "m" ] || [ "$lastc" = "M" ];then
|
||
size=$value
|
||
elif [ "$lastc" = "g" ] || [ "$lastc" = "G" ];then
|
||
size=$(($value * 1024))
|
||
fi
|
||
echo +"$size"M
|
||
}
|
||
#======================================
|
||
# pxePartitionInput
|
||
#--------------------------------------
|
||
function pxePartitionInput {
|
||
local IFS=$IFS_ORIG
|
||
if [ $PARTITIONER = "fdasd" ];then
|
||
pxePartitionInputFDASD
|
||
else
|
||
pxePartitionInputGeneric
|
||
fi
|
||
}
|
||
#======================================
|
||
# pxeRaidPartitionInput
|
||
#--------------------------------------
|
||
function pxeRaidPartitionInput {
|
||
local IFS=$IFS_ORIG
|
||
if [ $PARTITIONER = "fdasd" ];then
|
||
pxeRaidPartitionInputFDASD
|
||
else
|
||
pxeRaidPartitionInputGeneric
|
||
fi
|
||
}
|
||
#======================================
|
||
# pxePartitionInputFDASD
|
||
#--------------------------------------
|
||
function pxePartitionInputFDASD {
|
||
local IFS=$IFS_ORIG
|
||
local field=0
|
||
local count=0
|
||
local IFS=","
|
||
for i in $PART;do
|
||
field=0
|
||
count=$((count + 1))
|
||
IFS=";" ; for n in $i;do
|
||
case $field in
|
||
0) partSize=$n ; field=1 ;;
|
||
1) partID=$n ; field=2 ;;
|
||
2) partMount=$n;
|
||
esac
|
||
done
|
||
partSize=$(pxeSizeToMB $partSize)
|
||
if [ "$partID" = '82' ] || [ "$partID" = 'S' ];then
|
||
partID=2
|
||
elif [ "$partID" = '83' ] || [ "$partID" = 'L' ];then
|
||
partID=1
|
||
elif [ "$partID" = '8e' ] || [ "$partID" = 'V' ];then
|
||
partID=4
|
||
else
|
||
partID=1
|
||
fi
|
||
echo -n "n . $partSize "
|
||
if [ $partID = "2" ] || [ $partID = "4" ];then
|
||
echo -n "t $count $partID "
|
||
fi
|
||
done
|
||
echo "w"
|
||
}
|
||
#======================================
|
||
# pxeRaidPartitionInputFDASD
|
||
#--------------------------------------
|
||
function pxeRaidPartitionInputFDASD {
|
||
pxePartitionInputFDASD
|
||
}
|
||
#======================================
|
||
# pxePartitionInputGeneric
|
||
#--------------------------------------
|
||
function pxePartitionInputGeneric {
|
||
local IFS=","
|
||
local field=0
|
||
local count=0
|
||
local pname
|
||
for i in $PART;do
|
||
field=0
|
||
count=$((count + 1))
|
||
IFS=";" ; for n in $i;do
|
||
case $field in
|
||
0) partSize=$n ; field=1 ;;
|
||
1) partID=$n ; field=2 ;;
|
||
2) partMount=$n;
|
||
esac
|
||
done
|
||
partSize=$(pxeSizeToMB $partSize)
|
||
pname=lxrw
|
||
if [ $partID = "S" ] || [ $partID = "82" ];then
|
||
partID=82
|
||
pname=lxswap
|
||
fi
|
||
if [ $partID = "L" ] || [ $partID = "83" ];then
|
||
partID=83
|
||
if [ "$partMount" = "/boot" ];then
|
||
pname=lxboot
|
||
else
|
||
pname=lxroot
|
||
fi
|
||
fi
|
||
if [ $partID = "V" ] || [ $partID = "8e" ];then
|
||
partID=8e
|
||
pname=lxlvm
|
||
fi
|
||
if [ $partID = "fd" ] || [ ! -z "$RAID" ];then
|
||
partID=fd
|
||
pname=lxroot
|
||
fi
|
||
if [ $count -eq 1 ];then
|
||
echo -n "n p:$pname $count 1 $partSize "
|
||
if [ $partID = "82" ] || \
|
||
[ $partID = "8e" ] || \
|
||
[ $partID = "41" ] || \
|
||
[ $partID = "fd" ]
|
||
then
|
||
echo -n "t $count $partID "
|
||
fi
|
||
else
|
||
echo -n "n p:$pname $count . $partSize "
|
||
if [ $partID = "82" ] || \
|
||
[ $partID = "8e" ] || \
|
||
[ $partID = "41" ] || \
|
||
[ $partID = "fd" ]
|
||
then
|
||
echo -n "t $count $partID "
|
||
fi
|
||
fi
|
||
done
|
||
echo "w q"
|
||
}
|
||
#======================================
|
||
# pxeRaidPartitionInputGeneric
|
||
#--------------------------------------
|
||
function pxeRaidPartitionInputGeneric {
|
||
pxePartitionInputGeneric
|
||
}
|
||
#======================================
|
||
# pxeRaidCreate
|
||
#--------------------------------------
|
||
function pxeRaidCreate {
|
||
local IFS=","
|
||
local count=0
|
||
local mdcount=0
|
||
local raidFirst
|
||
local raidSecond
|
||
local conf=/mdadm.conf
|
||
echo -n > $conf
|
||
for i in $PART;do
|
||
count=$((count + 1))
|
||
raidFirst=$(ddn $raidDiskFirst $count)
|
||
raidSecond=$(ddn $raidDiskSecond $count)
|
||
if ! waitForStorageDevice $raidFirst;then
|
||
return
|
||
fi
|
||
if ! waitForStorageDevice $raidSecond;then
|
||
return
|
||
fi
|
||
mdadm --zero-superblock $raidFirst
|
||
mdadm --zero-superblock $raidSecond
|
||
mdadm --create --metadata=0.9 --run /dev/md$mdcount \
|
||
--level=$raidLevel --raid-disks=2 $raidFirst $raidSecond
|
||
if [ ! $? = 0 ];then
|
||
systemException \
|
||
"Failed to create raid array... fatal !" \
|
||
"reboot"
|
||
fi
|
||
mdadm -Db /dev/md$mdcount >> $conf
|
||
mdcount=$((mdcount + 1))
|
||
done
|
||
}
|
||
#======================================
|
||
# pxeRaidAssemble
|
||
#--------------------------------------
|
||
function pxeRaidAssemble {
|
||
local IFS=";"
|
||
local count=0
|
||
local mdcount=0
|
||
local field=0
|
||
local devices
|
||
local raidFirst
|
||
local raidSecond
|
||
local conf=/mdadm.conf
|
||
echo -n > $conf
|
||
for n in $RAID;do
|
||
case $field in
|
||
0) raidLevel=$n ; field=1 ;;
|
||
1) raidDiskFirst=$n ; field=2 ;;
|
||
2) raidDiskSecond=$n; field=3
|
||
esac
|
||
done
|
||
IFS=","
|
||
for i in $PART;do
|
||
count=$((count + 1))
|
||
raidFirst=$(ddn $raidDiskFirst $count)
|
||
raidSecond=$(ddn $raidDiskSecond $count)
|
||
if ! waitForStorageDevice $raidFirst;then
|
||
echo "Warning: device $raidFirst did not appear"
|
||
else
|
||
devices=$raidFirst
|
||
fi
|
||
if ! waitForStorageDevice $raidSecond;then
|
||
echo "Warning: device $raidSecond did not appear"
|
||
else
|
||
devices="$devices $raidSecond"
|
||
fi
|
||
IFS=$IFS_ORIG
|
||
mdadm --assemble --run /dev/md$mdcount $devices
|
||
if ! waitForStorageDevice /dev/md$mdcount; then
|
||
# start any array that has been partially assembled
|
||
mdadm -IRs
|
||
if ! waitForStorageDevice /dev/md$mdcount; then
|
||
systemException \
|
||
"Failed to assemble raid array, too many devices missing" \
|
||
"reboot"
|
||
fi
|
||
fi
|
||
mdadm -Db /dev/md$mdcount >> $conf
|
||
mdcount=$((mdcount + 1))
|
||
done
|
||
}
|
||
#======================================
|
||
# pxeRaidZeroSuperBlock
|
||
#--------------------------------------
|
||
function pxeRaidZeroSuperBlock {
|
||
# /.../
|
||
# if we switch from a raid setup back to a non-raid
|
||
# setup and use the same partition table setup as before
|
||
# it might happen that the raid superblock survives.
|
||
# This function removes all raid super blocks from
|
||
# all partitions in the PART setup. If the partition
|
||
# layout is different compared to the former raid layout
|
||
# the superblock is not valid anymore
|
||
# ----
|
||
local IFS=","
|
||
local count=1
|
||
local device
|
||
for i in $PART;do
|
||
device=$(ddn $imageDiskDevice $count)
|
||
if ! waitForStorageDevice $device;then
|
||
continue
|
||
fi
|
||
mdadm --zero-superblock $device
|
||
count=$((count + 1))
|
||
done
|
||
}
|
||
#======================================
|
||
# pxeRaidStop
|
||
#--------------------------------------
|
||
function pxeRaidStop {
|
||
local IFS=","
|
||
local count=0
|
||
for i in $PART;do
|
||
mdadm --stop /dev/md$count
|
||
count=$((count + 1))
|
||
done
|
||
}
|
||
#======================================
|
||
# pxeSwapDevice
|
||
#--------------------------------------
|
||
function pxeSwapDevice {
|
||
local IFS=","
|
||
local field=0
|
||
local count=0
|
||
local device
|
||
for i in $PART;do
|
||
field=0
|
||
count=$((count + 1))
|
||
IFS=";" ; for n in $i;do
|
||
case $field in
|
||
0) partSize=$n ; field=1 ;;
|
||
1) partID=$n ; field=2 ;;
|
||
2) partMount=$n;
|
||
esac
|
||
done
|
||
if test $partID = "82" -o $partID = "S";then
|
||
device=$(ddn $DISK $count)
|
||
waitForStorageDevice $device
|
||
echo $device
|
||
return
|
||
fi
|
||
done
|
||
}
|
||
#======================================
|
||
# pxeRaidSwapDevice
|
||
#--------------------------------------
|
||
function pxeRaidSwapDevice {
|
||
local IFS=","
|
||
local field=0
|
||
local count=0
|
||
local mdcount=0
|
||
local device
|
||
for i in $PART;do
|
||
field=0
|
||
count=$((count + 1))
|
||
IFS=";" ; for n in $i;do
|
||
case $field in
|
||
0) partSize=$n ; field=1 ;;
|
||
1) partID=$n ; field=2 ;;
|
||
2) partMount=$n;
|
||
esac
|
||
done
|
||
if test $partID = "82" -o $partID = "S";then
|
||
device=/dev/md$mdcount
|
||
waitForStorageDevice $device
|
||
echo $device
|
||
return
|
||
fi
|
||
mdcount=$((mdcount + 1))
|
||
done
|
||
}
|
||
#======================================
|
||
# pxeRaidPartCheck
|
||
#--------------------------------------
|
||
function pxeRaidPartCheck {
|
||
local IFS=";"
|
||
local count=0
|
||
local field=0
|
||
local n
|
||
local raidLevel
|
||
local raidDiskFirst
|
||
local raidDiskSecond
|
||
local device
|
||
local partSize
|
||
local partID
|
||
local partMount
|
||
local IdFirst
|
||
local IdSecond
|
||
local raidFirst
|
||
local raidSecond
|
||
local size
|
||
local maxDiffPlus=10240 # max 10MB bigger
|
||
local maxDiffMinus=10240 # max 10MB smaller
|
||
for n in $RAID;do
|
||
case $field in
|
||
0) raidLevel=$n ; field=1 ;;
|
||
1) raidDiskFirst=$n ; field=2 ;;
|
||
2) raidDiskSecond=$n; field=3
|
||
esac
|
||
done
|
||
IFS=","
|
||
for i in $PART;do
|
||
count=$((count + 1))
|
||
field=0
|
||
IFS=";" ; for n in $i;do
|
||
case $field in
|
||
0) partSize=$n ; field=1 ;;
|
||
1) partID=$n ; field=2 ;;
|
||
2) partMount=$n;
|
||
esac
|
||
done
|
||
IdFirst="$(partitionID $raidDiskFirst $count)"
|
||
IdSecond="$(partitionID $raidDiskSecond $count)"
|
||
raidFirst=$(ddn $raidDiskFirst $count)
|
||
raidSecond=$(ddn $raidDiskSecond $count)
|
||
if [ "$IdFirst" != "fd" ] || ! waitForStorageDevice $raidFirst;then
|
||
raidFirst=
|
||
fi
|
||
if [ "$IdSecond" != "fd" ] || ! waitForStorageDevice $raidSecond;then
|
||
raidSecond=
|
||
fi
|
||
# /.../
|
||
# RAID should be able to work in degraded mode when
|
||
# one of the disks is missing
|
||
# ----
|
||
if [ -z "$raidFirst" -a -z "$raidSecond" ]; then
|
||
return 1
|
||
fi
|
||
if [ "$partSize" == "x" ] ; then
|
||
# partition use all available space
|
||
continue
|
||
fi
|
||
for device in $raidFirst $raidSecond ; do
|
||
size=$(partitionSize $device)
|
||
if [ "$(( partSize * 1024 - size ))" -gt "$maxDiffMinus" -o \
|
||
"$(( size - partSize * 1024 ))" -gt "$maxDiffPlus" ]
|
||
then
|
||
return 1
|
||
fi
|
||
done
|
||
done
|
||
return 0
|
||
}
|
||
#======================================
|
||
# pxePartitionSetupCheck
|
||
#--------------------------------------
|
||
function pxePartitionSetupCheck {
|
||
# /.../
|
||
# validation check for the PART line. So far this
|
||
# function counts the given partition sizes and
|
||
# checks if it's possible to setup those partitions
|
||
# with respect to the available disk size
|
||
# ----
|
||
local IFS=","
|
||
local field=0
|
||
local count=0
|
||
local reqsizeMB=0
|
||
if [ -z "$DISK" ];then
|
||
# no disk device available, might be a ram only
|
||
# or diskless client
|
||
return
|
||
fi
|
||
local haveKBytes=$(partitionSize $DISK)
|
||
local haveMBytes=$((haveKBytes / 1024))
|
||
for i in $PART;do
|
||
field=0
|
||
count=$((count + 1))
|
||
IFS=";" ; for n in $i;do
|
||
case $field in
|
||
0) partSize=$n; field=1 ;;
|
||
esac
|
||
done
|
||
if [ "$partSize" == "x" ] ; then
|
||
# partition requests all available space
|
||
# use a fake value of 10 MB as minimum
|
||
reqsizeMB=$((reqsizeMB + 10))
|
||
else
|
||
# some size was requested, use value as MB size
|
||
reqsizeMB=$((reqsizeMB + partSize))
|
||
fi
|
||
done
|
||
if [ $reqsizeMB -gt $haveMBytes ];then
|
||
systemException \
|
||
"Requested partition sizes exceeds disk size" \
|
||
"reboot"
|
||
fi
|
||
}
|
||
#======================================
|
||
# pxePartCheck
|
||
#--------------------------------------
|
||
function pxePartCheck {
|
||
# /.../
|
||
# check the current partition table according to the
|
||
# current setup of the PART line. Thus this function
|
||
# checks if a new partition table setup compared to
|
||
# the existing one was requested. Additionally the check
|
||
# is clever enough to find out if the new partition
|
||
# table setup would destroy data on the existing one
|
||
# or if it only increases the partitions so that no
|
||
# data loss is expected.
|
||
# ----
|
||
local IFS=$IFS_ORIG
|
||
local count=0
|
||
local field=0
|
||
local n
|
||
local partSize
|
||
local partID
|
||
local partMount
|
||
local device
|
||
local size
|
||
local maxDiffPlus=10240 # max 10MB bigger
|
||
local maxDiffMinus=10240 # max 10MB smaller
|
||
IFS=","
|
||
for i in $PART;do
|
||
count=$((count + 1))
|
||
field=0
|
||
IFS=";" ; for n in $i;do
|
||
case $field in
|
||
0) partSize=$n ; field=1 ;;
|
||
1) partID=$n ; field=2 ;;
|
||
2) partMount=$n;
|
||
esac
|
||
done
|
||
device=$(ddn $DISK $count)
|
||
if [ "$(partitionID $DISK $count)" != "$partID" ]; then
|
||
return 1
|
||
fi
|
||
if ! waitForStorageDevice $device;then
|
||
return 1
|
||
fi
|
||
if [ "$partSize" == "x" ] ; then
|
||
# partition use all available space
|
||
continue
|
||
fi
|
||
size=$(partitionSize $device)
|
||
if [ "$(( partSize * 1024 - size ))" -gt "$maxDiffMinus" -o \
|
||
"$(( size - partSize * 1024 ))" -gt "$maxDiffPlus" ]
|
||
then
|
||
return 1
|
||
fi
|
||
done
|
||
return 0
|
||
}
|
||
#======================================
|
||
# pxeBootDevice
|
||
#--------------------------------------
|
||
function pxeBootDevice {
|
||
local IFS=","
|
||
local field=0
|
||
local count=0
|
||
local device
|
||
for i in $PART;do
|
||
field=0
|
||
count=$((count + 1))
|
||
IFS=";" ; for n in $i;do
|
||
case $field in
|
||
0) partSize=$n ; field=1 ;;
|
||
1) partID=$n ; field=2 ;;
|
||
2) partMount=$n;
|
||
esac
|
||
done
|
||
if [ $partMount = "/boot" ];then
|
||
device=$(ddn $DISK $count)
|
||
waitForStorageDevice $device
|
||
echo $device
|
||
return
|
||
fi
|
||
done
|
||
}
|
||
#======================================
|
||
# startUtimer
|
||
#--------------------------------------
|
||
function startUtimer {
|
||
local IFS=$IFS_ORIG
|
||
local utimer=$(lookup utimer)
|
||
if [ -x $utimer ];then
|
||
if [ ! -e /tmp/utimer ];then
|
||
ln -s $UTIMER_INFO /tmp/utimer
|
||
fi
|
||
$utimer
|
||
export UTIMER=$(cat /var/run/utimer.pid)
|
||
if [ -f /iprocs ];then
|
||
cat /iprocs | grep -v UTIMER_PID > /iprocs
|
||
fi
|
||
echo UTIMER_PID=$UTIMER >> /iprocs
|
||
fi
|
||
}
|
||
#======================================
|
||
# setupBootPartitionPXE
|
||
#--------------------------------------
|
||
function setupBootPartitionPXE {
|
||
#======================================
|
||
# Variable setup
|
||
#--------------------------------------
|
||
local IFS=$IFS_ORIG
|
||
local fstype
|
||
local mpoint=boot_bind
|
||
unset NETBOOT_ONLY
|
||
local prefix=/mnt
|
||
#======================================
|
||
# Don't operate with unknown root part
|
||
#--------------------------------------
|
||
if [ -z "$imageRootDevice" ];then
|
||
# /.../
|
||
# this case should only be reached when the netboot
|
||
# code checks if the image needs an update. The update
|
||
# check happens as early as possible and at that time
|
||
# the root device variable is not set, so we use this
|
||
# as the trigger to return
|
||
#
|
||
return
|
||
fi
|
||
if [ ! -e "$imageRootDevice" ];then
|
||
# /.../
|
||
# the device does not exist case happens if NFSROOT is used.
|
||
# In this situation the variable holds the nfs root path
|
||
# and options and not a local device. For this setup we
|
||
# also don't need a boot partition because the client will
|
||
# always boot from the network, so we use this as return
|
||
# trigger too
|
||
# ----
|
||
export NETBOOT_ONLY=yes
|
||
return
|
||
fi
|
||
#======================================
|
||
# Check for boot partition in PART
|
||
#--------------------------------------
|
||
local bootdev=$(pxeBootDevice)
|
||
if [ -e "$bootdev" ];then
|
||
export imageBootDevice=$bootdev
|
||
fi
|
||
#======================================
|
||
# Initial bootid setup
|
||
#--------------------------------------
|
||
if [ ! -z "$imageBootDevice" ];then
|
||
# bootid is boot partition
|
||
export bootid=$(nd $imageBootDevice)
|
||
else
|
||
# bootid is root partition
|
||
export bootid=$(nd $imageRootDevice)
|
||
export imageBootDevice=$imageRootDevice
|
||
fi
|
||
if [ ! -z "$RAID" ] && [ ! -z "$bootid" ];then
|
||
# raid md devices start with 0 but partition id's start with 1
|
||
export bootid=$((bootid + 1))
|
||
fi
|
||
#======================================
|
||
# Probe boot/root filesystem
|
||
#--------------------------------------
|
||
fstype=$(probeFileSystem $imageRootDevice)
|
||
#======================================
|
||
# return if no extra boot partition
|
||
#--------------------------------------
|
||
if [ $imageBootDevice = $imageRootDevice ];then
|
||
if [ $fstype = "unknown" ] || [ "$haveLuks" = "yes" ];then
|
||
# /.../
|
||
# there is no extra boot device and the root device has an
|
||
# unsupported boot filesystem or layer, mark as netboot only
|
||
# ----
|
||
export NETBOOT_ONLY=yes
|
||
fi
|
||
# no boot partition setup required
|
||
return
|
||
fi
|
||
#======================================
|
||
# Check boot partition filesystem
|
||
#--------------------------------------
|
||
local fstype_boot=$(probeFileSystem $imageBootDevice)
|
||
if [ $fstype_boot = "unknown" ];then
|
||
# /.../
|
||
# there is a boot device with an unknown filesystem
|
||
# create boot filesystem
|
||
# ----
|
||
createFilesystem $imageBootDevice $fstype
|
||
fi
|
||
#======================================
|
||
# export bootpart relevant variables
|
||
#--------------------------------------
|
||
export bootPartitionFSType=$fstype
|
||
export kiwi_BootPart=$bootid
|
||
#======================================
|
||
# copy boot data from image to bootpart
|
||
#--------------------------------------
|
||
mkdir -p /$mpoint
|
||
mount $imageBootDevice /$mpoint
|
||
cp -a $prefix/boot /$mpoint
|
||
if [ -e /boot.tgz ];then
|
||
tar -xf /boot.tgz -C /$mpoint
|
||
fi
|
||
umount /$mpoint
|
||
rmdir /$mpoint
|
||
#======================================
|
||
# bind mount boot partition
|
||
#--------------------------------------
|
||
# the resetBootBind() function will resolve this to a
|
||
# standard /boot mount when the bootloader will be
|
||
# installed in preinit.
|
||
# ---
|
||
rm -rf $prefix/boot
|
||
mkdir $prefix/boot
|
||
mkdir $prefix/$mpoint
|
||
mount $imageBootDevice $prefix/$mpoint
|
||
mount --bind \
|
||
$prefix/$mpoint/boot $prefix/boot
|
||
}
|
||
#======================================
|
||
# setupBootPartition
|
||
#--------------------------------------
|
||
function setupBootPartition {
|
||
#======================================
|
||
# Variable setup
|
||
#--------------------------------------
|
||
local IFS=$IFS_ORIG
|
||
local label=undef
|
||
local mpoint=boot_bind
|
||
local fstype
|
||
local BID=1
|
||
local prefix=/mnt
|
||
#======================================
|
||
# Check for partition IDs meta data
|
||
#--------------------------------------
|
||
if [ ! -z "$kiwi_BootPart" ];then
|
||
BID=$kiwi_BootPart
|
||
fi
|
||
#======================================
|
||
# Check for boot partition
|
||
#--------------------------------------
|
||
if [ -z "$imageDiskDevice" ];then
|
||
# no disk device like for live ISO based on clicfs
|
||
return
|
||
fi
|
||
label=$(blkid $(ddn $imageDiskDevice $BID) -s LABEL -o value)
|
||
if [ "$label" = "BOOT" ];then
|
||
export imageBootDevice=$(ddn $imageDiskDevice $BID)
|
||
fi
|
||
#======================================
|
||
# Probe boot partition filesystem
|
||
#--------------------------------------
|
||
fstype=$(probeFileSystem $(ddn $imageDiskDevice $BID))
|
||
export bootPartitionFSType=$fstype
|
||
#======================================
|
||
# Export bootid if not yet done
|
||
#--------------------------------------
|
||
if [ -z "$bootid" ];then
|
||
export bootid=$BID
|
||
fi
|
||
#======================================
|
||
# Return if no boot setup required
|
||
#--------------------------------------
|
||
if [ ! "$label" = "BOOT" ] || [ ! -e "$imageBootDevice" ];then
|
||
return
|
||
fi
|
||
#======================================
|
||
# copy boot data from image to bootpart
|
||
#--------------------------------------
|
||
mkdir -p /$mpoint
|
||
mount $imageBootDevice /$mpoint
|
||
cp -a $prefix/boot /$mpoint
|
||
if [ -e /boot.tgz ];then
|
||
tar -xf /boot.tgz -C /$mpoint
|
||
fi
|
||
umount /$mpoint
|
||
rmdir /$mpoint
|
||
#======================================
|
||
# bind mount boot partition
|
||
#--------------------------------------
|
||
# the resetBootBind() function will resolve this to a
|
||
# standard /boot mount when the bootloader will be
|
||
# installed in preinit.
|
||
# ---
|
||
rm -rf $prefix/boot
|
||
mkdir $prefix/boot
|
||
mkdir $prefix/$mpoint
|
||
mount $imageBootDevice $prefix/$mpoint
|
||
mount --bind \
|
||
$prefix/$mpoint/boot $prefix/boot
|
||
}
|
||
#======================================
|
||
# isVirtioDevice
|
||
#--------------------------------------
|
||
function isVirtioDevice {
|
||
local IFS=$IFS_ORIG
|
||
if [ $haveDASD -eq 0 ] && [ $haveZFCP -eq 0 ];then
|
||
return 0
|
||
fi
|
||
return 1
|
||
}
|
||
#======================================
|
||
# isDASDDevice
|
||
#--------------------------------------
|
||
function isDASDDevice {
|
||
local IFS=$IFS_ORIG
|
||
if [ $haveDASD -eq 1 ];then
|
||
return 0
|
||
fi
|
||
return 1
|
||
}
|
||
#======================================
|
||
# isZFCPDevice
|
||
#--------------------------------------
|
||
function isZFCPDevice {
|
||
local IFS=$IFS_ORIG
|
||
if [ $haveZFCP -eq 1 ];then
|
||
return 0
|
||
fi
|
||
return 1
|
||
}
|
||
#======================================
|
||
# runPreinitServices
|
||
#--------------------------------------
|
||
function runPreinitServices {
|
||
# /.../
|
||
# run the .sh scripts in /etc/init.d/kiwi while
|
||
# inside the preinit stage of the kiwi boot process
|
||
# ----
|
||
local IFS=$IFS_ORIG
|
||
local service=/etc/init.d/kiwi/$1
|
||
if [ ! -d $service ];then
|
||
Echo "kiwi service $service not found... skipped"
|
||
return
|
||
fi
|
||
for script in $service/*.sh;do
|
||
test -e $script && bash -x $script
|
||
done
|
||
}
|
||
#======================================
|
||
# setupTTY
|
||
#--------------------------------------
|
||
function setupTTY {
|
||
# /.../
|
||
# create tty device nodes in case we don't have devtmpfs
|
||
# ----
|
||
local IFS=$IFS_ORIG
|
||
local tty_driver
|
||
local major
|
||
local minor
|
||
local tty
|
||
if $have_devtmpfs;then
|
||
return
|
||
fi
|
||
if [ "$console" ]; then
|
||
tty_driver="${tty_driver:+$tty_driver }${console%%,*}"
|
||
fi
|
||
for o in $tty_driver; do
|
||
case "$o" in
|
||
ttyS*) test -e /dev/$o || mknod -m 0660 /dev/$o c 4 64 ;;
|
||
tty*) test -e /dev/$o || mknod -m 0660 /dev/$o c 4 1 ;;
|
||
esac
|
||
done
|
||
tty_driver=$(showconsole -n 2>/dev/null)
|
||
if test -n "$tty_driver" ; then
|
||
major=${tty_driver%% *}
|
||
minor=${tty_driver##* }
|
||
if test $major -eq 4 -a $minor -lt 64 ; then
|
||
tty=/dev/tty$minor
|
||
test -e $tty || mknod -m 0660 $tty c 4 $minor
|
||
fi
|
||
if test $major -eq 4 -a $minor -ge 64 ; then
|
||
tty=/dev/ttyS$((64-$minor))
|
||
test -e $tty || mknod -m 0660 $tty c 4 $minor
|
||
fi
|
||
fi
|
||
}
|
||
#======================================
|
||
# setupConsoleFont
|
||
#--------------------------------------
|
||
function setupConsoleFont {
|
||
setfont $CONSOLE_FONT
|
||
}
|
||
#======================================
|
||
# setupConsole
|
||
#--------------------------------------
|
||
function setupConsole {
|
||
# /.../
|
||
# placeholder method for custom console setup
|
||
# ----
|
||
:
|
||
}
|
||
#======================================
|
||
# cleanPartitionTable
|
||
#--------------------------------------
|
||
function cleanPartitionTable {
|
||
# /.../
|
||
# remove partition table and create a new msdos
|
||
# table label if parted is in use
|
||
# ----
|
||
local IFS=$IFS_ORIG
|
||
dd if=/dev/zero of=$imageDiskDevice bs=512 count=1 >/dev/null
|
||
if [ $PARTITIONER = "parted" ];then
|
||
parted -s $imageDiskDevice mklabel msdos
|
||
fi
|
||
}
|
||
#======================================
|
||
# partitionTableType
|
||
#--------------------------------------
|
||
function partitionTableType {
|
||
# /.../
|
||
# get partition table type
|
||
# ----
|
||
local device=$(getDiskDevice $imageDiskDevice)
|
||
if ! parted -m -s $device unit s print > /tmp/table;then
|
||
systemException \
|
||
"Failed to retrieve current partition table" \
|
||
"reboot"
|
||
fi
|
||
cat /tmp/table | grep ^$device: | cut -f6 -d:
|
||
}
|
||
#======================================
|
||
# preparePartitionTable
|
||
#--------------------------------------
|
||
function preparePartitionTable {
|
||
# /.../
|
||
# update partition table to allow resizing partitions
|
||
# for a new disk geometry
|
||
# ----
|
||
local IFS=$IFS_ORIG
|
||
#======================================
|
||
# check for hybrid iso
|
||
#--------------------------------------
|
||
if [ "$kiwi_hybridpersistent" = "true" ];then
|
||
# /.../
|
||
# The partition table written into an iso doesn't
|
||
# like the resync, so we return early here
|
||
# ----
|
||
return
|
||
fi
|
||
#======================================
|
||
# get table type
|
||
#--------------------------------------
|
||
local plabel=$(partitionTableType)
|
||
#======================================
|
||
# prepare table
|
||
#--------------------------------------
|
||
if [[ "$plabel" =~ gpt ]];then
|
||
#======================================
|
||
# relocate backup GPT to new disk end
|
||
#--------------------------------------
|
||
relocateGPTAtEndOfDisk
|
||
fi
|
||
return 0
|
||
}
|
||
#======================================
|
||
# finalizePartitionTable
|
||
#--------------------------------------
|
||
function finalizePartitionTable {
|
||
# /.../
|
||
# finalize partition table with flags which might get
|
||
# lost during repartition steps
|
||
# ----
|
||
local IFS=$IFS_ORIG
|
||
#======================================
|
||
# get table type
|
||
#--------------------------------------
|
||
local plabel=$(partitionTableType)
|
||
#======================================
|
||
# activate boot partition
|
||
#--------------------------------------
|
||
if [[ $arch =~ i.86|x86_64 ]] && [ $plabel = "msdos" ];then
|
||
activateBootPartition
|
||
fi
|
||
#======================================
|
||
# finalize table
|
||
#--------------------------------------
|
||
if [[ "$plabel" =~ gpt ]];then
|
||
#======================================
|
||
# check if GPT needs to be hybrid
|
||
#--------------------------------------
|
||
if [ "$kiwi_gpt_hybrid_mbr" = "true" ];then
|
||
createHybridGPT
|
||
fi
|
||
fi
|
||
return 0
|
||
}
|
||
#======================================
|
||
# resetBootBind
|
||
#--------------------------------------
|
||
function resetBootBind {
|
||
# /.../
|
||
# remove the bind mount boot setup and replace with a
|
||
# symbolic link to make the suse kernel update process
|
||
# to work correctly
|
||
# ----
|
||
local IFS=$IFS_ORIG
|
||
local bprefix=$1
|
||
local bootdir=$bprefix/boot_bind
|
||
if [ ! -e /proc/mounts ];then
|
||
mount -t proc proc /proc
|
||
fi
|
||
#======================================
|
||
# find bind boot dir
|
||
#--------------------------------------
|
||
if [ ! -e "/$bootdir" ];then
|
||
return
|
||
fi
|
||
#======================================
|
||
# reset bind mount to standard boot dir
|
||
#--------------------------------------
|
||
shopt -s dotglob
|
||
umount $bprefix/boot
|
||
mv /$bootdir/boot /$bootdir/tmp
|
||
mv /$bootdir/tmp/* /$bootdir
|
||
rm -rf /$bootdir/tmp
|
||
umount /$bootdir
|
||
rmdir /$bootdir
|
||
shopt -u dotglob
|
||
#======================================
|
||
# update fstab entry
|
||
#--------------------------------------
|
||
grep -v ^/boot_bind $bprefix/etc/fstab > $bprefix/etc/fstab.new
|
||
mv $bprefix/etc/fstab.new $bprefix/etc/fstab
|
||
sed -i -e s@/boot_bind@/boot@ $bprefix/etc/fstab
|
||
#======================================
|
||
# mount boot again
|
||
#--------------------------------------
|
||
chroot $bprefix mount $imageBootDevice /boot
|
||
}
|
||
#======================================
|
||
# setupKernelLinks
|
||
#--------------------------------------
|
||
function setupKernelLinks {
|
||
# /.../
|
||
# check kernel names and links to kernel and initrd
|
||
# according to the different boot-up situations
|
||
# ----
|
||
local IFS=$IFS_ORIG
|
||
local prefix=/mnt
|
||
#======================================
|
||
# mount boot partition if required
|
||
#--------------------------------------
|
||
local mountCalled=no
|
||
if [ -e "$imageBootDevice" ] && blkid $imageBootDevice;then
|
||
if kiwiMount $imageBootDevice "$prefix";then
|
||
mountCalled=yes
|
||
fi
|
||
fi
|
||
#======================================
|
||
# Change to boot directory
|
||
#--------------------------------------
|
||
pushd $prefix/boot >/dev/null
|
||
#======================================
|
||
# setup if overlay filesystem is used
|
||
#--------------------------------------
|
||
if [ "$kiwi_oemkboot" = "true" ] || \
|
||
[ "$PXE_KIWI_INITRD" = "yes" ] || \
|
||
[ ! -z "$kiwi_ROPart" ]
|
||
then
|
||
# /.../
|
||
# we are using a special root setup based on an overlay
|
||
# filesystem. In this case we can't use the SuSE Linux
|
||
# initrd but must stick to the kiwi boot system.
|
||
# ----
|
||
IFS="," ; for i in $KERNEL_LIST;do
|
||
if test -z "$i";then
|
||
continue
|
||
fi
|
||
kernel=`echo $i | cut -f1 -d:`
|
||
initrd=`echo $i | cut -f2 -d:`
|
||
break
|
||
done
|
||
IFS=$IFS_ORIG
|
||
if [ "$PXE_KIWI_INITRD" = "yes" ];then
|
||
if [ ! -f initrd.kiwi ] && [ ! -f linux.kiwi ];then
|
||
Echo "WARNING: can't find kiwi initrd/linux !"
|
||
Echo -b "local boot will not work, maybe you forgot"
|
||
Echo -b "to add KIWI_INITRD and KIWI_KERNEL in config.<MAC> ?"
|
||
else
|
||
rm -f $initrd && ln -s initrd.kiwi $initrd
|
||
rm -f $kernel && ln -s linux.kiwi $kernel
|
||
fi
|
||
else
|
||
rm -f $initrd && ln -s initrd.vmx $initrd
|
||
rm -f $kernel && ln -s linux.vmx $kernel
|
||
fi
|
||
fi
|
||
#======================================
|
||
# make sure boot => . link exists
|
||
#--------------------------------------
|
||
if [ ! "$bootPartitionFSType" = "vfat" ] && [ ! -e boot ];then
|
||
ln -s . boot
|
||
fi
|
||
#======================================
|
||
# umount boot partition if required
|
||
#--------------------------------------
|
||
popd >/dev/null
|
||
if [ "$mountCalled" = "yes" ];then
|
||
umount $prefix
|
||
fi
|
||
}
|
||
#======================================
|
||
# activateBootPartition
|
||
#--------------------------------------
|
||
function activateBootPartition {
|
||
local IFS=$IFS_ORIG
|
||
local device=$imageBootDevice
|
||
if [ ! -e $device ];then
|
||
device=$imageRootDevice
|
||
fi
|
||
if [ ! -e $device ];then
|
||
echo "Can't find boot partition, activation skipped"
|
||
return
|
||
fi
|
||
local bootID=$(nd $device)
|
||
local diskID=$(dn $device)
|
||
parted $diskID set $bootID boot on
|
||
}
|
||
#======================================
|
||
# relocateGPTAtEndOfDisk
|
||
#--------------------------------------
|
||
function relocateGPTAtEndOfDisk {
|
||
local IFS=$IFS_ORIG
|
||
local input=/part.input
|
||
if ! lookup gdisk &>/dev/null;then
|
||
Echo "Warning, gdisk tool not found"
|
||
Echo "This could break the resize of the image"
|
||
fi
|
||
rm -f $input
|
||
for cmd in x e w y; do
|
||
echo $cmd >> $input
|
||
done
|
||
gdisk $imageDiskDevice < $input 1>&2
|
||
if [ ! $? = 0 ]; then
|
||
Echo "Failed to write backup GPT at end of disk !"
|
||
Echo "This could break the resize of the image"
|
||
fi
|
||
}
|
||
#======================================
|
||
# createHybridGPT
|
||
#--------------------------------------
|
||
function createHybridGPT {
|
||
local IFS=$IFS_ORIG
|
||
local partition_count=$(
|
||
sgdisk -p $imageDiskDevice | grep -E '^\s+[0-9]+' | wc -l
|
||
)
|
||
if [ $partition_count -gt 3 ]; then
|
||
# The max number of partitions to embed is 3
|
||
# see man sgdisk for details
|
||
partition_count=3
|
||
fi
|
||
if ! sgdisk -h $(seq -s : 1 $partition_count) $imageDiskDevice; then
|
||
Echo "Failed to create hybrid GPT/MBR !"
|
||
fi
|
||
}
|
||
#======================================
|
||
# FBOK
|
||
#--------------------------------------
|
||
function FBOK {
|
||
local IFS=$IFS_ORIG
|
||
if [ ! -e /dev/fb0 ];then
|
||
# no framebuffer device found
|
||
return 1
|
||
fi
|
||
if ! lookup fbiterm &>/dev/null;then
|
||
# no framebuffer terminal program found
|
||
return 1
|
||
fi
|
||
if lookup isconsole &>/dev/null;then
|
||
if ! isconsole;then
|
||
# inappropriate ioctl (not a linux console)
|
||
return 1
|
||
fi
|
||
elif ! fbiterm echo &>/dev/null;then
|
||
# fbiterm can't be called with echo test cmd
|
||
return 1
|
||
fi
|
||
return 0
|
||
}
|
||
#======================================
|
||
# backupDiskLayout
|
||
#--------------------------------------
|
||
function backupDiskLayout {
|
||
local IFS=$IFS_ORIG
|
||
local devname=$1
|
||
local device=$(getDiskDevice $devname)
|
||
IFS=""
|
||
local parted=$(parted -m -s $device unit cyl print | grep -v Warning:)
|
||
local pcount=$(echo $parted | tail -n 1 | cut -f1 -d:)
|
||
local diskhd=$(echo $parted | head -n 3 | tail -n 2 | head -n 1)
|
||
local plabel=$(echo $diskhd | cut -f6 -d:)
|
||
IFS=$IFS_ORIG
|
||
if [[ $plabel =~ gpt ]];then
|
||
backupGPT $device $pcount
|
||
else
|
||
backupMBR $device
|
||
fi
|
||
}
|
||
#======================================
|
||
# backupMBR
|
||
#--------------------------------------
|
||
function backupMBR {
|
||
local IFS=$IFS_ORIG
|
||
local device=$1
|
||
dd if=$device bs=1 count=512
|
||
}
|
||
#======================================
|
||
# backupGPT
|
||
#--------------------------------------
|
||
function backupGPT {
|
||
local IFS=$IFS_ORIG
|
||
local device=$1
|
||
local pcount=$2
|
||
dd if=$device bs=1 count=$(((128 * pcount) + 1024))
|
||
}
|
||
#======================================
|
||
# loop_setup
|
||
#--------------------------------------
|
||
function loop_setup {
|
||
local IFS=$IFS_ORIG
|
||
local target="$@"
|
||
local logical_sector_size
|
||
if [ ! -z "$kiwi_target_blocksize" ];then
|
||
logical_sector_size="-L $kiwi_target_blocksize"
|
||
fi
|
||
local loop=$(losetup $logical_sector_size -f --show "$target")
|
||
if [ ! -e "$loop" ];then
|
||
return 1
|
||
fi
|
||
echo $loop
|
||
}
|
||
#======================================
|
||
# loop_delete
|
||
#--------------------------------------
|
||
function loop_delete {
|
||
local IFS=$IFS_ORIG
|
||
local target="$@"
|
||
losetup -d "$target"
|
||
}
|
||
#======================================
|
||
# startMultipathd
|
||
#--------------------------------------
|
||
function startMultipathd {
|
||
local multipath_config=/etc/multipath.conf
|
||
local wwid_timeout=3
|
||
#======================================
|
||
# check already running
|
||
#--------------------------------------
|
||
if pidof multipathd &>/dev/null; then
|
||
Echo "startMultipathd: daemon already running"
|
||
return 0
|
||
fi
|
||
#======================================
|
||
# check the tools
|
||
#--------------------------------------
|
||
for tool in multipathd multipath;do
|
||
if ! lookup $tool &>/dev/null;then
|
||
Echo "startMultipathd: $tool not found"
|
||
return 1
|
||
fi
|
||
done
|
||
#======================================
|
||
# lookup multipath configuration
|
||
#--------------------------------------
|
||
if [ ! -f $multipath_config ];then
|
||
Echo "startMultipathd: no multipath configuration found"
|
||
return 1
|
||
fi
|
||
#======================================
|
||
# load multipath dm modules
|
||
#--------------------------------------
|
||
if ! modprobe dm-multipath;then
|
||
Echo "startMultipathd: can't load dm-multipath"
|
||
return 1
|
||
fi
|
||
#======================================
|
||
# start multipath daemon
|
||
#--------------------------------------
|
||
mkdir -p /etc/multipath
|
||
if ! multipathd;then
|
||
Echo "startMultipathd: failed to start multipathd"
|
||
return 1
|
||
fi
|
||
#======================================
|
||
# wait for devices to settle
|
||
#--------------------------------------
|
||
udevPending
|
||
#======================================
|
||
# sleep for a while
|
||
#--------------------------------------
|
||
# make sure /etc/multipath/wwids are written
|
||
if [ ! -z "$kiwi_wwid_wait_timeout" ];then
|
||
wwid_timeout=$kiwi_wwid_wait_timeout
|
||
fi
|
||
sleep $wwid_timeout
|
||
export MULTIPATHD_PID=$(pidof multipathd | tr ' ' ,)
|
||
return 0
|
||
}
|
||
#======================================
|
||
# stopMultipathd
|
||
#--------------------------------------
|
||
function stopMultipathd {
|
||
# /.../
|
||
# stop multipathd started by us
|
||
# ----
|
||
local IFS=$IFS_ORIG
|
||
if [ -z "$MULTIPATHD_PID" ];then
|
||
return
|
||
fi
|
||
local IFS=,
|
||
for p in $MULTIPATHD_PID; do
|
||
if kill -0 $p &>/dev/null;then
|
||
kill $p
|
||
fi
|
||
done
|
||
}
|
||
#======================================
|
||
# loadSELinuxPolicy
|
||
#--------------------------------------
|
||
function loadSELinuxPolicy {
|
||
# /.../
|
||
# load selinux policy and enforce selinux
|
||
# ----
|
||
local IFS=$IFS_ORIG
|
||
if ! lookup load_policy &>/dev/null;then
|
||
Echo "load_policy not found"
|
||
fi
|
||
if ! lookup restorecon &>/dev/null;then
|
||
Echo "restorecon not found"
|
||
fi
|
||
load_policy -i
|
||
echo 0 > /sys/fs/selinux/enforce
|
||
restorecon -F -R /dev
|
||
}
|
||
#======================================
|
||
# initialize
|
||
#--------------------------------------
|
||
function initialize {
|
||
local IFS=$IFS_ORIG
|
||
#======================================
|
||
# Exports boot image .profile
|
||
#--------------------------------------
|
||
if [ -f /.profile ];then
|
||
importFile < /.profile
|
||
if [ ! -z "$kiwi_bootloader" ];then
|
||
export loader=$kiwi_bootloader
|
||
fi
|
||
fi
|
||
#======================================
|
||
# Check partitioner capabilities
|
||
#--------------------------------------
|
||
if echo $kiwi_initrdname | grep -qE '(oem|net)boot';then
|
||
if [ $PARTITIONER = "unsupported" ];then
|
||
systemException \
|
||
"Installed parted version is too old" \
|
||
"reboot"
|
||
fi
|
||
fi
|
||
#======================================
|
||
# Check for hotfix kernel
|
||
#--------------------------------------
|
||
reloadKernel
|
||
#======================================
|
||
# Prevent blank screen
|
||
#--------------------------------------
|
||
if [ -x /usr/bin/setterm ];then
|
||
setterm -powersave off -blank 0
|
||
fi
|
||
#======================================
|
||
# Start boot timer (first stage)
|
||
#--------------------------------------
|
||
startUtimer
|
||
}
|
||
|
||
# vim: set noexpandtab:
|