mirror of
https://github.com/adulau/aha.git
synced 2024-12-29 04:06:22 +00:00
[PATCH] md: allow dirty raid[456] arrays to be started at boot
See patch to md.txt for more details Signed-off-by: Neil Brown <neilb@suse.de> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
This commit is contained in:
parent
14f8d26b8e
commit
6ff8d8ec06
5 changed files with 49 additions and 8 deletions
|
@ -51,6 +51,30 @@ superblock can be autodetected and run at boot time.
|
||||||
The kernel parameter "raid=partitionable" (or "raid=part") means
|
The kernel parameter "raid=partitionable" (or "raid=part") means
|
||||||
that all auto-detected arrays are assembled as partitionable.
|
that all auto-detected arrays are assembled as partitionable.
|
||||||
|
|
||||||
|
Boot time assembly of degraded/dirty arrays
|
||||||
|
-------------------------------------------
|
||||||
|
|
||||||
|
If a raid5 or raid6 array is both dirty and degraded, it could have
|
||||||
|
undetectable data corruption. This is because the fact that it is
|
||||||
|
'dirty' means that the parity cannot be trusted, and the fact that it
|
||||||
|
is degraded means that some datablocks are missing and cannot reliably
|
||||||
|
be reconstructed (due to no parity).
|
||||||
|
|
||||||
|
For this reason, md will normally refuse to start such an array. This
|
||||||
|
requires the sysadmin to take action to explicitly start the array
|
||||||
|
desipite possible corruption. This is normally done with
|
||||||
|
mdadm --assemble --force ....
|
||||||
|
|
||||||
|
This option is not really available if the array has the root
|
||||||
|
filesystem on it. In order to support this booting from such an
|
||||||
|
array, md supports a module parameter "start_dirty_degraded" which,
|
||||||
|
when set to 1, bypassed the checks and will allows dirty degraded
|
||||||
|
arrays to be started.
|
||||||
|
|
||||||
|
So, to boot with a root filesystem of a dirty degraded raid[56], use
|
||||||
|
|
||||||
|
md-mod.start_dirty_degraded=1
|
||||||
|
|
||||||
|
|
||||||
Superblock formats
|
Superblock formats
|
||||||
------------------
|
------------------
|
||||||
|
|
|
@ -1937,6 +1937,7 @@ static void md_safemode_timeout(unsigned long data)
|
||||||
md_wakeup_thread(mddev->thread);
|
md_wakeup_thread(mddev->thread);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int start_dirty_degraded;
|
||||||
|
|
||||||
static int do_md_run(mddev_t * mddev)
|
static int do_md_run(mddev_t * mddev)
|
||||||
{
|
{
|
||||||
|
@ -2048,6 +2049,7 @@ static int do_md_run(mddev_t * mddev)
|
||||||
mddev->recovery = 0;
|
mddev->recovery = 0;
|
||||||
mddev->resync_max_sectors = mddev->size << 1; /* may be over-ridden by personality */
|
mddev->resync_max_sectors = mddev->size << 1; /* may be over-ridden by personality */
|
||||||
mddev->barriers_work = 1;
|
mddev->barriers_work = 1;
|
||||||
|
mddev->ok_start_degraded = start_dirty_degraded;
|
||||||
|
|
||||||
if (start_readonly)
|
if (start_readonly)
|
||||||
mddev->ro = 2; /* read-only, but switch on first write */
|
mddev->ro = 2; /* read-only, but switch on first write */
|
||||||
|
@ -4509,6 +4511,8 @@ static int set_ro(const char *val, struct kernel_param *kp)
|
||||||
}
|
}
|
||||||
|
|
||||||
module_param_call(start_ro, set_ro, get_ro, NULL, 0600);
|
module_param_call(start_ro, set_ro, get_ro, NULL, 0600);
|
||||||
|
module_param(start_dirty_degraded, int, 0644);
|
||||||
|
|
||||||
|
|
||||||
EXPORT_SYMBOL(register_md_personality);
|
EXPORT_SYMBOL(register_md_personality);
|
||||||
EXPORT_SYMBOL(unregister_md_personality);
|
EXPORT_SYMBOL(unregister_md_personality);
|
||||||
|
|
|
@ -1904,11 +1904,18 @@ static int run(mddev_t *mddev)
|
||||||
|
|
||||||
if (mddev->degraded == 1 &&
|
if (mddev->degraded == 1 &&
|
||||||
mddev->recovery_cp != MaxSector) {
|
mddev->recovery_cp != MaxSector) {
|
||||||
|
if (mddev->ok_start_degraded)
|
||||||
|
printk(KERN_WARNING
|
||||||
|
"raid5: starting dirty degraded array: %s"
|
||||||
|
"- data corruption possible.\n",
|
||||||
|
mdname(mddev));
|
||||||
|
else {
|
||||||
printk(KERN_ERR
|
printk(KERN_ERR
|
||||||
"raid5: cannot start dirty degraded array for %s\n",
|
"raid5: cannot start dirty degraded array for %s\n",
|
||||||
mdname(mddev));
|
mdname(mddev));
|
||||||
goto abort;
|
goto abort;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
mddev->thread = md_register_thread(raid5d, mddev, "%s_raid5");
|
mddev->thread = md_register_thread(raid5d, mddev, "%s_raid5");
|
||||||
|
|
|
@ -1929,13 +1929,18 @@ static int run(mddev_t *mddev)
|
||||||
goto abort;
|
goto abort;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if 0 /* FIX: For now */
|
|
||||||
if (mddev->degraded > 0 &&
|
if (mddev->degraded > 0 &&
|
||||||
mddev->recovery_cp != MaxSector) {
|
mddev->recovery_cp != MaxSector) {
|
||||||
printk(KERN_ERR "raid6: cannot start dirty degraded array for %s\n", mdname(mddev));
|
if (mddev->ok_start_degraded)
|
||||||
|
printk(KERN_WARNING "raid6: starting dirty degraded array:%s"
|
||||||
|
"- data corruption possible.\n",
|
||||||
|
mdname(mddev));
|
||||||
|
else {
|
||||||
|
printk(KERN_ERR "raid6: cannot start dirty degraded array"
|
||||||
|
" for %s\n", mdname(mddev));
|
||||||
goto abort;
|
goto abort;
|
||||||
}
|
}
|
||||||
#endif
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
mddev->thread = md_register_thread(raid6d, mddev, "%s_raid6");
|
mddev->thread = md_register_thread(raid6d, mddev, "%s_raid6");
|
||||||
|
|
|
@ -183,6 +183,7 @@ struct mddev_s
|
||||||
sector_t resync_mismatches; /* count of sectors where
|
sector_t resync_mismatches; /* count of sectors where
|
||||||
* parity/replica mismatch found
|
* parity/replica mismatch found
|
||||||
*/
|
*/
|
||||||
|
int ok_start_degraded;
|
||||||
/* recovery/resync flags
|
/* recovery/resync flags
|
||||||
* NEEDED: we might need to start a resync/recover
|
* NEEDED: we might need to start a resync/recover
|
||||||
* RUNNING: a thread is running, or about to be started
|
* RUNNING: a thread is running, or about to be started
|
||||||
|
|
Loading…
Reference in a new issue