File: infiniband.py

package info (click to toggle)
python-hardware 0.30.0-4
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 1,560 kB
  • sloc: python: 6,364; makefile: 24; sh: 6
file content (155 lines) | stat: -rw-r--r-- 6,784 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
# Copyright (C) 2013-2015 eNovance SAS <licensing@enovance.com>
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
#      http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.

"""Fetch information about Infiniband cards."""

import re
import sys

from hardware import detect_utils
from hardware.detect_utils import cmd


def ib_card_drv():
    """Return an array of IB devices (ex: ['mlx4_0'])."""
    ret, output = cmd('ibstat -l')
    if ret == 0:
        # Use filter to omit empty item due to trailing newline.
        return list(filter(None, output.split('\n')))

    return []


# {'node_guid': '0x0002c90300ea6840', 'sys_guid': '0x0002c90300ea6843',
#  'fw_ver': '2.11.500',
#   'device_type': 'MT4099',
#   'hw_ver': '0', 'nb_ports': '2'}
def ib_global_info(card_drv):
    """Return global info of a IB card in a python dict.

    :param card_drv: a card device ID (e.g. mlx4_0)
    :returns: a list containing information on the card device
    """
    global_card_info = {}
    ret, global_info = cmd('ibstat %s -s' % card_drv)
    if ret == 0:
        for line in global_info.split('\n'):
            re_dev = re.search('CA type: (.*)', line)
            if re_dev is not None:
                global_card_info['device_type'] = re_dev.group(1)
            re_nb_ports = re.search('Number of ports: (.*)', line)
            if re_nb_ports is not None:
                global_card_info['nb_ports'] = re_nb_ports.group(1)
            re_fw_ver = re.search('Firmware version: (.*)', line)
            if re_fw_ver is not None:
                global_card_info['fw_ver'] = re_fw_ver.group(1)
            re_hw_ver = re.search('Hardware version: (.*)', line)
            if re_hw_ver is not None:
                global_card_info['hw_ver'] = re_hw_ver.group(1)
            re_node_guid = re.search('Node GUID: (.*)', line)
            if re_node_guid is not None:
                global_card_info['node_guid'] = re_node_guid.group(1)
            re_sys_guid = re.search('System image GUID: (.*)', line)
            if re_sys_guid is not None:
                global_card_info['sys_guid'] = re_sys_guid.group(1)
    return global_card_info


# {'base_lid': '0', 'port_guid': '0x0002c90300ea6841', 'rate': '40',
# 'physical_state': 'Down', 'sm_lid': '0', 'state': 'Down', 'lmc': '0'}
def ib_port_info(card_drv, port):
    """Return port infos of a IB card_drv in a python dict.

    :param card_drv: a card device ID (e.g. mlx4_0)
    :param port: the port number (e.g. 1)
    :returns: a list containing information on the port
    """
    port_infos = {}
    ret, port_desc = cmd('ibstat %s %i' % (card_drv, port))
    if ret == 0:
        for line in port_desc.split('\n'):
            re_state = re.search('State: (.*)', line)
            if re_state is not None:
                port_infos['state'] = re_state.group(1)
            re_phy_state = re.search('State: (.*)', line)
            if re_phy_state is not None:
                port_infos['physical_state'] = re_phy_state.group(1)
            re_rate = re.search('Rate: (.*)', line)
            if re_rate is not None:
                port_infos['rate'] = re_rate.group(1)
            re_blid = re.search('Base lid: (.*)', line)
            if re_blid is not None:
                port_infos['base_lid'] = re_blid.group(1)
            re_lmc = re.search('LMC: (.*)', line)
            if re_lmc is not None:
                port_infos['lmc'] = re_lmc.group(1)
            re_smlid = re.search('SM lid: (.*)', line)
            if re_smlid is not None:
                port_infos['sm_lid'] = re_smlid.group(1)
            re_pguid = re.search('Port GUID: (.*)', line)
            if re_pguid is not None:
                port_infos['port_guid'] = re_pguid.group(1)
    return port_infos


def detect():
    """Detect Infiniband devices.

    To detect if an IB device is present, we search for a pci device.
    This pci device shall be from vendor Mellanox (15b3) from class 0280
    Class 280 stands for a Network Controller while ethernet device are 0200.
    """
    hw_lst = []
    status, _ = detect_utils.cmd(
        "lspci -d 15b3: -n|awk '{print $2}'|grep -q '0280'")
    if status != 0:
        sys.stderr.write('Info: No Infiniband device found\n')
        return []

    for ib_card in range(len(ib_card_drv())):
        card_type = ib_card_drv()[ib_card]
        ib_infos = ib_global_info(card_type)
        nb_ports = ib_infos['nb_ports']
        hw_lst.append(('infiniband', 'card%i' % ib_card,
                       'card_type', card_type))
        hw_lst.append(('infiniband', 'card%i' % ib_card,
                       'device_type', ib_infos['device_type']))
        hw_lst.append(('infiniband', 'card%i' % ib_card,
                       'fw_version', ib_infos['fw_ver']))
        hw_lst.append(('infiniband', 'card%i' % ib_card,
                       'hw_version', ib_infos['hw_ver']))
        hw_lst.append(('infiniband', 'card%i' % ib_card,
                       'nb_ports', nb_ports))
        hw_lst.append(('infiniband', 'card%i' % ib_card,
                       'sys_guid', ib_infos['sys_guid']))
        hw_lst.append(('infiniband', 'card%i' % ib_card,
                       'node_guid', ib_infos['node_guid']))
        for port in range(1, int(nb_ports) + 1):
            ib_port_infos = ib_port_info(card_type, port)
            hw_lst.append(('infiniband', 'card%i_port%i' % (ib_card, port),
                           'state', ib_port_infos['state']))
            hw_lst.append(('infiniband', 'card%i_port%i' % (ib_card, port),
                           'physical_state',
                           ib_port_infos['physical_state']))
            hw_lst.append(('infiniband', 'card%i_port%i' % (ib_card, port),
                           'rate', ib_port_infos['rate']))
            hw_lst.append(('infiniband', 'card%i_port%i' % (ib_card, port),
                           'base_lid', ib_port_infos['base_lid']))
            hw_lst.append(('infiniband', 'card%i_port%i' % (ib_card, port),
                           'lmc', ib_port_infos['lmc']))
            hw_lst.append(('infiniband', 'card%i_port%i' % (ib_card, port),
                           'sm_lid', ib_port_infos['sm_lid']))
            hw_lst.append(('infiniband', 'card%i_port%i' % (ib_card, port),
                           'port_guid', ib_port_infos['port_guid']))
    return hw_lst