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:
+153
-3
@@ -83,8 +83,8 @@ static int write_fsck_sysroot_service(const char *dir, const char *what) {
|
||||
fprintf(f,
|
||||
"# Automatically generated by %1$s\n\n"
|
||||
"[Unit]\n"
|
||||
"Documentation=man:systemd-fsck-root.service(8)\n"
|
||||
"Description=File System Check on %2$s\n"
|
||||
"Documentation=man:systemd-fsck-root.service(8)\n"
|
||||
"DefaultDependencies=no\n"
|
||||
"BindsTo=%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);
|
||||
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
|
||||
* 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);
|
||||
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",
|
||||
"# 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);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
+13
-4
@@ -39,11 +39,20 @@ int generator_write_timeouts(
|
||||
char **filtered);
|
||||
|
||||
int generator_write_device_deps(
|
||||
const char *dir,
|
||||
const char *what,
|
||||
const char *where,
|
||||
const char *opts);
|
||||
const char *dir,
|
||||
const char *what,
|
||||
const char *where,
|
||||
const char *opts);
|
||||
|
||||
int generator_write_initrd_root_device_deps(
|
||||
const char *dir,
|
||||
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);
|
||||
|
||||
Reference in New Issue
Block a user