summaryrefslogtreecommitdiff
path: root/src/core
diff options
context:
space:
mode:
authormichaelolbrich <m.olbrich@pengutronix.de>2016-06-05 17:25:14 +0200
committerZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>2016-06-05 11:25:14 -0400
commit0a62f81045dd810c8f1223cccbac4d706ea2cb45 (patch)
tree5218c0d96b8173529c8778ff7bee1a4c745fad9c /src/core
parent592705f2f708b313ef3e07677463fe676cdd774a (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/core')
-rw-r--r--src/core/automount.c14
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,