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.

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