mirror of
https://github.com/systemd/systemd.git
synced 2024-12-22 17:35:35 +03:00
Compare commits
1 Commits
85083bacaf
...
3ac5952cc3
Author | SHA1 | Date | |
---|---|---|---|
|
3ac5952cc3 |
13
.github/workflows/coverage.yml
vendored
13
.github/workflows/coverage.yml
vendored
@ -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
|
||||||
|
|
||||||
|
5
.github/workflows/mkosi.yml
vendored
5
.github/workflows/mkosi.yml
vendored
@ -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
1
.gitignore
vendored
@ -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
18
TODO
@ -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
|
||||||
|
210
docs/HACKING.md
210
docs/HACKING.md
@ -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,
|
||||||
|
@ -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
|
|
||||||
|
@ -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>
|
||||||
|
@ -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>
|
||||||
|
|
||||||
|
@ -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" />
|
||||||
|
@ -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>
|
||||||
|
@ -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")"
|
||||||
|
@ -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
|
||||||
|
@ -3,7 +3,6 @@
|
|||||||
[Build]
|
[Build]
|
||||||
ToolsTreePackages=
|
ToolsTreePackages=
|
||||||
gcc
|
gcc
|
||||||
gdb
|
|
||||||
gperf
|
gperf
|
||||||
lcov
|
lcov
|
||||||
llvm
|
llvm
|
||||||
|
@ -1,7 +0,0 @@
|
|||||||
# SPDX-License-Identifier: LGPL-2.1-or-later
|
|
||||||
|
|
||||||
[Match]
|
|
||||||
ToolsTreeDistribution=centos
|
|
||||||
|
|
||||||
[Build]
|
|
||||||
ToolsTreeRepositories=epel,epel-next
|
|
@ -5,7 +5,6 @@ ToolsTreeDistribution=opensuse
|
|||||||
|
|
||||||
[Build]
|
[Build]
|
||||||
ToolsTreePackages=
|
ToolsTreePackages=
|
||||||
libz1
|
|
||||||
gh
|
gh
|
||||||
mypy
|
mypy
|
||||||
pkgconfig(blkid)
|
pkgconfig(blkid)
|
||||||
|
@ -1,7 +0,0 @@
|
|||||||
# SPDX-License-Identifier: LGPL-2.1-or-later
|
|
||||||
|
|
||||||
[Match]
|
|
||||||
PathExists=build/
|
|
||||||
|
|
||||||
[Build]
|
|
||||||
ExtraSearchPaths=build/
|
|
9
po/fi.po
9
po/fi.po
@ -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"
|
||||||
|
@ -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
|
||||||
|
@ -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++) {
|
||||||
if (r < 0)
|
_cleanup_free_ char *buf = NULL;
|
||||||
return r;
|
size_t size;
|
||||||
|
|
||||||
|
r = read_virtual_file_at(smbios_fd, smbios_files[f], SIZE_MAX, &buf, &size);
|
||||||
|
if (r < 0)
|
||||||
|
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 (!c)
|
||||||
if (smbios_fields[f]) {
|
return log_oom();
|
||||||
_cleanup_free_ char *u = NULL;
|
|
||||||
|
|
||||||
u = utf16_to_utf8(smbios_fields[f], SIZE_MAX);
|
|
||||||
if (!u)
|
|
||||||
return log_oom();
|
|
||||||
|
|
||||||
c = cescape(u);
|
|
||||||
if (!c)
|
|
||||||
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) {
|
||||||
|
@ -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);
|
||||||
|
|
||||||
|
@ -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(¬_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(¬_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, ¬_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, ¬_ready_units) < 0)
|
if (device_setup_units(m, dev, &ready_units, ¬_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, ¬_ready_units);
|
(void) device_setup_units(m, dev, &ready_units, ¬_ready_units);
|
||||||
|
|
||||||
if (action == SD_DEVICE_REMOVE) {
|
if (action == SD_DEVICE_REMOVE) {
|
||||||
|
@ -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 */
|
||||||
|
@ -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);
|
||||||
assert(r != -EEXIST);
|
if (r < 0) {
|
||||||
if (r < 0)
|
assert(r != -EEXIST);
|
||||||
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);
|
||||||
assert(r != -EEXIST);
|
if (r < 0) {
|
||||||
if (r < 0)
|
assert(r != -EEXIST);
|
||||||
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);
|
||||||
assert(r != -EEXIST);
|
if (r < 0) {
|
||||||
if (r < 0)
|
assert(r != -EEXIST);
|
||||||
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,38 +445,15 @@ 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) {
|
r = decrypt_credential_and_warn(
|
||||||
|
id,
|
||||||
case RUNTIME_SCOPE_SYSTEM:
|
now(CLOCK_REALTIME),
|
||||||
/* In system mode talk directly to the TPM */
|
/* tpm2_device= */ NULL,
|
||||||
r = decrypt_credential_and_warn(
|
/* tpm2_signature_path= */ NULL,
|
||||||
id,
|
getuid(),
|
||||||
now(CLOCK_REALTIME),
|
&IOVEC_MAKE(data, size),
|
||||||
/* tpm2_device= */ NULL,
|
CREDENTIAL_ANY_SCOPE,
|
||||||
/* tpm2_signature_path= */ NULL,
|
&plaintext);
|
||||||
getuid(),
|
|
||||||
&IOVEC_MAKE(data, size),
|
|
||||||
CREDENTIAL_ANY_SCOPE,
|
|
||||||
&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;
|
||||||
|
|
||||||
|
@ -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));
|
||||||
|
|
||||||
|
@ -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");
|
||||||
}
|
}
|
||||||
|
@ -28,36 +28,23 @@
|
|||||||
#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 (i > 0)
|
||||||
|
sha1_process_bytes(L"&", 2, &ctx);
|
||||||
if (!smbios_fields[i]) {
|
sha1_process_bytes(smbios_fields[i], strlen16(smbios_fields[i]) * sizeof(char16_t), &ctx);
|
||||||
/* If some SMBIOS field is missing, don't generate the CHID, as per spec */
|
|
||||||
memzero(ret_chid, sizeof(EFI_GUID));
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (i > 0)
|
|
||||||
sha1_process_bytes(L"&", 2, &ctx);
|
|
||||||
|
|
||||||
sha1_process_bytes(smbios_fields[i], strlen16(smbios_fields[i]) * sizeof(char16_t), &ctx);
|
|
||||||
}
|
|
||||||
|
|
||||||
uint8_t hash[SHA1_DIGEST_SIZE];
|
uint8_t hash[SHA1_DIGEST_SIZE];
|
||||||
sha1_finish_ctx(&ctx, hash);
|
sha1_finish_ctx(&ctx, hash);
|
||||||
|
|
||||||
@ -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)
|
||||||
|
get_chid(smbios_fields, chid_smbios_table[i], &ret_chids[i]);
|
||||||
|
else
|
||||||
memzero(&ret_chids[i], sizeof(EFI_GUID));
|
memzero(&ret_chids[i], sizeof(EFI_GUID));
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
get_chid(smbios_fields, chid_smbios_table[i], &ret_chids[i]);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -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;
|
||||||
|
|
||||||
|
@ -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)
|
||||||
|
@ -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);
|
||||||
|
@ -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);
|
||||||
|
@ -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;
|
||||||
|
@ -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);
|
||||||
|
@ -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);
|
|
||||||
}
|
|
||||||
|
@ -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);
|
||||||
|
@ -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;
|
||||||
|
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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;
|
||||||
|
@ -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;
|
||||||
|
|
||||||
|
@ -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");
|
||||||
|
|
||||||
|
@ -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;
|
||||||
|
@ -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);
|
||||||
|
@ -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)
|
||||||
|
@ -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;
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
@ -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);
|
||||||
|
|
||||||
|
@ -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,
|
||||||
|
@ -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);
|
||||||
|
@ -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;
|
||||||
|
|
||||||
|
@ -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;
|
||||||
|
@ -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;
|
||||||
|
@ -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;
|
/* Use the initrd search path if there is one, otherwise use the common one */
|
||||||
|
return in_initrd() && image_search_path_initrd[class] ? image_search_path_initrd[class] : image_search_path[class];
|
||||||
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 */
|
|
||||||
ns = in_initrd() && image_search_path_initrd[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;
|
||||||
|
|
||||||
|
@ -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);
|
||||||
|
@ -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;
|
||||||
|
|
||||||
|
@ -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
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -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;
|
||||||
|
|
||||||
|
@ -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) {
|
||||||
|
@ -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");
|
||||||
|
@ -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)
|
||||||
|
@ -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)
|
||||||
|
@ -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)
|
|
||||||
|
@ -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',
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
]
|
]
|
||||||
|
@ -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() {
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
|
@ -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"
|
||||||
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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' },
|
||||||
|
Loading…
Reference in New Issue
Block a user