#endif
#include "securebits-util.h"
#include "signal-util.h"
+#include "socket-netlink.h"
#include "stat-util.h"
#include "string-util.h"
#include "strv.h"
+#include "syslog-util.h"
+#include "time-util.h"
#include "unit-name.h"
#include "unit-printf.h"
#include "user-util.h"
-#include "time-util.h"
#include "web-util.h"
static int parse_socket_protocol(const char *s) {
return 0;
}
+int config_parse_exec_coredump_filter(
+ const char* unit,
+ const char *filename,
+ unsigned line,
+ const char *section,
+ unsigned section_line,
+ const char *lvalue,
+ int ltype,
+ const char *rvalue,
+ void *data,
+ void *userdata) {
+
+ ExecContext *c = data;
+ int r;
+
+ assert(filename);
+ assert(lvalue);
+ assert(rvalue);
+ assert(data);
+
+ if (isempty(rvalue)) {
+ c->coredump_filter = 0;
+ c->coredump_filter_set = false;
+ return 0;
+ }
+
+ uint64_t f;
+ r = coredump_filter_mask_from_string(rvalue, &f);
+ if (r < 0) {
+ log_syntax(unit, LOG_WARNING, filename, line, r,
+ "Failed to parse the CoredumpFilter=%s, ignoring: %m", rvalue);
+ return 0;
+ }
+
+ c->coredump_filter |= f;
+ c->oom_score_adjust_set = true;
+ return 0;
+}
+
int config_parse_exec(
const char *unit,
const char *filename,
assert(e);
e += ltype;
- rvalue += strspn(rvalue, WHITESPACE);
if (isempty(rvalue)) {
/* An empty assignment resets the list */
void *userdata) {
ExecContext *c = data;
+ int r;
assert(filename);
assert(lvalue);
assert(rvalue);
assert(data);
- return parse_cpu_set_extend(rvalue, &c->cpu_set, true, unit, filename, line, lvalue);
+ if (streq(rvalue, "numa")) {
+ c->cpu_affinity_from_numa = true;
+ cpu_set_reset(&c->cpu_set);
+
+ return 0;
+ }
+
+ r = parse_cpu_set_extend(rvalue, &c->cpu_set, true, unit, filename, line, lvalue);
+ if (r >= 0)
+ c->cpu_affinity_from_numa = false;
+
+ return r;
}
int config_parse_capability_set(
return 0;
}
-int config_parse_service_timeout_abort(
+int config_parse_timeout_abort(
const char *unit,
const char *filename,
unsigned line,
void *data,
void *userdata) {
- Service *s = userdata;
+ usec_t *ret = data;
int r;
assert(filename);
assert(lvalue);
assert(rvalue);
- assert(s);
+ assert(ret);
+
+ /* Note: apart from setting the arg, this returns an extra bit of information in the return value. */
- rvalue += strspn(rvalue, WHITESPACE);
if (isempty(rvalue)) {
- s->timeout_abort_set = false;
- return 0;
+ *ret = 0;
+ return 0; /* "not set" */
}
- r = parse_sec(rvalue, &s->timeout_abort_usec);
- if (r < 0) {
- log_syntax(unit, LOG_ERR, filename, line, r, "Failed to parse TimeoutAbortSec= setting, ignoring: %s", rvalue);
- return 0;
- }
+ r = parse_sec(rvalue, ret);
+ if (r < 0)
+ return log_syntax(unit, LOG_ERR, filename, line, r, "Failed to parse %s= setting, ignoring: %s", lvalue, rvalue);
+
+ return 1; /* "set" */
+}
+
+int config_parse_service_timeout_abort(
+ const char *unit,
+ const char *filename,
+ unsigned line,
+ const char *section,
+ unsigned section_line,
+ const char *lvalue,
+ int ltype,
+ const char *rvalue,
+ void *data,
+ void *userdata) {
+
+ Service *s = userdata;
+ int r;
- s->timeout_abort_set = true;
+ assert(s);
+
+ r = config_parse_timeout_abort(unit, filename, line, section, section_line, lvalue, ltype, rvalue,
+ &s->timeout_abort_usec, s);
+ if (r >= 0)
+ s->timeout_abort_set = r;
return 0;
}
return -ENOEXEC;
}
- if (!valid_user_group_name_or_id_compat(k)) {
+ if (!valid_user_group_name(k, VALID_USER_ALLOW_NUMERIC|VALID_USER_RELAX|VALID_USER_WARN)) {
log_syntax(unit, LOG_ERR, filename, line, 0, "Invalid user/group name or numeric ID: %s", k);
return -ENOEXEC;
}
return -ENOEXEC;
}
- if (!valid_user_group_name_or_id_compat(k)) {
+ if (!valid_user_group_name(k, VALID_USER_ALLOW_NUMERIC|VALID_USER_RELAX|VALID_USER_WARN)) {
log_syntax(unit, LOG_ERR, filename, line, 0, "Invalid user/group name or numeric ID: %s", k);
return -ENOEXEC;
}
}
}
+int config_parse_log_namespace(
+ const char *unit,
+ const char *filename,
+ unsigned line,
+ const char *section,
+ unsigned section_line,
+ const char *lvalue,
+ int ltype,
+ const char *rvalue,
+ void *data,
+ void *userdata) {
+
+ _cleanup_free_ char *k = NULL;
+ ExecContext *c = data;
+ const Unit *u = userdata;
+ int r;
+
+ assert(filename);
+ assert(lvalue);
+ assert(rvalue);
+ assert(c);
+
+ if (isempty(rvalue)) {
+ c->log_namespace = mfree(c->log_namespace);
+ return 0;
+ }
+
+ r = unit_full_printf(u, rvalue, &k);
+ if (r < 0) {
+ log_syntax(unit, LOG_ERR, filename, line, r, "Failed to resolve unit specifiers in %s, ignoring: %m", rvalue);
+ return 0;
+ }
+
+ if (!log_namespace_name_valid(k)) {
+ log_syntax(unit, LOG_ERR, filename, line, SYNTHETIC_ERRNO(EINVAL), "Specified log namespace name is not valid: %s", k);
+ return 0;
+ }
+
+ free_and_replace(c->log_namespace, k);
+ return 0;
+}
+
int config_parse_unit_condition_path(
const char *unit,
const char *filename,
return 0;
}
-int config_parse_cpuset_cpus(
+int config_parse_allowed_cpus(
const char *unit,
const char *filename,
unsigned line,
return 0;
}
-int config_parse_cpuset_mems(
+int config_parse_allowed_mems(
const char *unit,
const char *filename,
unsigned line,
return r;
if (null_or_empty(&st)) {
- u->load_state = UNIT_MASKED;
+ /* Unit file is masked */
+
+ u->load_state = u->perpetual ? UNIT_LOADED : UNIT_MASKED; /* don't allow perpetual units to ever be masked */
u->fragment_mtime = 0;
} else {
u->load_state = UNIT_LOADED;
{ config_parse_unsigned, "UNSIGNED" },
{ config_parse_iec_size, "SIZE" },
{ config_parse_iec_uint64, "SIZE" },
- { config_parse_si_size, "SIZE" },
+ { config_parse_si_uint64, "SIZE" },
{ config_parse_bool, "BOOLEAN" },
{ config_parse_string, "STRING" },
{ config_parse_path, "PATH" },
return 0;
}
-int config_parse_timeout_abort(
- const char* unit,
+int config_parse_swap_priority(
+ const char *unit,
const char *filename,
unsigned line,
const char *section,
void *data,
void *userdata) {
- usec_t *timeout_usec = data;
- int r;
+ Swap *s = userdata;
+ int r, priority;
+ assert(s);
assert(filename);
assert(lvalue);
assert(rvalue);
- assert(timeout_usec);
+ assert(data);
- rvalue += strspn(rvalue, WHITESPACE);
if (isempty(rvalue)) {
- *timeout_usec = false;
+ s->parameters_fragment.priority = -1;
+ s->parameters_fragment.priority_set = false;
return 0;
}
- r = parse_sec(rvalue, timeout_usec);
+ r = safe_atoi(rvalue, &priority);
if (r < 0) {
- log_syntax(unit, LOG_ERR, filename, line, r, "Failed to parse DefaultTimeoutAbortSec= setting, ignoring: %s", rvalue);
+ log_syntax(unit, LOG_ERR, filename, line, r, "Invalid swap pririty '%s', ignoring.", rvalue);
+ return 0;
+ }
+
+ if (priority < -1) {
+ log_syntax(unit, LOG_ERR, filename, line, 0, "Sorry, swap priorities smaller than -1 may only be assigned by the kernel itself, ignoring: %s", rvalue);
+ return 0;
+ }
+
+ if (priority > 32767) {
+ log_syntax(unit, LOG_ERR, filename, line, 0, "Swap priority out of range, ignoring: %s", rvalue);
return 0;
}
- *timeout_usec = true;
+ s->parameters_fragment.priority = priority;
+ s->parameters_fragment.priority_set = true;
return 0;
}