systemd-252-18

Resolves: #2161260,#2170883,#2178222,#2190226,#2209912,#2211065,#2213521,#2226980,#2230364,#2231845
This commit is contained in:
Jan Macku 2023-08-22 13:24:53 +02:00
parent 234ac58cb7
commit ea71a49292
84 changed files with 12382 additions and 1 deletions

View File

@ -0,0 +1,83 @@
From df138e1005d2eab39f55aea3bd128b660e1e6a15 Mon Sep 17 00:00:00 2001
From: Jan Macku <jamacku@redhat.com>
Date: Tue, 1 Aug 2023 16:18:06 +0200
Subject: [PATCH] doc: add downstream CONTRIBUTING document
rhel-only
Related: #2170883
---
CONTRIBUTING.md | 64 +++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 64 insertions(+)
create mode 100644 CONTRIBUTING.md
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
new file mode 100644
index 0000000000..86a742ea43
--- /dev/null
+++ b/CONTRIBUTING.md
@@ -0,0 +1,64 @@
+# Contributing
+
+Welcome to systemd source-git for CentOS Stream and RHEL. When contributing, please follow the guide below.
+
+## Workflow
+
+```mermaid
+flowchart LR
+ A(Issue) --> B{is fixed\nupstream}
+ B -->|YES| C(backport\nupstream patch)
+ B -->|NO| D(upstream\nsubmit issue or PR)
+ D --> E{accepted\nand fixed}
+ E -->|YES| C
+ E -->|NO| F(rhel-only patch) --> G
+ C --> G(submit PR)
+```
+
+## Filing issues
+
+When you find an issue with systemd used in CentOS Stream or RHEL, please file an issue by using Bugzilla ticket systemd - [link](https://bugzilla.redhat.com/enter_bug.cgi?classification=Red%20Hat)
+GitHub Issues are not supported tracking system. If your issue is reproducible using the latest upstream version of systemd, please consider creating [upstream issue](https://github.com/systemd/systemd/issues/new/choose).
+
+## Posting Pull Requests
+
+Every Pull Request has to comply with the following rules:
+
+- Each commit has to reference [upstream](https://github.com/systemd/systemd) commit.
+- Each commit has to reference the approved issue/tracker.
+- Pull requests have to pass mandatory CI validation and testing
+- Pull requests have to be approved by at least one systemd downstream maintainer
+
+### Upstream reference
+
+When doing a back-port of an upstream commit, always use `cherry-pick -x <sha>`. Consider proposing a change upstream first when an upstream commit doesn't exist.
+If the change isn't upstream relevant or accepted by upstream, mark the commit with the `rhel-only` string.
+
+```md
+doc: Fix TYPO
+
+rhel-only
+
+Resolves: #1234567
+```
+
+### Issue reference
+
+Each commit has to reference the relevant approved systemd issue (see: [Filling issues section](#filing-issues)). For referencing issues, we use the following keywords:
+
+- **Resolves** for commits that directly resolve issues described in a referenced tracker
+- **Relates** for commits related to the referenced issue, but they don't fix it. Usually, tests and documentation.
+- **Reverts** for commits that reverts previously merged commit
+
+```md
+doc: Fix TYPO
+
+(cherry picked from commit c5afbac31bb33e7b1f4d59b253425af991a630a4)
+
+Resolves: #1234567
+```
+
+### Validation and testing
+
+Each Pull Request has to pass all enabled tests that are automatically run using GitHub Actions, CentOS Stream CI, and others.
+If CI failure is unrelated to the change introduced in Pull Request, the downstream maintainer will set the `ci-waived` label and explain why CI was waived.

View File

@ -0,0 +1,57 @@
From 2c849b9750ff4978a865e2bb377af69a86038da4 Mon Sep 17 00:00:00 2001
From: Jan Macku <jamacku@redhat.com>
Date: Tue, 8 Aug 2023 11:37:32 +0200
Subject: [PATCH] doc: improve CONTRIBUTING document
based on feedback from: https://github.com/redhat-plumbers/systemd-rhel8/pull/407
rhel-only
Related: #2170883
---
CONTRIBUTING.md | 11 +++++++----
1 file changed, 7 insertions(+), 4 deletions(-)
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index 86a742ea43..361366d899 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -17,7 +17,8 @@ flowchart LR
## Filing issues
-When you find an issue with systemd used in CentOS Stream or RHEL, please file an issue by using Bugzilla ticket systemd - [link](https://bugzilla.redhat.com/enter_bug.cgi?classification=Red%20Hat)
+When you find an issue with systemd used in CentOS Stream or RHEL, please file an issue in [Jira ticket system](https://issues.redhat.com/secure/CreateIssue!default.jspa) (set Project to **RHEL** and Component to **systemd**).
+
GitHub Issues are not supported tracking system. If your issue is reproducible using the latest upstream version of systemd, please consider creating [upstream issue](https://github.com/systemd/systemd/issues/new/choose).
## Posting Pull Requests
@@ -39,7 +40,7 @@ doc: Fix TYPO
rhel-only
-Resolves: #1234567
+Resolves: RHEL-678
```
### Issue reference
@@ -47,15 +48,17 @@ Resolves: #1234567
Each commit has to reference the relevant approved systemd issue (see: [Filling issues section](#filing-issues)). For referencing issues, we use the following keywords:
- **Resolves** for commits that directly resolve issues described in a referenced tracker
-- **Relates** for commits related to the referenced issue, but they don't fix it. Usually, tests and documentation.
+- **Related** for commits related to the referenced issue, but they don't fix it. Usually, tests and documentation.
- **Reverts** for commits that reverts previously merged commit
+When referencing issues, use following structure: `<keyword>: <issue ID>`. See the example below:
+
```md
doc: Fix TYPO
(cherry picked from commit c5afbac31bb33e7b1f4d59b253425af991a630a4)
-Resolves: #1234567
+Resolves: RHEL-678
```
### Validation and testing

View File

@ -0,0 +1,25 @@
From eff259c8c7677bbbe64890873bd64349871dd6c5 Mon Sep 17 00:00:00 2001
From: Jan Macku <jamacku@redhat.com>
Date: Tue, 8 Aug 2023 13:07:06 +0200
Subject: [PATCH] doc: use link with prefilled Jira issue
rhel-only
Related: #2170883
---
CONTRIBUTING.md | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index 361366d899..1de2b88995 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -17,7 +17,7 @@ flowchart LR
## Filing issues
-When you find an issue with systemd used in CentOS Stream or RHEL, please file an issue in [Jira ticket system](https://issues.redhat.com/secure/CreateIssue!default.jspa) (set Project to **RHEL** and Component to **systemd**).
+When you find an issue with systemd used in CentOS Stream or RHEL, please file an issue in [Jira ticket system](https://issues.redhat.com/secure/CreateIssueDetails!init.jspa?pid=12332745&issuetype=1&components=12380515).
GitHub Issues are not supported tracking system. If your issue is reproducible using the latest upstream version of systemd, please consider creating [upstream issue](https://github.com/systemd/systemd/issues/new/choose).

View File

@ -0,0 +1,52 @@
From 581094db0528e22af351912849474ad322502c28 Mon Sep 17 00:00:00 2001
From: Jan Macku <jamacku@redhat.com>
Date: Thu, 10 Aug 2023 15:16:29 +0200
Subject: [PATCH] docs: link downstream CONTRIBUTING in README
This should increase the visibility of the downstream CONTRIBUTING.
Also fix some wording and update links.
rhel-only
Related: #2170883
---
CONTRIBUTING.md | 4 ++--
README.md | 2 +-
2 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index 1de2b88995..bd17067be2 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -17,7 +17,7 @@ flowchart LR
## Filing issues
-When you find an issue with systemd used in CentOS Stream or RHEL, please file an issue in [Jira ticket system](https://issues.redhat.com/secure/CreateIssueDetails!init.jspa?pid=12332745&issuetype=1&components=12380515).
+When you find an issue with systemd used in **CentOS Stream** or **RHEL**, please file an issue in Red Hat [Jira ticket system](https://issues.redhat.com/secure/CreateIssueDetails!init.jspa?pid=12332745&issuetype=1&components=12380515&priority=10300).
GitHub Issues are not supported tracking system. If your issue is reproducible using the latest upstream version of systemd, please consider creating [upstream issue](https://github.com/systemd/systemd/issues/new/choose).
@@ -51,7 +51,7 @@ Each commit has to reference the relevant approved systemd issue (see: [Filling
- **Related** for commits related to the referenced issue, but they don't fix it. Usually, tests and documentation.
- **Reverts** for commits that reverts previously merged commit
-When referencing issues, use following structure: `<keyword>: <issue ID>`. See the example below:
+When referencing issues, use the following structure: `<keyword>: <issue ID>`. See the example below:
```md
doc: Fix TYPO
diff --git a/README.md b/README.md
index e507c4cb57..11a1b38038 100644
--- a/README.md
+++ b/README.md
@@ -30,7 +30,7 @@ Please see the [Code Map](docs/ARCHITECTURE.md) for information about this repos
Please see the [Hacking guide](docs/HACKING.md) for information on how to hack on systemd and test your modifications.
-Please see our [Contribution Guidelines](docs/CONTRIBUTING.md) for more information about filing GitHub Issues and posting GitHub Pull Requests.
+Please see our [Contribution Guidelines](CONTRIBUTING.md) for more information about filing GitHub Issues and posting GitHub Pull Requests.
When preparing patches for systemd, please follow our [Coding Style Guidelines](docs/CODING_STYLE.md).

View File

@ -0,0 +1,51 @@
From b544c7bfd7812458516d29a11511498ece02b9ee Mon Sep 17 00:00:00 2001
From: Ilya Leoshkevich <iii@linux.ibm.com>
Date: Mon, 30 Jan 2023 21:21:48 +0100
Subject: [PATCH] bpf: fix restrict_fs on s390x
Linux kernel's bpf-next contains BPF LSM support for s390x. systemd's
test-bpf-lsm currently fails with this kernel.
This is an endianness issue: in the restrict_fs bpf program,
magic_number has type unsigned long (64 bits on s390x), but magic_map
keys are uint32_t (32 bits). Accessing magic_map using 64-bit keys may
work by accident on little-endian systems, but fails hard on big-endian
ones.
Fix by casting magic_number to uint32_t.
(cherry picked from commit 907046282c27ee2ced5e22abb80ed8df2e157baf)
Resolves: #2230364
---
src/core/bpf/restrict_fs/restrict-fs.bpf.c | 10 +++++++---
1 file changed, 7 insertions(+), 3 deletions(-)
diff --git a/src/core/bpf/restrict_fs/restrict-fs.bpf.c b/src/core/bpf/restrict_fs/restrict-fs.bpf.c
index 522a029785..eb5ed3e7fe 100644
--- a/src/core/bpf/restrict_fs/restrict-fs.bpf.c
+++ b/src/core/bpf/restrict_fs/restrict-fs.bpf.c
@@ -39,16 +39,20 @@ struct {
SEC("lsm/file_open")
int BPF_PROG(restrict_filesystems, struct file *file, int ret)
{
- unsigned long magic_number;
+ unsigned long raw_magic_number;
uint64_t cgroup_id;
- uint32_t *value, *magic_map, zero = 0, *is_allow;
+ uint32_t *value, *magic_map, magic_number, zero = 0, *is_allow;
/* ret is the return value from the previous BPF program or 0 if it's
* the first hook */
if (ret != 0)
return ret;
- BPF_CORE_READ_INTO(&magic_number, file, f_inode, i_sb, s_magic);
+ BPF_CORE_READ_INTO(&raw_magic_number, file, f_inode, i_sb, s_magic);
+ /* super_block.s_magic is unsigned long, but magic_map keys are
+ * uint32_t. Using s_magic as-is would fail on big-endian systems,
+ * which have 64-bit unsigned long. So cast it. */
+ magic_number = (uint32_t)raw_magic_number;
cgroup_id = bpf_get_current_cgroup_id();

View File

@ -0,0 +1,24 @@
From fb3db0b1e27b2e60b86677907c761cb6d0a31c5e Mon Sep 17 00:00:00 2001
From: Jan Macku <jamacku@redhat.com>
Date: Mon, 14 Aug 2023 15:44:11 +0200
Subject: [PATCH] udev/net_id: use naming scheme for RHEL-9.3
rhel-only
Resolves: #2231845
---
src/shared/netif-naming-scheme.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/src/shared/netif-naming-scheme.c b/src/shared/netif-naming-scheme.c
index d846c794a8..0f50533279 100644
--- a/src/shared/netif-naming-scheme.c
+++ b/src/shared/netif-naming-scheme.c
@@ -28,6 +28,7 @@ static const NamingScheme naming_schemes[] = {
{ "rhel-9.0", NAMING_RHEL_9_0 },
{ "rhel-9.1", NAMING_RHEL_9_1 },
{ "rhel-9.2", NAMING_RHEL_9_2 },
+ { "rhel-9.3", NAMING_RHEL_9_3 },
/* … add more schemes here, as the logic to name devices is updated … */
EXTRA_NET_NAMING_MAP

View File

@ -0,0 +1,46 @@
From 87e554ca8567647afef3ba79f75bc98d67716fdb Mon Sep 17 00:00:00 2001
From: Daan De Meyer <daan.j.demeyer@gmail.com>
Date: Tue, 23 May 2023 16:24:47 +0200
Subject: [PATCH] core/timer: Always use inactive_exit_timestamp if it is set
If we're doing a daemon-reload, we'll be going from TIMER_DEAD => TIMER_WAITING,
so we won't use inactive_exit_timestamp because TIMER_DEAD != UNIT_ACTIVE, even
though inactive_exit_timestamp is serialized/deserialized and will be valid after
the daemon-reload.
This issue can lead to timers never firing as we'll always calculate the next
elapse based on the current realtime on daemon-reload, so if daemon-reload happens
often enough, the elapse interval will be moved into the future every time, which
means the timer will never trigger.
To fix the issue, let's always use inactive_exit_timestamp if it is set, and only
fall back to the current realtime if it is not set.
(cherry picked from commit 6546045fa0bf84737bd8b2e1e8bf7dd3941d8352)
Resolves: #2211065
---
src/core/timer.c | 10 ++++------
1 file changed, 4 insertions(+), 6 deletions(-)
diff --git a/src/core/timer.c b/src/core/timer.c
index b6810c8599..711500313d 100644
--- a/src/core/timer.c
+++ b/src/core/timer.c
@@ -401,12 +401,10 @@ static void timer_enter_waiting(Timer *t, bool time_change) {
if (t->last_trigger.realtime > 0)
b = t->last_trigger.realtime;
- else {
- if (state_translation_table[t->state] == UNIT_ACTIVE)
- b = UNIT(t)->inactive_exit_timestamp.realtime;
- else
- b = ts.realtime;
- }
+ else if (dual_timestamp_is_set(&UNIT(t)->inactive_exit_timestamp))
+ b = UNIT(t)->inactive_exit_timestamp.realtime;
+ else
+ b = ts.realtime;
r = calendar_spec_next_usec(v->calendar_spec, b, &v->next_elapse);
if (r < 0)

View File

@ -0,0 +1,25 @@
From 9974ff3bce3b309f086585929b21ac29d4d4f582 Mon Sep 17 00:00:00 2001
From: Daan De Meyer <daan.j.demeyer@gmail.com>
Date: Wed, 24 May 2023 11:41:37 +0200
Subject: [PATCH] timer: Use dual_timestamp_is_set() in one more place
(cherry picked from commit e21f75afcd95a46261a36a2614712eff6bc119f4)
Related: #2211065
---
src/core/timer.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/core/timer.c b/src/core/timer.c
index 711500313d..60e8fea79f 100644
--- a/src/core/timer.c
+++ b/src/core/timer.c
@@ -399,7 +399,7 @@ static void timer_enter_waiting(Timer *t, bool time_change) {
* to that. If we don't, just start from
* the activation time. */
- if (t->last_trigger.realtime > 0)
+ if (dual_timestamp_is_set(&t->last_trigger))
b = t->last_trigger.realtime;
else if (dual_timestamp_is_set(&UNIT(t)->inactive_exit_timestamp))
b = UNIT(t)->inactive_exit_timestamp.realtime;

View File

@ -0,0 +1,77 @@
From 5c1e6fb6440f86d59720d2d3673eb81c9255c5e8 Mon Sep 17 00:00:00 2001
From: Mike Yuan <me@yhndnzj.com>
Date: Thu, 11 May 2023 13:05:39 +0800
Subject: [PATCH] loginctl: list-users: also show state
(cherry picked from commit bae05711b5d06f330423f69d4d6500c907b8d322)
Related: #2209912
---
src/login/loginctl.c | 35 ++++++++++++++++++++++++++++++-----
1 file changed, 30 insertions(+), 5 deletions(-)
diff --git a/src/login/loginctl.c b/src/login/loginctl.c
index 4dbfa0db44..8b72ebae57 100644
--- a/src/login/loginctl.c
+++ b/src/login/loginctl.c
@@ -205,13 +205,15 @@ static int list_users(int argc, char *argv[], void *userdata) {
if (r < 0)
return bus_log_parse_error(r);
- table = table_new("uid", "user", "linger");
+ table = table_new("uid", "user", "linger", "state");
if (!table)
return log_oom();
(void) table_set_align_percent(table, TABLE_HEADER_CELL(0), 100);
for (;;) {
+ _cleanup_(sd_bus_error_free) sd_bus_error error_property = SD_BUS_ERROR_NULL;
+ _cleanup_free_ char *state = NULL;
const char *user, *object;
uint32_t uid;
int linger;
@@ -227,16 +229,39 @@ static int list_users(int argc, char *argv[], void *userdata) {
object,
"org.freedesktop.login1.User",
"Linger",
- &error,
+ &error_property,
'b',
&linger);
- if (r < 0)
- return log_error_errno(r, "Failed to get linger status: %s", bus_error_message(&error, r));
+ if (r < 0) {
+ if (sd_bus_error_has_name(&error_property, SD_BUS_ERROR_UNKNOWN_OBJECT))
+ /* The user logged out when we're querying the property */
+ continue;
+
+ return log_error_errno(r, "Failed to get linger status for user %s: %s",
+ user, bus_error_message(&error_property, r));
+ }
+
+ r = sd_bus_get_property_string(bus,
+ "org.freedesktop.login1",
+ object,
+ "org.freedesktop.login1.User",
+ "State",
+ &error_property,
+ &state);
+ if (r < 0) {
+ if (sd_bus_error_has_name(&error_property, SD_BUS_ERROR_UNKNOWN_OBJECT))
+ /* The user logged out when we're querying the property */
+ continue;
+
+ return log_error_errno(r, "Failed to get state for user %s: %s",
+ user, bus_error_message(&error_property, r));
+ }
r = table_add_many(table,
TABLE_UID, (uid_t) uid,
TABLE_STRING, user,
- TABLE_BOOLEAN, linger);
+ TABLE_BOOLEAN, linger,
+ TABLE_STRING, state);
if (r < 0)
return table_log_add_error(r);
}

View File

@ -0,0 +1,67 @@
From 327f02ddb69c6f908db86e250d240c1036b5c394 Mon Sep 17 00:00:00 2001
From: Mike Yuan <me@yhndnzj.com>
Date: Thu, 11 May 2023 13:17:59 +0800
Subject: [PATCH] loginctl: list-sessions: minor modernization
(cherry picked from commit 486f61a8c908d63c47625c352e456d80c88b4687)
Related: #2209912
---
src/login/loginctl.c | 37 +++++++++++++++++++------------------
1 file changed, 19 insertions(+), 18 deletions(-)
diff --git a/src/login/loginctl.c b/src/login/loginctl.c
index 8b72ebae57..9c21b97bb5 100644
--- a/src/login/loginctl.c
+++ b/src/login/loginctl.c
@@ -141,9 +141,9 @@ static int list_sessions(int argc, char *argv[], void *userdata) {
(void) table_set_align_percent(table, TABLE_HEADER_CELL(1), 100);
for (;;) {
- _cleanup_(sd_bus_error_free) sd_bus_error error_tty = SD_BUS_ERROR_NULL;
- _cleanup_(sd_bus_message_unrefp) sd_bus_message *reply_tty = NULL;
- const char *id, *user, *seat, *object, *tty = NULL;
+ _cleanup_(sd_bus_error_free) sd_bus_error error_property = SD_BUS_ERROR_NULL;
+ _cleanup_free_ char *tty = NULL;
+ const char *id, *user, *seat, *object;
uint32_t uid;
r = sd_bus_message_read(reply, "(susso)", &id, &uid, &user, &seat, &object);
@@ -152,21 +152,22 @@ static int list_sessions(int argc, char *argv[], void *userdata) {
if (r == 0)
break;
- r = sd_bus_get_property(
- bus,
- "org.freedesktop.login1",
- object,
- "org.freedesktop.login1.Session",
- "TTY",
- &error_tty,
- &reply_tty,
- "s");
- if (r < 0)
- log_warning_errno(r, "Failed to get TTY for session %s: %s", id, bus_error_message(&error_tty, r));
- else {
- r = sd_bus_message_read(reply_tty, "s", &tty);
- if (r < 0)
- return bus_log_parse_error(r);
+ r = sd_bus_get_property_string(bus,
+ "org.freedesktop.login1",
+ object,
+ "org.freedesktop.login1.Session",
+ "TTY",
+ &error_property,
+ &tty);
+ if (r < 0) {
+ if (sd_bus_error_has_name(&error_property, SD_BUS_ERROR_UNKNOWN_OBJECT))
+ /* The session is already closed when we're querying the property */
+ continue;
+
+ log_warning_errno(r, "Failed to get TTY for session %s, ignoring: %s",
+ id, bus_error_message(&error_property, r));
+
+ sd_bus_error_free(&error_property);
}
r = table_add_many(table,

View File

@ -0,0 +1,65 @@
From a6b868dd39b60199862e306a272b54d2ef617317 Mon Sep 17 00:00:00 2001
From: Mike Yuan <me@yhndnzj.com>
Date: Thu, 11 May 2023 13:21:37 +0800
Subject: [PATCH] loginctl: list-sessions: also show state
(cherry picked from commit 8b6c039a1ac73da006bfe9d5735515bba12ef3c4)
Related: #2209912
---
src/login/loginctl.c | 23 ++++++++++++++++++++---
1 file changed, 20 insertions(+), 3 deletions(-)
diff --git a/src/login/loginctl.c b/src/login/loginctl.c
index 9c21b97bb5..0bea31796d 100644
--- a/src/login/loginctl.c
+++ b/src/login/loginctl.c
@@ -132,7 +132,7 @@ static int list_sessions(int argc, char *argv[], void *userdata) {
if (r < 0)
return bus_log_parse_error(r);
- table = table_new("session", "uid", "user", "seat", "tty");
+ table = table_new("session", "uid", "user", "seat", "tty", "state");
if (!table)
return log_oom();
@@ -142,7 +142,7 @@ static int list_sessions(int argc, char *argv[], void *userdata) {
for (;;) {
_cleanup_(sd_bus_error_free) sd_bus_error error_property = SD_BUS_ERROR_NULL;
- _cleanup_free_ char *tty = NULL;
+ _cleanup_free_ char *tty = NULL, *state = NULL;
const char *id, *user, *seat, *object;
uint32_t uid;
@@ -170,12 +170,29 @@ static int list_sessions(int argc, char *argv[], void *userdata) {
sd_bus_error_free(&error_property);
}
+ r = sd_bus_get_property_string(bus,
+ "org.freedesktop.login1",
+ object,
+ "org.freedesktop.login1.Session",
+ "State",
+ &error_property,
+ &state);
+ if (r < 0) {
+ if (sd_bus_error_has_name(&error_property, SD_BUS_ERROR_UNKNOWN_OBJECT))
+ /* The session is already closed when we're querying the property */
+ continue;
+
+ return log_error_errno(r, "Failed to get state for session %s: %s",
+ id, bus_error_message(&error_property, r));
+ }
+
r = table_add_many(table,
TABLE_STRING, id,
TABLE_UID, (uid_t) uid,
TABLE_STRING, user,
TABLE_STRING, seat,
- TABLE_STRING, strna(tty));
+ TABLE_STRING, strna(tty),
+ TABLE_STRING, state);
if (r < 0)
return table_log_add_error(r);
}

View File

@ -0,0 +1,59 @@
From 89f043cce92c336105e1b36b9eac4ba3bd1333b9 Mon Sep 17 00:00:00 2001
From: Mike Yuan <me@yhndnzj.com>
Date: Mon, 15 May 2023 13:45:33 +0800
Subject: [PATCH] test: add test for state in loginctl list-{users,sessions}
(cherry picked from commit 306ff2e29798f571fba573577abaeb812f7e3166)
Related: #2209912
---
test/units/testsuite-35.sh | 18 ++++++++++++++----
1 file changed, 14 insertions(+), 4 deletions(-)
diff --git a/test/units/testsuite-35.sh b/test/units/testsuite-35.sh
index 85925f2471..c9b2417bb7 100755
--- a/test/units/testsuite-35.sh
+++ b/test/units/testsuite-35.sh
@@ -520,7 +520,7 @@ test_session_properties() {
/usr/lib/systemd/tests/manual/test-session-properties "/org/freedesktop/login1/session/_3${s?}"
}
-test_list_users() {
+test_list_users_sessions() {
if [[ ! -c /dev/tty2 ]]; then
echo "/dev/tty2 does not exist, skipping test ${FUNCNAME[0]}."
return
@@ -531,12 +531,22 @@ test_list_users() {
assert_eq "$(loginctl list-users --no-legend | awk '$2 == "logind-test-user" { print $1 }')" "$(id -ru logind-test-user)"
assert_eq "$(loginctl list-users --no-legend | awk '$2 == "logind-test-user" { print $3 }')" no
+ assert_eq "$(loginctl list-users --no-legend | awk '$2 == "logind-test-user" { print $4 }')" active
+ assert_eq "$(loginctl list-sessions --no-legend | awk '$3 == "logind-test-user" { print $6 }')" active
loginctl enable-linger logind-test-user
-
assert_eq "$(loginctl list-users --no-legend | awk '$2 == "logind-test-user" { print $3 }')" yes
-}
+ for s in $(loginctl list-sessions --no-legend | awk '$3 == "logind-test-user" { print $1 }'); do
+ loginctl terminate-session "$s"
+ done
+ if ! timeout 30 bash -c "while loginctl --no-legend | grep -q logind-test-user; do sleep 1; done"; then
+ echo "WARNING: session for logind-test-user still active, ignoring."
+ return
+ fi
+
+ assert_eq "$(loginctl list-users --no-legend | awk '$2 == "logind-test-user" { print $4 }')" lingering
+}
teardown_stop_idle_session() (
set +eux
@@ -585,7 +595,7 @@ test_sanity_check
test_session
test_lock_idle_action
test_session_properties
-test_list_users
+test_list_users_sessions
test_stop_idle_session
touch /testok

View File

@ -0,0 +1,45 @@
From 3d3681dd81ad5bbae8eab7c1b4487f97678cc875 Mon Sep 17 00:00:00 2001
From: Frantisek Sumsal <frantisek@sumsal.cz>
Date: Mon, 22 May 2023 15:08:29 +0200
Subject: [PATCH] test: add a missing session activation
Otherwise test_list_user_sessions() would fail unless ordered after
test_session(), which activates the session.
(cherry picked from commit 587ae50d5529d4f312cc95ce8f0ece688c9672dc)
Related: #2209912
---
test/units/testsuite-35.sh | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/test/units/testsuite-35.sh b/test/units/testsuite-35.sh
index c9b2417bb7..09009fc257 100755
--- a/test/units/testsuite-35.sh
+++ b/test/units/testsuite-35.sh
@@ -529,6 +529,9 @@ test_list_users_sessions() {
trap cleanup_session RETURN
create_session
+ # Activate the session
+ loginctl activate "$(loginctl --no-legend | awk '$3 == "logind-test-user" { print $1 }')"
+
assert_eq "$(loginctl list-users --no-legend | awk '$2 == "logind-test-user" { print $1 }')" "$(id -ru logind-test-user)"
assert_eq "$(loginctl list-users --no-legend | awk '$2 == "logind-test-user" { print $3 }')" no
assert_eq "$(loginctl list-users --no-legend | awk '$2 == "logind-test-user" { print $4 }')" active
@@ -586,6 +589,7 @@ EOF
: >/failed
setup_test_user
+test_list_users_sessions
test_enable_debug
test_properties
test_started
@@ -595,7 +599,6 @@ test_sanity_check
test_session
test_lock_idle_action
test_session_properties
-test_list_users_sessions
test_stop_idle_session
touch /testok

View File

@ -0,0 +1,57 @@
From f515f2a2182e98a93b669ea744b3809be883d7fa Mon Sep 17 00:00:00 2001
From: David Tardon <dtardon@redhat.com>
Date: Fri, 19 May 2023 14:21:44 +0200
Subject: [PATCH] test: extend test for loginctl list-*
(cherry picked from commit 98a155962d384ad2dd1cd11449a0143b5cfae8ef)
Related: #2209912
---
test/units/testsuite-35.sh | 17 ++++++++++++++---
1 file changed, 14 insertions(+), 3 deletions(-)
diff --git a/test/units/testsuite-35.sh b/test/units/testsuite-35.sh
index 09009fc257..c817bc82bb 100755
--- a/test/units/testsuite-35.sh
+++ b/test/units/testsuite-35.sh
@@ -520,7 +520,9 @@ test_session_properties() {
/usr/lib/systemd/tests/manual/test-session-properties "/org/freedesktop/login1/session/_3${s?}"
}
-test_list_users_sessions() {
+test_list_users_sessions_seats() {
+ local session seat
+
if [[ ! -c /dev/tty2 ]]; then
echo "/dev/tty2 does not exist, skipping test ${FUNCNAME[0]}."
return
@@ -532,10 +534,19 @@ test_list_users_sessions() {
# Activate the session
loginctl activate "$(loginctl --no-legend | awk '$3 == "logind-test-user" { print $1 }')"
+ session=$(loginctl list-sessions --no-legend | awk '$3 == "logind-test-user" { print $1 }')
+ : check that we got a valid session id
+ busctl get-property org.freedesktop.login1 "/org/freedesktop/login1/session/_3${session?}" org.freedesktop.login1.Session Id
+ assert_eq "$(loginctl list-sessions --no-legend | awk '$3 == "logind-test-user" { print $2 }')" "$(id -ru logind-test-user)"
+ seat=$(loginctl list-sessions --no-legend | awk '$3 == "logind-test-user" { print $4 }')
+ assert_eq "$(loginctl list-sessions --no-legend | awk '$3 == "logind-test-user" { print $5 }')" tty2
+ assert_eq "$(loginctl list-sessions --no-legend | awk '$3 == "logind-test-user" { print $6 }')" active
+
+ loginctl list-seats --no-legend | grep -Fwq "${seat?}"
+
assert_eq "$(loginctl list-users --no-legend | awk '$2 == "logind-test-user" { print $1 }')" "$(id -ru logind-test-user)"
assert_eq "$(loginctl list-users --no-legend | awk '$2 == "logind-test-user" { print $3 }')" no
assert_eq "$(loginctl list-users --no-legend | awk '$2 == "logind-test-user" { print $4 }')" active
- assert_eq "$(loginctl list-sessions --no-legend | awk '$3 == "logind-test-user" { print $6 }')" active
loginctl enable-linger logind-test-user
assert_eq "$(loginctl list-users --no-legend | awk '$2 == "logind-test-user" { print $3 }')" yes
@@ -589,7 +600,7 @@ EOF
: >/failed
setup_test_user
-test_list_users_sessions
+test_list_users_sessions_seats
test_enable_debug
test_properties
test_started

View File

@ -0,0 +1,66 @@
From d2a9e9536aa881c130af938ccdc444252fff6412 Mon Sep 17 00:00:00 2001
From: David Tardon <dtardon@redhat.com>
Date: Tue, 23 May 2023 10:48:15 +0200
Subject: [PATCH] loginctl: shorten variable name
(cherry picked from commit 86f128558d57586bd28c55eb63968eab3dc4b36e)
Related: #2209912
---
src/login/loginctl.c | 16 ++++++++--------
1 file changed, 8 insertions(+), 8 deletions(-)
diff --git a/src/login/loginctl.c b/src/login/loginctl.c
index 0bea31796d..fad09cbe55 100644
--- a/src/login/loginctl.c
+++ b/src/login/loginctl.c
@@ -141,7 +141,7 @@ static int list_sessions(int argc, char *argv[], void *userdata) {
(void) table_set_align_percent(table, TABLE_HEADER_CELL(1), 100);
for (;;) {
- _cleanup_(sd_bus_error_free) sd_bus_error error_property = SD_BUS_ERROR_NULL;
+ _cleanup_(sd_bus_error_free) sd_bus_error e = SD_BUS_ERROR_NULL;
_cleanup_free_ char *tty = NULL, *state = NULL;
const char *id, *user, *seat, *object;
uint32_t uid;
@@ -157,17 +157,17 @@ static int list_sessions(int argc, char *argv[], void *userdata) {
object,
"org.freedesktop.login1.Session",
"TTY",
- &error_property,
+ &e,
&tty);
if (r < 0) {
- if (sd_bus_error_has_name(&error_property, SD_BUS_ERROR_UNKNOWN_OBJECT))
+ if (sd_bus_error_has_name(&e, SD_BUS_ERROR_UNKNOWN_OBJECT))
/* The session is already closed when we're querying the property */
continue;
log_warning_errno(r, "Failed to get TTY for session %s, ignoring: %s",
- id, bus_error_message(&error_property, r));
+ id, bus_error_message(&e, r));
- sd_bus_error_free(&error_property);
+ sd_bus_error_free(&e);
}
r = sd_bus_get_property_string(bus,
@@ -175,15 +175,15 @@ static int list_sessions(int argc, char *argv[], void *userdata) {
object,
"org.freedesktop.login1.Session",
"State",
- &error_property,
+ &e,
&state);
if (r < 0) {
- if (sd_bus_error_has_name(&error_property, SD_BUS_ERROR_UNKNOWN_OBJECT))
+ if (sd_bus_error_has_name(&e, SD_BUS_ERROR_UNKNOWN_OBJECT))
/* The session is already closed when we're querying the property */
continue;
return log_error_errno(r, "Failed to get state for session %s: %s",
- id, bus_error_message(&error_property, r));
+ id, bus_error_message(&e, r));
}
r = table_add_many(table,

View File

@ -0,0 +1,150 @@
From f8a5e518f0bfd44b37d3b52a8e88e67ced716889 Mon Sep 17 00:00:00 2001
From: David Tardon <dtardon@redhat.com>
Date: Fri, 19 May 2023 13:33:58 +0200
Subject: [PATCH] loginctl: use bus_map_all_properties
(cherry picked from commit 5b7d1536d0c2ccf0b7688490f31c92c1e766ea44)
Related: #2209912
---
src/login/loginctl.c | 84 ++++++++++++++++++--------------------------
1 file changed, 34 insertions(+), 50 deletions(-)
diff --git a/src/login/loginctl.c b/src/login/loginctl.c
index fad09cbe55..9a09bfc82c 100644
--- a/src/login/loginctl.c
+++ b/src/login/loginctl.c
@@ -53,6 +53,27 @@ static OutputMode arg_output = OUTPUT_SHORT;
STATIC_DESTRUCTOR_REGISTER(arg_property, strv_freep);
+typedef struct SessionStatusInfo {
+ const char *id;
+ uid_t uid;
+ const char *name;
+ struct dual_timestamp timestamp;
+ unsigned vtnr;
+ const char *seat;
+ const char *tty;
+ const char *display;
+ bool remote;
+ const char *remote_host;
+ const char *remote_user;
+ const char *service;
+ pid_t leader;
+ const char *type;
+ const char *class;
+ const char *state;
+ const char *scope;
+ const char *desktop;
+} SessionStatusInfo;
+
static OutputFlags get_output_flags(void) {
return
@@ -114,6 +135,13 @@ static int show_table(Table *table, const char *word) {
}
static int list_sessions(int argc, char *argv[], void *userdata) {
+
+ static const struct bus_properties_map map[] = {
+ { "State", "s", NULL, offsetof(SessionStatusInfo, state) },
+ { "TTY", "s", NULL, offsetof(SessionStatusInfo, tty) },
+ {},
+ };
+
_cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
_cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL;
_cleanup_(table_unrefp) Table *table = NULL;
@@ -142,9 +170,10 @@ static int list_sessions(int argc, char *argv[], void *userdata) {
for (;;) {
_cleanup_(sd_bus_error_free) sd_bus_error e = SD_BUS_ERROR_NULL;
- _cleanup_free_ char *tty = NULL, *state = NULL;
const char *id, *user, *seat, *object;
uint32_t uid;
+ _cleanup_(sd_bus_message_unrefp) sd_bus_message *m = NULL;
+ SessionStatusInfo i = {};
r = sd_bus_message_read(reply, "(susso)", &id, &uid, &user, &seat, &object);
if (r < 0)
@@ -152,38 +181,14 @@ static int list_sessions(int argc, char *argv[], void *userdata) {
if (r == 0)
break;
- r = sd_bus_get_property_string(bus,
- "org.freedesktop.login1",
- object,
- "org.freedesktop.login1.Session",
- "TTY",
- &e,
- &tty);
+ r = bus_map_all_properties(bus, "org.freedesktop.login1", object, map, BUS_MAP_BOOLEAN_AS_BOOL, &e, &m, &i);
if (r < 0) {
if (sd_bus_error_has_name(&e, SD_BUS_ERROR_UNKNOWN_OBJECT))
/* The session is already closed when we're querying the property */
continue;
- log_warning_errno(r, "Failed to get TTY for session %s, ignoring: %s",
+ log_warning_errno(r, "Failed to get properties of session %s, ignoring: %s",
id, bus_error_message(&e, r));
-
- sd_bus_error_free(&e);
- }
-
- r = sd_bus_get_property_string(bus,
- "org.freedesktop.login1",
- object,
- "org.freedesktop.login1.Session",
- "State",
- &e,
- &state);
- if (r < 0) {
- if (sd_bus_error_has_name(&e, SD_BUS_ERROR_UNKNOWN_OBJECT))
- /* The session is already closed when we're querying the property */
- continue;
-
- return log_error_errno(r, "Failed to get state for session %s: %s",
- id, bus_error_message(&e, r));
}
r = table_add_many(table,
@@ -191,8 +196,8 @@ static int list_sessions(int argc, char *argv[], void *userdata) {
TABLE_UID, (uid_t) uid,
TABLE_STRING, user,
TABLE_STRING, seat,
- TABLE_STRING, strna(tty),
- TABLE_STRING, state);
+ TABLE_STRING, strna(i.tty),
+ TABLE_STRING, i.state);
if (r < 0)
return table_log_add_error(r);
}
@@ -375,27 +380,6 @@ static int show_unit_cgroup(sd_bus *bus, const char *interface, const char *unit
return 0;
}
-typedef struct SessionStatusInfo {
- const char *id;
- uid_t uid;
- const char *name;
- struct dual_timestamp timestamp;
- unsigned vtnr;
- const char *seat;
- const char *tty;
- const char *display;
- bool remote;
- const char *remote_host;
- const char *remote_user;
- const char *service;
- pid_t leader;
- const char *type;
- const char *class;
- const char *state;
- const char *scope;
- const char *desktop;
-} SessionStatusInfo;
-
typedef struct UserStatusInfo {
uid_t uid;
bool linger;

View File

@ -0,0 +1,96 @@
From b4e164914c66eb8aeb71170c1d7615589783f467 Mon Sep 17 00:00:00 2001
From: David Tardon <dtardon@redhat.com>
Date: Fri, 19 May 2023 14:03:09 +0200
Subject: [PATCH] loginctl: show session idle status in list-sessions
(cherry picked from commit 556723e738b96a5c2b2d45a96b87b7b80e0c5664)
Resolves: #2209912
---
src/login/loginctl.c | 31 +++++++++++++++++++++----------
test/units/testsuite-35.sh | 2 ++
2 files changed, 23 insertions(+), 10 deletions(-)
diff --git a/src/login/loginctl.c b/src/login/loginctl.c
index 9a09bfc82c..967ae230ab 100644
--- a/src/login/loginctl.c
+++ b/src/login/loginctl.c
@@ -72,6 +72,8 @@ typedef struct SessionStatusInfo {
const char *state;
const char *scope;
const char *desktop;
+ bool idle_hint;
+ dual_timestamp idle_hint_timestamp;
} SessionStatusInfo;
static OutputFlags get_output_flags(void) {
@@ -137,8 +139,10 @@ static int show_table(Table *table, const char *word) {
static int list_sessions(int argc, char *argv[], void *userdata) {
static const struct bus_properties_map map[] = {
- { "State", "s", NULL, offsetof(SessionStatusInfo, state) },
- { "TTY", "s", NULL, offsetof(SessionStatusInfo, tty) },
+ { "IdleHint", "b", NULL, offsetof(SessionStatusInfo, idle_hint) },
+ { "IdleSinceHintMonotonic", "t", NULL, offsetof(SessionStatusInfo, idle_hint_timestamp.monotonic) },
+ { "State", "s", NULL, offsetof(SessionStatusInfo, state) },
+ { "TTY", "s", NULL, offsetof(SessionStatusInfo, tty) },
{},
};
@@ -160,7 +164,7 @@ static int list_sessions(int argc, char *argv[], void *userdata) {
if (r < 0)
return bus_log_parse_error(r);
- table = table_new("session", "uid", "user", "seat", "tty", "state");
+ table = table_new("session", "uid", "user", "seat", "tty", "state", "idle", "since");
if (!table)
return log_oom();
@@ -183,12 +187,11 @@ static int list_sessions(int argc, char *argv[], void *userdata) {
r = bus_map_all_properties(bus, "org.freedesktop.login1", object, map, BUS_MAP_BOOLEAN_AS_BOOL, &e, &m, &i);
if (r < 0) {
- if (sd_bus_error_has_name(&e, SD_BUS_ERROR_UNKNOWN_OBJECT))
- /* The session is already closed when we're querying the property */
- continue;
-
- log_warning_errno(r, "Failed to get properties of session %s, ignoring: %s",
- id, bus_error_message(&e, r));
+ log_full_errno(sd_bus_error_has_name(&e, SD_BUS_ERROR_UNKNOWN_OBJECT) ? LOG_DEBUG : LOG_WARNING,
+ r,
+ "Failed to get properties of session %s, ignoring: %s",
+ id, bus_error_message(&e, r));
+ continue;
}
r = table_add_many(table,
@@ -197,7 +200,15 @@ static int list_sessions(int argc, char *argv[], void *userdata) {
TABLE_STRING, user,
TABLE_STRING, seat,
TABLE_STRING, strna(i.tty),
- TABLE_STRING, i.state);
+ TABLE_STRING, i.state,
+ TABLE_BOOLEAN, i.idle_hint);
+ if (r < 0)
+ return table_log_add_error(r);
+
+ if (i.idle_hint)
+ r = table_add_cell(table, NULL, TABLE_TIMESTAMP_RELATIVE, &i.idle_hint_timestamp.monotonic);
+ else
+ r = table_add_cell(table, NULL, TABLE_EMPTY, NULL);
if (r < 0)
return table_log_add_error(r);
}
diff --git a/test/units/testsuite-35.sh b/test/units/testsuite-35.sh
index c817bc82bb..1863c535a4 100755
--- a/test/units/testsuite-35.sh
+++ b/test/units/testsuite-35.sh
@@ -541,6 +541,8 @@ test_list_users_sessions_seats() {
seat=$(loginctl list-sessions --no-legend | awk '$3 == "logind-test-user" { print $4 }')
assert_eq "$(loginctl list-sessions --no-legend | awk '$3 == "logind-test-user" { print $5 }')" tty2
assert_eq "$(loginctl list-sessions --no-legend | awk '$3 == "logind-test-user" { print $6 }')" active
+ assert_eq "$(loginctl list-sessions --no-legend | awk '$3 == "logind-test-user" { print $7 }')" no
+ assert_eq "$(loginctl list-sessions --no-legend | awk '$3 == "logind-test-user" { print $8 }')" ''
loginctl list-seats --no-legend | grep -Fwq "${seat?}"

View File

@ -0,0 +1,184 @@
From 1cb097a7c664b253556b3b63b7899d76d7e4cba5 Mon Sep 17 00:00:00 2001
From: Mike Yuan <me@yhndnzj.com>
Date: Wed, 24 May 2023 19:42:03 +0800
Subject: [PATCH] loginctl: some modernizations
(cherry picked from commit c9443393b5a1e6f8941e04e2641135ab3936a8a0)
Related: #2209912
---
src/login/loginctl.c | 85 +++++++++++++++++++++++---------------------
1 file changed, 44 insertions(+), 41 deletions(-)
diff --git a/src/login/loginctl.c b/src/login/loginctl.c
index 967ae230ab..25e5787c11 100644
--- a/src/login/loginctl.c
+++ b/src/login/loginctl.c
@@ -57,7 +57,7 @@ typedef struct SessionStatusInfo {
const char *id;
uid_t uid;
const char *name;
- struct dual_timestamp timestamp;
+ dual_timestamp timestamp;
unsigned vtnr;
const char *seat;
const char *tty;
@@ -76,8 +76,36 @@ typedef struct SessionStatusInfo {
dual_timestamp idle_hint_timestamp;
} SessionStatusInfo;
-static OutputFlags get_output_flags(void) {
+typedef struct UserStatusInfo {
+ uid_t uid;
+ bool linger;
+ const char *name;
+ dual_timestamp timestamp;
+ const char *state;
+ char **sessions;
+ const char *display;
+ const char *slice;
+} UserStatusInfo;
+typedef struct SeatStatusInfo {
+ const char *id;
+ const char *active_session;
+ char **sessions;
+} SeatStatusInfo;
+
+static void user_status_info_done(UserStatusInfo *info) {
+ assert(info);
+
+ strv_free(info->sessions);
+}
+
+static void seat_status_info_done(SeatStatusInfo *info) {
+ assert(info);
+
+ strv_free(info->sessions);
+}
+
+static OutputFlags get_output_flags(void) {
return
FLAGS_SET(arg_print_flags, BUS_PRINT_PROPERTY_SHOW_EMPTY) * OUTPUT_SHOW_ALL |
(arg_full || !on_tty() || pager_have()) * OUTPUT_FULL_WIDTH |
@@ -86,8 +114,13 @@ static OutputFlags get_output_flags(void) {
static int get_session_path(sd_bus *bus, const char *session_id, sd_bus_error *error, char **path) {
_cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL;
- int r;
char *ans;
+ int r;
+
+ assert(bus);
+ assert(session_id);
+ assert(error);
+ assert(path);
r = bus_call_method(bus, bus_login_mgr, "GetSession", error, &reply, "s", session_id);
if (r < 0)
@@ -391,41 +424,13 @@ static int show_unit_cgroup(sd_bus *bus, const char *interface, const char *unit
return 0;
}
-typedef struct UserStatusInfo {
- uid_t uid;
- bool linger;
- const char *name;
- struct dual_timestamp timestamp;
- const char *state;
- char **sessions;
- const char *display;
- const char *slice;
-} UserStatusInfo;
-
-typedef struct SeatStatusInfo {
- const char *id;
- const char *active_session;
- char **sessions;
-} SeatStatusInfo;
-
-static void user_status_info_clear(UserStatusInfo *info) {
- if (info) {
- strv_free(info->sessions);
- zero(*info);
- }
-}
-
-static void seat_status_info_clear(SeatStatusInfo *info) {
- if (info) {
- strv_free(info->sessions);
- zero(*info);
- }
-}
-
static int prop_map_first_of_struct(sd_bus *bus, const char *member, sd_bus_message *m, sd_bus_error *error, void *userdata) {
const char *contents;
int r;
+ assert(bus);
+ assert(m);
+
r = sd_bus_message_peek_type(m, NULL, &contents);
if (r < 0)
return r;
@@ -473,7 +478,7 @@ static int prop_map_sessions_strv(sd_bus *bus, const char *member, sd_bus_messag
static int print_session_status_info(sd_bus *bus, const char *path, bool *new_line) {
- static const struct bus_properties_map map[] = {
+ static const struct bus_properties_map map[] = {
{ "Id", "s", NULL, offsetof(SessionStatusInfo, id) },
{ "Name", "s", NULL, offsetof(SessionStatusInfo, name) },
{ "TTY", "s", NULL, offsetof(SessionStatusInfo, tty) },
@@ -608,7 +613,7 @@ static int print_session_status_info(sd_bus *bus, const char *path, bool *new_li
static int print_user_status_info(sd_bus *bus, const char *path, bool *new_line) {
- static const struct bus_properties_map map[] = {
+ static const struct bus_properties_map map[] = {
{ "Name", "s", NULL, offsetof(UserStatusInfo, name) },
{ "Linger", "b", NULL, offsetof(UserStatusInfo, linger) },
{ "Slice", "s", NULL, offsetof(UserStatusInfo, slice) },
@@ -623,7 +628,7 @@ static int print_user_status_info(sd_bus *bus, const char *path, bool *new_line)
_cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
_cleanup_(sd_bus_message_unrefp) sd_bus_message *m = NULL;
- _cleanup_(user_status_info_clear) UserStatusInfo i = {};
+ _cleanup_(user_status_info_done) UserStatusInfo i = {};
int r;
r = bus_map_all_properties(bus, "org.freedesktop.login1", path, map, BUS_MAP_BOOLEAN_AS_BOOL, &error, &m, &i);
@@ -685,7 +690,7 @@ static int print_user_status_info(sd_bus *bus, const char *path, bool *new_line)
static int print_seat_status_info(sd_bus *bus, const char *path, bool *new_line) {
- static const struct bus_properties_map map[] = {
+ static const struct bus_properties_map map[] = {
{ "Id", "s", NULL, offsetof(SeatStatusInfo, id) },
{ "ActiveSession", "(so)", prop_map_first_of_struct, offsetof(SeatStatusInfo, active_session) },
{ "Sessions", "a(so)", prop_map_sessions_strv, offsetof(SeatStatusInfo, sessions) },
@@ -694,7 +699,7 @@ static int print_seat_status_info(sd_bus *bus, const char *path, bool *new_line)
_cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
_cleanup_(sd_bus_message_unrefp) sd_bus_message *m = NULL;
- _cleanup_(seat_status_info_clear) SeatStatusInfo i = {};
+ _cleanup_(seat_status_info_done) SeatStatusInfo i = {};
int r;
r = bus_map_all_properties(bus, "org.freedesktop.login1", path, map, 0, &error, &m, &i);
@@ -1009,7 +1014,6 @@ static int activate(int argc, char *argv[], void *userdata) {
}
for (int i = 1; i < argc; i++) {
-
r = bus_call_method(
bus,
bus_login_mgr,
@@ -1039,7 +1043,6 @@ static int kill_session(int argc, char *argv[], void *userdata) {
arg_kill_whom = "all";
for (int i = 1; i < argc; i++) {
-
r = bus_call_method(
bus,
bus_login_mgr,

View File

@ -0,0 +1,55 @@
From 0884a1675b2ad20fdf7f98849ad6592a10b893e4 Mon Sep 17 00:00:00 2001
From: Mike Yuan <me@yhndnzj.com>
Date: Thu, 25 May 2023 01:20:45 +0800
Subject: [PATCH] loginctl: list-sessions: fix timestamp for idle hint
Follow-up for 556723e738b96a5c2b2d45a96b87b7b80e0c5664
TABLE_TIMESTAMP_RELATIVE takes a realtime timestamp.
(cherry picked from commit be88af3d9646c8bd1aaea3d4a00520e97ee8674d)
Related: #2209912
---
src/login/loginctl.c | 14 +++++++-------
1 file changed, 7 insertions(+), 7 deletions(-)
diff --git a/src/login/loginctl.c b/src/login/loginctl.c
index 25e5787c11..598acf766d 100644
--- a/src/login/loginctl.c
+++ b/src/login/loginctl.c
@@ -73,7 +73,7 @@ typedef struct SessionStatusInfo {
const char *scope;
const char *desktop;
bool idle_hint;
- dual_timestamp idle_hint_timestamp;
+ usec_t idle_hint_timestamp;
} SessionStatusInfo;
typedef struct UserStatusInfo {
@@ -171,11 +171,11 @@ static int show_table(Table *table, const char *word) {
static int list_sessions(int argc, char *argv[], void *userdata) {
- static const struct bus_properties_map map[] = {
- { "IdleHint", "b", NULL, offsetof(SessionStatusInfo, idle_hint) },
- { "IdleSinceHintMonotonic", "t", NULL, offsetof(SessionStatusInfo, idle_hint_timestamp.monotonic) },
- { "State", "s", NULL, offsetof(SessionStatusInfo, state) },
- { "TTY", "s", NULL, offsetof(SessionStatusInfo, tty) },
+ static const struct bus_properties_map map[] = {
+ { "IdleHint", "b", NULL, offsetof(SessionStatusInfo, idle_hint) },
+ { "IdleSinceHint", "t", NULL, offsetof(SessionStatusInfo, idle_hint_timestamp) },
+ { "State", "s", NULL, offsetof(SessionStatusInfo, state) },
+ { "TTY", "s", NULL, offsetof(SessionStatusInfo, tty) },
{},
};
@@ -239,7 +239,7 @@ static int list_sessions(int argc, char *argv[], void *userdata) {
return table_log_add_error(r);
if (i.idle_hint)
- r = table_add_cell(table, NULL, TABLE_TIMESTAMP_RELATIVE, &i.idle_hint_timestamp.monotonic);
+ r = table_add_cell(table, NULL, TABLE_TIMESTAMP_RELATIVE, &i.idle_hint_timestamp);
else
r = table_add_cell(table, NULL, TABLE_EMPTY, NULL);
if (r < 0)

View File

@ -0,0 +1,103 @@
From 837b3a3ba22efd133c8b39e142994405cc1aa322 Mon Sep 17 00:00:00 2001
From: Mike Yuan <me@yhndnzj.com>
Date: Tue, 23 May 2023 18:27:05 +0800
Subject: [PATCH] loginctl: list-users: use bus_map_all_properties
(cherry picked from commit 8b0da9971afabd47e2e0b72be82dc37c06caabee)
Related: #2209912
---
src/login/loginctl.c | 58 ++++++++++++++++++--------------------------
1 file changed, 24 insertions(+), 34 deletions(-)
diff --git a/src/login/loginctl.c b/src/login/loginctl.c
index 598acf766d..98bb87bd87 100644
--- a/src/login/loginctl.c
+++ b/src/login/loginctl.c
@@ -254,6 +254,13 @@ static int list_sessions(int argc, char *argv[], void *userdata) {
}
static int list_users(int argc, char *argv[], void *userdata) {
+
+ static const struct bus_properties_map property_map[] = {
+ { "Linger", "b", NULL, offsetof(UserStatusInfo, linger) },
+ { "State", "s", NULL, offsetof(UserStatusInfo, state) },
+ {},
+ };
+
_cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
_cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL;
_cleanup_(table_unrefp) Table *table = NULL;
@@ -280,10 +287,10 @@ static int list_users(int argc, char *argv[], void *userdata) {
for (;;) {
_cleanup_(sd_bus_error_free) sd_bus_error error_property = SD_BUS_ERROR_NULL;
- _cleanup_free_ char *state = NULL;
+ _cleanup_(sd_bus_message_unrefp) sd_bus_message *reply_property = NULL;
+ _cleanup_(user_status_info_done) UserStatusInfo info = {};
const char *user, *object;
uint32_t uid;
- int linger;
r = sd_bus_message_read(reply, "(uso)", &uid, &user, &object);
if (r < 0)
@@ -291,44 +298,27 @@ static int list_users(int argc, char *argv[], void *userdata) {
if (r == 0)
break;
- r = sd_bus_get_property_trivial(bus,
- "org.freedesktop.login1",
- object,
- "org.freedesktop.login1.User",
- "Linger",
- &error_property,
- 'b',
- &linger);
+ r = bus_map_all_properties(bus,
+ "org.freedesktop.login1",
+ object,
+ property_map,
+ BUS_MAP_BOOLEAN_AS_BOOL,
+ &error_property,
+ &reply_property,
+ &info);
if (r < 0) {
- if (sd_bus_error_has_name(&error_property, SD_BUS_ERROR_UNKNOWN_OBJECT))
- /* The user logged out when we're querying the property */
- continue;
-
- return log_error_errno(r, "Failed to get linger status for user %s: %s",
- user, bus_error_message(&error_property, r));
- }
-
- r = sd_bus_get_property_string(bus,
- "org.freedesktop.login1",
- object,
- "org.freedesktop.login1.User",
- "State",
- &error_property,
- &state);
- if (r < 0) {
- if (sd_bus_error_has_name(&error_property, SD_BUS_ERROR_UNKNOWN_OBJECT))
- /* The user logged out when we're querying the property */
- continue;
-
- return log_error_errno(r, "Failed to get state for user %s: %s",
- user, bus_error_message(&error_property, r));
+ log_full_errno(sd_bus_error_has_name(&error_property, SD_BUS_ERROR_UNKNOWN_OBJECT) ? LOG_DEBUG : LOG_WARNING,
+ r,
+ "Failed to get properties of user %s, ignoring: %s",
+ user, bus_error_message(&error_property, r));
+ continue;
}
r = table_add_many(table,
TABLE_UID, (uid_t) uid,
TABLE_STRING, user,
- TABLE_BOOLEAN, linger,
- TABLE_STRING, state);
+ TABLE_BOOLEAN, info.linger,
+ TABLE_STRING, info.state);
if (r < 0)
return table_log_add_error(r);
}

View File

@ -0,0 +1,78 @@
From e9d8b5a3d251007444f7722e34cd43ca4c1d628b Mon Sep 17 00:00:00 2001
From: Mike Yuan <me@yhndnzj.com>
Date: Tue, 23 May 2023 18:54:30 +0800
Subject: [PATCH] loginctl: also show idle hint in session-status
(cherry picked from commit 82449055af97cf92466dbe132a89c9d889440c3d)
Related: #2209912
---
src/login/loginctl.c | 48 ++++++++++++++++++++++++++------------------
1 file changed, 29 insertions(+), 19 deletions(-)
diff --git a/src/login/loginctl.c b/src/login/loginctl.c
index 98bb87bd87..e2eda66da7 100644
--- a/src/login/loginctl.c
+++ b/src/login/loginctl.c
@@ -469,25 +469,27 @@ static int prop_map_sessions_strv(sd_bus *bus, const char *member, sd_bus_messag
static int print_session_status_info(sd_bus *bus, const char *path, bool *new_line) {
static const struct bus_properties_map map[] = {
- { "Id", "s", NULL, offsetof(SessionStatusInfo, id) },
- { "Name", "s", NULL, offsetof(SessionStatusInfo, name) },
- { "TTY", "s", NULL, offsetof(SessionStatusInfo, tty) },
- { "Display", "s", NULL, offsetof(SessionStatusInfo, display) },
- { "RemoteHost", "s", NULL, offsetof(SessionStatusInfo, remote_host) },
- { "RemoteUser", "s", NULL, offsetof(SessionStatusInfo, remote_user) },
- { "Service", "s", NULL, offsetof(SessionStatusInfo, service) },
- { "Desktop", "s", NULL, offsetof(SessionStatusInfo, desktop) },
- { "Type", "s", NULL, offsetof(SessionStatusInfo, type) },
- { "Class", "s", NULL, offsetof(SessionStatusInfo, class) },
- { "Scope", "s", NULL, offsetof(SessionStatusInfo, scope) },
- { "State", "s", NULL, offsetof(SessionStatusInfo, state) },
- { "VTNr", "u", NULL, offsetof(SessionStatusInfo, vtnr) },
- { "Leader", "u", NULL, offsetof(SessionStatusInfo, leader) },
- { "Remote", "b", NULL, offsetof(SessionStatusInfo, remote) },
- { "Timestamp", "t", NULL, offsetof(SessionStatusInfo, timestamp.realtime) },
- { "TimestampMonotonic", "t", NULL, offsetof(SessionStatusInfo, timestamp.monotonic) },
- { "User", "(uo)", prop_map_first_of_struct, offsetof(SessionStatusInfo, uid) },
- { "Seat", "(so)", prop_map_first_of_struct, offsetof(SessionStatusInfo, seat) },
+ { "Id", "s", NULL, offsetof(SessionStatusInfo, id) },
+ { "Name", "s", NULL, offsetof(SessionStatusInfo, name) },
+ { "TTY", "s", NULL, offsetof(SessionStatusInfo, tty) },
+ { "Display", "s", NULL, offsetof(SessionStatusInfo, display) },
+ { "RemoteHost", "s", NULL, offsetof(SessionStatusInfo, remote_host) },
+ { "RemoteUser", "s", NULL, offsetof(SessionStatusInfo, remote_user) },
+ { "Service", "s", NULL, offsetof(SessionStatusInfo, service) },
+ { "Desktop", "s", NULL, offsetof(SessionStatusInfo, desktop) },
+ { "Type", "s", NULL, offsetof(SessionStatusInfo, type) },
+ { "Class", "s", NULL, offsetof(SessionStatusInfo, class) },
+ { "Scope", "s", NULL, offsetof(SessionStatusInfo, scope) },
+ { "State", "s", NULL, offsetof(SessionStatusInfo, state) },
+ { "VTNr", "u", NULL, offsetof(SessionStatusInfo, vtnr) },
+ { "Leader", "u", NULL, offsetof(SessionStatusInfo, leader) },
+ { "Remote", "b", NULL, offsetof(SessionStatusInfo, remote) },
+ { "Timestamp", "t", NULL, offsetof(SessionStatusInfo, timestamp.realtime) },
+ { "TimestampMonotonic", "t", NULL, offsetof(SessionStatusInfo, timestamp.monotonic) },
+ { "IdleHint", "b", NULL, offsetof(SessionStatusInfo, idle_hint) },
+ { "IdleSinceHint", "t", NULL, offsetof(SessionStatusInfo, idle_hint_timestamp) },
+ { "User", "(uo)", prop_map_first_of_struct, offsetof(SessionStatusInfo, uid) },
+ { "Seat", "(so)", prop_map_first_of_struct, offsetof(SessionStatusInfo, seat) },
{}
};
@@ -578,6 +580,14 @@ static int print_session_status_info(sd_bus *bus, const char *path, bool *new_li
if (i.state)
printf("\t State: %s\n", i.state);
+ if (i.idle_hint && timestamp_is_set(i.idle_hint_timestamp))
+ printf("\t Idle: %s since %s (%s)\n",
+ yes_no(i.idle_hint),
+ FORMAT_TIMESTAMP(i.idle_hint_timestamp),
+ FORMAT_TIMESTAMP_RELATIVE(i.idle_hint_timestamp));
+ else
+ printf("\t Idle: %s\n", yes_no(i.idle_hint));
+
if (i.scope) {
printf("\t Unit: %s\n", i.scope);
show_unit_cgroup(bus, "org.freedesktop.systemd1.Scope", i.scope, i.leader);

View File

@ -0,0 +1,45 @@
From 0b4518d1f00543a25b5fc30a6203cd59c84cf8c4 Mon Sep 17 00:00:00 2001
From: Yu Watanabe <watanabe.yu+github@gmail.com>
Date: Sun, 7 May 2023 18:34:35 +0900
Subject: [PATCH] memory-util: make ArrayCleanup passed to array_cleanup()
const
Should not change any behavior, preparation for later commits.
(cherry picked from commit 3facdc7da8ad424a38ce9c673fbb94a41e070a7d)
Related: #2190226
---
src/basic/memory-util.h | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/src/basic/memory-util.h b/src/basic/memory-util.h
index 8d75befed5..eea9c0e92f 100644
--- a/src/basic/memory-util.h
+++ b/src/basic/memory-util.h
@@ -123,13 +123,13 @@ static inline void erase_char(char *p) {
}
/* An automatic _cleanup_-like logic for destroy arrays (i.e. pointers + size) when leaving scope */
-struct ArrayCleanup {
+typedef struct ArrayCleanup {
void **parray;
size_t *pn;
free_array_func_t pfunc;
-};
+} ArrayCleanup;
-static inline void array_cleanup(struct ArrayCleanup *c) {
+static inline void array_cleanup(const ArrayCleanup *c) {
assert(c);
assert(!c->parray == !c->pn);
@@ -147,7 +147,7 @@ static inline void array_cleanup(struct ArrayCleanup *c) {
}
#define CLEANUP_ARRAY(array, n, func) \
- _cleanup_(array_cleanup) _unused_ struct ArrayCleanup CONCATENATE(_cleanup_array_, UNIQ) = { \
+ _cleanup_(array_cleanup) _unused_ const ArrayCleanup CONCATENATE(_cleanup_array_, UNIQ) = { \
.parray = (void**) &(array), \
.pn = &(n), \
.pfunc = (free_array_func_t) ({ \

View File

@ -0,0 +1,87 @@
From 8d45c6b730d7c56e970708767301700397756b52 Mon Sep 17 00:00:00 2001
From: Yu Watanabe <watanabe.yu+github@gmail.com>
Date: Sun, 7 May 2023 18:37:13 +0900
Subject: [PATCH] static-destruct: several cleanups
No functional changes, preparation for later commits.
(cherry picked from commit 555ead898539183a435e18c6e1e4d5fb89499231)
Related: #2190226
---
src/basic/static-destruct.h | 42 ++++++++++++++++++-------------------
1 file changed, 21 insertions(+), 21 deletions(-)
diff --git a/src/basic/static-destruct.h b/src/basic/static-destruct.h
index 97baac7abb..4bc82889be 100644
--- a/src/basic/static-destruct.h
+++ b/src/basic/static-destruct.h
@@ -10,6 +10,21 @@
* feel a bit like the gcc cleanup attribute, but for static variables. Note that this does not work for static
* variables declared in .so's, as the list is private to the same linking unit. But maybe that's a good thing. */
+#define _common_static_destruct_attrs_ \
+ /* Older compilers don't know "retain" attribute. */ \
+ _Pragma("GCC diagnostic ignored \"-Wattributes\"") \
+ /* The actual destructor structure we place in a special section to find it. */ \
+ _section_("SYSTEMD_STATIC_DESTRUCT") \
+ /* Use pointer alignment, since that is apparently what gcc does for static variables. */ \
+ _alignptr_ \
+ /* Make sure this is not dropped from the image despite not being explicitly referenced. */ \
+ _used_ \
+ /* Prevent garbage collection by the linker. */ \
+ _retain_ \
+ /* Make sure that AddressSanitizer doesn't pad this variable: we want everything in this section
+ * packed next to each other so that we can enumerate it. */ \
+ _variable_no_sanitize_address_
+
typedef struct StaticDestructor {
void *data;
free_func_t destroy;
@@ -24,19 +39,7 @@ typedef struct StaticDestructor {
typeof(variable) *q = p; \
func(q); \
} \
- /* Older compilers don't know "retain" attribute. */ \
- _Pragma("GCC diagnostic ignored \"-Wattributes\"") \
- /* The actual destructor structure we place in a special section to find it. */ \
- _section_("SYSTEMD_STATIC_DESTRUCT") \
- /* Use pointer alignment, since that is apparently what gcc does for static variables. */ \
- _alignptr_ \
- /* Make sure this is not dropped from the image despite not being explicitly referenced. */ \
- _used_ \
- /* Prevent garbage collection by the linker. */ \
- _retain_ \
- /* Make sure that AddressSanitizer doesn't pad this variable: we want everything in this section
- * packed next to each other so that we can enumerate it. */ \
- _variable_no_sanitize_address_ \
+ _common_static_destruct_attrs_ \
static const StaticDestructor UNIQ_T(static_destructor_entry, uq) = { \
.data = &(variable), \
.destroy = UNIQ_T(static_destructor_wrapper, uq), \
@@ -44,20 +47,17 @@ typedef struct StaticDestructor {
/* Beginning and end of our section listing the destructors. We define these as weak as we want this to work
* even if no destructors are defined and the section is missing. */
-extern const struct StaticDestructor _weak_ __start_SYSTEMD_STATIC_DESTRUCT[];
-extern const struct StaticDestructor _weak_ __stop_SYSTEMD_STATIC_DESTRUCT[];
+extern const StaticDestructor _weak_ __start_SYSTEMD_STATIC_DESTRUCT[];
+extern const StaticDestructor _weak_ __stop_SYSTEMD_STATIC_DESTRUCT[];
/* The function to destroy everything. (Note that this must be static inline, as it's key that it remains in
* the same linking unit as the variables we want to destroy.) */
static inline void static_destruct(void) {
- const StaticDestructor *d;
-
if (!__start_SYSTEMD_STATIC_DESTRUCT)
return;
- d = ALIGN_PTR(__start_SYSTEMD_STATIC_DESTRUCT);
- while (d < __stop_SYSTEMD_STATIC_DESTRUCT) {
+ for (const StaticDestructor *d = ALIGN_PTR(__start_SYSTEMD_STATIC_DESTRUCT);
+ d < __stop_SYSTEMD_STATIC_DESTRUCT;
+ d = ALIGN_PTR(d + 1))
d->destroy(d->data);
- d = ALIGN_PTR(d + 1);
- }
}

View File

@ -0,0 +1,172 @@
From a8f31096dcd402b4c8d57c2a8f86b52146077ce3 Mon Sep 17 00:00:00 2001
From: Yu Watanabe <watanabe.yu+github@gmail.com>
Date: Tue, 9 May 2023 06:44:27 +0900
Subject: [PATCH] static-destruct: introduce STATIC_ARRAY_DESTRUCTOR_REGISTER()
(cherry picked from commit 9695b0c01bf3d4b260432fb6754c7fbe9173c7db)
Related: #2190226
---
src/basic/static-destruct.h | 50 ++++++++++++++++++++++++++++++---
src/test/test-static-destruct.c | 41 ++++++++++++++++++++++++---
2 files changed, 83 insertions(+), 8 deletions(-)
diff --git a/src/basic/static-destruct.h b/src/basic/static-destruct.h
index 4bc82889be..2ffc6516f8 100644
--- a/src/basic/static-destruct.h
+++ b/src/basic/static-destruct.h
@@ -4,6 +4,7 @@
#include "alloc-util.h"
#include "macro.h"
+#include "memory-util.h"
/* A framework for registering static variables that shall be freed on shutdown of a process. It's a bit like gcc's
* destructor attribute, but allows us to precisely schedule when we want to free the variables. This is supposed to
@@ -25,9 +26,24 @@
* packed next to each other so that we can enumerate it. */ \
_variable_no_sanitize_address_
-typedef struct StaticDestructor {
+typedef enum StaticDestructorType {
+ STATIC_DESTRUCTOR_SIMPLE,
+ STATIC_DESTRUCTOR_ARRAY,
+ _STATIC_DESTRUCTOR_TYPE_MAX,
+ _STATIC_DESTRUCTOR_INVALID = -EINVAL,
+} StaticDestructorType;
+
+typedef struct SimpleCleanup {
void *data;
free_func_t destroy;
+} SimpleCleanup;
+
+typedef struct StaticDestructor {
+ StaticDestructorType type;
+ union {
+ SimpleCleanup simple;
+ ArrayCleanup array;
+ };
} StaticDestructor;
#define STATIC_DESTRUCTOR_REGISTER(variable, func) \
@@ -41,10 +57,25 @@ typedef struct StaticDestructor {
} \
_common_static_destruct_attrs_ \
static const StaticDestructor UNIQ_T(static_destructor_entry, uq) = { \
- .data = &(variable), \
- .destroy = UNIQ_T(static_destructor_wrapper, uq), \
+ .type = STATIC_DESTRUCTOR_SIMPLE, \
+ .simple.data = &(variable), \
+ .simple.destroy = UNIQ_T(static_destructor_wrapper, uq), \
}
+#define STATIC_ARRAY_DESTRUCTOR_REGISTER(a, n, func) \
+ _STATIC_ARRAY_DESTRUCTOR_REGISTER(UNIQ, a, n, func)
+
+#define _STATIC_ARRAY_DESTRUCTOR_REGISTER(uq, a, n, func) \
+ /* Type-safety check */ \
+ _unused_ static void (* UNIQ_T(static_destructor_wrapper, uq))(typeof(a[0]) *x, size_t y) = (func); \
+ _common_static_destruct_attrs_ \
+ static const StaticDestructor UNIQ_T(static_destructor_entry, uq) = { \
+ .type = STATIC_DESTRUCTOR_ARRAY, \
+ .array.parray = (void**) &(a), \
+ .array.pn = &(n), \
+ .array.pfunc = (free_array_func_t) (func), \
+ };
+
/* Beginning and end of our section listing the destructors. We define these as weak as we want this to work
* even if no destructors are defined and the section is missing. */
extern const StaticDestructor _weak_ __start_SYSTEMD_STATIC_DESTRUCT[];
@@ -59,5 +90,16 @@ static inline void static_destruct(void) {
for (const StaticDestructor *d = ALIGN_PTR(__start_SYSTEMD_STATIC_DESTRUCT);
d < __stop_SYSTEMD_STATIC_DESTRUCT;
d = ALIGN_PTR(d + 1))
- d->destroy(d->data);
+ switch (d->type) {
+ case STATIC_DESTRUCTOR_SIMPLE:
+ d->simple.destroy(d->simple.data);
+ break;
+
+ case STATIC_DESTRUCTOR_ARRAY:
+ array_cleanup(&d->array);
+ break;
+
+ default:
+ assert_not_reached();
+ }
}
diff --git a/src/test/test-static-destruct.c b/src/test/test-static-destruct.c
index cb518ea362..ef8648f588 100644
--- a/src/test/test-static-destruct.c
+++ b/src/test/test-static-destruct.c
@@ -2,17 +2,38 @@
#include "alloc-util.h"
#include "static-destruct.h"
+#include "strv.h"
#include "tests.h"
static int foo = 0;
static int bar = 0;
static int baz = 0;
-static char* memory = NULL;
+static char *memory = NULL;
+static char **strings = NULL;
+static size_t n_strings = 0;
+static int *integers = NULL;
+static size_t n_integers = 0;
static void test_destroy(int *b) {
(*b)++;
}
+static void test_strings_destroy(char **array, size_t n) {
+ assert_se(n == 3);
+ assert_se(strv_equal(array, STRV_MAKE("a", "bbb", "ccc")));
+
+ strv_free(array);
+}
+
+static void test_integers_destroy(int *array, size_t n) {
+ assert_se(n == 10);
+
+ for (size_t i = 0; i < n; i++)
+ assert_se(array[i] == (int)(i * i));
+
+ free(array);
+}
+
STATIC_DESTRUCTOR_REGISTER(foo, test_destroy);
STATIC_DESTRUCTOR_REGISTER(bar, test_destroy);
STATIC_DESTRUCTOR_REGISTER(bar, test_destroy);
@@ -20,15 +41,27 @@ STATIC_DESTRUCTOR_REGISTER(baz, test_destroy);
STATIC_DESTRUCTOR_REGISTER(baz, test_destroy);
STATIC_DESTRUCTOR_REGISTER(baz, test_destroy);
STATIC_DESTRUCTOR_REGISTER(memory, freep);
+STATIC_ARRAY_DESTRUCTOR_REGISTER(strings, n_strings, test_strings_destroy);
+STATIC_ARRAY_DESTRUCTOR_REGISTER(integers, n_integers, test_integers_destroy);
TEST(static_destruct) {
+ assert_se(foo == 0 && bar == 0 && baz == 0);
assert_se(memory = strdup("hallo"));
+ assert_se(strings = strv_new("a", "bbb", "ccc"));
+ n_strings = strv_length(strings);
+ n_integers = 10;
+ assert_se(integers = new(int, n_integers));
+ for (size_t i = 0; i < n_integers; i++)
+ integers[i] = i * i;
- assert_se(foo == 0 && bar == 0 && baz == 0);
static_destruct();
- assert_se(foo == 1 && bar == 2 && baz == 3);
- assert_se(memory == NULL);
+ assert_se(foo == 1 && bar == 2 && baz == 3);
+ assert_se(!memory);
+ assert_se(!strings);
+ assert_se(n_strings == 0);
+ assert_se(!integers);
+ assert_se(n_integers == 0);
}
DEFINE_TEST_MAIN(LOG_INFO);

View File

@ -0,0 +1,40 @@
From 7ca6eafaa28848cb917a2cd4af78a9c85c3fd51a Mon Sep 17 00:00:00 2001
From: Yu Watanabe <watanabe.yu+github@gmail.com>
Date: Thu, 9 Mar 2023 13:14:12 +0900
Subject: [PATCH] macro: support the case that the number of elements has const
qualifier
Follow-up for 5716c27e1f52d2aba9dd02916c01d6271d9d0b16.
Addresses https://github.com/systemd/systemd/pull/26303#issuecomment-1460712007.
(cherry picked from commit b9872fe1ddb61a7f930c652887c04e2f82b43be4)
Related: #2190226
---
src/basic/macro.h | 10 ++++++----
1 file changed, 6 insertions(+), 4 deletions(-)
diff --git a/src/basic/macro.h b/src/basic/macro.h
index b977730e54..72a2c7267e 100644
--- a/src/basic/macro.h
+++ b/src/basic/macro.h
@@ -329,12 +329,14 @@ static inline int __coverity_check_and_return__(int condition) {
#endif
#endif
-#define _FOREACH_ARRAY(i, array, num, m, s) \
- for (typeof(num) m = (num); m > 0; m = 0) \
- for (typeof(array[0]) *s = (array), *i = s; s && i < s + m; i++)
+#define _FOREACH_ARRAY(i, array, num, m, end) \
+ for (typeof(array[0]) *i = (array), *end = ({ \
+ typeof(num) m = (num); \
+ (i && m > 0) ? i + m : NULL; \
+ }); end && i < end; i++)
#define FOREACH_ARRAY(i, array, num) \
- _FOREACH_ARRAY(i, array, num, UNIQ_T(m, UNIQ), UNIQ_T(s, UNIQ))
+ _FOREACH_ARRAY(i, array, num, UNIQ_T(m, UNIQ), UNIQ_T(end, UNIQ))
#define DEFINE_TRIVIAL_DESTRUCTOR(name, type, func) \
static inline void name(type *p) { \

View File

@ -0,0 +1,74 @@
From b663e9f1256c62fa0e1c0fb80e6cd4a3c055716d Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= <zbyszek@in.waw.pl>
Date: Wed, 28 Sep 2022 13:38:56 +0200
Subject: [PATCH] shared/generator: apply similar config reordering of
generated units
(cherry picked from commit ce37fb0d92ca8af31215c81b573ebaac81ed6fd2)
Related: #2190226
---
src/shared/generator.c | 18 ++++++++++++------
1 file changed, 12 insertions(+), 6 deletions(-)
diff --git a/src/shared/generator.c b/src/shared/generator.c
index 5d019f4f4e..4c684fc3e7 100644
--- a/src/shared/generator.c
+++ b/src/shared/generator.c
@@ -116,6 +116,7 @@ static int write_fsck_sysroot_service(
"[Unit]\n"
"Description=File System Check on %2$s\n"
"Documentation=man:%3$s(8)\n"
+ "\n"
"DefaultDependencies=no\n"
"BindsTo=%4$s\n"
"Conflicts=shutdown.target\n"
@@ -409,11 +410,13 @@ int generator_hook_up_mkswap(
"[Unit]\n"
"Description=Make Swap on %%f\n"
"Documentation=man:systemd-mkswap@.service(8)\n"
+ "\n"
"DefaultDependencies=no\n"
"BindsTo=%%i.device\n"
- "Conflicts=shutdown.target\n"
"After=%%i.device\n"
- "Before=shutdown.target %s\n"
+ "Before=%s\n"
+ "Conflicts=shutdown.target\n"
+ "Before=shutdown.target\n"
"\n"
"[Service]\n"
"Type=oneshot\n"
@@ -486,13 +489,15 @@ int generator_hook_up_mkfs(
"[Unit]\n"
"Description=Make File System on %%f\n"
"Documentation=man:systemd-makefs@.service(8)\n"
+ "\n"
"DefaultDependencies=no\n"
"BindsTo=%%i.device\n"
- "Conflicts=shutdown.target\n"
"After=%%i.device\n"
/* fsck might or might not be used, so let's be safe and order
* ourselves before both systemd-fsck@.service and the mount unit. */
- "Before=shutdown.target systemd-fsck@%%i.service %s\n"
+ "Before=systemd-fsck@%%i.service %s\n"
+ "Conflicts=shutdown.target\n"
+ "Before=shutdown.target\n"
"\n"
"[Service]\n"
"Type=oneshot\n"
@@ -624,11 +629,12 @@ int generator_write_cryptsetup_unit_section(
fprintf(f, "SourcePath=%s\n", source);
fprintf(f,
+ "\n"
"DefaultDependencies=no\n"
- "IgnoreOnIsolate=true\n"
"After=cryptsetup-pre.target systemd-udevd-kernel.socket\n"
"Before=blockdev@dev-mapper-%%i.target\n"
- "Wants=blockdev@dev-mapper-%%i.target\n");
+ "Wants=blockdev@dev-mapper-%%i.target\n"
+ "IgnoreOnIsolate=true\n");
return 0;
}

View File

@ -0,0 +1,34 @@
From 0770b3b7af5f11a65bc11307789c2ed45e5c8155 Mon Sep 17 00:00:00 2001
From: Yu Watanabe <watanabe.yu+github@gmail.com>
Date: Mon, 8 May 2023 20:06:33 +0900
Subject: [PATCH] nulstr-util: make ret_size in strv_make_nulstr() optional
(cherry picked from commit 16cda99c737714d6d259e45808e39f94408d90bd)
Related: #2190226
---
src/basic/strv.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/src/basic/strv.c b/src/basic/strv.c
index 24fc56a1a5..66b70befd6 100644
--- a/src/basic/strv.c
+++ b/src/basic/strv.c
@@ -706,7 +706,6 @@ int strv_make_nulstr(char * const *l, char **ret, size_t *ret_size) {
size_t n = 0;
assert(ret);
- assert(ret_size);
STRV_FOREACH(i, l) {
size_t z;
@@ -731,7 +730,8 @@ int strv_make_nulstr(char * const *l, char **ret, size_t *ret_size) {
assert(n > 0);
*ret = TAKE_PTR(m);
- *ret_size = n - 1;
+ if (ret_size)
+ *ret_size = n - 1;
return 0;
}

View File

@ -0,0 +1,105 @@
From d175d6d2260cd4b2116669953058fa9bef7ae478 Mon Sep 17 00:00:00 2001
From: Lennart Poettering <lennart@poettering.net>
Date: Sun, 16 Oct 2022 22:39:31 +0200
Subject: [PATCH] generator: teach generator_add_symlink() to instantiate
specified unit
if we want generators to instantiate a template service, we need to
teach generator_add_symlink() the concept.
Just some preparation for a later commit.
While we are at it, modernize the function around
path_extract_filename() + path_extract_directory()
(cherry picked from commit 0ba07f907721941f611eaca9521937c467bdfff2)
Related: #2190226
---
src/shared/generator.c | 51 ++++++++++++++++++++++++++++++++++--------
src/shared/generator.h | 6 ++++-
2 files changed, 47 insertions(+), 10 deletions(-)
diff --git a/src/shared/generator.c b/src/shared/generator.c
index 4c684fc3e7..6001b2778c 100644
--- a/src/shared/generator.c
+++ b/src/shared/generator.c
@@ -59,19 +59,52 @@ int generator_open_unit_file(
return 0;
}
-int generator_add_symlink(const char *dir, const char *dst, const char *dep_type, const char *src) {
- /* Adds a symlink from <dst>.<dep_type>/ to <src> (if src is absolute)
- * or ../<src> (otherwise). */
+int generator_add_symlink_full(
+ const char *dir,
+ const char *dst,
+ const char *dep_type,
+ const char *src,
+ const char *instance) {
+
+ _cleanup_free_ char *dn = NULL, *fn = NULL, *instantiated = NULL, *to = NULL, *from = NULL;
+ int r;
+
+ assert(dir);
+ assert(dst);
+ assert(dep_type);
+ assert(src);
+
+ /* Adds a symlink from <dst>.<dep_type>/ to <src> (if src is absolute) or ../<src> (otherwise). If
+ * <instance> is specified, then <src> must be a template unit name, and we'll instantiate it. */
- const char *from, *to;
+ r = path_extract_directory(src, &dn);
+ if (r < 0 && r != -EDESTADDRREQ) /* EDESTADDRREQ → just a file name was passed */
+ return log_error_errno(r, "Failed to extract directory name from '%s': %m", src);
- from = path_is_absolute(src) ? src : strjoina("../", src);
- to = strjoina(dir, "/", dst, ".", dep_type, "/", basename(src));
+ r = path_extract_filename(src, &fn);
+ if (r < 0)
+ return log_error_errno(r, "Failed to extract file name from '%s': %m", src);
+ if (r == O_DIRECTORY)
+ return log_error_errno(SYNTHETIC_ERRNO(EISDIR), "Expected path to regular file name, but got '%s', refusing.", src);
+
+ if (instance) {
+ r = unit_name_replace_instance(fn, instance, &instantiated);
+ if (r < 0)
+ return log_error_errno(r, "Failed to instantiate '%s' for '%s': %m", fn, instance);
+ }
+
+ from = path_join(dn ?: "..", fn);
+ if (!from)
+ return log_oom();
+
+ to = strjoin(dir, "/", dst, ".", dep_type, "/", instantiated ?: fn);
+ if (!to)
+ return log_oom();
(void) mkdir_parents_label(to, 0755);
- if (symlink(from, to) < 0)
- if (errno != EEXIST)
- return log_error_errno(errno, "Failed to create symlink \"%s\": %m", to);
+
+ if (symlink(from, to) < 0 && errno != EEXIST)
+ return log_error_errno(errno, "Failed to create symlink \"%s\": %m", to);
return 0;
}
diff --git a/src/shared/generator.h b/src/shared/generator.h
index 1b4f36ac53..a4049dbd8f 100644
--- a/src/shared/generator.h
+++ b/src/shared/generator.h
@@ -12,7 +12,11 @@ int generator_open_unit_file(
const char *name,
FILE **file);
-int generator_add_symlink(const char *dir, const char *dst, const char *dep_type, const char *src);
+int generator_add_symlink_full(const char *dir, const char *dst, const char *dep_type, const char *src, const char *instance);
+
+static inline int generator_add_symlink(const char *dir, const char *dst, const char *dep_type, const char *src) {
+ return generator_add_symlink_full(dir, dst, dep_type, src, NULL);
+}
int generator_write_fsck_deps(
FILE *f,

View File

@ -0,0 +1,270 @@
From 09fd7becfe7bd05ea354fdd9326cd6175ca7143d Mon Sep 17 00:00:00 2001
From: Lennart Poettering <lennart@poettering.net>
Date: Sun, 16 Oct 2022 22:45:17 +0200
Subject: [PATCH] units: rework growfs units to be just a regular unit that is
instantiated
The systemd-growfs@.service units are currently written in full for each
file system to grow. Which is kinda pointless given that (besides an
optional ordering dep) they contain always the same definition. Let's
fix that and add a static template for this logic, that the generator
simply instantiates (and adds an ordering dep for).
This mimics how systemd-fsck@.service is handled. Similar to the wait
that for root fs there's a special instance systemd-fsck-root.service
we also add a special instance systemd-growfs-root.service for the root
fs, since it has slightly different deps.
Fixes: #20788
See: #10014
(cherry picked from commit 50072ccf1bfee8a53563a083a3a52b26f0d5678f)
Related: #2190226
---
src/basic/special.h | 2 +
src/shared/generator.c | 126 ++++++++++++++++-----------
units/meson.build | 2 +
units/systemd-growfs-root.service.in | 22 +++++
units/systemd-growfs@.service.in | 23 +++++
5 files changed, 126 insertions(+), 49 deletions(-)
create mode 100644 units/systemd-growfs-root.service.in
create mode 100644 units/systemd-growfs@.service.in
diff --git a/src/basic/special.h b/src/basic/special.h
index 5d1111fd71..9bb36c5732 100644
--- a/src/basic/special.h
+++ b/src/basic/special.h
@@ -87,6 +87,8 @@
#define SPECIAL_REMOUNT_FS_SERVICE "systemd-remount-fs.service"
#define SPECIAL_VOLATILE_ROOT_SERVICE "systemd-volatile-root.service"
#define SPECIAL_UDEVD_SERVICE "systemd-udevd.service"
+#define SPECIAL_GROWFS_SERVICE "systemd-growfs@.service"
+#define SPECIAL_GROWFS_ROOT_SERVICE "systemd-growfs-root.service"
/* Services systemd relies on */
#define SPECIAL_DBUS_SERVICE "dbus.service"
diff --git a/src/shared/generator.c b/src/shared/generator.c
index 6001b2778c..5d617bbe99 100644
--- a/src/shared/generator.c
+++ b/src/shared/generator.c
@@ -109,6 +109,64 @@ int generator_add_symlink_full(
return 0;
}
+static int generator_add_ordering(
+ const char *dir,
+ const char *src,
+ const char *order,
+ const char *dst,
+ const char *instance) {
+
+ _cleanup_free_ char *instantiated = NULL, *p = NULL, *fn = NULL;
+ _cleanup_fclose_ FILE *f = NULL;
+ const char *to;
+ int r;
+
+ assert(dir);
+ assert(src);
+ assert(order);
+ assert(dst);
+
+ /* Adds in an explicit ordering dependency of type <order> from <src> to <dst>. If <instance> is
+ * specified, it is inserted into <dst>. */
+
+ if (instance) {
+ r = unit_name_replace_instance(dst, instance, &instantiated);
+ if (r < 0)
+ return log_error_errno(r, "Failed to instantiate '%s' for '%s': %m", dst, instance);
+
+ to = instantiated;
+ } else
+ to = dst;
+
+ fn = strjoin(src, ".d/50-order-", to, ".conf");
+ if (!fn)
+ return log_oom();
+
+ p = path_join(dir, fn);
+ if (!p)
+ return log_oom();
+
+ (void) mkdir_parents_label(p, 0755);
+
+ r = fopen_unlocked(p, "wxe", &f);
+ if (r < 0)
+ return log_error_errno(r, "Failed to create '%s': %m", p);
+
+ fprintf(f,
+ "# Automatically generated by %s\n\n"
+ "[Unit]\n"
+ "%s=%s\n",
+ program_invocation_short_name,
+ order,
+ to);
+
+ r = fflush_and_check(f);
+ if (r < 0)
+ return log_error_errno(r, "Failed to write drop-in '%s': %m", p);
+
+ return 0;
+}
+
static int write_fsck_sysroot_service(
const char *unit, /* Either SPECIAL_FSCK_ROOT_SERVICE or SPECIAL_FSCK_USR_SERVICE */
const char *dir,
@@ -555,66 +613,36 @@ int generator_hook_up_growfs(
const char *where,
const char *target) {
- _cleanup_free_ char *unit = NULL, *escaped = NULL, *where_unit = NULL, *unit_file = NULL;
- _cleanup_fclose_ FILE *f = NULL;
+ const char *growfs_unit, *growfs_unit_path;
+ _cleanup_free_ char *where_unit = NULL, *instance = NULL;
int r;
assert(dir);
assert(where);
- escaped = cescape(where);
- if (!escaped)
- return log_oom();
-
- r = unit_name_from_path_instance("systemd-growfs", where, ".service", &unit);
- if (r < 0)
- return log_error_errno(r, "Failed to make unit instance name from path \"%s\": %m",
- where);
-
r = unit_name_from_path(where, ".mount", &where_unit);
if (r < 0)
- return log_error_errno(r, "Failed to make unit name from path \"%s\": %m",
- where);
-
- unit_file = path_join(dir, unit);
- if (!unit_file)
- return log_oom();
-
- log_debug("Creating %s", unit_file);
-
- f = fopen(unit_file, "wxe");
- if (!f)
- return log_error_errno(errno, "Failed to create unit file %s: %m",
- unit_file);
+ return log_error_errno(r, "Failed to make unit name from path '%s': %m", where);
- fprintf(f,
- "# Automatically generated by %s\n\n"
- "[Unit]\n"
- "Description=Grow File System on %%f\n"
- "Documentation=man:systemd-growfs@.service(8)\n"
- "DefaultDependencies=no\n"
- "BindsTo=%%i.mount\n"
- "Conflicts=shutdown.target\n"
- "After=systemd-repart.service %%i.mount\n"
- "Before=shutdown.target%s%s\n",
- program_invocation_short_name,
- target ? " " : "",
- strempty(target));
+ if (empty_or_root(where)) {
+ growfs_unit = SPECIAL_GROWFS_ROOT_SERVICE;
+ growfs_unit_path = SYSTEM_DATA_UNIT_DIR "/" SPECIAL_GROWFS_ROOT_SERVICE;
+ } else {
+ growfs_unit = SPECIAL_GROWFS_SERVICE;
+ growfs_unit_path = SYSTEM_DATA_UNIT_DIR "/" SPECIAL_GROWFS_SERVICE;
- if (empty_or_root(where)) /* Make sure the root fs is actually writable before we resize it */
- fprintf(f,
- "After=systemd-remount-fs.service\n");
+ r = unit_name_path_escape(where, &instance);
+ if (r < 0)
+ return log_error_errno(r, "Failed to escape path '%s': %m", where);
+ }
- fprintf(f,
- "\n"
- "[Service]\n"
- "Type=oneshot\n"
- "RemainAfterExit=yes\n"
- "ExecStart="SYSTEMD_GROWFS_PATH " %s\n"
- "TimeoutSec=0\n",
- escaped);
+ if (target) {
+ r = generator_add_ordering(dir, target, "After", growfs_unit, instance);
+ if (r < 0)
+ return r;
+ }
- return generator_add_symlink(dir, where_unit, "wants", unit);
+ return generator_add_symlink_full(dir, where_unit, "wants", growfs_unit_path, instance);
}
int generator_enable_remount_fs_service(const char *dir) {
diff --git a/units/meson.build b/units/meson.build
index eae7394731..a99f27adc5 100644
--- a/units/meson.build
+++ b/units/meson.build
@@ -264,6 +264,8 @@ in_units = [
'sysinit.target.wants/'],
['systemd-pcrphase.service', 'HAVE_GNU_EFI HAVE_OPENSSL HAVE_TPM2',
'sysinit.target.wants/'],
+ ['systemd-growfs-root.service', ''],
+ ['systemd-growfs@.service', ''],
]
add_wants = []
diff --git a/units/systemd-growfs-root.service.in b/units/systemd-growfs-root.service.in
new file mode 100644
index 0000000000..295bafd5af
--- /dev/null
+++ b/units/systemd-growfs-root.service.in
@@ -0,0 +1,22 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
+#
+# This file is part of systemd.
+#
+# systemd is free software; you can redistribute it and/or modify it
+# under the terms of the GNU Lesser General Public License as published by
+# the Free Software Foundation; either version 2.1 of the License, or
+# (at your option) any later version.
+
+[Unit]
+Description=Grow Root File System
+Documentation=man:systemd-growfs-root.service(8)
+DefaultDependencies=no
+Conflicts=shutdown.target
+After=systemd-repart.service systemd-remount-fs.service
+Before=shutdown.target
+
+[Service]
+Type=oneshot
+RemainAfterExit=yes
+ExecStart={{ROOTLIBEXECDIR}}/systemd-growfs /
+TimeoutSec=0
diff --git a/units/systemd-growfs@.service.in b/units/systemd-growfs@.service.in
new file mode 100644
index 0000000000..7154e4ca76
--- /dev/null
+++ b/units/systemd-growfs@.service.in
@@ -0,0 +1,23 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
+#
+# This file is part of systemd.
+#
+# systemd is free software; you can redistribute it and/or modify it
+# under the terms of the GNU Lesser General Public License as published by
+# the Free Software Foundation; either version 2.1 of the License, or
+# (at your option) any later version.
+
+[Unit]
+Description=Grow File System on %f
+Documentation=man:systemd-growfs@.service(8)
+DefaultDependencies=no
+BindsTo=%i.mount
+Conflicts=shutdown.target
+After=systemd-repart.service %i.mount
+Before=shutdown.target
+
+[Service]
+Type=oneshot
+RemainAfterExit=yes
+ExecStart={{ROOTLIBEXECDIR}}/systemd-growfs %f
+TimeoutSec=0

View File

@ -0,0 +1,159 @@
From 2739a62abe692e9ca5792fc46f03cd4618a65000 Mon Sep 17 00:00:00 2001
From: Lily Foster <lily@lily.flowers>
Date: Wed, 25 Jan 2023 19:05:08 -0500
Subject: [PATCH] fstab-generator: use correct targets when /sysroot is
specificied in fstab only
(cherry picked from commit dfce61dda7b7b15b910221e5ca1673b371554368)
Related: #2190226
---
man/systemd-fstab-generator.xml | 7 ++-
src/fstab-generator/fstab-generator.c | 63 +++++++++++++++++++++------
2 files changed, 54 insertions(+), 16 deletions(-)
diff --git a/man/systemd-fstab-generator.xml b/man/systemd-fstab-generator.xml
index b7908377a4..30204f5d8a 100644
--- a/man/systemd-fstab-generator.xml
+++ b/man/systemd-fstab-generator.xml
@@ -81,12 +81,15 @@
<listitem><para>Configures the operating system's root filesystem to mount when running in the
initrd. This accepts a device node path (usually <filename>/dev/disk/by-uuid/…</filename> or
- <filename>/dev/disk/by-label/…</filename> or similar), or the special values <literal>gpt-auto</literal>
- and <literal>tmpfs</literal>.</para>
+ <filename>/dev/disk/by-label/…</filename> or similar), or the special values <literal>gpt-auto</literal>,
+ <literal>fstab</literal>, and <literal>tmpfs</literal>.</para>
<para>Use <literal>gpt-auto</literal> to explicitly request automatic root file system discovery via
<citerefentry><refentrytitle>systemd-gpt-auto-generator</refentrytitle><manvolnum>8</manvolnum></citerefentry>.</para>
+ <para>Use <literal>fstab</literal> to explicitly request automatic root file system discovery via
+ the initrd <filename>/etc/fstab</filename> rather than via kernel command line.</para>
+
<para>Use <literal>tmpfs</literal> in order to mount a <citerefentry
project='man-pages'><refentrytitle>tmpfs</refentrytitle><manvolnum>5</manvolnum></citerefentry> file
system as root file system of the OS. This is useful in combination with
diff --git a/src/fstab-generator/fstab-generator.c b/src/fstab-generator/fstab-generator.c
index e76de45a0f..9bf5f04d1d 100644
--- a/src/fstab-generator/fstab-generator.c
+++ b/src/fstab-generator/fstab-generator.c
@@ -633,6 +633,19 @@ static const char* sysroot_fstab_path(void) {
return getenv("SYSTEMD_SYSROOT_FSTAB") ?: "/sysroot/etc/fstab";
}
+static int add_sysusr_sysroot_usr_bind_mount(const char *source) {
+ return add_mount(source,
+ arg_dest,
+ "/sysusr/usr",
+ "/sysroot/usr",
+ NULL,
+ NULL,
+ "bind",
+ 0,
+ 0,
+ SPECIAL_INITRD_FS_TARGET);
+}
+
static int parse_fstab(bool initrd) {
_cleanup_endmntent_ FILE *f = NULL;
const char *fstab;
@@ -734,7 +747,7 @@ static int parse_fstab(bool initrd) {
if (streq(me->mnt_type, "swap"))
k = add_swap(fstab, what, me, flags);
else {
- bool rw_only, automount;
+ bool rw_only, automount, is_sysroot, is_sysroot_usr;
rw_only = fstab_test_option(me->mnt_opts, "x-systemd.rw-only\0");
automount = fstab_test_option(me->mnt_opts,
@@ -744,21 +757,43 @@ static int parse_fstab(bool initrd) {
flags |= rw_only * MOUNT_RW_ONLY |
automount * MOUNT_AUTOMOUNT;
+ is_sysroot = in_initrd() && path_equal(where, "/sysroot");
+ /* See comment from add_sysroot_usr_mount about the need for extra indirection
+ * in case /usr needs to be mounted in order for the root fs to be synthesized
+ * based on configuration included in /usr/, e.g. systemd-repart. */
+ is_sysroot_usr = in_initrd() && path_equal(where, "/sysroot/usr");
+
const char *target_unit =
initrd ? SPECIAL_INITRD_FS_TARGET :
+ is_sysroot ? SPECIAL_INITRD_ROOT_FS_TARGET :
+ is_sysroot_usr ? SPECIAL_INITRD_USR_FS_TARGET :
mount_is_network(me) ? SPECIAL_REMOTE_FS_TARGET :
SPECIAL_LOCAL_FS_TARGET;
+ if (is_sysroot && is_device_path(what)) {
+ r = generator_write_initrd_root_device_deps(arg_dest, what);
+ if (r < 0)
+ return r;
+ }
+
k = add_mount(fstab,
arg_dest,
what,
- canonical_where ?: where,
- canonical_where ? where: NULL,
+ is_sysroot_usr ? "/sysusr/usr" : canonical_where ?: where,
+ !is_sysroot_usr && canonical_where ? where : NULL,
me->mnt_type,
me->mnt_opts,
me->mnt_passno,
flags,
target_unit);
+
+ if (is_sysroot_usr && k >= 0) {
+ log_debug("Synthesizing fstab entry what=/sysusr/usr where=/sysroot/usr opts=bind");
+
+ r = add_sysusr_sysroot_usr_bind_mount(fstab);
+ if (r != 0)
+ k = r;
+ }
}
if (arg_sysroot_check && k > 0)
@@ -836,6 +871,10 @@ static int add_sysroot_mount(void) {
/* This is handled by gpt-auto-generator */
log_debug("Skipping root directory handling, as gpt-auto was requested.");
return 0;
+ } else if (streq(arg_root_what, "fstab")) {
+ /* This is handled by parse_fstab */
+ log_debug("Using initrd's fstab for /sysroot/ configuration.");
+ return 0;
}
r = sysroot_is_nfsroot();
@@ -951,6 +990,11 @@ static int add_sysroot_usr_mount(void) {
log_debug("Skipping /usr/ directory handling, as gpt-auto was requested.");
return 1; /* systemd-gpt-auto-generator will generate a unit for this, hence report that a
* unit file is being created for the host /usr/ mount. */
+ } else if (streq(arg_usr_what, "fstab")) {
+ /* This is handled by parse_fstab */
+ log_debug("Using initrd's fstab for /sysroot/usr/ configuration.");
+ return 1; /* parse_fstab will generate a unit for this, hence report that a
+ * unit file is being created for the host /usr/ mount. */
}
if (path_equal(arg_usr_what, "/dev/nfs")) {
@@ -992,18 +1036,9 @@ static int add_sysroot_usr_mount(void) {
if (r < 0)
return r;
- log_debug("Synthesizing entry what=/sysusr/usr where=/sysrootr/usr opts=bind");
+ log_debug("Synthesizing entry what=/sysusr/usr where=/sysroot/usr opts=bind");
- r = add_mount("/proc/cmdline",
- arg_dest,
- "/sysusr/usr",
- "/sysroot/usr",
- NULL,
- NULL,
- "bind",
- 0,
- 0,
- SPECIAL_INITRD_FS_TARGET);
+ r = add_sysusr_sysroot_usr_bind_mount("/proc/cmdline");
if (r < 0)
return r;

View File

@ -0,0 +1,70 @@
From 77a8682a6ee41a92aa1e07b557607c65e94d904b Mon Sep 17 00:00:00 2001
From: Lily Foster <lily@lily.flowers>
Date: Wed, 25 Jan 2023 18:52:06 -0500
Subject: [PATCH] fstab-generator: add SYSTEMD_SYSFS_CHECK env var
This forces processing of /dev entries in fstab when running in a
container is detected (checked as the existence of read-only /sys).
(cherry picked from commit 905dd992f8fbfe486e68808ce88e1662c970ab35)
Related: #2190226
---
docs/ENVIRONMENT.md | 4 ++++
src/fstab-generator/fstab-generator.c | 14 +++++++++++---
2 files changed, 15 insertions(+), 3 deletions(-)
diff --git a/docs/ENVIRONMENT.md b/docs/ENVIRONMENT.md
index 70fac2e361..f1a4692b59 100644
--- a/docs/ENVIRONMENT.md
+++ b/docs/ENVIRONMENT.md
@@ -54,6 +54,10 @@ All tools:
* `$SYSTEMD_SYSROOT_FSTAB` — if set, use this path instead of
`/sysroot/etc/fstab`. Only useful for debugging `systemd-fstab-generator`.
+* `$SYSTEMD_SYSFS_CHECK` — takes a boolean. If set, overrides sysfs container
+ detection that ignores `/dev/` entries in fstab. Only useful for debugging
+ `systemd-fstab-generator`.
+
* `$SYSTEMD_CRYPTTAB` — if set, use this path instead of `/etc/crypttab`. Only
useful for debugging. Currently only supported by
`systemd-cryptsetup-generator`.
diff --git a/src/fstab-generator/fstab-generator.c b/src/fstab-generator/fstab-generator.c
index 9bf5f04d1d..bbd669e477 100644
--- a/src/fstab-generator/fstab-generator.c
+++ b/src/fstab-generator/fstab-generator.c
@@ -8,6 +8,7 @@
#include "bus-error.h"
#include "bus-locator.h"
#include "chase-symlinks.h"
+#include "env-util.h"
#include "fd-util.h"
#include "fileio.h"
#include "fstab-util.h"
@@ -650,7 +651,7 @@ static int parse_fstab(bool initrd) {
_cleanup_endmntent_ FILE *f = NULL;
const char *fstab;
struct mntent *me;
- int r = 0;
+ int r = 0, sysfs_check = -1;
if (initrd)
fstab = sysroot_fstab_path();
@@ -688,8 +689,15 @@ static int parse_fstab(bool initrd) {
continue;
}
- if (is_device_path(what)) {
- log_info("Running in a container, ignoring fstab device entry for %s.", what);
+ if (sysfs_check < 0) {
+ r = getenv_bool_secure("SYSTEMD_SYSFS_CHECK");
+ if (r < 0 && r != -ENXIO)
+ log_debug_errno(r, "Failed to parse $SYSTEMD_SYSFS_CHECK, ignoring: %m");
+ sysfs_check = r != 0;
+ }
+
+ if (sysfs_check && is_device_path(what)) {
+ log_info("/sys/ is read-only (running in a container?), ignoring fstab device entry for %s.", what);
continue;
}
}

View File

@ -0,0 +1,155 @@
From 337826320020e4e1e8f6be62c3c65d5b157bb58d Mon Sep 17 00:00:00 2001
From: Lily Foster <lily@lily.flowers>
Date: Wed, 25 Jan 2023 18:52:30 -0500
Subject: [PATCH] test: add fstab file support for fstab-generator tests
(cherry picked from commit ef0c7ab6ac1ad2a38988fd4aa959aaa0408f2f4b)
Related: #2190226
---
test/test-fstab-generator.sh | 6 +++++-
.../initrd-fs.target.requires/sysroot-usr.mount | 0
.../50-root-device.conf | 5 +++++
.../initrd-root-fs.target.requires/sysroot.mount | 0
.../initrd-usr-fs.target.requires/sysroot.mount | 0
.../sysusr-usr.mount | 0
.../sysroot-usr.mount | 11 +++++++++++
.../sysroot.mount | 13 +++++++++++++
.../systemd-fsck-root.service | 16 ++++++++++++++++
.../sysusr-usr.mount | 11 +++++++++++
.../test-17-initrd-sysroot.fstab.input | 2 ++
11 files changed, 63 insertions(+), 1 deletion(-)
create mode 100644 test/test-fstab-generator/test-17-initrd-sysroot.fstab.expected/initrd-fs.target.requires/sysroot-usr.mount
create mode 100644 test/test-fstab-generator/test-17-initrd-sysroot.fstab.expected/initrd-root-device.target.d/50-root-device.conf
create mode 100644 test/test-fstab-generator/test-17-initrd-sysroot.fstab.expected/initrd-root-fs.target.requires/sysroot.mount
create mode 100644 test/test-fstab-generator/test-17-initrd-sysroot.fstab.expected/initrd-usr-fs.target.requires/sysroot.mount
create mode 100644 test/test-fstab-generator/test-17-initrd-sysroot.fstab.expected/initrd-usr-fs.target.requires/sysusr-usr.mount
create mode 100644 test/test-fstab-generator/test-17-initrd-sysroot.fstab.expected/sysroot-usr.mount
create mode 100644 test/test-fstab-generator/test-17-initrd-sysroot.fstab.expected/sysroot.mount
create mode 100644 test/test-fstab-generator/test-17-initrd-sysroot.fstab.expected/systemd-fsck-root.service
create mode 100644 test/test-fstab-generator/test-17-initrd-sysroot.fstab.expected/sysusr-usr.mount
create mode 100644 test/test-fstab-generator/test-17-initrd-sysroot.fstab.input
diff --git a/test/test-fstab-generator.sh b/test/test-fstab-generator.sh
index 7c060dfac7..c86914a107 100755
--- a/test/test-fstab-generator.sh
+++ b/test/test-fstab-generator.sh
@@ -26,7 +26,11 @@ for f in "$src"/test-*.input; do
trap "rm -rf '$out'" EXIT INT QUIT PIPE
# shellcheck disable=SC2046
- SYSTEMD_LOG_LEVEL=debug SYSTEMD_IN_INITRD=yes SYSTEMD_PROC_CMDLINE="fstab=no $(cat "$f")" $generator "$out" "$out" "$out"
+ if [[ "$f" == *.fstab.input ]]; then
+ SYSTEMD_LOG_LEVEL=debug SYSTEMD_IN_INITRD=yes SYSTEMD_SYSFS_CHECK=no SYSTEMD_PROC_CMDLINE="fstab=yes root=fstab" SYSTEMD_FSTAB="$f" SYSTEMD_SYSROOT_FSTAB="/dev/null" $generator "$out" "$out" "$out"
+ else
+ SYSTEMD_LOG_LEVEL=debug SYSTEMD_IN_INITRD=yes SYSTEMD_PROC_CMDLINE="fstab=no $(cat "$f")" $generator "$out" "$out" "$out"
+ fi
if [[ -f "$out"/systemd-fsck-root.service ]]; then
# For split-usr system
diff --git a/test/test-fstab-generator/test-17-initrd-sysroot.fstab.expected/initrd-fs.target.requires/sysroot-usr.mount b/test/test-fstab-generator/test-17-initrd-sysroot.fstab.expected/initrd-fs.target.requires/sysroot-usr.mount
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/test/test-fstab-generator/test-17-initrd-sysroot.fstab.expected/initrd-root-device.target.d/50-root-device.conf b/test/test-fstab-generator/test-17-initrd-sysroot.fstab.expected/initrd-root-device.target.d/50-root-device.conf
new file mode 100644
index 0000000000..47c4232223
--- /dev/null
+++ b/test/test-fstab-generator/test-17-initrd-sysroot.fstab.expected/initrd-root-device.target.d/50-root-device.conf
@@ -0,0 +1,5 @@
+# Automatically generated by systemd-fstab-generator
+
+[Unit]
+Requires=dev-sdx1.device
+After=dev-sdx1.device
diff --git a/test/test-fstab-generator/test-17-initrd-sysroot.fstab.expected/initrd-root-fs.target.requires/sysroot.mount b/test/test-fstab-generator/test-17-initrd-sysroot.fstab.expected/initrd-root-fs.target.requires/sysroot.mount
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/test/test-fstab-generator/test-17-initrd-sysroot.fstab.expected/initrd-usr-fs.target.requires/sysroot.mount b/test/test-fstab-generator/test-17-initrd-sysroot.fstab.expected/initrd-usr-fs.target.requires/sysroot.mount
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/test/test-fstab-generator/test-17-initrd-sysroot.fstab.expected/initrd-usr-fs.target.requires/sysusr-usr.mount b/test/test-fstab-generator/test-17-initrd-sysroot.fstab.expected/initrd-usr-fs.target.requires/sysusr-usr.mount
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/test/test-fstab-generator/test-17-initrd-sysroot.fstab.expected/sysroot-usr.mount b/test/test-fstab-generator/test-17-initrd-sysroot.fstab.expected/sysroot-usr.mount
new file mode 100644
index 0000000000..69be9c17d4
--- /dev/null
+++ b/test/test-fstab-generator/test-17-initrd-sysroot.fstab.expected/sysroot-usr.mount
@@ -0,0 +1,11 @@
+# Automatically generated by systemd-fstab-generator
+
+[Unit]
+Documentation=man:fstab(5) man:systemd-fstab-generator(8)
+SourcePath=/etc/fstab
+Before=initrd-fs.target
+
+[Mount]
+What=/sysusr/usr
+Where=/sysroot/usr
+Options=bind
diff --git a/test/test-fstab-generator/test-17-initrd-sysroot.fstab.expected/sysroot.mount b/test/test-fstab-generator/test-17-initrd-sysroot.fstab.expected/sysroot.mount
new file mode 100644
index 0000000000..0e8a701be9
--- /dev/null
+++ b/test/test-fstab-generator/test-17-initrd-sysroot.fstab.expected/sysroot.mount
@@ -0,0 +1,13 @@
+# Automatically generated by systemd-fstab-generator
+
+[Unit]
+Documentation=man:fstab(5) man:systemd-fstab-generator(8)
+SourcePath=/etc/fstab
+Before=initrd-root-fs.target
+Requires=systemd-fsck-root.service
+After=systemd-fsck-root.service
+After=blockdev@dev-sdx1.target
+
+[Mount]
+What=/dev/sdx1
+Where=/sysroot
diff --git a/test/test-fstab-generator/test-17-initrd-sysroot.fstab.expected/systemd-fsck-root.service b/test/test-fstab-generator/test-17-initrd-sysroot.fstab.expected/systemd-fsck-root.service
new file mode 100644
index 0000000000..7f914fdd14
--- /dev/null
+++ b/test/test-fstab-generator/test-17-initrd-sysroot.fstab.expected/systemd-fsck-root.service
@@ -0,0 +1,16 @@
+# Automatically generated by systemd-fstab-generator
+
+[Unit]
+Description=File System Check on /dev/sdx1
+Documentation=man:systemd-fsck-root.service(8)
+DefaultDependencies=no
+BindsTo=dev-sdx1.device
+Conflicts=shutdown.target
+After=initrd-root-device.target local-fs-pre.target dev-sdx1.device
+Before=shutdown.target
+
+[Service]
+Type=oneshot
+RemainAfterExit=yes
+ExecStart=/usr/lib/systemd/systemd-fsck /dev/sdx1
+TimeoutSec=0
diff --git a/test/test-fstab-generator/test-17-initrd-sysroot.fstab.expected/sysusr-usr.mount b/test/test-fstab-generator/test-17-initrd-sysroot.fstab.expected/sysusr-usr.mount
new file mode 100644
index 0000000000..63fcb10340
--- /dev/null
+++ b/test/test-fstab-generator/test-17-initrd-sysroot.fstab.expected/sysusr-usr.mount
@@ -0,0 +1,11 @@
+# Automatically generated by systemd-fstab-generator
+
+[Unit]
+Documentation=man:fstab(5) man:systemd-fstab-generator(8)
+SourcePath=/etc/fstab
+Before=initrd-usr-fs.target
+After=blockdev@dev-sdx2.target
+
+[Mount]
+What=/dev/sdx2
+Where=/sysusr/usr
diff --git a/test/test-fstab-generator/test-17-initrd-sysroot.fstab.input b/test/test-fstab-generator/test-17-initrd-sysroot.fstab.input
new file mode 100644
index 0000000000..1ba9b0624e
--- /dev/null
+++ b/test/test-fstab-generator/test-17-initrd-sysroot.fstab.input
@@ -0,0 +1,2 @@
+/dev/sdx1 /sysroot auto defaults 0 1
+/dev/sdx2 /sysroot/usr auto defaults 0 0

View File

@ -0,0 +1,345 @@
From 8a964936a2c117b3e6706781026a239dd5727975 Mon Sep 17 00:00:00 2001
From: Yu Watanabe <watanabe.yu+github@gmail.com>
Date: Fri, 12 May 2023 03:54:13 +0900
Subject: [PATCH] test-fstab-generator: also check file contents
Since e683878c0f03a4ffa123e37b27933fbf7e144901, only filenames are
checked. Let's check contents of generated unit files.
(cherry picked from commit 70bf9f62b9f3c46bb7d111342889bfac7c9ca45e)
Related: #2190226
---
test/test-fstab-generator.sh | 55 ++++++++++++++++---
.../sysroot.mount | 1 +
.../sysroot.mount | 1 +
.../systemd-fsck-root.service | 1 +
.../sysroot.mount | 1 +
.../sysroot.mount | 1 +
.../systemd-fsck-root.service | 1 +
.../sysroot.mount | 1 +
.../sysroot.mount | 1 +
.../systemd-fsck-root.service | 1 +
.../sysroot.mount | 1 +
.../sysroot.mount | 1 +
.../systemd-fsck-root.service | 1 +
.../sysroot.mount | 1 +
.../sysroot.mount | 1 +
.../sysroot-usr.mount | 1 +
.../sysroot.mount | 1 +
.../sysroot.mount | 1 +
.../sysusr-usr.mount | 1 +
.../systemd-fsck-root.service | 1 +
20 files changed, 67 insertions(+), 7 deletions(-)
mode change 100644 => 120000 test/test-fstab-generator/test-12-dev-sdx.expected/initrd-root-fs.target.requires/sysroot.mount
mode change 100644 => 120000 test/test-fstab-generator/test-12-dev-sdx.expected/initrd-usr-fs.target.requires/sysroot.mount
mode change 100644 => 120000 test/test-fstab-generator/test-13-label.expected/initrd-root-fs.target.requires/sysroot.mount
mode change 100644 => 120000 test/test-fstab-generator/test-13-label.expected/initrd-usr-fs.target.requires/sysroot.mount
mode change 100644 => 120000 test/test-fstab-generator/test-14-uuid.expected/initrd-root-fs.target.requires/sysroot.mount
mode change 100644 => 120000 test/test-fstab-generator/test-14-uuid.expected/initrd-usr-fs.target.requires/sysroot.mount
mode change 100644 => 120000 test/test-fstab-generator/test-15-partuuid.expected/initrd-root-fs.target.requires/sysroot.mount
mode change 100644 => 120000 test/test-fstab-generator/test-15-partuuid.expected/initrd-usr-fs.target.requires/sysroot.mount
mode change 100644 => 120000 test/test-fstab-generator/test-16-tmpfs.expected/initrd-root-fs.target.requires/sysroot.mount
mode change 100644 => 120000 test/test-fstab-generator/test-16-tmpfs.expected/initrd-usr-fs.target.requires/sysroot.mount
mode change 100644 => 120000 test/test-fstab-generator/test-17-initrd-sysroot.fstab.expected/initrd-fs.target.requires/sysroot-usr.mount
mode change 100644 => 120000 test/test-fstab-generator/test-17-initrd-sysroot.fstab.expected/initrd-root-fs.target.requires/sysroot.mount
mode change 100644 => 120000 test/test-fstab-generator/test-17-initrd-sysroot.fstab.expected/initrd-usr-fs.target.requires/sysroot.mount
mode change 100644 => 120000 test/test-fstab-generator/test-17-initrd-sysroot.fstab.expected/initrd-usr-fs.target.requires/sysusr-usr.mount
diff --git a/test/test-fstab-generator.sh b/test/test-fstab-generator.sh
index c86914a107..c844d0dae1 100755
--- a/test/test-fstab-generator.sh
+++ b/test/test-fstab-generator.sh
@@ -1,6 +1,8 @@
#!/usr/bin/env bash
# SPDX-License-Identifier: LGPL-2.1-or-later
set -e
+shopt -s nullglob
+shopt -s globstar
if [[ -n "$1" ]]; then
generator=$1
@@ -25,23 +27,62 @@ for f in "$src"/test-*.input; do
# shellcheck disable=SC2064
trap "rm -rf '$out'" EXIT INT QUIT PIPE
- # shellcheck disable=SC2046
- if [[ "$f" == *.fstab.input ]]; then
+ exp="${f%.input}.expected"
+
+ if [[ "${f##*/}" =~ \.fstab\.input ]]; then
SYSTEMD_LOG_LEVEL=debug SYSTEMD_IN_INITRD=yes SYSTEMD_SYSFS_CHECK=no SYSTEMD_PROC_CMDLINE="fstab=yes root=fstab" SYSTEMD_FSTAB="$f" SYSTEMD_SYSROOT_FSTAB="/dev/null" $generator "$out" "$out" "$out"
else
SYSTEMD_LOG_LEVEL=debug SYSTEMD_IN_INITRD=yes SYSTEMD_PROC_CMDLINE="fstab=no $(cat "$f")" $generator "$out" "$out" "$out"
fi
- if [[ -f "$out"/systemd-fsck-root.service ]]; then
- # For split-usr system
- sed -i -e 's:ExecStart=/lib/systemd/systemd-fsck:ExecStart=/usr/lib/systemd/systemd-fsck:' "$out"/systemd-fsck-root.service
+ # For split-usr system
+ for i in "$out"/systemd-*.service; do
+ sed -i -e 's:ExecStart=/lib/systemd/:ExecStart=/usr/lib/systemd/:' "$i"
+ done
+
+ if [[ "${f##*/}" =~ \.fstab\.input ]]; then
+ for i in "$out"/*.{automount,mount,swap}; do
+ sed -i -e 's:SourcePath=.*$:SourcePath=/etc/fstab:' "$i"
+ done
fi
- # We store empty files rather than symlinks, so that they don't get pruned when packaged up, so compare
+ # We store empty files rather than dead symlinks, so that they don't get pruned when packaged up, so compare
# the list of filenames rather than their content
- if ! diff -u <(find "$out" -printf '%P\n' | sort) <(find "${f%.input}.expected" -printf '%P\n' | sort); then
+ if ! diff -u <(find "$out" -printf '%P\n' | sort) <(find "$exp" -printf '%P\n' | sort); then
+ echo "**** Unexpected output for $f"
+ exit 1
+ fi
+
+ # Check the main units.
+ if ! diff -u "$out" "$exp"; then
echo "**** Unexpected output for $f"
exit 1
fi
+
+ # Also check drop-ins.
+ for i in "$out"/*; do
+ [[ -d "$i" ]] || continue
+
+ dir="${i##*/}"
+
+ for j in "$i"/*; do
+ fname="${j##*/}"
+ expf="$exp/$dir/$fname"
+
+ if [[ -L "$j" && ! -e "$j" ]]; then
+ # For dead symlink, we store an empty file.
+ if [[ ! -e "$expf" || -n "$(cat "$expf")" ]]; then
+ echo "**** Unexpected symlink $j created by $f"
+ exit 1
+ fi
+ continue
+ fi
+
+ if ! diff -u "$j" "$expf"; then
+ echo "**** Unexpected output in $j for $f"
+ exit 1
+ fi
+ done
+ done
) || exit 1
done
diff --git a/test/test-fstab-generator/test-12-dev-sdx.expected/initrd-root-fs.target.requires/sysroot.mount b/test/test-fstab-generator/test-12-dev-sdx.expected/initrd-root-fs.target.requires/sysroot.mount
deleted file mode 100644
index e69de29bb2..0000000000
diff --git a/test/test-fstab-generator/test-12-dev-sdx.expected/initrd-root-fs.target.requires/sysroot.mount b/test/test-fstab-generator/test-12-dev-sdx.expected/initrd-root-fs.target.requires/sysroot.mount
new file mode 120000
index 0000000000..0c969cdbd4
--- /dev/null
+++ b/test/test-fstab-generator/test-12-dev-sdx.expected/initrd-root-fs.target.requires/sysroot.mount
@@ -0,0 +1 @@
+../sysroot.mount
\ No newline at end of file
diff --git a/test/test-fstab-generator/test-12-dev-sdx.expected/initrd-usr-fs.target.requires/sysroot.mount b/test/test-fstab-generator/test-12-dev-sdx.expected/initrd-usr-fs.target.requires/sysroot.mount
deleted file mode 100644
index e69de29bb2..0000000000
diff --git a/test/test-fstab-generator/test-12-dev-sdx.expected/initrd-usr-fs.target.requires/sysroot.mount b/test/test-fstab-generator/test-12-dev-sdx.expected/initrd-usr-fs.target.requires/sysroot.mount
new file mode 120000
index 0000000000..0c969cdbd4
--- /dev/null
+++ b/test/test-fstab-generator/test-12-dev-sdx.expected/initrd-usr-fs.target.requires/sysroot.mount
@@ -0,0 +1 @@
+../sysroot.mount
\ No newline at end of file
diff --git a/test/test-fstab-generator/test-12-dev-sdx.expected/systemd-fsck-root.service b/test/test-fstab-generator/test-12-dev-sdx.expected/systemd-fsck-root.service
index 7f914fdd14..95d943b87a 100644
--- a/test/test-fstab-generator/test-12-dev-sdx.expected/systemd-fsck-root.service
+++ b/test/test-fstab-generator/test-12-dev-sdx.expected/systemd-fsck-root.service
@@ -3,6 +3,7 @@
[Unit]
Description=File System Check on /dev/sdx1
Documentation=man:systemd-fsck-root.service(8)
+
DefaultDependencies=no
BindsTo=dev-sdx1.device
Conflicts=shutdown.target
diff --git a/test/test-fstab-generator/test-13-label.expected/initrd-root-fs.target.requires/sysroot.mount b/test/test-fstab-generator/test-13-label.expected/initrd-root-fs.target.requires/sysroot.mount
deleted file mode 100644
index e69de29bb2..0000000000
diff --git a/test/test-fstab-generator/test-13-label.expected/initrd-root-fs.target.requires/sysroot.mount b/test/test-fstab-generator/test-13-label.expected/initrd-root-fs.target.requires/sysroot.mount
new file mode 120000
index 0000000000..0c969cdbd4
--- /dev/null
+++ b/test/test-fstab-generator/test-13-label.expected/initrd-root-fs.target.requires/sysroot.mount
@@ -0,0 +1 @@
+../sysroot.mount
\ No newline at end of file
diff --git a/test/test-fstab-generator/test-13-label.expected/initrd-usr-fs.target.requires/sysroot.mount b/test/test-fstab-generator/test-13-label.expected/initrd-usr-fs.target.requires/sysroot.mount
deleted file mode 100644
index e69de29bb2..0000000000
diff --git a/test/test-fstab-generator/test-13-label.expected/initrd-usr-fs.target.requires/sysroot.mount b/test/test-fstab-generator/test-13-label.expected/initrd-usr-fs.target.requires/sysroot.mount
new file mode 120000
index 0000000000..0c969cdbd4
--- /dev/null
+++ b/test/test-fstab-generator/test-13-label.expected/initrd-usr-fs.target.requires/sysroot.mount
@@ -0,0 +1 @@
+../sysroot.mount
\ No newline at end of file
diff --git a/test/test-fstab-generator/test-13-label.expected/systemd-fsck-root.service b/test/test-fstab-generator/test-13-label.expected/systemd-fsck-root.service
index a1327396ca..d6c59ff608 100644
--- a/test/test-fstab-generator/test-13-label.expected/systemd-fsck-root.service
+++ b/test/test-fstab-generator/test-13-label.expected/systemd-fsck-root.service
@@ -3,6 +3,7 @@
[Unit]
Description=File System Check on /dev/disk/by-label/Root
Documentation=man:systemd-fsck-root.service(8)
+
DefaultDependencies=no
BindsTo=dev-disk-by\x2dlabel-Root.device
Conflicts=shutdown.target
diff --git a/test/test-fstab-generator/test-14-uuid.expected/initrd-root-fs.target.requires/sysroot.mount b/test/test-fstab-generator/test-14-uuid.expected/initrd-root-fs.target.requires/sysroot.mount
deleted file mode 100644
index e69de29bb2..0000000000
diff --git a/test/test-fstab-generator/test-14-uuid.expected/initrd-root-fs.target.requires/sysroot.mount b/test/test-fstab-generator/test-14-uuid.expected/initrd-root-fs.target.requires/sysroot.mount
new file mode 120000
index 0000000000..0c969cdbd4
--- /dev/null
+++ b/test/test-fstab-generator/test-14-uuid.expected/initrd-root-fs.target.requires/sysroot.mount
@@ -0,0 +1 @@
+../sysroot.mount
\ No newline at end of file
diff --git a/test/test-fstab-generator/test-14-uuid.expected/initrd-usr-fs.target.requires/sysroot.mount b/test/test-fstab-generator/test-14-uuid.expected/initrd-usr-fs.target.requires/sysroot.mount
deleted file mode 100644
index e69de29bb2..0000000000
diff --git a/test/test-fstab-generator/test-14-uuid.expected/initrd-usr-fs.target.requires/sysroot.mount b/test/test-fstab-generator/test-14-uuid.expected/initrd-usr-fs.target.requires/sysroot.mount
new file mode 120000
index 0000000000..0c969cdbd4
--- /dev/null
+++ b/test/test-fstab-generator/test-14-uuid.expected/initrd-usr-fs.target.requires/sysroot.mount
@@ -0,0 +1 @@
+../sysroot.mount
\ No newline at end of file
diff --git a/test/test-fstab-generator/test-14-uuid.expected/systemd-fsck-root.service b/test/test-fstab-generator/test-14-uuid.expected/systemd-fsck-root.service
index 5945560287..cd9583c4dd 100644
--- a/test/test-fstab-generator/test-14-uuid.expected/systemd-fsck-root.service
+++ b/test/test-fstab-generator/test-14-uuid.expected/systemd-fsck-root.service
@@ -3,6 +3,7 @@
[Unit]
Description=File System Check on /dev/disk/by-uuid/3f5ad593-4546-4a94-a374-bcfb68aa11f7
Documentation=man:systemd-fsck-root.service(8)
+
DefaultDependencies=no
BindsTo=dev-disk-by\x2duuid-3f5ad593\x2d4546\x2d4a94\x2da374\x2dbcfb68aa11f7.device
Conflicts=shutdown.target
diff --git a/test/test-fstab-generator/test-15-partuuid.expected/initrd-root-fs.target.requires/sysroot.mount b/test/test-fstab-generator/test-15-partuuid.expected/initrd-root-fs.target.requires/sysroot.mount
deleted file mode 100644
index e69de29bb2..0000000000
diff --git a/test/test-fstab-generator/test-15-partuuid.expected/initrd-root-fs.target.requires/sysroot.mount b/test/test-fstab-generator/test-15-partuuid.expected/initrd-root-fs.target.requires/sysroot.mount
new file mode 120000
index 0000000000..0c969cdbd4
--- /dev/null
+++ b/test/test-fstab-generator/test-15-partuuid.expected/initrd-root-fs.target.requires/sysroot.mount
@@ -0,0 +1 @@
+../sysroot.mount
\ No newline at end of file
diff --git a/test/test-fstab-generator/test-15-partuuid.expected/initrd-usr-fs.target.requires/sysroot.mount b/test/test-fstab-generator/test-15-partuuid.expected/initrd-usr-fs.target.requires/sysroot.mount
deleted file mode 100644
index e69de29bb2..0000000000
diff --git a/test/test-fstab-generator/test-15-partuuid.expected/initrd-usr-fs.target.requires/sysroot.mount b/test/test-fstab-generator/test-15-partuuid.expected/initrd-usr-fs.target.requires/sysroot.mount
new file mode 120000
index 0000000000..0c969cdbd4
--- /dev/null
+++ b/test/test-fstab-generator/test-15-partuuid.expected/initrd-usr-fs.target.requires/sysroot.mount
@@ -0,0 +1 @@
+../sysroot.mount
\ No newline at end of file
diff --git a/test/test-fstab-generator/test-15-partuuid.expected/systemd-fsck-root.service b/test/test-fstab-generator/test-15-partuuid.expected/systemd-fsck-root.service
index aa1d455ecd..650ed8070a 100644
--- a/test/test-fstab-generator/test-15-partuuid.expected/systemd-fsck-root.service
+++ b/test/test-fstab-generator/test-15-partuuid.expected/systemd-fsck-root.service
@@ -3,6 +3,7 @@
[Unit]
Description=File System Check on /dev/disk/by-partuuid/3f5ad593-4546-4a94-a374-bcfb68aa11f7
Documentation=man:systemd-fsck-root.service(8)
+
DefaultDependencies=no
BindsTo=dev-disk-by\x2dpartuuid-3f5ad593\x2d4546\x2d4a94\x2da374\x2dbcfb68aa11f7.device
Conflicts=shutdown.target
diff --git a/test/test-fstab-generator/test-16-tmpfs.expected/initrd-root-fs.target.requires/sysroot.mount b/test/test-fstab-generator/test-16-tmpfs.expected/initrd-root-fs.target.requires/sysroot.mount
deleted file mode 100644
index e69de29bb2..0000000000
diff --git a/test/test-fstab-generator/test-16-tmpfs.expected/initrd-root-fs.target.requires/sysroot.mount b/test/test-fstab-generator/test-16-tmpfs.expected/initrd-root-fs.target.requires/sysroot.mount
new file mode 120000
index 0000000000..0c969cdbd4
--- /dev/null
+++ b/test/test-fstab-generator/test-16-tmpfs.expected/initrd-root-fs.target.requires/sysroot.mount
@@ -0,0 +1 @@
+../sysroot.mount
\ No newline at end of file
diff --git a/test/test-fstab-generator/test-16-tmpfs.expected/initrd-usr-fs.target.requires/sysroot.mount b/test/test-fstab-generator/test-16-tmpfs.expected/initrd-usr-fs.target.requires/sysroot.mount
deleted file mode 100644
index e69de29bb2..0000000000
diff --git a/test/test-fstab-generator/test-16-tmpfs.expected/initrd-usr-fs.target.requires/sysroot.mount b/test/test-fstab-generator/test-16-tmpfs.expected/initrd-usr-fs.target.requires/sysroot.mount
new file mode 120000
index 0000000000..0c969cdbd4
--- /dev/null
+++ b/test/test-fstab-generator/test-16-tmpfs.expected/initrd-usr-fs.target.requires/sysroot.mount
@@ -0,0 +1 @@
+../sysroot.mount
\ No newline at end of file
diff --git a/test/test-fstab-generator/test-17-initrd-sysroot.fstab.expected/initrd-fs.target.requires/sysroot-usr.mount b/test/test-fstab-generator/test-17-initrd-sysroot.fstab.expected/initrd-fs.target.requires/sysroot-usr.mount
deleted file mode 100644
index e69de29bb2..0000000000
diff --git a/test/test-fstab-generator/test-17-initrd-sysroot.fstab.expected/initrd-fs.target.requires/sysroot-usr.mount b/test/test-fstab-generator/test-17-initrd-sysroot.fstab.expected/initrd-fs.target.requires/sysroot-usr.mount
new file mode 120000
index 0000000000..8bcbb16eae
--- /dev/null
+++ b/test/test-fstab-generator/test-17-initrd-sysroot.fstab.expected/initrd-fs.target.requires/sysroot-usr.mount
@@ -0,0 +1 @@
+../sysroot-usr.mount
\ No newline at end of file
diff --git a/test/test-fstab-generator/test-17-initrd-sysroot.fstab.expected/initrd-root-fs.target.requires/sysroot.mount b/test/test-fstab-generator/test-17-initrd-sysroot.fstab.expected/initrd-root-fs.target.requires/sysroot.mount
deleted file mode 100644
index e69de29bb2..0000000000
diff --git a/test/test-fstab-generator/test-17-initrd-sysroot.fstab.expected/initrd-root-fs.target.requires/sysroot.mount b/test/test-fstab-generator/test-17-initrd-sysroot.fstab.expected/initrd-root-fs.target.requires/sysroot.mount
new file mode 120000
index 0000000000..0c969cdbd4
--- /dev/null
+++ b/test/test-fstab-generator/test-17-initrd-sysroot.fstab.expected/initrd-root-fs.target.requires/sysroot.mount
@@ -0,0 +1 @@
+../sysroot.mount
\ No newline at end of file
diff --git a/test/test-fstab-generator/test-17-initrd-sysroot.fstab.expected/initrd-usr-fs.target.requires/sysroot.mount b/test/test-fstab-generator/test-17-initrd-sysroot.fstab.expected/initrd-usr-fs.target.requires/sysroot.mount
deleted file mode 100644
index e69de29bb2..0000000000
diff --git a/test/test-fstab-generator/test-17-initrd-sysroot.fstab.expected/initrd-usr-fs.target.requires/sysroot.mount b/test/test-fstab-generator/test-17-initrd-sysroot.fstab.expected/initrd-usr-fs.target.requires/sysroot.mount
new file mode 120000
index 0000000000..0c969cdbd4
--- /dev/null
+++ b/test/test-fstab-generator/test-17-initrd-sysroot.fstab.expected/initrd-usr-fs.target.requires/sysroot.mount
@@ -0,0 +1 @@
+../sysroot.mount
\ No newline at end of file
diff --git a/test/test-fstab-generator/test-17-initrd-sysroot.fstab.expected/initrd-usr-fs.target.requires/sysusr-usr.mount b/test/test-fstab-generator/test-17-initrd-sysroot.fstab.expected/initrd-usr-fs.target.requires/sysusr-usr.mount
deleted file mode 100644
index e69de29bb2..0000000000
diff --git a/test/test-fstab-generator/test-17-initrd-sysroot.fstab.expected/initrd-usr-fs.target.requires/sysusr-usr.mount b/test/test-fstab-generator/test-17-initrd-sysroot.fstab.expected/initrd-usr-fs.target.requires/sysusr-usr.mount
new file mode 120000
index 0000000000..8fb2e18647
--- /dev/null
+++ b/test/test-fstab-generator/test-17-initrd-sysroot.fstab.expected/initrd-usr-fs.target.requires/sysusr-usr.mount
@@ -0,0 +1 @@
+../sysusr-usr.mount
\ No newline at end of file
diff --git a/test/test-fstab-generator/test-17-initrd-sysroot.fstab.expected/systemd-fsck-root.service b/test/test-fstab-generator/test-17-initrd-sysroot.fstab.expected/systemd-fsck-root.service
index 7f914fdd14..95d943b87a 100644
--- a/test/test-fstab-generator/test-17-initrd-sysroot.fstab.expected/systemd-fsck-root.service
+++ b/test/test-fstab-generator/test-17-initrd-sysroot.fstab.expected/systemd-fsck-root.service
@@ -3,6 +3,7 @@
[Unit]
Description=File System Check on /dev/sdx1
Documentation=man:systemd-fsck-root.service(8)
+
DefaultDependencies=no
BindsTo=dev-sdx1.device
Conflicts=shutdown.target

View File

@ -0,0 +1,667 @@
From 9afc07262dd2b37a20094909ab0a8cddb29cefc8 Mon Sep 17 00:00:00 2001
From: Yu Watanabe <watanabe.yu+github@gmail.com>
Date: Fri, 19 May 2023 09:31:51 +0900
Subject: [PATCH] test-fstab-generator: add tests for mount options
(cherry picked from commit 82c29dbee0ae4c438d25482083facc75f84bc5ee)
Related: #2190226
---
test/test-fstab-generator.sh | 9 +++++++++
.../foo.service.requires/mnt-requiredby.mount | 1 +
.../foo.service.wants/mnt-wantedby.mount | 1 +
.../50-root-device.conf | 5 +++++
.../sysroot.mount | 1 +
.../sysroot.mount | 1 +
...rder-systemd-growfs@mnt-growfs.service.conf | 4 ++++
.../local-fs.target.requires/mnt-after.mount | 1 +
.../mnt-automount1.automount | 1 +
.../local-fs.target.requires/mnt-before.mount | 1 +
.../local-fs.target.requires/mnt-growfs.mount | 1 +
.../local-fs.target.requires/mnt-mkfs.mount | 1 +
.../local-fs.target.requires/mnt-pcrfs.mount | 1 +
.../mnt-reqmounts.mount | 1 +
.../mnt-requires.mount | 1 +
.../local-fs.target.requires/mnt-rwonly.mount | 1 +
.../local-fs.target.requires/mnt-timeout.mount | 1 +
.../mnt-automount2.automount | 1 +
.../local-fs.target.wants/mnt-nofail.mount | 1 +
.../mnt-after.mount | 13 +++++++++++++
.../mnt-automount1.automount | 9 +++++++++
.../mnt-automount1.mount | 12 ++++++++++++
.../mnt-automount2.automount | 8 ++++++++
.../mnt-automount2.mount | 11 +++++++++++
.../mnt-before.mount | 13 +++++++++++++
.../mnt-growfs.mount | 12 ++++++++++++
.../systemd-growfs@mnt-growfs.service | 0
.../mnt-mkfs.mount | 13 +++++++++++++
.../systemd-makefs@dev-sdx12.service | 1 +
.../mnt-noauto.mount | 12 ++++++++++++
.../mnt-nofail.mount | 11 +++++++++++
.../mnt-pcrfs.mount | 12 ++++++++++++
.../mnt-reqmounts.mount | 13 +++++++++++++
.../mnt-requiredby.mount | 12 ++++++++++++
.../mnt-requires.mount | 14 ++++++++++++++
.../mnt-rwonly.mount | 13 +++++++++++++
.../mnt-timeout.mount | 13 +++++++++++++
.../mnt-wantedby.mount | 12 ++++++++++++
.../sysroot.mount | 13 +++++++++++++
.../systemd-fsck-root.service | 17 +++++++++++++++++
.../systemd-makefs@dev-sdx12.service | 18 ++++++++++++++++++
.../test-18-options.fstab.input | 16 ++++++++++++++++
42 files changed, 302 insertions(+)
create mode 120000 test/test-fstab-generator/test-18-options.fstab.expected/foo.service.requires/mnt-requiredby.mount
create mode 120000 test/test-fstab-generator/test-18-options.fstab.expected/foo.service.wants/mnt-wantedby.mount
create mode 100644 test/test-fstab-generator/test-18-options.fstab.expected/initrd-root-device.target.d/50-root-device.conf
create mode 120000 test/test-fstab-generator/test-18-options.fstab.expected/initrd-root-fs.target.requires/sysroot.mount
create mode 120000 test/test-fstab-generator/test-18-options.fstab.expected/initrd-usr-fs.target.requires/sysroot.mount
create mode 100644 test/test-fstab-generator/test-18-options.fstab.expected/local-fs.target.d/50-order-systemd-growfs@mnt-growfs.service.conf
create mode 120000 test/test-fstab-generator/test-18-options.fstab.expected/local-fs.target.requires/mnt-after.mount
create mode 120000 test/test-fstab-generator/test-18-options.fstab.expected/local-fs.target.requires/mnt-automount1.automount
create mode 120000 test/test-fstab-generator/test-18-options.fstab.expected/local-fs.target.requires/mnt-before.mount
create mode 120000 test/test-fstab-generator/test-18-options.fstab.expected/local-fs.target.requires/mnt-growfs.mount
create mode 120000 test/test-fstab-generator/test-18-options.fstab.expected/local-fs.target.requires/mnt-mkfs.mount
create mode 120000 test/test-fstab-generator/test-18-options.fstab.expected/local-fs.target.requires/mnt-pcrfs.mount
create mode 120000 test/test-fstab-generator/test-18-options.fstab.expected/local-fs.target.requires/mnt-reqmounts.mount
create mode 120000 test/test-fstab-generator/test-18-options.fstab.expected/local-fs.target.requires/mnt-requires.mount
create mode 120000 test/test-fstab-generator/test-18-options.fstab.expected/local-fs.target.requires/mnt-rwonly.mount
create mode 120000 test/test-fstab-generator/test-18-options.fstab.expected/local-fs.target.requires/mnt-timeout.mount
create mode 120000 test/test-fstab-generator/test-18-options.fstab.expected/local-fs.target.wants/mnt-automount2.automount
create mode 120000 test/test-fstab-generator/test-18-options.fstab.expected/local-fs.target.wants/mnt-nofail.mount
create mode 100644 test/test-fstab-generator/test-18-options.fstab.expected/mnt-after.mount
create mode 100644 test/test-fstab-generator/test-18-options.fstab.expected/mnt-automount1.automount
create mode 100644 test/test-fstab-generator/test-18-options.fstab.expected/mnt-automount1.mount
create mode 100644 test/test-fstab-generator/test-18-options.fstab.expected/mnt-automount2.automount
create mode 100644 test/test-fstab-generator/test-18-options.fstab.expected/mnt-automount2.mount
create mode 100644 test/test-fstab-generator/test-18-options.fstab.expected/mnt-before.mount
create mode 100644 test/test-fstab-generator/test-18-options.fstab.expected/mnt-growfs.mount
create mode 100644 test/test-fstab-generator/test-18-options.fstab.expected/mnt-growfs.mount.wants/systemd-growfs@mnt-growfs.service
create mode 100644 test/test-fstab-generator/test-18-options.fstab.expected/mnt-mkfs.mount
create mode 120000 test/test-fstab-generator/test-18-options.fstab.expected/mnt-mkfs.mount.requires/systemd-makefs@dev-sdx12.service
create mode 100644 test/test-fstab-generator/test-18-options.fstab.expected/mnt-noauto.mount
create mode 100644 test/test-fstab-generator/test-18-options.fstab.expected/mnt-nofail.mount
create mode 100644 test/test-fstab-generator/test-18-options.fstab.expected/mnt-pcrfs.mount
create mode 100644 test/test-fstab-generator/test-18-options.fstab.expected/mnt-reqmounts.mount
create mode 100644 test/test-fstab-generator/test-18-options.fstab.expected/mnt-requiredby.mount
create mode 100644 test/test-fstab-generator/test-18-options.fstab.expected/mnt-requires.mount
create mode 100644 test/test-fstab-generator/test-18-options.fstab.expected/mnt-rwonly.mount
create mode 100644 test/test-fstab-generator/test-18-options.fstab.expected/mnt-timeout.mount
create mode 100644 test/test-fstab-generator/test-18-options.fstab.expected/mnt-wantedby.mount
create mode 100644 test/test-fstab-generator/test-18-options.fstab.expected/sysroot.mount
create mode 100644 test/test-fstab-generator/test-18-options.fstab.expected/systemd-fsck-root.service
create mode 100644 test/test-fstab-generator/test-18-options.fstab.expected/systemd-makefs@dev-sdx12.service
create mode 100644 test/test-fstab-generator/test-18-options.fstab.input
diff --git a/test/test-fstab-generator.sh b/test/test-fstab-generator.sh
index c844d0dae1..7df67ce305 100755
--- a/test/test-fstab-generator.sh
+++ b/test/test-fstab-generator.sh
@@ -35,6 +35,15 @@ for f in "$src"/test-*.input; do
SYSTEMD_LOG_LEVEL=debug SYSTEMD_IN_INITRD=yes SYSTEMD_PROC_CMDLINE="fstab=no $(cat "$f")" $generator "$out" "$out" "$out"
fi
+ # The option x-systemd.growfs creates symlink to system's systemd-growfs@.service in .mount.wants directory.
+ # The system that the test is currently running on may not have or may have outdated unit file.
+ # Let's replace the symlink with an empty file.
+ for i in "$out"/*/systemd-growfs@*.service; do
+ [[ -L "$i" ]] || continue
+ rm "$i"
+ touch "$i"
+ done
+
# For split-usr system
for i in "$out"/systemd-*.service; do
sed -i -e 's:ExecStart=/lib/systemd/:ExecStart=/usr/lib/systemd/:' "$i"
diff --git a/test/test-fstab-generator/test-18-options.fstab.expected/foo.service.requires/mnt-requiredby.mount b/test/test-fstab-generator/test-18-options.fstab.expected/foo.service.requires/mnt-requiredby.mount
new file mode 120000
index 0000000000..6b012b09ef
--- /dev/null
+++ b/test/test-fstab-generator/test-18-options.fstab.expected/foo.service.requires/mnt-requiredby.mount
@@ -0,0 +1 @@
+../mnt-requiredby.mount
\ No newline at end of file
diff --git a/test/test-fstab-generator/test-18-options.fstab.expected/foo.service.wants/mnt-wantedby.mount b/test/test-fstab-generator/test-18-options.fstab.expected/foo.service.wants/mnt-wantedby.mount
new file mode 120000
index 0000000000..cdf21276b6
--- /dev/null
+++ b/test/test-fstab-generator/test-18-options.fstab.expected/foo.service.wants/mnt-wantedby.mount
@@ -0,0 +1 @@
+../mnt-wantedby.mount
\ No newline at end of file
diff --git a/test/test-fstab-generator/test-18-options.fstab.expected/initrd-root-device.target.d/50-root-device.conf b/test/test-fstab-generator/test-18-options.fstab.expected/initrd-root-device.target.d/50-root-device.conf
new file mode 100644
index 0000000000..47c4232223
--- /dev/null
+++ b/test/test-fstab-generator/test-18-options.fstab.expected/initrd-root-device.target.d/50-root-device.conf
@@ -0,0 +1,5 @@
+# Automatically generated by systemd-fstab-generator
+
+[Unit]
+Requires=dev-sdx1.device
+After=dev-sdx1.device
diff --git a/test/test-fstab-generator/test-18-options.fstab.expected/initrd-root-fs.target.requires/sysroot.mount b/test/test-fstab-generator/test-18-options.fstab.expected/initrd-root-fs.target.requires/sysroot.mount
new file mode 120000
index 0000000000..0c969cdbd4
--- /dev/null
+++ b/test/test-fstab-generator/test-18-options.fstab.expected/initrd-root-fs.target.requires/sysroot.mount
@@ -0,0 +1 @@
+../sysroot.mount
\ No newline at end of file
diff --git a/test/test-fstab-generator/test-18-options.fstab.expected/initrd-usr-fs.target.requires/sysroot.mount b/test/test-fstab-generator/test-18-options.fstab.expected/initrd-usr-fs.target.requires/sysroot.mount
new file mode 120000
index 0000000000..0c969cdbd4
--- /dev/null
+++ b/test/test-fstab-generator/test-18-options.fstab.expected/initrd-usr-fs.target.requires/sysroot.mount
@@ -0,0 +1 @@
+../sysroot.mount
\ No newline at end of file
diff --git a/test/test-fstab-generator/test-18-options.fstab.expected/local-fs.target.d/50-order-systemd-growfs@mnt-growfs.service.conf b/test/test-fstab-generator/test-18-options.fstab.expected/local-fs.target.d/50-order-systemd-growfs@mnt-growfs.service.conf
new file mode 100644
index 0000000000..ac770bcb51
--- /dev/null
+++ b/test/test-fstab-generator/test-18-options.fstab.expected/local-fs.target.d/50-order-systemd-growfs@mnt-growfs.service.conf
@@ -0,0 +1,4 @@
+# Automatically generated by systemd-fstab-generator
+
+[Unit]
+After=systemd-growfs@mnt-growfs.service
diff --git a/test/test-fstab-generator/test-18-options.fstab.expected/local-fs.target.requires/mnt-after.mount b/test/test-fstab-generator/test-18-options.fstab.expected/local-fs.target.requires/mnt-after.mount
new file mode 120000
index 0000000000..68364ef19c
--- /dev/null
+++ b/test/test-fstab-generator/test-18-options.fstab.expected/local-fs.target.requires/mnt-after.mount
@@ -0,0 +1 @@
+../mnt-after.mount
\ No newline at end of file
diff --git a/test/test-fstab-generator/test-18-options.fstab.expected/local-fs.target.requires/mnt-automount1.automount b/test/test-fstab-generator/test-18-options.fstab.expected/local-fs.target.requires/mnt-automount1.automount
new file mode 120000
index 0000000000..3638a8c90e
--- /dev/null
+++ b/test/test-fstab-generator/test-18-options.fstab.expected/local-fs.target.requires/mnt-automount1.automount
@@ -0,0 +1 @@
+../mnt-automount1.automount
\ No newline at end of file
diff --git a/test/test-fstab-generator/test-18-options.fstab.expected/local-fs.target.requires/mnt-before.mount b/test/test-fstab-generator/test-18-options.fstab.expected/local-fs.target.requires/mnt-before.mount
new file mode 120000
index 0000000000..3a50a40d5f
--- /dev/null
+++ b/test/test-fstab-generator/test-18-options.fstab.expected/local-fs.target.requires/mnt-before.mount
@@ -0,0 +1 @@
+../mnt-before.mount
\ No newline at end of file
diff --git a/test/test-fstab-generator/test-18-options.fstab.expected/local-fs.target.requires/mnt-growfs.mount b/test/test-fstab-generator/test-18-options.fstab.expected/local-fs.target.requires/mnt-growfs.mount
new file mode 120000
index 0000000000..cb05081e45
--- /dev/null
+++ b/test/test-fstab-generator/test-18-options.fstab.expected/local-fs.target.requires/mnt-growfs.mount
@@ -0,0 +1 @@
+../mnt-growfs.mount
\ No newline at end of file
diff --git a/test/test-fstab-generator/test-18-options.fstab.expected/local-fs.target.requires/mnt-mkfs.mount b/test/test-fstab-generator/test-18-options.fstab.expected/local-fs.target.requires/mnt-mkfs.mount
new file mode 120000
index 0000000000..51f897e419
--- /dev/null
+++ b/test/test-fstab-generator/test-18-options.fstab.expected/local-fs.target.requires/mnt-mkfs.mount
@@ -0,0 +1 @@
+../mnt-mkfs.mount
\ No newline at end of file
diff --git a/test/test-fstab-generator/test-18-options.fstab.expected/local-fs.target.requires/mnt-pcrfs.mount b/test/test-fstab-generator/test-18-options.fstab.expected/local-fs.target.requires/mnt-pcrfs.mount
new file mode 120000
index 0000000000..276dfc0731
--- /dev/null
+++ b/test/test-fstab-generator/test-18-options.fstab.expected/local-fs.target.requires/mnt-pcrfs.mount
@@ -0,0 +1 @@
+../mnt-pcrfs.mount
\ No newline at end of file
diff --git a/test/test-fstab-generator/test-18-options.fstab.expected/local-fs.target.requires/mnt-reqmounts.mount b/test/test-fstab-generator/test-18-options.fstab.expected/local-fs.target.requires/mnt-reqmounts.mount
new file mode 120000
index 0000000000..7efce8da9a
--- /dev/null
+++ b/test/test-fstab-generator/test-18-options.fstab.expected/local-fs.target.requires/mnt-reqmounts.mount
@@ -0,0 +1 @@
+../mnt-reqmounts.mount
\ No newline at end of file
diff --git a/test/test-fstab-generator/test-18-options.fstab.expected/local-fs.target.requires/mnt-requires.mount b/test/test-fstab-generator/test-18-options.fstab.expected/local-fs.target.requires/mnt-requires.mount
new file mode 120000
index 0000000000..34a6aad26f
--- /dev/null
+++ b/test/test-fstab-generator/test-18-options.fstab.expected/local-fs.target.requires/mnt-requires.mount
@@ -0,0 +1 @@
+../mnt-requires.mount
\ No newline at end of file
diff --git a/test/test-fstab-generator/test-18-options.fstab.expected/local-fs.target.requires/mnt-rwonly.mount b/test/test-fstab-generator/test-18-options.fstab.expected/local-fs.target.requires/mnt-rwonly.mount
new file mode 120000
index 0000000000..d03abd2353
--- /dev/null
+++ b/test/test-fstab-generator/test-18-options.fstab.expected/local-fs.target.requires/mnt-rwonly.mount
@@ -0,0 +1 @@
+../mnt-rwonly.mount
\ No newline at end of file
diff --git a/test/test-fstab-generator/test-18-options.fstab.expected/local-fs.target.requires/mnt-timeout.mount b/test/test-fstab-generator/test-18-options.fstab.expected/local-fs.target.requires/mnt-timeout.mount
new file mode 120000
index 0000000000..b0ec730825
--- /dev/null
+++ b/test/test-fstab-generator/test-18-options.fstab.expected/local-fs.target.requires/mnt-timeout.mount
@@ -0,0 +1 @@
+../mnt-timeout.mount
\ No newline at end of file
diff --git a/test/test-fstab-generator/test-18-options.fstab.expected/local-fs.target.wants/mnt-automount2.automount b/test/test-fstab-generator/test-18-options.fstab.expected/local-fs.target.wants/mnt-automount2.automount
new file mode 120000
index 0000000000..a30481ec1f
--- /dev/null
+++ b/test/test-fstab-generator/test-18-options.fstab.expected/local-fs.target.wants/mnt-automount2.automount
@@ -0,0 +1 @@
+../mnt-automount2.automount
\ No newline at end of file
diff --git a/test/test-fstab-generator/test-18-options.fstab.expected/local-fs.target.wants/mnt-nofail.mount b/test/test-fstab-generator/test-18-options.fstab.expected/local-fs.target.wants/mnt-nofail.mount
new file mode 120000
index 0000000000..b82bbad730
--- /dev/null
+++ b/test/test-fstab-generator/test-18-options.fstab.expected/local-fs.target.wants/mnt-nofail.mount
@@ -0,0 +1 @@
+../mnt-nofail.mount
\ No newline at end of file
diff --git a/test/test-fstab-generator/test-18-options.fstab.expected/mnt-after.mount b/test/test-fstab-generator/test-18-options.fstab.expected/mnt-after.mount
new file mode 100644
index 0000000000..2aebb686a7
--- /dev/null
+++ b/test/test-fstab-generator/test-18-options.fstab.expected/mnt-after.mount
@@ -0,0 +1,13 @@
+# Automatically generated by systemd-fstab-generator
+
+[Unit]
+Documentation=man:fstab(5) man:systemd-fstab-generator(8)
+SourcePath=/etc/fstab
+After=foo.service
+Before=local-fs.target
+After=blockdev@dev-sdx3.target
+
+[Mount]
+What=/dev/sdx3
+Where=/mnt/after
+Options=x-systemd.after=foo.service
diff --git a/test/test-fstab-generator/test-18-options.fstab.expected/mnt-automount1.automount b/test/test-fstab-generator/test-18-options.fstab.expected/mnt-automount1.automount
new file mode 100644
index 0000000000..e376689b67
--- /dev/null
+++ b/test/test-fstab-generator/test-18-options.fstab.expected/mnt-automount1.automount
@@ -0,0 +1,9 @@
+# Automatically generated by systemd-fstab-generator
+
+[Unit]
+SourcePath=/etc/fstab
+Documentation=man:fstab(5) man:systemd-fstab-generator(8)
+
+[Automount]
+Where=/mnt/automount1
+TimeoutIdleSec=30min
diff --git a/test/test-fstab-generator/test-18-options.fstab.expected/mnt-automount1.mount b/test/test-fstab-generator/test-18-options.fstab.expected/mnt-automount1.mount
new file mode 100644
index 0000000000..1413292c79
--- /dev/null
+++ b/test/test-fstab-generator/test-18-options.fstab.expected/mnt-automount1.mount
@@ -0,0 +1,12 @@
+# Automatically generated by systemd-fstab-generator
+
+[Unit]
+Documentation=man:fstab(5) man:systemd-fstab-generator(8)
+SourcePath=/etc/fstab
+Before=local-fs.target
+After=blockdev@dev-sdx9.target
+
+[Mount]
+What=/dev/sdx9
+Where=/mnt/automount1
+Options=x-systemd.automount,x-systemd.idle-timeout=30m
diff --git a/test/test-fstab-generator/test-18-options.fstab.expected/mnt-automount2.automount b/test/test-fstab-generator/test-18-options.fstab.expected/mnt-automount2.automount
new file mode 100644
index 0000000000..e05d3976ef
--- /dev/null
+++ b/test/test-fstab-generator/test-18-options.fstab.expected/mnt-automount2.automount
@@ -0,0 +1,8 @@
+# Automatically generated by systemd-fstab-generator
+
+[Unit]
+SourcePath=/etc/fstab
+Documentation=man:fstab(5) man:systemd-fstab-generator(8)
+
+[Automount]
+Where=/mnt/automount2
diff --git a/test/test-fstab-generator/test-18-options.fstab.expected/mnt-automount2.mount b/test/test-fstab-generator/test-18-options.fstab.expected/mnt-automount2.mount
new file mode 100644
index 0000000000..1eba08c9f7
--- /dev/null
+++ b/test/test-fstab-generator/test-18-options.fstab.expected/mnt-automount2.mount
@@ -0,0 +1,11 @@
+# Automatically generated by systemd-fstab-generator
+
+[Unit]
+Documentation=man:fstab(5) man:systemd-fstab-generator(8)
+SourcePath=/etc/fstab
+After=blockdev@dev-sdx10.target
+
+[Mount]
+What=/dev/sdx10
+Where=/mnt/automount2
+Options=x-systemd.automount,nofail
diff --git a/test/test-fstab-generator/test-18-options.fstab.expected/mnt-before.mount b/test/test-fstab-generator/test-18-options.fstab.expected/mnt-before.mount
new file mode 100644
index 0000000000..eea084b7b6
--- /dev/null
+++ b/test/test-fstab-generator/test-18-options.fstab.expected/mnt-before.mount
@@ -0,0 +1,13 @@
+# Automatically generated by systemd-fstab-generator
+
+[Unit]
+Documentation=man:fstab(5) man:systemd-fstab-generator(8)
+SourcePath=/etc/fstab
+Before=foo.service
+Before=local-fs.target
+After=blockdev@dev-sdx4.target
+
+[Mount]
+What=/dev/sdx4
+Where=/mnt/before
+Options=x-systemd.before=foo.service
diff --git a/test/test-fstab-generator/test-18-options.fstab.expected/mnt-growfs.mount b/test/test-fstab-generator/test-18-options.fstab.expected/mnt-growfs.mount
new file mode 100644
index 0000000000..bbe958c076
--- /dev/null
+++ b/test/test-fstab-generator/test-18-options.fstab.expected/mnt-growfs.mount
@@ -0,0 +1,12 @@
+# Automatically generated by systemd-fstab-generator
+
+[Unit]
+Documentation=man:fstab(5) man:systemd-fstab-generator(8)
+SourcePath=/etc/fstab
+Before=local-fs.target
+After=blockdev@dev-sdx13.target
+
+[Mount]
+What=/dev/sdx13
+Where=/mnt/growfs
+Options=x-systemd.growfs
diff --git a/test/test-fstab-generator/test-18-options.fstab.expected/mnt-growfs.mount.wants/systemd-growfs@mnt-growfs.service b/test/test-fstab-generator/test-18-options.fstab.expected/mnt-growfs.mount.wants/systemd-growfs@mnt-growfs.service
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/test/test-fstab-generator/test-18-options.fstab.expected/mnt-mkfs.mount b/test/test-fstab-generator/test-18-options.fstab.expected/mnt-mkfs.mount
new file mode 100644
index 0000000000..be4c8fa17f
--- /dev/null
+++ b/test/test-fstab-generator/test-18-options.fstab.expected/mnt-mkfs.mount
@@ -0,0 +1,13 @@
+# Automatically generated by systemd-fstab-generator
+
+[Unit]
+Documentation=man:fstab(5) man:systemd-fstab-generator(8)
+SourcePath=/etc/fstab
+Before=local-fs.target
+After=blockdev@dev-sdx12.target
+
+[Mount]
+What=/dev/sdx12
+Where=/mnt/mkfs
+Type=ext4
+Options=x-systemd.makefs
diff --git a/test/test-fstab-generator/test-18-options.fstab.expected/mnt-mkfs.mount.requires/systemd-makefs@dev-sdx12.service b/test/test-fstab-generator/test-18-options.fstab.expected/mnt-mkfs.mount.requires/systemd-makefs@dev-sdx12.service
new file mode 120000
index 0000000000..fe80548a68
--- /dev/null
+++ b/test/test-fstab-generator/test-18-options.fstab.expected/mnt-mkfs.mount.requires/systemd-makefs@dev-sdx12.service
@@ -0,0 +1 @@
+../systemd-makefs@dev-sdx12.service
\ No newline at end of file
diff --git a/test/test-fstab-generator/test-18-options.fstab.expected/mnt-noauto.mount b/test/test-fstab-generator/test-18-options.fstab.expected/mnt-noauto.mount
new file mode 100644
index 0000000000..4d52a6e698
--- /dev/null
+++ b/test/test-fstab-generator/test-18-options.fstab.expected/mnt-noauto.mount
@@ -0,0 +1,12 @@
+# Automatically generated by systemd-fstab-generator
+
+[Unit]
+Documentation=man:fstab(5) man:systemd-fstab-generator(8)
+SourcePath=/etc/fstab
+Before=local-fs.target
+After=blockdev@dev-sdx15.target
+
+[Mount]
+What=/dev/sdx15
+Where=/mnt/noauto
+Options=noauto
diff --git a/test/test-fstab-generator/test-18-options.fstab.expected/mnt-nofail.mount b/test/test-fstab-generator/test-18-options.fstab.expected/mnt-nofail.mount
new file mode 100644
index 0000000000..3c20b652b0
--- /dev/null
+++ b/test/test-fstab-generator/test-18-options.fstab.expected/mnt-nofail.mount
@@ -0,0 +1,11 @@
+# Automatically generated by systemd-fstab-generator
+
+[Unit]
+Documentation=man:fstab(5) man:systemd-fstab-generator(8)
+SourcePath=/etc/fstab
+After=blockdev@dev-sdx16.target
+
+[Mount]
+What=/dev/sdx16
+Where=/mnt/nofail
+Options=nofail
diff --git a/test/test-fstab-generator/test-18-options.fstab.expected/mnt-pcrfs.mount b/test/test-fstab-generator/test-18-options.fstab.expected/mnt-pcrfs.mount
new file mode 100644
index 0000000000..2c070e695a
--- /dev/null
+++ b/test/test-fstab-generator/test-18-options.fstab.expected/mnt-pcrfs.mount
@@ -0,0 +1,12 @@
+# Automatically generated by systemd-fstab-generator
+
+[Unit]
+Documentation=man:fstab(5) man:systemd-fstab-generator(8)
+SourcePath=/etc/fstab
+Before=local-fs.target
+After=blockdev@dev-sdx14.target
+
+[Mount]
+What=/dev/sdx14
+Where=/mnt/pcrfs
+Options=x-systemd.pcrfs
diff --git a/test/test-fstab-generator/test-18-options.fstab.expected/mnt-reqmounts.mount b/test/test-fstab-generator/test-18-options.fstab.expected/mnt-reqmounts.mount
new file mode 100644
index 0000000000..c21ccd27ba
--- /dev/null
+++ b/test/test-fstab-generator/test-18-options.fstab.expected/mnt-reqmounts.mount
@@ -0,0 +1,13 @@
+# Automatically generated by systemd-fstab-generator
+
+[Unit]
+Documentation=man:fstab(5) man:systemd-fstab-generator(8)
+SourcePath=/etc/fstab
+RequiresMountsFor=/hoge
+Before=local-fs.target
+After=blockdev@dev-sdx6.target
+
+[Mount]
+What=/dev/sdx6
+Where=/mnt/reqmounts
+Options=x-systemd.requires-mounts-for=/hoge
diff --git a/test/test-fstab-generator/test-18-options.fstab.expected/mnt-requiredby.mount b/test/test-fstab-generator/test-18-options.fstab.expected/mnt-requiredby.mount
new file mode 100644
index 0000000000..5edc4ddf22
--- /dev/null
+++ b/test/test-fstab-generator/test-18-options.fstab.expected/mnt-requiredby.mount
@@ -0,0 +1,12 @@
+# Automatically generated by systemd-fstab-generator
+
+[Unit]
+Documentation=man:fstab(5) man:systemd-fstab-generator(8)
+SourcePath=/etc/fstab
+Before=local-fs.target
+After=blockdev@dev-sdx8.target
+
+[Mount]
+What=/dev/sdx8
+Where=/mnt/requiredby
+Options=x-systemd.required-by=foo.service
diff --git a/test/test-fstab-generator/test-18-options.fstab.expected/mnt-requires.mount b/test/test-fstab-generator/test-18-options.fstab.expected/mnt-requires.mount
new file mode 100644
index 0000000000..8386616593
--- /dev/null
+++ b/test/test-fstab-generator/test-18-options.fstab.expected/mnt-requires.mount
@@ -0,0 +1,14 @@
+# Automatically generated by systemd-fstab-generator
+
+[Unit]
+Documentation=man:fstab(5) man:systemd-fstab-generator(8)
+SourcePath=/etc/fstab
+After=foo.service
+Requires=foo.service
+Before=local-fs.target
+After=blockdev@dev-sdx5.target
+
+[Mount]
+What=/dev/sdx5
+Where=/mnt/requires
+Options=x-systemd.requires=foo.service
diff --git a/test/test-fstab-generator/test-18-options.fstab.expected/mnt-rwonly.mount b/test/test-fstab-generator/test-18-options.fstab.expected/mnt-rwonly.mount
new file mode 100644
index 0000000000..8649734386
--- /dev/null
+++ b/test/test-fstab-generator/test-18-options.fstab.expected/mnt-rwonly.mount
@@ -0,0 +1,13 @@
+# Automatically generated by systemd-fstab-generator
+
+[Unit]
+Documentation=man:fstab(5) man:systemd-fstab-generator(8)
+SourcePath=/etc/fstab
+Before=local-fs.target
+After=blockdev@dev-sdx11.target
+
+[Mount]
+What=/dev/sdx11
+Where=/mnt/rwonly
+Options=x-systemd.rw-only
+ReadWriteOnly=yes
diff --git a/test/test-fstab-generator/test-18-options.fstab.expected/mnt-timeout.mount b/test/test-fstab-generator/test-18-options.fstab.expected/mnt-timeout.mount
new file mode 100644
index 0000000000..09d772a52b
--- /dev/null
+++ b/test/test-fstab-generator/test-18-options.fstab.expected/mnt-timeout.mount
@@ -0,0 +1,13 @@
+# Automatically generated by systemd-fstab-generator
+
+[Unit]
+Documentation=man:fstab(5) man:systemd-fstab-generator(8)
+SourcePath=/etc/fstab
+Before=local-fs.target
+After=blockdev@dev-sdx2.target
+
+[Mount]
+What=/dev/sdx2
+Where=/mnt/timeout
+TimeoutSec=10min
+Options=x-systemd.mount-timeout=10m
diff --git a/test/test-fstab-generator/test-18-options.fstab.expected/mnt-wantedby.mount b/test/test-fstab-generator/test-18-options.fstab.expected/mnt-wantedby.mount
new file mode 100644
index 0000000000..e12df820d4
--- /dev/null
+++ b/test/test-fstab-generator/test-18-options.fstab.expected/mnt-wantedby.mount
@@ -0,0 +1,12 @@
+# Automatically generated by systemd-fstab-generator
+
+[Unit]
+Documentation=man:fstab(5) man:systemd-fstab-generator(8)
+SourcePath=/etc/fstab
+Before=local-fs.target
+After=blockdev@dev-sdx7.target
+
+[Mount]
+What=/dev/sdx7
+Where=/mnt/wantedby
+Options=x-systemd.wanted-by=foo.service
diff --git a/test/test-fstab-generator/test-18-options.fstab.expected/sysroot.mount b/test/test-fstab-generator/test-18-options.fstab.expected/sysroot.mount
new file mode 100644
index 0000000000..0e8a701be9
--- /dev/null
+++ b/test/test-fstab-generator/test-18-options.fstab.expected/sysroot.mount
@@ -0,0 +1,13 @@
+# Automatically generated by systemd-fstab-generator
+
+[Unit]
+Documentation=man:fstab(5) man:systemd-fstab-generator(8)
+SourcePath=/etc/fstab
+Before=initrd-root-fs.target
+Requires=systemd-fsck-root.service
+After=systemd-fsck-root.service
+After=blockdev@dev-sdx1.target
+
+[Mount]
+What=/dev/sdx1
+Where=/sysroot
diff --git a/test/test-fstab-generator/test-18-options.fstab.expected/systemd-fsck-root.service b/test/test-fstab-generator/test-18-options.fstab.expected/systemd-fsck-root.service
new file mode 100644
index 0000000000..95d943b87a
--- /dev/null
+++ b/test/test-fstab-generator/test-18-options.fstab.expected/systemd-fsck-root.service
@@ -0,0 +1,17 @@
+# Automatically generated by systemd-fstab-generator
+
+[Unit]
+Description=File System Check on /dev/sdx1
+Documentation=man:systemd-fsck-root.service(8)
+
+DefaultDependencies=no
+BindsTo=dev-sdx1.device
+Conflicts=shutdown.target
+After=initrd-root-device.target local-fs-pre.target dev-sdx1.device
+Before=shutdown.target
+
+[Service]
+Type=oneshot
+RemainAfterExit=yes
+ExecStart=/usr/lib/systemd/systemd-fsck /dev/sdx1
+TimeoutSec=0
diff --git a/test/test-fstab-generator/test-18-options.fstab.expected/systemd-makefs@dev-sdx12.service b/test/test-fstab-generator/test-18-options.fstab.expected/systemd-makefs@dev-sdx12.service
new file mode 100644
index 0000000000..303c1ee680
--- /dev/null
+++ b/test/test-fstab-generator/test-18-options.fstab.expected/systemd-makefs@dev-sdx12.service
@@ -0,0 +1,18 @@
+# Automatically generated by systemd-fstab-generator
+
+[Unit]
+Description=Make File System on %f
+Documentation=man:systemd-makefs@.service(8)
+
+DefaultDependencies=no
+BindsTo=%i.device
+After=%i.device
+Before=systemd-fsck@%i.service mnt-mkfs.mount
+Conflicts=shutdown.target
+Before=shutdown.target
+
+[Service]
+Type=oneshot
+RemainAfterExit=yes
+ExecStart=/usr/lib/systemd/systemd-makefs ext4 /dev/sdx12
+TimeoutSec=0
diff --git a/test/test-fstab-generator/test-18-options.fstab.input b/test/test-fstab-generator/test-18-options.fstab.input
new file mode 100644
index 0000000000..98ef0b9fba
--- /dev/null
+++ b/test/test-fstab-generator/test-18-options.fstab.input
@@ -0,0 +1,16 @@
+/dev/sdx1 /sysroot auto defaults 0 1
+/dev/sdx2 /mnt/timeout auto x-systemd.mount-timeout=10m 0 0
+/dev/sdx3 /mnt/after auto x-systemd.after=foo.service 0 0
+/dev/sdx4 /mnt/before auto x-systemd.before=foo.service 0 0
+/dev/sdx5 /mnt/requires auto x-systemd.requires=foo.service 0 0
+/dev/sdx6 /mnt/reqmounts auto x-systemd.requires-mounts-for=/hoge 0 0
+/dev/sdx7 /mnt/wantedby auto x-systemd.wanted-by=foo.service 0 0
+/dev/sdx8 /mnt/requiredby auto x-systemd.required-by=foo.service 0 0
+/dev/sdx9 /mnt/automount1 auto x-systemd.automount,x-systemd.idle-timeout=30m 0 0
+/dev/sdx10 /mnt/automount2 auto x-systemd.automount,nofail 0 0
+/dev/sdx11 /mnt/rwonly auto x-systemd.rw-only 0 0
+/dev/sdx12 /mnt/mkfs ext4 x-systemd.makefs 0 0
+/dev/sdx13 /mnt/growfs auto x-systemd.growfs 0 0
+/dev/sdx14 /mnt/pcrfs auto x-systemd.pcrfs 0 0
+/dev/sdx15 /mnt/noauto auto noauto 0 0
+/dev/sdx16 /mnt/nofail auto nofail 0 0

View File

@ -0,0 +1,408 @@
From ddcdc462b935fc210677f664d61cf556fb2abe0f Mon Sep 17 00:00:00 2001
From: Yu Watanabe <watanabe.yu+github@gmail.com>
Date: Mon, 8 May 2023 19:45:34 +0900
Subject: [PATCH] fstab-generator: split out several functions from
parse_fstab()
No functional changes, just refactoring and preparation for later
commits.
(cherry picked from commit cfeb4d378ecd1ea50c0a0248c384e49983511fa8)
Related: #2190226
---
src/fstab-generator/fstab-generator.c | 323 ++++++++++++++------------
1 file changed, 171 insertions(+), 152 deletions(-)
diff --git a/src/fstab-generator/fstab-generator.c b/src/fstab-generator/fstab-generator.c
index bbd669e477..4ea95f29eb 100644
--- a/src/fstab-generator/fstab-generator.c
+++ b/src/fstab-generator/fstab-generator.c
@@ -99,7 +99,7 @@ static int write_what(FILE *f, const char *what) {
static int add_swap(
const char *source,
const char *what,
- struct mntent *me,
+ const char *options,
MountPointFlags flags) {
_cleanup_free_ char *name = NULL;
@@ -107,7 +107,6 @@ static int add_swap(
int r;
assert(what);
- assert(me);
if (!arg_swap_enabled) {
log_info("Swap unit generation disabled on kernel command line, ignoring fstab swap entry for %s.", what);
@@ -155,7 +154,7 @@ static int add_swap(
if (r < 0)
return r;
- r = write_options(f, me->mnt_opts);
+ r = write_options(f, options);
if (r < 0)
return r;
@@ -164,7 +163,7 @@ static int add_swap(
return log_error_errno(r, "Failed to write unit file %s: %m", name);
/* use what as where, to have a nicer error message */
- r = generator_write_timeouts(arg_dest, what, what, me->mnt_opts, NULL);
+ r = generator_write_timeouts(arg_dest, what, what, options, NULL);
if (r < 0)
return r;
@@ -188,18 +187,14 @@ static int add_swap(
return true;
}
-static bool mount_is_network(struct mntent *me) {
- assert(me);
-
- return fstab_test_option(me->mnt_opts, "_netdev\0") ||
- fstype_is_network(me->mnt_type);
+static bool mount_is_network(const char *fstype, const char *options) {
+ return fstab_test_option(options, "_netdev\0") ||
+ (fstype && fstype_is_network(fstype));
}
-static bool mount_in_initrd(struct mntent *me) {
- assert(me);
-
- return fstab_test_option(me->mnt_opts, "x-initrd.mount\0") ||
- path_equal(me->mnt_dir, "/usr");
+static bool mount_in_initrd(const char *where, const char *options) {
+ return fstab_test_option(options, "x-initrd.mount\0") ||
+ (where && path_equal(where, "/usr"));
}
static int write_timeout(
@@ -634,6 +629,20 @@ static const char* sysroot_fstab_path(void) {
return getenv("SYSTEMD_SYSROOT_FSTAB") ?: "/sysroot/etc/fstab";
}
+static bool sysfs_check(void) {
+ static int cached = -1;
+ int r;
+
+ if (cached < 0) {
+ r = getenv_bool_secure("SYSTEMD_SYSFS_CHECK");
+ if (r < 0 && r != -ENXIO)
+ log_debug_errno(r, "Failed to parse $SYSTEMD_SYSFS_CHECK, ignoring: %m");
+ cached = r != 0;
+ }
+
+ return cached;
+}
+
static int add_sysusr_sysroot_usr_bind_mount(const char *source) {
return add_mount(source,
arg_dest,
@@ -647,11 +656,153 @@ static int add_sysusr_sysroot_usr_bind_mount(const char *source) {
SPECIAL_INITRD_FS_TARGET);
}
+static MountPointFlags fstab_options_to_flags(const char *options, bool is_swap) {
+ MountPointFlags flags = 0;
+
+ if (fstab_test_option(options, "x-systemd.makefs\0"))
+ flags |= MOUNT_MAKEFS;
+ if (fstab_test_option(options, "x-systemd.growfs\0"))
+ flags |= MOUNT_GROWFS;
+ if (fstab_test_yes_no_option(options, "noauto\0" "auto\0"))
+ flags |= MOUNT_NOAUTO;
+ if (fstab_test_yes_no_option(options, "nofail\0" "fail\0"))
+ flags |= MOUNT_NOFAIL;
+
+ if (!is_swap) {
+ if (fstab_test_option(options, "x-systemd.rw-only\0"))
+ flags |= MOUNT_RW_ONLY;
+ if (fstab_test_option(options,
+ "comment=systemd.automount\0"
+ "x-systemd.automount\0"))
+ flags |= MOUNT_AUTOMOUNT;
+ }
+
+ return flags;
+}
+
+static int parse_fstab_one(
+ const char *source,
+ const char *what_original,
+ const char *where_original,
+ const char *fstype,
+ const char *options,
+ int passno,
+ bool initrd) {
+
+ _cleanup_free_ char *what = NULL, *where = NULL, *canonical_where = NULL;
+ MountPointFlags flags;
+ int r;
+
+ assert(what_original);
+ assert(where_original);
+ assert(fstype);
+ assert(options);
+
+ if (initrd && !mount_in_initrd(where_original, options))
+ return 0;
+
+ what = fstab_node_to_udev_node(what_original);
+ if (!what)
+ return log_oom();
+
+ if (path_is_read_only_fs("/sys") > 0 &&
+ (streq(what, "sysfs") ||
+ (sysfs_check() && is_device_path(what)))) {
+ log_info("/sys/ is read-only (running in a container?), ignoring mount for %s.", what);
+ return 0;
+ }
+
+ where = strdup(where_original);
+ if (!where)
+ return log_oom();
+
+ if (is_path(where)) {
+ path_simplify(where);
+
+ /* Follow symlinks here; see 5261ba901845c084de5a8fd06500ed09bfb0bd80 which makes sense for
+ * mount units, but causes problems since it historically worked to have symlinks in e.g.
+ * /etc/fstab. So we canonicalize here. Note that we use CHASE_NONEXISTENT to handle the case
+ * where a symlink refers to another mount target; this works assuming the sub-mountpoint
+ * target is the final directory.
+ *
+ * FIXME: when chase() learns to chase non-existent paths, use this here and
+ * drop the prefixing with /sysroot on error below.
+ */
+ r = chase_symlinks(where, initrd ? "/sysroot" : NULL, CHASE_PREFIX_ROOT | CHASE_NONEXISTENT,
+ &canonical_where, NULL);
+ if (r < 0) {
+ /* If we can't canonicalize, continue as if it wasn't a symlink */
+ log_debug_errno(r, "Failed to read symlink target for %s, using as-is: %m", where);
+
+ if (initrd) {
+ canonical_where = path_join("/sysroot", where);
+ if (!canonical_where)
+ return log_oom();
+ }
+
+ } else if (streq(canonical_where, where)) /* If it was fully canonicalized, suppress the change */
+ canonical_where = mfree(canonical_where);
+ else
+ log_debug("Canonicalized what=%s where=%s to %s", what, where, canonical_where);
+ }
+
+ flags = fstab_options_to_flags(options, streq_ptr(fstype, "swap"));
+
+ log_debug("Found entry what=%s where=%s type=%s makefs=%s growfs=%s noauto=%s nofail=%s",
+ what, where, strna(fstype),
+ yes_no(flags & MOUNT_MAKEFS), yes_no(flags & MOUNT_GROWFS),
+ yes_no(flags & MOUNT_NOAUTO), yes_no(flags & MOUNT_NOFAIL));
+
+ if (streq_ptr(fstype, "swap"))
+ return add_swap(source, what, options, flags);
+
+ bool is_sysroot = in_initrd() && path_equal(where, "/sysroot");
+ /* See comment from add_sysroot_usr_mount() about the need for extra indirection in case /usr needs
+ * to be mounted in order for the root fs to be synthesized based on configuration included in /usr/,
+ * e.g. systemd-repart. */
+ bool is_sysroot_usr = in_initrd() && path_equal(where, "/sysroot/usr");
+
+ const char *target_unit =
+ initrd ? SPECIAL_INITRD_FS_TARGET :
+ is_sysroot ? SPECIAL_INITRD_ROOT_FS_TARGET :
+ is_sysroot_usr ? SPECIAL_INITRD_USR_FS_TARGET :
+ mount_is_network(fstype, options) ? SPECIAL_REMOTE_FS_TARGET :
+ SPECIAL_LOCAL_FS_TARGET;
+
+ if (is_sysroot && is_device_path(what)) {
+ r = generator_write_initrd_root_device_deps(arg_dest, what);
+ if (r < 0)
+ return r;
+ }
+
+ r = add_mount(source,
+ arg_dest,
+ what,
+ is_sysroot_usr ? "/sysusr/usr" : canonical_where ?: where,
+ !is_sysroot_usr && canonical_where ? where : NULL,
+ fstype,
+ options,
+ passno,
+ flags,
+ target_unit);
+ if (r <= 0)
+ return r;
+
+ if (is_sysroot_usr) {
+ log_debug("Synthesizing fstab entry what=/sysusr/usr where=/sysroot/usr opts=bind");
+ r = add_sysusr_sysroot_usr_bind_mount(source);
+ if (r < 0)
+ return r;
+ }
+
+ return true;
+}
+
static int parse_fstab(bool initrd) {
_cleanup_endmntent_ FILE *f = NULL;
const char *fstab;
struct mntent *me;
- int r = 0, sysfs_check = -1;
+ int r, ret = 0;
if (initrd)
fstab = sysroot_fstab_path();
@@ -671,146 +822,14 @@ static int parse_fstab(bool initrd) {
}
while ((me = getmntent(f))) {
- _cleanup_free_ char *where = NULL, *what = NULL, *canonical_where = NULL;
- bool makefs, growfs, noauto, nofail;
- MountPointFlags flags;
- int k;
-
- if (initrd && !mount_in_initrd(me))
- continue;
-
- what = fstab_node_to_udev_node(me->mnt_fsname);
- if (!what)
- return log_oom();
-
- if (path_is_read_only_fs("/sys") > 0) {
- if (streq(what, "sysfs")) {
- log_info("Running in a container, ignoring fstab entry for %s.", what);
- continue;
- }
-
- if (sysfs_check < 0) {
- r = getenv_bool_secure("SYSTEMD_SYSFS_CHECK");
- if (r < 0 && r != -ENXIO)
- log_debug_errno(r, "Failed to parse $SYSTEMD_SYSFS_CHECK, ignoring: %m");
- sysfs_check = r != 0;
- }
-
- if (sysfs_check && is_device_path(what)) {
- log_info("/sys/ is read-only (running in a container?), ignoring fstab device entry for %s.", what);
- continue;
- }
- }
-
- where = strdup(me->mnt_dir);
- if (!where)
- return log_oom();
-
- if (is_path(where)) {
- path_simplify(where);
-
- /* Follow symlinks here; see 5261ba901845c084de5a8fd06500ed09bfb0bd80 which makes sense for
- * mount units, but causes problems since it historically worked to have symlinks in e.g.
- * /etc/fstab. So we canonicalize here. Note that we use CHASE_NONEXISTENT to handle the case
- * where a symlink refers to another mount target; this works assuming the sub-mountpoint
- * target is the final directory.
- *
- * FIXME: when chase_symlinks() learns to chase non-existent paths, use this here and
- * drop the prefixing with /sysroot on error below.
- */
- k = chase_symlinks(where, initrd ? "/sysroot" : NULL,
- CHASE_PREFIX_ROOT | CHASE_NONEXISTENT,
- &canonical_where, NULL);
- if (k < 0) {
- /* If we can't canonicalize, continue as if it wasn't a symlink */
- log_debug_errno(k, "Failed to read symlink target for %s, using as-is: %m", where);
-
- if (initrd) {
- canonical_where = path_join("/sysroot", where);
- if (!canonical_where)
- return log_oom();
- }
-
- } else if (streq(canonical_where, where)) /* If it was fully canonicalized, suppress the change */
- canonical_where = mfree(canonical_where);
- else
- log_debug("Canonicalized what=%s where=%s to %s", what, where, canonical_where);
- }
-
- makefs = fstab_test_option(me->mnt_opts, "x-systemd.makefs\0");
- growfs = fstab_test_option(me->mnt_opts, "x-systemd.growfs\0");
- noauto = fstab_test_yes_no_option(me->mnt_opts, "noauto\0" "auto\0");
- nofail = fstab_test_yes_no_option(me->mnt_opts, "nofail\0" "fail\0");
-
- log_debug("Found entry what=%s where=%s type=%s makefs=%s growfs=%s noauto=%s nofail=%s",
- what, where, me->mnt_type,
- yes_no(makefs), yes_no(growfs),
- yes_no(noauto), yes_no(nofail));
-
- flags = makefs * MOUNT_MAKEFS |
- growfs * MOUNT_GROWFS |
- noauto * MOUNT_NOAUTO |
- nofail * MOUNT_NOFAIL;
-
- if (streq(me->mnt_type, "swap"))
- k = add_swap(fstab, what, me, flags);
- else {
- bool rw_only, automount, is_sysroot, is_sysroot_usr;
-
- rw_only = fstab_test_option(me->mnt_opts, "x-systemd.rw-only\0");
- automount = fstab_test_option(me->mnt_opts,
- "comment=systemd.automount\0"
- "x-systemd.automount\0");
-
- flags |= rw_only * MOUNT_RW_ONLY |
- automount * MOUNT_AUTOMOUNT;
-
- is_sysroot = in_initrd() && path_equal(where, "/sysroot");
- /* See comment from add_sysroot_usr_mount about the need for extra indirection
- * in case /usr needs to be mounted in order for the root fs to be synthesized
- * based on configuration included in /usr/, e.g. systemd-repart. */
- is_sysroot_usr = in_initrd() && path_equal(where, "/sysroot/usr");
-
- const char *target_unit =
- initrd ? SPECIAL_INITRD_FS_TARGET :
- is_sysroot ? SPECIAL_INITRD_ROOT_FS_TARGET :
- is_sysroot_usr ? SPECIAL_INITRD_USR_FS_TARGET :
- mount_is_network(me) ? SPECIAL_REMOTE_FS_TARGET :
- SPECIAL_LOCAL_FS_TARGET;
-
- if (is_sysroot && is_device_path(what)) {
- r = generator_write_initrd_root_device_deps(arg_dest, what);
- if (r < 0)
- return r;
- }
-
- k = add_mount(fstab,
- arg_dest,
- what,
- is_sysroot_usr ? "/sysusr/usr" : canonical_where ?: where,
- !is_sysroot_usr && canonical_where ? where : NULL,
- me->mnt_type,
- me->mnt_opts,
- me->mnt_passno,
- flags,
- target_unit);
-
- if (is_sysroot_usr && k >= 0) {
- log_debug("Synthesizing fstab entry what=/sysusr/usr where=/sysroot/usr opts=bind");
-
- r = add_sysusr_sysroot_usr_bind_mount(fstab);
- if (r != 0)
- k = r;
- }
- }
-
- if (arg_sysroot_check && k > 0)
+ r = parse_fstab_one(fstab, me->mnt_fsname, me->mnt_dir, me->mnt_type, me->mnt_opts, me->mnt_passno, initrd);
+ if (r < 0 && ret >= 0)
+ ret = r;
+ if (arg_sysroot_check && r > 0)
return true; /* We found a mount or swap that would be started… */
- if (r >= 0 && k < 0)
- r = k;
}
- return r;
+ return ret;
}
static int sysroot_is_nfsroot(void) {

View File

@ -0,0 +1,81 @@
From 90c66a0982b41c38cfd027a2bb3e6b33d0744e68 Mon Sep 17 00:00:00 2001
From: Yu Watanabe <watanabe.yu+github@gmail.com>
Date: Fri, 12 May 2023 16:08:32 +0900
Subject: [PATCH] fstab-generator: call add_swap() earlier
As 'where' field will be ignored for swap entry.
(cherry picked from commit 256604ccddd41a16de329ff792c5f49d6750e510)
Related: #2190226
---
src/fstab-generator/fstab-generator.c | 21 +++++++++++++++------
1 file changed, 15 insertions(+), 6 deletions(-)
diff --git a/src/fstab-generator/fstab-generator.c b/src/fstab-generator/fstab-generator.c
index 4ea95f29eb..742a84b485 100644
--- a/src/fstab-generator/fstab-generator.c
+++ b/src/fstab-generator/fstab-generator.c
@@ -128,6 +128,11 @@ static int add_swap(
return true;
}
+ log_debug("Found swap entry what=%s makefs=%s growfs=%s noauto=%s nofail=%s",
+ what,
+ yes_no(flags & MOUNT_MAKEFS), yes_no(flags & MOUNT_GROWFS),
+ yes_no(flags & MOUNT_NOAUTO), yes_no(flags & MOUNT_NOFAIL));
+
r = unit_name_from_path(what, ".swap", &name);
if (r < 0)
return log_error_errno(r, "Failed to generate unit name: %m");
@@ -691,16 +696,18 @@ static int parse_fstab_one(
_cleanup_free_ char *what = NULL, *where = NULL, *canonical_where = NULL;
MountPointFlags flags;
+ bool is_swap;
int r;
assert(what_original);
- assert(where_original);
assert(fstype);
assert(options);
if (initrd && !mount_in_initrd(where_original, options))
return 0;
+ is_swap = streq_ptr(fstype, "swap");
+
what = fstab_node_to_udev_node(what_original);
if (!what)
return log_oom();
@@ -712,6 +719,13 @@ static int parse_fstab_one(
return 0;
}
+ flags = fstab_options_to_flags(options, is_swap);
+
+ if (is_swap)
+ return add_swap(source, what, options, flags);
+
+ assert(where_original); /* 'where' is not necessary for swap entry. */
+
where = strdup(where_original);
if (!where)
return log_oom();
@@ -746,16 +760,11 @@ static int parse_fstab_one(
log_debug("Canonicalized what=%s where=%s to %s", what, where, canonical_where);
}
- flags = fstab_options_to_flags(options, streq_ptr(fstype, "swap"));
-
log_debug("Found entry what=%s where=%s type=%s makefs=%s growfs=%s noauto=%s nofail=%s",
what, where, strna(fstype),
yes_no(flags & MOUNT_MAKEFS), yes_no(flags & MOUNT_GROWFS),
yes_no(flags & MOUNT_NOAUTO), yes_no(flags & MOUNT_NOFAIL));
- if (streq_ptr(fstype, "swap"))
- return add_swap(source, what, options, flags);
-
bool is_sysroot = in_initrd() && path_equal(where, "/sysroot");
/* See comment from add_sysroot_usr_mount() about the need for extra indirection in case /usr needs
* to be mounted in order for the root fs to be synthesized based on configuration included in /usr/,

View File

@ -0,0 +1,41 @@
From 6858b1611dd198607c246b835d8840d15d8f09e5 Mon Sep 17 00:00:00 2001
From: Yu Watanabe <watanabe.yu+github@gmail.com>
Date: Wed, 24 May 2023 07:24:52 +0900
Subject: [PATCH] fstab-generator: refuse to add swap earlier if disabled
No functional change, preparation for later commits.
(cherry picked from commit 9445623363fc47ee5a9265adeb9f4ca1a80ebfe4)
Related: #2190226
---
src/fstab-generator/fstab-generator.c | 9 ++++-----
1 file changed, 4 insertions(+), 5 deletions(-)
diff --git a/src/fstab-generator/fstab-generator.c b/src/fstab-generator/fstab-generator.c
index 742a84b485..2cd4de29f0 100644
--- a/src/fstab-generator/fstab-generator.c
+++ b/src/fstab-generator/fstab-generator.c
@@ -108,11 +108,6 @@ static int add_swap(
assert(what);
- if (!arg_swap_enabled) {
- log_info("Swap unit generation disabled on kernel command line, ignoring fstab swap entry for %s.", what);
- return 0;
- }
-
if (access("/proc/swaps", F_OK) < 0) {
log_info("Swap not supported, ignoring fstab swap entry for %s.", what);
return 0;
@@ -707,6 +702,10 @@ static int parse_fstab_one(
return 0;
is_swap = streq_ptr(fstype, "swap");
+ if (is_swap && !arg_swap_enabled) {
+ log_info("Swap unit generation disabled on kernel command line, ignoring swap entry for %s.", what);
+ return 0;
+ }
what = fstab_node_to_udev_node(what_original);
if (!what)

View File

@ -0,0 +1,119 @@
From 38d81fc89f325801922971229a894038fe207eae Mon Sep 17 00:00:00 2001
From: Yu Watanabe <watanabe.yu+github@gmail.com>
Date: Wed, 24 May 2023 07:04:06 +0900
Subject: [PATCH] fstab-generator: refuse invalid mount point path in fstab
earlier
(cherry picked from commit 6742eca13497dd9dd548ba3e2ced2588d82720ac)
Related: #2190226
---
src/fstab-generator/fstab-generator.c | 68 +++++++++++++--------------
1 file changed, 34 insertions(+), 34 deletions(-)
diff --git a/src/fstab-generator/fstab-generator.c b/src/fstab-generator/fstab-generator.c
index 2cd4de29f0..bd1508bc30 100644
--- a/src/fstab-generator/fstab-generator.c
+++ b/src/fstab-generator/fstab-generator.c
@@ -689,7 +689,7 @@ static int parse_fstab_one(
int passno,
bool initrd) {
- _cleanup_free_ char *what = NULL, *where = NULL, *canonical_where = NULL;
+ _cleanup_free_ char *what = NULL, *where = NULL;
MountPointFlags flags;
bool is_swap;
int r;
@@ -725,50 +725,50 @@ static int parse_fstab_one(
assert(where_original); /* 'where' is not necessary for swap entry. */
- where = strdup(where_original);
- if (!where)
- return log_oom();
-
- if (is_path(where)) {
- path_simplify(where);
+ if (!is_path(where_original)) {
+ log_warning("Mount point %s is not a valid path, ignoring.", where);
+ return 0;
+ }
- /* Follow symlinks here; see 5261ba901845c084de5a8fd06500ed09bfb0bd80 which makes sense for
- * mount units, but causes problems since it historically worked to have symlinks in e.g.
- * /etc/fstab. So we canonicalize here. Note that we use CHASE_NONEXISTENT to handle the case
- * where a symlink refers to another mount target; this works assuming the sub-mountpoint
- * target is the final directory.
- *
- * FIXME: when chase() learns to chase non-existent paths, use this here and
- * drop the prefixing with /sysroot on error below.
- */
- r = chase_symlinks(where, initrd ? "/sysroot" : NULL, CHASE_PREFIX_ROOT | CHASE_NONEXISTENT,
- &canonical_where, NULL);
- if (r < 0) {
- /* If we can't canonicalize, continue as if it wasn't a symlink */
- log_debug_errno(r, "Failed to read symlink target for %s, using as-is: %m", where);
-
- if (initrd) {
- canonical_where = path_join("/sysroot", where);
- if (!canonical_where)
- return log_oom();
- }
+ /* Follow symlinks here; see 5261ba901845c084de5a8fd06500ed09bfb0bd80 which makes sense for
+ * mount units, but causes problems since it historically worked to have symlinks in e.g.
+ * /etc/fstab. So we canonicalize here. Note that we use CHASE_NONEXISTENT to handle the case
+ * where a symlink refers to another mount target; this works assuming the sub-mountpoint
+ * target is the final directory.
+ *
+ * FIXME: when chase() learns to chase non-existent paths, use this here and
+ * drop the prefixing with /sysroot on error below.
+ */
+ r = chase_symlinks(where_original, initrd ? "/sysroot" : NULL, CHASE_PREFIX_ROOT | CHASE_NONEXISTENT, &where, NULL);
+ if (r < 0) {
+ /* If we can't canonicalize, continue as if it wasn't a symlink */
+ log_debug_errno(r, "Failed to read symlink target for %s, using as-is: %m", where_original);
- } else if (streq(canonical_where, where)) /* If it was fully canonicalized, suppress the change */
- canonical_where = mfree(canonical_where);
+ if (initrd)
+ where = path_join("/sysroot", where_original);
else
- log_debug("Canonicalized what=%s where=%s to %s", what, where, canonical_where);
+ where = strdup(where_original);
+ if (!where)
+ return log_oom();
+
+ path_simplify(where);
}
+ if (streq(where, where_original)) /* If it was fully canonicalized, suppress the change */
+ where = mfree(where);
+ else
+ log_debug("Canonicalized what=%s where=%s to %s", what, where_original, where);
+
log_debug("Found entry what=%s where=%s type=%s makefs=%s growfs=%s noauto=%s nofail=%s",
what, where, strna(fstype),
yes_no(flags & MOUNT_MAKEFS), yes_no(flags & MOUNT_GROWFS),
yes_no(flags & MOUNT_NOAUTO), yes_no(flags & MOUNT_NOFAIL));
- bool is_sysroot = in_initrd() && path_equal(where, "/sysroot");
+ bool is_sysroot = in_initrd() && path_equal(where ?: where_original, "/sysroot");
/* See comment from add_sysroot_usr_mount() about the need for extra indirection in case /usr needs
* to be mounted in order for the root fs to be synthesized based on configuration included in /usr/,
* e.g. systemd-repart. */
- bool is_sysroot_usr = in_initrd() && path_equal(where, "/sysroot/usr");
+ bool is_sysroot_usr = in_initrd() && path_equal(where ?: where_original, "/sysroot/usr");
const char *target_unit =
initrd ? SPECIAL_INITRD_FS_TARGET :
@@ -786,8 +786,8 @@ static int parse_fstab_one(
r = add_mount(source,
arg_dest,
what,
- is_sysroot_usr ? "/sysusr/usr" : canonical_where ?: where,
- !is_sysroot_usr && canonical_where ? where : NULL,
+ is_sysroot_usr ? "/sysusr/usr" : where ?: where_original,
+ !is_sysroot_usr && where ? where_original : NULL,
fstype,
options,
passno,

View File

@ -0,0 +1,75 @@
From 00f65b3c9b052007857558ec0776944ffe3979d4 Mon Sep 17 00:00:00 2001
From: Yu Watanabe <watanabe.yu+github@gmail.com>
Date: Mon, 8 May 2023 19:47:17 +0900
Subject: [PATCH] fstab-generator: fix error code propagation in
run_generator()
Previously, some errors might be ignored.
(cherry picked from commit 2646f1844553b5d9c6109ad6b1b86da0b6b1f248)
Related: #2190226
---
src/fstab-generator/fstab-generator.c | 29 +++++++++++++++++++--------
1 file changed, 21 insertions(+), 8 deletions(-)
diff --git a/src/fstab-generator/fstab-generator.c b/src/fstab-generator/fstab-generator.c
index bd1508bc30..c53feb6154 100644
--- a/src/fstab-generator/fstab-generator.c
+++ b/src/fstab-generator/fstab-generator.c
@@ -1265,7 +1265,7 @@ static int determine_usr(void) {
* with /sysroot/etc/fstab available, and then we can write additional units based
* on that file. */
static int run_generator(void) {
- int r, r2 = 0, r3 = 0;
+ int r, ret = 0;
r = proc_cmdline_parse(parse_proc_cmdline_item, NULL, 0);
if (r < 0)
@@ -1286,26 +1286,39 @@ static int run_generator(void) {
/* Always honour root= and usr= in the kernel command line if we are in an initrd */
if (in_initrd()) {
r = add_sysroot_mount();
+ if (r < 0 && ret >= 0)
+ ret = r;
- r2 = add_sysroot_usr_mount_or_fallback();
+ r = add_sysroot_usr_mount_or_fallback();
+ if (r < 0 && ret >= 0)
+ ret = r;
- r3 = add_volatile_root();
- } else
+ r = add_volatile_root();
+ if (r < 0 && ret >= 0)
+ ret = r;
+ } else {
r = add_volatile_var();
+ if (r < 0 && ret >= 0)
+ ret = r;
+ }
/* Honour /etc/fstab only when that's enabled */
if (arg_fstab_enabled) {
/* Parse the local /etc/fstab, possibly from the initrd */
- r2 = parse_fstab(false);
+ r = parse_fstab(false);
+ if (r < 0 && ret >= 0)
+ ret = r;
/* If running in the initrd also parse the /etc/fstab from the host */
if (in_initrd())
- r3 = parse_fstab(true);
+ r = parse_fstab(true);
else
- r3 = generator_enable_remount_fs_service(arg_dest);
+ r = generator_enable_remount_fs_service(arg_dest);
+ if (r < 0 && ret >= 0)
+ ret = r;
}
- return r < 0 ? r : r2 < 0 ? r2 : r3;
+ return ret;
}
static int run(int argc, char **argv) {

View File

@ -0,0 +1,307 @@
From 752ce62315bb38bd1267bd49dccc4dad2e9d05ee Mon Sep 17 00:00:00 2001
From: Yu Watanabe <watanabe.yu+github@gmail.com>
Date: Mon, 8 May 2023 19:49:33 +0900
Subject: [PATCH] fstab-generator: support defining mount units through kernel
command line
Now, the following kernel command line options are supported:
systemd.mount-extra=what:where:fstype:options
systemd.swap-extra=what:options
Closes #27260.
(cherry picked from commit 55365b0a233ae3024411fd0815ad930e20f6a3d6)
Resolves: #2190226
---
man/systemd-fstab-generator.xml | 27 +++++
src/fstab-generator/fstab-generator.c | 164 +++++++++++++++++++++++++-
2 files changed, 186 insertions(+), 5 deletions(-)
diff --git a/man/systemd-fstab-generator.xml b/man/systemd-fstab-generator.xml
index 30204f5d8a..b29022fab7 100644
--- a/man/systemd-fstab-generator.xml
+++ b/man/systemd-fstab-generator.xml
@@ -239,6 +239,33 @@
any swap devices configured in <filename>/etc/fstab</filename>.
Defaults to enabled.</para></listitem>
</varlistentry>
+
+ <varlistentry>
+ <term><varname>systemd.mount-extra=<replaceable>WHAT</replaceable>:<replaceable>WHERE</replaceable>[:<replaceable>FSTYPE</replaceable>[:<replaceable>OPTIONS</replaceable>]]</varname></term>
+
+ <listitem>
+ <para>Specifies the mount unit. Takes at least two and at most four fields separated with a colon
+ (<literal>:</literal>). Each field is handled as the corresponding fstab field. This option can be
+ specified multiple times.</para>
+ <para>Example:
+ <programlisting>
+systemd.mount-extra=/dev/sda1:/mount-point:ext4:rw,noatime</programlisting>
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><varname>systemd.swap-extra=<replaceable>WHAT</replaceable>[:<replaceable>OPTIONS</replaceable>]</varname></term>
+
+ <listitem>
+ <para>Specifies the swap unit. Takes the block device to be used as a swap device, and optionally
+ takes mount options followed by a colon (<literal>:</literal>).</para>
+ <para>Example:
+ <programlisting>
+systemd.swap=/dev/sda2:x-systemd.makefs</programlisting>
+ </para>
+ </listitem>
+ </varlistentry>
</variablelist>
</refsect1>
diff --git a/src/fstab-generator/fstab-generator.c b/src/fstab-generator/fstab-generator.c
index c53feb6154..910e29d26b 100644
--- a/src/fstab-generator/fstab-generator.c
+++ b/src/fstab-generator/fstab-generator.c
@@ -20,6 +20,7 @@
#include "mount-setup.h"
#include "mount-util.h"
#include "mountpoint-util.h"
+#include "nulstr-util.h"
#include "parse-util.h"
#include "path-util.h"
#include "proc-cmdline.h"
@@ -43,6 +44,15 @@ typedef enum MountPointFlags {
MOUNT_RW_ONLY = 1 << 5,
} MountPointFlags;
+typedef struct Mount {
+ char *what;
+ char *where;
+ char *fstype;
+ char *options;
+} Mount;
+
+static void mount_array_free(Mount *mounts, size_t n);
+
static bool arg_sysroot_check = false;
static const char *arg_dest = NULL;
static const char *arg_dest_late = NULL;
@@ -58,6 +68,8 @@ static char *arg_usr_fstype = NULL;
static char *arg_usr_options = NULL;
static char *arg_usr_hash = NULL;
static VolatileMode arg_volatile_mode = _VOLATILE_MODE_INVALID;
+static Mount *arg_mounts = NULL;
+static size_t arg_n_mounts = 0;
STATIC_DESTRUCTOR_REGISTER(arg_root_what, freep);
STATIC_DESTRUCTOR_REGISTER(arg_root_fstype, freep);
@@ -67,6 +79,101 @@ STATIC_DESTRUCTOR_REGISTER(arg_usr_what, freep);
STATIC_DESTRUCTOR_REGISTER(arg_usr_fstype, freep);
STATIC_DESTRUCTOR_REGISTER(arg_usr_options, freep);
STATIC_DESTRUCTOR_REGISTER(arg_usr_hash, freep);
+STATIC_ARRAY_DESTRUCTOR_REGISTER(arg_mounts, arg_n_mounts, mount_array_free);
+
+static void mount_done(Mount *m) {
+ assert(m);
+
+ free(m->what);
+ free(m->where);
+ free(m->fstype);
+ free(m->options);
+}
+
+static void mount_array_free(Mount *mounts, size_t n) {
+ FOREACH_ARRAY(m, mounts, n)
+ mount_done(m);
+
+ free(mounts);
+}
+
+static int mount_array_add_internal(char *in_what, char *in_where, const char *in_fstype, const char *in_options) {
+ _cleanup_free_ char *what = NULL, *where = NULL, *fstype = NULL, *options = NULL;
+ int r;
+
+ /* This takes what and where. */
+
+ what = ASSERT_PTR(in_what);
+ where = in_where;
+
+ fstype = strdup(isempty(in_fstype) ? "auto" : in_fstype);
+ if (!fstype)
+ return -ENOMEM;
+
+ if (streq(fstype, "swap"))
+ where = mfree(where);
+
+ if (!isempty(in_options)) {
+ _cleanup_strv_free_ char **options_strv = NULL;
+
+ r = strv_split_full(&options_strv, in_options, ",", 0);
+ if (r < 0)
+ return r;
+
+ r = strv_make_nulstr(options_strv, &options, NULL);
+ } else
+ r = strv_make_nulstr(STRV_MAKE("defaults"), &options, NULL);
+ if (r < 0)
+ return r;
+
+ if (!GREEDY_REALLOC(arg_mounts, arg_n_mounts + 1))
+ return -ENOMEM;
+
+ arg_mounts[arg_n_mounts++] = (Mount) {
+ .what = TAKE_PTR(what),
+ .where = TAKE_PTR(where),
+ .fstype = TAKE_PTR(fstype),
+ .options = TAKE_PTR(options),
+ };
+
+ return 0;
+}
+
+static int mount_array_add(const char *str) {
+ _cleanup_free_ char *what = NULL, *where = NULL, *fstype = NULL, *options = NULL;
+ int r;
+
+ assert(str);
+
+ r = extract_many_words(&str, ":", EXTRACT_CUNESCAPE | EXTRACT_DONT_COALESCE_SEPARATORS,
+ &what, &where, &fstype, &options, NULL);
+ if (r < 0)
+ return r;
+ if (r < 2)
+ return -EINVAL;
+ if (!isempty(str))
+ return -EINVAL;
+
+ return mount_array_add_internal(TAKE_PTR(what), TAKE_PTR(where), fstype, options);
+}
+
+static int mount_array_add_swap(const char *str) {
+ _cleanup_free_ char *what = NULL, *options = NULL;
+ int r;
+
+ assert(str);
+
+ r = extract_many_words(&str, ":", EXTRACT_CUNESCAPE | EXTRACT_DONT_COALESCE_SEPARATORS,
+ &what, &options, NULL);
+ if (r < 0)
+ return r;
+ if (r < 1)
+ return -EINVAL;
+ if (!isempty(str))
+ return -EINVAL;
+
+ return mount_array_add_internal(TAKE_PTR(what), NULL, "swap", options);
+}
static int write_options(FILE *f, const char *options) {
_cleanup_free_ char *o = NULL;
@@ -109,12 +216,12 @@ static int add_swap(
assert(what);
if (access("/proc/swaps", F_OK) < 0) {
- log_info("Swap not supported, ignoring fstab swap entry for %s.", what);
+ log_info("Swap not supported, ignoring swap entry for %s.", what);
return 0;
}
if (detect_container() > 0) {
- log_info("Running in a container, ignoring fstab swap entry for %s.", what);
+ log_info("Running in a container, ignoring swap entry for %s.", what);
return 0;
}
@@ -687,7 +794,8 @@ static int parse_fstab_one(
const char *fstype,
const char *options,
int passno,
- bool initrd) {
+ bool initrd,
+ bool use_swap_enabled) {
_cleanup_free_ char *what = NULL, *where = NULL;
MountPointFlags flags;
@@ -702,7 +810,7 @@ static int parse_fstab_one(
return 0;
is_swap = streq_ptr(fstype, "swap");
- if (is_swap && !arg_swap_enabled) {
+ if (is_swap && use_swap_enabled && !arg_swap_enabled) {
log_info("Swap unit generation disabled on kernel command line, ignoring swap entry for %s.", what);
return 0;
}
@@ -830,7 +938,9 @@ static int parse_fstab(bool initrd) {
}
while ((me = getmntent(f))) {
- r = parse_fstab_one(fstab, me->mnt_fsname, me->mnt_dir, me->mnt_type, me->mnt_opts, me->mnt_passno, initrd);
+ r = parse_fstab_one(fstab,
+ me->mnt_fsname, me->mnt_dir, me->mnt_type, me->mnt_opts, me->mnt_passno,
+ initrd, /* use_swap_enabled = */ true);
if (r < 0 && ret >= 0)
ret = r;
if (arg_sysroot_check && r > 0)
@@ -1129,6 +1239,28 @@ static int add_volatile_var(void) {
SPECIAL_LOCAL_FS_TARGET);
}
+static int add_mounts_from_cmdline(void) {
+ int r, ret = 0;
+
+ /* Handle each entries found in cmdline as a fstab entry. */
+
+ FOREACH_ARRAY(m, arg_mounts, arg_n_mounts) {
+ r = parse_fstab_one(
+ "/proc/cmdline",
+ m->what,
+ m->where,
+ m->fstype,
+ m->options,
+ /* passno = */ 0,
+ /* initrd = */ false,
+ /* use_swap_enabled = */ false);
+ if (r < 0 && ret >= 0)
+ ret = r;
+ }
+
+ return ret;
+}
+
static int parse_proc_cmdline_item(const char *key, const char *value, void *data) {
int r;
@@ -1225,6 +1357,24 @@ static int parse_proc_cmdline_item(const char *key, const char *value, void *dat
log_warning("Failed to parse systemd.swap switch %s. Ignoring.", value);
else
arg_swap_enabled = r;
+
+ } else if (streq(key, "systemd.mount-extra")) {
+
+ if (proc_cmdline_value_missing(key, value))
+ return 0;
+
+ r = mount_array_add(value);
+ if (r < 0)
+ log_warning("Failed to parse systemd.mount-extra= option, ignoring: %s", value);
+
+ } else if (streq(key, "systemd.swap-extra")) {
+
+ if (proc_cmdline_value_missing(key, value))
+ return 0;
+
+ r = mount_array_add_swap(value);
+ if (r < 0)
+ log_warning("Failed to parse systemd.swap-extra= option, ignoring: %s", value);
}
return 0;
@@ -1318,6 +1468,10 @@ static int run_generator(void) {
ret = r;
}
+ r = add_mounts_from_cmdline();
+ if (r < 0 && ret >= 0)
+ ret = r;
+
return ret;
}

View File

@ -0,0 +1,412 @@
From 329afb79232d9206d8e64fc9cfa3a0e71dda532f Mon Sep 17 00:00:00 2001
From: Yu Watanabe <watanabe.yu+github@gmail.com>
Date: Fri, 12 May 2023 03:55:46 +0900
Subject: [PATCH] test: add test cases for defining mount and swap units from
kernel cmdline
(cherry picked from commit 93ec924c41cece471c9b530cfddcc7cbfd536969)
Related: #2190226
---
test/test-fstab-generator.sh | 20 ++++++++++++++++++-
.../hoge-without_fstype.mount | 11 ++++++++++
.../hoge-without_options.mount | 11 ++++++++++
.../hoge-withx20space.mount | 12 +++++++++++
.../50-root-device.conf | 5 +++++
.../sysroot.mount | 1 +
.../sysroot.mount | 1 +
.../hoge-without_fstype.mount | 1 +
.../hoge-without_options.mount | 1 +
.../hoge-withx20space.mount | 1 +
.../sysroot.mount | 11 ++++++++++
.../test-19-mounts-from-cmdline.input | 5 +++++
.../sysroot.mount | 0
.../dev-sdy1.swap | 9 +++++++++
.../dev-sdy2.swap | 10 ++++++++++
.../systemd-mkswap@dev-sdy2.service | 1 +
.../dev-sdy3.swap | 10 ++++++++++
.../systemd-mkswap@dev-sdy3.service | 1 +
.../dev-sdy4.swap | 9 +++++++++
.../sysroot.mount | 0
.../swap.target.requires/dev-sdy1.swap | 1 +
.../swap.target.requires/dev-sdy2.swap | 1 +
.../swap.target.requires/dev-sdy3.swap | 1 +
.../swap.target.requires/dev-sdy4.swap | 1 +
.../systemd-mkswap@dev-sdy2.service | 18 +++++++++++++++++
.../systemd-mkswap@dev-sdy3.service | 18 +++++++++++++++++
.../test-20-swap-from-cmdline.input | 4 ++++
27 files changed, 163 insertions(+), 1 deletion(-)
create mode 100644 test/test-fstab-generator/test-19-mounts-from-cmdline.expected/hoge-without_fstype.mount
create mode 100644 test/test-fstab-generator/test-19-mounts-from-cmdline.expected/hoge-without_options.mount
create mode 100644 test/test-fstab-generator/test-19-mounts-from-cmdline.expected/hoge-withx20space.mount
create mode 100644 test/test-fstab-generator/test-19-mounts-from-cmdline.expected/initrd-root-device.target.d/50-root-device.conf
create mode 120000 test/test-fstab-generator/test-19-mounts-from-cmdline.expected/initrd-root-fs.target.requires/sysroot.mount
create mode 120000 test/test-fstab-generator/test-19-mounts-from-cmdline.expected/initrd-usr-fs.target.requires/sysroot.mount
create mode 120000 test/test-fstab-generator/test-19-mounts-from-cmdline.expected/local-fs.target.requires/hoge-without_fstype.mount
create mode 120000 test/test-fstab-generator/test-19-mounts-from-cmdline.expected/local-fs.target.requires/hoge-without_options.mount
create mode 120000 test/test-fstab-generator/test-19-mounts-from-cmdline.expected/remote-fs.target.requires/hoge-withx20space.mount
create mode 100644 test/test-fstab-generator/test-19-mounts-from-cmdline.expected/sysroot.mount
create mode 100644 test/test-fstab-generator/test-19-mounts-from-cmdline.input
create mode 100644 test/test-fstab-generator/test-20-swap-from-cmdline.expected.container/initrd-usr-fs.target.requires/sysroot.mount
create mode 100644 test/test-fstab-generator/test-20-swap-from-cmdline.expected/dev-sdy1.swap
create mode 100644 test/test-fstab-generator/test-20-swap-from-cmdline.expected/dev-sdy2.swap
create mode 120000 test/test-fstab-generator/test-20-swap-from-cmdline.expected/dev-sdy2.swap.requires/systemd-mkswap@dev-sdy2.service
create mode 100644 test/test-fstab-generator/test-20-swap-from-cmdline.expected/dev-sdy3.swap
create mode 120000 test/test-fstab-generator/test-20-swap-from-cmdline.expected/dev-sdy3.swap.requires/systemd-mkswap@dev-sdy3.service
create mode 100644 test/test-fstab-generator/test-20-swap-from-cmdline.expected/dev-sdy4.swap
create mode 100644 test/test-fstab-generator/test-20-swap-from-cmdline.expected/initrd-usr-fs.target.requires/sysroot.mount
create mode 120000 test/test-fstab-generator/test-20-swap-from-cmdline.expected/swap.target.requires/dev-sdy1.swap
create mode 120000 test/test-fstab-generator/test-20-swap-from-cmdline.expected/swap.target.requires/dev-sdy2.swap
create mode 120000 test/test-fstab-generator/test-20-swap-from-cmdline.expected/swap.target.requires/dev-sdy3.swap
create mode 120000 test/test-fstab-generator/test-20-swap-from-cmdline.expected/swap.target.requires/dev-sdy4.swap
create mode 100644 test/test-fstab-generator/test-20-swap-from-cmdline.expected/systemd-mkswap@dev-sdy2.service
create mode 100644 test/test-fstab-generator/test-20-swap-from-cmdline.expected/systemd-mkswap@dev-sdy3.service
create mode 100644 test/test-fstab-generator/test-20-swap-from-cmdline.input
diff --git a/test/test-fstab-generator.sh b/test/test-fstab-generator.sh
index 7df67ce305..68c9d0631e 100755
--- a/test/test-fstab-generator.sh
+++ b/test/test-fstab-generator.sh
@@ -28,11 +28,14 @@ for f in "$src"/test-*.input; do
trap "rm -rf '$out'" EXIT INT QUIT PIPE
exp="${f%.input}.expected"
+ if [[ "${f##*/}" =~ swap ]] && systemd-detect-virt --container >/dev/null; then
+ exp="${exp}.container"
+ fi
if [[ "${f##*/}" =~ \.fstab\.input ]]; then
SYSTEMD_LOG_LEVEL=debug SYSTEMD_IN_INITRD=yes SYSTEMD_SYSFS_CHECK=no SYSTEMD_PROC_CMDLINE="fstab=yes root=fstab" SYSTEMD_FSTAB="$f" SYSTEMD_SYSROOT_FSTAB="/dev/null" $generator "$out" "$out" "$out"
else
- SYSTEMD_LOG_LEVEL=debug SYSTEMD_IN_INITRD=yes SYSTEMD_PROC_CMDLINE="fstab=no $(cat "$f")" $generator "$out" "$out" "$out"
+ SYSTEMD_LOG_LEVEL=debug SYSTEMD_IN_INITRD=yes SYSTEMD_SYSFS_CHECK=no SYSTEMD_PROC_CMDLINE="fstab=no $(cat "$f")" $generator "$out" "$out" "$out"
fi
# The option x-systemd.growfs creates symlink to system's systemd-growfs@.service in .mount.wants directory.
@@ -55,6 +58,21 @@ for f in "$src"/test-*.input; do
done
fi
+ # .deb packager seems to dislike files named with backslash. So, as a workaround, we store files
+ # without backslash in .expected.
+ for i in "$out"/**/*\\*.{mount,swap}; do
+ k="${i//\\/}"
+ if [[ "$i" != "$k" ]]; then
+ if [[ -f "$i" ]]; then
+ mv "$i" "$k"
+ elif [[ -L "$i" ]]; then
+ dest=$(readlink "$i")
+ rm "$i"
+ ln -s "${dest//\\/}" "$k"
+ fi
+ fi
+ done
+
# We store empty files rather than dead symlinks, so that they don't get pruned when packaged up, so compare
# the list of filenames rather than their content
if ! diff -u <(find "$out" -printf '%P\n' | sort) <(find "$exp" -printf '%P\n' | sort); then
diff --git a/test/test-fstab-generator/test-19-mounts-from-cmdline.expected/hoge-without_fstype.mount b/test/test-fstab-generator/test-19-mounts-from-cmdline.expected/hoge-without_fstype.mount
new file mode 100644
index 0000000000..4d7d975cc0
--- /dev/null
+++ b/test/test-fstab-generator/test-19-mounts-from-cmdline.expected/hoge-without_fstype.mount
@@ -0,0 +1,11 @@
+# Automatically generated by systemd-fstab-generator
+
+[Unit]
+Documentation=man:fstab(5) man:systemd-fstab-generator(8)
+SourcePath=/proc/cmdline
+Before=local-fs.target
+After=blockdev@dev-sdx3.target
+
+[Mount]
+What=/dev/sdx3
+Where=/hoge/without_fstype
diff --git a/test/test-fstab-generator/test-19-mounts-from-cmdline.expected/hoge-without_options.mount b/test/test-fstab-generator/test-19-mounts-from-cmdline.expected/hoge-without_options.mount
new file mode 100644
index 0000000000..4f16d2e40b
--- /dev/null
+++ b/test/test-fstab-generator/test-19-mounts-from-cmdline.expected/hoge-without_options.mount
@@ -0,0 +1,11 @@
+# Automatically generated by systemd-fstab-generator
+
+[Unit]
+Documentation=man:fstab(5) man:systemd-fstab-generator(8)
+SourcePath=/proc/cmdline
+Before=local-fs.target
+After=blockdev@dev-sdx2.target
+
+[Mount]
+What=/dev/sdx2
+Where=/hoge/without_options
diff --git a/test/test-fstab-generator/test-19-mounts-from-cmdline.expected/hoge-withx20space.mount b/test/test-fstab-generator/test-19-mounts-from-cmdline.expected/hoge-withx20space.mount
new file mode 100644
index 0000000000..e9ffb4bbd9
--- /dev/null
+++ b/test/test-fstab-generator/test-19-mounts-from-cmdline.expected/hoge-withx20space.mount
@@ -0,0 +1,12 @@
+# Automatically generated by systemd-fstab-generator
+
+[Unit]
+Documentation=man:fstab(5) man:systemd-fstab-generator(8)
+SourcePath=/proc/cmdline
+Before=remote-fs.target
+
+[Mount]
+What=//foo￾bar
+Where=/hoge/with space
+Type=cifs
+Options=rw
diff --git a/test/test-fstab-generator/test-19-mounts-from-cmdline.expected/initrd-root-device.target.d/50-root-device.conf b/test/test-fstab-generator/test-19-mounts-from-cmdline.expected/initrd-root-device.target.d/50-root-device.conf
new file mode 100644
index 0000000000..47c4232223
--- /dev/null
+++ b/test/test-fstab-generator/test-19-mounts-from-cmdline.expected/initrd-root-device.target.d/50-root-device.conf
@@ -0,0 +1,5 @@
+# Automatically generated by systemd-fstab-generator
+
+[Unit]
+Requires=dev-sdx1.device
+After=dev-sdx1.device
diff --git a/test/test-fstab-generator/test-19-mounts-from-cmdline.expected/initrd-root-fs.target.requires/sysroot.mount b/test/test-fstab-generator/test-19-mounts-from-cmdline.expected/initrd-root-fs.target.requires/sysroot.mount
new file mode 120000
index 0000000000..0c969cdbd4
--- /dev/null
+++ b/test/test-fstab-generator/test-19-mounts-from-cmdline.expected/initrd-root-fs.target.requires/sysroot.mount
@@ -0,0 +1 @@
+../sysroot.mount
\ No newline at end of file
diff --git a/test/test-fstab-generator/test-19-mounts-from-cmdline.expected/initrd-usr-fs.target.requires/sysroot.mount b/test/test-fstab-generator/test-19-mounts-from-cmdline.expected/initrd-usr-fs.target.requires/sysroot.mount
new file mode 120000
index 0000000000..0c969cdbd4
--- /dev/null
+++ b/test/test-fstab-generator/test-19-mounts-from-cmdline.expected/initrd-usr-fs.target.requires/sysroot.mount
@@ -0,0 +1 @@
+../sysroot.mount
\ No newline at end of file
diff --git a/test/test-fstab-generator/test-19-mounts-from-cmdline.expected/local-fs.target.requires/hoge-without_fstype.mount b/test/test-fstab-generator/test-19-mounts-from-cmdline.expected/local-fs.target.requires/hoge-without_fstype.mount
new file mode 120000
index 0000000000..d46cee354e
--- /dev/null
+++ b/test/test-fstab-generator/test-19-mounts-from-cmdline.expected/local-fs.target.requires/hoge-without_fstype.mount
@@ -0,0 +1 @@
+../hoge-without_fstype.mount
\ No newline at end of file
diff --git a/test/test-fstab-generator/test-19-mounts-from-cmdline.expected/local-fs.target.requires/hoge-without_options.mount b/test/test-fstab-generator/test-19-mounts-from-cmdline.expected/local-fs.target.requires/hoge-without_options.mount
new file mode 120000
index 0000000000..9c790fb248
--- /dev/null
+++ b/test/test-fstab-generator/test-19-mounts-from-cmdline.expected/local-fs.target.requires/hoge-without_options.mount
@@ -0,0 +1 @@
+../hoge-without_options.mount
\ No newline at end of file
diff --git a/test/test-fstab-generator/test-19-mounts-from-cmdline.expected/remote-fs.target.requires/hoge-withx20space.mount b/test/test-fstab-generator/test-19-mounts-from-cmdline.expected/remote-fs.target.requires/hoge-withx20space.mount
new file mode 120000
index 0000000000..2404d7619f
--- /dev/null
+++ b/test/test-fstab-generator/test-19-mounts-from-cmdline.expected/remote-fs.target.requires/hoge-withx20space.mount
@@ -0,0 +1 @@
+../hoge-withx20space.mount
\ No newline at end of file
diff --git a/test/test-fstab-generator/test-19-mounts-from-cmdline.expected/sysroot.mount b/test/test-fstab-generator/test-19-mounts-from-cmdline.expected/sysroot.mount
new file mode 100644
index 0000000000..c8547fa539
--- /dev/null
+++ b/test/test-fstab-generator/test-19-mounts-from-cmdline.expected/sysroot.mount
@@ -0,0 +1,11 @@
+# Automatically generated by systemd-fstab-generator
+
+[Unit]
+Documentation=man:fstab(5) man:systemd-fstab-generator(8)
+SourcePath=/proc/cmdline
+Before=initrd-root-fs.target
+After=blockdev@dev-sdx1.target
+
+[Mount]
+What=/dev/sdx1
+Where=/sysroot
diff --git a/test/test-fstab-generator/test-19-mounts-from-cmdline.input b/test/test-fstab-generator/test-19-mounts-from-cmdline.input
new file mode 100644
index 0000000000..4312d01e52
--- /dev/null
+++ b/test/test-fstab-generator/test-19-mounts-from-cmdline.input
@@ -0,0 +1,5 @@
+systemd.mount-extra=/dev/sdx1:/sysroot:auto:defaults
+systemd.mount-extra=/dev/sdx2:/hoge/without_options:auto
+systemd.mount-extra=/dev/sdx3:/hoge/without_fstype
+systemd.mount-extra=/dev/sdx4
+systemd.mount-extra=//foo\ufffebar:/hoge/with\x20space:cifs:rw,seclabel
diff --git a/test/test-fstab-generator/test-20-swap-from-cmdline.expected.container/initrd-usr-fs.target.requires/sysroot.mount b/test/test-fstab-generator/test-20-swap-from-cmdline.expected.container/initrd-usr-fs.target.requires/sysroot.mount
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/test/test-fstab-generator/test-20-swap-from-cmdline.expected/dev-sdy1.swap b/test/test-fstab-generator/test-20-swap-from-cmdline.expected/dev-sdy1.swap
new file mode 100644
index 0000000000..f515bc149e
--- /dev/null
+++ b/test/test-fstab-generator/test-20-swap-from-cmdline.expected/dev-sdy1.swap
@@ -0,0 +1,9 @@
+# Automatically generated by systemd-fstab-generator
+
+[Unit]
+Documentation=man:fstab(5) man:systemd-fstab-generator(8)
+SourcePath=/proc/cmdline
+After=blockdev@dev-sdy1.target
+
+[Swap]
+What=/dev/sdy1
diff --git a/test/test-fstab-generator/test-20-swap-from-cmdline.expected/dev-sdy2.swap b/test/test-fstab-generator/test-20-swap-from-cmdline.expected/dev-sdy2.swap
new file mode 100644
index 0000000000..104260a60d
--- /dev/null
+++ b/test/test-fstab-generator/test-20-swap-from-cmdline.expected/dev-sdy2.swap
@@ -0,0 +1,10 @@
+# Automatically generated by systemd-fstab-generator
+
+[Unit]
+Documentation=man:fstab(5) man:systemd-fstab-generator(8)
+SourcePath=/proc/cmdline
+After=blockdev@dev-sdy2.target
+
+[Swap]
+What=/dev/sdy2
+Options=x-systemd.makefs
diff --git a/test/test-fstab-generator/test-20-swap-from-cmdline.expected/dev-sdy2.swap.requires/systemd-mkswap@dev-sdy2.service b/test/test-fstab-generator/test-20-swap-from-cmdline.expected/dev-sdy2.swap.requires/systemd-mkswap@dev-sdy2.service
new file mode 120000
index 0000000000..5248a5f8b7
--- /dev/null
+++ b/test/test-fstab-generator/test-20-swap-from-cmdline.expected/dev-sdy2.swap.requires/systemd-mkswap@dev-sdy2.service
@@ -0,0 +1 @@
+../systemd-mkswap@dev-sdy2.service
\ No newline at end of file
diff --git a/test/test-fstab-generator/test-20-swap-from-cmdline.expected/dev-sdy3.swap b/test/test-fstab-generator/test-20-swap-from-cmdline.expected/dev-sdy3.swap
new file mode 100644
index 0000000000..3b6563d216
--- /dev/null
+++ b/test/test-fstab-generator/test-20-swap-from-cmdline.expected/dev-sdy3.swap
@@ -0,0 +1,10 @@
+# Automatically generated by systemd-fstab-generator
+
+[Unit]
+Documentation=man:fstab(5) man:systemd-fstab-generator(8)
+SourcePath=/proc/cmdline
+After=blockdev@dev-sdy3.target
+
+[Swap]
+What=/dev/sdy3
+Options=x-systemd.makefs
diff --git a/test/test-fstab-generator/test-20-swap-from-cmdline.expected/dev-sdy3.swap.requires/systemd-mkswap@dev-sdy3.service b/test/test-fstab-generator/test-20-swap-from-cmdline.expected/dev-sdy3.swap.requires/systemd-mkswap@dev-sdy3.service
new file mode 120000
index 0000000000..e41d758141
--- /dev/null
+++ b/test/test-fstab-generator/test-20-swap-from-cmdline.expected/dev-sdy3.swap.requires/systemd-mkswap@dev-sdy3.service
@@ -0,0 +1 @@
+../systemd-mkswap@dev-sdy3.service
\ No newline at end of file
diff --git a/test/test-fstab-generator/test-20-swap-from-cmdline.expected/dev-sdy4.swap b/test/test-fstab-generator/test-20-swap-from-cmdline.expected/dev-sdy4.swap
new file mode 100644
index 0000000000..37d90f7b64
--- /dev/null
+++ b/test/test-fstab-generator/test-20-swap-from-cmdline.expected/dev-sdy4.swap
@@ -0,0 +1,9 @@
+# Automatically generated by systemd-fstab-generator
+
+[Unit]
+Documentation=man:fstab(5) man:systemd-fstab-generator(8)
+SourcePath=/proc/cmdline
+After=blockdev@dev-sdy4.target
+
+[Swap]
+What=/dev/sdy4
diff --git a/test/test-fstab-generator/test-20-swap-from-cmdline.expected/initrd-usr-fs.target.requires/sysroot.mount b/test/test-fstab-generator/test-20-swap-from-cmdline.expected/initrd-usr-fs.target.requires/sysroot.mount
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/test/test-fstab-generator/test-20-swap-from-cmdline.expected/swap.target.requires/dev-sdy1.swap b/test/test-fstab-generator/test-20-swap-from-cmdline.expected/swap.target.requires/dev-sdy1.swap
new file mode 120000
index 0000000000..a899ff84c0
--- /dev/null
+++ b/test/test-fstab-generator/test-20-swap-from-cmdline.expected/swap.target.requires/dev-sdy1.swap
@@ -0,0 +1 @@
+../dev-sdy1.swap
\ No newline at end of file
diff --git a/test/test-fstab-generator/test-20-swap-from-cmdline.expected/swap.target.requires/dev-sdy2.swap b/test/test-fstab-generator/test-20-swap-from-cmdline.expected/swap.target.requires/dev-sdy2.swap
new file mode 120000
index 0000000000..14df9d6acc
--- /dev/null
+++ b/test/test-fstab-generator/test-20-swap-from-cmdline.expected/swap.target.requires/dev-sdy2.swap
@@ -0,0 +1 @@
+../dev-sdy2.swap
\ No newline at end of file
diff --git a/test/test-fstab-generator/test-20-swap-from-cmdline.expected/swap.target.requires/dev-sdy3.swap b/test/test-fstab-generator/test-20-swap-from-cmdline.expected/swap.target.requires/dev-sdy3.swap
new file mode 120000
index 0000000000..19663fe046
--- /dev/null
+++ b/test/test-fstab-generator/test-20-swap-from-cmdline.expected/swap.target.requires/dev-sdy3.swap
@@ -0,0 +1 @@
+../dev-sdy3.swap
\ No newline at end of file
diff --git a/test/test-fstab-generator/test-20-swap-from-cmdline.expected/swap.target.requires/dev-sdy4.swap b/test/test-fstab-generator/test-20-swap-from-cmdline.expected/swap.target.requires/dev-sdy4.swap
new file mode 120000
index 0000000000..9bfd9d8316
--- /dev/null
+++ b/test/test-fstab-generator/test-20-swap-from-cmdline.expected/swap.target.requires/dev-sdy4.swap
@@ -0,0 +1 @@
+../dev-sdy4.swap
\ No newline at end of file
diff --git a/test/test-fstab-generator/test-20-swap-from-cmdline.expected/systemd-mkswap@dev-sdy2.service b/test/test-fstab-generator/test-20-swap-from-cmdline.expected/systemd-mkswap@dev-sdy2.service
new file mode 100644
index 0000000000..0911f03f62
--- /dev/null
+++ b/test/test-fstab-generator/test-20-swap-from-cmdline.expected/systemd-mkswap@dev-sdy2.service
@@ -0,0 +1,18 @@
+# Automatically generated by systemd-fstab-generator
+
+[Unit]
+Description=Make Swap on %f
+Documentation=man:systemd-mkswap@.service(8)
+
+DefaultDependencies=no
+BindsTo=%i.device
+After=%i.device
+Before=dev-sdy2.swap
+Conflicts=shutdown.target
+Before=shutdown.target
+
+[Service]
+Type=oneshot
+RemainAfterExit=yes
+ExecStart=/usr/lib/systemd/systemd-makefs swap /dev/sdy2
+TimeoutSec=0
diff --git a/test/test-fstab-generator/test-20-swap-from-cmdline.expected/systemd-mkswap@dev-sdy3.service b/test/test-fstab-generator/test-20-swap-from-cmdline.expected/systemd-mkswap@dev-sdy3.service
new file mode 100644
index 0000000000..6201fec86b
--- /dev/null
+++ b/test/test-fstab-generator/test-20-swap-from-cmdline.expected/systemd-mkswap@dev-sdy3.service
@@ -0,0 +1,18 @@
+# Automatically generated by systemd-fstab-generator
+
+[Unit]
+Description=Make Swap on %f
+Documentation=man:systemd-mkswap@.service(8)
+
+DefaultDependencies=no
+BindsTo=%i.device
+After=%i.device
+Before=dev-sdy3.swap
+Conflicts=shutdown.target
+Before=shutdown.target
+
+[Service]
+Type=oneshot
+RemainAfterExit=yes
+ExecStart=/usr/lib/systemd/systemd-makefs swap /dev/sdy3
+TimeoutSec=0
diff --git a/test/test-fstab-generator/test-20-swap-from-cmdline.input b/test/test-fstab-generator/test-20-swap-from-cmdline.input
new file mode 100644
index 0000000000..953c09ff10
--- /dev/null
+++ b/test/test-fstab-generator/test-20-swap-from-cmdline.input
@@ -0,0 +1,4 @@
+systemd.mount-extra=/dev/sdy1:none:swap
+systemd.mount-extra=/dev/sdy2:none:swap:x-systemd.makefs
+systemd.swap-extra=/dev/sdy3:x-systemd.makefs,nofail
+systemd.swap-extra=/dev/sdy4

View File

@ -0,0 +1,221 @@
From cfff52ac273243140b894b735221c0eef2891fe8 Mon Sep 17 00:00:00 2001
From: Lennart Poettering <lennart@poettering.net>
Date: Tue, 6 Jun 2023 09:29:51 +0200
Subject: [PATCH] generators: change TimeoutSec=0 to TimeoutSec=infinity
With these settings we intend to turn off timeouts for possibly
interactive/slow commands. The officially documented way to turn off the
time-outs is to setting them to infinity. So far we set them to zero
here though.
This lead to some confusiong, for example #18224. Let's fix this by
uniformly spelling out TimeoutSec=infinity.
This doesn't change behaviour. It just makes our generated files match
what we document, without relying on historic compat support.
Fixes: #18224
(cherry picked from commit a9b837aa34a2d0bff1687427c66bed3b74cf0fed)
Related: #2190226
---
src/cryptsetup/cryptsetup-generator.c | 3 ++-
src/gpt-auto-generator/gpt-auto-generator.c | 2 +-
src/hibernate-resume/hibernate-resume-generator.c | 3 ++-
src/integritysetup/integritysetup-generator.c | 2 +-
src/shared/generator.c | 8 ++++----
.../test-12-dev-sdx.expected/systemd-fsck-root.service | 2 +-
.../test-13-label.expected/systemd-fsck-root.service | 2 +-
.../test-14-uuid.expected/systemd-fsck-root.service | 2 +-
.../test-15-partuuid.expected/systemd-fsck-root.service | 2 +-
.../systemd-fsck-root.service | 2 +-
.../systemd-fsck-root.service | 2 +-
.../systemd-makefs@dev-sdx12.service | 2 +-
.../systemd-mkswap@dev-sdy2.service | 2 +-
.../systemd-mkswap@dev-sdy3.service | 2 +-
14 files changed, 19 insertions(+), 17 deletions(-)
diff --git a/src/cryptsetup/cryptsetup-generator.c b/src/cryptsetup/cryptsetup-generator.c
index 07903f1044..9e8e7e746f 100644
--- a/src/cryptsetup/cryptsetup-generator.c
+++ b/src/cryptsetup/cryptsetup-generator.c
@@ -551,7 +551,8 @@ static int create_disk(
if (!noauto && !nofail) {
r = write_drop_in(arg_dest, dmname, 40, "device-timeout",
"# Automatically generated by systemd-cryptsetup-generator\n\n"
- "[Unit]\nJobTimeoutSec=0");
+ "[Unit]\n"
+ "JobTimeoutSec=infinity\n");
if (r < 0)
log_warning_errno(r, "Failed to write device timeout drop-in: %m");
}
diff --git a/src/gpt-auto-generator/gpt-auto-generator.c b/src/gpt-auto-generator/gpt-auto-generator.c
index 143faa0c39..0bab43e69a 100644
--- a/src/gpt-auto-generator/gpt-auto-generator.c
+++ b/src/gpt-auto-generator/gpt-auto-generator.c
@@ -112,7 +112,7 @@ static int add_cryptsetup(
r = write_drop_in_format(arg_dest, dmname, 50, "job-timeout",
"# Automatically generated by systemd-gpt-auto-generator\n\n"
"[Unit]\n"
- "JobTimeoutSec=0"); /* the binary handles timeouts anyway */
+ "JobTimeoutSec=infinity"); /* the binary handles timeouts anyway */
if (r < 0)
log_warning_errno(r, "Failed to write device timeout drop-in, ignoring: %m");
diff --git a/src/hibernate-resume/hibernate-resume-generator.c b/src/hibernate-resume/hibernate-resume-generator.c
index 82c2a56493..6714fbf408 100644
--- a/src/hibernate-resume/hibernate-resume-generator.c
+++ b/src/hibernate-resume/hibernate-resume-generator.c
@@ -94,7 +94,8 @@ static int process_resume(void) {
r = write_drop_in(arg_dest, device_unit, 40, "device-timeout",
"# Automatically generated by systemd-hibernate-resume-generator\n\n"
- "[Unit]\nJobTimeoutSec=0");
+ "[Unit]\n"
+ "JobTimeoutSec=infinity\n");
if (r < 0)
log_warning_errno(r, "Failed to write device timeout drop-in: %m");
diff --git a/src/integritysetup/integritysetup-generator.c b/src/integritysetup/integritysetup-generator.c
index 15f508902d..5df6d81a84 100644
--- a/src/integritysetup/integritysetup-generator.c
+++ b/src/integritysetup/integritysetup-generator.c
@@ -100,7 +100,7 @@ static int create_disk(
"[Service]\n"
"Type=oneshot\n"
"RemainAfterExit=yes\n"
- "TimeoutSec=0\n"
+ "TimeoutSec=infinity\n"
"ExecStart=" ROOTLIBEXECDIR "/systemd-integritysetup attach '%s' '%s' '%s' '%s'\n"
"ExecStop=" ROOTLIBEXECDIR "/systemd-integritysetup detach '%s'\n",
name_escaped, device, empty_to_dash(key_file_escaped), empty_to_dash(options),
diff --git a/src/shared/generator.c b/src/shared/generator.c
index 5d617bbe99..f1c5e506ab 100644
--- a/src/shared/generator.c
+++ b/src/shared/generator.c
@@ -218,7 +218,7 @@ static int write_fsck_sysroot_service(
"Type=oneshot\n"
"RemainAfterExit=yes\n"
"ExecStart=" SYSTEMD_FSCK_PATH " %7$s\n"
- "TimeoutSec=0\n",
+ "TimeoutSec=infinity\n",
program_invocation_short_name,
escaped,
unit,
@@ -513,7 +513,7 @@ int generator_hook_up_mkswap(
"Type=oneshot\n"
"RemainAfterExit=yes\n"
"ExecStart="SYSTEMD_MAKEFS_PATH " swap %s\n"
- "TimeoutSec=0\n",
+ "TimeoutSec=infinity\n",
program_invocation_short_name,
where_unit,
escaped);
@@ -594,7 +594,7 @@ int generator_hook_up_mkfs(
"Type=oneshot\n"
"RemainAfterExit=yes\n"
"ExecStart="SYSTEMD_MAKEFS_PATH " %s %s\n"
- "TimeoutSec=0\n",
+ "TimeoutSec=infinity\n",
program_invocation_short_name,
where_unit,
type,
@@ -738,7 +738,7 @@ int generator_write_cryptsetup_service_section(
"[Service]\n"
"Type=oneshot\n"
"RemainAfterExit=yes\n"
- "TimeoutSec=0\n" /* The binary handles timeouts on its own */
+ "TimeoutSec=infinity\n" /* The binary handles timeouts on its own */
"KeyringMode=shared\n" /* Make sure we can share cached keys among instances */
"OOMScoreAdjust=500\n" /* Unlocking can allocate a lot of memory if Argon2 is used */
"ExecStart=" SYSTEMD_CRYPTSETUP_PATH " attach '%s' '%s' '%s' '%s'\n"
diff --git a/test/test-fstab-generator/test-12-dev-sdx.expected/systemd-fsck-root.service b/test/test-fstab-generator/test-12-dev-sdx.expected/systemd-fsck-root.service
index 95d943b87a..147348899d 100644
--- a/test/test-fstab-generator/test-12-dev-sdx.expected/systemd-fsck-root.service
+++ b/test/test-fstab-generator/test-12-dev-sdx.expected/systemd-fsck-root.service
@@ -14,4 +14,4 @@ Before=shutdown.target
Type=oneshot
RemainAfterExit=yes
ExecStart=/usr/lib/systemd/systemd-fsck /dev/sdx1
-TimeoutSec=0
+TimeoutSec=infinity
diff --git a/test/test-fstab-generator/test-13-label.expected/systemd-fsck-root.service b/test/test-fstab-generator/test-13-label.expected/systemd-fsck-root.service
index d6c59ff608..85c1936bce 100644
--- a/test/test-fstab-generator/test-13-label.expected/systemd-fsck-root.service
+++ b/test/test-fstab-generator/test-13-label.expected/systemd-fsck-root.service
@@ -14,4 +14,4 @@ Before=shutdown.target
Type=oneshot
RemainAfterExit=yes
ExecStart=/usr/lib/systemd/systemd-fsck /dev/disk/by-label/Root
-TimeoutSec=0
+TimeoutSec=infinity
diff --git a/test/test-fstab-generator/test-14-uuid.expected/systemd-fsck-root.service b/test/test-fstab-generator/test-14-uuid.expected/systemd-fsck-root.service
index cd9583c4dd..1c7eaea103 100644
--- a/test/test-fstab-generator/test-14-uuid.expected/systemd-fsck-root.service
+++ b/test/test-fstab-generator/test-14-uuid.expected/systemd-fsck-root.service
@@ -14,4 +14,4 @@ Before=shutdown.target
Type=oneshot
RemainAfterExit=yes
ExecStart=/usr/lib/systemd/systemd-fsck /dev/disk/by-uuid/3f5ad593-4546-4a94-a374-bcfb68aa11f7
-TimeoutSec=0
+TimeoutSec=infinity
diff --git a/test/test-fstab-generator/test-15-partuuid.expected/systemd-fsck-root.service b/test/test-fstab-generator/test-15-partuuid.expected/systemd-fsck-root.service
index 650ed8070a..ab27bfd79c 100644
--- a/test/test-fstab-generator/test-15-partuuid.expected/systemd-fsck-root.service
+++ b/test/test-fstab-generator/test-15-partuuid.expected/systemd-fsck-root.service
@@ -14,4 +14,4 @@ Before=shutdown.target
Type=oneshot
RemainAfterExit=yes
ExecStart=/usr/lib/systemd/systemd-fsck /dev/disk/by-partuuid/3f5ad593-4546-4a94-a374-bcfb68aa11f7
-TimeoutSec=0
+TimeoutSec=infinity
diff --git a/test/test-fstab-generator/test-17-initrd-sysroot.fstab.expected/systemd-fsck-root.service b/test/test-fstab-generator/test-17-initrd-sysroot.fstab.expected/systemd-fsck-root.service
index 95d943b87a..147348899d 100644
--- a/test/test-fstab-generator/test-17-initrd-sysroot.fstab.expected/systemd-fsck-root.service
+++ b/test/test-fstab-generator/test-17-initrd-sysroot.fstab.expected/systemd-fsck-root.service
@@ -14,4 +14,4 @@ Before=shutdown.target
Type=oneshot
RemainAfterExit=yes
ExecStart=/usr/lib/systemd/systemd-fsck /dev/sdx1
-TimeoutSec=0
+TimeoutSec=infinity
diff --git a/test/test-fstab-generator/test-18-options.fstab.expected/systemd-fsck-root.service b/test/test-fstab-generator/test-18-options.fstab.expected/systemd-fsck-root.service
index 95d943b87a..147348899d 100644
--- a/test/test-fstab-generator/test-18-options.fstab.expected/systemd-fsck-root.service
+++ b/test/test-fstab-generator/test-18-options.fstab.expected/systemd-fsck-root.service
@@ -14,4 +14,4 @@ Before=shutdown.target
Type=oneshot
RemainAfterExit=yes
ExecStart=/usr/lib/systemd/systemd-fsck /dev/sdx1
-TimeoutSec=0
+TimeoutSec=infinity
diff --git a/test/test-fstab-generator/test-18-options.fstab.expected/systemd-makefs@dev-sdx12.service b/test/test-fstab-generator/test-18-options.fstab.expected/systemd-makefs@dev-sdx12.service
index 303c1ee680..4670c23e27 100644
--- a/test/test-fstab-generator/test-18-options.fstab.expected/systemd-makefs@dev-sdx12.service
+++ b/test/test-fstab-generator/test-18-options.fstab.expected/systemd-makefs@dev-sdx12.service
@@ -15,4 +15,4 @@ Before=shutdown.target
Type=oneshot
RemainAfterExit=yes
ExecStart=/usr/lib/systemd/systemd-makefs ext4 /dev/sdx12
-TimeoutSec=0
+TimeoutSec=infinity
diff --git a/test/test-fstab-generator/test-20-swap-from-cmdline.expected/systemd-mkswap@dev-sdy2.service b/test/test-fstab-generator/test-20-swap-from-cmdline.expected/systemd-mkswap@dev-sdy2.service
index 0911f03f62..0b0e7270ba 100644
--- a/test/test-fstab-generator/test-20-swap-from-cmdline.expected/systemd-mkswap@dev-sdy2.service
+++ b/test/test-fstab-generator/test-20-swap-from-cmdline.expected/systemd-mkswap@dev-sdy2.service
@@ -15,4 +15,4 @@ Before=shutdown.target
Type=oneshot
RemainAfterExit=yes
ExecStart=/usr/lib/systemd/systemd-makefs swap /dev/sdy2
-TimeoutSec=0
+TimeoutSec=infinity
diff --git a/test/test-fstab-generator/test-20-swap-from-cmdline.expected/systemd-mkswap@dev-sdy3.service b/test/test-fstab-generator/test-20-swap-from-cmdline.expected/systemd-mkswap@dev-sdy3.service
index 6201fec86b..1164c99476 100644
--- a/test/test-fstab-generator/test-20-swap-from-cmdline.expected/systemd-mkswap@dev-sdy3.service
+++ b/test/test-fstab-generator/test-20-swap-from-cmdline.expected/systemd-mkswap@dev-sdy3.service
@@ -15,4 +15,4 @@ Before=shutdown.target
Type=oneshot
RemainAfterExit=yes
ExecStart=/usr/lib/systemd/systemd-makefs swap /dev/sdy3
-TimeoutSec=0
+TimeoutSec=infinity

View File

@ -0,0 +1,98 @@
From 169bb520f7032ea699d3cdf46121d2819f562b51 Mon Sep 17 00:00:00 2001
From: Lennart Poettering <lennart@poettering.net>
Date: Tue, 6 Jun 2023 09:29:51 +0200
Subject: [PATCH] units: change TimeoutSec=0 to TimeoutSec=infinity
Follow-up for #27936
Let's also update a bunch of static unit files, matching what we just
did for the generators.
(cherry picked from commit 1775872679f1ace1771a14294306aa6782b5b263)
Related: #2190226
---
test/units/autorelabel.service | 2 +-
units/rc-local.service.in | 2 +-
units/systemd-fsck-root.service.in | 2 +-
units/systemd-fsck@.service.in | 2 +-
units/systemd-growfs-root.service.in | 2 +-
units/systemd-growfs@.service.in | 2 +-
units/systemd-quotacheck.service.in | 2 +-
7 files changed, 7 insertions(+), 7 deletions(-)
diff --git a/test/units/autorelabel.service b/test/units/autorelabel.service
index 1da1002cde..224981f76a 100644
--- a/test/units/autorelabel.service
+++ b/test/units/autorelabel.service
@@ -12,7 +12,7 @@ ConditionPathExists=|/.autorelabel
[Service]
ExecStart=sh -x -c 'echo 0 >/sys/fs/selinux/enforce && fixfiles -f -F relabel && rm /.autorelabel && systemctl --force reboot'
Type=oneshot
-TimeoutSec=0
+TimeoutSec=infinity
RemainAfterExit=yes
[Install]
diff --git a/units/rc-local.service.in b/units/rc-local.service.in
index 0eee722154..40ffc15c99 100644
--- a/units/rc-local.service.in
+++ b/units/rc-local.service.in
@@ -19,6 +19,6 @@ Wants=network-online.target
[Service]
Type=forking
ExecStart={{RC_LOCAL_PATH}} start
-TimeoutSec=0
+TimeoutSec=infinity
RemainAfterExit=yes
GuessMainPID=no
diff --git a/units/systemd-fsck-root.service.in b/units/systemd-fsck-root.service.in
index 8378df84c7..8cfbe7ce98 100644
--- a/units/systemd-fsck-root.service.in
+++ b/units/systemd-fsck-root.service.in
@@ -21,4 +21,4 @@ OnFailureJobMode=replace-irreversibly
Type=oneshot
RemainAfterExit=yes
ExecStart={{ROOTLIBEXECDIR}}/systemd-fsck
-TimeoutSec=0
+TimeoutSec=infinity
diff --git a/units/systemd-fsck@.service.in b/units/systemd-fsck@.service.in
index 06b91aea39..d773229812 100644
--- a/units/systemd-fsck@.service.in
+++ b/units/systemd-fsck@.service.in
@@ -20,4 +20,4 @@ Before=systemd-quotacheck.service shutdown.target
Type=oneshot
RemainAfterExit=yes
ExecStart={{ROOTLIBEXECDIR}}/systemd-fsck %f
-TimeoutSec=0
+TimeoutSec=infinity
diff --git a/units/systemd-growfs-root.service.in b/units/systemd-growfs-root.service.in
index 295bafd5af..1bbd26e0d7 100644
--- a/units/systemd-growfs-root.service.in
+++ b/units/systemd-growfs-root.service.in
@@ -19,4 +19,4 @@ Before=shutdown.target
Type=oneshot
RemainAfterExit=yes
ExecStart={{ROOTLIBEXECDIR}}/systemd-growfs /
-TimeoutSec=0
+TimeoutSec=infinity
diff --git a/units/systemd-growfs@.service.in b/units/systemd-growfs@.service.in
index 7154e4ca76..ff10a3f54e 100644
--- a/units/systemd-growfs@.service.in
+++ b/units/systemd-growfs@.service.in
@@ -20,4 +20,4 @@ Before=shutdown.target
Type=oneshot
RemainAfterExit=yes
ExecStart={{ROOTLIBEXECDIR}}/systemd-growfs %f
-TimeoutSec=0
+TimeoutSec=infinity
diff --git a/units/systemd-quotacheck.service.in b/units/systemd-quotacheck.service.in
index c3e936d220..8e9e9d0691 100644
--- a/units/systemd-quotacheck.service.in
+++ b/units/systemd-quotacheck.service.in
@@ -19,4 +19,4 @@ ConditionPathExists={{QUOTACHECK}}
Type=oneshot
RemainAfterExit=yes
ExecStart={{ROOTLIBEXECDIR}}/systemd-quotacheck
-TimeoutSec=0
+TimeoutSec=infinity

View File

@ -0,0 +1,27 @@
From 34694c7d927e1ac9ff92db95136ebc0a7859e5d5 Mon Sep 17 00:00:00 2001
From: Frantisek Sumsal <frantisek@sumsal.cz>
Date: Fri, 26 May 2023 14:05:40 +0200
Subject: [PATCH] fstab-generator: use correct swap name var
Follow-up to 9445623363.
(cherry picked from commit 3aed25932891d447b5a7ceec6ab61813c06fb0ec)
Related: #2190226
---
src/fstab-generator/fstab-generator.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/fstab-generator/fstab-generator.c b/src/fstab-generator/fstab-generator.c
index 910e29d26b..b92fb40f9b 100644
--- a/src/fstab-generator/fstab-generator.c
+++ b/src/fstab-generator/fstab-generator.c
@@ -811,7 +811,7 @@ static int parse_fstab_one(
is_swap = streq_ptr(fstype, "swap");
if (is_swap && use_swap_enabled && !arg_swap_enabled) {
- log_info("Swap unit generation disabled on kernel command line, ignoring swap entry for %s.", what);
+ log_info("Swap unit generation disabled on kernel command line, ignoring swap entry for %s.", what_original);
return 0;
}

View File

@ -0,0 +1,41 @@
From 25d1a4f55fec8713995eadd8f1830365f872a201 Mon Sep 17 00:00:00 2001
From: Lennart Poettering <lennart@poettering.net>
Date: Fri, 23 Jun 2023 22:49:55 +0200
Subject: [PATCH] fstab-generator: add more parameter name comments
(cherry picked from commit 3a065dfc29aa061906ab9dd886093581410b666a)
Related: #2190226
---
src/fstab-generator/fstab-generator.c | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/src/fstab-generator/fstab-generator.c b/src/fstab-generator/fstab-generator.c
index b92fb40f9b..e403a4c096 100644
--- a/src/fstab-generator/fstab-generator.c
+++ b/src/fstab-generator/fstab-generator.c
@@ -1425,7 +1425,7 @@ static int run_generator(void) {
(void) determine_usr();
if (arg_sysroot_check) {
- r = parse_fstab(true);
+ r = parse_fstab(/* initrd= */ true);
if (r == 0)
log_debug("Nothing interesting found, not doing daemon-reload.");
if (r > 0)
@@ -1455,13 +1455,13 @@ static int run_generator(void) {
/* Honour /etc/fstab only when that's enabled */
if (arg_fstab_enabled) {
/* Parse the local /etc/fstab, possibly from the initrd */
- r = parse_fstab(false);
+ r = parse_fstab(/* initrd= */ false);
if (r < 0 && ret >= 0)
ret = r;
/* If running in the initrd also parse the /etc/fstab from the host */
if (in_initrd())
- r = parse_fstab(true);
+ r = parse_fstab(/* initrd= */ true);
else
r = generator_enable_remount_fs_service(arg_dest);
if (r < 0 && ret >= 0)

View File

@ -0,0 +1,59 @@
From 0d6c4277b6841ad69e7aef6fff5c4c2b29357717 Mon Sep 17 00:00:00 2001
From: Lily Foster <lily@lily.flowers>
Date: Thu, 6 Jul 2023 16:13:53 -0400
Subject: [PATCH] fstab-generator: unify initrd-root-device.target dependency
handling code
This fixes a bug from #26038 where it would actually write generator
stuff during sysroot check when it was only supposed to check for daemon
reload.
(cherry picked from commit 9cf2203524baad8d7ebd298d46633e900daad821)
Related: #2190226
---
src/fstab-generator/fstab-generator.c | 17 ++++++-----------
1 file changed, 6 insertions(+), 11 deletions(-)
diff --git a/src/fstab-generator/fstab-generator.c b/src/fstab-generator/fstab-generator.c
index e403a4c096..6756885478 100644
--- a/src/fstab-generator/fstab-generator.c
+++ b/src/fstab-generator/fstab-generator.c
@@ -601,6 +601,12 @@ static int add_mount(
if (r < 0)
return r;
+ if (in_initrd() && path_equal(where, "/sysroot") && is_device_path(what)) {
+ r = generator_write_initrd_root_device_deps(dest, what);
+ if (r < 0)
+ return r;
+ }
+
r = write_mount_timeout(f, where, opts);
if (r < 0)
return r;
@@ -885,12 +891,6 @@ static int parse_fstab_one(
mount_is_network(fstype, options) ? SPECIAL_REMOTE_FS_TARGET :
SPECIAL_LOCAL_FS_TARGET;
- if (is_sysroot && is_device_path(what)) {
- r = generator_write_initrd_root_device_deps(arg_dest, what);
- if (r < 0)
- return r;
- }
-
r = add_mount(source,
arg_dest,
what,
@@ -1077,11 +1077,6 @@ static int add_sysroot_mount(void) {
log_debug("Found entry what=%s where=/sysroot type=%s opts=%s", what, strna(arg_root_fstype), strempty(opts));
- if (is_device_path(what)) {
- r = generator_write_initrd_root_device_deps(arg_dest, what);
- if (r < 0)
- return r;
- }
return add_mount("/proc/cmdline",
arg_dest,

View File

@ -0,0 +1,72 @@
From fd613a23cb8763da1ac47fcd1d7faacc8fd550d2 Mon Sep 17 00:00:00 2001
From: Mike Yuan <me@yhndnzj.com>
Date: Thu, 13 Jul 2023 23:13:10 +0800
Subject: [PATCH] fstab-util: add fstab_is_bind
(cherry picked from commit 35df78cd88e784abafd5df4545feeb3dd98e14a4)
Related: #2190226
---
src/core/mount.c | 9 +--------
src/shared/fstab-util.c | 13 +++++++++++++
src/shared/fstab-util.h | 2 ++
3 files changed, 16 insertions(+), 8 deletions(-)
diff --git a/src/core/mount.c b/src/core/mount.c
index ba55f7dd86..a46ac804d8 100644
--- a/src/core/mount.c
+++ b/src/core/mount.c
@@ -119,14 +119,7 @@ static bool mount_is_loop(const MountParameters *p) {
static bool mount_is_bind(const MountParameters *p) {
assert(p);
-
- if (fstab_test_option(p->options, "bind\0" "rbind\0"))
- return true;
-
- if (p->fstype && STR_IN_SET(p->fstype, "bind", "rbind"))
- return true;
-
- return false;
+ return fstab_is_bind(p->options, p->fstype);
}
static bool mount_is_bound_to_device(Mount *m) {
diff --git a/src/shared/fstab-util.c b/src/shared/fstab-util.c
index f683f05981..35e0d0d6f7 100644
--- a/src/shared/fstab-util.c
+++ b/src/shared/fstab-util.c
@@ -19,6 +19,8 @@ int fstab_has_fstype(const char *fstype) {
_cleanup_endmntent_ FILE *f = NULL;
struct mntent *m;
+ assert(fstype);
+
f = setmntent(fstab_path(), "re");
if (!f)
return errno == ENOENT ? false : -errno;
@@ -286,3 +288,14 @@ char *fstab_node_to_udev_node(const char *p) {
return strdup(p);
}
+
+bool fstab_is_bind(const char *options, const char *fstype) {
+
+ if (fstab_test_option(options, "bind\0" "rbind\0"))
+ return true;
+
+ if (fstype && STR_IN_SET(fstype, "bind", "rbind"))
+ return true;
+
+ return false;
+}
diff --git a/src/shared/fstab-util.h b/src/shared/fstab-util.h
index 6b596baafa..5979b476b6 100644
--- a/src/shared/fstab-util.h
+++ b/src/shared/fstab-util.h
@@ -40,3 +40,5 @@ char *fstab_node_to_udev_node(const char *p);
static inline const char* fstab_path(void) {
return secure_getenv("SYSTEMD_FSTAB") ?: "/etc/fstab";
}
+
+bool fstab_is_bind(const char *options, const char *fstype);

View File

@ -0,0 +1,150 @@
From e47358d080fb705b4aa89f8506c4bf0e0fce6910 Mon Sep 17 00:00:00 2001
From: Mike Yuan <me@yhndnzj.com>
Date: Thu, 13 Jul 2023 22:44:19 +0800
Subject: [PATCH] fstab-generator: resolve bind mount source when in initrd
We currently prepend /sysroot to mount points for entries
in /sysroot/etc/fstab. But when it comes to bind mounts,
the source needs to canonicalized too.
Fixes #6827
Replaces #7894
(cherry picked from commit b5fd3956ecaff8ef5f0b1826076965cab5fce604)
Related: #2190226
---
src/fstab-generator/fstab-generator.c | 79 ++++++++++++++++++---------
1 file changed, 53 insertions(+), 26 deletions(-)
diff --git a/src/fstab-generator/fstab-generator.c b/src/fstab-generator/fstab-generator.c
index 6756885478..4885d6d722 100644
--- a/src/fstab-generator/fstab-generator.c
+++ b/src/fstab-generator/fstab-generator.c
@@ -793,6 +793,40 @@ static MountPointFlags fstab_options_to_flags(const char *options, bool is_swap)
return flags;
}
+static int canonicalize_mount_path(const char *path, const char *type, bool initrd, char **ret) {
+ _cleanup_free_ char *p = NULL;
+ bool changed;
+ int r;
+
+ assert(path);
+ assert(type);
+ assert(STR_IN_SET(type, "where", "what"));
+ assert(ret);
+
+ // FIXME: when chase() learns to chase non-existent paths, use this here and drop the prefixing with
+ // /sysroot on error below.
+ r = chase_symlinks(path, initrd ? "/sysroot" : NULL, CHASE_PREFIX_ROOT | CHASE_NONEXISTENT, &p, NULL);
+ if (r < 0) {
+ log_debug_errno(r, "Failed to chase '%s', using as-is: %m", path);
+
+ if (initrd)
+ p = path_join("/sysroot", path);
+ else
+ p = strdup(path);
+ if (!p)
+ return log_oom();
+
+ path_simplify(p);
+ }
+
+ changed = !streq(path, p);
+ if (changed)
+ log_debug("Canonicalized %s=%s to %s", type, path, p);
+
+ *ret = TAKE_PTR(p);
+ return changed;
+}
+
static int parse_fstab_one(
const char *source,
const char *what_original,
@@ -805,7 +839,7 @@ static int parse_fstab_one(
_cleanup_free_ char *what = NULL, *where = NULL;
MountPointFlags flags;
- bool is_swap;
+ bool is_swap, where_changed;
int r;
assert(what_original);
@@ -840,7 +874,7 @@ static int parse_fstab_one(
assert(where_original); /* 'where' is not necessary for swap entry. */
if (!is_path(where_original)) {
- log_warning("Mount point %s is not a valid path, ignoring.", where);
+ log_warning("Mount point %s is not a valid path, ignoring.", where_original);
return 0;
}
@@ -848,41 +882,34 @@ static int parse_fstab_one(
* mount units, but causes problems since it historically worked to have symlinks in e.g.
* /etc/fstab. So we canonicalize here. Note that we use CHASE_NONEXISTENT to handle the case
* where a symlink refers to another mount target; this works assuming the sub-mountpoint
- * target is the final directory.
- *
- * FIXME: when chase() learns to chase non-existent paths, use this here and
- * drop the prefixing with /sysroot on error below.
- */
- r = chase_symlinks(where_original, initrd ? "/sysroot" : NULL, CHASE_PREFIX_ROOT | CHASE_NONEXISTENT, &where, NULL);
- if (r < 0) {
- /* If we can't canonicalize, continue as if it wasn't a symlink */
- log_debug_errno(r, "Failed to read symlink target for %s, using as-is: %m", where_original);
+ * target is the final directory. */
+ r = canonicalize_mount_path(where_original, "where", initrd, &where);
+ if (r < 0)
+ return r;
+ where_changed = r > 0;
- if (initrd)
- where = path_join("/sysroot", where_original);
- else
- where = strdup(where_original);
- if (!where)
- return log_oom();
+ if (initrd && fstab_is_bind(options, fstype)) {
+ /* When in initrd, the source of bind mount needs to be prepended with /sysroot as well. */
+ _cleanup_free_ char *p = NULL;
+
+ r = canonicalize_mount_path(what, "what", initrd, &p);
+ if (r < 0)
+ return r;
- path_simplify(where);
+ free_and_replace(what, p);
}
- if (streq(where, where_original)) /* If it was fully canonicalized, suppress the change */
- where = mfree(where);
- else
- log_debug("Canonicalized what=%s where=%s to %s", what, where_original, where);
log_debug("Found entry what=%s where=%s type=%s makefs=%s growfs=%s noauto=%s nofail=%s",
what, where, strna(fstype),
yes_no(flags & MOUNT_MAKEFS), yes_no(flags & MOUNT_GROWFS),
yes_no(flags & MOUNT_NOAUTO), yes_no(flags & MOUNT_NOFAIL));
- bool is_sysroot = in_initrd() && path_equal(where ?: where_original, "/sysroot");
+ bool is_sysroot = in_initrd() && path_equal(where, "/sysroot");
/* See comment from add_sysroot_usr_mount() about the need for extra indirection in case /usr needs
* to be mounted in order for the root fs to be synthesized based on configuration included in /usr/,
* e.g. systemd-repart. */
- bool is_sysroot_usr = in_initrd() && path_equal(where ?: where_original, "/sysroot/usr");
+ bool is_sysroot_usr = in_initrd() && path_equal(where, "/sysroot/usr");
const char *target_unit =
initrd ? SPECIAL_INITRD_FS_TARGET :
@@ -894,8 +921,8 @@ static int parse_fstab_one(
r = add_mount(source,
arg_dest,
what,
- is_sysroot_usr ? "/sysusr/usr" : where ?: where_original,
- !is_sysroot_usr && where ? where_original : NULL,
+ is_sysroot_usr ? "/sysusr/usr" : where,
+ !is_sysroot_usr && where_changed ? where_original : NULL,
fstype,
options,
passno,

View File

@ -0,0 +1,147 @@
From a6a19f42916248badbc087d75c28e9c96a8ddb28 Mon Sep 17 00:00:00 2001
From: Yu Watanabe <watanabe.yu+github@gmail.com>
Date: Wed, 26 Jul 2023 03:17:01 +0900
Subject: [PATCH] fstab-generator: rename 'initrd' flag to 'prefix_sysroot'
The name 'initrd' is confusing with 'in_initrd()'.
(cherry picked from commit 8f88e57397bc6d4f897c4547770e67abd849498d)
Related: #2190226
---
src/fstab-generator/fstab-generator.c | 32 +++++++++++++--------------
1 file changed, 16 insertions(+), 16 deletions(-)
diff --git a/src/fstab-generator/fstab-generator.c b/src/fstab-generator/fstab-generator.c
index 4885d6d722..07f5ae5b73 100644
--- a/src/fstab-generator/fstab-generator.c
+++ b/src/fstab-generator/fstab-generator.c
@@ -793,7 +793,7 @@ static MountPointFlags fstab_options_to_flags(const char *options, bool is_swap)
return flags;
}
-static int canonicalize_mount_path(const char *path, const char *type, bool initrd, char **ret) {
+static int canonicalize_mount_path(const char *path, const char *type, bool prefix_sysroot, char **ret) {
_cleanup_free_ char *p = NULL;
bool changed;
int r;
@@ -805,11 +805,11 @@ static int canonicalize_mount_path(const char *path, const char *type, bool init
// FIXME: when chase() learns to chase non-existent paths, use this here and drop the prefixing with
// /sysroot on error below.
- r = chase_symlinks(path, initrd ? "/sysroot" : NULL, CHASE_PREFIX_ROOT | CHASE_NONEXISTENT, &p, NULL);
+ r = chase_symlinks(path, prefix_sysroot ? "/sysroot" : NULL, CHASE_PREFIX_ROOT | CHASE_NONEXISTENT, &p, NULL);
if (r < 0) {
log_debug_errno(r, "Failed to chase '%s', using as-is: %m", path);
- if (initrd)
+ if (prefix_sysroot)
p = path_join("/sysroot", path);
else
p = strdup(path);
@@ -834,7 +834,7 @@ static int parse_fstab_one(
const char *fstype,
const char *options,
int passno,
- bool initrd,
+ bool prefix_sysroot,
bool use_swap_enabled) {
_cleanup_free_ char *what = NULL, *where = NULL;
@@ -846,7 +846,7 @@ static int parse_fstab_one(
assert(fstype);
assert(options);
- if (initrd && !mount_in_initrd(where_original, options))
+ if (prefix_sysroot && !mount_in_initrd(where_original, options))
return 0;
is_swap = streq_ptr(fstype, "swap");
@@ -883,16 +883,16 @@ static int parse_fstab_one(
* /etc/fstab. So we canonicalize here. Note that we use CHASE_NONEXISTENT to handle the case
* where a symlink refers to another mount target; this works assuming the sub-mountpoint
* target is the final directory. */
- r = canonicalize_mount_path(where_original, "where", initrd, &where);
+ r = canonicalize_mount_path(where_original, "where", prefix_sysroot, &where);
if (r < 0)
return r;
where_changed = r > 0;
- if (initrd && fstab_is_bind(options, fstype)) {
+ if (prefix_sysroot && fstab_is_bind(options, fstype)) {
/* When in initrd, the source of bind mount needs to be prepended with /sysroot as well. */
_cleanup_free_ char *p = NULL;
- r = canonicalize_mount_path(what, "what", initrd, &p);
+ r = canonicalize_mount_path(what, "what", prefix_sysroot, &p);
if (r < 0)
return r;
@@ -912,7 +912,7 @@ static int parse_fstab_one(
bool is_sysroot_usr = in_initrd() && path_equal(where, "/sysroot/usr");
const char *target_unit =
- initrd ? SPECIAL_INITRD_FS_TARGET :
+ prefix_sysroot ? SPECIAL_INITRD_FS_TARGET :
is_sysroot ? SPECIAL_INITRD_ROOT_FS_TARGET :
is_sysroot_usr ? SPECIAL_INITRD_USR_FS_TARGET :
mount_is_network(fstype, options) ? SPECIAL_REMOTE_FS_TARGET :
@@ -941,13 +941,13 @@ static int parse_fstab_one(
return true;
}
-static int parse_fstab(bool initrd) {
+static int parse_fstab(bool prefix_sysroot) {
_cleanup_endmntent_ FILE *f = NULL;
const char *fstab;
struct mntent *me;
int r, ret = 0;
- if (initrd)
+ if (prefix_sysroot)
fstab = sysroot_fstab_path();
else {
fstab = fstab_path();
@@ -967,7 +967,7 @@ static int parse_fstab(bool initrd) {
while ((me = getmntent(f))) {
r = parse_fstab_one(fstab,
me->mnt_fsname, me->mnt_dir, me->mnt_type, me->mnt_opts, me->mnt_passno,
- initrd, /* use_swap_enabled = */ true);
+ prefix_sysroot, /* use_swap_enabled = */ true);
if (r < 0 && ret >= 0)
ret = r;
if (arg_sysroot_check && r > 0)
@@ -1274,7 +1274,7 @@ static int add_mounts_from_cmdline(void) {
m->fstype,
m->options,
/* passno = */ 0,
- /* initrd = */ false,
+ /* prefix_sysroot = */ false,
/* use_swap_enabled = */ false);
if (r < 0 && ret >= 0)
ret = r;
@@ -1447,7 +1447,7 @@ static int run_generator(void) {
(void) determine_usr();
if (arg_sysroot_check) {
- r = parse_fstab(/* initrd= */ true);
+ r = parse_fstab(/* prefix_sysroot = */ true);
if (r == 0)
log_debug("Nothing interesting found, not doing daemon-reload.");
if (r > 0)
@@ -1477,13 +1477,13 @@ static int run_generator(void) {
/* Honour /etc/fstab only when that's enabled */
if (arg_fstab_enabled) {
/* Parse the local /etc/fstab, possibly from the initrd */
- r = parse_fstab(/* initrd= */ false);
+ r = parse_fstab(/* prefix_sysroot = */ false);
if (r < 0 && ret >= 0)
ret = r;
/* If running in the initrd also parse the /etc/fstab from the host */
if (in_initrd())
- r = parse_fstab(/* initrd= */ true);
+ r = parse_fstab(/* prefix_sysroot = */ true);
else
r = generator_enable_remount_fs_service(arg_dest);
if (r < 0 && ret >= 0)

View File

@ -0,0 +1,31 @@
From 8ad2a47f14cd674644d1a4893ec7996c6bcb9be4 Mon Sep 17 00:00:00 2001
From: Yu Watanabe <watanabe.yu+github@gmail.com>
Date: Wed, 26 Jul 2023 09:31:54 +0900
Subject: [PATCH] fstab-generator: fix target of /sysroot/usr
If /usr mount is picked from the main system's fstab file (prefix_sysroot
is true, and the path is prefixed as /sysroot/usr), then previously it
was installed in the wrong target unit.
(cherry picked from commit b93d9e06fc6abbd496ec3fb150a4e01c3b7ec72b)
Related: #2190226
---
src/fstab-generator/fstab-generator.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/fstab-generator/fstab-generator.c b/src/fstab-generator/fstab-generator.c
index 07f5ae5b73..a7c34cfdf7 100644
--- a/src/fstab-generator/fstab-generator.c
+++ b/src/fstab-generator/fstab-generator.c
@@ -912,9 +912,9 @@ static int parse_fstab_one(
bool is_sysroot_usr = in_initrd() && path_equal(where, "/sysroot/usr");
const char *target_unit =
- prefix_sysroot ? SPECIAL_INITRD_FS_TARGET :
is_sysroot ? SPECIAL_INITRD_ROOT_FS_TARGET :
is_sysroot_usr ? SPECIAL_INITRD_USR_FS_TARGET :
+ prefix_sysroot ? SPECIAL_INITRD_FS_TARGET :
mount_is_network(fstype, options) ? SPECIAL_REMOTE_FS_TARGET :
SPECIAL_LOCAL_FS_TARGET;

View File

@ -0,0 +1,201 @@
From a1b1037640e6b01116ad637bbc7abe8612d6e0f4 Mon Sep 17 00:00:00 2001
From: Yu Watanabe <watanabe.yu+github@gmail.com>
Date: Wed, 26 Jul 2023 04:17:27 +0900
Subject: [PATCH] fstab-generator: add rd.systemd.mount-extra= and friends
Previously, mounts specified in systemd.mount-extra= are equally handled
both in initrd and the main system. So, the mounts for the main system
are also mounted in initrd.
This introduces rd.systemd.mount-extra=, which specifies mounts in initrd.
Then, mounts specified in systemd.mount-extra= are still mounted both in
initrd and the main system, but prefixed with /sysroot/ when running in
initrd.
Fixes #28516.
(cherry picked from commit 45c535ddb009d89f2740bdf3a5c88594962759fb)
Related: #2190226
---
man/systemd-fstab-generator.xml | 11 +++++--
src/fstab-generator/fstab-generator.c | 31 +++++++++++++------
.../test-19-mounts-from-cmdline.input | 10 +++---
.../test-20-swap-from-cmdline.input | 8 ++---
4 files changed, 39 insertions(+), 21 deletions(-)
diff --git a/man/systemd-fstab-generator.xml b/man/systemd-fstab-generator.xml
index b29022fab7..66289d6be3 100644
--- a/man/systemd-fstab-generator.xml
+++ b/man/systemd-fstab-generator.xml
@@ -242,11 +242,15 @@
<varlistentry>
<term><varname>systemd.mount-extra=<replaceable>WHAT</replaceable>:<replaceable>WHERE</replaceable>[:<replaceable>FSTYPE</replaceable>[:<replaceable>OPTIONS</replaceable>]]</varname></term>
+ <term><varname>rd.systemd.mount-extra=<replaceable>WHAT</replaceable>:<replaceable>WHERE</replaceable>[:<replaceable>FSTYPE</replaceable>[:<replaceable>OPTIONS</replaceable>]]</varname></term>
<listitem>
<para>Specifies the mount unit. Takes at least two and at most four fields separated with a colon
(<literal>:</literal>). Each field is handled as the corresponding fstab field. This option can be
- specified multiple times.</para>
+ specified multiple times. <varname>rd.systemd.mount-extra=</varname> is honored only in the initrd,
+ while <varname>systemd.mount-extra=</varname> is honored by both the main system and the initrd.
+ In the initrd, the mount point (and also source path if the mount is bind mount) specified in
+ <varname>systemd.mount-extra=</varname> is prefixed with <filename>/sysroot/</filename>.</para>
<para>Example:
<programlisting>
systemd.mount-extra=/dev/sda1:/mount-point:ext4:rw,noatime</programlisting>
@@ -256,10 +260,13 @@ systemd.mount-extra=/dev/sda1:/mount-point:ext4:rw,noatime</programlisting>
<varlistentry>
<term><varname>systemd.swap-extra=<replaceable>WHAT</replaceable>[:<replaceable>OPTIONS</replaceable>]</varname></term>
+ <term><varname>rd.systemd.swap-extra=<replaceable>WHAT</replaceable>[:<replaceable>OPTIONS</replaceable>]</varname></term>
<listitem>
<para>Specifies the swap unit. Takes the block device to be used as a swap device, and optionally
- takes mount options followed by a colon (<literal>:</literal>).</para>
+ takes mount options followed by a colon (<literal>:</literal>). This option can be specified
+ multiple times. <varname>rd.systemd.swap-extra=</varname> is honored only in the initrd, while
+ <varname>systemd.swap-extra=</varname> is honored by both the main system and the initrd.</para>
<para>Example:
<programlisting>
systemd.swap=/dev/sda2:x-systemd.makefs</programlisting>
diff --git a/src/fstab-generator/fstab-generator.c b/src/fstab-generator/fstab-generator.c
index a7c34cfdf7..f91a863a1d 100644
--- a/src/fstab-generator/fstab-generator.c
+++ b/src/fstab-generator/fstab-generator.c
@@ -45,6 +45,7 @@ typedef enum MountPointFlags {
} MountPointFlags;
typedef struct Mount {
+ bool for_initrd;
char *what;
char *where;
char *fstype;
@@ -97,7 +98,13 @@ static void mount_array_free(Mount *mounts, size_t n) {
free(mounts);
}
-static int mount_array_add_internal(char *in_what, char *in_where, const char *in_fstype, const char *in_options) {
+static int mount_array_add_internal(
+ bool for_initrd,
+ char *in_what,
+ char *in_where,
+ const char *in_fstype,
+ const char *in_options) {
+
_cleanup_free_ char *what = NULL, *where = NULL, *fstype = NULL, *options = NULL;
int r;
@@ -130,6 +137,7 @@ static int mount_array_add_internal(char *in_what, char *in_where, const char *i
return -ENOMEM;
arg_mounts[arg_n_mounts++] = (Mount) {
+ .for_initrd = for_initrd,
.what = TAKE_PTR(what),
.where = TAKE_PTR(where),
.fstype = TAKE_PTR(fstype),
@@ -139,7 +147,7 @@ static int mount_array_add_internal(char *in_what, char *in_where, const char *i
return 0;
}
-static int mount_array_add(const char *str) {
+static int mount_array_add(bool for_initrd, const char *str) {
_cleanup_free_ char *what = NULL, *where = NULL, *fstype = NULL, *options = NULL;
int r;
@@ -154,10 +162,10 @@ static int mount_array_add(const char *str) {
if (!isempty(str))
return -EINVAL;
- return mount_array_add_internal(TAKE_PTR(what), TAKE_PTR(where), fstype, options);
+ return mount_array_add_internal(for_initrd, TAKE_PTR(what), TAKE_PTR(where), fstype, options);
}
-static int mount_array_add_swap(const char *str) {
+static int mount_array_add_swap(bool for_initrd, const char *str) {
_cleanup_free_ char *what = NULL, *options = NULL;
int r;
@@ -172,7 +180,7 @@ static int mount_array_add_swap(const char *str) {
if (!isempty(str))
return -EINVAL;
- return mount_array_add_internal(TAKE_PTR(what), NULL, "swap", options);
+ return mount_array_add_internal(for_initrd, TAKE_PTR(what), NULL, "swap", options);
}
static int write_options(FILE *f, const char *options) {
@@ -1267,6 +1275,9 @@ static int add_mounts_from_cmdline(void) {
/* Handle each entries found in cmdline as a fstab entry. */
FOREACH_ARRAY(m, arg_mounts, arg_n_mounts) {
+ if (m->for_initrd && !in_initrd())
+ continue;
+
r = parse_fstab_one(
"/proc/cmdline",
m->what,
@@ -1274,7 +1285,7 @@ static int add_mounts_from_cmdline(void) {
m->fstype,
m->options,
/* passno = */ 0,
- /* prefix_sysroot = */ false,
+ /* prefix_sysroot = */ !m->for_initrd && in_initrd(),
/* use_swap_enabled = */ false);
if (r < 0 && ret >= 0)
ret = r;
@@ -1380,21 +1391,21 @@ static int parse_proc_cmdline_item(const char *key, const char *value, void *dat
else
arg_swap_enabled = r;
- } else if (streq(key, "systemd.mount-extra")) {
+ } else if (STR_IN_SET(key, "systemd.mount-extra", "rd.systemd.mount-extra")) {
if (proc_cmdline_value_missing(key, value))
return 0;
- r = mount_array_add(value);
+ r = mount_array_add(startswith(key, "rd."), value);
if (r < 0)
log_warning("Failed to parse systemd.mount-extra= option, ignoring: %s", value);
- } else if (streq(key, "systemd.swap-extra")) {
+ } else if (STR_IN_SET(key, "systemd.swap-extra", "rd.systemd.swap-extra")) {
if (proc_cmdline_value_missing(key, value))
return 0;
- r = mount_array_add_swap(value);
+ r = mount_array_add_swap(startswith(key, "rd."), value);
if (r < 0)
log_warning("Failed to parse systemd.swap-extra= option, ignoring: %s", value);
}
diff --git a/test/test-fstab-generator/test-19-mounts-from-cmdline.input b/test/test-fstab-generator/test-19-mounts-from-cmdline.input
index 4312d01e52..f2cc6fc075 100644
--- a/test/test-fstab-generator/test-19-mounts-from-cmdline.input
+++ b/test/test-fstab-generator/test-19-mounts-from-cmdline.input
@@ -1,5 +1,5 @@
-systemd.mount-extra=/dev/sdx1:/sysroot:auto:defaults
-systemd.mount-extra=/dev/sdx2:/hoge/without_options:auto
-systemd.mount-extra=/dev/sdx3:/hoge/without_fstype
-systemd.mount-extra=/dev/sdx4
-systemd.mount-extra=//foo\ufffebar:/hoge/with\x20space:cifs:rw,seclabel
+rd.systemd.mount-extra=/dev/sdx1:/sysroot:auto:defaults
+rd.systemd.mount-extra=/dev/sdx2:/hoge/without_options:auto
+rd.systemd.mount-extra=/dev/sdx3:/hoge/without_fstype
+rd.systemd.mount-extra=/dev/sdx4
+rd.systemd.mount-extra=//foo\ufffebar:/hoge/with\x20space:cifs:rw,seclabel
diff --git a/test/test-fstab-generator/test-20-swap-from-cmdline.input b/test/test-fstab-generator/test-20-swap-from-cmdline.input
index 953c09ff10..d92c5300e2 100644
--- a/test/test-fstab-generator/test-20-swap-from-cmdline.input
+++ b/test/test-fstab-generator/test-20-swap-from-cmdline.input
@@ -1,4 +1,4 @@
-systemd.mount-extra=/dev/sdy1:none:swap
-systemd.mount-extra=/dev/sdy2:none:swap:x-systemd.makefs
-systemd.swap-extra=/dev/sdy3:x-systemd.makefs,nofail
-systemd.swap-extra=/dev/sdy4
+rd.systemd.mount-extra=/dev/sdy1:none:swap
+rd.systemd.mount-extra=/dev/sdy2:none:swap:x-systemd.makefs
+rd.systemd.swap-extra=/dev/sdy3:x-systemd.makefs,nofail
+rd.systemd.swap-extra=/dev/sdy4

View File

@ -0,0 +1,79 @@
From c22461b748ca92c3d2bdb799f0b7cd26ce72b03c Mon Sep 17 00:00:00 2001
From: Yu Watanabe <watanabe.yu+github@gmail.com>
Date: Wed, 26 Jul 2023 09:39:23 +0900
Subject: [PATCH] fstab-generator: add a flag to accept entry for "/" in initrd
When both prefix_sysroot and accept_root is true, the entry for "/" will
be accepted and converted to "/sysroot/".
Why? If the entry is read from the main system's fstab, then we already
mounted /sysroot/, hence it is not and should not re-add the .mount unit
for /sysroot/. However, if we want to specify the root mount through the
kernel command line or credential, without this change, we need to
specify the same entry in the two options. E.g.
===
systemd.mount-extra=/dev/sda1:/:auto:defaults
rd.systemd.mount-extra=/dev/sda1:/sysroot:auto:defaults
===
That's inconvenient. Of course, we can dedup that by using traditional
options, but cannot when defined in credential.
(cherry picked from commit 22f5a825e40ad9c8eeae18b763676759d24bb434)
Related: #2190226
---
src/fstab-generator/fstab-generator.c | 12 ++++++++----
1 file changed, 8 insertions(+), 4 deletions(-)
diff --git a/src/fstab-generator/fstab-generator.c b/src/fstab-generator/fstab-generator.c
index f91a863a1d..cf3ff4f598 100644
--- a/src/fstab-generator/fstab-generator.c
+++ b/src/fstab-generator/fstab-generator.c
@@ -307,9 +307,9 @@ static bool mount_is_network(const char *fstype, const char *options) {
(fstype && fstype_is_network(fstype));
}
-static bool mount_in_initrd(const char *where, const char *options) {
+static bool mount_in_initrd(const char *where, const char *options, bool accept_root) {
return fstab_test_option(options, "x-initrd.mount\0") ||
- (where && path_equal(where, "/usr"));
+ (where && PATH_IN_SET(where, "/usr", accept_root ? "/" : NULL));
}
static int write_timeout(
@@ -843,6 +843,7 @@ static int parse_fstab_one(
const char *options,
int passno,
bool prefix_sysroot,
+ bool accept_root, /* This takes an effect only when prefix_sysroot is true. */
bool use_swap_enabled) {
_cleanup_free_ char *what = NULL, *where = NULL;
@@ -854,7 +855,7 @@ static int parse_fstab_one(
assert(fstype);
assert(options);
- if (prefix_sysroot && !mount_in_initrd(where_original, options))
+ if (prefix_sysroot && !mount_in_initrd(where_original, options, accept_root))
return 0;
is_swap = streq_ptr(fstype, "swap");
@@ -975,7 +976,9 @@ static int parse_fstab(bool prefix_sysroot) {
while ((me = getmntent(f))) {
r = parse_fstab_one(fstab,
me->mnt_fsname, me->mnt_dir, me->mnt_type, me->mnt_opts, me->mnt_passno,
- prefix_sysroot, /* use_swap_enabled = */ true);
+ prefix_sysroot,
+ /* accept_root = */ false,
+ /* use_swap_enabled = */ true);
if (r < 0 && ret >= 0)
ret = r;
if (arg_sysroot_check && r > 0)
@@ -1286,6 +1289,7 @@ static int add_mounts_from_cmdline(void) {
m->options,
/* passno = */ 0,
/* prefix_sysroot = */ !m->for_initrd && in_initrd(),
+ /* accept_root = */ true,
/* use_swap_enabled = */ false);
if (r < 0 && ret >= 0)
ret = r;

View File

@ -0,0 +1,223 @@
From 6933334a0d98b65f502abea4183f74275f11a50c Mon Sep 17 00:00:00 2001
From: Yu Watanabe <watanabe.yu+github@gmail.com>
Date: Wed, 26 Jul 2023 06:30:37 +0900
Subject: [PATCH] test-fstab-generator: extract core part as a function
No functional change, preparation for later commits.
(cherry picked from commit 7f8c67c9965a5f70a6c1592db4f5339f4851a5de)
Related: #2190226
---
test/test-fstab-generator.sh | 184 ++++++++++++++++++-----------------
1 file changed, 96 insertions(+), 88 deletions(-)
diff --git a/test/test-fstab-generator.sh b/test/test-fstab-generator.sh
index 68c9d0631e..d5844b8c3f 100755
--- a/test/test-fstab-generator.sh
+++ b/test/test-fstab-generator.sh
@@ -1,10 +1,10 @@
#!/usr/bin/env bash
# SPDX-License-Identifier: LGPL-2.1-or-later
-set -e
+set -eux
shopt -s nullglob
shopt -s globstar
-if [[ -n "$1" ]]; then
+if [[ -n "${1:-}" ]]; then
generator=$1
elif [[ -x /usr/lib/systemd/system-generators/systemd-fstab-generator ]]; then
generator=/usr/lib/systemd/system-generators/systemd-fstab-generator
@@ -19,97 +19,105 @@ src="$(dirname "$0")/testdata/test-fstab-generator"
# fsck(8) is located in /usr/sbin on Debian
PATH=$PATH:/usr/sbin
-for f in "$src"/test-*.input; do
- echo "*** Running $f"
-
- (
- out=$(mktemp --tmpdir --directory "test-fstab-generator.XXXXXXXXXX")
- # shellcheck disable=SC2064
- trap "rm -rf '$out'" EXIT INT QUIT PIPE
-
- exp="${f%.input}.expected"
- if [[ "${f##*/}" =~ swap ]] && systemd-detect-virt --container >/dev/null; then
- exp="${exp}.container"
- fi
-
- if [[ "${f##*/}" =~ \.fstab\.input ]]; then
- SYSTEMD_LOG_LEVEL=debug SYSTEMD_IN_INITRD=yes SYSTEMD_SYSFS_CHECK=no SYSTEMD_PROC_CMDLINE="fstab=yes root=fstab" SYSTEMD_FSTAB="$f" SYSTEMD_SYSROOT_FSTAB="/dev/null" $generator "$out" "$out" "$out"
- else
- SYSTEMD_LOG_LEVEL=debug SYSTEMD_IN_INITRD=yes SYSTEMD_SYSFS_CHECK=no SYSTEMD_PROC_CMDLINE="fstab=no $(cat "$f")" $generator "$out" "$out" "$out"
- fi
-
- # The option x-systemd.growfs creates symlink to system's systemd-growfs@.service in .mount.wants directory.
- # The system that the test is currently running on may not have or may have outdated unit file.
- # Let's replace the symlink with an empty file.
- for i in "$out"/*/systemd-growfs@*.service; do
- [[ -L "$i" ]] || continue
- rm "$i"
- touch "$i"
+test_one() (
+ local input out exp i j k dir fname expf
+
+ input=${1?}
+
+ : "*** Running $input"
+
+ out=$(mktemp --tmpdir --directory "test-fstab-generator.XXXXXXXXXX")
+ # shellcheck disable=SC2064
+ trap "rm -rf '$out'" EXIT INT QUIT PIPE
+
+ exp="${input%.input}.expected"
+ if [[ "${input##*/}" =~ swap ]] && systemd-detect-virt --container >/dev/null; then
+ exp="${exp}.container"
+ fi
+
+ if [[ "${input##*/}" =~ \.fstab\.input ]]; then
+ SYSTEMD_LOG_LEVEL=debug SYSTEMD_IN_INITRD=yes SYSTEMD_SYSFS_CHECK=no SYSTEMD_PROC_CMDLINE="fstab=yes root=fstab" SYSTEMD_FSTAB="$input" SYSTEMD_SYSROOT_FSTAB="/dev/null" $generator "$out" "$out" "$out"
+ else
+ SYSTEMD_LOG_LEVEL=debug SYSTEMD_IN_INITRD=yes SYSTEMD_SYSFS_CHECK=no SYSTEMD_PROC_CMDLINE="fstab=no $(cat "$input")" $generator "$out" "$out" "$out"
+ fi
+
+ # The option x-systemd.growfs creates symlink to system's systemd-growfs@.service in .mount.wants directory.
+ # The system that the test is currently running on may not have or may have outdated unit file.
+ # Let's replace the symlink with an empty file.
+ for i in "$out"/*/systemd-growfs@*.service; do
+ [[ -L "$i" ]] || continue
+ rm "$i"
+ touch "$i"
+ done
+
+ # For split-usr system
+ for i in "$out"/systemd-*.service; do
+ sed -i -e 's:ExecStart=/lib/systemd/:ExecStart=/usr/lib/systemd/:' "$i"
+ done
+
+ if [[ "${input##*/}" =~ \.fstab\.input ]]; then
+ for i in "$out"/*.{automount,mount,swap}; do
+ sed -i -e 's:SourcePath=.*$:SourcePath=/etc/fstab:' "$i"
done
-
- # For split-usr system
- for i in "$out"/systemd-*.service; do
- sed -i -e 's:ExecStart=/lib/systemd/:ExecStart=/usr/lib/systemd/:' "$i"
- done
-
- if [[ "${f##*/}" =~ \.fstab\.input ]]; then
- for i in "$out"/*.{automount,mount,swap}; do
- sed -i -e 's:SourcePath=.*$:SourcePath=/etc/fstab:' "$i"
- done
+ fi
+
+ # .deb packager seems to dislike files named with backslash. So, as a workaround, we store files
+ # without backslash in .expected.
+ for i in "$out"/**/*\\*.{mount,swap}; do
+ k="${i//\\/}"
+ if [[ "$i" != "$k" ]]; then
+ if [[ -f "$i" ]]; then
+ mv "$i" "$k"
+ elif [[ -L "$i" ]]; then
+ dest=$(readlink "$i")
+ rm "$i"
+ ln -s "${dest//\\/}" "$k"
+ fi
fi
-
- # .deb packager seems to dislike files named with backslash. So, as a workaround, we store files
- # without backslash in .expected.
- for i in "$out"/**/*\\*.{mount,swap}; do
- k="${i//\\/}"
- if [[ "$i" != "$k" ]]; then
- if [[ -f "$i" ]]; then
- mv "$i" "$k"
- elif [[ -L "$i" ]]; then
- dest=$(readlink "$i")
- rm "$i"
- ln -s "${dest//\\/}" "$k"
+ done
+
+ # We store empty files rather than dead symlinks, so that they don't get pruned when packaged up, so compare
+ # the list of filenames rather than their content
+ if ! diff -u <(find "$out" -printf '%P\n' | sort) <(find "$exp" -printf '%P\n' | sort); then
+ : "**** Unexpected output for $input"
+ return 1
+ fi
+
+ # Check the main units.
+ if ! diff -u "$out" "$exp"; then
+ : "**** Unexpected output for $input"
+ return 1
+ fi
+
+ # Also check drop-ins.
+ for i in "$out"/*; do
+ [[ -d "$i" ]] || continue
+
+ dir="${i##*/}"
+
+ for j in "$i"/*; do
+ fname="${j##*/}"
+ expf="$exp/$dir/$fname"
+
+ if [[ -L "$j" && ! -e "$j" ]]; then
+ # For dead symlink, we store an empty file.
+ if [[ ! -e "$expf" || -n "$(cat "$expf")" ]]; then
+ : "**** Unexpected symlink $j created by $input"
+ return 1
fi
+ continue
fi
- done
- # We store empty files rather than dead symlinks, so that they don't get pruned when packaged up, so compare
- # the list of filenames rather than their content
- if ! diff -u <(find "$out" -printf '%P\n' | sort) <(find "$exp" -printf '%P\n' | sort); then
- echo "**** Unexpected output for $f"
- exit 1
- fi
-
- # Check the main units.
- if ! diff -u "$out" "$exp"; then
- echo "**** Unexpected output for $f"
- exit 1
- fi
-
- # Also check drop-ins.
- for i in "$out"/*; do
- [[ -d "$i" ]] || continue
-
- dir="${i##*/}"
-
- for j in "$i"/*; do
- fname="${j##*/}"
- expf="$exp/$dir/$fname"
+ if ! diff -u "$j" "$expf"; then
+ : "**** Unexpected output in $j for $input"
+ return 1
+ fi
+ done
+ done
- if [[ -L "$j" && ! -e "$j" ]]; then
- # For dead symlink, we store an empty file.
- if [[ ! -e "$expf" || -n "$(cat "$expf")" ]]; then
- echo "**** Unexpected symlink $j created by $f"
- exit 1
- fi
- continue
- fi
+ return 0
+)
- if ! diff -u "$j" "$expf"; then
- echo "**** Unexpected output in $j for $f"
- exit 1
- fi
- done
- done
- ) || exit 1
+for f in "$src"/test-*.input; do
+ test_one "$f"
done

View File

@ -0,0 +1,738 @@
From aa4e0d1737d0a2ed6cf6c7851009d1de3ffe93da Mon Sep 17 00:00:00 2001
From: Yu Watanabe <watanabe.yu+github@gmail.com>
Date: Wed, 26 Jul 2023 07:04:48 +0900
Subject: [PATCH] test-fstab-generator: also test with SYSTEMD_IN_INITRD=no
(cherry picked from commit aeded6b0b5a41f80d2f4663d8f023af2888b444d)
Related: #2190226
---
test/test-fstab-generator.sh | 31 +++++++++++++------
.../sysroot-usr.mount | 1 +
.../local-fs.target.requires/sysroot.mount | 1 +
.../systemd-remount-fs.service | 0
.../sysroot-usr.mount | 11 +++++++
.../sysroot.mount | 13 ++++++++
.../foo.service.requires/mnt-requiredby.mount | 1 +
.../foo.service.wants/mnt-wantedby.mount | 1 +
...der-systemd-growfs@mnt-growfs.service.conf | 4 +++
.../local-fs.target.requires/mnt-after.mount | 1 +
.../mnt-automount1.automount | 1 +
.../local-fs.target.requires/mnt-before.mount | 1 +
.../local-fs.target.requires/mnt-growfs.mount | 1 +
.../local-fs.target.requires/mnt-mkfs.mount | 1 +
.../local-fs.target.requires/mnt-pcrfs.mount | 1 +
.../mnt-reqmounts.mount | 1 +
.../mnt-requires.mount | 1 +
.../local-fs.target.requires/mnt-rwonly.mount | 1 +
.../mnt-timeout.mount | 1 +
.../local-fs.target.requires/sysroot.mount | 1 +
.../mnt-automount2.automount | 1 +
.../local-fs.target.wants/mnt-nofail.mount | 1 +
.../systemd-remount-fs.service | 0
.../mnt-after.mount | 13 ++++++++
.../mnt-automount1.automount | 9 ++++++
.../mnt-automount1.mount | 12 +++++++
.../mnt-automount2.automount | 8 +++++
.../mnt-automount2.mount | 11 +++++++
.../mnt-before.mount | 13 ++++++++
.../mnt-growfs.mount | 12 +++++++
.../systemd-growfs@mnt-growfs.service | 0
.../mnt-mkfs.mount | 13 ++++++++
.../systemd-makefs@dev-sdx12.service | 1 +
.../mnt-noauto.mount | 12 +++++++
.../mnt-nofail.mount | 11 +++++++
.../mnt-pcrfs.mount | 12 +++++++
.../mnt-reqmounts.mount | 13 ++++++++
.../mnt-requiredby.mount | 12 +++++++
.../mnt-requires.mount | 14 +++++++++
.../mnt-rwonly.mount | 13 ++++++++
.../mnt-timeout.mount | 13 ++++++++
.../mnt-wantedby.mount | 12 +++++++
.../sysroot.mount | 13 ++++++++
.../systemd-makefs@dev-sdx12.service | 18 +++++++++++
44 files changed, 301 insertions(+), 10 deletions(-)
create mode 120000 test/test-fstab-generator/test-17-initrd-sysroot.fstab.expected.sysroot/local-fs.target.requires/sysroot-usr.mount
create mode 120000 test/test-fstab-generator/test-17-initrd-sysroot.fstab.expected.sysroot/local-fs.target.requires/sysroot.mount
create mode 100644 test/test-fstab-generator/test-17-initrd-sysroot.fstab.expected.sysroot/local-fs.target.wants/systemd-remount-fs.service
create mode 100644 test/test-fstab-generator/test-17-initrd-sysroot.fstab.expected.sysroot/sysroot-usr.mount
create mode 100644 test/test-fstab-generator/test-17-initrd-sysroot.fstab.expected.sysroot/sysroot.mount
create mode 120000 test/test-fstab-generator/test-18-options.fstab.expected.sysroot/foo.service.requires/mnt-requiredby.mount
create mode 120000 test/test-fstab-generator/test-18-options.fstab.expected.sysroot/foo.service.wants/mnt-wantedby.mount
create mode 100644 test/test-fstab-generator/test-18-options.fstab.expected.sysroot/local-fs.target.d/50-order-systemd-growfs@mnt-growfs.service.conf
create mode 120000 test/test-fstab-generator/test-18-options.fstab.expected.sysroot/local-fs.target.requires/mnt-after.mount
create mode 120000 test/test-fstab-generator/test-18-options.fstab.expected.sysroot/local-fs.target.requires/mnt-automount1.automount
create mode 120000 test/test-fstab-generator/test-18-options.fstab.expected.sysroot/local-fs.target.requires/mnt-before.mount
create mode 120000 test/test-fstab-generator/test-18-options.fstab.expected.sysroot/local-fs.target.requires/mnt-growfs.mount
create mode 120000 test/test-fstab-generator/test-18-options.fstab.expected.sysroot/local-fs.target.requires/mnt-mkfs.mount
create mode 120000 test/test-fstab-generator/test-18-options.fstab.expected.sysroot/local-fs.target.requires/mnt-pcrfs.mount
create mode 120000 test/test-fstab-generator/test-18-options.fstab.expected.sysroot/local-fs.target.requires/mnt-reqmounts.mount
create mode 120000 test/test-fstab-generator/test-18-options.fstab.expected.sysroot/local-fs.target.requires/mnt-requires.mount
create mode 120000 test/test-fstab-generator/test-18-options.fstab.expected.sysroot/local-fs.target.requires/mnt-rwonly.mount
create mode 120000 test/test-fstab-generator/test-18-options.fstab.expected.sysroot/local-fs.target.requires/mnt-timeout.mount
create mode 120000 test/test-fstab-generator/test-18-options.fstab.expected.sysroot/local-fs.target.requires/sysroot.mount
create mode 120000 test/test-fstab-generator/test-18-options.fstab.expected.sysroot/local-fs.target.wants/mnt-automount2.automount
create mode 120000 test/test-fstab-generator/test-18-options.fstab.expected.sysroot/local-fs.target.wants/mnt-nofail.mount
create mode 100644 test/test-fstab-generator/test-18-options.fstab.expected.sysroot/local-fs.target.wants/systemd-remount-fs.service
create mode 100644 test/test-fstab-generator/test-18-options.fstab.expected.sysroot/mnt-after.mount
create mode 100644 test/test-fstab-generator/test-18-options.fstab.expected.sysroot/mnt-automount1.automount
create mode 100644 test/test-fstab-generator/test-18-options.fstab.expected.sysroot/mnt-automount1.mount
create mode 100644 test/test-fstab-generator/test-18-options.fstab.expected.sysroot/mnt-automount2.automount
create mode 100644 test/test-fstab-generator/test-18-options.fstab.expected.sysroot/mnt-automount2.mount
create mode 100644 test/test-fstab-generator/test-18-options.fstab.expected.sysroot/mnt-before.mount
create mode 100644 test/test-fstab-generator/test-18-options.fstab.expected.sysroot/mnt-growfs.mount
create mode 100644 test/test-fstab-generator/test-18-options.fstab.expected.sysroot/mnt-growfs.mount.wants/systemd-growfs@mnt-growfs.service
create mode 100644 test/test-fstab-generator/test-18-options.fstab.expected.sysroot/mnt-mkfs.mount
create mode 120000 test/test-fstab-generator/test-18-options.fstab.expected.sysroot/mnt-mkfs.mount.requires/systemd-makefs@dev-sdx12.service
create mode 100644 test/test-fstab-generator/test-18-options.fstab.expected.sysroot/mnt-noauto.mount
create mode 100644 test/test-fstab-generator/test-18-options.fstab.expected.sysroot/mnt-nofail.mount
create mode 100644 test/test-fstab-generator/test-18-options.fstab.expected.sysroot/mnt-pcrfs.mount
create mode 100644 test/test-fstab-generator/test-18-options.fstab.expected.sysroot/mnt-reqmounts.mount
create mode 100644 test/test-fstab-generator/test-18-options.fstab.expected.sysroot/mnt-requiredby.mount
create mode 100644 test/test-fstab-generator/test-18-options.fstab.expected.sysroot/mnt-requires.mount
create mode 100644 test/test-fstab-generator/test-18-options.fstab.expected.sysroot/mnt-rwonly.mount
create mode 100644 test/test-fstab-generator/test-18-options.fstab.expected.sysroot/mnt-timeout.mount
create mode 100644 test/test-fstab-generator/test-18-options.fstab.expected.sysroot/mnt-wantedby.mount
create mode 100644 test/test-fstab-generator/test-18-options.fstab.expected.sysroot/sysroot.mount
create mode 100644 test/test-fstab-generator/test-18-options.fstab.expected.sysroot/systemd-makefs@dev-sdx12.service
diff --git a/test/test-fstab-generator.sh b/test/test-fstab-generator.sh
index d5844b8c3f..76097874f4 100755
--- a/test/test-fstab-generator.sh
+++ b/test/test-fstab-generator.sh
@@ -20,11 +20,12 @@ src="$(dirname "$0")/testdata/test-fstab-generator"
PATH=$PATH:/usr/sbin
test_one() (
- local input out exp i j k dir fname expf
+ local initrd input out exp i j k dir fname expf
input=${1?}
+ initrd=${2?}
- : "*** Running $input"
+ : "*** Running $input (initrd=$initrd)"
out=$(mktemp --tmpdir --directory "test-fstab-generator.XXXXXXXXXX")
# shellcheck disable=SC2064
@@ -34,17 +35,21 @@ test_one() (
if [[ "${input##*/}" =~ swap ]] && systemd-detect-virt --container >/dev/null; then
exp="${exp}.container"
fi
+ if [[ "$initrd" == no ]]; then
+ exp="${exp}.sysroot"
+ fi
if [[ "${input##*/}" =~ \.fstab\.input ]]; then
- SYSTEMD_LOG_LEVEL=debug SYSTEMD_IN_INITRD=yes SYSTEMD_SYSFS_CHECK=no SYSTEMD_PROC_CMDLINE="fstab=yes root=fstab" SYSTEMD_FSTAB="$input" SYSTEMD_SYSROOT_FSTAB="/dev/null" $generator "$out" "$out" "$out"
+ SYSTEMD_LOG_LEVEL=debug SYSTEMD_IN_INITRD="$initrd" SYSTEMD_SYSFS_CHECK=no SYSTEMD_PROC_CMDLINE="fstab=yes root=fstab" SYSTEMD_FSTAB="$input" SYSTEMD_SYSROOT_FSTAB="/dev/null" $generator "$out" "$out" "$out"
else
- SYSTEMD_LOG_LEVEL=debug SYSTEMD_IN_INITRD=yes SYSTEMD_SYSFS_CHECK=no SYSTEMD_PROC_CMDLINE="fstab=no $(cat "$input")" $generator "$out" "$out" "$out"
+ SYSTEMD_LOG_LEVEL=debug SYSTEMD_IN_INITRD="$initrd" SYSTEMD_SYSFS_CHECK=no SYSTEMD_PROC_CMDLINE="fstab=no $(cat "$input")" $generator "$out" "$out" "$out"
fi
# The option x-systemd.growfs creates symlink to system's systemd-growfs@.service in .mount.wants directory.
+ # Also, when $initrd is no, symlink to systemd-remount-fs.service is created.
# The system that the test is currently running on may not have or may have outdated unit file.
# Let's replace the symlink with an empty file.
- for i in "$out"/*/systemd-growfs@*.service; do
+ for i in "$out"/*/systemd-growfs@*.service "$out"/local-fs.target.wants/systemd-remount-fs.service; do
[[ -L "$i" ]] || continue
rm "$i"
touch "$i"
@@ -76,16 +81,21 @@ test_one() (
fi
done
+ # We do not store empty directory.
+ if [[ -z "$(ls -A "$out")" && ! -d "$exp" ]]; then
+ return 0
+ fi
+
# We store empty files rather than dead symlinks, so that they don't get pruned when packaged up, so compare
# the list of filenames rather than their content
if ! diff -u <(find "$out" -printf '%P\n' | sort) <(find "$exp" -printf '%P\n' | sort); then
- : "**** Unexpected output for $input"
+ : "**** Unexpected output for $input (initrd=$initrd)"
return 1
fi
# Check the main units.
if ! diff -u "$out" "$exp"; then
- : "**** Unexpected output for $input"
+ : "**** Unexpected output for $input (initrd=$initrd)"
return 1
fi
@@ -102,14 +112,14 @@ test_one() (
if [[ -L "$j" && ! -e "$j" ]]; then
# For dead symlink, we store an empty file.
if [[ ! -e "$expf" || -n "$(cat "$expf")" ]]; then
- : "**** Unexpected symlink $j created by $input"
+ : "**** Unexpected symlink $j created by $input (initrd=$initrd)"
return 1
fi
continue
fi
if ! diff -u "$j" "$expf"; then
- : "**** Unexpected output in $j for $input"
+ : "**** Unexpected output in $j for $input (initrd=$initrd)"
return 1
fi
done
@@ -119,5 +129,6 @@ test_one() (
)
for f in "$src"/test-*.input; do
- test_one "$f"
+ test_one "$f" yes
+ test_one "$f" no
done
diff --git a/test/test-fstab-generator/test-17-initrd-sysroot.fstab.expected.sysroot/local-fs.target.requires/sysroot-usr.mount b/test/test-fstab-generator/test-17-initrd-sysroot.fstab.expected.sysroot/local-fs.target.requires/sysroot-usr.mount
new file mode 120000
index 0000000000..8bcbb16eae
--- /dev/null
+++ b/test/test-fstab-generator/test-17-initrd-sysroot.fstab.expected.sysroot/local-fs.target.requires/sysroot-usr.mount
@@ -0,0 +1 @@
+../sysroot-usr.mount
\ No newline at end of file
diff --git a/test/test-fstab-generator/test-17-initrd-sysroot.fstab.expected.sysroot/local-fs.target.requires/sysroot.mount b/test/test-fstab-generator/test-17-initrd-sysroot.fstab.expected.sysroot/local-fs.target.requires/sysroot.mount
new file mode 120000
index 0000000000..0c969cdbd4
--- /dev/null
+++ b/test/test-fstab-generator/test-17-initrd-sysroot.fstab.expected.sysroot/local-fs.target.requires/sysroot.mount
@@ -0,0 +1 @@
+../sysroot.mount
\ No newline at end of file
diff --git a/test/test-fstab-generator/test-17-initrd-sysroot.fstab.expected.sysroot/local-fs.target.wants/systemd-remount-fs.service b/test/test-fstab-generator/test-17-initrd-sysroot.fstab.expected.sysroot/local-fs.target.wants/systemd-remount-fs.service
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/test/test-fstab-generator/test-17-initrd-sysroot.fstab.expected.sysroot/sysroot-usr.mount b/test/test-fstab-generator/test-17-initrd-sysroot.fstab.expected.sysroot/sysroot-usr.mount
new file mode 100644
index 0000000000..effb6fc6d8
--- /dev/null
+++ b/test/test-fstab-generator/test-17-initrd-sysroot.fstab.expected.sysroot/sysroot-usr.mount
@@ -0,0 +1,11 @@
+# Automatically generated by systemd-fstab-generator
+
+[Unit]
+Documentation=man:fstab(5) man:systemd-fstab-generator(8)
+SourcePath=/etc/fstab
+Before=local-fs.target
+After=blockdev@dev-sdx2.target
+
+[Mount]
+What=/dev/sdx2
+Where=/sysroot/usr
diff --git a/test/test-fstab-generator/test-17-initrd-sysroot.fstab.expected.sysroot/sysroot.mount b/test/test-fstab-generator/test-17-initrd-sysroot.fstab.expected.sysroot/sysroot.mount
new file mode 100644
index 0000000000..56cecc05a0
--- /dev/null
+++ b/test/test-fstab-generator/test-17-initrd-sysroot.fstab.expected.sysroot/sysroot.mount
@@ -0,0 +1,13 @@
+# Automatically generated by systemd-fstab-generator
+
+[Unit]
+Documentation=man:fstab(5) man:systemd-fstab-generator(8)
+SourcePath=/etc/fstab
+Before=local-fs.target
+Requires=systemd-fsck@dev-sdx1.service
+After=systemd-fsck@dev-sdx1.service
+After=blockdev@dev-sdx1.target
+
+[Mount]
+What=/dev/sdx1
+Where=/sysroot
diff --git a/test/test-fstab-generator/test-18-options.fstab.expected.sysroot/foo.service.requires/mnt-requiredby.mount b/test/test-fstab-generator/test-18-options.fstab.expected.sysroot/foo.service.requires/mnt-requiredby.mount
new file mode 120000
index 0000000000..6b012b09ef
--- /dev/null
+++ b/test/test-fstab-generator/test-18-options.fstab.expected.sysroot/foo.service.requires/mnt-requiredby.mount
@@ -0,0 +1 @@
+../mnt-requiredby.mount
\ No newline at end of file
diff --git a/test/test-fstab-generator/test-18-options.fstab.expected.sysroot/foo.service.wants/mnt-wantedby.mount b/test/test-fstab-generator/test-18-options.fstab.expected.sysroot/foo.service.wants/mnt-wantedby.mount
new file mode 120000
index 0000000000..cdf21276b6
--- /dev/null
+++ b/test/test-fstab-generator/test-18-options.fstab.expected.sysroot/foo.service.wants/mnt-wantedby.mount
@@ -0,0 +1 @@
+../mnt-wantedby.mount
\ No newline at end of file
diff --git a/test/test-fstab-generator/test-18-options.fstab.expected.sysroot/local-fs.target.d/50-order-systemd-growfs@mnt-growfs.service.conf b/test/test-fstab-generator/test-18-options.fstab.expected.sysroot/local-fs.target.d/50-order-systemd-growfs@mnt-growfs.service.conf
new file mode 100644
index 0000000000..ac770bcb51
--- /dev/null
+++ b/test/test-fstab-generator/test-18-options.fstab.expected.sysroot/local-fs.target.d/50-order-systemd-growfs@mnt-growfs.service.conf
@@ -0,0 +1,4 @@
+# Automatically generated by systemd-fstab-generator
+
+[Unit]
+After=systemd-growfs@mnt-growfs.service
diff --git a/test/test-fstab-generator/test-18-options.fstab.expected.sysroot/local-fs.target.requires/mnt-after.mount b/test/test-fstab-generator/test-18-options.fstab.expected.sysroot/local-fs.target.requires/mnt-after.mount
new file mode 120000
index 0000000000..68364ef19c
--- /dev/null
+++ b/test/test-fstab-generator/test-18-options.fstab.expected.sysroot/local-fs.target.requires/mnt-after.mount
@@ -0,0 +1 @@
+../mnt-after.mount
\ No newline at end of file
diff --git a/test/test-fstab-generator/test-18-options.fstab.expected.sysroot/local-fs.target.requires/mnt-automount1.automount b/test/test-fstab-generator/test-18-options.fstab.expected.sysroot/local-fs.target.requires/mnt-automount1.automount
new file mode 120000
index 0000000000..3638a8c90e
--- /dev/null
+++ b/test/test-fstab-generator/test-18-options.fstab.expected.sysroot/local-fs.target.requires/mnt-automount1.automount
@@ -0,0 +1 @@
+../mnt-automount1.automount
\ No newline at end of file
diff --git a/test/test-fstab-generator/test-18-options.fstab.expected.sysroot/local-fs.target.requires/mnt-before.mount b/test/test-fstab-generator/test-18-options.fstab.expected.sysroot/local-fs.target.requires/mnt-before.mount
new file mode 120000
index 0000000000..3a50a40d5f
--- /dev/null
+++ b/test/test-fstab-generator/test-18-options.fstab.expected.sysroot/local-fs.target.requires/mnt-before.mount
@@ -0,0 +1 @@
+../mnt-before.mount
\ No newline at end of file
diff --git a/test/test-fstab-generator/test-18-options.fstab.expected.sysroot/local-fs.target.requires/mnt-growfs.mount b/test/test-fstab-generator/test-18-options.fstab.expected.sysroot/local-fs.target.requires/mnt-growfs.mount
new file mode 120000
index 0000000000..cb05081e45
--- /dev/null
+++ b/test/test-fstab-generator/test-18-options.fstab.expected.sysroot/local-fs.target.requires/mnt-growfs.mount
@@ -0,0 +1 @@
+../mnt-growfs.mount
\ No newline at end of file
diff --git a/test/test-fstab-generator/test-18-options.fstab.expected.sysroot/local-fs.target.requires/mnt-mkfs.mount b/test/test-fstab-generator/test-18-options.fstab.expected.sysroot/local-fs.target.requires/mnt-mkfs.mount
new file mode 120000
index 0000000000..51f897e419
--- /dev/null
+++ b/test/test-fstab-generator/test-18-options.fstab.expected.sysroot/local-fs.target.requires/mnt-mkfs.mount
@@ -0,0 +1 @@
+../mnt-mkfs.mount
\ No newline at end of file
diff --git a/test/test-fstab-generator/test-18-options.fstab.expected.sysroot/local-fs.target.requires/mnt-pcrfs.mount b/test/test-fstab-generator/test-18-options.fstab.expected.sysroot/local-fs.target.requires/mnt-pcrfs.mount
new file mode 120000
index 0000000000..276dfc0731
--- /dev/null
+++ b/test/test-fstab-generator/test-18-options.fstab.expected.sysroot/local-fs.target.requires/mnt-pcrfs.mount
@@ -0,0 +1 @@
+../mnt-pcrfs.mount
\ No newline at end of file
diff --git a/test/test-fstab-generator/test-18-options.fstab.expected.sysroot/local-fs.target.requires/mnt-reqmounts.mount b/test/test-fstab-generator/test-18-options.fstab.expected.sysroot/local-fs.target.requires/mnt-reqmounts.mount
new file mode 120000
index 0000000000..7efce8da9a
--- /dev/null
+++ b/test/test-fstab-generator/test-18-options.fstab.expected.sysroot/local-fs.target.requires/mnt-reqmounts.mount
@@ -0,0 +1 @@
+../mnt-reqmounts.mount
\ No newline at end of file
diff --git a/test/test-fstab-generator/test-18-options.fstab.expected.sysroot/local-fs.target.requires/mnt-requires.mount b/test/test-fstab-generator/test-18-options.fstab.expected.sysroot/local-fs.target.requires/mnt-requires.mount
new file mode 120000
index 0000000000..34a6aad26f
--- /dev/null
+++ b/test/test-fstab-generator/test-18-options.fstab.expected.sysroot/local-fs.target.requires/mnt-requires.mount
@@ -0,0 +1 @@
+../mnt-requires.mount
\ No newline at end of file
diff --git a/test/test-fstab-generator/test-18-options.fstab.expected.sysroot/local-fs.target.requires/mnt-rwonly.mount b/test/test-fstab-generator/test-18-options.fstab.expected.sysroot/local-fs.target.requires/mnt-rwonly.mount
new file mode 120000
index 0000000000..d03abd2353
--- /dev/null
+++ b/test/test-fstab-generator/test-18-options.fstab.expected.sysroot/local-fs.target.requires/mnt-rwonly.mount
@@ -0,0 +1 @@
+../mnt-rwonly.mount
\ No newline at end of file
diff --git a/test/test-fstab-generator/test-18-options.fstab.expected.sysroot/local-fs.target.requires/mnt-timeout.mount b/test/test-fstab-generator/test-18-options.fstab.expected.sysroot/local-fs.target.requires/mnt-timeout.mount
new file mode 120000
index 0000000000..b0ec730825
--- /dev/null
+++ b/test/test-fstab-generator/test-18-options.fstab.expected.sysroot/local-fs.target.requires/mnt-timeout.mount
@@ -0,0 +1 @@
+../mnt-timeout.mount
\ No newline at end of file
diff --git a/test/test-fstab-generator/test-18-options.fstab.expected.sysroot/local-fs.target.requires/sysroot.mount b/test/test-fstab-generator/test-18-options.fstab.expected.sysroot/local-fs.target.requires/sysroot.mount
new file mode 120000
index 0000000000..0c969cdbd4
--- /dev/null
+++ b/test/test-fstab-generator/test-18-options.fstab.expected.sysroot/local-fs.target.requires/sysroot.mount
@@ -0,0 +1 @@
+../sysroot.mount
\ No newline at end of file
diff --git a/test/test-fstab-generator/test-18-options.fstab.expected.sysroot/local-fs.target.wants/mnt-automount2.automount b/test/test-fstab-generator/test-18-options.fstab.expected.sysroot/local-fs.target.wants/mnt-automount2.automount
new file mode 120000
index 0000000000..a30481ec1f
--- /dev/null
+++ b/test/test-fstab-generator/test-18-options.fstab.expected.sysroot/local-fs.target.wants/mnt-automount2.automount
@@ -0,0 +1 @@
+../mnt-automount2.automount
\ No newline at end of file
diff --git a/test/test-fstab-generator/test-18-options.fstab.expected.sysroot/local-fs.target.wants/mnt-nofail.mount b/test/test-fstab-generator/test-18-options.fstab.expected.sysroot/local-fs.target.wants/mnt-nofail.mount
new file mode 120000
index 0000000000..b82bbad730
--- /dev/null
+++ b/test/test-fstab-generator/test-18-options.fstab.expected.sysroot/local-fs.target.wants/mnt-nofail.mount
@@ -0,0 +1 @@
+../mnt-nofail.mount
\ No newline at end of file
diff --git a/test/test-fstab-generator/test-18-options.fstab.expected.sysroot/local-fs.target.wants/systemd-remount-fs.service b/test/test-fstab-generator/test-18-options.fstab.expected.sysroot/local-fs.target.wants/systemd-remount-fs.service
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/test/test-fstab-generator/test-18-options.fstab.expected.sysroot/mnt-after.mount b/test/test-fstab-generator/test-18-options.fstab.expected.sysroot/mnt-after.mount
new file mode 100644
index 0000000000..2aebb686a7
--- /dev/null
+++ b/test/test-fstab-generator/test-18-options.fstab.expected.sysroot/mnt-after.mount
@@ -0,0 +1,13 @@
+# Automatically generated by systemd-fstab-generator
+
+[Unit]
+Documentation=man:fstab(5) man:systemd-fstab-generator(8)
+SourcePath=/etc/fstab
+After=foo.service
+Before=local-fs.target
+After=blockdev@dev-sdx3.target
+
+[Mount]
+What=/dev/sdx3
+Where=/mnt/after
+Options=x-systemd.after=foo.service
diff --git a/test/test-fstab-generator/test-18-options.fstab.expected.sysroot/mnt-automount1.automount b/test/test-fstab-generator/test-18-options.fstab.expected.sysroot/mnt-automount1.automount
new file mode 100644
index 0000000000..e376689b67
--- /dev/null
+++ b/test/test-fstab-generator/test-18-options.fstab.expected.sysroot/mnt-automount1.automount
@@ -0,0 +1,9 @@
+# Automatically generated by systemd-fstab-generator
+
+[Unit]
+SourcePath=/etc/fstab
+Documentation=man:fstab(5) man:systemd-fstab-generator(8)
+
+[Automount]
+Where=/mnt/automount1
+TimeoutIdleSec=30min
diff --git a/test/test-fstab-generator/test-18-options.fstab.expected.sysroot/mnt-automount1.mount b/test/test-fstab-generator/test-18-options.fstab.expected.sysroot/mnt-automount1.mount
new file mode 100644
index 0000000000..1413292c79
--- /dev/null
+++ b/test/test-fstab-generator/test-18-options.fstab.expected.sysroot/mnt-automount1.mount
@@ -0,0 +1,12 @@
+# Automatically generated by systemd-fstab-generator
+
+[Unit]
+Documentation=man:fstab(5) man:systemd-fstab-generator(8)
+SourcePath=/etc/fstab
+Before=local-fs.target
+After=blockdev@dev-sdx9.target
+
+[Mount]
+What=/dev/sdx9
+Where=/mnt/automount1
+Options=x-systemd.automount,x-systemd.idle-timeout=30m
diff --git a/test/test-fstab-generator/test-18-options.fstab.expected.sysroot/mnt-automount2.automount b/test/test-fstab-generator/test-18-options.fstab.expected.sysroot/mnt-automount2.automount
new file mode 100644
index 0000000000..e05d3976ef
--- /dev/null
+++ b/test/test-fstab-generator/test-18-options.fstab.expected.sysroot/mnt-automount2.automount
@@ -0,0 +1,8 @@
+# Automatically generated by systemd-fstab-generator
+
+[Unit]
+SourcePath=/etc/fstab
+Documentation=man:fstab(5) man:systemd-fstab-generator(8)
+
+[Automount]
+Where=/mnt/automount2
diff --git a/test/test-fstab-generator/test-18-options.fstab.expected.sysroot/mnt-automount2.mount b/test/test-fstab-generator/test-18-options.fstab.expected.sysroot/mnt-automount2.mount
new file mode 100644
index 0000000000..1eba08c9f7
--- /dev/null
+++ b/test/test-fstab-generator/test-18-options.fstab.expected.sysroot/mnt-automount2.mount
@@ -0,0 +1,11 @@
+# Automatically generated by systemd-fstab-generator
+
+[Unit]
+Documentation=man:fstab(5) man:systemd-fstab-generator(8)
+SourcePath=/etc/fstab
+After=blockdev@dev-sdx10.target
+
+[Mount]
+What=/dev/sdx10
+Where=/mnt/automount2
+Options=x-systemd.automount,nofail
diff --git a/test/test-fstab-generator/test-18-options.fstab.expected.sysroot/mnt-before.mount b/test/test-fstab-generator/test-18-options.fstab.expected.sysroot/mnt-before.mount
new file mode 100644
index 0000000000..eea084b7b6
--- /dev/null
+++ b/test/test-fstab-generator/test-18-options.fstab.expected.sysroot/mnt-before.mount
@@ -0,0 +1,13 @@
+# Automatically generated by systemd-fstab-generator
+
+[Unit]
+Documentation=man:fstab(5) man:systemd-fstab-generator(8)
+SourcePath=/etc/fstab
+Before=foo.service
+Before=local-fs.target
+After=blockdev@dev-sdx4.target
+
+[Mount]
+What=/dev/sdx4
+Where=/mnt/before
+Options=x-systemd.before=foo.service
diff --git a/test/test-fstab-generator/test-18-options.fstab.expected.sysroot/mnt-growfs.mount b/test/test-fstab-generator/test-18-options.fstab.expected.sysroot/mnt-growfs.mount
new file mode 100644
index 0000000000..bbe958c076
--- /dev/null
+++ b/test/test-fstab-generator/test-18-options.fstab.expected.sysroot/mnt-growfs.mount
@@ -0,0 +1,12 @@
+# Automatically generated by systemd-fstab-generator
+
+[Unit]
+Documentation=man:fstab(5) man:systemd-fstab-generator(8)
+SourcePath=/etc/fstab
+Before=local-fs.target
+After=blockdev@dev-sdx13.target
+
+[Mount]
+What=/dev/sdx13
+Where=/mnt/growfs
+Options=x-systemd.growfs
diff --git a/test/test-fstab-generator/test-18-options.fstab.expected.sysroot/mnt-growfs.mount.wants/systemd-growfs@mnt-growfs.service b/test/test-fstab-generator/test-18-options.fstab.expected.sysroot/mnt-growfs.mount.wants/systemd-growfs@mnt-growfs.service
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/test/test-fstab-generator/test-18-options.fstab.expected.sysroot/mnt-mkfs.mount b/test/test-fstab-generator/test-18-options.fstab.expected.sysroot/mnt-mkfs.mount
new file mode 100644
index 0000000000..be4c8fa17f
--- /dev/null
+++ b/test/test-fstab-generator/test-18-options.fstab.expected.sysroot/mnt-mkfs.mount
@@ -0,0 +1,13 @@
+# Automatically generated by systemd-fstab-generator
+
+[Unit]
+Documentation=man:fstab(5) man:systemd-fstab-generator(8)
+SourcePath=/etc/fstab
+Before=local-fs.target
+After=blockdev@dev-sdx12.target
+
+[Mount]
+What=/dev/sdx12
+Where=/mnt/mkfs
+Type=ext4
+Options=x-systemd.makefs
diff --git a/test/test-fstab-generator/test-18-options.fstab.expected.sysroot/mnt-mkfs.mount.requires/systemd-makefs@dev-sdx12.service b/test/test-fstab-generator/test-18-options.fstab.expected.sysroot/mnt-mkfs.mount.requires/systemd-makefs@dev-sdx12.service
new file mode 120000
index 0000000000..fe80548a68
--- /dev/null
+++ b/test/test-fstab-generator/test-18-options.fstab.expected.sysroot/mnt-mkfs.mount.requires/systemd-makefs@dev-sdx12.service
@@ -0,0 +1 @@
+../systemd-makefs@dev-sdx12.service
\ No newline at end of file
diff --git a/test/test-fstab-generator/test-18-options.fstab.expected.sysroot/mnt-noauto.mount b/test/test-fstab-generator/test-18-options.fstab.expected.sysroot/mnt-noauto.mount
new file mode 100644
index 0000000000..4d52a6e698
--- /dev/null
+++ b/test/test-fstab-generator/test-18-options.fstab.expected.sysroot/mnt-noauto.mount
@@ -0,0 +1,12 @@
+# Automatically generated by systemd-fstab-generator
+
+[Unit]
+Documentation=man:fstab(5) man:systemd-fstab-generator(8)
+SourcePath=/etc/fstab
+Before=local-fs.target
+After=blockdev@dev-sdx15.target
+
+[Mount]
+What=/dev/sdx15
+Where=/mnt/noauto
+Options=noauto
diff --git a/test/test-fstab-generator/test-18-options.fstab.expected.sysroot/mnt-nofail.mount b/test/test-fstab-generator/test-18-options.fstab.expected.sysroot/mnt-nofail.mount
new file mode 100644
index 0000000000..3c20b652b0
--- /dev/null
+++ b/test/test-fstab-generator/test-18-options.fstab.expected.sysroot/mnt-nofail.mount
@@ -0,0 +1,11 @@
+# Automatically generated by systemd-fstab-generator
+
+[Unit]
+Documentation=man:fstab(5) man:systemd-fstab-generator(8)
+SourcePath=/etc/fstab
+After=blockdev@dev-sdx16.target
+
+[Mount]
+What=/dev/sdx16
+Where=/mnt/nofail
+Options=nofail
diff --git a/test/test-fstab-generator/test-18-options.fstab.expected.sysroot/mnt-pcrfs.mount b/test/test-fstab-generator/test-18-options.fstab.expected.sysroot/mnt-pcrfs.mount
new file mode 100644
index 0000000000..2c070e695a
--- /dev/null
+++ b/test/test-fstab-generator/test-18-options.fstab.expected.sysroot/mnt-pcrfs.mount
@@ -0,0 +1,12 @@
+# Automatically generated by systemd-fstab-generator
+
+[Unit]
+Documentation=man:fstab(5) man:systemd-fstab-generator(8)
+SourcePath=/etc/fstab
+Before=local-fs.target
+After=blockdev@dev-sdx14.target
+
+[Mount]
+What=/dev/sdx14
+Where=/mnt/pcrfs
+Options=x-systemd.pcrfs
diff --git a/test/test-fstab-generator/test-18-options.fstab.expected.sysroot/mnt-reqmounts.mount b/test/test-fstab-generator/test-18-options.fstab.expected.sysroot/mnt-reqmounts.mount
new file mode 100644
index 0000000000..c21ccd27ba
--- /dev/null
+++ b/test/test-fstab-generator/test-18-options.fstab.expected.sysroot/mnt-reqmounts.mount
@@ -0,0 +1,13 @@
+# Automatically generated by systemd-fstab-generator
+
+[Unit]
+Documentation=man:fstab(5) man:systemd-fstab-generator(8)
+SourcePath=/etc/fstab
+RequiresMountsFor=/hoge
+Before=local-fs.target
+After=blockdev@dev-sdx6.target
+
+[Mount]
+What=/dev/sdx6
+Where=/mnt/reqmounts
+Options=x-systemd.requires-mounts-for=/hoge
diff --git a/test/test-fstab-generator/test-18-options.fstab.expected.sysroot/mnt-requiredby.mount b/test/test-fstab-generator/test-18-options.fstab.expected.sysroot/mnt-requiredby.mount
new file mode 100644
index 0000000000..5edc4ddf22
--- /dev/null
+++ b/test/test-fstab-generator/test-18-options.fstab.expected.sysroot/mnt-requiredby.mount
@@ -0,0 +1,12 @@
+# Automatically generated by systemd-fstab-generator
+
+[Unit]
+Documentation=man:fstab(5) man:systemd-fstab-generator(8)
+SourcePath=/etc/fstab
+Before=local-fs.target
+After=blockdev@dev-sdx8.target
+
+[Mount]
+What=/dev/sdx8
+Where=/mnt/requiredby
+Options=x-systemd.required-by=foo.service
diff --git a/test/test-fstab-generator/test-18-options.fstab.expected.sysroot/mnt-requires.mount b/test/test-fstab-generator/test-18-options.fstab.expected.sysroot/mnt-requires.mount
new file mode 100644
index 0000000000..8386616593
--- /dev/null
+++ b/test/test-fstab-generator/test-18-options.fstab.expected.sysroot/mnt-requires.mount
@@ -0,0 +1,14 @@
+# Automatically generated by systemd-fstab-generator
+
+[Unit]
+Documentation=man:fstab(5) man:systemd-fstab-generator(8)
+SourcePath=/etc/fstab
+After=foo.service
+Requires=foo.service
+Before=local-fs.target
+After=blockdev@dev-sdx5.target
+
+[Mount]
+What=/dev/sdx5
+Where=/mnt/requires
+Options=x-systemd.requires=foo.service
diff --git a/test/test-fstab-generator/test-18-options.fstab.expected.sysroot/mnt-rwonly.mount b/test/test-fstab-generator/test-18-options.fstab.expected.sysroot/mnt-rwonly.mount
new file mode 100644
index 0000000000..8649734386
--- /dev/null
+++ b/test/test-fstab-generator/test-18-options.fstab.expected.sysroot/mnt-rwonly.mount
@@ -0,0 +1,13 @@
+# Automatically generated by systemd-fstab-generator
+
+[Unit]
+Documentation=man:fstab(5) man:systemd-fstab-generator(8)
+SourcePath=/etc/fstab
+Before=local-fs.target
+After=blockdev@dev-sdx11.target
+
+[Mount]
+What=/dev/sdx11
+Where=/mnt/rwonly
+Options=x-systemd.rw-only
+ReadWriteOnly=yes
diff --git a/test/test-fstab-generator/test-18-options.fstab.expected.sysroot/mnt-timeout.mount b/test/test-fstab-generator/test-18-options.fstab.expected.sysroot/mnt-timeout.mount
new file mode 100644
index 0000000000..09d772a52b
--- /dev/null
+++ b/test/test-fstab-generator/test-18-options.fstab.expected.sysroot/mnt-timeout.mount
@@ -0,0 +1,13 @@
+# Automatically generated by systemd-fstab-generator
+
+[Unit]
+Documentation=man:fstab(5) man:systemd-fstab-generator(8)
+SourcePath=/etc/fstab
+Before=local-fs.target
+After=blockdev@dev-sdx2.target
+
+[Mount]
+What=/dev/sdx2
+Where=/mnt/timeout
+TimeoutSec=10min
+Options=x-systemd.mount-timeout=10m
diff --git a/test/test-fstab-generator/test-18-options.fstab.expected.sysroot/mnt-wantedby.mount b/test/test-fstab-generator/test-18-options.fstab.expected.sysroot/mnt-wantedby.mount
new file mode 100644
index 0000000000..e12df820d4
--- /dev/null
+++ b/test/test-fstab-generator/test-18-options.fstab.expected.sysroot/mnt-wantedby.mount
@@ -0,0 +1,12 @@
+# Automatically generated by systemd-fstab-generator
+
+[Unit]
+Documentation=man:fstab(5) man:systemd-fstab-generator(8)
+SourcePath=/etc/fstab
+Before=local-fs.target
+After=blockdev@dev-sdx7.target
+
+[Mount]
+What=/dev/sdx7
+Where=/mnt/wantedby
+Options=x-systemd.wanted-by=foo.service
diff --git a/test/test-fstab-generator/test-18-options.fstab.expected.sysroot/sysroot.mount b/test/test-fstab-generator/test-18-options.fstab.expected.sysroot/sysroot.mount
new file mode 100644
index 0000000000..56cecc05a0
--- /dev/null
+++ b/test/test-fstab-generator/test-18-options.fstab.expected.sysroot/sysroot.mount
@@ -0,0 +1,13 @@
+# Automatically generated by systemd-fstab-generator
+
+[Unit]
+Documentation=man:fstab(5) man:systemd-fstab-generator(8)
+SourcePath=/etc/fstab
+Before=local-fs.target
+Requires=systemd-fsck@dev-sdx1.service
+After=systemd-fsck@dev-sdx1.service
+After=blockdev@dev-sdx1.target
+
+[Mount]
+What=/dev/sdx1
+Where=/sysroot
diff --git a/test/test-fstab-generator/test-18-options.fstab.expected.sysroot/systemd-makefs@dev-sdx12.service b/test/test-fstab-generator/test-18-options.fstab.expected.sysroot/systemd-makefs@dev-sdx12.service
new file mode 100644
index 0000000000..4670c23e27
--- /dev/null
+++ b/test/test-fstab-generator/test-18-options.fstab.expected.sysroot/systemd-makefs@dev-sdx12.service
@@ -0,0 +1,18 @@
+# Automatically generated by systemd-fstab-generator
+
+[Unit]
+Description=Make File System on %f
+Documentation=man:systemd-makefs@.service(8)
+
+DefaultDependencies=no
+BindsTo=%i.device
+After=%i.device
+Before=systemd-fsck@%i.service mnt-mkfs.mount
+Conflicts=shutdown.target
+Before=shutdown.target
+
+[Service]
+Type=oneshot
+RemainAfterExit=yes
+ExecStart=/usr/lib/systemd/systemd-makefs ext4 /dev/sdx12
+TimeoutSec=infinity

View File

@ -0,0 +1,295 @@
From 51fc4ab85319890e7af8cdc3ac1314e8d9e00a6e Mon Sep 17 00:00:00 2001
From: Yu Watanabe <watanabe.yu+github@gmail.com>
Date: Wed, 26 Jul 2023 07:37:29 +0900
Subject: [PATCH] test-fstab-generator: add more tests for systemd.mount-extra=
and friends
(cherry picked from commit 03de154a1ecea1acef36a469157548b6a55921a5)
Related: #2190226
---
.../foo-also_in_initrd.mount | 12 ++++++++++++
.../foo-not_in_initrd.mount | 11 +++++++++++
.../foo-also_in_initrd.mount | 1 +
.../foo-not_in_initrd.mount | 1 +
.../local-fs.target.requires/usr.mount | 1 +
.../usr.mount | 11 +++++++++++
.../sysroot-foo-also_in_initrd.mount | 1 +
.../initrd-fs.target.requires/sysroot-usr.mount | 1 +
.../initrd-usr-fs.target.requires/sysusr-usr.mount | 1 +
.../sysroot-foo-also_in_initrd.mount | 13 +++++++++++++
.../sysroot-usr.mount | 11 +++++++++++
.../sysusr-usr.mount | 11 +++++++++++
.../test-19-mounts-from-cmdline.input | 3 +++
.../dev-sdy5.swap | 10 ++++++++++
.../dev-sdy6.swap | 9 +++++++++
.../swap.target.requires/dev-sdy5.swap | 1 +
.../swap.target.requires/dev-sdy6.swap | 1 +
.../dev-sdy5.swap | 10 ++++++++++
.../swap.target.requires/dev-sdy5.swap | 1 +
.../test-20-swap-from-cmdline.input | 2 ++
20 files changed, 112 insertions(+)
create mode 100644 test/test-fstab-generator/test-19-mounts-from-cmdline.expected.sysroot/foo-also_in_initrd.mount
create mode 100644 test/test-fstab-generator/test-19-mounts-from-cmdline.expected.sysroot/foo-not_in_initrd.mount
create mode 120000 test/test-fstab-generator/test-19-mounts-from-cmdline.expected.sysroot/local-fs.target.requires/foo-also_in_initrd.mount
create mode 120000 test/test-fstab-generator/test-19-mounts-from-cmdline.expected.sysroot/local-fs.target.requires/foo-not_in_initrd.mount
create mode 120000 test/test-fstab-generator/test-19-mounts-from-cmdline.expected.sysroot/local-fs.target.requires/usr.mount
create mode 100644 test/test-fstab-generator/test-19-mounts-from-cmdline.expected.sysroot/usr.mount
create mode 120000 test/test-fstab-generator/test-19-mounts-from-cmdline.expected/initrd-fs.target.requires/sysroot-foo-also_in_initrd.mount
create mode 120000 test/test-fstab-generator/test-19-mounts-from-cmdline.expected/initrd-fs.target.requires/sysroot-usr.mount
create mode 120000 test/test-fstab-generator/test-19-mounts-from-cmdline.expected/initrd-usr-fs.target.requires/sysusr-usr.mount
create mode 100644 test/test-fstab-generator/test-19-mounts-from-cmdline.expected/sysroot-foo-also_in_initrd.mount
create mode 100644 test/test-fstab-generator/test-19-mounts-from-cmdline.expected/sysroot-usr.mount
create mode 100644 test/test-fstab-generator/test-19-mounts-from-cmdline.expected/sysusr-usr.mount
create mode 100644 test/test-fstab-generator/test-20-swap-from-cmdline.expected.sysroot/dev-sdy5.swap
create mode 100644 test/test-fstab-generator/test-20-swap-from-cmdline.expected.sysroot/dev-sdy6.swap
create mode 120000 test/test-fstab-generator/test-20-swap-from-cmdline.expected.sysroot/swap.target.requires/dev-sdy5.swap
create mode 120000 test/test-fstab-generator/test-20-swap-from-cmdline.expected.sysroot/swap.target.requires/dev-sdy6.swap
create mode 100644 test/test-fstab-generator/test-20-swap-from-cmdline.expected/dev-sdy5.swap
create mode 120000 test/test-fstab-generator/test-20-swap-from-cmdline.expected/swap.target.requires/dev-sdy5.swap
diff --git a/test/test-fstab-generator/test-19-mounts-from-cmdline.expected.sysroot/foo-also_in_initrd.mount b/test/test-fstab-generator/test-19-mounts-from-cmdline.expected.sysroot/foo-also_in_initrd.mount
new file mode 100644
index 0000000000..8cc17c5d92
--- /dev/null
+++ b/test/test-fstab-generator/test-19-mounts-from-cmdline.expected.sysroot/foo-also_in_initrd.mount
@@ -0,0 +1,12 @@
+# Automatically generated by systemd-fstab-generator
+
+[Unit]
+Documentation=man:fstab(5) man:systemd-fstab-generator(8)
+SourcePath=/proc/cmdline
+Before=local-fs.target
+After=blockdev@dev-sdx6.target
+
+[Mount]
+What=/dev/sdx6
+Where=/foo/also_in_initrd
+Options=x-initrd.mount
diff --git a/test/test-fstab-generator/test-19-mounts-from-cmdline.expected.sysroot/foo-not_in_initrd.mount b/test/test-fstab-generator/test-19-mounts-from-cmdline.expected.sysroot/foo-not_in_initrd.mount
new file mode 100644
index 0000000000..8a5e28ebbf
--- /dev/null
+++ b/test/test-fstab-generator/test-19-mounts-from-cmdline.expected.sysroot/foo-not_in_initrd.mount
@@ -0,0 +1,11 @@
+# Automatically generated by systemd-fstab-generator
+
+[Unit]
+Documentation=man:fstab(5) man:systemd-fstab-generator(8)
+SourcePath=/proc/cmdline
+Before=local-fs.target
+After=blockdev@dev-sdx7.target
+
+[Mount]
+What=/dev/sdx7
+Where=/foo/not_in_initrd
diff --git a/test/test-fstab-generator/test-19-mounts-from-cmdline.expected.sysroot/local-fs.target.requires/foo-also_in_initrd.mount b/test/test-fstab-generator/test-19-mounts-from-cmdline.expected.sysroot/local-fs.target.requires/foo-also_in_initrd.mount
new file mode 120000
index 0000000000..e4b2711fb9
--- /dev/null
+++ b/test/test-fstab-generator/test-19-mounts-from-cmdline.expected.sysroot/local-fs.target.requires/foo-also_in_initrd.mount
@@ -0,0 +1 @@
+../foo-also_in_initrd.mount
\ No newline at end of file
diff --git a/test/test-fstab-generator/test-19-mounts-from-cmdline.expected.sysroot/local-fs.target.requires/foo-not_in_initrd.mount b/test/test-fstab-generator/test-19-mounts-from-cmdline.expected.sysroot/local-fs.target.requires/foo-not_in_initrd.mount
new file mode 120000
index 0000000000..85965fe86e
--- /dev/null
+++ b/test/test-fstab-generator/test-19-mounts-from-cmdline.expected.sysroot/local-fs.target.requires/foo-not_in_initrd.mount
@@ -0,0 +1 @@
+../foo-not_in_initrd.mount
\ No newline at end of file
diff --git a/test/test-fstab-generator/test-19-mounts-from-cmdline.expected.sysroot/local-fs.target.requires/usr.mount b/test/test-fstab-generator/test-19-mounts-from-cmdline.expected.sysroot/local-fs.target.requires/usr.mount
new file mode 120000
index 0000000000..a570574e46
--- /dev/null
+++ b/test/test-fstab-generator/test-19-mounts-from-cmdline.expected.sysroot/local-fs.target.requires/usr.mount
@@ -0,0 +1 @@
+../usr.mount
\ No newline at end of file
diff --git a/test/test-fstab-generator/test-19-mounts-from-cmdline.expected.sysroot/usr.mount b/test/test-fstab-generator/test-19-mounts-from-cmdline.expected.sysroot/usr.mount
new file mode 100644
index 0000000000..ff01ec4fde
--- /dev/null
+++ b/test/test-fstab-generator/test-19-mounts-from-cmdline.expected.sysroot/usr.mount
@@ -0,0 +1,11 @@
+# Automatically generated by systemd-fstab-generator
+
+[Unit]
+Documentation=man:fstab(5) man:systemd-fstab-generator(8)
+SourcePath=/proc/cmdline
+Before=local-fs.target
+After=blockdev@dev-sdx5.target
+
+[Mount]
+What=/dev/sdx5
+Where=/usr
diff --git a/test/test-fstab-generator/test-19-mounts-from-cmdline.expected/initrd-fs.target.requires/sysroot-foo-also_in_initrd.mount b/test/test-fstab-generator/test-19-mounts-from-cmdline.expected/initrd-fs.target.requires/sysroot-foo-also_in_initrd.mount
new file mode 120000
index 0000000000..314c46cccf
--- /dev/null
+++ b/test/test-fstab-generator/test-19-mounts-from-cmdline.expected/initrd-fs.target.requires/sysroot-foo-also_in_initrd.mount
@@ -0,0 +1 @@
+../sysroot-foo-also_in_initrd.mount
\ No newline at end of file
diff --git a/test/test-fstab-generator/test-19-mounts-from-cmdline.expected/initrd-fs.target.requires/sysroot-usr.mount b/test/test-fstab-generator/test-19-mounts-from-cmdline.expected/initrd-fs.target.requires/sysroot-usr.mount
new file mode 120000
index 0000000000..8bcbb16eae
--- /dev/null
+++ b/test/test-fstab-generator/test-19-mounts-from-cmdline.expected/initrd-fs.target.requires/sysroot-usr.mount
@@ -0,0 +1 @@
+../sysroot-usr.mount
\ No newline at end of file
diff --git a/test/test-fstab-generator/test-19-mounts-from-cmdline.expected/initrd-usr-fs.target.requires/sysusr-usr.mount b/test/test-fstab-generator/test-19-mounts-from-cmdline.expected/initrd-usr-fs.target.requires/sysusr-usr.mount
new file mode 120000
index 0000000000..8fb2e18647
--- /dev/null
+++ b/test/test-fstab-generator/test-19-mounts-from-cmdline.expected/initrd-usr-fs.target.requires/sysusr-usr.mount
@@ -0,0 +1 @@
+../sysusr-usr.mount
\ No newline at end of file
diff --git a/test/test-fstab-generator/test-19-mounts-from-cmdline.expected/sysroot-foo-also_in_initrd.mount b/test/test-fstab-generator/test-19-mounts-from-cmdline.expected/sysroot-foo-also_in_initrd.mount
new file mode 100644
index 0000000000..8baf1568b1
--- /dev/null
+++ b/test/test-fstab-generator/test-19-mounts-from-cmdline.expected/sysroot-foo-also_in_initrd.mount
@@ -0,0 +1,13 @@
+# Automatically generated by systemd-fstab-generator
+
+[Unit]
+Documentation=man:fstab(5) man:systemd-fstab-generator(8)
+SourcePath=/proc/cmdline
+Before=initrd-fs.target
+After=blockdev@dev-sdx6.target
+
+[Mount]
+What=/dev/sdx6
+# Canonicalized from /foo/also_in_initrd
+Where=/sysroot/foo/also_in_initrd
+Options=x-initrd.mount
diff --git a/test/test-fstab-generator/test-19-mounts-from-cmdline.expected/sysroot-usr.mount b/test/test-fstab-generator/test-19-mounts-from-cmdline.expected/sysroot-usr.mount
new file mode 100644
index 0000000000..7f6d33cb3d
--- /dev/null
+++ b/test/test-fstab-generator/test-19-mounts-from-cmdline.expected/sysroot-usr.mount
@@ -0,0 +1,11 @@
+# Automatically generated by systemd-fstab-generator
+
+[Unit]
+Documentation=man:fstab(5) man:systemd-fstab-generator(8)
+SourcePath=/proc/cmdline
+Before=initrd-fs.target
+
+[Mount]
+What=/sysusr/usr
+Where=/sysroot/usr
+Options=bind
diff --git a/test/test-fstab-generator/test-19-mounts-from-cmdline.expected/sysusr-usr.mount b/test/test-fstab-generator/test-19-mounts-from-cmdline.expected/sysusr-usr.mount
new file mode 100644
index 0000000000..f1fedb3775
--- /dev/null
+++ b/test/test-fstab-generator/test-19-mounts-from-cmdline.expected/sysusr-usr.mount
@@ -0,0 +1,11 @@
+# Automatically generated by systemd-fstab-generator
+
+[Unit]
+Documentation=man:fstab(5) man:systemd-fstab-generator(8)
+SourcePath=/proc/cmdline
+Before=initrd-usr-fs.target
+After=blockdev@dev-sdx5.target
+
+[Mount]
+What=/dev/sdx5
+Where=/sysusr/usr
diff --git a/test/test-fstab-generator/test-19-mounts-from-cmdline.input b/test/test-fstab-generator/test-19-mounts-from-cmdline.input
index f2cc6fc075..f16e494ecb 100644
--- a/test/test-fstab-generator/test-19-mounts-from-cmdline.input
+++ b/test/test-fstab-generator/test-19-mounts-from-cmdline.input
@@ -3,3 +3,6 @@ rd.systemd.mount-extra=/dev/sdx2:/hoge/without_options:auto
rd.systemd.mount-extra=/dev/sdx3:/hoge/without_fstype
rd.systemd.mount-extra=/dev/sdx4
rd.systemd.mount-extra=//foo\ufffebar:/hoge/with\x20space:cifs:rw,seclabel
+systemd.mount-extra=/dev/sdx5:/usr:auto:defaults
+systemd.mount-extra=/dev/sdx6:/foo/also_in_initrd:auto:x-initrd.mount
+systemd.mount-extra=/dev/sdx7:/foo/not_in_initrd:auto:defaults
diff --git a/test/test-fstab-generator/test-20-swap-from-cmdline.expected.sysroot/dev-sdy5.swap b/test/test-fstab-generator/test-20-swap-from-cmdline.expected.sysroot/dev-sdy5.swap
new file mode 100644
index 0000000000..a9009ce3bc
--- /dev/null
+++ b/test/test-fstab-generator/test-20-swap-from-cmdline.expected.sysroot/dev-sdy5.swap
@@ -0,0 +1,10 @@
+# Automatically generated by systemd-fstab-generator
+
+[Unit]
+Documentation=man:fstab(5) man:systemd-fstab-generator(8)
+SourcePath=/proc/cmdline
+After=blockdev@dev-sdy5.target
+
+[Swap]
+What=/dev/sdy5
+Options=x-initrd.mount
diff --git a/test/test-fstab-generator/test-20-swap-from-cmdline.expected.sysroot/dev-sdy6.swap b/test/test-fstab-generator/test-20-swap-from-cmdline.expected.sysroot/dev-sdy6.swap
new file mode 100644
index 0000000000..383a8c3865
--- /dev/null
+++ b/test/test-fstab-generator/test-20-swap-from-cmdline.expected.sysroot/dev-sdy6.swap
@@ -0,0 +1,9 @@
+# Automatically generated by systemd-fstab-generator
+
+[Unit]
+Documentation=man:fstab(5) man:systemd-fstab-generator(8)
+SourcePath=/proc/cmdline
+After=blockdev@dev-sdy6.target
+
+[Swap]
+What=/dev/sdy6
diff --git a/test/test-fstab-generator/test-20-swap-from-cmdline.expected.sysroot/swap.target.requires/dev-sdy5.swap b/test/test-fstab-generator/test-20-swap-from-cmdline.expected.sysroot/swap.target.requires/dev-sdy5.swap
new file mode 120000
index 0000000000..04565dbf44
--- /dev/null
+++ b/test/test-fstab-generator/test-20-swap-from-cmdline.expected.sysroot/swap.target.requires/dev-sdy5.swap
@@ -0,0 +1 @@
+../dev-sdy5.swap
\ No newline at end of file
diff --git a/test/test-fstab-generator/test-20-swap-from-cmdline.expected.sysroot/swap.target.requires/dev-sdy6.swap b/test/test-fstab-generator/test-20-swap-from-cmdline.expected.sysroot/swap.target.requires/dev-sdy6.swap
new file mode 120000
index 0000000000..3b36226323
--- /dev/null
+++ b/test/test-fstab-generator/test-20-swap-from-cmdline.expected.sysroot/swap.target.requires/dev-sdy6.swap
@@ -0,0 +1 @@
+../dev-sdy6.swap
\ No newline at end of file
diff --git a/test/test-fstab-generator/test-20-swap-from-cmdline.expected/dev-sdy5.swap b/test/test-fstab-generator/test-20-swap-from-cmdline.expected/dev-sdy5.swap
new file mode 100644
index 0000000000..a9009ce3bc
--- /dev/null
+++ b/test/test-fstab-generator/test-20-swap-from-cmdline.expected/dev-sdy5.swap
@@ -0,0 +1,10 @@
+# Automatically generated by systemd-fstab-generator
+
+[Unit]
+Documentation=man:fstab(5) man:systemd-fstab-generator(8)
+SourcePath=/proc/cmdline
+After=blockdev@dev-sdy5.target
+
+[Swap]
+What=/dev/sdy5
+Options=x-initrd.mount
diff --git a/test/test-fstab-generator/test-20-swap-from-cmdline.expected/swap.target.requires/dev-sdy5.swap b/test/test-fstab-generator/test-20-swap-from-cmdline.expected/swap.target.requires/dev-sdy5.swap
new file mode 120000
index 0000000000..04565dbf44
--- /dev/null
+++ b/test/test-fstab-generator/test-20-swap-from-cmdline.expected/swap.target.requires/dev-sdy5.swap
@@ -0,0 +1 @@
+../dev-sdy5.swap
\ No newline at end of file
diff --git a/test/test-fstab-generator/test-20-swap-from-cmdline.input b/test/test-fstab-generator/test-20-swap-from-cmdline.input
index d92c5300e2..adde91e180 100644
--- a/test/test-fstab-generator/test-20-swap-from-cmdline.input
+++ b/test/test-fstab-generator/test-20-swap-from-cmdline.input
@@ -2,3 +2,5 @@ rd.systemd.mount-extra=/dev/sdy1:none:swap
rd.systemd.mount-extra=/dev/sdy2:none:swap:x-systemd.makefs
rd.systemd.swap-extra=/dev/sdy3:x-systemd.makefs,nofail
rd.systemd.swap-extra=/dev/sdy4
+systemd.swap-extra=/dev/sdy5:x-initrd.mount
+systemd.swap-extra=/dev/sdy6

View File

@ -0,0 +1,206 @@
From accb88b9c080f1da1f9543921ae25b5f0296ec2a Mon Sep 17 00:00:00 2001
From: Yu Watanabe <watanabe.yu+github@gmail.com>
Date: Fri, 28 Jul 2023 06:07:17 +0900
Subject: [PATCH] fstab-generator: enable fsck for block device mounts
specified in systemd.mount-extra=
Like we do for root= or so.
Another possible option is adding support of fifth (sixth?) field in
systemd.mount-extra=. But that may be overkill, hence let's do that
later if someone request that.
Fixes fsck part of issue #28541.
(cherry picked from commit 239cce3870438aab69b2495ccb980a9d90140217)
Related: #2190226
---
src/fstab-generator/fstab-generator.c | 5 ++++-
.../foo-also_in_initrd.mount | 2 ++
.../foo-not_in_initrd.mount | 2 ++
.../usr.mount | 2 ++
.../hoge-without_fstype.mount | 2 ++
.../hoge-without_options.mount | 2 ++
.../sysroot-foo-also_in_initrd.mount | 2 ++
.../sysroot.mount | 2 ++
.../systemd-fsck-root.service | 17 +++++++++++++++++
.../systemd-fsck-usr.service | 17 +++++++++++++++++
.../sysusr-usr.mount | 2 ++
11 files changed, 54 insertions(+), 1 deletion(-)
create mode 100644 test/test-fstab-generator/test-19-mounts-from-cmdline.expected/systemd-fsck-root.service
create mode 100644 test/test-fstab-generator/test-19-mounts-from-cmdline.expected/systemd-fsck-usr.service
diff --git a/src/fstab-generator/fstab-generator.c b/src/fstab-generator/fstab-generator.c
index cf3ff4f598..c3fe285344 100644
--- a/src/fstab-generator/fstab-generator.c
+++ b/src/fstab-generator/fstab-generator.c
@@ -880,6 +880,9 @@ static int parse_fstab_one(
if (is_swap)
return add_swap(source, what, options, flags);
+ if (passno < 0)
+ passno = is_device_path(what);
+
assert(where_original); /* 'where' is not necessary for swap entry. */
if (!is_path(where_original)) {
@@ -1287,7 +1290,7 @@ static int add_mounts_from_cmdline(void) {
m->where,
m->fstype,
m->options,
- /* passno = */ 0,
+ /* passno = */ -1,
/* prefix_sysroot = */ !m->for_initrd && in_initrd(),
/* accept_root = */ true,
/* use_swap_enabled = */ false);
diff --git a/test/test-fstab-generator/test-19-mounts-from-cmdline.expected.sysroot/foo-also_in_initrd.mount b/test/test-fstab-generator/test-19-mounts-from-cmdline.expected.sysroot/foo-also_in_initrd.mount
index 8cc17c5d92..ed72fb283f 100644
--- a/test/test-fstab-generator/test-19-mounts-from-cmdline.expected.sysroot/foo-also_in_initrd.mount
+++ b/test/test-fstab-generator/test-19-mounts-from-cmdline.expected.sysroot/foo-also_in_initrd.mount
@@ -4,6 +4,8 @@
Documentation=man:fstab(5) man:systemd-fstab-generator(8)
SourcePath=/proc/cmdline
Before=local-fs.target
+Requires=systemd-fsck@dev-sdx6.service
+After=systemd-fsck@dev-sdx6.service
After=blockdev@dev-sdx6.target
[Mount]
diff --git a/test/test-fstab-generator/test-19-mounts-from-cmdline.expected.sysroot/foo-not_in_initrd.mount b/test/test-fstab-generator/test-19-mounts-from-cmdline.expected.sysroot/foo-not_in_initrd.mount
index 8a5e28ebbf..11b52788df 100644
--- a/test/test-fstab-generator/test-19-mounts-from-cmdline.expected.sysroot/foo-not_in_initrd.mount
+++ b/test/test-fstab-generator/test-19-mounts-from-cmdline.expected.sysroot/foo-not_in_initrd.mount
@@ -4,6 +4,8 @@
Documentation=man:fstab(5) man:systemd-fstab-generator(8)
SourcePath=/proc/cmdline
Before=local-fs.target
+Requires=systemd-fsck@dev-sdx7.service
+After=systemd-fsck@dev-sdx7.service
After=blockdev@dev-sdx7.target
[Mount]
diff --git a/test/test-fstab-generator/test-19-mounts-from-cmdline.expected.sysroot/usr.mount b/test/test-fstab-generator/test-19-mounts-from-cmdline.expected.sysroot/usr.mount
index ff01ec4fde..bfdede543a 100644
--- a/test/test-fstab-generator/test-19-mounts-from-cmdline.expected.sysroot/usr.mount
+++ b/test/test-fstab-generator/test-19-mounts-from-cmdline.expected.sysroot/usr.mount
@@ -4,6 +4,8 @@
Documentation=man:fstab(5) man:systemd-fstab-generator(8)
SourcePath=/proc/cmdline
Before=local-fs.target
+Wants=systemd-fsck@dev-sdx5.service
+After=systemd-fsck@dev-sdx5.service
After=blockdev@dev-sdx5.target
[Mount]
diff --git a/test/test-fstab-generator/test-19-mounts-from-cmdline.expected/hoge-without_fstype.mount b/test/test-fstab-generator/test-19-mounts-from-cmdline.expected/hoge-without_fstype.mount
index 4d7d975cc0..a7c6ee9913 100644
--- a/test/test-fstab-generator/test-19-mounts-from-cmdline.expected/hoge-without_fstype.mount
+++ b/test/test-fstab-generator/test-19-mounts-from-cmdline.expected/hoge-without_fstype.mount
@@ -4,6 +4,8 @@
Documentation=man:fstab(5) man:systemd-fstab-generator(8)
SourcePath=/proc/cmdline
Before=local-fs.target
+Requires=systemd-fsck@dev-sdx3.service
+After=systemd-fsck@dev-sdx3.service
After=blockdev@dev-sdx3.target
[Mount]
diff --git a/test/test-fstab-generator/test-19-mounts-from-cmdline.expected/hoge-without_options.mount b/test/test-fstab-generator/test-19-mounts-from-cmdline.expected/hoge-without_options.mount
index 4f16d2e40b..157ae2b6a4 100644
--- a/test/test-fstab-generator/test-19-mounts-from-cmdline.expected/hoge-without_options.mount
+++ b/test/test-fstab-generator/test-19-mounts-from-cmdline.expected/hoge-without_options.mount
@@ -4,6 +4,8 @@
Documentation=man:fstab(5) man:systemd-fstab-generator(8)
SourcePath=/proc/cmdline
Before=local-fs.target
+Requires=systemd-fsck@dev-sdx2.service
+After=systemd-fsck@dev-sdx2.service
After=blockdev@dev-sdx2.target
[Mount]
diff --git a/test/test-fstab-generator/test-19-mounts-from-cmdline.expected/sysroot-foo-also_in_initrd.mount b/test/test-fstab-generator/test-19-mounts-from-cmdline.expected/sysroot-foo-also_in_initrd.mount
index 8baf1568b1..098961dc9e 100644
--- a/test/test-fstab-generator/test-19-mounts-from-cmdline.expected/sysroot-foo-also_in_initrd.mount
+++ b/test/test-fstab-generator/test-19-mounts-from-cmdline.expected/sysroot-foo-also_in_initrd.mount
@@ -4,6 +4,8 @@
Documentation=man:fstab(5) man:systemd-fstab-generator(8)
SourcePath=/proc/cmdline
Before=initrd-fs.target
+Requires=systemd-fsck@dev-sdx6.service
+After=systemd-fsck@dev-sdx6.service
After=blockdev@dev-sdx6.target
[Mount]
diff --git a/test/test-fstab-generator/test-19-mounts-from-cmdline.expected/sysroot.mount b/test/test-fstab-generator/test-19-mounts-from-cmdline.expected/sysroot.mount
index c8547fa539..f46b71a1f0 100644
--- a/test/test-fstab-generator/test-19-mounts-from-cmdline.expected/sysroot.mount
+++ b/test/test-fstab-generator/test-19-mounts-from-cmdline.expected/sysroot.mount
@@ -4,6 +4,8 @@
Documentation=man:fstab(5) man:systemd-fstab-generator(8)
SourcePath=/proc/cmdline
Before=initrd-root-fs.target
+Requires=systemd-fsck-root.service
+After=systemd-fsck-root.service
After=blockdev@dev-sdx1.target
[Mount]
diff --git a/test/test-fstab-generator/test-19-mounts-from-cmdline.expected/systemd-fsck-root.service b/test/test-fstab-generator/test-19-mounts-from-cmdline.expected/systemd-fsck-root.service
new file mode 100644
index 0000000000..147348899d
--- /dev/null
+++ b/test/test-fstab-generator/test-19-mounts-from-cmdline.expected/systemd-fsck-root.service
@@ -0,0 +1,17 @@
+# Automatically generated by systemd-fstab-generator
+
+[Unit]
+Description=File System Check on /dev/sdx1
+Documentation=man:systemd-fsck-root.service(8)
+
+DefaultDependencies=no
+BindsTo=dev-sdx1.device
+Conflicts=shutdown.target
+After=initrd-root-device.target local-fs-pre.target dev-sdx1.device
+Before=shutdown.target
+
+[Service]
+Type=oneshot
+RemainAfterExit=yes
+ExecStart=/usr/lib/systemd/systemd-fsck /dev/sdx1
+TimeoutSec=infinity
diff --git a/test/test-fstab-generator/test-19-mounts-from-cmdline.expected/systemd-fsck-usr.service b/test/test-fstab-generator/test-19-mounts-from-cmdline.expected/systemd-fsck-usr.service
new file mode 100644
index 0000000000..512e7b1636
--- /dev/null
+++ b/test/test-fstab-generator/test-19-mounts-from-cmdline.expected/systemd-fsck-usr.service
@@ -0,0 +1,17 @@
+# Automatically generated by systemd-fstab-generator
+
+[Unit]
+Description=File System Check on /dev/sdx5
+Documentation=man:systemd-fsck-usr.service(8)
+
+DefaultDependencies=no
+BindsTo=dev-sdx5.device
+Conflicts=shutdown.target
+After=local-fs-pre.target dev-sdx5.device
+Before=shutdown.target
+
+[Service]
+Type=oneshot
+RemainAfterExit=yes
+ExecStart=/usr/lib/systemd/systemd-fsck /dev/sdx5
+TimeoutSec=infinity
diff --git a/test/test-fstab-generator/test-19-mounts-from-cmdline.expected/sysusr-usr.mount b/test/test-fstab-generator/test-19-mounts-from-cmdline.expected/sysusr-usr.mount
index f1fedb3775..bfee6a4ff7 100644
--- a/test/test-fstab-generator/test-19-mounts-from-cmdline.expected/sysusr-usr.mount
+++ b/test/test-fstab-generator/test-19-mounts-from-cmdline.expected/sysusr-usr.mount
@@ -4,6 +4,8 @@
Documentation=man:fstab(5) man:systemd-fstab-generator(8)
SourcePath=/proc/cmdline
Before=initrd-usr-fs.target
+Requires=systemd-fsck-usr.service
+After=systemd-fsck-usr.service
After=blockdev@dev-sdx5.target
[Mount]

View File

@ -0,0 +1,48 @@
From cf363a503bf7cc4827dbbcd9a670987bf680d5b4 Mon Sep 17 00:00:00 2001
From: Yu Watanabe <watanabe.yu+github@gmail.com>
Date: Wed, 7 Dec 2022 12:01:59 +0900
Subject: [PATCH] core: use correct scope of looking up units
Fixes a bug introduced by 3b3557c410c7910fae0990599dcb82711cf5fbb7.
Fixes #25625.
(cherry picked from commit 47c57b4813c81187db86ed6e33ecf11f8a25825a)
Resolves: #2226980
---
src/core/dbus-manager.c | 11 ++++-------
1 file changed, 4 insertions(+), 7 deletions(-)
diff --git a/src/core/dbus-manager.c b/src/core/dbus-manager.c
index 2db12721a1..00380cc9c1 100644
--- a/src/core/dbus-manager.c
+++ b/src/core/dbus-manager.c
@@ -2629,11 +2629,10 @@ static int method_add_dependency_unit_files(sd_bus_message *message, void *userd
static int method_get_unit_file_links(sd_bus_message *message, void *userdata, sd_bus_error *error) {
_cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL;
+ Manager *m = ASSERT_PTR(userdata);
InstallChange *changes = NULL;
size_t n_changes = 0, i;
- UnitFileFlags flags;
const char *name;
- char **p;
int runtime, r;
r = sd_bus_message_read(message, "sb", &name, &runtime);
@@ -2648,11 +2647,9 @@ static int method_get_unit_file_links(sd_bus_message *message, void *userdata, s
if (r < 0)
return r;
- p = STRV_MAKE(name);
- flags = UNIT_FILE_DRY_RUN |
- (runtime ? UNIT_FILE_RUNTIME : 0);
-
- r = unit_file_disable(LOOKUP_SCOPE_SYSTEM, flags, NULL, p, &changes, &n_changes);
+ r = unit_file_disable(m->unit_file_scope,
+ UNIT_FILE_DRY_RUN | (runtime ? UNIT_FILE_RUNTIME : 0),
+ NULL, STRV_MAKE(name), &changes, &n_changes);
if (r < 0) {
log_error_errno(r, "Failed to get file links for %s: %m", name);
goto finish;

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,140 @@
From b186204ab9a7eb51fc2b2bbaa99d2865198e15e6 Mon Sep 17 00:00:00 2001
From: Frantisek Sumsal <frantisek@sumsal.cz>
Date: Wed, 10 May 2023 12:38:57 +0200
Subject: [PATCH] test: rename TEST-07-ISSUE-1981 to TEST-07-PID1
(cherry picked from commit 09c033a2763fe7f0e625901f199e646b3f132e84)
Related: #2213521
---
.../Makefile | 0
.../test.sh | 5 +-
test/units/testsuite-07.issue-1981.sh | 47 +++++++++++++++++++
test/units/testsuite-07.sh | 33 ++-----------
4 files changed, 52 insertions(+), 33 deletions(-)
rename test/{TEST-07-ISSUE-1981 => TEST-07-PID1}/Makefile (100%)
rename test/{TEST-07-ISSUE-1981 => TEST-07-PID1}/test.sh (62%)
create mode 100755 test/units/testsuite-07.issue-1981.sh
diff --git a/test/TEST-07-ISSUE-1981/Makefile b/test/TEST-07-PID1/Makefile
similarity index 100%
rename from test/TEST-07-ISSUE-1981/Makefile
rename to test/TEST-07-PID1/Makefile
diff --git a/test/TEST-07-ISSUE-1981/test.sh b/test/TEST-07-PID1/test.sh
similarity index 62%
rename from test/TEST-07-ISSUE-1981/test.sh
rename to test/TEST-07-PID1/test.sh
index 5bc41386b5..2b9dd418b8 100755
--- a/test/TEST-07-ISSUE-1981/test.sh
+++ b/test/TEST-07-PID1/test.sh
@@ -2,12 +2,9 @@
# SPDX-License-Identifier: LGPL-2.1-or-later
set -e
-TEST_DESCRIPTION="https://github.com/systemd/systemd/issues/1981"
-TEST_NO_QEMU=1
+TEST_DESCRIPTION="Tests for core PID1 functionality"
# shellcheck source=test/test-functions
. "${TEST_BASE_DIR:?}/test-functions"
-NSPAWN_TIMEOUT=30
-
do_test "$@"
diff --git a/test/units/testsuite-07.issue-1981.sh b/test/units/testsuite-07.issue-1981.sh
new file mode 100755
index 0000000000..6eb802c93f
--- /dev/null
+++ b/test/units/testsuite-07.issue-1981.sh
@@ -0,0 +1,47 @@
+#!/usr/bin/env bash
+# SPDX-License-Identifier: LGPL-2.1-or-later
+set -eux
+set -o pipefail
+
+# Segmentation fault in timer_enter_waiting while masking a unit
+# Issue: https://github.com/systemd/systemd/issues/1981
+
+at_exit() {
+ set +e
+
+ systemctl stop my.timer my.service
+ rm -f /run/systemd/system/my.{service,timer}
+ systemctl daemon-reload
+}
+
+trap at_exit EXIT
+
+mkdir -p /run/systemd/system
+
+cat >/run/systemd/system/my.service <<\EOF
+[Service]
+Type=oneshot
+ExecStartPre=sh -c 'test "$TRIGGER_UNIT" = my.timer'
+ExecStartPre=sh -c 'test -n "$TRIGGER_TIMER_REALTIME_USEC"'
+ExecStartPre=sh -c 'test -n "$TRIGGER_TIMER_MONOTONIC_USEC"'
+ExecStart=/bin/echo Timer runs me
+EOF
+
+cat >/run/systemd/system/my.timer <<EOF
+[Timer]
+OnBootSec=10s
+OnUnitInactiveSec=1h
+EOF
+
+systemctl unmask my.timer
+systemctl start my.timer
+
+mkdir -p /run/systemd/system/my.timer.d/
+cat >/run/systemd/system/my.timer.d/override.conf <<EOF
+[Timer]
+OnBootSec=10s
+OnUnitInactiveSec=1h
+EOF
+
+systemctl daemon-reload
+systemctl mask my.timer
diff --git a/test/units/testsuite-07.sh b/test/units/testsuite-07.sh
index 95ebe3876f..13c767e490 100755
--- a/test/units/testsuite-07.sh
+++ b/test/units/testsuite-07.sh
@@ -5,35 +5,10 @@ set -o pipefail
: >/failed
-cat >/lib/systemd/system/my.service <<EOF
-[Service]
-Type=oneshot
-ExecStartPre=sh -c 'test "\$TRIGGER_UNIT" = my.timer'
-ExecStartPre=sh -c 'test -n "\$TRIGGER_TIMER_REALTIME_USEC"'
-ExecStartPre=sh -c 'test -n "\$TRIGGER_TIMER_MONOTONIC_USEC"'
-ExecStart=/bin/echo Timer runs me
-EOF
-
-cat >/lib/systemd/system/my.timer <<EOF
-[Timer]
-OnBootSec=10s
-OnUnitInactiveSec=1h
-EOF
-
-systemctl unmask my.timer
-
-systemctl start my.timer
-
-mkdir -p /etc/systemd/system/my.timer.d/
-cat >/etc/systemd/system/my.timer.d/override.conf <<EOF
-[Timer]
-OnBootSec=10s
-OnUnitInactiveSec=1h
-EOF
-
-systemctl daemon-reload
-
-systemctl mask my.timer
+for script in "${0%.sh}".*.sh; do
+ echo "Running $script"
+ "./$script"
+done
touch /testok
rm /failed

View File

@ -0,0 +1,188 @@
From b6d8ff21df92e6686ce37b047c70c43967b8a2c1 Mon Sep 17 00:00:00 2001
From: Frantisek Sumsal <frantisek@sumsal.cz>
Date: Wed, 10 May 2023 13:07:26 +0200
Subject: [PATCH] test: merge TEST-08-ISSUE-2730 into TEST-07-PID1
(cherry picked from commit cd62ba42a40e5d87a83a98bc421419bd2778d4ec)
Related: #2213521
---
test/TEST-07-PID1/test.sh | 19 +++++++++++++++++++
test/TEST-08-ISSUE-2730/Makefile | 1 -
test/TEST-08-ISSUE-2730/test.sh | 14 --------------
test/meson.build | 12 ------------
test/testsuite-08.units/-.mount | 12 ------------
.../local-fs.target.wants/-.mount | 1 -
test/testsuite-08.units/root.mount | 1 -
.../systemd-remount-fs.service | 12 ------------
test/units/testsuite-07.sh | 4 ++++
test/units/testsuite-08.service | 8 --------
10 files changed, 23 insertions(+), 61 deletions(-)
delete mode 120000 test/TEST-08-ISSUE-2730/Makefile
delete mode 100755 test/TEST-08-ISSUE-2730/test.sh
delete mode 100644 test/testsuite-08.units/-.mount
delete mode 120000 test/testsuite-08.units/local-fs.target.wants/-.mount
delete mode 120000 test/testsuite-08.units/root.mount
delete mode 100644 test/testsuite-08.units/systemd-remount-fs.service
delete mode 100644 test/units/testsuite-08.service
diff --git a/test/TEST-07-PID1/test.sh b/test/TEST-07-PID1/test.sh
index 2b9dd418b8..c241840327 100755
--- a/test/TEST-07-PID1/test.sh
+++ b/test/TEST-07-PID1/test.sh
@@ -7,4 +7,23 @@ TEST_DESCRIPTION="Tests for core PID1 functionality"
# shellcheck source=test/test-functions
. "${TEST_BASE_DIR:?}/test-functions"
+test_append_files() {
+ local workspace="${1:?}"
+
+ # Issue: https://github.com/systemd/systemd/issues/2730
+ mkdir -p "$workspace/etc/systemd/system/"
+ cat >"$workspace/etc/systemd/system/issue2730.mount" <<EOF
+[Mount]
+What=tmpfs
+Where=/issue2730
+Type=tmpfs
+
+[Install]
+WantedBy=local-fs.target
+Alias=issue2730-alias.mount
+EOF
+ "${SYSTEMCTL:?}" enable --root="$workspace" issue2730.mount
+ ln -svrf "$workspace/etc/systemd/system/issue2730.mount" "$workspace/etc/systemd/system/issue2730-alias.mount"
+}
+
do_test "$@"
diff --git a/test/TEST-08-ISSUE-2730/Makefile b/test/TEST-08-ISSUE-2730/Makefile
deleted file mode 120000
index e9f93b1104..0000000000
--- a/test/TEST-08-ISSUE-2730/Makefile
+++ /dev/null
@@ -1 +0,0 @@
-../TEST-01-BASIC/Makefile
\ No newline at end of file
diff --git a/test/TEST-08-ISSUE-2730/test.sh b/test/TEST-08-ISSUE-2730/test.sh
deleted file mode 100755
index 0564314a86..0000000000
--- a/test/TEST-08-ISSUE-2730/test.sh
+++ /dev/null
@@ -1,14 +0,0 @@
-#!/usr/bin/env bash
-# SPDX-License-Identifier: LGPL-2.1-or-later
-set -e
-
-TEST_DESCRIPTION="https://github.com/systemd/systemd/issues/2730"
-IMAGE_NAME="test08"
-TEST_NO_NSPAWN=1
-
-# shellcheck source=test/test-functions
-. "${TEST_BASE_DIR:?}/test-functions"
-
-TEST_FORCE_NEWIMAGE=1
-
-do_test "$@"
diff --git a/test/meson.build b/test/meson.build
index f2080b5a9a..044ae781ee 100644
--- a/test/meson.build
+++ b/test/meson.build
@@ -61,18 +61,6 @@ if install_tests
install_data(kbd_model_map,
install_dir : testdata_dir + '/test-keymap-util')
- testsuite08_dir = testdata_dir + '/testsuite-08.units'
- install_data('testsuite-08.units/-.mount',
- install_dir : testsuite08_dir)
- install_data('testsuite-08.units/systemd-remount-fs.service',
- install_dir : testsuite08_dir)
- meson.add_install_script(meson_make_symlink,
- './-.mount',
- testsuite08_dir + '/root.mount')
- meson.add_install_script(meson_make_symlink,
- '../-.mount',
- testsuite08_dir + '/local-fs.target.wants/-.mount')
-
if conf.get('HAVE_GNU_EFI') == 1 and conf.get('HAVE_ZSTD') == 1
install_subdir('test-bcd',
exclude_files : '.gitattributes',
diff --git a/test/testsuite-08.units/-.mount b/test/testsuite-08.units/-.mount
deleted file mode 100644
index 66f29afab9..0000000000
--- a/test/testsuite-08.units/-.mount
+++ /dev/null
@@ -1,12 +0,0 @@
-# SPDX-License-Identifier: LGPL-2.1-or-later
-[Unit]
-Before=local-fs.target
-
-[Mount]
-What=/dev/sda1
-Where=/
-Options=noatime
-
-[Install]
-WantedBy=local-fs.target
-Alias=root.mount
diff --git a/test/testsuite-08.units/local-fs.target.wants/-.mount b/test/testsuite-08.units/local-fs.target.wants/-.mount
deleted file mode 120000
index 5566fceaa3..0000000000
--- a/test/testsuite-08.units/local-fs.target.wants/-.mount
+++ /dev/null
@@ -1 +0,0 @@
-../-.mount
\ No newline at end of file
diff --git a/test/testsuite-08.units/root.mount b/test/testsuite-08.units/root.mount
deleted file mode 120000
index fd8c47d1b0..0000000000
--- a/test/testsuite-08.units/root.mount
+++ /dev/null
@@ -1 +0,0 @@
--.mount
\ No newline at end of file
diff --git a/test/testsuite-08.units/systemd-remount-fs.service b/test/testsuite-08.units/systemd-remount-fs.service
deleted file mode 100644
index c7fdf2f68e..0000000000
--- a/test/testsuite-08.units/systemd-remount-fs.service
+++ /dev/null
@@ -1,12 +0,0 @@
-# SPDX-License-Identifier: LGPL-2.1-or-later
-[Unit]
-DefaultDependencies=no
-Conflicts=shutdown.target
-After=systemd-fsck-root.service
-Before=local-fs-pre.target local-fs.target shutdown.target
-Wants=local-fs-pre.target
-
-[Service]
-Type=oneshot
-RemainAfterExit=yes
-ExecStart=/bin/systemctl reload /
diff --git a/test/units/testsuite-07.sh b/test/units/testsuite-07.sh
index 13c767e490..8c004a72e5 100755
--- a/test/units/testsuite-07.sh
+++ b/test/units/testsuite-07.sh
@@ -5,6 +5,10 @@ set -o pipefail
: >/failed
+# Issue: https://github.com/systemd/systemd/issues/2730
+# See TEST-07-PID1/test.sh for the first "half" of the test
+mountpoint /issue2730
+
for script in "${0%.sh}".*.sh; do
echo "Running $script"
"./$script"
diff --git a/test/units/testsuite-08.service b/test/units/testsuite-08.service
deleted file mode 100644
index d6937663e2..0000000000
--- a/test/units/testsuite-08.service
+++ /dev/null
@@ -1,8 +0,0 @@
-# SPDX-License-Identifier: LGPL-2.1-or-later
-[Unit]
-Description=TEST-08-ISSUE-2730
-
-[Service]
-ExecStartPre=rm -f /failed /testok
-ExecStart=sh -x -c 'mount -o remount,rw /dev/sda1 && echo OK >/testok; systemctl poweroff'
-Type=oneshot

View File

@ -0,0 +1,76 @@
From 53da89d4a318cca04a9ec75e5d4431c36e10c140 Mon Sep 17 00:00:00 2001
From: Frantisek Sumsal <frantisek@sumsal.cz>
Date: Wed, 10 May 2023 13:13:12 +0200
Subject: [PATCH] test: merge TEST-09-ISSUE-2691 into TEST-07-PID1
(cherry picked from commit 4966a31ba3ef1eae37733a81bf318f4b18d11a96)
Related: #2213521
---
test/TEST-09-ISSUE-2691/Makefile | 1 -
test/TEST-09-ISSUE-2691/test.sh | 11 -----------
test/units/testsuite-07.service | 6 +++++-
test/units/testsuite-09.service | 11 -----------
4 files changed, 5 insertions(+), 24 deletions(-)
delete mode 120000 test/TEST-09-ISSUE-2691/Makefile
delete mode 100755 test/TEST-09-ISSUE-2691/test.sh
delete mode 100644 test/units/testsuite-09.service
diff --git a/test/TEST-09-ISSUE-2691/Makefile b/test/TEST-09-ISSUE-2691/Makefile
deleted file mode 120000
index e9f93b1104..0000000000
--- a/test/TEST-09-ISSUE-2691/Makefile
+++ /dev/null
@@ -1 +0,0 @@
-../TEST-01-BASIC/Makefile
\ No newline at end of file
diff --git a/test/TEST-09-ISSUE-2691/test.sh b/test/TEST-09-ISSUE-2691/test.sh
deleted file mode 100755
index 3fc243cc55..0000000000
--- a/test/TEST-09-ISSUE-2691/test.sh
+++ /dev/null
@@ -1,11 +0,0 @@
-#!/usr/bin/env bash
-# SPDX-License-Identifier: LGPL-2.1-or-later
-set -e
-
-TEST_DESCRIPTION="https://github.com/systemd/systemd/issues/2691"
-TEST_NO_NSPAWN=1
-
-# shellcheck source=test/test-functions
-. "${TEST_BASE_DIR:?}/test-functions"
-
-do_test "$@"
diff --git a/test/units/testsuite-07.service b/test/units/testsuite-07.service
index c478e12360..f45b9c7c5b 100644
--- a/test/units/testsuite-07.service
+++ b/test/units/testsuite-07.service
@@ -3,6 +3,10 @@
Description=TEST-07-ISSUE-1981
[Service]
+Type=oneshot
ExecStartPre=rm -f /failed /testok
ExecStart=/usr/lib/systemd/tests/testdata/units/%N.sh
-Type=oneshot
+# Issue: https://github.com/systemd/systemd/issues/2691
+ExecStop=sh -c 'kill -SEGV $$$$'
+RemainAfterExit=yes
+TimeoutStopSec=270s
diff --git a/test/units/testsuite-09.service b/test/units/testsuite-09.service
deleted file mode 100644
index 6f6cd9c522..0000000000
--- a/test/units/testsuite-09.service
+++ /dev/null
@@ -1,11 +0,0 @@
-# SPDX-License-Identifier: LGPL-2.1-or-later
-[Unit]
-Description=TEST-09-ISSUE-2691
-
-[Service]
-ExecStartPre=rm -f /failed /testok
-ExecStart=sh -c '>/testok'
-ExecStop=sh -c 'kill -SEGV $$$$'
-Type=oneshot
-RemainAfterExit=yes
-TimeoutStopSec=270s

View File

@ -0,0 +1,158 @@
From a001c9160b0722ce1c0943646b2a32d3841cddd5 Mon Sep 17 00:00:00 2001
From: Frantisek Sumsal <frantisek@sumsal.cz>
Date: Wed, 10 May 2023 13:41:03 +0200
Subject: [PATCH] test: merge TEST-10-ISSUE-2467 with TEST-07-PID1
(cherry picked from commit a8faac7dae6f54e88aad08d2d8c34e165ce6e922)
Related: #2213521
---
test/TEST-07-PID1/test.sh | 8 +++++++
test/TEST-10-ISSUE-2467/Makefile | 1 -
test/TEST-10-ISSUE-2467/test.sh | 22 -------------------
test/meson.build | 3 +++
.../issue2467.service} | 2 +-
.../issue2467.socket} | 0
test/units/testsuite-07.issue-2467.sh | 17 ++++++++++++++
test/units/testsuite-10.service | 16 --------------
8 files changed, 29 insertions(+), 40 deletions(-)
delete mode 120000 test/TEST-10-ISSUE-2467/Makefile
delete mode 100755 test/TEST-10-ISSUE-2467/test.sh
rename test/{testsuite-10.units/test10.service => testsuite-07.units/issue2467.service} (90%)
rename test/{testsuite-10.units/test10.socket => testsuite-07.units/issue2467.socket} (100%)
create mode 100755 test/units/testsuite-07.issue-2467.sh
delete mode 100644 test/units/testsuite-10.service
diff --git a/test/TEST-07-PID1/test.sh b/test/TEST-07-PID1/test.sh
index c241840327..1c3d7137fe 100755
--- a/test/TEST-07-PID1/test.sh
+++ b/test/TEST-07-PID1/test.sh
@@ -10,6 +10,14 @@ TEST_DESCRIPTION="Tests for core PID1 functionality"
test_append_files() {
local workspace="${1:?}"
+ # Collecting coverage slows this particular test quite a bit, causing
+ # it to fail with the default settings (20 triggers per 2 secs).
+ # Let's help it a bit in such case.
+ if get_bool "$IS_BUILT_WITH_COVERAGE"; then
+ mkdir -p "$workspace/etc/systemd/system/issue2467.socket.d"
+ printf "[Socket]\nTriggerLimitIntervalSec=10\n" >"$workspace/etc/systemd/system/issue2467.socket.d/coverage-override.conf"
+ fi
+
# Issue: https://github.com/systemd/systemd/issues/2730
mkdir -p "$workspace/etc/systemd/system/"
cat >"$workspace/etc/systemd/system/issue2730.mount" <<EOF
diff --git a/test/TEST-10-ISSUE-2467/Makefile b/test/TEST-10-ISSUE-2467/Makefile
deleted file mode 120000
index e9f93b1104..0000000000
--- a/test/TEST-10-ISSUE-2467/Makefile
+++ /dev/null
@@ -1 +0,0 @@
-../TEST-01-BASIC/Makefile
\ No newline at end of file
diff --git a/test/TEST-10-ISSUE-2467/test.sh b/test/TEST-10-ISSUE-2467/test.sh
deleted file mode 100755
index 8dabf3f2b6..0000000000
--- a/test/TEST-10-ISSUE-2467/test.sh
+++ /dev/null
@@ -1,22 +0,0 @@
-#!/usr/bin/env bash
-# SPDX-License-Identifier: LGPL-2.1-or-later
-set -e
-
-TEST_DESCRIPTION="https://github.com/systemd/systemd/issues/2467"
-
-# shellcheck source=test/test-functions
-. "${TEST_BASE_DIR:?}/test-functions"
-
-test_append_files() {
- (
- # Collecting coverage slows this particular test quite a bit, causing
- # it to fail with the default settings (20 triggers per 2 secs)
- # to trip over the default limit. Let's help it a bit in such case.
- if get_bool "$IS_BUILT_WITH_COVERAGE"; then
- mkdir -p "${initdir:?}/etc/systemd/system/test10.socket.d"
- printf "[Socket]\nTriggerLimitIntervalSec=10\n" >"${initdir:?}/etc/systemd/system/test10.socket.d/coverage-override.conf"
- fi
- )
-}
-
-do_test "$@"
diff --git a/test/meson.build b/test/meson.build
index 044ae781ee..92c92dcb3b 100644
--- a/test/meson.build
+++ b/test/meson.build
@@ -36,6 +36,9 @@ if install_tests
install_subdir('testsuite-06.units',
exclude_files : '.gitattributes',
install_dir : testdata_dir)
+ install_subdir('testsuite-07.units',
+ exclude_files : '.gitattributes',
+ install_dir : testdata_dir)
install_subdir('testsuite-10.units',
exclude_files : '.gitattributes',
install_dir : testdata_dir)
diff --git a/test/testsuite-10.units/test10.service b/test/testsuite-07.units/issue2467.service
similarity index 90%
rename from test/testsuite-10.units/test10.service
rename to test/testsuite-07.units/issue2467.service
index fc8fad9327..99d886f025 100644
--- a/test/testsuite-10.units/test10.service
+++ b/test/testsuite-07.units/issue2467.service
@@ -1,6 +1,6 @@
# SPDX-License-Identifier: LGPL-2.1-or-later
[Unit]
-Requires=test10.socket
+Requires=issue2467.socket
ConditionPathExistsGlob=/tmp/nonexistent
# Make sure we hit the socket trigger limit in the test and not the service start limit.
StartLimitInterval=1000
diff --git a/test/testsuite-10.units/test10.socket b/test/testsuite-07.units/issue2467.socket
similarity index 100%
rename from test/testsuite-10.units/test10.socket
rename to test/testsuite-07.units/issue2467.socket
diff --git a/test/units/testsuite-07.issue-2467.sh b/test/units/testsuite-07.issue-2467.sh
new file mode 100755
index 0000000000..a5dcfd55dd
--- /dev/null
+++ b/test/units/testsuite-07.issue-2467.sh
@@ -0,0 +1,17 @@
+#!/usr/bin/env bash
+# SPDX-License-Identifier: LGPL-2.1-or-later
+set -eux
+set -o pipefail
+
+# Don't start services every few ms if condition fails
+# Issue: https://github.com/systemd/systemd/issues/2467
+
+rm -f /tmp/nonexistent
+systemctl start issue2467.socket
+nc -w20 -U /run/test.ctl || :
+
+# TriggerLimitIntervalSec= by default is set to 2s. A "sleep 10" should give
+# systemd enough time even on slower machines, to reach the trigger limit.
+# shellcheck disable=SC2016
+timeout 10 bash -c 'while ! [[ "$(systemctl show issue2467.socket -P ActiveState)" == failed ]]; do sleep .5; done'
+[[ "$(systemctl show issue2467.socket -P Result)" == trigger-limit-hit ]]
diff --git a/test/units/testsuite-10.service b/test/units/testsuite-10.service
deleted file mode 100644
index 9fcfd673c6..0000000000
--- a/test/units/testsuite-10.service
+++ /dev/null
@@ -1,16 +0,0 @@
-# SPDX-License-Identifier: LGPL-2.1-or-later
-[Unit]
-Description=TEST-10-ISSUE-2467
-
-[Service]
-ExecStartPre=rm -f /failed /testok
-Type=oneshot
-ExecStart=rm -f /tmp/nonexistent
-ExecStart=systemctl start test10.socket
-ExecStart=-nc -w20 -U /run/test.ctl
-# TriggerLimitIntervalSec= by default is set to 2s. A "sleep 10" should give
-# systemd enough time even on slower machines, to reach the trigger limit.
-ExecStart=sleep 10
-ExecStart=sh -x -c 'test "$(systemctl show test10.socket -P ActiveState)" = failed'
-ExecStart=sh -x -c 'test "$(systemctl show test10.socket -P Result)" = trigger-limit-hit'
-ExecStart=sh -x -c 'echo OK >/testok'

View File

@ -0,0 +1,108 @@
From b04b14f0fda07377721362d9ff384f85a754ef18 Mon Sep 17 00:00:00 2001
From: Frantisek Sumsal <frantisek@sumsal.cz>
Date: Wed, 10 May 2023 13:49:34 +0200
Subject: [PATCH] test: merge TEST-11-ISSUE-3166 into TEST-07-PID1
(cherry picked from commit 33dff897b9ad1e24b2c737de1e41b21c4543c8e1)
Related: #2213521
---
test/TEST-11-ISSUE-3166/Makefile | 1 -
test/TEST-11-ISSUE-3166/test.sh | 11 -----------
.../issue3166-fail-on-restart.service} | 0
test/units/testsuite-07.issue-3166.sh | 16 ++++++++++++++++
test/units/testsuite-11.service | 8 --------
test/units/testsuite-11.sh | 14 --------------
6 files changed, 16 insertions(+), 34 deletions(-)
delete mode 120000 test/TEST-11-ISSUE-3166/Makefile
delete mode 100755 test/TEST-11-ISSUE-3166/test.sh
rename test/{testsuite-11.units/fail-on-restart.service => testsuite-07.units/issue3166-fail-on-restart.service} (100%)
create mode 100755 test/units/testsuite-07.issue-3166.sh
delete mode 100644 test/units/testsuite-11.service
delete mode 100755 test/units/testsuite-11.sh
diff --git a/test/TEST-11-ISSUE-3166/Makefile b/test/TEST-11-ISSUE-3166/Makefile
deleted file mode 120000
index e9f93b1104..0000000000
--- a/test/TEST-11-ISSUE-3166/Makefile
+++ /dev/null
@@ -1 +0,0 @@
-../TEST-01-BASIC/Makefile
\ No newline at end of file
diff --git a/test/TEST-11-ISSUE-3166/test.sh b/test/TEST-11-ISSUE-3166/test.sh
deleted file mode 100755
index 12dabd704d..0000000000
--- a/test/TEST-11-ISSUE-3166/test.sh
+++ /dev/null
@@ -1,11 +0,0 @@
-#!/usr/bin/env bash
-# SPDX-License-Identifier: LGPL-2.1-or-later
-set -e
-
-TEST_DESCRIPTION="https://github.com/systemd/systemd/issues/3166"
-TEST_NO_NSPAWN=1
-
-# shellcheck source=test/test-functions
-. "${TEST_BASE_DIR:?}/test-functions"
-
-do_test "$@"
diff --git a/test/testsuite-11.units/fail-on-restart.service b/test/testsuite-07.units/issue3166-fail-on-restart.service
similarity index 100%
rename from test/testsuite-11.units/fail-on-restart.service
rename to test/testsuite-07.units/issue3166-fail-on-restart.service
diff --git a/test/units/testsuite-07.issue-3166.sh b/test/units/testsuite-07.issue-3166.sh
new file mode 100755
index 0000000000..6677901358
--- /dev/null
+++ b/test/units/testsuite-07.issue-3166.sh
@@ -0,0 +1,16 @@
+#!/usr/bin/env bash
+# SPDX-License-Identifier: LGPL-2.1-or-later
+set -eux
+set -o pipefail
+
+# Service doesn't enter the "failed" state
+# Issue: https://github.com/systemd/systemd/issues/3166
+
+systemctl --no-block start issue3166-fail-on-restart.service
+active_state="$(systemctl show --value --property ActiveState issue3166-fail-on-restart.service)"
+while [[ "$active_state" == "activating" || "$active_state" =~ ^(in)?active$ ]]; do
+ sleep .5
+ active_state="$(systemctl show --value --property ActiveState issue3166-fail-on-restart.service)"
+done
+systemctl is-failed issue3166-fail-on-restart.service || exit 1
+[[ "$(systemctl show --value --property NRestarts issue3166-fail-on-restart.service)" -le 3 ]] || exit 1
diff --git a/test/units/testsuite-11.service b/test/units/testsuite-11.service
deleted file mode 100644
index 5dfcf50e3f..0000000000
--- a/test/units/testsuite-11.service
+++ /dev/null
@@ -1,8 +0,0 @@
-# SPDX-License-Identifier: LGPL-2.1-or-later
-[Unit]
-Description=TEST-11-ISSUE-3166
-
-[Service]
-ExecStartPre=rm -f /failed /testok
-ExecStart=/usr/lib/systemd/tests/testdata/units/%N.sh
-Type=oneshot
diff --git a/test/units/testsuite-11.sh b/test/units/testsuite-11.sh
deleted file mode 100755
index 7e1391d8ea..0000000000
--- a/test/units/testsuite-11.sh
+++ /dev/null
@@ -1,14 +0,0 @@
-#!/usr/bin/env bash
-# SPDX-License-Identifier: LGPL-2.1-or-later
-set -eux
-set -o pipefail
-
-systemctl --no-block start fail-on-restart.service
-active_state=$(systemctl show --value --property ActiveState fail-on-restart.service)
-while [[ "$active_state" == "activating" || "$active_state" =~ ^(in)?active$ ]]; do
- sleep .5
- active_state=$(systemctl show --value --property ActiveState fail-on-restart.service)
-done
-systemctl is-failed fail-on-restart.service || exit 1
-[[ "$(systemctl show --value --property NRestarts fail-on-restart.service)" -le 3 ]] || exit 1
-touch /testok

View File

@ -0,0 +1,172 @@
From 4fcfb4f333470be69b0929a787509e64ebe96b33 Mon Sep 17 00:00:00 2001
From: Frantisek Sumsal <frantisek@sumsal.cz>
Date: Wed, 10 May 2023 13:58:13 +0200
Subject: [PATCH] test: merge TEST-12-ISSUE-3171 into TEST-07-PID1
(cherry picked from commit 51b6dbf75ad48a816e6a1503fd5d7c4b9ba2b1d6)
Related: #2213521
---
test/TEST-12-ISSUE-3171/Makefile | 1 -
test/TEST-12-ISSUE-3171/test.sh | 11 ------
test/units/testsuite-07.issue-3171.sh | 50 +++++++++++++++++++++++++++
test/units/testsuite-12.service | 9 -----
test/units/testsuite-12.sh | 49 --------------------------
5 files changed, 50 insertions(+), 70 deletions(-)
delete mode 120000 test/TEST-12-ISSUE-3171/Makefile
delete mode 100755 test/TEST-12-ISSUE-3171/test.sh
create mode 100755 test/units/testsuite-07.issue-3171.sh
delete mode 100644 test/units/testsuite-12.service
delete mode 100755 test/units/testsuite-12.sh
diff --git a/test/TEST-12-ISSUE-3171/Makefile b/test/TEST-12-ISSUE-3171/Makefile
deleted file mode 120000
index e9f93b1104..0000000000
--- a/test/TEST-12-ISSUE-3171/Makefile
+++ /dev/null
@@ -1 +0,0 @@
-../TEST-01-BASIC/Makefile
\ No newline at end of file
diff --git a/test/TEST-12-ISSUE-3171/test.sh b/test/TEST-12-ISSUE-3171/test.sh
deleted file mode 100755
index 977e04ee3f..0000000000
--- a/test/TEST-12-ISSUE-3171/test.sh
+++ /dev/null
@@ -1,11 +0,0 @@
-#!/usr/bin/env bash
-# SPDX-License-Identifier: LGPL-2.1-or-later
-set -e
-
-TEST_DESCRIPTION="https://github.com/systemd/systemd/issues/3171"
-TEST_NO_QEMU=1
-
-# shellcheck source=test/test-functions
-. "${TEST_BASE_DIR:?}/test-functions"
-
-do_test "$@"
diff --git a/test/units/testsuite-07.issue-3171.sh b/test/units/testsuite-07.issue-3171.sh
new file mode 100755
index 0000000000..db17c25f90
--- /dev/null
+++ b/test/units/testsuite-07.issue-3171.sh
@@ -0,0 +1,50 @@
+#!/usr/bin/env bash
+# SPDX-License-Identifier: LGPL-2.1-or-later
+set -eux
+set -o pipefail
+
+# SocketGroup lost on daemon-reload with unit moving away temporarily
+# Issue: https://github.com/systemd/systemd/issues/3171
+
+echo "g adm - - -" | systemd-sysusers -
+
+U=/run/systemd/system/issue-3171.socket
+cat >$U <<EOF
+[Unit]
+Description=Test 12 socket
+[Socket]
+Accept=yes
+ListenStream=/run/issue-3171.socket
+SocketGroup=adm
+SocketMode=0660
+EOF
+
+cat >/run/systemd/system/issue-3171@.service <<EOF
+[Unit]
+Description=Test service
+[Service]
+StandardInput=socket
+ExecStart=/bin/sh -x -c cat
+EOF
+
+systemctl start issue-3171.socket
+systemctl is-active issue-3171.socket
+[[ "$(stat --format='%G' /run/issue-3171.socket)" == adm ]]
+echo A | nc -w1 -U /run/issue-3171.socket
+
+mv $U ${U}.disabled
+systemctl daemon-reload
+systemctl is-active issue-3171.socket
+[[ "$(stat --format='%G' /run/issue-3171.socket)" == adm ]]
+echo B | nc -w1 -U /run/issue-3171.socket && exit 1
+
+mv ${U}.disabled $U
+systemctl daemon-reload
+systemctl is-active issue-3171.socket
+echo C | nc -w1 -U /run/issue-3171.socket && exit 1
+[[ "$(stat --format='%G' /run/issue-3171.socket)" == adm ]]
+
+systemctl restart issue-3171.socket
+systemctl is-active issue-3171.socket
+echo D | nc -w1 -U /run/issue-3171.socket
+[[ "$(stat --format='%G' /run/issue-3171.socket)" == adm ]]
diff --git a/test/units/testsuite-12.service b/test/units/testsuite-12.service
deleted file mode 100644
index b26cfa575d..0000000000
--- a/test/units/testsuite-12.service
+++ /dev/null
@@ -1,9 +0,0 @@
-# SPDX-License-Identifier: LGPL-2.1-or-later
-[Unit]
-Description=TEST-12-ISSUE-3171
-After=multi-user.target
-
-[Service]
-ExecStartPre=rm -f /failed /testok
-ExecStart=/usr/lib/systemd/tests/testdata/units/%N.sh
-Type=oneshot
diff --git a/test/units/testsuite-12.sh b/test/units/testsuite-12.sh
deleted file mode 100755
index 8c22a8b031..0000000000
--- a/test/units/testsuite-12.sh
+++ /dev/null
@@ -1,49 +0,0 @@
-#!/usr/bin/env bash
-# SPDX-License-Identifier: LGPL-2.1-or-later
-set -eux
-set -o pipefail
-
-echo "g adm - - -" | systemd-sysusers -
-
-U=/run/systemd/system/test12.socket
-cat >$U <<EOF
-[Unit]
-Description=Test 12 socket
-[Socket]
-Accept=yes
-ListenStream=/run/test12.socket
-SocketGroup=adm
-SocketMode=0660
-EOF
-
-cat >/run/systemd/system/test12@.service <<EOF
-[Unit]
-Description=Test service
-[Service]
-StandardInput=socket
-ExecStart=/bin/sh -x -c cat
-EOF
-
-systemctl start test12.socket
-systemctl is-active test12.socket
-[[ "$(stat --format='%G' /run/test12.socket)" == adm ]]
-echo A | nc -w1 -U /run/test12.socket
-
-mv $U ${U}.disabled
-systemctl daemon-reload
-systemctl is-active test12.socket
-[[ "$(stat --format='%G' /run/test12.socket)" == adm ]]
-echo B | nc -w1 -U /run/test12.socket && exit 1
-
-mv ${U}.disabled $U
-systemctl daemon-reload
-systemctl is-active test12.socket
-echo C | nc -w1 -U /run/test12.socket && exit 1
-[[ "$(stat --format='%G' /run/test12.socket)" == adm ]]
-
-systemctl restart test12.socket
-systemctl is-active test12.socket
-echo D | nc -w1 -U /run/test12.socket
-[[ "$(stat --format='%G' /run/test12.socket)" == adm ]]
-
-touch /testok

View File

@ -0,0 +1,76 @@
From 82168bbf3db85a2e58b333794db5ce5b456ac91c Mon Sep 17 00:00:00 2001
From: Frantisek Sumsal <frantisek@sumsal.cz>
Date: Wed, 10 May 2023 14:02:54 +0200
Subject: [PATCH] test: move TEST-23's units into a dedicated subfolder
To remain consistent with other tests.
(cherry picked from commit 8412cdf4fd0576428d4d22949ef831bd4d51326d)
Related: #2213521
---
test/meson.build | 3 +++
.../testsuite-23-binds-to.service | 0
.../testsuite-23-bound-by.service | 0
test/{units => testsuite-23.units}/testsuite-23-fail.service | 0
.../testsuite-23-prop-stop-one.service | 0
.../testsuite-23-prop-stop-two.service | 0
.../testsuite-23-short-lived.service | 0
.../{units => testsuite-23.units}/testsuite-23-success.service | 0
test/{units => testsuite-23.units}/testsuite-23-uphold.service | 0
9 files changed, 3 insertions(+)
rename test/{units => testsuite-23.units}/testsuite-23-binds-to.service (100%)
rename test/{units => testsuite-23.units}/testsuite-23-bound-by.service (100%)
rename test/{units => testsuite-23.units}/testsuite-23-fail.service (100%)
rename test/{units => testsuite-23.units}/testsuite-23-prop-stop-one.service (100%)
rename test/{units => testsuite-23.units}/testsuite-23-prop-stop-two.service (100%)
rename test/{units => testsuite-23.units}/testsuite-23-short-lived.service (100%)
rename test/{units => testsuite-23.units}/testsuite-23-success.service (100%)
rename test/{units => testsuite-23.units}/testsuite-23-uphold.service (100%)
diff --git a/test/meson.build b/test/meson.build
index 92c92dcb3b..3ca544690a 100644
--- a/test/meson.build
+++ b/test/meson.build
@@ -48,6 +48,9 @@ if install_tests
install_subdir('testsuite-16.units',
exclude_files : '.gitattributes',
install_dir : testdata_dir)
+ install_subdir('testsuite-23.units',
+ exclude_files : '.gitattributes',
+ install_dir : testdata_dir)
install_subdir('testsuite-28.units',
exclude_files : '.gitattributes',
install_dir : testdata_dir)
diff --git a/test/units/testsuite-23-binds-to.service b/test/testsuite-23.units/testsuite-23-binds-to.service
similarity index 100%
rename from test/units/testsuite-23-binds-to.service
rename to test/testsuite-23.units/testsuite-23-binds-to.service
diff --git a/test/units/testsuite-23-bound-by.service b/test/testsuite-23.units/testsuite-23-bound-by.service
similarity index 100%
rename from test/units/testsuite-23-bound-by.service
rename to test/testsuite-23.units/testsuite-23-bound-by.service
diff --git a/test/units/testsuite-23-fail.service b/test/testsuite-23.units/testsuite-23-fail.service
similarity index 100%
rename from test/units/testsuite-23-fail.service
rename to test/testsuite-23.units/testsuite-23-fail.service
diff --git a/test/units/testsuite-23-prop-stop-one.service b/test/testsuite-23.units/testsuite-23-prop-stop-one.service
similarity index 100%
rename from test/units/testsuite-23-prop-stop-one.service
rename to test/testsuite-23.units/testsuite-23-prop-stop-one.service
diff --git a/test/units/testsuite-23-prop-stop-two.service b/test/testsuite-23.units/testsuite-23-prop-stop-two.service
similarity index 100%
rename from test/units/testsuite-23-prop-stop-two.service
rename to test/testsuite-23.units/testsuite-23-prop-stop-two.service
diff --git a/test/units/testsuite-23-short-lived.service b/test/testsuite-23.units/testsuite-23-short-lived.service
similarity index 100%
rename from test/units/testsuite-23-short-lived.service
rename to test/testsuite-23.units/testsuite-23-short-lived.service
diff --git a/test/units/testsuite-23-success.service b/test/testsuite-23.units/testsuite-23-success.service
similarity index 100%
rename from test/units/testsuite-23-success.service
rename to test/testsuite-23.units/testsuite-23-success.service
diff --git a/test/units/testsuite-23-uphold.service b/test/testsuite-23.units/testsuite-23-uphold.service
similarity index 100%
rename from test/units/testsuite-23-uphold.service
rename to test/testsuite-23.units/testsuite-23-uphold.service

View File

@ -0,0 +1,150 @@
From da8a864aae13f8b54b0f8ba619a704c026e0f2d2 Mon Sep 17 00:00:00 2001
From: Frantisek Sumsal <frantisek@sumsal.cz>
Date: Wed, 10 May 2023 14:19:40 +0200
Subject: [PATCH] test: merge TEST-47-ISSUE-14566 into TEST-07-PID1
(cherry picked from commit 11562ee585d5f2e42cb583f06aa01c7383d85f55)
Related: #2213521
---
test/TEST-47-ISSUE-14566/Makefile | 1 -
test/TEST-47-ISSUE-14566/test.sh | 10 ------
.../issue14566-repro.service} | 2 +-
.../issue14566-repro.sh} | 0
test/units/testsuite-07.issue-14566.sh | 31 +++++++++++++++++++
test/units/testsuite-47.service | 8 -----
test/units/testsuite-47.sh | 25 ---------------
7 files changed, 32 insertions(+), 45 deletions(-)
delete mode 120000 test/TEST-47-ISSUE-14566/Makefile
delete mode 100755 test/TEST-47-ISSUE-14566/test.sh
rename test/{units/testsuite-47-repro.service => testsuite-07.units/issue14566-repro.service} (66%)
rename test/{units/testsuite-47-repro.sh => testsuite-07.units/issue14566-repro.sh} (100%)
create mode 100755 test/units/testsuite-07.issue-14566.sh
delete mode 100644 test/units/testsuite-47.service
delete mode 100755 test/units/testsuite-47.sh
diff --git a/test/TEST-47-ISSUE-14566/Makefile b/test/TEST-47-ISSUE-14566/Makefile
deleted file mode 120000
index e9f93b1104..0000000000
--- a/test/TEST-47-ISSUE-14566/Makefile
+++ /dev/null
@@ -1 +0,0 @@
-../TEST-01-BASIC/Makefile
\ No newline at end of file
diff --git a/test/TEST-47-ISSUE-14566/test.sh b/test/TEST-47-ISSUE-14566/test.sh
deleted file mode 100755
index 8bdbe14b97..0000000000
--- a/test/TEST-47-ISSUE-14566/test.sh
+++ /dev/null
@@ -1,10 +0,0 @@
-#!/usr/bin/env bash
-# SPDX-License-Identifier: LGPL-2.1-or-later
-set -e
-
-TEST_DESCRIPTION="Test that KillMode=mixed does not leave left over processes with ExecStopPost="
-
-# shellcheck source=test/test-functions
-. "${TEST_BASE_DIR:?}/test-functions"
-
-do_test "$@"
diff --git a/test/units/testsuite-47-repro.service b/test/testsuite-07.units/issue14566-repro.service
similarity index 66%
rename from test/units/testsuite-47-repro.service
rename to test/testsuite-07.units/issue14566-repro.service
index 1508ac6242..56805963b4 100644
--- a/test/units/testsuite-47-repro.service
+++ b/test/testsuite-07.units/issue14566-repro.service
@@ -3,6 +3,6 @@
Description=Issue 14566 Repro
[Service]
-ExecStart=/usr/lib/systemd/tests/testdata/units/%N.sh
+ExecStart=/usr/lib/systemd/tests/testdata/testsuite-07.units/%N.sh
ExecStopPost=/bin/true
KillMode=mixed
diff --git a/test/units/testsuite-47-repro.sh b/test/testsuite-07.units/issue14566-repro.sh
similarity index 100%
rename from test/units/testsuite-47-repro.sh
rename to test/testsuite-07.units/issue14566-repro.sh
diff --git a/test/units/testsuite-07.issue-14566.sh b/test/units/testsuite-07.issue-14566.sh
new file mode 100755
index 0000000000..e17c3934c1
--- /dev/null
+++ b/test/units/testsuite-07.issue-14566.sh
@@ -0,0 +1,31 @@
+#!/usr/bin/env bash
+# SPDX-License-Identifier: LGPL-2.1-or-later
+set -eux
+set -o pipefail
+
+# Test that KillMode=mixed does not leave left over processes with ExecStopPost=
+# Issue: https://github.com/systemd/systemd/issues/14566
+
+if [[ -n "${ASAN_OPTIONS:-}" ]]; then
+ # Temporarily skip this test when running with sanitizers due to a deadlock
+ # See: https://bugzilla.redhat.com/show_bug.cgi?id=2098125
+ echo "Sanitizers detected, skipping the test..."
+ exit 0
+fi
+
+systemd-analyze log-level debug
+
+systemctl start issue14566-repro
+sleep 4
+systemctl status issue14566-repro
+
+leaked_pid=$(cat /leakedtestpid)
+
+systemctl stop issue14566-repro
+sleep 4
+
+# Leaked PID will still be around if we're buggy.
+# I personally prefer to see 42.
+ps -p "$leaked_pid" && exit 42
+
+systemd-analyze log-level info
diff --git a/test/units/testsuite-47.service b/test/units/testsuite-47.service
deleted file mode 100644
index d5ad480108..0000000000
--- a/test/units/testsuite-47.service
+++ /dev/null
@@ -1,8 +0,0 @@
-# SPDX-License-Identifier: LGPL-2.1-or-later
-[Unit]
-Description=TEST-47-ISSUE-14566
-
-[Service]
-ExecStartPre=rm -f /failed /testok
-ExecStart=/usr/lib/systemd/tests/testdata/units/%N.sh
-Type=oneshot
diff --git a/test/units/testsuite-47.sh b/test/units/testsuite-47.sh
deleted file mode 100755
index 529e9617a5..0000000000
--- a/test/units/testsuite-47.sh
+++ /dev/null
@@ -1,25 +0,0 @@
-#!/usr/bin/env bash
-# SPDX-License-Identifier: LGPL-2.1-or-later
-set -eux
-set -o pipefail
-
-systemd-analyze log-level debug
-
-systemctl start testsuite-47-repro
-sleep 4
-systemctl status testsuite-47-repro
-
-leaked_pid=$(cat /leakedtestpid)
-
-systemctl stop testsuite-47-repro
-sleep 4
-
-# Leaked PID will still be around if we're buggy.
-# I personally prefer to see 42.
-ps -p "$leaked_pid" && exit 42
-
-systemd-analyze log-level info
-
-echo OK >/testok
-
-exit 0

View File

@ -0,0 +1,120 @@
From 44a272e129174f72c4b150fec333011c4f9c7c69 Mon Sep 17 00:00:00 2001
From: Frantisek Sumsal <frantisek@sumsal.cz>
Date: Wed, 10 May 2023 14:26:08 +0200
Subject: [PATCH] test: merge TEST-51-ISSUE-16115 into TEST-07-PID1
(cherry picked from commit d8d8380a35c494b6cb7ec5ee12dbe93002bd2f2f)
Related: #2213521
---
test/TEST-51-ISSUE-16115/Makefile | 1 -
test/TEST-51-ISSUE-16115/test.sh | 10 ----------
.../issue16115-repro-1.service} | 0
.../issue16115-repro-2.service} | 0
.../issue16115-repro-3.service} | 0
test/units/testsuite-07.issue-16115.sh | 16 ++++++++++++++++
test/units/testsuite-51.service | 8 --------
test/units/testsuite-51.sh | 15 ---------------
8 files changed, 16 insertions(+), 34 deletions(-)
delete mode 120000 test/TEST-51-ISSUE-16115/Makefile
delete mode 100755 test/TEST-51-ISSUE-16115/test.sh
rename test/{units/testsuite-51-repro-1.service => testsuite-07.units/issue16115-repro-1.service} (100%)
rename test/{units/testsuite-51-repro-2.service => testsuite-07.units/issue16115-repro-2.service} (100%)
rename test/{units/testsuite-51-repro-3.service => testsuite-07.units/issue16115-repro-3.service} (100%)
create mode 100755 test/units/testsuite-07.issue-16115.sh
delete mode 100644 test/units/testsuite-51.service
delete mode 100755 test/units/testsuite-51.sh
diff --git a/test/TEST-51-ISSUE-16115/Makefile b/test/TEST-51-ISSUE-16115/Makefile
deleted file mode 120000
index e9f93b1104..0000000000
--- a/test/TEST-51-ISSUE-16115/Makefile
+++ /dev/null
@@ -1 +0,0 @@
-../TEST-01-BASIC/Makefile
\ No newline at end of file
diff --git a/test/TEST-51-ISSUE-16115/test.sh b/test/TEST-51-ISSUE-16115/test.sh
deleted file mode 100755
index 7b306fa57b..0000000000
--- a/test/TEST-51-ISSUE-16115/test.sh
+++ /dev/null
@@ -1,10 +0,0 @@
-#!/usr/bin/env bash
-# SPDX-License-Identifier: LGPL-2.1-or-later
-set -e
-
-TEST_DESCRIPTION="Test ExecCondition= does not restart on abnormal or failure"
-
-# shellcheck source=test/test-functions
-. "${TEST_BASE_DIR:?}/test-functions"
-
-do_test "$@"
diff --git a/test/units/testsuite-51-repro-1.service b/test/testsuite-07.units/issue16115-repro-1.service
similarity index 100%
rename from test/units/testsuite-51-repro-1.service
rename to test/testsuite-07.units/issue16115-repro-1.service
diff --git a/test/units/testsuite-51-repro-2.service b/test/testsuite-07.units/issue16115-repro-2.service
similarity index 100%
rename from test/units/testsuite-51-repro-2.service
rename to test/testsuite-07.units/issue16115-repro-2.service
diff --git a/test/units/testsuite-51-repro-3.service b/test/testsuite-07.units/issue16115-repro-3.service
similarity index 100%
rename from test/units/testsuite-51-repro-3.service
rename to test/testsuite-07.units/issue16115-repro-3.service
diff --git a/test/units/testsuite-07.issue-16115.sh b/test/units/testsuite-07.issue-16115.sh
new file mode 100755
index 0000000000..8f638269cd
--- /dev/null
+++ b/test/units/testsuite-07.issue-16115.sh
@@ -0,0 +1,16 @@
+#!/usr/bin/env bash
+# SPDX-License-Identifier: LGPL-2.1-or-later
+set -eux
+set -o pipefail
+
+# Test ExecCondition= does not restart on abnormal or failure
+# Issue: https://github.com/systemd/systemd/issues/16115
+
+systemctl start issue16115-repro-1
+systemctl start issue16115-repro-2
+systemctl start issue16115-repro-3
+sleep 5 # wait a bit in case there are restarts so we can count them below
+
+[[ "$(systemctl show issue16115-repro-1 -P NRestarts)" == "0" ]]
+[[ "$(systemctl show issue16115-repro-2 -P NRestarts)" == "0" ]]
+[[ "$(systemctl show issue16115-repro-3 -P NRestarts)" == "0" ]]
diff --git a/test/units/testsuite-51.service b/test/units/testsuite-51.service
deleted file mode 100644
index c241262c27..0000000000
--- a/test/units/testsuite-51.service
+++ /dev/null
@@ -1,8 +0,0 @@
-# SPDX-License-Identifier: LGPL-2.1-or-later
-[Unit]
-Description=TEST-51-ISSUE-16115
-
-[Service]
-ExecStartPre=rm -f /failed /testok
-ExecStart=/usr/lib/systemd/tests/testdata/units/%N.sh
-Type=oneshot
diff --git a/test/units/testsuite-51.sh b/test/units/testsuite-51.sh
deleted file mode 100755
index e603d953a4..0000000000
--- a/test/units/testsuite-51.sh
+++ /dev/null
@@ -1,15 +0,0 @@
-#!/usr/bin/env bash
-# SPDX-License-Identifier: LGPL-2.1-or-later
-set -eux
-set -o pipefail
-
-systemctl start testsuite-51-repro-1
-systemctl start testsuite-51-repro-2
-systemctl start testsuite-51-repro-3
-sleep 5 # wait a bit in case there are restarts so we can count them below
-
-[[ "$(systemctl show testsuite-51-repro-1 -P NRestarts)" == "0" ]]
-[[ "$(systemctl show testsuite-51-repro-2 -P NRestarts)" == "0" ]]
-[[ "$(systemctl show testsuite-51-repro-3 -P NRestarts)" == "0" ]]
-
-touch /testok

View File

@ -0,0 +1,273 @@
From 77827462f17ba6de2c56c7e242d1468f9c112cb3 Mon Sep 17 00:00:00 2001
From: Frantisek Sumsal <frantisek@sumsal.cz>
Date: Wed, 10 May 2023 20:17:19 +0200
Subject: [PATCH] test: merge TEST-20-MAINPIDGAMES into TEST-07-PID1
(cherry picked from commit 3a4b86264eef6bd51e880386388e8b3f95cbaa33)
Related: #2213521
---
test/TEST-20-MAINPIDGAMES/Makefile | 1 -
test/TEST-20-MAINPIDGAMES/test.sh | 10 ---
...-20.sh => testsuite-07.main-PID-change.sh} | 90 +++++++++++--------
test/units/testsuite-07.service | 1 +
test/units/testsuite-20.service | 11 ---
5 files changed, 52 insertions(+), 61 deletions(-)
delete mode 120000 test/TEST-20-MAINPIDGAMES/Makefile
delete mode 100755 test/TEST-20-MAINPIDGAMES/test.sh
rename test/units/{testsuite-20.sh => testsuite-07.main-PID-change.sh} (55%)
delete mode 100644 test/units/testsuite-20.service
diff --git a/test/TEST-20-MAINPIDGAMES/Makefile b/test/TEST-20-MAINPIDGAMES/Makefile
deleted file mode 120000
index e9f93b1104..0000000000
--- a/test/TEST-20-MAINPIDGAMES/Makefile
+++ /dev/null
@@ -1 +0,0 @@
-../TEST-01-BASIC/Makefile
\ No newline at end of file
diff --git a/test/TEST-20-MAINPIDGAMES/test.sh b/test/TEST-20-MAINPIDGAMES/test.sh
deleted file mode 100755
index b663201efb..0000000000
--- a/test/TEST-20-MAINPIDGAMES/test.sh
+++ /dev/null
@@ -1,10 +0,0 @@
-#!/usr/bin/env bash
-# SPDX-License-Identifier: LGPL-2.1-or-later
-set -e
-
-TEST_DESCRIPTION="test changing main PID"
-
-# shellcheck source=test/test-functions
-. "${TEST_BASE_DIR:?}/test-functions"
-
-do_test "$@"
diff --git a/test/units/testsuite-20.sh b/test/units/testsuite-07.main-PID-change.sh
similarity index 55%
rename from test/units/testsuite-20.sh
rename to test/units/testsuite-07.main-PID-change.sh
index 338769aacc..be4631f10d 100755
--- a/test/units/testsuite-20.sh
+++ b/test/units/testsuite-07.main-PID-change.sh
@@ -3,9 +3,13 @@
set -eux
set -o pipefail
+# Test changing the main PID
+
systemd-analyze log-level debug
-test "$(systemctl show -P MainPID testsuite-20.service)" -eq $$
+# The main service PID should be the parent bash process
+MAINPID="${PPID:?}"
+test "$(systemctl show -P MainPID testsuite-07.service)" -eq "$MAINPID"
# Start a test process inside of our own cgroup
sleep infinity &
@@ -13,48 +17,48 @@ INTERNALPID=$!
disown
# Start a test process outside of our own cgroup
-systemd-run -p DynamicUser=1 --unit=test20-sleep.service /bin/sleep infinity
-EXTERNALPID="$(systemctl show -P MainPID test20-sleep.service)"
+systemd-run -p DynamicUser=1 --unit=test-sleep.service /bin/sleep infinity
+EXTERNALPID="$(systemctl show -P MainPID test-sleep.service)"
# Update our own main PID to the external test PID, this should work
systemd-notify MAINPID="$EXTERNALPID"
-test "$(systemctl show -P MainPID testsuite-20.service)" -eq "$EXTERNALPID"
+test "$(systemctl show -P MainPID testsuite-07.service)" -eq "$EXTERNALPID"
# Update our own main PID to the internal test PID, this should work, too
systemd-notify MAINPID=$INTERNALPID
-test "$(systemctl show -P MainPID testsuite-20.service)" -eq "$INTERNALPID"
+test "$(systemctl show -P MainPID testsuite-07.service)" -eq "$INTERNALPID"
# Update it back to our own PID, this should also work
-systemd-notify MAINPID=$$
-test "$(systemctl show -P MainPID testsuite-20.service)" -eq $$
+systemd-notify MAINPID="$MAINPID"
+test "$(systemctl show -P MainPID testsuite-07.service)" -eq "$MAINPID"
# Try to set it to PID 1, which it should ignore, because that's the manager
systemd-notify MAINPID=1
-test "$(systemctl show -P MainPID testsuite-20.service)" -eq $$
+test "$(systemctl show -P MainPID testsuite-07.service)" -eq "$MAINPID"
# Try to set it to PID 0, which is invalid and should be ignored
systemd-notify MAINPID=0
-test "$(systemctl show -P MainPID testsuite-20.service)" -eq $$
+test "$(systemctl show -P MainPID testsuite-07.service)" -eq "$MAINPID"
# Try to set it to a valid but non-existing PID, which should be ignored. (Note
# that we set the PID to a value well above any known /proc/sys/kernel/pid_max,
# which means we can be pretty sure it doesn't exist by coincidence)
systemd-notify MAINPID=1073741824
-test "$(systemctl show -P MainPID testsuite-20.service)" -eq $$
+test "$(systemctl show -P MainPID testsuite-07.service)" -eq "$MAINPID"
# Change it again to the external PID, without privileges this time. This should be ignored, because the PID is from outside of our cgroup and we lack privileges.
systemd-notify --uid=1000 MAINPID="$EXTERNALPID"
-test "$(systemctl show -P MainPID testsuite-20.service)" -eq $$
+test "$(systemctl show -P MainPID testsuite-07.service)" -eq "$MAINPID"
# Change it again to the internal PID, without privileges this time. This should work, as the process is on our cgroup, and that's enough even if we lack privileges.
systemd-notify --uid=1000 MAINPID="$INTERNALPID"
-test "$(systemctl show -P MainPID testsuite-20.service)" -eq "$INTERNALPID"
+test "$(systemctl show -P MainPID testsuite-07.service)" -eq "$INTERNALPID"
# Update it back to our own PID, this should also work
-systemd-notify --uid=1000 MAINPID=$$
-test "$(systemctl show -P MainPID testsuite-20.service)" -eq $$
+systemd-notify --uid=1000 MAINPID="$MAINPID"
+test "$(systemctl show -P MainPID testsuite-07.service)" -eq "$MAINPID"
-cat >/tmp/test20-mainpid.sh <<EOF
+cat >/tmp/test-mainpid.sh <<\EOF
#!/usr/bin/env bash
set -eux
@@ -65,20 +69,26 @@ sleep infinity &
disown
sleep infinity &
-MAINPID=\$!
+MAINPID=$!
disown
sleep infinity &
disown
-echo \$MAINPID >/run/mainpidsh/pid
+echo $MAINPID >/run/mainpidsh/pid
EOF
-chmod +x /tmp/test20-mainpid.sh
+chmod +x /tmp/test-mainpid.sh
-systemd-run --unit=test20-mainpidsh.service -p StandardOutput=tty -p StandardError=tty -p Type=forking -p RuntimeDirectory=mainpidsh -p PIDFile=/run/mainpidsh/pid /tmp/test20-mainpid.sh
-test "$(systemctl show -P MainPID test20-mainpidsh.service)" -eq "$(cat /run/mainpidsh/pid)"
+systemd-run --unit=test-mainpidsh.service \
+ -p StandardOutput=tty \
+ -p StandardError=tty \
+ -p Type=forking \
+ -p RuntimeDirectory=mainpidsh \
+ -p PIDFile=/run/mainpidsh/pid \
+ /tmp/test-mainpid.sh
+test "$(systemctl show -P MainPID test-mainpidsh.service)" -eq "$(cat /run/mainpidsh/pid)"
-cat >/tmp/test20-mainpid2.sh <<EOF
+cat >/tmp/test-mainpid2.sh <<\EOF
#!/usr/bin/env bash
set -eux
@@ -89,21 +99,27 @@ sleep infinity &
disown
sleep infinity &
-MAINPID=\$!
+MAINPID=$!
disown
sleep infinity &
disown
-echo \$MAINPID >/run/mainpidsh2/pid
+echo $MAINPID >/run/mainpidsh2/pid
chown 1001:1001 /run/mainpidsh2/pid
EOF
-chmod +x /tmp/test20-mainpid2.sh
+chmod +x /tmp/test-mainpid2.sh
-systemd-run --unit=test20-mainpidsh2.service -p StandardOutput=tty -p StandardError=tty -p Type=forking -p RuntimeDirectory=mainpidsh2 -p PIDFile=/run/mainpidsh2/pid /tmp/test20-mainpid2.sh
-test "$(systemctl show -P MainPID test20-mainpidsh2.service)" -eq "$(cat /run/mainpidsh2/pid)"
+systemd-run --unit=test-mainpidsh2.service \
+ -p StandardOutput=tty \
+ -p StandardError=tty \
+ -p Type=forking \
+ -p RuntimeDirectory=mainpidsh2 \
+ -p PIDFile=/run/mainpidsh2/pid \
+ /tmp/test-mainpid2.sh
+test "$(systemctl show -P MainPID test-mainpidsh2.service)" -eq "$(cat /run/mainpidsh2/pid)"
-cat >/dev/shm/test20-mainpid3.sh <<EOF
+cat >/dev/shm/test-mainpid3.sh <<EOF
#!/usr/bin/env bash
set -eux
@@ -124,11 +140,11 @@ ln -s ../mainpidsh/pid /run/mainpidsh3/pid
# Quick assertion that the link isn't dead
test -f /run/mainpidsh3/pid
EOF
-chmod 755 /dev/shm/test20-mainpid3.sh
+chmod 755 /dev/shm/test-mainpid3.sh
# This has to fail, as we shouldn't accept the dangerous PID file, and then
# inotify-wait on it to be corrected which we never do.
-systemd-run --unit=test20-mainpidsh3.service \
+systemd-run --unit=test-mainpidsh3.service \
-p StandardOutput=tty \
-p StandardError=tty \
-p Type=forking \
@@ -136,15 +152,15 @@ systemd-run --unit=test20-mainpidsh3.service \
-p PIDFile=/run/mainpidsh3/pid \
-p DynamicUser=1 \
-p TimeoutStartSec=2s \
- /dev/shm/test20-mainpid3.sh \
+ /dev/shm/test-mainpid3.sh \
&& { echo 'unexpected success'; exit 1; }
# Test that this failed due to timeout, and not some other error
-test "$(systemctl show -P Result test20-mainpidsh3.service)" = timeout
+test "$(systemctl show -P Result test-mainpidsh3.service)" = timeout
# Test that scope units work
-systemd-run --scope --unit test20-true.scope /bin/true
-test "$(systemctl show -P Result test20-true.scope)" = success
+systemd-run --scope --unit test-true.scope /bin/true
+test "$(systemctl show -P Result test-true.scope)" = success
# Test that user scope units work as well
@@ -156,11 +172,7 @@ runas() {
}
systemctl start user@4711.service
-runas testuser systemd-run --scope --user --unit test20-true.scope /bin/true
-test "$(systemctl show -P Result test20-true.scope)" = success
+runas testuser systemd-run --scope --user --unit test-true.scope /bin/true
+test "$(systemctl show -P Result test-true.scope)" = success
systemd-analyze log-level info
-
-echo OK >/testok
-
-exit 0
diff --git a/test/units/testsuite-07.service b/test/units/testsuite-07.service
index f45b9c7c5b..cc0a747a88 100644
--- a/test/units/testsuite-07.service
+++ b/test/units/testsuite-07.service
@@ -6,6 +6,7 @@ Description=TEST-07-ISSUE-1981
Type=oneshot
ExecStartPre=rm -f /failed /testok
ExecStart=/usr/lib/systemd/tests/testdata/units/%N.sh
+NotifyAccess=all
# Issue: https://github.com/systemd/systemd/issues/2691
ExecStop=sh -c 'kill -SEGV $$$$'
RemainAfterExit=yes
diff --git a/test/units/testsuite-20.service b/test/units/testsuite-20.service
deleted file mode 100644
index 4228d0b875..0000000000
--- a/test/units/testsuite-20.service
+++ /dev/null
@@ -1,11 +0,0 @@
-# SPDX-License-Identifier: LGPL-2.1-or-later
-[Unit]
-Description=TEST-20-MAINPIDGAMES
-Before=getty-pre.target
-Wants=getty-pre.target
-
-[Service]
-ExecStartPre=rm -f /failed /testok
-ExecStart=/usr/lib/systemd/tests/testdata/units/%N.sh
-Type=oneshot
-NotifyAccess=all

View File

@ -0,0 +1,312 @@
From 47664038ed253f30518f434fb2967286c9382e7f Mon Sep 17 00:00:00 2001
From: Frantisek Sumsal <frantisek@sumsal.cz>
Date: Wed, 10 May 2023 21:12:01 +0200
Subject: [PATCH] test: abstract the common test parts into a utility script
Also, instead of bailing out on the first failed subtest, always run all
subtests and print a summary at the end (with an appropriate exit code).
(cherry picked from commit 15bbc0c1071c439d83e711ef7786d401b6c0a0d4)
Related: #2213521
---
test/units/test-control.sh | 126 +++++++++++++++++++++++++++++++++++++
test/units/testsuite-07.sh | 8 +--
test/units/testsuite-17.sh | 7 ++-
test/units/testsuite-22.sh | 7 ++-
test/units/testsuite-23.sh | 59 ++---------------
test/units/testsuite-74.sh | 8 +--
6 files changed, 146 insertions(+), 69 deletions(-)
create mode 100644 test/units/test-control.sh
diff --git a/test/units/test-control.sh b/test/units/test-control.sh
new file mode 100644
index 0000000000..dd28939cbf
--- /dev/null
+++ b/test/units/test-control.sh
@@ -0,0 +1,126 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
+# shellcheck shell=bash
+
+if [[ "${BASH_SOURCE[0]}" -ef "$0" ]]; then
+ echo >&2 "This file should not be executed directly"
+ exit 1
+fi
+
+declare -i CHILD_PID=0
+PASSED_TESTS=()
+FAILED_TESTS=()
+
+# Like trap, but passes the signal name as the first argument
+trap_with_sig() {
+ local fun="${1:?}"
+ local sig
+ shift
+
+ for sig in "$@"; do
+ # shellcheck disable=SC2064
+ trap "$fun $sig" "$sig"
+ done
+}
+
+# Propagate the caught signal to the current child process
+handle_signal() {
+ local sig="${1:?}"
+
+ if [[ $CHILD_PID -gt 0 ]]; then
+ echo "Propagating signal $sig to child process $CHILD_PID"
+ kill -s "$sig" "$CHILD_PID"
+ fi
+}
+
+# In order to make the handle_signal() stuff above work, we have to execute
+# each script asynchronously, since bash won't execute traps until the currently
+# executed command finishes. This, however, introduces another issue regarding
+# how bash's wait works. Quoting:
+#
+# When bash is waiting for an asynchronous command via the wait builtin,
+# the reception of a signal for which a trap has been set will cause the wait
+# builtin to return immediately with an exit status greater than 128,
+# immediately after which the trap is executed.
+#
+# In other words - every time we propagate a signal, wait returns with
+# 128+signal, so we have to wait again - repeat until the process dies.
+wait_harder() {
+ local pid="${1:?}"
+
+ while kill -0 "$pid" &>/dev/null; do
+ wait "$pid" || :
+ done
+
+ wait "$pid"
+}
+
+# Like run_subtests, but propagate specified signals to the subtest script
+run_subtests_with_signals() {
+ local subtests=("${0%.sh}".*.sh)
+ local subtest
+
+ if [[ "${#subtests[@]}" -eq 0 ]]; then
+ echo >&2 "No subtests found for file $0"
+ exit 1
+ fi
+
+ if [[ "$#" -eq 0 ]]; then
+ echo >&2 "No signals to propagate were specified"
+ exit 1
+ fi
+
+ trap_with_sig handle_signal "$@"
+
+ for subtest in "${subtests[@]}"; do
+ : "--- $subtest BEGIN ---"
+ "./$subtest" &
+ CHILD_PID=$!
+ wait_harder "$CHILD_PID" && PASSED_TESTS+=("$subtest") || FAILED_TESTS+=("$subtest")
+ : "--- $subtest END ---"
+ done
+
+ show_summary
+}
+
+run_subtests() {
+ local subtests=("${0%.sh}".*.sh)
+ local subtest
+
+ if [[ "${#subtests[@]}" -eq 0 ]]; then
+ echo >&2 "No subtests found for file $0"
+ exit 1
+ fi
+
+ for subtest in "${subtests[@]}"; do
+ : "--- $subtest BEGIN ---"
+ "./$subtest" && PASSED_TESTS+=("$subtest") || FAILED_TESTS+=("$subtest")
+ : "--- $subtest END ---"
+ done
+
+ show_summary
+}
+
+show_summary() {(
+ set +x
+
+ if [[ ${#PASSED_TESTS[@]} -eq 0 && ${#FAILED_TESTS[@]} -eq 0 ]]; then
+ echo >&2 "No tests were executed, this is most likely an error"
+ exit 1
+ fi
+
+ printf "PASSED TESTS: %3d:\n" "${#PASSED_TESTS[@]}"
+ echo "------------------"
+ for t in "${PASSED_TESTS[@]}"; do
+ echo "$t"
+ done
+
+ if [[ "${#FAILED_TESTS[@]}" -ne 0 ]]; then
+ printf "FAILED TESTS: %3d:\n" "${#FAILED_TESTS[@]}"
+ echo "------------------"
+ for t in "${FAILED_TESTS[@]}"; do
+ echo "$t"
+ done
+ fi
+
+ [[ "${#FAILED_TESTS[@]}" -eq 0 ]]
+)}
diff --git a/test/units/testsuite-07.sh b/test/units/testsuite-07.sh
index 8c004a72e5..58d278e1f1 100755
--- a/test/units/testsuite-07.sh
+++ b/test/units/testsuite-07.sh
@@ -3,16 +3,16 @@
set -eux
set -o pipefail
+# shellcheck source=test/units/test-control.sh
+. "$(dirname "$0")"/test-control.sh
+
: >/failed
# Issue: https://github.com/systemd/systemd/issues/2730
# See TEST-07-PID1/test.sh for the first "half" of the test
mountpoint /issue2730
-for script in "${0%.sh}".*.sh; do
- echo "Running $script"
- "./$script"
-done
+run_subtests
touch /testok
rm /failed
diff --git a/test/units/testsuite-17.sh b/test/units/testsuite-17.sh
index b389875ef1..72040f69d8 100755
--- a/test/units/testsuite-17.sh
+++ b/test/units/testsuite-17.sh
@@ -3,13 +3,14 @@
set -eux
set -o pipefail
+# shellcheck source=test/units/test-control.sh
+. "$(dirname "$0")"/test-control.sh
+
: >/failed
udevadm settle
-for t in "${0%.sh}".*.sh; do
- echo "Running $t"; ./"$t"
-done
+run_subtests
touch /testok
rm /failed
diff --git a/test/units/testsuite-22.sh b/test/units/testsuite-22.sh
index 43823f1d46..5a07e7b78c 100755
--- a/test/units/testsuite-22.sh
+++ b/test/units/testsuite-22.sh
@@ -3,11 +3,12 @@
set -eux
set -o pipefail
+# shellcheck source=test/units/test-control.sh
+. "$(dirname "$0")"/test-control.sh
+
: >/failed
-for t in "${0%.sh}".*.sh; do
- echo "Running $t"; ./"$t"
-done
+run_subtests
touch /testok
rm /failed
diff --git a/test/units/testsuite-23.sh b/test/units/testsuite-23.sh
index a6b8da34c9..3be645e20a 100755
--- a/test/units/testsuite-23.sh
+++ b/test/units/testsuite-23.sh
@@ -5,62 +5,11 @@ set -o pipefail
: >/failed
-declare -i CHILD_PID=0
+# shellcheck source=test/units/test-control.sh
+. "$(dirname "$0")"/test-control.sh
-# Note: all the signal shenanigans are necessary for the Upholds= tests
-
-# Like trap, but passes the signal name as the first argument
-trap_with_sig() {
- local fun="${1:?}"
- local sig
- shift
-
- for sig in "$@"; do
- # shellcheck disable=SC2064
- trap "$fun $sig" "$sig"
- done
-}
-
-# Propagate the caught signal to the current child process
-handle_signal() {
- local sig="${1:?}"
-
- if [[ $CHILD_PID -gt 0 ]]; then
- echo "Propagating signal $sig to child process $CHILD_PID"
- kill -s "$sig" "$CHILD_PID"
- fi
-}
-
-# In order to make the handle_signal() stuff above work, we have to execute
-# each script asynchronously, since bash won't execute traps until the currently
-# executed command finishes. This, however, introduces another issue regarding
-# how bash's wait works. Quoting:
-#
-# When bash is waiting for an asynchronous command via the wait builtin,
-# the reception of a signal for which a trap has been set will cause the wait
-# builtin to return immediately with an exit status greater than 128,
-# immediately after which the trap is executed.
-#
-# In other words - every time we propagate a signal, wait returns with
-# 128+signal, so we have to wait again - repeat until the process dies.
-wait_harder() {
- local pid="${1:?}"
-
- while kill -0 "$pid"; do
- wait "$pid" || :
- done
-
- wait "$pid"
-}
-
-trap_with_sig handle_signal SIGUSR1 SIGUSR2 SIGRTMIN+1
-
-for script in "${0%.sh}".*.sh; do
- echo "Running $script"
- "./$script" &
- CHILD_PID=$!
- wait_harder "$CHILD_PID"
-done
+# Note: the signal shenanigans are necessary for the Upholds= tests
+run_subtests_with_signals SIGUSR1 SIGUSR2 SIGRTMIN+1
touch /testok
rm /failed
diff --git a/test/units/testsuite-74.sh b/test/units/testsuite-74.sh
index 13c767e490..5a07e7b78c 100755
--- a/test/units/testsuite-74.sh
+++ b/test/units/testsuite-74.sh
@@ -3,12 +3,12 @@
set -eux
set -o pipefail
+# shellcheck source=test/units/test-control.sh
+. "$(dirname "$0")"/test-control.sh
+
: >/failed
-for script in "${0%.sh}".*.sh; do
- echo "Running $script"
- "./$script"
-done
+run_subtests
touch /testok
rm /failed

View File

@ -0,0 +1,208 @@
From c8d082c62be5c14f74270739144bc8e49360ba47 Mon Sep 17 00:00:00 2001
From: Yu Watanabe <watanabe.yu+github@gmail.com>
Date: Thu, 25 May 2023 06:48:16 +0900
Subject: [PATCH] test: add tests for JoinsNamespaceOf=
To illustrate the current behavior of the dependency.
(cherry picked from commit 8493a82d0bd5915eb951512cff5e570c43386283)
Related: #2213521
---
.../testsuite-23-joins-namespace-of-1.service | 7 +++++
.../testsuite-23-joins-namespace-of-2.service | 10 ++++++
.../testsuite-23-joins-namespace-of-3.service | 10 ++++++
.../testsuite-23-joins-namespace-of-4.service | 10 ++++++
.../testsuite-23-joins-namespace-of-5.service | 6 ++++
.../testsuite-23-joins-namespace-of-6.service | 10 ++++++
.../testsuite-23-joins-namespace-of-7.service | 11 +++++++
.../testsuite-23-joins-namespace-of-8.service | 9 ++++++
.../testsuite-23-joins-namespace-of-9.service | 11 +++++++
test/units/testsuite-23.JoinsNamespaceOf.sh | 31 +++++++++++++++++++
10 files changed, 115 insertions(+)
create mode 100644 test/testsuite-23.units/testsuite-23-joins-namespace-of-1.service
create mode 100644 test/testsuite-23.units/testsuite-23-joins-namespace-of-2.service
create mode 100644 test/testsuite-23.units/testsuite-23-joins-namespace-of-3.service
create mode 100644 test/testsuite-23.units/testsuite-23-joins-namespace-of-4.service
create mode 100644 test/testsuite-23.units/testsuite-23-joins-namespace-of-5.service
create mode 100644 test/testsuite-23.units/testsuite-23-joins-namespace-of-6.service
create mode 100644 test/testsuite-23.units/testsuite-23-joins-namespace-of-7.service
create mode 100644 test/testsuite-23.units/testsuite-23-joins-namespace-of-8.service
create mode 100644 test/testsuite-23.units/testsuite-23-joins-namespace-of-9.service
create mode 100755 test/units/testsuite-23.JoinsNamespaceOf.sh
diff --git a/test/testsuite-23.units/testsuite-23-joins-namespace-of-1.service b/test/testsuite-23.units/testsuite-23-joins-namespace-of-1.service
new file mode 100644
index 0000000000..9919a9fa82
--- /dev/null
+++ b/test/testsuite-23.units/testsuite-23-joins-namespace-of-1.service
@@ -0,0 +1,7 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
+[Service]
+Type=notify
+NotifyAccess=all
+MountAPIVFS=yes
+PrivateTmp=yes
+ExecStart=/bin/bash -c 'touch /tmp/shared-private-file && systemd-notify --ready && sleep infinity'
diff --git a/test/testsuite-23.units/testsuite-23-joins-namespace-of-2.service b/test/testsuite-23.units/testsuite-23-joins-namespace-of-2.service
new file mode 100644
index 0000000000..36b4c272fd
--- /dev/null
+++ b/test/testsuite-23.units/testsuite-23-joins-namespace-of-2.service
@@ -0,0 +1,10 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
+[Unit]
+JoinsNamespaceOf=testsuite-23-joins-namespace-of-1.service
+
+[Service]
+Type=oneshot
+MountAPIVFS=yes
+PrivateTmp=yes
+ExecStart=test -e /tmp/shared-private-file
+ExecStart=touch /tmp/hoge
diff --git a/test/testsuite-23.units/testsuite-23-joins-namespace-of-3.service b/test/testsuite-23.units/testsuite-23-joins-namespace-of-3.service
new file mode 100644
index 0000000000..9094445020
--- /dev/null
+++ b/test/testsuite-23.units/testsuite-23-joins-namespace-of-3.service
@@ -0,0 +1,10 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
+[Unit]
+JoinsNamespaceOf=testsuite-23-joins-namespace-of-1.service
+
+[Service]
+Type=oneshot
+MountAPIVFS=yes
+PrivateTmp=yes
+ExecStart=test -e /tmp/shared-private-file
+ExecStart=test -e /tmp/hoge
diff --git a/test/testsuite-23.units/testsuite-23-joins-namespace-of-4.service b/test/testsuite-23.units/testsuite-23-joins-namespace-of-4.service
new file mode 100644
index 0000000000..5e823a1778
--- /dev/null
+++ b/test/testsuite-23.units/testsuite-23-joins-namespace-of-4.service
@@ -0,0 +1,10 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
+[Unit]
+JoinsNamespaceOf=testsuite-23-joins-namespace-of-5.service
+
+[Service]
+Type=notify
+NotifyAccess=all
+MountAPIVFS=yes
+PrivateTmp=yes
+ExecStart=/bin/bash -c 'touch /tmp/shared-private-file && systemd-notify --ready && sleep infinity'
diff --git a/test/testsuite-23.units/testsuite-23-joins-namespace-of-5.service b/test/testsuite-23.units/testsuite-23-joins-namespace-of-5.service
new file mode 100644
index 0000000000..80594ccba2
--- /dev/null
+++ b/test/testsuite-23.units/testsuite-23-joins-namespace-of-5.service
@@ -0,0 +1,6 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
+[Service]
+Type=oneshot
+MountAPIVFS=yes
+PrivateTmp=yes
+ExecStart=test ! -e /tmp/shared-private-file
diff --git a/test/testsuite-23.units/testsuite-23-joins-namespace-of-6.service b/test/testsuite-23.units/testsuite-23-joins-namespace-of-6.service
new file mode 100644
index 0000000000..bbbfd7c67d
--- /dev/null
+++ b/test/testsuite-23.units/testsuite-23-joins-namespace-of-6.service
@@ -0,0 +1,10 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
+[Unit]
+JoinsNamespaceOf=testsuite-23-joins-namespace-of-8.service
+
+[Service]
+Type=notify
+NotifyAccess=all
+MountAPIVFS=yes
+PrivateTmp=yes
+ExecStart=/bin/bash -c 'touch /tmp/shared-private-file-x && systemd-notify --ready && sleep infinity'
diff --git a/test/testsuite-23.units/testsuite-23-joins-namespace-of-7.service b/test/testsuite-23.units/testsuite-23-joins-namespace-of-7.service
new file mode 100644
index 0000000000..6c7bbdb097
--- /dev/null
+++ b/test/testsuite-23.units/testsuite-23-joins-namespace-of-7.service
@@ -0,0 +1,11 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
+[Unit]
+JoinsNamespaceOf=testsuite-23-joins-namespace-of-8.service
+
+[Service]
+Type=oneshot
+MountAPIVFS=yes
+PrivateTmp=yes
+ExecStart=test ! -e /tmp/shared-private-file-x
+ExecStart=test ! -e /tmp/shared-private-file-y
+ExecStart=touch /tmp/hoge
diff --git a/test/testsuite-23.units/testsuite-23-joins-namespace-of-8.service b/test/testsuite-23.units/testsuite-23-joins-namespace-of-8.service
new file mode 100644
index 0000000000..f3ec0668de
--- /dev/null
+++ b/test/testsuite-23.units/testsuite-23-joins-namespace-of-8.service
@@ -0,0 +1,9 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
+[Service]
+Type=notify
+NotifyAccess=all
+MountAPIVFS=yes
+PrivateTmp=yes
+ExecStartPre=test ! -e /tmp/shared-private-file-x
+ExecStartPre=test ! -e /tmp/hoge
+ExecStart=/bin/bash -c 'touch /tmp/shared-private-file-y && systemd-notify --ready && sleep infinity'
diff --git a/test/testsuite-23.units/testsuite-23-joins-namespace-of-9.service b/test/testsuite-23.units/testsuite-23-joins-namespace-of-9.service
new file mode 100644
index 0000000000..01de7f9054
--- /dev/null
+++ b/test/testsuite-23.units/testsuite-23-joins-namespace-of-9.service
@@ -0,0 +1,11 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
+[Unit]
+JoinsNamespaceOf=testsuite-23-joins-namespace-of-8.service
+
+[Service]
+Type=oneshot
+MountAPIVFS=yes
+PrivateTmp=yes
+ExecStart=test ! -e /tmp/shared-private-file-x
+ExecStart=test -e /tmp/shared-private-file-y
+ExecStart=test ! -e /tmp/hoge
diff --git a/test/units/testsuite-23.JoinsNamespaceOf.sh b/test/units/testsuite-23.JoinsNamespaceOf.sh
new file mode 100755
index 0000000000..68ba465072
--- /dev/null
+++ b/test/units/testsuite-23.JoinsNamespaceOf.sh
@@ -0,0 +1,31 @@
+#!/usr/bin/env bash
+# SPDX-License-Identifier: LGPL-2.1-or-later
+
+set -eux
+set -o pipefail
+
+# Test JoinsNamespaceOf= with PrivateTmp=yes
+
+systemd-analyze log-level debug
+systemd-analyze log-target journal
+
+# simple case
+systemctl start testsuite-23-joins-namespace-of-1.service
+systemctl start testsuite-23-joins-namespace-of-2.service
+systemctl start testsuite-23-joins-namespace-of-3.service
+systemctl stop testsuite-23-joins-namespace-of-1.service
+
+# inverse dependency
+systemctl start testsuite-23-joins-namespace-of-4.service
+systemctl start testsuite-23-joins-namespace-of-5.service
+systemctl stop testsuite-23-joins-namespace-of-4.service
+
+# transitive dependency
+systemctl start testsuite-23-joins-namespace-of-6.service
+systemctl start testsuite-23-joins-namespace-of-7.service
+systemctl start testsuite-23-joins-namespace-of-8.service
+systemctl start testsuite-23-joins-namespace-of-9.service
+systemctl stop testsuite-23-joins-namespace-of-6.service
+systemctl stop testsuite-23-joins-namespace-of-8.service
+
+systemd-analyze log-level info

View File

@ -0,0 +1,24 @@
From bb6af3b07f6ef66d193bdee0345cc2b3a782e8b3 Mon Sep 17 00:00:00 2001
From: Yu Watanabe <watanabe.yu+github@gmail.com>
Date: Tue, 23 May 2023 06:03:52 +0900
Subject: [PATCH] core/unit: drop doubled empty line
(cherry picked from commit 512df9de23890fcfd5fdbfe633250fe848195d4b)
Related: #2213521
---
src/core/unit.c | 1 -
1 file changed, 1 deletion(-)
diff --git a/src/core/unit.c b/src/core/unit.c
index 0d1a590a3f..0faf66413b 100644
--- a/src/core/unit.c
+++ b/src/core/unit.c
@@ -987,7 +987,6 @@ static int unit_per_dependency_type_hashmap_update(
if (r < 0)
return r;
-
return 1;
}

View File

@ -0,0 +1,113 @@
From 096cfb2903d48b115e417010767388ff5c49b282 Mon Sep 17 00:00:00 2001
From: Yu Watanabe <watanabe.yu+github@gmail.com>
Date: Tue, 23 May 2023 06:36:44 +0900
Subject: [PATCH] core/unit: make JoinsNamespaceOf= implies the inverse
dependency
Previously, even if a.service has JoinsNamespaceOf=b.service, the
inverse direction of reference was not introduced.
Hence, a.service is started earlier than b.service, the namespace will
not shared with b.service.
Also, even if a.service had the reference to b.service, b.service did not.
If b.service is freed earlier, then unit_clear_dependencies() does not clear
the reference from a to b, and will cause use-after-free on unit_free() for
a.service.
Let's make JoinsNamespaceOf=b.service in a.service implies the inverse
dependency, i.e. JoinsNamespaceOf=a.service for b.service. Then, we can safely
free b.service.
(cherry picked from commit a60f96fcf55c3452e5b13d6daec537af1909eda3)
Related: #2213521
---
man/systemd.unit.xml | 12 +++++++-----
src/core/unit.c | 11 +++++------
.../testsuite-23-joins-namespace-of-5.service | 2 +-
.../testsuite-23-joins-namespace-of-8.service | 2 +-
.../testsuite-23-joins-namespace-of-9.service | 2 +-
5 files changed, 15 insertions(+), 14 deletions(-)
diff --git a/man/systemd.unit.xml b/man/systemd.unit.xml
index 8e1a3464df..d41909bcc6 100644
--- a/man/systemd.unit.xml
+++ b/man/systemd.unit.xml
@@ -858,16 +858,18 @@
<term><varname>JoinsNamespaceOf=</varname></term>
<listitem><para>For units that start processes (such as service units), lists one or more other units
- whose network and/or temporary file namespace to join. This only applies to unit types which support
- the <varname>PrivateNetwork=</varname>, <varname>NetworkNamespacePath=</varname>,
+ whose network and/or temporary file namespace to join. If this is specified on a unit (say, a.service
+ has <varname>JoinsNamespaceOf=b.service</varname>), then this the inverse dependency
+ (<varname>JoinsNamespaceOf=a.service</varname> for b.service) is implied. This only applies to unit
+ types which support the <varname>PrivateNetwork=</varname>, <varname>NetworkNamespacePath=</varname>,
<varname>PrivateIPC=</varname>, <varname>IPCNamespacePath=</varname>, and
<varname>PrivateTmp=</varname> directives (see
<citerefentry><refentrytitle>systemd.exec</refentrytitle><manvolnum>5</manvolnum></citerefentry> for
details). If a unit that has this setting set is started, its processes will see the same
<filename>/tmp/</filename>, <filename>/var/tmp/</filename>, IPC namespace and network namespace as
- one listed unit that is started. If multiple listed units are already started, it is not defined
- which namespace is joined. Note that this setting only has an effect if
- <varname>PrivateNetwork=</varname>/<varname>NetworkNamespacePath=</varname>,
+ one listed unit that is started. If multiple listed units are already started and these do not share
+ their namespace, then it is not defined which namespace is joined. Note that this setting only has an
+ effect if <varname>PrivateNetwork=</varname>/<varname>NetworkNamespacePath=</varname>,
<varname>PrivateIPC=</varname>/<varname>IPCNamespacePath=</varname> and/or
<varname>PrivateTmp=</varname> is enabled for both the unit that joins the namespace and the unit
whose namespace is joined.</para></listitem>
diff --git a/src/core/unit.c b/src/core/unit.c
index 0faf66413b..8b66139ad9 100644
--- a/src/core/unit.c
+++ b/src/core/unit.c
@@ -3108,12 +3108,11 @@ int unit_add_dependency(
return r;
notify = r > 0;
- if (inverse_table[d] != _UNIT_DEPENDENCY_INVALID && inverse_table[d] != d) {
- r = unit_add_dependency_hashmap(&other->dependencies, inverse_table[d], u, 0, mask);
- if (r < 0)
- return r;
- notify_other = r > 0;
- }
+ assert(inverse_table[d] >= 0 && inverse_table[d] < _UNIT_DEPENDENCY_MAX);
+ r = unit_add_dependency_hashmap(&other->dependencies, inverse_table[d], u, 0, mask);
+ if (r < 0)
+ return r;
+ notify_other = r > 0;
if (add_reference) {
r = unit_add_dependency_hashmap(&u->dependencies, UNIT_REFERENCES, other, mask, 0);
diff --git a/test/testsuite-23.units/testsuite-23-joins-namespace-of-5.service b/test/testsuite-23.units/testsuite-23-joins-namespace-of-5.service
index 80594ccba2..c3d316bfa2 100644
--- a/test/testsuite-23.units/testsuite-23-joins-namespace-of-5.service
+++ b/test/testsuite-23.units/testsuite-23-joins-namespace-of-5.service
@@ -3,4 +3,4 @@
Type=oneshot
MountAPIVFS=yes
PrivateTmp=yes
-ExecStart=test ! -e /tmp/shared-private-file
+ExecStart=test -e /tmp/shared-private-file
diff --git a/test/testsuite-23.units/testsuite-23-joins-namespace-of-8.service b/test/testsuite-23.units/testsuite-23-joins-namespace-of-8.service
index f3ec0668de..42053b99f8 100644
--- a/test/testsuite-23.units/testsuite-23-joins-namespace-of-8.service
+++ b/test/testsuite-23.units/testsuite-23-joins-namespace-of-8.service
@@ -4,6 +4,6 @@ Type=notify
NotifyAccess=all
MountAPIVFS=yes
PrivateTmp=yes
-ExecStartPre=test ! -e /tmp/shared-private-file-x
+ExecStartPre=test -e /tmp/shared-private-file-x
ExecStartPre=test ! -e /tmp/hoge
ExecStart=/bin/bash -c 'touch /tmp/shared-private-file-y && systemd-notify --ready && sleep infinity'
diff --git a/test/testsuite-23.units/testsuite-23-joins-namespace-of-9.service b/test/testsuite-23.units/testsuite-23-joins-namespace-of-9.service
index 01de7f9054..a50a7fcdc2 100644
--- a/test/testsuite-23.units/testsuite-23-joins-namespace-of-9.service
+++ b/test/testsuite-23.units/testsuite-23-joins-namespace-of-9.service
@@ -7,5 +7,5 @@ Type=oneshot
MountAPIVFS=yes
PrivateTmp=yes
ExecStart=test ! -e /tmp/shared-private-file-x
-ExecStart=test -e /tmp/shared-private-file-y
+ExecStart=test ! -e /tmp/shared-private-file-y
ExecStart=test ! -e /tmp/hoge

View File

@ -0,0 +1,140 @@
From 7ce47c0fc8b624d08f238f5ef364275ec8a791f5 Mon Sep 17 00:00:00 2001
From: Yu Watanabe <watanabe.yu+github@gmail.com>
Date: Thu, 25 May 2023 18:08:37 +0900
Subject: [PATCH] core/unit: search shared namespace in transitive relation of
JoinsNamespaceOf=
Previously, dependency chain of JoinsNamespaceOf= did not work, e.g.
- a.service has JoinsNamespaceOf=b.service
- b.service has JoinsNamespaceOf=c.service
if, first c.service, next a.service, finally b.service is started,
then a.service is not joined to the namespace of c.service. And, as
mentioned in the document, the namespace used by b.service is not
deterministic.
This makes when searching exsiting namespace to be joined, all units in
the transitive dependency of JoinsNamespaceOf= are checked.
(cherry picked from commit 83123a44989c095f9b7a89841db9917417fc451a)
Related: #2213521
---
src/core/unit.c | 36 ++++++++++++++++++-
src/core/unit.h | 1 +
.../testsuite-23-joins-namespace-of-7.service | 2 +-
.../testsuite-23-joins-namespace-of-8.service | 2 +-
.../testsuite-23-joins-namespace-of-9.service | 6 ++--
5 files changed, 41 insertions(+), 6 deletions(-)
diff --git a/src/core/unit.c b/src/core/unit.c
index 8b66139ad9..6acc63e091 100644
--- a/src/core/unit.c
+++ b/src/core/unit.c
@@ -4718,6 +4718,7 @@ int unit_require_mounts_for(Unit *u, const char *path, UnitDependencyMask mask)
}
int unit_setup_exec_runtime(Unit *u) {
+ _cleanup_set_free_ Set *units = NULL;
ExecRuntime **rt;
size_t offset;
Unit *other;
@@ -4731,9 +4732,15 @@ int unit_setup_exec_runtime(Unit *u) {
if (*rt)
return 0;
+ r = unit_get_transitive_dependency_set(u, UNIT_ATOM_JOINS_NAMESPACE_OF, &units);
+ if (r < 0)
+ return r;
+
/* Try to get it from somebody else */
- UNIT_FOREACH_DEPENDENCY(other, u, UNIT_ATOM_JOINS_NAMESPACE_OF) {
+ SET_FOREACH(other, units) {
r = exec_runtime_acquire(u->manager, NULL, other->id, false, rt);
+ if (r < 0)
+ return r;
if (r == 1)
return 1;
}
@@ -5921,6 +5928,33 @@ int unit_get_dependency_array(const Unit *u, UnitDependencyAtom atom, Unit ***re
return (int) n;
}
+int unit_get_transitive_dependency_set(Unit *u, UnitDependencyAtom atom, Set **ret) {
+ _cleanup_set_free_ Set *units = NULL, *queue = NULL;
+ Unit *other;
+ int r;
+
+ assert(u);
+ assert(ret);
+
+ /* Similar to unit_get_dependency_array(), but also search the same dependency in other units. */
+
+ do {
+ UNIT_FOREACH_DEPENDENCY(other, u, atom) {
+ r = set_ensure_put(&units, NULL, other);
+ if (r < 0)
+ return r;
+ if (r == 0)
+ continue;
+ r = set_ensure_put(&queue, NULL, other);
+ if (r < 0)
+ return r;
+ }
+ } while ((u = set_steal_first(queue)));
+
+ *ret = TAKE_PTR(units);
+ return 0;
+}
+
const ActivationDetailsVTable * const activation_details_vtable[_UNIT_TYPE_MAX] = {
[UNIT_PATH] = &activation_details_path_vtable,
[UNIT_TIMER] = &activation_details_timer_vtable,
diff --git a/src/core/unit.h b/src/core/unit.h
index 3bc7de3d1c..e79b5322b4 100644
--- a/src/core/unit.h
+++ b/src/core/unit.h
@@ -805,6 +805,7 @@ static inline const UnitVTable* UNIT_VTABLE(const Unit *u) {
Unit* unit_has_dependency(const Unit *u, UnitDependencyAtom atom, Unit *other);
int unit_get_dependency_array(const Unit *u, UnitDependencyAtom atom, Unit ***ret_array);
+int unit_get_transitive_dependency_set(Unit *u, UnitDependencyAtom atom, Set **ret);
static inline Hashmap* unit_get_dependencies(Unit *u, UnitDependency d) {
return hashmap_get(u->dependencies, UNIT_DEPENDENCY_TO_PTR(d));
diff --git a/test/testsuite-23.units/testsuite-23-joins-namespace-of-7.service b/test/testsuite-23.units/testsuite-23-joins-namespace-of-7.service
index 6c7bbdb097..60c083a3f4 100644
--- a/test/testsuite-23.units/testsuite-23-joins-namespace-of-7.service
+++ b/test/testsuite-23.units/testsuite-23-joins-namespace-of-7.service
@@ -6,6 +6,6 @@ JoinsNamespaceOf=testsuite-23-joins-namespace-of-8.service
Type=oneshot
MountAPIVFS=yes
PrivateTmp=yes
-ExecStart=test ! -e /tmp/shared-private-file-x
+ExecStart=test -e /tmp/shared-private-file-x
ExecStart=test ! -e /tmp/shared-private-file-y
ExecStart=touch /tmp/hoge
diff --git a/test/testsuite-23.units/testsuite-23-joins-namespace-of-8.service b/test/testsuite-23.units/testsuite-23-joins-namespace-of-8.service
index 42053b99f8..dac1cea7bd 100644
--- a/test/testsuite-23.units/testsuite-23-joins-namespace-of-8.service
+++ b/test/testsuite-23.units/testsuite-23-joins-namespace-of-8.service
@@ -5,5 +5,5 @@ NotifyAccess=all
MountAPIVFS=yes
PrivateTmp=yes
ExecStartPre=test -e /tmp/shared-private-file-x
-ExecStartPre=test ! -e /tmp/hoge
+ExecStartPre=test -e /tmp/hoge
ExecStart=/bin/bash -c 'touch /tmp/shared-private-file-y && systemd-notify --ready && sleep infinity'
diff --git a/test/testsuite-23.units/testsuite-23-joins-namespace-of-9.service b/test/testsuite-23.units/testsuite-23-joins-namespace-of-9.service
index a50a7fcdc2..6c64873b24 100644
--- a/test/testsuite-23.units/testsuite-23-joins-namespace-of-9.service
+++ b/test/testsuite-23.units/testsuite-23-joins-namespace-of-9.service
@@ -6,6 +6,6 @@ JoinsNamespaceOf=testsuite-23-joins-namespace-of-8.service
Type=oneshot
MountAPIVFS=yes
PrivateTmp=yes
-ExecStart=test ! -e /tmp/shared-private-file-x
-ExecStart=test ! -e /tmp/shared-private-file-y
-ExecStart=test ! -e /tmp/hoge
+ExecStart=test -e /tmp/shared-private-file-x
+ExecStart=test -e /tmp/shared-private-file-y
+ExecStart=test -e /tmp/hoge

View File

@ -0,0 +1,236 @@
From 08c48bbe717a0be0f8c41a4652473d8483e0fbde Mon Sep 17 00:00:00 2001
From: Yu Watanabe <watanabe.yu+github@gmail.com>
Date: Tue, 23 May 2023 17:49:16 +0900
Subject: [PATCH] core/unit: update bidirectional dependency simultaneously
Previously, if unit_add_dependency_hashmap() failed, then a
one-directional unit dependency reference might be created, and
triggeres use-after-free. See issue #27742 for more details.
This makes unit dependency always bidirectional, and cleanly revert
partial update on failure.
Fixes #27742.
(cherry picked from commit 831108245eb757f41fe0ebbccf1b42c9dd0ce297)
Resolves: #2213521
---
src/core/unit.c | 164 ++++++++++++++++++++++++++++++------------------
1 file changed, 103 insertions(+), 61 deletions(-)
diff --git a/src/core/unit.c b/src/core/unit.c
index 6acc63e091..438213a47a 100644
--- a/src/core/unit.c
+++ b/src/core/unit.c
@@ -990,46 +990,6 @@ static int unit_per_dependency_type_hashmap_update(
return 1;
}
-static int unit_add_dependency_hashmap(
- Hashmap **dependencies,
- UnitDependency d,
- Unit *other,
- UnitDependencyMask origin_mask,
- UnitDependencyMask destination_mask) {
-
- Hashmap *per_type;
- int r;
-
- assert(dependencies);
- assert(other);
- assert(origin_mask < _UNIT_DEPENDENCY_MASK_FULL);
- assert(destination_mask < _UNIT_DEPENDENCY_MASK_FULL);
- assert(origin_mask > 0 || destination_mask > 0);
-
- /* Ensure the top-level dependency hashmap exists that maps UnitDependency → Hashmap(Unit* →
- * UnitDependencyInfo) */
- r = hashmap_ensure_allocated(dependencies, NULL);
- if (r < 0)
- return r;
-
- /* Acquire the inner hashmap, that maps Unit* → UnitDependencyInfo, for the specified dependency
- * type, and if it's missing allocate it and insert it. */
- per_type = hashmap_get(*dependencies, UNIT_DEPENDENCY_TO_PTR(d));
- if (!per_type) {
- per_type = hashmap_new(NULL);
- if (!per_type)
- return -ENOMEM;
-
- r = hashmap_put(*dependencies, UNIT_DEPENDENCY_TO_PTR(d), per_type);
- if (r < 0) {
- hashmap_free(per_type);
- return r;
- }
- }
-
- return unit_per_dependency_type_hashmap_update(per_type, other, origin_mask, destination_mask);
-}
-
static void unit_merge_dependencies(Unit *u, Unit *other) {
Hashmap *deps;
void *dt; /* Actually of type UnitDependency, except that we don't bother casting it here,
@@ -3002,11 +2962,38 @@ bool unit_job_is_applicable(Unit *u, JobType j) {
}
}
-int unit_add_dependency(
+static Hashmap *unit_get_dependency_hashmap_per_type(Unit *u, UnitDependency d) {
+ Hashmap *deps;
+
+ assert(u);
+ assert(d >= 0 && d < _UNIT_DEPENDENCY_MAX);
+
+ deps = hashmap_get(u->dependencies, UNIT_DEPENDENCY_TO_PTR(d));
+ if (!deps) {
+ _cleanup_hashmap_free_ Hashmap *h = NULL;
+
+ h = hashmap_new(NULL);
+ if (!h)
+ return NULL;
+
+ if (hashmap_ensure_put(&u->dependencies, NULL, UNIT_DEPENDENCY_TO_PTR(d), h) < 0)
+ return NULL;
+
+ deps = TAKE_PTR(h);
+ }
+
+ return deps;
+}
+
+typedef enum NotifyDependencyFlags {
+ NOTIFY_DEPENDENCY_UPDATE_FROM = 1 << 0,
+ NOTIFY_DEPENDENCY_UPDATE_TO = 1 << 1,
+} NotifyDependencyFlags;
+
+static int unit_add_dependency_impl(
Unit *u,
UnitDependency d,
Unit *other,
- bool add_reference,
UnitDependencyMask mask) {
static const UnitDependency inverse_table[_UNIT_DEPENDENCY_MAX] = {
@@ -3042,12 +3029,78 @@ int unit_add_dependency(
[UNIT_IN_SLICE] = UNIT_SLICE_OF,
[UNIT_SLICE_OF] = UNIT_IN_SLICE,
};
+
+ Hashmap *u_deps, *other_deps;
+ UnitDependencyInfo u_info, u_info_old, other_info, other_info_old;
+ NotifyDependencyFlags flags = 0;
+ int r;
+
+ assert(u);
+ assert(other);
+ assert(d >= 0 && d < _UNIT_DEPENDENCY_MAX);
+ assert(inverse_table[d] >= 0 && inverse_table[d] < _UNIT_DEPENDENCY_MAX);
+ assert(mask > 0 && mask < _UNIT_DEPENDENCY_MASK_FULL);
+
+ /* Ensure the following two hashmaps for each unit exist:
+ * - the top-level dependency hashmap that maps UnitDependency → Hashmap(Unit* → UnitDependencyInfo),
+ * - the inner hashmap, that maps Unit* → UnitDependencyInfo, for the specified dependency type. */
+ u_deps = unit_get_dependency_hashmap_per_type(u, d);
+ if (!u_deps)
+ return -ENOMEM;
+
+ other_deps = unit_get_dependency_hashmap_per_type(other, inverse_table[d]);
+ if (!other_deps)
+ return -ENOMEM;
+
+ /* Save the original dependency info. */
+ u_info.data = u_info_old.data = hashmap_get(u_deps, other);
+ other_info.data = other_info_old.data = hashmap_get(other_deps, u);
+
+ /* Update dependency info. */
+ u_info.origin_mask |= mask;
+ other_info.destination_mask |= mask;
+
+ /* Save updated dependency info. */
+ if (u_info.data != u_info_old.data) {
+ r = hashmap_replace(u_deps, other, u_info.data);
+ if (r < 0)
+ return r;
+
+ flags = NOTIFY_DEPENDENCY_UPDATE_FROM;
+ }
+
+ if (other_info.data != other_info_old.data) {
+ r = hashmap_replace(other_deps, u, other_info.data);
+ if (r < 0) {
+ if (u_info.data != u_info_old.data) {
+ /* Restore the old dependency. */
+ if (u_info_old.data)
+ (void) hashmap_update(u_deps, other, u_info_old.data);
+ else
+ hashmap_remove(u_deps, other);
+ }
+ return r;
+ }
+
+ flags |= NOTIFY_DEPENDENCY_UPDATE_TO;
+ }
+
+ return flags;
+}
+
+int unit_add_dependency(
+ Unit *u,
+ UnitDependency d,
+ Unit *other,
+ bool add_reference,
+ UnitDependencyMask mask) {
+
UnitDependencyAtom a;
int r;
/* Helper to know whether sending a notification is necessary or not: if the dependency is already
* there, no need to notify! */
- bool notify, notify_other = false;
+ NotifyDependencyFlags notify_flags;
assert(u);
assert(d >= 0 && d < _UNIT_DEPENDENCY_MAX);
@@ -3103,35 +3156,24 @@ int unit_add_dependency(
return log_unit_error_errno(u, SYNTHETIC_ERRNO(EINVAL),
"Requested dependency SliceOf=%s refused (%s is not a cgroup unit).", other->id, other->id);
- r = unit_add_dependency_hashmap(&u->dependencies, d, other, mask, 0);
- if (r < 0)
- return r;
- notify = r > 0;
-
- assert(inverse_table[d] >= 0 && inverse_table[d] < _UNIT_DEPENDENCY_MAX);
- r = unit_add_dependency_hashmap(&other->dependencies, inverse_table[d], u, 0, mask);
+ r = unit_add_dependency_impl(u, d, other, mask);
if (r < 0)
return r;
- notify_other = r > 0;
+ notify_flags = r;
if (add_reference) {
- r = unit_add_dependency_hashmap(&u->dependencies, UNIT_REFERENCES, other, mask, 0);
- if (r < 0)
- return r;
- notify = notify || r > 0;
-
- r = unit_add_dependency_hashmap(&other->dependencies, UNIT_REFERENCED_BY, u, 0, mask);
+ r = unit_add_dependency_impl(u, UNIT_REFERENCES, other, mask);
if (r < 0)
return r;
- notify_other = notify_other || r > 0;
+ notify_flags |= r;
}
- if (notify)
+ if (FLAGS_SET(notify_flags, NOTIFY_DEPENDENCY_UPDATE_FROM))
unit_add_to_dbus_queue(u);
- if (notify_other)
+ if (FLAGS_SET(notify_flags, NOTIFY_DEPENDENCY_UPDATE_TO))
unit_add_to_dbus_queue(other);
- return notify || notify_other;
+ return notify_flags != 0;
}
int unit_add_two_dependencies(Unit *u, UnitDependency d, UnitDependency e, Unit *other, bool add_reference, UnitDependencyMask mask) {

View File

@ -0,0 +1,29 @@
From e5b40438543324acd504bbcf5d9b4cd71b46d931 Mon Sep 17 00:00:00 2001
From: Lennart Poettering <lennart@poettering.net>
Date: Wed, 4 Jan 2023 16:29:34 +0100
Subject: [PATCH] resolvectl: fix type of ifindex D-Bus field, and make sure to
initialize to zero in all code paths
(cherry picked from commit a5e6c8498ca375bafa865d5e46fa95e9313871ad)
Related: #2161260
---
src/resolve/resolvectl.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/src/resolve/resolvectl.c b/src/resolve/resolvectl.c
index c52773508f..2fd6c4914f 100644
--- a/src/resolve/resolvectl.c
+++ b/src/resolve/resolvectl.c
@@ -1208,9 +1208,10 @@ static int reset_server_features(int argc, char **argv, void *userdata) {
static int read_dns_server_one(sd_bus_message *m, bool with_ifindex, bool extended, char **ret) {
_cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
_cleanup_free_ char *pretty = NULL;
- int ifindex, family, r, k;
union in_addr_union a;
const char *name = NULL;
+ int32_t ifindex = 0;
+ int family, r, k;
uint16_t port = 0;
assert(m);

View File

@ -0,0 +1,100 @@
From cae4b6abbd66770e6761f6bd47f85cf271cc870b Mon Sep 17 00:00:00 2001
From: Lennart Poettering <lennart@poettering.net>
Date: Wed, 4 Jan 2023 16:32:51 +0100
Subject: [PATCH] resolved: add some line-breaks/comments
Let's make this a bit more readable.
(cherry picked from commit 5707fb12978e6818afba379b803da307050f541b)
Related: #2161260
---
src/resolve/resolvectl.c | 20 +++++++++++++++-----
src/resolve/resolved-bus.c | 12 ++++++++++--
2 files changed, 25 insertions(+), 7 deletions(-)
diff --git a/src/resolve/resolvectl.c b/src/resolve/resolvectl.c
index 2fd6c4914f..1cb16430e4 100644
--- a/src/resolve/resolvectl.c
+++ b/src/resolve/resolvectl.c
@@ -1217,7 +1217,11 @@ static int read_dns_server_one(sd_bus_message *m, bool with_ifindex, bool extend
assert(m);
assert(ret);
- r = sd_bus_message_enter_container(m, 'r', with_ifindex ? (extended ? "iiayqs" : "iiay") : (extended ? "iayqs" : "iay"));
+ r = sd_bus_message_enter_container(
+ m,
+ 'r',
+ with_ifindex ? (extended ? "iiayqs" : "iiay") :
+ (extended ? "iayqs" : "iay"));
if (r <= 0)
return r;
@@ -1262,7 +1266,6 @@ static int read_dns_server_one(sd_bus_message *m, bool with_ifindex, bool extend
return r;
*ret = TAKE_PTR(pretty);
-
return 1;
}
@@ -1731,7 +1734,14 @@ static int status_ifindex(sd_bus *bus, int ifindex, const char *name, StatusMode
return 0;
}
-static int map_global_dns_servers_internal(sd_bus *bus, const char *member, sd_bus_message *m, sd_bus_error *error, void *userdata, bool extended) {
+static int map_global_dns_servers_internal(
+ sd_bus *bus,
+ const char *member,
+ sd_bus_message *m,
+ sd_bus_error *error,
+ void *userdata,
+ bool extended) {
+
char ***l = ASSERT_PTR(userdata);
int r;
@@ -1768,11 +1778,11 @@ static int map_global_dns_servers_internal(sd_bus *bus, const char *member, sd_b
}
static int map_global_dns_servers(sd_bus *bus, const char *member, sd_bus_message *m, sd_bus_error *error, void *userdata) {
- return map_global_dns_servers_internal(bus, member, m, error, userdata, false);
+ return map_global_dns_servers_internal(bus, member, m, error, userdata, /* extended= */ false);
}
static int map_global_dns_servers_ex(sd_bus *bus, const char *member, sd_bus_message *m, sd_bus_error *error, void *userdata) {
- return map_global_dns_servers_internal(bus, member, m, error, userdata, true);
+ return map_global_dns_servers_internal(bus, member, m, error, userdata, /* extended= */ true);
}
static int map_global_current_dns_server(sd_bus *bus, const char *member, sd_bus_message *m, sd_bus_error *error, void *userdata) {
diff --git a/src/resolve/resolved-bus.c b/src/resolve/resolved-bus.c
index 2e3941da39..c818e1d52f 100644
--- a/src/resolve/resolved-bus.c
+++ b/src/resolve/resolved-bus.c
@@ -1371,7 +1371,11 @@ static int bus_method_resolve_service(sd_bus_message *message, void *userdata, s
return 1;
}
-int bus_dns_server_append(sd_bus_message *reply, DnsServer *s, bool with_ifindex, bool extended) {
+int bus_dns_server_append(
+ sd_bus_message *reply,
+ DnsServer *s,
+ bool with_ifindex, /* include "ifindex" field */
+ bool extended) { /* also include port number and server name */
int r;
assert(reply);
@@ -1390,7 +1394,11 @@ int bus_dns_server_append(sd_bus_message *reply, DnsServer *s, bool with_ifindex
}
}
- r = sd_bus_message_open_container(reply, 'r', with_ifindex ? (extended ? "iiayqs" : "iiay") : (extended ? "iayqs" : "iay"));
+ r = sd_bus_message_open_container(
+ reply,
+ 'r',
+ with_ifindex ? (extended ? "iiayqs" : "iiay") :
+ (extended ? "iayqs" : "iay"));
if (r < 0)
return r;

View File

@ -0,0 +1,122 @@
From 94bcb43713447d943c5123dc8baac96c4e37bb26 Mon Sep 17 00:00:00 2001
From: Lennart Poettering <lennart@poettering.net>
Date: Wed, 4 Jan 2023 16:36:15 +0100
Subject: [PATCH] resolvectl: don't filter loopback DNS server from global DNS
server list
"resolvectl status" shows per-link DNS servers separately from global
ones. When querying the global list, it will contain both per-link and
global servers however. Thus, to not show duplicate info we filter all
entries that actually have a non-zero ifindex set (under the assumption
that that's a per-link server).
This doesn't work if people configured 127.0.0.1 as global server
though, as we'll add ifindex 1 to it since
6e32414a66ff8dbcef233981a7066684d903ee9f unconditionally even for global
servers.
Let's address that by excluding entries with ifindex 1 from suppression.
This is safe as resolved ignores loopback ifaces, hence never will have
per-link servers on ifindex 1.
Note that this splits up the "with_ifindex" parameter into a second
parameter "only_global", since they semantically do two different
things. One controls whether we shall expect/parse an ifindex dbus
field. The other controls whether we shall filter all ifindex values set
!= 0. These are effectively always used in conjunction hence making them
the same actually worked. However this is utterly confusing I think,
which as I guess is resulting in the confusion around #25796 (which
removes the whole check)
(cherry picked from commit 889a1b9f4e799b31f1be06db74708aa8beb70829)
Resolves: #2161260
---
src/resolve/resolvectl.c | 30 +++++++++++++++---------------
1 file changed, 15 insertions(+), 15 deletions(-)
diff --git a/src/resolve/resolvectl.c b/src/resolve/resolvectl.c
index 1cb16430e4..e22e06d054 100644
--- a/src/resolve/resolvectl.c
+++ b/src/resolve/resolvectl.c
@@ -1205,7 +1205,13 @@ static int reset_server_features(int argc, char **argv, void *userdata) {
return 0;
}
-static int read_dns_server_one(sd_bus_message *m, bool with_ifindex, bool extended, char **ret) {
+static int read_dns_server_one(
+ sd_bus_message *m,
+ bool with_ifindex, /* read "ifindex" reply that also carries an interface index */
+ bool extended, /* read "extended" reply, i.e. with port number and server name */
+ bool only_global, /* suppress entries with an (non-loopback) ifindex set (i.e. which are specific to some interface) */
+ char **ret) {
+
_cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
_cleanup_free_ char *pretty = NULL;
union in_addr_union a;
@@ -1255,8 +1261,8 @@ static int read_dns_server_one(sd_bus_message *m, bool with_ifindex, bool extend
return 1;
}
- if (with_ifindex && ifindex != 0) {
- /* only show the global ones here */
+ if (only_global && ifindex > 0 && ifindex != LOOPBACK_IFINDEX) {
+ /* This one has an (non-loopback) ifindex set, and we were told to suppress those. Hence do so. */
*ret = NULL;
return 1;
}
@@ -1284,7 +1290,7 @@ static int map_link_dns_servers_internal(sd_bus *bus, const char *member, sd_bus
for (;;) {
_cleanup_free_ char *pretty = NULL;
- r = read_dns_server_one(m, false, extended, &pretty);
+ r = read_dns_server_one(m, /* with_ifindex= */ false, extended, /* only_global= */ false, &pretty);
if (r < 0)
return r;
if (r == 0)
@@ -1317,14 +1323,14 @@ static int map_link_current_dns_server(sd_bus *bus, const char *member, sd_bus_m
assert(m);
assert(userdata);
- return read_dns_server_one(m, false, false, userdata);
+ return read_dns_server_one(m, /* with_ifindex= */ false, /* extended= */ false, /* only_global= */ false, userdata);
}
static int map_link_current_dns_server_ex(sd_bus *bus, const char *member, sd_bus_message *m, sd_bus_error *error, void *userdata) {
assert(m);
assert(userdata);
- return read_dns_server_one(m, false, true, userdata);
+ return read_dns_server_one(m, /* with_ifindex= */ false, /* extended= */ true, /* only_global= */ false, userdata);
}
static int read_domain_one(sd_bus_message *m, bool with_ifindex, char **ret) {
@@ -1756,7 +1762,7 @@ static int map_global_dns_servers_internal(
for (;;) {
_cleanup_free_ char *pretty = NULL;
- r = read_dns_server_one(m, true, extended, &pretty);
+ r = read_dns_server_one(m, /* with_ifindex= */ true, extended, /* only_global= */ true, &pretty);
if (r < 0)
return r;
if (r == 0)
@@ -1786,17 +1792,11 @@ static int map_global_dns_servers_ex(sd_bus *bus, const char *member, sd_bus_mes
}
static int map_global_current_dns_server(sd_bus *bus, const char *member, sd_bus_message *m, sd_bus_error *error, void *userdata) {
- assert(m);
- assert(userdata);
-
- return read_dns_server_one(m, true, false, userdata);
+ return read_dns_server_one(m, /* with_ifindex= */ true, /* extended= */ false, /* only_global= */ true, userdata);
}
static int map_global_current_dns_server_ex(sd_bus *bus, const char *member, sd_bus_message *m, sd_bus_error *error, void *userdata) {
- assert(m);
- assert(userdata);
-
- return read_dns_server_one(m, true, true, userdata);
+ return read_dns_server_one(m, /* with_ifindex= */ true, /* extended= */ true, /* only_global= */ true, userdata);
}
static int map_global_domains(sd_bus *bus, const char *member, sd_bus_message *m, sd_bus_error *error, void *userdata) {

View File

@ -0,0 +1,75 @@
From 1d569167f70a59d4e1b44378fc29f282e98f9148 Mon Sep 17 00:00:00 2001
From: Lennart Poettering <lennart@poettering.net>
Date: Tue, 17 Jan 2023 20:12:30 +0100
Subject: [PATCH] blockdev-util: add simple wrapper around BLKSSZGET
Just adds some typesafety and generates an error if the field is not
initialized in the block device yet.
(cherry picked from commit 65046b92dcdc017f34e170a0e0f46ffc80b1dcdc)
Related: #2170883
---
src/shared/blockdev-util.c | 15 +++++++++++++++
src/shared/blockdev-util.h | 2 ++
src/shared/loop-util.c | 12 ++++++------
3 files changed, 23 insertions(+), 6 deletions(-)
diff --git a/src/shared/blockdev-util.c b/src/shared/blockdev-util.c
index 72fad160ed..27d3d075d9 100644
--- a/src/shared/blockdev-util.c
+++ b/src/shared/blockdev-util.c
@@ -788,3 +788,18 @@ int blockdev_reread_partition_table(sd_device *dev) {
return 0;
}
+
+int blockdev_get_sector_size(int fd, uint32_t *ret) {
+ int ssz = 0;
+
+ assert(fd >= 0);
+ assert(ret);
+
+ if (ioctl(fd, BLKSSZGET, &ssz) < 0)
+ return -errno;
+ if (ssz <= 0) /* make sure the field is initialized */
+ return log_debug_errno(SYNTHETIC_ERRNO(EIO), "Block device reported invalid sector size %i.", ssz);
+
+ *ret = ssz;
+ return 0;
+}
diff --git a/src/shared/blockdev-util.h b/src/shared/blockdev-util.h
index b2c14102ae..5b27d23e8a 100644
--- a/src/shared/blockdev-util.h
+++ b/src/shared/blockdev-util.h
@@ -54,3 +54,5 @@ int partition_enumerator_new(sd_device *dev, sd_device_enumerator **ret);
int block_device_remove_all_partitions(sd_device *dev, int fd);
int block_device_has_partitions(sd_device *dev);
int blockdev_reread_partition_table(sd_device *dev);
+
+int blockdev_get_sector_size(int fd, uint32_t *ret);
diff --git a/src/shared/loop-util.c b/src/shared/loop-util.c
index fb7e80b1b5..1c66fb779d 100644
--- a/src/shared/loop-util.c
+++ b/src/shared/loop-util.c
@@ -124,14 +124,14 @@ static int loop_configure_verify(int fd, const struct loop_config *c) {
assert(c);
if (c->block_size != 0) {
- int z;
+ uint32_t ssz;
- if (ioctl(fd, BLKSSZGET, &z) < 0)
- return -errno;
+ r = blockdev_get_sector_size(fd, &ssz);
+ if (r < 0)
+ return r;
- assert(z >= 0);
- if ((uint32_t) z != c->block_size)
- log_debug("LOOP_CONFIGURE didn't honour requested block size %u, got %i instead. Ignoring.", c->block_size, z);
+ if (ssz != c->block_size)
+ log_debug("LOOP_CONFIGURE didn't honour requested block size %" PRIu32 ", got %" PRIu32 " instead. Ignoring.", c->block_size, ssz);
}
if (c->info.lo_sizelimit != 0) {

View File

@ -0,0 +1,62 @@
From 7c3d3404ded062e3bff9384cf2c009dcc71d2dba Mon Sep 17 00:00:00 2001
From: Lennart Poettering <lennart@poettering.net>
Date: Tue, 17 Jan 2023 15:49:31 +0100
Subject: [PATCH] loop-util: insist on setting the sector size correctly
If we attach a disk image to a loopback device the sector size of the
image must match the one of the loopback device, hence be more careful
here.
(cherry picked from commit 1163ddb386ef46f63942171e6eab0ca64eb818e4)
Related: #2170883
---
src/shared/loop-util.c | 20 +++++++++++++++++++-
1 file changed, 19 insertions(+), 1 deletion(-)
diff --git a/src/shared/loop-util.c b/src/shared/loop-util.c
index 1c66fb779d..4e0b06ad83 100644
--- a/src/shared/loop-util.c
+++ b/src/shared/loop-util.c
@@ -130,8 +130,10 @@ static int loop_configure_verify(int fd, const struct loop_config *c) {
if (r < 0)
return r;
- if (ssz != c->block_size)
+ if (ssz != c->block_size) {
log_debug("LOOP_CONFIGURE didn't honour requested block size %" PRIu32 ", got %" PRIu32 " instead. Ignoring.", c->block_size, ssz);
+ broken = true;
+ }
}
if (c->info.lo_sizelimit != 0) {
@@ -172,6 +174,7 @@ static int loop_configure_verify(int fd, const struct loop_config *c) {
static int loop_configure_fallback(int fd, const struct loop_config *c) {
struct loop_info64 info_copy;
+ int r;
assert(fd >= 0);
assert(c);
@@ -219,6 +222,21 @@ static int loop_configure_fallback(int fd, const struct loop_config *c) {
if (ioctl(fd, BLKFLSBUF, 0) < 0)
log_debug_errno(errno, "Failed to issue BLKFLSBUF ioctl, ignoring: %m");
+ /* If a block size is requested then try to configure it. If that doesn't work, ignore errors, but
+ * afterwards, let's validate what is in effect, and if it doesn't match what we want, fail */
+ if (c->block_size != 0) {
+ uint32_t ssz;
+
+ if (ioctl(fd, LOOP_SET_BLOCK_SIZE, (unsigned long) c->block_size) < 0)
+ log_debug_errno(errno, "Failed to set sector size, ignoring: %m");
+
+ r = blockdev_get_sector_size(fd, &ssz);
+ if (r < 0)
+ return log_debug_errno(r, "Failed to read sector size: %m");
+ if (ssz != c->block_size)
+ return log_debug_errno(SYNTHETIC_ERRNO(EIO), "Sector size of loopback device doesn't match what we requested, refusing.");
+ }
+
/* LO_FLAGS_DIRECT_IO is a flags we need to configure via explicit ioctls. */
if (FLAGS_SET(c->info.lo_flags, LO_FLAGS_DIRECT_IO))
if (ioctl(fd, LOOP_SET_DIRECT_IO, 1UL) < 0)

View File

@ -0,0 +1,134 @@
From f86ffe711102f53b793c6529c82017b31389cbab Mon Sep 17 00:00:00 2001
From: Lennart Poettering <lennart@poettering.net>
Date: Tue, 17 Jan 2023 18:06:05 +0100
Subject: [PATCH] dissect-image: add probe_sector_size() helper for detecting
sector size of a GPT disk image
When we operate with DDIs with sector sizes != 512 we need to configure
the loopback device to match it, otherwise the image and the kernel
block device will disagree what things are.
Let's add a prober that tries to determine the sector size of a GPT DDI.
It does this by looking for the GPT partition table header at the
various byte offsets they must be located on, given a specific sector
size. It will try sector size 512, 1024, 2048 and 4096. Of these only
the 512 and 4096 really make sense IRL I guess, but let's be thorough.
(cherry picked from commit 05c4c59ff127668ddaa85f0a9fd67cee3c41ce00)
Related: #2170883
---
src/shared/dissect-image.c | 82 ++++++++++++++++++++++++++++++++++++++
src/shared/dissect-image.h | 2 +
2 files changed, 84 insertions(+)
diff --git a/src/shared/dissect-image.c b/src/shared/dissect-image.c
index 462ee4b3e8..5c7d26d6cf 100644
--- a/src/shared/dissect-image.c
+++ b/src/shared/dissect-image.c
@@ -61,6 +61,7 @@
#include "raw-clone.h"
#include "resize-fs.h"
#include "signal-util.h"
+#include "sparse-endian.h"
#include "stat-util.h"
#include "stdio-util.h"
#include "string-table.h"
@@ -74,6 +75,87 @@
/* how many times to wait for the device nodes to appear */
#define N_DEVICE_NODE_LIST_ATTEMPTS 10
+int probe_sector_size(int fd, uint32_t *ret) {
+
+ struct gpt_header {
+ char signature[8];
+ le32_t revision;
+ le32_t header_size;
+ le32_t crc32;
+ le32_t reserved;
+ le64_t my_lba;
+ le64_t alternate_lba;
+ le64_t first_usable_lba;
+ le64_t last_usable_lba;
+ sd_id128_t disk_guid;
+ le64_t partition_entry_lba;
+ le32_t number_of_partition_entries;
+ le32_t size_of_partition_entry;
+ le32_t partition_entry_array_crc32;
+ } _packed_;
+
+ /* Disk images might be for 512B or for 4096 sector sizes, let's try to auto-detect that by searching
+ * for the GPT headers at the relevant byte offsets */
+
+ assert_cc(sizeof(struct gpt_header) == 92);
+
+ /* We expect a sector size in the range 512…4096. The GPT header is located in the second
+ * sector. Hence it could be at byte 512 at the earliest, and at byte 4096 at the latest. And we must
+ * read with granularity of the largest sector size we care about. Which means 8K. */
+ uint8_t sectors[2 * 4096];
+ uint32_t found = 0;
+ ssize_t n;
+
+ assert(fd >= 0);
+ assert(ret);
+
+ n = pread(fd, sectors, sizeof(sectors), 0);
+ if (n < 0)
+ return -errno;
+ if (n != sizeof(sectors)) /* too short? */
+ goto not_found;
+
+ /* Let's see if we find the GPT partition header with various expected sector sizes */
+ for (uint32_t sz = 512; sz <= 4096; sz <<= 1) {
+ struct gpt_header *p;
+
+ assert(sizeof(sectors) >= sz * 2);
+ p = (struct gpt_header*) (sectors + sz);
+
+ if (memcmp(p->signature, (const char[8]) { 'E', 'F', 'I', ' ', 'P', 'A', 'R', 'T' }, 8) != 0)
+ continue;
+
+ if (le32toh(p->revision) != UINT32_C(0x00010000)) /* the only known revision of the spec: 1.0 */
+ continue;
+
+ if (le32toh(p->header_size) < sizeof(struct gpt_header))
+ continue;
+
+ if (le32toh(p->header_size) > 4096) /* larger than a sector? something is off… */
+ continue;
+
+ if (le64toh(p->my_lba) != 1) /* this sector must claim to be at sector offset 1 */
+ continue;
+
+ if (found != 0)
+ return log_debug_errno(SYNTHETIC_ERRNO(ENOTUNIQ),
+ "Detected valid partition table at offsets matching multiple sector sizes, refusing.");
+
+ found = sz;
+ }
+
+ if (found != 0) {
+ log_debug("Determined sector size %" PRIu32 " based on discovered partition table.", found);
+ *ret = found;
+ return 1; /* indicate we *did* find it */
+ }
+
+not_found:
+ log_debug("Couldn't find any partition table to derive sector size of.");
+ *ret = 512; /* pick the traditional default */
+ return 0; /* indicate we didn't find it */
+}
+
int probe_filesystem_full(int fd, const char *path, char **ret_fstype) {
/* Try to find device content type and return it in *ret_fstype. If nothing is found,
* 0/NULL will be returned. -EUCLEAN will be returned for ambiguous results, and an
diff --git a/src/shared/dissect-image.h b/src/shared/dissect-image.h
index 631d4c7a04..2c7b84f15b 100644
--- a/src/shared/dissect-image.h
+++ b/src/shared/dissect-image.h
@@ -315,3 +315,5 @@ bool dissected_image_verity_sig_ready(const DissectedImage *image, PartitionDesi
int mount_image_privately_interactively(const char *path, DissectImageFlags flags, char **ret_directory, LoopDevice **ret_loop_device);
int verity_dissect_and_mount(int src_fd, const char *src, const char *dest, const MountOptions *options, const char *required_host_os_release_id, const char *required_host_os_release_version_id, const char *required_host_os_release_sysext_level, const char *required_sysext_scope);
+
+int probe_sector_size(int fd, uint32_t *ret);

View File

@ -0,0 +1,370 @@
From 108dd8030923d241ebc3ac9a58099a020996f911 Mon Sep 17 00:00:00 2001
From: Lennart Poettering <lennart@poettering.net>
Date: Tue, 17 Jan 2023 18:50:59 +0100
Subject: [PATCH] loop-util: always tell kernel explicitly about loopback
sector size
Let's not leave the sector size unspecified: either set a user supplied
value, or auto-detect the right size by probing the disk image
accordingly.
(cherry picked from commit 22ee78a8987f29e7f837efab86ed090ab78c1170)
Related: #2170883
---
src/core/namespace.c | 1 +
src/dissect/dissect.c | 1 +
src/home/homework-luks.c | 20 +++++++++++--
src/nspawn/nspawn.c | 1 +
src/portable/portable.c | 2 +-
src/shared/discover-image.c | 2 +-
src/shared/dissect-image.c | 15 +++++++++-
src/shared/dissect-image.h | 2 ++
src/shared/loop-util.c | 60 +++++++++++++++++++++++++++++++++----
src/shared/loop-util.h | 5 ++--
src/sysext/sysext.c | 1 +
11 files changed, 98 insertions(+), 12 deletions(-)
diff --git a/src/core/namespace.c b/src/core/namespace.c
index 96b05303eb..8fd7ed0269 100644
--- a/src/core/namespace.c
+++ b/src/core/namespace.c
@@ -2093,6 +2093,7 @@ int setup_namespace(
r = loop_device_make_by_path(
root_image,
FLAGS_SET(dissect_image_flags, DISSECT_IMAGE_DEVICE_READ_ONLY) ? O_RDONLY : -1 /* < 0 means writable if possible, read-only as fallback */,
+ /* sector_size= */ UINT32_MAX,
FLAGS_SET(dissect_image_flags, DISSECT_IMAGE_NO_PARTITION_TABLE) ? 0 : LO_FLAGS_PARTSCAN,
LOCK_SH,
&loop_device);
diff --git a/src/dissect/dissect.c b/src/dissect/dissect.c
index c1d731dc82..b7c47561bc 100644
--- a/src/dissect/dissect.c
+++ b/src/dissect/dissect.c
@@ -931,6 +931,7 @@ static int run(int argc, char *argv[]) {
r = loop_device_make_by_path(
arg_image,
FLAGS_SET(arg_flags, DISSECT_IMAGE_DEVICE_READ_ONLY) ? O_RDONLY : O_RDWR,
+ /* sector_size= */ UINT32_MAX,
FLAGS_SET(arg_flags, DISSECT_IMAGE_NO_PARTITION_TABLE) ? 0 : LO_FLAGS_PARTSCAN,
LOCK_SH,
&d);
diff --git a/src/home/homework-luks.c b/src/home/homework-luks.c
index 5e1d5bbd65..53fa61b103 100644
--- a/src/home/homework-luks.c
+++ b/src/home/homework-luks.c
@@ -1378,7 +1378,15 @@ int home_setup_luks(
return r;
}
- r = loop_device_make(setup->image_fd, O_RDWR, offset, size, user_record_luks_sector_size(h), 0, LOCK_UN, &setup->loop);
+ r = loop_device_make(
+ setup->image_fd,
+ O_RDWR,
+ offset,
+ size,
+ h->luks_sector_size == UINT64_MAX ? UINT32_MAX : user_record_luks_sector_size(h), /* if sector size is not specified, select UINT32_MAX, i.e. auto-probe */
+ /* loop_flags= */ 0,
+ LOCK_UN,
+ &setup->loop);
if (r == -ENOENT) {
log_error_errno(r, "Loopback block device support is not available on this system.");
return -ENOLINK; /* make recognizable */
@@ -2302,7 +2310,15 @@ int home_create_luks(
log_info("Writing of partition table completed.");
- r = loop_device_make(setup->image_fd, O_RDWR, partition_offset, partition_size, user_record_luks_sector_size(h), 0, LOCK_EX, &setup->loop);
+ r = loop_device_make(
+ setup->image_fd,
+ O_RDWR,
+ partition_offset,
+ partition_size,
+ user_record_luks_sector_size(h),
+ 0,
+ LOCK_EX,
+ &setup->loop);
if (r < 0) {
if (r == -ENOENT) { /* this means /dev/loop-control doesn't exist, i.e. we are in a container
* or similar and loopback bock devices are not available, return a
diff --git a/src/nspawn/nspawn.c b/src/nspawn/nspawn.c
index 57723aa3cf..cdebe8e5c4 100644
--- a/src/nspawn/nspawn.c
+++ b/src/nspawn/nspawn.c
@@ -5737,6 +5737,7 @@ static int run(int argc, char *argv[]) {
r = loop_device_make_by_path(
arg_image,
arg_read_only ? O_RDONLY : O_RDWR,
+ /* sector_size= */ UINT32_MAX,
FLAGS_SET(dissect_image_flags, DISSECT_IMAGE_NO_PARTITION_TABLE) ? 0 : LO_FLAGS_PARTSCAN,
LOCK_SH,
&loop);
diff --git a/src/portable/portable.c b/src/portable/portable.c
index 570751f05b..8a989ed526 100644
--- a/src/portable/portable.c
+++ b/src/portable/portable.c
@@ -335,7 +335,7 @@ static int portable_extract_by_path(
assert(path);
- r = loop_device_make_by_path(path, O_RDONLY, LO_FLAGS_PARTSCAN, LOCK_SH, &d);
+ r = loop_device_make_by_path(path, O_RDONLY, /* sector_size= */ UINT32_MAX, LO_FLAGS_PARTSCAN, LOCK_SH, &d);
if (r == -EISDIR) {
_cleanup_free_ char *image_name = NULL;
diff --git a/src/shared/discover-image.c b/src/shared/discover-image.c
index 5d740de266..0488e215fd 100644
--- a/src/shared/discover-image.c
+++ b/src/shared/discover-image.c
@@ -1192,7 +1192,7 @@ int image_read_metadata(Image *i) {
_cleanup_(loop_device_unrefp) LoopDevice *d = NULL;
_cleanup_(dissected_image_unrefp) DissectedImage *m = NULL;
- r = loop_device_make_by_path(i->path, O_RDONLY, LO_FLAGS_PARTSCAN, LOCK_SH, &d);
+ r = loop_device_make_by_path(i->path, O_RDONLY, /* sector_size= */ UINT32_MAX, LO_FLAGS_PARTSCAN, LOCK_SH, &d);
if (r < 0)
return r;
diff --git a/src/shared/dissect-image.c b/src/shared/dissect-image.c
index 5c7d26d6cf..d2abd5a087 100644
--- a/src/shared/dissect-image.c
+++ b/src/shared/dissect-image.c
@@ -443,6 +443,7 @@ static int dissect_image(
assert(!verity || verity->root_hash_sig || verity->root_hash_sig_size == 0);
assert(!verity || (verity->root_hash || !verity->root_hash_sig));
assert(!((flags & DISSECT_IMAGE_GPT_ONLY) && (flags & DISSECT_IMAGE_NO_PARTITION_TABLE)));
+ assert(m->sector_size > 0);
/* Probes a disk image, and returns information about what it found in *ret.
*
@@ -489,6 +490,11 @@ static int dissect_image(
if (r != 0)
return errno_or_else(ENOMEM);
+ errno = 0;
+ r = blkid_probe_set_sectorsize(b, m->sector_size);
+ if (r != 0)
+ return errno_or_else(EIO);
+
if ((flags & DISSECT_IMAGE_GPT_ONLY) == 0) {
/* Look for file system superblocks, unless we only shall look for GPT partition tables */
blkid_probe_enable_superblocks(b, 1);
@@ -1328,6 +1334,10 @@ int dissect_image_file(
if (r < 0)
return r;
+ r = probe_sector_size(fd, &m->sector_size);
+ if (r < 0)
+ return r;
+
r = dissect_image(m, fd, path, verity, mount_options, flags);
if (r < 0)
return r;
@@ -3116,6 +3126,7 @@ int dissect_loop_device(
return r;
m->loop = loop_device_ref(loop);
+ m->sector_size = m->loop->sector_size;
r = dissect_image(m, loop->fd, loop->node, verity, mount_options, flags);
if (r < 0)
@@ -3295,6 +3306,7 @@ int mount_image_privately_interactively(
r = loop_device_make_by_path(
image,
FLAGS_SET(flags, DISSECT_IMAGE_DEVICE_READ_ONLY) ? O_RDONLY : O_RDWR,
+ /* sector_size= */ UINT32_MAX,
FLAGS_SET(flags, DISSECT_IMAGE_NO_PARTITION_TABLE) ? 0 : LO_FLAGS_PARTSCAN,
LOCK_SH,
&d);
@@ -3414,7 +3426,8 @@ int verity_dissect_and_mount(
* accepted by LOOP_CONFIGURE, so just let loop_device_make_by_path reopen it as a regular FD. */
r = loop_device_make_by_path(
src_fd >= 0 ? FORMAT_PROC_FD_PATH(src_fd) : src,
- -1,
+ /* open_flags= */ -1,
+ /* sector_size= */ UINT32_MAX,
verity.data_path ? 0 : LO_FLAGS_PARTSCAN,
LOCK_SH,
&loop_device);
diff --git a/src/shared/dissect-image.h b/src/shared/dissect-image.h
index 2c7b84f15b..becd69c26e 100644
--- a/src/shared/dissect-image.h
+++ b/src/shared/dissect-image.h
@@ -231,6 +231,8 @@ struct DissectedImage {
DissectedPartition partitions[_PARTITION_DESIGNATOR_MAX];
DecryptedImage *decrypted_image;
+ uint32_t sector_size;
+
/* Meta information extracted from /etc/os-release and similar */
char *image_name;
char *hostname;
diff --git a/src/shared/loop-util.c b/src/shared/loop-util.c
index 4e0b06ad83..468ef7a40a 100644
--- a/src/shared/loop-util.c
+++ b/src/shared/loop-util.c
@@ -19,6 +19,7 @@
#include "blockdev-util.h"
#include "device-util.h"
#include "devnum-util.h"
+#include "dissect-image.h"
#include "env-util.h"
#include "errno-util.h"
#include "fd-util.h"
@@ -408,6 +409,7 @@ static int loop_configure(
.diskseq = diskseq,
.uevent_seqnum_not_before = seqnum,
.timestamp_not_before = timestamp,
+ .sector_size = c->block_size,
};
*ret = TAKE_PTR(d);
@@ -420,7 +422,7 @@ static int loop_device_make_internal(
int open_flags,
uint64_t offset,
uint64_t size,
- uint32_t block_size,
+ uint32_t sector_size,
uint32_t loop_flags,
int lock_op,
LoopDevice **ret) {
@@ -491,9 +493,50 @@ static int loop_device_make_internal(
if (control < 0)
return -errno;
+ if (sector_size == 0)
+ /* If no sector size is specified, default to the classic default */
+ sector_size = 512;
+ else if (sector_size == UINT32_MAX) {
+
+ if (S_ISBLK(st.st_mode))
+ /* If the sector size is specified as UINT32_MAX we'll propagate the sector size of
+ * the underlying block device. */
+ r = blockdev_get_sector_size(fd, &sector_size);
+ else {
+ _cleanup_close_ int non_direct_io_fd = -1;
+ int probe_fd;
+
+ assert(S_ISREG(st.st_mode));
+
+ /* If sector size is specified as UINT32_MAX, we'll try to probe the right sector
+ * size of the image in question by looking for the GPT partition header at various
+ * offsets. This of course only works if the image already has a disk label.
+ *
+ * So here we actually want to read the file contents ourselves. This is quite likely
+ * not going to work if we managed to enable O_DIRECT, because in such a case there
+ * are some pretty strict alignment requirements to offset, size and target, but
+ * there's no way to query what alignment specifically is actually required. Hence,
+ * let's avoid the mess, and temporarily open an fd without O_DIRECT for the probing
+ * logic. */
+
+ if (FLAGS_SET(loop_flags, LO_FLAGS_DIRECT_IO)) {
+ non_direct_io_fd = fd_reopen(fd, O_RDONLY|O_CLOEXEC|O_NONBLOCK);
+ if (non_direct_io_fd < 0)
+ return non_direct_io_fd;
+
+ probe_fd = non_direct_io_fd;
+ } else
+ probe_fd = fd;
+
+ r = probe_sector_size(probe_fd, &sector_size);
+ }
+ if (r < 0)
+ return r;
+ }
+
config = (struct loop_config) {
.fd = fd,
- .block_size = block_size,
+ .block_size = sector_size,
.info = {
/* Use the specified flags, but configure the read-only flag from the open flags, and force autoclear */
.lo_flags = (loop_flags & ~LO_FLAGS_READ_ONLY) | ((open_flags & O_ACCMODE) == O_RDONLY ? LO_FLAGS_READ_ONLY : 0) | LO_FLAGS_AUTOCLEAR,
@@ -577,7 +620,7 @@ int loop_device_make(
int open_flags,
uint64_t offset,
uint64_t size,
- uint32_t block_size,
+ uint32_t sector_size,
uint32_t loop_flags,
int lock_op,
LoopDevice **ret) {
@@ -591,7 +634,7 @@ int loop_device_make(
open_flags,
offset,
size,
- block_size,
+ sector_size,
loop_flags_mangle(loop_flags),
lock_op,
ret);
@@ -600,6 +643,7 @@ int loop_device_make(
int loop_device_make_by_path(
const char *path,
int open_flags,
+ uint32_t sector_size,
uint32_t loop_flags,
int lock_op,
LoopDevice **ret) {
@@ -655,7 +699,7 @@ int loop_device_make_by_path(
direct ? "enabled" : "disabled",
direct != (direct_flags != 0) ? " (O_DIRECT was requested but not supported)" : "");
- return loop_device_make_internal(path, fd, open_flags, 0, 0, 0, loop_flags, lock_op, ret);
+ return loop_device_make_internal(path, fd, open_flags, 0, 0, sector_size, loop_flags, lock_op, ret);
}
static LoopDevice* loop_device_free(LoopDevice *d) {
@@ -797,6 +841,11 @@ int loop_device_open(
if (r < 0 && r != -EOPNOTSUPP)
return r;
+ uint32_t sector_size;
+ r = blockdev_get_sector_size(fd, &sector_size);
+ if (r < 0)
+ return r;
+
r = sd_device_get_devnum(dev, &devnum);
if (r < 0)
return r;
@@ -826,6 +875,7 @@ int loop_device_open(
.diskseq = diskseq,
.uevent_seqnum_not_before = UINT64_MAX,
.timestamp_not_before = USEC_INFINITY,
+ .sector_size = sector_size,
};
*ret = d;
diff --git a/src/shared/loop-util.h b/src/shared/loop-util.h
index e466a5abbd..6e838cef0b 100644
--- a/src/shared/loop-util.h
+++ b/src/shared/loop-util.h
@@ -23,13 +23,14 @@ struct LoopDevice {
uint64_t diskseq; /* Block device sequence number, monothonically incremented by the kernel on create/attach, or 0 if we don't know */
uint64_t uevent_seqnum_not_before; /* uevent sequm right before we attached the loopback device, or UINT64_MAX if we don't know */
usec_t timestamp_not_before; /* CLOCK_MONOTONIC timestamp taken immediately before attaching the loopback device, or USEC_INFINITY if we don't know */
+ uint32_t sector_size;
};
/* Returns true if LoopDevice object is not actually a loopback device but some other block device we just wrap */
#define LOOP_DEVICE_IS_FOREIGN(d) ((d)->nr < 0)
-int loop_device_make(int fd, int open_flags, uint64_t offset, uint64_t size, uint32_t block_size, uint32_t loop_flags, int lock_op, LoopDevice **ret);
-int loop_device_make_by_path(const char *path, int open_flags, uint32_t loop_flags, int lock_op, LoopDevice **ret);
+int loop_device_make(int fd, int open_flags, uint64_t offset, uint64_t size, uint32_t sector_size, uint32_t loop_flags, int lock_op, LoopDevice **ret);
+int loop_device_make_by_path(const char *path, int open_flags, uint32_t sector_size, uint32_t loop_flags, int lock_op, LoopDevice **ret);
int loop_device_open(sd_device *dev, int open_flags, int lock_op, LoopDevice **ret);
int loop_device_open_from_fd(int fd, int open_flags, int lock_op, LoopDevice **ret);
int loop_device_open_from_path(const char *path, int open_flags, int lock_op, LoopDevice **ret);
diff --git a/src/sysext/sysext.c b/src/sysext/sysext.c
index c57293b0e5..e1bf627528 100644
--- a/src/sysext/sysext.c
+++ b/src/sysext/sysext.c
@@ -534,6 +534,7 @@ static int merge_subprocess(Hashmap *images, const char *workspace) {
r = loop_device_make_by_path(
img->path,
O_RDONLY,
+ /* sector_size= */ UINT32_MAX,
FLAGS_SET(flags, DISSECT_IMAGE_NO_PARTITION_TABLE) ? 0 : LO_FLAGS_PARTSCAN,
LOCK_SH,
&d);

View File

@ -0,0 +1,25 @@
From 2f4fd9002d0f438f7643ec98368bed709cb49442 Mon Sep 17 00:00:00 2001
From: David Tardon <dtardon@redhat.com>
Date: Tue, 14 Mar 2023 16:06:39 +0100
Subject: [PATCH] Revert "Treat EPERM as "not available" too"
This reverts commit 9e51ecd3ec0484d7ffefb0ceaf242e96b31195bb.
Resolves: #2178222
---
src/nspawn/nspawn.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/nspawn/nspawn.c b/src/nspawn/nspawn.c
index cdebe8e5c4..df7b37ec4e 100644
--- a/src/nspawn/nspawn.c
+++ b/src/nspawn/nspawn.c
@@ -3806,7 +3806,7 @@ static int outer_child(
arg_uid_shift != 0) {
r = remount_idmap(directory, arg_uid_shift, arg_uid_range, UID_INVALID, REMOUNT_IDMAPPING_HOST_ROOT);
- if (IN_SET(r, -EINVAL, -EPERM) || ERRNO_IS_NOT_SUPPORTED(r)) {
+ if (r == -EINVAL || ERRNO_IS_NOT_SUPPORTED(r)) {
/* This might fail because the kernel or file system doesn't support idmapping. We
* can't really distinguish this nicely, nor do we have any guarantees about the
* error codes we see, could be EOPNOTSUPP or EINVAL. */

View File

@ -0,0 +1,26 @@
From 3aab4694f97f96fc7d3608fb3a7bff047e390b4e Mon Sep 17 00:00:00 2001
From: David Tardon <dtardon@redhat.com>
Date: Tue, 14 Mar 2023 16:07:28 +0100
Subject: [PATCH] Revert "test: accept EPERM for unavailable idmapped mounts as
well"
This reverts commit d2ccb0bf2b2078e13fc4cb1c2e2eb8079fa57df0.
Related: #2178222
---
test/units/testsuite-13.sh | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/test/units/testsuite-13.sh b/test/units/testsuite-13.sh
index 2b6e6df8a3..4ad7431e42 100755
--- a/test/units/testsuite-13.sh
+++ b/test/units/testsuite-13.sh
@@ -74,7 +74,7 @@ function check_rootidmap {
--register=no -D "$_root" \
--bind=/tmp/rootidmapdir:/mnt:rootidmap \
/bin/sh -c "$_command" |& tee nspawn.out; then
- if grep -Eq "Failed to map ids for bind mount.*: (Function not implemented|Operation not permitted)" nspawn.out; then
+ if grep -q "Failed to map ids for bind mount.*: Function not implemented" nspawn.out; then
echo "idmapped mounts are not supported, skipping the test..."
return 0
fi

View File

@ -21,7 +21,7 @@
Name: systemd Name: systemd
Url: https://systemd.io Url: https://systemd.io
Version: 252 Version: 252
Release: 17%{?dist} Release: 18%{?dist}
# For a breakdown of the licensing, see README # For a breakdown of the licensing, see README
License: LGPLv2+ and MIT and GPLv2+ License: LGPLv2+ and MIT and GPLv2+
Summary: System and Service Manager Summary: System and Service Manager
@ -364,6 +364,89 @@ Patch0283: 0283-core-service-when-resetting-PID-also-reset-known-fla.patch
Patch0284: 0284-ci-drop-systemd-stable-from-advanced-commit-linter-c.patch Patch0284: 0284-ci-drop-systemd-stable-from-advanced-commit-linter-c.patch
Patch0285: 0285-Revert-core-service-when-resetting-PID-also-reset-kn.patch Patch0285: 0285-Revert-core-service-when-resetting-PID-also-reset-kn.patch
Patch0286: 0286-ci-explicitly-install-python3-lldb-COMPILER_VERSION.patch Patch0286: 0286-ci-explicitly-install-python3-lldb-COMPILER_VERSION.patch
Patch0287: 0287-doc-add-downstream-CONTRIBUTING-document.patch
Patch0288: 0288-doc-improve-CONTRIBUTING-document.patch
Patch0289: 0289-doc-use-link-with-prefilled-Jira-issue.patch
Patch0290: 0290-docs-link-downstream-CONTRIBUTING-in-README.patch
Patch0291: 0291-bpf-fix-restrict_fs-on-s390x.patch
Patch0292: 0292-udev-net_id-use-naming-scheme-for-RHEL-9.3.patch
Patch0293: 0293-core-timer-Always-use-inactive_exit_timestamp-if-it-.patch
Patch0294: 0294-timer-Use-dual_timestamp_is_set-in-one-more-place.patch
Patch0295: 0295-loginctl-list-users-also-show-state.patch
Patch0296: 0296-loginctl-list-sessions-minor-modernization.patch
Patch0297: 0297-loginctl-list-sessions-also-show-state.patch
Patch0298: 0298-test-add-test-for-state-in-loginctl-list-users-sessi.patch
Patch0299: 0299-test-add-a-missing-session-activation.patch
Patch0300: 0300-test-extend-test-for-loginctl-list.patch
Patch0301: 0301-loginctl-shorten-variable-name.patch
Patch0302: 0302-loginctl-use-bus_map_all_properties.patch
Patch0303: 0303-loginctl-show-session-idle-status-in-list-sessions.patch
Patch0304: 0304-loginctl-some-modernizations.patch
Patch0305: 0305-loginctl-list-sessions-fix-timestamp-for-idle-hint.patch
Patch0306: 0306-loginctl-list-users-use-bus_map_all_properties.patch
Patch0307: 0307-loginctl-also-show-idle-hint-in-session-status.patch
Patch0308: 0308-memory-util-make-ArrayCleanup-passed-to-array_cleanu.patch
Patch0309: 0309-static-destruct-several-cleanups.patch
Patch0310: 0310-static-destruct-introduce-STATIC_ARRAY_DESTRUCTOR_RE.patch
Patch0311: 0311-macro-support-the-case-that-the-number-of-elements-h.patch
Patch0312: 0312-shared-generator-apply-similar-config-reordering-of-.patch
Patch0313: 0313-nulstr-util-make-ret_size-in-strv_make_nulstr-option.patch
Patch0314: 0314-generator-teach-generator_add_symlink-to-instantiate.patch
Patch0315: 0315-units-rework-growfs-units-to-be-just-a-regular-unit-.patch
Patch0316: 0316-fstab-generator-use-correct-targets-when-sysroot-is-.patch
Patch0317: 0317-fstab-generator-add-SYSTEMD_SYSFS_CHECK-env-var.patch
Patch0318: 0318-test-add-fstab-file-support-for-fstab-generator-test.patch
Patch0319: 0319-test-fstab-generator-also-check-file-contents.patch
Patch0320: 0320-test-fstab-generator-add-tests-for-mount-options.patch
Patch0321: 0321-fstab-generator-split-out-several-functions-from-par.patch
Patch0322: 0322-fstab-generator-call-add_swap-earlier.patch
Patch0323: 0323-fstab-generator-refuse-to-add-swap-earlier-if-disabl.patch
Patch0324: 0324-fstab-generator-refuse-invalid-mount-point-path-in-f.patch
Patch0325: 0325-fstab-generator-fix-error-code-propagation-in-run_ge.patch
Patch0326: 0326-fstab-generator-support-defining-mount-units-through.patch
Patch0327: 0327-test-add-test-cases-for-defining-mount-and-swap-unit.patch
Patch0328: 0328-generators-change-TimeoutSec-0-to-TimeoutSec-infinit.patch
Patch0329: 0329-units-change-TimeoutSec-0-to-TimeoutSec-infinity.patch
Patch0330: 0330-fstab-generator-use-correct-swap-name-var.patch
Patch0331: 0331-fstab-generator-add-more-parameter-name-comments.patch
Patch0332: 0332-fstab-generator-unify-initrd-root-device.target-depe.patch
Patch0333: 0333-fstab-util-add-fstab_is_bind.patch
Patch0334: 0334-fstab-generator-resolve-bind-mount-source-when-in-in.patch
Patch0335: 0335-fstab-generator-rename-initrd-flag-to-prefix_sysroot.patch
Patch0336: 0336-fstab-generator-fix-target-of-sysroot-usr.patch
Patch0337: 0337-fstab-generator-add-rd.systemd.mount-extra-and-frien.patch
Patch0338: 0338-fstab-generator-add-a-flag-to-accept-entry-for-in-in.patch
Patch0339: 0339-test-fstab-generator-extract-core-part-as-a-function.patch
Patch0340: 0340-test-fstab-generator-also-test-with-SYSTEMD_IN_INITR.patch
Patch0341: 0341-test-fstab-generator-add-more-tests-for-systemd.moun.patch
Patch0342: 0342-fstab-generator-enable-fsck-for-block-device-mounts-.patch
Patch0343: 0343-core-use-correct-scope-of-looking-up-units.patch
Patch0344: 0344-test-merge-unit-file-related-tests-into-TEST-23-UNIT.patch
Patch0345: 0345-test-rename-TEST-07-ISSUE-1981-to-TEST-07-PID1.patch
Patch0346: 0346-test-merge-TEST-08-ISSUE-2730-into-TEST-07-PID1.patch
Patch0347: 0347-test-merge-TEST-09-ISSUE-2691-into-TEST-07-PID1.patch
Patch0348: 0348-test-merge-TEST-10-ISSUE-2467-with-TEST-07-PID1.patch
Patch0349: 0349-test-merge-TEST-11-ISSUE-3166-into-TEST-07-PID1.patch
Patch0350: 0350-test-merge-TEST-12-ISSUE-3171-into-TEST-07-PID1.patch
Patch0351: 0351-test-move-TEST-23-s-units-into-a-dedicated-subfolder.patch
Patch0352: 0352-test-merge-TEST-47-ISSUE-14566-into-TEST-07-PID1.patch
Patch0353: 0353-test-merge-TEST-51-ISSUE-16115-into-TEST-07-PID1.patch
Patch0354: 0354-test-merge-TEST-20-MAINPIDGAMES-into-TEST-07-PID1.patch
Patch0355: 0355-test-abstract-the-common-test-parts-into-a-utility-s.patch
Patch0356: 0356-test-add-tests-for-JoinsNamespaceOf.patch
Patch0357: 0357-core-unit-drop-doubled-empty-line.patch
Patch0358: 0358-core-unit-make-JoinsNamespaceOf-implies-the-inverse-.patch
Patch0359: 0359-core-unit-search-shared-namespace-in-transitive-rela.patch
Patch0360: 0360-core-unit-update-bidirectional-dependency-simultaneo.patch
Patch0361: 0361-resolvectl-fix-type-of-ifindex-D-Bus-field-and-make-.patch
Patch0362: 0362-resolved-add-some-line-breaks-comments.patch
Patch0363: 0363-resolvectl-don-t-filter-loopback-DNS-server-from-glo.patch
Patch0364: 0364-blockdev-util-add-simple-wrapper-around-BLKSSZGET.patch
Patch0365: 0365-loop-util-insist-on-setting-the-sector-size-correctl.patch
Patch0366: 0366-dissect-image-add-probe_sector_size-helper-for-detec.patch
Patch0367: 0367-loop-util-always-tell-kernel-explicitly-about-loopba.patch
Patch0368: 0368-Revert-Treat-EPERM-as-not-available-too.patch
Patch0369: 0369-Revert-test-accept-EPERM-for-unavailable-idmapped-mo.patch
# Downstream-only patches (90009999) # Downstream-only patches (90009999)
@ -1185,6 +1268,91 @@ getent passwd systemd-oom &>/dev/null || useradd -r -l -g systemd-oom -d / -s /s
%files standalone-sysusers -f .file-list-standalone-sysusers %files standalone-sysusers -f .file-list-standalone-sysusers
%changelog %changelog
* Tue Aug 22 2023 systemd maintenance team <systemd-maint@redhat.com> - 252-18
- doc: add downstream CONTRIBUTING document (#2170883)
- doc: improve CONTRIBUTING document (#2170883)
- doc: use link with prefilled Jira issue (#2170883)
- docs: link downstream CONTRIBUTING in README (#2170883)
- bpf: fix restrict_fs on s390x (#2230364)
- udev/net_id: use naming scheme for RHEL-9.3 (#2231845)
- core/timer: Always use inactive_exit_timestamp if it is set (#2211065)
- timer: Use dual_timestamp_is_set() in one more place (#2211065)
- loginctl: list-users: also show state (#2209912)
- loginctl: list-sessions: minor modernization (#2209912)
- loginctl: list-sessions: also show state (#2209912)
- test: add test for state in loginctl list-{users,sessions} (#2209912)
- test: add a missing session activation (#2209912)
- test: extend test for loginctl list-* (#2209912)
- loginctl: shorten variable name (#2209912)
- loginctl: use bus_map_all_properties (#2209912)
- loginctl: show session idle status in list-sessions (#2209912)
- loginctl: some modernizations (#2209912)
- loginctl: list-sessions: fix timestamp for idle hint (#2209912)
- loginctl: list-users: use bus_map_all_properties (#2209912)
- loginctl: also show idle hint in session-status (#2209912)
- memory-util: make ArrayCleanup passed to array_cleanup() const (#2190226)
- static-destruct: several cleanups (#2190226)
- static-destruct: introduce STATIC_ARRAY_DESTRUCTOR_REGISTER() (#2190226)
- macro: support the case that the number of elements has const qualifier (#2190226)
- shared/generator: apply similar config reordering of generated units (#2190226)
- nulstr-util: make ret_size in strv_make_nulstr() optional (#2190226)
- generator: teach generator_add_symlink() to instantiate specified unit (#2190226)
- units: rework growfs units to be just a regular unit that is instantiated (#2190226)
- fstab-generator: use correct targets when /sysroot is specificied in fstab only (#2190226)
- fstab-generator: add SYSTEMD_SYSFS_CHECK env var (#2190226)
- test: add fstab file support for fstab-generator tests (#2190226)
- test-fstab-generator: also check file contents (#2190226)
- test-fstab-generator: add tests for mount options (#2190226)
- fstab-generator: split out several functions from parse_fstab() (#2190226)
- fstab-generator: call add_swap() earlier (#2190226)
- fstab-generator: refuse to add swap earlier if disabled (#2190226)
- fstab-generator: refuse invalid mount point path in fstab earlier (#2190226)
- fstab-generator: fix error code propagation in run_generator() (#2190226)
- fstab-generator: support defining mount units through kernel command line (#2190226)
- test: add test cases for defining mount and swap units from kernel cmdline (#2190226)
- generators: change TimeoutSec=0 to TimeoutSec=infinity (#2190226)
- units: change TimeoutSec=0 to TimeoutSec=infinity (#2190226)
- fstab-generator: use correct swap name var (#2190226)
- fstab-generator: add more parameter name comments (#2190226)
- fstab-generator: unify initrd-root-device.target dependency handling code (#2190226)
- fstab-util: add fstab_is_bind (#2190226)
- fstab-generator: resolve bind mount source when in initrd (#2190226)
- fstab-generator: rename 'initrd' flag to 'prefix_sysroot' (#2190226)
- fstab-generator: fix target of /sysroot/usr (#2190226)
- fstab-generator: add rd.systemd.mount-extra= and friends (#2190226)
- fstab-generator: add a flag to accept entry for "/" in initrd (#2190226)
- test-fstab-generator: extract core part as a function (#2190226)
- test-fstab-generator: also test with SYSTEMD_IN_INITRD=no (#2190226)
- test-fstab-generator: add more tests for systemd.mount-extra= and friends (#2190226)
- fstab-generator: enable fsck for block device mounts specified in systemd.mount-extra= (#2190226)
- core: use correct scope of looking up units (#2226980)
- test: merge unit file related tests into TEST-23-UNIT-FILE (#2213521)
- test: rename TEST-07-ISSUE-1981 to TEST-07-PID1 (#2213521)
- test: merge TEST-08-ISSUE-2730 into TEST-07-PID1 (#2213521)
- test: merge TEST-09-ISSUE-2691 into TEST-07-PID1 (#2213521)
- test: merge TEST-10-ISSUE-2467 with TEST-07-PID1 (#2213521)
- test: merge TEST-11-ISSUE-3166 into TEST-07-PID1 (#2213521)
- test: merge TEST-12-ISSUE-3171 into TEST-07-PID1 (#2213521)
- test: move TEST-23's units into a dedicated subfolder (#2213521)
- test: merge TEST-47-ISSUE-14566 into TEST-07-PID1 (#2213521)
- test: merge TEST-51-ISSUE-16115 into TEST-07-PID1 (#2213521)
- test: merge TEST-20-MAINPIDGAMES into TEST-07-PID1 (#2213521)
- test: abstract the common test parts into a utility script (#2213521)
- test: add tests for JoinsNamespaceOf= (#2213521)
- core/unit: drop doubled empty line (#2213521)
- core/unit: make JoinsNamespaceOf= implies the inverse dependency (#2213521)
- core/unit: search shared namespace in transitive relation of JoinsNamespaceOf= (#2213521)
- core/unit: update bidirectional dependency simultaneously (#2213521)
- resolvectl: fix type of ifindex D-Bus field, and make sure to initialize to zero in all code paths (#2161260)
- resolved: add some line-breaks/comments (#2161260)
- resolvectl: don't filter loopback DNS server from global DNS server list (#2161260)
- blockdev-util: add simple wrapper around BLKSSZGET (#2170883)
- loop-util: insist on setting the sector size correctly (#2170883)
- dissect-image: add probe_sector_size() helper for detecting sector size of a GPT disk image (#2170883)
- loop-util: always tell kernel explicitly about loopback sector size (#2170883)
- Revert "Treat EPERM as "not available" too" (#2178222)
- Revert "test: accept EPERM for unavailable idmapped mounts as well" (#2178222)
* Fri Aug 04 2023 systemd maintenance team <systemd-maint@redhat.com> - 252-17 * Fri Aug 04 2023 systemd maintenance team <systemd-maint@redhat.com> - 252-17
- Revert "core/service: when resetting PID also reset known flag" (#2225667 - Revert "core/service: when resetting PID also reset known flag" (#2225667
#2210237) #2210237)