SHA256
1
0
forked from pool/systemd

Accepting request 142164 from home:fcrozat:branches:Base:System

- Add remount-ro-before-unmount.patch: always remount read-only
  before unmounting in final shutdown loop.
- Add switch-root-try-pivot-root.patch: try pivot_root before
  overmounting /

OBS-URL: https://build.opensuse.org/request/show/142164
OBS-URL: https://build.opensuse.org/package/show/Base:System/systemd?expand=0&rev=313
This commit is contained in:
Cristian Rodríguez 2012-11-20 17:57:51 +00:00 committed by Git OBS Bridge
parent 62fc9acca7
commit fa79d4401d
6 changed files with 204 additions and 0 deletions

View File

@ -0,0 +1,95 @@
From 93bd157722c76b47d80742f290373c1ce2865070 Mon Sep 17 00:00:00 2001
From: Lennart Poettering <lennart@poettering.net>
Date: Fri, 16 Nov 2012 18:36:28 +0100
Subject: [PATCH] umount: always remount read-only before unmounting in final
shutdown loop
---
src/core/umount.c | 57 +++++++++++++++++++++++++----------------------------
1 file changed, 27 insertions(+), 30 deletions(-)
diff --git a/src/core/umount.c b/src/core/umount.c
index 83c9de3..e794057 100644
--- a/src/core/umount.c
+++ b/src/core/umount.c
@@ -407,6 +407,33 @@ static int mount_points_list_umount(MountPoint **head, bool *changed, bool log_e
assert(head);
LIST_FOREACH_SAFE(mount_point, m, n, *head) {
+
+ /* If we are in a container, don't attempt to
+ read-only mount anything as that brings no real
+ benefits, but might confuse the host, as we remount
+ the superblock here, not the bind mound. */
+ if (detect_container(NULL) <= 0) {
+ /* We always try to remount directories
+ * read-only first, before we go on and umount
+ * them.
+ *
+ * Mount points can be stacked. If a mount
+ * point is stacked below / or /usr, we
+ * cannnot umount or remount it directly,
+ * since there is no way to refer to the
+ * underlying mount. There's nothing we can do
+ * about it for the general case, but we can
+ * do something about it if it is aliased
+ * somehwere else via a bind mount. If we
+ * explicitly remount the super block of that
+ * alias read-only we hence should be
+ * relatively safe regarding keeping the fs we
+ * can otherwise not see dirty. */
+ mount(NULL, m->path, NULL, MS_REMOUNT|MS_RDONLY, NULL);
+ }
+
+ /* Skip / and /usr since we cannot unmount that
+ * anyway, since we are running from it */
if (path_equal(m->path, "/")
#ifndef HAVE_SPLIT_USR
|| path_equal(m->path, "/usr")
@@ -432,29 +459,6 @@ static int mount_points_list_umount(MountPoint **head, bool *changed, bool log_e
return n_failed;
}
-static int mount_points_list_remount_read_only(MountPoint **head, bool *changed) {
- MountPoint *m, *n;
- int n_failed = 0;
-
- assert(head);
-
- LIST_FOREACH_SAFE(mount_point, m, n, *head) {
-
- /* Trying to remount read-only */
- if (mount(NULL, m->path, NULL, MS_REMOUNT|MS_RDONLY, NULL) == 0) {
- if (changed)
- *changed = true;
-
- mount_point_free(head, m);
- } else {
- log_warning("Could not remount as read-only %s: %m", m->path);
- n_failed++;
- }
- }
-
- return n_failed;
-}
-
static int swap_points_list_off(MountPoint **head, bool *changed) {
MountPoint *m, *n;
int n_failed = 0;
@@ -571,13 +575,6 @@ int umount_all(bool *changed) {
if (r <= 0)
goto end;
- /* If we are in a container, don't attempt to read-only mount
- anything as that brings no real benefits, but might confuse
- the host, as we remount the superblock here, not the bind
- mound. */
- if (detect_container(NULL) <= 0)
- r = mount_points_list_remount_read_only(&mp_list_head, changed);
-
end:
mount_points_list_free(&mp_list_head);
--
1.7.10.4

View File

@ -0,0 +1,81 @@
From 891a4918ef75fa81e22691156c050d061bd53dd3 Mon Sep 17 00:00:00 2001
From: Lennart Poettering <lennart@poettering.net>
Date: Fri, 16 Nov 2012 18:15:30 +0100
Subject: [PATCH] switch-root: try pivot_root() before overmounting /
We should always try to umount the old root dir if possible, instead of
overmounting it -- if that's possible.
The initial ("first") kernel rootfs can never be umounted, hence
for the usual nitrd case we never bothered using pivot_root() and
hence with fully unmounting it. However, fedup now tranisitions twice
during boot, and in that case it is highly desirable that the "second"
root dir is entirely unmounted when we switch to the "third". This patch
makes that possible.
The pivot_root() needs a directory in the "third" root dir, to move the
"second" root dir to. We use /mnt for that, under the assumption that
this directory is likely to exist, and is not itself a mount point.
---
src/core/switch-root.c | 27 ++++++++++++++++++++++++++-
1 file changed, 26 insertions(+), 1 deletion(-)
diff --git a/src/core/switch-root.c b/src/core/switch-root.c
index 150332a..ce0e41d 100644
--- a/src/core/switch-root.c
+++ b/src/core/switch-root.c
@@ -30,6 +30,7 @@
#include "util.h"
#include "path-util.h"
#include "switch-root.h"
+#include "missing.h"
int switch_root(const char *new_root) {
@@ -44,10 +45,21 @@ int switch_root(const char *new_root) {
struct stat new_root_stat;
bool old_root_remove;
const char *i;
+ _cleanup_free_ char *temporary_old_root = NULL;
if (path_equal(new_root, "/"))
return 0;
+ /* When using pivot_root() we assume that /mnt exists as place
+ * we can temporarily move the old root to. As we immediately
+ * unmount it from there it doesn't matter much which
+ * directory we choose for this, but it should be more likely
+ * than not that /mnt exists and is suitable as mount point
+ * and is on the same fs as the old root dir */
+ temporary_old_root = strappend(new_root, "/mnt");
+ if (!temporary_old_root)
+ return -ENOMEM;
+
old_root_remove = in_initrd();
if (stat(new_root, &new_root_stat) < 0) {
@@ -103,7 +115,20 @@ int switch_root(const char *new_root) {
log_warning("Failed to open root directory: %m");
}
- if (mount(new_root, "/", NULL, MS_MOVE, NULL) < 0) {
+ /* We first try a pivot_root() so that we can umount the old
+ * root dir. In many cases (i.e. where rootfs is /), that's
+ * not possible however, and hence we simply overmount root */
+ if (pivot_root(new_root, temporary_old_root) >= 0) {
+
+ /* Immediately get rid of the old root. Since we are
+ * running off it we need to do this lazily. */
+ if (umount2(temporary_old_root, MNT_DETACH) < 0) {
+ r = -errno;
+ log_error("Failed to umount old root dir %s: %m", temporary_old_root);
+ goto fail;
+ }
+
+ } else if (mount(new_root, "/", NULL, MS_MOVE, NULL) < 0) {
r = -errno;
log_error("Failed to mount moving %s to /: %m", new_root);
goto fail;
--
1.7.10.4

View File

@ -1,3 +1,11 @@
-------------------------------------------------------------------
Tue Nov 20 18:25:49 CET 2012 - fcrozat@suse.com
- Add remount-ro-before-unmount.patch: always remount read-only
before unmounting in final shutdown loop.
- Add switch-root-try-pivot-root.patch: try pivot_root before
overmounting /
-------------------------------------------------------------------
Tue Nov 20 09:36:43 UTC 2012 - fcrozat@suse.com

View File

@ -148,6 +148,10 @@ Patch66: fix-dbus-crash.patch
Patch67: sync-on-shutdown.patch
# PATCH-FIX-UPSTREAM mount-efivars.patch fcrozat@suse.com -- mount efivars if booting under UEFI
Patch68: mount-efivars.patch
# PATCH-FIX-UPSTREAM switch-root-try-pivot-root.patch fcrozat@suse.com -- try pivot_root before overmounting /
Patch69: switch-root-try-pivot-root.patch
# PATCH-FIX-UPSTREAM remount-ro-before-unmount.patch fcrozat@suse.com -- remount ro before unmounting in final shutdown loop
Patch70: remount-ro-before-unmount.patch
# udev patches
# PATCH-FIX-OPENSUSE 0001-Reinstate-TIMEOUT-handling.patch
@ -353,6 +357,8 @@ cp %{SOURCE7} m4/
%patch66 -p1
%patch67 -p1
%patch68 -p1
%patch69 -p1
%patch70 -p1
%build
autoreconf -fiv

View File

@ -1,3 +1,11 @@
-------------------------------------------------------------------
Tue Nov 20 18:25:49 CET 2012 - fcrozat@suse.com
- Add remount-ro-before-unmount.patch: always remount read-only
before unmounting in final shutdown loop.
- Add switch-root-try-pivot-root.patch: try pivot_root before
overmounting /
-------------------------------------------------------------------
Tue Nov 20 09:36:43 UTC 2012 - fcrozat@suse.com

View File

@ -143,6 +143,10 @@ Patch66: fix-dbus-crash.patch
Patch67: sync-on-shutdown.patch
# PATCH-FIX-UPSTREAM mount-efivars.patch fcrozat@suse.com -- mount efivars if booting under UEFI
Patch68: mount-efivars.patch
# PATCH-FIX-UPSTREAM switch-root-try-pivot-root.patch fcrozat@suse.com -- try pivot_root before overmounting /
Patch69: switch-root-try-pivot-root.patch
# PATCH-FIX-UPSTREAM remount-ro-before-unmount.patch fcrozat@suse.com -- remount ro before unmounting in final shutdown loop
Patch70: remount-ro-before-unmount.patch
# udev patches
# PATCH-FIX-OPENSUSE 0001-Reinstate-TIMEOUT-handling.patch
@ -348,6 +352,8 @@ cp %{SOURCE7} m4/
%patch66 -p1
%patch67 -p1
%patch68 -p1
%patch69 -p1
%patch70 -p1
%build
autoreconf -fiv