
    p
fOV                         d Z ddlZddlZddlZddlmc mZ ddlmc mZ ddl	mc m
c mZ ddlmc m
c mZ ddlmZmZmZ g dZd Z G d de      Zg dZ G d d	e      Zy)
z>
Handle packages and modules to enable RDMA for IB networking
    N)	parse_docfind	getattrib)z/etc/dat.confz/etc/rdma/dat.confz/usr/local/etc/dat.confc           	         t        j                  d       t        |j                        }|t        j                  d       y t        |d      }|st        j                  d       y t        |d      }|st        j                  d       y t        |d      }|st        j                  d       y d	j                  t        d
t        |      d      D cg c]
  }|||dz     c}      }t        j                  dj                  ||             t        |||       j                          t        j                  d       y c c}w )Nz2Parsing SharedConfig XML contents for RDMA detailsz)Could not parse SharedConfig XML documentInstancez2Could not find <Instance> in SharedConfig documentrdmaIPv4AddresszYCould not find rdmaIPv4Address attribute on Instance element of SharedConfig.xml documentrdmaMacAddresszXCould not find rdmaMacAddress attribute on Instance element of SharedConfig.xml document:r      z$Found RDMA details. IPv4={0} MAC={1}zRDMA: device is set up)loggerverboser   xml_texterrorr   r   joinrangeleninfoformatRDMADeviceHandlerstart)
nd_versionshared_confxml_docinstance_elemrdma_ipv4_addrrdma_mac_addris          =/usr/lib/python3/dist-packages/azurelinuxagent/common/rdma.pysetup_rdma_devicer   '   s'   
NNGH,,-G@A*-MIJ}.?@Ng	im-=>Mf	h HH',QM0BA'FH"# ,Aa!e4 H IM
KK6==' ( nmZ@FFH
KK()
Hs   D>c                   H    e Zd ZdZdZd Zed        Zd Zd Z	d Z
d Zd	 Zy)
RDMAHandlerhv_network_directNc                 p   | j                   r| j                   S d}d}d}d}|dz  }t        j                  j                  |      s d}||z  }t	        j
                  ||z         yt        |d      5 }	 |j                  |      }|j                  |      }|ro|rm|j                  d	      d
   }	|	r|	j                         }	|j                  d	      d
   }
|
r|
j                         }
|	dk(  r|
| _         | j                   cddd       S n	 ddd       d}t	        j
                  ||z         y# 1 sw Y   $xY w)zRetrieve the firmware version information from the system.
           This depends on information provided by the Linux kernel.      /var/lib/hyperv/.kvp_pool_0z&Kernel does not provide the necessary z-information or the kvp daemon is not running.z'RDMA: Source file "%s" does not exist. Nrb    r   NdDriverVersionz'RDMA: NdDriverVersion not found in "%s")
r   ospathisfiler   r   openread	partitiondecode)selfkvp_key_sizekvp_value_sizedriver_info_sourcebase_kernel_err_msg	error_msg	pool_filekeyvaluekey_0value_0s              r   get_rdma_versionzRDMAHandler.get_rdma_versionO   sB    ????":FNNww~~01AI,,ILL%778$d+ 	ynn\2!~65MM'215E %#oog6q9G").."2 11*1#	 	   	" >	Y!334'	 	s   1BD,D,,D5c                      ddg} t        j                  d      \  }}|dk7  rt        d|z        | D ]8  }||v rt        j                  d|z          yt        j
                  d|z         : y	)
zILook for kvp daemon names in ps -ef output and return True/False
        
