X-Git-Url: http://git.ipfire.org/?a=blobdiff_plain;f=src%2Fshared%2Fgenerator.c;h=76808cbdd51c05e0ae95bc029594bb3a1978efca;hb=599601a4b9e11951ec6ea1dc33262a87f3c12bc9;hp=01229d8d71c5a2bf4098c8403653ced7a2290ef0;hpb=56f64d95763a799ba4475daf44d8e9f72a1bd474;p=thirdparty%2Fsystemd.git
diff --git a/src/shared/generator.c b/src/shared/generator.c
index 01229d8d71c..76808cbdd51 100644
--- a/src/shared/generator.c
+++ b/src/shared/generator.c
@@ -19,26 +19,85 @@
along with systemd; If not, see .
***/
-#include
+#include
#include
-#include "util.h"
-#include "special.h"
-#include "mkdir.h"
-#include "unit-name.h"
+#include "alloc-util.h"
+#include "dropin.h"
+#include "escape.h"
+#include "fd-util.h"
+#include "fileio.h"
+#include "fstab-util.h"
#include "generator.h"
+#include "log.h"
+#include "macro.h"
+#include "mkdir.h"
#include "path-util.h"
-#include "dropin.h"
+#include "special.h"
+#include "string-util.h"
+#include "time-util.h"
+#include "unit-name.h"
+#include "util.h"
+
+static int write_fsck_sysroot_service(const char *dir, const char *what) {
+ _cleanup_free_ char *device = NULL, *escaped = NULL;
+ _cleanup_fclose_ FILE *f = NULL;
+ const char *unit;
+ int r;
+
+ escaped = cescape(what);
+ if (!escaped)
+ return log_oom();
+
+ unit = strjoina(dir, "/systemd-fsck-root.service");
+ log_debug("Creating %s", unit);
+
+ r = unit_name_from_path(what, ".device", &device);
+ if (r < 0)
+ return log_error_errno(r, "Failed to convert device \"%s\" to unit name: %m", what);
+
+ f = fopen(unit, "wxe");
+ if (!f)
+ return log_error_errno(errno, "Failed to create unit file %s: %m", unit);
+
+ 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"
+ "DefaultDependencies=no\n"
+ "BindsTo=%3$s\n"
+ "After=%3$s local-fs-pre.target\n"
+ "Before=shutdown.target\n"
+ "\n"
+ "[Service]\n"
+ "Type=oneshot\n"
+ "RemainAfterExit=yes\n"
+ "ExecStart=" SYSTEMD_FSCK_PATH " %4$s\n"
+ "TimeoutSec=0\n",
+ program_invocation_short_name,
+ what,
+ device,
+ escaped);
+
+ r = fflush_and_check(f);
+ if (r < 0)
+ return log_error_errno(r, "Failed to write unit file %s: %m", unit);
+
+ return 0;
+}
int generator_write_fsck_deps(
FILE *f,
- const char *dest,
+ const char *dir,
const char *what,
const char *where,
const char *fstype) {
+ int r;
+
assert(f);
- assert(dest);
+ assert(dir);
assert(what);
assert(where);
@@ -48,91 +107,76 @@ int generator_write_fsck_deps(
}
if (!isempty(fstype) && !streq(fstype, "auto")) {
- int r;
r = fsck_exists(fstype);
- if (r == -ENOENT) {
+ if (r < 0)
+ log_warning_errno(r, "Checking was requested for %s, but couldn't detect if fsck.%s may be used, proceeding: %m", what, fstype);
+ else if (r == 0) {
/* treat missing check as essentially OK */
- log_debug_errno(r, "Checking was requested for %s, but fsck.%s does not exist: %m", what, fstype);
+ log_debug("Checking was requested for %s, but fsck.%s does not exist.", what, fstype);
return 0;
- } else if (r < 0)
- return log_warning_errno(r, "Checking was requested for %s, but fsck.%s cannot be used: %m", what, fstype);
+ }
}
- if (streq(where, "/")) {
- char *lnk;
+ if (path_equal(where, "/")) {
+ const char *lnk;
- lnk = strappenda(dest, "/" SPECIAL_LOCAL_FS_TARGET ".wants/systemd-fsck-root.service");
+ lnk = strjoina(dir, "/" SPECIAL_LOCAL_FS_TARGET ".wants/systemd-fsck-root.service");
mkdir_parents(lnk, 0755);
- if (symlink(SYSTEM_DATA_UNIT_PATH "/systemd-fsck-root.service", lnk) < 0) {
- log_error_errno(errno, "Failed to create symlink %s: %m", lnk);
- return -errno;
- }
+ if (symlink(SYSTEM_DATA_UNIT_PATH "/systemd-fsck-root.service", lnk) < 0)
+ return log_error_errno(errno, "Failed to create symlink %s: %m", lnk);
} else {
- _cleanup_free_ char *fsck = NULL;
+ _cleanup_free_ char *_fsck = NULL;
+ const char *fsck;
- fsck = unit_name_from_path_instance("systemd-fsck", what, ".service");
- if (!fsck)
- return log_oom();
+ if (in_initrd() && path_equal(where, "/sysroot")) {
+ r = write_fsck_sysroot_service(dir, what);
+ if (r < 0)
+ return r;
+
+ fsck = "systemd-fsck-root.service";
+ } else {
+ r = unit_name_from_path_instance("systemd-fsck", what, ".service", &_fsck);
+ if (r < 0)
+ return log_error_errno(r, "Failed to create fsck service name: %m");
+
+ fsck = _fsck;
+ }
fprintf(f,
- "RequiresOverridable=%s\n"
- "After=%s\n",
- fsck,
+ "Requires=%1$s\n"
+ "After=%1$s\n",
fsck);
}
return 0;
}
-int generator_write_timeouts(const char *dir, const char *what, const char *where,
- const char *opts, char **filtered) {
+int generator_write_timeouts(
+ const char *dir,
+ const char *what,
+ const char *where,
+ const char *opts,
+ char **filtered) {
/* Allow configuration how long we wait for a device that
* backs a mount point to show up. This is useful to support
* endless device timeouts for devices that show up only after
* user input, like crypto devices. */
- _cleanup_free_ char *node = NULL, *unit = NULL, *t = NULL;
- char *start, *timeout;
+ _cleanup_free_ char *node = NULL, *unit = NULL, *timeout = NULL;
usec_t u;
int r;
- size_t len;
-
- if ((start = mount_test_option(opts, "comment=systemd.device-timeout")))
- timeout = start + 31;
- else if ((start = mount_test_option(opts, "x-systemd.device-timeout")))
- timeout = start + 25;
- else {
- if (filtered) {
- *filtered = strdup(opts ?: "");
- if (!*filtered)
- return log_oom();
- }
-
- return 0;
- }
-
- len = strcspn(timeout, ",;" WHITESPACE);
- t = strndup(timeout, len);
- if (!t)
- return -ENOMEM;
- if (filtered) {
- char *prefix, *postfix;
-
- prefix = strndupa(opts, start - opts - (start != opts));
- postfix = timeout + len + (start == opts && timeout[len] != '\0');
- *filtered = strjoin(prefix, *postfix ? postfix : NULL, NULL);
- if (!*filtered)
- return log_oom();
- }
+ r = fstab_filter_options(opts, "comment=systemd.device-timeout\0" "x-systemd.device-timeout\0",
+ NULL, &timeout, filtered);
+ if (r <= 0)
+ return r;
- r = parse_sec(t, &u);
+ r = parse_sec(timeout, &u);
if (r < 0) {
- log_warning("Failed to parse timeout for %s, ignoring: %s",
- where, timeout);
+ log_warning("Failed to parse timeout for %s, ignoring: %s", where, timeout);
return 0;
}
@@ -140,13 +184,12 @@ int generator_write_timeouts(const char *dir, const char *what, const char *wher
if (!node)
return log_oom();
- unit = unit_name_from_path(node, ".device");
- if (!unit)
- return -ENOMEM;
+ 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 write_drop_in_format(dir, unit, 50, "device-timeout",
"# Automatically generated by %s\n\n"
- "[Unit]\nJobTimeoutSec=" USEC_FMT,
- program_invocation_short_name,
- u / USEC_PER_SEC);
+ "[Unit]\nJobTimeoutSec=%s",
+ program_invocation_short_name, timeout);
}