From 9fff8a1f165eb401f5411f96c755bb7704fdaa81 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Wed, 13 Oct 2010 03:57:04 +0200 Subject: [PATCH] mount: hook in q fsck@.service instance for all mount points with passno > 0 --- src/mount.c | 52 ++++++++++++++++++++++++++++++++--------- src/mount.h | 1 + src/service.c | 61 ++++++++++++++++++++++++++++++++++++++++++++----- src/service.h | 2 ++ src/unit-name.c | 24 +++++++++++++++++++ src/unit-name.h | 1 + 6 files changed, 124 insertions(+), 17 deletions(-) diff --git a/src/mount.c b/src/mount.c index 28ed8c3d..9d79cd53 100644 --- a/src/mount.c +++ b/src/mount.c @@ -333,7 +333,7 @@ static bool mount_is_bind(MountParameters *p) { static int mount_add_device_links(Mount *m) { MountParameters *p; - bool nofail, noauto; + int r; assert(m); @@ -344,18 +344,45 @@ static int mount_add_device_links(Mount *m) { else return 0; - if (!p->what || path_equal(m->where, "/")) + if (!p->what) return 0; - if (mount_is_bind(p)) - return 0; + if (!mount_is_bind(p) && !path_equal(m->where, "/")) { + bool nofail, noauto; - noauto = !!mount_test_option(p->options, MNTOPT_NOAUTO); - nofail = !!mount_test_option(p->options, "nofail"); + noauto = !!mount_test_option(p->options, MNTOPT_NOAUTO); + nofail = !!mount_test_option(p->options, "nofail"); + + if ((r = unit_add_node_link(UNIT(m), p->what, + !noauto && nofail && + UNIT(m)->meta.manager->running_as == MANAGER_SYSTEM)) < 0) + return r; + } + + if (p->passno > 0 /* && + UNIT(m)->meta.manager->running_as == MANAGER_SYSTEM */) { + char *name; + Unit *fsck; + /* Let's add in the fsck service */ - return unit_add_node_link(UNIT(m), p->what, - !noauto && nofail && - UNIT(m)->meta.manager->running_as == MANAGER_SYSTEM); + if (!(name = unit_name_from_path_instance("fsck", p->what, ".service"))) + return -ENOMEM; + + if ((r = manager_load_unit_prepare(m->meta.manager, name, NULL, NULL, &fsck)) < 0) { + log_warning("Failed to prepare unit %s: %s", name, strerror(-r)); + free(name); + return r; + } + + free(name); + + SERVICE(fsck)->fsck_passno = p->passno; + + if ((r = unit_add_two_dependencies(UNIT(m), UNIT_AFTER, UNIT_WANTS, fsck, true)) < 0) + return r; + } + + return 0; } static int mount_add_default_dependencies(Mount *m) { @@ -1161,6 +1188,7 @@ static int mount_add_one( const char *where, const char *options, const char *fstype, + int passno, bool from_proc_self_mountinfo, bool set_flags) { int r; @@ -1248,6 +1276,8 @@ static int mount_add_one( free(p->fstype); p->fstype = f; + p->passno = passno; + unit_add_to_dbus_queue(u); return 0; @@ -1381,7 +1411,7 @@ static int mount_load_etc_fstab(Manager *m) { !!mount_test_option(me->mnt_opts, "comment=systemd.swapon"), false); } else - k = mount_add_one(m, what, where, me->mnt_opts, me->mnt_type, false, false); + k = mount_add_one(m, what, where, me->mnt_opts, me->mnt_type, me->mnt_passno, false, false); free(what); free(where); @@ -1447,7 +1477,7 @@ static int mount_load_proc_self_mountinfo(Manager *m, bool set_flags) { goto finish; } - if ((k = mount_add_one(m, d, p, o, fstype, true, set_flags)) < 0) + if ((k = mount_add_one(m, d, p, o, fstype, 0, true, set_flags)) < 0) r = k; clean_up: diff --git a/src/mount.h b/src/mount.h index 8d8c738b..954058ce 100644 --- a/src/mount.h +++ b/src/mount.h @@ -56,6 +56,7 @@ typedef struct MountParameters { char *what; char *options; char *fstype; + int passno; } MountParameters; struct Mount { diff --git a/src/service.c b/src/service.c index d3852c76..310aa28c 100644 --- a/src/service.c +++ b/src/service.c @@ -929,6 +929,47 @@ static int service_load_sysv(Service *s) { } #endif +static int fsck_fix_order(Service *s) { + Meta *other; + int r; + + assert(s); + + if (s->fsck_passno <= 0) + return 0; + + /* For each pair of services where both have an fsck priority + * we order things based on it. */ + + LIST_FOREACH(units_per_type, other, s->meta.manager->units_per_type[UNIT_SERVICE]) { + Service *t; + UnitDependency d; + + t = (Service*) other; + + if (s == t) + continue; + + if (t->meta.load_state != UNIT_LOADED) + continue; + + if (t->fsck_passno <= 0) + continue; + + if (t->fsck_passno < s->fsck_passno) + d = UNIT_AFTER; + else if (t->fsck_passno > s->fsck_passno) + d = UNIT_BEFORE; + else + continue; + + if (!(r = unit_add_dependency(UNIT(s), d, UNIT(t), true)) < 0) + return r; + } + + return 0; +} + static int service_verify(Service *s) { assert(s); @@ -1022,6 +1063,9 @@ static int service_load(Unit *u) { return r; #endif + if ((r = fsck_fix_order(s)) < 0) + return r; + if (s->bus_name) if ((r = unit_watch_bus_name(u, s->bus_name)) < 0) return r; @@ -1108,22 +1152,27 @@ static void service_dump(Unit *u, FILE *f, const char *prefix) { if (s->sysv_path) fprintf(f, "%sSysV Init Script Path: %s\n" - "%sSysV Init Script has LSB Header: %s\n", + "%sSysV Init Script has LSB Header: %s\n" + "%sSysVEnabled: %s\n", prefix, s->sysv_path, - prefix, yes_no(s->sysv_has_lsb)); + prefix, yes_no(s->sysv_has_lsb), + prefix, yes_no(s->sysv_enabled)); if (s->sysv_start_priority >= 0) fprintf(f, - "%sSysVStartPriority: %i\n" - "%sSysVEnabled: %s\n", - prefix, s->sysv_start_priority, - prefix, yes_no(s->sysv_enabled)); + "%sSysVStartPriority: %i\n", + prefix, s->sysv_start_priority); if (s->sysv_runlevels) fprintf(f, "%sSysVRunLevels: %s\n", prefix, s->sysv_runlevels); #endif + if (s->fsck_passno > 0) + fprintf(f, + "%sFsckPassNo: %i\n", + prefix, s->fsck_passno); + if (s->status_text) fprintf(f, "%sStatus Text: %s\n", prefix, s->status_text); diff --git a/src/service.h b/src/service.h index eb44a438..500bebff 100644 --- a/src/service.h +++ b/src/service.h @@ -110,6 +110,8 @@ struct Service { pid_t main_pid, control_pid; int socket_fd; + int fsck_passno; + bool permissions_start_only; bool root_directory_start_only; bool remain_after_exit; diff --git a/src/unit-name.c b/src/unit-name.c index cd6e3cea..dbaa4a7b 100644 --- a/src/unit-name.c +++ b/src/unit-name.c @@ -377,6 +377,30 @@ char *unit_name_from_path(const char *path, const char *suffix) { return r; } +char *unit_name_from_path_instance(const char *prefix, const char *path, const char *suffix) { + char *p, *r; + + assert(path); + assert(suffix); + + if (!(p = strdup(path))) + return NULL; + + path_kill_slashes(p); + + path = p[0] == '/' ? p + 1 : p; + + if (path[0] == 0) { + free(p); + return unit_name_build_escape(prefix, "-", suffix); + } + + r = unit_name_build_escape(prefix, path, suffix); + free(p); + + return r; +} + char *unit_name_to_path(const char *name) { char *w, *e; diff --git a/src/unit-name.h b/src/unit-name.h index db1a79e8..9842db35 100644 --- a/src/unit-name.h +++ b/src/unit-name.h @@ -49,6 +49,7 @@ char *unit_name_replace_instance(const char *f, const char *i); char *unit_name_template(const char *f); char *unit_name_from_path(const char *path, const char *suffix); +char *unit_name_from_path_instance(const char *prefix, const char *path, const char *suffix); char *unit_name_to_path(const char *name); #endif -- 2.39.5