Hi all,
My colleague Will Cohen recently floated the idea of using PCP to
carefully lift some permissions restrictions in tools like perf,
and to enable perf functionality to be injected into PCP to some
extent. This RFC mail is an attempt to describe one possible way
to approach doing this, as I think its an awesome idea - even in
its most simple of forms (as described below).
A common form of running the Linux perf utility is with its script
command - see "perf scripts --list" for a comprehensive list, but
some examples are:
$ perf script --list
List of available trace scripts:
rw-by-pid system-wide r/w activity
rw-by-file <comm> r/w activity for a program, by file
failed-syscalls [comm] system-wide failed syscalls
However, these almost always require root permissions (modulo some
system-wide perf_event_paranoid trickery). Many sites would like
to have a less restrictive form of access control for running the
scripts and capturing their output for analysis. Note that many
scripts have parameters, such as a PID. It is also a very common
model to invoke these scripts for a short time, after which they
report collected data and then exit.
We could tackle this problem with a new pmdapipe(1) agent in PCP,
running as root and arbitrating access to the privileged commands.
This PMDA would primarily export one event metric, with records of
string type holding the command output. One of a configured set of
commands could be executed via pmevent(1) connecting to this PMDA
(via pmcd) which would execute the requested command and "pipe" the
output back to a client utility as event records. This client tool
would need very little intelligence, simply dumping the text out to
standard output (a --quiet mode to pmevent would possibly suffice).
The existing -x option to pmevent could be used to send parameters
to the PMDA from the client tool, before the pipe commences.
The piping (hot) PMDA would be more involved. It would need to:
- enforce access controls before allowing any command to be run on
behalf of an unprivileged client. This could be in the form of
using the client credentials (uid/gid) attributes, and an initial
specification on which users/groups are allowed access.
- provide a mechanism for configuration of a set of allowed commands
that it is prepared to execute, and a way to map the parameters to
the command line before executing the tool.
- track each remote client using the client-context-tracking feature
to ensure the event stream is sent to the originating client.
- once user credentials and parameters have been passed, and tracing
begins (via client-driven fetch), fork/exec the relevant command,
capture the output as it arrives and ship it back to the client.
- either when the child command exits or the client tool disconnects,
reap the child process and go back to passively lurking, awaiting
the next request.
To achieve the generalised configuration goals (while restricting the
runnable commands to a sanitised, secure, sysadmin-approved set), the
PMDA could read a configuration file on startup (and SIGHUP), perhaps
with a syntax along these lines:
$ cat /var/lib/pcp/pmdas/pipe/sample.conf
# instance user commands
rw_syscalls root perf script rw-by-file $1
bdev_trace root btrace -w $1 /dev/$2
[access]
allow user bob : all;
allow group perf : rw_syscalls;
With a setup like the above, a pmevent invocation like the following
should be possible as unprivileged user "bob":
$ pmevent -i bdev_trace -x '5 sda' pipe.firehose
8,2 5 1 0.000000000 25227 A WS 734332384 + 24 <- (253,2) 734330336
8,0 5 2 0.000000414 25227 A WS 735358432 + 24 <- (8,2) 734332384
8,0 5 3 0.000000756 25227 Q WS 735358432 + 24 [qemu-kvm]
[...5 seconds worth]
$
cheers.
--
Nathan
|