forked from pool/mdadm
- new upstream release 3.3.1, incorporates all current patches
and includes assorted other minor fixes. - 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 OBS-URL: https://build.opensuse.org/package/show/Base:System/mdadm?expand=0&rev=108
This commit is contained in:
parent
19460dbde5
commit
50a71fa70b
@ -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)
|
@ -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))
|
@ -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
|
||||
|
@ -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"
|
@ -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 */
|
@ -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);
|
@ -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);
|
@ -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),
|
@ -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)
|
@ -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,
|
@ -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,
|
@ -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))
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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);
|
@ -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
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
@ -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 ||
|
@ -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;
|
@ -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;
|
@ -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);
|
@ -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;
|
||||
|
@ -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);
|
@ -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);
|
@ -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,
|
@ -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"
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
3
mdadm-3.3.1.tar.xz
Normal file
@ -0,0 +1,3 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:d8c74112cfd77bdc1dbc1291fe8d9243c76d91bfa276fcb95f2a75ca7717ab02
|
||||
size 407964
|
@ -1,3 +0,0 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:9c07e518bdf3392ebac8874eb686258e10ea3ae0ff7a8acb6d014718a9c3ed45
|
||||
size 412431
|
@ -1,3 +1,52 @@
|
||||
-------------------------------------------------------------------
|
||||
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.
|
||||
|
||||
- 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
|
||||
|
||||
|
128
mdadm.spec
128
mdadm.spec
@ -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
|
||||
|
||||
%define _udevdir %(pkg-config --variable=udevdir udev)
|
||||
%define _systemdshutdowndir %{_unitdir}/../system-shutdown
|
||||
@ -133,46 +51,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
|
||||
@ -192,8 +70,6 @@ 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
|
||||
|
@ -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
|
@ -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);
|
||||
|
@ -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
117
mdmonitor
@ -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"
|
@ -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);
|
@ -1,7 +0,0 @@
|
||||
[Unit]
|
||||
Description=Activate md array even though degraded
|
||||
DefaultDependencies=no
|
||||
|
||||
[Service]
|
||||
Type=oneshot
|
||||
ExecStart=/sbin/mdadm --run /dev/%i
|
@ -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
|
@ -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
|
@ -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"
|
||||
|
@ -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"
|
||||
|
Loading…
Reference in New Issue
Block a user