Merge branch 'i8c' with version 239-82 into i8

i8 changed/i8/systemd-239-82.el8.inferit
Sergey Cherevko 7 months ago
commit 8692a06803
Signed by: scherevko
GPG Key ID: D87CBBC16D2E4A72

@ -0,0 +1,196 @@
From 1628f48a0ecd13db92b79b7689e74b0ed4cb31a0 Mon Sep 17 00:00:00 2001
From: Jan Macku <jamacku@redhat.com>
Date: Thu, 14 Sep 2023 13:54:12 +0200
Subject: [PATCH] ci: Extend source-git-automation
* on schedule and on demand workflows
* Added Tracker validation for Bugzilla and Jira
rhel-only
Resolves: RHEL-1087
---
.github/tracker-validator.yml | 13 +++
.../source-git-automation-on-demand.yml | 99 +++++++++++++++++++
.github/workflows/source-git-automation.yml | 29 +++++-
3 files changed, 139 insertions(+), 2 deletions(-)
create mode 100644 .github/tracker-validator.yml
create mode 100644 .github/workflows/source-git-automation-on-demand.yml
diff --git a/.github/tracker-validator.yml b/.github/tracker-validator.yml
new file mode 100644
index 0000000000..10ead63eaa
--- /dev/null
+++ b/.github/tracker-validator.yml
@@ -0,0 +1,13 @@
+labels:
+ missing-tracker: tracker/missing
+ invalid-product: tracker/invalid-product
+ invalid-component: tracker/invalid-component
+ unapproved: tracker/unapproved
+products:
+ - CentOS Stream 8
+ - rhel-8.2.0
+ - rhel-8.4.0
+ - rhel-8.6.0
+ - rhel-8.8.0
+ - rhel-8.9.0
+ - rhel-8.10.0
diff --git a/.github/workflows/source-git-automation-on-demand.yml b/.github/workflows/source-git-automation-on-demand.yml
new file mode 100644
index 0000000000..92a65c8cc7
--- /dev/null
+++ b/.github/workflows/source-git-automation-on-demand.yml
@@ -0,0 +1,99 @@
+---
+
+name: Source git Automation Scheduled/On Demand
+on:
+ schedule:
+ # Workflow runs every 15 minutes
+ - cron: '*/15 * * * *'
+ workflow_dispatch:
+ inputs:
+ pr-number:
+ description: 'Pull Request number/s ; when not provided, the workflow will run for all open PRs'
+ required: true
+ default: '0'
+
+permissions:
+ contents: read
+
+jobs:
+ # Get all open PRs
+ gather-pull-requests:
+ if: github.repository == 'redhat-plumbers/systemd-rhel8'
+ runs-on: ubuntu-latest
+
+ outputs:
+ pr-numbers: ${{ steps.get-pr-numbers.outputs.result }}
+ pr-numbers-manual: ${{ steps.parse-manual-input.outputs.result }}
+
+ steps:
+ - id: get-pr-numbers
+ if: inputs.pr-number == '0'
+ name: Get all open PRs
+ uses: actions/github-script@v6
+ with:
+ # !FIXME: this is not working if there is more than 100 PRs opened
+ script: |
+ const { data: pullRequests } = await github.rest.pulls.list({
+ owner: context.repo.owner,
+ repo: context.repo.repo,
+ state: 'open',
+ per_page: 100
+ });
+ return pullRequests.map(pr => pr.number);
+
+ - id: parse-manual-input
+ if: inputs.pr-number != '0'
+ name: Parse manual input
+ run: |
+ echo "result="[ ${{ inputs.pr-number }} ]"" >> $GITHUB_OUTPUT
+ shell: bash
+
+ validate-pr:
+ name: 'Validation of Pull Request #${{ matrix.pr-number }}'
+ needs: [ gather-pull-requests ]
+ runs-on: ubuntu-latest
+
+ strategy:
+ fail-fast: false
+ matrix:
+ pr-number: ${{ inputs.pr-number == 0 && fromJSON(needs.gather-pull-requests.outputs.pr-numbers) || fromJSON(needs.gather-pull-requests.outputs.pr-numbers-manual) }}
+
+ permissions:
+ statuses: write
+ checks: write
+ pull-requests: write
+
+ steps:
+ - name: Repository checkout
+ uses: actions/checkout@v3
+
+ - id: metadata
+ name: Gather Pull Request Metadata
+ uses: redhat-plumbers-in-action/gather-pull-request-metadata@v1
+ with:
+ pr-number: ${{ matrix.pr-number }}
+
+ - id: commit-linter
+ name: Lint Commits
+ uses: redhat-plumbers-in-action/advanced-commit-linter@v2
+ with:
+ pr-metadata: ${{ steps.metadata.outputs.metadata }}
+ token: ${{ secrets.GITHUB_TOKEN }}
+
+ # Validates tracker, changes tracker status, updates PR title
+ - id: tracker-validator
+ name: Validate Tracker
+ uses: redhat-plumbers-in-action/tracker-validator@v1
+ with:
+ pr-metadata: ${{ steps.metadata.outputs.metadata }}
+ component: systemd
+ tracker: ${{ fromJSON(steps.commit-linter.outputs.validated-pr-metadata).validation.tracker.id }}
+ tracker-type: ${{ fromJSON(steps.commit-linter.outputs.validated-pr-metadata).validation.tracker.type }}
+ bugzilla-instance: https://bugzilla.redhat.com
+ bugzilla-api-token: ${{ secrets.BUGZILLA_API_TOKEN }}
+ jira-instance: https://issues.redhat.com
+ jira-api-token: ${{ secrets.JIRA_API_TOKEN }}
+ token: ${{ secrets.GITHUB_TOKEN }}
+
+ # TODO: merge PR if all checks passed
+ # TODO: add comment to Tracker that PR was merged ...
diff --git a/.github/workflows/source-git-automation.yml b/.github/workflows/source-git-automation.yml
index e653e28a7f..16c6f83d77 100644
--- a/.github/workflows/source-git-automation.yml
+++ b/.github/workflows/source-git-automation.yml
@@ -12,7 +12,8 @@ jobs:
download-metadata:
if: >
github.event.workflow_run.event == 'pull_request' &&
- github.event.workflow_run.conclusion == 'success'
+ github.event.workflow_run.conclusion == 'success' &&
+ github.repository == 'redhat-plumbers/systemd-rhel8'
runs-on: ubuntu-latest
outputs:
@@ -33,13 +34,37 @@ jobs:
validated-pr-metadata: ${{ steps.commit-linter.outputs.validated-pr-metadata }}
permissions:
+ statuses: write
checks: write
pull-requests: write
steps:
- id: commit-linter
name: Lint Commits
- uses: redhat-plumbers-in-action/advanced-commit-linter@v1
+ uses: redhat-plumbers-in-action/advanced-commit-linter@v2
with:
pr-metadata: ${{ needs.download-metadata.outputs.pr-metadata }}
token: ${{ secrets.GITHUB_TOKEN }}
+
+ # Validates tracker, changes tracker status, updates PR title
+ tracker-validation:
+ needs: [ download-metadata, commit-linter ]
+ runs-on: ubuntu-latest
+
+ permissions:
+ checks: write
+ pull-requests: write
+
+ steps:
+ - name: Validate Tracker
+ uses: redhat-plumbers-in-action/tracker-validator@v1
+ with:
+ pr-metadata: ${{ needs.download-metadata.outputs.pr-metadata }}
+ component: systemd
+ tracker: ${{ fromJSON(needs.commit-linter.outputs.validated-pr-metadata).validation.tracker.id }}
+ tracker-type: ${{ fromJSON(needs.commit-linter.outputs.validated-pr-metadata).validation.tracker.type }}
+ bugzilla-instance: https://bugzilla.redhat.com
+ bugzilla-api-token: ${{ secrets.BUGZILLA_API_TOKEN }}
+ jira-instance: https://issues.redhat.com
+ jira-api-token: ${{ secrets.JIRA_API_TOKEN }}
+ token: ${{ secrets.GITHUB_TOKEN }}

@ -0,0 +1,32 @@
From 21200fc506b1d15be6ed6d5b9ac70f1ec865f9bc Mon Sep 17 00:00:00 2001
From: Jan Macku <jamacku@redhat.com>
Date: Tue, 19 Sep 2023 09:53:35 +0200
Subject: [PATCH] ci: add missing configuration for commit linter
rhel-only
Related: RHEL-1087
---
.github/advanced-commit-linter.yml | 2 ++
1 file changed, 2 insertions(+)
diff --git a/.github/advanced-commit-linter.yml b/.github/advanced-commit-linter.yml
index 0fb74a9dc8..86f0e911f2 100644
--- a/.github/advanced-commit-linter.yml
+++ b/.github/advanced-commit-linter.yml
@@ -11,6 +11,7 @@ policy:
- 'Resolves: #?'
- 'Related: #?'
- 'Reverts: #?'
+ type: bugzilla
issue-format:
- '\d+$'
url: 'https://bugzilla.redhat.com/show_bug.cgi?id='
@@ -18,6 +19,7 @@ policy:
- 'Resolves: '
- 'Related: '
- 'Reverts: '
+ type: jira
issue-format:
- 'RHEL-\d+$'
url: 'https://issues.redhat.com/browse/'

@ -0,0 +1,25 @@
From ffd775b4b96ce0d772bcbb2fe2fbc62ed06bb4a4 Mon Sep 17 00:00:00 2001
From: Jan Macku <jamacku@redhat.com>
Date: Tue, 19 Sep 2023 15:17:48 +0200
Subject: [PATCH] ci: add `Red Hat Enterprise Linux 8` to the list of supported
products
rhel-only
Related: RHEL-1087
---
.github/tracker-validator.yml | 1 +
1 file changed, 1 insertion(+)
diff --git a/.github/tracker-validator.yml b/.github/tracker-validator.yml
index 10ead63eaa..500dce3d92 100644
--- a/.github/tracker-validator.yml
+++ b/.github/tracker-validator.yml
@@ -4,6 +4,7 @@ labels:
invalid-component: tracker/invalid-component
unapproved: tracker/unapproved
products:
+ - Red Hat Enterprise Linux 8
- CentOS Stream 8
- rhel-8.2.0
- rhel-8.4.0

@ -0,0 +1,95 @@
From bf728def0c6eebdf8d2b8912232ba7806e109293 Mon Sep 17 00:00:00 2001
From: Jan Macku <jamacku@redhat.com>
Date: Fri, 20 Oct 2023 13:32:22 +0200
Subject: [PATCH] ci: enable source-git automation to validate reviews and ci
results
rhel-only
Related: RHEL-1087
---
.github/pull-request-validator.yml | 4 ++++
.../source-git-automation-on-demand.yml | 14 ++++++++++----
.github/workflows/source-git-automation.yml | 18 +++++++++++++++++-
3 files changed, 31 insertions(+), 5 deletions(-)
create mode 100644 .github/pull-request-validator.yml
diff --git a/.github/pull-request-validator.yml b/.github/pull-request-validator.yml
new file mode 100644
index 0000000000..4bb5bbec12
--- /dev/null
+++ b/.github/pull-request-validator.yml
@@ -0,0 +1,4 @@
+labels:
+ missing-review: pr/needs-review
+ changes-requested: pr/changes-requested
+ missing-failing-ci: pr/needs-ci
diff --git a/.github/workflows/source-git-automation-on-demand.yml b/.github/workflows/source-git-automation-on-demand.yml
index 92a65c8cc7..e70ba4857a 100644
--- a/.github/workflows/source-git-automation-on-demand.yml
+++ b/.github/workflows/source-git-automation-on-demand.yml
@@ -73,7 +73,8 @@ jobs:
with:
pr-number: ${{ matrix.pr-number }}
- - id: commit-linter
+ - if: ${{ !cancelled() }}
+ id: commit-linter
name: Lint Commits
uses: redhat-plumbers-in-action/advanced-commit-linter@v2
with:
@@ -81,7 +82,8 @@ jobs:
token: ${{ secrets.GITHUB_TOKEN }}
# Validates tracker, changes tracker status, updates PR title
- - id: tracker-validator
+ - if: ${{ !cancelled() }}
+ id: tracker-validator
name: Validate Tracker
uses: redhat-plumbers-in-action/tracker-validator@v1
with:
@@ -95,5 +97,9 @@ jobs:
jira-api-token: ${{ secrets.JIRA_API_TOKEN }}
token: ${{ secrets.GITHUB_TOKEN }}
- # TODO: merge PR if all checks passed
- # TODO: add comment to Tracker that PR was merged ...
+ - if: ${{ !cancelled() }}
+ name: Pull Request Validator
+ uses: redhat-plumbers-in-action/pull-request-validator@v1
+ with:
+ pr-metadata: ${{ steps.metadata.outputs.metadata }}
+ token: ${{ secrets.GITHUB_TOKEN }}
diff --git a/.github/workflows/source-git-automation.yml b/.github/workflows/source-git-automation.yml
index 16c6f83d77..9faaaca099 100644
--- a/.github/workflows/source-git-automation.yml
+++ b/.github/workflows/source-git-automation.yml
@@ -47,7 +47,8 @@ jobs:
token: ${{ secrets.GITHUB_TOKEN }}
# Validates tracker, changes tracker status, updates PR title
- tracker-validation:
+ tracker-validator:
+ if: ${{ !cancelled() }}
needs: [ download-metadata, commit-linter ]
runs-on: ubuntu-latest
@@ -68,3 +69,18 @@ jobs:
jira-instance: https://issues.redhat.com
jira-api-token: ${{ secrets.JIRA_API_TOKEN }}
token: ${{ secrets.GITHUB_TOKEN }}
+
+ pull-request-validator:
+ needs: [ download-metadata ]
+ runs-on: ubuntu-latest
+
+ permissions:
+ checks: write
+ pull-requests: write
+
+ steps:
+ - name: Pull Request Validator
+ uses: redhat-plumbers-in-action/pull-request-validator@v1
+ with:
+ pr-metadata: ${{ needs.download-metadata.outputs.pr-metadata }}
+ token: ${{ secrets.GITHUB_TOKEN }}

@ -0,0 +1,52 @@
From 36266d377ee5e57e24cd3c45f6db2a29919798f3 Mon Sep 17 00:00:00 2001
From: Jan Macku <jamacku@redhat.com>
Date: Fri, 20 Oct 2023 13:33:38 +0200
Subject: [PATCH] ci: remove Mergify config - replaced by Pull Request
Validator
rhel-only
Related: RHEL-1087
---
.mergify.yml | 32 --------------------------------
1 file changed, 32 deletions(-)
delete mode 100644 .mergify.yml
diff --git a/.mergify.yml b/.mergify.yml
deleted file mode 100644
index 624eb7291d..0000000000
--- a/.mergify.yml
+++ /dev/null
@@ -1,32 +0,0 @@
-# doc: https://docs.mergify.com
----
-
-pull_request_rules:
- - name: Add `needs-ci` label on CI fail
- conditions:
- - label!=ci-waived
- - or:
- # Unit tests
- - -check-success=build (stream8, GCC)
- - -check-success=build (stream8, GCC_ASAN)
- # CentOS Stream CI
- - -check-success=CentOS CI (CentOS Stream 8)
- actions:
- label:
- add:
- - needs-ci
-
- - name: Remove `needs-ci` label on CI success
- conditions:
- - or:
- - label=ci-waived
- - and:
- # Unit tests
- - check-success=build (stream8, GCC)
- - check-success=build (stream8, GCC_ASAN)
- # CentOS Stream CI
- - check-success=CentOS CI (CentOS Stream 8)
- actions:
- label:
- remove:
- - needs-ci

@ -0,0 +1,84 @@
From 73b327eeeb3e2f17cbc1abd19aa5b87c28fcf509 Mon Sep 17 00:00:00 2001
From: Jan Macku <jamacku@redhat.com>
Date: Fri, 3 Nov 2023 14:07:04 +0100
Subject: [PATCH] ci: enable auto-merge GH Action
rhel-only
Related: RHEL-1087
---
.github/auto-merge.yml | 4 ++++
.../source-git-automation-on-demand.yml | 14 ++++++++++++
.github/workflows/source-git-automation.yml | 22 +++++++++++++++++++
3 files changed, 40 insertions(+)
create mode 100644 .github/auto-merge.yml
diff --git a/.github/auto-merge.yml b/.github/auto-merge.yml
new file mode 100644
index 0000000000..35c2539295
--- /dev/null
+++ b/.github/auto-merge.yml
@@ -0,0 +1,4 @@
+labels:
+ dont-merge: dont-merge
+ manual-merge: pr/needs-manual-merge
+target-branch': ['main']
diff --git a/.github/workflows/source-git-automation-on-demand.yml b/.github/workflows/source-git-automation-on-demand.yml
index e70ba4857a..948708916d 100644
--- a/.github/workflows/source-git-automation-on-demand.yml
+++ b/.github/workflows/source-git-automation-on-demand.yml
@@ -59,6 +59,7 @@ jobs:
pr-number: ${{ inputs.pr-number == 0 && fromJSON(needs.gather-pull-requests.outputs.pr-numbers) || fromJSON(needs.gather-pull-requests.outputs.pr-numbers-manual) }}
permissions:
+ contents: write
statuses: write
checks: write
pull-requests: write
@@ -103,3 +104,16 @@ jobs:
with:
pr-metadata: ${{ steps.metadata.outputs.metadata }}
token: ${{ secrets.GITHUB_TOKEN }}
+
+ - id: auto-merge
+ name: Auto Merge
+ uses: redhat-plumbers-in-action/auto-merge@v1
+ with:
+ pr-metadata: ${{ steps.metadata.outputs.metadata }}
+ tracker: ${{ fromJSON(steps.commit-linter.outputs.validated-pr-metadata).validation.tracker.id }}
+ tracker-type: ${{ fromJSON(steps.commit-linter.outputs.validated-pr-metadata).validation.tracker.type }}
+ bugzilla-instance: https://bugzilla.redhat.com
+ bugzilla-api-token: ${{ secrets.BUGZILLA_API_TOKEN }}
+ jira-instance: https://issues.redhat.com
+ jira-api-token: ${{ secrets.JIRA_API_TOKEN }}
+ token: ${{ secrets.GITHUB_TOKEN }}
diff --git a/.github/workflows/source-git-automation.yml b/.github/workflows/source-git-automation.yml
index 9faaaca099..95819baa8b 100644
--- a/.github/workflows/source-git-automation.yml
+++ b/.github/workflows/source-git-automation.yml
@@ -84,3 +84,25 @@ jobs:
with:
pr-metadata: ${{ needs.download-metadata.outputs.pr-metadata }}
token: ${{ secrets.GITHUB_TOKEN }}
+
+ auto-merge:
+ needs: [ download-metadata, commit-linter, tracker-validator, pull-request-validator ]
+ runs-on: ubuntu-latest
+
+ permissions:
+ contents: write
+ checks: write
+ pull-requests: write
+
+ steps:
+ - name: Auto Merge
+ uses: redhat-plumbers-in-action/auto-merge@v1
+ with:
+ pr-metadata: ${{ needs.download-metadata.outputs.pr-metadata }}
+ tracker: ${{ fromJSON(needs.commit-linter.outputs.validated-pr-metadata).validation.tracker.id }}
+ tracker-type: ${{ fromJSON(needs.commit-linter.outputs.validated-pr-metadata).validation.tracker.type }}
+ bugzilla-instance: https://bugzilla.redhat.com
+ bugzilla-api-token: ${{ secrets.BUGZILLA_API_TOKEN }}
+ jira-instance: https://issues.redhat.com
+ jira-api-token: ${{ secrets.JIRA_API_TOKEN }}
+ token: ${{ secrets.GITHUB_TOKEN }}

