Compare commits

..

22 Commits

Author SHA1 Message Date
Lennart Poettering 2a407487b2
Merge pull request #17049 from mrc0mmand/code-and-spell-check
tree-wide: assorted cleanups/fixes
2020-09-14 23:00:02 +02:00
Zbigniew Jędrzejewski-Szmek 094c6fc338
Merge pull request #17031 from poettering/path-start-limit
core: propagate start limit hit from triggered unit to path unit
2020-09-14 21:51:39 +02:00
Zbigniew Jędrzejewski-Szmek bc2ed3bbf0
Merge pull request #17039 from poettering/dbus-default-dep
tweak when we synthesize dbus deps for service units
2020-09-14 21:45:53 +02:00
Lennart Poettering 60bcb45927 man: rework UMask= explanation
Mention the JSON user record stuff. Mention pam_umask explicitly.
Mention that UMask= of the per-user user@.service instance can be used
too.

Fixes: #16963
2020-09-14 21:44:06 +02:00
Lennart Poettering 2a03b9ed21 tree-wide: don't needlessly negate error number passed to bus_error_message()
Like it's customary in our codebase bus_error_message() internally takes
abs() of the passed error anyway, hence no need to explicitly negate it.
We mostly got this right, but in too many cases we didn't. Fix that.
2020-09-14 21:42:22 +02:00
Lennart Poettering ad0b610b0c bootctl: handle if LoaderSystemToken is invalid for some reason
This points to some firmware issue, but we should still be able to
correct things if this happens. Hence log about this and fix it.

Fixes: #17041
2020-09-14 21:33:31 +02:00
Lennart Poettering 0c94a31464
Merge pull request #17027 from poettering/env-escape-fix
make sure we our env file writer, parser and shell agree on things
2020-09-14 16:48:00 +02:00
Frantisek Sumsal 05827831a6 shared: drop a redundant if statement 2020-09-14 16:18:18 +02:00
Frantisek Sumsal 8d16f29b23 libsystemd: drop a redundant if statement 2020-09-14 16:18:02 +02:00
Frantisek Sumsal 890ea05ac2 home: return SYNTHETIC_ERRNO() when appropriate 2020-09-14 16:16:59 +02:00
Frantisek Sumsal 60d7a2029a basic: drop a redundant if statement 2020-09-14 16:16:18 +02:00
Frantisek Sumsal 973bc32ab6 core: consolidate alloc & put operations into one statement 2020-09-14 16:13:44 +02:00
Frantisek Sumsal 69e3234db7 tree-wide: fix typos found by codespell
Reported by Fossies.org
2020-09-14 15:32:37 +02:00
Lennart Poettering 22f401b269 unit-def: drop pointless 0 initialization of first enum value
This is implied in C and we generally don't bother with this, so don't
bother with this here either.
2020-09-14 13:05:09 +02:00
Lennart Poettering 47ab8f73e3 core: propagate unit start limit hit state to triggering path unit
We already do this for socket and automount units, do it for path units
too: if the triggered service keeps hitting the start limit, then fail
the triggering unit too, so that we don#t busy loop forever.

(Note that this leaves only timer units out in the cold for this kind of
protection, but it shouldn't matter there, as they are naturally
protected against busy loops: they are scheduled by time anyway).

Fixes: #16669
2020-09-14 13:05:09 +02:00
Lennart Poettering 0377cd2936 core: propagate triggered unit in more load states
In 4c2ef32767 we enabled propagating
triggered unit state to the triggering unit for service units in more
load states, so that we don't accidentally stop tracking state
correctly.

Do the same for our other triggering unit states: automounts, paths, and
timers.

Also, make this an assertion rather than a simple test. After all it
should never happen that we get called for half-loaded units or units of
the wrong type. The load routines should already have made this
impossible.
2020-09-14 13:05:09 +02:00
Lennart Poettering df8b14b591 test-fileio: test test strings with shell, too 2020-09-14 12:26:41 +02:00
Lennart Poettering 55f99c26c6 test-env-file: add test that tests our env file read + writer + shell against each other
Should hopefully make regressions on this unlikely.
2020-09-14 12:26:41 +02:00
Lennart Poettering de008e537d env-file: bring our decoding of double-quoted strings in env files in line with shell
In shell, inside of double quotes only a select few chars should be
escaped. If other chars are escaped this has no effect. Correct the list
of chars that need such escaping.

Also, make sure we can read back the stuff we wrote out without loss.

Fixes: #16788
2020-09-14 11:08:43 +02:00
Lennart Poettering 6fe3196350 test-fileio: use test strings that are actually valid in shell 2020-09-14 11:08:43 +02:00
Lennart Poettering a7f49f0b7c service: add implicit dbus deps only for Type=dbus units
We want to be able to use BusName= in services that run during early boot
already, and thus don't synthesize deps on dbus there. Instead add them
when Type=dbus is set, because in that case we actually really need
D-Bus support.

Fixes: #17037
2020-09-14 11:07:30 +02:00
Lennart Poettering 31d74c66e2 core: don't warn if BusName= is used for non-Type=dbus services
It's useful for more than just Type=dbus now, given #16976. Hence, let's
drop the warning.
2020-09-14 11:07:12 +02:00
44 changed files with 186 additions and 114 deletions

6
NEWS
View File

@ -90,7 +90,7 @@ CHANGES WITH 247 in spe:
latter it takes precedence over the former, similar to how most of latter it takes precedence over the former, similar to how most of
systemd's own configuration is handled. Given that PAM stack systemd's own configuration is handled. Given that PAM stack
definitions are primarily put together by OS vendors/distributions definitions are primarily put together by OS vendors/distributions
(though possibly overriden by users), this systemd release moves its (though possibly overridden by users), this systemd release moves its
own PAM stack configuration for the "systemd-user" PAM service (i.e. own PAM stack configuration for the "systemd-user" PAM service (i.e.
for the PAM session invoked by the per-user user@.service instance) for the PAM session invoked by the per-user user@.service instance)
from /etc/pam.d/ to /usr/lib/pam.d/. We recommend moving all from /etc/pam.d/ to /usr/lib/pam.d/. We recommend moving all
@ -98,7 +98,7 @@ CHANGES WITH 247 in spe:
/etc/pam.d/ to /usr/lib/pam.d/, but if such OS-wide migration is not /etc/pam.d/ to /usr/lib/pam.d/, but if such OS-wide migration is not
desired the location to which systemd installs its PAM stack desired the location to which systemd installs its PAM stack
configuration file may be changed via the "pamconfdir" meson variable configuration file may be changed via the "pamconfdir" meson variable
at build time, optionally undoing ths change of default paths at build time, optionally undoing this change of default paths
introduced with systemd 247. introduced with systemd 247.
CHANGES WITH 246: CHANGES WITH 246:
@ -260,7 +260,7 @@ CHANGES WITH 246:
generation for collection with systemd-pstore. generation for collection with systemd-pstore.
* We provide a set of udev rules to enable auto-suspend on PCI and USB * We provide a set of udev rules to enable auto-suspend on PCI and USB
devices that were tested to currectly support it. Previously, this devices that were tested to correctly support it. Previously, this
was distributed as a set of udev rules, but has now been replaced by was distributed as a set of udev rules, but has now been replaced by
by a set of hwdb entries (and a much shorter udev rule to take action by a set of hwdb entries (and a much shorter udev rule to take action
if the device modalias matches one of the new hwdb entries). if the device modalias matches one of the new hwdb entries).

View File

