Accepting request 236929 from Base:System

- mdadm.spec: change calling of mkinitrd to use the
  %regenerate_initrd_{post,posttrans} macros to optimise
  initrd regeneration. (bnc#881780)

- new upstream release 3.3.1, incorporates all current patches
  and includes assorted other minor fixes.
- 0001-Makefile-install-mdadm-grow-continue-.service.patch
  make sure mdadm-grow-continue.service is installed properly.
- remove mkinitrd files, we now use dracut
- Delete  0001-Assemble-allow-load_devices-to-change-the-st-which-i.patch
- Delete  0001-DDF-mark-missing-on-assembly-device-properly.patch
- Delete  0001-mdmon-.service-Change-type-of-process-start-up-to-fo.patch
- Delete  0001-systemd-various-fixes-for-boot-with-container-arrays.patch
- Delete  0002-Assemble-re-arrange-freeing-of-tst-in-load_devices.patch
- Delete  0002-DDF-guard-against-pdnum-being-negative.patch
- Delete  0003-Assemble-change-load_devices-to-return-most_recent-s.patch
- Delete  0003-DDF-fix-possible-mdmon-crash-when-updating-metadata.patch
- Delete  0003-Work-around-architectures-having-statfs.f_type-defin.patch
- Delete  0004-DDF-Don-t-fail-compare_super_ddf-due-to-re-configure.patch
- Delete  0004-DDF-report-seq-counter-as-events.patch
- Delete  0005-DDF-when-first-activating-an-array-record-any-missin.patch
- Delete  Assembe-fix-bug-in-force_array-it-wasn-t-forcing-pro.patch
- Delete  Assemble-Incremental-don-t-hold-O_EXCL-on-mddev-afte.patch
- Delete  Assemble-avoid-infinite-loop-when-auto-assembling-pa.patch
- Delete  DDF-add_to_super_ddf-be-careful-with-workspace_lba.patch
- Delete  DDF-allow-for-possibility-that-there-is-no-secondary.patch
- Delete  DDF-brief_examine_subarrays_ddf-print-array-name.patch
- Delete  DDF-compare_super_ddf-fix-sequence-number-check.patch
- Delete  DDF-factor-out-array-name-generation.patch
- Delete  DDF-fix-detection-of-failed-devices-during-assembly.patch

OBS-URL: https://build.opensuse.org/request/show/236929
OBS-URL: https://build.opensuse.org/package/show/openSUSE:Factory/mdadm?expand=0&rev=91
This commit is contained in:
Stephan Kulow 2014-06-18 05:49:35 +00:00 committed by Git OBS Bridge
commit a3528293fa
49 changed files with 99 additions and 3245 deletions

View File

@ -1,82 +0,0 @@
From df842e69a3cb7316a06ba45f8f04d7b9beb0170f Mon Sep 17 00:00:00 2001
From: NeilBrown <neilb@suse.de>
Date: Tue, 25 Feb 2014 14:54:34 +1100
Subject: [PATCH 1/3] Assemble: allow load_devices to change the 'st' which is
passed in.
The given 'st' might not be best. Making this interface change
will allow load_devices to return a better 'st'.
Signed-off-by: NeilBrown <neilb@suse.de>
---
Assemble.c | 10 ++++++++--
1 file changed, 8 insertions(+), 2 deletions(-)
--- mdadm-3.3.orig/Assemble.c
+++ mdadm-3.3/Assemble.c
@@ -551,7 +551,7 @@ struct devs {
};
static int load_devices(struct devs *devices, char *devmap,
- struct mddev_ident *ident, struct supertype *st,
+ struct mddev_ident *ident, struct supertype **stp,
struct mddev_dev *devlist, struct context *c,
struct mdinfo *content,
int mdfd, char *mddev,
@@ -567,6 +567,7 @@ static int load_devices(struct devs *dev
int most_recent = -1;
int bestcnt = 0;
int *best = *bestp;
+ struct supertype *st = *stp;
for (tmpdev = devlist; tmpdev; tmpdev=tmpdev->next) {
char *devname = tmpdev->devname;
@@ -610,6 +611,7 @@ static int load_devices(struct devs *dev
close(mdfd);
free(devices);
free(devmap);
+ *stp = st;
return -1;
}
tst->ss->getinfo_super(tst, content, devmap + devcnt * content->array.raid_disks);
@@ -636,6 +638,7 @@ static int load_devices(struct devs *dev
close(dfd);
free(devices);
free(devmap);
+ *stp = st;
return -1;
}
if (strcmp(c->update, "uuid")==0 &&
@@ -675,6 +678,7 @@ static int load_devices(struct devs *dev
close(mdfd);
free(devices);
free(devmap);
+ *stp = st;
return -1;
}
tst->ss->getinfo_super(tst, content, devmap + devcnt * content->array.raid_disks);
@@ -759,6 +763,7 @@ static int load_devices(struct devs *dev
close(mdfd);
free(devices);
free(devmap);
+ *stp = st;
return -1;
}
if (best[i] == -1
@@ -772,6 +777,7 @@ static int load_devices(struct devs *dev
*most_recentp = most_recent;
*bestcntp = bestcnt;
*bestp = best;
+ *stp = st;
return devcnt;
}
@@ -1432,7 +1438,7 @@ try_again:
/* Ok, no bad inconsistancy, we can try updating etc */
devices = xcalloc(num_devs, sizeof(*devices));
devmap = xcalloc(num_devs, content->array.raid_disks);
- devcnt = load_devices(devices, devmap, ident, st, devlist,
+ devcnt = load_devices(devices, devmap, ident, &st, devlist,
c, content, mdfd, mddev,
&most_recent, &bestcnt, &best, inargv);
if (devcnt < 0)

View File

@ -1,75 +0,0 @@
From e5a03804dc27e662be94290c62760dbc544c0211 Mon Sep 17 00:00:00 2001
From: NeilBrown <neilb@suse.de>
Date: Tue, 1 Apr 2014 16:15:06 +1100
Subject: [PATCH 1/4] DDF: mark missing-on-assembly device properly.
As well as removing from the array we really should mark
it is 'failed', and mark the array as degraded.
Signed-off-by: NeilBrown <neilb@suse.de>
---
super-ddf.c | 31 ++++++++++++++++++++++++++++---
1 file changed, 28 insertions(+), 3 deletions(-)
--- mdadm-3.3.orig/super-ddf.c
+++ mdadm-3.3/super-ddf.c
@@ -4117,7 +4117,7 @@ static int ddf_open_new(struct supertype
return 0;
}
-static void handle_missing(struct ddf_super *ddf, int inst)
+static void handle_missing(struct ddf_super *ddf, struct active_array *a, int inst)
{
/* This member array is being activated. If any devices
* are missing they must now be marked as failed.
@@ -4126,7 +4126,9 @@ static void handle_missing(struct ddf_su
unsigned int n_bvd;
struct vcl *vcl;
struct dl *dl;
+ int pd;
int n;
+ int state;
for (n = 0; ; n++) {
vc = find_vdcr(ddf, inst, n, &n_bvd, &vcl);
@@ -4138,7 +4140,30 @@ static void handle_missing(struct ddf_su
if (dl)
/* Found this disk, so not missing */
continue;
- vc->phys_refnum[n_bvd] = cpu_to_be32(0);
+
+ /* Mark the device as failed/missing. */
+ pd = find_phys(ddf, vc->phys_refnum[n_bvd]);
+ if (pd >= 0 && be16_and(ddf->phys->entries[pd].state,
+ cpu_to_be16(DDF_Online))) {
+ be16_clear(ddf->phys->entries[pd].state,
+ cpu_to_be16(DDF_Online));
+ be16_set(ddf->phys->entries[pd].state,
+ cpu_to_be16(DDF_Failed|DDF_Missing));
+ vc->phys_refnum[n_bvd] = cpu_to_be32(0);
+ ddf_set_updates_pending(ddf);
+ }
+
+ /* Mark the array as Degraded */
+ state = get_svd_state(ddf, vcl);
+ if (ddf->virt->entries[inst].state !=
+ ((ddf->virt->entries[inst].state & ~DDF_state_mask)
+ | state)) {
+ ddf->virt->entries[inst].state =
+ (ddf->virt->entries[inst].state & ~DDF_state_mask)
+ | state;
+ a->check_degraded = 1;
+ ddf_set_updates_pending(ddf);
+ }
}
}
@@ -4157,7 +4182,7 @@ static int ddf_set_array_state(struct ac
int inst = a->info.container_member;
int old = ddf->virt->entries[inst].state;
if (consistent == 2) {
- handle_missing(ddf, inst);
+ handle_missing(ddf, a, inst);
/* Should check if a recovery should be started FIXME */
consistent = 1;
if (!is_resync_complete(&a->info))

View File

@ -0,0 +1,28 @@
From 616f197f9d6d044afb9e27ddc9cd087d21d610f0 Mon Sep 17 00:00:00 2001
From: NeilBrown <neilb@suse.de>
Date: Tue, 10 Jun 2014 20:34:40 +1000
Subject: [PATCH] Makefile: install mdadm-grow-continue@.service
Forgot to add this to install-systemd target
Signed-off-by: NeilBrown <neilb@suse.de>
---
Makefile | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/Makefile b/Makefile
index c7e7a4272cde..1a4a5dcdb720 100644
--- a/Makefile
+++ b/Makefile
@@ -290,7 +290,7 @@ install-udev: udev-md-raid-arrays.rules udev-md-raid-assembly.rules
install-systemd: systemd/mdmon@.service
@for file in mdmon@.service mdmonitor.service mdadm-last-resort@.timer \
- mdadm-last-resort@.service ; \
+ mdadm-last-resort@.service mdadm-grow-continue@.service; \
do sed -e 's,BINDIR,$(BINDIR),g' systemd/$$file > .install.tmp && \
echo $(INSTALL) -D -m 644 systemd/$$file $(DESTDIR)$(SYSTEMD_DIR)/$$file ; \
$(INSTALL) -D -m 644 .install.tmp $(DESTDIR)$(SYSTEMD_DIR)/$$file ; \
--
2.0.0

View File

@ -1,42 +0,0 @@
From 2167de78aab599e7a7a8d057ef04bf18527bc129 Mon Sep 17 00:00:00 2001
From: Pawel Baldysiak <pawel.baldysiak@intel.com>
Date: Thu, 6 Mar 2014 15:51:44 +0100
Subject: [PATCH 1/6] mdmon@.service: Change type of process start-up to
'forking'.
Mdadm does not wait enough time when mdmon is started by systemd.
It causes various problems with behaviour of a RAID volume with external metadata.
For example: mdmon does not update a value of checkpoint during migration
and second RAID5 volume is read-only after reboot done during
container reshape (both problems occur with IMSM matadata).
If a type of process start-up is changed to 'forking', systemctl will
wait until mdmon (parent) process exits after calling fork.
This way mdmon will always be fully initialized after start_mdmon
and these problems will not occur.
In this case it is recommended to add a path to PIDFile, so that systemd
does not have to guess a PID of the mdmon process.
Signed-off-by: Pawel Baldysiak <pawel.baldysiak@intel.com>
Reviewed-by: Artur Paszkiewicz <artur.paszkiewicz@intel.com>
Reviewed-by: Lukasz Dorau <lukasz.dorau@intel.com>
Signed-off-by: NeilBrown <neilb@suse.de>
---
systemd/mdmon@.service | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/systemd/mdmon@.service b/systemd/mdmon@.service
index 5520cd03137c..304b26e890c7 100644
--- a/systemd/mdmon@.service
+++ b/systemd/mdmon@.service
@@ -14,5 +14,7 @@ Before=initrd-switch-root.target
# mdmon should never complain due to lack of a platform,
# that is mdadm's job if at all.
Environment=IMSM_NO_PLATFORM=1
-ExecStart=/sbin/mdmon --foreground %I
+ExecStart=/sbin/mdmon %I
+Type=forking
+PIDFile=/run/mdadm/%I.pid
KillMode=none
--
1.8.3.1.487.g3e7a5b4

View File

@ -1,83 +0,0 @@
From 8d1d32bb33da1bd08a398d26f364b84e69ac7b41 Mon Sep 17 00:00:00 2001
From: NeilBrown <neilb@suse.de>
Date: Tue, 8 Apr 2014 17:22:18 +1000
Subject: [PATCH] systemd: various fixes for boot with container-arrays.
1/ Add systemd shutdown script to ensure DDF and IMSM are
clean before we actually shutdown
2/ Get udev to tell systemd to run the mdmon@mdXXX.service
units when a member array appears.
If we boot off a member array (with dracut at least),
the mdmon started in the initramfs will lose track of
/sys etc, so we need to restart it.
systemd will try to forget about it too (but not actually
kill it because we said not to do this).
Having udev tell it to start it will allow a new mdmon to
run which can see /sys, and systemd will know about it.
3/ Always use --offroot and --takeover when starting mdmon with
systemd
--offroot is needed else shutdown will hang.
--takeover is needed incase an mdmon was started earlier
(e.g. in initramfs).
Neither hurt if they aren't actually needed.
Signed-off-by: NeilBrown <neilb@suse.de>
---
Makefile | 1 +
systemd/mdadm.shutdown | 4 ++++
systemd/mdmon@.service | 12 ++++++++++--
udev-md-raid-arrays.rules | 4 ++++
4 files changed, 19 insertions(+), 2 deletions(-)
create mode 100644 systemd/mdadm.shutdown
--- mdadm-3.3.orig/Makefile
+++ mdadm-3.3/Makefile
@@ -286,6 +286,7 @@ install-udev: udev-md-raid-arrays.rules
install-systemd: systemd/mdmon@.service
$(INSTALL) -D -m 644 systemd/mdmon@.service $(DESTDIR)$(SYSTEMD_DIR)/mdmon@.service
$(INSTALL) -D -m 644 systemd/mdmonitor.service $(DESTDIR)$(SYSTEMD_DIR)/mdmonitor.service
+ $(INSTALL) -D -m 755 systemd/mdadm.shutdown $(DESTDIR)$(SYSTEMD_DIR)-shutdown/mdadm.shutdown
[ -f /etc/SuSE-release -o -n "$(SUSE)" ] && $(INSTALL) -D -m 755 systemd/SUSE-mdadm_env.sh $(DESTDIR)$(SYSTEMD_DIR)/../scripts/mdadm_env.sh || true
uninstall:
--- /dev/null
+++ mdadm-3.3/systemd/mdadm.shutdown
@@ -0,0 +1,4 @@
+#!/bin/sh
+# We need to ensure all md arrays with external metadata
+# (e.g. IMSM, DDF) are clean before completing the shutdown.
+/sbin/mdadm --wait-clean --scan
--- mdadm-3.3.orig/systemd/mdmon@.service
+++ mdadm-3.3/systemd/mdmon@.service
@@ -14,7 +14,15 @@ Before=initrd-switch-root.target
# mdmon should never complain due to lack of a platform,
# that is mdadm's job if at all.
Environment=IMSM_NO_PLATFORM=1
-ExecStart=/sbin/mdmon %I
+# The mdmon starting in the initramfs (with dracut at least)
+# cannot see sysfs after root is mounted, so we will have to
+# 'takeover'. As the '--offroot --takeover' don't hurt when
+# not necessary, are are useful with root-on-md in dracut,
+# have them always present.
+ExecStart=/sbin/mdmon --offroot --takeover %I
Type=forking
-PIDFile=/run/mdadm/%I.pid
+# Don't set the PIDFile. It isn't necessary (systemd can work
+# it out) and systemd will remove it when transitioning from
+# initramfs to rootfs.
+#PIDFile=/run/mdadm/%I.pid
KillMode=none
--- mdadm-3.3.orig/udev-md-raid-arrays.rules
+++ mdadm-3.3/udev-md-raid-arrays.rules
@@ -34,4 +34,8 @@ ENV{ID_FS_USAGE}=="filesystem|other", EN
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"
+
LABEL="md_end"

View File

@ -1,89 +0,0 @@
From 9ee314dab91dc8479d2e981d0849ce777f7ea492 Mon Sep 17 00:00:00 2001
From: NeilBrown <neilb@suse.de>
Date: Tue, 25 Feb 2014 14:59:12 +1100
Subject: [PATCH 2/3] Assemble: re-arrange freeing of 'tst' in load_devices().
When we return in error, we need to free(tst), and ->free_super(tst);
Sometimes we didn't.
Also the final ->free_super(tst) should be followed by free(tst)
but wasn't.
Move that file free forward in the code a bit as we will want to use
the tst there in the next patch.
Signed-off-by: NeilBrown <neilb@suse.de>
---
Assemble.c | 19 +++++++++++--------
1 file changed, 11 insertions(+), 8 deletions(-)
--- mdadm-3.3.orig/Assemble.c
+++ mdadm-3.3/Assemble.c
@@ -572,6 +572,7 @@ static int load_devices(struct devs *dev
for (tmpdev = devlist; tmpdev; tmpdev=tmpdev->next) {
char *devname = tmpdev->devname;
struct stat stb;
+ struct supertype *tst;
int i;
if (tmpdev->used != 1)
@@ -582,7 +583,6 @@ static int load_devices(struct devs *dev
int dfd;
/* prepare useful information in info structures */
struct stat stb2;
- struct supertype *tst;
int err;
fstat(mdfd, &stb2);
@@ -611,6 +611,8 @@ static int load_devices(struct devs *dev
close(mdfd);
free(devices);
free(devmap);
+ tst->ss->free_super(tst);
+ free(tst);
*stp = st;
return -1;
}
@@ -660,15 +662,13 @@ static int load_devices(struct devs *dev
else
bitmap_done = 1;
}
- tst->ss->free_super(tst);
} else
#endif
{
- struct supertype *tst = dup_super(st);
- int dfd;
- dfd = dev_open(devname,
- tmpdev->disposition == 'I'
- ? O_RDWR : (O_RDWR|O_EXCL));
+ int dfd = dev_open(devname,
+ tmpdev->disposition == 'I'
+ ? O_RDWR : (O_RDWR|O_EXCL));
+ tst = dup_super(st);
if (dfd < 0 || tst->ss->load_super(tst, dfd, NULL) != 0) {
pr_err("cannot re-read metadata from %s - aborting\n",
@@ -678,11 +678,12 @@ static int load_devices(struct devs *dev
close(mdfd);
free(devices);
free(devmap);
+ tst->ss->free_super(tst);
+ free(tst);
*stp = st;
return -1;
}
tst->ss->getinfo_super(tst, content, devmap + devcnt * content->array.raid_disks);
- tst->ss->free_super(tst);
close(dfd);
}
@@ -705,6 +706,8 @@ static int load_devices(struct devs *dev
> devices[most_recent].i.events)
most_recent = devcnt;
}
+ tst->ss->free_super(tst);
+ free(tst);
if (content->array.level == LEVEL_MULTIPATH)
/* with multipath, the raid_disk from the superblock is meaningless */

View File

@ -1,90 +0,0 @@
From a44e993e37a76561fa30e932b93d85fab9bcc272 Mon Sep 17 00:00:00 2001
From: NeilBrown <neilb@suse.de>
Date: Wed, 2 Apr 2014 13:34:10 +1100
Subject: [PATCH 2/4] DDF: guard against ->pdnum being negative.
It is conceivable that ->pdnum could be -1, though only if
the metadata is corrupt.
We should be careful not to use it if it is.
Also remove an assignment for pdnum to ->container_member.
This is never used and cannot possibly mean anything.
Signed-off-by: NeilBrown <neilb@suse.de>
---
super-ddf.c | 22 ++++++++++++++++------
1 file changed, 16 insertions(+), 6 deletions(-)
--- mdadm-3.3.orig/super-ddf.c
+++ mdadm-3.3/super-ddf.c
@@ -2465,7 +2465,11 @@ static struct extent *get_extents(struct
struct extent *rv;
int n = 0;
unsigned int i;
- __u16 state = be16_to_cpu(ddf->phys->entries[dl->pdnum].state);
+ __u16 state;
+
+ if (dl->pdnum < 0)
+ return NULL;
+ state = be16_to_cpu(ddf->phys->entries[dl->pdnum].state);
if ((state & (DDF_Online|DDF_Failed|DDF_Missing)) != DDF_Online)
return NULL;
@@ -2900,7 +2904,7 @@ static int remove_from_super_ddf(struct
if (dl->major == dk->major &&
dl->minor == dk->minor)
break;
- if (!dl)
+ if (!dl || dl->pdnum < 0)
return -1;
if (st->update_tail) {
@@ -4096,7 +4100,7 @@ static int ddf_open_new(struct supertype
if (dl->major == dev->disk.major &&
dl->minor == dev->disk.minor)
break;
- if (!dl) {
+ if (!dl || dl->pdnum < 0) {
pr_err("%s: device %d/%d of subarray %d not found in meta data\n",
__func__, dev->disk.major, dev->disk.minor, n);
return -1;
@@ -4728,6 +4732,9 @@ static void ddf_process_update(struct su
for (dl = ddf->dlist; dl; dl = dl->next) {
unsigned int vn = 0;
int in_degraded = 0;
+
+ if (dl->pdnum < 0)
+ continue;
for (vcl = ddf->conflist; vcl ; vcl = vcl->next) {
unsigned int dn, ibvd;
const struct vd_config *conf;
@@ -4991,7 +4998,11 @@ static struct mdinfo *ddf_activate_spare
int is_dedicated = 0;
struct extent *ex;
unsigned int j;
- be16 state = ddf->phys->entries[dl->pdnum].state;
+ be16 state;
+
+ if (dl->pdnum < 0)
+ continue;
+ state = ddf->phys->entries[dl->pdnum].state;
if (be16_and(state,
cpu_to_be16(DDF_Failed|DDF_Missing)) ||
!be16_and(state,
@@ -5082,7 +5093,6 @@ static struct mdinfo *ddf_activate_spare
di->recovery_start = 0;
di->data_offset = pos;
di->component_size = a->info.component_size;
- di->container_member = dl->pdnum;
di->next = rv;
rv = di;
dprintf("%x:%x (%08x) to be %d at %llu\n",
@@ -5140,7 +5150,7 @@ static struct mdinfo *ddf_activate_spare
if (dl->major == di->disk.major
&& dl->minor == di->disk.minor)
break;
- if (!dl) {
+ if (!dl || dl->pdnum < 0) {
pr_err("%s: BUG: can't find disk %d (%d/%d)\n",
__func__, di->disk.raid_disk,
di->disk.major, di->disk.minor);

View File

@ -1,36 +0,0 @@
From 56bbc588f7f0f3bdd3ec23f02109b427c1d3b8f1 Mon Sep 17 00:00:00 2001
From: NeilBrown <neilb@suse.de>
Date: Tue, 25 Feb 2014 15:04:16 +1100
Subject: [PATCH 3/3] Assemble: change load_devices to return most_recent 'st'
value.
This means that
st->ss->getinfo_super(st, content, NULL);
clean = content->array.state & 1;
will get an up-to-date value for 'clean'. This fix allows
tests/03r5assem-failed
to work.
Signed-off-by: NeilBrown <neilb@suse.de>
---
Assemble.c | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)
--- mdadm-3.3.orig/Assemble.c
+++ mdadm-3.3/Assemble.c
@@ -703,8 +703,12 @@ static int load_devices(struct devs *dev
if (devices[devcnt].i.disk.state == 6) {
if (most_recent < 0 ||
devices[devcnt].i.events
- > devices[most_recent].i.events)
+ > devices[most_recent].i.events) {
+ struct supertype *tmp = tst;
+ tst = st;
+ st = tmp;
most_recent = devcnt;
+ }
}
tst->ss->free_super(tst);
free(tst);

View File

@ -1,27 +0,0 @@
From 188d31ed2b6dc195a4be1f5620ce2e5185d4e789 Mon Sep 17 00:00:00 2001
From: NeilBrown <neilb@suse.de>
Date: Wed, 2 Apr 2014 15:14:43 +1100
Subject: [PATCH 3/4] DDF: fix possible mdmon crash when updating metadata.
Testing 'c' and then using 'vdc' assumes that the two are in sync,
but sometimes they aren't.
Testing 'vdc' is safer.
This avoids a crash in some cases when failing/removing/added devices
to a DDF.
Signed-off-by: NeilBrown <neilb@suse.de>
---
super-ddf.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
--- mdadm-3.3.orig/super-ddf.c
+++ mdadm-3.3/super-ddf.c
@@ -3000,7 +3000,7 @@ static int __write_ddf_structure(struct
(const struct vd_config **)&vdc,
&dummy);
}
- if (c) {
+ if (vdc) {
dprintf("writing conf record %i on disk %08x for %s/%u\n",
i, be32_to_cpu(d->disk.refnum),
guid_str(vdc->guid),

View File

@ -1,38 +0,0 @@
From 76d0f1886fdef89891d617df7e7f3fde89a38e1a Mon Sep 17 00:00:00 2001
From: Jes Sorensen <Jes.Sorensen@redhat.com>
Date: Wed, 19 Mar 2014 14:26:02 +0100
Subject: [PATCH 3/6] Work around architectures having statfs.f_type defined as
long
Having RAMFS_MAGIC defined as 0x858458f6 causing problems when trying
to compare it directly against statfs.f_type being cast from long to
unsigned long.
This hack is extremly ugly, but it should at least do the right thing
for every situation.
Thanks to Arnd Bergmann for suggesting the fix.
Signed-off-by: Jes Sorensen <Jes.Sorensen@redhat.com>
Signed-off-by: NeilBrown <neilb@suse.de>
---
util.c | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)
--- mdadm-3.3.orig/util.c
+++ mdadm-3.3/util.c
@@ -1948,9 +1948,13 @@ int in_initrd(void)
{
/* This is based on similar function in systemd. */
struct statfs s;
+ /* statfs.f_type is signed long on s390x and MIPS, causing all
+ sorts of sign extension problems with RAMFS_MAGIC being
+ defined as 0x858458f6 */
return statfs("/", &s) >= 0 &&
((unsigned long)s.f_type == TMPFS_MAGIC ||
- (unsigned long)s.f_type == RAMFS_MAGIC);
+ ((unsigned long)s.f_type & 0xFFFFFFFFUL) ==
+ ((unsigned long)RAMFS_MAGIC & 0xFFFFFFFFUL));
}
void reopen_mddev(int mdfd)

View File

@ -1,86 +0,0 @@
From f43f5b32991c7f5a188940b00989c27f87feee81 Mon Sep 17 00:00:00 2001
From: NeilBrown <neilb@suse.de>
Date: Wed, 2 Apr 2014 15:26:35 +1100
Subject: [PATCH 4/4] DDF: Don't fail compare_super_ddf due to re-configure
changes.
It is possible that one device has seem some reconfig but the other
hasn't. In that case they are still the "same" DDF, even though
one might be older. Such age will be detected by 'seq' differences.
If A is new and B is old, then it is import that
mdadm -I B
mdadm -I A
doesn't get confused because A has the same uuid as B, but compare_super fails.
So: if the seq numbers are different, then just accept as two
different superblocks.
If they are the same, then look to copy data from new to old.
Signed-off-by: NeilBrown <neilb@suse.de>
---
super-ddf.c | 44 +++++++++++---------------------------------
1 file changed, 11 insertions(+), 33 deletions(-)
--- mdadm-3.3.orig/super-ddf.c
+++ mdadm-3.3/super-ddf.c
@@ -3937,47 +3937,25 @@ static int compare_super_ddf(struct supe
if (memcmp(first->anchor.guid, second->anchor.guid, DDF_GUID_LEN) != 0)
return 2;
- if (first->max_part != second->max_part ||
- !be16_eq(first->phys->used_pdes, second->phys->used_pdes) ||
- !be16_eq(first->virt->populated_vdes,
- second->virt->populated_vdes)) {
- dprintf("%s: PD/VD number mismatch\n", __func__);
- return 3;
- }
+ /* It is only OK to compare info in the anchor. Anything else
+ * could be changing due to a reconfig so must be ignored.
+ * guid really should be enough anyway.
+ */
- max_pds = be16_to_cpu(first->phys->used_pdes);
- for (dl2 = second->dlist; dl2; dl2 = dl2->next) {
- for (pd = 0; pd < max_pds; pd++)
- if (be32_eq(first->phys->entries[pd].refnum,
- dl2->disk.refnum))
- break;
- if (pd == max_pds) {
- dprintf("%s: no match for disk %08x\n", __func__,
- be32_to_cpu(dl2->disk.refnum));
- return 3;
- }
+ if (!be32_eq(first->active->seq, second->active->seq)) {
+ dprintf("%s: sequence number mismatch %u<->%u\n", __func__,
+ be32_to_cpu(first->active->seq),
+ be32_to_cpu(second->active->seq));
+ return 0;
}
- max_vds = be16_to_cpu(first->active->max_vd_entries);
- for (vl2 = second->conflist; vl2; vl2 = vl2->next) {
- if (!be32_eq(vl2->conf.magic, DDF_VD_CONF_MAGIC))
- continue;
- for (vd = 0; vd < max_vds; vd++)
- if (!memcmp(first->virt->entries[vd].guid,
- vl2->conf.guid, DDF_GUID_LEN))
- break;
- if (vd == max_vds) {
- dprintf("%s: no match for VD config\n", __func__);
- return 3;
- }
- }
- /* FIXME should I look at anything else? */
-
/*
At this point we are fairly sure that the meta data matches.
But the new disk may contain additional local data.
Add it to the super block.
*/
+ max_vds = be16_to_cpu(first->active->max_vd_entries);
+ max_pds = be16_to_cpu(first->phys->used_pdes);
for (vl2 = second->conflist; vl2; vl2 = vl2->next) {
for (vl1 = first->conflist; vl1; vl1 = vl1->next)
if (!memcmp(vl1->conf.guid, vl2->conf.guid,

View File

@ -1,56 +0,0 @@
From eba2859f50bc0de6da7938a9ec6cfe4ceef43874 Mon Sep 17 00:00:00 2001
From: NeilBrown <neilb@suse.de>
Date: Wed, 26 Mar 2014 14:19:43 +1100
Subject: [PATCH 4/6] DDF: report seq counter as events.
Also don't treat two devices with different seq numbers as completely
unrelated.
This allows split-brain detection to work properly for ddf.
Signed-off-by: NeilBrown <neilb@suse.de>
---
super-ddf.c | 11 ++++-------
1 file changed, 4 insertions(+), 7 deletions(-)
--- mdadm-3.3.orig/super-ddf.c
+++ mdadm-3.3/super-ddf.c
@@ -1929,6 +1929,8 @@ static void getinfo_super_ddf(struct sup
info->disk.state = (1 << MD_DISK_SYNC) | (1 << MD_DISK_ACTIVE);
else
info->disk.state = 1 << MD_DISK_FAULTY;
+
+ info->events = be32_to_cpu(ddf->active->seq);
} else {
info->disk.number = -1;
info->disk.raid_disk = -1;
@@ -2029,6 +2031,7 @@ static void getinfo_super_ddf_bvd(struct
(be16_to_cpu(ddf->phys->entries[info->disk.number].state) & DDF_Online) &&
!(be16_to_cpu(ddf->phys->entries[info->disk.number].state) & DDF_Failed))
info->disk.state = (1<<MD_DISK_SYNC)|(1<<MD_DISK_ACTIVE);
+ info->events = be32_to_cpu(ddf->active->seq);
}
info->container_member = ddf->currentconf->vcnum;
@@ -3841,7 +3844,7 @@ static struct mdinfo *container_content_
dev->disk.state = (1<<MD_DISK_SYNC)|(1<<MD_DISK_ACTIVE);
dev->recovery_start = MaxSector;
- dev->events = be32_to_cpu(ddf->primary.seq);
+ dev->events = be32_to_cpu(ddf->active->seq);
dev->data_offset =
be64_to_cpu(LBA_OFFSET(ddf, bvd)[iphys]);
dev->component_size = be64_to_cpu(bvd->blocks);
@@ -3928,12 +3931,6 @@ static int compare_super_ddf(struct supe
if (memcmp(first->anchor.guid, second->anchor.guid, DDF_GUID_LEN) != 0)
return 2;
- if (!be32_eq(first->active->seq, second->active->seq)) {
- dprintf("%s: sequence number mismatch %u<->%u\n", __func__,
- be32_to_cpu(first->active->seq),
- be32_to_cpu(second->active->seq));
- return 3;
- }
if (first->max_part != second->max_part ||
!be16_eq(first->phys->used_pdes, second->phys->used_pdes) ||
!be16_eq(first->virt->populated_vdes,

View File

@ -1,65 +0,0 @@
From 5a46fcd7f5b1bd1bf190784f112a15f383262af5 Mon Sep 17 00:00:00 2001
From: NeilBrown <neilb@suse.de>
Date: Wed, 26 Mar 2014 14:26:53 +1100
Subject: [PATCH 5/6] DDF: when first activating an array, record any missing
devices.
We must remember they are missing so that if they re-appear we
don't get confused.
Signed-off-by: NeilBrown <neilb@suse.de>
---
super-ddf.c | 28 ++++++++++++++++++++++++++++
1 file changed, 28 insertions(+)
--- mdadm-3.3.orig/super-ddf.c
+++ mdadm-3.3/super-ddf.c
@@ -511,6 +511,8 @@ static void pr_state(const struct ddf_su
static void _ddf_set_updates_pending(struct ddf_super *ddf, const char *func)
{
+ if (ddf->updates_pending)
+ return;
ddf->updates_pending = 1;
ddf->active->seq = cpu_to_be32((be32_to_cpu(ddf->active->seq)+1));
pr_state(ddf, func);
@@ -4115,6 +4117,31 @@ static int ddf_open_new(struct supertype
return 0;
}
+static void handle_missing(struct ddf_super *ddf, int inst)
+{
+ /* This member array is being activated. If any devices
+ * are missing they must now be marked as failed.
+ */
+ struct vd_config *vc;
+ unsigned int n_bvd;
+ struct vcl *vcl;
+ struct dl *dl;
+ int n;
+
+ for (n = 0; ; n++) {
+ vc = find_vdcr(ddf, inst, n, &n_bvd, &vcl);
+ if (!vc)
+ break;
+ for (dl = ddf->dlist; dl; dl = dl->next)
+ if (be32_eq(dl->disk.refnum, vc->phys_refnum[n_bvd]))
+ break;
+ if (dl)
+ /* Found this disk, so not missing */
+ continue;
+ vc->phys_refnum[n_bvd] = cpu_to_be32(0);
+ }
+}
+
/*
* The array 'a' is to be marked clean in the metadata.
* If '->resync_start' is not ~(unsigned long long)0, then the array is only
@@ -4130,6 +4157,7 @@ static int ddf_set_array_state(struct ac
int inst = a->info.container_member;
int old = ddf->virt->entries[inst].state;
if (consistent == 2) {
+ handle_missing(ddf, inst);
/* Should check if a recovery should be started FIXME */
consistent = 1;
if (!is_resync_complete(&a->info))

View File

@ -1,55 +0,0 @@
From f81a2b56c4b437f66aaf5582a9c6b7f5ab2103c4 Mon Sep 17 00:00:00 2001
From: NeilBrown <neilb@suse.de>
Date: Tue, 22 Oct 2013 09:55:04 +1100
Subject: [PATCH] Assembe: fix bug in force_array - it wasn't forcing properly.
Since 'best' was expanded to hold replacement devices, we might
need to go up to raid_disks*2 to find devices to force.
Also fix another place when considering replacement drives would
be wrong (the 'chosen' device should never be a replacement).
Reported-by: John Yates <jyates65@gmail.com>
Signed-off-by: NeilBrown <neilb@suse.de>
---
Assemble.c | 10 +++++++---
1 file changed, 7 insertions(+), 3 deletions(-)
diff --git a/Assemble.c b/Assemble.c
index 86b4c894b260..4d5ceeac8674 100644
--- a/Assemble.c
+++ b/Assemble.c
@@ -803,7 +803,9 @@ static int force_array(struct mdinfo *content,
int chosen_drive = -1;
int i;
- for (i = 0; i < content->array.raid_disks && i < bestcnt; i++) {
+ for (i = 0;
+ i < content->array.raid_disks * 2 && i < bestcnt;
+ i += 2) {
int j = best[i];
if (j>=0 &&
!devices[j].uptodate &&
@@ -863,7 +865,9 @@ static int force_array(struct mdinfo *content,
/* If there are any other drives of the same vintage,
* add them in as well. We can't lose and we might gain
*/
- for (i = 0; i < content->array.raid_disks && i < bestcnt ; i++) {
+ for (i = 0;
+ i < content->array.raid_disks * 2 && i < bestcnt ;
+ i += 2) {
int j = best[i];
if (j >= 0 &&
!devices[j].uptodate &&
@@ -1528,7 +1532,7 @@ try_again:
*/
chosen_drive = -1;
st->ss->free_super(st);
- for (i=0; chosen_drive < 0 && i<bestcnt; i++) {
+ for (i=0; chosen_drive < 0 && i<bestcnt; i+=2) {
int j = best[i];
int fd;
--
1.8.3.1.487.g3e7a5b4

View File

@ -1,88 +0,0 @@
From 8832342d3aad09d3c86af6dc9b137d6fd83af1ae Mon Sep 17 00:00:00 2001
From: NeilBrown <neilb@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 <neilb@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

View File

@ -1,34 +0,0 @@
From 284546ef89168c9003da192a177cae774199f889 Mon Sep 17 00:00:00 2001
From: NeilBrown <neilb@suse.de>
Date: Mon, 20 Jan 2014 15:23:31 +1100
Subject: [PATCH 07/13] Assemble: avoid infinite loop when auto-assembling
partial container.
When auto-assembling we loop until we get no successes.
If a device is found that look like it is part of an already-existing
container, but we subsequently fail to add that device, then the fact
that the container is running looks like a success. This can result
in infinite looping.
So if a container was already partially assemble, and is still only
partially assembled after we try to add devices, then don't treat that
as success.
Signed-off-by: NeilBrown <neilb@suse.de>
---
Assemble.c | 4 ++++
1 file changed, 4 insertions(+)
--- mdadm-3.3.orig/Assemble.c
+++ mdadm-3.3/Assemble.c
@@ -990,6 +990,10 @@ static int start_array(int mdfd,
}
st->ss->free_super(st);
sysfs_uevent(content, "change");
+ if (err_ok && okcnt < (unsigned)content->array.raid_disks)
+ /* Was partial, is still partial, so signal an error
+ * to ensure we don't retry */
+ return 1;
return 0;
}

View File

@ -1,58 +0,0 @@
From 105e6e93a2b556560d0275bd5ceb29751de28469 Mon Sep 17 00:00:00 2001
From: "mwilck@arcor.de" <mwilck@arcor.de>
Date: Tue, 24 Sep 2013 19:18:52 +0200
Subject: [PATCH] DDF: add_to_super_ddf: be careful with workspace_lba
Some vendor DDF structures interpret workspace_lba
very differently then us. Make a sanity check on the value
before using it for config_size.
Signed-off-by: Martin Wilck <mwilck@arcor.de>
Signed-off-by: NeilBrown <neilb@suse.de>
---
super-ddf.c | 27 ++++++++++++++++++++++++++-
1 file changed, 26 insertions(+), 1 deletion(-)
--- mdadm-3.3.orig/super-ddf.c
+++ mdadm-3.3/super-ddf.c
@@ -2704,6 +2704,31 @@ static unsigned int find_unused_pde(cons
return DDF_NOTFOUND;
}
+static void _set_config_size(struct phys_disk_entry *pde, const struct dl *dl)
+{
+ __u64 cfs, t;
+ cfs = min(dl->size - 32*1024*2ULL, be64_to_cpu(dl->primary_lba));
+ t = be64_to_cpu(dl->secondary_lba);
+ if (t != ~(__u64)0)
+ cfs = min(cfs, t);
+ /*
+ * Some vendor DDF structures interpret workspace_lba
+ * very differently then us. Make a sanity check on the value.
+ */
+ t = be64_to_cpu(dl->workspace_lba);
+ if (t < cfs) {
+ __u64 wsp = cfs - t;
+ if (wsp > 1024*1024*2ULL && wsp > dl->size / 16) {
+ pr_err("%s: %x:%x: workspace size 0x%llx too big, ignoring\n",
+ __func__, dl->major, dl->minor, wsp);
+ } else
+ cfs = t;
+ }
+ pde->config_size = cpu_to_be64(cfs);
+ dprintf("%s: %x:%x config_size %llx, DDF structure is %llx blocks\n",
+ __func__, dl->major, dl->minor, cfs, dl->size-cfs);
+}
+
/* add a device to a container, either while creating it or while
* expanding a pre-existing container
*/
@@ -2826,7 +2851,7 @@ static int add_to_super_ddf(struct super
if (ddf->dlist == NULL ||
be64_to_cpu(ddf->dlist->secondary_lba) != ~(__u64)0)
__calc_lba(dd, ddf->dlist, secondary_lba, 32);
- pde->config_size = dd->workspace_lba;
+ _set_config_size(pde, dd);
sprintf(pde->path, "%17.17s","Information: nil") ;
memset(pde->pad, 0xff, 6);

View File

@ -1,52 +0,0 @@
From b95cb4b9d88c8adf2adb7f2efef3ae3f72b27b8e Mon Sep 17 00:00:00 2001
From: NeilBrown <neilb@suse.de>
Date: Thu, 12 Sep 2013 14:57:28 +1000
Subject: [PATCH] DDF: allow for possibility that there is no secondary copy of
metadata.
If there isn't, we currently write the second copy at some
random location :-)
Reported-and-tested-by: Francis Moreau <francis.moro@gmail.com>
Signed-off-by: NeilBrown <neilb@suse.de>
---
super-ddf.c | 9 +++++++--
1 file changed, 7 insertions(+), 2 deletions(-)
diff --git a/super-ddf.c b/super-ddf.c
index 636d7b4..d2cdda4 100644
--- a/super-ddf.c
+++ b/super-ddf.c
@@ -880,7 +880,8 @@ static int load_ddf_headers(int fd, struct ddf_super *super, char *devname)
super->primary.openflag && !super->secondary.openflag)
)
super->active = &super->secondary;
- } else if (devname)
+ } else if (devname &&
+ be64_to_cpu(super->anchor.secondary_lba) != ~(__u64)0)
pr_err("Failed to load secondary DDF header on %s\n",
devname);
if (super->active == NULL)
@@ -2810,7 +2811,9 @@ static int add_to_super_ddf(struct supertype *st,
} while (0)
__calc_lba(dd, ddf->dlist, workspace_lba, 32);
__calc_lba(dd, ddf->dlist, primary_lba, 16);
- __calc_lba(dd, ddf->dlist, secondary_lba, 32);
+ if (ddf->dlist == NULL ||
+ be64_to_cpu(ddf->dlist->secondary_lba) != ~(__u64)0)
+ __calc_lba(dd, ddf->dlist, secondary_lba, 32);
pde->config_size = dd->workspace_lba;
sprintf(pde->path, "%17.17s","Information: nil") ;
@@ -2892,6 +2895,8 @@ static int __write_ddf_structure(struct dl *d, struct ddf_super *ddf, __u8 type)
default:
return 0;
}
+ if (sector == ~(__u64)0)
+ return 0;
header->type = type;
header->openflag = 1;
--
1.8.3.1.487.g3e7a5b4

View File

@ -1,44 +0,0 @@
From a8b25633544db9fb03bc3b12442aafbbae9c1e1c Mon Sep 17 00:00:00 2001
From: "mwilck@arcor.de" <mwilck@arcor.de>
Date: Wed, 11 Sep 2013 21:55:35 +0200
Subject: [PATCH] DDF: brief_examine_subarrays_ddf: print array name
Print an array name in brief output, like IMSM does.
SUSE's YaST2 (libstorage) needs this in order to detect MD arrays
during installation.
Signed-off-by: Martin Wilck <mwilck@arcor.de>
Signed-off-by: NeilBrown <neilb@suse.de>
---
super-ddf.c | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)
--- mdadm-3.3.orig/super-ddf.c
+++ mdadm-3.3/super-ddf.c
@@ -1519,6 +1519,7 @@ static void getinfo_super_ddf(struct sup
static void uuid_from_ddf_guid(const char *guid, int uuid[4]);
static void uuid_from_super_ddf(struct supertype *st, int uuid[4]);
+static void _ddf_array_name(char *name, const struct ddf_super *ddf, int i);
static unsigned int get_vd_num_of_subarray(struct supertype *st)
{
@@ -1578,13 +1579,16 @@ static void brief_examine_subarrays_ddf(
struct virtual_entry *ve = &ddf->virt->entries[i];
struct vcl vcl;
char nbuf1[64];
+ char namebuf[17];
if (all_ff(ve->guid))
continue;
memcpy(vcl.conf.guid, ve->guid, DDF_GUID_LEN);
ddf->currentconf =&vcl;
uuid_from_super_ddf(st, info.uuid);
fname_from_uuid(st, &info, nbuf1, ':');
- printf("ARRAY container=%s member=%d UUID=%s\n",
+ _ddf_array_name(namebuf, ddf, i);
+ printf("ARRAY%s%s container=%s member=%d UUID=%s\n",
+ namebuf[0] == '\0' ? "" : " /dev/md/", namebuf,
nbuf+5, i, nbuf1+5);
}
}

View File

@ -1,39 +0,0 @@
From 7039479987745f19b166b1c28d45dfc41420e6d9 Mon Sep 17 00:00:00 2001
From: "mwilck@arcor.de" <mwilck@arcor.de>
Date: Sat, 14 Sep 2013 22:47:12 +0200
Subject: [PATCH] DDF: compare_super_ddf: fix sequence number check
The sequence number check in compare_super_ddf was broken,
anchor sequence number is always -1.
With this patch, mdadm will refuse to add a disk with non-matching
sequence number.
This fixes Francis Moreau's problem reported with subject
"mdadm 3.3 fails to kick out non fresh disk".
FIXME: More work is needed here. Currently mdadm won't even add the
disk to the container, that's wrong. It should be added as a spare.
Signed-off-by: NeilBrown <neilb@suse.de>
---
super-ddf.c | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
--- mdadm-3.3.orig/super-ddf.c
+++ mdadm-3.3/super-ddf.c
@@ -3893,10 +3893,10 @@ static int compare_super_ddf(struct supe
if (memcmp(first->anchor.guid, second->anchor.guid, DDF_GUID_LEN) != 0)
return 2;
- if (!be32_eq(first->anchor.seq, second->anchor.seq)) {
- dprintf("%s: sequence number mismatch %u/%u\n", __func__,
- be32_to_cpu(first->anchor.seq),
- be32_to_cpu(second->anchor.seq));
+ if (!be32_eq(first->active->seq, second->active->seq)) {
+ dprintf("%s: sequence number mismatch %u<->%u\n", __func__,
+ be32_to_cpu(first->active->seq),
+ be32_to_cpu(second->active->seq));
return 3;
}
if (first->max_part != second->max_part ||

View File

@ -1,69 +0,0 @@
From 8bf989d8e1bf1c6305076ad8108ec207c23c03cb Mon Sep 17 00:00:00 2001
From: "mwilck@arcor.de" <mwilck@arcor.de>
Date: Wed, 11 Sep 2013 21:55:34 +0200
Subject: [PATCH] DDF: factor out array name generation
The same algorithm was used in getinfo_super_ddf_bvd and
container_content_ddf. Put it in a common function.
Signed-off-by: Martin Wilck <mwilck@arcor.de>
Signed-off-by: NeilBrown <neilb@suse.de>
---
super-ddf.c | 25 +++++++++++++------------
1 file changed, 13 insertions(+), 12 deletions(-)
--- mdadm-3.3.orig/super-ddf.c
+++ mdadm-3.3/super-ddf.c
@@ -1910,6 +1910,17 @@ static void getinfo_super_ddf(struct sup
}
}
+/* size of name must be at least 17 bytes! */
+static void _ddf_array_name(char *name, const struct ddf_super *ddf, int i)
+{
+ int j;
+ memcpy(name, ddf->virt->entries[i].name, 16);
+ name[16] = 0;
+ for(j = 0; j < 16; j++)
+ if (name[j] == ' ')
+ name[j] = 0;
+}
+
static void getinfo_super_ddf_bvd(struct supertype *st, struct mdinfo *info, char *map)
{
struct ddf_super *ddf = st->sb;
@@ -1987,11 +1998,7 @@ static void getinfo_super_ddf_bvd(struct
info->container_member);
info->safe_mode_delay = DDF_SAFE_MODE_DELAY;
- memcpy(info->name, ddf->virt->entries[info->container_member].name, 16);
- info->name[16]=0;
- for(j=0; j<16; j++)
- if (info->name[j] == ' ')
- info->name[j] = 0;
+ _ddf_array_name(info->name, ddf, info->container_member);
if (map)
for (j = 0; j < map_disks; j++) {
@@ -3656,7 +3663,6 @@ static struct mdinfo *container_content_
for (vc = ddf->conflist ; vc ; vc=vc->next)
{
unsigned int i;
- unsigned int j;
struct mdinfo *this;
char *ep;
__u32 *cptr;
@@ -3698,12 +3704,7 @@ static struct mdinfo *container_content_
this->array.state = 1;
this->resync_start = MaxSector;
}
- memcpy(this->name, ddf->virt->entries[i].name, 16);
- this->name[16]=0;
- for(j=0; j<16; j++)
- if (this->name[j] == ' ')
- this->name[j] = 0;
-
+ _ddf_array_name(this->name, ddf, i);
memset(this->uuid, 0, sizeof(this->uuid));
this->component_size = be64_to_cpu(vc->conf.blocks);
this->array.size = this->component_size / 2;

View File

@ -1,79 +0,0 @@
From f0e876ce03a63f150bb87b2734c139bc8bb285b2 Mon Sep 17 00:00:00 2001
From: NeilBrown <neilb@suse.de>
Date: Mon, 20 Jan 2014 15:27:29 +1100
Subject: [PATCH 08/13] DDF: fix detection of failed devices during assembly.
When we call "getinfo_super", we report the working/failed status
of the particular device, and also (via the 'map') the working/failed
status of every other device that this metadata is aware of.
It is important that the way we calculate "working or failed" is
consistent.
As it is, getinfo_super_ddf() will report a spare as "working", but
every other device will see it as "failed", which leads to failure to
assemble arrays with spares.
For getinfo_super_ddf (i.e. for the container), a device is assumed
"working" unless flagged as DDF_Failed.
For getinfo_super_ddf_bvd (for a member array), a device is assumed
"failed" unless DDF_Online is set, and DDF_Failed is not set.
Reported-by: "David F." <df7729@gmail.com>
Signed-off-by: NeilBrown <neilb@suse.de>
---
super-ddf.c | 18 ++++++++++++++----
1 file changed, 14 insertions(+), 4 deletions(-)
--- mdadm-3.3.orig/super-ddf.c
+++ mdadm-3.3/super-ddf.c
@@ -1914,6 +1914,7 @@ static void getinfo_super_ddf(struct sup
info->disk.major = 0;
info->disk.minor = 0;
if (ddf->dlist) {
+ struct phys_disk_entry *pde = NULL;
info->disk.number = be32_to_cpu(ddf->dlist->disk.refnum);
info->disk.raid_disk = find_phys(ddf, ddf->dlist->disk.refnum);
@@ -1921,12 +1922,19 @@ static void getinfo_super_ddf(struct sup
entries[info->disk.raid_disk].
config_size);
info->component_size = ddf->dlist->size - info->data_offset;
+ if (info->disk.raid_disk >= 0)
+ pde = ddf->phys->entries + info->disk.raid_disk;
+ if (pde &&
+ !(be16_to_cpu(pde->state) & DDF_Failed))
+ info->disk.state = (1 << MD_DISK_SYNC) | (1 << MD_DISK_ACTIVE);
+ else
+ info->disk.state = 1 << MD_DISK_FAULTY;
} else {
info->disk.number = -1;
info->disk.raid_disk = -1;
// info->disk.raid_disk = find refnum in the table and use index;
+ info->disk.state = (1 << MD_DISK_SYNC) | (1 << MD_DISK_ACTIVE);
}
- info->disk.state = (1 << MD_DISK_SYNC) | (1 << MD_DISK_ACTIVE);
info->recovery_start = MaxSector;
info->reshape_active = 0;
@@ -1944,8 +1952,6 @@ static void getinfo_super_ddf(struct sup
int i;
for (i = 0 ; i < map_disks; i++) {
if (i < info->array.raid_disks &&
- (be16_to_cpu(ddf->phys->entries[i].state)
- & DDF_Online) &&
!(be16_to_cpu(ddf->phys->entries[i].state)
& DDF_Failed))
map[i] = 1;
@@ -2018,7 +2024,11 @@ static void getinfo_super_ddf_bvd(struct
info->disk.raid_disk = cd + conf->sec_elmnt_seq
* be16_to_cpu(conf->prim_elmnt_count);
info->disk.number = dl->pdnum;
- info->disk.state = (1<<MD_DISK_SYNC)|(1<<MD_DISK_ACTIVE);
+ info->disk.state = 0;
+ if (info->disk.number >= 0 &&
+ (be16_to_cpu(ddf->phys->entries[info->disk.number].state) & DDF_Online) &&
+ !(be16_to_cpu(ddf->phys->entries[info->disk.number].state) & DDF_Failed))
+ info->disk.state = (1<<MD_DISK_SYNC)|(1<<MD_DISK_ACTIVE);
}
info->container_member = ddf->currentconf->vcnum;

View File

@ -1,115 +0,0 @@
From 7087f02b90ef7b5817193d385b8d83148565bff9 Mon Sep 17 00:00:00 2001
From: "mwilck@arcor.de" <mwilck@arcor.de>
Date: Mon, 9 Sep 2013 20:40:14 +0200
Subject: [PATCH] DDF: handle fake RAIDs with changing subarray UUIDs
Some fake RAID BIOSes (in particular, LSI ones) change the
VD GUID at every boot. These GUIDs are not suitable for
identifying an array. Luckily the header GUID appears to
remain constant.
We construct a pseudo-UUID from the header GUID and those
properties of the subarray that we expect to remain constant.
This is only array name and index; all else might change e.g.
during grow.
Don't do this for all non-MD arrays, only for those known
to use varying volume GUIDs.
This patch obsoletes my previous patch "DDF: new algorithm
for subarray UUID"
Signed-off-by: Martin Wilck <mwilck@arcor.de>
Signed-off-by: NeilBrown <neilb@suse.de>
---
super-ddf.c | 55 ++++++++++++++++++++++++++++++++++++++++++++++++++-----
1 file changed, 50 insertions(+), 5 deletions(-)
--- mdadm-3.3.orig/super-ddf.c
+++ mdadm-3.3/super-ddf.c
@@ -1584,6 +1584,7 @@ static void brief_examine_subarrays_ddf(
continue;
memcpy(vcl.conf.guid, ve->guid, DDF_GUID_LEN);
ddf->currentconf =&vcl;
+ vcl.vcnum = i;
uuid_from_super_ddf(st, info.uuid);
fname_from_uuid(st, &info, nbuf1, ':');
_ddf_array_name(namebuf, ddf, i);
@@ -1678,6 +1679,52 @@ static void detail_super_ddf(struct supe
*/
}
+static const char *vendors_with_variable_volume_UUID[] = {
+ "LSI ",
+};
+
+static int volume_id_is_reliable(const struct ddf_super *ddf)
+{
+ int n = sizeof(vendors_with_variable_volume_UUID) /
+ sizeof(vendors_with_variable_volume_UUID[0]);
+ int i;
+ for (i = 0; i < n; i++)
+ if (!memcmp(ddf->controller.guid,
+ vendors_with_variable_volume_UUID[i], 8))
+ return 0;
+ return 1;
+}
+
+static void uuid_of_ddf_subarray(const struct ddf_super *ddf,
+ unsigned int vcnum, int uuid[4])
+{
+ char buf[DDF_GUID_LEN+18], sha[20], *p;
+ struct sha1_ctx ctx;
+ if (volume_id_is_reliable(ddf)) {
+ uuid_from_ddf_guid(ddf->virt->entries[vcnum].guid, uuid);
+ return;
+ }
+ /*
+ * Some fake RAID BIOSes (in particular, LSI ones) change the
+ * VD GUID at every boot. These GUIDs are not suitable for
+ * identifying an array. Luckily the header GUID appears to
+ * remain constant.
+ * We construct a pseudo-UUID from the header GUID and those
+ * properties of the subarray that we expect to remain constant.
+ */
+ memset(buf, 0, sizeof(buf));
+ p = buf;
+ memcpy(p, ddf->anchor.guid, DDF_GUID_LEN);
+ p += DDF_GUID_LEN;
+ memcpy(p, ddf->virt->entries[vcnum].name, 16);
+ p += 16;
+ *((__u16 *) p) = vcnum;
+ sha1_init_ctx(&ctx);
+ sha1_process_bytes(buf, sizeof(buf), &ctx);
+ sha1_finish_ctx(&ctx, sha);
+ memcpy(uuid, sha, 4*4);
+}
+
static void brief_detail_super_ddf(struct supertype *st)
{
struct mdinfo info;
@@ -1689,7 +1736,7 @@ static void brief_detail_super_ddf(struc
else if (vcnum == DDF_NOTFOUND)
return;
else
- uuid_from_ddf_guid(ddf->virt->entries[vcnum].guid, info.uuid);
+ uuid_of_ddf_subarray(ddf, vcnum, info.uuid);
fname_from_uuid(st, &info, nbuf,':');
printf(" UUID=%s", nbuf + 5);
}
@@ -1832,13 +1879,11 @@ static void uuid_from_super_ddf(struct s
*/
struct ddf_super *ddf = st->sb;
struct vcl *vcl = ddf->currentconf;
- char *guid;
if (vcl)
- guid = vcl->conf.guid;
+ uuid_of_ddf_subarray(ddf, vcl->vcnum, uuid);
else
- guid = ddf->anchor.guid;
- uuid_from_ddf_guid(guid, uuid);
+ uuid_from_ddf_guid(ddf->anchor.guid, uuid);
}
static void getinfo_super_ddf_bvd(struct supertype *st, struct mdinfo *info, char *map);

View File

@ -1,25 +0,0 @@
From a34fea0eae78fbabb289a5bce6d7a04bf889156d Mon Sep 17 00:00:00 2001
From: NeilBrown <neilb@suse.de>
Date: Mon, 20 Jan 2014 12:25:23 +1100
Subject: [PATCH 06/13] DDF - really ignore DDF metadata on partitions.
See commit 357ac1067835d1cdd5f80acc28501db0ffc64957
which made a similar change for super-intel, and really should have
fixed DDF at the same time.
Signed-off-by: NeilBrown <neilb@suse.de>
---
super-ddf.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
--- mdadm-3.3.orig/super-ddf.c
+++ mdadm-3.3/super-ddf.c
@@ -1126,7 +1126,7 @@ static int load_super_ddf(struct superty
if (get_dev_size(fd, devname, &dsize) == 0)
return 1;
- if (!st->ignore_hw_compat && test_partition(fd))
+ if (test_partition(fd))
/* DDF is not allowed on partitions */
return 1;

View File

@ -1,58 +0,0 @@
From 5e7be8389446a4afa016351e65d1ead31a978f16 Mon Sep 17 00:00:00 2001
From: NeilBrown <neilb@suse.de>
Date: Mon, 20 Jan 2014 15:31:45 +1100
Subject: [PATCH 09/13] Grow: fix problems with prematurely aborting of
reshapes.
1/ when unfreezing, make sure the array is frozen first.
If it isn't we might end up interrupting a reshape.
2/ When the child finishes, don't call abort_reshape() as that
will interrupt the reshape. Just set suspend_* etc
explicitly.
Signed-off-by: NeilBrown <neilb@suse.de>
---
Grow.c | 16 +++++++++++++---
1 file changed, 13 insertions(+), 3 deletions(-)
--- mdadm-3.3.orig/Grow.c
+++ mdadm-3.3/Grow.c
@@ -612,9 +612,14 @@ static void unfreeze(struct supertype *s
return unfreeze_container(st);
else {
struct mdinfo *sra = sysfs_read(-1, st->devnm, GET_VERSION);
+ char buf[20];
- if (sra)
+ if (sra &&
+ sysfs_get_str(sra, NULL, "sync_action", buf, 20) > 0
+ && strcmp(buf, "frozen\n") == 0) {
+ printf("unfreeze\n");
sysfs_set_str(sra, NULL, "sync_action", "idle");
+ }
sysfs_free(sra);
}
}
@@ -2666,7 +2671,7 @@ static int impose_level(int fd, int leve
for (d = 0, found = 0;
d < MAX_DISKS && found < array.nr_disks;
d++) {
- mdu_disk_info_t disk;
+ mdu_disk_info_t disk;
disk.number = d;
if (ioctl(fd, GET_DISK_INFO, &disk) < 0)
continue;
@@ -4316,7 +4321,12 @@ int child_monitor(int afd, struct mdinfo
}
/* FIXME maybe call progress_reshape one more time instead */
- abort_reshape(sra); /* remove any remaining suspension */
+ /* remove any remaining suspension */
+ sysfs_set_num(sra, NULL, "suspend_lo", 0x7FFFFFFFFFFFFFFFULL);
+ sysfs_set_num(sra, NULL, "suspend_hi", 0);
+ sysfs_set_num(sra, NULL, "suspend_lo", 0);
+ sysfs_set_num(sra, NULL, "sync_min", 0);
+
if (reshape->before.data_disks == reshape->after.data_disks)
sysfs_set_num(sra, NULL, "sync_speed_min", speed);
free(buf);

View File

@ -1,25 +0,0 @@
From 1ca5c8e0c74946f4fcd74e97c5f48fba482d9596 Mon Sep 17 00:00:00 2001
From: NeilBrown <neilb@suse.de>
Date: Tue, 21 Jan 2014 09:40:02 +1100
Subject: [PATCH 10/13] IMSM: don't crash when creating an array with missing
devices.
'missing' devices are in a different list so when collection the
serial numbers of all devices we need to check both lists.
Signed-off-by: NeilBrown <neilb@suse.de>
---
super-intel.c | 2 ++
1 file changed, 2 insertions(+)
--- mdadm-3.3.orig/super-intel.c
+++ mdadm-3.3/super-intel.c
@@ -5210,6 +5210,8 @@ static int create_array(struct supertype
int idx = get_imsm_disk_idx(dev, i, MAP_X);
disk = get_imsm_disk(super, idx);
+ if (!disk)
+ disk = get_imsm_missing(super, idx);
serialcpy(inf[i].serial, disk->serial);
}
append_metadata_update(st, u, len);

View File

@ -1,294 +0,0 @@
From 9ca39acb3e8bc31811e463d19fae81c5501aea65 Mon Sep 17 00:00:00 2001
From: NeilBrown <neilb@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 <neilb@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,

View File

@ -1,154 +0,0 @@
From b11fe74db0d764c3a245d95bc3651be9bbd59463 Mon Sep 17 00:00:00 2001
From: NeilBrown <neilb@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 <neilb@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"

View File

@ -1,252 +0,0 @@
From d5a4041647d2b3328ce45ff727afe37477f07c75 Mon Sep 17 00:00:00 2001
From: NeilBrown <neilb@suse.de>
Date: Fri, 13 Sep 2013 10:51:20 +1000
Subject: [PATCH] Make -IRs and --run work properly for containers.
We really need to make sure assemble_container_content()
gets called to finished the assembly of these.
Reported-by: Francis Moreau <francis.moro@gmail.com>
Signed-off-by: NeilBrown <neilb@suse.de>
---
Assemble.c | 2 +-
Incremental.c | 53 +++++++++++++++++++++++++++++++++++++++++++++--------
Manage.c | 4 ++--
mdadm.c | 7 ++++---
mdadm.h | 4 ++--
5 files changed, 54 insertions(+), 16 deletions(-)
diff --git a/Assemble.c b/Assemble.c
index bc85603..86b4c89 100644
--- a/Assemble.c
+++ b/Assemble.c
@@ -1817,7 +1817,7 @@ int assemble_container_content(struct supertype *st, int mdfd,
working++;
} else if (errno == EEXIST)
preexist++;
- if (working + expansion == 0)
+ if (working + expansion == 0 && c->runstop <= 0)
return 1;/* Nothing new, don't try to start */
map_update(&map, fd2devnm(mdfd),
diff --git a/Incremental.c b/Incremental.c
index f256b48..1bb3638 100644
--- a/Incremental.c
+++ b/Incremental.c
@@ -44,7 +44,7 @@ static int try_spare(char *devname, int *dfdp, struct dev_policy *pol,
struct supertype *st, int verbose);
static int Incremental_container(struct supertype *st, char *devname,
- struct context *c);
+ struct context *c, char *only);
int Incremental(char *devname, struct context *c,
struct supertype *st)
@@ -138,7 +138,7 @@ int Incremental(char *devname, struct context *c,
if (map_lock(&map))
pr_err("failed to get "
"exclusive lock on mapfile\n");
- rv = Incremental_container(st, devname, c);
+ rv = Incremental_container(st, devname, c, NULL);
map_unlock(&map);
return rv;
}
@@ -478,7 +478,7 @@ int Incremental(char *devname, struct context *c,
close(mdfd);
sysfs_free(sra);
if (!rv)
- rv = Incremental_container(st, chosen_name, c);
+ rv = Incremental_container(st, chosen_name, c, NULL);
map_unlock(&map);
if (rv == 1)
/* Don't fail the whole -I if a subarray didn't
@@ -1278,7 +1278,7 @@ static int try_spare(char *devname, int *dfdp, struct dev_policy *pol,
return rv;
}
-int IncrementalScan(int verbose, char *devnm)
+int IncrementalScan(struct context *c, char *devnm)
{
/* look at every device listed in the 'map' file.
* If one is found that is not running then:
@@ -1290,10 +1290,13 @@ int IncrementalScan(int verbose, char *devnm)
struct map_ent *me;
struct mddev_ident *devs, *mddev;
int rv = 0;
+ char container[32];
+ char *only = NULL;
map_read(&mapl);
devs = conf_get_ident(NULL);
+restart:
for (me = mapl ; me ; me = me->next) {
mdu_array_info_t array;
mdu_bitmap_file_t bmf;
@@ -1302,10 +1305,42 @@ int IncrementalScan(int verbose, char *devnm)
if (devnm && strcmp(devnm, me->devnm) != 0)
continue;
+ if (devnm && me->metadata[0] == '/') {
+ char *sl;
+ /* member array, need to work on container */
+ strncpy(container, me->metadata+1, 32);
+ container[31] = 0;
+ sl = strchr(container, '/');
+ if (sl)
+ *sl = 0;
+ only = devnm;
+ devnm = container;
+ goto restart;
+ }
mdfd = open_dev(me->devnm);
if (mdfd < 0)
continue;
+ if (!isdigit(me->metadata[0])) {
+ /* must be a container */
+ struct supertype *st = super_by_fd(mdfd, NULL);
+ int ret = 0;
+ struct map_ent *map = NULL;
+ if (st)
+ st->ignore_hw_compat = 1;
+ if (st && st->ss->load_container)
+ ret = st->ss->load_container(st, mdfd, NULL);
+ close(mdfd);
+ if (!ret && st->ss->container_content) {
+ if (map_lock(&map))
+ pr_err("failed to get exclusive lock on mapfile\n");
+ ret = Incremental_container(st, me->path, c, only);
+ map_unlock(&map);
+ }
+ if (ret)
+ rv = 1;
+ continue;
+ }
if (ioctl(mdfd, GET_ARRAY_INFO, &array) == 0 ||
errno != ENODEV) {
close(mdfd);
@@ -1330,7 +1365,7 @@ int IncrementalScan(int verbose, char *devnm)
close(bmfd);
}
}
- if (verbose >= 0) {
+ if (c->verbose >= 0) {
if (added == 0)
pr_err("Added bitmap %s to %s\n",
mddev->bitmap_file, me->path);
@@ -1346,7 +1381,7 @@ int IncrementalScan(int verbose, char *devnm)
if (sra) {
if (sysfs_set_str(sra, NULL,
"array_state", "read-auto") == 0) {
- if (verbose >= 0)
+ if (c->verbose >= 0)
pr_err("started array %s\n",
me->path ?: me->devnm);
} else {
@@ -1387,7 +1422,7 @@ static char *container2devname(char *devname)
}
static int Incremental_container(struct supertype *st, char *devname,
- struct context *c)
+ struct context *c, char *only)
{
/* Collect the contents of this container and for each
* array, choose a device name and assemble the array.
@@ -1458,7 +1493,7 @@ static int Incremental_container(struct supertype *st, char *devname,
strcpy(chosen_name, mp->path);
else
strcpy(chosen_name, mp->devnm);
- } else {
+ } else if (!only) {
/* Check in mdadm.conf for container == devname and
* member == ra->text_version after second slash.
@@ -1515,6 +1550,8 @@ static int Incremental_container(struct supertype *st, char *devname,
trustworthy,
chosen_name);
}
+ if (only && (!mp || strcmp(mp->devnm, only) != 0))
+ continue;
if (mdfd < 0) {
pr_err("failed to open %s: %s.\n",
diff --git a/Manage.c b/Manage.c
index 910caa6..c8276ca 100644
--- a/Manage.c
+++ b/Manage.c
@@ -170,7 +170,7 @@ static void remove_devices(char *devnm, char *path)
free(path2);
}
-int Manage_run(char *devname, int fd, int verbose)
+int Manage_run(char *devname, int fd, struct context *c)
{
/* Run the array. Array must already be configured
* Requires >= 0.90.0
@@ -187,7 +187,7 @@ int Manage_run(char *devname, int fd, int verbose)
return 1;
}
strcpy(nm, nmp);
- return IncrementalScan(verbose, nm);
+ return IncrementalScan(c, nm);
}
int Manage_stop(char *devname, int fd, int verbose, int will_retry)
diff --git a/mdadm.c b/mdadm.c
index 1ada607..f55a035 100644
--- a/mdadm.c
+++ b/mdadm.c
@@ -1293,7 +1293,7 @@ int main(int argc, char *argv[])
if (!rv && c.readonly < 0)
rv = Manage_ro(devlist->devname, mdfd, c.readonly);
if (!rv && c.runstop > 0)
- rv = Manage_run(devlist->devname, mdfd, c.verbose);
+ rv = Manage_run(devlist->devname, mdfd, &c);
if (!rv && c.runstop < 0)
rv = Manage_stop(devlist->devname, mdfd, c.verbose, 0);
break;
@@ -1535,7 +1535,7 @@ int main(int argc, char *argv[])
pr_err("--incremental --scan --fail not supported.\n");
break;
}
- rv = IncrementalScan(c.verbose, NULL);
+ rv = IncrementalScan(&c, NULL);
}
if (!devlist) {
if (!rebuild_map && !c.scan) {
@@ -1804,7 +1804,8 @@ static int misc_list(struct mddev_dev *devlist,
if (mdfd>=0) {
switch(dv->disposition) {
case 'R':
- rv |= Manage_run(dv->devname, mdfd, c->verbose); break;
+ c->runstop = 1;
+ rv |= Manage_run(dv->devname, mdfd, c); break;
case 'S':
rv |= Manage_stop(dv->devname, mdfd, c->verbose, 0); break;
case 'o':
diff --git a/mdadm.h b/mdadm.h
index 2eca603..c90fe10 100644
--- a/mdadm.h
+++ b/mdadm.h
@@ -1171,7 +1171,7 @@ struct stat64;
extern int add_dev(const char *name, const struct stat *stb, int flag, struct FTW *s);
extern int Manage_ro(char *devname, int fd, int readonly);
-extern int Manage_run(char *devname, int fd, int quiet);
+extern int Manage_run(char *devname, int fd, struct context *c);
extern int Manage_stop(char *devname, int fd, int quiet,
int will_retry);
extern int Manage_subdevs(char *devname, int fd,
@@ -1237,7 +1237,7 @@ extern int WaitClean(char *dev, int sock, int verbose);
extern int Incremental(char *devname, struct context *c,
struct supertype *st);
extern void RebuildMap(void);
-extern int IncrementalScan(int verbose, char *devnm);
+extern int IncrementalScan(struct context *c, char *devnm);
extern int IncrementalRemove(char *devname, char *path, int verbose);
extern int CreateBitmap(char *filename, int force, char uuid[16],
unsigned long chunksize, unsigned long daemon_sleep,
--
1.8.3.1.487.g3e7a5b4

View File

@ -1,43 +0,0 @@
From 7bb1d61354e4f8932f0a6eb926d5855b05c8c7b8 Mon Sep 17 00:00:00 2001
From: "mwilck@arcor.de" <mwilck@arcor.de>
Date: Sat, 14 Sep 2013 23:24:07 +0200
Subject: [PATCH] Monitor: don't set arrays dirty after transition to read-only
This patch reverts commit 4867e068. Setting arrays dirty after
transition from inactive to anything else causes unnecessary
meta data writes and may wreak trouble unnecessarily when
a disk was missing during assembly but the array was never
written to.
The reason for 4867e068 was a special situation during reshape
from RAID0 to RAID4. I ran all IMSM test cases with it reverted
and found no regressions, so I believe the reshape logic for
IMSM works fine in mdadm 3.3 also without this.
Signed-off-by: Martin Wilck <mwilck@arcor.de>
Signed-off-by: NeilBrown <neilb@suse.de>
---
monitor.c | 7 -------
1 file changed, 7 deletions(-)
diff --git a/monitor.c b/monitor.c
index 742aa196fb3b..3b57ed05ec9b 100644
--- a/monitor.c
+++ b/monitor.c
@@ -270,13 +270,6 @@ static int read_and_act(struct active_array *a)
a->info.resync_start
);
- if (a->curr_state > inactive &&
- a->prev_state == inactive) {
- /* array has been started
- * possible that container operation has to be completed
- */
- a->container->ss->set_array_state(a, 0);
- }
if ((a->curr_state == bad_word || a->curr_state <= inactive) &&
a->prev_state > inactive) {
/* array has been stopped */
--
1.8.3.1.487.g3e7a5b4

View File

@ -1,42 +0,0 @@
From a4921f30ec2ecc2d685573899cb86064b0cd78e9 Mon Sep 17 00:00:00 2001
From: "mwilck@arcor.de" <mwilck@arcor.de>
Date: Tue, 24 Sep 2013 20:53:18 +0200
Subject: [PATCH] Monitor: write meta data in readonly state, sometimes
This patch reverts 24a216bf:
"Monitor: Don't write metadata in inactive array state".
While it's true that writing meta data is usually not necessary
in readonly state, there is one important exception: if a
disk goes faulty, we want to record that, even if the array is
inactive.
We might as well just revert 24a216bf, because with the recently
submitted patch
"Monitor: don't set arrays dirty after transition to read-only"
those meta data writes that really annoying (for a clean, readonly,
healthy array during startup) are gone anyway.
Signed-off-by: Martin Wilck <mwilck@arcor.de>
Signed-off-by: NeilBrown <neilb@suse.de>
---
monitor.c | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/monitor.c b/monitor.c
index 3b57ed05ec9b..f81e707532f6 100644
--- a/monitor.c
+++ b/monitor.c
@@ -421,8 +421,7 @@ static int read_and_act(struct active_array *a)
if (sync_completed > a->last_checkpoint)
a->last_checkpoint = sync_completed;
- if (deactivate || a->curr_state >= clean)
- a->container->ss->sync_metadata(a->container);
+ a->container->ss->sync_metadata(a->container);
dprintf("%s(%d): state:%s action:%s next(", __func__, a->info.container_member,
array_states[a->curr_state], sync_actions[a->curr_action]);
--
1.8.3.1.487.g3e7a5b4

View File

@ -1,237 +0,0 @@
From c1736844ba49ec1a8731b5815abfd6530b982a3b Mon Sep 17 00:00:00 2001
From: NeilBrown <neilb@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 <neilb@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

View File

@ -1,29 +0,0 @@
From dbdf3f15e7ed9d5462a6ece09dd1c57ca430d912 Mon Sep 17 00:00:00 2001
From: NeilBrown <neilb@suse.de>
Date: Tue, 10 Sep 2013 17:10:10 +1000
Subject: [PATCH] config: set "auto_seen" after processing the auto line.
Otherwise when we process an empty autoline (to be sure to
capture the MDADM_CONF_AUTO environment variable) we can end up
setting everything to 'yes' which over-rides 'no'.
Signed-off-by: NeilBrown <neilb@suse.de>
---
config.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/config.c b/config.c
index f1a70c5..a35807c 100644
--- a/config.c
+++ b/config.c
@@ -575,6 +575,7 @@ void autoline(char *line)
if (auto_seen)
return;
+ auto_seen = 1;
/* Parse the 'auto' line creating policy statements for the 'auto' policy.
*
--
1.8.3.1.487.g3e7a5b4

3
mdadm-3.3.1.tar.xz Normal file
View File

@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:d8c74112cfd77bdc1dbc1291fe8d9243c76d91bfa276fcb95f2a75ca7717ab02
size 407964

View File

@ -1,3 +0,0 @@
version https://git-lfs.github.com/spec/v1
oid sha256:9c07e518bdf3392ebac8874eb686258e10ea3ae0ff7a8acb6d014718a9c3ed45
size 412431

View File

@ -1,3 +1,62 @@
-------------------------------------------------------------------
Thu Jun 12 02:08:31 UTC 2014 - nfbrown@suse.com
- mdadm.spec: change calling of mkinitrd to use the
%regenerate_initrd_{post,posttrans} macros to optimise
initrd regeneration. (bnc#881780)
-------------------------------------------------------------------
Tue Jun 10 04:05:48 UTC 2014 - nfbrown@suse.com
- new upstream release 3.3.1, incorporates all current patches
and includes assorted other minor fixes.
- 0001-Makefile-install-mdadm-grow-continue-.service.patch
make sure mdadm-grow-continue.service is installed properly.
- remove mkinitrd files, we now use dracut
- Delete 0001-Assemble-allow-load_devices-to-change-the-st-which-i.patch
- Delete 0001-DDF-mark-missing-on-assembly-device-properly.patch
- Delete 0001-mdmon-.service-Change-type-of-process-start-up-to-fo.patch
- Delete 0001-systemd-various-fixes-for-boot-with-container-arrays.patch
- Delete 0002-Assemble-re-arrange-freeing-of-tst-in-load_devices.patch
- Delete 0002-DDF-guard-against-pdnum-being-negative.patch
- Delete 0003-Assemble-change-load_devices-to-return-most_recent-s.patch
- Delete 0003-DDF-fix-possible-mdmon-crash-when-updating-metadata.patch
- Delete 0003-Work-around-architectures-having-statfs.f_type-defin.patch
- Delete 0004-DDF-Don-t-fail-compare_super_ddf-due-to-re-configure.patch
- Delete 0004-DDF-report-seq-counter-as-events.patch
- Delete 0005-DDF-when-first-activating-an-array-record-any-missin.patch
- Delete Assembe-fix-bug-in-force_array-it-wasn-t-forcing-pro.patch
- Delete Assemble-Incremental-don-t-hold-O_EXCL-on-mddev-afte.patch
- Delete Assemble-avoid-infinite-loop-when-auto-assembling-pa.patch
- Delete DDF-add_to_super_ddf-be-careful-with-workspace_lba.patch
- Delete DDF-allow-for-possibility-that-there-is-no-secondary.patch
- Delete DDF-brief_examine_subarrays_ddf-print-array-name.patch
- Delete DDF-compare_super_ddf-fix-sequence-number-check.patch
- Delete DDF-factor-out-array-name-generation.patch
- Delete DDF-fix-detection-of-failed-devices-during-assembly.patch
- Delete DDF-handle-fake-RAIDs-with-changing-subarray-UUIDs.patch
- Delete DDF-really-ignore-DDF-metadata-on-partitions.patch
- Delete Grow-fix-problems-with-prematurely-aborting-of-resha.patch
- Delete IMSM-don-t-crash-when-creating-an-array-with-missing.patch
- Delete Incremental-add-export-handling.patch
- Delete Incremental-improve-support-for-DEVICE-based-restric.patch
- Delete Make-IRs-and-run-work-properly-for-containers.patch
- Delete Monitor-don-t-set-arrays-dirty-after-transition-to-r.patch
- Delete Monitor-write-meta-data-in-readonly-state-sometimes.patch
- Delete Restructure-assemble_container_content-and-improve-m.patch
- Delete config-set-auto_seen-after-processing-the-auto-line.patch
- Delete mdmon-.service-remove-over-ride-of-Standard-IO.patch
- Delete mdmon-don-t-complain-about-notifying-parent-when-the.patch
- Delete mdmon-honour-offroot-again.patch
- Delete mdmonitor
- Delete policy-NULL-path-isn-t-really-acceptable-use-the-dev.patch
- Delete systemd-mdadm-last-resort@.service
- Delete systemd-mdadm-last-resort@.timer
- Delete systemd-mdmon-set-IMSM_NO_PLATFORM-1.patch
- Delete udev-rules-try-mdadm-I-on-change-events.patch
- Delete udev-rules.degraded
-------------------------------------------------------------------
Tue Apr 8 07:38:42 UTC 2014 - nfbrown@suse.com

View File

@ -17,7 +17,7 @@
Name: mdadm
Version: 3.3
Version: 3.3.1
Release: 0
BuildRequires: binutils-devel
BuildRequires: groff
@ -34,94 +34,12 @@ Summary: Utility for Configuring MD Setup
License: GPL-2.0
Group: System/Base
BuildRoot: %{_tmppath}/%{name}-%{version}-build
Source: https://www.kernel.org/pub/linux/utils/raid/mdadm/%{name}-%{version}.tar.bz2
Source: https://www.kernel.org/pub/linux/utils/raid/mdadm/%{name}-%{version}.tar.xz
Source1: Software-RAID.HOWTO.tar.bz2
Source2: sysconfig.mdadm
Source5: mkinitrd-setup.sh
Source6: mkinitrd-boot.sh
Source7: mdadm.cron
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 nfbrown@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 nfbrown@suse.de
Patch2: DDF-allow-for-possibility-that-there-is-no-secondary.patch
# PATCH-FIX-UPSTREAM Make-IRs-and-run-work-properly-for-containers.patch upstream-bugfix nfbrown@suse.de
Patch3: Make-IRs-and-run-work-properly-for-containers.patch
# PATCH-FIX-UPSTREAM mdmon-honour-offroot-again.patch upstream-bugfix nfbrown@suse.de
Patch4: mdmon-honour-offroot-again.patch
# PATCH-FIX-UPSTREAM DDF-brief_examine_subarrays_ddf-print-array-name.patch upstream-bugfix nfbrown@suse.de
Patch5: DDF-brief_examine_subarrays_ddf-print-array-name.patch
# PATCH-FIX-UPSTREAM DDF-factor-out-array-name-generation.patch upstream-bugfix nfbrown@suse.de
Patch6: DDF-factor-out-array-name-generation.patch
# PATCH-FIX-UPSTREAM DDF-handle-fake-RAIDs-with-changing-subarray-UUIDs.patch upstream-bugfix nfbrown@suse.de
Patch7: DDF-handle-fake-RAIDs-with-changing-subarray-UUIDs.patch
# PATCH-FIX-UPSTREAM DDF-compare_super_ddf-fix-sequence-number-check.patch upstream-bugfix nfbrown@suse.de
Patch8: DDF-compare_super_ddf-fix-sequence-number-check.patch
# PATCH-FIX-UPSTREAM Monitor-don-t-set-arrays-dirty-after-transition-to-r.patch upstream-bugfix nfbrown@suse.de
Patch9: Monitor-don-t-set-arrays-dirty-after-transition-to-r.patch
# PATCH-FIX-UPSTREAM DDF-add_to_super_ddf-be-careful-with-workspace_lba.patch upstream-bugfix nfbrown@suse.de
Patch10: DDF-add_to_super_ddf-be-careful-with-workspace_lba.patch
# PATCH-FIX-UPSTREAM Monitor-write-meta-data-in-readonly-state-sometimes.patch upstream-bugfix nfbrown@suse.de
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 nfbrown@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 nfbrown@suse.de
Patch13: Restructure-assemble_container_content-and-improve-m.patch
# PATCH-FEATURE-UPSTREAM Incremental-add-export-handling.patch bnc#832501 nfbrown@suse.de
Patch14: Incremental-add-export-handling.patch
# PATCH-FEATURE-UPSTREAM udev-rules.degraded bnc#832501 nfbrown@suse.de
Patch15: udev-rules.degraded
# PATCH-FEATURE-UPSTREAM Incremental-improve-support-for-DEVICE-based-restric.patch bnc#851993 nfbrown@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 nfbrown@suse.de
Patch17: Assemble-Incremental-don-t-hold-O_EXCL-on-mddev-afte.patch
# PATCH-FIX-UPSTREAM mdmonitor bnc#849523 nfbrown@suse.de
Patch18: mdmonitor
# PATCH-FIX-UPSTREAM udev-rules-try-mdadm-I-on-change-events.patch bnc#851993 nfbrown@suse.de
Patch19: udev-rules-try-mdadm-I-on-change-events.patch
# PATCH-FIX-UPSTREAM policy-NULL-path-isn-t-really-acceptable-use-the-dev.patch nfbrown@suse.de
Patch20: policy-NULL-path-isn-t-really-acceptable-use-the-dev.patch
# PATCH-FIX-UPSTREAM DDF-really-ignore-DDF-metadata-on-partitions.patch nfbrown@suse.de
Patch21: DDF-really-ignore-DDF-metadata-on-partitions.patch
# PATCH-FIX-UPSTREAM Assemble-avoid-infinite-loop-when-auto-assembling-pa.patch nfbrown@suse.de
Patch22: Assemble-avoid-infinite-loop-when-auto-assembling-pa.patch
# PATCH-FIX-UPSTREAM DDF-fix-detection-of-failed-devices-during-assembly.patch nfbrown@suse.de
Patch23: DDF-fix-detection-of-failed-devices-during-assembly.patch
# PATCH-FIX-UPSTREAM Grow-fix-problems-with-prematurely-aborting-of-resha.patch nfbrown@suse.de
Patch24: Grow-fix-problems-with-prematurely-aborting-of-resha.patch
# PATCH-FIX-UPSTREAM IMSM-don-t-crash-when-creating-an-array-with-missing.patch nfbrown@suse.de
Patch25: IMSM-don-t-crash-when-creating-an-array-with-missing.patch
# PATCH-FIX-UPSTREAM mdmon-don-t-complain-about-notifying-parent-when-the.patch nfbrown@suse.de
Patch26: mdmon-don-t-complain-about-notifying-parent-when-the.patch
# PATCH-FIX-UPSTREAM systemd-mdmon-set-IMSM_NO_PLATFORM-1.patch nfbrown@suse.de
Patch27: systemd-mdmon-set-IMSM_NO_PLATFORM-1.patch
# PATCH-FIX-UPSTREAM mdmon-.service-remove-over-ride-of-Standard-IO.patch nfbrown@suse.de
Patch28: mdmon-.service-remove-over-ride-of-Standard-IO.patch
# PATCH-FIX-UPSTREAM 0001-Assemble-allow-load_devices-to-change-the-st-which-i.patch bnc#865221 nfbrown@suse.de
Patch32: 0001-Assemble-allow-load_devices-to-change-the-st-which-i.patch
# PATCH-FIX-UPSTREAM 0002-Assemble-re-arrange-freeing-of-tst-in-load_devices.patch bnc#865221 nfbrown@suse.de
Patch33: 0002-Assemble-re-arrange-freeing-of-tst-in-load_devices.patch
# PATCH-FIX-UPSTREAM 0003-Assemble-change-load_devices-to-return-most_recent-s.patch bnc#865221 nfbrown@suse.de
Patch34: 0003-Assemble-change-load_devices-to-return-most_recent-s.patch
# PATCH-FIX-UPSTREAM 0001-mdmon-.service-Change-type-of-process-start-up-to-fo.patch nfbrown@suse.de
Patch35: 0001-mdmon-.service-Change-type-of-process-start-up-to-fo.patch
# PATCH-FIX-UPSTREAM 0003-Work-around-architectures-having-statfs.f_type-defin.patch nfbrown@suse.de
Patch36: 0003-Work-around-architectures-having-statfs.f_type-defin.patch
# PATCH-FIX-UPSTREAM 0004-DDF-report-seq-counter-as-events.patch bnc#866660 nfbrown@suse.de
Patch37: 0004-DDF-report-seq-counter-as-events.patch
# PATCH-FIX-UPSTREAM 0005-DDF-when-first-activating-an-array-record-any-missin.patch bnc#866660 nfbrown@suse.de
Patch38: 0005-DDF-when-first-activating-an-array-record-any-missin.patch
# PATCH-FIX-UPSTREAM 0001-DDF-mark-missing-on-assembly-device-properly.patch bnc#866660 nfbrown@suse.de
Patch39: 0001-DDF-mark-missing-on-assembly-device-properly.patch
# PATCH-FIX-UPSTREAM 0002-DDF-guard-against-pdnum-being-negative.patch bnc#866660 nfbrown@suse.de
Patch40: 0002-DDF-guard-against-pdnum-being-negative.patch
# PATCH-FIX-UPSTREAM 0003-DDF-fix-possible-mdmon-crash-when-updating-metadata.patch bnc#866660 nfbrown@suse.de
Patch41: 0003-DDF-fix-possible-mdmon-crash-when-updating-metadata.patch
# PATCH-FIX-UPSTREAM 0004-DDF-Don-t-fail-compare_super_ddf-due-to-re-configure.patch bnc#866660 nfbrown@suse.de
Patch42: 0004-DDF-Don-t-fail-compare_super_ddf-due-to-re-configure.patch
# PATCH-FIX-UPSTREAM 0001-systemd-various-fixes-for-boot-with-container-arrays.patch bnc#866660 nfbrown@suse.de
Patch43: 0001-systemd-various-fixes-for-boot-with-container-arrays.patch
# PATCH-FIX-UPSTREAM 0001-Makefile-install-mdadm-grow-continue-.service.patch nfbrown@suse.de
Patch1: 0001-Makefile-install-mdadm-grow-continue-.service.patch
%define _udevdir %(pkg-config --variable=udevdir udev)
%define _systemdshutdowndir %{_unitdir}/../system-shutdown
@ -134,45 +52,6 @@ programs but with a very different interface.
%prep
%setup -q -a1
%patch1 -p1
%patch2 -p1
%patch3 -p1
%patch4 -p1
%patch5 -p1
%patch6 -p1
%patch7 -p1
%patch8 -p1
%patch9 -p1
%patch10 -p1
%patch11 -p1
%patch12 -p1
%patch13 -p1
%patch14 -p1
%patch15 -p1
%patch16 -p1
%patch17 -p1
%patch18 -p1
%patch19 -p1
%patch20 -p1
%patch21 -p1
%patch22 -p1
%patch23 -p1
%patch24 -p1
%patch25 -p1
%patch26 -p1
%patch27 -p1
%patch28 -p1
%patch32 -p1
%patch33 -p1
%patch34 -p1
%patch35 -p1
%patch36 -p1
%patch37 -p1
%patch38 -p1
%patch39 -p1
%patch40 -p1
%patch41 -p1
%patch42 -p1
%patch43 -p1
%build
make %{?_smp_mflags} CC="%__cc" CXFLAGS="$RPM_OPT_FLAGS -Wno-error" SUSE=yes
@ -185,39 +64,21 @@ make install install-systemd install-udev DESTDIR=%{buildroot} SYSTEMD_DIR=%{_un
rm -rf %{buildroot}/lib/udev
install -d %{buildroot}%{_var}/adm/fillup-templates
install -d %{buildroot}{%{_sbindir}
install -d %{buildroot}/lib/mkinitrd/scripts
install -m 755 %{S:5} %{buildroot}/lib/mkinitrd/scripts/setup-md.sh
install -m 755 %{S:6} %{buildroot}/lib/mkinitrd/scripts/boot-md.sh
install -d %{buildroot}/etc/cron.daily
install -m 755 %{S:7} %{buildroot}/etc/cron.daily/mdadm
install -m 644 %{S:2} %{buildroot}%{_var}/adm/fillup-templates/
install -d %{buildroot}%{_systemdshutdowndir}
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
if [ -e /var/lib/no_initrd_recreation_by_suspend ]; then
echo "Skipping recreation of existing initial ramdisks, due"
echo "to presence of /var/lib/no_initrd_recreation_by_suspend"
elif [ -x /sbin/mkinitrd ]; then
/sbin/mkinitrd
fi
%{?regenerate_initrd_post}
%fillup_only
%postun
[ -x /sbin/mkinitrd_setup ] && mkinitrd_setup
if [ -e /var/lib/no_initrd_recreation_by_suspend ]; then
echo "Skipping recreation of existing initial ramdisks, due"
echo "to presence of /var/lib/no_initrd_recreation_by_suspend"
elif [ -x /sbin/mkinitrd ]; then
/sbin/mkinitrd
fi
%{?regenerate_initrd_post}
%{insserv_cleanup}
%preun
%posttrans
%{?regenerate_initrd_posttrans}
%clean
rm -rf %{buildroot}
@ -229,10 +90,6 @@ rm -rf %{buildroot}
%doc %{_mandir}/man?/*
/sbin/*
%{_var}/adm/fillup-templates/sysconfig.mdadm
%dir /lib/mkinitrd
%dir /lib/mkinitrd/scripts
/lib/mkinitrd/scripts/setup-md.sh
/lib/mkinitrd/scripts/boot-md.sh
%{_udevdir}/rules.d/63-md-raid-arrays.rules
%{_udevdir}/rules.d/64-md-raid-assembly.rules
%dir /etc/cron.daily
@ -242,6 +99,7 @@ rm -rf %{buildroot}
%{_unitdir}/mdmonitor.service
%{_unitdir}/mdadm-last-resort@.timer
%{_unitdir}/mdadm-last-resort@.service
%{_unitdir}/mdadm-grow-continue@.service
%dir %{_unitdir}/../scripts
%{_unitdir}/../scripts/mdadm_env.sh

View File

@ -1,24 +0,0 @@
From 1f6b069494c1ecf8014a76fb10e8c8f5f6c27365 Mon Sep 17 00:00:00 2001
From: NeilBrown <neilb@suse.de>
Date: Wed, 22 Jan 2014 12:53:31 +1100
Subject: [PATCH 13/13] mdmon@.service: remove over-ride of Standard IO.
Redirecting output to /dev/null is unnecessary and hides any error
messages there might be. So leave as defaults which are none,
journal, inherit.
Signed-off-by: NeilBrown <neilb@suse.de>
---
systemd/mdmon@.service | 3 ---
1 file changed, 3 deletions(-)
--- mdadm-3.3.orig/systemd/mdmon@.service
+++ mdadm-3.3/systemd/mdmon@.service
@@ -15,7 +15,4 @@ Before=initrd-switch-root.target
# that is mdadm's job if at all.
Environment=IMSM_NO_PLATFORM=1
ExecStart=/sbin/mdmon --foreground %I
-StandardInput=null
-StandardOutput=null
-StandardError=null
KillMode=none

View File

@ -1,43 +0,0 @@
From 5e57245e3feba65385fc100e0f2c3d1214d79915 Mon Sep 17 00:00:00 2001
From: NeilBrown <neilb@suse.de>
Date: Tue, 21 Jan 2014 09:43:31 +1100
Subject: [PATCH 11/13] mdmon: don't complain about notifying parent when there
is no need
When run with --foreground mdmon has no need to notify any
parent, so it shouldn't even try, let alone complain when it fails.
Also close an end of a pipe which is no longer used.
Signed-off-by: NeilBrown <neilb@suse.de>
---
mdmon.c | 11 +++++++----
1 file changed, 7 insertions(+), 4 deletions(-)
--- mdadm-3.3.orig/mdmon.c
+++ mdadm-3.3/mdmon.c
@@ -429,6 +429,7 @@ static int mdmon(char *devnm, int must_f
wait(&status);
status = WEXITSTATUS(status);
}
+ close(pfd[0]);
return status;
}
} else
@@ -516,10 +517,12 @@ static int mdmon(char *devnm, int must_f
container->sock = make_control_sock(devnm);
status = 0;
- if (write(pfd[1], &status, sizeof(status)) < 0)
- pr_err("failed to notify our parent: %d\n",
- getppid());
- close(pfd[1]);
+ if (pfd[1] >= 0) {
+ if (write(pfd[1], &status, sizeof(status)) < 0)
+ pr_err("failed to notify our parent: %d\n",
+ getppid());
+ close(pfd[1]);
+ }
mlockall(MCL_CURRENT | MCL_FUTURE);

View File

@ -1,40 +0,0 @@
From 5d79c72e16b32d7d6d0f535348286a7f2a966092 Mon Sep 17 00:00:00 2001
From: "mwilck@arcor.de" <mwilck@arcor.de>
Date: Wed, 11 Sep 2013 22:15:19 +0200
Subject: [PATCH] mdmon: honour --offroot, again
commit 3e32ba9d removed support for --offroot, and a9c15847 made
mdmon use @ in argv[0] only when started from initrd.
This breaks mdadm in OpenSUSE 12.3, which starts mdmon from the
root file system and relies on --offroot to work as documented earlier.
Reintroducing --offroot as an undocumented option, as its use is going to
go away soon anyway.
If this can't be applied, it should probably be included as distro-specific
patch if mdadm 3.3 is built for OpenSUSE 12.3. I haven't checked if the
patch is necesary for OpenSUSE Factory, too.
Signed-off-by: Martin Wilck <mwilck@arcor.de>
Signed-off-by: NeilBrown <neilb@suse.de>
---
mdmon.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/mdmon.c b/mdmon.c
index f0b0623..8cd53d8 100644
--- a/mdmon.c
+++ b/mdmon.c
@@ -320,7 +320,7 @@ int main(int argc, char *argv[])
dofork = 0;
break;
case OffRootOpt:
- /* silently ignore old option */
+ argv[0][0] = '@';
break;
case 'h':
default:
--
1.8.3.1.487.g3e7a5b4

117
mdmonitor
View File

@ -1,117 +0,0 @@
From 61c094715836e76b66d7a69adcb6769127b5b77d Mon Sep 17 00:00:00 2001
From: NeilBrown <neilb@suse.de>
Date: Wed, 11 Dec 2013 10:47:54 +1100
Subject: [PATCH] Add mdmonitor.service systemd unit file.
References: bnc#849523
This systemd unit file runs mdadm in --monitor mode.
It is started by a SYSTEMD_WANTS signal from udev whenever
an md array is started that would benefit from mdadm --monitor.
Commandline arguments can be provided by a script
/usr/lib/systemd/scripts/mdadm_env.sh
which should write an
MDADM_MONITOR_ARGS=....
line to /run/sysconfig/mdadm
A script to extra args from SUSE's /etc/sysconfig/mdadm file
is provided.
If no mdadm_env.sh is provided, then args are "--scan" which
requires "mail" or "program" to be set in /etc/mdadm.conf.
I believe this is suitable for Fedora.
Signed-off-by: NeilBrown <neilb@suse.de>
---
Makefile | 2 ++
systemd/SUSE-mdadm_env.sh | 45 +++++++++++++++++++++++++++++++++++++++++++++
systemd/mdmonitor.service | 16 ++++++++++++++++
udev-md-raid-arrays.rules | 2 ++
4 files changed, 65 insertions(+)
--- mdadm-3.3.orig/Makefile
+++ mdadm-3.3/Makefile
@@ -285,6 +285,8 @@ install-udev: udev-md-raid-arrays.rules
install-systemd: systemd/mdmon@.service
$(INSTALL) -D -m 644 systemd/mdmon@.service $(DESTDIR)$(SYSTEMD_DIR)/mdmon@.service
+ $(INSTALL) -D -m 644 systemd/mdmonitor.service $(DESTDIR)$(SYSTEMD_DIR)/mdmonitor.service
+ [ -f /etc/SuSE-release -o -n "$(SUSE)" ] && $(INSTALL) -D -m 755 systemd/SUSE-mdadm_env.sh $(DESTDIR)$(SYSTEMD_DIR)/../scripts/mdadm_env.sh || true
uninstall:
rm -f $(DESTDIR)$(MAN8DIR)/mdadm.8 $(DESTDIR)$(MAN8DIR)/mdmon.8 $(DESTDIR)$(MAN4DIR)/md.4 $(DESTDIR)$(MAN5DIR)/mdadm.conf.5 $(DESTDIR)$(BINDIR)/mdadm
--- /dev/null
+++ mdadm-3.3/systemd/SUSE-mdadm_env.sh
@@ -0,0 +1,45 @@
+#!/bin/sh
+
+# extract configuration from /etc/sysconfig/mdadm and write
+# environment to /run/sysconfig/mdadm to be used by
+# systemd unit files.
+
+MDADM_SCAN="yes"
+
+# Following adapted from /etc/init.d/mdadmd on openSUSE
+
+mdadmd_CONFIG=/etc/sysconfig/mdadm
+if test -r $mdadmd_CONFIG; then
+ . $mdadmd_CONFIG
+fi
+
+if [ x$MDADM_DELAY != x"" ]; then
+ MDADM_DELAY="-d "$MDADM_DELAY;
+fi
+
+if [ x$MDADM_MAIL != x"" ]; then
+ MDADM_MAIL="-m \"$MDADM_MAIL\""
+fi
+
+if [ x$MDADM_PROGRAM != x"" ]; then
+ MDADM_PROGRAM="-p \"$MDADM_PROGRAM\""
+fi
+
+if [ x$MDADM_SCAN = x"yes" ]; then
+ MDADM_SCAN="--scan"
+else
+ MDADM_SCAN=""
+fi
+
+if [ x$MDADM_SEND_MAIL_ON_START = x"yes" ]; then
+ MDADM_SEND_MAIL="-t"
+else
+ MDADM_SEND_MAIL=""
+fi
+
+if [ x$MDADM_CONFIG != x"" ]; then
+ MDADM_CONFIG="-c \"$MDADM_CONFIG\""
+fi
+
+mkdir -p /run/sysconfig
+echo "MDADM_MONITOR_ARGS=$MDADM_RAIDDEVICES $MDADM_DELAY $MDADM_MAIL $MDADM_PROGRAM $MDADM_SCAN $MDADM_SEND_MAIL $MDADM_CONFIG" > /run/sysconfig/mdadm
--- /dev/null
+++ mdadm-3.3/systemd/mdmonitor.service
@@ -0,0 +1,16 @@
+# This file is part of mdadm.
+#
+# mdadm is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+
+[Unit]
+Description=MD array monitor
+DefaultDependencies=no
+
+[Service]
+Environment= MDADM_MONITOR_ARGS=--scan
+EnvironmentFile=-/run/sysconfig/mdadm
+ExecStartPre=-/usr/lib/systemd/scripts/mdadm_env.sh
+ExecStart=/sbin/mdadm --monitor $MDADM_MONITOR_ARGS
--- mdadm-3.3.orig/udev-md-raid-arrays.rules
+++ mdadm-3.3/udev-md-raid-arrays.rules
@@ -32,4 +32,6 @@ OPTIONS+="watch"
ENV{ID_FS_USAGE}=="filesystem|other|crypto", ENV{ID_FS_UUID_ENC}=="?*", SYMLINK+="disk/by-uuid/$env{ID_FS_UUID_ENC}"
ENV{ID_FS_USAGE}=="filesystem|other", ENV{ID_FS_LABEL_ENC}=="?*", SYMLINK+="disk/by-label/$env{ID_FS_LABEL_ENC}"
+ENV{MD_LEVEL}=="raid[1-9]*", ENV{SYSTEMD_WANTS}+="mdmonitor.service"
+
LABEL="md_end"

View File

@ -1,32 +0,0 @@
#!/bin/bash
#%stage: boot
#%depends: start
#%programs: /sbin/mdadm /sbin/mdmon
#%modules: raid0 raid1 raid10 raid456
#%if: -n "$need_mdadm"
#
##### MD (Software-)Raid
##
## This only sets the 'start_ro' module parameter to ensure
## arrays don't start resync until after the first write.
## All array assembly is performed by udev -> "mdadm -I"
##
## Command line parameters
## -----------------------
##
## need_mdadm=1 use MD raid
##
# load the necessary module before we initialize the raid system
load_modules
#check_for_device uses $md_major
#we depend on 'start' to ensure /proc/devices exists
md_major=$(sed -ne 's/\s*\([0-9]\+\)\s*md$/\1/p' /proc/devices)
# Always start md devices read/only. They will get set to rw as soon
# as the first write occurs. This way we can guarantee that no
# restore occurs before resume.
if [ -f /sys/module/md_mod/parameters/start_ro ]; then
echo 1 > /sys/module/md_mod/parameters/start_ro
fi

View File

@ -1,120 +0,0 @@
#!/bin/bash
#
#%stage: softraid
#
mdblockdev=
# Full mdadm.conf generated by mdadm.
# Contains all created MD RAIDs
mdadm_conf=
cont_list=
md_devs=
declare -A md_conf
# blockdev contains real devices (/dev/X) for root, resume, journal, dumb
for bd in $blockdev ; do
is_part_dev=false
case $bd in
/dev/md[_0-9]*p[0-9]* )
# Partitionable MD RAID. This is partition on RAID. Get the RAID
bd=${bd%%p[0-9]*}
is_part_dev=true
;;
/dev/md[0-9_]*)
;;
*)
mdblockdev="$mdblockdev $bd"
continue
;;
esac
# Check if this device is already added (possible for partitionable).
md_dev=`mdadm -D --export $bd | sed -n -e 's/^MD_DEVNAME=//p'`
if [ -z "$md_dev" ]; then
md_dev=${bd##/dev/}
else
bd="/dev/md/$md_dev"
fi
dup_found=false
for dup in $md_devs; do
if [ x"$dup" = x"$md_dev" ]; then
dup_found=true
break
fi
done
if $dup_found; then
if ! $is_part_dev; then
echo "setup-md.sh: $md_dev found multiple times" >&2
fi
continue
fi
mdconf=$(mdadm -Db "$bd")
if test -z "$mdconf"; then
mdblockdev="$mdblockdev $bd"
continue
fi
md_tmpblockdev=$(mdadm -Dbv $bd | sed -n "1D;s/,/ /g;s/^ *devices=//p")
mdblockdev="$mdblockdev $md_tmpblockdev"
md_devs="$md_devs $md_dev"
container=$(echo "$mdconf" | sed -rn 's/.* container=([^ ]*) .*/\1/p')
for cnt in $cont_list; do
if [ x"$container" = x"$cnt" ]; then
container=
break
fi
done
case "$container" in
"")
;;
/dev/*)
mdconf="$(mdadm -Db "$container")\\n$mdconf"
cont_list="$cont_list $container"
;;
[0-9a-f]*[0-9a-f])
if test -z "$mdadm_conf"; then
mdadm_conf=$(mdadm --examine --brief --scan)
fi
mdconf="$(echo "$mdadm_conf" | grep "UUID=$container")\\n$mdconf"
cont_list="$cont_list $container"
;;
*)
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
# Any 'md' device is replaced by it's component disks.
blockdev="$mdblockdev"
if [ -n "$root_md" ] ; then
need_mdadm=1
echo "AUTO -all" > $tmp_mnt/etc/mdadm.conf
for md in $md_devs; do
echo -e "${md_conf["$md"]}" >> $tmp_mnt/etc/mdadm.conf
done
fi
if [ "x$need_mdadm" = "x1" ] ; then
for rule in \
63-md-raid-arrays.rules \
64-md-raid-assembly.rules; do
if [ -f /usr/lib/udev/rules.d/$rule ]; then
cp /usr/lib/udev/rules.d/$rule $tmp_mnt/usr/lib/udev/rules.d
elif [ -f /lib/udev/rules.d/$rule ]; then
cp /lib/udev/rules.d/$rule $tmp_mnt/lib/udev/rules.d
fi
done
fi
save_var need_mdadm

View File

@ -1,64 +0,0 @@
From 75a721fd7d5e5ee7e578571fe58755fe07e446fc Mon Sep 17 00:00:00 2001
From: Lukasz Dorau <lukasz.dorau@intel.com>
Date: Thu, 19 Dec 2013 13:02:12 +0100
Subject: [PATCH 05/13] policy: NULL path isn't really acceptable - use the
devname
According to:
commit b451aa4846c5ccca5447a6b6d45e5623b8c8e961
Fix handling for "auto" line in mdadm.conf
a NULL path isn't really acceptable and the devname should be used instead.
Signed-off-by: Lukasz Dorau <lukasz.dorau@intel.com>
Signed-off-by: NeilBrown <neilb@suse.de>
---
policy.c | 35 +++++++++++++++++------------------
1 file changed, 17 insertions(+), 18 deletions(-)
--- mdadm-3.3.orig/policy.c
+++ mdadm-3.3/policy.c
@@ -200,26 +200,25 @@ static char *disk_path(struct mdinfo *di
int rv;
by_path = opendir(symlink);
- if (!by_path)
- return NULL;
- prefix_len = strlen(symlink);
-
- while ((ent = readdir(by_path)) != NULL) {
- if (ent->d_type != DT_LNK)
- continue;
- strncpy(symlink + prefix_len,
- ent->d_name,
- sizeof(symlink) - prefix_len);
- if (stat(symlink, &stb) < 0)
- continue;
- if ((stb.st_mode & S_IFMT) != S_IFBLK)
- continue;
- if (stb.st_rdev != makedev(disk->disk.major, disk->disk.minor))
- continue;
+ if (by_path) {
+ prefix_len = strlen(symlink);
+ while ((ent = readdir(by_path)) != NULL) {
+ if (ent->d_type != DT_LNK)
+ continue;
+ strncpy(symlink + prefix_len,
+ ent->d_name,
+ sizeof(symlink) - prefix_len);
+ if (stat(symlink, &stb) < 0)
+ continue;
+ if ((stb.st_mode & S_IFMT) != S_IFBLK)
+ continue;
+ if (stb.st_rdev != makedev(disk->disk.major, disk->disk.minor))
+ continue;
+ closedir(by_path);
+ return xstrdup(ent->d_name);
+ }
closedir(by_path);
- return xstrdup(ent->d_name);
}
- closedir(by_path);
/* A NULL path isn't really acceptable - use the devname.. */
sprintf(symlink, "/sys/dev/block/%d:%d", disk->disk.major, disk->disk.minor);
rv = readlink(symlink, nm, sizeof(nm)-1);

View File

@ -1,7 +0,0 @@
[Unit]
Description=Activate md array even though degraded
DefaultDependencies=no
[Service]
Type=oneshot
ExecStart=/sbin/mdadm --run /dev/%i

View File

@ -1,7 +0,0 @@
[Unit]
Description=Timer to wait for more drives before activating degraded array.
DefaultDependencies=no
Conflicts=sys-devices-virtual-block-%i.device
[Timer]
OnActiveSec=30

View File

@ -1,28 +0,0 @@
From 67ee238316785481a8ad440e531cae6c4dce36a4 Mon Sep 17 00:00:00 2001
From: NeilBrown <neilb@suse.de>
Date: Tue, 21 Jan 2014 09:46:07 +1100
Subject: [PATCH 12/13] systemd/mdmon: set IMSM_NO_PLATFORM=1
As mdmon doesn't inherit environment from mdadm when it is started
by system, it cannot inherit IMSM_NO_PLATFORM.
But if an imsm array as assembled then mdmon really should handle it
whether there is a platform present or not.
So always set this var.
Signed-off-by: NeilBrown <neilb@suse.de>
---
systemd/mdmon@.service | 3 +++
1 file changed, 3 insertions(+)
--- mdadm-3.3.orig/systemd/mdmon@.service
+++ mdadm-3.3/systemd/mdmon@.service
@@ -11,6 +11,9 @@ DefaultDependencies=no
Before=initrd-switch-root.target
[Service]
+# mdmon should never complain due to lack of a platform,
+# that is mdadm's job if at all.
+Environment=IMSM_NO_PLATFORM=1
ExecStart=/sbin/mdmon --foreground %I
StandardInput=null
StandardOutput=null

View File

@ -1,32 +0,0 @@
From 25392f5fc59f96fb766ecb5617d5276f8c87d489 Mon Sep 17 00:00:00 2001
From: NeilBrown <neilb@suse.de>
Date: Wed, 11 Dec 2013 12:29:22 +1100
Subject: [PATCH 02/13] udev rules: try "mdadm -I" on "change" events.
References: bnc#851993
We need to attempt "mdadm -I" on "change" events as well as "add" events,
as the "change" make make a device ready to be part of an array.
This is particularly important for stacked md devices. When the
member devices are "add"ed they don't have any content visible yet.
That doesn't happen until a "change".
Idea taken from Fedora udev file.
Signed-off-by: NeilBrown <neilb@suse.de>
---
udev-md-raid-assembly.rules | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
--- mdadm-3.3.orig/udev-md-raid-assembly.rules
+++ mdadm-3.3/udev-md-raid-assembly.rules
@@ -12,8 +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", 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=="add|change", IMPORT{program}="/sbin/mdadm --incremental --export $devnode --offroot ${DEVLINKS}"
+ACTION=="add|change", 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"

View File

@ -1,16 +0,0 @@
---
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"