X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?p=elogind.git;a=blobdiff_plain;f=mount.c;h=c989cddabf89f2e47c4e1ede7510aecc26d5752e;hp=55f11341a6bd03b9f134b2766721fd397a38d1d7;hb=07b0b134d3076fe223d6e15959b6081a74b56792;hpb=af5bc85dc1297079edc9890861aaa38de0ec30df diff --git a/mount.c b/mount.c index 55f11341a..c989cddab 100644 --- a/mount.c +++ b/mount.c @@ -113,87 +113,82 @@ static void mount_done(Unit *u) { unit_unwatch_timer(u, &m->timer_watch); } -static int mount_add_node_links(Mount *m) { +int mount_add_node_links(Unit *u, const char *what) { Unit *device; char *e; int r; - const char *what; - assert(m); - - /* Adds in links to the device that this node is based on */ + assert(u); - if (m->parameters_fragment.what) - what = m->parameters_fragment.what; - else if (m->parameters_etc_fstab.what) - what = m->parameters_etc_fstab.what; - else + if (!what) /* We observe kernel mounts only while they are live, * hence don't create any links for them */ return 0; + /* Adds in links to the device that this node is based on */ + if (!path_startswith(what, "/dev/")) return 0; if (!(e = unit_name_build_escape(what+1, NULL, ".device"))) return -ENOMEM; - r = manager_load_unit(UNIT(m)->meta.manager, e, NULL, &device); + r = manager_load_unit(u->meta.manager, e, NULL, &device); free(e); if (r < 0) return r; - if ((r = unit_add_dependency(UNIT(m), UNIT_AFTER, device, true)) < 0) + if ((r = unit_add_dependency(u, UNIT_AFTER, device, true)) < 0) return r; - if ((r = unit_add_dependency(UNIT(m), UNIT_REQUIRES, device, true)) < 0) + if ((r = unit_add_dependency(u, UNIT_REQUIRES, device, true)) < 0) return r; - 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) + if (u->meta.manager->running_as == MANAGER_INIT || + u->meta.manager->running_as == MANAGER_SYSTEM) + if ((r = unit_add_dependency(device, UNIT_WANTS, u, false)) < 0) return r; return 0; } -static int mount_add_path_links(Mount *m) { +int mount_add_path_links(Unit *u, const char *where, bool requires) { Meta *other; int r; - assert(m); + assert(u); /* 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]) { + LIST_FOREACH(units_per_type, other, u->meta.manager->units_per_type[UNIT_MOUNT]) { Mount *n; n = (Mount*) other; - if (n == m) + if (UNIT(n) == u) continue; - if (m->meta.load_state != UNIT_LOADED) + if (u->meta.load_state != UNIT_LOADED) continue; - if (path_startswith(m->where, n->where)) { + if (path_startswith(where, n->where)) { - if ((r = unit_add_dependency(UNIT(m), UNIT_AFTER, UNIT(other), true)) < 0) + if ((r = unit_add_dependency(u, UNIT_AFTER, UNIT(other), true)) < 0) return r; - if (n->from_etc_fstab || n->from_fragment) - if ((r = unit_add_dependency(UNIT(m), UNIT_REQUIRES, UNIT(other), true)) < 0) + if (requires) + if ((r = unit_add_dependency(u, UNIT_REQUIRES, UNIT(other), true)) < 0) return r; - } else if (path_startswith(n->where, m->where)) { + } else if (path_startswith(n->where, where)) { - if ((r = unit_add_dependency(UNIT(m), UNIT_BEFORE, UNIT(other), true)) < 0) + if ((r = unit_add_dependency(u, UNIT_BEFORE, UNIT(other), true)) < 0) return r; - if (m->from_etc_fstab || m->from_fragment) - if ((r = unit_add_dependency(UNIT(other), UNIT_REQUIRES, UNIT(m), true)) < 0) + if (requires) + if ((r = unit_add_dependency(UNIT(other), UNIT_REQUIRES, u, true)) < 0) return r; } } @@ -201,7 +196,7 @@ static int mount_add_path_links(Mount *m) { 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 +210,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,9 +229,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"); + 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; @@ -305,6 +300,9 @@ 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 = m->parameters_fragment.what; + if (!what) + what = m->parameters_etc_fstab.what; if (!m->where) if (!(m->where = unit_name_to_path(u->meta.id))) @@ -319,10 +317,10 @@ static int mount_load(Unit *u) { if (m->parameters_fragment.what) m->from_fragment = true; - if ((r = mount_add_node_links(MOUNT(u))) < 0) + if ((r = mount_add_node_links(u, what)) < 0) return r; - if ((r = mount_add_path_links(MOUNT(u))) < 0) + if ((r = mount_add_path_links(u, m->where, m->from_etc_fstab || m->from_fragment)) < 0) return r; if ((r = mount_add_target_links(MOUNT(u))) < 0) @@ -1049,9 +1047,9 @@ static int mount_add_one( goto fail; if (!(MOUNT(u)->where = strdup(where))) { - r = -ENOMEM; - goto fail; - } + r = -ENOMEM; + goto fail; + } if ((r = unit_set_description(u, where)) < 0) goto fail; @@ -1148,6 +1146,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 +1198,20 @@ 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, + !!mount_test_option(me->mnt_opts, MNTOPT_NOAUTO), + pri, + false); + } else + r = mount_add_one(m, what, where, me->mnt_opts, me->mnt_type, false, false); + free(what); free(where);