Switch to using a systemd generator for /var#859
Switch to using a systemd generator for /var#859cgwalters wants to merge 8 commits intoostreedev:masterfrom
Conversation
I really have no idea what I was thinking with that list of mount points. It seems arbitrary. Sadly `git log` doesn't help, and there's no comments. Basically, the only mounts we should care about are those that libostree creates. Which are just `/sysroot` and `/var`. Systemd will handle the other things like `/tmp`, it's not our job, and we shouldn't touch them.
By checking the mount status, we avoid remounting things if we don't need to. And printing a single line per mount helps debugging when things go wrong.
If one wants to set up a mount for `/var` in `/etc/fstab`, it won't be mounted since `ostree-prepare-root` set up a bind mount for `/var` to `/sysroot/ostree/$stateroot/var`, and systemd will take the already extant mount over what's in `/etc/fstab`. There are a few options to fix this, but what I settled on is parsing `/etc/fstab` in a generator (exactly like `systemd-fstab-generator` does), except here we look for an explicit mount for `/var`, and if one *isn't* found, synthesize the default ostree mount to the stateroot. Another nice property is that if an admin creates a `var.mount` unit in `/etc` for example, that will also override our mount. Note that today ostree doesn't hard depend on systemd, so this behavior only kicks in if we're built with systemd *and* libmount support (for parsing `/etc/fstab`). I didn't really test that case though. Initially I started writing this as a "pure libc" program, but at one point decided to use `libostree.so` to find the booted deployment. That didn't work out because `/boot` wasn't necessarily mounted and hence we couldn't find the bootloader config. A leftover artifact from this is that the generator code calls into libostree via the "cmd private" infrastructure. But it's an easy way to share code, and doesn't hurt.
jlebon
left a comment
There was a problem hiding this comment.
Looks good overall! Will give it a spin as well.
src/switchroot/ostree-remount.c
Outdated
| if (errno != EINVAL) | ||
| err (EXIT_FAILURE, "failed to remount %s", target); | ||
| } | ||
| printf ("Remounted: %s\n", target); |
There was a problem hiding this comment.
Maybe in the else instead, e.g.
if (mount (...) < 0)
{
...
}
else
printf ("Remounted: %s\n", target);?
There was a problem hiding this comment.
We call err and abort the process if it fails.
There was a problem hiding this comment.
But it'll still print it if we get EINVAL, right? That can be misleading. (Heck, maybe we should even print a different msg in the EINVAL case).
| "Documentation=man:ostree(1)\n" | ||
| "ConditionKernelCommandLine=!systemd.volatile\n" | ||
| /* We need /sysroot mounted writable first */ | ||
| "After=ostree-remount.service\n" |
There was a problem hiding this comment.
How about a SourcePath=/etc/fstab here?
There was a problem hiding this comment.
Don't we also need a Before=local-fs.target here?
There was a problem hiding this comment.
I actually had that originally since I was copying systemd, but then I realized the source isn't /etc/fstab. Right?
Will add the Before=.
There was a problem hiding this comment.
Oh right, got confused. Yeah, there's not really an applicable SourcePath here.
configure.ac
Outdated
| AC_DEFINE([HAVE_LIBSYSTEMD], 1, [Define if we have libsystemd]) | ||
| systemdsystemgeneratordir=$($PKG_CONFIG --variable=systemdsystemgeneratordir systemd) | ||
| AC_SUBST(systemdsystemgeneratordir) | ||
| ) |
There was a problem hiding this comment.
Can you provide a --with-systemdsystemgeneratordir option here? So that I can do unprivileged installs without completely turning off systemd. I can add it as a follow-up PR too.
|
Verified working with |
By checking the mount status, we avoid remounting things if we don't need to. And printing a single line per mount helps debugging when things go wrong. Closes: #859 Approved by: jlebon
If one wants to set up a mount for `/var` in `/etc/fstab`, it won't be mounted since `ostree-prepare-root` set up a bind mount for `/var` to `/sysroot/ostree/$stateroot/var`, and systemd will take the already extant mount over what's in `/etc/fstab`. There are a few options to fix this, but what I settled on is parsing `/etc/fstab` in a generator (exactly like `systemd-fstab-generator` does), except here we look for an explicit mount for `/var`, and if one *isn't* found, synthesize the default ostree mount to the stateroot. Another nice property is that if an admin creates a `var.mount` unit in `/etc` for example, that will also override our mount. Note that today ostree doesn't hard depend on systemd, so this behavior only kicks in if we're built with systemd *and* libmount support (for parsing `/etc/fstab`). I didn't really test that case though. Initially I started writing this as a "pure libc" program, but at one point decided to use `libostree.so` to find the booted deployment. That didn't work out because `/boot` wasn't necessarily mounted and hence we couldn't find the bootloader config. A leftover artifact from this is that the generator code calls into libostree via the "cmd private" infrastructure. But it's an easy way to share code, and doesn't hurt. Closes: #859 Approved by: jlebon
|
☀️ Test successful - status-atomicjenkins |
If one wants to set up a mount for
/varin/etc/fstab, itwon't be mounted since
ostree-prepare-rootset up a bind mount for/varto/sysroot/ostree/$stateroot/var, and systemd will takethe already extant mount over what's in
/etc/fstab.There are a few options to fix this, but what I settled on is parsing
/etc/fstabin a generator (exactly likesystemd-fstab-generatordoes),except here we look for an explicit mount for
/var, and if one isn't found,synthesize the default ostree mount to the stateroot. Another nice property is
that if an admin creates a
var.mountunit in/etcfor example, that willalso override our mount.
Note that today ostree doesn't hard depend on systemd, so this behavior only
kicks in if we're built with systemd and libmount support (for parsing
/etc/fstab). I didn't really test that case though.Initially I started writing this as a "pure libc" program, but at one point
decided to use
libostree.soto find the booted deployment. That didn't workout because
/bootwasn't necessarily mounted and hence we couldn't find thebootloader config. A leftover artifact from this is that the generator code
calls into libostree via the "cmd private" infrastructure. But it's an easy way
to share code, and doesn't hurt.