Commit 9fff8a1f authored by Lennart Poettering's avatar Lennart Poettering
Browse files

mount: hook in q fsck@.service instance for all mount points with passno > 0

parent 560d8f23
......@@ -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:
......
......@@ -56,6 +56,7 @@ typedef struct MountParameters {
char *what;
char *options;
char *fstype;
int passno;
} MountParameters;
struct Mount {
......
......@@ -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);
......
......@@ -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;
......
......@@ -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;
......
......@@ -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
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment