2020-11-09 05:23:58 +01:00
|
|
|
/* SPDX-License-Identifier: LGPL-2.1-or-later */
|
2010-02-03 13:03:47 +01:00
|
|
|
|
2010-01-23 01:52:57 +01:00
|
|
|
#include <errno.h>
|
2015-10-23 18:52:53 +02:00
|
|
|
#include <signal.h>
|
2010-01-29 02:07:41 +01:00
|
|
|
#include <stdio.h>
|
2010-01-29 06:04:08 +01:00
|
|
|
#include <sys/epoll.h>
|
2010-01-23 01:52:57 +01:00
|
|
|
|
2012-12-05 11:59:05 +01:00
|
|
|
#include "sd-messages.h"
|
2015-10-23 18:52:53 +02:00
|
|
|
|
2015-10-27 03:01:06 +01:00
|
|
|
#include "alloc-util.h"
|
2010-04-18 03:08:16 +02:00
|
|
|
#include "dbus-mount.h"
|
2018-11-27 20:15:45 +01:00
|
|
|
#include "dbus-unit.h"
|
2018-05-15 20:17:34 +02:00
|
|
|
#include "device.h"
|
2011-01-20 18:22:03 +01:00
|
|
|
#include "exit-status.h"
|
2016-11-07 16:14:59 +01:00
|
|
|
#include "format-util.h"
|
2015-10-23 18:52:53 +02:00
|
|
|
#include "fstab-util.h"
|
2019-04-04 12:54:19 +02:00
|
|
|
#include "libmount-util.h"
|
2015-10-23 18:52:53 +02:00
|
|
|
#include "log.h"
|
|
|
|
#include "manager.h"
|
|
|
|
#include "mkdir.h"
|
|
|
|
#include "mount-setup.h"
|
|
|
|
#include "mount.h"
|
2018-11-29 10:24:39 +01:00
|
|
|
#include "mountpoint-util.h"
|
2015-10-26 16:18:16 +01:00
|
|
|
#include "parse-util.h"
|
2015-10-23 18:52:53 +02:00
|
|
|
#include "path-util.h"
|
2015-10-27 14:24:58 +01:00
|
|
|
#include "process-util.h"
|
2018-10-17 20:40:09 +02:00
|
|
|
#include "serialize.h"
|
2015-10-23 18:52:53 +02:00
|
|
|
#include "special.h"
|
2015-10-26 22:31:05 +01:00
|
|
|
#include "string-table.h"
|
2015-10-27 03:01:06 +01:00
|
|
|
#include "string-util.h"
|
2015-10-23 18:52:53 +02:00
|
|
|
#include "strv.h"
|
|
|
|
#include "unit-name.h"
|
|
|
|
#include "unit.h"
|
2010-01-23 01:52:57 +01:00
|
|
|
|
2014-12-12 20:12:35 +01:00
|
|
|
#define RETRY_UMOUNT_MAX 32
|
|
|
|
|
2010-01-29 03:18:09 +01:00
|
|
|
static const UnitActiveState state_translation_table[_MOUNT_STATE_MAX] = {
|
|
|
|
[MOUNT_DEAD] = UNIT_INACTIVE,
|
|
|
|
[MOUNT_MOUNTING] = UNIT_ACTIVATING,
|
2018-01-20 21:12:09 +01:00
|
|
|
[MOUNT_MOUNTING_DONE] = UNIT_ACTIVATING,
|
2010-01-29 03:18:09 +01:00
|
|
|
[MOUNT_MOUNTED] = UNIT_ACTIVE,
|
2010-07-01 03:34:15 +02:00
|
|
|
[MOUNT_REMOUNTING] = UNIT_RELOADING,
|
2010-01-29 03:18:09 +01:00
|
|
|
[MOUNT_UNMOUNTING] = UNIT_DEACTIVATING,
|
2010-07-01 03:34:15 +02:00
|
|
|
[MOUNT_REMOUNTING_SIGTERM] = UNIT_RELOADING,
|
|
|
|
[MOUNT_REMOUNTING_SIGKILL] = UNIT_RELOADING,
|
2010-04-10 17:53:17 +02:00
|
|
|
[MOUNT_UNMOUNTING_SIGTERM] = UNIT_DEACTIVATING,
|
|
|
|
[MOUNT_UNMOUNTING_SIGKILL] = UNIT_DEACTIVATING,
|
2019-08-25 15:08:47 +02:00
|
|
|
[MOUNT_FAILED] = UNIT_FAILED,
|
|
|
|
[MOUNT_CLEANING] = UNIT_MAINTENANCE,
|
2010-01-29 03:18:09 +01:00
|
|
|
};
|
2010-01-23 01:52:57 +01:00
|
|
|
|
2013-11-19 21:12:59 +01:00
|
|
|
static int mount_dispatch_timer(sd_event_source *source, usec_t usec, void *userdata);
|
|
|
|
static int mount_dispatch_io(sd_event_source *source, int fd, uint32_t revents, void *userdata);
|
2019-07-17 18:57:13 +02:00
|
|
|
static int mount_process_proc_self_mountinfo(Manager *m);
|
2013-11-19 21:12:59 +01:00
|
|
|
|
2017-09-25 19:25:50 +02:00
|
|
|
static bool MOUNT_STATE_WITH_PROCESS(MountState state) {
|
|
|
|
return IN_SET(state,
|
|
|
|
MOUNT_MOUNTING,
|
|
|
|
MOUNT_MOUNTING_DONE,
|
|
|
|
MOUNT_REMOUNTING,
|
|
|
|
MOUNT_REMOUNTING_SIGTERM,
|
|
|
|
MOUNT_REMOUNTING_SIGKILL,
|
|
|
|
MOUNT_UNMOUNTING,
|
|
|
|
MOUNT_UNMOUNTING_SIGTERM,
|
2019-08-25 15:08:47 +02:00
|
|
|
MOUNT_UNMOUNTING_SIGKILL,
|
|
|
|
MOUNT_CLEANING);
|
2017-09-25 19:25:50 +02:00
|
|
|
}
|
|
|
|
|
2020-04-01 17:46:42 +02:00
|
|
|
static bool mount_is_automount(const MountParameters *p) {
|
|
|
|
assert(p);
|
|
|
|
|
|
|
|
return fstab_test_option(p->options,
|
|
|
|
"comment=systemd.automount\0"
|
|
|
|
"x-systemd.automount\0");
|
|
|
|
}
|
|
|
|
|
2018-11-28 12:32:14 +01:00
|
|
|
static bool mount_is_network(const MountParameters *p) {
|
|
|
|
assert(p);
|
|
|
|
|
|
|
|
if (fstab_test_option(p->options, "_netdev\0"))
|
2013-10-05 19:09:43 +02:00
|
|
|
return true;
|
|
|
|
|
2018-11-28 12:32:14 +01:00
|
|
|
if (p->fstype && fstype_is_network(p->fstype))
|
2013-10-05 19:09:43 +02:00
|
|
|
return true;
|
|
|
|
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2020-04-02 08:58:31 +02:00
|
|
|
static bool mount_is_nofail(const Mount *m) {
|
|
|
|
assert(m);
|
|
|
|
|
|
|
|
if (!m->from_fragment)
|
|
|
|
return false;
|
|
|
|
|
|
|
|
return fstab_test_yes_no_option(m->parameters_fragment.options, "nofail\0" "fail\0");
|
|
|
|
}
|
|
|
|
|
2016-04-25 13:25:00 +02:00
|
|
|
static bool mount_is_loop(const MountParameters *p) {
|
|
|
|
assert(p);
|
|
|
|
|
|
|
|
if (fstab_test_option(p->options, "loop\0"))
|
|
|
|
return true;
|
|
|
|
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2014-11-28 20:22:47 +01:00
|
|
|
static bool mount_is_bind(const MountParameters *p) {
|
2013-10-05 19:09:43 +02:00
|
|
|
assert(p);
|
|
|
|
|
2015-01-09 22:58:29 +01:00
|
|
|
if (fstab_test_option(p->options, "bind\0" "rbind\0"))
|
2013-10-05 19:09:43 +02:00
|
|
|
return true;
|
|
|
|
|
2015-01-09 22:58:29 +01:00
|
|
|
if (p->fstype && STR_IN_SET(p->fstype, "bind", "rbind"))
|
2013-10-05 19:09:43 +02:00
|
|
|
return true;
|
|
|
|
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2016-12-16 17:13:58 +01:00
|
|
|
static bool mount_is_bound_to_device(const Mount *m) {
|
|
|
|
const MountParameters *p;
|
|
|
|
|
|
|
|
if (m->from_fragment)
|
|
|
|
return true;
|
|
|
|
|
|
|
|
p = &m->parameters_proc_self_mountinfo;
|
|
|
|
return fstab_test_option(p->options, "x-systemd.device-bound\0");
|
|
|
|
}
|
|
|
|
|
2018-11-28 12:32:35 +01:00
|
|
|
static bool mount_needs_quota(const MountParameters *p) {
|
2013-10-05 19:09:43 +02:00
|
|
|
assert(p);
|
|
|
|
|
2018-11-28 12:32:35 +01:00
|
|
|
/* Quotas are not enabled on network filesystems, but we want them, for example, on storage connected via
|
|
|
|
* iscsi. We hence don't use mount_is_network() here, as that would also return true for _netdev devices. */
|
2015-03-30 14:42:02 +02:00
|
|
|
if (p->fstype && fstype_is_network(p->fstype))
|
2013-10-05 19:09:43 +02:00
|
|
|
return false;
|
|
|
|
|
|
|
|
if (mount_is_bind(p))
|
|
|
|
return false;
|
|
|
|
|
2015-01-09 22:58:29 +01:00
|
|
|
return fstab_test_option(p->options,
|
|
|
|
"usrquota\0" "grpquota\0" "quota\0" "usrjquota\0" "grpjquota\0");
|
2013-10-05 19:09:43 +02:00
|
|
|
}
|
|
|
|
|
2010-04-21 03:27:44 +02:00
|
|
|
static void mount_init(Unit *u) {
|
|
|
|
Mount *m = MOUNT(u);
|
2010-01-23 01:52:57 +01:00
|
|
|
|
2010-04-21 03:27:44 +02:00
|
|
|
assert(u);
|
2012-01-15 12:04:08 +01:00
|
|
|
assert(u->load_state == UNIT_STUB);
|
2010-04-21 03:27:44 +02:00
|
|
|
|
2013-11-04 17:47:43 +01:00
|
|
|
m->timeout_usec = u->manager->default_timeout_start_usec;
|
2018-01-13 13:30:43 +01:00
|
|
|
|
|
|
|
m->exec_context.std_output = u->manager->default_std_output;
|
|
|
|
m->exec_context.std_error = u->manager->default_std_error;
|
|
|
|
|
2010-07-02 00:28:44 +02:00
|
|
|
m->directory_mode = 0755;
|
|
|
|
|
2015-05-13 15:43:04 +02:00
|
|
|
/* We need to make sure that /usr/bin/mount is always called
|
|
|
|
* in the same process group as us, so that the autofs kernel
|
2010-04-21 03:27:44 +02:00
|
|
|
* side doesn't send us another mount request while we are
|
|
|
|
* already trying to comply its last one. */
|
2010-07-05 01:08:13 +02:00
|
|
|
m->exec_context.same_pgrp = true;
|
2010-04-16 23:24:39 +02:00
|
|
|
|
2010-04-21 03:27:44 +02:00
|
|
|
m->control_command_id = _MOUNT_EXEC_COMMAND_INVALID;
|
2011-04-14 03:55:03 +02:00
|
|
|
|
2013-11-25 15:26:30 +01:00
|
|
|
u->ignore_on_isolate = true;
|
2010-04-16 23:24:39 +02:00
|
|
|
}
|
|
|
|
|
core: rework unit timeout handling, and add new setting RuntimeMaxSec=
This clean-ups timeout handling in PID 1. Specifically, instead of storing 0 in internal timeout variables as
indication for a disabled timeout, use USEC_INFINITY which is in-line with how we do this in the rest of our code
(following the logic that 0 means "no", and USEC_INFINITY means "never").
This also replace all usec_t additions with invocations to usec_add(), so that USEC_INFINITY is properly propagated,
and sd-event considers it has indication for turning off the event source.
This also alters the deserialization of the units to restart timeouts from the time they were originally started from.
Before this patch timeouts would be restarted beginning with the time of the deserialization, which could lead to
artificially prolonged timeouts if a daemon reload took place.
Finally, a new RuntimeMaxSec= setting is introduced for service units, that specifies a maximum runtime after which a
specific service is forcibly terminated. This is useful to put time limits on time-intensive processing jobs.
This also simplifies the various xyz_spawn() calls of the various types in that explicit distruction of the timers is
removed, as that is done anyway by the state change handlers, and a state change is always done when the xyz_spawn()
calls fail.
Fixes: #2249
2016-02-01 21:48:10 +01:00
|
|
|
static int mount_arm_timer(Mount *m, usec_t usec) {
|
2013-11-19 21:12:59 +01:00
|
|
|
int r;
|
|
|
|
|
|
|
|
assert(m);
|
|
|
|
|
|
|
|
if (m->timer_event_source) {
|
core: rework unit timeout handling, and add new setting RuntimeMaxSec=
This clean-ups timeout handling in PID 1. Specifically, instead of storing 0 in internal timeout variables as
indication for a disabled timeout, use USEC_INFINITY which is in-line with how we do this in the rest of our code
(following the logic that 0 means "no", and USEC_INFINITY means "never").
This also replace all usec_t additions with invocations to usec_add(), so that USEC_INFINITY is properly propagated,
and sd-event considers it has indication for turning off the event source.
This also alters the deserialization of the units to restart timeouts from the time they were originally started from.
Before this patch timeouts would be restarted beginning with the time of the deserialization, which could lead to
artificially prolonged timeouts if a daemon reload took place.
Finally, a new RuntimeMaxSec= setting is introduced for service units, that specifies a maximum runtime after which a
specific service is forcibly terminated. This is useful to put time limits on time-intensive processing jobs.
This also simplifies the various xyz_spawn() calls of the various types in that explicit distruction of the timers is
removed, as that is done anyway by the state change handlers, and a state change is always done when the xyz_spawn()
calls fail.
Fixes: #2249
2016-02-01 21:48:10 +01:00
|
|
|
r = sd_event_source_set_time(m->timer_event_source, usec);
|
2013-11-19 21:12:59 +01:00
|
|
|
if (r < 0)
|
|
|
|
return r;
|
|
|
|
|
|
|
|
return sd_event_source_set_enabled(m->timer_event_source, SD_EVENT_ONESHOT);
|
|
|
|
}
|
|
|
|
|
core: rework unit timeout handling, and add new setting RuntimeMaxSec=
This clean-ups timeout handling in PID 1. Specifically, instead of storing 0 in internal timeout variables as
indication for a disabled timeout, use USEC_INFINITY which is in-line with how we do this in the rest of our code
(following the logic that 0 means "no", and USEC_INFINITY means "never").
This also replace all usec_t additions with invocations to usec_add(), so that USEC_INFINITY is properly propagated,
and sd-event considers it has indication for turning off the event source.
This also alters the deserialization of the units to restart timeouts from the time they were originally started from.
Before this patch timeouts would be restarted beginning with the time of the deserialization, which could lead to
artificially prolonged timeouts if a daemon reload took place.
Finally, a new RuntimeMaxSec= setting is introduced for service units, that specifies a maximum runtime after which a
specific service is forcibly terminated. This is useful to put time limits on time-intensive processing jobs.
This also simplifies the various xyz_spawn() calls of the various types in that explicit distruction of the timers is
removed, as that is done anyway by the state change handlers, and a state change is always done when the xyz_spawn()
calls fail.
Fixes: #2249
2016-02-01 21:48:10 +01:00
|
|
|
if (usec == USEC_INFINITY)
|
|
|
|
return 0;
|
|
|
|
|
2015-04-29 16:05:32 +02:00
|
|
|
r = sd_event_add_time(
|
2014-03-24 02:49:09 +01:00
|
|
|
UNIT(m)->manager->event,
|
|
|
|
&m->timer_event_source,
|
|
|
|
CLOCK_MONOTONIC,
|
core: rework unit timeout handling, and add new setting RuntimeMaxSec=
This clean-ups timeout handling in PID 1. Specifically, instead of storing 0 in internal timeout variables as
indication for a disabled timeout, use USEC_INFINITY which is in-line with how we do this in the rest of our code
(following the logic that 0 means "no", and USEC_INFINITY means "never").
This also replace all usec_t additions with invocations to usec_add(), so that USEC_INFINITY is properly propagated,
and sd-event considers it has indication for turning off the event source.
This also alters the deserialization of the units to restart timeouts from the time they were originally started from.
Before this patch timeouts would be restarted beginning with the time of the deserialization, which could lead to
artificially prolonged timeouts if a daemon reload took place.
Finally, a new RuntimeMaxSec= setting is introduced for service units, that specifies a maximum runtime after which a
specific service is forcibly terminated. This is useful to put time limits on time-intensive processing jobs.
This also simplifies the various xyz_spawn() calls of the various types in that explicit distruction of the timers is
removed, as that is done anyway by the state change handlers, and a state change is always done when the xyz_spawn()
calls fail.
Fixes: #2249
2016-02-01 21:48:10 +01:00
|
|
|
usec, 0,
|
2014-03-24 02:49:09 +01:00
|
|
|
mount_dispatch_timer, m);
|
2015-04-29 16:05:32 +02:00
|
|
|
if (r < 0)
|
|
|
|
return r;
|
|
|
|
|
|
|
|
(void) sd_event_source_set_description(m->timer_event_source, "mount-timer");
|
|
|
|
|
|
|
|
return 0;
|
2013-11-19 21:12:59 +01:00
|
|
|
}
|
|
|
|
|
2010-04-21 03:27:44 +02:00
|
|
|
static void mount_unwatch_control_pid(Mount *m) {
|
2010-04-11 00:22:36 +02:00
|
|
|
assert(m);
|
|
|
|
|
|
|
|
if (m->control_pid <= 0)
|
|
|
|
return;
|
|
|
|
|
|
|
|
unit_unwatch_pid(UNIT(m), m->control_pid);
|
|
|
|
m->control_pid = 0;
|
|
|
|
}
|
|
|
|
|
2010-04-10 17:53:17 +02:00
|
|
|
static void mount_parameters_done(MountParameters *p) {
|
|
|
|
assert(p);
|
|
|
|
|
2018-11-28 12:33:21 +01:00
|
|
|
p->what = mfree(p->what);
|
|
|
|
p->options = mfree(p->options);
|
|
|
|
p->fstype = mfree(p->fstype);
|
2010-04-10 17:53:17 +02:00
|
|
|
}
|
|
|
|
|
2010-01-26 21:39:06 +01:00
|
|
|
static void mount_done(Unit *u) {
|
2010-01-29 06:04:08 +01:00
|
|
|
Mount *m = MOUNT(u);
|
2010-01-26 04:18:44 +01:00
|
|
|
|
2010-01-29 06:04:08 +01:00
|
|
|
assert(m);
|
2010-01-26 04:18:44 +01:00
|
|
|
|
2015-09-08 18:43:11 +02:00
|
|
|
m->where = mfree(m->where);
|
2010-01-29 03:18:09 +01:00
|
|
|
|
2010-04-10 17:53:17 +02:00
|
|
|
mount_parameters_done(&m->parameters_proc_self_mountinfo);
|
|
|
|
mount_parameters_done(&m->parameters_fragment);
|
2010-01-29 06:04:08 +01:00
|
|
|
|
2018-02-06 08:00:34 +01:00
|
|
|
m->exec_runtime = exec_runtime_unref(m->exec_runtime, false);
|
2010-04-10 17:53:17 +02:00
|
|
|
exec_command_done_array(m->exec_command, _MOUNT_EXEC_COMMAND_MAX);
|
|
|
|
m->control_command = NULL;
|
2010-01-29 03:18:09 +01:00
|
|
|
|
2016-07-14 12:37:28 +02:00
|
|
|
dynamic_creds_unref(&m->dynamic_creds);
|
|
|
|
|
2010-04-21 03:27:44 +02:00
|
|
|
mount_unwatch_control_pid(m);
|
2010-01-29 03:18:09 +01:00
|
|
|
|
2013-11-19 21:12:59 +01:00
|
|
|
m->timer_event_source = sd_event_source_unref(m->timer_event_source);
|
2010-01-29 03:18:09 +01:00
|
|
|
}
|
|
|
|
|
2020-01-21 18:08:27 +01:00
|
|
|
static MountParameters* get_mount_parameters_fragment(Mount *m) {
|
2011-03-30 01:53:34 +02:00
|
|
|
assert(m);
|
|
|
|
|
|
|
|
if (m->from_fragment)
|
|
|
|
return &m->parameters_fragment;
|
|
|
|
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2020-01-21 18:08:27 +01:00
|
|
|
static MountParameters* get_mount_parameters(Mount *m) {
|
2011-03-30 01:53:34 +02:00
|
|
|
assert(m);
|
|
|
|
|
|
|
|
if (m->from_proc_self_mountinfo)
|
|
|
|
return &m->parameters_proc_self_mountinfo;
|
|
|
|
|
2012-05-22 19:23:33 +02:00
|
|
|
return get_mount_parameters_fragment(m);
|
2011-03-30 01:53:34 +02:00
|
|
|
}
|
|
|
|
|
2019-07-18 17:02:30 +02:00
|
|
|
static int update_parameters_proc_self_mountinfo(
|
2019-01-17 21:17:51 +01:00
|
|
|
Mount *m,
|
|
|
|
const char *what,
|
|
|
|
const char *options,
|
|
|
|
const char *fstype) {
|
|
|
|
|
|
|
|
MountParameters *p;
|
|
|
|
int r, q, w;
|
|
|
|
|
|
|
|
p = &m->parameters_proc_self_mountinfo;
|
|
|
|
|
|
|
|
r = free_and_strdup(&p->what, what);
|
|
|
|
if (r < 0)
|
|
|
|
return r;
|
|
|
|
|
|
|
|
q = free_and_strdup(&p->options, options);
|
|
|
|
if (q < 0)
|
|
|
|
return q;
|
|
|
|
|
|
|
|
w = free_and_strdup(&p->fstype, fstype);
|
|
|
|
if (w < 0)
|
|
|
|
return w;
|
|
|
|
|
|
|
|
return r > 0 || q > 0 || w > 0;
|
|
|
|
}
|
|
|
|
|
core: track why unit dependencies came to be
This replaces the dependencies Set* objects by Hashmap* objects, where
the key is the depending Unit, and the value is a bitmask encoding why
the specific dependency was created.
The bitmask contains a number of different, defined bits, that indicate
why dependencies exist, for example whether they are created due to
explicitly configured deps in files, by udev rules or implicitly.
Note that memory usage is not increased by this change, even though we
store more information, as we manage to encode the bit mask inside the
value pointer each Hashmap entry contains.
Why this all? When we know how a dependency came to be, we can update
dependencies correctly when a configuration source changes but others
are left unaltered. Specifically:
1. We can fix UDEV_WANTS dependency generation: so far we kept adding
dependencies configured that way, but if a device lost such a
dependency we couldn't them again as there was no scheme for removing
of dependencies in place.
2. We can implement "pin-pointed" reload of unit files. If we know what
dependencies were created as result of configuration in a unit file,
then we know what to flush out when we want to reload it.
3. It's useful for debugging: "systemd-analyze dump" now shows
this information, helping substantially with understanding how
systemd's dependency tree came to be the way it came to be.
2017-10-25 20:46:01 +02:00
|
|
|
static int mount_add_mount_dependencies(Mount *m) {
|
2010-09-28 01:03:19 +02:00
|
|
|
MountParameters *pm;
|
2012-01-15 12:04:08 +01:00
|
|
|
Unit *other;
|
2013-09-26 20:14:24 +02:00
|
|
|
Set *s;
|
2010-01-29 02:07:41 +01:00
|
|
|
int r;
|
|
|
|
|
2010-05-13 03:07:16 +02:00
|
|
|
assert(m);
|
2010-01-29 02:07:41 +01:00
|
|
|
|
2013-09-26 20:14:24 +02:00
|
|
|
if (!path_equal(m->where, "/")) {
|
core: track why unit dependencies came to be
This replaces the dependencies Set* objects by Hashmap* objects, where
the key is the depending Unit, and the value is a bitmask encoding why
the specific dependency was created.
The bitmask contains a number of different, defined bits, that indicate
why dependencies exist, for example whether they are created due to
explicitly configured deps in files, by udev rules or implicitly.
Note that memory usage is not increased by this change, even though we
store more information, as we manage to encode the bit mask inside the
value pointer each Hashmap entry contains.
Why this all? When we know how a dependency came to be, we can update
dependencies correctly when a configuration source changes but others
are left unaltered. Specifically:
1. We can fix UDEV_WANTS dependency generation: so far we kept adding
dependencies configured that way, but if a device lost such a
dependency we couldn't them again as there was no scheme for removing
of dependencies in place.
2. We can implement "pin-pointed" reload of unit files. If we know what
dependencies were created as result of configuration in a unit file,
then we know what to flush out when we want to reload it.
3. It's useful for debugging: "systemd-analyze dump" now shows
this information, helping substantially with understanding how
systemd's dependency tree came to be the way it came to be.
2017-10-25 20:46:01 +02:00
|
|
|
_cleanup_free_ char *parent = NULL;
|
|
|
|
|
|
|
|
/* Adds in links to other mount points that might lie further up in the hierarchy */
|
2015-10-26 17:30:56 +01:00
|
|
|
|
|
|
|
parent = dirname_malloc(m->where);
|
|
|
|
if (!parent)
|
|
|
|
return -ENOMEM;
|
2010-05-24 05:25:33 +02:00
|
|
|
|
core: track why unit dependencies came to be
This replaces the dependencies Set* objects by Hashmap* objects, where
the key is the depending Unit, and the value is a bitmask encoding why
the specific dependency was created.
The bitmask contains a number of different, defined bits, that indicate
why dependencies exist, for example whether they are created due to
explicitly configured deps in files, by udev rules or implicitly.
Note that memory usage is not increased by this change, even though we
store more information, as we manage to encode the bit mask inside the
value pointer each Hashmap entry contains.
Why this all? When we know how a dependency came to be, we can update
dependencies correctly when a configuration source changes but others
are left unaltered. Specifically:
1. We can fix UDEV_WANTS dependency generation: so far we kept adding
dependencies configured that way, but if a device lost such a
dependency we couldn't them again as there was no scheme for removing
of dependencies in place.
2. We can implement "pin-pointed" reload of unit files. If we know what
dependencies were created as result of configuration in a unit file,
then we know what to flush out when we want to reload it.
3. It's useful for debugging: "systemd-analyze dump" now shows
this information, helping substantially with understanding how
systemd's dependency tree came to be the way it came to be.
2017-10-25 20:46:01 +02:00
|
|
|
r = unit_require_mounts_for(UNIT(m), parent, UNIT_DEPENDENCY_IMPLICIT);
|
2013-01-04 21:29:48 +01:00
|
|
|
if (r < 0)
|
2010-05-24 05:25:33 +02:00
|
|
|
return r;
|
2013-01-04 21:29:48 +01:00
|
|
|
}
|
2010-05-24 05:25:33 +02:00
|
|
|
|
core: track why unit dependencies came to be
This replaces the dependencies Set* objects by Hashmap* objects, where
the key is the depending Unit, and the value is a bitmask encoding why
the specific dependency was created.
The bitmask contains a number of different, defined bits, that indicate
why dependencies exist, for example whether they are created due to
explicitly configured deps in files, by udev rules or implicitly.
Note that memory usage is not increased by this change, even though we
store more information, as we manage to encode the bit mask inside the
value pointer each Hashmap entry contains.
Why this all? When we know how a dependency came to be, we can update
dependencies correctly when a configuration source changes but others
are left unaltered. Specifically:
1. We can fix UDEV_WANTS dependency generation: so far we kept adding
dependencies configured that way, but if a device lost such a
dependency we couldn't them again as there was no scheme for removing
of dependencies in place.
2. We can implement "pin-pointed" reload of unit files. If we know what
dependencies were created as result of configuration in a unit file,
then we know what to flush out when we want to reload it.
3. It's useful for debugging: "systemd-analyze dump" now shows
this information, helping substantially with understanding how
systemd's dependency tree came to be the way it came to be.
2017-10-25 20:46:01 +02:00
|
|
|
/* Adds in dependencies to other mount points that might be needed for the source path (if this is a bind mount
|
|
|
|
* or a loop mount) to be available. */
|
2013-09-26 20:14:24 +02:00
|
|
|
pm = get_mount_parameters_fragment(m);
|
2013-10-05 19:09:43 +02:00
|
|
|
if (pm && pm->what &&
|
|
|
|
path_is_absolute(pm->what) &&
|
2016-04-25 13:25:00 +02:00
|
|
|
(mount_is_bind(pm) || mount_is_loop(pm) || !mount_is_network(pm))) {
|
2013-10-05 19:09:43 +02:00
|
|
|
|
core: track why unit dependencies came to be
This replaces the dependencies Set* objects by Hashmap* objects, where
the key is the depending Unit, and the value is a bitmask encoding why
the specific dependency was created.
The bitmask contains a number of different, defined bits, that indicate
why dependencies exist, for example whether they are created due to
explicitly configured deps in files, by udev rules or implicitly.
Note that memory usage is not increased by this change, even though we
store more information, as we manage to encode the bit mask inside the
value pointer each Hashmap entry contains.
Why this all? When we know how a dependency came to be, we can update
dependencies correctly when a configuration source changes but others
are left unaltered. Specifically:
1. We can fix UDEV_WANTS dependency generation: so far we kept adding
dependencies configured that way, but if a device lost such a
dependency we couldn't them again as there was no scheme for removing
of dependencies in place.
2. We can implement "pin-pointed" reload of unit files. If we know what
dependencies were created as result of configuration in a unit file,
then we know what to flush out when we want to reload it.
3. It's useful for debugging: "systemd-analyze dump" now shows
this information, helping substantially with understanding how
systemd's dependency tree came to be the way it came to be.
2017-10-25 20:46:01 +02:00
|
|
|
r = unit_require_mounts_for(UNIT(m), pm->what, UNIT_DEPENDENCY_FILE);
|
2013-01-04 21:29:48 +01:00
|
|
|
if (r < 0)
|
2010-05-13 03:07:16 +02:00
|
|
|
return r;
|
2013-01-04 21:29:48 +01:00
|
|
|
}
|
2010-01-29 02:07:41 +01:00
|
|
|
|
core: track why unit dependencies came to be
This replaces the dependencies Set* objects by Hashmap* objects, where
the key is the depending Unit, and the value is a bitmask encoding why
the specific dependency was created.
The bitmask contains a number of different, defined bits, that indicate
why dependencies exist, for example whether they are created due to
explicitly configured deps in files, by udev rules or implicitly.
Note that memory usage is not increased by this change, even though we
store more information, as we manage to encode the bit mask inside the
value pointer each Hashmap entry contains.
Why this all? When we know how a dependency came to be, we can update
dependencies correctly when a configuration source changes but others
are left unaltered. Specifically:
1. We can fix UDEV_WANTS dependency generation: so far we kept adding
dependencies configured that way, but if a device lost such a
dependency we couldn't them again as there was no scheme for removing
of dependencies in place.
2. We can implement "pin-pointed" reload of unit files. If we know what
dependencies were created as result of configuration in a unit file,
then we know what to flush out when we want to reload it.
3. It's useful for debugging: "systemd-analyze dump" now shows
this information, helping substantially with understanding how
systemd's dependency tree came to be the way it came to be.
2017-10-25 20:46:01 +02:00
|
|
|
/* Adds in dependencies to other units that use this path or paths further down in the hierarchy */
|
2013-09-26 20:14:24 +02:00
|
|
|
s = manager_get_units_requiring_mounts_for(UNIT(m)->manager, m->where);
|
2020-09-08 11:58:29 +02:00
|
|
|
SET_FOREACH(other, s) {
|
2010-01-29 02:07:41 +01:00
|
|
|
|
2013-09-26 20:14:24 +02:00
|
|
|
if (other->load_state != UNIT_LOADED)
|
|
|
|
continue;
|
2010-01-29 02:07:41 +01:00
|
|
|
|
2013-09-26 20:14:24 +02:00
|
|
|
if (other == UNIT(m))
|
|
|
|
continue;
|
2010-01-29 02:07:41 +01:00
|
|
|
|
core: track why unit dependencies came to be
This replaces the dependencies Set* objects by Hashmap* objects, where
the key is the depending Unit, and the value is a bitmask encoding why
the specific dependency was created.
The bitmask contains a number of different, defined bits, that indicate
why dependencies exist, for example whether they are created due to
explicitly configured deps in files, by udev rules or implicitly.
Note that memory usage is not increased by this change, even though we
store more information, as we manage to encode the bit mask inside the
value pointer each Hashmap entry contains.
Why this all? When we know how a dependency came to be, we can update
dependencies correctly when a configuration source changes but others
are left unaltered. Specifically:
1. We can fix UDEV_WANTS dependency generation: so far we kept adding
dependencies configured that way, but if a device lost such a
dependency we couldn't them again as there was no scheme for removing
of dependencies in place.
2. We can implement "pin-pointed" reload of unit files. If we know what
dependencies were created as result of configuration in a unit file,
then we know what to flush out when we want to reload it.
3. It's useful for debugging: "systemd-analyze dump" now shows
this information, helping substantially with understanding how
systemd's dependency tree came to be the way it came to be.
2017-10-25 20:46:01 +02:00
|
|
|
r = unit_add_dependency(other, UNIT_AFTER, UNIT(m), true, UNIT_DEPENDENCY_PATH);
|
2013-01-04 21:29:48 +01:00
|
|
|
if (r < 0)
|
2010-05-13 03:07:16 +02:00
|
|
|
return r;
|
2010-01-29 02:07:41 +01:00
|
|
|
|
2013-09-26 20:14:24 +02:00
|
|
|
if (UNIT(m)->fragment_path) {
|
|
|
|
/* If we have fragment configuration, then make this dependency required */
|
core: track why unit dependencies came to be
This replaces the dependencies Set* objects by Hashmap* objects, where
the key is the depending Unit, and the value is a bitmask encoding why
the specific dependency was created.
The bitmask contains a number of different, defined bits, that indicate
why dependencies exist, for example whether they are created due to
explicitly configured deps in files, by udev rules or implicitly.
Note that memory usage is not increased by this change, even though we
store more information, as we manage to encode the bit mask inside the
value pointer each Hashmap entry contains.
Why this all? When we know how a dependency came to be, we can update
dependencies correctly when a configuration source changes but others
are left unaltered. Specifically:
1. We can fix UDEV_WANTS dependency generation: so far we kept adding
dependencies configured that way, but if a device lost such a
dependency we couldn't them again as there was no scheme for removing
of dependencies in place.
2. We can implement "pin-pointed" reload of unit files. If we know what
dependencies were created as result of configuration in a unit file,
then we know what to flush out when we want to reload it.
3. It's useful for debugging: "systemd-analyze dump" now shows
this information, helping substantially with understanding how
systemd's dependency tree came to be the way it came to be.
2017-10-25 20:46:01 +02:00
|
|
|
r = unit_add_dependency(other, UNIT_REQUIRES, UNIT(m), true, UNIT_DEPENDENCY_PATH);
|
2013-09-26 20:14:24 +02:00
|
|
|
if (r < 0)
|
|
|
|
return r;
|
|
|
|
}
|
2012-04-29 14:26:07 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
core: track why unit dependencies came to be
This replaces the dependencies Set* objects by Hashmap* objects, where
the key is the depending Unit, and the value is a bitmask encoding why
the specific dependency was created.
The bitmask contains a number of different, defined bits, that indicate
why dependencies exist, for example whether they are created due to
explicitly configured deps in files, by udev rules or implicitly.
Note that memory usage is not increased by this change, even though we
store more information, as we manage to encode the bit mask inside the
value pointer each Hashmap entry contains.
Why this all? When we know how a dependency came to be, we can update
dependencies correctly when a configuration source changes but others
are left unaltered. Specifically:
1. We can fix UDEV_WANTS dependency generation: so far we kept adding
dependencies configured that way, but if a device lost such a
dependency we couldn't them again as there was no scheme for removing
of dependencies in place.
2. We can implement "pin-pointed" reload of unit files. If we know what
dependencies were created as result of configuration in a unit file,
then we know what to flush out when we want to reload it.
3. It's useful for debugging: "systemd-analyze dump" now shows
this information, helping substantially with understanding how
systemd's dependency tree came to be the way it came to be.
2017-10-25 20:46:01 +02:00
|
|
|
static int mount_add_device_dependencies(Mount *m) {
|
|
|
|
UnitDependencyMask mask;
|
|
|
|
MountParameters *p;
|
2016-12-16 17:13:58 +01:00
|
|
|
UnitDependency dep;
|
2010-10-13 03:57:04 +02:00
|
|
|
int r;
|
2010-08-25 20:37:04 +02:00
|
|
|
|
|
|
|
assert(m);
|
|
|
|
|
2015-01-28 13:53:25 +01:00
|
|
|
p = get_mount_parameters(m);
|
2012-05-22 19:23:33 +02:00
|
|
|
if (!p)
|
2010-08-25 20:37:04 +02:00
|
|
|
return 0;
|
|
|
|
|
2010-10-13 03:57:04 +02:00
|
|
|
if (!p->what)
|
2010-08-25 20:37:04 +02:00
|
|
|
return 0;
|
2010-09-28 01:03:19 +02:00
|
|
|
|
2012-09-24 12:48:46 +02:00
|
|
|
if (mount_is_bind(p))
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
if (!is_device_path(p->what))
|
|
|
|
return 0;
|
|
|
|
|
2020-01-21 18:09:09 +01:00
|
|
|
/* /dev/root is a really weird thing, it's not a real device, but just a path the kernel exports for
|
|
|
|
* the root file system specified on the kernel command line. Ignore it here. */
|
|
|
|
if (PATH_IN_SET(p->what, "/dev/root", "/dev/nfs"))
|
2015-05-13 14:40:37 +02:00
|
|
|
return 0;
|
|
|
|
|
2012-09-24 12:48:46 +02:00
|
|
|
if (path_equal(m->where, "/"))
|
|
|
|
return 0;
|
|
|
|
|
2020-01-21 18:19:08 +01:00
|
|
|
/* Mount units from /proc/self/mountinfo are not bound to devices by default since they're subject to
|
|
|
|
* races when devices are unplugged. But the user can still force this dep with an appropriate option
|
|
|
|
* (or udev property) so the mount units are automatically stopped when the device disappears
|
|
|
|
* suddenly. */
|
2016-12-16 17:13:58 +01:00
|
|
|
dep = mount_is_bound_to_device(m) ? UNIT_BINDS_TO : UNIT_REQUIRES;
|
|
|
|
|
2019-01-17 16:09:13 +01:00
|
|
|
/* We always use 'what' from /proc/self/mountinfo if mounted */
|
|
|
|
mask = m->from_proc_self_mountinfo ? UNIT_DEPENDENCY_MOUNTINFO_IMPLICIT : UNIT_DEPENDENCY_FILE;
|
core: track why unit dependencies came to be
This replaces the dependencies Set* objects by Hashmap* objects, where
the key is the depending Unit, and the value is a bitmask encoding why
the specific dependency was created.
The bitmask contains a number of different, defined bits, that indicate
why dependencies exist, for example whether they are created due to
explicitly configured deps in files, by udev rules or implicitly.
Note that memory usage is not increased by this change, even though we
store more information, as we manage to encode the bit mask inside the
value pointer each Hashmap entry contains.
Why this all? When we know how a dependency came to be, we can update
dependencies correctly when a configuration source changes but others
are left unaltered. Specifically:
1. We can fix UDEV_WANTS dependency generation: so far we kept adding
dependencies configured that way, but if a device lost such a
dependency we couldn't them again as there was no scheme for removing
of dependencies in place.
2. We can implement "pin-pointed" reload of unit files. If we know what
dependencies were created as result of configuration in a unit file,
then we know what to flush out when we want to reload it.
3. It's useful for debugging: "systemd-analyze dump" now shows
this information, helping substantially with understanding how
systemd's dependency tree came to be the way it came to be.
2017-10-25 20:46:01 +02:00
|
|
|
|
2019-10-28 18:50:43 +01:00
|
|
|
r = unit_add_node_dependency(UNIT(m), p->what, dep, mask);
|
2012-09-24 12:48:46 +02:00
|
|
|
if (r < 0)
|
|
|
|
return r;
|
2010-10-13 03:57:04 +02:00
|
|
|
|
2020-01-21 18:19:08 +01:00
|
|
|
return unit_add_blockdev_dependency(UNIT(m), p->what, mask);
|
2010-08-25 20:37:04 +02:00
|
|
|
}
|
|
|
|
|
core: track why unit dependencies came to be
This replaces the dependencies Set* objects by Hashmap* objects, where
the key is the depending Unit, and the value is a bitmask encoding why
the specific dependency was created.
The bitmask contains a number of different, defined bits, that indicate
why dependencies exist, for example whether they are created due to
explicitly configured deps in files, by udev rules or implicitly.
Note that memory usage is not increased by this change, even though we
store more information, as we manage to encode the bit mask inside the
value pointer each Hashmap entry contains.
Why this all? When we know how a dependency came to be, we can update
dependencies correctly when a configuration source changes but others
are left unaltered. Specifically:
1. We can fix UDEV_WANTS dependency generation: so far we kept adding
dependencies configured that way, but if a device lost such a
dependency we couldn't them again as there was no scheme for removing
of dependencies in place.
2. We can implement "pin-pointed" reload of unit files. If we know what
dependencies were created as result of configuration in a unit file,
then we know what to flush out when we want to reload it.
3. It's useful for debugging: "systemd-analyze dump" now shows
this information, helping substantially with understanding how
systemd's dependency tree came to be the way it came to be.
2017-10-25 20:46:01 +02:00
|
|
|
static int mount_add_quota_dependencies(Mount *m) {
|
|
|
|
UnitDependencyMask mask;
|
2012-05-22 19:23:33 +02:00
|
|
|
MountParameters *p;
|
core: track why unit dependencies came to be
This replaces the dependencies Set* objects by Hashmap* objects, where
the key is the depending Unit, and the value is a bitmask encoding why
the specific dependency was created.
The bitmask contains a number of different, defined bits, that indicate
why dependencies exist, for example whether they are created due to
explicitly configured deps in files, by udev rules or implicitly.
Note that memory usage is not increased by this change, even though we
store more information, as we manage to encode the bit mask inside the
value pointer each Hashmap entry contains.
Why this all? When we know how a dependency came to be, we can update
dependencies correctly when a configuration source changes but others
are left unaltered. Specifically:
1. We can fix UDEV_WANTS dependency generation: so far we kept adding
dependencies configured that way, but if a device lost such a
dependency we couldn't them again as there was no scheme for removing
of dependencies in place.
2. We can implement "pin-pointed" reload of unit files. If we know what
dependencies were created as result of configuration in a unit file,
then we know what to flush out when we want to reload it.
3. It's useful for debugging: "systemd-analyze dump" now shows
this information, helping substantially with understanding how
systemd's dependency tree came to be the way it came to be.
2017-10-25 20:46:01 +02:00
|
|
|
int r;
|
2012-05-22 19:23:33 +02:00
|
|
|
|
|
|
|
assert(m);
|
|
|
|
|
2016-02-24 21:24:23 +01:00
|
|
|
if (!MANAGER_IS_SYSTEM(UNIT(m)->manager))
|
2012-05-22 19:23:33 +02:00
|
|
|
return 0;
|
|
|
|
|
|
|
|
p = get_mount_parameters_fragment(m);
|
|
|
|
if (!p)
|
|
|
|
return 0;
|
|
|
|
|
2018-11-28 12:32:35 +01:00
|
|
|
if (!mount_needs_quota(p))
|
2012-05-22 19:23:33 +02:00
|
|
|
return 0;
|
|
|
|
|
core: track why unit dependencies came to be
This replaces the dependencies Set* objects by Hashmap* objects, where
the key is the depending Unit, and the value is a bitmask encoding why
the specific dependency was created.
The bitmask contains a number of different, defined bits, that indicate
why dependencies exist, for example whether they are created due to
explicitly configured deps in files, by udev rules or implicitly.
Note that memory usage is not increased by this change, even though we
store more information, as we manage to encode the bit mask inside the
value pointer each Hashmap entry contains.
Why this all? When we know how a dependency came to be, we can update
dependencies correctly when a configuration source changes but others
are left unaltered. Specifically:
1. We can fix UDEV_WANTS dependency generation: so far we kept adding
dependencies configured that way, but if a device lost such a
dependency we couldn't them again as there was no scheme for removing
of dependencies in place.
2. We can implement "pin-pointed" reload of unit files. If we know what
dependencies were created as result of configuration in a unit file,
then we know what to flush out when we want to reload it.
3. It's useful for debugging: "systemd-analyze dump" now shows
this information, helping substantially with understanding how
systemd's dependency tree came to be the way it came to be.
2017-10-25 20:46:01 +02:00
|
|
|
mask = m->from_fragment ? UNIT_DEPENDENCY_FILE : UNIT_DEPENDENCY_MOUNTINFO_IMPLICIT;
|
|
|
|
|
2018-09-15 20:02:00 +02:00
|
|
|
r = unit_add_two_dependencies_by_name(UNIT(m), UNIT_BEFORE, UNIT_WANTS, SPECIAL_QUOTACHECK_SERVICE, true, mask);
|
2012-05-22 19:23:33 +02:00
|
|
|
if (r < 0)
|
|
|
|
return r;
|
|
|
|
|
2018-09-15 20:02:00 +02:00
|
|
|
r = unit_add_two_dependencies_by_name(UNIT(m), UNIT_BEFORE, UNIT_WANTS, SPECIAL_QUOTAON_SERVICE, true, mask);
|
2012-05-22 19:23:33 +02:00
|
|
|
if (r < 0)
|
|
|
|
return r;
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2020-11-05 13:08:02 +01:00
|
|
|
static bool mount_is_extrinsic(Unit *u) {
|
2013-08-19 06:34:13 +02:00
|
|
|
MountParameters *p;
|
2020-11-05 13:08:02 +01:00
|
|
|
Mount *m = MOUNT(u);
|
2016-11-29 22:50:21 +01:00
|
|
|
assert(m);
|
2013-08-19 06:34:13 +02:00
|
|
|
|
2020-03-30 10:39:21 +02:00
|
|
|
/* Returns true for all units that are "magic" and should be excluded from the usual
|
|
|
|
* start-up and shutdown dependencies. We call them "extrinsic" here, as they are generally
|
|
|
|
* mounted outside of the systemd dependency logic. We shouldn't attempt to manage them
|
|
|
|
* ourselves but it's fine if the user operates on them with us. */
|
2016-11-29 22:50:21 +01:00
|
|
|
|
2020-03-30 10:39:21 +02:00
|
|
|
/* We only automatically manage mounts if we are in system mode */
|
2020-11-05 13:08:02 +01:00
|
|
|
if (MANAGER_IS_USER(u->manager))
|
2019-11-15 14:00:12 +01:00
|
|
|
return true;
|
|
|
|
|
2013-08-19 06:34:13 +02:00
|
|
|
p = get_mount_parameters(m);
|
2020-03-30 10:39:21 +02:00
|
|
|
if (p && fstab_is_extrinsic(m->where, p->options))
|
2016-11-29 22:50:21 +01:00
|
|
|
return true;
|
2013-08-19 06:34:13 +02:00
|
|
|
|
2016-11-29 22:50:21 +01:00
|
|
|
return false;
|
2013-08-19 06:34:13 +02:00
|
|
|
}
|
|
|
|
|
2020-04-09 15:01:53 +02:00
|
|
|
static int mount_add_default_ordering_dependencies(
|
|
|
|
Mount *m,
|
|
|
|
MountParameters *p,
|
|
|
|
UnitDependencyMask mask) {
|
|
|
|
|
2020-04-02 08:29:36 +02:00
|
|
|
const char *after, *before, *e;
|
2018-11-28 12:35:37 +01:00
|
|
|
int r;
|
2010-07-12 22:55:27 +02:00
|
|
|
|
|
|
|
assert(m);
|
|
|
|
|
2020-04-02 08:29:36 +02:00
|
|
|
e = path_startswith(m->where, "/sysroot");
|
|
|
|
if (e && in_initrd()) {
|
|
|
|
/* All mounts under /sysroot need to happen later, at initrd-fs.target time. IOW,
|
|
|
|
* it's not technically part of the basic initrd filesystem itself, and so
|
|
|
|
* shouldn't inherit the default Before=local-fs.target dependency. */
|
|
|
|
|
|
|
|
after = NULL;
|
|
|
|
before = isempty(e) ? SPECIAL_INITRD_ROOT_FS_TARGET : SPECIAL_INITRD_FS_TARGET;
|
|
|
|
|
|
|
|
} else if (mount_is_network(p)) {
|
2015-11-11 20:46:09 +01:00
|
|
|
after = SPECIAL_REMOTE_FS_PRE_TARGET;
|
2018-11-28 12:35:37 +01:00
|
|
|
before = SPECIAL_REMOTE_FS_TARGET;
|
2020-04-02 08:51:00 +02:00
|
|
|
|
2018-11-28 12:35:37 +01:00
|
|
|
} else {
|
2015-11-11 20:46:09 +01:00
|
|
|
after = SPECIAL_LOCAL_FS_PRE_TARGET;
|
2018-11-28 12:35:37 +01:00
|
|
|
before = SPECIAL_LOCAL_FS_TARGET;
|
|
|
|
}
|
|
|
|
|
2020-04-02 08:58:31 +02:00
|
|
|
if (!mount_is_nofail(m) && !mount_is_automount(p)) {
|
2019-01-26 12:00:04 +01:00
|
|
|
r = unit_add_dependency_by_name(UNIT(m), UNIT_BEFORE, before, true, mask);
|
|
|
|
if (r < 0)
|
|
|
|
return r;
|
|
|
|
}
|
2015-11-11 20:46:09 +01:00
|
|
|
|
2020-04-02 08:29:36 +02:00
|
|
|
if (after) {
|
|
|
|
r = unit_add_dependency_by_name(UNIT(m), UNIT_AFTER, after, true, mask);
|
|
|
|
if (r < 0)
|
|
|
|
return r;
|
|
|
|
}
|
2013-03-25 22:04:40 +01:00
|
|
|
|
2020-04-09 15:01:53 +02:00
|
|
|
return unit_add_two_dependencies_by_name(UNIT(m), UNIT_BEFORE, UNIT_CONFLICTS,
|
|
|
|
SPECIAL_UMOUNT_TARGET, true, mask);
|
|
|
|
}
|
|
|
|
|
2010-07-12 22:55:27 +02:00
|
|
|
static int mount_add_default_dependencies(Mount *m) {
|
core: track why unit dependencies came to be
This replaces the dependencies Set* objects by Hashmap* objects, where
the key is the depending Unit, and the value is a bitmask encoding why
the specific dependency was created.
The bitmask contains a number of different, defined bits, that indicate
why dependencies exist, for example whether they are created due to
explicitly configured deps in files, by udev rules or implicitly.
Note that memory usage is not increased by this change, even though we
store more information, as we manage to encode the bit mask inside the
value pointer each Hashmap entry contains.
Why this all? When we know how a dependency came to be, we can update
dependencies correctly when a configuration source changes but others
are left unaltered. Specifically:
1. We can fix UDEV_WANTS dependency generation: so far we kept adding
dependencies configured that way, but if a device lost such a
dependency we couldn't them again as there was no scheme for removing
of dependencies in place.
2. We can implement "pin-pointed" reload of unit files. If we know what
dependencies were created as result of configuration in a unit file,
then we know what to flush out when we want to reload it.
3. It's useful for debugging: "systemd-analyze dump" now shows
this information, helping substantially with understanding how
systemd's dependency tree came to be the way it came to be.
2017-10-25 20:46:01 +02:00
|
|
|
UnitDependencyMask mask;
|
2012-01-13 23:55:28 +01:00
|
|
|
MountParameters *p;
|
2018-11-28 12:35:37 +01:00
|
|
|
int r;
|
2010-07-12 22:55:27 +02:00
|
|
|
|
|
|
|
assert(m);
|
|
|
|
|
2015-11-11 20:42:39 +01:00
|
|
|
if (!UNIT(m)->default_dependencies)
|
|
|
|
return 0;
|
|
|
|
|
2020-04-09 15:01:53 +02:00
|
|
|
/* We do not add any default dependencies to /, /usr or /run/initramfs/, since they are
|
|
|
|
* guaranteed to stay mounted the whole time, since our system is on it. Also, don't
|
|
|
|
* bother with anything mounted below virtual file systems, it's also going to be virtual,
|
|
|
|
* and hence not worth the effort. */
|
2020-11-05 13:08:02 +01:00
|
|
|
if (mount_is_extrinsic(UNIT(m)))
|
2012-05-22 19:23:33 +02:00
|
|
|
return 0;
|
2010-07-12 22:55:27 +02:00
|
|
|
|
2015-01-23 13:44:44 +01:00
|
|
|
p = get_mount_parameters(m);
|
|
|
|
if (!p)
|
2012-05-22 19:23:33 +02:00
|
|
|
return 0;
|
|
|
|
|
core: track why unit dependencies came to be
This replaces the dependencies Set* objects by Hashmap* objects, where
the key is the depending Unit, and the value is a bitmask encoding why
the specific dependency was created.
The bitmask contains a number of different, defined bits, that indicate
why dependencies exist, for example whether they are created due to
explicitly configured deps in files, by udev rules or implicitly.
Note that memory usage is not increased by this change, even though we
store more information, as we manage to encode the bit mask inside the
value pointer each Hashmap entry contains.
Why this all? When we know how a dependency came to be, we can update
dependencies correctly when a configuration source changes but others
are left unaltered. Specifically:
1. We can fix UDEV_WANTS dependency generation: so far we kept adding
dependencies configured that way, but if a device lost such a
dependency we couldn't them again as there was no scheme for removing
of dependencies in place.
2. We can implement "pin-pointed" reload of unit files. If we know what
dependencies were created as result of configuration in a unit file,
then we know what to flush out when we want to reload it.
3. It's useful for debugging: "systemd-analyze dump" now shows
this information, helping substantially with understanding how
systemd's dependency tree came to be the way it came to be.
2017-10-25 20:46:01 +02:00
|
|
|
mask = m->from_fragment ? UNIT_DEPENDENCY_FILE : UNIT_DEPENDENCY_MOUNTINFO_DEFAULT;
|
2020-04-09 15:01:53 +02:00
|
|
|
|
|
|
|
r = mount_add_default_ordering_dependencies(m, p, mask);
|
2016-11-29 22:50:21 +01:00
|
|
|
if (r < 0)
|
|
|
|
return r;
|
core: track why unit dependencies came to be
This replaces the dependencies Set* objects by Hashmap* objects, where
the key is the depending Unit, and the value is a bitmask encoding why
the specific dependency was created.
The bitmask contains a number of different, defined bits, that indicate
why dependencies exist, for example whether they are created due to
explicitly configured deps in files, by udev rules or implicitly.
Note that memory usage is not increased by this change, even though we
store more information, as we manage to encode the bit mask inside the
value pointer each Hashmap entry contains.
Why this all? When we know how a dependency came to be, we can update
dependencies correctly when a configuration source changes but others
are left unaltered. Specifically:
1. We can fix UDEV_WANTS dependency generation: so far we kept adding
dependencies configured that way, but if a device lost such a
dependency we couldn't them again as there was no scheme for removing
of dependencies in place.
2. We can implement "pin-pointed" reload of unit files. If we know what
dependencies were created as result of configuration in a unit file,
then we know what to flush out when we want to reload it.
3. It's useful for debugging: "systemd-analyze dump" now shows
this information, helping substantially with understanding how
systemd's dependency tree came to be the way it came to be.
2017-10-25 20:46:01 +02:00
|
|
|
|
2013-03-25 22:04:40 +01:00
|
|
|
if (mount_is_network(p)) {
|
2020-04-02 08:51:00 +02:00
|
|
|
/* We order ourselves after network.target. This is primarily useful at shutdown:
|
|
|
|
* services that take down the network should order themselves before
|
|
|
|
* network.target, so that they are shut down only after this mount unit is
|
|
|
|
* stopped. */
|
2012-05-22 19:23:33 +02:00
|
|
|
|
2018-09-15 19:57:52 +02:00
|
|
|
r = unit_add_dependency_by_name(UNIT(m), UNIT_AFTER, SPECIAL_NETWORK_TARGET, true, mask);
|
2013-03-27 02:51:33 +01:00
|
|
|
if (r < 0)
|
|
|
|
return r;
|
|
|
|
|
2020-04-02 08:51:00 +02:00
|
|
|
/* We pull in network-online.target, and order ourselves after it. This is useful
|
|
|
|
* at start-up to actively pull in tools that want to be started before we start
|
|
|
|
* mounting network file systems, and whose purpose it is to delay this until the
|
|
|
|
* network is "up". */
|
2015-11-11 20:46:09 +01:00
|
|
|
|
2018-09-15 20:02:00 +02:00
|
|
|
r = unit_add_two_dependencies_by_name(UNIT(m), UNIT_WANTS, UNIT_AFTER, SPECIAL_NETWORK_ONLINE_TARGET, true, mask);
|
2013-03-25 22:04:40 +01:00
|
|
|
if (r < 0)
|
|
|
|
return r;
|
2018-11-28 12:35:37 +01:00
|
|
|
}
|
|
|
|
|
2017-10-26 17:24:55 +02:00
|
|
|
/* If this is a tmpfs mount then we have to unmount it before we try to deactivate swaps */
|
2017-11-12 14:25:58 +01:00
|
|
|
if (streq_ptr(p->fstype, "tmpfs")) {
|
2018-09-15 19:57:52 +02:00
|
|
|
r = unit_add_dependency_by_name(UNIT(m), UNIT_AFTER, SPECIAL_SWAP_TARGET, true, mask);
|
2017-10-26 17:24:55 +02:00
|
|
|
if (r < 0)
|
|
|
|
return r;
|
|
|
|
}
|
|
|
|
|
2010-07-12 22:55:27 +02:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2010-04-16 23:24:39 +02:00
|
|
|
static int mount_verify(Mount *m) {
|
2013-09-26 20:14:24 +02:00
|
|
|
_cleanup_free_ char *e = NULL;
|
2015-12-09 16:02:10 +01:00
|
|
|
MountParameters *p;
|
2015-04-30 20:21:00 +02:00
|
|
|
int r;
|
2013-09-26 20:14:24 +02:00
|
|
|
|
2010-04-16 23:24:39 +02:00
|
|
|
assert(m);
|
2019-10-11 12:48:33 +02:00
|
|
|
assert(UNIT(m)->load_state == UNIT_LOADED);
|
2010-04-16 23:24:39 +02:00
|
|
|
|
2017-07-31 12:32:09 +02:00
|
|
|
if (!m->from_fragment && !m->from_proc_self_mountinfo && !UNIT(m)->perpetual)
|
2010-05-21 03:32:21 +02:00
|
|
|
return -ENOENT;
|
|
|
|
|
2015-04-30 20:21:00 +02:00
|
|
|
r = unit_name_from_path(m->where, ".mount", &e);
|
|
|
|
if (r < 0)
|
core,network: major per-object logging rework
This changes log_unit_info() (and friends) to take a real Unit* object
insted of just a unit name as parameter. The call will now prefix all
logged messages with the unit name, thus allowing the unit name to be
dropped from the various passed romat strings, simplifying invocations
drastically, and unifying log output across messages. Also, UNIT= vs.
USER_UNIT= is now derived from the Manager object attached to the Unit
object, instead of getpid(). This has the benefit of correcting the
field for --test runs.
Also contains a couple of other logging improvements:
- Drops a couple of strerror() invocations in favour of using %m.
- Not only .mount units now warn if a symlinks exist for the mount
point already, .automount units do that too, now.
- A few invocations of log_struct() that didn't actually pass any
additional structured data have been replaced by simpler invocations
of log_unit_info() and friends.
- For structured data a new LOG_UNIT_MESSAGE() macro has been added,
that works like LOG_MESSAGE() but prefixes the message with the unit
name. Similar, there's now LOG_LINK_MESSAGE() and
LOG_NETDEV_MESSAGE().
- For structured data new LOG_UNIT_ID(), LOG_LINK_INTERFACE(),
LOG_NETDEV_INTERFACE() macros have been added that generate the
necessary per object fields. The old log_unit_struct() call has been
removed in favour of these new macros used in raw log_struct()
invocations. In addition to removing one more function call this
allows generated structured log messages that contain two object
fields, as necessary for example for network interfaces that are
joined into another network interface, and whose messages shall be
indexed by both.
- The LOG_ERRNO() macro has been removed, in favour of
log_struct_errno(). The latter has the benefit of ensuring that %m in
format strings is properly resolved to the specified error number.
- A number of logging messages have been converted to use
log_unit_info() instead of log_info()
- The client code in sysv-generator no longer #includes core code from
src/core/.
- log_unit_full_errno() has been removed, log_unit_full() instead takes
an errno now, too.
- log_unit_info(), log_link_info(), log_netdev_info() and friends, now
avoid double evaluation of their parameters
2015-05-11 20:38:21 +02:00
|
|
|
return log_unit_error_errno(UNIT(m), r, "Failed to generate unit name from mount path: %m");
|
2010-04-16 23:24:39 +02:00
|
|
|
|
2020-11-26 01:27:21 +01:00
|
|
|
if (!unit_has_name(UNIT(m), e))
|
|
|
|
return log_unit_error_errno(UNIT(m), SYNTHETIC_ERRNO(ENOEXEC), "Where= setting doesn't match unit name. Refusing.");
|
2010-04-16 23:24:39 +02:00
|
|
|
|
2020-11-26 01:27:21 +01:00
|
|
|
if (mount_point_is_api(m->where) || mount_point_ignore(m->where))
|
|
|
|
return log_unit_error_errno(UNIT(m), SYNTHETIC_ERRNO(ENOEXEC), "Cannot create mount unit for API file system %s. Refusing.", m->where);
|
2011-04-05 23:39:21 +02:00
|
|
|
|
2015-12-09 16:02:10 +01:00
|
|
|
p = get_mount_parameters_fragment(m);
|
2020-01-17 15:09:01 +01:00
|
|
|
if (p && !p->what && !UNIT(m)->perpetual)
|
|
|
|
return log_unit_error_errno(UNIT(m), SYNTHETIC_ERRNO(ENOEXEC),
|
|
|
|
"What= setting is missing. Refusing.");
|
2010-05-14 02:29:45 +02:00
|
|
|
|
2020-11-26 01:27:21 +01:00
|
|
|
if (m->exec_context.pam_name && m->kill_context.kill_mode != KILL_CONTROL_GROUP)
|
|
|
|
return log_unit_error_errno(UNIT(m), SYNTHETIC_ERRNO(ENOEXEC), "Unit has PAM enabled. Kill mode must be set to control-group'. Refusing.");
|
2010-06-19 16:57:54 +02:00
|
|
|
|
2010-04-16 23:24:39 +02:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2019-11-15 14:00:54 +01:00
|
|
|
static int mount_add_non_exec_dependencies(Mount *m) {
|
|
|
|
int r;
|
|
|
|
assert(m);
|
|
|
|
|
|
|
|
/* Adds in all dependencies directly responsible for ordering the mount, as opposed to dependencies
|
|
|
|
* resulting from the ExecContext and such. */
|
|
|
|
|
|
|
|
r = mount_add_device_dependencies(m);
|
|
|
|
if (r < 0)
|
|
|
|
return r;
|
|
|
|
|
|
|
|
r = mount_add_mount_dependencies(m);
|
|
|
|
if (r < 0)
|
|
|
|
return r;
|
|
|
|
|
|
|
|
r = mount_add_quota_dependencies(m);
|
|
|
|
if (r < 0)
|
|
|
|
return r;
|
|
|
|
|
|
|
|
r = mount_add_default_dependencies(m);
|
|
|
|
if (r < 0)
|
|
|
|
return r;
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2012-06-29 01:47:24 +02:00
|
|
|
static int mount_add_extras(Mount *m) {
|
|
|
|
Unit *u = UNIT(m);
|
2010-04-10 17:53:17 +02:00
|
|
|
int r;
|
|
|
|
|
2013-12-02 23:30:19 +01:00
|
|
|
assert(m);
|
|
|
|
|
2018-11-28 12:37:23 +01:00
|
|
|
/* Note: this call might be called after we already have been loaded once (and even when it has already been
|
|
|
|
* activated), in case data from /proc/self/mountinfo has changed. This means all code here needs to be ready
|
|
|
|
* to run with an already set up unit. */
|
|
|
|
|
2013-12-02 23:30:19 +01:00
|
|
|
if (u->fragment_path)
|
2012-06-29 01:47:24 +02:00
|
|
|
m->from_fragment = true;
|
2010-04-10 17:53:17 +02:00
|
|
|
|
2012-06-29 01:47:24 +02:00
|
|
|
if (!m->where) {
|
2015-04-30 20:21:00 +02:00
|
|
|
r = unit_name_to_path(u->id, &m->where);
|
|
|
|
if (r < 0)
|
|
|
|
return r;
|
2012-06-29 01:47:24 +02:00
|
|
|
}
|
2010-04-21 03:27:44 +02:00
|
|
|
|
2018-05-31 16:39:31 +02:00
|
|
|
path_simplify(m->where, false);
|
2010-04-10 17:53:17 +02:00
|
|
|
|
2013-12-02 23:30:19 +01:00
|
|
|
if (!u->description) {
|
2012-06-29 01:47:24 +02:00
|
|
|
r = unit_set_description(u, m->where);
|
|
|
|
if (r < 0)
|
2010-08-25 20:37:04 +02:00
|
|
|
return r;
|
2012-06-29 01:47:24 +02:00
|
|
|
}
|
2010-05-13 03:07:16 +02:00
|
|
|
|
2014-03-19 20:40:05 +01:00
|
|
|
r = unit_patch_contexts(u);
|
|
|
|
if (r < 0)
|
|
|
|
return r;
|
2010-07-10 02:41:06 +02:00
|
|
|
|
2014-03-19 20:40:05 +01:00
|
|
|
r = unit_add_exec_dependencies(u, &m->exec_context);
|
2013-06-17 21:33:26 +02:00
|
|
|
if (r < 0)
|
|
|
|
return r;
|
|
|
|
|
2015-08-28 17:36:39 +02:00
|
|
|
r = unit_set_default_slice(u);
|
2012-06-29 01:47:24 +02:00
|
|
|
if (r < 0)
|
|
|
|
return r;
|
|
|
|
|
2019-11-15 14:00:54 +01:00
|
|
|
r = mount_add_non_exec_dependencies(m);
|
2015-11-11 20:42:39 +01:00
|
|
|
if (r < 0)
|
|
|
|
return r;
|
2014-03-19 20:40:05 +01:00
|
|
|
|
2012-06-29 01:47:24 +02:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2019-10-11 12:48:33 +02:00
|
|
|
static void mount_load_root_mount(Unit *u) {
|
2016-10-25 00:04:55 +02:00
|
|
|
assert(u);
|
|
|
|
|
|
|
|
if (!unit_has_name(u, SPECIAL_ROOT_MOUNT))
|
2019-10-11 12:48:33 +02:00
|
|
|
return;
|
2016-10-25 00:04:55 +02:00
|
|
|
|
|
|
|
u->perpetual = true;
|
|
|
|
u->default_dependencies = false;
|
|
|
|
|
|
|
|
/* The stdio/kmsg bridge socket is on /, in order to avoid a dep loop, don't use kmsg logging for -.mount */
|
|
|
|
MOUNT(u)->exec_context.std_output = EXEC_OUTPUT_NULL;
|
|
|
|
MOUNT(u)->exec_context.std_input = EXEC_INPUT_NULL;
|
|
|
|
|
|
|
|
if (!u->description)
|
|
|
|
u->description = strdup("Root Mount");
|
|
|
|
}
|
|
|
|
|
2012-06-29 01:47:24 +02:00
|
|
|
static int mount_load(Unit *u) {
|
|
|
|
Mount *m = MOUNT(u);
|
2019-10-11 12:48:33 +02:00
|
|
|
int r, q = 0;
|
2012-06-29 01:47:24 +02:00
|
|
|
|
|
|
|
assert(u);
|
|
|
|
assert(u->load_state == UNIT_STUB);
|
|
|
|
|
2019-10-11 12:48:33 +02:00
|
|
|
mount_load_root_mount(u);
|
2016-10-25 00:04:55 +02:00
|
|
|
|
2019-10-11 10:41:44 +02:00
|
|
|
bool fragment_optional = m->from_proc_self_mountinfo || u->perpetual;
|
2019-10-11 12:48:33 +02:00
|
|
|
r = unit_load_fragment_and_dropin(u, !fragment_optional);
|
2018-11-28 12:37:43 +01:00
|
|
|
|
|
|
|
/* Add in some extras. Note we do this in all cases (even if we failed to load the unit) when announced by the
|
|
|
|
* kernel, because we need some things to be set up no matter what when the kernel establishes a mount and thus
|
|
|
|
* we need to update the state in our unit to track it. After all, consider that we don't allow changing the
|
|
|
|
* 'slice' field for a unit once it is active. */
|
|
|
|
if (u->load_state == UNIT_LOADED || m->from_proc_self_mountinfo || u->perpetual)
|
2019-10-11 12:48:33 +02:00
|
|
|
q = mount_add_extras(m);
|
2018-11-28 12:37:43 +01:00
|
|
|
|
2012-06-29 01:47:24 +02:00
|
|
|
if (r < 0)
|
|
|
|
return r;
|
2018-11-28 12:37:43 +01:00
|
|
|
if (q < 0)
|
|
|
|
return q;
|
2019-10-11 12:48:33 +02:00
|
|
|
if (u->load_state != UNIT_LOADED)
|
|
|
|
return 0;
|
2010-04-10 17:53:17 +02:00
|
|
|
|
2010-04-16 23:24:39 +02:00
|
|
|
return mount_verify(m);
|
2010-04-10 17:53:17 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
static void mount_set_state(Mount *m, MountState state) {
|
|
|
|
MountState old_state;
|
|
|
|
assert(m);
|
|
|
|
|
2018-11-27 20:15:45 +01:00
|
|
|
if (m->state != state)
|
|
|
|
bus_unit_send_pending_change_signal(UNIT(m), false);
|
|
|
|
|
2010-04-10 17:53:17 +02:00
|
|
|
old_state = m->state;
|
|
|
|
m->state = state;
|
|
|
|
|
2017-09-25 19:25:50 +02:00
|
|
|
if (!MOUNT_STATE_WITH_PROCESS(state)) {
|
2013-11-19 21:12:59 +01:00
|
|
|
m->timer_event_source = sd_event_source_unref(m->timer_event_source);
|
2010-04-21 03:27:44 +02:00
|
|
|
mount_unwatch_control_pid(m);
|
2010-04-10 17:53:17 +02:00
|
|
|
m->control_command = NULL;
|
2010-04-21 03:27:44 +02:00
|
|
|
m->control_command_id = _MOUNT_EXEC_COMMAND_INVALID;
|
2010-04-10 17:53:17 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
if (state != old_state)
|
core,network: major per-object logging rework
This changes log_unit_info() (and friends) to take a real Unit* object
insted of just a unit name as parameter. The call will now prefix all
logged messages with the unit name, thus allowing the unit name to be
dropped from the various passed romat strings, simplifying invocations
drastically, and unifying log output across messages. Also, UNIT= vs.
USER_UNIT= is now derived from the Manager object attached to the Unit
object, instead of getpid(). This has the benefit of correcting the
field for --test runs.
Also contains a couple of other logging improvements:
- Drops a couple of strerror() invocations in favour of using %m.
- Not only .mount units now warn if a symlinks exist for the mount
point already, .automount units do that too, now.
- A few invocations of log_struct() that didn't actually pass any
additional structured data have been replaced by simpler invocations
of log_unit_info() and friends.
- For structured data a new LOG_UNIT_MESSAGE() macro has been added,
that works like LOG_MESSAGE() but prefixes the message with the unit
name. Similar, there's now LOG_LINK_MESSAGE() and
LOG_NETDEV_MESSAGE().
- For structured data new LOG_UNIT_ID(), LOG_LINK_INTERFACE(),
LOG_NETDEV_INTERFACE() macros have been added that generate the
necessary per object fields. The old log_unit_struct() call has been
removed in favour of these new macros used in raw log_struct()
invocations. In addition to removing one more function call this
allows generated structured log messages that contain two object
fields, as necessary for example for network interfaces that are
joined into another network interface, and whose messages shall be
indexed by both.
- The LOG_ERRNO() macro has been removed, in favour of
log_struct_errno(). The latter has the benefit of ensuring that %m in
format strings is properly resolved to the specified error number.
- A number of logging messages have been converted to use
log_unit_info() instead of log_info()
- The client code in sysv-generator no longer #includes core code from
src/core/.
- log_unit_full_errno() has been removed, log_unit_full() instead takes
an errno now, too.
- log_unit_info(), log_link_info(), log_netdev_info() and friends, now
avoid double evaluation of their parameters
2015-05-11 20:38:21 +02:00
|
|
|
log_unit_debug(UNIT(m), "Changed %s -> %s", mount_state_to_string(old_state), mount_state_to_string(state));
|
2010-04-10 17:53:17 +02:00
|
|
|
|
2018-06-01 19:06:19 +02:00
|
|
|
unit_notify(UNIT(m), state_translation_table[old_state], state_translation_table[state],
|
|
|
|
m->reload_result == MOUNT_SUCCESS ? 0 : UNIT_NOTIFY_RELOAD_FAILURE);
|
2010-04-10 17:53:17 +02:00
|
|
|
}
|
|
|
|
|
2015-04-24 15:27:19 +02:00
|
|
|
static int mount_coldplug(Unit *u) {
|
2010-04-10 17:53:17 +02:00
|
|
|
Mount *m = MOUNT(u);
|
2010-04-21 03:27:44 +02:00
|
|
|
MountState new_state = MOUNT_DEAD;
|
|
|
|
int r;
|
2010-04-10 17:53:17 +02:00
|
|
|
|
|
|
|
assert(m);
|
|
|
|
assert(m->state == MOUNT_DEAD);
|
|
|
|
|
2010-04-21 03:27:44 +02:00
|
|
|
if (m->deserialized_state != m->state)
|
|
|
|
new_state = m->deserialized_state;
|
|
|
|
else if (m->from_proc_self_mountinfo)
|
|
|
|
new_state = MOUNT_MOUNTED;
|
2010-04-10 17:53:17 +02:00
|
|
|
|
2013-11-25 15:26:30 +01:00
|
|
|
if (new_state == m->state)
|
|
|
|
return 0;
|
2010-04-10 17:53:17 +02:00
|
|
|
|
2015-10-27 17:59:45 +01:00
|
|
|
if (m->control_pid > 0 &&
|
|
|
|
pid_is_unwaited(m->control_pid) &&
|
2017-09-25 19:25:50 +02:00
|
|
|
MOUNT_STATE_WITH_PROCESS(new_state)) {
|
2013-11-25 15:26:30 +01:00
|
|
|
|
2019-03-18 20:59:36 +01:00
|
|
|
r = unit_watch_pid(UNIT(m), m->control_pid, false);
|
2013-11-25 15:26:30 +01:00
|
|
|
if (r < 0)
|
|
|
|
return r;
|
2010-04-10 17:53:17 +02:00
|
|
|
|
core: rework unit timeout handling, and add new setting RuntimeMaxSec=
This clean-ups timeout handling in PID 1. Specifically, instead of storing 0 in internal timeout variables as
indication for a disabled timeout, use USEC_INFINITY which is in-line with how we do this in the rest of our code
(following the logic that 0 means "no", and USEC_INFINITY means "never").
This also replace all usec_t additions with invocations to usec_add(), so that USEC_INFINITY is properly propagated,
and sd-event considers it has indication for turning off the event source.
This also alters the deserialization of the units to restart timeouts from the time they were originally started from.
Before this patch timeouts would be restarted beginning with the time of the deserialization, which could lead to
artificially prolonged timeouts if a daemon reload took place.
Finally, a new RuntimeMaxSec= setting is introduced for service units, that specifies a maximum runtime after which a
specific service is forcibly terminated. This is useful to put time limits on time-intensive processing jobs.
This also simplifies the various xyz_spawn() calls of the various types in that explicit distruction of the timers is
removed, as that is done anyway by the state change handlers, and a state change is always done when the xyz_spawn()
calls fail.
Fixes: #2249
2016-02-01 21:48:10 +01:00
|
|
|
r = mount_arm_timer(m, usec_add(u->state_change_timestamp.monotonic, m->timeout_usec));
|
2013-11-25 15:26:30 +01:00
|
|
|
if (r < 0)
|
|
|
|
return r;
|
2010-04-21 03:27:44 +02:00
|
|
|
}
|
2010-04-10 17:53:17 +02:00
|
|
|
|
2018-02-06 08:00:34 +01:00
|
|
|
if (!IN_SET(new_state, MOUNT_DEAD, MOUNT_FAILED)) {
|
2016-07-14 12:37:28 +02:00
|
|
|
(void) unit_setup_dynamic_creds(u);
|
2018-02-06 08:00:34 +01:00
|
|
|
(void) unit_setup_exec_runtime(u);
|
|
|
|
}
|
2016-07-14 12:37:28 +02:00
|
|
|
|
2013-11-25 15:26:30 +01:00
|
|
|
mount_set_state(m, new_state);
|
2010-04-10 17:53:17 +02:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void mount_dump(Unit *u, FILE *f, const char *prefix) {
|
2018-02-09 08:36:37 +01:00
|
|
|
char buf[FORMAT_TIMESPAN_MAX];
|
2010-04-10 17:53:17 +02:00
|
|
|
Mount *m = MOUNT(u);
|
|
|
|
MountParameters *p;
|
|
|
|
|
|
|
|
assert(m);
|
|
|
|
assert(f);
|
|
|
|
|
2011-03-30 01:53:34 +02:00
|
|
|
p = get_mount_parameters(m);
|
2010-04-10 17:53:17 +02:00
|
|
|
|
|
|
|
fprintf(f,
|
|
|
|
"%sMount State: %s\n"
|
2012-02-03 03:27:25 +01:00
|
|
|
"%sResult: %s\n"
|
2019-08-25 15:08:47 +02:00
|
|
|
"%sClean Result: %s\n"
|
2010-04-10 17:53:17 +02:00
|
|
|
"%sWhere: %s\n"
|
|
|
|
"%sWhat: %s\n"
|
|
|
|
"%sFile System Type: %s\n"
|
|
|
|
"%sOptions: %s\n"
|
|
|
|
"%sFrom /proc/self/mountinfo: %s\n"
|
|
|
|
"%sFrom fragment: %s\n"
|
2016-11-29 22:50:21 +01:00
|
|
|
"%sExtrinsic: %s\n"
|
2016-08-26 17:57:22 +02:00
|
|
|
"%sDirectoryMode: %04o\n"
|
2016-08-27 16:42:05 +02:00
|
|
|
"%sSloppyOptions: %s\n"
|
2016-08-27 16:27:49 +02:00
|
|
|
"%sLazyUnmount: %s\n"
|
2018-01-30 09:09:59 +01:00
|
|
|
"%sForceUnmount: %s\n"
|
2020-05-01 10:20:17 +02:00
|
|
|
"%sReadWriteOnly: %s\n"
|
2019-02-12 14:27:04 +01:00
|
|
|
"%sTimeoutSec: %s\n",
|
2010-04-21 03:27:44 +02:00
|
|
|
prefix, mount_state_to_string(m->state),
|
2012-02-03 03:27:25 +01:00
|
|
|
prefix, mount_result_to_string(m->result),
|
2019-08-25 15:08:47 +02:00
|
|
|
prefix, mount_result_to_string(m->clean_result),
|
2010-04-10 17:53:17 +02:00
|
|
|
prefix, m->where,
|
2013-07-04 11:01:47 +02:00
|
|
|
prefix, p ? strna(p->what) : "n/a",
|
|
|
|
prefix, p ? strna(p->fstype) : "n/a",
|
|
|
|
prefix, p ? strna(p->options) : "n/a",
|
2010-04-10 17:53:17 +02:00
|
|
|
prefix, yes_no(m->from_proc_self_mountinfo),
|
|
|
|
prefix, yes_no(m->from_fragment),
|
2020-11-05 13:08:02 +01:00
|
|
|
prefix, yes_no(mount_is_extrinsic(u)),
|
2016-08-26 17:57:22 +02:00
|
|
|
prefix, m->directory_mode,
|
2016-08-27 16:42:05 +02:00
|
|
|
prefix, yes_no(m->sloppy_options),
|
2016-08-27 16:27:49 +02:00
|
|
|
prefix, yes_no(m->lazy_unmount),
|
2018-01-30 09:09:59 +01:00
|
|
|
prefix, yes_no(m->force_unmount),
|
2020-05-01 10:20:17 +02:00
|
|
|
prefix, yes_no(m->read_write_only),
|
2018-01-30 09:09:59 +01:00
|
|
|
prefix, format_timespan(buf, sizeof(buf), m->timeout_usec, USEC_PER_SEC));
|
2010-04-10 17:53:17 +02:00
|
|
|
|
|
|
|
if (m->control_pid > 0)
|
|
|
|
fprintf(f,
|
2013-12-30 23:22:26 +01:00
|
|
|
"%sControl PID: "PID_FMT"\n",
|
|
|
|
prefix, m->control_pid);
|
2010-04-10 17:53:17 +02:00
|
|
|
|
|
|
|
exec_context_dump(&m->exec_context, f, prefix);
|
2012-07-19 23:47:10 +02:00
|
|
|
kill_context_dump(&m->kill_context, f, prefix);
|
2019-10-03 14:21:29 +02:00
|
|
|
cgroup_context_dump(UNIT(m), f, prefix);
|
2010-04-10 17:53:17 +02:00
|
|
|
}
|
|
|
|
|
2010-04-21 03:27:44 +02:00
|
|
|
static int mount_spawn(Mount *m, ExecCommand *c, pid_t *_pid) {
|
2017-11-17 16:43:08 +01:00
|
|
|
|
2018-11-08 06:08:10 +01:00
|
|
|
_cleanup_(exec_params_clear) ExecParameters exec_params = {
|
2018-07-17 11:47:14 +02:00
|
|
|
.flags = EXEC_APPLY_SANDBOXING|EXEC_APPLY_CHROOT|EXEC_APPLY_TTY_STDIN,
|
|
|
|
.stdin_fd = -1,
|
|
|
|
.stdout_fd = -1,
|
|
|
|
.stderr_fd = -1,
|
|
|
|
.exec_fd = -1,
|
2014-08-23 15:28:37 +02:00
|
|
|
};
|
2017-11-17 16:43:08 +01:00
|
|
|
pid_t pid;
|
|
|
|
int r;
|
2010-04-21 03:27:44 +02:00
|
|
|
|
|
|
|
assert(m);
|
|
|
|
assert(c);
|
|
|
|
assert(_pid);
|
|
|
|
|
2017-11-17 16:43:08 +01:00
|
|
|
r = unit_prepare_exec(UNIT(m));
|
2016-07-14 12:37:28 +02:00
|
|
|
if (r < 0)
|
|
|
|
return r;
|
|
|
|
|
core: rework unit timeout handling, and add new setting RuntimeMaxSec=
This clean-ups timeout handling in PID 1. Specifically, instead of storing 0 in internal timeout variables as
indication for a disabled timeout, use USEC_INFINITY which is in-line with how we do this in the rest of our code
(following the logic that 0 means "no", and USEC_INFINITY means "never").
This also replace all usec_t additions with invocations to usec_add(), so that USEC_INFINITY is properly propagated,
and sd-event considers it has indication for turning off the event source.
This also alters the deserialization of the units to restart timeouts from the time they were originally started from.
Before this patch timeouts would be restarted beginning with the time of the deserialization, which could lead to
artificially prolonged timeouts if a daemon reload took place.
Finally, a new RuntimeMaxSec= setting is introduced for service units, that specifies a maximum runtime after which a
specific service is forcibly terminated. This is useful to put time limits on time-intensive processing jobs.
This also simplifies the various xyz_spawn() calls of the various types in that explicit distruction of the timers is
removed, as that is done anyway by the state change handlers, and a state change is always done when the xyz_spawn()
calls fail.
Fixes: #2249
2016-02-01 21:48:10 +01:00
|
|
|
r = mount_arm_timer(m, usec_add(now(CLOCK_MONOTONIC), m->timeout_usec));
|
2012-11-23 21:37:58 +01:00
|
|
|
if (r < 0)
|
core: rework unit timeout handling, and add new setting RuntimeMaxSec=
This clean-ups timeout handling in PID 1. Specifically, instead of storing 0 in internal timeout variables as
indication for a disabled timeout, use USEC_INFINITY which is in-line with how we do this in the rest of our code
(following the logic that 0 means "no", and USEC_INFINITY means "never").
This also replace all usec_t additions with invocations to usec_add(), so that USEC_INFINITY is properly propagated,
and sd-event considers it has indication for turning off the event source.
This also alters the deserialization of the units to restart timeouts from the time they were originally started from.
Before this patch timeouts would be restarted beginning with the time of the deserialization, which could lead to
artificially prolonged timeouts if a daemon reload took place.
Finally, a new RuntimeMaxSec= setting is introduced for service units, that specifies a maximum runtime after which a
specific service is forcibly terminated. This is useful to put time limits on time-intensive processing jobs.
This also simplifies the various xyz_spawn() calls of the various types in that explicit distruction of the timers is
removed, as that is done anyway by the state change handlers, and a state change is always done when the xyz_spawn()
calls fail.
Fixes: #2249
2016-02-01 21:48:10 +01:00
|
|
|
return r;
|
2010-04-21 03:27:44 +02:00
|
|
|
|
2018-10-31 15:49:19 +01:00
|
|
|
r = unit_set_exec_params(UNIT(m), &exec_params);
|
|
|
|
if (r < 0)
|
|
|
|
return r;
|
2014-08-23 15:28:37 +02:00
|
|
|
|
core,network: major per-object logging rework
This changes log_unit_info() (and friends) to take a real Unit* object
insted of just a unit name as parameter. The call will now prefix all
logged messages with the unit name, thus allowing the unit name to be
dropped from the various passed romat strings, simplifying invocations
drastically, and unifying log output across messages. Also, UNIT= vs.
USER_UNIT= is now derived from the Manager object attached to the Unit
object, instead of getpid(). This has the benefit of correcting the
field for --test runs.
Also contains a couple of other logging improvements:
- Drops a couple of strerror() invocations in favour of using %m.
- Not only .mount units now warn if a symlinks exist for the mount
point already, .automount units do that too, now.
- A few invocations of log_struct() that didn't actually pass any
additional structured data have been replaced by simpler invocations
of log_unit_info() and friends.
- For structured data a new LOG_UNIT_MESSAGE() macro has been added,
that works like LOG_MESSAGE() but prefixes the message with the unit
name. Similar, there's now LOG_LINK_MESSAGE() and
LOG_NETDEV_MESSAGE().
- For structured data new LOG_UNIT_ID(), LOG_LINK_INTERFACE(),
LOG_NETDEV_INTERFACE() macros have been added that generate the
necessary per object fields. The old log_unit_struct() call has been
removed in favour of these new macros used in raw log_struct()
invocations. In addition to removing one more function call this
allows generated structured log messages that contain two object
fields, as necessary for example for network interfaces that are
joined into another network interface, and whose messages shall be
indexed by both.
- The LOG_ERRNO() macro has been removed, in favour of
log_struct_errno(). The latter has the benefit of ensuring that %m in
format strings is properly resolved to the specified error number.
- A number of logging messages have been converted to use
log_unit_info() instead of log_info()
- The client code in sysv-generator no longer #includes core code from
src/core/.
- log_unit_full_errno() has been removed, log_unit_full() instead takes
an errno now, too.
- log_unit_info(), log_link_info(), log_netdev_info() and friends, now
avoid double evaluation of their parameters
2015-05-11 20:38:21 +02:00
|
|
|
r = exec_spawn(UNIT(m),
|
|
|
|
c,
|
2013-06-27 04:14:27 +02:00
|
|
|
&m->exec_context,
|
2014-08-23 15:28:37 +02:00
|
|
|
&exec_params,
|
2013-11-27 20:23:18 +01:00
|
|
|
m->exec_runtime,
|
2016-07-14 12:37:28 +02:00
|
|
|
&m->dynamic_creds,
|
2013-06-27 04:14:27 +02:00
|
|
|
&pid);
|
|
|
|
if (r < 0)
|
core: rework unit timeout handling, and add new setting RuntimeMaxSec=
This clean-ups timeout handling in PID 1. Specifically, instead of storing 0 in internal timeout variables as
indication for a disabled timeout, use USEC_INFINITY which is in-line with how we do this in the rest of our code
(following the logic that 0 means "no", and USEC_INFINITY means "never").
This also replace all usec_t additions with invocations to usec_add(), so that USEC_INFINITY is properly propagated,
and sd-event considers it has indication for turning off the event source.
This also alters the deserialization of the units to restart timeouts from the time they were originally started from.
Before this patch timeouts would be restarted beginning with the time of the deserialization, which could lead to
artificially prolonged timeouts if a daemon reload took place.
Finally, a new RuntimeMaxSec= setting is introduced for service units, that specifies a maximum runtime after which a
specific service is forcibly terminated. This is useful to put time limits on time-intensive processing jobs.
This also simplifies the various xyz_spawn() calls of the various types in that explicit distruction of the timers is
removed, as that is done anyway by the state change handlers, and a state change is always done when the xyz_spawn()
calls fail.
Fixes: #2249
2016-02-01 21:48:10 +01:00
|
|
|
return r;
|
2010-04-21 03:27:44 +02:00
|
|
|
|
2019-03-18 20:59:36 +01:00
|
|
|
r = unit_watch_pid(UNIT(m), pid, true);
|
2013-06-27 04:14:27 +02:00
|
|
|
if (r < 0)
|
core: rework unit timeout handling, and add new setting RuntimeMaxSec=
This clean-ups timeout handling in PID 1. Specifically, instead of storing 0 in internal timeout variables as
indication for a disabled timeout, use USEC_INFINITY which is in-line with how we do this in the rest of our code
(following the logic that 0 means "no", and USEC_INFINITY means "never").
This also replace all usec_t additions with invocations to usec_add(), so that USEC_INFINITY is properly propagated,
and sd-event considers it has indication for turning off the event source.
This also alters the deserialization of the units to restart timeouts from the time they were originally started from.
Before this patch timeouts would be restarted beginning with the time of the deserialization, which could lead to
artificially prolonged timeouts if a daemon reload took place.
Finally, a new RuntimeMaxSec= setting is introduced for service units, that specifies a maximum runtime after which a
specific service is forcibly terminated. This is useful to put time limits on time-intensive processing jobs.
This also simplifies the various xyz_spawn() calls of the various types in that explicit distruction of the timers is
removed, as that is done anyway by the state change handlers, and a state change is always done when the xyz_spawn()
calls fail.
Fixes: #2249
2016-02-01 21:48:10 +01:00
|
|
|
return r;
|
2010-04-21 03:27:44 +02:00
|
|
|
|
|
|
|
*_pid = pid;
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2012-02-03 03:10:56 +01:00
|
|
|
static void mount_enter_dead(Mount *m, MountResult f) {
|
2010-04-10 17:53:17 +02:00
|
|
|
assert(m);
|
|
|
|
|
core: remember first unit failure, not last unit failure
Previously, the result value of a unit was overriden with each failure that
took place, so that the result always reported the last failure that took
place.
With this commit this is changed, so that the first failure taking place is
stored instead. This should normally not matter much as multiple failures are
sufficiently uncommon. However, it improves one behaviour: if we send SIGABRT
to a service due to a watchdog timeout, then this currently would be reported
as "coredump" failure, rather than the "watchodg" failure it really is. Hence,
in order to report information about the type of the failure, and not about
the effect of it, let's change this from all unit type to store the first, not
the last failure.
This addresses the issue pointed out here:
https://github.com/systemd/systemd/pull/3818#discussion_r73433520
2016-08-04 21:14:27 +02:00
|
|
|
if (m->result == MOUNT_SUCCESS)
|
2012-02-03 03:10:56 +01:00
|
|
|
m->result = f;
|
2010-04-10 17:53:17 +02:00
|
|
|
|
2018-11-16 10:09:45 +01:00
|
|
|
unit_log_result(UNIT(m), m->result == MOUNT_SUCCESS, mount_result_to_string(m->result));
|
2020-05-26 14:29:46 +02:00
|
|
|
unit_warn_leftover_processes(UNIT(m), unit_log_leftover_process_stop);
|
|
|
|
|
2016-07-14 12:37:28 +02:00
|
|
|
mount_set_state(m, m->result != MOUNT_SUCCESS ? MOUNT_FAILED : MOUNT_DEAD);
|
|
|
|
|
2018-02-06 08:00:34 +01:00
|
|
|
m->exec_runtime = exec_runtime_unref(m->exec_runtime, true);
|
2013-11-27 20:23:18 +01:00
|
|
|
|
2020-07-23 08:49:52 +02:00
|
|
|
unit_destroy_runtime_data(UNIT(m), &m->exec_context);
|
2014-03-03 17:14:07 +01:00
|
|
|
|
2016-08-01 19:24:40 +02:00
|
|
|
unit_unref_uid_gid(UNIT(m), true);
|
|
|
|
|
2016-07-14 12:37:28 +02:00
|
|
|
dynamic_creds_destroy(&m->dynamic_creds);
|
2019-01-17 16:09:13 +01:00
|
|
|
|
|
|
|
/* Any dependencies based on /proc/self/mountinfo are now stale */
|
|
|
|
unit_remove_dependencies(UNIT(m), UNIT_DEPENDENCY_MOUNTINFO_IMPLICIT);
|
2010-04-10 17:53:17 +02:00
|
|
|
}
|
|
|
|
|
2012-02-03 03:10:56 +01:00
|
|
|
static void mount_enter_mounted(Mount *m, MountResult f) {
|
2010-04-13 02:06:27 +02:00
|
|
|
assert(m);
|
|
|
|
|
core: remember first unit failure, not last unit failure
Previously, the result value of a unit was overriden with each failure that
took place, so that the result always reported the last failure that took
place.
With this commit this is changed, so that the first failure taking place is
stored instead. This should normally not matter much as multiple failures are
sufficiently uncommon. However, it improves one behaviour: if we send SIGABRT
to a service due to a watchdog timeout, then this currently would be reported
as "coredump" failure, rather than the "watchodg" failure it really is. Hence,
in order to report information about the type of the failure, and not about
the effect of it, let's change this from all unit type to store the first, not
the last failure.
This addresses the issue pointed out here:
https://github.com/systemd/systemd/pull/3818#discussion_r73433520
2016-08-04 21:14:27 +02:00
|
|
|
if (m->result == MOUNT_SUCCESS)
|
2012-02-03 03:10:56 +01:00
|
|
|
m->result = f;
|
2010-04-13 02:06:27 +02:00
|
|
|
|
|
|
|
mount_set_state(m, MOUNT_MOUNTED);
|
|
|
|
}
|
|
|
|
|
mount: rework mount state engine
This changes the mount unit state engine in the following ways:
1. The MOUNT_MOUNTING_SIGTERM and MOUNT_MOUNTING_SIGKILL are removed.
They have been pretty much equivalent to MOUNT_UNMOUNTING_SIGTERM and
MOUNT_UNMOUNTING_SIGKILL in what they do, and the outcome has been
the same as well: the unit is stopped. Hence, let's simplify things a
bit, and merge them. Note that we keep
MOUNT_REMOUNTING_{SIGTERM|SIGKILL} however, as those states have a
different outcome: the unit remains started.
2. mount_enter_signal() will now honour the SendSIGKILL= option of the
mount unit if it was set. This was previously done already when we
entered the signal states through a timeout, and was simply missing
here.
3. A new helper function mount_enter_dead_or_mounted() is added that
places the mount unit in either MOUNT_DEAD or MOUNT_MOUNTED,
depending on what the kernel thinks about the mount's state. This
function is called at various places now, wherever we finished an
operation, and want to make sure our own state reflects again what
the kernel thinks. Previously we had very similar code in a number of
places and in other places didn't recheck the kernel state. Let's do
that with the same logic and function at all relevant places now.
4. Rework mount_stop(): never forget about running control processes.
Instead: when we have a start (i.e. a /bin/mount) process running,
and are asked to stop, then enter the kill states for it, so that it
gets cleaned up. This fixes #6048. Moreover, when we have a reload
process running convert the possible states into the relevant
unmounting states, so that we can properly execute the requested
operation.
Fixes #6048
2017-09-25 19:13:37 +02:00
|
|
|
static void mount_enter_dead_or_mounted(Mount *m, MountResult f) {
|
|
|
|
assert(m);
|
|
|
|
|
|
|
|
/* Enter DEAD or MOUNTED state, depending on what the kernel currently says about the mount point. We use this
|
|
|
|
* whenever we executed an operation, so that our internal state reflects what the kernel says again, after all
|
|
|
|
* ultimately we just mirror the kernel's internal state on this. */
|
|
|
|
|
|
|
|
if (m->from_proc_self_mountinfo)
|
|
|
|
mount_enter_mounted(m, f);
|
|
|
|
else
|
|
|
|
mount_enter_dead(m, f);
|
|
|
|
}
|
|
|
|
|
|
|
|
static int state_to_kill_operation(MountState state) {
|
|
|
|
switch (state) {
|
|
|
|
|
|
|
|
case MOUNT_REMOUNTING_SIGTERM:
|
2019-10-01 15:15:06 +02:00
|
|
|
return KILL_RESTART;
|
|
|
|
|
mount: rework mount state engine
This changes the mount unit state engine in the following ways:
1. The MOUNT_MOUNTING_SIGTERM and MOUNT_MOUNTING_SIGKILL are removed.
They have been pretty much equivalent to MOUNT_UNMOUNTING_SIGTERM and
MOUNT_UNMOUNTING_SIGKILL in what they do, and the outcome has been
the same as well: the unit is stopped. Hence, let's simplify things a
bit, and merge them. Note that we keep
MOUNT_REMOUNTING_{SIGTERM|SIGKILL} however, as those states have a
different outcome: the unit remains started.
2. mount_enter_signal() will now honour the SendSIGKILL= option of the
mount unit if it was set. This was previously done already when we
entered the signal states through a timeout, and was simply missing
here.
3. A new helper function mount_enter_dead_or_mounted() is added that
places the mount unit in either MOUNT_DEAD or MOUNT_MOUNTED,
depending on what the kernel thinks about the mount's state. This
function is called at various places now, wherever we finished an
operation, and want to make sure our own state reflects again what
the kernel thinks. Previously we had very similar code in a number of
places and in other places didn't recheck the kernel state. Let's do
that with the same logic and function at all relevant places now.
4. Rework mount_stop(): never forget about running control processes.
Instead: when we have a start (i.e. a /bin/mount) process running,
and are asked to stop, then enter the kill states for it, so that it
gets cleaned up. This fixes #6048. Moreover, when we have a reload
process running convert the possible states into the relevant
unmounting states, so that we can properly execute the requested
operation.
Fixes #6048
2017-09-25 19:13:37 +02:00
|
|
|
case MOUNT_UNMOUNTING_SIGTERM:
|
|
|
|
return KILL_TERMINATE;
|
|
|
|
|
|
|
|
case MOUNT_REMOUNTING_SIGKILL:
|
|
|
|
case MOUNT_UNMOUNTING_SIGKILL:
|
|
|
|
return KILL_KILL;
|
|
|
|
|
|
|
|
default:
|
|
|
|
return _KILL_OPERATION_INVALID;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-02-03 03:10:56 +01:00
|
|
|
static void mount_enter_signal(Mount *m, MountState state, MountResult f) {
|
2010-04-10 17:53:17 +02:00
|
|
|
int r;
|
|
|
|
|
|
|
|
assert(m);
|
|
|
|
|
core: remember first unit failure, not last unit failure
Previously, the result value of a unit was overriden with each failure that
took place, so that the result always reported the last failure that took
place.
With this commit this is changed, so that the first failure taking place is
stored instead. This should normally not matter much as multiple failures are
sufficiently uncommon. However, it improves one behaviour: if we send SIGABRT
to a service due to a watchdog timeout, then this currently would be reported
as "coredump" failure, rather than the "watchodg" failure it really is. Hence,
in order to report information about the type of the failure, and not about
the effect of it, let's change this from all unit type to store the first, not
the last failure.
This addresses the issue pointed out here:
https://github.com/systemd/systemd/pull/3818#discussion_r73433520
2016-08-04 21:14:27 +02:00
|
|
|
if (m->result == MOUNT_SUCCESS)
|
2012-02-03 03:10:56 +01:00
|
|
|
m->result = f;
|
2010-04-10 17:53:17 +02:00
|
|
|
|
2013-01-26 05:53:30 +01:00
|
|
|
r = unit_kill_context(
|
|
|
|
UNIT(m),
|
|
|
|
&m->kill_context,
|
mount: rework mount state engine
This changes the mount unit state engine in the following ways:
1. The MOUNT_MOUNTING_SIGTERM and MOUNT_MOUNTING_SIGKILL are removed.
They have been pretty much equivalent to MOUNT_UNMOUNTING_SIGTERM and
MOUNT_UNMOUNTING_SIGKILL in what they do, and the outcome has been
the same as well: the unit is stopped. Hence, let's simplify things a
bit, and merge them. Note that we keep
MOUNT_REMOUNTING_{SIGTERM|SIGKILL} however, as those states have a
different outcome: the unit remains started.
2. mount_enter_signal() will now honour the SendSIGKILL= option of the
mount unit if it was set. This was previously done already when we
entered the signal states through a timeout, and was simply missing
here.
3. A new helper function mount_enter_dead_or_mounted() is added that
places the mount unit in either MOUNT_DEAD or MOUNT_MOUNTED,
depending on what the kernel thinks about the mount's state. This
function is called at various places now, wherever we finished an
operation, and want to make sure our own state reflects again what
the kernel thinks. Previously we had very similar code in a number of
places and in other places didn't recheck the kernel state. Let's do
that with the same logic and function at all relevant places now.
4. Rework mount_stop(): never forget about running control processes.
Instead: when we have a start (i.e. a /bin/mount) process running,
and are asked to stop, then enter the kill states for it, so that it
gets cleaned up. This fixes #6048. Moreover, when we have a reload
process running convert the possible states into the relevant
unmounting states, so that we can properly execute the requested
operation.
Fixes #6048
2017-09-25 19:13:37 +02:00
|
|
|
state_to_kill_operation(state),
|
2013-01-26 05:53:30 +01:00
|
|
|
-1,
|
|
|
|
m->control_pid,
|
|
|
|
false);
|
|
|
|
if (r < 0)
|
|
|
|
goto fail;
|
2010-04-10 17:53:17 +02:00
|
|
|
|
2013-01-26 05:53:30 +01:00
|
|
|
if (r > 0) {
|
core: rework unit timeout handling, and add new setting RuntimeMaxSec=
This clean-ups timeout handling in PID 1. Specifically, instead of storing 0 in internal timeout variables as
indication for a disabled timeout, use USEC_INFINITY which is in-line with how we do this in the rest of our code
(following the logic that 0 means "no", and USEC_INFINITY means "never").
This also replace all usec_t additions with invocations to usec_add(), so that USEC_INFINITY is properly propagated,
and sd-event considers it has indication for turning off the event source.
This also alters the deserialization of the units to restart timeouts from the time they were originally started from.
Before this patch timeouts would be restarted beginning with the time of the deserialization, which could lead to
artificially prolonged timeouts if a daemon reload took place.
Finally, a new RuntimeMaxSec= setting is introduced for service units, that specifies a maximum runtime after which a
specific service is forcibly terminated. This is useful to put time limits on time-intensive processing jobs.
This also simplifies the various xyz_spawn() calls of the various types in that explicit distruction of the timers is
removed, as that is done anyway by the state change handlers, and a state change is always done when the xyz_spawn()
calls fail.
Fixes: #2249
2016-02-01 21:48:10 +01:00
|
|
|
r = mount_arm_timer(m, usec_add(now(CLOCK_MONOTONIC), m->timeout_usec));
|
2012-11-23 21:37:58 +01:00
|
|
|
if (r < 0)
|
2010-04-13 02:06:27 +02:00
|
|
|
goto fail;
|
2010-04-10 17:53:17 +02:00
|
|
|
|
2010-04-13 02:06:27 +02:00
|
|
|
mount_set_state(m, state);
|
mount: rework mount state engine
This changes the mount unit state engine in the following ways:
1. The MOUNT_MOUNTING_SIGTERM and MOUNT_MOUNTING_SIGKILL are removed.
They have been pretty much equivalent to MOUNT_UNMOUNTING_SIGTERM and
MOUNT_UNMOUNTING_SIGKILL in what they do, and the outcome has been
the same as well: the unit is stopped. Hence, let's simplify things a
bit, and merge them. Note that we keep
MOUNT_REMOUNTING_{SIGTERM|SIGKILL} however, as those states have a
different outcome: the unit remains started.
2. mount_enter_signal() will now honour the SendSIGKILL= option of the
mount unit if it was set. This was previously done already when we
entered the signal states through a timeout, and was simply missing
here.
3. A new helper function mount_enter_dead_or_mounted() is added that
places the mount unit in either MOUNT_DEAD or MOUNT_MOUNTED,
depending on what the kernel thinks about the mount's state. This
function is called at various places now, wherever we finished an
operation, and want to make sure our own state reflects again what
the kernel thinks. Previously we had very similar code in a number of
places and in other places didn't recheck the kernel state. Let's do
that with the same logic and function at all relevant places now.
4. Rework mount_stop(): never forget about running control processes.
Instead: when we have a start (i.e. a /bin/mount) process running,
and are asked to stop, then enter the kill states for it, so that it
gets cleaned up. This fixes #6048. Moreover, when we have a reload
process running convert the possible states into the relevant
unmounting states, so that we can properly execute the requested
operation.
Fixes #6048
2017-09-25 19:13:37 +02:00
|
|
|
} else if (state == MOUNT_REMOUNTING_SIGTERM && m->kill_context.send_sigkill)
|
2014-01-29 14:58:04 +01:00
|
|
|
mount_enter_signal(m, MOUNT_REMOUNTING_SIGKILL, MOUNT_SUCCESS);
|
mount: rework mount state engine
This changes the mount unit state engine in the following ways:
1. The MOUNT_MOUNTING_SIGTERM and MOUNT_MOUNTING_SIGKILL are removed.
They have been pretty much equivalent to MOUNT_UNMOUNTING_SIGTERM and
MOUNT_UNMOUNTING_SIGKILL in what they do, and the outcome has been
the same as well: the unit is stopped. Hence, let's simplify things a
bit, and merge them. Note that we keep
MOUNT_REMOUNTING_{SIGTERM|SIGKILL} however, as those states have a
different outcome: the unit remains started.
2. mount_enter_signal() will now honour the SendSIGKILL= option of the
mount unit if it was set. This was previously done already when we
entered the signal states through a timeout, and was simply missing
here.
3. A new helper function mount_enter_dead_or_mounted() is added that
places the mount unit in either MOUNT_DEAD or MOUNT_MOUNTED,
depending on what the kernel thinks about the mount's state. This
function is called at various places now, wherever we finished an
operation, and want to make sure our own state reflects again what
the kernel thinks. Previously we had very similar code in a number of
places and in other places didn't recheck the kernel state. Let's do
that with the same logic and function at all relevant places now.
4. Rework mount_stop(): never forget about running control processes.
Instead: when we have a start (i.e. a /bin/mount) process running,
and are asked to stop, then enter the kill states for it, so that it
gets cleaned up. This fixes #6048. Moreover, when we have a reload
process running convert the possible states into the relevant
unmounting states, so that we can properly execute the requested
operation.
Fixes #6048
2017-09-25 19:13:37 +02:00
|
|
|
else if (IN_SET(state, MOUNT_REMOUNTING_SIGTERM, MOUNT_REMOUNTING_SIGKILL))
|
2012-02-03 03:10:56 +01:00
|
|
|
mount_enter_mounted(m, MOUNT_SUCCESS);
|
mount: rework mount state engine
This changes the mount unit state engine in the following ways:
1. The MOUNT_MOUNTING_SIGTERM and MOUNT_MOUNTING_SIGKILL are removed.
They have been pretty much equivalent to MOUNT_UNMOUNTING_SIGTERM and
MOUNT_UNMOUNTING_SIGKILL in what they do, and the outcome has been
the same as well: the unit is stopped. Hence, let's simplify things a
bit, and merge them. Note that we keep
MOUNT_REMOUNTING_{SIGTERM|SIGKILL} however, as those states have a
different outcome: the unit remains started.
2. mount_enter_signal() will now honour the SendSIGKILL= option of the
mount unit if it was set. This was previously done already when we
entered the signal states through a timeout, and was simply missing
here.
3. A new helper function mount_enter_dead_or_mounted() is added that
places the mount unit in either MOUNT_DEAD or MOUNT_MOUNTED,
depending on what the kernel thinks about the mount's state. This
function is called at various places now, wherever we finished an
operation, and want to make sure our own state reflects again what
the kernel thinks. Previously we had very similar code in a number of
places and in other places didn't recheck the kernel state. Let's do
that with the same logic and function at all relevant places now.
4. Rework mount_stop(): never forget about running control processes.
Instead: when we have a start (i.e. a /bin/mount) process running,
and are asked to stop, then enter the kill states for it, so that it
gets cleaned up. This fixes #6048. Moreover, when we have a reload
process running convert the possible states into the relevant
unmounting states, so that we can properly execute the requested
operation.
Fixes #6048
2017-09-25 19:13:37 +02:00
|
|
|
else if (state == MOUNT_UNMOUNTING_SIGTERM && m->kill_context.send_sigkill)
|
2014-01-29 14:58:04 +01:00
|
|
|
mount_enter_signal(m, MOUNT_UNMOUNTING_SIGKILL, MOUNT_SUCCESS);
|
2010-04-13 02:06:27 +02:00
|
|
|
else
|
mount: rework mount state engine
This changes the mount unit state engine in the following ways:
1. The MOUNT_MOUNTING_SIGTERM and MOUNT_MOUNTING_SIGKILL are removed.
They have been pretty much equivalent to MOUNT_UNMOUNTING_SIGTERM and
MOUNT_UNMOUNTING_SIGKILL in what they do, and the outcome has been
the same as well: the unit is stopped. Hence, let's simplify things a
bit, and merge them. Note that we keep
MOUNT_REMOUNTING_{SIGTERM|SIGKILL} however, as those states have a
different outcome: the unit remains started.
2. mount_enter_signal() will now honour the SendSIGKILL= option of the
mount unit if it was set. This was previously done already when we
entered the signal states through a timeout, and was simply missing
here.
3. A new helper function mount_enter_dead_or_mounted() is added that
places the mount unit in either MOUNT_DEAD or MOUNT_MOUNTED,
depending on what the kernel thinks about the mount's state. This
function is called at various places now, wherever we finished an
operation, and want to make sure our own state reflects again what
the kernel thinks. Previously we had very similar code in a number of
places and in other places didn't recheck the kernel state. Let's do
that with the same logic and function at all relevant places now.
4. Rework mount_stop(): never forget about running control processes.
Instead: when we have a start (i.e. a /bin/mount) process running,
and are asked to stop, then enter the kill states for it, so that it
gets cleaned up. This fixes #6048. Moreover, when we have a reload
process running convert the possible states into the relevant
unmounting states, so that we can properly execute the requested
operation.
Fixes #6048
2017-09-25 19:13:37 +02:00
|
|
|
mount_enter_dead_or_mounted(m, MOUNT_SUCCESS);
|
2010-04-10 17:53:17 +02:00
|
|
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
fail:
|
core,network: major per-object logging rework
This changes log_unit_info() (and friends) to take a real Unit* object
insted of just a unit name as parameter. The call will now prefix all
logged messages with the unit name, thus allowing the unit name to be
dropped from the various passed romat strings, simplifying invocations
drastically, and unifying log output across messages. Also, UNIT= vs.
USER_UNIT= is now derived from the Manager object attached to the Unit
object, instead of getpid(). This has the benefit of correcting the
field for --test runs.
Also contains a couple of other logging improvements:
- Drops a couple of strerror() invocations in favour of using %m.
- Not only .mount units now warn if a symlinks exist for the mount
point already, .automount units do that too, now.
- A few invocations of log_struct() that didn't actually pass any
additional structured data have been replaced by simpler invocations
of log_unit_info() and friends.
- For structured data a new LOG_UNIT_MESSAGE() macro has been added,
that works like LOG_MESSAGE() but prefixes the message with the unit
name. Similar, there's now LOG_LINK_MESSAGE() and
LOG_NETDEV_MESSAGE().
- For structured data new LOG_UNIT_ID(), LOG_LINK_INTERFACE(),
LOG_NETDEV_INTERFACE() macros have been added that generate the
necessary per object fields. The old log_unit_struct() call has been
removed in favour of these new macros used in raw log_struct()
invocations. In addition to removing one more function call this
allows generated structured log messages that contain two object
fields, as necessary for example for network interfaces that are
joined into another network interface, and whose messages shall be
indexed by both.
- The LOG_ERRNO() macro has been removed, in favour of
log_struct_errno(). The latter has the benefit of ensuring that %m in
format strings is properly resolved to the specified error number.
- A number of logging messages have been converted to use
log_unit_info() instead of log_info()
- The client code in sysv-generator no longer #includes core code from
src/core/.
- log_unit_full_errno() has been removed, log_unit_full() instead takes
an errno now, too.
- log_unit_info(), log_link_info(), log_netdev_info() and friends, now
avoid double evaluation of their parameters
2015-05-11 20:38:21 +02:00
|
|
|
log_unit_warning_errno(UNIT(m), r, "Failed to kill processes: %m");
|
mount: rework mount state engine
This changes the mount unit state engine in the following ways:
1. The MOUNT_MOUNTING_SIGTERM and MOUNT_MOUNTING_SIGKILL are removed.
They have been pretty much equivalent to MOUNT_UNMOUNTING_SIGTERM and
MOUNT_UNMOUNTING_SIGKILL in what they do, and the outcome has been
the same as well: the unit is stopped. Hence, let's simplify things a
bit, and merge them. Note that we keep
MOUNT_REMOUNTING_{SIGTERM|SIGKILL} however, as those states have a
different outcome: the unit remains started.
2. mount_enter_signal() will now honour the SendSIGKILL= option of the
mount unit if it was set. This was previously done already when we
entered the signal states through a timeout, and was simply missing
here.
3. A new helper function mount_enter_dead_or_mounted() is added that
places the mount unit in either MOUNT_DEAD or MOUNT_MOUNTED,
depending on what the kernel thinks about the mount's state. This
function is called at various places now, wherever we finished an
operation, and want to make sure our own state reflects again what
the kernel thinks. Previously we had very similar code in a number of
places and in other places didn't recheck the kernel state. Let's do
that with the same logic and function at all relevant places now.
4. Rework mount_stop(): never forget about running control processes.
Instead: when we have a start (i.e. a /bin/mount) process running,
and are asked to stop, then enter the kill states for it, so that it
gets cleaned up. This fixes #6048. Moreover, when we have a reload
process running convert the possible states into the relevant
unmounting states, so that we can properly execute the requested
operation.
Fixes #6048
2017-09-25 19:13:37 +02:00
|
|
|
mount_enter_dead_or_mounted(m, MOUNT_FAILURE_RESOURCES);
|
2014-08-15 01:05:47 +02:00
|
|
|
}
|
|
|
|
|
2012-02-03 03:10:56 +01:00
|
|
|
static void mount_enter_unmounting(Mount *m) {
|
2010-04-10 17:53:17 +02:00
|
|
|
int r;
|
|
|
|
|
|
|
|
assert(m);
|
|
|
|
|
2014-12-12 20:12:35 +01:00
|
|
|
/* Start counting our attempts */
|
|
|
|
if (!IN_SET(m->state,
|
|
|
|
MOUNT_UNMOUNTING,
|
|
|
|
MOUNT_UNMOUNTING_SIGTERM,
|
|
|
|
MOUNT_UNMOUNTING_SIGKILL))
|
|
|
|
m->n_retry_umount = 0;
|
|
|
|
|
2010-04-21 03:27:44 +02:00
|
|
|
m->control_command_id = MOUNT_EXEC_UNMOUNT;
|
|
|
|
m->control_command = m->exec_command + MOUNT_EXEC_UNMOUNT;
|
2010-04-10 17:53:17 +02:00
|
|
|
|
2017-06-07 14:28:23 +02:00
|
|
|
r = exec_command_set(m->control_command, UMOUNT_PATH, m->where, "-c", NULL);
|
2016-08-26 17:57:22 +02:00
|
|
|
if (r >= 0 && m->lazy_unmount)
|
|
|
|
r = exec_command_append(m->control_command, "-l", NULL);
|
2016-08-27 16:27:49 +02:00
|
|
|
if (r >= 0 && m->force_unmount)
|
|
|
|
r = exec_command_append(m->control_command, "-f", NULL);
|
2014-12-12 20:12:35 +01:00
|
|
|
if (r < 0)
|
2010-04-10 17:53:17 +02:00
|
|
|
goto fail;
|
|
|
|
|
2010-04-21 03:27:44 +02:00
|
|
|
mount_unwatch_control_pid(m);
|
2010-04-11 00:22:36 +02:00
|
|
|
|
2014-12-12 20:12:35 +01:00
|
|
|
r = mount_spawn(m, m->control_command, &m->control_pid);
|
|
|
|
if (r < 0)
|
2010-04-10 17:53:17 +02:00
|
|
|
goto fail;
|
|
|
|
|
|
|
|
mount_set_state(m, MOUNT_UNMOUNTING);
|
|
|
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
fail:
|
core,network: major per-object logging rework
This changes log_unit_info() (and friends) to take a real Unit* object
insted of just a unit name as parameter. The call will now prefix all
logged messages with the unit name, thus allowing the unit name to be
dropped from the various passed romat strings, simplifying invocations
drastically, and unifying log output across messages. Also, UNIT= vs.
USER_UNIT= is now derived from the Manager object attached to the Unit
object, instead of getpid(). This has the benefit of correcting the
field for --test runs.
Also contains a couple of other logging improvements:
- Drops a couple of strerror() invocations in favour of using %m.
- Not only .mount units now warn if a symlinks exist for the mount
point already, .automount units do that too, now.
- A few invocations of log_struct() that didn't actually pass any
additional structured data have been replaced by simpler invocations
of log_unit_info() and friends.
- For structured data a new LOG_UNIT_MESSAGE() macro has been added,
that works like LOG_MESSAGE() but prefixes the message with the unit
name. Similar, there's now LOG_LINK_MESSAGE() and
LOG_NETDEV_MESSAGE().
- For structured data new LOG_UNIT_ID(), LOG_LINK_INTERFACE(),
LOG_NETDEV_INTERFACE() macros have been added that generate the
necessary per object fields. The old log_unit_struct() call has been
removed in favour of these new macros used in raw log_struct()
invocations. In addition to removing one more function call this
allows generated structured log messages that contain two object
fields, as necessary for example for network interfaces that are
joined into another network interface, and whose messages shall be
indexed by both.
- The LOG_ERRNO() macro has been removed, in favour of
log_struct_errno(). The latter has the benefit of ensuring that %m in
format strings is properly resolved to the specified error number.
- A number of logging messages have been converted to use
log_unit_info() instead of log_info()
- The client code in sysv-generator no longer #includes core code from
src/core/.
- log_unit_full_errno() has been removed, log_unit_full() instead takes
an errno now, too.
- log_unit_info(), log_link_info(), log_netdev_info() and friends, now
avoid double evaluation of their parameters
2015-05-11 20:38:21 +02:00
|
|
|
log_unit_warning_errno(UNIT(m), r, "Failed to run 'umount' task: %m");
|
mount: rework mount state engine
This changes the mount unit state engine in the following ways:
1. The MOUNT_MOUNTING_SIGTERM and MOUNT_MOUNTING_SIGKILL are removed.
They have been pretty much equivalent to MOUNT_UNMOUNTING_SIGTERM and
MOUNT_UNMOUNTING_SIGKILL in what they do, and the outcome has been
the same as well: the unit is stopped. Hence, let's simplify things a
bit, and merge them. Note that we keep
MOUNT_REMOUNTING_{SIGTERM|SIGKILL} however, as those states have a
different outcome: the unit remains started.
2. mount_enter_signal() will now honour the SendSIGKILL= option of the
mount unit if it was set. This was previously done already when we
entered the signal states through a timeout, and was simply missing
here.
3. A new helper function mount_enter_dead_or_mounted() is added that
places the mount unit in either MOUNT_DEAD or MOUNT_MOUNTED,
depending on what the kernel thinks about the mount's state. This
function is called at various places now, wherever we finished an
operation, and want to make sure our own state reflects again what
the kernel thinks. Previously we had very similar code in a number of
places and in other places didn't recheck the kernel state. Let's do
that with the same logic and function at all relevant places now.
4. Rework mount_stop(): never forget about running control processes.
Instead: when we have a start (i.e. a /bin/mount) process running,
and are asked to stop, then enter the kill states for it, so that it
gets cleaned up. This fixes #6048. Moreover, when we have a reload
process running convert the possible states into the relevant
unmounting states, so that we can properly execute the requested
operation.
Fixes #6048
2017-09-25 19:13:37 +02:00
|
|
|
mount_enter_dead_or_mounted(m, MOUNT_FAILURE_RESOURCES);
|
2010-04-10 17:53:17 +02:00
|
|
|
}
|
|
|
|
|
2010-04-16 23:24:39 +02:00
|
|
|
static void mount_enter_mounting(Mount *m) {
|
2010-04-10 17:53:17 +02:00
|
|
|
int r;
|
2011-03-30 01:53:34 +02:00
|
|
|
MountParameters *p;
|
2010-04-10 17:53:17 +02:00
|
|
|
|
|
|
|
assert(m);
|
|
|
|
|
2018-01-19 18:28:38 +01:00
|
|
|
r = unit_fail_if_noncanonical(UNIT(m), m->where);
|
core,network: major per-object logging rework
This changes log_unit_info() (and friends) to take a real Unit* object
insted of just a unit name as parameter. The call will now prefix all
logged messages with the unit name, thus allowing the unit name to be
dropped from the various passed romat strings, simplifying invocations
drastically, and unifying log output across messages. Also, UNIT= vs.
USER_UNIT= is now derived from the Manager object attached to the Unit
object, instead of getpid(). This has the benefit of correcting the
field for --test runs.
Also contains a couple of other logging improvements:
- Drops a couple of strerror() invocations in favour of using %m.
- Not only .mount units now warn if a symlinks exist for the mount
point already, .automount units do that too, now.
- A few invocations of log_struct() that didn't actually pass any
additional structured data have been replaced by simpler invocations
of log_unit_info() and friends.
- For structured data a new LOG_UNIT_MESSAGE() macro has been added,
that works like LOG_MESSAGE() but prefixes the message with the unit
name. Similar, there's now LOG_LINK_MESSAGE() and
LOG_NETDEV_MESSAGE().
- For structured data new LOG_UNIT_ID(), LOG_LINK_INTERFACE(),
LOG_NETDEV_INTERFACE() macros have been added that generate the
necessary per object fields. The old log_unit_struct() call has been
removed in favour of these new macros used in raw log_struct()
invocations. In addition to removing one more function call this
allows generated structured log messages that contain two object
fields, as necessary for example for network interfaces that are
joined into another network interface, and whose messages shall be
indexed by both.
- The LOG_ERRNO() macro has been removed, in favour of
log_struct_errno(). The latter has the benefit of ensuring that %m in
format strings is properly resolved to the specified error number.
- A number of logging messages have been converted to use
log_unit_info() instead of log_info()
- The client code in sysv-generator no longer #includes core code from
src/core/.
- log_unit_full_errno() has been removed, log_unit_full() instead takes
an errno now, too.
- log_unit_info(), log_link_info(), log_netdev_info() and friends, now
avoid double evaluation of their parameters
2015-05-11 20:38:21 +02:00
|
|
|
if (r < 0)
|
|
|
|
goto fail;
|
|
|
|
|
|
|
|
(void) mkdir_p_label(m->where, m->directory_mode);
|
2010-07-02 00:28:44 +02:00
|
|
|
|
core,network: major per-object logging rework
This changes log_unit_info() (and friends) to take a real Unit* object
insted of just a unit name as parameter. The call will now prefix all
logged messages with the unit name, thus allowing the unit name to be
dropped from the various passed romat strings, simplifying invocations
drastically, and unifying log output across messages. Also, UNIT= vs.
USER_UNIT= is now derived from the Manager object attached to the Unit
object, instead of getpid(). This has the benefit of correcting the
field for --test runs.
Also contains a couple of other logging improvements:
- Drops a couple of strerror() invocations in favour of using %m.
- Not only .mount units now warn if a symlinks exist for the mount
point already, .automount units do that too, now.
- A few invocations of log_struct() that didn't actually pass any
additional structured data have been replaced by simpler invocations
of log_unit_info() and friends.
- For structured data a new LOG_UNIT_MESSAGE() macro has been added,
that works like LOG_MESSAGE() but prefixes the message with the unit
name. Similar, there's now LOG_LINK_MESSAGE() and
LOG_NETDEV_MESSAGE().
- For structured data new LOG_UNIT_ID(), LOG_LINK_INTERFACE(),
LOG_NETDEV_INTERFACE() macros have been added that generate the
necessary per object fields. The old log_unit_struct() call has been
removed in favour of these new macros used in raw log_struct()
invocations. In addition to removing one more function call this
allows generated structured log messages that contain two object
fields, as necessary for example for network interfaces that are
joined into another network interface, and whose messages shall be
indexed by both.
- The LOG_ERRNO() macro has been removed, in favour of
log_struct_errno(). The latter has the benefit of ensuring that %m in
format strings is properly resolved to the specified error number.
- A number of logging messages have been converted to use
log_unit_info() instead of log_info()
- The client code in sysv-generator no longer #includes core code from
src/core/.
- log_unit_full_errno() has been removed, log_unit_full() instead takes
an errno now, too.
- log_unit_info(), log_link_info(), log_netdev_info() and friends, now
avoid double evaluation of their parameters
2015-05-11 20:38:21 +02:00
|
|
|
unit_warn_if_dir_nonempty(UNIT(m), m->where);
|
2020-05-26 14:29:46 +02:00
|
|
|
unit_warn_leftover_processes(UNIT(m), unit_log_leftover_process_start);
|
2017-11-24 22:02:22 +01:00
|
|
|
|
|
|
|
m->control_command_id = MOUNT_EXEC_MOUNT;
|
|
|
|
m->control_command = m->exec_command + MOUNT_EXEC_MOUNT;
|
|
|
|
|
2011-03-30 01:53:34 +02:00
|
|
|
/* Create the source directory for bind-mounts if needed */
|
2012-05-22 19:23:33 +02:00
|
|
|
p = get_mount_parameters_fragment(m);
|
2020-06-26 07:37:39 +02:00
|
|
|
if (p && mount_is_bind(p)) {
|
|
|
|
r = mkdir_p_label(p->what, m->directory_mode);
|
|
|
|
if (r < 0)
|
|
|
|
log_unit_error_errno(UNIT(m), r, "Failed to make bind mount source '%s': %m", p->what);
|
|
|
|
}
|
2014-08-15 01:05:47 +02:00
|
|
|
|
2015-12-09 16:02:10 +01:00
|
|
|
if (p) {
|
core/mount: filter out noauto,auto,nofail,fail options
We passed the full option string from fstab to /bin/mount. It would in
turn pass the full option string to its helper, if it needed to invoke
one. Some helpers would ignore things like "nofail", but others would
be confused. We could try to get all helpers to ignore those
"meta-options", but it seems better to simply filter them out.
In our model, /bin/mount simply has no business in knowing whether the
mount was configured as fail or nofail, auto or noauto, in the
fstab. If systemd tells invokes a command to mount something, and it
fails, it should always return an error. It seems cleaner to filter
out the option, since then there's no doubt how the command should
behave.
https://bugzilla.redhat.com/show_bug.cgi?id=1177823
2015-01-11 06:27:37 +01:00
|
|
|
_cleanup_free_ char *opts = NULL;
|
|
|
|
|
2015-12-09 16:02:10 +01:00
|
|
|
r = fstab_filter_options(p->options, "nofail\0" "noauto\0" "auto\0", NULL, NULL, &opts);
|
core/mount: filter out noauto,auto,nofail,fail options
We passed the full option string from fstab to /bin/mount. It would in
turn pass the full option string to its helper, if it needed to invoke
one. Some helpers would ignore things like "nofail", but others would
be confused. We could try to get all helpers to ignore those
"meta-options", but it seems better to simply filter them out.
In our model, /bin/mount simply has no business in knowing whether the
mount was configured as fail or nofail, auto or noauto, in the
fstab. If systemd tells invokes a command to mount something, and it
fails, it should always return an error. It seems cleaner to filter
out the option, since then there's no doubt how the command should
behave.
https://bugzilla.redhat.com/show_bug.cgi?id=1177823
2015-01-11 06:27:37 +01:00
|
|
|
if (r < 0)
|
|
|
|
goto fail;
|
|
|
|
|
2015-12-09 16:02:10 +01:00
|
|
|
r = exec_command_set(m->control_command, MOUNT_PATH, p->what, m->where, NULL);
|
2015-01-01 20:25:18 +01:00
|
|
|
if (r >= 0 && m->sloppy_options)
|
|
|
|
r = exec_command_append(m->control_command, "-s", NULL);
|
2020-05-01 10:20:17 +02:00
|
|
|
if (r >= 0 && m->read_write_only)
|
|
|
|
r = exec_command_append(m->control_command, "-w", NULL);
|
2015-12-09 16:02:10 +01:00
|
|
|
if (r >= 0 && p->fstype)
|
|
|
|
r = exec_command_append(m->control_command, "-t", p->fstype, NULL);
|
2015-01-12 13:46:39 +01:00
|
|
|
if (r >= 0 && !isempty(opts))
|
core/mount: filter out noauto,auto,nofail,fail options
We passed the full option string from fstab to /bin/mount. It would in
turn pass the full option string to its helper, if it needed to invoke
one. Some helpers would ignore things like "nofail", but others would
be confused. We could try to get all helpers to ignore those
"meta-options", but it seems better to simply filter them out.
In our model, /bin/mount simply has no business in knowing whether the
mount was configured as fail or nofail, auto or noauto, in the
fstab. If systemd tells invokes a command to mount something, and it
fails, it should always return an error. It seems cleaner to filter
out the option, since then there's no doubt how the command should
behave.
https://bugzilla.redhat.com/show_bug.cgi?id=1177823
2015-01-11 06:27:37 +01:00
|
|
|
r = exec_command_append(m->control_command, "-o", opts, NULL);
|
2015-01-01 20:25:18 +01:00
|
|
|
} else
|
2010-04-10 17:53:17 +02:00
|
|
|
r = -ENOENT;
|
|
|
|
if (r < 0)
|
|
|
|
goto fail;
|
|
|
|
|
2010-04-21 03:27:44 +02:00
|
|
|
mount_unwatch_control_pid(m);
|
2010-04-11 00:22:36 +02:00
|
|
|
|
2012-09-18 18:40:31 +02:00
|
|
|
r = mount_spawn(m, m->control_command, &m->control_pid);
|
|
|
|
if (r < 0)
|
2010-04-10 17:53:17 +02:00
|
|
|
goto fail;
|
|
|
|
|
|
|
|
mount_set_state(m, MOUNT_MOUNTING);
|
|
|
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
fail:
|
core,network: major per-object logging rework
This changes log_unit_info() (and friends) to take a real Unit* object
insted of just a unit name as parameter. The call will now prefix all
logged messages with the unit name, thus allowing the unit name to be
dropped from the various passed romat strings, simplifying invocations
drastically, and unifying log output across messages. Also, UNIT= vs.
USER_UNIT= is now derived from the Manager object attached to the Unit
object, instead of getpid(). This has the benefit of correcting the
field for --test runs.
Also contains a couple of other logging improvements:
- Drops a couple of strerror() invocations in favour of using %m.
- Not only .mount units now warn if a symlinks exist for the mount
point already, .automount units do that too, now.
- A few invocations of log_struct() that didn't actually pass any
additional structured data have been replaced by simpler invocations
of log_unit_info() and friends.
- For structured data a new LOG_UNIT_MESSAGE() macro has been added,
that works like LOG_MESSAGE() but prefixes the message with the unit
name. Similar, there's now LOG_LINK_MESSAGE() and
LOG_NETDEV_MESSAGE().
- For structured data new LOG_UNIT_ID(), LOG_LINK_INTERFACE(),
LOG_NETDEV_INTERFACE() macros have been added that generate the
necessary per object fields. The old log_unit_struct() call has been
removed in favour of these new macros used in raw log_struct()
invocations. In addition to removing one more function call this
allows generated structured log messages that contain two object
fields, as necessary for example for network interfaces that are
joined into another network interface, and whose messages shall be
indexed by both.
- The LOG_ERRNO() macro has been removed, in favour of
log_struct_errno(). The latter has the benefit of ensuring that %m in
format strings is properly resolved to the specified error number.
- A number of logging messages have been converted to use
log_unit_info() instead of log_info()
- The client code in sysv-generator no longer #includes core code from
src/core/.
- log_unit_full_errno() has been removed, log_unit_full() instead takes
an errno now, too.
- log_unit_info(), log_link_info(), log_netdev_info() and friends, now
avoid double evaluation of their parameters
2015-05-11 20:38:21 +02:00
|
|
|
log_unit_warning_errno(UNIT(m), r, "Failed to run 'mount' task: %m");
|
mount: rework mount state engine
This changes the mount unit state engine in the following ways:
1. The MOUNT_MOUNTING_SIGTERM and MOUNT_MOUNTING_SIGKILL are removed.
They have been pretty much equivalent to MOUNT_UNMOUNTING_SIGTERM and
MOUNT_UNMOUNTING_SIGKILL in what they do, and the outcome has been
the same as well: the unit is stopped. Hence, let's simplify things a
bit, and merge them. Note that we keep
MOUNT_REMOUNTING_{SIGTERM|SIGKILL} however, as those states have a
different outcome: the unit remains started.
2. mount_enter_signal() will now honour the SendSIGKILL= option of the
mount unit if it was set. This was previously done already when we
entered the signal states through a timeout, and was simply missing
here.
3. A new helper function mount_enter_dead_or_mounted() is added that
places the mount unit in either MOUNT_DEAD or MOUNT_MOUNTED,
depending on what the kernel thinks about the mount's state. This
function is called at various places now, wherever we finished an
operation, and want to make sure our own state reflects again what
the kernel thinks. Previously we had very similar code in a number of
places and in other places didn't recheck the kernel state. Let's do
that with the same logic and function at all relevant places now.
4. Rework mount_stop(): never forget about running control processes.
Instead: when we have a start (i.e. a /bin/mount) process running,
and are asked to stop, then enter the kill states for it, so that it
gets cleaned up. This fixes #6048. Moreover, when we have a reload
process running convert the possible states into the relevant
unmounting states, so that we can properly execute the requested
operation.
Fixes #6048
2017-09-25 19:13:37 +02:00
|
|
|
mount_enter_dead_or_mounted(m, MOUNT_FAILURE_RESOURCES);
|
2010-04-10 17:53:17 +02:00
|
|
|
}
|
|
|
|
|
2017-09-25 18:56:19 +02:00
|
|
|
static void mount_set_reload_result(Mount *m, MountResult result) {
|
|
|
|
assert(m);
|
|
|
|
|
|
|
|
/* Only store the first error we encounter */
|
|
|
|
if (m->reload_result != MOUNT_SUCCESS)
|
|
|
|
return;
|
|
|
|
|
|
|
|
m->reload_result = result;
|
|
|
|
}
|
|
|
|
|
2012-02-03 03:10:56 +01:00
|
|
|
static void mount_enter_remounting(Mount *m) {
|
2010-04-10 17:53:17 +02:00
|
|
|
int r;
|
2015-12-09 16:02:10 +01:00
|
|
|
MountParameters *p;
|
2010-04-10 17:53:17 +02:00
|
|
|
|
|
|
|
assert(m);
|
|
|
|
|
2017-09-25 18:56:19 +02:00
|
|
|
/* Reset reload result when we are about to start a new remount operation */
|
|
|
|
m->reload_result = MOUNT_SUCCESS;
|
|
|
|
|
2010-04-21 03:27:44 +02:00
|
|
|
m->control_command_id = MOUNT_EXEC_REMOUNT;
|
|
|
|
m->control_command = m->exec_command + MOUNT_EXEC_REMOUNT;
|
2010-04-10 17:53:17 +02:00
|
|
|
|
2015-12-09 16:02:10 +01:00
|
|
|
p = get_mount_parameters_fragment(m);
|
|
|
|
if (p) {
|
2010-04-10 17:53:17 +02:00
|
|
|
const char *o;
|
|
|
|
|
2015-12-09 16:02:10 +01:00
|
|
|
if (p->options)
|
|
|
|
o = strjoina("remount,", p->options);
|
2013-11-19 21:12:59 +01:00
|
|
|
else
|
2010-04-10 17:53:17 +02:00
|
|
|
o = "remount";
|
|
|
|
|
2015-05-13 15:43:04 +02:00
|
|
|
r = exec_command_set(m->control_command, MOUNT_PATH,
|
2015-12-09 16:02:10 +01:00
|
|
|
p->what, m->where,
|
2015-01-01 20:25:18 +01:00
|
|
|
"-o", o, NULL);
|
|
|
|
if (r >= 0 && m->sloppy_options)
|
|
|
|
r = exec_command_append(m->control_command, "-s", NULL);
|
2020-05-01 10:20:17 +02:00
|
|
|
if (r >= 0 && m->read_write_only)
|
|
|
|
r = exec_command_append(m->control_command, "-w", NULL);
|
2015-12-09 16:02:10 +01:00
|
|
|
if (r >= 0 && p->fstype)
|
|
|
|
r = exec_command_append(m->control_command, "-t", p->fstype, NULL);
|
2012-05-22 19:23:33 +02:00
|
|
|
} else
|
2010-04-10 17:53:17 +02:00
|
|
|
r = -ENOENT;
|
2010-10-12 04:06:21 +02:00
|
|
|
if (r < 0)
|
2010-04-10 17:53:17 +02:00
|
|
|
goto fail;
|
|
|
|
|
2010-04-21 03:27:44 +02:00
|
|
|
mount_unwatch_control_pid(m);
|
2010-04-11 00:22:36 +02:00
|
|
|
|
2013-11-19 21:12:59 +01:00
|
|
|
r = mount_spawn(m, m->control_command, &m->control_pid);
|
|
|
|
if (r < 0)
|
2010-04-10 17:53:17 +02:00
|
|
|
goto fail;
|
|
|
|
|
|
|
|
mount_set_state(m, MOUNT_REMOUNTING);
|
|
|
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
fail:
|
core,network: major per-object logging rework
This changes log_unit_info() (and friends) to take a real Unit* object
insted of just a unit name as parameter. The call will now prefix all
logged messages with the unit name, thus allowing the unit name to be
dropped from the various passed romat strings, simplifying invocations
drastically, and unifying log output across messages. Also, UNIT= vs.
USER_UNIT= is now derived from the Manager object attached to the Unit
object, instead of getpid(). This has the benefit of correcting the
field for --test runs.
Also contains a couple of other logging improvements:
- Drops a couple of strerror() invocations in favour of using %m.
- Not only .mount units now warn if a symlinks exist for the mount
point already, .automount units do that too, now.
- A few invocations of log_struct() that didn't actually pass any
additional structured data have been replaced by simpler invocations
of log_unit_info() and friends.
- For structured data a new LOG_UNIT_MESSAGE() macro has been added,
that works like LOG_MESSAGE() but prefixes the message with the unit
name. Similar, there's now LOG_LINK_MESSAGE() and
LOG_NETDEV_MESSAGE().
- For structured data new LOG_UNIT_ID(), LOG_LINK_INTERFACE(),
LOG_NETDEV_INTERFACE() macros have been added that generate the
necessary per object fields. The old log_unit_struct() call has been
removed in favour of these new macros used in raw log_struct()
invocations. In addition to removing one more function call this
allows generated structured log messages that contain two object
fields, as necessary for example for network interfaces that are
joined into another network interface, and whose messages shall be
indexed by both.
- The LOG_ERRNO() macro has been removed, in favour of
log_struct_errno(). The latter has the benefit of ensuring that %m in
format strings is properly resolved to the specified error number.
- A number of logging messages have been converted to use
log_unit_info() instead of log_info()
- The client code in sysv-generator no longer #includes core code from
src/core/.
- log_unit_full_errno() has been removed, log_unit_full() instead takes
an errno now, too.
- log_unit_info(), log_link_info(), log_netdev_info() and friends, now
avoid double evaluation of their parameters
2015-05-11 20:38:21 +02:00
|
|
|
log_unit_warning_errno(UNIT(m), r, "Failed to run 'remount' task: %m");
|
2017-09-25 18:56:19 +02:00
|
|
|
mount_set_reload_result(m, MOUNT_FAILURE_RESOURCES);
|
mount: rework mount state engine
This changes the mount unit state engine in the following ways:
1. The MOUNT_MOUNTING_SIGTERM and MOUNT_MOUNTING_SIGKILL are removed.
They have been pretty much equivalent to MOUNT_UNMOUNTING_SIGTERM and
MOUNT_UNMOUNTING_SIGKILL in what they do, and the outcome has been
the same as well: the unit is stopped. Hence, let's simplify things a
bit, and merge them. Note that we keep
MOUNT_REMOUNTING_{SIGTERM|SIGKILL} however, as those states have a
different outcome: the unit remains started.
2. mount_enter_signal() will now honour the SendSIGKILL= option of the
mount unit if it was set. This was previously done already when we
entered the signal states through a timeout, and was simply missing
here.
3. A new helper function mount_enter_dead_or_mounted() is added that
places the mount unit in either MOUNT_DEAD or MOUNT_MOUNTED,
depending on what the kernel thinks about the mount's state. This
function is called at various places now, wherever we finished an
operation, and want to make sure our own state reflects again what
the kernel thinks. Previously we had very similar code in a number of
places and in other places didn't recheck the kernel state. Let's do
that with the same logic and function at all relevant places now.
4. Rework mount_stop(): never forget about running control processes.
Instead: when we have a start (i.e. a /bin/mount) process running,
and are asked to stop, then enter the kill states for it, so that it
gets cleaned up. This fixes #6048. Moreover, when we have a reload
process running convert the possible states into the relevant
unmounting states, so that we can properly execute the requested
operation.
Fixes #6048
2017-09-25 19:13:37 +02:00
|
|
|
mount_enter_dead_or_mounted(m, MOUNT_SUCCESS);
|
2010-04-10 17:53:17 +02:00
|
|
|
}
|
|
|
|
|
2018-11-28 20:01:24 +01:00
|
|
|
static void mount_cycle_clear(Mount *m) {
|
|
|
|
assert(m);
|
|
|
|
|
|
|
|
/* Clear all state we shall forget for this new cycle */
|
|
|
|
|
|
|
|
m->result = MOUNT_SUCCESS;
|
|
|
|
m->reload_result = MOUNT_SUCCESS;
|
|
|
|
exec_command_reset_status_array(m->exec_command, _MOUNT_EXEC_COMMAND_MAX);
|
|
|
|
UNIT(m)->reset_accounting = true;
|
|
|
|
}
|
|
|
|
|
2010-04-10 17:53:17 +02:00
|
|
|
static int mount_start(Unit *u) {
|
|
|
|
Mount *m = MOUNT(u);
|
core: move enforcement of the start limit into per-unit-type code again
Let's move the enforcement of the per-unit start limit from unit.c into the
type-specific files again. For unit types that know a concept of "result" codes
this allows us to hook up the start limit condition to it with an explicit
result code. Also, this makes sure that the state checks in clal like
service_start() may be done before the start limit is checked, as the start
limit really should be checked last, right before everything has been verified
to be in order.
The generic start limit logic is left in unit.c, but the invocation of it is
moved into the per-type files, in the various xyz_start() functions, so that
they may place the check at the right location.
Note that this change drops the enforcement entirely from device, slice, target
and scope units, since these unit types generally may not fail activation, or
may only be activated a single time. This is also documented now.
Note that restores the "start-limit-hit" result code that existed before
6bf0f408e4833152197fb38fb10a9989c89f3a59 already in the service code. However,
it's not introduced for all units that have a result code concept.
Fixes #3166.
2016-05-02 13:01:26 +02:00
|
|
|
int r;
|
2010-04-10 17:53:17 +02:00
|
|
|
|
|
|
|
assert(m);
|
|
|
|
|
|
|
|
/* We cannot fulfill this request right now, try again later
|
|
|
|
* please! */
|
2016-10-10 22:28:38 +02:00
|
|
|
if (IN_SET(m->state,
|
|
|
|
MOUNT_UNMOUNTING,
|
|
|
|
MOUNT_UNMOUNTING_SIGTERM,
|
2019-08-25 15:08:47 +02:00
|
|
|
MOUNT_UNMOUNTING_SIGKILL,
|
|
|
|
MOUNT_CLEANING))
|
2010-04-10 17:53:17 +02:00
|
|
|
return -EAGAIN;
|
|
|
|
|
|
|
|
/* Already on it! */
|
2020-11-17 02:50:12 +01:00
|
|
|
if (IN_SET(m->state, MOUNT_MOUNTING, MOUNT_MOUNTING_DONE))
|
2010-04-10 17:53:17 +02:00
|
|
|
return 0;
|
|
|
|
|
2016-10-10 22:28:38 +02:00
|
|
|
assert(IN_SET(m->state, MOUNT_DEAD, MOUNT_FAILED));
|
2010-04-10 17:53:17 +02:00
|
|
|
|
2019-03-18 12:21:27 +01:00
|
|
|
r = unit_test_start_limit(u);
|
core: move enforcement of the start limit into per-unit-type code again
Let's move the enforcement of the per-unit start limit from unit.c into the
type-specific files again. For unit types that know a concept of "result" codes
this allows us to hook up the start limit condition to it with an explicit
result code. Also, this makes sure that the state checks in clal like
service_start() may be done before the start limit is checked, as the start
limit really should be checked last, right before everything has been verified
to be in order.
The generic start limit logic is left in unit.c, but the invocation of it is
moved into the per-type files, in the various xyz_start() functions, so that
they may place the check at the right location.
Note that this change drops the enforcement entirely from device, slice, target
and scope units, since these unit types generally may not fail activation, or
may only be activated a single time. This is also documented now.
Note that restores the "start-limit-hit" result code that existed before
6bf0f408e4833152197fb38fb10a9989c89f3a59 already in the service code. However,
it's not introduced for all units that have a result code concept.
Fixes #3166.
2016-05-02 13:01:26 +02:00
|
|
|
if (r < 0) {
|
|
|
|
mount_enter_dead(m, MOUNT_FAILURE_START_LIMIT_HIT);
|
|
|
|
return r;
|
|
|
|
}
|
|
|
|
|
2016-08-30 23:18:46 +02:00
|
|
|
r = unit_acquire_invocation_id(u);
|
|
|
|
if (r < 0)
|
|
|
|
return r;
|
|
|
|
|
2018-11-28 20:01:24 +01:00
|
|
|
mount_cycle_clear(m);
|
2010-04-16 23:24:39 +02:00
|
|
|
mount_enter_mounting(m);
|
2018-11-28 20:01:24 +01:00
|
|
|
|
2015-01-28 15:07:13 +01:00
|
|
|
return 1;
|
2010-04-10 17:53:17 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
static int mount_stop(Unit *u) {
|
|
|
|
Mount *m = MOUNT(u);
|
|
|
|
|
|
|
|
assert(m);
|
|
|
|
|
mount: rework mount state engine
This changes the mount unit state engine in the following ways:
1. The MOUNT_MOUNTING_SIGTERM and MOUNT_MOUNTING_SIGKILL are removed.
They have been pretty much equivalent to MOUNT_UNMOUNTING_SIGTERM and
MOUNT_UNMOUNTING_SIGKILL in what they do, and the outcome has been
the same as well: the unit is stopped. Hence, let's simplify things a
bit, and merge them. Note that we keep
MOUNT_REMOUNTING_{SIGTERM|SIGKILL} however, as those states have a
different outcome: the unit remains started.
2. mount_enter_signal() will now honour the SendSIGKILL= option of the
mount unit if it was set. This was previously done already when we
entered the signal states through a timeout, and was simply missing
here.
3. A new helper function mount_enter_dead_or_mounted() is added that
places the mount unit in either MOUNT_DEAD or MOUNT_MOUNTED,
depending on what the kernel thinks about the mount's state. This
function is called at various places now, wherever we finished an
operation, and want to make sure our own state reflects again what
the kernel thinks. Previously we had very similar code in a number of
places and in other places didn't recheck the kernel state. Let's do
that with the same logic and function at all relevant places now.
4. Rework mount_stop(): never forget about running control processes.
Instead: when we have a start (i.e. a /bin/mount) process running,
and are asked to stop, then enter the kill states for it, so that it
gets cleaned up. This fixes #6048. Moreover, when we have a reload
process running convert the possible states into the relevant
unmounting states, so that we can properly execute the requested
operation.
Fixes #6048
2017-09-25 19:13:37 +02:00
|
|
|
switch (m->state) {
|
|
|
|
|
|
|
|
case MOUNT_UNMOUNTING:
|
|
|
|
case MOUNT_UNMOUNTING_SIGKILL:
|
|
|
|
case MOUNT_UNMOUNTING_SIGTERM:
|
|
|
|
/* Already on it */
|
2010-04-10 17:53:17 +02:00
|
|
|
return 0;
|
|
|
|
|
mount: rework mount state engine
This changes the mount unit state engine in the following ways:
1. The MOUNT_MOUNTING_SIGTERM and MOUNT_MOUNTING_SIGKILL are removed.
They have been pretty much equivalent to MOUNT_UNMOUNTING_SIGTERM and
MOUNT_UNMOUNTING_SIGKILL in what they do, and the outcome has been
the same as well: the unit is stopped. Hence, let's simplify things a
bit, and merge them. Note that we keep
MOUNT_REMOUNTING_{SIGTERM|SIGKILL} however, as those states have a
different outcome: the unit remains started.
2. mount_enter_signal() will now honour the SendSIGKILL= option of the
mount unit if it was set. This was previously done already when we
entered the signal states through a timeout, and was simply missing
here.
3. A new helper function mount_enter_dead_or_mounted() is added that
places the mount unit in either MOUNT_DEAD or MOUNT_MOUNTED,
depending on what the kernel thinks about the mount's state. This
function is called at various places now, wherever we finished an
operation, and want to make sure our own state reflects again what
the kernel thinks. Previously we had very similar code in a number of
places and in other places didn't recheck the kernel state. Let's do
that with the same logic and function at all relevant places now.
4. Rework mount_stop(): never forget about running control processes.
Instead: when we have a start (i.e. a /bin/mount) process running,
and are asked to stop, then enter the kill states for it, so that it
gets cleaned up. This fixes #6048. Moreover, when we have a reload
process running convert the possible states into the relevant
unmounting states, so that we can properly execute the requested
operation.
Fixes #6048
2017-09-25 19:13:37 +02:00
|
|
|
case MOUNT_MOUNTING:
|
|
|
|
case MOUNT_MOUNTING_DONE:
|
|
|
|
case MOUNT_REMOUNTING:
|
|
|
|
/* If we are still waiting for /bin/mount, we go directly into kill mode. */
|
|
|
|
mount_enter_signal(m, MOUNT_UNMOUNTING_SIGTERM, MOUNT_SUCCESS);
|
|
|
|
return 0;
|
2010-04-10 17:53:17 +02:00
|
|
|
|
mount: rework mount state engine
This changes the mount unit state engine in the following ways:
1. The MOUNT_MOUNTING_SIGTERM and MOUNT_MOUNTING_SIGKILL are removed.
They have been pretty much equivalent to MOUNT_UNMOUNTING_SIGTERM and
MOUNT_UNMOUNTING_SIGKILL in what they do, and the outcome has been
the same as well: the unit is stopped. Hence, let's simplify things a
bit, and merge them. Note that we keep
MOUNT_REMOUNTING_{SIGTERM|SIGKILL} however, as those states have a
different outcome: the unit remains started.
2. mount_enter_signal() will now honour the SendSIGKILL= option of the
mount unit if it was set. This was previously done already when we
entered the signal states through a timeout, and was simply missing
here.
3. A new helper function mount_enter_dead_or_mounted() is added that
places the mount unit in either MOUNT_DEAD or MOUNT_MOUNTED,
depending on what the kernel thinks about the mount's state. This
function is called at various places now, wherever we finished an
operation, and want to make sure our own state reflects again what
the kernel thinks. Previously we had very similar code in a number of
places and in other places didn't recheck the kernel state. Let's do
that with the same logic and function at all relevant places now.
4. Rework mount_stop(): never forget about running control processes.
Instead: when we have a start (i.e. a /bin/mount) process running,
and are asked to stop, then enter the kill states for it, so that it
gets cleaned up. This fixes #6048. Moreover, when we have a reload
process running convert the possible states into the relevant
unmounting states, so that we can properly execute the requested
operation.
Fixes #6048
2017-09-25 19:13:37 +02:00
|
|
|
case MOUNT_REMOUNTING_SIGTERM:
|
|
|
|
/* If we are already waiting for a hung remount, convert this to the matching unmounting state */
|
|
|
|
mount_set_state(m, MOUNT_UNMOUNTING_SIGTERM);
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
case MOUNT_REMOUNTING_SIGKILL:
|
|
|
|
/* as above */
|
|
|
|
mount_set_state(m, MOUNT_UNMOUNTING_SIGKILL);
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
case MOUNT_MOUNTED:
|
|
|
|
mount_enter_unmounting(m);
|
|
|
|
return 1;
|
|
|
|
|
2019-08-25 15:08:47 +02:00
|
|
|
case MOUNT_CLEANING:
|
|
|
|
/* If we are currently cleaning, then abort it, brutally. */
|
|
|
|
mount_enter_signal(m, MOUNT_UNMOUNTING_SIGKILL, MOUNT_SUCCESS);
|
|
|
|
return 0;
|
|
|
|
|
mount: rework mount state engine
This changes the mount unit state engine in the following ways:
1. The MOUNT_MOUNTING_SIGTERM and MOUNT_MOUNTING_SIGKILL are removed.
They have been pretty much equivalent to MOUNT_UNMOUNTING_SIGTERM and
MOUNT_UNMOUNTING_SIGKILL in what they do, and the outcome has been
the same as well: the unit is stopped. Hence, let's simplify things a
bit, and merge them. Note that we keep
MOUNT_REMOUNTING_{SIGTERM|SIGKILL} however, as those states have a
different outcome: the unit remains started.
2. mount_enter_signal() will now honour the SendSIGKILL= option of the
mount unit if it was set. This was previously done already when we
entered the signal states through a timeout, and was simply missing
here.
3. A new helper function mount_enter_dead_or_mounted() is added that
places the mount unit in either MOUNT_DEAD or MOUNT_MOUNTED,
depending on what the kernel thinks about the mount's state. This
function is called at various places now, wherever we finished an
operation, and want to make sure our own state reflects again what
the kernel thinks. Previously we had very similar code in a number of
places and in other places didn't recheck the kernel state. Let's do
that with the same logic and function at all relevant places now.
4. Rework mount_stop(): never forget about running control processes.
Instead: when we have a start (i.e. a /bin/mount) process running,
and are asked to stop, then enter the kill states for it, so that it
gets cleaned up. This fixes #6048. Moreover, when we have a reload
process running convert the possible states into the relevant
unmounting states, so that we can properly execute the requested
operation.
Fixes #6048
2017-09-25 19:13:37 +02:00
|
|
|
default:
|
|
|
|
assert_not_reached("Unexpected state.");
|
|
|
|
}
|
2010-04-10 17:53:17 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
static int mount_reload(Unit *u) {
|
|
|
|
Mount *m = MOUNT(u);
|
|
|
|
|
|
|
|
assert(m);
|
|
|
|
assert(m->state == MOUNT_MOUNTED);
|
|
|
|
|
2012-02-03 03:10:56 +01:00
|
|
|
mount_enter_remounting(m);
|
mount: rework mount state engine
This changes the mount unit state engine in the following ways:
1. The MOUNT_MOUNTING_SIGTERM and MOUNT_MOUNTING_SIGKILL are removed.
They have been pretty much equivalent to MOUNT_UNMOUNTING_SIGTERM and
MOUNT_UNMOUNTING_SIGKILL in what they do, and the outcome has been
the same as well: the unit is stopped. Hence, let's simplify things a
bit, and merge them. Note that we keep
MOUNT_REMOUNTING_{SIGTERM|SIGKILL} however, as those states have a
different outcome: the unit remains started.
2. mount_enter_signal() will now honour the SendSIGKILL= option of the
mount unit if it was set. This was previously done already when we
entered the signal states through a timeout, and was simply missing
here.
3. A new helper function mount_enter_dead_or_mounted() is added that
places the mount unit in either MOUNT_DEAD or MOUNT_MOUNTED,
depending on what the kernel thinks about the mount's state. This
function is called at various places now, wherever we finished an
operation, and want to make sure our own state reflects again what
the kernel thinks. Previously we had very similar code in a number of
places and in other places didn't recheck the kernel state. Let's do
that with the same logic and function at all relevant places now.
4. Rework mount_stop(): never forget about running control processes.
Instead: when we have a start (i.e. a /bin/mount) process running,
and are asked to stop, then enter the kill states for it, so that it
gets cleaned up. This fixes #6048. Moreover, when we have a reload
process running convert the possible states into the relevant
unmounting states, so that we can properly execute the requested
operation.
Fixes #6048
2017-09-25 19:13:37 +02:00
|
|
|
|
2015-07-16 21:39:56 +02:00
|
|
|
return 1;
|
2010-04-10 17:53:17 +02:00
|
|
|
}
|
|
|
|
|
2010-04-21 03:27:44 +02:00
|
|
|
static int mount_serialize(Unit *u, FILE *f, FDSet *fds) {
|
|
|
|
Mount *m = MOUNT(u);
|
|
|
|
|
|
|
|
assert(m);
|
|
|
|
assert(f);
|
|
|
|
assert(fds);
|
|
|
|
|
2018-10-17 20:40:09 +02:00
|
|
|
(void) serialize_item(f, "state", mount_state_to_string(m->state));
|
|
|
|
(void) serialize_item(f, "result", mount_result_to_string(m->result));
|
|
|
|
(void) serialize_item(f, "reload-result", mount_result_to_string(m->reload_result));
|
2018-11-28 12:40:37 +01:00
|
|
|
(void) serialize_item_format(f, "n-retry-umount", "%u", m->n_retry_umount);
|
2010-04-21 03:27:44 +02:00
|
|
|
|
|
|
|
if (m->control_pid > 0)
|
2018-10-17 20:40:09 +02:00
|
|
|
(void) serialize_item_format(f, "control-pid", PID_FMT, m->control_pid);
|
2010-04-21 03:27:44 +02:00
|
|
|
|
|
|
|
if (m->control_command_id >= 0)
|
2018-10-17 20:40:09 +02:00
|
|
|
(void) serialize_item(f, "control-command", mount_exec_command_to_string(m->control_command_id));
|
2010-04-21 03:27:44 +02:00
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int mount_deserialize_item(Unit *u, const char *key, const char *value, FDSet *fds) {
|
|
|
|
Mount *m = MOUNT(u);
|
2018-11-28 12:40:37 +01:00
|
|
|
int r;
|
2010-04-21 03:27:44 +02:00
|
|
|
|
|
|
|
assert(u);
|
|
|
|
assert(key);
|
|
|
|
assert(value);
|
|
|
|
assert(fds);
|
|
|
|
|
|
|
|
if (streq(key, "state")) {
|
|
|
|
MountState state;
|
|
|
|
|
|
|
|
if ((state = mount_state_from_string(value)) < 0)
|
core,network: major per-object logging rework
This changes log_unit_info() (and friends) to take a real Unit* object
insted of just a unit name as parameter. The call will now prefix all
logged messages with the unit name, thus allowing the unit name to be
dropped from the various passed romat strings, simplifying invocations
drastically, and unifying log output across messages. Also, UNIT= vs.
USER_UNIT= is now derived from the Manager object attached to the Unit
object, instead of getpid(). This has the benefit of correcting the
field for --test runs.
Also contains a couple of other logging improvements:
- Drops a couple of strerror() invocations in favour of using %m.
- Not only .mount units now warn if a symlinks exist for the mount
point already, .automount units do that too, now.
- A few invocations of log_struct() that didn't actually pass any
additional structured data have been replaced by simpler invocations
of log_unit_info() and friends.
- For structured data a new LOG_UNIT_MESSAGE() macro has been added,
that works like LOG_MESSAGE() but prefixes the message with the unit
name. Similar, there's now LOG_LINK_MESSAGE() and
LOG_NETDEV_MESSAGE().
- For structured data new LOG_UNIT_ID(), LOG_LINK_INTERFACE(),
LOG_NETDEV_INTERFACE() macros have been added that generate the
necessary per object fields. The old log_unit_struct() call has been
removed in favour of these new macros used in raw log_struct()
invocations. In addition to removing one more function call this
allows generated structured log messages that contain two object
fields, as necessary for example for network interfaces that are
joined into another network interface, and whose messages shall be
indexed by both.
- The LOG_ERRNO() macro has been removed, in favour of
log_struct_errno(). The latter has the benefit of ensuring that %m in
format strings is properly resolved to the specified error number.
- A number of logging messages have been converted to use
log_unit_info() instead of log_info()
- The client code in sysv-generator no longer #includes core code from
src/core/.
- log_unit_full_errno() has been removed, log_unit_full() instead takes
an errno now, too.
- log_unit_info(), log_link_info(), log_netdev_info() and friends, now
avoid double evaluation of their parameters
2015-05-11 20:38:21 +02:00
|
|
|
log_unit_debug(u, "Failed to parse state value: %s", value);
|
2010-04-21 03:27:44 +02:00
|
|
|
else
|
|
|
|
m->deserialized_state = state;
|
2018-11-28 12:40:37 +01:00
|
|
|
|
2012-02-03 03:10:56 +01:00
|
|
|
} else if (streq(key, "result")) {
|
|
|
|
MountResult f;
|
2010-04-21 03:27:44 +02:00
|
|
|
|
2012-02-03 03:10:56 +01:00
|
|
|
f = mount_result_from_string(value);
|
|
|
|
if (f < 0)
|
core,network: major per-object logging rework
This changes log_unit_info() (and friends) to take a real Unit* object
insted of just a unit name as parameter. The call will now prefix all
logged messages with the unit name, thus allowing the unit name to be
dropped from the various passed romat strings, simplifying invocations
drastically, and unifying log output across messages. Also, UNIT= vs.
USER_UNIT= is now derived from the Manager object attached to the Unit
object, instead of getpid(). This has the benefit of correcting the
field for --test runs.
Also contains a couple of other logging improvements:
- Drops a couple of strerror() invocations in favour of using %m.
- Not only .mount units now warn if a symlinks exist for the mount
point already, .automount units do that too, now.
- A few invocations of log_struct() that didn't actually pass any
additional structured data have been replaced by simpler invocations
of log_unit_info() and friends.
- For structured data a new LOG_UNIT_MESSAGE() macro has been added,
that works like LOG_MESSAGE() but prefixes the message with the unit
name. Similar, there's now LOG_LINK_MESSAGE() and
LOG_NETDEV_MESSAGE().
- For structured data new LOG_UNIT_ID(), LOG_LINK_INTERFACE(),
LOG_NETDEV_INTERFACE() macros have been added that generate the
necessary per object fields. The old log_unit_struct() call has been
removed in favour of these new macros used in raw log_struct()
invocations. In addition to removing one more function call this
allows generated structured log messages that contain two object
fields, as necessary for example for network interfaces that are
joined into another network interface, and whose messages shall be
indexed by both.
- The LOG_ERRNO() macro has been removed, in favour of
log_struct_errno(). The latter has the benefit of ensuring that %m in
format strings is properly resolved to the specified error number.
- A number of logging messages have been converted to use
log_unit_info() instead of log_info()
- The client code in sysv-generator no longer #includes core code from
src/core/.
- log_unit_full_errno() has been removed, log_unit_full() instead takes
an errno now, too.
- log_unit_info(), log_link_info(), log_netdev_info() and friends, now
avoid double evaluation of their parameters
2015-05-11 20:38:21 +02:00
|
|
|
log_unit_debug(u, "Failed to parse result value: %s", value);
|
2012-02-03 03:10:56 +01:00
|
|
|
else if (f != MOUNT_SUCCESS)
|
|
|
|
m->result = f;
|
|
|
|
|
|
|
|
} else if (streq(key, "reload-result")) {
|
|
|
|
MountResult f;
|
|
|
|
|
|
|
|
f = mount_result_from_string(value);
|
|
|
|
if (f < 0)
|
core,network: major per-object logging rework
This changes log_unit_info() (and friends) to take a real Unit* object
insted of just a unit name as parameter. The call will now prefix all
logged messages with the unit name, thus allowing the unit name to be
dropped from the various passed romat strings, simplifying invocations
drastically, and unifying log output across messages. Also, UNIT= vs.
USER_UNIT= is now derived from the Manager object attached to the Unit
object, instead of getpid(). This has the benefit of correcting the
field for --test runs.
Also contains a couple of other logging improvements:
- Drops a couple of strerror() invocations in favour of using %m.
- Not only .mount units now warn if a symlinks exist for the mount
point already, .automount units do that too, now.
- A few invocations of log_struct() that didn't actually pass any
additional structured data have been replaced by simpler invocations
of log_unit_info() and friends.
- For structured data a new LOG_UNIT_MESSAGE() macro has been added,
that works like LOG_MESSAGE() but prefixes the message with the unit
name. Similar, there's now LOG_LINK_MESSAGE() and
LOG_NETDEV_MESSAGE().
- For structured data new LOG_UNIT_ID(), LOG_LINK_INTERFACE(),
LOG_NETDEV_INTERFACE() macros have been added that generate the
necessary per object fields. The old log_unit_struct() call has been
removed in favour of these new macros used in raw log_struct()
invocations. In addition to removing one more function call this
allows generated structured log messages that contain two object
fields, as necessary for example for network interfaces that are
joined into another network interface, and whose messages shall be
indexed by both.
- The LOG_ERRNO() macro has been removed, in favour of
log_struct_errno(). The latter has the benefit of ensuring that %m in
format strings is properly resolved to the specified error number.
- A number of logging messages have been converted to use
log_unit_info() instead of log_info()
- The client code in sysv-generator no longer #includes core code from
src/core/.
- log_unit_full_errno() has been removed, log_unit_full() instead takes
an errno now, too.
- log_unit_info(), log_link_info(), log_netdev_info() and friends, now
avoid double evaluation of their parameters
2015-05-11 20:38:21 +02:00
|
|
|
log_unit_debug(u, "Failed to parse reload result value: %s", value);
|
2012-02-03 03:10:56 +01:00
|
|
|
else if (f != MOUNT_SUCCESS)
|
|
|
|
m->reload_result = f;
|
2010-04-21 03:27:44 +02:00
|
|
|
|
2018-11-28 12:40:37 +01:00
|
|
|
} else if (streq(key, "n-retry-umount")) {
|
|
|
|
|
|
|
|
r = safe_atou(value, &m->n_retry_umount);
|
|
|
|
if (r < 0)
|
|
|
|
log_unit_debug(u, "Failed to parse n-retry-umount value: %s", value);
|
|
|
|
|
2010-04-21 03:27:44 +02:00
|
|
|
} else if (streq(key, "control-pid")) {
|
|
|
|
|
2018-11-28 12:41:14 +01:00
|
|
|
if (parse_pid(value, &m->control_pid) < 0)
|
core,network: major per-object logging rework
This changes log_unit_info() (and friends) to take a real Unit* object
insted of just a unit name as parameter. The call will now prefix all
logged messages with the unit name, thus allowing the unit name to be
dropped from the various passed romat strings, simplifying invocations
drastically, and unifying log output across messages. Also, UNIT= vs.
USER_UNIT= is now derived from the Manager object attached to the Unit
object, instead of getpid(). This has the benefit of correcting the
field for --test runs.
Also contains a couple of other logging improvements:
- Drops a couple of strerror() invocations in favour of using %m.
- Not only .mount units now warn if a symlinks exist for the mount
point already, .automount units do that too, now.
- A few invocations of log_struct() that didn't actually pass any
additional structured data have been replaced by simpler invocations
of log_unit_info() and friends.
- For structured data a new LOG_UNIT_MESSAGE() macro has been added,
that works like LOG_MESSAGE() but prefixes the message with the unit
name. Similar, there's now LOG_LINK_MESSAGE() and
LOG_NETDEV_MESSAGE().
- For structured data new LOG_UNIT_ID(), LOG_LINK_INTERFACE(),
LOG_NETDEV_INTERFACE() macros have been added that generate the
necessary per object fields. The old log_unit_struct() call has been
removed in favour of these new macros used in raw log_struct()
invocations. In addition to removing one more function call this
allows generated structured log messages that contain two object
fields, as necessary for example for network interfaces that are
joined into another network interface, and whose messages shall be
indexed by both.
- The LOG_ERRNO() macro has been removed, in favour of
log_struct_errno(). The latter has the benefit of ensuring that %m in
format strings is properly resolved to the specified error number.
- A number of logging messages have been converted to use
log_unit_info() instead of log_info()
- The client code in sysv-generator no longer #includes core code from
src/core/.
- log_unit_full_errno() has been removed, log_unit_full() instead takes
an errno now, too.
- log_unit_info(), log_link_info(), log_netdev_info() and friends, now
avoid double evaluation of their parameters
2015-05-11 20:38:21 +02:00
|
|
|
log_unit_debug(u, "Failed to parse control-pid value: %s", value);
|
2018-11-28 12:41:14 +01:00
|
|
|
|
2010-04-21 03:27:44 +02:00
|
|
|
} else if (streq(key, "control-command")) {
|
|
|
|
MountExecCommand id;
|
|
|
|
|
core,network: major per-object logging rework
This changes log_unit_info() (and friends) to take a real Unit* object
insted of just a unit name as parameter. The call will now prefix all
logged messages with the unit name, thus allowing the unit name to be
dropped from the various passed romat strings, simplifying invocations
drastically, and unifying log output across messages. Also, UNIT= vs.
USER_UNIT= is now derived from the Manager object attached to the Unit
object, instead of getpid(). This has the benefit of correcting the
field for --test runs.
Also contains a couple of other logging improvements:
- Drops a couple of strerror() invocations in favour of using %m.
- Not only .mount units now warn if a symlinks exist for the mount
point already, .automount units do that too, now.
- A few invocations of log_struct() that didn't actually pass any
additional structured data have been replaced by simpler invocations
of log_unit_info() and friends.
- For structured data a new LOG_UNIT_MESSAGE() macro has been added,
that works like LOG_MESSAGE() but prefixes the message with the unit
name. Similar, there's now LOG_LINK_MESSAGE() and
LOG_NETDEV_MESSAGE().
- For structured data new LOG_UNIT_ID(), LOG_LINK_INTERFACE(),
LOG_NETDEV_INTERFACE() macros have been added that generate the
necessary per object fields. The old log_unit_struct() call has been
removed in favour of these new macros used in raw log_struct()
invocations. In addition to removing one more function call this
allows generated structured log messages that contain two object
fields, as necessary for example for network interfaces that are
joined into another network interface, and whose messages shall be
indexed by both.
- The LOG_ERRNO() macro has been removed, in favour of
log_struct_errno(). The latter has the benefit of ensuring that %m in
format strings is properly resolved to the specified error number.
- A number of logging messages have been converted to use
log_unit_info() instead of log_info()
- The client code in sysv-generator no longer #includes core code from
src/core/.
- log_unit_full_errno() has been removed, log_unit_full() instead takes
an errno now, too.
- log_unit_info(), log_link_info(), log_netdev_info() and friends, now
avoid double evaluation of their parameters
2015-05-11 20:38:21 +02:00
|
|
|
id = mount_exec_command_from_string(value);
|
|
|
|
if (id < 0)
|
|
|
|
log_unit_debug(u, "Failed to parse exec-command value: %s", value);
|
2010-04-21 03:27:44 +02:00
|
|
|
else {
|
|
|
|
m->control_command_id = id;
|
|
|
|
m->control_command = m->exec_command + id;
|
|
|
|
}
|
|
|
|
} else
|
core,network: major per-object logging rework
This changes log_unit_info() (and friends) to take a real Unit* object
insted of just a unit name as parameter. The call will now prefix all
logged messages with the unit name, thus allowing the unit name to be
dropped from the various passed romat strings, simplifying invocations
drastically, and unifying log output across messages. Also, UNIT= vs.
USER_UNIT= is now derived from the Manager object attached to the Unit
object, instead of getpid(). This has the benefit of correcting the
field for --test runs.
Also contains a couple of other logging improvements:
- Drops a couple of strerror() invocations in favour of using %m.
- Not only .mount units now warn if a symlinks exist for the mount
point already, .automount units do that too, now.
- A few invocations of log_struct() that didn't actually pass any
additional structured data have been replaced by simpler invocations
of log_unit_info() and friends.
- For structured data a new LOG_UNIT_MESSAGE() macro has been added,
that works like LOG_MESSAGE() but prefixes the message with the unit
name. Similar, there's now LOG_LINK_MESSAGE() and
LOG_NETDEV_MESSAGE().
- For structured data new LOG_UNIT_ID(), LOG_LINK_INTERFACE(),
LOG_NETDEV_INTERFACE() macros have been added that generate the
necessary per object fields. The old log_unit_struct() call has been
removed in favour of these new macros used in raw log_struct()
invocations. In addition to removing one more function call this
allows generated structured log messages that contain two object
fields, as necessary for example for network interfaces that are
joined into another network interface, and whose messages shall be
indexed by both.
- The LOG_ERRNO() macro has been removed, in favour of
log_struct_errno(). The latter has the benefit of ensuring that %m in
format strings is properly resolved to the specified error number.
- A number of logging messages have been converted to use
log_unit_info() instead of log_info()
- The client code in sysv-generator no longer #includes core code from
src/core/.
- log_unit_full_errno() has been removed, log_unit_full() instead takes
an errno now, too.
- log_unit_info(), log_link_info(), log_netdev_info() and friends, now
avoid double evaluation of their parameters
2015-05-11 20:38:21 +02:00
|
|
|
log_unit_debug(u, "Unknown serialization key: %s", key);
|
2010-04-21 03:27:44 +02:00
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2013-05-03 04:51:50 +02:00
|
|
|
_pure_ static UnitActiveState mount_active_state(Unit *u) {
|
2010-04-10 17:53:17 +02:00
|
|
|
assert(u);
|
|
|
|
|
|
|
|
return state_translation_table[MOUNT(u)->state];
|
|
|
|
}
|
|
|
|
|
2013-05-03 04:51:50 +02:00
|
|
|
_pure_ static const char *mount_sub_state_to_string(Unit *u) {
|
2010-04-13 20:59:01 +02:00
|
|
|
assert(u);
|
|
|
|
|
2010-04-21 03:27:44 +02:00
|
|
|
return mount_state_to_string(MOUNT(u)->state);
|
2010-04-13 20:59:01 +02:00
|
|
|
}
|
|
|
|
|
2018-02-13 10:50:13 +01:00
|
|
|
_pure_ static bool mount_may_gc(Unit *u) {
|
2010-04-21 06:01:13 +02:00
|
|
|
Mount *m = MOUNT(u);
|
|
|
|
|
|
|
|
assert(m);
|
|
|
|
|
2018-02-13 10:50:13 +01:00
|
|
|
if (m->from_proc_self_mountinfo)
|
|
|
|
return false;
|
|
|
|
|
|
|
|
return true;
|
2010-04-21 06:01:13 +02:00
|
|
|
}
|
|
|
|
|
2010-04-10 17:53:17 +02:00
|
|
|
static void mount_sigchld_event(Unit *u, pid_t pid, int code, int status) {
|
|
|
|
Mount *m = MOUNT(u);
|
2012-02-03 03:10:56 +01:00
|
|
|
MountResult f;
|
2010-04-10 17:53:17 +02:00
|
|
|
|
|
|
|
assert(m);
|
|
|
|
assert(pid >= 0);
|
|
|
|
|
2010-06-16 05:10:31 +02:00
|
|
|
if (pid != m->control_pid)
|
|
|
|
return;
|
2010-04-10 17:53:17 +02:00
|
|
|
|
2019-07-17 18:57:13 +02:00
|
|
|
/* So here's the thing, we really want to know before /usr/bin/mount or /usr/bin/umount exit whether
|
|
|
|
* they established/remove a mount. This is important when mounting, but even more so when unmounting
|
|
|
|
* since we need to deal with nested mounts and otherwise cannot safely determine whether to repeat
|
|
|
|
* the unmounts. In theory, the kernel fires /proc/self/mountinfo changes off before returning from
|
|
|
|
* the mount() or umount() syscalls, and thus we should see the changes to the proc file before we
|
|
|
|
* process the waitid() for the /usr/bin/(u)mount processes. However, this is unfortunately racy: we
|
|
|
|
* have to waitid() for processes using P_ALL (since we need to reap unexpected children that got
|
|
|
|
* reparented to PID 1), but when using P_ALL we might end up reaping processes that terminated just
|
|
|
|
* instants ago, i.e. already after our last event loop iteration (i.e. after the last point we might
|
|
|
|
* have noticed /proc/self/mountinfo events via epoll). This means event loop priorities for
|
|
|
|
* processing SIGCHLD vs. /proc/self/mountinfo IO events are not as relevant as we want. To fix that
|
|
|
|
* race, let's explicitly scan /proc/self/mountinfo before we start processing /usr/bin/(u)mount
|
|
|
|
* dying. It's ugly, but it makes our ordering systematic again, and makes sure we always see
|
|
|
|
* /proc/self/mountinfo changes before our mount/umount exits. */
|
|
|
|
(void) mount_process_proc_self_mountinfo(u->manager);
|
|
|
|
|
2010-04-10 17:53:17 +02:00
|
|
|
m->control_pid = 0;
|
|
|
|
|
2016-10-10 22:07:30 +02:00
|
|
|
if (is_clean_exit(code, status, EXIT_CLEAN_COMMAND, NULL))
|
2012-02-03 03:10:56 +01:00
|
|
|
f = MOUNT_SUCCESS;
|
|
|
|
else if (code == CLD_EXITED)
|
|
|
|
f = MOUNT_FAILURE_EXIT_CODE;
|
|
|
|
else if (code == CLD_KILLED)
|
|
|
|
f = MOUNT_FAILURE_SIGNAL;
|
|
|
|
else if (code == CLD_DUMPED)
|
|
|
|
f = MOUNT_FAILURE_CORE_DUMP;
|
|
|
|
else
|
|
|
|
assert_not_reached("Unknown code");
|
|
|
|
|
2017-09-25 18:56:19 +02:00
|
|
|
if (IN_SET(m->state, MOUNT_REMOUNTING, MOUNT_REMOUNTING_SIGKILL, MOUNT_REMOUNTING_SIGTERM))
|
|
|
|
mount_set_reload_result(m, f);
|
|
|
|
else if (m->result == MOUNT_SUCCESS)
|
2012-02-03 03:10:56 +01:00
|
|
|
m->result = f;
|
2010-06-16 05:10:31 +02:00
|
|
|
|
2010-04-21 03:27:44 +02:00
|
|
|
if (m->control_command) {
|
2011-05-18 01:07:31 +02:00
|
|
|
exec_status_exit(&m->control_command->exec_status, &m->exec_context, pid, code, status);
|
2012-02-03 03:10:56 +01:00
|
|
|
|
2010-04-21 03:27:44 +02:00
|
|
|
m->control_command = NULL;
|
|
|
|
m->control_command_id = _MOUNT_EXEC_COMMAND_INVALID;
|
|
|
|
}
|
|
|
|
|
2018-11-13 22:10:38 +01:00
|
|
|
unit_log_process_exit(
|
2019-08-21 16:20:59 +02:00
|
|
|
u,
|
2018-11-13 22:10:38 +01:00
|
|
|
"Mount process",
|
|
|
|
mount_exec_command_to_string(m->control_command_id),
|
2019-08-21 16:20:59 +02:00
|
|
|
f == MOUNT_SUCCESS,
|
2018-11-13 22:10:38 +01:00
|
|
|
code, status);
|
2010-04-10 17:53:17 +02:00
|
|
|
|
2018-01-20 21:05:52 +01:00
|
|
|
/* Note that due to the io event priority logic, we can be sure the new mountinfo is loaded
|
|
|
|
* before we process the SIGCHLD for the mount command. */
|
2010-04-10 17:53:17 +02:00
|
|
|
|
|
|
|
switch (m->state) {
|
|
|
|
|
|
|
|
case MOUNT_MOUNTING:
|
2018-01-20 21:05:52 +01:00
|
|
|
/* Our mount point has not appeared in mountinfo. Something went wrong. */
|
2010-04-10 17:53:17 +02:00
|
|
|
|
2018-01-20 21:05:52 +01:00
|
|
|
if (f == MOUNT_SUCCESS) {
|
|
|
|
/* Either /bin/mount has an unexpected definition of success,
|
|
|
|
* or someone raced us and we lost. */
|
|
|
|
log_unit_warning(UNIT(m), "Mount process finished, but there is no mount.");
|
|
|
|
f = MOUNT_FAILURE_PROTOCOL;
|
|
|
|
}
|
|
|
|
mount_enter_dead(m, f);
|
|
|
|
break;
|
|
|
|
|
|
|
|
case MOUNT_MOUNTING_DONE:
|
|
|
|
mount_enter_mounted(m, f);
|
2010-04-10 17:53:17 +02:00
|
|
|
break;
|
|
|
|
|
2011-01-20 13:17:22 +01:00
|
|
|
case MOUNT_REMOUNTING:
|
|
|
|
case MOUNT_REMOUNTING_SIGTERM:
|
mount: rework mount state engine
This changes the mount unit state engine in the following ways:
1. The MOUNT_MOUNTING_SIGTERM and MOUNT_MOUNTING_SIGKILL are removed.
They have been pretty much equivalent to MOUNT_UNMOUNTING_SIGTERM and
MOUNT_UNMOUNTING_SIGKILL in what they do, and the outcome has been
the same as well: the unit is stopped. Hence, let's simplify things a
bit, and merge them. Note that we keep
MOUNT_REMOUNTING_{SIGTERM|SIGKILL} however, as those states have a
different outcome: the unit remains started.
2. mount_enter_signal() will now honour the SendSIGKILL= option of the
mount unit if it was set. This was previously done already when we
entered the signal states through a timeout, and was simply missing
here.
3. A new helper function mount_enter_dead_or_mounted() is added that
places the mount unit in either MOUNT_DEAD or MOUNT_MOUNTED,
depending on what the kernel thinks about the mount's state. This
function is called at various places now, wherever we finished an
operation, and want to make sure our own state reflects again what
the kernel thinks. Previously we had very similar code in a number of
places and in other places didn't recheck the kernel state. Let's do
that with the same logic and function at all relevant places now.
4. Rework mount_stop(): never forget about running control processes.
Instead: when we have a start (i.e. a /bin/mount) process running,
and are asked to stop, then enter the kill states for it, so that it
gets cleaned up. This fixes #6048. Moreover, when we have a reload
process running convert the possible states into the relevant
unmounting states, so that we can properly execute the requested
operation.
Fixes #6048
2017-09-25 19:13:37 +02:00
|
|
|
case MOUNT_REMOUNTING_SIGKILL:
|
|
|
|
mount_enter_dead_or_mounted(m, MOUNT_SUCCESS);
|
2011-01-20 13:17:22 +01:00
|
|
|
break;
|
|
|
|
|
2010-04-10 17:53:17 +02:00
|
|
|
case MOUNT_UNMOUNTING:
|
|
|
|
|
2018-01-13 18:22:46 +01:00
|
|
|
if (f == MOUNT_SUCCESS && m->from_proc_self_mountinfo) {
|
mount: rework mount state engine
This changes the mount unit state engine in the following ways:
1. The MOUNT_MOUNTING_SIGTERM and MOUNT_MOUNTING_SIGKILL are removed.
They have been pretty much equivalent to MOUNT_UNMOUNTING_SIGTERM and
MOUNT_UNMOUNTING_SIGKILL in what they do, and the outcome has been
the same as well: the unit is stopped. Hence, let's simplify things a
bit, and merge them. Note that we keep
MOUNT_REMOUNTING_{SIGTERM|SIGKILL} however, as those states have a
different outcome: the unit remains started.
2. mount_enter_signal() will now honour the SendSIGKILL= option of the
mount unit if it was set. This was previously done already when we
entered the signal states through a timeout, and was simply missing
here.
3. A new helper function mount_enter_dead_or_mounted() is added that
places the mount unit in either MOUNT_DEAD or MOUNT_MOUNTED,
depending on what the kernel thinks about the mount's state. This
function is called at various places now, wherever we finished an
operation, and want to make sure our own state reflects again what
the kernel thinks. Previously we had very similar code in a number of
places and in other places didn't recheck the kernel state. Let's do
that with the same logic and function at all relevant places now.
4. Rework mount_stop(): never forget about running control processes.
Instead: when we have a start (i.e. a /bin/mount) process running,
and are asked to stop, then enter the kill states for it, so that it
gets cleaned up. This fixes #6048. Moreover, when we have a reload
process running convert the possible states into the relevant
unmounting states, so that we can properly execute the requested
operation.
Fixes #6048
2017-09-25 19:13:37 +02:00
|
|
|
|
|
|
|
/* Still a mount point? If so, let's try again. Most likely there were multiple mount points
|
2018-01-22 18:42:25 +01:00
|
|
|
* stacked on top of each other. We might exceed the timeout specified by the user overall,
|
|
|
|
* but we will stop as soon as any one umount times out. */
|
mount: rework mount state engine
This changes the mount unit state engine in the following ways:
1. The MOUNT_MOUNTING_SIGTERM and MOUNT_MOUNTING_SIGKILL are removed.
They have been pretty much equivalent to MOUNT_UNMOUNTING_SIGTERM and
MOUNT_UNMOUNTING_SIGKILL in what they do, and the outcome has been
the same as well: the unit is stopped. Hence, let's simplify things a
bit, and merge them. Note that we keep
MOUNT_REMOUNTING_{SIGTERM|SIGKILL} however, as those states have a
different outcome: the unit remains started.
2. mount_enter_signal() will now honour the SendSIGKILL= option of the
mount unit if it was set. This was previously done already when we
entered the signal states through a timeout, and was simply missing
here.
3. A new helper function mount_enter_dead_or_mounted() is added that
places the mount unit in either MOUNT_DEAD or MOUNT_MOUNTED,
depending on what the kernel thinks about the mount's state. This
function is called at various places now, wherever we finished an
operation, and want to make sure our own state reflects again what
the kernel thinks. Previously we had very similar code in a number of
places and in other places didn't recheck the kernel state. Let's do
that with the same logic and function at all relevant places now.
4. Rework mount_stop(): never forget about running control processes.
Instead: when we have a start (i.e. a /bin/mount) process running,
and are asked to stop, then enter the kill states for it, so that it
gets cleaned up. This fixes #6048. Moreover, when we have a reload
process running convert the possible states into the relevant
unmounting states, so that we can properly execute the requested
operation.
Fixes #6048
2017-09-25 19:13:37 +02:00
|
|
|
|
|
|
|
if (m->n_retry_umount < RETRY_UMOUNT_MAX) {
|
|
|
|
log_unit_debug(u, "Mount still present, trying again.");
|
|
|
|
m->n_retry_umount++;
|
|
|
|
mount_enter_unmounting(m);
|
|
|
|
} else {
|
2018-01-20 21:05:52 +01:00
|
|
|
log_unit_warning(u, "Mount still present after %u attempts to unmount, giving up.", m->n_retry_umount);
|
mount: rework mount state engine
This changes the mount unit state engine in the following ways:
1. The MOUNT_MOUNTING_SIGTERM and MOUNT_MOUNTING_SIGKILL are removed.
They have been pretty much equivalent to MOUNT_UNMOUNTING_SIGTERM and
MOUNT_UNMOUNTING_SIGKILL in what they do, and the outcome has been
the same as well: the unit is stopped. Hence, let's simplify things a
bit, and merge them. Note that we keep
MOUNT_REMOUNTING_{SIGTERM|SIGKILL} however, as those states have a
different outcome: the unit remains started.
2. mount_enter_signal() will now honour the SendSIGKILL= option of the
mount unit if it was set. This was previously done already when we
entered the signal states through a timeout, and was simply missing
here.
3. A new helper function mount_enter_dead_or_mounted() is added that
places the mount unit in either MOUNT_DEAD or MOUNT_MOUNTED,
depending on what the kernel thinks about the mount's state. This
function is called at various places now, wherever we finished an
operation, and want to make sure our own state reflects again what
the kernel thinks. Previously we had very similar code in a number of
places and in other places didn't recheck the kernel state. Let's do
that with the same logic and function at all relevant places now.
4. Rework mount_stop(): never forget about running control processes.
Instead: when we have a start (i.e. a /bin/mount) process running,
and are asked to stop, then enter the kill states for it, so that it
gets cleaned up. This fixes #6048. Moreover, when we have a reload
process running convert the possible states into the relevant
unmounting states, so that we can properly execute the requested
operation.
Fixes #6048
2017-09-25 19:13:37 +02:00
|
|
|
mount_enter_mounted(m, f);
|
|
|
|
}
|
|
|
|
} else
|
2018-01-13 18:22:46 +01:00
|
|
|
mount_enter_dead_or_mounted(m, f);
|
mount: rework mount state engine
This changes the mount unit state engine in the following ways:
1. The MOUNT_MOUNTING_SIGTERM and MOUNT_MOUNTING_SIGKILL are removed.
They have been pretty much equivalent to MOUNT_UNMOUNTING_SIGTERM and
MOUNT_UNMOUNTING_SIGKILL in what they do, and the outcome has been
the same as well: the unit is stopped. Hence, let's simplify things a
bit, and merge them. Note that we keep
MOUNT_REMOUNTING_{SIGTERM|SIGKILL} however, as those states have a
different outcome: the unit remains started.
2. mount_enter_signal() will now honour the SendSIGKILL= option of the
mount unit if it was set. This was previously done already when we
entered the signal states through a timeout, and was simply missing
here.
3. A new helper function mount_enter_dead_or_mounted() is added that
places the mount unit in either MOUNT_DEAD or MOUNT_MOUNTED,
depending on what the kernel thinks about the mount's state. This
function is called at various places now, wherever we finished an
operation, and want to make sure our own state reflects again what
the kernel thinks. Previously we had very similar code in a number of
places and in other places didn't recheck the kernel state. Let's do
that with the same logic and function at all relevant places now.
4. Rework mount_stop(): never forget about running control processes.
Instead: when we have a start (i.e. a /bin/mount) process running,
and are asked to stop, then enter the kill states for it, so that it
gets cleaned up. This fixes #6048. Moreover, when we have a reload
process running convert the possible states into the relevant
unmounting states, so that we can properly execute the requested
operation.
Fixes #6048
2017-09-25 19:13:37 +02:00
|
|
|
|
2010-04-10 17:53:17 +02:00
|
|
|
break;
|
2018-01-22 18:42:25 +01:00
|
|
|
|
|
|
|
case MOUNT_UNMOUNTING_SIGKILL:
|
|
|
|
case MOUNT_UNMOUNTING_SIGTERM:
|
|
|
|
mount_enter_dead_or_mounted(m, f);
|
|
|
|
break;
|
2010-04-10 17:53:17 +02:00
|
|
|
|
2019-08-25 15:08:47 +02:00
|
|
|
case MOUNT_CLEANING:
|
|
|
|
if (m->clean_result == MOUNT_SUCCESS)
|
|
|
|
m->clean_result = f;
|
|
|
|
|
|
|
|
mount_enter_dead(m, MOUNT_SUCCESS);
|
|
|
|
break;
|
|
|
|
|
2010-04-10 17:53:17 +02:00
|
|
|
default:
|
|
|
|
assert_not_reached("Uh, control process died at wrong time.");
|
|
|
|
}
|
2010-08-20 02:26:05 +02:00
|
|
|
|
|
|
|
/* Notify clients about changed exit status */
|
|
|
|
unit_add_to_dbus_queue(u);
|
2010-04-10 17:53:17 +02:00
|
|
|
}
|
|
|
|
|
2013-11-19 21:12:59 +01:00
|
|
|
static int mount_dispatch_timer(sd_event_source *source, usec_t usec, void *userdata) {
|
|
|
|
Mount *m = MOUNT(userdata);
|
2010-04-10 17:53:17 +02:00
|
|
|
|
|
|
|
assert(m);
|
2013-11-19 21:12:59 +01:00
|
|
|
assert(m->timer_event_source == source);
|
2010-04-10 17:53:17 +02:00
|
|
|
|
|
|
|
switch (m->state) {
|
|
|
|
|
|
|
|
case MOUNT_MOUNTING:
|
|
|
|
case MOUNT_MOUNTING_DONE:
|
mount: rework mount state engine
This changes the mount unit state engine in the following ways:
1. The MOUNT_MOUNTING_SIGTERM and MOUNT_MOUNTING_SIGKILL are removed.
They have been pretty much equivalent to MOUNT_UNMOUNTING_SIGTERM and
MOUNT_UNMOUNTING_SIGKILL in what they do, and the outcome has been
the same as well: the unit is stopped. Hence, let's simplify things a
bit, and merge them. Note that we keep
MOUNT_REMOUNTING_{SIGTERM|SIGKILL} however, as those states have a
different outcome: the unit remains started.
2. mount_enter_signal() will now honour the SendSIGKILL= option of the
mount unit if it was set. This was previously done already when we
entered the signal states through a timeout, and was simply missing
here.
3. A new helper function mount_enter_dead_or_mounted() is added that
places the mount unit in either MOUNT_DEAD or MOUNT_MOUNTED,
depending on what the kernel thinks about the mount's state. This
function is called at various places now, wherever we finished an
operation, and want to make sure our own state reflects again what
the kernel thinks. Previously we had very similar code in a number of
places and in other places didn't recheck the kernel state. Let's do
that with the same logic and function at all relevant places now.
4. Rework mount_stop(): never forget about running control processes.
Instead: when we have a start (i.e. a /bin/mount) process running,
and are asked to stop, then enter the kill states for it, so that it
gets cleaned up. This fixes #6048. Moreover, when we have a reload
process running convert the possible states into the relevant
unmounting states, so that we can properly execute the requested
operation.
Fixes #6048
2017-09-25 19:13:37 +02:00
|
|
|
log_unit_warning(UNIT(m), "Mounting timed out. Terminating.");
|
|
|
|
mount_enter_signal(m, MOUNT_UNMOUNTING_SIGTERM, MOUNT_FAILURE_TIMEOUT);
|
2010-04-10 17:53:17 +02:00
|
|
|
break;
|
|
|
|
|
|
|
|
case MOUNT_REMOUNTING:
|
2017-10-02 15:40:15 +02:00
|
|
|
log_unit_warning(UNIT(m), "Remounting timed out. Terminating remount process.");
|
mount: rework mount state engine
This changes the mount unit state engine in the following ways:
1. The MOUNT_MOUNTING_SIGTERM and MOUNT_MOUNTING_SIGKILL are removed.
They have been pretty much equivalent to MOUNT_UNMOUNTING_SIGTERM and
MOUNT_UNMOUNTING_SIGKILL in what they do, and the outcome has been
the same as well: the unit is stopped. Hence, let's simplify things a
bit, and merge them. Note that we keep
MOUNT_REMOUNTING_{SIGTERM|SIGKILL} however, as those states have a
different outcome: the unit remains started.
2. mount_enter_signal() will now honour the SendSIGKILL= option of the
mount unit if it was set. This was previously done already when we
entered the signal states through a timeout, and was simply missing
here.
3. A new helper function mount_enter_dead_or_mounted() is added that
places the mount unit in either MOUNT_DEAD or MOUNT_MOUNTED,
depending on what the kernel thinks about the mount's state. This
function is called at various places now, wherever we finished an
operation, and want to make sure our own state reflects again what
the kernel thinks. Previously we had very similar code in a number of
places and in other places didn't recheck the kernel state. Let's do
that with the same logic and function at all relevant places now.
4. Rework mount_stop(): never forget about running control processes.
Instead: when we have a start (i.e. a /bin/mount) process running,
and are asked to stop, then enter the kill states for it, so that it
gets cleaned up. This fixes #6048. Moreover, when we have a reload
process running convert the possible states into the relevant
unmounting states, so that we can properly execute the requested
operation.
Fixes #6048
2017-09-25 19:13:37 +02:00
|
|
|
mount_set_reload_result(m, MOUNT_FAILURE_TIMEOUT);
|
|
|
|
mount_enter_signal(m, MOUNT_REMOUNTING_SIGTERM, MOUNT_SUCCESS);
|
2010-04-10 17:53:17 +02:00
|
|
|
break;
|
|
|
|
|
mount: rework mount state engine
This changes the mount unit state engine in the following ways:
1. The MOUNT_MOUNTING_SIGTERM and MOUNT_MOUNTING_SIGKILL are removed.
They have been pretty much equivalent to MOUNT_UNMOUNTING_SIGTERM and
MOUNT_UNMOUNTING_SIGKILL in what they do, and the outcome has been
the same as well: the unit is stopped. Hence, let's simplify things a
bit, and merge them. Note that we keep
MOUNT_REMOUNTING_{SIGTERM|SIGKILL} however, as those states have a
different outcome: the unit remains started.
2. mount_enter_signal() will now honour the SendSIGKILL= option of the
mount unit if it was set. This was previously done already when we
entered the signal states through a timeout, and was simply missing
here.
3. A new helper function mount_enter_dead_or_mounted() is added that
places the mount unit in either MOUNT_DEAD or MOUNT_MOUNTED,
depending on what the kernel thinks about the mount's state. This
function is called at various places now, wherever we finished an
operation, and want to make sure our own state reflects again what
the kernel thinks. Previously we had very similar code in a number of
places and in other places didn't recheck the kernel state. Let's do
that with the same logic and function at all relevant places now.
4. Rework mount_stop(): never forget about running control processes.
Instead: when we have a start (i.e. a /bin/mount) process running,
and are asked to stop, then enter the kill states for it, so that it
gets cleaned up. This fixes #6048. Moreover, when we have a reload
process running convert the possible states into the relevant
unmounting states, so that we can properly execute the requested
operation.
Fixes #6048
2017-09-25 19:13:37 +02:00
|
|
|
case MOUNT_REMOUNTING_SIGTERM:
|
|
|
|
mount_set_reload_result(m, MOUNT_FAILURE_TIMEOUT);
|
2010-04-10 17:53:17 +02:00
|
|
|
|
2012-07-19 23:47:10 +02:00
|
|
|
if (m->kill_context.send_sigkill) {
|
mount: rework mount state engine
This changes the mount unit state engine in the following ways:
1. The MOUNT_MOUNTING_SIGTERM and MOUNT_MOUNTING_SIGKILL are removed.
They have been pretty much equivalent to MOUNT_UNMOUNTING_SIGTERM and
MOUNT_UNMOUNTING_SIGKILL in what they do, and the outcome has been
the same as well: the unit is stopped. Hence, let's simplify things a
bit, and merge them. Note that we keep
MOUNT_REMOUNTING_{SIGTERM|SIGKILL} however, as those states have a
different outcome: the unit remains started.
2. mount_enter_signal() will now honour the SendSIGKILL= option of the
mount unit if it was set. This was previously done already when we
entered the signal states through a timeout, and was simply missing
here.
3. A new helper function mount_enter_dead_or_mounted() is added that
places the mount unit in either MOUNT_DEAD or MOUNT_MOUNTED,
depending on what the kernel thinks about the mount's state. This
function is called at various places now, wherever we finished an
operation, and want to make sure our own state reflects again what
the kernel thinks. Previously we had very similar code in a number of
places and in other places didn't recheck the kernel state. Let's do
that with the same logic and function at all relevant places now.
4. Rework mount_stop(): never forget about running control processes.
Instead: when we have a start (i.e. a /bin/mount) process running,
and are asked to stop, then enter the kill states for it, so that it
gets cleaned up. This fixes #6048. Moreover, when we have a reload
process running convert the possible states into the relevant
unmounting states, so that we can properly execute the requested
operation.
Fixes #6048
2017-09-25 19:13:37 +02:00
|
|
|
log_unit_warning(UNIT(m), "Remounting timed out. Killing.");
|
|
|
|
mount_enter_signal(m, MOUNT_REMOUNTING_SIGKILL, MOUNT_SUCCESS);
|
2011-01-18 22:55:54 +01:00
|
|
|
} else {
|
mount: rework mount state engine
This changes the mount unit state engine in the following ways:
1. The MOUNT_MOUNTING_SIGTERM and MOUNT_MOUNTING_SIGKILL are removed.
They have been pretty much equivalent to MOUNT_UNMOUNTING_SIGTERM and
MOUNT_UNMOUNTING_SIGKILL in what they do, and the outcome has been
the same as well: the unit is stopped. Hence, let's simplify things a
bit, and merge them. Note that we keep
MOUNT_REMOUNTING_{SIGTERM|SIGKILL} however, as those states have a
different outcome: the unit remains started.
2. mount_enter_signal() will now honour the SendSIGKILL= option of the
mount unit if it was set. This was previously done already when we
entered the signal states through a timeout, and was simply missing
here.
3. A new helper function mount_enter_dead_or_mounted() is added that
places the mount unit in either MOUNT_DEAD or MOUNT_MOUNTED,
depending on what the kernel thinks about the mount's state. This
function is called at various places now, wherever we finished an
operation, and want to make sure our own state reflects again what
the kernel thinks. Previously we had very similar code in a number of
places and in other places didn't recheck the kernel state. Let's do
that with the same logic and function at all relevant places now.
4. Rework mount_stop(): never forget about running control processes.
Instead: when we have a start (i.e. a /bin/mount) process running,
and are asked to stop, then enter the kill states for it, so that it
gets cleaned up. This fixes #6048. Moreover, when we have a reload
process running convert the possible states into the relevant
unmounting states, so that we can properly execute the requested
operation.
Fixes #6048
2017-09-25 19:13:37 +02:00
|
|
|
log_unit_warning(UNIT(m), "Remounting timed out. Skipping SIGKILL. Ignoring.");
|
|
|
|
mount_enter_dead_or_mounted(m, MOUNT_SUCCESS);
|
2011-01-18 22:55:54 +01:00
|
|
|
}
|
2010-04-10 17:53:17 +02:00
|
|
|
break;
|
|
|
|
|
mount: rework mount state engine
This changes the mount unit state engine in the following ways:
1. The MOUNT_MOUNTING_SIGTERM and MOUNT_MOUNTING_SIGKILL are removed.
They have been pretty much equivalent to MOUNT_UNMOUNTING_SIGTERM and
MOUNT_UNMOUNTING_SIGKILL in what they do, and the outcome has been
the same as well: the unit is stopped. Hence, let's simplify things a
bit, and merge them. Note that we keep
MOUNT_REMOUNTING_{SIGTERM|SIGKILL} however, as those states have a
different outcome: the unit remains started.
2. mount_enter_signal() will now honour the SendSIGKILL= option of the
mount unit if it was set. This was previously done already when we
entered the signal states through a timeout, and was simply missing
here.
3. A new helper function mount_enter_dead_or_mounted() is added that
places the mount unit in either MOUNT_DEAD or MOUNT_MOUNTED,
depending on what the kernel thinks about the mount's state. This
function is called at various places now, wherever we finished an
operation, and want to make sure our own state reflects again what
the kernel thinks. Previously we had very similar code in a number of
places and in other places didn't recheck the kernel state. Let's do
that with the same logic and function at all relevant places now.
4. Rework mount_stop(): never forget about running control processes.
Instead: when we have a start (i.e. a /bin/mount) process running,
and are asked to stop, then enter the kill states for it, so that it
gets cleaned up. This fixes #6048. Moreover, when we have a reload
process running convert the possible states into the relevant
unmounting states, so that we can properly execute the requested
operation.
Fixes #6048
2017-09-25 19:13:37 +02:00
|
|
|
case MOUNT_REMOUNTING_SIGKILL:
|
|
|
|
mount_set_reload_result(m, MOUNT_FAILURE_TIMEOUT);
|
2011-01-18 22:55:54 +01:00
|
|
|
|
mount: rework mount state engine
This changes the mount unit state engine in the following ways:
1. The MOUNT_MOUNTING_SIGTERM and MOUNT_MOUNTING_SIGKILL are removed.
They have been pretty much equivalent to MOUNT_UNMOUNTING_SIGTERM and
MOUNT_UNMOUNTING_SIGKILL in what they do, and the outcome has been
the same as well: the unit is stopped. Hence, let's simplify things a
bit, and merge them. Note that we keep
MOUNT_REMOUNTING_{SIGTERM|SIGKILL} however, as those states have a
different outcome: the unit remains started.
2. mount_enter_signal() will now honour the SendSIGKILL= option of the
mount unit if it was set. This was previously done already when we
entered the signal states through a timeout, and was simply missing
here.
3. A new helper function mount_enter_dead_or_mounted() is added that
places the mount unit in either MOUNT_DEAD or MOUNT_MOUNTED,
depending on what the kernel thinks about the mount's state. This
function is called at various places now, wherever we finished an
operation, and want to make sure our own state reflects again what
the kernel thinks. Previously we had very similar code in a number of
places and in other places didn't recheck the kernel state. Let's do
that with the same logic and function at all relevant places now.
4. Rework mount_stop(): never forget about running control processes.
Instead: when we have a start (i.e. a /bin/mount) process running,
and are asked to stop, then enter the kill states for it, so that it
gets cleaned up. This fixes #6048. Moreover, when we have a reload
process running convert the possible states into the relevant
unmounting states, so that we can properly execute the requested
operation.
Fixes #6048
2017-09-25 19:13:37 +02:00
|
|
|
log_unit_warning(UNIT(m), "Mount process still around after SIGKILL. Ignoring.");
|
|
|
|
mount_enter_dead_or_mounted(m, MOUNT_SUCCESS);
|
|
|
|
break;
|
|
|
|
|
|
|
|
case MOUNT_UNMOUNTING:
|
2017-10-02 15:40:15 +02:00
|
|
|
log_unit_warning(UNIT(m), "Unmounting timed out. Terminating.");
|
mount: rework mount state engine
This changes the mount unit state engine in the following ways:
1. The MOUNT_MOUNTING_SIGTERM and MOUNT_MOUNTING_SIGKILL are removed.
They have been pretty much equivalent to MOUNT_UNMOUNTING_SIGTERM and
MOUNT_UNMOUNTING_SIGKILL in what they do, and the outcome has been
the same as well: the unit is stopped. Hence, let's simplify things a
bit, and merge them. Note that we keep
MOUNT_REMOUNTING_{SIGTERM|SIGKILL} however, as those states have a
different outcome: the unit remains started.
2. mount_enter_signal() will now honour the SendSIGKILL= option of the
mount unit if it was set. This was previously done already when we
entered the signal states through a timeout, and was simply missing
here.
3. A new helper function mount_enter_dead_or_mounted() is added that
places the mount unit in either MOUNT_DEAD or MOUNT_MOUNTED,
depending on what the kernel thinks about the mount's state. This
function is called at various places now, wherever we finished an
operation, and want to make sure our own state reflects again what
the kernel thinks. Previously we had very similar code in a number of
places and in other places didn't recheck the kernel state. Let's do
that with the same logic and function at all relevant places now.
4. Rework mount_stop(): never forget about running control processes.
Instead: when we have a start (i.e. a /bin/mount) process running,
and are asked to stop, then enter the kill states for it, so that it
gets cleaned up. This fixes #6048. Moreover, when we have a reload
process running convert the possible states into the relevant
unmounting states, so that we can properly execute the requested
operation.
Fixes #6048
2017-09-25 19:13:37 +02:00
|
|
|
mount_enter_signal(m, MOUNT_UNMOUNTING_SIGTERM, MOUNT_FAILURE_TIMEOUT);
|
2010-04-10 17:53:17 +02:00
|
|
|
break;
|
|
|
|
|
|
|
|
case MOUNT_UNMOUNTING_SIGTERM:
|
2012-07-19 23:47:10 +02:00
|
|
|
if (m->kill_context.send_sigkill) {
|
mount: rework mount state engine
This changes the mount unit state engine in the following ways:
1. The MOUNT_MOUNTING_SIGTERM and MOUNT_MOUNTING_SIGKILL are removed.
They have been pretty much equivalent to MOUNT_UNMOUNTING_SIGTERM and
MOUNT_UNMOUNTING_SIGKILL in what they do, and the outcome has been
the same as well: the unit is stopped. Hence, let's simplify things a
bit, and merge them. Note that we keep
MOUNT_REMOUNTING_{SIGTERM|SIGKILL} however, as those states have a
different outcome: the unit remains started.
2. mount_enter_signal() will now honour the SendSIGKILL= option of the
mount unit if it was set. This was previously done already when we
entered the signal states through a timeout, and was simply missing
here.
3. A new helper function mount_enter_dead_or_mounted() is added that
places the mount unit in either MOUNT_DEAD or MOUNT_MOUNTED,
depending on what the kernel thinks about the mount's state. This
function is called at various places now, wherever we finished an
operation, and want to make sure our own state reflects again what
the kernel thinks. Previously we had very similar code in a number of
places and in other places didn't recheck the kernel state. Let's do
that with the same logic and function at all relevant places now.
4. Rework mount_stop(): never forget about running control processes.
Instead: when we have a start (i.e. a /bin/mount) process running,
and are asked to stop, then enter the kill states for it, so that it
gets cleaned up. This fixes #6048. Moreover, when we have a reload
process running convert the possible states into the relevant
unmounting states, so that we can properly execute the requested
operation.
Fixes #6048
2017-09-25 19:13:37 +02:00
|
|
|
log_unit_warning(UNIT(m), "Mount process timed out. Killing.");
|
2012-02-03 03:10:56 +01:00
|
|
|
mount_enter_signal(m, MOUNT_UNMOUNTING_SIGKILL, MOUNT_FAILURE_TIMEOUT);
|
2011-01-18 22:55:54 +01:00
|
|
|
} else {
|
mount: rework mount state engine
This changes the mount unit state engine in the following ways:
1. The MOUNT_MOUNTING_SIGTERM and MOUNT_MOUNTING_SIGKILL are removed.
They have been pretty much equivalent to MOUNT_UNMOUNTING_SIGTERM and
MOUNT_UNMOUNTING_SIGKILL in what they do, and the outcome has been
the same as well: the unit is stopped. Hence, let's simplify things a
bit, and merge them. Note that we keep
MOUNT_REMOUNTING_{SIGTERM|SIGKILL} however, as those states have a
different outcome: the unit remains started.
2. mount_enter_signal() will now honour the SendSIGKILL= option of the
mount unit if it was set. This was previously done already when we
entered the signal states through a timeout, and was simply missing
here.
3. A new helper function mount_enter_dead_or_mounted() is added that
places the mount unit in either MOUNT_DEAD or MOUNT_MOUNTED,
depending on what the kernel thinks about the mount's state. This
function is called at various places now, wherever we finished an
operation, and want to make sure our own state reflects again what
the kernel thinks. Previously we had very similar code in a number of
places and in other places didn't recheck the kernel state. Let's do
that with the same logic and function at all relevant places now.
4. Rework mount_stop(): never forget about running control processes.
Instead: when we have a start (i.e. a /bin/mount) process running,
and are asked to stop, then enter the kill states for it, so that it
gets cleaned up. This fixes #6048. Moreover, when we have a reload
process running convert the possible states into the relevant
unmounting states, so that we can properly execute the requested
operation.
Fixes #6048
2017-09-25 19:13:37 +02:00
|
|
|
log_unit_warning(UNIT(m), "Mount process timed out. Skipping SIGKILL. Ignoring.");
|
|
|
|
mount_enter_dead_or_mounted(m, MOUNT_FAILURE_TIMEOUT);
|
2011-01-18 22:55:54 +01:00
|
|
|
}
|
2010-04-10 17:53:17 +02:00
|
|
|
break;
|
|
|
|
|
|
|
|
case MOUNT_UNMOUNTING_SIGKILL:
|
mount: rework mount state engine
This changes the mount unit state engine in the following ways:
1. The MOUNT_MOUNTING_SIGTERM and MOUNT_MOUNTING_SIGKILL are removed.
They have been pretty much equivalent to MOUNT_UNMOUNTING_SIGTERM and
MOUNT_UNMOUNTING_SIGKILL in what they do, and the outcome has been
the same as well: the unit is stopped. Hence, let's simplify things a
bit, and merge them. Note that we keep
MOUNT_REMOUNTING_{SIGTERM|SIGKILL} however, as those states have a
different outcome: the unit remains started.
2. mount_enter_signal() will now honour the SendSIGKILL= option of the
mount unit if it was set. This was previously done already when we
entered the signal states through a timeout, and was simply missing
here.
3. A new helper function mount_enter_dead_or_mounted() is added that
places the mount unit in either MOUNT_DEAD or MOUNT_MOUNTED,
depending on what the kernel thinks about the mount's state. This
function is called at various places now, wherever we finished an
operation, and want to make sure our own state reflects again what
the kernel thinks. Previously we had very similar code in a number of
places and in other places didn't recheck the kernel state. Let's do
that with the same logic and function at all relevant places now.
4. Rework mount_stop(): never forget about running control processes.
Instead: when we have a start (i.e. a /bin/mount) process running,
and are asked to stop, then enter the kill states for it, so that it
gets cleaned up. This fixes #6048. Moreover, when we have a reload
process running convert the possible states into the relevant
unmounting states, so that we can properly execute the requested
operation.
Fixes #6048
2017-09-25 19:13:37 +02:00
|
|
|
log_unit_warning(UNIT(m), "Mount process still around after SIGKILL. Ignoring.");
|
|
|
|
mount_enter_dead_or_mounted(m, MOUNT_FAILURE_TIMEOUT);
|
2010-04-10 17:53:17 +02:00
|
|
|
break;
|
|
|
|
|
2019-08-25 15:08:47 +02:00
|
|
|
case MOUNT_CLEANING:
|
|
|
|
log_unit_warning(UNIT(m), "Cleaning timed out. killing.");
|
|
|
|
|
|
|
|
if (m->clean_result == MOUNT_SUCCESS)
|
|
|
|
m->clean_result = MOUNT_FAILURE_TIMEOUT;
|
|
|
|
|
|
|
|
mount_enter_signal(m, MOUNT_UNMOUNTING_SIGKILL, 0);
|
|
|
|
break;
|
|
|
|
|
2010-04-10 17:53:17 +02:00
|
|
|
default:
|
|
|
|
assert_not_reached("Timeout at wrong time.");
|
|
|
|
}
|
2013-11-19 21:12:59 +01:00
|
|
|
|
|
|
|
return 0;
|
2010-04-10 17:53:17 +02:00
|
|
|
}
|
|
|
|
|
2017-01-16 21:19:13 +01:00
|
|
|
static int mount_setup_new_unit(
|
2018-11-28 12:50:01 +01:00
|
|
|
Manager *m,
|
|
|
|
const char *name,
|
2017-01-16 21:19:13 +01:00
|
|
|
const char *what,
|
|
|
|
const char *where,
|
|
|
|
const char *options,
|
|
|
|
const char *fstype,
|
2018-11-28 19:06:30 +01:00
|
|
|
MountProcFlags *ret_flags,
|
2018-11-28 12:50:01 +01:00
|
|
|
Unit **ret) {
|
2017-01-16 21:19:13 +01:00
|
|
|
|
2018-11-28 12:50:01 +01:00
|
|
|
_cleanup_(unit_freep) Unit *u = NULL;
|
2018-11-28 12:46:35 +01:00
|
|
|
int r;
|
2017-01-16 21:19:13 +01:00
|
|
|
|
2018-11-28 12:50:01 +01:00
|
|
|
assert(m);
|
|
|
|
assert(name);
|
2018-11-28 19:06:30 +01:00
|
|
|
assert(ret_flags);
|
2018-11-28 12:50:01 +01:00
|
|
|
assert(ret);
|
|
|
|
|
|
|
|
r = unit_new_for_name(m, sizeof(Mount), name, &u);
|
|
|
|
if (r < 0)
|
|
|
|
return r;
|
2017-01-16 21:19:13 +01:00
|
|
|
|
2018-11-28 14:40:56 +01:00
|
|
|
r = free_and_strdup(&u->source_path, "/proc/self/mountinfo");
|
|
|
|
if (r < 0)
|
|
|
|
return r;
|
2017-01-16 21:19:13 +01:00
|
|
|
|
2018-11-28 14:40:56 +01:00
|
|
|
r = free_and_strdup(&MOUNT(u)->where, where);
|
|
|
|
if (r < 0)
|
|
|
|
return r;
|
2017-01-16 21:19:13 +01:00
|
|
|
|
2019-07-18 17:02:30 +02:00
|
|
|
r = update_parameters_proc_self_mountinfo(MOUNT(u), what, options, fstype);
|
2018-11-28 12:46:35 +01:00
|
|
|
if (r < 0)
|
|
|
|
return r;
|
2017-01-16 21:19:13 +01:00
|
|
|
|
2018-11-28 14:51:04 +01:00
|
|
|
/* This unit was generated because /proc/self/mountinfo reported it. Remember this, so that by the time we load
|
|
|
|
* the unit file for it (and thus add in extra deps right after) we know what source to attributes the deps
|
|
|
|
* to.*/
|
|
|
|
MOUNT(u)->from_proc_self_mountinfo = true;
|
|
|
|
|
|
|
|
/* We have only allocated the stub now, let's enqueue this unit for loading now, so that everything else is
|
|
|
|
* loaded in now. */
|
2017-01-20 01:46:47 +01:00
|
|
|
unit_add_to_load_queue(u);
|
2018-11-28 14:42:21 +01:00
|
|
|
|
2018-11-28 19:06:30 +01:00
|
|
|
*ret_flags = MOUNT_PROC_IS_MOUNTED | MOUNT_PROC_JUST_MOUNTED | MOUNT_PROC_JUST_CHANGED;
|
2018-11-28 12:50:01 +01:00
|
|
|
*ret = TAKE_PTR(u);
|
2017-01-16 21:19:13 +01:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int mount_setup_existing_unit(
|
|
|
|
Unit *u,
|
|
|
|
const char *what,
|
|
|
|
const char *where,
|
|
|
|
const char *options,
|
|
|
|
const char *fstype,
|
2018-11-28 19:06:30 +01:00
|
|
|
MountProcFlags *ret_flags) {
|
2017-01-16 21:19:13 +01:00
|
|
|
|
2018-11-28 12:46:35 +01:00
|
|
|
int r;
|
2017-01-16 21:19:13 +01:00
|
|
|
|
|
|
|
assert(u);
|
2020-01-14 16:25:45 +01:00
|
|
|
assert(ret_flags);
|
2017-01-16 21:19:13 +01:00
|
|
|
|
|
|
|
if (!MOUNT(u)->where) {
|
|
|
|
MOUNT(u)->where = strdup(where);
|
|
|
|
if (!MOUNT(u)->where)
|
|
|
|
return -ENOMEM;
|
|
|
|
}
|
|
|
|
|
2020-01-14 16:25:45 +01:00
|
|
|
/* In case we have multiple mounts established on the same mount point, let's merge flags set already
|
|
|
|
* for the current unit. Note that the flags field is reset on each iteration of reading
|
|
|
|
* /proc/self/mountinfo, hence we know for sure anything already set here is from the current
|
|
|
|
* iteration and thus worthy of taking into account. */
|
|
|
|
MountProcFlags flags =
|
|
|
|
MOUNT(u)->proc_flags | MOUNT_PROC_IS_MOUNTED;
|
|
|
|
|
2019-07-18 17:02:30 +02:00
|
|
|
r = update_parameters_proc_self_mountinfo(MOUNT(u), what, options, fstype);
|
2018-11-28 12:46:35 +01:00
|
|
|
if (r < 0)
|
|
|
|
return r;
|
2018-11-28 19:06:30 +01:00
|
|
|
if (r > 0)
|
|
|
|
flags |= MOUNT_PROC_JUST_CHANGED;
|
2017-01-16 21:19:13 +01:00
|
|
|
|
2020-01-14 16:25:45 +01:00
|
|
|
/* There are two conditions when we consider a mount point just mounted: when we haven't seen it in
|
|
|
|
* /proc/self/mountinfo before or when MOUNT_MOUNTING is our current state. Why bother with the
|
|
|
|
* latter? Shouldn't that be covered by the former? No, during reload it is not because we might then
|
|
|
|
* encounter a new /proc/self/mountinfo in combination with an old mount unit state (since it stems
|
|
|
|
* from the serialized state), and need to catch up. Since we know that the MOUNT_MOUNTING state is
|
|
|
|
* reached when we wait for the mount to appear we hence can assume that if we are in it, we are
|
|
|
|
* actually seeing it established for the first time. */
|
|
|
|
if (!MOUNT(u)->from_proc_self_mountinfo || MOUNT(u)->state == MOUNT_MOUNTING)
|
2018-11-28 19:06:30 +01:00
|
|
|
flags |= MOUNT_PROC_JUST_MOUNTED;
|
2019-01-08 19:35:55 +01:00
|
|
|
|
|
|
|
MOUNT(u)->from_proc_self_mountinfo = true;
|
2017-01-16 21:19:13 +01:00
|
|
|
|
2018-11-28 14:58:18 +01:00
|
|
|
if (IN_SET(u->load_state, UNIT_NOT_FOUND, UNIT_BAD_SETTING, UNIT_ERROR)) {
|
|
|
|
/* The unit was previously not found or otherwise not loaded. Now that the unit shows up in
|
|
|
|
* /proc/self/mountinfo we should reconsider it this, hence set it to UNIT_LOADED. */
|
2017-01-16 21:19:13 +01:00
|
|
|
u->load_state = UNIT_LOADED;
|
|
|
|
u->load_error = 0;
|
|
|
|
|
2018-11-28 19:06:30 +01:00
|
|
|
flags |= MOUNT_PROC_JUST_CHANGED;
|
2017-01-16 21:19:13 +01:00
|
|
|
}
|
|
|
|
|
2018-11-28 19:06:30 +01:00
|
|
|
if (FLAGS_SET(flags, MOUNT_PROC_JUST_CHANGED)) {
|
2018-11-28 14:56:27 +01:00
|
|
|
/* If things changed, then make sure that all deps are regenerated. Let's
|
|
|
|
* first remove all automatic deps, and then add in the new ones. */
|
|
|
|
|
|
|
|
unit_remove_dependencies(u, UNIT_DEPENDENCY_MOUNTINFO_IMPLICIT);
|
|
|
|
|
2019-11-15 14:00:54 +01:00
|
|
|
r = mount_add_non_exec_dependencies(MOUNT(u));
|
2018-11-28 14:56:27 +01:00
|
|
|
if (r < 0)
|
|
|
|
return r;
|
|
|
|
}
|
2017-01-16 21:19:13 +01:00
|
|
|
|
2018-11-28 19:06:30 +01:00
|
|
|
*ret_flags = flags;
|
2017-01-16 21:19:13 +01:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2015-02-27 21:55:08 +01:00
|
|
|
static int mount_setup_unit(
|
2010-04-10 17:53:17 +02:00
|
|
|
Manager *m,
|
|
|
|
const char *what,
|
|
|
|
const char *where,
|
|
|
|
const char *options,
|
|
|
|
const char *fstype,
|
|
|
|
bool set_flags) {
|
2014-01-07 00:25:05 +01:00
|
|
|
|
2017-01-16 21:19:13 +01:00
|
|
|
_cleanup_free_ char *e = NULL;
|
2018-11-28 19:06:30 +01:00
|
|
|
MountProcFlags flags;
|
2014-01-07 00:25:05 +01:00
|
|
|
Unit *u;
|
|
|
|
int r;
|
2010-01-29 02:07:41 +01:00
|
|
|
|
2010-01-29 03:18:09 +01:00
|
|
|
assert(m);
|
2010-01-29 02:07:41 +01:00
|
|
|
assert(what);
|
|
|
|
assert(where);
|
2010-04-10 17:53:17 +02:00
|
|
|
assert(options);
|
|
|
|
assert(fstype);
|
|
|
|
|
|
|
|
/* Ignore API mount points. They should never be referenced in
|
|
|
|
* dependencies ever. */
|
2011-04-05 23:39:21 +02:00
|
|
|
if (mount_point_is_api(where) || mount_point_ignore(where))
|
2010-11-11 11:15:16 +01:00
|
|
|
return 0;
|
2010-01-29 02:07:41 +01:00
|
|
|
|
2010-04-16 23:24:39 +02:00
|
|
|
if (streq(fstype, "autofs"))
|
|
|
|
return 0;
|
|
|
|
|
2010-05-14 02:29:45 +02:00
|
|
|
/* probably some kind of swap, ignore */
|
|
|
|
if (!is_path(where))
|
2010-01-29 02:07:41 +01:00
|
|
|
return 0;
|
|
|
|
|
2020-05-25 00:37:26 +02:00
|
|
|
/* Mount unit names have to be (like all other unit names) short enough to fit into file names. This
|
|
|
|
* means there's a good chance that overly long mount point paths after mangling them to look like a
|
|
|
|
* unit name would result in unit names we don't actually consider valid. This should be OK however
|
|
|
|
* as such long mount point paths should not happen on regular systems — and if they appear
|
|
|
|
* nonetheless they are generally synthesized by software, and thus managed by that other
|
|
|
|
* software. Having such long names just means you cannot use systemd to manage those specific mount
|
|
|
|
* points, which should be an OK restriction to make. After all we don't have to be able to manage
|
|
|
|
* all mount points in the world — as long as we don't choke on them when we encounter them. */
|
2015-04-30 20:21:00 +02:00
|
|
|
r = unit_name_from_path(where, ".mount", &e);
|
2020-05-25 00:37:26 +02:00
|
|
|
if (r < 0) {
|
|
|
|
static RateLimit rate_limit = { /* Let's log about this at warning level at most once every
|
|
|
|
* 5s. Given that we generate this whenever we read the file
|
|
|
|
* otherwise we probably shouldn't flood the logs with
|
|
|
|
* this */
|
|
|
|
.interval = 5 * USEC_PER_SEC,
|
|
|
|
.burst = 1,
|
|
|
|
};
|
|
|
|
|
|
|
|
return log_struct_errno(
|
|
|
|
ratelimit_below(&rate_limit) ? LOG_WARNING : LOG_DEBUG, r,
|
|
|
|
"MESSAGE_ID=" SD_MESSAGE_MOUNT_POINT_PATH_NOT_SUITABLE_STR,
|
|
|
|
"MOUNT_POINT=%s", where,
|
|
|
|
LOG_MESSAGE("Failed to generate valid unit name from path '%s', ignoring mount point: %m", where));
|
|
|
|
}
|
2010-01-29 02:07:41 +01:00
|
|
|
|
2012-01-15 10:53:49 +01:00
|
|
|
u = manager_get_unit(m, e);
|
2018-11-28 12:50:01 +01:00
|
|
|
if (u)
|
2017-01-16 21:19:13 +01:00
|
|
|
r = mount_setup_existing_unit(u, what, where, options, fstype, &flags);
|
2018-11-28 12:50:01 +01:00
|
|
|
else
|
|
|
|
/* First time we see this mount point meaning that it's not been initiated by a mount unit but rather
|
|
|
|
* by the sysadmin having called mount(8) directly. */
|
|
|
|
r = mount_setup_new_unit(m, e, what, where, options, fstype, &flags, &u);
|
2017-01-16 21:19:13 +01:00
|
|
|
if (r < 0)
|
2020-05-25 00:37:26 +02:00
|
|
|
return log_warning_errno(r, "Failed to set up mount unit for '%s': %m", where);
|
2014-02-26 04:27:50 +01:00
|
|
|
|
2018-11-28 19:06:30 +01:00
|
|
|
/* If the mount changed properties or state, let's notify our clients */
|
|
|
|
if (flags & (MOUNT_PROC_JUST_CHANGED|MOUNT_PROC_JUST_MOUNTED))
|
2014-02-26 04:27:50 +01:00
|
|
|
unit_add_to_dbus_queue(u);
|
2010-02-05 00:38:41 +01:00
|
|
|
|
2018-11-28 19:06:30 +01:00
|
|
|
if (set_flags)
|
|
|
|
MOUNT(u)->proc_flags = flags;
|
|
|
|
|
2010-01-29 02:07:41 +01:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2010-01-29 06:04:08 +01:00
|
|
|
static int mount_load_proc_self_mountinfo(Manager *m, bool set_flags) {
|
2019-04-04 13:36:19 +02:00
|
|
|
_cleanup_(mnt_free_tablep) struct libmnt_table *table = NULL;
|
|
|
|
_cleanup_(mnt_free_iterp) struct libmnt_iter *iter = NULL;
|
2018-11-28 12:41:44 +01:00
|
|
|
int r;
|
2010-01-29 02:07:41 +01:00
|
|
|
|
|
|
|
assert(m);
|
|
|
|
|
2019-04-05 14:43:06 +02:00
|
|
|
r = libmount_parse(NULL, NULL, &table, &iter);
|
2014-11-28 19:02:15 +01:00
|
|
|
if (r < 0)
|
2015-02-27 21:55:08 +01:00
|
|
|
return log_error_errno(r, "Failed to parse /proc/self/mountinfo: %m");
|
2010-04-10 17:53:17 +02:00
|
|
|
|
2014-11-28 19:02:15 +01:00
|
|
|
for (;;) {
|
2018-03-14 11:32:30 +01:00
|
|
|
struct libmnt_fs *fs;
|
2014-11-24 05:33:37 +01:00
|
|
|
const char *device, *path, *options, *fstype;
|
2010-01-29 02:07:41 +01:00
|
|
|
|
2019-04-04 13:36:19 +02:00
|
|
|
r = mnt_table_next_fs(table, iter, &fs);
|
|
|
|
if (r == 1)
|
2014-11-28 19:02:15 +01:00
|
|
|
break;
|
2019-04-04 13:36:19 +02:00
|
|
|
if (r < 0)
|
|
|
|
return log_error_errno(r, "Failed to get next entry from /proc/self/mountinfo: %m");
|
2014-11-28 19:02:15 +01:00
|
|
|
|
2014-11-24 05:33:37 +01:00
|
|
|
device = mnt_fs_get_source(fs);
|
|
|
|
path = mnt_fs_get_target(fs);
|
|
|
|
options = mnt_fs_get_options(fs);
|
|
|
|
fstype = mnt_fs_get_fstype(fs);
|
2010-06-02 23:03:39 +02:00
|
|
|
|
2015-06-04 15:39:49 +02:00
|
|
|
if (!device || !path)
|
|
|
|
continue;
|
|
|
|
|
2019-04-05 10:17:03 +02:00
|
|
|
device_found_node(m, device, DEVICE_FOUND_MOUNT, DEVICE_FOUND_MOUNT);
|
2015-02-27 21:55:08 +01:00
|
|
|
|
2019-04-05 10:17:03 +02:00
|
|
|
(void) mount_setup_unit(m, device, path, options, fstype, set_flags);
|
2010-01-29 02:07:41 +01:00
|
|
|
}
|
|
|
|
|
2018-11-28 12:41:44 +01:00
|
|
|
return 0;
|
2010-04-10 17:53:17 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
static void mount_shutdown(Manager *m) {
|
|
|
|
assert(m);
|
|
|
|
|
2013-11-19 21:12:59 +01:00
|
|
|
m->mount_event_source = sd_event_source_unref(m->mount_event_source);
|
|
|
|
|
2015-06-01 13:48:01 +02:00
|
|
|
mnt_unref_monitor(m->mount_monitor);
|
|
|
|
m->mount_monitor = NULL;
|
2010-01-29 02:07:41 +01:00
|
|
|
}
|
|
|
|
|
2016-02-04 00:35:43 +01:00
|
|
|
static int mount_get_timeout(Unit *u, usec_t *timeout) {
|
2014-01-27 06:57:34 +01:00
|
|
|
Mount *m = MOUNT(u);
|
2016-02-04 00:35:43 +01:00
|
|
|
usec_t t;
|
2014-01-27 06:57:34 +01:00
|
|
|
int r;
|
|
|
|
|
|
|
|
if (!m->timer_event_source)
|
|
|
|
return 0;
|
|
|
|
|
2016-02-04 00:35:43 +01:00
|
|
|
r = sd_event_source_get_time(m->timer_event_source, &t);
|
2014-01-27 06:57:34 +01:00
|
|
|
if (r < 0)
|
|
|
|
return r;
|
2016-02-04 00:35:43 +01:00
|
|
|
if (t == USEC_INFINITY)
|
|
|
|
return 0;
|
2014-01-27 06:57:34 +01:00
|
|
|
|
2016-02-04 00:35:43 +01:00
|
|
|
*timeout = t;
|
2014-01-27 06:57:34 +01:00
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
core: enumerate perpetual units in a separate per-unit-type method
Previously the enumerate() callback defined for each unit type would do
two things:
1. It would create perpetual units (i.e. -.slice, system.slice, -.mount and
init.scope)
2. It would enumerate units from /proc/self/mountinfo, /proc/swaps and
the udev database
With this change these two parts are split into two seperate methods:
enumerate() now only does #2, while enumerate_perpetual() is responsible
for #1. Why make this change? Well, perpetual units should have a
slightly different effect that those found through enumeration: as
perpetual units should be up unconditionally, perpetually and thus never
change state, they should also not pull in deps by their state changing,
not even when the state is first set to active. Thus, their state is
generally initialized through the per-device coldplug() method in
similar fashion to the deserialized state from a previous run would be
put into place. OTOH units found through regular enumeration should
result in state changes (and thus pull in deps due to state changes),
hence their state should be put in effect in the catchup() method
instead. Hence, given this difference, let's also separate the
functions, so that the rule is:
1. What is created in enumerate_perpetual() should be started in
coldplug()
2. What is created in enumerate() should be started in catchup().
2018-06-05 18:26:45 +02:00
|
|
|
static void mount_enumerate_perpetual(Manager *m) {
|
2016-10-25 00:04:55 +02:00
|
|
|
Unit *u;
|
|
|
|
int r;
|
|
|
|
|
|
|
|
assert(m);
|
|
|
|
|
|
|
|
/* Whatever happens, we know for sure that the root directory is around, and cannot go away. Let's
|
|
|
|
* unconditionally synthesize it here and mark it as perpetual. */
|
|
|
|
|
|
|
|
u = manager_get_unit(m, SPECIAL_ROOT_MOUNT);
|
|
|
|
if (!u) {
|
2016-10-25 00:29:05 +02:00
|
|
|
r = unit_new_for_name(m, sizeof(Mount), SPECIAL_ROOT_MOUNT, &u);
|
core: enumerate perpetual units in a separate per-unit-type method
Previously the enumerate() callback defined for each unit type would do
two things:
1. It would create perpetual units (i.e. -.slice, system.slice, -.mount and
init.scope)
2. It would enumerate units from /proc/self/mountinfo, /proc/swaps and
the udev database
With this change these two parts are split into two seperate methods:
enumerate() now only does #2, while enumerate_perpetual() is responsible
for #1. Why make this change? Well, perpetual units should have a
slightly different effect that those found through enumeration: as
perpetual units should be up unconditionally, perpetually and thus never
change state, they should also not pull in deps by their state changing,
not even when the state is first set to active. Thus, their state is
generally initialized through the per-device coldplug() method in
similar fashion to the deserialized state from a previous run would be
put into place. OTOH units found through regular enumeration should
result in state changes (and thus pull in deps due to state changes),
hence their state should be put in effect in the catchup() method
instead. Hence, given this difference, let's also separate the
functions, so that the rule is:
1. What is created in enumerate_perpetual() should be started in
coldplug()
2. What is created in enumerate() should be started in catchup().
2018-06-05 18:26:45 +02:00
|
|
|
if (r < 0) {
|
|
|
|
log_error_errno(r, "Failed to allocate the special " SPECIAL_ROOT_MOUNT " unit: %m");
|
|
|
|
return;
|
|
|
|
}
|
2016-10-25 00:04:55 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
u->perpetual = true;
|
|
|
|
MOUNT(u)->deserialized_state = MOUNT_MOUNTED;
|
|
|
|
|
|
|
|
unit_add_to_load_queue(u);
|
|
|
|
unit_add_to_dbus_queue(u);
|
|
|
|
}
|
|
|
|
|
|
|
|
static bool mount_is_mounted(Mount *m) {
|
|
|
|
assert(m);
|
|
|
|
|
2018-11-28 19:06:30 +01:00
|
|
|
return UNIT(m)->perpetual || FLAGS_SET(m->proc_flags, MOUNT_PROC_IS_MOUNTED);
|
2016-10-25 00:04:55 +02:00
|
|
|
}
|
|
|
|
|
2015-11-10 20:36:37 +01:00
|
|
|
static void mount_enumerate(Manager *m) {
|
2010-01-29 02:07:41 +01:00
|
|
|
int r;
|
2015-06-01 13:48:01 +02:00
|
|
|
|
2010-01-29 02:07:41 +01:00
|
|
|
assert(m);
|
|
|
|
|
2014-11-24 05:33:37 +01:00
|
|
|
mnt_init_debug(0);
|
|
|
|
|
2015-06-01 13:48:01 +02:00
|
|
|
if (!m->mount_monitor) {
|
|
|
|
int fd;
|
2010-01-29 06:04:08 +01:00
|
|
|
|
2015-06-01 13:48:01 +02:00
|
|
|
m->mount_monitor = mnt_new_monitor();
|
|
|
|
if (!m->mount_monitor) {
|
2015-11-10 20:36:37 +01:00
|
|
|
log_oom();
|
2013-11-19 21:12:59 +01:00
|
|
|
goto fail;
|
2015-06-01 13:48:01 +02:00
|
|
|
}
|
2013-11-25 15:35:10 +01:00
|
|
|
|
2015-06-01 13:48:01 +02:00
|
|
|
r = mnt_monitor_enable_kernel(m->mount_monitor, 1);
|
2015-11-10 20:36:37 +01:00
|
|
|
if (r < 0) {
|
|
|
|
log_error_errno(r, "Failed to enable watching of kernel mount events: %m");
|
2013-11-25 15:35:10 +01:00
|
|
|
goto fail;
|
2015-11-10 20:36:37 +01:00
|
|
|
}
|
|
|
|
|
2015-06-01 13:48:01 +02:00
|
|
|
r = mnt_monitor_enable_userspace(m->mount_monitor, 1, NULL);
|
2015-11-10 20:36:37 +01:00
|
|
|
if (r < 0) {
|
|
|
|
log_error_errno(r, "Failed to enable watching of userspace mount events: %m");
|
2014-12-10 01:45:43 +01:00
|
|
|
goto fail;
|
2015-11-10 20:36:37 +01:00
|
|
|
}
|
2014-11-28 19:43:09 +01:00
|
|
|
|
2015-06-01 13:48:01 +02:00
|
|
|
/* mnt_unref_monitor() will close the fd */
|
|
|
|
fd = r = mnt_monitor_get_fd(m->mount_monitor);
|
2015-11-10 20:36:37 +01:00
|
|
|
if (r < 0) {
|
|
|
|
log_error_errno(r, "Failed to acquire watch file descriptor: %m");
|
2014-12-10 01:45:43 +01:00
|
|
|
goto fail;
|
2015-11-10 20:36:37 +01:00
|
|
|
}
|
2014-11-24 05:33:39 +01:00
|
|
|
|
2015-06-01 13:48:01 +02:00
|
|
|
r = sd_event_add_io(m->event, &m->mount_event_source, fd, EPOLLIN, mount_dispatch_io, m);
|
2015-11-10 20:36:37 +01:00
|
|
|
if (r < 0) {
|
|
|
|
log_error_errno(r, "Failed to watch mount file descriptor: %m");
|
2014-11-24 05:33:39 +01:00
|
|
|
goto fail;
|
2015-11-10 20:36:37 +01:00
|
|
|
}
|
2014-11-24 05:33:39 +01:00
|
|
|
|
2018-01-23 18:13:01 +01:00
|
|
|
r = sd_event_source_set_priority(m->mount_event_source, SD_EVENT_PRIORITY_NORMAL-10);
|
2015-11-10 20:36:37 +01:00
|
|
|
if (r < 0) {
|
|
|
|
log_error_errno(r, "Failed to adjust mount watch priority: %m");
|
2014-11-24 05:33:39 +01:00
|
|
|
goto fail;
|
2015-11-10 20:36:37 +01:00
|
|
|
}
|
2015-04-29 16:05:32 +02:00
|
|
|
|
2020-07-09 18:16:44 +02:00
|
|
|
r = sd_event_source_set_ratelimit(m->mount_event_source, 1 * USEC_PER_SEC, 5);
|
|
|
|
if (r < 0) {
|
|
|
|
log_error_errno(r, "Failed to enable rate limit for mount events: %m");
|
|
|
|
goto fail;
|
|
|
|
}
|
|
|
|
|
2015-06-01 13:48:01 +02:00
|
|
|
(void) sd_event_source_set_description(m->mount_event_source, "mount-monitor-dispatch");
|
2014-11-24 05:33:39 +01:00
|
|
|
}
|
|
|
|
|
2013-03-25 00:45:16 +01:00
|
|
|
r = mount_load_proc_self_mountinfo(m, false);
|
|
|
|
if (r < 0)
|
2010-01-29 02:07:41 +01:00
|
|
|
goto fail;
|
|
|
|
|
2015-11-10 20:36:37 +01:00
|
|
|
return;
|
2010-01-29 02:07:41 +01:00
|
|
|
|
|
|
|
fail:
|
|
|
|
mount_shutdown(m);
|
2010-01-23 01:52:57 +01:00
|
|
|
}
|
|
|
|
|
2019-07-17 14:53:07 +02:00
|
|
|
static int drain_libmount(Manager *m) {
|
|
|
|
bool rescan = false;
|
|
|
|
int r;
|
|
|
|
|
|
|
|
assert(m);
|
|
|
|
|
|
|
|
/* Drain all events and verify that the event is valid.
|
|
|
|
*
|
|
|
|
* Note that libmount also monitors /run/mount mkdir if the directory does not exist yet. The mkdir
|
|
|
|
* may generate event which is irrelevant for us.
|
|
|
|
*
|
|
|
|
* error: r < 0; valid: r == 0, false positive: r == 1 */
|
|
|
|
do {
|
|
|
|
r = mnt_monitor_next_change(m->mount_monitor, NULL, NULL);
|
|
|
|
if (r < 0)
|
|
|
|
return log_error_errno(r, "Failed to drain libmount events: %m");
|
|
|
|
if (r == 0)
|
|
|
|
rescan = true;
|
|
|
|
} while (r == 0);
|
|
|
|
|
|
|
|
return rescan;
|
|
|
|
}
|
|
|
|
|
2019-07-17 18:57:13 +02:00
|
|
|
static int mount_process_proc_self_mountinfo(Manager *m) {
|
2018-12-19 11:32:26 +01:00
|
|
|
_cleanup_set_free_free_ Set *around = NULL, *gone = NULL;
|
|
|
|
const char *what;
|
|
|
|
Unit *u;
|
2010-01-29 06:04:08 +01:00
|
|
|
int r;
|
|
|
|
|
|
|
|
assert(m);
|
|
|
|
|
2019-07-17 14:53:07 +02:00
|
|
|
r = drain_libmount(m);
|
|
|
|
if (r <= 0)
|
|
|
|
return r;
|
2010-01-29 06:04:08 +01:00
|
|
|
|
2013-01-04 21:29:48 +01:00
|
|
|
r = mount_load_proc_self_mountinfo(m, true);
|
|
|
|
if (r < 0) {
|
2010-04-10 17:53:17 +02:00
|
|
|
/* Reset flags, just in case, for later calls */
|
2018-11-28 19:06:30 +01:00
|
|
|
LIST_FOREACH(units_by_type, u, m->units_by_type[UNIT_MOUNT])
|
|
|
|
MOUNT(u)->proc_flags = 0;
|
2010-04-10 17:53:17 +02:00
|
|
|
|
2018-12-19 11:32:26 +01:00
|
|
|
return 0;
|
2010-01-29 06:04:08 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
manager_dispatch_load_queue(m);
|
|
|
|
|
2012-01-15 12:37:16 +01:00
|
|
|
LIST_FOREACH(units_by_type, u, m->units_by_type[UNIT_MOUNT]) {
|
|
|
|
Mount *mount = MOUNT(u);
|
2010-01-29 06:04:08 +01:00
|
|
|
|
2016-10-25 00:04:55 +02:00
|
|
|
if (!mount_is_mounted(mount)) {
|
2010-04-10 17:53:17 +02:00
|
|
|
|
2015-05-19 17:19:27 +02:00
|
|
|
/* A mount point is not around right now. It
|
|
|
|
* might be gone, or might never have
|
|
|
|
* existed. */
|
|
|
|
|
|
|
|
if (mount->from_proc_self_mountinfo &&
|
|
|
|
mount->parameters_proc_self_mountinfo.what) {
|
|
|
|
|
|
|
|
/* Remember that this device might just have disappeared */
|
2018-02-08 18:58:35 +01:00
|
|
|
if (set_ensure_allocated(&gone, &path_hash_ops) < 0 ||
|
2020-04-29 08:47:51 +02:00
|
|
|
set_put_strdup(&gone, mount->parameters_proc_self_mountinfo.what) < 0)
|
2015-05-19 17:19:27 +02:00
|
|
|
log_oom(); /* we don't care too much about OOM here... */
|
|
|
|
}
|
2015-05-19 13:50:36 +02:00
|
|
|
|
2010-01-29 06:04:08 +01:00
|
|
|
mount->from_proc_self_mountinfo = false;
|
2019-07-18 17:02:30 +02:00
|
|
|
assert_se(update_parameters_proc_self_mountinfo(mount, NULL, NULL, NULL) >= 0);
|
2010-04-10 17:53:17 +02:00
|
|
|
|
|
|
|
switch (mount->state) {
|
|
|
|
|
|
|
|
case MOUNT_MOUNTED:
|
2018-11-28 20:01:24 +01:00
|
|
|
/* This has just been unmounted by somebody else, follow the state change. */
|
2012-02-03 03:10:56 +01:00
|
|
|
mount_enter_dead(mount, MOUNT_SUCCESS);
|
2010-04-10 17:53:17 +02:00
|
|
|
break;
|
|
|
|
|
2020-11-17 01:13:59 +01:00
|
|
|
case MOUNT_MOUNTING_DONE:
|
|
|
|
/* The mount command may add the corresponding proc mountinfo entry and
|
|
|
|
* then remove it because of an internal error. E.g., fuse.sshfs seems
|
|
|
|
* to do that when the connection fails. See #17617. To handle such the
|
|
|
|
* case, let's once set the state back to mounting. Then, the unit can
|
|
|
|
* correctly enter the failed state later in mount_sigchld(). */
|
|
|
|
mount_set_state(mount, MOUNT_MOUNTING);
|
|
|
|
break;
|
|
|
|
|
2010-04-10 17:53:17 +02:00
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2018-11-28 19:06:30 +01:00
|
|
|
} else if (mount->proc_flags & (MOUNT_PROC_JUST_MOUNTED|MOUNT_PROC_JUST_CHANGED)) {
|
2010-04-10 17:53:17 +02:00
|
|
|
|
2015-05-19 13:50:36 +02:00
|
|
|
/* A mount point was added or changed */
|
2010-04-10 17:53:17 +02:00
|
|
|
|
|
|
|
switch (mount->state) {
|
|
|
|
|
|
|
|
case MOUNT_DEAD:
|
2010-08-31 00:23:34 +02:00
|
|
|
case MOUNT_FAILED:
|
2016-08-30 23:18:46 +02:00
|
|
|
|
|
|
|
/* This has just been mounted by somebody else, follow the state change, but let's
|
|
|
|
* generate a new invocation ID for this implicitly and automatically. */
|
2018-11-28 20:01:24 +01:00
|
|
|
(void) unit_acquire_invocation_id(u);
|
|
|
|
mount_cycle_clear(mount);
|
2012-02-03 03:10:56 +01:00
|
|
|
mount_enter_mounted(mount, MOUNT_SUCCESS);
|
2010-04-10 17:53:17 +02:00
|
|
|
break;
|
|
|
|
|
|
|
|
case MOUNT_MOUNTING:
|
2013-11-25 15:26:30 +01:00
|
|
|
mount_set_state(mount, MOUNT_MOUNTING_DONE);
|
2010-04-10 17:53:17 +02:00
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
|
|
|
/* Nothing really changed, but let's
|
|
|
|
* issue an notification call
|
|
|
|
* nonetheless, in case somebody is
|
|
|
|
* waiting for this. (e.g. file system
|
|
|
|
* ro/rw remounts.) */
|
|
|
|
mount_set_state(mount, mount->state);
|
|
|
|
break;
|
|
|
|
}
|
2015-05-19 17:19:27 +02:00
|
|
|
}
|
2015-05-19 13:50:36 +02:00
|
|
|
|
2016-10-25 00:04:55 +02:00
|
|
|
if (mount_is_mounted(mount) &&
|
2015-05-19 17:19:27 +02:00
|
|
|
mount->from_proc_self_mountinfo &&
|
|
|
|
mount->parameters_proc_self_mountinfo.what) {
|
2018-11-28 19:02:47 +01:00
|
|
|
/* Track devices currently used */
|
2015-05-19 13:50:36 +02:00
|
|
|
|
2018-02-08 18:58:35 +01:00
|
|
|
if (set_ensure_allocated(&around, &path_hash_ops) < 0 ||
|
2020-04-29 08:47:51 +02:00
|
|
|
set_put_strdup(&around, mount->parameters_proc_self_mountinfo.what) < 0)
|
2015-05-19 17:19:27 +02:00
|
|
|
log_oom();
|
2010-04-10 17:53:17 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/* Reset the flags for later calls */
|
2018-11-28 19:06:30 +01:00
|
|
|
mount->proc_flags = 0;
|
2010-04-10 17:53:17 +02:00
|
|
|
}
|
2013-11-19 21:12:59 +01:00
|
|
|
|
2020-09-08 11:58:29 +02:00
|
|
|
SET_FOREACH(what, gone) {
|
2015-05-19 13:50:36 +02:00
|
|
|
if (set_contains(around, what))
|
|
|
|
continue;
|
|
|
|
|
|
|
|
/* Let the device units know that the device is no longer mounted */
|
2018-06-04 18:06:05 +02:00
|
|
|
device_found_node(m, what, 0, DEVICE_FOUND_MOUNT);
|
2015-05-19 13:50:36 +02:00
|
|
|
}
|
2018-12-19 11:32:26 +01:00
|
|
|
|
|
|
|
return 0;
|
2010-04-10 17:53:17 +02:00
|
|
|
}
|
|
|
|
|
2019-07-17 18:57:13 +02:00
|
|
|
static int mount_dispatch_io(sd_event_source *source, int fd, uint32_t revents, void *userdata) {
|
|
|
|
Manager *m = userdata;
|
|
|
|
|
|
|
|
assert(m);
|
|
|
|
assert(revents & EPOLLIN);
|
|
|
|
|
|
|
|
return mount_process_proc_self_mountinfo(m);
|
|
|
|
}
|
|
|
|
|
2010-08-31 00:23:34 +02:00
|
|
|
static void mount_reset_failed(Unit *u) {
|
2010-07-18 04:58:01 +02:00
|
|
|
Mount *m = MOUNT(u);
|
|
|
|
|
|
|
|
assert(m);
|
|
|
|
|
2010-08-31 00:23:34 +02:00
|
|
|
if (m->state == MOUNT_FAILED)
|
2010-07-18 04:58:01 +02:00
|
|
|
mount_set_state(m, MOUNT_DEAD);
|
|
|
|
|
2012-02-03 03:10:56 +01:00
|
|
|
m->result = MOUNT_SUCCESS;
|
|
|
|
m->reload_result = MOUNT_SUCCESS;
|
2019-08-25 15:08:47 +02:00
|
|
|
m->clean_result = MOUNT_SUCCESS;
|
2010-07-18 04:58:01 +02:00
|
|
|
}
|
|
|
|
|
2013-11-19 21:12:59 +01:00
|
|
|
static int mount_kill(Unit *u, KillWho who, int signo, sd_bus_error *error) {
|
mount: rework mount state engine
This changes the mount unit state engine in the following ways:
1. The MOUNT_MOUNTING_SIGTERM and MOUNT_MOUNTING_SIGKILL are removed.
They have been pretty much equivalent to MOUNT_UNMOUNTING_SIGTERM and
MOUNT_UNMOUNTING_SIGKILL in what they do, and the outcome has been
the same as well: the unit is stopped. Hence, let's simplify things a
bit, and merge them. Note that we keep
MOUNT_REMOUNTING_{SIGTERM|SIGKILL} however, as those states have a
different outcome: the unit remains started.
2. mount_enter_signal() will now honour the SendSIGKILL= option of the
mount unit if it was set. This was previously done already when we
entered the signal states through a timeout, and was simply missing
here.
3. A new helper function mount_enter_dead_or_mounted() is added that
places the mount unit in either MOUNT_DEAD or MOUNT_MOUNTED,
depending on what the kernel thinks about the mount's state. This
function is called at various places now, wherever we finished an
operation, and want to make sure our own state reflects again what
the kernel thinks. Previously we had very similar code in a number of
places and in other places didn't recheck the kernel state. Let's do
that with the same logic and function at all relevant places now.
4. Rework mount_stop(): never forget about running control processes.
Instead: when we have a start (i.e. a /bin/mount) process running,
and are asked to stop, then enter the kill states for it, so that it
gets cleaned up. This fixes #6048. Moreover, when we have a reload
process running convert the possible states into the relevant
unmounting states, so that we can properly execute the requested
operation.
Fixes #6048
2017-09-25 19:13:37 +02:00
|
|
|
Mount *m = MOUNT(u);
|
|
|
|
|
|
|
|
assert(m);
|
|
|
|
|
2019-03-28 09:43:56 +01:00
|
|
|
return unit_kill_common(u, who, signo, -1, m->control_pid, error);
|
2010-10-22 16:11:50 +02:00
|
|
|
}
|
|
|
|
|
2016-04-20 15:28:28 +02:00
|
|
|
static int mount_control_pid(Unit *u) {
|
|
|
|
Mount *m = MOUNT(u);
|
|
|
|
|
|
|
|
assert(m);
|
|
|
|
|
|
|
|
return m->control_pid;
|
|
|
|
}
|
|
|
|
|
2019-08-25 15:08:47 +02:00
|
|
|
static int mount_clean(Unit *u, ExecCleanMask mask) {
|
|
|
|
_cleanup_strv_free_ char **l = NULL;
|
|
|
|
Mount *m = MOUNT(u);
|
|
|
|
int r;
|
|
|
|
|
|
|
|
assert(m);
|
|
|
|
assert(mask != 0);
|
|
|
|
|
|
|
|
if (m->state != MOUNT_DEAD)
|
|
|
|
return -EBUSY;
|
|
|
|
|
|
|
|
r = exec_context_get_clean_directories(&m->exec_context, u->manager->prefix, mask, &l);
|
|
|
|
if (r < 0)
|
|
|
|
return r;
|
|
|
|
|
|
|
|
if (strv_isempty(l))
|
|
|
|
return -EUNATCH;
|
|
|
|
|
|
|
|
mount_unwatch_control_pid(m);
|
|
|
|
m->clean_result = MOUNT_SUCCESS;
|
|
|
|
m->control_command = NULL;
|
|
|
|
m->control_command_id = _MOUNT_EXEC_COMMAND_INVALID;
|
|
|
|
|
|
|
|
r = mount_arm_timer(m, usec_add(now(CLOCK_MONOTONIC), m->exec_context.timeout_clean_usec));
|
|
|
|
if (r < 0)
|
|
|
|
goto fail;
|
|
|
|
|
|
|
|
r = unit_fork_and_watch_rm_rf(u, l, &m->control_pid);
|
|
|
|
if (r < 0)
|
|
|
|
goto fail;
|
|
|
|
|
|
|
|
mount_set_state(m, MOUNT_CLEANING);
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
fail:
|
|
|
|
log_unit_warning_errno(u, r, "Failed to initiate cleaning: %m");
|
|
|
|
m->clean_result = MOUNT_FAILURE_RESOURCES;
|
|
|
|
m->timer_event_source = sd_event_source_unref(m->timer_event_source);
|
|
|
|
return r;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int mount_can_clean(Unit *u, ExecCleanMask *ret) {
|
|
|
|
Mount *m = MOUNT(u);
|
|
|
|
|
|
|
|
assert(m);
|
|
|
|
|
|
|
|
return exec_context_get_clean_mask(&m->exec_context, ret);
|
|
|
|
}
|
|
|
|
|
2010-04-21 03:27:44 +02:00
|
|
|
static const char* const mount_exec_command_table[_MOUNT_EXEC_COMMAND_MAX] = {
|
|
|
|
[MOUNT_EXEC_MOUNT] = "ExecMount",
|
|
|
|
[MOUNT_EXEC_UNMOUNT] = "ExecUnmount",
|
|
|
|
[MOUNT_EXEC_REMOUNT] = "ExecRemount",
|
|
|
|
};
|
|
|
|
|
|
|
|
DEFINE_STRING_TABLE_LOOKUP(mount_exec_command, MountExecCommand);
|
|
|
|
|
2012-02-03 03:10:56 +01:00
|
|
|
static const char* const mount_result_table[_MOUNT_RESULT_MAX] = {
|
|
|
|
[MOUNT_SUCCESS] = "success",
|
|
|
|
[MOUNT_FAILURE_RESOURCES] = "resources",
|
|
|
|
[MOUNT_FAILURE_TIMEOUT] = "timeout",
|
|
|
|
[MOUNT_FAILURE_EXIT_CODE] = "exit-code",
|
|
|
|
[MOUNT_FAILURE_SIGNAL] = "signal",
|
core: move enforcement of the start limit into per-unit-type code again
Let's move the enforcement of the per-unit start limit from unit.c into the
type-specific files again. For unit types that know a concept of "result" codes
this allows us to hook up the start limit condition to it with an explicit
result code. Also, this makes sure that the state checks in clal like
service_start() may be done before the start limit is checked, as the start
limit really should be checked last, right before everything has been verified
to be in order.
The generic start limit logic is left in unit.c, but the invocation of it is
moved into the per-type files, in the various xyz_start() functions, so that
they may place the check at the right location.
Note that this change drops the enforcement entirely from device, slice, target
and scope units, since these unit types generally may not fail activation, or
may only be activated a single time. This is also documented now.
Note that restores the "start-limit-hit" result code that existed before
6bf0f408e4833152197fb38fb10a9989c89f3a59 already in the service code. However,
it's not introduced for all units that have a result code concept.
Fixes #3166.
2016-05-02 13:01:26 +02:00
|
|
|
[MOUNT_FAILURE_CORE_DUMP] = "core-dump",
|
|
|
|
[MOUNT_FAILURE_START_LIMIT_HIT] = "start-limit-hit",
|
2018-01-20 21:05:52 +01:00
|
|
|
[MOUNT_FAILURE_PROTOCOL] = "protocol",
|
2012-02-03 03:10:56 +01:00
|
|
|
};
|
|
|
|
|
|
|
|
DEFINE_STRING_TABLE_LOOKUP(mount_result, MountResult);
|
|
|
|
|
2010-01-26 21:39:06 +01:00
|
|
|
const UnitVTable mount_vtable = {
|
2012-01-15 10:53:49 +01:00
|
|
|
.object_size = sizeof(Mount),
|
2013-11-19 21:12:59 +01:00
|
|
|
.exec_context_offset = offsetof(Mount, exec_context),
|
|
|
|
.cgroup_context_offset = offsetof(Mount, cgroup_context),
|
|
|
|
.kill_context_offset = offsetof(Mount, kill_context),
|
2013-11-27 20:23:18 +01:00
|
|
|
.exec_runtime_offset = offsetof(Mount, exec_runtime),
|
2016-07-14 12:37:28 +02:00
|
|
|
.dynamic_creds_offset = offsetof(Mount, dynamic_creds),
|
2012-09-18 11:40:01 +02:00
|
|
|
|
2011-08-01 00:43:05 +02:00
|
|
|
.sections =
|
|
|
|
"Unit\0"
|
|
|
|
"Mount\0"
|
|
|
|
"Install\0",
|
2013-06-27 04:14:27 +02:00
|
|
|
.private_section = "Mount",
|
2013-01-19 01:01:41 +01:00
|
|
|
|
2020-01-07 11:48:57 +01:00
|
|
|
.can_transient = true,
|
|
|
|
.can_fail = true,
|
|
|
|
|
2010-04-10 17:53:17 +02:00
|
|
|
.init = mount_init,
|
|
|
|
.load = mount_load,
|
2010-01-26 04:18:44 +01:00
|
|
|
.done = mount_done,
|
2010-04-10 17:53:17 +02:00
|
|
|
|
2010-01-29 03:18:09 +01:00
|
|
|
.coldplug = mount_coldplug,
|
|
|
|
|
2010-01-26 04:18:44 +01:00
|
|
|
.dump = mount_dump,
|
2010-01-23 01:52:57 +01:00
|
|
|
|
2010-04-10 17:53:17 +02:00
|
|
|
.start = mount_start,
|
|
|
|
.stop = mount_stop,
|
|
|
|
.reload = mount_reload,
|
|
|
|
|
2010-10-22 16:11:50 +02:00
|
|
|
.kill = mount_kill,
|
2019-08-25 15:08:47 +02:00
|
|
|
.clean = mount_clean,
|
|
|
|
.can_clean = mount_can_clean,
|
2010-10-22 16:11:50 +02:00
|
|
|
|
2010-04-21 03:27:44 +02:00
|
|
|
.serialize = mount_serialize,
|
|
|
|
.deserialize_item = mount_deserialize_item,
|
|
|
|
|
2010-01-29 03:18:09 +01:00
|
|
|
.active_state = mount_active_state,
|
2010-04-13 20:59:01 +02:00
|
|
|
.sub_state_to_string = mount_sub_state_to_string,
|
2010-01-29 02:07:41 +01:00
|
|
|
|
2019-08-22 17:08:16 +02:00
|
|
|
.will_restart = unit_will_restart_default,
|
|
|
|
|
2018-02-13 10:50:13 +01:00
|
|
|
.may_gc = mount_may_gc,
|
2020-11-05 13:08:02 +01:00
|
|
|
.is_extrinsic = mount_is_extrinsic,
|
2010-04-21 06:01:13 +02:00
|
|
|
|
2010-04-10 17:53:17 +02:00
|
|
|
.sigchld_event = mount_sigchld_event,
|
|
|
|
|
2010-08-31 00:23:34 +02:00
|
|
|
.reset_failed = mount_reset_failed,
|
2016-04-20 15:28:28 +02:00
|
|
|
|
|
|
|
.control_pid = mount_control_pid,
|
2010-07-18 04:58:01 +02:00
|
|
|
|
2013-06-27 23:21:21 +02:00
|
|
|
.bus_set_property = bus_mount_set_property,
|
|
|
|
.bus_commit_properties = bus_mount_commit_properties,
|
2010-04-18 03:08:16 +02:00
|
|
|
|
2014-01-27 06:57:34 +01:00
|
|
|
.get_timeout = mount_get_timeout,
|
|
|
|
|
core: enumerate perpetual units in a separate per-unit-type method
Previously the enumerate() callback defined for each unit type would do
two things:
1. It would create perpetual units (i.e. -.slice, system.slice, -.mount and
init.scope)
2. It would enumerate units from /proc/self/mountinfo, /proc/swaps and
the udev database
With this change these two parts are split into two seperate methods:
enumerate() now only does #2, while enumerate_perpetual() is responsible
for #1. Why make this change? Well, perpetual units should have a
slightly different effect that those found through enumeration: as
perpetual units should be up unconditionally, perpetually and thus never
change state, they should also not pull in deps by their state changing,
not even when the state is first set to active. Thus, their state is
generally initialized through the per-device coldplug() method in
similar fashion to the deserialized state from a previous run would be
put into place. OTOH units found through regular enumeration should
result in state changes (and thus pull in deps due to state changes),
hence their state should be put in effect in the catchup() method
instead. Hence, given this difference, let's also separate the
functions, so that the rule is:
1. What is created in enumerate_perpetual() should be started in
coldplug()
2. What is created in enumerate() should be started in catchup().
2018-06-05 18:26:45 +02:00
|
|
|
.enumerate_perpetual = mount_enumerate_perpetual,
|
2010-01-29 03:18:09 +01:00
|
|
|
.enumerate = mount_enumerate,
|
2012-05-13 18:18:54 +02:00
|
|
|
.shutdown = mount_shutdown,
|
|
|
|
|
|
|
|
.status_message_formats = {
|
|
|
|
.starting_stopping = {
|
|
|
|
[0] = "Mounting %s...",
|
|
|
|
[1] = "Unmounting %s...",
|
|
|
|
},
|
|
|
|
.finished_start_job = {
|
|
|
|
[JOB_DONE] = "Mounted %s.",
|
|
|
|
[JOB_FAILED] = "Failed to mount %s.",
|
|
|
|
[JOB_TIMEOUT] = "Timed out mounting %s.",
|
|
|
|
},
|
|
|
|
.finished_stop_job = {
|
|
|
|
[JOB_DONE] = "Unmounted %s.",
|
|
|
|
[JOB_FAILED] = "Failed unmounting %s.",
|
|
|
|
[JOB_TIMEOUT] = "Timed out unmounting %s.",
|
|
|
|
},
|
|
|
|
},
|
2010-01-23 01:52:57 +01:00
|
|
|
};
|