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