When an automount goes away, the tokens we answer are only those we have
read from the pipe. Requests the kernel queued after our last read stayed
blocked: closing the pipe does not wake them, the kernel only notices the
closed pipe and turns the autofs catatonic when yet another request fails
to reach us, and after the lazy unmount no request reaches it anymore. In
the normal stop path that window is one event loop iteration; for an
automount torn down at coldplug it spans the whole reload.
Set the autofs to catatonic state before letting go of it, which fails
everything still queued with ENOENT. Answer the known tokens first:
closing our end of the pipe before that made a racing request flip the
kernel into catatonic mode on its own, which discards the queue and
turns our answers into "token not found" errors.
Signed-off-by: Martin Pitt <martin@amutable.com>
When an automount unit ceases to exist across daemon-reload (observed:
because a generator no longer emits it), its deserialized state still
makes `automount_coldplug()` pick up the autofs pipe and resume the unit
as waiting/running. But nothing can serve that mount point anymore. The
kernel keeps blocking every process that touches the mount point until
PID 1 answers (which it won't), forever.
To fix this, fail pending requests and unmount the autofs when
coldplugging an automount unit that is not loaded anymore.
Fixes#43700
Signed-off-by: Martin Pitt <martin@amutable.com>
When an automount goes away, answering the requests the kernel already
queued is the only thing that unblocks the processes waiting on them, and
nothing retries it later. If the `EHOSTDOWN` calls fail, it leaves the
requesting processes hung with no trace in the journal.
Log the failures to make this easier to debug. Also move that teardown into
a helper function, the next commit needs it as well.
Signed-off-by: Martin Pitt <martin@amutable.com>
Releasing the requests the kernel queued goes through `open_ioctl_fd()`, which
asserts on the manager fd for /dev/autofs. That fd stays unset when
`open_dev_autofs()` fails while coldplugging an automount, while the
deserialized pipe and its tokens outlive it.
Report the failure to the caller instead of asserting/crashing PID 1.
Signed-off-by: Martin Pitt <martin@amutable.com>
The previous commit uses `parse_source_date_epoch()` for creating FAT
time stamps. Do the same in `mtools_exec()`, `mkfs.*`, and
`$E2FSPROGS_FAKE_TIME` instead of passing the raw environment variable.
That avoids these programs creating time stamps from a value we would
have rejected ourselves (unparsable, overflowing), read differently
(e.g. octal numbers), or from one that `secure_getenv()` declines to
look at under AT_SECURE.
Note: mtools derives file and directory timestamps from
$SOURCE_DATE_EPOCH since v4.0.20 (2018).
Use the new copy timestamp clamping mechanism from the previous commit
to fix unreproducible wall-clock files in the generated images.
That covers both modes: online mode writes through the kernel, and
offline mode stages the tree in a temporary directory before handing it
to mkfs or mcopy. `mcopy -m` then carries the clamped mtimes into the
FAT.
This complements commit 34c3d57474 (directory times) and commit
f191ca982c (FAT insertion order).
Cover all combinations (online/offline, with and without epoch) in the
new `testcase_vfat_reproducibility()`. Update `testcase_make_symlinks()`
to cover the symlink creation/re-fix their parent directory code paths.
Sadly, images are still not reproducible byte for byte. Document
systemd-repart's $SOURCE_DATE_EPOCH handling and remaining
reproducibility issues in the manpage.
Add a `ts_clamp` argument to `copy_tree_at_full()` and
`copy_times_full()` that clamps copied inodes to a given time stamp.
This is the recommended `$SOURCE_DATE_EPOCH` semantics [1] for
reproducible builds. Their non-`_full` APIs keep existing behaviour by
clamping to `USEC_INFINITY`.
atime and mtime are clamped separately: a file that was merely read
after the epoch has to keep its mtime and still lose its atime. E.g. FAT
(EFI partition) stores an access date.
[1] https://reproducible-builds.org/specs/source-date-epoch/
`r` at that point holds the return value of `pidref_safe_fork_full()`,
which is 0 in the child, so a failing `setenv()` was reported as
"Success".
Also, fix a stray "°".
Image builds create a key separate from the SecureBoot one for verity
signing. Its certificate ships inside the image as the sysext trust
anchor.
`genkey` certs had a hardcoded "SecureBoot signing key on host <fqdn of
the build machine>" CN, which describes neither that verity role nor a
meaningful hostname.
Make that name configurable with `SecureBootCertificateCommonName=`,
like mkosi's `--genkey-common-name`. That allows image build tools to
re-use `ukify genkey` for non-SB keys.
Unlike the implicit truncation for the default name, a specified one
which is too long is an error. Add a citation where that limit comes
frm.