Example #1
0
    def allocate(self, instance):
        ok_statuses = (fields.PciDeviceStatus.AVAILABLE,
                       fields.PciDeviceStatus.CLAIMED)
        if self.status not in ok_statuses:
            raise exception.PciDeviceInvalidStatus(
                compute_node_id=self.compute_node_id,
                address=self.address,
                status=self.status,
                hopestatus=ok_statuses)
        if (self.status == fields.PciDeviceStatus.CLAIMED
                and self.instance_uuid != instance['uuid']):
            raise exception.PciDeviceInvalidOwner(
                compute_node_id=self.compute_node_id,
                address=self.address,
                owner=self.instance_uuid,
                hopeowner=instance['uuid'])

        self.status = fields.PciDeviceStatus.ALLOCATED
        self.instance_uuid = instance['uuid']

        # Notes(yjiang5): remove this check when instance object for
        # compute manager is finished
        if isinstance(instance, dict):
            if 'pci_devices' not in instance:
                instance['pci_devices'] = []
            instance['pci_devices'].append(copy.copy(self))
        else:
            instance.pci_devices.objects.append(copy.copy(self))
Example #2
0
 def free(self, instance=None):
     ok_statuses = (fields.PciDeviceStatus.ALLOCATED,
                    fields.PciDeviceStatus.CLAIMED)
     if self.status not in ok_statuses:
         raise exception.PciDeviceInvalidStatus(
             compute_node_id=self.compute_node_id,
             address=self.address,
             status=self.status,
             hopestatus=ok_statuses)
     if instance and self.instance_uuid != instance['uuid']:
         raise exception.PciDeviceInvalidOwner(
             compute_node_id=self.compute_node_id,
             address=self.address,
             owner=self.instance_uuid,
             hopeowner=instance['uuid'])
     old_status = self.status
     self.status = fields.PciDeviceStatus.AVAILABLE
     self.instance_uuid = None
     self.request_id = None
     if old_status == fields.PciDeviceStatus.ALLOCATED and instance:
         # Notes(yjiang5): remove this check when instance object for
         # compute manager is finished
         existed = next(
             (dev for dev in instance['pci_devices'] if dev.id == self.id))
         if isinstance(instance, dict):
             instance['pci_devices'].remove(existed)
         else:
             instance.pci_devices.objects.remove(existed)
Example #3
0
    def remove(self):
        # We allow removal of a device is if it is unused. It can be unused
        # either by being in available state or being in a state that shows
        # that the parent or child device blocks the consumption of this device
        expected_states = [
            fields.PciDeviceStatus.AVAILABLE,
            fields.PciDeviceStatus.UNAVAILABLE,
            fields.PciDeviceStatus.UNCLAIMABLE,
        ]
        if self.status not in expected_states:
            raise exception.PciDeviceInvalidStatus(
                compute_node_id=self.compute_node_id,
                address=self.address,
                status=self.status,
                hopestatus=expected_states)
        # Just to be on the safe side, do not allow removal of device that has
        # an owner even if the state of the device suggests that it is not
        # owned.
        if 'instance_uuid' in self and self.instance_uuid is not None:
            raise exception.PciDeviceInvalidOwner(
                compute_node_id=self.compute_node_id,
                address=self.address,
                owner=self.instance_uuid,
                hopeowner=None,
            )

        self.status = fields.PciDeviceStatus.REMOVED
        self.instance_uuid = None
        self.request_id = None
Example #4
0
    def allocate(self, instance):
        ok_statuses = (fields.PciDeviceStatus.AVAILABLE,
                       fields.PciDeviceStatus.CLAIMED)
        parent_ok_statuses = (fields.PciDeviceStatus.AVAILABLE,
                              fields.PciDeviceStatus.UNCLAIMABLE,
                              fields.PciDeviceStatus.UNAVAILABLE)
        dependants_ok_statuses = (fields.PciDeviceStatus.AVAILABLE,
                                  fields.PciDeviceStatus.UNCLAIMABLE)
        if self.status not in ok_statuses:
            raise exception.PciDeviceInvalidStatus(
                compute_node_id=self.compute_node_id,
                address=self.address, status=self.status,
                hopestatus=ok_statuses)
        if (self.status == fields.PciDeviceStatus.CLAIMED and
                self.instance_uuid != instance['uuid']):
            raise exception.PciDeviceInvalidOwner(
                compute_node_id=self.compute_node_id,
                address=self.address, owner=self.instance_uuid,
                hopeowner=instance['uuid'])
        if self.dev_type == fields.PciDeviceType.SRIOV_PF:
            vfs_list = self.child_devices
            if not all([vf.status in dependants_ok_statuses for
                        vf in vfs_list]):
                raise exception.PciDeviceVFInvalidStatus(
                    compute_node_id=self.compute_node_id,
                    address=self.address)
            self._bulk_update_status(vfs_list,
                                     fields.PciDeviceStatus.UNAVAILABLE)

        elif self.dev_type in (
            fields.PciDeviceType.SRIOV_VF, fields.PciDeviceType.VDPA
        ):
            parent = self.parent_device
            if parent:
                if parent.status not in parent_ok_statuses:
                    raise exception.PciDevicePFInvalidStatus(
                        compute_node_id=self.compute_node_id,
                        address=self.parent_addr, status=self.status,
                        vf_address=self.address,
                        hopestatus=parent_ok_statuses)
                # Set PF status
                parent.status = fields.PciDeviceStatus.UNAVAILABLE
            else:
                LOG.debug('Physical function addr: %(pf_addr)s parent of '
                          'VF addr: %(vf_addr)s was not found',
                           {'pf_addr': self.parent_addr,
                            'vf_addr': self.address})

        self.status = fields.PciDeviceStatus.ALLOCATED
        self.instance_uuid = instance['uuid']

        # Notes(yjiang5): remove this check when instance object for
        # compute manager is finished
        if isinstance(instance, dict):
            if 'pci_devices' not in instance:
                instance['pci_devices'] = []
            instance['pci_devices'].append(copy.copy(self))
        else:
            instance.pci_devices.objects.append(copy.copy(self))
