diff options
author | Lee Duncan <lduncan@suse.com> | 2022-04-10 07:54:41 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-04-10 07:54:41 -0700 |
commit | d169831fd5c5afa9c3f5c0b17789791dfcea5208 (patch) | |
tree | efa94d391675800887c85247e9f66908b2dae382 | |
parent | 1451108792c1187974b87399f71822b59d62948c (diff) | |
parent | e1c491d59ffaeac367966b703f91eab4972a54f6 (diff) | |
download | open-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.template | 25 | ||||
-rw-r--r-- | utils/iscsi-gen-initiatorname.sh.template | 166 |
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 |