1
0
mirror of https://github.com/systemd/systemd.git synced 2024-12-22 17:35:35 +03:00

Compare commits

..

1 Commits

Author SHA1 Message Date
Luca Boccassi
3ac5952cc3
Merge 33319701ca into 8a135111ca 2024-12-19 22:30:45 -08:00
71 changed files with 428 additions and 1582 deletions

View File

@ -7,14 +7,6 @@ on:
# Calculate coverage daily at midnight # Calculate coverage daily at midnight
- cron: '0 0 * * *' - cron: '0 0 * * *'
pull_request:
branches:
- main
- v[0-9]+-stable
paths:
- .github/workflows/coverage.yml
- test/integration-test-wrapper.py
permissions: permissions:
contents: read contents: read
@ -24,7 +16,7 @@ jobs:
steps: steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683
- uses: systemd/mkosi@ba07d53000b6c560ad0b9f07550aca93c0284e88 - uses: systemd/mkosi@07ef37c4c0dad5dfc6cec86c967a7600df1cd88c
# Freeing up disk space with rm -rf can take multiple minutes. Since we don't need the extra free space # Freeing up disk space with rm -rf can take multiple minutes. Since we don't need the extra free space
# immediately, we remove the files in the background. However, we first move them to a different location # immediately, we remove the files in the background. However, we first move them to a different location
@ -57,6 +49,7 @@ jobs:
Distribution=arch Distribution=arch
[Build] [Build]
ToolsTree=default
ToolsTreeDistribution=arch ToolsTreeDistribution=arch
UseSubvolumes=yes UseSubvolumes=yes
WithTests=no WithTests=no
@ -71,7 +64,7 @@ jobs:
MESON_OPTIONS=--werror MESON_OPTIONS=--werror
COVERAGE=1 COVERAGE=1
[Runtime] [Host]
QemuMem=4G QemuMem=4G
EOF EOF

View File

@ -113,7 +113,7 @@ jobs:
steps: steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683
- uses: systemd/mkosi@ba07d53000b6c560ad0b9f07550aca93c0284e88 - uses: systemd/mkosi@c4bbf3b71a3e2cf947995caedf10f69da3c4957a
# Freeing up disk space with rm -rf can take multiple minutes. Since we don't need the extra free space # Freeing up disk space with rm -rf can take multiple minutes. Since we don't need the extra free space
# immediately, we remove the files in the background. However, we first move them to a different location # immediately, we remove the files in the background. However, we first move them to a different location
@ -152,6 +152,7 @@ jobs:
[Build] [Build]
UseSubvolumes=yes UseSubvolumes=yes
ToolsTree=default
ToolsTreeDistribution=fedora ToolsTreeDistribution=fedora
ToolsTreeRelease=rawhide ToolsTreeRelease=rawhide
@ -170,7 +171,7 @@ jobs:
[Content] [Content]
SELinuxRelabel=${{ matrix.relabel }} SELinuxRelabel=${{ matrix.relabel }}
[Runtime] [Host]
QemuMem=4G QemuMem=4G
EOF EOF

1
.gitignore vendored
View File

