Search
j0ke.net Open Build Service
>
Projects
>
hardware
:
raid
>
mdadm
> mdadm-3.2.2_git3b1dab1bdbda0
Sign Up
|
Log In
Username
Password
Cancel
Overview
Repositories
Revisions
Requests
Users
Advanced
Attributes
Meta
File mdadm-3.2.2_git3b1dab1bdbda0 of Package mdadm (Revision 1)
Currently displaying revision
1
,
show latest
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",