示例#1
0
 def _analyse_classes(self):
     all_classes = list(tc.classes(self.device_name))
     root_class = self._root_class(all_classes)
     default_class = self._default_class(all_classes)
     all_classes.remove(root_class)
     all_classes.remove(default_class)
     return TcClasses(all_classes, default_class, root_class)
示例#2
0
def report_network_qos(netinfo):
    """Augment netinfo information with QoS data for the engine"""
    qdiscs = defaultdict(list)
    for qdisc in tc.qdiscs(dev=None):  # None -> all dev qdiscs
        qdiscs[qdisc['dev']].append(qdisc)
    for net, attrs in netinfo['networks'].iteritems():
        iface = attrs['iface']
        if iface in netinfo['bridges']:
            host_ports = [port for port in attrs['ports'] if
                          not port.startswith('vnet')]
            if not host_ports:  # Port-less bridge
                continue
            iface, = host_ports
        if iface in netinfo['vlans']:
            vlan_id = netinfo['vlans'][iface]['vlanid']
            iface = netinfo['vlans'][iface]['iface']
            iface_qdiscs = qdiscs.get(iface)
            if iface_qdiscs is None:
                continue
            class_id = (get_root_qdisc(iface_qdiscs)['handle'] + '%x' %
                        vlan_id)
        else:
            iface_qdiscs = qdiscs.get(iface)
            if iface_qdiscs is None:
                continue
            class_id = (get_root_qdisc(iface_qdiscs)['handle'] +
                        DEFAULT_CLASSID)

        # Now that iface is either a bond or a nic, let's get the QoS info
        classes = [cls for cls in tc.classes(iface, classid=class_id) if
                   cls['kind'] == 'hfsc']
        if classes:
            cls, = classes
            attrs['hostQos'] = {'out': cls['hfsc']}
示例#3
0
def _uses_classes(device, root_qdisc_handle=None):
    """Returns true iff there's traffic classes in the device, ignoring the
    root class and a default unused class"""
    if root_qdisc_handle is None:
        root_qdisc = netinfo_qos.get_root_qdisc(tc.qdiscs(device))
        root_qdisc_handle = root_qdisc['handle']
    classes = [cls for cls in tc.classes(device, parent=root_qdisc_handle) if
               not cls.get('root')]
    return (classes and
            not(len(classes) == 1 and not ifaceUsed(device) and
                classes[0]['handle'] == root_qdisc_handle + _DEFAULT_CLASSID))
示例#4
0
def _qdisc_conf_out(dev, root_qdisc_handle, vlan_tag, class_id, qos):
    """Adds the traffic class and filtering to the current hfsc qdisc"""
    flow_id = _ROOT_QDISC_HANDLE + class_id

    def filt_flow_id(filt, kind):
        return filt.get(kind, {}).get('flowid')

    filters = [
        filt for filt in tc._filters(dev, parent=root_qdisc_handle)
        if flow_id in (filt_flow_id(filt, 'basic'), filt_flow_id(filt, 'u32'))
    ]

    # Clear up any previous filters to the class
    for filt in filters:
        try:
            tc.filter.delete(dev, filt['pref'], parent=root_qdisc_handle)
        except tc.TrafficControlException as tce:
            if tce.errCode != errno.EINVAL:  # no filters exist -> EINVAL
                raise

    # Clear the class in case it exists
    try:
        tc.cls.delete(dev, classid=root_qdisc_handle + class_id)
    except tc.TrafficControlException as tce:
        if tce.errCode != errno.ENOENT:
            raise

    _add_hfsc_cls(dev, root_qdisc_handle, class_id, **qos)
    if class_id == _DEFAULT_CLASSID:
        _add_non_vlanned_filter(dev, root_qdisc_handle)
    else:
        if not _is_explicit_defined_default_class(dev):
            default_class, = [
                c['hfsc'] for c in tc.classes(dev)
                if c['handle'] == _ROOT_QDISC_HANDLE + _DEFAULT_CLASSID
            ]
            ls_max_rate = _max_hfsc_ls_rate(dev)
            default_class['ls']['m2'] = ls_max_rate

            tc.cls.delete(dev, classid=_ROOT_QDISC_HANDLE + _DEFAULT_CLASSID)
            _add_hfsc_cls(dev,
                          _ROOT_QDISC_HANDLE,
                          _DEFAULT_CLASSID,
                          ls=default_class['ls'])
            _add_fair_qdisc(dev, _ROOT_QDISC_HANDLE, _DEFAULT_CLASSID)

        _add_vlan_filter(dev, vlan_tag, root_qdisc_handle, class_id)
    _add_fair_qdisc(dev, root_qdisc_handle, class_id)
