-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathiscsi
executable file
·331 lines (275 loc) · 9.88 KB
/
iscsi
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
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
#!/bin/sh
################################################################################
#
# OCF resource agent to manage a Linux-IO backing LUN
# Copyright (c) 2014 Linn Products Ltd.
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License along
# with this program; if not, write to the Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
#
################################################################################
: ${OCF_FUNCTIONS_DIR=${OCF_ROOT}/lib/heartbeat}
. ${OCF_FUNCTIONS_DIR}/ocf-shellfuncs
TCM_SYSFS=/sys/kernel/config/target/core
ISCSI=/sys/kernel/config/target/iscsi
#####################################################
# Listen to 0.0.0.0:3260 by default
OCF_RESKEY_portals_default="0.0.0.0:3260"
: ${OCF_RESKEY_portals=${OCF_RESKEY_portals_default}}
# Default ALUA target port group is default_tg_pt_gp
OCF_RESKEY_alua_tpg_default="default_tg_pt_gp"
: ${OCF_RESKEY_alua_tpg=${OCF_RESKEY_alua_tpg_default}}
iscsi_meta_data()
{
cat <<END
<?xml version="1.0"?>
<!DOCTYPE resource-agent SYSTEM "ra-api-1.dtd">
<resource-agent name="iscsi">
<version>1.0</version>
<longdesc lang="en">
The iscsi resource manages a Linux-IO (LIO) iSCSI Target
including LUN ACL mapping.
</longdesc>
<shortdesc lang="en">
Linux-IO iSCSI Target
</shortdesc>
<parameters>
<parameter name="iqn" required="1" unique="0">
<longdesc lang="en">
The target iSCSI Qualified Name (IQN). Should follow the conventional
"iqn.yyyy-mm.<reversed domain name>[:identifier]" syntax.
</longdesc>
<shortdesc lang="en">iSCSI target IQN</shortdesc>
<content type="string" />
</parameter>
<parameter name="portals" required="0" unique="0">
<longdesc lang="en">
iSCSI network portal addresses. if unset, the default is
to create a portal that listens on ${OCF_RESKEY_portals_default}.
</longdesc>
<shortdesc lang="en">iSCSI Portal addresses</shortdesc>
<content type="string" default="${OCF_RESKEY_portals_default}"/>
</parameter>
<parameter name="initiators" required="1" unique="0">
<longdesc lang="en">
Allowed initiators. A space-separated list of initiators allowed to
connect to this target. Initiators may be listed in any syntax
the LIO target implementation allows.
</longdesc>
<shortdesc lang="en">List of iSCSI initiators allowed to connect to this target</shortdesc>
<content type="string" />
</parameter>
<parameter name="luns" required="1" unique="0">
<longdesc lang="en">
The logical units to create as part of this target. Each logical unit is
specified as a lun:hba/name triplet. Separate multiple logical units with
spaces. Use shell syntax to escape special characters.
</longdesc>
<shortdesc lang="en">Logical Units</shortdesc>
<content type="string" />
</parameter>
<parameter name="alua_tpg" required="0" unique="0">
<longdesc lang="en">
ALUA Target Port Group to set on all exported LUNs via this RA. The string
"@hostname@" in the TPG name will be replaced with the current node's hostname.
</longdesc>
<shortdesc lang="en">ALUA Target Port Group</shortdesc>
<content type="string" default="${OCF_RESKEY_alua_tpg_default}"/>
</parameter>
</parameters>
<actions>
<action name="start" timeout="40" />
<action name="stop" timeout="10" />
<action name="status" timeout="10" interval="10" />
<action name="monitor" timeout="10" interval="10" />
<action name="meta-data" timeout="5" />
<action name="validate-all" timeout="10" />
</actions>
</resource-agent>
END
}
iscsi_methods()
{
cat <<-!
start
stop
status
monitor
meta-data
validate-all
!
}
iscsi_usage()
{
cat <<END
usage: $0 {start|stop|status|monitor|meta-data|validate-all}
END
}
find_hbadev()
{
local hba_list
local hba
local hbadev
local hba_type="${1%%/*}"
local lun_name="${1#*/}"
# list all HBAs of the configured type
hba_list=$(ls -1 $TCM_SYSFS | egrep "^${hba_type}_[0-9]+$")
for hba in $hba_list; do
hbadev="${hba}/${lun_name}"
if [ -d "${TCM_SYSFS}/${hbadev}" ]; then
echo "${hbadev}"
return 0
fi
done
return 1
}
#OCF_RESKEY_portals
#OCF_RESKEY_iqn
#OCF_RESKEY_initiators
#OCF_RESKEY_luns
iscsi_monitor()
{
# if target_core_mod isn't loaded, we can't be running
[ -e /sys/kernel/config/target/version ] || return $OCF_NOT_RUNNING
# if IQN does not exist we can't be running
[ -d /sys/kernel/config/target/iscsi/${OCF_RESKEY_iqn} ] || return $OCF_NOT_RUNNING
return $OCF_SUCCESS
}
iscsi_status()
{
# just call through to monitor
iscsi_monitor
}
iscsi_start()
{
# check if we have anything to do
iscsi_monitor; rc=$?
if [ $rc -eq $OCF_SUCCESS ]; then
ocf_log info "Resource is already running"
return $OCF_SUCCESS
fi
# load target_core_mod if it isn't already
if ! [ -e /sys/kernel/config/target/version ]; then
ocf_run modprobe target_core_mod; rc=$?
if [ $rc -ne 0 ]; then
return $OCF_ERR_GENERIC
fi
fi
# create the iSCSI Target Portal. This should also
# generate the default target port group.
for portal in ${OCF_RESKEY_portals}; do
ocf_run lio_node --addnp ${OCF_RESKEY_iqn} 1 \
${portal} || return $OCF_ERR_GENERIC
done
# add node ACL for each initiator target port group
for initiator in ${OCF_RESKEY_initiators}; do
ocf_run lio_node --addnodeacl ${OCF_RESKEY_iqn} 1 \
${initiator} || return $OCF_ERR_GENERIC
done
## FIXME: support authentication - disabled for now
ocf_run lio_node --disableauth ${OCF_RESKEY_iqn} 1 || return $OCF_ERR_GENERIC
## FIXME: add support for params
for lun in ${OCF_RESKEY_luns}; do
lun_id="${lun%%:*}"
lun_hbaname="${lun#*:}"
hbadev=$(find_hbadev "$lun_hbaname")
if [ -z "$hbadev" ]; then
ocf_log err "HBA device does not exist"
return $OCF_ERR_GENERIC
fi
ocf_run lio_node --addlun=${OCF_RESKEY_iqn} 1 ${lun_id} lun${lun_id} \
${hbadev} || return $OCF_ERR_GENERIC
if [ "$OCF_RESKEY_alua_tpg" != "$OCF_RESKEY_alua_tpg_default" ]; then
# Replace @hostname@ with our short hostname
OCF_RESKEY_alua_tpg="$(echo "$OCF_RESKEY_alua_tpg" | \
sed "s/@hostname@/$(hostname -s)/g")"
ocf_run lio_node --setaluatpg=${OCF_RESKEY_iqn} 1 ${lun_id} \
"$OCF_RESKEY_alua_tpg" || return $OCF_ERR_GENERIC
fi
for initiator in ${OCF_RESKEY_initiators}; do
ocf_run lio_node --addlunacl=${OCF_RESKEY_iqn} 1 \
${initiator} ${lun_id} ${lun_id} || return $OCF_ERR_GENERIC
done
done
## Enable TPG group after LUNS are enabled.
if [ "$(cat "${ISCSI}/${OCF_RESKEY_iqn}/tpgt_1/enable")" -ne 1 ]; then
ocf_run lio_node --enabletpg=${OCF_RESKEY_iqn} 1 || return $OCF_ERR_GENERIC
fi
return $OCF_SUCCESS
}
iscsi_stop()
{
## FIXME: must be a cleaner way to do this
## instead of all these if statements
## disable iSCSI Target port group first
## This will block I/O
if [ -d "${ISCSI}/${OCF_RESKEY_iqn}/tpgt_1" ]; then
if [ "$(cat "${ISCSI}/${OCF_RESKEY_iqn}/tpgt_1/enable")" -ne 0 ]; then
ocf_run lio_node --disabletpg=${OCF_RESKEY_iqn} 1 || return $OCF_ERR_GENERIC
fi
fi
## remove acls from each initiator for target port group
## remove LUN ACLs first then node ACLs
if [ -d "${ISCSI}/${OCF_RESKEY_iqn}/tpgt_1/acls" ]; then
initiator_list=$(ls -1 ${ISCSI}/${OCF_RESKEY_iqn}/tpgt_1/acls)
for initiator in $initiator_list; do
acl_list=$(ls -1 ${ISCSI}/${OCF_RESKEY_iqn}/tpgt_1/acls/$initiator | egrep "^lun_[0-9]+$")
for acl in $acl_list; do
acl_lun_id=${acl#*_}
ocf_run lio_node --dellunacl=${OCF_RESKEY_iqn} 1 ${initiator} ${acl_lun_id} || return $OCF_ERR_GENERIC
done
ocf_run lio_node --delnodeacl ${OCF_RESKEY_iqn} 1 ${initiator} || return $OCF_ERR_GENERIC
done
fi
## remove each lun for target port group
if [ -d "${ISCSI}/${OCF_RESKEY_iqn}/tpgt_1/lun" ]; then
lun_list=$(ls -1 ${ISCSI}/${OCF_RESKEY_iqn}/tpgt_1/lun | egrep "^lun_[0-9]+$")
for lun in $lun_list; do
lun_id=${lun#*_}
ocf_run lio_node --dellun=${OCF_RESKEY_iqn} 1 ${lun_id} || return $OCF_ERR_GENERIC
done
fi
## remove target port group
if [ -d "${ISCSI}/${OCF_RESKEY_iqn}/tpgt_1" ]; then
ocf_run lio_node --deltpg=${OCF_RESKEY_iqn} 1 || return $OCF_ERR_GENERIC
fi
## remove IQN
if [ -d "${ISCSI}/${OCF_RESKEY_iqn}" ]; then
ocf_run lio_node --deliqn=${OCF_RESKEY_iqn} || return $OCF_ERR_GENERIC
fi
## FIXME: if the last target clean up and unload kernel module
return $OCF_SUCCESS
}
iscsi_validate_all()
{
# ensure configfs is mounted
if [ ! -d /sys/kernel/config ]; then
ocf_run modprobe configfs; rc=$?
if [ $rc - ne 0 ]; then
ocf_log err "unable to load the configfs module"
return $OCF_ERR_INSTALLED
fi
fi
if ! grep -q '/sys/kernel/config configfs' /proc/mounts; then
ocf_run mount -t configfs configfs /sys/kernel/config; rc=$?
if [ $rc - ne 0]; then
ocf_log err "Unable to mount configfs on /sys/kernel/config"
return $OCF_ERR_INSTALLED
fi
fi
return $OCF_SUCCESS
}
OCF_REQUIRED_PARAMS="iqn initiators luns"
OCF_REQUIRED_BINARIES="lio_node"
ocf_rarun $*