I find myself wondering why the init is supposed to figure out what the computer is to be doing. That kind of "automagical" behavior is what drove me bonkers when trying to use Windows for more than a games console...
I dunno. If it's able to do what you want automatically that's amazing. If I can just plug the printer in and have it work that's amazing. If I can turn the wireless on my laptop on and it works that's amazing. And so on.
The problems arise when it doesn't automatically do what you want it to do and you don't have a good way of fixing it yourself. I'm not in a position to understand init systems so I will be in this camp if there's ever any problem with any init system. What matters to me, as the end user, is how likely it is to work automatically.
If systemd 'just works', then what's the problem? If systemd is broken... well, that's a problem, isn't it. But from what I've seen a lot (though not all, of course) of the arguments against it are highly political/philosophical and aren't based on whether it's actually working or not.
Hotplug isn't the job of systemd to begin with, though. It's the job of the device manager, which on Linux is usually udev (but alternatives like eudev, mdev, smdev and vdev exist) - udev being a part of the systemd repository and to an extent coupled with it (which will become complete when kdbus is merged into mainline Linux), however it's still a rather distinct piece of software that maintains the hardware database and listens to kernel uevents.
So if your init system is handling hotplug events, then that's some bad design. systemd doesn't stoop that low, though it still has plenty of mistakes - like putting the INI parser in PID1. As an example, even Apple put launchd's XML parser as a separate process!
There is tight interaction between udev and systemd. Heck, udev was folded into the systemd code (you find it now as a sub-dir of the systemd source tree over at freedesktop.org) because they didn't want code duplication...
This after having udev exist as a independent project for a decade.
These days the only way to download and install udev manually is to download the whole of systemd and then extract udev from that. Something that caused Gentoo to fork udev into eudev.
It's not really "automagical"; it's all quite well defined.
Honestly, I'll take a dozen 5-line unit files over a single "portable" init script that implements its own utility library, or yet another "simple" init script that's 90% standard boilerplate and still doesn't work because the 10% doing the real work doesn't check PID files correctly ("I can't just kill all processes called foo?") ...
Anyway, the point is that systemd models system states declaratively, solves the dependencies and executes the necessary steps required to reach that state, all without explicitly telling it what to do. If your dependencies are declared correctly, there is little danger of misbehaviour. The advantage to this is that parallelization is free and you never need explicit waits. In practice of course there will be misbehaving units and incomplete dependency declarations, but I think as admins gain experience with systemd those kinds of issues will drastically decrease. You'll still be able to run plain old scripts from unit files. I do that on my home server to start containers. since the contained process doesn't background itself and just prints to stdout and stderr, when started via systemd all its output will go into the journal and the tail shows up when I do "service container@foo status".
Analogous to SQL, I suppose something like "systemctl explain" might be useful. There's list-dependencies, which gets halfway there.
I believe it's not about between magical in the general case, but about how you specify dependencies between services, an area where systemd and upstart work differently.
Reminds me why slackware packages do not have dependency resolution, because it invariably breaks. This most often in the sense of X wants Y while Z wants Y+-1. And so you are at an impasse because the dependency resolver can't handle having two versions of Y installed at the same time.
A recent failure of systemd i have seen was related to NFS. For some reason systemd would yank the network down before dismounting NFS.
If you don't unmount NFS before taking down the network, it will sit there forever waiting for that final server response.
Another example was where while mount would happily ignore a flawed fstab entry but mount the rest, systemd would bail on the whole mount task and so halt the boot process.
I find myself wondering why the init is supposed to figure out what the computer is to be doing.
I've never messed with systemd configuration too much, but is it much more complicated than a make-style "how do I get there from here? OK lets do that"?
That's actually a pretty good summary of the difference between Upstart and systemd, with systemd your services declare what they depend on and your runlevel is now a "target" that declares that it depends on certain services. It does dependency resolution just like a package manager does.
If that were true you could never start those services in sysvinit either. It works great because there aren't cyclic references and practically no conflicting services. The dependency tree will always be pretty simple.
The problems arise when it doesn't automatically do what you want it to do and you don't have a good way of fixing it yourself. I'm not in a position to understand init systems so I will be in this camp if there's ever any problem with any init system. What matters to me, as the end user, is how likely it is to work automatically.
If systemd 'just works', then what's the problem? If systemd is broken... well, that's a problem, isn't it. But from what I've seen a lot (though not all, of course) of the arguments against it are highly political/philosophical and aren't based on whether it's actually working or not.