--- etc/mkinitrd/mkinitrd-boot.sh | 95 +++++++++++++++++++++++++++++++++++++++++ etc/mkinitrd/mkinitrd-setup.sh | 70 ++++++++++++++++++++++++++++++ etc/mkinitrd/mkinitrd-stop.sh | 21 +++++++++ 3 files changed, 186 insertions(+) --- /dev/null +++ b/etc/mkinitrd/mkinitrd-boot.sh @@ -0,0 +1,95 @@ +#!/bin/bash +#%stage: device +#%depends: network +#%programs: /sbin/iscsid /sbin/iscsiadm +#%modules: iscsi_tcp crc32c scsi_transport_iscsi +#%if: "$root_iscsi" -o "$TargetAddress" +# +##### iSCSI initialization +## +## This script initializes iSCSI (SCSI over IP). +## To be able to use this script, the network has to be setup. +## When everything worked as expected, the iSCSI devices will show +## up as real SCSI devices. +## +## Command line parameters +## ----------------------- +## +## TargetAddress the address of the iscsi server +## TargetPort the port of the iscsi server (defaults to 3260) +## TargetName the iscsi target name (connect to all if empty) +## iSCSI_ignoreNodes if set all stored nodes will be ignored (only +## iBFT and commandline nodes get parsed) +## + +### iSCSI_warning_InitiatorName +# shows a warning about iSCSI InitiatorName differences +# Origin should be something like "commandline" or "iBFT" +iSCSI_warning_InitiatorName() { + echo "iSCSI: WARNING" + echo "iSCSI: =======================" + echo "iSCSI: " + echo "iSCSI: InitiatorName given on $2 and internally stored Initiator are different." + echo "iSCSI: New: $tmp_InitiatorName" + echo "iSCSI: Stored: $InitiatorName" + echo "iSCSI: " + echo "iSCSI: using the $2 version" +} + +if [ "$iSCSI_ignoreNodes" ]; then + # make us forget we have to initialize stored nodes + echo "iSCSI: removing node information..." + iscsi_sessions= + rm -rf /etc/iscsi/nodes + mkdir /etc/iscsi/nodes +fi + +# get the command line InitiatorName +tmp_InitiatorName="$(get_param InitiatorName)" +# reads the InitiatorName variable +. /etc/iscsi/initiatorname.iscsi + +# Check of iBFT settings +if [ -d /sys/firmware/ibft/initiator ] ; then + # only use the iBFT InitiatorName if the commandline argument is not "default" + read iSCSI_INITIATOR_NAME < /sys/firmware/ibft/initiator + if [ "$iSCSI_INITIATOR_NAME" -a "$tmp_InitiatorName" != "default" ] ; then + iSCSI_warning_InitiatorName "$iSCSI_INITIATOR_NAME" "iBFT" + InitiatorName=$iSCSI_INITIATOR_NAME + fi +fi + +if [ "$tmp_InitiatorName" != "$InitiatorName" -a "$tmp_InitiatorName" != "default" -a "$tmp_InitiatorName" ]; then + iSCSI_warning_InitiatorName "$tmp_InitiatorName" "cmdline" + InitiatorName=$tmp_InitiatorName +fi + +# store the detected InitiatorName permanently +echo "InitiatorName=$InitiatorName" > /etc/iscsi/initiatorname.iscsi + +unset iSCSI_warning_InitiatorName + +load_modules + +echo "Starting iSCSI daemon" +/sbin/iscsid -n + +# log into iBFT nodes +/sbin/iscsiadm -m fw -l + +# Check for command line sessions +if [ -n "$TargetAddress" -a -n "$TargetName" ] ; then + + # try to detect and connect to the iscsi server + echo -n "Starting discovery on ${TargetAddress},${TargetName}: " + if /sbin/iscsiadm -m discovery -t st -p ${TargetAddress}:${TargetPort} 2> /dev/null ; then + echo "ok." + else + echo "failed." + fi + # Mark this node as 'onboot' + /sbin/iscsiadm -m node -p $TargetAddress:$TargetPort -T $TargetName -o update -n node.conn[0].startup -v onboot +fi + +# Activate all 'onboot' sessions +/sbin/iscsiadm -m node -L onboot --- /dev/null +++ b/etc/mkinitrd/mkinitrd-setup.sh @@ -0,0 +1,70 @@ +#!/bin/bash +# +#%stage: device +# +check_iscsi_root() { + local devname=$1 + local sysfs_path + + sysfs_path=$(/sbin/udevadm info -q path -n $devname 2> /dev/null) + if [ -z "$sysfs_path" ] || [ ! -d /sys$sysfs_path ] ; then + return; + fi + + pushd /sys$sysfs_path > /dev/null + if [ ! -d device ] ; then + cd .. + fi + + if [ ! -d device ] ; then + # no device link; return + popd > /dev/null + return; + fi + + cd -P device + cd ../.. + + if [ -d connection* ]; then + cd -P connection* + cid=${PWD#*connection} + sid=${cid%%:*} + if [ -d /sys/class/iscsi_session/session$sid ]; then + cd -P /sys/class/iscsi_session/session$sid + echo $(basename $PWD) + fi + fi + popd > /dev/null +} + +for bd in $blockdev; do + update_blockdev $bd + sid=$(check_iscsi_root $bd) + if [ "$sid" ]; then + root_iscsi=1 + iscsi_sessions="$iscsi_sessions ${sid#session}" + fi +done + +save_var root_iscsi +save_var iscsi_sessions + +if [ "${root_iscsi}" ]; then + for session in $iscsi_sessions; do + eval TargetName${session}=$(cat /sys/class/iscsi_session/session${session}/targetname) + eval TargetAddress${session}=$(cat /sys/class/iscsi_connection/connection${session}:0/address) + eval TargetPort${session}=$(cat /sys/class/iscsi_connection/connection${session}:0/port) + + save_var TargetName${session} + save_var TargetAddress${session} + save_var TargetPort${session} + done + # copy the iscsi configuration + cp -rp /etc/iscsi etc/ + if [ -z "$interface" ] ; then + interface="default" + fi +fi + +save_var TargetPort 3260 # in case the port was not defined via command line we assign a default port + --- /dev/null +++ b/etc/mkinitrd/mkinitrd-stop.sh @@ -0,0 +1,21 @@ +#!/bin/bash +# +#%stage: setup +#%provides: killprogs +# +#%if: "$root_iscsi" +#%dontshow +# +##### kill iscsi +## +## Because we will run and use the iSCSI daemon from the new root +## the old one has to be killed. During that time no iSCSI +## exceptions should occur! +## +## Command line parameters +## ----------------------- +## + +# kill iscsid, will be restarted from the real root +iscsi_pid=$(pidof iscsid) +[ "$iscsi_pid" ] && kill -TERM $iscsi_pid