Class: Hmc

Inherits:
ConnectableServer show all
Defined in:
lib/rbvppc/hmc.rb

Instance Attribute Summary

Attributes inherited from ConnectableServer

#debug

Instance Method Summary collapse

Methods inherited from ConnectableServer

#connect, #connected?, #disconnect, #initialize, #toggle_debug

Constructor Details

This class inherits a constructor from ConnectableServer

Instance Method Details

#activate_lpar(frame, name, profile_name) ⇒ Object

Active an LPAR using a profile



336
337
338
# File 'lib/rbvppc/hmc.rb', line 336

def activate_lpar(frame,name,profile_name)
    execute_cmd "chsysstate -r lpar -m #{frame} -o on -n #{name} -f #{profile_name}"
end

#add_vscsi(frame, lpar, server_lpar) ⇒ Object

Add vSCSI to LPAR Handles adding to profile and via DLPAR



687
688
689
690
691
692
693
694
695
696
# File 'lib/rbvppc/hmc.rb', line 687

def add_vscsi(frame,lpar,server_lpar)
    #Add vscsi to client and server LPAR profiles
    #Save the adapter slots used
    client_slot, server_slot = add_vscsi_to_profile(frame, lpar, server_lpar)
    
    #Run DLPAR commands against LPARs themselves (if necessary)
    add_vscsi_dlpar(frame, lpar, server_lpar, client_slot, server_slot)
    
    return [client_slot, server_slot]
end

#add_vscsi_dlpar(frame, lpar, server_lpar, client_slot_to_use = nil, server_slot_to_use = nil) ⇒ Object

Add vSCSI adapter via DLPAR command



720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
# File 'lib/rbvppc/hmc.rb', line 720

def add_vscsi_dlpar(frame,lpar,server_lpar,client_slot_to_use = nil, server_slot_to_use = nil)
   if client_slot_to_use.nil? and server_slot_to_use.nil?
     client_slot_to_use = get_next_slot(frame,lpar)
     server_slot_to_use = get_next_slot(frame,server_lpar)
   end
   
   #If the client LPAR is running, we have to do DLPAR on it.
   if check_lpar_state(frame,lpar) == "Running"
     execute_cmd("chhwres -r virtualio -m #{frame} -p #{lpar} -o a --rsubtype scsi -s #{client_slot_to_use} -a \"adapter_type=client,remote_lpar_name=#{server_lpar},remote_slot_num=#{server_slot_to_use}\" ")
   end
   
   #If the server LPAR is running, we have to do DLPAR on it.
   if check_lpar_state(frame,server_lpar) == "Running"
     execute_cmd("chhwres -r virtualio -m #{frame} -p #{server_lpar} -o a --rsubtype scsi -s #{server_slot_to_use} -a \"adapter_type=server,remote_lpar_name=#{lpar},remote_slot_num=#{client_slot_to_use}\" ")
   end
   
   #chhwres -r virtualio -m "FrameName" -p VioName -o a --rsubtype scsi -s 11 -a "adapter_type=server,remote_lpar_name=ClientLPAR,remote_slot_num=5" 
end

#add_vscsi_to_profile(frame, lpar, server_lpar) ⇒ Object

Add vSCSI adapter to LPAR profile

Raises:

  • (StandardError)


699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
# File 'lib/rbvppc/hmc.rb', line 699

def add_vscsi_to_profile(frame,lpar,server_lpar)
   virtual_slot_num = get_next_slot(frame,lpar)
   remote_slot_num = get_next_slot(frame,server_lpar)
   lpar_profile = get_lpar_curr_profile(frame,lpar)
   remote_lpar_profile = get_lpar_curr_profile(frame,server_lpar)
   
   raise StandardError.new("No available virtual adapter slots on client LPAR #{lpar}") if virtual_slot_num.nil?
   raise StandardError.new("No available virtual adapter slots on server LPAR #{server_lpar}") if remote_slot_num.nil?
   
   #Modify client LPAR's profile
   execute_cmd("chsyscfg -r prof -m #{frame} -i \"name=#{lpar_profile},lpar_name=#{lpar},virtual_scsi_adapters+=#{virtual_slot_num}/client//#{server_lpar}/#{remote_slot_num}/0\" ")
   #Modify server LPAR's profile
   execute_cmd("chsyscfg -r prof -m #{frame} -i \"name=#{remote_lpar_profile},lpar_name=#{server_lpar},virtual_scsi_adapters+=#{remote_slot_num}/server//#{lpar}/#{virtual_slot_num}/0\" ")
   
   #chsyscfg -r prof -m "FrameName" -i "name=ClientLPAR_prof,lpar_name=ClientLPAR,virtual_scsi_adapters+=4/client//ServerLPAR/11/0"
   #chsyscfg -r prof -m "FrameName" -i "name=ServerLPAR_PROFILE,lpar_name=ServerLPAR,virtual_scsi_adapters+=11/server//ClientLPAR/4/0"
   #Return the client slot and server slot used in the LPAR profiles
   return [virtual_slot_num, remote_slot_num]
end

#assign_disk_vhost(frame, vio, disk, vtd, vhost) ⇒ Object

Assign Disk/Logical Volume to a vSCSI Host Adapter



464
465
466
467
# File 'lib/rbvppc/hmc.rb', line 464

def assign_disk_vhost(frame, vio, disk, vtd, vhost)
    command = "mkvdev -vdev #{disk.name} -dev #{vtd} -vadapter #{vhost}"
    execute_vios_cmd(frame, vio, command)
end

#check_lpar_state(frame, lpar) ⇒ Object

Get LPAR state



351
352
353
# File 'lib/rbvppc/hmc.rb', line 351