@ -301,7 +301,7 @@ s - Service VLAN, m - Two-port MAC Relay (TPMR)
</term> </term>
<listitem><para>Reconfigure network interfaces. Takes interface name or index number. Note that <listitem><para>Reconfigure network interfaces. Takes interface name or index number. Note that
this does not reload <filename>.netdev</filename> or <filename>.network</filename> this does not reload <filename>.netdev</filename> or <filename>.network</filename>
corresponding to the the specifed interface. So, if you edit config files, it is necessary to corresponding to the the specified interface. So, if you edit config files, it is necessary to
call <command>networkctl reload</command> first to apply new settings.</para></listitem> call <command>networkctl reload</command> first to apply new settings.</para></listitem>
</varlistentry> </varlistentry>

View File

@ -213,7 +213,7 @@
specifies the initial size of the loopback file to create.</para> specifies the initial size of the loopback file to create.</para>
<para>The <option>--size=auto</option> option takes the sizes of pre-existing partitions into <para>The <option>--size=auto</option> option takes the sizes of pre-existing partitions into
account. However, it does not accomodate for partition tables that are not tightly packed: the account. However, it does not accommodate for partition tables that are not tightly packed: the
configured partitions might still not fit into the backing device if empty space exists between configured partitions might still not fit into the backing device if empty space exists between
pre-existing partitions (or before the first partition) that cannot be fully filled by partitions to pre-existing partitions (or before the first partition) that cannot be fully filled by partitions to
grow or create.</para> grow or create.</para>

View File

@ -863,12 +863,17 @@ CapabilityBoundingSet=~CAP_B CAP_C</programlisting>
<listitem><para>Controls the file mode creation mask. Takes an access mode in octal notation. See <listitem><para>Controls the file mode creation mask. Takes an access mode in octal notation. See
<citerefentry><refentrytitle>umask</refentrytitle><manvolnum>2</manvolnum></citerefentry> for <citerefentry><refentrytitle>umask</refentrytitle><manvolnum>2</manvolnum></citerefentry> for
details. Defaults to 0022 for system units. For units of the user service manager the default value details. Defaults to 0022 for system units. For user units the default value is inherited from the
is inherited from the user instance (whose default is inherited from the system service manager, and per-user service manager (whose default is in turn inherited from the system service manager, and
thus also is 0022). Hence changing the default value of a user instance, either via thus typically also is 0022 — unless overriden by a PAM module). In order to change the per-user mask
<varname>UMask=</varname> or via a PAM module, will affect the user instance itself and all user for all user services, consider setting the <varname>UMask=</varname> setting of the user's
units started by the user instance unless a user unit has specified its own <filename>user@.service</filename> system service instance. The per-user umask may also be set via
<varname>UMask=</varname>.</para></listitem> the <varname>umask</varname> field of a user's <ulink url="https://systemd.io/USER_RECORD">JSON User
Record</ulink> (for users managed by
<citerefentry><refentrytitle>systemd-homed.service</refentrytitle><manvolnum>8</manvolnum></citerefentry>
this field may be controlled via <command>homectl --umask=</command>). It may also be set via a PAM
module, such as <citerefentry
project='man-pages'><refentrytitle>pam_umask</refentrytitle><manvolnum>8</manvolnum></citerefentry>.</para></listitem>
</varlistentry> </varlistentry>
<varlistentry> <varlistentry>

View File

@ -200,13 +200,13 @@
</para> </para>
<para>If the address string is a string in the format <para>If the address string is a string in the format
<literal><replaceable>v.w.x.y</replaceable>:<replaceable>z</replaceable></literal>, it is interpeted <literal><replaceable>v.w.x.y</replaceable>:<replaceable>z</replaceable></literal>, it is interpreted
as IPv4 address <replaceable>v.w.x.y</replaceable> and port <replaceable>z</replaceable>.</para> as IPv4 address <replaceable>v.w.x.y</replaceable> and port <replaceable>z</replaceable>.</para>
<para>If the address string is a string in the format <para>If the address string is a string in the format
<literal>[<replaceable>x</replaceable>]:<replaceable>y</replaceable></literal>, it is interpreted as <literal>[<replaceable>x</replaceable>]:<replaceable>y</replaceable></literal>, it is interpreted as
IPv6 address <replaceable>x</replaceable> and port <replaceable>y</replaceable>. An optional IPv6 address <replaceable>x</replaceable> and port <replaceable>y</replaceable>. An optional
interface scope (interface name or number) may be specifed after a <literal>%</literal> symbol: interface scope (interface name or number) may be specified after a <literal>%</literal> symbol:
<literal>[<replaceable>x</replaceable>]:<replaceable>y</replaceable>%<replaceable>dev</replaceable></literal>. <literal>[<replaceable>x</replaceable>]:<replaceable>y</replaceable>%<replaceable>dev</replaceable></literal>.
Interface scopes are only useful with link-local addresses, because the kernel ignores them in other Interface scopes are only useful with link-local addresses, because the kernel ignores them in other
cases. Note that if an address is specified as IPv6, it might still make the service available via cases. Note that if an address is specified as IPv6, it might still make the service available via

View File

@ -39,7 +39,7 @@
<varlistentry id='tclass-classid'> <varlistentry id='tclass-classid'>
<term><varname>ClassId=</varname></term> <term><varname>ClassId=</varname></term>
<listitem> <listitem>
<para>Configues the unique identifier of the class. It is specified as the major and minor numbers in <para>Configures the unique identifier of the class. It is specified as the major and minor numbers in
hexadecimal in the range 0x1Oxffff separated with a colon (<literal>major:minor</literal>). hexadecimal in the range 0x1Oxffff separated with a colon (<literal>major:minor</literal>).
Defaults to unset.</para> Defaults to unset.</para>
</listitem> </listitem>

View File