示例#5
0
 def test_classes(self):
     cmd_line_ls_10 = 3200
     cmd_line_ls_m1_20 = 6400
     cmd_line_ls_d_20 = 152
     cmd_line_ls_m2_20 = 3200
     cmd_line_ls_30 = 3500
     cmd_line_ls_m2_5000 = 40000
     data = '\n'.join((
         'class hfsc 1: root',
         'class hfsc 1:10 parent 1: leaf 10: sc m1 0bit d 0us '
         'm2 {0}Kbit'.format(cmd_line_ls_10),  # end of previous line
         'class hfsc 1:20 parent 1: leaf 20: ls m1 {0}Kibit d {1}us '
         'm2 {2}Kbit ul m1 0bit d 0us m2 30000Kbit'.format(
             cmd_line_ls_m1_20, cmd_line_ls_d_20, cmd_line_ls_m2_20),
         'class hfsc 1:30 parent 1: leaf 40: sc m1 0bit d 0us '
         'm2 {0}bit'.format(cmd_line_ls_30),  # end of previous line
         'class hfsc 1:5000 parent 1: leaf 5000: ls m1 0bit d 0us '
         'm2 {0}Kbit'.format(cmd_line_ls_m2_5000),  # end of previous line
     ))
     reported_ls_10 = cmd_line_ls_10 * 1000 / 8
     reported_ls_m1_20 = cmd_line_ls_m1_20 * 1024 / 8
     reported_ls_d_20 = cmd_line_ls_d_20 / 8
     reported_ls_m2_20 = cmd_line_ls_m2_20 * 1000 / 8
     reported_ls_30 = cmd_line_ls_30 / 8
     reported_ls_5000 = cmd_line_ls_m2_5000 * 1000 / 8
     classes = (
         {'kind': 'hfsc', 'root': True, 'handle': '1:'},
         {'kind': 'hfsc', 'handle': '1:10', 'parent': '1:', 'leaf': '10:',
          'hfsc': {'ls': {'m1': 0, 'd': 0, 'm2': reported_ls_10},
                   'rt': {'m1': 0, 'd': 0, 'm2': reported_ls_10}}},
         {'kind': 'hfsc', 'handle': '1:20', 'parent': '1:', 'leaf': '20:',
          'hfsc': {'ls': {'m1': reported_ls_m1_20, 'd': reported_ls_d_20,
                          'm2': reported_ls_m2_20},
                   'ul': {'m1': 0, 'd': 0, 'm2': 30000 * 1000}}},
         {'kind': 'hfsc', 'handle': '1:30', 'parent': '1:', 'leaf': '40:',
          'hfsc': {'ls': {'m1': 0, 'd': 0, 'm2': reported_ls_30},
                   'rt': {'m1': 0, 'd': 0, 'm2': reported_ls_30}}},
         {'kind': 'hfsc', 'handle': '1:5000', 'parent': '1:',
          'leaf': '5000:', 'hfsc': {'ls': {'m1': 0, 'd': 0,
                                           'm2': reported_ls_5000}}},
     )
     for parsed, correct in zip_longest(tc.classes(None, out=data),
                                        classes):
         self.assertEqual(parsed, correct)
