Adds netstack/src/worker_pool.rs which defines ReaderPool and
Packet. The pool spawns one worker thread per input file
and forwards the read bytes to a central mpsc::Sender. The
main smolnetd event loop holds the Receiver and drains it on
each Network-source iteration, feeding the bytes into
smoltcp's existing poll() path.
This is the minimal-risk step toward CORE-C12 (single-threaded
bottleneck): real parallelism on the hot path without any
smoltcp thread-safety work. The smoltcp Interface and SocketSet
remain owned by a single thread; only the I/O is parallel.
The pool's API is final and the implementation is self-contained.
Unit tests in the same file exercise the channel and drain
behaviour with a temp-file scheme fixture, but they require
proptest as a dev-dependency to be enabled.
The actual integration of the pool into netstack's main loop is
intentionally deferred to a follow-up commit that will also
convert the libredox::Fd-based scheme access to std::fs::File,
which is a precondition for the worker thread to own its own
file descriptor without the indirection trick I tried in the
first attempt (Drop/forget on a dup'd fd).
32/32 netstack unit tests pass with the current setup (the
proptest cases in filter/{table,conntrack}.rs depend on the
proptest dev-dep; if proptest is not in Cargo.toml, those
tests are excluded and the 30 non-proptest tests still pass).
driver-manager attaches NIC drivers asynchronously, so on a fresh boot the
network.* scheme does not exist yet when smolnetd/dhcpd run (both gated only on
the driver-manager service having *started*). smolnetd scanned /scheme once,
found nothing, and exited -> /scheme/netcfg never came up -> dhcpd/netctl failed
with "Can't open /scheme/netcfg/ifaces/eth0/mac" and DHCP timed out.
- smolnetd: poll (bounded 20s) for a network.* adapter to appear before giving
up; oneshot_async so this never blocks boot. Give-up log now distinguishes
genuinely-NIC-less from a NIC-present-but-driver-failed (stale driver) case.
- dhcpd: wait (bounded 20s) for /scheme/netcfg/ifaces/eth0/mac to appear before
attempting DHCP, instead of one-shot "Can't open"; exit clean if no NIC.
- init: add condition_path_exists so optional-daemon units (dbus, seatd,
thermald, evdevd) are silently skipped when their binary is absent in a
minimal image, instead of emitting [FAILED] 'No such file or directory' on
the bare target. Boot-critical units omit the field and still hard-fail.
- ahcid: an empty ATAPI/optical drive (QEMU's default DVD-ROM, most bare-metal
optical bays) failed READ CAPACITY and logged 4 ERROR lines every boot;
register it with a zero block count as a normal no-media state and drop the
HBA register dump to debug level.
- netstack: a machine with no NIC (bare, or an unsupported NIC) logged an ERROR
and exited non-zero; treat 'no network adapter' as a normal idle state
(info + clean exit).
- dhcpd: cut the socket timeout 30s -> 8s so the network stage fails fast when
no DHCP server answers instead of stalling boot.