def test_set_port_qos_rule_invalid_qos_rule_exc(self, mock_get_default_sd,
                                                    mock_get_bandwidth_sd):
        self._mock_get_switch_port_alloc()

        mock_add_feature = self.netutils._jobutils.add_virt_feature
        mock_add_feature.side_effect = exceptions.InvalidParameterValue(
            '0x80070057')

        qos_rule = dict(min_kbps=20000,
                        max_kbps=30000,
                        max_burst_kbps=40000,
                        max_burst_size_kb=50000)

        self.assertRaises(exceptions.InvalidParameterValue,
                          self.netutils.set_port_qos_rule,
                          mock.sentinel.port_id, qos_rule)
Esempio n. 2
0
    def set_port_qos_rule(self, port_id, qos_rule):
        """Sets the QoS rule for the given port.

        :param port_id: the port's ID to which the QoS rule will be applied to.
        :param qos_rule: a dictionary containing the following keys:
            min_kbps, max_kbps, max_burst_kbps, max_burst_size_kb.
        :raises exceptions.HyperVInvalidException: if
            - min_kbps is smaller than 10MB.
            - max_kbps is smaller than min_kbps.
            - max_burst_kbps is smaller than max_kbps.
        :raises exceptions.HyperVException: if the QoS rule cannot be set.
        """

        # Hyper-V stores bandwidth limits in bytes.
        min_bps = qos_rule.get("min_kbps", 0) * units.Ki
        max_bps = qos_rule.get("max_kbps", 0) * units.Ki
        max_burst_bps = qos_rule.get("max_burst_kbps", 0) * units.Ki
        max_burst_sz = qos_rule.get("max_burst_size_kb", 0) * units.Ki

        if not (min_bps or max_bps or max_burst_bps or max_burst_sz):
            # no limits need to be set
            return

        if min_bps and min_bps < 10 * units.Mi:
            raise exceptions.InvalidParameterValue(param_name="min_kbps",
                                                   param_value=min_bps)
        if max_bps and max_bps < min_bps:
            raise exceptions.InvalidParameterValue(param_name="max_kbps",
                                                   param_value=max_bps)
        if max_burst_bps and max_burst_bps < max_bps:
            raise exceptions.InvalidParameterValue(param_name="max_burst_kbps",
                                                   param_value=max_burst_bps)

        port_alloc = self._get_switch_port_allocation(port_id)[0]
        bandwidth = self._get_bandwidth_setting_data_from_port_alloc(
            port_alloc)
        if bandwidth:
            # Removing the feature because it cannot be modified
            # due to a wmi exception.
            self._jobutils.remove_virt_feature(bandwidth)

            # remove from cache.
            self._bandwidth_sds.pop(port_alloc.InstanceID, None)

        bandwidth = self._get_default_setting_data(
            self._PORT_BANDWIDTH_SET_DATA)
        bandwidth.Reservation = min_bps
        bandwidth.Limit = max_bps
        bandwidth.BurstLimit = max_burst_bps
        bandwidth.BurstSize = max_burst_sz

        try:
            self._jobutils.add_virt_feature(bandwidth, port_alloc)
        except Exception as ex:
            if '0x80070057' in ex.message:
                raise exceptions.InvalidParameterValue(param_name="qos_rule",
                                                       param_value=qos_rule)
            raise exceptions.HyperVException(
                _LE('Unable to set qos rule %(qos_rule)s for port %(port)s. '
                    'Error: %(error)s') %
                dict(qos_rule=qos_rule, port=port_alloc, error=ex))
    def set_vswitch_port_offload(self,
                                 switch_port_name,
                                 sriov_enabled=None,
                                 iov_queues_requested=None,
                                 vmq_enabled=None,
                                 offloaded_sa=None):
        """Enables / Disables different offload options for the given port.

        Optional prameters are ignored if they are None.

        :param switch_port_name: the name of the port which will have VMQ
            enabled or disabled.
        :param sriov_enabled: if SR-IOV should be turned on or off.
        :param iov_queues_requested: the number of IOV queues to use. (> 1)
        :param vmq_enabled: if VMQ should be turned on or off.
        :param offloaded_sa: the number of IPsec SA offloads to use. (> 1)
        :raises os_win.exceptions.InvalidParameterValue: if an invalid value
            is passed for the iov_queues_requested or offloaded_sa parameters.
        """

        if iov_queues_requested is not None and iov_queues_requested < 1:
            raise exceptions.InvalidParameterValue(
                param_name='iov_queues_requested',
                param_value=iov_queues_requested)

        if offloaded_sa is not None and offloaded_sa < 1:
            raise exceptions.InvalidParameterValue(param_name='offloaded_sa',
                                                   param_value=offloaded_sa)

        port_alloc = self._get_switch_port_allocation(switch_port_name)[0]

        # NOTE(claudiub): All ports have a HW offload SD.
        hw_offload_sd = self._get_hw_offload_sd_from_port_alloc(port_alloc)
        sd_changed = False

        if sriov_enabled is not None:
            desired_state = (self._OFFLOAD_ENABLED
                             if sriov_enabled else self._OFFLOAD_DISABLED)
            if hw_offload_sd.IOVOffloadWeight != desired_state:
                hw_offload_sd.IOVOffloadWeight = desired_state
                sd_changed = True

        if iov_queues_requested is not None:
            if hw_offload_sd.IOVQueuePairsRequested != iov_queues_requested:
                hw_offload_sd.IOVQueuePairsRequested = iov_queues_requested
                sd_changed = True

        if vmq_enabled is not None:
            desired_state = (self._OFFLOAD_ENABLED
                             if vmq_enabled else self._OFFLOAD_DISABLED)
            if hw_offload_sd.VMQOffloadWeight != desired_state:
                hw_offload_sd.VMQOffloadWeight = desired_state
                sd_changed = True

        if offloaded_sa is not None:
            if hw_offload_sd.IPSecOffloadLimit != offloaded_sa:
                hw_offload_sd.IPSecOffloadLimit = offloaded_sa
                sd_changed = True

        # NOTE(claudiub): The HW offload SD can simply be modified. No need to
        # remove it and create a new one.
        if sd_changed:
            self._jobutils.modify_virt_feature(hw_offload_sd)