summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLee Duncan <lduncan@suse.com>2022-04-01 10:25:06 -0700
committerLee Duncan <lduncan@suse.com>2022-04-07 09:01:26 -0700
commit1aafa5e52fe2bbd15b9597fe09a3e2afb6e662df (patch)
treef8e345e040771817fbeaa1fbb8d254bf7628eabe
parent1451108792c1187974b87399f71822b59d62948c (diff)
downloadopen-iscsi-1aafa5e52fe2bbd15b9597fe09a3e2afb6e662df.tar.gz
Use kernel initiatorname when setting local iname
Update the iscsi-gen-initatorname script to take its initiator name from the kernel command line, if present. Also, beef up and simplify the error checking. Error messages will now go to stderr, and it is now an error to overwrite the initiatorname file unless the "force" option is set. The man page was updated, as well.
-rw-r--r--doc/iscsi-gen-initiatorname.8.template19
-rw-r--r--utils/iscsi-gen-initiatorname.sh.template154
2 files changed, 132 insertions, 41 deletions
diff --git a/doc/iscsi-gen-initiatorname.8.template b/doc/iscsi-gen-initiatorname.8.template
index e10a4ac..cd26f2d 100644
--- a/doc/iscsi-gen-initiatorname.8.template
+++ b/doc/iscsi-gen-initiatorname.8.template
@@ -1,4 +1,4 @@
-.TH ISCSI_GEN_INITIATORNAME 8 "Dec 2021" "" "Linux Administrator's Manual"
+.TH ISCSI_GEN_INITIATORNAME 8 "APR 2022" "" "Linux Administrator's Manual"
.SH NAME
iscsi-gen-initiatorname \- smart iSCSI initiator name generation tool
.SH SYNOPSIS
@@ -6,11 +6,20 @@ iscsi-gen-initiatorname \- smart iSCSI initiator name generation tool
[OPTIONS]
.SH "DESCRIPTION"
.B iscsi-gen-initiatorname
-generates a unique iSCSI node name on every invocation. If
-iBFT is in use, the iBFT-registered initiator name will be used.
+generates an iSCSI Initiator Name in the
+.I initiatorname.iscsi
+file. It is an error to try to overwrite an existing Initiator Name,
+unless the \fB-f\fP (\fIforce\fR) option is supplied.
.P
-If there is an existing initiator name, it will not be overwritten
-unless the \fB-f\fP option is supplied.
+The Initiator Name will be taken from the kernel command line,
+if present (from the \fIrd.initiatorname\fR parameter), else from
+the iBFT subsystem (if present in \fIsysfs\fR), else it will be
+generated using the \fBiscsi-iname\fR command.
+.P
+It is an error if both the kernel command-line Initiator Name
+and the iBFT Initiator Name are both set, and they are different.
+it is also an error to try to write over an Initiator Name file
+if it read-only, or to create one if its directory is not writable.
.SH OPTIONS
.TP
.BI [-h]
diff --git a/utils/iscsi-gen-initiatorname.sh.template b/utils/iscsi-gen-initiatorname.sh.template
index 3fa8dcc..e6260d7 100644
--- a/utils/iscsi-gen-initiatorname.sh.template
+++ b/utils/iscsi-gen-initiatorname.sh.template
@@ -2,15 +2,41 @@
#
# iscsi-gen-initiatorname
#
-# Generate a default iSCSI Initiatorname for SUSE installations.
+# Generate a default iSCSI Initiatorname for Linux installations.
#
# Copyright (c) 2022 Hannes Reinecke, SUSE Labs
# This script is licensed under the GPL.
#
+# external programs required:
+# * iscsi-iname (if needed to generate a new InitiatorName)
+#
+
+NAME=${0##*/}
+INAME_DIR="@HOMEDIR@"
+INAME_FILE="$INAME_DIR/initiatorname.iscsi"
+
+# our default IQN prefix
+DEFAULT_IQN_PREFIX="iqn.1996-04.de.suse:01"
+
+#
+# set up comments for initiatorname files using variables
+# instead of HERE documents, since we may be running when
+# temp filename space is read-only
+#
-NAME="$0"
-INAME_FILE="@HOMEDIR@/initiatorname.iscsi"
-IQN_PREFIX="iqn.1996-04.de.suse:01"
+KERNEL_COMMENTS="\
+##
+## iSCSI Initiatorname taken from Kernel Command line.
+##
+## DO NOT EDIT OR REMOVE THIS FILE!
+## If you remove this file, the iSCSI daemon will not start.
+## Any change here may be overwritten at next boot, if
+## the kernel command-line parameter is passed in, again.
+## If a different initiatorname is required please change the
+## initiatorname on the kernel command line and call:
+## # iscsi-gen-initiatorname -f
+## to recreate an updated version of this file.
+##"
IBFT_COMMENTS="\
##
@@ -20,8 +46,8 @@ IBFT_COMMENTS="\
## If you remove this file, the iSCSI daemon will not start.
## Any change here will not be reflected to the iBFT BIOS tables.
## If a different initiatorname is required please change the
-## initiatorname in the BIOS setup and call
-## @SBINDIR@/iscsi-gen-initiatorname -f
+## initiatorname in the BIOS setup and call:
+## # iscsi-gen-initiatorname -f
## to recreate an updated version of this file.
##"
@@ -32,9 +58,17 @@ NORMAL_COMMENTS="\
## DO NOT EDIT OR REMOVE THIS FILE!
## If you remove this file, the iSCSI daemon will not start.
## If you change the InitiatorName, existing access control lists
-## may reject this initiator. The InitiatorName must be unique
-## for each iSCSI initiator. Do NOT duplicate iSCSI InitiatorNames."
+## may reject this initiator. The InitiatorName must be unique
+## for each iSCSI initiator. Do NOT duplicate iSCSI InitiatorNames."
+# where iBFT initiator name file would live, if present
+IBFT_SYSFS_DIR=/sys/firmware/ibft/initiator
+
+#
+# print usage and exit
+#
+# usage: usage_and_exit EXIT_VALUE
+#
usage_and_exit()
{
xit_val=$1
@@ -42,11 +76,31 @@ usage_and_exit()
echo "Usage: $NAME [OPTIONS] -- generate an iSCSI initiatorname"
echo "Where OPTIONS are from:"
echo " -h print usage and exit"
- echo " -f overwrite existing initiator name, if any"
- echo " -p IQN-PRE set the prefix for the IQN generated (default $IQN_PREFIX)"
+ echo " -f overwrite existing InitiatorName, if any"
+ echo " -p IQN-PRE set the prefix for the IQN generated (default ${DEFAULT_IQN_PREFIX})"
exit $xit_val
}
+#
+# get kernel command-line-supplied initiatorname, if any
+#
+# usage: INAME=$(kernel_supplied_initiatorname)
+#
+kernel_supplied_initiatorname()
+{
+ kcl="$(</proc/cmdline)"
+ if [[ "$kcl" =~ rd.initiatorname ]] ; then
+ kcl=${kcl##*rd.initiatorname=}
+ echo ${kcl%% *}
+ else
+ echo ""
+ fi
+}
+
+#
+# start
+#
+
while getopts "hfp:" o ; do
case "${o}" in
h) usage_and_exit 0 ;;
@@ -59,44 +113,72 @@ shift $(($OPTIND-1))
if [ "$#" -gt 0 ] ; then
echo "Invalid argument(s): $*"
- usage_and_exit
+ usage_and_exit 1
fi
-# use the iBFT initiator name, if present
-if [ -d /sys/firmware/ibft/initiator ] ; then
- read iSCSI_INITIATOR_NAME < /sys/firmware/ibft/initiator/initiator-name
+# use prefix passed in, if any, else our default
+: ${IQN_PREFIX:=${DEFAULT_IQN_PREFIX}}
+
+# get kernel command-line-supplied initiator name, if any
+KERNEL_INAME="$(kernel_supplied_initiatorname)"
+
+# get the iBFT initiator name, if present
+[ -d $IBFT_SYSFS_DIR ] && read IBFT_INAME < $IBFT_SYSFS_DIR/initiator-name
+
+# get the systemd-supplied initiator name, if present (as InitiatorName)
+[ -r "$INAME_FILE" ] && . "$INAME_FILE"
+
+# if we have a local initiator name and "force" is not set end it now
+if [ "$InitiatorName" -a -z "$FORCE" ] ; then
+ echo "Error: you cannot overwrite the current InitiatorName unless 'force' is set." 1>&2
+ echo "Please call '$NAME -f' to update iSCSI InitiatorName, if needed." 1>&2
+ exit 1
fi
-# if we have an iBFT initiator name and an initiator name
-# file, they had better match, unless "force" is set
-if [ -f $INAME_FILE -a -z "$FORCE" ] ; then
- if [ "$iSCSI_INITIATOR_NAME" ] ; then
- eval $(cat $INAME_FILE | sed -e '/^#/d')
- if [ "$iSCSI_INITIATOR_NAME" != "$InitiatorName" ] ; then
- echo "iSCSI Initiatorname from iBFT is different from the current setting."
- echo "Please call '@SBINDIR@/iscsi-gen-initiatorname -f' to update the iSCSI Initiatorname."
- exit 1
- fi
+# ensure we can write the initiator name file
+if [ -r "$INAME_FILE" ] ; then
+ if [ ! -w "$INAME_FILE" ] ; then
+ echo "Error: cannot update InitiatorName, write protected: $INAME_FILE" 1>&1
+ echo "Please ensure you are root and filesystem is read/write." 1>&2
+ exit 1
fi
+ # the file exists but we can write over it
+elif [ ! -w "$INAME_DIR" ] ; then
+ echo "Error: no write permission in directory: $INAME_DIR" 1>&2
+ echo "Please ensure you are root and filesystem is read/write." 1>&2
+ exit 1
fi
-# if we have an initiator name from iBFT or from
-# an existing initiator name file, use it
-if [ "$iSCSI_INITIATOR_NAME" ] ; then
- echo "##" > $INAME_FILE || exit 1
- echo "## $INAME_FILE" >> $INAME_FILE
- echo "$IBFT_COMMENTS" >> $INAME_FILE
- echo "InitiatorName=$iSCSI_INITIATOR_NAME" >> $INAME_FILE
- chmod 0600 $INAME_FILE
+# if we have both iBFT and kernel command line initiator names that
+# do not match end it now
+if [ "$IBFT_INAME" -a "$KERNEL_INAME" -a "$IBFT_INAME" != "$KERNEL_INAME" ] ; then
+ echo "Error: Kernel cmdline Initiator Name: $KERNEL_INAME" 1>&2
+ echo " does not match iBFT Initiator Name: $IBFT_INAME" 1>&2
+ echo "Please ensure they both match, or remove the kernel parameter, then" 1>&2
+ echo " run '$NAME [-f]' to update iSCSI InitiatorName" 1>&2
+ exit 1
fi
-# if we still do not have an initiator name, create one
-if [ ! -f $INAME_FILE ] ; then
- echo "##" > $INAME_FILE || exit 1
+# now we know we want to write the initiator name
+
+# handle a write failure on this first write attempt to the initiator name
+# file, in *case* it we somehow missed that it is not writable
+echo "##" > $INAME_FILE || exit 1
+
+if [ "$KERNEL_INAME" ] ; then
+ echo "## $INAME_FILE" >> $INAME_FILE
+ echo "$KERNEL_COMMENTS" >> $INAME_FILE
+ echo "InitiatorName=$KERNEL_INAME" >> $INAME_FILE
+elif [ "$IBFT_INAME" ] ; then
+ echo "## $INAME_FILE" >> $INAME_FILE
+ echo "$IBFT_COMMENTS" >> $INAME_FILE
+ echo "InitiatorName=$IBFT_INAME" >> $INAME_FILE
+else
echo "## $INAME_FILE" >> $INAME_FILE
echo "$NORMAL_COMMENTS" >> $INAME_FILE
# create a unique initiator name using iscsi-iname
INAME=$(@SBINDIR@/iscsi-iname -p "$IQN_PREFIX")
echo "InitiatorName=$INAME" >> $INAME_FILE
- chmod 0600 $INAME_FILE
fi
+
+chmod 0600 $INAME_FILE