Move x-systemd-device.timeout handling from core to fstab-generator
Instead of adjusting job timeouts in the core, let fstab-generator write out a dropin snippet with the appropriate JobTimeout. x-systemd-device.timeout option is removed from Options= line in the generated unit. The functions to write dropins are moved from core/unit.c to shared/dropin.c, to make them available outside of core. generator.c is moved to libsystemd-label, because it now uses functions defined in dropin.c, which are in libsystemd-label.
This commit is contained in:
parent
6e81b5b9dc
commit
2968644080
|
@ -816,8 +816,6 @@ libsystemd_shared_la_SOURCES = \
|
|||
src/shared/bus-label.c \
|
||||
src/shared/bus-label.h \
|
||||
src/shared/gpt.h \
|
||||
src/shared/generator.h \
|
||||
src/shared/generator.c \
|
||||
src/shared/clean-ipc.h \
|
||||
src/shared/clean-ipc.c \
|
||||
src/shared/login-shared.c \
|
||||
|
@ -874,7 +872,11 @@ libsystemd_label_la_SOURCES = \
|
|||
src/shared/fileio-label.c \
|
||||
src/shared/fileio-label.h \
|
||||
src/shared/dev-setup.c \
|
||||
src/shared/dev-setup.h
|
||||
src/shared/dev-setup.h \
|
||||
src/shared/dropin.c \
|
||||
src/shared/dropin.h \
|
||||
src/shared/generator.h \
|
||||
src/shared/generator.c
|
||||
|
||||
libsystemd_label_la_CFLAGS = \
|
||||
$(AM_CFLAGS) \
|
||||
|
|
|
@ -418,57 +418,6 @@ static int mount_add_default_dependencies(Mount *m) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int mount_fix_timeouts(Mount *m) {
|
||||
MountParameters *p;
|
||||
const char *timeout = NULL;
|
||||
Unit *other;
|
||||
Iterator i;
|
||||
usec_t u;
|
||||
char *t;
|
||||
int r;
|
||||
|
||||
assert(m);
|
||||
|
||||
p = get_mount_parameters_fragment(m);
|
||||
if (!p)
|
||||
return 0;
|
||||
|
||||
/* 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. */
|
||||
|
||||
if ((timeout = mount_test_option(p->options, "comment=systemd.device-timeout")))
|
||||
timeout += 31;
|
||||
else if ((timeout = mount_test_option(p->options, "x-systemd.device-timeout")))
|
||||
timeout += 25;
|
||||
else
|
||||
return 0;
|
||||
|
||||
t = strndup(timeout, strcspn(timeout, ",;" WHITESPACE));
|
||||
if (!t)
|
||||
return -ENOMEM;
|
||||
|
||||
r = parse_sec(t, &u);
|
||||
free(t);
|
||||
|
||||
if (r < 0) {
|
||||
log_warning_unit(UNIT(m)->id,
|
||||
"Failed to parse timeout for %s, ignoring: %s",
|
||||
m->where, timeout);
|
||||
return r;
|
||||
}
|
||||
|
||||
SET_FOREACH(other, UNIT(m)->dependencies[UNIT_AFTER], i) {
|
||||
if (other->type != UNIT_DEVICE)
|
||||
continue;
|
||||
|
||||
other->job_timeout = u;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int mount_verify(Mount *m) {
|
||||
_cleanup_free_ char *e = NULL;
|
||||
bool b;
|
||||
|
@ -556,10 +505,6 @@ static int mount_add_extras(Mount *m) {
|
|||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = mount_fix_timeouts(m);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
if (u->default_dependencies) {
|
||||
r = mount_add_default_dependencies(m);
|
||||
if (r < 0)
|
||||
|
|
|
@ -51,6 +51,7 @@
|
|||
#include "dbus.h"
|
||||
#include "execute.h"
|
||||
#include "virt.h"
|
||||
#include "dropin.h"
|
||||
|
||||
const UnitVTable * const unit_vtable[_UNIT_TYPE_MAX] = {
|
||||
[UNIT_SERVICE] = &service_vtable,
|
||||
|
@ -2966,68 +2967,55 @@ ExecRuntime *unit_get_exec_runtime(Unit *u) {
|
|||
return *(ExecRuntime**) ((uint8_t*) u + offset);
|
||||
}
|
||||
|
||||
static int drop_in_file(Unit *u, UnitSetPropertiesMode mode, const char *name, char **_p, char **_q) {
|
||||
_cleanup_free_ char *b = NULL;
|
||||
char *p, *q;
|
||||
int r;
|
||||
|
||||
assert(u);
|
||||
assert(name);
|
||||
assert(_p);
|
||||
assert(_q);
|
||||
|
||||
b = xescape(name, "/.");
|
||||
if (!b)
|
||||
return -ENOMEM;
|
||||
|
||||
if (!filename_is_safe(b))
|
||||
return -EINVAL;
|
||||
|
||||
static int unit_drop_in_dir(Unit *u, UnitSetPropertiesMode mode, bool transient, char **dir) {
|
||||
if (u->manager->running_as == SYSTEMD_USER) {
|
||||
_cleanup_free_ char *c = NULL;
|
||||
int r;
|
||||
|
||||
r = user_config_home(&c);
|
||||
if (r < 0)
|
||||
return r;
|
||||
r = user_config_home(dir);
|
||||
if (r == 0)
|
||||
return -ENOENT;
|
||||
|
||||
p = strjoin(c, "/", u->id, ".d", NULL);
|
||||
} else if (mode == UNIT_PERSISTENT && !u->transient)
|
||||
p = strjoin("/etc/systemd/system/", u->id, ".d", NULL);
|
||||
else
|
||||
p = strjoin("/run/systemd/system/", u->id, ".d", NULL);
|
||||
if (!p)
|
||||
return -ENOMEM;
|
||||
|
||||
q = strjoin(p, "/90-", b, ".conf", NULL);
|
||||
if (!q) {
|
||||
free(p);
|
||||
return -ENOMEM;
|
||||
return r;
|
||||
}
|
||||
|
||||
*_p = p;
|
||||
*_q = q;
|
||||
if (mode == UNIT_PERSISTENT && !transient)
|
||||
*dir = strdup("/etc/systemd/system");
|
||||
else
|
||||
*dir = strdup("/run/systemd/system");
|
||||
if (!*dir)
|
||||
return -ENOMEM;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int unit_write_drop_in(Unit *u, UnitSetPropertiesMode mode, const char *name, const char *data) {
|
||||
_cleanup_free_ char *p = NULL, *q = NULL;
|
||||
static int unit_drop_in_file(Unit *u,
|
||||
UnitSetPropertiesMode mode, const char *name, char **p, char **q) {
|
||||
_cleanup_free_ char *dir = NULL;
|
||||
int r;
|
||||
|
||||
assert(u);
|
||||
|
||||
r = unit_drop_in_dir(u, mode, u->transient, &dir);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
return drop_in_file(dir, u->id, name, p, q);
|
||||
}
|
||||
|
||||
int unit_write_drop_in(Unit *u, UnitSetPropertiesMode mode, const char *name, const char *data) {
|
||||
|
||||
_cleanup_free_ char *dir = NULL;
|
||||
int r;
|
||||
|
||||
assert(u);
|
||||
assert(name);
|
||||
assert(data);
|
||||
|
||||
if (!IN_SET(mode, UNIT_PERSISTENT, UNIT_RUNTIME))
|
||||
return 0;
|
||||
|
||||
r = drop_in_file(u, mode, name, &p, &q);
|
||||
r = unit_drop_in_dir(u, mode, u->transient, &dir);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
mkdir_p(p, 0755);
|
||||
return write_string_file_atomic_label(q, data);
|
||||
return write_drop_in(dir, u->id, name, data);
|
||||
}
|
||||
|
||||
int unit_write_drop_in_format(Unit *u, UnitSetPropertiesMode mode, const char *name, const char *format, ...) {
|
||||
|
@ -3103,7 +3091,7 @@ int unit_remove_drop_in(Unit *u, UnitSetPropertiesMode mode, const char *name) {
|
|||
if (!IN_SET(mode, UNIT_PERSISTENT, UNIT_RUNTIME))
|
||||
return 0;
|
||||
|
||||
r = drop_in_file(u, mode, name, &p, &q);
|
||||
r = unit_drop_in_file(u, mode, name, &p, &q);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
|
|
|
@ -44,6 +44,7 @@ static char *arg_root_fstype = NULL;
|
|||
static char *arg_root_options = NULL;
|
||||
static int arg_root_rw = -1;
|
||||
|
||||
|
||||
static int mount_find_pri(struct mntent *me, int *ret) {
|
||||
char *end, *pri;
|
||||
unsigned long r;
|
||||
|
@ -173,7 +174,8 @@ static int add_mount(
|
|||
|
||||
_cleanup_free_ char
|
||||
*name = NULL, *unit = NULL, *lnk = NULL,
|
||||
*automount_name = NULL, *automount_unit = NULL;
|
||||
*automount_name = NULL, *automount_unit = NULL,
|
||||
*filtered = NULL;
|
||||
_cleanup_fclose_ FILE *f = NULL;
|
||||
int r;
|
||||
|
||||
|
@ -245,8 +247,12 @@ static int add_mount(
|
|||
if (!isempty(fstype) && !streq(fstype, "auto"))
|
||||
fprintf(f, "Type=%s\n", fstype);
|
||||
|
||||
if (!isempty(opts) && !streq(opts, "defaults"))
|
||||
fprintf(f, "Options=%s\n", opts);
|
||||
r = generator_write_timeouts(arg_dest, what, where, opts, &filtered);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
if (!isempty(filtered) && !streq(filtered, "defaults"))
|
||||
fprintf(f, "Options=%s\n", filtered);
|
||||
|
||||
fflush(f);
|
||||
if (ferror(f)) {
|
||||
|
|
|
@ -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);
|
||||
}
|
|
@ -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, ...);
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue