int generator_hook_up_growfs( const char *dir, const char *where, const char *target) { _cleanup_free_ char *unit = NULL, *escaped = NULL, *where_unit = NULL; _cleanup_fclose_ FILE *f = NULL; const char *unit_file; int r; escaped = cescape(where); if (!escaped) return log_oom(); r = unit_name_from_path_instance("systemd-growfs", where, ".service", &unit); if (r < 0) return log_error_errno(r, "Failed to make unit instance name from path \"%s\": %m", where); 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); unit_file = strjoina(dir, "/", unit); log_debug("Creating %s", unit_file); 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=Grow File System on %%f\n" "Documentation=man:[email protected](8)\n" "DefaultDependencies=no\n" "BindsTo=%%i.mount\n" "After=%%i.mount\n" "Before=shutdown.target\n" "Before=%s\n" "\n" "[Service]\n" "Type=oneshot\n" "RemainAfterExit=yes\n" "ExecStart="SYSTEMD_GROWFS_PATH " %s\n" "TimeoutSec=0\n", program_invocation_short_name, target, escaped); return generator_add_symlink(dir, where_unit, "wants", unit); }
static int add_swap( const char *what, struct mntent *me, bool noauto, bool nofail) { _cleanup_free_ char *name = NULL, *unit = NULL; _cleanup_fclose_ FILE *f = NULL; int r; assert(what); assert(me); if (access("/proc/swaps", F_OK) < 0) { log_info("Swap not supported, ignoring fstab swap entry for %s.", what); return 0; } if (detect_container() > 0) { log_info("Running in a container, ignoring fstab swap entry for %s.", what); return 0; } r = unit_name_from_path(what, ".swap", &name); if (r < 0) return log_error_errno(r, "Failed to generate unit name: %m"); unit = strjoin(arg_dest, "/", name); if (!unit) return log_oom(); f = fopen(unit, "wxe"); if (!f) return log_error_errno(errno, errno == EEXIST ? "Failed to create swap unit file %s, as it already exists. Duplicate entry in /etc/fstab?" : "Failed to create unit file %s: %m", unit); fputs_unlocked("# Automatically generated by systemd-fstab-generator\n\n" "[Unit]\n" "SourcePath=/etc/fstab\n" "Documentation=man:fstab(5) man:systemd-fstab-generator(8)\n\n" "[Swap]\n", f); r = write_what(f, what); if (r < 0) return r; r = write_options(f, me->mnt_opts); if (r < 0) return r; r = fflush_and_check(f); if (r < 0) return log_error_errno(r, "Failed to write unit file %s: %m", unit); /* use what as where, to have a nicer error message */ r = generator_write_timeouts(arg_dest, what, what, me->mnt_opts, NULL); if (r < 0) return r; if (!noauto) { r = generator_add_symlink(arg_dest, SPECIAL_SWAP_TARGET, nofail ? "wants" : "requires", name); if (r < 0) return r; } return 0; }
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:[email protected](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 [email protected] 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); }
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:[email protected](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); }
static int add_swap( const char *what, struct mntent *me, MountpointFlags flags) { _cleanup_free_ char *name = NULL; _cleanup_fclose_ FILE *f = NULL; int r; assert(what); assert(me); if (access("/proc/swaps", F_OK) < 0) { log_info("Swap not supported, ignoring fstab swap entry for %s.", what); return 0; } if (detect_container() > 0) { log_info("Running in a container, ignoring fstab swap entry for %s.", what); return 0; } r = unit_name_from_path(what, ".swap", &name); if (r < 0) return log_error_errno(r, "Failed to generate unit name: %m"); r = generator_open_unit_file(arg_dest, "/etc/fstab", name, &f); if (r < 0) return r; fputs("# Automatically generated by systemd-fstab-generator\n\n" "[Unit]\n" "SourcePath=/etc/fstab\n" "Documentation=man:fstab(5) man:systemd-fstab-generator(8)\n\n" "[Swap]\n", f); r = write_what(f, what); if (r < 0) return r; r = write_options(f, me->mnt_opts); if (r < 0) return r; r = fflush_and_check(f); if (r < 0) return log_error_errno(r, "Failed to write unit file %s: %m", name); /* use what as where, to have a nicer error message */ r = generator_write_timeouts(arg_dest, what, what, me->mnt_opts, NULL); if (r < 0) return r; if (flags & MAKEFS) { r = generator_hook_up_mkswap(arg_dest, what); if (r < 0) return r; } if (flags & GROWFS) /* TODO: swap devices must be wiped and recreated */ log_warning("%s: growing swap devices is currently unsupported.", what); if (!(flags & NOAUTO)) { r = generator_add_symlink(arg_dest, SPECIAL_SWAP_TARGET, (flags & NOFAIL) ? "wants" : "requires", name); if (r < 0) return r; } return 0; }
static int create_disk( const char *name, const char *device, const char *password, const char *options) { _cleanup_free_ char *p = NULL, *n = NULL, *d = NULL, *u = NULL, *e = NULL, *filtered = NULL, *u_escaped = NULL, *password_escaped = NULL, *filtered_escaped = NULL, *name_escaped = NULL; _cleanup_fclose_ FILE *f = NULL; const char *dmname; bool noauto, nofail, tmp, swap, netdev; int r; assert(name); assert(device); noauto = fstab_test_yes_no_option(options, "noauto\0" "auto\0"); nofail = fstab_test_yes_no_option(options, "nofail\0" "fail\0"); tmp = fstab_test_option(options, "tmp\0"); swap = fstab_test_option(options, "swap\0"); netdev = fstab_test_option(options, "_netdev\0"); if (tmp && swap) { log_error("Device '%s' cannot be both 'tmp' and 'swap'. Ignoring.", name); return -EINVAL; } name_escaped = specifier_escape(name); if (!name_escaped) return log_oom(); e = unit_name_escape(name); if (!e) return log_oom(); r = unit_name_build("systemd-cryptsetup", e, ".service", &n); if (r < 0) return log_error_errno(r, "Failed to generate unit name: %m"); p = strjoin(arg_dest, "/", n); if (!p) return log_oom(); u = fstab_node_to_udev_node(device); if (!u) return log_oom(); u_escaped = specifier_escape(u); if (!u_escaped) return log_oom(); r = unit_name_from_path(u, ".device", &d); if (r < 0) return log_error_errno(r, "Failed to generate unit name: %m"); password_escaped = specifier_escape(password); if (!password_escaped) return log_oom(); f = fopen(p, "wxe"); if (!f) return log_error_errno(errno, "Failed to create unit file %s: %m", p); fprintf(f, "# Automatically generated by systemd-cryptsetup-generator\n\n" "[Unit]\n" "Description=Cryptography Setup for %%I\n" "Documentation=man:crypttab(5) man:systemd-cryptsetup-generator(8) man:[email protected](8)\n" "SourcePath=/etc/crypttab\n" "DefaultDependencies=no\n" "Conflicts=umount.target\n" "IgnoreOnIsolate=true\n" "After=%s\n", netdev ? "remote-fs-pre.target" : "cryptsetup-pre.target"); if (!nofail) fprintf(f, "Before=%s\n", netdev ? "remote-cryptsetup.target" : "cryptsetup.target"); if (password) { if (STR_IN_SET(password, "/dev/urandom", "/dev/random", "/dev/hw_random")) fputs_unlocked("After=systemd-random-seed.service\n", f); else if (!STR_IN_SET(password, "-", "none")) { _cleanup_free_ char *uu; uu = fstab_node_to_udev_node(password); if (!uu) return log_oom(); if (!path_equal(uu, "/dev/null")) { if (path_startswith(uu, "/dev/")) { _cleanup_free_ char *dd = NULL; r = unit_name_from_path(uu, ".device", &dd); if (r < 0) return log_error_errno(r, "Failed to generate unit name: %m"); fprintf(f, "After=%1$s\nRequires=%1$s\n", dd); } else fprintf(f, "RequiresMountsFor=%s\n", password_escaped); } } } if (path_startswith(u, "/dev/")) { fprintf(f, "BindsTo=%s\n" "After=%s\n" "Before=umount.target\n", d, d); if (swap) fputs_unlocked("Before=dev-mapper-%i.swap\n", f); } else fprintf(f, "RequiresMountsFor=%s\n", u_escaped); r = generator_write_timeouts(arg_dest, device, name, options, &filtered); if (r < 0) return r; filtered_escaped = specifier_escape(filtered); if (!filtered_escaped) return log_oom(); fprintf(f, "\n[Service]\n" "Type=oneshot\n" "RemainAfterExit=yes\n" "TimeoutSec=0\n" /* the binary handles timeouts anyway */ "KeyringMode=shared\n" /* make sure we can share cached keys among instances */ "ExecStart=" SYSTEMD_CRYPTSETUP_PATH " attach '%s' '%s' '%s' '%s'\n" "ExecStop=" SYSTEMD_CRYPTSETUP_PATH " detach '%s'\n", name_escaped, u_escaped, strempty(password_escaped), strempty(filtered_escaped), name_escaped); if (tmp) fprintf(f, "ExecStartPost=/sbin/mke2fs '/dev/mapper/%s'\n", name_escaped); if (swap) fprintf(f, "ExecStartPost=/sbin/mkswap '/dev/mapper/%s'\n", name_escaped); r = fflush_and_check(f); if (r < 0) return log_error_errno(r, "Failed to write file %s: %m", p); if (!noauto) { r = generator_add_symlink(arg_dest, d, "wants", n); if (r < 0) return r; r = generator_add_symlink(arg_dest, netdev ? "remote-cryptsetup.target" : "cryptsetup.target", nofail ? "wants" : "requires", n); if (r < 0) return r; } dmname = strjoina("dev-mapper-", e, ".device"); r = generator_add_symlink(arg_dest, dmname, "requires", n); if (r < 0) return r; if (!noauto && !nofail) { r = write_drop_in(arg_dest, dmname, 90, "device-timeout", "# Automatically generated by systemd-cryptsetup-generator \n\n" "[Unit]\nJobTimeoutSec=0"); if (r < 0) return log_error_errno(r, "Failed to write device drop-in: %m"); } return 0; }