Skip to content

Switch to using a systemd generator for /var#859

Closed
cgwalters wants to merge 8 commits intoostreedev:masterfrom
cgwalters:var-mount
Closed

Switch to using a systemd generator for /var#859
cgwalters wants to merge 8 commits intoostreedev:masterfrom
cgwalters:var-mount

Conversation

@cgwalters
Copy link
Member

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.

cgwalters added 3 commits May 15, 2017 14:02
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.
Copy link
Member

@jlebon jlebon left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good overall! Will give it a spin as well.

if (errno != EINVAL)
err (EXIT_FAILURE, "failed to remount %s", target);
}
printf ("Remounted: %s\n", target);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe in the else instead, e.g.

if (mount (...) < 0)
  {
    ...
  }
else
  printf ("Remounted: %s\n", target);

?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We call err and abort the process if it fails.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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).

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

True, fixed. ⬇️

"Documentation=man:ostree(1)\n"
"ConditionKernelCommandLine=!systemd.volatile\n"
/* We need /sysroot mounted writable first */
"After=ostree-remount.service\n"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How about a SourcePath=/etc/fstab here?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Don't we also need a Before=local-fs.target here?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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=.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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)
)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

@jlebon
Copy link
Member

jlebon commented May 16, 2017

Verified working with /var as an fstab mount and not!
@rh-atomic-bot r+ 102ef0d

@rh-atomic-bot
Copy link

⌛ Testing commit 102ef0d with merge 3070588...

rh-atomic-bot pushed a commit that referenced this pull request May 16, 2017
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
rh-atomic-bot pushed a commit that referenced this pull request May 16, 2017
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
@cgwalters cgwalters mentioned this pull request May 16, 2017
@rh-atomic-bot
Copy link

☀️ Test successful - status-atomicjenkins
Approved by: jlebon
Pushing 3070588 to master...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants