mirror of
https://github.com/AuxXxilium/eudev.git
synced 2025-01-27 09:35:52 +07:00
mount: replace PID1 internal fstab parser with generator
Bit by bit we should remove non-unit parsing from PID 1 and move into generators, to clean up our code base a bit and clearly separate parsers.
This commit is contained in:
parent
745e2fb79a
commit
6b1dc2bd3c
1
.gitignore
vendored
1
.gitignore
vendored
@ -1,3 +1,4 @@
|
||||
/systemd-fstab-generator
|
||||
/systemd-delta
|
||||
/systemd-sleep
|
||||
/systemd-inhibit
|
||||
|
12
Makefile.am
12
Makefile.am
@ -237,7 +237,8 @@ rootlibexec_PROGRAMS = \
|
||||
systemd-sleep
|
||||
|
||||
systemgenerator_PROGRAMS = \
|
||||
systemd-getty-generator
|
||||
systemd-getty-generator \
|
||||
systemd-fstab-generator
|
||||
|
||||
dist_bashcompletion_DATA = \
|
||||
bash-completion/systemd-bash-completion.sh
|
||||
@ -1133,6 +1134,15 @@ systemd_getty_generator_LDADD = \
|
||||
libsystemd-label.la \
|
||||
libsystemd-shared.la
|
||||
|
||||
# ------------------------------------------------------------------------------
|
||||
systemd_fstab_generator_SOURCES = \
|
||||
src/fstab-generator/fstab-generator.c \
|
||||
src/core/mount-setup.c
|
||||
|
||||
systemd_fstab_generator_LDADD = \
|
||||
libsystemd-label.la \
|
||||
libsystemd-shared.la
|
||||
|
||||
# ------------------------------------------------------------------------------
|
||||
systemd_rc_local_generator_SOURCES = \
|
||||
src/rc-local-generator/rc-local-generator.c
|
||||
|
6
TODO
6
TODO
@ -23,6 +23,8 @@ Bugfixes:
|
||||
|
||||
Features:
|
||||
|
||||
* replace sysvpath by a new more generic property
|
||||
|
||||
* make sure show-logs checks for utf8 validity, not ascii validity
|
||||
|
||||
* add CapbilityBoundingSet to system.conf to set system-wide caps bounds, and same for TimerSlackNS
|
||||
@ -31,8 +33,6 @@ Features:
|
||||
|
||||
* readahead: when bumping /sys readahead variable save mtime and compare later to detect changes
|
||||
|
||||
* in rescue mode don't pull in sockets
|
||||
|
||||
* Document boot options such as forcefsck
|
||||
|
||||
* (attempt to) make Debianites happy:
|
||||
@ -51,8 +51,6 @@ Features:
|
||||
|
||||
* move passno parsing to fstab generator
|
||||
|
||||
* actually queue the new default unit after switch-root
|
||||
|
||||
* improve !/proc/*/loginuid situation: make /proc/*/loginuid less dependent on CONFIG_AUDIT,
|
||||
or use the users cgroup information when /proc/*/loginuid is not available.
|
||||
|
||||
|
@ -156,14 +156,12 @@ static int automount_add_default_dependencies(Automount *a) {
|
||||
|
||||
assert(a);
|
||||
|
||||
if (UNIT(a)->manager->running_as == MANAGER_SYSTEM) {
|
||||
if (UNIT(a)->manager->running_as != MANAGER_SYSTEM)
|
||||
return 0;
|
||||
|
||||
if ((r = unit_add_dependency_by_name(UNIT(a), UNIT_BEFORE, SPECIAL_BASIC_TARGET, NULL, true)) < 0)
|
||||
return r;
|
||||
|
||||
if ((r = unit_add_two_dependencies_by_name(UNIT(a), UNIT_BEFORE, UNIT_CONFLICTS, SPECIAL_UMOUNT_TARGET, NULL, true)) < 0)
|
||||
return r;
|
||||
}
|
||||
r = unit_add_two_dependencies_by_name(UNIT(a), UNIT_BEFORE, UNIT_CONFLICTS, SPECIAL_UMOUNT_TARGET, NULL, true);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -80,8 +80,6 @@ static int bus_mount_append_what(DBusMessageIter *i, const char *property, void
|
||||
d = m->parameters_proc_self_mountinfo.what;
|
||||
else if (m->from_fragment && m->parameters_fragment.what)
|
||||
d = m->parameters_fragment.what;
|
||||
else if (m->from_etc_fstab && m->parameters_etc_fstab.what)
|
||||
d = m->parameters_etc_fstab.what;
|
||||
else
|
||||
d = "";
|
||||
|
||||
@ -103,8 +101,6 @@ static int bus_mount_append_options(DBusMessageIter *i, const char *property, vo
|
||||
d = m->parameters_proc_self_mountinfo.options;
|
||||
else if (m->from_fragment && m->parameters_fragment.options)
|
||||
d = m->parameters_fragment.options;
|
||||
else if (m->from_etc_fstab && m->parameters_etc_fstab.options)
|
||||
d = m->parameters_etc_fstab.options;
|
||||
else
|
||||
d = "";
|
||||
|
||||
@ -126,8 +122,6 @@ static int bus_mount_append_type(DBusMessageIter *i, const char *property, void
|
||||
d = m->parameters_proc_self_mountinfo.fstype;
|
||||
else if (m->from_fragment && m->parameters_fragment.fstype)
|
||||
d = m->parameters_fragment.fstype;
|
||||
else if (m->from_etc_fstab && m->parameters_etc_fstab.fstype)
|
||||
d = m->parameters_etc_fstab.fstype;
|
||||
else
|
||||
d = "";
|
||||
|
||||
|
@ -75,8 +75,6 @@ static int bus_swap_append_priority(DBusMessageIter *i, const char *property, vo
|
||||
j = s->parameters_proc_swaps.priority;
|
||||
else if (s->from_fragment)
|
||||
j = s->parameters_fragment.priority;
|
||||
else if (s->from_etc_fstab)
|
||||
j = s->parameters_etc_fstab.priority;
|
||||
else
|
||||
j = -1;
|
||||
|
||||
|
312
src/core/mount.c
312
src/core/mount.c
@ -68,9 +68,13 @@ static void mount_init(Unit *u) {
|
||||
|
||||
exec_context_init(&m->exec_context);
|
||||
|
||||
/* The stdio/kmsg bridge socket is on /, in order to avoid a
|
||||
* dep loop, don't use kmsg logging for -.mount */
|
||||
if (!unit_has_name(u, "-.mount")) {
|
||||
if (unit_has_name(u, "-.mount")) {
|
||||
/* Don't allow start/stop for root directory */
|
||||
UNIT(m)->refuse_manual_start = true;
|
||||
UNIT(m)->refuse_manual_stop = true;
|
||||
} else {
|
||||
/* The stdio/kmsg bridge socket is on /, in order to avoid a
|
||||
* dep loop, don't use kmsg logging for -.mount */
|
||||
m->exec_context.std_output = u->manager->default_std_output;
|
||||
m->exec_context.std_error = u->manager->default_std_error;
|
||||
}
|
||||
@ -116,7 +120,6 @@ static void mount_done(Unit *u) {
|
||||
free(m->where);
|
||||
m->where = NULL;
|
||||
|
||||
mount_parameters_done(&m->parameters_etc_fstab);
|
||||
mount_parameters_done(&m->parameters_proc_self_mountinfo);
|
||||
mount_parameters_done(&m->parameters_fragment);
|
||||
|
||||
@ -129,13 +132,11 @@ static void mount_done(Unit *u) {
|
||||
unit_unwatch_timer(u, &m->timer_watch);
|
||||
}
|
||||
|
||||
static MountParameters* get_mount_parameters_configured(Mount *m) {
|
||||
static MountParameters* get_mount_parameters_fragment(Mount *m) {
|
||||
assert(m);
|
||||
|
||||
if (m->from_fragment)
|
||||
return &m->parameters_fragment;
|
||||
else if (m->from_etc_fstab)
|
||||
return &m->parameters_etc_fstab;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
@ -146,7 +147,7 @@ static MountParameters* get_mount_parameters(Mount *m) {
|
||||
if (m->from_proc_self_mountinfo)
|
||||
return &m->parameters_proc_self_mountinfo;
|
||||
|
||||
return get_mount_parameters_configured(m);
|
||||
return get_mount_parameters_fragment(m);
|
||||
}
|
||||
|
||||
static int mount_add_mount_links(Mount *m) {
|
||||
@ -156,7 +157,7 @@ static int mount_add_mount_links(Mount *m) {
|
||||
|
||||
assert(m);
|
||||
|
||||
pm = get_mount_parameters_configured(m);
|
||||
pm = get_mount_parameters_fragment(m);
|
||||
|
||||
/* Adds in links to other mount points that might lie below or
|
||||
* above us in the hierarchy */
|
||||
@ -171,7 +172,7 @@ static int mount_add_mount_links(Mount *m) {
|
||||
if (UNIT(n)->load_state != UNIT_LOADED)
|
||||
continue;
|
||||
|
||||
pn = get_mount_parameters_configured(n);
|
||||
pn = get_mount_parameters_fragment(n);
|
||||
|
||||
if (path_startswith(m->where, n->where)) {
|
||||
|
||||
@ -336,160 +337,113 @@ static bool needs_quota(MountParameters *p) {
|
||||
mount_test_option(p->options, "grpjquota");
|
||||
}
|
||||
|
||||
static int mount_add_fstab_links(Mount *m) {
|
||||
const char *target, *after, *tu_wants = NULL;
|
||||
MountParameters *p;
|
||||
Unit *tu;
|
||||
int r;
|
||||
bool noauto, nofail, automount;
|
||||
|
||||
assert(m);
|
||||
|
||||
if (UNIT(m)->manager->running_as != MANAGER_SYSTEM)
|
||||
return 0;
|
||||
|
||||
if (!(p = get_mount_parameters_configured(m)))
|
||||
return 0;
|
||||
|
||||
if (p != &m->parameters_etc_fstab)
|
||||
return 0;
|
||||
|
||||
noauto = !!mount_test_option(p->options, "noauto");
|
||||
nofail = !!mount_test_option(p->options, "nofail");
|
||||
automount =
|
||||
mount_test_option(p->options, "comment=systemd.automount") ||
|
||||
mount_test_option(p->options, "x-systemd.automount");
|
||||
|
||||
if (mount_is_network(p)) {
|
||||
target = SPECIAL_REMOTE_FS_TARGET;
|
||||
after = tu_wants = SPECIAL_REMOTE_FS_PRE_TARGET;
|
||||
} else {
|
||||
target = SPECIAL_LOCAL_FS_TARGET;
|
||||
after = SPECIAL_LOCAL_FS_PRE_TARGET;
|
||||
}
|
||||
|
||||
r = manager_load_unit(UNIT(m)->manager, target, NULL, NULL, &tu);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
if (tu_wants) {
|
||||
r = unit_add_dependency_by_name(tu, UNIT_WANTS, tu_wants, NULL, true);
|
||||
if (r < 0)
|
||||
return r;
|
||||
}
|
||||
|
||||
if (after) {
|
||||
r = unit_add_dependency_by_name(UNIT(m), UNIT_AFTER, after, NULL, true);
|
||||
if (r < 0)
|
||||
return r;
|
||||
}
|
||||
|
||||
if (automount) {
|
||||
Unit *am;
|
||||
|
||||
if ((r = unit_load_related_unit(UNIT(m), ".automount", &am)) < 0)
|
||||
return r;
|
||||
|
||||
/* If auto is configured as well also pull in the
|
||||
* mount right-away, but don't rely on it. */
|
||||
if (!noauto) /* automount + auto */
|
||||
if ((r = unit_add_dependency(tu, UNIT_WANTS, UNIT(m), true)) < 0)
|
||||
return r;
|
||||
|
||||
/* Install automount unit */
|
||||
if (!nofail) /* automount + fail */
|
||||
return unit_add_two_dependencies(tu, UNIT_AFTER, UNIT_REQUIRES, am, true);
|
||||
else /* automount + nofail */
|
||||
return unit_add_two_dependencies(tu, UNIT_AFTER, UNIT_WANTS, am, true);
|
||||
|
||||
} else if (!noauto) {
|
||||
|
||||
/* Automatically add mount points that aren't natively
|
||||
* configured to local-fs.target */
|
||||
|
||||
if (!nofail) /* auto + fail */
|
||||
return unit_add_two_dependencies(tu, UNIT_AFTER, UNIT_REQUIRES, UNIT(m), true);
|
||||
else /* auto + nofail */
|
||||
return unit_add_dependency(tu, UNIT_WANTS, UNIT(m), true);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int mount_add_device_links(Mount *m) {
|
||||
MountParameters *p;
|
||||
int r;
|
||||
|
||||
assert(m);
|
||||
|
||||
if (!(p = get_mount_parameters_configured(m)))
|
||||
p = get_mount_parameters_fragment(m);
|
||||
if (!p)
|
||||
return 0;
|
||||
|
||||
if (!p->what)
|
||||
return 0;
|
||||
|
||||
if (!mount_is_bind(p) &&
|
||||
!path_equal(m->where, "/") &&
|
||||
p == &m->parameters_etc_fstab) {
|
||||
bool nofail, noauto;
|
||||
|
||||
noauto = !!mount_test_option(p->options, "noauto");
|
||||
nofail = !!mount_test_option(p->options, "nofail");
|
||||
|
||||
if ((r = unit_add_node_link(UNIT(m), p->what,
|
||||
!noauto && nofail &&
|
||||
UNIT(m)->manager->running_as == MANAGER_SYSTEM)) < 0)
|
||||
!path_equal(m->where, "/")) {
|
||||
r = unit_add_node_link(UNIT(m), p->what, false);
|
||||
if (r < 0)
|
||||
return r;
|
||||
}
|
||||
|
||||
if (p->passno > 0 &&
|
||||
!mount_is_bind(p) &&
|
||||
UNIT(m)->manager->running_as == MANAGER_SYSTEM &&
|
||||
!path_equal(m->where, "/")) {
|
||||
!path_equal(m->where, "/") &&
|
||||
UNIT(m)->manager->running_as == MANAGER_SYSTEM) {
|
||||
char *name;
|
||||
Unit *fsck;
|
||||
/* Let's add in the fsck service */
|
||||
|
||||
/* aka SPECIAL_FSCK_SERVICE */
|
||||
if (!(name = unit_name_from_path_instance("fsck", p->what, ".service")))
|
||||
name = unit_name_from_path_instance("fsck", p->what, ".service");
|
||||
if (!name)
|
||||
return -ENOMEM;
|
||||
|
||||
if ((r = manager_load_unit_prepare(UNIT(m)->manager, name, NULL, NULL, &fsck)) < 0) {
|
||||
r = manager_load_unit_prepare(UNIT(m)->manager, name, NULL, NULL, &fsck);
|
||||
if (r < 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_REQUIRES, fsck, true)) < 0)
|
||||
r = unit_add_two_dependencies(UNIT(m), UNIT_AFTER, UNIT_REQUIRES, fsck, true);
|
||||
if (r < 0)
|
||||
return r;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int mount_add_quota_links(Mount *m) {
|
||||
int r;
|
||||
MountParameters *p;
|
||||
|
||||
assert(m);
|
||||
|
||||
if (UNIT(m)->manager->running_as != MANAGER_SYSTEM)
|
||||
return 0;
|
||||
|
||||
p = get_mount_parameters_fragment(m);
|
||||
if (!p)
|
||||
return 0;
|
||||
|
||||
if (!needs_quota(p))
|
||||
return 0;
|
||||
|
||||
r = unit_add_two_dependencies_by_name(UNIT(m), UNIT_BEFORE, UNIT_WANTS, SPECIAL_QUOTACHECK_SERVICE, NULL, true);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = unit_add_two_dependencies_by_name(UNIT(m), UNIT_BEFORE, UNIT_WANTS, SPECIAL_QUOTAON_SERVICE, NULL, true);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int mount_add_default_dependencies(Mount *m) {
|
||||
int r;
|
||||
MountParameters *p;
|
||||
const char *after;
|
||||
|
||||
assert(m);
|
||||
|
||||
if (UNIT(m)->manager->running_as != MANAGER_SYSTEM)
|
||||
return 0;
|
||||
|
||||
p = get_mount_parameters_configured(m);
|
||||
if (p && needs_quota(p)) {
|
||||
if ((r = unit_add_two_dependencies_by_name(UNIT(m), UNIT_BEFORE, UNIT_WANTS, SPECIAL_QUOTACHECK_SERVICE, NULL, true)) < 0 ||
|
||||
(r = unit_add_two_dependencies_by_name(UNIT(m), UNIT_BEFORE, UNIT_WANTS, SPECIAL_QUOTAON_SERVICE, NULL, true)) < 0)
|
||||
return r;
|
||||
}
|
||||
p = get_mount_parameters_fragment(m);
|
||||
if (!p)
|
||||
return 0;
|
||||
|
||||
if (!path_equal(m->where, "/"))
|
||||
if ((r = unit_add_two_dependencies_by_name(UNIT(m), UNIT_BEFORE, UNIT_CONFLICTS, SPECIAL_UMOUNT_TARGET, NULL, true)) < 0)
|
||||
return r;
|
||||
if (path_equal(m->where, "/"))
|
||||
return 0;
|
||||
|
||||
if (mount_is_network(p))
|
||||
after = SPECIAL_REMOTE_FS_PRE_TARGET;
|
||||
else
|
||||
after = SPECIAL_LOCAL_FS_PRE_TARGET;
|
||||
|
||||
r = unit_add_two_dependencies_by_name(UNIT(m), UNIT_WANTS, UNIT_AFTER, after, NULL, true);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = unit_add_two_dependencies_by_name(UNIT(m), UNIT_BEFORE, UNIT_CONFLICTS, SPECIAL_UMOUNT_TARGET, NULL, true);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -505,7 +459,8 @@ static int mount_fix_timeouts(Mount *m) {
|
||||
|
||||
assert(m);
|
||||
|
||||
if (!(p = get_mount_parameters_configured(m)))
|
||||
p = get_mount_parameters_fragment(m);
|
||||
if (!p)
|
||||
return 0;
|
||||
|
||||
/* Allow configuration how long we wait for a device that
|
||||
@ -550,7 +505,7 @@ static int mount_verify(Mount *m) {
|
||||
if (UNIT(m)->load_state != UNIT_LOADED)
|
||||
return 0;
|
||||
|
||||
if (!m->from_etc_fstab && !m->from_fragment && !m->from_proc_self_mountinfo)
|
||||
if (!m->from_fragment && !m->from_proc_self_mountinfo)
|
||||
return -ENOENT;
|
||||
|
||||
if (!(e = unit_name_from_path(m->where, ".mount")))
|
||||
@ -599,11 +554,6 @@ static int mount_load(Unit *u) {
|
||||
|
||||
if (UNIT(m)->fragment_path)
|
||||
m->from_fragment = true;
|
||||
else if (m->from_etc_fstab)
|
||||
/* We always add several default dependencies to fstab mounts,
|
||||
* but we do not want the implicit complementing of Wants= with After=
|
||||
* in the target unit that this mount unit will be hooked into. */
|
||||
UNIT(m)->default_dependencies = false;
|
||||
|
||||
if (!m->where)
|
||||
if (!(m->where = unit_name_to_path(u->id)))
|
||||
@ -637,10 +587,11 @@ static int mount_load(Unit *u) {
|
||||
if ((r = mount_add_automount_links(m)) < 0)
|
||||
return r;
|
||||
|
||||
if ((r = mount_add_fstab_links(m)) < 0)
|
||||
r = mount_add_quota_links(m);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
if (UNIT(m)->default_dependencies || m->from_etc_fstab)
|
||||
if (UNIT(m)->default_dependencies)
|
||||
if ((r = mount_add_default_dependencies(m)) < 0)
|
||||
return r;
|
||||
|
||||
@ -775,7 +726,6 @@ static void mount_dump(Unit *u, FILE *f, const char *prefix) {
|
||||
"%sWhat: %s\n"
|
||||
"%sFile System Type: %s\n"
|
||||
"%sOptions: %s\n"
|
||||
"%sFrom /etc/fstab: %s\n"
|
||||
"%sFrom /proc/self/mountinfo: %s\n"
|
||||
"%sFrom fragment: %s\n"
|
||||
"%sDirectoryMode: %04o\n",
|
||||
@ -785,7 +735,6 @@ static void mount_dump(Unit *u, FILE *f, const char *prefix) {
|
||||
prefix, strna(p->what),
|
||||
prefix, strna(p->fstype),
|
||||
prefix, strna(p->options),
|
||||
prefix, yes_no(m->from_etc_fstab),
|
||||
prefix, yes_no(m->from_proc_self_mountinfo),
|
||||
prefix, yes_no(m->from_fragment),
|
||||
prefix, m->directory_mode);
|
||||
@ -969,7 +918,7 @@ static void mount_enter_mounting(Mount *m) {
|
||||
mkdir_p(m->where, m->directory_mode);
|
||||
|
||||
/* Create the source directory for bind-mounts if needed */
|
||||
p = get_mount_parameters_configured(m);
|
||||
p = get_mount_parameters_fragment(m);
|
||||
if (p && mount_is_bind(p))
|
||||
mkdir_p(p->what, m->directory_mode);
|
||||
|
||||
@ -982,12 +931,6 @@ static void mount_enter_mounting(Mount *m) {
|
||||
"-t", m->parameters_fragment.fstype ? m->parameters_fragment.fstype : "auto",
|
||||
m->parameters_fragment.options ? "-o" : NULL, m->parameters_fragment.options,
|
||||
NULL);
|
||||
else if (m->from_etc_fstab)
|
||||
r = exec_command_set(
|
||||
m->control_command,
|
||||
"/bin/mount",
|
||||
m->where,
|
||||
NULL);
|
||||
else
|
||||
r = -ENOENT;
|
||||
|
||||
@ -1046,14 +989,7 @@ static void mount_enter_remounting(Mount *m) {
|
||||
NULL);
|
||||
|
||||
free(buf);
|
||||
} else if (m->from_etc_fstab)
|
||||
r = exec_command_set(
|
||||
m->control_command,
|
||||
"/bin/mount",
|
||||
m->where,
|
||||
"-o", "remount",
|
||||
NULL);
|
||||
else
|
||||
} else
|
||||
r = -ENOENT;
|
||||
|
||||
if (r < 0)
|
||||
@ -1232,7 +1168,7 @@ static bool mount_check_gc(Unit *u) {
|
||||
|
||||
assert(m);
|
||||
|
||||
return m->from_etc_fstab || m->from_proc_self_mountinfo;
|
||||
return m->from_proc_self_mountinfo;
|
||||
}
|
||||
|
||||
static void mount_sigchld_event(Unit *u, pid_t pid, int code, int status) {
|
||||
@ -1416,7 +1352,6 @@ static int mount_add_one(
|
||||
const char *options,
|
||||
const char *fstype,
|
||||
int passno,
|
||||
bool from_proc_self_mountinfo,
|
||||
bool set_flags) {
|
||||
int r;
|
||||
Unit *u;
|
||||
@ -1430,8 +1365,6 @@ static int mount_add_one(
|
||||
assert(options);
|
||||
assert(fstype);
|
||||
|
||||
assert(!set_flags || from_proc_self_mountinfo);
|
||||
|
||||
/* Ignore API mount points. They should never be referenced in
|
||||
* dependencies ever. */
|
||||
if (mount_point_is_api(where) || mount_point_ignore(where))
|
||||
@ -1483,21 +1416,15 @@ static int mount_add_one(
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if (from_proc_self_mountinfo) {
|
||||
p = &MOUNT(u)->parameters_proc_self_mountinfo;
|
||||
|
||||
if (set_flags) {
|
||||
MOUNT(u)->is_mounted = true;
|
||||
MOUNT(u)->just_mounted = !MOUNT(u)->from_proc_self_mountinfo;
|
||||
MOUNT(u)->just_changed = !streq_ptr(p->options, o);
|
||||
}
|
||||
|
||||
MOUNT(u)->from_proc_self_mountinfo = true;
|
||||
} else {
|
||||
p = &MOUNT(u)->parameters_etc_fstab;
|
||||
MOUNT(u)->from_etc_fstab = true;
|
||||
p = &MOUNT(u)->parameters_proc_self_mountinfo;
|
||||
if (set_flags) {
|
||||
MOUNT(u)->is_mounted = true;
|
||||
MOUNT(u)->just_mounted = !MOUNT(u)->from_proc_self_mountinfo;
|
||||
MOUNT(u)->just_changed = !streq_ptr(p->options, o);
|
||||
}
|
||||
|
||||
MOUNT(u)->from_proc_self_mountinfo = true;
|
||||
|
||||
free(p->what);
|
||||
p->what = w;
|
||||
|
||||
@ -1545,68 +1472,6 @@ static int mount_find_pri(char *options) {
|
||||
return (int) r;
|
||||
}
|
||||
|
||||
static int mount_load_etc_fstab(Manager *m) {
|
||||
FILE *f;
|
||||
int r = 0;
|
||||
struct mntent* me;
|
||||
|
||||
assert(m);
|
||||
|
||||
errno = 0;
|
||||
f = setmntent("/etc/fstab", "r");
|
||||
if (!f)
|
||||
return errno == ENOENT ? 0 : -errno;
|
||||
|
||||
while ((me = getmntent(f))) {
|
||||
char *where, *what;
|
||||
int k;
|
||||
|
||||
if (!(what = fstab_node_to_udev_node(me->mnt_fsname))) {
|
||||
r = -ENOMEM;
|
||||
goto finish;
|
||||
}
|
||||
|
||||
if (!(where = strdup(me->mnt_dir))) {
|
||||
free(what);
|
||||
r = -ENOMEM;
|
||||
goto finish;
|
||||
}
|
||||
|
||||
if (what[0] == '/')
|
||||
path_kill_slashes(what);
|
||||
|
||||
if (where[0] == '/')
|
||||
path_kill_slashes(where);
|
||||
|
||||
if (streq(me->mnt_type, "swap")) {
|
||||
int pri;
|
||||
|
||||
if ((pri = mount_find_pri(me->mnt_opts)) < 0)
|
||||
k = pri;
|
||||
else
|
||||
k = swap_add_one(m,
|
||||
what,
|
||||
NULL,
|
||||
pri,
|
||||
!!mount_test_option(me->mnt_opts, "noauto"),
|
||||
!!mount_test_option(me->mnt_opts, "nofail"),
|
||||
false);
|
||||
} else
|
||||
k = mount_add_one(m, what, where, me->mnt_opts, me->mnt_type, me->mnt_passno, false, false);
|
||||
|
||||
free(what);
|
||||
free(where);
|
||||
|
||||
if (k < 0)
|
||||
r = k;
|
||||
}
|
||||
|
||||
finish:
|
||||
|
||||
endmntent(f);
|
||||
return r;
|
||||
}
|
||||
|
||||
static int mount_load_proc_self_mountinfo(Manager *m, bool set_flags) {
|
||||
int r = 0;
|
||||
unsigned i;
|
||||
@ -1659,7 +1524,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, 0, true, set_flags)) < 0)
|
||||
if ((k = mount_add_one(m, d, p, o, fstype, 0, set_flags)) < 0)
|
||||
r = k;
|
||||
|
||||
clean_up:
|
||||
@ -1715,9 +1580,6 @@ static int mount_enumerate(Manager *m) {
|
||||
return -errno;
|
||||
}
|
||||
|
||||
if ((r = mount_load_etc_fstab(m)) < 0)
|
||||
goto fail;
|
||||
|
||||
if ((r = mount_load_proc_self_mountinfo(m, false)) < 0)
|
||||
goto fail;
|
||||
|
||||
|
@ -75,11 +75,9 @@ struct Mount {
|
||||
|
||||
char *where;
|
||||
|
||||
MountParameters parameters_etc_fstab;
|
||||
MountParameters parameters_proc_self_mountinfo;
|
||||
MountParameters parameters_fragment;
|
||||
|
||||
bool from_etc_fstab:1;
|
||||
bool from_proc_self_mountinfo:1;
|
||||
bool from_fragment:1;
|
||||
|
||||
|
108
src/core/swap.c
108
src/core/swap.c
@ -87,7 +87,7 @@ static void swap_init(Unit *u) {
|
||||
s->exec_context.std_output = u->manager->default_std_output;
|
||||
s->exec_context.std_error = u->manager->default_std_error;
|
||||
|
||||
s->parameters_etc_fstab.priority = s->parameters_proc_swaps.priority = s->parameters_fragment.priority = -1;
|
||||
s->parameters_proc_swaps.priority = s->parameters_fragment.priority = -1;
|
||||
|
||||
s->timer_watch.type = WATCH_INVALID;
|
||||
|
||||
@ -116,9 +116,8 @@ static void swap_done(Unit *u) {
|
||||
free(s->what);
|
||||
s->what = NULL;
|
||||
|
||||
free(s->parameters_etc_fstab.what);
|
||||
free(s->parameters_fragment.what);
|
||||
s->parameters_etc_fstab.what = s->parameters_fragment.what = NULL;
|
||||
s->parameters_fragment.what = NULL;
|
||||
|
||||
exec_context_done(&s->exec_context);
|
||||
exec_command_done_array(s->exec_command, _SWAP_EXEC_COMMAND_MAX);
|
||||
@ -166,28 +165,16 @@ static int swap_add_mount_links(Swap *s) {
|
||||
|
||||
static int swap_add_target_links(Swap *s) {
|
||||
Unit *tu;
|
||||
SwapParameters *p;
|
||||
int r;
|
||||
|
||||
assert(s);
|
||||
|
||||
if (s->from_fragment)
|
||||
p = &s->parameters_fragment;
|
||||
else if (s->from_etc_fstab)
|
||||
p = &s->parameters_etc_fstab;
|
||||
else
|
||||
if (!s->from_fragment)
|
||||
return 0;
|
||||
|
||||
if ((r = manager_load_unit(UNIT(s)->manager, SPECIAL_SWAP_TARGET, NULL, NULL, &tu)) < 0)
|
||||
return r;
|
||||
|
||||
if (!p->noauto &&
|
||||
!p->nofail &&
|
||||
s->from_etc_fstab &&
|
||||
UNIT(s)->manager->running_as == MANAGER_SYSTEM)
|
||||
if ((r = unit_add_dependency(tu, UNIT_WANTS, UNIT(s), true)) < 0)
|
||||
return r;
|
||||
|
||||
return unit_add_dependency(UNIT(s), UNIT_BEFORE, tu, true);
|
||||
}
|
||||
|
||||
@ -201,8 +188,6 @@ static int swap_add_device_links(Swap *s) {
|
||||
|
||||
if (s->from_fragment)
|
||||
p = &s->parameters_fragment;
|
||||
else if (s->from_etc_fstab)
|
||||
p = &s->parameters_etc_fstab;
|
||||
else
|
||||
return 0;
|
||||
|
||||
@ -222,11 +207,12 @@ static int swap_add_default_dependencies(Swap *s) {
|
||||
|
||||
assert(s);
|
||||
|
||||
if (UNIT(s)->manager->running_as == MANAGER_SYSTEM) {
|
||||
if (UNIT(s)->manager->running_as != MANAGER_SYSTEM)
|
||||
return 0;
|
||||
|
||||
if ((r = unit_add_two_dependencies_by_name(UNIT(s), UNIT_BEFORE, UNIT_CONFLICTS, SPECIAL_UMOUNT_TARGET, NULL, true)) < 0)
|
||||
return r;
|
||||
}
|
||||
r = unit_add_two_dependencies_by_name(UNIT(s), UNIT_BEFORE, UNIT_CONFLICTS, SPECIAL_UMOUNT_TARGET, NULL, true);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -278,8 +264,6 @@ static int swap_load(Unit *u) {
|
||||
if (!s->what) {
|
||||
if (s->parameters_fragment.what)
|
||||
s->what = strdup(s->parameters_fragment.what);
|
||||
else if (s->parameters_etc_fstab.what)
|
||||
s->what = strdup(s->parameters_etc_fstab.what);
|
||||
else if (s->parameters_proc_swaps.what)
|
||||
s->what = strdup(s->parameters_proc_swaps.what);
|
||||
else
|
||||
@ -315,7 +299,7 @@ static int swap_load(Unit *u) {
|
||||
return swap_verify(s);
|
||||
}
|
||||
|
||||
int swap_add_one(
|
||||
static int swap_add_one(
|
||||
Manager *m,
|
||||
const char *what,
|
||||
const char *what_proc_swaps,
|
||||
@ -329,9 +313,11 @@ int swap_add_one(
|
||||
bool delete = false;
|
||||
int r;
|
||||
SwapParameters *p;
|
||||
Swap *first;
|
||||
|
||||
assert(m);
|
||||
assert(what);
|
||||
assert(what_proc_swaps);
|
||||
|
||||
e = unit_name_from_path(what, ".swap");
|
||||
if (!e)
|
||||
@ -339,8 +325,7 @@ int swap_add_one(
|
||||
|
||||
u = manager_get_unit(m, e);
|
||||
|
||||
if (what_proc_swaps &&
|
||||
u &&
|
||||
if (u &&
|
||||
SWAP(u)->from_proc_swaps &&
|
||||
!path_equal(SWAP(u)->parameters_proc_swaps.what, what_proc_swaps))
|
||||
return -EEXIST;
|
||||
@ -368,54 +353,37 @@ int swap_add_one(
|
||||
} else
|
||||
delete = false;
|
||||
|
||||
if (what_proc_swaps) {
|
||||
Swap *first;
|
||||
p = &SWAP(u)->parameters_proc_swaps;
|
||||
|
||||
p = &SWAP(u)->parameters_proc_swaps;
|
||||
|
||||
if (!p->what) {
|
||||
if (!(wp = strdup(what_proc_swaps))) {
|
||||
r = -ENOMEM;
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if (!m->swaps_by_proc_swaps)
|
||||
if (!(m->swaps_by_proc_swaps = hashmap_new(string_hash_func, string_compare_func))) {
|
||||
r = -ENOMEM;
|
||||
goto fail;
|
||||
}
|
||||
|
||||
free(p->what);
|
||||
p->what = wp;
|
||||
|
||||
first = hashmap_get(m->swaps_by_proc_swaps, wp);
|
||||
LIST_PREPEND(Swap, same_proc_swaps, first, SWAP(u));
|
||||
|
||||
if ((r = hashmap_replace(m->swaps_by_proc_swaps, wp, first)) < 0)
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if (set_flags) {
|
||||
SWAP(u)->is_active = true;
|
||||
SWAP(u)->just_activated = !SWAP(u)->from_proc_swaps;
|
||||
}
|
||||
|
||||
SWAP(u)->from_proc_swaps = true;
|
||||
|
||||
} else {
|
||||
p = &SWAP(u)->parameters_etc_fstab;
|
||||
|
||||
if (!(wp = strdup(what))) {
|
||||
if (!p->what) {
|
||||
if (!(wp = strdup(what_proc_swaps))) {
|
||||
r = -ENOMEM;
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if (!m->swaps_by_proc_swaps)
|
||||
if (!(m->swaps_by_proc_swaps = hashmap_new(string_hash_func, string_compare_func))) {
|
||||
r = -ENOMEM;
|
||||
goto fail;
|
||||
}
|
||||
|
||||
free(p->what);
|
||||
p->what = wp;
|
||||
|
||||
SWAP(u)->from_etc_fstab = true;
|
||||
first = hashmap_get(m->swaps_by_proc_swaps, wp);
|
||||
LIST_PREPEND(Swap, same_proc_swaps, first, SWAP(u));
|
||||
|
||||
if ((r = hashmap_replace(m->swaps_by_proc_swaps, wp, first)) < 0)
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if (set_flags) {
|
||||
SWAP(u)->is_active = true;
|
||||
SWAP(u)->just_activated = !SWAP(u)->from_proc_swaps;
|
||||
}
|
||||
|
||||
SWAP(u)->from_proc_swaps = true;
|
||||
|
||||
p->priority = priority;
|
||||
p->noauto = noauto;
|
||||
p->nofail = nofail;
|
||||
@ -567,8 +535,6 @@ static void swap_dump(Unit *u, FILE *f, const char *prefix) {
|
||||
p = &s->parameters_proc_swaps;
|
||||
else if (s->from_fragment)
|
||||
p = &s->parameters_fragment;
|
||||
else
|
||||
p = &s->parameters_etc_fstab;
|
||||
|
||||
fprintf(f,
|
||||
"%sSwap State: %s\n"
|
||||
@ -577,7 +543,6 @@ static void swap_dump(Unit *u, FILE *f, const char *prefix) {
|
||||
"%sPriority: %i\n"
|
||||
"%sNoAuto: %s\n"
|
||||
"%sNoFail: %s\n"
|
||||
"%sFrom /etc/fstab: %s\n"
|
||||
"%sFrom /proc/swaps: %s\n"
|
||||
"%sFrom fragment: %s\n",
|
||||
prefix, swap_state_to_string(s->state),
|
||||
@ -586,7 +551,6 @@ static void swap_dump(Unit *u, FILE *f, const char *prefix) {
|
||||
prefix, p->priority,
|
||||
prefix, yes_no(p->noauto),
|
||||
prefix, yes_no(p->nofail),
|
||||
prefix, yes_no(s->from_etc_fstab),
|
||||
prefix, yes_no(s->from_proc_swaps),
|
||||
prefix, yes_no(s->from_fragment));
|
||||
|
||||
@ -732,8 +696,6 @@ static void swap_enter_activating(Swap *s) {
|
||||
|
||||
if (s->from_fragment)
|
||||
priority = s->parameters_fragment.priority;
|
||||
else if (s->from_etc_fstab)
|
||||
priority = s->parameters_etc_fstab.priority;
|
||||
else
|
||||
priority = -1;
|
||||
|
||||
@ -928,7 +890,7 @@ static bool swap_check_gc(Unit *u) {
|
||||
|
||||
assert(s);
|
||||
|
||||
return s->from_etc_fstab || s->from_proc_swaps;
|
||||
return s->from_proc_swaps;
|
||||
}
|
||||
|
||||
static void swap_sigchld_event(Unit *u, pid_t pid, int code, int status) {
|
||||
@ -1269,8 +1231,6 @@ static int swap_enumerate(Manager *m) {
|
||||
return -errno;
|
||||
}
|
||||
|
||||
/* We rely on mount.c to load /etc/fstab for us */
|
||||
|
||||
if ((r = swap_load_proc_swaps(m, false)) < 0)
|
||||
swap_shutdown(m);
|
||||
|
||||
|
@ -71,11 +71,9 @@ struct Swap {
|
||||
|
||||
char *what;
|
||||
|
||||
SwapParameters parameters_etc_fstab;
|
||||
SwapParameters parameters_proc_swaps;
|
||||
SwapParameters parameters_fragment;
|
||||
|
||||
bool from_etc_fstab:1;
|
||||
bool from_proc_swaps:1;
|
||||
bool from_fragment:1;
|
||||
|
||||
@ -108,8 +106,6 @@ struct Swap {
|
||||
|
||||
extern const UnitVTable swap_vtable;
|
||||
|
||||
int swap_add_one(Manager *m, const char *what, const char *what_proc_swaps, int prio, bool no_auto, bool no_fail, bool set_flags);
|
||||
|
||||
int swap_add_one_mount_link(Swap *s, Mount *m);
|
||||
|
||||
int swap_dispatch_reload(Manager *m);
|
||||
|
@ -112,6 +112,7 @@ static int create_disk(
|
||||
}
|
||||
|
||||
fprintf(f,
|
||||
"# Automatically generated by systemd-cryptsetup-generator\n\n"
|
||||
"[Unit]\n"
|
||||
"Description=Cryptography Setup for %%I\n"
|
||||
"Conflicts=umount.target\n"
|
||||
|
1
src/fstab-generator/Makefile
Symbolic link
1
src/fstab-generator/Makefile
Symbolic link
@ -0,0 +1 @@
|
||||
../Makefile
|
517
src/fstab-generator/fstab-generator.c
Normal file
517
src/fstab-generator/fstab-generator.c
Normal file
@ -0,0 +1,517 @@
|
||||
/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
|
||||
|
||||
/***
|
||||
This file is part of systemd.
|
||||
|
||||
Copyright 2012 Lennart Poettering
|
||||
|
||||
systemd is free software; you can redistribute it and/or modify it
|
||||
under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation; either version 2.1 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
systemd is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with systemd; If not, see <http://www.gnu.org/licenses/>.
|
||||
***/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <mntent.h>
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "log.h"
|
||||
#include "util.h"
|
||||
#include "unit-name.h"
|
||||
#include "path-util.h"
|
||||
#include "mount-setup.h"
|
||||
#include "special.h"
|
||||
#include "mkdir.h"
|
||||
|
||||
static const char *arg_dest = "/tmp";
|
||||
|
||||
static int device_name(const char *path, char **unit) {
|
||||
char *p;
|
||||
|
||||
assert(path);
|
||||
|
||||
if (!is_device_path(path))
|
||||
return 0;
|
||||
|
||||
p = unit_name_from_path(path, ".device");
|
||||
if (!p)
|
||||
return -ENOMEM;
|
||||
|
||||
*unit = p;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int mount_find_pri(struct mntent *me, int *ret) {
|
||||
char *end, *pri;
|
||||
unsigned long r;
|
||||
|
||||
assert(me);
|
||||
assert(ret);
|
||||
|
||||
pri = hasmntopt(me, "pri");
|
||||
if (!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;
|
||||
|
||||
*ret = (int) r;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int add_swap(const char *what, struct mntent *me) {
|
||||
char *name = NULL, *unit = NULL, *lnk = NULL, *device = NULL;
|
||||
FILE *f = NULL;
|
||||
bool noauto, nofail;
|
||||
int r, pri = -1;
|
||||
|
||||
assert(what);
|
||||
assert(me);
|
||||
|
||||
r = mount_find_pri(me, &pri);
|
||||
if (r < 0) {
|
||||
log_error("Failed to parse priority");
|
||||
return pri;
|
||||
}
|
||||
|
||||
noauto = !!hasmntopt(me, "noauto");
|
||||
nofail = !!hasmntopt(me, "nofail");
|
||||
|
||||
name = unit_name_from_path(what, ".swap");
|
||||
if (!name) {
|
||||
log_error("Out of memory");
|
||||
r = -ENOMEM;
|
||||
goto finish;
|
||||
}
|
||||
|
||||
unit = join(arg_dest, "/", name, NULL);
|
||||
if (!unit) {
|
||||
log_error("Out of memory");
|
||||
r = -ENOMEM;
|
||||
goto finish;
|
||||
}
|
||||
|
||||
f = fopen(unit, "wxe");
|
||||
if (!f) {
|
||||
r = -errno;
|
||||
log_error("Failed to create unit file: %m");
|
||||
goto finish;
|
||||
}
|
||||
|
||||
fputs("# Automatically generated by systemd-fstab-generator\n\n"
|
||||
"[Unit]\n"
|
||||
"DefaultDependencies=no\n"
|
||||
"Conflicts=" SPECIAL_UMOUNT_TARGET "\n"
|
||||
"Before=" SPECIAL_UMOUNT_TARGET "\n", f);
|
||||
|
||||
if (!noauto && !nofail)
|
||||
fputs("Before=" SPECIAL_SWAP_TARGET "\n", f);
|
||||
|
||||
fprintf(f,
|
||||
"\n"
|
||||
"[Swap]\n"
|
||||
"What=%s\n",
|
||||
what);
|
||||
|
||||
if (pri >= 0)
|
||||
fprintf(f,
|
||||
"Priority=%i\n",
|
||||
pri);
|
||||
|
||||
fflush(f);
|
||||
if (ferror(f)) {
|
||||
log_error("Failed to write unit file: %m");
|
||||
r = -errno;
|
||||
goto finish;
|
||||
}
|
||||
|
||||
if (!noauto) {
|
||||
lnk = join(arg_dest, "/" SPECIAL_SWAP_TARGET ".wants/", name, NULL);
|
||||
if (!lnk) {
|
||||
log_error("Out of memory");
|
||||
r = -ENOMEM;
|
||||
goto finish;
|
||||
}
|
||||
|
||||
mkdir_parents(lnk, 0755);
|
||||
if (symlink(unit, lnk) < 0) {
|
||||
log_error("Failed to create symlink: %m");
|
||||
r = -errno;
|
||||
goto finish;
|
||||
}
|
||||
|
||||
r = device_name(what, &device);
|
||||
if (r < 0) {
|
||||
log_error("Out of memory");
|
||||
r = -ENOMEM;
|
||||
goto finish;
|
||||
}
|
||||
|
||||
if (r > 0) {
|
||||
free(lnk);
|
||||
lnk = join(arg_dest, "/", device, ".wants/", name, NULL);
|
||||
if (!lnk) {
|
||||
log_error("Out of memory");
|
||||
r = -ENOMEM;
|
||||
goto finish;
|
||||
}
|
||||
|
||||
mkdir_parents(lnk, 0755);
|
||||
if (symlink(unit, lnk) < 0) {
|
||||
log_error("Failed to create symlink: %m");
|
||||
r = -errno;
|
||||
goto finish;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
r = 0;
|
||||
finish:
|
||||
if (f)
|
||||
fclose(f);
|
||||
|
||||
free(unit);
|
||||
free(lnk);
|
||||
free(name);
|
||||
free(device);
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
static bool mount_is_bind(struct mntent *me) {
|
||||
assert(me);
|
||||
|
||||
return
|
||||
hasmntopt(me, "bind") ||
|
||||
streq(me->mnt_opts, "bind");
|
||||
}
|
||||
|
||||
static bool mount_is_network(struct mntent *me) {
|
||||
assert(me);
|
||||
|
||||
return
|
||||
hasmntopt(me, "_netdev") ||
|
||||
fstype_is_network(me->mnt_type);
|
||||
}
|
||||
|
||||
static int add_mount(const char *what, const char *where, struct mntent *me) {
|
||||
char *name = NULL, *unit = NULL, *lnk = NULL, *device = NULL, *automount_name = NULL, *automount_unit = NULL;
|
||||
FILE *f = NULL;
|
||||
bool noauto, nofail, automount, isbind, isnetwork;
|
||||
int r;
|
||||
const char *post, *pre;
|
||||
|
||||
assert(what);
|
||||
assert(where);
|
||||
assert(me);
|
||||
|
||||
if (streq(me->mnt_type, "autofs"))
|
||||
return 0;
|
||||
|
||||
if (!is_path(where)) {
|
||||
log_warning("Mount point %s is not a valid path, ignoring.", where);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (mount_point_is_api(where) ||
|
||||
mount_point_ignore(where))
|
||||
return 0;
|
||||
|
||||
isnetwork = mount_is_network(me);
|
||||
isbind = mount_is_bind(me);
|
||||
|
||||
noauto = !!hasmntopt(me, "noauto");
|
||||
nofail = !!hasmntopt(me, "nofail");
|
||||
automount =
|
||||
hasmntopt(me, "comment=systemd.automount") ||
|
||||
hasmntopt(me, "x-systemd.automount");
|
||||
|
||||
if (isnetwork) {
|
||||
post = SPECIAL_REMOTE_FS_TARGET;
|
||||
pre = SPECIAL_REMOTE_FS_PRE_TARGET;
|
||||
} else {
|
||||
post = SPECIAL_LOCAL_FS_TARGET;
|
||||
pre = SPECIAL_LOCAL_FS_PRE_TARGET;
|
||||
}
|
||||
|
||||
name = unit_name_from_path(where, ".mount");
|
||||
if (!name) {
|
||||
log_error("Out of memory");
|
||||
r = -ENOMEM;
|
||||
goto finish;
|
||||
}
|
||||
|
||||
unit = join(arg_dest, "/", name, NULL);
|
||||
if (!unit) {
|
||||
log_error("Out of memory");
|
||||
r = -ENOMEM;
|
||||
goto finish;
|
||||
}
|
||||
|
||||
f = fopen(unit, "wxe");
|
||||
if (!f) {
|
||||
r = -errno;
|
||||
log_error("Failed to create unit file: %m");
|
||||
goto finish;
|
||||
}
|
||||
|
||||
fputs("# Automatically generated by systemd-fstab-generator\n\n"
|
||||
"[Unit]\n"
|
||||
"DefaultDependencies=no\n", f);
|
||||
|
||||
if (!path_equal(where, "/"))
|
||||
fprintf(f,
|
||||
"After=%s\n"
|
||||
"Wants=%s\n"
|
||||
"Conflicts=" SPECIAL_UMOUNT_TARGET "\n"
|
||||
"Before=" SPECIAL_UMOUNT_TARGET "\n",
|
||||
pre,
|
||||
pre);
|
||||
|
||||
|
||||
if (!noauto && !nofail && !automount)
|
||||
fprintf(f,
|
||||
"Before=%s\n",
|
||||
post);
|
||||
|
||||
fprintf(f,
|
||||
"\n"
|
||||
"[Mount]\n"
|
||||
"What=%s\n"
|
||||
"Where=%s\n"
|
||||
"Type=%s\n"
|
||||
"FsckPassNo=%i\n",
|
||||
what,
|
||||
where,
|
||||
me->mnt_type,
|
||||
me->mnt_passno);
|
||||
|
||||
if (!isempty(me->mnt_opts) &&
|
||||
!streq(me->mnt_opts, "defaults"))
|
||||
fprintf(f,
|
||||
"Options=%s\n",
|
||||
me->mnt_opts);
|
||||
|
||||
fflush(f);
|
||||
if (ferror(f)) {
|
||||
log_error("Failed to write unit file: %m");
|
||||
r = -errno;
|
||||
goto finish;
|
||||
}
|
||||
|
||||
if (!noauto) {
|
||||
lnk = join(arg_dest, "/", post, nofail || automount ? ".wants/" : ".requires/", name, NULL);
|
||||
if (!lnk) {
|
||||
log_error("Out of memory");
|
||||
r = -ENOMEM;
|
||||
goto finish;
|
||||
}
|
||||
|
||||
mkdir_parents(lnk, 0755);
|
||||
if (symlink(unit, lnk) < 0) {
|
||||
log_error("Failed to create symlink: %m");
|
||||
r = -errno;
|
||||
goto finish;
|
||||
}
|
||||
|
||||
if (!isbind &&
|
||||
!path_equal(where, "/")) {
|
||||
|
||||
r = device_name(what, &device);
|
||||
if (r < 0) {
|
||||
log_error("Out of memory");
|
||||
r = -ENOMEM;
|
||||
goto finish;
|
||||
}
|
||||
|
||||
if (r > 0) {
|
||||
free(lnk);
|
||||
lnk = join(arg_dest, "/", device, ".wants/", name, NULL);
|
||||
if (!lnk) {
|
||||
log_error("Out of memory");
|
||||
r = -ENOMEM;
|
||||
goto finish;
|
||||
}
|
||||
|
||||
mkdir_parents(lnk, 0755);
|
||||
if (symlink(unit, lnk) < 0) {
|
||||
log_error("Failed to creat symlink: %m");
|
||||
r = -errno;
|
||||
goto finish;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (automount && !path_equal(where, "/")) {
|
||||
automount_name = unit_name_from_path(where, ".automount");
|
||||
if (!name) {
|
||||
log_error("Out of memory");
|
||||
r = -ENOMEM;
|
||||
goto finish;
|
||||
}
|
||||
|
||||
automount_unit = join(arg_dest, "/", automount_name, NULL);
|
||||
if (!automount_unit) {
|
||||
log_error("Out of memory");
|
||||
r = -ENOMEM;
|
||||
goto finish;
|
||||
}
|
||||
|
||||
fclose(f);
|
||||
f = fopen(automount_unit, "wxe");
|
||||
if (!f) {
|
||||
r = -errno;
|
||||
log_error("Failed to create unit file: %m");
|
||||
goto finish;
|
||||
}
|
||||
|
||||
fprintf(f,
|
||||
"# Automatically generated by systemd-fstab-generator\n\n"
|
||||
"[Unit]\n"
|
||||
"DefaultDependencies=no\n"
|
||||
"Conflicts=" SPECIAL_UMOUNT_TARGET "\n"
|
||||
"Before=" SPECIAL_UMOUNT_TARGET " %s\n"
|
||||
"\n"
|
||||
"[Automount]\n"
|
||||
"Where=%s\n",
|
||||
post,
|
||||
where);
|
||||
|
||||
fflush(f);
|
||||
if (ferror(f)) {
|
||||
log_error("Failed to write unit file: %m");
|
||||
r = -errno;
|
||||
goto finish;
|
||||
}
|
||||
|
||||
free(lnk);
|
||||
lnk = join(arg_dest, "/", post, nofail ? ".wants/" : ".requires/", automount_name, NULL);
|
||||
if (!lnk) {
|
||||
log_error("Out of memory");
|
||||
r = -ENOMEM;
|
||||
goto finish;
|
||||
}
|
||||
|
||||
mkdir_parents(lnk, 0755);
|
||||
if (symlink(automount_unit, lnk) < 0) {
|
||||
log_error("Failed to create symlink: %m");
|
||||
r = -errno;
|
||||
goto finish;
|
||||
}
|
||||
}
|
||||
|
||||
r = 0;
|
||||
finish:
|
||||
if (f)
|
||||
fclose(f);
|
||||
|
||||
free(unit);
|
||||
free(lnk);
|
||||
free(name);
|
||||
free(device);
|
||||
free(automount_name);
|
||||
free(automount_unit);
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
static int parse_fstab(void) {
|
||||
FILE *f;
|
||||
int r = 0;
|
||||
struct mntent *me;
|
||||
|
||||
errno = 0;
|
||||
f = setmntent("/etc/fstab", "r");
|
||||
if (!f) {
|
||||
if (errno == ENOENT)
|
||||
return 0;
|
||||
|
||||
log_error("Failed to open /etc/fstab: %m");
|
||||
return -errno;
|
||||
}
|
||||
|
||||
while ((me = getmntent(f))) {
|
||||
char *where, *what;
|
||||
int k;
|
||||
|
||||
what = fstab_node_to_udev_node(me->mnt_fsname);
|
||||
if (!what) {
|
||||
log_error("Out of memory");
|
||||
r = -ENOMEM;
|
||||
goto finish;
|
||||
}
|
||||
|
||||
where = strdup(me->mnt_dir);
|
||||
if (!where) {
|
||||
log_error("Out of memory");
|
||||
free(what);
|
||||
r = -ENOMEM;
|
||||
goto finish;
|
||||
}
|
||||
|
||||
if (is_path(what))
|
||||
path_kill_slashes(what);
|
||||
|
||||
if (is_path(where))
|
||||
path_kill_slashes(where);
|
||||
|
||||
log_debug("Found entry what=%s where=%s type=%s", what, where, me->mnt_type);
|
||||
|
||||
if (streq(me->mnt_type, "swap"))
|
||||
k = add_swap(what, me);
|
||||
else
|
||||
k = add_mount(what, where, me);
|
||||
|
||||
free(what);
|
||||
free(where);
|
||||
|
||||
if (k < 0)
|
||||
r = k;
|
||||
}
|
||||
|
||||
finish:
|
||||
endmntent(f);
|
||||
return r;
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
int r;
|
||||
|
||||
if (argc > 2) {
|
||||
log_error("This program takes one or no arguments.");
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
if (argc > 1)
|
||||
arg_dest = argv[1];
|
||||
|
||||
log_set_target(LOG_TARGET_AUTO);
|
||||
log_parse_environment();
|
||||
log_open();
|
||||
|
||||
log_set_max_level(LOG_DEBUG);
|
||||
|
||||
umask(0022);
|
||||
|
||||
r = parse_fstab();
|
||||
|
||||
return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS;
|
||||
}
|
Loading…
Reference in New Issue
Block a user