示例#6
0
 def test_classes(self):
     cmd_line_ls_10 = 3200
     cmd_line_ls_m1_20 = 6400
     cmd_line_ls_d_20 = 152
     cmd_line_ls_m2_20 = 3200
     cmd_line_ls_30 = 3500
     cmd_line_ls_m2_5000 = 40000
     data = '\n'.join((
         'class hfsc 1: root',
         'class hfsc 1:10 parent 1: leaf 10: sc m1 0bit d 0us '
         'm2 {0}Kbit'.format(cmd_line_ls_10),  # end of previous line
         'class hfsc 1:20 parent 1: leaf 20: ls m1 {0}Kibit d {1}us '
         'm2 {2}Kbit ul m1 0bit d 0us m2 30000Kbit'.format(
             cmd_line_ls_m1_20, cmd_line_ls_d_20, cmd_line_ls_m2_20),
         'class hfsc 1:30 parent 1: leaf 40: sc m1 0bit d 0us '
         'm2 {0}bit'.format(cmd_line_ls_30),  # end of previous line
         'class hfsc 1:5000 parent 1: leaf 5000: ls m1 0bit d 0us '
         'm2 {0}Kbit'.format(cmd_line_ls_m2_5000),  # end of previous line
     ))
     reported_ls_10 = cmd_line_ls_10 * 1000 / 8
     reported_ls_m1_20 = cmd_line_ls_m1_20 * 1024 / 8
     reported_ls_d_20 = cmd_line_ls_d_20 / 8
     reported_ls_m2_20 = cmd_line_ls_m2_20 * 1000 / 8
     reported_ls_30 = cmd_line_ls_30 / 8
     reported_ls_5000 = cmd_line_ls_m2_5000 * 1000 / 8
     classes = (
         {'kind': 'hfsc', 'root': True, 'handle': '1:'},
         {'kind': 'hfsc', 'handle': '1:10', 'parent': '1:', 'leaf': '10:',
          'hfsc': {'ls': {'m1': 0, 'd': 0, 'm2': reported_ls_10},
                   'rt': {'m1': 0, 'd': 0, 'm2': reported_ls_10}}},
         {'kind': 'hfsc', 'handle': '1:20', 'parent': '1:', 'leaf': '20:',
          'hfsc': {'ls': {'m1': reported_ls_m1_20, 'd': reported_ls_d_20,
                          'm2': reported_ls_m2_20},
                   'ul': {'m1': 0, 'd': 0, 'm2': 30000 * 1000}}},
         {'kind': 'hfsc', 'handle': '1:30', 'parent': '1:', 'leaf': '40:',
          'hfsc': {'ls': {'m1': 0, 'd': 0, 'm2': reported_ls_30},
                   'rt': {'m1': 0, 'd': 0, 'm2': reported_ls_30}}},
         {'kind': 'hfsc', 'handle': '1:5000', 'parent': '1:',
          'leaf': '5000:', 'hfsc': {'ls': {'m1': 0, 'd': 0,
                                           'm2': reported_ls_5000}}},
     )
     for parsed, correct in zip_longest(tc.classes(None, out=data),
                                        classes):
         self.assertEqual(parsed, correct)
示例#7
0
def report_network_qos(nets_info, devs_info):
    """Augment netinfo information with QoS data for the engine"""
    qdiscs = defaultdict(list)
    for qdisc in tc.qdiscs(dev=None):  # None -> all dev qdiscs
        qdiscs[qdisc['dev']].append(qdisc)
    for net, attrs in six.viewitems(nets_info):
        iface = attrs['iface']
        if iface in devs_info['bridges']:
            host_ports = [
                port for port in attrs['ports'] if not port.startswith('vnet')
            ]
            if not host_ports:  # Port-less bridge
                continue
            if len(host_ports) > 1:
                logging.error(
                    'Multiple southbound ports per network detected,'
                    ' ignoring this network for the QoS report '
                    '(network: %s, ports: %s)',
                    net,
                    host_ports,
                )
                continue
            (iface, ) = host_ports
        if iface in devs_info['vlans']:
            vlan_id = devs_info['vlans'][iface]['vlanid']
            iface = devs_info['vlans'][iface]['iface']
            iface_qdiscs = qdiscs.get(iface)
            if iface_qdiscs is None:
                continue
            class_id = get_root_qdisc(iface_qdiscs)['handle'] + '%x' % vlan_id
        else:
            iface_qdiscs = qdiscs.get(iface)
            if iface_qdiscs is None:
                continue
            class_id = get_root_qdisc(iface_qdiscs)['handle'] + DEFAULT_CLASSID

        # Now that iface is either a bond or a nic, let's get the QoS info
        classes = [
            cls for cls in tc.classes(iface, classid=class_id)
            if cls['kind'] == 'hfsc'
        ]
        if classes:
            (cls, ) = classes
            attrs['hostQos'] = {'out': cls['hfsc']}
示例#8
0
def _qdisc_conf_out(dev, root_qdisc_handle, vlan_tag, class_id, qos):
    """Adds the traffic class and filtering to the current hfsc qdisc"""
    flow_id = _ROOT_QDISC_HANDLE + class_id

    def filt_flow_id(filt, kind):
        return filt.get(kind, {}).get('flowid')

    filters = [filt for filt in tc._filters(dev, parent=root_qdisc_handle) if
               flow_id in
               (filt_flow_id(filt, 'basic'), filt_flow_id(filt, 'u32'))]

    # Clear up any previous filters to the class
    for filt in filters:
        try:
            tc.filter.delete(dev, filt['pref'], parent=root_qdisc_handle)
        except tc.TrafficControlException as tce:
            if tce.errCode != errno.EINVAL:  # no filters exist -> EINVAL
                raise

    # Clear the class in case it exists
    try:
        tc.cls.delete(dev, classid=root_qdisc_handle + class_id)
    except tc.TrafficControlException as tce:
        if tce.errCode != errno.ENOENT:
            raise

    _add_hfsc_cls(dev, root_qdisc_handle, class_id, **qos)
    if class_id == _DEFAULT_CLASSID:
        _add_non_vlanned_filter(dev, root_qdisc_handle)
    else:
        if not _is_explicit_defined_default_class(dev):
            default_class, = [c['hfsc'] for c in tc.classes(
                dev) if c['handle'] == _ROOT_QDISC_HANDLE + _DEFAULT_CLASSID]
            ls_max_rate = _max_hfsc_ls_rate(dev)
            default_class['ls']['m2'] = ls_max_rate

            tc.cls.delete(dev, classid=_ROOT_QDISC_HANDLE + _DEFAULT_CLASSID)
            _add_hfsc_cls(dev, _ROOT_QDISC_HANDLE, _DEFAULT_CLASSID,
                          ls=default_class['ls'])
            _add_fair_qdisc(dev, _ROOT_QDISC_HANDLE, _DEFAULT_CLASSID)

        _add_vlan_filter(dev, vlan_tag, root_qdisc_handle, class_id)
    _add_fair_qdisc(dev, root_qdisc_handle, class_id)
