Commit fc91558a authored by Martin Pitt's avatar Martin Pitt

Don't attempt to mount the same swap partition twice through different device node aliases

Patches cherry-picked from upstream git.

Closes: #772182
LP: #1399595
parent 1b31191d
......@@ -17,6 +17,8 @@ systemd (215-14) UNRELEASED; urgency=medium
name when the cgroup becomes empty. (Closes: #781210)
* boot-and-services, display-managers autopkgtests: Add missing python3 test
dependency.
* Don't attempt to mount the same swap partition twice through different
device node aliases. (Closes: #772182, LP: #1399595)
[ Christian Seiler ]
* Make the journald to syslog forwarding more robust by increasing the
......
From: Lennart Poettering <lennart@poettering.net>
Date: Wed, 28 Jan 2015 00:38:38 +0100
Subject: core: if two start jobs for the same swap device node are queued,
only dispatch one of them at a time
If two start jobs for two seperate .swap device nodes are queued, which
then turns out to be referring to the same device node, refuse
dispatching more than one of them at the same time.
This should solve an issue when the same swap partition is found via GPT
auto-discovery and via /etc/fstab, where one uses a symlink path, and
the other the raw devce node. So far we might have ended up invoking
mkswap on the same node at the very same time with the two device node
names.
With this change only one mkswap should be executed at a time. THis
mkswap should have immediate effect on the other swap unit, due to the
state in /proc/swaps changing, and thus suppressing actual invocation of
the second mkswap.
http://lists.freedesktop.org/archives/systemd-devel/2015-January/027314.html
---
src/core/swap.c | 19 ++++++++++++++++++-
1 file changed, 18 insertions(+), 1 deletion(-)
diff --git a/src/core/swap.c b/src/core/swap.c
index a6a2355..8a77e78 100644
--- a/src/core/swap.c
+++ b/src/core/swap.c
@@ -472,6 +472,7 @@ static int swap_process_new_swap(Manager *m, const char *device, int prio, bool
static void swap_set_state(Swap *s, SwapState state) {
SwapState old_state;
+ Swap *other;
assert(s);
@@ -499,6 +500,15 @@ static void swap_set_state(Swap *s, SwapState state) {
swap_state_to_string(state));
unit_notify(UNIT(s), state_translation_table[old_state], state_translation_table[state], true);
+
+ /* If there other units for the same device node have a job
+ queued it might be worth checking again if it is runnable
+ now. This is necessary, since swap_start() refuses
+ operation with EAGAIN if there's already another job for
+ the same device node queued. */
+ LIST_FOREACH_OTHERS(same_devnode, other, s)
+ if (UNIT(other)->job)
+ job_add_to_run_queue(UNIT(other)->job);
}
static int swap_coldplug(Unit *u) {
@@ -866,7 +876,7 @@ fail:
}
static int swap_start(Unit *u) {
- Swap *s = SWAP(u);
+ Swap *s = SWAP(u), *other;
assert(s);
@@ -888,6 +898,13 @@ static int swap_start(Unit *u) {
if (detect_container(NULL) > 0)
return -EPERM;
+ /* If there's a job for another swap unit for the same node
+ * running, then let's not dispatch this one for now, and wait
+ * until that other job has finished. */
+ LIST_FOREACH_OTHERS(same_devnode, other, s)
+ if (UNIT(other)->job && UNIT(other)->job->state == JOB_RUNNING)
+ return -EAGAIN;
+
s->result = SWAP_SUCCESS;
swap_enter_activating(s);
return 0;
From: Lennart Poettering <lennart@poettering.net>
Date: Wed, 28 Jan 2015 00:34:58 +0100
Subject: list: add macro for iterating through a list an item is in,
skipping the item
---
src/shared/list.h | 12 ++++++++++++
src/test/test-list.c | 7 +++++++
2 files changed, 19 insertions(+)
diff --git a/src/shared/list.h b/src/shared/list.h
index c020f7e..d535a17 100644
--- a/src/shared/list.h
+++ b/src/shared/list.h
@@ -130,6 +130,18 @@
#define LIST_FOREACH_AFTER(name,i,p) \
for ((i) = (p)->name##_next; (i); (i) = (i)->name##_next)
+/* Iterate through all the members of the list p is included in, but skip over p */
+#define LIST_FOREACH_OTHERS(name,i,p) \
+ for (({ \
+ (i) = (p); \
+ while ((i) && (i)->name##_prev) \
+ (i) = (i)->name##_prev; \
+ if ((i) == (p)) \
+ (i) = (p)->name##_next; \
+ }); \
+ (i); \
+ (i) = (i)->name##_next == (p) ? (p)->name##_next : (i)->name##_next)
+
/* Loop starting from p->next until p->prev.
p can be adjusted meanwhile. */
#define LIST_LOOP_BUT_ONE(name,i,head,p) \
diff --git a/src/test/test-list.c b/src/test/test-list.c
index fa52ad1..4e3be91 100644
--- a/src/test/test-list.c
+++ b/src/test/test-list.c
@@ -38,6 +38,13 @@ int main(int argc, const char *argv[]) {
LIST_PREPEND(item, head, &items[i]);
}
+ i = 0;
+ LIST_FOREACH_OTHERS(item, cursor, &items[2]) {
+ i++;
+ assert_se(cursor != &items[2]);
+ }
+ assert_se(i == ELEMENTSOF(items)-1);
+
assert_se(!LIST_JUST_US(item, head));
assert_se(items[0].item_next == NULL);
......@@ -142,6 +142,8 @@ units-tmpfiles-setup-dev-allow-unsafe-file-creation-.patch
core-don-t-migrate-PIDs-for-units-that-may-contain-s.patch
scope-make-attachment-of-initial-PIDs-a-bit-more-rob.patch
journald-also-increase-the-SendBuffer-of-dev-log-to-.patch
list-add-macro-for-iterating-through-a-list-an-item-.patch
core-if-two-start-jobs-for-the-same-swap-device-node.patch
## Debian specific patches:
Add-back-support-for-Debian-specific-config-files.patch
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment