summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLee Duncan <lduncan@suse.com>2022-04-10 07:54:41 -0700
committerGitHub <noreply@github.com>2022-04-10 07:54:41 -0700
commitd169831fd5c5afa9c3f5c0b17789791dfcea5208 (patch)
treeefa94d391675800887c85247e9f66908b2dae382
parent1451108792c1187974b87399f71822b59d62948c (diff)
parente1c491d59ffaeac367966b703f91eab4972a54f6 (diff)
downloadopen-iscsi-d169831fd5c5afa9c3f5c0b17789791dfcea5208.tar.gz
Merge pull request #336 from gonzoleeman/use-kernel-initiatorname-if-present
Use kernel initiatorname if present
-rw-r--r--doc/iscsi-gen-initiatorname.8.template25
-rw-r--r--utils/iscsi-gen-initiatorname.sh.template166
2 files changed, 146 insertions, 45 deletions
diff --git a/doc/iscsi-gen-initiatorname.8.template b/doc/iscsi-gen-initiatorname.8.template
index e10a4ac..97a6e21 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,26 @@ 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.
+.P
+You
+.B must
+be
+.I root
+to run this command.
.SH OPTIONS
.TP
.BI [-h]
diff --git a/utils/iscsi-gen-initiatorname.sh.template b/utils/iscsi-gen-initiatorname.sh.template
index 3fa8dcc..5c2bfdf 100644
--- a/utils/iscsi-gen-initiatorname.sh.template
+++ b/utils/iscsi-gen-initiatorname.sh.template
@@ -2,26 +2,52 @@
#
# 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="\
##
## iSCSI Initiatorname taken from iBFT BIOS tables.
##
-## DO NOT EDIT OR REMOVE THIS FILE!
+## DO NOT EDIT OR REMOVE THIS FILE!
## 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
+## If a different initiatorname is required please change the
+## initiatorname in the BIOS setup and call:
+## # iscsi-gen-initiatorname -f
## to recreate an updated version of this file.
##"
@@ -29,12 +55,20 @@ NORMAL_COMMENTS="\
##
## Default iSCSI Initiatorname.
##
-## DO NOT EDIT OR REMOVE THIS FILE!
+## 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 prefix for generated IQN (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 ;;
@@ -58,45 +112,77 @@ done
shift $(($OPTIND-1))
if [ "$#" -gt 0 ] ; then
- echo "Invalid argument(s): $*"
- usage_and_exit
+ echo "Error: Invalid argument(s): $*" 1>&2
+ 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
+if [ "$EUID" -ne 0 ] ; then
+ echo "Error: You must be root to run this command" 1>&2
+ usage_and_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
+# 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
+ usage_and_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 the 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 the 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