Add x-systemd.makefs option for fstab
I opted to completely generate a unit for both mount points and swaps. For swaps, it would be possible to use fixed template unit like systemd-mkswap@.service, because there's no information passed except the device name. For mount points, that's not possible because both the device name and file system type need to be passed. Nevertheless, I expect that options will need to passed to both mkfs and mkswap, in which case it'll be necessary to create units of both types anyway.
This commit is contained in:
parent
4191418baf
commit
da495a0385
|
@ -182,6 +182,7 @@ conf.set_quoted('CATALOG_DATABASE', join_paths(catalog
|
||||||
conf.set_quoted('SYSTEMD_CGROUP_AGENT_PATH', join_paths(rootlibexecdir, 'systemd-cgroups-agent'))
|
conf.set_quoted('SYSTEMD_CGROUP_AGENT_PATH', join_paths(rootlibexecdir, 'systemd-cgroups-agent'))
|
||||||
conf.set_quoted('SYSTEMD_BINARY_PATH', join_paths(rootlibexecdir, 'systemd'))
|
conf.set_quoted('SYSTEMD_BINARY_PATH', join_paths(rootlibexecdir, 'systemd'))
|
||||||
conf.set_quoted('SYSTEMD_FSCK_PATH', join_paths(rootlibexecdir, 'systemd-fsck'))
|
conf.set_quoted('SYSTEMD_FSCK_PATH', join_paths(rootlibexecdir, 'systemd-fsck'))
|
||||||
|
conf.set_quoted('SYSTEMD_MAKEFS_PATH', join_paths(rootlibexecdir, 'systemd-makefs'))
|
||||||
conf.set_quoted('SYSTEMD_SHUTDOWN_BINARY_PATH', join_paths(rootlibexecdir, 'systemd-shutdown'))
|
conf.set_quoted('SYSTEMD_SHUTDOWN_BINARY_PATH', join_paths(rootlibexecdir, 'systemd-shutdown'))
|
||||||
conf.set_quoted('SYSTEMD_SLEEP_BINARY_PATH', join_paths(rootlibexecdir, 'systemd-sleep'))
|
conf.set_quoted('SYSTEMD_SLEEP_BINARY_PATH', join_paths(rootlibexecdir, 'systemd-sleep'))
|
||||||
conf.set_quoted('SYSTEMCTL_BINARY_PATH', join_paths(rootbindir, 'systemctl'))
|
conf.set_quoted('SYSTEMCTL_BINARY_PATH', join_paths(rootbindir, 'systemctl'))
|
||||||
|
|
|
@ -51,6 +51,7 @@ typedef enum MountpointFlags {
|
||||||
NOAUTO = 1 << 0,
|
NOAUTO = 1 << 0,
|
||||||
NOFAIL = 1 << 1,
|
NOFAIL = 1 << 1,
|
||||||
AUTOMOUNT = 1 << 2,
|
AUTOMOUNT = 1 << 2,
|
||||||
|
MAKEFS = 1 << 3,
|
||||||
} MountpointFlags;
|
} MountpointFlags;
|
||||||
|
|
||||||
static const char *arg_dest = "/tmp";
|
static const char *arg_dest = "/tmp";
|
||||||
|
@ -155,6 +156,12 @@ static int add_swap(
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return r;
|
return r;
|
||||||
|
|
||||||
|
if (flags & MAKEFS) {
|
||||||
|
r = generator_hook_up_mkswap(arg_dest, what);
|
||||||
|
if (r < 0)
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
if (!(flags & NOAUTO)) {
|
if (!(flags & NOAUTO)) {
|
||||||
r = generator_add_symlink(arg_dest, SPECIAL_SWAP_TARGET,
|
r = generator_add_symlink(arg_dest, SPECIAL_SWAP_TARGET,
|
||||||
(flags & NOFAIL) ? "wants" : "requires", name);
|
(flags & NOFAIL) ? "wants" : "requires", name);
|
||||||
|
@ -307,10 +314,11 @@ static int add_mount(
|
||||||
const char *source) {
|
const char *source) {
|
||||||
|
|
||||||
_cleanup_free_ char
|
_cleanup_free_ char
|
||||||
*name = NULL, *unit = NULL,
|
*name = NULL,
|
||||||
*automount_name = NULL, *automount_unit = NULL,
|
*automount_name = NULL, *automount_unit = NULL,
|
||||||
*filtered = NULL,
|
*filtered = NULL,
|
||||||
*where_escaped = NULL;
|
*where_escaped = NULL;
|
||||||
|
const char *unit;
|
||||||
_cleanup_fclose_ FILE *f = NULL;
|
_cleanup_fclose_ FILE *f = NULL;
|
||||||
int r;
|
int r;
|
||||||
|
|
||||||
|
@ -347,9 +355,7 @@ static int add_mount(
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return log_error_errno(r, "Failed to generate unit name: %m");
|
return log_error_errno(r, "Failed to generate unit name: %m");
|
||||||
|
|
||||||
unit = strjoin(dest, "/", name);
|
unit = strjoina(dest, "/", name);
|
||||||
if (!unit)
|
|
||||||
return log_oom();
|
|
||||||
|
|
||||||
f = fopen(unit, "wxe");
|
f = fopen(unit, "wxe");
|
||||||
if (!f)
|
if (!f)
|
||||||
|
@ -447,6 +453,12 @@ static int add_mount(
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return log_error_errno(r, "Failed to write unit file %s: %m", unit);
|
return log_error_errno(r, "Failed to write unit file %s: %m", unit);
|
||||||
|
|
||||||
|
if (flags & MAKEFS) {
|
||||||
|
r = generator_hook_up_mkfs(dest, what, where, fstype);
|
||||||
|
if (r < 0)
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
if (!(flags & NOAUTO) && !(flags & AUTOMOUNT)) {
|
if (!(flags & NOAUTO) && !(flags & AUTOMOUNT)) {
|
||||||
r = generator_add_symlink(dest, post,
|
r = generator_add_symlink(dest, post,
|
||||||
(flags & NOFAIL) ? "wants" : "requires", name);
|
(flags & NOFAIL) ? "wants" : "requires", name);
|
||||||
|
@ -532,7 +544,7 @@ static int parse_fstab(bool initrd) {
|
||||||
|
|
||||||
while ((me = getmntent(f))) {
|
while ((me = getmntent(f))) {
|
||||||
_cleanup_free_ char *where = NULL, *what = NULL, *canonical_where = NULL;
|
_cleanup_free_ char *where = NULL, *what = NULL, *canonical_where = NULL;
|
||||||
bool noauto, nofail;
|
bool makefs, noauto, nofail;
|
||||||
int k;
|
int k;
|
||||||
|
|
||||||
if (initrd && !mount_in_initrd(me))
|
if (initrd && !mount_in_initrd(me))
|
||||||
|
@ -574,15 +586,17 @@ static int parse_fstab(bool initrd) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
makefs = fstab_test_option(me->mnt_opts, "x-systemd.makefs\0");
|
||||||
noauto = fstab_test_yes_no_option(me->mnt_opts, "noauto\0" "auto\0");
|
noauto = fstab_test_yes_no_option(me->mnt_opts, "noauto\0" "auto\0");
|
||||||
nofail = fstab_test_yes_no_option(me->mnt_opts, "nofail\0" "fail\0");
|
nofail = fstab_test_yes_no_option(me->mnt_opts, "nofail\0" "fail\0");
|
||||||
log_debug("Found entry what=%s where=%s type=%s nofail=%s noauto=%s",
|
log_debug("Found entry what=%s where=%s type=%s makefs=%s nofail=%s noauto=%s",
|
||||||
what, where, me->mnt_type,
|
what, where, me->mnt_type,
|
||||||
|
yes_no(makefs),
|
||||||
yes_no(noauto), yes_no(nofail));
|
yes_no(noauto), yes_no(nofail));
|
||||||
|
|
||||||
if (streq(me->mnt_type, "swap"))
|
if (streq(me->mnt_type, "swap"))
|
||||||
k = add_swap(what, me,
|
k = add_swap(what, me,
|
||||||
noauto*NOAUTO | nofail*NOFAIL);
|
makefs*MAKEFS | noauto*NOAUTO | nofail*NOFAIL);
|
||||||
else {
|
else {
|
||||||
bool automount;
|
bool automount;
|
||||||
const char *post;
|
const char *post;
|
||||||
|
@ -604,7 +618,7 @@ static int parse_fstab(bool initrd) {
|
||||||
me->mnt_type,
|
me->mnt_type,
|
||||||
me->mnt_opts,
|
me->mnt_opts,
|
||||||
me->mnt_passno,
|
me->mnt_passno,
|
||||||
noauto*NOAUTO | nofail*NOFAIL | automount*AUTOMOUNT,
|
makefs*MAKEFS | noauto*NOAUTO | nofail*NOFAIL | automount*AUTOMOUNT,
|
||||||
post,
|
post,
|
||||||
fstab_path);
|
fstab_path);
|
||||||
}
|
}
|
||||||
|
@ -665,7 +679,7 @@ static int add_sysroot_mount(void) {
|
||||||
arg_root_fstype,
|
arg_root_fstype,
|
||||||
opts,
|
opts,
|
||||||
is_device_path(what) ? 1 : 0, /* passno */
|
is_device_path(what) ? 1 : 0, /* passno */
|
||||||
0, /* noauto off, nofail off, automount off */
|
0, /* makefs off, noauto off, nofail off, automount off */
|
||||||
SPECIAL_INITRD_ROOT_FS_TARGET,
|
SPECIAL_INITRD_ROOT_FS_TARGET,
|
||||||
"/proc/cmdline");
|
"/proc/cmdline");
|
||||||
}
|
}
|
||||||
|
|
|
@ -83,8 +83,8 @@ static int write_fsck_sysroot_service(const char *dir, const char *what) {
|
||||||
fprintf(f,
|
fprintf(f,
|
||||||
"# Automatically generated by %1$s\n\n"
|
"# Automatically generated by %1$s\n\n"
|
||||||
"[Unit]\n"
|
"[Unit]\n"
|
||||||
"Documentation=man:systemd-fsck-root.service(8)\n"
|
|
||||||
"Description=File System Check on %2$s\n"
|
"Description=File System Check on %2$s\n"
|
||||||
|
"Documentation=man:systemd-fsck-root.service(8)\n"
|
||||||
"DefaultDependencies=no\n"
|
"DefaultDependencies=no\n"
|
||||||
"BindsTo=%3$s\n"
|
"BindsTo=%3$s\n"
|
||||||
"After=initrd-root-device.target local-fs-pre.target %3$s\n"
|
"After=initrd-root-device.target local-fs-pre.target %3$s\n"
|
||||||
|
@ -248,7 +248,8 @@ int generator_write_device_deps(
|
||||||
|
|
||||||
r = unit_name_from_path(node, ".device", &unit);
|
r = unit_name_from_path(node, ".device", &unit);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return log_error_errno(r, "Failed to make unit name from path: %m");
|
return log_error_errno(r, "Failed to make unit name from path \"%s\": %m",
|
||||||
|
node);
|
||||||
|
|
||||||
/* See mount_add_default_dependencies for explanation why we create such
|
/* See mount_add_default_dependencies for explanation why we create such
|
||||||
* dependencies. */
|
* dependencies. */
|
||||||
|
@ -266,7 +267,8 @@ int generator_write_initrd_root_device_deps(const char *dir, const char *what) {
|
||||||
|
|
||||||
r = unit_name_from_path(what, ".device", &unit);
|
r = unit_name_from_path(what, ".device", &unit);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return log_error_errno(r, "Failed to make unit name from path: %m");
|
return log_error_errno(r, "Failed to make unit name from path \"%s\": %m",
|
||||||
|
what);
|
||||||
|
|
||||||
return write_drop_in_format(dir, SPECIAL_INITRD_ROOT_DEVICE_TARGET, 50, "root-device",
|
return write_drop_in_format(dir, SPECIAL_INITRD_ROOT_DEVICE_TARGET, 50, "root-device",
|
||||||
"# Automatically generated by %s\n\n"
|
"# Automatically generated by %s\n\n"
|
||||||
|
@ -277,3 +279,151 @@ int generator_write_initrd_root_device_deps(const char *dir, const char *what) {
|
||||||
unit,
|
unit,
|
||||||
unit);
|
unit);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int generator_hook_up_mkswap(
|
||||||
|
const char *dir,
|
||||||
|
const char *what) {
|
||||||
|
|
||||||
|
_cleanup_free_ char *node = NULL, *unit = NULL, *escaped = NULL, *where_unit = NULL;
|
||||||
|
_cleanup_fclose_ FILE *f = NULL;
|
||||||
|
const char *unit_file;
|
||||||
|
int r;
|
||||||
|
|
||||||
|
node = fstab_node_to_udev_node(what);
|
||||||
|
if (!node)
|
||||||
|
return log_oom();
|
||||||
|
|
||||||
|
/* Nothing to work on. */
|
||||||
|
if (!is_device_path(node)) {
|
||||||
|
log_error("Cannot format something that is not a device node: %s", node);
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
r = unit_name_from_path_instance("systemd-mkswap", node, ".service", &unit);
|
||||||
|
if (r < 0)
|
||||||
|
return log_error_errno(r, "Failed to make unit instance name from path \"%s\": %m",
|
||||||
|
node);
|
||||||
|
|
||||||
|
unit_file = strjoina(dir, "/", unit);
|
||||||
|
log_debug("Creating %s", unit_file);
|
||||||
|
|
||||||
|
escaped = cescape(node);
|
||||||
|
if (!escaped)
|
||||||
|
return log_oom();
|
||||||
|
|
||||||
|
r = unit_name_from_path(what, ".swap", &where_unit);
|
||||||
|
if (r < 0)
|
||||||
|
return log_error_errno(r, "Failed to make unit name from path \"%s\": %m",
|
||||||
|
what);
|
||||||
|
|
||||||
|
f = fopen(unit_file, "wxe");
|
||||||
|
if (!f)
|
||||||
|
return log_error_errno(errno, "Failed to create unit file %s: %m",
|
||||||
|
unit_file);
|
||||||
|
|
||||||
|
fprintf(f,
|
||||||
|
"# Automatically generated by %s\n\n"
|
||||||
|
"[Unit]\n"
|
||||||
|
"Description=Make Swap on %%f\n"
|
||||||
|
"Documentation=man:systemd-mkswap@.service(8)\n"
|
||||||
|
"DefaultDependencies=no\n"
|
||||||
|
"BindsTo=%%i.device\n"
|
||||||
|
"After=%%i.device\n"
|
||||||
|
"Before=%s\n"
|
||||||
|
"Before=shutdown.target\n"
|
||||||
|
"\n"
|
||||||
|
"[Service]\n"
|
||||||
|
"Type=oneshot\n"
|
||||||
|
"RemainAfterExit=yes\n"
|
||||||
|
"ExecStart="SYSTEMD_MAKEFS_PATH " swap %s\n"
|
||||||
|
"TimeoutSec=0\n",
|
||||||
|
program_invocation_short_name,
|
||||||
|
where_unit,
|
||||||
|
escaped);
|
||||||
|
|
||||||
|
r = fflush_and_check(f);
|
||||||
|
if (r < 0)
|
||||||
|
return log_error_errno(r, "Failed to write unit file %s: %m", unit_file);
|
||||||
|
|
||||||
|
return generator_add_symlink(dir, where_unit, "requires", unit);
|
||||||
|
}
|
||||||
|
|
||||||
|
int generator_hook_up_mkfs(
|
||||||
|
const char *dir,
|
||||||
|
const char *what,
|
||||||
|
const char *where,
|
||||||
|
const char *type) {
|
||||||
|
|
||||||
|
_cleanup_free_ char *node = NULL, *unit = NULL, *escaped = NULL, *where_unit = NULL;
|
||||||
|
_cleanup_fclose_ FILE *f = NULL;
|
||||||
|
const char *unit_file;
|
||||||
|
int r;
|
||||||
|
|
||||||
|
node = fstab_node_to_udev_node(what);
|
||||||
|
if (!node)
|
||||||
|
return log_oom();
|
||||||
|
|
||||||
|
/* Nothing to work on. */
|
||||||
|
if (!is_device_path(node)) {
|
||||||
|
log_error("Cannot format something that is not a device node: %s", node);
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!type || streq(type, "auto")) {
|
||||||
|
log_error("Cannot format partition %s, filesystem type is not specified", node);
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
r = unit_name_from_path_instance("systemd-mkfs", node, ".service", &unit);
|
||||||
|
if (r < 0)
|
||||||
|
return log_error_errno(r, "Failed to make unit instance name from path \"%s\": %m",
|
||||||
|
node);
|
||||||
|
|
||||||
|
unit_file = strjoina(dir, "/", unit);
|
||||||
|
log_debug("Creating %s", unit_file);
|
||||||
|
|
||||||
|
escaped = cescape(node);
|
||||||
|
if (!escaped)
|
||||||
|
return log_oom();
|
||||||
|
|
||||||
|
r = unit_name_from_path(where, ".mount", &where_unit);
|
||||||
|
if (r < 0)
|
||||||
|
return log_error_errno(r, "Failed to make unit name from path \"%s\": %m",
|
||||||
|
where);
|
||||||
|
|
||||||
|
f = fopen(unit_file, "wxe");
|
||||||
|
if (!f)
|
||||||
|
return log_error_errno(errno, "Failed to create unit file %s: %m",
|
||||||
|
unit_file);
|
||||||
|
|
||||||
|
fprintf(f,
|
||||||
|
"# Automatically generated by %s\n\n"
|
||||||
|
"[Unit]\n"
|
||||||
|
"Description=Make File System on %%f\n"
|
||||||
|
"Documentation=man:systemd-mkfs@.service(8)\n"
|
||||||
|
"DefaultDependencies=no\n"
|
||||||
|
"BindsTo=%%i.device\n"
|
||||||
|
"After=%%i.device\n"
|
||||||
|
/* fsck might or might not be used, so let's be safe and order
|
||||||
|
* ourselves before both systemd-fsck@.service and the mount unit. */
|
||||||
|
"Before=systemd-fsck@%%i.service\n"
|
||||||
|
"Before=%s\n"
|
||||||
|
"Before=shutdown.target\n"
|
||||||
|
"\n"
|
||||||
|
"[Service]\n"
|
||||||
|
"Type=oneshot\n"
|
||||||
|
"RemainAfterExit=yes\n"
|
||||||
|
"ExecStart="SYSTEMD_MAKEFS_PATH " %s %s\n"
|
||||||
|
"TimeoutSec=0\n",
|
||||||
|
program_invocation_short_name,
|
||||||
|
where_unit,
|
||||||
|
type,
|
||||||
|
escaped);
|
||||||
|
// XXX: what about local-fs-pre.target?
|
||||||
|
|
||||||
|
r = fflush_and_check(f);
|
||||||
|
if (r < 0)
|
||||||
|
return log_error_errno(r, "Failed to write unit file %s: %m", unit_file);
|
||||||
|
|
||||||
|
return generator_add_symlink(dir, where_unit, "requires", unit);
|
||||||
|
}
|
||||||
|
|
|
@ -47,3 +47,12 @@ int generator_write_device_deps(
|
||||||
int generator_write_initrd_root_device_deps(
|
int generator_write_initrd_root_device_deps(
|
||||||
const char *dir,
|
const char *dir,
|
||||||
const char *what);
|
const char *what);
|
||||||
|
|
||||||
|
int generator_hook_up_mkswap(
|
||||||
|
const char *dir,
|
||||||
|
const char *what);
|
||||||
|
int generator_hook_up_mkfs(
|
||||||
|
const char *dir,
|
||||||
|
const char *what,
|
||||||
|
const char *where,
|
||||||
|
const char *type);
|
||||||
|
|
Loading…
Reference in a new issue