Exemple #1
0
def remove_outbound(device, vlan_tag, net_info):
    """Removes the qosOutbound configuration from the device and restores
    pfifo_fast if it was the last QoSed network on the device. vlan_tag
    can be None"""
    class_id = '%x' % (_NON_VLANNED_ID if vlan_tag is None else vlan_tag)
    MISSING_OBJ_ERR_CODES = (errno.EINVAL, errno.ENOENT, errno.EOPNOTSUPP)

    try:
        tc.filter.delete(
            device, pref=_NON_VLANNED_ID if vlan_tag is None else vlan_tag)
    except tc.TrafficControlException as tce:
        if tce.errCode not in MISSING_OBJ_ERR_CODES:  # No filter exists
            raise

    device_qdiscs = list(tc.qdiscs(device))
    if not device_qdiscs:
        return
    root_qdisc_handle = netinfo_qos.get_root_qdisc(device_qdiscs)['handle']
    try:
        tc.cls.delete(device, classid=root_qdisc_handle + class_id)
    except tc.TrafficControlException as tce:
        if tce.errCode not in MISSING_OBJ_ERR_CODES:  # No class exists
            raise

    if not _uses_classes(device, net_info,
                         root_qdisc_handle=root_qdisc_handle):
        try:
            tc._qdisc_del(device)
            tc._qdisc_del(device, kind='ingress')
        except tc.TrafficControlException as tce:
            if tce.errCode not in MISSING_OBJ_ERR_CODES:  # No qdisc
                raise
Exemple #2
0
 def _analyse_qdiscs(self):
     all_qdiscs = list(tc.qdiscs(self.device_name))
     ingress_qdisc = self._ingress_qdisc(all_qdiscs)
     root_qdisc = self._root_qdisc(all_qdiscs)
     leaf_qdiscs = self._leaf_qdiscs(all_qdiscs)
     self.assertEqual(len(leaf_qdiscs) + 2, len(all_qdiscs))
     return TcQdiscs(leaf_qdiscs, ingress_qdisc, root_qdisc)
Exemple #3
0
 def _analyse_qdiscs(self):
     all_qdiscs = list(tc.qdiscs(self.device_name))
     ingress_qdisc = self._ingress_qdisc(all_qdiscs)
     root_qdisc = self._root_qdisc(all_qdiscs)
     leaf_qdiscs = self._leaf_qdiscs(all_qdiscs)
     self.assertEqual(len(leaf_qdiscs) + 2, len(all_qdiscs))
     return TcQdiscs(leaf_qdiscs, ingress_qdisc, root_qdisc)
Exemple #4
0
def remove_outbound(device, vlan_tag):
    """Removes the qosOutbound configuration from the device and restores
    pfifo_fast if it was the last QoSed network on the device. vlan_tag
    can be None"""
    class_id = '%x' % (_NON_VLANNED_ID if vlan_tag is None else vlan_tag)
    MISSING_OBJ_ERR_CODES = (errno.EINVAL, errno.ENOENT, errno.EOPNOTSUPP)

    try:
        tc.filter.delete(
            device, pref=_NON_VLANNED_ID if vlan_tag is None else vlan_tag)
    except tc.TrafficControlException as tce:
        if tce.errCode not in MISSING_OBJ_ERR_CODES:  # No filter exists
            raise

    device_qdiscs = list(tc.qdiscs(device))
    if not device_qdiscs:
        return
    root_qdisc_handle = netinfo_qos.get_root_qdisc(device_qdiscs)['handle']
    try:
        tc.cls.delete(device, classid=root_qdisc_handle + class_id)
    except tc.TrafficControlException as tce:
        if tce.errCode not in MISSING_OBJ_ERR_CODES:  # No class exists
            raise

    if not _uses_classes(device, root_qdisc_handle=root_qdisc_handle):
        try:
            tc._qdisc_del(device)
            tc._qdisc_del(device, kind='ingress')
        except tc.TrafficControlException as tce:
            if tce.errCode not in MISSING_OBJ_ERR_CODES:  # No qdisc
                raise
