Introduce dtoctl, a CLI wrapper for running programs with DTO preloaded - #33
Introduce dtoctl, a CLI wrapper for running programs with DTO preloaded#33honggyukim wants to merge 3 commits into
Conversation
Using the DTO library today requires the user to understand two orthogonal mechanisms before a single program can be offloaded to DSA. The library has to be injected into the target through LD_PRELOAD, and its behavior is steered entirely through a set of roughly twenty DTO_* environment variables that must be discovered by reading the manual and then exported by hand. This is easy to get wrong: the LD_PRELOAD path and the variable names are stringly typed, an exported variable silently leaks into every later command in the same shell, and there is no validation or discoverability at the point of use. Provide a small wrapper, dtoctl, that turns this into a single self-describing command line. It follows the same model as hmctl from the hmsdk project: parse options, translate them into the environment the library expects, and then exec the target program so no state lingers in the caller's shell. On top of that model dtoctl also takes care of the injection itself by prepending the resolved libdto.so to LD_PRELOAD, which is possible because DTO works by transparently interposing on the standard memory APIs. Every DTO_* variable is exposed as an option so the mapping stays obvious and greppable. Only options that are actually given are written to the child environment; anything left unset keeps whatever the caller already exported or the library's own default, and an explicit option wins over an inherited variable. The library path is resolved from -l/--library, then $DTO_LIBRARY, then a compiled-in default, and execvp() is used so a bare command name on PATH works as well as an explicit path. Build and install dtoctl with both Make and CMake. Set its compiled-in library path to match the installation directory, since CMake's default /usr/local/lib differs from the Makefile's /usr/lib64. Allow that path to be overridden with DTOCTL_LIBPATH. With this in place the previous incantation $ export LD_PRELOAD=/usr/lib64/libdto.so $ export DTO_WAIT_METHOD=busypoll $ export DTO_CPU_SIZE_FRACTION=0.33 $ ./prog collapses to $ dtoctl -w busypoll -c 0.33 ./prog Signed-off-by: Honggyu Kim <honggyu.kim@sk.com>
The dtoctl options mirror the DTO_* environment variables, but a user coming to the tool for the first time still needs a single authoritative place that explains what each option does, what values it accepts, and how the library path and LD_PRELOAD are resolved. Scattering that information across the source help text alone makes it hard to consult without running the tool. Add a manual page in the same troff-friendly markdown form the hmsdk project uses for hmctl, and render it as a section 1 man page for the user command. Besides the per-option reference it documents the library resolution order and the override semantics, and it gathers the common tuning goals - latency, power, and cache-pollution avoidance - as ready-to-run examples such as $ dtoctl -w umwait -c 0.0 --no-auto-adjust ./prog so users can map an intent directly onto a command instead of reverse engineering it from the individual variables. Keep the markdown as the source form and generate dtoctl.1 with pandoc during the Makefile and CMake builds. Both build systems install the generated page under man1, so it can be read with $ man 1 dtoctl Pandoc is optional: when it is unavailable, print a message recommending its installation and skip manual generation. The Makefile can still install an already generated page. Ignore its generated doc/dtoctl.1 and remove it on make clean; CMake keeps its generated page in the build directory. Signed-off-by: Honggyu Kim <honggyu.kim@sk.com>
The README is where users first learn how to configure and run DTO, and until now it only described the manual LD_PRELOAD and DTO_* export workflow. A reader following it has no reason to know that dtoctl exists or that it removes most of that ceremony, so the easier path stays hidden precisely where people look for guidance. Introduce dtoctl after the environment variable reference and the common usage models that accompany it, so that discussion stays in one piece and the new section can point back at those usage models. Contrast the old export sequence with the equivalent $ dtoctl -w busypoll -c 0.33 ./prog and spell out the resolution order for libdto.so along with the rule that only the options actually passed are applied. Keep the per-option reference in dtoctl(1) instead of repeating it here. The option list already exists in the --help output and in the manual, and a third copy in the README would only be one more place to forget when an option changes. Signed-off-by: Honggyu Kim <honggyu.kim@sk.com>
|
Hi @byrnedj, this is the work that I showed you before. Please have a look. Thanks! |
There was a problem hiding this comment.
🟡 Changes recommended
There are a few correctness/UX issues (notably --stats-file not enabling stats) plus build cleanup gaps and missing test coverage for the new CLI behavior.
Once you've addressed the issues Copilot identified, you can request another Copilot review.
Pull request overview
This PR introduces dtoctl, a small CLI wrapper that configures DTO via command-line options, sets the corresponding DTO_* environment variables, prepends libdto.so to LD_PRELOAD, and then execs the target program to avoid leaking configuration into the caller’s shell.
Changes:
- Add
dtoctlexecutable that translates CLI options intoDTO_*env vars and composesLD_PRELOAD. - Add user documentation for
dtoctl(README section + pandoc-generateddtoctl(1)manpage source). - Update Makefile/CMake build and install flows to build/install
dtoctland optionally generate/install the man page.
File summaries
| File | Description |
|---|---|
| README.md | Documents dtoctl usage and library path resolution behavior. |
| Makefile | Builds/installs dtoctl and optionally generates/installs dtoctl(1) via pandoc. |
| dtoctl.c | Implements the dtoctl CLI wrapper (arg parsing, env var mapping, LD_PRELOAD composition, exec). |
| doc/dtoctl.md | Adds the dtoctl(1) manual source (pandoc markdown). |
| CMakeLists.txt | Adds dtoctl build/install rules and optional manpage generation/install. |
| .gitignore | Ignores the dtoctl binary and generated doc/dtoctl.1. |
Review details
- Files reviewed: 5/6 changed files
- Comments generated: 4
- Review effort level: Lite
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
| case OPT_STATS_FILE: | ||
| opts->stats_file = arg; | ||
| break; |
| clean: | ||
| rm -rf *.o *.so dto-test | ||
| rm -rf *.o *.so dto-test dtoctl | ||
| rm -f doc/dtoctl.1 |
| free(preload); | ||
| } | ||
|
|
||
| int main(int argc, char *argv[]) |
| execvp(opts.exename, argv); | ||
| perror(opts.exename); | ||
|
|
||
| return -1; |
Using DTO currently requires understanding two orthogonal mechanisms before a single
program can be offloaded to DSA. The library has to be injected into the target
through
LD_PRELOAD, and its behavior is steered entirely through manyDTO_*environment variables that have to be discovered in the README and then exported
by hand. That is easy to get wrong: the preload path and the variable names are
stringly typed, an exported variable silently leaks into every later command in
the same shell, and there is no validation or discoverability at the point of
use.
This adds
dtoctl, a small wrapper that turns the setup into a singleself-describing command line. It parses options, translates them into the
environment the library expects, prepends the resolved
libdto.sotoLD_PRELOAD, and thenexecvp()s the target program, so nothing lingers in thecaller's shell.
So the previous usage
collapses to