def check_lpar_state(frame, lpar)
    execute_cmd("lssyscfg -r lpar -m #{frame} --filter lpar_names=#{lpar} -F state").chomp
end

#clean_vadapter_string(vadapter_string) ⇒ Object



362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
# File 'lib/rbvppc/hmc.rb', line 362

def clean_vadapter_string(vadapter_string)
 if vadapter_string.chomp == "none"
   vadapter_string = ""
 end
 
 if vadapter_string.start_with?('"')
   vadapter_string = vadapter_string[1..-1]
 end
 
 if vadapter_string.end_with?('"')
   vadapter_string = vadapter_string[0..-2]
 end
 
 return vadapter_string
end

#create_lpar(hash) ⇒ Object

Create an LPAR



316
317
318
319
320
321
322
323
# File 'lib/rbvppc/hmc.rb', line 316

def create_lpar(hash)
    # frame,name,profile_name,max_virtual_slots,desired_mem,min_mem,max_mem,desired_procs,min_procs,max_procs,proc_mode,sharing_mode,desired_proc_units,max_proc_units,min_proc_units,uncap_weight)
    execute_cmd "mksyscfg -r lpar -m #{hash[:frame]} -i name=#{hash[:name]}, profile_name=#{hash[:profile_name]},boot_mode=norm," + 
         "auto_start=0,lpar_env=aixlinux,max_virtual_slots=#{hash[:max_virtual_slots]},desired_mem=#{hash[:desired_mem]}," + 
         "min_mem=#{hash[:min_mem]},max_mem=#{hash[:max_mem]},desired_procs=#{hash[:desired_procs]},min_procs=#{hash[:min_procs]}," + 
         "max_procs=#{hash[:max_procs]},proc_mode=#{hash[:proc_mode]},sharing_mode=#{hash[:sharing_mode]},desired_proc_units=#{hash[:desired_proc_units]}," + 
         "max_proc_units=#{hash[:max_proc_units]},min_proc_units=#{hash[:min_proc_units]},uncap_weight=#{hash[:uncap_weight]}" 
end

#create_vnic(frame, lpar_name, vlan_id, addl_vlan_ids, is_trunk, is_required) ⇒ Object

create vNIC on LPAR profile



867
868
869
870
871
872
873
874
875
876
877
# File 'lib/rbvppc/hmc.rb', line 867

def create_vnic(frame,lpar_name,vlan_id,addl_vlan_ids, is_trunk, is_required)
 ##chsyscfg -m Server-9117-MMA-SNxxxxx -r prof -i 'name=server_name,lpar_id=xx,"virtual_eth_adapters=596/1/596//0/1,506/1/506//0/1,"'
 #slot_number/is_ieee/port_vlan_id/"additional_vlan_id,additional_vlan_id"/is_trunk(number=priority)/is_required
 lpar_prof = get_lpar_curr_profile(frame,lpar_name)
 slot_number = get_next_slot(frame,lpar_name,"eth")
 #Going to assume adapter will always be ieee
 #For is Trunk how do we determine the number for priority? Do we just let the user pass it?
 result = execute_cmd("chsyscfg -m #{frame} -r prof -i \'name=#{lpar_prof},lpar_name=#{lpar_name},"+
                       "\"virtual_eth_adapters+=#{slot_number}/1/#{vlan_id}/\"#{addl_vlan_ids}" +
                       "\"/#{is_trunk}/#{is_required} \"\'")
end

#create_vnic_dlpar(frame, lpar_name, vlan_id) ⇒ Object

Create vNIC on LPAR via DLPAR As writen today defaulting ieee_virtual_eth=0 sets us to Not IEEE 802.1Q compatible. To add compatability set value to 1



881
882
883
884
# File 'lib/rbvppc/hmc.rb', line 881

def create_vnic_dlpar(frame, lpar_name,vlan_id)
   slot_number = get_next_slot(frame,lpar_name, "eth")
   result = execute_cmd("chhwres -r virtualio -m #{frame} -o a -p #{lpar_name} --rsubtype eth -s #{slot_number} -a \"ieee_virtual_eth=0,port_vlan_id=#{vlan_id}\"")
end

#defeat_rich_shomo(string) ⇒ Object



402
403
404
405
406
# File 'lib/rbvppc/hmc.rb', line 402

def defeat_rich_shomo(string)
    if (string == "I have never seen the movie Aliens") then
      return "Rich Defeated"
    end
end

#delete_lpar(frame, name) ⇒ Object

Delete an LPAR



326
327
328
# File 'lib/rbvppc/hmc.rb', line 326

def delete_lpar(frame,name)
    execute_cmd "rmsyscfg -r lpar -m #{frame} -n #{name}"
end

#execute_cmd(command) ⇒ Object

Execute commands on HMC setting language to US English



19
20
21
22
# File 'lib/rbvppc/hmc.rb', line 19

def execute_cmd(command)
    puts "export LANG=en_US.UTF-8;#{command}" if debug
    super "export LANG=en_US.UTF-8;#{command}"
end

#execute_vios_cmd(frame, vio, command) ⇒ Object

Execute VIOS commands via HMC



25
26
27
# File 'lib/rbvppc/hmc.rb', line 25

def  execute_vios_cmd(frame, vio, command)
    execute_cmd "viosvrcmd -m #{frame} -p #{vio} -c \" #{command} \""
end

#execute_vios_cmd_grep(frame, vio, command, grep_for) ⇒ Object

Execute VIOS commands via HMC grepping for a specific item.



30
31
32
# File 'lib/rbvppc/hmc.rb', line 30

def  execute_vios_cmd_grep(frame, vio, command, grep_for)
    execute_cmd "viosvrcmd -m #{frame} -p #{vio} -c \" #{command} \" | grep #{grep_for}"
end

