This is similar to string_hash_ops but operates one file system paths
specifically. It will ensure that "/foo//bar" and "///foo/bar" are
considered to be the same path for hashmap purposes.
This makes use of the existing path_compare() API, and adds a matching
hashing function for it.
Note that relative and absolute paths will hash to different values,
however whether the path is suffixed with a slash or not is not
detected. This matches the existing path_compare() behaviour, and
follows the logic that on Linux there can't be two different objects at
path /foo/bar and /foo/bar/ either.
This adds some paranoia code that moves some of the fds we allocate for
longer periods of times to fds > 2 if they are allocated below this
boundary. This is a paranoid safety thing, in order to avoid that
external code might end up erroneously use our fds under the assumption
they were valid stdin/stdout/stderr. Think: some app closes
stdin/stdout/stderr and then invokes 'fprintf(stderr, …' which causes
writes on our fds.
This both adds the helper to do the moving as well as ports over a
number of users to this new logic. Since we don't want to litter all our
code with invocations of this I tried to strictly focus on fds we keep
open for long periods of times only and only in code that is frequently
loaded into foreign programs (under the assumptions that in our own
codebase we are smart enough to always keep stdin/stdout/stderr
allocated to avoid this pitfall). Specifically this means all code used
by NSS and our sd-xyz API:
1. our logging APIs
2. sd-event
3. sd-bus
4. sd-resolve
5. sd-netlink
This changed was inspired by this:
https://github.com/systemd/systemd/issues/8075#issuecomment-363689755
This shows that apparently IRL there are programs that do close
stdin/stdout/stderr, and we should accomodate for that.
Note that this won't fix any bugs, this just makes sure that buggy
programs are less likely to interfere with out own code.
we still invoke ssh unnecessarily when there in incompatible or erreneous input
The fallow-up to finish that would make the code a bit more verbose,
as it would require repeating this bit:
```
r = bus_connect_transport(arg_transport, arg_host, false, &bus);
if (r < 0) {
log_error_errno(r, "Failed to create bus connection: %m");
goto finish;
}
sd_bus_set_allow_interactive_authorization(bus, arg_ask_password);
```
in every verb, after parsing.
v2: add waitpid() to avoid a zombie process, switch to SIGTERM from SIGKILL
v3: refactor, wait in bus_start_address()
We have the raw_getpid() definition in place anyway, and it's certainly
beneficial to expose the same semantics on pre glibc 2.24 and after it
too, hence always bypass glibc for this, and always cache things on our
side.
Fixes: #8113
gcc says:
[196/1142] Compiling C object 'src/basic/basic@sta/hashmap.c.o'.
../src/basic/hashmap.c: In function ‘cachemem_maintain’:
../src/basic/hashmap.c:1913:17: warning: suggest parentheses around assignment used as truth value [-Wparentheses]
mem->active = r = true;
^~~
which conflates two things: the first is transitive assignent a = b = c = d;
the second is assignment of the value of an expression, which happens to be a
an assignment expression here, and boolean. While the second _should_ be
parenthesized, the first should _not_, and it's more natural to understand
our code as the first, and gcc should treat this as an exception and not emit
the warning. But since it's a while until this will be fixed, let's update
our code too.
When used in a package installation script, we want to invoke systemd-sysusers
before that package is installed (so it can contain files owned by the newly
created user), so the configuration to use is specified on the command
line. This should be a copy of the configuration that will be installed as
/usr/lib/sysusers.d/package.conf. We still want to obey any overrides in
/etc/sysusers.d or /run/sysusers.d in the usual fashion. Otherwise, we'd get a
different result when systemd-sysusers is run with a copy of the new config on
the command line and when systemd-sysusers is run at boot after package
instalation. In the second case any files in /etc or /run have higher priority,
so the same should happen when the configuration is given on the command line.
More generally, we want the behaviour in this special case to be as close to
the case where the file is finally on disk as possible, so we have to read all
configuration files, since they all might contain overrides and additional
configuration that matters. Even files that have lower priority might specify
additional groups for the user we are creating. Thus, we need to read all
configuration, but insert our new configuration somewhere with the right
priority.
If --target=/path/to/file.conf is given on the command line, we gather the list
of files, and pretend that the command-line config is read from
/path/to/file.conf (doesn't matter if the file on disk actually exists or
not). All package scripts should use this option to obtain consistent and
idempotent behaviour.
The corner case when --target= is specified and there are no positional
arguments is disallowed.
v1:
- version with --config-name=
v2:
- disallow --config-name= and no positional args
v3:
- remove --config-name=
v4:
- add --target= and rework the code completely
v5:
- fix argcounting bug and add example in man page
v6:
- rename --target to --replace
This is the first error message when running unprivileged, and the message is
unspecific, so let's at least add some logging at debug level to make this less
confusing.
The function `strv_join_quoted()` is now not used, and has a bug
in the buffer size calculation when the strings needs to escaped,
as reported in #8056.
So, let's remove the function.
Closes#8056.
Red is used for highligting, the same as grep does. Except when the line is
highlighted red already, because it has high priority, in which case plain ansi
highlight is used for the matched substring.
Coloring is implemented for short and cat outputs, and not for other types.
I guess we could also add it for verbose output in the future.
Adds the basics of the IteratedCache and constructor support for the
Hashmap and OrderedHashmap types.
iterated_cache_get() is responsible for synchronizing the cache with
the associated Hashmap and making it available to the caller at the
supplied result pointers. Since iterated_cache_get() may need to
allocate memory, it may fail, so callers must check the return value.
On success, pointer arrays containing pointers to the associated
Hashmap's keys and values, in as-iterated order, are returned in
res_keys and res_values, respectively. Either may be supplied as NULL
to inhibit caching of the keys or values, respectively.
Note that if the cached Hashmap hasn't changed since the previous call
to iterated_cache_get(), and it's not a call activating caching of the
values or keys, the cost is effectively zero as the resulting pointers
will simply refer to the previously returned arrays as-is.
A cleanup function has also been added, iterated_cache_free().
This only frees the IteratedCache container and related arrays. The
associated Hashmap, its keys, and values are not affected. Also note
that the associated Hashmap does not automatically free its associated
IteratedCache when freed.
One could, in theory, safely access the arrays returned by a
successful iterated_cache_get() call after its associated Hashmap has
been freed, including the referenced values and keys. Provided the
iterated_cache_get() was performed prior to the hashmap free, and that
the type of hashmap free performed didn't free keys and/or values as
well.
log_open_console() did not switch from stderr to /dev/console, when
"always_reopen_console" was set. It was necessary to call
log_close_console() first.
By contrast, log_open() did switch between e.g. journald and kmsg according
to the value of "prohibit_ipc".
Let's fix log_open() to respect the values of all the log options, and we
can make log_close_*() private.
Also log_close_console() is changed. There was some precaution, avoiding
closing the console fd if we are not PID 1. I think commit 48a601fe made
a little mistake in leaving this in, and it only served to confuse
readers :).
Also I changed systemd-shutdown. Now we have log_set_prohibit_ipc(), let's
use it to clarify that systemd-shutdown is not expected to try and log via
journald (which it is about to kill). We avoided ever asking it to, but
it's more convenient for the reader if they don't have to think about that.
In that sense, it's similar to using assert() to validate a function's
arguments.
This removes LOG_TARGET_SAFE. It's made redundant by the new
"prohibit-ipc" logging flag, as it used to have a similar effect: avoid
logging to the journal/syslog, i.e. any local services in order to avoid
deadlocks when we lock from PID 1 or its utility processes (such as
generators).
All previous users of LOG_TARGET_SAFE are switched over to the new
setting. This makes things a bit safer for all, as not even the
SYSTEMD_LOG_TARGET env var can be used to accidentally log to the
journal anymore in these programs.
If set, we'll avoid logging to any IPC log targets, i.e. syslog or the
journal, but allow stderr, kmsg, console logging.
This is useful as PID 1 wants to turn this off explicitly as long as the
journal is not up.
Previously we'd open/close the log stream to these services whenever
needed but this is incompatible with the "open_when_needed" logic
introduced in #6915, which might open the log streams whenever it likes,
including possibly inside of the child process we fork off that'll
become journald later on. Hence, let's make this all explicit, and
instead of managing when we open/close log streams add a boolean that
clearly prohibits the IPC targets when needed, so that opening can be
done at any time, but will honour this.
See: #7985
This doesn't matter much, and we don't rely on it, but I think it's much
nicer if we log_set_target() and log_set_upgrade_syslog_to_journal() can
be called in either order and have the same effect.
The maximum number of processes a tasks on the system is usually lower
than what pid_t would allow, and is compiled into the kernel (and
documented in proc(5)). Let's add proper defines for that, so that
we can adjust the pid_max sysctl without fearing invalid accesses.
The commit f14f1806e3 introduced CHASE_SAFE
flag. When the flag is set, then `fd_parent` may not be properly closed.
This sets `_cleanup_close_` attribute to `fd_parent`.
Thus, now `fd_parent` is always closed properly.
The commit b1bfb84804 makes chase_symlinks()
recognize empty string for root as an invalid parameter. However,
empty root is often used e.g. systemd-nspawn.
This makes chase_symlinks() support empty string safely.
Fixes#7927.
If we take a relative path we first make it absolute, based on the
current working directory. But if CHASE_PREFIX_ROOT is passe we are
supposed to make the path absolute taking the specified root path into
account, but that makes no sense if we talk about the current working
directory as that is relative to the host's root in any case. Hence,
let's refuse this politely.