Exemple #5
0
 def _analyse_qdiscs(self, device_name):
     all_qdiscs = list(tc.qdiscs(device_name))
     ingress_qdisc = self._ingress_qdisc(all_qdiscs)
     root_qdisc = self._root_qdisc(all_qdiscs)
     leaf_qdiscs = self._leaf_qdiscs(all_qdiscs)
     assert len(leaf_qdiscs) + 2 == len(all_qdiscs)
     return TcQdiscs(leaf_qdiscs, ingress_qdisc, root_qdisc)
Exemple #6
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']}
Exemple #7
0
def configure_outbound(qosOutbound, device, vlan_tag):
    """Adds the qosOutbound configuration to the backing device (be it bond
    or nic). Adds a class and filter for default traffic if necessary. vlan_tag
    can be None"""
    root_qdisc = netinfo_qos.get_root_qdisc(tc.qdiscs(device))
    class_id = '%x' % (_NON_VLANNED_ID if vlan_tag is None else vlan_tag)
    if not root_qdisc or root_qdisc['kind'] != _SHAPING_QDISC_KIND:
        _fresh_qdisc_conf_out(device, vlan_tag, class_id, qosOutbound)
    else:
        _qdisc_conf_out(device, root_qdisc['handle'], vlan_tag, class_id,
                        qosOutbound)
Exemple #8
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))
Exemple #9
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))
Exemple #10
0
def configure_outbound(qosOutbound, device, vlan_tag):
    """Adds the qosOutbound configuration to the backing device (be it bond
    or nic). Adds a class and filter for default traffic if necessary. vlan_tag
    can be None"""
    root_qdisc = netinfo_qos.get_root_qdisc(tc.qdiscs(device))
    class_id = '%x' % (_NON_VLANNED_ID if vlan_tag is None else vlan_tag)
    if not root_qdisc or root_qdisc['kind'] != _SHAPING_QDISC_KIND:
        _fresh_qdisc_conf_out(device, vlan_tag, class_id, qosOutbound)
    else:
        _qdisc_conf_out(device, root_qdisc['handle'], vlan_tag, class_id,
                        qosOutbound)
Exemple #11
0
 def test_qdiscs(self):
     data = '\n'.join((
         'qdisc hfsc 1: root refcnt 2 default 5000',
         'qdisc sfq 10: parent 1:10 limit 127p quantum 1514b',
         'qdisc sfq 20: parent 1:20 limit 127p quantum 1514b',
         'qdisc sfq 30: parent 1:30 limit 127p quantum 30Kb perturb 3sec',
         'qdisc sfq 40: parent 1:40 limit 127p quantum 20Mb perturb 5sec',
         'qdisc ingress ffff: parent ffff:fff1 ----------------',
         'qdisc mq 0: dev wlp3s0 root',
         'qdisc ingress ffff: dev vdsmtest-Z2TMO parent ffff:fff1 '
         '----------------',  # end of previous line
         'qdisc pfifo_fast 0: dev em1 root refcnt 2 bands 3 priomap  '
         '1 2 2 2 1 2 0 0 1 1 1 1 1 1 1 1',  # end of previous line
         'qdisc pfifo_fast 0: dev wlp3s0 parent :1 bands 3 priomap  '
         '1 2 2 2 1 2 0 0 1 1 1 1 1 1 1 1',  # end of previous line
         'qdisc fq_codel 801e: root refcnt 2 limit 132p flows 15 quantum '
         '400 target 5.0ms interval 150.0ms ecn',  # end of previous line
     ))
     qdiscs = (
         {'kind': 'hfsc', 'root': True, 'handle': '1:', 'refcnt': 2,
          'hfsc': {'default': 0x5000}},
         {'kind': 'sfq', 'handle': '10:', 'parent': '1:10',
          'sfq': {'limit': 127, 'quantum': 1514}},
         {'kind': 'sfq', 'handle': '20:', 'parent': '1:20',
          'sfq': {'limit': 127, 'quantum': 1514}},
         {'kind': 'sfq', 'handle': '30:', 'parent': '1:30',
          'sfq': {'limit': 127, 'quantum': 30 * 1024, 'perturb': 3}},
         {'kind': 'sfq', 'handle': '40:', 'parent': '1:40',
          'sfq': {'limit': 127, 'quantum': 20 * 1024 ** 2, 'perturb': 5}},
         {'kind': 'ingress', 'handle': 'ffff:', 'parent': 'ffff:fff1'},
         {'kind': 'mq', 'handle': '0:', 'dev': 'wlp3s0', 'root': True},
         {'kind': 'ingress', 'handle': 'ffff:', 'dev': 'vdsmtest-Z2TMO',
          'parent': 'ffff:fff1'},
         {'kind': 'pfifo_fast', 'handle': '0:', 'dev': 'em1',
          'root': True, 'refcnt': 2, 'pfifo_fast': {
              'bands': 3,
              'priomap': [1, 2, 2, 2, 1, 2, 0, 0, 1, 1, 1, 1, 1, 1, 1]}},
         {'kind': 'pfifo_fast', 'handle': '0:', 'dev': 'wlp3s0',
          'parent': ':1', 'pfifo_fast': {
              'bands': 3,
              'priomap': [1, 2, 2, 2, 1, 2, 0, 0, 1, 1, 1, 1, 1, 1, 1]}},
         {'kind': 'fq_codel', 'handle': '801e:', 'root': True, 'refcnt': 2,
          'fq_codel': {'limit': 132, 'flows': 15, 'quantum': 400,
                       'target': 5000.0, 'interval': 150000.0,
                       'ecn': True}},
     )
     for parsed, correct in zip_longest(tc.qdiscs(None, out=data),
                                        qdiscs):
         self.assertEqual(parsed, correct)