#find_vhost_given_virtual_slot(frame, vio, server_slot) ⇒ Object

Find vhost to use when given the vSCSI adapter slot it occupies

Raises:

  • (StandardError)


558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
# File 'lib/rbvppc/hmc.rb', line 558

def find_vhost_given_virtual_slot(frame, vio, server_slot)
  command = "lsmap -all"
  
  #Execute an lsmap and grep for the line that contains the vhost
  #by finding the line that contains the physical adapter location.
  #This will definitely contain 'V#-C<slot number>' in it's name.
  result = execute_vios_cmd_grep(frame,vio,command,"V.-C#{server_slot}")
  raise StandardError.new("Unable to find vhost on #{vio} for vSCSI adapter in slot #{server_slot}") if result.nil?
  
  #Split the result on whitespace to get the columns
  #vhost, physical location, client LPAR ID (in hex)
  mapping_cols = result.split(/[[:blank:]]+/)
  
  #The name of the vhost will be in the first column of the command output
  return mapping_cols[0]
end

#get_attached_disknames(frame, vio, vhost) ⇒ Object

Get a list of all disknames attached to a vhost



576
577
578
579
580
581
# File 'lib/rbvppc/hmc.rb', line 576

def get_attached_disknames(frame,vio,vhost)
   cmd = "lsmap -vadapter #{vhost} -field backing -fmt :"
   diskname_output = execute_vios_cmd(frame,vio,cmd).chomp
   
   return diskname_output.split(/:/)
end

#get_frame_cpu(frame) ⇒ Object

Get Frame info - CPU/vCPU data



125
126
127
128
129
130
131
132
133
134
135
# File 'lib/rbvppc/hmc.rb', line 125

def get_frame_cpu(frame)
  info = execute_cmd("lshwres -r proc -m #{frame} --level sys")
  attributes = info.chomp.split(",")
  frame_hash = {}
  attributes.each do |line|
  	att,val = line.split("=")
  	frame_hash[att.to_sym]=val
  end
  
  return frame_hash
end

#get_frame_info(frame_id, field) ⇒ Object

Cobalt: function to find out more information (CPU and Memory) about a frame



297
298
299
300
301
302
# File 'lib/rbvppc/hmc.rb', line 297

def get_frame_info  frame_id, field
  res = {}
  output = execute_cmd("lshwres -m #{frame_id} -r #{field} --level sys")
  lines = output.nil? ? [] : output.split(",")
  lines.each {|line| key,val=line.split("="); res[key]=val unless key.nil? }    
end

#get_frame_mem(frame) ⇒ Object

Get Frame info - Memory Data



138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
# File 'lib/rbvppc/hmc.rb', line 138

