/lib/qemu-toolkit/iscsi_target.rb

https://bitbucket.org/kschiess/qemu-toolkit · Ruby · 80 lines · 55 code · 15 blank · 10 comment · 8 complexity · a104f5ef97930629a385806fb8b5b119 MD5 · raw file

  1. module QemuToolkit
  2. class ISCSITarget
  3. def initialize(iqn, address, backend)
  4. @iqn, @address = iqn, address
  5. @backend = backend
  6. # Keep track if disks has ever returned an array of size > 0. This would
  7. # mean that the target is connected and will stay connected until we
  8. # change that.
  9. @mapped = false
  10. end
  11. attr_reader :iqn
  12. attr_reader :address
  13. def mapped?
  14. disks.size > 0
  15. end
  16. def ensure_exists
  17. # If the target is mapped already, nothing to do.
  18. return if mapped?
  19. # Map the target
  20. begin
  21. @backend.iscsiadm :add, 'static-config', "#{iqn},#{address}", '2>/dev/null'
  22. rescue
  23. # Ignore already mapped targets
  24. end
  25. print "Waiting for iSCSI disks to come online..."
  26. while !mapped?
  27. print '.'
  28. sleep 0.5 # takes a short while until login
  29. end
  30. puts 'OK.'
  31. end
  32. # A cached 'list target -vS'
  33. #
  34. def target_list
  35. @backend.iscsiadm :list, :target, '-vS'
  36. end
  37. def disks
  38. luns = []
  39. state = 0
  40. last_lun = nil
  41. target_list.each_line do |line|
  42. case state
  43. when 0
  44. state += 1 if line.match(/^Target: #{Regexp.escape(iqn)}\n/m)
  45. lun = nil
  46. when 1
  47. if md=line.match(/^\s+LUN: (\d+)\n/m)
  48. last_lun = md[1]
  49. end
  50. if last_lun && md=line.match(/^\s+OS Device Name: (\/dev\/rdsk\/.*)\n/m)
  51. luns << [Integer(last_lun), md[1]]
  52. end
  53. state += 1 if line.match(/^Target: /)
  54. end
  55. end
  56. luns.sort_by { |no,_| no }.map { |_, dev| p0ify(dev) }
  57. end
  58. private
  59. def p0ify(str)
  60. # /dev/rdsk/c4t600144F0503CC9000000503F8B09000Ad0s2 to
  61. # /dev/rdsk/c4t600144F0503CC9000000503F8B09000Ad0p0
  62. str.sub(/s2$/, 'p0')
  63. end
  64. end
  65. end