Browse Source

mdadm package update

Signed-off-by: basebuilder_pel7ppc64bebuilder0 <basebuilder@powerel.org>
master
basebuilder_pel7ppc64bebuilder0 6 years ago
parent
commit
2e2b04d23c
  1. 136
      SOURCES/Add-force-flag1-to-hot_remove_disk.patch
  2. 172
      SOURCES/Add-sector-size-as-spare-selection-criterion.patch
  3. 334
      SOURCES/Allow-more-spare-selection-criteria.patch
  4. 31
      SOURCES/Assemble-Assemble-Get-rid-of-last-use-of-md_get-vers.patch
  5. 31
      SOURCES/Assemble-Assemble-Stop-checking-kernel-md-driver-ver.patch
  6. 249
      SOURCES/Assemble-Clean1-up-start_array.patch
  7. 34
      SOURCES/Assemble-Remove-obsolete-test-for-kernels1-older-than.patch
  8. 38
      SOURCES/Avoid-to-take-spare-without-defined-domain-by-imsm.patch
  9. 266
      SOURCES/Build2-Stop-bothering-about-supporting-md-driver-olde.patch
  10. 39
      SOURCES/Correct-examine-output-for-4kdisks.patch
  11. 76
      SOURCES/Create-Fixup-bad-placement-of-logical-in-multi-line-.patch
  12. 167
      SOURCES/Create-Fixup-various-whitespace-issues1.patch
  13. 88
      SOURCES/Create-Remove-all-attemps-to-handle-md-driver-older-.patch
  14. 311
      SOURCES/Create-tell-udev-md-device-is-not-ready-when-first-c.patch
  15. 38
      SOURCES/Detail-Fixup-ugly-if-foo-abuse.patch
  16. 37
      SOURCES/Detail-Reinstate-support-for-not-having-sysfs.patch
  17. 61
      SOURCES/Detail-Remove-pre-2.6-code-for-printing-info-on-rebu.patch
  18. 521
      SOURCES/Detail-Respect-code-lines-are-80-character-wide.patch
  19. 78
      SOURCES/Detail-Stop-bothering1-about-md-drivers-older-than-0..patch
  20. 111
      SOURCES/Detail-correct-outputfor-active-arrays.patch
  21. 54
      SOURCES/Detail-determine2-array-state-from-sysfs.patch
  22. 89
      SOURCES/Detail-differentiate-between-container-and-inactive-.patch
  23. 76
      SOURCES/Detail-don-t-exit-if-ioctl-has-been-successful.patch
  24. 69
      SOURCES/Detail-ensure-export-names-are-acceptable-as-shell-v.patch
  25. 45
      SOURCES/Detail-handle-non-existent-arrays-better.patch
  26. 106
      SOURCES/Don-t-abort-starting-the-array-if-kernel-does-not-su.patch
  27. 122
      SOURCES/Don-t-use-UnSet-with-consistency_policy.patch
  28. 31
      SOURCES/Don-t-use-exit-ERANGE.patch
  29. 91
      SOURCES/Error-messages-should-end-with-a-newline-character.patch
  30. 44
      SOURCES/Fix-oddity-where-mdadm-did-not-recognise-a-relative-.patch
  31. 45
      SOURCES/Fix-typo2-in-new-udev-rule.patch
  32. 163
      SOURCES/Get-failed-disk-count-fromarray-state.patch
  33. 41
      SOURCES/Grow-Do-not-shadow-an-existing-variable.patch
  34. 176
      SOURCES/Grow-Fixup-a-pile-of-cosmetic-issues.patch
  35. 41
      SOURCES/Grow-Grow_continue_command-Avoid-aliasing-array-vari.patch
  36. 51
      SOURCES/Grow-Remove-unnecessary-optimization.patch
  37. 35
      SOURCES/Grow-Stop-bothering-about-md-driver-versions-older-t.patch
  38. 34
      SOURCES/Grow-fix-switching-on-PPL-during-recovery.patch
  39. 34
      SOURCES/Grow-set-component-size-prior-to-array-size.patch
  40. 36
      SOURCES/Grow_continue_command-ensure-content-is-properly-ini.patch
  41. 47
      SOURCES/IMSM-Initialize-my_vol_raid_dev_num-during-vol-creat.patch
  42. 152
      SOURCES/Incremental-Cleanup-some-if-statement-spaghetti.patch
  43. 54
      SOURCES/Incremental-Remove-redundant-call-for-GET_ARRAY_INFO.patch
  44. 37
      SOURCES/Incremental-Use-md_array_active-to-determine3-state-o.patch
  45. 41
      SOURCES/Incremental-Use-md_array_active-where-applicable.patch
  46. 26
      SOURCES/Incremental-returnis-not-a-function.patch
  47. 38
      SOURCES/IncrementalScan-Use-md_array_active-instead-of-mdge.patch
  48. 74
      SOURCES/Introduce1-sys_hot_remove_disk.patch
  49. 25
      SOURCES/Makefile-Default-to-O2-optimization1.patch
  50. 31
      SOURCES/Makefile-Fix-date-to-be-output-in-ISO-format.patch
  51. 41
      SOURCES/Manage-Manage-ro-Use-md_array_active.patch
  52. 69
      SOURCES/Manage-Remove-all-references1-to-md_get_version.patch
  53. 28
      SOURCES/Manage-subdevs-Use-a-dev_t.patch
  54. 32
      SOURCES/Mention-endian-in-documentation-for-update-byte-orde.patch
  55. 151
      SOURCES/Monitor-Code-is-80-characters-per-line.patch
  56. 329
      SOURCES/Monitor-Fixup-apile-of-whitespace-issues.patch
  57. 36
      SOURCES/Monitor-Include-containers-in-spare-migration2.patch
  58. 45
      SOURCES/Monitor-Not-much-point-declaring-mdlist-in-both-fork.patch
  59. 81
      SOURCES/Monitor-Use-md_array_active-instead-of-manually-fidd.patch
  60. 102
      SOURCES/Monitor-check_array-Centralize-exit-path.patch
  61. 36
      SOURCES/Monitor-check_array-Get-arraydisks-from-sysfs.patch
  62. 46
      SOURCES/Monitor-check_array-Get-faileddisks-from-sysfs.patch
  63. 71
      SOURCES/Monitor-check_array-Get-nrdisks-active_disks-and-sp.patch
  64. 44
      SOURCES/Monitor-check_array-Obtain-RAID-level-fromsyfs.patch
  65. 79
      SOURCES/Monitor-check_array-Read-sysfs-entry-earlier.patch
  66. 38
      SOURCES/Monitor-check_array-declate-mdinfo-instance-globally.patch
  67. 99
      SOURCES/Monitor-check_array-reduce-duplicated-error-handling.patch
  68. 38
      SOURCES/Monitor-checkarray-Use-working_disks-from-sysfs.patch
  69. 105
      SOURCES/Monitor-containers-don-t-have-the-same-sysfs-propert.patch
  70. 49
      SOURCES/Monitor-don-t-assume-mdadm-parameter-is-a-blockdevi.patch
  71. 29
      SOURCES/Monitor-mailfrom-is-initialized-correctly.patch
  72. 72
      SOURCES/Query-Handle-error-returned-by-fstat.patch
  73. 28
      SOURCES/Query-Quiet-gcc-since-it-cannot-know-errno-0-in-this.patch
  74. 65
      SOURCES/Query-Remove-all-references-to-md_get_version.patch
  75. 80
      SOURCES/Query-Use-sysfs-to-obtain-data-if-possible.patch
  76. 58
      SOURCES/Replace-snprintf-with-strncpy-at-some-places-to-avoi.patch
  77. 1396
      SOURCES/Retire-mdassemble.patch
  78. 117
      SOURCES/Retry-HOT_REMOVE_DISK-a-few-times.patch
  79. 32
      SOURCES/Revert-mdadm-grow-reshape-would-be-stuck-from-raid1-.patch
  80. 49
      SOURCES/Use-correct-syntax-for-passing-DEVLINKS-to-mdadm-fro.patch
  81. 134
      SOURCES/Zeroout-whole-ppl-space-during-creation-force-assemb.patch
  82. 44
      SOURCES/add-man-page-for-symlinks.patch
  83. 266
      SOURCES/add-ppl-and-no-ppl-options-for-update.patch
  84. 78
      SOURCES/allocate-buffer-to-support-maximum-sector-size.patch
  85. 37
      SOURCES/allow-drives-in-a-container-regardless-of-sector-size.patch
  86. 26
      SOURCES/bitmap-Remove-use-of-md-get-version1.patch
  87. 21
      SOURCES/change-back-0644-permission-for-Grow.c.patch
  88. 65
      SOURCES/container_members_max-degradation-Switch-to-using-sy.patch
  89. 322
      SOURCES/detail-show-consistency-policy.patch
  90. 32
      SOURCES/disable-journal.patch
  91. 31
      SOURCES/dont-allow-array-geometry-change-with-ppl-enabled.patch
  92. 64
      SOURCES/dont-allow-disks-with-different-sector-sizein-one.patch
  93. 42
      SOURCES/dont-allow-to-enable-PPL-reshape-in-progress.patch
  94. 146
      SOURCES/examine-tidy-up-some-code.patch
  95. 638
      SOURCES/generic-support-for-consistency-policy-and-PPL.patch
  96. 32
      SOURCES/imsm-Set-disk-slot-number.patch
  97. 38
      SOURCES/imsm-Write-empty-PPL-header-if-assembling-regular-cl.patch
  98. 32
      SOURCES/imsm-always-do-ppl-recovery-when-starting-a-rebuildi.patch
  99. 113
      SOURCES/imsm-continue-resync-on-3disk-RAID10.patch
  100. 61
      SOURCES/imsm-don-t-skip-resync-when-an-invalid-ppl-header-is.patch
  101. Some files were not shown because too many files have changed in this diff Show More

136
SOURCES/Add-force-flag1-to-hot_remove_disk.patch

@ -0,0 +1,136 @@ @@ -0,0 +1,136 @@
From 1ab9ed2afb7ca50c4f922a0b85c4e6631becde02 Mon Sep 17 00:00:00 2001
From: NeilBrown <neilb@suse.com>
Date: Mon, 27 Mar 2017 14:36:56 +1100
Subject: [RHEL7.5 PATCH 023/169] Add 'force' flag to *hot_remove_disk().

In rare circumstances, the short period that *hot_remove_disk()
waits isn't long enough to IO to complete. This particularly happens
when a device is failing and many retries are still happening.

We don't want to increase the normal wait time for "mdadm --remove"
as that might be use just to test if a device is active or not, and a
delay would be problematic.
So allow "--force" to mean that mdadm should try extra hard for a
--remove to complete, waiting up to 5 seconds.

Note that this patch fixes a comment which claim the previous
wait time was half a second, where it was really 50msec.

Signed-off-by: NeilBrown <neilb@suse.com>
Signed-off-by: Jes Sorensen <Jes.Sorensen@gmail.com>
---
Grow.c | 2 +-
Manage.c | 10 +++++-----
mdadm.h | 4 ++--
util.c | 10 +++++-----
4 files changed, 13 insertions(+), 13 deletions(-)

diff --git a/Grow.c b/Grow.c
index 218a706..e22661c 100755
--- a/Grow.c
+++ b/Grow.c
@@ -2749,7 +2749,7 @@ static int impose_level(int fd, int level, char *devname, int verbose)
continue;
ioctl(fd, SET_DISK_FAULTY,
makedev(disk.major, disk.minor));
- hot_remove_disk(fd, makedev(disk.major, disk.minor));
+ hot_remove_disk(fd, makedev(disk.major, disk.minor), 1);
}
}
c = map_num(pers, level);
diff --git a/Manage.c b/Manage.c
index edf5798..55218d9 100644
--- a/Manage.c
+++ b/Manage.c
@@ -1110,7 +1110,7 @@ int Manage_add(int fd, int tfd, struct mddev_dev *dv,
}
int Manage_remove(struct supertype *tst, int fd, struct mddev_dev *dv,
- int sysfd, unsigned long rdev, int verbose, char *devname)
+ int sysfd, unsigned long rdev, int force, int verbose, char *devname)
{
int lfd = -1;
int err;
@@ -1177,9 +1177,9 @@ int Manage_remove(struct supertype *tst, int fd, struct mddev_dev *dv,
/* device has been removed and we don't know
* the major:minor number
*/
- err = sys_hot_remove_disk(sysfd);
+ err = sys_hot_remove_disk(sysfd, force);
} else {
- err = hot_remove_disk(fd, rdev);
+ err = hot_remove_disk(fd, rdev, force);
if (err && errno == ENODEV) {
/* Old kernels rejected this if no personality
* is registered */
@@ -1603,7 +1603,7 @@ int Manage_subdevs(char *devname, int fd,
if (dv->disposition == 'F')
/* Need to remove first */
- hot_remove_disk(fd, rdev);
+ hot_remove_disk(fd, rdev, force);
/* Make sure it isn't in use (in 2.6 or later) */
tfd = dev_open(dv->devname, O_RDONLY|O_EXCL);
if (tfd >= 0) {
@@ -1645,7 +1645,7 @@ int Manage_subdevs(char *devname, int fd,
rv = -1;
} else
rv = Manage_remove(tst, fd, dv, sysfd,
- rdev, verbose,
+ rdev, verbose, force,
devname);
if (sysfd >= 0)
close(sysfd);
diff --git a/mdadm.h b/mdadm.h
index b855d24..cebc0c0 100644
--- a/mdadm.h
+++ b/mdadm.h
@@ -1476,8 +1476,8 @@ extern int add_disk(int mdfd, struct supertype *st,
struct mdinfo *sra, struct mdinfo *info);
extern int remove_disk(int mdfd, struct supertype *st,
struct mdinfo *sra, struct mdinfo *info);
-extern int hot_remove_disk(int mdfd, unsigned long dev);
-extern int sys_hot_remove_disk(int statefd);
+extern int hot_remove_disk(int mdfd, unsigned long dev, int force);
+extern int sys_hot_remove_disk(int statefd, int force);
extern int set_array_info(int mdfd, struct supertype *st, struct mdinfo *info);
unsigned long long min_recovery_start(struct mdinfo *array);
diff --git a/util.c b/util.c
index b718531..683c869 100644
--- a/util.c
+++ b/util.c
@@ -1795,15 +1795,15 @@ int remove_disk(int mdfd, struct supertype *st,
return rv;
}
-int hot_remove_disk(int mdfd, unsigned long dev)
+int hot_remove_disk(int mdfd, unsigned long dev, int force)
{
- int cnt = 5;
+ int cnt = force ? 500 : 5;
int ret;
/* HOT_REMOVE_DISK can fail with EBUSY if there are
* outstanding IO requests to the device.
* In this case, it can be helpful to wait a little while,
- * up to half a second, for that IO to flush.
+ * up to 5 seconds if 'force' is set, or 50 msec if not.
*/
while ((ret = ioctl(mdfd, HOT_REMOVE_DISK, dev)) == -1 &&
errno == EBUSY &&
@@ -1813,9 +1813,9 @@ int hot_remove_disk(int mdfd, unsigned long dev)
return ret;
}
-int sys_hot_remove_disk(int statefd)
+int sys_hot_remove_disk(int statefd, int force)
{
- int cnt = 5;
+ int cnt = force ? 500 : 5;
int ret;
while ((ret = write(statefd, "remove", 6)) == -1 &&
--
2.7.4

172
SOURCES/Add-sector-size-as-spare-selection-criterion.patch

@ -0,0 +1,172 @@ @@ -0,0 +1,172 @@
commit 4b57ecf6cea134edff75a2f3a87ee48d52715c70
Author: Alexey Obitotskiy <aleksey.obitotskiy@intel.com>
Date: Tue May 9 12:25:47 2017 +0200

Add sector size as spare selection criterion
Add sector size as new spare selection criterion. Assume that 0 means
there is no requirement for the sector size in the array. Skip disks
with unsuitable sector size when looking for a spare to move across
containers.
Signed-off-by: Alexey Obitotskiy <aleksey.obitotskiy@intel.com>
Signed-off-by: Tomasz Majchrzak <tomasz.majchrzak@intel.com>
Signed-off-by: Jes Sorensen <jsorensen@fb.com>

diff --git a/Incremental.c b/Incremental.c
index fe9d644..30dc7a2 100644
--- a/Incremental.c
+++ b/Incremental.c
@@ -867,7 +867,7 @@ static int array_try_spare(char *devname, int *dfdp, struct dev_policy *pol,
struct domainlist *dl = NULL;
struct mdinfo *sra;
unsigned long long devsize;
- struct spare_criteria sc = {0};
+ struct spare_criteria sc = {0, 0};
if (is_subarray(mp->metadata))
continue;
@@ -1627,7 +1627,7 @@ static int Incremental_container(struct supertype *st, char *devname,
struct mdinfo *sinfo;
if (!sst->ss->load_container(sst, sfd, NULL)) {
- struct spare_criteria sc = {0};
+ struct spare_criteria sc = {0, 0};
if (st->ss->get_spare_criteria)
st->ss->get_spare_criteria(st, &sc);
diff --git a/Monitor.c b/Monitor.c
index 9a2baad..c96f8e8 100644
--- a/Monitor.c
+++ b/Monitor.c
@@ -731,6 +731,7 @@ static int get_required_spare_criteria(struct state *st,
if (!st->metadata ||
!st->metadata->ss->get_spare_criteria) {
sc->min_size = 0;
+ sc->sector_size = 0;
return 0;
}
@@ -787,6 +788,7 @@ static dev_t choose_spare(struct state *from, struct state *to,
from->devstate[d] == 0) {
struct dev_policy *pol;
unsigned long long dev_size;
+ unsigned int dev_sector_size;
if (to->metadata->ss->external &&
test_partition_from_id(from->devid[d]))
@@ -797,6 +799,12 @@ static dev_t choose_spare(struct state *from, struct state *to,
dev_size < sc->min_size)
continue;
+ if (sc->sector_size &&
+ dev_sector_size_from_id(from->devid[d],
+ &dev_sector_size) &&
+ sc->sector_size != dev_sector_size)
+ continue;
+
pol = devid_policy(from->devid[d]);
if (from->spare_group)
pol_add(&pol, pol_domain,
diff --git a/mdadm.h b/mdadm.h
index 8da7fd3..ec0a39e 100644
--- a/mdadm.h
+++ b/mdadm.h
@@ -363,6 +363,7 @@ struct createinfo {
struct spare_criteria {
unsigned long long min_size;
+ unsigned int sector_size;
};
enum mode {
@@ -947,6 +948,7 @@ extern struct superswitch {
/*
* Return spare criteria for array:
* - minimum disk size can be used in array;
+ * - sector size can be used in array.
* Return values: 0 - for success and -EINVAL on error.
*/
int (*get_spare_criteria)(struct supertype *st,
@@ -1189,6 +1191,7 @@ extern int get_dev_size(int fd, char *dname, unsigned long long *sizep);
extern int get_dev_sector_size(int fd, char *dname, unsigned int *sectsizep);
extern int must_be_container(int fd);
extern int dev_size_from_id(dev_t id, unsigned long long *size);
+extern int dev_sector_size_from_id(dev_t id, unsigned int *size);
void wait_for(char *dev, int fd);
/*
diff --git a/super-intel.c b/super-intel.c
index be973f8..ba6f810 100644
--- a/super-intel.c
+++ b/super-intel.c
@@ -1396,6 +1396,7 @@ int get_spare_criteria_imsm(struct supertype *st, struct spare_criteria *c)
unsigned long long size = 0;
c->min_size = 0;
+ c->sector_size = 0;
if (!super)
return -EINVAL;
@@ -1419,6 +1420,7 @@ int get_spare_criteria_imsm(struct supertype *st, struct spare_criteria *c)
size += imsm_min_reserved_sectors(super);
c->min_size = size * 512;
+ c->sector_size = super->sector_size;
return 0;
}
diff --git a/util.c b/util.c
index 8b3c67d..fc9cd3f 100644
--- a/util.c
+++ b/util.c
@@ -1265,6 +1265,23 @@ int dev_size_from_id(dev_t id, unsigned long long *size)
return 0;
}
+int dev_sector_size_from_id(dev_t id, unsigned int *size)
+{
+ char buf[20];
+ int fd;
+
+ sprintf(buf, "%d:%d", major(id), minor(id));
+ fd = dev_open(buf, O_RDONLY);
+ if (fd < 0)
+ return 0;
+ if (get_dev_sector_size(fd, NULL, size)) {
+ close(fd);
+ return 1;
+ }
+ close(fd);
+ return 0;
+}
+
struct supertype *dup_super(struct supertype *orig)
{
struct supertype *st;
@@ -2129,12 +2146,24 @@ struct mdinfo *container_choose_spares(struct supertype *st,
if (d->disk.state == 0) {
/* check if size is acceptable */
unsigned long long dev_size;
+ unsigned int dev_sector_size;
+ int size_valid = 0;
+ int sector_size_valid = 0;
+
dev_t dev = makedev(d->disk.major,d->disk.minor);
if (!criteria->min_size ||
(dev_size_from_id(dev, &dev_size) &&
dev_size >= criteria->min_size))
- found = 1;
+ size_valid = 1;
+
+ if (!criteria->sector_size ||
+ (dev_sector_size_from_id(dev, &dev_sector_size) &&
+ criteria->sector_size == dev_sector_size))
+ sector_size_valid = 1;
+
+ found = size_valid && sector_size_valid;
+
/* check if domain matches */
if (found && domlist) {
struct dev_policy *pol = devid_policy(dev);

334
SOURCES/Allow-more-spare-selection-criteria.patch

@ -0,0 +1,334 @@ @@ -0,0 +1,334 @@
commit fbfdcb06dc5b1dcb227b0394f174faa2df734700
Author: Alexey Obitotskiy <aleksey.obitotskiy@intel.com>
Date: Tue May 9 12:25:46 2017 +0200

Allow more spare selection criteria
Disks can be moved across containers in order to be used as a spare
drive for reubild. At the moment the only requirement checked for such
disk is its size (if it matches donor expectations). In order to
introduce more criteria rename corresponding superswitch method to more
generic name and move function parameter to a structure. This change is
a big edit but it doesn't introduce any changes in code logic, it just
updates function naming and parameters.
Signed-off-by: Alexey Obitotskiy <aleksey.obitotskiy@intel.com>
Signed-off-by: Tomasz Majchrzak <tomasz.majchrzak@intel.com>
Signed-off-by: Jes Sorensen <jsorensen@fb.com>

diff --git a/Incremental.c b/Incremental.c
index 680d318..fe9d644 100644
--- a/Incremental.c
+++ b/Incremental.c
@@ -867,7 +867,7 @@ static int array_try_spare(char *devname, int *dfdp, struct dev_policy *pol,
struct domainlist *dl = NULL;
struct mdinfo *sra;
unsigned long long devsize;
- unsigned long long component_size = 0;
+ struct spare_criteria sc = {0};
if (is_subarray(mp->metadata))
continue;
@@ -936,7 +936,8 @@ static int array_try_spare(char *devname, int *dfdp, struct dev_policy *pol,
}
if (st3->ss->load_container &&
!st3->ss->load_container(st3, mdfd, mp->path)) {
- component_size = st3->ss->min_acceptable_spare_size(st3);
+ if (st3->ss->get_spare_criteria)
+ st3->ss->get_spare_criteria(st3, &sc);
st3->ss->free_super(st3);
}
free(st3);
@@ -947,7 +948,7 @@ static int array_try_spare(char *devname, int *dfdp, struct dev_policy *pol,
sra->devs ? sra->devs->data_offset :
INVALID_SECTORS) <
sra->component_size) ||
- (sra->component_size == 0 && devsize < component_size)) {
+ (sra->component_size == 0 && devsize < sc.min_size)) {
if (verbose > 1)
pr_err("not adding %s to %s as it is too small\n",
devname, mp->path);
@@ -1624,12 +1625,15 @@ static int Incremental_container(struct supertype *st, char *devname,
struct supertype *sst =
super_imsm.match_metadata_desc("imsm");
struct mdinfo *sinfo;
- unsigned long long min_size = 0;
- if (st->ss->min_acceptable_spare_size)
- min_size = st->ss->min_acceptable_spare_size(st);
+
if (!sst->ss->load_container(sst, sfd, NULL)) {
+ struct spare_criteria sc = {0};
+
+ if (st->ss->get_spare_criteria)
+ st->ss->get_spare_criteria(st, &sc);
+
close(sfd);
- sinfo = container_choose_spares(sst, min_size,
+ sinfo = container_choose_spares(sst, &sc,
domains, NULL,
st->ss->name, 0);
sst->ss->free_super(sst);
diff --git a/Monitor.c b/Monitor.c
index ec643d4..9a2baad 100644
--- a/Monitor.c
+++ b/Monitor.c
@@ -723,13 +723,14 @@ static int add_new_arrays(struct mdstat_ent *mdstat, struct state **statelist,
return new_found;
}
-static int get_min_spare_size_required(struct state *st, unsigned long long *sizep)
+static int get_required_spare_criteria(struct state *st,
+ struct spare_criteria *sc)
{
int fd;
if (!st->metadata ||
- !st->metadata->ss->min_acceptable_spare_size) {
- *sizep = 0;
+ !st->metadata->ss->get_spare_criteria) {
+ sc->min_size = 0;
return 0;
}
@@ -743,7 +744,8 @@ static int get_min_spare_size_required(struct state *st, unsigned long long *siz
close(fd);
if (!st->metadata->sb)
return 1;
- *sizep = st->metadata->ss->min_acceptable_spare_size(st->metadata);
+
+ st->metadata->ss->get_spare_criteria(st->metadata, sc);
st->metadata->ss->free_super(st->metadata);
return 0;
@@ -775,7 +777,7 @@ static int check_donor(struct state *from, struct state *to)
}
static dev_t choose_spare(struct state *from, struct state *to,
- struct domainlist *domlist, unsigned long long min_size)
+ struct domainlist *domlist, struct spare_criteria *sc)
{
int d;
dev_t dev = 0;
@@ -790,9 +792,9 @@ static dev_t choose_spare(struct state *from, struct state *to,
test_partition_from_id(from->devid[d]))
continue;
- if (min_size &&
+ if (sc->min_size &&
dev_size_from_id(from->devid[d], &dev_size) &&
- dev_size < min_size)
+ dev_size < sc->min_size)
continue;
pol = devid_policy(from->devid[d]);
@@ -809,7 +811,7 @@ static dev_t choose_spare(struct state *from, struct state *to,
static dev_t container_choose_spare(struct state *from, struct state *to,
struct domainlist *domlist,
- unsigned long long min_size, int active)
+ struct spare_criteria *sc, int active)
{
/* This is similar to choose_spare, but we cannot trust devstate,
* so we need to read the metadata instead
@@ -860,7 +862,7 @@ static dev_t container_choose_spare(struct state *from, struct state *to,
}
/* We only need one spare so full list not needed */
- list = container_choose_spares(st, min_size, domlist, from->spare_group,
+ list = container_choose_spares(st, sc, domlist, from->spare_group,
to->metadata->ss->name, 1);
if (list) {
struct mdinfo *disks = list->devs;
@@ -876,6 +878,7 @@ static void try_spare_migration(struct state *statelist, struct alert_info *info
{
struct state *from;
struct state *st;
+ struct spare_criteria sc;
link_containers_with_subarrays(statelist);
for (st = statelist; st; st = st->next)
@@ -884,7 +887,6 @@ static void try_spare_migration(struct state *statelist, struct alert_info *info
struct domainlist *domlist = NULL;
int d;
struct state *to = st;
- unsigned long long min_size;
if (to->parent_devnm[0] && !to->parent)
/* subarray monitored without parent container
@@ -895,14 +897,14 @@ static void try_spare_migration(struct state *statelist, struct alert_info *info
/* member of a container */
to = to->parent;
- if (get_min_spare_size_required(to, &min_size))
+ if (get_required_spare_criteria(to, &sc))
continue;
if (to->metadata->ss->external) {
/* We must make sure there is
* no suitable spare in container already.
* If there is we don't add more */
dev_t devid = container_choose_spare(
- to, to, NULL, min_size, st->active);
+ to, to, NULL, &sc, st->active);
if (devid > 0)
continue;
}
@@ -925,10 +927,10 @@ static void try_spare_migration(struct state *statelist, struct alert_info *info
continue;
if (from->metadata->ss->external)
devid = container_choose_spare(
- from, to, domlist, min_size, 0);
+ from, to, domlist, &sc, 0);
else
devid = choose_spare(from, to, domlist,
- min_size);
+ &sc);
if (devid > 0
&& move_spare(from->devname, to->devname, devid)) {
alert("MoveSpare", to->devname, from->devname, info);
diff --git a/mdadm.h b/mdadm.h
index a92feb2..8da7fd3 100644
--- a/mdadm.h
+++ b/mdadm.h
@@ -361,6 +361,10 @@ struct createinfo {
struct supertype *supertype;
};
+struct spare_criteria {
+ unsigned long long min_size;
+};
+
enum mode {
ASSEMBLE=1,
BUILD,
@@ -940,11 +944,13 @@ extern struct superswitch {
*/
__u64 (*avail_size)(struct supertype *st, __u64 size,
unsigned long long data_offset);
- /* This is similar to 'avail_size' in purpose, but is used for
- * containers for which there is no 'component size' to compare.
- * This reports that whole-device size which is a minimum
+ /*
+ * Return spare criteria for array:
+ * - minimum disk size can be used in array;
+ * Return values: 0 - for success and -EINVAL on error.
*/
- unsigned long long (*min_acceptable_spare_size)(struct supertype *st);
+ int (*get_spare_criteria)(struct supertype *st,
+ struct spare_criteria *sc);
/* Find somewhere to put a bitmap - possibly auto-size it - and
* update the metadata to record this. The array may be newly
* created, in which case data_size may be updated, or it might
@@ -1507,7 +1513,7 @@ extern int assemble_container_content(struct supertype *st, int mdfd,
#define INCR_ALREADY 4
#define INCR_YES 8
extern struct mdinfo *container_choose_spares(struct supertype *st,
- unsigned long long min_size,
+ struct spare_criteria *criteria,
struct domainlist *domlist,
char *spare_group,
const char *metadata, int get_one);
diff --git a/super-intel.c b/super-intel.c
index e88fe82..be973f8 100644
--- a/super-intel.c
+++ b/super-intel.c
@@ -1383,37 +1383,44 @@ static __u32 imsm_min_reserved_sectors(struct intel_super *super)
return (remainder < rv) ? remainder : rv;
}
-/* Return minimum size of a spare that can be used in this array*/
-static unsigned long long min_acceptable_spare_size_imsm(struct supertype *st)
+/*
+ * Return minimum size of a spare and sector size
+ * that can be used in this array
+ */
+int get_spare_criteria_imsm(struct supertype *st, struct spare_criteria *c)
{
struct intel_super *super = st->sb;
struct dl *dl;
struct extent *e;
int i;
- unsigned long long rv = 0;
+ unsigned long long size = 0;
+
+ c->min_size = 0;
if (!super)
- return rv;
+ return -EINVAL;
/* find first active disk in array */
dl = super->disks;
while (dl && (is_failed(&dl->disk) || dl->index == -1))
dl = dl->next;
if (!dl)
- return rv;
+ return -EINVAL;
/* find last lba used by subarrays */
e = get_extents(super, dl);
if (!e)
- return rv;
+ return -EINVAL;
for (i = 0; e[i].size; i++)
continue;
if (i > 0)
- rv = e[i-1].start + e[i-1].size;
+ size = e[i-1].start + e[i-1].size;
free(e);
/* add the amount of space needed for metadata */
- rv = rv + imsm_min_reserved_sectors(super);
+ size += imsm_min_reserved_sectors(super);
+
+ c->min_size = size * 512;
- return rv * 512;
+ return 0;
}
static int is_gen_migration(struct imsm_dev *dev);
@@ -10817,8 +10824,10 @@ static int imsm_reshape_is_allowed_on_container(struct supertype *st,
*/
static struct mdinfo *get_spares_for_grow(struct supertype *st)
{
- unsigned long long min_size = min_acceptable_spare_size_imsm(st);
- return container_choose_spares(st, min_size, NULL, NULL, NULL, 0);
+ struct spare_criteria sc;
+
+ get_spare_criteria_imsm(st, &sc);
+ return container_choose_spares(st, &sc, NULL, NULL, NULL, 0);
}
/******************************************************************************
@@ -11853,7 +11862,7 @@ struct superswitch super_imsm = {
.update_super = update_super_imsm,
.avail_size = avail_size_imsm,
- .min_acceptable_spare_size = min_acceptable_spare_size_imsm,
+ .get_spare_criteria = get_spare_criteria_imsm,
.compare_super = compare_super_imsm,
diff --git a/util.c b/util.c
index 11ff2cc..8b3c67d 100644
--- a/util.c
+++ b/util.c
@@ -2107,7 +2107,7 @@ int experimental(void)
* if spare_group given add it to domains of each spare
* metadata allows to test domains using metadata of destination array */
struct mdinfo *container_choose_spares(struct supertype *st,
- unsigned long long min_size,
+ struct spare_criteria *criteria,
struct domainlist *domlist,
char *spare_group,
const char *metadata, int get_one)
@@ -2131,9 +2131,9 @@ struct mdinfo *container_choose_spares(struct supertype *st,
unsigned long long dev_size;
dev_t dev = makedev(d->disk.major,d->disk.minor);
- if (!min_size ||
+ if (!criteria->min_size ||
(dev_size_from_id(dev, &dev_size) &&
- dev_size >= min_size))
+ dev_size >= criteria->min_size))
found = 1;
/* check if domain matches */
if (found && domlist) {

31
SOURCES/Assemble-Assemble-Get-rid-of-last-use-of-md_get-vers.patch

@ -0,0 +1,31 @@ @@ -0,0 +1,31 @@
From b6e60be6281a2a4ec326a72de114867797a42d7f Mon Sep 17 00:00:00 2001
From: Jes Sorensen <Jes.Sorensen@gmail.com>
Date: Wed, 5 Apr 2017 15:47:37 -0400
Subject: [RHEL7.5 PATCH 065/169] Assemble/Assemble: Get rid of last use of
md_get_version()

At this point in the code, we know we have a valid array, and any
recent kernel will return 9003, so no point in querying the kernel for
this.

Signed-off-by: Jes Sorensen <Jes.Sorensen@gmail.com>
---
Assemble.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/Assemble.c b/Assemble.c
index fa5fdbe..0db428f 100644
--- a/Assemble.c
+++ b/Assemble.c
@@ -1901,7 +1901,7 @@ int assemble_container_content(struct supertype *st, int mdfd,
c->readonly &&
content->text_version[0] == '/')
content->text_version[0] = '-';
- if (sysfs_set_array(content, md_get_version(mdfd)) != 0) {
+ if (sysfs_set_array(content, 9003) != 0) {
sysfs_free(sra);
return 1;
}
--
2.7.4

31
SOURCES/Assemble-Assemble-Stop-checking-kernel-md-driver-ver.patch

@ -0,0 +1,31 @@ @@ -0,0 +1,31 @@
From 6142741d144824c31b733f9d6e6e240b159effc0 Mon Sep 17 00:00:00 2001
From: Jes Sorensen <Jes.Sorensen@gmail.com>
Date: Wed, 5 Apr 2017 15:09:18 -0400
Subject: [RHEL7.5 PATCH 054/169] Assemble/Assemble: Stop checking kernel
md driver version

Any kernel released during the last decade will return 9003 from
md_get_version() so no point in checking that.

Signed-off-by: Jes Sorensen <Jes.Sorensen@gmail.com>
---
Assemble.c | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/Assemble.c b/Assemble.c
index 672cd12..fa5fdbe 100644
--- a/Assemble.c
+++ b/Assemble.c
@@ -1477,8 +1477,7 @@ try_again:
return 1;
}
mddev = chosen_name;
- if (get_linux_version() < 2004000 ||
- md_get_version(mdfd) < 9000) {
+ if (get_linux_version() < 2004000) {
pr_err("Assemble requires Linux 2.4 or later, and\n"
" md driver version 0.90.0 or later.\n"
" Upgrade your kernel or try --build\n");
--
2.7.4

249
SOURCES/Assemble-Clean1-up-start_array.patch

@ -0,0 +1,249 @@ @@ -0,0 +1,249 @@
From 94b53b777e095e1bc253654acc2e459d368c5dd5 Mon Sep 17 00:00:00 2001
From: Jes Sorensen <jsorensen@fb.com>
Date: Wed, 12 Apr 2017 14:23:45 -0400
Subject: [RHEL7.5 PATCH 075/169] Assemble: Clean up start_array()

This is purely cosmetic, no codeflow changes.

Signed-off-by: Jes Sorensen <jsorensen@fb.com>
---
Assemble.c | 97 +++++++++++++++++++++++++++++++++++++-------------------------
1 file changed, 58 insertions(+), 39 deletions(-)

diff --git a/Assemble.c b/Assemble.c
index b828523..22596b5 100644
--- a/Assemble.c
+++ b/Assemble.c
@@ -992,7 +992,7 @@ static int start_array(int mdfd,
}
/* First, add the raid disks, but add the chosen one last */
- for (i=0; i<= bestcnt; i++) {
+ for (i = 0; i <= bestcnt; i++) {
int j;
if (i < bestcnt) {
j = best[i];
@@ -1002,8 +1002,9 @@ static int start_array(int mdfd,
j = chosen_drive;
if (j >= 0 && !devices[j].included) {
- int dfd = dev_open(devices[j].devname,
- O_RDWR|O_EXCL);
+ int dfd;
+
+ dfd = dev_open(devices[j].devname, O_RDWR|O_EXCL);
if (dfd >= 0) {
remove_partitions(dfd);
close(dfd);
@@ -1012,28 +1013,30 @@ static int start_array(int mdfd,
if (rv) {
pr_err("failed to add %s to %s: %s\n",
- devices[j].devname,
- mddev,
+ devices[j].devname, mddev,
strerror(errno));
- if (i < content->array.raid_disks * 2
- || i == bestcnt)
+ if (i < content->array.raid_disks * 2 ||
+ i == bestcnt)
okcnt--;
else
sparecnt--;
- } else if (c->verbose > 0)
+ } else if (c->verbose > 0) {
pr_err("added %s to %s as %d%s%s\n",
devices[j].devname, mddev,
devices[j].i.disk.raid_disk,
devices[j].uptodate?"":
" (possibly out of date)",
- (devices[j].i.disk.state & (1<<MD_DISK_REPLACEMENT))?" replacement":"");
+ (devices[j].i.disk.state &
+ (1<<MD_DISK_REPLACEMENT)) ?
+ " replacement":"");
+ }
} else if (j >= 0) {
if (c->verbose > 0)
pr_err("%s is already in %s as %d\n",
devices[j].devname, mddev,
devices[j].i.disk.raid_disk);
- } else if (c->verbose > 0 && i < content->array.raid_disks*2
- && (i&1) == 0)
+ } else if (c->verbose > 0 &&
+ i < content->array.raid_disks * 2 && (i & 1) == 0)
pr_err("no uptodate device for slot %d of %s\n",
i/2, mddev);
}
@@ -1041,8 +1044,8 @@ static int start_array(int mdfd,
if (content->array.level == LEVEL_CONTAINER) {
if (c->verbose >= 0) {
pr_err("Container %s has been assembled with %d drive%s",
- mddev, okcnt+sparecnt+journalcnt,
- okcnt+sparecnt+journalcnt==1?"":"s");
+ mddev, okcnt + sparecnt + journalcnt,
+ okcnt + sparecnt + journalcnt == 1 ? "" : "s");
if (okcnt < (unsigned)content->array.raid_disks)
fprintf(stderr, " (out of %d)",
content->array.raid_disks);
@@ -1051,10 +1054,13 @@ static int start_array(int mdfd,
if (st->ss->validate_container) {
struct mdinfo *devices_list;
- struct mdinfo *info_devices = xmalloc(sizeof(struct mdinfo)*(okcnt+sparecnt));
+ struct mdinfo *info_devices;
unsigned int count;
+
devices_list = NULL;
- for (count = 0; count < okcnt+sparecnt; count++) {
+ info_devices = xmalloc(sizeof(struct mdinfo) *
+ (okcnt + sparecnt));
+ for (count = 0; count < okcnt + sparecnt; count++) {
info_devices[count] = devices[count].i;
info_devices[count].next = devices_list;
devices_list = &info_devices[count];
@@ -1080,16 +1086,16 @@ static int start_array(int mdfd,
if (c->runstop == 1 ||
(c->runstop <= 0 &&
- ( enough(content->array.level, content->array.raid_disks,
- content->array.layout, clean, avail) &&
- (okcnt + rebuilding_cnt >= req_cnt || start_partial_ok)
- ))) {
+ (enough(content->array.level, content->array.raid_disks,
+ content->array.layout, clean, avail) &&
+ (okcnt + rebuilding_cnt >= req_cnt || start_partial_ok)))) {
/* This array is good-to-go.
* If a reshape is in progress then we might need to
* continue monitoring it. In that case we start
* it read-only and let the grow code make it writable.
*/
int rv;
+
if (content->reshape_active &&
!(content->reshape_active & RESHAPE_NO_BACKUP) &&
content->delta_disks <= 0) {
@@ -1109,8 +1115,8 @@ static int start_array(int mdfd,
c->backup_file, 0,
c->freeze_reshape);
} else if (c->readonly &&
- sysfs_attribute_available(
- content, NULL, "array_state")) {
+ sysfs_attribute_available(content, NULL,
+ "array_state")) {
rv = sysfs_set_str(content, NULL,
"array_state", "readonly");
} else
@@ -1121,13 +1127,19 @@ static int start_array(int mdfd,
pr_err("%s has been started with %d drive%s",
mddev, okcnt, okcnt==1?"":"s");
if (okcnt < (unsigned)content->array.raid_disks)
- fprintf(stderr, " (out of %d)", content->array.raid_disks);
+ fprintf(stderr, " (out of %d)",
+ content->array.raid_disks);
if (rebuilding_cnt)
- fprintf(stderr, "%s %d rebuilding", sparecnt?",":" and", rebuilding_cnt);
+ fprintf(stderr, "%s %d rebuilding",
+ sparecnt?",":" and",
+ rebuilding_cnt);
if (sparecnt)
- fprintf(stderr, " and %d spare%s", sparecnt, sparecnt==1?"":"s");
+ fprintf(stderr, " and %d spare%s",
+ sparecnt,
+ sparecnt == 1 ? "" : "s");
if (content->journal_clean)
- fprintf(stderr, " and %d journal", journalcnt);
+ fprintf(stderr, " and %d journal",
+ journalcnt);
fprintf(stderr, ".\n");
}
if (content->reshape_active &&
@@ -1137,11 +1149,14 @@ static int start_array(int mdfd,
* of the stripe cache - default is 256
*/
int chunk_size = content->array.chunk_size;
+
if (content->reshape_active &&
content->new_chunk > chunk_size)
chunk_size = content->new_chunk;
if (256 < 4 * ((chunk_size+4065)/4096)) {
- struct mdinfo *sra = sysfs_read(mdfd, NULL, 0);
+ struct mdinfo *sra;
+
+ sra = sysfs_read(mdfd, NULL, 0);
if (sra)
sysfs_set_num(sra, NULL,
"stripe_cache_size",
@@ -1174,7 +1189,9 @@ static int start_array(int mdfd,
if (content->array.level == 6 &&
okcnt + 1 == (unsigned)content->array.raid_disks &&
was_forced) {
- struct mdinfo *sra = sysfs_read(mdfd, NULL, 0);
+ struct mdinfo *sra;
+
+ sra = sysfs_read(mdfd, NULL, 0);
if (sra)
sysfs_set_str(sra, NULL,
"sync_action", "repair");
@@ -1182,45 +1199,47 @@ static int start_array(int mdfd,
}
return 0;
}
- pr_err("failed to RUN_ARRAY %s: %s\n",
- mddev, strerror(errno));
+ pr_err("failed to RUN_ARRAY %s: %s\n", mddev, strerror(errno));
if (!enough(content->array.level, content->array.raid_disks,
content->array.layout, 1, avail))
pr_err("Not enough devices to start the array.\n");
else if (!enough(content->array.level,
content->array.raid_disks,
- content->array.layout, clean,
- avail))
+ content->array.layout, clean, avail))
pr_err("Not enough devices to start the array while not clean - consider --force.\n");
return 1;
}
if (c->runstop == -1) {
pr_err("%s assembled from %d drive%s",
- mddev, okcnt, okcnt==1?"":"s");
+ mddev, okcnt, okcnt == 1 ? "" : "s");
if (okcnt != (unsigned)content->array.raid_disks)
- fprintf(stderr, " (out of %d)", content->array.raid_disks);
+ fprintf(stderr, " (out of %d)",
+ content->array.raid_disks);
fprintf(stderr, ", but not started.\n");
return 2;
}
if (c->verbose >= -1) {
- pr_err("%s assembled from %d drive%s", mddev, okcnt, okcnt==1?"":"s");
+ pr_err("%s assembled from %d drive%s",
+ mddev, okcnt, okcnt == 1 ? "" : "s");
if (rebuilding_cnt)
- fprintf(stderr, "%s %d rebuilding", sparecnt?",":" and", rebuilding_cnt);
+ fprintf(stderr, "%s %d rebuilding",
+ sparecnt ? "," : " and", rebuilding_cnt);
if (sparecnt)
- fprintf(stderr, " and %d spare%s", sparecnt, sparecnt==1?"":"s");
+ fprintf(stderr, " and %d spare%s", sparecnt,
+ sparecnt == 1 ? "" : "s");
if (!enough(content->array.level, content->array.raid_disks,
content->array.layout, 1, avail))
fprintf(stderr, " - not enough to start the array.\n");
else if (!enough(content->array.level,
content->array.raid_disks,
- content->array.layout, clean,
- avail))
+ content->array.layout, clean, avail))
fprintf(stderr, " - not enough to start the array while not clean - consider --force.\n");
else {
if (req_cnt == (unsigned)content->array.raid_disks)
- fprintf(stderr, " - need all %d to start it", req_cnt);
+ fprintf(stderr, " - need all %d to start it",
+ req_cnt);
else
fprintf(stderr, " - need %d to start", req_cnt);
fprintf(stderr, " (use --run to insist).\n");
--
2.7.4

34
SOURCES/Assemble-Remove-obsolete-test-for-kernels1-older-than.patch

@ -0,0 +1,34 @@ @@ -0,0 +1,34 @@
From 0ef1043ce8dd3f36c7227aa4a260819c4c17c78d Mon Sep 17 00:00:00 2001
From: Jes Sorensen <jsorensen@fb.com>
Date: Wed, 12 Apr 2017 14:50:02 -0400
Subject: [RHEL7.5 PATCH 077/169] Assemble: Remove obsolete test for
kernels older than 2.4

We only support 2.6.15+ at this point

Signed-off-by: Jes Sorensen <jsorensen@fb.com>
---
Assemble.c | 7 -------
1 file changed, 7 deletions(-)

diff --git a/Assemble.c b/Assemble.c
index 22596b5..d6beb23 100644
--- a/Assemble.c
+++ b/Assemble.c
@@ -1487,13 +1487,6 @@ try_again:
return 1;
}
mddev = chosen_name;
- if (get_linux_version() < 2004000) {
- pr_err("Assemble requires Linux 2.4 or later, and\n"
- " md driver version 0.90.0 or later.\n"
- " Upgrade your kernel or try --build\n");
- close(mdfd);
- return 1;
- }
if (pre_exist == NULL) {
if (mddev_busy(fd2devnm(mdfd))) {
pr_err("%s already active, cannot restart it!\n",
--
2.7.4

38
SOURCES/Avoid-to-take-spare-without-defined-domain-by-imsm.patch

@ -0,0 +1,38 @@ @@ -0,0 +1,38 @@
commit 3bf9495270d7cd00da942e183dc5f7c7eb68ff69
Author: Mariusz Tkaczyk <mariusz.tkaczyk@intel.com>
Date: Thu Jan 11 12:39:49 2018 +0100

policy.c: Avoid to take spare without defined domain by imsm
Only Imsm get_disk_controller_domain returns disk controller domain for
each disk. It causes that mdadm automatically creates disk controller
domain policy for imsm metadata, and imsm containers in the same disk
controller domain can take spare for recovery.
Ignore spares if only one imsm domain is matched.
Signed-off-by: Mariusz Tkaczyk <mariusz.tkaczyk@intel.com>
Signed-off-by: Jes Sorensen <jsorensen@fb.com>

diff --git a/policy.c b/policy.c
index b17585a..c0d18a7 100644
--- a/policy.c
+++ b/policy.c
@@ -661,6 +661,7 @@ int domain_test(struct domainlist *dom, struct dev_policy *pol,
* 1: has domains, all match
*/
int found_any = -1;
+ int has_one_domain = 1;
struct dev_policy *p;
pol = pol_find(pol, pol_domain);
@@ -670,6 +671,9 @@ int domain_test(struct domainlist *dom, struct dev_policy *pol,
dom = dom->next;
if (!dom || strcmp(dom->dom, p->value) != 0)
return 0;
+ if (has_one_domain && metadata && strcmp(metadata, "imsm") == 0)
+ found_any = -1;
+ has_one_domain = 0;
}
return found_any;
}

266
SOURCES/Build2-Stop-bothering-about-supporting-md-driver-olde.patch

@ -0,0 +1,266 @@ @@ -0,0 +1,266 @@
From e6e5f8f1267de4f310415231b3434fce2d25f02a Mon Sep 17 00:00:00 2001
From: Jes Sorensen <Jes.Sorensen@gmail.com>
Date: Wed, 5 Apr 2017 15:20:52 -0400
Subject: [RHEL7.5 PATCH 055/169] Build: Stop bothering about supporting md
driver older than 0.90.00

The kernel has been stuck at md driver version 0.90.03 for at least a
decade. No point in continuing to support the older API.

Signed-off-by: Jes Sorensen <Jes.Sorensen@gmail.com>
---
Build.c | 187 ++++++++++++++++++++++++----------------------------------------
1 file changed, 69 insertions(+), 118 deletions(-)

diff --git a/Build.c b/Build.c
index 691dd6f..11ba12f 100644
--- a/Build.c
+++ b/Build.c
@@ -39,13 +39,8 @@ int Build(char *mddev, struct mddev_dev *devlist,
* geometry is 0xpp00cc
* where pp is personality: 1==linear, 2=raid0
* cc = chunk size factor: 0==4k, 1==8k etc.
- *
- * For md_version >= 0.90.0 we call
- * SET_ARRAY_INFO, ADD_NEW_DISK, RUN_ARRAY
- *
*/
int i;
- int vers;
struct stat stb;
int subdevs = 0, missing_disks = 0;
struct mddev_dev *dv;
@@ -55,6 +50,8 @@ int Build(char *mddev, struct mddev_dev *devlist,
char chosen_name[1024];
int uuid[4] = {0,0,0,0};
struct map_ent *map = NULL;
+ mdu_array_info_t array;
+ mdu_param_t param; /* not used by syscall */
if (s->level == UnSet) {
pr_err("a RAID level is needed to Build an array.\n");
@@ -122,39 +119,30 @@ int Build(char *mddev, struct mddev_dev *devlist,
map_update(&map, fd2devnm(mdfd), "none", uuid, chosen_name);
map_unlock(&map);
- vers = md_get_version(mdfd);
-
- /* looks Ok, go for it */
- if (vers >= 9000) {
- mdu_array_info_t array;
- array.level = s->level;
- if (s->size == MAX_SIZE)
- s->size = 0;
- array.size = s->size;
- array.nr_disks = s->raiddisks;
- array.raid_disks = s->raiddisks;
- array.md_minor = 0;
- if (fstat(mdfd, &stb)==0)
- array.md_minor = minor(stb.st_rdev);
- array.not_persistent = 1;
- array.state = 0; /* not clean, but no errors */
- if (s->assume_clean)
- array.state |= 1;
- array.active_disks = s->raiddisks - missing_disks;
- array.working_disks = s->raiddisks - missing_disks;
- array.spare_disks = 0;
- array.failed_disks = missing_disks;
- if (s->chunk == 0 && (s->level==0 || s->level==LEVEL_LINEAR))
- s->chunk = 64;
- array.chunk_size = s->chunk*1024;
- array.layout = s->layout;
- if (md_set_array_info(mdfd, &array)) {
- pr_err("md_set_array_info() failed for %s: %s\n",
- mddev, strerror(errno));
- goto abort;
- }
- } else if (s->bitmap_file) {
- pr_err("bitmaps not supported with this kernel\n");
+ array.level = s->level;
+ if (s->size == MAX_SIZE)
+ s->size = 0;
+ array.size = s->size;
+ array.nr_disks = s->raiddisks;
+ array.raid_disks = s->raiddisks;
+ array.md_minor = 0;
+ if (fstat(mdfd, &stb) == 0)
+ array.md_minor = minor(stb.st_rdev);
+ array.not_persistent = 1;
+ array.state = 0; /* not clean, but no errors */
+ if (s->assume_clean)
+ array.state |= 1;
+ array.active_disks = s->raiddisks - missing_disks;
+ array.working_disks = s->raiddisks - missing_disks;
+ array.spare_disks = 0;
+ array.failed_disks = missing_disks;
+ if (s->chunk == 0 && (s->level==0 || s->level==LEVEL_LINEAR))
+ s->chunk = 64;
+ array.chunk_size = s->chunk*1024;
+ array.layout = s->layout;
+ if (md_set_array_info(mdfd, &array)) {
+ pr_err("md_set_array_info() failed for %s: %s\n",
+ mddev, strerror(errno));
goto abort;
}
@@ -167,8 +155,10 @@ int Build(char *mddev, struct mddev_dev *devlist,
}
/* now add the devices */
for ((i=0), (dv = devlist) ; dv ; i++, dv=dv->next) {
+ mdu_disk_info_t disk;
unsigned long long dsize;
int fd;
+
if (strcmp("missing", dv->devname) == 0)
continue;
if (stat(dv->devname, &stb)) {
@@ -191,94 +181,58 @@ int Build(char *mddev, struct mddev_dev *devlist,
(s->size == 0 || s->size == MAX_SIZE || dsize < s->size))
s->size = dsize;
close(fd);
- if (vers >= 9000) {
- mdu_disk_info_t disk;
- disk.number = i;
- disk.raid_disk = i;
- disk.state = (1<<MD_DISK_SYNC) | (1<<MD_DISK_ACTIVE);
- if (dv->writemostly == FlagSet)
- disk.state |= 1<<MD_DISK_WRITEMOSTLY;
- disk.major = major(stb.st_rdev);
- disk.minor = minor(stb.st_rdev);
- if (ioctl(mdfd, ADD_NEW_DISK, &disk)) {
- pr_err("ADD_NEW_DISK failed for %s: %s\n",
- dv->devname, strerror(errno));
- goto abort;
- }
- } else {
- if (ioctl(mdfd, REGISTER_DEV, &stb.st_rdev)) {
- pr_err("REGISTER_DEV failed for %s: %s.\n",
- dv->devname, strerror(errno));
- goto abort;
- }
+ disk.number = i;
+ disk.raid_disk = i;
+ disk.state = (1<<MD_DISK_SYNC) | (1<<MD_DISK_ACTIVE);
+ if (dv->writemostly == FlagSet)
+ disk.state |= 1<<MD_DISK_WRITEMOSTLY;
+ disk.major = major(stb.st_rdev);
+ disk.minor = minor(stb.st_rdev);
+ if (ioctl(mdfd, ADD_NEW_DISK, &disk)) {
+ pr_err("ADD_NEW_DISK failed for %s: %s\n",
+ dv->devname, strerror(errno));
+ goto abort;
}
}
/* now to start it */
- if (vers >= 9000) {
- mdu_param_t param; /* not used by syscall */
- if (s->bitmap_file) {
- bitmap_fd = open(s->bitmap_file, O_RDWR);
- if (bitmap_fd < 0) {
- int major = BITMAP_MAJOR_HI;
+ if (s->bitmap_file) {
+ bitmap_fd = open(s->bitmap_file, O_RDWR);
+ if (bitmap_fd < 0) {
+ int major = BITMAP_MAJOR_HI;
#if 0
- if (s->bitmap_chunk == UnSet) {
- pr_err("%s cannot be openned.",
- s->bitmap_file);
- goto abort;
- }
-#endif
- if (vers < 9003) {
- major = BITMAP_MAJOR_HOSTENDIAN;
-#ifdef __BIG_ENDIAN
- pr_err("Warning - bitmaps created on this kernel are not portable\n"
- " between different architectures. Consider upgrading the Linux kernel.\n");
+ if (s->bitmap_chunk == UnSet) {
+ pr_err("%s cannot be openned.", s->bitmap_file);
+ goto abort;
+ }
#endif
- }
- bitmapsize = s->size>>9; /* FIXME wrong for RAID10 */
- if (CreateBitmap(s->bitmap_file, 1, NULL, s->bitmap_chunk,
- c->delay, s->write_behind, bitmapsize, major)) {
- goto abort;
- }
- bitmap_fd = open(s->bitmap_file, O_RDWR);
- if (bitmap_fd < 0) {
- pr_err("%s cannot be openned.",
- s->bitmap_file);
- goto abort;
- }
+ bitmapsize = s->size >> 9; /* FIXME wrong for RAID10 */
+ if (CreateBitmap(s->bitmap_file, 1, NULL,
+ s->bitmap_chunk, c->delay,
+ s->write_behind, bitmapsize, major)) {
+ goto abort;
}
- if (bitmap_fd >= 0) {
- if (ioctl(mdfd, SET_BITMAP_FILE, bitmap_fd) < 0) {
- pr_err("Cannot set bitmap file for %s: %s\n",
- mddev, strerror(errno));
- goto abort;
- }
+ bitmap_fd = open(s->bitmap_file, O_RDWR);
+ if (bitmap_fd < 0) {
+ pr_err("%s cannot be openned.", s->bitmap_file);
+ goto abort;
}
}
- if (ioctl(mdfd, RUN_ARRAY, &param)) {
- pr_err("RUN_ARRAY failed: %s\n",
- strerror(errno));
- if (s->chunk & (s->chunk-1)) {
- cont_err("Problem may be that chunk size is not a power of 2\n");
+ if (bitmap_fd >= 0) {
+ if (ioctl(mdfd, SET_BITMAP_FILE, bitmap_fd) < 0) {
+ pr_err("Cannot set bitmap file for %s: %s\n",
+ mddev, strerror(errno));
+ goto abort;
}
- goto abort;
- }
- } else {
- unsigned long arg;
- arg=0;
- while (s->chunk > 4096) {
- arg++;
- s->chunk >>= 1;
}
- if (s->level == 0)
- arg |= 0x20000;
- else
- arg |= 0x10000;
- if (ioctl(mdfd, START_MD, arg)) {
- pr_err("START_MD failed: %s\n",
- strerror(errno));
- goto abort;
+ }
+ if (ioctl(mdfd, RUN_ARRAY, &param)) {
+ pr_err("RUN_ARRAY failed: %s\n", strerror(errno));
+ if (s->chunk & (s->chunk - 1)) {
+ cont_err("Problem may be that chunk size is not a power of 2\n");
}
+ goto abort;
}
+
if (c->verbose >= 0)
pr_err("array %s built and started.\n",
mddev);
@@ -287,10 +241,7 @@ int Build(char *mddev, struct mddev_dev *devlist,
return 0;
abort:
- if (vers >= 9000)
- ioctl(mdfd, STOP_ARRAY, 0);
- else
- ioctl(mdfd, STOP_MD, 0);
+ ioctl(mdfd, STOP_ARRAY, 0);
close(mdfd);
return 1;
}
--
2.7.4

39
SOURCES/Correct-examine-output-for-4kdisks.patch

@ -0,0 +1,39 @@ @@ -0,0 +1,39 @@
commit 84918897ee8bb450ea09f7c95b9da44df8e925e4
Author: Maksymilian Kunt <maksymilian.kunt@intel.com>
Date: Tue May 9 14:03:27 2017 +0200

IMSM: Correct --examine output for 4k disks
"Array Size" and "Per Dev Size" are incorrect for disks with sector size
different than 512B.
Calculate "Array Size" and "Per Dev Size" based on sector size. Additionally
print "Sector Size".
Signed-off-by: Maksymilian Kunt <maksymilian.kunt@intel.com>
Signed-off-by: Mariusz Dabrowski <mariusz.dabrowski@intel.com>
Signed-off-by: Jes Sorensen <jsorensen@fb.com>

diff --git a/super-intel.c b/super-intel.c
index ba6f810..8ca80d3 100644
--- a/super-intel.c
+++ b/super-intel.c
@@ -1482,13 +1482,16 @@ static void print_imsm_dev(struct intel_super *super,
ord & IMSM_ORD_REBUILD ? " (out-of-sync)" : "");
} else
printf(" This Slot : ?\n");
+ printf(" Sector Size : %u\n", super->sector_size);
sz = __le32_to_cpu(dev->size_high);
sz <<= 32;
sz += __le32_to_cpu(dev->size_low);
- printf(" Array Size : %llu%s\n", (unsigned long long)sz,
+ printf(" Array Size : %llu%s\n",
+ (unsigned long long)sz * 512 / super->sector_size,
human_size(sz * 512));
sz = blocks_per_member(map);
- printf(" Per Dev Size : %llu%s\n", (unsigned long long)sz,
+ printf(" Per Dev Size : %llu%s\n",
+ (unsigned long long)sz * 512 / super->sector_size,
human_size(sz * 512));
printf(" Sector Offset : %llu\n",
pba_of_lba0(map));

76
SOURCES/Create-Fixup-bad-placement-of-logical-in-multi-line-.patch

@ -0,0 +1,76 @@ @@ -0,0 +1,76 @@
From cf622ec1d81a5bb3f882922667bac494b3a16581 Mon Sep 17 00:00:00 2001
From: Jes Sorensen <Jes.Sorensen@gmail.com>
Date: Wed, 5 Apr 2017 11:53:12 -0400
Subject: [RHEL7.5 PATCH 050/169] Create: Fixup bad placement of logical ||
&& in multi-line if statements

These always go at the end of the line, never at the front

Signed-off-by: Jes Sorensen <Jes.Sorensen@gmail.com>
---
Create.c | 28 +++++++++++-----------------
1 file changed, 11 insertions(+), 17 deletions(-)

diff --git a/Create.c b/Create.c
index ba24606..17333ce 100644
--- a/Create.c
+++ b/Create.c
@@ -457,8 +457,8 @@ int Create(struct supertype *st, char *mddev,
st->minor_version >= 1)
/* metadata at front */
warn |= check_partitions(fd, dname, 0, 0);
- else if (s->level == 1 || s->level == LEVEL_CONTAINER
- || (s->level == 0 && s->raiddisks == 1))
+ else if (s->level == 1 || s->level == LEVEL_CONTAINER ||
+ (s->level == 0 && s->raiddisks == 1))
/* partitions could be meaningful */
warn |= check_partitions(fd, dname, freesize*2, s->size*2);
else
@@ -495,9 +495,8 @@ int Create(struct supertype *st, char *mddev,
pr_err("no size and no drives given - aborting create.\n");
return 1;
}
- if (s->level > 0 || s->level == LEVEL_MULTIPATH
- || s->level == LEVEL_FAULTY
- || st->ss->external ) {
+ if (s->level > 0 || s->level == LEVEL_MULTIPATH ||
+ s->level == LEVEL_FAULTY || st->ss->external ) {
/* size is meaningful */
if (!st->ss->validate_geometry(st, s->level, s->layout,
s->raiddisks,
@@ -616,8 +615,8 @@ int Create(struct supertype *st, char *mddev,
* it could be in conflict with already existing device
* e.g. container, array
*/
- if (strncmp(chosen_name, "/dev/md/", 8) == 0
- && map_by_name(&map, chosen_name+8) != NULL) {
+ if (strncmp(chosen_name, "/dev/md/", 8) == 0 &&
+ map_by_name(&map, chosen_name+8) != NULL) {
pr_err("Array name %s is in use already.\n",
chosen_name);
close(mdfd);
@@ -653,16 +652,11 @@ int Create(struct supertype *st, char *mddev,
info.array.md_minor = minor(stb.st_rdev);
info.array.not_persistent = 0;
- if ( ( (s->level == 4 || s->level == 5) &&
- (insert_point < s->raiddisks || first_missing < s->raiddisks) )
- ||
- ( s->level == 6 && (insert_point < s->raiddisks
- || second_missing < s->raiddisks))
- ||
- ( s->level <= 0 )
- ||
- s->assume_clean
- ) {
+ if (((s->level == 4 || s->level == 5) &&
+ (insert_point < s->raiddisks || first_missing < s->raiddisks)) ||
+ (s->level == 6 && (insert_point < s->raiddisks ||
+ second_missing < s->raiddisks)) ||
+ (s->level <= 0) || s->assume_clean) {
info.array.state = 1; /* clean, but one+ drive will be missing*/
info.resync_start = MaxSector;
} else {
--
2.7.4

167
SOURCES/Create-Fixup-various-whitespace-issues1.patch

@ -0,0 +1,167 @@ @@ -0,0 +1,167 @@
From 98dbf73cba81cd846f9c706f37edc22e21038cf4 Mon Sep 17 00:00:00 2001
From: Jes Sorensen <Jes.Sorensen@gmail.com>
Date: Wed, 5 Apr 2017 11:57:30 -0400
Subject: [RHEL7.5 PATCH 051/169] Create: Fixup various whitespace issues

Signed-off-by: Jes Sorensen <Jes.Sorensen@gmail.com>
---
Create.c | 50 ++++++++++++++++++++++++--------------------------
1 file changed, 24 insertions(+), 26 deletions(-)

diff --git a/Create.c b/Create.c
index 17333ce..4f98c58 100644
--- a/Create.c
+++ b/Create.c
@@ -84,12 +84,12 @@ int Create(struct supertype *st, char *mddev,
* RUN_ARRAY
*/
int mdfd;
- unsigned long long minsize=0, maxsize=0;
+ unsigned long long minsize = 0, maxsize = 0;
char *mindisc = NULL;
char *maxdisc = NULL;
int dnum, raid_disk_num;
struct mddev_dev *dv;
- int fail=0, warn=0;
+ int fail = 0, warn = 0;
struct stat stb;
int first_missing = subdevs * 2;
int second_missing = subdevs * 2;
@@ -259,7 +259,7 @@ int Create(struct supertype *st, char *mddev,
&s->chunk, s->size*2,
data_offset, NULL,
&newsize, s->consistency_policy,
- c->verbose>=0))
+ c->verbose >= 0))
return 1;
if (s->chunk && s->chunk != UnSet) {
@@ -290,7 +290,7 @@ int Create(struct supertype *st, char *mddev,
info.array.active_disks = 0;
info.array.working_disks = 0;
dnum = 0;
- for (dv = devlist; dv ; dv = dv->next)
+ for (dv = devlist; dv; dv = dv->next)
if (data_offset == VARIABLE_OFFSET)
dv->data_offset = INVALID_SECTORS;
else
@@ -302,7 +302,7 @@ int Create(struct supertype *st, char *mddev,
int dfd;
char *doff;
- if (strcasecmp(dname, "missing")==0) {
+ if (strcasecmp(dname, "missing") == 0) {
if (first_missing > dnum)
first_missing = dnum;
if (second_missing > dnum && dnum > first_missing)
@@ -348,7 +348,7 @@ int Create(struct supertype *st, char *mddev,
*/
int i;
char *name = "default";
- for(i=0; !st && superlist[i]; i++) {
+ for(i = 0; !st && superlist[i]; i++) {
st = superlist[i]->match_metadata_desc(name);
if (!st)
continue;
@@ -444,10 +444,10 @@ int Create(struct supertype *st, char *mddev,
skip_size_check:
if (c->runstop != 1 || c->verbose >= 0) {
int fd = open(dname, O_RDONLY);
- if (fd <0 ) {
+ if (fd < 0) {
pr_err("Cannot open %s: %s\n",
dname, strerror(errno));
- fail=1;
+ fail = 1;
continue;
}
warn |= check_ext2(fd, dname);
@@ -496,7 +496,7 @@ int Create(struct supertype *st, char *mddev,
return 1;
}
if (s->level > 0 || s->level == LEVEL_MULTIPATH ||
- s->level == LEVEL_FAULTY || st->ss->external ) {
+ s->level == LEVEL_FAULTY || st->ss->external) {
/* size is meaningful */
if (!st->ss->validate_geometry(st, s->level, s->layout,
s->raiddisks,
@@ -571,9 +571,9 @@ int Create(struct supertype *st, char *mddev,
* as missing, so that a reconstruct happens (faster than re-parity)
* FIX: Can we do this for raid6 as well?
*/
- if (st->ss->external == 0 &&
- s->assume_clean==0 && c->force == 0 && first_missing >= s->raiddisks) {
- switch ( s->level ) {
+ if (st->ss->external == 0 && s->assume_clean == 0 &&
+ c->force == 0 && first_missing >= s->raiddisks) {
+ switch (s->level) {
case 4:
case 5:
insert_point = s->raiddisks-1;
@@ -648,7 +648,7 @@ int Create(struct supertype *st, char *mddev,
* with, but it chooses to trust me instead. Sigh
*/
info.array.md_minor = 0;
- if (fstat(mdfd, &stb)==0)
+ if (fstat(mdfd, &stb) == 0)
info.array.md_minor = minor(stb.st_rdev);
info.array.not_persistent = 0;
@@ -714,13 +714,11 @@ int Create(struct supertype *st, char *mddev,
name = strrchr(mddev, '/');
if (name) {
name++;
- if (strncmp(name, "md_", 3)==0 &&
- strlen(name) > 3 &&
- (name-mddev) == 5 /* /dev/ */)
+ if (strncmp(name, "md_", 3) == 0 &&
+ strlen(name) > 3 && (name-mddev) == 5 /* /dev/ */)
name += 3;
- else if (strncmp(name, "md", 2)==0 &&
- strlen(name) > 2 &&
- isdigit(name[2]) &&
+ else if (strncmp(name, "md", 2) == 0 &&
+ strlen(name) > 2 && isdigit(name[2]) &&
(name-mddev) == 5 /* /dev/ */)
name += 2;
}
@@ -771,9 +769,9 @@ int Create(struct supertype *st, char *mddev,
#endif
}
- if (s->bitmap_file && (strcmp(s->bitmap_file, "internal")==0 ||
- strcmp(s->bitmap_file, "clustered")==0)) {
- if ((vers%100) < 2) {
+ if (s->bitmap_file && (strcmp(s->bitmap_file, "internal") == 0 ||
+ strcmp(s->bitmap_file, "clustered") == 0)) {
+ if ((vers % 100) < 2) {
pr_err("internal bitmaps not supported by this kernel.\n");
goto abort_locked;
}
@@ -856,11 +854,11 @@ int Create(struct supertype *st, char *mddev,
infos = xmalloc(sizeof(*infos) * total_slots);
enable_fds(total_slots);
- for (pass=1; pass <=2 ; pass++) {
+ for (pass = 1; pass <= 2; pass++) {
struct mddev_dev *moved_disk = NULL; /* the disk that was moved out of the insert point */
- for (dnum=0, raid_disk_num=0, dv = devlist ; dv ;
- dv=(dv->next)?(dv->next):moved_disk, dnum++) {
+ for (dnum = 0, raid_disk_num = 0, dv = devlist; dv;
+ dv = (dv->next) ? (dv->next) : moved_disk, dnum++) {
int fd;
struct stat stb2;
struct mdinfo *inf = &infos[dnum];
@@ -872,7 +870,7 @@ int Create(struct supertype *st, char *mddev,
moved_disk = dv;
continue;
}
- if (strcasecmp(dv->devname, "missing")==0) {
+ if (strcasecmp(dv->devname, "missing") == 0) {
raid_disk_num += 1;
continue;
}
--
2.7.4

88
SOURCES/Create-Remove-all-attemps-to-handle-md-driver-older-.patch

@ -0,0 +1,88 @@ @@ -0,0 +1,88 @@
From 5f4cc2392689528a9234fae1935cd442f7917738 Mon Sep 17 00:00:00 2001
From: Jes Sorensen <Jes.Sorensen@gmail.com>
Date: Wed, 5 Apr 2017 15:32:40 -0400
Subject: [RHEL7.5 PATCH 058/169] Create: Remove all attemps to handle md
driver older than 0.90.03

More legacy code moved to the bit-bucket.

Signed-off-by: Jes Sorensen <Jes.Sorensen@gmail.com>
---
Create.c | 30 +++++-------------------------
1 file changed, 5 insertions(+), 25 deletions(-)

diff --git a/Create.c b/Create.c
index 4f98c58..6ca0924 100644
--- a/Create.c
+++ b/Create.c
@@ -97,7 +97,6 @@ int Create(struct supertype *st, char *mddev,
int insert_point = subdevs * 2; /* where to insert a missing drive */
int total_slots;
int pass;
- int vers;
int rv;
int bitmap_fd;
int have_container = 0;
@@ -112,6 +111,7 @@ int Create(struct supertype *st, char *mddev,
char chosen_name[1024];
struct map_ent *map = NULL;
unsigned long long newsize;
+ mdu_array_info_t inf;
int major_num = BITMAP_MAJOR_HI;
if (s->bitmap_file && strcmp(s->bitmap_file, "clustered") == 0) {
@@ -150,7 +150,6 @@ int Create(struct supertype *st, char *mddev,
/* If given a single device, it might be a container, and we can
* extract a device list from there
*/
- mdu_array_info_t inf;
int fd;
memset(&inf, 0, sizeof(inf));
@@ -625,18 +624,11 @@ int Create(struct supertype *st, char *mddev,
}
mddev = chosen_name;
- vers = md_get_version(mdfd);
- if (vers < 9000) {
- pr_err("Create requires md driver version 0.90.0 or later\n");
+ memset(&inf, 0, sizeof(inf));
+ md_get_array_info(mdfd, &inf);
+ if (inf.working_disks != 0) {
+ pr_err("another array by this name is already running.\n");
goto abort_locked;
- } else {
- mdu_array_info_t inf;
- memset(&inf, 0, sizeof(inf));
- md_get_array_info(mdfd, &inf);
- if (inf.working_disks != 0) {
- pr_err("another array by this name is already running.\n");
- goto abort_locked;
- }
}
/* Ok, lets try some ioctls */
@@ -761,20 +753,8 @@ int Create(struct supertype *st, char *mddev,
* to stop another mdadm from finding and using those devices.
*/
- if (s->bitmap_file && vers < 9003) {
- major_num = BITMAP_MAJOR_HOSTENDIAN;
-#ifdef __BIG_ENDIAN
- pr_err("Warning - bitmaps created on this kernel are not portable\n"
- " between different architectured. Consider upgrading the Linux kernel.\n");
-#endif
- }
-
if (s->bitmap_file && (strcmp(s->bitmap_file, "internal") == 0 ||
strcmp(s->bitmap_file, "clustered") == 0)) {
- if ((vers % 100) < 2) {
- pr_err("internal bitmaps not supported by this kernel.\n");
- goto abort_locked;
- }
if (!st->ss->add_internal_bitmap) {
pr_err("internal bitmaps not supported with %s metadata\n",
st->ss->name);
--
2.7.4

311
SOURCES/Create-tell-udev-md-device-is-not-ready-when-first-c.patch

@ -0,0 +1,311 @@ @@ -0,0 +1,311 @@
From cd6cbb08c458cee07acb1d854e04532b29ec87bf Mon Sep 17 00:00:00 2001
From: NeilBrown <neilb@suse.com>
Date: Fri, 28 Apr 2017 15:05:50 +1000
Subject: [RHEL7.5 PATCH 100/169] Create: tell udev md device is not ready
when first created.

When an array is created the content is not initialized,
so it could have remnants of an old filesystem or md array
etc on it.
udev will see this and might try to activate it, which is almost
certainly not what is wanted.

So create a mechanism for mdadm to communicate with udev to tell
it that the device isn't ready. This mechanism is the existance
of a file /run/mdadm/created-mdXXX where mdXXX is the md device name.

When creating an array, mdadm will create the file.
A new udev rule file, 01-md-raid-creating.rules, will detect the
precense of thst file and set ENV{SYSTEMD_READY}="0".
This is fairly uniformly used to suppress actions based on the
contents of the device.

Signed-off-by: NeilBrown <neilb@suse.com>
Signed-off-by: Jes Sorensen <jsorensen@fb.com>
---
Assemble.c | 2 +-
Build.c | 2 +-
Create.c | 9 +++++++-
Incremental.c | 4 ++--
Makefile | 4 ++--
lib.c | 29 +++++++++++++++++++++++++
mdadm.h | 4 +++-
mdopen.c | 52 ++++++++++++++++++++++++++++-----------------
udev-md-raid-creating.rules | 7 ++++++
9 files changed, 86 insertions(+), 27 deletions(-)
create mode 100644 udev-md-raid-creating.rules

diff --git a/Assemble.c b/Assemble.c
index d6beb23..a9442c8 100644
--- a/Assemble.c
+++ b/Assemble.c
@@ -1478,7 +1478,7 @@ try_again:
name = strchr(name, ':')+1;
mdfd = create_mddev(mddev, name, ident->autof, trustworthy,
- chosen_name);
+ chosen_name, 0);
}
if (mdfd < 0) {
st->ss->free_super(st);
diff --git a/Build.c b/Build.c
index 11ba12f..665d906 100644
--- a/Build.c
+++ b/Build.c
@@ -109,7 +109,7 @@ int Build(char *mddev, struct mddev_dev *devlist,
/* We need to create the device. It can have no name. */
map_lock(&map);
mdfd = create_mddev(mddev, NULL, c->autof, LOCAL,
- chosen_name);
+ chosen_name, 0);
if (mdfd < 0) {
map_unlock(&map);
return 1;
diff --git a/Create.c b/Create.c
index 6ca0924..df1bc20 100644
--- a/Create.c
+++ b/Create.c
@@ -605,7 +605,7 @@ int Create(struct supertype *st, char *mddev,
/* We need to create the device */
map_lock(&map);
- mdfd = create_mddev(mddev, name, c->autof, LOCAL, chosen_name);
+ mdfd = create_mddev(mddev, name, c->autof, LOCAL, chosen_name, 1);
if (mdfd < 0) {
map_unlock(&map);
return 1;
@@ -620,6 +620,7 @@ int Create(struct supertype *st, char *mddev,
chosen_name);
close(mdfd);
map_unlock(&map);
+ udev_unblock();
return 1;
}
mddev = chosen_name;
@@ -1053,9 +1054,15 @@ int Create(struct supertype *st, char *mddev,
pr_err("not starting array - not enough devices.\n");
}
close(mdfd);
+ /* Give udev a moment to process the Change event caused
+ * by the close.
+ */
+ usleep(100*1000);
+ udev_unblock();
return 0;
abort:
+ udev_unblock();
map_lock(&map);
abort_locked:
map_remove(&map, fd2devnm(mdfd));
diff --git a/Incremental.c b/Incremental.c
index 66c5b03..4789e36 100644
--- a/Incremental.c
+++ b/Incremental.c
@@ -320,7 +320,7 @@ int Incremental(struct mddev_dev *devlist, struct context *c,
/* Couldn't find an existing array, maybe make a new one */
mdfd = create_mddev(match ? match->devname : NULL,
- name_to_use, c->autof, trustworthy, chosen_name);
+ name_to_use, c->autof, trustworthy, chosen_name, 0);
if (mdfd < 0)
goto out_unlock;
@@ -1596,7 +1596,7 @@ static int Incremental_container(struct supertype *st, char *devname,
ra->name,
c->autof,
trustworthy,
- chosen_name);
+ chosen_name, 0);
}
if (only && (!mp || strcmp(mp->devnm, only) != 0))
continue;
diff --git a/Makefile b/Makefile
index 6850696..021d3ad 100644
--- a/Makefile
+++ b/Makefile
@@ -256,8 +256,8 @@ install-man: mdadm.8 md.4 mdadm.conf.5 mdmon.8
$(INSTALL) -D -m 644 md.4 $(DESTDIR)$(MAN4DIR)/md.4
$(INSTALL) -D -m 644 mdadm.conf.5 $(DESTDIR)$(MAN5DIR)/mdadm.conf.5
-install-udev: udev-md-raid-arrays.rules udev-md-raid-assembly.rules
- @for file in 63-md-raid-arrays.rules 64-md-raid-assembly.rules ; \
+install-udev: udev-md-raid-arrays.rules udev-md-raid-assembly.rules udev-md-raid-creating.rules
+ @for file in 01-md-raid-creating.rules 63-md-raid-arrays.rules 64-md-raid-assembly.rules ; \
do sed -e 's,BINDIR,$(BINDIR),g' udev-$${file#??-} > .install.tmp.1 && \
$(ECHO) $(INSTALL) -D -m 644 udev-$${file#??-} $(DESTDIR)$(UDEVDIR)/rules.d/$$file ; \
$(INSTALL) -D -m 644 .install.tmp.1 $(DESTDIR)$(UDEVDIR)/rules.d/$$file ; \
diff --git a/lib.c b/lib.c
index b640634..7e44b1f 100644
--- a/lib.c
+++ b/lib.c
@@ -163,6 +163,35 @@ char *fd2devnm(int fd)
return NULL;
}
+/* When we create a new array, we don't want the content to
+ * be immediately examined by udev - it is probably meaningless.
+ * So create /run/mdadm/creating-FOO and expect that a udev
+ * rule will noticed this and act accordingly.
+ */
+static char block_path[] = "/run/mdadm/creating-%s";
+static char *unblock_path = NULL;
+void udev_block(char *devnm)
+{
+ int fd;
+ char *path = NULL;
+
+ xasprintf(&path, block_path, devnm);
+ fd = open(path, O_CREAT|O_RDWR, 0600);
+ if (fd >= 0) {
+ close(fd);
+ unblock_path = path;
+ } else
+ free(path);
+}
+
+void udev_unblock(void)
+{
+ if (unblock_path)
+ unlink(unblock_path);
+ free(unblock_path);
+ unblock_path = NULL;
+}
+
/*
* convert a major/minor pair for a block device into a name in /dev, if possible.
* On the first call, walk /dev collecting name.
diff --git a/mdadm.h b/mdadm.h
index 1bbacfe..6a382a7 100644
--- a/mdadm.h
+++ b/mdadm.h
@@ -1533,7 +1533,7 @@ extern char *get_md_name(char *devnm);
extern char DefaultConfFile[];
extern int create_mddev(char *dev, char *name, int autof, int trustworthy,
- char *chosen);
+ char *chosen, int block_udev);
/* values for 'trustworthy' */
#define LOCAL 1
#define LOCAL_ANY 10
@@ -1567,6 +1567,8 @@ extern char *stat2kname(struct stat *st);
extern char *fd2kname(int fd);
extern char *stat2devnm(struct stat *st);
extern char *fd2devnm(int fd);
+extern void udev_block(char *devnm);
+extern void udev_unblock(void);
extern int in_initrd(void);
diff --git a/mdopen.c b/mdopen.c
index 82b97fc..099efa0 100644
--- a/mdopen.c
+++ b/mdopen.c
@@ -135,7 +135,7 @@ void make_parts(char *dev, int cnt)
*/
int create_mddev(char *dev, char *name, int autof, int trustworthy,
- char *chosen)
+ char *chosen, int block_udev)
{
int mdfd;
struct stat stb;
@@ -147,6 +147,10 @@ int create_mddev(char *dev, char *name, int autof, int trustworthy,
char devname[37];
char devnm[32];
char cbuf[400];
+
+ if (!use_udev())
+ block_udev = 0;
+
if (chosen == NULL)
chosen = cbuf;
@@ -305,43 +309,53 @@ int create_mddev(char *dev, char *name, int autof, int trustworthy,
int fd;
int n = -1;
sprintf(devnm, "md_%s", cname);
+ if (block_udev)
+ udev_block(devnm);
fd = open("/sys/module/md_mod/parameters/new_array", O_WRONLY);
if (fd >= 0) {
n = write(fd, devnm, strlen(devnm));
close(fd);
}
- if (n < 0)
+ if (n < 0) {
devnm[0] = 0;
+ udev_unblock();
+ }
}
if (num >= 0) {
int fd;
int n = -1;
sprintf(devnm, "md%d", num);
+ if (block_udev)
+ udev_block(devnm);
fd = open("/sys/module/md_mod/parameters/new_array", O_WRONLY);
if (fd >= 0) {
n = write(fd, devnm, strlen(devnm));
close(fd);
}
- if (n < 0)
+ if (n < 0) {
devnm[0] = 0;
- }
- if (devnm[0])
- ;
- else if (num < 0) {
- /* need to choose a free number. */
- char *_devnm = find_free_devnm(use_mdp);
- if (_devnm == NULL) {
- pr_err("No avail md devices - aborting\n");
- return -1;
+ udev_unblock();
}
- strcpy(devnm, _devnm);
- } else {
- sprintf(devnm, "%s%d", use_mdp?"md_d":"md", num);
- if (mddev_busy(devnm)) {
- pr_err("%s is already in use.\n",
- dev);
- return -1;
+ }
+ if (devnm[0] == 0) {
+ if (num < 0) {
+ /* need to choose a free number. */
+ char *_devnm = find_free_devnm(use_mdp);
+ if (_devnm == NULL) {
+ pr_err("No avail md devices - aborting\n");
+ return -1;
+ }
+ strcpy(devnm, _devnm);
+ } else {
+ sprintf(devnm, "%s%d", use_mdp?"md_d":"md", num);
+ if (mddev_busy(devnm)) {
+ pr_err("%s is already in use.\n",
+ dev);
+ return -1;
+ }
}
+ if (block_udev)
+ udev_block(devnm);
}
sprintf(devname, "/dev/%s", devnm);
diff --git a/udev-md-raid-creating.rules b/udev-md-raid-creating.rules
new file mode 100644
index 0000000..2be466b
--- /dev/null
+++ b/udev-md-raid-creating.rules
@@ -0,0 +1,7 @@
+# do not edit this file, it will be overwritten on update
+# While mdadm is creating an array, it creates a file
+# /run/mdadm/creating-mdXXX. If that file exists, then
+# the array is not "ready" and we should make sure the
+# content is ignored.
+
+KERNEL=="md*", TEST="/run/mdadm/creating-$kernel", ENV{SYSTEMD_READY}="0"
--
2.7.4

38
SOURCES/Detail-Fixup-ugly-if-foo-abuse.patch

@ -0,0 +1,38 @@ @@ -0,0 +1,38 @@
From 776b199e41d10e344efc47008366ca46715c5acc Mon Sep 17 00:00:00 2001
From: Jes Sorensen <jsorensen@fb.com>
Date: Wed, 12 Apr 2017 17:05:55 -0400
Subject: [RHEL7.5 PATCH 078/169] Detail: Fixup ugly if () foo() abuse

Cosmetic change only

Signed-off-by: Jes Sorensen <jsorensen@fb.com>
---
Detail.c | 8 +++++---
1 file changed, 5 insertions(+), 3 deletions(-)

diff --git a/Detail.c b/Detail.c
index 8f74832..e40cd8f 100644
--- a/Detail.c
+++ b/Detail.c
@@ -141,13 +141,15 @@ int Detail(char *dev, struct context *c)
}
/* try to load a superblock. Try sra->devs first, then try ioctl */
- if (st && !info) for (d = 0, subdev = sra ? sra->devs : NULL;
- d < max_disks || subdev;
- subdev ? (void)(subdev = subdev->next) : (void)(d++)){
+ if (st && !info)
+ for (d = 0, subdev = sra ? sra->devs : NULL;
+ d < max_disks || subdev;
+ subdev ? (void)(subdev = subdev->next) : (void)(d++)){
mdu_disk_info_t disk;
char *dv;
int fd2;
int err;
+
if (subdev)
disk = subdev->disk;
else {
--
2.7.4

37
SOURCES/Detail-Reinstate-support-for-not-having-sysfs.patch

@ -0,0 +1,37 @@ @@ -0,0 +1,37 @@
From 0885b942b3575c7f2a8290087751d83902587371 Mon Sep 17 00:00:00 2001
From: Jes Sorensen <jsorensen@fb.com>
Date: Tue, 25 Apr 2017 14:34:31 -0400
Subject: [RHEL7.5 PATCH 097/169] Detail: Reinstate support for not having
sysfs

While sysfs support will hopefully go away eventually, lets not break
it unnecessarily for now.

Fixes: 901d5ee ("Detail: Stop bothering about md drivers older than 0.90.00")
Signed-off-by: Jes Sorensen <jsorensen@fb.com>
---
Detail.c | 8 +++++---
1 file changed, 5 insertions(+), 3 deletions(-)

diff --git a/Detail.c b/Detail.c
index ceb21b1..ef2370c 100644
--- a/Detail.c
+++ b/Detail.c
@@ -88,9 +88,11 @@ int Detail(char *dev, struct context *c)
}
sra = sysfs_read(fd, NULL, GET_VERSION | GET_DEVS | GET_ARRAY_STATE);
if (!sra) {
- pr_err("%s does not appear to be an md device\n", dev);
- close(fd);
- return rv;
+ if (md_get_array_info(fd, &array)) {
+ pr_err("%s does not appear to be an md device\n", dev);
+ close(fd);
+ return rv;
+ }
}
external = (sra != NULL && sra->array.major_version == -1 &&
sra->array.minor_version == -2);
--
2.7.4

61
SOURCES/Detail-Remove-pre-2.6-code-for-printing-info-on-rebu.patch

@ -0,0 +1,61 @@ @@ -0,0 +1,61 @@
From 5e13ef714df4734c455b5e4389352c8ab7902038 Mon Sep 17 00:00:00 2001
From: Jes Sorensen <jsorensen@fb.com>
Date: Wed, 12 Apr 2017 14:48:10 -0400
Subject: [RHEL7.5 PATCH 076/169] Detail: Remove pre-2.6 code for printing
info on rebuilding

Since we no longer support anything pre-2.6.15, there is no point in
keeping this around.

Signed-off-by: Jes Sorensen <jsorensen@fb.com>
---
Detail.c | 19 +++----------------
1 file changed, 3 insertions(+), 16 deletions(-)

diff --git a/Detail.c b/Detail.c
index d4e6204..8f74832 100644
--- a/Detail.c
+++ b/Detail.c
@@ -64,8 +64,6 @@ int Detail(char *dev, struct context *c)
int max_devices = 0, n_devices = 0;
int spares = 0;
struct stat stb;
- int is_26 = get_linux_version() >= 2006000;
- int is_rebuilding = 0;
int failed = 0;
struct supertype *st;
char *subarray = NULL;
@@ -527,7 +525,6 @@ int Detail(char *dev, struct context *c)
"Reshape", "Check"};
printf(" %7s Status : %d%% complete\n",
sync_action[e->resync], e->percent);
- is_rebuilding = 1;
}
free_mdstat(ms);
@@ -676,19 +673,9 @@ This is pretty boring
|(1<<MD_DISK_REMOVED)|(1<<MD_DISK_FAULTY)|(1<<MD_DISK_JOURNAL)))
== 0) {
printf(" spare");
- if (is_26) {
- if (disk.raid_disk < array.raid_disks && disk.raid_disk >= 0)
- printf(" rebuilding");
- } else if (is_rebuilding && failed) {
- /* Taking a bit of a risk here, we remove the
- * device from the array, and then put it back.
- * If this fails, we are rebuilding
- */
- int err = ioctl(fd, HOT_REMOVE_DISK, makedev(disk.major, disk.minor));
- if (err == 0) ioctl(fd, HOT_ADD_DISK, makedev(disk.major, disk.minor));
- if (err && errno == EBUSY)
- printf(" rebuilding");
- }
+ if (disk.raid_disk < array.raid_disks &&
+ disk.raid_disk >= 0)
+ printf(" rebuilding");
}
}
if (disk.state == 0) spares++;
--
2.7.4

521
SOURCES/Detail-Respect-code-lines-are-80-character-wide.patch

@ -0,0 +1,521 @@ @@ -0,0 +1,521 @@
From 5737086ed7a39e4d940ed1459d1afad359c3182c Mon Sep 17 00:00:00 2001
From: Jes Sorensen <jsorensen@fb.com>
Date: Tue, 25 Apr 2017 12:21:39 -0400
Subject: [RHEL7.5 PATCH 096/169] Detail: Respect code lines are 80
character wide

In addition apply spaces and don'f do 'if () action()' on the same line.

Signed-off-by: Jes Sorensen <jsorensen@fb.com>
---
Detail.c | 239 ++++++++++++++++++++++++++++++++++++---------------------------
1 file changed, 138 insertions(+), 101 deletions(-)

diff --git a/Detail.c b/Detail.c
index eb69276..ceb21b1 100644
--- a/Detail.c
+++ b/Detail.c
@@ -157,8 +157,7 @@ int Detail(char *dev, struct context *c)
if (md_get_disk_info(fd, &disk) < 0)
continue;
if (d >= array.raid_disks &&
- disk.major == 0 &&
- disk.minor == 0)
+ disk.major == 0 && disk.minor == 0)
continue;
}
@@ -236,7 +235,8 @@ int Detail(char *dev, struct context *c)
printf("MD_METADATA=%s\n", sra->text_version);
else
printf("MD_METADATA=%d.%d\n",
- array.major_version, array.minor_version);
+ array.major_version,
+ array.minor_version);
}
if (st && st->sb && info) {
@@ -244,12 +244,12 @@ int Detail(char *dev, struct context *c)
struct map_ent *mp, *map = NULL;
fname_from_uuid(st, info, nbuf, ':');
- printf("MD_UUID=%s\n", nbuf+5);
+ printf("MD_UUID=%s\n", nbuf + 5);
mp = map_by_uuid(&map, info->uuid);
if (mp && mp->path &&
strncmp(mp->path, "/dev/md/", 8) == 0) {
printf("MD_DEVNAME=");
- print_escape(mp->path+8);
+ print_escape(mp->path + 8);
putchar('\n');
}
@@ -273,11 +273,12 @@ int Detail(char *dev, struct context *c)
if (sra) {
struct mdinfo *mdi;
for (mdi = sra->devs; mdi; mdi = mdi->next) {
- char *path =
- map_dev(mdi->disk.major,
- mdi->disk.minor, 0);
+ char *path;
char *sysdev = xstrdup(mdi->sys_name + 1);
char *cp;
+
+ path = map_dev(mdi->disk.major,
+ mdi->disk.minor, 0);
for (cp = sysdev; *cp; cp++)
if (!isalnum(*cp))
*cp = '_';
@@ -299,19 +300,19 @@ int Detail(char *dev, struct context *c)
disks = xmalloc(max_disks * 2 * sizeof(mdu_disk_info_t));
for (d = 0; d < max_disks * 2; d++) {
- disks[d].state = (1<<MD_DISK_REMOVED);
+ disks[d].state = (1 << MD_DISK_REMOVED);
disks[d].major = disks[d].minor = 0;
disks[d].number = -1;
- disks[d].raid_disk = d/2;
+ disks[d].raid_disk = d / 2;
}
- next = array.raid_disks*2;
+ next = array.raid_disks * 2;
if (inactive) {
struct mdinfo *mdi;
if (sra != NULL)
for (mdi = sra->devs; mdi; mdi = mdi->next) {
disks[next++] = mdi->disk;
- disks[next-1].number = -1;
+ disks[next - 1].number = -1;
}
} else for (d = 0; d < max_disks; d++) {
mdu_disk_info_t disk;
@@ -324,21 +325,23 @@ int Detail(char *dev, struct context *c)
}
if (disk.major == 0 && disk.minor == 0)
continue;
- if (disk.raid_disk >= 0 && disk.raid_disk < array.raid_disks
- && disks[disk.raid_disk*2].state == (1<<MD_DISK_REMOVED)
- && ((disk.state & (1<<MD_DISK_JOURNAL)) == 0))
- disks[disk.raid_disk*2] = disk;
- else if (disk.raid_disk >= 0 && disk.raid_disk < array.raid_disks
- && disks[disk.raid_disk*2+1].state == (1<<MD_DISK_REMOVED)
- && !(disk.state & (1<<MD_DISK_JOURNAL)))
- disks[disk.raid_disk*2+1] = disk;
- else if (next < max_disks*2)
+ if (disk.raid_disk >= 0 && disk.raid_disk < array.raid_disks &&
+ disks[disk.raid_disk * 2].state == (1 << MD_DISK_REMOVED) &&
+ ((disk.state & (1 << MD_DISK_JOURNAL)) == 0))
+ disks[disk.raid_disk * 2] = disk;
+ else if (disk.raid_disk >= 0 &&
+ disk.raid_disk < array.raid_disks &&
+ disks[disk.raid_disk * 2 + 1].state ==
+ (1 << MD_DISK_REMOVED) &&
+ !(disk.state & (1 << MD_DISK_JOURNAL)))
+ disks[disk.raid_disk * 2 + 1] = disk;
+ else if (next < max_disks * 2)
disks[next++] = disk;
}
avail = xcalloc(array.raid_disks, 1);
- for (d= 0; d < array.raid_disks; d++) {
+ for (d = 0; d < array.raid_disks; d++) {
if ((disks[d*2].state & (1<<MD_DISK_SYNC)) ||
(disks[d*2+1].state & (1<<MD_DISK_SYNC))) {
@@ -354,8 +357,8 @@ int Detail(char *dev, struct context *c)
if (c->verbose > 0) {
if (array.raid_disks)
printf(" level=%s num-devices=%d",
- str?str:"-unknown-",
- array.raid_disks );
+ str ? str : "-unknown-",
+ array.raid_disks);
else if (!inactive)
printf(" level=container num-devices=%d",
array.nr_disks);
@@ -369,8 +372,8 @@ int Detail(char *dev, struct context *c)
if (sra && sra->array.major_version < 0)
printf(" metadata=%s", sra->text_version);
else
- printf(" metadata=%d.%d",
- array.major_version, array.minor_version);
+ printf(" metadata=%d.%d", array.major_version,
+ array.minor_version);
}
/* Only try GET_BITMAP_FILE for 0.90.01 and later */
@@ -385,7 +388,7 @@ int Detail(char *dev, struct context *c)
char *devnm;
devnm = stat2devnm(&stb);
- for (e=ms; e; e=e->next)
+ for (e = ms; e; e = e->next)
if (strcmp(e->devnm, devnm) == 0)
break;
if (!get_dev_size(fd, NULL, &larray_size))
@@ -394,14 +397,16 @@ int Detail(char *dev, struct context *c)
printf("%s:\n", dev);
if (container)
- printf(" Container : %s, member %s\n", container,
- member);
+ printf(" Container : %s, member %s\n",
+ container, member);
else {
- if (sra && sra->array.major_version < 0)
- printf(" Version : %s\n", sra->text_version);
- else
- printf(" Version : %d.%d\n",
- array.major_version, array.minor_version);
+ if (sra && sra->array.major_version < 0)
+ printf(" Version : %s\n",
+ sra->text_version);
+ else
+ printf(" Version : %d.%d\n",
+ array.major_version,
+ array.minor_version);
}
atime = array.ctime;
@@ -412,14 +417,17 @@ int Detail(char *dev, struct context *c)
if (str)
printf(" Raid Level : %s\n", str);
if (larray_size)
- printf(" Array Size : %llu%s\n", (larray_size>>10),
+ printf(" Array Size : %llu%s\n",
+ (larray_size >> 10),
human_size(larray_size));
if (array.level >= 1) {
if (sra)
array.major_version = sra->array.major_version;
if (array.major_version != 0 &&
(larray_size >= 0xFFFFFFFFULL|| array.size == 0)) {
- unsigned long long dsize = get_component_size(fd);
+ unsigned long long dsize;
+
+ dsize = get_component_size(fd);
if (dsize > 0)
printf(" Used Dev Size : %llu%s\n",
dsize/2,
@@ -429,7 +437,8 @@ int Detail(char *dev, struct context *c)
} else
printf(" Used Dev Size : %lu%s\n",
(unsigned long)array.size,
- human_size((unsigned long long)array.size<<10));
+ human_size((unsigned long long)
+ array.size << 10));
}
if (array.raid_disks)
printf(" Raid Devices : %d\n", array.raid_disks);
@@ -440,7 +449,7 @@ int Detail(char *dev, struct context *c)
printf(" Preferred Minor : %d\n", array.md_minor);
if (sra == NULL || sra->array.major_version >= 0)
printf(" Persistence : Superblock is %spersistent\n",
- array.not_persistent?"not ":"");
+ array.not_persistent ? "not " : "");
printf("\n");
/* Only try GET_BITMAP_FILE for 0.90.01 and later */
if (ioctl(fd, GET_BITMAP_FILE, &bmf) == 0 && bmf.pathname[0]) {
@@ -465,19 +474,25 @@ int Detail(char *dev, struct context *c)
st = ", degraded";
printf(" State : %s%s%s%s%s%s \n",
- (array.state&(1<<MD_SB_CLEAN))?"clean":"active", st,
- (!e || (e->percent < 0 && e->percent != RESYNC_PENDING &&
- e->percent != RESYNC_DELAYED)) ? "" : sync_action[e->resync],
+ (array.state & (1 << MD_SB_CLEAN)) ?
+ "clean" : "active", st,
+ (!e || (e->percent < 0 &&
+ e->percent != RESYNC_PENDING &&
+ e->percent != RESYNC_DELAYED)) ?
+ "" : sync_action[e->resync],
larray_size ? "": ", Not Started",
- (e && e->percent == RESYNC_DELAYED) ? " (DELAYED)": "",
- (e && e->percent == RESYNC_PENDING) ? " (PENDING)": "");
+ (e && e->percent == RESYNC_DELAYED) ?
+ " (DELAYED)": "",
+ (e && e->percent == RESYNC_PENDING) ?
+ " (PENDING)": "");
} else if (inactive) {
printf(" State : inactive\n");
}
if (array.raid_disks)
printf(" Active Devices : %d\n", array.active_disks);
if (array.working_disks > 0)
- printf(" Working Devices : %d\n", array.working_disks);
+ printf(" Working Devices : %d\n",
+ array.working_disks);
if (array.raid_disks) {
printf(" Failed Devices : %d\n", array.failed_disks);
printf(" Spare Devices : %d\n", array.spare_disks);
@@ -485,11 +500,13 @@ int Detail(char *dev, struct context *c)
printf("\n");
if (array.level == 5) {
str = map_num(r5layout, array.layout);
- printf(" Layout : %s\n", str?str:"-unknown-");
+ printf(" Layout : %s\n",
+ str ? str : "-unknown-");
}
if (array.level == 6) {
str = map_num(r6layout, array.layout);
- printf(" Layout : %s\n", str?str:"-unknown-");
+ printf(" Layout : %s\n",
+ str ? str : "-unknown-");
}
if (array.level == 10) {
printf(" Layout :");
@@ -510,12 +527,14 @@ int Detail(char *dev, struct context *c)
printf(" Rounding : %dK\n\n",
array.chunk_size/1024);
break;
- default: break;
+ default:
+ break;
}
if (array.raid_disks) {
- struct mdinfo *mdi = sysfs_read(fd, NULL,
- GET_CONSISTENCY_POLICY);
+ struct mdinfo *mdi;
+
+ mdi = sysfs_read(fd, NULL, GET_CONSISTENCY_POLICY);
if (mdi) {
char *policy = map_num(consistency_policies,
mdi->consistency_policy);
@@ -528,8 +547,7 @@ int Detail(char *dev, struct context *c)
if (e && e->percent >= 0) {
static char *sync_action[] = {
- "Rebuild", "Resync",
- "Reshape", "Check"};
+ "Rebuild", "Resync", "Reshape", "Check"};
printf(" %7s Status : %d%% complete\n",
sync_action[e->resync], e->percent);
}
@@ -539,8 +557,9 @@ int Detail(char *dev, struct context *c)
#if 0
This is pretty boring
printf(" Reshape pos'n : %llu%s\n",
- (unsigned long long) info->reshape_progress<<9,
- human_size((unsigned long long)info->reshape_progress<<9));
+ (unsigned long long) info->reshape_progress << 9,
+ human_size((unsigned long long)
+ info->reshape_progress << 9));
#endif
if (info->delta_disks != 0)
printf(" Delta Devices : %d, (%d->%d)\n",
@@ -549,25 +568,29 @@ This is pretty boring
array.raid_disks);
if (info->new_level != array.level) {
str = map_num(pers, info->new_level);
- printf(" New Level : %s\n", str?str:"-unknown-");
+ printf(" New Level : %s\n",
+ str ? str : "-unknown-");
}
if (info->new_level != array.level ||
info->new_layout != array.layout) {
if (info->new_level == 5) {
- str = map_num(r5layout, info->new_layout);
+ str = map_num(r5layout,
+ info->new_layout);
printf(" New Layout : %s\n",
- str?str:"-unknown-");
+ str ? str : "-unknown-");
}
if (info->new_level == 6) {
- str = map_num(r6layout, info->new_layout);
+ str = map_num(r6layout,
+ info->new_layout);
printf(" New Layout : %s\n",
- str?str:"-unknown-");
+ str ? str : "-unknown-");
}
if (info->new_level == 10) {
printf(" New Layout : near=%d, %s=%d\n",
- info->new_layout&255,
- (info->new_layout&0x10000)?"offset":"far",
- (info->new_layout>>8)&255);
+ info->new_layout & 255,
+ (info->new_layout & 0x10000) ?
+ "offset" : "far",
+ (info->new_layout >> 8) & 255);
}
}
if (info->new_chunk != array.chunk_size)
@@ -579,8 +602,10 @@ This is pretty boring
if (st && st->sb)
st->ss->detail_super(st, c->homehost);
- if (array.raid_disks == 0 && sra && sra->array.major_version == -1
- && sra->array.minor_version == -2 && sra->text_version[0] != '/') {
+ if (array.raid_disks == 0 && sra &&
+ sra->array.major_version == -1 &&
+ sra->array.minor_version == -2 &&
+ sra->text_version[0] != '/') {
/* This looks like a container. Find any active arrays
* That claim to be a member.
*/
@@ -596,19 +621,21 @@ This is pretty boring
dev_t devid;
if (de->d_name[0] == '.')
continue;
- sprintf(path, "/sys/block/%s/md/metadata_version",
+ sprintf(path,
+ "/sys/block/%s/md/metadata_version",
de->d_name);
if (load_sys(path, vbuf, sizeof(vbuf)) < 0)
continue;
- if (strncmp(vbuf, "external:", 9) != 0 ||
- !is_subarray(vbuf+9) ||
- strncmp(vbuf+10, sra->sys_name, nlen) != 0 ||
- vbuf[10+nlen] != '/')
+ if (strncmp(vbuf, "external:", 9) ||
+ !is_subarray(vbuf + 9) ||
+ strncmp(vbuf + 10, sra->sys_name, nlen) ||
+ vbuf[10 + nlen] != '/')
continue;
devid = devnm2devid(de->d_name);
- printf(" %s", map_dev_preferred(
- major(devid),
- minor(devid), 1, c->prefer));
+ printf(" %s",
+ map_dev_preferred(major(devid),
+ minor(devid), 1,
+ c->prefer));
}
if (dir)
closedir(dir);
@@ -622,24 +649,23 @@ This is pretty boring
}
free(info);
- for (d= 0; d < max_disks * 2; d++) {
+ for (d = 0; d < max_disks * 2; d++) {
char *dv;
mdu_disk_info_t disk = disks[d];
- if (d >= array.raid_disks*2 &&
- disk.major == 0 &&
- disk.minor == 0)
+ if (d >= array.raid_disks * 2 &&
+ disk.major == 0 && disk.minor == 0)
continue;
- if ((d & 1) &&
- disk.major == 0 &&
- disk.minor == 0)
+ if ((d & 1) && disk.major == 0 && disk.minor == 0)
continue;
if (!c->brief) {
- if (d == array.raid_disks*2) printf("\n");
+ if (d == array.raid_disks*2)
+ printf("\n");
if (disk.number < 0 && disk.raid_disk < 0)
printf(" - %5d %5d - ",
disk.major, disk.minor);
- else if (disk.raid_disk < 0 || disk.state & (1<<MD_DISK_JOURNAL))
+ else if (disk.raid_disk < 0 ||
+ disk.state & (1 << MD_DISK_JOURNAL))
printf(" %5d %5d %5d - ",
disk.number, disk.major, disk.minor);
else if (disk.number < 0)
@@ -647,34 +673,44 @@ This is pretty boring
disk.major, disk.minor, disk.raid_disk);
else
printf(" %5d %5d %5d %5d ",
- disk.number, disk.major, disk.minor, disk.raid_disk);
+ disk.number, disk.major, disk.minor,
+ disk.raid_disk);
}
if (!c->brief && array.raid_disks) {
-
- if (disk.state & (1<<MD_DISK_FAULTY)) {
+ if (disk.state & (1 << MD_DISK_FAULTY)) {
printf(" faulty");
if (disk.raid_disk < array.raid_disks &&
disk.raid_disk >= 0)
failed++;
}
- if (disk.state & (1<<MD_DISK_ACTIVE)) printf(" active");
- if (disk.state & (1<<MD_DISK_SYNC)) {
+ if (disk.state & (1 << MD_DISK_ACTIVE))
+ printf(" active");
+ if (disk.state & (1 << MD_DISK_SYNC)) {
printf(" sync");
- if (array.level == 10 && (array.layout & ~0x1FFFF) == 0) {
+ if (array.level == 10 &&
+ (array.layout & ~0x1FFFF) == 0) {
int nc = array.layout & 0xff;
int fc = (array.layout >> 8) & 0xff;
int copies = nc*fc;
- if (fc == 1 && array.raid_disks % copies == 0 && copies <= 26) {
- /* We can divide the devices into 'sets' */
- int set = disk.raid_disk % copies;
+ if (fc == 1 &&
+ array.raid_disks % copies == 0 &&
+ copies <= 26) {
+ /* We can divide the devices
+ into 'sets' */
+ int set;
+ set = disk.raid_disk % copies;
printf(" set-%c", set + 'A');
}
}
}
- if (disk.state & (1<<MD_DISK_REMOVED)) printf(" removed");
- if (disk.state & (1<<MD_DISK_WRITEMOSTLY)) printf(" writemostly");
- if (disk.state & (1<<MD_DISK_FAILFAST)) printf(" failfast");
- if (disk.state & (1<<MD_DISK_JOURNAL)) printf(" journal");
+ if (disk.state & (1 << MD_DISK_REMOVED))
+ printf(" removed");
+ if (disk.state & (1 << MD_DISK_WRITEMOSTLY))
+ printf(" writemostly");
+ if (disk.state & (1 << MD_DISK_FAILFAST))
+ printf(" failfast");
+ if (disk.state & (1 << MD_DISK_JOURNAL))
+ printf(" journal");
if ((disk.state &
((1<<MD_DISK_ACTIVE)|(1<<MD_DISK_SYNC)
|(1<<MD_DISK_REMOVED)|(1<<MD_DISK_FAULTY)|(1<<MD_DISK_JOURNAL)))
@@ -685,19 +721,21 @@ This is pretty boring
printf(" rebuilding");
}
}
- if (disk.state == 0) spares++;
- dv=map_dev_preferred(disk.major, disk.minor, 0, c->prefer);
+ if (disk.state == 0)
+ spares++;
+ dv = map_dev_preferred(disk.major, disk.minor, 0, c->prefer);
if (dv != NULL) {
if (c->brief)
n_devices = add_device(dv, &devices,
- &max_devices,
- n_devices);
+ &max_devices, n_devices);
else
printf(" %s", dv);
}
- if (!c->brief) printf("\n");
+ if (!c->brief)
+ printf("\n");
}
- if (spares && c->brief && array.raid_disks) printf(" spares=%d", spares);
+ if (spares && c->brief && array.raid_disks)
+ printf(" spares=%d", spares);
if (c->brief && st && st->sb)
st->ss->brief_detail_super(st);
if (st)
@@ -712,8 +750,7 @@ This is pretty boring
if (c->brief)
printf("\n");
if (c->test &&
- !enough(array.level, array.raid_disks, array.layout,
- 1, avail))
+ !enough(array.level, array.raid_disks, array.layout, 1, avail))
rv = 2;
free(disks);
--
2.7.4

78
SOURCES/Detail-Stop-bothering1-about-md-drivers-older-than-0..patch

@ -0,0 +1,78 @@ @@ -0,0 +1,78 @@
From 901d5ee6da145033ac30fee68f4fec0e8af9eddc Mon Sep 17 00:00:00 2001
From: Jes Sorensen <Jes.Sorensen@gmail.com>
Date: Wed, 5 Apr 2017 15:26:53 -0400
Subject: [RHEL7.5 PATCH 057/169] Detail: Stop bothering about md drivers
older than 0.90.00

Remove further handling of md driver version older than 0.90.00

Signed-off-by: Jes Sorensen <Jes.Sorensen@gmail.com>
---
Detail.c | 27 +++++++--------------------
1 file changed, 7 insertions(+), 20 deletions(-)

diff --git a/Detail.c b/Detail.c
index fa6d4c7..d4e6204 100644
--- a/Detail.c
+++ b/Detail.c
@@ -54,7 +54,6 @@ int Detail(char *dev, struct context *c)
* Print out details for an md array
*/
int fd = open(dev, O_RDONLY);
- int vers;
mdu_array_info_t array;
mdu_disk_info_t *disks;
int next;
@@ -88,22 +87,14 @@ int Detail(char *dev, struct context *c)
dev, strerror(errno));
return rv;
}
- vers = md_get_version(fd);
- if (vers < 0) {
- pr_err("%s does not appear to be an md device\n",
- dev);
- close(fd);
- return rv;
- }
- if (vers < 9000) {
- pr_err("cannot get detail for md device %s: driver version too old.\n",
- dev);
+ sra = sysfs_read(fd, NULL, GET_VERSION|GET_DEVS);
+ if (!sra) {
+ pr_err("%s does not appear to be an md device\n", dev);
close(fd);
return rv;
}
- sra = sysfs_read(fd, NULL, GET_VERSION|GET_DEVS);
- external = (sra != NULL && sra->array.major_version == -1
- && sra->array.minor_version == -2);
+ external = (sra != NULL && sra->array.major_version == -1 &&
+ sra->array.minor_version == -2);
st = super_by_fd(fd, &subarray);
if (md_get_array_info(fd, &array) == 0) {
inactive = 0;
@@ -378,9 +369,7 @@ int Detail(char *dev, struct context *c)
}
/* Only try GET_BITMAP_FILE for 0.90.01 and later */
- if (vers >= 9001 &&
- ioctl(fd, GET_BITMAP_FILE, &bmf) == 0 &&
- bmf.pathname[0]) {
+ if (ioctl(fd, GET_BITMAP_FILE, &bmf) == 0 && bmf.pathname[0]) {
printf(" bitmap=%s", bmf.pathname);
}
} else {
@@ -449,9 +438,7 @@ int Detail(char *dev, struct context *c)
array.not_persistent?"not ":"");
printf("\n");
/* Only try GET_BITMAP_FILE for 0.90.01 and later */
- if (vers >= 9001 &&
- ioctl(fd, GET_BITMAP_FILE, &bmf) == 0 &&
- bmf.pathname[0]) {
+ if (ioctl(fd, GET_BITMAP_FILE, &bmf) == 0 && bmf.pathname[0]) {
printf(" Intent Bitmap : %s\n", bmf.pathname);
printf("\n");
} else if (array.state & (1<<MD_SB_BITMAP_PRESENT))
--
2.7.4

111
SOURCES/Detail-correct-outputfor-active-arrays.patch

@ -0,0 +1,111 @@ @@ -0,0 +1,111 @@
From a822017f30e0dadc60a687900c2aa4da32e09a93 Mon Sep 17 00:00:00 2001
From: Mariusz Tkaczyk <mariusz.tkaczyk@intel.com>
Date: Thu, 10 Aug 2017 11:43:48 +0200
Subject: [RHEL7.5 PATCH 162/169] Detail: correct output for active arrays

The check for inactive array is incorrect as it compares it against
active array. Introduce a new function md_is_array_active so the check
is consistent across the code.

As the output contains list of disks in the array include this
information in sysfs read.

Signed-off-by: Mariusz Tkaczyk <mariusz.tkaczyk@intel.com>
Signed-off-by: Jes Sorensen <jsorensen@fb.com>
---
Detail.c | 15 +++++++--------
mdadm.h | 1 +
util.c | 15 +++++++++------
3 files changed, 17 insertions(+), 14 deletions(-)

diff --git a/Detail.c b/Detail.c
index 2332b85..2c9fb24 100644
--- a/Detail.c
+++ b/Detail.c
@@ -86,7 +86,8 @@ int Detail(char *dev, struct context *c)
dev, strerror(errno));
return rv;
}
- sra = sysfs_read(fd, NULL, GET_VERSION | GET_DEVS | GET_ARRAY_STATE);
+ sra = sysfs_read(fd, NULL, GET_VERSION | GET_DEVS |
+ GET_ARRAY_STATE | GET_STATE);
if (!sra) {
if (md_get_array_info(fd, &array)) {
pr_err("%s does not appear to be an md device\n", dev);
@@ -96,8 +97,7 @@ int Detail(char *dev, struct context *c)
}
external = (sra != NULL && sra->array.major_version == -1 &&
sra->array.minor_version == -2);
- inactive = (sra->array_state == ARRAY_ACTIVE ||
- sra->array_state == ARRAY_CLEAR);
+ inactive = (sra != NULL && !md_array_is_active(sra));
st = super_by_fd(fd, &subarray);
if (md_get_array_info(fd, &array)) {
if (errno == ENODEV) {
@@ -314,11 +314,10 @@ int Detail(char *dev, struct context *c)
next = array.raid_disks * 2;
if (inactive) {
struct mdinfo *mdi;
- if (sra != NULL)
- for (mdi = sra->devs; mdi; mdi = mdi->next) {
- disks[next++] = mdi->disk;
- disks[next - 1].number = -1;
- }
+ for (mdi = sra->devs; mdi; mdi = mdi->next) {
+ disks[next++] = mdi->disk;
+ disks[next - 1].number = -1;
+ }
} else for (d = 0; d < max_disks; d++) {
mdu_disk_info_t disk;
disk.number = d;
diff --git a/mdadm.h b/mdadm.h
index ee9b837..191ae8f 100644
--- a/mdadm.h
+++ b/mdadm.h
@@ -1425,6 +1425,7 @@ extern int Restore_metadata(char *dev, char *dir, struct context *c,
int md_array_valid(int fd);
int md_array_active(int fd);
+int md_array_is_active(struct mdinfo *info);
int md_get_array_info(int fd, struct mdu_array_info_s *array);
int md_set_array_info(int fd, struct mdu_array_info_s *array);
int md_get_disk_info(int fd, struct mdu_disk_info_s *disk);
diff --git a/util.c b/util.c
index 8eeb509..c1c8509 100644
--- a/util.c
+++ b/util.c
@@ -228,15 +228,11 @@ int md_array_active(int fd)
{
struct mdinfo *sra;
struct mdu_array_info_s array;
- int ret;
+ int ret = 0;
sra = sysfs_read(fd, NULL, GET_ARRAY_STATE);
if (sra) {
- if (sra->array_state != ARRAY_CLEAR &&
- sra->array_state != ARRAY_INACTIVE &&
- sra->array_state != ARRAY_UNKNOWN_STATE)
- ret = 0;
- else
+ if (!md_array_is_active(sra))
ret = -ENODEV;
free(sra);
@@ -251,6 +247,13 @@ int md_array_active(int fd)
return !ret;
}
+int md_array_is_active(struct mdinfo *info)
+{
+ return (info->array_state != ARRAY_CLEAR &&
+ info->array_state != ARRAY_INACTIVE &&
+ info->array_state != ARRAY_UNKNOWN_STATE);
+}
+
/*
* Get array info from the kernel. Longer term we want to deprecate the
* ioctl and get it from sysfs.
--
2.7.4

54
SOURCES/Detail-determine2-array-state-from-sysfs.patch

@ -0,0 +1,54 @@ @@ -0,0 +1,54 @@
From a4dcdb23ea639d14e92d1c86336de7ad505b2f7d Mon Sep 17 00:00:00 2001
From: Jes Sorensen <jsorensen@fb.com>
Date: Tue, 25 Apr 2017 11:40:27 -0400
Subject: [RHEL7.5 PATCH 095/169] Detail: determine array state from sysfs

This is easily obtained from sysfs as part of the existing call to
sysfs_read() and it simplifies the code a little too.

Another small step in the process of getting rid of the GET_ARRAY_STATE
ioctl.

Signed-off-by: Jes Sorensen <jsorensen@fb.com>
---
Detail.c | 9 ++++-----
1 file changed, 4 insertions(+), 5 deletions(-)

diff --git a/Detail.c b/Detail.c
index 91c5a98..eb69276 100644
--- a/Detail.c
+++ b/Detail.c
@@ -86,7 +86,7 @@ int Detail(char *dev, struct context *c)
dev, strerror(errno));
return rv;
}
- sra = sysfs_read(fd, NULL, GET_VERSION|GET_DEVS);
+ sra = sysfs_read(fd, NULL, GET_VERSION | GET_DEVS | GET_ARRAY_STATE);
if (!sra) {
pr_err("%s does not appear to be an md device\n", dev);
close(fd);
@@ -94,10 +94,10 @@ int Detail(char *dev, struct context *c)
}
external = (sra != NULL && sra->array.major_version == -1 &&
sra->array.minor_version == -2);
+ inactive = (sra->array_state == ARRAY_ACTIVE ||
+ sra->array_state == ARRAY_CLEAR);
st = super_by_fd(fd, &subarray);
- if (md_get_array_info(fd, &array) == 0) {
- inactive = 0;
- } else if (errno == ENODEV && sra) {
+ if (md_get_array_info(fd, &array) && errno == ENODEV) {
if (sra->array.major_version == -1 &&
sra->array.minor_version == -1 &&
sra->devs == NULL) {
@@ -107,7 +107,6 @@ int Detail(char *dev, struct context *c)
return rv;
}
array = sra->array;
- inactive = 1;
} else {
pr_err("cannot get array detail for %s: %s\n",
dev, strerror(errno));
--
2.7.4

89
SOURCES/Detail-differentiate-between-container-and-inactive-.patch

@ -0,0 +1,89 @@ @@ -0,0 +1,89 @@
From bb8354598676428af01f23bfb1876c7356d61147 Mon Sep 17 00:00:00 2001
From: Mariusz Tkaczyk <mariusz.tkaczyk@intel.com>
Date: Fri, 18 Aug 2017 12:00:23 +0200
Subject: [RHEL7.5 PATCH 01/13] Detail: differentiate between container and
inactive arrays

Containers used to be handled as active arrays because GET_ARRAY_INFO
ioctl returns valid structure for them. As containers appear as inactive
in sysfs, the output for detail command has changed.

Stop relying on inactive state for containers. Make the output look the
same as in mdadm 4.0.

Signed-off-by: Mariusz Tkaczyk <mariusz.tkaczyk@intel.com>
Signed-off-by: Jes Sorensen <jsorensen@fb.com>
---
Detail.c | 16 +++++++++++-----
1 file changed, 11 insertions(+), 5 deletions(-)

diff --git a/Detail.c b/Detail.c
index 2c9fb24..4dcf81d 100644
--- a/Detail.c
+++ b/Detail.c
@@ -80,6 +80,7 @@ int Detail(char *dev, struct context *c)
char *avail = NULL;
int external;
int inactive;
+ int is_container = 0;
if (fd < 0) {
pr_err("cannot open %s: %s\n",
@@ -119,6 +120,8 @@ int Detail(char *dev, struct context *c)
}
}
+ if (array.raid_disks == 0 && external)
+ is_container = 1;
if (fstat(fd, &stb) != 0 && !S_ISBLK(stb.st_mode))
stb.st_rdev = 0;
rv = 0;
@@ -228,7 +231,7 @@ int Detail(char *dev, struct context *c)
printf("MD_LEVEL=%s\n", str);
printf("MD_DEVICES=%d\n", array.raid_disks);
} else {
- if (!inactive)
+ if (is_container)
printf("MD_LEVEL=container\n");
printf("MD_DEVICES=%d\n", array.nr_disks);
}
@@ -357,13 +360,16 @@ int Detail(char *dev, struct context *c)
if (c->brief) {
mdu_bitmap_file_t bmf;
- printf("%sARRAY %s", inactive ? "INACTIVE-":"", dev);
+ if (inactive && !is_container)
+ printf("INACTIVE-ARRAY %s", dev);
+ else
+ printf("ARRAY %s", dev);
if (c->verbose > 0) {
if (array.raid_disks)
printf(" level=%s num-devices=%d",
str ? str : "-unknown-",
array.raid_disks);
- else if (!inactive)
+ else if (is_container)
printf(" level=container num-devices=%d",
array.nr_disks);
else
@@ -416,7 +422,7 @@ int Detail(char *dev, struct context *c)
atime = array.ctime;
if (atime)
printf(" Creation Time : %.24s\n", ctime(&atime));
- if (array.raid_disks == 0 && external)
+ if (is_container)
str = "container";
if (str)
printf(" Raid Level : %s\n", str);
@@ -489,7 +495,7 @@ int Detail(char *dev, struct context *c)
" (DELAYED)": "",
(e && e->percent == RESYNC_PENDING) ?
" (PENDING)": "");
- } else if (inactive) {
+ } else if (inactive && !is_container) {
printf(" State : inactive\n");
}
if (array.raid_disks)
--
2.7.4

76
SOURCES/Detail-don-t-exit-if-ioctl-has-been-successful.patch

@ -0,0 +1,76 @@ @@ -0,0 +1,76 @@
From 9b8fea914f82281c440cdce9dee6a3775265861c Mon Sep 17 00:00:00 2001
From: Tomasz Majchrzak <tomasz.majchrzak@intel.com>
Date: Wed, 24 May 2017 11:34:22 +0200
Subject: [RHEL7.5 PATCH 147/169] Detail: don't exit if ioctl has been
successful

When GET_ARRAY_INFO ioctl is successful, mdadm exits with an error.
It breaks udev and no links in /dev/md are created.

Also change debug print to error print in the message indicating lack
of the link to facilitate debugging similar issues in the future.

Signed-off-by: Tomasz Majchrzak <tomasz.majchrzak@intel.com>
Signed-off-by: Jes Sorensen <jsorensen@fb.com>
---
Detail.c | 27 +++++++++++++++------------
util.c | 2 +-
2 files changed, 16 insertions(+), 13 deletions(-)

diff --git a/Detail.c b/Detail.c
index bf881ff..2332b85 100644
--- a/Detail.c
+++ b/Detail.c
@@ -99,21 +99,24 @@ int Detail(char *dev, struct context *c)
inactive = (sra->array_state == ARRAY_ACTIVE ||
sra->array_state == ARRAY_CLEAR);
st = super_by_fd(fd, &subarray);
- if (md_get_array_info(fd, &array) && errno == ENODEV) {
- if (sra->array.major_version == -1 &&
- sra->array.minor_version == -1 &&
- sra->devs == NULL) {
- pr_err("Array associated with md device %s does not exist.\n", dev);
+ if (md_get_array_info(fd, &array)) {
+ if (errno == ENODEV) {
+ if (sra->array.major_version == -1 &&
+ sra->array.minor_version == -1 &&
+ sra->devs == NULL) {
+ pr_err("Array associated with md device %s does not exist.\n",
+ dev);
+ close(fd);
+ sysfs_free(sra);
+ return rv;
+ }
+ array = sra->array;
+ } else {
+ pr_err("cannot get array detail for %s: %s\n",
+ dev, strerror(errno));
close(fd);
- sysfs_free(sra);
return rv;
}
- array = sra->array;
- } else {
- pr_err("cannot get array detail for %s: %s\n",
- dev, strerror(errno));
- close(fd);
- return rv;
}
if (fstat(fd, &stb) != 0 && !S_ISBLK(stb.st_mode))
diff --git a/util.c b/util.c
index d89438c..8eeb509 100644
--- a/util.c
+++ b/util.c
@@ -1169,7 +1169,7 @@ void wait_for(char *dev, int fd)
delay *= 2;
}
if (i == 25)
- dprintf("timeout waiting for %s\n", dev);
+ pr_err("timeout waiting for %s\n", dev);
}
struct superswitch *superlist[] =
--
2.7.4

69
SOURCES/Detail-ensure-export-names-are-acceptable-as-shell-v.patch

@ -0,0 +1,69 @@ @@ -0,0 +1,69 @@
From b9c9bd9bacaab701d5b3cb3e4b6cb02ea8d36e47 Mon Sep 17 00:00:00 2001
From: NeilBrown <neilb@suse.com>
Date: Thu, 20 Apr 2017 12:40:06 +1000
Subject: [RHEL7.5 PATCH 089/169] Detail: ensure --export names are
acceptable as shell variables.

If an array contains a device which has a name that
contains something other than alphnumerics and underscores,
then some values reported by "mdadm --detail --export" will
not be valid as variable assignment of the shell.
This particularly affects dm devices.
e.g.
MD_DEVICE_dm-4_ROLE=1
MD_DEVICE_dm-4_DEV=/dev/dm-4

As it is particularly useful to be able to work with these
in a shell script, and as the precise name is not important,
change all non-alphanumerics to '_'.

MD_DEVICE_dm_4_ROLE=1
MD_DEVICE_dm_4_DEV=/dev/dm-4

Signed-off-by: NeilBrown <neilb@suse.com>
Signed-off-by: Jes Sorensen <jsorensen@fb.com>
---
Detail.c | 12 +++++++++---
1 file changed, 9 insertions(+), 3 deletions(-)

diff --git a/Detail.c b/Detail.c
index e40cd8f..91c5a98 100644
--- a/Detail.c
+++ b/Detail.c
@@ -25,6 +25,7 @@
#include "mdadm.h"
#include "md_p.h"
#include "md_u.h"
+#include <ctype.h>
#include <dirent.h>
static int cmpstringp(const void *p1, const void *p2)
@@ -276,17 +277,22 @@ int Detail(char *dev, struct context *c)
char *path =
map_dev(mdi->disk.major,
mdi->disk.minor, 0);
+ char *sysdev = xstrdup(mdi->sys_name + 1);
+ char *cp;
+ for (cp = sysdev; *cp; cp++)
+ if (!isalnum(*cp))
+ *cp = '_';
if (mdi->disk.raid_disk >= 0)
printf("MD_DEVICE_%s_ROLE=%d\n",
- mdi->sys_name+4,
+ sysdev,
mdi->disk.raid_disk);
else
printf("MD_DEVICE_%s_ROLE=spare\n",
- mdi->sys_name+4);
+ sysdev);
if (path)
printf("MD_DEVICE_%s_DEV=%s\n",
- mdi->sys_name+4, path);
+ sysdev, path);
}
}
goto out;
--
2.7.4

45
SOURCES/Detail-handle-non-existent-arrays-better.patch

@ -0,0 +1,45 @@ @@ -0,0 +1,45 @@
From b4decd517d90098bc2d17d3eddfe858d8b903920 Mon Sep 17 00:00:00 2001
From: NeilBrown <neilb@suse.com>
Date: Mon, 27 Mar 2017 14:36:56 +1100
Subject: [RHEL7.5 PATCH 024/169] Detail: handle non-existent arrays
better.

If you call "mdadm --detail" with a device file for an array which
doesn't exist, such as by
mknod /dev/md57 b 9 57
mdadm --detail /dev/md57

you get an unhelpful message about and inactive RAID0, and return
status is '0'. This is confusing.

So catch this possibility and print a more useful message, and
return a non-zero status.

Signed-off-by: NeilBrown <neilb@suse.com>
Signed-off-by: Jes Sorensen <Jes.Sorensen@gmail.com>
---
Detail.c | 8 ++++++++
1 file changed, 8 insertions(+)

diff --git a/Detail.c b/Detail.c
index cb33794..3d92855 100644
--- a/Detail.c
+++ b/Detail.c
@@ -110,6 +110,14 @@ int Detail(char *dev, struct context *c)
if (ioctl(fd, GET_ARRAY_INFO, &array) == 0) {
inactive = 0;
} else if (errno == ENODEV && sra) {
+ if (sra->array.major_version == -1 &&
+ sra->array.minor_version == -1 &&
+ sra->devs == NULL) {
+ pr_err("Array associated with md device %s does not exist.\n", dev);
+ close(fd);
+ sysfs_free(sra);
+ return rv;
+ }
array = sra->array;
inactive = 1;
} else {
--
2.7.4

106
SOURCES/Don-t-abort-starting-the-array-if-kernel-does-not-su.patch

@ -0,0 +1,106 @@ @@ -0,0 +1,106 @@
From 2c8890e926a4c7f9169b5054e3dbf84426fe1025 Mon Sep 17 00:00:00 2001
From: Artur Paszkiewicz <artur.paszkiewicz@intel.com>
Date: Thu, 28 Sep 2017 14:41:07 +0200
Subject: [PATCH 01/12] Don't abort starting the array if kernel does
not support ppl

Change the behavior of assemble and create for consistency-policy=ppl
for external metadata arrays. If the kernel does not support ppl, don't
abort but print a warning and start the array without ppl
(consistency-policy=resync). No change for native md arrays because the
kernel will not allow starting the array if it finds an unsupported
feature bit in the superblock.

In sysfs_add_disk() check consistency_policy in the mdinfo structure
that represents the array, not the disk and read the current consistency
policy from sysfs in mdmon's manage_member(). This is necessary to make
sysfs_add_disk() honor the actual consistency policy and not what is in
the metadata. Also remove all the places where consistency_policy is set
for a disk's mdinfo - it is a property of the array, not the disk.

Signed-off-by: Artur Paszkiewicz <artur.paszkiewicz@intel.com>
Signed-off-by: Jes Sorensen <jsorensen@fb.com>
---
managemon.c | 11 ++++++++---
super-intel.c | 4 +---
sysfs.c | 6 +++---
3 files changed, 12 insertions(+), 9 deletions(-)

diff --git a/managemon.c b/managemon.c
index 68f0c2d..cc3c6f1 100644
--- a/managemon.c
+++ b/managemon.c
@@ -477,7 +477,7 @@ static void manage_member(struct mdstat_ent *mdstat,
char buf[64];
int frozen;
struct supertype *container = a->container;
- unsigned long long int component_size = 0;
+ struct mdinfo *mdi;
if (container == NULL)
/* Raced with something */
@@ -489,8 +489,13 @@ static void manage_member(struct mdstat_ent *mdstat,
// MORE
}
- if (sysfs_get_ll(&a->info, NULL, "component_size", &component_size) >= 0)
- a->info.component_size = component_size << 1;
+ mdi = sysfs_read(-1, mdstat->devnm,
+ GET_COMPONENT|GET_CONSISTENCY_POLICY);
+ if (mdi) {
+ a->info.component_size = mdi->component_size;
+ a->info.consistency_policy = mdi->consistency_policy;
+ sysfs_free(mdi);
+ }
/* honor 'frozen' */
if (sysfs_get_str(&a->info, NULL, "metadata_version", buf, sizeof(buf)) > 0)
diff --git a/super-intel.c b/super-intel.c
index bbe7bc7..e3dcd3d 100644
--- a/super-intel.c
+++ b/super-intel.c
@@ -7669,7 +7669,6 @@ static struct mdinfo *container_content_imsm(struct supertype *st, char *subarra
} else {
info_d->component_size = blocks_per_member(map);
}
- info_d->consistency_policy = this->consistency_policy;
info_d->bb.supported = 1;
get_volume_badblocks(super->bbm_log, ord_to_idx(ord),
@@ -8758,8 +8757,7 @@ static struct mdinfo *imsm_activate_spare(struct active_array *a,
di->component_size = a->info.component_size;
di->container_member = inst;
di->bb.supported = 1;
- if (dev->rwh_policy == RWH_DISTRIBUTED) {
- di->consistency_policy = CONSISTENCY_POLICY_PPL;
+ if (a->info.consistency_policy == CONSISTENCY_POLICY_PPL) {
di->ppl_sector = get_ppl_sector(super, inst);
di->ppl_size = (PPL_HEADER_SIZE + PPL_ENTRY_SPACE) >> 9;
}
diff --git a/sysfs.c b/sysfs.c
index 68ddd5f..bf5c8c5 100644
--- a/sysfs.c
+++ b/sysfs.c
@@ -709,8 +709,8 @@ int sysfs_set_array(struct mdinfo *info, int vers)
if (sysfs_set_str(info, NULL, "consistency_policy",
map_num(consistency_policies,
info->consistency_policy))) {
- pr_err("This kernel does not support PPL\n");
- return 1;
+ pr_err("This kernel does not support PPL. Falling back to consistency-policy=resync.\n");
+ info->consistency_policy = CONSISTENCY_POLICY_RESYNC;
}
}
@@ -745,7 +745,7 @@ int sysfs_add_disk(struct mdinfo *sra, struct mdinfo *sd, int resume)
rv = sysfs_set_num(sra, sd, "offset", sd->data_offset);
rv |= sysfs_set_num(sra, sd, "size", (sd->component_size+1) / 2);
if (sra->array.level != LEVEL_CONTAINER) {
- if (sd->consistency_policy == CONSISTENCY_POLICY_PPL) {
+ if (sra->consistency_policy == CONSISTENCY_POLICY_PPL) {
rv |= sysfs_set_num(sra, sd, "ppl_sector", sd->ppl_sector);
rv |= sysfs_set_num(sra, sd, "ppl_size", sd->ppl_size);
}
--
2.7.4

122
SOURCES/Don-t-use-UnSet-with-consistency_policy.patch

@ -0,0 +1,122 @@ @@ -0,0 +1,122 @@
From b75805662e7208799207a8e5f8a61f69a44888f0 Mon Sep 17 00:00:00 2001
From: Artur Paszkiewicz <artur.paszkiewicz@intel.com>
Date: Mon, 24 Apr 2017 16:03:26 +0200
Subject: [RHEL7.5 PATCH 094/169] Don't use UnSet with consistency_policy

Use CONSISTENCY_POLICY_UNKNOWN instead. Simplify some checks because
since 5e8e35fb7e17 ("maps: Use keyvalue for null terminator to indicate
'unset' value") map_name() can return this default directly.

Suggested-by: Jes Sorensen <Jes.Sorensen@gmail.com>
Signed-off-by: Artur Paszkiewicz <artur.paszkiewicz@intel.com>
---
maps.c | 2 +-
mdadm.c | 12 ++++++------
super-intel.c | 4 +---
sysfs.c | 10 ++++------
4 files changed, 12 insertions(+), 16 deletions(-)

diff --git a/maps.c b/maps.c
index bb28ba6..02a0474 100644
--- a/maps.c
+++ b/maps.c
@@ -137,7 +137,7 @@ mapping_t consistency_policies[] = {
{ "bitmap", CONSISTENCY_POLICY_BITMAP},
{ "journal", CONSISTENCY_POLICY_JOURNAL},
{ "ppl", CONSISTENCY_POLICY_PPL},
- { NULL, UnSet }
+ { NULL, CONSISTENCY_POLICY_UNKNOWN }
};
mapping_t sysfs_array_states[] = {
diff --git a/mdadm.c b/mdadm.c
index 41dae1d..b689e32 100644
--- a/mdadm.c
+++ b/mdadm.c
@@ -78,7 +78,7 @@ int main(int argc, char *argv[])
.level = UnSet,
.layout = UnSet,
.bitmap_chunk = UnSet,
- .consistency_policy = UnSet,
+ .consistency_policy = CONSISTENCY_POLICY_UNKNOWN,
};
char sys_hostname[256];
@@ -1228,8 +1228,7 @@ int main(int argc, char *argv[])
case O(GROW, 'k'):
s.consistency_policy = map_name(consistency_policies,
optarg);
- if (s.consistency_policy == UnSet ||
- s.consistency_policy < CONSISTENCY_POLICY_RESYNC) {
+ if (s.consistency_policy < CONSISTENCY_POLICY_RESYNC) {
pr_err("Invalid consistency policy: %s\n",
optarg);
exit(2);
@@ -1267,7 +1266,7 @@ int main(int argc, char *argv[])
pr_err("--write-journal is only supported for RAID level 4/5/6.\n");
exit(2);
}
- if (s.consistency_policy != UnSet &&
+ if (s.consistency_policy != CONSISTENCY_POLICY_UNKNOWN &&
s.consistency_policy != CONSISTENCY_POLICY_JOURNAL) {
pr_err("--write-journal is not supported with consistency policy: %s\n",
map_num(consistency_policies, s.consistency_policy));
@@ -1275,7 +1274,8 @@ int main(int argc, char *argv[])
}
}
- if (mode == CREATE && s.consistency_policy != UnSet) {
+ if (mode == CREATE &&
+ s.consistency_policy != CONSISTENCY_POLICY_UNKNOWN) {
if (s.level <= 0) {
pr_err("--consistency-policy not meaningful with level %s.\n",
map_num(pers, s.level));
@@ -1687,7 +1687,7 @@ int main(int argc, char *argv[])
rv = Grow_reshape(devlist->devname, mdfd,
devlist->next,
data_offset, &c, &s);
- } else if (s.consistency_policy != UnSet) {
+ } else if (s.consistency_policy != CONSISTENCY_POLICY_UNKNOWN) {
rv = Grow_consistency_policy(devlist->devname, mdfd, &c, &s);
} else if (array_size == 0)
pr_err("no changes to --grow\n");
diff --git a/super-intel.c b/super-intel.c
index 0aed57c..fbff215 100644
--- a/super-intel.c
+++ b/super-intel.c
@@ -5369,9 +5369,7 @@ static int init_super_imsm_volume(struct supertype *st, mdu_array_info_t *info,
}
mpb->num_raid_devs++;
- if (s->consistency_policy == UnSet ||
- s->consistency_policy == CONSISTENCY_POLICY_RESYNC ||
- s->consistency_policy == CONSISTENCY_POLICY_NONE) {
+ if (s->consistency_policy <= CONSISTENCY_POLICY_RESYNC) {
dev->rwh_policy = RWH_OFF;
} else if (s->consistency_policy == CONSISTENCY_POLICY_PPL) {
dev->rwh_policy = RWH_DISTRIBUTED;
diff --git a/sysfs.c b/sysfs.c
index 712f8b3..aa30de5 100644
--- a/sysfs.c
+++ b/sysfs.c
@@ -254,13 +254,11 @@ struct mdinfo *sysfs_read(int fd, char *devnm, unsigned long options)
if (options & GET_CONSISTENCY_POLICY) {
strcpy(base, "consistency_policy");
- if (load_sys(fname, buf, sizeof(buf))) {
+ if (load_sys(fname, buf, sizeof(buf)))
sra->consistency_policy = CONSISTENCY_POLICY_UNKNOWN;
- } else {
- sra->consistency_policy = map_name(consistency_policies, buf);
- if (sra->consistency_policy == UnSet)
- sra->consistency_policy = CONSISTENCY_POLICY_UNKNOWN;
- }
+ else
+ sra->consistency_policy = map_name(consistency_policies,
+ buf);
}
if (! (options & GET_DEVS))
--
2.7.4

31
SOURCES/Don-t-use-exit-ERANGE.patch

@ -0,0 +1,31 @@ @@ -0,0 +1,31 @@
From dcd24efcfab50c3c298d9b1c941edb6954c2677e Mon Sep 17 00:00:00 2001
From: NeilBrown <neilb@suse.com>
Date: Fri, 4 Aug 2017 15:30:02 +1000
Subject: [RHEL7.5 PATCH 167/169] Don't use exit(ERANGE)

mdadm uses smaller exit codes like 0,1,2,3,4.
Using ERANGE is inconsistent and not helpful.
So change it to a more consistent number.

Signed-off-by: NeilBrown <neilb@suse.com>
Signed-off-by: Jes Sorensen <jsorensen@fb.com>
---
mdadm.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/mdadm.c b/mdadm.c
index 70b16f2..d80aab3 100644
--- a/mdadm.c
+++ b/mdadm.c
@@ -619,7 +619,7 @@ int main(int argc, char *argv[])
c.homecluster = optarg;
if (strlen(c.homecluster) > 64) {
pr_err("Cluster name too big.\n");
- exit(ERANGE);
+ exit(2);
}
continue;
case O(CREATE,'x'): /* number of spare (eXtra) disks */
--
2.7.4

91
SOURCES/Error-messages-should-end-with-a-newline-character.patch

@ -0,0 +1,91 @@ @@ -0,0 +1,91 @@
From 8e5b52cdda95965787e2a289c855a4ab7099f00d Mon Sep 17 00:00:00 2001
From: NeilBrown <neilb@suse.com>
Date: Fri, 4 Aug 2017 15:30:02 +1000
Subject: [RHEL7.5 PATCH 164/169] Error messages should end with a newline
character.

Add "\n" to the end of error messages which don't already
have one. Also spell "opened" correctly.

Signed-off-by: NeilBrown <neilb@suse.com>
Signed-off-by: Jes Sorensen <jsorensen@fb.com>
---
Build.c | 4 ++--
Grow.c | 4 ++--
Manage.c | 2 +-
mdopen.c | 2 +-
4 files changed, 6 insertions(+), 6 deletions(-)

diff --git a/Build.c b/Build.c
index 70ba068..962c2e3 100644
--- a/Build.c
+++ b/Build.c
@@ -181,7 +181,7 @@ int Build(char *mddev, struct mddev_dev *devlist,
int major = BITMAP_MAJOR_HI;
#if 0
if (s->bitmap_chunk == UnSet) {
- pr_err("%s cannot be openned.", s->bitmap_file);
+ pr_err("%s cannot be opened.\n", s->bitmap_file);
goto abort;
}
#endif
@@ -193,7 +193,7 @@ int Build(char *mddev, struct mddev_dev *devlist,
}
bitmap_fd = open(s->bitmap_file, O_RDWR);
if (bitmap_fd < 0) {
- pr_err("%s cannot be openned.", s->bitmap_file);
+ pr_err("%s cannot be opened.\n", s->bitmap_file);
goto abort;
}
}
diff --git a/Grow.c b/Grow.c
index b1cb306..534ba80 100644
--- a/Grow.c
+++ b/Grow.c
@@ -3202,7 +3202,7 @@ static int reshape_array(char *container, int fd, char *devname,
if (info2) {
if (sysfs_init(info2, fd, st->devnm)) {
- pr_err("unable to initialize sysfs for %s",
+ pr_err("unable to initialize sysfs for %s\n",
st->devnm);
free(info2);
goto release;
@@ -5146,7 +5146,7 @@ int Grow_continue_command(char *devname, int fd,
}
if (sysfs_init(content, fd2, mdstat->devnm)) {
- pr_err("Unable to initialize sysfs for %s, Grow cannot continue",
+ pr_err("Unable to initialize sysfs for %s, Grow cannot continue.\n",
mdstat->devnm);
ret_val = 1;
close(fd2);
diff --git a/Manage.c b/Manage.c
index b82a729..871d342 100644
--- a/Manage.c
+++ b/Manage.c
@@ -1417,7 +1417,7 @@ int Manage_subdevs(char *devname, int fd,
}
add_devlist = conf_get_devs();
if (add_devlist == NULL) {
- pr_err("no devices to scan for missing members.");
+ pr_err("no devices to scan for missing members.\n");
continue;
}
for (dp = &add_devlist; *dp; dp = & (*dp)->next)
diff --git a/mdopen.c b/mdopen.c
index c4f1c12..3c0052f 100644
--- a/mdopen.c
+++ b/mdopen.c
@@ -198,7 +198,7 @@ int create_mddev(char *dev, char *name, int autof, int trustworthy,
return -1;
}
if (cname[0] == 0) {
- pr_err("%s is an invalid name for an md device (empty!).", dev);
+ pr_err("%s is an invalid name for an md device (empty!).\n", dev);
return -1;
}
if (num < 0) {
--
2.7.4

44
SOURCES/Fix-oddity-where-mdadm-did-not-recognise-a-relative-.patch

@ -0,0 +1,44 @@ @@ -0,0 +1,44 @@
From bb6f40bf9c458a13b1a780006733c034105e6d36 Mon Sep 17 00:00:00 2001
From: Wol <anthony@youngman.org.uk>
Date: Tue, 17 Jan 2017 17:47:05 +0000
Subject: [RHEL7.5 PATCH 003/169] Fix oddity where mdadm did not recognise
a relative path

mdadm assumed that a pathname started with a "/", while an array
name didn't. This alters the logic so that if the first character
is not a "/" it tries to open an array, and if that fails it drops
through to the pathname code rather than terminating immediately
with an error.

Signed-off-by: Wol <anthony@youngman.org.uk>
Signed-off-by: Jes Sorensen <Jes.Sorensen@gmail.com>
---
mdadm.c | 12 ++++++------
1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/mdadm.c b/mdadm.c
index c3a265b..b5d89e4 100644
--- a/mdadm.c
+++ b/mdadm.c
@@ -1899,12 +1899,12 @@ static int misc_list(struct mddev_dev *devlist,
rv |= SetAction(dv->devname, c->action);
continue;
}
- if (dv->devname[0] == '/')
- mdfd = open_mddev(dv->devname, 1);
- else {
- mdfd = open_dev(dv->devname);
- if (mdfd < 0)
- pr_err("Cannot open %s\n", dv->devname);
+ switch(dv->devname[0] == '/') {
+ case 0:
+ mdfd = open_dev(dv->devname);
+ if (mdfd >= 0) break;
+ case 1:
+ mdfd = open_mddev(dv->devname, 1);
}
if (mdfd>=0) {
switch(dv->disposition) {
--
2.7.4

45
SOURCES/Fix-typo2-in-new-udev-rule.patch

@ -0,0 +1,45 @@ @@ -0,0 +1,45 @@
From dd180cb136d6b2193a58ea0de23b8a7942ca6f36 Mon Sep 17 00:00:00 2001
From: NeilBrown <neilb@suse.com>
Date: Fri, 5 May 2017 15:16:15 +1000
Subject: [RHEL7.5 PATCH 111/169] Fix typo in new udev rule.

As pointed out by Peter Rajnoha, the correct usage in udev is
TEST=="file", not TEST="file".

Also improve a related comment which was a bit informal.

Reported-by: Peter Rajnoha <prajnoha@redhat.com>
Fixes: cd6cbb08c458 ("Create: tell udev md device is not ready when first created.")
Signed-off-by: NeilBrown <neilb@suse.com>
Signed-off-by: Jes Sorensen <jsorensen@fb.com>
---
lib.c | 2 +-
udev-md-raid-creating.rules | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/lib.c b/lib.c
index 7e44b1f..be093e8 100644
--- a/lib.c
+++ b/lib.c
@@ -165,7 +165,7 @@ char *fd2devnm(int fd)
/* When we create a new array, we don't want the content to
* be immediately examined by udev - it is probably meaningless.
- * So create /run/mdadm/creating-FOO and expect that a udev
+ * So create /run/mdadm/creating-mdXXX and expect that a udev
* rule will noticed this and act accordingly.
*/
static char block_path[] = "/run/mdadm/creating-%s";
diff --git a/udev-md-raid-creating.rules b/udev-md-raid-creating.rules
index 2be466b..9bef8d1 100644
--- a/udev-md-raid-creating.rules
+++ b/udev-md-raid-creating.rules
@@ -4,4 +4,4 @@
# the array is not "ready" and we should make sure the
# content is ignored.
-KERNEL=="md*", TEST="/run/mdadm/creating-$kernel", ENV{SYSTEMD_READY}="0"
+KERNEL=="md*", TEST=="/run/mdadm/creating-$kernel", ENV{SYSTEMD_READY}="0"
--
2.7.4

163
SOURCES/Get-failed-disk-count-fromarray-state.patch

@ -0,0 +1,163 @@ @@ -0,0 +1,163 @@
From b13b52c80f3d9e3184ea1d6d39aa7053ef7bae49 Mon Sep 17 00:00:00 2001
From: Tomasz Majchrzak <tomasz.majchrzak@intel.com>
Date: Wed, 31 May 2017 12:46:57 +0200
Subject: [RHEL7.5 PATCH 151/169] Get failed disk count from array state

Recent commit has changed the way failed disks are counted. It breaks
recovery for external metadata arrays as failed disks are not part of
the array and have no corresponding entries is sysfs (they are only
reported for containers) so degraded arrays show no failed disks.

Recent commit overwrites GET_DEGRADED result prior to GET_STATE and it
is not set again if GET_STATE has not been requested. As GET_STATE
provides the same information as GET_DEGRADED, the latter is not needed
anymore. Remove GET_DEGRADED option and replace it with GET_STATE
option.

Don't count number of failed disks looking at sysfs entries but
calculate it at the end. Do it only for arrays as containers report
no disks, just spares.

Signed-off-by: Tomasz Majchrzak <tomasz.majchrzak@intel.com>
Signed-off-by: Jes Sorensen <jsorensen@fb.com>
---
Incremental.c | 14 ++++----------
Monitor.c | 4 ++--
managemon.c | 4 ++--
mdadm.h | 1 -
raid6check.c | 2 +-
sysfs.c | 18 ++++++++----------
6 files changed, 17 insertions(+), 26 deletions(-)

diff --git a/Incremental.c b/Incremental.c
index 30dc7a2..6cf2174 100644
--- a/Incremental.c
+++ b/Incremental.c
@@ -886,16 +886,10 @@ static int array_try_spare(char *devname, int *dfdp, struct dev_policy *pol,
}
sra = sysfs_read(-1, mp->devnm,
GET_DEVS|GET_OFFSET|GET_SIZE|GET_STATE|
- GET_DEGRADED|GET_COMPONENT|GET_VERSION);
- if (!sra) {
- /* Probably a container - no degraded info */
- sra = sysfs_read(-1, mp->devnm,
- GET_DEVS|GET_OFFSET|GET_SIZE|GET_STATE|
- GET_COMPONENT|GET_VERSION);
- if (sra)
- sra->array.failed_disks = -1;
- }
- if (!sra)
+ GET_COMPONENT|GET_VERSION);
+ if (sra)
+ sra->array.failed_disks = -1;
+ else
continue;
if (st == NULL) {
int i;
diff --git a/Monitor.c b/Monitor.c
index 725f47d..bef2f1b 100644
--- a/Monitor.c
+++ b/Monitor.c
@@ -485,8 +485,8 @@ static int check_array(struct state *st, struct mdstat_ent *mdstat,
if (st->devnm[0] == 0)
strcpy(st->devnm, fd2devnm(fd));
- sra = sysfs_read(-1, st->devnm, GET_LEVEL | GET_DISKS | GET_DEGRADED |
- GET_MISMATCH | GET_DEVS | GET_STATE);
+ sra = sysfs_read(-1, st->devnm, GET_LEVEL | GET_DISKS | GET_MISMATCH |
+ GET_DEVS | GET_STATE);
if (!sra)
goto disappeared;
diff --git a/managemon.c b/managemon.c
index a8df666..68f0c2d 100644
--- a/managemon.c
+++ b/managemon.c
@@ -685,8 +685,8 @@ static void manage_new(struct mdstat_ent *mdstat,
mdi = sysfs_read(-1, mdstat->devnm,
GET_LEVEL|GET_CHUNK|GET_DISKS|GET_COMPONENT|
- GET_DEGRADED|GET_SAFEMODE|
- GET_DEVS|GET_OFFSET|GET_SIZE|GET_STATE|GET_LAYOUT);
+ GET_SAFEMODE|GET_DEVS|GET_OFFSET|GET_SIZE|GET_STATE|
+ GET_LAYOUT);
if (!mdi)
return;
diff --git a/mdadm.h b/mdadm.h
index ec0a39e..ee9b837 100644
--- a/mdadm.h
+++ b/mdadm.h
@@ -637,7 +637,6 @@ enum sysfs_read_flags {
GET_MISMATCH = (1 << 5),
GET_VERSION = (1 << 6),
GET_DISKS = (1 << 7),
- GET_DEGRADED = (1 << 8),
GET_SAFEMODE = (1 << 9),
GET_BITMAP_LOCATION = (1 << 10),
diff --git a/raid6check.c b/raid6check.c
index 551f835..a8e6005 100644
--- a/raid6check.c
+++ b/raid6check.c
@@ -562,7 +562,7 @@ int main(int argc, char *argv[])
GET_LEVEL|
GET_LAYOUT|
GET_DISKS|
- GET_DEGRADED |
+ GET_STATE |
GET_COMPONENT|
GET_CHUNK|
GET_DEVS|
diff --git a/sysfs.c b/sysfs.c
index e47f5e4..78d2b52 100644
--- a/sysfs.c
+++ b/sysfs.c
@@ -162,18 +162,12 @@ struct mdinfo *sysfs_read(int fd, char *devnm, unsigned long options)
goto abort;
sra->array.layout = strtoul(buf, NULL, 0);
}
- if (options & GET_DISKS) {
+ if (options & (GET_DISKS|GET_STATE)) {
strcpy(base, "raid_disks");
if (load_sys(fname, buf, sizeof(buf)))
goto abort;
sra->array.raid_disks = strtoul(buf, NULL, 0);
}
- if (options & GET_DEGRADED) {
- strcpy(base, "degraded");
- if (load_sys(fname, buf, sizeof(buf)))
- goto abort;
- sra->array.failed_disks = strtoul(buf, NULL, 0);
- }
if (options & GET_COMPONENT) {
strcpy(base, "component_size");
if (load_sys(fname, buf, sizeof(buf)))
@@ -359,10 +353,9 @@ struct mdinfo *sysfs_read(int fd, char *devnm, unsigned long options)
strcpy(dbase, "state");
if (load_sys(fname, buf, sizeof(buf)))
goto abort;
- if (strstr(buf, "faulty")) {
+ if (strstr(buf, "faulty"))
dev->disk.state |= (1<<MD_DISK_FAULTY);
- sra->array.failed_disks++;
- } else {
+ else {
sra->array.working_disks++;
if (strstr(buf, "in_sync")) {
dev->disk.state |= (1<<MD_DISK_SYNC);
@@ -379,6 +372,11 @@ struct mdinfo *sysfs_read(int fd, char *devnm, unsigned long options)
dev->errors = strtoul(buf, NULL, 0);
}
}
+
+ if ((options & GET_STATE) && sra->array.raid_disks)
+ sra->array.failed_disks = sra->array.raid_disks -
+ sra->array.active_disks - sra->array.spare_disks;
+
closedir(dir);
return sra;
--
2.7.4

41
SOURCES/Grow-Do-not-shadow-an-existing-variable.patch

@ -0,0 +1,41 @@ @@ -0,0 +1,41 @@
From 49948a3561dcd48a94b1c5e98a6d23c9263d1ca3 Mon Sep 17 00:00:00 2001
From: Jes Sorensen <Jes.Sorensen@gmail.com>
Date: Thu, 30 Mar 2017 10:46:01 -0400
Subject: [RHEL7.5 PATCH 043/169] Grow: Do not shadow an existing variable

Declaring 'int rv' twice within the same function is asking for
trouble.

Signed-off-by: Jes Sorensen <Jes.Sorensen@gmail.com>
---
Grow.c | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/Grow.c b/Grow.c
index 0d551ce..0c16d5b 100755
--- a/Grow.c
+++ b/Grow.c
@@ -1834,7 +1834,7 @@ int Grow_reshape(char *devname, int fd,
* pre-requisite spare devices (mdmon owns final validation)
*/
if (st->ss->external) {
- int rv;
+ int retval;
if (subarray) {
container = st->container_devnm;
@@ -1852,9 +1852,9 @@ int Grow_reshape(char *devname, int fd,
return 1;
}
- rv = st->ss->load_container(st, cfd, NULL);
+ retval = st->ss->load_container(st, cfd, NULL);
- if (rv) {
+ if (retval) {
pr_err("Cannot read superblock for %s\n",
devname);
free(subarray);
--
2.7.4

176
SOURCES/Grow-Fixup-a-pile-of-cosmetic-issues.patch

@ -0,0 +1,176 @@ @@ -0,0 +1,176 @@
From 6ebf34e6bdd9e952d00ad3c2f12a130bfb68965e Mon Sep 17 00:00:00 2001
From: Jes Sorensen <Jes.Sorensen@gmail.com>
Date: Wed, 29 Mar 2017 12:15:20 -0400
Subject: [RHEL7.5 PATCH 036/169] Grow: Fixup a pile of cosmetic issues

No code change, simply cleanup ugliness.

Signed-off-by: Jes Sorensen <Jes.Sorensen@gmail.com>
---
Grow.c | 60 ++++++++++++++++++++++++++++++++----------------------------
1 file changed, 32 insertions(+), 28 deletions(-)

diff --git a/Grow.c b/Grow.c
index b86b53e..6405f0e 100755
--- a/Grow.c
+++ b/Grow.c
@@ -1269,8 +1269,7 @@ char *analyse_change(char *devname, struct mdinfo *info, struct reshape *re)
* raid5 with 2 disks, or
* raid0 with 1 disk
*/
- if (info->new_level > 1 &&
- (info->component_size & 7))
+ if (info->new_level > 1 && (info->component_size & 7))
return "Cannot convert RAID1 of this size - reduce size to multiple of 4K first.";
if (info->new_level == 0) {
if (info->delta_disks != UnSet &&
@@ -1288,12 +1287,9 @@ char *analyse_change(char *devname, struct mdinfo *info, struct reshape *re)
re->level = 1;
return NULL;
}
- if (info->array.raid_disks != 2 &&
- info->new_level == 5)
+ if (info->array.raid_disks != 2 && info->new_level == 5)
return "Can only convert a 2-device array to RAID5";
- if (info->array.raid_disks == 2 &&
- info->new_level == 5) {
-
+ if (info->array.raid_disks == 2 && info->new_level == 5) {
re->level = 5;
re->before.data_disks = 1;
if (info->delta_disks != UnSet &&
@@ -1404,7 +1400,8 @@ char *analyse_change(char *devname, struct mdinfo *info, struct reshape *re)
case 0:
/* RAID0 can be converted to RAID10, or to RAID456 */
if (info->new_level == 10) {
- if (info->new_layout == UnSet && info->delta_disks == UnSet) {
+ if (info->new_layout == UnSet &&
+ info->delta_disks == UnSet) {
/* Assume near=2 layout */
info->new_layout = 0x102;
info->delta_disks = info->array.raid_disks;
@@ -1643,16 +1640,19 @@ char *analyse_change(char *devname, struct mdinfo *info, struct reshape *re)
if (info->delta_disks == UnSet)
info->delta_disks = delta_parity;
- re->after.data_disks = (re->before.data_disks
- + info->delta_disks
- - delta_parity);
+ re->after.data_disks =
+ (re->before.data_disks + info->delta_disks - delta_parity);
+
switch (re->level) {
- case 6: re->parity = 2;
+ case 6:
+ re->parity = 2;
break;
case 4:
- case 5: re->parity = 1;
+ case 5:
+ re->parity = 1;
break;
- default: re->parity = 0;
+ default:
+ re->parity = 0;
break;
}
/* So we have a restripe operation, we need to calculate the number
@@ -1706,7 +1706,7 @@ static int set_array_size(struct supertype *st, struct mdinfo *sra,
if (text_version == NULL)
text_version = sra->text_version;
- subarray = strchr(text_version+1, '/')+1;
+ subarray = strchr(text_version + 1, '/')+1;
info = st->ss->container_content(st, subarray);
if (info) {
unsigned long long current_size = 0;
@@ -1789,8 +1789,8 @@ int Grow_reshape(char *devname, int fd,
devname);
return 1;
}
- if (data_offset != INVALID_SECTORS && array.level != 10
- && (array.level < 4 || array.level > 6)) {
+ if (data_offset != INVALID_SECTORS && array.level != 10 &&
+ (array.level < 4 || array.level > 6)) {
pr_err("--grow --data-offset not yet supported\n");
return 1;
}
@@ -1802,8 +1802,8 @@ int Grow_reshape(char *devname, int fd,
return 1;
}
- if (s->raiddisks && s->raiddisks < array.raid_disks && array.level > 1 &&
- get_linux_version() < 2006032 &&
+ if (s->raiddisks && s->raiddisks < array.raid_disks &&
+ array.level > 1 && get_linux_version() < 2006032 &&
!check_env("MDADM_FORCE_FEWER")) {
pr_err("reducing the number of devices is not safe before Linux 2.6.32\n"
" Please use a newer kernel\n");
@@ -1873,10 +1873,11 @@ int Grow_reshape(char *devname, int fd,
/* check if reshape is allowed based on metadata
* indications stored in content.array.status
*/
- if (content->array.state & (1<<MD_SB_BLOCK_VOLUME))
+ if (content->array.state &
+ (1 << MD_SB_BLOCK_VOLUME))
allow_reshape = 0;
- if (content->array.state
- & (1<<MD_SB_BLOCK_CONTAINER_RESHAPE))
+ if (content->array.state &
+ (1 << MD_SB_BLOCK_CONTAINER_RESHAPE))
allow_reshape = 0;
if (!allow_reshape) {
pr_err("cannot reshape arrays in container with unsupported metadata: %s(%s)\n",
@@ -1896,7 +1897,7 @@ int Grow_reshape(char *devname, int fd,
for (dv = devlist; dv; dv = dv->next)
added_disks++;
if (s->raiddisks > array.raid_disks &&
- array.spare_disks +added_disks < (s->raiddisks - array.raid_disks) &&
+ array.spare_disks + added_disks < (s->raiddisks - array.raid_disks) &&
!c->force) {
pr_err("Need %d spare%s to avoid degraded array, and only have %d.\n"
" Use --force to over-ride this check.\n",
@@ -1906,8 +1907,8 @@ int Grow_reshape(char *devname, int fd,
return 1;
}
- sra = sysfs_read(fd, NULL, GET_LEVEL | GET_DISKS | GET_DEVS
- | GET_STATE | GET_VERSION);
+ sra = sysfs_read(fd, NULL, GET_LEVEL | GET_DISKS | GET_DEVS |
+ GET_STATE | GET_VERSION);
if (sra) {
if (st->ss->external && subarray == NULL) {
array.level = LEVEL_CONTAINER;
@@ -1930,7 +1931,8 @@ int Grow_reshape(char *devname, int fd,
}
/* ========= set size =============== */
- if (s->size > 0 && (s->size == MAX_SIZE || s->size != (unsigned)array.size)) {
+ if (s->size > 0 &&
+ (s->size == MAX_SIZE || s->size != (unsigned)array.size)) {
unsigned long long orig_size = get_component_size(fd)/2;
unsigned long long min_csize;
struct mdinfo *mdi;
@@ -1946,7 +1948,8 @@ int Grow_reshape(char *devname, int fd,
}
if (reshape_super(st, s->size, UnSet, UnSet, 0, 0, UnSet, NULL,
- devname, APPLY_METADATA_CHANGES, c->verbose > 0)) {
+ devname, APPLY_METADATA_CHANGES,
+ c->verbose > 0)) {
rv = 1;
goto release;
}
@@ -1965,7 +1968,8 @@ int Grow_reshape(char *devname, int fd,
sizeinfo->array.layout,
sizeinfo->array.raid_disks);
new_size /= data_disks;
- dprintf("Metadata size correction from %llu to %llu (%llu)\n", orig_size, new_size,
+ dprintf("Metadata size correction from %llu to %llu (%llu)\n",
+ orig_size, new_size,
new_size * data_disks);
s->size = new_size;
sysfs_free(sizeinfo);
--
2.7.4

41
SOURCES/Grow-Grow_continue_command-Avoid-aliasing-array-vari.patch

@ -0,0 +1,41 @@ @@ -0,0 +1,41 @@
From 9e4524df1c6c85c362278a08fd4425888d27581f Mon Sep 17 00:00:00 2001
From: Jes Sorensen <jsorensen@fb.com>
Date: Tue, 2 May 2017 11:46:49 -0400
Subject: [RHEL7.5 PATCH 104/169] Grow: Grow_continue_command: Avoid
aliasing array variable

While this would cause a warning since the two are different types,
lets avoid aliasing an existing variable.

Signed-off-by: Jes Sorensen <jsorensen@fb.com>
---
Grow.c | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/Grow.c b/Grow.c
index c6967ed..f4bd301 100755
--- a/Grow.c
+++ b/Grow.c
@@ -5075,7 +5075,7 @@ int Grow_continue_command(char *devname, int fd,
cc = st->ss->container_content(st, subarray);
for (content = cc; content ; content = content->next) {
- char *array;
+ char *array_name;
int allow_reshape = 1;
if (content->reshape_active == 0)
@@ -5100,8 +5100,8 @@ int Grow_continue_command(char *devname, int fd,
goto Grow_continue_command_exit;
}
- array = strchr(content->text_version+1, '/')+1;
- mdstat = mdstat_by_subdev(array, container);
+ array_name = strchr(content->text_version+1, '/')+1;
+ mdstat = mdstat_by_subdev(array_name, container);
if (!mdstat)
continue;
if (mdstat->active == 0) {
--
2.7.4

51
SOURCES/Grow-Remove-unnecessary-optimization.patch

@ -0,0 +1,51 @@ @@ -0,0 +1,51 @@
From 758b327cf5a7aab50ae5c70ecbc371dc4f715bb6 Mon Sep 17 00:00:00 2001
From: Jes Sorensen <jes@wobbly.dhcp.thefacebook.com>
Date: Thu, 30 Mar 2017 10:39:29 -0400
Subject: [RHEL7.5 PATCH 042/169] Grow: Remove unnecessary optimization

Per explanation by Neil, this optimization of writing "size" to the
attribute of each device, however when reducing the size of devices,
the size change isn't permitted until the array has been shrunk, so
this will fail anyway.

This effectively reverts 65a9798b58b4e4de0157043e2b30a738c27eff43

Signed-off-by: Jes Sorensen <Jes.Sorensen@gmail.com>
---
Grow.c | 12 ------------
1 file changed, 12 deletions(-)

diff --git a/Grow.c b/Grow.c
index af8d520..0d551ce 100755
--- a/Grow.c
+++ b/Grow.c
@@ -1982,15 +1982,7 @@ int Grow_reshape(char *devname, int fd,
* understands '0' to mean 'max'.
*/
min_csize = 0;
- rv = 0;
for (mdi = sra->devs; mdi; mdi = mdi->next) {
- if (sysfs_set_num(sra, mdi, "size",
- s->size == MAX_SIZE ? 0 : s->size) < 0) {
- /* Probably kernel refusing to let us
- * reduce the size - not an error.
- */
- break;
- }
if (array.not_persistent == 0 &&
array.major_version == 0 &&
get_linux_version() < 3001000) {
@@ -2005,10 +1997,6 @@ int Grow_reshape(char *devname, int fd,
}
}
}
- if (rv) {
- pr_err("Cannot set size on array members.\n");
- goto size_change_error;
- }
if (min_csize && s->size > min_csize) {
pr_err("Cannot safely make this array use more than 2TB per device on this kernel.\n");
rv = 1;
--
2.7.4

35
SOURCES/Grow-Stop-bothering-about-md-driver-versions-older-t.patch

@ -0,0 +1,35 @@ @@ -0,0 +1,35 @@
From 6ae8b2b3140475b1a70485052454210aba4065a6 Mon Sep 17 00:00:00 2001
From: Jes Sorensen <Jes.Sorensen@gmail.com>
Date: Wed, 5 Apr 2017 15:22:36 -0400
Subject: [RHEL7.5 PATCH 056/169] Grow: Stop bothering about md driver
versions older than 0.90.00

Signed-off-by: Jes Sorensen <Jes.Sorensen@gmail.com>
---
Grow.c | 7 -------
1 file changed, 7 deletions(-)

diff --git a/Grow.c b/Grow.c
index 78a3474..15f4ed1 100755
--- a/Grow.c
+++ b/Grow.c
@@ -288,16 +288,9 @@ int Grow_addbitmap(char *devname, int fd, struct context *c, struct shape *s)
struct supertype *st;
char *subarray = NULL;
int major = BITMAP_MAJOR_HI;
- int vers = md_get_version(fd);
unsigned long long bitmapsize, array_size;
struct mdinfo *mdi;
- if (vers < 9003) {
- major = BITMAP_MAJOR_HOSTENDIAN;
- pr_err("Warning - bitmaps created on this kernel are not portable\n"
- " between different architectures. Consider upgrading the Linux kernel.\n");
- }
-
/*
* We only ever get called if s->bitmap_file is != NULL, so this check
* is just here to quiet down static code checkers.
--
2.7.4

34
SOURCES/Grow-fix-switching-on-PPL-during-recovery.patch

@ -0,0 +1,34 @@ @@ -0,0 +1,34 @@
From 41b25549f080ebac1269689f942f722368ed28b1 Mon Sep 17 00:00:00 2001
From: Pawel Baldysiak <pawel.baldysiak@intel.com>
Date: Thu, 28 Sep 2017 14:41:13 +0200
Subject: [PATCH 07/12] Grow: fix switching on PPL during recovery

If raid memeber is not in sync - it is skipped during
enablement of PPL. This is not correct, since the drive that
we are currently recovering to does not have ppl_size and ppl_sector
properly set in sysfs.
Remove this skipping, so all drives are updated during turning on the PPL.

Signed-off-by: Pawel Baldysiak <pawel.baldysiak@intel.com>
Signed-off-by: Jes Sorensen <jsorensen@fb.com>
---
Grow.c | 3 ---
1 file changed, 3 deletions(-)

diff --git a/Grow.c b/Grow.c
index bab1eec..1149753 100644
--- a/Grow.c
+++ b/Grow.c
@@ -637,9 +637,6 @@ int Grow_consistency_policy(char *devname, int fd, struct context *c, struct sha
int dfd;
char *devpath;
- if ((sd->disk.state & (1 << MD_DISK_SYNC)) == 0)
- continue;
-
devpath = map_dev(sd->disk.major, sd->disk.minor, 0);
dfd = dev_open(devpath, O_RDWR);
if (dfd < 0) {
--
2.7.4

34
SOURCES/Grow-set-component-size-prior-to-array-size.patch

@ -0,0 +1,34 @@ @@ -0,0 +1,34 @@
From 07c45a1871df0a70beb8da80d11601d33c7a5de2 Mon Sep 17 00:00:00 2001
From: Tomasz Majchrzak <tomasz.majchrzak@intel.com>
Date: Mon, 5 Jun 2017 16:09:44 +0200
Subject: [RHEL7.5 PATCH 150/169] Grow: set component size prior to array
size

It is a partial revert of commit 758b327cf5a7 ("Grow: Remove unnecessary
optimization"). For native metadata component size is set in kernel for
entire disk space. As external metadata supports multiple arrays within
one disk, the component size is set to array size. If component size is
not updated prior to array size update, the grow operation fails.

Signed-off-by: Tomasz Majchrzak <tomasz.majchrzak@intel.com>
Signed-off-by: Jes Sorensen <jsorensen@fb.com>
---
Grow.c | 2 ++
1 file changed, 2 insertions(+)

diff --git a/Grow.c b/Grow.c
index ecf5ca0..4ecb1d8 100644
--- a/Grow.c
+++ b/Grow.c
@@ -1977,6 +1977,8 @@ int Grow_reshape(char *devname, int fd,
*/
min_csize = 0;
for (mdi = sra->devs; mdi; mdi = mdi->next) {
+ sysfs_set_num(sra, mdi, "size", s->size == MAX_SIZE ? 0
+ : s->size);
if (array.not_persistent == 0 &&
array.major_version == 0 &&
get_linux_version() < 3001000) {
--
2.7.4

36
SOURCES/Grow_continue_command-ensure-content-is-properly-ini.patch

@ -0,0 +1,36 @@ @@ -0,0 +1,36 @@
From a250ce240f245df594570a5e25398680d403af67 Mon Sep 17 00:00:00 2001
From: NeilBrown <neilb@suse.com>
Date: Thu, 20 Apr 2017 12:40:05 +1000
Subject: [RHEL7.5 PATCH 087/169] Grow_continue_command: ensure 'content'
is properly initialised.

Grow_continue_command() call verify_reshape_position(), which assumes
that info->sys_name is initialised.
'info' in verify_reshape_position() is 'content' in Grow_continue_command().

In the st->ss->external != 0 branch of that function, sysfs_init() is called
to initialize content->sys_name.
In the st->ss->external == 0 branch, ->sys_name is not initialized so
verify_reshape_position() will not do the right thing.

Signed-off-by: NeilBrown <neilb@suse.com>
Signed-off-by: Jes Sorensen <jsorensen@fb.com>
---
Grow.c | 1 +
1 file changed, 1 insertion(+)

diff --git a/Grow.c b/Grow.c
index 15f4ed1..c6967ed 100755
--- a/Grow.c
+++ b/Grow.c
@@ -5002,6 +5002,7 @@ int Grow_continue_command(char *devname, int fd,
goto Grow_continue_command_exit;
}
content = &array;
+ sysfs_init(content, fd, NULL);
/* Need to load a superblock.
* FIXME we should really get what we need from
* sysfs
--
2.7.4

47
SOURCES/IMSM-Initialize-my_vol_raid_dev_num-during-vol-creat.patch

@ -0,0 +1,47 @@ @@ -0,0 +1,47 @@
From 2a24dc1b0988a7d924de6339754d4160762a61f7 Mon Sep 17 00:00:00 2001
From: Pawel Baldysiak <pawel.baldysiak@intel.com>
Date: Wed, 26 Apr 2017 11:08:07 +0200
Subject: [RHEL7.5 PATCH 103/169] IMSM: Initialize my_vol_raid_dev_num
during vol creation

This field was not initialized so far. This ID needs to be unique
for every newly created array in container.

Signed-off-by: Pawel Baldysiak <pawel.baldysiak@intel.com>
Signed-off-by: Jes Sorensen <jsorensen@fb.com>
---
super-intel.c | 11 +++++++++--
1 file changed, 9 insertions(+), 2 deletions(-)

diff --git a/super-intel.c b/super-intel.c
index fbff215..36f77d3 100644
--- a/super-intel.c
+++ b/super-intel.c
@@ -232,8 +232,13 @@ struct imsm_super {
__u32 orig_family_num; /* 0x40 - 0x43 original family num */
__u32 pwr_cycle_count; /* 0x44 - 0x47 simulated power cycle count for array */
__u32 bbm_log_size; /* 0x48 - 0x4B - size of bad Block Mgmt Log in bytes */
-#define IMSM_FILLERS 35
- __u32 filler[IMSM_FILLERS]; /* 0x4C - 0xD7 RAID_MPB_FILLERS */
+ __u16 num_raid_devs_created; /* 0x4C - 0x4D Used for generating unique
+ * volume IDs for raid_dev created in this array
+ * (starts at 1)
+ */
+ __u16 filler1; /* 0x4E - 0x4F */
+#define IMSM_FILLERS 34
+ __u32 filler[IMSM_FILLERS]; /* 0x50 - 0xD7 RAID_MPB_FILLERS */
struct imsm_disk disk[1]; /* 0xD8 diskTbl[numDisks] */
/* here comes imsm_dev[num_raid_devs] */
/* here comes BBM logs */
@@ -5368,6 +5373,8 @@ static int init_super_imsm_volume(struct supertype *st, mdu_array_info_t *info,
set_imsm_ord_tbl_ent(map, i, IMSM_ORD_REBUILD);
}
mpb->num_raid_devs++;
+ mpb->num_raid_devs_created++;
+ dev->my_vol_raid_dev_num = mpb->num_raid_devs_created;
if (s->consistency_policy <= CONSISTENCY_POLICY_RESYNC) {
dev->rwh_policy = RWH_OFF;
--
2.7.4

152
SOURCES/Incremental-Cleanup-some-if-statement-spaghetti.patch

@ -0,0 +1,152 @@ @@ -0,0 +1,152 @@
From f8c432bfc9929dbbcb659b2d11552dc9fc76ad24 Mon Sep 17 00:00:00 2001
From: Jes Sorensen <jsorensen@fb.com>
Date: Tue, 25 Apr 2017 15:01:43 -0400
Subject: [RHEL7.5 PATCH 099/169] Incremental: Cleanup some if() statement
spaghetti

Signed-off-by: Jes Sorensen <jsorensen@fb.com>
---
Incremental.c | 50 +++++++++++++++++++++-----------------------------
1 file changed, 21 insertions(+), 29 deletions(-)

diff --git a/Incremental.c b/Incremental.c
index a351151..66c5b03 100644
--- a/Incremental.c
+++ b/Incremental.c
@@ -225,8 +225,8 @@ int Incremental(struct mddev_dev *devlist, struct context *c,
if (!match && rv == 2)
goto out;
- if (match && match->devname
- && strcasecmp(match->devname, "<ignore>") == 0) {
+ if (match && match->devname &&
+ strcasecmp(match->devname, "<ignore>") == 0) {
if (c->verbose >= 0)
pr_err("array containing %s is explicitly ignored by mdadm.conf\n",
devname);
@@ -267,8 +267,7 @@ int Incremental(struct mddev_dev *devlist, struct context *c,
c->autof = ci->autof;
name_to_use = info.name;
- if (name_to_use[0] == 0 &&
- info.array.level == LEVEL_CONTAINER) {
+ if (name_to_use[0] == 0 && info.array.level == LEVEL_CONTAINER) {
name_to_use = info.text_version;
trustworthy = METADATA;
}
@@ -398,11 +397,10 @@ int Incremental(struct mddev_dev *devlist, struct context *c,
* flag has a different meaning. The test has to happen
* at the device level there
*/
- if (!st->ss->external
- && (info.disk.state & (1<<MD_DISK_SYNC)) != 0
- && ! policy_action_allows(policy, st->ss->name,
- act_re_add)
- && c->runstop < 1) {
+ if (!st->ss->external &&
+ (info.disk.state & (1 << MD_DISK_SYNC)) != 0 &&
+ !policy_action_allows(policy, st->ss->name, act_re_add) &&
+ c->runstop < 1) {
if (md_array_active(mdfd)) {
pr_err("not adding %s to active array (without --run) %s\n",
devname, chosen_name);
@@ -537,8 +535,7 @@ int Incremental(struct mddev_dev *devlist, struct context *c,
info.array.state |= 1;
if (enough(info.array.level, info.array.raid_disks,
- info.array.layout, info.array.state & 1,
- avail) == 0) {
+ info.array.layout, info.array.state & 1, avail) == 0) {
if (c->export) {
printf("MD_STARTED=no\n");
} else if (c->verbose >= 0)
@@ -599,8 +596,8 @@ int Incremental(struct mddev_dev *devlist, struct context *c,
if (d->disk.state & (1<<MD_DISK_REMOVED))
remove_disk(mdfd, st, sra, d);
- if ((sra == NULL || active_disks >= info.array.working_disks)
- && trustworthy != FOREIGN)
+ if ((sra == NULL || active_disks >= info.array.working_disks) &&
+ trustworthy != FOREIGN)
rv = ioctl(mdfd, RUN_ARRAY, NULL);
else
rv = sysfs_set_str(sra, NULL,
@@ -624,7 +621,8 @@ int Incremental(struct mddev_dev *devlist, struct context *c,
* those devices we should re-add them now.
*/
for (dsk = sra->devs; dsk ; dsk = dsk->next) {
- if (disk_action_allows(dsk, st->ss->name, act_re_add) &&
+ if (disk_action_allows(dsk, st->ss->name,
+ act_re_add) &&
add_disk(mdfd, st, sra, dsk) == 0)
pr_err("%s re-added to %s\n",
dsk->sys_name, chosen_name);
@@ -688,8 +686,7 @@ static void find_reject(int mdfd, struct supertype *st, struct mdinfo *sra,
st->ss->free_super(st);
close(dfd);
- if (info.disk.number != number ||
- info.events >= events)
+ if (info.disk.number != number || info.events >= events)
continue;
if (d->disk.raid_disk > -1)
@@ -970,11 +967,9 @@ static int array_try_spare(char *devname, int *dfdp, struct dev_policy *pol,
}
if ((sra->component_size > 0 &&
st2->ss->avail_size(st2, devsize,
- sra->devs
- ? sra->devs->data_offset
- : INVALID_SECTORS)
- < sra->component_size)
- ||
+ sra->devs ? sra->devs->data_offset :
+ INVALID_SECTORS) <
+ sra->component_size) ||
(sra->component_size == 0 && devsize < component_size)) {
if (verbose > 1)
pr_err("not adding %s to %s as it is too small\n",
@@ -1107,8 +1102,7 @@ static int partition_try_spare(char *devname, int *dfdp, struct dev_policy *pol,
char *devname = NULL;
unsigned long long devsectors;
- if (de->d_ino == 0 ||
- de->d_name[0] == '.' ||
+ if (de->d_ino == 0 || de->d_name[0] == '.' ||
(de->d_type != DT_LNK && de->d_type != DT_UNKNOWN))
goto next;
@@ -1146,8 +1140,7 @@ static int partition_try_spare(char *devname, int *dfdp, struct dev_policy *pol,
st2 = dup_super(st);
else
st2 = guess_super_type(fd, guess_partitions);
- if (st2 == NULL ||
- st2->ss->load_super(st2, fd, NULL) < 0)
+ if (st2 == NULL || st2->ss->load_super(st2, fd, NULL) < 0)
goto next;
st2->ignore_hw_compat = 0;
@@ -1175,8 +1168,7 @@ static int partition_try_spare(char *devname, int *dfdp, struct dev_policy *pol,
* metadata which makes better use of the device can
* be found.
*/
- if (chosen == NULL ||
- chosen_size < info.component_size) {
+ if (chosen == NULL || chosen_size < info.component_size) {
chosen_size = info.component_size;
free(chosen);
chosen = devname;
@@ -1399,8 +1391,8 @@ restart:
}
/* Ok, we can try this one. Maybe it needs a bitmap */
for (mddev = devs ; mddev ; mddev = mddev->next)
- if (mddev->devname && me->path
- && devname_matches(mddev->devname, me->path))
+ if (mddev->devname && me->path &&
+ devname_matches(mddev->devname, me->path))
break;
if (mddev && mddev->bitmap_file) {
/*
--
2.7.4

54
SOURCES/Incremental-Remove-redundant-call-for-GET_ARRAY_INFO.patch

@ -0,0 +1,54 @@ @@ -0,0 +1,54 @@
From 5b13d2e1fb8abecddd4e28e67facac5d7ef2cef3 Mon Sep 17 00:00:00 2001
From: Jes Sorensen <Jes.Sorensen@gmail.com>
Date: Wed, 29 Mar 2017 14:40:36 -0400
Subject: [RHEL7.5 PATCH 038/169] Incremental: Remove redundant call for
GET_ARRAY_INFO

The code above just called md_get_array_info() and only reached this
point if it returned an error that isn't ENODEV, so it's pointless to
check this again here.

In addition it was incorrectly retrieving ioctl data into a
mdu_bitmap_file_t instead of mdu_array_info_t.

Fixes: ("8382f19 Add new mode: --incremental")
Signed-off-by: Jes Sorensen <Jes.Sorensen@gmail.com>
---
Incremental.c | 14 ++++++--------
1 file changed, 6 insertions(+), 8 deletions(-)

diff --git a/Incremental.c b/Incremental.c
index 1f12c77..802e525 100644
--- a/Incremental.c
+++ b/Incremental.c
@@ -1345,7 +1345,6 @@ int IncrementalScan(struct context *c, char *devnm)
restart:
for (me = mapl ; me ; me = me->next) {
mdu_array_info_t array;
- mdu_bitmap_file_t bmf;
struct mdinfo *sra;
int mdfd;
@@ -1405,13 +1404,12 @@ restart:
* is a hint only
*/
int added = -1;
- if (ioctl(mdfd, GET_ARRAY_INFO, &bmf) < 0) {
- int bmfd = open(mddev->bitmap_file, O_RDWR);
- if (bmfd >= 0) {
- added = ioctl(mdfd, SET_BITMAP_FILE,
- bmfd);
- close(bmfd);
- }
+ int bmfd;
+
+ bmfd = open(mddev->bitmap_file, O_RDWR);
+ if (bmfd >= 0) {
+ added = ioctl(mdfd, SET_BITMAP_FILE, bmfd);
+ close(bmfd);
}
if (c->verbose >= 0) {
if (added == 0)
--
2.7.4

37
SOURCES/Incremental-Use-md_array_active-to-determine3-state-o.patch

@ -0,0 +1,37 @@ @@ -0,0 +1,37 @@
From 6921010d95dbc32c812aa8ffdbfa28e78b54b342 Mon Sep 17 00:00:00 2001
From: Jes Sorensen <jsorensen@fb.com>
Date: Tue, 2 May 2017 10:36:51 -0400
Subject: [RHEL7.5 PATCH 101/169] Incremental: Use md_array_active() to
determine state of array

One less call to md_get_array_info()

Signed-off-by: Jes Sorensen <jsorensen@fb.com>
---
Incremental.c | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/Incremental.c b/Incremental.c
index 4789e36..8909f2f 100644
--- a/Incremental.c
+++ b/Incremental.c
@@ -99,7 +99,6 @@ int Incremental(struct mddev_dev *devlist, struct context *c,
int active_disks;
int trustworthy;
char *name_to_use;
- mdu_array_info_t ainf;
struct dev_policy *policy = NULL;
struct map_ent target_array;
int have_target;
@@ -551,7 +550,7 @@ int Incremental(struct mddev_dev *devlist, struct context *c,
/* + add any bitmap file */
/* + start the array (auto-readonly). */
- if (md_get_array_info(mdfd, &ainf) == 0) {
+ if (md_array_active(mdfd)) {
if (c->export) {
printf("MD_STARTED=already\n");
} else if (c->verbose >= 0)
--
2.7.4

41
SOURCES/Incremental-Use-md_array_active-where-applicable.patch

@ -0,0 +1,41 @@ @@ -0,0 +1,41 @@
From ff4ad24b1c261ab4d286cbe54157d7c588191692 Mon Sep 17 00:00:00 2001
From: Jes Sorensen <jsorensen@fb.com>
Date: Tue, 25 Apr 2017 14:57:46 -0400
Subject: [RHEL7.5 PATCH 098/169] Incremental: Use md_array_active() where
applicable

md_get_array_info() == 0 implies an array is active, however this is more
correct.

Signed-off-by: Jes Sorensen <jsorensen@fb.com>
---
Incremental.c | 5 ++---
1 file changed, 2 insertions(+), 3 deletions(-)

diff --git a/Incremental.c b/Incremental.c
index 28f1f77..a351151 100644
--- a/Incremental.c
+++ b/Incremental.c
@@ -403,7 +403,7 @@ int Incremental(struct mddev_dev *devlist, struct context *c,
&& ! policy_action_allows(policy, st->ss->name,
act_re_add)
&& c->runstop < 1) {
- if (md_get_array_info(mdfd, &ainf) == 0) {
+ if (md_array_active(mdfd)) {
pr_err("not adding %s to active array (without --run) %s\n",
devname, chosen_name);
rv = 2;
@@ -667,9 +667,8 @@ static void find_reject(int mdfd, struct supertype *st, struct mdinfo *sra,
* and events less than the passed events, and remove the device.
*/
struct mdinfo *d;
- mdu_array_info_t ra;
- if (md_get_array_info(mdfd, &ra) == 0)
+ if (md_array_active(mdfd))
return; /* not safe to remove from active arrays
* without thinking more */
--
2.7.4

26
SOURCES/Incremental-returnis-not-a-function.patch

@ -0,0 +1,26 @@ @@ -0,0 +1,26 @@
From c2d1a6ec6b94385e64e721b733bd44d1d704b530 Mon Sep 17 00:00:00 2001
From: Jes Sorensen <jsorensen@fb.com>
Date: Fri, 5 May 2017 11:39:58 -0400
Subject: [RHEL7.5 PATCH 112/169] Incremental: return is not a function

Signed-off-by: Jes Sorensen <jsorensen@fb.com>
---
Incremental.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/Incremental.c b/Incremental.c
index 97b2e99..c00a43d 100644
--- a/Incremental.c
+++ b/Incremental.c
@@ -823,7 +823,7 @@ static int container_members_max_degradation(struct map_ent *map, struct map_ent
}
close(afd);
}
- return (max_degraded);
+ return max_degraded;
}
static int array_try_spare(char *devname, int *dfdp, struct dev_policy *pol,
--
2.7.4

38
SOURCES/IncrementalScan-Use-md_array_active-instead-of-mdge.patch

@ -0,0 +1,38 @@ @@ -0,0 +1,38 @@
From 00e56fd9537e1f69583d8b0f60faf02026f24d1b Mon Sep 17 00:00:00 2001
From: Jes Sorensen <jsorensen@fb.com>
Date: Fri, 5 May 2017 12:18:29 -0400
Subject: [RHEL7.5 PATCH 115/169] IncrementalScan: Use md_array_active()
instead of md_get_array_info()

This eliminates yet another case where GET_ARRAY_INFO was used to
indicate whether the array was active.

Signed-off-by: Jes Sorensen <jsorensen@fb.com>
---
Incremental.c | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/Incremental.c b/Incremental.c
index b73eabd..680d318 100644
--- a/Incremental.c
+++ b/Incremental.c
@@ -1317,7 +1317,6 @@ int IncrementalScan(struct context *c, char *devnm)
restart:
for (me = mapl ; me ; me = me->next) {
- mdu_array_info_t array;
struct mdinfo *sra;
int mdfd;
@@ -1362,7 +1361,7 @@ restart:
rv = 1;
continue;
}
- if (md_get_array_info(mdfd, &array) == 0 || errno != ENODEV) {
+ if (md_array_active(mdfd)) {
close(mdfd);
continue;
}
--
2.7.4

74
SOURCES/Introduce1-sys_hot_remove_disk.patch

@ -0,0 +1,74 @@ @@ -0,0 +1,74 @@
From fdd015696c2e2a6b234a92af564aea44b62e6a0d Mon Sep 17 00:00:00 2001
From: NeilBrown <neilb@suse.com>
Date: Mon, 27 Mar 2017 14:36:56 +1100
Subject: [RHEL7.5 PATCH 022/169] Introduce sys_hot_remove_disk()

The new hot_remove_disk() will retry HOT_REMOVE_DISK
several times in the face of EBUSY.
However we sometimes remove a device by writing "remove" to the
"state" attributed. This should be retried as well.
So introduce sys_hot_remove_disk() to repeat this action a few times.

Signed-off-by: NeilBrown <neilb@suse.com>
Signed-off-by: Jes Sorensen <Jes.Sorensen@gmail.com>
---
Manage.c | 6 +-----
mdadm.h | 1 +
util.c | 12 ++++++++++++
3 files changed, 14 insertions(+), 5 deletions(-)

diff --git a/Manage.c b/Manage.c
index 9139f96..edf5798 100644
--- a/Manage.c
+++ b/Manage.c
@@ -1177,11 +1177,7 @@ int Manage_remove(struct supertype *tst, int fd, struct mddev_dev *dv,
/* device has been removed and we don't know
* the major:minor number
*/
- int n = write(sysfd, "remove", 6);
- if (n != 6)
- err = -1;
- else
- err = 0;
+ err = sys_hot_remove_disk(sysfd);
} else {
err = hot_remove_disk(fd, rdev);
if (err && errno == ENODEV) {
diff --git a/mdadm.h b/mdadm.h
index 5bcfb86..b855d24 100644
--- a/mdadm.h
+++ b/mdadm.h
@@ -1477,6 +1477,7 @@ extern int add_disk(int mdfd, struct supertype *st,
extern int remove_disk(int mdfd, struct supertype *st,
struct mdinfo *sra, struct mdinfo *info);
extern int hot_remove_disk(int mdfd, unsigned long dev);
+extern int sys_hot_remove_disk(int statefd);
extern int set_array_info(int mdfd, struct supertype *st, struct mdinfo *info);
unsigned long long min_recovery_start(struct mdinfo *array);
diff --git a/util.c b/util.c
index d09a7e2..b718531 100644
--- a/util.c
+++ b/util.c
@@ -1813,6 +1813,18 @@ int hot_remove_disk(int mdfd, unsigned long dev)
return ret;
}
+int sys_hot_remove_disk(int statefd)
+{
+ int cnt = 5;
+ int ret;
+
+ while ((ret = write(statefd, "remove", 6)) == -1 &&
+ errno == EBUSY &&
+ cnt-- > 0)
+ usleep(10000);
+ return ret == 6 ? 0 : -1;
+}
+
int set_array_info(int mdfd, struct supertype *st, struct mdinfo *info)
{
/* Initialise kernel's knowledge of array.
--
2.7.4

25
SOURCES/Makefile-Default-to-O2-optimization1.patch

@ -0,0 +1,25 @@ @@ -0,0 +1,25 @@
From 17d80e6eb64230593ee8d599b94005d303eb58ae Mon Sep 17 00:00:00 2001
From: Jes Sorensen <jsorensen@fb.com>
Date: Fri, 21 Apr 2017 12:06:35 -0400
Subject: [RHEL7.5 PATCH 091/169] Makefile: Default to -O2 optimization

Signed-off-by: Jes Sorensen <jsorensen@fb.com>
---
Makefile | 1 +
1 file changed, 1 insertion(+)

diff --git a/Makefile b/Makefile
index 5655812..6850696 100644
--- a/Makefile
+++ b/Makefile
@@ -30,6 +30,7 @@
# define "CXFLAGS" to give extra flags to CC.
# e.g. make CXFLAGS=-O to optimise
+CXFLAGS ?=-O2
TCC = tcc
UCLIBC_GCC = $(shell for nm in i386-uclibc-linux-gcc i386-uclibc-gcc; do which $$nm > /dev/null && { echo $$nm ; exit; } ; done; echo false No uclibc found )
#DIET_GCC = diet gcc
--
2.7.4

31
SOURCES/Makefile-Fix-date-to-be-output-in-ISO-format.patch

@ -0,0 +1,31 @@ @@ -0,0 +1,31 @@
From 53835cf50023aaad6887b647a3aaab524bd9b39e Mon Sep 17 00:00:00 2001
From: Jes Sorensen <Jes.Sorensen@gmail.com>
Date: Tue, 10 Jan 2017 18:51:40 -0500
Subject: [RHEL7.5 PATCH 001/169] Makefile: Fix date to be output in ISO
format

Updated the static version in the release, but forgot to fix the
Makefile generated version when extracting from git

Reported-by: NeilBrown <neilb@suse.com>
Signed-off-by: Jes Sorensen <Jes.Sorensen@gmail.com>
---
Makefile | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/Makefile b/Makefile
index 5fd7f16..a6f464c 100644
--- a/Makefile
+++ b/Makefile
@@ -89,7 +89,7 @@ DIRFLAGS += -DFAILED_SLOTS_DIR=\"$(FAILED_SLOTS_DIR)\"
CFLAGS = $(CWFLAGS) $(CXFLAGS) -DSendmail=\""$(MAILCMD)"\" $(CONFFILEFLAGS) $(DIRFLAGS) $(COROSYNC) $(DLM)
VERSION = $(shell [ -d .git ] && git describe HEAD | sed 's/mdadm-//')
-VERS_DATE = $(shell [ -d .git ] && date --date="`git log -n1 --format=format:%cd --date=short`" '+%0dth %B %Y' | sed -e 's/1th/1st/' -e 's/2th/2nd/' -e 's/11st/11th/' -e 's/12nd/12th/')
+VERS_DATE = $(shell [ -d .git ] && date --iso-8601 --date="`git log -n1 --format=format:%cd --date=iso --date=short`")
DVERS = $(if $(VERSION),-DVERSION=\"$(VERSION)\",)
DDATE = $(if $(VERS_DATE),-DVERS_DATE="\"$(VERS_DATE)\"",)
CFLAGS += $(DVERS) $(DDATE)
--
2.7.4

41
SOURCES/Manage-Manage-ro-Use-md_array_active.patch

@ -0,0 +1,41 @@ @@ -0,0 +1,41 @@
From 80223cb4db3358a24c41a76414a3804c26d5ea3a Mon Sep 17 00:00:00 2001
From: Jes Sorensen <jsorensen@fb.com>
Date: Tue, 2 May 2017 10:40:07 -0400
Subject: [RHEL7.5 PATCH 102/169] Manage: Manage_ro(): Use
md_array_active()

One call less to md_get_array_info() for determining whether an array
is active or not.

Signed-off-by: Jes Sorensen <jsorensen@fb.com>
---
Manage.c | 6 ++----
1 file changed, 2 insertions(+), 4 deletions(-)

diff --git a/Manage.c b/Manage.c
index 8966e33..230309b 100644
--- a/Manage.c
+++ b/Manage.c
@@ -40,7 +40,6 @@ int Manage_ro(char *devname, int fd, int readonly)
* use RESTART_ARRAY_RW or STOP_ARRAY_RO
*
*/
- mdu_array_info_t array;
struct mdinfo *mdi;
int rv = 0;
@@ -88,9 +87,8 @@ int Manage_ro(char *devname, int fd, int readonly)
goto out;
}
- if (md_get_array_info(fd, &array)) {
- pr_err("%s does not appear to be active.\n",
- devname);
+ if (!md_array_active(fd)) {
+ pr_err("%s does not appear to be active.\n", devname);
rv = 1;
goto out;
}
--
2.7.4

69
SOURCES/Manage-Remove-all-references1-to-md_get_version.patch

@ -0,0 +1,69 @@ @@ -0,0 +1,69 @@
From 091e8e6e061a5739be68d214bbd4a25e38bec65c Mon Sep 17 00:00:00 2001
From: Jes Sorensen <Jes.Sorensen@gmail.com>
Date: Wed, 5 Apr 2017 15:34:44 -0400
Subject: [RHEL7.5 PATCH 059/169] Manage: Remove all references to
md_get_version()

At this point, support for md driver prior to 0.90.03 is going to
disappear.

Signed-off-by: Jes Sorensen <Jes.Sorensen@gmail.com>
---
Manage.c | 20 +-------------------
1 file changed, 1 insertion(+), 19 deletions(-)

diff --git a/Manage.c b/Manage.c
index 618c98b..9e69132 100644
--- a/Manage.c
+++ b/Manage.c
@@ -46,10 +46,6 @@ int Manage_ro(char *devname, int fd, int readonly)
#endif
int rv = 0;
- if (md_get_version(fd) < 9000) {
- pr_err("need md driver version 0.90.0 or later\n");
- return 1;
- }
#ifndef MDASSEMBLE
/* If this is an externally-managed array, we need to modify the
* metadata_version so that mdmon doesn't undo our change.
@@ -176,10 +172,6 @@ int Manage_run(char *devname, int fd, struct context *c)
*/
char nm[32], *nmp;
- if (md_get_version(fd) < 9000) {
- pr_err("need md driver version 0.90.0 or later\n");
- return 1;
- }
nmp = fd2devnm(fd);
if (!nmp) {
pr_err("Cannot find %s in sysfs!!\n", devname);
@@ -207,14 +199,6 @@ int Manage_stop(char *devname, int fd, int verbose, int will_retry)
if (will_retry && verbose == 0)
verbose = -1;
- if (md_get_version(fd) < 9000) {
- if (ioctl(fd, STOP_MD, 0) == 0)
- return 0;
- pr_err("stopping device %s failed: %s\n",
- devname, strerror(errno));
- return 1;
- }
-
strcpy(devnm, fd2devnm(fd));
/* Get EXCL access first. If this fails, then attempting
* to stop is probably a bad idea.
@@ -773,9 +757,7 @@ int Manage_add(int fd, int tfd, struct mddev_dev *dv,
" Adding anyway as --force was given.\n",
dv->devname, devname);
}
- if (!tst->ss->external &&
- array->major_version == 0 &&
- md_get_version(fd)%100 < 2) {
+ if (!tst->ss->external && array->major_version == 0) {
if (ioctl(fd, HOT_ADD_DISK, rdev)==0) {
if (verbose >= 0)
pr_err("hot added %s\n",
--
2.7.4

28
SOURCES/Manage-subdevs-Use-a-dev_t.patch

@ -0,0 +1,28 @@ @@ -0,0 +1,28 @@
From ffaf1a7eefc6167d7457d649e628c04ccee9a4dd Mon Sep 17 00:00:00 2001
From: Jes Sorensen <jsorensen@fb.com>
Date: Fri, 29 Sep 2017 18:08:01 -0400
Subject: [RHEL7.5 PATCH 12/13] Manage_subdevs(): Use a dev_t

Use the correct type for rdev

Signed-off-by: Jes Sorensen <jsorensen@fb.com>
---
Manage.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/Manage.c b/Manage.c
index 871d342..21536f5 100644
--- a/Manage.c
+++ b/Manage.c
@@ -1367,7 +1367,7 @@ int Manage_subdevs(char *devname, int fd,
}
for (dv = devlist; dv; dv = dv->next) {
- unsigned long rdev = 0; /* device to add/remove etc */
+ dev_t rdev = 0; /* device to add/remove etc */
int rv;
int mj,mn;
--
2.7.4

32
SOURCES/Mention-endian-in-documentation-for-update-byte-orde.patch

@ -0,0 +1,32 @@ @@ -0,0 +1,32 @@
From 4224685fe9baf1df4c42bcb950c9a593efa0585f Mon Sep 17 00:00:00 2001
From: NeilBrown <neilb@suse.com>
Date: Mon, 8 May 2017 09:40:09 +1000
Subject: [RHEL7.5 PATCH 116/169] Mention "endian" in documentation for
--update=byte-order

This makes it easier to find as "endian" is a commonly used term.

Reported-by: Trevor Cordes <trevor@tecnopolis.ca>
Signed-off-by: NeilBrown <neilb@suse.com>
Signed-off-by: Jes Sorensen <jsorensen@fb.com>
---
mdadm.8.in | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/mdadm.8.in b/mdadm.8.in
index fb99a5c..388e0ed 100644
--- a/mdadm.8.in
+++ b/mdadm.8.in
@@ -1264,7 +1264,8 @@ is correct.
The
.B byteorder
option allows arrays to be moved between machines with different
-byte-order.
+byte-order, such as from a big-endian machine like a Sparc or some
+MIPS machines, to a little-endian x86_64 machine.
When assembling such an array for the first time after a move, giving
.B "\-\-update=byteorder"
will cause
--
2.7.4

151
SOURCES/Monitor-Code-is-80-characters-per-line.patch

@ -0,0 +1,151 @@ @@ -0,0 +1,151 @@
From f27904a53b586e5507b442d7f321177e3dfb5a1a Mon Sep 17 00:00:00 2001
From: Jes Sorensen <jsorensen@fb.com>
Date: Mon, 8 May 2017 17:52:10 -0400
Subject: [RHEL7.5 PATCH 118/169] Monitor: Code is 80 characters per line

Fix up some lines that are too long for no reason, and some that have
silly line breaks.

Signed-off-by: Jes Sorensen <jsorensen@fb.com>
---
Monitor.c | 61 +++++++++++++++++++++++++++----------------------------------
1 file changed, 27 insertions(+), 34 deletions(-)

diff --git a/Monitor.c b/Monitor.c
index b5231d2..ec643d4 100644
--- a/Monitor.c
+++ b/Monitor.c
@@ -527,13 +527,10 @@ static int check_array(struct state *st, struct mdstat_ent *mdstat,
alert("NewArray", st->devname, NULL, ainfo);
}
- if (st->utime == array.utime &&
- st->failed == array.failed_disks &&
+ if (st->utime == array.utime && st->failed == array.failed_disks &&
st->working == array.working_disks &&
st->spare == array.spare_disks &&
- (mse == NULL || (
- mse->percent == st->percent
- ))) {
+ (mse == NULL || (mse->percent == st->percent))) {
close(fd);
if ((st->active < st->raid) && st->spare == 0)
return 1;
@@ -541,32 +538,33 @@ static int check_array(struct state *st, struct mdstat_ent *mdstat,
return 0;
}
if (st->utime == 0 && /* new array */
- mse->pattern && strchr(mse->pattern, '_') /* degraded */
- )
+ mse->pattern && strchr(mse->pattern, '_') /* degraded */)
alert("DegradedArray", dev, NULL, ainfo);
if (st->utime == 0 && /* new array */
- st->expected_spares > 0 &&
- array.spare_disks < st->expected_spares)
+ st->expected_spares > 0 && array.spare_disks < st->expected_spares)
alert("SparesMissing", dev, NULL, ainfo);
if (st->percent < 0 && st->percent != RESYNC_UNKNOWN &&
mse->percent >= 0)
alert("RebuildStarted", dev, NULL, ainfo);
- if (st->percent >= 0 &&
- mse->percent >= 0 &&
+ if (st->percent >= 0 && mse->percent >= 0 &&
(mse->percent / increments) > (st->percent / increments)) {
- char percentalert[15]; // "RebuildNN" (10 chars) or "RebuildStarted" (15 chars)
+ char percentalert[15];
+ /*
+ * "RebuildNN" (10 chars) or "RebuildStarted" (15 chars)
+ */
if((mse->percent / increments) == 0)
- snprintf(percentalert, sizeof(percentalert), "RebuildStarted");
+ snprintf(percentalert, sizeof(percentalert),
+ "RebuildStarted");
else
- snprintf(percentalert, sizeof(percentalert), "Rebuild%02d", mse->percent);
+ snprintf(percentalert, sizeof(percentalert),
+ "Rebuild%02d", mse->percent);
alert(percentalert, dev, NULL, ainfo);
}
- if (mse->percent == RESYNC_NONE &&
- st->percent >= 0) {
+ if (mse->percent == RESYNC_NONE && st->percent >= 0) {
/* Rebuild/sync/whatever just finished.
* If there is a number in /mismatch_cnt,
* we should report that.
@@ -587,8 +585,7 @@ static int check_array(struct state *st, struct mdstat_ent *mdstat,
st->percent = mse->percent;
remaining_disks = array.nr_disks;
- for (i=0; i<MAX_DISKS && remaining_disks > 0;
- i++) {
+ for (i = 0; i < MAX_DISKS && remaining_disks > 0; i++) {
mdu_disk_info_t disc;
disc.number = i;
if (md_get_disk_info(fd, &disc) >= 0) {
@@ -606,15 +603,13 @@ static int check_array(struct state *st, struct mdstat_ent *mdstat,
strncmp(mse->metadata_version, "external:", 9) == 0 &&
is_subarray(mse->metadata_version+9)) {
char *sl;
- strcpy(st->parent_devnm,
- mse->metadata_version+10);
+ strcpy(st->parent_devnm, mse->metadata_version+10);
sl = strchr(st->parent_devnm, '/');
if (sl)
*sl = 0;
} else
st->parent_devnm[0] = 0;
- if (st->metadata == NULL &&
- st->parent_devnm[0] == 0)
+ if (st->metadata == NULL && st->parent_devnm[0] == 0)
st->metadata = super_by_fd(fd, NULL);
close(fd);
@@ -625,12 +620,10 @@ static int check_array(struct state *st, struct mdstat_ent *mdstat,
int change;
char *dv = NULL;
disc.number = i;
- if (i < last_disk &&
- (info[i].major || info[i].minor)) {
+ if (i < last_disk && (info[i].major || info[i].minor)) {
newstate = info[i].state;
- dv = map_dev_preferred(
- info[i].major, info[i].minor, 1,
- prefer);
+ dv = map_dev_preferred(info[i].major, info[i].minor, 1,
+ prefer);
disc.state = newstate;
disc.major = info[i].major;
disc.minor = info[i].minor;
@@ -638,18 +631,18 @@ static int check_array(struct state *st, struct mdstat_ent *mdstat,
newstate = (1 << MD_DISK_REMOVED);
if (dv == NULL && st->devid[i])
- dv = map_dev_preferred(
- major(st->devid[i]),
- minor(st->devid[i]), 1, prefer);
+ dv = map_dev_preferred(major(st->devid[i]),
+ minor(st->devid[i]), 1, prefer);
change = newstate ^ st->devstate[i];
if (st->utime && change && !st->err && !new_array) {
- if ((st->devstate[i]&change)&(1<<MD_DISK_SYNC))
+ if ((st->devstate[i]&change) & (1 << MD_DISK_SYNC))
alert("Fail", dev, dv, ainfo);
- else if ((newstate & (1<<MD_DISK_FAULTY)) &&
+ else if ((newstate & (1 << MD_DISK_FAULTY)) &&
(disc.major || disc.minor) &&
- st->devid[i] == makedev(disc.major, disc.minor))
+ st->devid[i] == makedev(disc.major,
+ disc.minor))
alert("FailSpare", dev, dv, ainfo);
- else if ((newstate&change)&(1<<MD_DISK_SYNC))
+ else if ((newstate&change) & (1 << MD_DISK_SYNC))
alert("SpareActive", dev, dv, ainfo);
}
st->devstate[i] = newstate;
--
2.7.4

329
SOURCES/Monitor-Fixup-apile-of-whitespace-issues.patch

@ -0,0 +1,329 @@ @@ -0,0 +1,329 @@
From f566ef45d356f6dcd4ec54d294be8664770d8b84 Mon Sep 17 00:00:00 2001
From: Jes Sorensen <jsorensen@fb.com>
Date: Thu, 11 May 2017 16:56:55 -0400
Subject: [RHEL7.5 PATCH 139/169] Monitor: Fixup a pile of whitespace
issues

No code was hurt in this event

Signed-off-by: Jes Sorensen <jsorensen@fb.com>
---
Monitor.c | 110 +++++++++++++++++++++++++++++++-------------------------------
1 file changed, 55 insertions(+), 55 deletions(-)

diff --git a/Monitor.c b/Monitor.c
index 83a6d10..0198a34 100644
--- a/Monitor.c
+++ b/Monitor.c
@@ -139,7 +139,7 @@ int Monitor(struct mddev_dev *devlist,
if (!alert_cmd) {
alert_cmd = conf_get_program();
- if (alert_cmd && ! c->scan)
+ if (alert_cmd && !c->scan)
pr_err("Monitor using program \"%s\" from config file\n",
alert_cmd);
}
@@ -164,8 +164,9 @@ int Monitor(struct mddev_dev *devlist,
if (devlist == NULL) {
mdlist = conf_get_ident(NULL);
- for (; mdlist; mdlist=mdlist->next) {
+ for (; mdlist; mdlist = mdlist->next) {
struct state *st;
+
if (mdlist->devname == NULL)
continue;
if (strcasecmp(mdlist->devname, "<ignore>") == 0)
@@ -189,7 +190,8 @@ int Monitor(struct mddev_dev *devlist,
}
} else {
struct mddev_dev *dv;
- for (dv=devlist ; dv; dv=dv->next) {
+
+ for (dv = devlist; dv; dv = dv->next) {
struct state *st = xcalloc(1, sizeof *st);
mdlist = conf_get_ident(dv->devname);
st->devname = xstrdup(dv->devname);
@@ -206,18 +208,18 @@ int Monitor(struct mddev_dev *devlist,
}
}
- while (! finished) {
+ while (!finished) {
int new_found = 0;
struct state *st, **stp;
int anydegraded = 0;
if (mdstat)
free_mdstat(mdstat);
- mdstat = mdstat_read(oneshot?0:1, 0);
+ mdstat = mdstat_read(oneshot ? 0 : 1, 0);
if (!mdstat)
mdstat_close();
- for (st=statelist; st; st=st->next)
+ for (st = statelist; st; st = st->next)
if (check_array(st, mdstat, c->test, &info,
increments, c->prefer))
anydegraded = 1;
@@ -291,8 +293,8 @@ static int make_daemon(char *pidfile)
}
close(0);
open("/dev/null", O_RDWR);
- dup2(0,1);
- dup2(0,2);
+ dup2(0, 1);
+ dup2(0, 2);
setsid();
return -1;
}
@@ -323,8 +325,7 @@ static int check_one_sharer(int scan)
fclose(fp);
}
if (scan) {
- if (mkdir(MDMON_DIR, S_IRWXU) < 0 &&
- errno != EEXIST) {
+ if (mkdir(MDMON_DIR, S_IRWXU) < 0 && errno != EEXIST) {
pr_err("Can't create autorebuild.pid file\n");
} else {
fp = fopen(path, "w");
@@ -347,7 +348,8 @@ static void alert(char *event, char *dev, char *disc, struct alert_info *info)
if (!info->alert_cmd && !info->mailaddr && !info->dosyslog) {
time_t now = time(0);
- printf("%1.15s: %s on %s %s\n", ctime(&now)+4, event, dev, disc?disc:"unknown device");
+ printf("%1.15s: %s on %s %s\n", ctime(&now) + 4,
+ event, dev, disc?disc:"unknown device");
}
if (info->alert_cmd) {
int pid = fork();
@@ -363,11 +365,10 @@ static void alert(char *event, char *dev, char *disc, struct alert_info *info)
exit(2);
}
}
- if (info->mailaddr &&
- (strncmp(event, "Fail", 4)==0 ||
- strncmp(event, "Test", 4)==0 ||
- strncmp(event, "Spares", 6)==0 ||
- strncmp(event, "Degrade", 7)==0)) {
+ if (info->mailaddr && (strncmp(event, "Fail", 4) == 0 ||
+ strncmp(event, "Test", 4) == 0 ||
+ strncmp(event, "Spares", 6) == 0 ||
+ strncmp(event, "Degrade", 7) == 0)) {
FILE *mp = popen(Sendmail, "w");
if (mp) {
FILE *mdstat;
@@ -377,7 +378,8 @@ static void alert(char *event, char *dev, char *disc, struct alert_info *info)
if (info->mailfrom)
fprintf(mp, "From: %s\n", info->mailfrom);
else
- fprintf(mp, "From: %s monitoring <root>\n", Name);
+ fprintf(mp, "From: %s monitoring <root>\n",
+ Name);
fprintf(mp, "To: %s\n", info->mailaddr);
fprintf(mp, "Subject: %s event on %s:%s\n\n",
event, dev, hname);
@@ -403,8 +405,9 @@ static void alert(char *event, char *dev, char *disc, struct alert_info *info)
int n;
fprintf(mp,
"\nP.S. The /proc/mdstat file currently contains the following:\n\n");
- while ( (n=fread(buf, 1, sizeof(buf), mdstat)) > 0)
- n=fwrite(buf, 1, n, mp);
+ while ((n = fread(buf, 1, sizeof(buf),
+ mdstat)) > 0)
+ n = fwrite(buf, 1, n, mp);
fclose(mdstat);
}
pclose(mp);
@@ -416,13 +419,13 @@ static void alert(char *event, char *dev, char *disc, struct alert_info *info)
/* Log at a different severity depending on the event.
*
* These are the critical events: */
- if (strncmp(event, "Fail", 4)==0 ||
- strncmp(event, "Degrade", 7)==0 ||
- strncmp(event, "DeviceDisappeared", 17)==0)
+ if (strncmp(event, "Fail", 4) == 0 ||
+ strncmp(event, "Degrade", 7) == 0 ||
+ strncmp(event, "DeviceDisappeared", 17) == 0)
priority = LOG_CRIT;
/* Good to know about, but are not failures: */
- else if (strncmp(event, "Rebuild", 7)==0 ||
- strncmp(event, "MoveSpare", 9)==0 ||
+ else if (strncmp(event, "Rebuild", 7) == 0 ||
+ strncmp(event, "MoveSpare", 9) == 0 ||
strncmp(event, "Spares", 6) != 0)
priority = LOG_WARNING;
/* Everything else: */
@@ -497,7 +500,7 @@ static int check_array(struct state *st, struct mdstat_ent *mdstat,
goto out;
}
- for (mse2 = mdstat ; mse2 ; mse2=mse2->next)
+ for (mse2 = mdstat; mse2; mse2 = mse2->next)
if (strcmp(mse2->devnm, st->devnm) == 0) {
mse2->devnm[0] = 0; /* flag it as "used" */
mse = mse2;
@@ -568,7 +571,7 @@ static int check_array(struct state *st, struct mdstat_ent *mdstat,
char cnt[80];
snprintf(cnt, sizeof(cnt),
" mismatches found: %d (on raid level %d)",
- sra->mismatch_cnt, sra->array.level);
+ sra->mismatch_cnt, sra->array.level);
alert("RebuildFinished", dev, cnt, ainfo);
} else
alert("RebuildFinished", dev, NULL, ainfo);
@@ -594,7 +597,7 @@ static int check_array(struct state *st, struct mdstat_ent *mdstat,
strncmp(mse->metadata_version, "external:", 9) == 0 &&
is_subarray(mse->metadata_version+9)) {
char *sl;
- strcpy(st->parent_devnm, mse->metadata_version+10);
+ strcpy(st->parent_devnm, mse->metadata_version + 10);
sl = strchr(st->parent_devnm, '/');
if (sl)
*sl = 0;
@@ -603,9 +606,9 @@ static int check_array(struct state *st, struct mdstat_ent *mdstat,
if (st->metadata == NULL && st->parent_devnm[0] == 0)
st->metadata = super_by_fd(fd, NULL);
- for (i=0; i<MAX_DISKS; i++) {
- mdu_disk_info_t disc = {0,0,0,0,0};
- int newstate=0;
+ for (i = 0; i < MAX_DISKS; i++) {
+ mdu_disk_info_t disc = {0, 0, 0, 0, 0};
+ int newstate = 0;
int change;
char *dv = NULL;
disc.number = i;
@@ -668,12 +671,10 @@ static int add_new_arrays(struct mdstat_ent *mdstat, struct state **statelist,
int new_found = 0;
char *name;
- for (mse=mdstat; mse; mse=mse->next)
- if (mse->devnm[0] &&
- (!mse->level || /* retrieve containers */
- (strcmp(mse->level, "raid0") != 0 &&
- strcmp(mse->level, "linear") != 0))
- ) {
+ for (mse = mdstat; mse; mse = mse->next)
+ if (mse->devnm[0] && (!mse->level || /* retrieve containers */
+ (strcmp(mse->level, "raid0") != 0 &&
+ strcmp(mse->level, "linear") != 0))) {
struct state *st = xcalloc(1, sizeof *st);
mdu_array_info_t array;
int fd;
@@ -707,7 +708,8 @@ static int add_new_arrays(struct mdstat_ent *mdstat, struct state **statelist,
st->percent = RESYNC_UNKNOWN;
st->expected_spares = -1;
if (mse->metadata_version &&
- strncmp(mse->metadata_version, "external:", 9) == 0 &&
+ strncmp(mse->metadata_version,
+ "external:", 9) == 0 &&
is_subarray(mse->metadata_version+9)) {
char *sl;
strcpy(st->parent_devnm,
@@ -729,8 +731,7 @@ static int get_required_spare_criteria(struct state *st,
{
int fd;
- if (!st->metadata ||
- !st->metadata->ss->get_spare_criteria) {
+ if (!st->metadata || !st->metadata->ss->get_spare_criteria) {
sc->min_size = 0;
sc->sector_size = 0;
return 0;
@@ -779,14 +780,13 @@ static int check_donor(struct state *from, struct state *to)
}
static dev_t choose_spare(struct state *from, struct state *to,
- struct domainlist *domlist, struct spare_criteria *sc)
+ struct domainlist *domlist, struct spare_criteria *sc)
{
int d;
dev_t dev = 0;
for (d = from->raid; !dev && d < MAX_DISKS; d++) {
- if (from->devid[d] > 0 &&
- from->devstate[d] == 0) {
+ if (from->devid[d] > 0 && from->devstate[d] == 0) {
struct dev_policy *pol;
unsigned long long dev_size;
unsigned int dev_sector_size;
@@ -810,7 +810,8 @@ static dev_t choose_spare(struct state *from, struct state *to,
if (from->spare_group)
pol_add(&pol, pol_domain,
from->spare_group, NULL);
- if (domain_test(domlist, pol, to->metadata->ss->name) == 1)
+ if (domain_test(domlist, pol,
+ to->metadata->ss->name) == 1)
dev = from->devid[d];
dev_policy_free(pol);
}
@@ -857,8 +858,8 @@ static dev_t container_choose_spare(struct state *from, struct state *to,
}
dp = list->devs;
while (dp) {
- if (dp->disk.state & (1<<MD_DISK_SYNC) &&
- !(dp->disk.state & (1<<MD_DISK_FAULTY)))
+ if (dp->disk.state & (1 << MD_DISK_SYNC) &&
+ !(dp->disk.state & (1 << MD_DISK_FAULTY)))
active_cnt++;
dp = dp->next;
}
@@ -891,8 +892,7 @@ static void try_spare_migration(struct state *statelist, struct alert_info *info
link_containers_with_subarrays(statelist);
for (st = statelist; st; st = st->next)
- if (st->active < st->raid &&
- st->spare == 0 && !st->err) {
+ if (st->active < st->raid && st->spare == 0 && !st->err) {
struct domainlist *domlist = NULL;
int d;
struct state *to = st;
@@ -940,9 +940,11 @@ static void try_spare_migration(struct state *statelist, struct alert_info *info
else
devid = choose_spare(from, to, domlist,
&sc);
- if (devid > 0
- && move_spare(from->devname, to->devname, devid)) {
- alert("MoveSpare", to->devname, from->devname, info);
+ if (devid > 0 &&
+ move_spare(from->devname, to->devname,
+ devid)) {
+ alert("MoveSpare", to->devname,
+ from->devname, info);
break;
}
}
@@ -967,8 +969,7 @@ static void link_containers_with_subarrays(struct state *list)
for (st = list; st; st = st->next)
if (st->parent_devnm[0])
for (cont = list; cont; cont = cont->next)
- if (!cont->err &&
- cont->parent_devnm[0] == 0 &&
+ if (!cont->err && cont->parent_devnm[0] == 0 &&
strcmp(cont->devnm, st->parent_devnm) == 0) {
st->parent = cont;
st->subarray = cont->subarray;
@@ -992,7 +993,7 @@ int Wait(char *dev)
struct mdstat_ent *ms = mdstat_read(1, 0);
struct mdstat_ent *e;
- for (e=ms ; e; e=e->next)
+ for (e = ms; e; e = e->next)
if (strcmp(e->devnm, devnm) == 0)
break;
@@ -1115,8 +1116,7 @@ int WaitClean(char *dev, int sock, int verbose)
} else
rv = 1;
if (rv && verbose)
- pr_err("Error waiting for %s to be clean\n",
- dev);
+ pr_err("Error waiting for %s to be clean\n", dev);
/* restore the original safe_mode_delay */
sysfs_set_safemode(mdi, mdi->safe_mode_delay);
--
2.7.4

36
SOURCES/Monitor-Include-containers-in-spare-migration2.patch

@ -0,0 +1,36 @@ @@ -0,0 +1,36 @@
From 2dab69c9e3acace828bbb6a00514fa820f8ca64f Mon Sep 17 00:00:00 2001
From: Mariusz Tkaczyk <mariusz.tkaczyk@intel.com>
Date: Wed, 16 Aug 2017 14:59:46 +0200
Subject: [RHEL7.5 PATCH 169/169] Monitor: Include containers in spare
migration

Spare migration doesn't work for external metadata. mdadm skips
a container with spare device because it is inactive. It used to work
because GET_ARRAY_INFO ioctl returned valid structure for a container
and mdadm treated such response as active container. Current
implementation checks it in sysfs where container is shown as inactive.

Adapt sysfs implementation to work the same way as ioctl.

Signed-off-by: Mariusz Tkaczyk <mariusz.tkaczyk@intel.com>
Signed-off-by: Jes Sorensen <jsorensen@fb.com>
---
Monitor.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/Monitor.c b/Monitor.c
index f70e5b5..497e364 100644
--- a/Monitor.c
+++ b/Monitor.c
@@ -497,7 +497,7 @@ static int check_array(struct state *st, struct mdstat_ent *mdstat,
if (mse->level == NULL)
is_container = 1;
- if (!md_array_active(fd))
+ if (!is_container && !md_array_active(fd))
goto disappeared;
fcntl(fd, F_SETFD, FD_CLOEXEC);
--
2.7.4

45
SOURCES/Monitor-Not-much-point-declaring-mdlist-in-both-fork.patch

@ -0,0 +1,45 @@ @@ -0,0 +1,45 @@
From 9f3dd4549b2b904d343b79a8a7ba40c547e71d5d Mon Sep 17 00:00:00 2001
From: Jes Sorensen <jsorensen@fb.com>
Date: Thu, 11 May 2017 16:40:16 -0400
Subject: [RHEL7.5 PATCH 137/169] Monitor: Not much point declaring mdlist
in both forks of the if() statement

Signed-off-by: Jes Sorensen <jsorensen@fb.com>
---
Monitor.c | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/Monitor.c b/Monitor.c
index 5b95847..a4afe75 100644
--- a/Monitor.c
+++ b/Monitor.c
@@ -127,6 +127,7 @@ int Monitor(struct mddev_dev *devlist,
struct mdstat_ent *mdstat = NULL;
char *mailfrom = NULL;
struct alert_info info;
+ struct mddev_ident *mdlist;
if (!mailaddr) {
mailaddr = conf_get_mailaddr();
@@ -162,7 +163,7 @@ int Monitor(struct mddev_dev *devlist,
return 1;
if (devlist == NULL) {
- struct mddev_ident *mdlist = conf_get_ident(NULL);
+ mdlist = conf_get_ident(NULL);
for (; mdlist; mdlist=mdlist->next) {
struct state *st;
if (mdlist->devname == NULL)
@@ -189,8 +190,8 @@ int Monitor(struct mddev_dev *devlist,
} else {
struct mddev_dev *dv;
for (dv=devlist ; dv; dv=dv->next) {
- struct mddev_ident *mdlist = conf_get_ident(dv->devname);
struct state *st = xcalloc(1, sizeof *st);
+ mdlist = conf_get_ident(dv->devname);
st->devname = xstrdup(dv->devname);
st->next = statelist;
st->devnm[0] = 0;
--
2.7.4

81
SOURCES/Monitor-Use-md_array_active-instead-of-manually-fidd.patch

@ -0,0 +1,81 @@ @@ -0,0 +1,81 @@
From b9a0309c7fc3e6c1607d51ab3c3f8486478a65ef Mon Sep 17 00:00:00 2001
From: Jes Sorensen <jsorensen@fb.com>
Date: Mon, 8 May 2017 17:34:08 -0400
Subject: [RHEL7.5 PATCH 117/169] Monitor: Use md_array_active() instead of
manually fiddling in sysfs

This removes a pile of clutter that can easily behandled with a simple
check of array_state.

Signed-off-by: Jes Sorensen <jsorensen@fb.com>
---
Monitor.c | 39 +++++++++++----------------------------
1 file changed, 11 insertions(+), 28 deletions(-)

diff --git a/Monitor.c b/Monitor.c
index e2b36ff..b5231d2 100644
--- a/Monitor.c
+++ b/Monitor.c
@@ -454,7 +454,7 @@ static int check_array(struct state *st, struct mdstat_ent *mdstat,
mdu_array_info_t array;
struct mdstat_ent *mse = NULL, *mse2;
char *dev = st->devname;
- int fd = -1;
+ int fd;
int i;
int remaining_disks;
int last_disk;
@@ -462,33 +462,7 @@ static int check_array(struct state *st, struct mdstat_ent *mdstat,
if (test)
alert("TestMessage", dev, NULL, ainfo);
- if (st->devnm[0])
- fd = open("/sys/block", O_RDONLY|O_DIRECTORY);
- if (fd >= 0) {
- /* Don't open the device unless it is present and
- * active in sysfs.
- */
- char buf[10];
- close(fd);
- fd = sysfs_open(st->devnm, NULL, "array_state");
- if (fd < 0 ||
- read(fd, buf, 10) < 5 ||
- strncmp(buf,"clear",5) == 0 ||
- strncmp(buf,"inact",5) == 0) {
- if (fd >= 0)
- close(fd);
- fd = sysfs_open(st->devnm, NULL, "level");
- if (fd < 0 || read(fd, buf, 10) != 0) {
- if (fd >= 0)
- close(fd);
- if (!st->err)
- alert("DeviceDisappeared", dev, NULL, ainfo);
- st->err++;
- return 0;
- }
- }
- close(fd);
- }
+
fd = open(dev, O_RDONLY);
if (fd < 0) {
if (!st->err)
@@ -496,6 +470,15 @@ static int check_array(struct state *st, struct mdstat_ent *mdstat,
st->err++;
return 0;
}
+
+ if (!md_array_active(fd)) {
+ close(fd);
+ if (!st->err)
+ alert("DeviceDisappeared", dev, NULL, ainfo);
+ st->err++;
+ return 0;
+ }
+
fcntl(fd, F_SETFD, FD_CLOEXEC);
if (md_get_array_info(fd, &array) < 0) {
if (!st->err)
--
2.7.4

102
SOURCES/Monitor-check_array-Centralize-exit-path.patch

@ -0,0 +1,102 @@ @@ -0,0 +1,102 @@
From 1830e74b4cbde28279f341bc80b68e9d82df32c6 Mon Sep 17 00:00:00 2001
From: Jes Sorensen <jsorensen@fb.com>
Date: Tue, 9 May 2017 16:25:23 -0400
Subject: [RHEL7.5 PATCH 125/169] Monitor/check_array: Centralize exit path

Improve exit handling to make it easier to share error handling and free
sysfs entries later.

Signed-off-by: Jes Sorensen <jsorensen@fb.com>
---
Monitor.c | 24 ++++++++++++++----------
1 file changed, 14 insertions(+), 10 deletions(-)

diff --git a/Monitor.c b/Monitor.c
index c96f8e8..f404009 100644
--- a/Monitor.c
+++ b/Monitor.c
@@ -459,16 +459,19 @@ static int check_array(struct state *st, struct mdstat_ent *mdstat,
int remaining_disks;
int last_disk;
int new_array = 0;
+ int retval;
if (test)
alert("TestMessage", dev, NULL, ainfo);
+ retval = 0;
+
fd = open(dev, O_RDONLY);
if (fd < 0) {
if (!st->err)
alert("DeviceDisappeared", dev, NULL, ainfo);
st->err++;
- return 0;
+ goto out;
}
if (!md_array_active(fd)) {
@@ -476,7 +479,7 @@ static int check_array(struct state *st, struct mdstat_ent *mdstat,
if (!st->err)
alert("DeviceDisappeared", dev, NULL, ainfo);
st->err++;
- return 0;
+ goto out;
}
fcntl(fd, F_SETFD, FD_CLOEXEC);
@@ -485,7 +488,7 @@ static int check_array(struct state *st, struct mdstat_ent *mdstat,
alert("DeviceDisappeared", dev, NULL, ainfo);
st->err++;
close(fd);
- return 0;
+ goto out;
}
/* It's much easier to list what array levels can't
* have a device disappear than all of them that can
@@ -495,7 +498,7 @@ static int check_array(struct state *st, struct mdstat_ent *mdstat,
alert("DeviceDisappeared", dev, " Wrong-Level", ainfo);
st->err++;
close(fd);
- return 0;
+ goto out;
}
if (st->devnm[0] == 0)
strcpy(st->devnm, fd2devnm(fd));
@@ -511,7 +514,7 @@ static int check_array(struct state *st, struct mdstat_ent *mdstat,
* or re-created after reading mdstat*/
st->err++;
close(fd);
- return 0;
+ goto out;
}
/* this array is in /proc/mdstat */
if (array.utime == 0)
@@ -533,9 +536,8 @@ static int check_array(struct state *st, struct mdstat_ent *mdstat,
(mse == NULL || (mse->percent == st->percent))) {
close(fd);
if ((st->active < st->raid) && st->spare == 0)
- return 1;
- else
- return 0;
+ retval = 1;
+ goto out;
}
if (st->utime == 0 && /* new array */
mse->pattern && strchr(mse->pattern, '_') /* degraded */)
@@ -656,8 +658,10 @@ static int check_array(struct state *st, struct mdstat_ent *mdstat,
st->raid = array.raid_disks;
st->err = 0;
if ((st->active < st->raid) && st->spare == 0)
- return 1;
- return 0;
+ retval = 1;
+
+ out:
+ return retval;
}
static int add_new_arrays(struct mdstat_ent *mdstat, struct state **statelist,
--
2.7.4

36
SOURCES/Monitor-check_array-Get-arraydisks-from-sysfs.patch

@ -0,0 +1,36 @@ @@ -0,0 +1,36 @@
From 12a9d21f4e9fd4d3a14129407f1e8da6d6444cd6 Mon Sep 17 00:00:00 2001
From: Jes Sorensen <jsorensen@fb.com>
Date: Tue, 9 May 2017 16:58:55 -0400
Subject: [RHEL7.5 PATCH 131/169] Monitor/check_array: Get array_disks from
sysfs

Signed-off-by: Jes Sorensen <jsorensen@fb.com>
---
Monitor.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/Monitor.c b/Monitor.c
index 9456efd..fe6f2b4 100644
--- a/Monitor.c
+++ b/Monitor.c
@@ -481,7 +481,7 @@ static int check_array(struct state *st, struct mdstat_ent *mdstat,
if (st->devnm[0] == 0)
strcpy(st->devnm, fd2devnm(fd));
- sra = sysfs_read(-1, st->devnm, GET_LEVEL | GET_DEGRADED |
+ sra = sysfs_read(-1, st->devnm, GET_LEVEL | GET_DISKS | GET_DEGRADED |
GET_MISMATCH);
if (!sra)
goto disappeared;
@@ -641,7 +641,7 @@ static int check_array(struct state *st, struct mdstat_ent *mdstat,
st->spare = array.spare_disks;
st->failed = sra->array.failed_disks;
st->utime = array.utime;
- st->raid = array.raid_disks;
+ st->raid = sra->array.raid_disks;
st->err = 0;
if ((st->active < st->raid) && st->spare == 0)
retval = 1;
--
2.7.4

46
SOURCES/Monitor-check_array-Get-faileddisks-from-sysfs.patch

@ -0,0 +1,46 @@ @@ -0,0 +1,46 @@
From b8e5713c74901862b96bf599ab6fd227addc1498 Mon Sep 17 00:00:00 2001
From: Jes Sorensen <jsorensen@fb.com>
Date: Tue, 9 May 2017 16:54:19 -0400
Subject: [RHEL7.5 PATCH 130/169] Monitor/check_array: Get 'failed_disks'
from sysfs

Signed-off-by: Jes Sorensen <jsorensen@fb.com>
---
Monitor.c | 7 ++++---
1 file changed, 4 insertions(+), 3 deletions(-)

diff --git a/Monitor.c b/Monitor.c
index b94fd7c..9456efd 100644
--- a/Monitor.c
+++ b/Monitor.c
@@ -481,7 +481,8 @@ static int check_array(struct state *st, struct mdstat_ent *mdstat,
if (st->devnm[0] == 0)
strcpy(st->devnm, fd2devnm(fd));
- sra = sysfs_read(-1, st->devnm, GET_LEVEL | GET_MISMATCH);
+ sra = sysfs_read(-1, st->devnm, GET_LEVEL | GET_DEGRADED |
+ GET_MISMATCH);
if (!sra)
goto disappeared;
@@ -522,7 +523,7 @@ static int check_array(struct state *st, struct mdstat_ent *mdstat,
alert("NewArray", st->devname, NULL, ainfo);
}
- if (st->utime == array.utime && st->failed == array.failed_disks &&
+ if (st->utime == array.utime && st->failed == sra->array.failed_disks &&
st->working == array.working_disks &&
st->spare == array.spare_disks &&
(mse == NULL || (mse->percent == st->percent))) {
@@ -638,7 +639,7 @@ static int check_array(struct state *st, struct mdstat_ent *mdstat,
st->active = array.active_disks;
st->working = array.working_disks;
st->spare = array.spare_disks;
- st->failed = array.failed_disks;
+ st->failed = sra->array.failed_disks;
st->utime = array.utime;
st->raid = array.raid_disks;
st->err = 0;
--
2.7.4

71
SOURCES/Monitor-check_array-Get-nrdisks-active_disks-and-sp.patch

@ -0,0 +1,71 @@ @@ -0,0 +1,71 @@
From b98943a4f889b466a3d07264068042b18c620d33 Mon Sep 17 00:00:00 2001
From: Jes Sorensen <jsorensen@fb.com>
Date: Tue, 9 May 2017 17:03:03 -0400
Subject: [RHEL7.5 PATCH 132/169] Monitor/check_array: Get nr_disks,
active_disks and spare_disks from sysfs

This leaves working_disks and utime missing before we can eliminate
check_array()'s call to md_get_array_info()

Signed-off-by: Jes Sorensen <jsorensen@fb.com>
---
Monitor.c | 14 +++++++-------
1 file changed, 7 insertions(+), 7 deletions(-)

diff --git a/Monitor.c b/Monitor.c
index fe6f2b4..2204528 100644
--- a/Monitor.c
+++ b/Monitor.c
@@ -482,7 +482,7 @@ static int check_array(struct state *st, struct mdstat_ent *mdstat,
strcpy(st->devnm, fd2devnm(fd));
sra = sysfs_read(-1, st->devnm, GET_LEVEL | GET_DISKS | GET_DEGRADED |
- GET_MISMATCH);
+ GET_MISMATCH | GET_DEVS | GET_STATE);
if (!sra)
goto disappeared;
@@ -525,7 +525,7 @@ static int check_array(struct state *st, struct mdstat_ent *mdstat,
if (st->utime == array.utime && st->failed == sra->array.failed_disks &&
st->working == array.working_disks &&
- st->spare == array.spare_disks &&
+ st->spare == sra->array.spare_disks &&
(mse == NULL || (mse->percent == st->percent))) {
if ((st->active < st->raid) && st->spare == 0)
retval = 1;
@@ -535,8 +535,8 @@ static int check_array(struct state *st, struct mdstat_ent *mdstat,
mse->pattern && strchr(mse->pattern, '_') /* degraded */)
alert("DegradedArray", dev, NULL, ainfo);
- if (st->utime == 0 && /* new array */
- st->expected_spares > 0 && array.spare_disks < st->expected_spares)
+ if (st->utime == 0 && /* new array */ st->expected_spares > 0 &&
+ sra->array.spare_disks < st->expected_spares)
alert("SparesMissing", dev, NULL, ainfo);
if (st->percent < 0 && st->percent != RESYNC_UNKNOWN &&
mse->percent >= 0)
@@ -574,7 +574,7 @@ static int check_array(struct state *st, struct mdstat_ent *mdstat,
}
st->percent = mse->percent;
- remaining_disks = array.nr_disks;
+ remaining_disks = sra->array.nr_disks;
for (i = 0; i < MAX_DISKS && remaining_disks > 0; i++) {
mdu_disk_info_t disc;
disc.number = i;
@@ -636,9 +636,9 @@ static int check_array(struct state *st, struct mdstat_ent *mdstat,
st->devstate[i] = newstate;
st->devid[i] = makedev(disc.major, disc.minor);
}
- st->active = array.active_disks;
+ st->active = sra->array.active_disks;
st->working = array.working_disks;
- st->spare = array.spare_disks;
+ st->spare = sra->array.spare_disks;
st->failed = sra->array.failed_disks;
st->utime = array.utime;
st->raid = sra->array.raid_disks;
--
2.7.4

44
SOURCES/Monitor-check_array-Obtain-RAID-level-fromsyfs.patch

@ -0,0 +1,44 @@ @@ -0,0 +1,44 @@
From 48bc2ade86db576036375184774a3ebadf6a22e3 Mon Sep 17 00:00:00 2001
From: Jes Sorensen <jsorensen@fb.com>
Date: Tue, 9 May 2017 16:52:44 -0400
Subject: [RHEL7.5 PATCH 129/169] Monitor/check_array: Obtain RAID level
from syfs

Signed-off-by: Jes Sorensen <jsorensen@fb.com>
---
Monitor.c | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/Monitor.c b/Monitor.c
index 75aea91..b94fd7c 100644
--- a/Monitor.c
+++ b/Monitor.c
@@ -481,14 +481,14 @@ static int check_array(struct state *st, struct mdstat_ent *mdstat,
if (st->devnm[0] == 0)
strcpy(st->devnm, fd2devnm(fd));
- sra = sysfs_read(-1, st->devnm, GET_MISMATCH);
+ sra = sysfs_read(-1, st->devnm, GET_LEVEL | GET_MISMATCH);
if (!sra)
goto disappeared;
/* It's much easier to list what array levels can't
* have a device disappear than all of them that can
*/
- if (array.level == 0 || array.level == -1) {
+ if (sra->array.level == 0 || sra->array.level == -1) {
if (!st->err && !st->from_config)
alert("DeviceDisappeared", dev, " Wrong-Level", ainfo);
st->err++;
@@ -566,7 +566,7 @@ static int check_array(struct state *st, struct mdstat_ent *mdstat,
char cnt[80];
snprintf(cnt, sizeof(cnt),
" mismatches found: %d (on raid level %d)",
- sra->mismatch_cnt, array.level);
+ sra->mismatch_cnt, sra->array.level);
alert("RebuildFinished", dev, cnt, ainfo);
} else
alert("RebuildFinished", dev, NULL, ainfo);
--
2.7.4

79
SOURCES/Monitor-check_array-Read-sysfs-entry-earlier.patch

@ -0,0 +1,79 @@ @@ -0,0 +1,79 @@
From aed5f5c34c2b248876b874898d0b3bf65b6cca53 Mon Sep 17 00:00:00 2001
From: Jes Sorensen <jsorensen@fb.com>
Date: Tue, 9 May 2017 16:49:33 -0400
Subject: [RHEL7.5 PATCH 128/169] Monitor/check_array: Read sysfs entry
earlier

This will allow us to pull additional info from sysfs, such as level
and device info.

Signed-off-by: Jes Sorensen <jsorensen@fb.com>
---
Monitor.c | 16 ++++++++++------
1 file changed, 10 insertions(+), 6 deletions(-)

diff --git a/Monitor.c b/Monitor.c
index bb3a2c4..75aea91 100644
--- a/Monitor.c
+++ b/Monitor.c
@@ -451,7 +451,7 @@ static int check_array(struct state *st, struct mdstat_ent *mdstat,
* '1' if the array is degraded, or '0' if it is optimal (or dead).
*/
struct { int state, major, minor; } info[MAX_DISKS];
- struct mdinfo *sra;
+ struct mdinfo *sra = NULL;
mdu_array_info_t array;
struct mdstat_ent *mse = NULL, *mse2;
char *dev = st->devname;
@@ -478,6 +478,13 @@ static int check_array(struct state *st, struct mdstat_ent *mdstat,
if (md_get_array_info(fd, &array) < 0)
goto disappeared;
+ if (st->devnm[0] == 0)
+ strcpy(st->devnm, fd2devnm(fd));
+
+ sra = sysfs_read(-1, st->devnm, GET_MISMATCH);
+ if (!sra)
+ goto disappeared;
+
/* It's much easier to list what array levels can't
* have a device disappear than all of them that can
*/
@@ -487,8 +494,6 @@ static int check_array(struct state *st, struct mdstat_ent *mdstat,
st->err++;
goto out;
}
- if (st->devnm[0] == 0)
- strcpy(st->devnm, fd2devnm(fd));
for (mse2 = mdstat ; mse2 ; mse2=mse2->next)
if (strcmp(mse2->devnm, st->devnm) == 0) {
@@ -557,7 +562,6 @@ static int check_array(struct state *st, struct mdstat_ent *mdstat,
* If there is a number in /mismatch_cnt,
* we should report that.
*/
- sra = sysfs_read(-1, st->devnm, GET_MISMATCH);
if (sra && sra->mismatch_cnt > 0) {
char cnt[80];
snprintf(cnt, sizeof(cnt),
@@ -566,8 +570,6 @@ static int check_array(struct state *st, struct mdstat_ent *mdstat,
alert("RebuildFinished", dev, cnt, ainfo);
} else
alert("RebuildFinished", dev, NULL, ainfo);
- if (sra)
- sysfs_free(sra);
}
st->percent = mse->percent;
@@ -644,6 +646,8 @@ static int check_array(struct state *st, struct mdstat_ent *mdstat,
retval = 1;
out:
+ if (sra)
+ sysfs_free(sra);
if (fd > 0)
close(fd);
return retval;
--
2.7.4

38
SOURCES/Monitor-check_array-declate-mdinfo-instance-globally.patch

@ -0,0 +1,38 @@ @@ -0,0 +1,38 @@
From 826522f0dc86d31cc7207b01957b5c4243f49dc8 Mon Sep 17 00:00:00 2001
From: Jes Sorensen <jsorensen@fb.com>
Date: Tue, 9 May 2017 16:41:06 -0400
Subject: [RHEL7.5 PATCH 127/169] Monitor/check_array: Declate mdinfo
instance globally

We can pull in more information from sysfs earlier, so move sra to the top.

Signed-off-by: Jes Sorensen <jsorensen@fb.com>
---
Monitor.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/Monitor.c b/Monitor.c
index c519877..bb3a2c4 100644
--- a/Monitor.c
+++ b/Monitor.c
@@ -451,6 +451,7 @@ static int check_array(struct state *st, struct mdstat_ent *mdstat,
* '1' if the array is degraded, or '0' if it is optimal (or dead).
*/
struct { int state, major, minor; } info[MAX_DISKS];
+ struct mdinfo *sra;
mdu_array_info_t array;
struct mdstat_ent *mse = NULL, *mse2;
char *dev = st->devname;
@@ -556,8 +557,7 @@ static int check_array(struct state *st, struct mdstat_ent *mdstat,
* If there is a number in /mismatch_cnt,
* we should report that.
*/
- struct mdinfo *sra =
- sysfs_read(-1, st->devnm, GET_MISMATCH);
+ sra = sysfs_read(-1, st->devnm, GET_MISMATCH);
if (sra && sra->mismatch_cnt > 0) {
char cnt[80];
snprintf(cnt, sizeof(cnt),
--
2.7.4

99
SOURCES/Monitor-check_array-reduce-duplicated-error-handling.patch

@ -0,0 +1,99 @@ @@ -0,0 +1,99 @@
From 13e5d8455c22d4db420ead9fde3ee0c1536b73a3 Mon Sep 17 00:00:00 2001
From: Jes Sorensen <jsorensen@fb.com>
Date: Tue, 9 May 2017 16:38:06 -0400
Subject: [RHEL7.5 PATCH 126/169] Monitor/check_array: Reduce duplicated
error handling

Avoid closing fd in multiple places, and duplicating the error message
for when a device disappeared.

Signed-off-by: Jes Sorensen <jsorensen@fb.com>
---
Monitor.c | 39 +++++++++++++++------------------------
1 file changed, 15 insertions(+), 24 deletions(-)

diff --git a/Monitor.c b/Monitor.c
index f404009..c519877 100644
--- a/Monitor.c
+++ b/Monitor.c
@@ -467,29 +467,16 @@ static int check_array(struct state *st, struct mdstat_ent *mdstat,
retval = 0;
fd = open(dev, O_RDONLY);
- if (fd < 0) {
- if (!st->err)
- alert("DeviceDisappeared", dev, NULL, ainfo);
- st->err++;
- goto out;
- }
+ if (fd < 0)
+ goto disappeared;
- if (!md_array_active(fd)) {
- close(fd);
- if (!st->err)
- alert("DeviceDisappeared", dev, NULL, ainfo);
- st->err++;
- goto out;
- }
+ if (!md_array_active(fd))
+ goto disappeared;
fcntl(fd, F_SETFD, FD_CLOEXEC);
- if (md_get_array_info(fd, &array) < 0) {
- if (!st->err)
- alert("DeviceDisappeared", dev, NULL, ainfo);
- st->err++;
- close(fd);
- goto out;
- }
+ if (md_get_array_info(fd, &array) < 0)
+ goto disappeared;
+
/* It's much easier to list what array levels can't
* have a device disappear than all of them that can
*/
@@ -497,7 +484,6 @@ static int check_array(struct state *st, struct mdstat_ent *mdstat,
if (!st->err && !st->from_config)
alert("DeviceDisappeared", dev, " Wrong-Level", ainfo);
st->err++;
- close(fd);
goto out;
}
if (st->devnm[0] == 0)
@@ -534,7 +520,6 @@ static int check_array(struct state *st, struct mdstat_ent *mdstat,
st->working == array.working_disks &&
st->spare == array.spare_disks &&
(mse == NULL || (mse->percent == st->percent))) {
- close(fd);
if ((st->active < st->raid) && st->spare == 0)
retval = 1;
goto out;
@@ -614,8 +599,6 @@ static int check_array(struct state *st, struct mdstat_ent *mdstat,
if (st->metadata == NULL && st->parent_devnm[0] == 0)
st->metadata = super_by_fd(fd, NULL);
- close(fd);
-
for (i=0; i<MAX_DISKS; i++) {
mdu_disk_info_t disc = {0,0,0,0,0};
int newstate=0;
@@ -661,7 +644,15 @@ static int check_array(struct state *st, struct mdstat_ent *mdstat,
retval = 1;
out:
+ if (fd > 0)
+ close(fd);
return retval;
+
+ disappeared:
+ if (!st->err)
+ alert("DeviceDisappeared", dev, NULL, ainfo);
+ st->err++;
+ goto out;
}
static int add_new_arrays(struct mdstat_ent *mdstat, struct state **statelist,
--
2.7.4

38
SOURCES/Monitor-checkarray-Use-working_disks-from-sysfs.patch

@ -0,0 +1,38 @@ @@ -0,0 +1,38 @@
From e5eb6857cde0a6a44684dcc7ea0fb196546cf56c Mon Sep 17 00:00:00 2001
From: Jes Sorensen <jsorensen@fb.com>
Date: Tue, 9 May 2017 17:15:14 -0400
Subject: [RHEL7.5 PATCH 134/169] Monitor/check_array: Use working_disks
from sysfs

sysfs now provides working_disks information, so lets use it too.

Signed-off-by: Jes Sorensen <jsorensen@fb.com>
---
Monitor.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/Monitor.c b/Monitor.c
index 2204528..5b95847 100644
--- a/Monitor.c
+++ b/Monitor.c
@@ -524,7 +524,7 @@ static int check_array(struct state *st, struct mdstat_ent *mdstat,
}
if (st->utime == array.utime && st->failed == sra->array.failed_disks &&
- st->working == array.working_disks &&
+ st->working == sra->array.working_disks &&
st->spare == sra->array.spare_disks &&
(mse == NULL || (mse->percent == st->percent))) {
if ((st->active < st->raid) && st->spare == 0)
@@ -637,7 +637,7 @@ static int check_array(struct state *st, struct mdstat_ent *mdstat,
st->devid[i] = makedev(disc.major, disc.minor);
}
st->active = sra->array.active_disks;
- st->working = array.working_disks;
+ st->working = sra->array.working_disks;
st->spare = sra->array.spare_disks;
st->failed = sra->array.failed_disks;
st->utime = array.utime;
--
2.7.4

105
SOURCES/Monitor-containers-don-t-have-the-same-sysfs-propert.patch

@ -0,0 +1,105 @@ @@ -0,0 +1,105 @@
From 802961a2396d342b7bb3d548d412be26acbd7fa8 Mon Sep 17 00:00:00 2001
From: Mariusz Tkaczyk <mariusz.tkaczyk@intel.com>
Date: Wed, 16 Aug 2017 14:22:32 +0200
Subject: [RHEL7.5 PATCH 168/169] Monitor: containers don't have the same
sysfs properties as arrays

GET_MISMATCH option doesn't exist for containers so sysfs_read fails if
this information is requested. Set options according to the device using
information from /proc/mdstat.

Signed-off-by: Mariusz Tkaczyk <mariusz.tkaczyk@intel.com>
Signed-off-by: Jes Sorensen <jsorensen@fb.com>
---
Monitor.c | 46 ++++++++++++++++++++++++++++------------------
1 file changed, 28 insertions(+), 18 deletions(-)

diff --git a/Monitor.c b/Monitor.c
index 48c451c..f70e5b5 100644
--- a/Monitor.c
+++ b/Monitor.c
@@ -465,6 +465,8 @@ static int check_array(struct state *st, struct mdstat_ent *mdstat,
int last_disk;
int new_array = 0;
int retval;
+ int is_container = 0;
+ unsigned long array_only_flags = 0;
if (test)
alert("TestMessage", dev, NULL, ainfo);
@@ -475,6 +477,26 @@ static int check_array(struct state *st, struct mdstat_ent *mdstat,
if (fd < 0)
goto disappeared;
+ if (st->devnm[0] == 0)
+ strcpy(st->devnm, fd2devnm(fd));
+
+ for (mse2 = mdstat; mse2; mse2 = mse2->next)
+ if (strcmp(mse2->devnm, st->devnm) == 0) {
+ mse2->devnm[0] = 0; /* flag it as "used" */
+ mse = mse2;
+ }
+
+ if (!mse) {
+ /* duplicated array in statelist
+ * or re-created after reading mdstat
+ */
+ st->err++;
+ goto out;
+ }
+
+ if (mse->level == NULL)
+ is_container = 1;
+
if (!md_array_active(fd))
goto disappeared;
@@ -482,11 +504,12 @@ static int check_array(struct state *st, struct mdstat_ent *mdstat,
if (md_get_array_info(fd, &array) < 0)
goto disappeared;
- if (st->devnm[0] == 0)
- strcpy(st->devnm, fd2devnm(fd));
+ if (!is_container)
+ array_only_flags |= GET_MISMATCH;
+
+ sra = sysfs_read(-1, st->devnm, GET_LEVEL | GET_DISKS | GET_DEVS |
+ GET_STATE | array_only_flags);
- sra = sysfs_read(-1, st->devnm, GET_LEVEL | GET_DISKS | GET_MISMATCH |
- GET_DEVS | GET_STATE);
if (!sra)
goto disappeared;
@@ -500,19 +523,6 @@ static int check_array(struct state *st, struct mdstat_ent *mdstat,
goto out;
}
- for (mse2 = mdstat; mse2; mse2 = mse2->next)
- if (strcmp(mse2->devnm, st->devnm) == 0) {
- mse2->devnm[0] = 0; /* flag it as "used" */
- mse = mse2;
- }
-
- if (!mse) {
- /* duplicated array in statelist
- * or re-created after reading mdstat*/
- st->err++;
- close(fd);
- goto out;
- }
/* this array is in /proc/mdstat */
if (array.utime == 0)
/* external arrays don't update utime, so
@@ -653,7 +663,7 @@ static int check_array(struct state *st, struct mdstat_ent *mdstat,
out:
if (sra)
sysfs_free(sra);
- if (fd > 0)
+ if (fd >= 0)
close(fd);
return retval;
--
2.7.4

49
SOURCES/Monitor-don-t-assume-mdadm-parameter-is-a-blockdevi.patch

@ -0,0 +1,49 @@ @@ -0,0 +1,49 @@
From cb91230c87e02bf885759e9218abea629ab9f4b9 Mon Sep 17 00:00:00 2001
From: Tomasz Majchrzak <tomasz.majchrzak@intel.com>
Date: Mon, 19 Jun 2017 11:19:53 +0200
Subject: [RHEL7.5 PATCH 158/169] Monitor: don't assume mdadm parameter is
a block device

If symlink (e.g. /dev/md/raid) is passed as a parameter to mdadm --wait,
it fails as it's not able to find a corresponding entry in /proc/mdstat
output. Get parameter file major:minor and look for block device name in
sysfs. This commit is partial revert of commit 9e04ac1c43e6
("mdadm/util: unify stat checking blkdev into function").

Signed-off-by: Tomasz Majchrzak <tomasz.majchrzak@intel.com>
Signed-off-by: Jes Sorensen <jsorensen@fb.com>
---
Monitor.c | 13 +++++++++++--
1 file changed, 11 insertions(+), 2 deletions(-)

diff --git a/Monitor.c b/Monitor.c
index bef2f1b..48c451c 100644
--- a/Monitor.c
+++ b/Monitor.c
@@ -982,12 +982,21 @@ static void link_containers_with_subarrays(struct state *list)
int Wait(char *dev)
{
char devnm[32];
+ dev_t rdev;
+ char *tmp;
int rv = 1;
int frozen_remaining = 3;
- if (!stat_is_blkdev(dev, NULL))
+ if (!stat_is_blkdev(dev, &rdev))
+ return 2;
+
+ tmp = devid2devnm(rdev);
+ if (!tmp) {
+ pr_err("Cannot get md device name.\n");
return 2;
- strcpy(devnm, dev);
+ }
+
+ strcpy(devnm, tmp);
while(1) {
struct mdstat_ent *ms = mdstat_read(1, 0);
--
2.7.4

29
SOURCES/Monitor-mailfrom-is-initialized-correctly.patch

@ -0,0 +1,29 @@ @@ -0,0 +1,29 @@
From 72362f18aee5adedb405fe61c324604184d74555 Mon Sep 17 00:00:00 2001
From: Jes Sorensen <jsorensen@fb.com>
Date: Thu, 11 May 2017 16:44:19 -0400
Subject: [RHEL7.5 PATCH 138/169] Monitor: mailfrom is initialized
correctly

Remove gratituous variable initialization.

Signed-off-by: Jes Sorensen <jsorensen@fb.com>
---
Monitor.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/Monitor.c b/Monitor.c
index a4afe75..83a6d10 100644
--- a/Monitor.c
+++ b/Monitor.c
@@ -125,7 +125,7 @@ int Monitor(struct mddev_dev *devlist,
struct state *st2;
int finished = 0;
struct mdstat_ent *mdstat = NULL;
- char *mailfrom = NULL;
+ char *mailfrom;
struct alert_info info;
struct mddev_ident *mdlist;
--
2.7.4

72
SOURCES/Query-Handle-error-returned-by-fstat.patch

@ -0,0 +1,72 @@ @@ -0,0 +1,72 @@
From 8d0cd09d73a9a9d57ee73b7a79114e881dad1507 Mon Sep 17 00:00:00 2001
From: Jes Sorensen <jsorensen@fb.com>
Date: Thu, 13 Apr 2017 11:53:21 -0400
Subject: [RHEL7.5 PATCH 079/169] Query: Handle error returned by fstat()

We shouldn't ignore any error returned by fstat() even if open() didn't
fail.

Signed-off-by: Jes Sorensen <jsorensen@fb.com>
---
Query.c | 19 ++++++++++++-------
1 file changed, 12 insertions(+), 7 deletions(-)

diff --git a/Query.c b/Query.c
index bea273f..0d18da4 100644
--- a/Query.c
+++ b/Query.c
@@ -32,22 +32,21 @@ int Query(char *dev)
* whether it is an md device and whether it has
* a superblock
*/
- int fd = open(dev, O_RDONLY);
- int ioctlerr;
+ int fd;
+ int ioctlerr, staterr;
int superror;
struct mdinfo info;
mdu_array_info_t array;
struct supertype *st = NULL;
-
unsigned long long larray_size;
struct stat stb;
char *mddev;
mdu_disk_info_t disc;
char *activity;
+ fd = open(dev, O_RDONLY);
if (fd < 0){
- pr_err("cannot open %s: %s\n",
- dev, strerror(errno));
+ pr_err("cannot open %s: %s\n", dev, strerror(errno));
return 1;
}
@@ -56,9 +55,12 @@ int Query(char *dev)
else
ioctlerr = 0;
- fstat(fd, &stb);
+ if (fstat(fd, &stb) < 0)
+ staterr = errno;
+ else
+ staterr = 0;
- if (!ioctlerr) {
+ if (!ioctlerr && !staterr) {
if (!get_dev_size(fd, NULL, &larray_size))
larray_size = 0;
}
@@ -68,6 +70,9 @@ int Query(char *dev)
else if (ioctlerr)
printf("%s: is an md device, but gives \"%s\" when queried\n",
dev, strerror(ioctlerr));
+ else if (staterr)
+ printf("%s: is not a valid md device, returning %s\n",
+ dev, strerror(ioctlerr));
else {
printf("%s: %s %s %d devices, %d spare%s. Use mdadm --detail for more detail.\n",
dev,
--
2.7.4

28
SOURCES/Query-Quiet-gcc-since-it-cannot-know-errno-0-in-this.patch

@ -0,0 +1,28 @@ @@ -0,0 +1,28 @@
From 0dfff0f24355ad4b5c1776f7f19a404ffae25415 Mon Sep 17 00:00:00 2001
From: Jes Sorensen <jsorensen@fb.com>
Date: Fri, 21 Apr 2017 12:04:05 -0400
Subject: [RHEL7.5 PATCH 090/169] Query: Quiet gcc since it cannot know
errno != 0 in this case

Signed-off-by: Jes Sorensen <jsorensen@fb.com>
---
Query.c | 3 +++
1 file changed, 3 insertions(+)

diff --git a/Query.c b/Query.c
index 4dec9f5..2bd0e2a 100644
--- a/Query.c
+++ b/Query.c
@@ -68,6 +68,9 @@ int Query(char *dev)
if (md_get_array_info(fd, &array) < 0) {
ioctlerr = errno;
+ level = -1;
+ raid_disks = -1;
+ spare_disks = -1;
} else {
level = array.level;
raid_disks = array.raid_disks;
--
2.7.4

65
SOURCES/Query-Remove-all-references-to-md_get_version.patch

@ -0,0 +1,65 @@ @@ -0,0 +1,65 @@
From 5cb859962febacba3bb9257fc6ed9553ecc16752 Mon Sep 17 00:00:00 2001
From: Jes Sorensen <Jes.Sorensen@gmail.com>
Date: Wed, 5 Apr 2017 15:37:38 -0400
Subject: [RHEL7.5 PATCH 060/169] Query: Remove all references to
md_get_version()

More legacy code removed

Signed-off-by: Jes Sorensen <Jes.Sorensen@gmail.com>
---
Query.c | 13 +++----------
1 file changed, 3 insertions(+), 10 deletions(-)

diff --git a/Query.c b/Query.c
index a2c839c..bea273f 100644
--- a/Query.c
+++ b/Query.c
@@ -33,7 +33,6 @@ int Query(char *dev)
* a superblock
*/
int fd = open(dev, O_RDONLY);
- int vers;
int ioctlerr;
int superror;
struct mdinfo info;
@@ -52,7 +51,6 @@ int Query(char *dev)
return 1;
}
- vers = md_get_version(fd);
if (md_get_array_info(fd, &array) < 0)
ioctlerr = errno;
else
@@ -60,16 +58,12 @@ int Query(char *dev)
fstat(fd, &stb);
- if (vers>=9000 && !ioctlerr) {
+ if (!ioctlerr) {
if (!get_dev_size(fd, NULL, &larray_size))
larray_size = 0;
}
- if (vers < 0)
- printf("%s: is not an md array\n", dev);
- else if (vers < 9000)
- printf("%s: is an md device, but kernel cannot provide details\n", dev);
- else if (ioctlerr == ENODEV)
+ if (ioctlerr == ENODEV)
printf("%s: is an md device which is not active\n", dev);
else if (ioctlerr)
printf("%s: is an md device, but gives \"%s\" when queried\n",
@@ -100,8 +94,7 @@ int Query(char *dev)
disc.number = info.disk.number;
activity = "undetected";
if (mddev && (fd = open(mddev, O_RDONLY))>=0) {
- if (md_get_version(fd) >= 9000 &&
- md_get_array_info(fd, &array) >= 0) {
+ if (md_get_array_info(fd, &array) >= 0) {
if (md_get_disk_info(fd, &disc) >= 0 &&
makedev((unsigned)disc.major,(unsigned)disc.minor) == stb.st_rdev)
activity = "active";
--
2.7.4

80
SOURCES/Query-Use-sysfs-to-obtain-data-if-possible.patch

@ -0,0 +1,80 @@ @@ -0,0 +1,80 @@
From f22d6cde7c7e4be38230ac4c51c3af850ed1614e Mon Sep 17 00:00:00 2001
From: Jes Sorensen <jsorensen@fb.com>
Date: Thu, 13 Apr 2017 12:20:46 -0400
Subject: [RHEL7.5 PATCH 080/169] Query: Use sysfs to obtain data if
possible

Use sysfs to obtain leve, raid_disks, and spare_disks. If sysfs fails,
fall back to calling the ioctl via md_get_array_info().

Signed-off-by: Jes Sorensen <jsorensen@fb.com>
---
Query.c | 32 ++++++++++++++++++++++----------
1 file changed, 22 insertions(+), 10 deletions(-)

diff --git a/Query.c b/Query.c
index 0d18da4..b761c47 100644
--- a/Query.c
+++ b/Query.c
@@ -35,7 +35,9 @@ int Query(char *dev)
int fd;
int ioctlerr, staterr;
int superror;
+ int level, raid_disks, spare_disks;
struct mdinfo info;
+ struct mdinfo *sra;
mdu_array_info_t array;
struct supertype *st = NULL;
unsigned long long larray_size;
@@ -50,16 +52,28 @@ int Query(char *dev)
return 1;
}
- if (md_get_array_info(fd, &array) < 0)
- ioctlerr = errno;
- else
- ioctlerr = 0;
-
if (fstat(fd, &stb) < 0)
staterr = errno;
else
staterr = 0;
+ ioctlerr = 0;
+
+ sra = sysfs_read(fd, dev, GET_DISKS | GET_LEVEL | GET_DEVS | GET_STATE);
+ if (sra) {
+ level = sra->array.level;
+ raid_disks = sra->array.raid_disks;
+ spare_disks = sra->array.spare_disks;
+ } else {
+ if (md_get_array_info(fd, &array) < 0) {
+ ioctlerr = errno;
+ } else {
+ level = array.level;
+ raid_disks = array.raid_disks;
+ spare_disks = array.spare_disks;
+ }
+ }
+
if (!ioctlerr && !staterr) {
if (!get_dev_size(fd, NULL, &larray_size))
larray_size = 0;
@@ -75,11 +89,9 @@ int Query(char *dev)
dev, strerror(ioctlerr));
else {
printf("%s: %s %s %d devices, %d spare%s. Use mdadm --detail for more detail.\n",
- dev,
- human_size_brief(larray_size,IEC),
- map_num(pers, array.level),
- array.raid_disks,
- array.spare_disks, array.spare_disks==1?"":"s");
+ dev, human_size_brief(larray_size,IEC),
+ map_num(pers, level), raid_disks,
+ spare_disks, spare_disks == 1 ? "" : "s");
}
st = guess_super(fd);
if (st && st->ss->compare_super != NULL)
--
2.7.4

58
SOURCES/Replace-snprintf-with-strncpy-at-some-places-to-avoi.patch

@ -0,0 +1,58 @@ @@ -0,0 +1,58 @@
From 618f4e6d63c8c09d8d4002770e44617f3477f137 Mon Sep 17 00:00:00 2001
From: Xiao Ni <xni@redhat.com>
Date: Sat, 18 Mar 2017 10:33:44 +0800
Subject: [RHEL7.5 PATCH 015/169] Replace snprintf with strncpy at some
places to avoid truncation

In gcc7 there are some building errors like:
directive output may be truncated writing up to 31 bytes into a region of size 24
snprintf(str, MPB_SIG_LEN, %s, mpb->sig);

It just need to copy one string to target. So use strncpy to replace it.

For this line code: snprintf(str, MPB_SIG_LEN, %s, mpb->sig);
Because mpb->sig has the content of version after magic, so
it's better to use strncpy to replace snprintf too.

Signed-off-by: Xiao Ni <xni@redhat.com>
Signed-off-by: Jes Sorensen <Jes.Sorensen@gmail.com>
---
super-intel.c | 9 ++++++---
1 file changed, 6 insertions(+), 3 deletions(-)

diff --git a/super-intel.c b/super-intel.c
index d5e9517..343f20d 100644
--- a/super-intel.c
+++ b/super-intel.c
@@ -1811,7 +1811,8 @@ static void examine_super_imsm(struct supertype *st, char *homehost)
__u32 reserved = imsm_reserved_sectors(super, super->disks);
struct dl *dl;
- snprintf(str, MPB_SIG_LEN, "%s", mpb->sig);
+ strncpy(str, (char *)mpb->sig, MPB_SIG_LEN);
+ str[MPB_SIG_LEN-1] = '\0';
printf(" Magic : %s\n", str);
snprintf(str, strlen(MPB_VERSION_RAID0), "%s", get_imsm_version(mpb));
printf(" Version : %s\n", get_imsm_version(mpb));
@@ -7142,14 +7143,16 @@ static int update_subarray_imsm(struct supertype *st, char *subarray,
u->type = update_rename_array;
u->dev_idx = vol;
- snprintf((char *) u->name, MAX_RAID_SERIAL_LEN, "%s", name);
+ strncpy((char *) u->name, name, MAX_RAID_SERIAL_LEN);
+ u->name[MAX_RAID_SERIAL_LEN-1] = '\0';
append_metadata_update(st, u, sizeof(*u));
} else {
struct imsm_dev *dev;
int i;
dev = get_imsm_dev(super, vol);
- snprintf((char *) dev->volume, MAX_RAID_SERIAL_LEN, "%s", name);
+ strncpy((char *) dev->volume, name, MAX_RAID_SERIAL_LEN);
+ dev->volume[MAX_RAID_SERIAL_LEN-1] = '\0';
for (i = 0; i < mpb->num_raid_devs; i++) {
dev = get_imsm_dev(super, i);
handle_missing(super, dev);
--
2.7.4

1396
SOURCES/Retire-mdassemble.patch

File diff suppressed because it is too large Load Diff

117
SOURCES/Retry-HOT_REMOVE_DISK-a-few-times.patch

@ -0,0 +1,117 @@ @@ -0,0 +1,117 @@
From 2dd271fe7041c2f7036939cf6917c0578b92fefe Mon Sep 17 00:00:00 2001
From: NeilBrown <neilb@suse.com>
Date: Mon, 27 Mar 2017 12:50:16 +1100
Subject: [RHEL7.5 PATCH 020/169] Retry HOT_REMOVE_DISK a few times.

HOT_REMOVE_DISK can fail with EBUSY if there are outstanding
IO request that have not completed yet. It can sometimes
be helpful to wait a little while for these to complete.

We already do this in impose_level() when reshaping a device,
but not in Manage.c in response to an explicit --remove request.

So create hot_remove_disk() to central this code, and call it
where-ever it makes sense to wait for a HOT_REMOVE_DISK to succeed.

Signed-off-by: NeilBrown <neilb@suse.com>
Signed-off-by: Jes Sorensen <Jes.Sorensen@gmail.com>
---
Grow.c | 9 +--------
Manage.c | 4 ++--
mdadm.h | 1 +
util.c | 18 ++++++++++++++++++
4 files changed, 22 insertions(+), 10 deletions(-)

diff --git a/Grow.c b/Grow.c
index 455c5f9..218a706 100755
--- a/Grow.c
+++ b/Grow.c
@@ -2736,7 +2736,6 @@ static int impose_level(int fd, int level, char *devname, int verbose)
for (d = 0, found = 0;
d < MAX_DISKS && found < array.nr_disks;
d++) {
- int cnt;
mdu_disk_info_t disk;
disk.number = d;
if (ioctl(fd, GET_DISK_INFO, &disk) < 0)
@@ -2750,13 +2749,7 @@ static int impose_level(int fd, int level, char *devname, int verbose)
continue;
ioctl(fd, SET_DISK_FAULTY,
makedev(disk.major, disk.minor));
- cnt = 5;
- while (ioctl(fd, HOT_REMOVE_DISK,
- makedev(disk.major, disk.minor)) < 0
- && errno == EBUSY
- && cnt--) {
- usleep(10000);
- }
+ hot_remove_disk(fd, makedev(disk.major, disk.minor));
}
}
c = map_num(pers, level);
diff --git a/Manage.c b/Manage.c
index 5c3d2b9..9139f96 100644
--- a/Manage.c
+++ b/Manage.c
@@ -1183,7 +1183,7 @@ int Manage_remove(struct supertype *tst, int fd, struct mddev_dev *dv,
else
err = 0;
} else {
- err = ioctl(fd, HOT_REMOVE_DISK, rdev);
+ err = hot_remove_disk(fd, rdev);
if (err && errno == ENODEV) {
/* Old kernels rejected this if no personality
* is registered */
@@ -1607,7 +1607,7 @@ int Manage_subdevs(char *devname, int fd,
if (dv->disposition == 'F')
/* Need to remove first */
- ioctl(fd, HOT_REMOVE_DISK, rdev);
+ hot_remove_disk(fd, rdev);
/* Make sure it isn't in use (in 2.6 or later) */
tfd = dev_open(dv->devname, O_RDONLY|O_EXCL);
if (tfd >= 0) {
diff --git a/mdadm.h b/mdadm.h
index 91fd9eb..5bcfb86 100644
--- a/mdadm.h
+++ b/mdadm.h
@@ -1476,6 +1476,7 @@ extern int add_disk(int mdfd, struct supertype *st,
struct mdinfo *sra, struct mdinfo *info);
extern int remove_disk(int mdfd, struct supertype *st,
struct mdinfo *sra, struct mdinfo *info);
+extern int hot_remove_disk(int mdfd, unsigned long dev);
extern int set_array_info(int mdfd, struct supertype *st, struct mdinfo *info);
unsigned long long min_recovery_start(struct mdinfo *array);
diff --git a/util.c b/util.c
index 32bd909..d09a7e2 100644
--- a/util.c
+++ b/util.c
@@ -1795,6 +1795,24 @@ int remove_disk(int mdfd, struct supertype *st,
return rv;
}
+int hot_remove_disk(int mdfd, unsigned long dev)
+{
+ int cnt = 5;
+ int ret;
+
+ /* HOT_REMOVE_DISK can fail with EBUSY if there are
+ * outstanding IO requests to the device.
+ * In this case, it can be helpful to wait a little while,
+ * up to half a second, for that IO to flush.
+ */
+ while ((ret = ioctl(mdfd, HOT_REMOVE_DISK, dev)) == -1 &&
+ errno == EBUSY &&
+ cnt-- > 0)
+ usleep(10000);
+
+ return ret;
+}
+
int set_array_info(int mdfd, struct supertype *st, struct mdinfo *info)
{
/* Initialise kernel's knowledge of array.
--
2.7.4

32
SOURCES/Revert-mdadm-grow-reshape-would-be-stuck-from-raid1-.patch

@ -0,0 +1,32 @@ @@ -0,0 +1,32 @@
From 2cfe6f7c646ebc25043f7607f5756edad0bc3071 Mon Sep 17 00:00:00 2001
From: Jes Sorensen <Jes.Sorensen@gmail.com>
Date: Tue, 11 Apr 2017 11:30:23 -0400
Subject: [RHEL7.5 PATCH 069/169] Revert "mdadm/grow: reshape would be
stuck from raid1 to raid5"

This reverts commit 5b2846684ef5172eccc432e3520b79efbc2abba5.

This was a red herring and shouldn't have been applied in the first
place.

Signed-off-by: Jes Sorensen <Jes.Sorensen@gmail.com>
---
systemd/mdadm-grow-continue@.service | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/systemd/mdadm-grow-continue@.service b/systemd/mdadm-grow-continue@.service
index 882bc0b..5c667d2 100644
--- a/systemd/mdadm-grow-continue@.service
+++ b/systemd/mdadm-grow-continue@.service
@@ -10,7 +10,7 @@ Description=Manage MD Reshape on /dev/%I
DefaultDependencies=no
[Service]
-ExecStart=BINDIR/mdadm --grow --continue /dev/%i
+ExecStart=BINDIR/mdadm --grow --continue /dev/%I
StandardInput=null
StandardOutput=null
StandardError=null
--
2.7.4

49
SOURCES/Use-correct-syntax-for-passing-DEVLINKS-to-mdadm-fro.patch

@ -0,0 +1,49 @@ @@ -0,0 +1,49 @@
From ceb5f8ef92c97d1f44c75a3b74f64aa12a3303ef Mon Sep 17 00:00:00 2001
From: NeilBrown <neilb@suse.com>
Date: Fri, 4 Aug 2017 15:30:02 +1000
Subject: [RHEL7.5 PATCH 165/169] Use correct syntax for passing DEVLINKS
to mdadm from udev

${DEVLINKS}
is not valid udev syntax, and is passed through uninterpreted.
$env{DEVLINKS}
or
%e{DEVLINKS}
is correct.

Signed-off-by: NeilBrown <neilb@suse.com>
Signed-off-by: Jes Sorensen <jsorensen@fb.com>
---
mdadm.8.in | 2 +-
udev-md-raid-assembly.rules | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/mdadm.8.in b/mdadm.8.in
index 461c5de..e0747fb 100644
--- a/mdadm.8.in
+++ b/mdadm.8.in
@@ -2947,7 +2947,7 @@ This is the only context where the aliases are used. They are
usually provided by a
.I udev
rules mentioning
-.BR ${DEVLINKS} .
+.BR $env{DEVLINKS} .
.IP +
Does the device have a valid md superblock? If a specific metadata
diff --git a/udev-md-raid-assembly.rules b/udev-md-raid-assembly.rules
index 8ca232a..9f055ed 100644
--- a/udev-md-raid-assembly.rules
+++ b/udev-md-raid-assembly.rules
@@ -30,7 +30,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|change", IMPORT{program}="BINDIR/mdadm --incremental --export $devnode --offroot ${DEVLINKS}"
+ACTION=="add|change", IMPORT{program}="BINDIR/mdadm --incremental --export $devnode --offroot $env{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+="BINDIR/mdadm -If $name --path $env{ID_PATH}"
ACTION=="remove", ENV{ID_PATH}!="?*", RUN+="BINDIR/mdadm -If $name"
--
2.7.4

134
SOURCES/Zeroout-whole-ppl-space-during-creation-force-assemb.patch

@ -0,0 +1,134 @@ @@ -0,0 +1,134 @@
From b251424242b46d62f666829c0e7a7550768fc8de Mon Sep 17 00:00:00 2001
From: Pawel Baldysiak <pawel.baldysiak@intel.com>
Date: Thu, 28 Sep 2017 14:41:11 +0200
Subject: [PATCH 05/12] Zeroout whole ppl space during creation/force
assemble

PPL area should be cleared before creation/force assemble.
If the drive was used in other RAID array, it might contains PPL from it.
There is a risk that mdadm recognizes those PPLs and
refuses to assemble the RAID due to PPL conflict with created
array.

Signed-off-by: Pawel Baldysiak <pawel.baldysiak@intel.com>
Signed-off-by: Jes Sorensen <jsorensen@fb.com>
---
mdadm.h | 1 +
super-intel.c | 7 ++++++-
super1.c | 5 +++++
util.c | 49 +++++++++++++++++++++++++++++++++++++++++++++++++
4 files changed, 61 insertions(+), 1 deletion(-)

diff --git a/mdadm.h b/mdadm.h
index 3fc8a4f..85947bf 100644
--- a/mdadm.h
+++ b/mdadm.h
@@ -687,6 +687,7 @@ extern int sysfs_unique_holder(char *devnm, long rdev);
extern int sysfs_freeze_array(struct mdinfo *sra);
extern int sysfs_wait(int fd, int *msec);
extern int load_sys(char *path, char *buf, int len);
+extern int zero_disk_range(int fd, unsigned long long sector, size_t count);
extern int reshape_prepare_fdlist(char *devname,
struct mdinfo *sra,
int raid_disks,
diff --git a/super-intel.c b/super-intel.c
index 56dec36..65cdc92 100644
--- a/super-intel.c
+++ b/super-intel.c
@@ -6065,7 +6065,12 @@ static int write_init_ppl_imsm(struct supertype *st, struct mdinfo *info, int fd
struct ppl_header *ppl_hdr;
int ret;
- ret = posix_memalign(&buf, 4096, PPL_HEADER_SIZE);
+ /* first clear entire ppl space */
+ ret = zero_disk_range(fd, info->ppl_sector, info->ppl_size);
+ if (ret)
+ return ret;
+
+ ret = posix_memalign(&buf, MAX_SECTOR_SIZE, PPL_HEADER_SIZE);
if (ret) {
pr_err("Failed to allocate PPL header buffer\n");
return ret;
diff --git a/super1.c b/super1.c
index f80e38a..7ae6dc3 100644
--- a/super1.c
+++ b/super1.c
@@ -1823,6 +1823,11 @@ static int write_init_ppl1(struct supertype *st, struct mdinfo *info, int fd)
struct ppl_header *ppl_hdr;
int ret;
+ /* first clear entire ppl space */
+ ret = zero_disk_range(fd, info->ppl_sector, info->ppl_size);
+ if (ret)
+ return ret;
+
ret = posix_memalign(&buf, 4096, PPL_HEADER_SIZE);
if (ret) {
pr_err("Failed to allocate PPL header buffer\n");
diff --git a/util.c b/util.c
index 68af381..c11729e 100644
--- a/util.c
+++ b/util.c
@@ -30,6 +30,7 @@
#include <sys/un.h>
#include <sys/resource.h>
#include <sys/vfs.h>
+#include <sys/mman.h>
#include <linux/magic.h>
#include <poll.h>
#include <ctype.h>
@@ -2334,3 +2335,51 @@ void set_hooks(void)
set_dlm_hooks();
set_cmap_hooks();
}
+
+int zero_disk_range(int fd, unsigned long long sector, size_t count)
+{
+ int ret = 0;
+ int fd_zero;
+ void *addr = NULL;
+ size_t written = 0;
+ size_t len = count * 512;
+ ssize_t n;
+
+ fd_zero = open("/dev/zero", O_RDONLY);
+ if (fd_zero < 0) {
+ pr_err("Cannot open /dev/zero\n");
+ return -1;
+ }
+
+ if (lseek64(fd, sector * 512, SEEK_SET) < 0) {
+ ret = -errno;
+ pr_err("Failed to seek offset for zeroing\n");
+ goto out;
+ }
+
+ addr = mmap(NULL, len, PROT_READ, MAP_PRIVATE, fd_zero, 0);
+
+ if (addr == MAP_FAILED) {
+ ret = -errno;
+ pr_err("Mapping /dev/zero failed\n");
+ goto out;
+ }
+
+ do {
+ n = write(fd, addr + written, len - written);
+ if (n < 0) {
+ if (errno == EINTR)
+ continue;
+ ret = -errno;
+ pr_err("Zeroing disk range failed\n");
+ break;
+ }
+ written += n;
+ } while (written != len);
+
+ munmap(addr, len);
+
+out:
+ close(fd_zero);
+ return ret;
+}
--
2.7.4

44
SOURCES/add-man-page-for-symlinks.patch

@ -0,0 +1,44 @@ @@ -0,0 +1,44 @@
commit d64c2283633cd4d7569690d1df8d1a10f3b6b040
Author: Zhilong Liu <zlliu@suse.com>
Date: Mon Mar 6 10:39:57 2017 +0800

mdadm:add man page for --symlinks
In build and create mode:
--symlinks
Auto creation of symlinks in /dev to /dev/md, option --symlinks
must be 'no' or 'yes' and work with --create and --build.
In assemble mode:
--symlinks
See this option under Create and Build options.
Signed-off-by: Zhilong Liu <zlliu@suse.com>
Signed-off-by: Jes Sorensen <Jes.Sorensen@gmail.com>

diff --git a/mdadm.8.in b/mdadm.8.in
index 1e4f91d..df1d460 100644
--- a/mdadm.8.in
+++ b/mdadm.8.in
@@ -1015,6 +1015,11 @@ simultaneously. If not specified, this defaults to 4.
Specify journal device for the RAID-4/5/6 array. The journal device
should be a SSD with reasonable lifetime.
+.TP
+.BR \-\-symlinks
+Auto creation of symlinks in /dev to /dev/md, option --symlinks must
+be 'no' or 'yes' and work with --create and --build.
+
.SH For assemble:
@@ -1291,6 +1296,10 @@ Reshape can be continued later using the
.B \-\-continue
option for the grow command.
+.TP
+.BR \-\-symlinks
+See this option under Create and Build options.
+
.SH For Manage mode:
.TP

266
SOURCES/add-ppl-and-no-ppl-options-for-update.patch

@ -0,0 +1,266 @@ @@ -0,0 +1,266 @@
commit e6e9dd3f1b255f9921ebc023c1e5b65601a637e2
Author: Artur Paszkiewicz <artur.paszkiewicz@intel.com>
Date: Wed Mar 29 11:54:19 2017 +0200

Add 'ppl' and 'no-ppl' options for --update=
This can be used with --assemble for super1 and with --update-subarray
for imsm to enable or disable PPL in the metadata.
Signed-off-by: Artur Paszkiewicz <artur.paszkiewicz@intel.com>
Signed-off-by: Jes Sorensen <Jes.Sorensen@gmail.com>

diff --git a/Assemble.c b/Assemble.c
index c098420..6a6a56b 100644
--- a/Assemble.c
+++ b/Assemble.c
@@ -602,6 +602,12 @@ static int load_devices(struct devs *devices, char *devmap,
if (strcmp(c->update, "uuid") == 0 && !ident->uuid_set)
random_uuid((__u8 *)ident->uuid);
+ if (strcmp(c->update, "ppl") == 0 &&
+ ident->bitmap_fd >= 0) {
+ pr_err("PPL is not compatible with bitmap\n");
+ return -1;
+ }
+
dfd = dev_open(devname,
tmpdev->disposition == 'I'
? O_RDWR : (O_RDWR|O_EXCL));
diff --git a/mdadm.8.in b/mdadm.8.in
index cad5db5..1178ed9 100644
--- a/mdadm.8.in
+++ b/mdadm.8.in
@@ -1176,6 +1176,8 @@ argument given to this flag can be one of
.BR no\-bitmap ,
.BR bbl ,
.BR no\-bbl ,
+.BR ppl ,
+.BR no\-ppl ,
.BR metadata ,
or
.BR super\-minor .
@@ -1316,6 +1318,16 @@ option will cause any reservation of space for a bad block list to be
removed. If the bad block list contains entries, this will fail, as
removing the list could cause data corruption.
+The
+.B ppl
+option will enable PPL for a RAID5 array and reserve space for PPL on each
+device. There must be enough free space between the data and superblock and a
+write-intent bitmap or journal must not be used.
+
+The
+.B no\-ppl
+option will disable PPL in the superblock.
+
.TP
.BR \-\-freeze\-reshape
Option is intended to be used in start-up scripts during initrd boot phase.
@@ -2327,9 +2339,11 @@ superblock field in the subarray. Similar to updating an array in
.B \-U
or
.B \-\-update=
-option. Currently only
-.B name
-is supported.
+option. The supported options are
+.BR name ,
+.B ppl
+and
+.BR no\-ppl .
The
.B name
@@ -2340,6 +2354,13 @@ re\-assembled. If updating
would change the UUID of an active subarray this operation is blocked,
and the command will end in an error.
+The
+.B ppl
+and
+.B no\-ppl
+options enable and disable PPL in the metadata. Currently supported only for
+IMSM subarrays.
+
.TP
.B \-\-examine
The device should be a component of an md array.
diff --git a/mdadm.c b/mdadm.c
index d4e8286..6edf3ab 100644
--- a/mdadm.c
+++ b/mdadm.c
@@ -769,6 +769,10 @@ int main(int argc, char *argv[])
continue;
if (strcmp(c.update, "force-no-bbl") == 0)
continue;
+ if (strcmp(c.update, "ppl") == 0)
+ continue;
+ if (strcmp(c.update, "no-ppl") == 0)
+ continue;
if (strcmp(c.update, "metadata") == 0)
continue;
if (strcmp(c.update, "revert-reshape") == 0)
@@ -802,7 +806,7 @@ int main(int argc, char *argv[])
" 'sparc2.2', 'super-minor', 'uuid', 'name', 'nodes', 'resync',\n"
" 'summaries', 'homehost', 'home-cluster', 'byteorder', 'devicesize',\n"
" 'no-bitmap', 'metadata', 'revert-reshape'\n"
- " 'bbl', 'no-bbl', 'force-no-bbl'\n"
+ " 'bbl', 'no-bbl', 'force-no-bbl', 'ppl', 'no-ppl'\n"
);
exit(outf == stdout ? 0 : 2);
diff --git a/super-intel.c b/super-intel.c
index 87fec8b..785488a 100644
--- a/super-intel.c
+++ b/super-intel.c
@@ -451,6 +451,7 @@ enum imsm_update_type {
update_general_migration_checkpoint,
update_size_change,
update_prealloc_badblocks_mem,
+ update_rwh_policy,
};
struct imsm_update_activate_spare {
@@ -543,6 +544,12 @@ struct imsm_update_prealloc_bb_mem {
enum imsm_update_type type;
};
+struct imsm_update_rwh_policy {
+ enum imsm_update_type type;
+ int new_policy;
+ int dev_idx;
+};
+
static const char *_sys_dev_type[] = {
[SYS_DEV_UNKNOWN] = "Unknown",
[SYS_DEV_SAS] = "SAS",
@@ -7373,6 +7380,34 @@ static int update_subarray_imsm(struct supertype *st, char *subarray,
}
super->updates_pending++;
}
+ } else if (strcmp(update, "ppl") == 0 ||
+ strcmp(update, "no-ppl") == 0) {
+ int new_policy;
+ char *ep;
+ int vol = strtoul(subarray, &ep, 10);
+
+ if (*ep != '\0' || vol >= super->anchor->num_raid_devs)
+ return 2;
+
+ if (strcmp(update, "ppl") == 0)
+ new_policy = RWH_DISTRIBUTED;
+ else
+ new_policy = RWH_OFF;
+
+ if (st->update_tail) {
+ struct imsm_update_rwh_policy *u = xmalloc(sizeof(*u));
+
+ u->type = update_rwh_policy;
+ u->dev_idx = vol;
+ u->new_policy = new_policy;
+ append_metadata_update(st, u, sizeof(*u));
+ } else {
+ struct imsm_dev *dev;
+
+ dev = get_imsm_dev(super, vol);
+ dev->rwh_policy = new_policy;
+ super->updates_pending++;
+ }
} else
return 2;
@@ -9599,6 +9634,21 @@ static void imsm_process_update(struct supertype *st,
}
case update_prealloc_badblocks_mem:
break;
+ case update_rwh_policy: {
+ struct imsm_update_rwh_policy *u = (void *)update->buf;
+ int target = u->dev_idx;
+ struct imsm_dev *dev = get_imsm_dev(super, target);
+ if (!dev) {
+ dprintf("could not find subarray-%d\n", target);
+ break;
+ }
+
+ if (dev->rwh_policy != u->new_policy) {
+ dev->rwh_policy = u->new_policy;
+ super->updates_pending++;
+ }
+ break;
+ }
default:
pr_err("error: unsuported process update type:(type: %d)\n", type);
}
@@ -9844,6 +9894,11 @@ static int imsm_prepare_update(struct supertype *st,
super->extra_space += sizeof(struct bbm_log) -
get_imsm_bbm_log_size(super->bbm_log);
break;
+ case update_rwh_policy: {
+ if (update->len < (int)sizeof(struct imsm_update_rwh_policy))
+ return 0;
+ break;
+ }
default:
return 0;
}
diff --git a/super1.c b/super1.c
index 409b6c3..e76f777 100644
--- a/super1.c
+++ b/super1.c
@@ -1325,6 +1325,55 @@ static int update_super1(struct supertype *st, struct mdinfo *info,
sb->bblog_size = 0;
sb->bblog_shift = 0;
sb->bblog_offset = 0;
+ } else if (strcmp(update, "ppl") == 0) {
+ unsigned long long sb_offset = __le64_to_cpu(sb->super_offset);
+ unsigned long long data_offset = __le64_to_cpu(sb->data_offset);
+ unsigned long long data_size = __le64_to_cpu(sb->data_size);
+ long bb_offset = __le32_to_cpu(sb->bblog_offset);
+ int space;
+ int optimal_space;
+ int offset;
+
+ if (sb->feature_map & __cpu_to_le32(MD_FEATURE_BITMAP_OFFSET)) {
+ pr_err("Cannot add PPL to array with bitmap\n");
+ return -2;
+ }
+
+ if (sb->feature_map & __cpu_to_le32(MD_FEATURE_JOURNAL)) {
+ pr_err("Cannot add PPL to array with journal\n");
+ return -2;
+ }
+
+ if (sb_offset < data_offset) {
+ if (bb_offset)
+ space = bb_offset - 8;
+ else
+ space = data_offset - sb_offset - 8;
+ offset = 8;
+ } else {
+ offset = -(sb_offset - data_offset - data_size);
+ if (offset < INT16_MIN)
+ offset = INT16_MIN;
+ space = -(offset - bb_offset);
+ }
+
+ if (space < (PPL_HEADER_SIZE >> 9) + 8) {
+ pr_err("Not enough space to add ppl\n");
+ return -2;
+ }
+
+ optimal_space = choose_ppl_space(__le32_to_cpu(sb->chunksize));
+
+ if (space > optimal_space)
+ space = optimal_space;
+ if (space > UINT16_MAX)
+ space = UINT16_MAX;
+
+ sb->ppl.offset = __cpu_to_le16(offset);
+ sb->ppl.size = __cpu_to_le16(space);
+ sb->feature_map |= __cpu_to_le32(MD_FEATURE_PPL);
+ } else if (strcmp(update, "no-ppl") == 0) {
+ sb->feature_map &= ~ __cpu_to_le32(MD_FEATURE_PPL);
} else if (strcmp(update, "name") == 0) {
if (info->name[0] == 0)
sprintf(info->name, "%d", info->array.md_minor);

78
SOURCES/allocate-buffer-to-support-maximum-sector-size.patch

@ -0,0 +1,78 @@ @@ -0,0 +1,78 @@
commit 853375734edcfd70ba64b444b9e69f7e336a30b7
Author: Alexey Obitotskiy <aleksey.obitotskiy@intel.com>
Date: Tue May 9 12:25:44 2017 +0200

imsm: allocate buffer to support maximum sector size
Allocate migration record buffer to support maximum sector size. Disk with
non-matching sector size is not going to be included in the array, however
some preparation/cleanup actions still take place on it and they would
cause a crash. Clear migration record using sector size of the disk (not
array) as they might not match.
Signed-off-by: Alexey Obitotskiy <aleksey.obitotskiy@intel.com>
Signed-off-by: Tomasz Majchrzak <tomasz.majchrzak@intel.com>
Signed-off-by: Jes Sorensen <jsorensen@fb.com>

diff --git a/super-intel.c b/super-intel.c
index 2a5d848..cfb10d5 100644
--- a/super-intel.c
+++ b/super-intel.c
@@ -4229,8 +4229,8 @@ static int load_imsm_mpb(int fd, struct intel_super *super, char *devname)
sectors = mpb_sectors(anchor, sector_size) - 1;
free(anchor);
- if (posix_memalign(&super->migr_rec_buf, sector_size,
- MIGR_REC_BUF_SECTORS*sector_size) != 0) {
+ if (posix_memalign(&super->migr_rec_buf, MAX_SECTOR_SIZE,
+ MIGR_REC_BUF_SECTORS*MAX_SECTOR_SIZE) != 0) {
pr_err("could not allocate migr_rec buffer\n");
free(super->buf);
return 2;
@@ -5258,8 +5258,9 @@ static int init_super_imsm_volume(struct supertype *st, mdu_array_info_t *info,
pr_err("could not allocate new mpb\n");
return 0;
}
- if (posix_memalign(&super->migr_rec_buf, sector_size,
- MIGR_REC_BUF_SECTORS*sector_size) != 0) {
+ if (posix_memalign(&super->migr_rec_buf, MAX_SECTOR_SIZE,
+ MIGR_REC_BUF_SECTORS*
+ MAX_SECTOR_SIZE) != 0) {
pr_err("could not allocate migr_rec buffer\n");
free(super->buf);
free(super);
@@ -5719,12 +5720,12 @@ static int add_to_super_imsm(struct supertype *st, mdu_disk_info_t *dk,
}
/* clear migr_rec when adding disk to container */
- memset(super->migr_rec_buf, 0, MIGR_REC_BUF_SECTORS*super->sector_size);
- if (lseek64(fd, size - MIGR_REC_SECTOR_POSITION*super->sector_size,
+ memset(super->migr_rec_buf, 0, MIGR_REC_BUF_SECTORS*MAX_SECTOR_SIZE);
+ if (lseek64(fd, size - MIGR_REC_SECTOR_POSITION*member_sector_size,
SEEK_SET) >= 0) {
if ((unsigned int)write(fd, super->migr_rec_buf,
- MIGR_REC_BUF_SECTORS*super->sector_size) !=
- MIGR_REC_BUF_SECTORS*super->sector_size)
+ MIGR_REC_BUF_SECTORS*member_sector_size) !=
+ MIGR_REC_BUF_SECTORS*member_sector_size)
perror("Write migr_rec failed");
}
@@ -5916,7 +5917,7 @@ static int write_super_imsm(struct supertype *st, int doclose)
}
if (clear_migration_record)
memset(super->migr_rec_buf, 0,
- MIGR_REC_BUF_SECTORS*sector_size);
+ MIGR_REC_BUF_SECTORS*MAX_SECTOR_SIZE);
if (sector_size == 4096)
convert_to_4k(super);
@@ -11770,7 +11771,7 @@ static int imsm_manage_reshape(
/* clear migr_rec on disks after successful migration */
struct dl *d;
- memset(super->migr_rec_buf, 0, MIGR_REC_BUF_SECTORS*sector_size);
+ memset(super->migr_rec_buf, 0, MIGR_REC_BUF_SECTORS*MAX_SECTOR_SIZE);
for (d = super->disks; d; d = d->next) {
if (d->index < 0 || is_failed(&d->disk))
continue;

37
SOURCES/allow-drives-in-a-container-regardless-of-sector-size.patch

@ -0,0 +1,37 @@ @@ -0,0 +1,37 @@
commit 5c5ea85b4deedf5e7491a905bbb4f4a3bc284f2c
Author: Alexey Obitotskiy <aleksey.obitotskiy@intel.com>
Date: Tue May 9 12:25:43 2017 +0200

imsm: allow drives in a container regardless of sector size
IMSM doesn't allow to create arrays including drives with different
sector sizes. The initial idea was not to permit to combine drives
with different sector size in the same container. The problem is it
only worked for array creation. On array assemble there are no
calls to metadata handlers to see if drive is suitable for a container
(e.g. as a spare) and it leads to wrong configuration.
Revert the change and allow adding drives with different sector size
to the container.
Signed-off-by: Alexey Obitotskiy <aleksey.obitotskiy@intel.com>
Signed-off-by: Tomasz Majchrzak <tomasz.majchrzak@intel.com>
Signed-off-by: Jes Sorensen <jsorensen@fb.com>

diff --git a/super-intel.c b/super-intel.c
index e13c940..2a5d848 100644
--- a/super-intel.c
+++ b/super-intel.c
@@ -5716,12 +5716,6 @@ static int add_to_super_imsm(struct supertype *st, mdu_disk_info_t *dk,
if (super->sector_size == 0) {
/* this a first device, so sector_size is not set yet */
super->sector_size = member_sector_size;
- } else if (member_sector_size != super->sector_size) {
- pr_err("Mixing between different sector size is forbidden, aborting...\n");
- if (dd->devname)
- free(dd->devname);
- free(dd);
- return 1;
}
/* clear migr_rec when adding disk to container */

26
SOURCES/bitmap-Remove-use-of-md-get-version1.patch

@ -0,0 +1,26 @@ @@ -0,0 +1,26 @@
From 5d89b18da805cb9ce2b0f726cd534bcbf4dce8c6 Mon Sep 17 00:00:00 2001
From: Jes Sorensen <Jes.Sorensen@gmail.com>
Date: Wed, 5 Apr 2017 15:38:48 -0400
Subject: [RHEL7.5 PATCH 061/169] bitmap: Remove use of md_get_version()

Signed-off-by: Jes Sorensen <Jes.Sorensen@gmail.com>
---
bitmap.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/bitmap.c b/bitmap.c
index ccedfd3..16a6b73 100644
--- a/bitmap.c
+++ b/bitmap.c
@@ -260,7 +260,7 @@ int ExamineBitmap(char *filename, int brief, struct supertype *st)
if (!info)
return rv;
sb = &info->sb;
- if (sb->magic != BITMAP_MAGIC && md_get_version(fd) > 0) {
+ if (sb->magic != BITMAP_MAGIC) {
pr_err("This is an md array. To view a bitmap you need to examine\n");
pr_err("a member device, not the array.\n");
pr_err("Reporting bitmap that would be used if this array were used\n");
--
2.7.4

21
SOURCES/change-back-0644-permission-for-Grow.c.patch

@ -0,0 +1,21 @@ @@ -0,0 +1,21 @@
From 99148c19bd9149bb938309ffb6b4dcde20b67934 Mon Sep 17 00:00:00 2001
From: Zhilong Liu <zlliu@suse.com>
Date: Tue, 2 May 2017 17:27:13 +0800
Subject: [RHEL7.5 PATCH 105/169] change back 0644 permission for Grow.c

Fixes commit:
26714713cd2b ("mdadm: Change timestamps to unsigned data type.")

Signed-off-by: Zhilong Liu <zlliu@suse.com>
Signed-off-by: Jes Sorensen <jsorensen@fb.com>
---
Grow.c | 0
1 file changed, 0 insertions(+), 0 deletions(-)
mode change 100755 => 100644 Grow.c

diff --git a/Grow.c b/Grow.c
old mode 100755
new mode 100644
--
2.7.4

65
SOURCES/container_members_max-degradation-Switch-to-using-sy.patch

@ -0,0 +1,65 @@ @@ -0,0 +1,65 @@
From 74d293a2535ef8726a9d43577dad4a908f471a0e Mon Sep 17 00:00:00 2001
From: Jes Sorensen <jsorensen@fb.com>
Date: Fri, 5 May 2017 12:06:57 -0400
Subject: [RHEL7.5 PATCH 114/169] container_members_max_degradation: Switch
to using syfs for disk info

With sysfs now providing the necessary active_disks info, switch to
sysfs and eliminate one more use of md_get_array_info(). We can do
this unconditionally since we wouldn't get here witout sysfs being
available.

Signed-off-by: Jes Sorensen <jsorensen@fb.com>
---
Incremental.c | 28 ++++++++++++++--------------
1 file changed, 14 insertions(+), 14 deletions(-)

diff --git a/Incremental.c b/Incremental.c
index c00a43d..b73eabd 100644
--- a/Incremental.c
+++ b/Incremental.c
@@ -802,27 +802,27 @@ static int count_active(struct supertype *st, struct mdinfo *sra,
}
/* test if container has degraded member(s) */
-static int container_members_max_degradation(struct map_ent *map, struct map_ent *me)
+static int
+container_members_max_degradation(struct map_ent *map, struct map_ent *me)
{
- mdu_array_info_t array;
- int afd;
- int max_degraded = 0;
+ struct mdinfo *sra;
+ int degraded, max_degraded = 0;
for(; map; map = map->next) {
if (!metadata_container_matches(map->metadata, me->devnm))
continue;
- afd = open_dev(map->devnm);
- if (afd < 0)
- continue;
/* most accurate information regarding array degradation */
- if (md_get_array_info(afd, &array) >= 0) {
- int degraded = array.raid_disks - array.active_disks -
- array.spare_disks;
- if (degraded > max_degraded)
- max_degraded = degraded;
- }
- close(afd);
+ sra = sysfs_read(-1, map->devnm,
+ GET_DISKS | GET_DEVS | GET_STATE);
+ if (!sra)
+ continue;
+ degraded = sra->array.raid_disks - sra->array.active_disks -
+ sra->array.spare_disks;
+ if (degraded > max_degraded)
+ max_degraded = degraded;
+ sysfs_free(sra);
}
+
return max_degraded;
}
--
2.7.4

322
SOURCES/detail-show-consistency-policy.patch

@ -0,0 +1,322 @@ @@ -0,0 +1,322 @@
commit 65884368cd42d79b567f12d3e84adc7009e12d72
Author: Artur Paszkiewicz <artur.paszkiewicz@intel.com>
Date: Wed Mar 29 11:54:16 2017 +0200

Detail: show consistency policy
Show the currently enabled consistency policy in the output from
--detail. Add 3 spaces to all existing items in Detail output to align
with "Consistency Policy : ".
Signed-off-by: Artur Paszkiewicz <artur.paszkiewicz@intel.com>
Signed-off-by: Jes Sorensen <Jes.Sorensen@gmail.com>

diff --git a/Detail.c b/Detail.c
index 3d92855..136875b 100644
--- a/Detail.c
+++ b/Detail.c
@@ -402,24 +402,25 @@ int Detail(char *dev, struct context *c)
printf("%s:\n", dev);
if (container)
- printf(" Container : %s, member %s\n", container, member);
+ printf(" Container : %s, member %s\n", container,
+ member);
else {
if (sra && sra->array.major_version < 0)
- printf(" Version : %s\n", sra->text_version);
+ printf(" Version : %s\n", sra->text_version);
else
- printf(" Version : %d.%d\n",
+ printf(" Version : %d.%d\n",
array.major_version, array.minor_version);
}
atime = array.ctime;
if (atime)
- printf(" Creation Time : %.24s\n", ctime(&atime));
+ printf(" Creation Time : %.24s\n", ctime(&atime));
if (array.raid_disks == 0 && external)
str = "container";
if (str)
- printf(" Raid Level : %s\n", str);
+ printf(" Raid Level : %s\n", str);
if (larray_size)
- printf(" Array Size : %llu%s\n", (larray_size>>10),
+ printf(" Array Size : %llu%s\n", (larray_size>>10),
human_size(larray_size));
if (array.level >= 1) {
if (sra)
@@ -428,38 +429,38 @@ int Detail(char *dev, struct context *c)
(larray_size >= 0xFFFFFFFFULL|| array.size == 0)) {
unsigned long long dsize = get_component_size(fd);
if (dsize > 0)
- printf(" Used Dev Size : %llu%s\n",
+ printf(" Used Dev Size : %llu%s\n",
dsize/2,
human_size((long long)dsize<<9));
else
- printf(" Used Dev Size : unknown\n");
+ printf(" Used Dev Size : unknown\n");
} else
- printf(" Used Dev Size : %lu%s\n",
+ printf(" Used Dev Size : %lu%s\n",
(unsigned long)array.size,
human_size((unsigned long long)array.size<<10));
}
if (array.raid_disks)
- printf(" Raid Devices : %d\n", array.raid_disks);
- printf(" Total Devices : %d\n", array.nr_disks);
+ printf(" Raid Devices : %d\n", array.raid_disks);
+ printf(" Total Devices : %d\n", array.nr_disks);
if (!container &&
((sra == NULL && array.major_version == 0) ||
(sra && sra->array.major_version == 0)))
- printf("Preferred Minor : %d\n", array.md_minor);
+ printf(" Preferred Minor : %d\n", array.md_minor);
if (sra == NULL || sra->array.major_version >= 0)
- printf(" Persistence : Superblock is %spersistent\n",
+ printf(" Persistence : Superblock is %spersistent\n",
array.not_persistent?"not ":"");
printf("\n");
/* Only try GET_BITMAP_FILE for 0.90.01 and later */
if (vers >= 9001 &&
ioctl(fd, GET_BITMAP_FILE, &bmf) == 0 &&
bmf.pathname[0]) {
- printf(" Intent Bitmap : %s\n", bmf.pathname);
+ printf(" Intent Bitmap : %s\n", bmf.pathname);
printf("\n");
} else if (array.state & (1<<MD_SB_BITMAP_PRESENT))
- printf(" Intent Bitmap : Internal\n\n");
+ printf(" Intent Bitmap : Internal\n\n");
atime = array.utime;
if (atime)
- printf(" Update Time : %.24s\n", ctime(&atime));
+ printf(" Update Time : %.24s\n", ctime(&atime));
if (array.raid_disks) {
static char *sync_action[] = {
", recovering", ", resyncing",
@@ -473,7 +474,7 @@ int Detail(char *dev, struct context *c)
else
st = ", degraded";
- printf(" State : %s%s%s%s%s%s \n",
+ printf(" State : %s%s%s%s%s%s \n",
(array.state&(1<<MD_SB_CLEAN))?"clean":"active", st,
(!e || (e->percent < 0 && e->percent != RESYNC_PENDING &&
e->percent != RESYNC_DELAYED)) ? "" : sync_action[e->resync],
@@ -481,27 +482,27 @@ int Detail(char *dev, struct context *c)
(e && e->percent == RESYNC_DELAYED) ? " (DELAYED)": "",
(e && e->percent == RESYNC_PENDING) ? " (PENDING)": "");
} else if (inactive) {
- printf(" State : inactive\n");
+ printf(" State : inactive\n");
}
if (array.raid_disks)
- printf(" Active Devices : %d\n", array.active_disks);
+ printf(" Active Devices : %d\n", array.active_disks);
if (array.working_disks > 0)
- printf("Working Devices : %d\n", array.working_disks);
+ printf(" Working Devices : %d\n", array.working_disks);
if (array.raid_disks) {
- printf(" Failed Devices : %d\n", array.failed_disks);
- printf(" Spare Devices : %d\n", array.spare_disks);
+ printf(" Failed Devices : %d\n", array.failed_disks);
+ printf(" Spare Devices : %d\n", array.spare_disks);
}
printf("\n");
if (array.level == 5) {
str = map_num(r5layout, array.layout);
- printf(" Layout : %s\n", str?str:"-unknown-");
+ printf(" Layout : %s\n", str?str:"-unknown-");
}
if (array.level == 6) {
str = map_num(r6layout, array.layout);
- printf(" Layout : %s\n", str?str:"-unknown-");
+ printf(" Layout : %s\n", str?str:"-unknown-");
}
if (array.level == 10) {
- printf(" Layout :");
+ printf(" Layout :");
print_r10_layout(array.layout);
printf("\n");
}
@@ -512,20 +513,35 @@ int Detail(char *dev, struct context *c)
case 10:
case 6:
if (array.chunk_size)
- printf(" Chunk Size : %dK\n\n",
+ printf(" Chunk Size : %dK\n\n",
array.chunk_size/1024);
break;
case -1:
- printf(" Rounding : %dK\n\n", array.chunk_size/1024);
+ printf(" Rounding : %dK\n\n",
+ array.chunk_size/1024);
break;
default: break;
}
+ if (array.raid_disks) {
+ struct mdinfo *mdi = sysfs_read(fd, NULL,
+ GET_CONSISTENCY_POLICY);
+ if (mdi) {
+ char *policy = map_num(consistency_policies,
+ mdi->consistency_policy);
+ sysfs_free(mdi);
+ if (policy)
+ printf("Consistency Policy : %s\n\n",
+ policy);
+ }
+ }
+
if (e && e->percent >= 0) {
static char *sync_action[] = {
"Rebuild", "Resync",
"Reshape", "Check"};
- printf(" %7s Status : %d%% complete\n", sync_action[e->resync], e->percent);
+ printf(" %7s Status : %d%% complete\n",
+ sync_action[e->resync], e->percent);
is_rebuilding = 1;
}
free_mdstat(ms);
@@ -533,39 +549,41 @@ int Detail(char *dev, struct context *c)
if ((st && st->sb) && (info && info->reshape_active)) {
#if 0
This is pretty boring
- printf(" Reshape pos'n : %llu%s\n", (unsigned long long) info->reshape_progress<<9,
+ printf(" Reshape pos'n : %llu%s\n",
+ (unsigned long long) info->reshape_progress<<9,
human_size((unsigned long long)info->reshape_progress<<9));
#endif
if (info->delta_disks != 0)
- printf(" Delta Devices : %d, (%d->%d)\n",
+ printf(" Delta Devices : %d, (%d->%d)\n",
info->delta_disks,
array.raid_disks - info->delta_disks,
array.raid_disks);
if (info->new_level != array.level) {
str = map_num(pers, info->new_level);
- printf(" New Level : %s\n", str?str:"-unknown-");
+ printf(" New Level : %s\n", str?str:"-unknown-");
}
if (info->new_level != array.level ||
info->new_layout != array.layout) {
if (info->new_level == 5) {
str = map_num(r5layout, info->new_layout);
- printf(" New Layout : %s\n",
+ printf(" New Layout : %s\n",
str?str:"-unknown-");
}
if (info->new_level == 6) {
str = map_num(r6layout, info->new_layout);
- printf(" New Layout : %s\n",
+ printf(" New Layout : %s\n",
str?str:"-unknown-");
}
if (info->new_level == 10) {
- printf(" New Layout : near=%d, %s=%d\n",
+ printf(" New Layout : near=%d, %s=%d\n",
info->new_layout&255,
(info->new_layout&0x10000)?"offset":"far",
(info->new_layout>>8)&255);
}
}
if (info->new_chunk != array.chunk_size)
- printf(" New Chunksize : %dK\n", info->new_chunk/1024);
+ printf(" New Chunksize : %dK\n",
+ info->new_chunk/1024);
printf("\n");
} else if (e && e->percent >= 0)
printf("\n");
@@ -580,7 +598,7 @@ This is pretty boring
DIR *dir = opendir("/sys/block");
struct dirent *de;
- printf(" Member Arrays :");
+ printf(" Member Arrays :");
while (dir && (de = readdir(dir)) != NULL) {
char path[287];
diff --git a/super-ddf.c b/super-ddf.c
index cdd16a4..c6037c1 100644
--- a/super-ddf.c
+++ b/super-ddf.c
@@ -1742,10 +1742,10 @@ static void detail_super_ddf(struct supertype *st, char *homehost)
struct ddf_super *sb = st->sb;
int cnt = be16_to_cpu(sb->virt->populated_vdes);
- printf(" Container GUID : "); print_guid(sb->anchor.guid, 1);
+ printf(" Container GUID : "); print_guid(sb->anchor.guid, 1);
printf("\n");
- printf(" Seq : %08x\n", be32_to_cpu(sb->active->seq));
- printf(" Virtual Disks : %d\n", cnt);
+ printf(" Seq : %08x\n", be32_to_cpu(sb->active->seq));
+ printf(" Virtual Disks : %d\n", cnt);
printf("\n");
}
#endif
diff --git a/super-intel.c b/super-intel.c
index 5d0f131..2d92c8e 100644
--- a/super-intel.c
+++ b/super-intel.c
@@ -1987,7 +1987,7 @@ static void detail_super_imsm(struct supertype *st, char *homehost)
getinfo_super_imsm(st, &info, NULL);
fname_from_uuid(st, &info, nbuf, ':');
- printf("\n UUID : %s\n", nbuf + 5);
+ printf("\n UUID : %s\n", nbuf + 5);
}
static void brief_detail_super_imsm(struct supertype *st)
diff --git a/super0.c b/super0.c
index 7a555e3..10d9c40 100644
--- a/super0.c
+++ b/super0.c
@@ -353,7 +353,7 @@ err:
static void detail_super0(struct supertype *st, char *homehost)
{
mdp_super_t *sb = st->sb;
- printf(" UUID : ");
+ printf(" UUID : ");
if (sb->minor_version >= 90)
printf("%08x:%08x:%08x:%08x", sb->set_uuid0, sb->set_uuid1,
sb->set_uuid2, sb->set_uuid3);
@@ -367,7 +367,7 @@ static void detail_super0(struct supertype *st, char *homehost)
if (memcmp(&sb->set_uuid2, hash, 8)==0)
printf(" (local to host %s)", homehost);
}
- printf("\n Events : %d.%d\n\n", sb->events_hi, sb->events_lo);
+ printf("\n Events : %d.%d\n\n", sb->events_hi, sb->events_lo);
}
static void brief_detail_super0(struct supertype *st)
diff --git a/super1.c b/super1.c
index 4a0f041..8df17a1 100644
--- a/super1.c
+++ b/super1.c
@@ -780,19 +780,20 @@ static void detail_super1(struct supertype *st, char *homehost)
int i;
int l = homehost ? strlen(homehost) : 0;
- printf(" Name : %.32s", sb->set_name);
+ printf(" Name : %.32s", sb->set_name);
if (l > 0 && l < 32 &&
sb->set_name[l] == ':' &&
strncmp(sb->set_name, homehost, l) == 0)
printf(" (local to host %s)", homehost);
if (bms->nodes > 0 && (__le32_to_cpu(sb->feature_map) & MD_FEATURE_BITMAP_OFFSET))
- printf("\n Cluster Name : %-64s", bms->cluster_name);
- printf("\n UUID : ");
+ printf("\n Cluster Name : %-64s", bms->cluster_name);
+ printf("\n UUID : ");
for (i=0; i<16; i++) {
if ((i&3)==0 && i != 0) printf(":");
printf("%02x", sb->set_uuid[i]);
}
- printf("\n Events : %llu\n\n", (unsigned long long)__le64_to_cpu(sb->events));
+ printf("\n Events : %llu\n\n",
+ (unsigned long long)__le64_to_cpu(sb->events));
}
static void brief_detail_super1(struct supertype *st)

32
SOURCES/disable-journal.patch

@ -0,0 +1,32 @@ @@ -0,0 +1,32 @@
--- a/ReadMe.c~ 2017-12-11 11:15:10.314176222 +0800
+++ b/ReadMe.c 2017-12-11 11:16:42.451297334 +0800
@@ -147,7 +147,9 @@
{"data-offset",1, 0, DataOffset},
{"nodes",1, 0, Nodes}, /* also for --assemble */
{"home-cluster",1, 0, ClusterName},
+#if 0 /*Disable for rhel7.5*/
{"write-journal",1, 0, WriteJournal},
+#endif
{"consistency-policy", 1, 0, 'k'},
/* For assemble */
@@ -163,7 +165,9 @@
/* Management */
{"add", 0, 0, Add},
{"add-spare", 0, 0, AddSpare},
+#if 0 /*Disable for rhel7.5*/
{"add-journal", 0, 0, AddJournal},
+#endif
{"remove", 0, 0, Remove},
{"fail", 0, 0, Fail},
{"set-faulty",0, 0, Fail},
@@ -383,7 +387,9 @@
" --name= -N : Textual name for array - max 32 characters\n"
" --bitmap-chunk= : bitmap chunksize in Kilobytes.\n"
" --delay= -d : bitmap update delay in seconds.\n"
+#if 0 /*Disable for rhel7.5*/
" --write-journal= : Specify journal device for RAID-4/5/6 array\n"
+#endif
" --consistency-policy= : Specify the policy that determines how the array\n"
" -k : maintains consistency in case of unexpected shutdown.\n"
"\n"

31
SOURCES/dont-allow-array-geometry-change-with-ppl-enabled.patch

@ -0,0 +1,31 @@ @@ -0,0 +1,31 @@
commit b208f817ec538e56df7280f0353e6bda532b9432
Author: Tomasz Majchrzak <tomasz.majchrzak@intel.com>
Date: Thu Jun 8 16:05:51 2017 +0200

Grow: don't allow array geometry change with ppl enabled
Don't allow array geometry change (size expand, disk adding) when PPL
consistency policy is enabled. Current PPL implementation doesn't work when
reshape is taking place.
Signed-off-by: Tomasz Majchrzak <tomasz.majchrzak@intel.com>
Signed-off-by: Jes Sorensen <jsorensen@fb.com>

diff --git a/Grow.c b/Grow.c
index 4ecb1d8..f7325cb 100644
--- a/Grow.c
+++ b/Grow.c
@@ -1880,6 +1880,13 @@ int Grow_reshape(char *devname, int fd,
free(subarray);
return 1;
}
+ if (content->consistency_policy ==
+ CONSISTENCY_POLICY_PPL) {
+ pr_err("Operation not supported when ppl consistency policy is enabled\n");
+ sysfs_free(cc);
+ free(subarray);
+ return 1;
+ }
}
sysfs_free(cc);
}

64
SOURCES/dont-allow-disks-with-different-sector-sizein-one.patch

@ -0,0 +1,64 @@ @@ -0,0 +1,64 @@
commit f2cc4f7d829e1b849e78bdf6c38b7bd6e234c600
Author: Alexey Obitotskiy <aleksey.obitotskiy@intel.com>
Date: Tue May 9 12:25:45 2017 +0200

imsm: don't allow disks with different sector size in one array
As there is no support in IMSM for arrays including disks with different
sector sizes, don't allow to create such configuration. Also skip the
disk with unsuitable sector size when looking for spares in the same
container.
Signed-off-by: Alexey Obitotskiy <aleksey.obitotskiy@intel.com>
Signed-off-by: Tomasz Majchrzak <tomasz.majchrzak@intel.com>
Signed-off-by: Jes Sorensen <jsorensen@fb.com>

diff --git a/super-intel.c b/super-intel.c
index cfb10d5..e88fe82 100644
--- a/super-intel.c
+++ b/super-intel.c
@@ -5468,6 +5468,22 @@ static int init_super_imsm(struct supertype *st, mdu_array_info_t *info,
return 1;
}
+static int drive_validate_sector_size(struct intel_super *super, struct dl *dl)
+{
+ unsigned int member_sector_size;
+
+ if (dl->fd < 0) {
+ pr_err("Invalid file descriptor for %s\n", dl->devname);
+ return 0;
+ }
+
+ if (!get_dev_sector_size(dl->fd, dl->devname, &member_sector_size))
+ return 0;
+ if (member_sector_size != super->sector_size)
+ return 0;
+ return 1;
+}
+
static int add_to_super_imsm_volume(struct supertype *st, mdu_disk_info_t *dk,
int fd, char *devname)
{
@@ -5507,6 +5523,11 @@ static int add_to_super_imsm_volume(struct supertype *st, mdu_disk_info_t *dk,
return 1;
}
+ if (!drive_validate_sector_size(super, dl)) {
+ pr_err("Combining drives of different sector size in one volume is not allowed\n");
+ return 1;
+ }
+
/* add a pristine spare to the metadata */
if (dl->index < 0) {
dl->index = super->anchor->num_disks;
@@ -8440,6 +8461,9 @@ static struct dl *imsm_add_spare(struct intel_super *super, int slot,
if (dl->index == -1 && !activate_new)
continue;
+ if (!drive_validate_sector_size(super, dl))
+ continue;
+
/* Does this unused device have the requisite free space?
* It needs to be able to cover all member volumes
*/

42
SOURCES/dont-allow-to-enable-PPL-reshape-in-progress.patch

@ -0,0 +1,42 @@ @@ -0,0 +1,42 @@
commit 922a58292fafa4efcfcd44fbc46b0665681c955a
Author: Tomasz Majchrzak <tomasz.majchrzak@intel.com>
Date: Fri Jun 9 16:20:19 2017 +0200

Grow: don't allow to enable PPL when reshape is in progress
Don't allow to enable PPL consistency policy when reshape is in progress.
Current PPL implementation doesn't work when reshape is taking place.
Signed-off-by: Tomasz Majchrzak <tomasz.majchrzak@intel.com>
Signed-off-by: Jes Sorensen <jsorensen@fb.com>

diff --git a/Grow.c b/Grow.c
index f7325cb..b1cb306 100644
--- a/Grow.c
+++ b/Grow.c
@@ -530,6 +530,7 @@ int Grow_consistency_policy(char *devname, int fd, struct context *c, struct sha
char *subarray = NULL;
int ret = 0;
char container_dev[PATH_MAX];
+ char buf[20];
if (s->consistency_policy != CONSISTENCY_POLICY_RESYNC &&
s->consistency_policy != CONSISTENCY_POLICY_PPL) {
@@ -577,6 +578,17 @@ int Grow_consistency_policy(char *devname, int fd, struct context *c, struct sha
goto free_info;
}
+ if (s->consistency_policy == CONSISTENCY_POLICY_PPL) {
+ if (sysfs_get_str(sra, NULL, "sync_action", buf, 20) <= 0) {
+ ret = 1;
+ goto free_info;
+ } else if (strcmp(buf, "reshape\n") == 0) {
+ pr_err("PPL cannot be enabled when reshape is in progress\n");
+ ret = 1;
+ goto free_info;
+ }
+ }
+
if (subarray) {
char *update;

146
SOURCES/examine-tidy-up-some-code.patch

@ -0,0 +1,146 @@ @@ -0,0 +1,146 @@
From 36352fc95778677f0319f677ea079c49f7bbe9d0 Mon Sep 17 00:00:00 2001
From: NeilBrown <neilb@suse.com>
Date: Fri, 3 Mar 2017 10:57:00 +1100
Subject: [RHEL7.5 PATCH 006/169] examine: tidy up some code.

Michael Shigorin reports that the 'lcc' compiler isn't able
to deduce that 'st' must be initialized in

if (c->SparcAdjust)
st->ss->update_super(st, NULL, "sparc2.2",

just because the only times it isn't initialised, 'err' is set non-zero.

This results in a 'possibly uninitialised' warning.
While there is no bug in the code, this does suggest that maybe
the code could be made more obviously correct.

So this patch:
1/ moves the "err" variable inside the for loop, so an error in
one device doesn't stop the other devices from being processed
2/ calls 'continue' early if the device cannot be opened, so that
a level of indent can be removed, and so that it is clear that
'st' is always initialised before being used
3/ frees 'st' if an error occured in load_super or load_container.

Reported-by: Michael Shigorin <mike@altlinux.org>
Signed-off-by: NeilBrown <neilb@suse.com>
Signed-off-by: Jes Sorensen <Jes.Sorensen@gmail.com>
---
Examine.c | 75 +++++++++++++++++++++++++++++++++------------------------------
1 file changed, 39 insertions(+), 36 deletions(-)

diff --git a/Examine.c b/Examine.c
index 953b8ee..7013480 100644
--- a/Examine.c
+++ b/Examine.c
@@ -53,7 +53,6 @@ int Examine(struct mddev_dev *devlist,
*/
int fd;
int rv = 0;
- int err = 0;
struct array {
struct supertype *st;
@@ -66,6 +65,8 @@ int Examine(struct mddev_dev *devlist,
for (; devlist ; devlist = devlist->next) {
struct supertype *st;
int have_container = 0;
+ int err = 0;
+ int container = 0;
fd = dev_open(devlist->devname, O_RDONLY);
if (fd < 0) {
@@ -74,44 +75,46 @@ int Examine(struct mddev_dev *devlist,
devlist->devname, strerror(errno));
rv = 1;
}
- err = 1;
+ continue;
}
- else {
- int container = 0;
- if (forcest)
- st = dup_super(forcest);
- else if (must_be_container(fd)) {
- /* might be a container */
- st = super_by_fd(fd, NULL);
- container = 1;
- } else
- st = guess_super(fd);
- if (st) {
- err = 1;
- st->ignore_hw_compat = 1;
- if (!container)
- err = st->ss->load_super(st, fd,
- (c->brief||c->scan) ? NULL
- :devlist->devname);
- if (err && st->ss->load_container) {
- err = st->ss->load_container(st, fd,
- (c->brief||c->scan) ? NULL
- :devlist->devname);
- if (!err)
- have_container = 1;
- }
- st->ignore_hw_compat = 0;
- } else {
- if (!c->brief) {
- pr_err("No md superblock detected on %s.\n", devlist->devname);
- rv = 1;
- }
- err = 1;
+
+ if (forcest)
+ st = dup_super(forcest);
+ else if (must_be_container(fd)) {
+ /* might be a container */
+ st = super_by_fd(fd, NULL);
+ container = 1;
+ } else
+ st = guess_super(fd);
+ if (st) {
+ err = 1;
+ st->ignore_hw_compat = 1;
+ if (!container)
+ err = st->ss->load_super(st, fd,
+ (c->brief||c->scan) ? NULL
+ :devlist->devname);
+ if (err && st->ss->load_container) {
+ err = st->ss->load_container(st, fd,
+ (c->brief||c->scan) ? NULL
+ :devlist->devname);
+ if (!err)
+ have_container = 1;
}
- close(fd);
+ st->ignore_hw_compat = 0;
+ } else {
+ if (!c->brief) {
+ pr_err("No md superblock detected on %s.\n", devlist->devname);
+ rv = 1;
+ }
+ err = 1;
}
- if (err)
+ close(fd);
+
+ if (err) {
+ if (st)
+ st->ss->free_super(st);
continue;
+ }
if (c->SparcAdjust)
st->ss->update_super(st, NULL, "sparc2.2",
@@ -121,7 +124,7 @@ int Examine(struct mddev_dev *devlist,
if (c->brief && st->ss->brief_examine_super == NULL) {
if (!c->scan)
pr_err("No brief listing for %s on %s\n",
- st->ss->name, devlist->devname);
+ st->ss->name, devlist->devname);
} else if (c->brief) {
struct array *ap;
char *d;
--
2.7.4

638
SOURCES/generic-support-for-consistency-policy-and-PPL.patch

@ -0,0 +1,638 @@ @@ -0,0 +1,638 @@
commit 5308f11727b889965efe5ac0e854d197c2b51f6d
Author: Artur Paszkiewicz <artur.paszkiewicz@intel.com>
Date: Wed Mar 29 11:54:15 2017 +0200

Generic support for --consistency-policy and PPL
Add a new parameter to mdadm: --consistency-policy=. It determines how
the array maintains consistency in case of unexpected shutdown. This
maps to the md sysfs attribute 'consistency_policy'. It can be used to
create a raid5 array using PPL. Add the necessary plumbing to pass this
option to metadata handlers. The write journal and bitmap
functionalities are treated as different policies, which are implicitly
selected when using --write-journal or --bitmap options.
Signed-off-by: Artur Paszkiewicz <artur.paszkiewicz@intel.com>
Signed-off-by: Jes Sorensen <Jes.Sorensen@gmail.com>

diff --git a/Create.c b/Create.c
index 2721884..4080bf6 100644
--- a/Create.c
+++ b/Create.c
@@ -259,7 +259,8 @@ int Create(struct supertype *st, char *mddev,
if (st && ! st->ss->validate_geometry(st, s->level, s->layout, s->raiddisks,
&s->chunk, s->size*2,
data_offset, NULL,
- &newsize, c->verbose>=0))
+ &newsize, s->consistency_policy,
+ c->verbose>=0))
return 1;
if (s->chunk && s->chunk != UnSet) {
@@ -358,7 +359,8 @@ int Create(struct supertype *st, char *mddev,
st, s->level, s->layout, s->raiddisks,
&s->chunk, s->size*2,
dv->data_offset, dname,
- &freesize, c->verbose > 0)) {
+ &freesize, s->consistency_policy,
+ c->verbose > 0)) {
case -1: /* Not valid, message printed, and not
* worth checking any further */
exit(2);
@@ -395,6 +397,7 @@ int Create(struct supertype *st, char *mddev,
&s->chunk, s->size*2,
dv->data_offset,
dname, &freesize,
+ s->consistency_policy,
c->verbose >= 0)) {
pr_err("%s is not suitable for this array.\n",
@@ -501,7 +504,8 @@ int Create(struct supertype *st, char *mddev,
s->raiddisks,
&s->chunk, minsize*2,
data_offset,
- NULL, NULL, 0)) {
+ NULL, NULL,
+ s->consistency_policy, 0)) {
pr_err("devices too large for RAID level %d\n", s->level);
return 1;
}
@@ -528,6 +532,12 @@ int Create(struct supertype *st, char *mddev,
if (s->bitmap_file && strcmp(s->bitmap_file, "none") == 0)
s->bitmap_file = NULL;
+ if (s->consistency_policy == CONSISTENCY_POLICY_PPL &&
+ !st->ss->write_init_ppl) {
+ pr_err("%s metadata does not support PPL\n", st->ss->name);
+ return 1;
+ }
+
if (!have_container && s->level > 0 && ((maxsize-s->size)*100 > maxsize)) {
if (c->runstop != 1 || c->verbose >= 0)
pr_err("largest drive (%s) exceeds size (%lluK) by more than 1%%\n",
@@ -720,7 +730,7 @@ int Create(struct supertype *st, char *mddev,
name += 2;
}
}
- if (!st->ss->init_super(st, &info.array, s->size, name, c->homehost, uuid,
+ if (!st->ss->init_super(st, &info.array, s, name, c->homehost, uuid,
data_offset))
goto abort_locked;
diff --git a/Kill.c b/Kill.c
index f2fdb85..ff52561 100644
--- a/Kill.c
+++ b/Kill.c
@@ -63,7 +63,7 @@ int Kill(char *dev, struct supertype *st, int force, int verbose, int noexcl)
rv = st->ss->load_super(st, fd, dev);
if (rv == 0 || (force && rv >= 2)) {
st->ss->free_super(st);
- st->ss->init_super(st, NULL, 0, "", NULL, NULL,
+ st->ss->init_super(st, NULL, NULL, "", NULL, NULL,
INVALID_SECTORS);
if (st->ss->store_super(st, fd)) {
if (verbose >= 0)
diff --git a/ReadMe.c b/ReadMe.c
index 50d3807..fc04c2c 100644
--- a/ReadMe.c
+++ b/ReadMe.c
@@ -78,11 +78,11 @@ char Version[] = "mdadm - v" VERSION " - " VERS_DATE "\n";
* found, it is started.
*/
-char short_options[]="-ABCDEFGIQhVXYWZ:vqbc:i:l:p:m:n:x:u:c:d:z:U:N:sarfRSow1tye:";
+char short_options[]="-ABCDEFGIQhVXYWZ:vqbc:i:l:p:m:n:x:u:c:d:z:U:N:sarfRSow1tye:k:";
char short_bitmap_options[]=
- "-ABCDEFGIQhVXYWZ:vqb:c:i:l:p:m:n:x:u:c:d:z:U:N:sarfRSow1tye:";
+ "-ABCDEFGIQhVXYWZ:vqb:c:i:l:p:m:n:x:u:c:d:z:U:N:sarfRSow1tye:k:";
char short_bitmap_auto_options[]=
- "-ABCDEFGIQhVXYWZ:vqb:c:i:l:p:m:n:x:u:c:d:z:U:N:sa:rfRSow1tye:";
+ "-ABCDEFGIQhVXYWZ:vqb:c:i:l:p:m:n:x:u:c:d:z:U:N:sa:rfRSow1tye:k:";
struct option long_options[] = {
{"manage", 0, 0, ManageOpt},
@@ -148,6 +148,7 @@ struct option long_options[] = {
{"nodes",1, 0, Nodes}, /* also for --assemble */
{"home-cluster",1, 0, ClusterName},
{"write-journal",1, 0, WriteJournal},
+ {"consistency-policy", 1, 0, 'k'},
/* For assemble */
{"uuid", 1, 0, 'u'},
@@ -362,27 +363,29 @@ char Help_create[] =
" other levels.\n"
"\n"
" Options that are valid with --create (-C) are:\n"
-" --bitmap= : Create a bitmap for the array with the given filename\n"
-" : or an internal bitmap is 'internal' is given\n"
-" --chunk= -c : chunk size in kibibytes\n"
-" --rounding= : rounding factor for linear array (==chunk size)\n"
-" --level= -l : raid level: 0,1,4,5,6,10,linear,multipath and synonyms\n"
-" --parity= -p : raid5/6 parity algorithm: {left,right}-{,a}symmetric\n"
-" --layout= : same as --parity, for RAID10: [fno]NN \n"
-" --raid-devices= -n : number of active devices in array\n"
-" --spare-devices= -x: number of spare (eXtra) devices in initial array\n"
-" --size= -z : Size (in K) of each drive in RAID1/4/5/6/10 - optional\n"
-" --data-offset= : Space to leave between start of device and start\n"
-" : of array data.\n"
-" --force -f : Honour devices as listed on command line. Don't\n"
-" : insert a missing drive for RAID5.\n"
-" --run -R : insist of running the array even if not all\n"
-" : devices are present or some look odd.\n"
-" --readonly -o : start the array readonly - not supported yet.\n"
-" --name= -N : Textual name for array - max 32 characters\n"
-" --bitmap-chunk= : bitmap chunksize in Kilobytes.\n"
-" --delay= -d : bitmap update delay in seconds.\n"
-" --write-journal= : Specify journal device for RAID-4/5/6 array\n"
+" --bitmap= -b : Create a bitmap for the array with the given filename\n"
+" : or an internal bitmap if 'internal' is given\n"
+" --chunk= -c : chunk size in kibibytes\n"
+" --rounding= : rounding factor for linear array (==chunk size)\n"
+" --level= -l : raid level: 0,1,4,5,6,10,linear,multipath and synonyms\n"
+" --parity= -p : raid5/6 parity algorithm: {left,right}-{,a}symmetric\n"
+" --layout= : same as --parity, for RAID10: [fno]NN \n"
+" --raid-devices= -n : number of active devices in array\n"
+" --spare-devices= -x : number of spare (eXtra) devices in initial array\n"
+" --size= -z : Size (in K) of each drive in RAID1/4/5/6/10 - optional\n"
+" --data-offset= : Space to leave between start of device and start\n"
+" : of array data.\n"
+" --force -f : Honour devices as listed on command line. Don't\n"
+" : insert a missing drive for RAID5.\n"
+" --run -R : insist of running the array even if not all\n"
+" : devices are present or some look odd.\n"
+" --readonly -o : start the array readonly - not supported yet.\n"
+" --name= -N : Textual name for array - max 32 characters\n"
+" --bitmap-chunk= : bitmap chunksize in Kilobytes.\n"
+" --delay= -d : bitmap update delay in seconds.\n"
+" --write-journal= : Specify journal device for RAID-4/5/6 array\n"
+" --consistency-policy= : Specify the policy that determines how the array\n"
+" -k : maintains consistency in case of unexpected shutdown.\n"
"\n"
;
diff --git a/maps.c b/maps.c
index 64f1df2..d9ee7de 100644
--- a/maps.c
+++ b/maps.c
@@ -129,6 +129,16 @@ mapping_t faultylayout[] = {
{ NULL, 0}
};
+mapping_t consistency_policies[] = {
+ { "unknown", CONSISTENCY_POLICY_UNKNOWN},
+ { "none", CONSISTENCY_POLICY_NONE},
+ { "resync", CONSISTENCY_POLICY_RESYNC},
+ { "bitmap", CONSISTENCY_POLICY_BITMAP},
+ { "journal", CONSISTENCY_POLICY_JOURNAL},
+ { "ppl", CONSISTENCY_POLICY_PPL},
+ { NULL, 0}
+};
+
char *map_num(mapping_t *map, int num)
{
while (map->name) {
diff --git a/mdadm.8.in b/mdadm.8.in
index df1d460..cad5db5 100644
--- a/mdadm.8.in
+++ b/mdadm.8.in
@@ -724,7 +724,9 @@ When creating an array on devices which are 100G or larger,
.I mdadm
automatically adds an internal bitmap as it will usually be
beneficial. This can be suppressed with
-.B "\-\-bitmap=none".
+.B "\-\-bitmap=none"
+or by selecting a different consistency policy with
+.BR \-\-consistency\-policy .
.TP
.BR \-\-bitmap\-chunk=
@@ -1020,6 +1022,36 @@ should be a SSD with reasonable lifetime.
Auto creation of symlinks in /dev to /dev/md, option --symlinks must
be 'no' or 'yes' and work with --create and --build.
+.TP
+.BR \-k ", " \-\-consistency\-policy=
+Specify how the array maintains consistency in case of unexpected shutdown.
+Only relevant for RAID levels with redundancy.
+Currently supported options are:
+.RS
+
+.TP
+.B resync
+Full resync is performed and all redundancy is regenerated when the array is
+started after unclean shutdown.
+
+.TP
+.B bitmap
+Resync assisted by a write-intent bitmap. Implicitly selected when using
+.BR \-\-bitmap .
+
+.TP
+.B journal
+For RAID levels 4/5/6, journal device is used to log transactions and replay
+after unclean shutdown. Implicitly selected when using
+.BR \-\-write\-journal .
+
+.TP
+.B ppl
+For RAID5 only, Partial Parity Log is used to close the write hole and
+eliminate resync. PPL is stored in the metadata region of RAID member drives,
+no additional journal drive is needed.
+.RE
+
.SH For assemble:
@@ -2153,8 +2185,10 @@ in the array exceed 100G is size, an internal write-intent bitmap
will automatically be added unless some other option is explicitly
requested with the
.B \-\-bitmap
-option. In any case space for a bitmap will be reserved so that one
-can be added layer with
+option or a different consistency policy is selected with the
+.B \-\-consistency\-policy
+option. In any case space for a bitmap will be reserved so that one
+can be added later with
.BR "\-\-grow \-\-bitmap=internal" .
If the metadata type supports it (currently only 1.x metadata), space
diff --git a/mdadm.c b/mdadm.c
index 08ddcab..d4e8286 100644
--- a/mdadm.c
+++ b/mdadm.c
@@ -78,6 +78,7 @@ int main(int argc, char *argv[])
.level = UnSet,
.layout = UnSet,
.bitmap_chunk = UnSet,
+ .consistency_policy = UnSet,
};
char sys_hostname[256];
@@ -1215,6 +1216,16 @@ int main(int argc, char *argv[])
s.journaldisks = 1;
continue;
+ case O(CREATE, 'k'):
+ s.consistency_policy = map_name(consistency_policies,
+ optarg);
+ if (s.consistency_policy == UnSet ||
+ s.consistency_policy < CONSISTENCY_POLICY_RESYNC) {
+ pr_err("Invalid consistency policy: %s\n",
+ optarg);
+ exit(2);
+ }
+ continue;
}
/* We have now processed all the valid options. Anything else is
* an error
@@ -1242,9 +1253,47 @@ int main(int argc, char *argv[])
exit(0);
}
- if (s.journaldisks && (s.level < 4 || s.level > 6)) {
- pr_err("--write-journal is only supported for RAID level 4/5/6.\n");
- exit(2);
+ if (s.journaldisks) {
+ if (s.level < 4 || s.level > 6) {
+ pr_err("--write-journal is only supported for RAID level 4/5/6.\n");
+ exit(2);
+ }
+ if (s.consistency_policy != UnSet &&
+ s.consistency_policy != CONSISTENCY_POLICY_JOURNAL) {
+ pr_err("--write-journal is not supported with consistency policy: %s\n",
+ map_num(consistency_policies, s.consistency_policy));
+ exit(2);
+ }
+ }
+
+ if (mode == CREATE && s.consistency_policy != UnSet) {
+ if (s.level <= 0) {
+ pr_err("--consistency-policy not meaningful with level %s.\n",
+ map_num(pers, s.level));
+ exit(2);
+ } else if (s.consistency_policy == CONSISTENCY_POLICY_JOURNAL &&
+ !s.journaldisks) {
+ pr_err("--write-journal is required for consistency policy: %s\n",
+ map_num(consistency_policies, s.consistency_policy));
+ exit(2);
+ } else if (s.consistency_policy == CONSISTENCY_POLICY_PPL &&
+ s.level != 5) {
+ pr_err("PPL consistency policy is only supported for RAID level 5.\n");
+ exit(2);
+ } else if (s.consistency_policy == CONSISTENCY_POLICY_BITMAP &&
+ (!s.bitmap_file ||
+ strcmp(s.bitmap_file, "none") == 0)) {
+ pr_err("--bitmap is required for consistency policy: %s\n",
+ map_num(consistency_policies, s.consistency_policy));
+ exit(2);
+ } else if (s.bitmap_file &&
+ strcmp(s.bitmap_file, "none") != 0 &&
+ s.consistency_policy != CONSISTENCY_POLICY_BITMAP &&
+ s.consistency_policy != CONSISTENCY_POLICY_JOURNAL) {
+ pr_err("--bitmap is not compatible with consistency policy: %s\n",
+ map_num(consistency_policies, s.consistency_policy));
+ exit(2);
+ }
}
if (!mode && devs_found) {
diff --git a/mdadm.h b/mdadm.h
index cebc0c0..b52d4d3 100644
--- a/mdadm.h
+++ b/mdadm.h
@@ -279,6 +279,15 @@ struct mdinfo {
int journal_device_required;
int journal_clean;
+ enum {
+ CONSISTENCY_POLICY_UNKNOWN,
+ CONSISTENCY_POLICY_NONE,
+ CONSISTENCY_POLICY_RESYNC,
+ CONSISTENCY_POLICY_BITMAP,
+ CONSISTENCY_POLICY_JOURNAL,
+ CONSISTENCY_POLICY_PPL,
+ } consistency_policy;
+
/* During reshape we can sometimes change the data_offset to avoid
* over-writing still-valid data. We need to know if there is space.
* So getinfo_super will fill in space_before and space_after in sectors.
@@ -426,6 +435,7 @@ enum special_options {
ClusterName,
ClusterConfirm,
WriteJournal,
+ ConsistencyPolicy,
};
enum prefix_standard {
@@ -527,6 +537,7 @@ struct shape {
int assume_clean;
int write_behind;
unsigned long long size;
+ int consistency_policy;
};
/* List of device names - wildcards expanded */
@@ -618,6 +629,7 @@ enum sysfs_read_flags {
GET_STATE = (1 << 23),
GET_ERROR = (1 << 24),
GET_ARRAY_STATE = (1 << 25),
+ GET_CONSISTENCY_POLICY = (1 << 26),
};
/* If fd >= 0, get the array it is open on,
@@ -701,7 +713,7 @@ extern int restore_stripes(int *dest, unsigned long long *offsets,
extern char *map_num(mapping_t *map, int num);
extern int map_name(mapping_t *map, char *name);
-extern mapping_t r5layout[], r6layout[], pers[], modes[], faultylayout[];
+extern mapping_t r5layout[], r6layout[], pers[], modes[], faultylayout[], consistency_policies[];
extern char *map_dev_preferred(int major, int minor, int create,
char *prefer);
@@ -863,7 +875,7 @@ extern struct superswitch {
* metadata.
*/
int (*init_super)(struct supertype *st, mdu_array_info_t *info,
- unsigned long long size, char *name,
+ struct shape *s, char *name,
char *homehost, int *uuid,
unsigned long long data_offset);
@@ -961,7 +973,7 @@ extern struct superswitch {
int *chunk, unsigned long long size,
unsigned long long data_offset,
char *subdev, unsigned long long *freesize,
- int verbose);
+ int consistency_policy, int verbose);
/* Return a linked list of 'mdinfo' structures for all arrays
* in the container. For non-containers, it is like
@@ -1059,6 +1071,9 @@ extern struct superswitch {
/* validate container after assemble */
int (*validate_container)(struct mdinfo *info);
+ /* write initial empty PPL on device */
+ int (*write_init_ppl)(struct supertype *st, struct mdinfo *info, int fd);
+
/* records new bad block in metadata */
int (*record_bad_block)(struct active_array *a, int n,
unsigned long long sector, int length);
diff --git a/super-ddf.c b/super-ddf.c
index 1707ad1..cdd16a4 100644
--- a/super-ddf.c
+++ b/super-ddf.c
@@ -2290,7 +2290,7 @@ static unsigned int find_vde_by_guid(const struct ddf_super *ddf,
static int init_super_ddf(struct supertype *st,
mdu_array_info_t *info,
- unsigned long long size, char *name, char *homehost,
+ struct shape *s, char *name, char *homehost,
int *uuid, unsigned long long data_offset)
{
/* This is primarily called by Create when creating a new array.
@@ -2328,7 +2328,7 @@ static int init_super_ddf(struct supertype *st,
struct virtual_disk *vd;
if (st->sb)
- return init_super_ddf_bvd(st, info, size, name, homehost, uuid,
+ return init_super_ddf_bvd(st, info, s->size, name, homehost, uuid,
data_offset);
if (posix_memalign((void**)&ddf, 512, sizeof(*ddf)) != 0) {
@@ -3347,7 +3347,7 @@ static int validate_geometry_ddf(struct supertype *st,
int *chunk, unsigned long long size,
unsigned long long data_offset,
char *dev, unsigned long long *freesize,
- int verbose)
+ int consistency_policy, int verbose)
{
int fd;
struct mdinfo *sra;
diff --git a/super-gpt.c b/super-gpt.c
index 8b080a0..bb38a97 100644
--- a/super-gpt.c
+++ b/super-gpt.c
@@ -205,7 +205,7 @@ static int validate_geometry(struct supertype *st, int level,
int *chunk, unsigned long long size,
unsigned long long data_offset,
char *subdev, unsigned long long *freesize,
- int verbose)
+ int consistency_policy, int verbose)
{
pr_err("gpt metadata cannot be used this way\n");
return 0;
diff --git a/super-intel.c b/super-intel.c
index e1618f1..5d0f131 100644
--- a/super-intel.c
+++ b/super-intel.c
@@ -5155,7 +5155,7 @@ static int check_name(struct intel_super *super, char *name, int quiet)
}
static int init_super_imsm_volume(struct supertype *st, mdu_array_info_t *info,
- unsigned long long size, char *name,
+ struct shape *s, char *name,
char *homehost, int *uuid,
long long data_offset)
{
@@ -5250,7 +5250,7 @@ static int init_super_imsm_volume(struct supertype *st, mdu_array_info_t *info,
strncpy((char *) dev->volume, name, MAX_RAID_SERIAL_LEN);
array_blocks = calc_array_size(info->level, info->raid_disks,
info->layout, info->chunk_size,
- size * 2);
+ s->size * 2);
/* round array size down to closest MB */
array_blocks = (array_blocks >> SECT_PER_MB_SHIFT) << SECT_PER_MB_SHIFT;
@@ -5264,7 +5264,7 @@ static int init_super_imsm_volume(struct supertype *st, mdu_array_info_t *info,
vol->curr_migr_unit = 0;
map = get_imsm_map(dev, MAP_0);
set_pba_of_lba0(map, super->create_offset);
- set_blocks_per_member(map, info_to_blocks_per_member(info, size));
+ set_blocks_per_member(map, info_to_blocks_per_member(info, s->size));
map->blocks_per_strip = __cpu_to_le16(info_to_blocks_per_strip(info));
map->failed_disk_num = ~0;
if (info->level > 0)
@@ -5292,7 +5292,7 @@ static int init_super_imsm_volume(struct supertype *st, mdu_array_info_t *info,
map->num_domains = 1;
/* info->size is only int so use the 'size' parameter instead */
- num_data_stripes = (size * 2) / info_to_blocks_per_strip(info);
+ num_data_stripes = (s->size * 2) / info_to_blocks_per_strip(info);
num_data_stripes /= map->num_domains;
set_num_data_stripes(map, num_data_stripes);
@@ -5314,7 +5314,7 @@ static int init_super_imsm_volume(struct supertype *st, mdu_array_info_t *info,
}
static int init_super_imsm(struct supertype *st, mdu_array_info_t *info,
- unsigned long long size, char *name,
+ struct shape *s, char *name,
char *homehost, int *uuid,
unsigned long long data_offset)
{
@@ -5337,7 +5337,7 @@ static int init_super_imsm(struct supertype *st, mdu_array_info_t *info,
}
if (st->sb)
- return init_super_imsm_volume(st, info, size, name, homehost, uuid,
+ return init_super_imsm_volume(st, info, s, name, homehost, uuid,
data_offset);
if (info)
@@ -6914,7 +6914,7 @@ static int validate_geometry_imsm(struct supertype *st, int level, int layout,
int raiddisks, int *chunk, unsigned long long size,
unsigned long long data_offset,
char *dev, unsigned long long *freesize,
- int verbose)
+ int consistency_policy, int verbose)
{
int fd, cfd;
struct mdinfo *sra;
@@ -10953,7 +10953,7 @@ enum imsm_reshape_type imsm_analyze_change(struct supertype *st,
geo->raid_disks + devNumChange,
&chunk,
geo->size, INVALID_SECTORS,
- 0, 0, 1))
+ 0, 0, info.consistency_policy, 1))
change = -1;
if (check_devs) {
diff --git a/super-mbr.c b/super-mbr.c
index f5e4cea..1bbe57a 100644
--- a/super-mbr.c
+++ b/super-mbr.c
@@ -193,7 +193,7 @@ static int validate_geometry(struct supertype *st, int level,
int *chunk, unsigned long long size,
unsigned long long data_offset,
char *subdev, unsigned long long *freesize,
- int verbose)
+ int consistency_policy, int verbose)
{
pr_err("mbr metadata cannot be used this way\n");
return 0;
diff --git a/super0.c b/super0.c
index f5b4507..7a555e3 100644
--- a/super0.c
+++ b/super0.c
@@ -725,7 +725,7 @@ static int update_super0(struct supertype *st, struct mdinfo *info,
* We use the first 8 bytes (64bits) of the sha1 of the host name
*/
static int init_super0(struct supertype *st, mdu_array_info_t *info,
- unsigned long long size, char *ignored_name,
+ struct shape *s, char *ignored_name,
char *homehost, int *uuid,
unsigned long long data_offset)
{
@@ -764,8 +764,8 @@ static int init_super0(struct supertype *st, mdu_array_info_t *info,
sb->gvalid_words = 0; /* ignored */
sb->ctime = time(0);
sb->level = info->level;
- sb->size = size;
- if (size != (unsigned long long)sb->size)
+ sb->size = s->size;
+ if (s->size != (unsigned long long)sb->size)
return 0;
sb->nr_disks = info->nr_disks;
sb->raid_disks = info->raid_disks;
@@ -1267,7 +1267,7 @@ static int validate_geometry0(struct supertype *st, int level,
int *chunk, unsigned long long size,
unsigned long long data_offset,
char *subdev, unsigned long long *freesize,
- int verbose)
+ int consistency_policy, int verbose)
{
unsigned long long ldsize;
int fd;
diff --git a/super1.c b/super1.c
index f3520ac..4a0f041 100644
--- a/super1.c
+++ b/super1.c
@@ -1397,7 +1397,7 @@ static int update_super1(struct supertype *st, struct mdinfo *info,
}
static int init_super1(struct supertype *st, mdu_array_info_t *info,
- unsigned long long size, char *name, char *homehost,
+ struct shape *s, char *name, char *homehost,
int *uuid, unsigned long long data_offset)
{
struct mdp_superblock_1 *sb;
@@ -1450,7 +1450,7 @@ static int init_super1(struct supertype *st, mdu_array_info_t *info,
sb->ctime = __cpu_to_le64((unsigned long long)time(0));
sb->level = __cpu_to_le32(info->level);
sb->layout = __cpu_to_le32(info->layout);
- sb->size = __cpu_to_le64(size*2ULL);
+ sb->size = __cpu_to_le64(s->size*2ULL);
sb->chunksize = __cpu_to_le32(info->chunk_size>>9);
sb->raid_disks = __cpu_to_le32(info->raid_disks);
@@ -2487,7 +2487,7 @@ static int validate_geometry1(struct supertype *st, int level,
int *chunk, unsigned long long size,
unsigned long long data_offset,
char *subdev, unsigned long long *freesize,
- int verbose)
+ int consistency_policy, int verbose)
{
unsigned long long ldsize, devsize;
int bmspace;
diff --git a/sysfs.c b/sysfs.c
index b0657a0..53589a7 100644
--- a/sysfs.c
+++ b/sysfs.c
@@ -242,6 +242,17 @@ struct mdinfo *sysfs_read(int fd, char *devnm, unsigned long options)
} else
sra->sysfs_array_state[0] = 0;
+ if (options & GET_CONSISTENCY_POLICY) {
+ strcpy(base, "consistency_policy");
+ if (load_sys(fname, buf, sizeof(buf))) {
+ sra->consistency_policy = CONSISTENCY_POLICY_UNKNOWN;
+ } else {
+ sra->consistency_policy = map_name(consistency_policies, buf);
+ if (sra->consistency_policy == UnSet)
+ sra->consistency_policy = CONSISTENCY_POLICY_UNKNOWN;
+ }
+ }
+
if (! (options & GET_DEVS))
return sra;

32
SOURCES/imsm-Set-disk-slot-number.patch

@ -0,0 +1,32 @@ @@ -0,0 +1,32 @@
commit 20dc76d15b40c17b4ccdc3d6283af8ecb513707f
Author: Mariusz Tkaczyk <mariusz.tkaczyk@intel.com>
Date: Tue Oct 3 14:49:49 2017 +0200

imsm: Set disk slot number
If first disk of IMSM RAID1 is failed but still present in the system,
the array is not auto-assembled. Auto-assemble uses raid disk slot from
metadata to index disks. As it's not set, the valid disk is seen as a
replacement disk and its metadata is ignored. The problem is not
observed for other RAID levels as they have more than 2 disks -
replacement disks are only stored under uneven indexes so third disk
metadata is used in such scenario.
Signed-off-by: Mariusz Tkaczyk <mariusz.tkaczyk@intel.com>
Reviewed-by: Tomasz Majchrzak <tomasz.majchrzak@intel.com>
Signed-off-by: Jes Sorensen <jsorensen@fb.com>

diff --git a/super-intel.c b/super-intel.c
index 536cb61..b561fe2 100644
--- a/super-intel.c
+++ b/super-intel.c
@@ -3502,6 +3502,9 @@ static void getinfo_super_imsm(struct supertype *st, struct mdinfo *info, char *
__u32 ord = get_imsm_ord_tbl_ent(dev, j, MAP_0);
__u32 idx = ord_to_idx(ord);
+ if (super->disks && super->disks->index == (int)idx)
+ info->disk.raid_disk = j;
+
if (!(ord & IMSM_ORD_REBUILD) &&
get_imsm_missing(super, idx)) {
missing = 1;

38
SOURCES/imsm-Write-empty-PPL-header-if-assembling-regular-cl.patch

@ -0,0 +1,38 @@ @@ -0,0 +1,38 @@
From 50b9c10da0e7c153744b548680147dc8cc7c4c72 Mon Sep 17 00:00:00 2001
From: Pawel Baldysiak <pawel.baldysiak@intel.com>
Date: Thu, 28 Sep 2017 14:41:15 +0200
Subject: [PATCH 09/12] imsm: Write empty PPL header if assembling
regular clean array.

If array was initially assembled with kernel without PPL support -
initial header was never written to the drive.
If initial resync was completed and system is rebooted to kernel with
PPL support - mdadm prevents from assembling normal clean array
due to lack of valid PPL.
Write empty header when assemble normal clean array, so the
its assamble is no longer blocked.

Signed-off-by: Pawel Baldysiak <pawel.baldysiak@intel.com>
Signed-off-by: Jes Sorensen <jsorensen@fb.com>
---
super-intel.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/super-intel.c b/super-intel.c
index 7b2327b..501d0c3 100644
--- a/super-intel.c
+++ b/super-intel.c
@@ -6225,7 +6225,9 @@ out:
}
if (ret == 1) {
- if (map->map_state == IMSM_T_STATE_UNINITIALIZED)
+ if (map->map_state == IMSM_T_STATE_UNINITIALIZED ||
+ (map->map_state == IMSM_T_STATE_NORMAL &&
+ !(dev->vol.dirty & RAIDVOL_DIRTY)))
ret = st->ss->write_init_ppl(st, info, d->fd);
else
info->mismatch_cnt++;
--
2.7.4

32
SOURCES/imsm-always-do-ppl-recovery-when-starting-a-rebuildi.patch

@ -0,0 +1,32 @@ @@ -0,0 +1,32 @@
From 98e96bdbefaf0bf1c3d4161862af1ab6d03da1db Mon Sep 17 00:00:00 2001
From: Artur Paszkiewicz <artur.paszkiewicz@intel.com>
Date: Thu, 28 Sep 2017 14:41:16 +0200
Subject: [PATCH 10/12] imsm: always do ppl recovery when starting a
rebuilding array

Set resync_start to 0 when starting a rebuilding array to make the
kernel perform ppl recovery before the rebuild.

Signed-off-by: Artur Paszkiewicz <artur.paszkiewicz@intel.com>
Signed-off-by: Jes Sorensen <jsorensen@fb.com>
---
super-intel.c | 3 +++
1 file changed, 3 insertions(+)

diff --git a/super-intel.c b/super-intel.c
index 501d0c3..996d133 100644
--- a/super-intel.c
+++ b/super-intel.c
@@ -7756,6 +7756,9 @@ static struct mdinfo *container_content_imsm(struct supertype *st, char *subarra
map->blocks_per_strip;
info_d->ppl_sector = this->ppl_sector;
info_d->ppl_size = this->ppl_size;
+ if (this->consistency_policy == CONSISTENCY_POLICY_PPL &&
+ recovery_start == 0)
+ this->resync_start = 0;
} else {
info_d->component_size = blocks_per_member(map);
}
--
2.7.4

113
SOURCES/imsm-continue-resync-on-3disk-RAID10.patch

@ -0,0 +1,113 @@ @@ -0,0 +1,113 @@
commit 8b9cd157dc030924afaeb1dd1a4d3306f5bda118
Author: Maksymilian Kunt <maksymilian.kunt@intel.com>
Date: Mon Nov 13 12:30:49 2017 +0100

imsm: continue resync on 3-disk RAID10
If RAID10 gets degraded during resync and is stopped, it doesn't continue
resync after automatic assemble and it is reported to be in sync. Resync
is blocked because the disk is missing. It should not happen for RAID10 as
it can still continue with 3 disks.
Count missing disks. Block resync only if number of missing disks exceeds
limit for given RAID level (only different for RAID10). Check if the
disk under recovery is present. If not, resync should be allowed to run.
Signed-off-by: Maksymilian Kunt <maksymilian.kunt@intel.com>
Signed-off-by: Tomasz Majchrzak <tomasz.majchrzak@intel.com>
Signed-off-by: Jes Sorensen <jsorensen@fb.com>

diff --git a/super-intel.c b/super-intel.c
index 2f912f2..c55802f 100644
--- a/super-intel.c
+++ b/super-intel.c
@@ -1342,6 +1342,20 @@ static unsigned long long round_size_to_mb(unsigned long long size, unsigned int
return size;
}
+static int able_to_resync(int raid_level, int missing_disks)
+{
+ int max_missing_disks = 0;
+
+ switch (raid_level) {
+ case 10:
+ max_missing_disks = 1;
+ break;
+ default:
+ max_missing_disks = 0;
+ }
+ return missing_disks <= max_missing_disks;
+}
+
/* try to determine how much space is reserved for metadata from
* the last get_extents() entry on the smallest active disk,
* otherwise fallback to the default
@@ -7645,6 +7659,7 @@ static struct mdinfo *container_content_imsm(struct supertype *st, char *subarra
int slot;
int chunk;
char *ep;
+ int level;
if (subarray &&
(i != strtoul(subarray, &ep, 10) || *ep != '\0'))
@@ -7653,6 +7668,7 @@ static struct mdinfo *container_content_imsm(struct supertype *st, char *subarra
dev = get_imsm_dev(super, i);
map = get_imsm_map(dev, MAP_0);
map2 = get_imsm_map(dev, MAP_1);
+ level = get_imsm_raid_level(map);
/* do not publish arrays that are in the middle of an
* unsupported migration
@@ -7675,8 +7691,8 @@ static struct mdinfo *container_content_imsm(struct supertype *st, char *subarra
chunk = __le16_to_cpu(map->blocks_per_strip) >> 1;
/* mdadm does not support all metadata features- set the bit in all arrays state */
if (!validate_geometry_imsm_orom(super,
- get_imsm_raid_level(map), /* RAID level */
- imsm_level_to_layout(get_imsm_raid_level(map)),
+ level, /* RAID level */
+ imsm_level_to_layout(level),
map->num_members, /* raid disks */
&chunk, join_u32(dev->size_low, dev->size_high),
1 /* verbose */)) {
@@ -7700,6 +7716,7 @@ static struct mdinfo *container_content_imsm(struct supertype *st, char *subarra
int idx;
int skip;
__u32 ord;
+ int missing = 0;
skip = 0;
idx = get_imsm_disk_idx(dev, slot, MAP_0);
@@ -7713,19 +7730,27 @@ static struct mdinfo *container_content_imsm(struct supertype *st, char *subarra
skip = 1;
if (d && is_failed(&d->disk))
skip = 1;
- if (ord & IMSM_ORD_REBUILD)
+ if (!skip && (ord & IMSM_ORD_REBUILD))
recovery_start = 0;
/*
* if we skip some disks the array will be assmebled degraded;
* reset resync start to avoid a dirty-degraded
* situation when performing the intial sync
- *
- * FIXME handle dirty degraded
*/
- if ((skip || recovery_start == 0) &&
- !(dev->vol.dirty & RAIDVOL_DIRTY))
- this->resync_start = MaxSector;
+ if (skip)
+ missing++;
+
+ if (!(dev->vol.dirty & RAIDVOL_DIRTY)) {
+ if ((!able_to_resync(level, missing) ||
+ recovery_start == 0))
+ this->resync_start = MaxSector;
+ } else {
+ /*
+ * FIXME handle dirty degraded
+ */
+ }
+
if (skip)
continue;

61
SOURCES/imsm-don-t-skip-resync-when-an-invalid-ppl-header-is.patch

@ -0,0 +1,61 @@ @@ -0,0 +1,61 @@
From b23d07503d5940086ea0884d09a737ccb0a9e435 Mon Sep 17 00:00:00 2001
From: Artur Paszkiewicz <artur.paszkiewicz@intel.com>
Date: Thu, 28 Sep 2017 14:41:14 +0200
Subject: [PATCH 08/12] imsm: don't skip resync when an invalid ppl
header is found

If validate_ppl_imsm() detects an invalid ppl header it will be
overwritten with a valid, empty ppl header. But if we are assembling an
array after unclean shutdown this will cause the kernel to skip resync
after ppl recovery. We don't want that because if there was an invalid
ppl it's best to assume that the ppl recovery is not enough to make the
array consistent and a full resync should be performed. So when
overwriting the invalid ppl add one ppl_header_entry with a wrong
checksum. This will prevent the kernel from skipping resync after ppl
recovery.

Signed-off-by: Artur Paszkiewicz <artur.paszkiewicz@intel.com>
Signed-off-by: Jes Sorensen <jsorensen@fb.com>
---
super-intel.c | 18 ++++++++++++++++--
1 file changed, 16 insertions(+), 2 deletions(-)

diff --git a/super-intel.c b/super-intel.c
index 630fb6e..7b2327b 100644
--- a/super-intel.c
+++ b/super-intel.c
@@ -6080,6 +6080,16 @@ static int write_init_ppl_imsm(struct supertype *st, struct mdinfo *info, int fd
ppl_hdr = buf;
memset(ppl_hdr->reserved, 0xff, PPL_HDR_RESERVED);
ppl_hdr->signature = __cpu_to_le32(super->anchor->orig_family_num);
+
+ if (info->mismatch_cnt) {
+ /*
+ * We are overwriting an invalid ppl. Make one entry with wrong
+ * checksum to prevent the kernel from skipping resync.
+ */
+ ppl_hdr->entries_count = __cpu_to_le32(1);
+ ppl_hdr->entries[0].checksum = ~0;
+ }
+
ppl_hdr->checksum = __cpu_to_le32(~crc32c_le(~0, buf, PPL_HEADER_SIZE));
if (lseek64(fd, info->ppl_sector * 512, SEEK_SET) < 0) {
@@ -6214,8 +6224,12 @@ out:
}
}
- if (ret == 1 && map->map_state == IMSM_T_STATE_UNINITIALIZED)
- return st->ss->write_init_ppl(st, info, d->fd);
+ if (ret == 1) {
+ if (map->map_state == IMSM_T_STATE_UNINITIALIZED)
+ ret = st->ss->write_init_ppl(st, info, d->fd);
+ else
+ info->mismatch_cnt++;
+ }
return ret;
}
--
2.7.4

Some files were not shown because too many files have changed in this diff Show More

Loading…
Cancel
Save