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

Andrey Borzenkov arvidjaar at gmail.com
Wed Apr 9 19:38:59 PDT 2014


В Wed, 9 Apr 2014 13:49:47 -0400
Vivek Goyal <vgoyal at redhat.com> пишет:

> On Wed, Apr 09, 2014 at 05:36:13PM +0800, WANG Chao wrote:
> > 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.
> 
> Ok, I want to understand what is "never reach a target" means.
> 
> So with nofail opion for rootfs we should have following situation.
> 
> - sysroot.mount
> 	Before=initrd-root-fs.target
> - initrd-root-fs.target
> 	Requires=sysroot.mount
> 	OnFailure=emergency.target
> - initrd.target
> 	Wants=initrd-root-fs.target
> 	OnFailure=emergency.target
> - dracut-pre-pivot.service
> 	After=initrd.target sysroot.mount
> 
> Now let us say sysroot.mount failed activation because root device did not
> show up. We waited for certain time interval, then time out. Now what will
> happen to initrd-root-fs.target and initrd.target states.
> 

Assuming initrd-root-fs.target Requires sysroot.mounts it enters Failed
state and systemd effectively executes analog of "systemctl start
emergency.target". What happens after that is defined entirely by what
emergency.target pulls in. 

initrd.target in your example does not depend on sysroot.mount in any
way so unless there are further indirect dependencies it actually
should be reached at this point.

> Also let us say if we pass rootflags=nofail, I am assuming that we
> have following situation.
> 
> - sysroot.mount
> - initrd-root-fs.target
> 	Wants=sysroot.mount
> 	OnFailure=emergency.target
> - initrd.target
> 	Wants=initrd-root-fs.target
> 	OnFailure=emergency.target
> - dracut-pre-pivot.service
> 	After=initrd.target sysroot.mount
> 
> What will happen in this scenario if sysroot.mount fails.
> 

In this case failed sysroot.mount will be ignored and
initrd-root-fs.target enters Active state.


More information about the systemd-devel mailing list