summaryrefslogtreecommitdiff
path: root/utils/iscsi-gen-initiatorname.sh.template
blob: 5c2bfdf85229958a2a2642025dd2e891acbd410a (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
#!/bin/bash
#
# iscsi-gen-initiatorname
#
# 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
#

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!
## 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:
##   # iscsi-gen-initiatorname -f
## to recreate an updated version of this file.
##"

NORMAL_COMMENTS="\
##
## Default iSCSI Initiatorname.
##
## 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."

# 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

    echo "Usage: $NAME [OPTIONS] -- generate an iSCSI initiatorname"
    echo "Where OPTIONS are from:"
    echo "   -h          print usage and exit"
    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 ;;
	f) FORCE=1 ;;
	p) IQN_PREFIX=${OPTARG} ;;
	?) usage_and_exit 1 ;;
    esac
done
shift $(($OPTIND-1))

if [ "$#" -gt 0 ] ; then
    echo "Error: Invalid argument(s): $*" 1>&2
    usage_and_exit 1
fi

if [ "$EUID" -ne 0 ] ; then
    echo "Error: You must be root to run this command" 1>&2
    usage_and_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 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

# 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
fi

chmod 0600 $INAME_FILE