Accepting request 178832 from Base:System

- assemble-EXCL-race.fix: avoid some races during
  array assembled- particularly at boot (bnc#793954)
- boot.md: make sure systemd-udev-trigger runs before
  boot.md to avoid races: bnc#793954
- mdmon@.service - new file plus patches to allow
  mdmon to be started by systemd, so it doesn't
  kill it (bnc#321366)

OBS-URL: https://build.opensuse.org/request/show/178832
OBS-URL: https://build.opensuse.org/package/show/openSUSE:Factory/mdadm?expand=0&rev=82
This commit is contained in:
Stephan Kulow 2013-06-18 08:33:48 +00:00 committed by Git OBS Bridge
commit 0c80e21f70
8 changed files with 356 additions and 3 deletions

View File

@ -0,0 +1,99 @@
References: bnc#821366
Git-commit: 0f7bdf8946316548500858303549e396655450c5
From: Jes Sorensen <Jes.Sorensen@redhat.com>
Date: Fri, 1 Feb 2013 16:15:18 +0100
Subject: [PATCH] Add support for launching mdmon via systemctl instead of
fork/exec
If launching mdmon via systemctl fails, we fall back to the old method
of fork/exec. This allows for having mdmon launched via systemctl
which avoids problems with it getting killed by systemd due to it
ending up in the parent's cgroup (udev).
Signed-off-by: Jes Sorensen <Jes.Sorensen@redhat.com>
Signed-off-by: NeilBrown <neilb@suse.de>
---
Makefile | 4 ++++
systemd/mdmon@.service | 18 ++++++++++++++++++
util.c | 28 ++++++++++++++++++++++++++++
3 files changed, 50 insertions(+)
create mode 100644 systemd/mdmon@.service
--- mdadm-3.2.6.orig/Makefile
+++ mdadm-3.2.6/Makefile
@@ -73,6 +73,7 @@ MAP_PATH = $(MAP_DIR)/$(MAP_FILE)
MDMON_DIR = $(MAP_DIR)
# place for autoreplace cookies
FAILED_SLOTS_DIR = /run/mdadm/failed-slots
+SYSTEMD_DIR=/lib/systemd/system
DIRFLAGS = -DMAP_DIR=\"$(MAP_DIR)\" -DMAP_FILE=\"$(MAP_FILE)\"
DIRFLAGS += -DMDMON_DIR=\"$(MDMON_DIR)\"
DIRFLAGS += -DFAILED_SLOTS_DIR=\"$(FAILED_SLOTS_DIR)\"
@@ -256,6 +257,9 @@ install-man: mdadm.8 md.4 mdadm.conf.5 m
install-udev: udev-md-raid.rules
$(INSTALL) -D -m 644 udev-md-raid.rules $(DESTDIR)/lib/udev/rules.d/64-md-raid.rules
+install-systemd: systemd/mdmon@.service
+ $(INSTALL) -D -m 644 systemd/mdmon@.service $(DESTDIR)$(SYSTEMD_DIR)/mdmon@.service
+
uninstall:
rm -f $(DESTDIR)$(MAN8DIR)/mdadm.8 $(DESTDIR)$(MAN8DIR)/mdmon.8 $(DESTDIR)$(MAN4DIR)/md.4 $(DESTDIR)$(MAN5DIR)/mdadm.conf.5 $(DESTDIR)$(BINDIR)/mdadm
--- /dev/null
+++ mdadm-3.2.6/systemd/mdmon@.service
@@ -0,0 +1,18 @@
+# This file is part of mdadm.
+#
+# mdadm is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+
+[Unit]
+Description=MD Metadata Monitor on /dev/%I
+DefaultDependencies=no
+Before=initrd-switch-root.target
+
+[Service]
+ExecStart=/sbin/mdmon %I
+StandardInput=null
+StandardOutput=null
+StandardError=null
+KillMode=none
--- mdadm-3.2.6.orig/util.c
+++ mdadm-3.2.6/util.c
@@ -1641,6 +1641,34 @@ int start_mdmon(int devnum)
} else
pathbuf[0] = '\0';
+ /* First try to run systemctl */
+ switch(fork()) {
+ case 0:
+ /* FIXME yuk. CLOSE_EXEC?? */
+ skipped = 0;
+ for (i = 3; skipped < 20; i++)
+ if (close(i) < 0)
+ skipped++;
+ else
+ skipped = 0;
+
+ snprintf(pathbuf, sizeof(pathbuf), "mdmon@%s.service",
+ devnum2devname(devnum));
+ status = execl("/usr/bin/systemctl", "systemctl", "start",
+ pathbuf, NULL);
+ status = execl("/bin/systemctl", "systemctl", "start",
+ pathbuf, NULL);
+ exit(1);
+ case -1: fprintf(stderr, Name ":cannot run mdmon. "
+ "Array remains readonly\n");
+ return -1;
+ default: /* parent - good */
+ pid = wait(&status);
+ if (pid >= 0 && status == 0)
+ return 0;
+ }
+
+ /* That failed, try running mdmon directly */
switch(fork()) {
case 0:
/* FIXME yuk. CLOSE_EXEC?? */

View File

@ -0,0 +1,28 @@
References: bnc#821366
Git-commit: 15c10423aa9435ed72bd292fecca69224a20fdc8
From: Jes Sorensen <Jes.Sorensen@redhat.com>
Date: Fri, 1 Feb 2013 16:15:19 +0100
Subject: [PATCH] In case launching mdmon fails, print an error message before
exiting
Signed-off-by: Jes Sorensen <Jes.Sorensen@redhat.com>
Signed-off-by: NeilBrown <neilb@suse.de>
---
util.c | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
--- mdadm-3.2.6.orig/util.c
+++ mdadm-3.2.6/util.c
@@ -1697,8 +1697,11 @@ int start_mdmon(int devnum)
return -1;
default: /* parent - good */
pid = wait(&status);
- if (pid < 0 || status != 0)
+ if (pid < 0 || status != 0) {
+ fprintf(stderr, Name ":failed to launch mdmon. "
+ "Array remains readonly\n");
return -1;
+ }
}
return 0;
}

