[DTrace-devel] top-of-file comment for one-parse-per-mapping world (was Re: [PATCH v3 06/21] dtprobed: add the DOF stash)
Nick Alcock
nick.alcock at oracle.com
Wed Feb 14 17:21:24 UTC 2024
On 12 Feb 2024, Nick Alcock stated:
> On 12 Feb 2024, Kris Van Hees spake thusly:
>
>> Initial comments (mostly on the comments, that are pretty crucial for people
>> to understand what is going on here).
>
> ... here's the new top-of-file comment block, which hopefully make a bit
> more sense now:
[...]
... and here's what it might look like in a one-file-per-mapping world:
* The state storage structure is as follows:
*
* /run/dtrace/stash/: Things private to dtprobed.
*
* .../dof/$dev-$ino/: DOF contributed by particular mappings (as
* received from some probe-containing program).
*
* .../dof/$dev-$ino/raw: raw DOF, precisely as received
*
* .../dof/$dev-$ino/parsed: parsed DOF, dofhp_addr-independent (as
* if dofhp_addr were 0).
*
* .../dof/$dev-$ino/relocs: unknown reloc-like indications of what
* offsets in "parsed" to adjust to apply a dofhp_addr with a given
* offset (... maybe just a straight list of 64-bit file offsets?)
*
* .../dof-pid/$pid/$dev-$ino/: contains everything relating to DOF
* contributed by a particular USDT-containing ELF object within a given
* process (henceforth "DOF source"). Each DTRACEHIOC_ADDDOF ioctl call
* creates one of these.
*
* .../dof-pid/$pid/$gen: symlink to a single $dev-$ino dir. "$gen" is an
* incrementing generation counter starting at zero for every unique PID,
* used to uniquely identify DOF pieces to remove.
*
* .../dof-pid/$pid/next-gen: The next generation counter to use for a new
* piece of DOF from this process. Encoded as a sparse file whose size is
* the next counter value to use.
*
* .../dof-pid/$pid/exec-mapping: a dev/ino pair in the form
* $dev-$ino (as in the $dev-$ino directory entries): the dev/ino of the
* process's primary text mapping, as given by libproc.
*
* .../dof-pid/$pid/$dev-$ino/raw: hardlink to the raw DOF for
* a given DOF source. Pruned of dead processes at startup and on
* occasion: entries also deleted on receipt of DTRACEHIOC_REMOVE
* ioctls. A hardlink is used in order to bump the link count for
* the corresponding parsed DOF in the dof/$dev-$ino/ directory: when this
* link count falls to 1, the DOF is considered dead and the
* corresponding probe is removed.
*
* .../dof-pid/$pid/$dev-$ino/dh: Raw form of the dof_helper_t received from
* a given DTRACEHIOC_ADDDOF, serialized straight to disk with no changes.
* Preserved for all DTRACEHIOC_ADDDOFs, even if the DOF was already
* contributed by some other process. Keeping this around allows the DOF to
* be re-parsed as needed, even by a later re-execution of a different
* version of the same daemon with a different dof_parsed_t structure, and to
* be re-parsed with appropriate addresses for whichever mapping of this DOF
* is under consideration.
*
* .../dof-pid/$pid/$dev-$ino/parsed/: Directory containing broken-up
* parsed DOF for a given DOF source. Deleted when empty.
*
* .../dof-pid/$pid/$dev-$ino/parsed/all: parsed DOF (from
* /dof/$dev-$ino/parsed) with relocs applied given dof-pid/.../dh
* and dof-pid/.../relocs. Deleted at daemon startup if the
* dof_parswed_t structure changes. The file consists of a
* uint64_t version number (DOF_PARSED_VERSION), a uint64_t count of
* tracepoints, and then that many struct dof_parsed_t's of type
* DIT_TRACEPOINT. Broken up into...
* # (... may not need this one at all, we might be able to reloc and
* # cut into chunks simultaneously? there is no other use for this
* # file other than generating the split-up parsed stuff below.)
*
* .../dof-pid/$pid/$dev-$ino/parsed/$prv$pid:$mod:$fun:$prb: ...
* parsed DOF for a given PID/mapping/probe triplet, from
* dof/$dev-$ino/parsed with relocs from dof/$dev-$ino/relocs
* applied, given the addresses in .../dh. Deleted at daemon startup
* if the dof_parsed_t structure changed.
*
* /run/dtrace/probes/: Per-probe info, written by dtprobed, read by DTrace.
*
* .../$pid/$prv$pid/$mod/$fun/$prb: Hardlink from $prv$pid:$mod:$fun:$prb
* above; parsed representation of one probe in a given process. Removed by
* dtprobed when the process dies, or if all mappings containing the probe
* are unmmapped. Used by DTrace for tracing by PID.
*
* (If a probe exists in multiple different mappings in a given process, they
* must all be identical.)
*
* In future, symlinks in /run/dtrace/probes/$prv$pid may exist, used for
* globbing provider names across processes.
The dof_parsed_t gains a new enumerand DIT_RELOC connected to this new
entry in the unnamed union in dof_parsed_t (DOF_PARSED_VERSION 2):
struct dpi_reloc {
/*
* A location needing dofhp_addr-relative relocation.
*/
size_t offset;
};
The parser stuffs these into the parser stream whenever it currently
applies a reloc (in dof_slurp()). dof_stash.c can then trivially run
down these, write them to /relocs, and later use those to apply relocs
to the DOF to emit per-PID, per-mapping DOF without reparsing anything
or relying on the dofhp_addr at parse time. We don't need a reloc type
or anything because the parser only applies one type of reloc anyway :)
... does this make sense?
More information about the DTrace-devel
mailing list