Much of these deficiencies boil down to the design criteria for systemd, which is basically to avoid forcing the system administrator to perform dependency graph resolution. This was a direct response to Upstart, which pushed this work to the administrator (or distro packager) by design.
Thus the declarative syntax for unit files, which do not explicitly control dependency resolution, parallelization, or startup order, which is simply not necessary or cared about for 99% of use cases. The 1% case there is for situations where you should not use a prebaked init system in the first place, such as when you absolutely need deterministic boots, i.e. in an embedded or realtime context.
> In systemd, however, the execution state is not based on explicit chain loading, but on serializing unit file options to a private ExecContext structure overlayed into Unit objects and set for service unit types.
This is not a problem with systemd's design. This is a problem with software written without the assumption of reliable process supervision, which is a reasonable assumption given the history of UNIX daemonization. systemd takes the (apparently controversial) stance that processes should not manage their own execution environment, or that of their dependencies. It provides numerous prebuilt hacks to make things work for broken software, but nobody should expect systemd to design for 100% of situations where processes do Weird Shit™.
And yes, I'm including "delegated service restarters" under this umbrella. The need for something like this absolutely smells of poor design. It also flies in the face of the author's preference for deterministic execution behavior, because by definition your process will execute differently depending on if it was started or restarted.
The link to "systemd house of horrors" [1] only proves this point.
> A supervisor insisting on programmatic accommodations from service writers is not the most desirable state of affairs. A rarely discussed alternative to the two common approaches is, again as with startup speed optimization minus parallelism, checkpoint/restore: checkpoint a process image from a point where initialization is known to be complete and overlay it on startup, using a tool such as DMTCP or CRIU.
I don't know about anyone else, but this sounds like an absolute nightmare. For one, it relies on the service exposing enough information to be checkpointed at the right time; at which point, you might as well call sd_notify or hook in a script to do it for you, so this is not a reduction in requiring programmatic accommodations from service writers. Two, process-snapshotting is not a panacea, and is a nightmare to debug when it breaks your expectations; you'll need to test all sorts of process state, including open pipes/fds/sockets, signals, system calls (!), shmem buffers, etc. At which point it's best to just let the service notify you directly when the process is done. Which is a facility that systemd provides.
> Of course we also have the issue of circular dependencies in the systemd architecture itself. We have the init, process manager, process supervisor, cgroup writer, local service tools, the Unit object structure (which might benefit from being made a protocol), timers, mounts, automounts and swaps all in the same module with ill-defined boundaries.
A worthy criticism. I would also like to see a bit more modularization from systemd, but I can also see the point of systemd developers not expending effort to do so. For one, it would drastically increase the number of contexts for testing (i.e. can we verify the service manager works without the cgroups module loaded, etc). I think systemd is at the point where it's rock-solid for all of its use cases, and a pluggable/composable architecture would have delayed this situation for not very much benefit.
In short, systemd imposes its opinions about process init and supervision. Whether or not this is reasonable is up for debate. However, it is very useful to have both a strong opinion and a solid implementation of this opinion.
IMO, the idealized world that systemd supports (i.e. non-forking services, initialization notification, strict execution environment and dependency declaration, centralized and opaque init/dependency-resolution/parallelization) is a vast improvement over the status quo and actually improves the lives of service writers (by removing an entire class of responsibilities), so I think it's a reasonable opinion and thus I think systemd has a reasonable design and architecture.
There are many known technical deficiencies with the implementation that are mostly being worked on, but I'm not seeing anything damning of the whole idea.
[1] http://homepage.ntlworld.com./jonathan.deboynepollard/FGA/sy...