load-fragment.c revision 19f6d710772305610b928bc2678b9d77fe11e770
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen/***
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen This file is part of systemd.
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen Copyright 2010 Lennart Poettering
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen Copyright 2012 Holger Hans Peter Freyther
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen systemd is free software; you can redistribute it and/or modify it
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen under the terms of the GNU Lesser General Public License as published by
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen the Free Software Foundation; either version 2.1 of the License, or
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen (at your option) any later version.
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen systemd is distributed in the hope that it will be useful, but
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen WITHOUT ANY WARRANTY; without even the implied warranty of
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen Lesser General Public License for more details.
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen You should have received a copy of the GNU Lesser General Public License
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen along with systemd; If not, see <http://www.gnu.org/licenses/>.
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen***/
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen#include <linux/oom.h>
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen#include <assert.h>
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen#include <errno.h>
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen#include <string.h>
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen#include <unistd.h>
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen#include <fcntl.h>
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen#include <sched.h>
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen#include <sys/prctl.h>
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen#include <sys/mount.h>
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen#include <linux/fs.h>
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen#include <sys/stat.h>
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen#include <sys/time.h>
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen#include <sys/resource.h>
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
f2341e0a87cab1558c84c933956e9181d5fb6c52Lennart Poettering#include <systemd/sd-messages.h>
f2341e0a87cab1558c84c933956e9181d5fb6c52Lennart Poettering
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen#include "unit.h"
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen#include "strv.h"
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen#include "conf-parser.h"
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen#include "load-fragment.h"
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen#include "log.h"
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen#include "ioprio.h"
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen#include "securebits.h"
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen#include "missing.h"
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen#include "unit-name.h"
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen#include "unit-printf.h"
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen#include "dbus-common.h"
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen#include "utf8.h"
d5d8429a12c4b1ef0dcd226c0904f00f4fa4898aLennart Poettering#include "path-util.h"
d5d8429a12c4b1ef0dcd226c0904f00f4fa4898aLennart Poettering#include "syscall-list.h"
d5d8429a12c4b1ef0dcd226c0904f00f4fa4898aLennart Poettering#include "env-util.h"
d5d8429a12c4b1ef0dcd226c0904f00f4fa4898aLennart Poettering#include "cgroup.h"
d5d8429a12c4b1ef0dcd226c0904f00f4fa4898aLennart Poettering
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen#ifndef HAVE_SYSV_COMPAT
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersenint config_parse_warn_compat(const char *unit,
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen const char *filename,
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen unsigned line,
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen const char *section,
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen const char *lvalue,
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen int ltype,
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen const char *rvalue,
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen void *data,
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen void *userdata) {
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen log_syntax(unit, LOG_DEBUG, filename, line, EINVAL,
8fba1c8d4e3d05d2af2848b6570bdc09e725d06eZbigniew Jędrzejewski-Szmek "Support for option %s= has been disabled at compile time and is ignored",
8fba1c8d4e3d05d2af2848b6570bdc09e725d06eZbigniew Jędrzejewski-Szmek lvalue);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen return 0;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen}
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen#endif
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersenint config_parse_unit_deps(const char* unit,
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen const char *filename,
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen unsigned line,
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen const char *section,
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen const char *lvalue,
260ad50f5b4a9795032e3119c64f838a2d03370dThomas Hindoe Paaboel Andersen int ltype,
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen const char *rvalue,
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen void *data,
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen void *userdata) {
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen UnitDependency d = ltype;
8fba1c8d4e3d05d2af2848b6570bdc09e725d06eZbigniew Jędrzejewski-Szmek Unit *u = userdata;
8fba1c8d4e3d05d2af2848b6570bdc09e725d06eZbigniew Jędrzejewski-Szmek char *w;
8fba1c8d4e3d05d2af2848b6570bdc09e725d06eZbigniew Jędrzejewski-Szmek size_t l;
8fba1c8d4e3d05d2af2848b6570bdc09e725d06eZbigniew Jędrzejewski-Szmek char *state;
8fba1c8d4e3d05d2af2848b6570bdc09e725d06eZbigniew Jędrzejewski-Szmek
8fba1c8d4e3d05d2af2848b6570bdc09e725d06eZbigniew Jędrzejewski-Szmek assert(filename);
8fba1c8d4e3d05d2af2848b6570bdc09e725d06eZbigniew Jędrzejewski-Szmek assert(lvalue);
8fba1c8d4e3d05d2af2848b6570bdc09e725d06eZbigniew Jędrzejewski-Szmek assert(rvalue);
8fba1c8d4e3d05d2af2848b6570bdc09e725d06eZbigniew Jędrzejewski-Szmek
8fba1c8d4e3d05d2af2848b6570bdc09e725d06eZbigniew Jędrzejewski-Szmek FOREACH_WORD_QUOTED(w, l, rvalue, state) {
8fba1c8d4e3d05d2af2848b6570bdc09e725d06eZbigniew Jędrzejewski-Szmek _cleanup_free_ char *t = NULL, *k = NULL;
8fba1c8d4e3d05d2af2848b6570bdc09e725d06eZbigniew Jędrzejewski-Szmek int r;
8fba1c8d4e3d05d2af2848b6570bdc09e725d06eZbigniew Jędrzejewski-Szmek
8fba1c8d4e3d05d2af2848b6570bdc09e725d06eZbigniew Jędrzejewski-Szmek t = strndup(w, l);
8fba1c8d4e3d05d2af2848b6570bdc09e725d06eZbigniew Jędrzejewski-Szmek if (!t)
8fba1c8d4e3d05d2af2848b6570bdc09e725d06eZbigniew Jędrzejewski-Szmek return log_oom();
8fba1c8d4e3d05d2af2848b6570bdc09e725d06eZbigniew Jędrzejewski-Szmek
8fba1c8d4e3d05d2af2848b6570bdc09e725d06eZbigniew Jędrzejewski-Szmek r = unit_name_printf(u, t, &k);
8fba1c8d4e3d05d2af2848b6570bdc09e725d06eZbigniew Jędrzejewski-Szmek if (r < 0) {
8fba1c8d4e3d05d2af2848b6570bdc09e725d06eZbigniew Jędrzejewski-Szmek log_syntax(unit, LOG_ERR, filename, line, -r,
8fba1c8d4e3d05d2af2848b6570bdc09e725d06eZbigniew Jędrzejewski-Szmek "Failed to resolve specifiers, ignoring: %s", strerror(-r));
8fba1c8d4e3d05d2af2848b6570bdc09e725d06eZbigniew Jędrzejewski-Szmek continue;
8fba1c8d4e3d05d2af2848b6570bdc09e725d06eZbigniew Jędrzejewski-Szmek }
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen r = unit_add_dependency_by_name(u, d, k, NULL, true);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen if (r < 0)
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen log_syntax(unit, LOG_ERR, filename, line, -r,
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen "Failed to add dependency on %s, ignoring: %s", k, strerror(-r));
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen }
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen return 0;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen}
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersenint config_parse_unit_string_printf(const char *unit,
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen const char *filename,
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen unsigned line,
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen const char *section,
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen const char *lvalue,
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen int ltype,
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen const char *rvalue,
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen void *data,
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen void *userdata) {
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen Unit *u = userdata;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen _cleanup_free_ char *k = NULL;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen int r;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen assert(filename);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen assert(lvalue);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen assert(rvalue);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen assert(u);
b7e7184634d573fb73143210962acce205f37f61Michael Biebl
b7e7184634d573fb73143210962acce205f37f61Michael Biebl r = unit_full_printf(u, rvalue, &k);
b7e7184634d573fb73143210962acce205f37f61Michael Biebl if (r < 0)
b7e7184634d573fb73143210962acce205f37f61Michael Biebl log_syntax(unit, LOG_ERR, filename, line, -r,
b7e7184634d573fb73143210962acce205f37f61Michael Biebl "Failed to resolve unit specifiers on %s, ignoring: %s", rvalue, strerror(-r));
b7e7184634d573fb73143210962acce205f37f61Michael Biebl
b7e7184634d573fb73143210962acce205f37f61Michael Biebl return config_parse_string(unit, filename, line, section, lvalue, ltype,
b7e7184634d573fb73143210962acce205f37f61Michael Biebl k ? k : rvalue, data, userdata);
b7e7184634d573fb73143210962acce205f37f61Michael Biebl}
b7e7184634d573fb73143210962acce205f37f61Michael Biebl
b7e7184634d573fb73143210962acce205f37f61Michael Bieblint config_parse_unit_strv_printf(const char *unit,
b7e7184634d573fb73143210962acce205f37f61Michael Biebl const char *filename,
b7e7184634d573fb73143210962acce205f37f61Michael Biebl unsigned line,
b7e7184634d573fb73143210962acce205f37f61Michael Biebl const char *section,
b7e7184634d573fb73143210962acce205f37f61Michael Biebl const char *lvalue,
b7e7184634d573fb73143210962acce205f37f61Michael Biebl int ltype,
b7e7184634d573fb73143210962acce205f37f61Michael Biebl const char *rvalue,
b7e7184634d573fb73143210962acce205f37f61Michael Biebl void *data,
b7e7184634d573fb73143210962acce205f37f61Michael Biebl void *userdata) {
b7e7184634d573fb73143210962acce205f37f61Michael Biebl
b7e7184634d573fb73143210962acce205f37f61Michael Biebl Unit *u = userdata;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen _cleanup_free_ char *k = NULL;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen int r;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
8fba1c8d4e3d05d2af2848b6570bdc09e725d06eZbigniew Jędrzejewski-Szmek assert(filename);
8fba1c8d4e3d05d2af2848b6570bdc09e725d06eZbigniew Jędrzejewski-Szmek assert(lvalue);
8fba1c8d4e3d05d2af2848b6570bdc09e725d06eZbigniew Jędrzejewski-Szmek assert(rvalue);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen assert(u);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen r = unit_full_printf(u, rvalue, &k);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen if (r < 0)
260ad50f5b4a9795032e3119c64f838a2d03370dThomas Hindoe Paaboel Andersen log_syntax(unit, LOG_ERR, filename, line, -r,
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen "Failed to resolve unit specifiers on %s, ignoring: %s", rvalue, strerror(-r));
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
8fba1c8d4e3d05d2af2848b6570bdc09e725d06eZbigniew Jędrzejewski-Szmek return config_parse_strv(unit, filename, line, section, lvalue, ltype,
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen k ? k : rvalue, data, userdata);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen}
77354c7e6f096a447245a8781c1eaa4acbe67089Martin Pitt
77354c7e6f096a447245a8781c1eaa4acbe67089Martin Pittint config_parse_unit_path_printf(const char *unit,
77354c7e6f096a447245a8781c1eaa4acbe67089Martin Pitt const char *filename,
4e5589836c9e143796c3f3d81e67ab7a9209e2b0Martin Pitt unsigned line,
77354c7e6f096a447245a8781c1eaa4acbe67089Martin Pitt const char *section,
9993ef2e9817b35b1d467707bef12b2a140b62dcLennart Poettering const char *lvalue,
77354c7e6f096a447245a8781c1eaa4acbe67089Martin Pitt int ltype,
77354c7e6f096a447245a8781c1eaa4acbe67089Martin Pitt const char *rvalue,
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen void *data,
4a62c710b62a5a3c7a8a278b810b9d5b5a0c8f4fMichal Schmidt void *userdata) {
4a62c710b62a5a3c7a8a278b810b9d5b5a0c8f4fMichal Schmidt
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen Unit *u = userdata;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen _cleanup_free_ char *k = NULL;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen int r;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
aad0a2c80097926757d4385e5f5492082d47f006Zbigniew Jędrzejewski-Szmek assert(filename);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen assert(lvalue);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen assert(rvalue);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen assert(u);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen r = unit_full_printf(u, rvalue, &k);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen if (r < 0)
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen log_syntax(unit, LOG_ERR, filename, line, -r,
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen "Failed to resolve unit specifiers on %s, ignoring: %s", rvalue, strerror(-r));
260ad50f5b4a9795032e3119c64f838a2d03370dThomas Hindoe Paaboel Andersen
260ad50f5b4a9795032e3119c64f838a2d03370dThomas Hindoe Paaboel Andersen return config_parse_path(unit, filename, line, section, lvalue, ltype,
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen k ? k : rvalue, data, userdata);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen}
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersenint config_parse_socket_listen(const char *unit,
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen const char *filename,
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen unsigned line,
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen const char *section,
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen const char *lvalue,
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen int ltype,
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen const char *rvalue,
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen void *data,
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen void *userdata) {
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen SocketPort *p, *tail;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen Socket *s;
d171ed1c50ba64928b7fb30ee2ae729fdfe0826bThomas Hindoe Paaboel Andersen int r;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen assert(filename);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen assert(lvalue);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen assert(rvalue);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen assert(data);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen s = SOCKET(data);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen if (isempty(rvalue)) {
260ad50f5b4a9795032e3119c64f838a2d03370dThomas Hindoe Paaboel Andersen /* An empty assignment removes all ports */
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen socket_free_ports(s);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen return 0;
f2341e0a87cab1558c84c933956e9181d5fb6c52Lennart Poettering }
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen p = new0(SocketPort, 1);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen if (!p)
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen return log_oom();
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen if (ltype != SOCKET_SOCKET) {
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen p->type = ltype;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen r = unit_full_printf(UNIT(s), rvalue, &p->path);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen if (r < 0) {
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen p->path = strdup(rvalue);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen if (!p->path) {
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen free(p);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen return log_oom();
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen } else
0b2ec8a3bfdd6118b3b4958d236ee203ad420f28David Herrmann log_syntax(unit, LOG_ERR, filename, line, -r,
0b2ec8a3bfdd6118b3b4958d236ee203ad420f28David Herrmann "Failed to resolve unit specifiers on %s, ignoring: %s", rvalue, strerror(-r));
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen }
264581a2f1599a27de577549dc75fccefef6a579Felipe Sateler
264581a2f1599a27de577549dc75fccefef6a579Felipe Sateler path_kill_slashes(p->path);
0b2ec8a3bfdd6118b3b4958d236ee203ad420f28David Herrmann
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen } else if (streq(lvalue, "ListenNetlink")) {
0b2ec8a3bfdd6118b3b4958d236ee203ad420f28David Herrmann _cleanup_free_ char *k = NULL;
0b2ec8a3bfdd6118b3b4958d236ee203ad420f28David Herrmann
0b2ec8a3bfdd6118b3b4958d236ee203ad420f28David Herrmann p->type = SOCKET_SOCKET;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen r = unit_full_printf(UNIT(s), rvalue, &k);
0b2ec8a3bfdd6118b3b4958d236ee203ad420f28David Herrmann if (r < 0)
0b2ec8a3bfdd6118b3b4958d236ee203ad420f28David Herrmann log_syntax(unit, LOG_ERR, filename, line, -r,
0b2ec8a3bfdd6118b3b4958d236ee203ad420f28David Herrmann "Failed to resolve unit specifiers on %s, ignoring: %s", rvalue, strerror(-r));
0b2ec8a3bfdd6118b3b4958d236ee203ad420f28David Herrmann
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen r = socket_address_parse_netlink(&p->address, k ? k : rvalue);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen if (r < 0) {
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen log_syntax(unit, LOG_ERR, filename, line, -r,
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen "Failed to parse address value, ignoring: %s", rvalue);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen free(p);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen return 0;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen }
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen } else {
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen _cleanup_free_ char *k = NULL;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen p->type = SOCKET_SOCKET;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen r = unit_full_printf(UNIT(s), rvalue, &k);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen if (r < 0)
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen log_syntax(unit, LOG_ERR, filename, line, -r,
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen "Failed to resolve unit specifiers on %s, ignoring: %s", rvalue, strerror(-r));
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen r = socket_address_parse(&p->address, k ? k : rvalue);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen if (r < 0) {
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen log_syntax(unit, LOG_ERR, filename, line, -r,
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen "Failed to parse address value, ignoring: %s", rvalue);
4e4885553447f6f4c014bfa3e5b5837a76a0e612Lennart Poettering free(p);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen return 0;
4e4885553447f6f4c014bfa3e5b5837a76a0e612Lennart Poettering }
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen if (streq(lvalue, "ListenStream"))
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen p->address.type = SOCK_STREAM;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen else if (streq(lvalue, "ListenDatagram"))
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen p->address.type = SOCK_DGRAM;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen else {
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen assert(streq(lvalue, "ListenSequentialPacket"));
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen p->address.type = SOCK_SEQPACKET;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen }
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen if (socket_address_family(&p->address) != AF_LOCAL && p->address.type == SOCK_SEQPACKET) {
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen log_syntax(unit, LOG_ERR, filename, line, ENOTSUP,
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen "Address family not supported, ignoring: %s", rvalue);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen free(p);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen return 0;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen }
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen }
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen p->fd = -1;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen if (s->ports) {
29e0e6d8c1f7f648b7c998880d034eaa3e58c53aMartin Pitt LIST_FIND_TAIL(SocketPort, port, s->ports, tail);
4e4885553447f6f4c014bfa3e5b5837a76a0e612Lennart Poettering LIST_INSERT_AFTER(SocketPort, port, s->ports, tail, p);
40780877c19ef408da8ab21f4156cfc153f94b5cMartin Pitt } else
3315f085178f46155fda345d9526c09083b45946Lennart Poettering LIST_PREPEND(SocketPort, port, s->ports, p);
4e4885553447f6f4c014bfa3e5b5837a76a0e612Lennart Poettering
3315f085178f46155fda345d9526c09083b45946Lennart Poettering return 0;
3315f085178f46155fda345d9526c09083b45946Lennart Poettering}
29e0e6d8c1f7f648b7c998880d034eaa3e58c53aMartin Pitt
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersenint config_parse_socket_bind(const char *unit,
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen const char *filename,
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen unsigned line,
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen const char *section,
7410616cd9dbbec97cf98d75324da5cda2b2f7a2Lennart Poettering const char *lvalue,
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen int ltype,
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen const char *rvalue,
7410616cd9dbbec97cf98d75324da5cda2b2f7a2Lennart Poettering void *data,
7410616cd9dbbec97cf98d75324da5cda2b2f7a2Lennart Poettering void *userdata) {
7410616cd9dbbec97cf98d75324da5cda2b2f7a2Lennart Poettering
7410616cd9dbbec97cf98d75324da5cda2b2f7a2Lennart Poettering Socket *s;
3315f085178f46155fda345d9526c09083b45946Lennart Poettering SocketAddressBindIPv6Only b;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen assert(filename);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen assert(lvalue);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen assert(rvalue);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen assert(data);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen s = SOCKET(data);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen b = socket_address_bind_ipv6_only_from_string(rvalue);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen if (b < 0) {
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen int r;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen r = parse_boolean(rvalue);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen if (r < 0) {
1e2fee5f757c0bb3a6fea216b1e10ee7b3c0e12eZbigniew Jędrzejewski-Szmek log_syntax(unit, LOG_ERR, filename, line, EINVAL,
1e2fee5f757c0bb3a6fea216b1e10ee7b3c0e12eZbigniew Jędrzejewski-Szmek "Failed to parse bind IPv6 only value, ignoring: %s", rvalue);
1e2fee5f757c0bb3a6fea216b1e10ee7b3c0e12eZbigniew Jędrzejewski-Szmek return 0;
1e2fee5f757c0bb3a6fea216b1e10ee7b3c0e12eZbigniew Jędrzejewski-Szmek }
1e2fee5f757c0bb3a6fea216b1e10ee7b3c0e12eZbigniew Jędrzejewski-Szmek
1e2fee5f757c0bb3a6fea216b1e10ee7b3c0e12eZbigniew Jędrzejewski-Szmek s->bind_ipv6_only = r ? SOCKET_ADDRESS_IPV6_ONLY : SOCKET_ADDRESS_BOTH;
1e2fee5f757c0bb3a6fea216b1e10ee7b3c0e12eZbigniew Jędrzejewski-Szmek } else
2c09a745eba5f463e12b498a2f62a5036253c55cFelipe Sateler s->bind_ipv6_only = b;
1e2fee5f757c0bb3a6fea216b1e10ee7b3c0e12eZbigniew Jędrzejewski-Szmek
1e2fee5f757c0bb3a6fea216b1e10ee7b3c0e12eZbigniew Jędrzejewski-Szmek return 0;
1e2fee5f757c0bb3a6fea216b1e10ee7b3c0e12eZbigniew Jędrzejewski-Szmek}
e987f2a809c6bab7e7bae4ca8f598ea5bafd5225Zbigniew Jędrzejewski-Szmek
1e2fee5f757c0bb3a6fea216b1e10ee7b3c0e12eZbigniew Jędrzejewski-Szmekint config_parse_exec_nice(const char *unit,
1e2fee5f757c0bb3a6fea216b1e10ee7b3c0e12eZbigniew Jędrzejewski-Szmek const char *filename,
1e2fee5f757c0bb3a6fea216b1e10ee7b3c0e12eZbigniew Jędrzejewski-Szmek unsigned line,
1e2fee5f757c0bb3a6fea216b1e10ee7b3c0e12eZbigniew Jędrzejewski-Szmek const char *section,
1e2fee5f757c0bb3a6fea216b1e10ee7b3c0e12eZbigniew Jędrzejewski-Szmek const char *lvalue,
1e2fee5f757c0bb3a6fea216b1e10ee7b3c0e12eZbigniew Jędrzejewski-Szmek int ltype,
1e2fee5f757c0bb3a6fea216b1e10ee7b3c0e12eZbigniew Jędrzejewski-Szmek const char *rvalue,
2c09a745eba5f463e12b498a2f62a5036253c55cFelipe Sateler void *data,
2c09a745eba5f463e12b498a2f62a5036253c55cFelipe Sateler void *userdata) {
1e2fee5f757c0bb3a6fea216b1e10ee7b3c0e12eZbigniew Jędrzejewski-Szmek
1e2fee5f757c0bb3a6fea216b1e10ee7b3c0e12eZbigniew Jędrzejewski-Szmek ExecContext *c = data;
e987f2a809c6bab7e7bae4ca8f598ea5bafd5225Zbigniew Jędrzejewski-Szmek int priority, r;
f2341e0a87cab1558c84c933956e9181d5fb6c52Lennart Poettering
2c09a745eba5f463e12b498a2f62a5036253c55cFelipe Sateler assert(filename);
1e2fee5f757c0bb3a6fea216b1e10ee7b3c0e12eZbigniew Jędrzejewski-Szmek assert(lvalue);
1e2fee5f757c0bb3a6fea216b1e10ee7b3c0e12eZbigniew Jędrzejewski-Szmek assert(rvalue);
1e2fee5f757c0bb3a6fea216b1e10ee7b3c0e12eZbigniew Jędrzejewski-Szmek assert(data);
1e2fee5f757c0bb3a6fea216b1e10ee7b3c0e12eZbigniew Jędrzejewski-Szmek
1e2fee5f757c0bb3a6fea216b1e10ee7b3c0e12eZbigniew Jędrzejewski-Szmek r = safe_atoi(rvalue, &priority);
1e2fee5f757c0bb3a6fea216b1e10ee7b3c0e12eZbigniew Jędrzejewski-Szmek if (r < 0) {
1e2fee5f757c0bb3a6fea216b1e10ee7b3c0e12eZbigniew Jędrzejewski-Szmek log_syntax(unit, LOG_ERR, filename, line, -r,
1e2fee5f757c0bb3a6fea216b1e10ee7b3c0e12eZbigniew Jędrzejewski-Szmek "Failed to parse nice priority, ignoring: %s. ", rvalue);
1e2fee5f757c0bb3a6fea216b1e10ee7b3c0e12eZbigniew Jędrzejewski-Szmek return 0;
1e2fee5f757c0bb3a6fea216b1e10ee7b3c0e12eZbigniew Jędrzejewski-Szmek }
1e2fee5f757c0bb3a6fea216b1e10ee7b3c0e12eZbigniew Jędrzejewski-Szmek
1e2fee5f757c0bb3a6fea216b1e10ee7b3c0e12eZbigniew Jędrzejewski-Szmek if (priority < PRIO_MIN || priority >= PRIO_MAX) {
1e2fee5f757c0bb3a6fea216b1e10ee7b3c0e12eZbigniew Jędrzejewski-Szmek log_syntax(unit, LOG_ERR, filename, line, ERANGE,
1e2fee5f757c0bb3a6fea216b1e10ee7b3c0e12eZbigniew Jędrzejewski-Szmek "Nice priority out of range, ignoring: %s", rvalue);
1e2fee5f757c0bb3a6fea216b1e10ee7b3c0e12eZbigniew Jędrzejewski-Szmek return 0;
1e2fee5f757c0bb3a6fea216b1e10ee7b3c0e12eZbigniew Jędrzejewski-Szmek }
0b2ec8a3bfdd6118b3b4958d236ee203ad420f28David Herrmann
2c09a745eba5f463e12b498a2f62a5036253c55cFelipe Sateler c->nice = priority;
2c09a745eba5f463e12b498a2f62a5036253c55cFelipe Sateler c->nice_set = true;
2c09a745eba5f463e12b498a2f62a5036253c55cFelipe Sateler
1e2fee5f757c0bb3a6fea216b1e10ee7b3c0e12eZbigniew Jędrzejewski-Szmek return 0;
1e2fee5f757c0bb3a6fea216b1e10ee7b3c0e12eZbigniew Jędrzejewski-Szmek}
f2341e0a87cab1558c84c933956e9181d5fb6c52Lennart Poettering
1e2fee5f757c0bb3a6fea216b1e10ee7b3c0e12eZbigniew Jędrzejewski-Szmekint config_parse_exec_oom_score_adjust(const char* unit,
1e2fee5f757c0bb3a6fea216b1e10ee7b3c0e12eZbigniew Jędrzejewski-Szmek const char *filename,
1e2fee5f757c0bb3a6fea216b1e10ee7b3c0e12eZbigniew Jędrzejewski-Szmek unsigned line,
1e2fee5f757c0bb3a6fea216b1e10ee7b3c0e12eZbigniew Jędrzejewski-Szmek const char *section,
1e2fee5f757c0bb3a6fea216b1e10ee7b3c0e12eZbigniew Jędrzejewski-Szmek const char *lvalue,
1e2fee5f757c0bb3a6fea216b1e10ee7b3c0e12eZbigniew Jędrzejewski-Szmek int ltype,
1e2fee5f757c0bb3a6fea216b1e10ee7b3c0e12eZbigniew Jędrzejewski-Szmek const char *rvalue,
1e2fee5f757c0bb3a6fea216b1e10ee7b3c0e12eZbigniew Jędrzejewski-Szmek void *data,
1e2fee5f757c0bb3a6fea216b1e10ee7b3c0e12eZbigniew Jędrzejewski-Szmek void *userdata) {
1e2fee5f757c0bb3a6fea216b1e10ee7b3c0e12eZbigniew Jędrzejewski-Szmek
1e2fee5f757c0bb3a6fea216b1e10ee7b3c0e12eZbigniew Jędrzejewski-Szmek ExecContext *c = data;
1e2fee5f757c0bb3a6fea216b1e10ee7b3c0e12eZbigniew Jędrzejewski-Szmek int oa, r;
1e2fee5f757c0bb3a6fea216b1e10ee7b3c0e12eZbigniew Jędrzejewski-Szmek
1e2fee5f757c0bb3a6fea216b1e10ee7b3c0e12eZbigniew Jędrzejewski-Szmek assert(filename);
e987f2a809c6bab7e7bae4ca8f598ea5bafd5225Zbigniew Jędrzejewski-Szmek assert(lvalue);
1e2fee5f757c0bb3a6fea216b1e10ee7b3c0e12eZbigniew Jędrzejewski-Szmek assert(rvalue);
1e2fee5f757c0bb3a6fea216b1e10ee7b3c0e12eZbigniew Jędrzejewski-Szmek assert(data);
1e2fee5f757c0bb3a6fea216b1e10ee7b3c0e12eZbigniew Jędrzejewski-Szmek
f2341e0a87cab1558c84c933956e9181d5fb6c52Lennart Poettering r = safe_atoi(rvalue, &oa);
1e2fee5f757c0bb3a6fea216b1e10ee7b3c0e12eZbigniew Jędrzejewski-Szmek if (r < 0) {
1e2fee5f757c0bb3a6fea216b1e10ee7b3c0e12eZbigniew Jędrzejewski-Szmek log_syntax(unit, LOG_ERR, filename, line, -r,
1e2fee5f757c0bb3a6fea216b1e10ee7b3c0e12eZbigniew Jędrzejewski-Szmek "Failed to parse the OOM score adjust value, ignoring: %s", rvalue);
1e2fee5f757c0bb3a6fea216b1e10ee7b3c0e12eZbigniew Jędrzejewski-Szmek return 0;
1e2fee5f757c0bb3a6fea216b1e10ee7b3c0e12eZbigniew Jędrzejewski-Szmek }
1e2fee5f757c0bb3a6fea216b1e10ee7b3c0e12eZbigniew Jędrzejewski-Szmek
1e2fee5f757c0bb3a6fea216b1e10ee7b3c0e12eZbigniew Jędrzejewski-Szmek if (oa < OOM_SCORE_ADJ_MIN || oa > OOM_SCORE_ADJ_MAX) {
1e2fee5f757c0bb3a6fea216b1e10ee7b3c0e12eZbigniew Jędrzejewski-Szmek log_syntax(unit, LOG_ERR, filename, line, ERANGE,
1e2fee5f757c0bb3a6fea216b1e10ee7b3c0e12eZbigniew Jędrzejewski-Szmek "OOM score adjust value out of range, ignoring: %s", rvalue);
1e2fee5f757c0bb3a6fea216b1e10ee7b3c0e12eZbigniew Jędrzejewski-Szmek return 0;
1e2fee5f757c0bb3a6fea216b1e10ee7b3c0e12eZbigniew Jędrzejewski-Szmek }
1e2fee5f757c0bb3a6fea216b1e10ee7b3c0e12eZbigniew Jędrzejewski-Szmek
1e2fee5f757c0bb3a6fea216b1e10ee7b3c0e12eZbigniew Jędrzejewski-Szmek c->oom_score_adjust = oa;
e987f2a809c6bab7e7bae4ca8f598ea5bafd5225Zbigniew Jędrzejewski-Szmek c->oom_score_adjust_set = true;
1e2fee5f757c0bb3a6fea216b1e10ee7b3c0e12eZbigniew Jędrzejewski-Szmek
1e2fee5f757c0bb3a6fea216b1e10ee7b3c0e12eZbigniew Jędrzejewski-Szmek return 0;
1e2fee5f757c0bb3a6fea216b1e10ee7b3c0e12eZbigniew Jędrzejewski-Szmek}
e987f2a809c6bab7e7bae4ca8f598ea5bafd5225Zbigniew Jędrzejewski-Szmek
1e2fee5f757c0bb3a6fea216b1e10ee7b3c0e12eZbigniew Jędrzejewski-Szmekint config_parse_exec(const char *unit,
1e2fee5f757c0bb3a6fea216b1e10ee7b3c0e12eZbigniew Jędrzejewski-Szmek const char *filename,
f2341e0a87cab1558c84c933956e9181d5fb6c52Lennart Poettering unsigned line,
1e2fee5f757c0bb3a6fea216b1e10ee7b3c0e12eZbigniew Jędrzejewski-Szmek const char *section,
1e2fee5f757c0bb3a6fea216b1e10ee7b3c0e12eZbigniew Jędrzejewski-Szmek const char *lvalue,
1e2fee5f757c0bb3a6fea216b1e10ee7b3c0e12eZbigniew Jędrzejewski-Szmek int ltype,
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen const char *rvalue,
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen void *data,
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen void *userdata) {
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen ExecCommand **e = data, *nce;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen char *path, **n;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen unsigned k;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen int r;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen assert(filename);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen assert(lvalue);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen assert(rvalue);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen assert(e);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen e += ltype;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen if (isempty(rvalue)) {
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen /* An empty assignment resets the list */
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen exec_command_free_list(*e);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen *e = NULL;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen return 0;
77354c7e6f096a447245a8781c1eaa4acbe67089Martin Pitt }
77354c7e6f096a447245a8781c1eaa4acbe67089Martin Pitt
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen /* We accept an absolute path as first argument, or
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen * alternatively an absolute prefixed with @ to allow
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen * overriding of argv[0]. */
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen for (;;) {
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen int i;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen char *w;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen size_t l;
f2341e0a87cab1558c84c933956e9181d5fb6c52Lennart Poettering char *state;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen bool honour_argv0 = false, ignore = false;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen path = NULL;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen nce = NULL;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen n = NULL;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen rvalue += strspn(rvalue, WHITESPACE);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen if (rvalue[0] == 0)
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen break;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen for (i = 0; i < 2; i++) {
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen if (rvalue[0] == '-' && !ignore) {
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen ignore = true;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen rvalue ++;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen }
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen if (rvalue[0] == '@' && !honour_argv0) {
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen honour_argv0 = true;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen rvalue ++;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen }
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen }
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen if (*rvalue != '/') {
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen log_syntax(unit, LOG_ERR, filename, line, EINVAL,
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen "Executable path is not absolute, ignoring: %s", rvalue);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen return 0;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen }
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen k = 0;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen FOREACH_WORD_QUOTED(w, l, rvalue, state) {
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen if (strneq(w, ";", MAX(l, 1U)))
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen break;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen k++;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen }
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen n = new(char*, k + !honour_argv0);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen if (!n)
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen return log_oom();
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen k = 0;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen FOREACH_WORD_QUOTED(w, l, rvalue, state) {
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen if (strneq(w, ";", MAX(l, 1U)))
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen break;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen else if (strneq(w, "\\;", MAX(l, 1U)))
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen w ++;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen if (honour_argv0 && w == rvalue) {
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen assert(!path);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen path = strndup(w, l);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen if (!path) {
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen r = log_oom();
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen goto fail;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen }
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen if (!utf8_is_valid(path)) {
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen log_syntax(unit, LOG_ERR, filename, line, EINVAL,
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen "Path is not UTF-8 clean, ignoring assignment: %s",
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen rvalue);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen r = 0;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen goto fail;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen }
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen } else {
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen char *c;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen c = n[k++] = cunescape_length(w, l);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen if (!c) {
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen r = log_oom();
f2341e0a87cab1558c84c933956e9181d5fb6c52Lennart Poettering goto fail;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen }
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen if (!utf8_is_valid(c)) {
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen log_syntax(unit, LOG_ERR, filename, line, EINVAL,
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen "Path is not UTF-8 clean, ignoring assignment: %s",
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen rvalue);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen r = 0;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen goto fail;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen }
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen }
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen }
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen n[k] = NULL;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen if (!n[0]) {
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen log_syntax(unit, LOG_ERR, filename, line, EINVAL,
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen "Invalid command line, ignoring: %s", rvalue);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen r = 0;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen goto fail;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen }
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen if (!path) {
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen path = strdup(n[0]);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen if (!path) {
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen r = log_oom();
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen goto fail;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen }
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen }
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen assert(path_is_absolute(path));
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen nce = new0(ExecCommand, 1);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen if (!nce) {
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen r = log_oom();
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen goto fail;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen }
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen nce->argv = n;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen nce->path = path;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen nce->ignore = ignore;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen path_kill_slashes(nce->path);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen exec_command_append_list(e, nce);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
1e2fee5f757c0bb3a6fea216b1e10ee7b3c0e12eZbigniew Jędrzejewski-Szmek rvalue = state;
1e2fee5f757c0bb3a6fea216b1e10ee7b3c0e12eZbigniew Jędrzejewski-Szmek }
1e2fee5f757c0bb3a6fea216b1e10ee7b3c0e12eZbigniew Jędrzejewski-Szmek
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen return 0;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersenfail:
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen n[k] = NULL;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen strv_free(n);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen free(path);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen free(nce);
1e2fee5f757c0bb3a6fea216b1e10ee7b3c0e12eZbigniew Jędrzejewski-Szmek
1e2fee5f757c0bb3a6fea216b1e10ee7b3c0e12eZbigniew Jędrzejewski-Szmek return r;
1e2fee5f757c0bb3a6fea216b1e10ee7b3c0e12eZbigniew Jędrzejewski-Szmek}
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel AndersenDEFINE_CONFIG_PARSE_ENUM(config_parse_service_type, service_type, ServiceType, "Failed to parse service type");
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel AndersenDEFINE_CONFIG_PARSE_ENUM(config_parse_service_restart, service_restart, ServiceRestart, "Failed to parse service restart specifier");
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersenint config_parse_socket_bindtodevice(const char* unit,
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen const char *filename,
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen unsigned line,
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen const char *section,
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen const char *lvalue,
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen int ltype,
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen const char *rvalue,
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen void *data,
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen void *userdata) {
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen Socket *s = data;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen char *n;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen assert(filename);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen assert(lvalue);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen assert(rvalue);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen assert(data);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen if (rvalue[0] && !streq(rvalue, "*")) {
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen n = strdup(rvalue);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen if (!n)
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen return log_oom();
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen } else
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen n = NULL;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen free(s->bind_to_device);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen s->bind_to_device = n;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen return 0;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen}
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel AndersenDEFINE_CONFIG_PARSE_ENUM(config_parse_output, exec_output, ExecOutput, "Failed to parse output specifier");
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel AndersenDEFINE_CONFIG_PARSE_ENUM(config_parse_input, exec_input, ExecInput, "Failed to parse input specifier");
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersenint config_parse_exec_io_class(const char *unit,
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen const char *filename,
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen unsigned line,
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen const char *section,
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen const char *lvalue,
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen int ltype,
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen const char *rvalue,
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen void *data,
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen void *userdata) {
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen ExecContext *c = data;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen int x;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen assert(filename);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen assert(lvalue);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen assert(rvalue);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen assert(data);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen x = ioprio_class_from_string(rvalue);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen if (x < 0) {
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen log_syntax(unit, LOG_ERR, filename, line, EINVAL,
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen "Failed to parse IO scheduling class, ignoring: %s", rvalue);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen return 0;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen }
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen c->ioprio = IOPRIO_PRIO_VALUE(x, IOPRIO_PRIO_DATA(c->ioprio));
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen c->ioprio_set = true;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen return 0;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen}
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersenint config_parse_exec_io_priority(const char *unit,
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen const char *filename,
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen unsigned line,
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen const char *section,
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen const char *lvalue,
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen int ltype,
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen const char *rvalue,
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen void *data,
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen void *userdata) {
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen ExecContext *c = data;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen int i, r;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen assert(filename);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen assert(lvalue);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen assert(rvalue);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen assert(data);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen r = safe_atoi(rvalue, &i);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen if (r < 0 || i < 0 || i >= IOPRIO_BE_NR) {
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen log_syntax(unit, LOG_ERR, filename, line, -r,
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen "Failed to parse IO priority, ignoring: %s", rvalue);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen return 0;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen }
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen c->ioprio = IOPRIO_PRIO_VALUE(IOPRIO_PRIO_CLASS(c->ioprio), i);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen c->ioprio_set = true;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen return 0;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen}
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersenint config_parse_exec_cpu_sched_policy(const char *unit,
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen const char *filename,
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen unsigned line,
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen const char *section,
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen const char *lvalue,
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen int ltype,
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen const char *rvalue,
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen void *data,
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen void *userdata) {
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen ExecContext *c = data;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen int x;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen assert(filename);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen assert(lvalue);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen assert(rvalue);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen assert(data);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen x = sched_policy_from_string(rvalue);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen if (x < 0) {
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen log_syntax(unit, LOG_ERR, filename, line, -x,
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen "Failed to parse CPU scheduling policy, ignoring: %s", rvalue);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen return 0;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen }
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen c->cpu_sched_policy = x;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen /* Moving to or from real-time policy? We need to adjust the priority */
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen c->cpu_sched_priority = CLAMP(c->cpu_sched_priority, sched_get_priority_min(x), sched_get_priority_max(x));
a8ffe6fbcbfdba39aef8dce8b298b3e0cb377c0eZbigniew Jędrzejewski-Szmek c->cpu_sched_set = true;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen return 0;
a8ffe6fbcbfdba39aef8dce8b298b3e0cb377c0eZbigniew Jędrzejewski-Szmek}
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersenint config_parse_exec_cpu_sched_prio(const char *unit,
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen const char *filename,
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen unsigned line,
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen const char *section,
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen const char *lvalue,
56f64d95763a799ba4475daf44d8e9f72a1bd474Michal Schmidt int ltype,
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen const char *rvalue,
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen void *data,
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen void *userdata) {
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen ExecContext *c = data;
8fba1c8d4e3d05d2af2848b6570bdc09e725d06eZbigniew Jędrzejewski-Szmek int i, min, max, r;
805e5dda0a01c99d231824e1a9c4a208418bf342Lennart Poettering
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen assert(filename);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen assert(lvalue);
a986501b9059b72e8deced262554fbdd1ab9da17Lennart Poettering assert(rvalue);
a986501b9059b72e8deced262554fbdd1ab9da17Lennart Poettering assert(data);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
a986501b9059b72e8deced262554fbdd1ab9da17Lennart Poettering r = safe_atoi(rvalue, &i);
805e5dda0a01c99d231824e1a9c4a208418bf342Lennart Poettering if (r < 0) {
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen log_syntax(unit, LOG_ERR, filename, line, -r,
805e5dda0a01c99d231824e1a9c4a208418bf342Lennart Poettering "Failed to parse CPU scheduling policy, ignoring: %s", rvalue);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen return 0;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen }
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen /* On Linux RR/FIFO range from 1 to 99 and OTHER/BATCH may only be 0 */
805e5dda0a01c99d231824e1a9c4a208418bf342Lennart Poettering min = sched_get_priority_min(c->cpu_sched_policy);
805e5dda0a01c99d231824e1a9c4a208418bf342Lennart Poettering max = sched_get_priority_max(c->cpu_sched_policy);
805e5dda0a01c99d231824e1a9c4a208418bf342Lennart Poettering
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen if (i < min || i > max) {
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen log_syntax(unit, LOG_ERR, filename, line, ERANGE,
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen "CPU scheduling priority is out of range, ignoring: %s", rvalue);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen return 0;
a986501b9059b72e8deced262554fbdd1ab9da17Lennart Poettering }
a986501b9059b72e8deced262554fbdd1ab9da17Lennart Poettering
a986501b9059b72e8deced262554fbdd1ab9da17Lennart Poettering c->cpu_sched_priority = i;
805e5dda0a01c99d231824e1a9c4a208418bf342Lennart Poettering c->cpu_sched_set = true;
805e5dda0a01c99d231824e1a9c4a208418bf342Lennart Poettering
805e5dda0a01c99d231824e1a9c4a208418bf342Lennart Poettering return 0;
805e5dda0a01c99d231824e1a9c4a208418bf342Lennart Poettering}
a8ffe6fbcbfdba39aef8dce8b298b3e0cb377c0eZbigniew Jędrzejewski-Szmek
f4f01ec146d91cb6943828851d98eee6a1ad4dd9Martin Pittint config_parse_exec_cpu_affinity(const char *unit,
f4f01ec146d91cb6943828851d98eee6a1ad4dd9Martin Pitt const char *filename,
f4f01ec146d91cb6943828851d98eee6a1ad4dd9Martin Pitt unsigned line,
f4f01ec146d91cb6943828851d98eee6a1ad4dd9Martin Pitt const char *section,
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen const char *lvalue,
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen int ltype,
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen const char *rvalue,
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen void *data,
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen void *userdata) {
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen ExecContext *c = data;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen char *w;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen size_t l;
805e5dda0a01c99d231824e1a9c4a208418bf342Lennart Poettering char *state;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen assert(filename);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen assert(lvalue);
805e5dda0a01c99d231824e1a9c4a208418bf342Lennart Poettering assert(rvalue);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen assert(data);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen if (isempty(rvalue)) {
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen /* An empty assignment resets the CPU list */
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen if (c->cpuset)
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen CPU_FREE(c->cpuset);
a8ffe6fbcbfdba39aef8dce8b298b3e0cb377c0eZbigniew Jędrzejewski-Szmek c->cpuset = NULL;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen return 0;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen }
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
7a03974a6f4510dcb1850515a80c2063c767a80fThomas Hindoe Paaboel Andersen FOREACH_WORD_QUOTED(w, l, rvalue, state) {
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen _cleanup_free_ char *t = NULL;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen int r;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen unsigned cpu;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen t = strndup(w, l);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen if (!t)
a8ffe6fbcbfdba39aef8dce8b298b3e0cb377c0eZbigniew Jędrzejewski-Szmek return log_oom();
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen r = safe_atou(t, &cpu);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen if (!c->cpuset) {
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen c->cpuset = cpu_set_malloc(&c->cpuset_ncpus);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen if (!c->cpuset)
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen return log_oom();
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen }
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen if (r < 0 || cpu >= c->cpuset_ncpus) {
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen log_syntax(unit, LOG_ERR, filename, line, ERANGE,
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen "Failed to parse CPU affinity '%s', ignoring: %s", t, rvalue);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen return 0;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen }
56f64d95763a799ba4475daf44d8e9f72a1bd474Michal Schmidt
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen CPU_SET_S(cpu, CPU_ALLOC_SIZE(c->cpuset_ncpus), c->cpuset);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen }
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen return 0;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen}
7a03974a6f4510dcb1850515a80c2063c767a80fThomas Hindoe Paaboel Andersen
7a03974a6f4510dcb1850515a80c2063c767a80fThomas Hindoe Paaboel Andersenint config_parse_exec_capabilities(const char *unit,
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen const char *filename,
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen unsigned line,
a34bf9db5da0fdd6bdb14459e203dbe41ee99614Lennart Poettering const char *section,
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen const char *lvalue,
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen int ltype,
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen const char *rvalue,
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen void *data,
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen void *userdata) {
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen ExecContext *c = data;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen cap_t cap;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen assert(filename);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen assert(lvalue);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen assert(rvalue);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen assert(data);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen cap = cap_from_text(rvalue);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen if (!cap) {
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen log_syntax(unit, LOG_ERR, filename, line, errno,
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen "Failed to parse capabilities, ignoring: %s", rvalue);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen return 0;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen }
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen if (c->capabilities)
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen cap_free(c->capabilities);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen c->capabilities = cap;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen return 0;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen}
8c84621c25c563c7428f3d355136fc542389aab8Thomas Hindoe Paaboel Andersen
8c84621c25c563c7428f3d355136fc542389aab8Thomas Hindoe Paaboel Andersenint config_parse_exec_secure_bits(const char *unit,
f4f01ec146d91cb6943828851d98eee6a1ad4dd9Martin Pitt const char *filename,
f4f01ec146d91cb6943828851d98eee6a1ad4dd9Martin Pitt unsigned line,
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen const char *section,
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen const char *lvalue,
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen int ltype,
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen const char *rvalue,
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen void *data,
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen void *userdata) {
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen ExecContext *c = data;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen char *w;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen size_t l;
d5099efc47d4e6ac60816b5381a5f607ab03f06eMichal Schmidt char *state;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen assert(filename);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen assert(lvalue);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen assert(rvalue);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen assert(data);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen if (isempty(rvalue)) {
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen /* An empty assignment resets the field */
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen c->secure_bits = 0;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen return 0;
d5099efc47d4e6ac60816b5381a5f607ab03f06eMichal Schmidt }
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen FOREACH_WORD_QUOTED(w, l, rvalue, state) {
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen if (first_word(w, "keep-caps"))
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen c->secure_bits |= 1<<SECURE_KEEP_CAPS;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen else if (first_word(w, "keep-caps-locked"))
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen c->secure_bits |= 1<<SECURE_KEEP_CAPS_LOCKED;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen else if (first_word(w, "no-setuid-fixup"))
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen c->secure_bits |= 1<<SECURE_NO_SETUID_FIXUP;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen else if (first_word(w, "no-setuid-fixup-locked"))
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen c->secure_bits |= 1<<SECURE_NO_SETUID_FIXUP_LOCKED;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen else if (first_word(w, "noroot"))
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen c->secure_bits |= 1<<SECURE_NOROOT;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen else if (first_word(w, "noroot-locked"))
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen c->secure_bits |= 1<<SECURE_NOROOT_LOCKED;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen else {
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen log_syntax(unit, LOG_ERR, filename, line, EINVAL,
260ad50f5b4a9795032e3119c64f838a2d03370dThomas Hindoe Paaboel Andersen "Failed to parse secure bits, ignoring: %s", rvalue);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen return 0;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen }
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen }
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen return 0;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen}
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersenint config_parse_bounding_set(const char *unit,
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen const char *filename,
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen unsigned line,
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen const char *section,
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen const char *lvalue,
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen int ltype,
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen const char *rvalue,
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen void *data,
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen void *userdata) {
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen uint64_t *capability_bounding_set_drop = data;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen char *w;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen size_t l;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen char *state;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen bool invert = false;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen uint64_t sum = 0;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen assert(filename);
f8bc41822ba19905707a97f9d87262f2c2b6e5faZbigniew Jędrzejewski-Szmek assert(lvalue);
5921fc3cc36df4baa5e16060e7675ace9eda2befThomas Hindoe Paaboel Andersen assert(rvalue);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen assert(data);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen if (rvalue[0] == '~') {
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen invert = true;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen rvalue++;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen }
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen /* Note that we store this inverted internally, since the
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen * kernel wants it like this. But we actually expose it
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen * non-inverted everywhere to have a fully normalized
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen * interface. */
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen FOREACH_WORD_QUOTED(w, l, rvalue, state) {
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen _cleanup_free_ char *t = NULL;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen int r;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen cap_value_t cap;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
b2c23da8cea1987a1a329f5a964d3299b7ca7890Lennart Poettering t = strndup(w, l);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen if (!t)
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen return log_oom();
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen r = cap_from_name(t, &cap);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen if (r < 0) {
d5099efc47d4e6ac60816b5381a5f607ab03f06eMichal Schmidt log_syntax(unit, LOG_ERR, filename, line, errno,
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen "Failed to parse capability in bounding set, ignoring: %s", t);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen continue;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen }
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen sum |= ((uint64_t) 1ULL) << (uint64_t) cap;
a8ffe6fbcbfdba39aef8dce8b298b3e0cb377c0eZbigniew Jędrzejewski-Szmek }
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen if (invert)
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen *capability_bounding_set_drop |= sum;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen else
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen *capability_bounding_set_drop |= ~sum;
a8ffe6fbcbfdba39aef8dce8b298b3e0cb377c0eZbigniew Jędrzejewski-Szmek
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen return 0;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen}
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersenint config_parse_limit(const char *unit,
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen const char *filename,
b3fae863ef548add2d01c3956ce7720f4eeeca7eLennart Poettering unsigned line,
b3fae863ef548add2d01c3956ce7720f4eeeca7eLennart Poettering const char *section,
b3fae863ef548add2d01c3956ce7720f4eeeca7eLennart Poettering const char *lvalue,
b3fae863ef548add2d01c3956ce7720f4eeeca7eLennart Poettering int ltype,
b3fae863ef548add2d01c3956ce7720f4eeeca7eLennart Poettering const char *rvalue,
b3fae863ef548add2d01c3956ce7720f4eeeca7eLennart Poettering void *data,
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen void *userdata) {
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen struct rlimit **rl = data;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen unsigned long long u;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen assert(filename);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen assert(lvalue);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen assert(rvalue);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen assert(data);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen rl += ltype;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
if (streq(rvalue, "infinity"))
u = (unsigned long long) RLIM_INFINITY;
else {
int r;
r = safe_atollu(rvalue, &u);
if (r < 0) {
log_syntax(unit, LOG_ERR, filename, line, -r,
"Failed to parse resource value, ignoring: %s", rvalue);
return 0;
}
}
if (!*rl) {
*rl = new(struct rlimit, 1);
if (!*rl)
return log_oom();
}
(*rl)->rlim_cur = (*rl)->rlim_max = (rlim_t) u;
return 0;
}
#ifdef HAVE_SYSV_COMPAT
int config_parse_sysv_priority(const char *unit,
const char *filename,
unsigned line,
const char *section,
const char *lvalue,
int ltype,
const char *rvalue,
void *data,
void *userdata) {
int *priority = data;
int i, r;
assert(filename);
assert(lvalue);
assert(rvalue);
assert(data);
r = safe_atoi(rvalue, &i);
if (r < 0 || i < 0) {
log_syntax(unit, LOG_ERR, filename, line, -r,
"Failed to parse SysV start priority, ignoring: %s", rvalue);
return 0;
}
*priority = (int) i;
return 0;
}
#endif
int config_parse_fsck_passno(const char *unit,
const char *filename,
unsigned line,
const char *section,
const char *lvalue,
int ltype,
const char *rvalue,
void *data,
void *userdata) {
int *passno = data;
int i, r;
assert(filename);
assert(lvalue);
assert(rvalue);
assert(data);
r = safe_atoi(rvalue, &i);
if (r || i < 0) {
log_syntax(unit, LOG_ERR, filename, line, -r,
"Failed to parse fsck pass number, ignoring: %s", rvalue);
return 0;
}
*passno = (int) i;
return 0;
}
DEFINE_CONFIG_PARSE_ENUM(config_parse_kill_mode, kill_mode, KillMode, "Failed to parse kill mode");
int config_parse_kill_signal(const char *unit,
const char *filename,
unsigned line,
const char *section,
const char *lvalue,
int ltype,
const char *rvalue,
void *data,
void *userdata) {
int *sig = data;
int r;
assert(filename);
assert(lvalue);
assert(rvalue);
assert(sig);
r = signal_from_string_try_harder(rvalue);
if (r <= 0) {
log_syntax(unit, LOG_ERR, filename, line, -r,
"Failed to parse kill signal, ignoring: %s", rvalue);
return 0;
}
*sig = r;
return 0;
}
int config_parse_exec_mount_flags(const char *unit,
const char *filename,
unsigned line,
const char *section,
const char *lvalue,
int ltype,
const char *rvalue,
void *data,
void *userdata) {
ExecContext *c = data;
char *w;
size_t l;
char *state;
unsigned long flags = 0;
assert(filename);
assert(lvalue);
assert(rvalue);
assert(data);
FOREACH_WORD_SEPARATOR(w, l, rvalue, ", ", state) {
_cleanup_free_ char *t;
t = strndup(w, l);
if (!t)
return log_oom();
if (streq(t, "shared"))
flags |= MS_SHARED;
else if (streq(t, "slave"))
flags |= MS_SLAVE;
else if (streq(w, "private"))
flags |= MS_PRIVATE;
else {
log_syntax(unit, LOG_ERR, filename, line, EINVAL,
"Failed to parse mount flag %s, ignoring: %s",
t, rvalue);
return 0;
}
}
c->mount_flags = flags;
return 0;
}
int config_parse_timer(const char *unit,
const char *filename,
unsigned line,
const char *section,
const char *lvalue,
int ltype,
const char *rvalue,
void *data,
void *userdata) {
Timer *t = data;
usec_t u = 0;
TimerValue *v;
TimerBase b;
CalendarSpec *c = NULL;
clockid_t id;
assert(filename);
assert(lvalue);
assert(rvalue);
assert(data);
if (isempty(rvalue)) {
/* Empty assignment resets list */
timer_free_values(t);
return 0;
}
b = timer_base_from_string(lvalue);
if (b < 0) {
log_syntax(unit, LOG_ERR, filename, line, -b,
"Failed to parse timer base, ignoring: %s", lvalue);
return 0;
}
if (b == TIMER_CALENDAR) {
if (calendar_spec_from_string(rvalue, &c) < 0) {
log_syntax(unit, LOG_ERR, filename, line, EINVAL,
"Failed to parse calendar specification, ignoring: %s",
rvalue);
return 0;
}
id = CLOCK_REALTIME;
} else {
if (parse_sec(rvalue, &u) < 0) {
log_syntax(unit, LOG_ERR, filename, line, EINVAL,
"Failed to parse timer value, ignoring: %s",
rvalue);
return 0;
}
id = CLOCK_MONOTONIC;
}
v = new0(TimerValue, 1);
if (!v)
return log_oom();
v->base = b;
v->clock_id = id;
v->value = u;
v->calendar_spec = c;
LIST_PREPEND(TimerValue, value, t->values, v);
return 0;
}
int config_parse_trigger_unit(
const char *unit,
const char *filename,
unsigned line,
const char *section,
const char *lvalue,
int ltype,
const char *rvalue,
void *data,
void *userdata) {
_cleanup_free_ char *p = NULL;
Unit *u = data;
UnitType type;
int r;
assert(filename);
assert(lvalue);
assert(rvalue);
assert(data);
if (!set_isempty(u->dependencies[UNIT_TRIGGERS])) {
log_syntax(unit, LOG_ERR, filename, line, EINVAL,
"Multiple units to trigger specified, ignoring: %s", rvalue);
return 0;
}
r = unit_name_printf(u, rvalue, &p);
if (r < 0)
log_syntax(unit, LOG_ERR, filename, line, -r,
"Failed to resolve specifiers, ignoring: %s", strerror(-r));
type = unit_name_to_type(p ?: rvalue);
if (type < 0) {
log_syntax(unit, LOG_ERR, filename, line, EINVAL,
"Unit type not valid, ignoring: %s", rvalue);
return 0;
}
if (type == u->type) {
log_syntax(unit, LOG_ERR, filename, line, EINVAL,
"Trigger cannot be of same type, ignoring: %s", rvalue);
return 0;
}
r = unit_add_two_dependencies_by_name(u, UNIT_BEFORE, UNIT_TRIGGERS, p ?: rvalue, NULL, true);
if (r < 0) {
log_syntax(unit, LOG_ERR, filename, line, -r,
"Failed to add trigger on %s, ignoring: %s", p ?: rvalue, strerror(-r));
return 0;
}
return 0;
}
int config_parse_path_spec(const char *unit,
const char *filename,
unsigned line,
const char *section,
const char *lvalue,
int ltype,
const char *rvalue,
void *data,
void *userdata) {
Path *p = data;
PathSpec *s;
PathType b;
_cleanup_free_ char *k = NULL;
int r;
assert(filename);
assert(lvalue);
assert(rvalue);
assert(data);
if (isempty(rvalue)) {
/* Empty assignment clears list */
path_free_specs(p);
return 0;
}
b = path_type_from_string(lvalue);
if (b < 0) {
log_syntax(unit, LOG_ERR, filename, line, EINVAL,
"Failed to parse path type, ignoring: %s", lvalue);
return 0;
}
r = unit_full_printf(UNIT(p), rvalue, &k);
if (r < 0) {
k = strdup(rvalue);
if (!k)
return log_oom();
else
log_syntax(unit, LOG_ERR, filename, line, -r,
"Failed to resolve unit specifiers on %s. Ignoring.",
rvalue);
}
if (!path_is_absolute(k)) {
log_syntax(unit, LOG_ERR, filename, line, EINVAL,
"Path is not absolute, ignoring: %s", k);
return 0;
}
s = new0(PathSpec, 1);
if (!s)
return log_oom();
s->path = path_kill_slashes(k);
k = NULL;
s->type = b;
s->inotify_fd = -1;
LIST_PREPEND(PathSpec, spec, p->specs, s);
return 0;
}
int config_parse_socket_service(const char *unit,
const char *filename,
unsigned line,
const char *section,
const char *lvalue,
int ltype,
const char *rvalue,
void *data,
void *userdata) {
Socket *s = data;
int r;
DBusError error;
Unit *x;
_cleanup_free_ char *p = NULL;
assert(filename);
assert(lvalue);
assert(rvalue);
assert(data);
dbus_error_init(&error);
r = unit_name_printf(UNIT(s), rvalue, &p);
if (r < 0)
log_syntax(unit, LOG_ERR, filename, line, -r,
"Failed to resolve specifiers, ignoring: %s", rvalue);
if (!endswith(p ?: rvalue, ".service")) {
log_syntax(unit, LOG_ERR, filename, line, EINVAL,
"Unit must be of type service, ignoring: %s", rvalue);
return 0;
}
r = manager_load_unit(UNIT(s)->manager, p ?: rvalue, NULL, &error, &x);
if (r < 0) {
log_syntax(unit, LOG_ERR, filename, line, r,
"Failed to load unit %s, ignoring: %s",
rvalue, bus_error(&error, r));
dbus_error_free(&error);
return 0;
}
unit_ref_set(&s->service, x);
return 0;
}
int config_parse_service_sockets(const char *unit,
const char *filename,
unsigned line,
const char *section,
const char *lvalue,
int ltype,
const char *rvalue,
void *data,
void *userdata) {
Service *s = data;
int r;
char *state, *w;
size_t l;
assert(filename);
assert(lvalue);
assert(rvalue);
assert(data);
FOREACH_WORD_QUOTED(w, l, rvalue, state) {
_cleanup_free_ char *t = NULL, *k = NULL;
t = strndup(w, l);
if (!t)
return log_oom();
r = unit_name_printf(UNIT(s), t, &k);
if (r < 0)
log_syntax(unit, LOG_ERR, filename, line, -r,
"Failed to resolve specifiers, ignoring: %s", strerror(-r));
if (!endswith(k ?: t, ".socket")) {
log_syntax(unit, LOG_ERR, filename, line, EINVAL,
"Unit must be of type socket, ignoring: %s", k ?: t);
continue;
}
r = unit_add_two_dependencies_by_name(UNIT(s), UNIT_WANTS, UNIT_AFTER, k ?: t, NULL, true);
if (r < 0)
log_syntax(unit, LOG_ERR, filename, line, -r,
"Failed to add dependency on %s, ignoring: %s",
k ?: t, strerror(-r));
r = unit_add_dependency_by_name(UNIT(s), UNIT_TRIGGERED_BY, k ?: t, NULL, true);
if (r < 0)
return r;
}
return 0;
}
int config_parse_service_timeout(const char *unit,
const char *filename,
unsigned line,
const char *section,
const char *lvalue,
int ltype,
const char *rvalue,
void *data,
void *userdata) {
Service *s = userdata;
int r;
assert(filename);
assert(lvalue);
assert(rvalue);
assert(s);
r = config_parse_sec(unit, filename, line, section, lvalue, ltype,
rvalue, data, userdata);
if (r < 0)
return r;
if (streq(lvalue, "TimeoutSec")) {
s->start_timeout_defined = true;
s->timeout_stop_usec = s->timeout_start_usec;
} else if (streq(lvalue, "TimeoutStartSec"))
s->start_timeout_defined = true;
return 0;
}
int config_parse_unit_env_file(const char *unit,
const char *filename,
unsigned line,
const char *section,
const char *lvalue,
int ltype,
const char *rvalue,
void *data,
void *userdata) {
char ***env = data;
Unit *u = userdata;
_cleanup_free_ char *n = NULL;
const char *s;
int r;
assert(filename);
assert(lvalue);
assert(rvalue);
assert(data);
if (isempty(rvalue)) {
/* Empty assignment frees the list */
strv_free(*env);
*env = NULL;
return 0;
}
r = unit_full_printf(u, rvalue, &n);
if (r < 0)
log_syntax(unit, LOG_ERR, filename, line, r,
"Failed to resolve specifiers, ignoring: %s", rvalue);
s = n ?: rvalue;
if (!path_is_absolute(s[0] == '-' ? s + 1 : s)) {
log_syntax(unit, LOG_ERR, filename, line, EINVAL,
"Path '%s' is not absolute, ignoring.", s);
return 0;
}
r = strv_extend(env, s);
if (r < 0)
return log_oom();
return 0;
}
int config_parse_environ(const char *unit,
const char *filename,
unsigned line,
const char *section,
const char *lvalue,
int ltype,
const char *rvalue,
void *data,
void *userdata) {
Unit *u = userdata;
char*** env = data, *w, *state;
size_t l;
_cleanup_free_ char *k = NULL;
int r;
assert(filename);
assert(lvalue);
assert(rvalue);
assert(data);
if (isempty(rvalue)) {
/* Empty assignment resets the list */
strv_free(*env);
*env = NULL;
return 0;
}
if (u) {
r = unit_full_printf(u, rvalue, &k);
if (r < 0)
log_syntax(unit, LOG_ERR, filename, line, -r,
"Failed to resolve specifiers, ignoring: %s", rvalue);
}
if (!k)
k = strdup(rvalue);
if (!k)
return log_oom();
FOREACH_WORD_QUOTED(w, l, k, state) {
_cleanup_free_ char *n;
char **x;
n = cunescape_length(w, l);
if (!n)
return log_oom();
if (!env_assignment_is_valid(n)) {
log_syntax(unit, LOG_ERR, filename, line, EINVAL,
"Invalid environment assignment, ignoring: %s", rvalue);
continue;
}
x = strv_env_set(*env, n);
if (!x)
return log_oom();
strv_free(*env);
*env = x;
}
return 0;
}
int config_parse_ip_tos(const char *unit,
const char *filename,
unsigned line,
const char *section,
const char *lvalue,
int ltype,
const char *rvalue,
void *data,
void *userdata) {
int *ip_tos = data, x;
assert(filename);
assert(lvalue);
assert(rvalue);
assert(data);
x = ip_tos_from_string(rvalue);
if (x < 0) {
log_syntax(unit, LOG_ERR, filename, line, EINVAL,
"Failed to parse IP TOS value, ignoring: %s", rvalue);
return 0;
}
*ip_tos = x;
return 0;
}
int config_parse_unit_condition_path(const char *unit,
const char *filename,
unsigned line,
const char *section,
const char *lvalue,
int ltype,
const char *rvalue,
void *data,
void *userdata) {
ConditionType cond = ltype;
Unit *u = data;
bool trigger, negate;
Condition *c;
_cleanup_free_ char *p = NULL;
int r;
assert(filename);
assert(lvalue);
assert(rvalue);
assert(data);
if (isempty(rvalue)) {
/* Empty assignment resets the list */
condition_free_list(u->conditions);
u->conditions = NULL;
return 0;
}
trigger = rvalue[0] == '|';
if (trigger)
rvalue++;
negate = rvalue[0] == '!';
if (negate)
rvalue++;
r = unit_full_printf(u, rvalue, &p);
if (r < 0)
log_syntax(unit, LOG_ERR, filename, line, -r,
"Failed to resolve specifiers, ignoring: %s", rvalue);
if (!p) {
p = strdup(rvalue);
if (!p)
return log_oom();
}
if (!path_is_absolute(p)) {
log_syntax(unit, LOG_ERR, filename, line, EINVAL,
"Path in condition not absolute, ignoring: %s", p);
return 0;
}
c = condition_new(cond, p, trigger, negate);
if (!c)
return log_oom();
LIST_PREPEND(Condition, conditions, u->conditions, c);
return 0;
}
int config_parse_unit_condition_string(const char *unit,
const char *filename,
unsigned line,
const char *section,
const char *lvalue,
int ltype,
const char *rvalue,
void *data,
void *userdata) {
ConditionType cond = ltype;
Unit *u = data;
bool trigger, negate;
Condition *c;
_cleanup_free_ char *s = NULL;
int r;
assert(filename);
assert(lvalue);
assert(rvalue);
assert(data);
if (isempty(rvalue)) {
/* Empty assignment resets the list */
condition_free_list(u->conditions);
u->conditions = NULL;
return 0;
}
trigger = rvalue[0] == '|';
if (trigger)
rvalue++;
negate = rvalue[0] == '!';
if (negate)
rvalue++;
r = unit_full_printf(u, rvalue, &s);
if (r < 0)
log_syntax(unit, LOG_ERR, filename, line, -r,
"Failed to resolve specifiers, ignoring: %s", rvalue);
if (!s) {
s = strdup(rvalue);
if (!s)
return log_oom();
}
c = condition_new(cond, s, trigger, negate);
if (!c)
return log_oom();
LIST_PREPEND(Condition, conditions, u->conditions, c);
return 0;
}
int config_parse_unit_condition_null(const char *unit,
const char *filename,
unsigned line,
const char *section,
const char *lvalue,
int ltype,
const char *rvalue,
void *data,
void *userdata) {
Unit *u = data;
Condition *c;
bool trigger, negate;
int b;
assert(filename);
assert(lvalue);
assert(rvalue);
assert(data);
if (isempty(rvalue)) {
/* Empty assignment resets the list */
condition_free_list(u->conditions);
u->conditions = NULL;
return 0;
}
trigger = rvalue[0] == '|';
if (trigger)
rvalue++;
negate = rvalue[0] == '!';
if (negate)
rvalue++;
b = parse_boolean(rvalue);
if (b < 0) {
log_syntax(unit, LOG_ERR, filename, line, -b,
"Failed to parse boolean value in condition, ignoring: %s",
rvalue);
return 0;
}
if (!b)
negate = !negate;
c = condition_new(CONDITION_NULL, NULL, trigger, negate);
if (!c)
return log_oom();
LIST_PREPEND(Condition, conditions, u->conditions, c);
return 0;
}
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");
int config_parse_unit_requires_mounts_for(const char *unit,
const char *filename,
unsigned line,
const char *section,
const char *lvalue,
int ltype,
const char *rvalue,
void *data,
void *userdata) {
Unit *u = userdata;
int r;
bool empty_before;
assert(filename);
assert(lvalue);
assert(rvalue);
assert(data);
empty_before = !u->requires_mounts_for;
r = config_parse_path_strv(unit, filename, line, section, lvalue, ltype,
rvalue, data, userdata);
/* Make it easy to find units with requires_mounts set */
if (empty_before && u->requires_mounts_for)
LIST_PREPEND(Unit, has_requires_mounts_for, u->manager->has_requires_mounts_for, u);
return r;
}
int config_parse_documentation(const char *unit,
const char *filename,
unsigned line,
const char *section,
const char *lvalue,
int ltype,
const char *rvalue,
void *data,
void *userdata) {
Unit *u = userdata;
int r;
char **a, **b;
assert(filename);
assert(lvalue);
assert(rvalue);
assert(u);
if (isempty(rvalue)) {
/* Empty assignment resets the list */
strv_free(u->documentation);
u->documentation = NULL;
return 0;
}
r = config_parse_unit_strv_printf(unit, filename, line, section, lvalue, ltype,
rvalue, data, userdata);
if (r < 0)
return r;
for (a = b = u->documentation; a && *a; a++) {
if (is_valid_documentation_url(*a))
*(b++) = *a;
else {
log_syntax(unit, LOG_ERR, filename, line, EINVAL,
"Invalid URL, ignoring: %s", *a);
free(*a);
}
}
*b = NULL;
return r;
}
static void syscall_set(uint32_t *p, int nr) {
nr = SYSCALL_TO_INDEX(nr);
p[nr >> 4] |= 1 << (nr & 31);
}
static void syscall_unset(uint32_t *p, int nr) {
nr = SYSCALL_TO_INDEX(nr);
p[nr >> 4] &= ~(1 << (nr & 31));
}
int config_parse_syscall_filter(const char *unit,
const char *filename,
unsigned line,
const char *section,
const char *lvalue,
int ltype,
const char *rvalue,
void *data,
void *userdata) {
ExecContext *c = data;
Unit *u = userdata;
bool invert = false;
char *w;
size_t l;
char *state;
assert(filename);
assert(lvalue);
assert(rvalue);
assert(u);
if (isempty(rvalue)) {
/* Empty assignment resets the list */
free(c->syscall_filter);
c->syscall_filter = NULL;
return 0;
}
if (rvalue[0] == '~') {
invert = true;
rvalue++;
}
if (!c->syscall_filter) {
size_t n;
n = (syscall_max() + 31) >> 4;
c->syscall_filter = new(uint32_t, n);
if (!c->syscall_filter)
return log_oom();
memset(c->syscall_filter, invert ? 0xFF : 0, n * sizeof(uint32_t));
/* Add these by default */
syscall_set(c->syscall_filter, __NR_execve);
syscall_set(c->syscall_filter, __NR_rt_sigreturn);
#ifdef __NR_sigreturn
syscall_set(c->syscall_filter, __NR_sigreturn);
#endif
syscall_set(c->syscall_filter, __NR_exit_group);
syscall_set(c->syscall_filter, __NR_exit);
}
FOREACH_WORD_QUOTED(w, l, rvalue, state) {
int id;
_cleanup_free_ char *t = NULL;
t = strndup(w, l);
if (!t)
return log_oom();
id = syscall_from_name(t);
if (id < 0) {
log_syntax(unit, LOG_ERR, filename, line, EINVAL,
"Failed to parse syscall, ignoring: %s", t);
continue;
}
if (invert)
syscall_unset(c->syscall_filter, id);
else
syscall_set(c->syscall_filter, id);
}
c->no_new_privileges = true;
return 0;
}
int config_parse_unit_slice(
const char *unit,
const char *filename,
unsigned line,
const char *section,
const char *lvalue,
int ltype,
const char *rvalue,
void *data,
void *userdata) {
_cleanup_free_ char *k = NULL;
Unit *u = userdata, *slice;
int r;
assert(filename);
assert(lvalue);
assert(rvalue);
assert(u);
r = unit_name_printf(u, rvalue, &k);
if (r < 0)
log_syntax(unit, LOG_ERR, filename, line, -r,
"Failed to resolve unit specifiers on %s. Ignoring.", rvalue);
if (!k) {
k = strdup(rvalue);
if (!k)
return log_oom();
}
r = manager_load_unit(u->manager, k, NULL, NULL, &slice);
if (r < 0) {
log_syntax(unit, LOG_ERR, filename, line, -r,
"Failed to load slice unit %s. Ignoring.", k);
return 0;
}
if (slice->type != UNIT_SLICE) {
log_syntax(unit, LOG_ERR, filename, line, EINVAL,
"Slice unit %s is not a slice. Ignoring.", k);
return 0;
}
unit_ref_set(&u->slice, slice);
return 0;
}
DEFINE_CONFIG_PARSE_ENUM(config_parse_device_policy, cgroup_device_policy, CGroupDevicePolicy, "Failed to parse device policy");
int config_parse_cpu_shares(
const char *unit,
const char *filename,
unsigned line,
const char *section,
const char *lvalue,
int ltype,
const char *rvalue,
void *data,
void *userdata) {
CGroupContext *c = data;
unsigned long lu;
int r;
assert(filename);
assert(lvalue);
assert(rvalue);
if (isempty(rvalue)) {
c->cpu_shares = 1024;
return 0;
}
r = safe_atolu(rvalue, &lu);
if (r < 0 || lu <= 0) {
log_syntax(unit, LOG_ERR, filename, line, EINVAL,
"CPU shares '%s' invalid. Ignoring.", rvalue);
return 0;
}
c->cpu_shares = lu;
return 0;
}
int config_parse_memory_limit(
const char *unit,
const char *filename,
unsigned line,
const char *section,
const char *lvalue,
int ltype,
const char *rvalue,
void *data,
void *userdata) {
CGroupContext *c = data;
uint64_t *limit;
off_t bytes;
int r;
limit = streq(lvalue, "MemoryLimit") ? &c->memory_limit : &c->memory_soft_limit;
if (isempty(rvalue)) {
*limit = (uint64_t) -1;
return 0;
}
assert_cc(sizeof(uint64_t) == sizeof(off_t));
r = parse_bytes(rvalue, &bytes);
if (r < 0) {
log_syntax(unit, LOG_ERR, filename, line, EINVAL,
"Memory limit '%s' invalid. Ignoring.", rvalue);
return 0;
}
*limit = (uint64_t) bytes;
return 0;
}
int config_parse_device_allow(
const char *unit,
const char *filename,
unsigned line,
const char *section,
const char *lvalue,
int ltype,
const char *rvalue,
void *data,
void *userdata) {
_cleanup_free_ char *path = NULL;
CGroupContext *c = data;
CGroupDeviceAllow *a;
const char *m;
size_t n;
if (isempty(rvalue)) {
while (c->device_allow)
cgroup_context_free_device_allow(c, c->device_allow);
return 0;
}
n = strcspn(rvalue, WHITESPACE);
path = strndup(rvalue, n);
if (!path)
return log_oom();
if (!path_startswith(path, "/dev")) {
log_syntax(unit, LOG_ERR, filename, line, EINVAL,
"Invalid device node path '%s'. Ignoring.", path);
return 0;
}
m = rvalue + n + strspn(rvalue + n, WHITESPACE);
if (isempty(m))
m = "rwm";
if (!in_charset(m, "rwm")) {
log_syntax(unit, LOG_ERR, filename, line, EINVAL,
"Invalid device rights '%s'. Ignoring.", m);
return 0;
}
a = new0(CGroupDeviceAllow, 1);
if (!a)
return log_oom();
a->path = path;
path = NULL;
a->r = !!strchr(m, 'r');
a->w = !!strchr(m, 'w');
a->m = !!strchr(m, 'm');
LIST_PREPEND(CGroupDeviceAllow, device_allow, c->device_allow, a);
return 0;
}
int config_parse_blockio_weight(
const char *unit,
const char *filename,
unsigned line,
const char *section,
const char *lvalue,
int ltype,
const char *rvalue,
void *data,
void *userdata) {
CGroupContext *c = data;
unsigned long lu;
int r;
assert(filename);
assert(lvalue);
assert(rvalue);
if (isempty(rvalue)) {
c->blockio_weight = 1000;
return 0;
}
r = safe_atolu(rvalue, &lu);
if (r < 0 || lu < 10 || lu > 1000) {
log_syntax(unit, LOG_ERR, filename, line, EINVAL,
"Block IO weight '%s' invalid. Ignoring.", rvalue);
return 0;
}
c->blockio_weight = lu;
return 0;
}
int config_parse_blockio_device_weight(
const char *unit,
const char *filename,
unsigned line,
const char *section,
const char *lvalue,
int ltype,
const char *rvalue,
void *data,
void *userdata) {
_cleanup_free_ char *path = NULL;
CGroupBlockIODeviceWeight *w;
CGroupContext *c = data;
unsigned long lu;
const char *weight;
size_t n;
int r;
assert(filename);
assert(lvalue);
assert(rvalue);
if (isempty(rvalue)) {
while (c->blockio_device_weights)
cgroup_context_free_blockio_device_weight(c, c->blockio_device_weights);
return 0;
}
n = strcspn(rvalue, WHITESPACE);
weight = rvalue + n;
if (!*weight) {
log_syntax(unit, LOG_ERR, filename, line, EINVAL,
"Expected block device and device weight. Ignoring.");
return 0;
}
path = strndup(rvalue, n);
if (!path)
return log_oom();
if (!path_startswith(path, "/dev")) {
log_syntax(unit, LOG_ERR, filename, line, EINVAL,
"Invalid device node path '%s'. Ignoring.", path);
return 0;
}
weight += strspn(weight, WHITESPACE);
r = safe_atolu(weight, &lu);
if (r < 0 || lu < 10 || lu > 1000) {
log_syntax(unit, LOG_ERR, filename, line, EINVAL,
"Block IO weight '%s' invalid. Ignoring.", rvalue);
return 0;
}
w = new0(CGroupBlockIODeviceWeight, 1);
if (!w)
return log_oom();
w->path = path;
path = NULL;
w->weight = lu;
LIST_PREPEND(CGroupBlockIODeviceWeight, device_weights, c->blockio_device_weights, w);
return 0;
}
int config_parse_blockio_bandwidth(
const char *unit,
const char *filename,
unsigned line,
const char *section,
const char *lvalue,
int ltype,
const char *rvalue,
void *data,
void *userdata) {
_cleanup_free_ char *path = NULL;
CGroupBlockIODeviceBandwidth *b;
CGroupContext *c = data;
const char *bandwidth;
off_t bytes;
bool read;
size_t n;
int r;
assert(filename);
assert(lvalue);
assert(rvalue);
read = streq("BlockIOReadBandwidth", lvalue);
if (isempty(rvalue)) {
CGroupBlockIODeviceBandwidth *next;
LIST_FOREACH_SAFE (device_bandwidths, b, next, c->blockio_device_bandwidths)
if (b->read == read)
cgroup_context_free_blockio_device_bandwidth(c, b);
return 0;
}
n = strcspn(rvalue, WHITESPACE);
bandwidth = rvalue + n;
bandwidth += strspn(bandwidth, WHITESPACE);
if (!*bandwidth) {
log_syntax(unit, LOG_ERR, filename, line, EINVAL,
"Expected space separated pair of device node and bandwidth. Ignoring.");
return 0;
}
path = strndup(rvalue, n);
if (!path)
return log_oom();
if (!path_startswith(path, "/dev")) {
log_syntax(unit, LOG_ERR, filename, line, EINVAL,
"Invalid device node path '%s'. Ignoring.", path);
return 0;
}
r = parse_bytes(bandwidth, &bytes);
if (r < 0 || bytes <= 0) {
log_syntax(unit, LOG_ERR, filename, line, EINVAL,
"Block IO Bandwidth '%s' invalid. Ignoring.", rvalue);
return 0;
}
b = new0(CGroupBlockIODeviceBandwidth, 1);
if (!b)
return log_oom();
b->path = path;
path = NULL;
b->bandwidth = (uint64_t) bytes;
b->read = read;
LIST_PREPEND(CGroupBlockIODeviceBandwidth, device_bandwidths, c->blockio_device_bandwidths, b);
return 0;
}
#define FOLLOW_MAX 8
static int open_follow(char **filename, FILE **_f, Set *names, char **_final) {
unsigned c = 0;
int fd, r;
FILE *f;
char *id = NULL;
assert(filename);
assert(*filename);
assert(_f);
assert(names);
/* This will update the filename pointer if the loaded file is
* reached by a symlink. The old string will be freed. */
for (;;) {
char *target, *name;
if (c++ >= FOLLOW_MAX)
return -ELOOP;
path_kill_slashes(*filename);
/* Add the file name we are currently looking at to
* the names of this unit, but only if it is a valid
* unit name. */
name = path_get_file_name(*filename);
if (unit_name_is_valid(name, true)) {
id = set_get(names, name);
if (!id) {
id = strdup(name);
if (!id)
return -ENOMEM;
r = set_consume(names, id);
if (r < 0)
return r;
}
}
/* Try to open the file name, but don't if its a symlink */
fd = open(*filename, O_RDONLY|O_CLOEXEC|O_NOCTTY|O_NOFOLLOW);
if (fd >= 0)
break;
if (errno != ELOOP)
return -errno;
/* Hmm, so this is a symlink. Let's read the name, and follow it manually */
r = readlink_and_make_absolute(*filename, &target);
if (r < 0)
return r;
free(*filename);
*filename = target;
}
f = fdopen(fd, "re");
if (!f) {
r = -errno;
close_nointr_nofail(fd);
return r;
}
*_f = f;
*_final = id;
return 0;
}
static int merge_by_names(Unit **u, Set *names, const char *id) {
char *k;
int r;
assert(u);
assert(*u);
assert(names);
/* Let's try to add in all symlink names we found */
while ((k = set_steal_first(names))) {
/* First try to merge in the other name into our
* unit */
r = unit_merge_by_name(*u, k);
if (r < 0) {
Unit *other;
/* Hmm, we couldn't merge the other unit into
* ours? Then let's try it the other way
* round */
other = manager_get_unit((*u)->manager, k);
free(k);
if (other) {
r = unit_merge(other, *u);
if (r >= 0) {
*u = other;
return merge_by_names(u, names, NULL);
}
}
return r;
}
if (id == k)
unit_choose_id(*u, id);
free(k);
}
return 0;
}
static int load_from_path(Unit *u, const char *path) {
int r;
Set *symlink_names;
FILE *f = NULL;
char *filename = NULL, *id = NULL;
Unit *merged;
struct stat st;
assert(u);
assert(path);
symlink_names = set_new(string_hash_func, string_compare_func);
if (!symlink_names)
return -ENOMEM;
if (path_is_absolute(path)) {
filename = strdup(path);
if (!filename) {
r = -ENOMEM;
goto finish;
}
r = open_follow(&filename, &f, symlink_names, &id);
if (r < 0) {
free(filename);
filename = NULL;
if (r != -ENOENT)
goto finish;
}
} else {
char **p;
STRV_FOREACH(p, u->manager->lookup_paths.unit_path) {
/* Instead of opening the path right away, we manually
* follow all symlinks and add their name to our unit
* name set while doing so */
filename = path_make_absolute(path, *p);
if (!filename) {
r = -ENOMEM;
goto finish;
}
if (u->manager->unit_path_cache &&
!set_get(u->manager->unit_path_cache, filename))
r = -ENOENT;
else
r = open_follow(&filename, &f, symlink_names, &id);
if (r < 0) {
free(filename);
filename = NULL;
if (r != -ENOENT)
goto finish;
/* Empty the symlink names for the next run */
set_clear_free(symlink_names);
continue;
}
break;
}
}
if (!filename) {
/* Hmm, no suitable file found? */
r = 0;
goto finish;
}
merged = u;
r = merge_by_names(&merged, symlink_names, id);
if (r < 0)
goto finish;
if (merged != u) {
u->load_state = UNIT_MERGED;
r = 0;
goto finish;
}
if (fstat(fileno(f), &st) < 0) {
r = -errno;
goto finish;
}
if (null_or_empty(&st))
u->load_state = UNIT_MASKED;
else {
u->load_state = UNIT_LOADED;
/* Now, parse the file contents */
r = config_parse(u->id, filename, f, UNIT_VTABLE(u)->sections,
config_item_perf_lookup,
(void*) load_fragment_gperf_lookup, false, true, u);
if (r < 0)
goto finish;
}
free(u->fragment_path);
u->fragment_path = filename;
filename = NULL;
u->fragment_mtime = timespec_load(&st.st_mtim);
if (u->source_path) {
if (stat(u->source_path, &st) >= 0)
u->source_mtime = timespec_load(&st.st_mtim);
else
u->source_mtime = 0;
}
r = 0;
finish:
set_free_free(symlink_names);
free(filename);
if (f)
fclose(f);
return r;
}
int unit_load_fragment(Unit *u) {
int r;
Iterator i;
const char *t;
assert(u);
assert(u->load_state == UNIT_STUB);
assert(u->id);
/* First, try to find the unit under its id. We always look
* for unit files in the default directories, to make it easy
* to override things by placing things in /etc/systemd/system */
r = load_from_path(u, u->id);
if (r < 0)
return r;
/* Try to find an alias we can load this with */
if (u->load_state == UNIT_STUB)
SET_FOREACH(t, u->names, i) {
if (t == u->id)
continue;
r = load_from_path(u, t);
if (r < 0)
return r;
if (u->load_state != UNIT_STUB)
break;
}
/* And now, try looking for it under the suggested (originally linked) path */
if (u->load_state == UNIT_STUB && u->fragment_path) {
r = load_from_path(u, u->fragment_path);
if (r < 0)
return r;
if (u->load_state == UNIT_STUB) {
/* Hmm, this didn't work? Then let's get rid
* of the fragment path stored for us, so that
* we don't point to an invalid location. */
free(u->fragment_path);
u->fragment_path = NULL;
}
}
/* Look for a template */
if (u->load_state == UNIT_STUB && u->instance) {
char *k;
k = unit_name_template(u->id);
if (!k)
return -ENOMEM;
r = load_from_path(u, k);
free(k);
if (r < 0)
return r;
if (u->load_state == UNIT_STUB)
SET_FOREACH(t, u->names, i) {
if (t == u->id)
continue;
k = unit_name_template(t);
if (!k)
return -ENOMEM;
r = load_from_path(u, k);
free(k);
if (r < 0)
return r;
if (u->load_state != UNIT_STUB)
break;
}
}
return 0;
}
void unit_dump_config_items(FILE *f) {
static const struct {
const ConfigParserCallback callback;
const char *rvalue;
} table[] = {
{ config_parse_int, "INTEGER" },
{ config_parse_unsigned, "UNSIGNED" },
{ config_parse_bytes_size, "SIZE" },
{ config_parse_bool, "BOOLEAN" },
{ config_parse_string, "STRING" },
{ config_parse_path, "PATH" },
{ config_parse_unit_path_printf, "PATH" },
{ config_parse_strv, "STRING [...]" },
{ config_parse_exec_nice, "NICE" },
{ config_parse_exec_oom_score_adjust, "OOMSCOREADJUST" },
{ config_parse_exec_io_class, "IOCLASS" },
{ config_parse_exec_io_priority, "IOPRIORITY" },
{ config_parse_exec_cpu_sched_policy, "CPUSCHEDPOLICY" },
{ config_parse_exec_cpu_sched_prio, "CPUSCHEDPRIO" },
{ config_parse_exec_cpu_affinity, "CPUAFFINITY" },
{ config_parse_mode, "MODE" },
{ config_parse_unit_env_file, "FILE" },
{ config_parse_output, "OUTPUT" },
{ config_parse_input, "INPUT" },
{ config_parse_facility, "FACILITY" },
{ config_parse_level, "LEVEL" },
{ config_parse_exec_capabilities, "CAPABILITIES" },
{ config_parse_exec_secure_bits, "SECUREBITS" },
{ config_parse_bounding_set, "BOUNDINGSET" },
{ config_parse_limit, "LIMIT" },
{ config_parse_unit_deps, "UNIT [...]" },
{ config_parse_exec, "PATH [ARGUMENT [...]]" },
{ config_parse_service_type, "SERVICETYPE" },
{ config_parse_service_restart, "SERVICERESTART" },
#ifdef HAVE_SYSV_COMPAT
{ config_parse_sysv_priority, "SYSVPRIORITY" },
#else
{ config_parse_warn_compat, "NOTSUPPORTED" },
#endif
{ config_parse_kill_mode, "KILLMODE" },
{ config_parse_kill_signal, "SIGNAL" },
{ config_parse_socket_listen, "SOCKET [...]" },
{ config_parse_socket_bind, "SOCKETBIND" },
{ config_parse_socket_bindtodevice, "NETWORKINTERFACE" },
{ config_parse_sec, "SECONDS" },
{ config_parse_nsec, "NANOSECONDS" },
{ config_parse_path_strv, "PATH [...]" },
{ config_parse_unit_requires_mounts_for, "PATH [...]" },
{ config_parse_exec_mount_flags, "MOUNTFLAG [...]" },
{ config_parse_unit_string_printf, "STRING" },
{ config_parse_trigger_unit, "UNIT" },
{ config_parse_timer, "TIMER" },
{ config_parse_path_spec, "PATH" },
{ config_parse_notify_access, "ACCESS" },
{ config_parse_ip_tos, "TOS" },
{ config_parse_unit_condition_path, "CONDITION" },
{ config_parse_unit_condition_string, "CONDITION" },
{ config_parse_unit_condition_null, "CONDITION" },
{ config_parse_unit_slice, "SLICE" },
{ config_parse_documentation, "URL" },
{ config_parse_service_timeout, "SECONDS" },
{ config_parse_start_limit_action, "ACTION" },
{ config_parse_set_status, "STATUS" },
{ config_parse_service_sockets, "SOCKETS" },
{ config_parse_fsck_passno, "PASSNO" },
{ config_parse_environ, "ENVIRON" },
{ config_parse_syscall_filter, "SYSCALL" },
{ config_parse_cpu_shares, "SHARES" },
{ config_parse_memory_limit, "LIMIT" },
{ config_parse_device_allow, "DEVICE" },
{ config_parse_device_policy, "POLICY" },
{ config_parse_blockio_bandwidth, "BANDWIDTH" },
{ config_parse_blockio_weight, "WEIGHT" },
{ config_parse_blockio_device_weight, "DEVICEWEIGHT" },
{ config_parse_long, "LONG" },
{ config_parse_socket_service, "SERVICE" },
};
const char *prev = NULL;
const char *i;
assert(f);
NULSTR_FOREACH(i, load_fragment_gperf_nulstr) {
const char *rvalue = "OTHER", *lvalue;
unsigned j;
size_t prefix_len;
const char *dot;
const ConfigPerfItem *p;
assert_se(p = load_fragment_gperf_lookup(i, strlen(i)));
dot = strchr(i, '.');
lvalue = dot ? dot + 1 : i;
prefix_len = dot-i;
if (dot)
if (!prev || !strneq(prev, i, prefix_len+1)) {
if (prev)
fputc('\n', f);
fprintf(f, "[%.*s]\n", (int) prefix_len, i);
}
for (j = 0; j < ELEMENTSOF(table); j++)
if (p->parse == table[j].callback) {
rvalue = table[j].rvalue;
break;
}
fprintf(f, "%s=%s\n", lvalue, rvalue);
prev = i;
}
}