From cabf58b24f899416cd63c93593ad85e62b81ed58 Mon Sep 17 00:00:00 2001 From: Franck Bui Date: Tue, 16 May 2017 21:27:44 +0200 Subject: [PATCH 1/5] swap: make use of manager_get_unit() in swap.c Minor cleanup, no functional changes. --- src/core/swap.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/core/swap.c b/src/core/swap.c index e9468e105c..72e5a614bc 100644 --- a/src/core/swap.c +++ b/src/core/swap.c @@ -1340,7 +1340,7 @@ int swap_process_device_new(Manager *m, struct udev_device *dev) { struct udev_list_entry *item = NULL, *first = NULL; _cleanup_free_ char *e = NULL; const char *dn; - Swap *s; + Unit *u; int r = 0; assert(m); @@ -1354,9 +1354,9 @@ int swap_process_device_new(Manager *m, struct udev_device *dev) { if (r < 0) return r; - s = hashmap_get(m->units, e); - if (s) - r = swap_set_devnode(s, dn); + u = manager_get_unit(m, e); + if (u) + r = swap_set_devnode(SWAP(u), dn); first = udev_device_get_devlinks_list_entry(dev); udev_list_entry_foreach(item, first) { @@ -1367,9 +1367,9 @@ int swap_process_device_new(Manager *m, struct udev_device *dev) { if (q < 0) return q; - s = hashmap_get(m->units, n); - if (s) { - q = swap_set_devnode(s, dn); + u = manager_get_unit(m, n); + if (u) { + q = swap_set_devnode(SWAP(u), dn); if (q < 0) r = q; } From d31ae54818c7a02d4bb07aa41e24166d252d6f31 Mon Sep 17 00:00:00 2001 From: Franck Bui Date: Wed, 17 May 2017 12:43:59 +0200 Subject: [PATCH 2/5] swap: make use of IN_SET() Minor cleanups, no functional changes. --- src/core/swap.c | 58 ++++++++++++++++++++++++------------------------- 1 file changed, 29 insertions(+), 29 deletions(-) diff --git a/src/core/swap.c b/src/core/swap.c index 72e5a614bc..4c3a74ce00 100644 --- a/src/core/swap.c +++ b/src/core/swap.c @@ -487,13 +487,14 @@ static void swap_set_state(Swap *s, SwapState state) { old_state = s->state; s->state = state; - if (state != SWAP_ACTIVATING && - state != SWAP_ACTIVATING_SIGTERM && - state != SWAP_ACTIVATING_SIGKILL && - state != SWAP_ACTIVATING_DONE && - state != SWAP_DEACTIVATING && - state != SWAP_DEACTIVATING_SIGTERM && - state != SWAP_DEACTIVATING_SIGKILL) { + if (!IN_SET(state, + SWAP_ACTIVATING, + SWAP_ACTIVATING_SIGTERM, + SWAP_ACTIVATING_SIGKILL, + SWAP_ACTIVATING_DONE, + SWAP_DEACTIVATING, + SWAP_DEACTIVATING_SIGTERM, + SWAP_DEACTIVATING_SIGKILL)) { s->timer_event_source = sd_event_source_unref(s->timer_event_source); swap_unwatch_control_pid(s); s->control_command = NULL; @@ -695,20 +696,19 @@ static void swap_enter_active(Swap *s, SwapResult f) { static void swap_enter_signal(Swap *s, SwapState state, SwapResult f) { int r; + KillOperation kop; assert(s); if (s->result == SWAP_SUCCESS) s->result = f; - r = unit_kill_context( - UNIT(s), - &s->kill_context, - (state != SWAP_ACTIVATING_SIGTERM && state != SWAP_DEACTIVATING_SIGTERM) ? - KILL_KILL : KILL_TERMINATE, - -1, - s->control_pid, - false); + if (IN_SET(state, SWAP_ACTIVATING_SIGTERM, SWAP_DEACTIVATING_SIGTERM)) + kop = KILL_TERMINATE; + else + kop = KILL_KILL; + + r = unit_kill_context(UNIT(s), &s->kill_context, kop, -1, s->control_pid, false); if (r < 0) goto fail; @@ -829,17 +829,18 @@ static int swap_start(Unit *u) { /* We cannot fulfill this request right now, try again later * please! */ - if (s->state == SWAP_DEACTIVATING || - s->state == SWAP_DEACTIVATING_SIGTERM || - s->state == SWAP_DEACTIVATING_SIGKILL || - s->state == SWAP_ACTIVATING_SIGTERM || - s->state == SWAP_ACTIVATING_SIGKILL) + if (IN_SET(s->state, + SWAP_DEACTIVATING, + SWAP_DEACTIVATING_SIGTERM, + SWAP_DEACTIVATING_SIGKILL, + SWAP_ACTIVATING_SIGTERM, + SWAP_ACTIVATING_SIGKILL)) return -EAGAIN; if (s->state == SWAP_ACTIVATING) return 0; - assert(s->state == SWAP_DEAD || s->state == SWAP_FAILED); + assert(IN_SET(s->state, SWAP_DEAD, SWAP_FAILED)); if (detect_container() > 0) return -EPERM; @@ -873,16 +874,15 @@ static int swap_stop(Unit *u) { assert(s); - if (s->state == SWAP_DEACTIVATING || - s->state == SWAP_DEACTIVATING_SIGTERM || - s->state == SWAP_DEACTIVATING_SIGKILL || - s->state == SWAP_ACTIVATING_SIGTERM || - s->state == SWAP_ACTIVATING_SIGKILL) + if (IN_SET(s->state, + SWAP_DEACTIVATING, + SWAP_DEACTIVATING_SIGTERM, + SWAP_DEACTIVATING_SIGKILL, + SWAP_ACTIVATING_SIGTERM, + SWAP_ACTIVATING_SIGKILL)) return 0; - assert(s->state == SWAP_ACTIVATING || - s->state == SWAP_ACTIVATING_DONE || - s->state == SWAP_ACTIVE); + assert(IN_SET(s->state, SWAP_ACTIVATING, SWAP_ACTIVATING_DONE, SWAP_ACTIVE)); if (detect_container() > 0) return -EPERM; From b9088048b15cd21242b2308498fa865f864bfe45 Mon Sep 17 00:00:00 2001 From: Franck Bui Date: Tue, 27 Jun 2017 09:52:12 +0200 Subject: [PATCH 3/5] fstab-util: don't eat up errors in fstab_is_mount_point() That way the caller can decide what to do with failures, whether to consider them or ignore them. --- src/gpt-auto-generator/gpt-auto-generator.c | 5 ++++- src/shared/fstab-util.c | 13 +++++++++---- src/shared/fstab-util.h | 2 +- 3 files changed, 14 insertions(+), 6 deletions(-) diff --git a/src/gpt-auto-generator/gpt-auto-generator.c b/src/gpt-auto-generator/gpt-auto-generator.c index 3578e2513c..a6cd8af1b7 100644 --- a/src/gpt-auto-generator/gpt-auto-generator.c +++ b/src/gpt-auto-generator/gpt-auto-generator.c @@ -435,7 +435,10 @@ static int add_esp(DissectedPartition *p) { esp = access("/efi/", F_OK) >= 0 ? "/efi" : "/boot"; /* We create an .automount which is not overridden by the .mount from the fstab generator. */ - if (fstab_is_mount_point(esp)) { + r = fstab_is_mount_point(esp); + if (r < 0) + return log_error_errno(r, "Failed to parse fstab: %m"); + if (r == 0) { log_debug("%s specified in fstab, ignoring.", esp); return 0; } diff --git a/src/shared/fstab-util.c b/src/shared/fstab-util.c index c3106f1ae9..5675b0beac 100644 --- a/src/shared/fstab-util.c +++ b/src/shared/fstab-util.c @@ -34,18 +34,23 @@ #include "strv.h" #include "util.h" -bool fstab_is_mount_point(const char *mount) { +int fstab_is_mount_point(const char *mount) { _cleanup_endmntent_ FILE *f = NULL; struct mntent *m; f = setmntent("/etc/fstab", "re"); if (!f) - return false; + return errno == ENOENT ? false : -errno; + + for (;;) { + errno = 0; + m = getmntent(f); + if (!m) + return errno != 0 ? -errno : false; - while ((m = getmntent(f))) if (path_equal(m->mnt_dir, mount)) return true; - + } return false; } diff --git a/src/shared/fstab-util.h b/src/shared/fstab-util.h index 679f6902f7..bae8c0a894 100644 --- a/src/shared/fstab-util.h +++ b/src/shared/fstab-util.h @@ -24,7 +24,7 @@ #include "macro.h" -bool fstab_is_mount_point(const char *mount); +int fstab_is_mount_point(const char *mount); int fstab_filter_options(const char *opts, const char *names, const char **namefound, char **value, char **filtered); From 6c1921e9f39ce450bbd066341afc6a677ef122cb Mon Sep 17 00:00:00 2001 From: Franck Bui Date: Mon, 26 Jun 2017 15:22:10 +0200 Subject: [PATCH 4/5] fstab-util: introduce fstab_has_fstype() helper --- src/shared/fstab-util.c | 20 ++++++++++++++++++++ src/shared/fstab-util.h | 1 + 2 files changed, 21 insertions(+) diff --git a/src/shared/fstab-util.c b/src/shared/fstab-util.c index 5675b0beac..ec2e868ca8 100644 --- a/src/shared/fstab-util.c +++ b/src/shared/fstab-util.c @@ -34,6 +34,26 @@ #include "strv.h" #include "util.h" +int fstab_has_fstype(const char *fstype) { + _cleanup_endmntent_ FILE *f = NULL; + struct mntent *m; + + f = setmntent("/etc/fstab", "re"); + if (!f) + return errno == ENOENT ? false : -errno; + + for (;;) { + errno = 0; + m = getmntent(f); + if (!m) + return errno != 0 ? -errno : false; + + if (streq(m->mnt_type, fstype)) + return true; + } + return false; +} + int fstab_is_mount_point(const char *mount) { _cleanup_endmntent_ FILE *f = NULL; struct mntent *m; diff --git a/src/shared/fstab-util.h b/src/shared/fstab-util.h index bae8c0a894..bbf0441351 100644 --- a/src/shared/fstab-util.h +++ b/src/shared/fstab-util.h @@ -25,6 +25,7 @@ #include "macro.h" int fstab_is_mount_point(const char *mount); +int fstab_has_fstype(const char *fstype); int fstab_filter_options(const char *opts, const char *names, const char **namefound, char **value, char **filtered); From fc5bc384c7691bc9aacf05bfa79a2a02c3d8d45d Mon Sep 17 00:00:00 2001 From: Franck Bui Date: Mon, 26 Jun 2017 15:23:35 +0200 Subject: [PATCH 5/5] gpt-auto-generator: disable gpt auto logic for swaps if at least one is defined in fstab If a swap partition is created on a disk using GPT then the unit generated by the gpt-generator can shadow the one generated by the fstab-generator. This can be an issue if the fstab entry for the swap has options since they are simply ignored if PID1 decides to use the unit created by the gpt-generator since this unit carries no information about the swap options. This patch simply disables the GPT auto logic for swaps if at least one entry for swap is defined in /etc/fstab. Fixes: #6192 --- src/gpt-auto-generator/gpt-auto-generator.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/gpt-auto-generator/gpt-auto-generator.c b/src/gpt-auto-generator/gpt-auto-generator.c index a6cd8af1b7..c5319169b3 100644 --- a/src/gpt-auto-generator/gpt-auto-generator.c +++ b/src/gpt-auto-generator/gpt-auto-generator.c @@ -305,6 +305,15 @@ static int add_swap(const char *path) { assert(path); + /* Disable the swap auto logic if at least one swap is defined in /etc/fstab, see #6192. */ + r = fstab_has_fstype("swap"); + if (r < 0) + return log_error_errno(r, "Failed to parse fstab: %m"); + if (r == 0) { + log_debug("swap specified in fstab, ignoring."); + return 0; + } + log_debug("Adding swap: %s", path); r = unit_name_from_path(path, ".swap", &name);