Sisyphus repository
Last update: 1 october 2023 | SRPMs: 18631 | Visits: 37560889
en ru br
ALT Linux repos
S:4.2-alt3
5.0: 2.6.3-alt1
4.1: 2.6.3-alt1
4.0: 2.6.1-alt3.1
3.0: 1.12.0-alt2

Group :: System/Configuration/Hardware
RPM: mdadm

 Main   Changelog   Spec   Patches   Sources   Download   Gear   Bugs and FR  Repocop 

Patch: mdadm-4.2.patch
Download


 .gear/rules                                        |   2 +
 .../tags/91f21b2745717d306b5b59e4508bb4d371e4c3b6  |  23 +
 .gear/tags/list                                    |   1 +
 .gear/upstream/remotes                             |   3 +
 .gitignore                                         |   1 +
 Assemble.c                                         |   6 +-
 Build.c                                            |  23 +-
 Create.c                                           |  67 +-
 Detail.c                                           |   4 +-
 Grow.c                                             |  30 +-
 Makefile                                           |   9 +-
 Monitor.c                                          |   5 +-
 Query.c                                            |   6 +-
 ReadMe.c                                           |  11 +-
 alt/README.recipes                                 | 149 ++++
 alt/checkarray                                     | 210 ++++++
 alt/mdadm.conf                                     |  14 +
 alt/mdadm.crond                                    |  11 +
 alt/mdadm.init                                     |  75 ++
 alt/mdadm.service                                  |  11 +
 alt/mdadm.sysconfig                                |   3 +
 alt/raidtabtomdadm.sh                              |  30 +
 managemon.c                                        |   1 -
 maps.c                                             |  24 +
 mdadm.8.in                                         |  53 +-
 mdadm.c                                            |  38 +-
 mdadm.conf.5                                       | 706 -------------------
 mdadm.conf.5.in                                    | 776 +++++++++++++++++++++
 mdadm.h                                            |  25 +-
 mdadm.spec                                         | 343 ++++++++-
 mdmon.c                                            |   1 -
 monitor.c                                          |   1 -
 probe_roms.c                                       |   6 +-
 raid6check.c                                       |  25 +-
 super-ddf.c                                        |   6 +-
 super-intel.c                                      |   9 +-
 super0.c                                           |   2 +-
 super1.c                                           |   2 +-
 sysfs.c                                            |   9 +-
 systemd/mdadm-grow-continue@.service               |   1 -
 systemd/mdmon.service                              |  10 +
 systemd/mdmonitor.service                          |   6 +-
 udev-md-raid-arrays.rules                          |   8 +-
 udev-md-raid-assembly.rules                        |   5 +-
 udev-md-raid-safe-timeouts.rules                   |   2 +-
 util.c                                             |   1 -
 46 files changed, 1857 insertions(+), 897 deletions(-)
diff --git a/.gear/rules b/.gear/rules
new file mode 100644
index 00000000..436d6606
--- /dev/null
+++ b/.gear/rules
@@ -0,0 +1,2 @@
+tar: @name@-@version@:.
+diff: @name@-@version@:. . name=@name@-@version@.patch
diff --git a/.gear/tags/91f21b2745717d306b5b59e4508bb4d371e4c3b6 b/.gear/tags/91f21b2745717d306b5b59e4508bb4d371e4c3b6
new file mode 100644
index 00000000..d0d10c09
--- /dev/null
+++ b/.gear/tags/91f21b2745717d306b5b59e4508bb4d371e4c3b6
@@ -0,0 +1,23 @@
+object e30ca260741d727e6f444e8f2ce25fe7a5a26567
+type commit
+tag mdadm-4.2
+tagger Jes Sorensen <jsorensen@fb.com> 1640893427 -0500
+
+Release mdadm-4.2
+-----BEGIN PGP SIGNATURE-----
+
+iQJFBAABCAAvFiEEaoa4Dh0i8h0LJrp1OX2C4FManJEFAmHOC/cRHGpzb3JlbnNl
+bkBmYi5jb20ACgkQOX2C4FManJEIVg/8DU/wZmkdHWVwoWu8UlJrob9IT4rL54Rv
+8jAHiQr9iRjCA6A9QDVB3FhMYhFa9335JoRFRvf1oP8dJm8u77o3ZYR0Sx9Xzd4L
+Nkbcm9PO+x+hErgP008VB9lgRUrImbFnfYd0+cuEHl90yZx0JTptDG1HwccCFkoW
+5+S8ewVedv4zABg5McLtO1p9EivpRWO6q4COlxB9xmKUVF/XxRgNwOOD1P+U6DIu
+PQmQk/C9gWSVAi42TphDuzi09aTb2rmyhWZcESymcevWKvHTOGE9uAopBriIDNmg
+ClP/G4o4mFE/LEY3OywneWEXjm+G2wgnODmS7vJ2pgdhj9bNuFvOtXz5Q/HhMP+b
+x3DYj2i5q6JO06sNWfK8WikMBkWTO++MLKIf51a7k9/X4KWVYSJJmdq3pz9woCJM
+3vu9Dnt70PhkxMrJBmPKXcCcr1sLYnbZC320kuwY+xM3sLAri9Jp3jWdASWMh+/O
+f3niJNzMtWxSoOKwg9N7VXVYGcNZF+JGltdJUd+hl8GPz6bXR+wv79RnoUVTlb9N
+N2xpO3K1OQYjVrMcHgE4b35FyTpm8i0OSSGaFw6kdh2ZW1PsI+A/DEREXcpRqnFz
+FPLa4+SrlPBLoFdZIvxm4GZTzuqXhOH1+ZATz5NUrmQl3+PebtDLQMkZ0J55VZXt
+2WH5DeYYhz4=
+=4isn
+-----END PGP SIGNATURE-----
diff --git a/.gear/tags/list b/.gear/tags/list
new file mode 100644
index 00000000..10afd958
--- /dev/null
+++ b/.gear/tags/list
@@ -0,0 +1 @@
+91f21b2745717d306b5b59e4508bb4d371e4c3b6 mdadm-4.2
diff --git a/.gear/upstream/remotes b/.gear/upstream/remotes
new file mode 100644
index 00000000..374c3c76
--- /dev/null
+++ b/.gear/upstream/remotes
@@ -0,0 +1,3 @@
+[remote "upstream"]
+	url = https://git.kernel.org/pub/scm/utils/mdadm/mdadm.git
+	fetch = +refs/heads/*:refs/remotes/upstream/*
diff --git a/.gitignore b/.gitignore
index 217fe76d..8d791c6f 100644
--- a/.gitignore
+++ b/.gitignore
@@ -3,6 +3,7 @@
 /*-stamp
 /mdadm
 /mdadm.8
+/mdadm.conf.5
 /mdadm.udeb
 /mdassemble
 /mdmon
diff --git a/Assemble.c b/Assemble.c
index 704b8293..9eac9ce0 100644
--- a/Assemble.c
+++ b/Assemble.c
@@ -63,7 +63,7 @@ static void set_array_assembly_status(struct context *c,
 				   struct assembly_array_info *arr)
 {
 	int raid_disks = arr->preexist_cnt + arr->new_cnt;
-	char *status_msg = map_num(assemble_statuses, status);
+	char *status_msg = map_num_s(assemble_statuses, status);
 
 	if (c->export && result)
 		*result |= status;
@@ -77,9 +77,7 @@ static void set_array_assembly_status(struct context *c,
 		fprintf(stderr, " (%d new)", arr->new_cnt);
 	if (arr->exp_cnt)
 		fprintf(stderr, " ( + %d for expansion)", arr->exp_cnt);
-	if (status_msg)
-		fprintf(stderr, " %s", status_msg);
-	fprintf(stderr, ".\n");
+	fprintf(stderr, " %s.\n", status_msg);
 }
 
 static int name_matches(char *found, char *required, char *homehost, int require_homehost)
diff --git a/Build.c b/Build.c
index 962c2e37..8d6f6f58 100644
--- a/Build.c
+++ b/Build.c
@@ -71,28 +71,7 @@ int Build(char *mddev, struct mddev_dev *devlist,
 	}
 
 	if (s->layout == UnSet)
-		switch(s->level) {
-		default: /* no layout */
-			s->layout = 0;
-			break;
-		case 10:
-			s->layout = 0x102; /* near=2, far=1 */
-			if (c->verbose > 0)
-				pr_err("layout defaults to n1\n");
-			break;
-		case 5:
-		case 6:
-			s->layout = map_name(r5layout, "default");
-			if (c->verbose > 0)
-				pr_err("layout defaults to %s\n", map_num(r5layout, s->layout));
-			break;
-		case LEVEL_FAULTY:
-			s->layout = map_name(faultylayout, "default");
-
-			if (c->verbose > 0)
-				pr_err("layout defaults to %s\n", map_num(faultylayout, s->layout));
-			break;
-		}
+		s->layout = default_layout(NULL, s->level, c->verbose);
 
 	/* We need to create the device.  It can have no name. */
 	map_lock(&map);
diff --git a/Create.c b/Create.c
index 0ff1922d..c84c1ac8 100644
--- a/Create.c
+++ b/Create.c
@@ -39,39 +39,54 @@ static int round_size_and_verify(unsigned long long *size, int chunk)
 	return 0;
 }
 
-static int default_layout(struct supertype *st, int level, int verbose)
+/**
+ * default_layout() - Get default layout for level.
+ * @st: metadata requested, could be NULL.
+ * @level: raid level requested.
+ * @verbose: verbose level.
+ *
+ * Try to ask metadata handler first, otherwise use global defaults.
+ *
+ * Return: Layout or &UnSet, return value meaning depends of level used.
+ */
+int default_layout(struct supertype *st, int level, int verbose)
 {
 	int layout = UnSet;
+	mapping_t *layout_map = NULL;
+	char *layout_name = NULL;
 
 	if (st && st->ss->default_geometry)
 		st->ss->default_geometry(st, &level, &layout, NULL);
 
-	if (layout == UnSet)
-		switch(level) {
-		default: /* no layout */
-			layout = 0;
-			break;
-		case 0:
-			layout = RAID0_ORIG_LAYOUT;
-			break;
-		case 10:
-			layout = 0x102; /* near=2, far=1 */
-			if (verbose > 0)
-				pr_err("layout defaults to n2\n");
-			break;
-		case 5:
-		case 6:
-			layout = map_name(r5layout, "default");
-			if (verbose > 0)
-				pr_err("layout defaults to %s\n", map_num(r5layout, layout));
-			break;
-		case LEVEL_FAULTY:
-			layout = map_name(faultylayout, "default");
+	if (layout != UnSet)
+		return layout;
 
-			if (verbose > 0)
-				pr_err("layout defaults to %s\n", map_num(faultylayout, layout));
-			break;
-		}
+	switch (level) {
+	default: /* no layout */
+		layout = 0;
+		break;
+	case 0:
+		layout = RAID0_ORIG_LAYOUT;
+		break;
+	case 10:
+		layout = 0x102; /* near=2, far=1 */
+		layout_name = "n2";
+		break;
+	case 5:
+	case 6:
+		layout_map = r5layout;
+		break;
+	case LEVEL_FAULTY:
+		layout_map = faultylayout;
+		break;
+	}
+
+	if (layout_map) {
+		layout = map_name(layout_map, "default");
+		layout_name = map_num_s(layout_map, layout);
+	}
+	if (layout_name && verbose > 0)
+		pr_err("layout defaults to %s\n", layout_name);
 
 	return layout;
 }
diff --git a/Detail.c b/Detail.c
index 95d4cc70..ce7a8445 100644
--- a/Detail.c
+++ b/Detail.c
@@ -495,8 +495,8 @@ int Detail(char *dev, struct context *c)
 			if (array.state & (1 << MD_SB_CLEAN)) {
 				if ((array.level == 0) ||
 				    (array.level == LEVEL_LINEAR))
-					arrayst = map_num(sysfs_array_states,
-							  sra->array_state);
+					arrayst = map_num_s(sysfs_array_states,
+							       sra->array_state);
 				else
 					arrayst = "clean";
 			} else {
diff --git a/Grow.c b/Grow.c
index 9c6fc95e..8a242b0f 100644
--- a/Grow.c
+++ b/Grow.c
@@ -26,7 +26,6 @@
 #include	<sys/mman.h>
 #include	<stddef.h>
 #include	<stdint.h>
-#include	<signal.h>
 #include	<sys/wait.h>
 
 #if ! defined(__BIG_ENDIAN) && ! defined(__LITTLE_ENDIAN)
@@ -548,7 +547,7 @@ int Grow_consistency_policy(char *devname, int fd, struct context *c, struct sha
 	if (s->consistency_policy != CONSISTENCY_POLICY_RESYNC &&
 	    s->consistency_policy != CONSISTENCY_POLICY_PPL) {
 		pr_err("Operation not supported for consistency policy %s\n",
-		       map_num(consistency_policies, s->consistency_policy));
+		       map_num_s(consistency_policies, s->consistency_policy));
 		return 1;
 	}
 
@@ -579,14 +578,14 @@ int Grow_consistency_policy(char *devname, int fd, struct context *c, struct sha
 
 	if (sra->consistency_policy == (unsigned)s->consistency_policy) {
 		pr_err("Consistency policy is already %s\n",
-		       map_num(consistency_policies, s->consistency_policy));
+		       map_num_s(consistency_policies, s->consistency_policy));
 		ret = 1;
 		goto free_info;
 	} else if (sra->consistency_policy != CONSISTENCY_POLICY_RESYNC &&
 		   sra->consistency_policy != CONSISTENCY_POLICY_PPL) {
 		pr_err("Current consistency policy is %s, cannot change to %s\n",
-		       map_num(consistency_policies, sra->consistency_policy),
-		       map_num(consistency_policies, s->consistency_policy));
+		       map_num_s(consistency_policies, sra->consistency_policy),
+		       map_num_s(consistency_policies, s->consistency_policy));
 		ret = 1;
 		goto free_info;
 	}
@@ -705,8 +704,8 @@ int Grow_consistency_policy(char *devname, int fd, struct context *c, struct sha
 	}
 
 	ret = sysfs_set_str(sra, NULL, "consistency_policy",
-			    map_num(consistency_policies,
-				    s->consistency_policy));
+			    map_num_s(consistency_policies,
+					 s->consistency_policy));
 	if (ret)
 		pr_err("Failed to change array consistency policy\n");
 
@@ -1001,8 +1000,8 @@ int remove_disks_for_takeover(struct supertype *st,
 				rv = 1;
 			sysfs_free(arrays);
 			if (rv) {
-				pr_err("Error. Cannot perform operation on /dev/%s\n", st->devnm);
-				pr_err("For this operation it MUST be single array in container\n");
+				pr_err("Error. Cannot perform operation on %s- for this operation "
+				       "it MUST be single array in container\n", st->devnm);
 				return rv;
 			}
 		}
@@ -1998,6 +1997,12 @@ int Grow_reshape(char *devname, int fd,
 			goto release;
 		}
 