Example #5
0
 def free(self, instance=None):
     ok_statuses = (fields.PciDeviceStatus.ALLOCATED,
                    fields.PciDeviceStatus.CLAIMED)
     free_devs = []
     if self.status not in ok_statuses:
         raise exception.PciDeviceInvalidStatus(
             compute_node_id=self.compute_node_id,
             address=self.address,
             status=self.status,
             hopestatus=ok_statuses)
     if instance and self.instance_uuid != instance['uuid']:
         raise exception.PciDeviceInvalidOwner(
             compute_node_id=self.compute_node_id,
             address=self.address,
             owner=self.instance_uuid,
             hopeowner=instance['uuid'])
     if self.dev_type == fields.PciDeviceType.SRIOV_PF:
         # Set all PF dependants status to AVAILABLE
         vfs_list = objects.PciDeviceList.get_by_parent_address(
             self._context, self.compute_node_id, self.address)
         self._bulk_update_status(vfs_list,
                                  fields.PciDeviceStatus.AVAILABLE)
         free_devs.extend(vfs_list)
     if self.dev_type == fields.PciDeviceType.SRIOV_VF:
         # Set PF status to AVAILABLE if all of it's VFs are free
         vfs_list = objects.PciDeviceList.get_by_parent_address(
             self._context, self.compute_node_id, self.parent_addr)
         if all([vf.is_available() for vf in vfs_list if vf.id != self.id]):
             try:
                 parent = self.get_by_dev_addr(self._context,
                                               self.compute_node_id,
                                               self.parent_addr)
                 parent.status = fields.PciDeviceStatus.AVAILABLE
                 free_devs.append(parent)
             except exception.PciDeviceNotFound:
                 LOG.debug(
                     'Physical function addr: %(pf_addr)s parent of '
                     'VF addr: %(vf_addr)s was not found', {
                         'pf_addr': self.parent_addr,
                         'vf_addr': self.address
                     })
     old_status = self.status
     self.status = fields.PciDeviceStatus.AVAILABLE
     free_devs.append(self)
     self.instance_uuid = None
     self.request_id = None
     if old_status == fields.PciDeviceStatus.ALLOCATED and instance:
         # Notes(yjiang5): remove this check when instance object for
         # compute manager is finished
         existed = next(
             (dev for dev in instance['pci_devices'] if dev.id == self.id))
         if isinstance(instance, dict):
             instance['pci_devices'].remove(existed)
         else:
             instance.pci_devices.objects.remove(existed)
     return free_devs
Example #6
0
def free(devobj, instance=None):
    if instance and devobj.instance_uuid != instance['uuid']:
        raise exception.PciDeviceInvalidOwner(
            compute_node_id=devobj.compute_node_id,
            address=devobj.address, owner=devobj.instance_uuid,
            hopeowner=instance['uuid'])
    old_status = devobj.status
    devobj.status = 'available'
    devobj.instance_uuid = None
    if old_status == 'allocated' and instance:
        # Notes(yjiang5): remove this check when instance object for
        # compute manager is finished
        existed = next((dev for dev in instance['pci_devices']
            if dev.id == devobj.id))
        if isinstance(instance, dict):
            instance['pci_devices'].remove(existed)
        else:
            instance.pci_devices.objects.remove(existed)
Example #7
0
def allocate(devobj, instance):
    if devobj.status == 'claimed' and devobj.instance_uuid != instance['uuid']:
        raise exception.PciDeviceInvalidOwner(
            compute_node_id=devobj.compute_node_id,
            address=devobj.address, owner=devobj.instance_uuid,
            hopeowner=instance['uuid'])

    devobj.status = 'allocated'
    devobj.instance_uuid = instance['uuid']

    # Notes(yjiang5): remove this check when instance object for
    # compute manager is finished
    if isinstance(instance, dict):
        if 'pci_devices' not in instance:
            instance['pci_devices'] = []
        instance['pci_devices'].append(copy.copy(devobj))
    else:
        instance.pci_devices.objects.append(copy.copy(devobj))