- 0001-DDF-mark-missing-on-assembly-device-properly.patch

- 0002-DDF-guard-against-pdnum-being-negative.patch
- 0003-DDF-fix-possible-mdmon-crash-when-updating-metadata.patch
- 0004-DDF-Don-t-fail-compare_super_ddf-due-to-re-configure.patch
  More upstream DDF fixes (bnc#866660)

- 0001-mdmon-.service-Change-type-of-process-start-up-to-fo.patch
- 0003-Work-around-architectures-having-statfs.f_type-defin.patch
- 0004-DDF-report-seq-counter-as-events.patch
- 0005-DDF-when-first-activating-an-array-record-any-missin.patch
  Two fixes for DDF (bnc#866660) and a couple of other upstream fixes
  just for good measure.

- 0001-Assemble-allow-load_devices-to-change-the-st-which-i.patch
  0002-Assemble-re-arrange-freeing-of-tst-in-load_devices.patch
  0003-Assemble-change-load_devices-to-return-most_recent-s.patch
  Allow RAID5 to be assembled even when firs device listed recently
  failed (bnc#865221)

OBS-URL: https://build.opensuse.org/package/show/Base:System/mdadm?expand=0&rev=105
This commit is contained in:
Neil Brown 2014-04-02 06:19:16 +00:00 committed by Git OBS Bridge
parent 8983119084
commit aca7a2aa5a
13 changed files with 747 additions and 0 deletions

View File

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

@ -0,0 +1,75 @@
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,42 @@
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

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

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

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

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

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

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

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

@ -0,0 +1,65 @@
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,3 +1,31 @@
-------------------------------------------------------------------
Wed Apr 2 04:41:53 UTC 2014 - nfbrown@suse.com
- 0001-DDF-mark-missing-on-assembly-device-properly.patch
- 0002-DDF-guard-against-pdnum-being-negative.patch
- 0003-DDF-fix-possible-mdmon-crash-when-updating-metadata.patch
- 0004-DDF-Don-t-fail-compare_super_ddf-due-to-re-configure.patch
More upstream DDF fixes (bnc#866660)
-------------------------------------------------------------------
Wed Mar 26 04:00:51 UTC 2014 - nfbrown@suse.com
- 0001-mdmon-.service-Change-type-of-process-start-up-to-fo.patch
- 0003-Work-around-architectures-having-statfs.f_type-defin.patch
- 0004-DDF-report-seq-counter-as-events.patch
- 0005-DDF-when-first-activating-an-array-record-any-missin.patch
Two fixes for DDF (bnc#866660) and a couple of other upstream fixes
just for good measure.
-------------------------------------------------------------------
Tue Mar 4 22:48:20 UTC 2014 - nfbrown@suse.com
- 0001-Assemble-allow-load_devices-to-change-the-st-which-i.patch
0002-Assemble-re-arrange-freeing-of-tst-in-load_devices.patch
0003-Assemble-change-load_devices-to-return-most_recent-s.patch
Allow RAID5 to be assembled even when firs device listed recently
failed (bnc#865221)
-------------------------------------------------------------------
Wed Jan 22 23:45:34 UTC 2014 - nfbrown@suse.com

View File

@ -99,6 +99,28 @@ Patch26: mdmon-don-t-complain-about-notifying-parent-when-the.patch
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
%define _udevdir %(pkg-config --variable=udevdir udev)
%define _systemdshutdowndir %{_unitdir}/../system-shutdown
@ -138,6 +160,17 @@ programs but with a very different interface.
%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
%build
make %{?_smp_mflags} CC="%__cc" CXFLAGS="$RPM_OPT_FLAGS -Wno-error" SUSE=yes