diff --git a/man/systemd.exec.xml b/man/systemd.exec.xml index b21c5aa104..8fb9ecc6dc 100644 --- a/man/systemd.exec.xml +++ b/man/systemd.exec.xml @@ -728,7 +728,8 @@ CapabilityBoundingSet=~CAP_B CAP_C Sets the I/O scheduling class for executed processes. Takes an integer between 0 and 3 or one of the strings , , or - . See + . If the empty string is assigned to this option, all prior assignments to both + IOSchedulingClass= and IOSchedulingPriority= have no effect. See ioprio_set2 for details. @@ -738,7 +739,9 @@ CapabilityBoundingSet=~CAP_B CAP_C Sets the I/O scheduling priority for executed processes. Takes an integer between 0 (highest priority) and 7 (lowest priority). The available priorities depend on the selected I/O scheduling class (see - above). See ioprio_set2 for + above). If the empty string is assigned to this option, all prior assignments to both + IOSchedulingClass= and IOSchedulingPriority= have no effect. + See ioprio_set2 for details. diff --git a/src/basic/socket-util.c b/src/basic/socket-util.c index 95a79f7b53..508f6a26f7 100644 --- a/src/basic/socket-util.c +++ b/src/basic/socket-util.c @@ -790,7 +790,7 @@ static const char* const socket_address_bind_ipv6_only_table[_SOCKET_ADDRESS_BIN DEFINE_STRING_TABLE_LOOKUP(socket_address_bind_ipv6_only, SocketAddressBindIPv6Only); -SocketAddressBindIPv6Only parse_socket_address_bind_ipv6_only_or_bool(const char *n) { +SocketAddressBindIPv6Only socket_address_bind_ipv6_only_or_bool_from_string(const char *n) { int r; r = parse_boolean(n); diff --git a/src/basic/socket-util.h b/src/basic/socket-util.h index c2b6107f49..9cd7f9ec54 100644 --- a/src/basic/socket-util.h +++ b/src/basic/socket-util.h @@ -116,7 +116,7 @@ int socknameinfo_pretty(union sockaddr_union *sa, socklen_t salen, char **_ret); const char* socket_address_bind_ipv6_only_to_string(SocketAddressBindIPv6Only b) _const_; SocketAddressBindIPv6Only socket_address_bind_ipv6_only_from_string(const char *s) _pure_; -SocketAddressBindIPv6Only parse_socket_address_bind_ipv6_only_or_bool(const char *s); +SocketAddressBindIPv6Only socket_address_bind_ipv6_only_or_bool_from_string(const char *s); int netlink_family_to_string_alloc(int b, char **s); int netlink_family_from_string(const char *s) _pure_; diff --git a/src/core/dbus-execute.c b/src/core/dbus-execute.c index 977ef22c94..ec1b62fb42 100644 --- a/src/core/dbus-execute.c +++ b/src/core/dbus-execute.c @@ -1024,8 +1024,8 @@ static BUS_DEFINE_SET_TRANSIENT_IS_VALID(nice, "i", int32_t, int, "%" PRIi32, ni static BUS_DEFINE_SET_TRANSIENT_PARSE(std_input, ExecInput, exec_input_from_string); static BUS_DEFINE_SET_TRANSIENT_PARSE(std_output, ExecOutput, exec_output_from_string); static BUS_DEFINE_SET_TRANSIENT_PARSE(utmp_mode, ExecUtmpMode, exec_utmp_mode_from_string); -static BUS_DEFINE_SET_TRANSIENT_PARSE(protect_system, ProtectSystem, parse_protect_system_or_bool); -static BUS_DEFINE_SET_TRANSIENT_PARSE(protect_home, ProtectHome, parse_protect_home_or_bool); +static BUS_DEFINE_SET_TRANSIENT_PARSE(protect_system, ProtectSystem, protect_system_or_bool_from_string); +static BUS_DEFINE_SET_TRANSIENT_PARSE(protect_home, ProtectHome, protect_home_or_bool_from_string); static BUS_DEFINE_SET_TRANSIENT_PARSE(keyring_mode, ExecKeyringMode, exec_keyring_mode_from_string); static BUS_DEFINE_SET_TRANSIENT_PARSE(preserve_mode, ExecPreserveMode, exec_preserve_mode_from_string); static BUS_DEFINE_SET_TRANSIENT_PARSE_PTR(personality, unsigned long, parse_personality); diff --git a/src/core/dbus-socket.c b/src/core/dbus-socket.c index 893e3d3839..88e180a037 100644 --- a/src/core/dbus-socket.c +++ b/src/core/dbus-socket.c @@ -142,7 +142,10 @@ static inline bool check_size_t_truncation(uint64_t t) { return (size_t) t == t; } -static inline const char* socket_protocol_to_name_supported(int32_t i) { +static inline const char* supported_socket_protocol_to_string(int32_t i) { + if (i == IPPROTO_IP) + return ""; + if (!IN_SET(i, IPPROTO_UDPLITE, IPPROTO_SCTP)) return NULL; @@ -152,11 +155,11 @@ static inline const char* socket_protocol_to_name_supported(int32_t i) { static BUS_DEFINE_SET_TRANSIENT(int, "i", int32_t, int, "%" PRIi32); static BUS_DEFINE_SET_TRANSIENT(message_queue, "x", int64_t, long, "%" PRIi64); static BUS_DEFINE_SET_TRANSIENT_IS_VALID(size_t_check_truncation, "t", uint64_t, size_t, "%" PRIu64, check_size_t_truncation); -static BUS_DEFINE_SET_TRANSIENT_PARSE(bind_ipv6_only, SocketAddressBindIPv6Only, parse_socket_address_bind_ipv6_only_or_bool); +static BUS_DEFINE_SET_TRANSIENT_PARSE(bind_ipv6_only, SocketAddressBindIPv6Only, socket_address_bind_ipv6_only_or_bool_from_string); static BUS_DEFINE_SET_TRANSIENT_STRING_WITH_CHECK(fdname, fdname_is_valid); static BUS_DEFINE_SET_TRANSIENT_STRING_WITH_CHECK(ifname, ifname_valid); static BUS_DEFINE_SET_TRANSIENT_TO_STRING_ALLOC(ip_tos, "i", int32_t, int, "%" PRIi32, ip_tos_to_string_alloc); -static BUS_DEFINE_SET_TRANSIENT_TO_STRING(socket_protocol, "i", int32_t, int, "%" PRIi32, socket_protocol_to_name_supported); +static BUS_DEFINE_SET_TRANSIENT_TO_STRING(socket_protocol, "i", int32_t, int, "%" PRIi32, supported_socket_protocol_to_string); static int bus_socket_set_transient_property( Socket *s, diff --git a/src/core/load-fragment-gperf.gperf.m4 b/src/core/load-fragment-gperf.gperf.m4 index 3757a651b2..44c9978c54 100644 --- a/src/core/load-fragment-gperf.gperf.m4 +++ b/src/core/load-fragment-gperf.gperf.m4 @@ -59,11 +59,11 @@ $1.SyslogLevelPrefix, config_parse_bool, 0, $1.LogLevelMax, config_parse_log_level, 0, offsetof($1, exec_context.log_level_max) $1.LogExtraFields, config_parse_log_extra_fields, 0, offsetof($1, exec_context) $1.Capabilities, config_parse_warn_compat, DISABLED_LEGACY, offsetof($1, exec_context) -$1.SecureBits, config_parse_exec_secure_bits, 0, offsetof($1, exec_context) +$1.SecureBits, config_parse_exec_secure_bits, 0, offsetof($1, exec_context.secure_bits) $1.CapabilityBoundingSet, config_parse_capability_set, 0, offsetof($1, exec_context.capability_bounding_set) $1.AmbientCapabilities, config_parse_capability_set, 0, offsetof($1, exec_context.capability_ambient_set) $1.TimerSlackNSec, config_parse_nsec, 0, offsetof($1, exec_context.timer_slack_nsec) -$1.NoNewPrivileges, config_parse_no_new_privileges, 0, offsetof($1, exec_context) +$1.NoNewPrivileges, config_parse_bool, 0, offsetof($1, exec_context.no_new_privileges) $1.KeyringMode, config_parse_exec_keyring_mode, 0, offsetof($1, exec_context.keyring_mode) m4_ifdef(`HAVE_SECCOMP', `$1.SystemCallFilter, config_parse_syscall_filter, 0, offsetof($1, exec_context) @@ -114,9 +114,9 @@ $1.ProtectKernelModules, config_parse_bool, 0, $1.ProtectControlGroups, config_parse_bool, 0, offsetof($1, exec_context.protect_control_groups) $1.PrivateNetwork, config_parse_bool, 0, offsetof($1, exec_context.private_network) $1.PrivateUsers, config_parse_bool, 0, offsetof($1, exec_context.private_users) -$1.ProtectSystem, config_parse_protect_system, 0, offsetof($1, exec_context) -$1.ProtectHome, config_parse_protect_home, 0, offsetof($1, exec_context) -$1.MountFlags, config_parse_exec_mount_flags, 0, offsetof($1, exec_context) +$1.ProtectSystem, config_parse_protect_system, 0, offsetof($1, exec_context.protect_system) +$1.ProtectHome, config_parse_protect_home, 0, offsetof($1, exec_context.protect_home) +$1.MountFlags, config_parse_exec_mount_flags, 0, offsetof($1, exec_context.mount_flags) $1.MountAPIVFS, config_parse_bool, 0, offsetof($1, exec_context.mount_apivfs) $1.Personality, config_parse_personality, 0, offsetof($1, exec_context.personality) $1.RuntimeDirectoryPreserve, config_parse_runtime_preserve_mode, 0, offsetof($1, exec_context.runtime_directory_preserve_mode) @@ -155,8 +155,8 @@ $1.KillSignal, config_parse_signal, 0, m4_define(`CGROUP_CONTEXT_CONFIG_ITEMS', `$1.Slice, config_parse_unit_slice, 0, 0 $1.CPUAccounting, config_parse_bool, 0, offsetof($1, cgroup_context.cpu_accounting) -$1.CPUWeight, config_parse_cpu_weight, 0, offsetof($1, cgroup_context.cpu_weight) -$1.StartupCPUWeight, config_parse_cpu_weight, 0, offsetof($1, cgroup_context.startup_cpu_weight) +$1.CPUWeight, config_parse_cg_weight, 0, offsetof($1, cgroup_context.cpu_weight) +$1.StartupCPUWeight, config_parse_cg_weight, 0, offsetof($1, cgroup_context.startup_cpu_weight) $1.CPUShares, config_parse_cpu_shares, 0, offsetof($1, cgroup_context.cpu_shares) $1.StartupCPUShares, config_parse_cpu_shares, 0, offsetof($1, cgroup_context.startup_cpu_shares) $1.CPUQuota, config_parse_cpu_quota, 0, offsetof($1, cgroup_context) @@ -169,8 +169,8 @@ $1.MemoryLimit, config_parse_memory_limit, 0, $1.DeviceAllow, config_parse_device_allow, 0, offsetof($1, cgroup_context) $1.DevicePolicy, config_parse_device_policy, 0, offsetof($1, cgroup_context.device_policy) $1.IOAccounting, config_parse_bool, 0, offsetof($1, cgroup_context.io_accounting) -$1.IOWeight, config_parse_io_weight, 0, offsetof($1, cgroup_context.io_weight) -$1.StartupIOWeight, config_parse_io_weight, 0, offsetof($1, cgroup_context.startup_io_weight) +$1.IOWeight, config_parse_cg_weight, 0, offsetof($1, cgroup_context.io_weight) +$1.StartupIOWeight, config_parse_cg_weight, 0, offsetof($1, cgroup_context.startup_io_weight) $1.IODeviceWeight, config_parse_io_device_weight, 0, offsetof($1, cgroup_context) $1.IOReadBandwidthMax, config_parse_io_limit, 0, offsetof($1, cgroup_context) $1.IOWriteBandwidthMax, config_parse_io_limit, 0, offsetof($1, cgroup_context) @@ -291,7 +291,7 @@ Service.ExecStopPost, config_parse_exec, SERVICE_EXE Service.RestartSec, config_parse_sec, 0, offsetof(Service, restart_usec) Service.TimeoutSec, config_parse_service_timeout, 0, 0 Service.TimeoutStartSec, config_parse_service_timeout, 0, 0 -Service.TimeoutStopSec, config_parse_service_timeout, 0, 0 +Service.TimeoutStopSec, config_parse_sec_fix_0, 0, offsetof(Service, timeout_stop_usec) Service.RuntimeMaxSec, config_parse_sec, 0, offsetof(Service, runtime_max_usec) Service.WatchdogSec, config_parse_sec, 0, offsetof(Service, watchdog_usec) m4_dnl The following five only exist for compatibility, they moved into Unit, see above @@ -330,8 +330,8 @@ Socket.ListenNetlink, config_parse_socket_listen, SOCKET_SOCK Socket.ListenSpecial, config_parse_socket_listen, SOCKET_SPECIAL, 0 Socket.ListenMessageQueue, config_parse_socket_listen, SOCKET_MQUEUE, 0 Socket.ListenUSBFunction, config_parse_socket_listen, SOCKET_USB_FUNCTION, 0 -Socket.SocketProtocol, config_parse_socket_protocol, 0, 0 -Socket.BindIPv6Only, config_parse_socket_bind, 0, 0, +Socket.SocketProtocol, config_parse_socket_protocol, 0, offsetof(Socket, socket_protocol) +Socket.BindIPv6Only, config_parse_socket_bind, 0, offsetof(Socket, bind_ipv6_only) Socket.Backlog, config_parse_unsigned, 0, offsetof(Socket, backlog) Socket.BindToDevice, config_parse_socket_bindtodevice, 0, 0 Socket.ExecStartPre, config_parse_exec, SOCKET_EXEC_START_PRE, offsetof(Socket, exec_command) diff --git a/src/core/load-fragment.c b/src/core/load-fragment.c index f16b0d182b..dd4c755894 100644 --- a/src/core/load-fragment.c +++ b/src/core/load-fragment.c @@ -61,7 +61,42 @@ #include "utf8.h" #include "web-util.h" +static int supported_socket_protocol_from_string(const char *s) { + int r; + + if (isempty(s)) + return IPPROTO_IP; + + r = socket_protocol_from_name(s); + if (r < 0) + return -EINVAL; + if (!IN_SET(r, IPPROTO_UDPLITE, IPPROTO_SCTP)) + return -EPROTONOSUPPORT; + + return r; +} + +DEFINE_CONFIG_PARSE(config_parse_socket_protocol, supported_socket_protocol_from_string, "Failed to parse socket protocol"); +DEFINE_CONFIG_PARSE(config_parse_exec_secure_bits, secure_bits_from_string, "Failed to parse secure bits"); DEFINE_CONFIG_PARSE_ENUM(config_parse_collect_mode, collect_mode, CollectMode, "Failed to parse garbage collection mode"); +DEFINE_CONFIG_PARSE_ENUM(config_parse_device_policy, cgroup_device_policy, CGroupDevicePolicy, "Failed to parse device policy"); +DEFINE_CONFIG_PARSE_ENUM(config_parse_emergency_action, emergency_action, EmergencyAction, "Failed to parse failure action specifier"); +DEFINE_CONFIG_PARSE_ENUM(config_parse_exec_keyring_mode, exec_keyring_mode, ExecKeyringMode, "Failed to parse keyring mode"); +DEFINE_CONFIG_PARSE_ENUM(config_parse_exec_utmp_mode, exec_utmp_mode, ExecUtmpMode, "Failed to parse utmp mode"); +DEFINE_CONFIG_PARSE_ENUM(config_parse_job_mode, job_mode, JobMode, "Failed to parse job mode"); +DEFINE_CONFIG_PARSE_ENUM(config_parse_kill_mode, kill_mode, KillMode, "Failed to parse kill mode"); +DEFINE_CONFIG_PARSE_ENUM(config_parse_notify_access, notify_access, NotifyAccess, "Failed to parse notify access specifier"); +DEFINE_CONFIG_PARSE_ENUM(config_parse_protect_home, protect_home_or_bool, ProtectHome, "Failed to parse protect home value"); +DEFINE_CONFIG_PARSE_ENUM(config_parse_protect_system, protect_system_or_bool, ProtectSystem, "Failed to parse protect system value"); +DEFINE_CONFIG_PARSE_ENUM(config_parse_runtime_preserve_mode, exec_preserve_mode, ExecPreserveMode, "Failed to parse runtime directory preserve mode"); +DEFINE_CONFIG_PARSE_ENUM(config_parse_service_type, service_type, ServiceType, "Failed to parse service type"); +DEFINE_CONFIG_PARSE_ENUM(config_parse_service_restart, service_restart, ServiceRestart, "Failed to parse service restart specifier"); +DEFINE_CONFIG_PARSE_ENUM(config_parse_socket_bind, socket_address_bind_ipv6_only_or_bool, SocketAddressBindIPv6Only, "Failed to parse bind IPv6 only value"); +DEFINE_CONFIG_PARSE_ENUM_WITH_DEFAULT(config_parse_ip_tos, ip_tos, int, -1, "Failed to parse IP TOS value"); +DEFINE_CONFIG_PARSE_PTR(config_parse_blockio_weight, cg_blkio_weight_parse, uint64_t, "Invalid block IO weight"); +DEFINE_CONFIG_PARSE_PTR(config_parse_cg_weight, cg_weight_parse, uint64_t, "Invalid weight"); +DEFINE_CONFIG_PARSE_PTR(config_parse_cpu_shares, cg_cpu_shares_parse, uint64_t, "Invalid CPU shares"); +DEFINE_CONFIG_PARSE_PTR(config_parse_exec_mount_flags, mount_propagation_flags_from_string, unsigned long, "Failed to parse mount flag"); int config_parse_unit_deps( const char *unit, @@ -404,72 +439,6 @@ int config_parse_socket_listen(const char *unit, return 0; } -int config_parse_socket_protocol(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) { - Socket *s; - int r; - - assert(filename); - assert(lvalue); - assert(rvalue); - assert(data); - - s = SOCKET(data); - - r = socket_protocol_from_name(rvalue); - if (r < 0) { - log_syntax(unit, LOG_ERR, filename, line, r, "Invalid socket protocol '%s', ignoring: %m", rvalue); - return 0; - } else if (!IN_SET(r, IPPROTO_UDPLITE, IPPROTO_SCTP)) { - log_syntax(unit, LOG_ERR, filename, line, 0, "Socket protocol not supported, ignoring: %s", rvalue); - return 0; - } - - s->socket_protocol = r; - - return 0; -} - -int config_parse_socket_bind(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) { - - Socket *s; - SocketAddressBindIPv6Only b; - - assert(filename); - assert(lvalue); - assert(rvalue); - assert(data); - - s = SOCKET(data); - - b = parse_socket_address_bind_ipv6_only_or_bool(rvalue); - if (b < 0) { - log_syntax(unit, LOG_ERR, filename, line, 0, "Failed to parse bind IPv6 only value, ignoring: %s", rvalue); - return 0; - } - - s->bind_ipv6_only = b; - - return 0; -} - int config_parse_exec_nice( const char *unit, const char *filename, @@ -490,6 +459,11 @@ int config_parse_exec_nice( assert(rvalue); assert(data); + if (isempty(rvalue)) { + c->nice_set = false; + return 0; + } + r = parse_nice(rvalue, &priority); if (r < 0) { if (r == -ERANGE) @@ -779,9 +753,6 @@ int config_parse_exec( return 0; } -DEFINE_CONFIG_PARSE_ENUM(config_parse_service_type, service_type, ServiceType, "Failed to parse service type"); -DEFINE_CONFIG_PARSE_ENUM(config_parse_service_restart, service_restart, ServiceRestart, "Failed to parse service restart specifier"); - int config_parse_socket_bindtodevice( const char* unit, const char *filename, @@ -1111,6 +1082,12 @@ int config_parse_exec_io_class(const char *unit, assert(rvalue); assert(data); + if (isempty(rvalue)) { + c->ioprio_set = false; + c->ioprio = IOPRIO_PRIO_VALUE(IOPRIO_CLASS_BE, 0); + return 0; + } + x = ioprio_class_from_string(rvalue); if (x < 0) { log_syntax(unit, LOG_ERR, filename, line, 0, "Failed to parse IO scheduling class, ignoring: %s", rvalue); @@ -1142,6 +1119,12 @@ int config_parse_exec_io_priority(const char *unit, assert(rvalue); assert(data); + if (isempty(rvalue)) { + c->ioprio_set = false; + c->ioprio = IOPRIO_PRIO_VALUE(IOPRIO_CLASS_BE, 0); + return 0; + } + r = ioprio_parse_priority(rvalue, &i); if (r < 0) { log_syntax(unit, LOG_ERR, filename, line, r, "Failed to parse IO priority, ignoring: %s", rvalue); @@ -1173,6 +1156,13 @@ int config_parse_exec_cpu_sched_policy(const char *unit, assert(rvalue); assert(data); + if (isempty(rvalue)) { + c->cpu_sched_set = false; + c->cpu_sched_policy = SCHED_OTHER; + c->cpu_sched_priority = 0; + return 0; + } + x = sched_policy_from_string(rvalue); if (x < 0) { log_syntax(unit, LOG_ERR, filename, line, 0, "Failed to parse CPU scheduling policy, ignoring: %s", rvalue); @@ -1277,43 +1267,6 @@ int config_parse_exec_cpu_affinity(const char *unit, return 0; } -int config_parse_exec_secure_bits(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)) { - /* An empty assignment resets the field */ - c->secure_bits = 0; - return 0; - } - - r = secure_bits_from_string(rvalue); - if (r < 0) { - log_syntax(unit, LOG_WARNING, filename, line, r, - "Failed to parse secure bits, ignoring: %s", rvalue); - return 0; - } - - c->secure_bits = r; - - return 0; -} - int config_parse_capability_set( const char *unit, const char *filename, @@ -1365,71 +1318,6 @@ int config_parse_capability_set( return 0; } -#if HAVE_SYSV_COMPAT -int config_parse_sysv_priority(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) { - - int *priority = data; - int i, r; - - assert(filename); - assert(lvalue); - assert(rvalue); - assert(data); - - r = safe_atoi(rvalue, &i); - if (r < 0) { - log_syntax(unit, LOG_ERR, filename, line, r, "Failed to parse SysV start priority, ignoring: %s", rvalue); - return 0; - } - if (i < 0) { - log_syntax(unit, LOG_ERR, filename, line, 0, "Invalid SysV start priority, ignoring: %s", rvalue); - return 0; - } - - *priority = (int) i; - return 0; -} -#endif - -DEFINE_CONFIG_PARSE_ENUM(config_parse_exec_utmp_mode, exec_utmp_mode, ExecUtmpMode, "Failed to parse utmp mode"); -DEFINE_CONFIG_PARSE_ENUM(config_parse_kill_mode, kill_mode, KillMode, "Failed to parse kill mode"); - -int config_parse_exec_mount_flags( - 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); - - r = mount_propagation_flags_from_string(rvalue, &c->mount_flags); - if (r < 0) - log_syntax(unit, LOG_ERR, filename, line, r, "Failed to parse mount flag %s, ignoring: %m", rvalue); - - return 0; -} - int config_parse_exec_selinux_context( const char *unit, const char *filename, @@ -1956,26 +1844,21 @@ int config_parse_service_timeout( assert(rvalue); assert(s); - /* This is called for three cases: TimeoutSec=, TimeoutStopSec= and TimeoutStartSec=. */ + /* This is called for two cases: TimeoutSec= and TimeoutStartSec=. */ - r = parse_sec(rvalue, &usec); + /* Traditionally, these options accepted 0 to disable the timeouts. However, a timeout of 0 suggests it happens + * immediately, hence fix this to become USEC_INFINITY instead. This is in-line with how we internally handle + * all other timeouts. */ + r = parse_sec_fix_0(rvalue, &usec); if (r < 0) { log_syntax(unit, LOG_ERR, filename, line, r, "Failed to parse %s= parameter, ignoring: %s", lvalue, rvalue); return 0; } - /* Traditionally, these options accepted 0 to disable the timeouts. However, a timeout of 0 suggests it happens - * immediately, hence fix this to become USEC_INFINITY instead. This is in-line with how we internally handle - * all other timeouts. */ - if (usec <= 0) - usec = USEC_INFINITY; + s->start_timeout_defined = true; + s->timeout_start_usec = usec; - if (!streq(lvalue, "TimeoutStopSec")) { - s->start_timeout_defined = true; - s->timeout_start_usec = usec; - } - - if (!streq(lvalue, "TimeoutStartSec")) + if (streq(lvalue, "TimeoutSec")) s->timeout_stop_usec = usec; return 0; @@ -2139,6 +2022,12 @@ int config_parse_working_directory( assert(c); assert(u); + if (isempty(rvalue)) { + c->working_directory_home = false; + c->working_directory = mfree(c->working_directory); + return 0; + } + if (rvalue[0] == '-') { missing_ok = true; rvalue++; @@ -2514,34 +2403,6 @@ int config_parse_log_extra_fields( } } -int config_parse_ip_tos(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) { - - 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, 0, "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, @@ -2703,9 +2564,6 @@ int config_parse_unit_condition_null( 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_emergency_action, emergency_action, EmergencyAction, "Failed to parse failure action specifier"); - int config_parse_unit_requires_mounts_for( const char *unit, const char *filename, @@ -3152,64 +3010,6 @@ int config_parse_unit_slice( return 0; } -DEFINE_CONFIG_PARSE_ENUM(config_parse_device_policy, cgroup_device_policy, CGroupDevicePolicy, "Failed to parse device policy"); - -int config_parse_cpu_weight( - 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) { - - uint64_t *weight = data; - int r; - - assert(filename); - assert(lvalue); - assert(rvalue); - - r = cg_weight_parse(rvalue, weight); - if (r < 0) { - log_syntax(unit, LOG_ERR, filename, line, r, "Invalid CPU weight '%s', ignoring: %m", rvalue); - return 0; - } - - return 0; -} - -int config_parse_cpu_shares( - 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) { - - uint64_t *shares = data; - int r; - - assert(filename); - assert(lvalue); - assert(rvalue); - - r = cg_cpu_shares_parse(rvalue, shares); - if (r < 0) { - log_syntax(unit, LOG_ERR, filename, line, r, "Invalid CPU shares '%s', ignoring: %m", rvalue); - return 0; - } - - return 0; -} - int config_parse_cpu_quota( const char *unit, const char *filename, @@ -3487,34 +3287,6 @@ int config_parse_device_allow( return 0; } -int config_parse_io_weight( - 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) { - - uint64_t *weight = data; - int r; - - assert(filename); - assert(lvalue); - assert(rvalue); - - r = cg_weight_parse(rvalue, weight); - if (r < 0) { - log_syntax(unit, LOG_ERR, filename, line, r, "Invalid IO weight '%s', ignoring.", rvalue); - return 0; - } - - return 0; -} - int config_parse_io_device_weight( const char *unit, const char *filename, @@ -3687,34 +3459,6 @@ int config_parse_io_limit( return 0; } -int config_parse_blockio_weight( - 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) { - - uint64_t *weight = data; - int r; - - assert(filename); - assert(lvalue); - assert(rvalue); - - r = cg_blkio_weight_parse(rvalue, weight); - if (r < 0) { - log_syntax(unit, LOG_ERR, filename, line, r, "Invalid block IO weight '%s', ignoring: %m", rvalue); - return 0; - } - - return 0; -} - int config_parse_blockio_device_weight( const char *unit, const char *filename, @@ -3885,8 +3629,6 @@ int config_parse_blockio_bandwidth( return 0; } -DEFINE_CONFIG_PARSE_ENUM(config_parse_job_mode, job_mode, JobMode, "Failed to parse job mode"); - int config_parse_job_mode_isolate( const char *unit, const char *filename, @@ -3918,8 +3660,6 @@ int config_parse_job_mode_isolate( return 0; } -DEFINE_CONFIG_PARSE_ENUM(config_parse_runtime_preserve_mode, exec_preserve_mode, ExecPreserveMode, "Failed to parse runtime directory preserve mode"); - int config_parse_exec_directories( const char *unit, const char *filename, @@ -4369,104 +4109,6 @@ int config_parse_bind_paths( return 0; } -int config_parse_no_new_privileges( - 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); - - r = parse_boolean(rvalue); - if (r < 0) { - log_syntax(unit, LOG_ERR, filename, line, r, "Failed to parse boolean value, ignoring: %s", rvalue); - return 0; - } - - c->no_new_privileges = r; - - return 0; -} - -int config_parse_protect_home( - 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; - ProtectHome h; - - assert(filename); - assert(lvalue); - assert(rvalue); - assert(data); - - /* Our enum shall be a superset of booleans, hence first try - * to parse as boolean, and then as enum */ - - h = parse_protect_home_or_bool(rvalue); - if (h < 0) { - log_syntax(unit, LOG_ERR, filename, line, 0, "Failed to parse protect home value, ignoring: %s", rvalue); - return 0; - } - - c->protect_home = h; - - return 0; -} - -int config_parse_protect_system( - 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; - ProtectSystem s; - - assert(filename); - assert(lvalue); - assert(rvalue); - assert(data); - - s = parse_protect_system_or_bool(rvalue); - if (s < 0) { - log_syntax(unit, LOG_ERR, filename, line, 0, "Failed to parse protect system value, ignoring: %s", rvalue); - return 0; - } - - c->protect_system = s; - - return 0; -} - -DEFINE_CONFIG_PARSE_ENUM(config_parse_exec_keyring_mode, exec_keyring_mode, ExecKeyringMode, "Failed to parse keyring mode"); - int config_parse_job_timeout_sec( const char* unit, const char *filename, @@ -4875,9 +4517,7 @@ void unit_dump_config_items(FILE *f) { const ConfigParserCallback callback; const char *rvalue; } table[] = { -#if !HAVE_SYSV_COMPAT || !HAVE_SECCOMP || !HAVE_PAM || !HAVE_SELINUX || !ENABLE_SMACK || !HAVE_APPARMOR { config_parse_warn_compat, "NOTSUPPORTED" }, -#endif { config_parse_int, "INTEGER" }, { config_parse_unsigned, "UNSIGNED" }, { config_parse_iec_size, "SIZE" }, @@ -4908,9 +4548,6 @@ void unit_dump_config_items(FILE *f) { { config_parse_exec, "PATH [ARGUMENT [...]]" }, { config_parse_service_type, "SERVICETYPE" }, { config_parse_service_restart, "SERVICERESTART" }, -#if HAVE_SYSV_COMPAT - { config_parse_sysv_priority, "SYSVPRIORITY" }, -#endif { config_parse_kill_mode, "KILLMODE" }, { config_parse_signal, "SIGNAL" }, { config_parse_socket_listen, "SOCKET [...]" }, @@ -4946,12 +4583,11 @@ void unit_dump_config_items(FILE *f) { { config_parse_restrict_namespaces, "NAMESPACES" }, #endif { config_parse_cpu_shares, "SHARES" }, - { config_parse_cpu_weight, "WEIGHT" }, + { config_parse_cg_weight, "WEIGHT" }, { config_parse_memory_limit, "LIMIT" }, { config_parse_device_allow, "DEVICE" }, { config_parse_device_policy, "POLICY" }, { config_parse_io_limit, "LIMIT" }, - { config_parse_io_weight, "WEIGHT" }, { config_parse_io_device_weight, "DEVICEWEIGHT" }, { config_parse_blockio_bandwidth, "BANDWIDTH" }, { config_parse_blockio_weight, "WEIGHT" }, diff --git a/src/core/load-fragment.h b/src/core/load-fragment.h index 4bfe943981..9a3ccd9d26 100644 --- a/src/core/load-fragment.h +++ b/src/core/load-fragment.h @@ -44,7 +44,6 @@ CONFIG_PARSER_PROTOTYPE(config_parse_exec_cpu_sched_prio); CONFIG_PARSER_PROTOTYPE(config_parse_exec_cpu_affinity); CONFIG_PARSER_PROTOTYPE(config_parse_exec_secure_bits); CONFIG_PARSER_PROTOTYPE(config_parse_capability_set); -CONFIG_PARSER_PROTOTYPE(config_parse_sysv_priority); CONFIG_PARSER_PROTOTYPE(config_parse_kill_signal); CONFIG_PARSER_PROTOTYPE(config_parse_exec_mount_flags); CONFIG_PARSER_PROTOTYPE(config_parse_timer); @@ -68,14 +67,13 @@ CONFIG_PARSER_PROTOTYPE(config_parse_environ); CONFIG_PARSER_PROTOTYPE(config_parse_pass_environ); CONFIG_PARSER_PROTOTYPE(config_parse_unset_environ); CONFIG_PARSER_PROTOTYPE(config_parse_unit_slice); -CONFIG_PARSER_PROTOTYPE(config_parse_cpu_weight); +CONFIG_PARSER_PROTOTYPE(config_parse_cg_weight); CONFIG_PARSER_PROTOTYPE(config_parse_cpu_shares); CONFIG_PARSER_PROTOTYPE(config_parse_memory_limit); CONFIG_PARSER_PROTOTYPE(config_parse_tasks_max); CONFIG_PARSER_PROTOTYPE(config_parse_delegate); CONFIG_PARSER_PROTOTYPE(config_parse_device_policy); CONFIG_PARSER_PROTOTYPE(config_parse_device_allow); -CONFIG_PARSER_PROTOTYPE(config_parse_io_weight); CONFIG_PARSER_PROTOTYPE(config_parse_io_device_weight); CONFIG_PARSER_PROTOTYPE(config_parse_io_limit); CONFIG_PARSER_PROTOTYPE(config_parse_blockio_weight); @@ -93,7 +91,6 @@ CONFIG_PARSER_PROTOTYPE(config_parse_exec_directories); CONFIG_PARSER_PROTOTYPE(config_parse_set_status); CONFIG_PARSER_PROTOTYPE(config_parse_namespace_path_strv); CONFIG_PARSER_PROTOTYPE(config_parse_temporary_filesystems); -CONFIG_PARSER_PROTOTYPE(config_parse_no_new_privileges); CONFIG_PARSER_PROTOTYPE(config_parse_cpu_quota); CONFIG_PARSER_PROTOTYPE(config_parse_protect_home); CONFIG_PARSER_PROTOTYPE(config_parse_protect_system); diff --git a/src/core/namespace.c b/src/core/namespace.c index 3154cad58a..24da3b8a64 100644 --- a/src/core/namespace.c +++ b/src/core/namespace.c @@ -1682,7 +1682,7 @@ static const char *const protect_home_table[_PROTECT_HOME_MAX] = { DEFINE_STRING_TABLE_LOOKUP(protect_home, ProtectHome); -ProtectHome parse_protect_home_or_bool(const char *s) { +ProtectHome protect_home_or_bool_from_string(const char *s) { int r; r = parse_boolean(s); @@ -1703,7 +1703,7 @@ static const char *const protect_system_table[_PROTECT_SYSTEM_MAX] = { DEFINE_STRING_TABLE_LOOKUP(protect_system, ProtectSystem); -ProtectSystem parse_protect_system_or_bool(const char *s) { +ProtectSystem protect_system_or_bool_from_string(const char *s) { int r; r = parse_boolean(s); diff --git a/src/core/namespace.h b/src/core/namespace.h index d8e4682255..705eb4e13a 100644 --- a/src/core/namespace.h +++ b/src/core/namespace.h @@ -97,11 +97,11 @@ int setup_netns(int netns_storage_socket[2]); const char* protect_home_to_string(ProtectHome p) _const_; ProtectHome protect_home_from_string(const char *s) _pure_; -ProtectHome parse_protect_home_or_bool(const char *s); +ProtectHome protect_home_or_bool_from_string(const char *s); const char* protect_system_to_string(ProtectSystem p) _const_; ProtectSystem protect_system_from_string(const char *s) _pure_; -ProtectSystem parse_protect_system_or_bool(const char *s); +ProtectSystem protect_system_or_bool_from_string(const char *s); void bind_mount_free_many(BindMount *b, size_t n); int bind_mount_add(BindMount **b, size_t *n, const BindMount *item); diff --git a/src/core/socket.c b/src/core/socket.c index 45c49eac49..238c942a1a 100644 --- a/src/core/socket.c +++ b/src/core/socket.c @@ -786,27 +786,28 @@ static void socket_dump(Unit *u, FILE *f, const char *prefix) { "%sKeepAliveTimeSec: %s\n", prefix, format_timespan(time_string, FORMAT_TIMESPAN_MAX, s->keep_alive_time, USEC_PER_SEC)); - if (s->keep_alive_interval) + if (s->keep_alive_interval > 0) fprintf(f, "%sKeepAliveIntervalSec: %s\n", prefix, format_timespan(time_string, FORMAT_TIMESPAN_MAX, s->keep_alive_interval, USEC_PER_SEC)); - if (s->keep_alive_cnt) + if (s->keep_alive_cnt > 0) fprintf(f, "%sKeepAliveProbes: %u\n", prefix, s->keep_alive_cnt); - if (s->defer_accept) + if (s->defer_accept > 0) fprintf(f, "%sDeferAcceptSec: %s\n", prefix, format_timespan(time_string, FORMAT_TIMESPAN_MAX, s->defer_accept, USEC_PER_SEC)); LIST_FOREACH(port, p, s->ports) { - if (p->type == SOCKET_SOCKET) { + switch (p->type) { + case SOCKET_SOCKET: { + _cleanup_free_ char *k = NULL; const char *t; int r; - char *k = NULL; r = socket_address_print(&p->address, &k); if (r < 0) @@ -815,15 +816,20 @@ static void socket_dump(Unit *u, FILE *f, const char *prefix) { t = k; fprintf(f, "%s%s: %s\n", prefix, listen_lookup(socket_address_family(&p->address), p->address.type), t); - free(k); - } else if (p->type == SOCKET_SPECIAL) + break; + } + case SOCKET_SPECIAL: fprintf(f, "%sListenSpecial: %s\n", prefix, p->path); - else if (p->type == SOCKET_USB_FUNCTION) + break; + case SOCKET_USB_FUNCTION: fprintf(f, "%sListenUSBFunction: %s\n", prefix, p->path); - else if (p->type == SOCKET_MQUEUE) + break; + case SOCKET_MQUEUE: fprintf(f, "%sListenMessageQueue: %s\n", prefix, p->path); - else + break; + default: fprintf(f, "%sListenFIFO: %s\n", prefix, p->path); + } } fprintf(f, @@ -1033,43 +1039,43 @@ static void socket_apply_socket_options(Socket *s, int fd) { assert(fd >= 0); if (s->keep_alive) { - int b = s->keep_alive; - if (setsockopt(fd, SOL_SOCKET, SO_KEEPALIVE, &b, sizeof(b)) < 0) + int one = 1; + if (setsockopt(fd, SOL_SOCKET, SO_KEEPALIVE, &one, sizeof(one)) < 0) log_unit_warning_errno(UNIT(s), errno, "SO_KEEPALIVE failed: %m"); } - if (s->keep_alive_time) { + if (s->keep_alive_time > 0) { int value = s->keep_alive_time / USEC_PER_SEC; if (setsockopt(fd, SOL_TCP, TCP_KEEPIDLE, &value, sizeof(value)) < 0) log_unit_warning_errno(UNIT(s), errno, "TCP_KEEPIDLE failed: %m"); } - if (s->keep_alive_interval) { + if (s->keep_alive_interval > 0) { int value = s->keep_alive_interval / USEC_PER_SEC; if (setsockopt(fd, SOL_TCP, TCP_KEEPINTVL, &value, sizeof(value)) < 0) log_unit_warning_errno(UNIT(s), errno, "TCP_KEEPINTVL failed: %m"); } - if (s->keep_alive_cnt) { + if (s->keep_alive_cnt > 0) { int value = s->keep_alive_cnt; if (setsockopt(fd, SOL_TCP, TCP_KEEPCNT, &value, sizeof(value)) < 0) log_unit_warning_errno(UNIT(s), errno, "TCP_KEEPCNT failed: %m"); } - if (s->defer_accept) { + if (s->defer_accept > 0) { int value = s->defer_accept / USEC_PER_SEC; if (setsockopt(fd, SOL_TCP, TCP_DEFER_ACCEPT, &value, sizeof(value)) < 0) log_unit_warning_errno(UNIT(s), errno, "TCP_DEFER_ACCEPT failed: %m"); } if (s->no_delay) { - int b = s->no_delay; + int one = 1; if (s->socket_protocol == IPPROTO_SCTP) { - if (setsockopt(fd, SOL_SCTP, SCTP_NODELAY, &b, sizeof(b)) < 0) + if (setsockopt(fd, SOL_SCTP, SCTP_NODELAY, &one, sizeof(one)) < 0) log_unit_warning_errno(UNIT(s), errno, "SCTP_NODELAY failed: %m"); } else { - if (setsockopt(fd, SOL_TCP, TCP_NODELAY, &b, sizeof(b)) < 0) + if (setsockopt(fd, SOL_TCP, TCP_NODELAY, &one, sizeof(one)) < 0) log_unit_warning_errno(UNIT(s), errno, "TCP_NODELAY failed: %m"); } } @@ -1100,7 +1106,6 @@ static void socket_apply_socket_options(Socket *s, int fd) { int value = (int) s->receive_buffer; /* We first try with SO_RCVBUFFORCE, in case we have the perms for that */ - if (setsockopt(fd, SOL_SOCKET, SO_RCVBUFFORCE, &value, sizeof(value)) < 0) if (setsockopt(fd, SOL_SOCKET, SO_RCVBUF, &value, sizeof(value)) < 0) log_unit_warning_errno(UNIT(s), errno, "SO_RCVBUF failed: %m"); @@ -1190,7 +1195,7 @@ static int fifo_address_create( return r; /* Enforce the right access mode for the fifo */ - old_mask = umask(~ socket_mode); + old_mask = umask(~socket_mode); /* Include the original umask in our mask */ (void) umask(~socket_mode | old_mask); @@ -1294,7 +1299,7 @@ static int mq_address_create( } /* Enforce the right access mode for the mq */ - old_mask = umask(~ mq_mode); + old_mask = umask(~mq_mode); /* Include the original umask in our mask */ (void) umask(~mq_mode | old_mask); diff --git a/src/shared/conf-parser.c b/src/shared/conf-parser.c index b74daefa2b..c74c83ba5b 100644 --- a/src/shared/conf-parser.c +++ b/src/shared/conf-parser.c @@ -502,34 +502,7 @@ int config_parse_many( } #define DEFINE_PARSER(type, vartype, conv_func) \ - int config_parse_##type( \ - 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) { \ - \ - vartype *i = data; \ - int r; \ - \ - assert(filename); \ - assert(lvalue); \ - assert(rvalue); \ - assert(data); \ - \ - r = conv_func(rvalue, i); \ - if (r < 0) \ - log_syntax(unit, LOG_ERR, filename, line, r, \ - "Failed to parse %s value, ignoring: %s", \ - #type, rvalue); \ - \ - return 0; \ - } + DEFINE_CONFIG_PARSE_PTR(config_parse_##type, conv_func, vartype, "Failed to parse " #type " value") DEFINE_PARSER(int, int, safe_atoi); DEFINE_PARSER(long, long, safe_atoli); diff --git a/src/shared/conf-parser.h b/src/shared/conf-parser.h index 0b0532d1ab..70d313d4eb 100644 --- a/src/shared/conf-parser.h +++ b/src/shared/conf-parser.h @@ -152,7 +152,45 @@ typedef enum Disabled { DISABLED_EXPERIMENTAL, } Disabled; -#define DEFINE_CONFIG_PARSE_ENUM(function,name,type,msg) \ +#define DEFINE_CONFIG_PARSE(function, parser, msg) \ + CONFIG_PARSER_PROTOTYPE(function) { \ + int *i = data, r; \ + \ + assert(filename); \ + assert(lvalue); \ + assert(rvalue); \ + assert(data); \ + \ + r = parser(rvalue); \ + if (r < 0) { \ + log_syntax(unit, LOG_ERR, filename, line, r, \ + msg ", ignoring: %s", rvalue); \ + return 0; \ + } \ + \ + *i = r; \ + return 0; \ + } + +#define DEFINE_CONFIG_PARSE_PTR(function, parser, type, msg) \ + CONFIG_PARSER_PROTOTYPE(function) { \ + type *i = data; \ + int r; \ + \ + assert(filename); \ + assert(lvalue); \ + assert(rvalue); \ + assert(data); \ + \ + r = parser(rvalue, i); \ + if (r < 0) \ + log_syntax(unit, LOG_ERR, filename, line, r, \ + msg ", ignoring: %s", rvalue); \ + \ + return 0; \ + } + +#define DEFINE_CONFIG_PARSE_ENUM(function, name, type, msg) \ CONFIG_PARSER_PROTOTYPE(function) { \ type *i = data, x; \ \ @@ -161,8 +199,9 @@ typedef enum Disabled { assert(rvalue); \ assert(data); \ \ - if ((x = name##_from_string(rvalue)) < 0) { \ - log_syntax(unit, LOG_ERR, filename, line, -x, \ + x = name##_from_string(rvalue); \ + if (x < 0) { \ + log_syntax(unit, LOG_ERR, filename, line, 0, \ msg ", ignoring: %s", rvalue); \ return 0; \ } \ @@ -171,7 +210,32 @@ typedef enum Disabled { return 0; \ } -#define DEFINE_CONFIG_PARSE_ENUMV(function,name,type,invalid,msg) \ +#define DEFINE_CONFIG_PARSE_ENUM_WITH_DEFAULT(function, name, type, default_value, msg) \ + CONFIG_PARSER_PROTOTYPE(function) { \ + type *i = data, x; \ + \ + assert(filename); \ + assert(lvalue); \ + assert(rvalue); \ + assert(data); \ + \ + if (isempty(rvalue)) { \ + *i = default_value; \ + return 0; \ + } \ + \ + x = name##_from_string(rvalue); \ + if (x < 0) { \ + log_syntax(unit, LOG_ERR, filename, line, 0, \ + msg ", ignoring: %s", rvalue); \ + return 0; \ + } \ + \ + *i = x; \ + return 0; \ + } + +#define DEFINE_CONFIG_PARSE_ENUMV(function, name, type, invalid, msg) \ CONFIG_PARSER_PROTOTYPE(function) { \ type **enums = data, x, *ys; \ _cleanup_free_ type *xs = NULL; \ @@ -198,17 +262,17 @@ typedef enum Disabled { return -ENOMEM; \ \ if ((x = name##_from_string(en)) < 0) { \ - log_syntax(unit, LOG_ERR, filename, line, \ - -x, msg ", ignoring: %s", en); \ + log_syntax(unit, LOG_ERR, filename, line, 0, \ + msg ", ignoring: %s", en); \ continue; \ } \ \ for (ys = xs; x != invalid && *ys != invalid; ys++) { \ if (*ys == x) { \ - log_syntax(unit, LOG_ERR, filename, \ - line, -x, \ - "Duplicate entry, ignoring: %s", \ - en); \ + log_syntax(unit, LOG_NOTICE, filename, \ + line, 0, \ + "Duplicate entry, ignoring: %s", \ + en); \ x = invalid; \ } \ } \