IF YOU WOULD LIKE TO GET AN ACCOUNT, please write an
email to Administrator. User accounts are meant only to access repo
and report issues and/or generate pull requests.
This is a purpose-specific Git hosting for
BaseALT
projects. Thank you for your understanding!
Только зарегистрированные пользователи имеют доступ к сервису!
Для получения аккаунта, обратитесь к администратору.
This changes real_journal_next() to leverage the IteratedCache for
accelerating iteration across the open journal files.
journalctl timing comparisons with 100 journal files of 8MiB size
party to this boot:
Pre (~v235):
# time ./journalctl -b --no-pager > /dev/null
real 0m9.613s
user 0m9.560s
sys 0m0.053s
# time ./journalctl -b --no-pager > /dev/null
real 0m9.548s
user 0m9.525s
sys 0m0.023s
# time ./journalctl -b --no-pager > /dev/null
real 0m9.612s
user 0m9.582s
sys 0m0.030s
Post-IteratedCache:
# time ./journalctl -b --no-pager > /dev/null
real 0m8.449s
user 0m8.425s
sys 0m0.024s
# time ./journalctl -b --no-pager > /dev/null
real 0m8.409s
user 0m8.382s
sys 0m0.027s
# time ./journalctl -b --no-pager > /dev/null
real 0m8.410s
user 0m8.350s
sys 0m0.061s
~12.5% improvement, the benefit increases the more log files there are.
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.
When using SELinux with legacy cgroups the tmpfs on /sys/fs/cgroup is by
default labelled as tmpfs_t. This label is also inherited by the "cpu"
and "cpuacct" symbolic links. Unfortunately the policy expects them to
be labelled as cgroup_t, which is used for all the actual cgroup
filesystems. Failure to do so results in a stream of denials.
This state cannot be fixed reliably when the cgroup filesystem structure
is set-up as the SELinux policy is not yet loaded at this
moment. It also cannot be fixed later as the root of the cgroup
filesystem is remounted read-only. In order to fix it the root of the
cgroup filesystem needs to be temporary remounted read-write, relabelled
and remounted back read-only.
This makes sure we migrate /var/lib/<foo> if it exists to
/var/lib/private/<foo> if DynamicUser=1 is set. This is useful to allow
turning on DynamicUser= on services that previously didn't use it, and
we can deal with this, and migrate the relevant directories as
necessary.
Note that "downgrading" from DynamicUser=1 backto DynamicUser=0 works
too. However in that case we simply continue to use
/var/lib/private/<foo>, which works because /var/lib/<foo> is a symlink
there after all.
Let's always leave logging to the call that actually added the fields to
the bus message. This way we don't get duplicate logging whenver
bus_append_unit_property_assignment() ends up being called, which does
all its logging on its own (and probably should do, as it can output
much more precise errors).
IN_SET only works for constant values, hence clarify that. Moreover, we
declared a statement "s" we never made use of. Drop it.
Also, for both scripts, let's support 10 items. More causes spatch to
die with "Stack overflow" for me.
Unfortunately, there are far too many properties currently not
accessible to transient units. The first step to opening them all up is
to figure out which ones they are.
This changes the unit search path logic to never drop the transient and
control directories from the unit search path. This is necessary as we
add new entries to both during runtime, due to the "systemctl
set-property" and transient unit logic.
Previously, the "transient" directory was created during early boot to
deal with this, but the "control" directories were not covered like
that. Creating the control directories early at boot is not possible
however, as /etc might be read-only then, and we do define a persistent
control directory. Hence, let's create these dirs on-demand when we need
them, and make sure the search path clean-up logic never drops them from
the search path even if they are initially missing.
(Also, always create these paths properly labelled)
We shouldn't rely on C's incremental assignment of values of enums for
bit fields. That'll work only between the first two flags, but for
everything following will break horrible. Hence, let's avoid any
ambiguity here, and let's clearly define the flags as shifts of 1.
This message is displayed either when the unit file itself is newer than
what is loaded, but also when any of the drop-ins is newer. Say so in
the message, in order not to confuse the user unnecessarily.
Let's make sure that when we return a D-Bus error, we return a native
one, if we generate it ourselves, and use errno-based error
synthetization only if we received an errno ourselves. Yes, this makes
things slightly longer, but is highly misleading as we propagate D-Bus
errors, and not errnos to the client.
This majorly refactors the transient unit file and drop-in writing
logic, so that we properly C-escape and specifier-escape (% → %%)
everything we write out, so that when we read it back again, specifiers
are parsed that aren't supposed to be parsed.
This renames unit_write_drop_in() and friends by unit_write_setting().
The name change is supposed to clarify that the functions are not only
used to write drop-in files, but also transient unit files.
The previous "mode" parameter to this function is replaced by a more
generic "flags", which knows additional flags for implicit C-style and
specifier escaping before writing things out. This can cover most
properties where either form of escaping is defined. For the cases where
this isn't sufficient, we add helpers unit_escape_setting() and
unit_concat_strv() for escaping individual strings or strvs properly.
While we are at it, we also prettify generation of transient unit files:
we try to reduce the number of section headers written out: previously
we'd write the right section header our for each setting. With this
change we do so only if the setting lives in a different section than
the one before.
(This should also be considered preparation for when we add proper APIs
to systemd to write normal, persistant unit files through the bus API)
Let's always escape strings we receive from the user before writing them
out to unit file settings that suppor specifier expansion, so that user
strings are transported as-is.
Using specifiers in these settings isn't particularly useful by itself,
but it unifies behaviour a bit. It's kinda surprising that What= in
mount units resolves specifies, but Where= does not. Hence let's add
that too. Also, it's surprising Where=/What= in mount units behaves
differently than in automount and swap units, hence resolve specifiers
there too. Then, Type= in mount units is nowadays an arbitrary,
sometimes non-trivial string (think fuse!), hence let's also expand
specifiers there, to match the rest of the mount settings.
This has the benefit that when writing code that generates unit files,
less care has to be taken to check whether escaping of specifiers is
necessary or not: broadly everything that takes arbitrary user strings
now does specifier expansion, while enums/numerics/booleans do not.
We process C-style escapes in Environment=, hence we should process it
in UnsetEnvironment= too, as the latter accepts assignments much like
the former, including arbitrary values specified by the user.
All other cases where we accept a reboot argument are decoded with
config_parse_unit_string_printf() rather than
config_parse_unit_path_printf(), and that's really the only thing what
makes sense here, hence adjust this here, too.
The code in install-printf.c and unit-printf.c for these is pretty much
the same and very generic. Let's move this all over to the generic
specifier.c, and share the implementations.
Specifier expansion (much like C escape handling) should be a helper for
writing unit files, but should be nothing we do on programatic APIs. For
those, the client can do the necessary replacements anyway, and we
really should be careful with doing such string processing of data we
get via lower level programmatic APIs.
We currently do specifier expansion only for the env var transient unit
APIs, no other properties do this. Let's remove it here too, to be fully
systematic.
Yes, in a way this is API breakage, but then again this API isn't
documented yet, and an outlier, hence let's clear this up now, before it
is too late.