- 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

Reply via email to