summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLennart Poettering <lennart@poettering.net>2010-10-13 03:57:04 +0200
committerLennart Poettering <lennart@poettering.net>2010-10-13 03:57:04 +0200
commit9fff8a1f165eb401f5411f96c755bb7704fdaa81 (patch)
tree69b40bc4da9f6b8962d14c9ebf989f23d0133e82
parent560d8f23811162542c1748f711ea6dce269d2720 (diff)
mount: hook in q fsck@.service instance for all mount points with passno > 0
-rw-r--r--src/mount.c52
-rw-r--r--src/mount.h1
-rw-r--r--src/service.c61
-rw-r--r--src/service.h2
-rw-r--r--src/unit-name.c24
-rw-r--r--src/unit-name.h1
6 files changed, 124 insertions, 17 deletions
diff --git a/src/mount.c b/src/mount.c
index 28ed8c3ddc..9d79cd537d 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 8d8c738b07..954058ceb5 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 d3852c76a1..310aa28c0c 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 eb44a43895..500bebff08 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 cd6e3cea5c..dbaa4a7b12 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 db1a79e8d5..9842db3552 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