hypervkvpdhv_kvp_daemonzps -efr   zRDMA: ps -ef failed: %sz RDMA: kvp daemon (%s) is runningTz$RDMA: kvp daemon (%s) is not runningF)	shellutilrun_get_output	Exceptionr   r   r   )kvp_daemon_namesexitcodeps_outns       r   is_kvp_daemon_runningz!RDMAHandler.is_kvp_daemon_runningv   s     )/:$33H=&q=5>??! 	KAF{>BCEIJ	K     c                 ,   t        j                  d| j                  z         t        j                  d| j                  z        }|dk7  r6d}|dz  }t        j
                  || j                  | j                  fz         yt        j                  d       y)	zuLoad the kernel driver, this depends on the proper driver
           to be installed with the install_driver() methodzRDMA: probing module '%s'zmodprobe --first-time %sr   z#Could not load "%s" kernel module. z7Run "modprobe --first-time %s" as root for more detailsFz,RDMA: Loaded the kernel driver successfully.T)r   r   driver_module_namer@   runr   )r1   resultr6   s      r   load_driver_modulezRDMAHandler.load_driver_module   s     	/$2I2IIJ9D<S<SSTQ;=IRRILLT44d6M6MNN BCrH   c                     | j                   r;t        j                         r| j                          y t	        j
                  d       y t	        j
                  d       y )Nz;RDMA: check RDMA driver is disabled, skip installing driverz8RDMA: skip installing driver when ndversion not present
)r   confenable_check_rdma_driverinstall_driverr   r   r1   s    r   install_driver_if_neededz$RDMAHandler.install_driver_if_needed   s;    ??,,.##%YZKKSTrH   c                 .    t        j                  d       y)zqInstall the driver. This is distribution specific and must
           be overwritten in the child implementation.z*RDMAHandler.install_driver not implementedN)r   r   rR   s    r   rQ   zRDMAHandler.install_driver   s     	ABrH   c                     d| j                   z  }t        j                  |      \  }}t        j                  d       |rt        j                  d       yt        j                  d       y)z5Check if the network module is loaded in kernel spacezlsmod | grep ^%sz$RDMA: Checking if the module loaded.zRDMA: module loaded.TzRDMA: module not loaded.F)rJ   r@   rA   r   r   )r1   cmdstatusloaded_moduless       r   is_driver_loadedzRDMAHandler.is_driver_loaded   sW     4#:#::!*!9!9#!>:;KK././rH   c                     t        j                  d       t        j                  d      }|dk7  rt        j                  d       yy)zuReboot the system. This is required as the kernel module for
           the rdma driver cannot be unloaded with rmmodzRDMA: Rebooting system.zshutdown -r nowr   z!RDMA: Failed to reboot the systemN)r   r   r@   rK   r   )r1   rets     r   reboot_systemzRDMAHandler.reboot_system   s9     	-.mm-.!8LL<= rH   )__name__
__module____qualname__rJ   r   r<   staticmethodrG   rM   rS   rQ   rY   r\    rH   r   r!   r!   K   sB    ,J%N  $UC
	>rH   r!   c                       e Zd ZdZdZdZdZdZdZdZ	dZ
dZdZd Zd	 Zd
 Zd Zd Zd Zd Zd Zed        Zed        Zed        Zed        Zed        Zed        Zed        Zed        Zed        Zy)r   z^
    Responsible for writing RDMA IP and MAC address to the /dev/hvnd_rdma
    interface.
    z/dev/hvnd_rdmaz/sys/class/infinibandx      <   Nc                 .    || _         || _        || _        y )N)	ipv4_addrmac_addrr   )r1   rg   rh   r   s       r   __init__zRDMADeviceHandler.__init__   s    " $rH   c                 x    t        j                  d       | j                          t        j                  d       y )Nz!RDMA: starting device processing.z"RDMA: completed device processing.)r   r   processrR   s    r   r   zRDMADeviceHandler.start   s%    7889rH   c                 (   	 | j                   s&t        j                  d       | j                          y t        j                  d       | j	                          y # t
        $ r.}t        j                  dj                  |             Y d }~y d }~ww xY w)Nz%RDMA: provisioning SRIOV RDMA device.z.RDMA: provisioning Network Direct RDMA device.z#RDMA: device processing failed: {0})r   r   r   provision_sriov_rdmaprovision_network_direct_rdmarB   r   r   )r1   es     r   rk   zRDMADeviceHandler.process   sn    	J??CD))+LM224 	JLL>EEaHII	Js   1A %A 	B#$BBc                    t         j                  t        | j                         t	        j
                         s@t        j                  d       t         j                  | j                  | j                         y d}d}t        j                  d|z  d      \  }}|dk(  r|j                         }nt        j                  d       t        j                  d|z        \  }}|dk7  rt        j                  d	|z         y t        j                  d
