Hello community,

here is the log from the commit of package mdadm for openSUSE:Factory checked 
in at 2013-12-06 11:46:05
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/mdadm (Old)
 and      /work/SRC/openSUSE:Factory/.mdadm.new (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "mdadm"

Changes:
--------
--- /work/SRC/openSUSE:Factory/mdadm/mdadm.changes      2013-11-12 
09:51:54.000000000 +0100
+++ /work/SRC/openSUSE:Factory/.mdadm.new/mdadm.changes 2013-12-06 
11:46:06.000000000 +0100
@@ -1,0 +2,24 @@
+Wed Dec  4 23:57:16 UTC 2013 - nfbr...@suse.com
+
+- Assemble-Incremental-don-t-hold-O_EXCL-on-mddev-afte.patch
+  Ensure fsck/mount don't find an md array to be BUSY
+  the moment it appears.
+- mkinitrd-setup.sh: Make the array device names in
+  /etc/mdadm.conf in the initrd match those in /etc/mdadm.conf
+  in the root filesystem.  (bnc#851993)
+
+-------------------------------------------------------------------
+Tue Dec  3 03:06:07 UTC 2013 - nfbr...@suse.com
+
+- Restructure-assemble_container_content-and-improve-m.patch
+- Incremental-add-export-handling.patch
+- udev-rules.degraded
+- systemd-mdadm-last-resort@.service
+- systemd-mdadm-last-resort@.timer
+  Teach systemd to start degraded arrays after a timeout if
+  some missing devices never appear (bnc#832501)
+- Incremental-improve-support-for-DEVICE-based-restric.patch
+  Teach "mdadm --incremental" to handle "DEVICE" lists from
+  mdadm.conf properly (bnc@851993)
+
+-------------------------------------------------------------------

New:
----
  Assemble-Incremental-don-t-hold-O_EXCL-on-mddev-afte.patch
  Incremental-add-export-handling.patch
  Incremental-improve-support-for-DEVICE-based-restric.patch
  Restructure-assemble_container_content-and-improve-m.patch
  systemd-mdadm-last-resort@.service
  systemd-mdadm-last-resort@.timer
  udev-rules.degraded

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ mdadm.spec ++++++
--- /var/tmp/diff_new_pack.JTd7H1/_old  2013-12-06 11:46:08.000000000 +0100
+++ /var/tmp/diff_new_pack.JTd7H1/_new  2013-12-06 11:46:08.000000000 +0100
@@ -43,6 +43,8 @@
 Source6:        mkinitrd-boot.sh
 Source7:        mdadm.cron
 Source8:        mdadm.shutdown
+Source9:        systemd-mdadm-last-resort@.timer
+Source10:       systemd-mdadm-last-resort@.service
 # PATCH-FIX-UPSTREAM config-set-auto_seen-after-processing-the-auto-line.patch 
upstream-bugfix nfbr...@suse.de
 Patch1:         config-set-auto_seen-after-processing-the-auto-line.patch
 # PATCH-FIX-UPSTREAM 
DDF-allow-for-possibility-that-there-is-no-secondary.patch upstream-bugfix 
nfbr...@suse.de
@@ -67,6 +69,16 @@
 Patch11:        Monitor-write-meta-data-in-readonly-state-sometimes.patch
 # PATCH-FIX-UPSTREAM 
Assembe-fix-bug-in-force_array-it-wasn-t-forcing-pro.patch upstream-bugfix 
nfbr...@suse.de
 Patch12:        Assembe-fix-bug-in-force_array-it-wasn-t-forcing-pro.patch
+# PATCH-FEATURE-UPSTREAM 
Restructure-assemble_container_content-and-improve-m.patch bnc#832501 
nfbr...@suse.de
+Patch13:        Restructure-assemble_container_content-and-improve-m.patch
+# PATCH-FEATURE-UPSTREAM Incremental-add-export-handling.patch bnc#832501 
nfbr...@suse.de
+Patch14:        Incremental-add-export-handling.patch
+# PATCH-FEATURE-UPSTREAM udev-rules.degraded bnc#832501 nfbr...@suse.de
+Patch15:        udev-rules.degraded
+# PATCH-FEATURE-UPSTREAM 
Incremental-improve-support-for-DEVICE-based-restric.patch bnc#851993 
nfbr...@suse.de
+Patch16:        Incremental-improve-support-for-DEVICE-based-restric.patch
+# PATCH-FIX-UPSTREAM 
Assemble-Incremental-don-t-hold-O_EXCL-on-mddev-afte.patch nfbr...@suse.de
+Patch17:        Assemble-Incremental-don-t-hold-O_EXCL-on-mddev-afte.patch
 
 %define _udevdir %(pkg-config --variable=udevdir udev)
 %define _systemdshutdowndir %{_unitdir}/../system-shutdown
@@ -90,6 +102,11 @@
 %patch10 -p1
 %patch11 -p1
 %patch12 -p1
+%patch13 -p1
+%patch14 -p1
+%patch15 -p1
+%patch16 -p1
+%patch17 -p1
 
 %build
 make %{?_smp_mflags} CC="%__cc" CXFLAGS="$RPM_OPT_FLAGS -Wno-error"
@@ -112,6 +129,8 @@
 ln -sf ../../etc/init.d/mdadmd %{buildroot}/%{_sbindir}/rcmdadmd
 install -d %{buildroot}%{_systemdshutdowndir}
 install -m 755 %{S:8} %{buildroot}%{_systemdshutdowndir}/mdadm.shutdown
+install -m 644 %{S:9} %{buildroot}%{_unitdir}/mdadm-last-resort@.timer
+install -m 644 %{S:10} %{buildroot}%{_unitdir}/mdadm-last-resort@.service
 
 %post
 [ -x /sbin/mkinitrd_setup ] && mkinitrd_setup
@@ -162,5 +181,7 @@
 /etc/cron.daily/mdadm
 %{_systemdshutdowndir}/mdadm.shutdown
 %{_unitdir}/mdmon@.service
+%{_unitdir}/mdadm-last-resort@.timer
+%{_unitdir}/mdadm-last-resort@.service
 
 %changelog

++++++ Assemble-Incremental-don-t-hold-O_EXCL-on-mddev-afte.patch ++++++
>From 8832342d3aad09d3c86af6dc9b137d6fd83af1ae Mon Sep 17 00:00:00 2001
From: NeilBrown <ne...@suse.de>
Date: Thu, 5 Dec 2013 10:35:16 +1100
Subject: [PATCH] Assemble/Incremental: don't hold O_EXCL on mddev after
 assembly.

As soon as the array is assembled, udev or systemd might run
fsck and mount it.  So we need to drop O_EXCL promptly.

Signed-off-by: NeilBrown <ne...@suse.de>
---
 Assemble.c    |  1 +
 Incremental.c | 10 +++++++---
 mdadm.h       |  1 +
 util.c        | 14 ++++++++++++++
 4 files changed, 23 insertions(+), 3 deletions(-)

diff --git a/Assemble.c b/Assemble.c
index 44e905bb8667..7e8e79570352 100644
--- a/Assemble.c
+++ b/Assemble.c
@@ -1037,6 +1037,7 @@ static int start_array(int mdfd,
                } else
 #endif
                        rv = ioctl(mdfd, RUN_ARRAY, NULL);
+               reopen_mddev(mdfd); /* drop O_EXCL */
                if (rv == 0) {
                        if (c->verbose >= 0) {
                                pr_err("%s has been started with %d drive%s",
diff --git a/Incremental.c b/Incremental.c
index f548bad9785d..c9372587f518 100644
--- a/Incremental.c
+++ b/Incremental.c
@@ -588,10 +588,14 @@ int Incremental(struct mddev_dev *devlist, struct context 
*c,
                else
                        rv = sysfs_set_str(sra, NULL,
                                           "array_state", "read-auto");
+               /* Array might be O_EXCL which  will interfere with
+                * fsck and mount.  So re-open without O_EXCL.
+                */
+               reopen_mddev(mdfd);
                if (rv == 0) {
-               if (c->export) {
-                       printf("MD_STARTED=yes\n");
-               } else if (c->verbose >= 0)
+                       if (c->export) {
+                               printf("MD_STARTED=yes\n");
+                       } else if (c->verbose >= 0)
                                pr_err("%s attached to %s, which has been 
started.\n",
                                       devname, chosen_name);
                        rv = 0;
diff --git a/mdadm.h b/mdadm.h
index 69facaf32956..7f222a6d7a78 100644
--- a/mdadm.h
+++ b/mdadm.h
@@ -1272,6 +1272,7 @@ extern int check_partitions(int fd, char *dname,
 extern int get_mdp_major(void);
 extern int dev_open(char *dev, int flags);
 extern int open_dev(char *devnm);
+extern void reopen_mddev(int mdfd);
 extern int open_dev_flags(char *devnm, int flags);
 extern int open_dev_excl(char *devnm);
 extern int is_standard(char *dev, int *nump);
diff --git a/util.c b/util.c
index 12a19e7a5a3a..e32d97a011e7 100644
--- a/util.c
+++ b/util.c
@@ -1950,3 +1950,17 @@ int in_initrd(void)
                ((unsigned long)s.f_type == TMPFS_MAGIC ||
                 (unsigned long)s.f_type == RAMFS_MAGIC);
 }
+
+void reopen_mddev(int mdfd)
+{
+       /* Re-open without any O_EXCL, but keep
+        * the same fd
+        */
+       char *devnm;
+       int fd;
+       devnm = fd2devnm(mdfd);
+       close(mdfd);
+       fd = open_dev(devnm);
+       if (fd >= 0 && fd != mdfd)
+               dup2(fd, mdfd);
+}
-- 
1.8.3.1.487.g3e7a5b4

++++++ Incremental-add-export-handling.patch ++++++
>From 9ca39acb3e8bc31811e463d19fae81c5501aea65 Mon Sep 17 00:00:00 2001
From: NeilBrown <ne...@suse.de>
Date: Thu, 28 Nov 2013 15:15:30 +1100
Subject: [PATCH] Incremental: add --export handling.

If --export is given with --incremental, then
  MD_DEVNAME
is output which gives the name of the device (in /dev/md) that
is the array (or container) that the device would be added to.
Also
  MD_STARTED
is set to one of
  no
  unsafe
  yes
  nothing

to indicate if the array was started.  IF MD_STARTED=unsafe
then it may be appropriate to run
  mdadm -R /dev/md/$MD_DEVNAME
after a timeout to ensure newly degraded array are started.

If
  MD_FOREIGN=yes
it might be appropriate to suppress this as the array is
probably not critical.

Signed-off-by: NeilBrown <ne...@suse.de>
---
 Assemble.c    |   19 ++++++++++++-----
 Incremental.c |   64 ++++++++++++++++++++++++++++++++++++++++++++++++++--------
 mdadm.8.in    |   21 +++++++++++++++++--
 mdadm.h       |    6 ++++-
 4 files changed, 94 insertions(+), 16 deletions(-)

--- mdadm-3.3.orig/Assemble.c
+++ mdadm-3.3/Assemble.c
@@ -1419,7 +1419,7 @@ try_again:
                /* This is a member of a container.  Try starting the array. */
                int err;
                err = assemble_container_content(st, mdfd, content, c,
-                                                chosen_name);
+                                                chosen_name, NULL);
                close(mdfd);
                return err;
        }
@@ -1771,7 +1771,7 @@ try_again:
 #ifndef MDASSEMBLE
 int assemble_container_content(struct supertype *st, int mdfd,
                               struct mdinfo *content, struct context *c,
-                              char *chosen_name)
+                              char *chosen_name, int *result)
 {
        struct mdinfo *dev, *sra;
        int working = 0, preexist = 0;
@@ -1838,7 +1838,9 @@ int assemble_container_content(struct su
 
        if (enough(content->array.level, content->array.raid_disks,
                   content->array.layout, content->array.state & 1, avail) == 
0) {
-               if (c->verbose >= 0) {
+               if (c->export && result)
+                       *result |= INCR_NO;
+               else if (c->verbose >= 0) {
                        pr_err("%s assembled with %d device%s",
                               chosen_name, preexist + working,
                               preexist + working == 1 ? "":"s");
@@ -1854,7 +1856,9 @@ int assemble_container_content(struct su
        if (c->runstop <= 0 &&
            (working + preexist + expansion) <
            content->array.working_disks) {
-               if (c->verbose >= 0) {
+               if (c->export && result)
+                       *result |= INCR_UNSAFE;
+               else if (c->verbose >= 0) {
                        pr_err("%s assembled with %d device%s",
                               chosen_name, preexist + working,
                               preexist + working == 1 ? "":"s");
@@ -1918,7 +1922,12 @@ int assemble_container_content(struct su
            !start_reshape)
                block_subarray(content);
 
-       if (c->verbose >= 0) {
+       if (c->export && result) {
+               if (err)
+                       *result |= INCR_NO;
+               else
+                       *result |= INCR_YES;
+       } else if (c->verbose >= 0) {
                if (err)
                        pr_err("array %s now has %d device%s",
                               chosen_name, working + preexist,
--- mdadm-3.3.orig/Incremental.c
+++ mdadm-3.3/Incremental.c
@@ -91,6 +91,7 @@ int Incremental(char *devname, struct co
        struct mdinfo *sra = NULL, *d;
        struct mddev_ident *match;
        char chosen_name[1024];
+       char *md_devname;
        int rv = 1;
        struct map_ent *mp, *map = NULL;
        int dfd = -1, mdfd = -1;
@@ -138,6 +139,8 @@ int Incremental(char *devname, struct co
                        if (map_lock(&map))
                                pr_err("failed to get "
                                       "exclusive lock on mapfile\n");
+                       if (c->export)
+                               printf("MD_DEVNAME=%s\n", devname);
                        rv = Incremental_container(st, devname, c, NULL);
                        map_unlock(&map);
                        return rv;
@@ -459,6 +462,15 @@ int Incremental(char *devname, struct co
                        info.array.working_disks ++;
 
        }
+       if (strncmp(chosen_name, "/dev/md/", 8) == 0)
+               md_devname = chosen_name+8;
+       else
+               md_devname = chosen_name;
+       if (c->export) {
+               printf("MD_DEVICE=%s\n", fd2devnm(mdfd));
+               printf("MD_DEVNAME=%s\n", md_devname);
+               printf("MD_FOREIGN=%s\n", trustworthy == FOREIGN ? "yes" : 
"no");
+       }
 
        /* 7/ Is there enough devices to possibly start the array? */
        /* 7a/ if not, finish with success. */
@@ -466,7 +478,7 @@ int Incremental(char *devname, struct co
                char devnm[32];
                /* Try to assemble within the container */
                sysfs_uevent(sra, "change");
-               if (c->verbose >= 0)
+               if (!c->export && c->verbose >= 0)
                        pr_err("container %s now has %d device%s\n",
                               chosen_name, info.array.working_disks,
                               info.array.working_disks == 1?"":"s");
@@ -503,7 +515,9 @@ int Incremental(char *devname, struct co
        if (enough(info.array.level, info.array.raid_disks,
                   info.array.layout, info.array.state & 1,
                   avail) == 0) {
-               if (c->verbose >= 0)
+               if (c->export) {
+                       printf("MD_STARTED=no\n");
+               } else if (c->verbose >= 0)
                        pr_err("%s attached to %s, not enough to start (%d).\n",
                               devname, chosen_name, active_disks);
                rv = 0;
@@ -517,7 +531,9 @@ int Incremental(char *devname, struct co
        /*   + start the array (auto-readonly). */
 
        if (ioctl(mdfd, GET_ARRAY_INFO, &ainf) == 0) {
-               if (c->verbose >= 0)
+               if (c->export) {
+                       printf("MD_STARTED=already\n");
+               } else if (c->verbose >= 0)
                        pr_err("%s attached to %s which is already active.\n",
                               devname, chosen_name);
                rv = 0;
@@ -564,7 +580,9 @@ int Incremental(char *devname, struct co
                        rv = sysfs_set_str(sra, NULL,
                                           "array_state", "read-auto");
                if (rv == 0) {
-                       if (c->verbose >= 0)
+               if (c->export) {
+                       printf("MD_STARTED=yes\n");
+               } else if (c->verbose >= 0)
                                pr_err("%s attached to %s, which has been 
started.\n",
                                       devname, chosen_name);
                        rv = 0;
@@ -587,7 +605,9 @@ int Incremental(char *devname, struct co
                        rv = 1;
                }
        } else {
-               if (c->verbose >= 0)
+               if (c->export) {
+                       printf("MD_STARTED=unsafe\n");
+               } else if (c->verbose >= 0)
                        pr_err("%s attached to %s, not enough to start 
safely.\n",
                               devname, chosen_name);
                rv = 0;
@@ -1441,6 +1461,7 @@ static int Incremental_container(struct
        int sfd;
        int ra_blocked = 0;
        int ra_all = 0;
+       int result = 0;
 
        st->ss->getinfo_super(st, &info, NULL);
 
@@ -1448,7 +1469,9 @@ static int Incremental_container(struct
            info.container_enough > 0)
                /* pass */;
        else {
-               if (c->verbose)
+               if (c->export) {
+                       printf("MD_STARTED=no\n");
+               } else if (c->verbose)
                        pr_err("not enough devices to start the container\n");
                return 0;
        }
@@ -1469,8 +1492,12 @@ static int Incremental_container(struct
 
        list = st->ss->container_content(st, NULL);
        /* when nothing to activate - quit */
-       if (list == NULL)
+       if (list == NULL) {
+               if (c->export) {
+                       printf("MD_STARTED=nothing\n");
+               }
                return 0;
+       }
        for (ra = list ; ra ; ra = ra->next) {
                int mdfd;
                char chosen_name[1024];
@@ -1560,9 +1587,30 @@ static int Incremental_container(struct
                }
 
                assemble_container_content(st, mdfd, ra, c,
-                                          chosen_name);
+                                          chosen_name, &result);
                close(mdfd);
        }
+       if (c->export && result) {
+               char sep = '=';
+               printf("MD_STARTED");
+               if (result & INCR_NO) {
+                       printf("%cno", sep);
+                       sep = ',';
+               }
+               if (result & INCR_UNSAFE) {
+                       printf("%cunsafe", sep);
+                       sep = ',';
+               }
+               if (result & INCR_ALREADY) {
+                       printf("%calready", sep);
+                       sep = ',';
+               }
+               if (result & INCR_YES) {
+                       printf("%cyes", sep);
+                       sep = ',';
+               }
+               printf("\n");
+       }
 
        /* don't move spares to container with volume being activated
           when all volumes are blocked */
--- mdadm-3.3.orig/mdadm.8.in
+++ mdadm-3.3/mdadm.8.in
@@ -1428,13 +1428,30 @@ absolute filepath or a link, e.g.
 .TP
 .BR \-Y ", " \-\-export
 When used with
-.B \-\-detail , \-\-detail-platform
-or
+.BR \-\-detail ,
+.BR \-\-detail-platform ,
 .BR \-\-examine ,
+or
+.B \-\-incremental
 output will be formatted as
 .B key=value
 pairs for easy import into the environment.
 
+With
+.B \-\-incremental
+The value
+.B MD_STARTED
+indicates whether an array was started
+.RB ( yes )
+or not, which may include a reason
+.RB ( unsafe ", " nothing ", " no ).
+Also the value
+.B MD_FOREIGN
+indicates if the array is expected on this host
+.RB ( no ),
+or seems to be from elsewhere
+.RB ( yes ).
+
 .TP
 .BR \-E ", " \-\-examine
 Print contents of the metadata stored on the named device(s).
--- mdadm-3.3.orig/mdadm.h
+++ mdadm-3.3/mdadm.h
@@ -1328,7 +1328,11 @@ extern void append_metadata_update(struc
 extern int assemble_container_content(struct supertype *st, int mdfd,
                                      struct mdinfo *content,
                                      struct context *c,
-                                     char *chosen_name);
+                                     char *chosen_name, int *result);
+#define        INCR_NO         1
+#define        INCR_UNSAFE     2
+#define        INCR_ALREADY    4
+#define        INCR_YES        8
 extern struct mdinfo *container_choose_spares(struct supertype *st,
                                              unsigned long long min_size,
                                              struct domainlist *domlist,
++++++ Incremental-improve-support-for-DEVICE-based-restric.patch ++++++
>From b11fe74db0d764c3a245d95bc3651be9bbd59463 Mon Sep 17 00:00:00 2001
From: NeilBrown <ne...@suse.de>
Date: Tue, 3 Dec 2013 14:01:24 +1100
Subject: [PATCH] Incremental: improve support for "DEVICE" based restriction
 in mdadm.conf

--incremental currently fails if the device name passed does not
textually match the names permitted by the DEVICE line in mdadm.conf.
This is problematic when "mdadm -I" is run by udev as the name given
can be a temp name.

This patch makes two improvements:
1/ We generate a list of all existing devices that match the names
  in mdadm.conf, and allow rdev based matching
2/ We allows extra aliases to be provided on the command line, and
  perform textual matching on those.  This is particularly suitable
  for udev usages as ${DEVLINKS} can be provided even though the links
  make not yet be created.

Signed-off-by: NeilBrown <ne...@suse.de>
---
 Incremental.c               |   18 ++++++++++++++++--
 mdadm.8.in                  |   12 ++++++++++--
 mdadm.c                     |   16 ++++++++--------
 mdadm.h                     |    2 +-
 udev-md-raid-assembly.rules |    2 +-
 5 files changed, 36 insertions(+), 14 deletions(-)

--- mdadm-3.3.orig/Incremental.c
+++ mdadm-3.3/Incremental.c
@@ -46,7 +46,7 @@ static int try_spare(char *devname, int
 static int Incremental_container(struct supertype *st, char *devname,
                                 struct context *c, char *only);
 
-int Incremental(char *devname, struct context *c,
+int Incremental(struct mddev_dev *devlist, struct context *c,
                struct supertype *st)
 {
        /* Add this device to an array, creating the array if necessary
@@ -103,6 +103,7 @@ int Incremental(char *devname, struct co
        struct dev_policy *policy = NULL;
        struct map_ent target_array;
        int have_target;
+       char *devname = devlist->devname;
 
        struct createinfo *ci = conf_get_create_info();
 
@@ -153,7 +154,20 @@ int Incremental(char *devname, struct co
 
        /* 1/ Check if device is permitted by mdadm.conf */
 
-       if (!conf_test_dev(devname)) {
+       for (;devlist; devlist = devlist->next)
+               if (conf_test_dev(devlist->devname))
+                       break;
+       if (!devlist) {
+               devlist = conf_get_devs();
+               for (;devlist; devlist = devlist->next) {
+                       struct stat st2;
+                       if (stat(devlist->devname, &st2) == 0 &&
+                           (st2.st_mode & S_IFMT) == S_IFBLK &&
+                           st2.st_rdev == stb.st_rdev)
+                               break;
+               }
+       }
+       if (!devlist) {
                if (c->verbose >= 0)
                        pr_err("%s not permitted by mdadm.conf.\n",
                               devname);
--- mdadm-3.3.orig/mdadm.8.in
+++ mdadm-3.3/mdadm.8.in
@@ -2664,6 +2664,7 @@ Usage:
 .RB [ \-\-run ]
 .RB [ \-\-quiet ]
 .I component-device
+.RI [ optional-aliases-for-device ]
 .HP 12
 Usage:
 .B mdadm \-\-incremental \-\-fail
@@ -2718,16 +2719,23 @@ That is, is it listed in a
 .B DEVICES
 line in that file.  If
 .B DEVICES
-is absent then the default it to allow any device.  Similar if
+is absent then the default it to allow any device.  Similarly if
 .B DEVICES
 contains the special word
 .B partitions
 then any device is allowed.  Otherwise the device name given to
-.I mdadm
+.IR mdadm ,
+or one of the aliases given, or an alias found in the filesystem,
 must match one of the names or patterns in a
 .B DEVICES
 line.
 
+This is the only context where the aliases are used.  They are
+usually provided by a
+.I udev
+rules mentioning
+.BR ${DEVLINKS} .
+
 .IP +
 Does the device have a valid md superblock?  If a specific metadata
 version is requested with
--- mdadm-3.3.orig/mdadm.c
+++ mdadm-3.3/mdadm.c
@@ -1544,16 +1544,16 @@ int main(int argc, char *argv[])
                        }
                        break;
                }
-               if (devlist->next) {
-                       pr_err("--incremental can only handle one device.\n");
-                       rv = 1;
-                       break;
-               }
-               if (devmode == 'f')
+               if (devmode == 'f') {
+                       if (devlist->next) {
+                               pr_err("'--incremental --fail' can only handle 
one device.\n");
+                               rv = 1;
+                               break;
+                       }
                        rv = IncrementalRemove(devlist->devname, remove_path,
                                               c.verbose);
-               else
-                       rv = Incremental(devlist->devname, &c, ss);
+               } else
+                       rv = Incremental(devlist, &c, ss);
                break;
        case AUTODETECT:
                autodetect();
--- mdadm-3.3.orig/mdadm.h
+++ mdadm-3.3/mdadm.h
@@ -1232,7 +1232,7 @@ extern int Update_subarray(char *dev, ch
 extern int Wait(char *dev);
 extern int WaitClean(char *dev, int sock, int verbose);
 
-extern int Incremental(char *devname, struct context *c,
+extern int Incremental(struct mddev_dev *devlist, struct context *c,
                       struct supertype *st);
 extern void RebuildMap(void);
 extern int IncrementalScan(struct context *c, char *devnm);
--- mdadm-3.3.orig/udev-md-raid-assembly.rules
+++ mdadm-3.3/udev-md-raid-assembly.rules
@@ -12,7 +12,7 @@ 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", IMPORT{program}="/sbin/mdadm --incremental --export $devnode 
--offroot"
+ACTION=="add", IMPORT{program}="/sbin/mdadm --incremental --export $devnode 
--offroot ${DEVLINKS}"
 ACTION=="add", ENV{MD_STARTED}=="*unsafe*", ENV{MD_FOREIGN}=="no", 
ENV{SYSTEMD_WANTS}+="mdadm-last-resort@$env{MD_DEVICE}.timer"
 ACTION=="remove", ENV{ID_PATH}=="?*", RUN+="/sbin/mdadm -If $name --path 
$env{ID_PATH}"
 ACTION=="remove", ENV{ID_PATH}!="?*", RUN+="/sbin/mdadm -If $name"
++++++ Restructure-assemble_container_content-and-improve-m.patch ++++++
>From c1736844ba49ec1a8731b5815abfd6530b982a3b Mon Sep 17 00:00:00 2001
From: NeilBrown <ne...@suse.de>
Date: Thu, 28 Nov 2013 14:47:41 +1100
Subject: [PATCH 1/2] Restructure assemble_container_content and  improve
 messages.

We lose one level of indent, and now get told the difference between
'not assemble because not safe' and 'not assembled because not enough
devices'.

Signed-off-by: NeilBrown <ne...@suse.de>
---
 Assemble.c | 176 ++++++++++++++++++++++++++++++++++---------------------------
 1 file changed, 99 insertions(+), 77 deletions(-)

diff --git a/Assemble.c b/Assemble.c
index 4d5ceeac8674..11b77c288608 100644
--- a/Assemble.c
+++ b/Assemble.c
@@ -1779,6 +1779,8 @@ int assemble_container_content(struct supertype *st, int 
mdfd,
        struct map_ent *map = NULL;
        int old_raid_disks;
        int start_reshape;
+       char *avail = NULL;
+       int err;
 
        sysfs_init(content, mdfd, NULL);
 
@@ -1812,7 +1814,10 @@ int assemble_container_content(struct supertype *st, int 
mdfd,
        if (sra)
                sysfs_free(sra);
        old_raid_disks = content->array.raid_disks - content->delta_disks;
-       for (dev = content->devs; dev; dev = dev->next)
+       avail = xcalloc(content->array.raid_disks, 1);
+       for (dev = content->devs; dev; dev = dev->next) {
+               if (dev->disk.raid_disk >= 0)
+                       avail[dev->disk.raid_disk] = 1;
                if (sysfs_add_disk(content, dev, 1) == 0) {
                        if (dev->disk.raid_disk >= old_raid_disks &&
                            content->reshape_active)
@@ -1821,100 +1826,117 @@ int assemble_container_content(struct supertype *st, 
int mdfd,
                                working++;
                } else if (errno == EEXIST)
                        preexist++;
-       if (working + expansion == 0 && c->runstop <= 0)
+       }
+       if (working + expansion == 0 && c->runstop <= 0) {
+               free(avail);
                return 1;/* Nothing new, don't try to start */
-
+       }
        map_update(&map, fd2devnm(mdfd),
                   content->text_version,
                   content->uuid, chosen_name);
 
-       if (c->runstop > 0 ||
-           (working + preexist + expansion) >=
-           content->array.working_disks) {
-               int err;
-
-               if (start_reshape) {
-                       int spare = content->array.raid_disks + expansion;
-                       if (restore_backup(st, content,
-                                          working,
-                                          spare, c->backup_file, c->verbose) 
== 1)
-                               return 1;
-
-                       err = sysfs_set_str(content, NULL,
-                                           "array_state", "readonly");
-                       if (err)
-                               return 1;
-
-                       if (st->ss->external) {
-                               if (!mdmon_running(st->container_devnm))
-                                       start_mdmon(st->container_devnm);
-                               ping_monitor(st->container_devnm);
-                               if (mdmon_running(st->container_devnm) &&
-                                   st->update_tail == NULL)
-                                       st->update_tail = &st->updates;
-                       }
-
-                       err = Grow_continue(mdfd, st, content, c->backup_file,
-                                           c->freeze_reshape);
-               } else switch(content->array.level) {
-                       case LEVEL_LINEAR:
-                       case LEVEL_MULTIPATH:
-                       case 0:
-                               err = sysfs_set_str(content, NULL, 
"array_state",
-                                                   c->readonly ? "readonly" : 
"active");
-                               break;
-                       default:
-                               err = sysfs_set_str(content, NULL, 
"array_state",
-                                                   "readonly");
-                               /* start mdmon if needed. */
-                               if (!err) {
-                                       if (!mdmon_running(st->container_devnm))
-                                               
start_mdmon(st->container_devnm);
-                                       ping_monitor(st->container_devnm);
-                               }
-                               break;
-                       }
-               if (!err)
-                       sysfs_set_safemode(content, content->safe_mode_delay);
-
-               /* Block subarray here if it is not reshaped now
-                * It has be blocked a little later to allow mdmon to switch in
-                * in to R/W state
-                */
-               if (st->ss->external && content->recovery_blocked &&
-                   !start_reshape)
-                       block_subarray(content);
 
+       if (enough(content->array.level, content->array.raid_disks,
+                  content->array.layout, content->array.state & 1, avail) == 
0) {
                if (c->verbose >= 0) {
-                       if (err)
-                               pr_err("array %s now has %d device%s",
-                                      chosen_name, working + preexist,
-                                      working + preexist == 1 ? "":"s");
-                       else
-                               pr_err("Started %s with %d device%s",
-                                      chosen_name, working + preexist,
-                                      working + preexist == 1 ? "":"s");
+                       pr_err("%s assembled with %d device%s",
+                              chosen_name, preexist + working,
+                              preexist + working == 1 ? "":"s");
                        if (preexist)
                                fprintf(stderr, " (%d new)", working);
-                       if (expansion)
-                               fprintf(stderr, " ( + %d for expansion)",
-                                       expansion);
-                       fprintf(stderr, "\n");
+                       fprintf(stderr, " but not started\n");
                }
-               if (!err)
-                       wait_for(chosen_name, mdfd);
-               return err;
-               /* FIXME should have an O_EXCL and wait for read-auto */
-       } else {
+               free(avail);
+               return 1;
+       }
+       free(avail);
+
+       if (c->runstop <= 0 &&
+           (working + preexist + expansion) <
+           content->array.working_disks) {
                if (c->verbose >= 0) {
                        pr_err("%s assembled with %d device%s",
                               chosen_name, preexist + working,
                               preexist + working == 1 ? "":"s");
                        if (preexist)
                                fprintf(stderr, " (%d new)", working);
-                       fprintf(stderr, " but not started\n");
+                       fprintf(stderr, " but not safe to start\n");
                }
                return 1;
        }
+
+
+       if (start_reshape) {
+               int spare = content->array.raid_disks + expansion;
+               if (restore_backup(st, content,
+                                  working,
+                                  spare, c->backup_file, c->verbose) == 1)
+                       return 1;
+
+               err = sysfs_set_str(content, NULL,
+                                   "array_state", "readonly");
+               if (err)
+                       return 1;
+
+               if (st->ss->external) {
+                       if (!mdmon_running(st->container_devnm))
+                               start_mdmon(st->container_devnm);
+                       ping_monitor(st->container_devnm);
+                       if (mdmon_running(st->container_devnm) &&
+                           st->update_tail == NULL)
+                               st->update_tail = &st->updates;
+               }
+
+               err = Grow_continue(mdfd, st, content, c->backup_file,
+                                   c->freeze_reshape);
+       } else switch(content->array.level) {
+               case LEVEL_LINEAR:
+               case LEVEL_MULTIPATH:
+               case 0:
+                       err = sysfs_set_str(content, NULL, "array_state",
+                                           c->readonly ? "readonly" : 
"active");
+                       break;
+               default:
+                       err = sysfs_set_str(content, NULL, "array_state",
+                                           "readonly");
+                       /* start mdmon if needed. */
+                       if (!err) {
+                               if (!mdmon_running(st->container_devnm))
+                                       start_mdmon(st->container_devnm);
+                               ping_monitor(st->container_devnm);
+                       }
+                       break;
+               }
+       if (!err)
+               sysfs_set_safemode(content, content->safe_mode_delay);
+
+       /* Block subarray here if it is not reshaped now
+        * It has be blocked a little later to allow mdmon to switch in
+        * in to R/W state
+        */
+       if (st->ss->external && content->recovery_blocked &&
+           !start_reshape)
+               block_subarray(content);
+
+       if (c->verbose >= 0) {
+               if (err)
+                       pr_err("array %s now has %d device%s",
+                              chosen_name, working + preexist,
+                              working + preexist == 1 ? "":"s");
+               else
+                       pr_err("Started %s with %d device%s",
+                              chosen_name, working + preexist,
+                              working + preexist == 1 ? "":"s");
+               if (preexist)
+                       fprintf(stderr, " (%d new)", working);
+               if (expansion)
+                       fprintf(stderr, " ( + %d for expansion)",
+                               expansion);
+               fprintf(stderr, "\n");
+       }
+       if (!err)
+               wait_for(chosen_name, mdfd);
+       return err;
+       /* FIXME should have an O_EXCL and wait for read-auto */
 }
 #endif
-- 
1.8.3.1.487.g3e7a5b4

++++++ mkinitrd-setup.sh ++++++
--- /var/tmp/diff_new_pack.JTd7H1/_old  2013-12-06 11:46:08.000000000 +0100
+++ /var/tmp/diff_new_pack.JTd7H1/_new  2013-12-06 11:46:08.000000000 +0100
@@ -81,6 +81,15 @@
         echo "unrecognized container for $md_dev: $container"
         ;;
     esac
+    # If /etc/mdadm.conf contains a different name for this
+    # array, then use that.
+    md_uuid=`echo $mdconf | sed -n -e 's/.* UUID=\([0-9a-f:]*\).*/\1/p'`
+    if [ -f /etc/mdadm.conf -a -n "$md_uuid" ]; then
+       md_devname=`sed -n -e 's,^ARRAY  */dev/\([^ ]*\) 
.*[Uu][Uu][Ii][Dd]='$md_uuid'.*,\1,p' /etc/mdadm.conf`
+       if [ -n "$md_devname" ]; then
+          mdconf=`echo $mdconf | sed -e 's,^ARRAY /dev/\([^ ]*\),ARRAY 
/dev/'$md_devname','`
+       fi
+    fi
     md_conf["$md_dev"]="$mdconf"
     root_md=1
 done

++++++ systemd-mdadm-last-resort@.service ++++++
[Unit]
Description=Activate md array even though degraded
DefaultDependencies=no

[Service]
Type=oneshot
ExecStart=/sbin/mdadm --run /dev/%i
++++++ systemd-mdadm-last-resort@.timer ++++++
[Unit]
Description=Timer to wait for more drives before activating degraded array.
DefaultDependencies=no

[Timer]
OnActiveSec=30
++++++ udev-rules.degraded ++++++
---
 udev-md-raid-assembly.rules |    3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

--- mdadm-3.3.orig/udev-md-raid-assembly.rules
+++ mdadm-3.3/udev-md-raid-assembly.rules
@@ -12,7 +12,8 @@ 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", RUN+="/sbin/mdadm --incremental $devnode --offroot"
+ACTION=="add", IMPORT{program}="/sbin/mdadm --incremental --export $devnode 
--offroot"
+ACTION=="add", ENV{MD_STARTED}=="*unsafe*", ENV{MD_FOREIGN}=="no", 
ENV{SYSTEMD_WANTS}+="mdadm-last-resort@$env{MD_DEVICE}.timer"
 ACTION=="remove", ENV{ID_PATH}=="?*", RUN+="/sbin/mdadm -If $name --path 
$env{ID_PATH}"
 ACTION=="remove", ENV{ID_PATH}!="?*", RUN+="/sbin/mdadm -If $name"
 
-- 
To unsubscribe, e-mail: opensuse-commit+unsubscr...@opensuse.org
For additional commands, e-mail: opensuse-commit+h...@opensuse.org

Reply via email to