[systemd-devel] [PATCH] fstab-generator: local-fs.target waits for nofail mounts

WANG Chao chaowang at redhat.com
Wed Apr 9 02:36:13 PDT 2014


On 04/08/14 at 06:02pm, Vivek Goyal wrote:
> On Tue, Apr 08, 2014 at 02:14:33AM +0200, Zbigniew Jędrzejewski-Szmek wrote:
> 
> [..]
> > > > > Defining a new target which by default waits for all the local fs target
> > > > > sounds interesting. Again, I have the question, what will happen to 
> > > > > local-fs-all.target if some device does not show up and say one of the
> > > > > mounts specified in /etc/fstab fails.
> > It result is different for Requires= and for Wants=. Iff there's a chain
> > of Requires= from the failing unit (.device in this case) to the target unit
> > it will fail. Otherwise, it'll just be delayed. If, as I suggested above local-fs-all.target
> > would have Requires= on the .mount units, then your unit could still have
> > Wants=/After=local-fs-all.target, and it'll be started even if some mounts
> > fail.
> 
> Thanks now I understand the difference between Requires= and Wants=
> better.
> 
> > 
> > > > > What we want is.
> > > > > 
> > > > > - Wait for all devices to show up as specified in /etc/fstab. Run fsck
> > > > >   on devices. Mount devices to mount points specified.
> > > > > 
> > > > > - If everything is successful, things are fine and local-fs-all.target
> > > > >   will be reached.
> > > > > 
> > > > > - If some device does not show up, or if fsck fails or mount fails, still
> > > > >   local-fs-all.target should reach so that kdump module can detect that
> > > > >   failure happened and can take alternative action.
> > Alternatively, you can specify a soft depenendency on local-fs-all.target by
> > using Wants=local-fs-all.target. I think this is preferable, because we want
> > local-fs-all.target to be as similar as possible to local-fs.target, which
> > has Requires= on the mount points.
> > 
> > With this caveat, this should all be satisfied with my proposal.
> 
> Agreed. We could define Wants=local-fs-all.target and that would make
> sure that our unit will be started even if local-fs-all.target fails.
> 
> > 
> > > > You can use OnFailure= to define unit(s) started when
> > > > local-fs-all.target fails. But it sounds like you are not really
> > > > interested in *all* filesystems, but in specific fileststems defined in
> > > > kdump configuration.
> > > 
> > > Kdump scripts registers with dracut as pre-pivot hook. And I believe
> > > that in initramfs environments /etc/fstab does not contain all
> > > filesystems. It prmarily contains root and any file system specified
> > > on dracut command line using --mount option during initramfs generation.
> > > 
> > > So my understanding that given the fact that /etc/fstab is minimal in
> > > initramfs, we should be fine waiting for all the fs specified. 
> > > 
> > > Given the fact that we run under dracut pre-pivot hook callback, I think
> > > dracut-pre-pivot.service wil have to create a dependency to run after
> > > local-fs-all.target is reached.
> > Hm, maybe. It would be good to get some input from Harald here.
> > This is pretty specialized, so maybe it'd be better to have a separate unit
> > positioned before or after or parallel to dracut-pre-pivot.service.
> 
> I am just thinking loud now. Taking a step back and going back to
> figure out why did we introduce "nofail" to begin with.
> 
> If I go through kexec-tools logs, it says "nofail" was introduced
> otherwise we never reach initrd.target. I am wondering why that's the
> case. Current initrd.target seems to have following.
> 
> [Unit]
> Description=Initrd Target
> Requires=basic.target
> Conflicts=rescue.service rescue.target
> After=basic.target rescue.service rescue.target
> AllowIsolate=yes
> OnFailure=emergency.target
> OnFailureIsolate=yes
> ConditionPathExists=/etc/initrd-release

dracut doesn't use this initrd.target. It uses the stock one from
systemd:

[Unit]
Description=Initrd Default Target
Documentation=man:systemd.special(7)
OnFailure=emergency.target
OnFailureIsolate=yes
ConditionPathExists=/etc/initrd-release
Requires=basic.target
Wants=initrd-root-fs.target initrd-fs.target initrd-parse-etc.service
After=initrd-root-fs.target initrd-fs.target basic.target
rescue.service rescue.target
AllowIsolate=yes

In sysroot.mount context, if we don't use "nofail" in case of root disk
failure, we will never reach initrd-root-fs.target and hence we never
reach initrd.target and dracut-pre-povit.service never get a chance to
start.

> 
> So it Requires=basic.target. Now let us say basic.target fails, then
> I am assuming emergency.target will be activated. And if we hook into
> emergency-shell binary and make it run a registered error handler if
> it is available, then kdump can drop its handler and take action on
> failure.
> 
> IOW, what if we stop passing "nofail". Then local-fs.target practically
> becomes local-fs-all.target. Either services will start just fine (after
> a wait for deivces to show up). Or units will start failing and if boot
> can't cointinue then somewhere we will fall into emergency shell and
> then emergency shell will call into kdump handler.
> 
> This is assuming that we have designed boot path in such a way that
> most of the time we will not do infinite wait (until and unless user
> asked us to do to. (x-systemd.device-timeout=0). So either we will wait
> for finite amount of time and then fail some services but continue to
> boot. And along the path if we can't make progress then we will drop into
> emergency shell.
> 
> If above assumption is right, then hooking into emergency shell logic
> in initramfs should provide what I am looking for.

I think that's right. Stop passing "nofail" and install own error
handler should be the right thing to do.

Thanks
WANG Chao


More information about the systemd-devel mailing list