Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

> I don't think dependency order is particularly valuable in the real world. Manually specifying order imposes a strictness upon reality that isn't there.

I mean... sometimes you have to do it, because that strictness really is there.

> the simpler solution to compiling the kernel is just blacklisting the module.

What module? I'm not talking about removing a module, but changing a compile-time option for one.

Removing a module is certainly best achieved by just blacklisting it, that's why I mentioned this as a lazy example that the author picked. (But, FWIW, even that has unexpected consequences. A while back, for example, you could (sometimes significantly) improve the startup time of most embedded devices running Linux by removing the modules instead of blacklisting it because going through the list of blacklisted modules is surprisingly slow. That's probably not a relevant use case for what the author of this article is describing though)



If it's really needed and there is no way around it, it'll be painful in almost any sane and modern init system (OpenRC isn't that much better at it than Systemd, neither is svcs from Solaris which sucks the most at configs).

A good init system IMO doesn't have deterministic behaviour built in but rather as emergent property. Your start order falls out of the service definition.

---

The bluetooth module. Linux is highly modular and you can blacklist modules you don't want. And you can even compile modules after the fact. If you need bluetooth but your distro didn't ship it, you can in fact compile just that module and load it.

Only some core options need a full recompile of the kernel but that isn't too terrible on most distros (apt source, Arch's ABS, etc.) either.


> The bluetooth module.

What bluetooth module? `CONFIG_BFQ_GROUP_IOSCHED=y` is a cgroup-related option.

It's not pretty, and not because of a lack of tooling (apt source, ABS, whatever). The problem is that, since there's no "standard" configuration that you can depend on (unlike FreeBSD), you can't just take a "standard" system and reliably change a compile-time setting (or compile a module, or blacklist a module). There are a lot more moving parts (other compile options enabled downstream, additional patches applied downstream, especially in LTS kernels, compile-time options for userland applications and so on) which vary from one distro to another.

I personally see the value of this approach. I think it's more flexible than what FreeBSD does. But it is far more time-consuming and, generally, pretty nerve wracking.


NixOS lets you do that kinda of stuff though. You specify that you want a kernel option enabled and it'll make sure that any kernel you install has it enabled or compiles one from the upstream source you set (or the default one).

Even upgrading your kernel will ensure the option is enabled. And it'll ensure that any downstream modifications done by wherever you pull the kernel from has them enabled too.


Any distribution can do that -- at the end of the day, you can always get e.g. the linux-kernel deb-src and set the option in Kconfig. That will not solve the rest of the problem -- interaction with other kernel config flags, or side-effects vs. applications that assume a specific kernel configuration and patch set.


No, NixOS solves that. Apps can require Kernel Config Flags to be set and the interactions between flags can be modelled in NixOS. And it'll all be side-effect free and the nixos rebuild command will tell you at build time if it's wrong.


> sometimes you have to do it, because that strictness really is there.

In that case, wouldn't it be more correct to specify the strictness explicity through service dependencies?

Service dependencies form a DAG. Sequential start of services can be modeled by a DAG in which every node except the first and the last one has exactly one dependency and one dependant. So systemd way of starting services is a superset of the traditional, sequential way.


That's sort of the model that systemd uses (used?). However, non-trivial setups that attempt to use it tend to degenerate into very complex beasts, for various reasons, including:

- Unit properties can be specified both ways. For example, an unit can specify both that it should start after another unit (After=) and that it should start before another unit (Before=). So if you have two units, B can start after A either because B's definition includes After=A, or because A's definition includes Before=B.

- Order and dependency is specified separately. If B depends on A (specified by Wants=A in B's definition) that does not, in fact, guarantee sequential start.

- Some properties only apply to some systemd units. For example, Before= dependencies don't (didn't?) apply to device targets.


> So if you have two units, B can start after A either because B's definition includes After=A, or because A's definition includes Before=B.

That's true. However, most software can be easily misconfigured if you don't know what you're doing. And when creating any kind of DAG, it's implied we need to avoid cycles. I suppose systemd could use a tool for visualizing service dependencies and order.

> Order and dependency is specified separately

Order is stricter than dependency, and it slows down the whole process. If things can run in parallel, they should. If they cannot, then we should specify it explicitly. Leaving out order would make systemd useless for situations when order matters, and leaving out dependency would slow the whole process down.

> Some properties only apply to some systemd units. For example, Before= dependencies don't (didn't?) apply to device targets.

I agree, the rules are pretty complex. I don't like that about systemd at all. Combined with the fact that there are 175 different options [0] you can use in a unit file makes systemd really unpleasant for writing any kinds of services. I have a couple of boilerplate unit files I've written long time ago and I just reuse them with changed parameters.

[0] check for yourself:

    cat <(man systemd.service) <(man systemd.unit) <(man systemd.exec) | grep '^       [A-Za-z]*=' | sed 's/=.*/=/' | sort -u


> I mean... sometimes you have to do it, because that strictness really is there.

In which case you specify service dependencies and systemd will start them one after another, you know, you have the After= option in your units just for that.

In all other cases does it matter jack shit, to put it bluntly, if your bluetooth services start after your NFS share exports or before them? Or is it some sort of OCD speaking?


> In which case you specify service dependencies and systemd will start them one after another, you know, you have the After= option in your units just for that.

First off, After= specifies order, not functional dependency. This doesn't do what you want which, I think, kind of proves my point. The complaint in the original article (and mine) isn't that it's impossible to specify order between two services, which, yes, you can do just fine. The complaint is that doing so repeatably across boot times is impossible (because systemd literally and explicitly does not support it) and that debugging the "weak" version of it is really difficult.

It's really difficult because Aftter= is, literally, one twelfth of the story, possibly less. Order and dependency ae specified not just though After=, but also Before=, Wants=, Requires=, WantedBy=, RequiedBy=, Requisite=, RequisiteOf=, Triggers=, TriggeredBy=, PartOf= and ConsistsOf=.

Ordering and dependency are treated separately by systemd. I think that's a good design trade-off but it's not without consequences.




Consider applying for YC's Summer 2026 batch! Applications are open till May 4

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: