From 7f2806d50937a7fbe6d673ce8fc62634129c3a12 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Wed, 29 Nov 2017 20:02:11 +0100 Subject: [PATCH] Add x-systemd.growfs option for fstab --- meson.build | 1 + src/fstab-generator/fstab-generator.c | 22 ++++++++--- src/shared/generator.c | 55 +++++++++++++++++++++++++++ src/shared/generator.h | 4 ++ 4 files changed, 77 insertions(+), 5 deletions(-) diff --git a/meson.build b/meson.build index b9015c8f1a..6eff25f45c 100644 --- a/meson.build +++ b/meson.build @@ -183,6 +183,7 @@ conf.set_quoted('SYSTEMD_CGROUP_AGENT_PATH', join_paths(rootlib 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_MAKEFS_PATH', join_paths(rootlibexecdir, 'systemd-makefs')) +conf.set_quoted('SYSTEMD_GROWFS_PATH', join_paths(rootlibexecdir, 'systemd-growfs')) 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('SYSTEMCTL_BINARY_PATH', join_paths(rootbindir, 'systemctl')) diff --git a/src/fstab-generator/fstab-generator.c b/src/fstab-generator/fstab-generator.c index 5bdeae04c3..68e7c23cbe 100644 --- a/src/fstab-generator/fstab-generator.c +++ b/src/fstab-generator/fstab-generator.c @@ -52,6 +52,7 @@ typedef enum MountpointFlags { NOFAIL = 1 << 1, AUTOMOUNT = 1 << 2, MAKEFS = 1 << 3, + GROWFS = 1 << 4, } MountpointFlags; static const char *arg_dest = "/tmp"; @@ -162,6 +163,10 @@ static int add_swap( 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); @@ -459,6 +464,12 @@ static int add_mount( return r; } + if (flags & GROWFS) { + r = generator_hook_up_growfs(dest, where, post); + if (r < 0) + return r; + } + if (!(flags & NOAUTO) && !(flags & AUTOMOUNT)) { r = generator_add_symlink(dest, post, (flags & NOFAIL) ? "wants" : "requires", name); @@ -544,7 +555,7 @@ static int parse_fstab(bool initrd) { while ((me = getmntent(f))) { _cleanup_free_ char *where = NULL, *what = NULL, *canonical_where = NULL; - bool makefs, noauto, nofail; + bool makefs, growfs, noauto, nofail; int k; if (initrd && !mount_in_initrd(me)) @@ -587,6 +598,7 @@ static int parse_fstab(bool initrd) { } makefs = fstab_test_option(me->mnt_opts, "x-systemd.makefs\0"); + growfs = fstab_test_option(me->mnt_opts, "x-systemd.growfs\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 makefs=%s nofail=%s noauto=%s", @@ -596,7 +608,7 @@ static int parse_fstab(bool initrd) { if (streq(me->mnt_type, "swap")) k = add_swap(what, me, - makefs*MAKEFS | noauto*NOAUTO | nofail*NOFAIL); + makefs*MAKEFS | growfs*GROWFS | noauto*NOAUTO | nofail*NOFAIL); else { bool automount; const char *post; @@ -618,12 +630,12 @@ static int parse_fstab(bool initrd) { me->mnt_type, me->mnt_opts, me->mnt_passno, - makefs*MAKEFS | noauto*NOAUTO | nofail*NOFAIL | automount*AUTOMOUNT, + makefs*MAKEFS | growfs*GROWFS | noauto*NOAUTO | nofail*NOFAIL | automount*AUTOMOUNT, post, fstab_path); } - if (k < 0) + if (r >= 0 && k < 0) r = k; } @@ -679,7 +691,7 @@ static int add_sysroot_mount(void) { arg_root_fstype, opts, is_device_path(what) ? 1 : 0, /* passno */ - 0, /* makefs off, noauto off, nofail off, automount off */ + 0, /* makefs off, growfs off, noauto off, nofail off, automount off */ SPECIAL_INITRD_ROOT_FS_TARGET, "/proc/cmdline"); } diff --git a/src/shared/generator.c b/src/shared/generator.c index 7c764328d6..3495a7ef7d 100644 --- a/src/shared/generator.c +++ b/src/shared/generator.c @@ -427,3 +427,58 @@ int generator_hook_up_mkfs( return generator_add_symlink(dir, where_unit, "requires", unit); } + +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:systemd-growfs@.service(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); +} diff --git a/src/shared/generator.h b/src/shared/generator.h index f4109b95a3..32d1ad021c 100644 --- a/src/shared/generator.h +++ b/src/shared/generator.h @@ -56,3 +56,7 @@ int generator_hook_up_mkfs( const char *what, const char *where, const char *type); +int generator_hook_up_growfs( + const char *dir, + const char *where, + const char *target);