def get_frame_mem(frame)
  info = execute_cmd("lshwres -r mem -m #{frame} --level sys")
  #Remove Substrings that are surrounded by double quotes
  quoted_substrings = info.chomp.match(/"[^"]+"/)
  info.gsub!(/"[^"]+"/, "")
      
 	#Handle strings that are not quoted
  attributes = info.chomp.split(",")
  frame_hash = {}
  attributes.each do |line|
 	  att,val = line.split("=")
    frame_hash[att.to_sym]=val
  end

 	#Find used memory by subtracting available from total
  used_mem = frame_hash[:configurable_sys_mem].to_i - frame_hash[:curr_avail_sys_mem].to_i
  frame_hash[:used_mem]=used_mem.to_s
	
 	#Handle strings that are quoted checking for more than one
  quoted_substrings = quoted_substrings.to_s
  #match on "," 
 	unless quoted_substrings.match(/\"(.*)\",\"(.*)\"/)
    substring = quoted_substrings.to_s.chomp.split("=")
    substring.each do |line|
     line.gsub!("\"","")
    end
    temp_str = substring[1]
    ratios = temp_str.split(',')
    frame_hash[:"#{substring[0]}"]=ratios
	else
    quoted = quoted_substrings.chomp.split('","')
    quoted.each do |line|
      line.gsub!("\"","")
   att,val = line.split('=')
      ratios = val.split(',')
      frame_hash[att.to_sym]=ratios
    end
  end
             
  return frame_hash
end

#get_frame_specs(frame) ⇒ Object

Get Frame info- type,model,serial number



105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
# File 'lib/rbvppc/hmc.rb', line 105

def get_frame_specs(frame)
 	info = execute_cmd("lssyscfg -r sys -m #{frame}")
	attributes = info.chomp.split(",")
	frame_hash = {}
	attributes.each do |line|
att,val = line.split("=")
case att
when "name"
	frame_hash[:name]=val
when "type_model"
	frame_hash[:type_model]=val
when "serial_num"
	frame_hash[:serial_num]=val
end
	end

	return frame_hash
end

#get_lpar_curr_profile(frame, lpar, filter = "lpar_name") ⇒ Object

Get the Current Profile of an LPAR



181
182
183
184
# File 'lib/rbvppc/hmc.rb', line 181

def get_lpar_curr_profile(frame, lpar, filter = "lpar_name")
 curr_prof = execute_cmd "lssyscfg -r lpar -m #{frame} --filter #{filter}s=#{lpar} -F curr_profile"
return curr_prof.chomp
end

#get_lpar_def_profile(frame, lpar, filter = "lpar_name") ⇒ Object

Get the Default Profile of an LPAR



187
188
189
190
# File 'lib/rbvppc/hmc.rb', line 187

def get_lpar_def_profile(frame, lpar, filter = "lpar_name")
  def_prof = execute_cmd "lssyscfg -r lpar -m #{frame} --filter #{filter}s=#{lpar} -F default_profile"
 return def_prof.chomp
end

#get_lpar_id(frame, lpar) ⇒ Object

Get the ID of an LPAR



752
753
754
755
# File 'lib/rbvppc/hmc.rb', line 752

def get_lpar_id(frame, lpar)
 lpar_id = execute_cmd "lssyscfg -r lpar -m #{frame} --filter lpar_names=#{lpar} -F lpar_id"
 return lpar_id.chomp
end

#get_lpar_options(frame, lpar, filter = "lpar_name") ⇒ Object

Get the general attributes of an lpar by specifying the frame and lpar names as Strings. Returns an options hash representing that LPAR



195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
# File 'lib/rbvppc/hmc.rb', line 195

def get_lpar_options(frame, lpar, filter = "lpar_name")
  profile_name = get_lpar_curr_profile(frame, lpar, filter)
  info = execute_cmd "lssyscfg -r prof -m \'#{frame}\' --filter profile_names=\'#{profile_name}\',lpar_names=\'#{lpar}\' "
                #"-F name,lpar_name,lpar_id,min_mem,desired_mem,max_mem,proc_mode,min_proc_units," + 
                #"desired_proc_units,max_proc_units,min_procs,desired_procs,max_procs,sharing_mode,uncap_weight,max_virtual_slots"
    attributes = info.chomp.split(",")
    lpar_hash = {}
    attributes.each do |line|
        att,val = line.split("=")
        case att
        when "name"
            lpar_hash[:current_profile]=val
        when "lpar_name"
            lpar_hash[:name]=val
        when "lpar_id"
            lpar_hash[:id]=val
        when "min_mem"
            lpar_hash[:min_mem]=val
        when "desired_mem"
            lpar_hash[:des_mem]=val
        when "max_mem"
            lpar_hash[:max_mem]=val
        when "proc_mode"
            lpar_hash[:proc_mode]=val
        when "min_proc_units"
            lpar_hash[:min_proc]=val
        when "desired_proc_units"
            lpar_hash[:des_proc]=val
        when "max_proc_units"
            lpar_hash[:max_proc]=val
        when "min_procs"
            lpar_hash[:min_vcpu]=val
        when "desired_procs"
            lpar_hash[:des_vcpu]=val
        when "max_procs"
            lpar_hash[:max_vcpu]=val
        when "sharing_mode"
            lpar_hash[:sharing_mode]=val
        when "uncap_weight"
            lpar_hash[:uncap_weight]=val
        when "max_virtual_slots"
            lpar_hash[:max_virt_slots]=val
        end
    end
    lpar_hash[:hmc]=self
    lpar_hash[:frame]=frame
    
    return lpar_hash
end

#get_mac_address(frame, client_lpar) ⇒ Object

Get the MAC address of an LPAR



357
358
359
360
# File 'lib/rbvppc/hmc.rb', line 357

def get_mac_address(frame, client_lpar)
  result = execute_cmd "lshwres -r virtualio --rsubtype eth --level lpar -m #{frame} -F mac_addr --filter \"lpar_names=#{client_lpar}\" "
  return result.chomp
end

#get_max_virtual_slots(frame, lpar) ⇒ Object

Returns 30 when test in dublin lab on frame: rslppc03 lpar:dwin004



780
781
782
783
784
785
# File 'lib/rbvppc/hmc.rb', line 780

def get_max_virtual_slots(frame, lpar)
    #max_slots = execute_cmd "lshwres --level lpar -r virtualio --rsubtype slot  -m #{frame} --filter lpar_names=#{lpar} -F curr_max_virtual_slots"
    lpar_prof = get_lpar_curr_profile(frame,lpar)
    max_slots = execute_cmd "lssyscfg -r prof -m '#{frame}' --filter 'lpar_names=#{lpar},profile_names=#{lpar_prof}' -F max_virtual_slots"
    return max_slots.chomp.to_i
end

#get_next_slot(frame, lpar, type = nil) ⇒ Object

Get next usable virtual slot on an LPAR Returns nil if no usable slots exist



850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
# File 'lib/rbvppc/hmc.rb', line 850

def get_next_slot(frame,lpar, type = nil)
  max_slots = get_max_virtual_slots(frame,lpar)
  used_slots = get_used_virtual_slots(frame,lpar)
  lowest_slot=11
  if !type.nil?
   lowest_slot=2 if type == "eth"
  end
  
  lowest_slot.upto(max_slots) do |n|
   if !used_slots.include?(n)
    return n
   end
  end
  return nil
end

#get_releaseObject

Get the HMC Release



40
41
42
# File 'lib/rbvppc/hmc.rb', line 40

def get_release
    execute_cmd("lshmc -V | grep 'Release:'|cut -d':' -f2").chomp
end

#get_used_virtual_slots(frame, lpar) ⇒ Object

Return array of used virtual adapter slots for an LPAR



789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
# File 'lib/rbvppc/hmc.rb', line 789

def get_used_virtual_slots(frame, lpar)
    #scsi_slot_output = execute_cmd "lshwres -r virtualio --rsubtype scsi -m #{frame} --level lpar --filter lpar_names=#{lpar} -F slot_num"
    #eth_slot_output = execute_cmd "lshwres -r virtualio --rsubtype eth -m #{frame} --level lpar --filter lpar_names=#{lpar} -F slot_num"
    #serial_slot_output = execute_cmd "lshwres -r virtualio --rsubtype serial -m #{frame} --level lpar --filter lpar_names=#{lpar} -F slot_num"
    lpar_prof = get_lpar_curr_profile(frame,lpar)
    
    scsi_slot_output = clean_vadapter_string(execute_cmd "lssyscfg -r prof -m '#{frame}' --filter 'lpar_names=#{lpar},profile_names=#{lpar_prof}' -F virtual_scsi_adapters")
    serial_slot_output = clean_vadapter_string(execute_cmd "lssyscfg -r prof -m '#{frame}' --filter 'lpar_names=#{lpar},profile_names=#{lpar_prof}' -F virtual_serial_adapters")
    eth_slot_output = clean_vadapter_string(execute_cmd "lssyscfg -r prof -m '#{frame}' --filter 'lpar_names=#{lpar},profile_names=#{lpar_prof}' -F virtual_eth_adapters")
    used_slots = []
    
    if scsi_slot_output.include?(",")
     scsi_slots = scsi_slot_output.split(/,/)
    else
     scsi_slots = [scsi_slot_output]
    end
    
    if serial_slot_output.include?(",")
     serial_slots = serial_slot_output.split(/,/)
    else
     serial_slots = [serial_slot_output]
    end
    
    if eth_slot_output.include?(",")
     eth_slots = eth_slot_output.split(/,/)
    else
     eth_slots = [eth_slot_output]
    end
    
    scsi_slots.each do |adapter_line|
     if !adapter_line.empty?
      parse_hash = parse_vscsi_syntax(adapter_line)
      used_slots.push(parse_hash[:virtual_slot_num].to_i)
     end
    end
    
    serial_slots.each do |adapter_line|
     if !adapter_line.empty?
      parse_hash = parse_vserial_syntax(adapter_line)
      used_slots.push(parse_hash[:virtual_slot_num].to_i)
     end
    end
    
    eth_slots.each do |adapter_line|
     if !adapter_line.empty?
      parse_hash = parse_vnic_syntax(adapter_line)
      used_slots.push(parse_hash[:virtual_slot_num].to_i)
     end
    end
    
    #slot_output.each_line do |line|
    # line.chomp!
    # if !line.empty?
    #  used_slots.push(line.to_i)
    # end
    #end
    return used_slots
end

#get_versionObject

Get the HMC version



35
36
37
# File 'lib/rbvppc/hmc.rb', line 35

def get_version
    execute_cmd("lshmc -V | grep 'Version:'|cut -d':' -f2").chomp
end

#get_vio_version(frame, vio) ⇒ Object

Get VIOS version



488
489
490
491
# File 'lib/rbvppc/hmc.rb', line 488

def get_vio_version(frame, vio)
    command = "ioslevel"
    execute_vios_cmd(frame, vio, command)
end

#get_vscsi_adapters(frame, lpar) ⇒ Object

Returns array of output with vSCSI adapter information about the client LPAR



764
765
766
767
768
769
770
771
772
773
774
775
776
777
# File 'lib/rbvppc/hmc.rb', line 764

def get_vscsi_adapters(frame, lpar)
    #Get this LPAR's profile name
    lpar_prof = get_lpar_curr_profile(frame,lpar)
    
    #Get vSCSI adapter info from this LPAR's profile
    scsi_adapter_output = clean_vadapter_string(execute_cmd("lssyscfg -r prof -m #{frame} --filter 'lpar_names=#{lpar},profile_names=#{lpar_prof}' -F virtual_scsi_adapters").chomp)
    
    if scsi_adapter_output.include?(",")
     scsi_adapters = scsi_adapter_output.split(/,/)
    else
     scsi_adapters = [scsi_adapter_output]
    end
    return scsi_adapters
end

#hard_shutdown_lpar(frame, name) ⇒ Object

Hard shutdown LPAR



341
342
343
# File 'lib/rbvppc/hmc.rb', line 341

def hard_shutdown_lpar(frame,name)
    execute_cmd "chsysstate -r lpar -m #{frame} -o shutdown --immed -n #{name}"
end

#is_connected?Boolean

Validate connection to hmc is established

Returns:

  • (Boolean)


287
288
289
290
291
292
293
294
# File 'lib/rbvppc/hmc.rb', line 287

def is_connected?
     version = get_version
     if version.nil?
       return false
     else
       return true
     end     
end

#list_all_io_adapters(frame) ⇒ Object

Show all I/O adapters on the frame Doesn’t work malformed command



741
742
743
# File 'lib/rbvppc/hmc.rb', line 741

def list_all_io_adapters(frame)
    execute_cmd "lshwres -r io -m #{frame} --rsubtype slot --filter -F lpar_name:drc_name:description"
end

#list_all_mapped_disks(frame, vio) ⇒ Object

List all Disk Mappings



518
519
520
521
522
523
524
525
526
527
528
529
530
531
# File 'lib/rbvppc/hmc.rb', line 518

def list_all_mapped_disks(frame, vio)
    command = "lsmap -all -type disk"
    result = execute_vios_cmd_grep(frame, vio, command, "Backing")
    mapped_disks = []
    result.each_line do |line|
     line.chomp!
     line_elements=line.split(/[[:blank:]]+/)
     #3rd element should be disk name, since first is 'Backing' and
     #the second is 'device'
     disk_name = line_elements[2]
     mapped_disks.push(disk_name) if !mapped_disks.include?(disk_name)
    end
    return mapped_disks
end

#list_available_disks(frame, vio) ⇒ Object

List unmapped disks on VIOS

lspv -free  doesn't include disks that have been mapped before and contain a 'VGID'


501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
# File 'lib/rbvppc/hmc.rb', line 501

def list_available_disks(frame,vio )
    command = "lspv -avail -fmt : -field name pvid size"
    all_disk_output = execute_vios_cmd(frame, vio, command)
    mapped_disks = list_all_mapped_disks(frame,vio)
    unmapped_disks = []
    all_disk_output.each_line do |line|
     line.chomp!
     disk_name,disk_pvid,disk_size = line.split(/:/)
     if !mapped_disks.include?(disk_name)
       unmapped_disks.push(Lun.new(disk_name,disk_pvid,disk_size))
     end
    end
    
    return unmapped_disks
end

#list_framesObject

List the Frames managed by HMC



45
46
47
48
49
50
51
52
53
54
# File 'lib/rbvppc/hmc.rb', line 45

def list_frames
    out_array = []
    result = execute_cmd "lssyscfg -r sys -F name"
    result.each_line do |x|
      x.chomp!
      out_array.push(x)
    end      
    #Return the output array
    return out_array	
end

#list_io_adapters_on_lpar(frame, lpar) ⇒ Object

Show I/O adapters on a specific LPAR No results found when testing in dublin lab



747
748
749
# File 'lib/rbvppc/hmc.rb', line 747

def list_io_adapters_on_lpar(frame, lpar)
    execute_cmd "lshwres -r io -m #{frame} --rsubtype slot -F lpar_name:description --filter \"lpar_names=#{lpar}\""
end

#list_lpars_on_frame(frame) ⇒ Object

List LPARs on a frame



57
58
59
60
61
62
63
64
65
# File 'lib/rbvppc/hmc.rb', line 57

def list_lpars_on_frame(frame)
  result = execute_cmd "lssyscfg -r prof -m #{frame} -F lpar_name"
  lpar_arr = []
  result.each_line do |line|
    line.chomp!
    lpar_arr.push(line)
  end
  return lpar_arr
end

#list_shared_eth_adapters(frame, vio) ⇒ Object

List Shared Ethernet Adapters on VIOS



482
483
484
485
# File 'lib/rbvppc/hmc.rb', line 482

def list_shared_eth_adapters(frame,vio)
    command = "lsmap -all -net"
    execute_vios_cmd(frame, vio, command)
end

#list_status_of_lpars(frame = nil) ⇒ Object

Show status of lpars on frame (Power 5/6/7) Sample output dwin004:Running rslpl004:Running



254
255
256
257
258
259
260
# File 'lib/rbvppc/hmc.rb', line 254

def list_status_of_lpars(frame = nil)
    if frame.nil?
        #return lpars on all frames?
    else
     execute_cmd "lssyscfg -m #{frame} -r lpar -F name:state"
    end
end

#list_vios_on_frame(frame) ⇒ Object

List VIOS on a frame



86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
# File 'lib/rbvppc/hmc.rb', line 86

def list_vios_on_frame(frame)
	vios = []
	result = exectue_cmd "lssyscfg -r lpar -m #{frame} -F name,lpar_env | grep vioserver"
	result.each_line do |line|
		line = line.chomp!
		line_arr = line.split(',')
		line_arr.each do |field|
			if field == "vioserver"
				#We don't want to see "vioserver" in the array only the actual vios names
		    else
		vios.push(field)
	end
end
	end
			
	return vios
end

#list_vlans_on_frame(frame) ⇒ Object

List VLANs on a frame



69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
# File 'lib/rbvppc/hmc.rb', line 69

def list_vlans_on_frame(frame)
  vlans =[]
  result = execute_cmd "lshwres -r virtualio --rsubtype vswitch -m #{frame} -F"
  result.each_line do |line|
    line = line.chomp!
    line = line.delete "\""
    line_arr = line.split(',')
    line_arr.each do |field|
      vlans.push(field.to_str) if field.numeric?
    end

  end

  return vlans
end

#lpar_net_boot(nim_ip, lpar_ip, gateway, subnetmask, lpar) ⇒ Object

Netboot an lpar



273
274
275
276
277
278
279
280
281
282
283
284
# File 'lib/rbvppc/hmc.rb', line 273

def lpar_net_boot(nim_ip, lpar_ip, gateway, subnetmask, lpar)
    result = execute_cmd("lpar_netboot -t ent -D -s auto -d auto -A -f -S #{nim_ip} " +
                "-C #{lpar_ip} -G #{gateway} -K #{subnetmask} \"#{lpar.name}\" " + 
                "\"#{lpar.current_profile}\" \"#{lpar.frame}\" ")
    result = result.each_line do |line|
     line.chomp!
     line.match(/Network boot proceeding/) do |m|
      return true
     end
    end
    return false
end

#parse_slash_delim_string(slash_string, field_specs) ⇒ Object



440
441
442
443
444
445
446
447
448
449
# File 'lib/rbvppc/hmc.rb', line 440

def parse_slash_delim_string(slash_string, field_specs)
   # slash_string = "596/1/596//0/1"
   # field_specs = [:virtual_slot_num, :client_or_server, :remote_lpar_id...]
   values = slash_string.split(/\//)
   result = {}
   field_specs.each_index do |i|
      result[field_specs[i]] = values[i]
   end
   return result
end

#parse_vnic_syntax(vnic_string) ⇒ Object



378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
# File 'lib/rbvppc/hmc.rb', line 378

def parse_vnic_syntax(vnic_string)
  
  return parse_slash_delim_string(vnic_string,
          [:virtual_slot_num, :is_ieee, :port_vlan_id, :additional_vlan_ids, :is_trunk, :is_required]) if !vnic_string.empty?
  
=begin
  vnic_attributes = vnic_string.split(/\//)
  slot_num = vnic_attributes[0]
  is_ieee = vnic_attributes[1]
  port_vlan_id = vnic_attributes[2]
  additional_vlan_ids = vnic_attributes[3]
  is_trunk = vnic_attributes[4]
  is_required = vnic_attributes[5]
  
  return { :virtual_slot_num => slot_num,
           :is_ieee => is_ieee,
           :port_vlan_id => port_vlan_id,
           :additional_vlan_ids => additional_vlan_ids,
           :is_trunk => is_trunk,
           :is_required => is_required
         }
=end
end

#parse_vscsi_syntax(vscsi_string) ⇒ Object



409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
# File 'lib/rbvppc/hmc.rb', line 409

def parse_vscsi_syntax(vscsi_string)
  
  return parse_slash_delim_string(vscsi_string, 
          [:virtual_slot_num, :client_or_server, :remote_lpar_id, :remote_lpar_name, :remote_slot_num, :is_required]) if !vscsi_string.empty?
  
=begin
  vscsi_attributes = vscsi_string.split(/\//)
  virtual_slot_num = vscsi_attributes[0]
  client_or_server = vscsi_attributes[1]
  remote_lpar_id = vscsi_attributes[2]
  remote_lpar_name = vscsi_attributes[3]
  remote_slot_num = vscsi_attributes[4]
  is_required = vscsi_attributes[5]
  
  return { :virtual_slot_num => virtual_slot_num,
           :client_or_server => client_or_server,
           :remote_lpar_id => remote_lpar_id,
           :remote_lpar_name => remote_lpar_name,
           :remote_slot_num => remote_slot_num,
           :is_required => is_required
         }
=end
end

#parse_vserial_syntax(vserial_string) ⇒ Object



433
434
435
436
437
# File 'lib/rbvppc/hmc.rb', line 433

def parse_vserial_syntax(vserial_string)

  return parse_slash_delim_string(vserial_string,
           [:virtual_slot_num, :client_or_server, :supports_hmc, :remote_lpar_id, :remote_lpar_name, :remote_slot_num, :is_required]) if !vserial_string.empty?
end

#reboot_hmcObject

Reboot the HMC



246
247
248
# File 'lib/rbvppc/hmc.rb', line 246

def reboot_hmc
    execute_cmd "hmcshutdown -t now -r"
end

#reboot_vio(frame, vio) ⇒ Object

Reboot VIOS



494
495
496
497
# File 'lib/rbvppc/hmc.rb', line 494

def reboot_vio(frame,vio)
    command ="shutdown -restart"
    execute_vios_cmd(frame,vio,command)
end

#recursive_remove_vhost(frame, vio, vhost) ⇒ Object

Recursively remove a Virtual SCSI Host Adapter



458
459
460
461
# File 'lib/rbvppc/hmc.rb', line 458

def recursive_remove_vhost(frame, vio, vhost)
    command = "rmdev -dev #{vhost} -recursive"
    execute_vios_cmd(frame, vio, command)
end

#remove_all_disks_from_lpar(frame, lpar) ⇒ Object

Removes all disks/vhosts/vSCSIs from a client LPAR and it’s VIOs



584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
# File 'lib/rbvppc/hmc.rb', line 584

def remove_all_disks_from_lpar(frame,lpar)
   #Get all vscsi adapters on lpar
   vscsi_adapters = get_vscsi_adapters(frame,lpar)
   
   vscsi_adapters.each do |adapter|
     #Parse the adapter syntax into a hash
     adapter_hash = parse_vscsi_syntax(adapter)
     #Find the adapter slot on the VIO that this occupies
     server_slot = adapter_hash[:remote_slot_num]
     #Find the name of the VIO that this attaches to
     vio_name = adapter_hash[:remote_lpar_name]
     #Find the vhost that this represents, given the adapter slot
     vhost = find_vhost_given_virtual_slot(frame,vio_name,server_slot)
     #Find the list of disknames that are attached to this vhost
     disknames = get_attached_disknames(frame,vio_name,vhost)
     disknames.each do |hdisk|
       #Remove each disk from the vhost it's assigned to
       remove_disk_from_vhost(frame,vio_name,hdisk)
     end
     #Remove the vhost itself
     remove_vhost(frame,vio_name,vhost)
     #After all disks and the vhost are removed,
     #remove the vSCSI adapter from both the VIO and the client LPAR
     remove_vscsi(frame,lpar,vio_name,adapter)
   end
end

#remove_disk_from_vhost(frame, vio, diskname) ⇒ Object

Remove physical disk from vhost adapter



476
477
478
479
# File 'lib/rbvppc/hmc.rb', line 476

def remove_disk_from_vhost(frame,vio,diskname)
   command = "rmvdev -vdev #{diskname}"
   execute_vios_cmd(frame, vio, command)
end

#remove_vhost(frame, vio, vhost) ⇒ Object

Remove a Virtual SCSI Host Adapter



452
453
454
455
# File 'lib/rbvppc/hmc.rb', line 452

def remove_vhost(frame, vio, vhost)
    command = "rmdev -dev #{vhost}"
    execute_vios_cmd(frame, vio, command)
end

#remove_vscsi(frame, lpar, server_lpar, adapter_details = nil) ⇒ Object

Remove vSCSI from LPAR Handles removing from the LPAR profiles as well as DLPAR Last parameter is optional and if it isn’t specified then it looks for an adapter on lpar that is attached to server_lpar and removes that from the profile/hardware of both the client and server



617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
# File 'lib/rbvppc/hmc.rb', line 617

def remove_vscsi(frame,lpar,server_lpar,adapter_details=nil)
 if adapter_details.nil?
  adapters = get_vscsi_adapters(frame,lpar)
  adapters.each do |adapter|
   adapter_details = adapter if adapter.include?(server_lpar)
  end
 end
 
 #Parse the adapter details into a hash
 adapter_hash = parse_vscsi_syntax(adapter_details)
 
 #Remove this vSCSI from the lpar and server lpar profiles
 remove_vscsi_from_profile(frame,lpar,server_lpar,adapter_hash)
 
 #Remove this vSCSI from the actual hardware of lpar and server lpar
 remove_vscsi_dlpar(frame,lpar,server_lpar,adapter_hash)
 
end

#remove_vscsi_dlpar(frame, lpar, server_lpar, vscsi_hash) ⇒ Object

Remove vSCSI from LPARs via DLPAR



667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
# File 'lib/rbvppc/hmc.rb', line 667

def remove_vscsi_dlpar(frame,lpar,server_lpar,vscsi_hash)
   
   client_slot = vscsi_hash[:virtual_slot_num]
   server_slot = vscsi_hash[:remote_slot_num]
   
   #If the client LPAR is running, we have to do DLPAR on it.
   #if check_lpar_state(frame,lpar) == "Running"
     #execute_cmd("chhwres -r virtualio -m #{frame} -p #{lpar} -o r --rsubtype scsi -s #{client_slot}")
     #-a \"adapter_type=client,remote_lpar_name=#{server_lpar},remote_slot_num=#{server_slot}\" ")
   #end
   
   #If the server LPAR is running, we have to do DLPAR on it.
   if check_lpar_state(frame,server_lpar) == "Running"
     execute_cmd("chhwres -r virtualio -m #{frame} -p #{server_lpar} -o r --rsubtype scsi -s #{server_slot}")
     #-a \"adapter_type=server,remote_lpar_name=#{lpar},remote_slot_num=#{client_slot}\" ")
   end
end

#remove_vscsi_from_profile(frame, lpar, server_lpar, vscsi_hash) ⇒ Object

Remove vSCSI from the LPAR profiles only



637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
# File 'lib/rbvppc/hmc.rb', line 637

def remove_vscsi_from_profile(frame,lpar,server_lpar,vscsi_hash)
   lpar_profile = get_lpar_curr_profile(frame,lpar)
   remote_lpar_profile = get_lpar_curr_profile(frame,server_lpar)
   client_lpar_id = get_lpar_id(frame,lpar)
   
   #TODO: Add checking of vscsi_hash to make sure it's populated
   #      the way it's expected to be
   
   client_slot = vscsi_hash[:virtual_slot_num]
   server_lpar_id = vscsi_hash[:remote_lpar_id]
   if server_lpar != vscsi_hash[:remote_lpar_name]
    #server_lpar and the LPAR cited in the
    #vscsi hash aren't the same...
    #error out or do something else here...?
   end
   server_slot = vscsi_hash[:remote_slot_num]
   is_req = vscsi_hash[:is_required]
   
   #Modify client LPAR's profile to no longer include the adapter
   #whose details occupy the vscsi_hash
   execute_cmd("chsyscfg -r prof -m #{frame} -i \"name=#{lpar_profile},lpar_name=#{lpar}," +
               "virtual_scsi_adapters-=#{client_slot}/client/#{server_lpar_id}/#{server_lpar}/#{server_slot}/#{is_req}\" ")
               
   #Modify the server LPAR's profile to no longer include the client
   execute_cmd("chsyscfg -r prof -m #{frame} -i \"name=#{remote_lpar_profile},lpar_name=#{server_lpar}," +
               "virtual_scsi_adapters-=#{server_slot}/server/#{client_lpar_id}/#{lpar}/#{client_slot}/#{is_req}\" ")
 
end

#remove_vtd_from_vhost(frame, vio, vtd) ⇒ Object

Remove Disk/Logical Volume from vSCSI Host Adapter



470
471
472
473
# File 'lib/rbvppc/hmc.rb', line 470

def remove_vtd_from_vhost(frame, vio, vtd)
    command = "rmvdev -vtd #{vtd}"
    execute_vios_cmd(frame, vio, command)
end

#rename_lpar(frame, oldname, newname) ⇒ Object

Rename an LPAR



331
332
333
# File 'lib/rbvppc/hmc.rb', line 331

def rename_lpar(frame, oldname, newname)
    execute_cmd "chsyscfg -r lpar -m #{frame} -i \'name=#{oldname},new_name=#{newname}\'"
end

#select_any_avail_disk(frame, vio1, vio2) ⇒ Object



533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
# File 'lib/rbvppc/hmc.rb', line 533

def select_any_avail_disk(frame, vio1, vio2)
    primary_vio_disks = list_available_disks(frame,vio1) 
    secondary_vio_disks = list_available_disks(frame,vio2)
    
    return {} if primary_vio_disks.empty? or secondary_vio_disks.empty?
    
    vio1_lun = primary_vio_disks[0]
    vio2_lun = nil
    secondary_vio_disks.each do |lun|
     if vio1_lun == lun
      vio2_lun = lun
      break
     end
    end
    
    if vio2_lun.nil?
     raise StandardError.new("LUN with PVID #{vio1_lun.pvid} not found on #{vio2}")
    end
    # return [vio1_disk_name, vio2_disk_name]
    # return [vio1_lun, vio2_lun]
    return {:on_vio1 => vio1_lun, :on_vio2 => vio2_lun}
end

#set_lpar_proc_units(frame, lpar, units) ⇒ Object

Set the processing units for an lpar



758
759
760
# File 'lib/rbvppc/hmc.rb', line 758

def set_lpar_proc_units(frame, lpar, units)
    execute_cmd "chhwres -r proc -m #{frame} -o a -p #{lpar} --procunits #{units} "
end

#soft_shutdown_lpar(frame, lpar) ⇒ Object

Soft shutdown an LPAR



346
347
348
# File 'lib/rbvppc/hmc.rb', line 346

def soft_shutdown_lpar(frame, lpar)
    execute_cmd "chsysstate -r lpar -m #{frame} -o shutdown -n #{lpar}"
end

#view_dlpar_statusObject

Overview DLPAR Status



263
264
265
# File 'lib/rbvppc/hmc.rb', line 263

def view_dlpar_status
    execute_cmd "lspartition -dlpar"
end

#view_hmc_filesystem_spaceObject

Show available filesystem space on the hmc



268
269
270
# File 'lib/rbvppc/hmc.rb', line 268

def view_hmc_filesystem_space
    execute_cmd "monhmc -r disk -n 0"
end