@ -7,7 +7,6 @@
.config.args .config.args
.gdb_history .gdb_history
.deps/ .deps/
.venv/
.mypy_cache/ .mypy_cache/
__pycache__/ __pycache__/
/*.gcda /*.gcda

18
TODO
View File

@ -122,18 +122,6 @@ Deprecations and removals:
Features: Features:
* importd: introduce a per-user instance, that downloads into per-user DDI dirs
* sysupdated: similar
* portabled: similar
* machined: implement a per-user instance, that manages per-user DDI dirs for
images. systemd-nspawn/systemd-vmspawn should probably register with both the
system and the user scoped machined instance. The former to get the machine
name registered as hostname, and the latter so that the image stuff is nicely
per-user managed.
* resolved: make resolved process DNR DHCP info * resolved: make resolved process DNR DHCP info
* Teach systemd-ssh-generator to generated an /run/issue.d/ drop-in telling * Teach systemd-ssh-generator to generated an /run/issue.d/ drop-in telling
@ -403,6 +391,8 @@ Features:
the bg via vmspawn/nspawn if not done so yet and then requests a shell inside the bg via vmspawn/nspawn if not done so yet and then requests a shell inside
it for the invoking user. it for the invoking user.
* importd/…: define per-user dirs for container/VM images too.
* add a new specifier to unit files that figures out the DDI the unit file is * add a new specifier to unit files that figures out the DDI the unit file is
from, tracing through overlayfs, DM, loopback block device. from, tracing through overlayfs, DM, loopback block device.
@ -456,6 +446,10 @@ Features:
* credentials: add a flag to the scoped credentials that if set require PK * credentials: add a flag to the scoped credentials that if set require PK
reauthentication when unlocking a secret. reauthentication when unlocking a secret.
* teach systemd --user to properly load credentials off disk, with
/etc/credstore equivalent and similar. Make sure that $CREDENTIALS_DIRECTORY=
actually works too when run with user privs.
* extend the smbios11 logic for passing credentials so that instead of passing * extend the smbios11 logic for passing credentials so that instead of passing
the credential data literally it can also just reference an AF_VSOCK CID/port the credential data literally it can also just reference an AF_VSOCK CID/port
to read them from. This way the data doesn't remain in the SMBIOS blob during to read them from. This way the data doesn't remain in the SMBIOS blob during

View File

@ -7,97 +7,94 @@ SPDX-License-Identifier: LGPL-2.1-or-later
# Hacking on systemd # Hacking on systemd
We welcome all contributions to systemd. If you notice a bug or a missing We welcome all contributions to systemd.
feature, please feel invited to fix it, and submit your work as a If you notice a bug or a missing feature, please feel invited to fix it, and submit your work as a
[GitHub Pull Request (PR)](https://github.com/systemd/systemd/pull/new). [GitHub Pull Request (PR)](https://github.com/systemd/systemd/pull/new).
Please make sure to follow our [Coding Style](/CODING_STYLE) when submitting Please make sure to follow our [Coding Style](/CODING_STYLE) when submitting patches.
patches. Also have a look at our [Contribution Guidelines](/CONTRIBUTING). Also have a look at our [Contribution Guidelines](/CONTRIBUTING).
When adding new functionality, tests should be added. For shared functionality When adding new functionality, tests should be added.
(in `src/basic/` and `src/shared/`) unit tests should be sufficient. The general For shared functionality (in `src/basic/` and `src/shared/`) unit tests should be sufficient.
policy is to keep tests in matching files underneath `src/test/`, e.g. The general policy is to keep tests in matching files underneath `src/test/`,
`src/test/test-path-util.c` contains tests for any functions in e.g. `src/test/test-path-util.c` contains tests for any functions in `src/basic/path-util.c`.
`src/basic/path-util.c`. If adding a new source file, consider adding a matching If adding a new source file, consider adding a matching test executable.
test executable. For features at a higher level, tests in `src/test/` are very For features at a higher level, tests in `src/test/` are very strongly recommended.
strongly recommended. If that is not possible, integration tests in `test/` are If that is not possible, integration tests in `test/` are encouraged.
encouraged. Please always test your work before submitting a PR.
## Hacking on systemd with mkosi Please always test your work before submitting a PR.
For many of the components of systemd testing is straightforward as you can simply compile systemd and run the relevant tool from the build directory.
[mkosi](https://mkosi.systemd.io/) is our swiss army knife for hacking on For some components (most importantly, systemd/PID 1 itself) this is not possible, however.
systemd. It makes sure all necessary dependencies are available to build systemd In order to simplify testing for cases like this we provide a set of `mkosi` config files directly in the source tree.
and allows building and booting an OS image with the latest systemd installed [mkosi](https://mkosi.systemd.io/)
for testing purposes. is a tool for building clean OS images from an upstream distribution in combination with a fresh build of the project in the local working directory.
To make use of this, please install `mkosi` from the [GitHub repository](https://github.com/systemd/mkosi#running-mkosi-from-the-repository).
First, install `mkosi` from the `mkosi` will build an image for the host distro by default.
[GitHub repository](https://github.com/systemd/mkosi#running-mkosi-from-the-repository). First, run `mkosi genkey` to generate a key and certificate to be used for secure boot and verity signing.
Note that it's not possible to use your distribution's packaged version of mkosi After that is done, it is sufficient to type `mkosi` in the systemd project directory to generate a disk image you can boot either in `systemd-nspawn` or in a UEFI-capable VM:
as mkosi has to be installed outside of `/usr` for the following steps to work.
Then, you can build and run systemd executables as follows:
```sh ```sh
$ mkosi -f sandbox meson setup build $ sudo mkosi boot # nspawn still needs sudo for now
$ mkosi -f sandbox ninja -C build
$ mkosi -f sandbox build/systemctl --version
``` ```
To build and boot an OS image with the latest systemd installed: or:
```sh ```sh
$ mkosi -f genkey # Generate signing keys once. $ mkosi qemu
$ mkosi -f sandbox ninja -C build mkosi # (re-)build the OS image
$ sudo mkosi boot # Boot the image with systemd-nspawn.
$ mkosi qemu # Boot the image with qemu.
``` ```
Putting this all together, here's a series of commands for preparing a patch for By default, the tools from your host system are used to build the image.
systemd: Sometimes we start using mkosi features that rely on functionality in systemd
tools that's not in an official release yet. In that case, you'll need to build
systemd from source on the host and configure mkosi to use the tools from the
systemd build directory.
To do a local build, most distributions provide very simple and convenient ways
to install most development packages necessary to build systemd:
```sh ```sh
$ git clone https://github.com/systemd/mkosi.git # Fedora
$ ln -s $PWD/mkosi/bin/mkosi ~/.local/bin/mkosi # Make sure ~/.local/bin is in $PATH. $ sudo dnf builddep systemd
$ git clone https://github.com/systemd/systemd.git # Debian/Ubuntu
$ sudo apt-get build-dep systemd
# Arch
$ sudo pacman -S devtools
$ pkgctl repo clone --protocol=https systemd
$ cd systemd $ cd systemd
$ git checkout -b <BRANCH> # where BRANCH is the name of the branch $ makepkg -seoc
$ $EDITOR src/core/main.c # or wherever you'd like to make your changes
$ mkosi -f sandbox meson setup build # Set up meson
$ mkosi -f genkey # Generate signing keys once.
$ mkosi -f sandbox ninja -C build mkosi # (re-)build the test image
$ mkosi qemu # Boot the image in qemu
$ git add -p # interactively put together your patch
$ git commit # commit it
$ git push -u <REMOTE> # where REMOTE is your "fork" on GitHub
``` ```
And after that, head over to your repo on GitHub and click "Compare & pull After installing the development packages, systemd can be built from source as follows:
request"
Happy hacking! ```sh
$ meson setup build <options>
$ ninja -C build
$ meson test -C build
```
The following sections contain advanced topics on how to speed up development or To have `mkosi` use the systemd tools from the `build/` directory, add the
streamline debugging. Feel free to read them if you're interested but they're following to `mkosi.local.conf`:
not required to write basic patches.
## Building the OS image without a tools tree
By default, `mkosi` will first build a tools tree and use it build the image and
provide the environment for `mkosi sandbox`. To disable the tools tree and use
binaries from your host instead, write the following to `mkosi.local.conf`:
```conf ```conf
[Build] [Host]
ToolsTree= ExtraSearchPaths=build/
``` ```
## Rebuilding systemd without rebuilding the OS image And if you want `mkosi` to build a tools image and use the tools from there
instead of looking for tools on the host, add the following to
`mkosi.local.conf`:
Every time the `mkosi` target is built, a fresh image is built. To build the ```conf
latest changes and re-install systemd without rebuilding the image, run one of [Host]
the following commands in another terminal on your host after booting the image ToolsTree=default
(choose the right one depending on the distribution of the container or virtual ```
machine):
Every time you rerun the `mkosi` command a fresh image is built, incorporating
all current changes you made to the project tree. To build the latest changes
and re-install after booting the image, run one of the following commands in
another terminal on your host (choose the right one depending on the
distribution of the container or virtual machine):
```sh ```sh
mkosi -t none && mkosi ssh dnf upgrade --disablerepo="*" --assumeyes "/work/build/*.rpm" # CentOS/Fedora mkosi -t none && mkosi ssh dnf upgrade --disablerepo="*" --assumeyes "/work/build/*.rpm" # CentOS/Fedora
@ -110,6 +107,26 @@ and optionally restart the daemon(s) you're working on using
`systemctl restart <units>` or `systemctl daemon-reexec` if you're working on `systemctl restart <units>` or `systemctl daemon-reexec` if you're working on
pid1 or `systemctl soft-reboot` to restart everything. pid1 or `systemctl soft-reboot` to restart everything.
Putting this all together, here's a series of commands for preparing a patch for systemd:
```sh
$ git clone https://github.com/systemd/mkosi.git
$ ln -s $PWD/mkosi/bin/mkosi /usr/local/bin/mkosi
$ git clone https://github.com/systemd/systemd.git
$ cd systemd
$ git checkout -b <BRANCH> # where BRANCH is the name of the branch
$ vim src/core/main.c # or wherever you'd like to make your changes
$ mkosi -f qemu # (re-)build and boot up the test image in qemu
$ mkosi -t none # Build new packages without rebuilding the image
$ git add -p # interactively put together your patch
$ git commit # commit it
$ git push -u <REMOTE> # where REMOTE is your "fork" on GitHub
```
And after that, head over to your repo on GitHub and click "Compare & pull request"
Happy hacking!
## Building distribution packages with mkosi ## Building distribution packages with mkosi
To build distribution packages for a specific distribution and release without To build distribution packages for a specific distribution and release without
@ -184,6 +201,67 @@ Those are not useful when compiling for distribution and can be disabled by sett
See [Testing systemd using sanitizers](/TESTING_WITH_SANITIZERS) for more information on how to build with sanitizers enabled in mkosi. See [Testing systemd using sanitizers](/TESTING_WITH_SANITIZERS) for more information on how to build with sanitizers enabled in mkosi.
## Fuzzers
systemd includes fuzzers in `src/fuzz/` that use libFuzzer and are automatically run by [OSS-Fuzz](https://github.com/google/oss-fuzz) with sanitizers.
To add a fuzz target, create a new `src/fuzz/fuzz-foo.c` file with a `LLVMFuzzerTestOneInput` function and add it to the list in `src/fuzz/meson.build`.
Whenever possible, a seed corpus and a dictionary should also be added with new fuzz targets.
The dictionary should be named `src/fuzz/fuzz-foo.dict` and the seed corpus should be built and exported as `$OUT/fuzz-foo_seed_corpus.zip` in `tools/oss-fuzz.sh`.
The fuzzers can be built locally if you have libFuzzer installed by running `tools/oss-fuzz.sh`, or by running:
```sh
CC=clang CXX=clang++ \
meson setup build-libfuzz -Dllvm-fuzz=true -Db_sanitize=address,undefined -Db_lundef=false \
-Dc_args='-fno-omit-frame-pointer -DFUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION'
ninja -C build-libfuzz fuzzers
```
Each fuzzer then can be then run manually together with a directory containing the initial corpus:
```
export UBSAN_OPTIONS=print_stacktrace=1:print_summary=1:halt_on_error=1
build-libfuzz/fuzz-varlink-idl test/fuzz/fuzz-varlink-idl/
```
Note: the `halt_on_error=1` UBSan option is especially important,
otherwise the fuzzer won't crash when undefined behavior is triggered.
You should also confirm that the fuzzers can be built and run using
[the OSS-Fuzz toolchain](https://google.github.io/oss-fuzz/advanced-topics/reproducing/#building-using-docker):
```sh
path_to_systemd=...
git clone --depth=1 https://github.com/google/oss-fuzz
cd oss-fuzz
for sanitizer in address undefined memory; do
for engine in libfuzzer afl honggfuzz; do
./infra/helper.py build_fuzzers --sanitizer "$sanitizer" --engine "$engine" \
--clean systemd "$path_to_systemd"
./infra/helper.py check_build --sanitizer "$sanitizer" --engine "$engine" \
-e ALLOWED_BROKEN_TARGETS_PERCENTAGE=0 systemd
done
done
./infra/helper.py build_fuzzers --clean --architecture i386 systemd "$path_to_systemd"
./infra/helper.py check_build --architecture i386 -e ALLOWED_BROKEN_TARGETS_PERCENTAGE=0 systemd
./infra/helper.py build_fuzzers --clean --sanitizer coverage systemd "$path_to_systemd"
./infra/helper.py coverage --no-corpus-download systemd
```
If you find a bug that impacts the security of systemd,
please follow the guidance in [CONTRIBUTING.md](/CONTRIBUTING) on how to report a security vulnerability.
For more details on building fuzzers and integrating with OSS-Fuzz, visit:
- [Setting up a new project - OSS-Fuzz](https://google.github.io/oss-fuzz/getting-started/new-project-guide/)
- [Tutorials - OSS-Fuzz](https://google.github.io/oss-fuzz/reference/useful-links/#tutorials)
## Debugging binaries that need to run as root in vscode ## Debugging binaries that need to run as root in vscode
When trying to debug binaries that need to run as root, When trying to debug binaries that need to run as root,

View File

@ -3,7 +3,3 @@
# Dell iDRAC Virtual USB NIC # Dell iDRAC Virtual USB NIC
usb:v413CpA102* usb:v413CpA102*
ID_NET_NAME_FROM_DATABASE=idrac ID_NET_NAME_FROM_DATABASE=idrac
# Disable inclusion of PCI domain in interface names on Azure MANA
pci:v00001414d000000BA*
ID_NET_NAME_INCLUDE_DOMAIN=0

View File

@ -97,18 +97,6 @@
</listitem> </listitem>
</varlistentry> </varlistentry>
<varlistentry>
<term><varname>systemd.break=</varname></term>
<term><varname>rd.systemd.break=</varname></term>
<listitem>
<para>Parameters understood by
<citerefentry><refentrytitle>systemd-debug-generator</refentrytitle><manvolnum>8</manvolnum></citerefentry>,
to pause the boot process at a certain point and spawn a debug shell.</para>
<xi:include href="version-info.xml" xpointer="v258"/>
</listitem>
</varlistentry>
<varlistentry> <varlistentry>
<term><varname>systemd.run=</varname></term> <term><varname>systemd.run=</varname></term>
<term><varname>systemd.run_success_action=</varname></term> <term><varname>systemd.run_success_action=</varname></term>

View File

@ -31,131 +31,45 @@
<refsect1> <refsect1>
<title>Description</title> <title>Description</title>
<para><command>systemd-debug-generator</command> is a generator that provides some debugging <para><filename>systemd-debug-generator</filename> is a generator
functionality.</para> that reads the kernel command line and understands three
options:</para>
<para><command>systemd-debug-generator</command> implements <para>If the <option>systemd.mask=</option> or <option>rd.systemd.mask=</option>
option is specified and followed by a unit name, this unit is
masked for the runtime (i.e. for this session — from boot to shutdown), similarly to the effect of
<citerefentry><refentrytitle>systemctl</refentrytitle><manvolnum>1</manvolnum></citerefentry>'s
<command>mask</command> command. This is useful to boot with
certain units removed from the initial boot transaction for
debugging system startup. May be specified more than once.
<option>rd.systemd.mask=</option> is honored only by initial
RAM disk (initrd) while <option>systemd.mask=</option> is
honored only in the main system.</para>
<para>If the <option>systemd.wants=</option> or
<option>rd.systemd.wants=</option> option is specified
and followed by a unit name, a start job for this unit is added to
the initial transaction. This is useful to start one or more
additional units at boot. May be specified more than once.
<option>rd.systemd.wants=</option> is honored only by initial
RAM disk (initrd) while <option>systemd.wants=</option> is
honored only in the main system.</para>
<para>If the <option>systemd.debug_shell</option> or <option>rd.systemd.debug_shell</option> option is
specified, the debug shell service <literal>debug-shell.service</literal> is pulled into the boot
transaction and a debug shell will be spawned during early boot. By default,
<filename>&DEBUGTTY;</filename> is used, but a specific tty can also be specified, either with or without
the <filename>/dev/</filename> prefix. To set the tty to use without enabling the debug shell, the
<option>systemd.default_debug_tty=</option> option can be used which also takes a tty with or without the
<filename>/dev/</filename> prefix. Note that the shell may also be turned on persistently by enabling it
with <citerefentry><refentrytitle>systemctl</refentrytitle><manvolnum>1</manvolnum></citerefentry>'s
<command>enable</command> command. <option>rd.systemd.debug_shell</option> is honored only by initial
RAM disk (initrd) while <option>systemd.debug_shell</option> is honored only in the main system.</para>
<para><filename>systemd-debug-generator</filename> implements
<citerefentry><refentrytitle>systemd.generator</refentrytitle><manvolnum>7</manvolnum></citerefentry>.</para> <citerefentry><refentrytitle>systemd.generator</refentrytitle><manvolnum>7</manvolnum></citerefentry>.</para>
</refsect1> </refsect1>
<refsect1>
<title>Kernel Command Line</title>
<para><command>systemd-debug-generator</command> understands the following kernel command line
parameters:</para>
<variablelist class='kernel-commandline-options'>
<varlistentry>
<term><varname>systemd.mask=</varname></term>
<term><varname>rd.systemd.mask=</varname></term>
<listitem><para>These options take a unit name as argument. The unit specified is masked for the
runtime (i.e. for this session — from boot to shutdown), similarly to the effect of
<citerefentry><refentrytitle>systemctl</refentrytitle><manvolnum>1</manvolnum></citerefentry>'s
<command>mask</command> command. This is useful to boot with certain units removed from the initial
boot transaction for debugging system startup. May be specified more than once. The option prefixed
with <literal>rd.</literal> is honored only in the initrd, while the one without prefix is only
honored in the main system.</para>
<xi:include href="version-info.xml" xpointer="v215"/></listitem>
</varlistentry>
<varlistentry>
<term><varname>systemd.wants=</varname></term>
<term><varname>rd.systemd.wants=</varname></term>
<listitem><para>These options take a unit name as argument. A start job for this unit is added to the
initial transaction. This is useful to start one or more additional units at boot. May be specified
more than once. The option prefixed with <literal>rd.</literal> is honored only in the initrd, while
the one that is not prefixed only in the main system.</para>
<xi:include href="version-info.xml" xpointer="v215"/></listitem>
</varlistentry>
<varlistentry>
<term><varname>systemd.debug_shell</varname></term>
<term><varname>rd.systemd.debug_shell</varname></term>
<term><varname>systemd.default_debug_tty=</varname></term>
<term><varname>rd.systemd.default_debug_tty=</varname></term>
<listitem><para>If the <option>systemd.debug_shell</option> or
<option>rd.systemd.debug_shell</option> option is specified, the debug shell service
<literal>debug-shell.service</literal> is pulled into the boot transaction and a debug shell will be
spawned during early boot. By default, <filename>&DEBUGTTY;</filename> is used, but a specific tty
can also be specified, either with or without the <filename>/dev/</filename> prefix. To set the tty
to use without enabling the debug shell, the <option>systemd.default_debug_tty=</option> option can
be used which also takes a tty with or without the <filename>/dev/</filename> prefix. Note that the
shell may also be turned on persistently by enabling it with
<citerefentry><refentrytitle>systemctl</refentrytitle><manvolnum>1</manvolnum></citerefentry>'s
<command>enable</command> command. The options prefixed with <literal>rd.</literal> are honored only
in the initrd, while the ones without prefix are only honored in the main system.</para>
<xi:include href="version-info.xml" xpointer="v215"/></listitem>
</varlistentry>
<varlistentry>
<term><varname>systemd.break=</varname></term>
<term><varname>rd.systemd.break=</varname></term>
<listitem><para>Takes one of <option>pre-udev</option>, <option>pre-basic</option>,
<option>pre-mount</option>, or <option>pre-switch-root</option> (the default for the
<literal>rd.</literal> option). It also accepts multiple values separated by comma
(<literal>,</literal>). These options allow to pause the boot process at a certain point and spawn a
debug shell. After exiting this shell, the system will resume booting. The option prefixed with
<literal>rd.</literal> is honored only in the initrd, while the one without prefix is only honored in
the main system.</para>
<table>
<title>Available breakpoints</title>
<tgroup cols='4'>
<colspec colname='breakpoint' />
<colspec colname='description' />
<colspec colname='initrd' />
<colspec colname='main' />
<thead>
<row>
<entry>Breakpoints</entry>
<entry>Description</entry>
<entry>Can be used in the initrd</entry>
<entry>Can be used in the main system</entry>
</row>
</thead>
<tbody>
<row>
<entry><option>pre-udev</option></entry>
<entry>Before starting to process kernel uevents, i.e., before <filename>systemd-udevd.service</filename> starts.</entry>
<entry></entry>
<entry></entry>
</row>
<row>
<entry><option>pre-basic</option></entry>
<entry>Before leaving early boot and regular services start, i.e., before <filename>basic.target</filename> is reached.</entry>
<entry></entry>
<entry></entry>
</row>
<row>
<entry><option>pre-mount</option></entry>
<entry>Before the root filesystem is mounted, i.e., before <filename>sysroot.mount</filename> starts.</entry>
<entry></entry>
<entry></entry>
</row>
<row>
<entry><option>pre-switch-root</option></entry>
<entry>Before switching from the initrd to the real root.</entry>
<entry></entry>
<entry></entry>
</row>
</tbody>
</tgroup>
</table>
<xi:include href="version-info.xml" xpointer="v258"/></listitem>
</varlistentry>
</variablelist>
</refsect1>
<refsect1> <refsect1>
<title>System Credentials</title> <title>System Credentials</title>
@ -194,8 +108,6 @@
<member><citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry></member> <member><citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry></member>
<member><citerefentry><refentrytitle>systemctl</refentrytitle><manvolnum>1</manvolnum></citerefentry></member> <member><citerefentry><refentrytitle>systemctl</refentrytitle><manvolnum>1</manvolnum></citerefentry></member>
<member><citerefentry><refentrytitle>kernel-command-line</refentrytitle><manvolnum>7</manvolnum></citerefentry></member> <member><citerefentry><refentrytitle>kernel-command-line</refentrytitle><manvolnum>7</manvolnum></citerefentry></member>
<member><citerefentry><refentrytitle>systemd.system-credentials</refentrytitle><manvolnum>7</manvolnum></citerefentry></member>
<member><citerefentry><refentrytitle>bootup</refentrytitle><manvolnum>7</manvolnum></citerefentry></member>
</simplelist></para> </simplelist></para>
</refsect1> </refsect1>

View File

@ -503,17 +503,6 @@
<xi:include href="version-info.xml" xpointer="v254"/></listitem> <xi:include href="version-info.xml" xpointer="v254"/></listitem>
</varlistentry> </varlistentry>
<varlistentry>
<term><option>--system</option></term>
<term><option>--user</option></term>
<listitem><para>When used together with <option>--discover</option> controls whether to search for
images installed system-wide or in the user's directories in <varname>$HOME</varname>. If neither
switch is specified, will search within both scopes.</para>
<xi:include href="version-info.xml" xpointer="v258"/></listitem>
</varlistentry>
<xi:include href="standard-options.xml" xpointer="image-policy-open" /> <xi:include href="standard-options.xml" xpointer="image-policy-open" />
<xi:include href="standard-options.xml" xpointer="no-pager" /> <xi:include href="standard-options.xml" xpointer="no-pager" />
<xi:include href="standard-options.xml" xpointer="no-legend" /> <xi:include href="standard-options.xml" xpointer="no-legend" />

View File

@ -3468,43 +3468,37 @@ StandardInputData=V2XigLJyZSBubyBzdHJhbmdlcnMgdG8gbG92ZQpZb3Uga25vdyB0aGUgcnVsZX
<term><varname>LoadCredentialEncrypted=</varname><replaceable>ID</replaceable><optional>:<replaceable>PATH</replaceable></optional></term> <term><varname>LoadCredentialEncrypted=</varname><replaceable>ID</replaceable><optional>:<replaceable>PATH</replaceable></optional></term>
<listitem><para>Pass a credential to the unit. Credentials are limited-size binary or textual objects <listitem><para>Pass a credential to the unit. Credentials are limited-size binary or textual objects
that may be passed to unit processes. They are primarily intended for passing cryptographic keys that may be passed to unit processes. They are primarily used for passing cryptographic keys (both
(both public and private) or certificates, user account information or identity information from host public and private) or certificates, user account information or identity information from host to
to services, but can be freely used to pass any kind of limited-size information to a service. The services. The data is accessible from the unit's processes via the file system, at a read-only
data is accessible from the unit's processes via the file system, at a read-only location that (if location that (if possible and permitted) is backed by non-swappable memory. The data is only
possible and permitted) is backed by non-swappable memory. The data is only accessible to the user accessible to the user associated with the unit, via the
associated with the unit, via the <varname>User=</varname>/<varname>DynamicUser=</varname> settings <varname>User=</varname>/<varname>DynamicUser=</varname> settings (as well as the superuser). When
(as well as the superuser). When available, the location of credentials is exported as the available, the location of credentials is exported as the <varname>$CREDENTIALS_DIRECTORY</varname>
<varname>$CREDENTIALS_DIRECTORY</varname> environment variable to the unit's processes.</para> environment variable to the unit's processes.</para>
<para>The <varname>LoadCredential=</varname> setting takes a textual ID to use as name for a <para>The <varname>LoadCredential=</varname> setting takes a textual ID to use as name for a
credential plus a file system path, separated by a colon. The ID must be a short ASCII string credential plus a file system path, separated by a colon. The ID must be a short ASCII string
suitable as filename in the filesystem, and may be chosen freely by the user. If the specified path suitable as filename in the filesystem, and may be chosen freely by the user. If the specified path
is absolute it is opened as regular file and the credential data is read from it. If the absolute is absolute it is opened as regular file and the credential data is read from it. If the absolute
path refers to an <constant>AF_UNIX</constant> stream socket in the file system a connection is made path refers to an <constant>AF_UNIX</constant> stream socket in the file system a connection is made
to it (once at process invocation) and the credential data read from the connection, providing an to it (only once at unit start-up) and the credential data read from the connection, providing an
easy IPC integration point for dynamically transferring credentials from other services.</para> easy IPC integration point for dynamically transferring credentials from other services.</para>
<para>If the specified path is not absolute and itself qualifies as valid credential identifier it is <para>If the specified path is not absolute and itself qualifies as valid credential identifier it is
attempted to find a credential that the service manager itself received under the specified name — attempted to find a credential that the service manager itself received under the specified name —
which may be used to propagate credentials from an invoking environment (e.g. a container manager which may be used to propagate credentials from an invoking environment (e.g. a container manager
that invoked the service manager) into a service. If no matching passed credential is found, the that invoked the service manager) into a service. If no matching system credential is found, the
system service manager will search the directories <filename>/etc/credstore/</filename>, directories <filename>/etc/credstore/</filename>, <filename>/run/credstore/</filename> and
<filename>/run/credstore/</filename> and <filename>/usr/lib/credstore/</filename> for files under the <filename>/usr/lib/credstore/</filename> are searched for files under the credential's name — which
credential's name — which hence are recommended locations for credential data on disk. If hence are recommended locations for credential data on disk. If
<varname>LoadCredentialEncrypted=</varname> is used <filename>/run/credstore.encrypted/</filename>, <varname>LoadCredentialEncrypted=</varname> is used <filename>/run/credstore.encrypted/</filename>,
<filename>/etc/credstore.encrypted/</filename>, and <filename>/etc/credstore.encrypted/</filename>, and
<filename>/usr/lib/credstore.encrypted/</filename> are searched as well. The per-user service manager <filename>/usr/lib/credstore.encrypted/</filename> are searched as well.</para>
will search <filename>$XDG_CONFIG_HOME/credstore/</filename>,
<filename>$XDG_RUNTIME_DIR/credstore/</filename>, <filename>$HOME/.local/lib/credstore/</filename>
(and the counterparts ending with <filename>…/credstore.encrypted/</filename>) instead. The
<citerefentry><refentrytitle>systemd-path</refentrytitle><manvolnum>1</manvolnum></citerefentry> tool
may be used to query the precise credential store search path.</para>
<para>If the file system path is omitted it is chosen identical to the credential name, i.e. this is <para>If the file system path is omitted it is chosen identical to the credential name, i.e. this is
a terse way to declare credentials to inherit from the service manager or credstore directories into a terse way to declare credentials to inherit from the service manager into a service. This option
a service. This option may be used multiple times, each time defining an additional credential to may be used multiple times, each time defining an additional credential to pass to the unit.</para>
pass to the unit.</para>
<para>Note that if the path is not specified or a valid credential identifier is given, i.e. <para>Note that if the path is not specified or a valid credential identifier is given, i.e.
in the above two cases, a missing credential is not considered fatal.</para> in the above two cases, a missing credential is not considered fatal.</para>

View File

@ -1,6 +1,5 @@
#!/bin/bash #!/bin/bash
# SPDX-License-Identifier: LGPL-2.1-or-later # SPDX-License-Identifier: LGPL-2.1-or-later
set -e
if command -v flatpak-spawn >/dev/null; then if command -v flatpak-spawn >/dev/null; then
SPAWN=(flatpak-spawn --host) SPAWN=(flatpak-spawn --host)
@ -8,7 +7,7 @@ else
SPAWN=() SPAWN=()
fi fi
MKOSI_CONFIG="$("${SPAWN[@]}" mkosi --json summary | jq -r .Images[-1])" MKOSI_CONFIG="$("${SPAWN[@]}" --host mkosi --json summary | jq -r .Images[-1])"
DISTRIBUTION="$(jq -r .Distribution <<< "$MKOSI_CONFIG")" DISTRIBUTION="$(jq -r .Distribution <<< "$MKOSI_CONFIG")"
RELEASE="$(jq -r .Release <<< "$MKOSI_CONFIG")" RELEASE="$(jq -r .Release <<< "$MKOSI_CONFIG")"
ARCH="$(jq -r .Architecture <<< "$MKOSI_CONFIG")" ARCH="$(jq -r .Architecture <<< "$MKOSI_CONFIG")"

View File

@ -29,7 +29,6 @@ RepartDirectories=mkosi.repart
OutputDirectory=build/mkosi.output OutputDirectory=build/mkosi.output
[Build] [Build]
ToolsTree=default
BuildDirectory=build/mkosi.builddir BuildDirectory=build/mkosi.builddir
CacheDirectory=build/mkosi.cache CacheDirectory=build/mkosi.cache
BuildSourcesEphemeral=yes BuildSourcesEphemeral=yes
@ -131,7 +130,7 @@ Packages=
zsh zsh
zstd zstd
[Runtime] [Host]
Credentials= Credentials=
journal.storage=persistent journal.storage=persistent
tty.serial.hvc0.agetty.autologin=root tty.serial.hvc0.agetty.autologin=root

View File

@ -3,7 +3,6 @@
[Build] [Build]
ToolsTreePackages= ToolsTreePackages=
gcc gcc
gdb
gperf gperf
lcov lcov
llvm llvm

View File

@ -1,7 +0,0 @@
# SPDX-License-Identifier: LGPL-2.1-or-later
[Match]
ToolsTreeDistribution=centos
[Build]
ToolsTreeRepositories=epel,epel-next

View File

@ -5,7 +5,6 @@ ToolsTreeDistribution=opensuse
[Build] [Build]
ToolsTreePackages= ToolsTreePackages=
libz1
gh gh
mypy mypy
pkgconfig(blkid) pkgconfig(blkid)

View File

@ -1,7 +0,0 @@
# SPDX-License-Identifier: LGPL-2.1-or-later
[Match]
PathExists=build/
[Build]
ExtraSearchPaths=build/

View File

@ -8,8 +8,8 @@ msgid ""
msgstr "" msgstr ""
"Report-Msgid-Bugs-To: \n" "Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2024-11-28 18:16+0900\n" "POT-Creation-Date: 2024-11-28 18:16+0900\n"
"PO-Revision-Date: 2024-12-20 15:38+0000\n" "PO-Revision-Date: 2024-11-20 19:13+0000\n"
"Last-Translator: Ricky Tigg <ricky.tigg@gmail.com>\n" "Last-Translator: Jiri Grönroos <jiri.gronroos@iki.fi>\n"
"Language-Team: Finnish <https://translate.fedoraproject.org/projects/systemd/" "Language-Team: Finnish <https://translate.fedoraproject.org/projects/systemd/"
"main/fi/>\n" "main/fi/>\n"
"Language: fi\n" "Language: fi\n"
@ -17,7 +17,7 @@ msgstr ""
"Content-Type: text/plain; charset=UTF-8\n" "Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n" "Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=n != 1;\n" "Plural-Forms: nplurals=2; plural=n != 1;\n"
"X-Generator: Weblate 5.9.1\n" "X-Generator: Weblate 5.8.2\n"
#: src/core/org.freedesktop.systemd1.policy.in:22 #: src/core/org.freedesktop.systemd1.policy.in:22
msgid "Send passphrase back to system" msgid "Send passphrase back to system"
@ -1176,8 +1176,9 @@ msgid "Manage optional features"
msgstr "Hallitse valinnaisia ominaisuuksia" msgstr "Hallitse valinnaisia ominaisuuksia"
#: src/sysupdate/org.freedesktop.sysupdate1.policy:76 #: src/sysupdate/org.freedesktop.sysupdate1.policy:76
#, fuzzy
msgid "Authentication is required to manage optional features." msgid "Authentication is required to manage optional features."
msgstr "Todennus vaaditaan valinnaisten ominaisuuksien hallintaan." msgstr "Todennus vaaditaan valinnaisten ominaisuuksien hallintaan"
#: src/timedate/org.freedesktop.timedate1.policy:22 #: src/timedate/org.freedesktop.timedate1.policy:22
msgid "Set system time" msgid "Set system time"

View File

@ -29,8 +29,6 @@ _systemd_dissect() {
local cur=${COMP_WORDS[COMP_CWORD]} prev_1=${COMP_WORDS[COMP_CWORD-1]} prev_2=${COMP_WORDS[COMP_CWORD-2]} words cword local cur=${COMP_WORDS[COMP_CWORD]} prev_1=${COMP_WORDS[COMP_CWORD-1]} prev_2=${COMP_WORDS[COMP_CWORD-2]} words cword
local -A OPTS=( local -A OPTS=(
[STANDALONE]='-h --help --version [STANDALONE]='-h --help --version
--user
--system
--discover --discover
--no-pager --no-pager
--no-legend --no-legend

View File

@ -4,7 +4,6 @@
#include "analyze-chid.h" #include "analyze-chid.h"
#include "chid-fundamental.h" #include "chid-fundamental.h"
#include "efi-api.h" #include "efi-api.h"
#include "escape.h"
#include "fd-util.h" #include "fd-util.h"
#include "fileio.h" #include "fileio.h"
#include "format-table.h" #include "format-table.h"
@ -31,20 +30,6 @@ static int parse_chid_type(const char *s, size_t *ret) {
return 0; return 0;
} }
static const char *const chid_smbios_friendly[_CHID_SMBIOS_FIELDS_MAX] = {
[CHID_SMBIOS_MANUFACTURER] = "manufacturer",
[CHID_SMBIOS_FAMILY] = "family",
[CHID_SMBIOS_PRODUCT_NAME] = "product-name",
[CHID_SMBIOS_PRODUCT_SKU] = "product-sku",
[CHID_SMBIOS_BASEBOARD_MANUFACTURER] = "baseboard-manufacturer",
[CHID_SMBIOS_BASEBOARD_PRODUCT] = "baseboard-product",
[CHID_SMBIOS_BIOS_VENDOR] = "bios-vendor",
[CHID_SMBIOS_BIOS_VERSION] = "bios-version",
[CHID_SMBIOS_BIOS_MAJOR] = "bios-major",
[CHID_SMBIOS_BIOS_MINOR] = "bios-minor",
[CHID_SMBIOS_ENCLOSURE_TYPE] = "enclosure-type",
};
static const char chid_smbios_fields_char[_CHID_SMBIOS_FIELDS_MAX] = { static const char chid_smbios_fields_char[_CHID_SMBIOS_FIELDS_MAX] = {
[CHID_SMBIOS_MANUFACTURER] = 'M', [CHID_SMBIOS_MANUFACTURER] = 'M',
[CHID_SMBIOS_FAMILY] = 'F', [CHID_SMBIOS_FAMILY] = 'F',
@ -52,11 +37,6 @@ static const char chid_smbios_fields_char[_CHID_SMBIOS_FIELDS_MAX] = {
[CHID_SMBIOS_PRODUCT_SKU] = 'S', [CHID_SMBIOS_PRODUCT_SKU] = 'S',
[CHID_SMBIOS_BASEBOARD_MANUFACTURER] = 'm', [CHID_SMBIOS_BASEBOARD_MANUFACTURER] = 'm',
[CHID_SMBIOS_BASEBOARD_PRODUCT] = 'p', [CHID_SMBIOS_BASEBOARD_PRODUCT] = 'p',
[CHID_SMBIOS_BIOS_VENDOR] = 'B',
[CHID_SMBIOS_BIOS_VERSION] = 'v',
[CHID_SMBIOS_BIOS_MAJOR] = 'R',
[CHID_SMBIOS_BIOS_MINOR] = 'r',
[CHID_SMBIOS_ENCLOSURE_TYPE] = 'e',
}; };
static char *chid_smbios_fields_string(uint32_t combination) { static char *chid_smbios_fields_string(uint32_t combination) {
@ -107,7 +87,7 @@ static void smbios_fields_free(char16_t *(*fields)[_CHID_SMBIOS_FIELDS_MAX]) {
free(*i); free(*i);
} }
static int smbios_fields_acquire(char16_t *fields[static _CHID_SMBIOS_FIELDS_MAX]) { int verb_chid(int argc, char *argv[], void *userdata) {
static const char *const smbios_files[_CHID_SMBIOS_FIELDS_MAX] = { static const char *const smbios_files[_CHID_SMBIOS_FIELDS_MAX] = {
[CHID_SMBIOS_MANUFACTURER] = "sys_vendor", [CHID_SMBIOS_MANUFACTURER] = "sys_vendor",
@ -116,115 +96,8 @@ static int smbios_fields_acquire(char16_t *fields[static _CHID_SMBIOS_FIELDS_MAX
[CHID_SMBIOS_PRODUCT_SKU] = "product_sku", [CHID_SMBIOS_PRODUCT_SKU] = "product_sku",
[CHID_SMBIOS_BASEBOARD_MANUFACTURER] = "board_vendor", [CHID_SMBIOS_BASEBOARD_MANUFACTURER] = "board_vendor",
[CHID_SMBIOS_BASEBOARD_PRODUCT] = "board_name", [CHID_SMBIOS_BASEBOARD_PRODUCT] = "board_name",
[CHID_SMBIOS_BIOS_VENDOR] = "bios_vendor",
[CHID_SMBIOS_BIOS_VERSION] = "bios_version",
[CHID_SMBIOS_BIOS_MAJOR] = "bios_release",
[CHID_SMBIOS_BIOS_MINOR] = "bios_release",
[CHID_SMBIOS_ENCLOSURE_TYPE] = "chassis_type",
}; };
int r;
_cleanup_close_ int smbios_fd = open("/sys/class/dmi/id", O_RDONLY|O_DIRECTORY|O_CLOEXEC);
if (smbios_fd < 0)
return log_error_errno(errno, "Failed to open SMBIOS sysfs object: %m");
for (ChidSmbiosFields f = 0; f < _CHID_SMBIOS_FIELDS_MAX; f++) {
_cleanup_free_ char *buf = NULL;
size_t size;
/* According to the CHID spec we should not generate CHIDs for SMBIOS fields that aren't set
* or are set to an empty string. Hence leave them NULL here. */
if (!smbios_files[f])
continue;
r = read_virtual_file_at(smbios_fd, smbios_files[f], SIZE_MAX, &buf, &size);
if (r == -ENOENT) {
log_debug_errno(r, "SMBIOS field '%s' not set, skipping.", smbios_files[f]);
continue;
}
if (r < 0)
return log_error_errno(r, "Failed to read SMBIOS field '%s': %m", smbios_files[f]);
if (size == 0 || (size == 1 && buf[0] == '\n')) {
log_debug("SMBIOS field '%s' is empty, skipping.", smbios_files[f]);
continue;
}
if (buf[size-1] != '\n')
return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Expected SMBIOS field '%s' to end in newline, but it doesn't, refusing.", smbios_files[f]);
buf[size-1] = 0;
size--;
switch (f) {
case CHID_SMBIOS_BIOS_MAJOR:
case CHID_SMBIOS_BIOS_MINOR: {
/* The kernel exposes this a string <major>.<minor>, split them apart again. */
char *dot = memchr(buf, '.', size);
if (!dot)
return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "BIOS release field '%s' contains no dot?", smbios_files[f]);
const char *p;
if (f == CHID_SMBIOS_BIOS_MAJOR) {
*dot = 0;
p = buf;
} else {
assert(f == CHID_SMBIOS_BIOS_MINOR);
p = dot + 1;
}
/* The kernel exports the enclosure in decimal, we need it in hex (zero left-padded) */
uint8_t u;
r = safe_atou8(p, &u);
if (r < 0)
return log_error_errno(r, "Failed to parse BIOS release: %s", p);
buf = mfree(buf);
if (asprintf(&buf, "%02x", u) < 0)
return log_oom();
size = strlen(buf);
break;
}
case CHID_SMBIOS_ENCLOSURE_TYPE: {
/* The kernel exports the enclosure in decimal, we need it in hex (no padding!) */
uint8_t u;
r = safe_atou8(buf, &u);
if (r < 0)
return log_error_errno(r, "Failed to parse enclosure type: %s", buf);
buf = mfree(buf);
if (u == 0)
buf = strdup(""); /* zero is mapped to empty string */
else
(void) asprintf(&buf, "%x", u);
if (!buf)
return log_oom();
size = strlen(buf);
break;
}
default:
break;
}
fields[f] = utf8_to_utf16(buf, size);
if (!fields[f])
return log_oom();
}
return 0;
}
int verb_chid(int argc, char *argv[], void *userdata) {
_cleanup_(table_unrefp) Table *table = NULL; _cleanup_(table_unrefp) Table *table = NULL;
int r; int r;
@ -238,10 +111,28 @@ int verb_chid(int argc, char *argv[], void *userdata) {
(void) table_set_align_percent(table, table_get_cell(table, 0, 0), 100); (void) table_set_align_percent(table, table_get_cell(table, 0, 0), 100);
(void) table_set_align_percent(table, table_get_cell(table, 0, 1), 50); (void) table_set_align_percent(table, table_get_cell(table, 0, 1), 50);
_cleanup_close_ int smbios_fd = open("/sys/class/dmi/id", O_RDONLY|O_DIRECTORY|O_CLOEXEC);
if (smbios_fd < 0)
return log_error_errno(errno, "Failed to open SMBIOS sysfs object: %m");
_cleanup_(smbios_fields_free) char16_t* smbios_fields[_CHID_SMBIOS_FIELDS_MAX] = {}; _cleanup_(smbios_fields_free) char16_t* smbios_fields[_CHID_SMBIOS_FIELDS_MAX] = {};
r = smbios_fields_acquire(smbios_fields); for (ChidSmbiosFields f = 0; f < _CHID_SMBIOS_FIELDS_MAX; f++) {
_cleanup_free_ char *buf = NULL;
size_t size;
r = read_virtual_file_at(smbios_fd, smbios_files[f], SIZE_MAX, &buf, &size);
if (r < 0) if (r < 0)
return r; return log_error_errno(r, "Failed to read SMBIOS field '%s': %m", smbios_files[f]);
if (size < 1 || buf[size-1] != '\n')
return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Expected SMBIOS field '%s' to end in newline, but it doesn't, refusing.", smbios_files[f]);
size--;
smbios_fields[f] = utf8_to_utf16(buf, size);
if (!smbios_fields[f])
return log_oom();
}
EFI_GUID chids[CHID_TYPES_MAX] = {}; EFI_GUID chids[CHID_TYPES_MAX] = {};
chid_calculate((const char16_t* const*) smbios_fields, chids); chid_calculate((const char16_t* const*) smbios_fields, chids);
@ -281,19 +172,9 @@ int verb_chid(int argc, char *argv[], void *userdata) {
return log_oom(); return log_oom();
for (ChidSmbiosFields f = 0; f < _CHID_SMBIOS_FIELDS_MAX; f++) { for (ChidSmbiosFields f = 0; f < _CHID_SMBIOS_FIELDS_MAX; f++) {
_cleanup_free_ char *c = NULL; _cleanup_free_ char *c = utf16_to_utf8(smbios_fields[f], SIZE_MAX);
if (smbios_fields[f]) {
_cleanup_free_ char *u = NULL;
u = utf16_to_utf8(smbios_fields[f], SIZE_MAX);
if (!u)
return log_oom();
c = cescape(u);
if (!c) if (!c)
return log_oom(); return log_oom();
}
if (!strextend(&legend, if (!strextend(&legend,
ansi_grey(), ansi_grey(),
@ -307,11 +188,11 @@ int verb_chid(int argc, char *argv[], void *userdata) {
special_glyph(SPECIAL_GLYPH_ARROW_RIGHT), special_glyph(SPECIAL_GLYPH_ARROW_RIGHT),
" ", " ",
ansi_normal(), ansi_normal(),
chid_smbios_friendly[f], smbios_files[f],
ansi_grey(), ansi_grey(),
" (", " (",
c ? ansi_highlight() : ansi_grey(), ansi_highlight(),
strna(c), c,
ansi_grey(), ansi_grey(),
")", ")",
ansi_normal())) ansi_normal()))
@ -319,9 +200,9 @@ int verb_chid(int argc, char *argv[], void *userdata) {
w += separator * 3 + w += separator * 3 +
4 + 4 +
utf8_console_width(chid_smbios_friendly[f]) + utf8_console_width(smbios_files[f]) +
2 + 2 +
utf8_console_width(strna(c)) + utf8_console_width(c) +
1; 1;
if (w > 79) { if (w > 79) {

View File

@ -9,8 +9,8 @@
#define AUDIT_SESSION_INVALID UINT32_MAX #define AUDIT_SESSION_INVALID UINT32_MAX
int audit_session_from_pid(const PidRef *pid, uint32_t *ret_id); int audit_session_from_pid(const PidRef *pid, uint32_t *id);
int audit_loginuid_from_pid(const PidRef *pid, uid_t *ret_uid); int audit_loginuid_from_pid(const PidRef *pid, uid_t *uid);
bool use_audit(void); bool use_audit(void);

View File

@ -85,9 +85,7 @@ static int device_set_sysfs(Device *d, const char *sysfs) {
Unit *u = UNIT(ASSERT_PTR(d)); Unit *u = UNIT(ASSERT_PTR(d));
int r; int r;
assert(sysfs); if (streq_ptr(d->sysfs, sysfs))
if (path_equal(d->sysfs, sysfs))
return 0; return 0;
Hashmap **devices = &u->manager->devices_by_sysfs; Hashmap **devices = &u->manager->devices_by_sysfs;
@ -334,20 +332,6 @@ static void device_catchup(Unit *u) {
Device *d = ASSERT_PTR(DEVICE(u)); Device *d = ASSERT_PTR(DEVICE(u));
/* Second, let's update the state with the enumerated state */ /* Second, let's update the state with the enumerated state */
/* If Device.found (set from Device.deserialized_found) does not have DEVICE_FOUND_UDEV, and the
* device has not been processed by udevd while enumeration, it indicates the unit was never active
* before reexecution, hence we can safely drop the flag from Device.enumerated_found. The device
* will be set up later when udev finishes processing (see also comment in
* device_setup_devlink_unit_one()).
*
* NB: 💣💣💣 If Device.found already contains udev, i.e. the unit was fully ready before
* reexecution, do not unset the flag. Otherwise, e.g. if systemd-udev-trigger.service is started
* just before reexec, reload, and so on, devices being reprocessed (carrying ID_PROCESSING=1
* property) on enumeration and will enter dead state. See issue #35329. */
if (!FLAGS_SET(d->found, DEVICE_FOUND_UDEV) && !d->processed)
d->enumerated_found &= ~DEVICE_FOUND_UDEV;
device_update_found_one(d, d->enumerated_found, _DEVICE_FOUND_MASK); device_update_found_one(d, d->enumerated_found, _DEVICE_FOUND_MASK);
} }
@ -793,16 +777,8 @@ static int device_setup_devlink_unit_one(Manager *m, const char *devlink, Set **
assert(ready_units); assert(ready_units);
assert(not_ready_units); assert(not_ready_units);
if (sd_device_new_from_devname(&dev, devlink) >= 0 && device_is_ready(dev)) { if (sd_device_new_from_devname(&dev, devlink) >= 0 && device_is_ready(dev))
if (MANAGER_IS_RUNNING(m) && device_is_processed(dev) <= 0)
/* The device is being processed by udevd. We will receive relevant uevent for the
* device later when completed. Let's ignore the device now. */
return 0;
/* Note, even if the device is being processed by udevd, setup the unit on enumerate.
* See also the comments in device_catchup(). */
return device_setup_unit(m, dev, devlink, /* main = */ false, ready_units); return device_setup_unit(m, dev, devlink, /* main = */ false, ready_units);
}
/* the devlink is already removed or not ready */ /* the devlink is already removed or not ready */
if (device_by_path(m, devlink, &u) < 0) if (device_by_path(m, devlink, &u) < 0)
@ -898,15 +874,14 @@ static int device_setup_extra_units(Manager *m, sd_device *dev, Set **ready_unit
return 0; return 0;
} }
static int device_setup_units(Manager *m, sd_device *dev, Set **ret_ready_units, Set **ret_not_ready_units) { static int device_setup_units(Manager *m, sd_device *dev, Set **ready_units, Set **not_ready_units) {
_cleanup_set_free_ Set *ready_units = NULL, *not_ready_units = NULL;
const char *syspath, *devname = NULL; const char *syspath, *devname = NULL;
int r; int r;
assert(m); assert(m);
assert(dev); assert(dev);
assert(ret_ready_units); assert(ready_units);
assert(ret_not_ready_units); assert(not_ready_units);
r = sd_device_get_syspath(dev, &syspath); r = sd_device_get_syspath(dev, &syspath);
if (r < 0) if (r < 0)
@ -926,13 +901,13 @@ static int device_setup_units(Manager *m, sd_device *dev, Set **ret_ready_units,
/* Add the main unit named after the syspath. If this one fails, don't bother with the rest, /* Add the main unit named after the syspath. If this one fails, don't bother with the rest,
* as this one shall be the main device unit the others just follow. (Compare with how * as this one shall be the main device unit the others just follow. (Compare with how
* device_following() is implemented, see below, which looks for the sysfs device.) */ * device_following() is implemented, see below, which looks for the sysfs device.) */
r = device_setup_unit(m, dev, syspath, /* main = */ true, &ready_units); r = device_setup_unit(m, dev, syspath, /* main = */ true, ready_units);
if (r < 0) if (r < 0)
return r; return r;
/* Add an additional unit for the device node */ /* Add an additional unit for the device node */
if (sd_device_get_devname(dev, &devname) >= 0) if (sd_device_get_devname(dev, &devname) >= 0)
(void) device_setup_unit(m, dev, devname, /* main = */ false, &ready_units); (void) device_setup_unit(m, dev, devname, /* main = */ false, ready_units);
} else { } else {
Unit *u; Unit *u;
@ -940,30 +915,28 @@ static int device_setup_units(Manager *m, sd_device *dev, Set **ret_ready_units,
/* If the device exists but not ready, then save the units and unset udev bits later. */ /* If the device exists but not ready, then save the units and unset udev bits later. */
if (device_by_path(m, syspath, &u) >= 0) { if (device_by_path(m, syspath, &u) >= 0) {
r = set_ensure_put(&not_ready_units, NULL, DEVICE(u)); r = set_ensure_put(not_ready_units, NULL, DEVICE(u));
if (r < 0) if (r < 0)
log_unit_debug_errno(u, r, "Failed to store unit, ignoring: %m"); log_unit_debug_errno(u, r, "Failed to store unit, ignoring: %m");
} }
if (sd_device_get_devname(dev, &devname) >= 0 && if (sd_device_get_devname(dev, &devname) >= 0 &&
device_by_path(m, devname, &u) >= 0) { device_by_path(m, devname, &u) >= 0) {
r = set_ensure_put(&not_ready_units, NULL, DEVICE(u)); r = set_ensure_put(not_ready_units, NULL, DEVICE(u));
if (r < 0) if (r < 0)
log_unit_debug_errno(u, r, "Failed to store unit, ignoring: %m"); log_unit_debug_errno(u, r, "Failed to store unit, ignoring: %m");
} }
} }
/* Next, add/update additional .device units point to aliases and symlinks. */ /* Next, add/update additional .device units point to aliases and symlinks. */
(void) device_setup_extra_units(m, dev, &ready_units, &not_ready_units); (void) device_setup_extra_units(m, dev, ready_units, not_ready_units);
/* Safety check: no unit should be in ready_units and not_ready_units simultaneously. */ /* Safety check: no unit should be in ready_units and not_ready_units simultaneously. */
Unit *u; Unit *u;
SET_FOREACH(u, not_ready_units) SET_FOREACH(u, *not_ready_units)
if (set_remove(ready_units, u)) if (set_remove(*ready_units, u))
log_unit_error(u, "Cannot activate and deactivate the unit simultaneously. Deactivating."); log_unit_error(u, "Cannot activate and deactivate the unit simultaneously. Deactivating.");
*ret_ready_units = TAKE_PTR(ready_units);
*ret_not_ready_units = TAKE_PTR(not_ready_units);
return 0; return 0;
} }
@ -1073,32 +1046,13 @@ static void device_enumerate(Manager *m) {
FOREACH_DEVICE(e, dev) { FOREACH_DEVICE(e, dev) {
_cleanup_set_free_ Set *ready_units = NULL, *not_ready_units = NULL; _cleanup_set_free_ Set *ready_units = NULL, *not_ready_units = NULL;
const char *syspath;
bool processed;
Device *d; Device *d;
r = sd_device_get_syspath(dev, &syspath);
if (r < 0) {
log_device_debug_errno(dev, r, "Failed to get syspath of enumerated device, ignoring: %m");
continue;
}
r = device_is_processed(dev);
if (r < 0)
log_device_debug_errno(dev, r, "Failed to check if device is processed by udevd, assuming not: %m");
processed = r > 0;
if (device_setup_units(m, dev, &ready_units, &not_ready_units) < 0) if (device_setup_units(m, dev, &ready_units, &not_ready_units) < 0)
continue; continue;
SET_FOREACH(d, ready_units) { SET_FOREACH(d, ready_units)
device_update_found_one(d, DEVICE_FOUND_UDEV, DEVICE_FOUND_UDEV); device_update_found_one(d, DEVICE_FOUND_UDEV, DEVICE_FOUND_UDEV);
/* Why we need to check the syspath here? Because the device unit may be generated by
* a devlink, and the syspath may be different from the one of the original device. */
if (path_equal(d->sysfs, syspath))
d->processed = processed;
}
SET_FOREACH(d, not_ready_units) SET_FOREACH(d, not_ready_units)
device_update_found_one(d, DEVICE_NOT_FOUND, DEVICE_FOUND_UDEV); device_update_found_one(d, DEVICE_NOT_FOUND, DEVICE_FOUND_UDEV);
} }
@ -1143,6 +1097,7 @@ static void device_remove_old_on_move(Manager *m, sd_device *dev) {
} }
static int device_dispatch_io(sd_device_monitor *monitor, sd_device *dev, void *userdata) { static int device_dispatch_io(sd_device_monitor *monitor, sd_device *dev, void *userdata) {
_cleanup_set_free_ Set *ready_units = NULL, *not_ready_units = NULL;
Manager *m = ASSERT_PTR(userdata); Manager *m = ASSERT_PTR(userdata);
sd_device_action_t action; sd_device_action_t action;
const char *sysfs; const char *sysfs;
@ -1195,7 +1150,6 @@ static int device_dispatch_io(sd_device_monitor *monitor, sd_device *dev, void *
* change events */ * change events */
ready = device_is_ready(dev); ready = device_is_ready(dev);
_cleanup_set_free_ Set *ready_units = NULL, *not_ready_units = NULL;
(void) device_setup_units(m, dev, &ready_units, &not_ready_units); (void) device_setup_units(m, dev, &ready_units, &not_ready_units);
if (action == SD_DEVICE_REMOVE) { if (action == SD_DEVICE_REMOVE) {

View File

@ -29,9 +29,7 @@ struct Device {
DeviceState state, deserialized_state; DeviceState state, deserialized_state;
DeviceFound found, deserialized_found, enumerated_found; DeviceFound found, deserialized_found, enumerated_found;
bool processed; /* Whether udevd has done processing the device, i.e. the device has database and
* ID_PROCESSING=1 udev property is not set. This is used only by enumeration and
* subsequent catchup process. */
bool bind_mounts; bool bind_mounts;
/* The SYSTEMD_WANTS udev property for this device the last time we saw it */ /* The SYSTEMD_WANTS udev property for this device the last time we saw it */

View File

@ -117,9 +117,10 @@ int exec_context_put_load_credential(ExecContext *c, const char *id, const char
return -ENOMEM; return -ENOMEM;
r = hashmap_ensure_put(&c->load_credentials, &exec_load_credential_hash_ops, lc->id, lc); r = hashmap_ensure_put(&c->load_credentials, &exec_load_credential_hash_ops, lc->id, lc);
if (r < 0) {
assert(r != -EEXIST); assert(r != -EEXIST);
if (r < 0)
return r; return r;
}
TAKE_PTR(lc); TAKE_PTR(lc);
} }
@ -166,9 +167,10 @@ int exec_context_put_set_credential(
return -ENOMEM; return -ENOMEM;
r = hashmap_ensure_put(&c->set_credentials, &exec_set_credential_hash_ops, sc->id, sc); r = hashmap_ensure_put(&c->set_credentials, &exec_set_credential_hash_ops, sc->id, sc);
if (r < 0) {
assert(r != -EEXIST); assert(r != -EEXIST);
if (r < 0)
return r; return r;
}
TAKE_PTR(sc); TAKE_PTR(sc);
} }
@ -191,22 +193,19 @@ int exec_context_put_import_credential(ExecContext *c, const char *glob, const c
*ic = (ExecImportCredential) { *ic = (ExecImportCredential) {
.glob = strdup(glob), .glob = strdup(glob),
.rename = rename ? strdup(rename) : NULL,
}; };
if (!ic->glob) if (!ic->glob || (rename && !ic->rename))
return -ENOMEM; return -ENOMEM;
if (rename) {
ic->rename = strdup(rename);
if (!ic->rename)
return -ENOMEM;
}
if (ordered_set_contains(c->import_credentials, ic)) if (ordered_set_contains(c->import_credentials, ic))
return 0; return 0;
r = ordered_set_ensure_put(&c->import_credentials, &exec_import_credential_hash_ops, ic); r = ordered_set_ensure_put(&c->import_credentials, &exec_import_credential_hash_ops, ic);
if (r < 0) {
assert(r != -EEXIST); assert(r != -EEXIST);
if (r < 0)
return r; return r;
}
TAKE_PTR(ic); TAKE_PTR(ic);
@ -384,46 +383,30 @@ typedef enum CredentialSearchPath {
_CREDENTIAL_SEARCH_PATH_INVALID = -EINVAL, _CREDENTIAL_SEARCH_PATH_INVALID = -EINVAL,
} CredentialSearchPath; } CredentialSearchPath;
static int credential_search_path(const ExecParameters *params, CredentialSearchPath path, char ***ret) { static char** credential_search_path(const ExecParameters *params, CredentialSearchPath path) {
_cleanup_strv_free_ char **l = NULL; _cleanup_strv_free_ char **l = NULL;
int r;
assert(params); assert(params);
assert(path >= 0 && path < _CREDENTIAL_SEARCH_PATH_MAX); assert(path >= 0 && path < _CREDENTIAL_SEARCH_PATH_MAX);
assert(ret);
/* Assemble a search path to find credentials in. For non-encrypted credentials, We'll look in /* Assemble a search path to find credentials in. For non-encrypted credentials, We'll look in
* /etc/credstore/ (and similar directories in /usr/lib/ + /run/). If we're looking for encrypted * /etc/credstore/ (and similar directories in /usr/lib/ + /run/). If we're looking for encrypted
* credentials, we'll look in /etc/credstore.encrypted/ (and similar dirs). */ * credentials, we'll look in /etc/credstore.encrypted/ (and similar dirs). */
if (IN_SET(path, CREDENTIAL_SEARCH_PATH_ENCRYPTED, CREDENTIAL_SEARCH_PATH_ALL)) { if (IN_SET(path, CREDENTIAL_SEARCH_PATH_ENCRYPTED, CREDENTIAL_SEARCH_PATH_ALL)) {
r = strv_extend(&l, params->received_encrypted_credentials_directory); if (strv_extend(&l, params->received_encrypted_credentials_directory) < 0)
if (r < 0) return NULL;
return r;
_cleanup_strv_free_ char **add = NULL; if (strv_extend_strv(&l, CONF_PATHS_STRV("credstore.encrypted"), /* filter_duplicates= */ true) < 0)
r = credential_store_path_encrypted(params->runtime_scope, &add); return NULL;
if (r < 0)
return r;
r = strv_extend_strv_consume(&l, TAKE_PTR(add), /* filter_duplicates= */ false);
if (r < 0)
return r;
} }
if (IN_SET(path, CREDENTIAL_SEARCH_PATH_TRUSTED, CREDENTIAL_SEARCH_PATH_ALL)) { if (IN_SET(path, CREDENTIAL_SEARCH_PATH_TRUSTED, CREDENTIAL_SEARCH_PATH_ALL)) {
r = strv_extend(&l, params->received_credentials_directory); if (strv_extend(&l, params->received_credentials_directory) < 0)
if (r < 0) return NULL;
return r;
_cleanup_strv_free_ char **add = NULL; if (strv_extend_strv(&l, CONF_PATHS_STRV("credstore"), /* filter_duplicates= */ true) < 0)
r = credential_store_path(params->runtime_scope, &add); return NULL;
if (r < 0)
return r;
r = strv_extend_strv_consume(&l, TAKE_PTR(add), /* filter_duplicates= */ false);
if (r < 0)
return r;
} }
if (DEBUG_LOGGING) { if (DEBUG_LOGGING) {
@ -431,8 +414,7 @@ static int credential_search_path(const ExecParameters *params, CredentialSearch
log_debug("Credential search path is: %s", strempty(t)); log_debug("Credential search path is: %s", strempty(t));
} }
*ret = TAKE_PTR(l); return TAKE_PTR(l);
return 0;
} }
struct load_cred_args { struct load_cred_args {
@ -463,10 +445,6 @@ static int maybe_decrypt_and_write_credential(
assert(data || size == 0); assert(data || size == 0);
if (args->encrypted) { if (args->encrypted) {
switch (args->params->runtime_scope) {
case RUNTIME_SCOPE_SYSTEM:
/* In system mode talk directly to the TPM */
r = decrypt_credential_and_warn( r = decrypt_credential_and_warn(
id, id,
now(CLOCK_REALTIME), now(CLOCK_REALTIME),
@ -476,25 +454,6 @@ static int maybe_decrypt_and_write_credential(
&IOVEC_MAKE(data, size), &IOVEC_MAKE(data, size),
CREDENTIAL_ANY_SCOPE, CREDENTIAL_ANY_SCOPE,
&plaintext); &plaintext);
break;
case RUNTIME_SCOPE_USER:
/* In per user mode we'll not have access to the machine secret, nor to the TPM (most
* likely), hence go via the IPC service instead. Do this if we are run in root's
* per-user invocation too, to minimize differences and because isolating this logic
* into a separate process is generally a good thing anyway. */
r = ipc_decrypt_credential(
id,
now(CLOCK_REALTIME),
getuid(),
&IOVEC_MAKE(data, size),
/* flags= */ 0, /* only allow user creds in user scope */
&plaintext);
break;
default:
assert_not_reached();
}
if (r < 0) if (r < 0)
return r; return r;
@ -652,9 +611,9 @@ static int load_credential(
* directory we received ourselves. We don't support the AF_UNIX stuff in this mode, since we * directory we received ourselves. We don't support the AF_UNIX stuff in this mode, since we
* are operating on a credential store, i.e. this is guaranteed to be regular files. */ * are operating on a credential store, i.e. this is guaranteed to be regular files. */
r = credential_search_path(args->params, CREDENTIAL_SEARCH_PATH_ALL, &search_path); search_path = credential_search_path(args->params, CREDENTIAL_SEARCH_PATH_ALL);
if (r < 0) if (!search_path)
return r; return -ENOMEM;
missing_ok = true; missing_ok = true;
} else } else
@ -838,9 +797,9 @@ static int acquire_credentials(
ORDERED_SET_FOREACH(ic, context->import_credentials) { ORDERED_SET_FOREACH(ic, context->import_credentials) {
_cleanup_free_ char **search_path = NULL; _cleanup_free_ char **search_path = NULL;
r = credential_search_path(params, CREDENTIAL_SEARCH_PATH_TRUSTED, &search_path); search_path = credential_search_path(params, CREDENTIAL_SEARCH_PATH_TRUSTED);
if (r < 0) if (!search_path)
return r; return -ENOMEM;
args.encrypted = false; args.encrypted = false;
@ -852,10 +811,9 @@ static int acquire_credentials(
return r; return r;
search_path = strv_free(search_path); search_path = strv_free(search_path);
search_path = credential_search_path(params, CREDENTIAL_SEARCH_PATH_ENCRYPTED);
r = credential_search_path(params, CREDENTIAL_SEARCH_PATH_ENCRYPTED, &search_path); if (!search_path)
if (r < 0) return -ENOMEM;
return r;
args.encrypted = true; args.encrypted = true;

View File

@ -3,11 +3,9 @@
#include <unistd.h> #include <unistd.h>
#include "alloc-util.h" #include "alloc-util.h"
#include "bitfield.h"
#include "creds-util.h" #include "creds-util.h"
#include "dropin.h" #include "dropin.h"
#include "errno-util.h" #include "errno-util.h"
#include "extract-word.h"
#include "fd-util.h" #include "fd-util.h"
#include "fileio.h" #include "fileio.h"
#include "generator.h" #include "generator.h"
@ -29,7 +27,6 @@ static char **arg_wants = NULL;
static bool arg_debug_shell = false; static bool arg_debug_shell = false;
static char *arg_debug_tty = NULL; static char *arg_debug_tty = NULL;
static char *arg_default_debug_tty = NULL; static char *arg_default_debug_tty = NULL;
static uint32_t arg_breakpoints = 0;
STATIC_DESTRUCTOR_REGISTER(arg_default_unit, freep); STATIC_DESTRUCTOR_REGISTER(arg_default_unit, freep);
STATIC_DESTRUCTOR_REGISTER(arg_mask, strv_freep); STATIC_DESTRUCTOR_REGISTER(arg_mask, strv_freep);
@ -37,91 +34,6 @@ STATIC_DESTRUCTOR_REGISTER(arg_wants, strv_freep);
STATIC_DESTRUCTOR_REGISTER(arg_debug_tty, freep); STATIC_DESTRUCTOR_REGISTER(arg_debug_tty, freep);
STATIC_DESTRUCTOR_REGISTER(arg_default_debug_tty, freep); STATIC_DESTRUCTOR_REGISTER(arg_default_debug_tty, freep);
typedef enum BreakpointType {
BREAKPOINT_PRE_UDEV,
BREAKPOINT_PRE_BASIC,
BREAKPOINT_PRE_SYSROOT_MOUNT,
BREAKPOINT_PRE_SWITCH_ROOT,
_BREAKPOINT_TYPE_MAX,
_BREAKPOINT_TYPE_INVALID = -EINVAL,
} BreakpointType;
typedef enum BreakpointValidity {
BREAKPOINT_DEFAULT = 1 << 0,
BREAKPOINT_IN_INITRD = 1 << 1,
BREAKPOINT_ON_HOST = 1 << 2,
} BreakpointValidity;
typedef struct BreakpointInfo {
BreakpointType type;
const char *name;
const char *unit;
BreakpointValidity validity;
} BreakpointInfo;
static const struct BreakpointInfo breakpoint_info_table[_BREAKPOINT_TYPE_MAX] = {
{ BREAKPOINT_PRE_UDEV, "pre-udev", "breakpoint-pre-udev.service", BREAKPOINT_IN_INITRD | BREAKPOINT_ON_HOST },
{ BREAKPOINT_PRE_BASIC, "pre-basic", "breakpoint-pre-basic.service", BREAKPOINT_IN_INITRD | BREAKPOINT_ON_HOST },
{ BREAKPOINT_PRE_SYSROOT_MOUNT, "pre-mount", "breakpoint-pre-mount.service", BREAKPOINT_IN_INITRD },
{ BREAKPOINT_PRE_SWITCH_ROOT, "pre-switch-root", "breakpoint-pre-switch-root.service", BREAKPOINT_IN_INITRD | BREAKPOINT_DEFAULT },
};
static BreakpointType parse_breakpoint_from_string_one(const char *s) {
assert(s);
FOREACH_ARRAY(i, breakpoint_info_table, ELEMENTSOF(breakpoint_info_table))
if (streq(i->name, s))
return i->type;
return _BREAKPOINT_TYPE_INVALID;
}
static int parse_breakpoint_from_string(const char *s, uint32_t *ret_breakpoints) {
uint32_t breakpoints = 0;
int r;
assert(ret_breakpoints);
/* Empty value? set default breakpoint */
if (isempty(s)) {
if (in_initrd()) {
FOREACH_ARRAY(i, breakpoint_info_table, ELEMENTSOF(breakpoint_info_table))
if (i->validity & BREAKPOINT_DEFAULT) {
breakpoints |= 1 << i->type;
break;
}
} else
log_warning("No default breakpoint defined on the host, ignoring breakpoint request from kernel command line.");
} else
for (;;) {
_cleanup_free_ char *t = NULL;
BreakpointType tt;
r = extract_first_word(&s, &t, ",", EXTRACT_DONT_COALESCE_SEPARATORS);
if (r < 0)
return r;
if (r == 0)
break;
tt = parse_breakpoint_from_string_one(t);
if (tt < 0) {
log_warning("Invalid breakpoint value '%s', ignoring.", t);
continue;
}
if (in_initrd() && !FLAGS_SET(breakpoint_info_table[tt].validity, BREAKPOINT_IN_INITRD))
log_warning("Breakpoint '%s' not valid in the initrd, ignoring.", t);
else if (!in_initrd() && !FLAGS_SET(breakpoint_info_table[tt].validity, BREAKPOINT_ON_HOST))
log_warning("Breakpoint '%s' not valid on the host, ignoring.", t);
else
breakpoints |= 1 << tt;
}
*ret_breakpoints = breakpoints;
return 0;
}
static int parse_proc_cmdline_item(const char *key, const char *value, void *data) { static int parse_proc_cmdline_item(const char *key, const char *value, void *data) {
int r; int r;
@ -176,15 +88,6 @@ static int parse_proc_cmdline_item(const char *key, const char *value, void *dat
return free_and_strdup_warn(&arg_default_unit, value); return free_and_strdup_warn(&arg_default_unit, value);
} else if (streq(key, "systemd.break")) {
uint32_t breakpoints = 0;
r = parse_breakpoint_from_string(value, &breakpoints);
if (r < 0)
return log_warning_errno(r, "Failed to parse breakpoint value '%s': %m", value);
arg_breakpoints |= breakpoints;
} else if (!value) { } else if (!value) {
const char *target; const char *target;
@ -366,10 +269,6 @@ static int run(const char *dest, const char *dest_early, const char *dest_late)
RET_GATHER(r, install_debug_shell_dropin()); RET_GATHER(r, install_debug_shell_dropin());
} }
BIT_FOREACH(i, arg_breakpoints)
if (strv_extend(&arg_wants, breakpoint_info_table[i].unit) < 0)
return log_oom();
if (get_credentials_dir(&credentials_dir) >= 0) if (get_credentials_dir(&credentials_dir) >= 0)
RET_GATHER(r, process_unit_credentials(credentials_dir)); RET_GATHER(r, process_unit_credentials(credentials_dir));

View File

@ -95,7 +95,6 @@ static char *arg_loop_ref = NULL;
static ImagePolicy *arg_image_policy = NULL; static ImagePolicy *arg_image_policy = NULL;
static bool arg_mtree_hash = true; static bool arg_mtree_hash = true;
static bool arg_via_service = false; static bool arg_via_service = false;
static RuntimeScope arg_runtime_scope = _RUNTIME_SCOPE_INVALID;
STATIC_DESTRUCTOR_REGISTER(arg_image, freep); STATIC_DESTRUCTOR_REGISTER(arg_image, freep);
STATIC_DESTRUCTOR_REGISTER(arg_root, freep); STATIC_DESTRUCTOR_REGISTER(arg_root, freep);
@ -152,8 +151,6 @@ static int help(void) {
" Generate JSON output\n" " Generate JSON output\n"
" --loop-ref=NAME Set reference string for loopback device\n" " --loop-ref=NAME Set reference string for loopback device\n"
" --mtree-hash=BOOL Whether to include SHA256 hash in the mtree output\n" " --mtree-hash=BOOL Whether to include SHA256 hash in the mtree output\n"
" --user Discover user images\n"
" --system Discover system images\n"
"\n%3$sCommands:%4$s\n" "\n%3$sCommands:%4$s\n"
" -h --help Show this help\n" " -h --help Show this help\n"
" --version Show package version\n" " --version Show package version\n"
@ -277,8 +274,6 @@ static int parse_argv(int argc, char *argv[]) {
ARG_VALIDATE, ARG_VALIDATE,
ARG_MTREE_HASH, ARG_MTREE_HASH,
ARG_MAKE_ARCHIVE, ARG_MAKE_ARCHIVE,
ARG_SYSTEM,
ARG_USER,
}; };
static const struct option options[] = { static const struct option options[] = {
@ -312,13 +307,10 @@ static int parse_argv(int argc, char *argv[]) {
{ "validate", no_argument, NULL, ARG_VALIDATE }, { "validate", no_argument, NULL, ARG_VALIDATE },
{ "mtree-hash", required_argument, NULL, ARG_MTREE_HASH }, { "mtree-hash", required_argument, NULL, ARG_MTREE_HASH },
{ "make-archive", no_argument, NULL, ARG_MAKE_ARCHIVE }, { "make-archive", no_argument, NULL, ARG_MAKE_ARCHIVE },
{ "system", no_argument, NULL, ARG_SYSTEM },
{ "user", no_argument, NULL, ARG_USER },
{} {}
}; };
_cleanup_free_ char **buf = NULL; /* we use free(), not strv_free() here, as we don't copy the strings here */ _cleanup_free_ char **buf = NULL; /* we use free(), not strv_free() here, as we don't copy the strings here */
bool system_scope_requested = false, user_scope_requested = false;
int c, r; int c, r;
assert(argc >= 0); assert(argc >= 0);
@ -539,6 +531,7 @@ static int parse_argv(int argc, char *argv[]) {
break; break;
case ARG_MAKE_ARCHIVE: case ARG_MAKE_ARCHIVE:
r = dlopen_libarchive(); r = dlopen_libarchive();
if (r < 0) if (r < 0)
return log_error_errno(r, "Archive support not available (compiled without libarchive, or libarchive not installed?)."); return log_error_errno(r, "Archive support not available (compiled without libarchive, or libarchive not installed?).");
@ -546,14 +539,6 @@ static int parse_argv(int argc, char *argv[]) {
arg_action = ACTION_MAKE_ARCHIVE; arg_action = ACTION_MAKE_ARCHIVE;
break; break;
case ARG_SYSTEM:
system_scope_requested = true;
break;
case ARG_USER:
user_scope_requested = true;
break;
case '?': case '?':
return -EINVAL; return -EINVAL;
@ -562,10 +547,6 @@ static int parse_argv(int argc, char *argv[]) {
} }
} }
if (system_scope_requested || user_scope_requested)
arg_runtime_scope = system_scope_requested && user_scope_requested ? _RUNTIME_SCOPE_INVALID :
system_scope_requested ? RUNTIME_SCOPE_SYSTEM : RUNTIME_SCOPE_USER;
switch (arg_action) { switch (arg_action) {
case ACTION_DISSECT: case ACTION_DISSECT:
@ -1870,7 +1851,7 @@ static int action_discover(void) {
return log_oom(); return log_oom();
for (ImageClass cl = 0; cl < _IMAGE_CLASS_MAX; cl++) { for (ImageClass cl = 0; cl < _IMAGE_CLASS_MAX; cl++) {
r = image_discover(arg_runtime_scope, cl, NULL, images); r = image_discover(cl, NULL, images);
if (r < 0) if (r < 0)
return log_error_errno(r, "Failed to discover images: %m"); return log_error_errno(r, "Failed to discover images: %m");
} }

View File

@ -28,33 +28,20 @@
#include "memory-util-fundamental.h" #include "memory-util-fundamental.h"
#include "sha1-fundamental.h" #include "sha1-fundamental.h"
static void get_chid( static void get_chid(const char16_t *const smbios_fields[static _CHID_SMBIOS_FIELDS_MAX], uint32_t mask, EFI_GUID *ret_chid) {
const char16_t *const smbios_fields[static _CHID_SMBIOS_FIELDS_MAX],
uint32_t mask,
EFI_GUID *ret_chid) {
assert(mask != 0); assert(mask != 0);
assert(ret_chid); assert(ret_chid);
const EFI_GUID namespace = { UINT32_C(0x12d8ff70), UINT16_C(0x7f4c), UINT16_C(0x7d4c), {} }; /* Swapped to BE */
struct sha1_ctx ctx = {}; struct sha1_ctx ctx = {};
sha1_init_ctx(&ctx); sha1_init_ctx(&ctx);
static const EFI_GUID namespace = { UINT32_C(0x12d8ff70), UINT16_C(0x7f4c), UINT16_C(0x7d4c), {} }; /* Swapped to BE */
sha1_process_bytes(&namespace, sizeof(namespace), &ctx); sha1_process_bytes(&namespace, sizeof(namespace), &ctx);
for (ChidSmbiosFields i = 0; i < _CHID_SMBIOS_FIELDS_MAX; i++) { for (unsigned i = 0; i < _CHID_SMBIOS_FIELDS_MAX; i++)
if (!FLAGS_SET(mask, UINT32_C(1) << i)) if ((mask >> i) & 1) {
continue;
if (!smbios_fields[i]) {
/* If some SMBIOS field is missing, don't generate the CHID, as per spec */
memzero(ret_chid, sizeof(EFI_GUID));
return;
}
if (i > 0) if (i > 0)
sha1_process_bytes(L"&", 2, &ctx); sha1_process_bytes(L"&", 2, &ctx);
sha1_process_bytes(smbios_fields[i], strlen16(smbios_fields[i]) * sizeof(char16_t), &ctx); sha1_process_bytes(smbios_fields[i], strlen16(smbios_fields[i]) * sizeof(char16_t), &ctx);
} }
@ -75,30 +62,6 @@ static void get_chid(
} }
const uint32_t chid_smbios_table[CHID_TYPES_MAX] = { const uint32_t chid_smbios_table[CHID_TYPES_MAX] = {
[0] = (UINT32_C(1) << CHID_SMBIOS_MANUFACTURER) |
(UINT32_C(1) << CHID_SMBIOS_FAMILY) |
(UINT32_C(1) << CHID_SMBIOS_PRODUCT_NAME) |
(UINT32_C(1) << CHID_SMBIOS_PRODUCT_SKU) |
(UINT32_C(1) << CHID_SMBIOS_BIOS_VENDOR) |
(UINT32_C(1) << CHID_SMBIOS_BIOS_VERSION) |
(UINT32_C(1) << CHID_SMBIOS_BIOS_MAJOR) |
(UINT32_C(1) << CHID_SMBIOS_BIOS_MINOR),
[1] = (UINT32_C(1) << CHID_SMBIOS_MANUFACTURER) |
(UINT32_C(1) << CHID_SMBIOS_FAMILY) |
(UINT32_C(1) << CHID_SMBIOS_PRODUCT_NAME) |
(UINT32_C(1) << CHID_SMBIOS_BIOS_VENDOR) |
(UINT32_C(1) << CHID_SMBIOS_BIOS_VERSION) |
(UINT32_C(1) << CHID_SMBIOS_BIOS_MAJOR) |
(UINT32_C(1) << CHID_SMBIOS_BIOS_MINOR),
[2] = (UINT32_C(1) << CHID_SMBIOS_MANUFACTURER) |
(UINT32_C(1) << CHID_SMBIOS_PRODUCT_NAME) |
(UINT32_C(1) << CHID_SMBIOS_BIOS_VENDOR) |
(UINT32_C(1) << CHID_SMBIOS_BIOS_VERSION) |
(UINT32_C(1) << CHID_SMBIOS_BIOS_MAJOR) |
(UINT32_C(1) << CHID_SMBIOS_BIOS_MINOR),
[3] = (UINT32_C(1) << CHID_SMBIOS_MANUFACTURER) | [3] = (UINT32_C(1) << CHID_SMBIOS_MANUFACTURER) |
(UINT32_C(1) << CHID_SMBIOS_FAMILY) | (UINT32_C(1) << CHID_SMBIOS_FAMILY) |
(UINT32_C(1) << CHID_SMBIOS_PRODUCT_NAME) | (UINT32_C(1) << CHID_SMBIOS_PRODUCT_NAME) |
@ -139,26 +102,18 @@ const uint32_t chid_smbios_table[CHID_TYPES_MAX] = {
[11] = (UINT32_C(1) << CHID_SMBIOS_MANUFACTURER) | [11] = (UINT32_C(1) << CHID_SMBIOS_MANUFACTURER) |
(UINT32_C(1) << CHID_SMBIOS_FAMILY), (UINT32_C(1) << CHID_SMBIOS_FAMILY),
[12] = (UINT32_C(1) << CHID_SMBIOS_MANUFACTURER) |
(UINT32_C(1) << CHID_SMBIOS_ENCLOSURE_TYPE),
[13] = (UINT32_C(1) << CHID_SMBIOS_MANUFACTURER) | [13] = (UINT32_C(1) << CHID_SMBIOS_MANUFACTURER) |
(UINT32_C(1) << CHID_SMBIOS_BASEBOARD_MANUFACTURER) | (UINT32_C(1) << CHID_SMBIOS_BASEBOARD_MANUFACTURER) |
(UINT32_C(1) << CHID_SMBIOS_BASEBOARD_PRODUCT), (UINT32_C(1) << CHID_SMBIOS_BASEBOARD_PRODUCT),
[14] = (UINT32_C(1) << CHID_SMBIOS_MANUFACTURER),
}; };
void chid_calculate(const char16_t *const smbios_fields[static _CHID_SMBIOS_FIELDS_MAX], EFI_GUID ret_chids[static CHID_TYPES_MAX]) { void chid_calculate(const char16_t *const smbios_fields[static _CHID_SMBIOS_FIELDS_MAX], EFI_GUID ret_chids[static CHID_TYPES_MAX]) {
assert(smbios_fields); assert(smbios_fields);
assert(ret_chids); assert(ret_chids);
for (size_t i = 0; i < CHID_TYPES_MAX; i++) { for (size_t i = 0; i < CHID_TYPES_MAX; i++)
if (chid_smbios_table[i] == 0) { if (chid_smbios_table[i] != 0)
memzero(&ret_chids[i], sizeof(EFI_GUID));
continue;
}
get_chid(smbios_fields, chid_smbios_table[i], &ret_chids[i]); get_chid(smbios_fields, chid_smbios_table[i], &ret_chids[i]);
} else
memzero(&ret_chids[i], sizeof(EFI_GUID));
} }

View File

@ -20,11 +20,6 @@ typedef enum ChidSmbiosFields {
CHID_SMBIOS_PRODUCT_SKU, CHID_SMBIOS_PRODUCT_SKU,
CHID_SMBIOS_BASEBOARD_MANUFACTURER, CHID_SMBIOS_BASEBOARD_MANUFACTURER,
CHID_SMBIOS_BASEBOARD_PRODUCT, CHID_SMBIOS_BASEBOARD_PRODUCT,
CHID_SMBIOS_BIOS_VENDOR,
CHID_SMBIOS_BIOS_VERSION,
CHID_SMBIOS_BIOS_MAJOR,
CHID_SMBIOS_BIOS_MINOR,
CHID_SMBIOS_ENCLOSURE_TYPE,
_CHID_SMBIOS_FIELDS_MAX, _CHID_SMBIOS_FIELDS_MAX,
} ChidSmbiosFields; } ChidSmbiosFields;

View File

@ -25,7 +25,6 @@
static ImportCompressType arg_compress = IMPORT_COMPRESS_UNKNOWN; static ImportCompressType arg_compress = IMPORT_COMPRESS_UNKNOWN;
static ImageClass arg_class = IMAGE_MACHINE; static ImageClass arg_class = IMAGE_MACHINE;
static RuntimeScope arg_runtime_scope = _RUNTIME_SCOPE_INVALID;
static void determine_compression_from_filename(const char *p) { static void determine_compression_from_filename(const char *p) {
@ -67,7 +66,7 @@ static int export_tar(int argc, char *argv[], void *userdata) {
local = argv[1]; local = argv[1];
if (image_name_is_valid(local)) { if (image_name_is_valid(local)) {
r = image_find(arg_runtime_scope, arg_class, local, NULL, &image); r = image_find(arg_class, local, NULL, &image);
if (r == -ENOENT) if (r == -ENOENT)
return log_error_errno(r, "Image %s not found.", local); return log_error_errno(r, "Image %s not found.", local);
if (r < 0) if (r < 0)
@ -140,7 +139,7 @@ static int export_raw(int argc, char *argv[], void *userdata) {
local = argv[1]; local = argv[1];
if (image_name_is_valid(local)) { if (image_name_is_valid(local)) {
r = image_find(arg_runtime_scope, arg_class, local, NULL, &image); r = image_find(arg_class, local, NULL, &image);
if (r == -ENOENT) if (r == -ENOENT)
return log_error_errno(r, "Image %s not found.", local); return log_error_errno(r, "Image %s not found.", local);
if (r < 0) if (r < 0)

View File

@ -34,7 +34,6 @@ static bool arg_sync = true;
static bool arg_direct = false; static bool arg_direct = false;
static const char *arg_image_root = NULL; static const char *arg_image_root = NULL;
static ImageClass arg_class = IMAGE_MACHINE; static ImageClass arg_class = IMAGE_MACHINE;
static RuntimeScope arg_runtime_scope = _RUNTIME_SCOPE_INVALID;
typedef struct ProgressInfo { typedef struct ProgressInfo {
RateLimit limit; RateLimit limit;
@ -146,7 +145,7 @@ static int import_fs(int argc, char *argv[], void *userdata) {
return log_oom(); return log_oom();
if (!arg_force) { if (!arg_force) {
r = image_find(arg_runtime_scope, arg_class, local, NULL, NULL); r = image_find(arg_class, local, NULL, NULL);
if (r < 0) { if (r < 0) {
if (r != -ENOENT) if (r != -ENOENT)
return log_error_errno(r, "Failed to check whether image '%s' exists: %m", local); return log_error_errno(r, "Failed to check whether image '%s' exists: %m", local);

View File

@ -30,7 +30,6 @@ static const char *arg_image_root = NULL;
static ImportFlags arg_import_flags = IMPORT_BTRFS_SUBVOL | IMPORT_BTRFS_QUOTA | IMPORT_CONVERT_QCOW2 | IMPORT_SYNC; static ImportFlags arg_import_flags = IMPORT_BTRFS_SUBVOL | IMPORT_BTRFS_QUOTA | IMPORT_CONVERT_QCOW2 | IMPORT_SYNC;
static uint64_t arg_offset = UINT64_MAX, arg_size_max = UINT64_MAX; static uint64_t arg_offset = UINT64_MAX, arg_size_max = UINT64_MAX;
static ImageClass arg_class = IMAGE_MACHINE; static ImageClass arg_class = IMAGE_MACHINE;
static RuntimeScope arg_runtime_scope = _RUNTIME_SCOPE_INVALID;
static int normalize_local(const char *local, char **ret) { static int normalize_local(const char *local, char **ret) {
_cleanup_free_ char *ll = NULL; _cleanup_free_ char *ll = NULL;
@ -64,7 +63,7 @@ static int normalize_local(const char *local, char **ret) {
local = "imported"; local = "imported";
if (!FLAGS_SET(arg_import_flags, IMPORT_FORCE)) { if (!FLAGS_SET(arg_import_flags, IMPORT_FORCE)) {
r = image_find(arg_runtime_scope, arg_class, local, NULL, NULL); r = image_find(arg_class, local, NULL, NULL);
if (r < 0) { if (r < 0) {
if (r != -ENOENT) if (r != -ENOENT)
return log_error_errno(r, "Failed to check whether image '%s' exists: %m", local); return log_error_errno(r, "Failed to check whether image '%s' exists: %m", local);

View File

@ -111,8 +111,6 @@ struct Manager {
bool use_btrfs_subvol; bool use_btrfs_subvol;
bool use_btrfs_quota; bool use_btrfs_quota;
RuntimeScope runtime_scope; /* for now: always RUNTIME_SCOPE_SYSTEM */
}; };
#define TRANSFERS_MAX 64 #define TRANSFERS_MAX 64
@ -723,7 +721,6 @@ static int manager_new(Manager **ret) {
*m = (Manager) { *m = (Manager) {
.use_btrfs_subvol = true, .use_btrfs_subvol = true,
.use_btrfs_quota = true, .use_btrfs_quota = true,
.runtime_scope = RUNTIME_SCOPE_SYSTEM,
}; };
r = sd_event_default(&m->event); r = sd_event_default(&m->event);
@ -1335,7 +1332,6 @@ static int method_cancel_transfer(sd_bus_message *msg, void *userdata, sd_bus_er
static int method_list_images(sd_bus_message *msg, void *userdata, sd_bus_error *error) { static int method_list_images(sd_bus_message *msg, void *userdata, sd_bus_error *error) {
_cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL; _cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL;
ImageClass class = _IMAGE_CLASS_INVALID; ImageClass class = _IMAGE_CLASS_INVALID;
Manager *m = ASSERT_PTR(userdata);
int r; int r;
assert(msg); assert(msg);
@ -1376,7 +1372,7 @@ static int method_list_images(sd_bus_message *msg, void *userdata, sd_bus_error
if (!h) if (!h)
return -ENOMEM; return -ENOMEM;
r = image_discover(m->runtime_scope, c, /* root= */ NULL, h); r = image_discover(c, /* root= */ NULL, h);
if (r < 0) { if (r < 0) {
if (class >= 0) if (class >= 0)
return r; return r;

View File

@ -33,7 +33,6 @@ static ImportFlags arg_import_flags = IMPORT_PULL_SETTINGS | IMPORT_PULL_ROOTHAS
static uint64_t arg_offset = UINT64_MAX, arg_size_max = UINT64_MAX; static uint64_t arg_offset = UINT64_MAX, arg_size_max = UINT64_MAX;
static char *arg_checksum = NULL; static char *arg_checksum = NULL;
static ImageClass arg_class = IMAGE_MACHINE; static ImageClass arg_class = IMAGE_MACHINE;
static RuntimeScope arg_runtime_scope = _RUNTIME_SCOPE_INVALID;
STATIC_DESTRUCTOR_REGISTER(arg_checksum, freep); STATIC_DESTRUCTOR_REGISTER(arg_checksum, freep);
@ -67,7 +66,7 @@ static int normalize_local(const char *local, const char *url, char **ret) {
local); local);
if (!FLAGS_SET(arg_import_flags, IMPORT_FORCE)) { if (!FLAGS_SET(arg_import_flags, IMPORT_FORCE)) {
r = image_find(arg_runtime_scope, arg_class, local, NULL, NULL); r = image_find(arg_class, local, NULL, NULL);
if (r < 0) { if (r < 0) {
if (r != -ENOENT) if (r != -ENOENT)
return log_error_errno(r, "Failed to check whether image '%s' exists: %m", local); return log_error_errno(r, "Failed to check whether image '%s' exists: %m", local);

View File

@ -84,19 +84,3 @@ static inline char** generator_binary_paths(RuntimeScope runtime_scope) {
static inline char** env_generator_binary_paths(RuntimeScope runtime_scope) { static inline char** env_generator_binary_paths(RuntimeScope runtime_scope) {
return generator_binary_paths_internal(runtime_scope, true); return generator_binary_paths_internal(runtime_scope, true);
} }
static inline int credential_store_path(RuntimeScope runtime_scope, char ***ret) {
return sd_path_lookup_strv(
runtime_scope == RUNTIME_SCOPE_SYSTEM ?
SD_PATH_SYSTEM_SEARCH_CREDENTIAL_STORE : SD_PATH_USER_SEARCH_CREDENTIAL_STORE,
/* suffix= */ NULL,
ret);
}
static inline int credential_store_path_encrypted(RuntimeScope runtime_scope, char ***ret) {
return sd_path_lookup_strv(
runtime_scope == RUNTIME_SCOPE_SYSTEM ?
SD_PATH_SYSTEM_SEARCH_CREDENTIAL_STORE_ENCRYPTED : SD_PATH_USER_SEARCH_CREDENTIAL_STORE_ENCRYPTED,
/* suffix= */ NULL,
ret);
}

View File

@ -36,12 +36,7 @@ static int from_environment(const char *envname, const char *fallback, const cha
return -ENXIO; return -ENXIO;
} }
static int from_home_dir( static int from_home_dir(const char *envname, const char *suffix, char **buffer, const char **ret) {
const char *envname,
const char *suffix,
char **buffer,
const char **ret) {
_cleanup_free_ char *h = NULL; _cleanup_free_ char *h = NULL;
int r; int r;
@ -355,30 +350,6 @@ static int get_path(uint64_t type, char **buffer, const char **ret) {
case SD_PATH_SYSTEMD_USER_ENVIRONMENT_GENERATOR: case SD_PATH_SYSTEMD_USER_ENVIRONMENT_GENERATOR:
*ret = USER_ENV_GENERATOR_DIR; *ret = USER_ENV_GENERATOR_DIR;
return 0; return 0;
case SD_PATH_SYSTEM_CREDENTIAL_STORE:
*ret = "/etc/credstore";
return 0;
case SD_PATH_SYSTEM_CREDENTIAL_STORE_ENCRYPTED:
*ret = "/etc/credstore.encrypted";
return 0;
case SD_PATH_USER_CREDENTIAL_STORE:
r = xdg_user_config_dir("credstore", buffer);
if (r < 0)
return r;
*ret = *buffer;
return 0;
case SD_PATH_USER_CREDENTIAL_STORE_ENCRYPTED:
r = xdg_user_config_dir("credstore.encrypted", buffer);
if (r < 0)
return r;
*ret = *buffer;
return 0;
} }
return -EOPNOTSUPP; return -EOPNOTSUPP;
@ -395,12 +366,12 @@ static int get_path_alloc(uint64_t type, const char *suffix, char **ret) {
if (r < 0) if (r < 0)
return r; return r;
if (!isempty(suffix)) { if (suffix) {
char *suffixed = path_join(p, suffix); char *suffixed = path_join(p, suffix);
if (!suffixed) if (!suffixed)
return -ENOMEM; return -ENOMEM;
path_simplify_full(suffixed, PATH_SIMPLIFY_KEEP_TRAILING_SLASH); path_simplify(suffixed);
free_and_replace(buffer, suffixed); free_and_replace(buffer, suffixed);
} else if (!buffer) { } else if (!buffer) {
@ -630,55 +601,8 @@ static int get_search(uint64_t type, char ***ret) {
case SD_PATH_SYSTEMD_SEARCH_NETWORK: case SD_PATH_SYSTEMD_SEARCH_NETWORK:
return strv_from_nulstr(ret, NETWORK_DIRS_NULSTR); return strv_from_nulstr(ret, NETWORK_DIRS_NULSTR);
case SD_PATH_SYSTEM_SEARCH_CREDENTIAL_STORE:
case SD_PATH_SYSTEM_SEARCH_CREDENTIAL_STORE_ENCRYPTED: {
const char *suffix =
type == SD_PATH_SYSTEM_SEARCH_CREDENTIAL_STORE_ENCRYPTED ? "credstore.encrypted" : "credstore";
_cleanup_strv_free_ char **l = NULL;
FOREACH_STRING(d, CONF_PATHS("")) {
char *j = path_join(d, suffix);
if (!j)
return -ENOMEM;
r = strv_consume(&l, TAKE_PTR(j));
if (r < 0)
return r;
} }
*ret = TAKE_PTR(l);
return 0;
}
case SD_PATH_USER_SEARCH_CREDENTIAL_STORE:
case SD_PATH_USER_SEARCH_CREDENTIAL_STORE_ENCRYPTED: {
const char *suffix =
type == SD_PATH_USER_SEARCH_CREDENTIAL_STORE_ENCRYPTED ? "credstore.encrypted" : "credstore";
static const uint64_t dirs[] = {
SD_PATH_USER_CONFIGURATION,
SD_PATH_USER_RUNTIME,
SD_PATH_USER_LIBRARY_PRIVATE,
};
_cleanup_strv_free_ char **l = NULL;
FOREACH_ELEMENT(d, dirs) {
_cleanup_free_ char *p = NULL;
r = sd_path_lookup(*d, suffix, &p);
if (r == -ENXIO)
continue;
if (r < 0)
return r;
r = strv_consume(&l, TAKE_PTR(p));
if (r < 0)
return r;
}
*ret = TAKE_PTR(l);
return 0;
}}
return -EOPNOTSUPP; return -EOPNOTSUPP;
} }
@ -713,7 +637,7 @@ _public_ int sd_path_lookup_strv(uint64_t type, const char *suffix, char ***ret)
if (!path_extend(i, suffix)) if (!path_extend(i, suffix))
return -ENOMEM; return -ENOMEM;
path_simplify_full(*i, PATH_SIMPLIFY_KEEP_TRAILING_SLASH); path_simplify(*i);
} }
*ret = TAKE_PTR(l); *ret = TAKE_PTR(l);

View File

@ -178,7 +178,7 @@ int bus_image_method_clone(
return sd_bus_error_set_errnof(error, r, "Failed to fork(): %m"); return sd_bus_error_set_errnof(error, r, "Failed to fork(): %m");
if (r == 0) { if (r == 0) {
errno_pipe_fd[0] = safe_close(errno_pipe_fd[0]); errno_pipe_fd[0] = safe_close(errno_pipe_fd[0]);
r = image_clone(image, new_name, read_only, m->runtime_scope); r = image_clone(image, new_name, read_only);
report_errno_and_exit(errno_pipe_fd[1], r); report_errno_and_exit(errno_pipe_fd[1], r);
} }
@ -402,7 +402,6 @@ char* image_bus_path(const char *name) {
static int image_node_enumerator(sd_bus *bus, const char *path, void *userdata, char ***nodes, sd_bus_error *error) { static int image_node_enumerator(sd_bus *bus, const char *path, void *userdata, char ***nodes, sd_bus_error *error) {
_cleanup_hashmap_free_ Hashmap *images = NULL; _cleanup_hashmap_free_ Hashmap *images = NULL;
_cleanup_strv_free_ char **l = NULL; _cleanup_strv_free_ char **l = NULL;
Manager *m = ASSERT_PTR(userdata);
Image *image; Image *image;
int r; int r;
@ -414,7 +413,7 @@ static int image_node_enumerator(sd_bus *bus, const char *path, void *userdata,
if (!images) if (!images)
return -ENOMEM; return -ENOMEM;
r = image_discover(m->runtime_scope, IMAGE_MACHINE, NULL, images); r = image_discover(IMAGE_MACHINE, NULL, images);
if (r < 0) if (r < 0)
return r; return r;

View File

@ -148,7 +148,7 @@ int vl_method_clone_image(sd_varlink *link, sd_json_variant *parameters, sd_varl
return log_debug_errno(r, "Failed to fork: %m"); return log_debug_errno(r, "Failed to fork: %m");
if (r == 0) { if (r == 0) {
errno_pipe_fd[0] = safe_close(errno_pipe_fd[0]); errno_pipe_fd[0] = safe_close(errno_pipe_fd[0]);
r = image_clone(image, p.new_name, p.read_only > 0, manager->runtime_scope); r = image_clone(image, p.new_name, p.read_only > 0);
report_errno_and_exit(errno_pipe_fd[1], r); report_errno_and_exit(errno_pipe_fd[1], r);
} }

View File

@ -440,7 +440,7 @@ int manager_acquire_image(Manager *m, const char *name, Image **ret) {
return log_debug_errno(r, "Failed to enable source: %m") ; return log_debug_errno(r, "Failed to enable source: %m") ;
_cleanup_(image_unrefp) Image *image = NULL; _cleanup_(image_unrefp) Image *image = NULL;
r = image_find(m->runtime_scope, IMAGE_MACHINE, name, NULL, &image); r = image_find(IMAGE_MACHINE, name, NULL, &image);
if (r < 0) if (r < 0)
return log_debug_errno(r, "Failed to find image: %m"); return log_debug_errno(r, "Failed to find image: %m");
@ -467,7 +467,7 @@ int rename_image_and_update_cache(Manager *m, Image *image, const char* new_name
/* The image is cached with its name, hence it is necessary to remove from the cache before renaming. */ /* The image is cached with its name, hence it is necessary to remove from the cache before renaming. */
assert_se(hashmap_remove_value(m->image_cache, image->name, image)); assert_se(hashmap_remove_value(m->image_cache, image->name, image));
r = image_rename(image, new_name, m->runtime_scope); r = image_rename(image, new_name);
if (r < 0) { if (r < 0) {
image = image_unref(image); image = image_unref(image);
return r; return r;

View File

@ -123,7 +123,7 @@ static int method_get_image(sd_bus_message *message, void *userdata, sd_bus_erro
if (r < 0) if (r < 0)
return r; return r;
r = image_find(m->runtime_scope, IMAGE_MACHINE, name, NULL, NULL); r = image_find(IMAGE_MACHINE, name, NULL, NULL);
if (r == -ENOENT) if (r == -ENOENT)
return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_IMAGE, "No image '%s' known", name); return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_IMAGE, "No image '%s' known", name);
if (r < 0) if (r < 0)
@ -476,7 +476,7 @@ static int method_list_images(sd_bus_message *message, void *userdata, sd_bus_er
if (!images) if (!images)
return -ENOMEM; return -ENOMEM;
r = image_discover(m->runtime_scope, IMAGE_MACHINE, NULL, images); r = image_discover(IMAGE_MACHINE, NULL, images);
if (r < 0) if (r < 0)
return r; return r;
@ -753,7 +753,7 @@ static int method_clean_pool(sd_bus_message *message, void *userdata, sd_bus_err
goto child_fail; goto child_fail;
} }
r = image_discover(m->runtime_scope, IMAGE_MACHINE, NULL, images); r = image_discover(IMAGE_MACHINE, NULL, images);
if (r < 0) if (r < 0)
goto child_fail; goto child_fail;

View File

@ -641,7 +641,6 @@ static int list_image_one_and_maybe_read_metadata(sd_varlink *link, Image *image
} }
static int vl_method_list_images(sd_varlink *link, sd_json_variant *parameters, sd_varlink_method_flags_t flags, void *userdata) { static int vl_method_list_images(sd_varlink *link, sd_json_variant *parameters, sd_varlink_method_flags_t flags, void *userdata) {
Manager *m = ASSERT_PTR(userdata);
struct params { struct params {
const char *image_name; const char *image_name;
AcquireMetadata acquire_metadata; AcquireMetadata acquire_metadata;
@ -668,7 +667,7 @@ static int vl_method_list_images(sd_varlink *link, sd_json_variant *parameters,
if (!image_name_is_valid(p.image_name)) if (!image_name_is_valid(p.image_name))
return sd_varlink_error_invalid_parameter_name(link, "name"); return sd_varlink_error_invalid_parameter_name(link, "name");
r = image_find(m->runtime_scope, IMAGE_MACHINE, p.image_name, /* root = */ NULL, &found); r = image_find(IMAGE_MACHINE, p.image_name, /* root = */ NULL, &found);
if (r == -ENOENT) if (r == -ENOENT)
return sd_varlink_error(link, "io.systemd.MachineImage.NoSuchImage", NULL); return sd_varlink_error(link, "io.systemd.MachineImage.NoSuchImage", NULL);
if (r < 0) if (r < 0)
@ -684,7 +683,7 @@ static int vl_method_list_images(sd_varlink *link, sd_json_variant *parameters,
if (!images) if (!images)
return -ENOMEM; return -ENOMEM;
r = image_discover(m->runtime_scope, IMAGE_MACHINE, /* root = */ NULL, images); r = image_discover(IMAGE_MACHINE, /* root = */ NULL, images);
if (r < 0) if (r < 0)
return log_debug_errno(r, "Failed to discover images: %m"); return log_debug_errno(r, "Failed to discover images: %m");

View File

@ -40,14 +40,10 @@ static int manager_new(Manager **ret) {
assert(ret); assert(ret);
m = new(Manager, 1); m = new0(Manager, 1);
if (!m) if (!m)
return -ENOMEM; return -ENOMEM;
*m = (Manager) {
.runtime_scope = RUNTIME_SCOPE_SYSTEM,
};
m->machines = hashmap_new(&machine_hash_ops); m->machines = hashmap_new(&machine_hash_ops);
if (!m->machines) if (!m->machines)
return -ENOMEM; return -ENOMEM;

View File

@ -42,8 +42,6 @@ struct Manager {
sd_varlink_server *varlink_userdb_server; sd_varlink_server *varlink_userdb_server;
sd_varlink_server *varlink_machine_server; sd_varlink_server *varlink_machine_server;
RuntimeScope runtime_scope; /* for now: always RUNTIME_SCOPE_SYSTEM */
}; };
int manager_add_machine(Manager *m, const char *name, Machine **ret); int manager_add_machine(Manager *m, const char *name, Machine **ret);

View File

@ -3167,8 +3167,7 @@ static int determine_names(void) {
if (arg_machine) { if (arg_machine) {
_cleanup_(image_unrefp) Image *i = NULL; _cleanup_(image_unrefp) Image *i = NULL;
r = image_find(arg_privileged ? RUNTIME_SCOPE_SYSTEM : RUNTIME_SCOPE_USER, r = image_find(IMAGE_MACHINE, arg_machine, NULL, &i);
IMAGE_MACHINE, arg_machine, NULL, &i);
if (r == -ENOENT) if (r == -ENOENT)
return log_error_errno(r, "No image for machine '%s'.", arg_machine); return log_error_errno(r, "No image for machine '%s'.", arg_machine);
if (r < 0) if (r < 0)

View File

@ -14,7 +14,6 @@
#include "main-func.h" #include "main-func.h"
#include "pager.h" #include "pager.h"
#include "pretty-print.h" #include "pretty-print.h"
#include "sort-util.h"
#include "string-util.h" #include "string-util.h"
static const char *arg_suffix = NULL; static const char *arg_suffix = NULL;
@ -102,50 +101,27 @@ static const char* const path_table[_SD_PATH_MAX] = {
[SD_PATH_SYSTEMD_USER_ENVIRONMENT_GENERATOR] = "systemd-user-environment-generator", [SD_PATH_SYSTEMD_USER_ENVIRONMENT_GENERATOR] = "systemd-user-environment-generator",
[SD_PATH_SYSTEMD_SEARCH_SYSTEM_ENVIRONMENT_GENERATOR] = "systemd-search-system-environment-generator", [SD_PATH_SYSTEMD_SEARCH_SYSTEM_ENVIRONMENT_GENERATOR] = "systemd-search-system-environment-generator",
[SD_PATH_SYSTEMD_SEARCH_USER_ENVIRONMENT_GENERATOR] = "systemd-search-user-environment-generator", [SD_PATH_SYSTEMD_SEARCH_USER_ENVIRONMENT_GENERATOR] = "systemd-search-user-environment-generator",
[SD_PATH_SYSTEM_CREDENTIAL_STORE] = "system-credential-store",
[SD_PATH_SYSTEM_SEARCH_CREDENTIAL_STORE] = "system-search-credential-store",
[SD_PATH_SYSTEM_CREDENTIAL_STORE_ENCRYPTED] = "system-credential-store-encrypted",
[SD_PATH_SYSTEM_SEARCH_CREDENTIAL_STORE_ENCRYPTED] = "system-search-credential-store-encrypted",
[SD_PATH_USER_CREDENTIAL_STORE] = "user-credential-store",
[SD_PATH_USER_SEARCH_CREDENTIAL_STORE] = "user-search-credential-store",
[SD_PATH_USER_CREDENTIAL_STORE_ENCRYPTED] = "user-credential-store-encrypted",
[SD_PATH_USER_SEARCH_CREDENTIAL_STORE_ENCRYPTED] = "user-search-credential-store-encrypted",
}; };
static int order_cmp(const size_t *a, const size_t *b) {
assert(*a < ELEMENTSOF(path_table));
assert(*b < ELEMENTSOF(path_table));
return strcmp(path_table[*a], path_table[*b]);
}
static int list_paths(void) { static int list_paths(void) {
int ret = 0, r; int r = 0;
pager_open(arg_pager_flags); pager_open(arg_pager_flags);
size_t order[ELEMENTSOF(path_table)]; for (size_t i = 0; i < ELEMENTSOF(path_table); i++) {
for (size_t i = 0; i < ELEMENTSOF(order); i++)
order[i] = i;
typesafe_qsort(order, ELEMENTSOF(order), order_cmp);
for (size_t i = 0; i < ELEMENTSOF(order); i++) {
size_t j = order[i];
const char *t = ASSERT_PTR(path_table[j]);
_cleanup_free_ char *p = NULL; _cleanup_free_ char *p = NULL;
r = sd_path_lookup(j, arg_suffix, &p); int q;
if (r < 0) {
log_full_errno(r == -ENXIO ? LOG_DEBUG : LOG_ERR, r, "Failed to query %s, proceeding: %m", t); q = sd_path_lookup(i, arg_suffix, &p);
if (r != -ENXIO) if (q < 0) {
RET_GATHER(ret, r); log_full_errno(q == -ENXIO ? LOG_DEBUG : LOG_ERR,
q, "Failed to query %s: %m", path_table[i]);
if (q != -ENXIO)
RET_GATHER(r, q);
continue; continue;
} }
printf("%s%s:%s %s\n", ansi_highlight(), t, ansi_normal(), p); printf("%s%s:%s %s\n", ansi_highlight(), path_table[i], ansi_normal(), p);
} }
return r; return r;
@ -178,16 +154,14 @@ static int help(void) {
if (r < 0) if (r < 0)
return log_oom(); return log_oom();
printf("%s [OPTIONS...] [NAME...]\n" printf("%s [OPTIONS...] [NAME...]\n\n"
"\n%sShow system and user paths.%s\n\n" "Show system and user paths.\n\n"
" -h --help Show this help\n" " -h --help Show this help\n"
" --version Show package version\n" " --version Show package version\n"
" --suffix=SUFFIX Suffix to append to paths\n" " --suffix=SUFFIX Suffix to append to paths\n"
" --no-pager Do not pipe output into a pager\n" " --no-pager Do not pipe output into a pager\n"
"\nSee the %s for details.\n", "\nSee the %s for details.\n",
program_invocation_short_name, program_invocation_short_name,
ansi_highlight(),
ansi_normal(),
link); link);
return 0; return 0;
@ -250,11 +224,10 @@ static int run(int argc, char* argv[]) {
if (r <= 0) if (r <= 0)
return r; return r;
if (argc > optind) { if (argc > optind)
r = 0;
for (int i = optind; i < argc; i++) for (int i = optind; i < argc; i++)
RET_GATHER(r, print_path(argv[i])); RET_GATHER(r, print_path(argv[i]));
} else else
r = list_paths(); r = list_paths();
return r; return r;

View File

@ -173,7 +173,6 @@ DEFINE_PRIVATE_HASH_OPS_WITH_VALUE_DESTRUCTOR(portable_metadata_hash_ops, char,
PortableMetadata, portable_metadata_unref); PortableMetadata, portable_metadata_unref);
static int extract_now( static int extract_now(
RuntimeScope scope,
const char *where, const char *where,
char **matches, char **matches,
const char *image_name, const char *image_name,
@ -200,7 +199,6 @@ static int extract_now(
* parent. To handle both cases in one call this function also gets a 'socket_fd' parameter, which when >= 0 is * parent. To handle both cases in one call this function also gets a 'socket_fd' parameter, which when >= 0 is
* used to send the data to the parent. */ * used to send the data to the parent. */
assert(scope < _RUNTIME_SCOPE_MAX);
assert(where); assert(where);
/* First, find os-release/extension-release and send it upstream (or just save it). */ /* First, find os-release/extension-release and send it upstream (or just save it). */
@ -250,7 +248,7 @@ static int extract_now(
/* Then, send unit file data to the parent (or/and add it to the hashmap). For that we use our usual unit /* Then, send unit file data to the parent (or/and add it to the hashmap). For that we use our usual unit
* discovery logic. Note that we force looking inside of /lib/systemd/system/ for units too, as the * discovery logic. Note that we force looking inside of /lib/systemd/system/ for units too, as the
* image might have a legacy split-usr layout. */ * image might have a legacy split-usr layout. */
r = lookup_paths_init(&paths, scope, LOOKUP_PATHS_SPLIT_USR, where); r = lookup_paths_init(&paths, RUNTIME_SCOPE_SYSTEM, LOOKUP_PATHS_SPLIT_USR, where);
if (r < 0) if (r < 0)
return log_debug_errno(r, "Failed to acquire lookup paths: %m"); return log_debug_errno(r, "Failed to acquire lookup paths: %m");
@ -350,7 +348,6 @@ static int extract_now(
} }
static int portable_extract_by_path( static int portable_extract_by_path(
RuntimeScope scope,
const char *path, const char *path,
bool path_is_extension, bool path_is_extension,
bool relax_extension_release_check, bool relax_extension_release_check,
@ -384,7 +381,7 @@ static int portable_extract_by_path(
if (r < 0) if (r < 0)
return log_error_errno(r, "Failed to extract image name from path '%s': %m", path); return log_error_errno(r, "Failed to extract image name from path '%s': %m", path);
r = extract_now(scope, path, matches, image_name, path_is_extension, /* relax_extension_release_check= */ false, -1, &os_release, &unit_files); r = extract_now(path, matches, image_name, path_is_extension, /* relax_extension_release_check= */ false, -1, &os_release, &unit_files);
if (r < 0) if (r < 0)
return r; return r;
@ -461,7 +458,7 @@ static int portable_extract_by_path(
goto child_finish; goto child_finish;
} }
r = extract_now(scope, tmpdir, matches, m->image_name, path_is_extension, relax_extension_release_check, seq[1], NULL, NULL); r = extract_now(tmpdir, matches, m->image_name, path_is_extension, relax_extension_release_check, seq[1], NULL, NULL);
child_finish: child_finish:
_exit(r < 0 ? EXIT_FAILURE : EXIT_SUCCESS); _exit(r < 0 ? EXIT_FAILURE : EXIT_SUCCESS);
@ -552,7 +549,6 @@ static int portable_extract_by_path(
} }
static int extract_image_and_extensions( static int extract_image_and_extensions(
RuntimeScope scope,
const char *name_or_path, const char *name_or_path,
char **matches, char **matches,
char **extension_image_paths, char **extension_image_paths,
@ -599,7 +595,7 @@ static int extract_image_and_extensions(
name_or_path = result.path; name_or_path = result.path;
} }
r = image_find_harder(scope, IMAGE_PORTABLE, name_or_path, /* root= */ NULL, &image); r = image_find_harder(IMAGE_PORTABLE, name_or_path, /* root= */ NULL, &image);
if (r < 0) if (r < 0)
return r; return r;
@ -637,7 +633,7 @@ static int extract_image_and_extensions(
path = ext_result.path; path = ext_result.path;
} }
r = image_find_harder(scope, IMAGE_PORTABLE, path, NULL, &new); r = image_find_harder(IMAGE_PORTABLE, path, NULL, &new);
if (r < 0) if (r < 0)
return r; return r;
@ -649,7 +645,6 @@ static int extract_image_and_extensions(
} }
r = portable_extract_by_path( r = portable_extract_by_path(
scope,
image->path, image->path,
/* path_is_extension= */ false, /* path_is_extension= */ false,
/* relax_extension_release_check= */ false, /* relax_extension_release_check= */ false,
@ -692,7 +687,6 @@ static int extract_image_and_extensions(
const char *e; const char *e;
r = portable_extract_by_path( r = portable_extract_by_path(
scope,
ext->path, ext->path,
/* path_is_extension= */ true, /* path_is_extension= */ true,
relax_extension_release_check, relax_extension_release_check,
@ -760,7 +754,6 @@ static int extract_image_and_extensions(
} }
int portable_extract( int portable_extract(
RuntimeScope scope,
const char *name_or_path, const char *name_or_path,
char **matches, char **matches,
char **extension_image_paths, char **extension_image_paths,
@ -782,7 +775,6 @@ int portable_extract(
assert(name_or_path); assert(name_or_path);
r = extract_image_and_extensions( r = extract_image_and_extensions(
scope,
name_or_path, name_or_path,
matches, matches,
extension_image_paths, extension_image_paths,
@ -1434,7 +1426,6 @@ static int image_target_path(
} }
static int install_image( static int install_image(
RuntimeScope scope,
const char *image_path, const char *image_path,
PortableFlags flags, PortableFlags flags,
PortableChange **changes, PortableChange **changes,
@ -1443,14 +1434,13 @@ static int install_image(
_cleanup_free_ char *target = NULL; _cleanup_free_ char *target = NULL;
int r; int r;
assert(scope < _RUNTIME_SCOPE_MAX);
assert(image_path); assert(image_path);
/* If the image is outside of the image search also link it into it, so that it can be found with /* If the image is outside of the image search also link it into it, so that it can be found with
* short image names and is listed among the images. If we are operating in mixed mode, the image is * short image names and is listed among the images. If we are operating in mixed mode, the image is
* copied instead. */ * copied instead. */
if (image_in_search_path(scope, IMAGE_PORTABLE, NULL, image_path)) if (image_in_search_path(IMAGE_PORTABLE, NULL, image_path))
return 0; return 0;
r = image_target_path(image_path, flags, &target); r = image_target_path(image_path, flags, &target);
@ -1495,7 +1485,6 @@ static int install_image(
} }
static int install_image_and_extensions( static int install_image_and_extensions(
RuntimeScope scope,
const Image *image, const Image *image,
OrderedHashmap *extension_images, OrderedHashmap *extension_images,
PortableFlags flags, PortableFlags flags,
@ -1508,12 +1497,12 @@ static int install_image_and_extensions(
assert(image); assert(image);
ORDERED_HASHMAP_FOREACH(ext, extension_images) { ORDERED_HASHMAP_FOREACH(ext, extension_images) {
r = install_image(scope, ext->path, flags, changes, n_changes); r = install_image(ext->path, flags, changes, n_changes);
if (r < 0) if (r < 0)
return r; return r;
} }
r = install_image(scope, image->path, flags, changes, n_changes); r = install_image(image->path, flags, changes, n_changes);
if (r < 0) if (r < 0)
return r; return r;
@ -1606,7 +1595,6 @@ static void log_portable_verb(
} }
int portable_attach( int portable_attach(
RuntimeScope scope,
sd_bus *bus, sd_bus *bus,
const char *name_or_path, const char *name_or_path,
char **matches, char **matches,
@ -1627,10 +1615,7 @@ int portable_attach(
PortableMetadata *item; PortableMetadata *item;
int r; int r;
assert(scope < _RUNTIME_SCOPE_MAX);
r = extract_image_and_extensions( r = extract_image_and_extensions(
scope,
name_or_path, name_or_path,
matches, matches,
extension_image_paths, extension_image_paths,
@ -1687,13 +1672,13 @@ int portable_attach(
strempty(extensions_joined)); strempty(extensions_joined));
} }
r = lookup_paths_init(&paths, scope, /* flags= */ 0, NULL); r = lookup_paths_init(&paths, RUNTIME_SCOPE_SYSTEM, /* flags= */ 0, NULL);
if (r < 0) if (r < 0)
return r; return r;
if (!FLAGS_SET(flags, PORTABLE_REATTACH) && !FLAGS_SET(flags, PORTABLE_FORCE_ATTACH)) if (!FLAGS_SET(flags, PORTABLE_REATTACH) && !FLAGS_SET(flags, PORTABLE_FORCE_ATTACH))
HASHMAP_FOREACH(item, unit_files) { HASHMAP_FOREACH(item, unit_files) {
r = unit_file_exists(scope, &paths, item->name); r = unit_file_exists(RUNTIME_SCOPE_SYSTEM, &paths, item->name);
if (r < 0) if (r < 0)
return sd_bus_error_set_errnof(error, r, "Failed to determine whether unit '%s' exists on the host: %m", item->name); return sd_bus_error_set_errnof(error, r, "Failed to determine whether unit '%s' exists on the host: %m", item->name);
if (r > 0) if (r > 0)
@ -1715,7 +1700,7 @@ int portable_attach(
/* We don't care too much for the image symlink/copy, it's just a convenience thing, it's not necessary for /* We don't care too much for the image symlink/copy, it's just a convenience thing, it's not necessary for
* proper operation otherwise. */ * proper operation otherwise. */
(void) install_image_and_extensions(scope, image, extension_images, flags, changes, n_changes); (void) install_image_and_extensions(image, extension_images, flags, changes, n_changes);
log_portable_verb( log_portable_verb(
"attached", "attached",
@ -1859,7 +1844,6 @@ static int test_chroot_dropin(
} }
int portable_detach( int portable_detach(
RuntimeScope scope,
sd_bus *bus, sd_bus *bus,
const char *name_or_path, const char *name_or_path,
char **extension_image_paths, char **extension_image_paths,
@ -1873,12 +1857,12 @@ int portable_detach(
_cleanup_free_ char *extensions = NULL; _cleanup_free_ char *extensions = NULL;
_cleanup_closedir_ DIR *d = NULL; _cleanup_closedir_ DIR *d = NULL;
const char *where, *item; const char *where, *item;
int r, ret = 0; int ret = 0;
int r;
assert(scope < _RUNTIME_SCOPE_MAX);
assert(name_or_path); assert(name_or_path);
r = lookup_paths_init(&paths, scope, /* flags= */ 0, NULL); r = lookup_paths_init(&paths, RUNTIME_SCOPE_SYSTEM, /* flags= */ 0, NULL);
if (r < 0) if (r < 0)
return r; return r;
@ -1946,7 +1930,7 @@ int portable_detach(
if (r == 0) if (r == 0)
break; break;
if (path_is_absolute(image) && !image_in_search_path(scope, IMAGE_PORTABLE, NULL, image)) { if (path_is_absolute(image) && !image_in_search_path(IMAGE_PORTABLE, NULL, image)) {
r = set_ensure_consume(&markers, &path_hash_ops_free, TAKE_PTR(image)); r = set_ensure_consume(&markers, &path_hash_ops_free, TAKE_PTR(image));
if (r < 0) if (r < 0)
return r; return r;
@ -2047,7 +2031,6 @@ not_found:
} }
static int portable_get_state_internal( static int portable_get_state_internal(
RuntimeScope scope,
sd_bus *bus, sd_bus *bus,
const char *name_or_path, const char *name_or_path,
char **extension_image_paths, char **extension_image_paths,
@ -2062,11 +2045,10 @@ static int portable_get_state_internal(
const char *where; const char *where;
int r; int r;
assert(scope < _RUNTIME_SCOPE_MAX);
assert(name_or_path); assert(name_or_path);
assert(ret); assert(ret);
r = lookup_paths_init(&paths, scope, /* flags= */ 0, NULL); r = lookup_paths_init(&paths, RUNTIME_SCOPE_SYSTEM, /* flags= */ 0, NULL);
if (r < 0) if (r < 0)
return r; return r;
@ -2102,7 +2084,7 @@ static int portable_get_state_internal(
if (r == 0) if (r == 0)
continue; continue;
r = unit_file_lookup_state(scope, &paths, de->d_name, &state); r = unit_file_lookup_state(RUNTIME_SCOPE_SYSTEM, &paths, de->d_name, &state);
if (r < 0) if (r < 0)
return log_debug_errno(r, "Failed to determine unit file state of '%s': %m", de->d_name); return log_debug_errno(r, "Failed to determine unit file state of '%s': %m", de->d_name);
if (!IN_SET(state, UNIT_FILE_STATIC, UNIT_FILE_DISABLED, UNIT_FILE_LINKED, UNIT_FILE_LINKED_RUNTIME)) if (!IN_SET(state, UNIT_FILE_STATIC, UNIT_FILE_DISABLED, UNIT_FILE_LINKED, UNIT_FILE_LINKED_RUNTIME))
@ -2127,7 +2109,6 @@ static int portable_get_state_internal(
} }
int portable_get_state( int portable_get_state(
RuntimeScope scope,
sd_bus *bus, sd_bus *bus,
const char *name_or_path, const char *name_or_path,
char **extension_image_paths, char **extension_image_paths,
@ -2144,19 +2125,12 @@ int portable_get_state(
/* We look for matching units twice: once in the regular directories, and once in the runtime directories — but /* We look for matching units twice: once in the regular directories, and once in the runtime directories — but
* the latter only if we didn't find anything in the former. */ * the latter only if we didn't find anything in the former. */
r = portable_get_state_internal( r = portable_get_state_internal(bus, name_or_path, extension_image_paths, flags & ~PORTABLE_RUNTIME, &state, error);
scope,
bus,
name_or_path,
extension_image_paths,
flags & ~PORTABLE_RUNTIME,
&state,
error);
if (r < 0) if (r < 0)
return r; return r;
if (state == PORTABLE_DETACHED) { if (state == PORTABLE_DETACHED) {
r = portable_get_state_internal(scope, bus, name_or_path, extension_image_paths, flags | PORTABLE_RUNTIME, &state, error); r = portable_get_state_internal(bus, name_or_path, extension_image_paths, flags | PORTABLE_RUNTIME, &state, error);
if (r < 0) if (r < 0)
return r; return r;
} }

View File

@ -6,7 +6,6 @@
#include "dissect-image.h" #include "dissect-image.h"
#include "hashmap.h" #include "hashmap.h"
#include "macro.h" #include "macro.h"
#include "runtime-scope.h"
#include "set.h" #include "set.h"
#include "string-util.h" #include "string-util.h"
@ -70,12 +69,12 @@ DEFINE_TRIVIAL_CLEANUP_FUNC(PortableMetadata*, portable_metadata_unref);
int portable_metadata_hashmap_to_sorted_array(Hashmap *unit_files, PortableMetadata ***ret); int portable_metadata_hashmap_to_sorted_array(Hashmap *unit_files, PortableMetadata ***ret);
int portable_extract(RuntimeScope scope, const char *image, char **matches, char **extension_image_paths, const ImagePolicy *image_policy, PortableFlags flags, PortableMetadata **ret_os_release, OrderedHashmap **ret_extension_releases, Hashmap **ret_unit_files, char ***ret_valid_prefixes, sd_bus_error *error); int portable_extract(const char *image, char **matches, char **extension_image_paths, const ImagePolicy *image_policy, PortableFlags flags, PortableMetadata **ret_os_release, OrderedHashmap **ret_extension_releases, Hashmap **ret_unit_files, char ***ret_valid_prefixes, sd_bus_error *error);
int portable_attach(RuntimeScope scope, sd_bus *bus, const char *name_or_path, char **matches, const char *profile, char **extension_images, const ImagePolicy* image_policy, PortableFlags flags, PortableChange **changes, size_t *n_changes, sd_bus_error *error); int portable_attach(sd_bus *bus, const char *name_or_path, char **matches, const char *profile, char **extension_images, const ImagePolicy* image_policy, PortableFlags flags, PortableChange **changes, size_t *n_changes, sd_bus_error *error);
int portable_detach(RuntimeScope scope, sd_bus *bus, const char *name_or_path, char **extension_image_paths, PortableFlags flags, PortableChange **changes, size_t *n_changes, sd_bus_error *error); int portable_detach(sd_bus *bus, const char *name_or_path, char **extension_image_paths, PortableFlags flags, PortableChange **changes, size_t *n_changes, sd_bus_error *error);
int portable_get_state(RuntimeScope scope, sd_bus *bus, const char *name_or_path, char **extension_image_paths, PortableFlags flags, PortableState *ret, sd_bus_error *error); int portable_get_state(sd_bus *bus, const char *name_or_path, char **extension_image_paths, PortableFlags flags, PortableState *ret, sd_bus_error *error);
int portable_get_profiles(char ***ret); int portable_get_profiles(char ***ret);

View File

@ -165,7 +165,6 @@ static int method_list_images(sd_bus_message *message, void *userdata, sd_bus_er
return r; return r;
r = portable_get_state( r = portable_get_state(
m->runtime_scope,
sd_bus_message_get_bus(message), sd_bus_message_get_bus(message),
image->path, image->path,
NULL, NULL,
@ -226,7 +225,6 @@ static int method_get_image_metadata(sd_bus_message *message, void *userdata, sd
static int method_get_image_state(sd_bus_message *message, void *userdata, sd_bus_error *error) { static int method_get_image_state(sd_bus_message *message, void *userdata, sd_bus_error *error) {
_cleanup_strv_free_ char **extension_images = NULL; _cleanup_strv_free_ char **extension_images = NULL;
Manager *m = ASSERT_PTR(userdata);
const char *name_or_path; const char *name_or_path;
PortableState state; PortableState state;
int r; int r;
@ -256,7 +254,6 @@ static int method_get_image_state(sd_bus_message *message, void *userdata, sd_bu
} }
r = portable_get_state( r = portable_get_state(
m->runtime_scope,
sd_bus_message_get_bus(message), sd_bus_message_get_bus(message),
name_or_path, name_or_path,
extension_images, extension_images,
@ -333,7 +330,6 @@ static int method_detach_image(sd_bus_message *message, void *userdata, sd_bus_e
return 1; /* Will call us back */ return 1; /* Will call us back */
r = portable_detach( r = portable_detach(
m->runtime_scope,
sd_bus_message_get_bus(message), sd_bus_message_get_bus(message),
name_or_path, name_or_path,
extension_images, extension_images,

View File

@ -114,8 +114,10 @@ int bus_image_common_get_metadata(
assert(name_or_path || image); assert(name_or_path || image);
assert(message); assert(message);
if (!m) if (!m) {
m = ASSERT_PTR(ASSERT_PTR(image)->userdata); assert(image);
m = image->userdata;
}
bool have_exti = sd_bus_message_is_method_call(message, NULL, "GetImageMetadataWithExtensions") || bool have_exti = sd_bus_message_is_method_call(message, NULL, "GetImageMetadataWithExtensions") ||
sd_bus_message_is_method_call(message, NULL, "GetMetadataWithExtensions"); sd_bus_message_is_method_call(message, NULL, "GetMetadataWithExtensions");
@ -158,7 +160,6 @@ int bus_image_common_get_metadata(
return 1; return 1;
r = portable_extract( r = portable_extract(
m->runtime_scope,
image->path, image->path,
matches, matches,
extension_images, extension_images,
@ -263,7 +264,6 @@ static int bus_image_method_get_state(
_cleanup_strv_free_ char **extension_images = NULL; _cleanup_strv_free_ char **extension_images = NULL;
Image *image = ASSERT_PTR(userdata); Image *image = ASSERT_PTR(userdata);
Manager *m = ASSERT_PTR(image->userdata);
PortableState state; PortableState state;
int r; int r;
@ -288,7 +288,6 @@ static int bus_image_method_get_state(
} }
r = portable_get_state( r = portable_get_state(
m->runtime_scope,
sd_bus_message_get_bus(message), sd_bus_message_get_bus(message),
image->path, image->path,
extension_images, extension_images,
@ -386,7 +385,6 @@ int bus_image_common_attach(
return 1; return 1;
r = portable_attach( r = portable_attach(
m->runtime_scope,
sd_bus_message_get_bus(message), sd_bus_message_get_bus(message),
image->path, image->path,
matches, matches,
@ -465,7 +463,6 @@ static int bus_image_method_detach(
return 1; /* Will call us back */ return 1; /* Will call us back */
r = portable_detach( r = portable_detach(
m->runtime_scope,
sd_bus_message_get_bus(message), sd_bus_message_get_bus(message),
image->path, image->path,
extension_images, extension_images,
@ -516,7 +513,6 @@ int bus_image_common_remove(
return 1; /* Will call us back */ return 1; /* Will call us back */
r = portable_get_state( r = portable_get_state(
m->runtime_scope,
sd_bus_message_get_bus(message), sd_bus_message_get_bus(message),
image->path, image->path,
NULL, NULL,
@ -720,7 +716,6 @@ int bus_image_common_reattach(
return 1; return 1;
r = portable_detach( r = portable_detach(
m->runtime_scope,
sd_bus_message_get_bus(message), sd_bus_message_get_bus(message),
image->path, image->path,
extension_images, extension_images,
@ -732,7 +727,6 @@ int bus_image_common_reattach(
return r; return r;
r = portable_attach( r = portable_attach(
m->runtime_scope,
sd_bus_message_get_bus(message), sd_bus_message_get_bus(message),
image->path, image->path,
matches, matches,
@ -1045,7 +1039,7 @@ int bus_image_acquire(
if (image_name_is_valid(name_or_path)) { if (image_name_is_valid(name_or_path)) {
/* If it's a short name, let's search for it */ /* If it's a short name, let's search for it */
r = image_find(m->runtime_scope, IMAGE_PORTABLE, name_or_path, NULL, &loaded); r = image_find(IMAGE_PORTABLE, name_or_path, NULL, &loaded);
if (r == -ENOENT) if (r == -ENOENT)
return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_PORTABLE_IMAGE, return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_PORTABLE_IMAGE,
"No image '%s' found.", name_or_path); "No image '%s' found.", name_or_path);

View File

@ -91,7 +91,7 @@ int manager_image_cache_discover(Manager *m, Hashmap *images, sd_bus_error *erro
/* A wrapper around image_discover() (for finding images in search path) and portable_discover_attached() (for /* A wrapper around image_discover() (for finding images in search path) and portable_discover_attached() (for
* finding attached images). */ * finding attached images). */
r = image_discover(m->runtime_scope, IMAGE_PORTABLE, NULL, images); r = image_discover(IMAGE_PORTABLE, NULL, images);
if (r < 0) if (r < 0)
return r; return r;

View File

@ -28,14 +28,10 @@ static int manager_new(Manager **ret) {
assert(ret); assert(ret);
m = new(Manager, 1); m = new0(Manager, 1);
if (!m) if (!m)
return -ENOMEM; return -ENOMEM;
*m = (Manager) {
.runtime_scope = RUNTIME_SCOPE_SYSTEM,
};
r = sd_event_default(&m->event); r = sd_event_default(&m->event);
if (r < 0) if (r < 0)
return r; return r;

View File

@ -7,7 +7,6 @@
#include "bus-object.h" #include "bus-object.h"
#include "hashmap.h" #include "hashmap.h"
#include "list.h" #include "list.h"
#include "runtime-scope.h"
typedef struct Manager Manager; typedef struct Manager Manager;
@ -24,8 +23,6 @@ struct Manager {
LIST_HEAD(Operation, operations); LIST_HEAD(Operation, operations);
unsigned n_operations; unsigned n_operations;
RuntimeScope runtime_scope; /* for now always RUNTIME_SCOPE_SYSTEM */
}; };
extern const BusObjectImplementation manager_object; extern const BusObjectImplementation manager_object;

View File

@ -12,8 +12,6 @@
#include <sys/stat.h> #include <sys/stat.h>
#include <unistd.h> #include <unistd.h>
#include "sd-path.h"
#include "alloc-util.h" #include "alloc-util.h"
#include "blockdev-util.h" #include "blockdev-util.h"
#include "btrfs-util.h" #include "btrfs-util.h"
@ -555,95 +553,12 @@ static int image_make(
return -EMEDIUMTYPE; return -EMEDIUMTYPE;
} }
static int pick_image_search_path( static const char *pick_image_search_path(ImageClass class) {
RuntimeScope scope, if (class < 0 || class >= _IMAGE_CLASS_MAX)
ImageClass class, return NULL;
char ***ret) {
int r;
assert(scope < _RUNTIME_SCOPE_MAX && scope != RUNTIME_SCOPE_GLOBAL);
assert(class < _IMAGE_CLASS_MAX);
assert(ret);
if (class < 0) {
*ret = NULL;
return 0;
}
if (scope < 0) {
_cleanup_strv_free_ char **a = NULL, **b = NULL;
r = pick_image_search_path(RUNTIME_SCOPE_USER, class, &a);
if (r < 0)
return r;
r = pick_image_search_path(RUNTIME_SCOPE_SYSTEM, class, &b);
if (r < 0)
return r;
r = strv_extend_strv(&a, b, /* filter_duplicates= */ false);
if (r < 0)
return r;
*ret = TAKE_PTR(a);
return 0;
}
switch (scope) {
case RUNTIME_SCOPE_SYSTEM: {
const char *ns;
/* Use the initrd search path if there is one, otherwise use the common one */ /* Use the initrd search path if there is one, otherwise use the common one */
ns = in_initrd() && image_search_path_initrd[class] ? return in_initrd() && image_search_path_initrd[class] ? image_search_path_initrd[class] : image_search_path[class];
image_search_path_initrd[class] :
image_search_path[class];
if (!ns)
break;
_cleanup_strv_free_ char **search = strv_split_nulstr(ns);
if (!search)
return -ENOMEM;
*ret = TAKE_PTR(search);
return 0;
}
case RUNTIME_SCOPE_USER: {
if (class != IMAGE_MACHINE)
break;
static const uint64_t dirs[] = {
SD_PATH_USER_RUNTIME,
SD_PATH_USER_STATE_PRIVATE,
SD_PATH_USER_LIBRARY_PRIVATE,
};
_cleanup_strv_free_ char **search = NULL;
FOREACH_ELEMENT(d, dirs) {
_cleanup_free_ char *p = NULL;
r = sd_path_lookup(*d, "machines", &p);
if (r == -ENXIO) /* No XDG_RUNTIME_DIR set */
continue;
if (r < 0)
return r;
r = strv_consume(&search, TAKE_PTR(p));
if (r < 0)
return r;
}
*ret = TAKE_PTR(search);
return 0;
}
default:
assert_not_reached();
}
*ret = NULL;
return 0;
} }
static char **make_possible_filenames(ImageClass class, const char *image_name) { static char **make_possible_filenames(ImageClass class, const char *image_name) {
@ -677,8 +592,7 @@ static char **make_possible_filenames(ImageClass class, const char *image_name)
return TAKE_PTR(l); return TAKE_PTR(l);
} }
int image_find(RuntimeScope scope, int image_find(ImageClass class,
ImageClass class,
const char *name, const char *name,
const char *root, const char *root,
Image **ret) { Image **ret) {
@ -688,7 +602,6 @@ int image_find(RuntimeScope scope,
* some root directory.) */ * some root directory.) */
int open_flags = root ? O_NOFOLLOW : 0, r; int open_flags = root ? O_NOFOLLOW : 0, r;
assert(scope < _RUNTIME_SCOPE_MAX && scope != RUNTIME_SCOPE_GLOBAL);
assert(class >= 0); assert(class >= 0);
assert(class < _IMAGE_CLASS_MAX); assert(class < _IMAGE_CLASS_MAX);
assert(name); assert(name);
@ -701,16 +614,11 @@ int image_find(RuntimeScope scope,
if (!names) if (!names)
return -ENOMEM; return -ENOMEM;
_cleanup_strv_free_ char **search = NULL; NULSTR_FOREACH(path, pick_image_search_path(class)) {
r = pick_image_search_path(scope, class, &search);
if (r < 0)
return r;
STRV_FOREACH(path, search) {
_cleanup_free_ char *resolved = NULL; _cleanup_free_ char *resolved = NULL;
_cleanup_closedir_ DIR *d = NULL; _cleanup_closedir_ DIR *d = NULL;
r = chase_and_opendir(*path, root, CHASE_PREFIX_ROOT, &resolved, &d); r = chase_and_opendir(path, root, CHASE_PREFIX_ROOT, &resolved, &d);
if (r == -ENOENT) if (r == -ENOENT)
continue; continue;
if (r < 0) if (r < 0)
@ -814,7 +722,7 @@ int image_find(RuntimeScope scope,
} }
} }
if (scope == RUNTIME_SCOPE_SYSTEM && class == IMAGE_MACHINE && streq(name, ".host")) { if (class == IMAGE_MACHINE && streq(name, ".host")) {
r = image_make(class, r = image_make(class,
".host", ".host",
/* dir_fd= */ AT_FDCWD, /* dir_fd= */ AT_FDCWD,
@ -863,21 +771,14 @@ int image_from_path(const char *path, Image **ret) {
ret); ret);
} }
int image_find_harder( int image_find_harder(ImageClass class, const char *name_or_path, const char *root, Image **ret) {
RuntimeScope scope,
ImageClass class,
const char *name_or_path,
const char *root,
Image **ret) {
if (image_name_is_valid(name_or_path)) if (image_name_is_valid(name_or_path))
return image_find(scope, class, name_or_path, root, ret); return image_find(class, name_or_path, root, ret);
return image_from_path(name_or_path, ret); return image_from_path(name_or_path, ret);
} }
int image_discover( int image_discover(
RuntimeScope scope,
ImageClass class, ImageClass class,
const char *root, const char *root,
Hashmap *h) { Hashmap *h) {
@ -887,21 +788,15 @@ int image_discover(
* some root directory.) */ * some root directory.) */
int open_flags = root ? O_NOFOLLOW : 0, r; int open_flags = root ? O_NOFOLLOW : 0, r;
assert(scope < _RUNTIME_SCOPE_MAX && scope != RUNTIME_SCOPE_GLOBAL);
assert(class >= 0); assert(class >= 0);
assert(class < _IMAGE_CLASS_MAX); assert(class < _IMAGE_CLASS_MAX);
assert(h); assert(h);
_cleanup_strv_free_ char **search = NULL; NULSTR_FOREACH(path, pick_image_search_path(class)) {
r = pick_image_search_path(scope, class, &search);
if (r < 0)
return r;
STRV_FOREACH(path, search) {
_cleanup_free_ char *resolved = NULL; _cleanup_free_ char *resolved = NULL;
_cleanup_closedir_ DIR *d = NULL; _cleanup_closedir_ DIR *d = NULL;
r = chase_and_opendir(*path, root, CHASE_PREFIX_ROOT, &resolved, &d); r = chase_and_opendir(path, root, CHASE_PREFIX_ROOT, &resolved, &d);
if (r == -ENOENT) if (r == -ENOENT)
continue; continue;
if (r < 0) if (r < 0)
@ -1051,7 +946,7 @@ int image_discover(
} }
} }
if (scope == RUNTIME_SCOPE_SYSTEM && class == IMAGE_MACHINE && !hashmap_contains(h, ".host")) { if (class == IMAGE_MACHINE && !hashmap_contains(h, ".host")) {
_cleanup_(image_unrefp) Image *image = NULL; _cleanup_(image_unrefp) Image *image = NULL;
r = image_make(IMAGE_MACHINE, r = image_make(IMAGE_MACHINE,
@ -1168,7 +1063,7 @@ static int rename_auxiliary_file(const char *path, const char *new_name, const c
return rename_noreplace(AT_FDCWD, path, AT_FDCWD, rs); return rename_noreplace(AT_FDCWD, path, AT_FDCWD, rs);
} }
int image_rename(Image *i, const char *new_name, RuntimeScope scope) { int image_rename(Image *i, const char *new_name) {
_cleanup_(release_lock_file) LockFile global_lock = LOCK_FILE_INIT, local_lock = LOCK_FILE_INIT, name_lock = LOCK_FILE_INIT; _cleanup_(release_lock_file) LockFile global_lock = LOCK_FILE_INIT, local_lock = LOCK_FILE_INIT, name_lock = LOCK_FILE_INIT;
_cleanup_free_ char *new_path = NULL, *nn = NULL, *roothash = NULL; _cleanup_free_ char *new_path = NULL, *nn = NULL, *roothash = NULL;
_cleanup_strv_free_ char **settings = NULL; _cleanup_strv_free_ char **settings = NULL;
@ -1203,7 +1098,7 @@ int image_rename(Image *i, const char *new_name, RuntimeScope scope) {
if (r < 0) if (r < 0)
return r; return r;
r = image_find(scope, IMAGE_MACHINE, new_name, NULL, NULL); r = image_find(IMAGE_MACHINE, new_name, NULL, NULL);
if (r >= 0) if (r >= 0)
return -EEXIST; return -EEXIST;
if (r != -ENOENT) if (r != -ENOENT)
@ -1290,7 +1185,7 @@ static int clone_auxiliary_file(const char *path, const char *new_name, const ch
return copy_file_atomic(path, rs, 0664, COPY_REFLINK); return copy_file_atomic(path, rs, 0664, COPY_REFLINK);
} }
int image_clone(Image *i, const char *new_name, bool read_only, RuntimeScope scope) { int image_clone(Image *i, const char *new_name, bool read_only) {
_cleanup_(release_lock_file) LockFile name_lock = LOCK_FILE_INIT; _cleanup_(release_lock_file) LockFile name_lock = LOCK_FILE_INIT;
_cleanup_strv_free_ char **settings = NULL; _cleanup_strv_free_ char **settings = NULL;
_cleanup_free_ char *roothash = NULL; _cleanup_free_ char *roothash = NULL;
@ -1317,7 +1212,7 @@ int image_clone(Image *i, const char *new_name, bool read_only, RuntimeScope sco
if (r < 0) if (r < 0)
return r; return r;
r = image_find(scope, IMAGE_MACHINE, new_name, NULL, NULL); r = image_find(IMAGE_MACHINE, new_name, NULL, NULL);
if (r >= 0) if (r >= 0)
return -EEXIST; return -EEXIST;
if (r != -ENOENT) if (r != -ENOENT)
@ -1751,35 +1646,24 @@ int image_name_lock(const char *name, int operation, LockFile *ret) {
} }
bool image_in_search_path( bool image_in_search_path(
RuntimeScope scope,
ImageClass class, ImageClass class,
const char *root, const char *root,
const char *image) { const char *image) {
int r;
assert(scope < _RUNTIME_SCOPE_MAX && scope != RUNTIME_SCOPE_GLOBAL);
assert(class >= 0);
assert(class < _IMAGE_CLASS_MAX);
assert(image); assert(image);
_cleanup_strv_free_ char **search = NULL; NULSTR_FOREACH(path, pick_image_search_path(class)) {
r = pick_image_search_path(scope, class, &search);
if (r < 0)
return r;
STRV_FOREACH(path, search) {
const char *p, *q; const char *p, *q;
size_t k; size_t k;
if (!empty_or_root(root)) { if (!empty_or_root(root)) {
q = path_startswith(*path, root); q = path_startswith(path, root);
if (!q) if (!q)
continue; continue;
} else } else
q = *path; q = path;
p = path_startswith(q, *path); p = path_startswith(q, path);
if (!p) if (!p)
continue; continue;

View File

@ -13,7 +13,6 @@
#include "macro.h" #include "macro.h"
#include "os-util.h" #include "os-util.h"
#include "path-util.h" #include "path-util.h"
#include "runtime-scope.h"
#include "string-util.h" #include "string-util.h"
#include "time-util.h" #include "time-util.h"
@ -61,14 +60,14 @@ Image *image_ref(Image *i);
DEFINE_TRIVIAL_CLEANUP_FUNC(Image*, image_unref); DEFINE_TRIVIAL_CLEANUP_FUNC(Image*, image_unref);
int image_find(RuntimeScope scope, ImageClass class, const char *name, const char *root, Image **ret); int image_find(ImageClass class, const char *name, const char *root, Image **ret);
int image_from_path(const char *path, Image **ret); int image_from_path(const char *path, Image **ret);
int image_find_harder(RuntimeScope scope, ImageClass class, const char *name_or_path, const char *root, Image **ret); int image_find_harder(ImageClass class, const char *name_or_path, const char *root, Image **ret);
int image_discover(RuntimeScope scope, ImageClass class, const char *root, Hashmap *map); int image_discover(ImageClass class, const char *root, Hashmap *map);
int image_remove(Image *i); int image_remove(Image *i);
int image_rename(Image *i, const char *new_name, RuntimeScope scope); int image_rename(Image *i, const char *new_name);
int image_clone(Image *i, const char *new_name, bool read_only, RuntimeScope scope); int image_clone(Image *i, const char *new_name, bool read_only);
int image_read_only(Image *i, bool b); int image_read_only(Image *i, bool b);
const char* image_type_to_string(ImageType t) _const_; const char* image_type_to_string(ImageType t) _const_;
@ -81,7 +80,7 @@ int image_set_limit(Image *i, uint64_t referenced_max);
int image_read_metadata(Image *i, const ImagePolicy *image_policy); int image_read_metadata(Image *i, const ImagePolicy *image_policy);
bool image_in_search_path(RuntimeScope scope, ImageClass class, const char *root, const char *image); bool image_in_search_path(ImageClass class, const char *root, const char *image);
static inline char **image_extension_release(Image *image, ImageClass class) { static inline char **image_extension_release(Image *image, ImageClass class) {
assert(image); assert(image);

View File

@ -2031,7 +2031,7 @@ static int image_discover_and_read_metadata(
if (!images) if (!images)
return log_oom(); return log_oom();
r = image_discover(RUNTIME_SCOPE_SYSTEM, image_class, arg_root, images); r = image_discover(image_class, arg_root, images);
if (r < 0) if (r < 0)
return log_error_errno(r, "Failed to discover images: %m"); return log_error_errno(r, "Failed to discover images: %m");
@ -2278,7 +2278,7 @@ static int verb_list(int argc, char **argv, void *userdata) {
if (!images) if (!images)
return log_oom(); return log_oom();
r = image_discover(RUNTIME_SCOPE_SYSTEM, arg_image_class, arg_root, images); r = image_discover(arg_image_class, arg_root, images);
if (r < 0) if (r < 0)
return log_error_errno(r, "Failed to discover images: %m"); return log_error_errno(r, "Failed to discover images: %m");
@ -2339,7 +2339,7 @@ static int vl_method_list(sd_varlink *link, sd_json_variant *parameters, sd_varl
if (!images) if (!images)
return -ENOMEM; return -ENOMEM;
r = image_discover(RUNTIME_SCOPE_SYSTEM, image_class, arg_root, images); r = image_discover(image_class, arg_root, images);
if (r < 0) if (r < 0)
return r; return r;

View File

@ -120,16 +120,6 @@ enum {
SD_PATH_USER_STATE_PRIVATE, SD_PATH_USER_STATE_PRIVATE,
/* credential store */
SD_PATH_SYSTEM_CREDENTIAL_STORE,
SD_PATH_SYSTEM_SEARCH_CREDENTIAL_STORE,
SD_PATH_SYSTEM_CREDENTIAL_STORE_ENCRYPTED,
SD_PATH_SYSTEM_SEARCH_CREDENTIAL_STORE_ENCRYPTED,
SD_PATH_USER_CREDENTIAL_STORE,
SD_PATH_USER_SEARCH_CREDENTIAL_STORE,
SD_PATH_USER_CREDENTIAL_STORE_ENCRYPTED,
SD_PATH_USER_SEARCH_CREDENTIAL_STORE_ENCRYPTED,
_SD_PATH_MAX _SD_PATH_MAX
}; };

View File

@ -46,8 +46,6 @@ typedef struct Manager {
Hashmap *polkit_registry; Hashmap *polkit_registry;
sd_event_source *notify_event; sd_event_source *notify_event;
RuntimeScope runtime_scope; /* For now only RUNTIME_SCOPE_SYSTEM */
} Manager; } Manager;
/* Forward declare so that jobs can call it on exit */ /* Forward declare so that jobs can call it on exit */
@ -1732,14 +1730,10 @@ static int manager_new(Manager **ret) {
assert(ret); assert(ret);
m = new(Manager, 1); m = new0(Manager, 1);
if (!m) if (!m)
return -ENOMEM; return -ENOMEM;
*m = (Manager) {
.runtime_scope = RUNTIME_SCOPE_SYSTEM,
};
r = sd_event_default(&m->event); r = sd_event_default(&m->event);
if (r < 0) if (r < 0)
return r; return r;
@ -1801,7 +1795,7 @@ static int manager_enumerate_image_class(Manager *m, TargetClass class) {
if (!images) if (!images)
return -ENOMEM; return -ENOMEM;
r = image_discover(m->runtime_scope, (ImageClass) class, NULL, images); r = image_discover((ImageClass) class, NULL, images);
if (r < 0) if (r < 0)
return r; return r;

View File

@ -11,7 +11,6 @@ const char16_t *const test_fields[_CHID_SMBIOS_FIELDS_MAX] = {
[CHID_SMBIOS_FAMILY] = u"To be filled by O.E.M.", [CHID_SMBIOS_FAMILY] = u"To be filled by O.E.M.",
[CHID_SMBIOS_BASEBOARD_PRODUCT] = u"MPG X670E CARBON WIFI (MS-7D70)", [CHID_SMBIOS_BASEBOARD_PRODUCT] = u"MPG X670E CARBON WIFI (MS-7D70)",
[CHID_SMBIOS_BASEBOARD_MANUFACTURER] = u"Micro-Star International Co., Ltd.", [CHID_SMBIOS_BASEBOARD_MANUFACTURER] = u"Micro-Star International Co., Ltd.",
[CHID_SMBIOS_ENCLOSURE_TYPE] = u"3",
}; };
/* Actual output of `fwupdtool hwids`: /* Actual output of `fwupdtool hwids`:
@ -52,7 +51,7 @@ Extra Hardware IDs
{7b3d90ce-ed79-5951-a48a-764ea9f11146} <- Manufacturer + BiosVendor {7b3d90ce-ed79-5951-a48a-764ea9f11146} <- Manufacturer + BiosVendor
*/ */
static const EFI_GUID actual_chids[CHID_TYPES_MAX] = { static const EFI_GUID actual_chids[] = {
{0x00000000, 0x0000, 0x0000, {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, {0x00000000, 0x0000, 0x0000, {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
{0x00000000, 0x0000, 0x0000, {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, {0x00000000, 0x0000, 0x0000, {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
{0x00000000, 0x0000, 0x0000, {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, {0x00000000, 0x0000, 0x0000, {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
@ -65,9 +64,9 @@ static const EFI_GUID actual_chids[CHID_TYPES_MAX] = {
{0xc12c1f4a, 0x332d, 0x5d72, {0xaa, 0x36, 0x7a, 0x3d, 0x41, 0x3b, 0x47, 0x9a}}, {0xc12c1f4a, 0x332d, 0x5d72, {0xaa, 0x36, 0x7a, 0x3d, 0x41, 0x3b, 0x47, 0x9a}},
{0x28ac9cf2, 0x5bde, 0x59f7, {0xae, 0xbe, 0x4b, 0x3d, 0x00, 0x80, 0x90, 0xfe}}, {0x28ac9cf2, 0x5bde, 0x59f7, {0xae, 0xbe, 0x4b, 0x3d, 0x00, 0x80, 0x90, 0xfe}},
{0xe821e0e2, 0xe11a, 0x5e94, {0xbf, 0x5d, 0xff, 0xe5, 0x3c, 0x5e, 0x50, 0x48}}, {0xe821e0e2, 0xe11a, 0x5e94, {0xbf, 0x5d, 0xff, 0xe5, 0x3c, 0x5e, 0x50, 0x48}},
{0xbdd76d3e, 0x147f, 0x58a9, {0xa0, 0xb2, 0x42, 0x13, 0x64, 0x54, 0xed, 0x07}}, {0x00000000, 0x0000, 0x0000, {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
{0xb2e58e8b, 0xfb10, 0x5cd0, {0x8f, 0xb0, 0x5b, 0xd9, 0x31, 0xf1, 0x87, 0x1a}}, {0xb2e58e8b, 0xfb10, 0x5cd0, {0x8f, 0xb0, 0x5b, 0xd9, 0x31, 0xf1, 0x87, 0x1a}},
{0x50af5797, 0xa2f2, 0x58b1, {0x9a, 0x1a, 0x45, 0x3b, 0xcb, 0xb2, 0xe0, 0x25}}, {0x00000000, 0x0000, 0x0000, {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
}; };
TEST(chid) { TEST(chid) {

View File

@ -1398,10 +1398,6 @@ static void run_tests(RuntimeScope scope, char **patterns) {
ASSERT_NOT_NULL(unit_paths = strjoin(PRIVATE_UNIT_DIR, ":", user_runtime_unit_dir)); ASSERT_NOT_NULL(unit_paths = strjoin(PRIVATE_UNIT_DIR, ":", user_runtime_unit_dir));
ASSERT_OK(setenv_unit_path(unit_paths)); ASSERT_OK(setenv_unit_path(unit_paths));
/* Write credential for test-execute-load-credential to the fake runtime dir, too */
_cleanup_free_ char *j = ASSERT_PTR(path_join(runtime_dir, "credstore/test-execute.load-credential"));
ASSERT_OK(write_string_file(j, "foo", WRITE_STRING_FILE_CREATE|WRITE_STRING_FILE_MKDIR_0755));
r = manager_new(scope, MANAGER_TEST_RUN_BASIC, &m); r = manager_new(scope, MANAGER_TEST_RUN_BASIC, &m);
if (manager_errno_skip_test(r)) if (manager_errno_skip_test(r))
return (void) log_tests_skipped_errno(r, "manager_new"); return (void) log_tests_skipped_errno(r, "manager_new");

View File

@ -650,16 +650,7 @@ static int get_pci_slot_specifiers(
* where the slot makes up the upper 5 bits. */ * where the slot makes up the upper 5 bits. */
func += slot * 8; func += slot * 8;
/* Include the PCI domain in the name if the ID_NET_NAME_INCLUDE_DOMAIN property says so, if it is if (domain > 0 && asprintf(&domain_spec, "P%u", domain) < 0)
* set. If it is not set, include it if the domain is non-zero. */
r = device_get_property_bool(dev, "ID_NET_NAME_INCLUDE_DOMAIN");
if (r < 0) {
if (r != -ENOENT)
log_device_warning_errno(dev, r, "Failed to read property \"ID_NET_NAME_INCLUDE_DOMAIN\", ignoring: %m");
r = domain > 0;
}
if (r > 0 && asprintf(&domain_spec, "P%u", domain) < 0)
return log_oom_debug(); return log_oom_debug();
if (asprintf(&bus_and_slot_spec, "p%us%u", bus, slot) < 0) if (asprintf(&bus_and_slot_spec, "p%us%u", bus, slot) < 0)

View File

@ -2236,8 +2236,7 @@ static int determine_names(void) {
if (arg_machine) { if (arg_machine) {
_cleanup_(image_unrefp) Image *i = NULL; _cleanup_(image_unrefp) Image *i = NULL;
r = image_find(arg_privileged ? RUNTIME_SCOPE_SYSTEM : RUNTIME_SCOPE_USER, r = image_find(IMAGE_MACHINE, arg_machine, NULL, &i);
IMAGE_MACHINE, arg_machine, NULL, &i);
if (r == -ENOENT) if (r == -ENOENT)
return log_error_errno(r, "No image for machine '%s'.", arg_machine); return log_error_errno(r, "No image for machine '%s'.", arg_machine);
if (r < 0) if (r < 0)

View File

@ -459,72 +459,3 @@ test unit (be it a static one or a transient one created via systemd-run), with
main mount namespace - in that case use `IGNORE_MISSING_COVERAGE=yes` in the main mount namespace - in that case use `IGNORE_MISSING_COVERAGE=yes` in the
test definition (i.e. `TEST-*-NAME/test.sh`), which will skip the post-test test definition (i.e. `TEST-*-NAME/test.sh`), which will skip the post-test
check for missing coverage for the respective test. check for missing coverage for the respective test.
## Fuzzers
systemd includes fuzzers in `src/fuzz/` that use libFuzzer and are automatically
run by [OSS-Fuzz](https://github.com/google/oss-fuzz) with sanitizers. To add a
fuzz target, create a new `src/fuzz/fuzz-foo.c` file with a
`LLVMFuzzerTestOneInput` function and add it to the list in
`src/fuzz/meson.build`.
Whenever possible, a seed corpus and a dictionary should also be added with new
fuzz targets. The dictionary should be named `src/fuzz/fuzz-foo.dict` and the
seed corpus should be built and exported as `$OUT/fuzz-foo_seed_corpus.zip` in
`tools/oss-fuzz.sh`.
The fuzzers can be built locally if you have libFuzzer installed by running
`tools/oss-fuzz.sh`, or by running:
```sh
CC=clang CXX=clang++ \
meson setup build-libfuzz -Dllvm-fuzz=true -Db_sanitize=address,undefined -Db_lundef=false \
-Dc_args='-fno-omit-frame-pointer -DFUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION'
ninja -C build-libfuzz fuzzers
```
Each fuzzer then can be then run manually together with a directory containing
the initial corpus:
```
export UBSAN_OPTIONS=print_stacktrace=1:print_summary=1:halt_on_error=1
build-libfuzz/fuzz-varlink-idl test/fuzz/fuzz-varlink-idl/
```
Note: the `halt_on_error=1` UBSan option is especially important, otherwise the
fuzzer won't crash when undefined behavior is triggered.
You should also confirm that the fuzzers can be built and run using
[the OSS-Fuzz toolchain](https://google.github.io/oss-fuzz/advanced-topics/reproducing/#building-using-docker):
```sh
path_to_systemd=...
git clone --depth=1 https://github.com/google/oss-fuzz
cd oss-fuzz
for sanitizer in address undefined memory; do
for engine in libfuzzer afl honggfuzz; do
./infra/helper.py build_fuzzers --sanitizer "$sanitizer" --engine "$engine" \
--clean systemd "$path_to_systemd"
./infra/helper.py check_build --sanitizer "$sanitizer" --engine "$engine" \
-e ALLOWED_BROKEN_TARGETS_PERCENTAGE=0 systemd
done
done
./infra/helper.py build_fuzzers --clean --architecture i386 systemd "$path_to_systemd"
./infra/helper.py check_build --architecture i386 -e ALLOWED_BROKEN_TARGETS_PERCENTAGE=0 systemd
./infra/helper.py build_fuzzers --clean --sanitizer coverage systemd "$path_to_systemd"
./infra/helper.py coverage --no-corpus-download systemd
```
If you find a bug that impacts the security of systemd, please follow the
guidance in [CONTRIBUTING.md](/CONTRIBUTING) on how to report a security
vulnerability.
For more details on building fuzzers and integrating with OSS-Fuzz, visit:
- [Setting up a new project - OSS-Fuzz](https://google.github.io/oss-fuzz/getting-started/new-project-guide/)
- [Tutorials - OSS-Fuzz](https://google.github.io/oss-fuzz/reference/useful-links/#tutorials)

View File

@ -3,11 +3,5 @@
integration_tests += [ integration_tests += [
integration_test_template + { integration_test_template + {
'name' : fs.name(meson.current_source_dir()), 'name' : fs.name(meson.current_source_dir()),
'configuration' : integration_test_template['configuration'] + {
# Do not request user session, as it may trigger to start
# hostnamed in an unexpected timing, and the test may fail.
'wants' : 'multi-user.target',
'after' : 'multi-user.target',
},
}, },
] ]

View File

@ -1129,7 +1129,7 @@ testcase_unpriv() {
local tmpdir name local tmpdir name
tmpdir="$(mktemp -d /var/tmp/TEST-13-NSPAWN.unpriv.XXX)" tmpdir="$(mktemp -d /var/tmp/TEST-13-NSPAWN.unpriv.XXX)"
name="unprv-${tmpdir##*.}" name="unpriv-${tmpdir##*.}"
trap 'rm -fr ${tmpdir@Q} || true; rm -f /run/verity.d/test-13-nspawn-${name@Q} || true' RETURN ERR trap 'rm -fr ${tmpdir@Q} || true; rm -f /run/verity.d/test-13-nspawn-${name@Q} || true' RETURN ERR
create_dummy_ddi "$tmpdir" "$name" create_dummy_ddi "$tmpdir" "$name"
chown --recursive testuser: "$tmpdir" chown --recursive testuser: "$tmpdir"
@ -1141,17 +1141,6 @@ testcase_unpriv() {
-- \ -- \
systemd-nspawn --pipe --private-network --register=no --keep-unit --image="$tmpdir/$name.raw" echo hello >"$tmpdir/stdout.txt" systemd-nspawn --pipe --private-network --register=no --keep-unit --image="$tmpdir/$name.raw" echo hello >"$tmpdir/stdout.txt"
echo hello | cmp "$tmpdir/stdout.txt" - echo hello | cmp "$tmpdir/stdout.txt" -
# Make sure per-user search path logic works
systemd-run --pipe --uid=testuser mkdir -p /home/testuser/.local/state/machines
systemd-run --pipe --uid=testuser ln -s "$tmpdir/$name.raw" /home/testuser/.local/state/machines/"x$name.raw"
systemd-run \
--pipe \
--uid=testuser \
--property=Delegate=yes \
-- \
systemd-nspawn --pipe --private-network --register=no --keep-unit --machine="x$name" echo hello >"$tmpdir/stdout.txt"
echo hello | cmp "$tmpdir/stdout.txt" -
} }
testcase_fuse() { testcase_fuse() {

View File

@ -31,50 +31,18 @@ cat >/run/udev/udev.conf.d/timeout.conf <<EOF
event_timeout=1h event_timeout=1h
EOF EOF
# First, test 'add' event.
mkdir -p /run/udev/rules.d/ mkdir -p /run/udev/rules.d/
cat >/run/udev/rules.d/99-testsuite.rules <<EOF cat >/run/udev/rules.d/99-testsuite.rules <<EOF
SUBSYSTEM=="net", ACTION=="add", KERNEL=="${IFNAME}", OPTIONS="log_level=debug", RUN+="/usr/bin/sleep 1000" SUBSYSTEM=="net", ACTION=="change", KERNEL=="${IFNAME}", OPTIONS="log_level=debug", RUN+="/usr/bin/sleep 1000"
EOF EOF
udevadm control --reload udevadm control --reload
ip link add "$IFNAME" type dummy ip link add "$IFNAME" type dummy
IFINDEX=$(ip -json link show "$IFNAME" | jq '.[].ifindex') IFINDEX=$(ip -json link show "$IFNAME" | jq '.[].ifindex')
timeout 30 bash -c "until [[ -e /run/udev/data/n${IFINDEX} ]] && grep -q -F 'ID_PROCESSING=1' /run/udev/data/n${IFINDEX}; do sleep .5; done" udevadm wait --timeout 10 "/sys/class/net/${IFNAME}"
# Check if the database file is created.
(! systemctl is-active "sys-devices-virtual-net-${IFNAME}.device") [[ -e "/run/udev/data/n${IFINDEX}" ]]
(! systemctl is-active "sys-subsystem-net-devices-${IFNAME}.device")
for _ in {1..3}; do
systemctl daemon-reexec
(! systemctl is-active "sys-devices-virtual-net-${IFNAME}.device")
(! systemctl is-active "sys-subsystem-net-devices-${IFNAME}.device")
done
for _ in {1..3}; do
systemctl daemon-reload
(! systemctl is-active "sys-devices-virtual-net-${IFNAME}.device")
(! systemctl is-active "sys-subsystem-net-devices-${IFNAME}.device")
done
# Check if the reexec and reload have finished during processing the event.
grep -q -F 'ID_PROCESSING=1' "/run/udev/data/n${IFINDEX}"
# Forcibly kill sleep command ivoked by the udev rule to finish processing the add event.
killall sleep
udevadm settle --timeout=20
# Check if ID_PROCESSING flag is unset, and the device units are active.
(! grep -q -F 'ID_PROCESSING=1' "/run/udev/data/n${IFINDEX}")
systemctl is-active "sys-devices-virtual-net-${IFNAME}.device"
systemctl is-active "sys-subsystem-net-devices-${IFNAME}.device"
# Next, test 'change' event.
cat >/run/udev/rules.d/99-testsuite.rules <<EOF
SUBSYSTEM=="net", ACTION=="change", KERNEL=="${IFNAME}", OPTIONS="log_level=debug", RUN+="/usr/bin/sleep 1000"
EOF
udevadm control --reload
systemd-run \ systemd-run \
-p After="sys-subsystem-net-devices-${IFNAME}.device" \ -p After="sys-subsystem-net-devices-${IFNAME}.device" \
@ -82,29 +50,22 @@ systemd-run \
-u testsleep.service \ -u testsleep.service \
sleep 1h sleep 1h
udevadm trigger "/sys/class/net/${IFNAME}" timeout 10 bash -c 'until systemctl is-active testsleep.service; do sleep .5; done'
timeout 30 bash -c "until grep -q -F 'ID_PROCESSING=1' /run/udev/data/n${IFINDEX}; do sleep .5; done"
# Check if the service and device units are still active even ID_PROCESSING flag is set. udevadm trigger "/sys/class/net/${IFNAME}"
systemctl is-active testsleep.service timeout 30 bash -c "until grep -F 'ID_PROCESSING=1' /run/udev/data/n${IFINDEX}; do sleep .5; done"
systemctl is-active "sys-devices-virtual-net-${IFNAME}.device"
systemctl is-active "sys-subsystem-net-devices-${IFNAME}.device"
for _ in {1..3}; do for _ in {1..3}; do
systemctl daemon-reexec systemctl daemon-reexec
systemctl is-active testsleep.service systemctl is-active testsleep.service
systemctl is-active "sys-devices-virtual-net-${IFNAME}.device"
systemctl is-active "sys-subsystem-net-devices-${IFNAME}.device"
done done
for _ in {1..3}; do for _ in {1..3}; do
systemctl daemon-reload systemctl daemon-reload
systemctl is-active testsleep.service systemctl is-active testsleep.service
systemctl is-active "sys-devices-virtual-net-${IFNAME}.device"
systemctl is-active "sys-subsystem-net-devices-${IFNAME}.device"
done done
# Check if the reexec and reload have finished during processing the event. # Check if the reexec and reload have finished during processing the event.
grep -q -F 'ID_PROCESSING=1' "/run/udev/data/n${IFINDEX}" grep -F 'ID_PROCESSING=1' "/run/udev/data/n${IFINDEX}"
exit 0 exit 0

View File

@ -615,10 +615,6 @@ grep -q -F '{"name":"b","type":"raw","class":"portable","ro":false,"path":"/run/
grep -q -F '{"name":"c","type":"raw","class":"sysext","ro":false,"path":"/run/extensions/c.raw"' /tmp/discover.json grep -q -F '{"name":"c","type":"raw","class":"sysext","ro":false,"path":"/run/extensions/c.raw"' /tmp/discover.json
rm /tmp/discover.json /run/machines/a.raw /run/portables/b.raw /run/extensions/c.raw rm /tmp/discover.json /run/machines/a.raw /run/portables/b.raw /run/extensions/c.raw
systemd-dissect --discover --system
systemd-dissect --discover --user
systemd-dissect --discover --system --user
LOOP="$(systemd-dissect --attach --loop-ref=waldo "$MINIMAL_IMAGE.raw")" LOOP="$(systemd-dissect --attach --loop-ref=waldo "$MINIMAL_IMAGE.raw")"
# Wait until the symlinks we want to test are established # Wait until the symlinks we want to test are established

View File

@ -490,7 +490,7 @@ cmp /tmp/vlcredsdata /tmp/vlcredsdata2
rm /tmp/vlcredsdata /tmp/vlcredsdata2 rm /tmp/vlcredsdata /tmp/vlcredsdata2
clean_usertest() { clean_usertest() {
rm -f /tmp/usertest.data /tmp/usertest.data /tmp/brummbaer.data rm -f /tmp/usertest.data /tmp/usertest.data
} }
trap clean_usertest EXIT trap clean_usertest EXIT
@ -520,12 +520,6 @@ XDG_RUNTIME_DIR=/run/user/0 systemd-run --pipe --user --unit=waldi.service -p Lo
# Test mount unit with credential # Test mount unit with credential
test_mount_with_credential test_mount_with_credential
# Fully unpriv operation
dd if=/dev/urandom of=/tmp/brummbaer.data bs=4096 count=1
run0 -u testuser --pipe mkdir -p /home/testuser/.config/credstore.encrypted
run0 -u testuser --pipe systemd-creds encrypt --user --name=brummbaer - /home/testuser/.config/credstore.encrypted/brummbaer < /tmp/brummbaer.data
run0 -u testuser --pipe systemd-run --user --pipe -p ImportCredential=brummbaer systemd-creds cat brummbaer | cmp /tmp/brummbaer.data
systemd-analyze log-level info systemd-analyze log-level info
touch /testok touch /testok

View File

@ -69,51 +69,6 @@ SYSTEMD_PROC_CMDLINE="$CMDLINE" run_and_list "$GENERATOR_BIN" "$OUT_DIR"
link_endswith "$OUT_DIR/early/default.target.wants/debug-shell.service" /lib/systemd/system/debug-shell.service link_endswith "$OUT_DIR/early/default.target.wants/debug-shell.service" /lib/systemd/system/debug-shell.service
grep -F "/dev/tty666" "$OUT_DIR/early/debug-shell.service.d/50-tty.conf" grep -F "/dev/tty666" "$OUT_DIR/early/debug-shell.service.d/50-tty.conf"
# systemd.break (default)
: "debug-shell: regular + systemd.break"
CMDLINE="$CMDLINE systemd.break"
SYSTEMD_PROC_CMDLINE="$CMDLINE" run_and_list "$GENERATOR_BIN" "$OUT_DIR"
test ! -h "$OUT_DIR/early/default.target.wants/breakpoint-pre-udev.service"
test ! -h "$OUT_DIR/early/default.target.wants/breakpoint-pre-mount.service"
test ! -h "$OUT_DIR/early/default.target.wants/breakpoint-pre-switch-root.service"
# systemd.break=pre-switch-root
: "debug-shell: regular + systemd.break=pre-switch-root"
CMDLINE="$CMDLINE systemd.break=pre-switch-root"
SYSTEMD_PROC_CMDLINE="$CMDLINE" run_and_list "$GENERATOR_BIN" "$OUT_DIR"
test ! -h "$OUT_DIR/early/default.target.wants/breakpoint-pre-udev.service"
test ! -h "$OUT_DIR/early/default.target.wants/breakpoint-pre-mount.service"
test ! -h "$OUT_DIR/early/default.target.wants/breakpoint-pre-switch-root.service"
# systemd.break=pre-mount
: "debug-shell: regular + systemd.break=pre-mount"
CMDLINE="$CMDLINE systemd.break=pre-mount"
SYSTEMD_PROC_CMDLINE="$CMDLINE" run_and_list "$GENERATOR_BIN" "$OUT_DIR"
test ! -h "$OUT_DIR/early/default.target.wants/breakpoint-pre-udev.service"
test ! -h "$OUT_DIR/early/default.target.wants/breakpoint-pre-mount.service"
test ! -h "$OUT_DIR/early/default.target.wants/breakpoint-pre-switch-root.service"
# systemd.break=pre-basic
: "debug-shell: regular + systemd.break=pre-basic"
CMDLINE="$CMDLINE systemd.break=pre-basic"
SYSTEMD_PROC_CMDLINE="$CMDLINE" run_and_list "$GENERATOR_BIN" "$OUT_DIR"
link_endswith "$OUT_DIR/early/default.target.wants/breakpoint-pre-basic.service" /lib/systemd/system/breakpoint-pre-basic.service
# systemd.break=pre-udev
: "debug-shell: regular + systemd.break=pre-udev"
CMDLINE="$CMDLINE systemd.break=pre-udev"
SYSTEMD_PROC_CMDLINE="$CMDLINE" run_and_list "$GENERATOR_BIN" "$OUT_DIR"
link_endswith "$OUT_DIR/early/default.target.wants/breakpoint-pre-udev.service" /lib/systemd/system/breakpoint-pre-udev.service
# systemd.break=pre-udev,pre-basic,pre-mount,pre-switch-root
: "debug-shell: regular + systemd.break=pre-udev,pre-basic,pre-mount,pre-switch-root"
rm -f "$OUT_DIR/early/default.target.wants/breakpoint-pre-udev.service"
rm -f "$OUT_DIR/early/default.target.wants/breakpoint-pre-basic.service"
CMDLINE="$CMDLINE systemd.break=pre-udev,pre-basic,pre-mount,pre-switch-root"
SYSTEMD_PROC_CMDLINE="$CMDLINE" run_and_list "$GENERATOR_BIN" "$OUT_DIR"
link_endswith "$OUT_DIR/early/default.target.wants/breakpoint-pre-udev.service" /lib/systemd/system/breakpoint-pre-udev.service
link_endswith "$OUT_DIR/early/default.target.wants/breakpoint-pre-basic.service" /lib/systemd/system/breakpoint-pre-basic.service
# Now override the default target via systemd.unit= # Now override the default target via systemd.unit=
: "debug-shell: regular + systemd.unit=" : "debug-shell: regular + systemd.unit="
CMDLINE="$CMDLINE systemd.unit=my-fancy.target" CMDLINE="$CMDLINE systemd.unit=my-fancy.target"
@ -148,50 +103,6 @@ CMDLINE="$CMDLINE rd.systemd.debug_shell"
SYSTEMD_IN_INITRD=1 SYSTEMD_PROC_CMDLINE="$CMDLINE" run_and_list "$GENERATOR_BIN" "$OUT_DIR" SYSTEMD_IN_INITRD=1 SYSTEMD_PROC_CMDLINE="$CMDLINE" run_and_list "$GENERATOR_BIN" "$OUT_DIR"
link_endswith "$OUT_DIR/early/initrd.target.wants/debug-shell.service" /lib/systemd/system/debug-shell.service link_endswith "$OUT_DIR/early/initrd.target.wants/debug-shell.service" /lib/systemd/system/debug-shell.service
# rd.systemd.break (default)
: "debug-shell: initrd + rd.systemd.break"
CMDLINE="$CMDLINE rd.systemd.break"
SYSTEMD_IN_INITRD=1 SYSTEMD_PROC_CMDLINE="$CMDLINE" run_and_list "$GENERATOR_BIN" "$OUT_DIR"
link_endswith "$OUT_DIR/early/initrd.target.wants/breakpoint-pre-switch-root.service" /lib/systemd/system/breakpoint-pre-switch-root.service
# rd.systemd.break=pre-udev
: "debug-shell: initrd + rd.systemd.break=pre-udev"
CMDLINE="$CMDLINE rd.systemd.break=pre-udev"
SYSTEMD_IN_INITRD=1 SYSTEMD_PROC_CMDLINE="$CMDLINE" run_and_list "$GENERATOR_BIN" "$OUT_DIR"
link_endswith "$OUT_DIR/early/initrd.target.wants/breakpoint-pre-udev.service" /lib/systemd/system/breakpoint-pre-udev.service
# rd.systemd.break=pre-basic
: "debug-shell: initrd + rd.systemd.break=pre-basic"
CMDLINE="$CMDLINE rd.systemd.break=pre-basic"
SYSTEMD_IN_INITRD=1 SYSTEMD_PROC_CMDLINE="$CMDLINE" run_and_list "$GENERATOR_BIN" "$OUT_DIR"
link_endswith "$OUT_DIR/early/initrd.target.wants/breakpoint-pre-basic.service" /lib/systemd/system/breakpoint-pre-basic.service
# rd.systemd.break=pre-mount
: "debug-shell: initrd + rd.systemd.break=pre-mount"
CMDLINE="$CMDLINE rd.systemd.break=pre-mount"
SYSTEMD_IN_INITRD=1 SYSTEMD_PROC_CMDLINE="$CMDLINE" run_and_list "$GENERATOR_BIN" "$OUT_DIR"
link_endswith "$OUT_DIR/early/initrd.target.wants/breakpoint-pre-mount.service" /lib/systemd/system/breakpoint-pre-mount.service
# rd.systemd.break=pre-switch-root
: "debug-shell: initrd + rd.systemd.break=pre-switch-root"
rm -f "$OUT_DIR/early/initrd.target.wants/breakpoint-pre-switch-root.service"
CMDLINE="$CMDLINE rd.systemd.break=pre-switch-root"
SYSTEMD_IN_INITRD=1 SYSTEMD_PROC_CMDLINE="$CMDLINE" run_and_list "$GENERATOR_BIN" "$OUT_DIR"
link_endswith "$OUT_DIR/early/initrd.target.wants/breakpoint-pre-switch-root.service" /lib/systemd/system/breakpoint-pre-switch-root.service
# rd.systemd.break=pre-udev,pre-basic,pre-mount,pre-switch-root
: "debug-shell: initrd + rd.systemd.break=pre-udev,pre-mount,pre-switch-root"
rm -f "$OUT_DIR/early/initrd.target.wants/breakpoint-pre-udev.service"
rm -f "$OUT_DIR/early/initrd.target.wants/breakpoint-pre-basic.service"
rm -f "$OUT_DIR/early/initrd.target.wants/breakpoint-pre-mount.service"
rm -f "$OUT_DIR/early/initrd.target.wants/breakpoint-pre-switch-root.service"
CMDLINE="$CMDLINE rd.systemd.break=pre-udev,pre-basic,pre-mount,pre-switch-root"
SYSTEMD_IN_INITRD=1 SYSTEMD_PROC_CMDLINE="$CMDLINE" run_and_list "$GENERATOR_BIN" "$OUT_DIR"
link_endswith "$OUT_DIR/early/initrd.target.wants/breakpoint-pre-udev.service" /lib/systemd/system/breakpoint-pre-udev.service
link_endswith "$OUT_DIR/early/initrd.target.wants/breakpoint-pre-basic.service" /lib/systemd/system/breakpoint-pre-basic.service
link_endswith "$OUT_DIR/early/initrd.target.wants/breakpoint-pre-mount.service" /lib/systemd/system/breakpoint-pre-mount.service
link_endswith "$OUT_DIR/early/initrd.target.wants/breakpoint-pre-switch-root.service" /lib/systemd/system/breakpoint-pre-switch-root.service
# Override the default target # Override the default target
: "debug-shell: initrd + rd.systemd.unit" : "debug-shell: initrd + rd.systemd.unit"
CMDLINE="$CMDLINE rd.systemd.unit=my-fancy-initrd.target" CMDLINE="$CMDLINE rd.systemd.unit=my-fancy-initrd.target"

View File

@ -1,35 +0,0 @@
# SPDX-License-Identifier: LGPL-2.1-or-later
#
# This file is part of systemd.
#
# systemd is free software; you can redistribute it and/or modify it
# under the terms of the GNU Lesser General Public License as published by
# the Free Software Foundation; either version 2.1 of the License, or
# (at your option) any later version.
[Unit]
Description=Breakpoint Before Basic System
Documentation=man:systemd-debug-generator(8)
DefaultDependencies=no
Conflicts=shutdown.target emergency.target
After=sysinit.target sockets.target paths.target slices.target tmp.mount systemd-vconsole-setup.service
Before=basic.target
[Service]
Environment=SHELL_PROMPT_PREFIX="pre-basic "
Type=oneshot
ExecStartPre=-plymouth --wait quit
# Execute shell with "-" prefix to not consider the unit failed if it exits with
# a non-zero value
ExecStart=-{{SUSHELL}}
StandardInput=tty-force
StandardOutput=inherit
StandardError=inherit
KillMode=process
IgnoreSIGPIPE=no
# bash ignores SIGTERM
KillSignal=SIGHUP
# Unset locale for the console getty since the console has problems
# displaying some internationalized messages.
UnsetEnvironment=LANG LANGUAGE LC_CTYPE LC_NUMERIC LC_TIME LC_COLLATE LC_MONETARY LC_MESSAGES LC_PAPER LC_NAME LC_ADDRESS LC_TELEPHONE LC_MEASUREMENT LC_IDENTIFICATION

View File

@ -1,36 +0,0 @@
# SPDX-License-Identifier: LGPL-2.1-or-later
#
# This file is part of systemd.
#
# systemd is free software; you can redistribute it and/or modify it
# under the terms of the GNU Lesser General Public License as published by
# the Free Software Foundation; either version 2.1 of the License, or
# (at your option) any later version.
[Unit]
Description=Breakpoint Before Mounting the Root Filesystem on /sysroot
Documentation=man:systemd-debug-generator(8)
AssertPathExists=/etc/initrd-release
DefaultDependencies=no
Conflicts=shutdown.target emergency.target
After=basic.target systemd-vconsole-setup.service
Before=initrd-root-fs.target sysroot.mount systemd-fsck-root.service
[Service]
Environment=SHELL_PROMPT_PREFIX="pre-mount "
Type=oneshot
ExecStartPre=-plymouth --wait quit
# Execute shell with "-" prefix to not consider the unit failed if it exits with
# a non-zero value
ExecStart=-{{SUSHELL}}
StandardInput=tty-force
StandardOutput=inherit
StandardError=inherit
KillMode=process
IgnoreSIGPIPE=no
# bash ignores SIGTERM
KillSignal=SIGHUP
# Unset locale for the console getty since the console has problems
# displaying some internationalized messages.
UnsetEnvironment=LANG LANGUAGE LC_CTYPE LC_NUMERIC LC_TIME LC_COLLATE LC_MONETARY LC_MESSAGES LC_PAPER LC_NAME LC_ADDRESS LC_TELEPHONE LC_MEASUREMENT LC_IDENTIFICATION

View File

@ -1,37 +0,0 @@
# SPDX-License-Identifier: LGPL-2.1-or-later
#
# This file is part of systemd.
#
# systemd is free software; you can redistribute it and/or modify it
# under the terms of the GNU Lesser General Public License as published by
# the Free Software Foundation; either version 2.1 of the License, or
# (at your option) any later version.
[Unit]
Description=Breakpoint Before Switching Root
Documentation=man:systemd-debug-generator(8)
AssertPathExists=/etc/initrd-release
DefaultDependencies=no
Conflicts=shutdown.target emergency.target
Wants=remote-fs.target
After=initrd.target initrd-parse-etc.service sysroot.mount remote-fs.target systemd-vconsole-setup.service
Before=initrd-cleanup.service
[Service]
Environment=SHELL_PROMPT_PREFIX="pre-switch-root "
Type=oneshot
ExecStartPre=-plymouth --wait quit
# Execute shell with "-" prefix to not consider the unit failed if it exits with
# a non-zero value
ExecStart=-{{SUSHELL}}
StandardInput=tty-force
StandardOutput=inherit
StandardError=inherit
KillMode=process
IgnoreSIGPIPE=no
# bash ignores SIGTERM
KillSignal=SIGHUP
# Unset locale for the console getty since the console has problems
# displaying some internationalized messages.
UnsetEnvironment=LANG LANGUAGE LC_CTYPE LC_NUMERIC LC_TIME LC_COLLATE LC_MONETARY LC_MESSAGES LC_PAPER LC_NAME LC_ADDRESS LC_TELEPHONE LC_MEASUREMENT LC_IDENTIFICATION

View File

@ -1,36 +0,0 @@
# SPDX-License-Identifier: LGPL-2.1-or-later
#
# This file is part of systemd.
#
# systemd is free software; you can redistribute it and/or modify it
# under the terms of the GNU Lesser General Public License as published by
# the Free Software Foundation; either version 2.1 of the License, or
# (at your option) any later version.
[Unit]
Description=Breakpoint Before Starting to Process Kernel uevents
Documentation=man:systemd-debug-generator(8)
DefaultDependencies=no
Conflicts=shutdown.target emergency.target
Wants=systemd-journald.socket
After=systemd-journald.socket systemd-vconsole-setup.service
Before=systemd-udevd.service systemd-udev-trigger.service
[Service]
Environment=SHELL_PROMPT_PREFIX="pre-udev "
Type=oneshot
ExecStartPre=-plymouth --wait quit
# Execute shell with "-" prefix to not consider the unit failed if it exits with
# a non-zero value
ExecStart=-{{SUSHELL}}
StandardInput=tty-force
StandardOutput=inherit
StandardError=inherit
KillMode=process
IgnoreSIGPIPE=no
# bash ignores SIGTERM
KillSignal=SIGHUP
# Unset locale for the console getty since the console has problems
# displaying some internationalized messages.
UnsetEnvironment=LANG LANGUAGE LC_CTYPE LC_NUMERIC LC_TIME LC_COLLATE LC_MONETARY LC_MESSAGES LC_PAPER LC_NAME LC_ADDRESS LC_TELEPHONE LC_MEASUREMENT LC_IDENTIFICATION

View File

@ -7,10 +7,6 @@ units = [
{ 'file' : 'blockdev@.target' }, { 'file' : 'blockdev@.target' },
{ 'file' : 'bluetooth.target' }, { 'file' : 'bluetooth.target' },
{ 'file' : 'boot-complete.target' }, { 'file' : 'boot-complete.target' },
{ 'file' : 'breakpoint-pre-basic.service.in' },
{ 'file' : 'breakpoint-pre-mount.service.in' },
{ 'file' : 'breakpoint-pre-switch-root.service.in' },
{ 'file' : 'breakpoint-pre-udev.service.in' },
{ 'file' : 'capsule@.service.in' }, { 'file' : 'capsule@.service.in' },
{ 'file' : 'capsule.slice' }, { 'file' : 'capsule.slice' },
{ 'file' : 'console-getty.service.in' }, { 'file' : 'console-getty.service.in' },