示例#9
0
文件: qos.py 项目: nirs/vdsm
def report_network_qos(nets_info, devs_info):
    """Augment netinfo information with QoS data for the engine"""
    qdiscs = defaultdict(list)
    for qdisc in tc.qdiscs(dev=None):  # None -> all dev qdiscs
        qdiscs[qdisc['dev']].append(qdisc)
    for net, attrs in six.viewitems(nets_info):
        iface = attrs['iface']
        if iface in devs_info['bridges']:
            host_ports = [port for port in attrs['ports'] if
                          not port.startswith('vnet')]
            if not host_ports:  # Port-less bridge
                continue
            if len(host_ports) > 1:
                logging.error('Multiple southbound ports per network detected,'
                              ' ignoring this network for the QoS report '
                              '(network: %s, ports: %s)', net, host_ports)
                continue
            iface, = host_ports
        if iface in devs_info['vlans']:
            vlan_id = devs_info['vlans'][iface]['vlanid']
            iface = devs_info['vlans'][iface]['iface']
            iface_qdiscs = qdiscs.get(iface)
            if iface_qdiscs is None:
                continue
            class_id = (get_root_qdisc(iface_qdiscs)['handle'] + '%x' %
                        vlan_id)
        else:
            iface_qdiscs = qdiscs.get(iface)
            if iface_qdiscs is None:
                continue
            class_id = (get_root_qdisc(iface_qdiscs)['handle'] +
                        DEFAULT_CLASSID)

        # Now that iface is either a bond or a nic, let's get the QoS info
        classes = [cls for cls in tc.classes(iface, classid=class_id) if
                   cls['kind'] == 'hfsc']
        if classes:
            cls, = classes
            attrs['hostQos'] = {'out': cls['hfsc']}
示例#10
0
def report_network_qos(nets_info, devs_info):
    """Augment netinfo information with QoS data for the engine"""
    qdiscs = defaultdict(list)
    for qdisc in tc.qdiscs(dev=None):  # None -> all dev qdiscs
        qdiscs[qdisc['dev']].append(qdisc)
    for net, attrs in six.viewitems(nets_info):
        iface = attrs['iface']
        if iface in devs_info['bridges']:
            host_ports = [
                port for port in attrs['ports'] if not port.startswith('vnet')
            ]
            if not host_ports:  # Port-less bridge
                continue
            iface, = host_ports
        if iface in devs_info['vlans']:
            vlan_id = devs_info['vlans'][iface]['vlanid']
            iface = devs_info['vlans'][iface]['iface']
            iface_qdiscs = qdiscs.get(iface)
            if iface_qdiscs is None:
                continue
            class_id = (get_root_qdisc(iface_qdiscs)['handle'] +
                        '%x' % vlan_id)
        else:
            iface_qdiscs = qdiscs.get(iface)
            if iface_qdiscs is None:
                continue
            class_id = (get_root_qdisc(iface_qdiscs)['handle'] +
                        DEFAULT_CLASSID)

        # Now that iface is either a bond or a nic, let's get the QoS info
        classes = [
            cls for cls in tc.classes(iface, classid=class_id)
            if cls['kind'] == 'hfsc'
        ]
        if classes:
            cls, = classes
            attrs['hostQos'] = {'out': cls['hfsc']}
示例#11
0
文件: qos.py 项目: wuyeliang/vdsm
def _max_hfsc_ls_rate(dev):
    return max([
        cls['hfsc']['ls']['m2'] for cls in tc.classes(dev)
        if cls['kind'] == 'hfsc' and 'root' not in cls
    ])
示例#12
0
def _max_hfsc_ls_rate(dev):
    return max([cls['hfsc']['ls']['m2'] for cls in tc.classes(dev)
                if cls['kind'] == 'hfsc' and 'root' not in cls])