+		if (array.level == 0) {
+			pr_err("Component size change is not supported for RAID0\n");
+			rv = 1;
+			goto release;
+		}
+
 		if (reshape_super(st, s->size, UnSet, UnSet, 0, 0, UnSet, NULL,
 				  devname, APPLY_METADATA_CHANGES,
 				  c->verbose > 0)) {
@@ -2236,7 +2241,7 @@ size_change_error:
 		info.new_layout = UnSet;
 		if (info.array.level == 6 && info.new_level == UnSet) {
 			char l[40], *h;
-			strcpy(l, map_num(r6layout, info.array.layout));
+			strcpy(l, map_num_s(r6layout, info.array.layout));
 			h = strrchr(l, '-');
 			if (h && strcmp(h, "-6") == 0) {
 				*h = 0;
@@ -2261,7 +2266,7 @@ size_change_error:
 			info.new_layout = info.array.layout;
 		else if (info.array.level == 5 && info.new_level == 6) {
 			char l[40];
-			strcpy(l, map_num(r5layout, info.array.layout));
+			strcpy(l, map_num_s(r5layout, info.array.layout));
 			strcat(l, "-6");
 			info.new_layout = map_name(r6layout, l);
 		} else {
@@ -3560,7 +3565,8 @@ started:
 		fd = -1;
 	mlockall(MCL_FUTURE);
 
-	signal(SIGTERM, catch_term);
+	if (signal_s(SIGTERM, catch_term) == SIG_ERR)
+		goto release;
 
 	if (st->ss->external) {
 		/* metadata handler takes it from here */
diff --git a/Makefile b/Makefile
index 2a51d813..7cfb9bc0 100644
--- a/Makefile
+++ b/Makefile
@@ -227,7 +227,12 @@ raid6check : raid6check.o mdadm.h $(CHECK_OBJS)
 
 mdadm.8 : mdadm.8.in
 	sed -e 's/{DEFAULT_METADATA}/$(DEFAULT_METADATA)/g' \
-	-e 's,{MAP_PATH},$(MAP_PATH),g'  mdadm.8.in > mdadm.8
+	-e 's,{MAP_PATH},$(MAP_PATH),g' -e 's,{CONFFILE},$(CONFFILE),g' \
+	-e 's,{CONFFILE2},$(CONFFILE2),g'  mdadm.8.in > mdadm.8
+
+mdadm.conf.5 : mdadm.conf.5.in
+	sed -e 's,{CONFFILE},$(CONFFILE),g' \
+	-e 's,{CONFFILE2},$(CONFFILE2),g'  mdadm.conf.5.in > mdadm.conf.5
 
 mdadm.man : mdadm.8
 	man -l mdadm.8 > mdadm.man
@@ -286,7 +291,7 @@ install-systemd: systemd/mdmon@.service
 		mdcheck_start.timer mdcheck_start.service \
 		mdcheck_continue.timer mdcheck_continue.service \
 		mdmonitor-oneshot.timer mdmonitor-oneshot.service \
-		; \
+		mdmon.service; \
 	do sed -e 's,BINDIR,$(BINDIR),g' systemd/$$file > .install.tmp.2 && \
 	   $(ECHO) $(INSTALL) -D -m 644 systemd/$$file $(DESTDIR)$(SYSTEMD_DIR)/$$file ; \
 	   $(INSTALL) -D -m 644 .install.tmp.2 $(DESTDIR)$(SYSTEMD_DIR)/$$file ; \
diff --git a/Monitor.c b/Monitor.c
index 30c031a2..c0ab5412 100644
--- a/Monitor.c
+++ b/Monitor.c
@@ -26,7 +26,6 @@
 #include	"md_p.h"
 #include	"md_u.h"
 #include	<sys/wait.h>
-#include	<signal.h>
 #include	<limits.h>
 #include	<syslog.h>
 #ifndef NO_LIBUDEV
@@ -435,8 +434,10 @@ static void alert(char *event, char *dev, char *disc, struct alert_info *info)
 		if (mp) {
 			FILE *mdstat;
 			char hname[256];
+
 			gethostname(hname, sizeof(hname));
-			signal(SIGPIPE, SIG_IGN);
+			signal_s(SIGPIPE, SIG_IGN);
+
 			if (info->mailfrom)
 				fprintf(mp, "From: %s\n", info->mailfrom);
 			else
diff --git a/Query.c b/Query.c
index 23fbf8aa..e6da6ae7 100644
--- a/Query.c
+++ b/Query.c
@@ -39,7 +39,7 @@ int Query(char *dev)
 	struct mdinfo info;
 	struct mdinfo *sra;
 	struct supertype *st = NULL;
-	unsigned long long larray_size;
+	unsigned long long larray_size = 0;
 	struct stat stb;
 	char *mddev;
 	mdu_disk_info_t disc;
@@ -93,7 +93,7 @@ int Query(char *dev)
 	else {
 		printf("%s: %s %s %d devices, %d spare%s. Use mdadm --detail for more detail.\n",
 		       dev, human_size_brief(larray_size,IEC),
-		       map_num(pers, level), raid_disks,
+		       map_num_s(pers, level), raid_disks,
 		       spare_disks, spare_disks == 1 ? "" : "s");
 	}
 	st = guess_super(fd);
@@ -131,7 +131,7 @@ int Query(char *dev)
 		       dev,
 		       info.disk.number, info.array.raid_disks,
 		       activity,
-		       map_num(pers, info.array.level),
+		       map_num_s(pers, info.array.level),
 		       mddev);
 		if (st->ss == &super0)
 			put_md_name(mddev);
diff --git a/ReadMe.c b/ReadMe.c
index 81399765..8f873c48 100644
--- a/ReadMe.c
+++ b/ReadMe.c
@@ -613,7 +613,6 @@ char Help_incr[] =
 ;
 
 char Help_config[] =
-"The /etc/mdadm.conf config file:\n\n"
 " The config file contains, apart from blank lines and comment lines that\n"
 " start with a hash(#), array lines, device lines, and various\n"
 " configuration lines.\n"
@@ -636,10 +635,12 @@ char Help_config[] =
 " than a device must match all of them to be considered.\n"
 "\n"
 " Other configuration lines include:\n"
-"  mailaddr, mailfrom, program     used for --monitor mode\n"
-"  create, auto                    used when creating device names in /dev\n"
-"  homehost, policy, part-policy   used to guide policy in various\n"
-"                                  situations\n"
+"  mailaddr, mailfrom, program, monitordelay    used for --monitor mode\n"
+"  create, auto                                 used when creating device names in /dev\n"
+"  homehost, homecluster, policy, part-policy   used to guide policy in various\n"
+"                                               situations\n"
+"\n"
+"For more details see mdadm.conf(5).\n"
 "\n"
 ;
 
diff --git a/alt/README.recipes b/alt/README.recipes
new file mode 100644
index 00000000..2b1891e0
--- /dev/null
+++ b/alt/README.recipes
@@ -0,0 +1,149 @@
+mdadm recipes
+=============
+
+The following examples/recipes may help you with your mdadm experience. I'll
+leave it as an exercise to use the correct device names and parameters in each
+case. You can find pointers to additional documentation in the README.Debian
+file.
+
+Enjoy. Submissions welcome.
+
+The latest version of this document is available here:
+  http://git.debian.org/?p=pkg-mdadm/mdadm.git;a=blob;f=debian/README.recipes;hb=HEAD
+
+0. create a new array
+~~~~~~~~~~~~~~~~~~~~~
+    mdadm --create -l1 -n2 -x1 /dev/md0 /dev/sd[abc]1   # RAID 1, 1 spare
+    mdadm --create -l5 -n3 -x1 /dev/md0 /dev/sd[abcd]1  # RAID 5, 1 spare
+    mdadm --create -l6 -n4 -x1 /dev/md0 /dev/sd[abcde]1 # RAID 6, 1 spare
+
+1. create a degraded array
+~~~~~~~~~~~~~~~~~~~~~~~~~~
+    mdadm --create -l5 -n3 /dev/md0 /dev/sda1 missing /dev/sdb1
+    mdadm --create -l6 -n4 /dev/md0 /dev/sda1 missing /dev/sdb1 missing
+
+2. assemble an existing array
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+    mdadm --assemble --auto=yes /dev/md0 /dev/sd[abc]1
+
+    # if the array is degraded, it won't be started. use --run:
+    mdadm --assemble --auto=yes --run /dev/md0 /dev/sd[ab]1
+
+    # or start it by hand:
+    mdadm --run /dev/md0
+
+3. assemble all arrays in /etc/mdadm/mdadm.conf
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+    mdadm --assemble --auto=yes --scan
+
+4. assemble a dirty degraded array
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+    mdadm --assemble --auto=yes --force /dev/md0 /dev/sd[ab]1
+    mdadm --run /dev/md0
+
+4b. assemble a dirty degraded array at boot-time
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+    If the array is started at boot time by the kernel (partition type 0xfd),
+    you can force-assemble it by passing the kernel boot parameter
+
+      md-mod.start_dirty_degraded=1
+
+5. stop arrays
+~~~~~~~~~~~~~~
+    mdadm --stop /dev/md0
+
+    # to stop all arrays in /etc/mdadm/mdadm.conf
+    mdadm --stop --scan
+
+6. hot-add components
+~~~~~~~~~~~~~~~~~~~~~
+    # on the running array:
+    mdadm --add /dev/md0 /dev/sdc1
+    # if you add more components than the array was setup with, additional
+    # components will be spares
+
+7. hot-remove components
+~~~~~~~~~~~~~~~~~~~~~~~~
+    # on the running array:
+    mdadm --fail /dev/md0 /dev/sdb1
+    # if you have configured spares, watch /proc/mdstat how it fills in
+    mdadm --remove /dev/md0 /dev/sdb1
+
+8. hot-grow a RAID1 by adding new components
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+    # on the running array, in either order:
+    mdadm --grow -n3 /dev/md0
+    mdadm --add /dev/md0 /dev/sdc1
+    # note: without growing first, additional devices become spares and are
+    # *not* synchronised after the add.
+
+9. hot-shrink a RAID1 by removing components
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+    mdadm --fail /dev/md0 /dev/sdc1
+    mdadm --remove /dev/md0 /dev/sdc1
+    mdadm --grow -n2 /dev/md0
+
+10. convert existing filesystem to RAID 1
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+    # The idea is to create a degraded RAID 1 on the second partition, move
+    # data, then hot add the first. This seems safer to me than simply to
+    # force-add a superblock to the existing filesystem.
+    #
+    # Assume /dev/sda1 holds the data (and let's assume it's mounted on
+    # /home) and /dev/sdb1 is empty and of the same size...
+    #
+    mdadm --create /dev/md0 -l1 -n2 /dev/sdb1 missing
+    mkfs -t <type> /dev/md0
+    mount /dev/md0 /mnt
+    tar -cf- -C /home . | tar -xf- -C /mnt -p
+    # consider verifying the data
+    umount /home
+    umount /mnt
+    mount /dev/md0 /home    # also change /etc/fstab
+    mdadm --add /dev/md0 /dev/sda1
+
+    Warren Togami has a document explaining how to convert a filesystem on
+    a remote system via SSH: http://togami.com/~warren/guides/remoteraidcrazies/
+
+10b. convert existing filesystem to RAID 1 in-place
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+    In-place conversion of /dev/sda1 to /dev/md0 is effectively
+      mdadm --create /dev/md0 -l1 -n2 /dev/sda1 missing
+    however, do NOT do this, as you risk filesystem corruption.
+
+    If you need to do this, first unmount and shrink the filesystem by
+    a megabyte (if supported). Then run the above command, then (optionally)
+    again grow the filesystem as much as possible.
+
+    Do make sure you have backups. If you do not yet, consider method (10)
+    instead (and make backups anyway!).
+
+11. convert existing filesystem to RAID 5/6
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+    # See (10) for the basics.
+    mdadm --create /dev/md0 -l5 -n3 /dev/sdb1 /dev/sdc1 missing
+    #mdadm --create /dev/md0 -l6 -n4 /dev/sdb1 /dev/sdc1 /dev/sdd1 missing
+    mkfs -t <type> /dev/md0
+    mount /dev/md0 /mnt
+    tar -cf- -C /home . | tar -xf- -C /mnt -p
+    # consider verifying the data
+    umount /home
+    umount /mnt
+    mount /dev/md0 /home    # also change /etc/fstab
+    mdadm --add /dev/md0 /dev/sda1
+
+12. change the preferred minor of an MD array (RAID)
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+    # you need to manually assemble the array to change the preferred minor
+    # if you manually assemble, the superblock will be updated to reflect
+    # the preferred minor as you indicate with the assembly.
+    # for example, to set the preferred minor to 4:
+    mdadm --assemble /dev/md4 /dev/sd[abc]1
+
+    # this only works on 2.6 kernels, and only for RAID levels of 1 and above.
+    # for other MD arrays, you need to specify --update explicitly:
+    mdadm --assemble --update=super-minor /dev/md4 /dev/sd[abc]1
+
+    # see also item 12 in the FAQ contained with the Debian package.
+
+ -- martin f. krafft <madduck@debian.org>  Fri, 06 Oct 2006 15:39:58 +0200
diff --git a/alt/checkarray b/alt/checkarray
new file mode 100755
index 00000000..9d2217a1
--- /dev/null
+++ b/alt/checkarray
@@ -0,0 +1,210 @@
+#!/bin/sh
+#
+# checkarray -- initiates a check run of an MD array's redundancy information.
+#
+# Copyright © martin f. krafft <madduck@debian.org>
+# distributed under the terms of the Artistic Licence 2.0
+#
+set -eu
+
+PROGNAME=${0##*/}
+
+about()
+{
+  echo "$PROGNAME -- MD array (RAID) redundancy checker tool"
+  echo "Copyright © martin f. krafft <madduck@debian.org>"
+  echo "Copyright © Vitaly Kuznetsov <vitty@altlinux.org>"
+  echo "Released under the terms of the Artistic Licence 2.0"
+}
+
+usage()
+{
+  about
+  echo
+  echo "Usage: $PROGNAME [options] [arrays]"
+  echo
+  echo "Valid options are:"
+  cat <<-_eof | column -s\& -t
+	-a|--all & check all assembled arrays (check /proc/mdstat).
+	-s|--status & print redundancy check status of devices.
+	-x|--cancel & queue a request to cancel a running redundancy check.
+	-i|--idle & perform check in a lowest I/O scheduling class (idle).
+	-l|--slow & perform check in a lower-than-standard I/O scheduling class.
+	-f|--fast & perform check in higher-than-standard I/O scheduling class.
+	--realtime & perform check in real-time I/O scheduling class (DANGEROUS!).
+	-c|--cron & honour AUTOCHECK setting in /etc/sysconfig/mdadm.
+	-q|--quiet & suppress informational messages.
+	-Q|--real-quiet & suppress all output messages, including warnings and errors.
+	-h|--help & show this output.
+	-V|--version & show version information.
+	_eof
+  echo
+  echo "Examples:"
+  echo "  $PROGNAME --all --idle"
+  echo "  $PROGNAME --quiet /dev/md[123]"
+  echo "  $PROGNAME -sa"
+  echo "  $PROGNAME -x --all"
+  echo
+  echo "Devices can be specified in almost any format. The following are"
+  echo "all equivalent:"
+  echo "  /dev/md0, md0, /dev/md/0, /sys/block/md0"
+  echo
+  echo "The --all option overrides all arrays passed to the script."
+  echo
+  echo "You can also control the status of a check with /proc/mdstat ."
+}
+
+SHORTOPTS=achVqQsxilf
+LONGOPTS=all,cron,help,version,quiet,real-quiet,status,cancel,idle,slow,fast,realtime
+
+eval set -- $(getopt -o $SHORTOPTS -l $LONGOPTS -n $PROGNAME -- "$@")
+
+arrays=''
+cron=0
+all=0
+quiet=0
+status=0
+action=check
+ionice=
+
+for opt in $@; do
+  case "$opt" in
+    -a|--all) all=1;;
+    -s|--status) action=status;;
+    -x|--cancel) action=idle;;
+    -i|--idle) ionice=idle;;
+    -l|--slow) ionice=low;;
+    -f|--fast) ionice=high;;
+    --realtime) ionice=realtime;;
+    -c|--cron) cron=1;;
+    -q|--quiet) quiet=1;;
+    -Q|--real-quiet) quiet=2;;
+    -h|--help) usage; exit 0;;
+    -V|--version) about; exit 0;;
+    /dev/md/*|md/*) arrays="${arrays:+$arrays }md${opt#*md/}";;
+    /dev/md*|md*) arrays="${arrays:+$arrays }${opt#/dev/}";;
+    /sys/block/md*) arrays="${arrays:+$arrays }${opt#/sys/block/}";;
+    --) :;;
+    *) echo "$PROGNAME: E: invalid option: $opt" >&2; usage >&2; exit 0;;
+  esac
+done
+
+is_true()
+{
+  case "${1:-}" in
+    [Yy]es|[Yy]|1|[Tt]rue|[Tt]) return 0;;
+    *) return 1;
+  esac
+}
+
+AUTOCHECK=
+
+ALTCONFIG=/etc/sysconfig/mdadm
+[ -r $ALTCONFIG ] && . $ALTCONFIG
+if [ $cron = 1 ] && ( [ "x$AUTOCHECK" = "xfalse" ] || [ "x$AUTOCHECK" = "xno" ] ); then
+  [ $quiet -lt 1 ] && echo "$PROGNAME: I: disabled in $ALTCONFIG ." >&2
+  exit 0
+fi
+
+if [ ! -f /proc/mdstat ]; then
+  [ $quiet -lt 2 ] && echo "$PROGNAME: E: MD subsystem not loaded, or /proc unavailable." >&2
+  exit 2
+fi
+
+if [ ! -d /sys/block ]; then
+  [ $quiet -lt 2 ] && echo "$PROGNAME: E: /sys filesystem not available." >&2
+  exit 7
+fi
+
+if [ -z "$(ls /sys/block/md* 2>/dev/null)" ]; then
+  if [ $quiet -lt 2 ] && [ $cron != 1 ]; then
+    echo "$PROGNAME: W: no active MD arrays found." >&2
+    echo "$PROGNAME: W: (maybe uninstall the mdadm package?)" >&2
+  fi
+  exit 0
+fi
+
+if [ -z "$(ls /sys/block/md*/md/level 2>/dev/null)" ]; then
+  [ $quiet -lt 2 ] && echo "$PROGNAME: E: kernel too old, no support for redundancy checks." >&2
+  exit 6
+fi
+
+if ! egrep -q '^raid([1456]|10)$' /sys/block/md*/md/level 2>/dev/null; then
+  [ $quiet -lt 1 ] && echo "$PROGNAME: I: no redundant arrays present; skipping checks..." >&2
+  exit 0
+fi
+
+if [ -z "$(ls /sys/block/md*/md/sync_action 2>/dev/null)" ]; then
+  [ $quiet -lt 2 ] && echo "$PROGNAME: E: no kernel support for redundancy checks." >&2
+  exit 3
+fi
+
+[ $all = 1 ] && arrays="$(ls -d1 /sys/block/md* | cut -d/ -f4)"
+
+for array in $arrays; do
+  SYNC_ACTION_CTL=/sys/block/$array/md/sync_action
+
+  if [ ! -e $SYNC_ACTION_CTL ]; then
+    [ $quiet -lt 1 ] && echo "$PROGNAME: I: skipping non-redundant array $array." >&2
+    continue
+  fi
+
+  cur_status="$(cat $SYNC_ACTION_CTL)"
+
+  if [ $action = status ]; then
+    echo "$array: $cur_status"
+    continue
+  fi
+
+  if [ ! -w $SYNC_ACTION_CTL ]; then
+    [ $quiet -lt 2 ] && echo "$PROGNAME: E: $SYNC_ACTION_CTL not writeable." >&2
+    exit 4
+  fi
+
+  if [ "$(cat /sys/block/$array/md/array_state)" = 'read-auto' ]; then
+    echo "$PROGNAME: W: array $array in auto-read-only state, skipping..." >&2
+    continue
+  fi
+
+  case "$action" in
+    idle)
+      echo $action > $SYNC_ACTION_CTL
+      [ $quiet -lt 1 ] && echo "$PROGNAME: I: cancel request queued for array $array." >&2
+      ;;
+
+    check)
+      if [ "$cur_status" != idle ]; then
+        [ $quiet -lt 2 ] && echo "$PROGNAME: W: array $array not idle, skipping..." >&2
+        continue
+      fi
+
+      # queue request for the array. The kernel will make sure that these requests
+      # are properly queued so as to not kill one of the array.
+      echo $action > $SYNC_ACTION_CTL
+      [ $quiet -lt 1 ] && echo "$PROGNAME: I: check queued for array $array." >&2
+
+      case "$ionice" in
+        idle) arg='-c3';;
+        low) arg='-c2 -n7';;
+        high) arg='-c2 -n0';;
+        realtime) arg='-c1 -n4';;
+        *) break;;
+      esac
+
+      resync_pid= wait=5
+      while [ $wait -gt 0 ]; do
+        wait=$((wait - 1))
+        resync_pid=$(ps -ef | awk -v dev=$array 'BEGIN { pattern = "^\\[" dev "_resync]$" } $8 ~ pattern { print $2 }')
+        if [ -n "$resync_pid" ]; then
+          echo "$PROGNAME: I: selecting $ionice I/O scheduling class for resync of $array." >&2
+          ionice -p "$resync_pid" $arg
+          break
+        fi
+        sleep 1
+      done
+      ;;
+  esac
+
+done
+
+exit 0
diff --git a/alt/mdadm.conf b/alt/mdadm.conf
new file mode 100644
index 00000000..7ddcabe3
--- /dev/null
+++ b/alt/mdadm.conf
@@ -0,0 +1,14 @@
+#
+#  /etc/mdadm.conf  --  mdadm configuration file
+#
+#  Customized for ALTLinux
+#  See complete sample on manual page and in documentation directory
+#
+#  This is a minimalistic skeleton but it should work out-of:a+box!
+#
+
+MAILADDR root
+PROGRAM /sbin/mdadm-syslog-events
+DEVICE partitions
+
+## EOF ##
diff --git a/alt/mdadm.crond b/alt/mdadm.crond
new file mode 100644
index 00000000..2eab9db0
--- /dev/null
+++ b/alt/mdadm.crond
@@ -0,0 +1,11 @@
+# cron.d/mdadm -- schedules periodic redundancy checks of MD devices
+#
+# Copyright © martin f. krafft <madduck@madduck.net>
+# distributed under the terms of the Artistic Licence 2.0
+#
+
+# By default, run at 00:57 on every Sunday, but do nothing unless the day of
+# the month is less than or equal to 7. Thus, only run on the first Sunday of
+# each month. crontab(5) sucks, unfortunately, in this regard; therefore this
+# hack (see #380425).
+57 0 * * 0 root if [ -x /usr/share/mdadm/checkarray ] && [ $(date +\%d) -le 7 ]; then /usr/share/mdadm/checkarray --cron --all --idle --quiet; fi
diff --git a/alt/mdadm.init b/alt/mdadm.init
new file mode 100644
index 00000000..d80e177e
--- /dev/null
+++ b/alt/mdadm.init
@@ -0,0 +1,75 @@
+#!/bin/sh
+#
+# mdadm	This starts, stops, and reloads the mdadm-based
+#	software RAID monitoring and management facility
+#
+# chkconfig: 2345 15 85
+# description: software RAID monitoring and management
+# processname: mdadm
+# config: /etc/mdadm.conf
+# pidfile: /var/run/mdadm.pid
+#
+
+# Source function library.
+WITHOUT_RC_COMPAT=1
+. /etc/init.d/functions
+
+MDADM_MONITOR_ARGS=""
+SourceIfNotEmpty /etc/sysconfig/mdadm
+
+PIDFILE=/var/run/mdadm.pid
+LOCKFILE=/var/lock/subsys/mdadm
+CONFFILE=/etc/mdadm.conf
+EXPECTUSER=root
+RETVAL=0
+
+call()
+{
+	local fn=$1; shift
+	$fn --pidfile "$PIDFILE" --lockfile "$LOCKFILE" --expect-user "$EXPECTUSER" -- mdadm "$@"
+	RETVAL=$?; return $RETVAL
+}
+
+need_start()
+{
+	grep -iwqs noraidtab /proc/cmdline && return 1
+	# Make sure configuration file exists and has information we can use
+	# At least MAILADDR or PROGRAM must be set in order to run mdadm --monitor
+	grep -qs '^[[:space:]]*\(MAILADDR\|PROGRAM\)[[:space:]]\+[^[:space:]]' "$CONFFILE" || return
+	grep -qs '^md[0-9]\+[[:space:]]*:' /proc/mdstat || return
+}
+
+start()
+{
+	need_start || return 0
+	call start_daemon --monitor --scan --daemonise --pid-file=$PIDFILE "$MDADM_MONITOR_ARGS"
+}
+
+stop()
+{
+	call stop_daemon
+}
+
+restart()
+{
+	stop
+	start
+}
+
+case "$1" in
+	start|stop)
+		$1 ;;
+	restart|reload)
+		restart ;;
+	status)
+		call status ;;
+	condstop)
+		[ -e "$LOCKFILE" ] && stop ;;
+	condrestart|condreload)
+		[ -e "$LOCKFILE" ] && restart ;;
+	*)
+		msg_usage "${0##*/} {start|stop|status|restart|condrestart|condstop}"
+		RETVAL=1 ;;
+esac
+
+exit $RETVAL
diff --git a/alt/mdadm.service b/alt/mdadm.service
new file mode 100644
index 00000000..474be33e
--- /dev/null
+++ b/alt/mdadm.service
@@ -0,0 +1,11 @@
+[Unit]
+Description=software RAID monitoring and management
+After=local-fs.target
+Requires=local-fs.target
+ConditionKernelCommandLine=!noraidtab
+
+[Service]
+ExecStart=/sbin/mdadm --monitor --scan
+
+[Install]
+WantedBy=local-fs.target
diff --git a/alt/mdadm.sysconfig b/alt/mdadm.sysconfig
new file mode 100644
index 00000000..b634cb49
--- /dev/null
+++ b/alt/mdadm.sysconfig
@@ -0,0 +1,3 @@
+# monitoring options
+# MDADM_MONITOR_ARGS="-d MDADM_DELAY -m MDADM_MAIL -p MDADM_PROGRAM"
+MDADM_MONITOR_ARGS=""
diff --git a/alt/raidtabtomdadm.sh b/alt/raidtabtomdadm.sh
new file mode 100644
index 00000000..0a02f646
--- /dev/null
+++ b/alt/raidtabtomdadm.sh
@@ -0,0 +1,30 @@
+#!/bin/sh
+# scans /etc/raidtab and current system and adds to /etc/mdadm.conf all md
+# devices defined in raidtab, it also adds (commented) devices not in raidtab
+
+if [ -f /etc/raidtab ]; then
+echo "Converting your /etc/raidtab file to /etc/mdadm.conf"
+echo "Raidtab backup saved as: /etc/raidtab.backup.$$"
+
+grep -qs '/^[[:space:]]*DEVICE' /etc/mdadm.conf || echo "DEVICE partitions" >> /etc/mdadm.conf
+
+raidtab=`awk '/^[[:space:]]*raiddev/ {sub ("md/","md",$2); print $2}' /etc/raidtab`
+mdadm=`awk '/^[[:space:]]*ARRAY/ {sub ("md/","md",$2); print $2}' /etc/mdadm.conf`
+
+mdadm -Esc partitions | awk -v "raidtab=$raidtab" -v "mdadm=$mdadm" '
+	BEGIN {
+		split (raidtab,r)
+		split (mdadm,m)
+	}
+	/^ARRAY[[:space:]]/ {
+		for (v in m) {
+			if ( $2 == m[v]) {next}
+		}
+		for (v in r) {
+			if ( $2 == r[v]) {print $0, "auto=yes";next}
+		}
+		print "# " $0
+	}' >> /etc/mdadm.conf
+
+mv /etc/raidtab /etc/raidtab.backup.$$
+fi
diff --git a/managemon.c b/managemon.c
index bb7334cf..0e9bdf00 100644
--- a/managemon.c
+++ b/managemon.c
@@ -106,7 +106,6 @@
 #include	"mdmon.h"
 #include	<sys/syscall.h>
 #include	<sys/socket.h>
