Esempio n. 1
0
    def _set_launch_distance(self):
        """Set launch distance limits to driver."""

        try:
            limit_path = self._basedir / "ldist_max_nsec"
            with self._proc.open(limit_path, "r") as fobj:
                ldist_max = fobj.read().strip()

            limit_path = self._basedir / "ldist_min_nsec"
            with self._proc.open(limit_path, "r") as fobj:
                ldist_min = fobj.read().strip()
        except Error as err:
            raise Error(
                f"failed to read launch distance limit from '{limit_path}'"
                f"{self._proc.hostmsg}:\n{err}")

        ldist_min = Trivial.str_to_num(ldist_min)
        ldist_max = Trivial.str_to_num(ldist_max)
        from_path = self._basedir / "ldist_from_nsec"
        to_path = self._basedir / "ldist_to_nsec"

        for ldist, ldist_path in zip_longest(self._ldist, [from_path, to_path],
                                             fillvalue=self._ldist[-1]):
            if ldist < ldist_min or ldist > ldist_max:
                raise Error(
                    f"launch distance '{ldist}' is out of range, it should be in range of "
                    f"[{ldist_min},{ldist_max}]")
            if not FSHelpers.exists(ldist_path, proc=self._proc):
                raise Error(
                    f"path i'{ldist_path}' does not exist{self._proc.hostmsg}")
            # open()/write() doesn't work for this file when done over SSH.
            self._proc.run_verify(f"echo {ldist} > {ldist_path}", shell=True)
Esempio n. 2
0
def validate_ldist(ldist):
    """
    Validate and modify launch distanse. 'ldist' argument is string of single or two comma-separated
    integers, and tells launch distance in microseconds. Return value is launch distance in
    nanoseconds, as list of one or two integers.
    """

    ldst = Trivial.split_csv_line(ldist)

    for idx, val in enumerate(ldst):
        ldst[idx] = Trivial.str_to_num(val, default=None)
        if ldst[idx] is None:
            raise Error(f"bad launch distance '{ldist}', should be an integer")
        if ldst[idx] <= 0:
            raise Error(
                f"bad launch distance value '{ldst[idx]}', should be greater than zero"
            )

    ldst_str = ", ".join([str(val) for val in ldst])
    if len(ldst) > 2:
        raise Error(
            f"bad launch distance range '{ldst_str}', it should include 2 numbers"
        )
    if len(ldst) == 2 and ldst[1] - ldst[0] < 0:
        raise Error(
            f"bad launch distance range '{ldst_str}', first number cannot be "
            f"greater than the second number")

    # Return launch distance as nanoseconds.
    for idx, val in enumerate(ldst):
        ldst[idx] = val * 1000

    return ldst
Esempio n. 3
0
def _get_percentile(funcname):
    """
    Parses and validates the percentile statistics function name (e.g., "99%") and returns the
    percent value (99).
    """

    percent = Trivial.str_to_num(funcname[:-1])
    if percent <= 0 or percent >= 100:
        raise Error(f"bad percentile number in '{funcname}', should be in range of "
                    f"(0, 100)")
    return percent
Esempio n. 4
0
    def get_resolution(self):
        """Returns resolution of the delayed event devices in nanoseconds."""

        try:
            path = self._basedir / "resolution_nsec"
            with self._proc.open(path, "r") as fobj:
                resolution = fobj.read().strip()
        except Error as err:
            raise Error(
                f"failed to read the delayed event reslolution from '{path}'"
                f"{self._proc.hostmsg}:\n{err}")

        return Trivial.str_to_num(resolution)
Esempio n. 5
0
    def set_post_trigger(self, path, trange=None):
        """
        Configure the post-trigger - a program that has to be executed after a datapoint is
        collected. The arguments are as follows.
          * path - path to the executable program to run. The program will be executed with the
            '--latency <value>' option, where '<value>' is the observed wake latency value in
            nanoseconds.
          * trange - the post-trigger range. By default, the trigger program is executed on every
            datapoint. But if the trigger range is provided, the trigger program will be executed
            only when wake latency is in trigger range.
        """

        if not FSHelpers.isexe(path, proc=self._proc):
            raise Error(
                f"post-trigger program '{path}' does not exist{self._proc.hostmsg} or it "
                f"is not an executable file")

        self._post_trigger = path

        if trange is not None:
            vals = Trivial.split_csv_line(trange)

            for idx, val in enumerate(vals):
                if not Trivial.is_int(val):
                    raise Error(
                        f"bad post-trigger range value '{val}', should be an integer "
                        f"amount of nanoseconds")
                vals[idx] = Trivial.str_to_num(val, default=None)
                if vals[idx] < 0:
                    raise Error(
                        f"bad post trigger range value '{vals[idx]}', should be greater or "
                        f"equal to zero")

            if len(vals) != 2:
                raise Error(
                    f"bad post trigger range '{trange}', it should include 2 numbers"
                )
            if vals[1] - vals[0] < 0:
                raise Error(
                    f"bad post trigger range '{trange}', first number cannot be greater "
                    f"than the second number")

            self._post_trigger_range = vals
