You are presenting this in certain way that I think veers into inaccurate and misleading in an attempt to smooth things over and be nice.
What we had before systemd was -
90% glue code, reimplemented quite badly across X distributions.
That glue code was, in practice, extremely brittle and very very unfun to attempt to keep even simple daemons running "portably" distribution to distribution.
The other 10% was increasingly aging and ill maintained c code snippets.
That was not a nice world for people actually using it.
For people making stuff up about "the old days" that didn't actually participate in the misery of making basic systemv scripts, yeah it was composable and we lost something.
The internals of systemd are just as brittle, and the model of unit file configuration does not really apply cleanly beyond the simplest cases. So editing unit files becomes an undocumented dark art.
Chiming in here to say that systemd seems to cover the 80% (or even 90%) case pretty nicely, however that last 10-20% is now really difficult.
Anyone who has really delved into systemd knows this but they get shouted down as halting progress and hugging bash scripts, which is disingenuous as bash scripts (as per sysvinit) were painful and had great difficulties in areas such as determinism and parallel execution.
If you ever want an example of what I mean: look at how systemd starts mysql. Someone (not me) spent at least a man month making that work.
I do begrudge the all or nothing approach that systemd is taking (even if it claims to be modular), but I will admit openly: that 80% case is a lot nicer.
> If you ever want an example of what I mean: look at how systemd starts mysql. Someone (not me) spent at least a man month making that work.
I was curious, so I cracked open the mariadb.service unit that ships with Arch Linux. Other distros might ship different unit definitions, but this is the one I'm looking at.
It's large, yes, but very well commented and seems quite clear to me.
Much of the complexity seems to be around sandboxing: PrivateNetwork, CapabilityBoundingSet, PrivateDevices, ReadWritePaths, ProtectHome, PrivateTmp. These are all settings to do with hardening the service. They're totally optional, and can be removed without impacting functionality.
There is some extra complexity in the ExecStartPre and ExecStartPost commands. This appears to be something to do with the Galera cluster functionality. I'm not entirely sure what's happening with those, but I imagine these commands would also be present in a SysV init script implementing the same functionality.
The rest is pretty standard stuff: the user/group is set, along with the umask and some ulimits. LD_PRELOAD is set to load jemalloc. There's also some start/stop timeouts configured, with a comment explaining that these same timeout values were used in the SysV init scripts in the past.
Essentially, I'm not really sold that any of this complexity is caused by systemd. The hardening strikes me as a little unusual, and at a guess I'd say that this probably wouldn't be present in a SysV init script. If it were, the configuration would live in executable code, not in strictly declarative config directives.
> The internals of systemd are just as brittle, and the model of unit file configuration does not really apply cleanly beyond the simplest cases. So editing unit files becomes an undocumented dark art.
I call bullshit on that.
We removed few thousand lines of SysV init scripts from our configuration management that were basically fixed by us for subtle errors when we migrated to systemd. There is very little cases that aren't handled by very simple systemd units, in fact I'd dare you to give example that would be easy in SysV and hard in systemd.
Few fun cases:
Process after doing /etc/init.d/servicename start -> status immediately returned service stopped. That confused service managers like Pacemaker that thought the service failed to start. Why?
The app did start -> save pid file. Java app so it took a second.
The script just forked the app into background. So if you run status after start the pidfile was not there and it showed it is stopped. Not the problem in systemd
Another
(IIRC) MySQL init script put pid file in /var/run/, like everything else. Bit old install so /var/run wasn't a separate partition or tmpfs.
MySQL init script also didn't try to start if it found the PID existing in system. It didn't check what* was running tho.
So in crash scenario, server started, MySQL init script went "oh, there is apache daemon using that PID I had last reboot, clearly that means mysql is working" and exited. MySQL status returned MySQL working. Not a problem in systemd
Another:
Script just... sent signal and exited on stop. App could took some minutes to shut down. stop -> start failed, pid was lost coz script removed file with it after sending signal.... similar problem with multi-process app scripts not killing all childs. Systemd "just have a cgroup and mark service as stopped once everything dies" fixes that. YOu can ask for that behaviour if you tell systemd to not kill processes on stop but that's pretty much "purposefully using non-default settings" so can't be really done on accident.
IIRC all or most of that is how SysV init script by standard should not work but were simply bugged
Those scripts were in popular packages in "enterprise" linux distros. If even those maintainers can't make "simple SysV script" then maybe sysv scripts aren't as "simple" as some people claim they are.
What we had before systemd was -
90% glue code, reimplemented quite badly across X distributions.
That glue code was, in practice, extremely brittle and very very unfun to attempt to keep even simple daemons running "portably" distribution to distribution.
The other 10% was increasingly aging and ill maintained c code snippets.
That was not a nice world for people actually using it.
For people making stuff up about "the old days" that didn't actually participate in the misery of making basic systemv scripts, yeah it was composable and we lost something.