Beispiel #1
0
    def prepare(self):
        """Prepare to start measurements."""

        # Ensure the kernel is fresh enough.
        kver = KernelVersion.get_kver(proc=self._proc)
        if KernelVersion.kver_lt(kver, "5.1-rc1"):
            raise Error(
                f"version of the running kernel{self._proc.hostmsg} is {kver}, but it "
                f"does not support the ETF qdisc.\nPlease, use kernel version 5.1 or "
                f"newer")

        try:
            self._nmcli = _Nmcli.Nmcli(proc=self._proc)
        except ErrorNotSupported:
            pass
        else:
            # We have to configure the I210 network interface in a special way, but if it is managed
            # by NetworkManager, the configuration may get reset at any point. Therefore, detach the
            # network interface from NetworkManager.
            _LOG.info("Detaching network interface '%s' from NetworkManager%s",
                      self._ifname, self._proc.hostmsg)
            self._nmcli.unmanage(self._ifname)

        # Ensure the interface exists and has carrier. It must be brought up before we can check the
        # carrier status.
        self._netif.up()
        self._netif.wait_for_carrier(10)

        # Make sure the network interface has an IP address.
        ipaddr = self._netif.get_ipv4_addr(default=None)
        if ipaddr:
            _LOG.debug("network interface '%s'%s has IP address '%s'",
                       self._ifname, self._proc.hostmsg, ipaddr)
        else:
            ipaddr = self._netif.get_unique_ipv4_addr()
            ipaddr += "/16"
            self._netif.set_ipv4_addr(ipaddr)
            # Ensure the IP was set.
            self._netif.get_ipv4_addr()
            _LOG.info("Assigned IP address '%s' to interface '%s'%s", ipaddr,
                      self._ifname, self._proc.hostmsg)

        self._drv.load(unload=True, opts=f"ifname={self._ifname}")

        # We use the ETF qdisc for scheduling delayed network packets. Configure it and start the
        # 'phc2sys' process in background in order to keep the host and NIC clocks in sync.

        # Get the TAI offset first.
        stdout, _ = self._proc.run_verify(
            f"{self._ndlrunner_bin} --tai-offset")
        tai_offset = self._get_line(prefix="TAI offset", line=stdout)
        if not Trivial.is_int(tai_offset):
            raise Error(
                f"unexpected 'ndlrunner --tai-offset' output:\n{stdout}")

        _LOG.info("Configuring the ETF qdisc%s", self._proc.hostmsg)
        self._etfqdisc.configure()
        _LOG.info("Starting NIC-to-system clock synchronization process%s",
                  self._proc.hostmsg)
        self._etfqdisc.start_phc2sys(tai_offset=int(tai_offset))
Beispiel #2
0
def _parse_turbostat_line(heading, line):
    """Parse a single turbostat line."""

    line_data = {}
    for key, value in zip_longest(heading.keys(), line):
        if value is not None and value != "-":
            if not heading[key]:
                if Trivial.is_int(value):
                    heading[key] = int
                elif Trivial.is_float(value):
                    heading[key] = float
                else:
                    heading[key] = str
            line_data[key] = heading[key](value)

    return line_data
Beispiel #3
0
def is_root(proc=None):
    """
    If 'proc' is 'None' or a 'Proc' object, return 'True' if current process' user name is 'root'
    and 'False' if current process' user name is not 'root'. If 'proc' is an 'SSH' object, returns
    'True' if the SSH user has 'root' permissions on the remote host, otherwise returns 'False'.
    """

    if not proc or not proc.is_remote:
        return Trivial.is_root()

    stdout, _ = proc.run_verify("id -u")
    stdout = stdout.strip()
    if not Trivial.is_int(stdout):
        raise Error(
            "unexpected output from 'id -u' command, expected an integer, got:\n{stdout}"
        )

    return int(stdout) == 0
Beispiel #4
0
    def _get_latency(self):
        """
        Read the next latency data line from the 'ndlrunner' helper, parse it, and ireturn the
        resulting dictionary.
        """

        line = self._get_line(prefix="datapoint")
        line = Trivial.split_csv_line(line)

        if len(line) != 2:
            msg = self._unexpected_line_error_prefix(line)
            raise Error(
                f"{msg}\nExpected 2 comma-separated integers, got {len(line)}")

        for val in line:
            if not Trivial.is_int(val):
                msg = self._unexpected_line_error_prefix(line)
                raise Error(
                    f"{msg}\n: Expected 2 comma-separated integers, got a non-integer "
                    f"'{val}'")

        # Convert nanoseconds to microseconds.
        line = [int(val) / 1000 for val in line]
        return {"RTD": line[0], "LDist": line[1]}