Esempio n. 6
0
def _deploy_prepare(args, toolname, minkver):
    """
    Validate command-line arguments of the "deploy" command and prepare for builing the helpers and
    drivers. The arguments are as follows.
      o args - the command line arguments.
      o toolname - name of the tool being deployed (e.g., 'ndl').
      o minkver - the minimum required version number.
    """

    args.tmpdir = None
    args.kver = None

    if not args.ihost:
        args.ihost = "localhost"
    if not args.bhost:
        args.bhost = args.ihost

    if args.ihost != args.bhost and not args.bhost == "localhost":
        raise Error("build host (--build-host) must be the local host or the same as deploy host "
                    "(--host)")

    if args.ihost == "localhost" and args.bhost == "localhost":
        for attr in ("username", "privkey", "timeout"):
            if getattr(args, attr) is not None:
                _LOG.warning("ignoring the '--%s' option as it not useful for a local host", attr)

    if not args.timeout:
        args.timeout = 8
    else:
        args.timeout = Trivial.str_to_num(args.timeout)
    if not args.username:
        args.username = "******"

    if args.privkey and not args.privkey.is_dir():
        raise Error(f"path '{args.privkey}' does not exist or it is not a directory")

    if hasattr(args, "drvsrc"):
        if not args.drvsrc:
            args.drvsrc = FSHelpers.search_for_app_data("wult", _DRV_SRC_SUBPATH/f"{toolname}",
                                                        pathdescr=f"{toolname} drivers sources")

        if not args.drvsrc.is_dir():
            raise Error(f"path '{args.drvsrc}' does not exist or it is not a directory")

    if hasattr(args, "helpersrc"):
        if not args.helpersrc:
            args.helpersrc = FSHelpers.search_for_app_data("wult",
                                                           _HELPERS_SRC_SUBPATH/f"{toolname}",
                                                           pathdescr=f"{toolname} helper sources")
        if not args.helpersrc.is_dir():
            raise Error(f"path '{args.helpersrc}' does not exist or it is not a directory")

    with contextlib.closing(get_proc(args, args.bhost)) as proc:
        if not FSHelpers.which("make", default=None, proc=proc):
            raise Error(f"please, install the 'make' tool{proc.hostmsg}")

        if not args.ksrc:
            args.kver = KernelVersion.get_kver(proc=proc)
            if not args.ksrc:
                args.ksrc = Path(f"/lib/modules/{args.kver}/build")
        else:
            args.ksrc = FSHelpers.abspath(args.ksrc, proc=proc)

        if not FSHelpers.isdir(args.ksrc, proc=proc):
            raise Error(f"kernel sources directory '{args.ksrc}' does not exist{proc.hostmsg}")

        if not args.kver:
            args.kver = KernelVersion.get_kver_ktree(args.ksrc, proc=proc)

        _LOG.info("Kernel sources path: %s", args.ksrc)
        _LOG.info("Kernel version: %s", args.kver)

        if KernelVersion.kver_lt(args.kver, minkver):
            raise Error(f"version of the kernel{proc.hostmsg} is {args.kver}, and it is not new "
                        f"enough.\nPlease, use kernel version {minkver} or newer.")

        args.tmpdir = FSHelpers.mktemp(prefix=f"{toolname}-", proc=proc)

        if hasattr(args, "drvsrc"):
            _LOG.debug("copying the drivers to %s:\n   '%s' -> '%s'",
                       proc.hostname, args.drvsrc, args.tmpdir)
            proc.rsync(f"{args.drvsrc}/", args.tmpdir / "drivers", remotesrc=False, remotedst=True)
            args.drvsrc = args.tmpdir / "drivers"
            _LOG.info("Drivers will be compiled on host '%s'", proc.hostname)

        if hasattr(args, "helpersrc"):
            _LOG.debug("copying the helpers to %s:\n  '%s' -> '%s'",
                       proc.hostname, args.helpersrc, args.tmpdir)
            proc.rsync(f"{args.helpersrc}/", args.tmpdir / "helpers", remotesrc=False,
                       remotedst=True)
            args.helpersrc = args.tmpdir / "helpers"
            _LOG.info("Helpers will be compiled on host '%s'", proc.hostname)

    with contextlib.closing(get_proc(args, args.ihost)) as proc:
        if not args.kmodpath:
            args.kmodpath = Path(f"/lib/modules/{args.kver}")
        if not FSHelpers.isdir(args.kmodpath, proc=proc):
            raise Error(f"kernel modules directory '{args.kmodpath}' does not exist{proc.hostmsg}")

        _LOG.info("Drivers will be deployed to '%s'%s", args.kmodpath, proc.hostmsg)
        _LOG.info("Kernel modules path%s: %s", proc.hostmsg, args.kmodpath)

        if hasattr(args, "helpersrc"):
            if not args.helpers_path:
                args.helpers_path = get_helpers_deploy_path(proc, toolname)
            _LOG.info("Helpers will be deployed to '%s'%s", args.helpers_path, proc.hostmsg)