@ -432,7 +432,7 @@ static int hardlink_context_setup(
* bottleneck we can certainly place an in-memory hash table in front of this, but for the beginning, * bottleneck we can certainly place an in-memory hash table in front of this, but for the beginning,
* let's keep things simple, and just use the disk as lookup table for inodes. * let's keep things simple, and just use the disk as lookup table for inodes.
* *
* Note that this should have zero performace impact as long as .n_link of all files copied remains * Note that this should have zero performance impact as long as .n_link of all files copied remains
* <= 0, because in that case we will not actually allocate the hardlink inode lookup table directory * <= 0, because in that case we will not actually allocate the hardlink inode lookup table directory
* on disk (we do so lazily, when the first candidate with .n_link > 1 is seen). This means, in the * on disk (we do so lazily, when the first candidate with .n_link > 1 is seen). This means, in the
* common case where hardlinks are not used at all or only for few files the fact that we store the * common case where hardlinks are not used at all or only for few files the fact that we store the

View File

@ -209,17 +209,21 @@ static int parse_env_file_internal(
case DOUBLE_QUOTE_VALUE_ESCAPE: case DOUBLE_QUOTE_VALUE_ESCAPE:
state = DOUBLE_QUOTE_VALUE; state = DOUBLE_QUOTE_VALUE;
if (c == '"') { if (strchr(SHELL_NEED_ESCAPE, c)) {
/* If this is a char that needs escaping, just unescape it. */
if (!GREEDY_REALLOC(value, value_alloc, n_value+2)) if (!GREEDY_REALLOC(value, value_alloc, n_value+2))
return -ENOMEM; return -ENOMEM;
value[n_value++] = '"'; value[n_value++] = c;
} else if (!strchr(NEWLINE, c)) { } else if (c != '\n') {
/* If other char than what needs escaping, keep the "\" in place, like the
* real shell does. */
if (!GREEDY_REALLOC(value, value_alloc, n_value+3)) if (!GREEDY_REALLOC(value, value_alloc, n_value+3))
return -ENOMEM; return -ENOMEM;
value[n_value++] = '\\'; value[n_value++] = '\\';
value[n_value++] = c; value[n_value++] = c;
} }
/* Escaped newlines (aka "continuation lines") are eaten up entirely */
break; break;
case COMMENT: case COMMENT:

View File

@ -153,10 +153,8 @@ int pipe_eof(int fd) {
int r; int r;
r = fd_wait_for_event(fd, POLLIN, 0); r = fd_wait_for_event(fd, POLLIN, 0);
if (r < 0) if (r <= 0)
return r; return r;
if (r == 0)
return 0;
return !!(r & POLLHUP); return !!(r & POLLHUP);
} }

View File

@ -9,7 +9,7 @@
* when other criteria (cpu weight, nice level) are identical. * when other criteria (cpu weight, nice level) are identical.
* In this case service units have the highest priority. */ * In this case service units have the highest priority. */
typedef enum UnitType { typedef enum UnitType {
UNIT_SERVICE = 0, UNIT_SERVICE,
UNIT_MOUNT, UNIT_MOUNT,
UNIT_SWAP, UNIT_SWAP,
UNIT_SOCKET, UNIT_SOCKET,
@ -25,7 +25,7 @@ typedef enum UnitType {
} UnitType; } UnitType;
typedef enum UnitLoadState { typedef enum UnitLoadState {
UNIT_STUB = 0, UNIT_STUB,
UNIT_LOADED, UNIT_LOADED,
UNIT_NOT_FOUND, /* error condition #1: unit file not found */ UNIT_NOT_FOUND, /* error condition #1: unit file not found */
UNIT_BAD_SETTING, /* error condition #2: we couldn't parse some essential unit file setting */ UNIT_BAD_SETTING, /* error condition #2: we couldn't parse some essential unit file setting */

View File

@ -1454,7 +1454,9 @@ static int install_random_seed(const char *esp) {
} }
r = efi_get_variable(EFI_VENDOR_LOADER, "LoaderSystemToken", NULL, NULL, &token_size); r = efi_get_variable(EFI_VENDOR_LOADER, "LoaderSystemToken", NULL, NULL, &token_size);
if (r < 0) { if (r == -ENODATA)
log_debug_errno(r, "LoaderSystemToken EFI variable is invalid (too short?), replacing.");
else if (r < 0) {
if (r != -ENOENT) if (r != -ENOENT)
return log_error_errno(r, "Failed to test system token validity: %m"); return log_error_errno(r, "Failed to test system token validity: %m");
} else { } else {

View File

@ -507,8 +507,8 @@ static void automount_trigger_notify(Unit *u, Unit *other) {
assert(other); assert(other);
/* Filter out invocations with bogus state */ /* Filter out invocations with bogus state */
if (other->load_state != UNIT_LOADED || other->type != UNIT_MOUNT) assert(UNIT_IS_LOAD_COMPLETE(other->load_state));
return; assert(other->type == UNIT_MOUNT);
/* Don't propagate state changes from the mount if we are already down */ /* Don't propagate state changes from the mount if we are already down */
if (!IN_SET(a->state, AUTOMOUNT_WAITING, AUTOMOUNT_RUNNING)) if (!IN_SET(a->state, AUTOMOUNT_WAITING, AUTOMOUNT_RUNNING))

View File

@ -2484,7 +2484,7 @@ static int acquire_credentials(
if (dfd < 0) if (dfd < 0)
return -errno; return -errno;
/* First we use the literally specified credentials. Note that they might be overriden again below, /* First we use the literally specified credentials. Note that they might be overridden again below,
* and thus act as a "default" if the same credential is specified multiple times */ * and thus act as a "default" if the same credential is specified multiple times */
HASHMAP_FOREACH(sc, context->set_credentials) { HASHMAP_FOREACH(sc, context->set_credentials) {
size_t add; size_t add;
@ -4340,7 +4340,7 @@ static int exec_child(
* we'll try not to call PR_SET_SECUREBITS unless necessary. Setting securebits requires * we'll try not to call PR_SET_SECUREBITS unless necessary. Setting securebits requires
* CAP_SETPCAP. */ * CAP_SETPCAP. */
if (prctl(PR_GET_SECUREBITS) != secure_bits) { if (prctl(PR_GET_SECUREBITS) != secure_bits) {
/* CAP_SETPCAP is required to set securebits. This capabilitiy is raised into the /* CAP_SETPCAP is required to set securebits. This capability is raised into the
* effective set here. * effective set here.
* The effective set is overwritten during execve with the following values: * The effective set is overwritten during execve with the following values:
* - ambient set (for non-root processes) * - ambient set (for non-root processes)

View File

@ -542,7 +542,7 @@ int mount_setup(bool loaded_policy, bool leave_propagation) {
/* Also create /run/systemd/inaccessible nodes, so that we always have something to mount /* Also create /run/systemd/inaccessible nodes, so that we always have something to mount
* inaccessible nodes from. If we run in a container the host might have created these for us already * inaccessible nodes from. If we run in a container the host might have created these for us already
* in /run/host/inaccessible/. Use those if we can, since tht way we likely get access to block/char * in /run/host/inaccessible/. Use those if we can, since that way we likely get access to block/char
* device nodes that are inaccessible, and if userns is used to nodes that are on mounts owned by a * device nodes that are inaccessible, and if userns is used to nodes that are on mounts owned by a
* userns outside the container and thus nicely read-only and not remountable. */ * userns outside the container and thus nicely read-only and not remountable. */
if (access("/run/host/inaccessible/", F_OK) < 0) { if (access("/run/host/inaccessible/", F_OK) < 0) {

View File

@ -748,10 +748,23 @@ static void path_trigger_notify(Unit *u, Unit *other) {
assert(u); assert(u);
assert(other); assert(other);
/* Invoked whenever the unit we trigger changes state or gains /* Invoked whenever the unit we trigger changes state or gains or loses a job */
* or loses a job */
if (other->load_state != UNIT_LOADED) /* Filter out invocations with bogus state */
assert(UNIT_IS_LOAD_COMPLETE(other->load_state));
/* Don't propagate state changes from the triggered unit if we are already down */
if (!IN_SET(p->state, PATH_WAITING, PATH_RUNNING))
return;
/* Propagate start limit hit state */
if (other->start_limit_hit) {
path_enter_dead(p, PATH_FAILURE_UNIT_START_LIMIT_HIT);
return;
}
/* Don't propagate anything if there's still a job queued */
if (other->job)
return; return;
if (p->state == PATH_RUNNING && if (p->state == PATH_RUNNING &&
@ -790,6 +803,7 @@ static const char* const path_result_table[_PATH_RESULT_MAX] = {
[PATH_SUCCESS] = "success", [PATH_SUCCESS] = "success",
[PATH_FAILURE_RESOURCES] = "resources", [PATH_FAILURE_RESOURCES] = "resources",
[PATH_FAILURE_START_LIMIT_HIT] = "start-limit-hit", [PATH_FAILURE_START_LIMIT_HIT] = "start-limit-hit",
[PATH_FAILURE_UNIT_START_LIMIT_HIT] = "unit-start-limit-hit",
}; };
DEFINE_STRING_TABLE_LOOKUP(path_result, PathResult); DEFINE_STRING_TABLE_LOOKUP(path_result, PathResult);

View File

@ -45,6 +45,7 @@ typedef enum PathResult {
PATH_SUCCESS, PATH_SUCCESS,
PATH_FAILURE_RESOURCES, PATH_FAILURE_RESOURCES,
PATH_FAILURE_START_LIMIT_HIT, PATH_FAILURE_START_LIMIT_HIT,
PATH_FAILURE_UNIT_START_LIMIT_HIT,
_PATH_RESULT_MAX, _PATH_RESULT_MAX,
_PATH_RESULT_INVALID = -1 _PATH_RESULT_INVALID = -1
} PathResult; } PathResult;

View File

@ -589,9 +589,6 @@ static int service_verify(Service *s) {
return -ENOEXEC; return -ENOEXEC;
} }
if (s->bus_name && s->type != SERVICE_DBUS)
log_unit_warning(UNIT(s), "Service has a D-Bus service name specified, but is not of type dbus. Ignoring.");
if (s->exec_context.pam_name && !IN_SET(s->kill_context.kill_mode, KILL_CONTROL_GROUP, KILL_MIXED)) { if (s->exec_context.pam_name && !IN_SET(s->kill_context.kill_mode, KILL_CONTROL_GROUP, KILL_MIXED)) {
log_unit_error(UNIT(s), "Service has PAM enabled. Kill mode must be set to 'control-group' or 'mixed'. Refusing."); log_unit_error(UNIT(s), "Service has PAM enabled. Kill mode must be set to 'control-group' or 'mixed'. Refusing.");
return -ENOEXEC; return -ENOEXEC;
@ -687,7 +684,7 @@ static int service_setup_bus_name(Service *s) {
assert(s); assert(s);
if (!s->bus_name) if (s->type != SERVICE_DBUS)
return 0; return 0;
r = unit_add_dependency_by_name(UNIT(s), UNIT_REQUIRES, SPECIAL_DBUS_SOCKET, true, UNIT_DEPENDENCY_FILE); r = unit_add_dependency_by_name(UNIT(s), UNIT_REQUIRES, SPECIAL_DBUS_SOCKET, true, UNIT_DEPENDENCY_FILE);
@ -2313,7 +2310,7 @@ static void service_enter_restart(Service *s) {
return; return;
fail: fail:
log_unit_warning(UNIT(s), "Failed to schedule restart job: %s", bus_error_message(&error, -r)); log_unit_warning(UNIT(s), "Failed to schedule restart job: %s", bus_error_message(&error, r));
service_enter_dead(s, SERVICE_FAILURE_RESOURCES, false); service_enter_dead(s, SERVICE_FAILURE_RESOURCES, false);
} }
@ -2329,7 +2326,7 @@ static void service_enter_reload_by_notify(Service *s) {
/* service_enter_reload_by_notify is never called during a reload, thus no loops are possible. */ /* service_enter_reload_by_notify is never called during a reload, thus no loops are possible. */
r = manager_propagate_reload(UNIT(s)->manager, UNIT(s), JOB_FAIL, &error); r = manager_propagate_reload(UNIT(s)->manager, UNIT(s), JOB_FAIL, &error);
if (r < 0) if (r < 0)
log_unit_warning(UNIT(s), "Failed to schedule propagation of reload: %s", bus_error_message(&error, -r)); log_unit_warning(UNIT(s), "Failed to schedule propagation of reload: %s", bus_error_message(&error, r));
} }
static void service_enter_reload(Service *s) { static void service_enter_reload(Service *s) {

View File

@ -3265,13 +3265,8 @@ static void socket_trigger_notify(Unit *u, Unit *other) {
assert(other); assert(other);
/* Filter out invocations with bogus state */ /* Filter out invocations with bogus state */
if (!IN_SET(other->load_state, assert(UNIT_IS_LOAD_COMPLETE(other->load_state));
UNIT_LOADED, assert(other->type == UNIT_SERVICE);
UNIT_NOT_FOUND,
UNIT_BAD_SETTING,
UNIT_ERROR,
UNIT_MASKED) || other->type != UNIT_SERVICE)
return;
/* Don't propagate state changes from the service if we are already down */ /* Don't propagate state changes from the service if we are already down */
if (!IN_SET(s->state, SOCKET_RUNNING, SOCKET_LISTENING)) if (!IN_SET(s->state, SOCKET_RUNNING, SOCKET_LISTENING))

View File

@ -746,8 +746,8 @@ static void timer_trigger_notify(Unit *u, Unit *other) {
assert(u); assert(u);
assert(other); assert(other);
if (other->load_state != UNIT_LOADED) /* Filter out invocations with bogus state */
return; assert(UNIT_IS_LOAD_COMPLETE(other->load_state));
/* Reenable all timers that depend on unit state */ /* Reenable all timers that depend on unit state */
LIST_FOREACH(value, v, t->values) LIST_FOREACH(value, v, t->values)

View File

@ -938,7 +938,7 @@ int transaction_add_job_and_dependencies(
/* Safety check that the unit is a valid state, i.e. not in UNIT_STUB or UNIT_MERGED which should only be set /* Safety check that the unit is a valid state, i.e. not in UNIT_STUB or UNIT_MERGED which should only be set
* temporarily. */ * temporarily. */
if (!IN_SET(unit->load_state, UNIT_LOADED, UNIT_ERROR, UNIT_NOT_FOUND, UNIT_BAD_SETTING, UNIT_MASKED)) if (!UNIT_IS_LOAD_COMPLETE(unit->load_state))
return sd_bus_error_setf(e, BUS_ERROR_LOAD_FAILED, "Unit %s is not loaded properly.", unit->id); return sd_bus_error_setf(e, BUS_ERROR_LOAD_FAILED, "Unit %s is not loaded properly.", unit->id);
if (type != JOB_STOP) { if (type != JOB_STOP) {

View File

@ -209,11 +209,7 @@ static int unit_add_alias(Unit *u, char *donated_name) {
/* Make sure that u->names is allocated. We may leave u->names /* Make sure that u->names is allocated. We may leave u->names
* empty if we fail later, but this is not a problem. */ * empty if we fail later, but this is not a problem. */
r = set_ensure_allocated(&u->aliases, &string_hash_ops); r = set_ensure_put(&u->aliases, &string_hash_ops, donated_name);
if (r < 0)
return r;
r = set_put(u->aliases, donated_name);
if (r < 0) if (r < 0)
return r; return r;
assert(r > 0); assert(r > 0);

View File

@ -49,6 +49,10 @@ static inline bool UNIT_IS_INACTIVE_OR_FAILED(UnitActiveState t) {
return IN_SET(t, UNIT_INACTIVE, UNIT_FAILED); return IN_SET(t, UNIT_INACTIVE, UNIT_FAILED);
} }
static inline bool UNIT_IS_LOAD_COMPLETE(UnitLoadState t) {
return t >= 0 && t < _UNIT_LOAD_STATE_MAX && t != UNIT_STUB && t != UNIT_MERGED;
}
/* Stores the 'reason' a dependency was created as a bit mask, i.e. due to which configuration source it came to be. We /* Stores the 'reason' a dependency was created as a bit mask, i.e. due to which configuration source it came to be. We
* use this so that we can selectively flush out parts of dependencies again. Note that the same dependency might be * use this so that we can selectively flush out parts of dependencies again. Note that the same dependency might be
* created as a result of multiple "reasons", hence the bitmask. */ * created as a result of multiple "reasons", hence the bitmask. */

View File

@ -534,6 +534,7 @@ finish:
fido_dev_info_free(&di, di_size); fido_dev_info_free(&di, di_size);
return r; return r;
#else #else
return log_error_errno(EOPNOTSUPP, "FIDO2 tokens not supported on this build."); return log_error_errno(SYNTHETIC_ERRNO(EOPNOTSUPP),
"FIDO2 tokens not supported on this build.");
#endif #endif
} }

View File

@ -475,6 +475,7 @@ int find_pkcs11_token_auto(char **ret) {
return 0; return 0;
#else #else
return log_error_errno(EOPNOTSUPP, "PKCS#11 tokens not supported on this build."); return log_error_errno(SYNTHETIC_ERRNO(EOPNOTSUPP),
"PKCS#11 tokens not supported on this build.");
#endif #endif
} }

View File

@ -2183,7 +2183,7 @@ int home_create_luks(
if (disk_uuid_path) if (disk_uuid_path)
(void) ioctl(image_fd, BLKRRPART, 0); (void) ioctl(image_fd, BLKRRPART, 0);
else { else {
/* If we operate on a file, sync the contaning directory too. */ /* If we operate on a file, sync the containing directory too. */
r = fsync_directory_of_file(image_fd); r = fsync_directory_of_file(image_fd);
if (r < 0) { if (r < 0) {
log_error_errno(r, "Failed to synchronize directory of image file to disk: %m"); log_error_errno(r, "Failed to synchronize directory of image file to disk: %m");

View File

@ -229,7 +229,7 @@ static int set_simple_string(sd_bus *bus, const char *method, const char *value)
&error, NULL, &error, NULL,
"sb", value, arg_ask_password); "sb", value, arg_ask_password);
if (r < 0) if (r < 0)
return log_error_errno(r, "Could not set property: %s", bus_error_message(&error, -r)); return log_error_errno(r, "Could not set property: %s", bus_error_message(&error, r));
return 0; return 0;
} }

View File

@ -115,7 +115,7 @@ static int change_runlevel(Server *s, int runlevel) {
NULL, NULL,
"ss", target, mode); "ss", target, mode);
if (r < 0) if (r < 0)
return log_error_errno(r, "Failed to change runlevel: %s", bus_error_message(&error, -r)); return log_error_errno(r, "Failed to change runlevel: %s", bus_error_message(&error, r));
return 0; return 0;
} }

View File

@ -581,10 +581,7 @@ const char *bus_error_message(const sd_bus_error *e, int error) {
return e->message; return e->message;
} }
if (error < 0) return strerror_safe(abs(error));
error = -error;
return strerror_safe(error);
} }
static bool map_ok(const sd_bus_error_map *map) { static bool map_ok(const sd_bus_error_map *map) {

View File

@ -373,7 +373,7 @@ static void* client2(void *p) {
r = sd_bus_send(bus, m, NULL); r = sd_bus_send(bus, m, NULL);
if (r < 0) { if (r < 0) {
log_error("Failed to issue method call: %s", bus_error_message(&error, -r)); log_error("Failed to issue method call: %s", bus_error_message(&error, r));
goto finish; goto finish;
} }
@ -392,7 +392,7 @@ static void* client2(void *p) {
r = sd_bus_send(bus, m, NULL); r = sd_bus_send(bus, m, NULL);
if (r < 0) { if (r < 0) {
log_error("Failed to issue signal: %s", bus_error_message(&error, -r)); log_error("Failed to issue signal: %s", bus_error_message(&error, r));
goto finish; goto finish;
} }
@ -412,7 +412,7 @@ static void* client2(void *p) {
r = sd_bus_call(bus, m, 0, &error, &reply); r = sd_bus_call(bus, m, 0, &error, &reply);
if (r < 0) { if (r < 0) {
log_error("Failed to issue method call: %s", bus_error_message(&error, -r)); log_error("Failed to issue method call: %s", bus_error_message(&error, r));
goto finish; goto finish;
} }
@ -442,7 +442,7 @@ static void* client2(void *p) {
r = sd_bus_call(bus, m, 200 * USEC_PER_MSEC, &error, &reply); r = sd_bus_call(bus, m, 200 * USEC_PER_MSEC, &error, &reply);
if (r < 0) if (r < 0)
log_info("Failed to issue method call: %s", bus_error_message(&error, -r)); log_info("Failed to issue method call: %s", bus_error_message(&error, r));
else else
log_info("Slow call succeed."); log_info("Slow call succeed.");
@ -462,7 +462,7 @@ static void* client2(void *p) {
r = sd_bus_call_async(bus, NULL, m, quit_callback, &quit, 200 * USEC_PER_MSEC); r = sd_bus_call_async(bus, NULL, m, quit_callback, &quit, 200 * USEC_PER_MSEC);
if (r < 0) { if (r < 0) {
log_info("Failed to issue method call: %s", bus_error_message(&error, -r)); log_info("Failed to issue method call: %s", bus_error_message(&error, r));
goto finish; goto finish;
} }

View File

@ -129,7 +129,7 @@ static int client(struct context *c) {
r = sd_bus_call(bus, m, 0, &error, &reply); r = sd_bus_call(bus, m, 0, &error, &reply);
if (r < 0) if (r < 0)
return log_error_errno(r, "Failed to issue method call: %s", bus_error_message(&error, -r)); return log_error_errno(r, "Failed to issue method call: %s", bus_error_message(&error, r));
return 0; return 0;
} }

View File

@ -495,10 +495,8 @@ static int rtnl_poll(sd_netlink *rtnl, bool need_more, uint64_t timeout_usec) {
m = timeout_usec; m = timeout_usec;
r = fd_wait_for_event(rtnl->fd, e, m); r = fd_wait_for_event(rtnl->fd, e, m);
if (r < 0) if (r <= 0)
return r; return r;
if (r == 0)
return 0;
return 1; return 1;
} }

View File

@ -178,7 +178,7 @@ static int set_locale(int argc, char **argv, void *userdata) {
r = sd_bus_call(bus, m, 0, &error, NULL); r = sd_bus_call(bus, m, 0, &error, NULL);
if (r < 0) if (r < 0)
return log_error_errno(r, "Failed to issue method call: %s", bus_error_message(&error, -r)); return log_error_errno(r, "Failed to issue method call: %s", bus_error_message(&error, r));
return 0; return 0;
} }
@ -218,7 +218,7 @@ static int set_vconsole_keymap(int argc, char **argv, void *userdata) {
NULL, NULL,
"ssbb", map, toggle_map, arg_convert, arg_ask_password); "ssbb", map, toggle_map, arg_convert, arg_ask_password);
if (r < 0) if (r < 0)
return log_error_errno(r, "Failed to set keymap: %s", bus_error_message(&error, -r)); return log_error_errno(r, "Failed to set keymap: %s", bus_error_message(&error, r));
return 0; return 0;
} }
@ -260,7 +260,7 @@ static int set_x11_keymap(int argc, char **argv, void *userdata) {
"ssssbb", layout, model, variant, options, "ssssbb", layout, model, variant, options,
arg_convert, arg_ask_password); arg_convert, arg_ask_password);
if (r < 0) if (r < 0)
return log_error_errno(r, "Failed to set keymap: %s", bus_error_message(&error, -r)); return log_error_errno(r, "Failed to set keymap: %s", bus_error_message(&error, r));
return 0; return 0;
} }

View File

@ -1022,7 +1022,7 @@ static int kill_session(int argc, char *argv[], void *userdata) {
&error, NULL, &error, NULL,
"ssi", argv[i], arg_kill_who, arg_signal); "ssi", argv[i], arg_kill_who, arg_signal);
if (r < 0) if (r < 0)
return log_error_errno(r, "Could not kill session: %s", bus_error_message(&error, -r)); return log_error_errno(r, "Could not kill session: %s", bus_error_message(&error, r));
} }
return 0; return 0;
@ -1071,7 +1071,7 @@ static int enable_linger(int argc, char *argv[], void *userdata) {
&error, NULL, &error, NULL,
"ubb", (uint32_t) uid, b, true); "ubb", (uint32_t) uid, b, true);
if (r < 0) if (r < 0)
return log_error_errno(r, "Could not enable linger: %s", bus_error_message(&error, -r)); return log_error_errno(r, "Could not enable linger: %s", bus_error_message(&error, r));
} }
return 0; return 0;
@ -1096,7 +1096,7 @@ static int terminate_user(int argc, char *argv[], void *userdata) {
r = bus_call_method(bus, bus_login_mgr, "TerminateUser", &error, NULL, "u", (uint32_t) uid); r = bus_call_method(bus, bus_login_mgr, "TerminateUser", &error, NULL, "u", (uint32_t) uid);
if (r < 0) if (r < 0)
return log_error_errno(r, "Could not terminate user: %s", bus_error_message(&error, -r)); return log_error_errno(r, "Could not terminate user: %s", bus_error_message(&error, r));
} }
return 0; return 0;
@ -1129,7 +1129,7 @@ static int kill_user(int argc, char *argv[], void *userdata) {
&error, NULL, &error, NULL,
"ui", (uint32_t) uid, arg_signal); "ui", (uint32_t) uid, arg_signal);
if (r < 0) if (r < 0)
return log_error_errno(r, "Could not kill user: %s", bus_error_message(&error, -r)); return log_error_errno(r, "Could not kill user: %s", bus_error_message(&error, r));
} }
return 0; return 0;
@ -1154,7 +1154,7 @@ static int attach(int argc, char *argv[], void *userdata) {
&error, NULL, &error, NULL,
"ssb", argv[1], argv[i], true); "ssb", argv[1], argv[i], true);
if (r < 0) if (r < 0)
return log_error_errno(r, "Could not attach device: %s", bus_error_message(&error, -r)); return log_error_errno(r, "Could not attach device: %s", bus_error_message(&error, r));
} }
return 0; return 0;
@ -1172,7 +1172,7 @@ static int flush_devices(int argc, char *argv[], void *userdata) {
r = bus_call_method(bus, bus_login_mgr, "FlushDevices", &error, NULL, "b", true); r = bus_call_method(bus, bus_login_mgr, "FlushDevices", &error, NULL, "b", true);
if (r < 0) if (r < 0)
return log_error_errno(r, "Could not flush devices: %s", bus_error_message(&error, -r)); return log_error_errno(r, "Could not flush devices: %s", bus_error_message(&error, r));
return 0; return 0;
} }
@ -1194,7 +1194,7 @@ static int lock_sessions(int argc, char *argv[], void *userdata) {
&error, NULL, &error, NULL,
NULL); NULL);
if (r < 0) if (r < 0)
return log_error_errno(r, "Could not lock sessions: %s", bus_error_message(&error, -r)); return log_error_errno(r, "Could not lock sessions: %s", bus_error_message(&error, r));
return 0; return 0;
} }
@ -1213,7 +1213,7 @@ static int terminate_seat(int argc, char *argv[], void *userdata) {
r = bus_call_method(bus, bus_login_mgr, "TerminateSeat", &error, NULL, "s", argv[i]); r = bus_call_method(bus, bus_login_mgr, "TerminateSeat", &error, NULL, "s", argv[i]);
if (r < 0) if (r < 0)
return log_error_errno(r, "Could not terminate seat: %s", bus_error_message(&error, -r)); return log_error_errno(r, "Could not terminate seat: %s", bus_error_message(&error, r));
} }
return 0; return 0;

