X-Git-Url: https://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?a=blobdiff_plain;f=src%2Fshared%2Fgenerator.c;h=414470be1c4a1ecf8029c60bb711ac93ea0a802e;hb=56dec05d29098b151421625c68525c2c3961e574;hp=49647c1ab6b55857ff687ae350fb1dd27ad14cbc;hpb=e48fdd84432bbf9c2ecc339183258c7c33116032;p=elogind.git
diff --git a/src/shared/generator.c b/src/shared/generator.c
index 49647c1ab..414470be1 100644
--- a/src/shared/generator.c
+++ b/src/shared/generator.c
@@ -19,6 +19,7 @@
along with systemd; If not, see .
***/
+#include
#include
#include "util.h"
@@ -26,32 +27,36 @@
#include "mkdir.h"
#include "unit-name.h"
#include "generator.h"
+#include "path-util.h"
+#include "dropin.h"
int generator_write_fsck_deps(
FILE *f,
const char *dest,
const char *what,
const char *where,
- const char *type) {
+ const char *fstype) {
assert(f);
+ assert(dest);
+ assert(what);
+ assert(where);
if (!is_device_path(what)) {
log_warning("Checking was requested for \"%s\", but it is not a device.", what);
return 0;
}
- if (type && !streq(type, "auto")) {
- const char *checker;
+ if (!isempty(fstype) && !streq(fstype, "auto")) {
int r;
-
- checker = strappenda("/sbin/fsck.", type);
- r = access(checker, X_OK);
- if (r < 0) {
- log_warning("Checking was requested for %s, but %s cannot be used: %m", what, checker);
-
+ r = fsck_exists(fstype);
+ if (r == -ENOENT) {
/* treat missing check as essentially OK */
- return errno == ENOENT ? 0 : -errno;
+ log_debug("Checking was requested for %s, but fsck.%s does not exist: %s", what, fstype, strerror(-r));
+ return 0;
+ } else if (r < 0) {
+ log_warning("Checking was requested for %s, but fsck.%s cannot be used: %s", what, fstype, strerror(-r));
+ return r;
}
}
@@ -82,3 +87,68 @@ int generator_write_fsck_deps(
return 0;
}
+
+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;
+ 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 = parse_sec(t, &u);
+ if (r < 0) {
+ log_warning("Failed to parse timeout for %s, ignoring: %s",
+ where, timeout);
+ return 0;
+ }
+
+ node = fstab_node_to_udev_node(what);
+ if (!node)
+ return log_oom();
+
+ unit = unit_name_from_path(node, ".device");
+ if (!unit)
+ return -ENOMEM;
+
+ 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);
+}