-#include	<signal.h>
 
 static void close_aa(struct active_array *aa)
 {
diff --git a/maps.c b/maps.c
index a4fd2797..20fcf719 100644
--- a/maps.c
+++ b/maps.c
@@ -166,6 +166,30 @@ mapping_t sysfs_array_states[] = {
 	{ NULL, ARRAY_UNKNOWN_STATE }
 };
 
+/**
+ * map_num_s() - Safer alternative of map_num() function.
+ * @map: map to search.
+ * @num: key to match.
+ *
+ * Shall be used only if key existence is quaranted.
+ *
+ * Return: Pointer to name of the element.
+ */
+char *map_num_s(mapping_t *map, int num)
+{
+	char *ret = map_num(map, num);
+
+	assert(ret);
+	return ret;
+}
+
+/**
+ * map_num() - get element name by key.
+ * @map: map to search.
+ * @num: key to match.
+ *
+ * Return: Pointer to name of the element or NULL.
+ */
 char *map_num(mapping_t *map, int num)
 {
 	while (map->name) {
diff --git a/mdadm.8.in b/mdadm.8.in
index be902dba..0be02e4a 100644
--- a/mdadm.8.in
+++ b/mdadm.8.in
@@ -266,14 +266,11 @@ the exact meaning of this option in different contexts.
 
 .TP
 .BR \-c ", " \-\-config=
-Specify the config file or directory.  Default is to use
-.B /etc/mdadm.conf
-and
-.BR /etc/mdadm.conf.d ,
-or if those are missing then
-.B /etc/mdadm/mdadm.conf
-and
-.BR /etc/mdadm/mdadm.conf.d .
+Specify the config file or directory.  If not specified, default config file
+and default conf.d directory will be used.  See
+.BR mdadm.conf (5)
+for more details.
+
 If the config file given is
 .B "partitions"
 then nothing will be read, but
@@ -459,7 +456,8 @@ number of spare devices.
 
 .TP
 .BR \-z ", " \-\-size=
-Amount (in Kilobytes) of space to use from each drive in RAID levels 1/4/5/6.
+Amount (in Kilobytes) of space to use from each drive in RAID levels 1/4/5/6/10
+and for RAID 0 on external metadata.
 This must be a multiple of the chunk size, and must leave about 128Kb
 of space at the end of the drive for the RAID superblock.
 If this is not specified
@@ -478,10 +476,19 @@ To guard against this it can be useful to set the initial size
 slightly smaller than the smaller device with the aim that it will
 still be larger than any replacement.
 
+This option can be used with
+.B \-\-create
+for determining initial size of an array. For external metadata,
+it can be used on a volume, but not on a container itself.
+Setting initial size of
+.B RAID 0
+array is only valid for external metadata.
+
 This value can be set with
 .B \-\-grow
-for RAID level 1/4/5/6 though
+for RAID level 1/4/5/6/10 though
 DDF arrays may not be able to support this.
+RAID 0 array size cannot be changed.
 If the array was created with a size smaller than the currently
 active drives, the extra space can be accessed using
 .BR \-\-grow .
@@ -501,11 +508,6 @@ problems the array can be made bigger again with no loss with another
 .B "\-\-grow \-\-size="
 command.
 
-This value cannot be used when creating a
-.B CONTAINER
-such as with DDF and IMSM metadata, though it perfectly valid when
-creating an array inside a container.
-
 .TP
 .BR \-Z ", " \-\-array\-size=
 This is only meaningful with
@@ -2008,11 +2010,9 @@ The config file is only used if explicitly named with
 .B \-\-config
 or requested with (a possibly implicit)
 .BR \-\-scan .
-In the later case,
-.B /etc/mdadm.conf
-or
-.B /etc/mdadm/mdadm.conf
-is used.
+In the later case, default config file is used.  See
+.BR mdadm.conf (5)
+for more details.
 
 If
 .B \-\-scan
@@ -3339,18 +3339,17 @@ uses this to find arrays when
 is given in Misc mode, and to monitor array reconstruction
 on Monitor mode.
 
-.SS /etc/mdadm.conf
+.SS {CONFFILE} (or {CONFFILE2})
 
-The config file lists which devices may be scanned to see if
-they contain MD super block, and gives identifying information
-(e.g. UUID) about known MD arrays.  See
+Default config file.  See
 .BR mdadm.conf (5)
 for more details.
 
-.SS /etc/mdadm.conf.d
+.SS {CONFFILE}.d (or {CONFFILE2}.d)
 
-A directory containing configuration files which are read in lexical
-order.
+Default directory containing configuration files.  See
+.BR mdadm.conf (5)
+for more details.
 
 .SS {MAP_PATH}
 When
diff --git a/mdadm.c b/mdadm.c
index 26299b2e..8feb13be 100644
--- a/mdadm.c
+++ b/mdadm.c
@@ -280,8 +280,8 @@ int main(int argc, char *argv[])
 			else
 				fprintf(stderr, "-%c", opt);
 			fprintf(stderr, " would set mdadm mode to \"%s\", but it is already set to \"%s\".\n",
-				map_num(modes, newmode),
-				map_num(modes, mode));
+				map_num_s(modes, newmode),
+				map_num_s(modes, mode));
 			exit(2);
 		} else if (!mode && newmode) {
 			mode = newmode;
@@ -544,7 +544,7 @@ int main(int argc, char *argv[])
 			switch(s.level) {
 			default:
 				pr_err("layout not meaningful for %s arrays.\n",
-					map_num(pers, s.level));
+					map_num_s(pers, s.level));
 				exit(2);
 			case UnSet:
 				pr_err("raid level must be given before layout.\n");
@@ -1248,10 +1248,10 @@ int main(int argc, char *argv[])
 		if (option_index > 0)
 			pr_err(":option --%s not valid in %s mode\n",
 				long_options[option_index].name,
-				map_num(modes, mode));
+				map_num_s(modes, mode));
 		else
 			pr_err("option -%c not valid in %s mode\n",
-				opt, map_num(modes, mode));
+				opt, map_num_s(modes, mode));
 		exit(2);
 
 	}
