Example #1
0
    def _init_dev_details(self):
        self.vendor_id = self.tags.pop("vendor_id", ANY)
        self.product_id = self.tags.pop("product_id", ANY)
        self.address = self.tags.pop("address", None)
        self.dev_name = self.tags.pop("devname", None)

        self.vendor_id = self.vendor_id.strip()
        get_pci_dev_info(self, 'vendor_id', MAX_VENDOR_ID, '%04x')
        get_pci_dev_info(self, 'product_id', MAX_PRODUCT_ID, '%04x')

        if self.address and self.dev_name:
            raise exception.PciDeviceInvalidDeviceName()
        if not self.dev_name:
            address_str = self.address or "*:*:*.*"
            self.address = PciAddress(address_str, False)
    def _init_dev_details(self):
        self.vendor_id = self.tags.pop("vendor_id", ANY)
        self.product_id = self.tags.pop("product_id", ANY)
        # Note(moshele): The address attribute can be a string or a dict.
        # For glob syntax or specific pci it is a string and for regex syntax
        # it is a dict. The WhitelistPciAddress class handles both types.
        self.address = self.tags.pop("address", None)
        self.dev_name = self.tags.pop("devname", None)

        self.vendor_id = self.vendor_id.strip()
        get_pci_dev_info(self, 'vendor_id', MAX_VENDOR_ID, '%04x')
        get_pci_dev_info(self, 'product_id', MAX_PRODUCT_ID, '%04x')

        if self.address and self.dev_name:
            raise exception.PciDeviceInvalidDeviceName()
        if not self.dev_name:
            pci_address = self.address or "*:*:*.*"
            self.address = WhitelistPciAddress(pci_address, False)
Example #3
0
    def _init_dev_details(self):
        self.vendor_id = self.tags.pop("vendor_id", ANY)
        self.product_id = self.tags.pop("product_id", ANY)
        self.address = self.tags.pop("address", None)
        self.dev_name = self.tags.pop("devname", None)

        self.vendor_id = self.vendor_id.strip()
        get_pci_dev_info(self, 'vendor_id', MAX_VENDOR_ID, '%04x')
        get_pci_dev_info(self, 'product_id', MAX_PRODUCT_ID, '%04x')

        pf = False
        if self.address and self.dev_name:
            raise exception.PciDeviceInvalidDeviceName()
        if not self.address:
            if self.dev_name:
                self.address, pf = utils.get_function_by_ifname(self.dev_name)
                if not self.address:
                    raise exception.PciDeviceNotFoundById(id=self.dev_name)
            else:
                self.address = "*:*:*.*"

        self.address = PciAddress(self.address, pf)
Example #4
0
    def _init_dev_details(self) -> None:
        self.vendor_id = self.tags.pop("vendor_id", ANY)
        self.product_id = self.tags.pop("product_id", ANY)
        self.dev_name = self.tags.pop("devname", None)
        self.address: ty.Optional[WhitelistPciAddress] = None
        # Note(moshele): The address attribute can be a string or a dict.
        # For glob syntax or specific pci it is a string and for regex syntax
        # it is a dict. The WhitelistPciAddress class handles both types.
        address = self.tags.pop("address", None)

        self.vendor_id = self.vendor_id.strip()
        self._set_pci_dev_info('vendor_id', MAX_VENDOR_ID, '%04x')
        self._set_pci_dev_info('product_id', MAX_PRODUCT_ID, '%04x')

        if address and self.dev_name:
            raise exception.PciDeviceInvalidDeviceName()

        if not self.dev_name:
            self.address = WhitelistPciAddress(address or '*:*:*.*', False)

        # PFs with remote_managed tags are explicitly not supported. If they
        # are tagged as such by mistake in the whitelist Nova will
        # raise an exception. The reason for excluding PFs is the lack of a way
        # for an instance to access the control plane at the remote side (e.g.
        # on a DPU) for managing the PF representor corresponding to the PF.
        address_obj = self._address_obj()
        self._remote_managed = strutils.bool_from_string(
            self.tags.get(PCI_REMOTE_MANAGED_TAG))
        if self._remote_managed:
            if address_obj is None:
                # Note that this will happen if a netdev was specified in the
                # whitelist but it is not actually present on a system - in
                # this case Nova is not able to look up an address by
                # a netdev name.
                raise exception.PciDeviceRemoteManagedNotPresent()
            elif address_obj.is_physical_function:
                pf_addr = str(address_obj.pci_address_spec)
                vf_product_id = utils.get_vf_product_id_by_pf_addr(pf_addr)
                # VF vendor IDs have to match the corresponding PF vendor IDs
                # per the SR-IOV spec so we use it for matching here.
                pf_vendor_id, pf_product_id = utils.get_pci_ids_by_pci_addr(
                    pf_addr)
                # Check the actual vendor ID and VF product ID of an assumed
                # VF (based on the actual PF). The VF product ID must match
                # the actual one if this is a VF device spec.
                if (self.product_id == vf_product_id
                        and self.vendor_id in (pf_vendor_id, ANY)):
                    pass
                elif (self.product_id in (pf_product_id, ANY)
                      and self.vendor_id in (pf_vendor_id, ANY)):
                    raise exception.PciDeviceInvalidPFRemoteManaged(
                        address_obj.pci_address_spec)
                else:
                    # The specified product and vendor IDs of what is supposed
                    # to be a VF corresponding to the PF PCI address do not
                    # match the actual ones for this PF. This means that the
                    # whitelist is invalid.
                    raise exception.PciConfigInvalidWhitelist(
                        reason=_('the specified VF vendor ID %(vendor_id)s and'
                                 ' product ID %(product_id)s do not match the'
                                 ' expected VF IDs based on the corresponding'
                                 ' PF identified by PCI address %(pf_addr)s') %
                        {
                            'vendor_id': self.vendor_id,
                            'product_id': self.product_id,
                            'pf_addr': pf_addr
                        })