X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?p=elogind.git;a=blobdiff_plain;f=src%2Fmount.c;h=d651e8714bb2115abf8b16e15fc75f2fc2f44cb3;hp=08d5de28d7ebc54ee5a3b37f6a09d7c90211eecd;hb=c68364b790d1a13ef1df0e2fbb99ded6d67e60e3;hpb=173a8d04fc3535b571fe4a0d4715c18be315a43a diff --git a/src/mount.c b/src/mount.c index 08d5de28d..d651e8714 100644 --- a/src/mount.c +++ b/src/mount.c @@ -50,7 +50,7 @@ static const UnitActiveState state_translation_table[_MOUNT_STATE_MAX] = { [MOUNT_REMOUNTING_SIGKILL] = UNIT_RELOADING, [MOUNT_UNMOUNTING_SIGTERM] = UNIT_DEACTIVATING, [MOUNT_UNMOUNTING_SIGKILL] = UNIT_DEACTIVATING, - [MOUNT_MAINTENANCE] = UNIT_MAINTENANCE + [MOUNT_FAILED] = UNIT_FAILED }; static void mount_init(Unit *u) { @@ -266,7 +266,11 @@ static int mount_add_target_links(Mount *m) { return unit_add_two_dependencies(tu, UNIT_AFTER, UNIT_WANTS, UNIT(am), true); } else { - if (!noauto && handle) + /* Automatically add mount points that aren't natively + * configured to local-fs.target */ + if (!noauto && + handle && + !m->from_fragment) if (user || m->meta.manager->running_as == MANAGER_SYSTEM) if ((r = unit_add_dependency(tu, UNIT_WANTS, UNIT(m), true)) < 0) return r; @@ -464,7 +468,7 @@ static void mount_set_state(Mount *m, MountState state) { state == MOUNT_REMOUNTING_SIGKILL || state == MOUNT_UNMOUNTING_SIGTERM || state == MOUNT_UNMOUNTING_SIGKILL || - state == MOUNT_MAINTENANCE) + state == MOUNT_FAILED) mount_notify_automount(m, -ENODEV); if (state != old_state) @@ -604,7 +608,7 @@ static void mount_enter_dead(Mount *m, bool success) { if (!success) m->failure = true; - mount_set_state(m, m->failure ? MOUNT_MAINTENANCE : MOUNT_DEAD); + mount_set_state(m, m->failure ? MOUNT_FAILED : MOUNT_DEAD); } static void mount_enter_mounted(Mount *m, bool success) { @@ -618,7 +622,8 @@ static void mount_enter_mounted(Mount *m, bool success) { static void mount_enter_signal(Mount *m, MountState state, bool success) { int r; - bool sent = false; + Set *pid_set = NULL; + bool wait_for_exit = false; assert(m); @@ -630,26 +635,39 @@ static void mount_enter_signal(Mount *m, MountState state, bool success) { state == MOUNT_UNMOUNTING_SIGTERM || state == MOUNT_REMOUNTING_SIGTERM) ? m->exec_context.kill_signal : SIGKILL; - if (m->exec_context.kill_mode == KILL_CONTROL_GROUP) { + if (m->control_pid > 0) { + if (kill(m->exec_context.kill_mode == KILL_PROCESS_GROUP ? + -m->control_pid : + m->control_pid, sig) < 0 && errno != ESRCH) - if ((r = cgroup_bonding_kill_list(m->meta.cgroup_bondings, sig)) < 0) { - if (r != -EAGAIN && r != -ESRCH) - goto fail; - } else - sent = true; + log_warning("Failed to kill control process %li: %m", (long) m->control_pid); + else + wait_for_exit = true; } - if (!sent && m->control_pid > 0) - if (kill(m->exec_context.kill_mode == KILL_PROCESS ? - m->control_pid : - -m->control_pid, sig) < 0 && errno != ESRCH) { + if (m->exec_context.kill_mode == KILL_CONTROL_GROUP) { - r = -errno; + if (!(pid_set = set_new(trivial_hash_func, trivial_compare_func))) { + r = -ENOMEM; goto fail; } + + /* Exclude the control pid from being killed via the cgroup */ + if (m->control_pid > 0) + if ((r = set_put(pid_set, LONG_TO_PTR(m->control_pid))) < 0) + goto fail; + + if ((r = cgroup_bonding_kill_list(m->meta.cgroup_bondings, sig, pid_set)) < 0) { + if (r != -EAGAIN && r != -ESRCH && r != -ENOENT) + log_warning("Failed to kill control group: %s", strerror(-r)); + } else if (r > 0) + wait_for_exit = true; + + set_free(pid_set); + } } - if (sent) { + if (wait_for_exit) { if ((r = unit_watch_timer(UNIT(m), m->timeout_usec, &m->timer_watch)) < 0) goto fail; @@ -668,6 +686,9 @@ fail: mount_enter_mounted(m, false); else mount_enter_dead(m, false); + + if (pid_set) + set_free(pid_set); } static void mount_enter_unmounting(Mount *m, bool success) { @@ -835,7 +856,7 @@ static int mount_start(Unit *u) { m->state == MOUNT_MOUNTING_SIGKILL) return 0; - assert(m->state == MOUNT_DEAD || m->state == MOUNT_MAINTENANCE); + assert(m->state == MOUNT_DEAD || m->state == MOUNT_FAILED); m->failure = false; mount_enter_mounting(m); @@ -1503,7 +1524,7 @@ void mount_fd_event(Manager *m, int events) { switch (mount->state) { case MOUNT_DEAD: - case MOUNT_MAINTENANCE: + case MOUNT_FAILED: mount_enter_mounted(mount, true); break; @@ -1527,12 +1548,12 @@ void mount_fd_event(Manager *m, int events) { } } -static void mount_reset_maintenance(Unit *u) { +static void mount_reset_failed(Unit *u) { Mount *m = MOUNT(u); assert(m); - if (m->state == MOUNT_MAINTENANCE) + if (m->state == MOUNT_FAILED) mount_set_state(m, MOUNT_DEAD); m->failure = false; @@ -1551,7 +1572,7 @@ static const char* const mount_state_table[_MOUNT_STATE_MAX] = { [MOUNT_REMOUNTING_SIGKILL] = "remounting-sigkill", [MOUNT_UNMOUNTING_SIGTERM] = "unmounting-sigterm", [MOUNT_UNMOUNTING_SIGKILL] = "unmounting-sigkill", - [MOUNT_MAINTENANCE] = "maintenance" + [MOUNT_FAILED] = "failed" }; DEFINE_STRING_TABLE_LOOKUP(mount_state, MountState); @@ -1595,7 +1616,7 @@ const UnitVTable mount_vtable = { .sigchld_event = mount_sigchld_event, .timer_event = mount_timer_event, - .reset_maintenance = mount_reset_maintenance, + .reset_failed = mount_reset_failed, .bus_interface = "org.freedesktop.systemd1.Mount", .bus_message_handler = bus_mount_message_handler,