@@ -1276,7 +1276,7 @@ int main(int argc, char *argv[])
 		if (s.consistency_policy != CONSISTENCY_POLICY_UNKNOWN &&
 		    s.consistency_policy != CONSISTENCY_POLICY_JOURNAL) {
 			pr_err("--write-journal is not supported with consistency policy: %s\n",
-			       map_num(consistency_policies, s.consistency_policy));
+			       map_num_s(consistency_policies, s.consistency_policy));
 			exit(2);
 		}
 	}
@@ -1285,12 +1285,12 @@ int main(int argc, char *argv[])
 	    s.consistency_policy != CONSISTENCY_POLICY_UNKNOWN) {
 		if (s.level <= 0) {
 			pr_err("--consistency-policy not meaningful with level %s.\n",
-			       map_num(pers, s.level));
+			       map_num_s(pers, s.level));
 			exit(2);
 		} else if (s.consistency_policy == CONSISTENCY_POLICY_JOURNAL &&
 			   !s.journaldisks) {
 			pr_err("--write-journal is required for consistency policy: %s\n",
-			       map_num(consistency_policies, s.consistency_policy));
+			       map_num_s(consistency_policies, s.consistency_policy));
 			exit(2);
 		} else if (s.consistency_policy == CONSISTENCY_POLICY_PPL &&
 			   s.level != 5) {
@@ -1300,14 +1300,14 @@ int main(int argc, char *argv[])
 			   (!s.bitmap_file ||
 			    strcmp(s.bitmap_file, "none") == 0)) {
 			pr_err("--bitmap is required for consistency policy: %s\n",
-			       map_num(consistency_policies, s.consistency_policy));
+			       map_num_s(consistency_policies, s.consistency_policy));
 			exit(2);
 		} else if (s.bitmap_file &&
 			   strcmp(s.bitmap_file, "none") != 0 &&
 			   s.consistency_policy != CONSISTENCY_POLICY_BITMAP &&
 			   s.consistency_policy != CONSISTENCY_POLICY_JOURNAL) {
 			pr_err("--bitmap is not compatible with consistency policy: %s\n",
-			       map_num(consistency_policies, s.consistency_policy));
+			       map_num_s(consistency_policies, s.consistency_policy));
 			exit(2);
 		}
 	}
