summaryrefslogtreecommitdiffstats
path: root/src/shared/generator.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/shared/generator.c')
-rw-r--r--src/shared/generator.c106
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();
}