View File

@ -0,0 +1,94 @@
References: bnc#821366
Git-commit: 030419821fb77f9955f2017b4a6d3d8139d6db25
From: NeilBrown <neilb@suse.de>
Date: Tue, 5 Feb 2013 15:57:09 +1100
Subject: [PATCH] mdmon: add --foreground option
While not strictly necessary for systemd, it is cleaner to avoid
forking when running from a management daemon. So add a --foreground
option to mdmon.
Signed-off-by: NeilBrown <neilb@suse.de>
---
mdmon.8 | 10 +++++++++-
mdmon.c | 9 +++++++--
systemd/mdmon@.service | 2 +-
3 files changed, 17 insertions(+), 4 deletions(-)
--- mdadm-3.2.6.orig/mdmon.8
+++ mdadm-3.2.6/mdmon.8
@@ -5,7 +5,7 @@ mdmon \- monitor MD external metadata ar
.SH SYNOPSIS
-.BI mdmon " [--all] [--takeover] [--offroot] CONTAINER"
+.BI mdmon " [--all] [--takeover] [--offroot] [--foreground] CONTAINER"
.SH OVERVIEW
The 2.6.27 kernel brings the ability to support external metadata arrays.
@@ -131,6 +131,14 @@ The
device to monitor. It can be a full path like /dev/md/container, or a
simple md device name like md127.
.TP
+.B \-\-foreground
+Normally,
+.I mdmon
+will fork and continue in the background. Adding this option will
+skip that step and run
+.I mdmon
+in the foreground.
+.TP
.B \-\-takeover
This instructs
.I mdmon
--- mdadm-3.2.6.orig/mdmon.c
+++ mdadm-3.2.6/mdmon.c
@@ -295,15 +295,17 @@ int main(int argc, char *argv[])
int opt;
int all = 0;
int takeover = 0;
+ int dofork = 1;
static struct option options[] = {
{"all", 0, NULL, 'a'},
{"takeover", 0, NULL, 't'},
{"help", 0, NULL, 'h'},
{"offroot", 0, NULL, OffRootOpt},
+ {"foreground", 0, NULL, 'F'},
{NULL, 0, NULL, 0}
};
- while ((opt = getopt_long(argc, argv, "tha", options, NULL)) != -1) {
+ while ((opt = getopt_long(argc, argv, "thaF", options, NULL)) != -1) {
switch (opt) {
case 'a':
container_name = argv[optind-1];
@@ -312,6 +314,9 @@ int main(int argc, char *argv[])
case 't':
takeover = 1;
break;
+ case 'F':
+ dofork = 0;
+ break;
case OffRootOpt:
argv[0][0] = '@';
break;
@@ -383,7 +388,7 @@ int main(int argc, char *argv[])
container_name);
exit(1);
}
- return mdmon(devname, devnum, do_fork(), takeover);
+ return mdmon(devname, devnum, dofork && do_fork(), takeover);
}
static int mdmon(char *devname, int devnum, int must_fork, int takeover)
--- mdadm-3.2.6.orig/systemd/mdmon@.service
+++ mdadm-3.2.6/systemd/mdmon@.service
@@ -11,7 +11,7 @@ DefaultDependencies=no
Before=initrd-switch-root.target
[Service]
-ExecStart=/sbin/mdmon %I
+ExecStart=/sbin/mdmon --foreground %I
StandardInput=null
StandardOutput=null
StandardError=null

