diff options
author | michaelolbrich <m.olbrich@pengutronix.de> | 2016-06-05 17:25:14 +0200 |
---|---|---|
committer | Zbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl> | 2016-06-05 11:25:14 -0400 |
commit | 0a62f81045dd810c8f1223cccbac4d706ea2cb45 (patch) | |
tree | 5218c0d96b8173529c8778ff7bee1a4c745fad9c /src | |
parent | 592705f2f708b313ef3e07677463fe676cdd774a (diff) |
automount: handle expire_tokens when the mount unit changes its state (#3434)
This basically reverts 7b2fd9d51259f6cf350791434e640ac3519acc6c ("core:
remove duplicate code in automount_update_mount()").
This was not duplicate code. The expire_tokens need to be handled as well:
Send 0 == success for MOUNT_DEAD (umount successful), do nothing for
MOUNT_UNMOUNTING (not yet done) and an error for everything else.
Otherwise the automount logic will assume unmounting is not done and will
not send any new requests for mounting. As a result, the corresponding
mount unit is never mounted.
Without this, automounts with TimeoutIdleSec= are broken. Once the idle
timeout triggered a umount, any access to the corresponding filesystem
hangs forever.
Fixes #3332.
Diffstat (limited to 'src')
-rw-r--r-- | src/core/automount.c | 14 |
1 files changed, 14 insertions, 0 deletions
diff --git a/src/core/automount.c b/src/core/automount.c index f06d837e30..85803a9c4a 100644 --- a/src/core/automount.c +++ b/src/core/automount.c @@ -502,6 +502,20 @@ static void automount_trigger_notify(Unit *u, Unit *other) { automount_set_state(a, AUTOMOUNT_RUNNING); } + if (IN_SET(MOUNT(other)->state, + MOUNT_MOUNTING, MOUNT_MOUNTING_DONE, + MOUNT_MOUNTED, MOUNT_REMOUNTING, + MOUNT_MOUNTING_SIGTERM, MOUNT_MOUNTING_SIGKILL, + MOUNT_REMOUNTING_SIGTERM, MOUNT_REMOUNTING_SIGKILL, + MOUNT_UNMOUNTING_SIGTERM, MOUNT_UNMOUNTING_SIGKILL, + MOUNT_FAILED)) { + + (void) automount_send_ready(a, a->expire_tokens, -ENODEV); + } + + if (MOUNT(other)->state == MOUNT_DEAD) + (void) automount_send_ready(a, a->expire_tokens, 0); + /* The mount is in some unhappy state now, let's unfreeze any waiting clients */ if (IN_SET(MOUNT(other)->state, MOUNT_DEAD, MOUNT_UNMOUNTING, |