When booting from virtiofs, we won't be able to find a root block
device. Let's gracefully handle this similar to how we don't fail
if we can't find a GPT partition table.
I have a system with /usr/lib/repart.d/50-root.conf with GrowFileSystem=yes.
The partition wouldn't be resized in the initrd, because
ConditionDirectoryNotEmpty=|/sysusr/usr/lib/repart.d was evaluated very early,
before /sysroot was mounted. There was no ordering dependency between
systemd-repart.service and sysroot.mount. (There was After=initrd-usr-fs.target,
but it seems to be only referred to by systemd-fstab-generator, which in my
case doesn't even run, because there's no fstab.)
But in fact, we neeed to run systemd-repart in the initrd only in limited
circumstances: when we need to create the root device based on config under
sysusr.mount. If there is config on the root device, it can be executed in
the host system, early during boot. Thus, let's remove the condition on
/sysroot/…. Without an ordering dependency on sysroot.mount, it was subject to
a race condition anyway. (A race condition with a low probability of "winning",
because systemd-repart.service has no dependencies, but sysroot.mount requires
a device to be detected and the mount to happen.)
The other problem was that systemd-repart.service didn't have the ordering wrt.
initrd-switch-root.target, so it was subject to the same race condition that
was fixed for other units in 7c0e2b5559. (If the
systemd-repart.service/stop job is slow, we could end up not restarting
systemd-repart.service in the host system.)
With the changes here, I see systemd-repart.service/start running twice:
in the initrd it is skipped because the conditions fail, and then in the
host system it runs normally.
Note: support for /sysroot is retained in systemd-repart code. I don't see a
strong reason to remove it, since it may still be useful to people invoking
repart in the initrd in other circumstances.
No functional change, just a cleanup to make the subsequent changes easier to
see. This is a continuation of 9810e41942
> The block is reordered and split to have:
> 1. description + documentation
> 2. (optionally) conditions
> 3. all the dependencies
The dependencies for shutdown.target are listed separately because they are the
other deps are for startup, and shutdown.target only matter much later.
We want to make use of that when formatting file systems, hence let's
pull in these modules explicitly.
(This is necessary because we are an early boot service that might run
before systemd-tmpfiles-dev.service, which creates /dev/loop-control and
/dev/mapper/control.)
Alternatively we could just order ourselves after
systemd-tmpfiles-dev.service, but I think there's value in adding an
explicit minimal ordering here, since we know what we'll need.
Fixes: #25775
We don't need two (and half) templating systems anymore, yay!
I'm keeping the changes minimal, to make the diff manageable. Some enhancements
due to a better templating system might be possible in the future.
For handling of '## ' — see the next commit.
This changes the fstab-generator to handle mounting of /usr/ a bit
differently than before. Instead of immediately mounting the fs to
/sysroot/usr/ we'll first mount it to /sysusr/usr/ and then add a
separate bind mount that mounts it from /sysusr/usr/ to /sysroot/usr/.
This way we can access /usr independently of the root fs, without for
waiting to be mounted via the /sysusr/ hierarchy. This is useful for
invoking systemd-repart while a root fs doesn't exist yet and for
creating it, with partition data read from the /usr/ hierarchy.
This introduces a new generic target initrd-usr-fs.target that may be
used to generically order services against /sysusr/ to become available.
This reverts commit 7e1ed1f3b2.
systemd-repart is not a user service that should be something people
enable/disable, instead it should just work if there's configuration for
it. It's like systemd-tmpfiles, systemd-sysusers, systemd-load-modules,
systemd-binfmt, systemd-systemd-sysctl which are NOPs if they have no
configuration, and thus don't hurt, but cannot be disabled since they
are too deep part of the OS.
This doesn't mean people couldn't disable the service if they really
want to, there's after all "systemctl mask" and build-time disabling,
but those are OS developer facing instead of admin facing, that's how it
should be.
Note that systemd-repart is in particular an initrd service, and so far
enable/disable state of those is not managed anyway via "systemctl
enable/disable" but more what dracut decides to package up and what not.
This essentially adds another layer of configurability:
build disable, this, presence of configuration. The default is
set to enabled, because the service does nothing w/o config.