load-fragment.c revision d91c34f21ff7445dcee3efe2368aebe2d6c266db
4e67ddd6b39c2847cc399ab0874427baa7ea8935Lennart Poettering/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
4e67ddd6b39c2847cc399ab0874427baa7ea8935Lennart Poettering This file is part of systemd.
4e67ddd6b39c2847cc399ab0874427baa7ea8935Lennart Poettering Copyright 2010 Lennart Poettering
4e67ddd6b39c2847cc399ab0874427baa7ea8935Lennart Poettering Copyright 2012 Holger Hans Peter Freyther
4e67ddd6b39c2847cc399ab0874427baa7ea8935Lennart Poettering systemd is free software; you can redistribute it and/or modify it
4e67ddd6b39c2847cc399ab0874427baa7ea8935Lennart Poettering under the terms of the GNU Lesser General Public License as published by
4e67ddd6b39c2847cc399ab0874427baa7ea8935Lennart Poettering the Free Software Foundation; either version 2.1 of the License, or
b5e9dba8d60b8fb80b6302b6ea2cd665b3ab370cLennart Poettering (at your option) any later version.
along with systemd; If not, see <http://www.gnu.org/licenses/>.
#include <assert.h>
#include <errno.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <sched.h>
#include "unit.h"
#include "strv.h"
#include "conf-parser.h"
#include "load-fragment.h"
#include "log.h"
#include "ioprio.h"
#include "securebits.h"
#include "missing.h"
#include "unit-name.h"
#include "unit-printf.h"
#include "bus-errors.h"
#include "utf8.h"
#include "path-util.h"
#include "syscall-list.h"
#include "env-util.h"
#ifndef HAVE_SYSV_COMPAT
const char *filename,
unsigned line,
const char *section,
const char *lvalue,
int ltype,
const char *rvalue,
void *data,
void *userdata) {
log_debug("[%s:%u] Support for option %s= has been disabled at compile time and is ignored", filename, line, lvalue);
const char *filename,
unsigned line,
const char *section,
const char *lvalue,
int ltype,
const char *rvalue,
void *data,
void *userdata) {
size_t l;
char *state;
t = strndup(w, l);
return log_oom();
k = unit_name_printf(u, t);
return log_oom();
const char *filename,
unsigned line,
const char *section,
const char *lvalue,
int ltype,
const char *rvalue,
void *data,
void *userdata) {
assert(u);
const char *filename,
unsigned line,
const char *section,
const char *lvalue,
int ltype,
const char *rvalue,
void *data,
void *userdata) {
assert(u);
const char *filename,
unsigned line,
const char *section,
const char *lvalue,
int ltype,
const char *rvalue,
void *data,
void *userdata) {
assert(u);
const char *filename,
unsigned line,
const char *section,
const char *lvalue,
int ltype,
const char *rvalue,
void *data,
void *userdata) {
Socket *s;
return log_oom();
if (!p->path) {
if (!p->path) {
free(p);
return log_oom();
free(p);
free(p);
free(p);
if (s->ports) {
const char *filename,
unsigned line,
const char *section,
const char *lvalue,
int ltype,
const char *rvalue,
void *data,
void *userdata) {
Socket *s;
s->bind_ipv6_only = b;
const char *filename,
unsigned line,
const char *section,
const char *lvalue,
int ltype,
const char *rvalue,
void *data,
void *userdata) {
int priority;
c->nice_set = true;
const char *filename,
unsigned line,
const char *section,
const char *lvalue,
int ltype,
const char *rvalue,
void *data,
void *userdata) {
int oa;
log_error("[%s:%u] Failed to parse the OOM score adjust value, ignoring: %s", filename, line, rvalue);
c->oom_score_adjust_set = true;
int config_parse_exec(
const char *filename,
unsigned line,
const char *section,
const char *lvalue,
int ltype,
const char *rvalue,
void *data,
void *userdata) {
char *path, **n;
assert(e);
e += ltype;
*e = NULL;
size_t l;
char *state;
n = NULL;
if (rvalue[0] == 0)
ignore = true;
rvalue ++;
honour_argv0 = true;
rvalue ++;
return log_oom();
if (!path) {
r = log_oom();
goto fail;
goto fail;
c = n[k++] = cunescape_length(w, l);
r = log_oom();
goto fail;
if (!utf8_is_valid(c)) {
goto fail;
n[k] = NULL;
goto fail;
if (!path) {
if (!path) {
r = log_oom();
goto fail;
if (!nce) {
r = log_oom();
goto fail;
fail:
n[k] = NULL;
strv_free(n);
DEFINE_CONFIG_PARSE_ENUM(config_parse_service_type, service_type, ServiceType, "Failed to parse service type");
DEFINE_CONFIG_PARSE_ENUM(config_parse_service_restart, service_restart, ServiceRestart, "Failed to parse service restart specifier");
const char *filename,
unsigned line,
const char *section,
const char *lvalue,
int ltype,
const char *rvalue,
void *data,
void *userdata) {
return log_oom();
n = NULL;
s->bind_to_device = n;
DEFINE_CONFIG_PARSE_ENUM(config_parse_output, exec_output, ExecOutput, "Failed to parse output specifier");
DEFINE_CONFIG_PARSE_ENUM(config_parse_input, exec_input, ExecInput, "Failed to parse input specifier");
const char *filename,
unsigned line,
const char *section,
const char *lvalue,
int ltype,
const char *rvalue,
void *data,
void *userdata) {
c->ioprio_set = true;
const char *filename,
unsigned line,
const char *section,
const char *lvalue,
int ltype,
const char *rvalue,
void *data,
void *userdata) {
c->ioprio_set = true;
const char *filename,
unsigned line,
const char *section,
const char *lvalue,
int ltype,
const char *rvalue,
void *data,
void *userdata) {
c->cpu_sched_policy = x;
c->cpu_sched_priority = CLAMP(c->cpu_sched_priority, sched_get_priority_min(x), sched_get_priority_max(x));
c->cpu_sched_set = true;
const char *filename,
unsigned line,
const char *section,
const char *lvalue,
int ltype,
const char *rvalue,
void *data,
void *userdata) {
c->cpu_sched_priority = i;
c->cpu_sched_set = true;
const char *filename,
unsigned line,
const char *section,
const char *lvalue,
int ltype,
const char *rvalue,
void *data,
void *userdata) {
size_t l;
char *state;
if (c->cpuset)
unsigned cpu;
t = strndup(w, l);
return log_oom();
if (!c->cpuset) {
if (!c->cpuset)
return log_oom();
const char *filename,
unsigned line,
const char *section,
const char *lvalue,
int ltype,
const char *rvalue,
void *data,
void *userdata) {
if (!cap) {
return log_oom();
if (c->capabilities)
const char *filename,
unsigned line,
const char *section,
const char *lvalue,
int ltype,
const char *rvalue,
void *data,
void *userdata) {
size_t l;
char *state;
c->secure_bits = 0;
const char *filename,
unsigned line,
const char *section,
const char *lvalue,
int ltype,
const char *rvalue,
void *data,
void *userdata) {
size_t l;
char *state;
bool invert = false;
invert = true;
rvalue++;
t = strndup(w, l);
return log_oom();
if (invert)
int config_parse_limit(
const char *filename,
unsigned line,
const char *section,
const char *lvalue,
int ltype,
const char *rvalue,
void *data,
void *userdata) {
u = (unsigned long long) RLIM_INFINITY;
if (!*rl) {
if (!*rl)
return log_oom();
const char *filename,
unsigned line,
const char *section,
const char *lvalue,
int ltype,
const char *rvalue,
void *data,
void *userdata) {
size_t l;
char *state;
t = strndup(w, l);
return log_oom();
k = unit_full_printf(u, t);
if (!ku)
return log_oom();
#ifdef HAVE_SYSV_COMPAT
const char *filename,
unsigned line,
const char *section,
const char *lvalue,
int ltype,
const char *rvalue,
void *data,
void *userdata) {
*priority = (int) i;
const char *filename,
unsigned line,
const char *section,
const char *lvalue,
int ltype,
const char *rvalue,
void *data,
void *userdata) {
*passno = (int) i;
const char *filename,
unsigned line,
const char *section,
const char *lvalue,
int ltype,
const char *rvalue,
void *data,
void *userdata) {
*sig = r;
const char *filename,
unsigned line,
const char *section,
const char *lvalue,
int ltype,
const char *rvalue,
void *data,
void *userdata) {
size_t l;
char *state;
unsigned long flags = 0;
char _cleanup_free_ *t;
t = strndup(w, l);
return log_oom();
int config_parse_timer(
const char *filename,
unsigned line,
const char *section,
const char *lvalue,
int ltype,
const char *rvalue,
void *data,
void *userdata) {
usec_t u = 0;
TimerValue *v;
TimerBase b;
if (b == TIMER_CALENDAR) {
return log_oom();
v->base = b;
v->value = u;
v->calendar_spec = c;
const char *filename,
unsigned line,
const char *section,
const char *lvalue,
int ltype,
const char *rvalue,
void *data,
void *userdata) {
Unit *u;
return log_oom();
log_error("[%s:%u] Failed to load unit %s, ignoring: %s", filename, line, rvalue, bus_error(&error, r));
const char *filename,
unsigned line,
const char *section,
const char *lvalue,
int ltype,
const char *rvalue,
void *data,
void *userdata) {
PathSpec *s;
PathType b;
path_free_specs(p);
return log_oom();
if (!path_is_absolute(k)) {
free(k);
free(k);
return log_oom();
s->type = b;
const char *filename,
unsigned line,
const char *section,
const char *lvalue,
int ltype,
const char *rvalue,
void *data,
void *userdata) {
Unit *u;
return log_oom();
const char *filename,
unsigned line,
const char *section,
const char *lvalue,
int ltype,
const char *rvalue,
void *data,
void *userdata) {
Unit *x;
return log_oom();
log_error("[%s:%u] Failed to load unit %s, ignoring: %s", filename, line, rvalue, bus_error(&error, r));
const char *filename,
unsigned line,
const char *section,
const char *lvalue,
int ltype,
const char *rvalue,
void *data,
void *userdata) {
char *state, *w;
size_t l;
t = strndup(w, l);
return log_oom();
return log_oom();
const char *filename,
unsigned line,
const char *section,
const char *lvalue,
int ltype,
const char *rvalue,
void *data,
void *userdata) {
assert(s);
s->start_timeout_defined = true;
s->start_timeout_defined = true;
const char *filename,
unsigned line,
const char *section,
const char *lvalue,
int ltype,
const char *rvalue,
void *data,
void *userdata) {
return log_oom();
return log_oom();
int config_parse_environ(
const char *filename,
unsigned line,
const char *section,
const char *lvalue,
int ltype,
const char *rvalue,
void *data,
void *userdata) {
size_t l;
assert(u);
return log_oom();
_cleanup_free_ char *n;
n = cunescape_length(w, l);
return log_oom();
if (!env_assignment_is_valid(n)) {
return log_oom();
*env = x;
int config_parse_ip_tos(
const char *filename,
unsigned line,
const char *section,
const char *lvalue,
int ltype,
const char *rvalue,
void *data,
void *userdata) {
*ip_tos = x;
const char *filename,
unsigned line,
const char *section,
const char *lvalue,
int ltype,
const char *rvalue,
void *data,
void *userdata) {
Condition *c;
if (trigger)
rvalue++;
if (negate)
rvalue++;
return log_oom();
if (!path_is_absolute(p)) {
return log_oom();
const char *filename,
unsigned line,
const char *section,
const char *lvalue,
int ltype,
const char *rvalue,
void *data,
void *userdata) {
Condition *c;
if (trigger)
rvalue++;
if (negate)
rvalue++;
return log_oom();
return log_oom();
const char *filename,
unsigned line,
const char *section,
const char *lvalue,
int ltype,
const char *rvalue,
void *data,
void *userdata) {
Condition *c;
if (trigger)
rvalue++;
if (negate)
rvalue++;
log_error("[%s:%u] Failed to parse boolean value in condition, ignoring: %s", filename, line, rvalue);
return log_oom();
DEFINE_CONFIG_PARSE_ENUM(config_parse_notify_access, notify_access, NotifyAccess, "Failed to parse notify access specifier");
DEFINE_CONFIG_PARSE_ENUM(config_parse_start_limit_action, start_limit_action, StartLimitAction, "Failed to parse start limit action specifier");
const char *filename,
unsigned line,
const char *section,
const char *lvalue,
int ltype,
const char *rvalue,
void *data,
void *userdata) {
size_t a, b;
const CGroupSemantics *s;
return log_oom();
const char *filename,
unsigned line,
const char *section,
const char *lvalue,
int ltype,
const char *rvalue,
void *data,
void *userdata) {
const CGroupSemantics *s;
log_error("[%s:%u] Unknown or unsupported cgroup attribute %s, ignoring: %s", filename, line, lvalue, rvalue);
const char *filename,
unsigned line,
const char *section,
const char *lvalue,
int ltype,
const char *rvalue,
void *data,
void *userdata) {
bool empty_before;
const char *filename,
unsigned line,
const char *section,
const char *lvalue,
int ltype,
const char *rvalue,
void *data,
void *userdata) {
assert(u);
for (a = b = u->documentation; a && *a; a++) {
if (is_valid_documentation_url(*a))
free(*a);
*b = NULL;
const char *filename,
unsigned line,
const char *section,
const char *lvalue,
int ltype,
const char *rvalue,
void *data,
void *userdata) {
bool invert = false;
size_t l;
char *state;
assert(u);
invert = true;
rvalue++;
if (!c->syscall_filter) {
size_t n;
if (!c->syscall_filter)
return log_oom();
#ifdef __NR_sigreturn
int id;
t = strndup(w, l);
return log_oom();
if (id < 0) {
if (invert)
c->no_new_privileges = true;
int fd, r;
FILE *f;
if (c++ >= FOLLOW_MAX)
return -ELOOP;
if (!id) {
if (!id)
return -ENOMEM;
if (fd >= 0)
return -errno;
r = -errno;
*_f = f;
assert(u);
assert(*u);
r = unit_merge_by_name(*u, k);
free(k);
if (other) {
*u = other;
if (id == k)
free(k);
assert(u);
if (!symlink_names)
return -ENOMEM;
if (!filename) {
r = -ENOMEM;
goto finish;
if (r != -ENOENT)
goto finish;
if (!filename) {
r = -ENOMEM;
goto finish;
r = -ENOENT;
if (r != -ENOENT)
goto finish;
if (!filename) {
goto finish;
merged = u;
goto finish;
if (merged != u) {
goto finish;
r = -errno;
goto finish;
r = config_parse(filename, f, UNIT_VTABLE(u)->sections, config_item_perf_lookup, (void*) load_fragment_gperf_lookup, false, u);
goto finish;
if (u->source_path) {
u->source_mtime = 0;
fclose(f);
Iterator i;
assert(u);
if (t == u->id)
r = load_from_path(u, t);
return -ENOMEM;
r = load_from_path(u, k);
free(k);
if (t == u->id)
k = unit_name_template(t);
return -ENOMEM;
r = load_from_path(u, k);
free(k);
const char *rvalue;
} table[] = {
#ifdef HAVE_SYSV_COMPAT
assert(f);
const char *dot;
const ConfigPerfItem *p;
if (dot)
if (prev)
prev = i;