You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

247 lines
5.8 KiB

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