Exemple #12
0
 def test_qdiscs(self):
     data = '\n'.join((
         'qdisc hfsc 1: root refcnt 2 default 5000',
         'qdisc sfq 10: parent 1:10 limit 127p quantum 1514b',
         'qdisc sfq 20: parent 1:20 limit 127p quantum 1514b',
         'qdisc sfq 30: parent 1:30 limit 127p quantum 30Kb perturb 3sec',
         'qdisc sfq 40: parent 1:40 limit 127p quantum 20Mb perturb 5sec',
         'qdisc ingress ffff: parent ffff:fff1 ----------------',
         'qdisc mq 0: dev wlp3s0 root',
         'qdisc ingress ffff: dev vdsmtest-Z2TMO parent ffff:fff1 '
         '----------------',  # end of previous line
         'qdisc pfifo_fast 0: dev em1 root refcnt 2 bands 3 priomap  '
         '1 2 2 2 1 2 0 0 1 1 1 1 1 1 1 1',  # end of previous line
         'qdisc pfifo_fast 0: dev wlp3s0 parent :1 bands 3 priomap  '
         '1 2 2 2 1 2 0 0 1 1 1 1 1 1 1 1',  # end of previous line
         'qdisc fq_codel 801e: root refcnt 2 limit 132p flows 15 quantum '
         '400 target 5.0ms interval 150.0ms ecn',  # end of previous line
     ))
     qdiscs = (
         {'kind': 'hfsc', 'root': True, 'handle': '1:', 'refcnt': 2,
          'hfsc': {'default': 0x5000}},
         {'kind': 'sfq', 'handle': '10:', 'parent': '1:10',
          'sfq': {'limit': 127, 'quantum': 1514}},
         {'kind': 'sfq', 'handle': '20:', 'parent': '1:20',
          'sfq': {'limit': 127, 'quantum': 1514}},
         {'kind': 'sfq', 'handle': '30:', 'parent': '1:30',
          'sfq': {'limit': 127, 'quantum': 30 * 1024, 'perturb': 3}},
         {'kind': 'sfq', 'handle': '40:', 'parent': '1:40',
          'sfq': {'limit': 127, 'quantum': 20 * 1024 ** 2, 'perturb': 5}},
         {'kind': 'ingress', 'handle': 'ffff:', 'parent': 'ffff:fff1'},
         {'kind': 'mq', 'handle': '0:', 'dev': 'wlp3s0', 'root': True},
         {'kind': 'ingress', 'handle': 'ffff:', 'dev': 'vdsmtest-Z2TMO',
          'parent': 'ffff:fff1'},
         {'kind': 'pfifo_fast', 'handle': '0:', 'dev': 'em1',
          'root': True, 'refcnt': 2, 'pfifo_fast': {
              'bands': 3,
              'priomap': [1, 2, 2, 2, 1, 2, 0, 0, 1, 1, 1, 1, 1, 1, 1]}},
         {'kind': 'pfifo_fast', 'handle': '0:', 'dev': 'wlp3s0',
          'parent': ':1', 'pfifo_fast': {
              'bands': 3,
              'priomap': [1, 2, 2, 2, 1, 2, 0, 0, 1, 1, 1, 1, 1, 1, 1]}},
         {'kind': 'fq_codel', 'handle': '801e:', 'root': True, 'refcnt': 2,
          'fq_codel': {'limit': 132, 'flows': 15, 'quantum': 400,
                       'target': 5000.0, 'interval': 150000.0,
                       'ecn': True}},
     )
     for parsed, correct in zip_longest(tc.qdiscs(None, out=data),
                                        qdiscs):
         self.assertEqual(parsed, correct)
