killall() is implemented by discovering all PIDs who's name matches the
specified process, and then sending individual kills for each PID. If a
PID no longer exists by the time the kill is sent (e.g. if it was a
child of one of the previously killed PIDs), this will result in a
TargetError, which for the purposes of killall() should be ignored.
On older combinations of ADB/Android versions, the adb host command always
exits with 0 if it was able to run the command on the target, even if the
command failed (https://code.google.com/p/android/issues/detail?id=3254).
When we need the target's exit code (check_exit_code=True), we currently work
around this behaviour by echoing the target's exit code after the command and
parsing it out of the output.
The ADB behaviour is now "fixed" on newer versions with newer Androids (It's not
clear which versions these are and it appears that different builds of ADB with
the same version number differ in this respect). For those version combinations
adb_shell will currently raise a CalledProcessError when check_exit_code=False
and the target command fails.
So lets now use the "echo $?" trick whether or not we need the exit code.
Fixes https://github.com/ARM-software/devlib/issues/85
The current run_into method attempts to execute:
<...>/shutils CGMOUNT=<...> cgroups_run_into <...>
Which should instead be:
CGMOUNT=<...> <...>/shutils cgroups_run_into <...>
So just use cgroups_run_into_cmd to generate the command, then execute that.
When ANDROID_HOME is defined, ANDROID_HOME/platform-tools was appended
to the PATH in the environment of the Python interpreter. That meant
that if an adb binary was in PATH, it would be picked in preference to
the one under ANDROID_HOME. This is now reversed so that ANDROID_HOME
takes precedence.
Perviously, a parameter passed into SshConnection controlled whether the
connection was established over SSH or Telnet. Now, there is a separate
class for Telnet connections.
Now that connection classes can be passed as arguments on Target
instatiation, they are part of the user-facing API and are marked as
such by exporting them in the main __init__.py
conn_cls is no longer a class attribute and is specified on
instantiaation as well. This more flexible -- new connection types no
longer require a corresponding new Target subclass but can be used with
existing targets. This is also more consistent with how Platforms are
handled.
Unit info from comments on `struct cpuidle_state` definition in
include/linux/cpuidle.h in Linux 4.9 source (see drivers/cpuidle/sysfs.c
for the code that exposes that data to userspace)
Some systems mount multiple CGroup controllers in the same hierarchy, this
happens in desktop systems using systemd but it's also the default for
systems using CGroups v2. Unfortunately the current CGroup modules can
mount only single-controller hierarchies, thus failing when a controller
is already mounted with others in a single hierarchy.
This patch fixes this issue by:
- keeping track of which controllers are mounted in each hierarchy
- muting hierarchies instead of controllers
- creating Controller objects which reference the hierarchy they belong to
Thus, the new constructor of the Controller object requires to specify
the hierarchy ID as well as the list of controller which have to be
mounted in that hierarchy. The hierarchy ID is used to create a single
mount point for all the controllers in that hierarchy. This single mount
points are now named:
<CGMOUNT>/devlib_cgh<ID>
where "cgh" stands for "CGroup Hierarchy" and <ID> is the specified
numerical identified of that hierarchy.
This patch removes also the Controller::__new__() method, which seems not to
have sense anymore, as well as the Controller::probe() method, which is
not more used. Indeed, all and only the available hierarchies are pre-mounted
at module initialization time.
Signed-off-by: Patrick Bellasi <patrick.bellasi@arm.com>
This is just a simple re-factoring patch in preparation of the following
one. Since we have a list of CGroups subsystems, which includes the
hierarchy ID for each entry, let's use directly these namedtuples in the
mouting loop. The following patch will make use of the hierarchy ID to
properly mount each controller.
Signed-off-by: Patrick Bellasi <patrick.bellasi@arm.com>
In the previous patch:
cgroups: Mount cgroups controllers in devlib working dir
we changed the default mount point for devlib managed CGroups but forgot to
update the support for execution of a workload within a specified CGroup.
The run_into support is provide by a shutil script, which still has hardcoded
the old path (i.e. /sys/fs/cgroup/devlib_*). This patch fixes this by:
- resetting the default path to the Linux standard /sys/fs/cgroup
- use-sing the existing CGMOUNT env variable to specify which CGroups mount
point to use
The cgroups::run_into is also updated to use the self.cgroup_root via
CGMOUNT when the shutils' script is called.
Moreover, an additional cgroups::run_into_cmd method is added which just
returns a properly formatted run_into shutils' call.
Signed-off-by: Patrick Bellasi <patrick.bellasi@arm.com>
If a process is added to $PIDS but then exits before the
cgroups_task_move invokation finishes, then echoing its PID to
cgroups.procs results in an I/O error. If that process is the last in
$PIDS, then that failing echo command is the last of the function, so
the script exits with an error and devlib raises an exception.
Add `|| true` to avoid this problem.
Use case: To check if a kernel supports function profiling we need to
check for the presence of
"/sys/kernel/debug/tracing/function_profiler_enabled", but
"/sys/kernel/debug/"'s permissions are 700.
When there are multiple matches for the wildcard, the output has been
observed to have a space at the end. That means the pull command doesn't
work. This commit fixes that.
These quotes end up being passed literally into the shutils function
arguments (i.e $3 is '-e', $4 is '"foo"') which means that the grep
command never finds matches. `exclude` is a list of comms, which don't
have spaces in them, so we can just remove the quotes.
Android seems to have a buggy `mount` command which causes
`mount -o remount` to result in duplicated mounts. We can't unmonunt and
then re-mount /sys/fs/cgroup because there may be pre-existing mounts at
subdirectories. So we create a 'cgroups' directory in the devlib working
directory and mount cgroup controller FS's there.
Without this patch, this will result in an error due to trying to call
`.cgroup` on None. Making this a RuntimeError instaed means that a) you
get a more useful error message and b) you can catch the exception
without blanket `except Exception as e`.
On some systems CPUs sometimes remain idle for several seconds. If a
trace capture begins during one of these long idle periods, that CPU's
idle state is unknown (in practice it is probably in its deepest
available state from cpuidle's perspective but that can't be known for
sure).
The solution to the equivalent problem for cpufreq is to read the
current frequencies from sysfs and inject artificial cpu_frequency
events using trace_marker (see cpu_freq_trace_all_frequencies in
bin/scripts/shutils.in). However we can't read the current idle state
from sysfs.
Instead, wake up each CPU by executing the "true" command on it via
taskset.