summaryrefslogtreecommitdiff
path: root/src/shared
diff options
context:
space:
mode:
Diffstat (limited to 'src/shared')
-rw-r--r--src/shared/dropin.c98
-rw-r--r--src/shared/dropin.h31
-rw-r--r--src/shared/generator.c57
-rw-r--r--src/shared/generator.h3
-rw-r--r--src/shared/path-lookup.h2
5 files changed, 191 insertions, 0 deletions
diff --git a/src/shared/dropin.c b/src/shared/dropin.c
new file mode 100644
index 0000000000..7774236f71
--- /dev/null
+++ b/src/shared/dropin.c
@@ -0,0 +1,98 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/***
+ This file is part of systemd.
+
+ Copyright 2014 Zbigniew Jędrzejewski-Szmek
+
+ systemd is free software; you can redistribute it and/or modify it
+ under the terms of the GNU Lesser General Public License as published by
+ the Free Software Foundation; either version 2.1 of the License, or
+ (at your option) any later version.
+
+ systemd is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include "dropin.h"
+#include "util.h"
+#include "mkdir.h"
+#include "fileio-label.h"
+
+int drop_in_file(const char *dir, const char *unit,
+ const char *name, char **_p, char **_q) {
+
+ _cleanup_free_ char *b = NULL;
+ char *p, *q;
+
+ assert(unit);
+ assert(name);
+ assert(_p);
+ assert(_q);
+
+ b = xescape(name, "/.");
+ if (!b)
+ return -ENOMEM;
+
+ if (!filename_is_safe(b))
+ return -EINVAL;
+
+ p = strjoin(dir, "/", unit, ".d", NULL);
+ if (!p)
+ return -ENOMEM;
+
+ q = strjoin(p, "/90-", b, ".conf", NULL);
+ if (!q) {
+ free(p);
+ return -ENOMEM;
+ }
+
+ *_p = p;
+ *_q = q;
+ return 0;
+}
+
+int write_drop_in(const char *dir, const char *unit,
+ const char *name, const char *data) {
+
+ _cleanup_free_ char *p = NULL, *q = NULL;
+ int r;
+
+ assert(dir);
+ assert(unit);
+ assert(name);
+ assert(data);
+
+ r = drop_in_file(dir, unit, name, &p, &q);
+ if (r < 0)
+ return r;
+
+ mkdir_p(p, 0755);
+ return write_string_file_atomic_label(q, data);
+}
+
+int write_drop_in_format(const char *dir, const char *unit,
+ const char *name, const char *format, ...) {
+ _cleanup_free_ char *p = NULL;
+ va_list ap;
+ int r;
+
+ assert(dir);
+ assert(unit);
+ assert(name);
+ assert(format);
+
+ va_start(ap, format);
+ r = vasprintf(&p, format, ap);
+ va_end(ap);
+
+ if (r < 0)
+ return -ENOMEM;
+
+ return write_drop_in(dir, unit, name, p);
+}
diff --git a/src/shared/dropin.h b/src/shared/dropin.h
new file mode 100644
index 0000000000..2958632963
--- /dev/null
+++ b/src/shared/dropin.h
@@ -0,0 +1,31 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+#pragma once
+
+/***
+ This file is part of systemd.
+
+ Copyright 2014 Zbigniew Jędrzejewski-Szmek
+
+ systemd is free software; you can redistribute it and/or modify it
+ under the terms of the GNU Lesser General Public License as published by
+ the Free Software Foundation; either version 2.1 of the License, or
+ (at your option) any later version.
+
+ systemd is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+int drop_in_file(const char *dir, const char *unit,
+ const char *name, char **_p, char **_q);
+
+int write_drop_in(const char *dir, const char *unit,
+ const char *name, const char *data);
+
+int write_drop_in_format(const char *dir, const char *unit,
+ const char *name, const char *format, ...);
diff --git a/src/shared/generator.c b/src/shared/generator.c
index dcfddaa731..762033bbdf 100644
--- a/src/shared/generator.c
+++ b/src/shared/generator.c
@@ -28,6 +28,7 @@
#include "unit-name.h"
#include "generator.h"
#include "path-util.h"
+#include "dropin.h"
int generator_write_fsck_deps(
FILE *f,
@@ -86,3 +87,59 @@ 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 *prefix, *start, *timeout, *postfix;
+ 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 {
+ *filtered = strdup(opts);
+ if (!*filtered)
+ return log_oom();
+
+ return 0;
+ }
+
+ len = strcspn(timeout, ",;" WHITESPACE);
+ t = strndup(timeout, len);
+ if (!t)
+ return -ENOMEM;
+
+ prefix = strndupa(opts, start - opts - (start != opts));
+ postfix = timeout + len + (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, "device-timeout",
+ "[Unit]\nJobTimeoutSec=%u", u / USEC_PER_SEC);
+}
diff --git a/src/shared/generator.h b/src/shared/generator.h
index 0140aa943f..64bd28f596 100644
--- a/src/shared/generator.h
+++ b/src/shared/generator.h
@@ -24,3 +24,6 @@
#include <stdio.h>
int generator_write_fsck_deps(FILE *f, const char *dest, const char *what, const char *where, const char *type);
+
+int generator_write_timeouts(const char *dir, const char *what, const char *where,
+ const char *opts, char **filtered);
diff --git a/src/shared/path-lookup.h b/src/shared/path-lookup.h
index 847a52f20a..4c77bee393 100644
--- a/src/shared/path-lookup.h
+++ b/src/shared/path-lookup.h
@@ -21,6 +21,8 @@
along with systemd; If not, see <http://www.gnu.org/licenses/>.
***/
+#include "macro.h"
+
typedef struct LookupPaths {
char **unit_path;
#ifdef HAVE_SYSV_COMPAT