Skip to content

pv-runtime: Use more file-descriptor-relative I/O

Simon McVittie requested to merge wip/smcv/overrides-fdio into main

There are several overlapping goals to this branch:

  • Shorten log messages by making things happen relative to /overrides. With a soldier container on a Debian 12 test system, this reduces the size of the log from about 345K to 305K.
  • Reduce diff noise between otherwise similar logs, so we can compare them more easily
  • Make pv-runtime less confusing by juggling fewer subtly different versions of the same path relative to different places (this is only partially achieved, we still store the path in the container separately for now)
  • More error detection, where I happened to notice we were ignoring it

After this branch, remaining diff noise comes from:

  • The pid in the pressure-vessel[xxx] prefix (out of scope for this branch, and easy to postprocess out)
  • The final arguments to bwrap, which are important to output and relatively easy to ignore; we could convert them to be relative to a fd pointing to the mutable sysroot if desired, but that might be better as a separate branch
  • Profiling timings, which we should suppress when we are trying to minimize diff, but that's out of scope for this branch, and in any case they're not that noisy (O(1) of them)
  • Process IDs of the processes we run (easy to ignore because they're all right at the end)
  • A couple of mentions of the path to the tmp-XXXXXX directory, from which we should keep at least one so that the info is in the log at all (but in any case these are O(1) and easy to ignore because they're bunched together)
  • pv-adverb's LOCPATH (O(1) times, and easy to ignore because it's right at the end)

/cc @denittis


  • pv-runtime: Open the overrides directory as a file descriptor

    We'll use this to do I/O relative to this file descriptor, instead of using absolute paths in the current filesystem namespace.

    To make this work, we have to create the directory with its parents. Previously, we were only creating the last path component, which was fine when creating /tmp/pressure-vessel-wrap.XXXXXX/overrides in a directory /tmp/pressure-vessel-wrap.XXXXXX that we already created, but didn't work in practice when creating .../var/tmp-XXXXXX/usr/lib/pressure-vessel/overrides. This was hidden by the fact that we didn't check the result of g_mkdir() for errors, and by the time we tried to do anything with the overrides directory, we had created .../var/tmp-XXXXXX/usr/lib/pressure-vessel/overrides/lib/TUPLE with its parents (with the side-effect of creating the overrides directory).

  • pv-runtime: Cache some paths relative to overrides fd

    We'll use these to do fd-relative I/O.

  • pv-runtime: Capture libraries into a path relative to /overrides

    The resulting /proc-relative path will be a lot shorter than a full path including /overrides, and if we are doing the same operations in the same order during initialization, then in practice the file descriptor will be the same; both of these make log files easier to diff.

    This also lets us thread relative paths through the various functions that call this one, which will make it easier to make their logging equally concise.

  • pv-runtime: Use relative paths to capture libraries in simple cases

  • pv-runtime: Use fd-relative I/O in bind_icds()

    This gives us shorter log messages based on paths relative to the overrides directory.

  • pv-runtime: Use fd-relative I/O to create symlinks in aliases/

  • pv-runtime: Detect errors when creating directories below /overrides

  • pv-runtime: Look up overridden libraries with fd-relative I/O

    This means we are "naturally" working with relative paths, reducing duplication in our debug log messages.

  • pv-runtime: Use fd-relative I/O to inspect glibc symlink

  • pv-runtime: Use fd-relative I/O for pv_runtime_collect_lib_symlink_data

    This brings us a step closer to having all accesses to /overrides be relative to the overrides_fd, which would make the various absolute and relative paths pointing into /overrides less confusing.

  • pv-runtime: Use fd-relative I/O when deciding what aliases to create

  • pv-runtime: Stop caching absolute paths pointing into .../overrides

    We now do all I/O via self->overrides_fd.

  • pv-runtime: Make pv_runtime_get_capsule_capture_libs failable

  • pv-runtime: Look up libcapsule knowledge using fd-relative I/O

    This removes some avoidable diff between capsule-capture-libs calls.

  • pv-runtime: Pass container to capsule-capture-libs with fd-relative I/O

    This avoids another diff between otherwise similar logs.

  • pv-runtime: Abbreviate path to generated JSON manifests

    If we give a relative path starting with overrides/, it's reasonably obvious from context what file we're writing to on the host system and where it will end up in the container. The necessary code restructuring to do this also makes it more obvious that the path write_to_file in the current execution environment, the path json_in_container in the resulting container, and the debug-log message all match up.

    We still need write_to_dir in setup_each_json_manifest(), but only to create the directory we're going to be populating.

Edited by Simon McVittie

Merge request reports