unit_unwatch_timer(u, &m->timer_watch);
}
-static int mount_add_node_links(Mount *m) {
- Unit *device;
- char *e;
+static int mount_add_mount_links(Mount *m) {
+ Meta *other;
int r;
- const char *what;
assert(m);
- /* Adds in links to the device that this node is based on */
+ /* Adds in links to other mount points that might lie below or
+ * above us in the hierarchy */
- if (m->parameters_fragment.what)
- what = m->parameters_fragment.what;
- else if (m->parameters_etc_fstab.what)
- what = m->parameters_etc_fstab.what;
- else
- /* We observe kernel mounts only while they are live,
- * hence don't create any links for them */
- return 0;
+ LIST_FOREACH(units_per_type, other, m->meta.manager->units_per_type[UNIT_MOUNT]) {
+ Mount *n = (Mount*) other;
- if (!path_startswith(what, "/dev/"))
- return 0;
+ if (n == m)
+ continue;
- if (!(e = unit_name_build_escape(what+1, NULL, ".device")))
- return -ENOMEM;
+ if (n->meta.load_state != UNIT_LOADED)
+ continue;
- r = manager_load_unit(UNIT(m)->meta.manager, e, NULL, &device);
- free(e);
+ if (path_startswith(m->where, n->where)) {
- if (r < 0)
- return r;
+ if ((r = unit_add_dependency(UNIT(m), UNIT_AFTER, UNIT(n), true)) < 0)
+ return r;
- if ((r = unit_add_dependency(UNIT(m), UNIT_AFTER, device, true)) < 0)
- return r;
+ if (n->from_etc_fstab || n->from_fragment)
+ if ((r = unit_add_dependency(UNIT(m), UNIT_REQUIRES, UNIT(n), true)) < 0)
+ return r;
- if ((r = unit_add_dependency(UNIT(m), UNIT_REQUIRES, device, true)) < 0)
- return r;
+ } else if (path_startswith(n->where, m->where)) {
- if (UNIT(m)->meta.manager->running_as == MANAGER_INIT ||
- UNIT(m)->meta.manager->running_as == MANAGER_SYSTEM)
- if ((r = unit_add_dependency(device, UNIT_WANTS, UNIT(m), false)) < 0)
- return r;
+ if ((r = unit_add_dependency(UNIT(m), UNIT_BEFORE, UNIT(n), true)) < 0)
+ return r;
+
+ if (m->from_etc_fstab || m->from_fragment)
+ if ((r = unit_add_dependency(UNIT(n), UNIT_REQUIRES, UNIT(m), true)) < 0)
+ return r;
+ }
+ }
return 0;
}
-static int mount_add_path_links(Mount *m) {
+static int mount_add_swap_links(Mount *m) {
Meta *other;
int r;
assert(m);
- /* Adds in link to other mount points, that might lie below or
- * above us in the hierarchy */
-
- LIST_FOREACH(units_per_type, other, UNIT(m)->meta.manager->units_per_type[UNIT_MOUNT]) {
- Mount *n;
-
- n = (Mount*) other;
+ LIST_FOREACH(units_per_type, other, m->meta.manager->units_per_type[UNIT_SWAP])
+ if ((r = swap_add_one_mount_link((Swap*) other, m)) < 0)
+ return r;
- if (n == m)
- continue;
+ return 0;
+}
- if (m->meta.load_state != UNIT_LOADED)
- continue;
+static int mount_add_automount_links(Mount *m) {
+ Meta *other;
+ int r;
- if (path_startswith(m->where, n->where)) {
+ assert(m);
- if ((r = unit_add_dependency(UNIT(m), UNIT_AFTER, UNIT(other), true)) < 0)
- return r;
+ LIST_FOREACH(units_per_type, other, m->meta.manager->units_per_type[UNIT_AUTOMOUNT])
+ if ((r = automount_add_one_mount_link((Automount*) other, m)) < 0)
+ return r;
- if (n->from_etc_fstab || n->from_fragment)
- if ((r = unit_add_dependency(UNIT(m), UNIT_REQUIRES, UNIT(other), true)) < 0)
- return r;
+ return 0;
+}
- } else if (path_startswith(n->where, m->where)) {
+static int mount_add_socket_links(Mount *m) {
+ Meta *other;
+ int r;
- if ((r = unit_add_dependency(UNIT(m), UNIT_BEFORE, UNIT(other), true)) < 0)
- return r;
+ assert(m);
- if (m->from_etc_fstab || m->from_fragment)
- if ((r = unit_add_dependency(UNIT(other), UNIT_REQUIRES, UNIT(m), true)) < 0)
- return r;
- }
- }
+ LIST_FOREACH(units_per_type, other, m->meta.manager->units_per_type[UNIT_SOCKET])
+ if ((r = socket_add_one_mount_link((Socket*) other, m)) < 0)
+ return r;
return 0;
}
-static bool mount_test_option(const char *haystack, const char *needle) {
+static char* mount_test_option(const char *haystack, const char *needle) {
struct mntent me;
assert(needle);
zero(me);
me.mnt_opts = (char*) haystack;
- return !!hasmntopt(&me, needle);
+ return hasmntopt(&me, needle);
}
static int mount_add_target_links(Mount *m) {
else
return 0;
- noauto = mount_test_option(p->options, MNTOPT_NOAUTO);
- handle = mount_test_option(p->options, "comment=systemd.mount");
- automount = mount_test_option(p->options, "comment=systemd.automount");
-
- if (noauto && !handle && !automount)
- return 0;
+ noauto = !!mount_test_option(p->options, MNTOPT_NOAUTO);
+ handle = !!mount_test_option(p->options, "comment=systemd.mount");
+ automount = !!mount_test_option(p->options, "comment=systemd.automount");
if (mount_test_option(p->options, "_netdev") ||
fstype_is_network(p->fstype))
} else {
- if (handle)
+ if (!noauto && handle)
if ((r = unit_add_dependency(tu, UNIT_WANTS, UNIT(m), true)) < 0)
return r;
return -EINVAL;
}
+ if (m->meta.fragment_path && !m->parameters_fragment.what) {
+ log_error("%s's What setting is missing. Refusing.", UNIT(m)->meta.id);
+ return -EBADMSG;
+ }
+
return 0;
}
/* This is a new unit? Then let's add in some extras */
if (u->meta.load_state == UNIT_LOADED) {
+ const char *what = NULL;
+
+ if (m->meta.fragment_path)
+ m->from_fragment = true;
if (!m->where)
if (!(m->where = unit_name_to_path(u->meta.id)))
path_kill_slashes(m->where);
- /* Minor validity checking */
- if ((m->parameters_fragment.options || m->parameters_fragment.fstype) && !m->parameters_fragment.what)
- return -EBADMSG;
+ if (!m->meta.description)
+ if ((r = unit_set_description(u, m->where)) < 0)
+ return r;
- if (m->parameters_fragment.what)
- m->from_fragment = true;
+ if (m->from_fragment && m->parameters_fragment.what)
+ what = m->parameters_fragment.what;
+ else if (m->from_etc_fstab && m->parameters_etc_fstab.what)
+ what = m->parameters_etc_fstab.what;
+ else if (m->from_proc_self_mountinfo && m->parameters_proc_self_mountinfo.what)
+ what = m->parameters_proc_self_mountinfo.what;
+
+ if (what)
+ if ((r = unit_add_node_link(u, what,
+ (u->meta.manager->running_as == MANAGER_INIT ||
+ u->meta.manager->running_as == MANAGER_SYSTEM))) < 0)
+ return r;
- if ((r = mount_add_node_links(MOUNT(u))) < 0)
+ if ((r = mount_add_mount_links(m)) < 0)
return r;
- if ((r = mount_add_path_links(MOUNT(u))) < 0)
+ if ((r = mount_add_socket_links(m)) < 0)
return r;
- if ((r = mount_add_target_links(MOUNT(u))) < 0)
+ if ((r = mount_add_swap_links(m)) < 0)
+ return r;
+
+ if ((r = mount_add_automount_links(m)) < 0)
+ return r;
+
+ if ((r = mount_add_target_links(m)) < 0)
return r;
if ((r = unit_add_default_cgroup(u)) < 0)
mount_notify_automount(m, -ENODEV);
if (state != old_state)
- log_debug("%s changed %s → %s",
+ log_debug("%s changed %s -> %s",
UNIT(m)->meta.id,
mount_state_to_string(old_state),
mount_state_to_string(state));
NULL,
&m->exec_context,
NULL, 0,
+ m->meta.manager->environment,
true,
true,
UNIT(m)->meta.manager->confirm_spawn,
assert(m);
assert(pid >= 0);
- success = code == CLD_EXITED && status == 0;
+ success = is_clean_exit(code, status);
m->failure = m->failure || !success;
assert(m->control_pid == pid);
Unit *u;
bool delete;
char *e, *w = NULL, *o = NULL, *f = NULL;
- MountParameters *mp;
+ MountParameters *p;
assert(m);
assert(what);
if (streq(fstype, "autofs"))
return 0;
- /* probably some kind of swap, which we don't cover for now */
- if (where[0] != '/')
+ /* probably some kind of swap, ignore */
+ if (!is_path(where))
return 0;
if (!(e = unit_name_from_path(where, ".mount")))
goto fail;
if (!(MOUNT(u)->where = strdup(where))) {
- r = -ENOMEM;
- goto fail;
- }
-
- if ((r = unit_set_description(u, where)) < 0)
+ r = -ENOMEM;
goto fail;
+ }
unit_add_to_load_queue(u);
} else {
}
if (from_proc_self_mountinfo) {
- mp = &MOUNT(u)->parameters_proc_self_mountinfo;
+ p = &MOUNT(u)->parameters_proc_self_mountinfo;
if (set_flags) {
MOUNT(u)->is_mounted = true;
MOUNT(u)->just_mounted = !MOUNT(u)->from_proc_self_mountinfo;
- MOUNT(u)->just_changed = !streq_ptr(MOUNT(u)->parameters_proc_self_mountinfo.options, o);
+ MOUNT(u)->just_changed = !streq_ptr(p->options, o);
}
MOUNT(u)->from_proc_self_mountinfo = true;
-
} else {
- mp = &MOUNT(u)->parameters_etc_fstab;
-
+ p = &MOUNT(u)->parameters_etc_fstab;
MOUNT(u)->from_etc_fstab = true;
}
- free(mp->what);
- mp->what = w;
+ free(p->what);
+ p->what = w;
- free(mp->options);
- mp->options = o;
+ free(p->options);
+ p->options = o;
- free(mp->fstype);
- mp->fstype = f;
+ free(p->fstype);
+ p->fstype = f;
unit_add_to_dbus_queue(u);
if (delete && u)
unit_free(u);
- return 0;
+ return r;
}
static char *fstab_node_to_udev_node(char *p) {
return strdup(p);
}
+static int mount_find_pri(char *options) {
+ char *end, *pri;
+ unsigned long r;
+
+ if (!(pri = mount_test_option(options, "pri=")))
+ return 0;
+
+ pri += 4;
+
+ errno = 0;
+ r = strtoul(pri, &end, 10);
+
+ if (errno != 0)
+ return -errno;
+
+ if (end == pri || (*end != ',' && *end != 0))
+ return -EINVAL;
+
+ return (int) r;
+}
+
static int mount_load_etc_fstab(Manager *m) {
FILE *f;
int r;
if (where[0] == '/')
path_kill_slashes(where);
- r = mount_add_one(m, what, where, me->mnt_opts, me->mnt_type, false, false);
+ if (streq(me->mnt_type, "swap")) {
+ int pri;
+
+ if ((pri = mount_find_pri(me->mnt_opts)) < 0)
+ r = pri;
+ else
+ r = swap_add_one(m,
+ what,
+ pri,
+ !!mount_test_option(me->mnt_opts, MNTOPT_NOAUTO),
+ !!mount_test_option(me->mnt_opts, "comment=systemd.swapon"),
+ false);
+ } else
+ r = mount_add_one(m, what, where, me->mnt_opts, me->mnt_type, false, false);
+
free(what);
free(where);
* table changes */
if ((r = mount_load_proc_self_mountinfo(m, true)) < 0) {
- log_error("Failed to reread /proc/self/mountinfo: %s", strerror(-errno));
+ log_error("Failed to reread /proc/self/mountinfo: %s", strerror(errno));
/* Reset flags, just in case, for later calls */
LIST_FOREACH(units_per_type, meta, m->units_per_type[UNIT_MOUNT]) {