tgt 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237
  1. #!/bin/sh /etc/rc.common
  2. START=91
  3. STOP=10
  4. EXTRA_COMMANDS="show"
  5. EXTRA_HELP=" show Show current configuration of tgtd"
  6. NAME=tgt
  7. PROG=/usr/sbin/tgtd
  8. USE_PROCD=1
  9. tgtadm="/usr/sbin/tgtadm --lld iscsi"
  10. logger="logger -p daemon.err -s -t $NAME"
  11. validate_lun_section() {
  12. uci_validate_section tgt lun $1 \
  13. 'device:or(file, device)' \
  14. 'type:or("disk", "cd", "pt"):disk' \
  15. 'bstype:or("rdwr", "aio", "sg"):rdwr' \
  16. 'sync:bool:0' \
  17. 'direct:bool:0' \
  18. 'blocksize:uinteger' \
  19. 'mode_page:string' \
  20. 'product_id:string' \
  21. 'product_rev:string' \
  22. 'readonly:bool:0' \
  23. 'removable:bool' \
  24. 'scsi_id:string' \
  25. 'scsi_sn:string' \
  26. 'sense_format:range(0, 1)' \
  27. 'vendor_id:string'
  28. }
  29. handle_lun() {
  30. local tgt_lun=$1
  31. local tgtid=$2
  32. local readonly device type bstype sync direct
  33. local my_tgtid=${tgt_lun%_*}
  34. local lun=${tgt_lun#*_}
  35. [ $my_tgtid -eq $tgtid ] || return 0
  36. validate_lun_section $tgt_lun || {
  37. $logger "Validation failed for LUN $tgt_lun"
  38. return 1
  39. }
  40. [ "$device" ] || {
  41. $logger "Device is required for target $tgt_lun"
  42. return 1
  43. }
  44. if [ $sync -ne 0 -o $direct -ne 0 ]; then
  45. local bsoflags
  46. [ $sync -ne 0 ] && bsoflags="sync"
  47. [ $direct -ne 0 ] && bsoflags="direct"
  48. [ $sync -ne 0 -a $direct -ne 0 ] && bsoflags="sync:direct"
  49. bsoflags="--bsoflags $bsoflags"
  50. fi
  51. blocksize=${blocksize+--blocksize=$blocksize}
  52. local params='' i
  53. for i in mode_page product_id product_rev readonly removable scsi_id scsi_sn sense_format vendor_id; do
  54. eval params=\${$i+$i=\$$i,}\$params
  55. done
  56. local _tgtadm="$tgtadm --mode logicalunit --tid $tgtid --lun $lun"
  57. $_tgtadm --op new --backing-store $device --device-type $type --bstype $bstype --bstype $bstype $bsoflags $blocksize || {
  58. $logger "Failed to create lun $tgt_lun"
  59. return 1
  60. }
  61. $_tgtadm --op update --param $params || {
  62. $logger "Failed to update lun $tgt_lun"
  63. return 1
  64. }
  65. }
  66. validate_account_section () {
  67. uci_validate_section tgt account $1 \
  68. 'target:list(uinteger)' \
  69. 'user:string' \
  70. 'password:string' \
  71. 'outgoing:bool:0'
  72. }
  73. handle_account() {
  74. local _tgtadm="$tgtadm --mode account"
  75. local user password target outgoing
  76. validate_account_section $1 || {
  77. $logger "Validation failed for account ${user:-$1}"
  78. return 1
  79. }
  80. [ "$user" ] || {
  81. $logger "User is required for account $1. Run 'uci show tgt.$1' and check options"
  82. return 1
  83. }
  84. [ "$target" ] || {
  85. $logger "Target is required for account $user"
  86. return 1
  87. }
  88. [ "$password" ] || {
  89. $logger "Password is required for account $user"
  90. return 1
  91. }
  92. $_tgtadm --op new --user "$user" --password "$password" || {
  93. $logger "Failed to create user $username"
  94. return 1
  95. }
  96. }
  97. bind_account_to_target() {
  98. local _tgtadm="$tgtadm --mode account"
  99. local tgtid=$2 user password outgoing
  100. validate_account_section $1 || {
  101. $logger "Validation failed for account ${user:-$1}"
  102. return 1
  103. }
  104. [ "$outgoing" -ne 0 ] && outgoing=--outgoing || outgoing=""
  105. local t
  106. for t in $target; do
  107. [ "$t" -eq "$tgtid" ] && {
  108. $_tgtadm --op bind --tid $tgtid --user "$user" $outgoing || {
  109. $logger "Failed to bind user $username to target $tgtid"
  110. return 1
  111. }
  112. }
  113. done
  114. return 0
  115. }
  116. validate_target_section() {
  117. uci_validate_section tgt target $1 \
  118. 'name:string:iqn.2012-06.org.openwrt' \
  119. 'allow_address:list(string):ALL' \
  120. 'allow_name:list(string)'
  121. }
  122. handle_target() {
  123. local tgtid=$1
  124. local _tgtadm="$tgtadm --mode target"
  125. local name allow
  126. [ $tgtid -ge 0 ] || return 1
  127. validate_target_section $tgtid || {
  128. $logger "Validation failed for target $tgtid"
  129. return 1
  130. }
  131. $_tgtadm --op new --tid $tgtid --targetname $name || {
  132. $logger "Failed to create target $tgtid"
  133. return 1
  134. }
  135. local i
  136. for i in $allow_address; do
  137. $_tgtadm --op bind --tid $tgtid --initiator-address $i || {
  138. $logger "Failed to set allow $i to connect to target $tgtid"
  139. return 1
  140. }
  141. done
  142. for i in $allow_name; do
  143. $_tgtadm --op bind --tid $tgtid --initiator-name $i || {
  144. $logger "Failed to set allow $i to connect to target $tgtid"
  145. return 1
  146. }
  147. done
  148. config_foreach handle_lun lun $tgtid || return 1
  149. config_foreach bind_account_to_target account $tgtid || return 1
  150. }
  151. configure() {
  152. config_load $NAME
  153. $tgtadm --mode sys --op update --name State -v offline || {
  154. $logger "Failed to set system state to Offline"
  155. return 1
  156. }
  157. config_foreach handle_account account || return 1
  158. config_foreach handle_target target || return 1
  159. $tgtadm --mode sys --op update --name State -v ready || {
  160. $logger "Failed to set system state to Ready"
  161. return 1
  162. }
  163. return 0
  164. }
  165. validate_tgt_section() {
  166. uci_validate_section tgt options $1 \
  167. 'iothreads:uinteger' \
  168. 'portal:list(string)' \
  169. 'nop_interval:uinteger' \
  170. 'nop_count:uinteger'
  171. }
  172. start_service() {
  173. local iothreads portal nop_interval nop_count
  174. validate_tgt_section tgt || {
  175. $logger "Validation failed for tgt options"
  176. return 1
  177. }
  178. procd_open_instance
  179. procd_set_param command $PROG -f
  180. [ "$iothreads" ] && procd_append_param command -t $iothreads
  181. [ "${portal}${nop_interval}${nop_count}" ] && {
  182. local iscsi="" i
  183. for i in nop_interval nop_count; do
  184. eval iscsi=\${$i+$i=\$$i,}\$iscsi
  185. done
  186. for i in $portal; do
  187. iscsi="portal=$i,$iscsi"
  188. done
  189. procd_append_param command --iscsi $iscsi
  190. }
  191. procd_set_param respawn
  192. procd_close_instance
  193. logger -p daemon.info -t $NAME -s "Configuration will be loaded in seconds"
  194. ( sleep 5; configure || { stop_service; exit 1; } ) &
  195. }
  196. stop_service() {
  197. $tgtadm --mode sys --op update --name State -v offline || {
  198. $logger "Failed to set system state to Offline"
  199. return 1
  200. }
  201. $tgtadm --mode target --op show \
  202. | awk '$1 == "Target" {sub(/:/,"",$2); print $2}' \
  203. | xargs -r -n1 $tgtadm --mode target --op delete --force --tid
  204. $tgtadm --mode sys --op delete
  205. }
  206. reload_service() {
  207. stop_service
  208. start_service
  209. }
  210. show() {
  211. $tgtadm --mode target --op show
  212. }