View File

@ -720,7 +720,7 @@ static int show_machine(int argc, char *argv[], void *userdata) {
r = bus_call_method(bus, bus_machine_mgr, "GetMachine", &error, &reply, "s", argv[i]); r = bus_call_method(bus, bus_machine_mgr, "GetMachine", &error, &reply, "s", argv[i]);
if (r < 0) if (r < 0)
return log_error_errno(r, "Could not get path to machine: %s", bus_error_message(&error, -r)); return log_error_errno(r, "Could not get path to machine: %s", bus_error_message(&error, r));
r = sd_bus_message_read(reply, "o", &path); r = sd_bus_message_read(reply, "o", &path);
if (r < 0) if (r < 0)
@ -1037,7 +1037,7 @@ static int show_image(int argc, char *argv[], void *userdata) {
r = bus_call_method(bus, bus_machine_mgr, "GetImage", &error, &reply, "s", argv[i]); r = bus_call_method(bus, bus_machine_mgr, "GetImage", &error, &reply, "s", argv[i]);
if (r < 0) if (r < 0)
return log_error_errno(r, "Could not get path to image: %s", bus_error_message(&error, -r)); return log_error_errno(r, "Could not get path to image: %s", bus_error_message(&error, r));
r = sd_bus_message_read(reply, "o", &path); r = sd_bus_message_read(reply, "o", &path);
if (r < 0) if (r < 0)
@ -1073,7 +1073,7 @@ static int kill_machine(int argc, char *argv[], void *userdata) {
NULL, NULL,
"ssi", argv[i], arg_kill_who, arg_signal); "ssi", argv[i], arg_kill_who, arg_signal);
if (r < 0) if (r < 0)
return log_error_errno(r, "Could not kill machine: %s", bus_error_message(&error, -r)); return log_error_errno(r, "Could not kill machine: %s", bus_error_message(&error, r));
} }
return 0; return 0;
@ -1105,7 +1105,7 @@ static int terminate_machine(int argc, char *argv[], void *userdata) {
for (int i = 1; i < argc; i++) { for (int i = 1; i < argc; i++) {
r = bus_call_method(bus, bus_machine_mgr, "TerminateMachine", &error, NULL, "s", argv[i]); r = bus_call_method(bus, bus_machine_mgr, "TerminateMachine", &error, NULL, "s", argv[i]);
if (r < 0) if (r < 0)
return log_error_errno(r, "Could not terminate machine: %s", bus_error_message(&error, -r)); return log_error_errno(r, "Could not terminate machine: %s", bus_error_message(&error, r));
} }
return 0; return 0;
@ -1184,7 +1184,7 @@ static int bind_mount(int argc, char *argv[], void *userdata) {
arg_read_only, arg_read_only,
arg_mkdir); arg_mkdir);
if (r < 0) if (r < 0)
return log_error_errno(r, "Failed to bind mount: %s", bus_error_message(&error, -r)); return log_error_errno(r, "Failed to bind mount: %s", bus_error_message(&error, r));
return 0; return 0;
} }
@ -1347,7 +1347,7 @@ static int login_machine(int argc, char *argv[], void *userdata) {
r = bus_call_method(bus, bus_machine_mgr, "OpenMachineLogin", &error, &reply, "s", machine); r = bus_call_method(bus, bus_machine_mgr, "OpenMachineLogin", &error, &reply, "s", machine);
if (r < 0) if (r < 0)
return log_error_errno(r, "Failed to get login PTY: %s", bus_error_message(&error, -r)); return log_error_errno(r, "Failed to get login PTY: %s", bus_error_message(&error, r));
r = sd_bus_message_read(reply, "hs", &master, NULL); r = sd_bus_message_read(reply, "hs", &master, NULL);
if (r < 0) if (r < 0)
@ -1430,7 +1430,7 @@ static int shell_machine(int argc, char *argv[], void *userdata) {
r = sd_bus_call(bus, m, 0, &error, &reply); r = sd_bus_call(bus, m, 0, &error, &reply);
if (r < 0) if (r < 0)
return log_error_errno(r, "Failed to get shell PTY: %s", bus_error_message(&error, -r)); return log_error_errno(r, "Failed to get shell PTY: %s", bus_error_message(&error, r));
r = sd_bus_message_read(reply, "hs", &master, NULL); r = sd_bus_message_read(reply, "hs", &master, NULL);
if (r < 0) if (r < 0)
@ -1485,7 +1485,7 @@ static int rename_image(int argc, char *argv[], void *userdata) {
NULL, NULL,
"ss", argv[1], argv[2]); "ss", argv[1], argv[2]);
if (r < 0) if (r < 0)
return log_error_errno(r, "Could not rename image: %s", bus_error_message(&error, -r)); return log_error_errno(r, "Could not rename image: %s", bus_error_message(&error, r));
return 0; return 0;
} }
@ -1535,7 +1535,7 @@ static int read_only_image(int argc, char *argv[], void *userdata) {
r = bus_call_method(bus, bus_machine_mgr, "MarkImageReadOnly", &error, NULL, "sb", argv[1], b); r = bus_call_method(bus, bus_machine_mgr, "MarkImageReadOnly", &error, NULL, "sb", argv[1], b);
if (r < 0) if (r < 0)
return log_error_errno(r, "Could not mark image read-only: %s", bus_error_message(&error, -r)); return log_error_errno(r, "Could not mark image read-only: %s", bus_error_message(&error, r));
return 0; return 0;
} }
@ -1552,7 +1552,7 @@ static int image_exists(sd_bus *bus, const char *name) {
if (sd_bus_error_has_name(&error, BUS_ERROR_NO_SUCH_IMAGE)) if (sd_bus_error_has_name(&error, BUS_ERROR_NO_SUCH_IMAGE))
return 0; return 0;
return log_error_errno(r, "Failed to check whether image %s exists: %s", name, bus_error_message(&error, -r)); return log_error_errno(r, "Failed to check whether image %s exists: %s", name, bus_error_message(&error, r));
} }
return 1; return 1;
@ -1617,7 +1617,7 @@ static int start_machine(int argc, char *argv[], void *userdata) {
&reply, &reply,
"ss", unit, "fail"); "ss", unit, "fail");
if (r < 0) if (r < 0)
return log_error_errno(r, "Failed to start unit: %s", bus_error_message(&error, -r)); return log_error_errno(r, "Failed to start unit: %s", bus_error_message(&error, r));
r = sd_bus_message_read(reply, "o", &object); r = sd_bus_message_read(reply, "o", &object);
if (r < 0) if (r < 0)
@ -1697,7 +1697,7 @@ static int enable_machine(int argc, char *argv[], void *userdata) {
r = sd_bus_call(bus, m, 0, &error, &reply); r = sd_bus_call(bus, m, 0, &error, &reply);
if (r < 0) if (r < 0)
return log_error_errno(r, "Failed to enable or disable unit: %s", bus_error_message(&error, -r)); return log_error_errno(r, "Failed to enable or disable unit: %s", bus_error_message(&error, r));
if (streq(argv[0], "enable")) { if (streq(argv[0], "enable")) {
r = sd_bus_message_read(reply, "b", NULL); r = sd_bus_message_read(reply, "b", NULL);
@ -1719,7 +1719,7 @@ static int enable_machine(int argc, char *argv[], void *userdata) {
NULL, NULL,
NULL); NULL);
if (r < 0) { if (r < 0) {
log_error("Failed to reload daemon: %s", bus_error_message(&error, -r)); log_error("Failed to reload daemon: %s", bus_error_message(&error, r));
goto finish; goto finish;
} }
@ -1831,7 +1831,7 @@ static int transfer_image_common(sd_bus *bus, sd_bus_message *m) {
r = sd_bus_call(bus, m, 0, &error, &reply); r = sd_bus_call(bus, m, 0, &error, &reply);
if (r < 0) if (r < 0)
return log_error_errno(r, "Failed to transfer image: %s", bus_error_message(&error, -r)); return log_error_errno(r, "Failed to transfer image: %s", bus_error_message(&error, r));
r = sd_bus_message_read(reply, "uo", &id, &path); r = sd_bus_message_read(reply, "uo", &id, &path);
if (r < 0) if (r < 0)
@ -2272,7 +2272,7 @@ static int list_transfers(int argc, char *argv[], void *userdata) {
r = bus_call_method(bus, bus_import_mgr, "ListTransfers", &error, &reply, NULL); r = bus_call_method(bus, bus_import_mgr, "ListTransfers", &error, &reply, NULL);
if (r < 0) if (r < 0)
return log_error_errno(r, "Could not get transfers: %s", bus_error_message(&error, -r)); return log_error_errno(r, "Could not get transfers: %s", bus_error_message(&error, r));
r = sd_bus_message_enter_container(reply, 'a', "(usssdo)"); r = sd_bus_message_enter_container(reply, 'a', "(usssdo)");
if (r < 0) if (r < 0)
@ -2369,7 +2369,7 @@ static int cancel_transfer(int argc, char *argv[], void *userdata) {
r = bus_call_method(bus, bus_import_mgr, "CancelTransfer", &error, NULL, "u", id); r = bus_call_method(bus, bus_import_mgr, "CancelTransfer", &error, NULL, "u", id);
if (r < 0) if (r < 0)
return log_error_errno(r, "Could not cancel transfer: %s", bus_error_message(&error, -r)); return log_error_errno(r, "Could not cancel transfer: %s", bus_error_message(&error, r));
} }
return 0; return 0;

View File

@ -704,7 +704,7 @@ static int dhcp4_address_ready_callback(Address *address) {
r = dhcp4_start_acd(link); r = dhcp4_start_acd(link);
if (r < 0) if (r < 0)
return log_link_error_errno(link, r, "Failed to start IPv4ACD for DHCP4 adddress: %m"); return log_link_error_errno(link, r, "Failed to start IPv4ACD for DHCP4 address: %m");
dhcp4_check_ready(link); dhcp4_check_ready(link);
return 0; return 0;

View File

@ -66,7 +66,7 @@
/* Hard lower limit for new partition sizes */ /* Hard lower limit for new partition sizes */
#define HARD_MIN_SIZE 4096 #define HARD_MIN_SIZE 4096
/* libfdisk takes off sightly more than 1M of the disk size when creating a GPT disk label */ /* libfdisk takes off slightly more than 1M of the disk size when creating a GPT disk label */
#define GPT_METADATA_SIZE (1044*1024) #define GPT_METADATA_SIZE (1044*1024)
/* LUKS2 takes off 16M of the partition size with its metadata by default */ /* LUKS2 takes off 16M of the partition size with its metadata by default */

View File

@ -648,7 +648,7 @@ static int manager_dns_stub_fd_extra(Manager *m, DnsStubListenerExtra *l, int ty
if (r < 0) if (r < 0)
goto fail; goto fail;
/* Do not set IP_TTL for extra DNS stub listners, as the address may not be local and in that case /* Do not set IP_TTL for extra DNS stub listeners, as the address may not be local and in that case
* people may want ttl > 1. */ * people may want ttl > 1. */
r = socket_set_freebind(fd, l->family, true); r = socket_set_freebind(fd, l->family, true);

View File

@ -1146,7 +1146,7 @@ static int start_transient_service(
&pty_reply, &pty_reply,
"s", arg_host); "s", arg_host);
if (r < 0) if (r < 0)
return log_error_errno(r, "Failed to get machine PTY: %s", bus_error_message(&error, -r)); return log_error_errno(r, "Failed to get machine PTY: %s", bus_error_message(&error, r));
r = sd_bus_message_read(pty_reply, "hs", &master, &s); r = sd_bus_message_read(pty_reply, "hs", &master, &s);
if (r < 0) if (r < 0)
@ -1468,7 +1468,7 @@ static int start_transient_scope(sd_bus *bus) {
r = sd_bus_call(bus, m, 0, &error, &reply); r = sd_bus_call(bus, m, 0, &error, &reply);
if (r < 0) if (r < 0)
return log_error_errno(r, "Failed to start transient scope unit: %s", bus_error_message(&error, -r)); return log_error_errno(r, "Failed to start transient scope unit: %s", bus_error_message(&error, r));
r = sd_bus_message_read(reply, "o", &object); r = sd_bus_message_read(reply, "o", &object);
if (r < 0) if (r < 0)
@ -1688,7 +1688,7 @@ static int start_transient_trigger(
r = sd_bus_call(bus, m, 0, &error, &reply); r = sd_bus_call(bus, m, 0, &error, &reply);
if (r < 0) if (r < 0)
return log_error_errno(r, "Failed to start transient %s unit: %s", suffix + 1, bus_error_message(&error, -r)); return log_error_errno(r, "Failed to start transient %s unit: %s", suffix + 1, bus_error_message(&error, r));
r = sd_bus_message_read(reply, "o", &object); r = sd_bus_message_read(reply, "o", &object);
if (r < 0) if (r < 0)

View File

@ -36,7 +36,7 @@ static int populate_uid_cache(const char *root, Hashmap **ret) {
if (!cache) if (!cache)
return -ENOMEM; return -ENOMEM;
/* The directory list is harcoded here: /etc is the standard, and rpm-ostree uses /usr/lib. This /* The directory list is hardcoded here: /etc is the standard, and rpm-ostree uses /usr/lib. This
* could be made configurable, but I don't see the point right now. */ * could be made configurable, but I don't see the point right now. */
const char *fname; const char *fname;

View File

@ -210,7 +210,7 @@ typedef struct RecoveryKey {
/* The type of recovery key, must be "modhex64" right now */ /* The type of recovery key, must be "modhex64" right now */
char *type; char *type;
/* A UNIX pasword hash of the normalized form of modhex64 */ /* A UNIX password hash of the normalized form of modhex64 */
char *hashed_password; char *hashed_password;
} RecoveryKey; } RecoveryKey;

View File

@ -1045,10 +1045,8 @@ int varlink_wait(Varlink *v, usec_t timeout) {
return events; return events;
r = fd_wait_for_event(fd, events, t); r = fd_wait_for_event(fd, events, t);
if (r < 0) if (r <= 0)
return r; return r;
if (r == 0)
return 0;
handle_revents(v, r); handle_revents(v, r);
return 1; return 1;

View File

@ -2,6 +2,7 @@
#include "env-file.h" #include "env-file.h"
#include "fd-util.h" #include "fd-util.h"
#include "fileio.h"
#include "fs-util.h" #include "fs-util.h"
#include "macro.h" #include "macro.h"
#include "strv.h" #include "strv.h"
@ -132,6 +133,46 @@ static void test_load_env_file_5(void) {
assert_se(data[2] == NULL); assert_se(data[2] == NULL);
} }
static void test_write_and_load_env_file(void) {
const char *v;
/* Make sure that our writer, parser and the shell agree on what our env var files mean */
FOREACH_STRING(v,
"obbardc-laptop",
"obbardc\\-laptop",
"obbardc-lap\\top",
"obbardc-lap\\top",
"obbardc-lap\\\\top",
"double\"quote",
"single\'quote",
"dollar$dollar",
"newline\nnewline") {
_cleanup_(unlink_and_freep) char *p = NULL;
_cleanup_strv_free_ char **l = NULL;
_cleanup_free_ char *j = NULL, *w = NULL, *cmd = NULL, *from_shell = NULL;
_cleanup_fclose_ FILE *f = NULL;
size_t sz;
assert_se(tempfn_random_child(NULL, NULL, &p) >= 0);
assert_se(j = strjoin("TEST=", v));
assert_se(write_env_file(p, STRV_MAKE(j)) >= 0);
assert_se(cmd = strjoin(". ", p, " && /bin/echo -n \"$TEST\""));
assert_se(f = popen(cmd, "re"));
assert_se(read_full_stream(f, &from_shell, &sz) >= 0);
assert_se(sz == strlen(v));
assert_se(streq(from_shell, v));
assert_se(load_env_file(NULL, p, &l) >= 0);
assert_se(strv_equal(l, STRV_MAKE(j)));
assert_se(parse_env_file(NULL, p, "TEST", &w) >= 0);
assert_se(streq_ptr(w, v));
}
}
int main(int argc, char *argv[]) { int main(int argc, char *argv[]) {
test_setup_logging(LOG_INFO); test_setup_logging(LOG_INFO);
@ -140,4 +181,8 @@ int main(int argc, char *argv[]) {
test_load_env_file_3(); test_load_env_file_3();
test_load_env_file_4(); test_load_env_file_4();
test_load_env_file_5(); test_load_env_file_5();
test_write_and_load_env_file();
return 0;
} }

View File

@ -151,6 +151,18 @@ static void test_parse_env_file(void) {
assert_se(r >= 0); assert_se(r >= 0);
} }
static void test_one_shell_var(const char *file, const char *variable, const char *value) {
_cleanup_free_ char *cmd = NULL, *from_shell = NULL;
_cleanup_fclose_ FILE *f = NULL;
size_t sz;
assert_se(cmd = strjoin(". ", file, " && /bin/echo -n \"$", variable, "\""));
assert_se(f = popen(cmd, "re"));
assert_se(read_full_stream(f, &from_shell, &sz) >= 0);
assert_se(sz == strlen(value));
assert_se(streq(from_shell, value));
}
static void test_parse_multiline_env_file(void) { static void test_parse_multiline_env_file(void) {
_cleanup_(unlink_tempfilep) char _cleanup_(unlink_tempfilep) char
t[] = "/tmp/test-fileio-in-XXXXXX", t[] = "/tmp/test-fileio-in-XXXXXX",
@ -162,8 +174,8 @@ static void test_parse_multiline_env_file(void) {
assert_se(fmkostemp_safe(t, "w", &f) == 0); assert_se(fmkostemp_safe(t, "w", &f) == 0);
fputs("one=BAR\\\n" fputs("one=BAR\\\n"
" VAR\\\n" "\\ \\ \\ \\ VAR\\\n"
"\tGAR\n" "\\\tGAR\n"
"#comment\n" "#comment\n"
"two=\"bar\\\n" "two=\"bar\\\n"
" var\\\n" " var\\\n"
@ -173,9 +185,13 @@ static void test_parse_multiline_env_file(void) {
" var \\\n" " var \\\n"
"\tgar \"\n", f); "\tgar \"\n", f);
fflush(f); assert_se(fflush_and_check(f) >= 0);
fclose(f); fclose(f);
test_one_shell_var(t, "one", "BAR VAR\tGAR");
test_one_shell_var(t, "two", "bar var\tgar");
test_one_shell_var(t, "tri", "bar var \tgar ");
r = load_env_file(NULL, t, &a); r = load_env_file(NULL, t, &a);
assert_se(r >= 0); assert_se(r >= 0);

View File

@ -528,7 +528,7 @@ static int dir_cleanup(
continue; continue;
/* If statx() is supported, use it. It's preferable over fstatat() since it tells us /* If statx() is supported, use it. It's preferable over fstatat() since it tells us
* explicitly where we are looking at a mount point, for free as side information. Determing * explicitly where we are looking at a mount point, for free as side information. Determining
* the same information without statx() is hard, see the complexity of path_is_mount_point(), * the same information without statx() is hard, see the complexity of path_is_mount_point(),
* and also much slower as it requires a number of syscalls instead of just one. Hence, when * and also much slower as it requires a number of syscalls instead of just one. Hence, when
* we have modern statx() we use it instead of fstat() and do proper mount point checks, * we have modern statx() we use it instead of fstat() and do proper mount point checks,