parent
fb370302cb
commit
7b6202c5f1
@ -1 +1,2 @@
|
|||||||
|
SOURCES/rhel-net-naming-sysattrs-v0.5.tar.gz
|
||||||
SOURCES/systemd-252.tar.gz
|
SOURCES/systemd-252.tar.gz
|
||||||
|
@ -1 +1,2 @@
|
|||||||
|
9ce6834429dbb9cb049de1bdf77bc8c84763709c SOURCES/rhel-net-naming-sysattrs-v0.5.tar.gz
|
||||||
7c961dc6e8bb950825b85129f59dc80f4536cabb SOURCES/systemd-252.tar.gz
|
7c961dc6e8bb950825b85129f59dc80f4536cabb SOURCES/systemd-252.tar.gz
|
||||||
|
@ -0,0 +1,223 @@
|
|||||||
|
From 55d337de1940076855c1687ffd588498d068724e Mon Sep 17 00:00:00 2001
|
||||||
|
From: Jan Macku <jamacku@redhat.com>
|
||||||
|
Date: Mon, 18 Sep 2023 13:51:43 +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-1086
|
||||||
|
---
|
||||||
|
.github/advanced-commit-linter.yml | 2 +
|
||||||
|
.github/tracker-validator.yml | 18 ++++
|
||||||
|
.../source-git-automation-on-demand.yml | 100 ++++++++++++++++++
|
||||||
|
.github/workflows/source-git-automation.yml | 29 ++++-
|
||||||
|
4 files changed, 147 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/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/'
|
||||||
|
diff --git a/.github/tracker-validator.yml b/.github/tracker-validator.yml
|
||||||
|
new file mode 100644
|
||||||
|
index 0000000000..9e43e4e7d5
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/.github/tracker-validator.yml
|
||||||
|
@@ -0,0 +1,18 @@
|
||||||
|
+labels:
|
||||||
|
+ missing-tracker: tracker/missing
|
||||||
|
+ invalid-product: tracker/invalid-product
|
||||||
|
+ invalid-component: tracker/invalid-component
|
||||||
|
+ unapproved: tracker/unapproved
|
||||||
|
+products:
|
||||||
|
+ - Red Hat Enterprise Linux 9
|
||||||
|
+ - CentOS Stream 9
|
||||||
|
+ - rhel-9.0.0
|
||||||
|
+ - rhel-9.2.0
|
||||||
|
+ - rhel-9.3.0
|
||||||
|
+ - rhel-9.4.0
|
||||||
|
+ - rhel-9.5.0
|
||||||
|
+ - rhel-9.6.0
|
||||||
|
+ - rhel-9.7.0
|
||||||
|
+ - rhel-9.8.0
|
||||||
|
+ - rhel-9.9.0
|
||||||
|
+ - rhel-9.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..60d7bcf32d
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/.github/workflows/source-git-automation-on-demand.yml
|
||||||
|
@@ -0,0 +1,100 @@
|
||||||
|
+---
|
||||||
|
+
|
||||||
|
+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-rhel9'
|
||||||
|
+ 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: |
|
||||||
|
+ # shellcheck disable=SC2086
|
||||||
|
+ 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..7fabb88a83 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-rhel9'
|
||||||
|
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,159 @@
|
|||||||
|
From dcc59dffa5116bf96618065cd60742cb660224b8 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Lukas Nykryn <lnykryn@redhat.com>
|
||||||
|
Date: Fri, 22 Sep 2023 13:28:02 +0200
|
||||||
|
Subject: [PATCH] netif-naming-scheme: let's also include rhel8 schemes
|
||||||
|
|
||||||
|
With this patch user in rhel9 can also pick a scheme from rhel8.
|
||||||
|
This could be useful on in-place upgrades.
|
||||||
|
|
||||||
|
rhel-only
|
||||||
|
Resolves: RHEL-7026
|
||||||
|
---
|
||||||
|
man/systemd.net-naming-scheme.xml | 88 +++++++++++++++++++++++++++++++
|
||||||
|
src/shared/netif-naming-scheme.c | 10 ++++
|
||||||
|
src/shared/netif-naming-scheme.h | 12 +++++
|
||||||
|
3 files changed, 110 insertions(+)
|
||||||
|
|
||||||
|
diff --git a/man/systemd.net-naming-scheme.xml b/man/systemd.net-naming-scheme.xml
|
||||||
|
index ade4e27e31..c6ab86906a 100644
|
||||||
|
--- a/man/systemd.net-naming-scheme.xml
|
||||||
|
+++ b/man/systemd.net-naming-scheme.xml
|
||||||
|
@@ -459,6 +459,94 @@
|
||||||
|
</listitem>
|
||||||
|
</varlistentry>
|
||||||
|
|
||||||
|
+ <varlistentry>
|
||||||
|
+ <term><constant>rhel-8.0</constant></term>
|
||||||
|
+
|
||||||
|
+ <listitem><para>Naming was changed for virtual network interfaces created with SR-IOV and NPAR and
|
||||||
|
+ for devices where the PCI network controller device does not have a slot number associated.</para>
|
||||||
|
+
|
||||||
|
+ <para>SR-IOV virtual devices are named based on the name of the parent interface, with a suffix of
|
||||||
|
+ <literal>v<replaceable>port</replaceable></literal>, where <replaceable>port</replaceable> is the
|
||||||
|
+ virtual device number. Previously those virtual devices were named as if completely independent.
|
||||||
|
+ </para>
|
||||||
|
+
|
||||||
|
+ <para>The ninth and later NPAR virtual devices are named following the scheme used for the first
|
||||||
|
+ eight NPAR partitions. Previously those devices were not renamed and the kernel default
|
||||||
|
+ ("eth<replaceable>N</replaceable>") was used.</para>
|
||||||
|
+
|
||||||
|
+ <para>Names are also generated for PCI devices where the PCI network controller device does not
|
||||||
|
+ have an associated slot number itself, but one of its parents does. Previously those devices were
|
||||||
|
+ not renamed and the kernel default was used.</para>
|
||||||
|
+ </listitem>
|
||||||
|
+ </varlistentry>
|
||||||
|
+
|
||||||
|
+ <varlistentry>
|
||||||
|
+ <term><constant>rhel-8.1</constant></term>
|
||||||
|
+
|
||||||
|
+ <para>Same as naming scheme <constant>rhel-8.0</constant>.</para>
|
||||||
|
+ </varlistentry>
|
||||||
|
+
|
||||||
|
+ <varlistentry>
|
||||||
|
+ <term><constant>rhel-8.2</constant></term>
|
||||||
|
+
|
||||||
|
+ <para>Same as naming scheme <constant>rhel-8.0</constant>.</para>
|
||||||
|
+ </varlistentry>
|
||||||
|
+
|
||||||
|
+ <varlistentry>
|
||||||
|
+ <term><constant>rhel-8.3</constant></term>
|
||||||
|
+
|
||||||
|
+ <para>Same as naming scheme <constant>rhel-8.0</constant>.</para>
|
||||||
|
+ </varlistentry>
|
||||||
|
+
|
||||||
|
+ <varlistentry>
|
||||||
|
+ <term><constant>rhel-8.4</constant></term>
|
||||||
|
+
|
||||||
|
+ <listitem><para>If the PCI slot is assocated with PCI bridge and that has multiple child network
|
||||||
|
+ controllers then all of them might derive the same value of <varname>ID_NET_NAME_SLOT</varname>
|
||||||
|
+ property. That could cause naming conflict if the property is selected as a device name. Now, we detect the
|
||||||
|
+ situation, slot - bridge relation, and we don't produce the <varname>ID_NET_NAME_SLOT</varname> property to
|
||||||
|
+ avoid possible naming conflict.</para></listitem>
|
||||||
|
+ </varlistentry>
|
||||||
|
+
|
||||||
|
+ <varlistentry>
|
||||||
|
+ <term><constant>rhel-8.5</constant></term>
|
||||||
|
+
|
||||||
|
+ <para>Same as naming scheme <constant>rhel-8.4</constant>.</para>
|
||||||
|
+ </varlistentry>
|
||||||
|
+
|
||||||
|
+ <varlistentry>
|
||||||
|
+ <term><constant>rhel-8.6</constant></term>
|
||||||
|
+
|
||||||
|
+ <para>Same as naming scheme <constant>rhel-8.4</constant>.</para>
|
||||||
|
+ </varlistentry>
|
||||||
|
+
|
||||||
|
+ <varlistentry>
|
||||||
|
+ <term><constant>rhel-8.7</constant></term>
|
||||||
|
+
|
||||||
|
+ <listitem><para>PCI hotplug slot names for the s390 PCI driver are a hexadecimal representation
|
||||||
|
+ of the <filename>function_id</filename> device attribute. This attribute is now used to build the
|
||||||
|
+ <varname>ID_NET_NAME_SLOT</varname>. Before that, all slot names were parsed as decimal
|
||||||
|
+ numbers, which could either result in an incorrect value of the <varname>ID_NET_NAME_SLOT</varname>
|
||||||
|
+ property or none at all.</para>
|
||||||
|
+
|
||||||
|
+ <para>Some firmware and hypervisor implementations report unreasonable high numbers for the onboard
|
||||||
|
+ index. To prevent the generation of bogus onbard interface names, index numbers greater than 16381
|
||||||
|
+ (2^14-1) were ignored. For s390 PCI devices index values up to 65535 (2^16-1) are valid. To account
|
||||||
|
+ for that, the limit is increased to now 65535.</para></listitem>
|
||||||
|
+ </varlistentry>
|
||||||
|
+
|
||||||
|
+ <varlistentry>
|
||||||
|
+ <term><constant>rhel-8.8</constant></term>
|
||||||
|
+
|
||||||
|
+ <para>Same as naming scheme <constant>rhel-8.7</constant>.</para>
|
||||||
|
+ </varlistentry>
|
||||||
|
+
|
||||||
|
+ <varlistentry>
|
||||||
|
+ <term><constant>rhel-8.9</constant></term>
|
||||||
|
+
|
||||||
|
+ <para>Same as naming scheme <constant>rhel-8.7</constant>.</para>
|
||||||
|
+ </varlistentry>
|
||||||
|
+
|
||||||
|
<varlistentry>
|
||||||
|
<term><constant>rhel-9.0</constant></term>
|
||||||
|
|
||||||
|
diff --git a/src/shared/netif-naming-scheme.c b/src/shared/netif-naming-scheme.c
|
||||||
|
index 0f50533279..9cfa5ca8e6 100644
|
||||||
|
--- a/src/shared/netif-naming-scheme.c
|
||||||
|
+++ b/src/shared/netif-naming-scheme.c
|
||||||
|
@@ -25,6 +25,16 @@ static const NamingScheme naming_schemes[] = {
|
||||||
|
{ "v250", NAMING_V250 },
|
||||||
|
{ "v251", NAMING_V251 },
|
||||||
|
{ "v252", NAMING_V252 },
|
||||||
|
+ { "rhel-8.0", NAMING_RHEL_8_0 },
|
||||||
|
+ { "rhel-8.1", NAMING_RHEL_8_1 },
|
||||||
|
+ { "rhel-8.2", NAMING_RHEL_8_2 },
|
||||||
|
+ { "rhel-8.3", NAMING_RHEL_8_3 },
|
||||||
|
+ { "rhel-8.4", NAMING_RHEL_8_4 },
|
||||||
|
+ { "rhel-8.5", NAMING_RHEL_8_5 },
|
||||||
|
+ { "rhel-8.6", NAMING_RHEL_8_6 },
|
||||||
|
+ { "rhel-8.7", NAMING_RHEL_8_7 },
|
||||||
|
+ { "rhel-8.8", NAMING_RHEL_8_8 },
|
||||||
|
+ { "rhel-8.9", NAMING_RHEL_8_9 },
|
||||||
|
{ "rhel-9.0", NAMING_RHEL_9_0 },
|
||||||
|
{ "rhel-9.1", NAMING_RHEL_9_1 },
|
||||||
|
{ "rhel-9.2", NAMING_RHEL_9_2 },
|
||||||
|
diff --git a/src/shared/netif-naming-scheme.h b/src/shared/netif-naming-scheme.h
|
||||||
|
index fb3c8eb9b3..ed45536f65 100644
|
||||||
|
--- a/src/shared/netif-naming-scheme.h
|
||||||
|
+++ b/src/shared/netif-naming-scheme.h
|
||||||
|
@@ -52,6 +52,18 @@ typedef enum NamingSchemeFlags {
|
||||||
|
NAMING_V250 = NAMING_V249 | NAMING_XEN_VIF,
|
||||||
|
NAMING_V251 = NAMING_V250 | NAMING_BRIDGE_MULTIFUNCTION_SLOT,
|
||||||
|
NAMING_V252 = NAMING_V251 | NAMING_DEVICETREE_ALIASES,
|
||||||
|
+
|
||||||
|
+ NAMING_RHEL_8_0 = NAMING_V239,
|
||||||
|
+ NAMING_RHEL_8_1 = NAMING_V239,
|
||||||
|
+ NAMING_RHEL_8_2 = NAMING_V239,
|
||||||
|
+ NAMING_RHEL_8_3 = NAMING_V239,
|
||||||
|
+ NAMING_RHEL_8_4 = NAMING_V239 | NAMING_BRIDGE_NO_SLOT,
|
||||||
|
+ NAMING_RHEL_8_5 = NAMING_RHEL_8_4,
|
||||||
|
+ NAMING_RHEL_8_6 = NAMING_RHEL_8_4,
|
||||||
|
+ 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_9_0 = NAMING_V250 | NAMING_BRIDGE_MULTIFUNCTION_SLOT,
|
||||||
|
NAMING_RHEL_9_1 = NAMING_RHEL_9_0,
|
||||||
|
NAMING_RHEL_9_2 = NAMING_RHEL_9_0,
|
@ -0,0 +1,368 @@
|
|||||||
|
From f898f9d1290a25d70f2be99f4cf142060ca7ae63 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Joshua Zivkovic <joshua.zivkovic@codethink.co.uk>
|
||||||
|
Date: Wed, 2 Nov 2022 08:55:50 +0000
|
||||||
|
Subject: [PATCH] systemd-analyze: Add table and JSON output implementation to
|
||||||
|
plot
|
||||||
|
|
||||||
|
(cherry picked from commit ff46b2f97c42d73401ca3ffaaef54a017dc23923)
|
||||||
|
|
||||||
|
Resolves: RHEL-5070
|
||||||
|
---
|
||||||
|
src/analyze/analyze-plot.c | 168 ++++++++++++++++++++++++++-----------
|
||||||
|
src/analyze/analyze.c | 36 ++++++--
|
||||||
|
src/analyze/analyze.h | 2 +
|
||||||
|
3 files changed, 154 insertions(+), 52 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/src/analyze/analyze-plot.c b/src/analyze/analyze-plot.c
|
||||||
|
index 100bdc3787..24f4add099 100644
|
||||||
|
--- a/src/analyze/analyze-plot.c
|
||||||
|
+++ b/src/analyze/analyze-plot.c
|
||||||
|
@@ -5,6 +5,7 @@
|
||||||
|
#include "analyze-time-data.h"
|
||||||
|
#include "bus-error.h"
|
||||||
|
#include "bus-map-properties.h"
|
||||||
|
+#include "format-table.h"
|
||||||
|
#include "sort-util.h"
|
||||||
|
#include "version.h"
|
||||||
|
|
||||||
|
@@ -37,7 +38,7 @@ typedef struct HostInfo {
|
||||||
|
char *architecture;
|
||||||
|
} HostInfo;
|
||||||
|
|
||||||
|
-static HostInfo* free_host_info(HostInfo *hi) {
|
||||||
|
+static HostInfo *free_host_info(HostInfo *hi) {
|
||||||
|
if (!hi)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
@@ -87,7 +88,7 @@ static int acquire_host_info(sd_bus *bus, HostInfo **hi) {
|
||||||
|
}
|
||||||
|
|
||||||
|
r = bus_map_all_properties(
|
||||||
|
- system_bus ?: bus,
|
||||||
|
+ system_bus ? : bus,
|
||||||
|
"org.freedesktop.hostname1",
|
||||||
|
"/org/freedesktop/hostname1",
|
||||||
|
hostname_map,
|
||||||
|
@@ -156,15 +157,14 @@ static void svg_graph_box(double height, double begin, double end) {
|
||||||
|
SCALE_Y * height);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
-
|
||||||
|
static int plot_unit_times(UnitTimes *u, double width, int y) {
|
||||||
|
bool b;
|
||||||
|
|
||||||
|
if (!u->name)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
- svg_bar("activating", u->activating, u->activated, y);
|
||||||
|
- svg_bar("active", u->activated, u->deactivating, y);
|
||||||
|
+ svg_bar("activating", u->activating, u->activated, y);
|
||||||
|
+ svg_bar("active", u->activated, u->deactivating, y);
|
||||||
|
svg_bar("deactivating", u->deactivating, u->deactivated, y);
|
||||||
|
|
||||||
|
/* place the text on the left if we have passed the half of the svg width */
|
||||||
|
@@ -178,41 +178,27 @@ static int plot_unit_times(UnitTimes *u, double width, int y) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
-int verb_plot(int argc, char *argv[], void *userdata) {
|
||||||
|
- _cleanup_(free_host_infop) HostInfo *host = NULL;
|
||||||
|
- _cleanup_(sd_bus_flush_close_unrefp) sd_bus *bus = NULL;
|
||||||
|
- _cleanup_(unit_times_free_arrayp) UnitTimes *times = NULL;
|
||||||
|
- _cleanup_free_ char *pretty_times = NULL;
|
||||||
|
- bool use_full_bus = arg_scope == LOOKUP_SCOPE_SYSTEM;
|
||||||
|
- BootTimes *boot;
|
||||||
|
+static void limit_times_to_boot(const BootTimes *boot, UnitTimes *u) {
|
||||||
|
+ if (u->deactivated > u->activating && u->deactivated <= boot->finish_time && u->activated == 0
|
||||||
|
+ && u->deactivating == 0)
|
||||||
|
+ u->activated = u->deactivating = u->deactivated;
|
||||||
|
+ if (u->activated < u->activating || u->activated > boot->finish_time)
|
||||||
|
+ u->activated = boot->finish_time;
|
||||||
|
+ if (u->deactivating < u->activated || u->deactivating > boot->finish_time)
|
||||||
|
+ u->deactivating = boot->finish_time;
|
||||||
|
+ if (u->deactivated < u->deactivating || u->deactivated > boot->finish_time)
|
||||||
|
+ u->deactivated = boot->finish_time;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static int produce_plot_as_svg(
|
||||||
|
+ UnitTimes *times,
|
||||||
|
+ const HostInfo *host,
|
||||||
|
+ const BootTimes *boot,
|
||||||
|
+ const char *pretty_times) {
|
||||||
|
+ int m = 1, y = 0;
|
||||||
|
UnitTimes *u;
|
||||||
|
- int n, m = 1, y = 0, r;
|
||||||
|
double width;
|
||||||
|
|
||||||
|
- r = acquire_bus(&bus, &use_full_bus);
|
||||||
|
- if (r < 0)
|
||||||
|
- return bus_log_connect_error(r, arg_transport);
|
||||||
|
-
|
||||||
|
- n = acquire_boot_times(bus, &boot);
|
||||||
|
- if (n < 0)
|
||||||
|
- return n;
|
||||||
|
-
|
||||||
|
- n = pretty_boot_time(bus, &pretty_times);
|
||||||
|
- if (n < 0)
|
||||||
|
- return n;
|
||||||
|
-
|
||||||
|
- if (use_full_bus || arg_scope != LOOKUP_SCOPE_SYSTEM) {
|
||||||
|
- n = acquire_host_info(bus, &host);
|
||||||
|
- if (n < 0)
|
||||||
|
- return n;
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- n = acquire_time_data(bus, ×);
|
||||||
|
- if (n <= 0)
|
||||||
|
- return n;
|
||||||
|
-
|
||||||
|
- typesafe_qsort(times, n, compare_unit_start);
|
||||||
|
-
|
||||||
|
width = SCALE_X * (boot->firmware_time + boot->finish_time);
|
||||||
|
if (width < 800.0)
|
||||||
|
width = 800.0;
|
||||||
|
@@ -245,16 +231,8 @@ int verb_plot(int argc, char *argv[], void *userdata) {
|
||||||
|
if (text_width > text_start && text_width + text_start > width)
|
||||||
|
width = text_width + text_start;
|
||||||
|
|
||||||
|
- if (u->deactivated > u->activating &&
|
||||||
|
- u->deactivated <= boot->finish_time &&
|
||||||
|
- u->activated == 0 && u->deactivating == 0)
|
||||||
|
- u->activated = u->deactivating = u->deactivated;
|
||||||
|
- if (u->activated < u->activating || u->activated > boot->finish_time)
|
||||||
|
- u->activated = boot->finish_time;
|
||||||
|
- if (u->deactivating < u->activated || u->deactivating > boot->finish_time)
|
||||||
|
- u->deactivating = boot->finish_time;
|
||||||
|
- if (u->deactivated < u->deactivating || u->deactivated > boot->finish_time)
|
||||||
|
- u->deactivated = boot->finish_time;
|
||||||
|
+ limit_times_to_boot(boot, u);
|
||||||
|
+
|
||||||
|
m++;
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -391,5 +369,101 @@ int verb_plot(int argc, char *argv[], void *userdata) {
|
||||||
|
|
||||||
|
svg("</svg>\n");
|
||||||
|
|
||||||
|
+ return 0;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static int show_table(Table *table, const char *word) {
|
||||||
|
+ int r;
|
||||||
|
+
|
||||||
|
+ assert(table);
|
||||||
|
+ assert(word);
|
||||||
|
+
|
||||||
|
+ if (table_get_rows(table) > 1) {
|
||||||
|
+ table_set_header(table, arg_legend);
|
||||||
|
+
|
||||||
|
+ if (!FLAGS_SET(arg_json_format_flags, JSON_FORMAT_OFF))
|
||||||
|
+ r = table_print_json(table, NULL, arg_json_format_flags | JSON_FORMAT_COLOR_AUTO);
|
||||||
|
+ else
|
||||||
|
+ r = table_print(table, NULL);
|
||||||
|
+ if (r < 0)
|
||||||
|
+ return table_log_print_error(r);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ if (arg_legend) {
|
||||||
|
+ if (table_get_rows(table) > 1)
|
||||||
|
+ printf("\n%zu %s listed.\n", table_get_rows(table) - 1, word);
|
||||||
|
+ else
|
||||||
|
+ printf("No %s.\n", word);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ return 0;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static int produce_plot_as_text(UnitTimes *times, const BootTimes *boot) {
|
||||||
|
+ _cleanup_(table_unrefp) Table *table = NULL;
|
||||||
|
+ int r;
|
||||||
|
+
|
||||||
|
+ table = table_new("name", "activated", "activating", "time", "deactivated", "deactivating");
|
||||||
|
+ if (!table)
|
||||||
|
+ return log_oom();
|
||||||
|
+
|
||||||
|
+ for (; times->has_data; times++) {
|
||||||
|
+ limit_times_to_boot(boot, times);
|
||||||
|
+
|
||||||
|
+ r = table_add_many(
|
||||||
|
+ table,
|
||||||
|
+ TABLE_STRING, times->name,
|
||||||
|
+ TABLE_TIMESPAN_MSEC, times->activated,
|
||||||
|
+ TABLE_TIMESPAN_MSEC, times->activating,
|
||||||
|
+ TABLE_TIMESPAN_MSEC, times->time,
|
||||||
|
+ TABLE_TIMESPAN_MSEC, times->deactivated,
|
||||||
|
+ TABLE_TIMESPAN_MSEC, times->deactivating);
|
||||||
|
+ if (r < 0)
|
||||||
|
+ return table_log_add_error(r);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ return show_table(table, "Units");
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+int verb_plot(int argc, char *argv[], void *userdata) {
|
||||||
|
+ _cleanup_(free_host_infop) HostInfo *host = NULL;
|
||||||
|
+ _cleanup_(sd_bus_flush_close_unrefp) sd_bus *bus = NULL;
|
||||||
|
+ _cleanup_(unit_times_free_arrayp) UnitTimes *times = NULL;
|
||||||
|
+ _cleanup_free_ char *pretty_times = NULL;
|
||||||
|
+ bool use_full_bus = arg_scope == LOOKUP_SCOPE_SYSTEM;
|
||||||
|
+ BootTimes *boot;
|
||||||
|
+ int n, r;
|
||||||
|
+
|
||||||
|
+ r = acquire_bus(&bus, &use_full_bus);
|
||||||
|
+ if (r < 0)
|
||||||
|
+ return bus_log_connect_error(r, arg_transport);
|
||||||
|
+
|
||||||
|
+ n = acquire_boot_times(bus, &boot);
|
||||||
|
+ if (n < 0)
|
||||||
|
+ return n;
|
||||||
|
+
|
||||||
|
+ n = pretty_boot_time(bus, &pretty_times);
|
||||||
|
+ if (n < 0)
|
||||||
|
+ return n;
|
||||||
|
+
|
||||||
|
+ if (use_full_bus || arg_scope != LOOKUP_SCOPE_SYSTEM) {
|
||||||
|
+ n = acquire_host_info(bus, &host);
|
||||||
|
+ if (n < 0)
|
||||||
|
+ return n;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ n = acquire_time_data(bus, ×);
|
||||||
|
+ if (n <= 0)
|
||||||
|
+ return n;
|
||||||
|
+
|
||||||
|
+ typesafe_qsort(times, n, compare_unit_start);
|
||||||
|
+
|
||||||
|
+ if (!FLAGS_SET(arg_json_format_flags, JSON_FORMAT_OFF) || arg_table)
|
||||||
|
+ r = produce_plot_as_text(times, boot);
|
||||||
|
+ else
|
||||||
|
+ r = produce_plot_as_svg(times, host, boot, pretty_times);
|
||||||
|
+ if (r < 0)
|
||||||
|
+ return r;
|
||||||
|
+
|
||||||
|
return EXIT_SUCCESS;
|
||||||
|
}
|
||||||
|
diff --git a/src/analyze/analyze.c b/src/analyze/analyze.c
|
||||||
|
index 6e47357a11..825c19c6f4 100644
|
||||||
|
--- a/src/analyze/analyze.c
|
||||||
|
+++ b/src/analyze/analyze.c
|
||||||
|
@@ -105,6 +105,8 @@ char *arg_unit = NULL;
|
||||||
|
JsonFormatFlags arg_json_format_flags = JSON_FORMAT_OFF;
|
||||||
|
bool arg_quiet = false;
|
||||||
|
char *arg_profile = NULL;
|
||||||
|
+bool arg_legend = true;
|
||||||
|
+bool arg_table = false;
|
||||||
|
|
||||||
|
STATIC_DESTRUCTOR_REGISTER(arg_dot_from_patterns, strv_freep);
|
||||||
|
STATIC_DESTRUCTOR_REGISTER(arg_dot_to_patterns, strv_freep);
|
||||||
|
@@ -217,8 +219,10 @@ static int help(int argc, char *argv[], void *userdata) {
|
||||||
|
" --security-policy=PATH Use custom JSON security policy instead\n"
|
||||||
|
" of built-in one\n"
|
||||||
|
" --json=pretty|short|off Generate JSON output of the security\n"
|
||||||
|
- " analysis table\n"
|
||||||
|
+ " analysis table, or plot's raw time data\n"
|
||||||
|
" --no-pager Do not pipe output into a pager\n"
|
||||||
|
+ " --no-legend Disable column headers and hints in plot\n"
|
||||||
|
+ " with either --table or --json=\n"
|
||||||
|
" --system Operate on system systemd instance\n"
|
||||||
|
" --user Operate on user systemd instance\n"
|
||||||
|
" --global Operate on global user configuration\n"
|
||||||
|
@@ -238,6 +242,7 @@ static int help(int argc, char *argv[], void *userdata) {
|
||||||
|
" specified time\n"
|
||||||
|
" --profile=name|PATH Include the specified profile in the\n"
|
||||||
|
" security review of the unit(s)\n"
|
||||||
|
+ " --table Output plot's raw time data as a table\n"
|
||||||
|
" -h --help Show this help\n"
|
||||||
|
" --version Show package version\n"
|
||||||
|
" -q --quiet Do not emit hints\n"
|
||||||
|
@@ -280,6 +285,8 @@ static int parse_argv(int argc, char *argv[]) {
|
||||||
|
ARG_SECURITY_POLICY,
|
||||||
|
ARG_JSON,
|
||||||
|
ARG_PROFILE,
|
||||||
|
+ ARG_TABLE,
|
||||||
|
+ ARG_NO_LEGEND,
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct option options[] = {
|
||||||
|
@@ -310,6 +317,8 @@ static int parse_argv(int argc, char *argv[]) {
|
||||||
|
{ "unit", required_argument, NULL, 'U' },
|
||||||
|
{ "json", required_argument, NULL, ARG_JSON },
|
||||||
|
{ "profile", required_argument, NULL, ARG_PROFILE },
|
||||||
|
+ { "table", optional_argument, NULL, ARG_TABLE },
|
||||||
|
+ { "no-legend", optional_argument, NULL, ARG_NO_LEGEND },
|
||||||
|
{}
|
||||||
|
};
|
||||||
|
|
||||||
|
@@ -448,14 +457,12 @@ static int parse_argv(int argc, char *argv[]) {
|
||||||
|
r = safe_atou(optarg, &arg_iterations);
|
||||||
|
if (r < 0)
|
||||||
|
return log_error_errno(r, "Failed to parse iterations: %s", optarg);
|
||||||
|
-
|
||||||
|
break;
|
||||||
|
|
||||||
|
case ARG_BASE_TIME:
|
||||||
|
r = parse_timestamp(optarg, &arg_base_time);
|
||||||
|
if (r < 0)
|
||||||
|
return log_error_errno(r, "Failed to parse --base-time= parameter: %s", optarg);
|
||||||
|
-
|
||||||
|
break;
|
||||||
|
|
||||||
|
case ARG_PROFILE:
|
||||||
|
@@ -486,6 +493,15 @@ static int parse_argv(int argc, char *argv[]) {
|
||||||
|
free_and_replace(arg_unit, mangled);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
+
|
||||||
|
+ case ARG_TABLE:
|
||||||
|
+ arg_table = true;
|
||||||
|
+ break;
|
||||||
|
+
|
||||||
|
+ case ARG_NO_LEGEND:
|
||||||
|
+ arg_legend = false;
|
||||||
|
+ break;
|
||||||
|
+
|
||||||
|
case '?':
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
@@ -497,9 +513,9 @@ static int parse_argv(int argc, char *argv[]) {
|
||||||
|
return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
|
||||||
|
"Option --offline= is only supported for security right now.");
|
||||||
|
|
||||||
|
- if (arg_json_format_flags != JSON_FORMAT_OFF && !STRPTR_IN_SET(argv[optind], "security", "inspect-elf"))
|
||||||
|
+ if (arg_json_format_flags != JSON_FORMAT_OFF && !STRPTR_IN_SET(argv[optind], "security", "inspect-elf", "plot"))
|
||||||
|
return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
|
||||||
|
- "Option --json= is only supported for security and inspect-elf right now.");
|
||||||
|
+ "Option --json= is only supported for security, inspect-elf, and plot right now.");
|
||||||
|
|
||||||
|
if (arg_threshold != 100 && !streq_ptr(argv[optind], "security"))
|
||||||
|
return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
|
||||||
|
@@ -536,6 +552,16 @@ static int parse_argv(int argc, char *argv[]) {
|
||||||
|
if (streq_ptr(argv[optind], "condition") && arg_unit && optind < argc - 1)
|
||||||
|
return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "No conditions can be passed if --unit= is used.");
|
||||||
|
|
||||||
|
+ if ((!arg_legend && !streq_ptr(argv[optind], "plot")) ||
|
||||||
|
+ (streq_ptr(argv[optind], "plot") && !arg_legend && !arg_table && FLAGS_SET(arg_json_format_flags, JSON_FORMAT_OFF)))
|
||||||
|
+ return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Option --no-legend is only supported for plot with either --table or --json=.");
|
||||||
|
+
|
||||||
|
+ if (arg_table && !streq_ptr(argv[optind], "plot"))
|
||||||
|
+ return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Option --table is only supported for plot right now.");
|
||||||
|
+
|
||||||
|
+ if (arg_table && !FLAGS_SET(arg_json_format_flags, JSON_FORMAT_OFF))
|
||||||
|
+ return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "--table and --json= are mutually exclusive.");
|
||||||
|
+
|
||||||
|
return 1; /* work to do */
|
||||||
|
}
|
||||||
|
|
||||||
|
diff --git a/src/analyze/analyze.h b/src/analyze/analyze.h
|
||||||
|
index da12058c43..e4af7b47e0 100644
|
||||||
|
--- a/src/analyze/analyze.h
|
||||||
|
+++ b/src/analyze/analyze.h
|
||||||
|
@@ -36,6 +36,8 @@ extern char *arg_unit;
|
||||||
|
extern JsonFormatFlags arg_json_format_flags;
|
||||||
|
extern bool arg_quiet;
|
||||||
|
extern char *arg_profile;
|
||||||
|
+extern bool arg_legend;
|
||||||
|
+extern bool arg_table;
|
||||||
|
|
||||||
|
int acquire_bus(sd_bus **bus, bool *use_full_bus);
|
||||||
|
|
@ -0,0 +1,69 @@
|
|||||||
|
From 09514fbcaf51f1c12b651420e24400ff7319c638 Mon Sep 17 00:00:00 2001
|
||||||
|
From: joshuazivkovic <joshua.zivkovic@codethink.co.uk>
|
||||||
|
Date: Wed, 14 Dec 2022 12:31:22 +0000
|
||||||
|
Subject: [PATCH] systemd-analyze: Update man/systemd-analyze.xml with Plot
|
||||||
|
JSON and table
|
||||||
|
|
||||||
|
(cherry picked from commit dc57a3387bbe7770491f35e0d993f411237636b5)
|
||||||
|
|
||||||
|
Resolves: RHEL-5070
|
||||||
|
---
|
||||||
|
man/systemd-analyze.xml | 31 ++++++++++++++++++++++++++++---
|
||||||
|
1 file changed, 28 insertions(+), 3 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/man/systemd-analyze.xml b/man/systemd-analyze.xml
|
||||||
|
index 0d91cdd7d0..5ba0d40fa0 100644
|
||||||
|
--- a/man/systemd-analyze.xml
|
||||||
|
+++ b/man/systemd-analyze.xml
|
||||||
|
@@ -274,8 +274,8 @@ Timestamp units-load-finish: Thu 2019-03-14 23:28:07 CET
|
||||||
|
<refsect2>
|
||||||
|
<title><command>systemd-analyze plot</command></title>
|
||||||
|
|
||||||
|
- <para>This command prints an SVG graphic detailing which system services have been started at what
|
||||||
|
- time, highlighting the time they spent on initialization.</para>
|
||||||
|
+ <para>This command prints either an SVG graphic, detailing which system services have been started at what
|
||||||
|
+ time, highlighting the time they spent on initialization, or the raw time data in JSON or table format.</para>
|
||||||
|
|
||||||
|
<example>
|
||||||
|
<title><command>Plot a bootchart</command></title>
|
||||||
|
@@ -1204,7 +1204,17 @@ $ systemd-analyze verify /tmp/source:alias.service
|
||||||
|
corresponds to a higher security threat. The JSON version of the table is printed to standard
|
||||||
|
output. The <replaceable>MODE</replaceable> passed to the option can be one of three:
|
||||||
|
<option>off</option> which is the default, <option>pretty</option> and <option>short</option>
|
||||||
|
- which respectively output a prettified or shorted JSON version of the security table.</para></listitem>
|
||||||
|
+ which respectively output a prettified or shorted JSON version of the security table.
|
||||||
|
+
|
||||||
|
+ With the <command>plot</command> command, genereate a JSON formatted output of the raw time data.
|
||||||
|
+ The format is a JSON array with objects containing the following fields: <varname>name</varname>
|
||||||
|
+ which is the unit name, <varname>activated</varname> which is the time after startup the
|
||||||
|
+ service was activated, <varname>activating</varname> which is how long after startup the service
|
||||||
|
+ was initially started, <varname>time</varname> which is how long the service took to activate
|
||||||
|
+ from when it was initially started, <varname>deactivated</varname> which is the time after startup
|
||||||
|
+ that the service was deactivated, <varname>deactivating</varname> whcih is the time after startup
|
||||||
|
+ that the service was initially told to deactivate.
|
||||||
|
+ </para></listitem>
|
||||||
|
</varlistentry>
|
||||||
|
|
||||||
|
<varlistentry>
|
||||||
|
@@ -1235,6 +1245,21 @@ $ systemd-analyze verify /tmp/source:alias.service
|
||||||
|
other paths.</para></listitem>
|
||||||
|
</varlistentry>
|
||||||
|
|
||||||
|
+ <varlistentry>
|
||||||
|
+ <term><option>--table</option></term>
|
||||||
|
+
|
||||||
|
+ <listitem><para>When used with the <command>plot</command> command, the raw time data is output in a table.
|
||||||
|
+ </para></listitem>
|
||||||
|
+ </varlistentry>
|
||||||
|
+
|
||||||
|
+ <varlistentry>
|
||||||
|
+ <term><option>--no-legend</option></term>
|
||||||
|
+
|
||||||
|
+ <listitem><para>When used with the <command>plot</command> command in combination with either
|
||||||
|
+ <option>--table</option> or <option>--json=</option>, no legends or hints are included in the output.
|
||||||
|
+ </para></listitem>
|
||||||
|
+ </varlistentry>
|
||||||
|
+
|
||||||
|
<xi:include href="user-system-options.xml" xpointer="host" />
|
||||||
|
<xi:include href="user-system-options.xml" xpointer="machine" />
|
||||||
|
|
@ -0,0 +1,87 @@
|
|||||||
|
From a1bc66bfeac890107411686cb7567c9ffa926972 Mon Sep 17 00:00:00 2001
|
||||||
|
From: joshuazivkovic <joshua.zivkovic@codethink.co.uk>
|
||||||
|
Date: Wed, 14 Dec 2022 12:31:59 +0000
|
||||||
|
Subject: [PATCH] systemd-analyze: Add tab complete logic for plot
|
||||||
|
|
||||||
|
(cherry picked from commit f21a6502d81ca5690467cb161dafd4b875e4430e)
|
||||||
|
|
||||||
|
Resolves: RHEL-5070
|
||||||
|
---
|
||||||
|
shell-completion/bash/systemd-analyze | 8 +++++++-
|
||||||
|
shell-completion/zsh/_systemd-analyze | 14 ++++++++++++--
|
||||||
|
2 files changed, 19 insertions(+), 3 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/shell-completion/bash/systemd-analyze b/shell-completion/bash/systemd-analyze
|
||||||
|
index b1baec9978..5edba7bf58 100644
|
||||||
|
--- a/shell-completion/bash/systemd-analyze
|
||||||
|
+++ b/shell-completion/bash/systemd-analyze
|
||||||
|
@@ -62,7 +62,7 @@ _systemd_analyze() {
|
||||||
|
)
|
||||||
|
|
||||||
|
local -A VERBS=(
|
||||||
|
- [STANDALONE]='time blame plot unit-paths exit-status calendar timestamp timespan'
|
||||||
|
+ [STANDALONE]='time blame unit-paths exit-status calendar timestamp timespan'
|
||||||
|
[CRITICAL_CHAIN]='critical-chain'
|
||||||
|
[DOT]='dot'
|
||||||
|
[DUMP]='dump'
|
||||||
|
@@ -72,6 +72,7 @@ _systemd_analyze() {
|
||||||
|
[SECURITY]='security'
|
||||||
|
[CONDITION]='condition'
|
||||||
|
[INSPECT_ELF]='inspect-elf'
|
||||||
|
+ [PLOT]='plot'
|
||||||
|
)
|
||||||
|
|
||||||
|
local CONFIGS='systemd/bootchart.conf systemd/coredump.conf systemd/journald.conf
|
||||||
|
@@ -195,6 +196,11 @@ _systemd_analyze() {
|
||||||
|
comps=$( compgen -A file -- "$cur" )
|
||||||
|
compopt -o filenames
|
||||||
|
fi
|
||||||
|
+
|
||||||
|
+ elif __contains_word "$verb" ${VERBS[PLOT]}; then
|
||||||
|
+ if [[ $cur = -* ]]; then
|
||||||
|
+ comps='--help --version --system --user --global --no-pager --json=off --json=pretty --json=short --table --no-legend'
|
||||||
|
+ fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
COMPREPLY=( $(compgen -W '$comps' -- "$cur") )
|
||||||
|
diff --git a/shell-completion/zsh/_systemd-analyze b/shell-completion/zsh/_systemd-analyze
|
||||||
|
index e305995cef..2e046ea111 100644
|
||||||
|
--- a/shell-completion/zsh/_systemd-analyze
|
||||||
|
+++ b/shell-completion/zsh/_systemd-analyze
|
||||||
|
@@ -40,6 +40,13 @@
|
||||||
|
_describe -t groups 'file system groups' _groups || compadd "$@"
|
||||||
|
}
|
||||||
|
|
||||||
|
+(( $+functions[_systemd-analyze_plot] )) ||
|
||||||
|
+ _systemd-analyze_plot() {
|
||||||
|
+ local -a _options
|
||||||
|
+ _options=( '--json=off' '--json=pretty' '--json=short' '--table' '--no-legend' )
|
||||||
|
+ _describe 'plot options' _options
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
(( $+functions[_systemd-analyze_commands] )) ||
|
||||||
|
_systemd-analyze_commands(){
|
||||||
|
local -a _systemd_analyze_cmds
|
||||||
|
@@ -48,7 +55,8 @@
|
||||||
|
'time:Print time spent in the kernel before reaching userspace'
|
||||||
|
'blame:Print list of running units ordered by time to init'
|
||||||
|
'critical-chain:Print a tree of the time critical chain of units'
|
||||||
|
- 'plot:Output SVG graphic showing service initialization'
|
||||||
|
+ 'plot:Output SVG graphic showing service initialization, or raw time data in
|
||||||
|
+JSON or table format'
|
||||||
|
'dot:Dump dependency graph (in dot(1) format)'
|
||||||
|
'dump:Dump server status'
|
||||||
|
'cat-config:Cat systemd config files'
|
||||||
|
@@ -97,9 +105,11 @@ _arguments \
|
||||||
|
'--offline=[Perform a security review of the specified unit files]:BOOL:(yes no)' \
|
||||||
|
'--threshold=[Set a value to compare the overall security exposure level with]: NUMBER' \
|
||||||
|
'--security-policy=[Use customized requirements to compare unit files against]: PATH' \
|
||||||
|
- '--json=[Generate a JSON output of the security analysis table]:MODE:(pretty short off)' \
|
||||||
|
+ "--json=[Generate a JSON output of the security analysis table or plot's raw time data]:MODE:(pretty short off)" \
|
||||||
|
+ "--table=[Generate a table of plot's raw time data]" \
|
||||||
|
'--profile=[Include the specified profile in the security review of units]: PATH' \
|
||||||
|
'--no-pager[Do not pipe output into a pager]' \
|
||||||
|
+ "--no-legend[Do not show the headers and footers for plot's raw time data formats]" \
|
||||||
|
'--man=[Do (not) check for existence of man pages]:BOOL:(yes no)' \
|
||||||
|
'--generators=[Do (not) run unit generators]:BOOL:(yes no)' \
|
||||||
|
'--order[When generating graph for dot, show only order]' \
|
@ -0,0 +1,34 @@
|
|||||||
|
From 503c6777cc0a05e4ba174ff674fdf9ce3ed87341 Mon Sep 17 00:00:00 2001
|
||||||
|
From: joshuazivkovic <joshua.zivkovic@codethink.co.uk>
|
||||||
|
Date: Fri, 13 Jan 2023 09:17:27 +0000
|
||||||
|
Subject: [PATCH] systemd-analyze: Add --json=, --table and -no-legend tests
|
||||||
|
for plot
|
||||||
|
|
||||||
|
(cherry picked from commit a23be57de3a5c5afb9ca878775ae838c3341f90c)
|
||||||
|
|
||||||
|
Resolves: RHEL-5070
|
||||||
|
---
|
||||||
|
test/units/testsuite-65.sh | 9 +++++++++
|
||||||
|
1 file changed, 9 insertions(+)
|
||||||
|
|
||||||
|
diff --git a/test/units/testsuite-65.sh b/test/units/testsuite-65.sh
|
||||||
|
index ebe1f57b52..4093c5a2a7 100755
|
||||||
|
--- a/test/units/testsuite-65.sh
|
||||||
|
+++ b/test/units/testsuite-65.sh
|
||||||
|
@@ -18,7 +18,16 @@ systemd-analyze || :
|
||||||
|
systemd-analyze time || :
|
||||||
|
systemd-analyze blame || :
|
||||||
|
systemd-analyze critical-chain || :
|
||||||
|
+# plot
|
||||||
|
systemd-analyze plot >/dev/null || :
|
||||||
|
+systemd-analyze plot --json=pretty >/dev/null || :
|
||||||
|
+systemd-analyze plot --json=short >/dev/null || :
|
||||||
|
+systemd-analyze plot --json=off >/dev/null || :
|
||||||
|
+systemd-analyze plot --json=pretty --no-legend >/dev/null || :
|
||||||
|
+systemd-analyze plot --json=short --no-legend >/dev/null || :
|
||||||
|
+systemd-analyze plot --json=off --no-legend >/dev/null || :
|
||||||
|
+systemd-analyze plot --table >/dev/null || :
|
||||||
|
+systemd-analyze plot --table --no-legend >/dev/null || :
|
||||||
|
# legacy/deprecated options (moved to systemctl, but still usable from analyze)
|
||||||
|
systemd-analyze log-level
|
||||||
|
systemd-analyze log-level "$(systemctl log-level)"
|
@ -0,0 +1,95 @@
|
|||||||
|
From 16f06c8cfbdf660e1c4e2052b7dd121f3497ff0f Mon Sep 17 00:00:00 2001
|
||||||
|
From: Jan Macku <jamacku@redhat.com>
|
||||||
|
Date: Wed, 18 Oct 2023 15:24:23 +0200
|
||||||
|
Subject: [PATCH] ci: enable source-git automation to validate reviews and ci
|
||||||
|
results
|
||||||
|
|
||||||
|
rhel-only
|
||||||
|
|
||||||
|
Related: RHEL-1086
|
||||||
|
---
|
||||||
|
.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 60d7bcf32d..2dd6af3113 100644
|
||||||
|
--- a/.github/workflows/source-git-automation-on-demand.yml
|
||||||
|
+++ b/.github/workflows/source-git-automation-on-demand.yml
|
||||||
|
@@ -74,7 +74,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:
|
||||||
|
@@ -82,7 +83,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:
|
||||||
|
@@ -96,5 +98,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 7fabb88a83..214e72de6f 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,181 @@
|
|||||||
|
From c31597c9112c4676f918b14999506a586d6ef8f4 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Jan Macku <jamacku@redhat.com>
|
||||||
|
Date: Wed, 18 Oct 2023 15:47:54 +0200
|
||||||
|
Subject: [PATCH] ci: remove Mergify config - replaced by Pull Request
|
||||||
|
Validator
|
||||||
|
|
||||||
|
rhel-only
|
||||||
|
|
||||||
|
Related: RHEL-1086
|
||||||
|
---
|
||||||
|
.mergify.yml | 161 ---------------------------------------------------
|
||||||
|
1 file changed, 161 deletions(-)
|
||||||
|
delete mode 100644 .mergify.yml
|
||||||
|
|
||||||
|
diff --git a/.mergify.yml b/.mergify.yml
|
||||||
|
deleted file mode 100644
|
||||||
|
index e862808ca7..0000000000
|
||||||
|
--- a/.mergify.yml
|
||||||
|
+++ /dev/null
|
||||||
|
@@ -1,161 +0,0 @@
|
||||||
|
-# doc: https://docs.mergify.com
|
||||||
|
----
|
||||||
|
-
|
||||||
|
-pull_request_rules:
|
||||||
|
- - name: Add `needs-ci` label on CI fail - v252
|
||||||
|
- conditions:
|
||||||
|
- # Policy is relevant for rhel-9.2.0 branches and newer & main branch
|
||||||
|
- - base~=^main$|^rhel-9.([2-9]|\d{2,}).0$
|
||||||
|
- - label!=ci-waived
|
||||||
|
- - or:
|
||||||
|
- # Build test
|
||||||
|
- # test build check only when the tests have been run ...
|
||||||
|
- - and:
|
||||||
|
- - files~=^(\S+\/meson\.build|\.github\/workflows\/\S+|meson_options\.txt|src\/\S+|test\/fuzz\/\S+)
|
||||||
|
- - or:
|
||||||
|
- - -check-success=build (gcc, 11, bfd, gcrypt)
|
||||||
|
- - -check-success=build (gcc, 12, gold, openssl)
|
||||||
|
- - -check-success=build (clang, 13, mold, gcrypt)
|
||||||
|
- - -check-success=build (clang, 14, lld, openssl)
|
||||||
|
- - -check-success=build (clang, 15, bfd, auto)
|
||||||
|
- # Unit tests
|
||||||
|
- - -check-success=build (GCC, auto)
|
||||||
|
- - -check-success=build (GCC_ASAN_UBSAN, auto)
|
||||||
|
- - -check-success=build (CLANG, auto)
|
||||||
|
- - -check-success=build (CLANG_RELEASE, auto)
|
||||||
|
- - -check-success=build (CLANG_ASAN_UBSAN, auto)
|
||||||
|
- - -check-success=build (CLANG_ASAN_UBSAN_NO_DEPS, auto)
|
||||||
|
- - -check-success=build (GCC, openssl)
|
||||||
|
- - -check-success=build (CLANG, gcrypt)
|
||||||
|
- # ClusterFuzzingLite
|
||||||
|
- - -check-success=PR (address)
|
||||||
|
- - -check-success=PR (undefined)
|
||||||
|
- - -check-success=PR (memory)
|
||||||
|
- # CentOS CI
|
||||||
|
- - -check-success=CentOS CI (CentOS Stream 9)
|
||||||
|
- - -check-success=CentOS CI (CentOS Stream 9 + sanitizers)
|
||||||
|
- # Packit
|
||||||
|
- - -check-success=rpm-build:centos-stream-9-aarch64
|
||||||
|
- - -check-success=rpm-build:centos-stream-9-x86_64
|
||||||
|
- # Other
|
||||||
|
- - -check-success=Lint Code Base
|
||||||
|
- - -check-success=Differential ShellCheck
|
||||||
|
- # CodeQL
|
||||||
|
- # test CodeQL check only when the CodeQL have been run ...
|
||||||
|
- - and:
|
||||||
|
- - files~=^(\S+\/meson\.build|\.github\/\S+\/codeql|src\/\S+|test\/\S+|tools\/\S+)
|
||||||
|
- - -check-success=CodeQL
|
||||||
|
- actions:
|
||||||
|
- label:
|
||||||
|
- add:
|
||||||
|
- - needs-ci
|
||||||
|
-
|
||||||
|
- - name: Add `needs-ci` label on CI fail - v250
|
||||||
|
- conditions:
|
||||||
|
- # Policy is relevant branches before rhel-9.2.0
|
||||||
|
- - base~=^rhel-9.0.0-beta$|^rhel-9.[0-1].0$
|
||||||
|
- - label!=ci-waived
|
||||||
|
- - or:
|
||||||
|
- # Build test
|
||||||
|
- - -check-success=build (gcc, 10, bfd)
|
||||||
|
- - -check-success=build (gcc, 11, gold)
|
||||||
|
- - -check-success=build (clang, 11, bfd)
|
||||||
|
- - -check-success=build (clang, 12, gold)
|
||||||
|
- - -check-success=build (clang, 13, lld)
|
||||||
|
- # Unit tests
|
||||||
|
- - -check-success=build (GCC, auto)
|
||||||
|
- - -check-success=build (GCC_ASAN_UBSAN, auto)
|
||||||
|
- - -check-success=build (CLANG, auto)
|
||||||
|
- - -check-success=build (CLANG_ASAN_UBSAN, auto)
|
||||||
|
- - -check-success=build (GCC, openssl)
|
||||||
|
- - -check-success=build (CLANG, gcrypt)
|
||||||
|
- # CentOS CI
|
||||||
|
- - -check-success=CentOS CI (CentOS Stream 9)
|
||||||
|
- - -check-success=CentOS CI (CentOS Stream 9 + sanitizers)
|
||||||
|
- # Packit
|
||||||
|
- - -check-success=rpm-build:centos-stream-9-aarch64
|
||||||
|
- - -check-success=rpm-build:centos-stream-9-x86_64
|
||||||
|
- actions:
|
||||||
|
- label:
|
||||||
|
- add:
|
||||||
|
- - needs-ci
|
||||||
|
-
|
||||||
|
- - name: Remove `needs-ci` label on CI success - v252
|
||||||
|
- conditions:
|
||||||
|
- # Policy is relevant for rhel-9.2.0 branches and newer & main branch
|
||||||
|
- - base~=^main$|^rhel-9.([2-9]|\d{2,}).0$
|
||||||
|
- - or:
|
||||||
|
- - label=ci-waived
|
||||||
|
- - and:
|
||||||
|
- # Build test
|
||||||
|
- # test build check only when specific files are changed ...
|
||||||
|
- - or:
|
||||||
|
- - -files~=^(\S+\/meson\.build|\.github\/workflows\/\S+|meson_options\.txt|src\/\S+|test\/fuzz\/\S+)
|
||||||
|
- - and:
|
||||||
|
- - check-success=build (gcc, 11, bfd, gcrypt)
|
||||||
|
- - check-success=build (gcc, 12, gold, openssl)
|
||||||
|
- - check-success=build (clang, 13, mold, gcrypt)
|
||||||
|
- - check-success=build (clang, 14, lld, openssl)
|
||||||
|
- - check-success=build (clang, 15, bfd, auto)
|
||||||
|
- # Unit tests
|
||||||
|
- - check-success=build (GCC, auto)
|
||||||
|
- - check-success=build (GCC_ASAN_UBSAN, auto)
|
||||||
|
- - check-success=build (CLANG, auto)
|
||||||
|
- - check-success=build (CLANG_RELEASE, auto)
|
||||||
|
- - check-success=build (CLANG_ASAN_UBSAN, auto)
|
||||||
|
- - check-success=build (CLANG_ASAN_UBSAN_NO_DEPS, auto)
|
||||||
|
- - check-success=build (GCC, openssl)
|
||||||
|
- - check-success=build (CLANG, gcrypt)
|
||||||
|
- # ClusterFuzzingLite
|
||||||
|
- - check-success=PR (address)
|
||||||
|
- - check-success=PR (undefined)
|
||||||
|
- - check-success=PR (memory)
|
||||||
|
- # CentOS CI
|
||||||
|
- - check-success=CentOS CI (CentOS Stream 9)
|
||||||
|
- - check-success=CentOS CI (CentOS Stream 9 + sanitizers)
|
||||||
|
- # CodeQL
|
||||||
|
- # test CodeQL check only when specific files are changed ...
|
||||||
|
- - or:
|
||||||
|
- - -files~=^(\S+\/meson\.build|\.github\/\S+\/codeql|src\/\S+|test\/\S+|tools\/\S+)
|
||||||
|
- - check-success=CodeQL
|
||||||
|
- # Packit
|
||||||
|
- - check-success=rpm-build:centos-stream-9-aarch64
|
||||||
|
- - check-success=rpm-build:centos-stream-9-x86_64
|
||||||
|
- # Other
|
||||||
|
- - check-success=Lint Code Base
|
||||||
|
- - check-success=Differential ShellCheck
|
||||||
|
- actions:
|
||||||
|
- label:
|
||||||
|
- remove:
|
||||||
|
- - needs-ci
|
||||||
|
-
|
||||||
|
- - name: Remove `needs-ci` label on CI success - v250
|
||||||
|
- conditions:
|
||||||
|
- # Policy is relevant branches before rhel-9.2.0
|
||||||
|
- - base~=^rhel-9.0.0-beta$|^rhel-9.[0-1].0$
|
||||||
|
- - or:
|
||||||
|
- - label=ci-waived
|
||||||
|
- - and:
|
||||||
|
- # Build test
|
||||||
|
- - check-success=build (gcc, 10, bfd)
|
||||||
|
- - check-success=build (gcc, 11, gold)
|
||||||
|
- - check-success=build (clang, 11, bfd)
|
||||||
|
- - check-success=build (clang, 12, gold)
|
||||||
|
- - check-success=build (clang, 13, lld)
|
||||||
|
- # Unit tests
|
||||||
|
- - check-success=build (GCC, auto)
|
||||||
|
- - check-success=build (GCC_ASAN_UBSAN, auto)
|
||||||
|
- - check-success=build (CLANG, auto)
|
||||||
|
- - check-success=build (CLANG_ASAN_UBSAN, auto)
|
||||||
|
- - check-success=build (GCC, openssl)
|
||||||
|
- - check-success=build (CLANG, gcrypt)
|
||||||
|
- # CentOS CI
|
||||||
|
- - check-success=CentOS CI (CentOS Stream 9)
|
||||||
|
- - check-success=CentOS CI (CentOS Stream 9 + sanitizers)
|
||||||
|
- # Packit
|
||||||
|
- - check-success=rpm-build:centos-stream-9-aarch64
|
||||||
|
- - check-success=rpm-build:centos-stream-9-x86_64
|
||||||
|
- actions:
|
||||||
|
- label:
|
||||||
|
- remove:
|
||||||
|
- - needs-ci
|
@ -0,0 +1,84 @@
|
|||||||
|
From 34adeef90a0a8cc1210742e5623968cbb39222eb Mon Sep 17 00:00:00 2001
|
||||||
|
From: Jan Macku <jamacku@redhat.com>
|
||||||
|
Date: Fri, 3 Nov 2023 12:32:18 +0100
|
||||||
|
Subject: [PATCH] ci: enable auto-merge GH Action
|
||||||
|
|
||||||
|
rhel-only
|
||||||
|
|
||||||
|
Related: RHEL-1086
|
||||||
|
---
|
||||||
|
.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 2dd6af3113..2c506f2b3e 100644
|
||||||
|
--- a/.github/workflows/source-git-automation-on-demand.yml
|
||||||
|
+++ b/.github/workflows/source-git-automation-on-demand.yml
|
||||||
|
@@ -60,6 +60,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
|
||||||
|
@@ -104,3 +105,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 214e72de6f..17135b590f 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,41 @@
|
|||||||
|
From 715b05f97cde12424bb6d425264569f7f921dc72 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Jan Macku <jamacku@redhat.com>
|
||||||
|
Date: Tue, 7 Nov 2023 13:33:40 +0100
|
||||||
|
Subject: [PATCH] ci: add missing permissions
|
||||||
|
|
||||||
|
issues: write is required for the pull request merging according to:
|
||||||
|
|
||||||
|
https://github.com/cli/cli/discussions/6379#discussioncomment-3806051
|
||||||
|
|
||||||
|
rhel-only
|
||||||
|
|
||||||
|
Related: RHEL-1086
|
||||||
|
---
|
||||||
|
.github/workflows/source-git-automation-on-demand.yml | 1 +
|
||||||
|
.github/workflows/source-git-automation.yml | 1 +
|
||||||
|
2 files changed, 2 insertions(+)
|
||||||
|
|
||||||
|
diff --git a/.github/workflows/source-git-automation-on-demand.yml b/.github/workflows/source-git-automation-on-demand.yml
|
||||||
|
index 2c506f2b3e..bf2ea2260c 100644
|
||||||
|
--- a/.github/workflows/source-git-automation-on-demand.yml
|
||||||
|
+++ b/.github/workflows/source-git-automation-on-demand.yml
|
||||||
|
@@ -63,6 +63,7 @@ jobs:
|
||||||
|
contents: write
|
||||||
|
statuses: write
|
||||||
|
checks: write
|
||||||
|
+ issues: write
|
||||||
|
pull-requests: write
|
||||||
|
|
||||||
|
steps:
|
||||||
|
diff --git a/.github/workflows/source-git-automation.yml b/.github/workflows/source-git-automation.yml
|
||||||
|
index 17135b590f..d71664efa0 100644
|
||||||
|
--- a/.github/workflows/source-git-automation.yml
|
||||||
|
+++ b/.github/workflows/source-git-automation.yml
|
||||||
|
@@ -92,6 +92,7 @@ jobs:
|
||||||
|
permissions:
|
||||||
|
contents: write
|
||||||
|
checks: write
|
||||||
|
+ issues: write
|
||||||
|
pull-requests: write
|
||||||
|
|
||||||
|
steps:
|
@ -0,0 +1,47 @@
|
|||||||
|
From 3d7593697ac29c7308ef72453a621a1d24662415 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Jan Macku <jamacku@redhat.com>
|
||||||
|
Date: Tue, 7 Nov 2023 14:25:02 +0100
|
||||||
|
Subject: [PATCH] ci: `permissions: write-all`
|
||||||
|
|
||||||
|
rhel-only
|
||||||
|
|
||||||
|
Related: RHEL-1086
|
||||||
|
---
|
||||||
|
.github/workflows/source-git-automation-on-demand.yml | 11 +++++------
|
||||||
|
.github/workflows/source-git-automation.yml | 1 -
|
||||||
|
2 files changed, 5 insertions(+), 7 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/.github/workflows/source-git-automation-on-demand.yml b/.github/workflows/source-git-automation-on-demand.yml
|
||||||
|
index bf2ea2260c..3f3da959c4 100644
|
||||||
|
--- a/.github/workflows/source-git-automation-on-demand.yml
|
||||||
|
+++ b/.github/workflows/source-git-automation-on-demand.yml
|
||||||
|
@@ -59,12 +59,11 @@ jobs:
|
||||||
|
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:
|
||||||
|
- contents: write
|
||||||
|
- statuses: write
|
||||||
|
- checks: write
|
||||||
|
- issues: write
|
||||||
|
- pull-requests: write
|
||||||
|
+ permissions: write-all
|
||||||
|
+ # contents: write
|
||||||
|
+ # statuses: write
|
||||||
|
+ # checks: write
|
||||||
|
+ # pull-requests: write
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: Repository checkout
|
||||||
|
diff --git a/.github/workflows/source-git-automation.yml b/.github/workflows/source-git-automation.yml
|
||||||
|
index d71664efa0..17135b590f 100644
|
||||||
|
--- a/.github/workflows/source-git-automation.yml
|
||||||
|
+++ b/.github/workflows/source-git-automation.yml
|
||||||
|
@@ -92,7 +92,6 @@ jobs:
|
||||||
|
permissions:
|
||||||
|
contents: write
|
||||||
|
checks: write
|
||||||
|
- issues: write
|
||||||
|
pull-requests: write
|
||||||
|
|
||||||
|
steps:
|
@ -0,0 +1,33 @@
|
|||||||
|
From 594d2eb17d4548313eddf4e13ac8c734b268ae93 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Jan Macku <jamacku@redhat.com>
|
||||||
|
Date: Mon, 7 Aug 2023 15:11:00 +0200
|
||||||
|
Subject: [PATCH] ci(lint): exclude `.in` files from ShellCheck lint
|
||||||
|
|
||||||
|
Exclude all `.in` files because they may contain unsupported syntax, and
|
||||||
|
they have to be preprocessed first. For example:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
Error: SHELLCHECK_WARNING:
|
||||||
|
./src/rpm/systemd-update-helper.in:130:37: warning[SC1083]: This { is literal. Check expression (missing ;/\n?) or quote it.
|
||||||
|
```
|
||||||
|
|
||||||
|
Related to: https://github.com/systemd/systemd/pull/28521
|
||||||
|
|
||||||
|
(cherry picked from commit 97eb82682126e7f3ee956a025078ea2b801955cb)
|
||||||
|
|
||||||
|
Related: RHEL-1086
|
||||||
|
---
|
||||||
|
.github/workflows/differential-shellcheck.yml | 2 ++
|
||||||
|
1 file changed, 2 insertions(+)
|
||||||
|
|
||||||
|
diff --git a/.github/workflows/differential-shellcheck.yml b/.github/workflows/differential-shellcheck.yml
|
||||||
|
index 3662126304..0d3eee48e2 100644
|
||||||
|
--- a/.github/workflows/differential-shellcheck.yml
|
||||||
|
+++ b/.github/workflows/differential-shellcheck.yml
|
||||||
|
@@ -32,4 +32,6 @@ jobs:
|
||||||
|
- name: Differential ShellCheck
|
||||||
|
uses: redhat-plumbers-in-action/differential-shellcheck@v4
|
||||||
|
with:
|
||||||
|
+ # exclude all `.in` files because they may contain unsupported syntax, and they have to be preprocessed first
|
||||||
|
+ exclude-path: '**/*.in'
|
||||||
|
token: ${{ secrets.GITHUB_TOKEN }}
|
@ -0,0 +1,43 @@
|
|||||||
|
From 5221edaee281175e3a8ba3e676ba5622085eb1ef Mon Sep 17 00:00:00 2001
|
||||||
|
From: Lennart Poettering <lennart@poettering.net>
|
||||||
|
Date: Tue, 26 Sep 2023 09:52:05 +0200
|
||||||
|
Subject: [PATCH] udev: raise RLIMIT_NOFILE as high as we can
|
||||||
|
|
||||||
|
We might need a lot of fds on large systems, hence raise RLIMIT_NOFILE
|
||||||
|
to what the service manager allows us, which is quite a lot these days.
|
||||||
|
|
||||||
|
udev already sets FORK_RLIMIT_NOFILE_SAFE when forking of chilren, thus
|
||||||
|
ensuring that forked off processes get their RLIMIT_NOFILE soft limit
|
||||||
|
reset to 1K for compat with crappy old select().
|
||||||
|
|
||||||
|
Replaces: #29298
|
||||||
|
Fixes: #28583
|
||||||
|
(cherry picked from commit 1617424ce76d797d081dd6cb1082b954c4d2bf38)
|
||||||
|
|
||||||
|
Resolves: RHEL-11040
|
||||||
|
---
|
||||||
|
src/udev/udevd.c | 4 ++++
|
||||||
|
1 file changed, 4 insertions(+)
|
||||||
|
|
||||||
|
diff --git a/src/udev/udevd.c b/src/udev/udevd.c
|
||||||
|
index e3a2742733..ccc3c0eece 100644
|
||||||
|
--- a/src/udev/udevd.c
|
||||||
|
+++ b/src/udev/udevd.c
|
||||||
|
@@ -55,6 +55,7 @@
|
||||||
|
#include "pretty-print.h"
|
||||||
|
#include "proc-cmdline.h"
|
||||||
|
#include "process-util.h"
|
||||||
|
+#include "rlimit-util.h"
|
||||||
|
#include "selinux-util.h"
|
||||||
|
#include "signal-util.h"
|
||||||
|
#include "socket-util.h"
|
||||||
|
@@ -2040,6 +2041,9 @@ int run_udevd(int argc, char *argv[]) {
|
||||||
|
if (r < 0)
|
||||||
|
return r;
|
||||||
|
|
||||||
|
+ /* Make sure we can have plenty fds (for example for pidfds) */
|
||||||
|
+ (void) rlimit_nofile_bump(-1);
|
||||||
|
+
|
||||||
|
r = RET_NERRNO(mkdir("/run/udev", 0755));
|
||||||
|
if (r < 0 && r != -EEXIST)
|
||||||
|
return log_error_errno(r, "Failed to create /run/udev: %m");
|
@ -0,0 +1,37 @@
|
|||||||
|
From 57d5e48a572b98d6ab978072daddac2f7faf8dc8 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Nick Rosbrook <nick.rosbrook@canonical.com>
|
||||||
|
Date: Wed, 2 Nov 2022 11:05:01 -0400
|
||||||
|
Subject: [PATCH] udev/net: allow new link name as an altname before renaming
|
||||||
|
happens
|
||||||
|
|
||||||
|
When configuring a link's alternative names, the link's new name to-be
|
||||||
|
is not allowed to be included because interface renaming will fail if
|
||||||
|
the new name is already present as an alternative name. However,
|
||||||
|
rtnl_set_link_name will delete the conflicting alternative name before
|
||||||
|
renaming the device, if necessary.
|
||||||
|
|
||||||
|
Allow the new link name to be set as an alternative name before the
|
||||||
|
device is renamed. This means that if the rename is later skipped (i.e.
|
||||||
|
because the link is already up), then the name can at least still be
|
||||||
|
present as an alternative name.
|
||||||
|
|
||||||
|
(cherry picked from commit d0b31efc1ab7f6826ad834cf6b9e371bf73776aa)
|
||||||
|
|
||||||
|
Related: RHEL-5988
|
||||||
|
---
|
||||||
|
src/udev/net/link-config.c | 2 --
|
||||||
|
1 file changed, 2 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/src/udev/net/link-config.c b/src/udev/net/link-config.c
|
||||||
|
index e408725b08..5d28526527 100644
|
||||||
|
--- a/src/udev/net/link-config.c
|
||||||
|
+++ b/src/udev/net/link-config.c
|
||||||
|
@@ -841,8 +841,6 @@ static int link_apply_alternative_names(Link *link, sd_netlink **rtnl) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
- if (link->new_name)
|
||||||
|
- strv_remove(altnames, link->new_name);
|
||||||
|
strv_remove(altnames, link->ifname);
|
||||||
|
|
||||||
|
r = rtnl_get_link_alternative_names(rtnl, link->ifindex, ¤t_altnames);
|
@ -0,0 +1,64 @@
|
|||||||
|
From ded04e17443f1e9a99705d39ae7dde72eb24ef34 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Nick Rosbrook <nick.rosbrook@canonical.com>
|
||||||
|
Date: Fri, 2 Dec 2022 15:26:18 -0500
|
||||||
|
Subject: [PATCH] sd-netlink: do not swap old name and alternative name
|
||||||
|
|
||||||
|
Commit 434a348380 ("netlink: do not fail when new interface name is
|
||||||
|
already used as an alternative name") added logic to set the old
|
||||||
|
interface name as an alternative name, but only when the new name is
|
||||||
|
currently an alternative name. This is not the desired outcome in most
|
||||||
|
cases, and the important part of this commit was to delete the new name
|
||||||
|
from the list of alternative names if necessary.
|
||||||
|
|
||||||
|
(cherry picked from commit 080afbb57c4b2d592c5cf77ab10c6e0be74f0732)
|
||||||
|
|
||||||
|
Related: RHEL-5988
|
||||||
|
---
|
||||||
|
src/libsystemd/sd-netlink/netlink-util.c | 13 -------------
|
||||||
|
1 file changed, 13 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/src/libsystemd/sd-netlink/netlink-util.c b/src/libsystemd/sd-netlink/netlink-util.c
|
||||||
|
index 12cdc99ff2..6b4c25fe5a 100644
|
||||||
|
--- a/src/libsystemd/sd-netlink/netlink-util.c
|
||||||
|
+++ b/src/libsystemd/sd-netlink/netlink-util.c
|
||||||
|
@@ -3,7 +3,6 @@
|
||||||
|
#include "sd-netlink.h"
|
||||||
|
|
||||||
|
#include "fd-util.h"
|
||||||
|
-#include "format-util.h"
|
||||||
|
#include "io-util.h"
|
||||||
|
#include "memory-util.h"
|
||||||
|
#include "netlink-internal.h"
|
||||||
|
@@ -15,7 +14,6 @@
|
||||||
|
int rtnl_set_link_name(sd_netlink **rtnl, int ifindex, const char *name) {
|
||||||
|
_cleanup_(sd_netlink_message_unrefp) sd_netlink_message *message = NULL;
|
||||||
|
_cleanup_strv_free_ char **alternative_names = NULL;
|
||||||
|
- char old_name[IF_NAMESIZE] = {};
|
||||||
|
int r;
|
||||||
|
|
||||||
|
assert(rtnl);
|
||||||
|
@@ -35,10 +33,6 @@ int rtnl_set_link_name(sd_netlink **rtnl, int ifindex, const char *name) {
|
||||||
|
if (r < 0)
|
||||||
|
return log_debug_errno(r, "Failed to remove '%s' from alternative names on network interface %i: %m",
|
||||||
|
name, ifindex);
|
||||||
|
-
|
||||||
|
- r = format_ifname(ifindex, old_name);
|
||||||
|
- if (r < 0)
|
||||||
|
- return log_debug_errno(r, "Failed to get current name of network interface %i: %m", ifindex);
|
||||||
|
}
|
||||||
|
|
||||||
|
r = sd_rtnl_message_new_link(*rtnl, &message, RTM_SETLINK, ifindex);
|
||||||
|
@@ -53,13 +47,6 @@ int rtnl_set_link_name(sd_netlink **rtnl, int ifindex, const char *name) {
|
||||||
|
if (r < 0)
|
||||||
|
return r;
|
||||||
|
|
||||||
|
- if (!isempty(old_name)) {
|
||||||
|
- r = rtnl_set_link_alternative_names(rtnl, ifindex, STRV_MAKE(old_name));
|
||||||
|
- if (r < 0)
|
||||||
|
- log_debug_errno(r, "Failed to set '%s' as an alternative name on network interface %i, ignoring: %m",
|
||||||
|
- old_name, ifindex);
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,66 @@
|
|||||||
|
From 9b6a3b192ba0f22ce99aa5c48c6c7143d12dddba Mon Sep 17 00:00:00 2001
|
||||||
|
From: Nick Rosbrook <nick.rosbrook@canonical.com>
|
||||||
|
Date: Wed, 2 Nov 2022 05:36:14 -0400
|
||||||
|
Subject: [PATCH] sd-netlink: restore altname on error in rtnl_set_link_name
|
||||||
|
|
||||||
|
If a current alternative name is to be used to rename a network
|
||||||
|
interface, the alternative name must be removed first. If interface
|
||||||
|
renaming fails, restore the alternative name that was deleted if
|
||||||
|
necessary.
|
||||||
|
|
||||||
|
(cherry picked from commit 4d600667f8af2985850b03a46357e068d3fb8570)
|
||||||
|
|
||||||
|
Related: RHEL-5988
|
||||||
|
---
|
||||||
|
src/libsystemd/sd-netlink/netlink-util.c | 19 ++++++++++++++++---
|
||||||
|
1 file changed, 16 insertions(+), 3 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/src/libsystemd/sd-netlink/netlink-util.c b/src/libsystemd/sd-netlink/netlink-util.c
|
||||||
|
index 6b4c25fe5a..cfcf2578d6 100644
|
||||||
|
--- a/src/libsystemd/sd-netlink/netlink-util.c
|
||||||
|
+++ b/src/libsystemd/sd-netlink/netlink-util.c
|
||||||
|
@@ -14,6 +14,7 @@
|
||||||
|
int rtnl_set_link_name(sd_netlink **rtnl, int ifindex, const char *name) {
|
||||||
|
_cleanup_(sd_netlink_message_unrefp) sd_netlink_message *message = NULL;
|
||||||
|
_cleanup_strv_free_ char **alternative_names = NULL;
|
||||||
|
+ bool altname_deleted = false;
|
||||||
|
int r;
|
||||||
|
|
||||||
|
assert(rtnl);
|
||||||
|
@@ -33,21 +34,33 @@ int rtnl_set_link_name(sd_netlink **rtnl, int ifindex, const char *name) {
|
||||||
|
if (r < 0)
|
||||||
|
return log_debug_errno(r, "Failed to remove '%s' from alternative names on network interface %i: %m",
|
||||||
|
name, ifindex);
|
||||||
|
+
|
||||||
|
+ altname_deleted = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
r = sd_rtnl_message_new_link(*rtnl, &message, RTM_SETLINK, ifindex);
|
||||||
|
if (r < 0)
|
||||||
|
- return r;
|
||||||
|
+ goto fail;
|
||||||
|
|
||||||
|
r = sd_netlink_message_append_string(message, IFLA_IFNAME, name);
|
||||||
|
if (r < 0)
|
||||||
|
- return r;
|
||||||
|
+ goto fail;
|
||||||
|
|
||||||
|
r = sd_netlink_call(*rtnl, message, 0, NULL);
|
||||||
|
if (r < 0)
|
||||||
|
- return r;
|
||||||
|
+ goto fail;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
+
|
||||||
|
+fail:
|
||||||
|
+ if (altname_deleted) {
|
||||||
|
+ int q = rtnl_set_link_alternative_names(rtnl, ifindex, STRV_MAKE(name));
|
||||||
|
+ if (q < 0)
|
||||||
|
+ log_debug_errno(q, "Failed to restore '%s' as an alternative name on network interface %i, ignoring: %m",
|
||||||
|
+ name, ifindex);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
int rtnl_set_link_properties(
|
@ -0,0 +1,65 @@
|
|||||||
|
From ca122b3f1e00ba6a70e7575266502579108c4b47 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Nick Rosbrook <nick.rosbrook@canonical.com>
|
||||||
|
Date: Fri, 2 Dec 2022 15:35:25 -0500
|
||||||
|
Subject: [PATCH] udev: attempt device rename even if interface is up
|
||||||
|
|
||||||
|
Currently rename_netif() will not attempt to rename a device if it is
|
||||||
|
already up, because the kernel will return -EBUSY unless live renaming
|
||||||
|
is allowed on the device. This restriction will be removed in a future
|
||||||
|
kernel version [1].
|
||||||
|
|
||||||
|
To cover both cases, always attempt to rename the interface and return 0
|
||||||
|
if we get -EBUSY.
|
||||||
|
|
||||||
|
[1] https://git.kernel.org/pub/scm/linux/kernel/git/netdev/net-next.git/commit/?id=bd039b5ea2a9
|
||||||
|
|
||||||
|
(cherry picked from commit 53584e7b61373c26635b906eb64e98fbd3fd3ba4)
|
||||||
|
|
||||||
|
Related: RHEL-5988
|
||||||
|
---
|
||||||
|
src/udev/udev-event.c | 18 ++++++------------
|
||||||
|
1 file changed, 6 insertions(+), 12 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/src/udev/udev-event.c b/src/udev/udev-event.c
|
||||||
|
index b3d92d5150..08d69cf1f0 100644
|
||||||
|
--- a/src/udev/udev-event.c
|
||||||
|
+++ b/src/udev/udev-event.c
|
||||||
|
@@ -862,7 +862,6 @@ int udev_event_spawn(
|
||||||
|
static int rename_netif(UdevEvent *event) {
|
||||||
|
const char *oldname;
|
||||||
|
sd_device *dev;
|
||||||
|
- unsigned flags;
|
||||||
|
int ifindex, r;
|
||||||
|
|
||||||
|
assert(event);
|
||||||
|
@@ -896,17 +895,7 @@ static int rename_netif(UdevEvent *event) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
- r = rtnl_get_link_info(&event->rtnl, ifindex, NULL, &flags, NULL, NULL, NULL);
|
||||||
|
- if (r < 0)
|
||||||
|
- return log_device_warning_errno(dev, r, "Failed to get link flags: %m");
|
||||||
|
-
|
||||||
|
- if (FLAGS_SET(flags, IFF_UP)) {
|
||||||
|
- log_device_info(dev, "Network interface '%s' is already up, refusing to rename to '%s'.",
|
||||||
|
- oldname, event->name);
|
||||||
|
- return 0;
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- /* Set ID_RENAMING boolean property here, and drop it in the corresponding move uevent later. */
|
||||||
|
+ /* Set ID_RENAMING boolean property here. It will be dropped when the corresponding move uevent is processed. */
|
||||||
|
r = device_add_property(dev, "ID_RENAMING", "1");
|
||||||
|
if (r < 0)
|
||||||
|
return log_device_warning_errno(dev, r, "Failed to add 'ID_RENAMING' property: %m");
|
||||||
|
@@ -927,6 +916,11 @@ static int rename_netif(UdevEvent *event) {
|
||||||
|
return log_device_debug_errno(event->dev_db_clone, r, "Failed to update database under /run/udev/data/: %m");
|
||||||
|
|
||||||
|
r = rtnl_set_link_name(&event->rtnl, ifindex, event->name);
|
||||||
|
+ if (r == -EBUSY) {
|
||||||
|
+ log_device_info(dev, "Network interface '%s' is already up, cannot rename to '%s'.",
|
||||||
|
+ oldname, event->name);
|
||||||
|
+ return 0;
|
||||||
|
+ }
|
||||||
|
if (r < 0)
|
||||||
|
return log_device_error_errno(dev, r, "Failed to rename network interface %i from '%s' to '%s': %m",
|
||||||
|
ifindex, oldname, event->name);
|
@ -0,0 +1,74 @@
|
|||||||
|
From 32188058ad3b9a8bfc555215982145a128adfc44 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Nick Rosbrook <nick.rosbrook@canonical.com>
|
||||||
|
Date: Tue, 22 Nov 2022 17:01:47 -0500
|
||||||
|
Subject: [PATCH] sd-netlink: add a test for rtnl_set_link_name()
|
||||||
|
|
||||||
|
Add a test that verifies a deleted alternative name is restored on error
|
||||||
|
in rtnl_set_link_name().
|
||||||
|
|
||||||
|
(cherry picked from commit b338a8bb402a3ab241a617e096b21ae6a7b7badf)
|
||||||
|
|
||||||
|
Related: RHEL-5988
|
||||||
|
---
|
||||||
|
src/libsystemd/sd-netlink/test-netlink.c | 27 ++++++++++++++++++++++++
|
||||||
|
1 file changed, 27 insertions(+)
|
||||||
|
|
||||||
|
diff --git a/src/libsystemd/sd-netlink/test-netlink.c b/src/libsystemd/sd-netlink/test-netlink.c
|
||||||
|
index 3f74ecc068..2d93f9eba0 100644
|
||||||
|
--- a/src/libsystemd/sd-netlink/test-netlink.c
|
||||||
|
+++ b/src/libsystemd/sd-netlink/test-netlink.c
|
||||||
|
@@ -8,6 +8,7 @@
|
||||||
|
#include <linux/if_macsec.h>
|
||||||
|
#include <linux/l2tp.h>
|
||||||
|
#include <linux/nl80211.h>
|
||||||
|
+#include <unistd.h>
|
||||||
|
|
||||||
|
#include "sd-netlink.h"
|
||||||
|
|
||||||
|
@@ -16,6 +17,7 @@
|
||||||
|
#include "macro.h"
|
||||||
|
#include "netlink-genl.h"
|
||||||
|
#include "netlink-internal.h"
|
||||||
|
+#include "netlink-util.h"
|
||||||
|
#include "socket-util.h"
|
||||||
|
#include "stdio-util.h"
|
||||||
|
#include "string-util.h"
|
||||||
|
@@ -667,6 +669,30 @@ static void test_genl(void) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
+static void test_rtnl_set_link_name(sd_netlink *rtnl, int ifindex) {
|
||||||
|
+ _cleanup_strv_free_ char **alternative_names = NULL;
|
||||||
|
+ int r;
|
||||||
|
+
|
||||||
|
+ log_debug("/* %s */", __func__);
|
||||||
|
+
|
||||||
|
+ if (geteuid() != 0)
|
||||||
|
+ return (void) log_tests_skipped("not root");
|
||||||
|
+
|
||||||
|
+ /* Test that the new name (which is currently an alternative name) is
|
||||||
|
+ * restored as an alternative name on error. Create an error by using
|
||||||
|
+ * an invalid device name, namely one that exceeds IFNAMSIZ
|
||||||
|
+ * (alternative names can exceed IFNAMSIZ, but not regular names). */
|
||||||
|
+ r = rtnl_set_link_alternative_names(&rtnl, ifindex, STRV_MAKE("testlongalternativename"));
|
||||||
|
+ if (r == -EPERM)
|
||||||
|
+ return (void) log_tests_skipped("missing required capabilities");
|
||||||
|
+
|
||||||
|
+ assert_se(r >= 0);
|
||||||
|
+ assert_se(rtnl_set_link_name(&rtnl, ifindex, "testlongalternativename") == -EINVAL);
|
||||||
|
+ assert_se(rtnl_get_link_alternative_names(&rtnl, ifindex, &alternative_names) >= 0);
|
||||||
|
+ assert_se(strv_contains(alternative_names, "testlongalternativename"));
|
||||||
|
+ assert_se(rtnl_delete_link_alternative_names(&rtnl, ifindex, STRV_MAKE("testlongalternativename")) >= 0);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
int main(void) {
|
||||||
|
sd_netlink *rtnl;
|
||||||
|
sd_netlink_message *m;
|
||||||
|
@@ -698,6 +724,7 @@ int main(void) {
|
||||||
|
test_pipe(if_loopback);
|
||||||
|
test_event_loop(if_loopback);
|
||||||
|
test_link_configure(rtnl, if_loopback);
|
||||||
|
+ test_rtnl_set_link_name(rtnl, if_loopback);
|
||||||
|
|
||||||
|
test_get_addresses(rtnl);
|
||||||
|
test_message_link_bridge(rtnl);
|
@ -0,0 +1,50 @@
|
|||||||
|
From 6e095bdbd88ddbe289210720e7a55b62fa593ab8 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Nick Rosbrook <nick.rosbrook@canonical.com>
|
||||||
|
Date: Wed, 7 Dec 2022 12:28:28 -0500
|
||||||
|
Subject: [PATCH] test-network: add a test for renaming device to current
|
||||||
|
altname
|
||||||
|
|
||||||
|
(cherry picked from commit f68f644a167af3452be853b631fa9144c6716c28)
|
||||||
|
|
||||||
|
Related: RHEL-5988
|
||||||
|
---
|
||||||
|
.../test-network/conf/12-dummy-rename-to-altname.link | 7 +++++++
|
||||||
|
test/test-network/systemd-networkd-tests.py | 11 +++++++++++
|
||||||
|
2 files changed, 18 insertions(+)
|
||||||
|
create mode 100644 test/test-network/conf/12-dummy-rename-to-altname.link
|
||||||
|
|
||||||
|
diff --git a/test/test-network/conf/12-dummy-rename-to-altname.link b/test/test-network/conf/12-dummy-rename-to-altname.link
|
||||||
|
new file mode 100644
|
||||||
|
index 0000000000..bef4bf3dc5
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/test/test-network/conf/12-dummy-rename-to-altname.link
|
||||||
|
@@ -0,0 +1,7 @@
|
||||||
|
+# SPDX-License-Identifier: LGPL-2.1-or-later
|
||||||
|
+[Match]
|
||||||
|
+OriginalName=dummy98
|
||||||
|
+
|
||||||
|
+[Link]
|
||||||
|
+Name=dummyalt
|
||||||
|
+AlternativeName=dummyalt hogehogehogehogehogehoge
|
||||||
|
diff --git a/test/test-network/systemd-networkd-tests.py b/test/test-network/systemd-networkd-tests.py
|
||||||
|
index 87710ef3fb..696618790a 100755
|
||||||
|
--- a/test/test-network/systemd-networkd-tests.py
|
||||||
|
+++ b/test/test-network/systemd-networkd-tests.py
|
||||||
|
@@ -936,6 +936,17 @@ class NetworkctlTests(unittest.TestCase, Utilities):
|
||||||
|
output = check_output(*networkctl_cmd, '-n', '0', 'status', 'dummy98', env=env)
|
||||||
|
self.assertRegex(output, 'hogehogehogehogehogehoge')
|
||||||
|
|
||||||
|
+ @expectedFailureIfAlternativeNameIsNotAvailable()
|
||||||
|
+ def test_rename_to_altname(self):
|
||||||
|
+ copy_network_unit('26-netdev-link-local-addressing-yes.network',
|
||||||
|
+ '12-dummy.netdev', '12-dummy-rename-to-altname.link')
|
||||||
|
+ start_networkd()
|
||||||
|
+ self.wait_online(['dummyalt:degraded'])
|
||||||
|
+
|
||||||
|
+ output = check_output(*networkctl_cmd, '-n', '0', 'status', 'dummyalt', env=env)
|
||||||
|
+ self.assertIn('hogehogehogehogehogehoge', output)
|
||||||
|
+ self.assertNotIn('dummy98', output)
|
||||||
|
+
|
||||||
|
def test_reconfigure(self):
|
||||||
|
copy_network_unit('25-address-static.network', '12-dummy.netdev')
|
||||||
|
start_networkd()
|
@ -0,0 +1,58 @@
|
|||||||
|
From d808bd97790dd8a38d844c827d2d9dbcb700d8c0 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Yu Watanabe <watanabe.yu+github@gmail.com>
|
||||||
|
Date: Mon, 9 Jan 2023 11:20:35 +0900
|
||||||
|
Subject: [PATCH] udev: align table
|
||||||
|
|
||||||
|
(cherry picked from commit bb1234d1d6b7b14424093a917890bb4013b4ff3e)
|
||||||
|
|
||||||
|
Related: RHEL-5988
|
||||||
|
---
|
||||||
|
src/udev/udev-event.c | 34 +++++++++++++++++-----------------
|
||||||
|
1 file changed, 17 insertions(+), 17 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/src/udev/udev-event.c b/src/udev/udev-event.c
|
||||||
|
index 08d69cf1f0..3ac12d9b52 100644
|
||||||
|
--- a/src/udev/udev-event.c
|
||||||
|
+++ b/src/udev/udev-event.c
|
||||||
|
@@ -119,24 +119,24 @@ struct subst_map_entry {
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct subst_map_entry map[] = {
|
||||||
|
- { .name = "devnode", .fmt = 'N', .type = FORMAT_SUBST_DEVNODE },
|
||||||
|
- { .name = "tempnode", .fmt = 'N', .type = FORMAT_SUBST_DEVNODE }, /* deprecated */
|
||||||
|
- { .name = "attr", .fmt = 's', .type = FORMAT_SUBST_ATTR },
|
||||||
|
- { .name = "sysfs", .fmt = 's', .type = FORMAT_SUBST_ATTR }, /* deprecated */
|
||||||
|
- { .name = "env", .fmt = 'E', .type = FORMAT_SUBST_ENV },
|
||||||
|
- { .name = "kernel", .fmt = 'k', .type = FORMAT_SUBST_KERNEL },
|
||||||
|
+ { .name = "devnode", .fmt = 'N', .type = FORMAT_SUBST_DEVNODE },
|
||||||
|
+ { .name = "tempnode", .fmt = 'N', .type = FORMAT_SUBST_DEVNODE }, /* deprecated */
|
||||||
|
+ { .name = "attr", .fmt = 's', .type = FORMAT_SUBST_ATTR },
|
||||||
|
+ { .name = "sysfs", .fmt = 's', .type = FORMAT_SUBST_ATTR }, /* deprecated */
|
||||||
|
+ { .name = "env", .fmt = 'E', .type = FORMAT_SUBST_ENV },
|
||||||
|
+ { .name = "kernel", .fmt = 'k', .type = FORMAT_SUBST_KERNEL },
|
||||||
|
{ .name = "number", .fmt = 'n', .type = FORMAT_SUBST_KERNEL_NUMBER },
|
||||||
|
- { .name = "driver", .fmt = 'd', .type = FORMAT_SUBST_DRIVER },
|
||||||
|
- { .name = "devpath", .fmt = 'p', .type = FORMAT_SUBST_DEVPATH },
|
||||||
|
- { .name = "id", .fmt = 'b', .type = FORMAT_SUBST_ID },
|
||||||
|
- { .name = "major", .fmt = 'M', .type = FORMAT_SUBST_MAJOR },
|
||||||
|
- { .name = "minor", .fmt = 'm', .type = FORMAT_SUBST_MINOR },
|
||||||
|
- { .name = "result", .fmt = 'c', .type = FORMAT_SUBST_RESULT },
|
||||||
|
- { .name = "parent", .fmt = 'P', .type = FORMAT_SUBST_PARENT },
|
||||||
|
- { .name = "name", .fmt = 'D', .type = FORMAT_SUBST_NAME },
|
||||||
|
- { .name = "links", .fmt = 'L', .type = FORMAT_SUBST_LINKS },
|
||||||
|
- { .name = "root", .fmt = 'r', .type = FORMAT_SUBST_ROOT },
|
||||||
|
- { .name = "sys", .fmt = 'S', .type = FORMAT_SUBST_SYS },
|
||||||
|
+ { .name = "driver", .fmt = 'd', .type = FORMAT_SUBST_DRIVER },
|
||||||
|
+ { .name = "devpath", .fmt = 'p', .type = FORMAT_SUBST_DEVPATH },
|
||||||
|
+ { .name = "id", .fmt = 'b', .type = FORMAT_SUBST_ID },
|
||||||
|
+ { .name = "major", .fmt = 'M', .type = FORMAT_SUBST_MAJOR },
|
||||||
|
+ { .name = "minor", .fmt = 'm', .type = FORMAT_SUBST_MINOR },
|
||||||
|
+ { .name = "result", .fmt = 'c', .type = FORMAT_SUBST_RESULT },
|
||||||
|
+ { .name = "parent", .fmt = 'P', .type = FORMAT_SUBST_PARENT },
|
||||||
|
+ { .name = "name", .fmt = 'D', .type = FORMAT_SUBST_NAME },
|
||||||
|
+ { .name = "links", .fmt = 'L', .type = FORMAT_SUBST_LINKS },
|
||||||
|
+ { .name = "root", .fmt = 'r', .type = FORMAT_SUBST_ROOT },
|
||||||
|
+ { .name = "sys", .fmt = 'S', .type = FORMAT_SUBST_SYS },
|
||||||
|
};
|
||||||
|
|
||||||
|
static const char *format_type_to_string(FormatSubstitutionType t) {
|
@ -0,0 +1,47 @@
|
|||||||
|
From 3b4d91e7ab44738f3773a3bfd4a6c5fb9bbc7322 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Yu Watanabe <watanabe.yu+github@gmail.com>
|
||||||
|
Date: Mon, 9 Jan 2023 14:00:09 +0900
|
||||||
|
Subject: [PATCH] sd-device: make device_set_syspath() clear sysname and sysnum
|
||||||
|
|
||||||
|
Otherwise, when a new syspath is assigned to the sd-device object,
|
||||||
|
sd_device_get_sysname() or _sysnum() will provide an outdated device
|
||||||
|
name or number.
|
||||||
|
|
||||||
|
(cherry picked from commit 9a26098e90116fdb5fcffa03485b375ee0c82b6a)
|
||||||
|
|
||||||
|
Related: RHEL-5988
|
||||||
|
---
|
||||||
|
src/libsystemd/sd-device/device-private.c | 4 ----
|
||||||
|
src/libsystemd/sd-device/sd-device.c | 4 ++++
|
||||||
|
2 files changed, 4 insertions(+), 4 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/src/libsystemd/sd-device/device-private.c b/src/libsystemd/sd-device/device-private.c
|
||||||
|
index bc7a838608..2c1d922ea3 100644
|
||||||
|
--- a/src/libsystemd/sd-device/device-private.c
|
||||||
|
+++ b/src/libsystemd/sd-device/device-private.c
|
||||||
|
@@ -646,10 +646,6 @@ int device_rename(sd_device *device, const char *name) {
|
||||||
|
if (r < 0)
|
||||||
|
return r;
|
||||||
|
|
||||||
|
- /* Here, only clear the sysname and sysnum. They will be set when requested. */
|
||||||
|
- device->sysnum = NULL;
|
||||||
|
- device->sysname = mfree(device->sysname);
|
||||||
|
-
|
||||||
|
r = sd_device_get_property_value(device, "INTERFACE", &interface);
|
||||||
|
if (r == -ENOENT)
|
||||||
|
return 0;
|
||||||
|
diff --git a/src/libsystemd/sd-device/sd-device.c b/src/libsystemd/sd-device/sd-device.c
|
||||||
|
index f2e142457b..c822a0b2f0 100644
|
||||||
|
--- a/src/libsystemd/sd-device/sd-device.c
|
||||||
|
+++ b/src/libsystemd/sd-device/sd-device.c
|
||||||
|
@@ -250,6 +250,10 @@ int device_set_syspath(sd_device *device, const char *_syspath, bool verify) {
|
||||||
|
|
||||||
|
free_and_replace(device->syspath, syspath);
|
||||||
|
device->devpath = devpath;
|
||||||
|
+
|
||||||
|
+ /* Unset sysname and sysnum, they will be assigned when requested. */
|
||||||
|
+ device->sysnum = NULL;
|
||||||
|
+ device->sysname = mfree(device->sysname);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,62 @@
|
|||||||
|
From 2c6ea8a97986c58954603b587875a52b043e4d9b Mon Sep 17 00:00:00 2001
|
||||||
|
From: Yu Watanabe <watanabe.yu+github@gmail.com>
|
||||||
|
Date: Mon, 9 Jan 2023 14:07:16 +0900
|
||||||
|
Subject: [PATCH] sd-device: do not directly access entry in sd-device object
|
||||||
|
|
||||||
|
No functional change, just refactoring.
|
||||||
|
|
||||||
|
(cherry picked from commit 1de6a49721957a85a4934ddbdf88d535774597b1)
|
||||||
|
|
||||||
|
Related: RHEL-5988
|
||||||
|
---
|
||||||
|
src/libsystemd/sd-device/device-private.c | 14 +++++++++-----
|
||||||
|
1 file changed, 9 insertions(+), 5 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/src/libsystemd/sd-device/device-private.c b/src/libsystemd/sd-device/device-private.c
|
||||||
|
index 2c1d922ea3..9cec037237 100644
|
||||||
|
--- a/src/libsystemd/sd-device/device-private.c
|
||||||
|
+++ b/src/libsystemd/sd-device/device-private.c
|
||||||
|
@@ -621,7 +621,7 @@ int device_get_devlink_priority(sd_device *device, int *ret) {
|
||||||
|
|
||||||
|
int device_rename(sd_device *device, const char *name) {
|
||||||
|
_cleanup_free_ char *new_syspath = NULL;
|
||||||
|
- const char *interface;
|
||||||
|
+ const char *s;
|
||||||
|
int r;
|
||||||
|
|
||||||
|
assert(device);
|
||||||
|
@@ -630,7 +630,11 @@ int device_rename(sd_device *device, const char *name) {
|
||||||
|
if (!filename_is_valid(name))
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
- r = path_extract_directory(device->syspath, &new_syspath);
|
||||||
|
+ r = sd_device_get_syspath(device, &s);
|
||||||
|
+ if (r < 0)
|
||||||
|
+ return r;
|
||||||
|
+
|
||||||
|
+ r = path_extract_directory(s, &new_syspath);
|
||||||
|
if (r < 0)
|
||||||
|
return r;
|
||||||
|
|
||||||
|
@@ -642,18 +646,18 @@ int device_rename(sd_device *device, const char *name) {
|
||||||
|
|
||||||
|
/* At the time this is called, the renamed device may not exist yet. Hence, we cannot validate
|
||||||
|
* the new syspath. */
|
||||||
|
- r = device_set_syspath(device, new_syspath, false);
|
||||||
|
+ r = device_set_syspath(device, new_syspath, /* verify = */ false);
|
||||||
|
if (r < 0)
|
||||||
|
return r;
|
||||||
|
|
||||||
|
- r = sd_device_get_property_value(device, "INTERFACE", &interface);
|
||||||
|
+ r = sd_device_get_property_value(device, "INTERFACE", &s);
|
||||||
|
if (r == -ENOENT)
|
||||||
|
return 0;
|
||||||
|
if (r < 0)
|
||||||
|
return r;
|
||||||
|
|
||||||
|
/* like DEVPATH_OLD, INTERFACE_OLD is not saved to the db, but only stays around for the current event */
|
||||||
|
- r = device_add_property_internal(device, "INTERFACE_OLD", interface);
|
||||||
|
+ r = device_add_property_internal(device, "INTERFACE_OLD", s);
|
||||||
|
if (r < 0)
|
||||||
|
return r;
|
||||||
|
|
@ -0,0 +1,148 @@
|
|||||||
|
From 7f183125fbec97bd6e4c0b3ac792b0e0c23132e0 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Yu Watanabe <watanabe.yu+github@gmail.com>
|
||||||
|
Date: Mon, 9 Jan 2023 15:00:30 +0900
|
||||||
|
Subject: [PATCH] udev: move device_rename() from device-private.c
|
||||||
|
|
||||||
|
The function is used only by udevd.
|
||||||
|
|
||||||
|
(cherry picked from commit ff88b949531e70639c507f74da875a7de2adf543)
|
||||||
|
|
||||||
|
Related: RHEL-5988
|
||||||
|
---
|
||||||
|
src/libsystemd/sd-device/device-private.c | 45 ----------------------
|
||||||
|
src/libsystemd/sd-device/device-private.h | 1 -
|
||||||
|
src/udev/udev-event.c | 46 +++++++++++++++++++++++
|
||||||
|
3 files changed, 46 insertions(+), 46 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/src/libsystemd/sd-device/device-private.c b/src/libsystemd/sd-device/device-private.c
|
||||||
|
index 9cec037237..36b0da4f12 100644
|
||||||
|
--- a/src/libsystemd/sd-device/device-private.c
|
||||||
|
+++ b/src/libsystemd/sd-device/device-private.c
|
||||||
|
@@ -619,51 +619,6 @@ int device_get_devlink_priority(sd_device *device, int *ret) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
-int device_rename(sd_device *device, const char *name) {
|
||||||
|
- _cleanup_free_ char *new_syspath = NULL;
|
||||||
|
- const char *s;
|
||||||
|
- int r;
|
||||||
|
-
|
||||||
|
- assert(device);
|
||||||
|
- assert(name);
|
||||||
|
-
|
||||||
|
- if (!filename_is_valid(name))
|
||||||
|
- return -EINVAL;
|
||||||
|
-
|
||||||
|
- r = sd_device_get_syspath(device, &s);
|
||||||
|
- if (r < 0)
|
||||||
|
- return r;
|
||||||
|
-
|
||||||
|
- r = path_extract_directory(s, &new_syspath);
|
||||||
|
- if (r < 0)
|
||||||
|
- return r;
|
||||||
|
-
|
||||||
|
- if (!path_extend(&new_syspath, name))
|
||||||
|
- return -ENOMEM;
|
||||||
|
-
|
||||||
|
- if (!path_is_safe(new_syspath))
|
||||||
|
- return -EINVAL;
|
||||||
|
-
|
||||||
|
- /* At the time this is called, the renamed device may not exist yet. Hence, we cannot validate
|
||||||
|
- * the new syspath. */
|
||||||
|
- r = device_set_syspath(device, new_syspath, /* verify = */ false);
|
||||||
|
- if (r < 0)
|
||||||
|
- return r;
|
||||||
|
-
|
||||||
|
- r = sd_device_get_property_value(device, "INTERFACE", &s);
|
||||||
|
- if (r == -ENOENT)
|
||||||
|
- return 0;
|
||||||
|
- if (r < 0)
|
||||||
|
- return r;
|
||||||
|
-
|
||||||
|
- /* like DEVPATH_OLD, INTERFACE_OLD is not saved to the db, but only stays around for the current event */
|
||||||
|
- r = device_add_property_internal(device, "INTERFACE_OLD", s);
|
||||||
|
- if (r < 0)
|
||||||
|
- return r;
|
||||||
|
-
|
||||||
|
- return device_add_property_internal(device, "INTERFACE", name);
|
||||||
|
-}
|
||||||
|
-
|
||||||
|
static int device_shallow_clone(sd_device *device, sd_device **ret) {
|
||||||
|
_cleanup_(sd_device_unrefp) sd_device *dest = NULL;
|
||||||
|
const char *val = NULL;
|
||||||
|
diff --git a/src/libsystemd/sd-device/device-private.h b/src/libsystemd/sd-device/device-private.h
|
||||||
|
index a59f130aff..e57b74ba24 100644
|
||||||
|
--- a/src/libsystemd/sd-device/device-private.h
|
||||||
|
+++ b/src/libsystemd/sd-device/device-private.h
|
||||||
|
@@ -53,7 +53,6 @@ int device_properties_prepare(sd_device *device);
|
||||||
|
int device_get_properties_nulstr(sd_device *device, const char **ret_nulstr, size_t *ret_len);
|
||||||
|
int device_get_properties_strv(sd_device *device, char ***ret);
|
||||||
|
|
||||||
|
-int device_rename(sd_device *device, const char *name);
|
||||||
|
int device_clone_with_db(sd_device *device, sd_device **ret);
|
||||||
|
|
||||||
|
int device_tag_index(sd_device *dev, sd_device *dev_old, bool add);
|
||||||
|
diff --git a/src/udev/udev-event.c b/src/udev/udev-event.c
|
||||||
|
index 3ac12d9b52..1dc05f863d 100644
|
||||||
|
--- a/src/udev/udev-event.c
|
||||||
|
+++ b/src/udev/udev-event.c
|
||||||
|
@@ -12,6 +12,7 @@
|
||||||
|
#include "sd-event.h"
|
||||||
|
|
||||||
|
#include "alloc-util.h"
|
||||||
|
+#include "device-internal.h"
|
||||||
|
#include "device-private.h"
|
||||||
|
#include "device-util.h"
|
||||||
|
#include "fd-util.h"
|
||||||
|
@@ -859,6 +860,51 @@ int udev_event_spawn(
|
||||||
|
return r; /* 0 for success, and positive if the program failed */
|
||||||
|
}
|
||||||
|
|
||||||
|
+static int device_rename(sd_device *device, const char *name) {
|
||||||
|
+ _cleanup_free_ char *new_syspath = NULL;
|
||||||
|
+ const char *s;
|
||||||
|
+ int r;
|
||||||
|
+
|
||||||
|
+ assert(device);
|
||||||
|
+ assert(name);
|
||||||
|
+
|
||||||
|
+ if (!filename_is_valid(name))
|
||||||
|
+ return -EINVAL;
|
||||||
|
+
|
||||||
|
+ r = sd_device_get_syspath(device, &s);
|
||||||
|
+ if (r < 0)
|
||||||
|
+ return r;
|
||||||
|
+
|
||||||
|
+ r = path_extract_directory(s, &new_syspath);
|
||||||
|
+ if (r < 0)
|
||||||
|
+ return r;
|
||||||
|
+
|
||||||
|
+ if (!path_extend(&new_syspath, name))
|
||||||
|
+ return -ENOMEM;
|
||||||
|
+
|
||||||
|
+ if (!path_is_safe(new_syspath))
|
||||||
|
+ return -EINVAL;
|
||||||
|
+
|
||||||
|
+ /* At the time this is called, the renamed device may not exist yet. Hence, we cannot validate
|
||||||
|
+ * the new syspath. */
|
||||||
|
+ r = device_set_syspath(device, new_syspath, /* verify = */ false);
|
||||||
|
+ if (r < 0)
|
||||||
|
+ return r;
|
||||||
|
+
|
||||||
|
+ r = sd_device_get_property_value(device, "INTERFACE", &s);
|
||||||
|
+ if (r == -ENOENT)
|
||||||
|
+ return 0;
|
||||||
|
+ if (r < 0)
|
||||||
|
+ return r;
|
||||||
|
+
|
||||||
|
+ /* like DEVPATH_OLD, INTERFACE_OLD is not saved to the db, but only stays around for the current event */
|
||||||
|
+ r = device_add_property_internal(device, "INTERFACE_OLD", s);
|
||||||
|
+ if (r < 0)
|
||||||
|
+ return r;
|
||||||
|
+
|
||||||
|
+ return device_add_property_internal(device, "INTERFACE", name);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
static int rename_netif(UdevEvent *event) {
|
||||||
|
const char *oldname;
|
||||||
|
sd_device *dev;
|
@ -0,0 +1,155 @@
|
|||||||
|
From 1f4bc8c496d2a310ffa3e7174af40f7e596cd2d1 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Yu Watanabe <watanabe.yu+github@gmail.com>
|
||||||
|
Date: Mon, 9 Jan 2023 14:58:58 +0900
|
||||||
|
Subject: [PATCH] udev: restore syspath and properties on failure
|
||||||
|
|
||||||
|
Otherwise, invalid sysname or properties may be broadcast to udev
|
||||||
|
listeners.
|
||||||
|
|
||||||
|
(cherry picked from commit 210033847c340c43dd6835520f21f8b23ba29579)
|
||||||
|
|
||||||
|
Related: RHEL-5988
|
||||||
|
---
|
||||||
|
src/udev/udev-event.c | 93 +++++++++++++++++++++++++++++--------------
|
||||||
|
1 file changed, 64 insertions(+), 29 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/src/udev/udev-event.c b/src/udev/udev-event.c
|
||||||
|
index 1dc05f863d..fab454ae37 100644
|
||||||
|
--- a/src/udev/udev-event.c
|
||||||
|
+++ b/src/udev/udev-event.c
|
||||||
|
@@ -906,7 +906,8 @@ static int device_rename(sd_device *device, const char *name) {
|
||||||
|
}
|
||||||
|
|
||||||
|
static int rename_netif(UdevEvent *event) {
|
||||||
|
- const char *oldname;
|
||||||
|
+ _cleanup_free_ char *old_syspath = NULL, *old_sysname = NULL;
|
||||||
|
+ const char *s;
|
||||||
|
sd_device *dev;
|
||||||
|
int ifindex, r;
|
||||||
|
|
||||||
|
@@ -917,15 +918,6 @@ static int rename_netif(UdevEvent *event) {
|
||||||
|
|
||||||
|
dev = ASSERT_PTR(event->dev);
|
||||||
|
|
||||||
|
- /* Read sysname from cloned sd-device object, otherwise use-after-free is triggered, as the
|
||||||
|
- * main object will be renamed and dev->sysname will be freed in device_rename(). */
|
||||||
|
- r = sd_device_get_sysname(event->dev_db_clone, &oldname);
|
||||||
|
- if (r < 0)
|
||||||
|
- return log_device_error_errno(dev, r, "Failed to get sysname: %m");
|
||||||
|
-
|
||||||
|
- if (streq(event->name, oldname))
|
||||||
|
- return 0; /* The interface name is already requested name. */
|
||||||
|
-
|
||||||
|
if (!device_for_action(dev, SD_DEVICE_ADD))
|
||||||
|
return 0; /* Rename the interface only when it is added. */
|
||||||
|
|
||||||
|
@@ -933,7 +925,7 @@ static int rename_netif(UdevEvent *event) {
|
||||||
|
if (r == -ENOENT)
|
||||||
|
return 0; /* Device is not a network interface. */
|
||||||
|
if (r < 0)
|
||||||
|
- return log_device_error_errno(dev, r, "Failed to get ifindex: %m");
|
||||||
|
+ return log_device_warning_errno(dev, r, "Failed to get ifindex: %m");
|
||||||
|
|
||||||
|
if (naming_scheme_has(NAMING_REPLACE_STRICTLY) &&
|
||||||
|
!ifname_valid(event->name)) {
|
||||||
|
@@ -941,39 +933,82 @@ static int rename_netif(UdevEvent *event) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
- /* Set ID_RENAMING boolean property here. It will be dropped when the corresponding move uevent is processed. */
|
||||||
|
- r = device_add_property(dev, "ID_RENAMING", "1");
|
||||||
|
+ r = sd_device_get_sysname(dev, &s);
|
||||||
|
if (r < 0)
|
||||||
|
- return log_device_warning_errno(dev, r, "Failed to add 'ID_RENAMING' property: %m");
|
||||||
|
+ return log_device_warning_errno(dev, r, "Failed to get sysname: %m");
|
||||||
|
|
||||||
|
- r = device_rename(dev, event->name);
|
||||||
|
+ if (streq(event->name, s))
|
||||||
|
+ return 0; /* The interface name is already requested name. */
|
||||||
|
+
|
||||||
|
+ old_sysname = strdup(s);
|
||||||
|
+ if (!old_sysname)
|
||||||
|
+ return -ENOMEM;
|
||||||
|
+
|
||||||
|
+ r = sd_device_get_syspath(dev, &s);
|
||||||
|
if (r < 0)
|
||||||
|
- return log_device_warning_errno(dev, r, "Failed to update properties with new name '%s': %m", event->name);
|
||||||
|
+ return log_device_warning_errno(dev, r, "Failed to get syspath: %m");
|
||||||
|
+
|
||||||
|
+ old_syspath = strdup(s);
|
||||||
|
+ if (!old_syspath)
|
||||||
|
+ return -ENOMEM;
|
||||||
|
+
|
||||||
|
+ r = device_rename(dev, event->name);
|
||||||
|
+ if (r < 0) {
|
||||||
|
+ log_device_warning_errno(dev, r, "Failed to update properties with new name '%s': %m", event->name);
|
||||||
|
+ goto revert;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ /* Set ID_RENAMING boolean property here. It will be dropped when the corresponding move uevent is processed. */
|
||||||
|
+ r = device_add_property(dev, "ID_RENAMING", "1");
|
||||||
|
+ if (r < 0) {
|
||||||
|
+ log_device_warning_errno(dev, r, "Failed to add 'ID_RENAMING' property: %m");
|
||||||
|
+ goto revert;
|
||||||
|
+ }
|
||||||
|
|
||||||
|
/* Also set ID_RENAMING boolean property to cloned sd_device object and save it to database
|
||||||
|
* before calling rtnl_set_link_name(). Otherwise, clients (e.g., systemd-networkd) may receive
|
||||||
|
* RTM_NEWLINK netlink message before the database is updated. */
|
||||||
|
r = device_add_property(event->dev_db_clone, "ID_RENAMING", "1");
|
||||||
|
- if (r < 0)
|
||||||
|
- return log_device_warning_errno(event->dev_db_clone, r, "Failed to add 'ID_RENAMING' property: %m");
|
||||||
|
+ if (r < 0) {
|
||||||
|
+ log_device_warning_errno(event->dev_db_clone, r, "Failed to add 'ID_RENAMING' property: %m");
|
||||||
|
+ goto revert;
|
||||||
|
+ }
|
||||||
|
|
||||||
|
r = device_update_db(event->dev_db_clone);
|
||||||
|
- if (r < 0)
|
||||||
|
- return log_device_debug_errno(event->dev_db_clone, r, "Failed to update database under /run/udev/data/: %m");
|
||||||
|
+ if (r < 0) {
|
||||||
|
+ log_device_debug_errno(event->dev_db_clone, r, "Failed to update database under /run/udev/data/: %m");
|
||||||
|
+ goto revert;
|
||||||
|
+ }
|
||||||
|
|
||||||
|
r = rtnl_set_link_name(&event->rtnl, ifindex, event->name);
|
||||||
|
- if (r == -EBUSY) {
|
||||||
|
- log_device_info(dev, "Network interface '%s' is already up, cannot rename to '%s'.",
|
||||||
|
- oldname, event->name);
|
||||||
|
- return 0;
|
||||||
|
+ if (r < 0) {
|
||||||
|
+ if (r == -EBUSY) {
|
||||||
|
+ log_device_info(dev, "Network interface '%s' is already up, cannot rename to '%s'.",
|
||||||
|
+ old_sysname, event->name);
|
||||||
|
+ r = 0;
|
||||||
|
+ } else
|
||||||
|
+ log_device_error_errno(dev, r, "Failed to rename network interface %i from '%s' to '%s': %m",
|
||||||
|
+ ifindex, old_sysname, event->name);
|
||||||
|
+ goto revert;
|
||||||
|
}
|
||||||
|
- if (r < 0)
|
||||||
|
- return log_device_error_errno(dev, r, "Failed to rename network interface %i from '%s' to '%s': %m",
|
||||||
|
- ifindex, oldname, event->name);
|
||||||
|
-
|
||||||
|
- log_device_debug(dev, "Network interface %i is renamed from '%s' to '%s'", ifindex, oldname, event->name);
|
||||||
|
|
||||||
|
+ log_device_debug(dev, "Network interface %i is renamed from '%s' to '%s'", ifindex, old_sysname, event->name);
|
||||||
|
return 1;
|
||||||
|
+
|
||||||
|
+revert:
|
||||||
|
+ /* Restore 'dev_db_clone' */
|
||||||
|
+ (void) device_add_property(event->dev_db_clone, "ID_RENAMING", NULL);
|
||||||
|
+ (void) device_update_db(event->dev_db_clone);
|
||||||
|
+
|
||||||
|
+ /* Restore 'dev' */
|
||||||
|
+ (void) device_set_syspath(dev, old_syspath, /* verify = */ false);
|
||||||
|
+ if (sd_device_get_property_value(dev, "INTERFACE_OLD", &s) >= 0) {
|
||||||
|
+ (void) device_add_property_internal(dev, "INTERFACE", s);
|
||||||
|
+ (void) device_add_property_internal(dev, "INTERFACE_OLD", NULL);
|
||||||
|
+ }
|
||||||
|
+ (void) device_add_property(dev, "ID_RENAMING", NULL);
|
||||||
|
+
|
||||||
|
+ return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int update_devnode(UdevEvent *event) {
|
@ -0,0 +1,56 @@
|
|||||||
|
From 284d6f9171ba819bcccb6a2df7c3012ba8483a0c Mon Sep 17 00:00:00 2001
|
||||||
|
From: Yu Watanabe <watanabe.yu+github@gmail.com>
|
||||||
|
Date: Mon, 9 Jan 2023 16:44:11 +0900
|
||||||
|
Subject: [PATCH] sd-device: introduce device_get_property_int()
|
||||||
|
|
||||||
|
(cherry picked from commit eedfef0f0d2654fcde2a3b694e62518d688af827)
|
||||||
|
|
||||||
|
Related: RHEL-5988
|
||||||
|
---
|
||||||
|
src/libsystemd/sd-device/device-private.h | 1 +
|
||||||
|
src/libsystemd/sd-device/sd-device.c | 20 ++++++++++++++++++++
|
||||||
|
2 files changed, 21 insertions(+)
|
||||||
|
|
||||||
|
diff --git a/src/libsystemd/sd-device/device-private.h b/src/libsystemd/sd-device/device-private.h
|
||||||
|
index e57b74ba24..d9a519a4d9 100644
|
||||||
|
--- a/src/libsystemd/sd-device/device-private.h
|
||||||
|
+++ b/src/libsystemd/sd-device/device-private.h
|
||||||
|
@@ -18,6 +18,7 @@ int device_new_from_strv(sd_device **ret, char **strv);
|
||||||
|
int device_opendir(sd_device *device, const char *subdir, DIR **ret);
|
||||||
|
|
||||||
|
int device_get_property_bool(sd_device *device, const char *key);
|
||||||
|
+int device_get_property_int(sd_device *device, const char *key, int *ret);
|
||||||
|
int device_get_sysattr_int(sd_device *device, const char *sysattr, int *ret_value);
|
||||||
|
int device_get_sysattr_unsigned(sd_device *device, const char *sysattr, unsigned *ret_value);
|
||||||
|
int device_get_sysattr_bool(sd_device *device, const char *sysattr);
|
||||||
|
diff --git a/src/libsystemd/sd-device/sd-device.c b/src/libsystemd/sd-device/sd-device.c
|
||||||
|
index c822a0b2f0..7ee67b4641 100644
|
||||||
|
--- a/src/libsystemd/sd-device/sd-device.c
|
||||||
|
+++ b/src/libsystemd/sd-device/sd-device.c
|
||||||
|
@@ -2186,6 +2186,26 @@ int device_get_property_bool(sd_device *device, const char *key) {
|
||||||
|
return parse_boolean(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
+int device_get_property_int(sd_device *device, const char *key, int *ret) {
|
||||||
|
+ const char *value;
|
||||||
|
+ int r, v;
|
||||||
|
+
|
||||||
|
+ assert(device);
|
||||||
|
+ assert(key);
|
||||||
|
+
|
||||||
|
+ r = sd_device_get_property_value(device, key, &value);
|
||||||
|
+ if (r < 0)
|
||||||
|
+ return r;
|
||||||
|
+
|
||||||
|
+ r = safe_atoi(value, &v);
|
||||||
|
+ if (r < 0)
|
||||||
|
+ return r;
|
||||||
|
+
|
||||||
|
+ if (ret)
|
||||||
|
+ *ret = v;
|
||||||
|
+ return 0;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
_public_ int sd_device_get_trigger_uuid(sd_device *device, sd_id128_t *ret) {
|
||||||
|
const char *s;
|
||||||
|
sd_id128_t id;
|
@ -0,0 +1,32 @@
|
|||||||
|
From 42a11f89c8836493847a69906ef2765e2e984dbf Mon Sep 17 00:00:00 2001
|
||||||
|
From: Yu Watanabe <watanabe.yu+github@gmail.com>
|
||||||
|
Date: Mon, 9 Jan 2023 16:11:04 +0900
|
||||||
|
Subject: [PATCH] core/device: downgrade log level for ignored errors
|
||||||
|
|
||||||
|
(cherry picked from commit 58b0a3e5112a27daa181383458f68955eb081551)
|
||||||
|
|
||||||
|
Related: RHEL-5988
|
||||||
|
---
|
||||||
|
src/core/device.c | 4 ++--
|
||||||
|
1 file changed, 2 insertions(+), 2 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/src/core/device.c b/src/core/device.c
|
||||||
|
index 224fc90835..09b7d56e1e 100644
|
||||||
|
--- a/src/core/device.c
|
||||||
|
+++ b/src/core/device.c
|
||||||
|
@@ -1095,13 +1095,13 @@ static int device_dispatch_io(sd_device_monitor *monitor, sd_device *dev, void *
|
||||||
|
|
||||||
|
r = sd_device_get_syspath(dev, &sysfs);
|
||||||
|
if (r < 0) {
|
||||||
|
- log_device_error_errno(dev, r, "Failed to get device syspath, ignoring: %m");
|
||||||
|
+ log_device_warning_errno(dev, r, "Failed to get device syspath, ignoring: %m");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
r = sd_device_get_action(dev, &action);
|
||||||
|
if (r < 0) {
|
||||||
|
- log_device_error_errno(dev, r, "Failed to get udev action, ignoring: %m");
|
||||||
|
+ log_device_warning_errno(dev, r, "Failed to get udev action, ignoring: %m");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,45 @@
|
|||||||
|
From b59fda96b0e24b93dcdb061da24c42a924ae0b20 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Yu Watanabe <watanabe.yu+github@gmail.com>
|
||||||
|
Date: Mon, 9 Jan 2023 16:11:52 +0900
|
||||||
|
Subject: [PATCH] core/device: ignore failed uevents
|
||||||
|
|
||||||
|
When udevd failed to process the device, SYSTEMD_ALIAS or any other
|
||||||
|
properties may contain invalid values. Let's refuse to handle the uevent.
|
||||||
|
|
||||||
|
(cherry picked from commit e9336d6ac346df38d96c91ba0447b3c76ee6697b)
|
||||||
|
|
||||||
|
Related: RHEL-5988
|
||||||
|
---
|
||||||
|
src/core/device.c | 19 +++++++++++++++++++
|
||||||
|
1 file changed, 19 insertions(+)
|
||||||
|
|
||||||
|
diff --git a/src/core/device.c b/src/core/device.c
|
||||||
|
index 09b7d56e1e..f007bdfd9b 100644
|
||||||
|
--- a/src/core/device.c
|
||||||
|
+++ b/src/core/device.c
|
||||||
|
@@ -1108,6 +1108,25 @@ static int device_dispatch_io(sd_device_monitor *monitor, sd_device *dev, void *
|
||||||
|
if (action == SD_DEVICE_MOVE)
|
||||||
|
device_remove_old_on_move(m, dev);
|
||||||
|
|
||||||
|
+ /* When udevd failed to process the device, SYSTEMD_ALIAS or any other properties may contain invalid
|
||||||
|
+ * values. Let's refuse to handle the uevent. */
|
||||||
|
+ if (sd_device_get_property_value(dev, "UDEV_WORKER_FAILED", NULL) >= 0) {
|
||||||
|
+ int v;
|
||||||
|
+
|
||||||
|
+ if (device_get_property_int(dev, "UDEV_WORKER_ERRNO", &v) >= 0)
|
||||||
|
+ log_device_warning_errno(dev, v, "systemd-udevd failed to process the device, ignoring: %m");
|
||||||
|
+ else if (device_get_property_int(dev, "UDEV_WORKER_EXIT_STATUS", &v) >= 0)
|
||||||
|
+ log_device_warning(dev, "systemd-udevd failed to process the device with exit status %i, ignoring.", v);
|
||||||
|
+ else if (device_get_property_int(dev, "UDEV_WORKER_SIGNAL", &v) >= 0) {
|
||||||
|
+ const char *s;
|
||||||
|
+ (void) sd_device_get_property_value(dev, "UDEV_WORKER_SIGNAL_NAME", &s);
|
||||||
|
+ log_device_warning(dev, "systemd-udevd failed to process the device with signal %i(%s), ignoring.", v, strna(s));
|
||||||
|
+ } else
|
||||||
|
+ log_device_warning(dev, "systemd-udevd failed to process the device with unknown result, ignoring.");
|
||||||
|
+
|
||||||
|
+ return 0;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
/* A change event can signal that a device is becoming ready, in particular if the device is using
|
||||||
|
* the SYSTEMD_READY logic in udev so we need to reach the else block of the following if, even for
|
||||||
|
* change events */
|
@ -0,0 +1,99 @@
|
|||||||
|
From 9e9f53612dc2356796cffb25826008944aede0e3 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Yu Watanabe <watanabe.yu+github@gmail.com>
|
||||||
|
Date: Mon, 9 Jan 2023 16:02:09 +0900
|
||||||
|
Subject: [PATCH] test: add tests for failure in renaming network interface
|
||||||
|
|
||||||
|
(cherry picked from commit 2d0d75b279924934c4c8e9acbc48456b01b71f00)
|
||||||
|
|
||||||
|
Related: RHEL-5988
|
||||||
|
---
|
||||||
|
test/units/testsuite-17.02.sh | 78 +++++++++++++++++++++++++++++++++++
|
||||||
|
1 file changed, 78 insertions(+)
|
||||||
|
|
||||||
|
diff --git a/test/units/testsuite-17.02.sh b/test/units/testsuite-17.02.sh
|
||||||
|
index 7abbce7747..ed3b39d074 100755
|
||||||
|
--- a/test/units/testsuite-17.02.sh
|
||||||
|
+++ b/test/units/testsuite-17.02.sh
|
||||||
|
@@ -102,4 +102,82 @@ timeout 30 bash -c 'while [[ "$(systemctl show --property=ActiveState --value /s
|
||||||
|
# cleanup
|
||||||
|
ip link del hoge
|
||||||
|
|
||||||
|
+teardown_netif_renaming_conflict() {
|
||||||
|
+ set +ex
|
||||||
|
+
|
||||||
|
+ if [[ -n "$KILL_PID" ]]; then
|
||||||
|
+ kill "$KILL_PID"
|
||||||
|
+ fi
|
||||||
|
+
|
||||||
|
+ rm -rf "$TMPDIR"
|
||||||
|
+
|
||||||
|
+ rm -f /run/udev/rules.d/50-testsuite.rules
|
||||||
|
+ udevadm control --reload --timeout=30
|
||||||
|
+
|
||||||
|
+ ip link del hoge
|
||||||
|
+ ip link del foobar
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+test_netif_renaming_conflict() {
|
||||||
|
+ local since found=
|
||||||
|
+
|
||||||
|
+ trap teardown_netif_renaming_conflict RETURN
|
||||||
|
+
|
||||||
|
+ cat >/run/udev/rules.d/50-testsuite.rules <<EOF
|
||||||
|
+ACTION!="add", GOTO="hoge_end"
|
||||||
|
+SUBSYSTEM!="net", GOTO="hoge_end"
|
||||||
|
+
|
||||||
|
+OPTIONS="log_level=debug"
|
||||||
|
+
|
||||||
|
+KERNEL=="foobar", NAME="hoge"
|
||||||
|
+
|
||||||
|
+LABEL="hoge_end"
|
||||||
|
+EOF
|
||||||
|
+
|
||||||
|
+ udevadm control --log-priority=debug --reload --timeout=30
|
||||||
|
+
|
||||||
|
+ ip link add hoge type dummy
|
||||||
|
+ udevadm wait --timeout=30 --settle /sys/devices/virtual/net/hoge
|
||||||
|
+
|
||||||
|
+ TMPDIR=$(mktemp -d -p /tmp udev-tests.XXXXXX)
|
||||||
|
+ udevadm monitor --udev --property --subsystem-match=net >"$TMPDIR"/monitor.txt &
|
||||||
|
+ KILL_PID="$!"
|
||||||
|
+
|
||||||
|
+ # make sure that 'udevadm monitor' actually monitor uevents
|
||||||
|
+ sleep 1
|
||||||
|
+
|
||||||
|
+ since="$(date '+%H:%M:%S')"
|
||||||
|
+
|
||||||
|
+ # add another interface which will conflict with an existing interface
|
||||||
|
+ ip link add foobar type dummy
|
||||||
|
+
|
||||||
|
+ for _ in {1..40}; do
|
||||||
|
+ if (
|
||||||
|
+ grep -q 'ACTION=add' "$TMPDIR"/monitor.txt
|
||||||
|
+ grep -q 'DEVPATH=/devices/virtual/net/foobar' "$TMPDIR"/monitor.txt
|
||||||
|
+ grep -q 'SUBSYSTEM=net' "$TMPDIR"/monitor.txt
|
||||||
|
+ grep -q 'INTERFACE=foobar' "$TMPDIR"/monitor.txt
|
||||||
|
+ grep -q 'ID_NET_DRIVER=dummy' "$TMPDIR"/monitor.txt
|
||||||
|
+ grep -q 'ID_NET_NAME=foobar' "$TMPDIR"/monitor.txt
|
||||||
|
+ # Even when network interface renaming is failed, SYSTEMD_ALIAS with the conflicting name will be broadcast.
|
||||||
|
+ grep -q 'SYSTEMD_ALIAS=/sys/subsystem/net/devices/hoge' "$TMPDIR"/monitor.txt
|
||||||
|
+ grep -q 'UDEV_WORKER_FAILED=1' "$TMPDIR"/monitor.txt
|
||||||
|
+ grep -q 'UDEV_WORKER_ERRNO=17' "$TMPDIR"/monitor.txt
|
||||||
|
+ grep -q 'UDEV_WORKER_ERRNO_NAME=EEXIST' "$TMPDIR"/monitor.txt
|
||||||
|
+ ); then
|
||||||
|
+ cat "$TMPDIR"/monitor.txt
|
||||||
|
+ found=1
|
||||||
|
+ break
|
||||||
|
+ fi
|
||||||
|
+ sleep .5
|
||||||
|
+ done
|
||||||
|
+ test -n "$found"
|
||||||
|
+
|
||||||
|
+ timeout 30 bash -c "while ! journalctl _PID=1 _COMM=systemd --since $since | grep -q 'foobar: systemd-udevd failed to process the device, ignoring: File exists'; do sleep 1; done"
|
||||||
|
+ # check if the invalid SYSTEMD_ALIAS property for the interface foobar is ignored by PID1
|
||||||
|
+ assert_eq "$(systemctl show --property=SysFSPath --value /sys/subsystem/net/devices/hoge)" "/sys/devices/virtual/net/hoge"
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+test_netif_renaming_conflict
|
||||||
|
+
|
||||||
|
exit 0
|
@ -0,0 +1,623 @@
|
|||||||
|
From a3c14074e6cd91053ffafb0eb4b16054564e4239 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Yu Watanabe <watanabe.yu+github@gmail.com>
|
||||||
|
Date: Mon, 9 Jan 2023 20:33:35 +0900
|
||||||
|
Subject: [PATCH] test: modernize test-netlink.c
|
||||||
|
|
||||||
|
(cherry picked from commit eafff21da2978bfa4c5c4171a595abaeb1d170dc)
|
||||||
|
|
||||||
|
Related: RHEL-5988
|
||||||
|
---
|
||||||
|
src/libsystemd/sd-netlink/test-netlink.c | 362 ++++++++---------------
|
||||||
|
1 file changed, 116 insertions(+), 246 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/src/libsystemd/sd-netlink/test-netlink.c b/src/libsystemd/sd-netlink/test-netlink.c
|
||||||
|
index 2d93f9eba0..f740035639 100644
|
||||||
|
--- a/src/libsystemd/sd-netlink/test-netlink.c
|
||||||
|
+++ b/src/libsystemd/sd-netlink/test-netlink.c
|
||||||
|
@@ -24,11 +24,12 @@
|
||||||
|
#include "strv.h"
|
||||||
|
#include "tests.h"
|
||||||
|
|
||||||
|
-static void test_message_link_bridge(sd_netlink *rtnl) {
|
||||||
|
+TEST(message_newlink_bridge) {
|
||||||
|
+ _cleanup_(sd_netlink_unrefp) sd_netlink *rtnl = NULL;
|
||||||
|
_cleanup_(sd_netlink_message_unrefp) sd_netlink_message *message = NULL;
|
||||||
|
uint32_t cost;
|
||||||
|
|
||||||
|
- log_debug("/* %s */", __func__);
|
||||||
|
+ assert_se(sd_netlink_open(&rtnl) >= 0);
|
||||||
|
|
||||||
|
assert_se(sd_rtnl_message_new_link(rtnl, &message, RTM_NEWLINK, 1) >= 0);
|
||||||
|
assert_se(sd_rtnl_message_link_set_family(message, AF_BRIDGE) >= 0);
|
||||||
|
@@ -44,99 +45,81 @@ static void test_message_link_bridge(sd_netlink *rtnl) {
|
||||||
|
assert_se(sd_netlink_message_exit_container(message) >= 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
-static void test_link_configure(sd_netlink *rtnl, int ifindex) {
|
||||||
|
+TEST(message_getlink) {
|
||||||
|
+ _cleanup_(sd_netlink_unrefp) sd_netlink *rtnl = NULL;
|
||||||
|
_cleanup_(sd_netlink_message_unrefp) sd_netlink_message *message = NULL, *reply = NULL;
|
||||||
|
- uint32_t mtu_out;
|
||||||
|
- const char *name_out;
|
||||||
|
- struct ether_addr mac_out;
|
||||||
|
-
|
||||||
|
- log_debug("/* %s */", __func__);
|
||||||
|
-
|
||||||
|
- /* we'd really like to test NEWLINK, but let's not mess with the running kernel */
|
||||||
|
- assert_se(sd_rtnl_message_new_link(rtnl, &message, RTM_GETLINK, ifindex) >= 0);
|
||||||
|
-
|
||||||
|
- assert_se(sd_netlink_call(rtnl, message, 0, &reply) == 1);
|
||||||
|
-
|
||||||
|
- assert_se(sd_netlink_message_read_string(reply, IFLA_IFNAME, &name_out) >= 0);
|
||||||
|
- assert_se(sd_netlink_message_read_ether_addr(reply, IFLA_ADDRESS, &mac_out) >= 0);
|
||||||
|
- assert_se(sd_netlink_message_read_u32(reply, IFLA_MTU, &mtu_out) >= 0);
|
||||||
|
-}
|
||||||
|
-
|
||||||
|
-static void test_link_get(sd_netlink *rtnl, int ifindex) {
|
||||||
|
- _cleanup_(sd_netlink_message_unrefp) sd_netlink_message *m = NULL, *r = NULL;
|
||||||
|
- const char *str_data;
|
||||||
|
+ int ifindex;
|
||||||
|
uint8_t u8_data;
|
||||||
|
+ uint16_t u16_data;
|
||||||
|
uint32_t u32_data;
|
||||||
|
+ const char *str_data;
|
||||||
|
struct ether_addr eth_data;
|
||||||
|
|
||||||
|
- log_debug("/* %s */", __func__);
|
||||||
|
+ assert_se(sd_netlink_open(&rtnl) >= 0);
|
||||||
|
+ ifindex = (int) if_nametoindex("lo");
|
||||||
|
|
||||||
|
- assert_se(sd_rtnl_message_new_link(rtnl, &m, RTM_GETLINK, ifindex) >= 0);
|
||||||
|
- assert_se(m);
|
||||||
|
+ /* we'd really like to test NEWLINK, but let's not mess with the running kernel */
|
||||||
|
+ assert_se(sd_rtnl_message_new_link(rtnl, &message, RTM_GETLINK, ifindex) >= 0);
|
||||||
|
+ assert_se(sd_netlink_call(rtnl, message, 0, &reply) == 1);
|
||||||
|
|
||||||
|
- assert_se(sd_netlink_call(rtnl, m, 0, &r) == 1);
|
||||||
|
+ /* u8 */
|
||||||
|
+ assert_se(sd_netlink_message_read_u8(reply, IFLA_CARRIER, &u8_data) >= 0);
|
||||||
|
+ assert_se(sd_netlink_message_read_u8(reply, IFLA_OPERSTATE, &u8_data) >= 0);
|
||||||
|
+ assert_se(sd_netlink_message_read_u8(reply, IFLA_LINKMODE, &u8_data) >= 0);
|
||||||
|
|
||||||
|
- assert_se(sd_netlink_message_read_string(r, IFLA_IFNAME, &str_data) == 0);
|
||||||
|
+ /* u16 */
|
||||||
|
+ assert_se(sd_netlink_message_get_type(reply, &u16_data) >= 0);
|
||||||
|
+ assert_se(u16_data == RTM_NEWLINK);
|
||||||
|
|
||||||
|
- assert_se(sd_netlink_message_read_u8(r, IFLA_CARRIER, &u8_data) == 0);
|
||||||
|
- assert_se(sd_netlink_message_read_u8(r, IFLA_OPERSTATE, &u8_data) == 0);
|
||||||
|
- assert_se(sd_netlink_message_read_u8(r, IFLA_LINKMODE, &u8_data) == 0);
|
||||||
|
+ /* u32 */
|
||||||
|
+ assert_se(sd_netlink_message_read_u32(reply, IFLA_MTU, &u32_data) >= 0);
|
||||||
|
+ assert_se(sd_netlink_message_read_u32(reply, IFLA_GROUP, &u32_data) >= 0);
|
||||||
|
+ assert_se(sd_netlink_message_read_u32(reply, IFLA_TXQLEN, &u32_data) >= 0);
|
||||||
|
+ assert_se(sd_netlink_message_read_u32(reply, IFLA_NUM_TX_QUEUES, &u32_data) >= 0);
|
||||||
|
+ assert_se(sd_netlink_message_read_u32(reply, IFLA_NUM_RX_QUEUES, &u32_data) >= 0);
|
||||||
|
|
||||||
|
- assert_se(sd_netlink_message_read_u32(r, IFLA_MTU, &u32_data) == 0);
|
||||||
|
- assert_se(sd_netlink_message_read_u32(r, IFLA_GROUP, &u32_data) == 0);
|
||||||
|
- assert_se(sd_netlink_message_read_u32(r, IFLA_TXQLEN, &u32_data) == 0);
|
||||||
|
- assert_se(sd_netlink_message_read_u32(r, IFLA_NUM_TX_QUEUES, &u32_data) == 0);
|
||||||
|
- assert_se(sd_netlink_message_read_u32(r, IFLA_NUM_RX_QUEUES, &u32_data) == 0);
|
||||||
|
+ /* string */
|
||||||
|
+ assert_se(sd_netlink_message_read_string(reply, IFLA_IFNAME, &str_data) >= 0);
|
||||||
|
|
||||||
|
- assert_se(sd_netlink_message_read_ether_addr(r, IFLA_ADDRESS, ð_data) == 0);
|
||||||
|
+ /* ether_addr */
|
||||||
|
+ assert_se(sd_netlink_message_read_ether_addr(reply, IFLA_ADDRESS, ð_data) >= 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
-static void test_address_get(sd_netlink *rtnl, int ifindex) {
|
||||||
|
- _cleanup_(sd_netlink_message_unrefp) sd_netlink_message *m = NULL, *r = NULL;
|
||||||
|
+TEST(message_address) {
|
||||||
|
+ _cleanup_(sd_netlink_unrefp) sd_netlink *rtnl = NULL;
|
||||||
|
+ _cleanup_(sd_netlink_message_unrefp) sd_netlink_message *message = NULL, *reply = NULL;
|
||||||
|
+ int ifindex;
|
||||||
|
struct in_addr in_data;
|
||||||
|
struct ifa_cacheinfo cache;
|
||||||
|
const char *label;
|
||||||
|
|
||||||
|
- log_debug("/* %s */", __func__);
|
||||||
|
+ assert_se(sd_netlink_open(&rtnl) >= 0);
|
||||||
|
+ ifindex = (int) if_nametoindex("lo");
|
||||||
|
|
||||||
|
- assert_se(sd_rtnl_message_new_addr(rtnl, &m, RTM_GETADDR, ifindex, AF_INET) >= 0);
|
||||||
|
- assert_se(m);
|
||||||
|
- assert_se(sd_netlink_message_set_request_dump(m, true) >= 0);
|
||||||
|
- assert_se(sd_netlink_call(rtnl, m, -1, &r) == 1);
|
||||||
|
+ assert_se(sd_rtnl_message_new_addr(rtnl, &message, RTM_GETADDR, ifindex, AF_INET) >= 0);
|
||||||
|
+ assert_se(sd_netlink_message_set_request_dump(message, true) >= 0);
|
||||||
|
+ assert_se(sd_netlink_call(rtnl, message, 0, &reply) == 1);
|
||||||
|
|
||||||
|
- assert_se(sd_netlink_message_read_in_addr(r, IFA_LOCAL, &in_data) == 0);
|
||||||
|
- assert_se(sd_netlink_message_read_in_addr(r, IFA_ADDRESS, &in_data) == 0);
|
||||||
|
- assert_se(sd_netlink_message_read_string(r, IFA_LABEL, &label) == 0);
|
||||||
|
- assert_se(sd_netlink_message_read_cache_info(r, IFA_CACHEINFO, &cache) == 0);
|
||||||
|
+ assert_se(sd_netlink_message_read_in_addr(reply, IFA_LOCAL, &in_data) >= 0);
|
||||||
|
+ assert_se(sd_netlink_message_read_in_addr(reply, IFA_ADDRESS, &in_data) >= 0);
|
||||||
|
+ assert_se(sd_netlink_message_read_string(reply, IFA_LABEL, &label) >= 0);
|
||||||
|
+ assert_se(sd_netlink_message_read_cache_info(reply, IFA_CACHEINFO, &cache) == 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
-static void test_route(sd_netlink *rtnl) {
|
||||||
|
+TEST(message_route) {
|
||||||
|
+ _cleanup_(sd_netlink_unrefp) sd_netlink *rtnl = NULL;
|
||||||
|
_cleanup_(sd_netlink_message_unrefp) sd_netlink_message *req = NULL;
|
||||||
|
struct in_addr addr, addr_data;
|
||||||
|
uint32_t index = 2, u32_data;
|
||||||
|
- int r;
|
||||||
|
|
||||||
|
- log_debug("/* %s */", __func__);
|
||||||
|
+ assert_se(sd_netlink_open(&rtnl) >= 0);
|
||||||
|
|
||||||
|
- r = sd_rtnl_message_new_route(rtnl, &req, RTM_NEWROUTE, AF_INET, RTPROT_STATIC);
|
||||||
|
- if (r < 0) {
|
||||||
|
- log_error_errno(r, "Could not create RTM_NEWROUTE message: %m");
|
||||||
|
- return;
|
||||||
|
- }
|
||||||
|
+ assert_se(sd_rtnl_message_new_route(rtnl, &req, RTM_NEWROUTE, AF_INET, RTPROT_STATIC) >= 0);
|
||||||
|
|
||||||
|
addr.s_addr = htobe32(INADDR_LOOPBACK);
|
||||||
|
|
||||||
|
- r = sd_netlink_message_append_in_addr(req, RTA_GATEWAY, &addr);
|
||||||
|
- if (r < 0) {
|
||||||
|
- log_error_errno(r, "Could not append RTA_GATEWAY attribute: %m");
|
||||||
|
- return;
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- r = sd_netlink_message_append_u32(req, RTA_OIF, index);
|
||||||
|
- if (r < 0) {
|
||||||
|
- log_error_errno(r, "Could not append RTA_OIF attribute: %m");
|
||||||
|
- return;
|
||||||
|
- }
|
||||||
|
+ assert_se(sd_netlink_message_append_in_addr(req, RTA_GATEWAY, &addr) >= 0);
|
||||||
|
+ assert_se(sd_netlink_message_append_u32(req, RTA_OIF, index) >= 0);
|
||||||
|
|
||||||
|
assert_se(sd_netlink_message_rewind(req, rtnl) >= 0);
|
||||||
|
|
||||||
|
@@ -149,135 +132,94 @@ static void test_route(sd_netlink *rtnl) {
|
||||||
|
assert_se((req = sd_netlink_message_unref(req)) == NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
-static void test_multiple(void) {
|
||||||
|
- sd_netlink *rtnl1, *rtnl2;
|
||||||
|
-
|
||||||
|
- log_debug("/* %s */", __func__);
|
||||||
|
-
|
||||||
|
- assert_se(sd_netlink_open(&rtnl1) >= 0);
|
||||||
|
- assert_se(sd_netlink_open(&rtnl2) >= 0);
|
||||||
|
-
|
||||||
|
- rtnl1 = sd_netlink_unref(rtnl1);
|
||||||
|
- rtnl2 = sd_netlink_unref(rtnl2);
|
||||||
|
-}
|
||||||
|
-
|
||||||
|
static int link_handler(sd_netlink *rtnl, sd_netlink_message *m, void *userdata) {
|
||||||
|
- char *ifname = userdata;
|
||||||
|
const char *data;
|
||||||
|
|
||||||
|
assert_se(rtnl);
|
||||||
|
assert_se(m);
|
||||||
|
- assert_se(userdata);
|
||||||
|
|
||||||
|
- log_info("%s: got link info about %s", __func__, ifname);
|
||||||
|
- free(ifname);
|
||||||
|
+ assert_se(streq_ptr(userdata, "foo"));
|
||||||
|
|
||||||
|
assert_se(sd_netlink_message_read_string(m, IFLA_IFNAME, &data) >= 0);
|
||||||
|
assert_se(streq(data, "lo"));
|
||||||
|
|
||||||
|
+ log_info("%s: got link info about %s", __func__, data);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
-static void test_event_loop(int ifindex) {
|
||||||
|
+TEST(netlink_event_loop) {
|
||||||
|
_cleanup_(sd_event_unrefp) sd_event *event = NULL;
|
||||||
|
_cleanup_(sd_netlink_unrefp) sd_netlink *rtnl = NULL;
|
||||||
|
_cleanup_(sd_netlink_message_unrefp) sd_netlink_message *m = NULL;
|
||||||
|
- char *ifname;
|
||||||
|
-
|
||||||
|
- log_debug("/* %s */", __func__);
|
||||||
|
-
|
||||||
|
- ifname = strdup("lo2");
|
||||||
|
- assert_se(ifname);
|
||||||
|
+ _cleanup_free_ char *userdata = NULL;
|
||||||
|
+ int ifindex;
|
||||||
|
|
||||||
|
assert_se(sd_netlink_open(&rtnl) >= 0);
|
||||||
|
- assert_se(sd_rtnl_message_new_link(rtnl, &m, RTM_GETLINK, ifindex) >= 0);
|
||||||
|
+ ifindex = (int) if_nametoindex("lo");
|
||||||
|
|
||||||
|
- assert_se(sd_netlink_call_async(rtnl, NULL, m, link_handler, NULL, ifname, 0, NULL) >= 0);
|
||||||
|
+ assert_se(userdata = strdup("foo"));
|
||||||
|
|
||||||
|
assert_se(sd_event_default(&event) >= 0);
|
||||||
|
-
|
||||||
|
assert_se(sd_netlink_attach_event(rtnl, event, 0) >= 0);
|
||||||
|
|
||||||
|
+ assert_se(sd_rtnl_message_new_link(rtnl, &m, RTM_GETLINK, ifindex) >= 0);
|
||||||
|
+ assert_se(sd_netlink_call_async(rtnl, NULL, m, link_handler, NULL, userdata, 0, NULL) >= 0);
|
||||||
|
+
|
||||||
|
assert_se(sd_event_run(event, 0) >= 0);
|
||||||
|
|
||||||
|
assert_se(sd_netlink_detach_event(rtnl) >= 0);
|
||||||
|
-
|
||||||
|
assert_se((rtnl = sd_netlink_unref(rtnl)) == NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void test_async_destroy(void *userdata) {
|
||||||
|
}
|
||||||
|
|
||||||
|
-static void test_async(int ifindex) {
|
||||||
|
+TEST(netlink_call_async) {
|
||||||
|
_cleanup_(sd_netlink_unrefp) sd_netlink *rtnl = NULL;
|
||||||
|
- _cleanup_(sd_netlink_message_unrefp) sd_netlink_message *m = NULL, *r = NULL;
|
||||||
|
+ _cleanup_(sd_netlink_message_unrefp) sd_netlink_message *m = NULL, *reply = NULL;
|
||||||
|
_cleanup_(sd_netlink_slot_unrefp) sd_netlink_slot *slot = NULL;
|
||||||
|
+ _cleanup_free_ char *userdata = NULL;
|
||||||
|
sd_netlink_destroy_t destroy_callback;
|
||||||
|
const char *description;
|
||||||
|
- char *ifname;
|
||||||
|
-
|
||||||
|
- log_debug("/* %s */", __func__);
|
||||||
|
-
|
||||||
|
- ifname = strdup("lo");
|
||||||
|
- assert_se(ifname);
|
||||||
|
+ int ifindex;
|
||||||
|
|
||||||
|
assert_se(sd_netlink_open(&rtnl) >= 0);
|
||||||
|
+ ifindex = (int) if_nametoindex("lo");
|
||||||
|
|
||||||
|
- assert_se(sd_rtnl_message_new_link(rtnl, &m, RTM_GETLINK, ifindex) >= 0);
|
||||||
|
+ assert_se(userdata = strdup("foo"));
|
||||||
|
|
||||||
|
- assert_se(sd_netlink_call_async(rtnl, &slot, m, link_handler, test_async_destroy, ifname, 0, "hogehoge") >= 0);
|
||||||
|
+ assert_se(sd_rtnl_message_new_link(rtnl, &m, RTM_GETLINK, ifindex) >= 0);
|
||||||
|
+ assert_se(sd_netlink_call_async(rtnl, &slot, m, link_handler, test_async_destroy, userdata, 0, "hogehoge") >= 0);
|
||||||
|
|
||||||
|
assert_se(sd_netlink_slot_get_netlink(slot) == rtnl);
|
||||||
|
- assert_se(sd_netlink_slot_get_userdata(slot) == ifname);
|
||||||
|
- assert_se(sd_netlink_slot_get_destroy_callback(slot, &destroy_callback) == 1);
|
||||||
|
- assert_se(destroy_callback == test_async_destroy);
|
||||||
|
- assert_se(sd_netlink_slot_get_floating(slot) == 0);
|
||||||
|
- assert_se(sd_netlink_slot_get_description(slot, &description) == 1);
|
||||||
|
- assert_se(streq(description, "hogehoge"));
|
||||||
|
-
|
||||||
|
- assert_se(sd_netlink_wait(rtnl, 0) >= 0);
|
||||||
|
- assert_se(sd_netlink_process(rtnl, &r) >= 0);
|
||||||
|
-
|
||||||
|
- assert_se((rtnl = sd_netlink_unref(rtnl)) == NULL);
|
||||||
|
-}
|
||||||
|
|
||||||
|
-static void test_slot_set(int ifindex) {
|
||||||
|
- _cleanup_(sd_netlink_unrefp) sd_netlink *rtnl = NULL;
|
||||||
|
- _cleanup_(sd_netlink_message_unrefp) sd_netlink_message *m = NULL, *r = NULL;
|
||||||
|
- _cleanup_(sd_netlink_slot_unrefp) sd_netlink_slot *slot = NULL;
|
||||||
|
- sd_netlink_destroy_t destroy_callback;
|
||||||
|
- const char *description;
|
||||||
|
- char *ifname;
|
||||||
|
-
|
||||||
|
- log_debug("/* %s */", __func__);
|
||||||
|
-
|
||||||
|
- ifname = strdup("lo");
|
||||||
|
- assert_se(ifname);
|
||||||
|
-
|
||||||
|
- assert_se(sd_netlink_open(&rtnl) >= 0);
|
||||||
|
-
|
||||||
|
- assert_se(sd_rtnl_message_new_link(rtnl, &m, RTM_GETLINK, ifindex) >= 0);
|
||||||
|
-
|
||||||
|
- assert_se(sd_netlink_call_async(rtnl, &slot, m, link_handler, NULL, NULL, 0, NULL) >= 0);
|
||||||
|
+ assert_se(sd_netlink_slot_get_userdata(slot) == userdata);
|
||||||
|
+ assert_se(sd_netlink_slot_set_userdata(slot, NULL) == userdata);
|
||||||
|
+ assert_se(sd_netlink_slot_get_userdata(slot) == NULL);
|
||||||
|
+ assert_se(sd_netlink_slot_set_userdata(slot, userdata) == NULL);
|
||||||
|
+ assert_se(sd_netlink_slot_get_userdata(slot) == userdata);
|
||||||
|
|
||||||
|
- assert_se(sd_netlink_slot_get_netlink(slot) == rtnl);
|
||||||
|
- assert_se(!sd_netlink_slot_get_userdata(slot));
|
||||||
|
- assert_se(!sd_netlink_slot_set_userdata(slot, ifname));
|
||||||
|
- assert_se(sd_netlink_slot_get_userdata(slot) == ifname);
|
||||||
|
- assert_se(sd_netlink_slot_get_destroy_callback(slot, NULL) == 0);
|
||||||
|
+ assert_se(sd_netlink_slot_get_destroy_callback(slot, &destroy_callback) == 1);
|
||||||
|
+ assert_se(destroy_callback == test_async_destroy);
|
||||||
|
+ assert_se(sd_netlink_slot_set_destroy_callback(slot, NULL) >= 0);
|
||||||
|
+ assert_se(sd_netlink_slot_get_destroy_callback(slot, &destroy_callback) == 0);
|
||||||
|
+ assert_se(destroy_callback == NULL);
|
||||||
|
assert_se(sd_netlink_slot_set_destroy_callback(slot, test_async_destroy) >= 0);
|
||||||
|
assert_se(sd_netlink_slot_get_destroy_callback(slot, &destroy_callback) == 1);
|
||||||
|
assert_se(destroy_callback == test_async_destroy);
|
||||||
|
+
|
||||||
|
assert_se(sd_netlink_slot_get_floating(slot) == 0);
|
||||||
|
assert_se(sd_netlink_slot_set_floating(slot, 1) == 1);
|
||||||
|
assert_se(sd_netlink_slot_get_floating(slot) == 1);
|
||||||
|
- assert_se(sd_netlink_slot_get_description(slot, NULL) == 0);
|
||||||
|
- assert_se(sd_netlink_slot_set_description(slot, "hogehoge") >= 0);
|
||||||
|
+
|
||||||
|
assert_se(sd_netlink_slot_get_description(slot, &description) == 1);
|
||||||
|
assert_se(streq(description, "hogehoge"));
|
||||||
|
+ assert_se(sd_netlink_slot_set_description(slot, NULL) >= 0);
|
||||||
|
+ assert_se(sd_netlink_slot_get_description(slot, &description) == 0);
|
||||||
|
+ assert_se(description == NULL);
|
||||||
|
|
||||||
|
assert_se(sd_netlink_wait(rtnl, 0) >= 0);
|
||||||
|
- assert_se(sd_netlink_process(rtnl, &r) >= 0);
|
||||||
|
+ assert_se(sd_netlink_process(rtnl, &reply) >= 0);
|
||||||
|
|
||||||
|
assert_se((rtnl = sd_netlink_unref(rtnl)) == NULL);
|
||||||
|
}
|
||||||
|
@@ -322,23 +264,21 @@ static void test_async_object_destroy(void *userdata) {
|
||||||
|
test_async_object_unref(t);
|
||||||
|
}
|
||||||
|
|
||||||
|
-static void test_async_destroy_callback(int ifindex) {
|
||||||
|
+TEST(async_destroy_callback) {
|
||||||
|
_cleanup_(sd_netlink_unrefp) sd_netlink *rtnl = NULL;
|
||||||
|
- _cleanup_(sd_netlink_message_unrefp) sd_netlink_message *m = NULL, *r = NULL;
|
||||||
|
+ _cleanup_(sd_netlink_message_unrefp) sd_netlink_message *m = NULL, *reply = NULL;
|
||||||
|
_cleanup_(test_async_object_unrefp) struct test_async_object *t = NULL;
|
||||||
|
_cleanup_(sd_netlink_slot_unrefp) sd_netlink_slot *slot = NULL;
|
||||||
|
- char *ifname;
|
||||||
|
+ int ifindex;
|
||||||
|
|
||||||
|
- log_debug("/* %s */", __func__);
|
||||||
|
+ assert_se(sd_netlink_open(&rtnl) >= 0);
|
||||||
|
+ ifindex = (int) if_nametoindex("lo");
|
||||||
|
|
||||||
|
assert_se(t = new(struct test_async_object, 1));
|
||||||
|
- assert_se(ifname = strdup("lo"));
|
||||||
|
*t = (struct test_async_object) {
|
||||||
|
.n_ref = 1,
|
||||||
|
- .ifname = ifname,
|
||||||
|
};
|
||||||
|
-
|
||||||
|
- assert_se(sd_netlink_open(&rtnl) >= 0);
|
||||||
|
+ assert_se(t->ifname = strdup("lo"));
|
||||||
|
|
||||||
|
/* destroy callback is called after processing message */
|
||||||
|
assert_se(sd_rtnl_message_new_link(rtnl, &m, RTM_GETLINK, ifindex) >= 0);
|
||||||
|
@@ -349,7 +289,7 @@ static void test_async_destroy_callback(int ifindex) {
|
||||||
|
assert_se(t->n_ref == 2);
|
||||||
|
|
||||||
|
assert_se(sd_netlink_wait(rtnl, 0) >= 0);
|
||||||
|
- assert_se(sd_netlink_process(rtnl, &r) == 1);
|
||||||
|
+ assert_se(sd_netlink_process(rtnl, &reply) == 1);
|
||||||
|
assert_se(t->n_ref == 1);
|
||||||
|
|
||||||
|
assert_se(!sd_netlink_message_unref(m));
|
||||||
|
@@ -394,14 +334,13 @@ static int pipe_handler(sd_netlink *rtnl, sd_netlink_message *m, void *userdata)
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
-static void test_pipe(int ifindex) {
|
||||||
|
+TEST(pipe) {
|
||||||
|
_cleanup_(sd_netlink_unrefp) sd_netlink *rtnl = NULL;
|
||||||
|
_cleanup_(sd_netlink_message_unrefp) sd_netlink_message *m1 = NULL, *m2 = NULL;
|
||||||
|
- int counter = 0;
|
||||||
|
-
|
||||||
|
- log_debug("/* %s */", __func__);
|
||||||
|
+ int ifindex, counter = 0;
|
||||||
|
|
||||||
|
assert_se(sd_netlink_open(&rtnl) >= 0);
|
||||||
|
+ ifindex = (int) if_nametoindex("lo");
|
||||||
|
|
||||||
|
assert_se(sd_rtnl_message_new_link(rtnl, &m1, RTM_GETLINK, ifindex) >= 0);
|
||||||
|
assert_se(sd_rtnl_message_new_link(rtnl, &m2, RTM_GETLINK, ifindex) >= 0);
|
||||||
|
@@ -420,13 +359,14 @@ static void test_pipe(int ifindex) {
|
||||||
|
assert_se((rtnl = sd_netlink_unref(rtnl)) == NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
-static void test_container(sd_netlink *rtnl) {
|
||||||
|
+TEST(message_container) {
|
||||||
|
+ _cleanup_(sd_netlink_unrefp) sd_netlink *rtnl = NULL;
|
||||||
|
_cleanup_(sd_netlink_message_unrefp) sd_netlink_message *m = NULL;
|
||||||
|
uint16_t u16_data;
|
||||||
|
uint32_t u32_data;
|
||||||
|
const char *string_data;
|
||||||
|
|
||||||
|
- log_debug("/* %s */", __func__);
|
||||||
|
+ assert_se(sd_netlink_open(&rtnl) >= 0);
|
||||||
|
|
||||||
|
assert_se(sd_rtnl_message_new_link(rtnl, &m, RTM_NEWLINK, 0) >= 0);
|
||||||
|
|
||||||
|
@@ -434,9 +374,7 @@ static void test_container(sd_netlink *rtnl) {
|
||||||
|
assert_se(sd_netlink_message_open_container_union(m, IFLA_INFO_DATA, "vlan") >= 0);
|
||||||
|
assert_se(sd_netlink_message_append_u16(m, IFLA_VLAN_ID, 100) >= 0);
|
||||||
|
assert_se(sd_netlink_message_close_container(m) >= 0);
|
||||||
|
- assert_se(sd_netlink_message_append_string(m, IFLA_INFO_KIND, "vlan") >= 0);
|
||||||
|
assert_se(sd_netlink_message_close_container(m) >= 0);
|
||||||
|
- assert_se(sd_netlink_message_close_container(m) == -EINVAL);
|
||||||
|
|
||||||
|
assert_se(sd_netlink_message_rewind(m, rtnl) >= 0);
|
||||||
|
|
||||||
|
@@ -453,16 +391,12 @@ static void test_container(sd_netlink *rtnl) {
|
||||||
|
assert_se(sd_netlink_message_exit_container(m) >= 0);
|
||||||
|
|
||||||
|
assert_se(sd_netlink_message_read_u32(m, IFLA_LINKINFO, &u32_data) < 0);
|
||||||
|
-
|
||||||
|
- assert_se(sd_netlink_message_exit_container(m) == -EINVAL);
|
||||||
|
}
|
||||||
|
|
||||||
|
-static void test_match(void) {
|
||||||
|
+TEST(sd_netlink_add_match) {
|
||||||
|
_cleanup_(sd_netlink_slot_unrefp) sd_netlink_slot *s1 = NULL, *s2 = NULL;
|
||||||
|
_cleanup_(sd_netlink_unrefp) sd_netlink *rtnl = NULL;
|
||||||
|
|
||||||
|
- log_debug("/* %s */", __func__);
|
||||||
|
-
|
||||||
|
assert_se(sd_netlink_open(&rtnl) >= 0);
|
||||||
|
|
||||||
|
assert_se(sd_netlink_add_match(rtnl, &s1, RTM_NEWLINK, link_handler, NULL, NULL, NULL) >= 0);
|
||||||
|
@@ -475,17 +409,17 @@ static void test_match(void) {
|
||||||
|
assert_se((rtnl = sd_netlink_unref(rtnl)) == NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
-static void test_get_addresses(sd_netlink *rtnl) {
|
||||||
|
+TEST(dump_addresses) {
|
||||||
|
+ _cleanup_(sd_netlink_unrefp) sd_netlink *rtnl = NULL;
|
||||||
|
_cleanup_(sd_netlink_message_unrefp) sd_netlink_message *req = NULL, *reply = NULL;
|
||||||
|
- sd_netlink_message *m;
|
||||||
|
|
||||||
|
- log_debug("/* %s */", __func__);
|
||||||
|
+ assert_se(sd_netlink_open(&rtnl) >= 0);
|
||||||
|
|
||||||
|
assert_se(sd_rtnl_message_new_addr(rtnl, &req, RTM_GETADDR, 0, AF_UNSPEC) >= 0);
|
||||||
|
assert_se(sd_netlink_message_set_request_dump(req, true) >= 0);
|
||||||
|
assert_se(sd_netlink_call(rtnl, req, 0, &reply) >= 0);
|
||||||
|
|
||||||
|
- for (m = reply; m; m = sd_netlink_message_next(m)) {
|
||||||
|
+ for (sd_netlink_message *m = reply; m; m = sd_netlink_message_next(m)) {
|
||||||
|
uint16_t type;
|
||||||
|
unsigned char scope, flags;
|
||||||
|
int family, ifindex;
|
||||||
|
@@ -505,21 +439,20 @@ static void test_get_addresses(sd_netlink *rtnl) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
-static void test_message(sd_netlink *rtnl) {
|
||||||
|
+TEST(sd_netlink_message_get_errno) {
|
||||||
|
+ _cleanup_(sd_netlink_unrefp) sd_netlink *rtnl = NULL;
|
||||||
|
_cleanup_(sd_netlink_message_unrefp) sd_netlink_message *m = NULL;
|
||||||
|
|
||||||
|
- log_debug("/* %s */", __func__);
|
||||||
|
+ assert_se(sd_netlink_open(&rtnl) >= 0);
|
||||||
|
|
||||||
|
assert_se(message_new_synthetic_error(rtnl, -ETIMEDOUT, 1, &m) >= 0);
|
||||||
|
assert_se(sd_netlink_message_get_errno(m) == -ETIMEDOUT);
|
||||||
|
}
|
||||||
|
|
||||||
|
-static void test_array(void) {
|
||||||
|
+TEST(message_array) {
|
||||||
|
_cleanup_(sd_netlink_unrefp) sd_netlink *genl = NULL;
|
||||||
|
_cleanup_(sd_netlink_message_unrefp) sd_netlink_message *m = NULL;
|
||||||
|
|
||||||
|
- log_debug("/* %s */", __func__);
|
||||||
|
-
|
||||||
|
assert_se(sd_genl_socket_open(&genl) >= 0);
|
||||||
|
assert_se(sd_genl_message_new(genl, CTRL_GENL_NAME, CTRL_CMD_GETFAMILY, &m) >= 0);
|
||||||
|
|
||||||
|
@@ -557,12 +490,13 @@ static void test_array(void) {
|
||||||
|
assert_se(sd_netlink_message_exit_container(m) >= 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
-static void test_strv(sd_netlink *rtnl) {
|
||||||
|
+TEST(message_strv) {
|
||||||
|
+ _cleanup_(sd_netlink_unrefp) sd_netlink *rtnl = NULL;
|
||||||
|
_cleanup_(sd_netlink_message_unrefp) sd_netlink_message *m = NULL;
|
||||||
|
_cleanup_strv_free_ char **names_in = NULL, **names_out;
|
||||||
|
const char *p;
|
||||||
|
|
||||||
|
- log_debug("/* %s */", __func__);
|
||||||
|
+ assert_se(sd_netlink_open(&rtnl) >= 0);
|
||||||
|
|
||||||
|
assert_se(sd_rtnl_message_new_link(rtnl, &m, RTM_NEWLINKPROP, 1) >= 0);
|
||||||
|
|
||||||
|
@@ -624,7 +558,7 @@ static int genl_ctrl_match_callback(sd_netlink *genl, sd_netlink_message *m, voi
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
-static void test_genl(void) {
|
||||||
|
+TEST(genl) {
|
||||||
|
_cleanup_(sd_event_unrefp) sd_event *event = NULL;
|
||||||
|
_cleanup_(sd_netlink_unrefp) sd_netlink *genl = NULL;
|
||||||
|
_cleanup_(sd_netlink_message_unrefp) sd_netlink_message *m = NULL;
|
||||||
|
@@ -632,8 +566,6 @@ static void test_genl(void) {
|
||||||
|
uint8_t cmd;
|
||||||
|
int r;
|
||||||
|
|
||||||
|
- log_debug("/* %s */", __func__);
|
||||||
|
-
|
||||||
|
assert_se(sd_genl_socket_open(&genl) >= 0);
|
||||||
|
assert_se(sd_event_default(&event) >= 0);
|
||||||
|
assert_se(sd_netlink_attach_event(genl, event, 0) >= 0);
|
||||||
|
@@ -669,15 +601,17 @@ static void test_genl(void) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
-static void test_rtnl_set_link_name(sd_netlink *rtnl, int ifindex) {
|
||||||
|
+TEST(rtnl_set_link_name) {
|
||||||
|
+ _cleanup_(sd_netlink_unrefp) sd_netlink *rtnl = NULL;
|
||||||
|
_cleanup_strv_free_ char **alternative_names = NULL;
|
||||||
|
- int r;
|
||||||
|
-
|
||||||
|
- log_debug("/* %s */", __func__);
|
||||||
|
+ int ifindex, r;
|
||||||
|
|
||||||
|
if (geteuid() != 0)
|
||||||
|
return (void) log_tests_skipped("not root");
|
||||||
|
|
||||||
|
+ assert_se(sd_netlink_open(&rtnl) >= 0);
|
||||||
|
+ ifindex = (int) if_nametoindex("lo");
|
||||||
|
+
|
||||||
|
/* Test that the new name (which is currently an alternative name) is
|
||||||
|
* restored as an alternative name on error. Create an error by using
|
||||||
|
* an invalid device name, namely one that exceeds IFNAMSIZ
|
||||||
|
@@ -693,68 +627,4 @@ static void test_rtnl_set_link_name(sd_netlink *rtnl, int ifindex) {
|
||||||
|
assert_se(rtnl_delete_link_alternative_names(&rtnl, ifindex, STRV_MAKE("testlongalternativename")) >= 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
-int main(void) {
|
||||||
|
- sd_netlink *rtnl;
|
||||||
|
- sd_netlink_message *m;
|
||||||
|
- sd_netlink_message *r;
|
||||||
|
- const char *string_data;
|
||||||
|
- int if_loopback;
|
||||||
|
- uint16_t type;
|
||||||
|
-
|
||||||
|
- test_setup_logging(LOG_DEBUG);
|
||||||
|
-
|
||||||
|
- test_match();
|
||||||
|
- test_multiple();
|
||||||
|
-
|
||||||
|
- assert_se(sd_netlink_open(&rtnl) >= 0);
|
||||||
|
- assert_se(rtnl);
|
||||||
|
-
|
||||||
|
- test_route(rtnl);
|
||||||
|
- test_message(rtnl);
|
||||||
|
- test_container(rtnl);
|
||||||
|
- test_array();
|
||||||
|
- test_strv(rtnl);
|
||||||
|
-
|
||||||
|
- if_loopback = (int) if_nametoindex("lo");
|
||||||
|
- assert_se(if_loopback > 0);
|
||||||
|
-
|
||||||
|
- test_async(if_loopback);
|
||||||
|
- test_slot_set(if_loopback);
|
||||||
|
- test_async_destroy_callback(if_loopback);
|
||||||
|
- test_pipe(if_loopback);
|
||||||
|
- test_event_loop(if_loopback);
|
||||||
|
- test_link_configure(rtnl, if_loopback);
|
||||||
|
- test_rtnl_set_link_name(rtnl, if_loopback);
|
||||||
|
-
|
||||||
|
- test_get_addresses(rtnl);
|
||||||
|
- test_message_link_bridge(rtnl);
|
||||||
|
-
|
||||||
|
- assert_se(sd_rtnl_message_new_link(rtnl, &m, RTM_GETLINK, if_loopback) >= 0);
|
||||||
|
- assert_se(m);
|
||||||
|
-
|
||||||
|
- assert_se(sd_netlink_message_get_type(m, &type) >= 0);
|
||||||
|
- assert_se(type == RTM_GETLINK);
|
||||||
|
-
|
||||||
|
- assert_se(sd_netlink_message_read_string(m, IFLA_IFNAME, &string_data) == -EPERM);
|
||||||
|
-
|
||||||
|
- assert_se(sd_netlink_call(rtnl, m, 0, &r) == 1);
|
||||||
|
- assert_se(sd_netlink_message_get_type(r, &type) >= 0);
|
||||||
|
- assert_se(type == RTM_NEWLINK);
|
||||||
|
-
|
||||||
|
- assert_se((r = sd_netlink_message_unref(r)) == NULL);
|
||||||
|
-
|
||||||
|
- assert_se(sd_netlink_call(rtnl, m, -1, &r) == -EPERM);
|
||||||
|
- assert_se((m = sd_netlink_message_unref(m)) == NULL);
|
||||||
|
- assert_se((r = sd_netlink_message_unref(r)) == NULL);
|
||||||
|
-
|
||||||
|
- test_link_get(rtnl, if_loopback);
|
||||||
|
- test_address_get(rtnl, if_loopback);
|
||||||
|
-
|
||||||
|
- assert_se((m = sd_netlink_message_unref(m)) == NULL);
|
||||||
|
- assert_se((r = sd_netlink_message_unref(r)) == NULL);
|
||||||
|
- assert_se((rtnl = sd_netlink_unref(rtnl)) == NULL);
|
||||||
|
-
|
||||||
|
- test_genl();
|
||||||
|
-
|
||||||
|
- return EXIT_SUCCESS;
|
||||||
|
-}
|
||||||
|
+DEFINE_TEST_MAIN(LOG_DEBUG);
|
@ -0,0 +1,105 @@
|
|||||||
|
From 49fa9a23e444f864a4f06fb0c7b1f54ff0513206 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Yu Watanabe <watanabe.yu+github@gmail.com>
|
||||||
|
Date: Mon, 9 Jan 2023 21:00:53 +0900
|
||||||
|
Subject: [PATCH] test-netlink: use dummy interface to test assigning new
|
||||||
|
interface name
|
||||||
|
|
||||||
|
Fixes #25981.
|
||||||
|
|
||||||
|
(cherry picked from commit 5ccbe7fb197b01e0cf1f1ab523703274ef552555)
|
||||||
|
|
||||||
|
Related: RHEL-5988
|
||||||
|
---
|
||||||
|
src/libsystemd/sd-netlink/test-netlink.c | 59 ++++++++++++++++++++++--
|
||||||
|
1 file changed, 55 insertions(+), 4 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/src/libsystemd/sd-netlink/test-netlink.c b/src/libsystemd/sd-netlink/test-netlink.c
|
||||||
|
index f740035639..9ad8ecf320 100644
|
||||||
|
--- a/src/libsystemd/sd-netlink/test-netlink.c
|
||||||
|
+++ b/src/libsystemd/sd-netlink/test-netlink.c
|
||||||
|
@@ -601,30 +601,81 @@ TEST(genl) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
+static void remove_dummy_interfacep(int *ifindex) {
|
||||||
|
+ _cleanup_(sd_netlink_unrefp) sd_netlink *rtnl = NULL;
|
||||||
|
+ _cleanup_(sd_netlink_message_unrefp) sd_netlink_message *message = NULL;
|
||||||
|
+
|
||||||
|
+ if (!ifindex || *ifindex <= 0)
|
||||||
|
+ return;
|
||||||
|
+
|
||||||
|
+ assert_se(sd_netlink_open(&rtnl) >= 0);
|
||||||
|
+
|
||||||
|
+ assert_se(sd_rtnl_message_new_link(rtnl, &message, RTM_DELLINK, *ifindex) >= 0);
|
||||||
|
+ assert_se(sd_netlink_call(rtnl, message, 0, NULL) == 1);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
TEST(rtnl_set_link_name) {
|
||||||
|
_cleanup_(sd_netlink_unrefp) sd_netlink *rtnl = NULL;
|
||||||
|
+ _cleanup_(sd_netlink_message_unrefp) sd_netlink_message *message = NULL, *reply = NULL;
|
||||||
|
+ _cleanup_(remove_dummy_interfacep) int ifindex = 0;
|
||||||
|
_cleanup_strv_free_ char **alternative_names = NULL;
|
||||||
|
- int ifindex, r;
|
||||||
|
+ int r;
|
||||||
|
|
||||||
|
if (geteuid() != 0)
|
||||||
|
return (void) log_tests_skipped("not root");
|
||||||
|
|
||||||
|
assert_se(sd_netlink_open(&rtnl) >= 0);
|
||||||
|
- ifindex = (int) if_nametoindex("lo");
|
||||||
|
+
|
||||||
|
+ assert_se(sd_rtnl_message_new_link(rtnl, &message, RTM_NEWLINK, 0) >= 0);
|
||||||
|
+ assert_se(sd_netlink_message_append_string(message, IFLA_IFNAME, "test-netlink") >= 0);
|
||||||
|
+ assert_se(sd_netlink_message_open_container(message, IFLA_LINKINFO) >= 0);
|
||||||
|
+ assert_se(sd_netlink_message_append_string(message, IFLA_INFO_KIND, "dummy") >= 0);
|
||||||
|
+ r = sd_netlink_call(rtnl, message, 0, &reply);
|
||||||
|
+ if (r == -EPERM)
|
||||||
|
+ return (void) log_tests_skipped("missing required capabilities");
|
||||||
|
+ if (r == -EOPNOTSUPP)
|
||||||
|
+ return (void) log_tests_skipped("dummy network interface is not supported");
|
||||||
|
+ assert_se(r >= 0);
|
||||||
|
+
|
||||||
|
+ message = sd_netlink_message_unref(message);
|
||||||
|
+ reply = sd_netlink_message_unref(reply);
|
||||||
|
+
|
||||||
|
+ assert_se(sd_rtnl_message_new_link(rtnl, &message, RTM_GETLINK, 0) >= 0);
|
||||||
|
+ assert_se(sd_netlink_message_append_string(message, IFLA_IFNAME, "test-netlink") >= 0);
|
||||||
|
+ assert_se(sd_netlink_call(rtnl, message, 0, &reply) == 1);
|
||||||
|
+
|
||||||
|
+ assert_se(sd_rtnl_message_link_get_ifindex(reply, &ifindex) >= 0);
|
||||||
|
+ assert_se(ifindex > 0);
|
||||||
|
|
||||||
|
/* Test that the new name (which is currently an alternative name) is
|
||||||
|
* restored as an alternative name on error. Create an error by using
|
||||||
|
* an invalid device name, namely one that exceeds IFNAMSIZ
|
||||||
|
* (alternative names can exceed IFNAMSIZ, but not regular names). */
|
||||||
|
- r = rtnl_set_link_alternative_names(&rtnl, ifindex, STRV_MAKE("testlongalternativename"));
|
||||||
|
+ r = rtnl_set_link_alternative_names(&rtnl, ifindex, STRV_MAKE("testlongalternativename", "test-shortname"));
|
||||||
|
if (r == -EPERM)
|
||||||
|
return (void) log_tests_skipped("missing required capabilities");
|
||||||
|
-
|
||||||
|
+ if (r == -EOPNOTSUPP)
|
||||||
|
+ return (void) log_tests_skipped("alternative name is not supported");
|
||||||
|
assert_se(r >= 0);
|
||||||
|
+
|
||||||
|
+ assert_se(rtnl_get_link_alternative_names(&rtnl, ifindex, &alternative_names) >= 0);
|
||||||
|
+ assert_se(strv_contains(alternative_names, "testlongalternativename"));
|
||||||
|
+ assert_se(strv_contains(alternative_names, "test-shortname"));
|
||||||
|
+
|
||||||
|
assert_se(rtnl_set_link_name(&rtnl, ifindex, "testlongalternativename") == -EINVAL);
|
||||||
|
+ assert_se(rtnl_set_link_name(&rtnl, ifindex, "test-shortname") >= 0);
|
||||||
|
+
|
||||||
|
+ alternative_names = strv_free(alternative_names);
|
||||||
|
assert_se(rtnl_get_link_alternative_names(&rtnl, ifindex, &alternative_names) >= 0);
|
||||||
|
assert_se(strv_contains(alternative_names, "testlongalternativename"));
|
||||||
|
+ assert_se(!strv_contains(alternative_names, "test-shortname"));
|
||||||
|
+
|
||||||
|
assert_se(rtnl_delete_link_alternative_names(&rtnl, ifindex, STRV_MAKE("testlongalternativename")) >= 0);
|
||||||
|
+
|
||||||
|
+ alternative_names = strv_free(alternative_names);
|
||||||
|
+ assert_se(rtnl_get_link_alternative_names(&rtnl, ifindex, &alternative_names) >= 0);
|
||||||
|
+ assert_se(!strv_contains(alternative_names, "testlongalternativename"));
|
||||||
|
+ assert_se(!strv_contains(alternative_names, "test-shortname"));
|
||||||
|
}
|
||||||
|
|
||||||
|
DEFINE_TEST_MAIN(LOG_DEBUG);
|
@ -0,0 +1,26 @@
|
|||||||
|
From 2deb458c5fd4ac318018b8464fa677dc4570ba61 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Yu Watanabe <watanabe.yu+github@gmail.com>
|
||||||
|
Date: Tue, 16 May 2023 16:34:31 +0900
|
||||||
|
Subject: [PATCH] udev: use SYNTHETIC_ERRNO() at one more place
|
||||||
|
|
||||||
|
(cherry picked from commit b3cfe5900108df81fbf547b297d51ac8c7359a9b)
|
||||||
|
|
||||||
|
Related: RHEL-5988
|
||||||
|
---
|
||||||
|
src/udev/udevadm-test-builtin.c | 3 +--
|
||||||
|
1 file changed, 1 insertion(+), 2 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/src/udev/udevadm-test-builtin.c b/src/udev/udevadm-test-builtin.c
|
||||||
|
index 81b633611e..5570eec789 100644
|
||||||
|
--- a/src/udev/udevadm-test-builtin.c
|
||||||
|
+++ b/src/udev/udevadm-test-builtin.c
|
||||||
|
@@ -87,8 +87,7 @@ int builtin_main(int argc, char *argv[], void *userdata) {
|
||||||
|
|
||||||
|
cmd = udev_builtin_lookup(arg_command);
|
||||||
|
if (cmd < 0) {
|
||||||
|
- log_error("Unknown command '%s'", arg_command);
|
||||||
|
- r = -EINVAL;
|
||||||
|
+ r = log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Unknown command '%s'", arg_command);
|
||||||
|
goto finish;
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,351 @@
|
|||||||
|
From 09bc1c97130c4e646233ee3ea27ba03c226117d7 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Yu Watanabe <watanabe.yu+github@gmail.com>
|
||||||
|
Date: Tue, 16 May 2023 11:29:49 +0900
|
||||||
|
Subject: [PATCH] udev: make udev_builtin_run() take UdevEvent*
|
||||||
|
|
||||||
|
No functional change, preparation for later commits.
|
||||||
|
|
||||||
|
(cherry picked from commit 5668f3a7cfccca704ea8e8bdc84ca7e17a5f101e)
|
||||||
|
|
||||||
|
Related: RHEL-5988
|
||||||
|
---
|
||||||
|
src/udev/udev-builtin-blkid.c | 3 ++-
|
||||||
|
src/udev/udev-builtin-btrfs.c | 3 ++-
|
||||||
|
src/udev/udev-builtin-hwdb.c | 3 ++-
|
||||||
|
src/udev/udev-builtin-input_id.c | 6 ++----
|
||||||
|
src/udev/udev-builtin-keyboard.c | 3 ++-
|
||||||
|
src/udev/udev-builtin-kmod.c | 5 ++---
|
||||||
|
src/udev/udev-builtin-net_id.c | 3 ++-
|
||||||
|
src/udev/udev-builtin-net_setup_link.c | 7 ++++---
|
||||||
|
src/udev/udev-builtin-path_id.c | 5 ++---
|
||||||
|
src/udev/udev-builtin-uaccess.c | 3 ++-
|
||||||
|
src/udev/udev-builtin-usb_id.c | 5 ++---
|
||||||
|
src/udev/udev-builtin.c | 7 ++++---
|
||||||
|
src/udev/udev-builtin.h | 6 ++++--
|
||||||
|
src/udev/udev-event.c | 2 +-
|
||||||
|
src/udev/udev-rules.c | 2 +-
|
||||||
|
src/udev/udevadm-test-builtin.c | 10 ++++++++--
|
||||||
|
16 files changed, 42 insertions(+), 31 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/src/udev/udev-builtin-blkid.c b/src/udev/udev-builtin-blkid.c
|
||||||
|
index 9f5646ffdd..63d1bd579d 100644
|
||||||
|
--- a/src/udev/udev-builtin-blkid.c
|
||||||
|
+++ b/src/udev/udev-builtin-blkid.c
|
||||||
|
@@ -237,7 +237,8 @@ static int probe_superblocks(blkid_probe pr) {
|
||||||
|
return blkid_do_safeprobe(pr);
|
||||||
|
}
|
||||||
|
|
||||||
|
-static int builtin_blkid(sd_device *dev, sd_netlink **rtnl, int argc, char *argv[], bool test) {
|
||||||
|
+static int builtin_blkid(UdevEvent *event, int argc, char *argv[], bool test) {
|
||||||
|
+ sd_device *dev = ASSERT_PTR(ASSERT_PTR(event)->dev);
|
||||||
|
const char *devnode, *root_partition = NULL, *data, *name;
|
||||||
|
_cleanup_(blkid_free_probep) blkid_probe pr = NULL;
|
||||||
|
bool noraid = false, is_gpt = false;
|
||||||
|
diff --git a/src/udev/udev-builtin-btrfs.c b/src/udev/udev-builtin-btrfs.c
|
||||||
|
index 8cd627807f..b36eadb47a 100644
|
||||||
|
--- a/src/udev/udev-builtin-btrfs.c
|
||||||
|
+++ b/src/udev/udev-builtin-btrfs.c
|
||||||
|
@@ -13,7 +13,8 @@
|
||||||
|
#include "udev-builtin.h"
|
||||||
|
#include "util.h"
|
||||||
|
|
||||||
|
-static int builtin_btrfs(sd_device *dev, sd_netlink **rtnl, int argc, char *argv[], bool test) {
|
||||||
|
+static int builtin_btrfs(UdevEvent *event, int argc, char *argv[], bool test) {
|
||||||
|
+ sd_device *dev = ASSERT_PTR(ASSERT_PTR(event)->dev);
|
||||||
|
struct btrfs_ioctl_vol_args args = {};
|
||||||
|
_cleanup_close_ int fd = -1;
|
||||||
|
int r;
|
||||||
|
diff --git a/src/udev/udev-builtin-hwdb.c b/src/udev/udev-builtin-hwdb.c
|
||||||
|
index 8d652e46fe..19e07e734f 100644
|
||||||
|
--- a/src/udev/udev-builtin-hwdb.c
|
||||||
|
+++ b/src/udev/udev-builtin-hwdb.c
|
||||||
|
@@ -118,7 +118,7 @@ next:
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
-static int builtin_hwdb(sd_device *dev, sd_netlink **rtnl, int argc, char *argv[], bool test) {
|
||||||
|
+static int builtin_hwdb(UdevEvent *event, int argc, char *argv[], bool test) {
|
||||||
|
static const struct option options[] = {
|
||||||
|
{ "filter", required_argument, NULL, 'f' },
|
||||||
|
{ "device", required_argument, NULL, 'd' },
|
||||||
|
@@ -131,6 +131,7 @@ static int builtin_hwdb(sd_device *dev, sd_netlink **rtnl, int argc, char *argv[
|
||||||
|
const char *subsystem = NULL;
|
||||||
|
const char *prefix = NULL;
|
||||||
|
_cleanup_(sd_device_unrefp) sd_device *srcdev = NULL;
|
||||||
|
+ sd_device *dev = ASSERT_PTR(ASSERT_PTR(event)->dev);
|
||||||
|
int r;
|
||||||
|
|
||||||
|
if (!hwdb)
|
||||||
|
diff --git a/src/udev/udev-builtin-input_id.c b/src/udev/udev-builtin-input_id.c
|
||||||
|
index 0742120248..4322ce04b3 100644
|
||||||
|
--- a/src/udev/udev-builtin-input_id.c
|
||||||
|
+++ b/src/udev/udev-builtin-input_id.c
|
||||||
|
@@ -356,8 +356,8 @@ static bool test_key(sd_device *dev,
|
||||||
|
return found;
|
||||||
|
}
|
||||||
|
|
||||||
|
-static int builtin_input_id(sd_device *dev, sd_netlink **rtnl, int argc, char *argv[], bool test) {
|
||||||
|
- sd_device *pdev;
|
||||||
|
+static int builtin_input_id(UdevEvent *event, int argc, char *argv[], bool test) {
|
||||||
|
+ sd_device *pdev, *dev = ASSERT_PTR(ASSERT_PTR(event)->dev);
|
||||||
|
unsigned long bitmask_ev[NBITS(EV_MAX)];
|
||||||
|
unsigned long bitmask_abs[NBITS(ABS_MAX)];
|
||||||
|
unsigned long bitmask_key[NBITS(KEY_MAX)];
|
||||||
|
@@ -367,8 +367,6 @@ static int builtin_input_id(sd_device *dev, sd_netlink **rtnl, int argc, char *a
|
||||||
|
bool is_pointer;
|
||||||
|
bool is_key;
|
||||||
|
|
||||||
|
- assert(dev);
|
||||||
|
-
|
||||||
|
/* walk up the parental chain until we find the real input device; the
|
||||||
|
* argument is very likely a subdevice of this, like eventN */
|
||||||
|
for (pdev = dev; pdev; ) {
|
||||||
|
diff --git a/src/udev/udev-builtin-keyboard.c b/src/udev/udev-builtin-keyboard.c
|
||||||
|
index 6dd9eebd93..dac087a9e6 100644
|
||||||
|
--- a/src/udev/udev-builtin-keyboard.c
|
||||||
|
+++ b/src/udev/udev-builtin-keyboard.c
|
||||||
|
@@ -159,7 +159,8 @@ static int set_trackpoint_sensitivity(sd_device *dev, const char *value) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
-static int builtin_keyboard(sd_device *dev, sd_netlink **rtnl, int argc, char *argv[], bool test) {
|
||||||
|
+static int builtin_keyboard(UdevEvent *event, int argc, char *argv[], bool test) {
|
||||||
|
+ sd_device *dev = ASSERT_PTR(ASSERT_PTR(event)->dev);
|
||||||
|
unsigned release[1024];
|
||||||
|
unsigned release_count = 0;
|
||||||
|
_cleanup_close_ int fd = -1;
|
||||||
|
diff --git a/src/udev/udev-builtin-kmod.c b/src/udev/udev-builtin-kmod.c
|
||||||
|
index eade042f35..3ab5c485f8 100644
|
||||||
|
--- a/src/udev/udev-builtin-kmod.c
|
||||||
|
+++ b/src/udev/udev-builtin-kmod.c
|
||||||
|
@@ -22,11 +22,10 @@ _printf_(6,0) static void udev_kmod_log(void *data, int priority, const char *fi
|
||||||
|
log_internalv(priority, 0, file, line, fn, format, args);
|
||||||
|
}
|
||||||
|
|
||||||
|
-static int builtin_kmod(sd_device *dev, sd_netlink **rtnl, int argc, char *argv[], bool test) {
|
||||||
|
+static int builtin_kmod(UdevEvent *event, int argc, char *argv[], bool test) {
|
||||||
|
+ sd_device *dev = ASSERT_PTR(ASSERT_PTR(event)->dev);
|
||||||
|
int r;
|
||||||
|
|
||||||
|
- assert(dev);
|
||||||
|
-
|
||||||
|
if (!ctx)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
diff --git a/src/udev/udev-builtin-net_id.c b/src/udev/udev-builtin-net_id.c
|
||||||
|
index c57568f8cb..cecf854b98 100644
|
||||||
|
--- a/src/udev/udev-builtin-net_id.c
|
||||||
|
+++ b/src/udev/udev-builtin-net_id.c
|
||||||
|
@@ -1109,7 +1109,8 @@ static int get_link_info(sd_device *dev, LinkInfo *info) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
-static int builtin_net_id(sd_device *dev, sd_netlink **rtnl, int argc, char *argv[], bool test) {
|
||||||
|
+static int builtin_net_id(UdevEvent *event, int argc, char *argv[], bool test) {
|
||||||
|
+ sd_device *dev = ASSERT_PTR(ASSERT_PTR(event)->dev);
|
||||||
|
const char *prefix;
|
||||||
|
NetNames names = {};
|
||||||
|
LinkInfo info = {
|
||||||
|
diff --git a/src/udev/udev-builtin-net_setup_link.c b/src/udev/udev-builtin-net_setup_link.c
|
||||||
|
index ea7b1c5f60..4bf42cd492 100644
|
||||||
|
--- a/src/udev/udev-builtin-net_setup_link.c
|
||||||
|
+++ b/src/udev/udev-builtin-net_setup_link.c
|
||||||
|
@@ -10,14 +10,15 @@
|
||||||
|
|
||||||
|
static LinkConfigContext *ctx = NULL;
|
||||||
|
|
||||||
|
-static int builtin_net_setup_link(sd_device *dev, sd_netlink **rtnl, int argc, char **argv, bool test) {
|
||||||
|
+static int builtin_net_setup_link(UdevEvent *event, int argc, char **argv, bool test) {
|
||||||
|
+ sd_device *dev = ASSERT_PTR(ASSERT_PTR(event)->dev);
|
||||||
|
_cleanup_(link_freep) Link *link = NULL;
|
||||||
|
int r;
|
||||||
|
|
||||||
|
if (argc > 1)
|
||||||
|
return log_device_error_errno(dev, SYNTHETIC_ERRNO(EINVAL), "This program takes no arguments.");
|
||||||
|
|
||||||
|
- r = link_new(ctx, rtnl, dev, &link);
|
||||||
|
+ r = link_new(ctx, &event->rtnl, dev, &link);
|
||||||
|
if (r == -ENODEV) {
|
||||||
|
log_device_debug_errno(dev, r, "Link vanished while getting information, ignoring.");
|
||||||
|
return 0;
|
||||||
|
@@ -38,7 +39,7 @@ static int builtin_net_setup_link(sd_device *dev, sd_netlink **rtnl, int argc, c
|
||||||
|
return log_device_error_errno(dev, r, "Failed to get link config: %m");
|
||||||
|
}
|
||||||
|
|
||||||
|
- r = link_apply_config(ctx, rtnl, link);
|
||||||
|
+ r = link_apply_config(ctx, &event->rtnl, link);
|
||||||
|
if (r == -ENODEV)
|
||||||
|
log_device_debug_errno(dev, r, "Link vanished while applying configuration, ignoring.");
|
||||||
|
else if (r < 0)
|
||||||
|
diff --git a/src/udev/udev-builtin-path_id.c b/src/udev/udev-builtin-path_id.c
|
||||||
|
index d58a3d5d60..6f4d7cbc5b 100644
|
||||||
|
--- a/src/udev/udev-builtin-path_id.c
|
||||||
|
+++ b/src/udev/udev-builtin-path_id.c
|
||||||
|
@@ -581,15 +581,14 @@ static int find_real_nvme_parent(sd_device *dev, sd_device **ret) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
-static int builtin_path_id(sd_device *dev, sd_netlink **rtnl, int argc, char *argv[], bool test) {
|
||||||
|
+static int builtin_path_id(UdevEvent *event, int argc, char *argv[], bool test) {
|
||||||
|
+ sd_device *dev = ASSERT_PTR(ASSERT_PTR(event)->dev);
|
||||||
|
_cleanup_(sd_device_unrefp) sd_device *dev_other_branch = NULL;
|
||||||
|
_cleanup_free_ char *path = NULL, *compat_path = NULL;
|
||||||
|
bool supported_transport = false, supported_parent = false;
|
||||||
|
const char *subsystem;
|
||||||
|
int r;
|
||||||
|
|
||||||
|
- assert(dev);
|
||||||
|
-
|
||||||
|
/* walk up the chain of devices and compose path */
|
||||||
|
for (sd_device *parent = dev; parent; ) {
|
||||||
|
const char *subsys, *sysname;
|
||||||
|
diff --git a/src/udev/udev-builtin-uaccess.c b/src/udev/udev-builtin-uaccess.c
|
||||||
|
index 6e73d99375..36c993cbb0 100644
|
||||||
|
--- a/src/udev/udev-builtin-uaccess.c
|
||||||
|
+++ b/src/udev/udev-builtin-uaccess.c
|
||||||
|
@@ -16,7 +16,8 @@
|
||||||
|
#include "log.h"
|
||||||
|
#include "udev-builtin.h"
|
||||||
|
|
||||||
|
-static int builtin_uaccess(sd_device *dev, sd_netlink **rtnl, int argc, char *argv[], bool test) {
|
||||||
|
+static int builtin_uaccess(UdevEvent *event, int argc, char *argv[], bool test) {
|
||||||
|
+ sd_device *dev = ASSERT_PTR(ASSERT_PTR(event)->dev);
|
||||||
|
const char *path = NULL, *seat;
|
||||||
|
bool changed_acl = false;
|
||||||
|
uid_t uid;
|
||||||
|
diff --git a/src/udev/udev-builtin-usb_id.c b/src/udev/udev-builtin-usb_id.c
|
||||||
|
index 847c2b8316..f3fc3cfdb3 100644
|
||||||
|
--- a/src/udev/udev-builtin-usb_id.c
|
||||||
|
+++ b/src/udev/udev-builtin-usb_id.c
|
||||||
|
@@ -224,7 +224,8 @@ static int dev_if_packed_info(sd_device *dev, char *ifs_str, size_t len) {
|
||||||
|
* 6.) If the device supplies a serial number, this number
|
||||||
|
* is concatenated with the identification with an underscore '_'.
|
||||||
|
*/
|
||||||
|
-static int builtin_usb_id(sd_device *dev, sd_netlink **rtnl, int argc, char *argv[], bool test) {
|
||||||
|
+static int builtin_usb_id(UdevEvent *event, int argc, char *argv[], bool test) {
|
||||||
|
+ sd_device *dev = ASSERT_PTR(ASSERT_PTR(event)->dev);
|
||||||
|
char vendor_str[64] = "";
|
||||||
|
char vendor_str_enc[256];
|
||||||
|
const char *vendor_id;
|
||||||
|
@@ -250,8 +251,6 @@ static int builtin_usb_id(sd_device *dev, sd_netlink **rtnl, int argc, char *arg
|
||||||
|
const char *syspath, *sysname, *devtype, *interface_syspath;
|
||||||
|
int r;
|
||||||
|
|
||||||
|
- assert(dev);
|
||||||
|
-
|
||||||
|
r = sd_device_get_syspath(dev, &syspath);
|
||||||
|
if (r < 0)
|
||||||
|
return r;
|
||||||
|
diff --git a/src/udev/udev-builtin.c b/src/udev/udev-builtin.c
|
||||||
|
index c98c6fa714..c84db8855c 100644
|
||||||
|
--- a/src/udev/udev-builtin.c
|
||||||
|
+++ b/src/udev/udev-builtin.c
|
||||||
|
@@ -98,11 +98,12 @@ UdevBuiltinCommand udev_builtin_lookup(const char *command) {
|
||||||
|
return _UDEV_BUILTIN_INVALID;
|
||||||
|
}
|
||||||
|
|
||||||
|
-int udev_builtin_run(sd_device *dev, sd_netlink **rtnl, UdevBuiltinCommand cmd, const char *command, bool test) {
|
||||||
|
+int udev_builtin_run(UdevEvent *event, UdevBuiltinCommand cmd, const char *command, bool test) {
|
||||||
|
_cleanup_strv_free_ char **argv = NULL;
|
||||||
|
int r;
|
||||||
|
|
||||||
|
- assert(dev);
|
||||||
|
+ assert(event);
|
||||||
|
+ assert(event->dev);
|
||||||
|
assert(cmd >= 0 && cmd < _UDEV_BUILTIN_MAX);
|
||||||
|
assert(command);
|
||||||
|
|
||||||
|
@@ -115,7 +116,7 @@ int udev_builtin_run(sd_device *dev, sd_netlink **rtnl, UdevBuiltinCommand cmd,
|
||||||
|
|
||||||
|
/* we need '0' here to reset the internal state */
|
||||||
|
optind = 0;
|
||||||
|
- return builtins[cmd]->cmd(dev, rtnl, strv_length(argv), argv, test);
|
||||||
|
+ return builtins[cmd]->cmd(event, strv_length(argv), argv, test);
|
||||||
|
}
|
||||||
|
|
||||||
|
int udev_builtin_add_property(sd_device *dev, bool test, const char *key, const char *val) {
|
||||||
|
diff --git a/src/udev/udev-builtin.h b/src/udev/udev-builtin.h
|
||||||
|
index bcfec03aae..919d51e798 100644
|
||||||
|
--- a/src/udev/udev-builtin.h
|
||||||
|
+++ b/src/udev/udev-builtin.h
|
||||||
|
@@ -6,6 +6,8 @@
|
||||||
|
#include "sd-device.h"
|
||||||
|
#include "sd-netlink.h"
|
||||||
|
|
||||||
|
+#include "udev-event.h"
|
||||||
|
+
|
||||||
|
typedef enum UdevBuiltinCommand {
|
||||||
|
#if HAVE_BLKID
|
||||||
|
UDEV_BUILTIN_BLKID,
|
||||||
|
@@ -30,7 +32,7 @@ typedef enum UdevBuiltinCommand {
|
||||||
|
|
||||||
|
typedef struct UdevBuiltin {
|
||||||
|
const char *name;
|
||||||
|
- int (*cmd)(sd_device *dev, sd_netlink **rtnl, int argc, char *argv[], bool test);
|
||||||
|
+ int (*cmd)(UdevEvent *event, int argc, char *argv[], bool test);
|
||||||
|
const char *help;
|
||||||
|
int (*init)(void);
|
||||||
|
void (*exit)(void);
|
||||||
|
@@ -74,7 +76,7 @@ void udev_builtin_exit(void);
|
||||||
|
UdevBuiltinCommand udev_builtin_lookup(const char *command);
|
||||||
|
const char *udev_builtin_name(UdevBuiltinCommand cmd);
|
||||||
|
bool udev_builtin_run_once(UdevBuiltinCommand cmd);
|
||||||
|
-int udev_builtin_run(sd_device *dev, sd_netlink **rtnl, UdevBuiltinCommand cmd, const char *command, bool test);
|
||||||
|
+int udev_builtin_run(UdevEvent *event, UdevBuiltinCommand cmd, const char *command, bool test);
|
||||||
|
void udev_builtin_list(void);
|
||||||
|
bool udev_builtin_should_reload(void);
|
||||||
|
int udev_builtin_add_property(sd_device *dev, bool test, const char *key, const char *val);
|
||||||
|
diff --git a/src/udev/udev-event.c b/src/udev/udev-event.c
|
||||||
|
index fab454ae37..cf90d6f205 100644
|
||||||
|
--- a/src/udev/udev-event.c
|
||||||
|
+++ b/src/udev/udev-event.c
|
||||||
|
@@ -1200,7 +1200,7 @@ void udev_event_execute_run(UdevEvent *event, usec_t timeout_usec, int timeout_s
|
||||||
|
|
||||||
|
if (builtin_cmd != _UDEV_BUILTIN_INVALID) {
|
||||||
|
log_device_debug(event->dev, "Running built-in command \"%s\"", command);
|
||||||
|
- r = udev_builtin_run(event->dev, &event->rtnl, builtin_cmd, command, false);
|
||||||
|
+ r = udev_builtin_run(event, builtin_cmd, command, false);
|
||||||
|
if (r < 0)
|
||||||
|
log_device_debug_errno(event->dev, r, "Failed to run built-in command \"%s\", ignoring: %m", command);
|
||||||
|
} else {
|
||||||
|
diff --git a/src/udev/udev-rules.c b/src/udev/udev-rules.c
|
||||||
|
index a8473041c3..9336ce1cd3 100644
|
||||||
|
--- a/src/udev/udev-rules.c
|
||||||
|
+++ b/src/udev/udev-rules.c
|
||||||
|
@@ -1972,7 +1972,7 @@ static int udev_rule_apply_token_to_event(
|
||||||
|
|
||||||
|
log_rule_debug(dev, rules, "Importing properties from results of builtin command '%s'", buf);
|
||||||
|
|
||||||
|
- r = udev_builtin_run(dev, &event->rtnl, cmd, buf, false);
|
||||||
|
+ r = udev_builtin_run(event, cmd, buf, false);
|
||||||
|
if (r < 0) {
|
||||||
|
/* remember failure */
|
||||||
|
log_rule_debug_errno(dev, rules, r, "Failed to run builtin '%s': %m", buf);
|
||||||
|
diff --git a/src/udev/udevadm-test-builtin.c b/src/udev/udevadm-test-builtin.c
|
||||||
|
index 5570eec789..5d1fafbd03 100644
|
||||||
|
--- a/src/udev/udevadm-test-builtin.c
|
||||||
|
+++ b/src/udev/udevadm-test-builtin.c
|
||||||
|
@@ -72,7 +72,7 @@ static int parse_argv(int argc, char *argv[]) {
|
||||||
|
}
|
||||||
|
|
||||||
|
int builtin_main(int argc, char *argv[], void *userdata) {
|
||||||
|
- _cleanup_(sd_netlink_unrefp) sd_netlink *rtnl = NULL;
|
||||||
|
+ _cleanup_(udev_event_freep) UdevEvent *event = NULL;
|
||||||
|
_cleanup_(sd_device_unrefp) sd_device *dev = NULL;
|
||||||
|
UdevBuiltinCommand cmd;
|
||||||
|
int r;
|
||||||
|
@@ -97,7 +97,13 @@ int builtin_main(int argc, char *argv[], void *userdata) {
|
||||||
|
goto finish;
|
||||||
|
}
|
||||||
|
|
||||||
|
- r = udev_builtin_run(dev, &rtnl, cmd, arg_command, true);
|
||||||
|
+ event = udev_event_new(dev, 0, NULL, LOG_DEBUG);
|
||||||
|
+ if (!event) {
|
||||||
|
+ r = log_oom();
|
||||||
|
+ goto finish;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ r = udev_builtin_run(event, cmd, arg_command, true);
|
||||||
|
if (r < 0)
|
||||||
|
log_debug_errno(r, "Builtin command '%s' fails: %m", arg_command);
|
||||||
|
|
@ -0,0 +1,26 @@
|
|||||||
|
From 87a2e6ccd7989f2b271f557c6303a4eb412a03cb Mon Sep 17 00:00:00 2001
|
||||||
|
From: Yu Watanabe <watanabe.yu+github@gmail.com>
|
||||||
|
Date: Tue, 16 May 2023 11:46:11 +0900
|
||||||
|
Subject: [PATCH] udev/net: verify ID_NET_XYZ before trying to assign it as an
|
||||||
|
alternative name
|
||||||
|
|
||||||
|
(cherry picked from commit e65c6c1baa8ea905f7e5bad3b8486d509775ec6a)
|
||||||
|
|
||||||
|
Related: RHEL-5988
|
||||||
|
---
|
||||||
|
src/udev/net/link-config.c | 2 +-
|
||||||
|
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||||
|
|
||||||
|
diff --git a/src/udev/net/link-config.c b/src/udev/net/link-config.c
|
||||||
|
index 5d28526527..4fcf373f8e 100644
|
||||||
|
--- a/src/udev/net/link-config.c
|
||||||
|
+++ b/src/udev/net/link-config.c
|
||||||
|
@@ -834,7 +834,7 @@ static int link_apply_alternative_names(Link *link, sd_netlink **rtnl) {
|
||||||
|
default:
|
||||||
|
assert_not_reached();
|
||||||
|
}
|
||||||
|
- if (!isempty(n)) {
|
||||||
|
+ if (ifname_valid_full(n, IFNAME_VALID_ALTERNATIVE)) {
|
||||||
|
r = strv_extend(&altnames, n);
|
||||||
|
if (r < 0)
|
||||||
|
return log_oom();
|
@ -0,0 +1,29 @@
|
|||||||
|
From dd4c492721ed4be1b4c26cd937566dac2e97ba19 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Yu Watanabe <watanabe.yu+github@gmail.com>
|
||||||
|
Date: Tue, 16 May 2023 13:05:09 +0900
|
||||||
|
Subject: [PATCH] udev/net: generate new network interface name only on add
|
||||||
|
uevent
|
||||||
|
|
||||||
|
On other uevents, the name will be anyway ignored in rename_netif() in
|
||||||
|
udev-event.c.
|
||||||
|
|
||||||
|
(cherry picked from commit cd941e6596adba6bb139c387ae596f26b35701f7)
|
||||||
|
|
||||||
|
Related: RHEL-5988
|
||||||
|
---
|
||||||
|
src/udev/net/link-config.c | 2 +-
|
||||||
|
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||||
|
|
||||||
|
diff --git a/src/udev/net/link-config.c b/src/udev/net/link-config.c
|
||||||
|
index 4fcf373f8e..c9789bcb7c 100644
|
||||||
|
--- a/src/udev/net/link-config.c
|
||||||
|
+++ b/src/udev/net/link-config.c
|
||||||
|
@@ -722,7 +722,7 @@ static int link_generate_new_name(Link *link) {
|
||||||
|
config = link->config;
|
||||||
|
device = link->device;
|
||||||
|
|
||||||
|
- if (link->action == SD_DEVICE_MOVE) {
|
||||||
|
+ if (link->action != SD_DEVICE_ADD) {
|
||||||
|
log_link_debug(link, "Skipping to apply Name= and NamePolicy= on '%s' uevent.",
|
||||||
|
device_action_to_string(link->action));
|
||||||
|
goto no_rename;
|
@ -0,0 +1,191 @@
|
|||||||
|
From ea5725b1e621c2733c28f818c3a58615a385337e Mon Sep 17 00:00:00 2001
|
||||||
|
From: Yu Watanabe <watanabe.yu+github@gmail.com>
|
||||||
|
Date: Tue, 16 May 2023 13:29:37 +0900
|
||||||
|
Subject: [PATCH] sd-netlink: make rtnl_set_link_name() optionally append
|
||||||
|
alternative names
|
||||||
|
|
||||||
|
(cherry picked from commit 81824455008070253c62bf5c27187028ba8e7e99)
|
||||||
|
|
||||||
|
Related: RHEL-5988
|
||||||
|
---
|
||||||
|
src/libsystemd/sd-netlink/netlink-util.c | 89 ++++++++++++++++++------
|
||||||
|
src/libsystemd/sd-netlink/netlink-util.h | 5 +-
|
||||||
|
src/libsystemd/sd-netlink/test-netlink.c | 6 +-
|
||||||
|
src/udev/udev-event.c | 2 +-
|
||||||
|
4 files changed, 78 insertions(+), 24 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/src/libsystemd/sd-netlink/netlink-util.c b/src/libsystemd/sd-netlink/netlink-util.c
|
||||||
|
index cfcf2578d6..5438737b42 100644
|
||||||
|
--- a/src/libsystemd/sd-netlink/netlink-util.c
|
||||||
|
+++ b/src/libsystemd/sd-netlink/netlink-util.c
|
||||||
|
@@ -11,44 +11,93 @@
|
||||||
|
#include "process-util.h"
|
||||||
|
#include "strv.h"
|
||||||
|
|
||||||
|
-int rtnl_set_link_name(sd_netlink **rtnl, int ifindex, const char *name) {
|
||||||
|
+static int set_link_name(sd_netlink **rtnl, int ifindex, const char *name) {
|
||||||
|
_cleanup_(sd_netlink_message_unrefp) sd_netlink_message *message = NULL;
|
||||||
|
- _cleanup_strv_free_ char **alternative_names = NULL;
|
||||||
|
- bool altname_deleted = false;
|
||||||
|
int r;
|
||||||
|
|
||||||
|
assert(rtnl);
|
||||||
|
assert(ifindex > 0);
|
||||||
|
assert(name);
|
||||||
|
|
||||||
|
- if (!ifname_valid(name))
|
||||||
|
+ /* Assign the requested name. */
|
||||||
|
+ r = sd_rtnl_message_new_link(*rtnl, &message, RTM_SETLINK, ifindex);
|
||||||
|
+ if (r < 0)
|
||||||
|
+ return r;
|
||||||
|
+
|
||||||
|
+ r = sd_netlink_message_append_string(message, IFLA_IFNAME, name);
|
||||||
|
+ if (r < 0)
|
||||||
|
+ return r;
|
||||||
|
+
|
||||||
|
+ return sd_netlink_call(*rtnl, message, 0, NULL);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+int rtnl_set_link_name(sd_netlink **rtnl, int ifindex, const char *name, char* const *alternative_names) {
|
||||||
|
+ _cleanup_strv_free_ char **original_altnames = NULL, **new_altnames = NULL;
|
||||||
|
+ bool altname_deleted = false;
|
||||||
|
+ int r;
|
||||||
|
+
|
||||||
|
+ assert(rtnl);
|
||||||
|
+ assert(ifindex > 0);
|
||||||
|
+
|
||||||
|
+ if (isempty(name) && strv_isempty(alternative_names))
|
||||||
|
+ return 0;
|
||||||
|
+
|
||||||
|
+ if (name && !ifname_valid(name))
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
- r = rtnl_get_link_alternative_names(rtnl, ifindex, &alternative_names);
|
||||||
|
+ /* If the requested name is already assigned as an alternative name, then first drop it. */
|
||||||
|
+ r = rtnl_get_link_alternative_names(rtnl, ifindex, &original_altnames);
|
||||||
|
if (r < 0)
|
||||||
|
log_debug_errno(r, "Failed to get alternative names on network interface %i, ignoring: %m",
|
||||||
|
ifindex);
|
||||||
|
|
||||||
|
- if (strv_contains(alternative_names, name)) {
|
||||||
|
- r = rtnl_delete_link_alternative_names(rtnl, ifindex, STRV_MAKE(name));
|
||||||
|
- if (r < 0)
|
||||||
|
- return log_debug_errno(r, "Failed to remove '%s' from alternative names on network interface %i: %m",
|
||||||
|
- name, ifindex);
|
||||||
|
+ if (name) {
|
||||||
|
+ if (strv_contains(original_altnames, name)) {
|
||||||
|
+ r = rtnl_delete_link_alternative_names(rtnl, ifindex, STRV_MAKE(name));
|
||||||
|
+ if (r < 0)
|
||||||
|
+ return log_debug_errno(r, "Failed to remove '%s' from alternative names on network interface %i: %m",
|
||||||
|
+ name, ifindex);
|
||||||
|
+
|
||||||
|
+ altname_deleted = true;
|
||||||
|
+ }
|
||||||
|
|
||||||
|
- altname_deleted = true;
|
||||||
|
+ r = set_link_name(rtnl, ifindex, name);
|
||||||
|
+ if (r < 0)
|
||||||
|
+ goto fail;
|
||||||
|
}
|
||||||
|
|
||||||
|
- r = sd_rtnl_message_new_link(*rtnl, &message, RTM_SETLINK, ifindex);
|
||||||
|
- if (r < 0)
|
||||||
|
- goto fail;
|
||||||
|
+ /* Filter out already assigned names from requested alternative names. Also, dedup the request. */
|
||||||
|
+ STRV_FOREACH(a, alternative_names) {
|
||||||
|
+ if (streq_ptr(name, *a))
|
||||||
|
+ continue;
|
||||||
|
|
||||||
|
- r = sd_netlink_message_append_string(message, IFLA_IFNAME, name);
|
||||||
|
- if (r < 0)
|
||||||
|
- goto fail;
|
||||||
|
+ if (strv_contains(original_altnames, *a))
|
||||||
|
+ continue;
|
||||||
|
|
||||||
|
- r = sd_netlink_call(*rtnl, message, 0, NULL);
|
||||||
|
- if (r < 0)
|
||||||
|
- goto fail;
|
||||||
|
+ if (strv_contains(new_altnames, *a))
|
||||||
|
+ continue;
|
||||||
|
+
|
||||||
|
+ if (!ifname_valid_full(*a, IFNAME_VALID_ALTERNATIVE))
|
||||||
|
+ continue;
|
||||||
|
+
|
||||||
|
+ r = strv_extend(&new_altnames, *a);
|
||||||
|
+ if (r < 0)
|
||||||
|
+ return r;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ strv_sort(new_altnames);
|
||||||
|
+
|
||||||
|
+ /* Finally, assign alternative names. */
|
||||||
|
+ r = rtnl_set_link_alternative_names(rtnl, ifindex, new_altnames);
|
||||||
|
+ if (r == -EEXIST) /* Already assigned to another interface? */
|
||||||
|
+ STRV_FOREACH(a, new_altnames) {
|
||||||
|
+ r = rtnl_set_link_alternative_names(rtnl, ifindex, STRV_MAKE(*a));
|
||||||
|
+ if (r < 0)
|
||||||
|
+ log_debug_errno(r, "Failed to assign '%s' as an alternative name on network interface %i, ignoring: %m",
|
||||||
|
+ *a, ifindex);
|
||||||
|
+ }
|
||||||
|
+ else if (r < 0)
|
||||||
|
+ log_debug_errno(r, "Failed to assign alternative names on network interface %i, ignoring: %m", ifindex);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
diff --git a/src/libsystemd/sd-netlink/netlink-util.h b/src/libsystemd/sd-netlink/netlink-util.h
|
||||||
|
index d14392a018..888e28642d 100644
|
||||||
|
--- a/src/libsystemd/sd-netlink/netlink-util.h
|
||||||
|
+++ b/src/libsystemd/sd-netlink/netlink-util.h
|
||||||
|
@@ -29,7 +29,10 @@ DEFINE_TRIVIAL_CLEANUP_FUNC(MultipathRoute*, multipath_route_free);
|
||||||
|
|
||||||
|
int multipath_route_dup(const MultipathRoute *m, MultipathRoute **ret);
|
||||||
|
|
||||||
|
-int rtnl_set_link_name(sd_netlink **rtnl, int ifindex, const char *name);
|
||||||
|
+int rtnl_set_link_name(sd_netlink **rtnl, int ifindex, const char *name, char* const* alternative_names);
|
||||||
|
+static inline int rtnl_append_link_alternative_names(sd_netlink **rtnl, int ifindex, char* const *alternative_names) {
|
||||||
|
+ return rtnl_set_link_name(rtnl, ifindex, NULL, alternative_names);
|
||||||
|
+}
|
||||||
|
int rtnl_set_link_properties(
|
||||||
|
sd_netlink **rtnl,
|
||||||
|
int ifindex,
|
||||||
|
diff --git a/src/libsystemd/sd-netlink/test-netlink.c b/src/libsystemd/sd-netlink/test-netlink.c
|
||||||
|
index 9ad8ecf320..43124b99ae 100644
|
||||||
|
--- a/src/libsystemd/sd-netlink/test-netlink.c
|
||||||
|
+++ b/src/libsystemd/sd-netlink/test-netlink.c
|
||||||
|
@@ -662,12 +662,13 @@ TEST(rtnl_set_link_name) {
|
||||||
|
assert_se(strv_contains(alternative_names, "testlongalternativename"));
|
||||||
|
assert_se(strv_contains(alternative_names, "test-shortname"));
|
||||||
|
|
||||||
|
- assert_se(rtnl_set_link_name(&rtnl, ifindex, "testlongalternativename") == -EINVAL);
|
||||||
|
- assert_se(rtnl_set_link_name(&rtnl, ifindex, "test-shortname") >= 0);
|
||||||
|
+ assert_se(rtnl_set_link_name(&rtnl, ifindex, "testlongalternativename", NULL) == -EINVAL);
|
||||||
|
+ assert_se(rtnl_set_link_name(&rtnl, ifindex, "test-shortname", STRV_MAKE("testlongalternativename", "test-shortname", "test-additional-name")) >= 0);
|
||||||
|
|
||||||
|
alternative_names = strv_free(alternative_names);
|
||||||
|
assert_se(rtnl_get_link_alternative_names(&rtnl, ifindex, &alternative_names) >= 0);
|
||||||
|
assert_se(strv_contains(alternative_names, "testlongalternativename"));
|
||||||
|
+ assert_se(strv_contains(alternative_names, "test-additional-name"));
|
||||||
|
assert_se(!strv_contains(alternative_names, "test-shortname"));
|
||||||
|
|
||||||
|
assert_se(rtnl_delete_link_alternative_names(&rtnl, ifindex, STRV_MAKE("testlongalternativename")) >= 0);
|
||||||
|
@@ -675,6 +676,7 @@ TEST(rtnl_set_link_name) {
|
||||||
|
alternative_names = strv_free(alternative_names);
|
||||||
|
assert_se(rtnl_get_link_alternative_names(&rtnl, ifindex, &alternative_names) >= 0);
|
||||||
|
assert_se(!strv_contains(alternative_names, "testlongalternativename"));
|
||||||
|
+ assert_se(strv_contains(alternative_names, "test-additional-name"));
|
||||||
|
assert_se(!strv_contains(alternative_names, "test-shortname"));
|
||||||
|
}
|
||||||
|
|
||||||
|
diff --git a/src/udev/udev-event.c b/src/udev/udev-event.c
|
||||||
|
index cf90d6f205..2662806d61 100644
|
||||||
|
--- a/src/udev/udev-event.c
|
||||||
|
+++ b/src/udev/udev-event.c
|
||||||
|
@@ -980,7 +980,7 @@ static int rename_netif(UdevEvent *event) {
|
||||||
|
goto revert;
|
||||||
|
}
|
||||||
|
|
||||||
|
- r = rtnl_set_link_name(&event->rtnl, ifindex, event->name);
|
||||||
|
+ r = rtnl_set_link_name(&event->rtnl, ifindex, event->name, NULL);
|
||||||
|
if (r < 0) {
|
||||||
|
if (r == -EBUSY) {
|
||||||
|
log_device_info(dev, "Network interface '%s' is already up, cannot rename to '%s'.",
|
@ -0,0 +1,233 @@
|
|||||||
|
From 11f76dbf187708c3eda4a4daeb058f544ea28af5 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Yu Watanabe <watanabe.yu+github@gmail.com>
|
||||||
|
Date: Tue, 16 May 2023 12:28:23 +0900
|
||||||
|
Subject: [PATCH] udev/net: assign alternative names only on add uevent
|
||||||
|
|
||||||
|
Previously, we first assign alternative names to a network interface,
|
||||||
|
then later change its main name if requested. So, we could not assign
|
||||||
|
the name that currently assigned as the main name of an interface as an
|
||||||
|
alternative name. So, we retry to assign the previous main name as an
|
||||||
|
alternative name on later move uevent.
|
||||||
|
|
||||||
|
However, that causes some confusing situation. E.g. if a .link file has
|
||||||
|
```
|
||||||
|
Name=foo
|
||||||
|
AlternativeNames=foo baz
|
||||||
|
```
|
||||||
|
then even if the interface is renamed by a user e.g. by invoking 'ip link'
|
||||||
|
command manually, the interface can be still referenced as 'foo', as the
|
||||||
|
name is now assigned as an alternative name.
|
||||||
|
|
||||||
|
This makes the order of name assignment inverse: the main name is first
|
||||||
|
changed, and then the requested alternative names are assigned. And
|
||||||
|
udevd do not assign alternative names on move uevent.
|
||||||
|
|
||||||
|
Replaces #27506.
|
||||||
|
|
||||||
|
(cherry picked from commit 9094ae52caca0c19ff6abdbd95d17d8e401ea3b1)
|
||||||
|
|
||||||
|
Resolves: RHEL-5988
|
||||||
|
---
|
||||||
|
src/udev/net/link-config.c | 37 ++++++++-------------
|
||||||
|
src/udev/net/link-config.h | 1 +
|
||||||
|
src/udev/udev-builtin-net_setup_link.c | 2 ++
|
||||||
|
src/udev/udev-event.c | 45 ++++++++++++++++++++++----
|
||||||
|
src/udev/udev-event.h | 1 +
|
||||||
|
5 files changed, 55 insertions(+), 31 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/src/udev/net/link-config.c b/src/udev/net/link-config.c
|
||||||
|
index c9789bcb7c..2d8c902fd3 100644
|
||||||
|
--- a/src/udev/net/link-config.c
|
||||||
|
+++ b/src/udev/net/link-config.c
|
||||||
|
@@ -363,6 +363,7 @@ Link *link_free(Link *link) {
|
||||||
|
sd_device_unref(link->device);
|
||||||
|
free(link->kind);
|
||||||
|
free(link->driver);
|
||||||
|
+ strv_free(link->altnames);
|
||||||
|
return mfree(link);
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -791,19 +792,22 @@ no_rename:
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
-static int link_apply_alternative_names(Link *link, sd_netlink **rtnl) {
|
||||||
|
- _cleanup_strv_free_ char **altnames = NULL, **current_altnames = NULL;
|
||||||
|
+static int link_generate_alternative_names(Link *link) {
|
||||||
|
+ _cleanup_strv_free_ char **altnames = NULL;
|
||||||
|
LinkConfig *config;
|
||||||
|
sd_device *device;
|
||||||
|
int r;
|
||||||
|
|
||||||
|
assert(link);
|
||||||
|
- assert(link->config);
|
||||||
|
- assert(link->device);
|
||||||
|
- assert(rtnl);
|
||||||
|
+ config = ASSERT_PTR(link->config);
|
||||||
|
+ device = ASSERT_PTR(link->device);
|
||||||
|
+ assert(!link->altnames);
|
||||||
|
|
||||||
|
- config = link->config;
|
||||||
|
- device = link->device;
|
||||||
|
+ if (link->action != SD_DEVICE_ADD) {
|
||||||
|
+ log_link_debug(link, "Skipping to apply AlternativeNames= and AlternativeNamesPolicy= on '%s' uevent.",
|
||||||
|
+ device_action_to_string(link->action));
|
||||||
|
+ return 0;
|
||||||
|
+ }
|
||||||
|
|
||||||
|
if (config->alternative_names) {
|
||||||
|
altnames = strv_copy(config->alternative_names);
|
||||||
|
@@ -841,22 +845,7 @@ static int link_apply_alternative_names(Link *link, sd_netlink **rtnl) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
- strv_remove(altnames, link->ifname);
|
||||||
|
-
|
||||||
|
- r = rtnl_get_link_alternative_names(rtnl, link->ifindex, ¤t_altnames);
|
||||||
|
- if (r < 0)
|
||||||
|
- log_link_debug_errno(link, r, "Failed to get alternative names, ignoring: %m");
|
||||||
|
-
|
||||||
|
- STRV_FOREACH(p, current_altnames)
|
||||||
|
- strv_remove(altnames, *p);
|
||||||
|
-
|
||||||
|
- strv_uniq(altnames);
|
||||||
|
- strv_sort(altnames);
|
||||||
|
- r = rtnl_set_link_alternative_names(rtnl, link->ifindex, altnames);
|
||||||
|
- if (r < 0)
|
||||||
|
- log_link_full_errno(link, r == -EOPNOTSUPP ? LOG_DEBUG : LOG_WARNING, r,
|
||||||
|
- "Could not set AlternativeName= or apply AlternativeNamesPolicy=, ignoring: %m");
|
||||||
|
-
|
||||||
|
+ link->altnames = TAKE_PTR(altnames);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -958,7 +947,7 @@ int link_apply_config(LinkConfigContext *ctx, sd_netlink **rtnl, Link *link) {
|
||||||
|
if (r < 0)
|
||||||
|
return r;
|
||||||
|
|
||||||
|
- r = link_apply_alternative_names(link, rtnl);
|
||||||
|
+ r = link_generate_alternative_names(link);
|
||||||
|
if (r < 0)
|
||||||
|
return r;
|
||||||
|
|
||||||
|
diff --git a/src/udev/net/link-config.h b/src/udev/net/link-config.h
|
||||||
|
index ea9f560f45..874a391543 100644
|
||||||
|
--- a/src/udev/net/link-config.h
|
||||||
|
+++ b/src/udev/net/link-config.h
|
||||||
|
@@ -27,6 +27,7 @@ typedef struct Link {
|
||||||
|
int ifindex;
|
||||||
|
const char *ifname;
|
||||||
|
const char *new_name;
|
||||||
|
+ char **altnames;
|
||||||
|
|
||||||
|
LinkConfig *config;
|
||||||
|
sd_device *device;
|
||||||
|
diff --git a/src/udev/udev-builtin-net_setup_link.c b/src/udev/udev-builtin-net_setup_link.c
|
||||||
|
index 4bf42cd492..e964bf7bf4 100644
|
||||||
|
--- a/src/udev/udev-builtin-net_setup_link.c
|
||||||
|
+++ b/src/udev/udev-builtin-net_setup_link.c
|
||||||
|
@@ -49,6 +49,8 @@ static int builtin_net_setup_link(UdevEvent *event, int argc, char **argv, bool
|
||||||
|
if (link->new_name)
|
||||||
|
udev_builtin_add_property(dev, test, "ID_NET_NAME", link->new_name);
|
||||||
|
|
||||||
|
+ event->altnames = TAKE_PTR(link->altnames);
|
||||||
|
+
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
diff --git a/src/udev/udev-event.c b/src/udev/udev-event.c
|
||||||
|
index 2662806d61..3315d34eff 100644
|
||||||
|
--- a/src/udev/udev-event.c
|
||||||
|
+++ b/src/udev/udev-event.c
|
||||||
|
@@ -88,6 +88,7 @@ UdevEvent *udev_event_free(UdevEvent *event) {
|
||||||
|
ordered_hashmap_free_free_free(event->seclabel_list);
|
||||||
|
free(event->program_result);
|
||||||
|
free(event->name);
|
||||||
|
+ strv_free(event->altnames);
|
||||||
|
|
||||||
|
return mfree(event);
|
||||||
|
}
|
||||||
|
@@ -918,9 +919,6 @@ static int rename_netif(UdevEvent *event) {
|
||||||
|
|
||||||
|
dev = ASSERT_PTR(event->dev);
|
||||||
|
|
||||||
|
- if (!device_for_action(dev, SD_DEVICE_ADD))
|
||||||
|
- return 0; /* Rename the interface only when it is added. */
|
||||||
|
-
|
||||||
|
r = sd_device_get_ifindex(dev, &ifindex);
|
||||||
|
if (r == -ENOENT)
|
||||||
|
return 0; /* Device is not a network interface. */
|
||||||
|
@@ -980,7 +978,7 @@ static int rename_netif(UdevEvent *event) {
|
||||||
|
goto revert;
|
||||||
|
}
|
||||||
|
|
||||||
|
- r = rtnl_set_link_name(&event->rtnl, ifindex, event->name, NULL);
|
||||||
|
+ r = rtnl_set_link_name(&event->rtnl, ifindex, event->name, event->altnames);
|
||||||
|
if (r < 0) {
|
||||||
|
if (r == -EBUSY) {
|
||||||
|
log_device_info(dev, "Network interface '%s' is already up, cannot rename to '%s'.",
|
||||||
|
@@ -1011,6 +1009,35 @@ revert:
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
+static int assign_altnames(UdevEvent *event) {
|
||||||
|
+ sd_device *dev = ASSERT_PTR(ASSERT_PTR(event)->dev);
|
||||||
|
+ int ifindex, r;
|
||||||
|
+ const char *s;
|
||||||
|
+
|
||||||
|
+ if (strv_isempty(event->altnames))
|
||||||
|
+ return 0;
|
||||||
|
+
|
||||||
|
+ r = sd_device_get_ifindex(dev, &ifindex);
|
||||||
|
+ if (r == -ENOENT)
|
||||||
|
+ return 0; /* Device is not a network interface. */
|
||||||
|
+ if (r < 0)
|
||||||
|
+ return log_device_warning_errno(dev, r, "Failed to get ifindex: %m");
|
||||||
|
+
|
||||||
|
+ r = sd_device_get_sysname(dev, &s);
|
||||||
|
+ if (r < 0)
|
||||||
|
+ return log_device_warning_errno(dev, r, "Failed to get sysname: %m");
|
||||||
|
+
|
||||||
|
+ /* Filter out the current interface name. */
|
||||||
|
+ strv_remove(event->altnames, s);
|
||||||
|
+
|
||||||
|
+ r = rtnl_append_link_alternative_names(&event->rtnl, ifindex, event->altnames);
|
||||||
|
+ if (r < 0)
|
||||||
|
+ log_device_full_errno(dev, r == -EOPNOTSUPP ? LOG_DEBUG : LOG_WARNING, r,
|
||||||
|
+ "Could not set AlternativeName= or apply AlternativeNamesPolicy=, ignoring: %m");
|
||||||
|
+
|
||||||
|
+ return 0;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
static int update_devnode(UdevEvent *event) {
|
||||||
|
sd_device *dev = ASSERT_PTR(ASSERT_PTR(event)->dev);
|
||||||
|
int r;
|
||||||
|
@@ -1163,9 +1190,13 @@ int udev_event_execute_rules(
|
||||||
|
|
||||||
|
DEVICE_TRACE_POINT(rules_finished, dev);
|
||||||
|
|
||||||
|
- r = rename_netif(event);
|
||||||
|
- if (r < 0)
|
||||||
|
- return r;
|
||||||
|
+ if (action == SD_DEVICE_ADD) {
|
||||||
|
+ r = rename_netif(event);
|
||||||
|
+ if (r < 0)
|
||||||
|
+ return r;
|
||||||
|
+ if (r == 0)
|
||||||
|
+ (void) assign_altnames(event);
|
||||||
|
+ }
|
||||||
|
|
||||||
|
r = update_devnode(event);
|
||||||
|
if (r < 0)
|
||||||
|
diff --git a/src/udev/udev-event.h b/src/udev/udev-event.h
|
||||||
|
index 74d065ce23..13bd85dcf7 100644
|
||||||
|
--- a/src/udev/udev-event.h
|
||||||
|
+++ b/src/udev/udev-event.h
|
||||||
|
@@ -23,6 +23,7 @@ typedef struct UdevEvent {
|
||||||
|
sd_device *dev_parent;
|
||||||
|
sd_device *dev_db_clone;
|
||||||
|
char *name;
|
||||||
|
+ char **altnames;
|
||||||
|
char *program_result;
|
||||||
|
mode_t mode;
|
||||||
|
uid_t uid;
|
@ -0,0 +1,105 @@
|
|||||||
|
From dec129d192c7815bdfbb71c88a1d7cdc3092f11f Mon Sep 17 00:00:00 2001
|
||||||
|
From: Yu Watanabe <watanabe.yu+github@gmail.com>
|
||||||
|
Date: Tue, 16 May 2023 16:28:54 +0900
|
||||||
|
Subject: [PATCH] test: add tests for renaming network interface
|
||||||
|
|
||||||
|
(cherry picked from commit 40b6b448bda5294582e685091123952fbcd43502)
|
||||||
|
|
||||||
|
Related: RHEL-5988
|
||||||
|
---
|
||||||
|
test/units/testsuite-17.12.sh | 86 +++++++++++++++++++++++++++++++++++
|
||||||
|
1 file changed, 86 insertions(+)
|
||||||
|
create mode 100755 test/units/testsuite-17.12.sh
|
||||||
|
|
||||||
|
diff --git a/test/units/testsuite-17.12.sh b/test/units/testsuite-17.12.sh
|
||||||
|
new file mode 100755
|
||||||
|
index 0000000000..df74d356ee
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/test/units/testsuite-17.12.sh
|
||||||
|
@@ -0,0 +1,86 @@
|
||||||
|
+#!/usr/bin/env bash
|
||||||
|
+# SPDX-License-Identifier: LGPL-2.1-or-later
|
||||||
|
+set -ex
|
||||||
|
+set -o pipefail
|
||||||
|
+
|
||||||
|
+# shellcheck source=test/units/assert.sh
|
||||||
|
+. "$(dirname "$0")"/assert.sh
|
||||||
|
+
|
||||||
|
+create_link_file() {
|
||||||
|
+ name=${1?}
|
||||||
|
+
|
||||||
|
+ mkdir -p /run/systemd/network/
|
||||||
|
+ cat >/run/systemd/network/10-test.link <<EOF
|
||||||
|
+[Match]
|
||||||
|
+Kind=dummy
|
||||||
|
+MACAddress=00:50:56:c0:00:18
|
||||||
|
+
|
||||||
|
+[Link]
|
||||||
|
+Name=$name
|
||||||
|
+AlternativeName=test1 test2 test3 test4
|
||||||
|
+EOF
|
||||||
|
+ udevadm control --reload
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+udevadm control --log-level=debug
|
||||||
|
+
|
||||||
|
+create_link_file test1
|
||||||
|
+ip link add address 00:50:56:c0:00:18 type dummy
|
||||||
|
+udevadm wait --settle --timeout=30 /sys/class/net/test1
|
||||||
|
+output=$(ip link show dev test1)
|
||||||
|
+if ! [[ "$output" =~ altname ]]; then
|
||||||
|
+ echo "alternative name for network interface not supported, skipping test."
|
||||||
|
+ exit 0
|
||||||
|
+fi
|
||||||
|
+assert_not_in "altname test1" "$output"
|
||||||
|
+assert_in "altname test2" "$output"
|
||||||
|
+assert_in "altname test3" "$output"
|
||||||
|
+assert_in "altname test4" "$output"
|
||||||
|
+
|
||||||
|
+# By triggering add event, Name= and AlternativeNames= are re-applied
|
||||||
|
+create_link_file test2
|
||||||
|
+udevadm trigger --action add --settle /sys/class/net/test1
|
||||||
|
+udevadm wait --settle --timeout=30 /sys/class/net/test2
|
||||||
|
+output=$(ip link show dev test2)
|
||||||
|
+assert_in "altname test1" "$output"
|
||||||
|
+assert_not_in "altname test2" "$output"
|
||||||
|
+assert_in "altname test3" "$output"
|
||||||
|
+assert_in "altname test4" "$output"
|
||||||
|
+
|
||||||
|
+# Name= and AlternativeNames= are not applied on move event
|
||||||
|
+create_link_file test3
|
||||||
|
+udevadm trigger --action move --settle /sys/class/net/test2
|
||||||
|
+udevadm wait --settle --timeout=30 /sys/class/net/test2
|
||||||
|
+output=$(ip link show dev test2)
|
||||||
|
+assert_in "altname test1" "$output"
|
||||||
|
+assert_not_in "altname test2" "$output"
|
||||||
|
+assert_in "altname test3" "$output"
|
||||||
|
+assert_in "altname test4" "$output"
|
||||||
|
+
|
||||||
|
+# Test move event triggered by manual renaming
|
||||||
|
+ip link set dev test2 name hoge
|
||||||
|
+udevadm wait --settle --timeout=30 /sys/class/net/hoge
|
||||||
|
+output=$(ip link show dev hoge)
|
||||||
|
+assert_in "altname test1" "$output"
|
||||||
|
+assert_not_in "altname test2" "$output"
|
||||||
|
+assert_in "altname test3" "$output"
|
||||||
|
+assert_in "altname test4" "$output"
|
||||||
|
+assert_not_in "altname hoge" "$output"
|
||||||
|
+
|
||||||
|
+# Re-test add event
|
||||||
|
+udevadm trigger --action add --settle /sys/class/net/hoge
|
||||||
|
+udevadm wait --settle --timeout=30 /sys/class/net/test3
|
||||||
|
+output=$(ip link show dev test3)
|
||||||
|
+assert_in "altname test1" "$output"
|
||||||
|
+assert_in "altname test2" "$output"
|
||||||
|
+assert_not_in "altname test3" "$output"
|
||||||
|
+assert_in "altname test4" "$output"
|
||||||
|
+assert_not_in "altname hoge" "$output"
|
||||||
|
+
|
||||||
|
+# cleanup
|
||||||
|
+ip link del dev test3
|
||||||
|
+
|
||||||
|
+rm -f /run/systemd/network/10-test.link
|
||||||
|
+udevadm control --reload --log-level=info
|
||||||
|
+
|
||||||
|
+exit 0
|
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,54 @@
|
|||||||
|
From 27e95f2513e24a6abc26c56f05c67c34492442d7 Mon Sep 17 00:00:00 2001
|
||||||
|
From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= <zbyszek@in.waw.pl>
|
||||||
|
Date: Tue, 15 Nov 2022 15:00:57 +0100
|
||||||
|
Subject: [PATCH] bootctl: make --json output normal json
|
||||||
|
|
||||||
|
We would output a sequence of concatenated JSON strings. 'jq' accepts such
|
||||||
|
output without fuss, and can even automatically build an array with --slurp/-s.
|
||||||
|
Nevertheless, parsing this format is more effort for the reader, since it's not
|
||||||
|
"standard JSON". E.g. Python's json module cannot do this out-of-the-box, but
|
||||||
|
needs some loop with json.JSONDecoder.raw_decode() and then collecting the
|
||||||
|
objects into an array. Such streaming output make sense in case of logs, where
|
||||||
|
we stream the output and it has no predefined length. But here we expect at
|
||||||
|
most a few dozen entries, so it's nicer to write normal JSON that is trivial to
|
||||||
|
parse.
|
||||||
|
|
||||||
|
I'm treating this is a bugfix and not attempting to provide compatibility
|
||||||
|
backwards. I don't think the previous format was seeing much use, and it's
|
||||||
|
trivial to adapt to the new one.
|
||||||
|
|
||||||
|
(cherry picked from commit b570204a97bccfbfce8fc4ffa65306f8a06fe16e)
|
||||||
|
|
||||||
|
Related: RHEL-13199
|
||||||
|
---
|
||||||
|
src/shared/bootspec.c | 8 +++++++-
|
||||||
|
1 file changed, 7 insertions(+), 1 deletion(-)
|
||||||
|
|
||||||
|
diff --git a/src/shared/bootspec.c b/src/shared/bootspec.c
|
||||||
|
index d3cfb41a12..fe44b5e9d2 100644
|
||||||
|
--- a/src/shared/bootspec.c
|
||||||
|
+++ b/src/shared/bootspec.c
|
||||||
|
@@ -1408,6 +1408,8 @@ int show_boot_entries(const BootConfig *config, JsonFormatFlags json_format) {
|
||||||
|
assert(config);
|
||||||
|
|
||||||
|
if (!FLAGS_SET(json_format, JSON_FORMAT_OFF)) {
|
||||||
|
+ _cleanup_(json_variant_unrefp) JsonVariant *array = NULL;
|
||||||
|
+
|
||||||
|
for (size_t i = 0; i < config->n_entries; i++) {
|
||||||
|
_cleanup_free_ char *opts = NULL;
|
||||||
|
const BootEntry *e = config->entries + i;
|
||||||
|
@@ -1447,9 +1449,13 @@ int show_boot_entries(const BootConfig *config, JsonFormatFlags json_format) {
|
||||||
|
if (r < 0)
|
||||||
|
return log_oom();
|
||||||
|
|
||||||
|
- json_variant_dump(v, json_format, stdout, NULL);
|
||||||
|
+ r = json_variant_append_array(&array, v);
|
||||||
|
+ if (r < 0)
|
||||||
|
+ return log_oom();
|
||||||
|
}
|
||||||
|
|
||||||
|
+ json_variant_dump(array, json_format, NULL, NULL);
|
||||||
|
+
|
||||||
|
} else {
|
||||||
|
for (size_t n = 0; n < config->n_entries; n++) {
|
||||||
|
r = show_boot_entry(
|
@ -0,0 +1,28 @@
|
|||||||
|
From 8fced1b2ed30b9cda338c35946d8dcc3820ac25a Mon Sep 17 00:00:00 2001
|
||||||
|
From: Frantisek Sumsal <frantisek@sumsal.cz>
|
||||||
|
Date: Wed, 5 Jul 2023 19:43:43 +0200
|
||||||
|
Subject: [PATCH] test: replace readfp() with read_file()
|
||||||
|
|
||||||
|
ConfigParser.readfp() has been deprecated since Python 3.2 and was
|
||||||
|
dropped completely in Python 3.11.
|
||||||
|
|
||||||
|
(cherry picked from commit ba4a1cd8a863f65ff016be72e520c323aa1e1a6f)
|
||||||
|
|
||||||
|
Related: RHEL-13199
|
||||||
|
---
|
||||||
|
test/sysv-generator-test.py | 2 +-
|
||||||
|
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||||
|
|
||||||
|
diff --git a/test/sysv-generator-test.py b/test/sysv-generator-test.py
|
||||||
|
index 484b610a02..84237bab61 100755
|
||||||
|
--- a/test/sysv-generator-test.py
|
||||||
|
+++ b/test/sysv-generator-test.py
|
||||||
|
@@ -80,7 +80,7 @@ class SysvGeneratorTest(unittest.TestCase):
|
||||||
|
cp = RawConfigParser(dict_type=MultiDict)
|
||||||
|
cp.optionxform = lambda o: o # don't lower-case option names
|
||||||
|
with open(service) as f:
|
||||||
|
- cp.readfp(f)
|
||||||
|
+ cp.read_file(f)
|
||||||
|
results[os.path.basename(service)] = cp
|
||||||
|
|
||||||
|
return (err, results)
|
@ -0,0 +1,81 @@
|
|||||||
|
From fe66c5955044cf2b93fa788ae7bdfe3a07f11449 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Luca Boccassi <bluca@debian.org>
|
||||||
|
Date: Sun, 21 May 2023 14:32:09 +0100
|
||||||
|
Subject: [PATCH] stub/measure: document and measure .uname UKI section
|
||||||
|
|
||||||
|
(cherry picked from commit b6f2e6860220aa89550f690b12246c4e8eb6e908)
|
||||||
|
|
||||||
|
Resolves: RHEL-13199
|
||||||
|
---
|
||||||
|
man/systemd-stub.xml | 3 +++
|
||||||
|
src/boot/measure.c | 3 +++
|
||||||
|
src/fundamental/tpm-pcr.c | 1 +
|
||||||
|
src/fundamental/tpm-pcr.h | 1 +
|
||||||
|
4 files changed, 8 insertions(+)
|
||||||
|
|
||||||
|
diff --git a/man/systemd-stub.xml b/man/systemd-stub.xml
|
||||||
|
index 415d663f53..85d30129d6 100644
|
||||||
|
--- a/man/systemd-stub.xml
|
||||||
|
+++ b/man/systemd-stub.xml
|
||||||
|
@@ -57,6 +57,9 @@
|
||||||
|
<citerefentry><refentrytitle>os-release</refentrytitle><manvolnum>5</manvolnum></citerefentry> file of
|
||||||
|
the OS the kernel belongs to, in the <literal>.osrel</literal> PE section.</para></listitem>
|
||||||
|
|
||||||
|
+ <listitem><para>Kernel version information, i.e. the output of <command>uname -r</command> for the
|
||||||
|
+ kernel included in the UKI, in the <literal>.uname</literal> PE section.</para></listitem>
|
||||||
|
+
|
||||||
|
<listitem><para>The initrd will be loaded from the <literal>.initrd</literal> PE section.
|
||||||
|
</para></listitem>
|
||||||
|
|
||||||
|
diff --git a/src/boot/measure.c b/src/boot/measure.c
|
||||||
|
index 0bbd386449..67ab84753e 100644
|
||||||
|
--- a/src/boot/measure.c
|
||||||
|
+++ b/src/boot/measure.c
|
||||||
|
@@ -79,6 +79,7 @@ static int help(int argc, char *argv[], void *userdata) {
|
||||||
|
" --initrd=PATH Path to initrd image file %7$s .initrd\n"
|
||||||
|
" --splash=PATH Path to splash bitmap file %7$s .splash\n"
|
||||||
|
" --dtb=PATH Path to Devicetree file %7$s .dtb\n"
|
||||||
|
+ " --uname=PATH Path to 'uname -r' file %7$s .uname\n"
|
||||||
|
" --pcrpkey=PATH Path to public key for PCR signatures %7$s .pcrpkey\n"
|
||||||
|
"\nSee the %2$s for details.\n",
|
||||||
|
program_invocation_short_name,
|
||||||
|
@@ -118,6 +119,7 @@ static int parse_argv(int argc, char *argv[]) {
|
||||||
|
ARG_INITRD,
|
||||||
|
ARG_SPLASH,
|
||||||
|
ARG_DTB,
|
||||||
|
+ ARG_UNAME,
|
||||||
|
_ARG_PCRSIG, /* the .pcrsig section is not input for signing, hence not actually an argument here */
|
||||||
|
_ARG_SECTION_LAST,
|
||||||
|
ARG_PCRPKEY = _ARG_SECTION_LAST,
|
||||||
|
@@ -139,6 +141,7 @@ static int parse_argv(int argc, char *argv[]) {
|
||||||
|
{ "initrd", required_argument, NULL, ARG_INITRD },
|
||||||
|
{ "splash", required_argument, NULL, ARG_SPLASH },
|
||||||
|
{ "dtb", required_argument, NULL, ARG_DTB },
|
||||||
|
+ { "uname", required_argument, NULL, ARG_UNAME },
|
||||||
|
{ "pcrpkey", required_argument, NULL, ARG_PCRPKEY },
|
||||||
|
{ "current", no_argument, NULL, 'c' },
|
||||||
|
{ "bank", required_argument, NULL, ARG_BANK },
|
||||||
|
diff --git a/src/fundamental/tpm-pcr.c b/src/fundamental/tpm-pcr.c
|
||||||
|
index 7609d83c2e..0685d37b05 100644
|
||||||
|
--- a/src/fundamental/tpm-pcr.c
|
||||||
|
+++ b/src/fundamental/tpm-pcr.c
|
||||||
|
@@ -11,6 +11,7 @@ const char* const unified_sections[_UNIFIED_SECTION_MAX + 1] = {
|
||||||
|
[UNIFIED_SECTION_INITRD] = ".initrd",
|
||||||
|
[UNIFIED_SECTION_SPLASH] = ".splash",
|
||||||
|
[UNIFIED_SECTION_DTB] = ".dtb",
|
||||||
|
+ [UNIFIED_SECTION_UNAME] = ".uname",
|
||||||
|
[UNIFIED_SECTION_PCRSIG] = ".pcrsig",
|
||||||
|
[UNIFIED_SECTION_PCRPKEY] = ".pcrpkey",
|
||||||
|
NULL,
|
||||||
|
diff --git a/src/fundamental/tpm-pcr.h b/src/fundamental/tpm-pcr.h
|
||||||
|
index 235d4841b0..24240b82ed 100644
|
||||||
|
--- a/src/fundamental/tpm-pcr.h
|
||||||
|
+++ b/src/fundamental/tpm-pcr.h
|
||||||
|
@@ -34,6 +34,7 @@ typedef enum UnifiedSection {
|
||||||
|
UNIFIED_SECTION_INITRD,
|
||||||
|
UNIFIED_SECTION_SPLASH,
|
||||||
|
UNIFIED_SECTION_DTB,
|
||||||
|
+ UNIFIED_SECTION_UNAME,
|
||||||
|
UNIFIED_SECTION_PCRSIG,
|
||||||
|
UNIFIED_SECTION_PCRPKEY,
|
||||||
|
_UNIFIED_SECTION_MAX,
|
@ -0,0 +1,96 @@
|
|||||||
|
From 16b3bb1a1bb8a0a42ad6eb56fd33dcb800c8af04 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Luca Boccassi <bluca@debian.org>
|
||||||
|
Date: Thu, 29 Jun 2023 23:41:48 +0100
|
||||||
|
Subject: [PATCH] boot: measure .sbat section
|
||||||
|
|
||||||
|
We are now merging .sbat sections from sd-stub and kernel image, so
|
||||||
|
measure it in PCR11.
|
||||||
|
|
||||||
|
(cherry picked from commit d5f91cf79361cab58e32bf7b76c41ba244add75f)
|
||||||
|
|
||||||
|
Resolves: RHEL-13199
|
||||||
|
---
|
||||||
|
man/systemd-measure.xml | 8 +++++---
|
||||||
|
src/boot/measure.c | 3 +++
|
||||||
|
src/fundamental/tpm-pcr.c | 1 +
|
||||||
|
src/fundamental/tpm-pcr.h | 1 +
|
||||||
|
4 files changed, 10 insertions(+), 3 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/man/systemd-measure.xml b/man/systemd-measure.xml
|
||||||
|
index 46fc979654..e08dbcdac9 100644
|
||||||
|
--- a/man/systemd-measure.xml
|
||||||
|
+++ b/man/systemd-measure.xml
|
||||||
|
@@ -66,9 +66,10 @@
|
||||||
|
<listitem><para>Pre-calculate the expected values seen in PCR register 11 after boot-up of a unified
|
||||||
|
kernel image consisting of the components specified with <option>--linux=</option>,
|
||||||
|
<option>--osrel=</option>, <option>--cmdline=</option>, <option>--initrd=</option>,
|
||||||
|
- <option>--splash=</option>, <option>--dtb=</option>, <option>--pcrpkey=</option> see below. Only
|
||||||
|
- <option>--linux=</option> is mandatory. (Alternatively, specify <option>--current</option> to use the
|
||||||
|
- current values of PCR register 11 instead.)</para></listitem>
|
||||||
|
+ <option>--splash=</option>, <option>--dtb=</option>, <option>--sbat=</option>,
|
||||||
|
+ <option>--pcrpkey=</option> see below. Only <option>--linux=</option> is mandatory. (Alternatively,
|
||||||
|
+ specify <option>--current</option> to use the current values of PCR register 11 instead.)</para>
|
||||||
|
+ </listitem>
|
||||||
|
</varlistentry>
|
||||||
|
|
||||||
|
<varlistentry>
|
||||||
|
@@ -104,6 +105,7 @@
|
||||||
|
<term><option>--initrd=PATH</option></term>
|
||||||
|
<term><option>--splash=PATH</option></term>
|
||||||
|
<term><option>--dtb=PATH</option></term>
|
||||||
|
+ <term><option>--sbat=PATH</option></term>
|
||||||
|
<term><option>--pcrpkey=PATH</option></term>
|
||||||
|
|
||||||
|
<listitem><para>When used with the <command>calculate</command> or <command>sign</command> verb,
|
||||||
|
diff --git a/src/boot/measure.c b/src/boot/measure.c
|
||||||
|
index 67ab84753e..84a7c357a4 100644
|
||||||
|
--- a/src/boot/measure.c
|
||||||
|
+++ b/src/boot/measure.c
|
||||||
|
@@ -80,6 +80,7 @@ static int help(int argc, char *argv[], void *userdata) {
|
||||||
|
" --splash=PATH Path to splash bitmap file %7$s .splash\n"
|
||||||
|
" --dtb=PATH Path to Devicetree file %7$s .dtb\n"
|
||||||
|
" --uname=PATH Path to 'uname -r' file %7$s .uname\n"
|
||||||
|
+ " --sbat=PATH Path to SBAT file %7$s .sbat\n"
|
||||||
|
" --pcrpkey=PATH Path to public key for PCR signatures %7$s .pcrpkey\n"
|
||||||
|
"\nSee the %2$s for details.\n",
|
||||||
|
program_invocation_short_name,
|
||||||
|
@@ -120,6 +121,7 @@ static int parse_argv(int argc, char *argv[]) {
|
||||||
|
ARG_SPLASH,
|
||||||
|
ARG_DTB,
|
||||||
|
ARG_UNAME,
|
||||||
|
+ ARG_SBAT,
|
||||||
|
_ARG_PCRSIG, /* the .pcrsig section is not input for signing, hence not actually an argument here */
|
||||||
|
_ARG_SECTION_LAST,
|
||||||
|
ARG_PCRPKEY = _ARG_SECTION_LAST,
|
||||||
|
@@ -142,6 +144,7 @@ static int parse_argv(int argc, char *argv[]) {
|
||||||
|
{ "splash", required_argument, NULL, ARG_SPLASH },
|
||||||
|
{ "dtb", required_argument, NULL, ARG_DTB },
|
||||||
|
{ "uname", required_argument, NULL, ARG_UNAME },
|
||||||
|
+ { "sbat", required_argument, NULL, ARG_SBAT },
|
||||||
|
{ "pcrpkey", required_argument, NULL, ARG_PCRPKEY },
|
||||||
|
{ "current", no_argument, NULL, 'c' },
|
||||||
|
{ "bank", required_argument, NULL, ARG_BANK },
|
||||||
|
diff --git a/src/fundamental/tpm-pcr.c b/src/fundamental/tpm-pcr.c
|
||||||
|
index 0685d37b05..2f7e9b428d 100644
|
||||||
|
--- a/src/fundamental/tpm-pcr.c
|
||||||
|
+++ b/src/fundamental/tpm-pcr.c
|
||||||
|
@@ -12,6 +12,7 @@ const char* const unified_sections[_UNIFIED_SECTION_MAX + 1] = {
|
||||||
|
[UNIFIED_SECTION_SPLASH] = ".splash",
|
||||||
|
[UNIFIED_SECTION_DTB] = ".dtb",
|
||||||
|
[UNIFIED_SECTION_UNAME] = ".uname",
|
||||||
|
+ [UNIFIED_SECTION_SBAT] = ".sbat",
|
||||||
|
[UNIFIED_SECTION_PCRSIG] = ".pcrsig",
|
||||||
|
[UNIFIED_SECTION_PCRPKEY] = ".pcrpkey",
|
||||||
|
NULL,
|
||||||
|
diff --git a/src/fundamental/tpm-pcr.h b/src/fundamental/tpm-pcr.h
|
||||||
|
index 24240b82ed..794d593825 100644
|
||||||
|
--- a/src/fundamental/tpm-pcr.h
|
||||||
|
+++ b/src/fundamental/tpm-pcr.h
|
||||||
|
@@ -35,6 +35,7 @@ typedef enum UnifiedSection {
|
||||||
|
UNIFIED_SECTION_SPLASH,
|
||||||
|
UNIFIED_SECTION_DTB,
|
||||||
|
UNIFIED_SECTION_UNAME,
|
||||||
|
+ UNIFIED_SECTION_SBAT,
|
||||||
|
UNIFIED_SECTION_PCRSIG,
|
||||||
|
UNIFIED_SECTION_PCRPKEY,
|
||||||
|
_UNIFIED_SECTION_MAX,
|
@ -0,0 +1,42 @@
|
|||||||
|
From 3c235c8d26813ae428053c284b67ddfe70d9caed Mon Sep 17 00:00:00 2001
|
||||||
|
From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= <zbyszek@in.waw.pl>
|
||||||
|
Date: Wed, 22 Nov 2023 15:38:47 +0100
|
||||||
|
Subject: [PATCH] Revert "test_ukify: no stinky root needed for signing"
|
||||||
|
|
||||||
|
This reverts commit 0d66468243d888dd721ba0072cbad742ab6fc690.
|
||||||
|
|
||||||
|
There was a huge rewrite of the tpm2 code that removed the requirement for
|
||||||
|
device access, but backporting that would be a huge effort. Let's instead skip
|
||||||
|
the tests for now. (They pass under root.)
|
||||||
|
|
||||||
|
Related: RHEL-13199
|
||||||
|
---
|
||||||
|
src/ukify/test/test_ukify.py | 8 ++++++++
|
||||||
|
1 file changed, 8 insertions(+)
|
||||||
|
|
||||||
|
diff --git a/src/ukify/test/test_ukify.py b/src/ukify/test/test_ukify.py
|
||||||
|
index b12c09d4bf..5a42a94799 100755
|
||||||
|
--- a/src/ukify/test/test_ukify.py
|
||||||
|
+++ b/src/ukify/test/test_ukify.py
|
||||||
|
@@ -661,6 +661,10 @@ def test_pcr_signing(kernel_initrd, tmpdir):
|
||||||
|
pytest.skip('linux+initrd not found')
|
||||||
|
if systemd_measure() is None:
|
||||||
|
pytest.skip('systemd-measure not found')
|
||||||
|
+ if os.getuid() != 0:
|
||||||
|
+ pytest.skip('must be root to access tpm2')
|
||||||
|
+ if subprocess.call(['systemd-creds', 'has-tpm2', '-q']) != 0:
|
||||||
|
+ pytest.skip('tpm2 is not available')
|
||||||
|
|
||||||
|
ourdir = pathlib.Path(__file__).parent
|
||||||
|
pub = unbase64(ourdir / 'example.tpm2-pcr-public.pem.base64')
|
||||||
|
@@ -724,6 +728,10 @@ def test_pcr_signing2(kernel_initrd, tmpdir):
|
||||||
|
pytest.skip('linux+initrd not found')
|
||||||
|
if systemd_measure() is None:
|
||||||
|
pytest.skip('systemd-measure not found')
|
||||||
|
+ if os.getuid() != 0:
|
||||||
|
+ pytest.skip('must be root to access tpm2')
|
||||||
|
+ if subprocess.call(['systemd-creds', 'has-tpm2', '-q']) != 0:
|
||||||
|
+ pytest.skip('tpm2 is not available')
|
||||||
|
|
||||||
|
ourdir = pathlib.Path(__file__).parent
|
||||||
|
pub = unbase64(ourdir / 'example.tpm2-pcr-public.pem.base64')
|
@ -0,0 +1,36 @@
|
|||||||
|
From 2adec0d845e6d00a604ddaa5639759896b78728f Mon Sep 17 00:00:00 2001
|
||||||
|
From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= <zbyszek@in.waw.pl>
|
||||||
|
Date: Mon, 28 Aug 2023 18:22:43 +0300
|
||||||
|
Subject: [PATCH] ukify: move to /usr/bin and mark as non non-experimental
|
||||||
|
|
||||||
|
The tool is moved into the $PATH and a compat symlink is provided.
|
||||||
|
|
||||||
|
It is fairly widely used now, and realistically we need to keep backwards
|
||||||
|
compat or people will be very unhappy.
|
||||||
|
|
||||||
|
(cherry picked from commit f65aa477d90ab7fbbc50ba05c55180213d5992e0)
|
||||||
|
|
||||||
|
Related: RHEL-13199
|
||||||
|
---
|
||||||
|
meson.build | 6 +++++-
|
||||||
|
1 file changed, 5 insertions(+), 1 deletion(-)
|
||||||
|
|
||||||
|
diff --git a/meson.build b/meson.build
|
||||||
|
index b874c2f9b4..e0495ed36a 100644
|
||||||
|
--- a/meson.build
|
||||||
|
+++ b/meson.build
|
||||||
|
@@ -3861,9 +3861,13 @@ ukify = custom_target(
|
||||||
|
command : [jinja2_cmdline, '@INPUT@', '@OUTPUT@'],
|
||||||
|
install : want_ukify,
|
||||||
|
install_mode : 'rwxr-xr-x',
|
||||||
|
- install_dir : rootlibexecdir)
|
||||||
|
+ install_dir : bindir)
|
||||||
|
if want_ukify
|
||||||
|
public_programs += ukify
|
||||||
|
+
|
||||||
|
+ meson.add_install_script(sh, '-c',
|
||||||
|
+ ln_s.format(bindir / 'ukify',
|
||||||
|
+ rootlibexecdir / 'ukify'))
|
||||||
|
endif
|
||||||
|
|
||||||
|
if want_tests != 'false' and want_kernel_install
|
@ -0,0 +1,221 @@
|
|||||||
|
From 90f26ba66f256fd65c6e7c38ed6f2138fed6b3ed Mon Sep 17 00:00:00 2001
|
||||||
|
From: Joerg Behrmann <behrmann@physik.fu-berlin.de>
|
||||||
|
Date: Wed, 23 Nov 2022 16:43:19 +0100
|
||||||
|
Subject: [PATCH] kernel-install: Add uki layout
|
||||||
|
|
||||||
|
Currently the kernel-install man page only documents the bls layout for use
|
||||||
|
with the boot loader spec type #1. 90-loaderentry.install uses this layout to
|
||||||
|
generate loader entries and copy the kernel image and initrd to $BOOT.
|
||||||
|
|
||||||
|
This commit documents a second layout "uki" and adds 90-uki-copy.install,
|
||||||
|
which copies a UKI "uki.efi" from the staging area or any file with the .efi
|
||||||
|
extension given on the command line to
|
||||||
|
$BOOT/EFI/Linux/$ENTRY_TOKEN-$KERNEl_VERSION(+$TRIES).efi
|
||||||
|
|
||||||
|
This allows for both locally generated and distro-provided UKIs to be handled
|
||||||
|
by kernel-install.
|
||||||
|
|
||||||
|
(cherry picked from commit 0ccfd3564b2532a4da6526a9e030362c4a142b77)
|
||||||
|
|
||||||
|
Resolves: RHEL-16354
|
||||||
|
---
|
||||||
|
man/kernel-install.xml | 38 ++++++++--
|
||||||
|
src/kernel-install/90-uki-copy.install | 97 ++++++++++++++++++++++++++
|
||||||
|
src/kernel-install/meson.build | 2 +
|
||||||
|
3 files changed, 131 insertions(+), 6 deletions(-)
|
||||||
|
create mode 100755 src/kernel-install/90-uki-copy.install
|
||||||
|
|
||||||
|
diff --git a/man/kernel-install.xml b/man/kernel-install.xml
|
||||||
|
index b8ea2b16b2..b1822a8847 100644
|
||||||
|
--- a/man/kernel-install.xml
|
||||||
|
+++ b/man/kernel-install.xml
|
||||||
|
@@ -108,6 +108,14 @@
|
||||||
|
is missing), or "Linux <replaceable>KERNEL-VERSION</replaceable>", if unset.</para>
|
||||||
|
|
||||||
|
<para>If <varname>$KERNEL_INSTALL_LAYOUT</varname> is not "bls", this plugin does nothing.</para></listitem>
|
||||||
|
+
|
||||||
|
+ <listitem><para><filename>90-uki-copy.install</filename> copies a file
|
||||||
|
+ <filename>uki.efi</filename> from <varname>$KERNEL_INSTALL_STAGING_AREA</varname> or if it does
|
||||||
|
+ not exist the <replaceable>KERNEL-IMAGE</replaceable> argument, iff it has a
|
||||||
|
+ <literal>.efi</literal> extension, to
|
||||||
|
+ <filename>$BOOT/EFI/Linux/<replaceable>ENTRY-TOKEN</replaceable>-<replaceable>KERNEL-VERSION</replaceable>.efi</filename>.</para>
|
||||||
|
+
|
||||||
|
+ <para>If <varname>$KERNEL_INSTALL_LAYOUT</varname> is not "uki", this plugin does nothing.</para></listitem>
|
||||||
|
</itemizedlist>
|
||||||
|
</listitem>
|
||||||
|
</varlistentry>
|
||||||
|
@@ -132,6 +140,9 @@
|
||||||
|
|
||||||
|
<listitem><para><filename>90-loaderentry.install</filename> removes the file
|
||||||
|
<filename>$BOOT/loader/entries/<replaceable>ENTRY-TOKEN</replaceable>-<replaceable>KERNEL-VERSION</replaceable>.conf</filename>.</para></listitem>
|
||||||
|
+
|
||||||
|
+ <listitem><para><filename>90-uki-copy.install</filename> removes the file
|
||||||
|
+ <filename>$BOOT/EFI/Linux/<replaceable>ENTRY-TOKEN</replaceable>-<replaceable>KERNEL-VERSION</replaceable>.efi</filename>.</para></listitem>
|
||||||
|
</itemizedlist>
|
||||||
|
</listitem>
|
||||||
|
</varlistentry>
|
||||||
|
@@ -213,7 +224,7 @@
|
||||||
|
(EFI System Partition) are mounted, and also conceptually referred to as <varname>$BOOT</varname>. Can
|
||||||
|
be overridden by setting <varname>$BOOT_ROOT</varname> (see below).</para>
|
||||||
|
|
||||||
|
- <para><varname>$KERNEL_INSTALL_LAYOUT=bls|other|...</varname> is set for the plugins to specify the
|
||||||
|
+ <para><varname>$KERNEL_INSTALL_LAYOUT=bls|uki|other|...</varname> is set for the plugins to specify the
|
||||||
|
installation layout. Defaults to <option>bls</option> if
|
||||||
|
<filename>$BOOT/<replaceable>ENTRY-TOKEN</replaceable></filename> exists, or <option>other</option>
|
||||||
|
otherwise. Additional layout names may be defined by convention. If a plugin uses a special layout,
|
||||||
|
@@ -235,6 +246,18 @@
|
||||||
|
<para>Implemented by <filename>90-loaderentry.install</filename>.</para>
|
||||||
|
</listitem>
|
||||||
|
</varlistentry>
|
||||||
|
+ <varlistentry>
|
||||||
|
+ <term>uki</term>
|
||||||
|
+ <listitem>
|
||||||
|
+ <para>Standard <ulink
|
||||||
|
+ url="https://uapi-group.org/specifications/specs/boot_loader_specification">Boot Loader
|
||||||
|
+ Specification</ulink> Type #2 layout, compatible with
|
||||||
|
+ <citerefentry><refentrytitle>systemd-boot</refentrytitle><manvolnum>7</manvolnum></citerefentry>:
|
||||||
|
+ unified kernel images under <filename>$BOOT/EFI/Linux</filename> as
|
||||||
|
+ <filename>$BOOT/EFI/Linux/<replaceable>ENTRY-TOKEN</replaceable>-<replaceable>KERNEL-VERSION</replaceable>[+<replaceable>TRIES</replaceable>].efi</filename>.</para>
|
||||||
|
+ <para>Implemented by <filename>90-uki-copy.install</filename>.</para>
|
||||||
|
+ </listitem>
|
||||||
|
+ </varlistentry>
|
||||||
|
<varlistentry>
|
||||||
|
<term>other</term>
|
||||||
|
<listitem>
|
||||||
|
@@ -312,12 +335,15 @@
|
||||||
|
<filename>/etc/kernel/tries</filename>
|
||||||
|
</term>
|
||||||
|
<listitem>
|
||||||
|
- <para>Read by <filename>90-loaderentry.install</filename>. If this file exists a numeric value is read from
|
||||||
|
- it and the naming of the generated entry file is slightly altered to include it as
|
||||||
|
- <filename>$BOOT/loader/entries/<replaceable>MACHINE-ID</replaceable>-<replaceable>KERNEL-VERSION</replaceable>+<replaceable>TRIES</replaceable>.conf</filename>. This
|
||||||
|
+ <para>Read by <filename>90-loaderentry.install</filename> and
|
||||||
|
+ <filename>90-uki-copy.install</filename>. If this file exists a numeric value is read from it
|
||||||
|
+ and the naming of the generated entry file or UKI is slightly altered to include it as
|
||||||
|
+ <filename>$BOOT/loader/entries/<replaceable>ENTRY-TOKEN</replaceable>-<replaceable>KERNEL-VERSION</replaceable>+<replaceable>TRIES</replaceable>.conf</filename>
|
||||||
|
+ or
|
||||||
|
+ <filename>$BOOT/EFI/Linux/<replaceable>ENTRY-TOKEN</replaceable>-<replaceable>KERNEL-VERSION</replaceable>+<replaceable>TRIES</replaceable>.conf</filename>, respectively. This
|
||||||
|
is useful for boot loaders such as
|
||||||
|
- <citerefentry><refentrytitle>systemd-boot</refentrytitle><manvolnum>7</manvolnum></citerefentry> which
|
||||||
|
- implement boot attempt counting with a counter embedded in the entry file name.
|
||||||
|
+ <citerefentry><refentrytitle>systemd-boot</refentrytitle><manvolnum>7</manvolnum></citerefentry>
|
||||||
|
+ which implement boot attempt counting with a counter embedded in the entry file name.
|
||||||
|
<varname>$KERNEL_INSTALL_CONF_ROOT</varname> may be used to override the path.</para>
|
||||||
|
</listitem>
|
||||||
|
</varlistentry>
|
||||||
|
diff --git a/src/kernel-install/90-uki-copy.install b/src/kernel-install/90-uki-copy.install
|
||||||
|
new file mode 100755
|
||||||
|
index 0000000000..d6e3deb723
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/src/kernel-install/90-uki-copy.install
|
||||||
|
@@ -0,0 +1,97 @@
|
||||||
|
+#!/bin/sh
|
||||||
|
+# -*- mode: shell-script; indent-tabs-mode: nil; sh-basic-offset: 4; -*-
|
||||||
|
+# ex: ts=8 sw=4 sts=4 et filetype=sh
|
||||||
|
+# SPDX-License-Identifier: LGPL-2.1-or-later
|
||||||
|
+#
|
||||||
|
+# This file is part of systemd.
|
||||||
|
+#
|
||||||
|
+# systemd is free software; you can redistribute it and/or modify it
|
||||||
|
+# under the terms of the GNU Lesser General Public License as published by
|
||||||
|
+# the Free Software Foundation; either version 2.1 of the License, or
|
||||||
|
+# (at your option) any later version.
|
||||||
|
+#
|
||||||
|
+# systemd is distributed in the hope that it will be useful, but
|
||||||
|
+# WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
+# General Public License for more details.
|
||||||
|
+#
|
||||||
|
+# You should have received a copy of the GNU Lesser General Public License
|
||||||
|
+# along with systemd; If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
+
|
||||||
|
+set -e
|
||||||
|
+
|
||||||
|
+COMMAND="${1:?}"
|
||||||
|
+KERNEL_VERSION="${2:?}"
|
||||||
|
+# shellcheck disable=SC2034
|
||||||
|
+ENTRY_DIR_ABS="$3"
|
||||||
|
+KERNEL_IMAGE="$4"
|
||||||
|
+
|
||||||
|
+[ "$KERNEL_INSTALL_LAYOUT" = "uki" ] || exit 0
|
||||||
|
+
|
||||||
|
+ENTRY_TOKEN="$KERNEL_INSTALL_ENTRY_TOKEN"
|
||||||
|
+BOOT_ROOT="$KERNEL_INSTALL_BOOT_ROOT"
|
||||||
|
+
|
||||||
|
+UKI_DIR="$BOOT_ROOT/EFI/Linux"
|
||||||
|
+
|
||||||
|
+case "$COMMAND" in
|
||||||
|
+ remove)
|
||||||
|
+ [ "$KERNEL_INSTALL_VERBOSE" -gt 0 ] && \
|
||||||
|
+ echo "Removing $UKI_DIR/$ENTRY_TOKEN-$KERNEL_VERSION*.efi"
|
||||||
|
+ exec rm -f \
|
||||||
|
+ "$UKI_DIR/$ENTRY_TOKEN-$KERNEL_VERSION.efi" \
|
||||||
|
+ "$UKI_DIR/$ENTRY_TOKEN-$KERNEL_VERSION+"*".efi"
|
||||||
|
+ ;;
|
||||||
|
+ add)
|
||||||
|
+ ;;
|
||||||
|
+ *)
|
||||||
|
+ exit 0
|
||||||
|
+ ;;
|
||||||
|
+esac
|
||||||
|
+
|
||||||
|
+if ! [ -d "$UKI_DIR" ]; then
|
||||||
|
+ echo "Error: entry directory '$UKI_DIR' does not exist" >&2
|
||||||
|
+ exit 1
|
||||||
|
+fi
|
||||||
|
+
|
||||||
|
+TRIES_FILE="${KERNEL_INSTALL_CONF_ROOT:-/etc/kernel}/tries"
|
||||||
|
+
|
||||||
|
+if [ -f "$TRIES_FILE" ]; then
|
||||||
|
+ read -r TRIES <"$TRIES_FILE"
|
||||||
|
+ if ! echo "$TRIES" | grep -q '^[0-9][0-9]*$'; then
|
||||||
|
+ echo "$TRIES_FILE does not contain an integer." >&2
|
||||||
|
+ exit 1
|
||||||
|
+ fi
|
||||||
|
+ UKI_FILE="$UKI_DIR/$ENTRY_TOKEN-$KERNEL_VERSION+$TRIES.efi"
|
||||||
|
+else
|
||||||
|
+ UKI_FILE="$UKI_DIR/$ENTRY_TOKEN-$KERNEL_VERSION.efi"
|
||||||
|
+fi
|
||||||
|
+
|
||||||
|
+# If there is a UKI named uki.efi on the staging area use that, if not use what
|
||||||
|
+# was passed in as $KERNEL_IMAGE but insist it has a .efi extension
|
||||||
|
+if [ -f "$KERNEL_INSTALL_STAGING_AREA/uki.efi" ]; then
|
||||||
|
+ [ "$KERNEL_INSTALL_VERBOSE" -gt 0 ] && echo "Installing $KERNEL_INSTALL_STAGING_AREA/uki.efi"
|
||||||
|
+ install -m 0644 "$KERNEL_INSTALL_STAGING_AREA/uki.efi" "$UKI_FILE" || {
|
||||||
|
+ echo "Error: could not copy '$KERNEL_INSTALL_STAGING_AREA/uki.efi' to '$UKI_FILE'." >&2
|
||||||
|
+ exit 1
|
||||||
|
+ }
|
||||||
|
+elif [ -n "$KERNEL_IMAGE" ]; then
|
||||||
|
+ [ -f "$KERNEL_IMAGE" ] || {
|
||||||
|
+ echo "Error: UKI '$KERNEL_IMAGE' not a file." >&2
|
||||||
|
+ exit 1
|
||||||
|
+ }
|
||||||
|
+ [ "$KERNEL_IMAGE" != "${KERNEL_IMAGE%*.efi}.efi" ] && {
|
||||||
|
+ echo "Error: $KERNEL_IMAGE is missing .efi suffix." >&2
|
||||||
|
+ exit 1
|
||||||
|
+ }
|
||||||
|
+ [ "$KERNEL_INSTALL_VERBOSE" -gt 0 ] && echo "Installing $KERNEL_IMAGE"
|
||||||
|
+ install -m 0644 "$KERNEL_IMAGE" "$UKI_FILE" || {
|
||||||
|
+ echo "Error: could not copy '$KERNEL_IMAGE' to '$UKI_FILE'." >&2
|
||||||
|
+ exit 1
|
||||||
|
+ }
|
||||||
|
+else
|
||||||
|
+ [ "$KERNEL_INSTALL_VERBOSE" -gt 0 ] && echo "No UKI available. Nothing to do."
|
||||||
|
+ exit 0
|
||||||
|
+fi
|
||||||
|
+chown root:root "$UKI_FILE" || :
|
||||||
|
+
|
||||||
|
+exit 0
|
||||||
|
diff --git a/src/kernel-install/meson.build b/src/kernel-install/meson.build
|
||||||
|
index 90a0e3ae49..68a4d43862 100644
|
||||||
|
--- a/src/kernel-install/meson.build
|
||||||
|
+++ b/src/kernel-install/meson.build
|
||||||
|
@@ -3,6 +3,8 @@
|
||||||
|
kernel_install_in = files('kernel-install.in')
|
||||||
|
loaderentry_install = files('90-loaderentry.install')
|
||||||
|
|
||||||
|
+uki_copy_install = files('90-uki-copy.install')
|
||||||
|
+
|
||||||
|
if want_kernel_install
|
||||||
|
install_data('50-depmod.install',
|
||||||
|
loaderentry_install,
|
@ -0,0 +1,25 @@
|
|||||||
|
From 5d3d683fd54100fea2a355b0ebc8b03d9b6c964b Mon Sep 17 00:00:00 2001
|
||||||
|
From: Gerd Hoffmann <kraxel@redhat.com>
|
||||||
|
Date: Wed, 25 Jan 2023 13:57:09 +0100
|
||||||
|
Subject: [PATCH] kernel-install: remove math slang from man page
|
||||||
|
|
||||||
|
(cherry picked from commit 642617f431457382ec2140a52ee08bfbb3e5e1db)
|
||||||
|
|
||||||
|
Related: RHEL-16354
|
||||||
|
---
|
||||||
|
man/kernel-install.xml | 2 +-
|
||||||
|
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||||
|
|
||||||
|
diff --git a/man/kernel-install.xml b/man/kernel-install.xml
|
||||||
|
index b1822a8847..1bc6e7aa05 100644
|
||||||
|
--- a/man/kernel-install.xml
|
||||||
|
+++ b/man/kernel-install.xml
|
||||||
|
@@ -111,7 +111,7 @@
|
||||||
|
|
||||||
|
<listitem><para><filename>90-uki-copy.install</filename> copies a file
|
||||||
|
<filename>uki.efi</filename> from <varname>$KERNEL_INSTALL_STAGING_AREA</varname> or if it does
|
||||||
|
- not exist the <replaceable>KERNEL-IMAGE</replaceable> argument, iff it has a
|
||||||
|
+ not exist the <replaceable>KERNEL-IMAGE</replaceable> argument, only if it has a
|
||||||
|
<literal>.efi</literal> extension, to
|
||||||
|
<filename>$BOOT/EFI/Linux/<replaceable>ENTRY-TOKEN</replaceable>-<replaceable>KERNEL-VERSION</replaceable>.efi</filename>.</para>
|
||||||
|
|
@ -0,0 +1,80 @@
|
|||||||
|
From 4f3593718196c007838eebf5d9b42f09318bd4e6 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Gerd Hoffmann <kraxel@redhat.com>
|
||||||
|
Date: Fri, 20 Jan 2023 09:05:18 +0100
|
||||||
|
Subject: [PATCH] kernel-install: handle uki installs automatically
|
||||||
|
|
||||||
|
Detect image type using "bootctl kernel-identify $kernel",
|
||||||
|
store result in KERNEL_INSTALL_IMAGE_TYPE.
|
||||||
|
|
||||||
|
Extend layout autodetection to check the kernel image type
|
||||||
|
and pick layout=uki for UKIs.
|
||||||
|
|
||||||
|
Resolves: https://github.com/systemd/systemd/issues/25822
|
||||||
|
(cherry picked from commit 3d5f0bfe4e72fdc4d8f8d65f96dc5501dfed8a64)
|
||||||
|
|
||||||
|
Related: RHEL-16354
|
||||||
|
---
|
||||||
|
man/kernel-install.xml | 17 +++++++++++++----
|
||||||
|
src/kernel-install/kernel-install.in | 12 ++++++++++--
|
||||||
|
2 files changed, 23 insertions(+), 6 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/man/kernel-install.xml b/man/kernel-install.xml
|
||||||
|
index 1bc6e7aa05..4d91b7b20b 100644
|
||||||
|
--- a/man/kernel-install.xml
|
||||||
|
+++ b/man/kernel-install.xml
|
||||||
|
@@ -224,10 +224,8 @@
|
||||||
|
(EFI System Partition) are mounted, and also conceptually referred to as <varname>$BOOT</varname>. Can
|
||||||
|
be overridden by setting <varname>$BOOT_ROOT</varname> (see below).</para>
|
||||||
|
|
||||||
|
- <para><varname>$KERNEL_INSTALL_LAYOUT=bls|uki|other|...</varname> is set for the plugins to specify the
|
||||||
|
- installation layout. Defaults to <option>bls</option> if
|
||||||
|
- <filename>$BOOT/<replaceable>ENTRY-TOKEN</replaceable></filename> exists, or <option>other</option>
|
||||||
|
- otherwise. Additional layout names may be defined by convention. If a plugin uses a special layout,
|
||||||
|
+ <para><varname>$KERNEL_INSTALL_LAYOUT=auto|bls|uki|other|...</varname> is set for the plugins to specify the
|
||||||
|
+ installation layout. Additional layout names may be defined by convention. If a plugin uses a special layout,
|
||||||
|
it's encouraged to declare its own layout name and configure <varname>layout=</varname> in
|
||||||
|
<filename>install.conf</filename> upon initial installation. The following values are currently
|
||||||
|
understood:</para>
|
||||||
|
@@ -264,6 +262,17 @@
|
||||||
|
<para>Some other layout not understood natively by <command>kernel-install</command>.</para>
|
||||||
|
</listitem>
|
||||||
|
</varlistentry>
|
||||||
|
+ <varlistentry>
|
||||||
|
+ <term>auto</term>
|
||||||
|
+ <listitem>
|
||||||
|
+ <para>Pick the layout automatically. If the kernel is a UKI set layout to
|
||||||
|
+ <option>uki</option>. If not default to <option>bls</option> if
|
||||||
|
+ <filename>$BOOT/loader/entries.srel</filename> with content <literal>type1</literal> or
|
||||||
|
+ <filename>$BOOT/<replaceable>ENTRY-TOKEN</replaceable></filename> exists, or
|
||||||
|
+ <option>other</option> otherwise.</para>
|
||||||
|
+ <para>Leaving layout blank has the same effect. This is the default.</para>
|
||||||
|
+ </listitem>
|
||||||
|
+ </varlistentry>
|
||||||
|
</variablelist>
|
||||||
|
|
||||||
|
<para><varname>$KERNEL_INSTALL_INITRD_GENERATOR</varname> is set for plugins to select the initrd
|
||||||
|
diff --git a/src/kernel-install/kernel-install.in b/src/kernel-install/kernel-install.in
|
||||||
|
index fa2c0d5276..25884fc0e2 100755
|
||||||
|
--- a/src/kernel-install/kernel-install.in
|
||||||
|
+++ b/src/kernel-install/kernel-install.in
|
||||||
|
@@ -250,10 +250,18 @@ if [ -z "$ENTRY_TOKEN" ]; then
|
||||||
|
echo "No entry-token candidate matched, using \"$ENTRY_TOKEN\" from machine-id"
|
||||||
|
fi
|
||||||
|
|
||||||
|
-if [ -z "$layout" ]; then
|
||||||
|
+export KERNEL_INSTALL_IMAGE_TYPE=""
|
||||||
|
+if [ -f "$1" ]; then
|
||||||
|
+ KERNEL_INSTALL_IMAGE_TYPE="$(bootctl kernel-identify "$1" 2>/dev/null || echo "unknown")"
|
||||||
|
+fi
|
||||||
|
+
|
||||||
|
+if [ "$layout" = "auto" ] || [ -z "$layout" ]; then
|
||||||
|
# No layout configured by the administrator. Let's try to figure it out
|
||||||
|
# automatically from metadata already contained in $BOOT_ROOT.
|
||||||
|
- if [ -e "$BOOT_ROOT/loader/entries.srel" ]; then
|
||||||
|
+ if [ "$KERNEL_INSTALL_IMAGE_TYPE" = "uki" ]; then
|
||||||
|
+ layout="uki"
|
||||||
|
+ log_verbose "Kernel image is UKI, using layout=$layout"
|
||||||
|
+ elif [ -e "$BOOT_ROOT/loader/entries.srel" ]; then
|
||||||
|
read -r ENTRIES_SREL <"$BOOT_ROOT/loader/entries.srel"
|
||||||
|
if [ "$ENTRIES_SREL" = "type1" ]; then
|
||||||
|
# The loader/entries.srel file clearly indicates that the installed
|
@ -0,0 +1,31 @@
|
|||||||
|
From cb2ead4b9fc17554a8694fd213bfb100d9c15678 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Gerd Hoffmann <kraxel@redhat.com>
|
||||||
|
Date: Fri, 20 Jan 2023 12:59:33 +0100
|
||||||
|
Subject: [PATCH] 90-uki-copy.install: create $BOOT/EFI/Linux directory if
|
||||||
|
needed
|
||||||
|
|
||||||
|
Do not consider a missing 'Linux' subdirectory an error.
|
||||||
|
Just create it instead.
|
||||||
|
|
||||||
|
(cherry picked from commit c7314ee7e290b3978e2f2d7726d07656eda071f9)
|
||||||
|
|
||||||
|
Related: RHEL-16354
|
||||||
|
---
|
||||||
|
src/kernel-install/90-uki-copy.install | 4 ++--
|
||||||
|
1 file changed, 2 insertions(+), 2 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/src/kernel-install/90-uki-copy.install b/src/kernel-install/90-uki-copy.install
|
||||||
|
index d6e3deb723..6c71b211d7 100755
|
||||||
|
--- a/src/kernel-install/90-uki-copy.install
|
||||||
|
+++ b/src/kernel-install/90-uki-copy.install
|
||||||
|
@@ -49,8 +49,8 @@ case "$COMMAND" in
|
||||||
|
esac
|
||||||
|
|
||||||
|
if ! [ -d "$UKI_DIR" ]; then
|
||||||
|
- echo "Error: entry directory '$UKI_DIR' does not exist" >&2
|
||||||
|
- exit 1
|
||||||
|
+ [ "$KERNEL_INSTALL_VERBOSE" -gt 0 ] && echo "creating $UKI_DIR"
|
||||||
|
+ mkdir -p "$UKI_DIR"
|
||||||
|
fi
|
||||||
|
|
||||||
|
TRIES_FILE="${KERNEL_INSTALL_CONF_ROOT:-/etc/kernel}/tries"
|
@ -0,0 +1,36 @@
|
|||||||
|
From d0b5386bde65b8c488d23f16ec4049d1e6378c25 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Daan De Meyer <daan.j.demeyer@gmail.com>
|
||||||
|
Date: Sun, 5 Nov 2023 13:50:25 +0100
|
||||||
|
Subject: [PATCH] kernel-install: Log location that uki is installed in
|
||||||
|
|
||||||
|
Let's log where we install a UKI when running in verbose mode.
|
||||||
|
|
||||||
|
(cherry picked from commit 4f5278eead35bc66cc943a493eab8a8b78174400)
|
||||||
|
|
||||||
|
Related: RHEL-16354
|
||||||
|
---
|
||||||
|
src/kernel-install/90-uki-copy.install | 4 ++--
|
||||||
|
1 file changed, 2 insertions(+), 2 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/src/kernel-install/90-uki-copy.install b/src/kernel-install/90-uki-copy.install
|
||||||
|
index 6c71b211d7..c66c09719c 100755
|
||||||
|
--- a/src/kernel-install/90-uki-copy.install
|
||||||
|
+++ b/src/kernel-install/90-uki-copy.install
|
||||||
|
@@ -69,7 +69,7 @@ fi
|
||||||
|
# If there is a UKI named uki.efi on the staging area use that, if not use what
|
||||||
|
# was passed in as $KERNEL_IMAGE but insist it has a .efi extension
|
||||||
|
if [ -f "$KERNEL_INSTALL_STAGING_AREA/uki.efi" ]; then
|
||||||
|
- [ "$KERNEL_INSTALL_VERBOSE" -gt 0 ] && echo "Installing $KERNEL_INSTALL_STAGING_AREA/uki.efi"
|
||||||
|
+ [ "$KERNEL_INSTALL_VERBOSE" -gt 0 ] && echo "Installing $KERNEL_INSTALL_STAGING_AREA/uki.efi as $UKI_FILE"
|
||||||
|
install -m 0644 "$KERNEL_INSTALL_STAGING_AREA/uki.efi" "$UKI_FILE" || {
|
||||||
|
echo "Error: could not copy '$KERNEL_INSTALL_STAGING_AREA/uki.efi' to '$UKI_FILE'." >&2
|
||||||
|
exit 1
|
||||||
|
@@ -83,7 +83,7 @@ elif [ -n "$KERNEL_IMAGE" ]; then
|
||||||
|
echo "Error: $KERNEL_IMAGE is missing .efi suffix." >&2
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
- [ "$KERNEL_INSTALL_VERBOSE" -gt 0 ] && echo "Installing $KERNEL_IMAGE"
|
||||||
|
+ [ "$KERNEL_INSTALL_VERBOSE" -gt 0 ] && echo "Installing $KERNEL_IMAGE as $UKI_FILE"
|
||||||
|
install -m 0644 "$KERNEL_IMAGE" "$UKI_FILE" || {
|
||||||
|
echo "Error: could not copy '$KERNEL_IMAGE' to '$UKI_FILE'." >&2
|
||||||
|
exit 1
|
@ -0,0 +1,25 @@
|
|||||||
|
From f0ab67eb46103c68a1fc708b45e2fa6b93780efb Mon Sep 17 00:00:00 2001
|
||||||
|
From: Lennart Poettering <lennart@poettering.net>
|
||||||
|
Date: Mon, 19 Dec 2022 22:25:28 +0100
|
||||||
|
Subject: [PATCH] bootctl: fix errno logging
|
||||||
|
|
||||||
|
(cherry picked from commit e425849e995e448f529d3c106bf1e3de2ca23a35)
|
||||||
|
|
||||||
|
Related: RHEL-16354
|
||||||
|
---
|
||||||
|
src/boot/bootctl.c | 2 +-
|
||||||
|
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||||
|
|
||||||
|
diff --git a/src/boot/bootctl.c b/src/boot/bootctl.c
|
||||||
|
index 7da48b4ca4..67fcbcc8cd 100644
|
||||||
|
--- a/src/boot/bootctl.c
|
||||||
|
+++ b/src/boot/bootctl.c
|
||||||
|
@@ -2028,7 +2028,7 @@ static int install_random_seed(const char *esp) {
|
||||||
|
return log_error_errno(SYNTHETIC_ERRNO(EIO), "Short write while writing random seed file.");
|
||||||
|
|
||||||
|
if (rename(tmp, path) < 0)
|
||||||
|
- return log_error_errno(r, "Failed to move random seed file into place: %m");
|
||||||
|
+ return log_error_errno(errno, "Failed to move random seed file into place: %m");
|
||||||
|
|
||||||
|
tmp = mfree(tmp);
|
||||||
|
|
@ -0,0 +1,214 @@
|
|||||||
|
From ca716a0fdfd434e52384dd74ff4c909aa95b6c81 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Gerd Hoffmann <kraxel@redhat.com>
|
||||||
|
Date: Mon, 16 Jan 2023 18:58:21 +0100
|
||||||
|
Subject: [PATCH] bootctl: add kernel-identity command
|
||||||
|
|
||||||
|
The command takes a kernel as argument and checks what kind of kernel
|
||||||
|
the image is. Returns one of uki, pe or unknown.
|
||||||
|
|
||||||
|
(cherry picked from commit 53c368d71ba43da7414ac86c58291a11da05ba84)
|
||||||
|
|
||||||
|
Resolves: RHEL-16354
|
||||||
|
---
|
||||||
|
man/bootctl.xml | 13 +++++
|
||||||
|
meson.build | 5 +-
|
||||||
|
src/boot/bootctl-uki.c | 109 +++++++++++++++++++++++++++++++++++++++++
|
||||||
|
src/boot/bootctl-uki.h | 3 ++
|
||||||
|
src/boot/bootctl.c | 4 ++
|
||||||
|
5 files changed, 133 insertions(+), 1 deletion(-)
|
||||||
|
create mode 100644 src/boot/bootctl-uki.c
|
||||||
|
create mode 100644 src/boot/bootctl-uki.h
|
||||||
|
|
||||||
|
diff --git a/man/bootctl.xml b/man/bootctl.xml
|
||||||
|
index dfc56d6125..0f992ec383 100644
|
||||||
|
--- a/man/bootctl.xml
|
||||||
|
+++ b/man/bootctl.xml
|
||||||
|
@@ -217,6 +217,19 @@
|
||||||
|
</variablelist>
|
||||||
|
</refsect1>
|
||||||
|
|
||||||
|
+ <refsect1>
|
||||||
|
+ <title><command>kernel</command> Commands</title>
|
||||||
|
+
|
||||||
|
+ <variablelist>
|
||||||
|
+ <varlistentry>
|
||||||
|
+ <term><option>kernel-identify</option> <replaceable>kernel</replaceable></term>
|
||||||
|
+
|
||||||
|
+ <listitem><para>Takes a kernel image as argument. Checks what kind of kernel the image is. Returns
|
||||||
|
+ one of uki, pe or unknown.</para></listitem>
|
||||||
|
+ </varlistentry>
|
||||||
|
+ </variablelist>
|
||||||
|
+ </refsect1>
|
||||||
|
+
|
||||||
|
<refsect1>
|
||||||
|
<title>Options</title>
|
||||||
|
<para>The following options are understood:</para>
|
||||||
|
diff --git a/meson.build b/meson.build
|
||||||
|
index e0495ed36a..936e612a01 100644
|
||||||
|
--- a/meson.build
|
||||||
|
+++ b/meson.build
|
||||||
|
@@ -2566,7 +2566,10 @@ if conf.get('HAVE_BLKID') == 1 and conf.get('HAVE_GNU_EFI') == 1
|
||||||
|
|
||||||
|
public_programs += executable(
|
||||||
|
'bootctl',
|
||||||
|
- 'src/boot/bootctl.c',
|
||||||
|
+ ['src/boot/bootctl.c',
|
||||||
|
+ 'src/boot/bootctl-uki.c',
|
||||||
|
+ 'src/boot/bootctl-uki.h',
|
||||||
|
+ ],
|
||||||
|
include_directories : includes,
|
||||||
|
link_with : [boot_link_with],
|
||||||
|
dependencies : [libblkid],
|
||||||
|
diff --git a/src/boot/bootctl-uki.c b/src/boot/bootctl-uki.c
|
||||||
|
new file mode 100644
|
||||||
|
index 0000000000..7e8e8a570b
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/src/boot/bootctl-uki.c
|
||||||
|
@@ -0,0 +1,109 @@
|
||||||
|
+/* SPDX-License-Identifier: LGPL-2.1-or-later */
|
||||||
|
+
|
||||||
|
+#include "bootctl-uki.h"
|
||||||
|
+#include "fd-util.h"
|
||||||
|
+#include "parse-util.h"
|
||||||
|
+#include "pe-header.h"
|
||||||
|
+
|
||||||
|
+#define MAX_SECTIONS 96
|
||||||
|
+
|
||||||
|
+static const uint8_t dos_file_magic[2] = "MZ";
|
||||||
|
+static const uint8_t pe_file_magic[4] = "PE\0\0";
|
||||||
|
+
|
||||||
|
+static const uint8_t name_osrel[8] = ".osrel";
|
||||||
|
+static const uint8_t name_linux[8] = ".linux";
|
||||||
|
+static const uint8_t name_initrd[8] = ".initrd";
|
||||||
|
+
|
||||||
|
+static int pe_sections(FILE *uki, struct PeSectionHeader **ret, size_t *ret_n) {
|
||||||
|
+ _cleanup_free_ struct PeSectionHeader *sections = NULL;
|
||||||
|
+ struct DosFileHeader dos;
|
||||||
|
+ struct PeHeader pe;
|
||||||
|
+ size_t scount;
|
||||||
|
+ uint64_t soff, items;
|
||||||
|
+ int rc;
|
||||||
|
+
|
||||||
|
+ items = fread(&dos, 1, sizeof(dos), uki);
|
||||||
|
+ if (items != sizeof(dos))
|
||||||
|
+ return log_error_errno(SYNTHETIC_ERRNO(EIO), "DOS header read error");
|
||||||
|
+ if (memcmp(dos.Magic, dos_file_magic, sizeof(dos_file_magic)) != 0)
|
||||||
|
+ goto no_sections;
|
||||||
|
+
|
||||||
|
+ rc = fseek(uki, le32toh(dos.ExeHeader), SEEK_SET);
|
||||||
|
+ if (rc < 0)
|
||||||
|
+ return log_error_errno(errno, "seek to PE header");
|
||||||
|
+ items = fread(&pe, 1, sizeof(pe), uki);
|
||||||
|
+ if (items != sizeof(pe))
|
||||||
|
+ return log_error_errno(SYNTHETIC_ERRNO(EIO), "PE header read error");
|
||||||
|
+ if (memcmp(pe.Magic, pe_file_magic, sizeof(pe_file_magic)) != 0)
|
||||||
|
+ goto no_sections;
|
||||||
|
+
|
||||||
|
+ soff = le32toh(dos.ExeHeader) + sizeof(pe) + le16toh(pe.FileHeader.SizeOfOptionalHeader);
|
||||||
|
+ rc = fseek(uki, soff, SEEK_SET);
|
||||||
|
+ if (rc < 0)
|
||||||
|
+ return log_error_errno(errno, "seek to PE section headers");
|
||||||
|
+
|
||||||
|
+ scount = le16toh(pe.FileHeader.NumberOfSections);
|
||||||
|
+ if (scount > MAX_SECTIONS)
|
||||||
|
+ goto no_sections;
|
||||||
|
+ sections = new(struct PeSectionHeader, scount);
|
||||||
|
+ if (!sections)
|
||||||
|
+ return log_oom();
|
||||||
|
+ items = fread(sections, sizeof(*sections), scount, uki);
|
||||||
|
+ if (items != scount)
|
||||||
|
+ return log_error_errno(SYNTHETIC_ERRNO(EIO), "PE section header read error");
|
||||||
|
+
|
||||||
|
+ *ret = TAKE_PTR(sections);
|
||||||
|
+ *ret_n = scount;
|
||||||
|
+ return 0;
|
||||||
|
+
|
||||||
|
+no_sections:
|
||||||
|
+ *ret = NULL;
|
||||||
|
+ *ret_n = 0;
|
||||||
|
+ return 0;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static int find_pe_section(struct PeSectionHeader *sections, size_t scount,
|
||||||
|
+ const uint8_t *name, size_t namelen, size_t *ret) {
|
||||||
|
+ for (size_t s = 0; s < scount; s++) {
|
||||||
|
+ if (memcmp_nn(sections[s].Name, sizeof(sections[s].Name),
|
||||||
|
+ name, namelen) == 0) {
|
||||||
|
+ if (ret)
|
||||||
|
+ *ret = s;
|
||||||
|
+ return 1;
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+ return 0;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static bool is_uki(struct PeSectionHeader *sections, size_t scount) {
|
||||||
|
+ return (find_pe_section(sections, scount, name_osrel, sizeof(name_osrel), NULL) &&
|
||||||
|
+ find_pe_section(sections, scount, name_linux, sizeof(name_linux), NULL) &&
|
||||||
|
+ find_pe_section(sections, scount, name_initrd, sizeof(name_initrd), NULL));
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+int verb_kernel_identify(int argc, char *argv[], void *userdata) {
|
||||||
|
+ _cleanup_fclose_ FILE *uki = NULL;
|
||||||
|
+ _cleanup_free_ struct PeSectionHeader *sections = NULL;
|
||||||
|
+ size_t scount;
|
||||||
|
+ int rc;
|
||||||
|
+
|
||||||
|
+ uki = fopen(argv[1], "re");
|
||||||
|
+ if (!uki)
|
||||||
|
+ return log_error_errno(errno, "Failed to open UKI file '%s': %m", argv[1]);
|
||||||
|
+
|
||||||
|
+ rc = pe_sections(uki, §ions, &scount);
|
||||||
|
+ if (rc < 0)
|
||||||
|
+ return EXIT_FAILURE;
|
||||||
|
+
|
||||||
|
+ if (sections) {
|
||||||
|
+ if (is_uki(sections, scount)) {
|
||||||
|
+ puts("uki");
|
||||||
|
+ return EXIT_SUCCESS;
|
||||||
|
+ }
|
||||||
|
+ puts("pe");
|
||||||
|
+ return EXIT_SUCCESS;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ puts("unknown");
|
||||||
|
+ return EXIT_SUCCESS;
|
||||||
|
+}
|
||||||
|
diff --git a/src/boot/bootctl-uki.h b/src/boot/bootctl-uki.h
|
||||||
|
new file mode 100644
|
||||||
|
index 0000000000..3c1fb5bc6a
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/src/boot/bootctl-uki.h
|
||||||
|
@@ -0,0 +1,3 @@
|
||||||
|
+/* SPDX-License-Identifier: LGPL-2.1-or-later */
|
||||||
|
+
|
||||||
|
+int verb_kernel_identify(int argc, char *argv[], void *userdata);
|
||||||
|
diff --git a/src/boot/bootctl.c b/src/boot/bootctl.c
|
||||||
|
index 67fcbcc8cd..58e4af85f8 100644
|
||||||
|
--- a/src/boot/bootctl.c
|
||||||
|
+++ b/src/boot/bootctl.c
|
||||||
|
@@ -14,6 +14,7 @@
|
||||||
|
|
||||||
|
#include "alloc-util.h"
|
||||||
|
#include "blkid-util.h"
|
||||||
|
+#include "bootctl-uki.h"
|
||||||
|
#include "bootspec.h"
|
||||||
|
#include "chase-symlinks.h"
|
||||||
|
#include "copy.h"
|
||||||
|
@@ -1453,6 +1454,8 @@ static int help(int argc, char *argv[], void *userdata) {
|
||||||
|
" remove Remove systemd-boot from the ESP and EFI variables\n"
|
||||||
|
" is-installed Test whether systemd-boot is installed in the ESP\n"
|
||||||
|
" random-seed Initialize random seed in ESP and EFI variables\n"
|
||||||
|
+ "\n%3$skernel Commands:%4$s\n"
|
||||||
|
+ " kernel-identify Identify kernel image type.\n"
|
||||||
|
"\n%3$sOptions:%4$s\n"
|
||||||
|
" -h --help Show this help\n"
|
||||||
|
" --version Print version\n"
|
||||||
|
@@ -2567,6 +2570,7 @@ static int bootctl_main(int argc, char *argv[]) {
|
||||||
|
{ "update", VERB_ANY, 1, 0, verb_install },
|
||||||
|
{ "remove", VERB_ANY, 1, 0, verb_remove },
|
||||||
|
{ "is-installed", VERB_ANY, 1, 0, verb_is_installed },
|
||||||
|
+ { "kernel-identify", 2, 2, 0, verb_kernel_identify },
|
||||||
|
{ "list", VERB_ANY, 1, 0, verb_list },
|
||||||
|
{ "set-default", 2, 2, 0, verb_set_efivar },
|
||||||
|
{ "set-oneshot", 2, 2, 0, verb_set_efivar },
|
@ -0,0 +1,150 @@
|
|||||||
|
From 3012047a48f67f6cceba50ce326497aa647074ea Mon Sep 17 00:00:00 2001
|
||||||
|
From: Gerd Hoffmann <kraxel@redhat.com>
|
||||||
|
Date: Tue, 17 Jan 2023 22:06:06 +0100
|
||||||
|
Subject: [PATCH] bootctl: add kernel-inspect command
|
||||||
|
|
||||||
|
Takes a kernel image as argument. Prints details about the kernel.
|
||||||
|
|
||||||
|
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
|
||||||
|
(cherry picked from commit a05255981ba5b04f1cf54ea656fbce1dfd9c3a68)
|
||||||
|
|
||||||
|
Resolves: RHEL-16354
|
||||||
|
---
|
||||||
|
man/bootctl.xml | 6 ++++
|
||||||
|
src/boot/bootctl-uki.c | 79 ++++++++++++++++++++++++++++++++++++++++++
|
||||||
|
src/boot/bootctl-uki.h | 1 +
|
||||||
|
src/boot/bootctl.c | 1 +
|
||||||
|
4 files changed, 87 insertions(+)
|
||||||
|
|
||||||
|
diff --git a/man/bootctl.xml b/man/bootctl.xml
|
||||||
|
index 0f992ec383..c12fe93214 100644
|
||||||
|
--- a/man/bootctl.xml
|
||||||
|
+++ b/man/bootctl.xml
|
||||||
|
@@ -227,6 +227,12 @@
|
||||||
|
<listitem><para>Takes a kernel image as argument. Checks what kind of kernel the image is. Returns
|
||||||
|
one of uki, pe or unknown.</para></listitem>
|
||||||
|
</varlistentry>
|
||||||
|
+
|
||||||
|
+ <varlistentry>
|
||||||
|
+ <term><option>kernel-inspect</option> <replaceable>kernel</replaceable></term>
|
||||||
|
+
|
||||||
|
+ <listitem><para>Takes a kernel image as argument. Prints details about the kernel.</para></listitem>
|
||||||
|
+ </varlistentry>
|
||||||
|
</variablelist>
|
||||||
|
</refsect1>
|
||||||
|
|
||||||
|
diff --git a/src/boot/bootctl-uki.c b/src/boot/bootctl-uki.c
|
||||||
|
index 7e8e8a570b..3085f703a8 100644
|
||||||
|
--- a/src/boot/bootctl-uki.c
|
||||||
|
+++ b/src/boot/bootctl-uki.c
|
||||||
|
@@ -13,6 +13,8 @@ static const uint8_t pe_file_magic[4] = "PE\0\0";
|
||||||
|
static const uint8_t name_osrel[8] = ".osrel";
|
||||||
|
static const uint8_t name_linux[8] = ".linux";
|
||||||
|
static const uint8_t name_initrd[8] = ".initrd";
|
||||||
|
+static const uint8_t name_cmdline[8] = ".cmdline";
|
||||||
|
+static const uint8_t name_uname[8] = ".uname";
|
||||||
|
|
||||||
|
static int pe_sections(FILE *uki, struct PeSectionHeader **ret, size_t *ret_n) {
|
||||||
|
_cleanup_free_ struct PeSectionHeader *sections = NULL;
|
||||||
|
@@ -107,3 +109,80 @@ int verb_kernel_identify(int argc, char *argv[], void *userdata) {
|
||||||
|
puts("unknown");
|
||||||
|
return EXIT_SUCCESS;
|
||||||
|
}
|
||||||
|
+
|
||||||
|
+static int read_pe_section(FILE *uki, const struct PeSectionHeader *section,
|
||||||
|
+ void **ret, size_t *ret_n) {
|
||||||
|
+ _cleanup_free_ void *data = NULL;
|
||||||
|
+ uint32_t size, bytes;
|
||||||
|
+ uint64_t soff;
|
||||||
|
+ int rc;
|
||||||
|
+
|
||||||
|
+ soff = le32toh(section->PointerToRawData);
|
||||||
|
+ size = le32toh(section->VirtualSize);
|
||||||
|
+
|
||||||
|
+ if (size > 16 * 1024)
|
||||||
|
+ return log_error_errno(SYNTHETIC_ERRNO(E2BIG), "PE section too big");
|
||||||
|
+
|
||||||
|
+ rc = fseek(uki, soff, SEEK_SET);
|
||||||
|
+ if (rc < 0)
|
||||||
|
+ return log_error_errno(errno, "seek to PE section");
|
||||||
|
+
|
||||||
|
+ data = malloc(size+1);
|
||||||
|
+ if (!data)
|
||||||
|
+ return log_oom();
|
||||||
|
+ ((uint8_t*) data)[size] = 0; /* safety NUL byte */
|
||||||
|
+
|
||||||
|
+ bytes = fread(data, 1, size, uki);
|
||||||
|
+ if (bytes != size)
|
||||||
|
+ return log_error_errno(SYNTHETIC_ERRNO(EIO), "PE section read error");
|
||||||
|
+
|
||||||
|
+ *ret = TAKE_PTR(data);
|
||||||
|
+ if (ret_n)
|
||||||
|
+ *ret_n = size;
|
||||||
|
+ return 0;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static void inspect_uki(FILE *uki, struct PeSectionHeader *sections, size_t scount) {
|
||||||
|
+ _cleanup_free_ char *cmdline = NULL;
|
||||||
|
+ _cleanup_free_ char *uname = NULL;
|
||||||
|
+ size_t idx;
|
||||||
|
+
|
||||||
|
+ if (find_pe_section(sections, scount, name_cmdline, sizeof(name_cmdline), &idx))
|
||||||
|
+ read_pe_section(uki, sections + idx, (void**)&cmdline, NULL);
|
||||||
|
+
|
||||||
|
+ if (find_pe_section(sections, scount, name_uname, sizeof(name_uname), &idx))
|
||||||
|
+ read_pe_section(uki, sections + idx, (void**)&uname, NULL);
|
||||||
|
+
|
||||||
|
+ if (cmdline)
|
||||||
|
+ printf(" Cmdline: %s\n", cmdline);
|
||||||
|
+ if (uname)
|
||||||
|
+ printf(" Version: %s\n", uname);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+int verb_kernel_inspect(int argc, char *argv[], void *userdata) {
|
||||||
|
+ _cleanup_fclose_ FILE *uki = NULL;
|
||||||
|
+ _cleanup_free_ struct PeSectionHeader *sections = NULL;
|
||||||
|
+ size_t scount;
|
||||||
|
+ int rc;
|
||||||
|
+
|
||||||
|
+ uki = fopen(argv[1], "re");
|
||||||
|
+ if (!uki)
|
||||||
|
+ return log_error_errno(errno, "Failed to open UKI file '%s': %m", argv[1]);
|
||||||
|
+
|
||||||
|
+ rc = pe_sections(uki, §ions, &scount);
|
||||||
|
+ if (rc < 0)
|
||||||
|
+ return EXIT_FAILURE;
|
||||||
|
+
|
||||||
|
+ if (sections) {
|
||||||
|
+ if (is_uki(sections, scount)) {
|
||||||
|
+ puts("Kernel Type: uki");
|
||||||
|
+ inspect_uki(uki, sections, scount);
|
||||||
|
+ return EXIT_SUCCESS;
|
||||||
|
+ }
|
||||||
|
+ puts("Kernel Type: pe");
|
||||||
|
+ return EXIT_SUCCESS;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ puts("Kernel Type: unknown");
|
||||||
|
+ return EXIT_SUCCESS;
|
||||||
|
+}
|
||||||
|
diff --git a/src/boot/bootctl-uki.h b/src/boot/bootctl-uki.h
|
||||||
|
index 3c1fb5bc6a..effb984d80 100644
|
||||||
|
--- a/src/boot/bootctl-uki.h
|
||||||
|
+++ b/src/boot/bootctl-uki.h
|
||||||
|
@@ -1,3 +1,4 @@
|
||||||
|
/* SPDX-License-Identifier: LGPL-2.1-or-later */
|
||||||
|
|
||||||
|
int verb_kernel_identify(int argc, char *argv[], void *userdata);
|
||||||
|
+int verb_kernel_inspect(int argc, char *argv[], void *userdata);
|
||||||
|
diff --git a/src/boot/bootctl.c b/src/boot/bootctl.c
|
||||||
|
index 58e4af85f8..b98673cd11 100644
|
||||||
|
--- a/src/boot/bootctl.c
|
||||||
|
+++ b/src/boot/bootctl.c
|
||||||
|
@@ -2571,6 +2571,7 @@ static int bootctl_main(int argc, char *argv[]) {
|
||||||
|
{ "remove", VERB_ANY, 1, 0, verb_remove },
|
||||||
|
{ "is-installed", VERB_ANY, 1, 0, verb_is_installed },
|
||||||
|
{ "kernel-identify", 2, 2, 0, verb_kernel_identify },
|
||||||
|
+ { "kernel-inspect", 2, 2, 0, verb_kernel_inspect },
|
||||||
|
{ "list", VERB_ANY, 1, 0, verb_list },
|
||||||
|
{ "set-default", 2, 2, 0, verb_set_efivar },
|
||||||
|
{ "set-oneshot", 2, 2, 0, verb_set_efivar },
|
@ -0,0 +1,24 @@
|
|||||||
|
From c1736cd4c9d0cb7b39333280bd30657e68481436 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Gerd Hoffmann <kraxel@redhat.com>
|
||||||
|
Date: Fri, 20 Jan 2023 13:30:48 +0100
|
||||||
|
Subject: [PATCH] bootctl: add kernel-inspect to --help text
|
||||||
|
|
||||||
|
(cherry picked from commit 24a3b37f12a1a752e5a1379cadc15031b04c3fba)
|
||||||
|
|
||||||
|
Related: RHEL-16354
|
||||||
|
---
|
||||||
|
src/boot/bootctl.c | 1 +
|
||||||
|
1 file changed, 1 insertion(+)
|
||||||
|
|
||||||
|
diff --git a/src/boot/bootctl.c b/src/boot/bootctl.c
|
||||||
|
index b98673cd11..cc35147376 100644
|
||||||
|
--- a/src/boot/bootctl.c
|
||||||
|
+++ b/src/boot/bootctl.c
|
||||||
|
@@ -1456,6 +1456,7 @@ static int help(int argc, char *argv[], void *userdata) {
|
||||||
|
" random-seed Initialize random seed in ESP and EFI variables\n"
|
||||||
|
"\n%3$skernel Commands:%4$s\n"
|
||||||
|
" kernel-identify Identify kernel image type.\n"
|
||||||
|
+ " kernel-inspect Prints details about the kernel.\n"
|
||||||
|
"\n%3$sOptions:%4$s\n"
|
||||||
|
" -h --help Show this help\n"
|
||||||
|
" --version Print version\n"
|
@ -0,0 +1,29 @@
|
|||||||
|
From d5d960b0b8db73ffe4cff9d156b0883876d722ac Mon Sep 17 00:00:00 2001
|
||||||
|
From: Lennart Poettering <lennart@poettering.net>
|
||||||
|
Date: Fri, 20 Jan 2023 18:29:13 +0100
|
||||||
|
Subject: [PATCH] bootctl: drop full stop at end of --help texts
|
||||||
|
|
||||||
|
We never do that, don't do so here either.
|
||||||
|
|
||||||
|
(cherry picked from commit 2b197967bf251ecf58b93fed0f51b9d4cd83fda4)
|
||||||
|
|
||||||
|
Related: RHEL-16354
|
||||||
|
---
|
||||||
|
src/boot/bootctl.c | 4 ++--
|
||||||
|
1 file changed, 2 insertions(+), 2 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/src/boot/bootctl.c b/src/boot/bootctl.c
|
||||||
|
index cc35147376..681c5bd44f 100644
|
||||||
|
--- a/src/boot/bootctl.c
|
||||||
|
+++ b/src/boot/bootctl.c
|
||||||
|
@@ -1455,8 +1455,8 @@ static int help(int argc, char *argv[], void *userdata) {
|
||||||
|
" is-installed Test whether systemd-boot is installed in the ESP\n"
|
||||||
|
" random-seed Initialize random seed in ESP and EFI variables\n"
|
||||||
|
"\n%3$skernel Commands:%4$s\n"
|
||||||
|
- " kernel-identify Identify kernel image type.\n"
|
||||||
|
- " kernel-inspect Prints details about the kernel.\n"
|
||||||
|
+ " kernel-identify Identify kernel image type\n"
|
||||||
|
+ " kernel-inspect Prints details about the kernel\n"
|
||||||
|
"\n%3$sOptions:%4$s\n"
|
||||||
|
" -h --help Show this help\n"
|
||||||
|
" --version Print version\n"
|
@ -0,0 +1,44 @@
|
|||||||
|
From 6ee66a4736bde681956ef8ab601a72a5cb7b19ed Mon Sep 17 00:00:00 2001
|
||||||
|
From: Lennart Poettering <lennart@poettering.net>
|
||||||
|
Date: Fri, 20 Jan 2023 18:30:06 +0100
|
||||||
|
Subject: [PATCH] bootctl: change section title for kernel image commands
|
||||||
|
|
||||||
|
Let's call them kernel *images*, not just *kernels*.
|
||||||
|
|
||||||
|
(cherry picked from commit 1e7d6cc07211de425bcc5c408c1f4376d6717305)
|
||||||
|
|
||||||
|
Related: RHEL-16354
|
||||||
|
---
|
||||||
|
man/bootctl.xml | 2 +-
|
||||||
|
src/boot/bootctl.c | 4 ++--
|
||||||
|
2 files changed, 3 insertions(+), 3 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/man/bootctl.xml b/man/bootctl.xml
|
||||||
|
index c12fe93214..d82f12d5bb 100644
|
||||||
|
--- a/man/bootctl.xml
|
||||||
|
+++ b/man/bootctl.xml
|
||||||
|
@@ -218,7 +218,7 @@
|
||||||
|
</refsect1>
|
||||||
|
|
||||||
|
<refsect1>
|
||||||
|
- <title><command>kernel</command> Commands</title>
|
||||||
|
+ <title>Kernel Image Commands</title>
|
||||||
|
|
||||||
|
<variablelist>
|
||||||
|
<varlistentry>
|
||||||
|
diff --git a/src/boot/bootctl.c b/src/boot/bootctl.c
|
||||||
|
index 681c5bd44f..4f2a6288fb 100644
|
||||||
|
--- a/src/boot/bootctl.c
|
||||||
|
+++ b/src/boot/bootctl.c
|
||||||
|
@@ -1454,9 +1454,9 @@ static int help(int argc, char *argv[], void *userdata) {
|
||||||
|
" remove Remove systemd-boot from the ESP and EFI variables\n"
|
||||||
|
" is-installed Test whether systemd-boot is installed in the ESP\n"
|
||||||
|
" random-seed Initialize random seed in ESP and EFI variables\n"
|
||||||
|
- "\n%3$skernel Commands:%4$s\n"
|
||||||
|
+ "\n%3$sKernel Image Commands:%4$s\n"
|
||||||
|
" kernel-identify Identify kernel image type\n"
|
||||||
|
- " kernel-inspect Prints details about the kernel\n"
|
||||||
|
+ " kernel-inspect Prints details about the kernel image\n"
|
||||||
|
"\n%3$sOptions:%4$s\n"
|
||||||
|
" -h --help Show this help\n"
|
||||||
|
" --version Print version\n"
|
@ -0,0 +1,25 @@
|
|||||||
|
From 2eae3094d018587e2550aaf895a7cbdeaea679bd Mon Sep 17 00:00:00 2001
|
||||||
|
From: Lennart Poettering <lennart@poettering.net>
|
||||||
|
Date: Fri, 20 Jan 2023 18:40:57 +0100
|
||||||
|
Subject: [PATCH] bootctl: remove space that should not be there
|
||||||
|
|
||||||
|
(cherry picked from commit e684d2d5f85a82ed47eb063809145540df01ae1a)
|
||||||
|
|
||||||
|
Related: RHEL-16354
|
||||||
|
---
|
||||||
|
src/boot/bootctl.c | 2 +-
|
||||||
|
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||||
|
|
||||||
|
diff --git a/src/boot/bootctl.c b/src/boot/bootctl.c
|
||||||
|
index 4f2a6288fb..3044f67b5a 100644
|
||||||
|
--- a/src/boot/bootctl.c
|
||||||
|
+++ b/src/boot/bootctl.c
|
||||||
|
@@ -1433,7 +1433,7 @@ static int help(int argc, char *argv[], void *userdata) {
|
||||||
|
if (r < 0)
|
||||||
|
return log_oom();
|
||||||
|
|
||||||
|
- printf("%1$s [OPTIONS...] COMMAND ...\n"
|
||||||
|
+ printf("%1$s [OPTIONS...] COMMAND ...\n"
|
||||||
|
"\n%5$sControl EFI firmware boot settings and manage boot loader.%6$s\n"
|
||||||
|
"\n%3$sGeneric EFI Firmware/Boot Loader Commands:%4$s\n"
|
||||||
|
" status Show status of installed boot loader and EFI variables\n"
|
@ -0,0 +1,73 @@
|
|||||||
|
From 6204aa43883fdf02d72bd0db6d3cfbfa7c075213 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Gerd Hoffmann <kraxel@redhat.com>
|
||||||
|
Date: Fri, 20 Jan 2023 15:40:36 +0100
|
||||||
|
Subject: [PATCH] bootctl: kernel-inspect: print os info
|
||||||
|
|
||||||
|
(cherry picked from commit 2d4260482cb8463f4de9502efd26bf8c64262669)
|
||||||
|
|
||||||
|
Related: RHEL-16354
|
||||||
|
---
|
||||||
|
src/boot/bootctl-uki.c | 29 ++++++++++++++++++++++++++++-
|
||||||
|
1 file changed, 28 insertions(+), 1 deletion(-)
|
||||||
|
|
||||||
|
diff --git a/src/boot/bootctl-uki.c b/src/boot/bootctl-uki.c
|
||||||
|
index 3085f703a8..6bdf926350 100644
|
||||||
|
--- a/src/boot/bootctl-uki.c
|
||||||
|
+++ b/src/boot/bootctl-uki.c
|
||||||
|
@@ -1,6 +1,7 @@
|
||||||
|
/* SPDX-License-Identifier: LGPL-2.1-or-later */
|
||||||
|
|
||||||
|
#include "bootctl-uki.h"
|
||||||
|
+#include "env-file.h"
|
||||||
|
#include "fd-util.h"
|
||||||
|
#include "parse-util.h"
|
||||||
|
#include "pe-header.h"
|
||||||
|
@@ -142,10 +143,31 @@ static int read_pe_section(FILE *uki, const struct PeSectionHeader *section,
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
+static void inspect_osrel(char *osrel, size_t osrel_size) {
|
||||||
|
+ _cleanup_fclose_ FILE *s = NULL;
|
||||||
|
+ _cleanup_free_ char *pname = NULL, *name = NULL;
|
||||||
|
+ int r;
|
||||||
|
+
|
||||||
|
+ assert(osrel);
|
||||||
|
+ s = fmemopen(osrel, osrel_size, "r");
|
||||||
|
+ if (!s)
|
||||||
|
+ return (void) log_warning_errno(errno, "Failed to open embedded os-release file, ignoring: %m");
|
||||||
|
+
|
||||||
|
+ r = parse_env_file(s, NULL,
|
||||||
|
+ "PRETTY_NAME", &pname,
|
||||||
|
+ "NAME", &name);
|
||||||
|
+ if (r < 0)
|
||||||
|
+ return (void) log_warning_errno(r, "Failed to parse embedded os-release file, ignoring: %m");
|
||||||
|
+
|
||||||
|
+ if (pname || name)
|
||||||
|
+ printf(" OS: %s\n", pname ?: name);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
static void inspect_uki(FILE *uki, struct PeSectionHeader *sections, size_t scount) {
|
||||||
|
_cleanup_free_ char *cmdline = NULL;
|
||||||
|
_cleanup_free_ char *uname = NULL;
|
||||||
|
- size_t idx;
|
||||||
|
+ _cleanup_free_ char *osrel = NULL;
|
||||||
|
+ size_t osrel_size, idx;
|
||||||
|
|
||||||
|
if (find_pe_section(sections, scount, name_cmdline, sizeof(name_cmdline), &idx))
|
||||||
|
read_pe_section(uki, sections + idx, (void**)&cmdline, NULL);
|
||||||
|
@@ -153,10 +175,15 @@ static void inspect_uki(FILE *uki, struct PeSectionHeader *sections, size_t scou
|
||||||
|
if (find_pe_section(sections, scount, name_uname, sizeof(name_uname), &idx))
|
||||||
|
read_pe_section(uki, sections + idx, (void**)&uname, NULL);
|
||||||
|
|
||||||
|
+ if (find_pe_section(sections, scount, name_osrel, sizeof(name_osrel), &idx))
|
||||||
|
+ read_pe_section(uki, sections + idx, (void**)&osrel, &osrel_size);
|
||||||
|
+
|
||||||
|
if (cmdline)
|
||||||
|
printf(" Cmdline: %s\n", cmdline);
|
||||||
|
if (uname)
|
||||||
|
printf(" Version: %s\n", uname);
|
||||||
|
+ if (osrel)
|
||||||
|
+ inspect_osrel(osrel, osrel_size);
|
||||||
|
}
|
||||||
|
|
||||||
|
int verb_kernel_inspect(int argc, char *argv[], void *userdata) {
|
@ -0,0 +1,207 @@
|
|||||||
|
From a9c7fe86260ca906c7378503e059eca0ad014947 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Yu Watanabe <watanabe.yu+github@gmail.com>
|
||||||
|
Date: Tue, 24 Jan 2023 22:59:59 +0900
|
||||||
|
Subject: [PATCH] bootctl-uki: several coding style fixlets
|
||||||
|
|
||||||
|
Mostly follow-ups for #26082.
|
||||||
|
|
||||||
|
(cherry picked from commit 5b532e14e3ac1d8f8cef90fd8c5b1ce277458ae7)
|
||||||
|
|
||||||
|
Related: RHEL-16354
|
||||||
|
---
|
||||||
|
src/boot/bootctl-uki.c | 105 +++++++++++++++++++++++------------------
|
||||||
|
1 file changed, 60 insertions(+), 45 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/src/boot/bootctl-uki.c b/src/boot/bootctl-uki.c
|
||||||
|
index 6bdf926350..3492fa548f 100644
|
||||||
|
--- a/src/boot/bootctl-uki.c
|
||||||
|
+++ b/src/boot/bootctl-uki.c
|
||||||
|
@@ -23,7 +23,10 @@ static int pe_sections(FILE *uki, struct PeSectionHeader **ret, size_t *ret_n) {
|
||||||
|
struct PeHeader pe;
|
||||||
|
size_t scount;
|
||||||
|
uint64_t soff, items;
|
||||||
|
- int rc;
|
||||||
|
+
|
||||||
|
+ assert(uki);
|
||||||
|
+ assert(ret);
|
||||||
|
+ assert(ret_n);
|
||||||
|
|
||||||
|
items = fread(&dos, 1, sizeof(dos), uki);
|
||||||
|
if (items != sizeof(dos))
|
||||||
|
@@ -31,9 +34,9 @@ static int pe_sections(FILE *uki, struct PeSectionHeader **ret, size_t *ret_n) {
|
||||||
|
if (memcmp(dos.Magic, dos_file_magic, sizeof(dos_file_magic)) != 0)
|
||||||
|
goto no_sections;
|
||||||
|
|
||||||
|
- rc = fseek(uki, le32toh(dos.ExeHeader), SEEK_SET);
|
||||||
|
- if (rc < 0)
|
||||||
|
+ if (fseek(uki, le32toh(dos.ExeHeader), SEEK_SET) < 0)
|
||||||
|
return log_error_errno(errno, "seek to PE header");
|
||||||
|
+
|
||||||
|
items = fread(&pe, 1, sizeof(pe), uki);
|
||||||
|
if (items != sizeof(pe))
|
||||||
|
return log_error_errno(SYNTHETIC_ERRNO(EIO), "PE header read error");
|
||||||
|
@@ -41,8 +44,7 @@ static int pe_sections(FILE *uki, struct PeSectionHeader **ret, size_t *ret_n) {
|
||||||
|
goto no_sections;
|
||||||
|
|
||||||
|
soff = le32toh(dos.ExeHeader) + sizeof(pe) + le16toh(pe.FileHeader.SizeOfOptionalHeader);
|
||||||
|
- rc = fseek(uki, soff, SEEK_SET);
|
||||||
|
- if (rc < 0)
|
||||||
|
+ if (fseek(uki, soff, SEEK_SET) < 0)
|
||||||
|
return log_error_errno(errno, "seek to PE section headers");
|
||||||
|
|
||||||
|
scount = le16toh(pe.FileHeader.NumberOfSections);
|
||||||
|
@@ -65,58 +67,72 @@ no_sections:
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
-static int find_pe_section(struct PeSectionHeader *sections, size_t scount,
|
||||||
|
- const uint8_t *name, size_t namelen, size_t *ret) {
|
||||||
|
- for (size_t s = 0; s < scount; s++) {
|
||||||
|
- if (memcmp_nn(sections[s].Name, sizeof(sections[s].Name),
|
||||||
|
- name, namelen) == 0) {
|
||||||
|
+static bool find_pe_section(
|
||||||
|
+ struct PeSectionHeader *sections,
|
||||||
|
+ size_t scount,
|
||||||
|
+ const uint8_t *name,
|
||||||
|
+ size_t namelen,
|
||||||
|
+ size_t *ret) {
|
||||||
|
+
|
||||||
|
+ assert(sections || scount == 0);
|
||||||
|
+ assert(name || namelen == 0);
|
||||||
|
+
|
||||||
|
+ for (size_t s = 0; s < scount; s++)
|
||||||
|
+ if (memcmp_nn(sections[s].Name, sizeof(sections[s].Name), name, namelen) == 0) {
|
||||||
|
if (ret)
|
||||||
|
*ret = s;
|
||||||
|
- return 1;
|
||||||
|
+ return true;
|
||||||
|
}
|
||||||
|
- }
|
||||||
|
- return 0;
|
||||||
|
+
|
||||||
|
+ return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool is_uki(struct PeSectionHeader *sections, size_t scount) {
|
||||||
|
- return (find_pe_section(sections, scount, name_osrel, sizeof(name_osrel), NULL) &&
|
||||||
|
+ assert(sections || scount == 0);
|
||||||
|
+
|
||||||
|
+ return
|
||||||
|
+ find_pe_section(sections, scount, name_osrel, sizeof(name_osrel), NULL) &&
|
||||||
|
find_pe_section(sections, scount, name_linux, sizeof(name_linux), NULL) &&
|
||||||
|
- find_pe_section(sections, scount, name_initrd, sizeof(name_initrd), NULL));
|
||||||
|
+ find_pe_section(sections, scount, name_initrd, sizeof(name_initrd), NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
int verb_kernel_identify(int argc, char *argv[], void *userdata) {
|
||||||
|
_cleanup_fclose_ FILE *uki = NULL;
|
||||||
|
_cleanup_free_ struct PeSectionHeader *sections = NULL;
|
||||||
|
size_t scount;
|
||||||
|
- int rc;
|
||||||
|
+ int r;
|
||||||
|
|
||||||
|
uki = fopen(argv[1], "re");
|
||||||
|
if (!uki)
|
||||||
|
return log_error_errno(errno, "Failed to open UKI file '%s': %m", argv[1]);
|
||||||
|
|
||||||
|
- rc = pe_sections(uki, §ions, &scount);
|
||||||
|
- if (rc < 0)
|
||||||
|
- return EXIT_FAILURE;
|
||||||
|
+ r = pe_sections(uki, §ions, &scount);
|
||||||
|
+ if (r < 0)
|
||||||
|
+ return r;
|
||||||
|
|
||||||
|
- if (sections) {
|
||||||
|
- if (is_uki(sections, scount)) {
|
||||||
|
- puts("uki");
|
||||||
|
- return EXIT_SUCCESS;
|
||||||
|
- }
|
||||||
|
+ if (!sections)
|
||||||
|
+ puts("unknown");
|
||||||
|
+ else if (is_uki(sections, scount))
|
||||||
|
+ puts("uki");
|
||||||
|
+ else
|
||||||
|
puts("pe");
|
||||||
|
- return EXIT_SUCCESS;
|
||||||
|
- }
|
||||||
|
|
||||||
|
- puts("unknown");
|
||||||
|
return EXIT_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
-static int read_pe_section(FILE *uki, const struct PeSectionHeader *section,
|
||||||
|
- void **ret, size_t *ret_n) {
|
||||||
|
+static int read_pe_section(
|
||||||
|
+ FILE *uki,
|
||||||
|
+ const struct PeSectionHeader *section,
|
||||||
|
+ void **ret,
|
||||||
|
+ size_t *ret_n) {
|
||||||
|
+
|
||||||
|
_cleanup_free_ void *data = NULL;
|
||||||
|
uint32_t size, bytes;
|
||||||
|
uint64_t soff;
|
||||||
|
- int rc;
|
||||||
|
+
|
||||||
|
+ assert(uki);
|
||||||
|
+ assert(section);
|
||||||
|
+ assert(ret);
|
||||||
|
|
||||||
|
soff = le32toh(section->PointerToRawData);
|
||||||
|
size = le32toh(section->VirtualSize);
|
||||||
|
@@ -124,8 +140,7 @@ static int read_pe_section(FILE *uki, const struct PeSectionHeader *section,
|
||||||
|
if (size > 16 * 1024)
|
||||||
|
return log_error_errno(SYNTHETIC_ERRNO(E2BIG), "PE section too big");
|
||||||
|
|
||||||
|
- rc = fseek(uki, soff, SEEK_SET);
|
||||||
|
- if (rc < 0)
|
||||||
|
+ if (fseek(uki, soff, SEEK_SET) < 0)
|
||||||
|
return log_error_errno(errno, "seek to PE section");
|
||||||
|
|
||||||
|
data = malloc(size+1);
|
||||||
|
@@ -169,6 +184,9 @@ static void inspect_uki(FILE *uki, struct PeSectionHeader *sections, size_t scou
|
||||||
|
_cleanup_free_ char *osrel = NULL;
|
||||||
|
size_t osrel_size, idx;
|
||||||
|
|
||||||
|
+ assert(uki);
|
||||||
|
+ assert(sections || scount == 0);
|
||||||
|
+
|
||||||
|
if (find_pe_section(sections, scount, name_cmdline, sizeof(name_cmdline), &idx))
|
||||||
|
read_pe_section(uki, sections + idx, (void**)&cmdline, NULL);
|
||||||
|
|
||||||
|
@@ -190,26 +208,23 @@ int verb_kernel_inspect(int argc, char *argv[], void *userdata) {
|
||||||
|
_cleanup_fclose_ FILE *uki = NULL;
|
||||||
|
_cleanup_free_ struct PeSectionHeader *sections = NULL;
|
||||||
|
size_t scount;
|
||||||
|
- int rc;
|
||||||
|
+ int r;
|
||||||
|
|
||||||
|
uki = fopen(argv[1], "re");
|
||||||
|
if (!uki)
|
||||||
|
return log_error_errno(errno, "Failed to open UKI file '%s': %m", argv[1]);
|
||||||
|
|
||||||
|
- rc = pe_sections(uki, §ions, &scount);
|
||||||
|
- if (rc < 0)
|
||||||
|
- return EXIT_FAILURE;
|
||||||
|
+ r = pe_sections(uki, §ions, &scount);
|
||||||
|
+ if (r < 0)
|
||||||
|
+ return r;
|
||||||
|
|
||||||
|
- if (sections) {
|
||||||
|
- if (is_uki(sections, scount)) {
|
||||||
|
- puts("Kernel Type: uki");
|
||||||
|
- inspect_uki(uki, sections, scount);
|
||||||
|
- return EXIT_SUCCESS;
|
||||||
|
- }
|
||||||
|
+ if (!sections)
|
||||||
|
+ puts("Kernel Type: unknown");
|
||||||
|
+ else if (is_uki(sections, scount)) {
|
||||||
|
+ puts("Kernel Type: uki");
|
||||||
|
+ inspect_uki(uki, sections, scount);
|
||||||
|
+ } else
|
||||||
|
puts("Kernel Type: pe");
|
||||||
|
- return EXIT_SUCCESS;
|
||||||
|
- }
|
||||||
|
|
||||||
|
- puts("Kernel Type: unknown");
|
||||||
|
return EXIT_SUCCESS;
|
||||||
|
}
|
@ -0,0 +1,171 @@
|
|||||||
|
From a83545ba5d0cc1b29f2bb4e2b794ce14b138e3fe Mon Sep 17 00:00:00 2001
|
||||||
|
From: Lennart Poettering <lennart@poettering.net>
|
||||||
|
Date: Mon, 23 Jan 2023 12:28:38 +0100
|
||||||
|
Subject: [PATCH] tree-wide: unify how we pick OS pretty name to display
|
||||||
|
|
||||||
|
(cherry picked from commit 02b7005e38db756711cd6463bda34e93cf304c3c)
|
||||||
|
|
||||||
|
Related: RHEL-16354
|
||||||
|
---
|
||||||
|
src/analyze/analyze-plot.c | 3 ++-
|
||||||
|
src/basic/os-util.c | 9 +++++++++
|
||||||
|
src/basic/os-util.h | 2 ++
|
||||||
|
src/core/main.c | 2 +-
|
||||||
|
src/firstboot/firstboot.c | 5 +++--
|
||||||
|
src/hostname/hostnamed.c | 7 ++++++-
|
||||||
|
src/journal-remote/journal-gatewayd.c | 9 ++++++---
|
||||||
|
7 files changed, 29 insertions(+), 8 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/src/analyze/analyze-plot.c b/src/analyze/analyze-plot.c
|
||||||
|
index 24f4add099..8aca691b3d 100644
|
||||||
|
--- a/src/analyze/analyze-plot.c
|
||||||
|
+++ b/src/analyze/analyze-plot.c
|
||||||
|
@@ -6,6 +6,7 @@
|
||||||
|
#include "bus-error.h"
|
||||||
|
#include "bus-map-properties.h"
|
||||||
|
#include "format-table.h"
|
||||||
|
+#include "os-util.h"
|
||||||
|
#include "sort-util.h"
|
||||||
|
#include "version.h"
|
||||||
|
|
||||||
|
@@ -283,7 +284,7 @@ static int produce_plot_as_svg(
|
||||||
|
svg("<text x=\"20\" y=\"50\">%s</text>", pretty_times);
|
||||||
|
if (host)
|
||||||
|
svg("<text x=\"20\" y=\"30\">%s %s (%s %s %s) %s %s</text>",
|
||||||
|
- isempty(host->os_pretty_name) ? "Linux" : host->os_pretty_name,
|
||||||
|
+ os_release_pretty_name(host->os_pretty_name, NULL),
|
||||||
|
strempty(host->hostname),
|
||||||
|
strempty(host->kernel_name),
|
||||||
|
strempty(host->kernel_release),
|
||||||
|
diff --git a/src/basic/os-util.c b/src/basic/os-util.c
|
||||||
|
index 8f8bb0881e..66cbfc76a5 100644
|
||||||
|
--- a/src/basic/os-util.c
|
||||||
|
+++ b/src/basic/os-util.c
|
||||||
|
@@ -370,3 +370,12 @@ int os_release_support_ended(const char *support_end, bool quiet) {
|
||||||
|
usec_t ts = now(CLOCK_REALTIME);
|
||||||
|
return DIV_ROUND_UP(ts, USEC_PER_SEC) > (usec_t) eol;
|
||||||
|
}
|
||||||
|
+
|
||||||
|
+const char *os_release_pretty_name(const char *pretty_name, const char *name) {
|
||||||
|
+ /* Distills a "pretty" name to show from os-release data. First argument is supposed to be the
|
||||||
|
+ * PRETTY_NAME= field, the second one the NAME= field. This function is trivial, of course, and
|
||||||
|
+ * exists mostly to ensure we use the same logic wherever possible. */
|
||||||
|
+
|
||||||
|
+ return empty_to_null(pretty_name) ?:
|
||||||
|
+ empty_to_null(name) ?: "Linux";
|
||||||
|
+}
|
||||||
|
diff --git a/src/basic/os-util.h b/src/basic/os-util.h
|
||||||
|
index d22f5ab8e7..1239f6f6b7 100644
|
||||||
|
--- a/src/basic/os-util.h
|
||||||
|
+++ b/src/basic/os-util.h
|
||||||
|
@@ -33,3 +33,5 @@ int load_os_release_pairs(const char *root, char ***ret);
|
||||||
|
int load_os_release_pairs_with_prefix(const char *root, const char *prefix, char ***ret);
|
||||||
|
|
||||||
|
int os_release_support_ended(const char *support_end, bool quiet);
|
||||||
|
+
|
||||||
|
+const char *os_release_pretty_name(const char *pretty_name, const char *name);
|
||||||
|
diff --git a/src/core/main.c b/src/core/main.c
|
||||||
|
index d3ec526e7e..0e2e5448bb 100644
|
||||||
|
--- a/src/core/main.c
|
||||||
|
+++ b/src/core/main.c
|
||||||
|
@@ -1339,7 +1339,7 @@ static int os_release_status(void) {
|
||||||
|
return log_full_errno(r == -ENOENT ? LOG_DEBUG : LOG_WARNING, r,
|
||||||
|
"Failed to read os-release file, ignoring: %m");
|
||||||
|
|
||||||
|
- const char *label = empty_to_null(pretty_name) ?: empty_to_null(name) ?: "Linux";
|
||||||
|
+ const char *label = os_release_pretty_name(pretty_name, name);
|
||||||
|
|
||||||
|
if (show_status_on(arg_show_status)) {
|
||||||
|
if (log_get_show_color())
|
||||||
|
diff --git a/src/firstboot/firstboot.c b/src/firstboot/firstboot.c
|
||||||
|
index 63db78b52d..10eda1d302 100644
|
||||||
|
--- a/src/firstboot/firstboot.c
|
||||||
|
+++ b/src/firstboot/firstboot.c
|
||||||
|
@@ -96,7 +96,7 @@ static bool press_any_key(void) {
|
||||||
|
}
|
||||||
|
|
||||||
|
static void print_welcome(void) {
|
||||||
|
- _cleanup_free_ char *pretty_name = NULL, *ansi_color = NULL;
|
||||||
|
+ _cleanup_free_ char *pretty_name = NULL, *os_name = NULL, *ansi_color = NULL;
|
||||||
|
static bool done = false;
|
||||||
|
const char *pn, *ac;
|
||||||
|
int r;
|
||||||
|
@@ -110,12 +110,13 @@ static void print_welcome(void) {
|
||||||
|
r = parse_os_release(
|
||||||
|
arg_root,
|
||||||
|
"PRETTY_NAME", &pretty_name,
|
||||||
|
+ "NAME", &os_name,
|
||||||
|
"ANSI_COLOR", &ansi_color);
|
||||||
|
if (r < 0)
|
||||||
|
log_full_errno(r == -ENOENT ? LOG_DEBUG : LOG_WARNING, r,
|
||||||
|
"Failed to read os-release file, ignoring: %m");
|
||||||
|
|
||||||
|
- pn = isempty(pretty_name) ? "Linux" : pretty_name;
|
||||||
|
+ pn = os_release_pretty_name(pretty_name, os_name);
|
||||||
|
ac = isempty(ansi_color) ? "0" : ansi_color;
|
||||||
|
|
||||||
|
if (colors_enabled())
|
||||||
|
diff --git a/src/hostname/hostnamed.c b/src/hostname/hostnamed.c
|
||||||
|
index 486b093062..2a675caada 100644
|
||||||
|
--- a/src/hostname/hostnamed.c
|
||||||
|
+++ b/src/hostname/hostnamed.c
|
||||||
|
@@ -147,6 +147,7 @@ static void context_read_machine_info(Context *c) {
|
||||||
|
}
|
||||||
|
|
||||||
|
static void context_read_os_release(Context *c) {
|
||||||
|
+ _cleanup_free_ char *os_name = NULL, *os_pretty_name = NULL;
|
||||||
|
struct stat current_stat = {};
|
||||||
|
int r;
|
||||||
|
|
||||||
|
@@ -163,12 +164,16 @@ static void context_read_os_release(Context *c) {
|
||||||
|
(UINT64_C(1) << PROP_OS_HOME_URL));
|
||||||
|
|
||||||
|
r = parse_os_release(NULL,
|
||||||
|
- "PRETTY_NAME", &c->data[PROP_OS_PRETTY_NAME],
|
||||||
|
+ "PRETTY_NAME", &os_pretty_name,
|
||||||
|
+ "NAME", &os_name,
|
||||||
|
"CPE_NAME", &c->data[PROP_OS_CPE_NAME],
|
||||||
|
"HOME_URL", &c->data[PROP_OS_HOME_URL]);
|
||||||
|
if (r < 0 && r != -ENOENT)
|
||||||
|
log_warning_errno(r, "Failed to read os-release file, ignoring: %m");
|
||||||
|
|
||||||
|
+ if (free_and_strdup(&c->data[PROP_OS_PRETTY_NAME], os_release_pretty_name(os_pretty_name, os_name)) < 0)
|
||||||
|
+ log_oom();
|
||||||
|
+
|
||||||
|
c->etc_os_release_stat = current_stat;
|
||||||
|
}
|
||||||
|
|
||||||
|
diff --git a/src/journal-remote/journal-gatewayd.c b/src/journal-remote/journal-gatewayd.c
|
||||||
|
index 34def4670e..e848ae5026 100644
|
||||||
|
--- a/src/journal-remote/journal-gatewayd.c
|
||||||
|
+++ b/src/journal-remote/journal-gatewayd.c
|
||||||
|
@@ -732,7 +732,7 @@ static int request_handler_machine(
|
||||||
|
_cleanup_(MHD_destroy_responsep) struct MHD_Response *response = NULL;
|
||||||
|
RequestMeta *m = ASSERT_PTR(connection_cls);
|
||||||
|
int r;
|
||||||
|
- _cleanup_free_ char* hostname = NULL, *os_name = NULL;
|
||||||
|
+ _cleanup_free_ char* hostname = NULL, *pretty_name = NULL, *os_name = NULL;
|
||||||
|
uint64_t cutoff_from = 0, cutoff_to = 0, usage = 0;
|
||||||
|
sd_id128_t mid, bid;
|
||||||
|
_cleanup_free_ char *v = NULL, *json = NULL;
|
||||||
|
@@ -763,7 +763,10 @@ static int request_handler_machine(
|
||||||
|
if (r < 0)
|
||||||
|
return mhd_respondf(connection, r, MHD_HTTP_INTERNAL_SERVER_ERROR, "Failed to determine disk usage: %m");
|
||||||
|
|
||||||
|
- (void) parse_os_release(NULL, "PRETTY_NAME", &os_name);
|
||||||
|
+ (void) parse_os_release(
|
||||||
|
+ NULL,
|
||||||
|
+ "PRETTY_NAME", &pretty_name,
|
||||||
|
+ "NAME=", &os_name);
|
||||||
|
(void) get_virtualization(&v);
|
||||||
|
|
||||||
|
r = asprintf(&json,
|
||||||
|
@@ -778,7 +781,7 @@ static int request_handler_machine(
|
||||||
|
SD_ID128_FORMAT_VAL(mid),
|
||||||
|
SD_ID128_FORMAT_VAL(bid),
|
||||||
|
hostname_cleanup(hostname),
|
||||||
|
- os_name ? os_name : "Linux",
|
||||||
|
+ os_release_pretty_name(pretty_name, os_name),
|
||||||
|
v ? v : "bare",
|
||||||
|
usage,
|
||||||
|
cutoff_from,
|
@ -0,0 +1,102 @@
|
|||||||
|
From 5374c8fb7c32e79f9dcd24333e5c117bd8963a1a Mon Sep 17 00:00:00 2001
|
||||||
|
From: Yu Watanabe <watanabe.yu+github@gmail.com>
|
||||||
|
Date: Wed, 25 Jan 2023 11:05:46 +0900
|
||||||
|
Subject: [PATCH] bootctl-uki: several follow-ups for inspect_osrel()
|
||||||
|
|
||||||
|
Follow-ups for #26124 and #26158.
|
||||||
|
|
||||||
|
- use os_release_pretty_name(),
|
||||||
|
- constify the buffer passed to inspect_osrel(),
|
||||||
|
- propagate errors in inspect_osrele(), and ignore them in the caller
|
||||||
|
side,
|
||||||
|
- and several coding style fixlets.
|
||||||
|
|
||||||
|
(cherry picked from commit 1b7586df976d7b033b4901a099337d83578bb8f1)
|
||||||
|
|
||||||
|
Related: RHEL-16354
|
||||||
|
---
|
||||||
|
src/boot/bootctl-uki.c | 36 ++++++++++++++++++++----------------
|
||||||
|
1 file changed, 20 insertions(+), 16 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/src/boot/bootctl-uki.c b/src/boot/bootctl-uki.c
|
||||||
|
index 3492fa548f..fd249c43fb 100644
|
||||||
|
--- a/src/boot/bootctl-uki.c
|
||||||
|
+++ b/src/boot/bootctl-uki.c
|
||||||
|
@@ -3,6 +3,7 @@
|
||||||
|
#include "bootctl-uki.h"
|
||||||
|
#include "env-file.h"
|
||||||
|
#include "fd-util.h"
|
||||||
|
+#include "os-util.h"
|
||||||
|
#include "parse-util.h"
|
||||||
|
#include "pe-header.h"
|
||||||
|
|
||||||
|
@@ -158,50 +159,53 @@ static int read_pe_section(
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
-static void inspect_osrel(char *osrel, size_t osrel_size) {
|
||||||
|
+static int inspect_osrel(const void *osrel, size_t osrel_size) {
|
||||||
|
_cleanup_fclose_ FILE *s = NULL;
|
||||||
|
_cleanup_free_ char *pname = NULL, *name = NULL;
|
||||||
|
int r;
|
||||||
|
|
||||||
|
- assert(osrel);
|
||||||
|
- s = fmemopen(osrel, osrel_size, "r");
|
||||||
|
+ assert(osrel || osrel_size == 0);
|
||||||
|
+
|
||||||
|
+ if (!osrel)
|
||||||
|
+ return 0;
|
||||||
|
+
|
||||||
|
+ s = fmemopen((void*) osrel, osrel_size, "r");
|
||||||
|
if (!s)
|
||||||
|
- return (void) log_warning_errno(errno, "Failed to open embedded os-release file, ignoring: %m");
|
||||||
|
+ return log_warning_errno(errno, "Failed to open embedded os-release file, ignoring: %m");
|
||||||
|
|
||||||
|
r = parse_env_file(s, NULL,
|
||||||
|
"PRETTY_NAME", &pname,
|
||||||
|
"NAME", &name);
|
||||||
|
if (r < 0)
|
||||||
|
- return (void) log_warning_errno(r, "Failed to parse embedded os-release file, ignoring: %m");
|
||||||
|
+ return log_warning_errno(r, "Failed to parse embedded os-release file, ignoring: %m");
|
||||||
|
|
||||||
|
- if (pname || name)
|
||||||
|
- printf(" OS: %s\n", pname ?: name);
|
||||||
|
+ printf(" OS: %s\n", os_release_pretty_name(pname, name));
|
||||||
|
+ return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void inspect_uki(FILE *uki, struct PeSectionHeader *sections, size_t scount) {
|
||||||
|
- _cleanup_free_ char *cmdline = NULL;
|
||||||
|
- _cleanup_free_ char *uname = NULL;
|
||||||
|
- _cleanup_free_ char *osrel = NULL;
|
||||||
|
- size_t osrel_size, idx;
|
||||||
|
+ _cleanup_free_ char *cmdline = NULL, *uname = NULL;
|
||||||
|
+ _cleanup_free_ void *osrel = NULL;
|
||||||
|
+ size_t osrel_size = 0, idx;
|
||||||
|
|
||||||
|
assert(uki);
|
||||||
|
assert(sections || scount == 0);
|
||||||
|
|
||||||
|
if (find_pe_section(sections, scount, name_cmdline, sizeof(name_cmdline), &idx))
|
||||||
|
- read_pe_section(uki, sections + idx, (void**)&cmdline, NULL);
|
||||||
|
+ read_pe_section(uki, sections + idx, (void**) &cmdline, NULL);
|
||||||
|
|
||||||
|
if (find_pe_section(sections, scount, name_uname, sizeof(name_uname), &idx))
|
||||||
|
- read_pe_section(uki, sections + idx, (void**)&uname, NULL);
|
||||||
|
+ read_pe_section(uki, sections + idx, (void**) &uname, NULL);
|
||||||
|
|
||||||
|
if (find_pe_section(sections, scount, name_osrel, sizeof(name_osrel), &idx))
|
||||||
|
- read_pe_section(uki, sections + idx, (void**)&osrel, &osrel_size);
|
||||||
|
+ read_pe_section(uki, sections + idx, &osrel, &osrel_size);
|
||||||
|
|
||||||
|
if (cmdline)
|
||||||
|
printf(" Cmdline: %s\n", cmdline);
|
||||||
|
if (uname)
|
||||||
|
printf(" Version: %s\n", uname);
|
||||||
|
- if (osrel)
|
||||||
|
- inspect_osrel(osrel, osrel_size);
|
||||||
|
+
|
||||||
|
+ (void) inspect_osrel(osrel, osrel_size);
|
||||||
|
}
|
||||||
|
|
||||||
|
int verb_kernel_inspect(int argc, char *argv[], void *userdata) {
|
@ -0,0 +1,25 @@
|
|||||||
|
From 47a9030cad80a684b9affcc2c35ef264e7a8b145 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Daan De Meyer <daan.j.demeyer@gmail.com>
|
||||||
|
Date: Thu, 9 Feb 2023 10:44:35 +0100
|
||||||
|
Subject: [PATCH] bootctl: Add missing %m
|
||||||
|
|
||||||
|
(cherry picked from commit 3b42ffe590c5728af50feb138890a44264c4b02e)
|
||||||
|
|
||||||
|
Related: RHEL-16354
|
||||||
|
---
|
||||||
|
src/boot/bootctl.c | 2 +-
|
||||||
|
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||||
|
|
||||||
|
diff --git a/src/boot/bootctl.c b/src/boot/bootctl.c
|
||||||
|
index 3044f67b5a..a0ca2afec2 100644
|
||||||
|
--- a/src/boot/bootctl.c
|
||||||
|
+++ b/src/boot/bootctl.c
|
||||||
|
@@ -1420,7 +1420,7 @@ static int install_entry_token(void) {
|
||||||
|
|
||||||
|
r = write_string_file("/etc/kernel/entry-token", arg_entry_token, WRITE_STRING_FILE_CREATE|WRITE_STRING_FILE_ATOMIC|WRITE_STRING_FILE_MKDIR_0755);
|
||||||
|
if (r < 0)
|
||||||
|
- return log_error_errno(r, "Failed to write entry token '%s' to /etc/kernel/entry-token", arg_entry_token);
|
||||||
|
+ return log_error_errno(r, "Failed to write entry token '%s' to /etc/kernel/entry-token: %m", arg_entry_token);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
@ -0,0 +1,41 @@
|
|||||||
|
From 618e38b8b775f45c0a18975ae33753b92c954092 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Gerd Hoffmann <kraxel@redhat.com>
|
||||||
|
Date: Tue, 24 Jan 2023 10:28:25 +0100
|
||||||
|
Subject: [PATCH] bootctl: tweak DOS header magic check
|
||||||
|
|
||||||
|
Read the magic first, try reading the full DOS exe header only in case
|
||||||
|
the magic check succeeds.
|
||||||
|
|
||||||
|
This avoids throwing an header read error on small dummy files as used
|
||||||
|
by test-kernel-install.
|
||||||
|
|
||||||
|
(cherry picked from commit 78088b8f43717a43661cd2c1627a9860904c4794)
|
||||||
|
|
||||||
|
Related: RHEL-16354
|
||||||
|
---
|
||||||
|
src/boot/bootctl-uki.c | 9 +++++++--
|
||||||
|
1 file changed, 7 insertions(+), 2 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/src/boot/bootctl-uki.c b/src/boot/bootctl-uki.c
|
||||||
|
index fd249c43fb..d90a850b1c 100644
|
||||||
|
--- a/src/boot/bootctl-uki.c
|
||||||
|
+++ b/src/boot/bootctl-uki.c
|
||||||
|
@@ -30,11 +30,16 @@ static int pe_sections(FILE *uki, struct PeSectionHeader **ret, size_t *ret_n) {
|
||||||
|
assert(ret_n);
|
||||||
|
|
||||||
|
items = fread(&dos, 1, sizeof(dos), uki);
|
||||||
|
- if (items != sizeof(dos))
|
||||||
|
- return log_error_errno(SYNTHETIC_ERRNO(EIO), "DOS header read error");
|
||||||
|
+ if (items < sizeof(dos.Magic))
|
||||||
|
+ return log_error_errno(SYNTHETIC_ERRNO(EIO), "File is smaller than DOS magic (got %"PRIu64" of %zu bytes)",
|
||||||
|
+ items, sizeof(dos.Magic));
|
||||||
|
if (memcmp(dos.Magic, dos_file_magic, sizeof(dos_file_magic)) != 0)
|
||||||
|
goto no_sections;
|
||||||
|
|
||||||
|
+ if (items != sizeof(dos))
|
||||||
|
+ return log_error_errno(SYNTHETIC_ERRNO(EIO), "File is smaller than DOS header (got %"PRIu64" of %zu bytes)",
|
||||||
|
+ items, sizeof(dos));
|
||||||
|
+
|
||||||
|
if (fseek(uki, le32toh(dos.ExeHeader), SEEK_SET) < 0)
|
||||||
|
return log_error_errno(errno, "seek to PE header");
|
||||||
|
|
@ -0,0 +1,30 @@
|
|||||||
|
From a1bd733809ff01c64a8a304a45e57277a5a98463 Mon Sep 17 00:00:00 2001
|
||||||
|
From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= <zbyszek@in.waw.pl>
|
||||||
|
Date: Fri, 8 Dec 2023 19:35:37 +0100
|
||||||
|
Subject: [PATCH] meson: fix installation of ukify
|
||||||
|
|
||||||
|
ln_s was added in upstream later on. It's not present in this branch.
|
||||||
|
Fixup for b98da2d9e7.
|
||||||
|
|
||||||
|
Related: RHEL-13199
|
||||||
|
---
|
||||||
|
meson.build | 6 +++---
|
||||||
|
1 file changed, 3 insertions(+), 3 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/meson.build b/meson.build
|
||||||
|
index 936e612a01..e09c426a72 100644
|
||||||
|
--- a/meson.build
|
||||||
|
+++ b/meson.build
|
||||||
|
@@ -3868,9 +3868,9 @@ ukify = custom_target(
|
||||||
|
if want_ukify
|
||||||
|
public_programs += ukify
|
||||||
|
|
||||||
|
- meson.add_install_script(sh, '-c',
|
||||||
|
- ln_s.format(bindir / 'ukify',
|
||||||
|
- rootlibexecdir / 'ukify'))
|
||||||
|
+ meson.add_install_script(meson_make_symlink,
|
||||||
|
+ bindir / 'ukify',
|
||||||
|
+ rootlibexecdir / 'ukify')
|
||||||
|
endif
|
||||||
|
|
||||||
|
if want_tests != 'false' and want_kernel_install
|
@ -0,0 +1,37 @@
|
|||||||
|
From 81802cf297a05d202aae5de21673fcc7064f9b7d Mon Sep 17 00:00:00 2001
|
||||||
|
From: Yu Watanabe <watanabe.yu+github@gmail.com>
|
||||||
|
Date: Fri, 28 Oct 2022 09:08:09 +0900
|
||||||
|
Subject: [PATCH] sd-id128: introduce id128_hash_ops_free
|
||||||
|
|
||||||
|
(cherry picked from commit 3e61656fab869bb40f019c38c3347885238294de)
|
||||||
|
|
||||||
|
Related: RHEL-5988
|
||||||
|
---
|
||||||
|
src/libsystemd/sd-id128/id128-util.c | 1 +
|
||||||
|
src/libsystemd/sd-id128/id128-util.h | 1 +
|
||||||
|
2 files changed, 2 insertions(+)
|
||||||
|
|
||||||
|
diff --git a/src/libsystemd/sd-id128/id128-util.c b/src/libsystemd/sd-id128/id128-util.c
|
||||||
|
index 4f52c14f64..cef340f3bc 100644
|
||||||
|
--- a/src/libsystemd/sd-id128/id128-util.c
|
||||||
|
+++ b/src/libsystemd/sd-id128/id128-util.c
|
||||||
|
@@ -184,6 +184,7 @@ sd_id128_t id128_make_v4_uuid(sd_id128_t id) {
|
||||||
|
}
|
||||||
|
|
||||||
|
DEFINE_HASH_OPS(id128_hash_ops, sd_id128_t, id128_hash_func, id128_compare_func);
|
||||||
|
+DEFINE_HASH_OPS_WITH_KEY_DESTRUCTOR(id128_hash_ops_free, sd_id128_t, id128_hash_func, id128_compare_func, free);
|
||||||
|
|
||||||
|
int id128_get_product(sd_id128_t *ret) {
|
||||||
|
sd_id128_t uuid;
|
||||||
|
diff --git a/src/libsystemd/sd-id128/id128-util.h b/src/libsystemd/sd-id128/id128-util.h
|
||||||
|
index 17b180c10c..9d8fe93641 100644
|
||||||
|
--- a/src/libsystemd/sd-id128/id128-util.h
|
||||||
|
+++ b/src/libsystemd/sd-id128/id128-util.h
|
||||||
|
@@ -30,6 +30,7 @@ int id128_write(const char *p, Id128Format f, sd_id128_t id, bool do_sync);
|
||||||
|
void id128_hash_func(const sd_id128_t *p, struct siphash *state);
|
||||||
|
int id128_compare_func(const sd_id128_t *a, const sd_id128_t *b) _pure_;
|
||||||
|
extern const struct hash_ops id128_hash_ops;
|
||||||
|
+extern const struct hash_ops id128_hash_ops_free;
|
||||||
|
|
||||||
|
sd_id128_t id128_make_v4_uuid(sd_id128_t id);
|
||||||
|
|
@ -0,0 +1,104 @@
|
|||||||
|
From 597c41edd3e94f2c16209359fbd8de7ed44225d7 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Yu Watanabe <watanabe.yu+github@gmail.com>
|
||||||
|
Date: Fri, 28 Oct 2022 10:14:09 +0900
|
||||||
|
Subject: [PATCH] udevadm-trigger: allow to fallback without synthetic UUID
|
||||||
|
only first time
|
||||||
|
|
||||||
|
If a device is successfully triggered with synthetic UUID, then that means
|
||||||
|
the kernel support it. Hence, it is not necessary to fallback without UUID
|
||||||
|
for later devices.
|
||||||
|
|
||||||
|
(cherry picked from commit b15039425feba8f316fb306b75d96e2f0f0b82fa)
|
||||||
|
|
||||||
|
Related: RHEL-5988
|
||||||
|
---
|
||||||
|
src/udev/udevadm-trigger.c | 22 ++++++++++++++--------
|
||||||
|
1 file changed, 14 insertions(+), 8 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/src/udev/udevadm-trigger.c b/src/udev/udevadm-trigger.c
|
||||||
|
index 1d421064d7..cda31edd75 100644
|
||||||
|
--- a/src/udev/udevadm-trigger.c
|
||||||
|
+++ b/src/udev/udevadm-trigger.c
|
||||||
|
@@ -26,17 +26,20 @@ static bool arg_verbose = false;
|
||||||
|
static bool arg_dry_run = false;
|
||||||
|
static bool arg_quiet = false;
|
||||||
|
static bool arg_uuid = false;
|
||||||
|
+static bool arg_settle = false;
|
||||||
|
|
||||||
|
static int exec_list(
|
||||||
|
sd_device_enumerator *e,
|
||||||
|
sd_device_action_t action,
|
||||||
|
Hashmap *settle_hashmap) {
|
||||||
|
|
||||||
|
- bool skip_uuid_logic = false;
|
||||||
|
+ int uuid_supported = -1;
|
||||||
|
const char *action_str;
|
||||||
|
sd_device *d;
|
||||||
|
int r, ret = 0;
|
||||||
|
|
||||||
|
+ assert(e);
|
||||||
|
+
|
||||||
|
action_str = device_action_to_string(action);
|
||||||
|
|
||||||
|
FOREACH_DEVICE_AND_SUBSYSTEM(e, d) {
|
||||||
|
@@ -57,14 +60,14 @@ static int exec_list(
|
||||||
|
|
||||||
|
/* Use the UUID mode if the user explicitly asked for it, or if --settle has been specified,
|
||||||
|
* so that we can recognize our own uevent. */
|
||||||
|
- r = sd_device_trigger_with_uuid(d, action, (arg_uuid || settle_hashmap) && !skip_uuid_logic ? &id : NULL);
|
||||||
|
- if (r == -EINVAL && !arg_uuid && settle_hashmap && !skip_uuid_logic) {
|
||||||
|
+ r = sd_device_trigger_with_uuid(d, action, (arg_uuid || arg_settle) && uuid_supported != 0 ? &id : NULL);
|
||||||
|
+ if (r == -EINVAL && !arg_uuid && arg_settle && uuid_supported < 0) {
|
||||||
|
/* If we specified a UUID because of the settling logic, and we got EINVAL this might
|
||||||
|
* be caused by an old kernel which doesn't know the UUID logic (pre-4.13). Let's try
|
||||||
|
* if it works without the UUID logic then. */
|
||||||
|
r = sd_device_trigger(d, action);
|
||||||
|
if (r != -EINVAL)
|
||||||
|
- skip_uuid_logic = true; /* dropping the uuid stuff changed the return code,
|
||||||
|
+ uuid_supported = false; /* dropping the uuid stuff changed the return code,
|
||||||
|
* hence don't bother next time */
|
||||||
|
}
|
||||||
|
if (r < 0) {
|
||||||
|
@@ -108,11 +111,14 @@ static int exec_list(
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
+ if (uuid_supported < 0)
|
||||||
|
+ uuid_supported = true;
|
||||||
|
+
|
||||||
|
/* If the user asked for it, write event UUID to stdout */
|
||||||
|
if (arg_uuid)
|
||||||
|
printf(SD_ID128_UUID_FORMAT_STR "\n", SD_ID128_FORMAT_VAL(id));
|
||||||
|
|
||||||
|
- if (settle_hashmap) {
|
||||||
|
+ if (arg_settle) {
|
||||||
|
_cleanup_free_ sd_id128_t *mid = NULL;
|
||||||
|
_cleanup_free_ char *sp = NULL;
|
||||||
|
|
||||||
|
@@ -285,7 +291,7 @@ int trigger_main(int argc, char *argv[], void *userdata) {
|
||||||
|
_cleanup_(sd_event_unrefp) sd_event *event = NULL;
|
||||||
|
_cleanup_hashmap_free_ Hashmap *settle_hashmap = NULL;
|
||||||
|
usec_t ping_timeout_usec = 5 * USEC_PER_SEC;
|
||||||
|
- bool settle = false, ping = false;
|
||||||
|
+ bool ping = false;
|
||||||
|
int c, r;
|
||||||
|
|
||||||
|
if (running_in_chroot() > 0) {
|
||||||
|
@@ -389,7 +395,7 @@ int trigger_main(int argc, char *argv[], void *userdata) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 'w':
|
||||||
|
- settle = true;
|
||||||
|
+ arg_settle = true;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case ARG_NAME: {
|
||||||
|
@@ -477,7 +483,7 @@ int trigger_main(int argc, char *argv[], void *userdata) {
|
||||||
|
return log_error_errno(r, "Failed to add parent match '%s': %m", argv[optind]);
|
||||||
|
}
|
||||||
|
|
||||||
|
- if (settle) {
|
||||||
|
+ if (arg_settle) {
|
||||||
|
settle_hashmap = hashmap_new(&path_hash_ops_free_free);
|
||||||
|
if (!settle_hashmap)
|
||||||
|
return log_oom();
|
@ -0,0 +1,196 @@
|
|||||||
|
From 73dbfdaab1d633e3a1ae96cc15c551eaa2fd4243 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Yu Watanabe <watanabe.yu+github@gmail.com>
|
||||||
|
Date: Fri, 28 Oct 2022 10:21:57 +0900
|
||||||
|
Subject: [PATCH] udevadm-trigger: settle with synthetic UUID if the kernel
|
||||||
|
support it
|
||||||
|
|
||||||
|
If the kernel support synthetic UUID in uevent, then let's assume that
|
||||||
|
the UUID is unique, and check only if the received UUID matches we
|
||||||
|
specified.
|
||||||
|
|
||||||
|
Partially fixes #25115.
|
||||||
|
|
||||||
|
(cherry picked from commit dfbd824a0b780310d7f865a6ea0d60434d924683)
|
||||||
|
|
||||||
|
Related: RHEL-5988
|
||||||
|
---
|
||||||
|
src/udev/udevadm-trigger.c | 82 +++++++++++++++++++-------------------
|
||||||
|
1 file changed, 40 insertions(+), 42 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/src/udev/udevadm-trigger.c b/src/udev/udevadm-trigger.c
|
||||||
|
index cda31edd75..3909fa237c 100644
|
||||||
|
--- a/src/udev/udevadm-trigger.c
|
||||||
|
+++ b/src/udev/udevadm-trigger.c
|
||||||
|
@@ -11,10 +11,12 @@
|
||||||
|
#include "device-util.h"
|
||||||
|
#include "fd-util.h"
|
||||||
|
#include "fileio.h"
|
||||||
|
+#include "id128-util.h"
|
||||||
|
#include "parse-util.h"
|
||||||
|
#include "path-util.h"
|
||||||
|
#include "process-util.h"
|
||||||
|
#include "set.h"
|
||||||
|
+#include "static-destruct.h"
|
||||||
|
#include "string-util.h"
|
||||||
|
#include "strv.h"
|
||||||
|
#include "udevadm.h"
|
||||||
|
@@ -31,8 +33,9 @@ static bool arg_settle = false;
|
||||||
|
static int exec_list(
|
||||||
|
sd_device_enumerator *e,
|
||||||
|
sd_device_action_t action,
|
||||||
|
- Hashmap *settle_hashmap) {
|
||||||
|
+ Set **ret_settle_path_or_ids) {
|
||||||
|
|
||||||
|
+ _cleanup_set_free_ Set *settle_path_or_ids = NULL;
|
||||||
|
int uuid_supported = -1;
|
||||||
|
const char *action_str;
|
||||||
|
sd_device *d;
|
||||||
|
@@ -119,60 +122,62 @@ static int exec_list(
|
||||||
|
printf(SD_ID128_UUID_FORMAT_STR "\n", SD_ID128_FORMAT_VAL(id));
|
||||||
|
|
||||||
|
if (arg_settle) {
|
||||||
|
- _cleanup_free_ sd_id128_t *mid = NULL;
|
||||||
|
- _cleanup_free_ char *sp = NULL;
|
||||||
|
+ if (uuid_supported) {
|
||||||
|
+ sd_id128_t *dup;
|
||||||
|
|
||||||
|
- sp = strdup(syspath);
|
||||||
|
- if (!sp)
|
||||||
|
- return log_oom();
|
||||||
|
+ dup = newdup(sd_id128_t, &id, 1);
|
||||||
|
+ if (!dup)
|
||||||
|
+ return log_oom();
|
||||||
|
|
||||||
|
- mid = newdup(sd_id128_t, &id, 1);
|
||||||
|
- if (!d)
|
||||||
|
- return log_oom();
|
||||||
|
+ r = set_ensure_consume(&settle_path_or_ids, &id128_hash_ops_free, dup);
|
||||||
|
+ } else {
|
||||||
|
+ char *dup;
|
||||||
|
+
|
||||||
|
+ dup = strdup(syspath);
|
||||||
|
+ if (!dup)
|
||||||
|
+ return log_oom();
|
||||||
|
|
||||||
|
- r = hashmap_put(settle_hashmap, sp, mid);
|
||||||
|
+ r = set_ensure_consume(&settle_path_or_ids, &path_hash_ops_free, dup);
|
||||||
|
+ }
|
||||||
|
if (r < 0)
|
||||||
|
return log_oom();
|
||||||
|
-
|
||||||
|
- TAKE_PTR(sp);
|
||||||
|
- TAKE_PTR(mid);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
+ if (ret_settle_path_or_ids)
|
||||||
|
+ *ret_settle_path_or_ids = TAKE_PTR(settle_path_or_ids);
|
||||||
|
+
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int device_monitor_handler(sd_device_monitor *m, sd_device *dev, void *userdata) {
|
||||||
|
- Hashmap *settle_hashmap = ASSERT_PTR(userdata);
|
||||||
|
- sd_id128_t *settle_id;
|
||||||
|
+ Set *settle_path_or_ids = * (Set**) ASSERT_PTR(userdata);
|
||||||
|
const char *syspath;
|
||||||
|
- char *k;
|
||||||
|
+ sd_id128_t id;
|
||||||
|
int r;
|
||||||
|
|
||||||
|
assert(dev);
|
||||||
|
|
||||||
|
r = sd_device_get_syspath(dev, &syspath);
|
||||||
|
if (r < 0) {
|
||||||
|
- log_debug_errno(r, "Failed to get syspath of device event, ignoring: %m");
|
||||||
|
+ log_device_debug_errno(dev, r, "Failed to get syspath of device event, ignoring: %m");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
- settle_id = hashmap_get2(settle_hashmap, syspath, (void**) &k);
|
||||||
|
- if (!settle_id) {
|
||||||
|
- log_debug("Got uevent for unexpected device '%s', ignoring.", syspath);
|
||||||
|
- return 0;
|
||||||
|
- }
|
||||||
|
- if (!sd_id128_is_null(*settle_id)) { /* If this is SD_ID128_NULL then we are on pre-4.13 and have no UUID to check, hence don't */
|
||||||
|
- sd_id128_t event_id;
|
||||||
|
+ if (sd_device_get_trigger_uuid(dev, &id) >= 0) {
|
||||||
|
+ _cleanup_free_ sd_id128_t *saved = NULL;
|
||||||
|
|
||||||
|
- r = sd_device_get_trigger_uuid(dev, &event_id);
|
||||||
|
- if (r < 0) {
|
||||||
|
- log_debug_errno(r, "Got uevent without synthetic UUID for device '%s', ignoring: %m", syspath);
|
||||||
|
+ saved = set_remove(settle_path_or_ids, &id);
|
||||||
|
+ if (!saved) {
|
||||||
|
+ log_device_debug(dev, "Got uevent not matching expected UUID, ignoring.");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
+ } else {
|
||||||
|
+ _cleanup_free_ char *saved = NULL;
|
||||||
|
|
||||||
|
- if (!sd_id128_equal(event_id, *settle_id)) {
|
||||||
|
- log_debug("Got uevent not matching expected UUID for device '%s', ignoring.", syspath);
|
||||||
|
+ saved = set_remove(settle_path_or_ids, syspath);
|
||||||
|
+ if (!saved) {
|
||||||
|
+ log_device_debug(dev, "Got uevent for unexpected device, ignoring.");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@@ -181,12 +186,9 @@ static int device_monitor_handler(sd_device_monitor *m, sd_device *dev, void *us
|
||||||
|
printf("settle %s\n", syspath);
|
||||||
|
|
||||||
|
if (arg_uuid)
|
||||||
|
- printf("settle " SD_ID128_UUID_FORMAT_STR "\n", SD_ID128_FORMAT_VAL(*settle_id));
|
||||||
|
+ printf("settle " SD_ID128_UUID_FORMAT_STR "\n", SD_ID128_FORMAT_VAL(id));
|
||||||
|
|
||||||
|
- free(hashmap_remove(settle_hashmap, syspath));
|
||||||
|
- free(k);
|
||||||
|
-
|
||||||
|
- if (hashmap_isempty(settle_hashmap))
|
||||||
|
+ if (set_isempty(settle_path_or_ids))
|
||||||
|
return sd_event_exit(sd_device_monitor_get_event(m), 0);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
@@ -289,7 +291,7 @@ int trigger_main(int argc, char *argv[], void *userdata) {
|
||||||
|
_cleanup_(sd_device_enumerator_unrefp) sd_device_enumerator *e = NULL;
|
||||||
|
_cleanup_(sd_device_monitor_unrefp) sd_device_monitor *m = NULL;
|
||||||
|
_cleanup_(sd_event_unrefp) sd_event *event = NULL;
|
||||||
|
- _cleanup_hashmap_free_ Hashmap *settle_hashmap = NULL;
|
||||||
|
+ _cleanup_set_free_ Set *settle_path_or_ids = NULL;
|
||||||
|
usec_t ping_timeout_usec = 5 * USEC_PER_SEC;
|
||||||
|
bool ping = false;
|
||||||
|
int c, r;
|
||||||
|
@@ -484,10 +486,6 @@ int trigger_main(int argc, char *argv[], void *userdata) {
|
||||||
|
}
|
||||||
|
|
||||||
|
if (arg_settle) {
|
||||||
|
- settle_hashmap = hashmap_new(&path_hash_ops_free_free);
|
||||||
|
- if (!settle_hashmap)
|
||||||
|
- return log_oom();
|
||||||
|
-
|
||||||
|
r = sd_event_default(&event);
|
||||||
|
if (r < 0)
|
||||||
|
return log_error_errno(r, "Failed to get default event: %m");
|
||||||
|
@@ -500,7 +498,7 @@ int trigger_main(int argc, char *argv[], void *userdata) {
|
||||||
|
if (r < 0)
|
||||||
|
return log_error_errno(r, "Failed to attach event to device monitor: %m");
|
||||||
|
|
||||||
|
- r = sd_device_monitor_start(m, device_monitor_handler, settle_hashmap);
|
||||||
|
+ r = sd_device_monitor_start(m, device_monitor_handler, &settle_path_or_ids);
|
||||||
|
if (r < 0)
|
||||||
|
return log_error_errno(r, "Failed to start device monitor: %m");
|
||||||
|
}
|
||||||
|
@@ -525,11 +523,11 @@ int trigger_main(int argc, char *argv[], void *userdata) {
|
||||||
|
assert_not_reached();
|
||||||
|
}
|
||||||
|
|
||||||
|
- r = exec_list(e, action, settle_hashmap);
|
||||||
|
+ r = exec_list(e, action, arg_settle ? &settle_path_or_ids : NULL);
|
||||||
|
if (r < 0)
|
||||||
|
return r;
|
||||||
|
|
||||||
|
- if (event && !hashmap_isempty(settle_hashmap)) {
|
||||||
|
+ if (!set_isempty(settle_path_or_ids)) {
|
||||||
|
r = sd_event_loop(event);
|
||||||
|
if (r < 0)
|
||||||
|
return log_error_errno(r, "Event loop failed: %m");
|
@ -0,0 +1,56 @@
|
|||||||
|
From 4007f494b2e4c45f2d59948af3f4053258d3f127 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Yu Watanabe <watanabe.yu+github@gmail.com>
|
||||||
|
Date: Fri, 28 Oct 2022 09:06:02 +0900
|
||||||
|
Subject: [PATCH] udevadm-trigger: also check with the original syspath if
|
||||||
|
device is renamed
|
||||||
|
|
||||||
|
For older kernels that synthetic UUID is not supported, we need to also
|
||||||
|
check the original device name, as udevd broadcasts uevent with new
|
||||||
|
sysname.
|
||||||
|
|
||||||
|
Fixes #25115.
|
||||||
|
|
||||||
|
(cherry picked from commit 1193448cb68e5a90cab027e16a093bbd367e9494)
|
||||||
|
|
||||||
|
Related: RHEL-5988
|
||||||
|
---
|
||||||
|
src/udev/udevadm-trigger.c | 26 ++++++++++++++++++++++++++
|
||||||
|
1 file changed, 26 insertions(+)
|
||||||
|
|
||||||
|
diff --git a/src/udev/udevadm-trigger.c b/src/udev/udevadm-trigger.c
|
||||||
|
index 3909fa237c..40ee5085a0 100644
|
||||||
|
--- a/src/udev/udevadm-trigger.c
|
||||||
|
+++ b/src/udev/udevadm-trigger.c
|
||||||
|
@@ -176,6 +176,32 @@ static int device_monitor_handler(sd_device_monitor *m, sd_device *dev, void *us
|
||||||
|
_cleanup_free_ char *saved = NULL;
|
||||||
|
|
||||||
|
saved = set_remove(settle_path_or_ids, syspath);
|
||||||
|
+ if (!saved) {
|
||||||
|
+ const char *old_sysname;
|
||||||
|
+
|
||||||
|
+ /* When the device is renamed, the new name is broadcast, and the old name is saved
|
||||||
|
+ * in INTERFACE_OLD. */
|
||||||
|
+
|
||||||
|
+ if (sd_device_get_property_value(dev, "INTERFACE_OLD", &old_sysname) >= 0) {
|
||||||
|
+ _cleanup_free_ char *dir = NULL, *old_syspath = NULL;
|
||||||
|
+
|
||||||
|
+ r = path_extract_directory(syspath, &dir);
|
||||||
|
+ if (r < 0) {
|
||||||
|
+ log_device_debug_errno(dev, r,
|
||||||
|
+ "Failed to extract directory from '%s', ignoring: %m",
|
||||||
|
+ syspath);
|
||||||
|
+ return 0;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ old_syspath = path_join(dir, old_sysname);
|
||||||
|
+ if (!old_syspath) {
|
||||||
|
+ log_oom_debug();
|
||||||
|
+ return 0;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ saved = set_remove(settle_path_or_ids, old_syspath);
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
if (!saved) {
|
||||||
|
log_device_debug(dev, "Got uevent for unexpected device, ignoring.");
|
||||||
|
return 0;
|
@ -0,0 +1,37 @@
|
|||||||
|
From ff755f035485eab0317d1320caa2748d5d4a2d78 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Yu Watanabe <watanabe.yu+github@gmail.com>
|
||||||
|
Date: Thu, 27 Oct 2022 05:48:05 +0900
|
||||||
|
Subject: [PATCH] test: use 'udevadm trigger --settle' even if device is
|
||||||
|
renamed
|
||||||
|
|
||||||
|
(cherry picked from commit ff4d2a09fd141474cb552d4b5bd5a53d9748a1b4)
|
||||||
|
|
||||||
|
Related: RHEL-5988
|
||||||
|
---
|
||||||
|
test/units/testsuite-17.02.sh | 6 ++----
|
||||||
|
1 file changed, 2 insertions(+), 4 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/test/units/testsuite-17.02.sh b/test/units/testsuite-17.02.sh
|
||||||
|
index ed3b39d074..82f9fd1f62 100755
|
||||||
|
--- a/test/units/testsuite-17.02.sh
|
||||||
|
+++ b/test/units/testsuite-17.02.sh
|
||||||
|
@@ -61,9 +61,7 @@ EOF
|
||||||
|
|
||||||
|
udevadm control --log-priority=debug --reload --timeout=30
|
||||||
|
|
||||||
|
-# FIXME(?): the 'add' uevent is broadcast as for 'foobar', instead of 'hoge'. Hence, we cannot use --settle here.
|
||||||
|
-# See issue #25115.
|
||||||
|
-udevadm trigger --action=add /sys/devices/virtual/net/hoge
|
||||||
|
+udevadm trigger --action=add --settle /sys/devices/virtual/net/hoge
|
||||||
|
udevadm wait --timeout=30 --settle /sys/devices/virtual/net/foobar
|
||||||
|
assert_not_in "ID_RENAMING=" "$(udevadm info /sys/devices/virtual/net/foobar)"
|
||||||
|
timeout 30 bash -c 'while [[ "$(systemctl show --property=ActiveState --value /sys/devices/virtual/net/hoge)" != "inactive" ]]; do sleep .5; done'
|
||||||
|
@@ -71,7 +69,7 @@ timeout 30 bash -c 'while [[ "$(systemctl show --property=ActiveState --value /s
|
||||||
|
timeout 30 bash -c 'while [[ "$(systemctl show --property=ActiveState --value /sys/devices/virtual/net/foobar)" != "active" ]]; do sleep .5; done'
|
||||||
|
timeout 30 bash -c 'while [[ "$(systemctl show --property=ActiveState --value /sys/subsystem/net/devices/foobar)" != "active" ]]; do sleep .5; done'
|
||||||
|
|
||||||
|
-udevadm trigger --action=add /sys/devices/virtual/net/foobar
|
||||||
|
+udevadm trigger --action=add --settle /sys/devices/virtual/net/foobar
|
||||||
|
udevadm wait --timeout=30 --settle /sys/devices/virtual/net/hoge
|
||||||
|
assert_not_in "ID_RENAMING=" "$(udevadm info /sys/devices/virtual/net/hoge)"
|
||||||
|
timeout 30 bash -c 'while [[ "$(systemctl show --property=ActiveState --value /sys/devices/virtual/net/hoge)" != "active" ]]; do sleep .5; done'
|
@ -0,0 +1,33 @@
|
|||||||
|
From e92c85b68932845c908cb3f38b2130c57065e263 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Lennart Poettering <lennart@poettering.net>
|
||||||
|
Date: Fri, 6 Jan 2023 11:27:17 +0100
|
||||||
|
Subject: [PATCH] sd-event: don't mistake USEC_INFINITY passed in for overflow
|
||||||
|
|
||||||
|
Let's pass USEC_INFINITY from sd_event_source_set_time_relative() to
|
||||||
|
sd_event_source_set_time() instead of raising EOVERFLOW.
|
||||||
|
|
||||||
|
We should raise EOVERFLOW only if your addition fails, but not if the
|
||||||
|
input already is USEC_INFINITY, since it's an entirely valid operation
|
||||||
|
to have an infinite time-out, and we should support that.
|
||||||
|
|
||||||
|
(cherry picked from commit ef8591951aefccb668201f24aa481aa6cda834da)
|
||||||
|
|
||||||
|
Related: RHEL-6090
|
||||||
|
---
|
||||||
|
src/libsystemd/sd-event/sd-event.c | 3 +++
|
||||||
|
1 file changed, 3 insertions(+)
|
||||||
|
|
||||||
|
diff --git a/src/libsystemd/sd-event/sd-event.c b/src/libsystemd/sd-event/sd-event.c
|
||||||
|
index 778070a5fb..cd73cd8bfd 100644
|
||||||
|
--- a/src/libsystemd/sd-event/sd-event.c
|
||||||
|
+++ b/src/libsystemd/sd-event/sd-event.c
|
||||||
|
@@ -2723,6 +2723,9 @@ _public_ int sd_event_source_set_time_relative(sd_event_source *s, uint64_t usec
|
||||||
|
assert_return(s, -EINVAL);
|
||||||
|
assert_return(EVENT_SOURCE_IS_TIME(s->type), -EDOM);
|
||||||
|
|
||||||
|
+ if (usec == USEC_INFINITY)
|
||||||
|
+ return sd_event_source_set_time(s, USEC_INFINITY);
|
||||||
|
+
|
||||||
|
r = sd_event_now(s->event, event_source_type_to_clock(s->type), &t);
|
||||||
|
if (r < 0)
|
||||||
|
return r;
|
@ -0,0 +1,118 @@
|
|||||||
|
From 917b03f2b5ccdd668a49da7df72baaddd338c071 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Lennart Poettering <lennart@poettering.net>
|
||||||
|
Date: Mon, 2 Jan 2023 15:06:10 +0100
|
||||||
|
Subject: [PATCH] pid1: rework service_arm_timer() to optionally take a
|
||||||
|
relative time value
|
||||||
|
|
||||||
|
In most cases this is actually what we want, hence simplify this case.
|
||||||
|
|
||||||
|
(cherry picked from commit e5d6dcce7f852b978251d062afb2fcba16714eb9)
|
||||||
|
|
||||||
|
Related: RHEL-6090
|
||||||
|
---
|
||||||
|
src/core/service.c | 24 ++++++++++++------------
|
||||||
|
1 file changed, 12 insertions(+), 12 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/src/core/service.c b/src/core/service.c
|
||||||
|
index 1e14cdc6ca..aa76b4ad9a 100644
|
||||||
|
--- a/src/core/service.c
|
||||||
|
+++ b/src/core/service.c
|
||||||
|
@@ -530,13 +530,13 @@ static usec_t service_running_timeout(Service *s) {
|
||||||
|
delta);
|
||||||
|
}
|
||||||
|
|
||||||
|
-static int service_arm_timer(Service *s, usec_t usec) {
|
||||||
|
+static int service_arm_timer(Service *s, bool relative, usec_t usec) {
|
||||||
|
int r;
|
||||||
|
|
||||||
|
assert(s);
|
||||||
|
|
||||||
|
if (s->timer_event_source) {
|
||||||
|
- r = sd_event_source_set_time(s->timer_event_source, usec);
|
||||||
|
+ r = (relative ? sd_event_source_set_time_relative : sd_event_source_set_time)(s->timer_event_source, usec);
|
||||||
|
if (r < 0)
|
||||||
|
return r;
|
||||||
|
|
||||||
|
@@ -546,7 +546,7 @@ static int service_arm_timer(Service *s, usec_t usec) {
|
||||||
|
if (usec == USEC_INFINITY)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
- r = sd_event_add_time(
|
||||||
|
+ r = (relative ? sd_event_add_time_relative : sd_event_add_time)(
|
||||||
|
UNIT(s)->manager->event,
|
||||||
|
&s->timer_event_source,
|
||||||
|
CLOCK_MONOTONIC,
|
||||||
|
@@ -1195,7 +1195,7 @@ static int service_coldplug(Unit *u) {
|
||||||
|
if (s->deserialized_state == s->state)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
- r = service_arm_timer(s, service_coldplug_timeout(s));
|
||||||
|
+ r = service_arm_timer(s, /* relative= */ false, service_coldplug_timeout(s));
|
||||||
|
if (r < 0)
|
||||||
|
return r;
|
||||||
|
|
||||||
|
@@ -1538,7 +1538,7 @@ static int service_spawn_internal(
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
- r = service_arm_timer(s, usec_add(now(CLOCK_MONOTONIC), timeout));
|
||||||
|
+ r = service_arm_timer(s, /* relative= */ true, timeout);
|
||||||
|
if (r < 0)
|
||||||
|
return r;
|
||||||
|
|
||||||
|
@@ -1857,7 +1857,7 @@ static void service_enter_dead(Service *s, ServiceResult f, bool allow_restart)
|
||||||
|
if (s->will_auto_restart) {
|
||||||
|
s->will_auto_restart = false;
|
||||||
|
|
||||||
|
- r = service_arm_timer(s, usec_add(now(CLOCK_MONOTONIC), s->restart_usec));
|
||||||
|
+ r = service_arm_timer(s, /* relative= */ true, s->restart_usec);
|
||||||
|
if (r < 0) {
|
||||||
|
s->n_keep_fd_store--;
|
||||||
|
goto fail;
|
||||||
|
@@ -1989,8 +1989,8 @@ static void service_enter_signal(Service *s, ServiceState state, ServiceResult f
|
||||||
|
goto fail;
|
||||||
|
|
||||||
|
if (r > 0) {
|
||||||
|
- r = service_arm_timer(s, usec_add(now(CLOCK_MONOTONIC),
|
||||||
|
- kill_operation == KILL_WATCHDOG ? service_timeout_abort_usec(s) : s->timeout_stop_usec));
|
||||||
|
+ r = service_arm_timer(s, /* relative= */ true,
|
||||||
|
+ kill_operation == KILL_WATCHDOG ? service_timeout_abort_usec(s) : s->timeout_stop_usec);
|
||||||
|
if (r < 0)
|
||||||
|
goto fail;
|
||||||
|
|
||||||
|
@@ -2020,7 +2020,7 @@ static void service_enter_stop_by_notify(Service *s) {
|
||||||
|
|
||||||
|
(void) unit_enqueue_rewatch_pids(UNIT(s));
|
||||||
|
|
||||||
|
- service_arm_timer(s, usec_add(now(CLOCK_MONOTONIC), s->timeout_stop_usec));
|
||||||
|
+ service_arm_timer(s, /* relative= */ true, s->timeout_stop_usec);
|
||||||
|
|
||||||
|
/* The service told us it's stopping, so it's as if we SIGTERM'd it. */
|
||||||
|
service_set_state(s, SERVICE_STOP_SIGTERM);
|
||||||
|
@@ -2099,7 +2099,7 @@ static void service_enter_running(Service *s, ServiceResult f) {
|
||||||
|
service_enter_stop_by_notify(s);
|
||||||
|
else {
|
||||||
|
service_set_state(s, SERVICE_RUNNING);
|
||||||
|
- service_arm_timer(s, service_running_timeout(s));
|
||||||
|
+ service_arm_timer(s, /* relative= */ false, service_running_timeout(s));
|
||||||
|
}
|
||||||
|
|
||||||
|
} else if (s->remain_after_exit)
|
||||||
|
@@ -2398,7 +2398,7 @@ static void service_enter_reload_by_notify(Service *s) {
|
||||||
|
|
||||||
|
assert(s);
|
||||||
|
|
||||||
|
- service_arm_timer(s, usec_add(now(CLOCK_MONOTONIC), s->timeout_start_usec));
|
||||||
|
+ service_arm_timer(s, /* relative= */ true, s->timeout_start_usec);
|
||||||
|
service_set_state(s, SERVICE_RELOAD);
|
||||||
|
|
||||||
|
/* service_enter_reload_by_notify is never called during a reload, thus no loops are possible. */
|
||||||
|
@@ -4570,7 +4570,7 @@ static int service_clean(Unit *u, ExecCleanMask mask) {
|
||||||
|
s->control_command = NULL;
|
||||||
|
s->control_command_id = _SERVICE_EXEC_COMMAND_INVALID;
|
||||||
|
|
||||||
|
- r = service_arm_timer(s, usec_add(now(CLOCK_MONOTONIC), s->exec_context.timeout_clean_usec));
|
||||||
|
+ r = service_arm_timer(s, /* relative= */ true, s->exec_context.timeout_clean_usec);
|
||||||
|
if (r < 0)
|
||||||
|
goto fail;
|
||||||
|
|
@ -0,0 +1,25 @@
|
|||||||
|
From efe1737efae0950b7ded32d9c5e1a9cfaea7296b Mon Sep 17 00:00:00 2001
|
||||||
|
From: Lennart Poettering <lennart@poettering.net>
|
||||||
|
Date: Mon, 2 Jan 2023 15:00:05 +0100
|
||||||
|
Subject: [PATCH] manager: add one more assert()
|
||||||
|
|
||||||
|
(cherry picked from commit 7fa49280bc33ba5135228401fb24dce0de5f9195)
|
||||||
|
|
||||||
|
Related: RHEL-6090
|
||||||
|
---
|
||||||
|
src/core/manager.c | 2 ++
|
||||||
|
1 file changed, 2 insertions(+)
|
||||||
|
|
||||||
|
diff --git a/src/core/manager.c b/src/core/manager.c
|
||||||
|
index 657263eb73..6371810ce3 100644
|
||||||
|
--- a/src/core/manager.c
|
||||||
|
+++ b/src/core/manager.c
|
||||||
|
@@ -806,6 +806,8 @@ static int manager_find_credentials_dirs(Manager *m) {
|
||||||
|
}
|
||||||
|
|
||||||
|
void manager_set_switching_root(Manager *m, bool switching_root) {
|
||||||
|
+ assert(m);
|
||||||
|
+
|
||||||
|
m->switching_root = MANAGER_IS_SYSTEM(m) && switching_root;
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,688 @@
|
|||||||
|
From f64d331351e33199c4096b2ae4a4b9d24d127661 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Lennart Poettering <lennart@poettering.net>
|
||||||
|
Date: Mon, 2 Jan 2023 16:49:23 +0100
|
||||||
|
Subject: [PATCH] pid1: add new Type=notify-reload service type
|
||||||
|
|
||||||
|
Fixes: #6162
|
||||||
|
(cherry picked from commit 3bd28bf721dc70722ff1c675026ed0b44ad968a3)
|
||||||
|
|
||||||
|
Resolves: RHEL-6090
|
||||||
|
---
|
||||||
|
man/org.freedesktop.systemd1.xml | 6 +
|
||||||
|
src/basic/unit-def.c | 2 +
|
||||||
|
src/basic/unit-def.h | 4 +-
|
||||||
|
src/core/dbus-service.c | 5 +
|
||||||
|
src/core/load-fragment-gperf.gperf.in | 1 +
|
||||||
|
src/core/service.c | 226 ++++++++++++++++++--------
|
||||||
|
src/core/service.h | 18 +-
|
||||||
|
src/shared/bus-unit-util.c | 3 +-
|
||||||
|
8 files changed, 189 insertions(+), 76 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/man/org.freedesktop.systemd1.xml b/man/org.freedesktop.systemd1.xml
|
||||||
|
index 13a84af747..c18428a092 100644
|
||||||
|
--- a/man/org.freedesktop.systemd1.xml
|
||||||
|
+++ b/man/org.freedesktop.systemd1.xml
|
||||||
|
@@ -2570,6 +2570,8 @@ node /org/freedesktop/systemd1/unit/avahi_2ddaemon_2eservice {
|
||||||
|
readonly u NRestarts = ...;
|
||||||
|
@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
|
||||||
|
readonly s OOMPolicy = '...';
|
||||||
|
+ @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
|
||||||
|
+ readonly i ReloadSignal = ...;
|
||||||
|
readonly t ExecMainStartTimestamp = ...;
|
||||||
|
readonly t ExecMainStartTimestampMonotonic = ...;
|
||||||
|
readonly t ExecMainExitTimestamp = ...;
|
||||||
|
@@ -3163,6 +3165,8 @@ node /org/freedesktop/systemd1/unit/avahi_2ddaemon_2eservice {
|
||||||
|
|
||||||
|
<!--property OOMPolicy is not documented!-->
|
||||||
|
|
||||||
|
+ <!--property ReloadSignal is not documented!-->
|
||||||
|
+
|
||||||
|
<!--property ExecCondition is not documented!-->
|
||||||
|
|
||||||
|
<!--property ExecConditionEx is not documented!-->
|
||||||
|
@@ -3715,6 +3719,8 @@ node /org/freedesktop/systemd1/unit/avahi_2ddaemon_2eservice {
|
||||||
|
|
||||||
|
<variablelist class="dbus-property" generated="True" extra-ref="OOMPolicy"/>
|
||||||
|
|
||||||
|
+ <variablelist class="dbus-property" generated="True" extra-ref="ReloadSignal"/>
|
||||||
|
+
|
||||||
|
<variablelist class="dbus-property" generated="True" extra-ref="ExecMainStartTimestamp"/>
|
||||||
|
|
||||||
|
<variablelist class="dbus-property" generated="True" extra-ref="ExecMainStartTimestampMonotonic"/>
|
||||||
|
diff --git a/src/basic/unit-def.c b/src/basic/unit-def.c
|
||||||
|
index 94cd603e32..bdb1860246 100644
|
||||||
|
--- a/src/basic/unit-def.c
|
||||||
|
+++ b/src/basic/unit-def.c
|
||||||
|
@@ -188,6 +188,8 @@ static const char* const service_state_table[_SERVICE_STATE_MAX] = {
|
||||||
|
[SERVICE_RUNNING] = "running",
|
||||||
|
[SERVICE_EXITED] = "exited",
|
||||||
|
[SERVICE_RELOAD] = "reload",
|
||||||
|
+ [SERVICE_RELOAD_SIGNAL] = "reload-signal",
|
||||||
|
+ [SERVICE_RELOAD_NOTIFY] = "reload-notify",
|
||||||
|
[SERVICE_STOP] = "stop",
|
||||||
|
[SERVICE_STOP_WATCHDOG] = "stop-watchdog",
|
||||||
|
[SERVICE_STOP_SIGTERM] = "stop-sigterm",
|
||||||
|
diff --git a/src/basic/unit-def.h b/src/basic/unit-def.h
|
||||||
|
index 5fcd51c095..bae132ea09 100644
|
||||||
|
--- a/src/basic/unit-def.h
|
||||||
|
+++ b/src/basic/unit-def.h
|
||||||
|
@@ -132,7 +132,9 @@ typedef enum ServiceState {
|
||||||
|
SERVICE_START_POST,
|
||||||
|
SERVICE_RUNNING,
|
||||||
|
SERVICE_EXITED, /* Nothing is running anymore, but RemainAfterExit is true hence this is OK */
|
||||||
|
- SERVICE_RELOAD,
|
||||||
|
+ SERVICE_RELOAD, /* Reloading via ExecReload= */
|
||||||
|
+ SERVICE_RELOAD_SIGNAL, /* Reloading via SIGHUP requested */
|
||||||
|
+ SERVICE_RELOAD_NOTIFY, /* Waiting for READY=1 after RELOADING=1 notify */
|
||||||
|
SERVICE_STOP, /* No STOP_PRE state, instead just register multiple STOP executables */
|
||||||
|
SERVICE_STOP_WATCHDOG,
|
||||||
|
SERVICE_STOP_SIGTERM,
|
||||||
|
diff --git a/src/core/dbus-service.c b/src/core/dbus-service.c
|
||||||
|
index 6e4bc0bd1a..3d130db66a 100644
|
||||||
|
--- a/src/core/dbus-service.c
|
||||||
|
+++ b/src/core/dbus-service.c
|
||||||
|
@@ -228,6 +228,7 @@ const sd_bus_vtable bus_service_vtable[] = {
|
||||||
|
SD_BUS_PROPERTY("GID", "u", bus_property_get_gid, offsetof(Unit, ref_gid), SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
|
||||||
|
SD_BUS_PROPERTY("NRestarts", "u", bus_property_get_unsigned, offsetof(Service, n_restarts), SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
|
||||||
|
SD_BUS_PROPERTY("OOMPolicy", "s", bus_property_get_oom_policy, offsetof(Service, oom_policy), SD_BUS_VTABLE_PROPERTY_CONST),
|
||||||
|
+ SD_BUS_PROPERTY("ReloadSignal", "i", bus_property_get_int, offsetof(Service, reload_signal), SD_BUS_VTABLE_PROPERTY_CONST),
|
||||||
|
|
||||||
|
BUS_EXEC_STATUS_VTABLE("ExecMain", offsetof(Service, main_exec_status), SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
|
||||||
|
BUS_EXEC_COMMAND_LIST_VTABLE("ExecCondition", offsetof(Service, exec_command[SERVICE_EXEC_CONDITION]), SD_BUS_VTABLE_PROPERTY_EMITS_INVALIDATION),
|
||||||
|
@@ -374,6 +375,7 @@ static BUS_DEFINE_SET_TRANSIENT_PARSE(service_restart, ServiceRestart, service_r
|
||||||
|
static BUS_DEFINE_SET_TRANSIENT_PARSE(oom_policy, OOMPolicy, oom_policy_from_string);
|
||||||
|
static BUS_DEFINE_SET_TRANSIENT_STRING_WITH_CHECK(bus_name, sd_bus_service_name_is_valid);
|
||||||
|
static BUS_DEFINE_SET_TRANSIENT_PARSE(timeout_failure_mode, ServiceTimeoutFailureMode, service_timeout_failure_mode_from_string);
|
||||||
|
+static BUS_DEFINE_SET_TRANSIENT_TO_STRING(reload_signal, "i", int32_t, int, "%" PRIi32, signal_to_string_with_check);
|
||||||
|
|
||||||
|
static int bus_service_set_transient_property(
|
||||||
|
Service *s,
|
||||||
|
@@ -532,6 +534,9 @@ static int bus_service_set_transient_property(
|
||||||
|
if (streq(name, "StandardErrorFileDescriptor"))
|
||||||
|
return bus_set_transient_std_fd(u, name, &s->stderr_fd, &s->exec_context.stdio_as_fds, message, flags, error);
|
||||||
|
|
||||||
|
+ if (streq(name, "ReloadSignal"))
|
||||||
|
+ return bus_set_transient_reload_signal(u, name, &s->reload_signal, message, flags, error);
|
||||||
|
+
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
diff --git a/src/core/load-fragment-gperf.gperf.in b/src/core/load-fragment-gperf.gperf.in
|
||||||
|
index 81a5971339..53089d5590 100644
|
||||||
|
--- a/src/core/load-fragment-gperf.gperf.in
|
||||||
|
+++ b/src/core/load-fragment-gperf.gperf.in
|
||||||
|
@@ -424,6 +424,7 @@ Service.BusPolicy, config_parse_warn_compat,
|
||||||
|
Service.USBFunctionDescriptors, config_parse_unit_path_printf, 0, offsetof(Service, usb_function_descriptors)
|
||||||
|
Service.USBFunctionStrings, config_parse_unit_path_printf, 0, offsetof(Service, usb_function_strings)
|
||||||
|
Service.OOMPolicy, config_parse_oom_policy, 0, offsetof(Service, oom_policy)
|
||||||
|
+Service.ReloadSignal, config_parse_signal, 0, offsetof(Service, reload_signal)
|
||||||
|
{{ EXEC_CONTEXT_CONFIG_ITEMS('Service') }}
|
||||||
|
{{ CGROUP_CONTEXT_CONFIG_ITEMS('Service') }}
|
||||||
|
{{ KILL_CONTEXT_CONFIG_ITEMS('Service') }}
|
||||||
|
diff --git a/src/core/service.c b/src/core/service.c
|
||||||
|
index aa76b4ad9a..902948905f 100644
|
||||||
|
--- a/src/core/service.c
|
||||||
|
+++ b/src/core/service.c
|
||||||
|
@@ -54,6 +54,8 @@ static const UnitActiveState state_translation_table[_SERVICE_STATE_MAX] = {
|
||||||
|
[SERVICE_RUNNING] = UNIT_ACTIVE,
|
||||||
|
[SERVICE_EXITED] = UNIT_ACTIVE,
|
||||||
|
[SERVICE_RELOAD] = UNIT_RELOADING,
|
||||||
|
+ [SERVICE_RELOAD_SIGNAL] = UNIT_RELOADING,
|
||||||
|
+ [SERVICE_RELOAD_NOTIFY] = UNIT_RELOADING,
|
||||||
|
[SERVICE_STOP] = UNIT_DEACTIVATING,
|
||||||
|
[SERVICE_STOP_WATCHDOG] = UNIT_DEACTIVATING,
|
||||||
|
[SERVICE_STOP_SIGTERM] = UNIT_DEACTIVATING,
|
||||||
|
@@ -78,6 +80,8 @@ static const UnitActiveState state_translation_table_idle[_SERVICE_STATE_MAX] =
|
||||||
|
[SERVICE_RUNNING] = UNIT_ACTIVE,
|
||||||
|
[SERVICE_EXITED] = UNIT_ACTIVE,
|
||||||
|
[SERVICE_RELOAD] = UNIT_RELOADING,
|
||||||
|
+ [SERVICE_RELOAD_SIGNAL] = UNIT_RELOADING,
|
||||||
|
+ [SERVICE_RELOAD_NOTIFY] = UNIT_RELOADING,
|
||||||
|
[SERVICE_STOP] = UNIT_DEACTIVATING,
|
||||||
|
[SERVICE_STOP_WATCHDOG] = UNIT_DEACTIVATING,
|
||||||
|
[SERVICE_STOP_SIGTERM] = UNIT_DEACTIVATING,
|
||||||
|
@@ -124,6 +128,8 @@ static void service_init(Unit *u) {
|
||||||
|
s->watchdog_original_usec = USEC_INFINITY;
|
||||||
|
|
||||||
|
s->oom_policy = _OOM_POLICY_INVALID;
|
||||||
|
+ s->reload_begin_usec = USEC_INFINITY;
|
||||||
|
+ s->reload_signal = SIGHUP;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void service_unwatch_control_pid(Service *s) {
|
||||||
|
@@ -765,7 +771,7 @@ static int service_add_extras(Service *s) {
|
||||||
|
|
||||||
|
/* If the service needs the notify socket, let's enable it automatically. */
|
||||||
|
if (s->notify_access == NOTIFY_NONE &&
|
||||||
|
- (s->type == SERVICE_NOTIFY || s->watchdog_usec > 0 || s->n_fd_store_max > 0))
|
||||||
|
+ (IN_SET(s->type, SERVICE_NOTIFY, SERVICE_NOTIFY_RELOAD) || s->watchdog_usec > 0 || s->n_fd_store_max > 0))
|
||||||
|
s->notify_access = NOTIFY_MAIN;
|
||||||
|
|
||||||
|
/* If no OOM policy was explicitly set, then default to the configure default OOM policy. Except when
|
||||||
|
@@ -830,7 +836,8 @@ static void service_dump(Unit *u, FILE *f, const char *prefix) {
|
||||||
|
"%sRestart: %s\n"
|
||||||
|
"%sNotifyAccess: %s\n"
|
||||||
|
"%sNotifyState: %s\n"
|
||||||
|
- "%sOOMPolicy: %s\n",
|
||||||
|
+ "%sOOMPolicy: %s\n"
|
||||||
|
+ "%sReloadSignal: %s\n",
|
||||||
|
prefix, service_state_to_string(s->state),
|
||||||
|
prefix, service_result_to_string(s->result),
|
||||||
|
prefix, service_result_to_string(s->reload_result),
|
||||||
|
@@ -843,7 +850,8 @@ static void service_dump(Unit *u, FILE *f, const char *prefix) {
|
||||||
|
prefix, service_restart_to_string(s->restart),
|
||||||
|
prefix, notify_access_to_string(s->notify_access),
|
||||||
|
prefix, notify_state_to_string(s->notify_state),
|
||||||
|
- prefix, oom_policy_to_string(s->oom_policy));
|
||||||
|
+ prefix, oom_policy_to_string(s->oom_policy),
|
||||||
|
+ prefix, signal_to_string(s->reload_signal));
|
||||||
|
|
||||||
|
if (s->control_pid > 0)
|
||||||
|
fprintf(f,
|
||||||
|
@@ -1088,7 +1096,7 @@ static void service_set_state(Service *s, ServiceState state) {
|
||||||
|
if (!IN_SET(state,
|
||||||
|
SERVICE_CONDITION, SERVICE_START_PRE, SERVICE_START, SERVICE_START_POST,
|
||||||
|
SERVICE_RUNNING,
|
||||||
|
- SERVICE_RELOAD,
|
||||||
|
+ SERVICE_RELOAD, SERVICE_RELOAD_SIGNAL, SERVICE_RELOAD_NOTIFY,
|
||||||
|
SERVICE_STOP, SERVICE_STOP_WATCHDOG, SERVICE_STOP_SIGTERM, SERVICE_STOP_SIGKILL, SERVICE_STOP_POST,
|
||||||
|
SERVICE_FINAL_WATCHDOG, SERVICE_FINAL_SIGTERM, SERVICE_FINAL_SIGKILL,
|
||||||
|
SERVICE_AUTO_RESTART,
|
||||||
|
@@ -1097,7 +1105,8 @@ static void service_set_state(Service *s, ServiceState state) {
|
||||||
|
|
||||||
|
if (!IN_SET(state,
|
||||||
|
SERVICE_START, SERVICE_START_POST,
|
||||||
|
- SERVICE_RUNNING, SERVICE_RELOAD,
|
||||||
|
+ SERVICE_RUNNING,
|
||||||
|
+ SERVICE_RELOAD, SERVICE_RELOAD_SIGNAL, SERVICE_RELOAD_NOTIFY,
|
||||||
|
SERVICE_STOP, SERVICE_STOP_WATCHDOG, SERVICE_STOP_SIGTERM, SERVICE_STOP_SIGKILL, SERVICE_STOP_POST,
|
||||||
|
SERVICE_FINAL_WATCHDOG, SERVICE_FINAL_SIGTERM, SERVICE_FINAL_SIGKILL)) {
|
||||||
|
service_unwatch_main_pid(s);
|
||||||
|
@@ -1106,7 +1115,7 @@ static void service_set_state(Service *s, ServiceState state) {
|
||||||
|
|
||||||
|
if (!IN_SET(state,
|
||||||
|
SERVICE_CONDITION, SERVICE_START_PRE, SERVICE_START, SERVICE_START_POST,
|
||||||
|
- SERVICE_RELOAD,
|
||||||
|
+ SERVICE_RELOAD, SERVICE_RELOAD_SIGNAL, SERVICE_RELOAD_NOTIFY,
|
||||||
|
SERVICE_STOP, SERVICE_STOP_WATCHDOG, SERVICE_STOP_SIGTERM, SERVICE_STOP_SIGKILL, SERVICE_STOP_POST,
|
||||||
|
SERVICE_FINAL_WATCHDOG, SERVICE_FINAL_SIGTERM, SERVICE_FINAL_SIGKILL,
|
||||||
|
SERVICE_CLEANING)) {
|
||||||
|
@@ -1122,7 +1131,8 @@ static void service_set_state(Service *s, ServiceState state) {
|
||||||
|
|
||||||
|
if (!IN_SET(state,
|
||||||
|
SERVICE_CONDITION, SERVICE_START_PRE, SERVICE_START, SERVICE_START_POST,
|
||||||
|
- SERVICE_RUNNING, SERVICE_RELOAD,
|
||||||
|
+ SERVICE_RUNNING,
|
||||||
|
+ SERVICE_RELOAD, SERVICE_RELOAD_SIGNAL, SERVICE_RELOAD_NOTIFY,
|
||||||
|
SERVICE_STOP, SERVICE_STOP_WATCHDOG, SERVICE_STOP_SIGTERM, SERVICE_STOP_SIGKILL, SERVICE_STOP_POST,
|
||||||
|
SERVICE_FINAL_WATCHDOG, SERVICE_FINAL_SIGTERM, SERVICE_FINAL_SIGKILL) &&
|
||||||
|
!(state == SERVICE_DEAD && UNIT(s)->job))
|
||||||
|
@@ -1131,7 +1141,7 @@ static void service_set_state(Service *s, ServiceState state) {
|
||||||
|
if (state != SERVICE_START)
|
||||||
|
s->exec_fd_event_source = sd_event_source_disable_unref(s->exec_fd_event_source);
|
||||||
|
|
||||||
|
- if (!IN_SET(state, SERVICE_START_POST, SERVICE_RUNNING, SERVICE_RELOAD))
|
||||||
|
+ if (!IN_SET(state, SERVICE_START_POST, SERVICE_RUNNING, SERVICE_RELOAD, SERVICE_RELOAD_SIGNAL, SERVICE_RELOAD_NOTIFY))
|
||||||
|
service_stop_watchdog(s);
|
||||||
|
|
||||||
|
/* For the inactive states unit_notify() will trim the cgroup,
|
||||||
|
@@ -1157,6 +1167,8 @@ static usec_t service_coldplug_timeout(Service *s) {
|
||||||
|
case SERVICE_START:
|
||||||
|
case SERVICE_START_POST:
|
||||||
|
case SERVICE_RELOAD:
|
||||||
|
+ case SERVICE_RELOAD_SIGNAL:
|
||||||
|
+ case SERVICE_RELOAD_NOTIFY:
|
||||||
|
return usec_add(UNIT(s)->state_change_timestamp.monotonic, s->timeout_start_usec);
|
||||||
|
|
||||||
|
case SERVICE_RUNNING:
|
||||||
|
@@ -1203,7 +1215,8 @@ static int service_coldplug(Unit *u) {
|
||||||
|
pid_is_unwaited(s->main_pid) &&
|
||||||
|
(IN_SET(s->deserialized_state,
|
||||||
|
SERVICE_START, SERVICE_START_POST,
|
||||||
|
- SERVICE_RUNNING, SERVICE_RELOAD,
|
||||||
|
+ SERVICE_RUNNING,
|
||||||
|
+ SERVICE_RELOAD, SERVICE_RELOAD_SIGNAL, SERVICE_RELOAD_NOTIFY,
|
||||||
|
SERVICE_STOP, SERVICE_STOP_WATCHDOG, SERVICE_STOP_SIGTERM, SERVICE_STOP_SIGKILL, SERVICE_STOP_POST,
|
||||||
|
SERVICE_FINAL_WATCHDOG, SERVICE_FINAL_SIGTERM, SERVICE_FINAL_SIGKILL))) {
|
||||||
|
r = unit_watch_pid(UNIT(s), s->main_pid, false);
|
||||||
|
@@ -1215,7 +1228,7 @@ static int service_coldplug(Unit *u) {
|
||||||
|
pid_is_unwaited(s->control_pid) &&
|
||||||
|
IN_SET(s->deserialized_state,
|
||||||
|
SERVICE_CONDITION, SERVICE_START_PRE, SERVICE_START, SERVICE_START_POST,
|
||||||
|
- SERVICE_RELOAD,
|
||||||
|
+ SERVICE_RELOAD, SERVICE_RELOAD_SIGNAL, SERVICE_RELOAD_NOTIFY,
|
||||||
|
SERVICE_STOP, SERVICE_STOP_WATCHDOG, SERVICE_STOP_SIGTERM, SERVICE_STOP_SIGKILL, SERVICE_STOP_POST,
|
||||||
|
SERVICE_FINAL_WATCHDOG, SERVICE_FINAL_SIGTERM, SERVICE_FINAL_SIGKILL,
|
||||||
|
SERVICE_CLEANING)) {
|
||||||
|
@@ -1230,7 +1243,7 @@ static int service_coldplug(Unit *u) {
|
||||||
|
(void) unit_setup_exec_runtime(u);
|
||||||
|
}
|
||||||
|
|
||||||
|
- if (IN_SET(s->deserialized_state, SERVICE_START_POST, SERVICE_RUNNING, SERVICE_RELOAD))
|
||||||
|
+ if (IN_SET(s->deserialized_state, SERVICE_START_POST, SERVICE_RUNNING, SERVICE_RELOAD, SERVICE_RELOAD_SIGNAL, SERVICE_RELOAD_NOTIFY))
|
||||||
|
service_start_watchdog(s);
|
||||||
|
|
||||||
|
if (UNIT_ISSET(s->accept_socket)) {
|
||||||
|
@@ -2255,7 +2268,7 @@ static void service_enter_start(Service *s) {
|
||||||
|
s->control_pid = pid;
|
||||||
|
service_set_state(s, SERVICE_START);
|
||||||
|
|
||||||
|
- } else if (IN_SET(s->type, SERVICE_ONESHOT, SERVICE_DBUS, SERVICE_NOTIFY, SERVICE_EXEC)) {
|
||||||
|
+ } else if (IN_SET(s->type, SERVICE_ONESHOT, SERVICE_DBUS, SERVICE_NOTIFY, SERVICE_NOTIFY_RELOAD, SERVICE_EXEC)) {
|
||||||
|
|
||||||
|
/* For oneshot services we wait until the start process exited, too, but it is our main process. */
|
||||||
|
|
||||||
|
@@ -2399,7 +2412,7 @@ static void service_enter_reload_by_notify(Service *s) {
|
||||||
|
assert(s);
|
||||||
|
|
||||||
|
service_arm_timer(s, /* relative= */ true, s->timeout_start_usec);
|
||||||
|
- service_set_state(s, SERVICE_RELOAD);
|
||||||
|
+ service_set_state(s, SERVICE_RELOAD_NOTIFY);
|
||||||
|
|
||||||
|
/* service_enter_reload_by_notify is never called during a reload, thus no loops are possible. */
|
||||||
|
r = manager_propagate_reload(UNIT(s)->manager, UNIT(s), JOB_FAIL, &error);
|
||||||
|
@@ -2408,6 +2421,7 @@ static void service_enter_reload_by_notify(Service *s) {
|
||||||
|
}
|
||||||
|
|
||||||
|
static void service_enter_reload(Service *s) {
|
||||||
|
+ bool killed = false;
|
||||||
|
int r;
|
||||||
|
|
||||||
|
assert(s);
|
||||||
|
@@ -2415,6 +2429,18 @@ static void service_enter_reload(Service *s) {
|
||||||
|
service_unwatch_control_pid(s);
|
||||||
|
s->reload_result = SERVICE_SUCCESS;
|
||||||
|
|
||||||
|
+ usec_t ts = now(CLOCK_MONOTONIC);
|
||||||
|
+
|
||||||
|
+ if (s->type == SERVICE_NOTIFY_RELOAD && s->main_pid > 0) {
|
||||||
|
+ r = kill_and_sigcont(s->main_pid, s->reload_signal);
|
||||||
|
+ if (r < 0) {
|
||||||
|
+ log_unit_warning_errno(UNIT(s), r, "Failed to send reload signal: %m");
|
||||||
|
+ goto fail;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ killed = true;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
s->control_command = s->exec_command[SERVICE_EXEC_RELOAD];
|
||||||
|
if (s->control_command) {
|
||||||
|
s->control_command_id = SERVICE_EXEC_RELOAD;
|
||||||
|
@@ -2424,17 +2450,28 @@ static void service_enter_reload(Service *s) {
|
||||||
|
s->timeout_start_usec,
|
||||||
|
EXEC_APPLY_SANDBOXING|EXEC_APPLY_CHROOT|EXEC_IS_CONTROL|EXEC_CONTROL_CGROUP,
|
||||||
|
&s->control_pid);
|
||||||
|
- if (r < 0)
|
||||||
|
+ if (r < 0) {
|
||||||
|
+ log_unit_warning_errno(UNIT(s), r, "Failed to run 'reload' task: %m");
|
||||||
|
goto fail;
|
||||||
|
+ }
|
||||||
|
|
||||||
|
service_set_state(s, SERVICE_RELOAD);
|
||||||
|
- } else
|
||||||
|
+ } else if (killed) {
|
||||||
|
+ service_arm_timer(s, /* relative= */ true, s->timeout_start_usec);
|
||||||
|
+ service_set_state(s, SERVICE_RELOAD_SIGNAL);
|
||||||
|
+ } else {
|
||||||
|
service_enter_running(s, SERVICE_SUCCESS);
|
||||||
|
+ return;
|
||||||
|
+ }
|
||||||
|
|
||||||
|
+ /* Store the timestamp when we started reloading: when reloading via SIGHUP we won't leave the reload
|
||||||
|
+ * state until we received both RELOADING=1 and READY=1 with MONOTONIC_USEC= set to a value above
|
||||||
|
+ * this. Thus we know for sure the reload cycle was executed *after* we requested it, and is not one
|
||||||
|
+ * that was already in progress before. */
|
||||||
|
+ s->reload_begin_usec = ts;
|
||||||
|
return;
|
||||||
|
|
||||||
|
fail:
|
||||||
|
- log_unit_warning_errno(UNIT(s), r, "Failed to run 'reload' task: %m");
|
||||||
|
s->reload_result = SERVICE_FAILURE_RESOURCES;
|
||||||
|
service_enter_running(s, SERVICE_SUCCESS);
|
||||||
|
}
|
||||||
|
@@ -2597,9 +2634,8 @@ static int service_stop(Unit *u) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
- /* If there's already something running we go directly into
|
||||||
|
- * kill mode. */
|
||||||
|
- if (IN_SET(s->state, SERVICE_CONDITION, SERVICE_START_PRE, SERVICE_START, SERVICE_START_POST, SERVICE_RELOAD, SERVICE_STOP_WATCHDOG)) {
|
||||||
|
+ /* If there's already something running we go directly into kill mode. */
|
||||||
|
+ if (IN_SET(s->state, SERVICE_CONDITION, SERVICE_START_PRE, SERVICE_START, SERVICE_START_POST, SERVICE_RELOAD, SERVICE_RELOAD_SIGNAL, SERVICE_RELOAD_NOTIFY, SERVICE_STOP_WATCHDOG)) {
|
||||||
|
service_enter_signal(s, SERVICE_STOP_SIGTERM, SERVICE_SUCCESS);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
@@ -2632,7 +2668,8 @@ _pure_ static bool service_can_reload(Unit *u) {
|
||||||
|
|
||||||
|
assert(s);
|
||||||
|
|
||||||
|
- return !!s->exec_command[SERVICE_EXEC_RELOAD];
|
||||||
|
+ return s->exec_command[SERVICE_EXEC_RELOAD] ||
|
||||||
|
+ s->type == SERVICE_NOTIFY_RELOAD;
|
||||||
|
}
|
||||||
|
|
||||||
|
static unsigned service_exec_command_index(Unit *u, ServiceExecCommand id, ExecCommand *current) {
|
||||||
|
@@ -2808,6 +2845,9 @@ static int service_serialize(Unit *u, FILE *f, FDSet *fds) {
|
||||||
|
if (s->watchdog_original_usec != USEC_INFINITY)
|
||||||
|
(void) serialize_item_format(f, "watchdog-original-usec", USEC_FMT, s->watchdog_original_usec);
|
||||||
|
|
||||||
|
+ if (s->reload_begin_usec != USEC_INFINITY)
|
||||||
|
+ (void) serialize_item_format(f, "reload-begin-usec", USEC_FMT, s->reload_begin_usec);
|
||||||
|
+
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -3146,6 +3186,10 @@ static int service_deserialize_item(Unit *u, const char *key, const char *value,
|
||||||
|
log_unit_debug_errno(u, r, "Failed to parse serialized flush restart counter setting '%s': %m", value);
|
||||||
|
else
|
||||||
|
s->flush_n_restarts = r;
|
||||||
|
+ } else if (streq(key, "reload-begin-usec")) {
|
||||||
|
+ r = deserialize_usec(value, &s->reload_begin_usec);
|
||||||
|
+ if (r < 0)
|
||||||
|
+ log_unit_debug_errno(u, r, "Failed to parse serialized reload begin timestamp '%s', ignoring: %m", value);
|
||||||
|
} else
|
||||||
|
log_unit_debug(u, "Unknown serialization key: %s", key);
|
||||||
|
|
||||||
|
@@ -3349,7 +3393,7 @@ static void service_notify_cgroup_empty_event(Unit *u) {
|
||||||
|
* SIGCHLD for. */
|
||||||
|
|
||||||
|
case SERVICE_START:
|
||||||
|
- if (s->type == SERVICE_NOTIFY &&
|
||||||
|
+ if (IN_SET(s->type, SERVICE_NOTIFY, SERVICE_NOTIFY_RELOAD) &&
|
||||||
|
main_pid_good(s) == 0 &&
|
||||||
|
control_pid_good(s) == 0) {
|
||||||
|
/* No chance of getting a ready notification anymore */
|
||||||
|
@@ -3553,17 +3597,19 @@ static void service_sigchld_event(Unit *u, pid_t pid, int code, int status) {
|
||||||
|
} else {
|
||||||
|
s->main_command = NULL;
|
||||||
|
|
||||||
|
- /* Services with ExitType=cgroup do not act on main PID exiting,
|
||||||
|
- * unless the cgroup is already empty */
|
||||||
|
+ /* Services with ExitType=cgroup do not act on main PID exiting, unless the cgroup is
|
||||||
|
+ * already empty */
|
||||||
|
if (s->exit_type == SERVICE_EXIT_MAIN || cgroup_good(s) <= 0) {
|
||||||
|
/* The service exited, so the service is officially gone. */
|
||||||
|
switch (s->state) {
|
||||||
|
|
||||||
|
case SERVICE_START_POST:
|
||||||
|
case SERVICE_RELOAD:
|
||||||
|
- /* If neither main nor control processes are running then
|
||||||
|
- * the current state can never exit cleanly, hence immediately
|
||||||
|
- * terminate the service. */
|
||||||
|
+ case SERVICE_RELOAD_SIGNAL:
|
||||||
|
+ case SERVICE_RELOAD_NOTIFY:
|
||||||
|
+ /* If neither main nor control processes are running then the current
|
||||||
|
+ * state can never exit cleanly, hence immediately terminate the
|
||||||
|
+ * service. */
|
||||||
|
if (control_pid_good(s) <= 0)
|
||||||
|
service_enter_stop(s, f);
|
||||||
|
|
||||||
|
@@ -3582,7 +3628,7 @@ static void service_sigchld_event(Unit *u, pid_t pid, int code, int status) {
|
||||||
|
else
|
||||||
|
service_enter_signal(s, SERVICE_STOP_SIGTERM, f);
|
||||||
|
break;
|
||||||
|
- } else if (s->type == SERVICE_NOTIFY) {
|
||||||
|
+ } else if (IN_SET(s->type, SERVICE_NOTIFY, SERVICE_NOTIFY_RELOAD)) {
|
||||||
|
/* Only enter running through a notification, so that the
|
||||||
|
* SERVICE_START state signifies that no ready notification
|
||||||
|
* has been received */
|
||||||
|
@@ -3675,15 +3721,13 @@ static void service_sigchld_event(Unit *u, pid_t pid, int code, int status) {
|
||||||
|
s->control_command->command_next &&
|
||||||
|
f == SERVICE_SUCCESS) {
|
||||||
|
|
||||||
|
- /* There is another command to *
|
||||||
|
- * execute, so let's do that. */
|
||||||
|
+ /* There is another command to * execute, so let's do that. */
|
||||||
|
|
||||||
|
log_unit_debug(u, "Running next control command for state %s.", service_state_to_string(s->state));
|
||||||
|
service_run_next_control(s);
|
||||||
|
|
||||||
|
} else {
|
||||||
|
- /* No further commands for this step, so let's
|
||||||
|
- * figure out what to do next */
|
||||||
|
+ /* No further commands for this step, so let's figure out what to do next */
|
||||||
|
|
||||||
|
s->control_command = NULL;
|
||||||
|
s->control_command_id = _SERVICE_EXEC_COMMAND_INVALID;
|
||||||
|
@@ -3761,12 +3805,22 @@ static void service_sigchld_event(Unit *u, pid_t pid, int code, int status) {
|
||||||
|
break;
|
||||||
|
|
||||||
|
case SERVICE_RELOAD:
|
||||||
|
+ case SERVICE_RELOAD_SIGNAL:
|
||||||
|
+ case SERVICE_RELOAD_NOTIFY:
|
||||||
|
if (f == SERVICE_SUCCESS)
|
||||||
|
if (service_load_pid_file(s, true) < 0)
|
||||||
|
service_search_main_pid(s);
|
||||||
|
|
||||||
|
s->reload_result = f;
|
||||||
|
- service_enter_running(s, SERVICE_SUCCESS);
|
||||||
|
+
|
||||||
|
+ /* If the last notification we received from the service process indiciates
|
||||||
|
+ * we are still reloading, then don't leave reloading state just yet, just
|
||||||
|
+ * transition into SERVICE_RELOAD_NOTIFY, to wait for the READY=1 coming,
|
||||||
|
+ * too. */
|
||||||
|
+ if (s->notify_state == NOTIFY_RELOADING)
|
||||||
|
+ service_set_state(s, SERVICE_RELOAD_NOTIFY);
|
||||||
|
+ else
|
||||||
|
+ service_enter_running(s, SERVICE_SUCCESS);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case SERVICE_STOP:
|
||||||
|
@@ -3869,6 +3923,8 @@ static int service_dispatch_timer(sd_event_source *source, usec_t usec, void *us
|
||||||
|
break;
|
||||||
|
|
||||||
|
case SERVICE_RELOAD:
|
||||||
|
+ case SERVICE_RELOAD_SIGNAL:
|
||||||
|
+ case SERVICE_RELOAD_NOTIFY:
|
||||||
|
log_unit_warning(UNIT(s), "Reload operation timed out. Killing reload process.");
|
||||||
|
service_kill_control_process(s);
|
||||||
|
s->reload_result = SERVICE_FAILURE_TIMEOUT;
|
||||||
|
@@ -4094,6 +4150,7 @@ static void service_notify_message(
|
||||||
|
|
||||||
|
Service *s = SERVICE(u);
|
||||||
|
bool notify_dbus = false;
|
||||||
|
+ usec_t monotonic_usec = USEC_INFINITY;
|
||||||
|
const char *e;
|
||||||
|
int r;
|
||||||
|
|
||||||
|
@@ -4112,7 +4169,7 @@ static void service_notify_message(
|
||||||
|
|
||||||
|
/* Interpret MAINPID= */
|
||||||
|
e = strv_find_startswith(tags, "MAINPID=");
|
||||||
|
- if (e && IN_SET(s->state, SERVICE_START, SERVICE_START_POST, SERVICE_RUNNING, SERVICE_RELOAD)) {
|
||||||
|
+ if (e && IN_SET(s->state, SERVICE_START, SERVICE_START_POST, SERVICE_RUNNING, SERVICE_RELOAD, SERVICE_RELOAD_SIGNAL, SERVICE_RELOAD_NOTIFY)) {
|
||||||
|
pid_t new_main_pid;
|
||||||
|
|
||||||
|
if (parse_pid(e, &new_main_pid) < 0)
|
||||||
|
@@ -4141,43 +4198,73 @@ static void service_notify_message(
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
- /* Interpret READY=/STOPPING=/RELOADING=. Last one wins. */
|
||||||
|
- STRV_FOREACH_BACKWARDS(i, tags) {
|
||||||
|
+ /* Parse MONOTONIC_USEC= */
|
||||||
|
+ e = strv_find_startswith(tags, "MONOTONIC_USEC=");
|
||||||
|
+ if (e) {
|
||||||
|
+ r = safe_atou64(e, &monotonic_usec);
|
||||||
|
+ if (r < 0)
|
||||||
|
+ log_unit_warning_errno(u, r, "Failed to parse MONOTONIC_USEC= field in notification message, ignoring: %s", e);
|
||||||
|
+ }
|
||||||
|
|
||||||
|
- if (streq(*i, "READY=1")) {
|
||||||
|
- s->notify_state = NOTIFY_READY;
|
||||||
|
+ /* Interpret READY=/STOPPING=/RELOADING=. STOPPING= wins over the others, and READY= over RELOADING= */
|
||||||
|
+ if (strv_contains(tags, "STOPPING=1")) {
|
||||||
|
+ s->notify_state = NOTIFY_STOPPING;
|
||||||
|
|
||||||
|
- /* Type=notify services inform us about completed
|
||||||
|
- * initialization with READY=1 */
|
||||||
|
- if (s->type == SERVICE_NOTIFY && s->state == SERVICE_START)
|
||||||
|
- service_enter_start_post(s);
|
||||||
|
+ if (IN_SET(s->state, SERVICE_RUNNING, SERVICE_RELOAD_SIGNAL, SERVICE_RELOAD_NOTIFY))
|
||||||
|
+ service_enter_stop_by_notify(s);
|
||||||
|
|
||||||
|
- /* Sending READY=1 while we are reloading informs us
|
||||||
|
- * that the reloading is complete */
|
||||||
|
- if (s->state == SERVICE_RELOAD && s->control_pid == 0)
|
||||||
|
- service_enter_running(s, SERVICE_SUCCESS);
|
||||||
|
+ notify_dbus = true;
|
||||||
|
|
||||||
|
- notify_dbus = true;
|
||||||
|
- break;
|
||||||
|
+ } else if (strv_contains(tags, "READY=1")) {
|
||||||
|
|
||||||
|
- } else if (streq(*i, "RELOADING=1")) {
|
||||||
|
- s->notify_state = NOTIFY_RELOADING;
|
||||||
|
+ s->notify_state = NOTIFY_READY;
|
||||||
|
|
||||||
|
- if (s->state == SERVICE_RUNNING)
|
||||||
|
- service_enter_reload_by_notify(s);
|
||||||
|
+ /* Type=notify services inform us about completed initialization with READY=1 */
|
||||||
|
+ if (IN_SET(s->type, SERVICE_NOTIFY, SERVICE_NOTIFY_RELOAD) &&
|
||||||
|
+ s->state == SERVICE_START)
|
||||||
|
+ service_enter_start_post(s);
|
||||||
|
|
||||||
|
- notify_dbus = true;
|
||||||
|
- break;
|
||||||
|
+ /* Sending READY=1 while we are reloading informs us that the reloading is complete. */
|
||||||
|
+ if (s->state == SERVICE_RELOAD_NOTIFY)
|
||||||
|
+ service_enter_running(s, SERVICE_SUCCESS);
|
||||||
|
|
||||||
|
- } else if (streq(*i, "STOPPING=1")) {
|
||||||
|
- s->notify_state = NOTIFY_STOPPING;
|
||||||
|
+ /* Combined RELOADING=1 and READY=1? Then this is indication that the service started and
|
||||||
|
+ * immediately finished reloading. */
|
||||||
|
+ if (s->state == SERVICE_RELOAD_SIGNAL &&
|
||||||
|
+ strv_contains(tags, "RELOADING=1") &&
|
||||||
|
+ monotonic_usec != USEC_INFINITY &&
|
||||||
|
+ monotonic_usec >= s->reload_begin_usec) {
|
||||||
|
+ _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
|
||||||
|
|
||||||
|
- if (s->state == SERVICE_RUNNING)
|
||||||
|
- service_enter_stop_by_notify(s);
|
||||||
|
+ /* Propagate a reload explicitly */
|
||||||
|
+ r = manager_propagate_reload(UNIT(s)->manager, UNIT(s), JOB_FAIL, &error);
|
||||||
|
+ if (r < 0)
|
||||||
|
+ log_unit_warning(UNIT(s), "Failed to schedule propagation of reload, ignoring: %s", bus_error_message(&error, r));
|
||||||
|
|
||||||
|
- notify_dbus = true;
|
||||||
|
- break;
|
||||||
|
+ service_enter_running(s, SERVICE_SUCCESS);
|
||||||
|
}
|
||||||
|
+
|
||||||
|
+ notify_dbus = true;
|
||||||
|
+
|
||||||
|
+ } else if (strv_contains(tags, "RELOADING=1")) {
|
||||||
|
+
|
||||||
|
+ s->notify_state = NOTIFY_RELOADING;
|
||||||
|
+
|
||||||
|
+ /* Sending RELOADING=1 after we send SIGHUP to request a reload will transition
|
||||||
|
+ * things to "reload-notify" state, where we'll wait for READY=1 to let us know the
|
||||||
|
+ * reload is done. Note that we insist on a timestamp being sent along here, so that
|
||||||
|
+ * we know for sure this is a reload cycle initiated *after* we sent the signal */
|
||||||
|
+ if (s->state == SERVICE_RELOAD_SIGNAL &&
|
||||||
|
+ monotonic_usec != USEC_INFINITY &&
|
||||||
|
+ monotonic_usec >= s->reload_begin_usec)
|
||||||
|
+ /* Note, we don't call service_enter_reload_by_notify() here, because we
|
||||||
|
+ * don't need reload propagation nor do we want to restart the time-out. */
|
||||||
|
+ service_set_state(s, SERVICE_RELOAD_NOTIFY);
|
||||||
|
+
|
||||||
|
+ if (s->state == SERVICE_RUNNING)
|
||||||
|
+ service_enter_reload_by_notify(s);
|
||||||
|
+
|
||||||
|
+ notify_dbus = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Interpret STATUS= */
|
||||||
|
@@ -4307,7 +4394,9 @@ static bool pick_up_pid_from_bus_name(Service *s) {
|
||||||
|
SERVICE_START,
|
||||||
|
SERVICE_START_POST,
|
||||||
|
SERVICE_RUNNING,
|
||||||
|
- SERVICE_RELOAD);
|
||||||
|
+ SERVICE_RELOAD,
|
||||||
|
+ SERVICE_RELOAD_SIGNAL,
|
||||||
|
+ SERVICE_RELOAD_NOTIFY);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int bus_name_pid_lookup_callback(sd_bus_message *reply, void *userdata, sd_bus_error *ret_error) {
|
||||||
|
@@ -4514,6 +4603,8 @@ static bool service_needs_console(Unit *u) {
|
||||||
|
SERVICE_START_POST,
|
||||||
|
SERVICE_RUNNING,
|
||||||
|
SERVICE_RELOAD,
|
||||||
|
+ SERVICE_RELOAD_SIGNAL,
|
||||||
|
+ SERVICE_RELOAD_NOTIFY,
|
||||||
|
SERVICE_STOP,
|
||||||
|
SERVICE_STOP_WATCHDOG,
|
||||||
|
SERVICE_STOP_SIGTERM,
|
||||||
|
@@ -4636,13 +4727,14 @@ static const char* const service_restart_table[_SERVICE_RESTART_MAX] = {
|
||||||
|
DEFINE_STRING_TABLE_LOOKUP(service_restart, ServiceRestart);
|
||||||
|
|
||||||
|
static const char* const service_type_table[_SERVICE_TYPE_MAX] = {
|
||||||
|
- [SERVICE_SIMPLE] = "simple",
|
||||||
|
- [SERVICE_FORKING] = "forking",
|
||||||
|
- [SERVICE_ONESHOT] = "oneshot",
|
||||||
|
- [SERVICE_DBUS] = "dbus",
|
||||||
|
- [SERVICE_NOTIFY] = "notify",
|
||||||
|
- [SERVICE_IDLE] = "idle",
|
||||||
|
- [SERVICE_EXEC] = "exec",
|
||||||
|
+ [SERVICE_SIMPLE] = "simple",
|
||||||
|
+ [SERVICE_FORKING] = "forking",
|
||||||
|
+ [SERVICE_ONESHOT] = "oneshot",
|
||||||
|
+ [SERVICE_DBUS] = "dbus",
|
||||||
|
+ [SERVICE_NOTIFY] = "notify",
|
||||||
|
+ [SERVICE_NOTIFY_RELOAD] = "notify-reload",
|
||||||
|
+ [SERVICE_IDLE] = "idle",
|
||||||
|
+ [SERVICE_EXEC] = "exec",
|
||||||
|
};
|
||||||
|
|
||||||
|
DEFINE_STRING_TABLE_LOOKUP(service_type, ServiceType);
|
||||||
|
diff --git a/src/core/service.h b/src/core/service.h
|
||||||
|
index 91e02e6d7e..194067f0e1 100644
|
||||||
|
--- a/src/core/service.h
|
||||||
|
+++ b/src/core/service.h
|
||||||
|
@@ -24,13 +24,14 @@ typedef enum ServiceRestart {
|
||||||
|
} ServiceRestart;
|
||||||
|
|
||||||
|
typedef enum ServiceType {
|
||||||
|
- SERVICE_SIMPLE, /* we fork and go on right-away (i.e. modern socket activated daemons) */
|
||||||
|
- SERVICE_FORKING, /* forks by itself (i.e. traditional daemons) */
|
||||||
|
- SERVICE_ONESHOT, /* we fork and wait until the program finishes (i.e. programs like fsck which run and need to finish before we continue) */
|
||||||
|
- SERVICE_DBUS, /* we fork and wait until a specific D-Bus name appears on the bus */
|
||||||
|
- SERVICE_NOTIFY, /* we fork and wait until a daemon sends us a ready message with sd_notify() */
|
||||||
|
- SERVICE_IDLE, /* much like simple, but delay exec() until all jobs are dispatched. */
|
||||||
|
- SERVICE_EXEC, /* we fork and wait until we execute exec() (this means our own setup is waited for) */
|
||||||
|
+ SERVICE_SIMPLE, /* we fork and go on right-away (i.e. modern socket activated daemons) */
|
||||||
|
+ SERVICE_FORKING, /* forks by itself (i.e. traditional daemons) */
|
||||||
|
+ SERVICE_ONESHOT, /* we fork and wait until the program finishes (i.e. programs like fsck which run and need to finish before we continue) */
|
||||||
|
+ SERVICE_DBUS, /* we fork and wait until a specific D-Bus name appears on the bus */
|
||||||
|
+ SERVICE_NOTIFY, /* we fork and wait until a daemon sends us a ready message with sd_notify() */
|
||||||
|
+ SERVICE_NOTIFY_RELOAD, /* just like SERVICE_NOTIFY, but also implements a reload protocol via SIGHUP */
|
||||||
|
+ SERVICE_IDLE, /* much like simple, but delay exec() until all jobs are dispatched. */
|
||||||
|
+ SERVICE_EXEC, /* we fork and wait until we execute exec() (this means our own setup is waited for) */
|
||||||
|
_SERVICE_TYPE_MAX,
|
||||||
|
_SERVICE_TYPE_INVALID = -EINVAL,
|
||||||
|
} ServiceType;
|
||||||
|
@@ -215,6 +216,9 @@ struct Service {
|
||||||
|
bool flush_n_restarts;
|
||||||
|
|
||||||
|
OOMPolicy oom_policy;
|
||||||
|
+
|
||||||
|
+ int reload_signal;
|
||||||
|
+ usec_t reload_begin_usec;
|
||||||
|
};
|
||||||
|
|
||||||
|
static inline usec_t service_timeout_abort_usec(Service *s) {
|
||||||
|
diff --git a/src/shared/bus-unit-util.c b/src/shared/bus-unit-util.c
|
||||||
|
index 922011eccd..a9844e1cc3 100644
|
||||||
|
--- a/src/shared/bus-unit-util.c
|
||||||
|
+++ b/src/shared/bus-unit-util.c
|
||||||
|
@@ -2065,7 +2065,8 @@ static int bus_append_kill_property(sd_bus_message *m, const char *field, const
|
||||||
|
if (STR_IN_SET(field, "KillSignal",
|
||||||
|
"RestartKillSignal",
|
||||||
|
"FinalKillSignal",
|
||||||
|
- "WatchdogSignal"))
|
||||||
|
+ "WatchdogSignal",
|
||||||
|
+ "ReloadSignal"))
|
||||||
|
return bus_append_signal_from_string(m, field, eq);
|
||||||
|
|
||||||
|
return 0;
|
@ -0,0 +1,420 @@
|
|||||||
|
From e8de964c146f67c91acdaff076420282c2d1b217 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Lennart Poettering <lennart@poettering.net>
|
||||||
|
Date: Mon, 2 Jan 2023 18:13:27 +0100
|
||||||
|
Subject: [PATCH] man: document Type=notify-reload
|
||||||
|
|
||||||
|
(cherry picked from commit 81e19b6f6585d656e972efad73781e184ca0e7a0)
|
||||||
|
|
||||||
|
Related: RHEL-6090
|
||||||
|
---
|
||||||
|
man/sd_notify.xml | 36 ++++--
|
||||||
|
man/systemd.service.xml | 248 ++++++++++++++++++++++------------------
|
||||||
|
2 files changed, 162 insertions(+), 122 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/man/sd_notify.xml b/man/sd_notify.xml
|
||||||
|
index de402950bb..d2dba00004 100644
|
||||||
|
--- a/man/sd_notify.xml
|
||||||
|
+++ b/man/sd_notify.xml
|
||||||
|
@@ -102,23 +102,35 @@
|
||||||
|
<varlistentry>
|
||||||
|
<term>READY=1</term>
|
||||||
|
|
||||||
|
- <listitem><para>Tells the service manager that service startup is finished, or the service finished loading its
|
||||||
|
- configuration. This is only used by systemd if the service definition file has <varname>Type=notify</varname>
|
||||||
|
- set. Since there is little value in signaling non-readiness, the only value services should send is
|
||||||
|
- <literal>READY=1</literal> (i.e. <literal>READY=0</literal> is not defined).</para></listitem>
|
||||||
|
+ <listitem><para>Tells the service manager that service startup is finished, or the service finished
|
||||||
|
+ re-loading its configuration. This is only used by systemd if the service definition file has
|
||||||
|
+ <varname>Type=notify</varname> or <varname>Type=notify-reload</varname> set. Since there is little
|
||||||
|
+ value in signaling non-readiness, the only value services should send is <literal>READY=1</literal>
|
||||||
|
+ (i.e. <literal>READY=0</literal> is not defined).</para></listitem>
|
||||||
|
</varlistentry>
|
||||||
|
|
||||||
|
<varlistentry>
|
||||||
|
<term>RELOADING=1</term>
|
||||||
|
|
||||||
|
- <listitem><para>Tells the service manager that the service is
|
||||||
|
- reloading its configuration. This is useful to allow the
|
||||||
|
- service manager to track the service's internal state, and
|
||||||
|
- present it to the user. Note that a service that sends this
|
||||||
|
- notification must also send a <literal>READY=1</literal>
|
||||||
|
- notification when it completed reloading its
|
||||||
|
- configuration. Reloads are propagated in the same way as they
|
||||||
|
- are when initiated by the user.</para></listitem>
|
||||||
|
+ <listitem><para>Tells the service manager that the service is beginning to reload its
|
||||||
|
+ configuration. This is useful to allow the service manager to track the service's internal state, and
|
||||||
|
+ present it to the user. Note that a service that sends this notification must also send a
|
||||||
|
+ <literal>READY=1</literal> notification when it completed reloading its configuration. Reloads the
|
||||||
|
+ service manager is notified about with this mechanisms are propagated in the same way as they are
|
||||||
|
+ when originally initiated through the service manager. This message is particularly relevant for
|
||||||
|
+ <varname>Type=notify-reload</varname> services, to inform the service manager that the request to
|
||||||
|
+ reload the service has been received and is now being processed.</para></listitem>
|
||||||
|
+ </varlistentry>
|
||||||
|
+
|
||||||
|
+ <varlistentry>
|
||||||
|
+ <term>MONOTONIC_USEC=…</term>
|
||||||
|
+
|
||||||
|
+ <listitem><para>A field carrying the monotonic timestamp (as per
|
||||||
|
+ <constant>CLOCK_MONOTONIC</constant>) formatted in decimal in µs, when the notification message was
|
||||||
|
+ generated by the client. This is typically used in combination with <literal>RELOADING=1</literal>,
|
||||||
|
+ to allow the service manager to properly synchronize reload cycles. See
|
||||||
|
+ <citerefentry><refentrytitle>systemd.service</refentrytitle><manvolnum>5</manvolnum></citerefentry>
|
||||||
|
+ for details, specifically <literal>Type=notify-reload</literal>.</para></listitem>
|
||||||
|
</varlistentry>
|
||||||
|
|
||||||
|
<varlistentry>
|
||||||
|
diff --git a/man/systemd.service.xml b/man/systemd.service.xml
|
||||||
|
index 1c9e59f722..ae54332440 100644
|
||||||
|
--- a/man/systemd.service.xml
|
||||||
|
+++ b/man/systemd.service.xml
|
||||||
|
@@ -157,7 +157,7 @@
|
||||||
|
<listitem>
|
||||||
|
<para>Configures the process start-up type for this service unit. One of <option>simple</option>,
|
||||||
|
<option>exec</option>, <option>forking</option>, <option>oneshot</option>, <option>dbus</option>,
|
||||||
|
- <option>notify</option> or <option>idle</option>:</para>
|
||||||
|
+ <option>notify</option>, <option>notify-reload</option> or <option>idle</option>:</para>
|
||||||
|
|
||||||
|
<itemizedlist>
|
||||||
|
<listitem><para>If set to <option>simple</option> (the default if <varname>ExecStart=</varname> is
|
||||||
|
@@ -216,14 +216,30 @@
|
||||||
|
logic thus should be prepared to receive a <constant>SIGTERM</constant> (or whichever signal is
|
||||||
|
configured in <varname>KillSignal=</varname>) as result.</para></listitem>
|
||||||
|
|
||||||
|
- <listitem><para>Behavior of <option>notify</option> is similar to <option>exec</option>; however, it is
|
||||||
|
- expected that the service sends a notification message via
|
||||||
|
- <citerefentry><refentrytitle>sd_notify</refentrytitle><manvolnum>3</manvolnum></citerefentry> or an
|
||||||
|
- equivalent call when it has finished starting up. systemd will proceed with starting follow-up units after
|
||||||
|
- this notification message has been sent. If this option is used, <varname>NotifyAccess=</varname> (see
|
||||||
|
- below) should be set to open access to the notification socket provided by systemd. If
|
||||||
|
- <varname>NotifyAccess=</varname> is missing or set to <option>none</option>, it will be forcibly set to
|
||||||
|
- <option>main</option>.</para></listitem>
|
||||||
|
+ <listitem><para>Behavior of <option>notify</option> is similar to <option>exec</option>; however,
|
||||||
|
+ it is expected that the service sends a <literal>READY=1</literal> notification message via
|
||||||
|
+ <citerefentry><refentrytitle>sd_notify</refentrytitle><manvolnum>3</manvolnum></citerefentry> or
|
||||||
|
+ an equivalent call when it has finished starting up. systemd will proceed with starting follow-up
|
||||||
|
+ units after this notification message has been sent. If this option is used,
|
||||||
|
+ <varname>NotifyAccess=</varname> (see below) should be set to open access to the notification
|
||||||
|
+ socket provided by systemd. If <varname>NotifyAccess=</varname> is missing or set to
|
||||||
|
+ <option>none</option>, it will be forcibly set to <option>main</option>.</para></listitem>
|
||||||
|
+
|
||||||
|
+ <listitem><para>Behavior of <option>notify-reload</option> is identical to
|
||||||
|
+ <option>notify</option>. However, it extends the logic in one way: the
|
||||||
|
+ <constant>SIGHUP</constant> UNIX process signal is sent to the service's main process when the
|
||||||
|
+ service is asked to reload. (The signal to send can be tweaked via
|
||||||
|
+ <varname>ReloadSignal=</varname>, see below.). When
|
||||||
|
+ initiating the reload process the service is then expected to reply with a notification message
|
||||||
|
+ via <citerefentry><refentrytitle>sd_notify</refentrytitle><manvolnum>3</manvolnum></citerefentry>
|
||||||
|
+ that contains the <literal>RELOADING=1</literal> field in combination with
|
||||||
|
+ <literal>MONOTONIC_USEC=</literal> set to the current monotonic time
|
||||||
|
+ (i.e. <constant>CLOCK_MONOTONIC</constant> in
|
||||||
|
+ <citerefentry><refentrytitle>clock_gettime</refentrytitle><manvolnum>2</manvolnum></citerefentry>)
|
||||||
|
+ in µs, formatted as decimal string. Once reloading is complete another notification message must
|
||||||
|
+ be sent, containing <literal>READY=1</literal>. Using this service type and implementing this
|
||||||
|
+ reload protocol is an efficient alternative to providing an <varname>ExecReload=</varname>
|
||||||
|
+ command for reloading of the service's configuration.</para></listitem>
|
||||||
|
|
||||||
|
<listitem><para>Behavior of <option>idle</option> is very similar to <option>simple</option>; however,
|
||||||
|
actual execution of the service program is delayed until all active jobs are dispatched. This may be used
|
||||||
|
@@ -233,25 +249,27 @@
|
||||||
|
anyway.</para></listitem>
|
||||||
|
</itemizedlist>
|
||||||
|
|
||||||
|
- <para>It is generally recommended to use <varname>Type=</varname><option>simple</option> for long-running
|
||||||
|
- services whenever possible, as it is the simplest and fastest option. However, as this service type won't
|
||||||
|
- propagate service start-up failures and doesn't allow ordering of other units against completion of
|
||||||
|
- initialization of the service (which for example is useful if clients need to connect to the service through
|
||||||
|
- some form of IPC, and the IPC channel is only established by the service itself — in contrast to doing this
|
||||||
|
- ahead of time through socket or bus activation or similar), it might not be sufficient for many cases. If so,
|
||||||
|
- <option>notify</option> or <option>dbus</option> (the latter only in case the service provides a D-Bus
|
||||||
|
- interface) are the preferred options as they allow service program code to precisely schedule when to
|
||||||
|
- consider the service started up successfully and when to proceed with follow-up units. The
|
||||||
|
- <option>notify</option> service type requires explicit support in the service codebase (as
|
||||||
|
- <function>sd_notify()</function> or an equivalent API needs to be invoked by the service at the appropriate
|
||||||
|
- time) — if it's not supported, then <option>forking</option> is an alternative: it supports the traditional
|
||||||
|
- UNIX service start-up protocol. Finally, <option>exec</option> might be an option for cases where it is
|
||||||
|
- enough to ensure the service binary is invoked, and where the service binary itself executes no or little
|
||||||
|
- initialization on its own (and its initialization is unlikely to fail). Note that using any type other than
|
||||||
|
- <option>simple</option> possibly delays the boot process, as the service manager needs to wait for service
|
||||||
|
- initialization to complete. It is hence recommended not to needlessly use any types other than
|
||||||
|
- <option>simple</option>. (Also note it is generally not recommended to use <option>idle</option> or
|
||||||
|
- <option>oneshot</option> for long-running services.)</para>
|
||||||
|
+ <para>It is generally recommended to use <varname>Type=</varname><option>simple</option> for
|
||||||
|
+ long-running services whenever possible, as it is the simplest and fastest option. However, as this
|
||||||
|
+ service type won't propagate service start-up failures and doesn't allow ordering of other units
|
||||||
|
+ against completion of initialization of the service (which for example is useful if clients need to
|
||||||
|
+ connect to the service through some form of IPC, and the IPC channel is only established by the
|
||||||
|
+ service itself — in contrast to doing this ahead of time through socket or bus activation or
|
||||||
|
+ similar), it might not be sufficient for many cases. If so, <option>notify</option>,
|
||||||
|
+ <option>notify-reload</option> or <option>dbus</option> (the latter only in case the service
|
||||||
|
+ provides a D-Bus interface) are the preferred options as they allow service program code to
|
||||||
|
+ precisely schedule when to consider the service started up successfully and when to proceed with
|
||||||
|
+ follow-up units. The <option>notify</option>/<option>notify-reload</option> service types require
|
||||||
|
+ explicit support in the service codebase (as <function>sd_notify()</function> or an equivalent API
|
||||||
|
+ needs to be invoked by the service at the appropriate time) — if it's not supported, then
|
||||||
|
+ <option>forking</option> is an alternative: it supports the traditional UNIX service start-up
|
||||||
|
+ protocol. Finally, <option>exec</option> might be an option for cases where it is enough to ensure
|
||||||
|
+ the service binary is invoked, and where the service binary itself executes no or little
|
||||||
|
+ initialization on its own (and its initialization is unlikely to fail). Note that using any type
|
||||||
|
+ other than <option>simple</option> possibly delays the boot process, as the service manager needs
|
||||||
|
+ to wait for service initialization to complete. It is hence recommended not to needlessly use any
|
||||||
|
+ types other than <option>simple</option>. (Also note it is generally not recommended to use
|
||||||
|
+ <option>idle</option> or <option>oneshot</option> for long-running services.)</para>
|
||||||
|
</listitem>
|
||||||
|
</varlistentry>
|
||||||
|
|
||||||
|
@@ -319,9 +337,10 @@
|
||||||
|
the file may not be a symlink to a file owned by a different user (neither directly nor indirectly), and the
|
||||||
|
PID file must refer to a process already belonging to the service.</para>
|
||||||
|
|
||||||
|
- <para>Note that PID files should be avoided in modern projects. Use <option>Type=notify</option> or
|
||||||
|
- <option>Type=simple</option> where possible, which does not require use of PID files to determine the
|
||||||
|
- main process of a service and avoids needless forking.</para></listitem>
|
||||||
|
+ <para>Note that PID files should be avoided in modern projects. Use <option>Type=notify</option>,
|
||||||
|
+ <option>Type=notify-reload</option> or <option>Type=simple</option> where possible, which does not
|
||||||
|
+ require use of PID files to determine the main process of a service and avoids needless
|
||||||
|
+ forking.</para></listitem>
|
||||||
|
</varlistentry>
|
||||||
|
|
||||||
|
<varlistentry>
|
||||||
|
@@ -443,12 +462,13 @@
|
||||||
|
with a <literal>-</literal> exit successfully.</para>
|
||||||
|
|
||||||
|
<para><varname>ExecStartPost=</varname> commands are only run after the commands specified in
|
||||||
|
- <varname>ExecStart=</varname> have been invoked successfully, as determined by <varname>Type=</varname>
|
||||||
|
- (i.e. the process has been started for <varname>Type=simple</varname> or <varname>Type=idle</varname>, the last
|
||||||
|
- <varname>ExecStart=</varname> process exited successfully for <varname>Type=oneshot</varname>, the initial
|
||||||
|
- process exited successfully for <varname>Type=forking</varname>, <literal>READY=1</literal> is sent for
|
||||||
|
- <varname>Type=notify</varname>, or the <varname>BusName=</varname> has been taken for
|
||||||
|
- <varname>Type=dbus</varname>).</para>
|
||||||
|
+ <varname>ExecStart=</varname> have been invoked successfully, as determined by
|
||||||
|
+ <varname>Type=</varname> (i.e. the process has been started for <varname>Type=simple</varname> or
|
||||||
|
+ <varname>Type=idle</varname>, the last <varname>ExecStart=</varname> process exited successfully for
|
||||||
|
+ <varname>Type=oneshot</varname>, the initial process exited successfully for
|
||||||
|
+ <varname>Type=forking</varname>, <literal>READY=1</literal> is sent for
|
||||||
|
+ <varname>Type=notify</varname>/<varname>Type=notify-reload</varname>, or the
|
||||||
|
+ <varname>BusName=</varname> has been taken for <varname>Type=dbus</varname>).</para>
|
||||||
|
|
||||||
|
<para>Note that <varname>ExecStartPre=</varname> may not be
|
||||||
|
used to start long-running processes. All processes forked
|
||||||
|
@@ -487,30 +507,26 @@
|
||||||
|
|
||||||
|
<varlistentry>
|
||||||
|
<term><varname>ExecReload=</varname></term>
|
||||||
|
- <listitem><para>Commands to execute to trigger a configuration
|
||||||
|
- reload in the service. This argument takes multiple command
|
||||||
|
- lines, following the same scheme as described for
|
||||||
|
- <varname>ExecStart=</varname> above. Use of this setting is
|
||||||
|
- optional. Specifier and environment variable substitution is
|
||||||
|
- supported here following the same scheme as for
|
||||||
|
+
|
||||||
|
+ <listitem><para>Commands to execute to trigger a configuration reload in the service. This argument
|
||||||
|
+ takes multiple command lines, following the same scheme as described for
|
||||||
|
+ <varname>ExecStart=</varname> above. Use of this setting is optional. Specifier and environment
|
||||||
|
+ variable substitution is supported here following the same scheme as for
|
||||||
|
<varname>ExecStart=</varname>.</para>
|
||||||
|
|
||||||
|
- <para>One additional, special environment variable is set: if
|
||||||
|
- known, <varname>$MAINPID</varname> is set to the main process
|
||||||
|
- of the daemon, and may be used for command lines like the
|
||||||
|
- following:</para>
|
||||||
|
+ <para>One additional, special environment variable is set: if known, <varname>$MAINPID</varname> is
|
||||||
|
+ set to the main process of the daemon, and may be used for command lines like the following:</para>
|
||||||
|
|
||||||
|
<programlisting>ExecReload=kill -HUP $MAINPID</programlisting>
|
||||||
|
|
||||||
|
- <para>Note however that reloading a daemon by sending a signal
|
||||||
|
- (as with the example line above) is usually not a good choice,
|
||||||
|
- because this is an asynchronous operation and hence not
|
||||||
|
- suitable to order reloads of multiple services against each
|
||||||
|
- other. It is strongly recommended to set
|
||||||
|
- <varname>ExecReload=</varname> to a command that not only
|
||||||
|
- triggers a configuration reload of the daemon, but also
|
||||||
|
- synchronously waits for it to complete. For example,
|
||||||
|
- <citerefentry project='mankier'><refentrytitle>dbus-broker</refentrytitle><manvolnum>1</manvolnum></citerefentry>
|
||||||
|
+ <para>Note however that reloading a daemon by enqueing a signal (as with the example line above) is
|
||||||
|
+ usually not a good choice, because this is an asynchronous operation and hence not suitable when
|
||||||
|
+ ordering reloads of multiple services against each other. It is thus strongly recommended to either
|
||||||
|
+ use <varname>Type=</varname><option>notify-reload</option> in place of
|
||||||
|
+ <varname>ExecReload=</varname>, or to set <varname>ExecReload=</varname> to a command that not only
|
||||||
|
+ triggers a configuration reload of the daemon, but also synchronously waits for it to complete. For
|
||||||
|
+ example, <citerefentry
|
||||||
|
+ project='mankier'><refentrytitle>dbus-broker</refentrytitle><manvolnum>1</manvolnum></citerefentry>
|
||||||
|
uses the following:</para>
|
||||||
|
|
||||||
|
<programlisting>ExecReload=busctl call org.freedesktop.DBus \
|
||||||
|
@@ -605,12 +621,13 @@
|
||||||
|
<citerefentry><refentrytitle>systemd-system.conf</refentrytitle><manvolnum>5</manvolnum></citerefentry>).
|
||||||
|
</para>
|
||||||
|
|
||||||
|
- <para>If a service of <varname>Type=notify</varname> sends <literal>EXTEND_TIMEOUT_USEC=…</literal>, this may cause
|
||||||
|
- the start time to be extended beyond <varname>TimeoutStartSec=</varname>. The first receipt of this message
|
||||||
|
- must occur before <varname>TimeoutStartSec=</varname> is exceeded, and once the start time has extended beyond
|
||||||
|
- <varname>TimeoutStartSec=</varname>, the service manager will allow the service to continue to start, provided
|
||||||
|
- the service repeats <literal>EXTEND_TIMEOUT_USEC=…</literal> within the interval specified until the service
|
||||||
|
- startup status is finished by <literal>READY=1</literal>. (see
|
||||||
|
+ <para>If a service of <varname>Type=notify</varname>/<varname>Type=notify-reload</varname> sends
|
||||||
|
+ <literal>EXTEND_TIMEOUT_USEC=…</literal>, this may cause the start time to be extended beyond
|
||||||
|
+ <varname>TimeoutStartSec=</varname>. The first receipt of this message must occur before
|
||||||
|
+ <varname>TimeoutStartSec=</varname> is exceeded, and once the start time has extended beyond
|
||||||
|
+ <varname>TimeoutStartSec=</varname>, the service manager will allow the service to continue to start,
|
||||||
|
+ provided the service repeats <literal>EXTEND_TIMEOUT_USEC=…</literal> within the interval specified
|
||||||
|
+ until the service startup status is finished by <literal>READY=1</literal>. (see
|
||||||
|
<citerefentry><refentrytitle>sd_notify</refentrytitle><manvolnum>3</manvolnum></citerefentry>).
|
||||||
|
</para></listitem>
|
||||||
|
</varlistentry>
|
||||||
|
@@ -633,12 +650,14 @@
|
||||||
|
<citerefentry><refentrytitle>systemd-system.conf</refentrytitle><manvolnum>5</manvolnum></citerefentry>).
|
||||||
|
</para>
|
||||||
|
|
||||||
|
- <para>If a service of <varname>Type=notify</varname> sends <literal>EXTEND_TIMEOUT_USEC=…</literal>, this may cause
|
||||||
|
- the stop time to be extended beyond <varname>TimeoutStopSec=</varname>. The first receipt of this message
|
||||||
|
- must occur before <varname>TimeoutStopSec=</varname> is exceeded, and once the stop time has extended beyond
|
||||||
|
- <varname>TimeoutStopSec=</varname>, the service manager will allow the service to continue to stop, provided
|
||||||
|
- the service repeats <literal>EXTEND_TIMEOUT_USEC=…</literal> within the interval specified, or terminates itself
|
||||||
|
- (see <citerefentry><refentrytitle>sd_notify</refentrytitle><manvolnum>3</manvolnum></citerefentry>).
|
||||||
|
+ <para>If a service of <varname>Type=notify</varname>/<varname>Type=notify-reload</varname> sends
|
||||||
|
+ <literal>EXTEND_TIMEOUT_USEC=…</literal>, this may cause the stop time to be extended beyond
|
||||||
|
+ <varname>TimeoutStopSec=</varname>. The first receipt of this message must occur before
|
||||||
|
+ <varname>TimeoutStopSec=</varname> is exceeded, and once the stop time has extended beyond
|
||||||
|
+ <varname>TimeoutStopSec=</varname>, the service manager will allow the service to continue to stop,
|
||||||
|
+ provided the service repeats <literal>EXTEND_TIMEOUT_USEC=…</literal> within the interval specified,
|
||||||
|
+ or terminates itself (see
|
||||||
|
+ <citerefentry><refentrytitle>sd_notify</refentrytitle><manvolnum>3</manvolnum></citerefentry>).
|
||||||
|
</para></listitem>
|
||||||
|
</varlistentry>
|
||||||
|
|
||||||
|
@@ -661,13 +680,15 @@
|
||||||
|
<citerefentry><refentrytitle>systemd-system.conf</refentrytitle><manvolnum>5</manvolnum></citerefentry>).
|
||||||
|
</para>
|
||||||
|
|
||||||
|
- <para>If a service of <varname>Type=notify</varname> handles <constant>SIGABRT</constant> itself (instead of relying
|
||||||
|
- on the kernel to write a core dump) it can send <literal>EXTEND_TIMEOUT_USEC=…</literal> to
|
||||||
|
- extended the abort time beyond <varname>TimeoutAbortSec=</varname>. The first receipt of this message
|
||||||
|
- must occur before <varname>TimeoutAbortSec=</varname> is exceeded, and once the abort time has extended beyond
|
||||||
|
- <varname>TimeoutAbortSec=</varname>, the service manager will allow the service to continue to abort, provided
|
||||||
|
- the service repeats <literal>EXTEND_TIMEOUT_USEC=…</literal> within the interval specified, or terminates itself
|
||||||
|
- (see <citerefentry><refentrytitle>sd_notify</refentrytitle><manvolnum>3</manvolnum></citerefentry>).
|
||||||
|
+ <para>If a service of <varname>Type=notify</varname>/<varname>Type=notify-reload</varname> handles
|
||||||
|
+ <constant>SIGABRT</constant> itself (instead of relying on the kernel to write a core dump) it can
|
||||||
|
+ send <literal>EXTEND_TIMEOUT_USEC=…</literal> to extended the abort time beyond
|
||||||
|
+ <varname>TimeoutAbortSec=</varname>. The first receipt of this message must occur before
|
||||||
|
+ <varname>TimeoutAbortSec=</varname> is exceeded, and once the abort time has extended beyond
|
||||||
|
+ <varname>TimeoutAbortSec=</varname>, the service manager will allow the service to continue to abort,
|
||||||
|
+ provided the service repeats <literal>EXTEND_TIMEOUT_USEC=…</literal> within the interval specified,
|
||||||
|
+ or terminates itself (see
|
||||||
|
+ <citerefentry><refentrytitle>sd_notify</refentrytitle><manvolnum>3</manvolnum></citerefentry>).
|
||||||
|
</para></listitem>
|
||||||
|
</varlistentry>
|
||||||
|
|
||||||
|
@@ -710,12 +731,13 @@
|
||||||
|
activation completed. Pass <literal>infinity</literal> (the default) to configure no runtime
|
||||||
|
limit.</para>
|
||||||
|
|
||||||
|
- <para>If a service of <varname>Type=notify</varname> sends <literal>EXTEND_TIMEOUT_USEC=…</literal>, this may cause
|
||||||
|
- the runtime to be extended beyond <varname>RuntimeMaxSec=</varname>. The first receipt of this message
|
||||||
|
- must occur before <varname>RuntimeMaxSec=</varname> is exceeded, and once the runtime has extended beyond
|
||||||
|
- <varname>RuntimeMaxSec=</varname>, the service manager will allow the service to continue to run, provided
|
||||||
|
- the service repeats <literal>EXTEND_TIMEOUT_USEC=…</literal> within the interval specified until the service
|
||||||
|
- shutdown is achieved by <literal>STOPPING=1</literal> (or termination). (see
|
||||||
|
+ <para>If a service of <varname>Type=notify</varname>/<varname>Type=notify-reload</varname> sends
|
||||||
|
+ <literal>EXTEND_TIMEOUT_USEC=…</literal>, this may cause the runtime to be extended beyond
|
||||||
|
+ <varname>RuntimeMaxSec=</varname>. The first receipt of this message must occur before
|
||||||
|
+ <varname>RuntimeMaxSec=</varname> is exceeded, and once the runtime has extended beyond
|
||||||
|
+ <varname>RuntimeMaxSec=</varname>, the service manager will allow the service to continue to run,
|
||||||
|
+ provided the service repeats <literal>EXTEND_TIMEOUT_USEC=…</literal> within the interval specified
|
||||||
|
+ until the service shutdown is achieved by <literal>STOPPING=1</literal> (or termination). (see
|
||||||
|
<citerefentry><refentrytitle>sd_notify</refentrytitle><manvolnum>3</manvolnum></citerefentry>).
|
||||||
|
</para></listitem>
|
||||||
|
</varlistentry>
|
||||||
|
@@ -1023,16 +1045,19 @@
|
||||||
|
<varlistentry>
|
||||||
|
<term><varname>NotifyAccess=</varname></term>
|
||||||
|
<listitem><para>Controls access to the service status notification socket, as accessible via the
|
||||||
|
- <citerefentry><refentrytitle>sd_notify</refentrytitle><manvolnum>3</manvolnum></citerefentry> call. Takes one
|
||||||
|
- of <option>none</option> (the default), <option>main</option>, <option>exec</option> or
|
||||||
|
- <option>all</option>. If <option>none</option>, no daemon status updates are accepted from the service
|
||||||
|
- processes, all status update messages are ignored. If <option>main</option>, only service updates sent from the
|
||||||
|
- main process of the service are accepted. If <option>exec</option>, only service updates sent from any of the
|
||||||
|
- main or control processes originating from one of the <varname>Exec*=</varname> commands are accepted. If
|
||||||
|
- <option>all</option>, all services updates from all members of the service's control group are accepted. This
|
||||||
|
- option should be set to open access to the notification socket when using <varname>Type=notify</varname> or
|
||||||
|
- <varname>WatchdogSec=</varname> (see above). If those options are used but <varname>NotifyAccess=</varname> is
|
||||||
|
- not configured, it will be implicitly set to <option>main</option>.</para>
|
||||||
|
+ <citerefentry><refentrytitle>sd_notify</refentrytitle><manvolnum>3</manvolnum></citerefentry>
|
||||||
|
+ call. Takes one of <option>none</option> (the default), <option>main</option>, <option>exec</option>
|
||||||
|
+ or <option>all</option>. If <option>none</option>, no daemon status updates are accepted from the
|
||||||
|
+ service processes, all status update messages are ignored. If <option>main</option>, only service
|
||||||
|
+ updates sent from the main process of the service are accepted. If <option>exec</option>, only
|
||||||
|
+ service updates sent from any of the main or control processes originating from one of the
|
||||||
|
+ <varname>Exec*=</varname> commands are accepted. If <option>all</option>, all services updates from
|
||||||
|
+ all members of the service's control group are accepted. This option should be set to open access to
|
||||||
|
+ the notification socket when using
|
||||||
|
+ <varname>Type=notify</varname>/<varname>Type=notify-reload</varname> or
|
||||||
|
+ <varname>WatchdogSec=</varname> (see above). If those options are used but
|
||||||
|
+ <varname>NotifyAccess=</varname> is not configured, it will be implicitly set to
|
||||||
|
+ <option>main</option>.</para>
|
||||||
|
|
||||||
|
<para>Note that <function>sd_notify()</function> notifications may be attributed to units correctly only if
|
||||||
|
either the sending process is still around at the time PID 1 processes the message, or if the sending process
|
||||||
|
@@ -1156,6 +1181,15 @@
|
||||||
|
kills, this setting determines the state of the unit after <command>systemd-oomd</command> kills a
|
||||||
|
cgroup associated with it.</para></listitem>
|
||||||
|
</varlistentry>
|
||||||
|
+
|
||||||
|
+ <varlistentry>
|
||||||
|
+ <term><varname>ReloadSignal=</varname></term>
|
||||||
|
+ <listitem><para>Configures the UNIX process signal to send to the service's main process when asked
|
||||||
|
+ to reload the service's configuration. Defaults to <constant>SIGHUP</constant>. This option has no
|
||||||
|
+ effect unless <varname>Type=</varname><option>notify-reload</option> is used, see
|
||||||
|
+ above.</para></listitem>
|
||||||
|
+ </varlistentry>
|
||||||
|
+
|
||||||
|
</variablelist>
|
||||||
|
|
||||||
|
<para id='shared-unit-options'>Check
|
||||||
|
@@ -1319,16 +1353,13 @@ WantedBy=multi-user.target</programlisting>
|
||||||
|
<citerefentry><refentrytitle>systemd.kill</refentrytitle><manvolnum>5</manvolnum></citerefentry>
|
||||||
|
for details.</para>
|
||||||
|
|
||||||
|
- <para>Note that this unit type does not include any type of
|
||||||
|
- notification when a service has completed initialization. For
|
||||||
|
- this, you should use other unit types, such as
|
||||||
|
- <varname>Type=</varname><option>notify</option> if the service
|
||||||
|
- understands systemd's notification protocol,
|
||||||
|
- <varname>Type=</varname><option>forking</option> if the service
|
||||||
|
- can background itself or
|
||||||
|
- <varname>Type=</varname><option>dbus</option> if the unit
|
||||||
|
- acquires a DBus name once initialization is complete. See
|
||||||
|
- below.</para>
|
||||||
|
+ <para>Note that this unit type does not include any type of notification when a service has completed
|
||||||
|
+ initialization. For this, you should use other unit types, such as
|
||||||
|
+ <varname>Type=</varname><option>notify</option>/<varname>Type=</varname><option>notify-reload</option>
|
||||||
|
+ if the service understands systemd's notification protocol,
|
||||||
|
+ <varname>Type=</varname><option>forking</option> if the service can background itself or
|
||||||
|
+ <varname>Type=</varname><option>dbus</option> if the unit acquires a DBus name once initialization is
|
||||||
|
+ complete. See below.</para>
|
||||||
|
</example>
|
||||||
|
|
||||||
|
<example>
|
||||||
|
@@ -1505,15 +1536,12 @@ SystemdService=simple-dbus-service.service</programlisting>
|
||||||
|
<example>
|
||||||
|
<title>Services that notify systemd about their initialization</title>
|
||||||
|
|
||||||
|
- <para><varname>Type=</varname><option>simple</option> services
|
||||||
|
- are really easy to write, but have the major disadvantage of
|
||||||
|
- systemd not being able to tell when initialization of the given
|
||||||
|
- service is complete. For this reason, systemd supports a simple
|
||||||
|
- notification protocol that allows daemons to make systemd aware
|
||||||
|
- that they are done initializing. Use
|
||||||
|
- <varname>Type=</varname><option>notify</option> for this. A
|
||||||
|
- typical service file for such a daemon would look like
|
||||||
|
- this:</para>
|
||||||
|
+ <para><varname>Type=</varname><option>simple</option> services are really easy to write, but have the
|
||||||
|
+ major disadvantage of systemd not being able to tell when initialization of the given service is
|
||||||
|
+ complete. For this reason, systemd supports a simple notification protocol that allows daemons to make
|
||||||
|
+ systemd aware that they are done initializing. Use <varname>Type=</varname><option>notify</option> or
|
||||||
|
+ <varname>Type=</varname><option>notify-reload</option> for this. A typical service file for such a
|
||||||
|
+ daemon would look like this:</para>
|
||||||
|
|
||||||
|
<programlisting>[Unit]
|
||||||
|
Description=Simple notifying service
|
@ -0,0 +1,105 @@
|
|||||||
|
From 567b6dcd4ff8e4a9c9b0b1629fa8c015d5e6a724 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Lennart Poettering <lennart@poettering.net>
|
||||||
|
Date: Mon, 2 Jan 2023 15:01:56 +0100
|
||||||
|
Subject: [PATCH] pid1: make sure we send our calling service manager
|
||||||
|
RELOADING=1 when reloading
|
||||||
|
|
||||||
|
And send READY=1 again when we are done with it.
|
||||||
|
|
||||||
|
We do this not only for "daemon-reload" but also for "daemon-reexec" and
|
||||||
|
"switch-root", since from the perspective of an encapsulating service
|
||||||
|
manager these three operations are not that different.
|
||||||
|
|
||||||
|
(cherry picked from commit dd0ab174c36492cdcb92cf46844fb0905b1d4a7e)
|
||||||
|
|
||||||
|
Related: RHEL-6090
|
||||||
|
---
|
||||||
|
src/core/main.c | 10 ++++++++++
|
||||||
|
src/core/manager.c | 12 ++++++++++++
|
||||||
|
src/core/manager.h | 1 +
|
||||||
|
units/user@.service.in | 2 +-
|
||||||
|
4 files changed, 24 insertions(+), 1 deletion(-)
|
||||||
|
|
||||||
|
diff --git a/src/core/main.c b/src/core/main.c
|
||||||
|
index 0e2e5448bb..126a4bce8c 100644
|
||||||
|
--- a/src/core/main.c
|
||||||
|
+++ b/src/core/main.c
|
||||||
|
@@ -1925,6 +1925,8 @@ static int invoke_main_loop(
|
||||||
|
LogTarget saved_log_target;
|
||||||
|
int saved_log_level;
|
||||||
|
|
||||||
|
+ manager_send_reloading(m);
|
||||||
|
+
|
||||||
|
log_info("Reloading.");
|
||||||
|
|
||||||
|
/* First, save any overridden log level/target, then parse the configuration file,
|
||||||
|
@@ -1955,6 +1957,10 @@ static int invoke_main_loop(
|
||||||
|
}
|
||||||
|
|
||||||
|
case MANAGER_REEXECUTE:
|
||||||
|
+
|
||||||
|
+ manager_send_reloading(m); /* From the perspective of the manager calling us this is
|
||||||
|
+ * pretty much the same as a reload */
|
||||||
|
+
|
||||||
|
r = prepare_reexecute(m, &arg_serialization, ret_fds, false);
|
||||||
|
if (r < 0) {
|
||||||
|
*ret_error_message = "Failed to prepare for reexecution";
|
||||||
|
@@ -1970,6 +1976,10 @@ static int invoke_main_loop(
|
||||||
|
return objective;
|
||||||
|
|
||||||
|
case MANAGER_SWITCH_ROOT:
|
||||||
|
+
|
||||||
|
+ manager_send_reloading(m); /* From the perspective of the manager calling us this is
|
||||||
|
+ * pretty much the same as a reload */
|
||||||
|
+
|
||||||
|
manager_set_switching_root(m, true);
|
||||||
|
|
||||||
|
if (!m->switch_root_init) {
|
||||||
|
diff --git a/src/core/manager.c b/src/core/manager.c
|
||||||
|
index 6371810ce3..b34103d7d3 100644
|
||||||
|
--- a/src/core/manager.c
|
||||||
|
+++ b/src/core/manager.c
|
||||||
|
@@ -3641,6 +3641,18 @@ void manager_check_finished(Manager *m) {
|
||||||
|
manager_invalidate_startup_units(m);
|
||||||
|
}
|
||||||
|
|
||||||
|
+void manager_send_reloading(Manager *m) {
|
||||||
|
+ assert(m);
|
||||||
|
+
|
||||||
|
+ /* Let whoever invoked us know that we are now reloading */
|
||||||
|
+ (void) sd_notifyf(/* unset= */ false,
|
||||||
|
+ "RELOADING=1\n"
|
||||||
|
+ "MONOTONIC_USEC=" USEC_FMT "\n", now(CLOCK_MONOTONIC));
|
||||||
|
+
|
||||||
|
+ /* And ensure that we'll send READY=1 again as soon as we are ready again */
|
||||||
|
+ m->ready_sent = false;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
static bool generator_path_any(const char* const* paths) {
|
||||||
|
bool found = false;
|
||||||
|
|
||||||
|
diff --git a/src/core/manager.h b/src/core/manager.h
|
||||||
|
index 75c16d6e26..87e63c3b68 100644
|
||||||
|
--- a/src/core/manager.h
|
||||||
|
+++ b/src/core/manager.h
|
||||||
|
@@ -535,6 +535,7 @@ void manager_send_unit_plymouth(Manager *m, Unit *u);
|
||||||
|
bool manager_unit_inactive_or_pending(Manager *m, const char *name);
|
||||||
|
|
||||||
|
void manager_check_finished(Manager *m);
|
||||||
|
+void manager_send_reloading(Manager *m);
|
||||||
|
|
||||||
|
void disable_printk_ratelimit(void);
|
||||||
|
void manager_recheck_dbus(Manager *m);
|
||||||
|
diff --git a/units/user@.service.in b/units/user@.service.in
|
||||||
|
index efbd5dfbc8..2c99f50905 100644
|
||||||
|
--- a/units/user@.service.in
|
||||||
|
+++ b/units/user@.service.in
|
||||||
|
@@ -17,7 +17,7 @@ IgnoreOnIsolate=yes
|
||||||
|
[Service]
|
||||||
|
User=%i
|
||||||
|
PAMName=systemd-user
|
||||||
|
-Type=notify
|
||||||
|
+Type=notify-reload
|
||||||
|
ExecStart={{ROOTLIBEXECDIR}}/systemd --user
|
||||||
|
Slice=user-%i.slice
|
||||||
|
KillMode=mixed
|
@ -0,0 +1,166 @@
|
|||||||
|
From fef242735b987c1870bcd0460cc0c802e78a3cde Mon Sep 17 00:00:00 2001
|
||||||
|
From: Lennart Poettering <lennart@poettering.net>
|
||||||
|
Date: Mon, 2 Jan 2023 17:25:46 +0100
|
||||||
|
Subject: [PATCH] networkd: implement Type=notify-reload protocol
|
||||||
|
|
||||||
|
(cherry picked from commit 0e07cdb0e77d0322bc866b5e13abbe38e988059d)
|
||||||
|
|
||||||
|
Related: RHEL-6090
|
||||||
|
---
|
||||||
|
src/network/networkd-manager-bus.c | 13 +-------
|
||||||
|
src/network/networkd-manager.c | 48 ++++++++++++++++++++++++++----
|
||||||
|
src/network/networkd-manager.h | 2 ++
|
||||||
|
src/network/networkd.c | 2 --
|
||||||
|
units/systemd-networkd.service.in | 3 +-
|
||||||
|
5 files changed, 47 insertions(+), 21 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/src/network/networkd-manager-bus.c b/src/network/networkd-manager-bus.c
|
||||||
|
index 2ab3aaadc2..67f951df69 100644
|
||||||
|
--- a/src/network/networkd-manager-bus.c
|
||||||
|
+++ b/src/network/networkd-manager-bus.c
|
||||||
|
@@ -197,7 +197,6 @@ static int bus_method_reconfigure_link(sd_bus_message *message, void *userdata,
|
||||||
|
|
||||||
|
static int bus_method_reload(sd_bus_message *message, void *userdata, sd_bus_error *error) {
|
||||||
|
Manager *manager = userdata;
|
||||||
|
- Link *link;
|
||||||
|
int r;
|
||||||
|
|
||||||
|
r = bus_verify_polkit_async(message, CAP_NET_ADMIN,
|
||||||
|
@@ -209,20 +208,10 @@ static int bus_method_reload(sd_bus_message *message, void *userdata, sd_bus_err
|
||||||
|
if (r == 0)
|
||||||
|
return 1; /* Polkit will call us back */
|
||||||
|
|
||||||
|
- r = netdev_load(manager, true);
|
||||||
|
+ r = manager_reload(manager);
|
||||||
|
if (r < 0)
|
||||||
|
return r;
|
||||||
|
|
||||||
|
- r = network_reload(manager);
|
||||||
|
- if (r < 0)
|
||||||
|
- return r;
|
||||||
|
-
|
||||||
|
- HASHMAP_FOREACH(link, manager->links_by_index) {
|
||||||
|
- r = link_reconfigure(link, /* force = */ false);
|
||||||
|
- if (r < 0)
|
||||||
|
- return r;
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
return sd_bus_reply_method_return(message, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
diff --git a/src/network/networkd-manager.c b/src/network/networkd-manager.c
|
||||||
|
index cdfd29bc0e..362ee84b09 100644
|
||||||
|
--- a/src/network/networkd-manager.c
|
||||||
|
+++ b/src/network/networkd-manager.c
|
||||||
|
@@ -483,6 +483,14 @@ static int signal_restart_callback(sd_event_source *s, const struct signalfd_sig
|
||||||
|
return sd_event_exit(sd_event_source_get_event(s), 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
+static int signal_reload_callback(sd_event_source *s, const struct signalfd_siginfo *si, void *userdata) {
|
||||||
|
+ Manager *m = ASSERT_PTR(userdata);
|
||||||
|
+
|
||||||
|
+ manager_reload(m);
|
||||||
|
+
|
||||||
|
+ return 0;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
static int manager_set_keep_configuration(Manager *m) {
|
||||||
|
int r;
|
||||||
|
|
||||||
|
@@ -517,12 +525,11 @@ int manager_setup(Manager *m) {
|
||||||
|
if (r < 0)
|
||||||
|
return r;
|
||||||
|
|
||||||
|
- assert_se(sigprocmask_many(SIG_SETMASK, NULL, SIGINT, SIGTERM, SIGUSR2, -1) >= 0);
|
||||||
|
-
|
||||||
|
(void) sd_event_set_watchdog(m->event, true);
|
||||||
|
- (void) sd_event_add_signal(m->event, NULL, SIGTERM, signal_terminate_callback, m);
|
||||||
|
- (void) sd_event_add_signal(m->event, NULL, SIGINT, signal_terminate_callback, m);
|
||||||
|
- (void) sd_event_add_signal(m->event, NULL, SIGUSR2, signal_restart_callback, m);
|
||||||
|
+ (void) sd_event_add_signal(m->event, NULL, SIGTERM | SD_EVENT_SIGNAL_PROCMASK, signal_terminate_callback, m);
|
||||||
|
+ (void) sd_event_add_signal(m->event, NULL, SIGINT | SD_EVENT_SIGNAL_PROCMASK, signal_terminate_callback, m);
|
||||||
|
+ (void) sd_event_add_signal(m->event, NULL, SIGUSR2 | SD_EVENT_SIGNAL_PROCMASK, signal_restart_callback, m);
|
||||||
|
+ (void) sd_event_add_signal(m->event, NULL, SIGHUP | SD_EVENT_SIGNAL_PROCMASK, signal_reload_callback, m);
|
||||||
|
|
||||||
|
r = sd_event_add_post(m->event, NULL, manager_dirty_handler, m);
|
||||||
|
if (r < 0)
|
||||||
|
@@ -1078,3 +1085,34 @@ int manager_set_timezone(Manager *m, const char *tz) {
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
+
|
||||||
|
+int manager_reload(Manager *m) {
|
||||||
|
+ Link *link;
|
||||||
|
+ int r;
|
||||||
|
+
|
||||||
|
+ assert(m);
|
||||||
|
+
|
||||||
|
+ (void) sd_notifyf(/* unset= */ false,
|
||||||
|
+ "RELOADING=1\n"
|
||||||
|
+ "STATUS=Reloading configuration...\n"
|
||||||
|
+ "MONOTONIC_USEC=" USEC_FMT, now(CLOCK_MONOTONIC));
|
||||||
|
+
|
||||||
|
+ r = netdev_load(m, /* reload= */ true);
|
||||||
|
+ if (r < 0)
|
||||||
|
+ goto finish;
|
||||||
|
+
|
||||||
|
+ r = network_reload(m);
|
||||||
|
+ if (r < 0)
|
||||||
|
+ goto finish;
|
||||||
|
+
|
||||||
|
+ HASHMAP_FOREACH(link, m->links_by_index) {
|
||||||
|
+ r = link_reconfigure(link, /* force = */ false);
|
||||||
|
+ if (r < 0)
|
||||||
|
+ goto finish;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ r = 0;
|
||||||
|
+finish:
|
||||||
|
+ (void) sd_notify(/* unset= */ false, NOTIFY_READY);
|
||||||
|
+ return r;
|
||||||
|
+}
|
||||||
|
diff --git a/src/network/networkd-manager.h b/src/network/networkd-manager.h
|
||||||
|
index 40e6092f85..e6183af0e4 100644
|
||||||
|
--- a/src/network/networkd-manager.h
|
||||||
|
+++ b/src/network/networkd-manager.h
|
||||||
|
@@ -115,4 +115,6 @@ int manager_enumerate(Manager *m);
|
||||||
|
int manager_set_hostname(Manager *m, const char *hostname);
|
||||||
|
int manager_set_timezone(Manager *m, const char *timezone);
|
||||||
|
|
||||||
|
+int manager_reload(Manager *m);
|
||||||
|
+
|
||||||
|
DEFINE_TRIVIAL_CLEANUP_FUNC(Manager*, manager_free);
|
||||||
|
diff --git a/src/network/networkd.c b/src/network/networkd.c
|
||||||
|
index d61769d9f3..68760e8ff4 100644
|
||||||
|
--- a/src/network/networkd.c
|
||||||
|
+++ b/src/network/networkd.c
|
||||||
|
@@ -81,8 +81,6 @@ static int run(int argc, char *argv[]) {
|
||||||
|
if (r < 0)
|
||||||
|
log_warning_errno(r, "Could not create runtime directory 'lldp': %m");
|
||||||
|
|
||||||
|
- assert_se(sigprocmask_many(SIG_BLOCK, NULL, SIGTERM, SIGINT, -1) >= 0);
|
||||||
|
-
|
||||||
|
r = manager_new(&m, /* test_mode = */ false);
|
||||||
|
if (r < 0)
|
||||||
|
return log_error_errno(r, "Could not create manager: %m");
|
||||||
|
diff --git a/units/systemd-networkd.service.in b/units/systemd-networkd.service.in
|
||||||
|
index d15129e7f0..d8b935a358 100644
|
||||||
|
--- a/units/systemd-networkd.service.in
|
||||||
|
+++ b/units/systemd-networkd.service.in
|
||||||
|
@@ -24,7 +24,6 @@ BusName=org.freedesktop.network1
|
||||||
|
CapabilityBoundingSet=CAP_NET_ADMIN CAP_NET_BIND_SERVICE CAP_NET_BROADCAST CAP_NET_RAW
|
||||||
|
DeviceAllow=char-* rw
|
||||||
|
ExecStart=!!{{ROOTLIBEXECDIR}}/systemd-networkd
|
||||||
|
-ExecReload=networkctl reload
|
||||||
|
FileDescriptorStoreMax=512
|
||||||
|
LockPersonality=yes
|
||||||
|
MemoryDenyWriteExecute=yes
|
||||||
|
@@ -48,7 +47,7 @@ RuntimeDirectoryPreserve=yes
|
||||||
|
SystemCallArchitectures=native
|
||||||
|
SystemCallErrorNumber=EPERM
|
||||||
|
SystemCallFilter=@system-service
|
||||||
|
-Type=notify
|
||||||
|
+Type=notify-reload
|
||||||
|
User=systemd-network
|
||||||
|
{{SERVICE_WATCHDOG}}
|
||||||
|
|
@ -0,0 +1,127 @@
|
|||||||
|
From daa0a0268e9ed03b8e3c39f003266d0b14cae120 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Lennart Poettering <lennart@poettering.net>
|
||||||
|
Date: Mon, 2 Jan 2023 17:21:16 +0100
|
||||||
|
Subject: [PATCH] udevd: implement the full Type=notify-reload protocol
|
||||||
|
|
||||||
|
We are basically already there, just need to add MONOTONIC_USEC= to the
|
||||||
|
RELOADING=1 message, and make sure the message is generated in really
|
||||||
|
all cases.
|
||||||
|
|
||||||
|
(cherry picked from commit f84331539deae28fbeb42d45ad0c8d583b3372a3)
|
||||||
|
|
||||||
|
Related: RHEL-6090
|
||||||
|
---
|
||||||
|
src/udev/udevd.c | 47 +++++++++++++++++++---------------
|
||||||
|
units/systemd-udevd.service.in | 3 +--
|
||||||
|
2 files changed, 28 insertions(+), 22 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/src/udev/udevd.c b/src/udev/udevd.c
|
||||||
|
index ccc3c0eece..6d82a6eff2 100644
|
||||||
|
--- a/src/udev/udevd.c
|
||||||
|
+++ b/src/udev/udevd.c
|
||||||
|
@@ -32,6 +32,7 @@
|
||||||
|
#include "cgroup-setup.h"
|
||||||
|
#include "cgroup-util.h"
|
||||||
|
#include "cpu-set-util.h"
|
||||||
|
+#include "daemon-util.h"
|
||||||
|
#include "dev-setup.h"
|
||||||
|
#include "device-monitor-private.h"
|
||||||
|
#include "device-private.h"
|
||||||
|
@@ -331,9 +332,7 @@ static void manager_exit(Manager *manager) {
|
||||||
|
|
||||||
|
manager->exit = true;
|
||||||
|
|
||||||
|
- sd_notify(false,
|
||||||
|
- "STOPPING=1\n"
|
||||||
|
- "STATUS=Starting shutdown...");
|
||||||
|
+ (void) sd_notify(/* unset= */ false, NOTIFY_STOPPING);
|
||||||
|
|
||||||
|
/* close sources of new events and discard buffered events */
|
||||||
|
manager->ctrl = udev_ctrl_unref(manager->ctrl);
|
||||||
|
@@ -351,7 +350,7 @@ static void manager_exit(Manager *manager) {
|
||||||
|
static void notify_ready(void) {
|
||||||
|
int r;
|
||||||
|
|
||||||
|
- r = sd_notifyf(false,
|
||||||
|
+ r = sd_notifyf(/* unset= */ false,
|
||||||
|
"READY=1\n"
|
||||||
|
"STATUS=Processing with %u children at max", arg_children_max);
|
||||||
|
if (r < 0)
|
||||||
|
@@ -376,23 +375,33 @@ static void manager_reload(Manager *manager, bool force) {
|
||||||
|
mac_selinux_maybe_reload();
|
||||||
|
|
||||||
|
/* Nothing changed. It is not necessary to reload. */
|
||||||
|
- if (!udev_rules_should_reload(manager->rules) && !udev_builtin_should_reload())
|
||||||
|
- return;
|
||||||
|
+ if (!udev_rules_should_reload(manager->rules) && !udev_builtin_should_reload()) {
|
||||||
|
|
||||||
|
- sd_notify(false,
|
||||||
|
- "RELOADING=1\n"
|
||||||
|
- "STATUS=Flushing configuration...");
|
||||||
|
+ if (!force)
|
||||||
|
+ return;
|
||||||
|
|
||||||
|
- manager_kill_workers(manager, false);
|
||||||
|
+ /* If we eat this up, then tell our service manager to just continue */
|
||||||
|
+ (void) sd_notifyf(/* unset= */ false,
|
||||||
|
+ "RELOADING=1\n"
|
||||||
|
+ "STATUS=Skipping configuration reloading, nothing changed.\n"
|
||||||
|
+ "MONOTONIC_USEC=" USEC_FMT, now(CLOCK_MONOTONIC));
|
||||||
|
+ } else {
|
||||||
|
+ (void) sd_notifyf(/* unset= */ false,
|
||||||
|
+ "RELOADING=1\n"
|
||||||
|
+ "STATUS=Flushing configuration...\n"
|
||||||
|
+ "MONOTONIC_USEC=" USEC_FMT, now(CLOCK_MONOTONIC));
|
||||||
|
|
||||||
|
- udev_builtin_exit();
|
||||||
|
- udev_builtin_init();
|
||||||
|
+ manager_kill_workers(manager, false);
|
||||||
|
|
||||||
|
- r = udev_rules_load(&rules, arg_resolve_name_timing);
|
||||||
|
- if (r < 0)
|
||||||
|
- log_warning_errno(r, "Failed to read udev rules, using the previously loaded rules, ignoring: %m");
|
||||||
|
- else
|
||||||
|
- udev_rules_free_and_replace(manager->rules, rules);
|
||||||
|
+ udev_builtin_exit();
|
||||||
|
+ udev_builtin_init();
|
||||||
|
+
|
||||||
|
+ r = udev_rules_load(&rules, arg_resolve_name_timing);
|
||||||
|
+ if (r < 0)
|
||||||
|
+ log_warning_errno(r, "Failed to read udev rules, using the previously loaded rules, ignoring: %m");
|
||||||
|
+ else
|
||||||
|
+ udev_rules_free_and_replace(manager->rules, rules);
|
||||||
|
+ }
|
||||||
|
|
||||||
|
notify_ready();
|
||||||
|
}
|
||||||
|
@@ -1982,9 +1991,7 @@ static int main_loop(Manager *manager) {
|
||||||
|
if (r < 0)
|
||||||
|
log_error_errno(r, "Event loop failed: %m");
|
||||||
|
|
||||||
|
- sd_notify(false,
|
||||||
|
- "STOPPING=1\n"
|
||||||
|
- "STATUS=Shutting down...");
|
||||||
|
+ (void) sd_notify(/* unset= */ false, NOTIFY_STOPPING);
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
diff --git a/units/systemd-udevd.service.in b/units/systemd-udevd.service.in
|
||||||
|
index e9dbe85ef4..dfc2a0e341 100644
|
||||||
|
--- a/units/systemd-udevd.service.in
|
||||||
|
+++ b/units/systemd-udevd.service.in
|
||||||
|
@@ -18,14 +18,13 @@ ConditionPathIsReadWrite=/sys
|
||||||
|
[Service]
|
||||||
|
CapabilityBoundingSet=~CAP_SYS_TIME CAP_WAKE_ALARM
|
||||||
|
Delegate=pids
|
||||||
|
-Type=notify
|
||||||
|
+Type=notify-reload
|
||||||
|
# Note that udev will reset the value internally for its workers
|
||||||
|
OOMScoreAdjust=-1000
|
||||||
|
Sockets=systemd-udevd-control.socket systemd-udevd-kernel.socket
|
||||||
|
Restart=always
|
||||||
|
RestartSec=0
|
||||||
|
ExecStart={{ROOTLIBEXECDIR}}/systemd-udevd
|
||||||
|
-ExecReload=udevadm control --reload --timeout 0
|
||||||
|
KillMode=mixed
|
||||||
|
TasksMax=infinity
|
||||||
|
PrivateMounts=yes
|
@ -0,0 +1,52 @@
|
|||||||
|
From dd9aa5ffe940ac6d5204a04fce5faafc3fc01924 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Lennart Poettering <lennart@poettering.net>
|
||||||
|
Date: Mon, 2 Jan 2023 17:35:23 +0100
|
||||||
|
Subject: [PATCH] logind: implement Type=notify-reload protocol properly
|
||||||
|
|
||||||
|
So close already. Let's add the two missing notifications too.
|
||||||
|
|
||||||
|
Fixes: #18484
|
||||||
|
(cherry picked from commit 5d71e463f49518c7702467f6145484afa31bf8ba)
|
||||||
|
|
||||||
|
Related: RHEL-6090
|
||||||
|
---
|
||||||
|
src/login/logind.c | 6 ++++++
|
||||||
|
units/systemd-logind.service.in | 1 +
|
||||||
|
2 files changed, 7 insertions(+)
|
||||||
|
|
||||||
|
diff --git a/src/login/logind.c b/src/login/logind.c
|
||||||
|
index cdca5ca58c..0348b19c05 100644
|
||||||
|
--- a/src/login/logind.c
|
||||||
|
+++ b/src/login/logind.c
|
||||||
|
@@ -1014,6 +1014,11 @@ static int manager_dispatch_reload_signal(sd_event_source *s, const struct signa
|
||||||
|
Manager *m = userdata;
|
||||||
|
int r;
|
||||||
|
|
||||||
|
+ (void) sd_notifyf(/* unset= */ false,
|
||||||
|
+ "RELOADING=1\n"
|
||||||
|
+ "STATUS=Reloading configuration...\n"
|
||||||
|
+ "MONOTONIC_USEC=" USEC_FMT, now(CLOCK_MONOTONIC));
|
||||||
|
+
|
||||||
|
manager_reset_config(m);
|
||||||
|
r = manager_parse_config_file(m);
|
||||||
|
if (r < 0)
|
||||||
|
@@ -1021,6 +1026,7 @@ static int manager_dispatch_reload_signal(sd_event_source *s, const struct signa
|
||||||
|
else
|
||||||
|
log_info("Config file reloaded.");
|
||||||
|
|
||||||
|
+ (void) sd_notify(/* unset= */ false, NOTIFY_READY);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
diff --git a/units/systemd-logind.service.in b/units/systemd-logind.service.in
|
||||||
|
index 042ea75d7a..24f5ddaa17 100644
|
||||||
|
--- a/units/systemd-logind.service.in
|
||||||
|
+++ b/units/systemd-logind.service.in
|
||||||
|
@@ -58,6 +58,7 @@ StateDirectory=systemd/linger
|
||||||
|
SystemCallArchitectures=native
|
||||||
|
SystemCallErrorNumber=EPERM
|
||||||
|
SystemCallFilter=@system-service
|
||||||
|
+Type=notify-reload
|
||||||
|
{{SERVICE_WATCHDOG}}
|
||||||
|
|
||||||
|
# Increase the default a bit in order to allow many simultaneous logins since
|
@ -0,0 +1,297 @@
|
|||||||
|
From 2b5c9fceaaa30ec9c2d031c9ca32b71c43f22f98 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Lennart Poettering <lennart@poettering.net>
|
||||||
|
Date: Tue, 3 Jan 2023 12:55:50 +0100
|
||||||
|
Subject: [PATCH] notify: add --stopping + --reloading switches
|
||||||
|
|
||||||
|
These wrap RELOADING=1 and STOPPING=1 messages. The former is
|
||||||
|
particularly useful, since we want to insert the MONOTONIC_USEC= field
|
||||||
|
into the message automatically, which is easy from C but harder from
|
||||||
|
shell.
|
||||||
|
|
||||||
|
(cherry picked from commit fd0f4da5457fbf7136f2d1888142d5fea75fd45a)
|
||||||
|
|
||||||
|
Related: RHEL-6090
|
||||||
|
---
|
||||||
|
man/systemd-notify.xml | 107 ++++++++++++++++++++++++-----------------
|
||||||
|
src/notify/notify.c | 39 +++++++++++++--
|
||||||
|
2 files changed, 97 insertions(+), 49 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/man/systemd-notify.xml b/man/systemd-notify.xml
|
||||||
|
index 1327d23155..a275123d40 100644
|
||||||
|
--- a/man/systemd-notify.xml
|
||||||
|
+++ b/man/systemd-notify.xml
|
||||||
|
@@ -30,34 +30,35 @@
|
||||||
|
<refsect1>
|
||||||
|
<title>Description</title>
|
||||||
|
|
||||||
|
- <para><command>systemd-notify</command> may be called by daemon
|
||||||
|
- scripts to notify the init system about status changes. It can be
|
||||||
|
- used to send arbitrary information, encoded in an
|
||||||
|
- environment-block-like list of strings. Most importantly, it can be
|
||||||
|
- used for start-up completion notification.</para>
|
||||||
|
-
|
||||||
|
- <para>This is mostly just a wrapper around
|
||||||
|
- <function>sd_notify()</function> and makes this functionality
|
||||||
|
+ <para><command>systemd-notify</command> may be called by service scripts to notify the invoking service
|
||||||
|
+ manager about status changes. It can be used to send arbitrary information, encoded in an
|
||||||
|
+ environment-block-like list of strings. Most importantly, it can be used for start-up completion
|
||||||
|
+ notification.</para>
|
||||||
|
+
|
||||||
|
+ <para>This is mostly just a wrapper around <function>sd_notify()</function> and makes this functionality
|
||||||
|
available to shell scripts. For details see
|
||||||
|
<citerefentry><refentrytitle>sd_notify</refentrytitle><manvolnum>3</manvolnum></citerefentry>.
|
||||||
|
</para>
|
||||||
|
|
||||||
|
- <para>The command line may carry a list of environment variables
|
||||||
|
- to send as part of the status update.</para>
|
||||||
|
+ <para>The command line may carry a list of environment variables to send as part of the status
|
||||||
|
+ update.</para>
|
||||||
|
|
||||||
|
<para>Note that systemd will refuse reception of status updates from this command unless
|
||||||
|
<varname>NotifyAccess=</varname> is set for the service unit this command is called from.</para>
|
||||||
|
|
||||||
|
- <para>Note that <function>sd_notify()</function> notifications may be attributed to units correctly only if either
|
||||||
|
- the sending process is still around at the time PID 1 processes the message, or if the sending process is
|
||||||
|
- explicitly runtime-tracked by the service manager. The latter is the case if the service manager originally forked
|
||||||
|
- off the process, i.e. on all processes that match <varname>NotifyAccess=</varname><option>main</option> or
|
||||||
|
- <varname>NotifyAccess=</varname><option>exec</option>. Conversely, if an auxiliary process of the unit sends an
|
||||||
|
- <function>sd_notify()</function> message and immediately exits, the service manager might not be able to properly
|
||||||
|
- attribute the message to the unit, and thus will ignore it, even if <varname>NotifyAccess=</varname><option>all
|
||||||
|
- </option> is set for it. When <option>--no-block</option> is used, all synchronization for reception of notifications
|
||||||
|
- is disabled, and hence the aforementioned race may occur if the invoking process is not the service manager or spawned
|
||||||
|
- by the service manager.</para>
|
||||||
|
+ <para>Note that <function>sd_notify()</function> notifications may be attributed to units correctly only
|
||||||
|
+ if either the sending process is still around at the time the service manager processes the message, or
|
||||||
|
+ if the sending process is explicitly runtime-tracked by the service manager. The latter is the case if
|
||||||
|
+ the service manager originally forked off the process, i.e. on all processes that match
|
||||||
|
+ <varname>NotifyAccess=</varname><option>main</option> or
|
||||||
|
+ <varname>NotifyAccess=</varname><option>exec</option>. Conversely, if an auxiliary process of the unit
|
||||||
|
+ sends an <function>sd_notify()</function> message and immediately exits, the service manager might not be
|
||||||
|
+ able to properly attribute the message to the unit, and thus will ignore it, even if
|
||||||
|
+ <varname>NotifyAccess=</varname><option>all</option> is set for it. To address this
|
||||||
|
+ <command>systemd-notify</command> will wait until the notification message has been processed by the
|
||||||
|
+ service manager. When <option>--no-block</option> is used, this synchronization for reception of
|
||||||
|
+ notifications is disabled, and hence the aforementioned race may occur if the invoking process is not the
|
||||||
|
+ service manager or spawned by the service manager.</para>
|
||||||
|
|
||||||
|
<para>Hence, <command>systemd-notify</command> will first attempt to invoke <function>sd_notify()</function>
|
||||||
|
pretending to have the PID of the invoking process. This will only succeed when invoked with sufficient privileges.
|
||||||
|
@@ -66,7 +67,6 @@
|
||||||
|
— appears as sender of the message, which in turn is helpful if the shell process is the main process of a service,
|
||||||
|
due to the limitations of <varname>NotifyAccess=</varname><option>all</option>. Use the <option>--pid=</option>
|
||||||
|
switch to tweak this behaviour.</para>
|
||||||
|
-
|
||||||
|
</refsect1>
|
||||||
|
|
||||||
|
<refsect1>
|
||||||
|
@@ -78,22 +78,42 @@
|
||||||
|
<varlistentry>
|
||||||
|
<term><option>--ready</option></term>
|
||||||
|
|
||||||
|
- <listitem><para>Inform the init system about service start-up
|
||||||
|
- completion. This is equivalent to <command>systemd-notify
|
||||||
|
- READY=1</command>. For details about the semantics of this
|
||||||
|
- option see
|
||||||
|
+ <listitem><para>Inform the invoking service manager about service start-up or configuration reload
|
||||||
|
+ completion. This is equivalent to <command>systemd-notify READY=1</command>. For details about the
|
||||||
|
+ semantics of this option see
|
||||||
|
+ <citerefentry><refentrytitle>sd_notify</refentrytitle><manvolnum>3</manvolnum></citerefentry>.</para></listitem>
|
||||||
|
+ </varlistentry>
|
||||||
|
+
|
||||||
|
+ <varlistentry>
|
||||||
|
+ <term><option>--reloading</option></term>
|
||||||
|
+
|
||||||
|
+ <listitem><para>Inform the invoking service manager about the beginning of a configuration reload
|
||||||
|
+ cycle. This is equivalent to <command>systemd-notify RELOADING=1</command> (but implicitly also sets
|
||||||
|
+ a <varname>MONOTONIC_USEC=</varname> field as required for <varname>Type=notify-reload</varname>
|
||||||
|
+ services, see
|
||||||
|
+ <citerefentry><refentrytitle>systemd.service</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
|
||||||
|
+ for details). For details about the semantics of this option see
|
||||||
|
+ <citerefentry><refentrytitle>sd_notify</refentrytitle><manvolnum>3</manvolnum></citerefentry>.</para></listitem>
|
||||||
|
+ </varlistentry>
|
||||||
|
+
|
||||||
|
+ <varlistentry>
|
||||||
|
+ <term><option>--stopping</option></term>
|
||||||
|
+
|
||||||
|
+ <listitem><para>Inform the invoking service manager about the beginning of the shutdown phase of the
|
||||||
|
+ service. This is equivalent to <command>systemd-notify STOPPING=1</command>. For details about the
|
||||||
|
+ semantics of this option see
|
||||||
|
<citerefentry><refentrytitle>sd_notify</refentrytitle><manvolnum>3</manvolnum></citerefentry>.</para></listitem>
|
||||||
|
</varlistentry>
|
||||||
|
|
||||||
|
<varlistentry>
|
||||||
|
<term><option>--pid=</option></term>
|
||||||
|
|
||||||
|
- <listitem><para>Inform the service manager about the main PID of the daemon. Takes a PID as
|
||||||
|
+ <listitem><para>Inform the service manager about the main PID of the service. Takes a PID as
|
||||||
|
argument. If the argument is specified as <literal>auto</literal> or omitted, the PID of the process
|
||||||
|
that invoked <command>systemd-notify</command> is used, except if that's the service manager. If the
|
||||||
|
argument is specified as <literal>self</literal>, the PID of the <command>systemd-notify</command>
|
||||||
|
command itself is used, and if <literal>parent</literal> is specified the calling process' PID is
|
||||||
|
- used — even if it is the service manager. This is equivalent to <command>systemd-notify
|
||||||
|
+ used — even if it is the service manager. The latter is equivalent to <command>systemd-notify
|
||||||
|
MAINPID=$PID</command>. For details about the semantics of this option see
|
||||||
|
<citerefentry><refentrytitle>sd_notify</refentrytitle><manvolnum>3</manvolnum></citerefentry>.</para></listitem>
|
||||||
|
</varlistentry>
|
||||||
|
@@ -110,27 +130,26 @@
|
||||||
|
<varlistentry>
|
||||||
|
<term><option>--status=</option></term>
|
||||||
|
|
||||||
|
- <listitem><para>Send a free-form status string for the daemon
|
||||||
|
- to the init systemd. This option takes the status string as
|
||||||
|
- argument. This is equivalent to <command>systemd-notify
|
||||||
|
- STATUS=…</command>. For details about the semantics of this
|
||||||
|
- option see
|
||||||
|
- <citerefentry><refentrytitle>sd_notify</refentrytitle><manvolnum>3</manvolnum></citerefentry>.</para></listitem>
|
||||||
|
+ <listitem><para>Send a free-form human readable status string for the daemon to the service
|
||||||
|
+ manager. This option takes the status string as argument. This is equivalent to
|
||||||
|
+ <command>systemd-notify STATUS=…</command>. For details about the semantics of this option see
|
||||||
|
+ <citerefentry><refentrytitle>sd_notify</refentrytitle><manvolnum>3</manvolnum></citerefentry>. This
|
||||||
|
+ information is shown in
|
||||||
|
+ <citerefentry><refentrytitle>systemctl</refentrytitle><manvolnum>1</manvolnum></citerefentry>'s
|
||||||
|
+ <command>status</command> output, among other places.</para></listitem>
|
||||||
|
</varlistentry>
|
||||||
|
|
||||||
|
<varlistentry>
|
||||||
|
<term><option>--booted</option></term>
|
||||||
|
|
||||||
|
- <listitem><para>Returns 0 if the system was booted up with
|
||||||
|
- systemd, non-zero otherwise. If this option is passed, no
|
||||||
|
- message is sent. This option is hence unrelated to the other
|
||||||
|
- options. For details about the semantics of this option, see
|
||||||
|
+ <listitem><para>Returns 0 if the system was booted up with systemd, non-zero otherwise. If this
|
||||||
|
+ option is passed, no message is sent. This option is hence unrelated to the other options. For
|
||||||
|
+ details about the semantics of this option, see
|
||||||
|
<citerefentry><refentrytitle>sd_booted</refentrytitle><manvolnum>3</manvolnum></citerefentry>. An
|
||||||
|
alternate way to check for this state is to call
|
||||||
|
- <citerefentry><refentrytitle>systemctl</refentrytitle><manvolnum>1</manvolnum></citerefentry>
|
||||||
|
- with the <command>is-system-running</command> command. It will
|
||||||
|
- return <literal>offline</literal> if the system was not booted
|
||||||
|
- with systemd. </para></listitem>
|
||||||
|
+ <citerefentry><refentrytitle>systemctl</refentrytitle><manvolnum>1</manvolnum></citerefentry> with
|
||||||
|
+ the <command>is-system-running</command> command. It will return <literal>offline</literal> if the
|
||||||
|
+ system was not booted with systemd. </para></listitem>
|
||||||
|
</varlistentry>
|
||||||
|
|
||||||
|
<varlistentry>
|
||||||
|
@@ -162,9 +181,8 @@
|
||||||
|
<example>
|
||||||
|
<title>Start-up Notification and Status Updates</title>
|
||||||
|
|
||||||
|
- <para>A simple shell daemon that sends start-up notifications
|
||||||
|
- after having set up its communication channel. During runtime it
|
||||||
|
- sends further status updates to the init system:</para>
|
||||||
|
+ <para>A simple shell daemon that sends start-up notifications after having set up its communication
|
||||||
|
+ channel. During runtime it sends further status updates to the init system:</para>
|
||||||
|
|
||||||
|
<programlisting>#!/bin/sh
|
||||||
|
|
||||||
|
@@ -192,5 +210,4 @@ done</programlisting>
|
||||||
|
<citerefentry><refentrytitle>sd_booted</refentrytitle><manvolnum>3</manvolnum></citerefentry>
|
||||||
|
</para>
|
||||||
|
</refsect1>
|
||||||
|
-
|
||||||
|
</refentry>
|
||||||
|
diff --git a/src/notify/notify.c b/src/notify/notify.c
|
||||||
|
index 7b23e7bdb0..2d4900a110 100644
|
||||||
|
--- a/src/notify/notify.c
|
||||||
|
+++ b/src/notify/notify.c
|
||||||
|
@@ -23,6 +23,8 @@
|
||||||
|
#include "util.h"
|
||||||
|
|
||||||
|
static bool arg_ready = false;
|
||||||
|
+static bool arg_reloading = false;
|
||||||
|
+static bool arg_stopping = false;
|
||||||
|
static pid_t arg_pid = 0;
|
||||||
|
static const char *arg_status = NULL;
|
||||||
|
static bool arg_booted = false;
|
||||||
|
@@ -42,7 +44,10 @@ static int help(void) {
|
||||||
|
"\n%sNotify the init system about service status updates.%s\n\n"
|
||||||
|
" -h --help Show this help\n"
|
||||||
|
" --version Show package version\n"
|
||||||
|
- " --ready Inform the init system about service start-up completion\n"
|
||||||
|
+ " --ready Inform the service manager about service start-up/reload\n"
|
||||||
|
+ " completion\n"
|
||||||
|
+ " --reloading Inform the service manager about configuration reloading\n"
|
||||||
|
+ " --stopping Inform the service manager about service shutdown\n"
|
||||||
|
" --pid[=PID] Set main PID of daemon\n"
|
||||||
|
" --uid=USER Set user to send from\n"
|
||||||
|
" --status=TEXT Set status text\n"
|
||||||
|
@@ -81,6 +86,8 @@ static int parse_argv(int argc, char *argv[]) {
|
||||||
|
|
||||||
|
enum {
|
||||||
|
ARG_READY = 0x100,
|
||||||
|
+ ARG_RELOADING,
|
||||||
|
+ ARG_STOPPING,
|
||||||
|
ARG_VERSION,
|
||||||
|
ARG_PID,
|
||||||
|
ARG_STATUS,
|
||||||
|
@@ -93,6 +100,8 @@ static int parse_argv(int argc, char *argv[]) {
|
||||||
|
{ "help", no_argument, NULL, 'h' },
|
||||||
|
{ "version", no_argument, NULL, ARG_VERSION },
|
||||||
|
{ "ready", no_argument, NULL, ARG_READY },
|
||||||
|
+ { "reloading", no_argument, NULL, ARG_RELOADING },
|
||||||
|
+ { "stopping", no_argument, NULL, ARG_STOPPING },
|
||||||
|
{ "pid", optional_argument, NULL, ARG_PID },
|
||||||
|
{ "status", required_argument, NULL, ARG_STATUS },
|
||||||
|
{ "booted", no_argument, NULL, ARG_BOOTED },
|
||||||
|
@@ -120,6 +129,14 @@ static int parse_argv(int argc, char *argv[]) {
|
||||||
|
arg_ready = true;
|
||||||
|
break;
|
||||||
|
|
||||||
|
+ case ARG_RELOADING:
|
||||||
|
+ arg_reloading = true;
|
||||||
|
+ break;
|
||||||
|
+
|
||||||
|
+ case ARG_STOPPING:
|
||||||
|
+ arg_stopping = true;
|
||||||
|
+ break;
|
||||||
|
+
|
||||||
|
case ARG_PID:
|
||||||
|
if (isempty(optarg) || streq(optarg, "auto")) {
|
||||||
|
arg_pid = getppid();
|
||||||
|
@@ -176,6 +193,8 @@ static int parse_argv(int argc, char *argv[]) {
|
||||||
|
|
||||||
|
if (optind >= argc &&
|
||||||
|
!arg_ready &&
|
||||||
|
+ !arg_stopping &&
|
||||||
|
+ !arg_reloading &&
|
||||||
|
!arg_status &&
|
||||||
|
!arg_pid &&
|
||||||
|
!arg_booted) {
|
||||||
|
@@ -187,10 +206,10 @@ static int parse_argv(int argc, char *argv[]) {
|
||||||
|
}
|
||||||
|
|
||||||
|
static int run(int argc, char* argv[]) {
|
||||||
|
- _cleanup_free_ char *status = NULL, *cpid = NULL, *n = NULL;
|
||||||
|
+ _cleanup_free_ char *status = NULL, *cpid = NULL, *n = NULL, *monotonic_usec = NULL;
|
||||||
|
_cleanup_strv_free_ char **final_env = NULL;
|
||||||
|
- char* our_env[4];
|
||||||
|
- unsigned i = 0;
|
||||||
|
+ char* our_env[7];
|
||||||
|
+ size_t i = 0;
|
||||||
|
pid_t source_pid;
|
||||||
|
int r;
|
||||||
|
|
||||||
|
@@ -212,9 +231,21 @@ static int run(int argc, char* argv[]) {
|
||||||
|
return r <= 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
+ if (arg_reloading) {
|
||||||
|
+ our_env[i++] = (char*) "RELOADING=1";
|
||||||
|
+
|
||||||
|
+ if (asprintf(&monotonic_usec, "MONOTONIC_USEC=" USEC_FMT, now(CLOCK_MONOTONIC)) < 0)
|
||||||
|
+ return log_oom();
|
||||||
|
+
|
||||||
|
+ our_env[i++] = monotonic_usec;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
if (arg_ready)
|
||||||
|
our_env[i++] = (char*) "READY=1";
|
||||||
|
|
||||||
|
+ if (arg_stopping)
|
||||||
|
+ our_env[i++] = (char*) "STOPPING=1";
|
||||||
|
+
|
||||||
|
if (arg_status) {
|
||||||
|
status = strjoin("STATUS=", arg_status);
|
||||||
|
if (!status)
|
@ -0,0 +1,74 @@
|
|||||||
|
From 3a2cb37fdbe4e761ae649716f6f8f71feffdd608 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Lennart Poettering <lennart@poettering.net>
|
||||||
|
Date: Tue, 3 Jan 2023 12:56:53 +0100
|
||||||
|
Subject: [PATCH] test: add Type=notify-reload testcase
|
||||||
|
|
||||||
|
(cherry picked from commit ee52bbc68f129cfed833990906c0a0a77ee12c42)
|
||||||
|
|
||||||
|
Related: RHEL-6090
|
||||||
|
---
|
||||||
|
test/units/testsuite-59.sh | 51 ++++++++++++++++++++++++++++++++++++++
|
||||||
|
1 file changed, 51 insertions(+)
|
||||||
|
|
||||||
|
diff --git a/test/units/testsuite-59.sh b/test/units/testsuite-59.sh
|
||||||
|
index 83db053107..475766a851 100755
|
||||||
|
--- a/test/units/testsuite-59.sh
|
||||||
|
+++ b/test/units/testsuite-59.sh
|
||||||
|
@@ -83,6 +83,57 @@ systemctl start testservice-abort-restart-59.service
|
||||||
|
systemctl --signal=SIGABRT kill testservice-abort-restart-59.service
|
||||||
|
wait_on_state_or_fail "testservice-abort-restart-59.service" "failed" "30"
|
||||||
|
|
||||||
|
+# Let's now test the notify-reload logic
|
||||||
|
+
|
||||||
|
+cat >/run/notify-reload-test.sh <<EOF
|
||||||
|
+#!/usr/bin/env bash
|
||||||
|
+set -eux
|
||||||
|
+set -o pipefail
|
||||||
|
+
|
||||||
|
+EXIT_STATUS=88
|
||||||
|
+LEAVE=0
|
||||||
|
+
|
||||||
|
+function reload() {
|
||||||
|
+ systemd-notify --reloading --status="Adding 11 to exit status"
|
||||||
|
+ EXIT_STATUS=\$((\$EXIT_STATUS + 11))
|
||||||
|
+ systemd-notify --ready --status="Back running"
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+function leave() {
|
||||||
|
+ systemd-notify --stopping --status="Adding 7 to exit status"
|
||||||
|
+ EXIT_STATUS=\$((\$EXIT_STATUS + 7))
|
||||||
|
+ LEAVE=1
|
||||||
|
+ return 0
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+trap reload SIGHUP
|
||||||
|
+trap leave SIGTERM
|
||||||
|
+
|
||||||
|
+systemd-notify --ready
|
||||||
|
+systemd-notify --status="Running now"
|
||||||
|
+
|
||||||
|
+while [ \$LEAVE = 0 ] ; do
|
||||||
|
+ sleep 1
|
||||||
|
+done
|
||||||
|
+
|
||||||
|
+systemd-notify --status="Adding 3 to exit status"
|
||||||
|
+EXIT_STATUS=\$((\$EXIT_STATUS + 3))
|
||||||
|
+exit \$EXIT_STATUS
|
||||||
|
+EOF
|
||||||
|
+
|
||||||
|
+chmod +x /run/notify-reload-test.sh
|
||||||
|
+
|
||||||
|
+systemd-analyze log-level debug
|
||||||
|
+
|
||||||
|
+systemd-run --unit notify-reload-test -p Type=notify-reload -p KillMode=process /run/notify-reload-test.sh
|
||||||
|
+systemctl reload notify-reload-test
|
||||||
|
+systemctl stop notify-reload-test
|
||||||
|
+
|
||||||
|
+test "$(systemctl show -p ExecMainStatus --value notify-reload-test)" = 109
|
||||||
|
+
|
||||||
|
+systemctl reset-failed notify-reload-test
|
||||||
|
+rm /run/notify-reload-test.sh
|
||||||
|
+
|
||||||
|
systemd-analyze log-level info
|
||||||
|
|
||||||
|
echo OK >/testok
|
@ -0,0 +1,45 @@
|
|||||||
|
From 3fa498dba2e67c1c97f25b093ec6c36e55023259 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Lennart Poettering <lennart@poettering.net>
|
||||||
|
Date: Mon, 2 Jan 2023 16:48:51 +0100
|
||||||
|
Subject: [PATCH] update TODO
|
||||||
|
|
||||||
|
(cherry picked from commit 6fee784964b2763bd4307181335a433078ba977c)
|
||||||
|
|
||||||
|
Related: RHEL-6090
|
||||||
|
---
|
||||||
|
TODO | 15 +++------------
|
||||||
|
1 file changed, 3 insertions(+), 12 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/TODO b/TODO
|
||||||
|
index 66c008bff3..8c67f93f35 100644
|
||||||
|
--- a/TODO
|
||||||
|
+++ b/TODO
|
||||||
|
@@ -700,17 +700,9 @@ Features:
|
||||||
|
and synthesize initrd from it, and measure it. Signing is not necessary, as
|
||||||
|
microcode does that on its own. Pass as first initrd to kernel.
|
||||||
|
|
||||||
|
-* Add a new service type very similar to Type=notify, that goes one step
|
||||||
|
- further and extends the protocol to cover reloads. Specifically, SIGHUP will
|
||||||
|
- become the official way to reload, and daemon has to respond with sd_notify()
|
||||||
|
- to report when it starts reloading, and when it is complete reloading. Care
|
||||||
|
- must be taken to remove races from this model. I.e. PID 1 needs to take
|
||||||
|
- CLOCK_MONOTONIC, then send SIGHUP, then wait for at least one RELOADING=1
|
||||||
|
- message that comes with a newer timestamp, then wait for a READY=1 message.
|
||||||
|
- while we are at it, also maybe extend the logic to require handling of some
|
||||||
|
- specific SIGRT signal for setting debug log level, that carries the level via
|
||||||
|
- the sigqueue() data parameter. With that we extended with minimal logic the
|
||||||
|
- service runtime logic quite substantially.
|
||||||
|
+* Maybe extend the service protocol to support handling of some specific SIGRT
|
||||||
|
+ signal for setting service log level, that carries the level via the
|
||||||
|
+ sigqueue() data parameter. Enable this via unit file setting.
|
||||||
|
|
||||||
|
* firstboot: maybe just default to C.UTF-8 locale if nothing is set, so that we
|
||||||
|
don't query this unnecessarily in entirely uninitialized
|
||||||
|
@@ -1738,7 +1730,6 @@ Features:
|
||||||
|
* unit files:
|
||||||
|
- allow port=0 in .socket units
|
||||||
|
- maybe introduce ExecRestartPre=
|
||||||
|
- - add ReloadSignal= for configuring a reload signal to use
|
||||||
|
- implement Register= switch in .socket units to enable registration
|
||||||
|
in Avahi, RPC and other socket registration services.
|
||||||
|
- allow Type=simple with PIDFile=
|
@ -0,0 +1,40 @@
|
|||||||
|
From 036f0593b33ddc0f40a333d790a276c3cffe862e Mon Sep 17 00:00:00 2001
|
||||||
|
From: msizanoen1 <msizanoen@qtmlabs.xyz>
|
||||||
|
Date: Tue, 2 May 2023 16:59:07 +0700
|
||||||
|
Subject: [PATCH] core: check for SERVICE_RELOAD_NOTIFY in
|
||||||
|
manager_dbus_is_running
|
||||||
|
|
||||||
|
This ensures that systemd won't erronously disconnect from the system
|
||||||
|
bus in case a bus recheck is triggered immediately after the bus service
|
||||||
|
emits `RELOADING=1`.
|
||||||
|
|
||||||
|
This fixes an issue where systemd-logind sometimes randomly stops
|
||||||
|
receiving `UnitRemoved` after a system update.
|
||||||
|
|
||||||
|
This also handles SERVICE_RELOAD_SIGNAL just in case somebody ever
|
||||||
|
creates a D-Bus broker implementation that uses `Type=notify-reload`.
|
||||||
|
|
||||||
|
(cherry picked from commit 845824acddf2e7e08c94afe7cfee6e50a682c947)
|
||||||
|
|
||||||
|
Related: RHEL-6090
|
||||||
|
---
|
||||||
|
src/core/manager.c | 6 +++++-
|
||||||
|
1 file changed, 5 insertions(+), 1 deletion(-)
|
||||||
|
|
||||||
|
diff --git a/src/core/manager.c b/src/core/manager.c
|
||||||
|
index b34103d7d3..eeee395b90 100644
|
||||||
|
--- a/src/core/manager.c
|
||||||
|
+++ b/src/core/manager.c
|
||||||
|
@@ -1696,7 +1696,11 @@ static bool manager_dbus_is_running(Manager *m, bool deserialized) {
|
||||||
|
u = manager_get_unit(m, SPECIAL_DBUS_SERVICE);
|
||||||
|
if (!u)
|
||||||
|
return false;
|
||||||
|
- if (!IN_SET((deserialized ? SERVICE(u)->deserialized_state : SERVICE(u)->state), SERVICE_RUNNING, SERVICE_RELOAD))
|
||||||
|
+ if (!IN_SET((deserialized ? SERVICE(u)->deserialized_state : SERVICE(u)->state),
|
||||||
|
+ SERVICE_RUNNING,
|
||||||
|
+ SERVICE_RELOAD,
|
||||||
|
+ SERVICE_RELOAD_NOTIFY,
|
||||||
|
+ SERVICE_RELOAD_SIGNAL))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return true;
|
@ -0,0 +1,37 @@
|
|||||||
|
From 4b2fb9adb3cd46cf6fe9b7e093d3f513a44f8e14 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Frantisek Sumsal <fsumsal@redhat.com>
|
||||||
|
Date: Thu, 14 Dec 2023 10:54:38 +0100
|
||||||
|
Subject: [PATCH] Revert "man: mention System Administrator's Guide in
|
||||||
|
systemctl manpage"
|
||||||
|
|
||||||
|
This reverts commit 5b2c931fb85d79db5a369a46eaeaf4ba297cbeef.
|
||||||
|
|
||||||
|
Related: RHEL-19436
|
||||||
|
|
||||||
|
rhel-only
|
||||||
|
---
|
||||||
|
man/systemctl.xml | 11 -----------
|
||||||
|
1 file changed, 11 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/man/systemctl.xml b/man/systemctl.xml
|
||||||
|
index b73d4ac048..55310c974e 100644
|
||||||
|
--- a/man/systemctl.xml
|
||||||
|
+++ b/man/systemctl.xml
|
||||||
|
@@ -2518,17 +2518,6 @@ Jan 12 10:46:45 example.com bluetoothd[8900]: gatt-time-server: Input/output err
|
||||||
|
<xi:include href="common-variables.xml" xpointer="urlify"/>
|
||||||
|
</refsect1>
|
||||||
|
|
||||||
|
- <refsect1>
|
||||||
|
- <title>Examples</title>
|
||||||
|
- <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/9/html/configuring_basic_system_settings/managing-system-services-with-systemctl_configuring-basic-system-settings">
|
||||||
|
- Managing System Services
|
||||||
|
- </ulink>
|
||||||
|
- </para>
|
||||||
|
- </refsect1>
|
||||||
|
-
|
||||||
|
<refsect1>
|
||||||
|
<title>See Also</title>
|
||||||
|
<para>
|
@ -0,0 +1,33 @@
|
|||||||
|
From 024e4e1989e8e1a8d67429ab7f36dcca5734f81b Mon Sep 17 00:00:00 2001
|
||||||
|
From: Frantisek Sumsal <fsumsal@redhat.com>
|
||||||
|
Date: Thu, 14 Dec 2023 10:56:51 +0100
|
||||||
|
Subject: [PATCH] man: mention RHEL documentation in systemctl's man page
|
||||||
|
|
||||||
|
Resolves: RHEL-19436
|
||||||
|
|
||||||
|
rhel-only
|
||||||
|
---
|
||||||
|
man/systemctl.xml | 10 ++++++++++
|
||||||
|
1 file changed, 10 insertions(+)
|
||||||
|
|
||||||
|
diff --git a/man/systemctl.xml b/man/systemctl.xml
|
||||||
|
index 55310c974e..1df0b158bd 100644
|
||||||
|
--- a/man/systemctl.xml
|
||||||
|
+++ b/man/systemctl.xml
|
||||||
|
@@ -2518,6 +2518,16 @@ Jan 12 10:46:45 example.com bluetoothd[8900]: gatt-time-server: Input/output err
|
||||||
|
<xi:include href="common-variables.xml" xpointer="urlify"/>
|
||||||
|
</refsect1>
|
||||||
|
|
||||||
|
+ <refsect1>
|
||||||
|
+ <title>Examples</title>
|
||||||
|
+ <para>
|
||||||
|
+ For examples how to use systemctl in comparison with old service and chkconfig commands please see:
|
||||||
|
+ <ulink url="https://access.redhat.com/documentation/en-us/red_hat_enterprise_linux/9/html/configuring_basic_system_settings/managing-systemd_configuring-basic-system-settings#managing-system-services-with-systemctl_managing-systemd">
|
||||||
|
+ Managing System Services
|
||||||
|
+ </ulink>
|
||||||
|
+ </para>
|
||||||
|
+ </refsect1>
|
||||||
|
+
|
||||||
|
<refsect1>
|
||||||
|
<title>See Also</title>
|
||||||
|
<para>
|
@ -0,0 +1,37 @@
|
|||||||
|
From 92ca40483db514bac34d8cd29438f48a794fae91 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-6216
|
||||||
|
---
|
||||||
|
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 0212569fb0..0306af84a2 100644
|
||||||
|
--- a/src/resolve/resolved-dns-transaction.c
|
||||||
|
+++ b/src/resolve/resolved-dns-transaction.c
|
||||||
|
@@ -2800,7 +2800,7 @@ static int dns_transaction_requires_rrsig(DnsTransaction *t, DnsResourceRecord *
|
||||||
|
if (r == 0)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
- return FLAGS_SET(t->answer_query_flags, SD_RESOLVED_AUTHENTICATED);
|
||||||
|
+ return FLAGS_SET(dt->answer_query_flags, SD_RESOLVED_AUTHENTICATED);
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
@@ -2827,7 +2827,7 @@ static int dns_transaction_requires_rrsig(DnsTransaction *t, DnsResourceRecord *
|
||||||
|
/* We found the transaction that was supposed to find the SOA RR for us. It was
|
||||||
|
* successful, but found no 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 FLAGS_SET(t->answer_query_flags, SD_RESOLVED_AUTHENTICATED);
|
||||||
|
+ return FLAGS_SET(dt->answer_query_flags, SD_RESOLVED_AUTHENTICATED);
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
@ -0,0 +1,404 @@
|
|||||||
|
From 9cd7868bc7cb5bda25c0470a9b4e349d4f2004fe Mon Sep 17 00:00:00 2001
|
||||||
|
From: Lukas Nykryn <lnykryn@redhat.com>
|
||||||
|
Date: Fri, 8 Dec 2023 12:33:06 +0100
|
||||||
|
Subject: [PATCH] udev: allow/denylist for reading sysfs attributes when
|
||||||
|
composing a NIC name
|
||||||
|
|
||||||
|
Users can currently pick specific versions of NIC naming, but that
|
||||||
|
does not guarantee that NIC names won't change after the kernel adds
|
||||||
|
a new sysfs attribute.
|
||||||
|
|
||||||
|
This patch allows for an allow/deny list of sysfs attributes
|
||||||
|
that could be used when composing the name.
|
||||||
|
|
||||||
|
These lists can be supplied as an hwdb entry in the form of
|
||||||
|
/etc/udev/hwdb.d/50-net-naming-allowlist.hwdb
|
||||||
|
net:naming:drvirtio_net
|
||||||
|
ID_NET_NAME_ALLOW=0
|
||||||
|
ID_NET_NAME_ALLOW_ACPI_INDEX=1
|
||||||
|
ID_NET_NAME_ALLOW_ADDR_ASSIGN_TYPE=1
|
||||||
|
ID_NET_NAME_ALLOW_ADDRESS=1
|
||||||
|
ID_NET_NAME_ALLOW_ARI_ENABLED=1
|
||||||
|
ID_NET_NAME_ALLOW_DEV_PORT=1
|
||||||
|
ID_NET_NAME_ALLOW_FUNCTION_ID=1
|
||||||
|
ID_NET_NAME_ALLOW_IFLINK=1
|
||||||
|
ID_NET_NAME_ALLOW_INDEX=1
|
||||||
|
ID_NET_NAME_ALLOW_LABEL=1
|
||||||
|
ID_NET_NAME_ALLOW_PHYS_PORT_NAME=1
|
||||||
|
ID_NET_NAME_ALLOW_TYPE=1
|
||||||
|
|
||||||
|
(cherry picked from commit 3b2e7dc5a285edbbb1bf6aed2d88b889d801613f)
|
||||||
|
|
||||||
|
Resolves: RHEL-1317
|
||||||
|
---
|
||||||
|
man/systemd.net-naming-scheme.xml | 69 ++++++++++++++++++++++++++
|
||||||
|
rules.d/75-net-description.rules | 2 +
|
||||||
|
src/shared/netif-naming-scheme.c | 81 +++++++++++++++++++++++++++++++
|
||||||
|
src/shared/netif-naming-scheme.h | 7 +++
|
||||||
|
src/udev/udev-builtin-net_id.c | 34 ++++++-------
|
||||||
|
5 files changed, 176 insertions(+), 17 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/man/systemd.net-naming-scheme.xml b/man/systemd.net-naming-scheme.xml
|
||||||
|
index c6ab86906a..ec9f3da437 100644
|
||||||
|
--- a/man/systemd.net-naming-scheme.xml
|
||||||
|
+++ b/man/systemd.net-naming-scheme.xml
|
||||||
|
@@ -588,6 +588,45 @@
|
||||||
|
particular version of systemd).</para>
|
||||||
|
</refsect1>
|
||||||
|
|
||||||
|
+ <refsect1>
|
||||||
|
+ <title>Limiting the use of specific sysfs attributes</title>
|
||||||
|
+
|
||||||
|
+ <para>When creating names for network cards, some naming schemes use data from sysfs populated
|
||||||
|
+ by the kernel. This means that although a specific naming scheme in udev is picked,
|
||||||
|
+ the network card's name can still change when a new kernel version adds a new sysfs attribute.
|
||||||
|
+ For example if kernel starts setting the <constant>phys_port_name</constant>, udev will append the
|
||||||
|
+ "<constant>n</constant><replaceable>phys_port_name</replaceable>" suffix to the device name.</para>
|
||||||
|
+
|
||||||
|
+ <variablelist>
|
||||||
|
+ <varlistentry>
|
||||||
|
+ <term><varname>ID_NET_NAME_ALLOW=<replaceable>BOOL</replaceable></varname></term>
|
||||||
|
+
|
||||||
|
+ <listitem><para>This evironment value sets a fallback policy for reading a sysfs attribute.
|
||||||
|
+ If set to <constant>0</constant> udev will not read any sysfs attribute by default, unless it is
|
||||||
|
+ explicitly allowlisted, see below. If set to <constant>1</constant> udev can use any sysfs attribute
|
||||||
|
+ unless it is explicitly forbidden. The default value is <constant>1</constant>.</para>
|
||||||
|
+
|
||||||
|
+ </listitem>
|
||||||
|
+ </varlistentry>
|
||||||
|
+
|
||||||
|
+ <varlistentry>
|
||||||
|
+ <term><varname>ID_NET_NAME_ALLOW_<replaceable>sysfsattr</replaceable>=<replaceable>BOOL</replaceable></varname></term>
|
||||||
|
+
|
||||||
|
+ <listitem><para>This evironment value explicitly states if udev shall use the specified
|
||||||
|
+ <replaceable>sysfsattr</replaceable>, when composing the device name.</para>
|
||||||
|
+
|
||||||
|
+ </listitem>
|
||||||
|
+ </varlistentry>
|
||||||
|
+ </variablelist>
|
||||||
|
+
|
||||||
|
+ <para>With these options, users can set an allowlist or denylist for sysfs attributes. To create
|
||||||
|
+ an allowlist, the user needs to set <varname>ID_NET_NAME_ALLOW=0</varname> for the device and then list
|
||||||
|
+ the allowed attributes with the
|
||||||
|
+ <varname>ID_NET_NAME_ALLOW_<replaceable>sysfsattr</replaceable>=1</varname>
|
||||||
|
+ options. In case of a denylist, the user needs to provide the list of denied attributes with
|
||||||
|
+ the <varname>ID_NET_NAME_ALLOW_<replaceable>sysfsattr</replaceable>=0</varname> options.</para>
|
||||||
|
+ </refsect1>
|
||||||
|
+
|
||||||
|
<refsect1>
|
||||||
|
<title>Examples</title>
|
||||||
|
|
||||||
|
@@ -674,6 +713,36 @@ ID_NET_NAME_PATH=enp0s29u1u2</programlisting>
|
||||||
|
ID_NET_NAME_MAC=enx026d3c00000a
|
||||||
|
ID_NET_NAME_PATH=encf5f0</programlisting>
|
||||||
|
</example>
|
||||||
|
+
|
||||||
|
+ <example>
|
||||||
|
+ <title>Set an allowlist for reading sysfs attributes for network card naming</title>
|
||||||
|
+
|
||||||
|
+ <programlisting><filename>/etc/udev/hwdb.d/50-net-naming-allowlist.hwdb</filename>
|
||||||
|
+net:naming:drvirtio_net:*
|
||||||
|
+ ID_NET_NAME_ALLOW=0
|
||||||
|
+ ID_NET_NAME_ALLOW_ACPI_INDEX=1
|
||||||
|
+ ID_NET_NAME_ALLOW_ADDR_ASSIGN_TYPE=1
|
||||||
|
+ ID_NET_NAME_ALLOW_ADDRESS=1
|
||||||
|
+ ID_NET_NAME_ALLOW_ARI_ENABLED=1
|
||||||
|
+ ID_NET_NAME_ALLOW_DEV_PORT=1
|
||||||
|
+ ID_NET_NAME_ALLOW_FUNCTION_ID=1
|
||||||
|
+ ID_NET_NAME_ALLOW_IFLINK=1
|
||||||
|
+ ID_NET_NAME_ALLOW_INDEX=1
|
||||||
|
+ ID_NET_NAME_ALLOW_LABEL=1
|
||||||
|
+ ID_NET_NAME_ALLOW_PHYS_PORT_NAME=1
|
||||||
|
+ ID_NET_NAME_ALLOW_TYPE=1</programlisting>
|
||||||
|
+ </example>
|
||||||
|
+
|
||||||
|
+ <example>
|
||||||
|
+ <title>Set a denylist so that specified sysfs attribute are ignored</title>
|
||||||
|
+
|
||||||
|
+ <programlisting><filename>/etc/udev/hwdb.d/50-net-naming-denylist.hwdb</filename>
|
||||||
|
+net:naming:drvirtio_net:*
|
||||||
|
+ ID_NET_NAME_ALLOW=1
|
||||||
|
+ ID_NET_NAME_ALLOW_DEV_PORT=0
|
||||||
|
+ ID_NET_NAME_ALLOW_PHYS_PORT_NAME=0
|
||||||
|
+ </programlisting>
|
||||||
|
+ </example>
|
||||||
|
</refsect1>
|
||||||
|
|
||||||
|
<refsect1>
|
||||||
|
diff --git a/rules.d/75-net-description.rules b/rules.d/75-net-description.rules
|
||||||
|
index 7e62f8b26b..5ba70a6545 100644
|
||||||
|
--- a/rules.d/75-net-description.rules
|
||||||
|
+++ b/rules.d/75-net-description.rules
|
||||||
|
@@ -3,6 +3,8 @@
|
||||||
|
ACTION=="remove", GOTO="net_end"
|
||||||
|
SUBSYSTEM!="net", GOTO="net_end"
|
||||||
|
|
||||||
|
+IMPORT{builtin}="hwdb 'net:naming:dr$env{ID_NET_DRIVER}:'"
|
||||||
|
+
|
||||||
|
IMPORT{builtin}="net_id"
|
||||||
|
|
||||||
|
SUBSYSTEMS=="usb", IMPORT{builtin}="usb_id", IMPORT{builtin}="hwdb --subsystem=usb"
|
||||||
|
diff --git a/src/shared/netif-naming-scheme.c b/src/shared/netif-naming-scheme.c
|
||||||
|
index 9cfa5ca8e6..e73c265371 100644
|
||||||
|
--- a/src/shared/netif-naming-scheme.c
|
||||||
|
+++ b/src/shared/netif-naming-scheme.c
|
||||||
|
@@ -1,6 +1,9 @@
|
||||||
|
/* SPDX-License-Identifier: LGPL-2.1-or-later */
|
||||||
|
|
||||||
|
+#include "sd-device.h"
|
||||||
|
+
|
||||||
|
#include "alloc-util.h"
|
||||||
|
+#include "device-private.h"
|
||||||
|
#include "netif-naming-scheme.h"
|
||||||
|
#include "proc-cmdline.h"
|
||||||
|
#include "string-util.h"
|
||||||
|
@@ -119,3 +122,81 @@ static const char* const alternative_names_policy_table[_NAMEPOLICY_MAX] = {
|
||||||
|
};
|
||||||
|
|
||||||
|
DEFINE_STRING_TABLE_LOOKUP(alternative_names_policy, NamePolicy);
|
||||||
|
+
|
||||||
|
+static int naming_sysattr_allowed_by_default(sd_device *dev) {
|
||||||
|
+ int r;
|
||||||
|
+
|
||||||
|
+ assert(dev);
|
||||||
|
+
|
||||||
|
+ r = device_get_property_bool(dev, "ID_NET_NAME_ALLOW");
|
||||||
|
+ if (r == -ENOENT)
|
||||||
|
+ return true;
|
||||||
|
+
|
||||||
|
+ return r;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static int naming_sysattr_allowed(sd_device *dev, const char *sysattr) {
|
||||||
|
+ char *sysattr_property;
|
||||||
|
+ int r;
|
||||||
|
+
|
||||||
|
+ assert(dev);
|
||||||
|
+ assert(sysattr);
|
||||||
|
+
|
||||||
|
+ sysattr_property = strjoina("ID_NET_NAME_ALLOW_", sysattr);
|
||||||
|
+ ascii_strupper(sysattr_property);
|
||||||
|
+
|
||||||
|
+ r = device_get_property_bool(dev, sysattr_property);
|
||||||
|
+ if (r == -ENOENT)
|
||||||
|
+ /* If ID_NET_NAME_ALLOW is not set or set to 1 default is to allow */
|
||||||
|
+ return naming_sysattr_allowed_by_default(dev);
|
||||||
|
+
|
||||||
|
+ return r;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+int device_get_sysattr_int_filtered(sd_device *device, const char *sysattr, int *ret_value) {
|
||||||
|
+ int r;
|
||||||
|
+
|
||||||
|
+ r = naming_sysattr_allowed(device, sysattr);
|
||||||
|
+ if (r < 0)
|
||||||
|
+ return r;
|
||||||
|
+ if (r == 0)
|
||||||
|
+ return -ENOENT;
|
||||||
|
+
|
||||||
|
+ return device_get_sysattr_int(device, sysattr, ret_value);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+int device_get_sysattr_unsigned_filtered(sd_device *device, const char *sysattr, unsigned *ret_value) {
|
||||||
|
+ int r;
|
||||||
|
+
|
||||||
|
+ r = naming_sysattr_allowed(device, sysattr);
|
||||||
|
+ if (r < 0)
|
||||||
|
+ return r;
|
||||||
|
+ if (r == 0)
|
||||||
|
+ return -ENOENT;
|
||||||
|
+
|
||||||
|
+ return device_get_sysattr_unsigned(device, sysattr, ret_value);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+int device_get_sysattr_bool_filtered(sd_device *device, const char *sysattr) {
|
||||||
|
+ int r;
|
||||||
|
+
|
||||||
|
+ r = naming_sysattr_allowed(device, sysattr);
|
||||||
|
+ if (r < 0)
|
||||||
|
+ return r;
|
||||||
|
+ if (r == 0)
|
||||||
|
+ return -ENOENT;
|
||||||
|
+
|
||||||
|
+ return device_get_sysattr_bool(device, sysattr);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+int device_get_sysattr_value_filtered(sd_device *device, const char *sysattr, const char **ret_value) {
|
||||||
|
+ int r;
|
||||||
|
+
|
||||||
|
+ r = naming_sysattr_allowed(device, sysattr);
|
||||||
|
+ if (r < 0)
|
||||||
|
+ return r;
|
||||||
|
+ if (r == 0)
|
||||||
|
+ return -ENOENT;
|
||||||
|
+
|
||||||
|
+ return sd_device_get_sysattr_value(device, sysattr, ret_value);
|
||||||
|
+}
|
||||||
|
diff --git a/src/shared/netif-naming-scheme.h b/src/shared/netif-naming-scheme.h
|
||||||
|
index ed45536f65..3baa7d5e72 100644
|
||||||
|
--- a/src/shared/netif-naming-scheme.h
|
||||||
|
+++ b/src/shared/netif-naming-scheme.h
|
||||||
|
@@ -3,6 +3,8 @@
|
||||||
|
|
||||||
|
#include <stdbool.h>
|
||||||
|
|
||||||
|
+#include "sd-device.h"
|
||||||
|
+
|
||||||
|
#include "macro.h"
|
||||||
|
|
||||||
|
/* So here's the deal: net_id is supposed to be an exercise in providing stable names for network devices. However, we
|
||||||
|
@@ -103,3 +105,8 @@ NamePolicy name_policy_from_string(const char *p) _pure_;
|
||||||
|
|
||||||
|
const char *alternative_names_policy_to_string(NamePolicy p) _const_;
|
||||||
|
NamePolicy alternative_names_policy_from_string(const char *p) _pure_;
|
||||||
|
+
|
||||||
|
+int device_get_sysattr_int_filtered(sd_device *device, const char *sysattr, int *ret_value);
|
||||||
|
+int device_get_sysattr_unsigned_filtered(sd_device *device, const char *sysattr, unsigned *ret_value);
|
||||||
|
+int device_get_sysattr_bool_filtered(sd_device *device, const char *sysattr);
|
||||||
|
+int device_get_sysattr_value_filtered(sd_device *device, const char *sysattr, const char **ret_value);
|
||||||
|
diff --git a/src/udev/udev-builtin-net_id.c b/src/udev/udev-builtin-net_id.c
|
||||||
|
index cecf854b98..c20df41c37 100644
|
||||||
|
--- a/src/udev/udev-builtin-net_id.c
|
||||||
|
+++ b/src/udev/udev-builtin-net_id.c
|
||||||
|
@@ -177,11 +177,11 @@ static int dev_pci_onboard(sd_device *dev, const LinkInfo *info, NetNames *names
|
||||||
|
assert(names);
|
||||||
|
|
||||||
|
/* ACPI _DSM — device specific method for naming a PCI or PCI Express device */
|
||||||
|
- if (sd_device_get_sysattr_value(names->pcidev, "acpi_index", &attr) >= 0)
|
||||||
|
+ if (device_get_sysattr_value_filtered(names->pcidev, "acpi_index", &attr) >= 0)
|
||||||
|
log_device_debug(names->pcidev, "acpi_index=%s", attr);
|
||||||
|
else {
|
||||||
|
/* SMBIOS type 41 — Onboard Devices Extended Information */
|
||||||
|
- r = sd_device_get_sysattr_value(names->pcidev, "index", &attr);
|
||||||
|
+ r = device_get_sysattr_value_filtered(names->pcidev, "index", &attr);
|
||||||
|
if (r < 0)
|
||||||
|
return r;
|
||||||
|
log_device_debug(names->pcidev, "index=%s", attr);
|
||||||
|
@@ -199,7 +199,7 @@ static int dev_pci_onboard(sd_device *dev, const LinkInfo *info, NetNames *names
|
||||||
|
"Not a valid onboard index: %lu", idx);
|
||||||
|
|
||||||
|
/* kernel provided port index for multiple ports on a single PCI function */
|
||||||
|
- if (sd_device_get_sysattr_value(dev, "dev_port", &attr) >= 0) {
|
||||||
|
+ if (device_get_sysattr_value_filtered(dev, "dev_port", &attr) >= 0) {
|
||||||
|
r = safe_atolu_full(attr, 10, &dev_port);
|
||||||
|
if (r < 0)
|
||||||
|
log_device_debug_errno(dev, r, "Failed to parse dev_port, ignoring: %m");
|
||||||
|
@@ -223,7 +223,7 @@ static int dev_pci_onboard(sd_device *dev, const LinkInfo *info, NetNames *names
|
||||||
|
idx, strempty(info->phys_port_name), dev_port,
|
||||||
|
special_glyph(SPECIAL_GLYPH_ARROW_RIGHT), empty_to_na(names->pci_onboard));
|
||||||
|
|
||||||
|
- if (sd_device_get_sysattr_value(names->pcidev, "label", &names->pci_onboard_label) >= 0)
|
||||||
|
+ if (device_get_sysattr_value_filtered(names->pcidev, "label", &names->pci_onboard_label) >= 0)
|
||||||
|
log_device_debug(dev, "Onboard label from PCI device: %s", names->pci_onboard_label);
|
||||||
|
else
|
||||||
|
names->pci_onboard_label = NULL;
|
||||||
|
@@ -260,7 +260,7 @@ static int is_pci_multifunction(sd_device *dev) {
|
||||||
|
static bool is_pci_ari_enabled(sd_device *dev) {
|
||||||
|
const char *a;
|
||||||
|
|
||||||
|
- if (sd_device_get_sysattr_value(dev, "ari_enabled", &a) < 0)
|
||||||
|
+ if (device_get_sysattr_value_filtered(dev, "ari_enabled", &a) < 0)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return streq(a, "1");
|
||||||
|
@@ -269,7 +269,7 @@ static bool is_pci_ari_enabled(sd_device *dev) {
|
||||||
|
static bool is_pci_bridge(sd_device *dev) {
|
||||||
|
const char *v, *p;
|
||||||
|
|
||||||
|
- if (sd_device_get_sysattr_value(dev, "modalias", &v) < 0)
|
||||||
|
+ if (device_get_sysattr_value_filtered(dev, "modalias", &v) < 0)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (!startswith(v, "pci:"))
|
||||||
|
@@ -309,7 +309,7 @@ static int parse_hotplug_slot_from_function_id(sd_device *dev, int slots_dirfd,
|
||||||
|
if (!naming_scheme_has(NAMING_SLOT_FUNCTION_ID))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
- if (sd_device_get_sysattr_value(dev, "function_id", &attr) < 0)
|
||||||
|
+ if (device_get_sysattr_value_filtered(dev, "function_id", &attr) < 0)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
r = safe_atou64(attr, &function_id);
|
||||||
|
@@ -366,7 +366,7 @@ static int dev_pci_slot(sd_device *dev, const LinkInfo *info, NetNames *names) {
|
||||||
|
func += slot * 8;
|
||||||
|
|
||||||
|
/* kernel provided port index for multiple ports on a single PCI function */
|
||||||
|
- if (sd_device_get_sysattr_value(dev, "dev_port", &attr) >= 0) {
|
||||||
|
+ if (device_get_sysattr_value_filtered(dev, "dev_port", &attr) >= 0) {
|
||||||
|
log_device_debug(dev, "dev_port=%s", attr);
|
||||||
|
|
||||||
|
r = safe_atolu_full(attr, 10, &dev_port);
|
||||||
|
@@ -378,7 +378,7 @@ static int dev_pci_slot(sd_device *dev, const LinkInfo *info, NetNames *names) {
|
||||||
|
* which thus stays initialized as 0. */
|
||||||
|
if (dev_port == 0 &&
|
||||||
|
info->iftype == ARPHRD_INFINIBAND &&
|
||||||
|
- sd_device_get_sysattr_value(dev, "dev_id", &attr) >= 0) {
|
||||||
|
+ device_get_sysattr_value_filtered(dev, "dev_id", &attr) >= 0) {
|
||||||
|
log_device_debug(dev, "dev_id=%s", attr);
|
||||||
|
|
||||||
|
r = safe_atolu_full(attr, 10, &dev_port);
|
||||||
|
@@ -449,7 +449,7 @@ static int dev_pci_slot(sd_device *dev, const LinkInfo *info, NetNames *names) {
|
||||||
|
if (!path)
|
||||||
|
return -ENOMEM;
|
||||||
|
|
||||||
|
- if (sd_device_get_sysattr_value(pci, path, &address) < 0)
|
||||||
|
+ if (device_get_sysattr_value_filtered(pci, path, &address) < 0)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
/* match slot address with device by stripping the function */
|
||||||
|
@@ -674,7 +674,7 @@ static int dev_devicetree_onboard(sd_device *dev, NetNames *names) {
|
||||||
|
if (!alias_index)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
- if (sd_device_get_sysattr_value(aliases_dev, alias, &alias_path) < 0)
|
||||||
|
+ if (device_get_sysattr_value_filtered(aliases_dev, alias, &alias_path) < 0)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (!path_equal(ofnode_path, alias_path))
|
||||||
|
@@ -693,7 +693,7 @@ static int dev_devicetree_onboard(sd_device *dev, NetNames *names) {
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ...but make sure we don't have an alias conflict */
|
||||||
|
- if (i == 0 && sd_device_get_sysattr_value(aliases_dev, conflict, NULL) >= 0)
|
||||||
|
+ if (i == 0 && device_get_sysattr_value_filtered(aliases_dev, conflict, NULL) >= 0)
|
||||||
|
return log_device_debug_errno(dev, SYNTHETIC_ERRNO(EEXIST),
|
||||||
|
"Ethernet alias conflict: ethernet and ethernet0 both exist");
|
||||||
|
|
||||||
|
@@ -944,7 +944,7 @@ static int names_mac(sd_device *dev, const LinkInfo *info) {
|
||||||
|
info->hw_addr.length);
|
||||||
|
|
||||||
|
/* check for NET_ADDR_PERM, skip random MAC addresses */
|
||||||
|
- r = sd_device_get_sysattr_value(dev, "addr_assign_type", &s);
|
||||||
|
+ r = device_get_sysattr_value_filtered(dev, "addr_assign_type", &s);
|
||||||
|
if (r < 0)
|
||||||
|
return log_device_debug_errno(dev, r, "Failed to read addr_assign_type: %m");
|
||||||
|
r = safe_atou(s, &i);
|
||||||
|
@@ -1080,11 +1080,11 @@ static int get_link_info(sd_device *dev, LinkInfo *info) {
|
||||||
|
if (r < 0)
|
||||||
|
return r;
|
||||||
|
|
||||||
|
- r = device_get_sysattr_int(dev, "iflink", &info->iflink);
|
||||||
|
+ r = device_get_sysattr_int_filtered(dev, "iflink", &info->iflink);
|
||||||
|
if (r < 0)
|
||||||
|
return r;
|
||||||
|
|
||||||
|
- r = device_get_sysattr_int(dev, "type", &info->iftype);
|
||||||
|
+ r = device_get_sysattr_int_filtered(dev, "type", &info->iftype);
|
||||||
|
if (r < 0)
|
||||||
|
return r;
|
||||||
|
|
||||||
|
@@ -1092,12 +1092,12 @@ static int get_link_info(sd_device *dev, LinkInfo *info) {
|
||||||
|
if (r < 0 && r != -ENOENT)
|
||||||
|
return r;
|
||||||
|
|
||||||
|
- r = sd_device_get_sysattr_value(dev, "phys_port_name", &info->phys_port_name);
|
||||||
|
+ r = device_get_sysattr_value_filtered(dev, "phys_port_name", &info->phys_port_name);
|
||||||
|
if (r >= 0)
|
||||||
|
/* Check if phys_port_name indicates virtual device representor */
|
||||||
|
(void) sscanf(info->phys_port_name, "pf%*uvf%d", &info->vf_representor_id);
|
||||||
|
|
||||||
|
- r = sd_device_get_sysattr_value(dev, "address", &s);
|
||||||
|
+ r = device_get_sysattr_value_filtered(dev, "address", &s);
|
||||||
|
if (r < 0 && r != -ENOENT)
|
||||||
|
return r;
|
||||||
|
if (r >= 0) {
|
@ -0,0 +1,38 @@
|
|||||||
|
From c5e8c8163c5063d7cc0a376022380f46a9d18ab0 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Yu Watanabe <watanabe.yu+github@gmail.com>
|
||||||
|
Date: Wed, 20 Dec 2023 15:08:49 +0900
|
||||||
|
Subject: [PATCH] man: environment value -> udev property
|
||||||
|
|
||||||
|
These are not environment variables, but udev properties.
|
||||||
|
|
||||||
|
Follow-up for 3b2e7dc5a285edbbb1bf6aed2d88b889d801613f.
|
||||||
|
|
||||||
|
(cherry picked from commit 044149e6152db7a8bb293aac19e84b3b06566d63)
|
||||||
|
|
||||||
|
Resolves: RHEL-1317
|
||||||
|
---
|
||||||
|
man/systemd.net-naming-scheme.xml | 4 ++--
|
||||||
|
1 file changed, 2 insertions(+), 2 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/man/systemd.net-naming-scheme.xml b/man/systemd.net-naming-scheme.xml
|
||||||
|
index ec9f3da437..639c03262f 100644
|
||||||
|
--- a/man/systemd.net-naming-scheme.xml
|
||||||
|
+++ b/man/systemd.net-naming-scheme.xml
|
||||||
|
@@ -601,7 +601,7 @@
|
||||||
|
<varlistentry>
|
||||||
|
<term><varname>ID_NET_NAME_ALLOW=<replaceable>BOOL</replaceable></varname></term>
|
||||||
|
|
||||||
|
- <listitem><para>This evironment value sets a fallback policy for reading a sysfs attribute.
|
||||||
|
+ <listitem><para>This udev property sets a fallback policy for reading a sysfs attribute.
|
||||||
|
If set to <constant>0</constant> udev will not read any sysfs attribute by default, unless it is
|
||||||
|
explicitly allowlisted, see below. If set to <constant>1</constant> udev can use any sysfs attribute
|
||||||
|
unless it is explicitly forbidden. The default value is <constant>1</constant>.</para>
|
||||||
|
@@ -612,7 +612,7 @@
|
||||||
|
<varlistentry>
|
||||||
|
<term><varname>ID_NET_NAME_ALLOW_<replaceable>sysfsattr</replaceable>=<replaceable>BOOL</replaceable></varname></term>
|
||||||
|
|
||||||
|
- <listitem><para>This evironment value explicitly states if udev shall use the specified
|
||||||
|
+ <listitem><para>This udev property explicitly states if udev shall use the specified
|
||||||
|
<replaceable>sysfsattr</replaceable>, when composing the device name.</para>
|
||||||
|
|
||||||
|
</listitem>
|
@ -0,0 +1,50 @@
|
|||||||
|
From 58b968fc319f227fde22725f862063010c1c4138 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Michal Sekletar <msekleta@redhat.com>
|
||||||
|
Date: Tue, 12 Dec 2023 19:03:39 +0100
|
||||||
|
Subject: [PATCH] logind: don't setup idle session watch for lock-screen and
|
||||||
|
greeter
|
||||||
|
|
||||||
|
Reason to skip the idle session logic for these session classes is that
|
||||||
|
they are idle by default.
|
||||||
|
|
||||||
|
(cherry picked from commit 508b4786e8592e82eb4832549f74aaa54335d14c)
|
||||||
|
|
||||||
|
Related: RHEL-20757
|
||||||
|
---
|
||||||
|
man/logind.conf.xml | 9 +++++----
|
||||||
|
src/login/logind-session.c | 2 +-
|
||||||
|
2 files changed, 6 insertions(+), 5 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/man/logind.conf.xml b/man/logind.conf.xml
|
||||||
|
index 1a87cf6baf..55cbabaafb 100644
|
||||||
|
--- a/man/logind.conf.xml
|
||||||
|
+++ b/man/logind.conf.xml
|
||||||
|
@@ -348,10 +348,11 @@
|
||||||
|
<term><varname>StopIdleSessionSec=</varname></term>
|
||||||
|
|
||||||
|
<listitem><para>Specifies a timeout in seconds, or a time span value after which
|
||||||
|
- <filename>systemd-logind</filename> checks the idle state of all sessions. Every session that is idle for
|
||||||
|
- longer then the timeout will be stopped. Defaults to <literal>infinity</literal>
|
||||||
|
- (<filename>systemd-logind</filename> is not checking the idle state of sessions). For details about the syntax
|
||||||
|
- of time spans, see
|
||||||
|
+ <filename>systemd-logind</filename> checks the idle state of all sessions. Every session that is idle
|
||||||
|
+ for longer than the timeout will be stopped. Note that this option doesn't apply to
|
||||||
|
+ <literal>greeter</literal> or <literal>lock-screen</literal> sessions. Defaults to
|
||||||
|
+ <literal>infinity</literal> (<filename>systemd-logind</filename> is not checking the idle state
|
||||||
|
+ of sessions). For details about the syntax of time spans, see
|
||||||
|
<citerefentry><refentrytitle>systemd.time</refentrytitle><manvolnum>7</manvolnum></citerefentry>.
|
||||||
|
</para></listitem>
|
||||||
|
</varlistentry>
|
||||||
|
diff --git a/src/login/logind-session.c b/src/login/logind-session.c
|
||||||
|
index 709a585013..68c2aa9670 100644
|
||||||
|
--- a/src/login/logind-session.c
|
||||||
|
+++ b/src/login/logind-session.c
|
||||||
|
@@ -735,7 +735,7 @@ static int session_setup_stop_on_idle_timer(Session *s) {
|
||||||
|
|
||||||
|
assert(s);
|
||||||
|
|
||||||
|
- if (s->manager->stop_idle_session_usec == USEC_INFINITY)
|
||||||
|
+ if (s->manager->stop_idle_session_usec == USEC_INFINITY || IN_SET(s->class, SESSION_GREETER, SESSION_LOCK_SCREEN))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
r = sd_event_add_time_relative(
|
@ -0,0 +1,33 @@
|
|||||||
|
From 51dba4b4c93298e32442c88cd0bce7715eea289d Mon Sep 17 00:00:00 2001
|
||||||
|
From: Lennart Poettering <lennart@poettering.net>
|
||||||
|
Date: Wed, 29 Nov 2023 11:07:08 +0100
|
||||||
|
Subject: [PATCH] logind: don't make idle action timer accuracy more coarse
|
||||||
|
than timeout
|
||||||
|
|
||||||
|
If we allow the timer accuracy to grow larger then the timeout itself
|
||||||
|
things are very confusing, because people might set a 1s time-out and we
|
||||||
|
turn that into 30s.
|
||||||
|
|
||||||
|
Hence, let's just cut off the 30s accuracy to the time-out itself, so
|
||||||
|
that we stay close to what users configured.
|
||||||
|
|
||||||
|
(cherry picked from commit e20bfa5005ab5458837bb62cb35bc1687f25124f)
|
||||||
|
|
||||||
|
Related: RHEL-20757
|
||||||
|
---
|
||||||
|
src/login/logind.c | 2 +-
|
||||||
|
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||||
|
|
||||||
|
diff --git a/src/login/logind.c b/src/login/logind.c
|
||||||
|
index 0348b19c05..70f72387c5 100644
|
||||||
|
--- a/src/login/logind.c
|
||||||
|
+++ b/src/login/logind.c
|
||||||
|
@@ -989,7 +989,7 @@ static int manager_dispatch_idle_action(sd_event_source *s, uint64_t t, void *us
|
||||||
|
m->event,
|
||||||
|
&m->idle_action_event_source,
|
||||||
|
CLOCK_MONOTONIC,
|
||||||
|
- elapse, USEC_PER_SEC*30,
|
||||||
|
+ elapse, MIN(USEC_PER_SEC*30, m->idle_action_usec), /* accuracy of 30s, but don't have an accuracy lower than the idle action timeout */
|
||||||
|
manager_dispatch_idle_action, m);
|
||||||
|
if (r < 0)
|
||||||
|
return log_error_errno(r, "Failed to add idle event source: %m");
|
@ -0,0 +1,58 @@
|
|||||||
|
From 468acdce5f4c6e5eaca7f348280e2491130e8d6d Mon Sep 17 00:00:00 2001
|
||||||
|
From: Lennart Poettering <lennart@poettering.net>
|
||||||
|
Date: Wed, 29 Nov 2023 11:09:20 +0100
|
||||||
|
Subject: [PATCH] logind: do TTY idle logic only for sessions marked as "tty"
|
||||||
|
|
||||||
|
Otherwise things might be weird, because background sessions might
|
||||||
|
become "idle", wich doesn#t really make much sense.
|
||||||
|
|
||||||
|
This shouldn't change much in 99% of the cases, but slightly corrects
|
||||||
|
behaviour as it ensures only "primary"/"foreground" sessions get the
|
||||||
|
idle logic, i.e. where a user exists that could actually make it
|
||||||
|
non-idle.
|
||||||
|
|
||||||
|
(cherry picked from commit 20604ff219cf4027f4ee9ca9ba7c0b9e72aec448)
|
||||||
|
|
||||||
|
Related: RHEL-20757
|
||||||
|
---
|
||||||
|
src/login/logind-session.c | 26 ++++++++++++++------------
|
||||||
|
1 file changed, 14 insertions(+), 12 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/src/login/logind-session.c b/src/login/logind-session.c
|
||||||
|
index 68c2aa9670..af5817e2b6 100644
|
||||||
|
--- a/src/login/logind-session.c
|
||||||
|
+++ b/src/login/logind-session.c
|
||||||
|
@@ -1029,19 +1029,21 @@ int session_get_idle_hint(Session *s, dual_timestamp *t) {
|
||||||
|
return s->idle_hint;
|
||||||
|
}
|
||||||
|
|
||||||
|
- /* For sessions with an explicitly configured tty, let's check its atime */
|
||||||
|
- if (s->tty) {
|
||||||
|
- r = get_tty_atime(s->tty, &atime);
|
||||||
|
- if (r >= 0)
|
||||||
|
- goto found_atime;
|
||||||
|
- }
|
||||||
|
+ if (s->type == SESSION_TTY) {
|
||||||
|
+ /* For sessions with an explicitly configured tty, let's check its atime */
|
||||||
|
+ if (s->tty) {
|
||||||
|
+ r = get_tty_atime(s->tty, &atime);
|
||||||
|
+ if (r >= 0)
|
||||||
|
+ goto found_atime;
|
||||||
|
+ }
|
||||||
|
|
||||||
|
- /* For sessions with a leader but no explicitly configured tty, let's check the controlling tty of
|
||||||
|
- * the leader */
|
||||||
|
- if (pid_is_valid(s->leader)) {
|
||||||
|
- r = get_process_ctty_atime(s->leader, &atime);
|
||||||
|
- if (r >= 0)
|
||||||
|
- goto found_atime;
|
||||||
|
+ /* For sessions with a leader but no explicitly configured tty, let's check the controlling tty of
|
||||||
|
+ * the leader */
|
||||||
|
+ if (pid_is_valid(s->leader)) {
|
||||||
|
+ r = get_process_ctty_atime(s->leader, &atime);
|
||||||
|
+ if (r >= 0)
|
||||||
|
+ goto found_atime;
|
||||||
|
+ }
|
||||||
|
}
|
||||||
|
|
||||||
|
if (t)
|
@ -0,0 +1,32 @@
|
|||||||
|
From f36dfb7ec1c780bdb74a4879fcce4be63adbaa6e Mon Sep 17 00:00:00 2001
|
||||||
|
From: Jan Janssen <medhefgo@web.de>
|
||||||
|
Date: Fri, 27 Jan 2023 14:28:58 +0100
|
||||||
|
Subject: [PATCH] meson: Properly install 90-uki-copy.install
|
||||||
|
|
||||||
|
(cherry picked from commit 4c181c1a33ef4de0130a131a2b332348dda672ed)
|
||||||
|
|
||||||
|
Resolves: RHEL-16354
|
||||||
|
---
|
||||||
|
src/kernel-install/meson.build | 7 +++++--
|
||||||
|
1 file changed, 5 insertions(+), 2 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/src/kernel-install/meson.build b/src/kernel-install/meson.build
|
||||||
|
index 68a4d43862..2ff62d5935 100644
|
||||||
|
--- a/src/kernel-install/meson.build
|
||||||
|
+++ b/src/kernel-install/meson.build
|
||||||
|
@@ -3,10 +3,13 @@
|
||||||
|
kernel_install_in = files('kernel-install.in')
|
||||||
|
loaderentry_install = files('90-loaderentry.install')
|
||||||
|
|
||||||
|
-uki_copy_install = files('90-uki-copy.install')
|
||||||
|
+kernel_install_files = files(
|
||||||
|
+ '50-depmod.install',
|
||||||
|
+ '90-uki-copy.install',
|
||||||
|
+)
|
||||||
|
|
||||||
|
if want_kernel_install
|
||||||
|
- install_data('50-depmod.install',
|
||||||
|
+ install_data(kernel_install_files,
|
||||||
|
loaderentry_install,
|
||||||
|
install_mode : 'rwxr-xr-x',
|
||||||
|
install_dir : kernelinstalldir)
|
@ -0,0 +1,189 @@
|
|||||||
|
From bf287f49fab60f47dd2547cdc3653fed53af3b21 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Jan Macku <jamacku@redhat.com>
|
||||||
|
Date: Fri, 12 Jan 2024 15:25:14 +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-1086
|
||||||
|
---
|
||||||
|
.../source-git-automation-on-demand.yml | 61 ++--------------
|
||||||
|
.github/workflows/source-git-automation.yml | 72 ++-----------------
|
||||||
|
2 files changed, 12 insertions(+), 121 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/.github/workflows/source-git-automation-on-demand.yml b/.github/workflows/source-git-automation-on-demand.yml
|
||||||
|
index 3f3da959c4..90149e74bb 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,62 +57,17 @@ jobs:
|
||||||
|
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: write-all
|
||||||
|
- # contents: write
|
||||||
|
- # statuses: write
|
||||||
|
- # checks: write
|
||||||
|
- # pull-requests: write
|
||||||
|
+ permissions:
|
||||||
|
+ # required for merging PRs
|
||||||
|
+ contents: 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 17135b590f..776ac5b237 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 5f98f309ccc71db57b93392c4f6427df620b8f53 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Jan Macku <jamacku@redhat.com>
|
||||||
|
Date: Fri, 12 Jan 2024 15:27:56 +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-1086
|
||||||
|
---
|
||||||
|
.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 90149e74bb..b5ccb891d1 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,39 @@
|
|||||||
|
From 5701905d024afc00a650ff2f2461570497694edb Mon Sep 17 00:00:00 2001
|
||||||
|
From: Jan Macku <jamacku@redhat.com>
|
||||||
|
Date: Fri, 12 Jan 2024 15:32:27 +0100
|
||||||
|
Subject: [PATCH] ci: add all Z-Stream versions to array of allowed versions
|
||||||
|
|
||||||
|
rhel-only
|
||||||
|
|
||||||
|
Related: RHEL-1086
|
||||||
|
---
|
||||||
|
.github/tracker-validator.yml | 10 ++++++++++
|
||||||
|
1 file changed, 10 insertions(+)
|
||||||
|
|
||||||
|
diff --git a/.github/tracker-validator.yml b/.github/tracker-validator.yml
|
||||||
|
index 9e43e4e7d5..f88cc0a572 100644
|
||||||
|
--- a/.github/tracker-validator.yml
|
||||||
|
+++ b/.github/tracker-validator.yml
|
||||||
|
@@ -7,12 +7,22 @@ products:
|
||||||
|
- Red Hat Enterprise Linux 9
|
||||||
|
- CentOS Stream 9
|
||||||
|
- rhel-9.0.0
|
||||||
|
+ - rhel-9.0.0.z
|
||||||
|
- rhel-9.2.0
|
||||||
|
+ - rhel-9.2.0.z
|
||||||
|
- rhel-9.3.0
|
||||||
|
+ - rhel-9.3.0.z
|
||||||
|
- rhel-9.4.0
|
||||||
|
+ - rhel-9.4.0.z
|
||||||
|
- rhel-9.5.0
|
||||||
|
+ - rhel-9.5.0.z
|
||||||
|
- rhel-9.6.0
|
||||||
|
+ - rhel-9.6.0.z
|
||||||
|
- rhel-9.7.0
|
||||||
|
+ - rhel-9.7.0.z
|
||||||
|
- rhel-9.8.0
|
||||||
|
+ - rhel-9.8.0.z
|
||||||
|
- rhel-9.9.0
|
||||||
|
+ - rhel-9.9.0.z
|
||||||
|
- rhel-9.10.0
|
||||||
|
+ - rhel-9.10.0.z
|
@ -0,0 +1,55 @@
|
|||||||
|
From 63b7060ef28895ce56bb058912e8e81bd00b8395 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Jan Macku <jamacku@redhat.com>
|
||||||
|
Date: Tue, 23 Jan 2024 15:23:05 +0100
|
||||||
|
Subject: [PATCH] udev/net_id: introduce naming scheme for RHEL-9.4
|
||||||
|
|
||||||
|
rhel-only
|
||||||
|
|
||||||
|
Resolves: RHEL-22427
|
||||||
|
---
|
||||||
|
man/systemd.net-naming-scheme.xml | 6 ++++++
|
||||||
|
src/shared/netif-naming-scheme.c | 1 +
|
||||||
|
src/shared/netif-naming-scheme.h | 1 +
|
||||||
|
3 files changed, 8 insertions(+)
|
||||||
|
|
||||||
|
diff --git a/man/systemd.net-naming-scheme.xml b/man/systemd.net-naming-scheme.xml
|
||||||
|
index 639c03262f..4f06587ec9 100644
|
||||||
|
--- a/man/systemd.net-naming-scheme.xml
|
||||||
|
+++ b/man/systemd.net-naming-scheme.xml
|
||||||
|
@@ -582,6 +582,12 @@
|
||||||
|
</listitem>
|
||||||
|
</varlistentry>
|
||||||
|
|
||||||
|
+ <varlistentry>
|
||||||
|
+ <term><constant>rhel-9.4</constant></term>
|
||||||
|
+
|
||||||
|
+ <listitem><para>Same as naming scheme <constant>rhel-9.3</constant>.</para></listitem>
|
||||||
|
+ </varlistentry>
|
||||||
|
+
|
||||||
|
</variablelist>
|
||||||
|
|
||||||
|
<para>Note that <constant>latest</constant> may be used to denote the latest scheme known (to this
|
||||||
|
diff --git a/src/shared/netif-naming-scheme.c b/src/shared/netif-naming-scheme.c
|
||||||
|
index e73c265371..bf27f5571b 100644
|
||||||
|
--- a/src/shared/netif-naming-scheme.c
|
||||||
|
+++ b/src/shared/netif-naming-scheme.c
|
||||||
|
@@ -42,6 +42,7 @@ static const NamingScheme naming_schemes[] = {
|
||||||
|
{ "rhel-9.1", NAMING_RHEL_9_1 },
|
||||||
|
{ "rhel-9.2", NAMING_RHEL_9_2 },
|
||||||
|
{ "rhel-9.3", NAMING_RHEL_9_3 },
|
||||||
|
+ { "rhel-9.4", NAMING_RHEL_9_4 },
|
||||||
|
/* … add more schemes here, as the logic to name devices is updated … */
|
||||||
|
|
||||||
|
EXTRA_NET_NAMING_MAP
|
||||||
|
diff --git a/src/shared/netif-naming-scheme.h b/src/shared/netif-naming-scheme.h
|
||||||
|
index 3baa7d5e72..f39c75c64e 100644
|
||||||
|
--- a/src/shared/netif-naming-scheme.h
|
||||||
|
+++ b/src/shared/netif-naming-scheme.h
|
||||||
|
@@ -70,6 +70,7 @@ typedef enum NamingSchemeFlags {
|
||||||
|
NAMING_RHEL_9_1 = NAMING_RHEL_9_0,
|
||||||
|
NAMING_RHEL_9_2 = NAMING_RHEL_9_0,
|
||||||
|
NAMING_RHEL_9_3 = NAMING_RHEL_9_0 | NAMING_SR_IOV_R,
|
||||||
|
+ NAMING_RHEL_9_4 = NAMING_RHEL_9_3,
|
||||||
|
|
||||||
|
EXTRA_NET_NAMING_SCHEMES
|
||||||
|
|
@ -0,0 +1,204 @@
|
|||||||
|
From 690c7cdadd1033bfb47e8de5cc9db781a6055e2a Mon Sep 17 00:00:00 2001
|
||||||
|
From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= <zbyszek@in.waw.pl>
|
||||||
|
Date: Wed, 9 Aug 2023 16:36:38 +0200
|
||||||
|
Subject: [PATCH] basic/errno-util: add wrappers which only accept negative
|
||||||
|
errno
|
||||||
|
|
||||||
|
We do 'IN_SET(r, -CONST1, -CONST2)', instead of 'IN_SET(-r, CONST1, CONST2)'
|
||||||
|
because -r is undefined if r is the minimum value (i.e. INT_MIN). But we know
|
||||||
|
that the constants are small, so their negative values are fine.
|
||||||
|
|
||||||
|
(cherry picked from commit b0be985cdd5e51f5f16d6bf541435c225f7c0633)
|
||||||
|
|
||||||
|
Related: RHEL-22443
|
||||||
|
---
|
||||||
|
src/basic/errno-util.h | 129 +++++++++++++++++++++----------------
|
||||||
|
src/test/test-errno-util.c | 7 ++
|
||||||
|
2 files changed, 80 insertions(+), 56 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/src/basic/errno-util.h b/src/basic/errno-util.h
|
||||||
|
index 091f99c590..be5c04e285 100644
|
||||||
|
--- a/src/basic/errno-util.h
|
||||||
|
+++ b/src/basic/errno-util.h
|
||||||
|
@@ -84,12 +84,21 @@ static inline int errno_or_else(int fallback) {
|
||||||
|
return -abs(fallback);
|
||||||
|
}
|
||||||
|
|
||||||
|
+/* abs(3) says: Trying to take the absolute value of the most negative integer is not defined. */
|
||||||
|
+#define _DEFINE_ABS_WRAPPER(name) \
|
||||||
|
+ static inline bool ERRNO_IS_##name(int r) { \
|
||||||
|
+ if (r == INT_MIN) \
|
||||||
|
+ return false; \
|
||||||
|
+ return ERRNO_IS_NEG_##name(-abs(r)); \
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
/* For send()/recv() or read()/write(). */
|
||||||
|
-static inline bool ERRNO_IS_TRANSIENT(int r) {
|
||||||
|
- return IN_SET(abs(r),
|
||||||
|
- EAGAIN,
|
||||||
|
- EINTR);
|
||||||
|
+static inline bool ERRNO_IS_NEG_TRANSIENT(int r) {
|
||||||
|
+ return IN_SET(r,
|
||||||
|
+ -EAGAIN,
|
||||||
|
+ -EINTR);
|
||||||
|
}
|
||||||
|
+_DEFINE_ABS_WRAPPER(TRANSIENT);
|
||||||
|
|
||||||
|
/* Hint #1: ENETUNREACH happens if we try to connect to "non-existing" special IP addresses, such as ::5.
|
||||||
|
*
|
||||||
|
@@ -98,79 +107,87 @@ static inline bool ERRNO_IS_TRANSIENT(int r) {
|
||||||
|
*
|
||||||
|
* Hint #3: When asynchronous connect() on TCP fails because the host never acknowledges a single packet,
|
||||||
|
* kernel tells us that with ETIMEDOUT, see tcp(7). */
|
||||||
|
-static inline bool ERRNO_IS_DISCONNECT(int r) {
|
||||||
|
- return IN_SET(abs(r),
|
||||||
|
- ECONNABORTED,
|
||||||
|
- ECONNREFUSED,
|
||||||
|
- ECONNRESET,
|
||||||
|
- EHOSTDOWN,
|
||||||
|
- EHOSTUNREACH,
|
||||||
|
- ENETDOWN,
|
||||||
|
- ENETRESET,
|
||||||
|
- ENETUNREACH,
|
||||||
|
- ENONET,
|
||||||
|
- ENOPROTOOPT,
|
||||||
|
- ENOTCONN,
|
||||||
|
- EPIPE,
|
||||||
|
- EPROTO,
|
||||||
|
- ESHUTDOWN,
|
||||||
|
- ETIMEDOUT);
|
||||||
|
+static inline bool ERRNO_IS_NEG_DISCONNECT(int r) {
|
||||||
|
+ return IN_SET(r,
|
||||||
|
+ -ECONNABORTED,
|
||||||
|
+ -ECONNREFUSED,
|
||||||
|
+ -ECONNRESET,
|
||||||
|
+ -EHOSTDOWN,
|
||||||
|
+ -EHOSTUNREACH,
|
||||||
|
+ -ENETDOWN,
|
||||||
|
+ -ENETRESET,
|
||||||
|
+ -ENETUNREACH,
|
||||||
|
+ -ENONET,
|
||||||
|
+ -ENOPROTOOPT,
|
||||||
|
+ -ENOTCONN,
|
||||||
|
+ -EPIPE,
|
||||||
|
+ -EPROTO,
|
||||||
|
+ -ESHUTDOWN,
|
||||||
|
+ -ETIMEDOUT);
|
||||||
|
}
|
||||||
|
+_DEFINE_ABS_WRAPPER(DISCONNECT);
|
||||||
|
|
||||||
|
/* Transient errors we might get on accept() that we should ignore. As per error handling comment in
|
||||||
|
* the accept(2) man page. */
|
||||||
|
-static inline bool ERRNO_IS_ACCEPT_AGAIN(int r) {
|
||||||
|
- return ERRNO_IS_DISCONNECT(r) ||
|
||||||
|
- ERRNO_IS_TRANSIENT(r) ||
|
||||||
|
- abs(r) == EOPNOTSUPP;
|
||||||
|
+static inline bool ERRNO_IS_NEG_ACCEPT_AGAIN(int r) {
|
||||||
|
+ return ERRNO_IS_NEG_DISCONNECT(r) ||
|
||||||
|
+ ERRNO_IS_NEG_TRANSIENT(r) ||
|
||||||
|
+ r == -EOPNOTSUPP;
|
||||||
|
}
|
||||||
|
+_DEFINE_ABS_WRAPPER(ACCEPT_AGAIN);
|
||||||
|
|
||||||
|
/* Resource exhaustion, could be our fault or general system trouble */
|
||||||
|
-static inline bool ERRNO_IS_RESOURCE(int r) {
|
||||||
|
- return IN_SET(abs(r),
|
||||||
|
- EMFILE,
|
||||||
|
- ENFILE,
|
||||||
|
- ENOMEM);
|
||||||
|
+static inline bool ERRNO_IS_NEG_RESOURCE(int r) {
|
||||||
|
+ return IN_SET(r,
|
||||||
|
+ -EMFILE,
|
||||||
|
+ -ENFILE,
|
||||||
|
+ -ENOMEM);
|
||||||
|
}
|
||||||
|
+_DEFINE_ABS_WRAPPER(RESOURCE);
|
||||||
|
|
||||||
|
/* Seven different errors for "operation/system call/ioctl/socket feature not supported" */
|
||||||
|
-static inline bool ERRNO_IS_NOT_SUPPORTED(int r) {
|
||||||
|
- return IN_SET(abs(r),
|
||||||
|
- EOPNOTSUPP,
|
||||||
|
- ENOTTY,
|
||||||
|
- ENOSYS,
|
||||||
|
- EAFNOSUPPORT,
|
||||||
|
- EPFNOSUPPORT,
|
||||||
|
- EPROTONOSUPPORT,
|
||||||
|
- ESOCKTNOSUPPORT);
|
||||||
|
+static inline bool ERRNO_IS_NEG_NOT_SUPPORTED(int r) {
|
||||||
|
+ return IN_SET(r,
|
||||||
|
+ -EOPNOTSUPP,
|
||||||
|
+ -ENOTTY,
|
||||||
|
+ -ENOSYS,
|
||||||
|
+ -EAFNOSUPPORT,
|
||||||
|
+ -EPFNOSUPPORT,
|
||||||
|
+ -EPROTONOSUPPORT,
|
||||||
|
+ -ESOCKTNOSUPPORT);
|
||||||
|
}
|
||||||
|
+_DEFINE_ABS_WRAPPER(NOT_SUPPORTED);
|
||||||
|
|
||||||
|
/* Two different errors for access problems */
|
||||||
|
-static inline bool ERRNO_IS_PRIVILEGE(int r) {
|
||||||
|
- return IN_SET(abs(r),
|
||||||
|
- EACCES,
|
||||||
|
- EPERM);
|
||||||
|
+static inline bool ERRNO_IS_NEG_PRIVILEGE(int r) {
|
||||||
|
+ return IN_SET(r,
|
||||||
|
+ -EACCES,
|
||||||
|
+ -EPERM);
|
||||||
|
}
|
||||||
|
+_DEFINE_ABS_WRAPPER(PRIVILEGE);
|
||||||
|
|
||||||
|
/* Three different errors for "not enough disk space" */
|
||||||
|
-static inline bool ERRNO_IS_DISK_SPACE(int r) {
|
||||||
|
- return IN_SET(abs(r),
|
||||||
|
- ENOSPC,
|
||||||
|
- EDQUOT,
|
||||||
|
- EFBIG);
|
||||||
|
+static inline bool ERRNO_IS_NEG_DISK_SPACE(int r) {
|
||||||
|
+ return IN_SET(r,
|
||||||
|
+ -ENOSPC,
|
||||||
|
+ -EDQUOT,
|
||||||
|
+ -EFBIG);
|
||||||
|
}
|
||||||
|
+_DEFINE_ABS_WRAPPER(DISK_SPACE);
|
||||||
|
|
||||||
|
/* Three different errors for "this device does not quite exist" */
|
||||||
|
-static inline bool ERRNO_IS_DEVICE_ABSENT(int r) {
|
||||||
|
- return IN_SET(abs(r),
|
||||||
|
- ENODEV,
|
||||||
|
- ENXIO,
|
||||||
|
- ENOENT);
|
||||||
|
+static inline bool ERRNO_IS_NEG_DEVICE_ABSENT(int r) {
|
||||||
|
+ return IN_SET(r,
|
||||||
|
+ -ENODEV,
|
||||||
|
+ -ENXIO,
|
||||||
|
+ -ENOENT);
|
||||||
|
}
|
||||||
|
+_DEFINE_ABS_WRAPPER(DEVICE_ABSENT);
|
||||||
|
|
||||||
|
/* Quite often we want to handle cases where the backing FS doesn't support extended attributes at all and
|
||||||
|
* where it simply doesn't have the requested xattr the same way */
|
||||||
|
-static inline bool ERRNO_IS_XATTR_ABSENT(int r) {
|
||||||
|
- return abs(r) == ENODATA ||
|
||||||
|
- ERRNO_IS_NOT_SUPPORTED(r);
|
||||||
|
+static inline bool ERRNO_IS_NEG_XATTR_ABSENT(int r) {
|
||||||
|
+ return r == -ENODATA ||
|
||||||
|
+ ERRNO_IS_NEG_NOT_SUPPORTED(r);
|
||||||
|
}
|
||||||
|
+_DEFINE_ABS_WRAPPER(XATTR_ABSENT);
|
||||||
|
diff --git a/src/test/test-errno-util.c b/src/test/test-errno-util.c
|
||||||
|
index f858927c92..507d53df7a 100644
|
||||||
|
--- a/src/test/test-errno-util.c
|
||||||
|
+++ b/src/test/test-errno-util.c
|
||||||
|
@@ -47,4 +47,11 @@ TEST(STRERROR_OR_ELSE) {
|
||||||
|
log_info("STRERROR_OR_ELSE(-EPERM, \"EOF\") → %s", STRERROR_OR_EOF(-EPERM));
|
||||||
|
}
|
||||||
|
|
||||||
|
+TEST(ERRNO_IS_TRANSIENT) {
|
||||||
|
+ assert_se( ERRNO_IS_NEG_TRANSIENT(-EINTR));
|
||||||
|
+ assert_se(!ERRNO_IS_NEG_TRANSIENT(EINTR));
|
||||||
|
+ assert_se( ERRNO_IS_TRANSIENT(-EINTR));
|
||||||
|
+ assert_se( ERRNO_IS_TRANSIENT(EINTR));
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
DEFINE_TEST_MAIN(LOG_INFO);
|
@ -0,0 +1,148 @@
|
|||||||
|
From 7c5ece0b649ebea23ebb28eb3cafdb28ba49a9d0 Mon Sep 17 00:00:00 2001
|
||||||
|
From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= <zbyszek@in.waw.pl>
|
||||||
|
Date: Wed, 9 Aug 2023 18:21:13 +0200
|
||||||
|
Subject: [PATCH] errno-util: allow ERRNO_IS_* to accept types wider than int
|
||||||
|
|
||||||
|
This is useful if the variable is ssize_t and we don't want to trigger a
|
||||||
|
warning or truncation.
|
||||||
|
|
||||||
|
With gcc (gcc-13.2.1-1.fc38.x86_64), the resulting systemd binary is identical,
|
||||||
|
so I assume that the compiler is able to completely optimize away the type.
|
||||||
|
|
||||||
|
(cherry picked from commit fe0feacb9e9641874fde459af4067d9b7e9d7462)
|
||||||
|
|
||||||
|
Related: RHEL-22443
|
||||||
|
---
|
||||||
|
src/basic/errno-util.h | 27 +++++++++++++++------------
|
||||||
|
src/test/test-errno-util.c | 13 +++++++++++++
|
||||||
|
2 files changed, 28 insertions(+), 12 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/src/basic/errno-util.h b/src/basic/errno-util.h
|
||||||
|
index be5c04e285..b10dd755c9 100644
|
||||||
|
--- a/src/basic/errno-util.h
|
||||||
|
+++ b/src/basic/errno-util.h
|
||||||
|
@@ -1,6 +1,7 @@
|
||||||
|
/* SPDX-License-Identifier: LGPL-2.1-or-later */
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
+#include <inttypes.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
@@ -86,14 +87,16 @@ static inline int errno_or_else(int fallback) {
|
||||||
|
|
||||||
|
/* abs(3) says: Trying to take the absolute value of the most negative integer is not defined. */
|
||||||
|
#define _DEFINE_ABS_WRAPPER(name) \
|
||||||
|
- static inline bool ERRNO_IS_##name(int r) { \
|
||||||
|
- if (r == INT_MIN) \
|
||||||
|
+ static inline bool ERRNO_IS_##name(intmax_t r) { \
|
||||||
|
+ if (r == INTMAX_MIN) \
|
||||||
|
return false; \
|
||||||
|
- return ERRNO_IS_NEG_##name(-abs(r)); \
|
||||||
|
+ return ERRNO_IS_NEG_##name(-imaxabs(r)); \
|
||||||
|
}
|
||||||
|
|
||||||
|
+assert_cc(INT_MAX <= INTMAX_MAX);
|
||||||
|
+
|
||||||
|
/* For send()/recv() or read()/write(). */
|
||||||
|
-static inline bool ERRNO_IS_NEG_TRANSIENT(int r) {
|
||||||
|
+static inline bool ERRNO_IS_NEG_TRANSIENT(intmax_t r) {
|
||||||
|
return IN_SET(r,
|
||||||
|
-EAGAIN,
|
||||||
|
-EINTR);
|
||||||
|
@@ -107,7 +110,7 @@ _DEFINE_ABS_WRAPPER(TRANSIENT);
|
||||||
|
*
|
||||||
|
* Hint #3: When asynchronous connect() on TCP fails because the host never acknowledges a single packet,
|
||||||
|
* kernel tells us that with ETIMEDOUT, see tcp(7). */
|
||||||
|
-static inline bool ERRNO_IS_NEG_DISCONNECT(int r) {
|
||||||
|
+static inline bool ERRNO_IS_NEG_DISCONNECT(intmax_t r) {
|
||||||
|
return IN_SET(r,
|
||||||
|
-ECONNABORTED,
|
||||||
|
-ECONNREFUSED,
|
||||||
|
@@ -129,7 +132,7 @@ _DEFINE_ABS_WRAPPER(DISCONNECT);
|
||||||
|
|
||||||
|
/* Transient errors we might get on accept() that we should ignore. As per error handling comment in
|
||||||
|
* the accept(2) man page. */
|
||||||
|
-static inline bool ERRNO_IS_NEG_ACCEPT_AGAIN(int r) {
|
||||||
|
+static inline bool ERRNO_IS_NEG_ACCEPT_AGAIN(intmax_t r) {
|
||||||
|
return ERRNO_IS_NEG_DISCONNECT(r) ||
|
||||||
|
ERRNO_IS_NEG_TRANSIENT(r) ||
|
||||||
|
r == -EOPNOTSUPP;
|
||||||
|
@@ -137,7 +140,7 @@ static inline bool ERRNO_IS_NEG_ACCEPT_AGAIN(int r) {
|
||||||
|
_DEFINE_ABS_WRAPPER(ACCEPT_AGAIN);
|
||||||
|
|
||||||
|
/* Resource exhaustion, could be our fault or general system trouble */
|
||||||
|
-static inline bool ERRNO_IS_NEG_RESOURCE(int r) {
|
||||||
|
+static inline bool ERRNO_IS_NEG_RESOURCE(intmax_t r) {
|
||||||
|
return IN_SET(r,
|
||||||
|
-EMFILE,
|
||||||
|
-ENFILE,
|
||||||
|
@@ -146,7 +149,7 @@ static inline bool ERRNO_IS_NEG_RESOURCE(int r) {
|
||||||
|
_DEFINE_ABS_WRAPPER(RESOURCE);
|
||||||
|
|
||||||
|
/* Seven different errors for "operation/system call/ioctl/socket feature not supported" */
|
||||||
|
-static inline bool ERRNO_IS_NEG_NOT_SUPPORTED(int r) {
|
||||||
|
+static inline bool ERRNO_IS_NEG_NOT_SUPPORTED(intmax_t r) {
|
||||||
|
return IN_SET(r,
|
||||||
|
-EOPNOTSUPP,
|
||||||
|
-ENOTTY,
|
||||||
|
@@ -159,7 +162,7 @@ static inline bool ERRNO_IS_NEG_NOT_SUPPORTED(int r) {
|
||||||
|
_DEFINE_ABS_WRAPPER(NOT_SUPPORTED);
|
||||||
|
|
||||||
|
/* Two different errors for access problems */
|
||||||
|
-static inline bool ERRNO_IS_NEG_PRIVILEGE(int r) {
|
||||||
|
+static inline bool ERRNO_IS_NEG_PRIVILEGE(intmax_t r) {
|
||||||
|
return IN_SET(r,
|
||||||
|
-EACCES,
|
||||||
|
-EPERM);
|
||||||
|
@@ -167,7 +170,7 @@ static inline bool ERRNO_IS_NEG_PRIVILEGE(int r) {
|
||||||
|
_DEFINE_ABS_WRAPPER(PRIVILEGE);
|
||||||
|
|
||||||
|
/* Three different errors for "not enough disk space" */
|
||||||
|
-static inline bool ERRNO_IS_NEG_DISK_SPACE(int r) {
|
||||||
|
+static inline bool ERRNO_IS_NEG_DISK_SPACE(intmax_t r) {
|
||||||
|
return IN_SET(r,
|
||||||
|
-ENOSPC,
|
||||||
|
-EDQUOT,
|
||||||
|
@@ -176,7 +179,7 @@ static inline bool ERRNO_IS_NEG_DISK_SPACE(int r) {
|
||||||
|
_DEFINE_ABS_WRAPPER(DISK_SPACE);
|
||||||
|
|
||||||
|
/* Three different errors for "this device does not quite exist" */
|
||||||
|
-static inline bool ERRNO_IS_NEG_DEVICE_ABSENT(int r) {
|
||||||
|
+static inline bool ERRNO_IS_NEG_DEVICE_ABSENT(intmax_t r) {
|
||||||
|
return IN_SET(r,
|
||||||
|
-ENODEV,
|
||||||
|
-ENXIO,
|
||||||
|
@@ -186,7 +189,7 @@ _DEFINE_ABS_WRAPPER(DEVICE_ABSENT);
|
||||||
|
|
||||||
|
/* Quite often we want to handle cases where the backing FS doesn't support extended attributes at all and
|
||||||
|
* where it simply doesn't have the requested xattr the same way */
|
||||||
|
-static inline bool ERRNO_IS_NEG_XATTR_ABSENT(int r) {
|
||||||
|
+static inline bool ERRNO_IS_NEG_XATTR_ABSENT(intmax_t r) {
|
||||||
|
return r == -ENODATA ||
|
||||||
|
ERRNO_IS_NEG_NOT_SUPPORTED(r);
|
||||||
|
}
|
||||||
|
diff --git a/src/test/test-errno-util.c b/src/test/test-errno-util.c
|
||||||
|
index 507d53df7a..cac0d5402b 100644
|
||||||
|
--- a/src/test/test-errno-util.c
|
||||||
|
+++ b/src/test/test-errno-util.c
|
||||||
|
@@ -52,6 +52,19 @@ TEST(ERRNO_IS_TRANSIENT) {
|
||||||
|
assert_se(!ERRNO_IS_NEG_TRANSIENT(EINTR));
|
||||||
|
assert_se( ERRNO_IS_TRANSIENT(-EINTR));
|
||||||
|
assert_se( ERRNO_IS_TRANSIENT(EINTR));
|
||||||
|
+
|
||||||
|
+ /* Test with type wider than int */
|
||||||
|
+ ssize_t r = -EAGAIN;
|
||||||
|
+ assert_se( ERRNO_IS_NEG_TRANSIENT(r));
|
||||||
|
+
|
||||||
|
+ /* On 64-bit arches, now (int) r == EAGAIN */
|
||||||
|
+ r = SSIZE_MAX - EAGAIN + 1;
|
||||||
|
+ assert_se(!ERRNO_IS_NEG_TRANSIENT(r));
|
||||||
|
+
|
||||||
|
+ assert_se(!ERRNO_IS_NEG_TRANSIENT(INT_MAX));
|
||||||
|
+ assert_se(!ERRNO_IS_NEG_TRANSIENT(INT_MIN));
|
||||||
|
+ assert_se(!ERRNO_IS_NEG_TRANSIENT(INTMAX_MAX));
|
||||||
|
+ assert_se(!ERRNO_IS_NEG_TRANSIENT(INTMAX_MIN));
|
||||||
|
}
|
||||||
|
|
||||||
|
DEFINE_TEST_MAIN(LOG_INFO);
|
@ -0,0 +1,184 @@
|
|||||||
|
From f2bf171137c348f6f976276504c8e8a54e33ff78 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Lukas Nykryn <lnykryn@redhat.com>
|
||||||
|
Date: Thu, 19 Oct 2023 10:38:06 +0200
|
||||||
|
Subject: [PATCH] udev: add new builtin net_driver
|
||||||
|
|
||||||
|
Currently the ID_NET_DRIVER is set in net_setup_link builtin.
|
||||||
|
But this is called pretty late in the udev processing chain.
|
||||||
|
|
||||||
|
Right now in some custom rules it was workarounded by calling ethtool
|
||||||
|
binary directly, which is ugly.
|
||||||
|
|
||||||
|
So let's split this code to a separate builtin.
|
||||||
|
|
||||||
|
(cherry picked from commit 2b5b25f123ceb89b3ff45b2380db1c8a88b046d9)
|
||||||
|
|
||||||
|
Resolves: RHEL-22443
|
||||||
|
---
|
||||||
|
rules.d/50-udev-default.rules.in | 2 ++
|
||||||
|
src/udev/meson.build | 1 +
|
||||||
|
src/udev/net/link-config.c | 5 ++-
|
||||||
|
src/udev/net/link-config.h | 2 +-
|
||||||
|
src/udev/udev-builtin-net_driver.c | 43 ++++++++++++++++++++++++++
|
||||||
|
src/udev/udev-builtin-net_setup_link.c | 3 --
|
||||||
|
src/udev/udev-builtin.c | 1 +
|
||||||
|
src/udev/udev-builtin.h | 2 ++
|
||||||
|
8 files changed, 52 insertions(+), 7 deletions(-)
|
||||||
|
create mode 100644 src/udev/udev-builtin-net_driver.c
|
||||||
|
|
||||||
|
diff --git a/rules.d/50-udev-default.rules.in b/rules.d/50-udev-default.rules.in
|
||||||
|
index 843bdaf9ce..f670b51987 100644
|
||||||
|
--- a/rules.d/50-udev-default.rules.in
|
||||||
|
+++ b/rules.d/50-udev-default.rules.in
|
||||||
|
@@ -17,6 +17,8 @@ SUBSYSTEM=="rtc", KERNEL=="rtc0", SYMLINK+="rtc", OPTIONS+="link_priority=-100"
|
||||||
|
SUBSYSTEM=="usb", ENV{DEVTYPE}=="usb_device", IMPORT{builtin}="usb_id", IMPORT{builtin}="hwdb --subsystem=usb"
|
||||||
|
ENV{MODALIAS}!="", IMPORT{builtin}="hwdb --subsystem=$env{SUBSYSTEM}"
|
||||||
|
|
||||||
|
+SUBSYSTEM=="net", IMPORT{builtin}="net_driver"
|
||||||
|
+
|
||||||
|
ACTION!="add", GOTO="default_end"
|
||||||
|
|
||||||
|
SUBSYSTEM=="tty", KERNEL=="ptmx", GROUP="tty", MODE="0666"
|
||||||
|
diff --git a/src/udev/meson.build b/src/udev/meson.build
|
||||||
|
index 08a1d97e81..564aa6de1b 100644
|
||||||
|
--- a/src/udev/meson.build
|
||||||
|
+++ b/src/udev/meson.build
|
||||||
|
@@ -35,6 +35,7 @@ libudevd_core_sources = files(
|
||||||
|
'udev-builtin-hwdb.c',
|
||||||
|
'udev-builtin-input_id.c',
|
||||||
|
'udev-builtin-keyboard.c',
|
||||||
|
+ 'udev-builtin-net_driver.c',
|
||||||
|
'udev-builtin-net_id.c',
|
||||||
|
'udev-builtin-net_setup_link.c',
|
||||||
|
'udev-builtin-path_id.c',
|
||||||
|
diff --git a/src/udev/net/link-config.c b/src/udev/net/link-config.c
|
||||||
|
index 2d8c902fd3..80c64519ab 100644
|
||||||
|
--- a/src/udev/net/link-config.c
|
||||||
|
+++ b/src/udev/net/link-config.c
|
||||||
|
@@ -362,7 +362,6 @@ Link *link_free(Link *link) {
|
||||||
|
|
||||||
|
sd_device_unref(link->device);
|
||||||
|
free(link->kind);
|
||||||
|
- free(link->driver);
|
||||||
|
strv_free(link->altnames);
|
||||||
|
return mfree(link);
|
||||||
|
}
|
||||||
|
@@ -415,8 +414,8 @@ int link_new(LinkConfigContext *ctx, sd_netlink **rtnl, sd_device *device, Link
|
||||||
|
log_link_debug_errno(link, r, "Failed to get permanent hardware address, ignoring: %m");
|
||||||
|
}
|
||||||
|
|
||||||
|
- r = ethtool_get_driver(&ctx->ethtool_fd, link->ifname, &link->driver);
|
||||||
|
- if (r < 0)
|
||||||
|
+ r = sd_device_get_property_value(link->device, "ID_NET_DRIVER", &link->driver);
|
||||||
|
+ if (r < 0 && r != -ENOENT)
|
||||||
|
log_link_debug_errno(link, r, "Failed to get driver, ignoring: %m");
|
||||||
|
|
||||||
|
*ret = TAKE_PTR(link);
|
||||||
|
diff --git a/src/udev/net/link-config.h b/src/udev/net/link-config.h
|
||||||
|
index 874a391543..8343783caf 100644
|
||||||
|
--- a/src/udev/net/link-config.h
|
||||||
|
+++ b/src/udev/net/link-config.h
|
||||||
|
@@ -34,7 +34,7 @@ typedef struct Link {
|
||||||
|
sd_device_action_t action;
|
||||||
|
|
||||||
|
char *kind;
|
||||||
|
- char *driver;
|
||||||
|
+ const char *driver;
|
||||||
|
uint16_t iftype;
|
||||||
|
uint32_t flags;
|
||||||
|
struct hw_addr_data hw_addr;
|
||||||
|
diff --git a/src/udev/udev-builtin-net_driver.c b/src/udev/udev-builtin-net_driver.c
|
||||||
|
new file mode 100644
|
||||||
|
index 0000000000..f1642a491d
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/src/udev/udev-builtin-net_driver.c
|
||||||
|
@@ -0,0 +1,43 @@
|
||||||
|
+/* SPDX-License-Identifier: LGPL-2.1-or-later */
|
||||||
|
+
|
||||||
|
+#include "alloc-util.h"
|
||||||
|
+#include "device-util.h"
|
||||||
|
+#include "errno-util.h"
|
||||||
|
+#include "ethtool-util.h"
|
||||||
|
+#include "fd-util.h"
|
||||||
|
+#include "log.h"
|
||||||
|
+#include "string-util.h"
|
||||||
|
+#include "udev-builtin.h"
|
||||||
|
+
|
||||||
|
+static int builtin_net_driver_set_driver(UdevEvent *event, int argc, char **argv, bool test) {
|
||||||
|
+ sd_device *dev = ASSERT_PTR(ASSERT_PTR(event)->dev);
|
||||||
|
+ _cleanup_close_ int ethtool_fd = -EBADF;
|
||||||
|
+ _cleanup_free_ char *driver = NULL;
|
||||||
|
+ const char *sysname;
|
||||||
|
+ int r;
|
||||||
|
+
|
||||||
|
+ r = sd_device_get_sysname(dev, &sysname);
|
||||||
|
+ if (r < 0)
|
||||||
|
+ return log_device_warning_errno(dev, r, "Failed to get sysname: %m");
|
||||||
|
+
|
||||||
|
+ r = ethtool_get_driver(ðtool_fd, sysname, &driver);
|
||||||
|
+ if (ERRNO_IS_NEG_NOT_SUPPORTED(r)) {
|
||||||
|
+ log_device_debug_errno(dev, r, "Querying driver name via ethtool API is not supported by device '%s', ignoring: %m", sysname);
|
||||||
|
+ return 0;
|
||||||
|
+ }
|
||||||
|
+ if (r == -ENODEV) {
|
||||||
|
+ log_device_debug_errno(dev, r, "Device already vanished, ignoring.");
|
||||||
|
+ return 0;
|
||||||
|
+ }
|
||||||
|
+ if (r < 0)
|
||||||
|
+ return log_device_warning_errno(dev, r, "Failed to get driver for '%s': %m", sysname);
|
||||||
|
+
|
||||||
|
+ return udev_builtin_add_property(event->dev, test, "ID_NET_DRIVER", driver);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+const UdevBuiltin udev_builtin_net_driver = {
|
||||||
|
+ .name = "net_driver",
|
||||||
|
+ .cmd = builtin_net_driver_set_driver,
|
||||||
|
+ .help = "Set driver for network device",
|
||||||
|
+ .run_once = true,
|
||||||
|
+};
|
||||||
|
diff --git a/src/udev/udev-builtin-net_setup_link.c b/src/udev/udev-builtin-net_setup_link.c
|
||||||
|
index e964bf7bf4..b0279a1814 100644
|
||||||
|
--- a/src/udev/udev-builtin-net_setup_link.c
|
||||||
|
+++ b/src/udev/udev-builtin-net_setup_link.c
|
||||||
|
@@ -26,9 +26,6 @@ static int builtin_net_setup_link(UdevEvent *event, int argc, char **argv, bool
|
||||||
|
if (r < 0)
|
||||||
|
return log_device_warning_errno(dev, r, "Failed to get link information: %m");
|
||||||
|
|
||||||
|
- if (link->driver)
|
||||||
|
- udev_builtin_add_property(dev, test, "ID_NET_DRIVER", link->driver);
|
||||||
|
-
|
||||||
|
r = link_get_config(ctx, link);
|
||||||
|
if (r < 0) {
|
||||||
|
if (r == -ENOENT) {
|
||||||
|
diff --git a/src/udev/udev-builtin.c b/src/udev/udev-builtin.c
|
||||||
|
index c84db8855c..d55dc3337d 100644
|
||||||
|
--- a/src/udev/udev-builtin.c
|
||||||
|
+++ b/src/udev/udev-builtin.c
|
||||||
|
@@ -22,6 +22,7 @@ static const UdevBuiltin *const builtins[_UDEV_BUILTIN_MAX] = {
|
||||||
|
#if HAVE_KMOD
|
||||||
|
[UDEV_BUILTIN_KMOD] = &udev_builtin_kmod,
|
||||||
|
#endif
|
||||||
|
+ [UDEV_BUILTIN_NET_DRIVER] = &udev_builtin_net_driver,
|
||||||
|
[UDEV_BUILTIN_NET_ID] = &udev_builtin_net_id,
|
||||||
|
[UDEV_BUILTIN_NET_LINK] = &udev_builtin_net_setup_link,
|
||||||
|
[UDEV_BUILTIN_PATH_ID] = &udev_builtin_path_id,
|
||||||
|
diff --git a/src/udev/udev-builtin.h b/src/udev/udev-builtin.h
|
||||||
|
index 919d51e798..c23f2d1613 100644
|
||||||
|
--- a/src/udev/udev-builtin.h
|
||||||
|
+++ b/src/udev/udev-builtin.h
|
||||||
|
@@ -19,6 +19,7 @@ typedef enum UdevBuiltinCommand {
|
||||||
|
#if HAVE_KMOD
|
||||||
|
UDEV_BUILTIN_KMOD,
|
||||||
|
#endif
|
||||||
|
+ UDEV_BUILTIN_NET_DRIVER,
|
||||||
|
UDEV_BUILTIN_NET_ID,
|
||||||
|
UDEV_BUILTIN_NET_LINK,
|
||||||
|
UDEV_BUILTIN_PATH_ID,
|
||||||
|
@@ -63,6 +64,7 @@ extern const UdevBuiltin udev_builtin_keyboard;
|
||||||
|
#if HAVE_KMOD
|
||||||
|
extern const UdevBuiltin udev_builtin_kmod;
|
||||||
|
#endif
|
||||||
|
+extern const UdevBuiltin udev_builtin_net_driver;
|
||||||
|
extern const UdevBuiltin udev_builtin_net_id;
|
||||||
|
extern const UdevBuiltin udev_builtin_net_setup_link;
|
||||||
|
extern const UdevBuiltin udev_builtin_path_id;
|
@ -0,0 +1,55 @@
|
|||||||
|
From 9ff108d83a19557593c1d0f1687878377e898a54 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Lukas Nykryn <lnykryn@redhat.com>
|
||||||
|
Date: Wed, 24 Jan 2024 13:49:21 +0100
|
||||||
|
Subject: [PATCH] udev/net_id: introduce naming scheme for RHEL-8.10
|
||||||
|
|
||||||
|
rhel-only
|
||||||
|
|
||||||
|
Resolves: RHEL-22427
|
||||||
|
---
|
||||||
|
man/systemd.net-naming-scheme.xml | 6 ++++++
|
||||||
|
src/shared/netif-naming-scheme.c | 1 +
|
||||||
|
src/shared/netif-naming-scheme.h | 1 +
|
||||||
|
3 files changed, 8 insertions(+)
|
||||||
|
|
||||||
|
diff --git a/man/systemd.net-naming-scheme.xml b/man/systemd.net-naming-scheme.xml
|
||||||
|
index 4f06587ec9..3bab402e98 100644
|
||||||
|
--- a/man/systemd.net-naming-scheme.xml
|
||||||
|
+++ b/man/systemd.net-naming-scheme.xml
|
||||||
|
@@ -547,6 +547,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>
|
||||||
|
+
|
||||||
|
<varlistentry>
|
||||||
|
<term><constant>rhel-9.0</constant></term>
|
||||||
|
|
||||||
|
diff --git a/src/shared/netif-naming-scheme.c b/src/shared/netif-naming-scheme.c
|
||||||
|
index bf27f5571b..536ed44b21 100644
|
||||||
|
--- a/src/shared/netif-naming-scheme.c
|
||||||
|
+++ b/src/shared/netif-naming-scheme.c
|
||||||
|
@@ -38,6 +38,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 },
|
||||||
|
{ "rhel-9.0", NAMING_RHEL_9_0 },
|
||||||
|
{ "rhel-9.1", NAMING_RHEL_9_1 },
|
||||||
|
{ "rhel-9.2", NAMING_RHEL_9_2 },
|
||||||
|
diff --git a/src/shared/netif-naming-scheme.h b/src/shared/netif-naming-scheme.h
|
||||||
|
index f39c75c64e..5f49157aaa 100644
|
||||||
|
--- a/src/shared/netif-naming-scheme.h
|
||||||
|
+++ b/src/shared/netif-naming-scheme.h
|
||||||
|
@@ -65,6 +65,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_RHEL_9_0 = NAMING_V250 | NAMING_BRIDGE_MULTIFUNCTION_SLOT,
|
||||||
|
NAMING_RHEL_9_1 = NAMING_RHEL_9_0,
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in new issue