forked from pool/mdadm
b5de3e63a0
have having a separate one. OBS-URL: https://build.opensuse.org/package/show/Base:System/mdadm?expand=0&rev=40
1004 lines
36 KiB
Plaintext
1004 lines
36 KiB
Plaintext
diff --git a/.gitignore b/.gitignore
|
||
index 2503bd8..7200741 100644
|
||
--- a/.gitignore
|
||
+++ b/.gitignore
|
||
@@ -2,6 +2,7 @@
|
||
/*.man
|
||
/*-stamp
|
||
/mdadm
|
||
+/mdadm.8
|
||
/mdadm.udeb
|
||
/mdmon
|
||
/swap_super
|
||
diff --git a/COPYING b/COPYING
|
||
index 60549be..d159169 100644
|
||
--- a/COPYING
|
||
+++ b/COPYING
|
||
@@ -1,12 +1,12 @@
|
||
- GNU GENERAL PUBLIC LICENSE
|
||
- Version 2, June 1991
|
||
+ GNU GENERAL PUBLIC LICENSE
|
||
+ Version 2, June 1991
|
||
|
||
- Copyright (C) 1989, 1991 Free Software Foundation, Inc.
|
||
- 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||
+ Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
|
||
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||
Everyone is permitted to copy and distribute verbatim copies
|
||
of this license document, but changing it is not allowed.
|
||
|
||
- Preamble
|
||
+ Preamble
|
||
|
||
The licenses for most software are designed to take away your
|
||
freedom to share and change it. By contrast, the GNU General Public
|
||
@@ -15,7 +15,7 @@ software--to make sure the software is free for all its users. This
|
||
General Public License applies to most of the Free Software
|
||
Foundation's software and to any other program whose authors commit to
|
||
using it. (Some other Free Software Foundation software is covered by
|
||
-the GNU Library General Public License instead.) You can apply it to
|
||
+the GNU Lesser General Public License instead.) You can apply it to
|
||
your programs, too.
|
||
|
||
When we speak of free software, we are referring to freedom, not
|
||
@@ -55,8 +55,8 @@ patent must be licensed for everyone's free use or not licensed at all.
|
||
|
||
The precise terms and conditions for copying, distribution and
|
||
modification follow.
|
||
-
|
||
- GNU GENERAL PUBLIC LICENSE
|
||
+
|
||
+ GNU GENERAL PUBLIC LICENSE
|
||
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||
|
||
0. This License applies to any program or other work which contains
|
||
@@ -110,7 +110,7 @@ above, provided that you also meet all of these conditions:
|
||
License. (Exception: if the Program itself is interactive but
|
||
does not normally print such an announcement, your work based on
|
||
the Program is not required to print an announcement.)
|
||
-
|
||
+
|
||
These requirements apply to the modified work as a whole. If
|
||
identifiable sections of that work are not derived from the Program,
|
||
and can be reasonably considered independent and separate works in
|
||
@@ -168,7 +168,7 @@ access to copy from a designated place, then offering equivalent
|
||
access to copy the source code from the same place counts as
|
||
distribution of the source code, even though third parties are not
|
||
compelled to copy the source along with the object code.
|
||
-
|
||
+
|
||
4. You may not copy, modify, sublicense, or distribute the Program
|
||
except as expressly provided under this License. Any attempt
|
||
otherwise to copy, modify, sublicense or distribute the Program is
|
||
@@ -225,7 +225,7 @@ impose that choice.
|
||
|
||
This section is intended to make thoroughly clear what is believed to
|
||
be a consequence of the rest of this License.
|
||
-
|
||
+
|
||
8. If the distribution and/or use of the Program is restricted in
|
||
certain countries either by patents or by copyrighted interfaces, the
|
||
original copyright holder who places the Program under this License
|
||
@@ -255,7 +255,7 @@ make exceptions for this. Our decision will be guided by the two goals
|
||
of preserving the free status of all derivatives of our free software and
|
||
of promoting the sharing and reuse of software generally.
|
||
|
||
- NO WARRANTY
|
||
+ NO WARRANTY
|
||
|
||
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
|
||
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
|
||
@@ -277,9 +277,9 @@ YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
|
||
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
|
||
POSSIBILITY OF SUCH DAMAGES.
|
||
|
||
- END OF TERMS AND CONDITIONS
|
||
-
|
||
- How to Apply These Terms to Your New Programs
|
||
+ END OF TERMS AND CONDITIONS
|
||
+
|
||
+ How to Apply These Terms to Your New Programs
|
||
|
||
If you develop a new program, and you want it to be of the greatest
|
||
possible use to the public, the best way to achieve this is to make it
|
||
@@ -291,7 +291,7 @@ convey the exclusion of warranty; and each file should have at least
|
||
the "copyright" line and a pointer to where the full notice is found.
|
||
|
||
<one line to give the program's name and a brief idea of what it does.>
|
||
- Copyright (C) 19yy <name of author>
|
||
+ Copyright (C) <year> <name of author>
|
||
|
||
This program is free software; you can redistribute it and/or modify
|
||
it under the terms of the GNU General Public License as published by
|
||
@@ -303,17 +303,16 @@ the "copyright" line and a pointer to where the full notice is found.
|
||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||
GNU General Public License for more details.
|
||
|
||
- You should have received a copy of the GNU General Public License
|
||
- along with this program; if not, write to the Free Software
|
||
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||
-
|
||
+ You should have received a copy of the GNU General Public License along
|
||
+ with this program; if not, write to the Free Software Foundation, Inc.,
|
||
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||
|
||
Also add information on how to contact you by electronic and paper mail.
|
||
|
||
If the program is interactive, make it output a short notice like this
|
||
when it starts in an interactive mode:
|
||
|
||
- Gnomovision version 69, Copyright (C) 19yy name of author
|
||
+ Gnomovision version 69, Copyright (C) year name of author
|
||
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
|
||
This is free software, and you are welcome to redistribute it
|
||
under certain conditions; type `show c' for details.
|
||
@@ -336,5 +335,5 @@ necessary. Here is a sample; alter the names:
|
||
This General Public License does not permit incorporating your program into
|
||
proprietary programs. If your program is a subroutine library, you may
|
||
consider it more useful to permit linking proprietary applications with the
|
||
-library. If this is what you want to do, use the GNU Library General
|
||
+library. If this is what you want to do, use the GNU Lesser General
|
||
Public License instead of this License.
|
||
diff --git a/Create.c b/Create.c
|
||
index 48115db..8d88aa1 100644
|
||
--- a/Create.c
|
||
+++ b/Create.c
|
||
@@ -856,15 +856,6 @@ int Create(struct supertype *st, char *mddev,
|
||
/* getinfo_super might have lost these ... */
|
||
inf->disk.major = major(stb.st_rdev);
|
||
inf->disk.minor = minor(stb.st_rdev);
|
||
- /* FIXME the following should not be needed
|
||
- * as getinfo_super is suppose to set
|
||
- * them. However it doesn't for imsm,
|
||
- * so we have this hack for now
|
||
- */
|
||
- if (st->ss == &super_imsm) {
|
||
- inf->disk.number = dnum;
|
||
- inf->disk.raid_disk = dnum;
|
||
- }
|
||
}
|
||
break;
|
||
case 2:
|
||
diff --git a/Detail.c b/Detail.c
|
||
index 375189d..ca34abe 100644
|
||
--- a/Detail.c
|
||
+++ b/Detail.c
|
||
@@ -372,11 +372,13 @@ int Detail(char *dev, int brief, int export, int test, char *homehost)
|
||
else
|
||
st = ", degraded";
|
||
|
||
- printf(" State : %s%s%s%s\n",
|
||
- (array.state&(1<<MD_SB_CLEAN))?"clean":"active",
|
||
- st,
|
||
- (!e || e->percent < 0) ? "" : sync_action[e->resync],
|
||
- larray_size ? "": ", Not Started");
|
||
+ printf(" State : %s%s%s%s%s%s \n",
|
||
+ (array.state&(1<<MD_SB_CLEAN))?"clean":"active", st,
|
||
+ (!e || (e->percent < 0 && e->percent != PROCESS_PENDING &&
|
||
+ e->percent != PROCESS_DELAYED)) ? "" : sync_action[e->resync],
|
||
+ larray_size ? "": ", Not Started",
|
||
+ e->percent == PROCESS_DELAYED ? " (DELAYED)": "",
|
||
+ e->percent == PROCESS_PENDING ? " (PENDING)": "");
|
||
}
|
||
if (array.raid_disks)
|
||
printf(" Active Devices : %d\n", array.active_disks);
|
||
@@ -416,10 +418,8 @@ int Detail(char *dev, int brief, int export, int test, char *homehost)
|
||
}
|
||
|
||
if (e && e->percent >= 0) {
|
||
- printf(" Re%s Status : %d%% complete\n",
|
||
- (st && st->sb && info->reshape_active)?
|
||
- "shape":"build",
|
||
- e->percent);
|
||
+ static char *sync_action[] = {"Rebuild", "Resync", "Reshape", "Check"};
|
||
+ printf(" %7s Status : %d%% complete\n", sync_action[e->resync], e->percent);
|
||
is_rebuilding = 1;
|
||
}
|
||
free_mdstat(ms);
|
||
@@ -430,12 +430,9 @@ 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));
|
||
#endif
|
||
- if (info->delta_disks > 0)
|
||
+ if (info->delta_disks != 0)
|
||
printf(" Delta Devices : %d, (%d->%d)\n",
|
||
info->delta_disks, array.raid_disks - info->delta_disks, array.raid_disks);
|
||
- if (info->delta_disks < 0)
|
||
- printf(" Delta Devices : %d, (%d->%d)\n",
|
||
- info->delta_disks, array.raid_disks, array.raid_disks + info->delta_disks);
|
||
if (info->new_level != array.level) {
|
||
char *c = map_num(pers, info->new_level);
|
||
printf(" New Level : %s\n", c?c:"-unknown-");
|
||
diff --git a/Grow.c b/Grow.c
|
||
index 6e31b94..1aab113 100644
|
||
--- a/Grow.c
|
||
+++ b/Grow.c
|
||
@@ -1268,7 +1268,7 @@ char *analyse_change(struct mdinfo *info, struct reshape *re)
|
||
|
||
if (re->after.data_disks < re->before.data_disks &&
|
||
get_linux_version() < 2006030)
|
||
- return "reshape to fewer devices is not supported before 2.6.32 - sorry.";
|
||
+ return "reshape to fewer devices is not supported before 2.6.30 - sorry.";
|
||
|
||
re->backup_blocks = compute_backup_blocks(
|
||
info->new_chunk, info->array.chunk_size,
|
||
@@ -1494,7 +1494,7 @@ int Grow_reshape(char *devname, int fd, int quiet, char *backup_file,
|
||
goto release;
|
||
}
|
||
if (assume_clean) {
|
||
- /* This will fail on kernels newer than 2.6.40 unless
|
||
+ /* This will fail on kernels newer than 3.0 unless
|
||
* a backport has been arranged.
|
||
*/
|
||
if (sra == NULL ||
|
||
@@ -2725,15 +2725,21 @@ check_progress:
|
||
int rv = -2;
|
||
tv.tv_sec = 10;
|
||
tv.tv_usec = 0;
|
||
- while (fd >= 0 && rv < 0) {
|
||
+ while (fd >= 0 && rv < 0 && tv.tv_sec > 0) {
|
||
fd_set rfds;
|
||
FD_ZERO(&rfds);
|
||
FD_SET(fd, &rfds);
|
||
if (select(fd+1, NULL, NULL, &rfds, &tv) != 1)
|
||
break;
|
||
- if (sysfs_fd_get_ll(fd, &completed) >= 0)
|
||
+ switch (sysfs_fd_get_ll(fd, &completed)) {
|
||
+ case 0:
|
||
/* all good again */
|
||
rv = 1;
|
||
+ break;
|
||
+ case -2: /* read error - abort */
|
||
+ tv.tv_sec = 0;
|
||
+ break;
|
||
+ }
|
||
}
|
||
if (fd >= 0)
|
||
close(fd);
|
||
diff --git a/Kill.c b/Kill.c
|
||
index 29a43ea..b841a5b 100644
|
||
--- a/Kill.c
|
||
+++ b/Kill.c
|
||
@@ -59,6 +59,7 @@ int Kill(char *dev, struct supertype *st, int force, int quiet, int noexcl)
|
||
close(fd);
|
||
return 2;
|
||
}
|
||
+ st->ignore_hw_compat = 1;
|
||
rv = st->ss->load_super(st, fd, dev);
|
||
if (force && rv >= 2)
|
||
rv = 0; /* ignore bad data in superblock */
|
||
diff --git a/Makefile b/Makefile
|
||
index 72087be..b8d363f 100644
|
||
--- a/Makefile
|
||
+++ b/Makefile
|
||
@@ -137,7 +137,7 @@ ASSEMBLE_FLAGS += -DMDASSEMBLE_AUTO
|
||
endif
|
||
|
||
all : mdadm mdmon
|
||
-man : mdadm.man md.man mdadm.conf.man mdmon.man
|
||
+man : mdadm.man md.man mdadm.conf.man mdmon.man raid6check.man
|
||
|
||
everything: all mdadm.static swap_super test_stripe \
|
||
mdassemble mdassemble.auto mdassemble.static mdassemble.man \
|
||
@@ -221,6 +221,9 @@ mdadm.conf.man : mdadm.conf.5
|
||
mdassemble.man : mdassemble.8
|
||
nroff -man mdassemble.8 > mdassemble.man
|
||
|
||
+raid6check.man : raid6check.8
|
||
+ nroff -man raid6check.8 > raid6check.man
|
||
+
|
||
$(OBJS) : $(INCL) mdmon.h
|
||
$(MON_OBJS) : $(INCL) mdmon.h
|
||
|
||
diff --git a/md.4 b/md.4
|
||
index 5e79639..378ecc9 100644
|
||
--- a/md.4
|
||
+++ b/md.4
|
||
@@ -128,7 +128,7 @@ have special-purpose uses and is supported.
|
||
From release 2.6.28, the
|
||
.I md
|
||
driver supports arrays with externally managed metadata. That is,
|
||
-the metadata is not managed by the kernel by rather by a user-space
|
||
+the metadata is not managed by the kernel but rather by a user-space
|
||
program which is external to the kernel. This allows support for a
|
||
variety of metadata formats without cluttering the kernel with lots of
|
||
details.
|
||
@@ -468,7 +468,7 @@ scrub starts and is incremented whenever a sector is
|
||
found that is a mismatch.
|
||
.I md
|
||
normally works in units much larger than a single sector and when it
|
||
-finds a mismatch, it does not determin exactly how many actual sectors were
|
||
+finds a mismatch, it does not determine exactly how many actual sectors were
|
||
affected but simply adds the number of sectors in the IO unit that was
|
||
used. So a value of 128 could simply mean that a single 64KB check
|
||
found an error (128 x 512bytes = 64KB).
|
||
@@ -661,7 +661,7 @@ to this file will cause the system-wide setting to have effect.
|
||
This is the partner of
|
||
.B md/sync_speed_min
|
||
and overrides
|
||
-.B /proc/sys/dev/raid/spool_limit_max
|
||
+.B /proc/sys/dev/raid/speed_limit_max
|
||
described below.
|
||
|
||
.TP
|
||
diff --git a/mdadm.8.in b/mdadm.8.in
|
||
index d2d7ef2..e22fde4 100644
|
||
--- a/mdadm.8.in
|
||
+++ b/mdadm.8.in
|
||
@@ -418,11 +418,22 @@ issued.
|
||
A suffix of 'M' or 'G' can be given to indicate Megabytes or
|
||
Gigabytes respectively.
|
||
|
||
+Sometimes a replacement drive can be a little smaller than the
|
||
+original drives though this should be minimised by IDEMA standards.
|
||
+Such a replacement drive will be rejected by
|
||
+.IR md .
|
||
+To guard against this it can be useful to set the initial size
|
||
+slightly smaller than the smaller device with the aim that it will
|
||
+still be larger than any replacement.
|
||
+
|
||
This value can be set with
|
||
.B \-\-grow
|
||
-for RAID level 1/4/5/6. If the array was created with a size smaller
|
||
-than the currently active drives, the extra space can be accessed
|
||
-using
|
||
+for RAID level 1/4/5/6 though
|
||
+.B CONTAINER
|
||
+based arrays such as those with IMSM metadata may not be able to
|
||
+support this.
|
||
+If the array was created with a size smaller than the currently
|
||
+active drives, the extra space can be accessed using
|
||
.BR \-\-grow .
|
||
The size can be given as
|
||
.B max
|
||
@@ -440,9 +451,10 @@ problems the array can be made bigger again with no loss with another
|
||
.B "\-\-grow \-\-size="
|
||
command.
|
||
|
||
-This value can not be used with
|
||
+This value cannot be used when creating a
|
||
.B CONTAINER
|
||
-metadata such as DDF and IMSM.
|
||
+such as with DDF and IMSM metadata, though it perfectly valid when
|
||
+creating an array inside a container.
|
||
|
||
.TP
|
||
.BR \-Z ", " \-\-array\-size=
|
||
@@ -706,7 +718,7 @@ facts the operator knows.
|
||
When an array is resized to a larger size with
|
||
.B "\-\-grow \-\-size="
|
||
the new space is normally resynced in that same way that the whole
|
||
-array is resynced at creation. From Linux version 2.6.40,
|
||
+array is resynced at creation. From Linux version 3.0,
|
||
.B \-\-assume\-clean
|
||
can be used with that command to avoid the automatic resync.
|
||
|
||
@@ -811,6 +823,11 @@ number, and there is no entry in /dev for that number and with a
|
||
non-standard name. Names that are not in 'standard' format are only
|
||
allowed in "/dev/md/".
|
||
|
||
+This is meaningful with
|
||
+.B \-\-create
|
||
+or
|
||
+.BR \-\-build .
|
||
+
|
||
.ig XX
|
||
.\".TP
|
||
.\".BR \-\-symlink = no
|
||
@@ -835,6 +852,28 @@ allowed in "/dev/md/".
|
||
.\"
|
||
.XX
|
||
|
||
+.TP
|
||
+.BR \-a ", " "\-\-add"
|
||
+This option can be used in Grow mode in two cases.
|
||
+
|
||
+If the target array is a Linear array, then
|
||
+.B \-\-add
|
||
+can be used to add one or more devices to the array. They
|
||
+are simply catenated on to the end of the array. Once added, the
|
||
+devices cannot be removed.
|
||
+
|
||
+If the
|
||
+.B \-\-raid\-disks
|
||
+option is being used to increase the number of devices in an array,
|
||
+then
|
||
+.B \-\-add
|
||
+can be used to add some extra devices to be included in the array.
|
||
+In most cases this is not needed as the extra devices can be added as
|
||
+spares first, and then the number of raid-disks can be changed.
|
||
+However for RAID0, it is not possible to add spares. So to increase
|
||
+the number of devices in a RAID0, it is necessary to set the new
|
||
+number of devices, and to add the new devices, in the same command.
|
||
+
|
||
.SH For assemble:
|
||
|
||
.TP
|
||
@@ -912,28 +951,6 @@ not as reliable as you would like.
|
||
See this option under Create and Build options.
|
||
|
||
.TP
|
||
-.BR \-a ", " "\-\-add"
|
||
-This option can be used in Grow mode in two cases.
|
||
-
|
||
-If the target array is a Linear array, then
|
||
-.B \-\-add
|
||
-can be used to add one or more devices to the array. They
|
||
-are simply catenated on to the end of the array. Once added, the
|
||
-devices cannot be removed.
|
||
-
|
||
-If the
|
||
-.B \-\-raid\-disks
|
||
-option is being used to increase the number of devices in an array,
|
||
-then
|
||
-.B \-\-add
|
||
-can be used to add some extra devices to be included in the array.
|
||
-In most cases this is not needed as the extra devices can be added as
|
||
-spares first, and then the number of raid-disks can be changed.
|
||
-However for RAID0, it is not possible to add spares. So to increase
|
||
-the number of devices in a RAID0, it is necessary to set the new
|
||
-number of devices, and to add the new devices, in the same command.
|
||
-
|
||
-.TP
|
||
.BR \-b ", " \-\-bitmap=
|
||
Specify the bitmap file that was given when the array was created. If
|
||
an array has an
|
||
@@ -1491,7 +1508,7 @@ the first device given is the md device.
|
||
In the second usage example, all devices listed are treated as md
|
||
devices and assembly is attempted.
|
||
In the third (where no devices are listed) all md devices that are
|
||
-listed in the configuration file are assembled. If not arrays are
|
||
+listed in the configuration file are assembled. If no arrays are
|
||
described by the configuration file, then any arrays that
|
||
can be found on unused devices will be assembled.
|
||
|
||
@@ -1600,7 +1617,7 @@ and no devices are listed,
|
||
will first attempt to assemble all the arrays listed in the config
|
||
file.
|
||
|
||
-In no array at listed in the config (other than those marked
|
||
+If no arrays are listed in the config (other than those marked
|
||
.BR <ignore> )
|
||
it will look through the available devices for possible arrays and
|
||
will try to assemble anything that it finds. Arrays which are tagged
|
||
@@ -2200,22 +2217,24 @@ change the "size" attribute for RAID1, RAID4, RAID5 and RAID6.
|
||
.IP \(bu 4
|
||
increase or decrease the "raid\-devices" attribute of RAID0, RAID1, RAID4,
|
||
RAID5, and RAID6.
|
||
-.IP \bu 4
|
||
+.IP \(bu 4
|
||
change the chunk-size and layout of RAID0, RAID4, RAID5 and RAID6.
|
||
-.IP \bu 4
|
||
+.IP \(bu 4
|
||
convert between RAID1 and RAID5, between RAID5 and RAID6, between
|
||
-RAID0, RAID5, and RAID5, and between RAID0 and RAID10 (in the near-2 mode).
|
||
+RAID0, RAID4, and RAID5, and between RAID0 and RAID10 (in the near-2 mode).
|
||
.IP \(bu 4
|
||
add a write-intent bitmap to any array which supports these bitmaps, or
|
||
remove a write-intent bitmap from such an array.
|
||
.PP
|
||
|
||
-Using GROW on containers is currently only support for Intel's IMSM
|
||
+Using GROW on containers is currently supported only for Intel's IMSM
|
||
container format. The number of devices in a container can be
|
||
increased - which affects all arrays in the container - or an array
|
||
in a container can be converted between levels where those levels are
|
||
supported by the container, and the conversion is on of those listed
|
||
-above.
|
||
+above. Resizing arrays in an IMSM container with
|
||
+.B "--grow --size"
|
||
+is not yet supported.
|
||
|
||
Grow functionality (e.g. expand a number of raid devices) for Intel's
|
||
IMSM container format has an experimental status. It is guarded by the
|
||
@@ -2250,7 +2269,7 @@ space to start being used. If the size is increased in this way, a
|
||
are synchronised.
|
||
|
||
Note that when an array changes size, any filesystem that may be
|
||
-stored in the array will not automatically grow for shrink to use or
|
||
+stored in the array will not automatically grow or shrink to use or
|
||
vacate the space. The
|
||
filesystem will need to be explicitly told to use the extra space
|
||
after growing, or to reduce its size
|
||
@@ -2259,7 +2278,7 @@ to shrinking the array.
|
||
|
||
Also the size of an array cannot be changed while it has an active
|
||
bitmap. If an array has a bitmap, it must be removed before the size
|
||
-can be changed. Once the change it complete a new bitmap can be created.
|
||
+can be changed. Once the change is complete a new bitmap can be created.
|
||
|
||
.SS RAID\-DEVICES CHANGES
|
||
|
||
@@ -2435,8 +2454,8 @@ must match one of the names or patterns in a
|
||
line.
|
||
|
||
.IP +
|
||
-Does the device have a valid md superblock. If a specific metadata
|
||
-version is request with
|
||
+Does the device have a valid md superblock? If a specific metadata
|
||
+version is requested with
|
||
.B \-\-metadata
|
||
or
|
||
.B \-e
|
||
@@ -2467,6 +2486,7 @@ is not able to positively identify the array as belonging to the
|
||
current host, the device will be rejected.
|
||
..
|
||
|
||
+.PP
|
||
.I mdadm
|
||
keeps a list of arrays that it has partially assembled in
|
||
.B /var/run/mdadm/map
|
||
@@ -2639,7 +2659,7 @@ can be started.
|
||
Any devices which are components of /dev/md4 will be marked as faulty
|
||
and then remove from the array.
|
||
|
||
-.B " mdadm --grow /dev/md4 --level=6 --backup-file=/root/backup-md4
|
||
+.B " mdadm --grow /dev/md4 --level=6 --backup-file=/root/backup-md4"
|
||
.br
|
||
The array
|
||
.B /dev/md4
|
||
@@ -2787,7 +2807,7 @@ configuration file at all.
|
||
For further information on mdadm usage, MD and the various levels of
|
||
RAID, see:
|
||
.IP
|
||
-.B http://linux\-raid.osdl.org/
|
||
+.B http://raid.wiki.kernel.org/
|
||
.PP
|
||
(based upon Jakob \(/Ostergaard's Software\-RAID.HOWTO)
|
||
.\".PP
|
||
diff --git a/mdadm.h b/mdadm.h
|
||
index e075dd2..8bd0077 100644
|
||
--- a/mdadm.h
|
||
+++ b/mdadm.h
|
||
@@ -1345,3 +1345,5 @@ static inline int xasprintf(char **strp, const char *fmt, ...) {
|
||
#define PATH_MAX 4096
|
||
#endif
|
||
|
||
+#define PROCESS_DELAYED -2
|
||
+#define PROCESS_PENDING -3
|
||
diff --git a/mdmon.8 b/mdmon.8
|
||
index 7939a99..03b31b8 100644
|
||
--- a/mdmon.8
|
||
+++ b/mdmon.8
|
||
@@ -104,7 +104,7 @@ within those disks. MD metadata in comparison defines a 1:1
|
||
relationship between a set of block devices and a raid array. For
|
||
example to create 2 arrays at different raid levels on a single
|
||
set of disks, MD metadata requires the disks be partitioned and then
|
||
-each array can created be created with a subset of those partitions. The
|
||
+each array can be created with a subset of those partitions. The
|
||
supported external formats perform this disk carving internally.
|
||
.P
|
||
Container devices simply hold references to all member disks and allow
|
||
@@ -172,7 +172,7 @@ Note that
|
||
is automatically started by
|
||
.I mdadm
|
||
when needed and so does not need to be considered when working with
|
||
-RAID arrays. The only times it is run other that by
|
||
+RAID arrays. The only times it is run other than by
|
||
.I mdadm
|
||
is when the boot scripts need to restart it after mounting the new
|
||
root filesystem.
|
||
diff --git a/mdstat.c b/mdstat.c
|
||
index 3d2edad..abf6bf9 100644
|
||
--- a/mdstat.c
|
||
+++ b/mdstat.c
|
||
@@ -257,10 +257,10 @@ struct mdstat_ent *mdstat_read(int hold, int start)
|
||
if (strncmp(w, "check", 5)==0)
|
||
ent->resync = 3;
|
||
|
||
- if (l > 8 && strcmp(w+l-8, "=DELAYED"))
|
||
- ent->percent = 0;
|
||
- if (l > 8 && strcmp(w+l-8, "=PENDING"))
|
||
- ent->percent = 0;
|
||
+ if (l > 8 && strcmp(w+l-8, "=DELAYED") == 0)
|
||
+ ent->percent = PROCESS_DELAYED;
|
||
+ if (l > 8 && strcmp(w+l-8, "=PENDING") == 0)
|
||
+ ent->percent = PROCESS_PENDING;
|
||
} else if (ent->percent == -1 &&
|
||
w[0] >= '0' &&
|
||
w[0] <= '9' &&
|
||
diff --git a/platform-intel.h b/platform-intel.h
|
||
index e24ae37..6c094d7 100644
|
||
--- a/platform-intel.h
|
||
+++ b/platform-intel.h
|
||
@@ -167,21 +167,6 @@ static inline int fls(int x)
|
||
return r;
|
||
}
|
||
|
||
-/**
|
||
- * imsm_orom_default_chunk - return the largest chunk size supported via orom
|
||
- * @orom: orom pointer from find_imsm_orom
|
||
- */
|
||
-static inline int imsm_orom_default_chunk(const struct imsm_orom *orom)
|
||
-{
|
||
- int fs = fls(orom->sss);
|
||
-
|
||
- if (!fs)
|
||
- return 0;
|
||
-
|
||
- return min(512, (1 << fs));
|
||
-}
|
||
-
|
||
-
|
||
enum sys_dev_type {
|
||
SYS_DEV_UNKNOWN = 0,
|
||
SYS_DEV_SAS,
|
||
@@ -189,7 +174,6 @@ enum sys_dev_type {
|
||
SYS_DEV_MAX
|
||
};
|
||
|
||
-
|
||
struct sys_dev {
|
||
enum sys_dev_type type;
|
||
char *path;
|
||
diff --git a/raid6check.8 b/raid6check.8
|
||
new file mode 100644
|
||
index 0000000..5003343
|
||
--- /dev/null
|
||
+++ b/raid6check.8
|
||
@@ -0,0 +1,96 @@
|
||
+.\" -*- nroff -*-
|
||
+.\" Copyright Piergiorgio Sartor and others.
|
||
+.\" This program is free software; you can redistribute it and/or modify
|
||
+.\" it under the terms of the GNU General Public License as published by
|
||
+.\" the Free Software Foundation; either version 2 of the License, or
|
||
+.\" (at your option) any later version.
|
||
+.\" See file COPYING in distribution for details.
|
||
+.TH RAID6CHECK 8 "" v1.0.0
|
||
+.SH NAME
|
||
+raid6check \- check MD RAID6 device for errors
|
||
+.I aka
|
||
+Linux Software RAID
|
||
+
|
||
+.SH SYNOPSIS
|
||
+
|
||
+.BI raid6check " <raid6 device> <start stripe> <number of stripes>"
|
||
+
|
||
+.SH DESCRIPTION
|
||
+RAID6 devices in which one single component drive has errors can use
|
||
+the double parity in order to find out which component drive.
|
||
+The "raid6check" tool checks, for each stripe, the double parity
|
||
+consistency, reports mismatches and, if possible, which
|
||
+component drive has the mismatch.
|
||
+Since it works at stripe level, it can report different drives with
|
||
+mismatches at different stripes.
|
||
+
|
||
+"raid6check" requires a non-degraded RAID6 MD device as first
|
||
+parameter, a starting stripe (usually 0) and the number of stripes
|
||
+to be checked.
|
||
+If this third parameter is also 0, it will check the array up to
|
||
+the end.
|
||
+
|
||
+"raid6check" will start printing information about the RAID6, then
|
||
+for each stripe, it will report the parity rotation status.
|
||
+In case of parity mismatches, "raid6check" reports, if possible,
|
||
+which component drive could be responsible. Otherwise it reports
|
||
+that it is not possible to find the component drive.
|
||
+
|
||
+If the given MD device is not a RAID6, "raid6check" will, of
|
||
+course, not continue.
|
||
+
|
||
+If the RAID6 MD device is degraded, "raid6check" will report
|
||
+an error and it will not proceed further.
|
||
+
|
||
+No write operations are performed on the array or the components.
|
||
+Furthermore, the checked array can be online and in use during
|
||
+the operation of "raid6check".
|
||
+
|
||
+.SH EXAMPLES
|
||
+
|
||
+.B " raid6check /dev/md0 0 0"
|
||
+.br
|
||
+This will check /dev/md0 from start to end.
|
||
+
|
||
+.B " raid6check /dev/md3 0 1"
|
||
+.br
|
||
+This will check the first stripe of /dev/md3.
|
||
+
|
||
+.B " raid6check /dev/md1 1000 0"
|
||
+.br
|
||
+This will check /dev/md1 from stripe 1000 up to the end.
|
||
+
|
||
+.B " raid6check /dev/m127 128 256"
|
||
+.br
|
||
+This will check 256 stripes of /dev/md127 starting from stripe 128.
|
||
+
|
||
+.B " raid6check /dev/md0 0 0 | grep -i error > md0_err.log"
|
||
+.br
|
||
+This will check /dev/md0 completely and create a log file only
|
||
+with errors, if any.
|
||
+
|
||
+.SH FILES
|
||
+
|
||
+"raid6check" uses directly the component drives as found in /dev.
|
||
+Furthermore, the sysfs interface is needed in order to find out
|
||
+the RAID6 parameters.
|
||
+
|
||
+.SH BUGS
|
||
+Negative parameters can lead to unexpected results.
|
||
+
|
||
+It is not clear what will happen if the RAID6 MD device gets
|
||
+degraded during the check.
|
||
+
|
||
+.PP
|
||
+The latest version of
|
||
+.I raid6check
|
||
+should always be available from
|
||
+.IP
|
||
+.B http://www.kernel.org/pub/linux/utils/raid/mdadm/
|
||
+.PP
|
||
+Related man pages:
|
||
+.PP
|
||
+.IR mdadm (8)
|
||
+.IR mdmon (8),
|
||
+.IR mdadm.conf (5),
|
||
+.IR md (4).
|
||
diff --git a/super-intel.c b/super-intel.c
|
||
index 2ef2b3c..ddf4de9 100644
|
||
--- a/super-intel.c
|
||
+++ b/super-intel.c
|
||
@@ -74,14 +74,17 @@
|
||
|
||
/* Define all supported attributes that have to be accepted by mdadm
|
||
*/
|
||
-#define MPB_ATTRIB_SUPPORTED MPB_ATTRIB_CHECKSUM_VERIFY | \
|
||
+#define MPB_ATTRIB_SUPPORTED (MPB_ATTRIB_CHECKSUM_VERIFY | \
|
||
MPB_ATTRIB_2TB | \
|
||
MPB_ATTRIB_2TB_DISK | \
|
||
MPB_ATTRIB_RAID0 | \
|
||
MPB_ATTRIB_RAID1 | \
|
||
MPB_ATTRIB_RAID10 | \
|
||
MPB_ATTRIB_RAID5 | \
|
||
- MPB_ATTRIB_EXP_STRIPE_SIZE
|
||
+ MPB_ATTRIB_EXP_STRIPE_SIZE)
|
||
+
|
||
+/* Define attributes that are unused but not harmful */
|
||
+#define MPB_ATTRIB_IGNORED (MPB_ATTRIB_NEVER_USE)
|
||
|
||
#define MPB_SECTOR_CNT 2210
|
||
#define IMSM_RESERVED_SECTORS 4096
|
||
@@ -341,7 +344,7 @@ struct intel_super {
|
||
struct extent *e; /* for determining freespace @ create */
|
||
int raiddisk; /* slot to fill in autolayout */
|
||
enum action action;
|
||
- } *disks;
|
||
+ } *disks, *current_disk;
|
||
struct dl *disk_mgmt_list; /* list of disks to add/remove while mdmon
|
||
active */
|
||
struct dl *missing; /* disks removed while we weren't looking */
|
||
@@ -1141,11 +1144,14 @@ void examine_migr_rec_imsm(struct intel_super *super)
|
||
static int imsm_check_attributes(__u32 attributes)
|
||
{
|
||
int ret_val = 1;
|
||
- __u32 not_supported = (MPB_ATTRIB_SUPPORTED)^0xffffffff;
|
||
+ __u32 not_supported = MPB_ATTRIB_SUPPORTED^0xffffffff;
|
||
+
|
||
+ not_supported &= ~MPB_ATTRIB_IGNORED;
|
||
|
||
not_supported &= attributes;
|
||
if (not_supported) {
|
||
- fprintf(stderr, Name "(IMSM): Unsupported attributes : %x\n", not_supported);
|
||
+ fprintf(stderr, Name "(IMSM): Unsupported attributes : %x\n",
|
||
+ (unsigned)__le32_to_cpu(not_supported));
|
||
if (not_supported & MPB_ATTRIB_CHECKSUM_VERIFY) {
|
||
dprintf("\t\tMPB_ATTRIB_CHECKSUM_VERIFY \n");
|
||
not_supported ^= MPB_ATTRIB_CHECKSUM_VERIFY;
|
||
@@ -1518,9 +1524,9 @@ static int ahci_enumerate_ports(const char *hba_path, int port_count, int host_b
|
||
fd2devname(fd, buf);
|
||
printf(" Port%d : %s", port, buf);
|
||
if (imsm_read_serial(fd, NULL, (__u8 *) buf) == 0)
|
||
- printf(" (%s)\n", buf);
|
||
+ printf(" (%.*s)\n", MAX_RAID_SERIAL_LEN, buf);
|
||
else
|
||
- printf("()\n");
|
||
+ printf(" ()\n");
|
||
}
|
||
close(fd);
|
||
free(path);
|
||
@@ -2201,7 +2207,7 @@ static void getinfo_super_imsm_volume(struct supertype *st, struct mdinfo *info,
|
||
if (prev_map)
|
||
map_to_analyse = prev_map;
|
||
|
||
- dl = super->disks;
|
||
+ dl = super->current_disk;
|
||
|
||
info->container_member = super->current_vol;
|
||
info->array.raid_disks = map->num_members;
|
||
@@ -2263,11 +2269,13 @@ static void getinfo_super_imsm_volume(struct supertype *st, struct mdinfo *info,
|
||
info->new_chunk = info->array.chunk_size;
|
||
info->delta_disks = 0;
|
||
}
|
||
- info->disk.major = 0;
|
||
- info->disk.minor = 0;
|
||
+
|
||
if (dl) {
|
||
info->disk.major = dl->major;
|
||
info->disk.minor = dl->minor;
|
||
+ info->disk.number = dl->index;
|
||
+ info->disk.raid_disk = get_imsm_disk_slot(map_to_analyse,
|
||
+ dl->index);
|
||
}
|
||
|
||
info->data_offset = __le32_to_cpu(map_to_analyse->pba_of_lba0);
|
||
@@ -2326,7 +2334,9 @@ static void getinfo_super_imsm_volume(struct supertype *st, struct mdinfo *info,
|
||
|
||
dprintf("IMSM: General Migration checkpoint : %llu "
|
||
"(%llu) -> read reshape progress : %llu\n",
|
||
- units, blocks_per_unit, info->reshape_progress);
|
||
+ (unsigned long long)units,
|
||
+ (unsigned long long)blocks_per_unit,
|
||
+ info->reshape_progress);
|
||
|
||
used_disks = imsm_num_data_members(dev, 1);
|
||
if (used_disks > 0) {
|
||
@@ -4327,7 +4337,7 @@ static int add_to_super_imsm_volume(struct supertype *st, mdu_disk_info_t *dk,
|
||
devname);
|
||
return 1;
|
||
}
|
||
- set_imsm_ord_tbl_ent(map, dk->number, dl->index);
|
||
+ set_imsm_ord_tbl_ent(map, dk->raid_disk, dl->index);
|
||
dl->disk.status = CONFIGURED_DISK;
|
||
|
||
/* if we are creating the first raid device update the family number */
|
||
@@ -4347,7 +4357,7 @@ static int add_to_super_imsm_volume(struct supertype *st, mdu_disk_info_t *dk,
|
||
mpb->family_num = __cpu_to_le32(sum);
|
||
mpb->orig_family_num = mpb->family_num;
|
||
}
|
||
-
|
||
+ super->current_disk = dl;
|
||
return 0;
|
||
}
|
||
|
||
@@ -4912,6 +4922,15 @@ static int is_raid_level_supported(const struct imsm_orom *orom, int level, int
|
||
return 0;
|
||
}
|
||
|
||
+static int imsm_default_chunk(const struct imsm_orom *orom)
|
||
+{
|
||
+ /* up to 512 if the plaform supports it, otherwise the platform max.
|
||
+ * 128 if no platform detected
|
||
+ */
|
||
+ int fs = max(7, orom ? fls(orom->sss) : 0);
|
||
+
|
||
+ return min(512, (1 << fs));
|
||
+}
|
||
|
||
#define pr_vrb(fmt, arg...) (void) (verbose && fprintf(stderr, Name fmt, ##arg))
|
||
/*
|
||
@@ -4940,15 +4959,16 @@ validate_geometry_imsm_orom(struct intel_super *super, int level, int layout,
|
||
level, raiddisks, raiddisks > 1 ? "s" : "");
|
||
return 0;
|
||
}
|
||
- if (super->orom && level != 1) {
|
||
- if (chunk && (*chunk == 0 || *chunk == UnSet))
|
||
- *chunk = imsm_orom_default_chunk(super->orom);
|
||
- else if (chunk && !imsm_orom_has_chunk(super->orom, *chunk)) {
|
||
- pr_vrb(": platform does not support a chunk size of: "
|
||
- "%d\n", *chunk);
|
||
- return 0;
|
||
- }
|
||
+
|
||
+ if (chunk && (*chunk == 0 || *chunk == UnSet))
|
||
+ *chunk = imsm_default_chunk(super->orom);
|
||
+
|
||
+ if (super->orom && chunk && !imsm_orom_has_chunk(super->orom, *chunk)) {
|
||
+ pr_vrb(": platform does not support a chunk size of: "
|
||
+ "%d\n", *chunk);
|
||
+ return 0;
|
||
}
|
||
+
|
||
if (layout != imsm_level_to_layout(level)) {
|
||
if (level == 5)
|
||
pr_vrb(": imsm raid 5 only supports the left-asymmetric layout\n");
|
||
@@ -5298,9 +5318,8 @@ static void default_geometry_imsm(struct supertype *st, int *level, int *layout,
|
||
if (level && layout && *layout == UnSet)
|
||
*layout = imsm_level_to_layout(*level);
|
||
|
||
- if (chunk && (*chunk == UnSet || *chunk == 0) &&
|
||
- super && super->orom)
|
||
- *chunk = imsm_orom_default_chunk(super->orom);
|
||
+ if (chunk && (*chunk == UnSet || *chunk == 0))
|
||
+ *chunk = imsm_default_chunk(super->orom);
|
||
}
|
||
|
||
static void handle_missing(struct intel_super *super, struct imsm_dev *dev);
|
||
@@ -8661,8 +8680,9 @@ static int imsm_reshape_super(struct supertype *st, long long size, int level,
|
||
dprintf("imsm: info: Volume operation\n");
|
||
/* find requested device */
|
||
while (dev) {
|
||
- imsm_find_array_minor_by_subdev(dev->index, st->container_dev, &devnum);
|
||
- if (devnum == geo.dev_id)
|
||
+ if (imsm_find_array_minor_by_subdev(
|
||
+ dev->index, st->container_dev, &devnum) == 0
|
||
+ && devnum == geo.dev_id)
|
||
break;
|
||
dev = dev->next;
|
||
}
|
||
diff --git a/super1.c b/super1.c
|
||
index 09be351..35e92a3 100644
|
||
--- a/super1.c
|
||
+++ b/super1.c
|
||
@@ -313,7 +313,7 @@ static void examine_super1(struct supertype *st, char *homehost)
|
||
printf("\n");
|
||
}
|
||
if (sb->devflags) {
|
||
- printf(" Flags :");
|
||
+ printf(" Flags :");
|
||
if (sb->devflags & WriteMostly1)
|
||
printf(" write-mostly");
|
||
printf("\n");
|
||
@@ -1056,6 +1056,8 @@ static int write_init_super1(struct supertype *st)
|
||
sb->dev_number = __cpu_to_le32(di->disk.number);
|
||
if (di->disk.state & (1<<MD_DISK_WRITEMOSTLY))
|
||
sb->devflags |= __cpu_to_le32(WriteMostly1);
|
||
+ else
|
||
+ sb->devflags &= ~(__cpu_to_le32(WriteMostly1));
|
||
|
||
if ((rfd = open("/dev/urandom", O_RDONLY)) < 0 ||
|
||
read(rfd, sb->device_uuid, 16) != 16) {
|
||
diff --git a/sysfs.c b/sysfs.c
|
||
index 44314ba..56813b7 100644
|
||
--- a/sysfs.c
|
||
+++ b/sysfs.c
|
||
@@ -470,7 +470,7 @@ int sysfs_fd_get_ll(int fd, unsigned long long *val)
|
||
lseek(fd, 0, 0);
|
||
n = read(fd, buf, sizeof(buf));
|
||
if (n <= 0)
|
||
- return -1;
|
||
+ return -2;
|
||
buf[n] = 0;
|
||
*val = strtoull(buf, &ep, 0);
|
||
if (ep == buf || (*ep != 0 && *ep != '\n' && *ep != ' '))
|
||
diff --git a/udev-md-raid.rules b/udev-md-raid.rules
|
||
index 1d89833..c2105bc 100644
|
||
--- a/udev-md-raid.rules
|
||
+++ b/udev-md-raid.rules
|
||
@@ -3,9 +3,11 @@
|
||
SUBSYSTEM!="block", GOTO="md_end"
|
||
|
||
# handle potential components of arrays
|
||
-ENV{ID_FS_TYPE}=="linux_raid_member", ACTION=="remove", RUN+="/sbin/mdadm -If $name --path $env{ID_PATH}"
|
||
+ENV{ID_FS_TYPE}=="linux_raid_member", ENV{ID_PATH}!="", ACTION=="remove", RUN+="/sbin/mdadm -If $name --path $env{ID_PATH}"
|
||
+ENV{ID_FS_TYPE}=="linux_raid_member", ENV{ID_PATH}=="", ACTION=="remove", RUN+="/sbin/mdadm -If $name"
|
||
ENV{ID_FS_TYPE}=="linux_raid_member", ACTION=="add", RUN+="/sbin/mdadm --incremental $env{DEVNAME}"
|
||
-ENV{ID_FS_TYPE}=="isw_raid_member", ACTION=="remove", RUN+="/sbin/mdadm -If $name --path $env{ID_PATH}"
|
||
+ENV{ID_FS_TYPE}=="isw_raid_member", ENV{ID_PATH}!="", ACTION=="remove", RUN+="/sbin/mdadm -If $name --path $env{ID_PATH}"
|
||
+ENV{ID_FS_TYPE}=="isw_raid_member", ENV{ID_PATH}=="", ACTION=="remove", RUN+="/sbin/mdadm -If $name"
|
||
ENV{ID_FS_TYPE}=="isw_raid_member", ACTION=="add", RUN+="/sbin/mdadm --incremental $env{DEVNAME}"
|
||
|
||
# handle md arrays
|
||
diff --git a/util.c b/util.c
|
||
index 10bbe56..ce03239 100644
|
||
--- a/util.c
|
||
+++ b/util.c
|
||
@@ -146,16 +146,16 @@ int get_linux_version()
|
||
{
|
||
struct utsname name;
|
||
char *cp;
|
||
- int a,b,c;
|
||
+ int a = 0, b = 0,c = 0;
|
||
if (uname(&name) <0)
|
||
return -1;
|
||
|
||
cp = name.release;
|
||
a = strtoul(cp, &cp, 10);
|
||
- if (*cp != '.') return -1;
|
||
- b = strtoul(cp+1, &cp, 10);
|
||
- if (*cp != '.') return -1;
|
||
- c = strtoul(cp+1, NULL, 10);
|
||
+ if (*cp == '.')
|
||
+ b = strtoul(cp+1, &cp, 10);
|
||
+ if (*cp == '.')
|
||
+ c = strtoul(cp+1, &cp, 10);
|
||
|
||
return (a*1000000)+(b*1000)+c;
|
||
}
|
||
@@ -535,6 +535,7 @@ int check_raid(int fd, char *name)
|
||
struct supertype *st = guess_super(fd);
|
||
|
||
if (!st) return 0;
|
||
+ st->ignore_hw_compat = 1;
|
||
st->ss->load_super(st, fd, name);
|
||
/* Looks like a raid array .. */
|
||
fprintf(stderr, Name ": %s appears to be part of a raid array:\n",
|