View File

@ -0,0 +1,30 @@
References: bnc#821366
Git-commit: 701d5b4ab5ad72f8998d4398d5b209fea877ce37
From: NeilBrown <neilb@suse.de>
Date: Wed, 15 May 2013 11:10:54 +1000
Subject: [PATCH] Suppress error messages from systemctl.
We call systemctl to see if systemd will run mdmon for us.
If it cannot, we run mdmon directly, so we aren't interested
in the error message.
So redirect stderr to /dev/null.
Signed-off-by: NeilBrown <neilb@suse.de>
---
util.c | 5 +++++
1 file changed, 5 insertions(+)
--- mdadm-3.2.6.orig/util.c
+++ mdadm-3.2.6/util.c
@@ -1652,6 +1652,11 @@ int start_mdmon(int devnum)
else
skipped = 0;
+ /* Don't want to see error messages from systemctl.
+ * If the service doesn't exist, we start mdmon ourselves.
+ */
+ close(2);
+ open("/dev/null", O_WRONLY);
snprintf(pathbuf, sizeof(pathbuf), "mdmon@%s.service",
devnum2devname(devnum));
status = execl("/usr/bin/systemctl", "systemctl", "start",

74
assemble-EXCL-race.fix Normal file
View File

@ -0,0 +1,74 @@
From: NeilBrown <neilb@suse.de>
References: bnc#793954
If we get EBUSY when openning a device during ASSEMBLE,
try again a limited number of times as we could be racing with
"mdadm -I" from udev or similar.
This is fixed upstream by more intrusive locking changed.
Signed-off-by: NeilBrown <neilb@suse.de>
---
Assemble.c | 36 +++++++++++++++++++++++++++++-------
1 file changed, 29 insertions(+), 7 deletions(-)
--- mdadm-3.2.6.orig/Assemble.c
+++ mdadm-3.2.6/Assemble.c
@@ -494,7 +494,7 @@ int Assemble(struct supertype *st, char
tmpdev = NULL;
goto loop;
} else {
-
+ int cnt = 5;
content = &info;
tst->ss->getinfo_super(tst, content, NULL);
@@ -508,6 +508,13 @@ int Assemble(struct supertype *st, char
* be looking at
*/
dfd = dev_open(devname, O_RDONLY | O_EXCL);
+ while (dfd < 0 && errno == EBUSY && cnt > 0) {
+ fprintf(stderr, "EBUSY - retrying dev_open of %s\n",
+ devname);
+ usleep(200000);
+ dfd = dev_open(devname, O_RDONLY | O_EXCL);
+ cnt--;
+ }
if (dfd < 0) {
if (report_missmatch)
fprintf(stderr, Name ": %s is busy - skipping\n", devname);
@@ -1315,13 +1322,28 @@ int Assemble(struct supertype *st, char
j = chosen_drive;
if (j >= 0 /* && devices[j].uptodate */) {
- int dfd = dev_open(devices[j].devname,
- O_RDWR|O_EXCL);
- if (dfd >= 0) {
- remove_partitions(dfd);
- close(dfd);
+ int cnt = 5;
+ while (cnt > 0) {
+ int dfd = dev_open(devices[j].devname,
+ O_RDWR|O_EXCL);
+ cnt--;
+ if (dfd < 0 && errno == EBUSY) {
+ fprintf(stderr, "EBUSY - retrying open of %s\n",
+ devices[j].devname);
+ usleep(200000);
+ continue;
+ }
+ if (dfd >= 0) {
+ remove_partitions(dfd);
+ close(dfd);
+ }
+ rv = add_disk(mdfd, st, content, &devices[j].i);
+ if (rv == 0 || errno != EBUSY)
+ break;
+ fprintf(stderr, "EBUSY - retrying add of %s\n",
+ devices[j].devname);
+ usleep(200000);
}
- rv = add_disk(mdfd, st, content, &devices[j].i);
if (rv) {
fprintf(stderr, Name ": failed to add "

View File

@ -23,7 +23,7 @@
# Provides: boot.md
# Required-Start: boot.udev boot.rootfsck
# Required-Stop: $null
# Should-Start: boot.scsidev boot.multipath udev-trigger
# Should-Start: boot.scsidev boot.multipath systemd-udev-trigger
# Should-Stop: boot.scsidev boot.multipath
# Default-Start: B
# Default-Stop:

View File

@ -1,3 +1,14 @@
-------------------------------------------------------------------
Thu Jun 13 04:12:54 UTC 2013 - nfbrown@suse.com
- assemble-EXCL-race.fix: avoid some races during
array assembled- particularly at boot (bnc#793954)
- boot.md: make sure systemd-udev-trigger runs before
boot.md to avoid races: bnc#793954
- mdmon@.service - new file plus patches to allow
mdmon to be started by systemd, so it doesn't
kill it (bnc#321366)
-------------------------------------------------------------------
Tue Apr 16 10:38:19 UTC 2013 - idonmez@suse.com

View File

@ -20,6 +20,7 @@ Name: mdadm
Version: 3.2.6
Release: 0
BuildRequires: binutils-devel
BuildRequires: groff
BuildRequires: pkgconfig
BuildRequires: sgmltool
BuildRequires: pkgconfig(libudev)
@ -42,9 +43,19 @@ Source5: mkinitrd-setup.sh
Source6: mkinitrd-boot.sh
Source7: mdadm.cron
Source8: mdadm.shutdown
#PATCH-FIX-UPSTREAM assemble-EXCL-race.fix bnc#793954
Patch1: assemble-EXCL-race.fix
#PATCH-FIX-UPSTREAM 0001-Add-support-for-launching-mdmon-via-systemctl-instea.patch bnc#821366
Patch2: 0001-Add-support-for-launching-mdmon-via-systemctl-instea.patch
#PATCH-FIX-UPSTREAM 0002-In-case-launching-mdmon-fails-print-an-error-message.patch bnc#821366
Patch3: 0002-In-case-launching-mdmon-fails-print-an-error-message.patch
#PATCH-FIX-UPSTREAM 0003-mdmon-add-foreground-option.patch bnc#821366
Patch4: 0003-mdmon-add-foreground-option.patch
#PATCH-FIX-UPSTREAM 0004-Suppress-error-messages-from-systemctl.patch bnc#821366
Patch5: 0004-Suppress-error-messages-from-systemctl.patch
%define _udevrulesdir %(pkg-config --variable=udevdir udev)/rules.d
%define _systemdshutdowndir %{_unitdir}/../system-shutdown
%define _systemdshutdowndir %{_unitdir}/../system-shutdown
%description
Mdadm is a program that can be used to control Linux md devices. It is
@ -53,6 +64,11 @@ programs but with a very different interface.
%prep
%setup -q -a1
%patch1 -p1
%patch2 -p1
%patch3 -p1
%patch4 -p1
%patch5 -p1
%build
make %{?_smp_mflags} CC="%__cc" CXFLAGS="$RPM_OPT_FLAGS -Wno-error"
@ -61,7 +77,7 @@ sgml2html Software-RAID.HOWTO.sgml
sgml2txt Software-RAID.HOWTO.sgml
%install
make install DESTDIR=%{buildroot}
make install install-systemd DESTDIR=%{buildroot} SYSTEMD_DIR=%{_unitdir}
rm -rf %{buildroot}/lib/udev
install -d %{buildroot}%{_var}/adm/fillup-templates
install -d %{buildroot}{%{_sbindir},%{_sysconfdir}/init.d}
@ -125,5 +141,6 @@ rm -rf %{buildroot}
%dir /etc/cron.daily
/etc/cron.daily/mdadm
%{_systemdshutdowndir}/mdadm.shutdown
%{_unitdir}/mdmon@.service
%changelog