PageRenderTime 34ms CodeModel.GetById 22ms app.highlight 10ms RepoModel.GetById 1ms app.codeStats 0ms

/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
 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