diff options
author | Lennart Poettering <lennart@poettering.net> | 2017-03-01 04:03:48 +0100 |
---|---|---|
committer | Zbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl> | 2017-02-28 22:03:48 -0500 |
commit | e350ca3f1ecb6672b74cd25d09ef23c7b309aa5a (patch) | |
tree | 5788a9c0d3b77577122abdfe323a07af1ec1467a | |
parent | 74278ce56732056bb3cc75062113e393db1d6dd2 (diff) |
automount: if an automount unit is masked, don't react to activation anymore (#5445)
Otherwise we'll hit an assert sooner or later.
This requires us to initialize ->where even if we come back in "masked"
mode, as otherwise we don't know how to operate on the automount and
detach it.
Fixes: #5441
-rw-r--r-- | src/core/automount.c | 78 |
1 files changed, 50 insertions, 28 deletions
diff --git a/src/core/automount.c b/src/core/automount.c index 8ff1ca90f7..99e8047620 100644 --- a/src/core/automount.c +++ b/src/core/automount.c @@ -101,17 +101,17 @@ static void unmount_autofs(Automount *a) { a->pipe_event_source = sd_event_source_unref(a->pipe_event_source); a->pipe_fd = safe_close(a->pipe_fd); - /* If we reload/reexecute things we keep the mount point - * around */ - if (a->where && - (UNIT(a)->manager->exit_code != MANAGER_RELOAD && - UNIT(a)->manager->exit_code != MANAGER_REEXECUTE)) { + /* If we reload/reexecute things we keep the mount point around */ + if (!IN_SET(UNIT(a)->manager->exit_code, MANAGER_RELOAD, MANAGER_REEXECUTE)) { + automount_send_ready(a, a->tokens, -EHOSTDOWN); automount_send_ready(a, a->expire_tokens, -EHOSTDOWN); - r = repeat_unmount(a->where, MNT_DETACH); - if (r < 0) - log_error_errno(r, "Failed to unmount: %m"); + if (a->where) { + r = repeat_unmount(a->where, MNT_DETACH); + if (r < 0) + log_error_errno(r, "Failed to unmount: %m"); + } } } @@ -186,6 +186,22 @@ static int automount_verify(Automount *a) { return 0; } +static int automount_set_where(Automount *a) { + int r; + + assert(a); + + if (a->where) + return 0; + + r = unit_name_to_path(UNIT(a)->id, &a->where); + if (r < 0) + return r; + + path_kill_slashes(a->where); + return 1; +} + static int automount_load(Unit *u) { Automount *a = AUTOMOUNT(u); int r; @@ -201,13 +217,9 @@ static int automount_load(Unit *u) { if (u->load_state == UNIT_LOADED) { Unit *x; - if (!a->where) { - r = unit_name_to_path(u->id, &a->where); - if (r < 0) - return r; - } - - path_kill_slashes(a->where); + r = automount_set_where(a); + if (r < 0) + return r; r = unit_load_related_unit(u, ".mount", &x); if (r < 0) @@ -256,26 +268,30 @@ static int automount_coldplug(Unit *u) { assert(a); assert(a->state == AUTOMOUNT_DEAD); - if (a->deserialized_state != a->state) { + if (a->deserialized_state == a->state) + return 0; + + if (IN_SET(a->deserialized_state, AUTOMOUNT_WAITING, AUTOMOUNT_RUNNING)) { + + r = automount_set_where(a); + if (r < 0) + return r; r = open_dev_autofs(u->manager); if (r < 0) return r; - if (a->deserialized_state == AUTOMOUNT_WAITING || - a->deserialized_state == AUTOMOUNT_RUNNING) { - assert(a->pipe_fd >= 0); + assert(a->pipe_fd >= 0); - r = sd_event_add_io(u->manager->event, &a->pipe_event_source, a->pipe_fd, EPOLLIN, automount_dispatch_io, u); - if (r < 0) - return r; + r = sd_event_add_io(u->manager->event, &a->pipe_event_source, a->pipe_fd, EPOLLIN, automount_dispatch_io, u); + if (r < 0) + return r; - (void) sd_event_source_set_description(a->pipe_event_source, "automount-io"); - if (a->deserialized_state == AUTOMOUNT_RUNNING) { - r = automount_start_expire(a); - if (r < 0) - log_unit_warning_errno(UNIT(a), r, "Failed to start expiration timer, ignoring: %m"); - } + (void) sd_event_source_set_description(a->pipe_event_source, "automount-io"); + if (a->deserialized_state == AUTOMOUNT_RUNNING) { + r = automount_start_expire(a); + if (r < 0) + log_unit_warning_errno(UNIT(a), r, "Failed to start expiration timer, ignoring: %m"); } automount_set_state(a, a->deserialized_state); @@ -733,6 +749,12 @@ static void automount_enter_runnning(Automount *a) { assert(a); + /* If the user masked our unit in the meantime, fail */ + if (UNIT(a)->load_state != UNIT_LOADED) { + log_unit_error(UNIT(a), "Suppressing automount event since unit is no longer loaded."); + goto fail; + } + /* We don't take mount requests anymore if we are supposed to * shut down anyway */ if (unit_stop_pending(UNIT(a))) { |