X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?a=blobdiff_plain;f=src%2Fcore%2Fmount.c;h=5c18d4e463128bf7f53eecd0735fea72a88f2099;hb=112a7f4696ebb96abdb42df62e1e794e903f66b3;hp=51a81a948870529d520e761f55456794800436c2;hpb=7f602784de4fd378120e8ebfe6d830862b9cae03;p=elogind.git diff --git a/src/core/mount.c b/src/core/mount.c index 51a81a948..5c18d4e46 100644 --- a/src/core/mount.c +++ b/src/core/mount.c @@ -82,6 +82,7 @@ static void mount_init(Unit *u) { } kill_context_init(&m->kill_context); + cgroup_context_init(&m->cgroup_context); /* We need to make sure that /bin/mount is always called in * the same process group as us, so that the autofs kernel @@ -127,6 +128,7 @@ static void mount_done(Unit *u) { mount_parameters_done(&m->parameters_proc_self_mountinfo); mount_parameters_done(&m->parameters_fragment); + cgroup_context_done(&m->cgroup_context); exec_context_done(&m->exec_context, manager_is_reloading_or_reexecuting(u->manager)); exec_command_done_array(m->exec_command, _MOUNT_EXEC_COMMAND_MAX); m->control_command = NULL; @@ -136,7 +138,7 @@ static void mount_done(Unit *u) { unit_unwatch_timer(u, &m->timer_watch); } -static MountParameters* get_mount_parameters_fragment(Mount *m) { +_pure_ static MountParameters* get_mount_parameters_fragment(Mount *m) { assert(m); if (m->from_fragment) @@ -145,7 +147,7 @@ static MountParameters* get_mount_parameters_fragment(Mount *m) { return NULL; } -static MountParameters* get_mount_parameters(Mount *m) { +_pure_ static MountParameters* get_mount_parameters(Mount *m) { assert(m); if (m->from_proc_self_mountinfo) @@ -293,7 +295,7 @@ static int mount_add_requires_mounts_links(Mount *m) { } static char* mount_test_option(const char *haystack, const char *needle) { - struct mntent me; + struct mntent me = { .mnt_opts = (char*) haystack }; assert(needle); @@ -303,9 +305,6 @@ static char* mount_test_option(const char *haystack, const char *needle) { if (!haystack) return NULL; - zero(me); - me.mnt_opts = (char*) haystack; - return hasmntopt(&me, needle); } @@ -339,6 +338,12 @@ static bool mount_is_bind(MountParameters *p) { return false; } +static bool mount_is_auto(MountParameters *p) { + assert(p); + + return !mount_test_option(p->options, "noauto"); +} + static bool needs_quota(MountParameters *p) { assert(p); @@ -357,6 +362,7 @@ static bool needs_quota(MountParameters *p) { static int mount_add_device_links(Mount *m) { MountParameters *p; + bool device_wants_mount = false; int r; assert(m); @@ -377,7 +383,10 @@ static int mount_add_device_links(Mount *m) { if (path_equal(m->where, "/")) return 0; - r = unit_add_node_link(UNIT(m), p->what, false); + if (mount_is_auto(p) && UNIT(m)->manager->running_as == SYSTEMD_SYSTEM) + device_wants_mount = true; + + r = unit_add_node_link(UNIT(m), p->what, device_wants_mount); if (r < 0) return r; @@ -438,6 +447,21 @@ static int mount_add_quota_links(Mount *m) { return 0; } +static bool should_umount(Mount *m) { + MountParameters *p; + + if (path_equal(m->where, "/") || + path_equal(m->where, "/usr")) + return false; + + p = get_mount_parameters(m); + if (p && mount_test_option(p->options, "x-initrd.mount") && + !in_initrd()) + return false; + + return true; +} + static int mount_add_default_dependencies(Mount *m) { const char *after, *after2, *online; MountParameters *p; @@ -482,9 +506,11 @@ static int mount_add_default_dependencies(Mount *m) { return r; } - r = unit_add_two_dependencies_by_name(UNIT(m), UNIT_BEFORE, UNIT_CONFLICTS, SPECIAL_UMOUNT_TARGET, NULL, true); - if (r < 0) - return r; + if (should_umount(m)) { + r = unit_add_two_dependencies_by_name(UNIT(m), UNIT_BEFORE, UNIT_CONFLICTS, SPECIAL_UMOUNT_TARGET, NULL, true); + if (r < 0) + return r; + } return 0; } @@ -650,7 +676,7 @@ static int mount_add_extras(Mount *m) { return r; } - r = unit_add_default_cgroups(u); + r = unit_add_default_slice(u); if (r < 0) return r; @@ -823,9 +849,9 @@ static void mount_dump(Unit *u, FILE *f, const char *prefix) { prefix, mount_state_to_string(m->state), prefix, mount_result_to_string(m->result), prefix, m->where, - prefix, strna(p->what), - prefix, strna(p->fstype), - prefix, strna(p->options), + prefix, p ? strna(p->what) : "n/a", + prefix, p ? strna(p->fstype) : "n/a", + prefix, p ? strna(p->options) : "n/a", prefix, yes_no(m->from_proc_self_mountinfo), prefix, yes_no(m->from_fragment), prefix, m->directory_mode); @@ -847,28 +873,31 @@ static int mount_spawn(Mount *m, ExecCommand *c, pid_t *_pid) { assert(c); assert(_pid); + unit_realize_cgroup(UNIT(m)); + 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, - NULL, - &m->exec_context, - NULL, 0, - UNIT(m)->manager->environment, - true, - true, - true, - UNIT(m)->manager->confirm_spawn, - UNIT(m)->cgroup_bondings, - UNIT(m)->cgroup_attributes, - NULL, - UNIT(m)->id, - NULL, - &pid)) < 0) + r = exec_spawn(c, + NULL, + &m->exec_context, + NULL, 0, + UNIT(m)->manager->environment, + true, + true, + true, + UNIT(m)->manager->confirm_spawn, + UNIT(m)->cgroup_mask, + UNIT(m)->cgroup_path, + UNIT(m)->id, + NULL, + &pid); + if (r < 0) goto fail; - if ((r = unit_watch_pid(UNIT(m), pid)) < 0) + r = unit_watch_pid(UNIT(m), pid); + if (r < 0) /* FIXME: we need to do something here */ goto fail; @@ -1263,19 +1292,19 @@ static int mount_deserialize_item(Unit *u, const char *key, const char *value, F return 0; } -static UnitActiveState mount_active_state(Unit *u) { +_pure_ static UnitActiveState mount_active_state(Unit *u) { assert(u); return state_translation_table[MOUNT(u)->state]; } -static const char *mount_sub_state_to_string(Unit *u) { +_pure_ static const char *mount_sub_state_to_string(Unit *u) { assert(u); return mount_state_to_string(MOUNT(u)->state); } -static bool mount_check_gc(Unit *u) { +_pure_ static bool mount_check_gc(Unit *u) { Mount *m = MOUNT(u); assert(m); @@ -1541,9 +1570,11 @@ static int mount_add_one( if (r < 0) goto fail; - r = unit_add_dependency_by_name(u, UNIT_CONFLICTS, SPECIAL_UMOUNT_TARGET, NULL, true); - if (r < 0) - goto fail; + if (should_umount(MOUNT(u))) { + r = unit_add_dependency_by_name(u, UNIT_CONFLICTS, SPECIAL_UMOUNT_TARGET, NULL, true); + if (r < 0) + goto fail; + } unit_add_to_load_queue(u); } else { @@ -1558,7 +1589,7 @@ static int mount_add_one( } } - if (u->load_state == UNIT_ERROR) { + if (u->load_state == UNIT_NOT_FOUND) { u->load_state = UNIT_LOADED; u->load_error = 0; @@ -1706,10 +1737,14 @@ static void mount_shutdown(Manager *m) { static int mount_enumerate(Manager *m) { int r; - struct epoll_event ev; assert(m); if (!m->proc_self_mountinfo) { + struct epoll_event ev = { + .events = EPOLLPRI, + .data.ptr = &m->mount_watch, + }; + m->proc_self_mountinfo = fopen("/proc/self/mountinfo", "re"); if (!m->proc_self_mountinfo) return -errno; @@ -1717,10 +1752,6 @@ static int mount_enumerate(Manager *m) { m->mount_watch.type = WATCH_MOUNT; m->mount_watch.fd = fileno(m->proc_self_mountinfo); - zero(ev); - ev.events = EPOLLPRI; - ev.data.ptr = &m->mount_watch; - if (epoll_ctl(m->epoll_fd, EPOLL_CTL_ADD, m->mount_watch.fd, &ev) < 0) return -errno; } @@ -1875,8 +1906,9 @@ const UnitVTable mount_vtable = { "Mount\0" "Install\0", + .private_section = "Mount", .exec_context_offset = offsetof(Mount, exec_context), - .exec_section = "Mount", + .cgroup_context_offset = offsetof(Mount, cgroup_context), .no_alias = true, .no_instances = true, @@ -1911,6 +1943,8 @@ const UnitVTable mount_vtable = { .bus_interface = "org.freedesktop.systemd1.Mount", .bus_message_handler = bus_mount_message_handler, .bus_invalidating_properties = bus_mount_invalidating_properties, + .bus_set_property = bus_mount_set_property, + .bus_commit_properties = bus_mount_commit_properties, .enumerate = mount_enumerate, .shutdown = mount_shutdown,