diff options
Diffstat (limited to 'src/shared/generator.c')
-rw-r--r-- | src/shared/generator.c | 106 |
1 files changed, 96 insertions, 10 deletions
diff --git a/src/shared/generator.c b/src/shared/generator.c index 5626587..1b3304a 100644 --- a/src/shared/generator.c +++ b/src/shared/generator.c @@ -15,6 +15,7 @@ #include "log.h" #include "macro.h" #include "mkdir-label.h" +#include "mountpoint-util.h" #include "path-util.h" #include "process-util.h" #include "special.h" @@ -29,6 +30,7 @@ int generator_open_unit_file_full( const char *source, const char *fn, FILE **ret_file, + char **ret_final_path, char **ret_temp_path) { _cleanup_free_ char *p = NULL; @@ -72,10 +74,13 @@ int generator_open_unit_file_full( program_invocation_short_name); *ret_file = f; + + if (ret_final_path) + *ret_final_path = TAKE_PTR(p); + return 0; } - int generator_add_symlink_full( const char *dir, const char *dst, @@ -88,11 +93,13 @@ int generator_add_symlink_full( assert(dir); assert(dst); - assert(dep_type); assert(src); - /* Adds a symlink from <dst>.<dep_type>/ to <src> (if src is absolute) or ../<src> (otherwise). If - * <instance> is specified, then <src> must be a template unit name, and we'll instantiate it. */ + /* If 'dep_type' is specified adds a symlink from <dst>.<dep_type>/ to <src> (if src is absolute) or ../<src> (otherwise). + * + * If 'dep_type' is NULL, it will create a symlink to <src> (i.e. create an alias. + * + * If <instance> is specified, then <src> must be a template unit name, and we'll instantiate it. */ r = path_extract_directory(src, &dn); if (r < 0 && r != -EDESTADDRREQ) /* EDESTADDRREQ → just a file name was passed */ @@ -110,11 +117,19 @@ int generator_add_symlink_full( return log_error_errno(r, "Failed to instantiate '%s' for '%s': %m", fn, instance); } - from = path_join(dn ?: "..", fn); - if (!from) - return log_oom(); + if (dep_type) { /* Create a .wants/ style dep */ + from = path_join(dn ?: "..", fn); + if (!from) + return log_oom(); + + to = strjoin(dir, "/", dst, ".", dep_type, "/", instantiated ?: fn); + } else { /* or create an alias */ + from = dn ? path_join(dn, fn) : strdup(fn); + if (!from) + return log_oom(); - to = strjoin(dir, "/", dst, ".", dep_type, "/", instantiated ?: fn); + to = strjoin(dir, "/", dst); + } if (!to) return log_oom(); @@ -694,6 +709,77 @@ int generator_hook_up_pcrfs( return generator_add_symlink_full(dir, where_unit, "wants", pcrfs_unit_path, instance); } +int generator_hook_up_quotacheck( + const char *dir, + const char *what, + const char *where, + const char *target, + const char *fstype) { + + _cleanup_free_ char *where_unit = NULL, *instance = NULL; + int r; + + assert(dir); + assert(where); + + if (isempty(fstype) || streq(fstype, "auto")) + return log_warning_errno(SYNTHETIC_ERRNO(EOPNOTSUPP), "Couldn't determine filesystem type for %s, quota cannot be activated", what); + if (!fstype_needs_quota(fstype)) + return log_warning_errno(SYNTHETIC_ERRNO(EOPNOTSUPP), "Quota was requested for %s, but not supported, ignoring: %s", what, fstype); + + /* quotacheck unit for system root */ + if (path_equal(where, "/")) + return generator_add_symlink(dir, SPECIAL_LOCAL_FS_TARGET, "wants", SYSTEM_DATA_UNIT_DIR "/" SPECIAL_QUOTACHECK_ROOT_SERVICE); + + r = unit_name_path_escape(where, &instance); + if (r < 0) + return log_error_errno(r, "Failed to escape path '%s': %m", where); + + if (target) { + r = generator_add_ordering(dir, target, "After", SPECIAL_QUOTACHECK_SERVICE, instance); + if (r < 0) + return r; + } + + 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); + + return generator_add_symlink_full(dir, where_unit, "wants", SYSTEM_DATA_UNIT_DIR "/" SPECIAL_QUOTACHECK_SERVICE, instance); +} + +int generator_hook_up_quotaon( + const char *dir, + const char *where, + const char *target) { + + _cleanup_free_ char *where_unit = NULL, *instance = NULL; + int r; + + assert(dir); + assert(where); + + /* quotaon unit for system root is not instantiated */ + if (path_equal(where, "/")) + return generator_add_symlink(dir, SPECIAL_LOCAL_FS_TARGET, "wants", SYSTEM_DATA_UNIT_DIR "/" SPECIAL_QUOTAON_ROOT_SERVICE); + + r = unit_name_path_escape(where, &instance); + if (r < 0) + return log_error_errno(r, "Failed to escape path '%s': %m", where); + + if (target) { + r = generator_add_ordering(dir, target, "After", SPECIAL_QUOTAON_SERVICE, instance); + if (r < 0) + return r; + } + + 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); + + return generator_add_symlink_full(dir, where_unit, "wants", SYSTEM_DATA_UNIT_DIR "/" SPECIAL_QUOTAON_SERVICE, instance); +} + int generator_enable_remount_fs_service(const char *dir) { /* Pull in systemd-remount-fs.service */ return generator_add_symlink(dir, SPECIAL_LOCAL_FS_TARGET, "wants", @@ -790,6 +876,7 @@ int generator_write_cryptsetup_service_section( "TimeoutSec=infinity\n" /* The binary handles timeouts on its own */ "KeyringMode=shared\n" /* Make sure we can share cached keys among instances */ "OOMScoreAdjust=500\n" /* Unlocking can allocate a lot of memory if Argon2 is used */ + "ImportCredential=cryptsetup.*\n" "ExecStart=" SYSTEMD_CRYPTSETUP_PATH " attach '%s' '%s' '%s' '%s'\n" "ExecStop=" SYSTEMD_CRYPTSETUP_PATH " detach '%s'\n", name_escaped, what_escaped, strempty(key_file_escaped), strempty(options_escaped), @@ -883,6 +970,5 @@ void log_setup_generator(void) { log_set_target(LOG_TARGET_JOURNAL_OR_KMSG); } - log_parse_environment(); - (void) log_open(); + log_setup(); } |