summaryrefslogtreecommitdiff
path: root/src/core/mount.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/core/mount.c')
-rw-r--r--src/core/mount.c227
1 files changed, 160 insertions, 67 deletions
diff --git a/src/core/mount.c b/src/core/mount.c
index 83e51a7aba..5d2b010013 100644
--- a/src/core/mount.c
+++ b/src/core/mount.c
@@ -30,6 +30,7 @@
#include "load-fragment.h"
#include "load-dropin.h"
#include "log.h"
+#include "sd-messages.h"
#include "strv.h"
#include "mkdir.h"
#include "path-util.h"
@@ -221,9 +222,11 @@ static int mount_add_swap_links(Mount *m) {
assert(m);
- LIST_FOREACH(units_by_type, other, UNIT(m)->manager->units_by_type[UNIT_SWAP])
- if ((r = swap_add_one_mount_link(SWAP(other), m)) < 0)
+ LIST_FOREACH(units_by_type, other, UNIT(m)->manager->units_by_type[UNIT_SWAP]) {
+ r = swap_add_one_mount_link(SWAP(other), m);
+ if (r < 0)
return r;
+ }
return 0;
}
@@ -234,9 +237,11 @@ static int mount_add_path_links(Mount *m) {
assert(m);
- LIST_FOREACH(units_by_type, other, UNIT(m)->manager->units_by_type[UNIT_PATH])
- if ((r = path_add_one_mount_link(PATH(other), m)) < 0)
+ LIST_FOREACH(units_by_type, other, UNIT(m)->manager->units_by_type[UNIT_PATH]) {
+ r = path_add_one_mount_link(PATH(other), m);
+ if (r < 0)
return r;
+ }
return 0;
}
@@ -247,9 +252,11 @@ static int mount_add_automount_links(Mount *m) {
assert(m);
- LIST_FOREACH(units_by_type, other, UNIT(m)->manager->units_by_type[UNIT_AUTOMOUNT])
- if ((r = automount_add_one_mount_link(AUTOMOUNT(other), m)) < 0)
+ LIST_FOREACH(units_by_type, other, UNIT(m)->manager->units_by_type[UNIT_AUTOMOUNT]) {
+ r = automount_add_one_mount_link(AUTOMOUNT(other), m);
+ if (r < 0)
return r;
+ }
return 0;
}
@@ -260,9 +267,11 @@ static int mount_add_socket_links(Mount *m) {
assert(m);
- LIST_FOREACH(units_by_type, other, UNIT(m)->manager->units_by_type[UNIT_SOCKET])
- if ((r = socket_add_one_mount_link(SOCKET(other), m)) < 0)
+ LIST_FOREACH(units_by_type, other, UNIT(m)->manager->units_by_type[UNIT_SOCKET]) {
+ r = socket_add_one_mount_link(SOCKET(other), m);
+ if (r < 0)
return r;
+ }
return 0;
}
@@ -352,17 +361,21 @@ static int mount_add_device_links(Mount *m) {
if (!p->what)
return 0;
- if (!mount_is_bind(p) &&
- !path_equal(m->where, "/")) {
- r = unit_add_node_link(UNIT(m), p->what, false);
- if (r < 0)
- return r;
- }
+ if (mount_is_bind(p))
+ return 0;
+
+ if (!is_device_path(p->what))
+ return 0;
+
+ if (path_equal(m->where, "/"))
+ return 0;
+
+ r = unit_add_node_link(UNIT(m), p->what, false);
+ if (r < 0)
+ return r;
if (p->passno > 0 &&
- !mount_is_bind(p) &&
- !path_equal(m->where, "/") &&
- UNIT(m)->manager->running_as == MANAGER_SYSTEM) {
+ UNIT(m)->manager->running_as == SYSTEMD_SYSTEM) {
char *name;
Unit *fsck;
/* Let's add in the fsck service */
@@ -374,7 +387,8 @@ static int mount_add_device_links(Mount *m) {
r = manager_load_unit_prepare(UNIT(m)->manager, name, NULL, NULL, &fsck);
if (r < 0) {
- log_warning("Failed to prepare unit %s: %s", name, strerror(-r));
+ log_warning_unit(name,
+ "Failed to prepare unit %s: %s", name, strerror(-r));
free(name);
return r;
}
@@ -396,7 +410,7 @@ static int mount_add_quota_links(Mount *m) {
assert(m);
- if (UNIT(m)->manager->running_as != MANAGER_SYSTEM)
+ if (UNIT(m)->manager->running_as != SYSTEMD_SYSTEM)
return 0;
p = get_mount_parameters_fragment(m);
@@ -424,7 +438,7 @@ static int mount_add_default_dependencies(Mount *m) {
assert(m);
- if (UNIT(m)->manager->running_as != MANAGER_SYSTEM)
+ if (UNIT(m)->manager->running_as != SYSTEMD_SYSTEM)
return 0;
p = get_mount_parameters_fragment(m);
@@ -485,7 +499,9 @@ static int mount_fix_timeouts(Mount *m) {
free(t);
if (r < 0) {
- log_warning("Failed to parse timeout for %s, ignoring: %s", m->where, timeout);
+ log_warning_unit(UNIT(m)->id,
+ "Failed to parse timeout for %s, ignoring: %s",
+ m->where, timeout);
return r;
}
@@ -517,22 +533,29 @@ static int mount_verify(Mount *m) {
free(e);
if (!b) {
- log_error("%s's Where setting doesn't match unit name. Refusing.", UNIT(m)->id);
+ log_error_unit(UNIT(m)->id,
+ "%s's Where setting doesn't match unit name. Refusing.",
+ UNIT(m)->id);
return -EINVAL;
}
if (mount_point_is_api(m->where) || mount_point_ignore(m->where)) {
- log_error("Cannot create mount unit for API file system %s. Refusing.", m->where);
+ log_error_unit(UNIT(m)->id,
+ "Cannot create mount unit for API file system %s. Refusing.",
+ m->where);
return -EINVAL;
}
if (UNIT(m)->fragment_path && !m->parameters_fragment.what) {
- log_error("%s's What setting is missing. Refusing.", UNIT(m)->id);
+ log_error_unit(UNIT(m)->id,
+ "%s's What setting is missing. Refusing.", UNIT(m)->id);
return -EBADMSG;
}
if (m->exec_context.pam_name && m->kill_context.kill_mode != KILL_CONTROL_GROUP) {
- log_error("%s has PAM enabled. Kill mode must be set to 'control-group'. Refusing.", UNIT(m)->id);
+ log_error_unit(UNIT(m)->id,
+ "%s has PAM enabled. Kill mode must be set to control-group'. Refusing.",
+ UNIT(m)->id);
return -EINVAL;
}
@@ -543,10 +566,6 @@ static int mount_add_extras(Mount *m) {
Unit *u = UNIT(m);
int r;
- r = unit_add_exec_dependencies(u, &m->exec_context);
- if (r < 0)
- return r;
-
if (UNIT(m)->fragment_path)
m->from_fragment = true;
@@ -558,6 +577,10 @@ static int mount_add_extras(Mount *m) {
path_kill_slashes(m->where);
+ r = unit_add_exec_dependencies(u, &m->exec_context);
+ if (r < 0)
+ return r;
+
if (!UNIT(m)->description) {
r = unit_set_description(u, m->where);
if (r < 0)
@@ -699,10 +722,11 @@ static void mount_set_state(Mount *m, MountState state) {
}
if (state != old_state)
- log_debug("%s changed %s -> %s",
- UNIT(m)->id,
- mount_state_to_string(old_state),
- mount_state_to_string(state));
+ log_debug_unit(UNIT(m)->id,
+ "%s changed %s -> %s",
+ UNIT(m)->id,
+ mount_state_to_string(old_state),
+ mount_state_to_string(state));
unit_notify(UNIT(m), state_translation_table[old_state], state_translation_table[state], m->reload_result == MOUNT_SUCCESS);
m->reload_result = MOUNT_SUCCESS;
@@ -737,10 +761,12 @@ static int mount_coldplug(Unit *u) {
if (m->control_pid <= 0)
return -EBADMSG;
- if ((r = unit_watch_pid(UNIT(m), m->control_pid)) < 0)
+ r = unit_watch_pid(UNIT(m), m->control_pid);
+ if (r < 0)
return r;
- if ((r = unit_watch_timer(UNIT(m), m->timeout_usec, &m->timer_watch)) < 0)
+ r = unit_watch_timer(UNIT(m), CLOCK_MONOTONIC, true, m->timeout_usec, &m->timer_watch);
+ if (r < 0)
return r;
}
@@ -796,7 +822,8 @@ static int mount_spawn(Mount *m, ExecCommand *c, pid_t *_pid) {
assert(c);
assert(_pid);
- if ((r = unit_watch_timer(UNIT(m), m->timeout_usec, &m->timer_watch)) < 0)
+ r = unit_watch_timer(UNIT(m), CLOCK_MONOTONIC, true, m->timeout_usec, &m->timer_watch);
+ if (r < 0)
goto fail;
if ((r = exec_spawn(c,
@@ -866,7 +893,9 @@ static void mount_enter_signal(Mount *m, MountState state, MountResult f) {
if (m->control_pid > 0) {
if (kill_and_sigcont(m->control_pid, sig) < 0 && errno != ESRCH)
- log_warning("Failed to kill control process %li: %m", (long) m->control_pid);
+ log_warning_unit(UNIT(m)->id,
+ "Failed to kill control process %li: %m",
+ (long) m->control_pid);
else
wait_for_exit = true;
}
@@ -886,7 +915,9 @@ static void mount_enter_signal(Mount *m, MountState state, MountResult f) {
r = cgroup_bonding_kill_list(UNIT(m)->cgroup_bondings, sig, true, false, pid_set, NULL);
if (r < 0) {
if (r != -EAGAIN && r != -ESRCH && r != -ENOENT)
- log_warning("Failed to kill control group: %s", strerror(-r));
+ log_warning_unit(UNIT(m)->id,
+ "Failed to kill control group: %s",
+ strerror(-r));
} else if (r > 0)
wait_for_exit = true;
@@ -896,7 +927,8 @@ static void mount_enter_signal(Mount *m, MountState state, MountResult f) {
}
if (wait_for_exit) {
- if ((r = unit_watch_timer(UNIT(m), m->timeout_usec, &m->timer_watch)) < 0)
+ r = unit_watch_timer(UNIT(m), CLOCK_MONOTONIC, true, m->timeout_usec, &m->timer_watch);
+ if (r < 0)
goto fail;
mount_set_state(m, state);
@@ -908,7 +940,8 @@ static void mount_enter_signal(Mount *m, MountState state, MountResult f) {
return;
fail:
- log_warning("%s failed to kill processes: %s", UNIT(m)->id, strerror(-r));
+ log_warning_unit(UNIT(m)->id,
+ "%s failed to kill processes: %s", UNIT(m)->id, strerror(-r));
if (state == MOUNT_REMOUNTING_SIGTERM || state == MOUNT_REMOUNTING_SIGKILL)
mount_enter_mounted(m, MOUNT_FAILURE_RESOURCES);
@@ -919,6 +952,18 @@ fail:
set_free(pid_set);
}
+void warn_if_dir_nonempty(const char *unit, const char* where) {
+ if (dir_is_empty(where) > 0)
+ return;
+ log_struct(LOG_NOTICE,
+ "MESSAGE=%s: Directory %s to mount over is not empty, mounting anyway.",
+ unit, where,
+ "WHERE=%s", where,
+ "_SYSTEMD_UNIT=%s", unit,
+ MESSAGE_ID(SD_MESSAGE_OVERMOUNTING),
+ NULL);
+}
+
static void mount_enter_unmounting(Mount *m) {
int r;
@@ -944,7 +989,9 @@ static void mount_enter_unmounting(Mount *m) {
return;
fail:
- log_warning("%s failed to run 'umount' task: %s", UNIT(m)->id, strerror(-r));
+ log_warning_unit(UNIT(m)->id,
+ "%s failed to run 'umount' task: %s",
+ UNIT(m)->id, strerror(-r));
mount_enter_mounted(m, MOUNT_FAILURE_RESOURCES);
}
@@ -959,6 +1006,8 @@ static void mount_enter_mounting(Mount *m) {
mkdir_p_label(m->where, m->directory_mode);
+ warn_if_dir_nonempty(m->meta.id, m->where);
+
/* Create the source directory for bind-mounts if needed */
p = get_mount_parameters_fragment(m);
if (p && mount_is_bind(p))
@@ -981,7 +1030,8 @@ static void mount_enter_mounting(Mount *m) {
mount_unwatch_control_pid(m);
- if ((r = mount_spawn(m, m->control_command, &m->control_pid)) < 0)
+ r = mount_spawn(m, m->control_command, &m->control_pid);
+ if (r < 0)
goto fail;
mount_set_state(m, MOUNT_MOUNTING);
@@ -989,7 +1039,9 @@ static void mount_enter_mounting(Mount *m) {
return;
fail:
- log_warning("%s failed to run 'mount' task: %s", UNIT(m)->id, strerror(-r));
+ log_warning_unit(UNIT(m)->id,
+ "%s failed to run 'mount' task: %s",
+ UNIT(m)->id, strerror(-r));
mount_enter_dead(m, MOUNT_FAILURE_RESOURCES);
}
@@ -1047,7 +1099,9 @@ static void mount_enter_remounting(Mount *m) {
return;
fail:
- log_warning("%s failed to run 'remount' task: %s", UNIT(m)->id, strerror(-r));
+ log_warning_unit(UNIT(m)->id,
+ "%s failed to run 'remount' task: %s",
+ UNIT(m)->id, strerror(-r));
m->reload_result = MOUNT_FAILURE_RESOURCES;
mount_enter_mounted(m, MOUNT_SUCCESS);
}
@@ -1149,7 +1203,7 @@ static int mount_deserialize_item(Unit *u, const char *key, const char *value, F
MountState state;
if ((state = mount_state_from_string(value)) < 0)
- log_debug("Failed to parse state value %s", value);
+ log_debug_unit(u->id, "Failed to parse state value %s", value);
else
m->deserialized_state = state;
} else if (streq(key, "result")) {
@@ -1157,7 +1211,8 @@ static int mount_deserialize_item(Unit *u, const char *key, const char *value, F
f = mount_result_from_string(value);
if (f < 0)
- log_debug("Failed to parse result value %s", value);
+ log_debug_unit(UNIT(m)->id,
+ "Failed to parse result value %s", value);
else if (f != MOUNT_SUCCESS)
m->result = f;
@@ -1166,7 +1221,8 @@ static int mount_deserialize_item(Unit *u, const char *key, const char *value, F
f = mount_result_from_string(value);
if (f < 0)
- log_debug("Failed to parse reload result value %s", value);
+ log_debug_unit(UNIT(m)->id,
+ "Failed to parse reload result value %s", value);
else if (f != MOUNT_SUCCESS)
m->reload_result = f;
@@ -1174,21 +1230,24 @@ static int mount_deserialize_item(Unit *u, const char *key, const char *value, F
pid_t pid;
if (parse_pid(value, &pid) < 0)
- log_debug("Failed to parse control-pid value %s", value);
+ log_debug_unit(UNIT(m)->id,
+ "Failed to parse control-pid value %s", value);
else
m->control_pid = pid;
} else if (streq(key, "control-command")) {
MountExecCommand id;
if ((id = mount_exec_command_from_string(value)) < 0)
- log_debug("Failed to parse exec-command value %s", value);
+ log_debug_unit(UNIT(m)->id,
+ "Failed to parse exec-command value %s", value);
else {
m->control_command_id = id;
m->control_command = m->exec_command + id;
}
} else
- log_debug("Unknown serialization key '%s'", key);
+ log_debug_unit(UNIT(m)->id,
+ "Unknown serialization key '%s'", key);
return 0;
}
@@ -1225,7 +1284,7 @@ static void mount_sigchld_event(Unit *u, pid_t pid, int code, int status) {
m->control_pid = 0;
- if (is_clean_exit(code, status))
+ if (is_clean_exit(code, status, NULL))
f = MOUNT_SUCCESS;
else if (code == CLD_EXITED)
f = MOUNT_FAILURE_EXIT_CODE;
@@ -1246,8 +1305,9 @@ static void mount_sigchld_event(Unit *u, pid_t pid, int code, int status) {
m->control_command_id = _MOUNT_EXEC_COMMAND_INVALID;
}
- log_full(f == MOUNT_SUCCESS ? LOG_DEBUG : LOG_NOTICE,
- "%s mount process exited, code=%s status=%i", u->id, sigchld_code_to_string(code), status);
+ log_full_unit(f == MOUNT_SUCCESS ? LOG_DEBUG : LOG_NOTICE, u->id,
+ "%s mount process exited, code=%s status=%i",
+ u->id, sigchld_code_to_string(code), status);
/* Note that mount(8) returning and the kernel sending us a
* mount table change event might happen out-of-order. If an
@@ -1314,27 +1374,33 @@ static void mount_timer_event(Unit *u, uint64_t elapsed, Watch *w) {
case MOUNT_MOUNTING:
case MOUNT_MOUNTING_DONE:
- log_warning("%s mounting timed out. Stopping.", u->id);
+ log_warning_unit(u->id,
+ "%s mounting timed out. Stopping.", u->id);
mount_enter_signal(m, MOUNT_MOUNTING_SIGTERM, MOUNT_FAILURE_TIMEOUT);
break;
case MOUNT_REMOUNTING:
- log_warning("%s remounting timed out. Stopping.", u->id);
+ log_warning_unit(u->id,
+ "%s remounting timed out. Stopping.", u->id);
m->reload_result = MOUNT_FAILURE_TIMEOUT;
mount_enter_mounted(m, MOUNT_SUCCESS);
break;
case MOUNT_UNMOUNTING:
- log_warning("%s unmounting timed out. Stopping.", u->id);
+ log_warning_unit(u->id,
+ "%s unmounting timed out. Stopping.", u->id);
mount_enter_signal(m, MOUNT_UNMOUNTING_SIGTERM, MOUNT_FAILURE_TIMEOUT);
break;
case MOUNT_MOUNTING_SIGTERM:
if (m->kill_context.send_sigkill) {
- log_warning("%s mounting timed out. Killing.", u->id);
+ log_warning_unit(u->id,
+ "%s mounting timed out. Killing.", u->id);
mount_enter_signal(m, MOUNT_MOUNTING_SIGKILL, MOUNT_FAILURE_TIMEOUT);
} else {
- log_warning("%s mounting timed out. Skipping SIGKILL. Ignoring.", u->id);
+ log_warning_unit(u->id,
+ "%s mounting timed out. Skipping SIGKILL. Ignoring.",
+ u->id);
if (m->from_proc_self_mountinfo)
mount_enter_mounted(m, MOUNT_FAILURE_TIMEOUT);
@@ -1345,10 +1411,13 @@ static void mount_timer_event(Unit *u, uint64_t elapsed, Watch *w) {
case MOUNT_REMOUNTING_SIGTERM:
if (m->kill_context.send_sigkill) {
- log_warning("%s remounting timed out. Killing.", u->id);
+ log_warning_unit(u->id,
+ "%s remounting timed out. Killing.", u->id);
mount_enter_signal(m, MOUNT_REMOUNTING_SIGKILL, MOUNT_FAILURE_TIMEOUT);
} else {
- log_warning("%s remounting timed out. Skipping SIGKILL. Ignoring.", u->id);
+ log_warning_unit(u->id,
+ "%s remounting timed out. Skipping SIGKILL. Ignoring.",
+ u->id);
if (m->from_proc_self_mountinfo)
mount_enter_mounted(m, MOUNT_FAILURE_TIMEOUT);
@@ -1359,10 +1428,13 @@ static void mount_timer_event(Unit *u, uint64_t elapsed, Watch *w) {
case MOUNT_UNMOUNTING_SIGTERM:
if (m->kill_context.send_sigkill) {
- log_warning("%s unmounting timed out. Killing.", u->id);
+ log_warning_unit(u->id,
+ "%s unmounting timed out. Killing.", u->id);
mount_enter_signal(m, MOUNT_UNMOUNTING_SIGKILL, MOUNT_FAILURE_TIMEOUT);
} else {
- log_warning("%s unmounting timed out. Skipping SIGKILL. Ignoring.", u->id);
+ log_warning_unit(u->id,
+ "%s unmounting timed out. Skipping SIGKILL. Ignoring.",
+ u->id);
if (m->from_proc_self_mountinfo)
mount_enter_mounted(m, MOUNT_FAILURE_TIMEOUT);
@@ -1374,7 +1446,9 @@ static void mount_timer_event(Unit *u, uint64_t elapsed, Watch *w) {
case MOUNT_MOUNTING_SIGKILL:
case MOUNT_REMOUNTING_SIGKILL:
case MOUNT_UNMOUNTING_SIGKILL:
- log_warning("%s mount process still around after SIGKILL. Ignoring.", u->id);
+ log_warning_unit(u->id,
+ "%s mount process still around after SIGKILL. Ignoring.",
+ u->id);
if (m->from_proc_self_mountinfo)
mount_enter_mounted(m, MOUNT_FAILURE_TIMEOUT);
@@ -1400,6 +1474,7 @@ static int mount_add_one(
bool delete;
char *e, *w = NULL, *o = NULL, *f = NULL;
MountParameters *p;
+ bool load_extras = false;
assert(m);
assert(what);
@@ -1450,12 +1525,21 @@ static int mount_add_one(
delete = false;
free(e);
+ if (!MOUNT(u)->where) {
+ MOUNT(u)->where = strdup(where);
+ if (!MOUNT(u)->where) {
+ r = -ENOMEM;
+ goto fail;
+ }
+ }
+
if (u->load_state == UNIT_ERROR) {
u->load_state = UNIT_LOADED;
u->load_error = 0;
- r = mount_add_extras(MOUNT(u));
- if (r < 0)
- goto fail;
+
+ /* Load in the extras later on, after we
+ * finished initialization of the unit */
+ load_extras = true;
}
}
@@ -1486,6 +1570,12 @@ static int mount_add_one(
p->passno = passno;
+ if (load_extras) {
+ r = mount_add_extras(MOUNT(u));
+ if (r < 0)
+ goto fail;
+ }
+
unit_add_to_dbus_queue(u);
return 0;
@@ -1630,7 +1720,8 @@ void mount_fd_event(Manager *m, int events) {
* /proc/self/mountinfo file, which informs us about mounting
* table changes */
- if ((r = mount_load_proc_self_mountinfo(m, true)) < 0) {
+ r = mount_load_proc_self_mountinfo(m, true);
+ if (r < 0) {
log_error("Failed to reread /proc/self/mountinfo: %s", strerror(-r));
/* Reset flags, just in case, for later calls */
@@ -1797,6 +1888,8 @@ DEFINE_STRING_TABLE_LOOKUP(mount_result, MountResult);
const UnitVTable mount_vtable = {
.object_size = sizeof(Mount),
+ .exec_context_offset = offsetof(Mount, exec_context),
+
.sections =
"Unit\0"
"Mount\0"