X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?p=elogind.git;a=blobdiff_plain;f=mount.c;h=b53c7c0d8a291a169ffbd65f1f35436fdfe9e175;hp=15cce6f8e442f64aa604042f5fe128605ae17300;hb=4e85aff465b2ce0fa34222e52a6f5a984140b22e;hpb=701cc384c283206a29b21e4e7302e5cf5f2d9433 diff --git a/mount.c b/mount.c index 15cce6f8e..b53c7c0d8 100644 --- a/mount.c +++ b/mount.c @@ -113,95 +113,87 @@ static void mount_done(Unit *u) { 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); @@ -215,7 +207,7 @@ static bool mount_test_option(const char *haystack, const char *needle) { zero(me); me.mnt_opts = (char*) haystack; - return !!hasmntopt(&me, needle); + return hasmntopt(&me, needle); } static int mount_add_target_links(Mount *m) { @@ -234,12 +226,9 @@ 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)) @@ -263,7 +252,7 @@ static int mount_add_target_links(Mount *m) { } else { - if (handle) + if (!noauto && handle) if ((r = unit_add_dependency(tu, UNIT_WANTS, UNIT(m), true)) < 0) return r; @@ -290,6 +279,11 @@ static int mount_verify(Mount *m) { 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; } @@ -305,6 +299,10 @@ static int mount_load(Unit *u) { /* 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))) @@ -312,20 +310,36 @@ static int mount_load(Unit *u) { 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) @@ -385,7 +399,7 @@ static void mount_set_state(Mount *m, MountState state) { 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)); @@ -492,6 +506,7 @@ static int mount_spawn(Mount *m, ExecCommand *c, pid_t *_pid) { NULL, &m->exec_context, NULL, 0, + m->meta.manager->environment, true, true, UNIT(m)->meta.manager->confirm_spawn, @@ -1009,7 +1024,7 @@ static int mount_add_one( Unit *u; bool delete; char *e, *w = NULL, *o = NULL, *f = NULL; - MountParameters *mp; + MountParameters *p; assert(m); assert(what); @@ -1027,8 +1042,8 @@ static int mount_add_one( 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"))) @@ -1049,12 +1064,9 @@ static int mount_add_one( 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 { @@ -1070,30 +1082,28 @@ static int mount_add_one( } 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); @@ -1107,7 +1117,7 @@ fail: if (delete && u) unit_free(u); - return 0; + return r; } static char *fstab_node_to_udev_node(char *p) { @@ -1148,6 +1158,27 @@ 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; @@ -1179,7 +1210,21 @@ static int mount_load_etc_fstab(Manager *m) { 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); @@ -1462,6 +1507,7 @@ const UnitVTable mount_vtable = { .no_alias = true, .no_instances = true, + .no_isolate = true, .init = mount_init, .load = mount_load,