NOAUTO = 1 << 0,
NOFAIL = 1 << 1,
AUTOMOUNT = 1 << 2,
+ MAKEFS = 1 << 3,
} MountpointFlags;
static const char *arg_dest = "/tmp";
if (r < 0)
return r;
+ if (flags & MAKEFS) {
+ r = generator_hook_up_mkswap(arg_dest, what);
+ if (r < 0)
+ return r;
+ }
+
if (!(flags & NOAUTO)) {
r = generator_add_symlink(arg_dest, SPECIAL_SWAP_TARGET,
(flags & NOFAIL) ? "wants" : "requires", name);
const char *source) {
_cleanup_free_ char
- *name = NULL, *unit = NULL,
+ *name = NULL,
*automount_name = NULL, *automount_unit = NULL,
*filtered = NULL,
*where_escaped = NULL;
+ const char *unit;
_cleanup_fclose_ FILE *f = NULL;
int r;
if (r < 0)
return log_error_errno(r, "Failed to generate unit name: %m");
- unit = strjoin(dest, "/", name);
- if (!unit)
- return log_oom();
+ unit = strjoina(dest, "/", name);
f = fopen(unit, "wxe");
if (!f)
if (r < 0)
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)) {
r = generator_add_symlink(dest, post,
(flags & NOFAIL) ? "wants" : "requires", name);
while ((me = getmntent(f))) {
_cleanup_free_ char *where = NULL, *what = NULL, *canonical_where = NULL;
- bool noauto, nofail;
+ bool makefs, noauto, nofail;
int k;
if (initrd && !mount_in_initrd(me))
}
}
+ makefs = fstab_test_option(me->mnt_opts, "x-systemd.makefs\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");
- 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,
+ yes_no(makefs),
yes_no(noauto), yes_no(nofail));
if (streq(me->mnt_type, "swap"))
k = add_swap(what, me,
- noauto*NOAUTO | nofail*NOFAIL);
+ makefs*MAKEFS | noauto*NOAUTO | nofail*NOFAIL);
else {
bool automount;
const char *post;
me->mnt_type,
me->mnt_opts,
me->mnt_passno,
- noauto*NOAUTO | nofail*NOFAIL | automount*AUTOMOUNT,
+ makefs*MAKEFS | noauto*NOAUTO | nofail*NOFAIL | automount*AUTOMOUNT,
post,
fstab_path);
}
arg_root_fstype,
opts,
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,
"/proc/cmdline");
}
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"
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. */
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"
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);
+}