Accepting request 206456 from Base:System

Bug fixes for mdadm and a new minor feature for FATE#316007

- DDF-handle-fake-RAIDs-with-changing-subarray-UUIDs.patch
- DDF-compare_super_ddf-fix-sequence-number-check.patch
- Monitor-don-t-set-arrays-dirty-after-transition-to-r.patch
- DDF-add_to_super_ddf-be-careful-with-workspace_lba.patch
- Monitor-write-meta-data-in-readonly-state-sometimes.patch
- Assembe-fix-bug-in-force_array-it-wasn-t-forcing-pro.patch
  Various bugfixes from upstream - several to improve
  DDF support, one which fixes a nasty bug in "--assemble --force".

- DDF-brief_examine_subarrays_ddf-print-array-name.patch
  DDF-factor-out-array-name-generation.patch
  Include name in "-Db" output for DDF
  FATE#316007

OBS-URL: https://build.opensuse.org/request/show/206456
OBS-URL: https://build.opensuse.org/package/show/openSUSE:Factory/mdadm?expand=0&rev=87
This commit is contained in:
Stephan Kulow 2013-11-12 08:51:53 +00:00 committed by Git OBS Bridge
commit e5f146b89b
10 changed files with 510 additions and 0 deletions

View File

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

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

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

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

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

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

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

@ -0,0 +1,42 @@
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,3 +1,24 @@
-------------------------------------------------------------------
Mon Nov 11 00:45:03 UTC 2013 - nfbrown@suse.com
- DDF-handle-fake-RAIDs-with-changing-subarray-UUIDs.patch
- DDF-compare_super_ddf-fix-sequence-number-check.patch
- Monitor-don-t-set-arrays-dirty-after-transition-to-r.patch
- DDF-add_to_super_ddf-be-careful-with-workspace_lba.patch
- Monitor-write-meta-data-in-readonly-state-sometimes.patch
- Assembe-fix-bug-in-force_array-it-wasn-t-forcing-pro.patch
Various bugfixes from upstream - several to improve
DDF support, one which fixes a nasty bug in "--assemble --force".
-------------------------------------------------------------------
Wed Nov 6 05:31:54 UTC 2013 - nfbrown@suse.com
- DDF-brief_examine_subarrays_ddf-print-array-name.patch
DDF-factor-out-array-name-generation.patch
Include name in "-Db" output for DDF
FATE#316007
-------------------------------------------------------------------
Fri Sep 13 01:46:00 UTC 2013 - nfbrown@suse.com

View File

@ -51,6 +51,22 @@ Patch2: DDF-allow-for-possibility-that-there-is-no-secondary.patch
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
%define _udevdir %(pkg-config --variable=udevdir udev)
%define _systemdshutdowndir %{_unitdir}/../system-shutdown
@ -66,6 +82,14 @@ programs but with a very different interface.
%patch2 -p1
%patch3 -p1
%patch4 -p1
%patch5 -p1
%patch6 -p1
%patch7 -p1
%patch8 -p1
%patch9 -p1
%patch10 -p1
%patch11 -p1
%patch12 -p1
%build
make %{?_smp_mflags} CC="%__cc" CXFLAGS="$RPM_OPT_FLAGS -Wno-error"