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.

251 lines
5.9 KiB

  1. #!/bin/sh /etc/rc.common
  2. START=91
  3. STOP=10
  4. extra_command "show" "Show current configuration of tgtd"
  5. NAME=tgt
  6. PROG=/usr/sbin/tgtd
  7. USE_PROCD=1
  8. tgtadm="/usr/sbin/tgtadm --lld iscsi"
  9. logger="logger -p daemon.err -s -t $NAME"
  10. validate_lun_section() {
  11. uci_load_validate tgt lun "$1" "$2" \
  12. 'device:or(file, device)' \
  13. 'type:or("disk", "cd", "pt"):disk' \
  14. 'bstype:or("rdwr", "aio", "sg"):rdwr' \
  15. 'sync:bool:0' \
  16. 'direct:bool:0' \
  17. 'blocksize:uinteger' \
  18. 'mode_page:string' \
  19. 'product_id:string' \
  20. 'product_rev:string' \
  21. 'readonly:bool:0' \
  22. 'removable:bool' \
  23. 'scsi_id:string' \
  24. 'scsi_sn:string' \
  25. 'sense_format:range(0, 1)' \
  26. 'vendor_id:string' \
  27. 'rotation_rate:uinteger'
  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 ] || [ "$direct" -ne 0 ]; then
  43. local bsoflags
  44. [ "$sync" -ne 0 ] && bsoflags="sync"
  45. [ "$direct" -ne 0 ] && bsoflags="direct"
  46. [ "$sync" -ne 0 ] && [ "$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 rotation_rate; 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. 'logging:bool:0'
  167. }
  168. start_tgt_instance() {
  169. local fg_flag=-f
  170. [ "$2" = 0 ] || {
  171. $logger "Validation failed for tgt options"
  172. return 1
  173. }
  174. procd_open_instance
  175. procd_set_param command $PROG
  176. [ "$logging" -eq 1 ] && fg_flag=-D
  177. procd_append_param command "$fg_flag"
  178. [ "$iothreads" ] && procd_append_param command -t "$iothreads"
  179. [ "$portal$nop_interval$nop_count" ] && {
  180. local iscsi="" i
  181. for i in nop_interval nop_count; do
  182. eval iscsi=\${$i+$i=\$$i,}\$iscsi
  183. done
  184. for i in $portal; do
  185. iscsi="portal=$i,$iscsi"
  186. done
  187. procd_append_param command --iscsi "$iscsi"
  188. }
  189. procd_set_param respawn
  190. procd_close_instance
  191. logger -p daemon.info -t "$NAME" -s "Configuration will be loaded in seconds"
  192. ( sleep 5; configure || { stop_service; exit 1; } ) &
  193. }
  194. start_service() {
  195. validate_tgt_section tgt start_tgt_instance
  196. }
  197. stop_service() {
  198. $tgtadm --mode sys --op update --name State -v offline || {
  199. $logger "Failed to set system state to Offline"
  200. return 1
  201. }
  202. $tgtadm --mode target --op show \
  203. | awk '$1 == "Target" {sub(/:/,"",$2); print $2}' \
  204. | xargs -r -n1 $tgtadm --mode target --op delete --force --tid
  205. $tgtadm --mode sys --op delete
  206. procd_kill tgt
  207. }
  208. reload_service() {
  209. stop_service
  210. start_service
  211. }
  212. service_triggers() {
  213. procd_add_reload_trigger "tgt"
  214. procd_open_validate
  215. validate_tgt_section
  216. validate_account_section
  217. validate_target_section
  218. validate_lun_section
  219. procd_close_validate
  220. }
  221. show() {
  222. $tgtadm --mode target --op show
  223. }