@@ -1787,6 +1787,7 @@ static int scan_assemble(struct supertype *ss,
 {
 	struct mddev_ident *a, *array_list =  conf_get_ident(NULL);
 	struct mddev_dev *devlist = conf_get_devs();
+	struct mdstat_ent *ms;
 	struct map_ent *map = NULL;
 	int cnt = 0;
 	int rv = 0;
@@ -1800,11 +1801,28 @@ static int scan_assemble(struct supertype *ss,
 		pr_err("No devices listed in conf file were found.\n");
 		return 1;
 	}
+	ms = mdstat_read(0, 1);
 	for (a = array_list; a; a = a->next) {
+		char *devpath;
 		a->assembled = 0;
 		if (a->autof == 0)
 			a->autof = c->autof;
+		if (a->devname &&
+		    (devpath = canonicalize_file_name(a->devname)) &&
+		    !strncmp(devpath, "/dev/", 5)) {
+			struct mdstat_ent *e;
+			for (e = ms; e; e = e->next) {
+				if (e->active &&
+				    !strcmp(devpath + 5, e->devnm)) {
+					a->assembled = 1;
+					cnt++;
+					break;
+				}
+			}
+			free(devpath);
+		}
 	}
+	free_mdstat(ms);
 	if (map_lock(&map))
 		pr_err("failed to get exclusive lock on mapfile\n");
 	do {
diff --git a/mdadm.conf.5 b/mdadm.conf.5
deleted file mode 100644
index 74a21c5f..00000000
--- a/mdadm.conf.5
+++ /dev/null
@@ -1,706 +0,0 @@
-.\" Copyright Neil Brown and others.
-.\"   This program 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.
-.\" See file COPYING in distribution for details.
-.TH MDADM.CONF 5
-.SH NAME
-mdadm.conf \- configuration for management of Software RAID with mdadm
-.SH SYNOPSIS
-/etc/mdadm.conf
-.SH DESCRIPTION
-.PP
-.I mdadm
-is a tool for creating, managing, and monitoring RAID devices using the
-.B md
-driver in Linux.
-.PP
-Some common tasks, such as assembling all arrays, can be simplified
-by describing the devices and arrays in this configuration file.
-
-.SS SYNTAX
-The file should be seen as a collection of words separated by white
-space (space, tab, or newline).
-Any word that beings with a hash sign (#) starts a comment and that
-word together with the remainder of the line is ignored.
-
-Spaces can be included in a word using quotation characters.  Either
-single quotes
-.RB ( ' )
-or double quotes (\fB"\fP)
-may be used.  All the characters from one quotation character to
-next identical character are protected and will not be used to
-separate words to start new quoted strings.  To include a single quote
-it must be between double quotes.  To include a double quote it must
-be between single quotes.
-
-Any line that starts with white space (space or tab) is treated as
-though it were a continuation of the previous line.
-
-Empty lines are ignored, but otherwise each (non continuation) line
-must start with a keyword as listed below.  The keywords are case
-insensitive and can be abbreviated to 3 characters.
-
-The keywords are:
-.TP
-.B DEVICE
-A
-.B device
-line lists the devices (whole devices or partitions) that might contain
-a component of an MD array.  When looking for the components of an
-array,
-.I mdadm
-will scan these devices (or any devices listed on the command line).
-
-The
-.B device
-line may contain a number of different devices (separated by spaces)
-and each device name can contain wild cards as defined by
-.BR glob (7).
-
-Also, there may be several device lines present in the file.
-
-Alternatively, a
-.B device
-line can contain either or both of the  words
-.B containers
-and
-.BR partitions .
-The word
-.B containers
-will cause
-.I mdadm
-to look for assembled CONTAINER arrays and included them as a source
-for assembling further arrays.
-
-The word
-.I partitions
-will cause
-.I mdadm
-to read
-.I /proc/partitions
-and include all devices and partitions found therein.
-.I mdadm
-does not use the names from
-.I /proc/partitions
-but only the major and minor device numbers.  It scans
-.I /dev
-to find the name that matches the numbers.
-
-If no DEVICE line is present, then "DEVICE partitions containers" is assumed.
-
-For example:
-.IP
-DEVICE /dev/hda* /dev/hdc*
-.br
-DEV    /dev/sd*
-.br
-DEVICE /dev/disk/by-path/pci*
-.br
-DEVICE partitions
-
-.TP
-.B ARRAY
-The ARRAY lines identify actual arrays.  The second word on the line
-may be the name of the device where the array is normally
-assembled, such as
-.B /dev/md1
-or
-.BR /dev/md/backup .
-If the name does not start with a slash
-.RB (' / '),
-it is treated as being in
-.BR /dev/md/ .
-Alternately the word
-.B <ignore>
-(complete with angle brackets) can be given in which case any array
-which matches the rest of the line will never be automatically assembled.
-If no device name is given,
-.I mdadm
-will use various heuristics to determine an appropriate name.
-
-Subsequent words identify the array, or identify the array as a member
-of a group. If multiple identities are given,
-then a component device must match ALL identities to be considered a
-match.  Each identity word has a tag, and equals sign, and some value.
-The tags are:
-.RS 4
-.TP
-.B uuid=
-The value should be a 128 bit uuid in hexadecimal, with punctuation
-interspersed if desired.  This must match the uuid stored in the
-superblock.
-.TP
-.B name=
-The value should be a simple textual name as was given to
-.I mdadm
-when the array was created.  This must match the name stored in the
-superblock on a device for that device to be included in the array.
-Not all superblock formats support names.
-.TP
-.B super\-minor=
-The value is an integer which indicates the minor number that was
-stored in the superblock when the array was created. When an array is
-created as /dev/mdX, then the minor number X is stored.
-.TP
-.B devices=
-The value is a comma separated list of device names or device name
-patterns.
-Only devices with names which match one entry in the list will be used
-to assemble the array.  Note that the devices
-listed there must also be listed on a DEVICE line.
-.TP
-.B level=
-The value is a RAID level.  This is not normally used to
-identify an array, but is supported so that the output of
-
-.B "mdadm \-\-examine \-\-scan"
-
-can be use directly in the configuration file.
-.TP
-.B num\-devices=
-The value is the number of devices in a complete active array.  As with
-.B level=
-this is mainly for compatibility with the output of
-
-.BR "mdadm \-\-examine \-\-scan" .
-
-.TP
-.B spares=
-The value is a number of spare devices to expect the array to have.
-The sole use of this keyword and value is as follows:
-.B mdadm \-\-monitor
-will report an array if it is found to have fewer than this number of
-spares when
-.B \-\-monitor
-starts or when
-.B \-\-oneshot
-is used.
-
-.TP
-.B spare\-group=
-The value is a textual name for a group of arrays.  All arrays with
-the same
-.B spare\-group
-name are considered to be part of the same group.  The significance of
-a group of arrays is that
-.I mdadm
-will, when monitoring the arrays, move a spare drive from one array in
-a group to another array in that group if the first array had a failed
-or missing drive but no spare.
-
-.TP
-.B auto=
-This option is rarely needed with mdadm-3.0, particularly if use with
-the Linux kernel v2.6.28 or later.
-It tells
-.I mdadm
-whether to use partitionable array or non-partitionable arrays and,
-in the absence of
-.IR udev ,
-how many partition devices to create.  From 2.6.28 all md array
-devices are partitionable, hence this option is not needed.
-
-The value of this option can be "yes" or "md" to indicate that a
-traditional, non-partitionable md array should be created, or "mdp",
-"part" or "partition" to indicate that a partitionable md array (only
-available in linux 2.6 and later) should be used.  This later set can
-also have a number appended to indicate how many partitions to create
-device files for, e.g.
-.BR auto=mdp5 .
-The default is 4.
-
-.TP
-.B bitmap=
-The option specifies a file in which a write-intent bitmap should be
-found.  When assembling the array,
-.I mdadm
-will provide this file to the
-.B md
-driver as the bitmap file.  This has the same function as the
-.B \-\-bitmap\-file
-option to
-.BR \-\-assemble .
-
-.TP
-.B metadata=
-Specify the metadata format that the array has.  This is mainly
-recognised for comparability with the output of
-.BR "mdadm \-Es" .
-
-.TP
-.B container=
-Specify that this array is a member array of some container.  The
-value given can be either a path name in /dev, or a UUID of the
-container array.
-
-.TP
-.B member=
-Specify that this array is a member array of some container.  Each
-type of container has some way to enumerate member arrays, often a
-simple sequence number.  The value identifies which member of a
-container the array is.  It will usually accompany a "container=" word.
-.RE
-
-.TP
-.B MAILADDR
-The
-.B mailaddr
-line gives an E-mail address that alerts should be
-sent to when
-.I mdadm
-is running in
-.B \-\-monitor
-mode (and was given the
-.B \-\-scan
-option).  There should only be one
-.B MAILADDR
-line and it should have only one address.  Any subsequent addresses
-are silently ignored.
-
-.TP
-.B MAILFROM
-The
-.B mailfrom
-line (which can only be abbreviated to at least 5 characters) gives an
-address to appear in the "From" address for alert mails.  This can be
-useful if you want to explicitly set a domain, as the default from
-address is "root" with no domain.  All words on this line are
-catenated with spaces to form the address.
-
-Note that this value cannot be set via the
-.I mdadm
-commandline.  It is only settable via the config file.
-
-.TP
-.B PROGRAM
-The
-.B program
-line gives the name of a program to be run when
-.B "mdadm \-\-monitor"
-detects potentially interesting events on any of the arrays that it
-is monitoring.  This program gets run with two or three arguments, they
-being the Event, the md device, and possibly the related component
-device.
-
-There should only be one
-.B program
-line and it should be give only one program.
-
-
-.TP
-.B CREATE
-The
-.B create
-line gives default values to be used when creating arrays, new members
-of arrays, and device entries for arrays.
-These include:
-
-.RS 4
-.TP
-.B owner=
-.TP
-.B group=
-These can give user/group ids or names to use instead of system
-defaults (root/wheel or root/disk).
-.TP
-.B mode=
-An octal file mode such as 0660 can be given to override the default
-of 0600.
-.TP
-.B auto=
-This corresponds to the
-.B \-\-auto
-flag to mdadm.  Give
-.BR yes ,
-.BR md ,
-.BR mdp ,
-.B part
-\(em possibly followed by a number of partitions \(em to indicate how
-missing device entries should be created.
-
-.TP
-.B metadata=
-The name of the metadata format to use if none is explicitly given.
-This can be useful to impose a system-wide default of version-1 superblocks.
-
-.TP
-.B symlinks=no
-Normally when creating devices in
-.B /dev/md/
-.I mdadm
-will create a matching symlink from
-.B /dev/
-with a name starting
-.B md
-or
-.BR md_ .
-Give
-.B symlinks=no
-to suppress this symlink creation.
-
-.TP
-.B names=yes
-Since Linux 2.6.29 it has been possible to create
-.B md
-devices with a name like
-.B md_home
-rather than just a number, like
-.BR md3 .
-.I mdadm
-will use the numeric alternative by default as other tools that interact
-with md arrays may expect only numbers.
-If
-.B names=yes
-is given in
-.I mdadm.conf
-then
-.I mdadm
-will use a name when appropriate.
-If
-.B names=no
-is given, then non-numeric
-.I md
-device names will not be used even if the default changes in a future
-release of
-.IR mdadm .
-
-.TP
-.B bbl=no
-By default,
-.I mdadm
-will reserve space for a bad block list (bbl) on all devices
-included in or added to any array that supports them.  Setting
-.B bbl=no
-will prevent this, so newly added devices will not have a bad
-block log.
-.RE
-
-.TP
-.B HOMEHOST
-The
-.B homehost
-line gives a default value for the
-.B \-\-homehost=
-option to mdadm.  There should normally be only one other word on the line.
-It should either be a host name, or one of the special words
-.BR <system>,
-.B <none>
-and
-.BR <ignore> .
-If
-.B <system>
-is given, then the
-.BR gethostname ( 2 )
-systemcall is used to get the host name.  This is the default.
-
-If
-.B <ignore>
-is given, then a flag is set so that when arrays are being
-auto-assembled the checking of the recorded
-.I homehost
-is disabled.
-If
-.B <ignore>
-is given it is also possible to give an explicit name which will be
-used when creating arrays.  This is the only case when there can be
-more that one other word on the
-.B HOMEHOST
-line.  If there are other words, or other
-.B HOMEHOST
-lines, they are silently ignored.
-
-If
-.B <none>
-is given, then the default of using
-.BR gethostname ( 2 )
-is over-ridden and no homehost name is assumed.
-
-When arrays are created, this host name will be stored in the
-metadata.  When arrays are assembled using auto-assembly, arrays which
-do not record the correct homehost name in their metadata will be
-assembled using a "foreign" name.  A "foreign" name alway ends with a
-digit string preceded by an underscore to differentiate it
-from any possible local name. e.g.
-.B /dev/md/1_1
-or
-.BR /dev/md/home_0 .
-.TP
-.B AUTO
-A list of names of metadata format can be given, each preceded by a
-plus or minus sign.  Also the word
-.I homehost
-is allowed as is
-.I all
-preceded by plus or minus sign.
-.I all
-is usually last.
-
-When
-.I mdadm
-is auto-assembling an array, either via
-.I \-\-assemble
-or
-.I \-\-incremental
-and it finds metadata of a given type, it checks that metadata type
-against those listed in this line.  The first match wins, where
-.I all
-matches anything.
-If a match is found that was preceded by a plus sign, the auto
-assembly is allowed.  If the match was preceded by a minus sign, the
-auto assembly is disallowed.  If no match is found, the auto assembly
-is allowed.
-
-If the metadata indicates that the array was created for
-.I this
-host, and the word
-.I homehost
-appears before any other match, then the array is treated as a valid
-candidate for auto-assembly.
-
-This can be used to disable all auto-assembly (so that only arrays
-explicitly listed in mdadm.conf or on the command line are assembled),
-or to disable assembly of certain metadata types which might be
-handled by other software.  It can also be used to disable assembly of
-all foreign arrays - normally such arrays are assembled but given a
-non-deterministic name in
-.BR /dev/md/ .
-
-The known metadata types are
-.BR 0.90 ,
-.BR 1.x ,
-.BR ddf ,
-.BR imsm .
-
-.B AUTO
-should be given at most once.  Subsequent lines are silently ignored.
-Thus an earlier config file in a config directory will over-ride
-the setting in a later config file.
-
-.TP
-.B POLICY
-This is used to specify what automatic behavior is allowed on devices
-newly appearing in the system and provides a way of marking spares that can
-be moved to other arrays as well as the migration domains.
-.I Domain
-can be defined through
-.I policy
-line by specifying a domain name for a number of paths from
-.BR /dev/disk/by-path/ .
-A device may belong to several domains. The domain of an array is a union
-of domains of all devices in that array.  A spare can be automatically
-moved from one array to another if the set of the destination array's
-.I domains
-contains all the
-.I domains
-of the new disk or if both arrays have the same
-.IR spare-group .
-
-To update hot plug configuration it is necessary to execute
-.B mdadm \-\-udev\-rules
-command after changing the config file
-
-Keywords used in the
-.I POLICY
-line and supported values are:
-
-.RS 4
-.TP
-.B domain=
-any arbitrary string
-.TP
-.B metadata=
-0.9 1.x ddf or imsm
-.TP
-.B path=
-file glob matching anything from
-.B /dev/disk/by-path
-.TP
-.B type=
-either
-.B disk
-or
-.BR part .
-.TP
-.B action=
-include, re-add, spare, spare-same-slot, or force-spare
-.TP
-.B auto=
-yes, no, or homehost.
-
-.P
-The
-.I action
-item determines the automatic behavior allowed for devices matching the
-.I path
-and
-.I type
-in the same line.  If a device matches several lines with different
-.I  actions
-then the most permissive will apply. The ordering of policy lines
-is irrelevant to the end result.
-.TP
-.B include
-allows adding a disk to an array if metadata on that disk matches that array
-.TP
-.B re\-add
-will include the device in the array if it appears to be a current member
-or a member that was recently removed and the array has a
-write-intent-bitmap to allow the
-.B re\-add
-functionality.
-.TP
-.B spare
-as above and additionally: if the device is bare it can
-become a spare if there is any array that it is a candidate for based
-on domains and metadata.
-.TP
-.B spare\-same\-slot
-as above and additionally if given slot was used by an array that went
-degraded recently and the device plugged in has no metadata then it will
-be automatically added to that array (or it's container)
-.TP
-.B force\-spare
-as above and the disk will become a spare in remaining cases
-.RE
-
-.TP
-.B PART-POLICY
-This is similar to
-.B POLICY
-and accepts the same keyword assignments.  It allows a consistent set
-of policies to applied to each of the partitions of a device.
-
-A
-.B PART-POLICY
-line should set
-.I type=disk
-and identify the path to one or more disk devices.  Each partition on
-these disks will be treated according to the
-.I action=
-setting  from this line.  If a
-.I domain
-is set in the line, then the domain associated with each patition will
-be based on the domain, but with
-.RB \(dq -part N\(dq
-appended, when N is the partition number for the partition that was
-found.
-
-.TP
-.B SYSFS
-The
-.B SYSFS
-line lists custom values of MD device's sysfs attributes which will be
-stored in sysfs after the array is assembled. Multiple lines are allowed and each
-line has to contain the uuid or the name of the device to which it relates.
-.RS 4
-.TP
-.B uuid=
-hexadecimal identifier of MD device. This has to match the uuid stored in the
-superblock.
-.TP
-.B name=
-name of the MD device as was given to
-.I mdadm
-when the array was created. It will be ignored if
-.B uuid
-is not empty.
-.RE
-
-.TP
-.B MONITORDELAY
-The
-.B monitordelay
-line gives a delay in seconds
-.I mdadm
-shall wait before pooling md arrays
-when
-.I mdadm
-is running in
-.B \-\-monitor
-mode.
-.B \-d/\-\-delay
-command line argument takes precedence over the config file
-
-.SH EXAMPLE
-DEVICE /dev/sd[bcdjkl]1
-.br
-DEVICE /dev/hda1 /dev/hdb1
-
-# /dev/md0 is known by its UUID.
-.br
-ARRAY /dev/md0 UUID=3aaa0122:29827cfa:5331ad66:ca767371
-.br
-# /dev/md1 contains all devices with a minor number of
-.br
-#   1 in the superblock.
-.br
-ARRAY /dev/md1 superminor=1
-.br
-# /dev/md2 is made from precisely these two devices
-.br
-ARRAY /dev/md2 devices=/dev/hda1,/dev/hdb1
-
-# /dev/md4 and /dev/md5 are a spare-group and spares
-.br
-#  can be moved between them
-.br
-ARRAY /dev/md4 uuid=b23f3c6d:aec43a9f:fd65db85:369432df
-.br
-           spare\-group=group1
-.br
-ARRAY /dev/md5 uuid=19464854:03f71b1b:e0df2edd:246cc977
-.br
-           spare\-group=group1
-.br
-# /dev/md/home is created if need to be a partitionable md array
-.br
-# any spare device number is allocated.
-.br
-ARRAY /dev/md/home UUID=9187a482:5dde19d9:eea3cc4a:d646ab8b
-.br
-           auto=part
-.br
-# The name of this array contains a space.
-.br
-ARRAY /dev/md9 name='Data Storage'
-.sp
-POLICY domain=domain1 metadata=imsm path=pci-0000:00:1f.2-scsi-*
-.br
-           action=spare
-.br
-POLICY domain=domain1 metadata=imsm path=pci-0000:04:00.0-scsi-[01]*
-.br
-           action=include
-.br
-# One domain comprising of devices attached to specified paths is defined.
-.br
-# Bare device matching first path will be made an imsm spare on hot plug.
-.br
-# If more than one array is created on devices belonging to domain1 and
-.br
-# one of them becomes degraded, then any imsm spare matching any path for
-.br
-# given domain name can be migrated.
-.br
-MAILADDR root@mydomain.tld
-.br
-PROGRAM /usr/sbin/handle\-mdadm\-events
-.br
-CREATE group=system mode=0640 auto=part\-8
-.br
-HOMEHOST <system>
-.br
-AUTO +1.x homehost \-all
-.br
-SYSFS name=/dev/md/raid5 group_thread_cnt=4 sync_speed_max=1000000
-.br
-SYSFS uuid=bead5eb6:31c17a27:da120ba2:7dfda40d group_thread_cnt=4
-sync_speed_max=1000000
-.br
-MONITORDELAY 60
-
-.SH SEE ALSO
-.BR mdadm (8),
-.BR md (4).
diff --git a/mdadm.conf.5.in b/mdadm.conf.5.in
new file mode 100644
index 00000000..cd4e6a9d
--- /dev/null
+++ b/mdadm.conf.5.in
@@ -0,0 +1,776 @@
+.\" Copyright Neil Brown and others.
+.\"   This program 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.
+.\" See file COPYING in distribution for details.
+.TH MDADM.CONF 5
+.SH NAME
+mdadm.conf \- configuration for management of Software RAID with mdadm
+.SH SYNOPSIS
+{CONFFILE}
+.SH DESCRIPTION
+.PP
+.I mdadm
+is a tool for creating, managing, and monitoring RAID devices using the
+.B md
+driver in Linux.
+.PP
+Some common tasks, such as assembling all arrays, can be simplified
+by describing the devices and arrays in this configuration file.
+
+.SS SYNTAX
+The file should be seen as a collection of words separated by white
+space (space, tab, or newline).
+Any word that beings with a hash sign (#) starts a comment and that
+word together with the remainder of the line is ignored.
+
+Spaces can be included in a word using quotation characters.  Either
+single quotes
+.RB ( ' )
+or double quotes (\fB"\fP)
+may be used.  All the characters from one quotation character to
+next identical character are protected and will not be used to
+separate words to start new quoted strings.  To include a single quote
+it must be between double quotes.  To include a double quote it must
+be between single quotes.
+
+Any line that starts with white space (space or tab) is treated as
+though it were a continuation of the previous line.
+
+Empty lines are ignored, but otherwise each (non continuation) line
+must start with a keyword as listed below.  The keywords are case
+insensitive and can be abbreviated to 3 characters.
+
+The keywords are:
+.TP
+.B DEVICE
+A
+.B device
+line lists the devices (whole devices or partitions) that might contain
+a component of an MD array.  When looking for the components of an
+array,
+.I mdadm
+will scan these devices (or any devices listed on the command line).
+
+The
+.B device
+line may contain a number of different devices (separated by spaces)
+and each device name can contain wild cards as defined by
+.BR glob (7).
+
+Also, there may be several device lines present in the file.
+
+Alternatively, a
+.B device
+line can contain either or both of the  words
+.B containers
+and
+.BR partitions .
+The word
+.B containers
+will cause
+.I mdadm
+to look for assembled CONTAINER arrays and included them as a source
+for assembling further arrays.
+
+The word
+.I partitions
+will cause
+.I mdadm
+to read
+.I /proc/partitions
+and include all devices and partitions found therein.
+.I mdadm
+does not use the names from
+.I /proc/partitions
+but only the major and minor device numbers.  It scans
+.I /dev
+to find the name that matches the numbers.
+
+If no DEVICE line is present in any config file,
+then "DEVICE partitions containers" is assumed.
+
+For example:
+.IP
+DEVICE /dev/hda* /dev/hdc*
+.br
+DEV    /dev/sd*
+.br
+DEVICE /dev/disk/by-path/pci*
+.br
+DEVICE partitions
+
+.TP
+.B ARRAY
+The ARRAY lines identify actual arrays.  The second word on the line
+may be the name of the device where the array is normally
+assembled, such as
+.B /dev/md1
+or
+.BR /dev/md/backup .
+If the name does not start with a slash
+.RB (' / '),
+it is treated as being in
+.BR /dev/md/ .
+Alternately the word
+.B <ignore>
+(complete with angle brackets) can be given in which case any array
+which matches the rest of the line will never be automatically assembled.
+If no device name is given,
+.I mdadm
+will use various heuristics to determine an appropriate name.
+
+Subsequent words identify the array, or identify the array as a member
+of a group. If multiple identities are given,
+then a component device must match ALL identities to be considered a
+match.  Each identity word has a tag, and equals sign, and some value.
+The tags are:
+.RS 4
+.TP
+.B uuid=
+The value should be a 128 bit uuid in hexadecimal, with punctuation
+interspersed if desired.  This must match the uuid stored in the
+superblock.
+.TP
+.B name=
+The value should be a simple textual name as was given to
+.I mdadm
+when the array was created.  This must match the name stored in the
+superblock on a device for that device to be included in the array.
+Not all superblock formats support names.
+.TP
+.B super\-minor=
+The value is an integer which indicates the minor number that was
+stored in the superblock when the array was created. When an array is
+created as /dev/mdX, then the minor number X is stored.
+.TP
+.B devices=
+The value is a comma separated list of device names or device name
+patterns.
+Only devices with names which match one entry in the list will be used
+to assemble the array.  Note that the devices
+listed there must also be listed on a DEVICE line.
+.TP
+.B level=
+The value is a RAID level.  This is not normally used to
+identify an array, but is supported so that the output of
+
+.B "mdadm \-\-examine \-\-scan"
+
+can be use directly in the configuration file.
+.TP
+.B num\-devices=
+The value is the number of devices in a complete active array.  As with
+.B level=
+this is mainly for compatibility with the output of
+
+.BR "mdadm \-\-examine \-\-scan" .
+
+.TP
+.B spares=
+The value is a number of spare devices to expect the array to have.
+The sole use of this keyword and value is as follows:
+.B mdadm \-\-monitor
+will report an array if it is found to have fewer than this number of
+spares when
+.B \-\-monitor
+starts or when
+.B \-\-oneshot
+is used.
+
+.TP
+.B spare\-group=
+The value is a textual name for a group of arrays.  All arrays with
+the same
+.B spare\-group
+name are considered to be part of the same group.  The significance of
+a group of arrays is that
+.I mdadm
+will, when monitoring the arrays, move a spare drive from one array in
+a group to another array in that group if the first array had a failed
+or missing drive but no spare.
+
+.TP
+.B auto=
+This option is rarely needed with mdadm-3.0, particularly if use with
+the Linux kernel v2.6.28 or later.
+It tells
+.I mdadm
+whether to use partitionable array or non-partitionable arrays and,
+in the absence of
+.IR udev ,
+how many partition devices to create.  From 2.6.28 all md array
+devices are partitionable, hence this option is not needed.
+
+The value of this option can be "yes" or "md" to indicate that a
+traditional, non-partitionable md array should be created, or "mdp",
+"part" or "partition" to indicate that a partitionable md array (only
+available in linux 2.6 and later) should be used.  This later set can
+also have a number appended to indicate how many partitions to create
+device files for, e.g.
+.BR auto=mdp5 .
+The default is 4.
+
+.TP
+.B bitmap=
+The option specifies a file in which a write-intent bitmap should be
+found.  When assembling the array,
+.I mdadm
+will provide this file to the
+.B md
+driver as the bitmap file.  This has the same function as the
+.B \-\-bitmap\-file
+option to
+.BR \-\-assemble .
+
+.TP
+.B metadata=
+Specify the metadata format that the array has.  This is mainly
+recognised for comparability with the output of
+.BR "mdadm \-Es" .
+
+.TP
+.B container=
+Specify that this array is a member array of some container.  The
+value given can be either a path name in /dev, or a UUID of the
+container array.
+
+.TP
+.B member=
+Specify that this array is a member array of some container.  Each
+type of container has some way to enumerate member arrays, often a
+simple sequence number.  The value identifies which member of a
+container the array is.  It will usually accompany a "container=" word.
+.RE
+
+.TP
+.B MAILADDR
+The
+.B mailaddr
+line gives an E-mail address that alerts should be
+sent to when
+.I mdadm
+is running in
+.B \-\-monitor
+mode (and was given the
+.B \-\-scan
+option).  There should only be one
+.B MAILADDR
+line and it should have only one address.  Any subsequent addresses
+are silently ignored.
+
+.TP
+.B MAILFROM
+The
+.B mailfrom
+line (which can only be abbreviated to at least 5 characters) gives an
+address to appear in the "From" address for alert mails.  This can be
+useful if you want to explicitly set a domain, as the default from
+address is "root" with no domain.  All words on this line are
+catenated with spaces to form the address.
+
+Note that this value cannot be set via the
+.I mdadm
+commandline.  It is only settable via the config file.
+There should only be one
+.B MAILADDR
+line and it should have only one address.  Any subsequent addresses
+are silently ignored.
+
+.TP
+.B PROGRAM
+The
+.B program
+line gives the name of a program to be run when
+.B "mdadm \-\-monitor"
+detects potentially interesting events on any of the arrays that it
+is monitoring.  This program gets run with two or three arguments, they
+being the Event, the md device, and possibly the related component
+device.
+
+There should only be one
+.B program
+line and it should be given only one program.  Any subsequent programs
+are silently ignored.
+
+
+.TP
+.B CREATE
+The
+.B create
+line gives default values to be used when creating arrays, new members
+of arrays, and device entries for arrays.
+
+There should only be one
+.B create
+line.  Any subsequent lines will override the previous settings.
+
+Keywords used in the
+.I CREATE
+line and supported values are:
+
+.RS 4
+.TP
+.B owner=
+.TP
+.B group=
+These can give user/group ids or names to use instead of system
+defaults (root/wheel or root/disk).
+.TP
+.B mode=
+An octal file mode such as 0660 can be given to override the default
+of 0600.
+.TP
+.B auto=
+This corresponds to the
+.B \-\-auto
+flag to mdadm.  Give
+.BR yes ,
+.BR md ,
+.BR mdp ,
+.B part
+\(em possibly followed by a number of partitions \(em to indicate how
+missing device entries should be created.
+
+.TP
+.B metadata=
+The name of the metadata format to use if none is explicitly given.
+This can be useful to impose a system-wide default of version-1 superblocks.
+
+.TP
+.B symlinks=no
+Normally when creating devices in
+.B /dev/md/
+.I mdadm
+will create a matching symlink from
+.B /dev/
+with a name starting
+.B md
+or
+.BR md_ .
+Give
+.B symlinks=no
+to suppress this symlink creation.
+
+.TP
+.B names=yes
+Since Linux 2.6.29 it has been possible to create
+.B md
+devices with a name like
+.B md_home
+rather than just a number, like
+.BR md3 .
+.I mdadm
+will use the numeric alternative by default as other tools that interact
+with md arrays may expect only numbers.
+If
+.B names=yes
+is given in
+.I mdadm.conf
+then
+.I mdadm
+will use a name when appropriate.
+If
+.B names=no
+is given, then non-numeric
+.I md
+device names will not be used even if the default changes in a future
+release of
+.IR mdadm .
+
+.TP
+.B bbl=no
+By default,
+.I mdadm
+will reserve space for a bad block list (bbl) on all devices
+included in or added to any array that supports them.  Setting
+.B bbl=no
+will prevent this, so newly added devices will not have a bad
+block log.
+.RE
+
+.TP
+.B HOMEHOST
+The
+.B homehost
+line gives a default value for the
+.B \-\-homehost=
+option to mdadm.  There should normally be only one other word on the line.
+It should either be a host name, or one of the special words
+.BR <system>,
+.B <none>
+and
+.BR <ignore> .
+If
+.B <system>
+is given, then the
+.BR gethostname ( 2 )
+systemcall is used to get the host name.  This is the default.
+
+If
+.B <ignore>
+is given, then a flag is set so that when arrays are being
+auto-assembled the checking of the recorded
+.I homehost
+is disabled.
+If
+.B <ignore>
+is given it is also possible to give an explicit name which will be
+used when creating arrays.  This is the only case when there can be
+more that one other word on the
+.B HOMEHOST
+line.  If there are other words, or other
+.B HOMEHOST
+lines, they are silently ignored.
+
+If
+.B <none>
+is given, then the default of using
+.BR gethostname ( 2 )
+is over-ridden and no homehost name is assumed.
+
+When arrays are created, this host name will be stored in the
+metadata.  When arrays are assembled using auto-assembly, arrays which
+do not record the correct homehost name in their metadata will be
+assembled using a "foreign" name.  A "foreign" name alway ends with a
+digit string preceded by an underscore to differentiate it
+from any possible local name. e.g.
+.B /dev/md/1_1
+or
+.BR /dev/md/home_0 .
+
+.TP
+.B HOMECLUSTER
+The
+.B homcluster
+line gives a default value for the
+.B \-\-homecluster=
+option to mdadm.  It specifies  the  cluster name for the md device.
+The md device can be assembled only on the cluster which matches
+the name specified. If
+.B homcluster
+is not provided, mdadm tries to detect the cluster name automatically.
+
+There should only be one
+.B homecluster
+line.  Any subsequent lines will be silently ignored.
+
+.TP
+.B AUTO
+A list of names of metadata format can be given, each preceded by a
+plus or minus sign.  Also the word
+.I homehost
+is allowed as is
+.I all
+preceded by plus or minus sign.
+.I all
+is usually last.
+
+When
+.I mdadm
+is auto-assembling an array, either via
+.I \-\-assemble
+or
+.I \-\-incremental
+and it finds metadata of a given type, it checks that metadata type
+against those listed in this line.  The first match wins, where
+.I all
+matches anything.
+If a match is found that was preceded by a plus sign, the auto
+assembly is allowed.  If the match was preceded by a minus sign, the
+auto assembly is disallowed.  If no match is found, the auto assembly
+is allowed.
+
+If the metadata indicates that the array was created for
+.I this
+host, and the word
+.I homehost
+appears before any other match, then the array is treated as a valid
+candidate for auto-assembly.
+
+This can be used to disable all auto-assembly (so that only arrays
+explicitly listed in mdadm.conf or on the command line are assembled),
+or to disable assembly of certain metadata types which might be
+handled by other software.  It can also be used to disable assembly of
+all foreign arrays - normally such arrays are assembled but given a
+non-deterministic name in
+.BR /dev/md/ .
+
+The known metadata types are
+.BR 0.90 ,
+.BR 1.x ,
+.BR ddf ,
+.BR imsm .
+
+.B AUTO
+should be given at most once.  Subsequent lines are silently ignored.
+Thus a later config file in a config directory will not overwrite
+the setting in an earlier config file.
+
+.TP
+.B POLICY
+This is used to specify what automatic behavior is allowed on devices
+newly appearing in the system and provides a way of marking spares that can
+be moved to other arrays as well as the migration domains.
+.I Domain
+can be defined through
+.I policy
+line by specifying a domain name for a number of paths from
+.BR /dev/disk/by-path/ .
+A device may belong to several domains. The domain of an array is a union
+of domains of all devices in that array.  A spare can be automatically
+moved from one array to another if the set of the destination array's
+.I domains
+contains all the
+.I domains
+of the new disk or if both arrays have the same
+.IR spare-group .
+
+To update hot plug configuration it is necessary to execute
+.B mdadm \-\-udev\-rules
+command after changing the config file
+
+Keywords used in the
+.I POLICY
+line and supported values are:
+
+.RS 4
+.TP
+.B domain=
+any arbitrary string
+.TP
+.B metadata=
+0.9 1.x ddf or imsm
+.TP
+.B path=
+file glob matching anything from
+.B /dev/disk/by-path
+.TP
+.B type=
+either
+.B disk
+or
+.BR part .
+.TP
+.B action=
+include, re-add, spare, spare-same-slot, or force-spare
+.TP
+.B auto=
+yes, no, or homehost.
+
+.P
+The
+.I action
+item determines the automatic behavior allowed for devices matching the
+.I path
+and
+.I type
+in the same line.  If a device matches several lines with different
+.I  actions
+then the most permissive will apply. The ordering of policy lines
+is irrelevant to the end result.
+.TP
+.B include
+allows adding a disk to an array if metadata on that disk matches that array
+.TP
+.B re\-add
+will include the device in the array if it appears to be a current member
+or a member that was recently removed and the array has a
+write-intent-bitmap to allow the
+.B re\-add
+functionality.
+.TP
+.B spare
+as above and additionally: if the device is bare it can
+become a spare if there is any array that it is a candidate for based
+on domains and metadata.
+.TP
+.B spare\-same\-slot
+as above and additionally if given slot was used by an array that went
+degraded recently and the device plugged in has no metadata then it will
+be automatically added to that array (or it's container)
+.TP
+.B force\-spare
+as above and the disk will become a spare in remaining cases
+.RE
+
+.TP
+.B PART-POLICY
+This is similar to
+.B POLICY
+and accepts the same keyword assignments.  It allows a consistent set
+of policies to applied to each of the partitions of a device.
+
+A
+.B PART-POLICY
+line should set
+.I type=disk
+and identify the path to one or more disk devices.  Each partition on
+these disks will be treated according to the
+.I action=
+setting  from this line.  If a
+.I domain
+is set in the line, then the domain associated with each patition will
+be based on the domain, but with
+.RB \(dq -part N\(dq
+appended, when N is the partition number for the partition that was
+found.
+
+.TP
+.B SYSFS
+The
+.B SYSFS
+line lists custom values of MD device's sysfs attributes which will be
+stored in sysfs after the array is assembled. Multiple lines are allowed and each
+line has to contain the uuid or the name of the device to which it relates.
+Lines are applied in reverse order.
+.RS 4
+.TP
+.B uuid=
+hexadecimal identifier of MD device. This has to match the uuid stored in the
+superblock.
+.TP
+.B name=
+name of the MD device as was given to
+.I mdadm
+when the array was created. It will be ignored if
+.B uuid
+is not empty.
+.RE
+
+.TP
+.B MONITORDELAY
+The
+.B monitordelay
+line gives a delay in seconds
+.I mdadm
+shall wait before pooling md arrays
+when
+.I mdadm
+is running in
+.B \-\-monitor
+mode.
+.B \-d/\-\-delay
+command line argument takes precedence over the config file.
+
+If multiple
+.B MINITORDELAY
+lines are provided, only first non-zero value is considered.
+
+.SH FILES
+
+.SS {CONFFILE}
+
+The default config file location, used when
+.I mdadm
+is running without --config option.
+
+.SS {CONFFILE}.d
+
+The default directory with config files. Used when
+.I mdadm
+is running without --config option, after successful reading of the
+.B {CONFFILE}
+default config file. Files in that directory
+are read in lexical order.
+
+
+.SS {CONFFILE2}
+
+Alternative config file that is read, when
+.I mdadm
+is running without --config option and the
+.B {CONFFILE}
+default config file was not opened successfully.
+
+.SS {CONFFILE2}.d
+
+The alternative directory with config files. Used when
+.I mdadm
+is runninng without --config option, after reading the
+.B {CONFFILE2}
+alternative config file whether it was successful or not. Files in
+that directory are read in lexical order.
+
+.SH EXAMPLE
+DEVICE /dev/sd[bcdjkl]1
+.br
+DEVICE /dev/hda1 /dev/hdb1
+
+# /dev/md0 is known by its UUID.
+.br
+ARRAY /dev/md0 UUID=3aaa0122:29827cfa:5331ad66:ca767371
+.br
+# /dev/md1 contains all devices with a minor number of
+.br
+#   1 in the superblock.
+.br
+ARRAY /dev/md1 superminor=1
+.br
+# /dev/md2 is made from precisely these two devices
+.br
+ARRAY /dev/md2 devices=/dev/hda1,/dev/hdb1
+
+# /dev/md4 and /dev/md5 are a spare-group and spares
+.br
+#  can be moved between them
+.br
+ARRAY /dev/md4 uuid=b23f3c6d:aec43a9f:fd65db85:369432df
+.br
+           spare\-group=group1
+.br
+ARRAY /dev/md5 uuid=19464854:03f71b1b:e0df2edd:246cc977
+.br
+           spare\-group=group1
+.br
+# /dev/md/home is created if need to be a partitionable md array
+.br
+# any spare device number is allocated.
+.br
+ARRAY /dev/md/home UUID=9187a482:5dde19d9:eea3cc4a:d646ab8b
+.br
+           auto=part
+.br
+# The name of this array contains a space.
+.br
+ARRAY /dev/md9 name='Data Storage'
+.sp
+POLICY domain=domain1 metadata=imsm path=pci-0000:00:1f.2-scsi-*
+.br
+           action=spare
+.br
+POLICY domain=domain1 metadata=imsm path=pci-0000:04:00.0-scsi-[01]*
+.br
+           action=include
+.br
+# One domain comprising of devices attached to specified paths is defined.
+.br
+# Bare device matching first path will be made an imsm spare on hot plug.
+.br
+# If more than one array is created on devices belonging to domain1 and
+.br
+# one of them becomes degraded, then any imsm spare matching any path for
+.br
+# given domain name can be migrated.
+.br
+MAILADDR root@mydomain.tld
+.br
+PROGRAM /usr/sbin/handle\-mdadm\-events
+.br
+CREATE group=system mode=0640 auto=part\-8
+.br
+HOMEHOST <system>
+.br
+AUTO +1.x homehost \-all
+.br
+SYSFS name=/dev/md/raid5 group_thread_cnt=4 sync_speed_max=1000000
+.br
+SYSFS uuid=bead5eb6:31c17a27:da120ba2:7dfda40d group_thread_cnt=4
+sync_speed_max=1000000
+.br
+MONITORDELAY 60
+
+.SH SEE ALSO
+.BR mdadm (8),
+.BR md (4).
diff --git a/mdadm.h b/mdadm.h
index c7268a71..09915a00 100644
--- a/mdadm.h
+++ b/mdadm.h
@@ -46,6 +46,7 @@ extern __off64_t lseek64 __P ((int __fd, __off64_t __offset, int __whence));
 #include	<string.h>
 #include	<syslog.h>
 #include	<stdbool.h>
+#include	<signal.h>
 /* Newer glibc requires sys/sysmacros.h directly for makedev() */
 #include	<sys/sysmacros.h>
 #ifdef __dietlibc__
@@ -769,7 +770,7 @@ extern int restore_stripes(int *dest, unsigned long long *offsets,
 #endif
 
 #define SYSLOG_FACILITY LOG_DAEMON
-
+extern char *map_num_s(mapping_t *map, int num);
 extern char *map_num(mapping_t *map, int num);
 extern int map_name(mapping_t *map, char *name);
 extern mapping_t r0layout[], r5layout[], r6layout[],
@@ -1511,6 +1512,7 @@ extern int get_linux_version(void);
 extern int mdadm_version(char *version);
 extern unsigned long long parse_size(char *size);
 extern int parse_uuid(char *str, int uuid[4]);
+int default_layout(struct supertype *st, int level, int verbose);
 extern int is_near_layout_10(int layout);
 extern int parse_layout_10(char *layout);
 extern int parse_layout_faulty(char *layout);
@@ -1729,6 +1731,27 @@ static inline char *to_subarray(struct mdstat_ent *ent, char *container)
 	return &ent->metadata_version[10+strlen(container)+1];
 }
 
+/**
+ * signal_s() - Wrapper for sigaction() with signal()-like interface.
+ * @sig: The signal to set the signal handler to.
+ * @handler: The signal handler.
+ *
+ * Return: previous handler or SIG_ERR on failure.
+ */
+static inline sighandler_t signal_s(int sig, sighandler_t handler)
+{
+	struct sigaction new_act;
+	struct sigaction old_act;
+
+	new_act.sa_handler = handler;
+	new_act.sa_flags = 0;
+
+	if (sigaction(sig, &new_act, &old_act) == 0)
+		return old_act.sa_handler;
+
+	return SIG_ERR;
+}
+
 #ifdef DEBUG
 #define dprintf(fmt, arg...) \
 	fprintf(stderr, "%s: %s: "fmt, Name, __func__, ##arg)
diff --git a/mdadm.spec b/mdadm.spec
index 1b7c6bd8..c3598145 100644
--- a/mdadm.spec
+++ b/mdadm.spec
@@ -1,47 +1,326 @@
-Summary:     mdadm is used for controlling Linux md devices (aka RAID arrays)
-Name:        mdadm
-Version:     4.2
-Release:     1
-Source:      https://www.kernel.org/pub/linux/utils/raid/mdadm/mdadm-%{version}.tar.gz
-URL:         https://neil.brown.name/blog/mdadm
-License:     GPL
-Group:       Utilities/System
-BuildRoot:   %{_tmppath}/%{name}-root
-Obsoletes:   mdctl
+%define _unpackaged_files_terminate_build 1
+%define _stripped_files_terminate_build 1
+%set_verify_elf_method strict
+
+%def_disable cluster
+%define _sbindir /sbin
+%define nowarn -Wno-implicit-fallthrough -Wno-format-truncation -Wno-format-overflow
+
+Name: mdadm
+Version: 4.2
+Release: alt3
+
+Summary: A tool for managing Soft RAID under Linux
+License: GPLv2+
+Group: System/Configuration/Hardware
+Url: https://raid.wiki.kernel.org/index.php/Linux_Raid
+
+Vcs: https://git.kernel.org/pub/scm/utils/mdadm/mdadm.git
+Source: %name-%version.tar
+Patch: %name-%version.patch
+
+BuildRequires: binutils-devel libudev-devel
+%{?_enable_cluster:BuildRequires: libcorosync-devel libdlm-devel}
+
+# due to /lib/udev/rules.d/64-md-raid.rules
+Conflicts: udev < 151
+
+# Pull in the tool subpackage on a package update, but
+# allow it to be installed individually
+Requires: %name-tool = %EVR
 
 %description
 mdadm is a program that can be used to create, manage, and monitor
 Linux MD (Software RAID) devices.
 
+As such is provides similar functionality to the raidtools packages.
+The particular differences to raidtools is that mdadm is a single
+program, and it can perform (almost) all functions without a
+configuration file (that a config file can be used to help with
+some common tasks).
+
+%package tool
+Summary: Primary '%name' command line tool for MD arrays maintenance
+Group: System/Configuration/Hardware
+%description tool
+%summary
+
+%package doc
+Summary: Optional documentation for %name
+Group: Documentation
+BuildArch: noarch
+%description doc
+%summary
+
 %prep
-%setup -q
-# we want to install in /sbin, not /usr/sbin...
-%define _exec_prefix %{nil}
+%setup
+%patch -p1
 
 %build
-# This is a debatable issue. The author of this RPM spec file feels that
-# people who install RPMs (especially given that the default RPM options
-# will strip the binary) are not going to be running gdb against the
-# program.
-make CXFLAGS="$RPM_OPT_FLAGS" SYSCONFDIR="%{_sysconfdir}"
+%add_optflags -D_FILE_OFFSET_BITS=64
+
+%make_build mdadm mdmon CXFLAGS='%optflags %nowarn' SYSCONFDIR='%_sysconfdir'
+bzip2 -9fk ChangeLog
 
 %install
-make DESTDIR=$RPM_BUILD_ROOT MANDIR=%{_mandir} BINDIR=%{_sbindir} install
-install -D -m644 mdadm.conf-example $RPM_BUILD_ROOT/%{_sysconfdir}/mdadm.conf
+%makeinstall_std install-systemd MANDIR=%_mandir BINDIR=%_sbindir SYSTEMD_DIR=%_unitdir
+install -pD -m755 alt/mdadm.init %buildroot%_initdir/mdadm
+install -pD -m755 misc/syslog-events %buildroot%_sbindir/mdadm-syslog-events
+install -pD -m600 alt/mdadm.conf %buildroot%_sysconfdir/mdadm.conf.sample
+touch %buildroot%_sysconfdir/mdadm.conf
+# install -pD -m644 alt/mdadm.service %%buildroot%%_unitdir/mdadm.service
+ln -r -s %buildroot%_unitdir/mdmonitor.service %buildroot%_unitdir/mdadm.service
+
+install -pD -m755 alt/checkarray %buildroot%_datadir/mdadm/checkarray
+install -pD -m644 alt/mdadm.sysconfig %buildroot%_sysconfdir/sysconfig/mdadm
+install -pD -m644 alt/mdadm.crond %buildroot%_sysconfdir/cron.d/mdadm
+
+# Cleanup (need adapt for mdadm_env.sh)
+rm -f %buildroot%_unitdir/{mdmonitor-oneshot,mdcheck_continue,mdcheck_start}.{service,timer}
+
+%post -f alt/raidtabtomdadm.sh
+%post_service mdadm
 
-%clean
-rm -rf $RPM_BUILD_ROOT
+%preun
+%preun_service mdadm
 
 %files
-%defattr(-,root,root)
-%doc TODO ChangeLog mdadm.conf-example COPYING
-%{_sbindir}/mdadm
-%{_sbindir}/mdmon
-/usr/lib/udev/rules.d/01-md-raid-creating.rules
-/usr/lib/udev/rules.d/63-md-raid-arrays.rules
-/usr/lib/udev/rules.d/64-md-raid-assembly.rules
-/usr/lib/udev/rules.d/69-md-clustered-confirm-device.rules
-%config(noreplace,missingok)/%{_sysconfdir}/mdadm.conf
-%{_mandir}/man*/md*
+%_sbindir/mdadm-syslog-events
+%_sbindir/mdmon
+%_man8dir/mdmon.*
+%config %_sysconfdir/mdadm.conf.sample
+%config(noreplace) %_sysconfdir/sysconfig/mdadm
+%_sysconfdir/cron.d/mdadm
+%_initdir/mdadm
+%_datadir/mdadm/
+/lib/udev/rules.d/01-md-raid-creating.rules
+/lib/udev/rules.d/63-md-raid-arrays.rules
+/lib/udev/rules.d/64-md-raid-assembly.rules
+/lib/udev/rules.d/69-md-clustered-confirm-device.rules
+%_unitdir/*
+/lib/systemd/system-shutdown/mdadm.shutdown
+
+%files tool
+%_sbindir/mdadm
+%_man8dir/mdadm.*
+%_man4dir/md.*
+%_man5dir/mdadm.conf.*
+%ghost %config(noreplace,missingok) %_sysconfdir/mdadm.conf
+
+%files doc
+%doc TODO ChangeLog.* mdadm.conf-example ANNOUNCE-%version alt/README*
 
 %changelog
+* Fri Mar 24 2023 Oleg Solovyov <mcpain@altlinux.org> 4.2-alt3
+- add mdmon.service
+
+* Mon Jun 06 2022 Alexey Shabalin <shaba@altlinux.org> 4.2-alt2
+- upstream snapshot 52c67fcdd6dadc4138ecad73e65599551804d445
+
+* Fri Jan 07 2022 Alexey Shabalin <shaba@altlinux.org> 4.2-alt1
+- 4.2
+
+* Mon Oct 11 2021 Aleksei Nikiforov <darktemplar@altlinux.org> 4.1-alt4
+- Fixed build with gcc-11
+
+* Wed Mar 10 2021 Slava Aseev <ptrnine@altlinux.org> 4.1-alt3
+- fix ftbfs due to -Werror=stringop-truncation
+
+* Thu Apr 02 2020 Alexey Shabalin <shaba@altlinux.org> 4.1-alt2
+- backported fixes from upstream
+
+* Wed Nov 28 2018 Alexey Shabalin <shaba@altlinux.org> 4.1-alt1
+- 4.1
+
+* Fri Mar 30 2018 Gremlin from Kremlin <gremlin@altlinux.ru> 4.0-alt2
+- move the primary 'mdadm' tool to separate subpackage with minimized
+  dependencies
+- move documentation to separate subpackage (so the people can read it
+  without installing the full package)
+
+* Tue Jan 17 2017 Alexey Shabalin <shaba@altlinux.ru> 4.0-alt1
+- 4.0
+
+* Thu Jun 16 2016 Alexey Shabalin <shaba@altlinux.ru> 3.4-alt1
+- 3.4
+
+* Tue Aug 11 2015 Alexey Shabalin <shaba@altlinux.ru> 3.3.4-alt1
+- 3.3.4
+
+* Mon Sep 01 2014 Alexey Shabalin <shaba@altlinux.ru> 3.3.2-alt1
+- 3.3.2
+
+* Tue Jun 17 2014 Alexey Shabalin <shaba@altlinux.ru> 3.3.1-alt1
+- 3.3.1
+
+* Mon Oct 07 2013 Alexey Shabalin <shaba@altlinux.ru> 3.3-alt1
+- 3.3
+
+* Mon May 13 2013 Alexey Shabalin <shaba@altlinux.ru> 3.2.6-alt3
+- modernize udev rules
+
+* Tue Jan 22 2013 Alexey Shabalin <shaba@altlinux.ru> 3.2.6-alt2
+- drop mdadm-activation.service
+
+* Thu Nov 22 2012 Alexey Shabalin <shaba@altlinux.ru> 3.2.6-alt1
+- 3.2.6
+- add mdadm-activation.service (and add to autorun)
+
+* Tue Jul 03 2012 Vitaly Kuznetsov <vitty@altlinux.ru> 3.2.5-alt1
+- 3.2.5
+
+* Tue Jan 31 2012 Vitaly Kuznetsov <vitty@altlinux.ru> 3.2.3-alt1
+- 3.2.3
+
+* Sat Aug 06 2011 Vitaly Kuznetsov <vitty@altlinux.ru> 3.2.2-alt2
+- fix AUTOCHECK check in autocheck script (ALT #25641)
+
+* Thu Jul 28 2011 Vitaly Kuznetsov <vitty@altlinux.ru> 3.2.2-alt1
+- 3.2.2
+
+* Mon May 23 2011 Vitaly Kuznetsov <vitty@altlinux.ru> 3.1.4-alt3
+- add crond job for periodical array check (ALT #25641)
+
+* Fri May 20 2011 Vitaly Kuznetsov <vitty@altlinux.ru> 3.1.4-alt2
+- shaba@:
+    add mdadm.service for systemd
+
+* Mon Sep 20 2010 Vitaly Kuznetsov <vitty@altlinux.ru> 3.1.4-alt1
+- Updated to mdadm-3.1.4-2-ga2ce5a1 (closes: #23792).
+- Packaged README.recipes from Debian (closes: #11518).
+- Packaged mdmon.
+- Dropped unused mdassemble.
+- Cleaned up specfile and startup script.
+
+* Sun Sep 19 2010 Vitaly Kuznetsov <vitty@altlinux.ru> 2.6.3-alt2
+- pack 64-md-raid.rules (removed by udev upstream in ver. 151)
+
+* Wed Aug 22 2007 Ilya Evseev <evseev@altlinux.ru> 2.6.3-alt1
+- updated to new version 2.6.3
+
+* Tue May 22 2007 Ilya Evseev <evseev@altlinux.ru> 2.6.2-alt1
+- updated to new version 2.6.2, fix patch #3
+
+* Mon Apr 16 2007 Dmitry V. Levin <ldv@altlinux.org> 2.6.1-alt3.1
+- mdadm.init: Fixed typo introduced in 2.6.1-alt3 release.
+- %%triggerun: Removed.
+- %%triggerin: Do not spam on every package update.
+
+* Sun Apr 15 2007 Ilya Evseev <evseev@altlinux.ru> 2.6.1-alt3
+- bugfixes:
+   + 11021: shutdown previous versions of mdadm at /usr/sbin on RPM upgrade
+   + 11431: dont start service when no records in /proc/mdstat
+
+* Sat Mar  3 2007 Ilya Evseev <evseev@altlinux.ru> 2.6.1-alt2
+- fixed installation path for mdadm-syslog-events
+
+* Sat Mar  3 2007 Ilya Evseev <evseev@altlinux.ru> 2.6.1-alt1
+- updated to version 2.6.1, simplify patch #3
+- bugfixes:
+   + 10357 (mdassemble crashes because dietlibc < 0.30-alt2
+            with gcc4.1 needs -fno-stack-protector)
+   + 10727 (missing mdassemble.8 manpage)
+   + 10782 (strange events in mdmonitor - possibly fixed in upstream?)
+   + 10909 (change 740 permissions to 755)
+   + 10910 (support condstop in service script)
+   + 10915 (move binaries from /usr/sbin to /sbin)
+
+* Wed Jan 24 2007 Ilya Evseev <evseev@altlinux.ru> 2.6-alt2
+- fixed x86_64 problems
+
+* Mon Jan 22 2007 Ilya Evseev <evseev@altlinux.ru> 2.6-alt1
+- updated to new version 2.6
+
+* Wed Nov 22 2006 Ilya Evseev <evseev@altlinux.ru> 2.5.6-alt1
+- updated to new version 2.5.6
+
+* Fri Oct 27 2006 Ilya Evseev <evseev@altlinux.ru> 2.5.5-alt1
+- updated to new version 2.5.5
+- patch for ignoring asprintf result (yes, I know that's dirty..)
+
+* Sat Sep  2 2006 Ilya Evseev <evseev@altlinux.ru> 2.5.3-alt2
+- fixed dietlibc-related problems (#9939) on x86_64
+- added optional disabling of dietlibc usage
+
+* Tue Aug  8 2006 Ilya Evseev <evseev@altlinux.ru> 2.5.3-alt1
+- updated to new version 2.5.3
+
+* Tue Jul 25 2006 Ilya Evseev <evseev@altlinux.ru> 2.5.2-alt1
+- updated to new version 2.5.2
+
+* Thu Jun 22 2006 Ilya Evseev <evseev@altlinux.ru> 2.5.1-alt1
+- updated to new version 2.5.1
+- patch #1 is no more needed because the same thing is now in the upstream
+- fixup command line arguments for mdassemble build
+
+* Mon May 29 2006 Ilya Evseev <evseev@altlinux.ru> 2.5-alt2
+- added patch #1 for omitting openssl dependency
+- little description changes
+
+* Fri May 26 2006 Ilya Evseev <evseev@altlinux.ru> 2.5-alt1
+- updated to new version 2.5
+
+* Fri Apr 28 2006 Ilya Evseev <evseev@altlinux.ru> 2.4.1-alt1
+- updated to new version 2.4.1
+
+* Thu Feb  9 2006 Ilya Evseev <evseev@altlinux.ru> 2.3.1-alt1
+- updated to new version 2.3.1
+
+* Fri Feb  3 2006 Ilya Evseev <evseev@altlinux.ru> 2.3-alt1
+- updated to new version 2.3
+- small specfile improvements:
+   + mdadm stuff was compiled twice
+   + more strict permissions for installed stuff
+
+* Fri Oct 14 2005 Ilya Evseev <evseev@altlinux.ru> 2.1-alt3
+- more once attempt to break new Sysiphus restrictions
+  (halt on undefined macros even they are commented)
+
+* Mon Oct 10 2005 Ilya Evseev <evseev@altlinux.ru> 2.1-alt2
+- added workaround for new Sisyphus restriction:
+  all macros should be defined even they are referenced in comments.
+
+* Fri Sep 16 2005 Ilya Evseev <evseev@altlinux.ru> 2.1-alt1
+- update to new version
+
+* Wed Jul 27 2005 Ilya Evseev <evseev@altlinux.ru> 1.12.0-alt2
+- bugfix #7087 (use grep instead of egrep in service script)
+- watch udev (un)install and display warnings about changed devices naming
+- created our own minimalistic configuration file for mdmonitor;
+  however, it should be completely functional in most cases
+
+* Wed Jul 13 2005 Michael Shigorin <mike@altlinux.org> 1.12.0-alt1
+- 1.12.0
+- removed peet@'s patch (fixed in 1.11.0)
+
+* Thu May 12 2005 Peter V. Saveliev <peet@altlinux.ru> 1.10.0-rad1
+- fixed device add
+
+* Sun Apr 10 2005 Ilya Evseev <evseev@altlinux.ru> 1.10.0-alt1
+- updated to 1.10.0, fixed segfault on 'mdadm -c partitions'
+- changed project URL and source URL
+- mdassemble cannot be disabled; it's installed to /sbin
+- documentation: placed patch that should be applied to /etc/rc.d/rc.sysinit
+  (see details on https://bugzilla.altlinux.org/show_bug.cgi?id=6322 and 6397)
+
+* Tue Mar 8 2005 Ilya Evseev <evseev@altlinux.ru> 1.9.0-alt1
+- 1.9.0
+- specfile:
+   + added russian summary and description,
+   + changed source URL,
+   + added mdmpd reference.
+- taken from Mdk:
+   + service init script,
+   + raidtools conversion script,
+   + diet libc bindings (may be turned off).
+
+* Mon Jan 26 2004 Dmitry V. Levin <ldv@altlinux.org> 1.5.0-alt1
+- Updated to 1.5.0.
+
+* Thu Dec 18 2003 Dmitry V. Levin <ldv@altlinux.org> 1.4.0-alt1
+- Updated to 1.4.0.
+- Specfile cleanup.
+
+* Tue May 20 2003 Alexander Bokovoy <ab@altlinux.ru> 1.2.0-alt1
+- Initial build for ALT Linux Sisyphus
+
diff --git a/mdmon.c b/mdmon.c
index c71e62c6..5570574b 100644
--- a/mdmon.c
+++ b/mdmon.c
@@ -56,7 +56,6 @@
 #include	<errno.h>
 #include	<string.h>
 #include	<fcntl.h>
-#include	<signal.h>
 #include	<dirent.h>
 #ifdef USE_PTHREADS
 #include	<pthread.h>
diff --git a/monitor.c b/monitor.c
index e0d3be67..b877e595 100644
--- a/monitor.c
+++ b/monitor.c
@@ -22,7 +22,6 @@
 #include "mdmon.h"
 #include <sys/syscall.h>
 #include <sys/select.h>
-#include <signal.h>
 
 static char *array_states[] = {
 	"clear", "inactive", "suspended", "readonly", "read-auto",
diff --git a/probe_roms.c b/probe_roms.c
index 7ea04c7a..94c80c2c 100644
--- a/probe_roms.c
+++ b/probe_roms.c
@@ -22,7 +22,6 @@
 #include "probe_roms.h"
 #include "mdadm.h"
 #include <unistd.h>
-#include <signal.h>
 #include <fcntl.h>
 #include <sys/mman.h>
 #include <sys/stat.h>
@@ -69,7 +68,8 @@ static int probe_address16(const __u16 *ptr, __u16 *val)
 
 void probe_roms_exit(void)
 {
-	signal(SIGBUS, SIG_DFL);
+	signal_s(SIGBUS, SIG_DFL);
+
 	if (rom_fd >= 0) {
 		close(rom_fd);
 		rom_fd = -1;
@@ -98,7 +98,7 @@ int probe_roms_init(unsigned long align)
 	if (roms_init())
 		return -1;
 
-	if (signal(SIGBUS, sigbus) == SIG_ERR)
+	if (signal_s(SIGBUS, sigbus) == SIG_ERR)
 		rc = -1;
 	if (rc == 0) {
 		fd = open("/dev/mem", O_RDONLY);
diff --git a/raid6check.c b/raid6check.c
index a8e6005b..99477761 100644
--- a/raid6check.c
+++ b/raid6check.c
@@ -24,7 +24,6 @@
 
 #include "mdadm.h"
 #include <stdint.h>
-#include <signal.h>
 #include <sys/mman.h>
 
 #define CHECK_PAGE_BITS (12)
@@ -130,30 +129,36 @@ void raid6_stats(int *disk, int *results, int raid_disks, int chunk_size)
 }
 
 int lock_stripe(struct mdinfo *info, unsigned long long start,
-		int chunk_size, int data_disks, sighandler_t *sig) {
+		int chunk_size, int data_disks, sighandler_t *sig)
+{
 	int rv;
+
+	sig[0] = signal_s(SIGTERM, SIG_IGN);
+	sig[1] = signal_s(SIGINT, SIG_IGN);
+	sig[2] = signal_s(SIGQUIT, SIG_IGN);
+
+	if (sig[0] == SIG_ERR || sig[1] == SIG_ERR || sig[2] == SIG_ERR)
+		return 1;
+
 	if(mlockall(MCL_CURRENT | MCL_FUTURE) != 0) {
 		return 2;
 	}
 
-	sig[0] = signal(SIGTERM, SIG_IGN);
-	sig[1] = signal(SIGINT, SIG_IGN);
-	sig[2] = signal(SIGQUIT, SIG_IGN);
-
 	rv = sysfs_set_num(info, NULL, "suspend_lo", start * chunk_size * data_disks);
 	rv |= sysfs_set_num(info, NULL, "suspend_hi", (start + 1) * chunk_size * data_disks);
 	return rv * 256;
 }
 
-int unlock_all_stripes(struct mdinfo *info, sighandler_t *sig) {
+int unlock_all_stripes(struct mdinfo *info, sighandler_t *sig)
+{
 	int rv;
 	rv = sysfs_set_num(info, NULL, "suspend_lo", 0x7FFFFFFFFFFFFFFFULL);
 	rv |= sysfs_set_num(info, NULL, "suspend_hi", 0);
 	rv |= sysfs_set_num(info, NULL, "suspend_lo", 0);
 
-	signal(SIGQUIT, sig[2]);
-	signal(SIGINT, sig[1]);
-	signal(SIGTERM, sig[0]);
+	signal_s(SIGQUIT, sig[2]);
+	signal_s(SIGINT, sig[1]);
+	signal_s(SIGTERM, sig[0]);
 
 	if(munlockall() != 0)
 		return 3;
diff --git a/super-ddf.c b/super-ddf.c
index 3f304cdc..8cda23a7 100644
--- a/super-ddf.c
+++ b/super-ddf.c
@@ -1477,13 +1477,13 @@ static void examine_vds(struct ddf_super *sb)
 		printf("\n");
 		printf("         unit[%d] : %d\n", i, be16_to_cpu(ve->unit));
 		printf("        state[%d] : %s, %s%s\n", i,
-		       map_num(ddf_state, ve->state & 7),
+		       map_num_s(ddf_state, ve->state & 7),
 		       (ve->state & DDF_state_morphing) ? "Morphing, ": "",
 		       (ve->state & DDF_state_inconsistent)? "Not Consistent" : "Consistent");
 		printf("   init state[%d] : %s\n", i,
-		       map_num(ddf_init_state, ve->init_state&DDF_initstate_mask));
+		       map_num_s(ddf_init_state, ve->init_state & DDF_initstate_mask));
 		printf("       access[%d] : %s\n", i,
-		       map_num(ddf_access, (ve->init_state & DDF_access_mask) >> 6));
+		       map_num_s(ddf_access, (ve->init_state & DDF_access_mask) >> 6));
 		printf("         Name[%d] : %.16s\n", i, ve->name);
 		examine_vd(i, sb, ve->guid);
 	}
diff --git a/super-intel.c b/super-intel.c
index d5fad102..ba3bd41f 100644
--- a/super-intel.c
+++ b/super-intel.c
@@ -5625,7 +5625,7 @@ static int init_super_imsm_volume(struct supertype *st, mdu_array_info_t *info,
 		free(dev);
 		free(dv);
 		pr_err("imsm does not support consistency policy %s\n",
-		       map_num(consistency_policies, s->consistency_policy));
+		       map_num_s(consistency_policies, s->consistency_policy));
 		return 0;
 	}
 
@@ -11683,8 +11683,8 @@ enum imsm_reshape_type imsm_analyze_change(struct supertype *st,
 		struct imsm_super *mpb = super->anchor;
 
 		if (mpb->num_raid_devs > 1) {
-			pr_err("Error. Cannot perform operation on %s- for this operation it MUST be single array in container\n",
-			       geo->dev_name);
+			pr_err("Error. Cannot perform operation on %s- for this operation "
+			       "it MUST be single array in container\n", geo->dev_name);
 			change = -1;
 		}
 	}
@@ -11783,9 +11783,8 @@ static int imsm_fix_size_mismatch(struct supertype *st, int subarray_index)
 			st->update_tail = &st->updates;
 		} else {
 			imsm_sync_metadata(st);
+			free(update);
 		}
-
-		free(update);
 	}
 	ret_val = 0;
 exit:
diff --git a/super0.c b/super0.c
index b79b97a9..61c9ec1d 100644
--- a/super0.c
+++ b/super0.c
@@ -288,7 +288,7 @@ static void export_examine_super0(struct supertype *st)
 {
 	mdp_super_t *sb = st->sb;
 
-	printf("MD_LEVEL=%s\n", map_num(pers, sb->level));
+	printf("MD_LEVEL=%s\n", map_num_s(pers, sb->level));
 	printf("MD_DEVICES=%d\n", sb->raid_disks);
 	if (sb->minor_version >= 90)
 		printf("MD_UUID=%08x:%08x:%08x:%08x\n",
diff --git a/super1.c b/super1.c
index a12a5bc8..e3e2f954 100644
--- a/super1.c
+++ b/super1.c
@@ -671,7 +671,7 @@ static void export_examine_super1(struct supertype *st)
 	int len = 32;
 	int layout;
 
-	printf("MD_LEVEL=%s\n", map_num(pers, __le32_to_cpu(sb->level)));
+	printf("MD_LEVEL=%s\n", map_num_s(pers, __le32_to_cpu(sb->level)));
 	printf("MD_DEVICES=%d\n", __le32_to_cpu(sb->raid_disks));
 	for (i = 0; i < 32; i++)
 		if (sb->set_name[i] == '\n' || sb->set_name[i] == '\0') {
diff --git a/sysfs.c b/sysfs.c
index 2995713d..0d98a65f 100644
--- a/sysfs.c
+++ b/sysfs.c
@@ -689,7 +689,7 @@ int sysfs_set_array(struct mdinfo *info, int vers)
 	if (info->array.level < 0)
 		return 0; /* FIXME */
 	rv |= sysfs_set_str(info, NULL, "level",
-			    map_num(pers, info->array.level));
+			    map_num_s(pers, info->array.level));
 	if (info->reshape_active && info->delta_disks != UnSet)
 		raid_disks -= info->delta_disks;
 	rv |= sysfs_set_num(info, NULL, "raid_disks", raid_disks);
@@ -724,9 +724,10 @@ int sysfs_set_array(struct mdinfo *info, int vers)
 	}
 
 	if (info->consistency_policy == CONSISTENCY_POLICY_PPL) {
-		if (sysfs_set_str(info, NULL, "consistency_policy",
-				  map_num(consistency_policies,
-					  info->consistency_policy))) {
+		char *policy = map_num_s(consistency_policies,
+					    info->consistency_policy);
+
+		if (sysfs_set_str(info, NULL, "consistency_policy", policy)) {
 			pr_err("This kernel does not support PPL. Falling back to consistency-policy=resync.\n");
 			info->consistency_policy = CONSISTENCY_POLICY_RESYNC;
 		}
diff --git a/systemd/mdadm-grow-continue@.service b/systemd/mdadm-grow-continue@.service
index 5c667d2a..9fdc8ec7 100644
--- a/systemd/mdadm-grow-continue@.service
+++ b/systemd/mdadm-grow-continue@.service
@@ -14,4 +14,3 @@ ExecStart=BINDIR/mdadm --grow --continue /dev/%I
 StandardInput=null
 StandardOutput=null
 StandardError=null
-KillMode=none
diff --git a/systemd/mdmon.service b/systemd/mdmon.service
new file mode 100644
index 00000000..396a4a6e
--- /dev/null
+++ b/systemd/mdmon.service
@@ -0,0 +1,10 @@
+[Unit]
+Description=MD Metadata Monitor on containers
+DefaultDependencies=no
+Before=initrd-switch-root.target
+
+[Service]
+Environment=IMSM_NO_PLATFORM=1
+ExecStart=BINDIR/mdmon --offroot --takeover --all
+Type=forking
+KillMode=none
diff --git a/systemd/mdmonitor.service b/systemd/mdmonitor.service
index 46f7b880..712f93a4 100644
--- a/systemd/mdmonitor.service
+++ b/systemd/mdmonitor.service
@@ -10,7 +10,5 @@ Description=MD array monitor
 DefaultDependencies=no
 
 [Service]
-Environment=  MDADM_MONITOR_ARGS=--scan
-EnvironmentFile=-/run/sysconfig/mdadm
-ExecStartPre=-/usr/lib/mdadm/mdadm_env.sh
-ExecStart=BINDIR/mdadm --monitor $MDADM_MONITOR_ARGS
+EnvironmentFile=/etc/sysconfig/mdadm
+ExecStart=BINDIR/mdadm --monitor --scan $MDADM_MONITOR_ARGS
diff --git a/udev-md-raid-arrays.rules b/udev-md-raid-arrays.rules
index 13c9076e..3a3e4095 100644
--- a/udev-md-raid-arrays.rules
+++ b/udev-md-raid-arrays.rules
@@ -3,7 +3,7 @@
 SUBSYSTEM!="block", GOTO="md_end"
 
 # handle md arrays
-ACTION!="add|change", GOTO="md_end"
+ACTION=="remove", GOTO="md_end"
 KERNEL!="md*", GOTO="md_end"
 
 # partitions have no md/{array_state,metadata_version}, but should not
@@ -37,8 +37,8 @@ ENV{ID_FS_USAGE}=="filesystem|other", ENV{ID_FS_LABEL_ENC}=="?*", SYMLINK+="disk
 ENV{MD_LEVEL}=="raid[1-9]*", ENV{SYSTEMD_WANTS}+="mdmonitor.service"
 
 # Tell systemd to run mdmon for our container, if we need it.
-ENV{MD_LEVEL}=="raid[1-9]*", ENV{MD_CONTAINER}=="?*", PROGRAM="/usr/bin/readlink $env{MD_CONTAINER}", ENV{MD_MON_THIS}="%c"
-ENV{MD_MON_THIS}=="?*", PROGRAM="/usr/bin/basename $env{MD_MON_THIS}", ENV{SYSTEMD_WANTS}+="mdmon@%c.service"
-ENV{RESHAPE_ACTIVE}=="yes", PROGRAM="/usr/bin/basename $env{MD_MON_THIS}", ENV{SYSTEMD_WANTS}+="mdadm-grow-continue@%c.service"
+ENV{MD_LEVEL}=="raid[1-9]*", ENV{MD_CONTAINER}=="?*", PROGRAM="/bin/readlink $env{MD_CONTAINER}", ENV{MD_MON_THIS}="%c"
+ENV{MD_MON_THIS}=="?*", PROGRAM="/bin/basename $env{MD_MON_THIS}", ENV{SYSTEMD_WANTS}+="mdmon@%c.service"
+ENV{RESHAPE_ACTIVE}=="yes", PROGRAM="/bin/basename $env{MD_MON_THIS}", ENV{SYSTEMD_WANTS}+="mdadm-grow-continue@%c.service"
 
 LABEL="md_end"
diff --git a/udev-md-raid-assembly.rules b/udev-md-raid-assembly.rules
index d668cddd..39b4344b 100644
--- a/udev-md-raid-assembly.rules
+++ b/udev-md-raid-assembly.rules
@@ -30,8 +30,9 @@ LABEL="md_inc"
 
 # remember you can limit what gets auto/incrementally assembled by
 # mdadm.conf(5)'s 'AUTO' and selectively whitelist using 'ARRAY'
-ACTION=="add|change", IMPORT{program}="BINDIR/mdadm --incremental --export $devnode --offroot $env{DEVLINKS}"
-ACTION=="add|change", ENV{MD_STARTED}=="*unsafe*", ENV{MD_FOREIGN}=="no", ENV{SYSTEMD_WANTS}+="mdadm-last-resort@$env{MD_DEVICE}.timer"
+ACTION!="remove", IMPORT{program}="BINDIR/mdadm --incremental --export $devnode --offroot $env{DEVLINKS}"
+ACTION!="remove", ENV{MD_STARTED}=="*unsafe*", ENV{MD_FOREIGN}=="no", ENV{SYSTEMD_WANTS}+="mdadm-last-resort@$env{MD_DEVICE}.timer"
+
 ACTION=="remove", ENV{ID_PATH}=="?*", RUN+="BINDIR/mdadm -If $name --path $env{ID_PATH}"
 ACTION=="remove", ENV{ID_PATH}!="?*", RUN+="BINDIR/mdadm -If $name"
 
diff --git a/udev-md-raid-safe-timeouts.rules b/udev-md-raid-safe-timeouts.rules
index 12bdcaa8..2e185cee 100644
--- a/udev-md-raid-safe-timeouts.rules
+++ b/udev-md-raid-safe-timeouts.rules
@@ -50,7 +50,7 @@ ENV{DEVTYPE}!="partition", GOTO="md_timeouts_end"
 
 IMPORT{program}="/sbin/mdadm --examine --export $devnode"
 
-ACTION=="add|change", \
+ACTION!="remove", \
   ENV{ID_FS_TYPE}=="linux_raid_member", \
   ENV{MD_LEVEL}=="raid[1-9]*", \
   TEST=="/sys/block/$parent/device/timeout", \
diff --git a/util.c b/util.c
index 3d05d074..cc94f96e 100644
--- a/util.c
+++ b/util.c
@@ -35,7 +35,6 @@
 #include	<poll.h>
 #include	<ctype.h>
 #include	<dirent.h>
-#include	<signal.h>
 #include	<dlfcn.h>
 
 
 
design & coding: Vladimir Lettiev aka crux © 2004-2005, Andrew Avramenko aka liks © 2007-2008
current maintainer: Michael Shigorin