@ -0,0 +1,179 @@
From d0f59d4190a9f1e0e6db4b22b5e87bec2db4f7fb Mon Sep 17 00:00:00 2001
From: Frantisek Sumsal <fsumsal@redhat.com>
Date: Mon, 27 Nov 2023 15:20:47 +0100
Subject: [PATCH] fstab-generator: allow overriding /etc/fstab with
$SYSTEMD_FSTAB
Based on: ed4ad4889723a9acdf75ed86f10cee0024bbbcbc
Related: RHEL-1087
rhel-only
---
src/cryptsetup/cryptsetup.c | 3 ++-
src/fstab-generator/fstab-generator.c | 28 ++++++++++++++-------------
src/remount-fs/remount-fs.c | 5 +++--
src/shared/fstab-util.c | 4 ++--
src/shared/fstab-util.h | 4 ++++
5 files changed, 26 insertions(+), 18 deletions(-)
diff --git a/src/cryptsetup/cryptsetup.c b/src/cryptsetup/cryptsetup.c
index 11162eb722..de4bc9579c 100644
--- a/src/cryptsetup/cryptsetup.c
+++ b/src/cryptsetup/cryptsetup.c
@@ -13,6 +13,7 @@
#include "device-util.h"
#include "escape.h"
#include "fileio.h"
+#include "fstab-util.h"
#include "log.h"
#include "mount-util.h"
#include "parse-util.h"
@@ -318,7 +319,7 @@ static char *disk_mount_point(const char *label) {
if (asprintf(&device, "/dev/mapper/%s", label) < 0)
return NULL;
- f = setmntent("/etc/fstab", "re");
+ f = setmntent(fstab_path(), "re");
if (!f)
return NULL;
diff --git a/src/fstab-generator/fstab-generator.c b/src/fstab-generator/fstab-generator.c
index f24c1d29da..105ddd2fd0 100644
--- a/src/fstab-generator/fstab-generator.c
+++ b/src/fstab-generator/fstab-generator.c
@@ -105,15 +105,17 @@ static int add_swap(
if (r < 0)
return log_error_errno(r, "Failed to generate unit name: %m");
- r = generator_open_unit_file(arg_dest, "/etc/fstab", name, &f);
+ r = generator_open_unit_file(arg_dest, fstab_path(), name, &f);
if (r < 0)
return r;
- fputs("# Automatically generated by systemd-fstab-generator\n\n"
- "[Unit]\n"
- "SourcePath=/etc/fstab\n"
- "Documentation=man:fstab(5) man:systemd-fstab-generator(8)\n\n"
- "[Swap]\n", f);
+ fprintf(f,
+ "# Automatically generated by systemd-fstab-generator\n\n"
+ "[Unit]\n"
+ "SourcePath=%s\n"
+ "Documentation=man:fstab(5) man:systemd-fstab-generator(8)\n\n"
+ "[Swap]\n",
+ fstab_path());
r = write_what(f, what);
if (r < 0)
@@ -334,7 +336,7 @@ static int add_mount(
if (r < 0)
return log_error_errno(r, "Failed to generate unit name: %m");
- r = generator_open_unit_file(dest, "/etc/fstab", name, &f);
+ r = generator_open_unit_file(dest, fstab_path(), name, &f);
if (r < 0)
return r;
@@ -451,7 +453,7 @@ static int add_mount(
fclose(f);
- r = generator_open_unit_file(dest, "/etc/fstab", automount_name, &f);
+ r = generator_open_unit_file(dest, fstab_path(), automount_name, &f);
if (r < 0)
return r;
@@ -503,17 +505,17 @@ static int add_mount(
static int parse_fstab(bool initrd) {
_cleanup_endmntent_ FILE *f = NULL;
- const char *fstab_path;
+ const char *fstab;
struct mntent *me;
int r = 0;
- fstab_path = initrd ? "/sysroot/etc/fstab" : "/etc/fstab";
- f = setmntent(fstab_path, "re");
+ fstab = initrd ? "/sysroot/etc/fstab" : fstab_path();
+ f = setmntent(fstab, "re");
if (!f) {
if (errno == ENOENT)
return 0;
- return log_error_errno(errno, "Failed to open %s: %m", fstab_path);
+ return log_error_errno(errno, "Failed to open %s: %m", fstab);
}
while ((me = getmntent(f))) {
@@ -592,7 +594,7 @@ static int parse_fstab(bool initrd) {
me->mnt_passno,
makefs*MAKEFS | growfs*GROWFS | noauto*NOAUTO | nofail*NOFAIL | automount*AUTOMOUNT,
post,
- fstab_path);
+ fstab);
}
if (r >= 0 && k < 0)
diff --git a/src/remount-fs/remount-fs.c b/src/remount-fs/remount-fs.c
index 9220a00215..5bcee999cc 100644
--- a/src/remount-fs/remount-fs.c
+++ b/src/remount-fs/remount-fs.c
@@ -9,6 +9,7 @@
#include <unistd.h>
#include "exit-status.h"
+#include "fstab-util.h"
#include "log.h"
#include "mount-setup.h"
#include "mount-util.h"
@@ -39,14 +40,14 @@ int main(int argc, char *argv[]) {
umask(0022);
- f = setmntent("/etc/fstab", "re");
+ f = setmntent(fstab_path(), "re");
if (!f) {
if (errno == ENOENT) {
r = 0;
goto finish;
}
- r = log_error_errno(errno, "Failed to open /etc/fstab: %m");
+ r = log_error_errno(errno, "Failed to open %s: %m", fstab_path());
goto finish;
}
diff --git a/src/shared/fstab-util.c b/src/shared/fstab-util.c
index 6fd9866c00..bc0c047509 100644
--- a/src/shared/fstab-util.c
+++ b/src/shared/fstab-util.c
@@ -21,7 +21,7 @@ int fstab_has_fstype(const char *fstype) {
_cleanup_endmntent_ FILE *f = NULL;
struct mntent *m;
- f = setmntent("/etc/fstab", "re");
+ f = setmntent(fstab_path(), "re");
if (!f)
return errno == ENOENT ? false : -errno;
@@ -41,7 +41,7 @@ int fstab_is_mount_point(const char *mount) {
_cleanup_endmntent_ FILE *f = NULL;
struct mntent *m;
- f = setmntent("/etc/fstab", "re");
+ f = setmntent(fstab_path(), "re");
if (!f)
return errno == ENOENT ? false : -errno;
diff --git a/src/shared/fstab-util.h b/src/shared/fstab-util.h
index 9820f78ca8..9ec6db068c 100644
--- a/src/shared/fstab-util.h
+++ b/src/shared/fstab-util.h
@@ -33,3 +33,7 @@ static inline bool fstab_test_yes_no_option(const char *opts, const char *yes_no
}
char *fstab_node_to_udev_node(const char *p);
+
+static inline const char *fstab_path(void) {
+ return secure_getenv("SYSTEMD_FSTAB") ?: "/etc/fstab";
+}

@ -0,0 +1,37 @@
From f4a9bdf74c23a55ea96de696155ce9a5dfa43850 Mon Sep 17 00:00:00 2001
From: Frantisek Sumsal <fsumsal@redhat.com>
Date: Mon, 27 Nov 2023 16:16:40 +0100
Subject: [PATCH] fstab-generator: allow overriding path to /sysroot/etc/fstab
too
Based on: 99e3d4767932bce5febb45e8543162d729d17425
Related: RHEL-1087
rhel-only
---
src/fstab-generator/fstab-generator.c | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/src/fstab-generator/fstab-generator.c b/src/fstab-generator/fstab-generator.c
index 105ddd2fd0..02f0bccd2f 100644
--- a/src/fstab-generator/fstab-generator.c
+++ b/src/fstab-generator/fstab-generator.c
@@ -503,13 +503,17 @@ static int add_mount(
return 0;
}
+static const char *sysroot_fstab_path(void) {
+ return getenv("SYSTEMD_SYSROOT_FSTAB") ?: "/sysroot/etc/fstab";
+}
+
static int parse_fstab(bool initrd) {
_cleanup_endmntent_ FILE *f = NULL;
const char *fstab;
struct mntent *me;
int r = 0;
- fstab = initrd ? "/sysroot/etc/fstab" : fstab_path();
+ fstab = initrd ? sysroot_fstab_path() : fstab_path();
f = setmntent(fstab, "re");
if (!f) {
if (errno == ENOENT)

@ -0,0 +1,611 @@
From 52026032996f021963f5af8d625a5b9653d3f815 Mon Sep 17 00:00:00 2001
From: Frantisek Sumsal <fsumsal@redhat.com>
Date: Mon, 27 Nov 2023 14:54:15 +0100
Subject: [PATCH] test: backport TEST-81-GENERATORS (fstab-generator only)
Some fstab-generator features are not present on RHEL 8 or they behave
differently - in such case there's an inline comment explaining what's
different with a reference to an upstream commit that introduced the
changed behavior.
Related: RHEL-1087
rhel-only
---
test/TEST-81-GENERATORS/Makefile | 1 +
test/TEST-81-GENERATORS/generator-utils.sh | 78 ++++
test/TEST-81-GENERATORS/test.sh | 50 +++
.../testsuite.fstab-generator.sh | 397 ++++++++++++++++++
test/TEST-81-GENERATORS/testsuite.sh | 14 +
test/test-functions | 2 +-
6 files changed, 541 insertions(+), 1 deletion(-)
create mode 120000 test/TEST-81-GENERATORS/Makefile
create mode 100755 test/TEST-81-GENERATORS/generator-utils.sh
create mode 100755 test/TEST-81-GENERATORS/test.sh
create mode 100755 test/TEST-81-GENERATORS/testsuite.fstab-generator.sh
create mode 100755 test/TEST-81-GENERATORS/testsuite.sh
diff --git a/test/TEST-81-GENERATORS/Makefile b/test/TEST-81-GENERATORS/Makefile
new file mode 120000
index 0000000000..e9f93b1104
--- /dev/null
+++ b/test/TEST-81-GENERATORS/Makefile
@@ -0,0 +1 @@
+../TEST-01-BASIC/Makefile
\ No newline at end of file
diff --git a/test/TEST-81-GENERATORS/generator-utils.sh b/test/TEST-81-GENERATORS/generator-utils.sh
new file mode 100755
index 0000000000..fb62747fa1
--- /dev/null
+++ b/test/TEST-81-GENERATORS/generator-utils.sh
@@ -0,0 +1,78 @@
+#!/usr/bin/env bash
+# SPDX-License-Identifier: LGPL-2.1-or-later
+
+link_endswith() {
+ [[ -h "${1:?}" && "$(readlink "${1:?}")" =~ ${2:?}$ ]]
+}
+
+link_eq() {
+ [[ -h "${1:?}" && "$(readlink "${1:?}")" == "${2:?}" ]]
+}
+
+# Get the value from a 'key=value' assignment
+opt_get_arg() {
+ local arg
+
+ IFS="=" read -r _ arg <<< "${1:?}"
+ test -n "$arg"
+ echo "$arg"
+}
+
+in_initrd() {
+ [[ "${SYSTEMD_IN_INITRD:-0}" -ne 0 ]]
+}
+
+# Check if we're parsing host's fstab in initrd
+in_initrd_host() {
+ in_initrd && [[ "${SYSTEMD_SYSROOT_FSTAB:-/dev/null}" != /dev/null ]]
+}
+
+in_container() {
+ systemd-detect-virt -qc
+}
+
+opt_filter() (
+ set +x
+ local opt split_options filtered_options
+
+ IFS="," read -ra split_options <<< "${1:?}"
+ for opt in "${split_options[@]}"; do
+ if [[ "$opt" =~ ${2:?} ]]; then
+ continue
+ fi
+
+ filtered_options+=("$opt")
+ done
+
+ IFS=","; printf "%s" "${filtered_options[*]}"
+)
+
+# Run the given generator $1 with target directory $2 - clean the target
+# directory beforehand
+run_and_list() {
+ local generator="${1:?}"
+ local out_dir="${2:?}"
+ local environ
+
+ # If $PID1_ENVIRON is set temporarily overmount /proc/1/environ with
+ # a temporary file that contains contents of $PID1_ENVIRON. This is
+ # necessary in cases where the generator reads the environment through
+ # getenv_for_pid(1, ...) or similar like getty-generator does.
+ #
+ # Note: $PID1_ENVIRON should be a NUL separated list of env assignments
+ if [[ -n "${PID1_ENVIRON:-}" ]]; then
+ environ="$(mktemp)"
+ echo -ne "${PID1_ENVIRON}\0" >"${environ:?}"
+ mount -v --bind "$environ" /proc/1/environ
+ fi
+
+ rm -fr "${out_dir:?}"/*
+ mkdir -p "$out_dir"/{normal,early,late}
+ SYSTEMD_LOG_LEVEL="${SYSTEMD_LOG_LEVEL:-debug}" "$generator" "$out_dir/normal" "$out_dir/early" "$out_dir/late"
+ ls -lR "$out_dir"
+
+ if [[ -n "${environ:-}" ]]; then
+ umount /proc/1/environ
+ rm -f "$environ"
+ fi
+}
diff --git a/test/TEST-81-GENERATORS/test.sh b/test/TEST-81-GENERATORS/test.sh
new file mode 100755
index 0000000000..ec9c608c60
--- /dev/null
+++ b/test/TEST-81-GENERATORS/test.sh
@@ -0,0 +1,50 @@
+#!/usr/bin/env bash
+set -e
+TEST_DESCRIPTION="Test systemd generators"
+
+# shellcheck source=test/test-functions
+. "$TEST_BASE_DIR/test-functions"
+
+test_setup() {
+ create_empty_image
+ mkdir -p "${TESTDIR:?}/root"
+ mount "${LOOPDEV:?}p1" "$TESTDIR/root"
+
+ (
+ LOG_LEVEL=5
+ # shellcheck disable=SC2046
+ eval $(udevadm info --export --query=env --name="${LOOPDEV}p2")
+
+ setup_basic_environment
+
+ # mask some services that we do not want to run in these tests
+ ln -fs /dev/null "$initdir/etc/systemd/system/systemd-hwdb-update.service"
+ ln -fs /dev/null "$initdir/etc/systemd/system/systemd-journal-catalog-update.service"
+ ln -fs /dev/null "$initdir/etc/systemd/system/systemd-networkd.service"
+ ln -fs /dev/null "$initdir/etc/systemd/system/systemd-networkd.socket"
+ ln -fs /dev/null "$initdir/etc/systemd/system/systemd-resolved.service"
+ ln -fs /dev/null "$initdir/etc/systemd/system/systemd-machined.service"
+
+ # setup the testsuite service
+ cat >"$initdir/etc/systemd/system/testsuite.service" <<EOF
+[Unit]
+Description=Testsuite service
+
+[Service]
+ExecStart=/bin/bash -x /testsuite.sh
+Type=oneshot
+StandardOutput=tty
+StandardError=tty
+NotifyAccess=all
+EOF
+ cp generator-utils.sh testsuite*.sh "$initdir/"
+
+ setup_testsuite
+ ) || return 1
+ setup_nspawn_root
+
+ ddebug "umount $TESTDIR/root"
+ umount "$TESTDIR/root"
+}
+
+do_test "$@"
diff --git a/test/TEST-81-GENERATORS/testsuite.fstab-generator.sh b/test/TEST-81-GENERATORS/testsuite.fstab-generator.sh
new file mode 100755
index 0000000000..705fd5e5c7
--- /dev/null
+++ b/test/TEST-81-GENERATORS/testsuite.fstab-generator.sh
@@ -0,0 +1,397 @@
+#!/usr/bin/env bash
+# SPDX-License-Identifier: LGPL-2.1-or-later
+# shellcheck disable=SC2235,SC2233
+set -eux
+set -o pipefail
+
+# shellcheck source=test/TEST-81-GENERATORS/generator-utils.sh
+. "$(dirname "$0")/generator-utils.sh"
+
+GENERATOR_BIN="/usr/lib/systemd/system-generators/systemd-fstab-generator"
+NETWORK_FS_RX="^(afs|ceph|cifs|gfs|gfs2|ncp|ncpfs|nfs|nfs4|ocfs2|orangefs|pvfs2|smb3|smbfs|davfs|glusterfs|lustre|sshfs)$"
+OUT_DIR="$(mktemp -d /tmp/fstab-generator.XXX)"
+FSTAB="$(mktemp)"
+
+at_exit() {
+ rm -fr "${OUT_DIR:?}" "${FSTAB:?}"
+}
+
+trap at_exit EXIT
+
+test -x "${GENERATOR_BIN:?}"
+
+FSTAB_GENERAL=(
+ # Valid entries
+ "/dev/test2 /nofail ext4 nofail 0 0"
+ "/dev/test3 /regular btrfs defaults 0 0"
+ "/dev/test4 /x-systemd.requires xfs x-systemd.requires=foo.service 0 0"
+ "/dev/test5 /x-systemd.before-after xfs x-systemd.before=foo.service,x-systemd.after=bar.mount 0 0"
+# Not supported on RHEL 8
+# "/dev/test6 /x-systemd.wanted-required-by xfs x-systemd.wanted-by=foo.service,x-systemd.required-by=bar.device 0 0"
+ "/dev/test7 /x-systemd.requires-mounts-for xfs x-systemd.requires-mounts-for=/foo/bar/baz 0 0"
+ "/dev/test8 /x-systemd.automount-idle-timeout vfat x-systemd.automount,x-systemd.idle-timeout=50s 0 0"
+ "/dev/test9 /x-systemd.makefs xfs x-systemd.makefs 0 0"
+ "/dev/test10 /x-systemd.growfs xfs x-systemd.growfs 0 0"
+ "/dev/test11 /_netdev ext4 defaults,_netdev 0 0"
+# Not supported on RHEL 8
+# "/dev/test12 /_rwonly ext4 x-systemd.rw-only 0 0"
+ "/dev/test13 /chaos1 zfs x-systemd.requires=hello.service,x-systemd.after=my.device 0 0"
+ "/dev/test14 /chaos2 zfs x-systemd.growfs,x-systemd.makefs 0 0"
+ "/dev/test15 /fstype/auto auto defaults 0 0"
+ "/dev/test16 /fsck/me ext4 defaults 0 1"
+ "/dev/test17 /also/fsck/me ext4 defaults,x-systemd.requires-mounts-for=/var/lib/foo 0 99"
+ "/dev/test18 /swap swap defaults 0 0"
+ "/dev/test19 /swap/makefs swap defaults,x-systemd.makefs 0 0"
+ "/dev/test20 /var xfs defaults,x-systemd.device-timeout=1h 0 0"
+ "/dev/test21 /usr ext4 defaults 0 1"
+ "/dev/test22 /initrd/mount ext2 defaults,x-initrd.mount 0 1"
+ "/dev/test23 /initrd/mount/nofail ext3 defaults,nofail,x-initrd.mount 0 1"
+ "/dev/test24 /initrd/mount/deps ext4 x-initrd.mount,x-systemd.before=early.service,x-systemd.after=late.service 0 1"
+
+ # Incomplete, but valid entries
+ "/dev/incomplete1 /incomplete1"
+ "/dev/incomplete2 /incomplete2 ext4"
+ "/dev/incomplete3 /incomplete3 ext4 defaults"
+ "/dev/incomplete4 /incomplete4 ext4 defaults 0"
+
+ # Remote filesystems
+ "/dev/remote1 /nfs nfs bg 0 0"
+ "/dev/remote2 /nfs4 nfs4 bg 0 0"
+ "bar.tld:/store /remote/storage nfs ro,x-systemd.after=store.service 0 0"
+ "user@host.tld:/remote/dir /remote/top-secret sshfs rw,x-systemd.before=naughty.service 0 0"
+ "foo.tld:/hello /hello/world ceph defaults 0 0"
+ "//192.168.0.1/storage /cifs-storage cifs automount,nofail 0 0"
+)
+
+FSTAB_GENERAL_ROOT=(
+ # rootfs with bunch of options we should ignore and fsck enabled
+ "/dev/test1 / ext4 noauto,nofail,x-systemd.automount,x-systemd.wanted-by=foo,x-systemd.required-by=bar 0 1"
+ "${FSTAB_GENERAL[@]}"
+)
+
+FSTAB_MINIMAL=(
+ "/dev/loop1 /foo/bar ext3 defaults 0 0"
+)
+
+FSTAB_DUPLICATE=(
+ "/dev/dup1 / ext4 defaults 0 1"
+ "/dev/dup2 / ext4 defaults,x-systemd.requires=foo.mount 0 2"
+)
+
+FSTAB_INVALID=(
+ # Ignored entries
+ "/dev/ignored1 /sys/fs/cgroup/foo ext4 defaults 0 0"
+ "/dev/ignored2 /sys/fs/selinux ext4 defaults 0 0"
+ "/dev/ignored3 /dev/console ext4 defaults 0 0"
+ "/dev/ignored4 /proc/kmsg ext4 defaults 0 0"
+ "/dev/ignored5 /proc/sys ext4 defaults 0 0"
+# Not ignored on RHEL 8, see 6f997852c8830ca073c55241b0068ebbf1f94a72
+# "/dev/ignored6 /proc/sys/kernel/random/boot_id ext4 defaults 0 0"
+# "/dev/ignored7 /run/host ext4 defaults 0 0"
+# "/dev/ignored8 /run/host/foo ext4 defaults 0 0"
+ "/dev/ignored9 /autofs autofs defaults 0 0"
+ "/dev/invalid1 not-a-path ext4 defaults 0 0"
+ ""
+ "/dev/invalid1"
+ " "
+ "\\"
+ "$"
+)
+
+check_fstab_mount_units() {
+ local what where fstype opts passno unit
+ local item opt split_options filtered_options supp service device arg
+ local array_name="${1:?}"
+ local out_dir="${2:?}/normal"
+ # Get a reference to the array from its name
+ local -n fstab_entries="$array_name"
+
+ # Running the checks in a container is pretty much useless, since we don't
+ # generate any mounts, but don't skip the whole test to test the "skip"
+ # paths as well
+ in_container && return 0
+
+ for item in "${fstab_entries[@]}"; do
+ # Don't use a pipe here, as it would make the variables out of scope
+ read -r what where fstype opts _ passno <<< "$item"
+
+ # Skip non-initrd mounts in initrd
+ if in_initrd_host && ! [[ "$opts" =~ x-initrd.mount ]]; then
+ continue
+ fi
+
+ if [[ "$fstype" == swap ]]; then
+ unit="$(systemd-escape --suffix=swap --path "${what:?}")"
+ cat "$out_dir/$unit"
+
+ grep -qE "^What=$what$" "$out_dir/$unit"
+ if [[ "$opts" != defaults ]]; then
+ grep -qE "^Options=$opts$" "$out_dir/$unit"
+ fi
+
+ if [[ "$opts" =~ x-systemd.makefs ]]; then
+ service="$(systemd-escape --template=systemd-mkswap@.service --path "$what")"
+ test -e "$out_dir/$service"
+ fi
+
+ continue
+ fi
+
+ # If we're parsing host's fstab in initrd, prefix all mount targets
+ # with /sysroot
+ in_initrd_host && where="/sysroot${where:?}"
+ unit="$(systemd-escape --suffix=mount --path "${where:?}")"
+ cat "$out_dir/$unit"
+
+ # Check the general stuff
+ grep -qE "^What=$what$" "$out_dir/$unit"
+ grep -qE "^Where=$where$" "$out_dir/$unit"
+ if [[ -n "$fstype" ]] && [[ "$fstype" != auto ]]; then
+ grep -qE "^Type=$fstype$" "$out_dir/$unit"
+ fi
+ if [[ -n "$opts" ]] && [[ "$opts" != defaults ]]; then
+ # Some options are not propagated to the generated unit
+ if [[ "$where" == / ]]; then
+ filtered_options="$(opt_filter "$opts" "(noauto|nofail|x-systemd.(wanted-by=|required-by=|automount|device-timeout=))")"
+ else
+ filtered_options="$(opt_filter "$opts" "^x-systemd.device-timeout=")"
+ fi
+
+ if [[ "${filtered_options[*]}" != defaults ]]; then
+ grep -qE "^Options=.*$filtered_options.*$" "$out_dir/$unit"
+ fi
+ fi
+
+ if ! [[ "$opts" =~ (noauto|x-systemd.(wanted-by=|required-by=|automount)) ]]; then
+ # We don't create the Requires=/Wants= symlinks for noauto/automount mounts
+ # and for mounts that use x-systemd.wanted-by=/required-by=
+ if in_initrd_host; then
+ if [[ "$where" == / ]] || ! [[ "$opts" =~ nofail ]]; then
+ link_eq "$out_dir/initrd-fs.target.requires/$unit" "../$unit"
+ else
+ link_eq "$out_dir/initrd-fs.target.wants/$unit" "../$unit"
+ fi
+ elif [[ "$fstype" =~ $NETWORK_FS_RX || "$opts" =~ _netdev ]]; then
+ # Units with network filesystems should have a Requires= dependency
+ # on the remote-fs.target, unless they use nofail or are an nfs "bg"
+ # mounts, in which case the dependency is downgraded to Wants=
+ if [[ "$opts" =~ nofail ]] || [[ "$fstype" =~ ^(nfs|nfs4) && "$opts" =~ bg ]]; then
+ link_eq "$out_dir/remote-fs.target.wants/$unit" "../$unit"
+ else
+ link_eq "$out_dir/remote-fs.target.requires/$unit" "../$unit"
+ fi
+ else
+ # Similarly, local filesystems should have a Requires= dependency on
+ # the local-fs.target, unless they use nofail, in which case the
+ # dependency is downgraded to Wants=. Rootfs is a special case,
+ # since we always ignore nofail there
+ if [[ "$where" == / ]] || ! [[ "$opts" =~ nofail ]]; then
+ link_eq "$out_dir/local-fs.target.requires/$unit" "../$unit"
+ else
+ link_eq "$out_dir/local-fs.target.wants/$unit" "../$unit"
+ fi
+ fi
+ fi
+
+ if [[ "${passno:=0}" -ne 0 ]]; then
+ # Generate systemd-fsck@.service dependencies, if applicable
+ if in_initrd && [[ "$where" == / || "$where" == /usr ]]; then
+ continue
+ fi
+
+ if [[ "$where" == / ]]; then
+ link_endswith "$out_dir/local-fs.target.wants/systemd-fsck-root.service" "/lib/systemd/system/systemd-fsck-root.service"
+ else
+ service="$(systemd-escape --template=systemd-fsck@.service --path "$what")"
+ grep -qE "^After=$service$" "$out_dir/$unit"
+ # On RHEL 8 this is always a Requires= dependency, even when the target
+ # is /usr, see afacf3fc8af0090620383228c6c84345ad63b6f8
+ grep -qE "^Requires=$service$" "$out_dir/$unit"
+ fi
+ fi
+
+ # Check various x-systemd options
+ #
+ # First, split them into an array to make splitting them even further
+ # easier
+ IFS="," read -ra split_options <<< "$opts"
+ # and process them one by one.
+ #
+ # Note: the "machinery" below might (and probably does) miss some
+ # combinations of supported options, so tread carefully
+ for opt in "${split_options[@]}"; do
+ if [[ "$opt" =~ ^x-systemd.requires= ]]; then
+ service="$(opt_get_arg "$opt")"
+ grep -qE "^Requires=$service$" "$out_dir/$unit"
+ grep -qE "^After=$service$" "$out_dir/$unit"
+ elif [[ "$opt" =~ ^x-systemd.before= ]]; then
+ service="$(opt_get_arg "$opt")"
+ grep -qE "^Before=$service$" "$out_dir/$unit"
+ elif [[ "$opt" =~ ^x-systemd.after= ]]; then
+ service="$(opt_get_arg "$opt")"
+ grep -qE "^After=$service$" "$out_dir/$unit"
+ elif [[ "$opt" =~ ^x-systemd.wanted-by= ]]; then
+ service="$(opt_get_arg "$opt")"
+ if [[ "$where" == / ]]; then
+ # This option is ignored for rootfs mounts
+ (! link_eq "$out_dir/$service.wants/$unit" "../$unit")
+ else
+ link_eq "$out_dir/$service.wants/$unit" "../$unit"
+ fi
+ elif [[ "$opt" =~ ^x-systemd.required-by= ]]; then
+ service="$(opt_get_arg "$opt")"
+ if [[ "$where" == / ]]; then
+ # This option is ignored for rootfs mounts
+ (! link_eq "$out_dir/$service.requires/$unit" "../$unit")
+ else
+ link_eq "$out_dir/$service.requires/$unit" "../$unit"
+ fi
+ elif [[ "$opt" =~ ^x-systemd.requires-mounts-for= ]]; then
+ arg="$(opt_get_arg "$opt")"
+ grep -qE "^RequiresMountsFor=$arg$" "$out_dir/$unit"
+ elif [[ "$opt" == x-systemd.device-bound ]]; then
+ # This is implied for fstab mounts
+ :
+ elif [[ "$opt" == x-systemd.automount ]]; then
+ # The $unit should have an accompanying automount unit
+ supp="$(systemd-escape --suffix=automount --path "$where")"
+ if [[ "$where" == / ]]; then
+ # This option is ignored for rootfs mounts
+ test ! -e "$out_dir/$supp"
+ (! link_eq "$out_dir/local-fs.target.requires/$supp" "../$supp")
+ else
+ test -e "$out_dir/$supp"
+ link_eq "$out_dir/local-fs.target.requires/$supp" "../$supp"
+ fi
+ elif [[ "$opt" =~ ^x-systemd.idle-timeout= ]]; then
+ # The timeout applies to the automount unit, not the original
+ # mount one
+ arg="$(opt_get_arg "$opt")"
+ supp="$(systemd-escape --suffix=automount --path "$where")"
+ grep -qE "^TimeoutIdleSec=$arg$" "$out_dir/$supp"
+ elif [[ "$opt" =~ ^x-systemd.device-timeout= ]]; then
+ arg="$(opt_get_arg "$opt")"
+ device="$(systemd-escape --suffix=device --path "$what")"
+ grep -qE "^JobRunningTimeoutSec=$arg$" "$out_dir/${device}.d/50-device-timeout.conf"
+ elif [[ "$opt" == x-systemd.makefs ]]; then
+ # In RHEL8 the unit is called systemd-mkfs@.service, see
+ # 804f8e1729e7663c75a88fcf0997539442b891d7
+ service="$(systemd-escape --template=systemd-mkfs@.service --path "$what")"
+ test -e "$out_dir/$service"
+ link_eq "$out_dir/${unit}.requires/$service" "../$service"
+ elif [[ "$opt" == x-systemd.rw-only ]]; then
+ grep -qE "^ReadWriteOnly=yes$" "$out_dir/$unit"
+ elif [[ "$opt" == x-systemd.growfs ]]; then
+ service="$(systemd-escape --template=systemd-growfs@.service --path "$where")"
+ # Another deviation from upstream, see 50072ccf1bfee8a53563a083a3a52b26f0d5678f
+ link_eq "$out_dir/${unit}.wants/$service" "../$service"
+ elif [[ "$opt" == bg ]] && [[ "$fstype" =~ ^(nfs|nfs4)$ ]]; then
+ # We "convert" nfs bg mounts to fg, so we can do the job-control
+ # ourselves
+ grep -qE "^Options=.*\bx-systemd.mount-timeout=infinity\b" "$out_dir/$unit"
+ grep -qE "^Options=.*\bfg\b.*" "$out_dir/$unit"
+ elif [[ "$opt" =~ ^x-systemd\. ]]; then
+ echo >&2 "Unhandled mount option: $opt"
+ exit 1
+ fi
+ done
+ done
+}
+
+: "fstab-generator: regular"
+printf "%s\n" "${FSTAB_GENERAL_ROOT[@]}" >"$FSTAB"
+cat "$FSTAB"
+SYSTEMD_FSTAB="$FSTAB" run_and_list "$GENERATOR_BIN" "$OUT_DIR"
+check_fstab_mount_units FSTAB_GENERAL_ROOT "$OUT_DIR"
+
+# Skip the rest when running in a container, as it makes little sense to check
+# initrd-related stuff there and fstab-generator might have a bit strange
+# behavior during certain tests, like https://github.com/systemd/systemd/issues/27156
+if in_container; then
+ echo "Running in a container, skipping the rest of the fstab-generator tests..."
+ exit 0
+fi
+
+# In this mode we treat the entries as "regular" ones
+: "fstab-generator: initrd - initrd fstab"
+printf "%s\n" "${FSTAB_GENERAL[@]}" >"$FSTAB"
+cat "$FSTAB"
+SYSTEMD_IN_INITRD=1 SYSTEMD_FSTAB="$FSTAB" SYSTEMD_SYSROOT_FSTAB=/dev/null run_and_list "$GENERATOR_BIN" "$OUT_DIR"
+SYSTEMD_IN_INITRD=1 SYSTEMD_FSTAB="$FSTAB" SYSTEMD_SYSROOT_FSTAB=/dev/null check_fstab_mount_units FSTAB_GENERAL "$OUT_DIR"
+
+# In this mode we prefix the mount target with /sysroot and ignore all mounts
+# that don't have the x-initrd.mount flag
+: "fstab-generator: initrd - host fstab"
+printf "%s\n" "${FSTAB_GENERAL_ROOT[@]}" >"$FSTAB"
+cat "$FSTAB"
+SYSTEMD_IN_INITRD=1 SYSTEMD_FSTAB=/dev/null SYSTEMD_SYSROOT_FSTAB="$FSTAB" run_and_list "$GENERATOR_BIN" "$OUT_DIR"
+SYSTEMD_IN_INITRD=1 SYSTEMD_FSTAB=/dev/null SYSTEMD_SYSROOT_FSTAB="$FSTAB" check_fstab_mount_units FSTAB_GENERAL_ROOT "$OUT_DIR"
+
+# Check the default stuff that we (almost) always create in initrd
+: "fstab-generator: initrd default"
+SYSTEMD_IN_INITRD=1 SYSTEMD_FSTAB=/dev/null SYSTEMD_SYSROOT_FSTAB=/dev/null run_and_list "$GENERATOR_BIN" "$OUT_DIR"
+test -e "$OUT_DIR/normal/sysroot.mount"
+test -e "$OUT_DIR/normal/systemd-fsck-root.service"
+link_eq "$OUT_DIR/normal/initrd-root-fs.target.requires/sysroot.mount" "../sysroot.mount"
+link_eq "$OUT_DIR/normal/initrd-root-fs.target.requires/sysroot.mount" "../sysroot.mount"
+
+# systemd-sysroot-fstab-check is not in RHEL 8
+
+: "fstab-generator: duplicate"
+printf "%s\n" "${FSTAB_DUPLICATE[@]}" >"$FSTAB"
+cat "$FSTAB"
+(! SYSTEMD_FSTAB="$FSTAB" run_and_list "$GENERATOR_BIN" "$OUT_DIR")
+
+: "fstab-generator: invalid"
+printf "%s\n" "${FSTAB_INVALID[@]}" >"$FSTAB"
+cat "$FSTAB"
+# Don't care about the exit code here
+SYSTEMD_FSTAB="$FSTAB" run_and_list "$GENERATOR_BIN" "$OUT_DIR" || :
+# No mounts should get created here
+[[ "$(find "$OUT_DIR" -name "*.mount" | wc -l)" -eq 0 ]]
+
+: "fstab-generator: kernel args - fstab=0"
+printf "%s\n" "${FSTAB_MINIMAL[@]}" >"$FSTAB"
+SYSTEMD_FSTAB="$FSTAB" SYSTEMD_PROC_CMDLINE="fstab=0" run_and_list "$GENERATOR_BIN" "$OUT_DIR"
+(! SYSTEMD_FSTAB="$FSTAB" check_fstab_mount_units FSTAB_MINIMAL "$OUT_DIR")
+SYSTEMD_IN_INITRD=1 SYSTEMD_FSTAB="$FSTAB" SYSTEMD_PROC_CMDLINE="fstab=0" run_and_list "$GENERATOR_BIN" "$OUT_DIR"
+(! SYSTEMD_IN_INITRD=1 SYSTEMD_FSTAB="$FSTAB" check_fstab_mount_units FSTAB_MINIMAL "$OUT_DIR")
+
+: "fstab-generator: kernel args - rd.fstab=0"
+printf "%s\n" "${FSTAB_MINIMAL[@]}" >"$FSTAB"
+SYSTEMD_FSTAB="$FSTAB" SYSTEMD_PROC_CMDLINE="rd.fstab=0" run_and_list "$GENERATOR_BIN" "$OUT_DIR"
+SYSTEMD_FSTAB="$FSTAB" check_fstab_mount_units FSTAB_MINIMAL "$OUT_DIR"
+SYSTEMD_IN_INITRD=1 SYSTEMD_FSTAB="$FSTAB" SYSTEMD_PROC_CMDLINE="rd.fstab=0" run_and_list "$GENERATOR_BIN" "$OUT_DIR"
+(! SYSTEMD_IN_INITRD=1 SYSTEMD_FSTAB="$FSTAB" check_fstab_mount_units FSTAB_MINIMAL "$OUT_DIR")
+
+# systemd.swap kernel cmdline arguments is not supported on RHEL 8, see
+# 567a5307601728c618546c584f63307283fa8def
+
+# Possible TODO
+# - combine the rootfs & usrfs arguments and mix them with fstab entries
+# - systemd.volatile=
+: "fstab-generator: kernel args - root= + rootfstype= + rootflags="
+# shellcheck disable=SC2034
+EXPECTED_FSTAB=(
+ "/dev/disk/by-label/rootfs / ext4 noexec,ro 0 1"
+)
+CMDLINE="root=LABEL=rootfs rootfstype=ext4 rootflags=noexec"
+SYSTEMD_IN_INITRD=1 SYSTEMD_FSTAB=/dev/null SYSTEMD_SYSROOT_FSTAB=/dev/null SYSTEMD_PROC_CMDLINE="$CMDLINE" run_and_list "$GENERATOR_BIN" "$OUT_DIR"
+# The /proc/cmdline here is a dummy value to tell the in_initrd_host() function
+# we're parsing host's fstab, but it's all on the kernel cmdline instead
+SYSTEMD_IN_INITRD=1 SYSTEMD_SYSROOT_FSTAB=/proc/cmdline check_fstab_mount_units EXPECTED_FSTAB "$OUT_DIR"
+
+# This is a very basic sanity test that involves manual checks, since adding it
+# to the check_fstab_mount_units() function would make it way too complex
+# (yet another possible TODO)
+: "fstab-generator: kernel args - mount.usr= + mount.usrfstype= + mount.usrflags="
+CMDLINE="mount.usr=UUID=be780f43-8803-4a76-9732-02ceda6e9808 mount.usrfstype=ext4 mount.usrflags=noexec,nodev"
+SYSTEMD_IN_INITRD=1 SYSTEMD_FSTAB=/dev/null SYSTEMD_SYSROOT_FSTAB=/dev/null SYSTEMD_PROC_CMDLINE="$CMDLINE" run_and_list "$GENERATOR_BIN" "$OUT_DIR"
+cat "$OUT_DIR/normal/sysroot-usr.mount"
+# We don't do the /sysusr/usr/ -> /sysroot/usr/ dance on RHEL 8, see
+# 29a24ab28e9790680348b1ffab653a321fa49a67
+grep -qE "^What=/dev/disk/by-uuid/be780f43-8803-4a76-9732-02ceda6e9808$" "$OUT_DIR/normal/sysroot-usr.mount"
+grep -qE "^Where=/sysroot/usr$" "$OUT_DIR/normal/sysroot-usr.mount"
+grep -qE "^Type=ext4$" "$OUT_DIR/normal/sysroot-usr.mount"
+grep -qE "^Options=noexec,nodev,ro$" "$OUT_DIR/normal/sysroot-usr.mount"
+link_eq "$OUT_DIR/normal/initrd-fs.target.requires/sysroot-usr.mount" "../sysroot-usr.mount"
diff --git a/test/TEST-81-GENERATORS/testsuite.sh b/test/TEST-81-GENERATORS/testsuite.sh
new file mode 100755
index 0000000000..13c767e490
--- /dev/null
+++ b/test/TEST-81-GENERATORS/testsuite.sh
@@ -0,0 +1,14 @@
+#!/usr/bin/env bash
+# SPDX-License-Identifier: LGPL-2.1-or-later
+set -eux
+set -o pipefail
+
+: >/failed
+
+for script in "${0%.sh}".*.sh; do
+ echo "Running $script"
+ "./$script"
+done
+
+touch /testok
+rm /failed
diff --git a/test/test-functions b/test/test-functions
index f0cf6f8575..2345ab6e8a 100644
--- a/test/test-functions
+++ b/test/test-functions
@@ -23,7 +23,7 @@ fi
PATH_TO_INIT=$ROOTLIBDIR/systemd
-BASICTOOLS="test sh bash setsid loadkeys setfont login sulogin gzip sleep echo mount umount cryptsetup date dmsetup modprobe sed cmp tee rm true false chmod chown ln xargs env mktemp mountpoint useradd userdel timeout jq wc awk diff"
+BASICTOOLS="test sh bash setsid loadkeys setfont login sulogin gzip sleep echo mount umount cryptsetup date dmsetup modprobe sed cmp tee rm true false chmod chown ln xargs env mktemp mountpoint useradd userdel timeout jq wc awk diff dirname readlink"
DEBUGTOOLS="df free ls stty cat ps ln ip route dmesg dhclient mkdir cp ping dhclient strace less grep id tty touch du sort hostname find"
STATEDIR="${BUILD_DIR:-.}/test/$(basename $(dirname $(realpath $0)))"

@ -0,0 +1,37 @@
From c3a86a3ab06713e865db694a80c0c5034ab902af Mon Sep 17 00:00:00 2001
From: Michal Sekletar <msekleta@redhat.com>
Date: Wed, 20 Dec 2023 16:44:14 +0100
Subject: [PATCH] resolved: actually check authenticated flag of SOA
transaction
Fixes #25676
(cherry picked from commit 3b4cc1437b51fcc0b08da8cc3f5d1175eed25eb1)
Resolves: RHEL-6213
---
src/resolve/resolved-dns-transaction.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/src/resolve/resolved-dns-transaction.c b/src/resolve/resolved-dns-transaction.c
index c975215468..6f614d7493 100644
--- a/src/resolve/resolved-dns-transaction.c
+++ b/src/resolve/resolved-dns-transaction.c
@@ -2520,7 +2520,7 @@ static int dns_transaction_requires_rrsig(DnsTransaction *t, DnsResourceRecord *
if (r == 0)
continue;
- return t->answer_authenticated;
+ return dt->answer_authenticated;
}
return true;
@@ -2550,7 +2550,7 @@ static int dns_transaction_requires_rrsig(DnsTransaction *t, DnsResourceRecord *
* RR for us. This means we are not at a zone cut. In
* this case, we require authentication if the SOA
* lookup was authenticated too. */
- return t->answer_authenticated;
+ return dt->answer_authenticated;
}
return true;

@ -0,0 +1,70 @@
From 1b547e500207a469a533d819db5b7c6c22516ec3 Mon Sep 17 00:00:00 2001
From: Lennart Poettering <lennart@poettering.net>
Date: Thu, 17 Jan 2019 12:23:21 +0100
Subject: [PATCH] fd-util: rework how we determine highest possible fd
(cherry picked from commit 498e265df1c63212ec1a0991c135877a23f1ba4f)
Related: RHEL-18302
---
src/basic/fd-util.c | 37 ++++++++++++++++++++++++++-----------
1 file changed, 26 insertions(+), 11 deletions(-)
diff --git a/src/basic/fd-util.c b/src/basic/fd-util.c
index e085dc23b4..fea93d2039 100644
--- a/src/basic/fd-util.c
+++ b/src/basic/fd-util.c
@@ -188,6 +188,27 @@ _pure_ static bool fd_in_set(int fd, const int fdset[], size_t n_fdset) {
return false;
}
+static int get_max_fd(void) {
+ struct rlimit rl;
+ rlim_t m;
+
+ /* Return the highest possible fd, based RLIMIT_NOFILE, but enforcing FD_SETSIZE-1 as lower boundary
+ * and INT_MAX as upper boundary. */
+
+ if (getrlimit(RLIMIT_NOFILE, &rl) < 0)
+ return -errno;
+
+ m = MAX(rl.rlim_cur, rl.rlim_max);
+ if (m < FD_SETSIZE) /* Let's always cover at least 1024 fds */
+ return FD_SETSIZE-1;
+
+ if (m == RLIM_INFINITY || m > INT_MAX) /* Saturate on overflow. After all fds are "int", hence can
+ * never be above INT_MAX */
+ return INT_MAX;
+
+ return (int) (m - 1);
+}
+
int close_all_fds(const int except[], size_t n_except) {
_cleanup_closedir_ DIR *d = NULL;
struct dirent *de;
@@ -197,20 +218,14 @@ int close_all_fds(const int except[], size_t n_except) {
d = opendir("/proc/self/fd");
if (!d) {
- struct rlimit rl;
int fd, max_fd;
- /* When /proc isn't available (for example in chroots) the fallback is brute forcing through the fd
- * table */
-
- assert_se(getrlimit(RLIMIT_NOFILE, &rl) >= 0);
-
- if (rl.rlim_max == 0)
- return -EINVAL;
+ /* When /proc isn't available (for example in chroots) the fallback is brute forcing through
+ * the fd table */
- /* Let's take special care if the resource limit is set to unlimited, or actually larger than the range
- * of 'int'. Let's avoid implicit overflows. */
- max_fd = (rl.rlim_max == RLIM_INFINITY || rl.rlim_max > INT_MAX) ? INT_MAX : (int) (rl.rlim_max - 1);
+ max_fd = get_max_fd();
+ if (max_fd < 0)
+ return max_fd;
for (fd = 3; fd >= 0; fd = fd < max_fd ? fd + 1 : -1) {
int q;

@ -0,0 +1,70 @@
From 957edb063f3e9751bbdc05bd973bb2190ab0e917 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= <zbyszek@in.waw.pl>
Date: Fri, 15 Mar 2019 15:13:25 +0100
Subject: [PATCH] basic/fd-util: refuse "infinite" loop in close_all_fds()
I had a test machine with ulimit -n set to 1073741816 through pam
("session required pam_limits.so set_all", which copies the limits from PID 1,
left over from testing of #10921).
test-execute would "hang" and then fail with a timeout when running
exec-inaccessiblepaths-proc.service. It turns out that the problem was in
close_all_fds(), which would go to the fallback path of doing close()
1073741813 times. Let's just fail if we hit this case. This only matters
for cases where both /proc is inaccessible, and the *soft* limit has been
raised.
(gdb) bt
#0 0x00007f7e2e73fdc8 in close () from target:/lib64/libc.so.6
#1 0x00007f7e2e42cdfd in close_nointr ()
from target:/home/zbyszek/src/systemd-work3/build-rawhide/src/shared/libsystemd-shared-241.so
#2 0x00007f7e2e42d525 in close_all_fds ()
from target:/home/zbyszek/src/systemd-work3/build-rawhide/src/shared/libsystemd-shared-241.so
#3 0x0000000000426e53 in exec_child ()
#4 0x0000000000429578 in exec_spawn ()
#5 0x00000000004ce1ab in service_spawn ()
#6 0x00000000004cff77 in service_enter_start ()
#7 0x00000000004d028f in service_enter_start_pre ()
#8 0x00000000004d16f2 in service_start ()
#9 0x00000000004568f4 in unit_start ()
#10 0x0000000000416987 in test ()
#11 0x0000000000417632 in test_exec_inaccessiblepaths ()
#12 0x0000000000419362 in run_tests ()
#13 0x0000000000419632 in main ()
(cherry picked from commit 6a461d1f59850ff27bd254a3b71fe9ade0523e76)
Related: RHEL-18302
---
src/basic/fd-util.c | 11 +++++++++++
1 file changed, 11 insertions(+)
diff --git a/src/basic/fd-util.c b/src/basic/fd-util.c
index fea93d2039..5d0df11d7e 100644
--- a/src/basic/fd-util.c
+++ b/src/basic/fd-util.c
@@ -24,6 +24,10 @@
#include "stdio-util.h"
#include "util.h"
+/* The maximum number of iterations in the loop to close descriptors in the fallback case
+ * when /proc/self/fd/ is inaccessible. */
+#define MAX_FD_LOOP_LIMIT (1024*1024)
+
int close_nointr(int fd) {
assert(fd >= 0);
@@ -227,6 +231,13 @@ int close_all_fds(const int except[], size_t n_except) {
if (max_fd < 0)
return max_fd;
+ /* Refuse to do the loop over more too many elements. It's better to fail immediately than to
+ * spin the CPU for a long time. */
+ if (max_fd > MAX_FD_LOOP_LIMIT)
+ return log_debug_errno(EPERM,
+ "/proc/self/fd is inaccessible. Refusing to loop over %d potential fds.",
+ max_fd);
+
for (fd = 3; fd >= 0; fd = fd < max_fd ? fd + 1 : -1) {
int q;

@ -0,0 +1,110 @@
From c2665abd4cae74f262d9a522b94528841ad141d2 Mon Sep 17 00:00:00 2001
From: Lennart Poettering <lennart@poettering.net>
Date: Tue, 12 Oct 2021 15:53:27 +0200
Subject: [PATCH] fd-util: split out inner fallback loop of close_all_fds() as
close_all_fds_without_malloc()
(cherry picked from commit 11966552a88039869972ca4b450f622664bd1c5e)
Related: RHEL-18302
---
src/basic/fd-util.c | 63 +++++++++++++++++++++++++--------------------
src/basic/fd-util.h | 1 +
2 files changed, 36 insertions(+), 28 deletions(-)
diff --git a/src/basic/fd-util.c b/src/basic/fd-util.c
index 5d0df11d7e..7e4611dfda 100644
--- a/src/basic/fd-util.c
+++ b/src/basic/fd-util.c
@@ -213,44 +213,51 @@ static int get_max_fd(void) {
return (int) (m - 1);
}
-int close_all_fds(const int except[], size_t n_except) {
- _cleanup_closedir_ DIR *d = NULL;
- struct dirent *de;
- int r = 0;
+int close_all_fds_without_malloc(const int except[], size_t n_except) {
+ int max_fd, r = 0;
assert(n_except == 0 || except);
- d = opendir("/proc/self/fd");
- if (!d) {
- int fd, max_fd;
+ /* This is the inner fallback core of close_all_fds(). This never calls malloc() or opendir() or so
+ * and hence is safe to be called in signal handler context. Most users should call close_all_fds(),
+ * but when we assume we are called from signal handler context, then use this simpler call
+ * instead. */
- /* When /proc isn't available (for example in chroots) the fallback is brute forcing through
- * the fd table */
+ max_fd = get_max_fd();
+ if (max_fd < 0)
+ return max_fd;
- max_fd = get_max_fd();
- if (max_fd < 0)
- return max_fd;
+ /* Refuse to do the loop over more too many elements. It's better to fail immediately than to
+ * spin the CPU for a long time. */
+ if (max_fd > MAX_FD_LOOP_LIMIT)
+ return log_debug_errno(EPERM,
+ "Refusing to loop over %d potential fds.",
+ max_fd);
- /* Refuse to do the loop over more too many elements. It's better to fail immediately than to
- * spin the CPU for a long time. */
- if (max_fd > MAX_FD_LOOP_LIMIT)
- return log_debug_errno(EPERM,
- "/proc/self/fd is inaccessible. Refusing to loop over %d potential fds.",
- max_fd);
+ for (int fd = 3; fd >= 0; fd = fd < max_fd ? fd + 1 : -1) {
+ int q;
- for (fd = 3; fd >= 0; fd = fd < max_fd ? fd + 1 : -1) {
- int q;
+ if (fd_in_set(fd, except, n_except))
+ continue;
- if (fd_in_set(fd, except, n_except))
- continue;
+ q = close_nointr(fd);
+ if (q < 0 && q != -EBADF && r >= 0)
+ r = q;
+ }
- q = close_nointr(fd);
- if (q < 0 && q != -EBADF && r >= 0)
- r = q;
- }
+ return r;
+}
- return r;
- }
+int close_all_fds(const int except[], size_t n_except) {
+ _cleanup_closedir_ DIR *d = NULL;
+ struct dirent *de;
+ int r = 0;
+
+ assert(n_except == 0 || except);
+
+ d = opendir("/proc/self/fd");
+ if (!d)
+ return close_all_fds_without_malloc(except, n_except); /* ultimate fallback if /proc/ is not available */
FOREACH_DIRENT(de, d, return -errno) {
int fd = -1, q;
diff --git a/src/basic/fd-util.h b/src/basic/fd-util.h
index 8adc959da8..b2837d3588 100644
--- a/src/basic/fd-util.h
+++ b/src/basic/fd-util.h
@@ -54,6 +54,7 @@ int fd_nonblock(int fd, bool nonblock);
int fd_cloexec(int fd, bool cloexec);
int close_all_fds(const int except[], size_t n_except);
+int close_all_fds_without_malloc(const int except[], size_t n_except);
int same_fd(int a, int b);

@ -0,0 +1,29 @@
From 140e598dcf6b86007b1daba42c31253521964b2e Mon Sep 17 00:00:00 2001
From: Lennart Poettering <lennart@poettering.net>
Date: Thu, 29 Jul 2021 16:50:44 +0200
Subject: [PATCH] exec-util: use close_all_fds_without_malloc() from freeze()
(cherry picked from commit ab27b2fe56c6c4bd0295b248448adb1c698e9284)
Resolves: RHEL-18302
---
src/basic/process-util.c | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/src/basic/process-util.c b/src/basic/process-util.c
index 6016d83d41..9e2237375d 100644
--- a/src/basic/process-util.c
+++ b/src/basic/process-util.c
@@ -991,8 +991,10 @@ _noreturn_ void freeze(void) {
log_close();
- /* Make sure nobody waits for us on a socket anymore */
- close_all_fds(NULL, 0);
+ /* Make sure nobody waits for us (i.e. on one of our sockets) anymore. Note that we use
+ * close_all_fds_without_malloc() instead of plain close_all_fds() here, since we want this function
+ * to be compatible with being called from signal handlers. */
+ (void) close_all_fds_without_malloc(NULL, 0);
sync();

@ -0,0 +1,185 @@
From 5d0fc67965b48e05c28d0993368a3982efd03b4b Mon Sep 17 00:00:00 2001
From: Jan Macku <jamacku@redhat.com>
Date: Fri, 12 Jan 2024 16:01:43 +0100
Subject: [PATCH] ci: use source-git-automation composite Action
This will allow us maintain the source-git automation in separate repo
and reduce the duplication of the code and noise in the systemd repo.
rhel-only
Related: RHEL-1087
---
.../source-git-automation-on-demand.yml | 55 ++------------
.github/workflows/source-git-automation.yml | 72 ++-----------------
2 files changed, 9 insertions(+), 118 deletions(-)
diff --git a/.github/workflows/source-git-automation-on-demand.yml b/.github/workflows/source-git-automation-on-demand.yml
index 948708916d..0c72f9f210 100644
--- a/.github/workflows/source-git-automation-on-demand.yml
+++ b/.github/workflows/source-git-automation-on-demand.yml
@@ -1,5 +1,3 @@
----
-
name: Source git Automation Scheduled/On Demand
on:
schedule:
@@ -59,61 +57,16 @@ jobs:
pr-number: ${{ inputs.pr-number == 0 && fromJSON(needs.gather-pull-requests.outputs.pr-numbers) || fromJSON(needs.gather-pull-requests.outputs.pr-numbers-manual) }}
permissions:
+ # required for merging PRs
contents: write
- statuses: write
- checks: write
+ # required for PR comments and setting labels
pull-requests: write
steps:
- - name: Repository checkout
- uses: actions/checkout@v3
-
- - id: metadata
- name: Gather Pull Request Metadata
- uses: redhat-plumbers-in-action/gather-pull-request-metadata@v1
+ - name: Source-git Automation
+ uses: redhat-plumbers-in-action/source-git-automation@v1
with:
pr-number: ${{ matrix.pr-number }}
-
- - if: ${{ !cancelled() }}
- id: commit-linter
- name: Lint Commits
- uses: redhat-plumbers-in-action/advanced-commit-linter@v2
- with:
- pr-metadata: ${{ steps.metadata.outputs.metadata }}
- token: ${{ secrets.GITHUB_TOKEN }}
-
- # Validates tracker, changes tracker status, updates PR title
- - if: ${{ !cancelled() }}
- id: tracker-validator
- name: Validate Tracker
- uses: redhat-plumbers-in-action/tracker-validator@v1
- with:
- pr-metadata: ${{ steps.metadata.outputs.metadata }}
- component: systemd
- tracker: ${{ fromJSON(steps.commit-linter.outputs.validated-pr-metadata).validation.tracker.id }}
- tracker-type: ${{ fromJSON(steps.commit-linter.outputs.validated-pr-metadata).validation.tracker.type }}
- bugzilla-instance: https://bugzilla.redhat.com
- bugzilla-api-token: ${{ secrets.BUGZILLA_API_TOKEN }}
- jira-instance: https://issues.redhat.com
- jira-api-token: ${{ secrets.JIRA_API_TOKEN }}
- token: ${{ secrets.GITHUB_TOKEN }}
-
- - if: ${{ !cancelled() }}
- name: Pull Request Validator
- uses: redhat-plumbers-in-action/pull-request-validator@v1
- with:
- pr-metadata: ${{ steps.metadata.outputs.metadata }}
- token: ${{ secrets.GITHUB_TOKEN }}
-
- - id: auto-merge
- name: Auto Merge
- uses: redhat-plumbers-in-action/auto-merge@v1
- with:
- pr-metadata: ${{ steps.metadata.outputs.metadata }}
- tracker: ${{ fromJSON(steps.commit-linter.outputs.validated-pr-metadata).validation.tracker.id }}
- tracker-type: ${{ fromJSON(steps.commit-linter.outputs.validated-pr-metadata).validation.tracker.type }}
- bugzilla-instance: https://bugzilla.redhat.com
bugzilla-api-token: ${{ secrets.BUGZILLA_API_TOKEN }}
- jira-instance: https://issues.redhat.com
jira-api-token: ${{ secrets.JIRA_API_TOKEN }}
token: ${{ secrets.GITHUB_TOKEN }}
diff --git a/.github/workflows/source-git-automation.yml b/.github/workflows/source-git-automation.yml
index 95819baa8b..b6cefa67b1 100644
--- a/.github/workflows/source-git-automation.yml
+++ b/.github/workflows/source-git-automation.yml
@@ -26,83 +26,21 @@ jobs:
with:
name: pr-metadata
- commit-linter:
+ source-git-automation:
needs: [ download-metadata ]
runs-on: ubuntu-latest
- outputs:
- validated-pr-metadata: ${{ steps.commit-linter.outputs.validated-pr-metadata }}
-
- permissions:
- statuses: write
- checks: write
- pull-requests: write
-
- steps:
- - id: commit-linter
- name: Lint Commits
- uses: redhat-plumbers-in-action/advanced-commit-linter@v2
- with:
- pr-metadata: ${{ needs.download-metadata.outputs.pr-metadata }}
- token: ${{ secrets.GITHUB_TOKEN }}
-
- # Validates tracker, changes tracker status, updates PR title
- tracker-validator:
- if: ${{ !cancelled() }}
- needs: [ download-metadata, commit-linter ]
- runs-on: ubuntu-latest
-
- permissions:
- checks: write
- pull-requests: write
-
- steps:
- - name: Validate Tracker
- uses: redhat-plumbers-in-action/tracker-validator@v1
- with:
- pr-metadata: ${{ needs.download-metadata.outputs.pr-metadata }}
- component: systemd
- tracker: ${{ fromJSON(needs.commit-linter.outputs.validated-pr-metadata).validation.tracker.id }}
- tracker-type: ${{ fromJSON(needs.commit-linter.outputs.validated-pr-metadata).validation.tracker.type }}
- bugzilla-instance: https://bugzilla.redhat.com
- bugzilla-api-token: ${{ secrets.BUGZILLA_API_TOKEN }}
- jira-instance: https://issues.redhat.com
- jira-api-token: ${{ secrets.JIRA_API_TOKEN }}
- token: ${{ secrets.GITHUB_TOKEN }}
-
- pull-request-validator:
- needs: [ download-metadata ]
- runs-on: ubuntu-latest
-
- permissions:
- checks: write
- pull-requests: write
-
- steps:
- - name: Pull Request Validator
- uses: redhat-plumbers-in-action/pull-request-validator@v1
- with:
- pr-metadata: ${{ needs.download-metadata.outputs.pr-metadata }}
- token: ${{ secrets.GITHUB_TOKEN }}
-
- auto-merge:
- needs: [ download-metadata, commit-linter, tracker-validator, pull-request-validator ]
- runs-on: ubuntu-latest
-
permissions:
+ # required for merging PRs
contents: write
- checks: write
+ # required for PR comments and setting labels
pull-requests: write
steps:
- - name: Auto Merge
- uses: redhat-plumbers-in-action/auto-merge@v1
+ - name: Source-git Automation
+ uses: redhat-plumbers-in-action/source-git-automation@v1
with:
pr-metadata: ${{ needs.download-metadata.outputs.pr-metadata }}
- tracker: ${{ fromJSON(needs.commit-linter.outputs.validated-pr-metadata).validation.tracker.id }}
- tracker-type: ${{ fromJSON(needs.commit-linter.outputs.validated-pr-metadata).validation.tracker.type }}
- bugzilla-instance: https://bugzilla.redhat.com
bugzilla-api-token: ${{ secrets.BUGZILLA_API_TOKEN }}
- jira-instance: https://issues.redhat.com
jira-api-token: ${{ secrets.JIRA_API_TOKEN }}
token: ${{ secrets.GITHUB_TOKEN }}

@ -0,0 +1,29 @@
From fd21fb2e2e3bbbd937d120197b11c740d608fb19 Mon Sep 17 00:00:00 2001
From: Jan Macku <jamacku@redhat.com>
Date: Fri, 12 Jan 2024 16:03:09 +0100
Subject: [PATCH] ci: increase the cron interval to 45 minutes
This should help us to avoid hitting the rate limit on the GitHub API.
rhel-only
Related: RHEL-1087
---
.github/workflows/source-git-automation-on-demand.yml | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/.github/workflows/source-git-automation-on-demand.yml b/.github/workflows/source-git-automation-on-demand.yml
index 0c72f9f210..6aeee51e6d 100644
--- a/.github/workflows/source-git-automation-on-demand.yml
+++ b/.github/workflows/source-git-automation-on-demand.yml
@@ -1,8 +1,8 @@
name: Source git Automation Scheduled/On Demand
on:
schedule:
- # Workflow runs every 15 minutes
- - cron: '*/15 * * * *'
+ # Workflow runs every 45 minutes
+ - cron: '*/45 * * * *'
workflow_dispatch:
inputs:
pr-number:

@ -0,0 +1,31 @@
From 42e3739198e41c65b986f69a53bc6c93f7e112be Mon Sep 17 00:00:00 2001
From: Jan Macku <jamacku@redhat.com>
Date: Fri, 12 Jan 2024 16:04:22 +0100
Subject: [PATCH] ci: add all Z-Stream versions to array of allowed versions
rhel-only
Related: RHEL-1087
---
.github/tracker-validator.yml | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/.github/tracker-validator.yml b/.github/tracker-validator.yml
index 500dce3d92..b09f702dd9 100644
--- a/.github/tracker-validator.yml
+++ b/.github/tracker-validator.yml
@@ -7,8 +7,14 @@ products:
- Red Hat Enterprise Linux 8
- CentOS Stream 8
- rhel-8.2.0
+ - rhel-8.2.0.z
- rhel-8.4.0
+ - rhel-8.4.0.z
- rhel-8.6.0
+ - rhel-8.6.0.z
- rhel-8.8.0
+ - rhel-8.8.0.z
- rhel-8.9.0
+ - rhel-8.9.0.z
- rhel-8.10.0
+ - rhel-8.10.0.z

@ -0,0 +1,215 @@
From dd3c13f364e03e843d838bf925a5fc85513343ed Mon Sep 17 00:00:00 2001
From: Lennart Poettering <lennart@poettering.net>
Date: Mon, 7 Jan 2019 17:48:28 +0100
Subject: [PATCH] tree-wide: always declare bitflag enums the same way
let's always use the 1 << x syntax. No change of behaviour or even of
the compiled binary.
(cherry picked from commit be0b7a1a66fd269b644124c4633088ab2224d1fb)
Resolves: RHEL-2857
---
src/basic/btrfs-util.h | 16 ++++++++--------
src/basic/cgroup-util.h | 6 +++---
src/basic/extract-word.h | 12 ++++++------
src/basic/unit-name.h | 10 +++++-----
src/libsystemd/sd-bus/bus-dump.h | 4 ++--
src/libsystemd/sd-bus/bus-protocol.h | 12 ++++++------
src/login/logind-inhibit.h | 18 +++++++++---------
src/resolve/resolved-dns-answer.h | 10 +++++-----
8 files changed, 44 insertions(+), 44 deletions(-)
diff --git a/src/basic/btrfs-util.h b/src/basic/btrfs-util.h
index a594387b5a..967627991f 100644
--- a/src/basic/btrfs-util.h
+++ b/src/basic/btrfs-util.h
@@ -27,17 +27,17 @@ typedef struct BtrfsQuotaInfo {
} BtrfsQuotaInfo;
typedef enum BtrfsSnapshotFlags {
- BTRFS_SNAPSHOT_FALLBACK_COPY = 1, /* If the source isn't a subvolume, reflink everything */
- BTRFS_SNAPSHOT_READ_ONLY = 2,
- BTRFS_SNAPSHOT_RECURSIVE = 4,
- BTRFS_SNAPSHOT_QUOTA = 8,
- BTRFS_SNAPSHOT_FALLBACK_DIRECTORY = 16, /* If the destination doesn't support subvolumes, reflink/copy instead */
- BTRFS_SNAPSHOT_FALLBACK_IMMUTABLE = 32, /* When we can't create a subvolume, use the FS_IMMUTABLE attribute for indicating read-only */
+ BTRFS_SNAPSHOT_FALLBACK_COPY = 1 << 0, /* If the source isn't a subvolume, reflink everything */
+ BTRFS_SNAPSHOT_READ_ONLY = 1 << 1,
+ BTRFS_SNAPSHOT_RECURSIVE = 1 << 2,
+ BTRFS_SNAPSHOT_QUOTA = 1 << 3,
+ BTRFS_SNAPSHOT_FALLBACK_DIRECTORY = 1 << 4, /* If the destination doesn't support subvolumes, reflink/copy instead */
+ BTRFS_SNAPSHOT_FALLBACK_IMMUTABLE = 1 << 5, /* When we can't create a subvolume, use the FS_IMMUTABLE attribute for indicating read-only */
} BtrfsSnapshotFlags;
typedef enum BtrfsRemoveFlags {
- BTRFS_REMOVE_RECURSIVE = 1,
- BTRFS_REMOVE_QUOTA = 2,
+ BTRFS_REMOVE_RECURSIVE = 1 << 0,
+ BTRFS_REMOVE_QUOTA = 1 << 1,
} BtrfsRemoveFlags;
int btrfs_is_filesystem(int fd);
diff --git a/src/basic/cgroup-util.h b/src/basic/cgroup-util.h
index 1210b38a83..65d2dbd4b6 100644
--- a/src/basic/cgroup-util.h
+++ b/src/basic/cgroup-util.h
@@ -136,9 +136,9 @@ int cg_enumerate_subgroups(const char *controller, const char *path, DIR **_d);
int cg_read_subgroup(DIR *d, char **fn);
typedef enum CGroupFlags {
- CGROUP_SIGCONT = 1,
- CGROUP_IGNORE_SELF = 2,
- CGROUP_REMOVE = 4,
+ CGROUP_SIGCONT = 1 << 0,
+ CGROUP_IGNORE_SELF = 1 << 1,
+ CGROUP_REMOVE = 1 << 2,
} CGroupFlags;
typedef void (*cg_kill_log_func_t)(pid_t pid, int sig, void *userdata);
diff --git a/src/basic/extract-word.h b/src/basic/extract-word.h
index 8c63b7c306..705ebbe95b 100644
--- a/src/basic/extract-word.h
+++ b/src/basic/extract-word.h
@@ -4,12 +4,12 @@
#include "macro.h"
typedef enum ExtractFlags {
- EXTRACT_RELAX = 1,
- EXTRACT_CUNESCAPE = 2,
- EXTRACT_CUNESCAPE_RELAX = 4,
- EXTRACT_QUOTES = 8,
- EXTRACT_DONT_COALESCE_SEPARATORS = 16,
- EXTRACT_RETAIN_ESCAPE = 32,
+ EXTRACT_RELAX = 1 << 0,
+ EXTRACT_CUNESCAPE = 1 << 1,
+ EXTRACT_CUNESCAPE_RELAX = 1 << 2,
+ EXTRACT_QUOTES = 1 << 3,
+ EXTRACT_DONT_COALESCE_SEPARATORS = 1 << 4,
+ EXTRACT_RETAIN_ESCAPE = 1 << 5,
} ExtractFlags;
int extract_first_word(const char **p, char **ret, const char *separators, ExtractFlags flags);
diff --git a/src/basic/unit-name.h b/src/basic/unit-name.h
index 602295af8f..7df532bbc8 100644
--- a/src/basic/unit-name.h
+++ b/src/basic/unit-name.h
@@ -9,9 +9,9 @@
#define UNIT_NAME_MAX 256
typedef enum UnitNameFlags {
- UNIT_NAME_PLAIN = 1, /* Allow foo.service */
- UNIT_NAME_INSTANCE = 2, /* Allow foo@bar.service */
- UNIT_NAME_TEMPLATE = 4, /* Allow foo@.service */
+ UNIT_NAME_PLAIN = 1 << 0, /* Allow foo.service */
+ UNIT_NAME_INSTANCE = 1 << 1, /* Allow foo@bar.service */
+ UNIT_NAME_TEMPLATE = 1 << 2, /* Allow foo@.service */
UNIT_NAME_ANY = UNIT_NAME_PLAIN|UNIT_NAME_INSTANCE|UNIT_NAME_TEMPLATE,
} UnitNameFlags;
@@ -53,8 +53,8 @@ int unit_name_from_path_instance(const char *prefix, const char *path, const cha
int unit_name_to_path(const char *name, char **ret);
typedef enum UnitNameMangle {
- UNIT_NAME_MANGLE_GLOB = 1,
- UNIT_NAME_MANGLE_WARN = 2,
+ UNIT_NAME_MANGLE_GLOB = 1 << 0,
+ UNIT_NAME_MANGLE_WARN = 1 << 1,
} UnitNameMangle;
int unit_name_mangle_with_suffix(const char *name, UnitNameMangle flags, const char *suffix, char **ret);
diff --git a/src/libsystemd/sd-bus/bus-dump.h b/src/libsystemd/sd-bus/bus-dump.h
index 8e47411a45..7c1f81edec 100644
--- a/src/libsystemd/sd-bus/bus-dump.h
+++ b/src/libsystemd/sd-bus/bus-dump.h
@@ -10,8 +10,8 @@
#include "sd-bus.h"
enum {
- BUS_MESSAGE_DUMP_WITH_HEADER = 1,
- BUS_MESSAGE_DUMP_SUBTREE_ONLY = 2,
+ BUS_MESSAGE_DUMP_WITH_HEADER = 1 << 0,
+ BUS_MESSAGE_DUMP_SUBTREE_ONLY = 1 << 1,
};
int bus_message_dump(sd_bus_message *m, FILE *f, unsigned flags);
diff --git a/src/libsystemd/sd-bus/bus-protocol.h b/src/libsystemd/sd-bus/bus-protocol.h
index 20d19d4022..f96d4b39aa 100644
--- a/src/libsystemd/sd-bus/bus-protocol.h
+++ b/src/libsystemd/sd-bus/bus-protocol.h
@@ -57,9 +57,9 @@ enum {
/* Flags */
enum {
- BUS_MESSAGE_NO_REPLY_EXPECTED = 1,
- BUS_MESSAGE_NO_AUTO_START = 2,
- BUS_MESSAGE_ALLOW_INTERACTIVE_AUTHORIZATION = 4,
+ BUS_MESSAGE_NO_REPLY_EXPECTED = 1 << 0,
+ BUS_MESSAGE_NO_AUTO_START = 1 << 1,
+ BUS_MESSAGE_ALLOW_INTERACTIVE_AUTHORIZATION = 1 << 2,
};
/* Header fields */
@@ -81,9 +81,9 @@ enum {
/* RequestName parameters */
enum {
- BUS_NAME_ALLOW_REPLACEMENT = 1,
- BUS_NAME_REPLACE_EXISTING = 2,
- BUS_NAME_DO_NOT_QUEUE = 4
+ BUS_NAME_ALLOW_REPLACEMENT = 1 << 0,
+ BUS_NAME_REPLACE_EXISTING = 1 << 1,
+ BUS_NAME_DO_NOT_QUEUE = 1 << 2,
};
/* RequestName returns */
diff --git a/src/login/logind-inhibit.h b/src/login/logind-inhibit.h
index d358a48559..650587106d 100644
--- a/src/login/logind-inhibit.h
+++ b/src/login/logind-inhibit.h
@@ -4,15 +4,15 @@
typedef struct Inhibitor Inhibitor;
typedef enum InhibitWhat {
- INHIBIT_SHUTDOWN = 1,
- INHIBIT_SLEEP = 2,
- INHIBIT_IDLE = 4,
- INHIBIT_HANDLE_POWER_KEY = 8,
- INHIBIT_HANDLE_SUSPEND_KEY = 16,
- INHIBIT_HANDLE_HIBERNATE_KEY = 32,
- INHIBIT_HANDLE_LID_SWITCH = 64,
- _INHIBIT_WHAT_MAX = 128,
- _INHIBIT_WHAT_INVALID = -1
+ INHIBIT_SHUTDOWN = 1 << 0,
+ INHIBIT_SLEEP = 1 << 1,
+ INHIBIT_IDLE = 1 << 2,
+ INHIBIT_HANDLE_POWER_KEY = 1 << 3,
+ INHIBIT_HANDLE_SUSPEND_KEY = 1 << 4,
+ INHIBIT_HANDLE_HIBERNATE_KEY = 1 << 5,
+ INHIBIT_HANDLE_LID_SWITCH = 1 << 6,
+ _INHIBIT_WHAT_MAX = 1 << 7,
+ _INHIBIT_WHAT_INVALID = -1
} InhibitWhat;
typedef enum InhibitMode {
diff --git a/src/resolve/resolved-dns-answer.h b/src/resolve/resolved-dns-answer.h
index aff594a00e..cc90a82529 100644
--- a/src/resolve/resolved-dns-answer.h
+++ b/src/resolve/resolved-dns-answer.h
@@ -15,11 +15,11 @@ typedef struct DnsAnswerItem DnsAnswerItem;
* Note that we usually encode the empty DnsAnswer object as a simple NULL. */
typedef enum DnsAnswerFlags {
- DNS_ANSWER_AUTHENTICATED = 1, /* Item has been authenticated */
- DNS_ANSWER_CACHEABLE = 2, /* Item is subject to caching */
- DNS_ANSWER_SHARED_OWNER = 4, /* For mDNS: RRset may be owner by multiple peers */
- DNS_ANSWER_CACHE_FLUSH = 8, /* For mDNS: sets cache-flush bit in the rrclass of response records */
- DNS_ANSWER_GOODBYE = 16, /* For mDNS: item is subject to disappear */
+ DNS_ANSWER_AUTHENTICATED = 1 << 0, /* Item has been authenticated */
+ DNS_ANSWER_CACHEABLE = 1 << 1, /* Item is subject to caching */
+ DNS_ANSWER_SHARED_OWNER = 1 << 2, /* For mDNS: RRset may be owner by multiple peers */
+ DNS_ANSWER_CACHE_FLUSH = 1 << 3, /* For mDNS: sets cache-flush bit in the rrclass of response records */
+ DNS_ANSWER_GOODBYE = 1 << 4, /* For mDNS: item is subject to disappear */
} DnsAnswerFlags;
struct DnsAnswerItem {

@ -0,0 +1,343 @@
From d3072cec8cec84c6cb6e5771a5084e64f78c7e80 Mon Sep 17 00:00:00 2001
From: Robert Marko <robert.marko@sartura.hr>
Date: Fri, 14 Aug 2020 13:10:18 +0200
Subject: [PATCH] login: Add KEY_RESTART handling
KEY_RESTART is widely used in Linux to indicate device reboot.
So lets handle it in the same fashion as KEY_POWER.
Signed-off-by: Robert Marko <robert.marko@sartura.hr>
(cherry picked from commit adbb2b6afed7858f64f5b940579f6efe79eee997)
Resolves: RHEL-2857
---
man/logind.conf.xml | 26 +++++++++++++++----------
src/login/logind-button.c | 25 +++++++++++++++++++-----
src/login/logind-core.c | 4 ++++
src/login/logind-dbus.c | 1 +
src/login/logind-gperf.gperf | 2 ++
src/login/logind-inhibit.c | 14 ++++++++++++-
src/login/logind-inhibit.h | 3 ++-
src/login/logind.conf.in | 2 ++
src/login/logind.h | 2 ++
src/login/org.freedesktop.login1.policy | 11 +++++++++++
src/systemd/sd-messages.h | 2 ++
11 files changed, 75 insertions(+), 17 deletions(-)
diff --git a/man/logind.conf.xml b/man/logind.conf.xml
index 00b5b1f2e8..56981c1837 100644
--- a/man/logind.conf.xml
+++ b/man/logind.conf.xml
@@ -202,10 +202,11 @@
<term><varname>HandleLidSwitch=</varname></term>
<term><varname>HandleLidSwitchExternalPower=</varname></term>
<term><varname>HandleLidSwitchDocked=</varname></term>
+ <term><varname>HandleRebootKey=</varname></term>
<listitem><para>Controls how logind shall handle the
- system power and sleep keys and the lid switch to trigger
- actions such as system power-off or suspend. Can be one of
+ system power, reboot and sleep keys and the lid switch to trigger
+ actions such as system power-off, reboot or suspend. Can be one of
<literal>ignore</literal>,
<literal>poweroff</literal>,
<literal>reboot</literal>,
@@ -222,7 +223,8 @@
in the respective event. Only input devices with the
<literal>power-switch</literal> udev tag will be watched for
key/lid switch events. <varname>HandlePowerKey=</varname>
- defaults to <literal>poweroff</literal>.
+ defaults to <literal>poweroff</literal>, <varname>HandleRebootKey=</varname>
+ defaults to <literal>reboot</literal>.
<varname>HandleSuspendKey=</varname> and
<varname>HandleLidSwitch=</varname> default to
<literal>suspend</literal>.
@@ -243,7 +245,8 @@
<para>A different application may disable logind's handling of system power and
sleep keys and the lid switch by taking a low-level inhibitor lock
(<literal>handle-power-key</literal>, <literal>handle-suspend-key</literal>,
- <literal>handle-hibernate-key</literal>, <literal>handle-lid-switch</literal>).
+ <literal>handle-hibernate-key</literal>, <literal>handle-lid-switch</literal>,
+ <literal>handle-reboot-switch</literal>).
This is most commonly used by graphical desktop environments
to take over suspend and hibernation handling, and to use their own configuration
mechanisms. If a low-level inhibitor lock is taken, logind will not take any
@@ -256,20 +259,23 @@
<term><varname>SuspendKeyIgnoreInhibited=</varname></term>
<term><varname>HibernateKeyIgnoreInhibited=</varname></term>
<term><varname>LidSwitchIgnoreInhibited=</varname></term>
+ <term><varname>RebootKeyIgnoreInhibited=</varname></term>
<listitem><para>Controls whether actions that <command>systemd-logind</command>
- takes when the power and sleep keys and the lid switch are triggered are subject
- to high-level inhibitor locks ("shutdown", "sleep", "idle"). Low level inhibitor
+ takes when the power, reboot and sleep keys and the lid switch are triggered are subject
+ to high-level inhibitor locks ("shutdown", "reboot", "sleep", "idle"). Low level inhibitor
locks (<literal>handle-power-key</literal>, <literal>handle-suspend-key</literal>,
- <literal>handle-hibernate-key</literal>, <literal>handle-lid-switch</literal>),
+ <literal>handle-hibernate-key</literal>, <literal>handle-lid-switch</literal>,
+ <literal>handle-reboot-key</literal>),
are always honored, irrespective of this setting.</para>
<para>These settings take boolean arguments. If <literal>no</literal>, the
inhibitor locks taken by applications are respected. If <literal>yes</literal>,
- "shutdown", "sleep", and "idle" inhibitor locks are ignored.
+ "shutdown", "reboot" "sleep", and "idle" inhibitor locks are ignored.
<varname>PowerKeyIgnoreInhibited=</varname>,
- <varname>SuspendKeyIgnoreInhibited=</varname>, and
- <varname>HibernateKeyIgnoreInhibited=</varname> default to <literal>no</literal>.
+ <varname>SuspendKeyIgnoreInhibited=</varname>,
+ <varname>HibernateKeyIgnoreInhibited=</varname> and
+ <varname>RebootKeyIgnoreInhibited=</varname> default to <literal>no</literal>.
<varname>LidSwitchIgnoreInhibited=</varname> defaults to <literal>yes</literal>.
This means that when <command>systemd-logind</command> is handling events by
itself (no low level inhibitor locks are taken by another application), the lid
diff --git a/src/login/logind-button.c b/src/login/logind-button.c
index 9944eb2316..48fc004198 100644
--- a/src/login/logind-button.c
+++ b/src/login/logind-button.c
@@ -15,7 +15,7 @@
#include "string-util.h"
#include "util.h"
-#define CONST_MAX4(a, b, c, d) CONST_MAX(CONST_MAX(a, b), CONST_MAX(c, d))
+#define CONST_MAX5(a, b, c, d, e) CONST_MAX(CONST_MAX(a, b), CONST_MAX(CONST_MAX(c, d), e))
#define ULONG_BITS (sizeof(unsigned long)*8)
@@ -159,7 +159,20 @@ static int button_dispatch(sd_event_source *s, int fd, uint32_t revents, void *u
manager_handle_action(b->manager, INHIBIT_HANDLE_POWER_KEY, b->manager->handle_power_key, b->manager->power_key_ignore_inhibited, true);
break;
- /* The kernel is a bit confused here:
+ /* The kernel naming is a bit confusing here:
+ KEY_RESTART was probably introduced for media playback purposes, but
+ is now being predominantly used to indicate device reboot.
+ */
+
+ case KEY_RESTART:
+ log_struct(LOG_INFO,
+ LOG_MESSAGE("Reboot key pressed."),
+ "MESSAGE_ID=" SD_MESSAGE_REBOOT_KEY_STR);
+
+ manager_handle_action(b->manager, INHIBIT_HANDLE_REBOOT_KEY, b->manager->handle_reboot_key, b->manager->reboot_key_ignore_inhibited, true);
+ break;
+
+ /* The kernel naming is a bit confusing here:
KEY_SLEEP = suspend-to-ram, which everybody else calls "suspend"
KEY_SUSPEND = suspend-to-disk, which everybody else calls "hibernate"
@@ -233,7 +246,7 @@ static int button_suitable(Button *b) {
return -errno;
if (bitset_get(types, EV_KEY)) {
- unsigned long keys[CONST_MAX4(KEY_POWER, KEY_POWER2, KEY_SLEEP, KEY_SUSPEND)/ULONG_BITS+1];
+ unsigned long keys[CONST_MAX5(KEY_POWER, KEY_POWER2, KEY_SLEEP, KEY_SUSPEND, KEY_RESTART)/ULONG_BITS+1];
if (ioctl(b->fd, EVIOCGBIT(EV_KEY, sizeof(keys)), keys) < 0)
return -errno;
@@ -241,7 +254,8 @@ static int button_suitable(Button *b) {
if (bitset_get(keys, KEY_POWER) ||
bitset_get(keys, KEY_POWER2) ||
bitset_get(keys, KEY_SLEEP) ||
- bitset_get(keys, KEY_SUSPEND))
+ bitset_get(keys, KEY_SUSPEND) ||
+ bitset_get(keys, KEY_RESTART))
return true;
}
@@ -262,7 +276,7 @@ static int button_suitable(Button *b) {
static int button_set_mask(Button *b) {
unsigned long
types[CONST_MAX(EV_KEY, EV_SW)/ULONG_BITS+1] = {},
- keys[CONST_MAX4(KEY_POWER, KEY_POWER2, KEY_SLEEP, KEY_SUSPEND)/ULONG_BITS+1] = {},
+ keys[CONST_MAX5(KEY_POWER, KEY_POWER2, KEY_SLEEP, KEY_SUSPEND, KEY_RESTART)/ULONG_BITS+1] = {},
switches[CONST_MAX(SW_LID, SW_DOCK)/ULONG_BITS+1] = {};
struct input_mask mask;
@@ -287,6 +301,7 @@ static int button_set_mask(Button *b) {
bitset_put(keys, KEY_POWER2);
bitset_put(keys, KEY_SLEEP);
bitset_put(keys, KEY_SUSPEND);
+ bitset_put(keys, KEY_RESTART);
mask = (struct input_mask) {
.type = EV_KEY,
diff --git a/src/login/logind-core.c b/src/login/logind-core.c
index abe6eecffb..81ec4f2653 100644
--- a/src/login/logind-core.c
+++ b/src/login/logind-core.c
@@ -39,10 +39,12 @@ void manager_reset_config(Manager *m) {
m->handle_lid_switch = HANDLE_SUSPEND;
m->handle_lid_switch_ep = _HANDLE_ACTION_INVALID;
m->handle_lid_switch_docked = HANDLE_IGNORE;
+ m->handle_reboot_key = HANDLE_REBOOT;
m->power_key_ignore_inhibited = false;
m->suspend_key_ignore_inhibited = false;
m->hibernate_key_ignore_inhibited = false;
m->lid_switch_ignore_inhibited = true;
+ m->reboot_key_ignore_inhibited = false;
m->holdoff_timeout_usec = 30 * USEC_PER_SEC;
@@ -698,6 +700,8 @@ bool manager_all_buttons_ignored(Manager *m) {
return false;
if (m->handle_lid_switch_docked != HANDLE_IGNORE)
return false;
+ if (m->handle_reboot_key != HANDLE_IGNORE)
+ return false;
return true;
}
diff --git a/src/login/logind-dbus.c b/src/login/logind-dbus.c
index dbac406035..61fd47999d 100644
--- a/src/login/logind-dbus.c
+++ b/src/login/logind-dbus.c
@@ -2616,6 +2616,7 @@ static int method_inhibit(sd_bus_message *message, void *userdata, sd_bus_error
w == INHIBIT_IDLE ? "org.freedesktop.login1.inhibit-block-idle" :
w == INHIBIT_HANDLE_POWER_KEY ? "org.freedesktop.login1.inhibit-handle-power-key" :
w == INHIBIT_HANDLE_SUSPEND_KEY ? "org.freedesktop.login1.inhibit-handle-suspend-key" :
+ w == INHIBIT_HANDLE_REBOOT_KEY ? "org.freedesktop.login1.inhibit-handle-reboot-key" :
w == INHIBIT_HANDLE_HIBERNATE_KEY ? "org.freedesktop.login1.inhibit-handle-hibernate-key" :
"org.freedesktop.login1.inhibit-handle-lid-switch",
NULL,
diff --git a/src/login/logind-gperf.gperf b/src/login/logind-gperf.gperf
index 214ac5c4a3..c49703698a 100644
--- a/src/login/logind-gperf.gperf
+++ b/src/login/logind-gperf.gperf
@@ -30,10 +30,12 @@ Login.HandleHibernateKey, config_parse_handle_action, 0, offse
Login.HandleLidSwitch, config_parse_handle_action, 0, offsetof(Manager, handle_lid_switch)
Login.HandleLidSwitchExternalPower, config_parse_handle_action, 0, offsetof(Manager, handle_lid_switch_ep)
Login.HandleLidSwitchDocked, config_parse_handle_action, 0, offsetof(Manager, handle_lid_switch_docked)
+Login.HandleRebootKey, config_parse_handle_action, 0, offsetof(Manager, handle_reboot_key)
Login.PowerKeyIgnoreInhibited, config_parse_bool, 0, offsetof(Manager, power_key_ignore_inhibited)
Login.SuspendKeyIgnoreInhibited, config_parse_bool, 0, offsetof(Manager, suspend_key_ignore_inhibited)
Login.HibernateKeyIgnoreInhibited, config_parse_bool, 0, offsetof(Manager, hibernate_key_ignore_inhibited)
Login.LidSwitchIgnoreInhibited, config_parse_bool, 0, offsetof(Manager, lid_switch_ignore_inhibited)
+Login.RebootKeyIgnoreInhibited, config_parse_bool, 0, offsetof(Manager, reboot_key_ignore_inhibited)
Login.HoldoffTimeoutSec, config_parse_sec, 0, offsetof(Manager, holdoff_timeout_usec)
Login.IdleAction, config_parse_handle_action, 0, offsetof(Manager, idle_action)
Login.IdleActionSec, config_parse_sec, 0, offsetof(Manager, idle_action_usec)
diff --git a/src/login/logind-inhibit.c b/src/login/logind-inhibit.c
index b1f45baaca..27b862e7c4 100644
--- a/src/login/logind-inhibit.c
+++ b/src/login/logind-inhibit.c
@@ -405,7 +405,15 @@ bool manager_is_inhibited(
}
const char *inhibit_what_to_string(InhibitWhat w) {
- static thread_local char buffer[97];
+ static thread_local char buffer[STRLEN(
+ "shutdown:"
+ "sleep:"
+ "idle:"
+ "handle-power-key:"
+ "handle-suspend-key:"
+ "handle-hibernate-key:"
+ "handle-lid-switch:"
+ "handle-reboot-key")+1];
char *p;
if (w < 0 || w >= _INHIBIT_WHAT_MAX)
@@ -426,6 +434,8 @@ const char *inhibit_what_to_string(InhibitWhat w) {
p = stpcpy(p, "handle-hibernate-key:");
if (w & INHIBIT_HANDLE_LID_SWITCH)
p = stpcpy(p, "handle-lid-switch:");
+ if (w & INHIBIT_HANDLE_REBOOT_KEY)
+ p = stpcpy(p, "handle-reboot-key:");
if (p > buffer)
*(p-1) = 0;
@@ -455,6 +465,8 @@ InhibitWhat inhibit_what_from_string(const char *s) {
what |= INHIBIT_HANDLE_HIBERNATE_KEY;
else if (l == 17 && strneq(word, "handle-lid-switch", l))
what |= INHIBIT_HANDLE_LID_SWITCH;
+ else if (l == 17 && strneq(word, "handle-reboot-key", l))
+ what |= INHIBIT_HANDLE_REBOOT_KEY;
else
return _INHIBIT_WHAT_INVALID;
}
diff --git a/src/login/logind-inhibit.h b/src/login/logind-inhibit.h
index 650587106d..51095a0bde 100644
--- a/src/login/logind-inhibit.h
+++ b/src/login/logind-inhibit.h
@@ -11,7 +11,8 @@ typedef enum InhibitWhat {
INHIBIT_HANDLE_SUSPEND_KEY = 1 << 4,
INHIBIT_HANDLE_HIBERNATE_KEY = 1 << 5,
INHIBIT_HANDLE_LID_SWITCH = 1 << 6,
- _INHIBIT_WHAT_MAX = 1 << 7,
+ INHIBIT_HANDLE_REBOOT_KEY = 1 << 7,
+ _INHIBIT_WHAT_MAX = 1 << 8,
_INHIBIT_WHAT_INVALID = -1
} InhibitWhat;
diff --git a/src/login/logind.conf.in b/src/login/logind.conf.in
index a62c2b0b57..95f2d48d02 100644
--- a/src/login/logind.conf.in
+++ b/src/login/logind.conf.in
@@ -24,10 +24,12 @@
#HandleLidSwitch=suspend
#HandleLidSwitchExternalPower=suspend
#HandleLidSwitchDocked=ignore
+#HandleRebootKey=reboot
#PowerKeyIgnoreInhibited=no
#SuspendKeyIgnoreInhibited=no
#HibernateKeyIgnoreInhibited=no
#LidSwitchIgnoreInhibited=yes
+#RebootKeyIgnoreInhibited=no
#HoldoffTimeoutSec=30s
#IdleAction=ignore
#IdleActionSec=30min
diff --git a/src/login/logind.h b/src/login/logind.h
index b9b4a5113f..395306ced3 100644
--- a/src/login/logind.h
+++ b/src/login/logind.h
@@ -111,11 +111,13 @@ struct Manager {
HandleAction handle_lid_switch;
HandleAction handle_lid_switch_ep;
HandleAction handle_lid_switch_docked;
+ HandleAction handle_reboot_key;
bool power_key_ignore_inhibited;
bool suspend_key_ignore_inhibited;
bool hibernate_key_ignore_inhibited;
bool lid_switch_ignore_inhibited;
+ bool reboot_key_ignore_inhibited;
bool remove_ipc;
diff --git a/src/login/org.freedesktop.login1.policy b/src/login/org.freedesktop.login1.policy
index 83760e1580..882975849e 100644
--- a/src/login/org.freedesktop.login1.policy
+++ b/src/login/org.freedesktop.login1.policy
@@ -113,6 +113,17 @@
</defaults>
</action>
+ <action id="org.freedesktop.login1.inhibit-handle-reboot-key">
+ <description gettext-domain="systemd">Allow applications to inhibit system handling of the reboot key</description>
+ <message gettext-domain="systemd">Authentication is required for an application to inhibit system handling of the reboot key.</message>
+ <defaults>
+ <allow_any>no</allow_any>
+ <allow_inactive>yes</allow_inactive>
+ <allow_active>yes</allow_active>
+ </defaults>
+ <annotate key="org.freedesktop.policykit.imply">org.freedesktop.login1.inhibit-handle-suspend-key org.freedesktop.login1.inhibit-handle-hibernate-key org.freedesktop.login1.inhibit-handle-lid-switch</annotate>
+ </action>
+
<action id="org.freedesktop.login1.set-self-linger">
<description gettext-domain="systemd">Allow non-logged-in user to run programs</description>
<message gettext-domain="systemd">Explicit request is required to run programs as a non-logged-in user.</message>
diff --git a/src/systemd/sd-messages.h b/src/systemd/sd-messages.h
index 847b698ba4..3e9584c0b2 100644
--- a/src/systemd/sd-messages.h
+++ b/src/systemd/sd-messages.h
@@ -134,6 +134,8 @@ _SD_BEGIN_DECLARATIONS;
#define SD_MESSAGE_SYSTEM_UNDOCKED_STR SD_ID128_MAKE_STR(51,e1,71,bd,58,52,48,56,81,10,14,4c,51,7c,ca,53)
#define SD_MESSAGE_POWER_KEY SD_ID128_MAKE(b7,2e,a4,a2,88,15,45,a0,b5,0e,20,0e,55,b9,b0,71)
#define SD_MESSAGE_POWER_KEY_STR SD_ID128_MAKE_STR(b7,2e,a4,a2,88,15,45,a0,b5,0e,20,0e,55,b9,b0,71)
+#define SD_MESSAGE_REBOOT_KEY SD_ID128_MAKE(9f,a9,d2,c0,12,13,4e,c3,85,45,1f,fe,31,6f,97,d0)
+#define SD_MESSAGE_REBOOT_KEY_STR SD_ID128_MAKE_STR(9f,a9,d2,c0,12,13,4e,c3,85,45,1f,fe,31,6f,97,d0)
#define SD_MESSAGE_SUSPEND_KEY SD_ID128_MAKE(b7,2e,a4,a2,88,15,45,a0,b5,0e,20,0e,55,b9,b0,72)
#define SD_MESSAGE_SUSPEND_KEY_STR SD_ID128_MAKE_STR(b7,2e,a4,a2,88,15,45,a0,b5,0e,20,0e,55,b9,b0,72)
#define SD_MESSAGE_HIBERNATE_KEY SD_ID128_MAKE(b7,2e,a4,a2,88,15,45,a0,b5,0e,20,0e,55,b9,b0,73)

@ -0,0 +1,62 @@
From dd7a5f4144bde111334582eafbc0f358e63854ea Mon Sep 17 00:00:00 2001
From: Yu Watanabe <watanabe.yu+github@gmail.com>
Date: Fri, 1 Feb 2019 11:49:24 +0100
Subject: [PATCH] analyze security: fix recursive call of
syscall_names_in_filter()
When `syscall_names_in_filter()` is called in itself, it is already
examined with `whitelist`. Or, in other words, `syscall_names_in_filter()`
returns bad or good in boolean. So, the returned value should not be
compared with `whitelist` again.
This replaces #11302.
(cherry picked from commit 95832a0f8c2941df83e72dfc9d37eab20da8b1fa)
Related: RHEL-5991
---
src/analyze/analyze-security.c | 24 +++++++++++-------------
1 file changed, 11 insertions(+), 13 deletions(-)
diff --git a/src/analyze/analyze-security.c b/src/analyze/analyze-security.c
index 969101c57b..5ef5d52e75 100644
--- a/src/analyze/analyze-security.c
+++ b/src/analyze/analyze-security.c
@@ -480,26 +480,24 @@ static bool syscall_names_in_filter(Set *s, bool whitelist, const SyscallFilterS
const char *syscall;
NULSTR_FOREACH(syscall, f->value) {
- bool b;
+ int id;
if (syscall[0] == '@') {
const SyscallFilterSet *g;
- assert_se(g = syscall_filter_set_find(syscall));
- b = syscall_names_in_filter(s, whitelist, g);
- } else {
-#if HAVE_SECCOMP
- int id;
- /* Let's see if the system call actually exists on this platform, before complaining */
- id = seccomp_syscall_resolve_name(syscall);
- if (id < 0)
- continue;
-#endif
+ assert_se(g = syscall_filter_set_find(syscall));
+ if (syscall_names_in_filter(s, whitelist, g))
+ return true; /* bad! */
- b = set_contains(s, syscall);
+ continue;
}
- if (whitelist == b) {
+ /* Let's see if the system call actually exists on this platform, before complaining */
+ id = seccomp_syscall_resolve_name(syscall);
+ if (id < 0)
+ continue;
+
+ if (set_contains(s, syscall) == whitelist) {
log_debug("Offending syscall filter item: %s", syscall);
return true; /* bad! */
}

@ -0,0 +1,28 @@
From c8fe27ea2c560a213c3e3968fa76b5dd84e181f5 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= <zbyszek@in.waw.pl>
Date: Sat, 1 Aug 2020 11:28:09 +0200
Subject: [PATCH] analyze-security: do not assign badness to filtered-out
syscalls
Fixes #16451, https://bugzilla.redhat.com/show_bug.cgi?id=1856273.
(cherry picked from commit 01ecb3674ad3650bcbb14155b2dcbd4b9f4ed57e)
Resolves: RHEL-5991
---
src/analyze/analyze-security.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/analyze/analyze-security.c b/src/analyze/analyze-security.c
index 5ef5d52e75..7c937e3587 100644
--- a/src/analyze/analyze-security.c
+++ b/src/analyze/analyze-security.c
@@ -549,7 +549,7 @@ static int assess_system_call_filter(
b = 10;
} else {
(void) asprintf(&d, "System call blacklist defined for service, and %s is included", f->name);
- b = 5;
+ b = 0;
}
}
}

@ -0,0 +1,105 @@
From 7aa12839166b5ae2c67d51946008543d016a7733 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= <zbyszek@in.waw.pl>
Date: Sat, 1 Aug 2020 11:41:57 +0200
Subject: [PATCH] analyze-security: include an actual syscall name in the
message
This information was already available in the debug output, but I think it
is good to include it in the message in the table. This makes it easier to wrap
one's head around the allowlist/denylist filtering.
(cherry picked from commit a9134af2e3ab22eba96228ea6ba440e89213cef2)
Related: RHEL-5991
---
src/analyze/analyze-security.c | 27 +++++++++++++++++----------
1 file changed, 17 insertions(+), 10 deletions(-)
diff --git a/src/analyze/analyze-security.c b/src/analyze/analyze-security.c
index 7c937e3587..d156aa607a 100644
--- a/src/analyze/analyze-security.c
+++ b/src/analyze/analyze-security.c
@@ -476,7 +476,7 @@ static int assess_system_call_architectures(
return 0;
}
-static bool syscall_names_in_filter(Set *s, bool whitelist, const SyscallFilterSet *f) {
+static bool syscall_names_in_filter(Set *s, bool whitelist, const SyscallFilterSet *f, const char **ret_offending_syscall) {
const char *syscall;
NULSTR_FOREACH(syscall, f->value) {
@@ -486,7 +486,7 @@ static bool syscall_names_in_filter(Set *s, bool whitelist, const SyscallFilterS
const SyscallFilterSet *g;
assert_se(g = syscall_filter_set_find(syscall));
- if (syscall_names_in_filter(s, whitelist, g))
+ if (syscall_names_in_filter(s, whitelist, g, ret_offending_syscall))
return true; /* bad! */
continue;
@@ -499,10 +499,13 @@ static bool syscall_names_in_filter(Set *s, bool whitelist, const SyscallFilterS
if (set_contains(s, syscall) == whitelist) {
log_debug("Offending syscall filter item: %s", syscall);
+ if (ret_offending_syscall)
+ *ret_offending_syscall = syscall;
return true; /* bad! */
}
}
+ *ret_offending_syscall = NULL;
return false;
}
@@ -513,31 +516,33 @@ static int assess_system_call_filter(
uint64_t *ret_badness,
char **ret_description) {
- const SyscallFilterSet *f;
- char *d = NULL;
- uint64_t b;
-
assert(a);
assert(info);
assert(ret_badness);
assert(ret_description);
assert(a->parameter < _SYSCALL_FILTER_SET_MAX);
- f = syscall_filter_sets + a->parameter;
+ const SyscallFilterSet *f = syscall_filter_sets + a->parameter;
+
+ char *d = NULL;
+ uint64_t b;
if (!info->system_call_filter_whitelist && set_isempty(info->system_call_filter)) {
d = strdup("Service does not filter system calls");
b = 10;
} else {
bool bad;
+ const char *offender = NULL;
log_debug("Analyzing system call filter, checking against: %s", f->name);
- bad = syscall_names_in_filter(info->system_call_filter, info->system_call_filter_whitelist, f);
+ bad = syscall_names_in_filter(info->system_call_filter, info->system_call_filter_whitelist, f, &offender);
log_debug("Result: %s", bad ? "bad" : "good");
if (info->system_call_filter_whitelist) {
if (bad) {
- (void) asprintf(&d, "System call whitelist defined for service, and %s is included", f->name);
+ (void) asprintf(&d, "System call whitelist defined for service, and %s is included "
+ "(e.g. %s is allowed)",
+ f->name, offender);
b = 9;
} else {
(void) asprintf(&d, "System call whitelist defined for service, and %s is not included", f->name);
@@ -545,7 +550,9 @@ static int assess_system_call_filter(
}
} else {
if (bad) {
- (void) asprintf(&d, "System call blacklist defined for service, and %s is not included", f->name);
+ (void) asprintf(&d, "System call blacklist defined for service, and %s is not included "
+ "(e.g. %s is allowed)",
+ f->name, offender);
b = 10;
} else {
(void) asprintf(&d, "System call blacklist defined for service, and %s is included", f->name);

@ -0,0 +1,50 @@
From 9d9c3d38451befec0494aea4fdb12c65289b0b46 Mon Sep 17 00:00:00 2001
From: Jan Macku <jamacku@redhat.com>
Date: Tue, 23 Jan 2024 15:15:00 +0100
Subject: [PATCH] udev/net_id: introduce naming scheme for RHEL-8.10
rhel-only
Resolves: RHEL-22426
---
man/systemd.net-naming-scheme.xml | 6 ++++++
src/udev/udev-builtin-net_id.c | 2 ++
2 files changed, 8 insertions(+)
diff --git a/man/systemd.net-naming-scheme.xml b/man/systemd.net-naming-scheme.xml
index ddd41646ae..25e8bd9aea 100644
--- a/man/systemd.net-naming-scheme.xml
+++ b/man/systemd.net-naming-scheme.xml
@@ -340,6 +340,12 @@
<para>Same as naming scheme <constant>rhel-8.7</constant>.</para>
</varlistentry>
+ <varlistentry>
+ <term><constant>rhel-8.10</constant></term>
+
+ <para>Same as naming scheme <constant>rhel-8.7</constant>.</para>
+ </varlistentry>
+
<para>Note that <constant>latest</constant> may be used to denote the latest scheme known to this
particular version of systemd.</para>
</variablelist>
diff --git a/src/udev/udev-builtin-net_id.c b/src/udev/udev-builtin-net_id.c
index 0f42c1c007..ece5d29205 100644
--- a/src/udev/udev-builtin-net_id.c
+++ b/src/udev/udev-builtin-net_id.c
@@ -143,6 +143,7 @@ typedef enum NamingSchemeFlags {
NAMING_RHEL_8_7 = NAMING_RHEL_8_4|NAMING_SLOT_FUNCTION_ID|NAMING_16BIT_INDEX,
NAMING_RHEL_8_8 = NAMING_RHEL_8_7,
NAMING_RHEL_8_9 = NAMING_RHEL_8_7,
+ NAMING_RHEL_8_10 = NAMING_RHEL_8_7,
_NAMING_SCHEME_FLAGS_INVALID = -1,
} NamingSchemeFlags;
@@ -165,6 +166,7 @@ static const NamingScheme naming_schemes[] = {
{ "rhel-8.7", NAMING_RHEL_8_7 },
{ "rhel-8.8", NAMING_RHEL_8_8 },
{ "rhel-8.9", NAMING_RHEL_8_9 },
+ { "rhel-8.10", NAMING_RHEL_8_10 },
/* … add more schemes here, as the logic to name devices is updated … */
};

@ -0,0 +1,79 @@
From 8ac0c00fa9699f1cd096a4775cf0cf7879b81f37 Mon Sep 17 00:00:00 2001
From: Jan Macku <jamacku@redhat.com>
Date: Fri, 9 Feb 2024 14:42:28 +0100
Subject: [PATCH] doc: add missing `<listitem>` to
`systemd.net-naming-scheme.xml`
rhel-only
Related: RHEL-22426
---
man/systemd.net-naming-scheme.xml | 16 ++++++++--------
1 file changed, 8 insertions(+), 8 deletions(-)
diff --git a/man/systemd.net-naming-scheme.xml b/man/systemd.net-naming-scheme.xml
index 25e8bd9aea..11ef2ea02f 100644
--- a/man/systemd.net-naming-scheme.xml
+++ b/man/systemd.net-naming-scheme.xml
@@ -276,19 +276,19 @@
<varlistentry>
<term><constant>rhel-8.1</constant></term>
- <para>Same as naming scheme <constant>rhel-8.0</constant>.</para>
+ <listitem><para>Same as naming scheme <constant>rhel-8.0</constant>.</para></listitem>
</varlistentry>
<varlistentry>
<term><constant>rhel-8.2</constant></term>
- <para>Same as naming scheme <constant>rhel-8.0</constant>.</para>
+ <listitem><para>Same as naming scheme <constant>rhel-8.0</constant>.</para></listitem>
</varlistentry>
<varlistentry>
<term><constant>rhel-8.3</constant></term>
- <para>Same as naming scheme <constant>rhel-8.0</constant>.</para>
+ <listitem><para>Same as naming scheme <constant>rhel-8.0</constant>.</para></listitem>
</varlistentry>
<varlistentry>
@@ -304,13 +304,13 @@
<varlistentry>
<term><constant>rhel-8.5</constant></term>
- <para>Same as naming scheme <constant>rhel-8.4</constant>.</para>
+ <listitem><para>Same as naming scheme <constant>rhel-8.4</constant>.</para></listitem>
</varlistentry>
<varlistentry>
<term><constant>rhel-8.6</constant></term>
- <para>Same as naming scheme <constant>rhel-8.4</constant>.</para>
+ <listitem><para>Same as naming scheme <constant>rhel-8.4</constant>.</para></listitem>
</varlistentry>
<varlistentry>
@@ -331,19 +331,19 @@
<varlistentry>
<term><constant>rhel-8.8</constant></term>
- <para>Same as naming scheme <constant>rhel-8.7</constant>.</para>
+ <listitem><para>Same as naming scheme <constant>rhel-8.7</constant>.</para></listitem>
</varlistentry>
<varlistentry>
<term><constant>rhel-8.9</constant></term>
- <para>Same as naming scheme <constant>rhel-8.7</constant>.</para>
+ <listitem><para>Same as naming scheme <constant>rhel-8.7</constant>.</para></listitem>
</varlistentry>
<varlistentry>
<term><constant>rhel-8.10</constant></term>
- <para>Same as naming scheme <constant>rhel-8.7</constant>.</para>
+ <listitem><para>Same as naming scheme <constant>rhel-8.7</constant>.</para></listitem>
</varlistentry>
<para>Note that <constant>latest</constant> may be used to denote the latest scheme known to this

@ -0,0 +1,34 @@
From 8bf7a6f42efba3ebe59872ba75233e75ffdf7c87 Mon Sep 17 00:00:00 2001
From: Michal Sekletar <msekleta@redhat.com>
Date: Mon, 11 Dec 2023 16:09:02 +0100
Subject: [PATCH] service: schedule cleanup of PID hashmaps when we now longer
have main_pid and we are in container
RHEL-only
Resolves: RHEL-5863
---
src/core/service.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/src/core/service.c b/src/core/service.c
index 0423f2c73e..82c09d59f0 100644
--- a/src/core/service.c
+++ b/src/core/service.c
@@ -34,6 +34,7 @@
#include "string-table.h"
#include "string-util.h"
#include "strv.h"
+#include "virt.h"
#include "unit-name.h"
#include "unit.h"
#include "utf8.h"
@@ -3535,7 +3536,7 @@ static void service_sigchld_event(Unit *u, pid_t pid, int code, int status) {
* detect when the cgroup becomes empty. Note that the control process is always
* our child so it's pointless to watch all other processes. */
if (!control_pid_good(s))
- if (!s->main_pid_known || s->main_pid_alien)
+ if (!s->main_pid_known || s->main_pid_alien || (s->main_pid == 0 && detect_container() > 0))
(void) unit_enqueue_rewatch_pids(u);
}

@ -0,0 +1,24 @@
From 9cb89ed011a12a210dce977aaa65f6b90e0ed928 Mon Sep 17 00:00:00 2001
From: Frantisek Sumsal <fsumsal@redhat.com>
Date: Thu, 22 Feb 2024 14:28:09 +0100
Subject: [PATCH] man: update link to RHEL documentation
Resolves: RHEL-26355
RHEL-only
---
man/systemctl.xml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/man/systemctl.xml b/man/systemctl.xml
index abc386e6fb..445d35fefd 100644
--- a/man/systemctl.xml
+++ b/man/systemctl.xml
@@ -2018,7 +2018,7 @@ Jan 12 10:46:45 example.com bluetoothd[8900]: gatt-time-server: Input/output err
<para>
For examples how to use systemctl in comparsion
with old service and chkconfig command please see:
- <ulink url="https://access.redhat.com/documentation/en-us/red_hat_enterprise_linux/8/html/configuring_basic_system_settings/managing-system-services-with-systemctl_configuring-basic-system-settings">
+ <ulink url="https://access.redhat.com/documentation/en-us/red_hat_enterprise_linux/8/html/configuring_basic_system_settings/managing-systemd_configuring-basic-system-settings#managing-system-services-with-systemctl_managing-systemd">
Managing System Services
</ulink>
</para>

@ -0,0 +1,20 @@
From ca150b92be2e0edf3bfafe88ee79a419e7e11aaa Mon Sep 17 00:00:00 2001
From: Jan Macku <jamacku@redhat.com>
Date: Mon, 4 Mar 2024 13:40:45 +0100
Subject: [PATCH] ci: add configuration for regression sniffer GA
rhel-only
Related: RHEL-1087
---
.github/regression-sniffer.yml | 1 +
1 file changed, 1 insertion(+)
create mode 100644 .github/regression-sniffer.yml
diff --git a/.github/regression-sniffer.yml b/.github/regression-sniffer.yml
new file mode 100644
index 0000000000..3824028e92
--- /dev/null
+++ b/.github/regression-sniffer.yml
@@ -0,0 +1 @@
+upstream: systemd/systemd

@ -0,0 +1,35 @@
From ccaa361e04719efc6bcf7f3201cc9e6a869677d8 Mon Sep 17 00:00:00 2001
From: Michal Sekletar <msekleta@redhat.com>
Date: Mon, 4 Mar 2024 14:40:32 +0100
Subject: [PATCH] coredump: actually store parsed unit in the context
RHEL-only
Related: RHEL-18302
---
src/coredump/coredump.c | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/src/coredump/coredump.c b/src/coredump/coredump.c
index d8acd2d3a7..7af8e97877 100644
--- a/src/coredump/coredump.c
+++ b/src/coredump/coredump.c
@@ -1262,6 +1262,8 @@ static int gather_pid_metadata(
context->meta[CONTEXT_EXE] = t;
if (cg_pid_get_unit(pid, &t) >= 0) {
+ context->meta[CONTEXT_UNIT] = t;
+
if (!is_journald_crash(context)) {
/* OK, now we know it's not the journal, hence we can make use of it now. */
log_set_target(LOG_TARGET_JOURNAL_OR_KMSG);
@@ -1275,8 +1277,7 @@ static int gather_pid_metadata(
}
set_iovec_string_field(iovec, n_iovec, "COREDUMP_UNIT=", context->meta[CONTEXT_UNIT]);
- } else
- context->meta[CONTEXT_UNIT] = t;
+ }
if (cg_pid_get_user_unit(pid, &t) >= 0)
set_iovec_field_free(iovec, n_iovec, "COREDUMP_USER_UNIT=", t);

@ -0,0 +1,184 @@
From 899e3c43d6ac9d97c3cb9340b778427391def4ac Mon Sep 17 00:00:00 2001
From: Jacek Migacz <jmigacz@redhat.com>
Date: Mon, 26 Feb 2024 13:47:24 +0100
Subject: [PATCH] resolved: limit the number of signature validations in a
transaction
It has been demonstrated that tolerating an unbounded number of dnssec
signature validations is a bad idea. It is easy for a maliciously
crafted DNS reply to contain as many keytag collisions as desired,
causing us to iterate every dnskey and signature combination in vain.
The solution is to impose a maximum number of validations we will
tolerate. While collisions are not hard to craft, I still expect they
are unlikely in the wild so it should be safe to pick fairly small
values.
Here two limits are imposed: one on the maximum number of invalid
signatures encountered per rrset, and another on the total number of
validations performed per transaction.
(cherry picked from commit 67d0ce8843d612a2245d0966197d4f528b911b66)
Resolves: RHEL-26644
---
src/resolve/resolved-dns-dnssec.c | 16 ++++++++++++++--
src/resolve/resolved-dns-dnssec.h | 9 ++++++++-
src/resolve/resolved-dns-transaction.c | 19 ++++++++++++++++---
3 files changed, 38 insertions(+), 6 deletions(-)
diff --git a/src/resolve/resolved-dns-dnssec.c b/src/resolve/resolved-dns-dnssec.c
index 0a6f482cc1..5dbfbc94c7 100644
--- a/src/resolve/resolved-dns-dnssec.c
+++ b/src/resolve/resolved-dns-dnssec.c
@@ -996,6 +996,7 @@ int dnssec_verify_rrset_search(
DnsResourceRecord **ret_rrsig) {
bool found_rrsig = false, found_invalid = false, found_expired_rrsig = false, found_unsupported_algorithm = false;
+ unsigned nvalidations = 0;
DnsResourceRecord *rrsig;
int r;
@@ -1041,6 +1042,14 @@ int dnssec_verify_rrset_search(
if (realtime == USEC_INFINITY)
realtime = now(CLOCK_REALTIME);
+ /* Have we seen an unreasonable number of invalid signaures? */
+ if (nvalidations > DNSSEC_INVALID_MAX) {
+ if (ret_rrsig)
+ *ret_rrsig = NULL;
+ *result = DNSSEC_TOO_MANY_VALIDATIONS;
+ return (int) nvalidations;
+ }
+
/* Yay, we found a matching RRSIG with a matching
* DNSKEY, awesome. Now let's verify all entries of
* the RRSet against the RRSIG and DNSKEY
@@ -1050,6 +1059,8 @@ int dnssec_verify_rrset_search(
if (r < 0)
return r;
+ nvalidations++;
+
switch (one_result) {
case DNSSEC_VALIDATED:
@@ -1060,7 +1071,7 @@ int dnssec_verify_rrset_search(
*ret_rrsig = rrsig;
*result = one_result;
- return 0;
+ return (int) nvalidations;
case DNSSEC_INVALID:
/* If the signature is invalid, let's try another
@@ -1107,7 +1118,7 @@ int dnssec_verify_rrset_search(
if (ret_rrsig)
*ret_rrsig = NULL;
- return 0;
+ return (int) nvalidations;
}
int dnssec_has_rrsig(DnsAnswer *a, const DnsResourceKey *key) {
@@ -2301,6 +2312,7 @@ static const char* const dnssec_result_table[_DNSSEC_RESULT_MAX] = {
[DNSSEC_FAILED_AUXILIARY] = "failed-auxiliary",
[DNSSEC_NSEC_MISMATCH] = "nsec-mismatch",
[DNSSEC_INCOMPATIBLE_SERVER] = "incompatible-server",
+ [DNSSEC_TOO_MANY_VALIDATIONS] = "too-many-validations",
};
DEFINE_STRING_TABLE_LOOKUP(dnssec_result, DnssecResult);
diff --git a/src/resolve/resolved-dns-dnssec.h b/src/resolve/resolved-dns-dnssec.h
index dfee7232c0..4d6abee084 100644
--- a/src/resolve/resolved-dns-dnssec.h
+++ b/src/resolve/resolved-dns-dnssec.h
@@ -9,12 +9,13 @@ typedef enum DnssecVerdict DnssecVerdict;
#include "resolved-dns-rr.h"
enum DnssecResult {
- /* These five are returned by dnssec_verify_rrset() */
+ /* These six are returned by dnssec_verify_rrset() */
DNSSEC_VALIDATED,
DNSSEC_VALIDATED_WILDCARD, /* Validated via a wildcard RRSIG, further NSEC/NSEC3 checks necessary */
DNSSEC_INVALID,
DNSSEC_SIGNATURE_EXPIRED,
DNSSEC_UNSUPPORTED_ALGORITHM,
+ DNSSEC_TOO_MANY_VALIDATIONS,
/* These two are added by dnssec_verify_rrset_search() */
DNSSEC_NO_SIGNATURE,
@@ -45,6 +46,12 @@ enum DnssecVerdict {
/* The longest digest we'll ever generate, of all digest algorithms we support */
#define DNSSEC_HASH_SIZE_MAX (MAX(20, 32))
+/* The most invalid signatures we will tolerate for a single rrset */
+#define DNSSEC_INVALID_MAX 5
+
+/* The total number of signature validations we will tolerate for a single transaction */
+#define DNSSEC_VALIDATION_MAX 64
+
int dnssec_rrsig_match_dnskey(DnsResourceRecord *rrsig, DnsResourceRecord *dnskey, bool revoked_ok);
int dnssec_key_match_rrsig(const DnsResourceKey *key, DnsResourceRecord *rrsig);
diff --git a/src/resolve/resolved-dns-transaction.c b/src/resolve/resolved-dns-transaction.c
index 6f614d7493..1ca6c9abc8 100644
--- a/src/resolve/resolved-dns-transaction.c
+++ b/src/resolve/resolved-dns-transaction.c
@@ -2870,11 +2870,14 @@ static int dnssec_validate_records(
DnsTransaction *t,
Phase phase,
bool *have_nsec,
+ unsigned *nvalidations,
DnsAnswer **validated) {
DnsResourceRecord *rr;
int r;
+ assert(nvalidations);
+
/* Returns negative on error, 0 if validation failed, 1 to restart validation, 2 when finished. */
DNS_ANSWER_FOREACH(rr, t->answer) {
@@ -2909,6 +2912,7 @@ static int dnssec_validate_records(
r = dnssec_verify_rrset_search(t->answer, rr->key, t->validated_keys, USEC_INFINITY, &result, &rrsig);
if (r < 0)
return r;
+ *nvalidations += r;
log_debug("Looking at %s: %s", strna(dns_resource_record_to_string(rr)), dnssec_result_to_string(result));
@@ -3086,7 +3090,8 @@ static int dnssec_validate_records(
DNSSEC_SIGNATURE_EXPIRED,
DNSSEC_NO_SIGNATURE))
manager_dnssec_verdict(t->scope->manager, DNSSEC_BOGUS, rr->key);
- else /* DNSSEC_MISSING_KEY or DNSSEC_UNSUPPORTED_ALGORITHM */
+ else /* DNSSEC_MISSING_KEY, DNSSEC_UNSUPPORTED_ALGORITHM,
+ or DNSSEC_TOO_MANY_VALIDATIONS */
manager_dnssec_verdict(t->scope->manager, DNSSEC_INDETERMINATE, rr->key);
/* This is a primary response to our question, and it failed validation.
@@ -3180,13 +3185,21 @@ int dns_transaction_validate_dnssec(DnsTransaction *t) {
return r;
phase = DNSSEC_PHASE_DNSKEY;
- for (;;) {
+ for (unsigned nvalidations = 0;;) {
bool have_nsec = false;
- r = dnssec_validate_records(t, phase, &have_nsec, &validated);
+ r = dnssec_validate_records(t, phase, &have_nsec, &nvalidations, &validated);
if (r <= 0)
return r;
+ if (nvalidations > DNSSEC_VALIDATION_MAX) {
+ /* This reply requires an onerous number of signature validations to verify. Let's
+ * not waste our time trying, as this shouldn't happen for well-behaved domains
+ * anyway. */
+ t->answer_dnssec_result = DNSSEC_TOO_MANY_VALIDATIONS;
+ return 0;
+ }
+
/* Try again as long as we managed to achieve something */
if (r == 1)
continue;

@ -0,0 +1,34 @@
From 92124e84be68005be92cce046c7c679b98199d66 Mon Sep 17 00:00:00 2001
From: Jacek Migacz <jmigacz@redhat.com>
Date: Mon, 26 Feb 2024 13:56:36 +0100
Subject: [PATCH] resolved: reduce the maximum nsec3 iterations to 100
According to RFC9267, the 2500 value is not helpful, and in fact it can
be harmful to permit a large number of iterations. Combined with limits
on the number of signature validations, I expect this will mitigate the
impact of maliciously crafted domains designed to cause excessive
cryptographic work.
(cherry picked from commit eba291124bc11f03732d1fc468db3bfac069f9cb)
Related: RHEL-26644
---
src/resolve/resolved-dns-dnssec.c | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/src/resolve/resolved-dns-dnssec.c b/src/resolve/resolved-dns-dnssec.c
index 5dbfbc94c7..5a0540568c 100644
--- a/src/resolve/resolved-dns-dnssec.c
+++ b/src/resolve/resolved-dns-dnssec.c
@@ -22,8 +22,9 @@
/* Permit a maximum clock skew of 1h 10min. This should be enough to deal with DST confusion */
#define SKEW_MAX (1*USEC_PER_HOUR + 10*USEC_PER_MINUTE)
-/* Maximum number of NSEC3 iterations we'll do. RFC5155 says 2500 shall be the maximum useful value */
-#define NSEC3_ITERATIONS_MAX 2500
+/* Maximum number of NSEC3 iterations we'll do. RFC5155 says 2500 shall be the maximum useful value, but
+ * RFC9276 § 3.2 says that we should reduce the acceptable iteration count */
+#define NSEC3_ITERATIONS_MAX 100
/*
* The DNSSEC Chain of trust:

@ -13,7 +13,7 @@
Name: systemd Name: systemd
Url: http://www.freedesktop.org/wiki/Software/systemd Url: http://www.freedesktop.org/wiki/Software/systemd
Version: 239 Version: 239
Release: 78%{?dist}.inferit Release: 82%{?dist}.inferit
# For a breakdown of the licensing, see README # For a breakdown of the licensing, see README
License: LGPLv2+ and MIT and GPLv2+ License: LGPLv2+ and MIT and GPLv2+
Summary: System and Service Manager Summary: System and Service Manager
@ -1659,6 +1659,47 @@ fi
%files tests -f .file-list-tests %files tests -f .file-list-tests
%changelog %changelog
* Thu May 23 2024 Sergey Cherevko <s.cherevko@msvsphere-os.ru> - 239-82.inferit
- Rebuilt for MSVSphere 8.10
* Thu Mar 07 2024 systemd maintenance team <systemd-maint@redhat.com> - 239-82
- ci: add configuration for regression sniffer GA (RHEL-1087)
- coredump: actually store parsed unit in the context (RHEL-18302)
- resolved: limit the number of signature validations in a transaction (RHEL-26644)
- resolved: reduce the maximum nsec3 iterations to 100 (RHEL-26644)
* Mon Feb 26 2024 systemd maintenance team <systemd-maint@redhat.com> - 239-81
- man: update link to RHEL documentation (RHEL-26355)
* Thu Feb 15 2024 systemd maintenance team <systemd-maint@redhat.com> - 239-80
- fd-util: rework how we determine highest possible fd (RHEL-18302)
- basic/fd-util: refuse "infinite" loop in close_all_fds() (RHEL-18302)
- fd-util: split out inner fallback loop of close_all_fds() as close_all_fds_without_malloc() (RHEL-18302)
- exec-util: use close_all_fds_without_malloc() from freeze() (RHEL-18302)
- ci: use source-git-automation composite Action (RHEL-1087)
- ci: increase the cron interval to 45 minutes (RHEL-1087)
- ci: add all Z-Stream versions to array of allowed versions (RHEL-1087)
- tree-wide: always declare bitflag enums the same way (RHEL-2857)
- login: Add KEY_RESTART handling (RHEL-2857)
- analyze security: fix recursive call of syscall_names_in_filter() (RHEL-5991)
- analyze-security: do not assign badness to filtered-out syscalls (RHEL-5991)
- analyze-security: include an actual syscall name in the message (RHEL-5991)
- udev/net_id: introduce naming scheme for RHEL-8.10 (RHEL-22426)
- doc: add missing `<listitem>` to `systemd.net-naming-scheme.xml` (RHEL-22426)
- service: schedule cleanup of PID hashmaps when we now longer have main_pid and we are in container (RHEL-5863)
* Mon Jan 08 2024 systemd maintenance team <systemd-maint@redhat.com> - 239-79
- ci: Extend source-git-automation (RHEL-1087)
- ci: add missing configuration for commit linter (RHEL-1087)
- ci: add `Red Hat Enterprise Linux 8` to the list of supported products (RHEL-1087)
- ci: enable source-git automation to validate reviews and ci results (RHEL-1087)
- ci: remove Mergify config - replaced by Pull Request Validator (RHEL-1087)
- ci: enable auto-merge GH Action (RHEL-1087)
- fstab-generator: allow overriding /etc/fstab with $SYSTEMD_FSTAB (RHEL-1087)
- fstab-generator: allow overriding path to /sysroot/etc/fstab too (RHEL-1087)
- test: backport TEST-81-GENERATORS (fstab-generator only) (RHEL-1087)
- resolved: actually check authenticated flag of SOA transaction (RHEL-6213)
* Fri Dec 22 2023 Arkady L. Shane <tigro@msvsphere-os.ru> - 239-78.inferit * Fri Dec 22 2023 Arkady L. Shane <tigro@msvsphere-os.ru> - 239-78.inferit
- Add safeguard in triggers - Add safeguard in triggers

Loading…
Cancel
Save