Merge branch 'f18'

This commit is contained in:
Lennart Poettering 2012-11-21 01:48:52 +01:00
commit 193cdfe6c1
5 changed files with 370 additions and 6 deletions

View File

@ -0,0 +1,120 @@
From 2b3509a898dcb65d6fba41f3c9cd484b00730017 Mon Sep 17 00:00:00 2001
From: Michal Schmidt <mschmidt@redhat.com>
Date: Thu, 15 Nov 2012 16:55:09 +0100
Subject: [PATCH] revert udev killing
revert of upstream commit 194bbe33382f5365be3865ed1779147cb680f1d3
---
src/udev/udevd.c | 32 ++++++++++++++++----------------
1 file changed, 16 insertions(+), 16 deletions(-)
diff --git a/src/udev/udevd.c b/src/udev/udevd.c
index ebd601e..53322b0 100644
--- a/src/udev/udevd.c
+++ b/src/udev/udevd.c
@@ -74,7 +74,6 @@ static int exec_delay;
static sigset_t sigmask_orig;
static UDEV_LIST(event_list);
static UDEV_LIST(worker_list);
-char *udev_cgroup;
static bool udev_exit;
enum event_state {
@@ -453,13 +452,22 @@ static int event_queue_insert(struct udev_device *dev)
return 0;
}
-static void worker_kill(struct udev *udev)
+static void worker_kill(struct udev *udev, int retain)
{
struct udev_list_node *loop;
+ int max;
+
+ if (children <= retain)
+ return;
+
+ max = children - retain;
udev_list_node_foreach(loop, &worker_list) {
struct worker *worker = node_to_worker(loop);
+ if (max-- <= 0)
+ break;
+
if (worker->state == WORKER_KILLED)
continue;
@@ -631,7 +639,7 @@ static struct udev_ctrl_connection *handle_ctrl_msg(struct udev_ctrl *uctrl)
log_debug("udevd message (SET_LOG_PRIORITY) received, log_priority=%i\n", i);
log_set_max_level(i);
udev_set_log_priority(udev, i);
- worker_kill(udev);
+ worker_kill(udev, 0);
}
if (udev_ctrl_get_stop_exec_queue(ctrl_msg) > 0) {
@@ -673,7 +681,7 @@ static struct udev_ctrl_connection *handle_ctrl_msg(struct udev_ctrl *uctrl)
}
free(key);
}
- worker_kill(udev);
+ worker_kill(udev, 0);
}
i = udev_ctrl_get_set_children_max(ctrl_msg);
@@ -1198,10 +1206,6 @@ int main(int argc, char *argv[])
rc = 3;
goto exit;
}
-
- /* get our own cgroup, we regularly kill everything udev has left behind */
- if (cg_get_by_pid(SYSTEMD_CGROUP_CONTROLLER, 0, &udev_cgroup) < 0)
- udev_cgroup = NULL;
} else {
/* open control and netlink socket */
udev_ctrl = udev_ctrl_new(udev);
@@ -1400,7 +1404,7 @@ int main(int argc, char *argv[])
/* discard queued events and kill workers */
event_queue_cleanup(udev, EVENT_QUEUED);
- worker_kill(udev);
+ worker_kill(udev, 0);
/* exit after all has cleaned up */
if (udev_list_node_is_empty(&event_list) && udev_list_node_is_empty(&worker_list))
@@ -1408,13 +1412,9 @@ int main(int argc, char *argv[])
/* timeout at exit for workers to finish */
timeout = 30 * 1000;
- } else if (udev_list_node_is_empty(&event_list) && !children) {
+ } else if (udev_list_node_is_empty(&event_list) && children <= 2) {
/* we are idle */
timeout = -1;
-
- /* cleanup possible left-over processes in our cgroup */
- if (udev_cgroup)
- cg_kill(SYSTEMD_CGROUP_CONTROLLER, udev_cgroup, SIGKILL, false, true, NULL);
} else {
/* kill idle or hanging workers */
timeout = 3 * 1000;
@@ -1435,7 +1435,7 @@ int main(int argc, char *argv[])
/* kill idle workers */
if (udev_list_node_is_empty(&event_list)) {
log_debug("cleanup idle workers\n");
- worker_kill(udev);
+ worker_kill(udev, 2);
}
/* check for hanging events */
@@ -1490,7 +1490,7 @@ int main(int argc, char *argv[])
/* reload requested, HUP signal received, rules changed, builtin changed */
if (reload) {
- worker_kill(udev);
+ worker_kill(udev, 0);
rules = udev_rules_unref(rules);
udev_builtin_exit(udev);
reload = false;
--
1.7.11.7

View File

@ -0,0 +1,49 @@
From 0049f05a8bb82c3e084bacc5945596761d706c55 Mon Sep 17 00:00:00 2001
From: Lennart Poettering <lennart@poettering.net>
Date: Fri, 16 Nov 2012 01:30:29 +0100
Subject: [PATCH] shutdown: readd explicit sync() when shutting down
As it turns out reboot() doesn't actually imply a file system sync, but
only a disk sync. Accordingly, readd explicit sync() invocations
immediately before we invoke reboot().
This is much less dramatic than it might sounds as we umount all
disks/read-only remount them anyway before going down.
---
src/core/service.c | 1 +
src/core/shutdown.c | 7 +++++++
2 files changed, 8 insertions(+)
diff --git a/src/core/service.c b/src/core/service.c
index cf08485..df72aba 100644
--- a/src/core/service.c
+++ b/src/core/service.c
@@ -2485,6 +2485,7 @@ static int service_start_limit_test(Service *s) {
case SERVICE_START_LIMIT_REBOOT_IMMEDIATE:
log_warning("%s start request repeated too quickly, rebooting immediately.", UNIT(s)->id);
+ sync();
reboot(RB_AUTOBOOT);
break;
diff --git a/src/core/shutdown.c b/src/core/shutdown.c
index cc8c57b..b59aef1 100644
--- a/src/core/shutdown.c
+++ b/src/core/shutdown.c
@@ -273,6 +273,13 @@ int main(int argc, char *argv[]) {
}
}
+ /* The kernel will automaticall flush ATA disks and suchlike
+ * on reboot(), but the file systems need to be synce'd
+ * explicitly in advance. So let's do this here, but not
+ * needlessly slow down containers. */
+ if (!in_container)
+ sync();
+
if (cmd == LINUX_REBOOT_CMD_KEXEC) {
if (!in_container) {
--
1.7.12.1

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.12.1

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.12.1

View File

@ -22,7 +22,7 @@ Url: http://www.freedesktop.org/wiki/Software/systemd
# THIS PACKAGE FOR A NON-RAWHIDE DEVELOPMENT DISTRIBUTION!
Version: 195
Release: 6%{?gitcommit:.git%{gitcommit}}%{?dist}
Release: 8%{?gitcommit:.git%{gitcommit}}%{?dist}
# For a breakdown of the licensing, see README
License: LGPLv2+ and MIT and GPLv2+
Summary: A System and Service Manager
@ -88,6 +88,13 @@ Source6: yum-protect-systemd.conf
# Temporary workaround for build error https://bugzilla.redhat.com/show_bug.cgi?id=872638
Patch0: disable-broken-test-build.patch
# F18Beta blocker workaround: https://bugzilla.redhat.com/show_bug.cgi?id=873576
Patch1: 0001-revert-udev-killing.patch
# https://bugzilla.redhat.com/show_bug.cgi?id=873459
Patch2: 0001-shutdown-readd-explicit-sync-when-shutting-down.patch
Patch3: 0001-umount-always-remount-read-only-before-unmounting-in.patch
Patch4: 0001-switch-root-try-pivot_root-before-overmounting.patch
Obsoletes: SysVinit < 2.86-24, sysvinit < 2.86-24
Provides: SysVinit = 2.86-24, sysvinit = 2.86-24
@ -196,6 +203,10 @@ glib-based applications using libudev functionality.
%prep
%setup -q %{?gitcommit:-n %{name}-git%{gitcommit}}
%patch0 -p1
%patch1 -p1
%patch2 -p1
%patch3 -p1
%patch4 -p1
%build
%{?gitcommit: ./autogen.sh }
@ -415,7 +426,7 @@ if [ -e /etc/sysconfig/i18n -a ! -e /etc/locale.conf ]; then
unset LC_TELEPHONE
unset LC_MEASUREMENT
unset LC_IDENTIFICATION
. /etc/sysconfig/i18n 2>&1 || :
. /etc/sysconfig/i18n >/dev/null 2>&1 || :
[ -n "$LANG" ] && echo LANG=$LANG > /etc/locale.conf 2>&1 || :
[ -n "$LC_CTYPE" ] && echo LC_CTYPE=$LC_CTYPE >> /etc/locale.conf 2>&1 || :
[ -n "$LC_NUMERIC" ] && echo LC_NUMERIC=$LC_NUMERIC >> /etc/locale.conf 2>&1 || :
@ -437,8 +448,8 @@ if [ -e /etc/sysconfig/keyboard -a ! -e /etc/vconsole.conf ]; then
unset SYSFONTACM
unset UNIMAP
unset KEYMAP
[ -e /etc/sysconfig/i18n ] && . /etc/sysconfig/i18n 2>&1 || :
. /etc/sysconfig/keyboard 2>&1 || :
[ -e /etc/sysconfig/i18n ] && . /etc/sysconfig/i18n >/dev/null 2>&1 || :
. /etc/sysconfig/keyboard >/dev/null 2>&1 || :
[ -n "$SYSFONT" ] && echo FONT=$SYSFONT > /etc/vconsole.conf 2>&1 || :
[ -n "$SYSFONTACM" ] && echo FONT_MAP=$SYSFONTACM >> /etc/vconsole.conf 2>&1 || :
[ -n "$UNIMAP" ] && echo FONT_UNIMAP=$UNIMAP >> /etc/vconsole.conf 2>&1 || :
@ -450,10 +461,10 @@ fi
# Migrate HOSTNAME= from /etc/sysconfig/network
if [ -e /etc/sysconfig/network -a ! -e /etc/hostname ]; then
unset HOSTNAME
. /etc/sysconfig/network 2>&1 || :
. /etc/sysconfig/network >/dev/null 2>&1 || :
[ -n "$HOSTNAME" ] && echo $HOSTNAME > /etc/hostname 2>&1 || :
fi
/usr/bin/sed -i '/^HOSTNAME=/d' /etc/sysconfig/network 2>&1 || :
/usr/bin/sed -i '/^HOSTNAME=/d' /etc/sysconfig/network >/dev/null 2>&1 || :
%posttrans
# Convert old /etc/sysconfig/desktop settings
@ -707,6 +718,14 @@ fi
%{_libdir}/pkgconfig/gudev-1.0*
%changelog
* Tue Nov 20 2012 Lennart Poettering <lpoetter@redhat.com> - 195-8
- https://bugzilla.redhat.com/show_bug.cgi?id=873459
- https://bugzilla.redhat.com/show_bug.cgi?id=878093
* Thu Nov 15 2012 Michal Schmidt <mschmidt@redhat.com> - 195-7
- Revert udev killing cgroup patch for F18 Beta.
- https://bugzilla.redhat.com/show_bug.cgi?id=873576
* Fri Nov 09 2012 Michal Schmidt <mschmidt@redhat.com> - 195-6
- Fix cyclical dep between systemd and systemd-libs.
- Avoid broken build of test-journal-syslog.