Exemple #13
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']}
Exemple #14
0
Fichier : qos.py Projet : 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']}
Exemple #15
0
 def test_qdiscs(self):
     data_lines = (
         'qdisc hfsc 1: root refcnt 2 default 5000',
         'qdisc ingress ffff: parent ffff:fff1 ----------------',
         'qdisc mq 0: dev wlp3s0 root',
         'qdisc ingress ffff: dev vdsmtest-Z2TMO parent ffff:fff1 '
         '----------------',  # end of previous line
         'qdisc pfifo_fast 0: dev em1 root refcnt 2 bands 3 priomap  '
         '1 2 2 2 1 2 0 0 1 1 1 1 1 1 1 1',  # end of previous line
         'qdisc pfifo_fast 0: dev wlp3s0 parent :1 bands 3 priomap  '
         '1 2 2 2 1 2 0 0 1 1 1 1 1 1 1 1',  # end of previous line
         'qdisc fq_codel 801e: root refcnt 2 limit 132p flows 15 quantum '
         '400 target 5.0ms interval 150.0ms ecn',  # end of previous line
     )
     data = '\n'.join(data_lines)
     qdiscs = (
         {
             'kind': 'hfsc',
             'root': True,
             'handle': '1:',
             'refcnt': 2,
             'hfsc': {
                 'default': 0x5000
             },
         },
         {
             'kind': 'ingress',
             'handle': 'ffff:',
             'parent': 'ffff:fff1'
         },
         {
             'kind': 'mq',
             'handle': '0:',
             'dev': 'wlp3s0',
             'root': True
         },
         {
             'kind': 'ingress',
             'handle': 'ffff:',
             'dev': 'vdsmtest-Z2TMO',
             'parent': 'ffff:fff1',
         },
         {
             'kind': 'pfifo_fast',
             'handle': '0:',
             'dev': 'em1',
             'root': True,
             'refcnt': 2,
             'pfifo_fast': {
                 'bands': 3,
                 'priomap': [1, 2, 2, 2, 1, 2, 0, 0, 1, 1, 1, 1, 1, 1, 1],
             },
         },
         {
             'kind': 'pfifo_fast',
             'handle': '0:',
             'dev': 'wlp3s0',
             'parent': ':1',
             'pfifo_fast': {
                 'bands': 3,
                 'priomap': [1, 2, 2, 2, 1, 2, 0, 0, 1, 1, 1, 1, 1, 1, 1],
             },
         },
         {
             'kind': 'fq_codel',
             'handle': '801e:',
             'root': True,
             'refcnt': 2,
             'fq_codel': {
                 'limit': 132,
                 'flows': 15,
                 'quantum': 400,
                 'target': 5000.0,
                 'interval': 150000.0,
                 'ecn': True,
             },
         },
     )
     for parsed, correct in zip_longest(tc.qdiscs(None, out=data), qdiscs):
         assert parsed == correct