chiark / gitweb /
mount: hook in q fsck@.service instance for all mount points with passno > 0
authorLennart Poettering <lennart@poettering.net>
Wed, 13 Oct 2010 01:57:04 +0000 (03:57 +0200)
committerLennart Poettering <lennart@poettering.net>
Wed, 13 Oct 2010 01:57:04 +0000 (03:57 +0200)
src/mount.c
src/mount.h
src/service.c
src/service.h
src/unit-name.c
src/unit-name.h

index 28ed8c3..9d79cd5 100644 (file)
@@ -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:
index 8d8c738..954058c 100644 (file)
@@ -56,6 +56,7 @@ typedef struct MountParameters {
         char *what;
         char *options;
         char *fstype;
+        int passno;
 } MountParameters;
 
 struct Mount {
index d3852c7..310aa28 100644 (file)
@@ -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);
index eb44a43..500bebf 100644 (file)
@@ -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;
index cd6e3ce..dbaa4a7 100644 (file)
@@ -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;
 
index db1a79e..9842db3 100644 (file)
@@ -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