Expand description
Diagnostic writes that never wait for the reader of a descriptor.
While --max-log-bytes is in force, termination of a run must not depend
on any diagnostic write (review of
https://github.com/rrnewton/hermit/pull/3686). A plain write(2) to a
blocking stderr whose reader stopped reading waits forever, so every
hermit diagnostic that can run in a capped run before the cap or the 123
classification goes through write_without_waiting once
forbid_waiting_diagnostics has been called.
crate::util::RetryingStderr reads the same flag: while it is set, its
writes go through write_without_waiting_for_a_reader and wait only
within its bounded deadline, never inside write(2).
This lives in detcore, below the hermit library and binary, because
detcore’s own stderr writer reads the flag, and because hermit’s
proc_mount writes its warning from the namespace-only pre_exec callback,
after fork, and from the container init: every function here except
write_without_waiting_for_a_reader makes only syscalls and signal-set
operations, without allocation, stdio locks or formatting.
Functions§
- diagnostics_
must_ not_ wait - Whether
forbid_waiting_diagnosticswas called. A single atomic load, so it is safe afterforkand in a signal handler. - forbid_
waiting_ diagnostics - From now on, in this process and every process it forks, a diagnostic that
asks
diagnostics_must_not_waitis written once withwrite_without_waitingand omitted when stderr cannot take it at once, andcrate::util::RetryingStderrnever waits insidewrite(2). Onlyhermit’smaincalls this, when--max-log-bytesis given. - last_
errno - The calling thread’s
errno, 0 when there is none. - proc_
self_ fd_ path /proc/self/fd/<fd>as a NUL-terminated path, built without allocating: the crossing writer may run with arbitrary locks held.- suppressing_
diagnostic_ signals - Run one diagnostic write (
writereturns its errno, 0 for none) so that no signal it generates escapes. - write_
without_ waiting - Put
bytesonfdonce, without waiting for the other end and without letting the attempt raise a signal. A diagnostic that cannot be delivered that way is omitted: the exit status still says why the run ended. - write_
without_ waiting_ for_ a_ reader - One write of
bytestofdthat cannot wait for a reader to drain the file, for a writer that then waits itself, within its own bound, when it is told the file is full (crate::util::RetryingStderrwhilediagnostics_must_not_wait). Returns the bytes written, which may be fewer thanbytes.len(), or the error;WouldBlockmeans full.