mdadm: enable sync file for udev rules
Mounting an md device may fail during boot from mdadm's claim
on the device not being released before systemd attempts to mount.
In this case it was found that essentially there is a race condition
occurring in which the mount cannot happen without some kind of delay
being added BEFORE the mount itself triggers, or manual intervention
after a timeout.
The findings:
the inode was for a tmp block node made by mdadm for md0.
crash> detailedsearch ff1b0c398ff28380
ff1b0c398f079720: ff1b0c398ff28380 slab:filp state:alloc
obj:ff1b0c398f079700 size:256
ff1b0c398ff284f8: ff1b0c398ff28380 slab:shmem_inode_cache
state:alloc obj:ff1b0c398ff28308 size:768
crash> struct file.f_inode,f_path ff1b0c398f079700
f_inode = 0xff1b0c398ff28380,
f_path = {
mnt = 0xff1b0c594aecc7a0,
dentry = 0xff1b0c3a8c614f00
},
crash> struct dentry.d_name 0xff1b0c3a8c614f00
d_name = {
{
{ hash = 3714992780, len = 16 },
hash_len = 72434469516
},
name = 0xff1b0c3a8c614f38 ".tmp.md.1454:9:0"
},
For the race condition, mdadm and udev have some infrastructure for making
the device be ignored while under construction. e.g.
$ cat lib/udev/rules.d/01-md-raid-creating.rules
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"
However, this feature currently is only used by the mdadm create command.
See calls to udev_block/udev_unblock in the mdadm code as to where and when
this behavior is used. Any md array being started by incremental or
normal assemble commands does not use this udev integration. So assembly
of an existing array does not look to have any explicit protection from
systemd/udev seeing an array as in a usable state before an mdadm instance
with O_EXCL closes its file handle.
This is for the sake of showing the use case for such an option and why
it would be helpful to delay the mount itself.
While mdadm is still constructing the array mdadm --incremental
that is called from within /usr/lib/udev/rules.d/64-md-raid-assembly.rules,
there is an attempt to mount the md device, but there is not a creation
of "/run/mdadm/creating-xxx" file when in incremental mode that
the rule is looking for. Therefore the device is not marked
as SYSTEMD_READY=0 in
"/usr/lib/udev/rules.d/01-md-raid-creating.rules" and missing
synchronization using the "/run/mdadm/creating-xxx" file.
As to this change affecting containers or IMSM...
(container's array state is inactive all the time)
Even if the "array_state" reports "inactive" when previous components
are added, the mdadm call for the very last array component that makes
it usable/ready, still needs to be synced properly - mdadm needs to drop
the claim first calling "close", then delete the "/run/mdadm/creating-xxx".
Then lets the udev know it is clear to act now (the "udev_unblock" in
mdadm code that generates a synthetic udev event so the rules are
reevalutated). It's this processing of the very last array component
that is the issue here (which is not IO error, but it is that trying to
open the dev returns -EBUSY because of the exclusive claim that mdadm
still holds while the mdadm device is being processed already by udev in
parallel, and that is what the
/run/mdadm/creating-xxx should prevent exactly).
The patch to Incremental.c is to enable creating the
"/run/mdadm/creating-xxx" file during incremental mode.
For the change to Create.c, the unlink is called right before dropping
the exculusive claim for the device. This should be the other way round
to avoid the race 100%. That is, if there's a "close" call and
"udev_unblock" call, the "close" should go first, then followed
"udev_unblock".
Signed-off-by: Nigel Croxon <ncroxon@redhat.com>
mdadm is a utility used to create and manage software RAID devices implemented through Multiple devices driver (MD) in kernel. It supports following RAID metadata formats:
Known as native or native RAID. First and default metadata format. Metadata management is implemented in MD driver.
Matrix Storage Manager Support (no reference, metadata format documentation is proprietary).
Known as IMSM. Metadata format developed and maintained by IntelĀ® as a part of VROC solution. There are some functional differences between native and imsm. The most important difference is that the metadata is managed from userspace.
CAUTION: imsm is compatible with Intel RST, however it is not officially supported. You are using it on your own risk.
Common RAID DDF Specification Revision
IMPORTANT: DDF is in maintenance only mode. There is no active development around it. Please do not use it in new solutions.
This Github site is not right place to ask if your are looking for:
This is the place where development of mdadm application is done. Please, do not use for looking for support. You should always ask on Mailing List.
Please use issues if you have confirmation that issue you are experiencing is related to mdadm components:
For example:
Generally, if you are not sure it is better to ask on Mailing List first.
Effective immediately Github is the primary location for mdadm. Please use pull requests to contribute.
It was originally hosted on kernel.org. You can access the old repository here.
While this is the preferred contribution method, mailing list submissions are still welcome and will be handled as has always been the case for mdadm. Please add “mdadm:” to the subject to allow automation to create Github Pull Request and run checks.
NOTE: Maintainers may ask you to send RFC to mailing list if the proposed code requires consultation with kernel developers.
Kernel coding style is used. Please familiarize with general kernel submitting patches documentation. Formatting, tags and commit message guidelines applies to mdadm.
Checkpatch script is run on every patch in pull request so be sure that your commits are not generating issues. There are some excludes, so the best is to follow github checkpatch action result.
Pull Request are closed by Rebase and Merge option, so it requires to keep every commit meaningful. Kernel style requires that. The review changes must be pushed with push --force to the chosen branch, then Pull Request will be automatically updated.
See Maintainers File.
We do not support kernel versions below v3.10. Please be aware that maintainers may remove workarounds and fixes for legacy issues.
The following packages are required for compilation:
| RHEL | SLES | Debian/Ubuntu |
|---|---|---|
pkgconf | pkg-config | pkg-config |
gcc | gcc | gcc |
make | make | make |
libudev-devel | libudev-devel | libudev-dev |
Run make command to compile mdadm.
Specifying more jobs e.g. make -j4 can decrease compilation time significantly.
Various values can be specified for the CXFLAGS variable to customize the build process:
make CXFLAGS=-ggdb to include gdb debugging information.make CXFLAGS=-DDEBUG to enable additional debug information through dprintf statements and call traces.make CXFLAGS=-DNO_LIBUDEV to compile without libudev.To build with more than one option specified in CXFLAGS, separate each option with a space, e.g. make CXFLAGS="-ggdb -DDEBUG".
Additionally, the EXTRAVERSION variable can be set to build with user-friendly version label, useful when customizing mdadm builds or labeling some instance in between major releases, e.g. make EXTRAVERSION="custom-label".
Before installing mdadm, it is advised to uninstall vendor-provided packages (mdadm.deb, mdadm.rpm etc.) in order to avoid configuration issues.
Run make install command to install mdadm. This command invokes the following targets:
install-bininstall-maninstall-udevAfter installing mdadm, consider rebuilding initramfs to ensure the changes take effect.
List of installation targets:
make install-bin to install the mdadm and mdmon binary files.make install-systemd to install the systemd services.make install-udev to install the udev rules.make install-man to install the manual pages (mdadm.8, md.4, mdadm.conf.5, mdmon.8).The following targets are deprecated and should not be used:
install-staticIt is released under the terms of the GNU General Public License version 2 as published by the Free Software Foundation.