mirror of
https://github.com/systemd/systemd
synced 2025-10-07 20:54:45 +02:00
Compare commits
59 Commits
7aefb194e7
...
869b44e0f7
Author | SHA1 | Date | |
---|---|---|---|
![]() |
869b44e0f7 | ||
![]() |
78738adf88 | ||
![]() |
4d7851380a | ||
![]() |
7b869ff949 | ||
![]() |
369f311686 | ||
![]() |
b1ce0a2b50 | ||
![]() |
531e6a2091 | ||
![]() |
0939d5c360 | ||
![]() |
1d81c3a74e | ||
![]() |
c35606b272 | ||
![]() |
3fc2a44043 | ||
![]() |
543a48b653 | ||
![]() |
da522c9921 | ||
![]() |
2b912d2066 | ||
![]() |
1a60b97524 | ||
![]() |
98751cf16e | ||
![]() |
090c3f924c | ||
![]() |
a1518f0a94 | ||
![]() |
1e29a967c7 | ||
![]() |
683efcf649 | ||
![]() |
4d000c4853 | ||
![]() |
ab1333b2b7 | ||
![]() |
bdfb884237 | ||
![]() |
a4a6e21673 | ||
![]() |
661b5bfd21 | ||
![]() |
86c4e42380 | ||
![]() |
0e0b482a71 | ||
![]() |
d38f87c56c | ||
![]() |
31b7616420 | ||
![]() |
628f45f4a3 | ||
![]() |
99ae2ae328 | ||
![]() |
878fa7d26e | ||
![]() |
0c0b4d544c | ||
![]() |
b3337feb55 | ||
![]() |
52fe0a490d | ||
![]() |
49bdc8b1e8 | ||
![]() |
d6b3793704 | ||
![]() |
054464ad52 | ||
![]() |
390097724b | ||
![]() |
470da65110 | ||
![]() |
d5f4bd3700 | ||
![]() |
e3fef210c8 | ||
![]() |
fe3f2ac073 | ||
![]() |
5dc3096efb | ||
![]() |
79eec46dfd | ||
![]() |
89701e02ac | ||
![]() |
303d1b6b57 | ||
![]() |
712f763036 | ||
![]() |
545fde151a | ||
![]() |
afa9992429 | ||
![]() |
a5d8520f86 | ||
![]() |
84c05ec632 | ||
![]() |
3484af2800 | ||
![]() |
5a1cb174f8 | ||
![]() |
204e3cb6c8 | ||
![]() |
7f76ff2821 | ||
![]() |
a4488ae6ae | ||
![]() |
3800adc9e5 | ||
![]() |
24a14e9050 |
16
.github/workflows/coverage.yml
vendored
16
.github/workflows/coverage.yml
vendored
@ -25,7 +25,7 @@ jobs:
|
|||||||
|
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683
|
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683
|
||||||
- uses: systemd/mkosi@0d1143150835b21c1bfe64428df5f45b558280b1
|
- uses: systemd/mkosi@184472f0f1f831ca29953546ec01fd941ff763a6
|
||||||
|
|
||||||
# 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
|
||||||
@ -83,22 +83,22 @@ jobs:
|
|||||||
run: mkosi summary
|
run: mkosi summary
|
||||||
|
|
||||||
- name: Build tools tree
|
- name: Build tools tree
|
||||||
run: sudo mkosi -f sandbox -- true
|
run: sudo mkosi -f box -- true
|
||||||
|
|
||||||
- name: Configure meson
|
- name: Configure meson
|
||||||
run: |
|
run: |
|
||||||
sudo mkosi sandbox -- \
|
sudo mkosi box -- \
|
||||||
meson setup \
|
meson setup \
|
||||||
--buildtype=debugoptimized \
|
--buildtype=debugoptimized \
|
||||||
build
|
build
|
||||||
|
|
||||||
- name: Build image
|
- name: Build image
|
||||||
run: sudo mkosi sandbox -- meson compile -C build mkosi
|
run: sudo mkosi box -- meson compile -C build mkosi
|
||||||
|
|
||||||
- name: Initial coverage report
|
- name: Initial coverage report
|
||||||
run: |
|
run: |
|
||||||
sudo mkdir -p build/test/coverage
|
sudo mkdir -p build/test/coverage
|
||||||
sudo mkosi sandbox -- \
|
sudo mkosi box -- \
|
||||||
lcov \
|
lcov \
|
||||||
--directory build/mkosi.builddir/arch~rolling~x86-64 \
|
--directory build/mkosi.builddir/arch~rolling~x86-64 \
|
||||||
--capture \
|
--capture \
|
||||||
@ -115,7 +115,7 @@ jobs:
|
|||||||
# --preserve-env makes sure all the github actions environment variables are propagated which are
|
# --preserve-env makes sure all the github actions environment variables are propagated which are
|
||||||
# used in integration-test-wrapper.py to construct the `gh` command line to download the journals
|
# used in integration-test-wrapper.py to construct the `gh` command line to download the journals
|
||||||
# of failed tests.
|
# of failed tests.
|
||||||
sudo --preserve-env mkosi sandbox -- \
|
sudo --preserve-env mkosi box -- \
|
||||||
env \
|
env \
|
||||||
TEST_RUNNER=ubuntu-24.04 \
|
TEST_RUNNER=ubuntu-24.04 \
|
||||||
meson test \
|
meson test \
|
||||||
@ -147,10 +147,10 @@ jobs:
|
|||||||
lcov_args+=(--add-tracefile "${file}")
|
lcov_args+=(--add-tracefile "${file}")
|
||||||
done < <(find build/test/coverage -name "TEST-*.coverage-info")
|
done < <(find build/test/coverage -name "TEST-*.coverage-info")
|
||||||
|
|
||||||
sudo mkosi sandbox -- lcov --ignore-errors inconsistent,inconsistent "${lcov_args[@]}" --output-file build/test/coverage/everything.coverage-info
|
sudo mkosi box -- lcov --ignore-errors inconsistent,inconsistent "${lcov_args[@]}" --output-file build/test/coverage/everything.coverage-info
|
||||||
|
|
||||||
- name: List coverage report
|
- name: List coverage report
|
||||||
run: sudo mkosi sandbox -- lcov --ignore-errors inconsistent,inconsistent --list build/test/coverage/everything.coverage-info
|
run: sudo mkosi box -- lcov --ignore-errors inconsistent,inconsistent --list build/test/coverage/everything.coverage-info
|
||||||
|
|
||||||
- name: Coveralls
|
- name: Coveralls
|
||||||
uses: coverallsapp/github-action@648a8eb78e6d50909eff900e4ec85cab4524a45b
|
uses: coverallsapp/github-action@648a8eb78e6d50909eff900e4ec85cab4524a45b
|
||||||
|
24
.github/workflows/linter.yml
vendored
24
.github/workflows/linter.yml
vendored
@ -38,10 +38,10 @@ jobs:
|
|||||||
LINTER_RULES_PATH: .github/linters
|
LINTER_RULES_PATH: .github/linters
|
||||||
GITHUB_ACTIONS_CONFIG_FILE: actionlint.yml
|
GITHUB_ACTIONS_CONFIG_FILE: actionlint.yml
|
||||||
|
|
||||||
- uses: systemd/mkosi@0d1143150835b21c1bfe64428df5f45b558280b1
|
- uses: systemd/mkosi@184472f0f1f831ca29953546ec01fd941ff763a6
|
||||||
|
|
||||||
- name: Check that tabs are not used in Python code
|
- name: Check that tabs are not used in Python code
|
||||||
run: sh -c '! git grep -P "\\t" -- src/basic/generate-bpf-delegate-configs.py src/boot/generate-hwids-section.py src/ukify/ukify.py test/integration-tests/integration-test-wrapper.py'
|
run: sh -c '! git grep -P "\\t" -- src/core/generate-bpf-delegate-configs.py src/boot/generate-hwids-section.py src/ukify/ukify.py test/integration-tests/integration-test-wrapper.py'
|
||||||
|
|
||||||
- name: Build tools tree
|
- name: Build tools tree
|
||||||
run: |
|
run: |
|
||||||
@ -51,29 +51,29 @@ jobs:
|
|||||||
ToolsTreeRelease=rawhide
|
ToolsTreeRelease=rawhide
|
||||||
EOF
|
EOF
|
||||||
|
|
||||||
mkosi -f sandbox -- true
|
mkosi -f box -- true
|
||||||
|
|
||||||
- name: Run mypy
|
- name: Run mypy
|
||||||
run: |
|
run: |
|
||||||
mkosi sandbox -- mypy --version
|
mkosi box -- mypy --version
|
||||||
mkosi sandbox -- mypy src/basic/generate-bpf-delegate-configs.py src/boot/generate-hwids-section.py src/test/generate-sym-test.py src/ukify/ukify.py test/integration-tests/integration-test-wrapper.py
|
mkosi box -- mypy src/core/generate-bpf-delegate-configs.py src/boot/generate-hwids-section.py src/test/generate-sym-test.py src/ukify/ukify.py test/integration-tests/integration-test-wrapper.py
|
||||||
|
|
||||||
- name: Run ruff check
|
- name: Run ruff check
|
||||||
run: |
|
run: |
|
||||||
mkosi sandbox -- ruff --version
|
mkosi box -- ruff --version
|
||||||
mkosi sandbox -- ruff check src/basic/generate-bpf-delegate-configs.py src/boot/generate-hwids-section.py src/test/generate-sym-test.py src/ukify/ukify.py test/integration-tests/integration-test-wrapper.py
|
mkosi box -- ruff check src/core/generate-bpf-delegate-configs.py src/boot/generate-hwids-section.py src/test/generate-sym-test.py src/ukify/ukify.py test/integration-tests/integration-test-wrapper.py
|
||||||
|
|
||||||
- name: Run ruff format
|
- name: Run ruff format
|
||||||
run: |
|
run: |
|
||||||
mkosi sandbox -- ruff --version
|
mkosi box -- ruff --version
|
||||||
if ! mkosi sandbox -- ruff format --check src/basic/generate-bpf-delegate-configs.py src/boot/generate-hwids-section.py src/test/generate-sym-test.py src/ukify/ukify.py test/integration-tests/integration-test-wrapper.py
|
if ! mkosi box -- ruff format --check src/core/generate-bpf-delegate-configs.py src/boot/generate-hwids-section.py src/test/generate-sym-test.py src/ukify/ukify.py test/integration-tests/integration-test-wrapper.py
|
||||||
then
|
then
|
||||||
echo "Please run 'ruff format' on the above files or apply the diffs below manually"
|
echo "Please run 'ruff format' on the above files or apply the diffs below manually"
|
||||||
mkosi sandbox -- ruff format --check --quiet --diff src/basic/generate-bpf-delegate-configs.py src/boot/generate-hwids-section.py src/test/generate-sym-test.py src/ukify/ukify.py test/integration-tests/integration-test-wrapper.py
|
mkosi box -- ruff format --check --quiet --diff src/core/generate-bpf-delegate-configs.py src/boot/generate-hwids-section.py src/test/generate-sym-test.py src/ukify/ukify.py test/integration-tests/integration-test-wrapper.py
|
||||||
fi
|
fi
|
||||||
|
|
||||||
- name: Configure meson
|
- name: Configure meson
|
||||||
run: mkosi sandbox -- env CC=clang CXX=clang++ meson setup -Dlocalegen-path=/usr/bin/locale-gen -Dcompat-mutable-uid-boundaries=true build
|
run: mkosi box -- env CC=clang CXX=clang++ meson setup -Dlocalegen-path=/usr/bin/locale-gen -Dcompat-mutable-uid-boundaries=true build
|
||||||
|
|
||||||
- name: Run clang-tidy
|
- name: Run clang-tidy
|
||||||
run: mkosi sandbox -- meson test -C build --suite=clang-tidy --print-errorlogs --no-stdsplit
|
run: mkosi box -- meson test -C build --suite=clang-tidy --print-errorlogs --no-stdsplit
|
||||||
|
12
.github/workflows/mkosi.yml
vendored
12
.github/workflows/mkosi.yml
vendored
@ -147,7 +147,7 @@ jobs:
|
|||||||
|
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683
|
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683
|
||||||
- uses: systemd/mkosi@0d1143150835b21c1bfe64428df5f45b558280b1
|
- uses: systemd/mkosi@184472f0f1f831ca29953546ec01fd941ff763a6
|
||||||
|
|
||||||
# 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
|
||||||
@ -214,21 +214,21 @@ jobs:
|
|||||||
run: mkosi summary
|
run: mkosi summary
|
||||||
|
|
||||||
- name: Build tools tree
|
- name: Build tools tree
|
||||||
run: sudo mkosi -f sandbox -- true
|
run: sudo mkosi -f box -- true
|
||||||
|
|
||||||
- name: Configure meson
|
- name: Configure meson
|
||||||
run: |
|
run: |
|
||||||
# /usr/sbin/bpftool is completely broken inside containers on Ubuntu which makes meson blow up so
|
# /usr/sbin/bpftool is completely broken inside containers on Ubuntu which makes meson blow up so
|
||||||
# disable the bpf-framework stuff to avoid the issue.
|
# disable the bpf-framework stuff to avoid the issue.
|
||||||
# TODO: Drop when we move off Ubuntu Noble as this will be fixed in the next Ubuntu LTS release.
|
# TODO: Drop when we move off Ubuntu Noble as this will be fixed in the next Ubuntu LTS release.
|
||||||
sudo mkosi sandbox -- \
|
sudo mkosi box -- \
|
||||||
meson setup \
|
meson setup \
|
||||||
--buildtype=debugoptimized \
|
--buildtype=debugoptimized \
|
||||||
-Dbpf-framework=disabled \
|
-Dbpf-framework=disabled \
|
||||||
build
|
build
|
||||||
|
|
||||||
- name: Build image
|
- name: Build image
|
||||||
run: sudo mkosi sandbox -- meson compile -C build mkosi
|
run: sudo mkosi box -- meson compile -C build mkosi
|
||||||
|
|
||||||
- name: Make sure sources weren't polluted by package build scripts
|
- name: Make sure sources weren't polluted by package build scripts
|
||||||
run: |
|
run: |
|
||||||
@ -243,7 +243,7 @@ jobs:
|
|||||||
|
|
||||||
- name: Run integration tests
|
- name: Run integration tests
|
||||||
run: |
|
run: |
|
||||||
if [[ "$(sudo mkosi sandbox -- meson test --help)" == *"--max-lines"* ]]; then
|
if [[ "$(sudo mkosi box -- meson test --help)" == *"--max-lines"* ]]; then
|
||||||
MAX_LINES=(--max-lines 300)
|
MAX_LINES=(--max-lines 300)
|
||||||
else
|
else
|
||||||
MAX_LINES=()
|
MAX_LINES=()
|
||||||
@ -256,7 +256,7 @@ jobs:
|
|||||||
# --preserve-env makes sure all the github actions environment variables are propagated which are
|
# --preserve-env makes sure all the github actions environment variables are propagated which are
|
||||||
# used in integration-test-wrapper.py to construct the `gh` command line to download the journals
|
# used in integration-test-wrapper.py to construct the `gh` command line to download the journals
|
||||||
# of failed tests.
|
# of failed tests.
|
||||||
sudo --preserve-env mkosi sandbox -- \
|
sudo --preserve-env mkosi box -- \
|
||||||
env \
|
env \
|
||||||
TEST_PREFER_QEMU=${{ matrix.vm }} \
|
TEST_PREFER_QEMU=${{ matrix.vm }} \
|
||||||
TEST_NO_QEMU=${{ matrix.no_qemu }} \
|
TEST_NO_QEMU=${{ matrix.no_qemu }} \
|
||||||
|
3
NEWS
3
NEWS
@ -135,6 +135,9 @@ CHANGES WITH 258 in spe:
|
|||||||
incompatible with PrivateDevices= and resulted in automatic extension
|
incompatible with PrivateDevices= and resulted in automatic extension
|
||||||
of the DeviceAllow= list. The latter behaviour has been removed.
|
of the DeviceAllow= list. The latter behaviour has been removed.
|
||||||
|
|
||||||
|
* The command 'journalctl --follow' now exits with success on
|
||||||
|
SIGTERM/SIGINT, or its pipe STDOUT is disconnected.
|
||||||
|
|
||||||
Announcements of Future Feature Removals:
|
Announcements of Future Feature Removals:
|
||||||
|
|
||||||
* Support for System V service scripts is deprecated and will be
|
* Support for System V service scripts is deprecated and will be
|
||||||
|
@ -20,6 +20,9 @@ There are many, and more are constantly added, so we will not enumerate them all
|
|||||||
|
|
||||||
The code that is shared between components is split into a few directories, each with a different purpose:
|
The code that is shared between components is split into a few directories, each with a different purpose:
|
||||||
|
|
||||||
|
- 'src/include/uapi/' contains copy of kernel headers we use.
|
||||||
|
'src/include/override/' contains wrappers for libc and kernel headers, to provide several missing symbols.
|
||||||
|
|
||||||
- `src/basic/` and `src/fundamental/` — those directories contain code primitives that are used by all other code.
|
- `src/basic/` and `src/fundamental/` — those directories contain code primitives that are used by all other code.
|
||||||
`src/fundamental/` is stricter, because it used for EFI and user-space code, while `src/basic/` is only used for user-space code.
|
`src/fundamental/` is stricter, because it used for EFI and user-space code, while `src/basic/` is only used for user-space code.
|
||||||
The code in `src/fundamental/` cannot depend on any other code in the tree, and `src/basic/` can depend only on itself and `src/fundamental/`.
|
The code in `src/fundamental/` cannot depend on any other code in the tree, and `src/basic/` can depend only on itself and `src/fundamental/`.
|
||||||
@ -43,6 +46,12 @@ Any code that is used only for EFI goes under `src/boot/efi/`, and `src/fundamen
|
|||||||
|
|
||||||
To summarize:
|
To summarize:
|
||||||
|
|
||||||
|
`src/include/uapi/`
|
||||||
|
- copy of kernel headers
|
||||||
|
|
||||||
|
`src/include/override/`
|
||||||
|
- wrappers for libc and kernel headers
|
||||||
|
|
||||||
`src/fundamental/`
|
`src/fundamental/`
|
||||||
- may be used by all code in the tree
|
- may be used by all code in the tree
|
||||||
- may not use any code outside of `src/fundamental/`
|
- may not use any code outside of `src/fundamental/`
|
||||||
|
@ -40,16 +40,16 @@ Then, you can build, run and test systemd executables as follows:
|
|||||||
|
|
||||||
```sh
|
```sh
|
||||||
$ mkosi -f genkey # Generate signing keys once.
|
$ mkosi -f genkey # Generate signing keys once.
|
||||||
$ mkosi -f sandbox -- meson setup -Dbpf-framework=disabled build # bpftool detection inside mkosi sandbox is broken on Ubuntu Noble and older
|
$ mkosi -f box -- meson setup -Dbpf-framework=disabled build # bpftool detection inside mkosi box is broken on Ubuntu Noble and older
|
||||||
$ mkosi -f sandbox -- meson compile -C build
|
$ mkosi -f box -- meson compile -C build
|
||||||
$ mkosi -f sandbox -- build/systemctl --version
|
$ mkosi -f box -- build/systemctl --version
|
||||||
$ mkosi -f sandbox -- meson test -C build # Run the unit tests
|
$ mkosi -f box -- meson test -C build # Run the unit tests
|
||||||
```
|
```
|
||||||
|
|
||||||
To build and boot an OS image with the latest systemd installed:
|
To build and boot an OS image with the latest systemd installed:
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
$ mkosi -f sandbox -- meson compile -C build mkosi # (re-)build the OS image
|
$ mkosi -f box -- meson compile -C build mkosi # (re-)build the OS image
|
||||||
$ mkosi boot # Boot the image with systemd-nspawn.
|
$ mkosi boot # Boot the image with systemd-nspawn.
|
||||||
$ mkosi vm # Boot the image with qemu.
|
$ mkosi vm # Boot the image with qemu.
|
||||||
```
|
```
|
||||||
@ -65,8 +65,8 @@ $ cd systemd
|
|||||||
$ git checkout -b <BRANCH> # where BRANCH is the name of the branch
|
$ git checkout -b <BRANCH> # where BRANCH is the name of the branch
|
||||||
$ $EDITOR src/core/main.c # or wherever you'd like to make your changes
|
$ $EDITOR src/core/main.c # or wherever you'd like to make your changes
|
||||||
$ mkosi -f genkey # Generate signing keys once.
|
$ mkosi -f genkey # Generate signing keys once.
|
||||||
$ mkosi -f sandbox -- meson setup build # Set up meson
|
$ mkosi -f box -- meson setup build # Set up meson
|
||||||
$ mkosi -f sandbox -- meson compile -C build mkosi # (re-)build the test image
|
$ mkosi -f box -- meson compile -C build mkosi # (re-)build the test image
|
||||||
$ mkosi vm # Boot the image in qemu
|
$ mkosi vm # Boot the image in qemu
|
||||||
$ git add -p # interactively put together your patch
|
$ git add -p # interactively put together your patch
|
||||||
$ git commit # commit it
|
$ git commit # commit it
|
||||||
@ -85,7 +85,7 @@ not required to write basic patches.
|
|||||||
## Building the OS image without a tools tree
|
## Building the OS image without a tools tree
|
||||||
|
|
||||||
By default, `mkosi` will first build a tools tree and use it build the image and
|
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
|
provide the environment for `mkosi box`. To disable the tools tree and use
|
||||||
binaries from your host instead, write the following to `mkosi/mkosi.local.conf`:
|
binaries from your host instead, write the following to `mkosi/mkosi.local.conf`:
|
||||||
|
|
||||||
```conf
|
```conf
|
||||||
@ -311,7 +311,7 @@ To debug systemd-boot in an IDE such as VSCode we can use a launch configuration
|
|||||||
right in your editor of choice (with the right plugin installed). When using mkosi, we can run clangd in the
|
right in your editor of choice (with the right plugin installed). When using mkosi, we can run clangd in the
|
||||||
mkosi tools tree to avoid needing to install clangd on the host machine.
|
mkosi tools tree to avoid needing to install clangd on the host machine.
|
||||||
|
|
||||||
All that is required is to run `mkosi -f sandbox true` once to make sure the tools tree is available and to modify
|
All that is required is to run `mkosi -f box true` once to make sure the tools tree is available and to modify
|
||||||
the path of the clangd binary used by your editor to the `mkosi.clangd` script included in the systemd repository.
|
the path of the clangd binary used by your editor to the `mkosi.clangd` script included in the systemd repository.
|
||||||
For example, for VScode, you'd have to add the following to the VSCode workspace settings of the systemd repository:
|
For example, for VScode, you'd have to add the following to the VSCode workspace settings of the systemd repository:
|
||||||
|
|
||||||
@ -329,7 +329,7 @@ When using clangd, it's recommended to setup the build directory containing the
|
|||||||
compilation database used by clangd to use clang as the compiler as well:
|
compilation database used by clangd to use clang as the compiler as well:
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
$ mkosi sandbox -- env CC=clang CXX=clang++ meson setup build
|
$ mkosi box -- env CC=clang CXX=clang++ meson setup build
|
||||||
```
|
```
|
||||||
|
|
||||||
Additionally, the `gensources` target can be used to make sure all generated
|
Additionally, the `gensources` target can be used to make sure all generated
|
||||||
@ -337,5 +337,5 @@ sources are generated to avoid clangd complaining that these source files don't
|
|||||||
exist.
|
exist.
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
$ mkosi sandbox -- ninja -C build gensources
|
$ mkosi box -- ninja -C build gensources
|
||||||
```
|
```
|
||||||
|
@ -20,9 +20,10 @@ xsltproc_flags = [
|
|||||||
'--stringparam', 'man.copyright.section.enabled', '0',
|
'--stringparam', 'man.copyright.section.enabled', '0',
|
||||||
'--stringparam', 'systemd.version', '@0@'.format(meson.project_version()),
|
'--stringparam', 'systemd.version', '@0@'.format(meson.project_version()),
|
||||||
'--path',
|
'--path',
|
||||||
'@0@:@1@:@2@'.format(meson.current_build_dir(),
|
'@0@:@1@:@2@:@3@'.format(meson.current_build_dir(),
|
||||||
meson.current_source_dir(),
|
meson.current_source_dir(),
|
||||||
libshared_build_dir)]
|
libshared_build_dir,
|
||||||
|
libcore_build_dir)]
|
||||||
|
|
||||||
custom_man_xsl = files('custom-man.xsl')
|
custom_man_xsl = files('custom-man.xsl')
|
||||||
custom_html_xsl = files('custom-html.xsl')
|
custom_html_xsl = files('custom-html.xsl')
|
||||||
@ -35,17 +36,6 @@ custom_entities_ent = custom_target(
|
|||||||
|
|
||||||
man_page_depends += custom_entities_ent
|
man_page_depends += custom_entities_ent
|
||||||
|
|
||||||
generate_bpf_delegate_configs = find_program('../src/basic/generate-bpf-delegate-configs.py')
|
|
||||||
|
|
||||||
bpf_delegate_xml = custom_target(
|
|
||||||
input : files('../src/basic/include/linux/bpf.h'),
|
|
||||||
output : 'bpf-delegate.xml',
|
|
||||||
command : [generate_bpf_delegate_configs,
|
|
||||||
'doc',
|
|
||||||
'@INPUT@'],
|
|
||||||
capture : true)
|
|
||||||
man_page_depends += bpf_delegate_xml
|
|
||||||
|
|
||||||
man_pages = []
|
man_pages = []
|
||||||
html_pages = []
|
html_pages = []
|
||||||
source_xml_files = []
|
source_xml_files = []
|
||||||
|
@ -2567,7 +2567,7 @@ RestrictNamespaces=~cgroup net</programlisting>
|
|||||||
available to the unit's processes. When mounting the BPF filesystem with the fsopen() API, four mount
|
available to the unit's processes. When mounting the BPF filesystem with the fsopen() API, four mount
|
||||||
options can be specified to set a list of BPF commands, maps, programs and attachment types that are
|
options can be specified to set a list of BPF commands, maps, programs and attachment types that are
|
||||||
allowed to be used. Processes needs to get a file descriptor for the bpffs mountpoint and use that to
|
allowed to be used. Processes needs to get a file descriptor for the bpffs mountpoint and use that to
|
||||||
get a token which will enable for that user namespace the BPF functionalities choosen upon bpffs mount.
|
get a token which will enable for that user namespace the BPF functionalities chosen upon bpffs mount.
|
||||||
A more detailed explanation of the feature can be found in this
|
A more detailed explanation of the feature can be found in this
|
||||||
<ulink url="https://lwn.net/Articles/947173/">LWN post</ulink>.</para>
|
<ulink url="https://lwn.net/Articles/947173/">LWN post</ulink>.</para>
|
||||||
|
|
||||||
|
40
meson.build
40
meson.build
@ -580,7 +580,6 @@ foreach ident : [
|
|||||||
['fsconfig', '''#include <sys/mount.h>'''], # since glibc-2.36
|
['fsconfig', '''#include <sys/mount.h>'''], # since glibc-2.36
|
||||||
['fsmount', '''#include <sys/mount.h>'''], # since glibc-2.36
|
['fsmount', '''#include <sys/mount.h>'''], # since glibc-2.36
|
||||||
['fsopen', '''#include <sys/mount.h>'''], # since glibc-2.36
|
['fsopen', '''#include <sys/mount.h>'''], # since glibc-2.36
|
||||||
['fspick', '''#include <sys/mount.h>'''], # since glibc-2.36
|
|
||||||
['mount_setattr', '''#include <sys/mount.h>'''], # since glibc-2.36
|
['mount_setattr', '''#include <sys/mount.h>'''], # since glibc-2.36
|
||||||
['move_mount', '''#include <sys/mount.h>'''], # since glibc-2.36
|
['move_mount', '''#include <sys/mount.h>'''], # since glibc-2.36
|
||||||
['open_tree', '''#include <sys/mount.h>'''], # since glibc-2.36
|
['open_tree', '''#include <sys/mount.h>'''], # since glibc-2.36
|
||||||
@ -591,15 +590,17 @@ foreach ident : [
|
|||||||
['ioprio_get', '''#include <sched.h>'''], # no known header declares ioprio_get
|
['ioprio_get', '''#include <sched.h>'''], # no known header declares ioprio_get
|
||||||
['ioprio_set', '''#include <sched.h>'''], # no known header declares ioprio_set
|
['ioprio_set', '''#include <sched.h>'''], # no known header declares ioprio_set
|
||||||
['rt_tgsigqueueinfo', '''#include <signal.h>'''], # no known header declares rt_tgsigqueueinfo
|
['rt_tgsigqueueinfo', '''#include <signal.h>'''], # no known header declares rt_tgsigqueueinfo
|
||||||
|
['open_tree_attr', '''#include <sys/mount.h>'''], # no known header declares open_tree_attr
|
||||||
['quotactl_fd', '''#include <sys/quota.h>'''], # no known header declares quotactl_fd
|
['quotactl_fd', '''#include <sys/quota.h>'''], # no known header declares quotactl_fd
|
||||||
['fchmodat2', '''#include <sys/stat.h>'''], # no known header declares fchmodat2
|
['fchmodat2', '''#include <sys/stat.h>'''], # no known header declares fchmodat2
|
||||||
['bpf', '''#include <sys/syscall.h>'''], # no known header declares bpf
|
['bpf', '''#include <sys/syscall.h>'''], # no known header declares bpf
|
||||||
['kcmp', '''#include <sys/syscall.h>'''], # no known header declares kcmp
|
['kcmp', '''#include <sys/syscall.h>'''], # no known header declares kcmp
|
||||||
['keyctl', '''#include <sys/syscall.h>'''], # no known header declares keyctl
|
['keyctl', '''#include <sys/syscall.h>'''], # no known header declares keyctl
|
||||||
['pivot_root', '''#include <sys/syscall.h>'''], # no known header declares pivot_root
|
['add_key', '''#include <sys/syscall.h>'''], # no known header declares add_key
|
||||||
|
['request_key', '''#include <sys/syscall.h>'''], # no known header declares request_key
|
||||||
['setxattrat', '''#include <sys/xattr.h>'''], # no known header declares setxattrat
|
['setxattrat', '''#include <sys/xattr.h>'''], # no known header declares setxattrat
|
||||||
['removexattrat', '''#include <sys/xattr.h>'''], # no known header declares removexattrat
|
['removexattrat', '''#include <sys/xattr.h>'''], # no known header declares removexattrat
|
||||||
['open_tree_attr', '''#include <sys/mount.h>'''], # no known header declares open_tree_attr
|
['pivot_root', '''#include <unistd.h>'''], # no known header declares pivot_root
|
||||||
]
|
]
|
||||||
|
|
||||||
have = cc.has_function(ident[0], prefix : ident[1], args : '-D_GNU_SOURCE')
|
have = cc.has_function(ident[0], prefix : ident[1], args : '-D_GNU_SOURCE')
|
||||||
@ -2008,16 +2009,33 @@ dbus_programs = []
|
|||||||
# A list of boot stubs. Required for testing of ukify.
|
# A list of boot stubs. Required for testing of ukify.
|
||||||
boot_stubs = []
|
boot_stubs = []
|
||||||
|
|
||||||
|
# This is similar to system_includes below, but for passing custom_target().
|
||||||
|
system_include_args = [
|
||||||
|
'-isystem', meson.project_build_root() / 'src/include/override',
|
||||||
|
'-isystem', meson.project_source_root() / 'src/include/override',
|
||||||
|
'-isystem', meson.project_build_root() / 'src/include/uapi',
|
||||||
|
'-isystem', meson.project_source_root() / 'src/include/uapi',
|
||||||
|
]
|
||||||
|
|
||||||
|
system_includes = [
|
||||||
|
include_directories(
|
||||||
|
# gcc(1) says
|
||||||
|
# "Directories specified with -isystem options are scanned in left-to-right order",
|
||||||
|
# and meson puts the directories in the reversed order. Hence, a directory with a lower
|
||||||
|
# priority must be listed earlier.
|
||||||
|
'src/include/uapi',
|
||||||
|
'src/include/override',
|
||||||
|
is_system : true,
|
||||||
|
),
|
||||||
|
]
|
||||||
|
|
||||||
basic_includes = [
|
basic_includes = [
|
||||||
include_directories(
|
include_directories(
|
||||||
'src/basic',
|
'src/basic',
|
||||||
'src/fundamental',
|
'src/fundamental',
|
||||||
'src/systemd',
|
'src/systemd',
|
||||||
),
|
),
|
||||||
include_directories(
|
system_includes,
|
||||||
'src/basic/include',
|
|
||||||
is_system : true,
|
|
||||||
),
|
|
||||||
version_include,
|
version_include,
|
||||||
]
|
]
|
||||||
|
|
||||||
@ -2039,6 +2057,8 @@ includes = [libsystemd_includes, include_directories('src/shared')]
|
|||||||
|
|
||||||
subdir('po')
|
subdir('po')
|
||||||
subdir('catalog')
|
subdir('catalog')
|
||||||
|
subdir('src/include')
|
||||||
|
subdir('src/libc')
|
||||||
subdir('src/fundamental')
|
subdir('src/fundamental')
|
||||||
subdir('src/basic')
|
subdir('src/basic')
|
||||||
subdir('src/libsystemd')
|
subdir('src/libsystemd')
|
||||||
@ -2054,7 +2074,8 @@ libsystemd = shared_library(
|
|||||||
# Make sure our library is never deleted from memory, so that our open logging fds don't leak on dlopen/dlclose cycles.
|
# Make sure our library is never deleted from memory, so that our open logging fds don't leak on dlopen/dlclose cycles.
|
||||||
'-z', 'nodelete',
|
'-z', 'nodelete',
|
||||||
'-Wl,--version-script=' + libsystemd_sym_path],
|
'-Wl,--version-script=' + libsystemd_sym_path],
|
||||||
link_with : [libbasic_static],
|
link_with : [libc_wrapper_static,
|
||||||
|
libbasic_static],
|
||||||
link_whole : [libsystemd_static],
|
link_whole : [libsystemd_static],
|
||||||
dependencies : [librt,
|
dependencies : [librt,
|
||||||
threads,
|
threads,
|
||||||
@ -2067,6 +2088,7 @@ libsystemd = shared_library(
|
|||||||
if static_libsystemd != 'false'
|
if static_libsystemd != 'false'
|
||||||
install_libsystemd_static = static_library(
|
install_libsystemd_static = static_library(
|
||||||
'systemd',
|
'systemd',
|
||||||
|
libc_wrapper_sources,
|
||||||
libsystemd_sources,
|
libsystemd_sources,
|
||||||
basic_sources,
|
basic_sources,
|
||||||
fundamental_sources,
|
fundamental_sources,
|
||||||
@ -2112,6 +2134,7 @@ libudev = shared_library(
|
|||||||
if static_libudev != 'false'
|
if static_libudev != 'false'
|
||||||
install_libudev_static = static_library(
|
install_libudev_static = static_library(
|
||||||
'udev',
|
'udev',
|
||||||
|
libc_wrapper_sources,
|
||||||
basic_sources,
|
basic_sources,
|
||||||
fundamental_sources,
|
fundamental_sources,
|
||||||
shared_sources,
|
shared_sources,
|
||||||
@ -2216,6 +2239,7 @@ nss_template = {
|
|||||||
# Note that we link NSS modules with '-z nodelete' so that mempools never get orphaned
|
# Note that we link NSS modules with '-z nodelete' so that mempools never get orphaned
|
||||||
'link_args' : ['-z', 'nodelete'],
|
'link_args' : ['-z', 'nodelete'],
|
||||||
'link_with' : [
|
'link_with' : [
|
||||||
|
libc_wrapper_static,
|
||||||
libsystemd_static,
|
libsystemd_static,
|
||||||
libshared_static,
|
libshared_static,
|
||||||
libbasic_static,
|
libbasic_static,
|
||||||
|
@ -9,7 +9,7 @@ else
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
exec "${SPAWN[@]}" \
|
exec "${SPAWN[@]}" \
|
||||||
mkosi sandbox -- \
|
mkosi box -- \
|
||||||
clangd \
|
clangd \
|
||||||
--compile-commands-dir=build \
|
--compile-commands-dir=build \
|
||||||
--path-mappings="\
|
--path-mappings="\
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
# SPDX-License-Identifier: LGPL-2.1-or-later
|
# SPDX-License-Identifier: LGPL-2.1-or-later
|
||||||
|
|
||||||
[Config]
|
[Config]
|
||||||
MinimumVersion=commit:0d1143150835b21c1bfe64428df5f45b558280b1
|
MinimumVersion=commit:184472f0f1f831ca29953546ec01fd941ff763a6
|
||||||
Dependencies=
|
Dependencies=
|
||||||
exitrd
|
exitrd
|
||||||
initrd
|
initrd
|
||||||
|
@ -1,8 +1,5 @@
|
|||||||
# SPDX-License-Identifier: LGPL-2.1-or-later
|
# SPDX-License-Identifier: LGPL-2.1-or-later
|
||||||
|
|
||||||
[Match]
|
|
||||||
Distribution=arch
|
|
||||||
|
|
||||||
[Build]
|
[Build]
|
||||||
Environment=
|
Environment=
|
||||||
GIT_URL=https://gitlab.archlinux.org/archlinux/packaging/packages/systemd.git
|
GIT_URL=https://gitlab.archlinux.org/archlinux/packaging/packages/systemd.git
|
||||||
|
@ -27,6 +27,8 @@ Packages=
|
|||||||
cryptsetup
|
cryptsetup
|
||||||
device-mapper-event
|
device-mapper-event
|
||||||
device-mapper-multipath
|
device-mapper-multipath
|
||||||
|
dfuzzer
|
||||||
|
erofs-utils
|
||||||
git-core
|
git-core
|
||||||
glibc-langpack-de
|
glibc-langpack-de
|
||||||
glibc-langpack-en
|
glibc-langpack-en
|
||||||
@ -38,6 +40,7 @@ Packages=
|
|||||||
iputils
|
iputils
|
||||||
iscsi-initiator-utils
|
iscsi-initiator-utils
|
||||||
kernel-core
|
kernel-core
|
||||||
|
knot
|
||||||
libcap-ng-utils
|
libcap-ng-utils
|
||||||
man-db
|
man-db
|
||||||
nmap-ncat
|
nmap-ncat
|
||||||
@ -52,6 +55,7 @@ Packages=
|
|||||||
python3-pexpect
|
python3-pexpect
|
||||||
# needed to upgrade and downgrade systemd-ukify in tests
|
# needed to upgrade and downgrade systemd-ukify in tests
|
||||||
python3-zstd
|
python3-zstd
|
||||||
|
qrencode
|
||||||
quota
|
quota
|
||||||
rpm
|
rpm
|
||||||
softhsm
|
softhsm
|
||||||
|
11
mkosi/mkosi.conf.d/centos-fedora/mkosi.conf.d/efi.conf
Normal file
11
mkosi/mkosi.conf.d/centos-fedora/mkosi.conf.d/efi.conf
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
# SPDX-License-Identifier: LGPL-2.1-or-later
|
||||||
|
|
||||||
|
[Match]
|
||||||
|
Architecture=uefi
|
||||||
|
|
||||||
|
[Content]
|
||||||
|
Packages=
|
||||||
|
sbsigntools
|
||||||
|
|
||||||
|
VolatilePackages=
|
||||||
|
systemd-boot
|
@ -1,9 +1,5 @@
|
|||||||
# SPDX-License-Identifier: LGPL-2.1-or-later
|
# SPDX-License-Identifier: LGPL-2.1-or-later
|
||||||
|
|
||||||
[Match]
|
|
||||||
Distribution=|centos
|
|
||||||
Distribution=|fedora
|
|
||||||
|
|
||||||
[Build]
|
[Build]
|
||||||
Environment=
|
Environment=
|
||||||
GIT_URL=https://src.fedoraproject.org/rpms/systemd.git
|
GIT_URL=https://src.fedoraproject.org/rpms/systemd.git
|
||||||
|
@ -5,6 +5,7 @@ Distribution=centos
|
|||||||
|
|
||||||
[Distribution]
|
[Distribution]
|
||||||
Release=10
|
Release=10
|
||||||
|
Repositories=epel,epel-next
|
||||||
|
|
||||||
[Build]
|
[Build]
|
||||||
Environment=
|
Environment=
|
||||||
|
@ -1,9 +0,0 @@
|
|||||||
# SPDX-License-Identifier: LGPL-2.1-or-later
|
|
||||||
|
|
||||||
[Match]
|
|
||||||
Release=9
|
|
||||||
|
|
||||||
[Distribution]
|
|
||||||
Repositories=
|
|
||||||
epel
|
|
||||||
epel-next
|
|
@ -1,18 +0,0 @@
|
|||||||
# SPDX-License-Identifier: LGPL-2.1-or-later
|
|
||||||
|
|
||||||
[Match]
|
|
||||||
Repositories=epel
|
|
||||||
Architecture=|x86
|
|
||||||
Architecture=|x86-64
|
|
||||||
Architecture=|arm
|
|
||||||
Architecture=|arm64
|
|
||||||
Architecture=|riscv32
|
|
||||||
Architecture=|riscv64
|
|
||||||
Architecture=|loongarch64
|
|
||||||
|
|
||||||
[Content]
|
|
||||||
Packages=
|
|
||||||
sbsigntools
|
|
||||||
|
|
||||||
VolatilePackages=
|
|
||||||
systemd-boot
|
|
@ -1,12 +0,0 @@
|
|||||||
# SPDX-License-Identifier: LGPL-2.1-or-later
|
|
||||||
|
|
||||||
[Match]
|
|
||||||
Repositories=epel
|
|
||||||
|
|
||||||
[Content]
|
|
||||||
Packages=
|
|
||||||
dfuzzer
|
|
||||||
dhcp-server
|
|
||||||
erofs-utils
|
|
||||||
knot
|
|
||||||
qrencode
|
|
@ -4,13 +4,7 @@
|
|||||||
Environment=WITH_DEBUG=1
|
Environment=WITH_DEBUG=1
|
||||||
|
|
||||||
[Match]
|
[Match]
|
||||||
Architecture=|x86
|
Architecture=uefi
|
||||||
Architecture=|x86-64
|
|
||||||
Architecture=|arm
|
|
||||||
Architecture=|arm64
|
|
||||||
Architecture=|riscv32
|
|
||||||
Architecture=|riscv64
|
|
||||||
Architecture=|loongarch64
|
|
||||||
|
|
||||||
[Content]
|
[Content]
|
||||||
VolatilePackages=
|
VolatilePackages=
|
||||||
|
@ -2,13 +2,7 @@
|
|||||||
# sbsigntool exists only on UEFI architectures
|
# sbsigntool exists only on UEFI architectures
|
||||||
|
|
||||||
[Match]
|
[Match]
|
||||||
Architecture=|x86
|
Architecture=uefi
|
||||||
Architecture=|x86-64
|
|
||||||
Architecture=|arm
|
|
||||||
Architecture=|arm64
|
|
||||||
Architecture=|riscv32
|
|
||||||
Architecture=|riscv64
|
|
||||||
Architecture=|loongarch64
|
|
||||||
|
|
||||||
[Content]
|
[Content]
|
||||||
Packages=
|
Packages=
|
||||||
|
@ -1,9 +1,5 @@
|
|||||||
# SPDX-License-Identifier: LGPL-2.1-or-later
|
# SPDX-License-Identifier: LGPL-2.1-or-later
|
||||||
|
|
||||||
[Match]
|
|
||||||
Distribution=|debian
|
|
||||||
Distribution=|ubuntu
|
|
||||||
|
|
||||||
[Build]
|
[Build]
|
||||||
Environment=
|
Environment=
|
||||||
GIT_URL=https://salsa.debian.org/systemd-team/systemd.git
|
GIT_URL=https://salsa.debian.org/systemd-team/systemd.git
|
||||||
|
@ -10,15 +10,11 @@ Release=rawhide
|
|||||||
Packages=
|
Packages=
|
||||||
btrfs-progs
|
btrfs-progs
|
||||||
compsize
|
compsize
|
||||||
dfuzzer
|
|
||||||
dhcp-server
|
dhcp-server
|
||||||
dnf5
|
dnf5
|
||||||
erofs-utils
|
|
||||||
f2fs-tools
|
f2fs-tools
|
||||||
# Required for systemd-networkd-tests.py (netdevsim and sch_xxx modules)
|
# Required for systemd-networkd-tests.py (netdevsim and sch_xxx modules)
|
||||||
kernel-modules-extra
|
kernel-modules-extra
|
||||||
kernel-modules-internal
|
kernel-modules-internal
|
||||||
knot
|
|
||||||
qrencode
|
|
||||||
rpmautospec
|
rpmautospec
|
||||||
scsi-target-utils
|
scsi-target-utils
|
||||||
|
@ -1,18 +0,0 @@
|
|||||||
# SPDX-License-Identifier: LGPL-2.1-or-later
|
|
||||||
|
|
||||||
[Match]
|
|
||||||
Distribution=fedora
|
|
||||||
Architecture=|x86
|
|
||||||
Architecture=|x86-64
|
|
||||||
Architecture=|arm
|
|
||||||
Architecture=|arm64
|
|
||||||
Architecture=|riscv32
|
|
||||||
Architecture=|riscv64
|
|
||||||
Architecture=|loongarch64
|
|
||||||
|
|
||||||
[Content]
|
|
||||||
Packages=
|
|
||||||
sbsigntools
|
|
||||||
|
|
||||||
VolatilePackages=
|
|
||||||
systemd-boot
|
|
@ -4,13 +4,7 @@
|
|||||||
Environment=WITH_DEBUG=1
|
Environment=WITH_DEBUG=1
|
||||||
|
|
||||||
[Match]
|
[Match]
|
||||||
Architecture=|x86
|
Architecture=uefi
|
||||||
Architecture=|x86-64
|
|
||||||
Architecture=|arm
|
|
||||||
Architecture=|arm64
|
|
||||||
Architecture=|riscv32
|
|
||||||
Architecture=|riscv64
|
|
||||||
Architecture=|loongarch64
|
|
||||||
|
|
||||||
[Content]
|
[Content]
|
||||||
VolatilePackages=
|
VolatilePackages=
|
||||||
|
@ -1,14 +1,7 @@
|
|||||||
# SPDX-License-Identifier: LGPL-2.1-or-later
|
# SPDX-License-Identifier: LGPL-2.1-or-later
|
||||||
|
|
||||||
[Match]
|
[Match]
|
||||||
Distribution=opensuse
|
Architecture=uefi
|
||||||
Architecture=|x86
|
|
||||||
Architecture=|x86-64
|
|
||||||
Architecture=|arm
|
|
||||||
Architecture=|arm64
|
|
||||||
Architecture=|riscv32
|
|
||||||
Architecture=|riscv64
|
|
||||||
Architecture=|loongarch64
|
|
||||||
|
|
||||||
[Content]
|
[Content]
|
||||||
VolatilePackages=
|
VolatilePackages=
|
||||||
|
@ -1,8 +1,5 @@
|
|||||||
# SPDX-License-Identifier: LGPL-2.1-or-later
|
# SPDX-License-Identifier: LGPL-2.1-or-later
|
||||||
|
|
||||||
[Match]
|
|
||||||
Distribution=opensuse
|
|
||||||
|
|
||||||
[Build]
|
[Build]
|
||||||
Environment=
|
Environment=
|
||||||
GIT_URL=https://github.com/bmwiedemann/openSUSE
|
GIT_URL=https://github.com/bmwiedemann/openSUSE
|
||||||
|
@ -1,5 +1,7 @@
|
|||||||
/* SPDX-License-Identifier: LGPL-2.1-or-later */
|
/* SPDX-License-Identifier: LGPL-2.1-or-later */
|
||||||
|
|
||||||
|
#include <linux/fs.h>
|
||||||
|
#include <linux/magic.h>
|
||||||
#include <signal.h>
|
#include <signal.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <sys/xattr.h>
|
#include <sys/xattr.h>
|
||||||
@ -18,8 +20,6 @@
|
|||||||
#include "fs-util.h"
|
#include "fs-util.h"
|
||||||
#include "log.h"
|
#include "log.h"
|
||||||
#include "login-util.h"
|
#include "login-util.h"
|
||||||
#include "missing_fs.h"
|
|
||||||
#include "missing_magic.h"
|
|
||||||
#include "parse-util.h"
|
#include "parse-util.h"
|
||||||
#include "path-util.h"
|
#include "path-util.h"
|
||||||
#include "pidref.h"
|
#include "pidref.h"
|
||||||
|
@ -126,10 +126,6 @@ int chaseat(int dir_fd, const char *path, ChaseFlags flags, char **ret_path, int
|
|||||||
assert(!FLAGS_SET(flags, CHASE_STEP|CHASE_EXTRACT_FILENAME));
|
assert(!FLAGS_SET(flags, CHASE_STEP|CHASE_EXTRACT_FILENAME));
|
||||||
assert(dir_fd >= 0 || dir_fd == AT_FDCWD);
|
assert(dir_fd >= 0 || dir_fd == AT_FDCWD);
|
||||||
|
|
||||||
/* Either the file may be missing, or we return an fd to the final object, but both make no sense */
|
|
||||||
if (FLAGS_SET(flags, CHASE_NONEXISTENT))
|
|
||||||
assert(!ret_fd);
|
|
||||||
|
|
||||||
if (FLAGS_SET(flags, CHASE_STEP))
|
if (FLAGS_SET(flags, CHASE_STEP))
|
||||||
assert(!ret_fd);
|
assert(!ret_fd);
|
||||||
|
|
||||||
@ -552,11 +548,13 @@ int chaseat(int dir_fd, const char *path, ChaseFlags flags, char **ret_path, int
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (ret_fd) {
|
if (ret_fd) {
|
||||||
/* Return the O_PATH fd we currently are looking to the caller. It can translate it to a
|
if (exists) {
|
||||||
* proper fd by opening /proc/self/fd/xyz. */
|
/* Return the O_PATH fd we currently are looking to the caller. It can translate it
|
||||||
|
* to a proper fd by opening /proc/self/fd/xyz. */
|
||||||
assert(fd >= 0);
|
assert(fd >= 0);
|
||||||
*ret_fd = TAKE_FD(fd);
|
*ret_fd = TAKE_FD(fd);
|
||||||
|
} else
|
||||||
|
*ret_fd = -EBADF;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (FLAGS_SET(flags, CHASE_STEP))
|
if (FLAGS_SET(flags, CHASE_STEP))
|
||||||
|
@ -3,19 +3,14 @@
|
|||||||
set -eu
|
set -eu
|
||||||
set -o pipefail
|
set -o pipefail
|
||||||
|
|
||||||
cpp="$1"
|
cpp="${1:?}"
|
||||||
filesystems_gperf="$2"
|
filesystems_gperf="${2:?}"
|
||||||
shift 2
|
shift 2
|
||||||
|
|
||||||
includes=""
|
|
||||||
for i in "$@"; do
|
|
||||||
includes="$includes -include $i"
|
|
||||||
done
|
|
||||||
|
|
||||||
error=false
|
error=false
|
||||||
|
|
||||||
# shellcheck disable=SC2086
|
# shellcheck disable=SC2086
|
||||||
for fs in $($cpp -dM $includes - </dev/null | \
|
for fs in $($cpp -dM -include linux/magic.h "$@" - </dev/null | \
|
||||||
grep -E '_MAGIC' | \
|
grep -E '_MAGIC' | \
|
||||||
grep -vE 'LINUX_MAGIC' | \
|
grep -vE 'LINUX_MAGIC' | \
|
||||||
awk '/^#define[ \t]+[A-Z0-9_]+MAGIC[ \t]+/ { print $2; }'); do
|
awk '/^#define[ \t]+[A-Z0-9_]+MAGIC[ \t]+/ { print $2; }'); do
|
||||||
|
@ -20,316 +20,24 @@
|
|||||||
#include "string-util.h"
|
#include "string-util.h"
|
||||||
#include "strv.h"
|
#include "strv.h"
|
||||||
|
|
||||||
static int files_add(
|
ConfFile* conf_file_free(ConfFile *c) {
|
||||||
DIR *dir,
|
if (!c)
|
||||||
const char *dirpath,
|
return NULL;
|
||||||
int rfd,
|
|
||||||
const char *root, /* for logging, can be NULL */
|
|
||||||
Hashmap **files,
|
|
||||||
Set **masked,
|
|
||||||
const char *suffix,
|
|
||||||
ConfFilesFlags flags) {
|
|
||||||
|
|
||||||
int r;
|
free(c->name);
|
||||||
|
free(c->result);
|
||||||
|
free(c->original_path);
|
||||||
|
free(c->resolved_path);
|
||||||
|
safe_close(c->fd);
|
||||||
|
|
||||||
assert(dir);
|
return mfree(c);
|
||||||
assert(dirpath);
|
|
||||||
assert(rfd >= 0 || rfd == AT_FDCWD);
|
|
||||||
assert(files);
|
|
||||||
assert(masked);
|
|
||||||
|
|
||||||
root = strempty(root);
|
|
||||||
|
|
||||||
FOREACH_DIRENT(de, dir, return log_debug_errno(errno, "Failed to read directory '%s/%s': %m",
|
|
||||||
root, skip_leading_slash(dirpath))) {
|
|
||||||
|
|
||||||
/* Does this match the suffix? */
|
|
||||||
if (suffix && !endswith(de->d_name, suffix))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
/* Has this file already been found in an earlier directory? */
|
|
||||||
if (hashmap_contains(*files, de->d_name)) {
|
|
||||||
log_debug("Skipping overridden file '%s/%s/%s'.",
|
|
||||||
root, skip_leading_slash(dirpath), de->d_name);
|
|
||||||
continue;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Has this been masked in an earlier directory? */
|
void conf_file_free_many(ConfFile **array, size_t n) {
|
||||||
if ((flags & CONF_FILES_FILTER_MASKED) != 0 && set_contains(*masked, de->d_name)) {
|
FOREACH_ARRAY(i, array, n)
|
||||||
log_debug("File '%s/%s/%s' is masked by previous entry.",
|
conf_file_free(*i);
|
||||||
root, skip_leading_slash(dirpath), de->d_name);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
_cleanup_free_ char *p = path_join(dirpath, de->d_name);
|
free(array);
|
||||||
if (!p)
|
|
||||||
return log_oom_debug();
|
|
||||||
|
|
||||||
_cleanup_free_ char *resolved_path = NULL;
|
|
||||||
bool need_stat = (flags & (CONF_FILES_FILTER_MASKED | CONF_FILES_REGULAR | CONF_FILES_DIRECTORY | CONF_FILES_EXECUTABLE)) != 0;
|
|
||||||
struct stat st;
|
|
||||||
|
|
||||||
if (!need_stat || FLAGS_SET(flags, CONF_FILES_FILTER_MASKED_BY_SYMLINK)) {
|
|
||||||
|
|
||||||
/* Even if no verification is requested, let's unconditionally call chaseat(),
|
|
||||||
* to drop unsafe symlinks. */
|
|
||||||
|
|
||||||
r = chaseat(rfd, p, CHASE_AT_RESOLVE_IN_ROOT | CHASE_NONEXISTENT, &resolved_path, /* ret_fd = */ NULL);
|
|
||||||
if (r < 0) {
|
|
||||||
log_debug_errno(r, "Failed to chase '%s/%s', ignoring: %m",
|
|
||||||
root, skip_leading_slash(p));
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (r == 0 && FLAGS_SET(flags, CONF_FILES_FILTER_MASKED_BY_SYMLINK)) {
|
|
||||||
|
|
||||||
/* If the path points to /dev/null in a image or so, then the device node may not exist. */
|
|
||||||
if (path_equal(skip_leading_slash(resolved_path), "dev/null")) {
|
|
||||||
/* Mark this one as masked */
|
|
||||||
r = set_put_strdup(masked, de->d_name);
|
|
||||||
if (r < 0)
|
|
||||||
return log_oom_debug();
|
|
||||||
|
|
||||||
log_debug("File '%s/%s' is a mask (symlink to /dev/null).",
|
|
||||||
root, skip_leading_slash(p));
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* If the flag is set, we need to have stat, hence, skip the entry. */
|
|
||||||
log_debug_errno(SYNTHETIC_ERRNO(ENOENT), "Failed to chase '%s/%s', ignoring: %m",
|
|
||||||
root, skip_leading_slash(p));
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (need_stat && fstatat(rfd, resolved_path, &st, AT_SYMLINK_NOFOLLOW) < 0) {
|
|
||||||
log_debug_errno(errno, "Failed to stat '%s/%s', ignoring: %m",
|
|
||||||
root, skip_leading_slash(p));
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
} else {
|
|
||||||
r = chase_and_statat(rfd, p, CHASE_AT_RESOLVE_IN_ROOT, &resolved_path, &st);
|
|
||||||
if (r < 0) {
|
|
||||||
log_debug_errno(r, "Failed to chase and stat '%s/%s', ignoring: %m",
|
|
||||||
root, skip_leading_slash(p));
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Is this a masking entry? */
|
|
||||||
if (FLAGS_SET(flags, CONF_FILES_FILTER_MASKED_BY_SYMLINK) && stat_may_be_dev_null(&st)) {
|
|
||||||
/* Mark this one as masked */
|
|
||||||
r = set_put_strdup(masked, de->d_name);
|
|
||||||
if (r < 0)
|
|
||||||
return log_oom_debug();
|
|
||||||
|
|
||||||
log_debug("File '%s/%s' is a mask (symlink to /dev/null).", root, skip_leading_slash(p));
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (FLAGS_SET(flags, CONF_FILES_FILTER_MASKED_BY_EMPTY) && stat_is_empty(&st)) {
|
|
||||||
/* Mark this one as masked */
|
|
||||||
r = set_put_strdup(masked, de->d_name);
|
|
||||||
if (r < 0)
|
|
||||||
return log_oom_debug();
|
|
||||||
|
|
||||||
log_debug("File '%s/%s' is a mask (an empty file).", root, skip_leading_slash(p));
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (FLAGS_SET(flags, CONF_FILES_REGULAR|CONF_FILES_DIRECTORY)) {
|
|
||||||
if (!S_ISREG(st.st_mode) && !S_ISDIR(st.st_mode)) {
|
|
||||||
log_debug("Ignoring '%s/%s', as it is neither a regular file or directory.", root, skip_leading_slash(p));
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
/* Is this node a regular file? */
|
|
||||||
if (FLAGS_SET(flags, CONF_FILES_REGULAR) && !S_ISREG(st.st_mode)) {
|
|
||||||
log_debug("Ignoring '%s/%s', as it is not a regular file.", root, skip_leading_slash(p));
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Is this node a directory? */
|
|
||||||
if (FLAGS_SET(flags, CONF_FILES_DIRECTORY) && !S_ISDIR(st.st_mode)) {
|
|
||||||
log_debug("Ignoring '%s/%s', as it is not a directory.", root, skip_leading_slash(p));
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Does this node have the executable bit set?
|
|
||||||
* As requested: check if the file is marked executable. Note that we don't check access(X_OK)
|
|
||||||
* here, as we care about whether the file is marked executable at all, and not whether it is
|
|
||||||
* executable for us, because if so, such errors are stuff we should log about. */
|
|
||||||
if (FLAGS_SET(flags, CONF_FILES_EXECUTABLE) && (st.st_mode & 0111) == 0) {
|
|
||||||
log_debug("Ignoring '%s/%s', as it is not marked executable.", root, skip_leading_slash(p));
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
_cleanup_free_ char *n = strdup(de->d_name);
|
|
||||||
if (!n)
|
|
||||||
return log_oom_debug();
|
|
||||||
|
|
||||||
r = hashmap_ensure_put(files, &string_hash_ops_free_free, n, p);
|
|
||||||
if (r < 0) {
|
|
||||||
assert(r == -ENOMEM);
|
|
||||||
return log_oom_debug();
|
|
||||||
}
|
|
||||||
assert(r > 0);
|
|
||||||
|
|
||||||
TAKE_PTR(n);
|
|
||||||
TAKE_PTR(p);
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int copy_and_sort_files_from_hashmap(Hashmap *fh, const char *root, ConfFilesFlags flags, char ***ret) {
|
|
||||||
_cleanup_free_ char **sv = NULL;
|
|
||||||
_cleanup_strv_free_ char **files = NULL;
|
|
||||||
size_t n = 0;
|
|
||||||
int r;
|
|
||||||
|
|
||||||
assert(ret);
|
|
||||||
|
|
||||||
r = hashmap_dump_sorted(fh, (void***) &sv, /* ret_n = */ NULL);
|
|
||||||
if (r < 0)
|
|
||||||
return log_oom_debug();
|
|
||||||
|
|
||||||
/* The entries in the array given by hashmap_dump_sorted() are still owned by the hashmap. */
|
|
||||||
STRV_FOREACH(s, sv) {
|
|
||||||
_cleanup_free_ char *p = NULL;
|
|
||||||
|
|
||||||
if (FLAGS_SET(flags, CONF_FILES_BASENAME)) {
|
|
||||||
r = path_extract_filename(*s, &p);
|
|
||||||
if (r < 0)
|
|
||||||
return log_debug_errno(r, "Failed to extract filename from '%s': %m", *s);
|
|
||||||
} else if (root) {
|
|
||||||
r = chaseat_prefix_root(*s, root, &p);
|
|
||||||
if (r < 0)
|
|
||||||
return log_debug_errno(r, "Failed to prefix '%s' with root '%s': %m", *s, root);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (p)
|
|
||||||
r = strv_consume_with_size(&files, &n, TAKE_PTR(p));
|
|
||||||
else
|
|
||||||
r = strv_extend_with_size(&files, &n, *s);
|
|
||||||
if (r < 0)
|
|
||||||
return log_oom_debug();
|
|
||||||
}
|
|
||||||
|
|
||||||
*ret = TAKE_PTR(files);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int insert_replacement(Hashmap **fh, char *filename_replacement, char *resolved_replacement, char **ret) {
|
|
||||||
_cleanup_free_ char *fname = ASSERT_PTR(filename_replacement), *path = ASSERT_PTR(resolved_replacement);
|
|
||||||
int r;
|
|
||||||
|
|
||||||
assert(fh);
|
|
||||||
|
|
||||||
/* This consumes the input filename and path. */
|
|
||||||
|
|
||||||
const char *existing = hashmap_get(*fh, fname);
|
|
||||||
if (existing) {
|
|
||||||
log_debug("An entry with higher priority already exists ('%s' -> '%s'), ignoring the replacement: %s",
|
|
||||||
fname, existing, path);
|
|
||||||
if (ret)
|
|
||||||
*ret = NULL;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
_cleanup_free_ char *copy = NULL;
|
|
||||||
if (ret) {
|
|
||||||
copy = strdup(path);
|
|
||||||
if (!copy)
|
|
||||||
return log_oom_debug();
|
|
||||||
}
|
|
||||||
|
|
||||||
r = hashmap_ensure_put(fh, &string_hash_ops_free_free, fname, path);
|
|
||||||
if (r < 0) {
|
|
||||||
assert(r == -ENOMEM);
|
|
||||||
return log_oom_debug();
|
|
||||||
}
|
|
||||||
assert(r > 0);
|
|
||||||
|
|
||||||
log_debug("Inserted replacement: '%s' -> '%s'", fname, path);
|
|
||||||
|
|
||||||
TAKE_PTR(fname);
|
|
||||||
TAKE_PTR(path);
|
|
||||||
|
|
||||||
if (ret)
|
|
||||||
*ret = TAKE_PTR(copy);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int conf_files_list_impl(
|
|
||||||
const char *suffix,
|
|
||||||
int rfd,
|
|
||||||
const char *root, /* for logging, can be NULL */
|
|
||||||
ConfFilesFlags flags,
|
|
||||||
const char * const *dirs,
|
|
||||||
const char *replacement,
|
|
||||||
Hashmap **ret,
|
|
||||||
char **ret_inserted) {
|
|
||||||
|
|
||||||
_cleanup_hashmap_free_ Hashmap *fh = NULL;
|
|
||||||
_cleanup_set_free_ Set *masked = NULL;
|
|
||||||
int r;
|
|
||||||
|
|
||||||
assert(rfd >= 0 || rfd == AT_FDCWD);
|
|
||||||
assert(ret);
|
|
||||||
|
|
||||||
_cleanup_free_ char *filename_replacement = NULL, *resolved_dirpath_replacement = NULL, *resolved_replacement = NULL, *inserted = NULL;
|
|
||||||
if (replacement) {
|
|
||||||
r = path_extract_filename(replacement, &filename_replacement);
|
|
||||||
if (r < 0)
|
|
||||||
return r;
|
|
||||||
|
|
||||||
_cleanup_free_ char *d = NULL;
|
|
||||||
r = path_extract_directory(replacement, &d);
|
|
||||||
if (r < 0)
|
|
||||||
return r;
|
|
||||||
|
|
||||||
r = chaseat(rfd, d, CHASE_AT_RESOLVE_IN_ROOT | CHASE_NONEXISTENT, &resolved_dirpath_replacement, /* ret_fd = */ NULL);
|
|
||||||
if (r < 0)
|
|
||||||
return r;
|
|
||||||
|
|
||||||
resolved_replacement = path_join(resolved_dirpath_replacement, filename_replacement);
|
|
||||||
if (!resolved_replacement)
|
|
||||||
return log_oom_debug();
|
|
||||||
}
|
|
||||||
|
|
||||||
STRV_FOREACH(p, dirs) {
|
|
||||||
_cleanup_closedir_ DIR *dir = NULL;
|
|
||||||
_cleanup_free_ char *path = NULL;
|
|
||||||
|
|
||||||
r = chase_and_opendirat(rfd, *p, CHASE_AT_RESOLVE_IN_ROOT, &path, &dir);
|
|
||||||
if (r < 0) {
|
|
||||||
if (r != -ENOENT)
|
|
||||||
log_debug_errno(r, "Failed to chase and open directory '%s%s', ignoring: %m", strempty(root), *p);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (resolved_replacement && path_equal(resolved_dirpath_replacement, path)) {
|
|
||||||
r = insert_replacement(&fh, TAKE_PTR(filename_replacement), TAKE_PTR(resolved_replacement), ret_inserted ? &inserted : NULL);
|
|
||||||
if (r < 0)
|
|
||||||
return r;
|
|
||||||
}
|
|
||||||
|
|
||||||
r = files_add(dir, path, rfd, root, &fh, &masked, suffix, flags);
|
|
||||||
if (r == -ENOMEM)
|
|
||||||
return r;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (resolved_replacement) {
|
|
||||||
r = insert_replacement(&fh, TAKE_PTR(filename_replacement), TAKE_PTR(resolved_replacement), ret_inserted ? &inserted : NULL);
|
|
||||||
if (r < 0)
|
|
||||||
return r;
|
|
||||||
}
|
|
||||||
|
|
||||||
*ret = TAKE_PTR(fh);
|
|
||||||
if (ret_inserted)
|
|
||||||
*ret_inserted = TAKE_PTR(inserted);
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int prepare_dirs(const char *root, char * const *dirs, int *ret_rfd, char **ret_root, char ***ret_dirs) {
|
static int prepare_dirs(const char *root, char * const *dirs, int *ret_rfd, char **ret_root, char ***ret_dirs) {
|
||||||
@ -339,25 +47,27 @@ static int prepare_dirs(const char *root, char * const *dirs, int *ret_rfd, char
|
|||||||
|
|
||||||
assert(ret_rfd);
|
assert(ret_rfd);
|
||||||
assert(ret_root);
|
assert(ret_root);
|
||||||
assert(ret_dirs);
|
assert(ret_dirs || strv_isempty(dirs));
|
||||||
|
|
||||||
r = empty_or_root_harder_to_null(&root);
|
r = empty_or_root_harder_to_null(&root);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return log_debug_errno(r, "Failed to determine if '%s' points to the root directory: %m", strempty(root));
|
return log_debug_errno(r, "Failed to determine if '%s' points to the root directory: %m", strempty(root));
|
||||||
|
|
||||||
|
if (ret_dirs) {
|
||||||
dirs_abs = strv_copy(dirs);
|
dirs_abs = strv_copy(dirs);
|
||||||
if (!dirs_abs)
|
if (!dirs_abs)
|
||||||
return log_oom();
|
return log_oom();
|
||||||
|
}
|
||||||
|
|
||||||
if (root) {
|
if (root) {
|
||||||
/* WHen a non-trivial root is specified, we will prefix the result later. Hence, it is not
|
/* When a non-trivial root is specified, we will prefix the result later. Hence, it is not
|
||||||
* necessary to modify each config directories here. but needs to normalize the root directory. */
|
* necessary to modify each config directories here. but needs to normalize the root directory. */
|
||||||
r = path_make_absolute_cwd(root, &root_abs);
|
r = path_make_absolute_cwd(root, &root_abs);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return log_debug_errno(r, "Failed to make '%s' absolute: %m", root);
|
return log_debug_errno(r, "Failed to make '%s' absolute: %m", root);
|
||||||
|
|
||||||
path_simplify(root_abs);
|
path_simplify(root_abs);
|
||||||
} else {
|
} else if (ret_dirs) {
|
||||||
/* When an empty root or "/" is specified, we will open "/" below, hence we need to make
|
/* When an empty root or "/" is specified, we will open "/" below, hence we need to make
|
||||||
* each config directory absolute if relative. */
|
* each config directory absolute if relative. */
|
||||||
r = path_strv_make_absolute_cwd(dirs_abs);
|
r = path_strv_make_absolute_cwd(dirs_abs);
|
||||||
@ -371,10 +81,465 @@ static int prepare_dirs(const char *root, char * const *dirs, int *ret_rfd, char
|
|||||||
|
|
||||||
*ret_rfd = TAKE_FD(rfd);
|
*ret_rfd = TAKE_FD(rfd);
|
||||||
*ret_root = TAKE_PTR(root_abs);
|
*ret_root = TAKE_PTR(root_abs);
|
||||||
|
if (ret_dirs)
|
||||||
*ret_dirs = TAKE_PTR(dirs_abs);
|
*ret_dirs = TAKE_PTR(dirs_abs);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int conf_file_prefix_root(ConfFile *c, const char *root) {
|
||||||
|
char *p;
|
||||||
|
int r;
|
||||||
|
|
||||||
|
assert(c);
|
||||||
|
|
||||||
|
r = chaseat_prefix_root(c->result, root, &p);
|
||||||
|
if (r < 0)
|
||||||
|
return log_debug_errno(r, "Failed to prefix '%s' with root '%s': %m", c->result, root);
|
||||||
|
free_and_replace(c->result, p);
|
||||||
|
|
||||||
|
r = chaseat_prefix_root(c->resolved_path, root, &p);
|
||||||
|
if (r < 0)
|
||||||
|
return log_debug_errno(r, "Failed to prefix '%s' with root '%s': %m", c->resolved_path, root);
|
||||||
|
free_and_replace(c->resolved_path, p);
|
||||||
|
|
||||||
|
/* Do not use chaseat_prefix_root(), as it is for the result of chaseat(), but the path is not chased. */
|
||||||
|
p = path_join(empty_to_root(root), skip_leading_slash(c->original_path));
|
||||||
|
if (!p)
|
||||||
|
return log_oom_debug();
|
||||||
|
path_simplify(p);
|
||||||
|
free_and_replace(c->original_path, p);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int conf_file_new_at(const char *path, int rfd, ChaseFlags chase_flags, ConfFile **ret) {
|
||||||
|
int r;
|
||||||
|
|
||||||
|
assert(path);
|
||||||
|
assert(rfd >= 0 || rfd == AT_FDCWD);
|
||||||
|
assert(ret);
|
||||||
|
|
||||||
|
_cleanup_free_ char *root = NULL;
|
||||||
|
if (rfd >= 0 && DEBUG_LOGGING)
|
||||||
|
(void) fd_get_path(rfd, &root);
|
||||||
|
|
||||||
|
_cleanup_(conf_file_freep) ConfFile *c = new(ConfFile, 1);
|
||||||
|
if (!c)
|
||||||
|
return log_oom_debug();
|
||||||
|
|
||||||
|
*c = (ConfFile) {
|
||||||
|
.original_path = strdup(path),
|
||||||
|
.fd = -EBADF,
|
||||||
|
};
|
||||||
|
|
||||||
|
if (!c->original_path)
|
||||||
|
return log_oom_debug();
|
||||||
|
|
||||||
|
r = path_extract_filename(path, &c->name);
|
||||||
|
if (r < 0)
|
||||||
|
return log_debug_errno(r, "Failed to extract filename from '%s': %m", path);
|
||||||
|
|
||||||
|
_cleanup_free_ char *dirpath = NULL, *resolved_dirpath = NULL;
|
||||||
|
r = path_extract_directory(path, &dirpath);
|
||||||
|
if (r < 0 && r != -EDESTADDRREQ)
|
||||||
|
return log_debug_errno(r, "Failed to extract directory from '%s': %m", path);
|
||||||
|
if (r >= 0) {
|
||||||
|
r = chaseat(rfd, dirpath,
|
||||||
|
CHASE_AT_RESOLVE_IN_ROOT | (FLAGS_SET(chase_flags, CHASE_NONEXISTENT) ? CHASE_NONEXISTENT : CHASE_MUST_BE_DIRECTORY),
|
||||||
|
&resolved_dirpath, /* ret_fd = */ NULL);
|
||||||
|
if (r < 0)
|
||||||
|
return log_debug_errno(r, "Failed to chase '%s%s': %m", empty_to_root(root), skip_leading_slash(dirpath));
|
||||||
|
}
|
||||||
|
|
||||||
|
c->result = path_join(resolved_dirpath, c->name);
|
||||||
|
if (!c->result)
|
||||||
|
return log_oom_debug();
|
||||||
|
|
||||||
|
r = chaseat(rfd, c->result, CHASE_AT_RESOLVE_IN_ROOT | chase_flags, &c->resolved_path, &c->fd);
|
||||||
|
if (r < 0)
|
||||||
|
return log_debug_errno(r, "Failed to chase '%s%s': %m", empty_to_root(root), skip_leading_slash(c->original_path));
|
||||||
|
|
||||||
|
if (c->fd >= 0 && fstat(c->fd, &c->st) < 0)
|
||||||
|
return log_debug_errno(r, "Failed to stat '%s%s': %m", empty_to_root(root), skip_leading_slash(c->resolved_path));
|
||||||
|
|
||||||
|
*ret = TAKE_PTR(c);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int conf_file_new(const char *path, const char *root, ChaseFlags chase_flags, ConfFile **ret) {
|
||||||
|
int r;
|
||||||
|
|
||||||
|
assert(path);
|
||||||
|
assert((chase_flags & (CHASE_PREFIX_ROOT | CHASE_STEP)) == 0);
|
||||||
|
assert(ret);
|
||||||
|
|
||||||
|
_cleanup_free_ char *root_abs = NULL;
|
||||||
|
_cleanup_close_ int rfd = -EBADF;
|
||||||
|
r = prepare_dirs(root, /* dirs = */ NULL, &rfd, &root_abs, /* ret_dirs = */ NULL);
|
||||||
|
if (r < 0)
|
||||||
|
return r;
|
||||||
|
|
||||||
|
_cleanup_free_ char *path_abs = NULL;
|
||||||
|
if (!root_abs) {
|
||||||
|
r = path_make_absolute_cwd(path, &path_abs);
|
||||||
|
if (r < 0)
|
||||||
|
return log_debug_errno(r, "Failed to make '%s' absolute: %m", path);
|
||||||
|
|
||||||
|
path = path_abs;
|
||||||
|
}
|
||||||
|
|
||||||
|
_cleanup_(conf_file_freep) ConfFile *c = NULL;
|
||||||
|
r = conf_file_new_at(path, rfd, chase_flags, &c);
|
||||||
|
if (r < 0)
|
||||||
|
return r;
|
||||||
|
|
||||||
|
r = conf_file_prefix_root(c, root_abs);
|
||||||
|
if (r < 0)
|
||||||
|
return r;
|
||||||
|
|
||||||
|
*ret = TAKE_PTR(c);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
DEFINE_PRIVATE_HASH_OPS_WITH_VALUE_DESTRUCTOR(
|
||||||
|
conf_file_hash_ops,
|
||||||
|
char, string_hash_func, string_compare_func,
|
||||||
|
ConfFile, conf_file_free);
|
||||||
|
|
||||||
|
static int files_add(
|
||||||
|
DIR *dir,
|
||||||
|
const char *original_dirpath,
|
||||||
|
const char *resolved_dirpath,
|
||||||
|
int rfd,
|
||||||
|
const char *root, /* for logging, can be NULL */
|
||||||
|
Hashmap **files,
|
||||||
|
Set **masked,
|
||||||
|
const char *suffix,
|
||||||
|
ConfFilesFlags flags) {
|
||||||
|
|
||||||
|
int r;
|
||||||
|
|
||||||
|
assert(dir);
|
||||||
|
assert(original_dirpath);
|
||||||
|
assert(resolved_dirpath);
|
||||||
|
assert(rfd >= 0 || rfd == AT_FDCWD);
|
||||||
|
assert(files);
|
||||||
|
assert(masked);
|
||||||
|
|
||||||
|
root = strempty(root);
|
||||||
|
|
||||||
|
FOREACH_DIRENT(de, dir, return log_debug_errno(errno, "Failed to read directory '%s/%s': %m",
|
||||||
|
root, skip_leading_slash(original_dirpath))) {
|
||||||
|
|
||||||
|
_cleanup_free_ char *original_path = path_join(original_dirpath, de->d_name);
|
||||||
|
if (!original_path)
|
||||||
|
return log_oom_debug();
|
||||||
|
|
||||||
|
/* Does this match the suffix? */
|
||||||
|
if (suffix && !endswith(de->d_name, suffix)) {
|
||||||
|
log_debug("Skipping file '%s/%s' with unexpected suffix.", root, skip_leading_slash(original_path));
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Has this file already been found in an earlier directory? */
|
||||||
|
if (hashmap_contains(*files, de->d_name)) {
|
||||||
|
log_debug("Skipping overridden file '%s/%s'.", root, skip_leading_slash(original_path));
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Has this been masked in an earlier directory? */
|
||||||
|
if ((flags & CONF_FILES_FILTER_MASKED) != 0 && set_contains(*masked, de->d_name)) {
|
||||||
|
log_debug("File '%s/%s' is masked by previous entry.", root, skip_leading_slash(original_path));
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
_cleanup_free_ char *p = path_join(resolved_dirpath, de->d_name);
|
||||||
|
if (!p)
|
||||||
|
return log_oom_debug();
|
||||||
|
|
||||||
|
_cleanup_free_ char *resolved_path = NULL;
|
||||||
|
_cleanup_close_ int fd = -EBADF;
|
||||||
|
bool need_stat = (flags & (CONF_FILES_FILTER_MASKED | CONF_FILES_REGULAR | CONF_FILES_DIRECTORY | CONF_FILES_EXECUTABLE)) != 0;
|
||||||
|
ChaseFlags chase_flags = CHASE_AT_RESOLVE_IN_ROOT;
|
||||||
|
|
||||||
|
if (!need_stat || FLAGS_SET(flags, CONF_FILES_FILTER_MASKED_BY_SYMLINK))
|
||||||
|
/* Even if no verification is requested, let's unconditionally call chaseat(),
|
||||||
|
* to drop unsafe symlinks. */
|
||||||
|
chase_flags |= CHASE_NONEXISTENT;
|
||||||
|
|
||||||
|
r = chaseat(rfd, p, chase_flags, &resolved_path, &fd);
|
||||||
|
if (r < 0) {
|
||||||
|
log_debug_errno(r, "Failed to chase '%s/%s', ignoring: %m",
|
||||||
|
root, skip_leading_slash(original_path));
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (r == 0) {
|
||||||
|
if (FLAGS_SET(flags, CONF_FILES_FILTER_MASKED_BY_SYMLINK)) {
|
||||||
|
|
||||||
|
/* If the path points to /dev/null in a image or so, then the device node may not exist. */
|
||||||
|
if (path_equal(skip_leading_slash(resolved_path), "dev/null")) {
|
||||||
|
/* Mark this one as masked */
|
||||||
|
r = set_put_strdup(masked, de->d_name);
|
||||||
|
if (r < 0)
|
||||||
|
return log_oom_debug();
|
||||||
|
|
||||||
|
log_debug("File '%s/%s' is a mask (symlink to /dev/null).",
|
||||||
|
root, skip_leading_slash(original_path));
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (need_stat) {
|
||||||
|
/* If we need to have stat, skip the entry. */
|
||||||
|
log_debug_errno(SYNTHETIC_ERRNO(ENOENT), "Failed to chase '%s/%s', ignoring: %m",
|
||||||
|
root, skip_leading_slash(original_path));
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Even if we do not need stat, let's take stat now. The caller may use the info later. */
|
||||||
|
struct stat st = {};
|
||||||
|
if (fd >= 0 && fstat(fd, &st) < 0) {
|
||||||
|
log_debug_errno(errno, "Failed to stat '%s/%s', ignoring: %m",
|
||||||
|
root, skip_leading_slash(original_path));
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Is this a masking entry? */
|
||||||
|
if (FLAGS_SET(flags, CONF_FILES_FILTER_MASKED_BY_SYMLINK) && stat_may_be_dev_null(&st)) {
|
||||||
|
/* Mark this one as masked */
|
||||||
|
r = set_put_strdup(masked, de->d_name);
|
||||||
|
if (r < 0)
|
||||||
|
return log_oom_debug();
|
||||||
|
|
||||||
|
log_debug("File '%s/%s' is a mask (symlink to /dev/null).", root, skip_leading_slash(original_path));
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (FLAGS_SET(flags, CONF_FILES_FILTER_MASKED_BY_EMPTY) && stat_is_empty(&st)) {
|
||||||
|
/* Mark this one as masked */
|
||||||
|
r = set_put_strdup(masked, de->d_name);
|
||||||
|
if (r < 0)
|
||||||
|
return log_oom_debug();
|
||||||
|
|
||||||
|
log_debug("File '%s/%s' is a mask (an empty file).", root, skip_leading_slash(original_path));
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (FLAGS_SET(flags, CONF_FILES_REGULAR|CONF_FILES_DIRECTORY)) {
|
||||||
|
if (!S_ISREG(st.st_mode) && !S_ISDIR(st.st_mode)) {
|
||||||
|
log_debug("Ignoring '%s/%s', as it is neither a regular file or directory.", root, skip_leading_slash(original_path));
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
/* Is this node a regular file? */
|
||||||
|
if (FLAGS_SET(flags, CONF_FILES_REGULAR) && !S_ISREG(st.st_mode)) {
|
||||||
|
log_debug("Ignoring '%s/%s', as it is not a regular file.", root, skip_leading_slash(original_path));
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Is this node a directory? */
|
||||||
|
if (FLAGS_SET(flags, CONF_FILES_DIRECTORY) && !S_ISDIR(st.st_mode)) {
|
||||||
|
log_debug("Ignoring '%s/%s', as it is not a directory.", root, skip_leading_slash(original_path));
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Does this node have the executable bit set?
|
||||||
|
* As requested: check if the file is marked executable. Note that we don't check access(X_OK)
|
||||||
|
* here, as we care about whether the file is marked executable at all, and not whether it is
|
||||||
|
* executable for us, because if so, such errors are stuff we should log about. */
|
||||||
|
if (FLAGS_SET(flags, CONF_FILES_EXECUTABLE) && (st.st_mode & 0111) == 0) {
|
||||||
|
log_debug("Ignoring '%s/%s', as it is not marked executable.", root, skip_leading_slash(original_path));
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
_cleanup_(conf_file_freep) ConfFile *c = new(ConfFile, 1);
|
||||||
|
if (!c)
|
||||||
|
return log_oom_debug();
|
||||||
|
|
||||||
|
*c = (ConfFile) {
|
||||||
|
.name = strdup(de->d_name),
|
||||||
|
.result = TAKE_PTR(p),
|
||||||
|
.original_path = TAKE_PTR(original_path),
|
||||||
|
.resolved_path = TAKE_PTR(resolved_path),
|
||||||
|
.fd = TAKE_FD(fd),
|
||||||
|
.st = st,
|
||||||
|
};
|
||||||
|
|
||||||
|
if (!c->name)
|
||||||
|
return log_oom_debug();
|
||||||
|
|
||||||
|
r = hashmap_ensure_put(files, &conf_file_hash_ops, c->name, c);
|
||||||
|
if (r < 0) {
|
||||||
|
assert(r == -ENOMEM);
|
||||||
|
return log_oom_debug();
|
||||||
|
}
|
||||||
|
assert(r > 0);
|
||||||
|
|
||||||
|
TAKE_PTR(c);
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int dump_files(Hashmap *fh, const char *root, ConfFile ***ret_files, size_t *ret_n_files) {
|
||||||
|
ConfFile **files = NULL;
|
||||||
|
size_t n_files = 0;
|
||||||
|
int r;
|
||||||
|
|
||||||
|
CLEANUP_ARRAY(files, n_files, conf_file_free_many);
|
||||||
|
|
||||||
|
assert(ret_files);
|
||||||
|
assert(ret_n_files);
|
||||||
|
|
||||||
|
/* The entries in the array given by hashmap_dump_sorted() are still owned by the hashmap. */
|
||||||
|
r = hashmap_dump_sorted(fh, (void***) &files, &n_files);
|
||||||
|
if (r < 0)
|
||||||
|
return log_oom_debug();
|
||||||
|
|
||||||
|
/* Hence, we need to remove them from the hashmap. */
|
||||||
|
FOREACH_ARRAY(i, files, n_files)
|
||||||
|
assert_se(hashmap_remove(fh, (*i)->name) == *i);
|
||||||
|
|
||||||
|
if (root)
|
||||||
|
FOREACH_ARRAY(i, files, n_files) {
|
||||||
|
r = conf_file_prefix_root(*i, root);
|
||||||
|
if (r < 0)
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
*ret_files = TAKE_PTR(files);
|
||||||
|
*ret_n_files = n_files;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int copy_and_sort_files_from_hashmap(Hashmap *fh, const char *root, ConfFilesFlags flags, char ***ret) {
|
||||||
|
_cleanup_strv_free_ char **results = NULL;
|
||||||
|
_cleanup_free_ ConfFile **files = NULL;
|
||||||
|
size_t n_files = 0, n_results = 0;
|
||||||
|
int r;
|
||||||
|
|
||||||
|
assert(ret);
|
||||||
|
|
||||||
|
/* The entries in the array given by hashmap_dump_sorted() are still owned by the hashmap.
|
||||||
|
* Hence, do not use conf_file_free_many() for 'entries' */
|
||||||
|
r = hashmap_dump_sorted(fh, (void***) &files, &n_files);
|
||||||
|
if (r < 0)
|
||||||
|
return log_oom_debug();
|
||||||
|
|
||||||
|
FOREACH_ARRAY(i, files, n_files) {
|
||||||
|
ConfFile *c = *i;
|
||||||
|
|
||||||
|
if (FLAGS_SET(flags, CONF_FILES_BASENAME))
|
||||||
|
r = strv_extend_with_size(&results, &n_results, c->name);
|
||||||
|
else if (root) {
|
||||||
|
char *p;
|
||||||
|
|
||||||
|
r = chaseat_prefix_root(c->result, root, &p);
|
||||||
|
if (r < 0)
|
||||||
|
return log_debug_errno(r, "Failed to prefix '%s' with root '%s': %m", c->result, root);
|
||||||
|
|
||||||
|
r = strv_consume_with_size(&results, &n_results, TAKE_PTR(p));
|
||||||
|
} else
|
||||||
|
r = strv_extend_with_size(&results, &n_results, c->result);
|
||||||
|
if (r < 0)
|
||||||
|
return log_oom_debug();
|
||||||
|
}
|
||||||
|
|
||||||
|
*ret = TAKE_PTR(results);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int insert_replacement(Hashmap **fh, ConfFile *replacement, const ConfFile **ret) {
|
||||||
|
_cleanup_(conf_file_freep) ConfFile *c = ASSERT_PTR(replacement);
|
||||||
|
int r;
|
||||||
|
|
||||||
|
assert(fh);
|
||||||
|
assert(ret);
|
||||||
|
|
||||||
|
/* This consumes the input ConfFile. */
|
||||||
|
|
||||||
|
ConfFile *existing = hashmap_get(*fh, c->name);
|
||||||
|
if (existing) {
|
||||||
|
log_debug("An entry with higher priority '%s' -> '%s' already exists, ignoring the replacement: %s",
|
||||||
|
existing->name, existing->result, c->original_path);
|
||||||
|
*ret = NULL;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
r = hashmap_ensure_put(fh, &conf_file_hash_ops, c->name, c);
|
||||||
|
if (r < 0) {
|
||||||
|
assert(r == -ENOMEM);
|
||||||
|
return log_oom_debug();
|
||||||
|
}
|
||||||
|
assert(r > 0);
|
||||||
|
|
||||||
|
log_debug("Inserted replacement: '%s' -> '%s'", c->name, c->result);
|
||||||
|
|
||||||
|
*ret = TAKE_PTR(c);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int conf_files_list_impl(
|
||||||
|
const char *suffix,
|
||||||
|
int rfd,
|
||||||
|
const char *root, /* for logging, can be NULL */
|
||||||
|
ConfFilesFlags flags,
|
||||||
|
const char * const *dirs,
|
||||||
|
const char *replacement,
|
||||||
|
Hashmap **ret,
|
||||||
|
const ConfFile **ret_inserted) {
|
||||||
|
|
||||||
|
_cleanup_hashmap_free_ Hashmap *fh = NULL;
|
||||||
|
_cleanup_set_free_ Set *masked = NULL;
|
||||||
|
_cleanup_(conf_file_freep) ConfFile *c = NULL;
|
||||||
|
const ConfFile *inserted = NULL;
|
||||||
|
int r;
|
||||||
|
|
||||||
|
assert(rfd >= 0 || rfd == AT_FDCWD);
|
||||||
|
assert(ret);
|
||||||
|
|
||||||
|
if (replacement) {
|
||||||
|
r = conf_file_new_at(replacement, rfd, CHASE_NONEXISTENT, &c);
|
||||||
|
if (r < 0)
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
STRV_FOREACH(p, dirs) {
|
||||||
|
_cleanup_closedir_ DIR *dir = NULL;
|
||||||
|
_cleanup_free_ char *path = NULL;
|
||||||
|
|
||||||
|
r = chase_and_opendirat(rfd, *p, CHASE_AT_RESOLVE_IN_ROOT, &path, &dir);
|
||||||
|
if (r < 0) {
|
||||||
|
if (r != -ENOENT)
|
||||||
|
log_debug_errno(r, "Failed to chase and open directory '%s/%s', ignoring: %m", strempty(root), skip_leading_slash(*p));
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (c && streq_ptr(path_startswith(c->result, path), c->name)) {
|
||||||
|
r = insert_replacement(&fh, TAKE_PTR(c), &inserted);
|
||||||
|
if (r < 0)
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
r = files_add(dir, *p, path, rfd, root, &fh, &masked, suffix, flags);
|
||||||
|
if (r == -ENOMEM)
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (c) {
|
||||||
|
r = insert_replacement(&fh, TAKE_PTR(c), &inserted);
|
||||||
|
if (r < 0)
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
*ret = TAKE_PTR(fh);
|
||||||
|
if (ret_inserted)
|
||||||
|
*ret_inserted = inserted;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
int conf_files_list_strv(
|
int conf_files_list_strv(
|
||||||
char ***ret,
|
char ***ret,
|
||||||
const char *suffix,
|
const char *suffix,
|
||||||
@ -402,6 +567,35 @@ int conf_files_list_strv(
|
|||||||
return copy_and_sort_files_from_hashmap(fh, empty_to_root(root_abs), flags, ret);
|
return copy_and_sort_files_from_hashmap(fh, empty_to_root(root_abs), flags, ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int conf_files_list_strv_full(
|
||||||
|
const char *suffix,
|
||||||
|
const char *root,
|
||||||
|
ConfFilesFlags flags,
|
||||||
|
const char * const *dirs,
|
||||||
|
ConfFile ***ret_files,
|
||||||
|
size_t *ret_n_files) {
|
||||||
|
|
||||||
|
_cleanup_hashmap_free_ Hashmap *fh = NULL;
|
||||||
|
_cleanup_close_ int rfd = -EBADF;
|
||||||
|
_cleanup_free_ char *root_abs = NULL;
|
||||||
|
_cleanup_strv_free_ char **dirs_abs = NULL;
|
||||||
|
int r;
|
||||||
|
|
||||||
|
assert(ret_files);
|
||||||
|
assert(ret_n_files);
|
||||||
|
|
||||||
|
r = prepare_dirs(root, (char**) dirs, &rfd, &root_abs, &dirs_abs);
|
||||||
|
if (r < 0)
|
||||||
|
return r;
|
||||||
|
|
||||||
|
r = conf_files_list_impl(suffix, rfd, root_abs, flags, (const char * const *) dirs_abs,
|
||||||
|
/* replacement = */ NULL, &fh, /* ret_inserted = */ NULL);
|
||||||
|
if (r < 0)
|
||||||
|
return r;
|
||||||
|
|
||||||
|
return dump_files(fh, empty_to_root(root_abs), ret_files, ret_n_files);
|
||||||
|
}
|
||||||
|
|
||||||
int conf_files_list_strv_at(
|
int conf_files_list_strv_at(
|
||||||
char ***ret,
|
char ***ret,
|
||||||
const char *suffix,
|
const char *suffix,
|
||||||
@ -426,14 +620,48 @@ int conf_files_list_strv_at(
|
|||||||
return copy_and_sort_files_from_hashmap(fh, /* root = */ NULL, flags, ret);
|
return copy_and_sort_files_from_hashmap(fh, /* root = */ NULL, flags, ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int conf_files_list_strv_at_full(
|
||||||
|
const char *suffix,
|
||||||
|
int rfd,
|
||||||
|
ConfFilesFlags flags,
|
||||||
|
const char * const *dirs,
|
||||||
|
ConfFile ***ret_files,
|
||||||
|
size_t *ret_n_files) {
|
||||||
|
|
||||||
|
_cleanup_hashmap_free_ Hashmap *fh = NULL;
|
||||||
|
_cleanup_free_ char *root = NULL;
|
||||||
|
int r;
|
||||||
|
|
||||||
|
assert(rfd >= 0 || rfd == AT_FDCWD);
|
||||||
|
assert(ret_files);
|
||||||
|
assert(ret_n_files);
|
||||||
|
|
||||||
|
if (rfd >= 0 && DEBUG_LOGGING)
|
||||||
|
(void) fd_get_path(rfd, &root); /* for logging */
|
||||||
|
|
||||||
|
r = conf_files_list_impl(suffix, rfd, root, flags, dirs, /* replacement = */ NULL, &fh, /* ret_inserted = */ NULL);
|
||||||
|
if (r < 0)
|
||||||
|
return r;
|
||||||
|
|
||||||
|
return dump_files(fh, /* root = */ NULL, ret_files, ret_n_files);
|
||||||
|
}
|
||||||
|
|
||||||
int conf_files_list(char ***ret, const char *suffix, const char *root, ConfFilesFlags flags, const char *dir) {
|
int conf_files_list(char ***ret, const char *suffix, const char *root, ConfFilesFlags flags, const char *dir) {
|
||||||
return conf_files_list_strv(ret, suffix, root, flags, STRV_MAKE_CONST(dir));
|
return conf_files_list_strv(ret, suffix, root, flags, STRV_MAKE_CONST(dir));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int conf_files_list_full(const char *suffix, const char *root, ConfFilesFlags flags, const char *dir, ConfFile ***ret_files, size_t *ret_n_files) {
|
||||||
|
return conf_files_list_strv_full(suffix, root, flags, STRV_MAKE_CONST(dir), ret_files, ret_n_files);
|
||||||
|
}
|
||||||
|
|
||||||
int conf_files_list_at(char ***ret, const char *suffix, int rfd, ConfFilesFlags flags, const char *dir) {
|
int conf_files_list_at(char ***ret, const char *suffix, int rfd, ConfFilesFlags flags, const char *dir) {
|
||||||
return conf_files_list_strv_at(ret, suffix, rfd, flags, STRV_MAKE_CONST(dir));
|
return conf_files_list_strv_at(ret, suffix, rfd, flags, STRV_MAKE_CONST(dir));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int conf_files_list_at_full(const char *suffix, int rfd, ConfFilesFlags flags, const char *dir, ConfFile ***ret_files, size_t *ret_n_files) {
|
||||||
|
return conf_files_list_strv_at_full(suffix, rfd, flags, STRV_MAKE_CONST(dir), ret_files, ret_n_files);
|
||||||
|
}
|
||||||
|
|
||||||
int conf_files_list_nulstr(char ***ret, const char *suffix, const char *root, ConfFilesFlags flags, const char *dirs) {
|
int conf_files_list_nulstr(char ***ret, const char *suffix, const char *root, ConfFilesFlags flags, const char *dirs) {
|
||||||
_cleanup_strv_free_ char **d = NULL;
|
_cleanup_strv_free_ char **d = NULL;
|
||||||
|
|
||||||
@ -446,6 +674,19 @@ int conf_files_list_nulstr(char ***ret, const char *suffix, const char *root, Co
|
|||||||
return conf_files_list_strv(ret, suffix, root, flags, (const char**) d);
|
return conf_files_list_strv(ret, suffix, root, flags, (const char**) d);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int conf_files_list_nulstr_full(const char *suffix, const char *root, ConfFilesFlags flags, const char *dirs, ConfFile ***ret_files, size_t *ret_n_files) {
|
||||||
|
_cleanup_strv_free_ char **d = NULL;
|
||||||
|
|
||||||
|
assert(ret_files);
|
||||||
|
assert(ret_n_files);
|
||||||
|
|
||||||
|
d = strv_split_nulstr(dirs);
|
||||||
|
if (!d)
|
||||||
|
return -ENOMEM;
|
||||||
|
|
||||||
|
return conf_files_list_strv_full(suffix, root, flags, (const char**) d, ret_files, ret_n_files);
|
||||||
|
}
|
||||||
|
|
||||||
int conf_files_list_nulstr_at(char ***ret, const char *suffix, int rfd, ConfFilesFlags flags, const char *dirs) {
|
int conf_files_list_nulstr_at(char ***ret, const char *suffix, int rfd, ConfFilesFlags flags, const char *dirs) {
|
||||||
_cleanup_strv_free_ char **d = NULL;
|
_cleanup_strv_free_ char **d = NULL;
|
||||||
|
|
||||||
@ -458,6 +699,19 @@ int conf_files_list_nulstr_at(char ***ret, const char *suffix, int rfd, ConfFile
|
|||||||
return conf_files_list_strv_at(ret, suffix, rfd, flags, (const char**) d);
|
return conf_files_list_strv_at(ret, suffix, rfd, flags, (const char**) d);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int conf_files_list_nulstr_at_full(const char *suffix, int rfd, ConfFilesFlags flags, const char *dirs, ConfFile ***ret_files, size_t *ret_n_files) {
|
||||||
|
_cleanup_strv_free_ char **d = NULL;
|
||||||
|
|
||||||
|
assert(ret_files);
|
||||||
|
assert(ret_n_files);
|
||||||
|
|
||||||
|
d = strv_split_nulstr(dirs);
|
||||||
|
if (!d)
|
||||||
|
return -ENOMEM;
|
||||||
|
|
||||||
|
return conf_files_list_strv_at_full(suffix, rfd, flags, (const char**) d, ret_files, ret_n_files);
|
||||||
|
}
|
||||||
|
|
||||||
int conf_files_list_with_replacement(
|
int conf_files_list_with_replacement(
|
||||||
const char *root,
|
const char *root,
|
||||||
char **config_dirs,
|
char **config_dirs,
|
||||||
@ -471,6 +725,7 @@ int conf_files_list_with_replacement(
|
|||||||
_cleanup_close_ int rfd = -EBADF;
|
_cleanup_close_ int rfd = -EBADF;
|
||||||
_cleanup_free_ char *root_abs = NULL;
|
_cleanup_free_ char *root_abs = NULL;
|
||||||
_cleanup_strv_free_ char **dirs_abs = NULL;
|
_cleanup_strv_free_ char **dirs_abs = NULL;
|
||||||
|
const ConfFile *c = NULL;
|
||||||
int r;
|
int r;
|
||||||
|
|
||||||
assert(ret_files);
|
assert(ret_files);
|
||||||
@ -480,18 +735,14 @@ int conf_files_list_with_replacement(
|
|||||||
return r;
|
return r;
|
||||||
|
|
||||||
r = conf_files_list_impl(".conf", rfd, root_abs, flags, (const char * const *) dirs_abs,
|
r = conf_files_list_impl(".conf", rfd, root_abs, flags, (const char * const *) dirs_abs,
|
||||||
replacement, &fh, ret_inserted ? &inserted : NULL);
|
replacement, &fh, ret_inserted ? &c : NULL);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return r;
|
return r;
|
||||||
|
|
||||||
if (inserted) {
|
if (c) {
|
||||||
char *p;
|
r = chaseat_prefix_root(c->result, root_abs, &inserted);
|
||||||
|
|
||||||
r = chaseat_prefix_root(inserted, root_abs, &p);
|
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return log_debug_errno(r, "Failed to prefix '%s' with root '%s': %m", inserted, empty_to_root(root_abs));
|
return log_debug_errno(r, "Failed to prefix '%s' with root '%s': %m", c->result, empty_to_root(root_abs));
|
||||||
|
|
||||||
free_and_replace(inserted, p);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
r = copy_and_sort_files_from_hashmap(fh, empty_to_root(root_abs), flags, ret_files);
|
r = copy_and_sort_files_from_hashmap(fh, empty_to_root(root_abs), flags, ret_files);
|
||||||
|
@ -1,6 +1,8 @@
|
|||||||
/* SPDX-License-Identifier: LGPL-2.1-or-later */
|
/* SPDX-License-Identifier: LGPL-2.1-or-later */
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include <sys/stat.h>
|
||||||
|
|
||||||
#include "forward.h"
|
#include "forward.h"
|
||||||
|
|
||||||
typedef enum ConfFilesFlags {
|
typedef enum ConfFilesFlags {
|
||||||
@ -13,12 +15,36 @@ typedef enum ConfFilesFlags {
|
|||||||
CONF_FILES_FILTER_MASKED = CONF_FILES_FILTER_MASKED_BY_SYMLINK | CONF_FILES_FILTER_MASKED_BY_EMPTY,
|
CONF_FILES_FILTER_MASKED = CONF_FILES_FILTER_MASKED_BY_SYMLINK | CONF_FILES_FILTER_MASKED_BY_EMPTY,
|
||||||
} ConfFilesFlags;
|
} ConfFilesFlags;
|
||||||
|
|
||||||
|
typedef struct ConfFile {
|
||||||
|
char *name; /* name of a file found in config directories */
|
||||||
|
char *result; /* resolved config directory with the original file name found in the directory */
|
||||||
|
char *original_path; /* original config directory with the original file name found in the directory */
|
||||||
|
char *resolved_path; /* fully resolved path, where the filename part of the path may be different from the original name */
|
||||||
|
int fd; /* O_PATH fd to resolved_path, -EBADF if the resolved_path does not exist */
|
||||||
|
struct stat st; /* stat of the file. */
|
||||||
|
} ConfFile;
|
||||||
|
|
||||||
|
ConfFile* conf_file_free(ConfFile *c);
|
||||||
|
DEFINE_TRIVIAL_CLEANUP_FUNC(ConfFile*, conf_file_free);
|
||||||
|
void conf_file_free_many(ConfFile **array, size_t n);
|
||||||
|
|
||||||
|
int conf_file_new_at(const char *path, int rfd, ChaseFlags chase_flags, ConfFile **ret);
|
||||||
|
int conf_file_new(const char *path, const char *root, ChaseFlags chase_flags, ConfFile **ret);
|
||||||
|
|
||||||
int conf_files_list(char ***ret, const char *suffix, const char *root, ConfFilesFlags flags, const char *dir);
|
int conf_files_list(char ***ret, const char *suffix, const char *root, ConfFilesFlags flags, const char *dir);
|
||||||
int conf_files_list_at(char ***ret, const char *suffix, int rfd, ConfFilesFlags flags, const char *dir);
|
int conf_files_list_at(char ***ret, const char *suffix, int rfd, ConfFilesFlags flags, const char *dir);
|
||||||
int conf_files_list_strv(char ***ret, const char *suffix, const char *root, ConfFilesFlags flags, const char* const* dirs);
|
int conf_files_list_strv(char ***ret, const char *suffix, const char *root, ConfFilesFlags flags, const char* const* dirs);
|
||||||
int conf_files_list_strv_at(char ***ret, const char *suffix, int rfd, ConfFilesFlags flags, const char * const *dirs);
|
int conf_files_list_strv_at(char ***ret, const char *suffix, int rfd, ConfFilesFlags flags, const char * const *dirs);
|
||||||
int conf_files_list_nulstr(char ***ret, const char *suffix, const char *root, ConfFilesFlags flags, const char *dirs);
|
int conf_files_list_nulstr(char ***ret, const char *suffix, const char *root, ConfFilesFlags flags, const char *dirs);
|
||||||
int conf_files_list_nulstr_at(char ***ret, const char *suffix, int rfd, ConfFilesFlags flags, const char *dirs);
|
int conf_files_list_nulstr_at(char ***ret, const char *suffix, int rfd, ConfFilesFlags flags, const char *dirs);
|
||||||
|
|
||||||
|
int conf_files_list_full(const char *suffix, const char *root, ConfFilesFlags flags, const char *dir, ConfFile ***ret_files, size_t *ret_n_files);
|
||||||
|
int conf_files_list_at_full(const char *suffix, int rfd, ConfFilesFlags flags, const char *dir, ConfFile ***ret_files, size_t *ret_n_files);
|
||||||
|
int conf_files_list_strv_full(const char *suffix, const char *root, ConfFilesFlags flags, const char * const *dirs, ConfFile ***ret_files, size_t *ret_n_files);
|
||||||
|
int conf_files_list_strv_at_full(const char *suffix, int rfd, ConfFilesFlags flags, const char * const *dirs, ConfFile ***ret_files, size_t *ret_n_files);
|
||||||
|
int conf_files_list_nulstr_full(const char *suffix, const char *root, ConfFilesFlags flags, const char *dirs, ConfFile ***ret_files, size_t *ret_n_files);
|
||||||
|
int conf_files_list_nulstr_at_full(const char *suffix, int rfd, ConfFilesFlags flags, const char *dirs, ConfFile ***ret_files, size_t *ret_n_files);
|
||||||
|
|
||||||
int conf_files_list_with_replacement(
|
int conf_files_list_with_replacement(
|
||||||
const char *root,
|
const char *root,
|
||||||
char **config_dirs,
|
char **config_dirs,
|
||||||
|
@ -2,8 +2,8 @@
|
|||||||
|
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
#include <linux/fs.h>
|
#include <linux/fs.h>
|
||||||
#include <linux/kcmp.h>
|
|
||||||
#include <sys/ioctl.h>
|
#include <sys/ioctl.h>
|
||||||
|
#include <sys/kcmp.h>
|
||||||
#include <sys/resource.h>
|
#include <sys/resource.h>
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
@ -16,7 +16,6 @@
|
|||||||
#include "format-util.h"
|
#include "format-util.h"
|
||||||
#include "fs-util.h"
|
#include "fs-util.h"
|
||||||
#include "log.h"
|
#include "log.h"
|
||||||
#include "missing_syscall.h"
|
|
||||||
#include "mountpoint-util.h"
|
#include "mountpoint-util.h"
|
||||||
#include "parse-util.h"
|
#include "parse-util.h"
|
||||||
#include "path-util.h"
|
#include "path-util.h"
|
||||||
|
@ -6,7 +6,6 @@ _Pragma("GCC diagnostic ignored \"-Wzero-as-null-pointer-constant\"")
|
|||||||
#include <linux/magic.h>
|
#include <linux/magic.h>
|
||||||
|
|
||||||
#include "filesystems.h"
|
#include "filesystems.h"
|
||||||
#include "missing_magic.h"
|
|
||||||
#include "stat-util.h"
|
#include "stat-util.h"
|
||||||
|
|
||||||
struct FilesystemMagic {
|
struct FilesystemMagic {
|
||||||
|
@ -104,6 +104,7 @@ typedef struct Set Set;
|
|||||||
|
|
||||||
typedef struct dual_timestamp dual_timestamp;
|
typedef struct dual_timestamp dual_timestamp;
|
||||||
typedef struct triple_timestamp triple_timestamp;
|
typedef struct triple_timestamp triple_timestamp;
|
||||||
|
typedef struct ConfFile ConfFile;
|
||||||
typedef struct LockFile LockFile;
|
typedef struct LockFile LockFile;
|
||||||
typedef struct PidRef PidRef;
|
typedef struct PidRef PidRef;
|
||||||
typedef struct Prioq Prioq;
|
typedef struct Prioq Prioq;
|
||||||
|
@ -16,7 +16,6 @@
|
|||||||
#include "label.h"
|
#include "label.h"
|
||||||
#include "lock-util.h"
|
#include "lock-util.h"
|
||||||
#include "log.h"
|
#include "log.h"
|
||||||
#include "missing_syscall.h"
|
|
||||||
#include "mkdir.h"
|
#include "mkdir.h"
|
||||||
#include "path-util.h"
|
#include "path-util.h"
|
||||||
#include "process-util.h"
|
#include "process-util.h"
|
||||||
|
@ -3,6 +3,9 @@
|
|||||||
set -eu
|
set -eu
|
||||||
set -o pipefail
|
set -o pipefail
|
||||||
|
|
||||||
${1:?} -E -dM -include sys/socket.h -include "${2:?}" - </dev/null | \
|
CC=${1:?}
|
||||||
|
shift
|
||||||
|
|
||||||
|
$CC -E -dM -include sys/socket.h "$@" - </dev/null | \
|
||||||
grep -Ev 'AF_UNSPEC|AF_MAX' | \
|
grep -Ev 'AF_UNSPEC|AF_MAX' | \
|
||||||
awk '/^#define[ \t]+AF_[^ \t]+[ \t]+[AP]F_[^ \t]/ { print $2; }'
|
awk '/^#define[ \t]+AF_[^ \t]+[ \t]+[AP]F_[^ \t]/ { print $2; }'
|
||||||
|
@ -3,6 +3,9 @@
|
|||||||
set -eu
|
set -eu
|
||||||
set -o pipefail
|
set -o pipefail
|
||||||
|
|
||||||
${1:?} -dM -include "${2:?}" - </dev/null | \
|
CC=${1:?}
|
||||||
|
shift
|
||||||
|
|
||||||
|
$CC -dM -include linux/if_arp.h "$@" - </dev/null | \
|
||||||
awk '/^#define[ \t]+ARPHRD_[^ \t]+[ \t]+[^ \t]/ { print $2; }' | \
|
awk '/^#define[ \t]+ARPHRD_[^ \t]+[ \t]+[^ \t]/ { print $2; }' | \
|
||||||
sed -e 's/ARPHRD_//'
|
sed -e 's/ARPHRD_//'
|
||||||
|
@ -3,6 +3,9 @@
|
|||||||
set -eu
|
set -eu
|
||||||
set -o pipefail
|
set -o pipefail
|
||||||
|
|
||||||
${1:?} -dM -include "${2:?}" - </dev/null | \
|
CC=${1:?}
|
||||||
|
shift
|
||||||
|
|
||||||
|
$CC -dM -include linux/capability.h "$@" - </dev/null | \
|
||||||
awk '/^#define[ \t]+CAP_[A-Z_]+[ \t]+/ { print $2; }' | \
|
awk '/^#define[ \t]+CAP_[A-Z_]+[ \t]+/ { print $2; }' | \
|
||||||
grep -v CAP_LAST_CAP
|
grep -v CAP_LAST_CAP
|
||||||
|
@ -6,6 +6,9 @@ set -o pipefail
|
|||||||
# In kernel's arch/parisc/include/uapi/asm/errno.h, ECANCELLED and EREFUSED are defined as aliases of
|
# In kernel's arch/parisc/include/uapi/asm/errno.h, ECANCELLED and EREFUSED are defined as aliases of
|
||||||
# ECANCELED and ECONNREFUSED, respectively. Let's drop them.
|
# ECANCELED and ECONNREFUSED, respectively. Let's drop them.
|
||||||
|
|
||||||
${1:?} -dM -include errno.h - </dev/null | \
|
CC=${1:?}
|
||||||
|
shift
|
||||||
|
|
||||||
|
$CC -dM -include errno.h "$@" - </dev/null | \
|
||||||
grep -Ev '^#define[[:space:]]+(ECANCELLED|EREFUSED)' | \
|
grep -Ev '^#define[[:space:]]+(ECANCELLED|EREFUSED)' | \
|
||||||
awk '/^#define[ \t]+E[^ _]+[ \t]+/ { print $2; }'
|
awk '/^#define[ \t]+E[^ _]+[ \t]+/ { print $2; }'
|
||||||
|
@ -1,8 +0,0 @@
|
|||||||
/* SPDX-License-Identifier: LGPL-2.1-or-later */
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
/* To make struct xattr_args defined, which is used by setxattrat(). Note, the kernel header must be
|
|
||||||
* included before the glibc header, otherwise the struct will not be defined. */
|
|
||||||
#include <linux/xattr.h>
|
|
||||||
|
|
||||||
#include_next <sys/xattr.h>
|
|
@ -3,7 +3,6 @@
|
|||||||
#include "alloc-util.h"
|
#include "alloc-util.h"
|
||||||
#include "keyring-util.h"
|
#include "keyring-util.h"
|
||||||
#include "log.h"
|
#include "log.h"
|
||||||
#include "missing_syscall.h"
|
|
||||||
|
|
||||||
int keyring_read(key_serial_t serial, void **ret, size_t *ret_size) {
|
int keyring_read(key_serial_t serial, void **ret, size_t *ret_size) {
|
||||||
size_t bufsize = 100;
|
size_t bufsize = 100;
|
||||||
|
@ -1,8 +1,9 @@
|
|||||||
/* SPDX-License-Identifier: LGPL-2.1-or-later */
|
/* SPDX-License-Identifier: LGPL-2.1-or-later */
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include <sys/keyctl.h> /* IWYU pragma: export */
|
||||||
|
|
||||||
#include "forward.h"
|
#include "forward.h"
|
||||||
#include "missing_keyctl.h"
|
|
||||||
|
|
||||||
/* Like TAKE_PTR() but for key_serial_t, resetting them to -1 */
|
/* Like TAKE_PTR() but for key_serial_t, resetting them to -1 */
|
||||||
#define TAKE_KEY_SERIAL(key_serial) TAKE_GENERIC(key_serial, key_serial_t, -1)
|
#define TAKE_KEY_SERIAL(key_serial) TAKE_GENERIC(key_serial, key_serial_t, -1)
|
||||||
|
@ -84,6 +84,7 @@ basic_sources = files(
|
|||||||
'psi-util.c',
|
'psi-util.c',
|
||||||
'random-util.c',
|
'random-util.c',
|
||||||
'ratelimit.c',
|
'ratelimit.c',
|
||||||
|
'raw-clone.c',
|
||||||
'recurse-dir.c',
|
'recurse-dir.c',
|
||||||
'replace-var.c',
|
'replace-var.c',
|
||||||
'rlimit-util.c',
|
'rlimit-util.c',
|
||||||
@ -119,44 +120,26 @@ basic_sources = files(
|
|||||||
|
|
||||||
sources += basic_sources
|
sources += basic_sources
|
||||||
|
|
||||||
missing_audit_h = files('missing_audit.h')
|
|
||||||
|
|
||||||
missing_syscall_def_h = files('missing_syscall_def.h')
|
|
||||||
basic_sources += missing_syscall_def_h
|
|
||||||
|
|
||||||
generate_af_list = find_program('generate-af-list.sh')
|
|
||||||
af_list_txt = custom_target(
|
|
||||||
output : 'af-list.txt',
|
|
||||||
command : [generate_af_list, cpp, files('include/sys/socket.h')],
|
|
||||||
capture : true)
|
|
||||||
|
|
||||||
generate_arphrd_list = find_program('generate-arphrd-list.sh')
|
|
||||||
arphrd_list_txt = custom_target(
|
|
||||||
output : 'arphrd-list.txt',
|
|
||||||
command : [generate_arphrd_list, cpp, files('include/linux/if_arp.h')],
|
|
||||||
capture : true)
|
|
||||||
|
|
||||||
generate_cap_list = find_program('generate-cap-list.sh')
|
|
||||||
cap_list_txt = custom_target(
|
|
||||||
output : 'cap-list.txt',
|
|
||||||
command : [generate_cap_list, cpp, files('include/linux/capability.h')],
|
|
||||||
capture : true)
|
|
||||||
|
|
||||||
generate_errno_list = find_program('generate-errno-list.sh')
|
|
||||||
errno_list_txt = custom_target(
|
|
||||||
output : 'errno-list.txt',
|
|
||||||
command : [generate_errno_list, cpp],
|
|
||||||
capture : true)
|
|
||||||
|
|
||||||
generated_gperf_headers = []
|
generated_gperf_headers = []
|
||||||
foreach item : [['af', af_list_txt, 'af', '', ['<sys/socket.h>']],
|
foreach item : [
|
||||||
['arphrd', arphrd_list_txt, 'arphrd', 'ARPHRD_', []],
|
# name, source, struct name, prefix, headers
|
||||||
['cap', cap_list_txt, 'capability', '', []],
|
['af', af_sources, 'af', '', ['<sys/socket.h>'], ],
|
||||||
['errno', errno_list_txt, 'errno', '', []]]
|
['arphrd', arphrd_sources, 'arphrd', 'ARPHRD_', ['<linux/if_arp.h>'], ],
|
||||||
|
['cap', cap_sources, 'capability', '', ['<linux/capability.h>'], ],
|
||||||
|
['errno', [], 'errno', '', ['<errno.h>'], ],
|
||||||
|
]
|
||||||
|
|
||||||
|
fname = '@0@-list.txt'.format(item[0])
|
||||||
|
generate_list = files('generate-@0@-list.sh'.format(item[0]))
|
||||||
|
list_txt = custom_target(
|
||||||
|
input : [generate_list, item[1]],
|
||||||
|
output : fname,
|
||||||
|
command : [env, 'bash', generate_list, cpp, system_include_args],
|
||||||
|
capture : true)
|
||||||
|
|
||||||
fname = '@0@-from-name.gperf'.format(item[0])
|
fname = '@0@-from-name.gperf'.format(item[0])
|
||||||
gperf_file = custom_target(
|
gperf_file = custom_target(
|
||||||
input : item[1],
|
input : list_txt,
|
||||||
output : fname,
|
output : fname,
|
||||||
command : [generate_gperfs, item[2], item[3], '@INPUT@'] + item[4],
|
command : [generate_gperfs, item[2], item[3], '@INPUT@'] + item[4],
|
||||||
capture : true)
|
capture : true)
|
||||||
@ -176,7 +159,7 @@ foreach item : [['af', af_list_txt, 'af', '', ['<sys/sock
|
|||||||
fname = '@0@-to-name.inc'.format(item[0])
|
fname = '@0@-to-name.inc'.format(item[0])
|
||||||
awkscript = '@0@-to-name.awk'.format(item[0])
|
awkscript = '@0@-to-name.awk'.format(item[0])
|
||||||
target2 = custom_target(
|
target2 = custom_target(
|
||||||
input : [awkscript, item[1]],
|
input : [awkscript, list_txt],
|
||||||
output : fname,
|
output : fname,
|
||||||
command : [awk, '-f', '@INPUT0@', '@INPUT1@'],
|
command : [awk, '-f', '@INPUT0@', '@INPUT1@'],
|
||||||
capture : true)
|
capture : true)
|
||||||
@ -189,61 +172,13 @@ basic_sources += generated_gperf_headers
|
|||||||
|
|
||||||
############################################################
|
############################################################
|
||||||
|
|
||||||
arch_list = [
|
|
||||||
'alpha',
|
|
||||||
'arc',
|
|
||||||
'arm',
|
|
||||||
'arm64',
|
|
||||||
'i386',
|
|
||||||
'ia64',
|
|
||||||
'loongarch64',
|
|
||||||
'm68k',
|
|
||||||
'mips64',
|
|
||||||
'mips64n32',
|
|
||||||
'mipso32',
|
|
||||||
'parisc',
|
|
||||||
'powerpc',
|
|
||||||
'powerpc64',
|
|
||||||
'riscv32',
|
|
||||||
'riscv64',
|
|
||||||
's390',
|
|
||||||
's390x',
|
|
||||||
'sparc',
|
|
||||||
'x86_64'
|
|
||||||
]
|
|
||||||
|
|
||||||
run_target(
|
|
||||||
'update-syscall-tables',
|
|
||||||
command : [update_syscall_tables_sh, meson.current_source_dir()] + arch_list)
|
|
||||||
|
|
||||||
syscall_list_txt = files('syscall-list.txt')
|
|
||||||
|
|
||||||
syscall_lists = []
|
|
||||||
foreach arch: arch_list
|
|
||||||
syscall_lists += files('syscalls-@0@.txt'.format(arch))
|
|
||||||
endforeach
|
|
||||||
|
|
||||||
missing_syscalls_py = find_program('missing_syscalls.py')
|
|
||||||
|
|
||||||
run_target(
|
|
||||||
'update-syscall-header',
|
|
||||||
command : [missing_syscalls_py,
|
|
||||||
missing_syscall_def_h,
|
|
||||||
syscall_lists])
|
|
||||||
|
|
||||||
############################################################
|
|
||||||
|
|
||||||
filesystem_includes = files(
|
|
||||||
'include/linux/magic.h',
|
|
||||||
'missing_magic.h',
|
|
||||||
)
|
|
||||||
|
|
||||||
check_filesystems = find_program('check-filesystems.sh')
|
check_filesystems = find_program('check-filesystems.sh')
|
||||||
r = run_command(
|
r = run_command(
|
||||||
[
|
[
|
||||||
'env', '--chdir', meson.project_build_root(),
|
'env', '--chdir', meson.project_build_root(),
|
||||||
check_filesystems, cpp, files('filesystems-gperf.gperf')
|
check_filesystems, cpp, files('filesystems-gperf.gperf'),
|
||||||
] + filesystem_includes,
|
system_include_args,
|
||||||
|
],
|
||||||
check: false,
|
check: false,
|
||||||
)
|
)
|
||||||
if r.returncode() != 0
|
if r.returncode() != 0
|
||||||
@ -273,17 +208,8 @@ filesystem_switch_case_inc = custom_target(
|
|||||||
'@INPUT@'],
|
'@INPUT@'],
|
||||||
capture : true)
|
capture : true)
|
||||||
|
|
||||||
generate_bpf_delegate_configs = find_program('generate-bpf-delegate-configs.py')
|
generated_sources += [filesystem_list_inc, filesystem_switch_case_inc, filesystems_gperf_h]
|
||||||
bpf_delegate_configs_inc = custom_target(
|
basic_sources += [filesystem_list_inc, filesystem_switch_case_inc, filesystems_gperf_h]
|
||||||
input : files('include/linux/bpf.h'),
|
|
||||||
output : 'bpf-delegate-configs.inc',
|
|
||||||
command : [generate_bpf_delegate_configs,
|
|
||||||
'code',
|
|
||||||
'@INPUT@'],
|
|
||||||
capture : true)
|
|
||||||
|
|
||||||
generated_sources += [filesystem_list_inc, filesystem_switch_case_inc, filesystems_gperf_h, bpf_delegate_configs_inc]
|
|
||||||
basic_sources += [filesystem_list_inc, filesystem_switch_case_inc, filesystems_gperf_h, bpf_delegate_configs_inc]
|
|
||||||
|
|
||||||
libbasic_static = static_library(
|
libbasic_static = static_library(
|
||||||
'basic',
|
'basic',
|
||||||
|
@ -1,249 +0,0 @@
|
|||||||
/* SPDX-License-Identifier: LGPL-2.1-or-later */
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
/* Missing glibc definitions to access certain kernel APIs */
|
|
||||||
|
|
||||||
#include <linux/mempolicy.h>
|
|
||||||
#include <sched.h>
|
|
||||||
#include <signal.h>
|
|
||||||
#include <sys/syscall.h>
|
|
||||||
#include <sys/xattr.h>
|
|
||||||
#include <unistd.h>
|
|
||||||
|
|
||||||
#ifdef ARCH_MIPS
|
|
||||||
#include <asm/sgidefs.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include "forward.h"
|
|
||||||
#include "missing_keyctl.h"
|
|
||||||
#include "missing_syscall_def.h"
|
|
||||||
|
|
||||||
/* ======================================================================= */
|
|
||||||
|
|
||||||
#if !HAVE_FCHMODAT2
|
|
||||||
/* since kernel v6.6 (78252deb023cf0879256fcfbafe37022c390762b) */
|
|
||||||
static inline int missing_fchmodat2(int dirfd, const char *path, mode_t mode, int flags) {
|
|
||||||
return syscall(__NR_fchmodat2, dirfd, path, mode, flags);
|
|
||||||
}
|
|
||||||
|
|
||||||
# define fchmodat2 missing_fchmodat2
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* ======================================================================= */
|
|
||||||
|
|
||||||
#if !HAVE_PIVOT_ROOT
|
|
||||||
static inline int missing_pivot_root(const char *new_root, const char *put_old) {
|
|
||||||
return syscall(__NR_pivot_root, new_root, put_old);
|
|
||||||
}
|
|
||||||
|
|
||||||
# define pivot_root missing_pivot_root
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* ======================================================================= */
|
|
||||||
|
|
||||||
#if !HAVE_IOPRIO_GET
|
|
||||||
static inline int missing_ioprio_get(int which, int who) {
|
|
||||||
return syscall(__NR_ioprio_get, which, who);
|
|
||||||
}
|
|
||||||
|
|
||||||
# define ioprio_get missing_ioprio_get
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* ======================================================================= */
|
|
||||||
|
|
||||||
#if !HAVE_IOPRIO_SET
|
|
||||||
static inline int missing_ioprio_set(int which, int who, int ioprio) {
|
|
||||||
return syscall(__NR_ioprio_set, which, who, ioprio);
|
|
||||||
}
|
|
||||||
|
|
||||||
# define ioprio_set missing_ioprio_set
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* ======================================================================= */
|
|
||||||
|
|
||||||
#if !HAVE_KCMP
|
|
||||||
static inline int missing_kcmp(pid_t pid1, pid_t pid2, int type, unsigned long idx1, unsigned long idx2) {
|
|
||||||
return syscall(__NR_kcmp, pid1, pid2, type, idx1, idx2);
|
|
||||||
}
|
|
||||||
|
|
||||||
# define kcmp missing_kcmp
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* ======================================================================= */
|
|
||||||
|
|
||||||
#if !HAVE_KEYCTL
|
|
||||||
static inline long missing_keyctl(int cmd, unsigned long arg2, unsigned long arg3, unsigned long arg4, unsigned long arg5) {
|
|
||||||
return syscall(__NR_keyctl, cmd, arg2, arg3, arg4, arg5);
|
|
||||||
|
|
||||||
# define keyctl missing_keyctl
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ======================================================================= */
|
|
||||||
|
|
||||||
static inline key_serial_t missing_add_key(const char *type, const char *description, const void *payload, size_t plen, key_serial_t ringid) {
|
|
||||||
return syscall(__NR_add_key, type, description, payload, plen, ringid);
|
|
||||||
|
|
||||||
# define add_key missing_add_key
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ======================================================================= */
|
|
||||||
|
|
||||||
static inline key_serial_t missing_request_key(const char *type, const char *description, const char * callout_info, key_serial_t destringid) {
|
|
||||||
return syscall(__NR_request_key, type, description, callout_info, destringid);
|
|
||||||
|
|
||||||
# define request_key missing_request_key
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* ======================================================================= */
|
|
||||||
|
|
||||||
#if !HAVE_BPF
|
|
||||||
union bpf_attr;
|
|
||||||
|
|
||||||
static inline int missing_bpf(int cmd, union bpf_attr *attr, size_t size) {
|
|
||||||
return (int) syscall(__NR_bpf, cmd, attr, size);
|
|
||||||
}
|
|
||||||
|
|
||||||
# define bpf missing_bpf
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* ======================================================================= */
|
|
||||||
|
|
||||||
#if !HAVE_SET_MEMPOLICY
|
|
||||||
static inline long missing_set_mempolicy(int mode, const unsigned long *nodemask,
|
|
||||||
unsigned long maxnode) {
|
|
||||||
return syscall(__NR_set_mempolicy, mode, nodemask, maxnode);
|
|
||||||
}
|
|
||||||
|
|
||||||
# define set_mempolicy missing_set_mempolicy
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if !HAVE_GET_MEMPOLICY
|
|
||||||
static inline long missing_get_mempolicy(int *mode, unsigned long *nodemask,
|
|
||||||
unsigned long maxnode, void *addr,
|
|
||||||
unsigned long flags) {
|
|
||||||
return syscall(__NR_get_mempolicy, mode, nodemask, maxnode, addr, flags);
|
|
||||||
}
|
|
||||||
|
|
||||||
# define get_mempolicy missing_get_mempolicy
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* ======================================================================= */
|
|
||||||
|
|
||||||
#if !HAVE_PIDFD_SEND_SIGNAL
|
|
||||||
/* since kernel v5.1 (3eb39f47934f9d5a3027fe00d906a45fe3a15fad) */
|
|
||||||
static inline int missing_pidfd_send_signal(int fd, int sig, siginfo_t *info, unsigned flags) {
|
|
||||||
return syscall(__NR_pidfd_send_signal, fd, sig, info, flags);
|
|
||||||
}
|
|
||||||
|
|
||||||
# define pidfd_send_signal missing_pidfd_send_signal
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* ======================================================================= */
|
|
||||||
|
|
||||||
#if !HAVE_PIDFD_OPEN
|
|
||||||
/* since kernel v5.3 (7615d9e1780e26e0178c93c55b73309a5dc093d7) */
|
|
||||||
static inline int missing_pidfd_open(pid_t pid, unsigned flags) {
|
|
||||||
return syscall(__NR_pidfd_open, pid, flags);
|
|
||||||
}
|
|
||||||
|
|
||||||
# define pidfd_open missing_pidfd_open
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* ======================================================================= */
|
|
||||||
|
|
||||||
#if !HAVE_RT_TGSIGQUEUEINFO
|
|
||||||
static inline int missing_rt_tgsigqueueinfo(pid_t tgid, pid_t tid, int sig, siginfo_t *info) {
|
|
||||||
return syscall(__NR_rt_tgsigqueueinfo, tgid, tid, sig, info);
|
|
||||||
}
|
|
||||||
|
|
||||||
# define rt_tgsigqueueinfo missing_rt_tgsigqueueinfo
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* ======================================================================= */
|
|
||||||
|
|
||||||
#if !HAVE_EXECVEAT
|
|
||||||
/* since kernel v3.19 (51f39a1f0cea1cacf8c787f652f26dfee9611874) */
|
|
||||||
static inline int missing_execveat(int dirfd, const char *pathname,
|
|
||||||
char *const argv[], char *const envp[],
|
|
||||||
int flags) {
|
|
||||||
return syscall(__NR_execveat, dirfd, pathname, argv, envp, flags);
|
|
||||||
}
|
|
||||||
|
|
||||||
# define execveat missing_execveat
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* ======================================================================= */
|
|
||||||
|
|
||||||
#if !HAVE_CLOSE_RANGE
|
|
||||||
/* since kernel v5.9 (9b4feb630e8e9801603f3cab3a36369e3c1cf88d) */
|
|
||||||
static inline int missing_close_range(unsigned first_fd, unsigned end_fd, unsigned flags) {
|
|
||||||
/* Kernel-side the syscall expects fds as unsigned integers (just like close() actually), while
|
|
||||||
* userspace exclusively uses signed integers for fds. glibc chose to expose it 1:1 however, hence we
|
|
||||||
* do so here too, even if we end up passing signed fds to it most of the time. */
|
|
||||||
return syscall(__NR_close_range,
|
|
||||||
first_fd,
|
|
||||||
end_fd,
|
|
||||||
flags);
|
|
||||||
}
|
|
||||||
|
|
||||||
# define close_range missing_close_range
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* ======================================================================= */
|
|
||||||
|
|
||||||
#if !HAVE_SCHED_SETATTR
|
|
||||||
/* since kernel 3.14 (e6cfc0295c7d51b008999a8b13a44fb43f8685ea) */
|
|
||||||
static inline ssize_t missing_sched_setattr(pid_t pid, struct sched_attr *attr, unsigned int flags) {
|
|
||||||
return syscall(__NR_sched_setattr, pid, attr, flags);
|
|
||||||
}
|
|
||||||
|
|
||||||
# define sched_setattr missing_sched_setattr
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* ======================================================================= */
|
|
||||||
|
|
||||||
/* glibc does not provide clone() on ia64, only clone2(). Not only that, but it also doesn't provide a
|
|
||||||
* prototype, only the symbol in the shared library (it provides a prototype for clone(), but not the
|
|
||||||
* symbol in the shared library). */
|
|
||||||
#if defined(__ia64__)
|
|
||||||
int __clone2(int (*fn)(void *), void *stack_base, size_t stack_size, int flags, void *arg);
|
|
||||||
#define HAVE_CLONE 0
|
|
||||||
#else
|
|
||||||
/* We know that everywhere else clone() is available, so we don't bother with a meson check (that takes time
|
|
||||||
* at build time) and just define it. Once the kernel drops ia64 support, we can drop this too. */
|
|
||||||
#define HAVE_CLONE 1
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* ======================================================================= */
|
|
||||||
|
|
||||||
#if !HAVE_QUOTACTL_FD
|
|
||||||
/* since kernel v5.14 (64c2c2c62f92339b176ea24403d8db16db36f9e6) */
|
|
||||||
static inline int missing_quotactl_fd(int fd, int cmd, int id, void *addr) {
|
|
||||||
return syscall(__NR_quotactl_fd, fd, cmd, id, addr);
|
|
||||||
}
|
|
||||||
|
|
||||||
# define quotactl_fd missing_quotactl_fd
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* ======================================================================= */
|
|
||||||
|
|
||||||
#if !HAVE_SETXATTRAT
|
|
||||||
/* since kernel v6.13 (6140be90ec70c39fa844741ca3cc807dd0866394) */
|
|
||||||
static inline int missing_setxattrat(int fd, const char *path, int at_flags, const char *name, const struct xattr_args *args, size_t size) {
|
|
||||||
return syscall(__NR_setxattrat, fd, path, at_flags, name, args, size);
|
|
||||||
}
|
|
||||||
|
|
||||||
# define setxattrat missing_setxattrat
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* ======================================================================= */
|
|
||||||
|
|
||||||
#if !HAVE_REMOVEXATTRAT
|
|
||||||
/* since kernel v6.13 (6140be90ec70c39fa844741ca3cc807dd0866394) */
|
|
||||||
static inline int missing_removexattrat(int fd, const char *path, int at_flags, const char *name) {
|
|
||||||
return syscall(__NR_removexattrat, fd, path, at_flags, name);
|
|
||||||
}
|
|
||||||
|
|
||||||
# define removexattrat missing_removexattrat
|
|
||||||
#endif
|
|
@ -1,6 +1,8 @@
|
|||||||
/* SPDX-License-Identifier: LGPL-2.1-or-later */
|
/* SPDX-License-Identifier: LGPL-2.1-or-later */
|
||||||
|
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
|
#include <linux/magic.h>
|
||||||
|
#include <linux/nsfs.h>
|
||||||
#include <sched.h>
|
#include <sched.h>
|
||||||
#include <sys/ioctl.h>
|
#include <sys/ioctl.h>
|
||||||
#include <sys/mount.h>
|
#include <sys/mount.h>
|
||||||
@ -10,8 +12,6 @@
|
|||||||
#include "fd-util.h"
|
#include "fd-util.h"
|
||||||
#include "fileio.h"
|
#include "fileio.h"
|
||||||
#include "log.h"
|
#include "log.h"
|
||||||
#include "missing_magic.h"
|
|
||||||
#include "missing_namespace.h"
|
|
||||||
#include "mountpoint-util.h"
|
#include "mountpoint-util.h"
|
||||||
#include "namespace-util.h"
|
#include "namespace-util.h"
|
||||||
#include "parse-util.h"
|
#include "parse-util.h"
|
||||||
|
@ -1,5 +1,7 @@
|
|||||||
/* SPDX-License-Identifier: LGPL-2.1-or-later */
|
/* SPDX-License-Identifier: LGPL-2.1-or-later */
|
||||||
|
|
||||||
|
#include <linux/fs.h>
|
||||||
|
#include <linux/magic.h>
|
||||||
#include <sys/ioctl.h>
|
#include <sys/ioctl.h>
|
||||||
#include <threads.h>
|
#include <threads.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
@ -7,8 +9,6 @@
|
|||||||
#include "errno-util.h"
|
#include "errno-util.h"
|
||||||
#include "fd-util.h"
|
#include "fd-util.h"
|
||||||
#include "fileio.h"
|
#include "fileio.h"
|
||||||
#include "missing_fs.h"
|
|
||||||
#include "missing_magic.h"
|
|
||||||
#include "mountpoint-util.h"
|
#include "mountpoint-util.h"
|
||||||
#include "parse-util.h"
|
#include "parse-util.h"
|
||||||
#include "pidfd-util.h"
|
#include "pidfd-util.h"
|
||||||
|
@ -4,7 +4,6 @@
|
|||||||
#include <sys/pidfd.h> /* IWYU pragma: export */
|
#include <sys/pidfd.h> /* IWYU pragma: export */
|
||||||
|
|
||||||
#include "forward.h"
|
#include "forward.h"
|
||||||
#include "missing_syscall.h" /* IWYU pragma: export */
|
|
||||||
|
|
||||||
int pidfd_get_namespace(int fd, unsigned long ns_type_cmd);
|
int pidfd_get_namespace(int fd, unsigned long ns_type_cmd);
|
||||||
|
|
||||||
|
@ -34,7 +34,6 @@
|
|||||||
#include "locale-util.h"
|
#include "locale-util.h"
|
||||||
#include "log.h"
|
#include "log.h"
|
||||||
#include "memory-util.h"
|
#include "memory-util.h"
|
||||||
#include "missing_syscall.h"
|
|
||||||
#include "mountpoint-util.h"
|
#include "mountpoint-util.h"
|
||||||
#include "namespace-util.h"
|
#include "namespace-util.h"
|
||||||
#include "nulstr-util.h"
|
#include "nulstr-util.h"
|
||||||
|
84
src/basic/raw-clone.c
Normal file
84
src/basic/raw-clone.c
Normal file
@ -0,0 +1,84 @@
|
|||||||
|
/* SPDX-License-Identifier: LGPL-2.1-or-later */
|
||||||
|
|
||||||
|
/***
|
||||||
|
Copyright © 2016 Michael Karcher
|
||||||
|
***/
|
||||||
|
|
||||||
|
#include <errno.h>
|
||||||
|
#include <sched.h>
|
||||||
|
#include <sys/syscall.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
#include "process-util.h"
|
||||||
|
#include "raw-clone.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* raw_clone() - uses clone to create a new process with clone flags
|
||||||
|
* @flags: Flags to pass to the clone system call
|
||||||
|
*
|
||||||
|
* Uses the clone system call to create a new process with the cloning flags and termination signal passed in the flags
|
||||||
|
* parameter. Opposed to glibc's clone function, using this function does not set up a separate stack for the child, but
|
||||||
|
* relies on copy-on-write semantics on the one stack at a common virtual address, just as fork does.
|
||||||
|
*
|
||||||
|
* To obtain copy-on-write semantics, flags must not contain CLONE_VM, and thus CLONE_THREAD and CLONE_SIGHAND
|
||||||
|
* (which require CLONE_VM) are not usable.
|
||||||
|
*
|
||||||
|
* Additionally, as this function does not pass the ptid (pidfd in the case of CLONE_PIDFD), newtls and ctid
|
||||||
|
* parameters to the kernel, flags must not contain CLONE_PARENT_SETTID, CLONE_CHILD_SETTID, CLONE_CHILD_CLEARTID,
|
||||||
|
* CLONE_SETTLS, or CLONE_PIDFD.
|
||||||
|
*
|
||||||
|
* WARNING: 💣 this call (just like glibc's own clone() wrapper) will not synchronize on glibc's malloc
|
||||||
|
* locks, which means they will be in an undefined state in the child if the parent is
|
||||||
|
* threaded. This means: the parent must either never use threads, or the child cannot use memory
|
||||||
|
* allocation itself. This is a major pitfall, hence be careful! 💣
|
||||||
|
*
|
||||||
|
* Returns: 0 in the child process and the child process id in the parent.
|
||||||
|
*/
|
||||||
|
pid_t raw_clone(unsigned long flags) {
|
||||||
|
pid_t ret;
|
||||||
|
|
||||||
|
assert((flags & (CLONE_VM|CLONE_PARENT_SETTID|CLONE_CHILD_SETTID|CLONE_CHILD_CLEARTID|CLONE_SETTLS|CLONE_PIDFD)) == 0);
|
||||||
|
#if defined(__s390x__) || defined(__s390__) || defined(__CRIS__)
|
||||||
|
/* On s390/s390x and cris the order of the first and second arguments
|
||||||
|
* of the raw clone() system call is reversed. */
|
||||||
|
ret = (pid_t) syscall(__NR_clone, NULL, flags);
|
||||||
|
#elif defined(__sparc__)
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* sparc always returns the other process id in %o0, and
|
||||||
|
* a boolean flag whether this is the child or the parent in
|
||||||
|
* %o1. Inline assembly is needed to get the flag returned
|
||||||
|
* in %o1.
|
||||||
|
*/
|
||||||
|
int in_child, child_pid, error;
|
||||||
|
|
||||||
|
asm volatile("mov %3, %%g1\n\t"
|
||||||
|
"mov %4, %%o0\n\t"
|
||||||
|
"mov 0 , %%o1\n\t"
|
||||||
|
#if defined(__arch64__)
|
||||||
|
"t 0x6d\n\t"
|
||||||
|
#else
|
||||||
|
"t 0x10\n\t"
|
||||||
|
#endif
|
||||||
|
"addx %%g0, 0, %2\n\t"
|
||||||
|
"mov %%o1, %0\n\t"
|
||||||
|
"mov %%o0, %1" :
|
||||||
|
"=r"(in_child), "=r"(child_pid), "=r"(error) :
|
||||||
|
"i"(__NR_clone), "r"(flags) :
|
||||||
|
"%o1", "%o0", "%g1", "cc" );
|
||||||
|
|
||||||
|
if (error) {
|
||||||
|
errno = child_pid;
|
||||||
|
ret = -1;
|
||||||
|
} else
|
||||||
|
ret = in_child ? 0 : child_pid;
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
ret = (pid_t) syscall(__NR_clone, flags, NULL);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (ret == 0)
|
||||||
|
reset_cached_pid();
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
@ -1,85 +1,8 @@
|
|||||||
/* SPDX-License-Identifier: LGPL-2.1-or-later */
|
/* SPDX-License-Identifier: LGPL-2.1-or-later */
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
/***
|
#include <sched.h> /* IWYU pragma: export */
|
||||||
Copyright © 2016 Michael Karcher
|
|
||||||
***/
|
|
||||||
|
|
||||||
#include <errno.h>
|
#include "forward.h"
|
||||||
#include <sched.h>
|
|
||||||
#include <sys/syscall.h>
|
|
||||||
|
|
||||||
#include "log.h"
|
pid_t raw_clone(unsigned long flags);
|
||||||
#include "macro.h"
|
|
||||||
#include "process-util.h"
|
|
||||||
|
|
||||||
/**
|
|
||||||
* raw_clone() - uses clone to create a new process with clone flags
|
|
||||||
* @flags: Flags to pass to the clone system call
|
|
||||||
*
|
|
||||||
* Uses the clone system call to create a new process with the cloning flags and termination signal passed in the flags
|
|
||||||
* parameter. Opposed to glibc's clone function, using this function does not set up a separate stack for the child, but
|
|
||||||
* relies on copy-on-write semantics on the one stack at a common virtual address, just as fork does.
|
|
||||||
*
|
|
||||||
* To obtain copy-on-write semantics, flags must not contain CLONE_VM, and thus CLONE_THREAD and CLONE_SIGHAND
|
|
||||||
* (which require CLONE_VM) are not usable.
|
|
||||||
*
|
|
||||||
* Additionally, as this function does not pass the ptid (pidfd in the case of CLONE_PIDFD), newtls and ctid
|
|
||||||
* parameters to the kernel, flags must not contain CLONE_PARENT_SETTID, CLONE_CHILD_SETTID, CLONE_CHILD_CLEARTID,
|
|
||||||
* CLONE_SETTLS, or CLONE_PIDFD.
|
|
||||||
*
|
|
||||||
* WARNING: 💣 this call (just like glibc's own clone() wrapper) will not synchronize on glibc's malloc
|
|
||||||
* locks, which means they will be in an undefined state in the child if the parent is
|
|
||||||
* threaded. This means: the parent must either never use threads, or the child cannot use memory
|
|
||||||
* allocation itself. This is a major pitfall, hence be careful! 💣
|
|
||||||
*
|
|
||||||
* Returns: 0 in the child process and the child process id in the parent.
|
|
||||||
*/
|
|
||||||
static inline pid_t raw_clone(unsigned long flags) {
|
|
||||||
pid_t ret;
|
|
||||||
|
|
||||||
assert((flags & (CLONE_VM|CLONE_PARENT_SETTID|CLONE_CHILD_SETTID|CLONE_CHILD_CLEARTID|CLONE_SETTLS|CLONE_PIDFD)) == 0);
|
|
||||||
#if defined(__s390x__) || defined(__s390__) || defined(__CRIS__)
|
|
||||||
/* On s390/s390x and cris the order of the first and second arguments
|
|
||||||
* of the raw clone() system call is reversed. */
|
|
||||||
ret = (pid_t) syscall(__NR_clone, NULL, flags);
|
|
||||||
#elif defined(__sparc__)
|
|
||||||
{
|
|
||||||
/**
|
|
||||||
* sparc always returns the other process id in %o0, and
|
|
||||||
* a boolean flag whether this is the child or the parent in
|
|
||||||
* %o1. Inline assembly is needed to get the flag returned
|
|
||||||
* in %o1.
|
|
||||||
*/
|
|
||||||
int in_child, child_pid, error;
|
|
||||||
|
|
||||||
asm volatile("mov %3, %%g1\n\t"
|
|
||||||
"mov %4, %%o0\n\t"
|
|
||||||
"mov 0 , %%o1\n\t"
|
|
||||||
#if defined(__arch64__)
|
|
||||||
"t 0x6d\n\t"
|
|
||||||
#else
|
|
||||||
"t 0x10\n\t"
|
|
||||||
#endif
|
|
||||||
"addx %%g0, 0, %2\n\t"
|
|
||||||
"mov %%o1, %0\n\t"
|
|
||||||
"mov %%o0, %1" :
|
|
||||||
"=r"(in_child), "=r"(child_pid), "=r"(error) :
|
|
||||||
"i"(__NR_clone), "r"(flags) :
|
|
||||||
"%o1", "%o0", "%g1", "cc" );
|
|
||||||
|
|
||||||
if (error) {
|
|
||||||
errno = child_pid;
|
|
||||||
ret = -1;
|
|
||||||
} else
|
|
||||||
ret = in_child ? 0 : child_pid;
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
ret = (pid_t) syscall(__NR_clone, flags, NULL);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (ret == 0)
|
|
||||||
reset_cached_pid();
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
@ -1,15 +0,0 @@
|
|||||||
/* SPDX-License-Identifier: LGPL-2.1-or-later */
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include <linux/reboot.h>
|
|
||||||
#include <sys/reboot.h>
|
|
||||||
#include <sys/syscall.h>
|
|
||||||
#include <unistd.h>
|
|
||||||
|
|
||||||
/* glibc defines the reboot() API call, which is a wrapper around the system call of the same name, but without the
|
|
||||||
* extra "arg" parameter. Since we need that parameter for some calls, let's add a "raw" wrapper that is defined the
|
|
||||||
* same way, except it takes the additional argument. */
|
|
||||||
|
|
||||||
static inline int raw_reboot(int cmd, const void *arg) {
|
|
||||||
return (int) syscall(SYS_reboot, LINUX_REBOOT_MAGIC1, LINUX_REBOOT_MAGIC2, cmd, arg);
|
|
||||||
}
|
|
@ -4,7 +4,6 @@
|
|||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
#include "errno-util.h"
|
#include "errno-util.h"
|
||||||
#include "missing_syscall.h"
|
|
||||||
#include "parse-util.h"
|
#include "parse-util.h"
|
||||||
#include "signal-util.h"
|
#include "signal-util.h"
|
||||||
#include "stdio-util.h"
|
#include "stdio-util.h"
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
/* SPDX-License-Identifier: LGPL-2.1-or-later */
|
/* SPDX-License-Identifier: LGPL-2.1-or-later */
|
||||||
|
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
|
#include <linux/magic.h>
|
||||||
#include <sys/statvfs.h>
|
#include <sys/statvfs.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
@ -13,7 +14,6 @@
|
|||||||
#include "fs-util.h"
|
#include "fs-util.h"
|
||||||
#include "hash-funcs.h"
|
#include "hash-funcs.h"
|
||||||
#include "log.h"
|
#include "log.h"
|
||||||
#include "missing_magic.h"
|
|
||||||
#include "mountpoint-util.h"
|
#include "mountpoint-util.h"
|
||||||
#include "path-util.h"
|
#include "path-util.h"
|
||||||
#include "siphash24.h"
|
#include "siphash24.h"
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
#include <linux/kd.h>
|
#include <linux/kd.h>
|
||||||
|
#include <linux/magic.h>
|
||||||
#include <linux/tiocl.h>
|
#include <linux/tiocl.h>
|
||||||
#include <linux/vt.h>
|
#include <linux/vt.h>
|
||||||
#include <poll.h>
|
#include <poll.h>
|
||||||
@ -27,7 +28,6 @@
|
|||||||
#include "inotify-util.h"
|
#include "inotify-util.h"
|
||||||
#include "io-util.h"
|
#include "io-util.h"
|
||||||
#include "log.h"
|
#include "log.h"
|
||||||
#include "missing_magic.h"
|
|
||||||
#include "namespace-util.h"
|
#include "namespace-util.h"
|
||||||
#include "parse-util.h"
|
#include "parse-util.h"
|
||||||
#include "path-util.h"
|
#include "path-util.h"
|
||||||
|
@ -8,7 +8,6 @@
|
|||||||
#include "errno-util.h"
|
#include "errno-util.h"
|
||||||
#include "fd-util.h"
|
#include "fd-util.h"
|
||||||
#include "fs-util.h"
|
#include "fs-util.h"
|
||||||
#include "missing_syscall.h"
|
|
||||||
#include "nulstr-util.h"
|
#include "nulstr-util.h"
|
||||||
#include "parse-util.h"
|
#include "parse-util.h"
|
||||||
#include "sparse-endian.h"
|
#include "sparse-endian.h"
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
/* SPDX-License-Identifier: LGPL-2.1-or-later */
|
/* SPDX-License-Identifier: LGPL-2.1-or-later */
|
||||||
|
|
||||||
#include <fnmatch.h>
|
#include <fnmatch.h>
|
||||||
|
#include <linux/bpf.h>
|
||||||
#include <linux/bpf_insn.h>
|
#include <linux/bpf_insn.h>
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
|
|
||||||
@ -12,7 +13,6 @@
|
|||||||
#include "fd-util.h"
|
#include "fd-util.h"
|
||||||
#include "fileio.h"
|
#include "fileio.h"
|
||||||
#include "log.h"
|
#include "log.h"
|
||||||
#include "missing_bpf.h"
|
|
||||||
#include "nulstr-util.h"
|
#include "nulstr-util.h"
|
||||||
#include "parse-util.h"
|
#include "parse-util.h"
|
||||||
#include "path-util.h"
|
#include "path-util.h"
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
/* SPDX-License-Identifier: LGPL-2.1-or-later */
|
/* SPDX-License-Identifier: LGPL-2.1-or-later */
|
||||||
|
|
||||||
#include <linux/bpf.h>
|
#include <linux/bpf.h>
|
||||||
|
#include <linux/magic.h>
|
||||||
|
|
||||||
#include "alloc-util.h"
|
#include "alloc-util.h"
|
||||||
#include "bpf-foreign.h"
|
#include "bpf-foreign.h"
|
||||||
@ -8,7 +9,6 @@
|
|||||||
#include "cgroup.h"
|
#include "cgroup.h"
|
||||||
#include "hash-funcs.h"
|
#include "hash-funcs.h"
|
||||||
#include "hashmap.h"
|
#include "hashmap.h"
|
||||||
#include "missing_magic.h"
|
|
||||||
#include "siphash24.h"
|
#include "siphash24.h"
|
||||||
#include "stat-util.h"
|
#include "stat-util.h"
|
||||||
#include "unit.h"
|
#include "unit.h"
|
||||||
|
@ -1,12 +1,10 @@
|
|||||||
/* SPDX-License-Identifier: LGPL-2.1-or-later */
|
/* SPDX-License-Identifier: LGPL-2.1-or-later */
|
||||||
|
|
||||||
#include <sys/reboot.h>
|
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
#include "ansi-color.h"
|
#include "ansi-color.h"
|
||||||
#include "emergency-action.h"
|
#include "emergency-action.h"
|
||||||
#include "manager.h"
|
#include "manager.h"
|
||||||
#include "raw-reboot.h"
|
|
||||||
#include "reboot-util.h"
|
#include "reboot-util.h"
|
||||||
#include "special.h"
|
#include "special.h"
|
||||||
#include "string-table.h"
|
#include "string-table.h"
|
||||||
|
@ -1,13 +1,14 @@
|
|||||||
/* SPDX-License-Identifier: LGPL-2.1-or-later */
|
/* SPDX-License-Identifier: LGPL-2.1-or-later */
|
||||||
|
|
||||||
#include <grp.h>
|
#include <grp.h>
|
||||||
#include <linux/ioprio.h>
|
|
||||||
#include <linux/prctl.h>
|
#include <linux/prctl.h>
|
||||||
#include <linux/sched.h>
|
#include <linux/sched.h>
|
||||||
#include <linux/securebits.h>
|
#include <linux/securebits.h>
|
||||||
#include <poll.h>
|
#include <poll.h>
|
||||||
#include <sys/eventfd.h>
|
#include <sys/eventfd.h>
|
||||||
#include <sys/ioctl.h>
|
#include <sys/ioctl.h>
|
||||||
|
#include <sys/ioprio.h>
|
||||||
|
#include <sys/keyctl.h>
|
||||||
#include <sys/mount.h>
|
#include <sys/mount.h>
|
||||||
#include <sys/prctl.h>
|
#include <sys/prctl.h>
|
||||||
#include <sys/statvfs.h>
|
#include <sys/statvfs.h>
|
||||||
@ -54,7 +55,6 @@
|
|||||||
#include "journal-send.h"
|
#include "journal-send.h"
|
||||||
#include "manager.h"
|
#include "manager.h"
|
||||||
#include "memfd-util.h"
|
#include "memfd-util.h"
|
||||||
#include "missing_syscall.h"
|
|
||||||
#include "mkdir-label.h"
|
#include "mkdir-label.h"
|
||||||
#include "mount-util.h"
|
#include "mount-util.h"
|
||||||
#include "namespace-util.h"
|
#include "namespace-util.h"
|
||||||
|
@ -100,15 +100,34 @@ load_fragment_gperf_nulstr_c = custom_target(
|
|||||||
command : [awk, '-f', '@INPUT0@', '@INPUT1@'],
|
command : [awk, '-f', '@INPUT0@', '@INPUT1@'],
|
||||||
capture : true)
|
capture : true)
|
||||||
|
|
||||||
generated_sources += [load_fragment_gperf_c, load_fragment_gperf_nulstr_c]
|
generate_bpf_delegate_configs = files('generate-bpf-delegate-configs.py')
|
||||||
|
bpf_delegate_configs_inc = custom_target(
|
||||||
|
input : [generate_bpf_delegate_configs, bpf_delegate_sources],
|
||||||
|
output : 'bpf-delegate-configs.inc',
|
||||||
|
command : [python,
|
||||||
|
generate_bpf_delegate_configs,
|
||||||
|
'code',
|
||||||
|
bpf_delegate_sources],
|
||||||
|
capture : true)
|
||||||
|
|
||||||
|
bpf_delegate_xml = custom_target(
|
||||||
|
input : [generate_bpf_delegate_configs, bpf_delegate_sources],
|
||||||
|
output : 'bpf-delegate.xml',
|
||||||
|
command : [python,
|
||||||
|
generate_bpf_delegate_configs,
|
||||||
|
'doc',
|
||||||
|
bpf_delegate_sources],
|
||||||
|
capture : true)
|
||||||
|
man_page_depends += bpf_delegate_xml
|
||||||
|
|
||||||
|
generated_sources += [load_fragment_gperf_c, load_fragment_gperf_nulstr_c, bpf_delegate_configs_inc]
|
||||||
|
libcore_sources += [load_fragment_gperf_c, load_fragment_gperf_nulstr_c, bpf_delegate_configs_inc]
|
||||||
|
libcore_build_dir = meson.current_build_dir()
|
||||||
libcore_name = 'systemd-core-@0@'.format(shared_lib_tag)
|
libcore_name = 'systemd-core-@0@'.format(shared_lib_tag)
|
||||||
|
|
||||||
libcore_static = static_library(
|
libcore_static = static_library(
|
||||||
libcore_name,
|
libcore_name,
|
||||||
libcore_sources,
|
libcore_sources,
|
||||||
load_fragment_gperf_c,
|
|
||||||
load_fragment_gperf_nulstr_c,
|
|
||||||
include_directories : [includes, include_directories('.')],
|
include_directories : [includes, include_directories('.')],
|
||||||
implicit_include_directories : false,
|
implicit_include_directories : false,
|
||||||
c_args : ['-fvisibility=default'],
|
c_args : ['-fvisibility=default'],
|
||||||
@ -162,6 +181,7 @@ executor_libs = get_option('link-executor-shared') ? \
|
|||||||
libcore,
|
libcore,
|
||||||
libshared,
|
libshared,
|
||||||
] : [
|
] : [
|
||||||
|
libc_wrapper_static,
|
||||||
libcore_static,
|
libcore_static,
|
||||||
libshared_static,
|
libshared_static,
|
||||||
libbasic_static,
|
libbasic_static,
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
/* SPDX-License-Identifier: LGPL-2.1-or-later */
|
/* SPDX-License-Identifier: LGPL-2.1-or-later */
|
||||||
|
|
||||||
#include <linux/loop.h>
|
#include <linux/loop.h>
|
||||||
|
#include <linux/magic.h>
|
||||||
#include <sched.h>
|
#include <sched.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
@ -29,7 +30,6 @@
|
|||||||
#include "log.h"
|
#include "log.h"
|
||||||
#include "loop-util.h"
|
#include "loop-util.h"
|
||||||
#include "loopback-setup.h"
|
#include "loopback-setup.h"
|
||||||
#include "missing_magic.h"
|
|
||||||
#include "mkdir-label.h"
|
#include "mkdir-label.h"
|
||||||
#include "mount-util.h"
|
#include "mount-util.h"
|
||||||
#include "mountpoint-util.h"
|
#include "mountpoint-util.h"
|
||||||
|
@ -9,6 +9,7 @@
|
|||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
#include "sd-bus.h"
|
#include "sd-bus.h"
|
||||||
|
#include "sd-varlink.h"
|
||||||
|
|
||||||
#include "alloc-util.h"
|
#include "alloc-util.h"
|
||||||
#include "audit-fd.h"
|
#include "audit-fd.h"
|
||||||
@ -26,6 +27,7 @@ static bool initialized = false;
|
|||||||
|
|
||||||
struct audit_info {
|
struct audit_info {
|
||||||
sd_bus_creds *creds;
|
sd_bus_creds *creds;
|
||||||
|
sd_varlink *link;
|
||||||
const char *path;
|
const char *path;
|
||||||
const char *cmdline;
|
const char *cmdline;
|
||||||
const char *function;
|
const char *function;
|
||||||
@ -48,12 +50,23 @@ static int audit_callback(
|
|||||||
char uid_buf[DECIMAL_STR_MAX(uid_t) + 1] = "n/a";
|
char uid_buf[DECIMAL_STR_MAX(uid_t) + 1] = "n/a";
|
||||||
char gid_buf[DECIMAL_STR_MAX(gid_t) + 1] = "n/a";
|
char gid_buf[DECIMAL_STR_MAX(gid_t) + 1] = "n/a";
|
||||||
|
|
||||||
|
if (audit->creds) {
|
||||||
|
/* DBus case */
|
||||||
if (sd_bus_creds_get_audit_login_uid(audit->creds, &login_uid) >= 0)
|
if (sd_bus_creds_get_audit_login_uid(audit->creds, &login_uid) >= 0)
|
||||||
xsprintf(login_uid_buf, UID_FMT, login_uid);
|
xsprintf(login_uid_buf, UID_FMT, login_uid);
|
||||||
if (sd_bus_creds_get_euid(audit->creds, &uid) >= 0)
|
if (sd_bus_creds_get_euid(audit->creds, &uid) >= 0)
|
||||||
xsprintf(uid_buf, UID_FMT, uid);
|
xsprintf(uid_buf, UID_FMT, uid);
|
||||||
if (sd_bus_creds_get_egid(audit->creds, &gid) >= 0)
|
if (sd_bus_creds_get_egid(audit->creds, &gid) >= 0)
|
||||||
xsprintf(gid_buf, GID_FMT, gid);
|
xsprintf(gid_buf, GID_FMT, gid);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (audit->link) {
|
||||||
|
/* varlink */
|
||||||
|
if (sd_varlink_get_peer_uid(audit->link, &uid) >= 0)
|
||||||
|
xsprintf(uid_buf, UID_FMT, uid);
|
||||||
|
if (sd_varlink_get_peer_gid(audit->link, &gid) >= 0)
|
||||||
|
xsprintf(gid_buf, GID_FMT, gid);
|
||||||
|
}
|
||||||
|
|
||||||
(void) snprintf(msgbuf, msgbufsize,
|
(void) snprintf(msgbuf, msgbufsize,
|
||||||
"auid=%s uid=%s gid=%s%s%s%s%s%s%s%s%s%s",
|
"auid=%s uid=%s gid=%s%s%s%s%s%s%s%s%s%s",
|
||||||
@ -164,13 +177,85 @@ static int access_init(sd_bus_error *error) {
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int get_our_contexts(const Unit *unit, const char **ret_acon, const char **ret_tclass, char **ret_fcon) {
|
||||||
|
_cleanup_freecon_ char *fcon = NULL;
|
||||||
|
|
||||||
|
assert(ret_acon);
|
||||||
|
assert(ret_tclass);
|
||||||
|
assert(ret_fcon);
|
||||||
|
|
||||||
|
if (unit && unit->access_selinux_context) {
|
||||||
|
/* Nice! The unit comes with a SELinux context read from the unit file */
|
||||||
|
*ret_acon = unit->access_selinux_context;
|
||||||
|
*ret_tclass = "service";
|
||||||
|
*ret_fcon = NULL;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* If no unit context is known, use our own */
|
||||||
|
|
||||||
|
/* Ideally, we should call mac_selinux_get_our_label() here because it
|
||||||
|
* does exactly the same - call getcon_raw(). However, it involves
|
||||||
|
* selinux_init() which opens label DB. It was not part of the
|
||||||
|
* original code. I don't want to change it for now. */
|
||||||
|
if (getcon_raw(&fcon) < 0)
|
||||||
|
return log_debug_errno(errno, "SELinux getcon_raw() failed: %m");
|
||||||
|
|
||||||
|
if (!fcon)
|
||||||
|
return log_debug_errno(SYNTHETIC_ERRNO(EOPNOTSUPP), "SELinux returned no context of the current process");
|
||||||
|
|
||||||
|
*ret_acon = fcon;
|
||||||
|
*ret_tclass = "system";
|
||||||
|
*ret_fcon = TAKE_PTR(fcon);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int check_access(
|
||||||
|
const char *scon,
|
||||||
|
const char *tcon,
|
||||||
|
const char *tclass,
|
||||||
|
const char *permission,
|
||||||
|
struct audit_info *audit_info,
|
||||||
|
sd_bus_error *error) {
|
||||||
|
|
||||||
|
bool enforce = mac_selinux_enforcing();
|
||||||
|
int r;
|
||||||
|
|
||||||
|
assert(scon);
|
||||||
|
assert(tcon);
|
||||||
|
assert(tclass);
|
||||||
|
assert(permission);
|
||||||
|
assert(audit_info);
|
||||||
|
assert(audit_info->function);
|
||||||
|
|
||||||
|
r = selinux_check_access(scon, tcon, tclass, permission, &audit_info);
|
||||||
|
if (r < 0) {
|
||||||
|
errno = -(r = errno_or_else(EPERM));
|
||||||
|
|
||||||
|
if (enforce)
|
||||||
|
sd_bus_error_setf(error, SD_BUS_ERROR_ACCESS_DENIED, "SELinux policy denies access: %m");
|
||||||
|
}
|
||||||
|
|
||||||
|
return log_selinux_enforcing_errno(
|
||||||
|
r,
|
||||||
|
"SELinux access check scon=%s tcon=%s tclass=%s perm=%s state=%s function=%s path=%s cmdline=%s: %m",
|
||||||
|
scon,
|
||||||
|
tcon,
|
||||||
|
tclass,
|
||||||
|
permission,
|
||||||
|
enforce ? "enforcing" : "permissive",
|
||||||
|
audit_info->function,
|
||||||
|
empty_to_na(audit_info->path),
|
||||||
|
empty_to_na(audit_info->cmdline));
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
This function communicates with the kernel to check whether or not it should
|
This function communicates with the kernel to check whether or not it should
|
||||||
allow the access.
|
allow the access.
|
||||||
If the machine is in permissive mode it will return ok. Audit messages will
|
If the machine is in permissive mode it will return ok. Audit messages will
|
||||||
still be generated if the access would be denied in enforcing mode.
|
still be generated if the access would be denied in enforcing mode.
|
||||||
*/
|
*/
|
||||||
int mac_selinux_access_check_internal(
|
int mac_selinux_access_check_bus_internal(
|
||||||
sd_bus_message *message,
|
sd_bus_message *message,
|
||||||
const Unit *unit,
|
const Unit *unit,
|
||||||
const char *permission,
|
const char *permission,
|
||||||
@ -216,31 +301,22 @@ int mac_selinux_access_check_internal(
|
|||||||
if (r < 0)
|
if (r < 0)
|
||||||
return r;
|
return r;
|
||||||
|
|
||||||
if (unit && unit->access_selinux_context) {
|
r = get_our_contexts(unit, &acon, &tclass, &fcon);
|
||||||
/* Nice! The unit comes with a SELinux context read from the unit file */
|
if (r < 0) {
|
||||||
acon = unit->access_selinux_context;
|
log_selinux_enforcing_errno(
|
||||||
tclass = "service";
|
r,
|
||||||
} else {
|
"Failed to retrieves SELinux context of current process (perm=%s)%s: %m",
|
||||||
/* If no unit context is known, use our own */
|
permission,
|
||||||
if (getcon_raw(&fcon) < 0) {
|
enforce ? "" : ", ignoring");
|
||||||
log_warning_errno(errno, "SELinux getcon_raw() failed%s (perm=%s): %m",
|
|
||||||
enforce ? "" : ", ignoring",
|
|
||||||
permission);
|
|
||||||
if (!enforce)
|
if (!enforce)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
if (r == -EOPNOTSUPP)
|
||||||
|
return sd_bus_error_setf(error, SD_BUS_ERROR_ACCESS_DENIED, "We appear not to have any SELinux context: %m");
|
||||||
|
|
||||||
return sd_bus_error_setf(error, SD_BUS_ERROR_ACCESS_DENIED, "Failed to get current context: %m");
|
return sd_bus_error_setf(error, SD_BUS_ERROR_ACCESS_DENIED, "Failed to get current context: %m");
|
||||||
}
|
}
|
||||||
if (!fcon) {
|
|
||||||
if (!enforce)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
return sd_bus_error_setf(error, SD_BUS_ERROR_ACCESS_DENIED, "We appear not to have any SELinux context: %m");
|
|
||||||
}
|
|
||||||
|
|
||||||
acon = fcon;
|
|
||||||
tclass = "system";
|
|
||||||
}
|
|
||||||
|
|
||||||
(void) sd_bus_creds_get_cmdline(creds, &cmdline);
|
(void) sd_bus_creds_get_cmdline(creds, &cmdline);
|
||||||
cl = strv_join(cmdline, " ");
|
cl = strv_join(cmdline, " ");
|
||||||
@ -252,23 +328,67 @@ int mac_selinux_access_check_internal(
|
|||||||
.function = function,
|
.function = function,
|
||||||
};
|
};
|
||||||
|
|
||||||
r = selinux_check_access(scon, acon, tclass, permission, &audit_info);
|
return check_access(scon, acon, tclass, permission, &audit_info, error);
|
||||||
if (r < 0) {
|
|
||||||
errno = -(r = errno_or_else(EPERM));
|
|
||||||
|
|
||||||
if (enforce)
|
|
||||||
sd_bus_error_setf(error, SD_BUS_ERROR_ACCESS_DENIED, "SELinux policy denies access: %m");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
log_full_errno_zerook(LOG_DEBUG, r,
|
int mac_selinux_access_check_varlink_internal(
|
||||||
"SELinux access check scon=%s tcon=%s tclass=%s perm=%s state=%s function=%s path=%s cmdline=%s: %m",
|
sd_varlink *link,
|
||||||
scon, acon, tclass, permission, enforce ? "enforcing" : "permissive", function, strna(unit ? unit->fragment_path : NULL), empty_to_na(cl));
|
const Unit *unit,
|
||||||
return enforce ? r : 0;
|
const char *permission,
|
||||||
|
const char *function) {
|
||||||
|
|
||||||
|
_cleanup_freecon_ char *fcon = NULL, *scon = NULL;
|
||||||
|
const char *tclass, *acon;
|
||||||
|
int r;
|
||||||
|
|
||||||
|
assert(link);
|
||||||
|
assert(permission);
|
||||||
|
assert(function);
|
||||||
|
|
||||||
|
r = access_init(/* error= */ NULL);
|
||||||
|
if (r <= 0)
|
||||||
|
return log_debug_errno(r, "Failed to init SELinux: %m");
|
||||||
|
|
||||||
|
/* delay call until we checked in `access_init()` if SELinux is actually enabled */
|
||||||
|
bool enforce = mac_selinux_enforcing();
|
||||||
|
|
||||||
|
int fd = sd_varlink_get_fd(link);
|
||||||
|
if (fd < 0)
|
||||||
|
return log_debug_errno(fd, "Failed to get varlink peer fd: %m");
|
||||||
|
|
||||||
|
/* We should call mac_selinux_get_peer_label() here similarly to get_our_contexts().
|
||||||
|
* See the explanation there why not. */
|
||||||
|
if (getpeercon_raw(fd, &scon) < 0)
|
||||||
|
return log_selinux_enforcing_errno(
|
||||||
|
errno,
|
||||||
|
"Failed to get peer SELinux context%s: %m",
|
||||||
|
enforce ? "" : ", ignoring");
|
||||||
|
|
||||||
|
if (!scon)
|
||||||
|
return log_selinux_enforcing_errno(
|
||||||
|
SYNTHETIC_ERRNO(EOPNOTSUPP),
|
||||||
|
"Peer does not have SELinux context");
|
||||||
|
|
||||||
|
r = get_our_contexts(unit, &acon, &tclass, &fcon);
|
||||||
|
if (r < 0)
|
||||||
|
return log_selinux_enforcing_errno(
|
||||||
|
r,
|
||||||
|
"Failed to retrieves SELinux context of current process (perm=%s)%s: %m",
|
||||||
|
permission,
|
||||||
|
enforce ? "" : ", ignoring");
|
||||||
|
|
||||||
|
struct audit_info audit_info = {
|
||||||
|
.link = link,
|
||||||
|
.path = unit ? unit->fragment_path : NULL,
|
||||||
|
.function = function,
|
||||||
|
};
|
||||||
|
|
||||||
|
return check_access(scon, acon, tclass, permission, &audit_info, /* error= */ NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
#else /* HAVE_SELINUX */
|
#else /* HAVE_SELINUX */
|
||||||
|
|
||||||
int mac_selinux_access_check_internal(
|
int mac_selinux_access_check_bus_internal(
|
||||||
sd_bus_message *message,
|
sd_bus_message *message,
|
||||||
const Unit *unit,
|
const Unit *unit,
|
||||||
const char *permission,
|
const char *permission,
|
||||||
@ -278,4 +398,12 @@ int mac_selinux_access_check_internal(
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int mac_selinux_access_check_varlink_internal(
|
||||||
|
sd_varlink *link,
|
||||||
|
const Unit *unit,
|
||||||
|
const char *permission,
|
||||||
|
const char *function) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
#endif /* HAVE_SELINUX */
|
#endif /* HAVE_SELINUX */
|
||||||
|
@ -3,10 +3,17 @@
|
|||||||
|
|
||||||
#include "core-forward.h"
|
#include "core-forward.h"
|
||||||
|
|
||||||
int mac_selinux_access_check_internal(sd_bus_message *message, const Unit *unit, const char *permission, const char *function, sd_bus_error *error);
|
int mac_selinux_access_check_bus_internal(sd_bus_message *message, const Unit *unit, const char *permission, const char *function, sd_bus_error *error);
|
||||||
|
int mac_selinux_access_check_varlink_internal(sd_varlink *link, const Unit *unit, const char *permission, const char *function);
|
||||||
|
|
||||||
#define mac_selinux_access_check(message, permission, error) \
|
#define mac_selinux_access_check(message, permission, error) \
|
||||||
mac_selinux_access_check_internal((message), NULL, (permission), __func__, (error))
|
mac_selinux_access_check_bus_internal((message), NULL, (permission), __func__, (error))
|
||||||
|
|
||||||
#define mac_selinux_unit_access_check(unit, message, permission, error) \
|
#define mac_selinux_unit_access_check(unit, message, permission, error) \
|
||||||
mac_selinux_access_check_internal((message), (unit), (permission), __func__, (error))
|
mac_selinux_access_check_bus_internal((message), (unit), (permission), __func__, (error))
|
||||||
|
|
||||||
|
#define mac_selinux_access_check_varlink(link, permission) \
|
||||||
|
mac_selinux_access_check_varlink_internal((link), NULL, (permission), __func__)
|
||||||
|
|
||||||
|
#define mac_selinux_unit_access_check_varlink(unit, link, permission) \
|
||||||
|
mac_selinux_access_check_bus_internal((link), (unit), (permission), __func__)
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
/* SPDX-License-Identifier: LGPL-2.1-or-later */
|
/* SPDX-License-Identifier: LGPL-2.1-or-later */
|
||||||
|
|
||||||
|
#include <linux/audit.h>
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
@ -31,7 +32,6 @@
|
|||||||
#include "image-policy.h"
|
#include "image-policy.h"
|
||||||
#include "log.h"
|
#include "log.h"
|
||||||
#include "manager.h"
|
#include "manager.h"
|
||||||
#include "missing_audit.h"
|
|
||||||
#include "mount-util.h"
|
#include "mount-util.h"
|
||||||
#include "namespace.h"
|
#include "namespace.h"
|
||||||
#include "open-file.h"
|
#include "open-file.h"
|
||||||
|
@ -39,48 +39,7 @@ static int manager_environment_build_json(sd_json_variant **ret, const char *nam
|
|||||||
return sd_json_variant_new_array_strv(ret, l);
|
return sd_json_variant_new_array_strv(ret, l);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int manager_context_build_json(sd_json_variant **ret, const char *name, void *userdata) {
|
static int log_level_build_json(sd_json_variant **ret, const char *name, void *userdata) {
|
||||||
Manager *m = ASSERT_PTR(userdata);
|
|
||||||
_cleanup_strv_free_ char **taints = NULL;
|
|
||||||
|
|
||||||
taints = taint_strv();
|
|
||||||
if (!taints)
|
|
||||||
return -ENOMEM;
|
|
||||||
|
|
||||||
return sd_json_buildo(
|
|
||||||
ASSERT_PTR(ret),
|
|
||||||
SD_JSON_BUILD_PAIR_STRING("Version", GIT_VERSION),
|
|
||||||
SD_JSON_BUILD_PAIR_STRING("Architecture", architecture_to_string(uname_architecture())),
|
|
||||||
SD_JSON_BUILD_PAIR_STRING("Features", systemd_features),
|
|
||||||
JSON_BUILD_PAIR_STRV_NON_EMPTY("Taints", taints),
|
|
||||||
SD_JSON_BUILD_PAIR_STRV("UnitPath", m->lookup_paths.search_path),
|
|
||||||
JSON_BUILD_PAIR_STRV_NON_EMPTY("Environment", m->transient_environment),
|
|
||||||
SD_JSON_BUILD_PAIR_STRING("DefaultStandardOutput", exec_output_to_string(m->defaults.std_output)),
|
|
||||||
SD_JSON_BUILD_PAIR_STRING("DefaultStandardError", exec_output_to_string(m->defaults.std_error)),
|
|
||||||
SD_JSON_BUILD_PAIR_BOOLEAN("ServiceWatchdogs", m->service_watchdogs),
|
|
||||||
JSON_BUILD_PAIR_FINITE_USEC("DefaultTimerAccuracyUSec", m->defaults.timer_accuracy_usec),
|
|
||||||
JSON_BUILD_PAIR_FINITE_USEC("DefaultTimeoutStartUSec", m->defaults.timeout_start_usec),
|
|
||||||
JSON_BUILD_PAIR_FINITE_USEC("DefaultTimeoutStopUSec", m->defaults.timeout_stop_usec),
|
|
||||||
JSON_BUILD_PAIR_FINITE_USEC("DefaultTimeoutAbortUSec", manager_default_timeout_abort_usec(m)),
|
|
||||||
JSON_BUILD_PAIR_FINITE_USEC("DefaultDeviceTimeoutUSec", m->defaults.device_timeout_usec),
|
|
||||||
JSON_BUILD_PAIR_FINITE_USEC("DefaultRestartUSec", m->defaults.restart_usec),
|
|
||||||
JSON_BUILD_PAIR_RATELIMIT("DefaultStartLimit", &m->defaults.start_limit),
|
|
||||||
SD_JSON_BUILD_PAIR_BOOLEAN("DefaultIOAccounting", m->defaults.io_accounting),
|
|
||||||
SD_JSON_BUILD_PAIR_BOOLEAN("DefaultIPAccounting", m->defaults.ip_accounting),
|
|
||||||
SD_JSON_BUILD_PAIR_BOOLEAN("DefaultMemoryAccounting", m->defaults.memory_accounting),
|
|
||||||
SD_JSON_BUILD_PAIR_BOOLEAN("DefaultTasksAccounting", m->defaults.tasks_accounting),
|
|
||||||
SD_JSON_BUILD_PAIR_CALLBACK("DefaultLimits", rlimit_table_build_json, m->defaults.rlimit),
|
|
||||||
SD_JSON_BUILD_PAIR_UNSIGNED("DefaultTasksMax", cgroup_tasks_max_resolve(&m->defaults.tasks_max)),
|
|
||||||
JSON_BUILD_PAIR_FINITE_USEC("DefaultMemoryPressureThresholdUSec", m->defaults.memory_pressure_threshold_usec),
|
|
||||||
SD_JSON_BUILD_PAIR_STRING("DefaultMemoryPressureWatch", cgroup_pressure_watch_to_string(m->defaults.memory_pressure_watch)),
|
|
||||||
JSON_BUILD_PAIR_FINITE_USEC("TimerSlackNSec", (uint64_t) prctl(PR_GET_TIMERSLACK)),
|
|
||||||
SD_JSON_BUILD_PAIR_STRING("DefaultOOMPolicy", oom_policy_to_string(m->defaults.oom_policy)),
|
|
||||||
SD_JSON_BUILD_PAIR_INTEGER("DefaultOOMScoreAdjust", m->defaults.oom_score_adjust),
|
|
||||||
SD_JSON_BUILD_PAIR_BOOLEAN("DefaultRestrictSUIDSGID", m->defaults.restrict_suid_sgid),
|
|
||||||
SD_JSON_BUILD_PAIR_STRING("CtrlAltDelBurstAction", emergency_action_to_string(m->cad_burst_action)));
|
|
||||||
}
|
|
||||||
|
|
||||||
static int log_level_build_runtime_json(sd_json_variant **ret, const char *name, void *userdata) {
|
|
||||||
_cleanup_(sd_json_variant_unrefp) sd_json_variant *v = NULL;
|
_cleanup_(sd_json_variant_unrefp) sd_json_variant *v = NULL;
|
||||||
int log_max_level = log_get_max_level();
|
int log_max_level = log_get_max_level();
|
||||||
int r;
|
int r;
|
||||||
@ -107,15 +66,70 @@ static int log_level_build_runtime_json(sd_json_variant **ret, const char *name,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int manager_runtime_build_json(sd_json_variant **ret, const char *name, void *userdata) {
|
static int manager_context_build_json(sd_json_variant **ret, const char *name, void *userdata) {
|
||||||
Manager *m = ASSERT_PTR(userdata);
|
Manager *m = ASSERT_PTR(userdata);
|
||||||
dual_timestamp watchdog_last_ping;
|
|
||||||
|
/* The main principle behind context/runtime split is the following:
|
||||||
|
* If it make sense to place a property into a config/unit file it belongs to Context.
|
||||||
|
* Otherwise it's a 'Runtime'. */
|
||||||
|
|
||||||
return sd_json_buildo(
|
return sd_json_buildo(
|
||||||
ASSERT_PTR(ret),
|
ASSERT_PTR(ret),
|
||||||
|
SD_JSON_BUILD_PAIR_BOOLEAN("ShowStatus", manager_get_show_status_on(m)),
|
||||||
|
JSON_BUILD_PAIR_CALLBACK_NON_NULL("LogLevel", log_level_build_json, m),
|
||||||
|
SD_JSON_BUILD_PAIR_STRING("LogTarget", log_target_to_string(log_get_target())),
|
||||||
|
JSON_BUILD_PAIR_CALLBACK_NON_NULL("Environment", manager_environment_build_json, m),
|
||||||
|
SD_JSON_BUILD_PAIR_STRING("DefaultStandardOutput", exec_output_to_string(m->defaults.std_output)),
|
||||||
|
SD_JSON_BUILD_PAIR_STRING("DefaultStandardError", exec_output_to_string(m->defaults.std_error)),
|
||||||
|
SD_JSON_BUILD_PAIR_BOOLEAN("ServiceWatchdogs", m->service_watchdogs),
|
||||||
|
JSON_BUILD_PAIR_FINITE_USEC("DefaultTimerAccuracyUSec", m->defaults.timer_accuracy_usec),
|
||||||
|
JSON_BUILD_PAIR_FINITE_USEC("DefaultTimeoutStartUSec", m->defaults.timeout_start_usec),
|
||||||
|
JSON_BUILD_PAIR_FINITE_USEC("DefaultTimeoutStopUSec", m->defaults.timeout_stop_usec),
|
||||||
|
JSON_BUILD_PAIR_FINITE_USEC("DefaultTimeoutAbortUSec", manager_default_timeout_abort_usec(m)),
|
||||||
|
JSON_BUILD_PAIR_FINITE_USEC("DefaultDeviceTimeoutUSec", m->defaults.device_timeout_usec),
|
||||||
|
JSON_BUILD_PAIR_FINITE_USEC("DefaultRestartUSec", m->defaults.restart_usec),
|
||||||
|
JSON_BUILD_PAIR_RATELIMIT("DefaultStartLimit", &m->defaults.start_limit),
|
||||||
|
SD_JSON_BUILD_PAIR_BOOLEAN("DefaultIOAccounting", m->defaults.io_accounting),
|
||||||
|
SD_JSON_BUILD_PAIR_BOOLEAN("DefaultIPAccounting", m->defaults.ip_accounting),
|
||||||
|
SD_JSON_BUILD_PAIR_BOOLEAN("DefaultMemoryAccounting", m->defaults.memory_accounting),
|
||||||
|
SD_JSON_BUILD_PAIR_BOOLEAN("DefaultTasksAccounting", m->defaults.tasks_accounting),
|
||||||
|
SD_JSON_BUILD_PAIR_CALLBACK("DefaultLimits", rlimit_table_build_json, m->defaults.rlimit),
|
||||||
|
SD_JSON_BUILD_PAIR_UNSIGNED("DefaultTasksMax", cgroup_tasks_max_resolve(&m->defaults.tasks_max)),
|
||||||
|
JSON_BUILD_PAIR_FINITE_USEC("DefaultMemoryPressureThresholdUSec", m->defaults.memory_pressure_threshold_usec),
|
||||||
|
SD_JSON_BUILD_PAIR_STRING("DefaultMemoryPressureWatch", cgroup_pressure_watch_to_string(m->defaults.memory_pressure_watch)),
|
||||||
|
JSON_BUILD_PAIR_FINITE_USEC("RuntimeWatchdogUSec", manager_get_watchdog(m, WATCHDOG_RUNTIME)),
|
||||||
|
JSON_BUILD_PAIR_FINITE_USEC("RebootWatchdogUSec", manager_get_watchdog(m, WATCHDOG_REBOOT)),
|
||||||
|
JSON_BUILD_PAIR_FINITE_USEC("KExecWatchdogUSec", manager_get_watchdog(m, WATCHDOG_KEXEC)),
|
||||||
|
JSON_BUILD_PAIR_FINITE_USEC("RuntimeWatchdogPreUSec", manager_get_watchdog(m, WATCHDOG_PRETIMEOUT)),
|
||||||
|
JSON_BUILD_PAIR_STRING_NON_EMPTY("RuntimeWatchdogPreGovernor", m->watchdog_pretimeout_governor),
|
||||||
|
JSON_BUILD_PAIR_STRING_NON_EMPTY("WatchdogDevice", watchdog_get_device()),
|
||||||
|
JSON_BUILD_PAIR_FINITE_USEC("TimerSlackNSec", (uint64_t) prctl(PR_GET_TIMERSLACK)),
|
||||||
|
SD_JSON_BUILD_PAIR_STRING("DefaultOOMPolicy", oom_policy_to_string(m->defaults.oom_policy)),
|
||||||
|
SD_JSON_BUILD_PAIR_INTEGER("DefaultOOMScoreAdjust", m->defaults.oom_score_adjust),
|
||||||
|
SD_JSON_BUILD_PAIR_BOOLEAN("DefaultRestrictSUIDSGID", m->defaults.restrict_suid_sgid),
|
||||||
|
SD_JSON_BUILD_PAIR_STRING("CtrlAltDelBurstAction", emergency_action_to_string(m->cad_burst_action)),
|
||||||
|
JSON_BUILD_PAIR_STRING_NON_EMPTY("ConfirmSpawn", manager_get_confirm_spawn(m)),
|
||||||
|
JSON_BUILD_PAIR_STRING_NON_EMPTY("ControlGroup", m->cgroup_root));
|
||||||
|
}
|
||||||
|
|
||||||
|
static int manager_runtime_build_json(sd_json_variant **ret, const char *name, void *userdata) {
|
||||||
|
Manager *m = ASSERT_PTR(userdata);
|
||||||
|
dual_timestamp watchdog_last_ping;
|
||||||
|
_cleanup_strv_free_ char **taints = NULL;
|
||||||
|
|
||||||
|
taints = taint_strv();
|
||||||
|
if (!taints)
|
||||||
|
return -ENOMEM;
|
||||||
|
|
||||||
|
return sd_json_buildo(
|
||||||
|
ASSERT_PTR(ret),
|
||||||
|
SD_JSON_BUILD_PAIR_STRING("Version", GIT_VERSION),
|
||||||
|
SD_JSON_BUILD_PAIR_STRING("Architecture", architecture_to_string(uname_architecture())),
|
||||||
|
SD_JSON_BUILD_PAIR_STRING("Features", systemd_features),
|
||||||
|
JSON_BUILD_PAIR_STRV_NON_EMPTY("Taints", taints),
|
||||||
|
SD_JSON_BUILD_PAIR_STRV("UnitPath", m->lookup_paths.search_path),
|
||||||
SD_JSON_BUILD_PAIR_STRING("Virtualization", virtualization_to_string(detect_virtualization())),
|
SD_JSON_BUILD_PAIR_STRING("Virtualization", virtualization_to_string(detect_virtualization())),
|
||||||
SD_JSON_BUILD_PAIR_STRING("ConfidentialVirtualization", confidential_virtualization_to_string(detect_confidential_virtualization())),
|
SD_JSON_BUILD_PAIR_STRING("ConfidentialVirtualization", confidential_virtualization_to_string(detect_confidential_virtualization())),
|
||||||
JSON_BUILD_PAIR_STRING_NON_EMPTY("ConfirmSpawn", manager_get_confirm_spawn(m)),
|
|
||||||
JSON_BUILD_PAIR_DUAL_TIMESTAMP_NON_NULL("FirmwareTimestamp", &m->timestamps[MANAGER_TIMESTAMP_FIRMWARE]),
|
JSON_BUILD_PAIR_DUAL_TIMESTAMP_NON_NULL("FirmwareTimestamp", &m->timestamps[MANAGER_TIMESTAMP_FIRMWARE]),
|
||||||
JSON_BUILD_PAIR_DUAL_TIMESTAMP_NON_NULL("LoaderTimestamp", &m->timestamps[MANAGER_TIMESTAMP_LOADER]),
|
JSON_BUILD_PAIR_DUAL_TIMESTAMP_NON_NULL("LoaderTimestamp", &m->timestamps[MANAGER_TIMESTAMP_LOADER]),
|
||||||
JSON_BUILD_PAIR_DUAL_TIMESTAMP_NON_NULL("KernelTimestamp", &m->timestamps[MANAGER_TIMESTAMP_KERNEL]),
|
JSON_BUILD_PAIR_DUAL_TIMESTAMP_NON_NULL("KernelTimestamp", &m->timestamps[MANAGER_TIMESTAMP_KERNEL]),
|
||||||
@ -135,26 +149,15 @@ static int manager_runtime_build_json(sd_json_variant **ret, const char *name, v
|
|||||||
JSON_BUILD_PAIR_DUAL_TIMESTAMP_NON_NULL("InitRDGeneratorsFinishTimestamp", &m->timestamps[MANAGER_TIMESTAMP_INITRD_GENERATORS_FINISH]),
|
JSON_BUILD_PAIR_DUAL_TIMESTAMP_NON_NULL("InitRDGeneratorsFinishTimestamp", &m->timestamps[MANAGER_TIMESTAMP_INITRD_GENERATORS_FINISH]),
|
||||||
JSON_BUILD_PAIR_DUAL_TIMESTAMP_NON_NULL("InitRDUnitsLoadStartTimestamp", &m->timestamps[MANAGER_TIMESTAMP_INITRD_UNITS_LOAD_START]),
|
JSON_BUILD_PAIR_DUAL_TIMESTAMP_NON_NULL("InitRDUnitsLoadStartTimestamp", &m->timestamps[MANAGER_TIMESTAMP_INITRD_UNITS_LOAD_START]),
|
||||||
JSON_BUILD_PAIR_DUAL_TIMESTAMP_NON_NULL("InitRDUnitsLoadFinishTimestamp", &m->timestamps[MANAGER_TIMESTAMP_INITRD_UNITS_LOAD_FINISH]),
|
JSON_BUILD_PAIR_DUAL_TIMESTAMP_NON_NULL("InitRDUnitsLoadFinishTimestamp", &m->timestamps[MANAGER_TIMESTAMP_INITRD_UNITS_LOAD_FINISH]),
|
||||||
SD_JSON_BUILD_PAIR_BOOLEAN("ShowStatus", manager_get_show_status_on(m)),
|
|
||||||
JSON_BUILD_PAIR_CALLBACK_NON_NULL("LogLevel", log_level_build_runtime_json, m),
|
|
||||||
SD_JSON_BUILD_PAIR_STRING("LogTarget", log_target_to_string(log_get_target())),
|
|
||||||
SD_JSON_BUILD_PAIR_UNSIGNED("NNames", hashmap_size(m->units)),
|
SD_JSON_BUILD_PAIR_UNSIGNED("NNames", hashmap_size(m->units)),
|
||||||
SD_JSON_BUILD_PAIR_UNSIGNED("NFailedUnits", set_size(m->failed_units)),
|
SD_JSON_BUILD_PAIR_UNSIGNED("NFailedUnits", set_size(m->failed_units)),
|
||||||
SD_JSON_BUILD_PAIR_UNSIGNED("NJobs", hashmap_size(m->jobs)),
|
SD_JSON_BUILD_PAIR_UNSIGNED("NJobs", hashmap_size(m->jobs)),
|
||||||
SD_JSON_BUILD_PAIR_UNSIGNED("NInstalledJobs", m->n_installed_jobs),
|
SD_JSON_BUILD_PAIR_UNSIGNED("NInstalledJobs", m->n_installed_jobs),
|
||||||
SD_JSON_BUILD_PAIR_UNSIGNED("NFailedJobs", m->n_failed_jobs),
|
SD_JSON_BUILD_PAIR_UNSIGNED("NFailedJobs", m->n_failed_jobs),
|
||||||
SD_JSON_BUILD_PAIR_REAL("Progress", manager_get_progress(m)),
|
SD_JSON_BUILD_PAIR_REAL("Progress", manager_get_progress(m)),
|
||||||
JSON_BUILD_PAIR_CALLBACK_NON_NULL("Environment", manager_environment_build_json, m),
|
|
||||||
JSON_BUILD_PAIR_STRING_NON_EMPTY("WatchdogDevice", watchdog_get_device()),
|
|
||||||
JSON_BUILD_PAIR_DUAL_TIMESTAMP_NON_NULL("WatchdogLastPingTimestamp", watchdog_get_last_ping_as_dual_timestamp(&watchdog_last_ping)),
|
JSON_BUILD_PAIR_DUAL_TIMESTAMP_NON_NULL("WatchdogLastPingTimestamp", watchdog_get_last_ping_as_dual_timestamp(&watchdog_last_ping)),
|
||||||
JSON_BUILD_PAIR_STRING_NON_EMPTY("ControlGroup", m->cgroup_root),
|
|
||||||
SD_JSON_BUILD_PAIR_STRING("SystemState", manager_state_to_string(manager_state(m))),
|
SD_JSON_BUILD_PAIR_STRING("SystemState", manager_state_to_string(manager_state(m))),
|
||||||
SD_JSON_BUILD_PAIR_UNSIGNED("ExitCode", m->return_value),
|
SD_JSON_BUILD_PAIR_UNSIGNED("ExitCode", m->return_value),
|
||||||
JSON_BUILD_PAIR_FINITE_USEC("RuntimeWatchdogUSec", manager_get_watchdog(m, WATCHDOG_RUNTIME)),
|
|
||||||
JSON_BUILD_PAIR_FINITE_USEC("RuntimeWatchdogPreUSec", manager_get_watchdog(m, WATCHDOG_PRETIMEOUT)),
|
|
||||||
JSON_BUILD_PAIR_STRING_NON_EMPTY("RuntimeWatchdogPreGovernor", m->watchdog_pretimeout_governor),
|
|
||||||
JSON_BUILD_PAIR_FINITE_USEC("RebootWatchdogUSec", manager_get_watchdog(m, WATCHDOG_REBOOT)),
|
|
||||||
JSON_BUILD_PAIR_FINITE_USEC("KExecWatchdogUSec", manager_get_watchdog(m, WATCHDOG_KEXEC)),
|
|
||||||
SD_JSON_BUILD_PAIR_UNSIGNED("SoftRebootsCount", m->soft_reboots_count));
|
SD_JSON_BUILD_PAIR_UNSIGNED("SoftRebootsCount", m->soft_reboots_count));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
/* SPDX-License-Identifier: LGPL-2.1-or-later */
|
/* SPDX-License-Identifier: LGPL-2.1-or-later */
|
||||||
|
|
||||||
#include <getopt.h>
|
#include <getopt.h>
|
||||||
|
#include <linux/magic.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
#include "sd-json.h"
|
#include "sd-json.h"
|
||||||
@ -23,7 +24,6 @@
|
|||||||
#include "log.h"
|
#include "log.h"
|
||||||
#include "main-func.h"
|
#include "main-func.h"
|
||||||
#include "memory-util.h"
|
#include "memory-util.h"
|
||||||
#include "missing_magic.h"
|
|
||||||
#include "pager.h"
|
#include "pager.h"
|
||||||
#include "parse-argument.h"
|
#include "parse-argument.h"
|
||||||
#include "parse-util.h"
|
#include "parse-util.h"
|
||||||
|
@ -19,7 +19,7 @@ int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
|
|||||||
assert_se(fd >= 0);
|
assert_se(fd >= 0);
|
||||||
assert_se(write(fd, data, size) == (ssize_t) size);
|
assert_se(write(fd, data, size) == (ssize_t) size);
|
||||||
|
|
||||||
(void) catalog_import_file(&h, name);
|
(void) catalog_import_file(&h, fd, name);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -22,8 +22,6 @@
|
|||||||
#include "keyring-util.h"
|
#include "keyring-util.h"
|
||||||
#include "log.h"
|
#include "log.h"
|
||||||
#include "memory-util.h"
|
#include "memory-util.h"
|
||||||
#include "missing_keyctl.h"
|
|
||||||
#include "missing_syscall.h"
|
|
||||||
#include "mkdir.h"
|
#include "mkdir.h"
|
||||||
#include "mount-util.h"
|
#include "mount-util.h"
|
||||||
#include "nulstr-util.h"
|
#include "nulstr-util.h"
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
/* SPDX-License-Identifier: LGPL-2.1-or-later */
|
/* SPDX-License-Identifier: LGPL-2.1-or-later */
|
||||||
|
|
||||||
#include <linux/loop.h>
|
#include <linux/loop.h>
|
||||||
|
#include <linux/magic.h>
|
||||||
#include <poll.h>
|
#include <poll.h>
|
||||||
#include <sys/file.h>
|
#include <sys/file.h>
|
||||||
#include <sys/ioctl.h>
|
#include <sys/ioctl.h>
|
||||||
@ -45,8 +46,6 @@
|
|||||||
#include "keyring-util.h"
|
#include "keyring-util.h"
|
||||||
#include "loop-util.h"
|
#include "loop-util.h"
|
||||||
#include "memory-util.h"
|
#include "memory-util.h"
|
||||||
#include "missing_magic.h"
|
|
||||||
#include "missing_syscall.h"
|
|
||||||
#include "mkdir.h"
|
#include "mkdir.h"
|
||||||
#include "mkfs-util.h"
|
#include "mkfs-util.h"
|
||||||
#include "openssl-util.h"
|
#include "openssl-util.h"
|
||||||
|
@ -4,7 +4,6 @@
|
|||||||
#include "homework-password-cache.h"
|
#include "homework-password-cache.h"
|
||||||
#include "keyring-util.h"
|
#include "keyring-util.h"
|
||||||
#include "log.h"
|
#include "log.h"
|
||||||
#include "missing_syscall.h"
|
|
||||||
#include "string-util.h"
|
#include "string-util.h"
|
||||||
#include "user-record.h"
|
#include "user-record.h"
|
||||||
|
|
||||||
|
@ -1,5 +1,7 @@
|
|||||||
/* SPDX-License-Identifier: LGPL-2.1-or-later */
|
/* SPDX-License-Identifier: LGPL-2.1-or-later */
|
||||||
|
|
||||||
|
#include <linux/magic.h>
|
||||||
|
|
||||||
#include "btrfs-util.h"
|
#include "btrfs-util.h"
|
||||||
#include "errno-util.h"
|
#include "errno-util.h"
|
||||||
#include "fd-util.h"
|
#include "fd-util.h"
|
||||||
@ -7,7 +9,6 @@
|
|||||||
#include "homework-quota.h"
|
#include "homework-quota.h"
|
||||||
#include "log.h"
|
#include "log.h"
|
||||||
#include "memory-util.h"
|
#include "memory-util.h"
|
||||||
#include "missing_magic.h"
|
|
||||||
#include "quota-util.h"
|
#include "quota-util.h"
|
||||||
#include "stat-util.h"
|
#include "stat-util.h"
|
||||||
#include "user-record.h"
|
#include "user-record.h"
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
/* SPDX-License-Identifier: LGPL-2.1-or-later */
|
/* SPDX-License-Identifier: LGPL-2.1-or-later */
|
||||||
|
|
||||||
|
#include <linux/magic.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <sys/mount.h>
|
#include <sys/mount.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
@ -35,8 +36,6 @@
|
|||||||
#include "loop-util.h"
|
#include "loop-util.h"
|
||||||
#include "main-func.h"
|
#include "main-func.h"
|
||||||
#include "memory-util.h"
|
#include "memory-util.h"
|
||||||
#include "missing_magic.h"
|
|
||||||
#include "missing_syscall.h"
|
|
||||||
#include "mount-util.h"
|
#include "mount-util.h"
|
||||||
#include "path-util.h"
|
#include "path-util.h"
|
||||||
#include "recovery-key.h"
|
#include "recovery-key.h"
|
||||||
|
@ -2,11 +2,11 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <linux/fscrypt.h>
|
#include <linux/fscrypt.h>
|
||||||
|
#include <sys/keyctl.h>
|
||||||
|
|
||||||
#include "sd-id128.h"
|
#include "sd-id128.h"
|
||||||
|
|
||||||
#include "homework-forward.h"
|
#include "homework-forward.h"
|
||||||
#include "missing_keyctl.h"
|
|
||||||
#include "user-record-util.h"
|
#include "user-record-util.h"
|
||||||
|
|
||||||
typedef struct HomeSetup {
|
typedef struct HomeSetup {
|
||||||
|
45
src/include/meson.build
Normal file
45
src/include/meson.build
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
# SPDX-License-Identifier: LGPL-2.1-or-later
|
||||||
|
|
||||||
|
subdir('override/sys')
|
||||||
|
|
||||||
|
# Source files that provides AF_XYZ
|
||||||
|
af_sources = files(
|
||||||
|
'override/sys/socket.h',
|
||||||
|
)
|
||||||
|
|
||||||
|
# Source files that provides ARPHRD_XYZ
|
||||||
|
arphrd_sources = files(
|
||||||
|
'uapi/linux/if_arp.h',
|
||||||
|
)
|
||||||
|
|
||||||
|
# Source files that provides CAP_XYZ
|
||||||
|
cap_sources = files(
|
||||||
|
'uapi/linux/capability.h',
|
||||||
|
)
|
||||||
|
|
||||||
|
# Source files that provides BPF delegate options
|
||||||
|
bpf_delegate_sources = files(
|
||||||
|
'uapi/linux/bpf.h',
|
||||||
|
)
|
||||||
|
|
||||||
|
# Source files that provides ETHTOOL_LINK_MODE_XYZ
|
||||||
|
ethtool_link_mode_sources = files(
|
||||||
|
'uapi/linux/ethtool.h',
|
||||||
|
)
|
||||||
|
|
||||||
|
# Source files that provides IPPROTO_XYZ
|
||||||
|
ipproto_sources = files(
|
||||||
|
'override/netinet/in.h',
|
||||||
|
'uapi/linux/in.h',
|
||||||
|
)
|
||||||
|
|
||||||
|
# Source files that provides AUDIT_XYZ
|
||||||
|
audit_sources = files(
|
||||||
|
'override/linux/audit.h',
|
||||||
|
)
|
||||||
|
|
||||||
|
# Source files that provides KEY_XYZ
|
||||||
|
keyboard_sources = files(
|
||||||
|
'uapi/linux/input.h',
|
||||||
|
'uapi/linux/input-event-codes.h',
|
||||||
|
)
|
@ -1,13 +1,15 @@
|
|||||||
/* SPDX-License-Identifier: LGPL-2.1-or-later */
|
/* SPDX-License-Identifier: LGPL-2.1-or-later */
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <linux/audit.h> /* IWYU pragma: export */
|
#include_next <linux/audit.h> /* IWYU pragma: export */
|
||||||
|
|
||||||
#if HAVE_AUDIT
|
#if HAVE_AUDIT
|
||||||
# include <libaudit.h> /* IWYU pragma: export */
|
# include <libaudit.h> /* IWYU pragma: export */
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* We use _Static_assert() directly here instead of assert_cc()
|
#include <assert.h>
|
||||||
|
|
||||||
|
/* We use static_assert() directly here instead of assert_cc()
|
||||||
* because if we include macro.h in this header, the invocation
|
* because if we include macro.h in this header, the invocation
|
||||||
* of generate-audit_type-list.sh becomes more complex.
|
* of generate-audit_type-list.sh becomes more complex.
|
||||||
*/
|
*/
|
||||||
@ -15,17 +17,17 @@
|
|||||||
#ifndef AUDIT_SERVICE_START
|
#ifndef AUDIT_SERVICE_START
|
||||||
# define AUDIT_SERVICE_START 1130 /* Service (daemon) start */
|
# define AUDIT_SERVICE_START 1130 /* Service (daemon) start */
|
||||||
#else
|
#else
|
||||||
_Static_assert(AUDIT_SERVICE_START == 1130, "");
|
static_assert(AUDIT_SERVICE_START == 1130, "");
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef AUDIT_SERVICE_STOP
|
#ifndef AUDIT_SERVICE_STOP
|
||||||
# define AUDIT_SERVICE_STOP 1131 /* Service (daemon) stop */
|
# define AUDIT_SERVICE_STOP 1131 /* Service (daemon) stop */
|
||||||
#else
|
#else
|
||||||
_Static_assert(AUDIT_SERVICE_STOP == 1131, "");
|
static_assert(AUDIT_SERVICE_STOP == 1131, "");
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef MAX_AUDIT_MESSAGE_LENGTH
|
#ifndef MAX_AUDIT_MESSAGE_LENGTH
|
||||||
# define MAX_AUDIT_MESSAGE_LENGTH 8970
|
# define MAX_AUDIT_MESSAGE_LENGTH 8970
|
||||||
#else
|
#else
|
||||||
_Static_assert(MAX_AUDIT_MESSAGE_LENGTH == 8970, "");
|
static_assert(MAX_AUDIT_MESSAGE_LENGTH == 8970, "");
|
||||||
#endif
|
#endif
|
@ -1,7 +1,7 @@
|
|||||||
/* SPDX-License-Identifier: LGPL-2.1-or-later */
|
/* SPDX-License-Identifier: LGPL-2.1-or-later */
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <linux/bpf.h> /* IWYU pragma: export */
|
#include_next <linux/bpf.h> /* IWYU pragma: export */
|
||||||
|
|
||||||
/* defined in linux/filter.h */
|
/* defined in linux/filter.h */
|
||||||
/* Unconditional jumps, goto pc + off16 */
|
/* Unconditional jumps, goto pc + off16 */
|
@ -1,7 +1,7 @@
|
|||||||
/* SPDX-License-Identifier: LGPL-2.1-or-later */
|
/* SPDX-License-Identifier: LGPL-2.1-or-later */
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <linux/fs.h> /* IWYU pragma: export */
|
#include_next <linux/fs.h> /* IWYU pragma: export */
|
||||||
|
|
||||||
/* Not exposed yet. Defined at fs/ext4/ext4.h */
|
/* Not exposed yet. Defined at fs/ext4/ext4.h */
|
||||||
#ifndef EXT4_IOC_RESIZE_FS
|
#ifndef EXT4_IOC_RESIZE_FS
|
@ -1,9 +1,9 @@
|
|||||||
/* SPDX-License-Identifier: LGPL-2.1-or-later */
|
/* SPDX-License-Identifier: LGPL-2.1-or-later */
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <linux/keyctl.h> /* IWYU pragma: export */
|
#include_next <linux/keyctl.h> /* IWYU pragma: export */
|
||||||
|
|
||||||
#include "forward.h"
|
#include <stdint.h>
|
||||||
|
|
||||||
/* From linux/key.h */
|
/* From linux/key.h */
|
||||||
#ifndef KEY_POS_VIEW
|
#ifndef KEY_POS_VIEW
|
||||||
@ -42,5 +42,5 @@ typedef int32_t key_serial_t;
|
|||||||
# define KEY_OTH_SETATTR 0x00000020
|
# define KEY_OTH_SETATTR 0x00000020
|
||||||
# define KEY_OTH_ALL 0x0000003f
|
# define KEY_OTH_ALL 0x0000003f
|
||||||
#else
|
#else
|
||||||
assert_cc(KEY_OTH_ALL == 0x0000003f);
|
static_assert(KEY_OTH_ALL == 0x0000003f, "");
|
||||||
#endif
|
#endif
|
@ -1,102 +1,104 @@
|
|||||||
/* SPDX-License-Identifier: LGPL-2.1-or-later */
|
/* SPDX-License-Identifier: LGPL-2.1-or-later */
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <linux/magic.h> /* IWYU pragma: export */
|
#include_next <linux/magic.h> /* IWYU pragma: export */
|
||||||
|
|
||||||
|
#include <assert.h>
|
||||||
|
|
||||||
/* Not exposed yet (4.20). Defined at ipc/mqueue.c */
|
/* Not exposed yet (4.20). Defined at ipc/mqueue.c */
|
||||||
#ifndef MQUEUE_MAGIC
|
#ifndef MQUEUE_MAGIC
|
||||||
# define MQUEUE_MAGIC 0x19800202
|
# define MQUEUE_MAGIC 0x19800202
|
||||||
#else
|
#else
|
||||||
assert_cc(MQUEUE_MAGIC == 0x19800202);
|
static_assert(MQUEUE_MAGIC == 0x19800202, "");
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* b1123ea6d3b3da25af5c8a9d843bd07ab63213f4 (4.8), dropped by 68f2736a858324c3ec852f6c2cddd9d1c777357d (v6.0) */
|
/* b1123ea6d3b3da25af5c8a9d843bd07ab63213f4 (4.8), dropped by 68f2736a858324c3ec852f6c2cddd9d1c777357d (v6.0) */
|
||||||
#ifndef BALLOON_KVM_MAGIC
|
#ifndef BALLOON_KVM_MAGIC
|
||||||
# define BALLOON_KVM_MAGIC 0x13661366
|
# define BALLOON_KVM_MAGIC 0x13661366
|
||||||
#else
|
#else
|
||||||
assert_cc(BALLOON_KVM_MAGIC == 0x13661366);
|
static_assert(BALLOON_KVM_MAGIC == 0x13661366, "");
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* 48b4800a1c6af2cdda344ea4e2c843dcc1f6afc9 (4.8), dropped by 68f2736a858324c3ec852f6c2cddd9d1c777357d (v6.0) */
|
/* 48b4800a1c6af2cdda344ea4e2c843dcc1f6afc9 (4.8), dropped by 68f2736a858324c3ec852f6c2cddd9d1c777357d (v6.0) */
|
||||||
#ifndef ZSMALLOC_MAGIC
|
#ifndef ZSMALLOC_MAGIC
|
||||||
# define ZSMALLOC_MAGIC 0x58295829
|
# define ZSMALLOC_MAGIC 0x58295829
|
||||||
#else
|
#else
|
||||||
assert_cc(ZSMALLOC_MAGIC == 0x58295829);
|
static_assert(ZSMALLOC_MAGIC == 0x58295829, "");
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* ea8157ab2ae5e914dd427e5cfab533b6da3819cd (5.3), dropped by 68f2736a858324c3ec852f6c2cddd9d1c777357d (v6.0) */
|
/* ea8157ab2ae5e914dd427e5cfab533b6da3819cd (5.3), dropped by 68f2736a858324c3ec852f6c2cddd9d1c777357d (v6.0) */
|
||||||
#ifndef Z3FOLD_MAGIC
|
#ifndef Z3FOLD_MAGIC
|
||||||
# define Z3FOLD_MAGIC 0x33
|
# define Z3FOLD_MAGIC 0x33
|
||||||
#else
|
#else
|
||||||
assert_cc(Z3FOLD_MAGIC == 0x33);
|
static_assert(Z3FOLD_MAGIC == 0x33, "");
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* fe030c9b85e6783bc52fe86449c0a4b8aa16c753 (5.5), dropped by 68f2736a858324c3ec852f6c2cddd9d1c777357d (v6.0) */
|
/* fe030c9b85e6783bc52fe86449c0a4b8aa16c753 (5.5), dropped by 68f2736a858324c3ec852f6c2cddd9d1c777357d (v6.0) */
|
||||||
#ifndef PPC_CMM_MAGIC
|
#ifndef PPC_CMM_MAGIC
|
||||||
# define PPC_CMM_MAGIC 0xc7571590
|
# define PPC_CMM_MAGIC 0xc7571590
|
||||||
#else
|
#else
|
||||||
assert_cc(PPC_CMM_MAGIC == 0xc7571590);
|
static_assert(PPC_CMM_MAGIC == 0xc7571590, "");
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Not in mainline but included in Ubuntu */
|
/* Not in mainline but included in Ubuntu */
|
||||||
#ifndef SHIFTFS_MAGIC
|
#ifndef SHIFTFS_MAGIC
|
||||||
# define SHIFTFS_MAGIC 0x6a656a62
|
# define SHIFTFS_MAGIC 0x6a656a62
|
||||||
#else
|
#else
|
||||||
assert_cc(SHIFTFS_MAGIC == 0x6a656a62);
|
static_assert(SHIFTFS_MAGIC == 0x6a656a62, "");
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Not exposed yet. Defined at fs/fuse/control.c */
|
/* Not exposed yet. Defined at fs/fuse/control.c */
|
||||||
#ifndef FUSE_CTL_SUPER_MAGIC
|
#ifndef FUSE_CTL_SUPER_MAGIC
|
||||||
# define FUSE_CTL_SUPER_MAGIC 0x65735543
|
# define FUSE_CTL_SUPER_MAGIC 0x65735543
|
||||||
#else
|
#else
|
||||||
assert_cc(FUSE_CTL_SUPER_MAGIC == 0x65735543);
|
static_assert(FUSE_CTL_SUPER_MAGIC == 0x65735543, "");
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Not exposed yet. Defined at fs/orangefs/orangefs-kernel.h */
|
/* Not exposed yet. Defined at fs/orangefs/orangefs-kernel.h */
|
||||||
#ifndef ORANGEFS_DEVREQ_MAGIC
|
#ifndef ORANGEFS_DEVREQ_MAGIC
|
||||||
# define ORANGEFS_DEVREQ_MAGIC 0x20030529
|
# define ORANGEFS_DEVREQ_MAGIC 0x20030529
|
||||||
#else
|
#else
|
||||||
assert_cc(ORANGEFS_DEVREQ_MAGIC == 0x20030529);
|
static_assert(ORANGEFS_DEVREQ_MAGIC == 0x20030529, "");
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* linux/gfs2_ondisk.h */
|
/* linux/gfs2_ondisk.h */
|
||||||
#ifndef GFS2_MAGIC
|
#ifndef GFS2_MAGIC
|
||||||
# define GFS2_MAGIC 0x01161970
|
# define GFS2_MAGIC 0x01161970
|
||||||
#else
|
#else
|
||||||
assert_cc(GFS2_MAGIC == 0x01161970);
|
static_assert(GFS2_MAGIC == 0x01161970, "");
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Not exposed yet. Defined at fs/configfs/mount.c */
|
/* Not exposed yet. Defined at fs/configfs/mount.c */
|
||||||
#ifndef CONFIGFS_MAGIC
|
#ifndef CONFIGFS_MAGIC
|
||||||
# define CONFIGFS_MAGIC 0x62656570
|
# define CONFIGFS_MAGIC 0x62656570
|
||||||
#else
|
#else
|
||||||
assert_cc(CONFIGFS_MAGIC == 0x62656570);
|
static_assert(CONFIGFS_MAGIC == 0x62656570, "");
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Not exposed yet. Defined at fs/vboxsf/super.c */
|
/* Not exposed yet. Defined at fs/vboxsf/super.c */
|
||||||
#ifndef VBOXSF_SUPER_MAGIC
|
#ifndef VBOXSF_SUPER_MAGIC
|
||||||
# define VBOXSF_SUPER_MAGIC 0x786f4256
|
# define VBOXSF_SUPER_MAGIC 0x786f4256
|
||||||
#else
|
#else
|
||||||
assert_cc(VBOXSF_SUPER_MAGIC == 0x786f4256);
|
static_assert(VBOXSF_SUPER_MAGIC == 0x786f4256, "");
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Not exposed yet, internally actually called RPCAUTH_GSSMAGIC. Defined in net/sunrpc/rpc_pipe.c */
|
/* Not exposed yet, internally actually called RPCAUTH_GSSMAGIC. Defined in net/sunrpc/rpc_pipe.c */
|
||||||
#ifndef RPC_PIPEFS_SUPER_MAGIC
|
#ifndef RPC_PIPEFS_SUPER_MAGIC
|
||||||
# define RPC_PIPEFS_SUPER_MAGIC 0x67596969
|
# define RPC_PIPEFS_SUPER_MAGIC 0x67596969
|
||||||
#else
|
#else
|
||||||
assert_cc(RPC_PIPEFS_SUPER_MAGIC == 0x67596969);
|
static_assert(RPC_PIPEFS_SUPER_MAGIC == 0x67596969, "");
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Not exposed yet, defined at fs/ntfs/ntfs.h */
|
/* Not exposed yet, defined at fs/ntfs/ntfs.h */
|
||||||
#ifndef NTFS_SB_MAGIC
|
#ifndef NTFS_SB_MAGIC
|
||||||
# define NTFS_SB_MAGIC 0x5346544e
|
# define NTFS_SB_MAGIC 0x5346544e
|
||||||
#else
|
#else
|
||||||
assert_cc(NTFS_SB_MAGIC == 0x5346544e);
|
static_assert(NTFS_SB_MAGIC == 0x5346544e, "");
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Not exposed yet, encoded literally in fs/ntfs3/super.c. */
|
/* Not exposed yet, encoded literally in fs/ntfs3/super.c. */
|
||||||
#ifndef NTFS3_SUPER_MAGIC
|
#ifndef NTFS3_SUPER_MAGIC
|
||||||
# define NTFS3_SUPER_MAGIC 0x7366746e
|
# define NTFS3_SUPER_MAGIC 0x7366746e
|
||||||
#else
|
#else
|
||||||
assert_cc(NTFS3_SUPER_MAGIC == 0x7366746e);
|
static_assert(NTFS3_SUPER_MAGIC == 0x7366746e, "");
|
||||||
#endif
|
#endif
|
@ -1,8 +1,7 @@
|
|||||||
/* SPDX-License-Identifier: LGPL-2.1-or-later */
|
/* SPDX-License-Identifier: LGPL-2.1-or-later */
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <linux/nsfs.h> /* IWYU pragma: export */
|
#include_next <linux/nsfs.h> /* IWYU pragma: export */
|
||||||
#include <linux/types.h>
|
|
||||||
|
|
||||||
/* Root namespace inode numbers, as per include/linux/proc_ns.h in the kernel source tree, since v3.8:
|
/* Root namespace inode numbers, as per include/linux/proc_ns.h in the kernel source tree, since v3.8:
|
||||||
* https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=98f842e675f96ffac96e6c50315790912b2812be */
|
* https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=98f842e675f96ffac96e6c50315790912b2812be */
|
@ -1,7 +1,8 @@
|
|||||||
/* SPDX-License-Identifier: LGPL-2.1-or-later */
|
/* SPDX-License-Identifier: LGPL-2.1-or-later */
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "forward.h"
|
#include <linux/ioctl.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
/* This is currently not exported in the public kernel headers, but the libxfs library code part of xfsprogs
|
/* This is currently not exported in the public kernel headers, but the libxfs library code part of xfsprogs
|
||||||
* defines it as public header */
|
* defines it as public header */
|
||||||
@ -22,7 +23,7 @@ typedef struct xfs_fsop_geom {
|
|||||||
uint64_t rtblocks;
|
uint64_t rtblocks;
|
||||||
uint64_t rtextents;
|
uint64_t rtextents;
|
||||||
uint64_t logstart;
|
uint64_t logstart;
|
||||||
unsigned char uuid[16];
|
uint8_t uuid[16];
|
||||||
uint32_t sunit;
|
uint32_t sunit;
|
||||||
uint32_t swidth;
|
uint32_t swidth;
|
||||||
int32_t version;
|
int32_t version;
|
@ -35,3 +35,22 @@ static_assert(PF_KTHREAD == 0x00200000, "");
|
|||||||
#else
|
#else
|
||||||
static_assert(TASK_COMM_LEN == 16, "");
|
static_assert(TASK_COMM_LEN == 16, "");
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/* glibc does not provide clone() on ia64, only clone2(). Not only that, but it also doesn't provide a
|
||||||
|
* prototype, only the symbol in the shared library (it provides a prototype for clone(), but not the
|
||||||
|
* symbol in the shared library). */
|
||||||
|
#if defined(__ia64__)
|
||||||
|
int __clone2(int (*fn)(void *), void *stack_base, size_t stack_size, int flags, void *arg);
|
||||||
|
#define HAVE_CLONE 0
|
||||||
|
#else
|
||||||
|
/* We know that everywhere else clone() is available, so we don't bother with a meson check (that takes time
|
||||||
|
* at build time) and just define it. Once the kernel drops ia64 support, we can drop this too. */
|
||||||
|
#define HAVE_CLONE 1
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Defined since glibc-2.41.
|
||||||
|
* Supported since kernel 3.14 (e6cfc0295c7d51b008999a8b13a44fb43f8685ea). */
|
||||||
|
#if !HAVE_SCHED_SETATTR
|
||||||
|
int missing_sched_setattr(pid_t pid, struct sched_attr *attr, unsigned flags);
|
||||||
|
# define sched_setattr missing_sched_setattr
|
||||||
|
#endif
|
9
src/include/override/signal.h
Normal file
9
src/include/override/signal.h
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
/* SPDX-License-Identifier: LGPL-2.1-or-later */
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include_next <signal.h>
|
||||||
|
|
||||||
|
#if !HAVE_RT_TGSIGQUEUEINFO
|
||||||
|
int missing_rt_tgsigqueueinfo(pid_t tgid, pid_t tid, int sig, siginfo_t *info);
|
||||||
|
# define rt_tgsigqueueinfo missing_rt_tgsigqueueinfo
|
||||||
|
#endif
|
11
src/include/override/sys/bpf.h
Normal file
11
src/include/override/sys/bpf.h
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
/* SPDX-License-Identifier: LGPL-2.1-or-later */
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <linux/bpf.h> /* IWYU pragma: export */
|
||||||
|
#include <stddef.h>
|
||||||
|
|
||||||
|
/* Supported since kernel v3.18 (749730ce42a2121e1c88350d69478bff3994b10a). */
|
||||||
|
#if !HAVE_BPF
|
||||||
|
int missing_bpf(int cmd, union bpf_attr *attr, size_t size);
|
||||||
|
# define bpf missing_bpf
|
||||||
|
#endif
|
@ -33,6 +33,20 @@ def parse_syscall_tables(filenames):
|
|||||||
return {filename.split('-')[-1][:-4]: parse_syscall_table(filename)
|
return {filename.split('-')[-1][:-4]: parse_syscall_table(filename)
|
||||||
for filename in filenames}
|
for filename in filenames}
|
||||||
|
|
||||||
|
HEADER = '''\
|
||||||
|
/* SPDX-License-Identifier: LGPL-2.1-or-later
|
||||||
|
* This file is generated by src/include/override/sys/generate-syscall.py. Do not edit!
|
||||||
|
*
|
||||||
|
* Use 'ninja -C build update-syscall-tables' to download new syscall tables,
|
||||||
|
* and 'ninja -C build update-syscall-header' to regenerate this file.
|
||||||
|
*/
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include_next <sys/syscall.h>
|
||||||
|
|
||||||
|
#include <assert.h>
|
||||||
|
'''
|
||||||
|
|
||||||
DEF_TEMPLATE_A = '''\
|
DEF_TEMPLATE_A = '''\
|
||||||
|
|
||||||
#ifndef __IGNORE_{syscall}
|
#ifndef __IGNORE_{syscall}
|
||||||
@ -97,7 +111,7 @@ DEF_TEMPLATE_C = '''\
|
|||||||
/* may be an (invalid) negative number due to libseccomp, see PR 13319 */
|
/* may be an (invalid) negative number due to libseccomp, see PR 13319 */
|
||||||
# if defined __NR_{syscall} && __NR_{syscall} >= 0
|
# if defined __NR_{syscall} && __NR_{syscall} >= 0
|
||||||
# if defined systemd_NR_{syscall}
|
# if defined systemd_NR_{syscall}
|
||||||
_Static_assert(__NR_{syscall} == systemd_NR_{syscall}, "");
|
static_assert(__NR_{syscall} == systemd_NR_{syscall}, "");
|
||||||
# endif
|
# endif
|
||||||
# else
|
# else
|
||||||
# if defined __NR_{syscall}
|
# if defined __NR_{syscall}
|
||||||
@ -128,16 +142,7 @@ def print_syscall_def(syscall, tables, out):
|
|||||||
file=out)
|
file=out)
|
||||||
|
|
||||||
def print_syscall_defs(syscalls, tables, out):
|
def print_syscall_defs(syscalls, tables, out):
|
||||||
print('''\
|
print(HEADER, file=out)
|
||||||
/* SPDX-License-Identifier: LGPL-2.1-or-later
|
|
||||||
* This file is generated by src/basic/missing_syscalls.py. Do not edit!
|
|
||||||
*
|
|
||||||
* Use 'ninja -C build update-syscall-tables' to download new syscall tables,
|
|
||||||
* and 'ninja -C build update-syscall-header' to regenerate this file.
|
|
||||||
*/
|
|
||||||
#pragma once
|
|
||||||
''',
|
|
||||||
file=out)
|
|
||||||
print(ARCH_CHECK, file=out)
|
print(ARCH_CHECK, file=out)
|
||||||
for syscall in syscalls:
|
for syscall in syscalls:
|
||||||
print_syscall_def(syscall, tables, out)
|
print_syscall_def(syscall, tables, out)
|
14
src/include/override/sys/ioprio.h
Normal file
14
src/include/override/sys/ioprio.h
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
/* SPDX-License-Identifier: LGPL-2.1-or-later */
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <linux/ioprio.h> /* IWYU pragma: export */
|
||||||
|
|
||||||
|
#if !HAVE_IOPRIO_GET
|
||||||
|
int missing_ioprio_get(int which, int who);
|
||||||
|
# define ioprio_get missing_ioprio_get
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if !HAVE_IOPRIO_SET
|
||||||
|
int missing_ioprio_set(int which, int who, int ioprio);
|
||||||
|
# define ioprio_set missing_ioprio_set
|
||||||
|
#endif
|
11
src/include/override/sys/kcmp.h
Normal file
11
src/include/override/sys/kcmp.h
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
/* SPDX-License-Identifier: LGPL-2.1-or-later */
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <linux/kcmp.h> /* IWYU pragma: export */
|
||||||
|
#include <sys/types.h>
|
||||||
|
|
||||||
|
/* Supported since kernel v3.5 (d97b46a64674a267bc41c9e16132ee2a98c3347d). */
|
||||||
|
#if !HAVE_KCMP
|
||||||
|
int missing_kcmp(pid_t pid1, pid_t pid2, int type, unsigned long idx1, unsigned long idx2);
|
||||||
|
# define kcmp missing_kcmp
|
||||||
|
#endif
|
20
src/include/override/sys/keyctl.h
Normal file
20
src/include/override/sys/keyctl.h
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
/* SPDX-License-Identifier: LGPL-2.1-or-later */
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <linux/keyctl.h> /* IWYU pragma: export */
|
||||||
|
#include <stddef.h>
|
||||||
|
|
||||||
|
#if !HAVE_KEYCTL
|
||||||
|
long missing_keyctl(int cmd, unsigned long arg2, unsigned long arg3, unsigned long arg4, unsigned long arg5);
|
||||||
|
# define keyctl missing_keyctl
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if !HAVE_ADD_KEY
|
||||||
|
key_serial_t missing_add_key(const char *type, const char *description, const void *payload, size_t plen, key_serial_t ringid);
|
||||||
|
# define add_key missing_add_key
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if !HAVE_REQUEST_KEY
|
||||||
|
key_serial_t missing_request_key(const char *type, const char *description, const char *callout_info, key_serial_t destringid);
|
||||||
|
# define request_key missing_request_key
|
||||||
|
#endif
|
14
src/include/override/sys/mempolicy.h
Normal file
14
src/include/override/sys/mempolicy.h
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
/* SPDX-License-Identifier: LGPL-2.1-or-later */
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <linux/mempolicy.h> /* IWYU pragma: export */
|
||||||
|
|
||||||
|
#if !HAVE_SET_MEMPOLICY
|
||||||
|
int missing_set_mempolicy(int mode, const unsigned long *nodemask, unsigned long maxnode);
|
||||||
|
# define set_mempolicy missing_set_mempolicy
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if !HAVE_GET_MEMPOLICY
|
||||||
|
int missing_get_mempolicy(int *mode, unsigned long *nodemask, unsigned long maxnode, void *addr, unsigned long flags);
|
||||||
|
# define get_mempolicy missing_get_mempolicy
|
||||||
|
#endif
|
41
src/include/override/sys/meson.build
Normal file
41
src/include/override/sys/meson.build
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
# SPDX-License-Identifier: LGPL-2.1-or-later
|
||||||
|
|
||||||
|
arch_list = [
|
||||||
|
'alpha',
|
||||||
|
'arc',
|
||||||
|
'arm',
|
||||||
|
'arm64',
|
||||||
|
'i386',
|
||||||
|
'ia64',
|
||||||
|
'loongarch64',
|
||||||
|
'm68k',
|
||||||
|
'mips64',
|
||||||
|
'mips64n32',
|
||||||
|
'mipso32',
|
||||||
|
'parisc',
|
||||||
|
'powerpc',
|
||||||
|
'powerpc64',
|
||||||
|
'riscv32',
|
||||||
|
'riscv64',
|
||||||
|
's390',
|
||||||
|
's390x',
|
||||||
|
'sparc',
|
||||||
|
'x86_64'
|
||||||
|
]
|
||||||
|
|
||||||
|
run_target(
|
||||||
|
'update-syscall-tables',
|
||||||
|
command : [update_syscall_tables_sh, meson.current_source_dir()] + arch_list)
|
||||||
|
|
||||||
|
syscall_list_txt = files('syscall-list.txt')
|
||||||
|
|
||||||
|
syscall_lists = []
|
||||||
|
foreach arch: arch_list
|
||||||
|
syscall_lists += files('syscalls-@0@.txt'.format(arch))
|
||||||
|
endforeach
|
||||||
|
|
||||||
|
generate_syscall_py = find_program('generate-syscall.py')
|
||||||
|
|
||||||
|
run_target(
|
||||||
|
'update-syscall-header',
|
||||||
|
command : [generate_syscall_py, files('syscall.h')] + syscall_lists)
|
@ -8,10 +8,6 @@
|
|||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <sys/ioctl.h>
|
#include <sys/ioctl.h>
|
||||||
#include <sys/syscall.h>
|
|
||||||
#include <unistd.h>
|
|
||||||
|
|
||||||
#include "missing_syscall_def.h"
|
|
||||||
|
|
||||||
/* Since glibc-2.37 (774058d72942249f71d74e7f2b639f77184160a6), sys/mount.h includes linux/mount.h, and
|
/* Since glibc-2.37 (774058d72942249f71d74e7f2b639f77184160a6), sys/mount.h includes linux/mount.h, and
|
||||||
* we can safely include both headers in the same source file. However, we cannot do that with older glibc.
|
* we can safely include both headers in the same source file. However, we cannot do that with older glibc.
|
||||||
@ -43,67 +39,56 @@ extern int umount2(const char *__special_file, int __flags) __THROW;
|
|||||||
|
|
||||||
/* Open the filesystem referenced by FS_NAME so it can be configured for
|
/* Open the filesystem referenced by FS_NAME so it can be configured for
|
||||||
mouting. */
|
mouting. */
|
||||||
|
/* Defined since glibc-2.36.
|
||||||
|
* Supported since kernel v5.2 (24dcb3d90a1f67fe08c68a004af37df059d74005). */
|
||||||
#if HAVE_FSOPEN
|
#if HAVE_FSOPEN
|
||||||
extern int fsopen(const char *__fs_name, unsigned int __flags) __THROW;
|
extern int fsopen(const char *__fs_name, unsigned int __flags) __THROW;
|
||||||
#else
|
#else
|
||||||
static inline int missing_fsopen(const char *fsname, unsigned flags) {
|
int missing_fsopen(const char *fsname, unsigned flags);
|
||||||
return syscall(__NR_fsopen, fsname, flags);
|
|
||||||
}
|
|
||||||
# define fsopen missing_fsopen
|
# define fsopen missing_fsopen
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Create a mount representation for the FD created by fsopen using
|
/* Create a mount representation for the FD created by fsopen using
|
||||||
FLAGS with ATTR_FLAGS describing how the mount is to be performed. */
|
FLAGS with ATTR_FLAGS describing how the mount is to be performed. */
|
||||||
|
/* Defined since glibc-2.36.
|
||||||
|
* Supported since kernel v5.2 (93766fbd2696c2c4453dd8e1070977e9cd4e6b6d). */
|
||||||
#if HAVE_FSMOUNT
|
#if HAVE_FSMOUNT
|
||||||
extern int fsmount(int __fd, unsigned int __flags, unsigned int __ms_flags) __THROW;
|
extern int fsmount(int __fd, unsigned int __flags, unsigned int __ms_flags) __THROW;
|
||||||
#else
|
#else
|
||||||
static inline int missing_fsmount(int fd, unsigned flags, unsigned ms_flags) {
|
int missing_fsmount(int fd, unsigned flags, unsigned ms_flags);
|
||||||
return syscall(__NR_fsmount, fd, flags, ms_flags);
|
|
||||||
}
|
|
||||||
# define fsmount missing_fsmount
|
# define fsmount missing_fsmount
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Add the mounted FROM_DFD referenced by FROM_PATHNAME filesystem returned
|
/* Add the mounted FROM_DFD referenced by FROM_PATHNAME filesystem returned
|
||||||
by fsmount in the hierarchy in the place TO_DFD reference by TO_PATHNAME
|
by fsmount in the hierarchy in the place TO_DFD reference by TO_PATHNAME
|
||||||
using FLAGS. */
|
using FLAGS. */
|
||||||
|
/* Defined since glibc-2.36.
|
||||||
|
* Supported since kernel v5.2 (2db154b3ea8e14b04fee23e3fdfd5e9d17fbc6ae). */
|
||||||
#if HAVE_MOVE_MOUNT
|
#if HAVE_MOVE_MOUNT
|
||||||
extern int move_mount(int __from_dfd, const char *__from_pathname, int __to_dfd, const char *__to_pathname, unsigned int flags) __THROW;
|
extern int move_mount(int __from_dfd, const char *__from_pathname, int __to_dfd, const char *__to_pathname, unsigned int flags) __THROW;
|
||||||
#else
|
#else
|
||||||
static inline int missing_move_mount(
|
int missing_move_mount(int from_dfd, const char *from_pathname, int to_dfd, const char *to_pathname, unsigned flags);
|
||||||
int from_dfd,
|
|
||||||
const char *from_pathname,
|
|
||||||
int to_dfd,
|
|
||||||
const char *to_pathname,
|
|
||||||
unsigned flags) {
|
|
||||||
|
|
||||||
return syscall(__NR_move_mount, from_dfd, from_pathname, to_dfd, to_pathname, flags);
|
|
||||||
}
|
|
||||||
# define move_mount missing_move_mount
|
# define move_mount missing_move_mount
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Set parameters and trigger CMD action on the FD context. KEY, VALUE,
|
/* Set parameters and trigger CMD action on the FD context. KEY, VALUE,
|
||||||
and AUX are used depending ng of the CMD. */
|
and AUX are used depending ng of the CMD. */
|
||||||
|
/* Defined since glibc-2.36.
|
||||||
|
* Supported since kernel v5.2 (ecdab150fddb42fe6a739335257949220033b782). */
|
||||||
#if HAVE_FSCONFIG
|
#if HAVE_FSCONFIG
|
||||||
extern int fsconfig(int __fd, unsigned int __cmd, const char *__key, const void *__value, int __aux) __THROW;
|
extern int fsconfig(int __fd, unsigned int __cmd, const char *__key, const void *__value, int __aux) __THROW;
|
||||||
#else
|
#else
|
||||||
static inline int missing_fsconfig(int fd, unsigned cmd, const char *key, const void *value, int aux) {
|
int missing_fsconfig(int fd, unsigned cmd, const char *key, const void *value, int aux);
|
||||||
return syscall(__NR_fsconfig, fd, cmd, key, value, aux);
|
|
||||||
}
|
|
||||||
# define fsconfig missing_fsconfig
|
# define fsconfig missing_fsconfig
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Equivalent of fopen for an existing mount point. */
|
|
||||||
#if HAVE_FSPICK
|
|
||||||
extern int fspick(int __dfd, const char *__path, unsigned int __flags) __THROW;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Open the mount point FILENAME in directory DFD using FLAGS. */
|
/* Open the mount point FILENAME in directory DFD using FLAGS. */
|
||||||
|
/* Defined since glibc-2.36.
|
||||||
|
* Supported since kernel v5.2 (a07b20004793d8926f78d63eb5980559f7813404). */
|
||||||
#if HAVE_OPEN_TREE
|
#if HAVE_OPEN_TREE
|
||||||
extern int open_tree(int __dfd, const char *__filename, unsigned int __flags) __THROW;
|
extern int open_tree(int __dfd, const char *__filename, unsigned int __flags) __THROW;
|
||||||
#else
|
#else
|
||||||
static inline int missing_open_tree(int dfd, const char *filename, unsigned flags) {
|
int missing_open_tree(int dfd, const char *filename, unsigned flags);
|
||||||
return syscall(__NR_open_tree, dfd, filename, flags);
|
|
||||||
}
|
|
||||||
# define open_tree missing_open_tree
|
# define open_tree missing_open_tree
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -112,21 +97,20 @@ static inline int missing_open_tree(int dfd, const char *filename, unsigned flag
|
|||||||
directory referred to by the file descriptor dirfd. Otherwise if DFD is
|
directory referred to by the file descriptor dirfd. Otherwise if DFD is
|
||||||
the special value AT_FDCWD then PATH is interpreted relative to the current
|
the special value AT_FDCWD then PATH is interpreted relative to the current
|
||||||
working directory of the calling process. */
|
working directory of the calling process. */
|
||||||
|
/* Defined since glibc-2.36.
|
||||||
|
* Supported since kernel v5.12 (2a1867219c7b27f928e2545782b86daaf9ad50bd). */
|
||||||
#if HAVE_MOUNT_SETATTR
|
#if HAVE_MOUNT_SETATTR
|
||||||
extern int mount_setattr(int __dfd, const char *__path, unsigned int __flags, struct mount_attr *__uattr, size_t __usize) __THROW;
|
extern int mount_setattr(int __dfd, const char *__path, unsigned int __flags, struct mount_attr *__uattr, size_t __usize) __THROW;
|
||||||
#else
|
#else
|
||||||
static inline int missing_mount_setattr(int dfd, const char *path, unsigned flags, struct mount_attr *attr, size_t size) {
|
int missing_mount_setattr(int dfd, const char *path, unsigned flags, struct mount_attr *attr, size_t size);
|
||||||
return syscall(__NR_mount_setattr, dfd, path, flags, attr, size);
|
|
||||||
}
|
|
||||||
# define mount_setattr missing_mount_setattr
|
# define mount_setattr missing_mount_setattr
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/* Not defined in glibc yet as of glibc-2.41.
|
||||||
|
* Supported since kernel v6.15 (c4a16820d90199409c9bf01c4f794e1e9e8d8fd8). */
|
||||||
#if HAVE_OPEN_TREE_ATTR
|
#if HAVE_OPEN_TREE_ATTR
|
||||||
extern int open_tree_attr(int __dfd, const char *__filename, unsigned int __flags, struct mount_attr *__uattr, size_t __usize) __THROW;
|
extern int open_tree_attr(int __dfd, const char *__filename, unsigned int __flags, struct mount_attr *__uattr, size_t __usize) __THROW;
|
||||||
#else
|
#else
|
||||||
static inline int missing_open_tree_attr(int dfd, const char *filename, unsigned int flags, struct mount_attr *attr, size_t size) {
|
int missing_open_tree_attr(int dfd, const char *filename, unsigned int flags, struct mount_attr *attr, size_t size);
|
||||||
return syscall(__NR_open_tree_attr, dfd, filename, flags, attr, size);
|
|
||||||
}
|
|
||||||
|
|
||||||
# define open_tree_attr missing_open_tree_attr
|
# define open_tree_attr missing_open_tree_attr
|
||||||
#endif
|
#endif
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user