|z        \  }}|dk(  rt        j                  d|t        j                         }|rat#        |j%                  d      d         }t#        |j%                  d      d         }|dkD  s
|dk(  rH|dkD  rCt        j                  d       d}n+t        j                  d       nt        j&                  d       |sjt         j)                  | j*                  | j,                  | j.                         t         j1                  | j*                  | j                  | j                         t         j                  | j                  | j                         y )Nz'RDMA: skip checking RDMA driver versionFr"   zmodprobe -R %s)chk_errr   z6RDMA: failed to resolve module name. Use original namezmodprobe %szRDMA: failed to load module %sz
modinfo %sz version:\s+(\d+)\.(\d+)\.(\d+)\Drd      z+Skip setting /dev/hvnd_rdma on 4.1 or laterTzLRDMA: hv_network_direct driver version not present, assuming 4.0.x or older.z5RDMA: failed to get module info on hv_network_direct.)r   update_dat_confdapl_config_pathsrg   rO   rP   r   r   update_network_interfacerh   r@   rA   stripr   research
IGNORECASEintgroupswarnwait_rdma_devicerdma_devdevice_check_timeout_secdevice_check_interval_secwrite_rdma_config_to_device)r1   skip_rdma_devicemodule_nameretcodeoutversionv1v2s           r   rn   z/RDMADeviceHandler.provision_network_direct_rdma   s   ))*;T^^L,,.KKAB66t}}dnnU ) //0@;0NX]^a<))+KKKPQ //0KLa<LL9KGH //{0JKa<ii CS"--XG*1-.*1-.6R1WaKK MN'+$jkKKOP..t<<d>\>\^99t~~t}}> 	224==$..QrH   c                    | j                         \  }}|r't        j                  d       | j                  |       y | j                  rt        j                  d       t
        j                  | j                  | j                  | j                         t
        j                  | j                  | j                  | j                         y t        j                  d       y )Nz0RDMA: provisioning multiple IP over IB addressesz,RDMA: provisioning single IP over IB addresszRDMA: missing IP address)read_ipoib_datar   r   provision_sriov_multiple_ibrg   r   wait_any_rdma_device	sriov_dirr   r   update_iboip_interfaceipoib_check_timeout_secipoib_check_interval_sec)r1   r8   r9   s      r   rm   z&RDMADeviceHandler.provision_sriov_rdma  s    ++-eKKJK,,U3^^KKFG224>>--t/M/MO44T^^,,d.K.KM KK23rH   c                    d}d}d}t         j                  j                  |      st        j                  d       yd }d }t        |d      5 }	 |j                  |      }|j                  |      }|rT|rR|j                  d      d   }|r|j                         }|d	k(  r(|j                  d      d   }|r|j                         }nnzd d d        |d	k(  r||fS y# 1 sw Y   xY w)
Nr$   r%   r&   zRDMA: can't read KVP pool 0)NNr'   r(   r   
IPoIB_Data)	r*   r+   r,   r   r   r-   r.   r/   r0   )	r1   r2   r3   r4   r:   r;   r7   r8   r9   s	            r   r   z!RDMADeviceHandler.read_ipoib_data  s     :ww~~01LL67$d+ 	ynn\2!~65MM'215E %,"'//'":1"="&-nn&6G 	  L 7##'	 	s   A<CC#c                 :   g }|j                  d      }t        |      dz
  }t        j                  d|d         }|rHt	        |j                  d      d         }||k7  rNt        j                  dj                  ||             y t        j                  dj                  |d                y t        d|dz         D ]  }t        j                  d||         }|r<|j                  d      d   }|j                  d      d   }	|j                  ||	f       Zt        j                  dj                  ||                 y  d	}
