- allow to select multiple addresses and ports to listent to - support both address- and name-based ACLs (note: config option has been changed from "allow" to "allow_address", "allow_name") - support more optionf for LUNs - support various device types (disk, cd, sg passthrough) - bind accounts to multiple targets - use uci_validate_section in the init script - improve error reporting, use logger instead of echo
Note: this patch depends on http://patchwork.openwrt.org/patch/5586/ Signed-off-by: Maxim Storchak <m.storc...@gmail.com> --- net/tgt/files/etc/config/tgt | 48 +++++++---- net/tgt/files/etc/init.d/tgt | 190 ++++++++++++++++++++++++++++++++---------- 2 files changed, 180 insertions(+), 58 deletions(-) diff --git a/net/tgt/files/etc/config/tgt b/net/tgt/files/etc/config/tgt index 98b2206..7686a13 100644 --- a/net/tgt/files/etc/config/tgt +++ b/net/tgt/files/etc/config/tgt @@ -2,40 +2,58 @@ config options 'tgt' # iothreads limits number of worker threads per rdwr target, default is 16 # which seems to be too much for an avarage router option iothreads '2' -# option portal '0.0.0.0:3260' # option nop_count '3' -# option nop_interval '5' +# option nop_interval '1' +# list portal '[::1]' +# list portal '127.0.0.1:3261' +# list portal '0.0.0.0:3262' +# list portal '[::]:3263' config target 1 option name 'iqn.2012-06.org.openwrt:target1' - option allow ALL +# list allow_name 'iqn.1994-05.org.example:fedcba987654' +# list allow_address '192.168.1.0/27' #config target 2 # option name 'iqn.2012-06.org.openwrt:t2' -# option allow 192.168.1.0/24 - # all options are set to default, except for the device -# for all type and bstype values see tgtd(8) # lun "name" is constructed as TGTID_LUN #config lun 1_1 -# option readonly 0 -# option device /dev/sda -# option type disk -# option bstype rdwr -# option sync 0 -# option direct 0 - +# option 'device' '/dev/sda' +# type of scsi device. available options: disk, cd, pt (sg passthrough) +# option 'type' 'disk' +# backing store access method: rdwr (read-write), aio (async IO), sg (for pt type only, device must be /dev/sgN) +# option 'bstype' 'aio' +# set sync and/or direct flags when opening device, affect only rdwr +# option 'sync' '0' +# option 'direct' '0' +# block size for lun, default is 512 +# option 'blocksize' 4096 +# override SCSI mode page, see tgtadm man page for details +# option 'mode_page' 'string' +# vendor, product, revision, SCSI ID and SCSI Serial number +# option 'vendor_id' 'string' +# option 'product_id' 'string' +# option 'product_rev' 'string' +# option 'scsi_id' 'string' +# option 'scsi_sn' 'string' +# refuse write attempts. applies only to disk type +# option 'readonly' '0' +# Disk devices default to non-removable, cd - to removable +# option 'removable' '0' +# 0 = Clasic sense format, 1 = Support descriptor format. +# option 'sense_format' '0' #config lun 2_1 -# option readonly 0 # option device /mnt/iscsi.img #config lun 2_2 # option device /dev/sdc #config account -# option target 1 +# list target 1 +# list target 2 # option user "username1" # option password "pass1" diff --git a/net/tgt/files/etc/init.d/tgt b/net/tgt/files/etc/init.d/tgt index 82648b6..da03201 100755 --- a/net/tgt/files/etc/init.d/tgt +++ b/net/tgt/files/etc/init.d/tgt @@ -10,23 +10,45 @@ PROG=/usr/sbin/tgtd USE_PROCD=1 tgtadm="/usr/sbin/tgtadm --lld iscsi" +logger="logger -p daemon.err -s -t $NAME" + +validate_lun_section() { + uci_validate_section tgt lun $1 \ + 'device:file' \ + 'type:or("disk", "cd", "pt"):disk' \ + 'bstype:or("rdwr", "aio", "sg"):rdwr' \ + 'sync:bool:0' \ + 'direct:bool:0' \ + 'blocksize:uinteger' \ + 'mode_page:string' \ + 'product_id:string' \ + 'product_rev:string' \ + 'readonly:bool:0' \ + 'removable:bool' \ + 'scsi_id:string' \ + 'scsi_sn:string' \ + 'sense_format:range(0, 1)' \ + 'vendor_id:string' +} handle_lun() { local tgt_lun=$1 local tgtid=$2 - local ro device type bstype sync direct + local readonly device type bstype sync direct local my_tgtid=${tgt_lun%_*} local lun=${tgt_lun#*_} + [ $my_tgtid -eq $tgtid ] || return 0 - config_get device $1 device "" - [ "$device" ] || return 1 + validate_lun_section $tgt_lun || { + $logger "Validation failed for LUN $tgt_lun" + return 1 + } + [ "$device" ] || { + $logger "Device is required for target $tgt_lun" + return 1 + } - config_get type $1 type disk - config_get bstype $1 bstype rdwr - config_get_bool readonly $1 readonly 0 - config_get_bool sync $1 sync 0 - config_get_bool direct $1 direct 0 if [ $sync -ne 0 -o $direct -ne 0 ]; then local bsoflags [ $sync -ne 0 ] && bsoflags="sync" @@ -35,60 +57,136 @@ handle_lun() { bsoflags="--bsoflags $bsoflags" fi + blocksize=${blocksize+--blocksize=$blocksize} + local params='' i + for i in mode_page product_id product_rev readonly removable scsi_id scsi_sn sense_format vendor_id; do + eval params=\${$i+$i=\$$i,}\$params + done + local _tgtadm="$tgtadm --mode logicalunit --tid $tgtid --lun $lun" - $_tgtadm --op new --backing-store $device --device-type $type --bstype $bstype --bstype $bstype $bsoflags || return 1 - $_tgtadm --op update --param readonly=$readonly || return 1 + $_tgtadm --op new --backing-store $device --device-type $type --bstype $bstype --bstype $bstype $bsoflags $blocksize || { + $logger "Failed to create lun $tgt_lun" + return 1 + } + $_tgtadm --op update --param $params || { + $logger "Failed to update lun $tgt_lun" + return 1 + } +} + +validate_account_section () { + uci_validate_section tgt account $1 \ + 'target:list(uinteger)' \ + 'user:string' \ + 'password:string' \ + 'outgoing:bool:0' } handle_account() { - local tgtid=$2 local _tgtadm="$tgtadm --mode account" - local target user password outgoing + local user password target outgoing + + validate_account_section $1 || { + $logger "Validation failed for account ${user:-$1}" + return 1 + } + [ "$user" ] || { + $logger "User is required for account $1. Run 'uci show tgt.$1' and check options" + return 1 + } + [ "$target" ] || { + $logger "Target is required for account $user" + return 1 + } + [ "$password" ] || { + $logger "Password is required for account $user" + return 1 + } + $_tgtadm --op new --user "$user" --password "$password" || { + $logger "Failed to create user $username" + return 1 + } +} - config_get target $1 target "" - [ "$target" ] || return 1 - [ $target -eq $tgtid ] || return 0 +bind_account_to_target() { + local _tgtadm="$tgtadm --mode account" + local tgtid=$2 user password outgoing - config_get user $1 user "" - [ "$user" ] || return 1 + validate_account_section $1 || { + $logger "Validation failed for account ${user:-$1}" + return 1 + } - config_get password $1 password "" - config_get_bool outgoing $1 outgoing 0 [ "$outgoing" -ne 0 ] && outgoing=--outgoing || outgoing="" + local t + for t in $target; do + [ "$t" -eq "$tgtid" ] && { + $_tgtadm --op bind --tid $tgtid --user "$user" $outgoing || { + $logger "Failed to bind user $username to target $tgtid" + return 1 + } + } + done + return 0 +} - $_tgtadm --op new --user "$user" --password "$password" || return 1 - $_tgtadm --op bind --tid $tgtid --user "$user" $outgoing || return 1 +validate_target_section() { + uci_validate_section tgt target $1 \ + 'name:string:iqn.2012-06.org.openwrt' \ + 'allow_address:list(string):ALL' \ + 'allow_name:list(string)' } handle_target() { local tgtid=$1 - local tgtname allow local _tgtadm="$tgtadm --mode target" + local name allow [ $tgtid -ge 0 ] || return 1 - - config_get tgtname $1 name iqn.2012-06.org.openwrt - config_get allow $1 allow ALL - - $_tgtadm --op new --tid $tgtid --targetname $tgtname || return 1 - $_tgtadm --op bind --tid $tgtid -I $allow || return 1 - + validate_target_section $tgtid || { + $logger "Validation failed for target $tgtid" + return 1 + } + $_tgtadm --op new --tid $tgtid --targetname $name || { + $logger "Failed to create target $tgtid" + return 1 + } + local i + for i in $allow_address; do + $_tgtadm --op bind --tid $tgtid --initiator-address $i || { + $logger "Failed to set allow $i to connect to target $tgtid" + return 1 + } + done + for i in $allow_name; do + $_tgtadm --op bind --tid $tgtid --initiator-name $i || { + $logger "Failed to set allow $i to connect to target $tgtid" + return 1 + } + done config_foreach handle_lun lun $tgtid || return 1 - config_foreach handle_account account $tgtid || return 1 + config_foreach bind_account_to_target account $tgtid || return 1 } configure() { config_load $NAME - $tgtadm --mode sys --op update --name State -v offline || return 1 + $tgtadm --mode sys --op update --name State -v offline || { + $logger "Failed to set system state to Offline" + return 1 + } + config_foreach handle_account account || return 1 config_foreach handle_target target || return 1 - $tgtadm --mode sys --op update --name State -v ready || return 1 + $tgtadm --mode sys --op update --name State -v ready || { + $logger "Failed to set system state to Ready" + return 1 + } return 0 } validate_tgt_section() { uci_validate_section tgt options $1 \ 'iothreads:uinteger' \ - 'portal:string' \ + 'portal:list(string)' \ 'nop_interval:uinteger' \ 'nop_count:uinteger' } @@ -96,30 +194,36 @@ validate_tgt_section() { start_service() { local iothreads portal nop_interval nop_count validate_tgt_section tgt || { - echo "validation failed" + $logger "Validation failed for tgt options" return 1 } procd_open_instance procd_set_param command $PROG -f [ "$iothreads" ] && procd_append_param command -t $iothreads [ "${portal}${nop_interval}${nop_count}" ] && { - local iscsi - [ "$portal" ] && iscsi="portal=$portal" - [ "$nop_interval" ] && iscsi="nop_interval=$nop_interval,$iscsi" - [ "$nop_count" ] && iscsi="nop_count=$nop_count,$iscsi" + local iscsi="" i + for i in nop_interval nop_count; do + eval iscsi=\${$i+$i=\$$i,}\$iscsi + done + for i in $portal; do + iscsi="portal=$i,$iscsi" + done procd_append_param command --iscsi $iscsi } procd_set_param respawn procd_close_instance - logger -t $NAME -s "Configuration will be loaded in seconds" + logger -p daemon.info -t $NAME -s "Configuration will be loaded in seconds" ( sleep 5; configure || { stop_service; exit 1; } ) & } stop_service() { - $tgtadm --mode sys --op update --name State -v offline - $tgtadm --mode target --op show \ - | awk '$1 == "Target" {sub(/:/,"",$2); print $2}' \ - | xargs -n1 $tgtadm --mode target --op delete --force --tid + $tgtadm --mode sys --op update --name State -v offline || { + $logger "Failed to set system state to Offline" + return 1 + } + $tgtadm --mode target --op show \ + | awk '$1 == "Target" {sub(/:/,"",$2); print $2}' \ + | xargs -r -n1 $tgtadm --mode target --op delete --force --tid $tgtadm --mode sys --op delete } -- 1.7.10.4 _______________________________________________ openwrt-devel mailing list openwrt-devel@lists.openwrt.org https://lists.openwrt.org/cgi-bin/mailman/listinfo/openwrt-devel