Repository URL to install this package:
| 
      
        
        
        Version: 
        
         
          
          3.4.52  ▾
        
         | 
ó
±EYc           @   sÚ   d  d l  Z  d  d l m Z d  d l m Z d  d l m Z d  d l m	 Z	 d  d l
 m Z d  d l m Z d  d l
 m Z d  d	 l m Z d  d
 l m Z e j Z e j e  Z d e f d     YZ e d
  Z d S(   iÿÿÿÿN(   t   cfg(   t   log(   t	   jsonutils(   t	   exception(   t   _LW(   t   objects(   t   fields(   t   stats(   t	   whitelistt
   PciDevTrackerc           B   s¹   e  Z d  Z d d  Z d   Z d   Z e d    Z d   Z	 e
 d    Z d   Z d   Z
 d	   Z d
   Z d   Z d   Z d d
  Z d   Z d   Z d   Z d   Z RS(   sj  Manage pci devices in a compute node.
    This class fetches pci passthrough information from hypervisor
    and tracks the usage of these devices.
    It's called by compute node resource tracker to allocate and free
    devices to/from instances, and to update the available pci passthrough
    devices information from hypervisor periodically.
    `pci_devs` attribute of this class is the in-memory "master copy" of all
    devices on each compute host, and all data changes that happen when
    claiming/allocating/freeing
    devices HAVE TO be made against instances contained in `pci_devs` list,
    because they are periodically flushed to the DB when the save()
    method is called.
    It is unsafe to fetch PciDevice objects elsewhere in the code for update
    purposes as those changes will end up being overwritten when the `pci_devs`
    are saved.
    c         C   s¯   t  t |   j   i  |  _ | |  _ t j t j  |  _	 t
 j d |  j	  |  _
 | |  _ | r| t
 j j | |  |  _ n t
 j d g   |  _ |  j |  j  |  j   d S(   s  Create a pci device tracker.
        If a node_id is passed in, it will fetch pci devices information
        from database, otherwise, it will create an empty devices list
        and the resource tracker will update the node_id information later.
        t
   dev_filterR   N(   t   superR	   t   __init__t   stalet   node_idR   t	   Whitelistt   CONFt   pci_passthrough_whitelistR
   R   t   PciDeviceStatst   _contextR   t
   PciDeviceListt   get_by_compute_nodet   pci_devst   _build_device_treet   _initial_instance_usage(   t   selft   contextR   (    (    sE   /home/tvault/.virtenv/lib/python2.7/site-packages/nova/pci/manager.pyR   8   s    				c         C   sÅ   t  j t  |  _ t  j t  |  _ x |  j D] } | j } | j t j	 j
 k ri |  j | j |  q. | j t j	 j k r |  j | j |  q. | j t j	 j
 k r. |  j j |  q. q. Wd  S(   N(   t   collectionst   defaultdictt   listt   allocationst   claimsR   t
   instance_uuidt   statusR   t   PciDeviceStatust   CLAIMEDt   appendt	   ALLOCATEDt	   AVAILABLER   t
   add_device(   R   t   devt   uuid(    (    sE   /home/tvault/.virtenv/lib/python2.7/site-packages/nova/pci/manager.pyR   N   s    	c         C   sr   xk |  j  D]` } | j   r
 | j |  : | j   | j t j j k ra |  j  j j	 |  n  Wd  QXq
 q
 Wd  S(   N(
   R   t   obj_what_changedt   obj_alternate_contextt   saveR!   R   R"   t   DELETEDR   t   remove(   R   R   R(   (    (    sE   /home/tvault/.virtenv/lib/python2.7/site-packages/nova/pci/manager.pyR,   Z   s    
c         C   s   |  j  S(   N(   R   (   R   (    (    sE   /home/tvault/.virtenv/lib/python2.7/site-packages/nova/pci/manager.pyt	   pci_statsb   s    c         C   sS   g  } x9 t  j |  D]( } |  j j |  r | j |  q q W|  j |  d S(   sû  Sync the pci device tracker with hypervisor information.
        To support pci device hot plug, we sync with the hypervisor
        periodically, fetching all devices information from hypervisor,
        update the tracker and sync the DB information.
        Devices should not be hot-plugged when assigned to a guest,
        but possibly the hypervisor has no such guarantee. The best
        we can do is to give a warning if a device is changed
        or removed while assigned.
        :param devices_json: The JSON-ified string of device information
                             that is returned from the virt driver's
                             get_available_resource() call in the
                             pci_passthrough_devices key.
        N(   R   t   loadsR
   t   device_assignableR$   t   _set_hvdevs(   R   t   devices_jsont   devicesR(   (    (    sE   /home/tvault/.virtenv/lib/python2.7/site-packages/nova/pci/manager.pyt(   update_devices_from_hypervisor_resourcesf   s
    c         C   sÓ   |  j  d d    i  } x³ |  D]« } | j t j j t j j f k rM q  n  | j t j j k r{ g  | _	 | | | j
 <q  | j t j j k r  | j | j
  | _ | j rË | | j
 j	 j |  qË q  q  Wd S(   sþ  Build a tree of devices that represents parent-child relationships.
        We need to have the relationships set up so that we can easily make
        all the necessary changes to parent/child devices without having to
        figure it out at each call site.
        This method just adds references to relevant instances already found
        in `pci_devs` to `child_devices` and `parent_device` fields of each
        one.
        Currently relationships are considered for SR-IOV PFs/VFs only.
        t   keyc         S   s   |  j  S(   N(   t   address(   t   x(    (    sE   /home/tvault/.virtenv/lib/python2.7/site-packages/nova/pci/manager.pyt   <lambda>   s    N(   t   sortR!   R   R"   t   REMOVEDR-   t   dev_typet
   PciDeviceTypet   SRIOV_PFt
   child_devicesR7   t   SRIOV_VFt   gett   parent_addrt
   parent_deviceR$   (   t   all_devst   parentsR(   (    (    sE   /home/tvault/.virtenv/lib/python2.7/site-packages/nova/pci/manager.pyR   ~   s    
		c            sî  t  g  |  j D] } | j ^ q
  } t  g  | D] } | d ^ q/  } x|  j D]    j | | k rë y   j   Wn\ t j k
 r× } t j t d  i   j	 d 6  j
 d 6| j   d 6 t j
 j   _	 qVX|  j j    qR t   f d   | D  } |  j | d <  j	 t j
 j t j
 j f k rI| |  j | d <qR   j |  qR Wx} g  | D]  } | d | | k rd| ^ qdD]N } |  j | d <t j j |  j |  } |  j j j |  |  j j |  qW|  j |  j  d  S(   NR7   s`   Trying to remove device with %(status)s ownership %(instance_uuid)s because of %(pci_exception)sR!   R    t
   pci_exceptionc         3   s(   |  ] } | d    j  k r | Vq d S(   R7   N(   R7   (   t   .0R(   (   t   existed(    sE   /home/tvault/.virtenv/lib/python2.7/site-packages/nova/pci/manager.pys	   <genexpr>¹   s    t   compute_node_id(   t   setR   R7   R.   R   t   PciDeviceInvalidStatust   LOGt   warningR   R!   R    t   format_messageR   R"   R;   R   t
   remove_devicet   nextR   R#   R%   R
   t
   update_deviceR   t	   PciDevicet   createR   R$   R'   R   (   R   R4   R(   t   exist_addrst	   new_addrst   et	   new_valuet   dev_obj(    (   RH   sE   /home/tvault/.virtenv/lib/python2.7/site-packages/nova/pci/manager.pyR2   ¢   s4    %#
$
c         C   s¡   d  } | r | j } n  |  j j | j |  } | s: d  S| j } x | D] } | j |  qJ W| r t d   | D  r t j	 t
 d  i | d 6 n  | S(   Nc         s   s   |  ] } | j  d  k Vq d  S(   N(   t	   numa_nodet   None(   RG   R(   (    (    sE   /home/tvault/.virtenv/lib/python2.7/site-packages/nova/pci/manager.pys	   <genexpr>æ   s    s\   Assigning a pci device without numa affinity toinstance %(instance)s which has numa topologyt   instance(   RZ   t   cellsR   t   consume_requestst   requestsR    t   claimt   anyRL   RM   R   (   R   R   t   pci_requestst   instance_numa_topologyt   instance_cellst   devsR    R(   (    (    sE   /home/tvault/.virtenv/lib/python2.7/site-packages/nova/pci/manager.pyt   _claim_instanceØ   s    		
	c         C   s"   x | D] } | j  |  q Wd  S(   N(   t   allocate(   R   R[   Rd   R(   (    (    sE   /home/tvault/.virtenv/lib/python2.7/site-packages/nova/pci/manager.pyt   _allocate_instanceì   s    
c         C   sM   |  j  j | d g   } |  j | |  | rI |  j | d c | 7<n  d  S(   NR)   (   R   t   popRg   R   (   R   R[   Rd   (    (    sE   /home/tvault/.virtenv/lib/python2.7/site-packages/nova/pci/manager.pyt   allocate_instanceð   s    c         C   sS   g  } |  j  rO | j rO | j } |  j | | |  } | rO | |  j | <qO n  | S(   N(   R   R^   R    Re   R   (   R   R   Ra   Rb   Rd   R    (    (    sE   /home/tvault/.virtenv/lib/python2.7/site-packages/nova/pci/manager.pyt   claim_instanceö   s    		c         C   sG   x@ |  j  D]5 } | | k r
 | j | d k r
 |  j |  q
 q
 Wd S(   sÖ   Free device from pci resource tracker
        :param dev: cloned pci device object that needs to be free
        :param instance: the instance that this pci device
                         is allocated to
        R)   N(   R   R    t   _free_device(   R   R(   R[   t   pci_dev(    (    sE   /home/tvault/.virtenv/lib/python2.7/site-packages/nova/pci/manager.pyt   free_device   s    c         C   sb   | j  |  } |  j j | j d   } | r= | j |  n  x | D] } |  j j |  qD Wd  S(   N(   t   freeR
   Rh   R7   RZ   RQ   R   R'   (   R   R(   R[   t
   freed_devsR
   (    (    sE   /home/tvault/.virtenv/lib/python2.7/site-packages/nova/pci/manager.pyRk   
  s    
c         C   s_   xX |  j  D]M } | j t j j t j j f k r
 | j | d k rW |  j |  qW q
 q
 Wd  S(   NR)   (   R   R!   R   R"   R#   R%   R    Rk   (   R   R[   R(   (    (    sE   /home/tvault/.virtenv/lib/python2.7/site-packages/nova/pci/manager.pyt   _free_instance  s
    c         C   sV   |  j  j | d d   r) |  j |  n) |  j j | d d   rR |  j |  n  d  S(   NR)   (   R   Rh   RZ   Rp   R   (   R   R   R[   (    (    sE   /home/tvault/.virtenv/lib/python2.7/site-packages/nova/pci/manager.pyt
   free_instance!  s    c         C   sL   |  j  s
 d S| d k r, |  j | |  n  | d k rH |  j |  n  d S(   sB   Update PCI usage information if devices are de/allocated.
        Niÿÿÿÿi   (   R   Rq   Ri   (   R   R   R[   t   sign(    (    sE   /home/tvault/.virtenv/lib/python2.7/site-packages/nova/pci/manager.pyt   update_pci_for_instance'  s    	c         C   s  t  d   | D  } | t  d   | D  O} | t  d   | D  O} xY t |  j  D]H } | | k rZ |  j j | g   } x | D] } |  j |  q WqZ qZ WxY t |  j  D]H } | | k r¶ |  j j | g   } x | D] } |  j |  qä Wq¶ q¶ Wd S(   s   Remove all usages for instances not passed in the parameter.
        The caller should hold the COMPUTE_RESOURCE_SEMAPHORE lock
        c         s   s   |  ] } | d  Vq d S(   R)   N(    (   RG   t   inst(    (    sE   /home/tvault/.virtenv/lib/python2.7/site-packages/nova/pci/manager.pys	   <genexpr>7  s    c         s   s   |  ] } | d  Vq d S(   R    N(    (   RG   t   mig(    (    sE   /home/tvault/.virtenv/lib/python2.7/site-packages/nova/pci/manager.pys	   <genexpr>8  s    c         s   s   |  ] } | d  Vq d S(   R)   N(    (   RG   Rt   (    (    sE   /home/tvault/.virtenv/lib/python2.7/site-packages/nova/pci/manager.pys	   <genexpr>9  s    N(   RJ   R   R   Rh   Rk   R   (   R   t	   instancest
   migrationst   orphansRH   R)   Rd   R(   (    (    sE   /home/tvault/.virtenv/lib/python2.7/site-packages/nova/pci/manager.pyt   clean_usage2  s    
N(   t   __name__t
   __module__t   __doc__RZ   R   R   R,   t   propertyR/   R5   t   staticmethodR   R2   Re   Rg   Ri   Rj   Rm   Rk   Rp   Rq   Rs   Ry   (    (    (    sE   /home/tvault/.virtenv/lib/python2.7/site-packages/nova/pci/manager.pyR	   "   s$   			$	6				
	
			c         C   sK   |  j  } | d k r g  Sg  | D]' } | j | k sA | d k r  | ^ q  S(   s  Get the devices allocated to one or all requests for an instance.
    - For generic PCI request, the request id is None.
    - For sr-iov networking, the request id is a valid uuid
    - There are a couple of cases where all the PCI devices allocated to an
      instance need to be returned. Refer to libvirt driver that handles
      soft_reboot and hard_boot of 'xen' instances.
    t   allN(   t   pci_devicesRZ   t
   request_id(   Rt   R   R   t   device(    (    sE   /home/tvault/.virtenv/lib/python2.7/site-packages/nova/pci/manager.pyt   get_instance_pci_devsI  s
    		
(   R   t   oslo_configR    t   oslo_logR   t   loggingt   oslo_serializationR   t   novaR   t	   nova.i18nR   R   t   nova.objectsR   t   nova.pciR   R   R   t	   getLoggerRz   RL   t   objectR	   RZ   R   (    (    (    sE   /home/tvault/.virtenv/lib/python2.7/site-packages/nova/pci/manager.pyt   <module>   s   	ÿ (