|
dkD  r@| j                  |      }|t        |      k(  ry t        j                  d       |
dz  }
|
dkD  r@t        j                  d
       y )N|rd   zNUMPAIRS:(\d+)r   z<RDMA: multiple IPs reported num={0} actual number of IPs={1}z2RDMA: failed to find number of IP addresses in {0}z([^:]+):(\d+\.\d+\.\d+\.\d+)z*RDMA: failed to find MAC/IP address in {0}re   z,RDMA: failed to set all IP over IB addresses)splitr   rw   matchrz   r{   r   r   r   r   appendupdate_iboip_interfacestimesleep)r1   r9   mac_ip_arrayvaluesnum_ipsr   numr   rh   rg   retrycounts               r   r   z-RDMADeviceHandler.provision_sriov_multiple_ib@  s~   S!f+/*F1I6ell1oa()Cg~[bbcfhopqLLMTTU[\]U^_`q'!)$ 		AHH<fQiHE <<?1-!LLOA.	##Xy$9:IPPQWXYQZ[\		 ai00>EL))JJqMQJE ai 	CDrH   c           	      &   d}t        j                  |      }d}|D ]  }t        j                  d|      sd }t	        t         j
                  j                  ||d            5 }|j                         }d d d        |s%t        j                  dj                  |             |j                         }t        j                  d|      }|s&t        j                  dj                  ||             d}|j                  |j                  d            }|D ]  }	|	d   |k(  sd}
	 d	d
d|dg}t        j                  |       d	dddj                  |	d         d|g}t        j                  |       |
dk(  r(t        j"                  dj                  |	d   |             |
r.|
dk7  r)t        j                  dj                  |	d   |             n|dz  }   |S # 1 sw Y   hxY w# t        j                  $ r}|j                   }
Y d }~d }~ww xY w)Nz/sys/class/netr   zib\w+addressz'RDMA: can't read address for device {0}z7.+(\w\w):(\w\w):(\w\w):\w\w:\w\w:(\w\w):(\w\w):(\w\w)\nz8RDMA: failed to parse address for device {0} address {1} iplinksetupaddraddz{0}/16rd   devz#RDMA: set address {0} to device {1}r   z0RDMA: failed to set IP address {0} on device {1})r*   listdirrw   r   r-   r+   r   r.   r   r   r   upperr{   r@   run_commandCommandError
returncoder   )r1   r   net_dirnicsr   nicrh   address_filer   mac_ipr[   
ip_commandr   s                r   r   z)RDMADeviceHandler.update_iboip_interfacesl  s   "zz'" .	C88Hc*Hbggll7C;< /',,./ FMMcRS~~'HHHWYabEW^^_bdlmn H}}U\\!_5H& !9(C/&*FE3%E
!--j9&*FE8??6RS9;UW\^a%b
!--j9 ax$I$P$PQWXYQZ\_$`asax%W%^%^_efg_hjm%no
-1.	` U/ /8 %11 /#../s%   #G$AG'G$	'H:HHc                 J   t        j                  d       ||z  }d}d }|sw||k  rrt        j                  d      \  }}|dk7  rt	        d      t        j                  d|t
        j                        }|rn"t        j                  |       |dz  }|s||k  rr|st	        d      d}t        j                  d	       d
j                  | |      }	t        j                  dj                  |	            dk7  rt	        dj                  |	            t        j                  d       y )NzWait for ib0 become availabler   ifconfig -a!Failed to list network interfacesib0rd   zib0 is not available   z:RDMA: configuring IPv4 addr and netmask on ipoib interface{0}/{1}zifconfig ib0 {0}zCould set addr to {0} on ib0z7RDMA: ipoib address and netmask configured on interface)r   r   r@   rA   rB   rw   rx   ry   r   r   r   rK   )
rg   timeout_seccheck_interval_sectotal_retriesrF   	found_ib0r[   outputnetmaskr   s
             r   r   z(RDMADeviceHandler.update_iboip_interface  s	   34#&88	M 1#22=AKCax CDD		%?IJJ)*FA M 1 233PQ	73==+22489Q>:AA$GHHMNrH   c                    t        j                  d       | D ]  }t        j                  dj                  |             t        j                  j                  |      s%t        j                  dj                  |             kt        j                  dj                  |             t        j                  |      }t        j                  ||      }t        j                  ||       t        j                  d        y t        d      )zs
        Looks at paths for dat.conf file and updates the ip address for the
        infiniband interface.
        z Updating DAPL configuration filezRDMA: trying {0}z"RDMA: DAPL config not found at {0}zRDMA: DAPL config is at: {0}z#RDMA: DAPL configuration is updatedNz;RDMA: DAPL configuration file not found at predefined paths)r   r   r   r*   r+   r,   fileutil	read_filer   replace_dat_conf_contents
write_filerB   )pathsrg   fcfgnew_cfgs        r   rs   z!RDMADeviceHandler.update_dat_conf  s     	67 	AKK*11!4577>>!$8??BDKK6==a@A$$Q'C'AAY G7+KK=>	 UVVrH   c                 V    d}dj                  |      }t        j                  |||       S )NzHofa-v2-ib0 u2.0 nonthreadsafe default libdaplofa.so.2 dapl.2.0 \"\S+ 0\"zFofa-v2-ib0 u2.0 nonthreadsafe default libdaplofa.so.2 dapl.2.0 "{0} 0")r   rw   sub)r   rg   oldnews       r   r   z+RDMADeviceHandler.replace_dat_conf_contents  s-    YX__vvc3$$rH   c                 0   t         j                  ||      }t        j                  dj	                  |             t        | d      5 }t        j                  d       |j                  |       d d d        t        j                  d       y # 1 sw Y   xY w)Nz-RDMA: Updating device with configuration: {0}wzRDMA: Device opened for writingz4RDMA: Updated device with IPv4/MAC addr successfully)r   generate_rdma_configr   r   r   r-   write)r+   rg   rh   datar   s        r   r   z-RDMADeviceHandler.write_rdma_config_to_device  sv     55iJ;BB4H	J$_ 	KK9:GGDM	 	JK	 	s   'BBc                 &    dj                  ||       S )Nz*rdmaMacAddress="{0}" rdmaIPv4Address="{1}")r   )rg   rh   s     r   r   z&RDMADeviceHandler.generate_rdma_config  s    ;BB8YWWrH   c                    t        j                  dj                  | |             ||z  }d}||k  ryt        j                  j                  |       rt        j                  d       y t        j                  dj                  |             t        j                  |       |dz  }||k  ryt        j                  d       t        dj                  ||            )Nz)RDMA: waiting for device={0} timeout={1}sr   zRDMA: device ready"RDMA: device not ready, sleep {0}srd   RDMA device wait timed out7The device did not show up in {0} seconds ({1} retries))r   r   r   r*   r+   existsr   r   r   r   rB   )r+   r   r   r   rF   s        r   r}   z"RDMADeviceHandler.wait_rdma_device  s    ?FFt[YZ#&88-ww~~d#01NN4;;<NOQJJ)*FA - 	12QXX( ) 	)rH   c                    t        j                  dj                  | |             ||z  }d}||k  rt        j                  |       }|r%t        j                  dj                  |              y t        j
                  dj                  |             t        j                  |       |dz  }||k  rt        j                  d       t        dj                  ||            )NzERDMA: waiting for any Infiniband device at directory={0} timeout={1}sr   zRDMA: device found in {0}r   rd   r   r   )
r   r   r   r*   r   r   r   r   r   rB   )	directoryr   r   r   rF   rs         r   r   z&RDMADeviceHandler.wait_any_rdma_device  s    SZZ;(	) $&88-

9%A7>>yIJNN4;;<NOQJJ)*FA - 	12QXX( ) 	)rH   c                 2   d}t        j                  d       t        j                  |       }t        j                  d|       t        j                  d       t	        j
                  dj                  |            dk7  rt        dj                  |            t        j                  d       d	j                  ||      }t	        j
                  d
j                  ||            dk7  rt        dj                  ||            t        j                  d       y )Nr   z5RDMA: will update the network interface with IPv4/MACz"RDMA: network interface found: {0}z#RDMA: bringing network interface upzifconfig {0} upr   z&Could not bring up RMDA interface: {0}z4RDMA: configuring IPv4 addr and netmask on interfacer   zifconfig {0} {1}zCould set addr to {1} on {0}z9RDMA: network address and netmask configured on interface)r   r   r   get_interface_by_macr@   rK   r   rB   )rh   rg   r   if_namer   s        r   ru   z*RDMADeviceHandler.update_network_interface  s    KL#88B8'B9:==*11':;q@DKKGTUUJK	73==+227DABaG:AA'4PQQOPrH   c                    t        j                  d      \  }}|dk7  rt        d      |j                  dd      }t	        j
                  dj                  |       |t        j                        }|t        dj                  |             |j                  d      }t	        j                  d|      }|t        |      dk(  rt        d	j                  |             |d
   S )Nr   r   r   
r   z(eth\d).*(HWaddr|ether) {0}z"Failed to get ifname with mac: {0}zeth\dzifname with mac: {0} not found)r@   rA   rB   replacerw   rx   r   ry   groupfindallr   )macr[   r   r   ethss        r   r   z&RDMADeviceHandler.get_interface_by_mac!  s    ..}=V!8?@@b)		8??D "--1=@GGLMMQzz(F+<3t9><CCCHIIBxrH   )r]   r^   r_   __doc__r~   r   r   r   r   r   rg   rh   r   ri   r   rk   rn   rm   r   r   r   r`   r   rs   r   r   r   r}   r   ru   r   ra   rH   r   r   r      s'   
  H'I" !  IHJ%
:
	J'RR4" D'EX6p O O2 W W, % % L L X X ) )  ) )& Q Q"  rH   r   )r   r*   rw   r   azurelinuxagent.common.confcommonrO   azurelinuxagent.common.loggerr   %azurelinuxagent.common.utils.fileutilutilsr   &azurelinuxagent.common.utils.shellutilr@   %azurelinuxagent.common.utils.textutilr   r   r   rt   r   objectr!   r   ra   rH   r   <module>r      sg   $ 
 	  * * . . 8 8 : : L L !Hl>& l>^F q qrH   