Loading Documentation/md.txt +24 −0 Original line number Diff line number Diff line Loading @@ -51,6 +51,30 @@ superblock can be autodetected and run at boot time. The kernel parameter "raid=partitionable" (or "raid=part") means 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 ------------------ Loading drivers/md/md.c +4 −0 Original line number Diff line number Diff line Loading @@ -1937,6 +1937,7 @@ static void md_safemode_timeout(unsigned long data) md_wakeup_thread(mddev->thread); } static int start_dirty_degraded; static int do_md_run(mddev_t * mddev) { Loading Loading @@ -2048,6 +2049,7 @@ static int do_md_run(mddev_t * mddev) mddev->recovery = 0; mddev->resync_max_sectors = mddev->size << 1; /* may be over-ridden by personality */ mddev->barriers_work = 1; mddev->ok_start_degraded = start_dirty_degraded; if (start_readonly) mddev->ro = 2; /* read-only, but switch on first write */ Loading Loading @@ -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(start_dirty_degraded, int, 0644); EXPORT_SYMBOL(register_md_personality); EXPORT_SYMBOL(unregister_md_personality); Loading drivers/md/raid5.c +11 −4 Original line number Diff line number Diff line Loading @@ -1904,11 +1904,18 @@ static int run(mddev_t *mddev) if (mddev->degraded == 1 && 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 "raid5: cannot start dirty degraded array for %s\n", mdname(mddev)); goto abort; } } { mddev->thread = md_register_thread(raid5d, mddev, "%s_raid5"); Loading drivers/md/raid6main.c +9 −4 Original line number Diff line number Diff line Loading @@ -1929,13 +1929,18 @@ static int run(mddev_t *mddev) goto abort; } #if 0 /* FIX: For now */ if (mddev->degraded > 0 && 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; } #endif } { mddev->thread = md_register_thread(raid6d, mddev, "%s_raid6"); Loading include/linux/raid/md_k.h +1 −0 Original line number Diff line number Diff line Loading @@ -183,6 +183,7 @@ struct mddev_s sector_t resync_mismatches; /* count of sectors where * parity/replica mismatch found */ int ok_start_degraded; /* recovery/resync flags * NEEDED: we might need to start a resync/recover * RUNNING: a thread is running, or about to be started Loading Loading
Documentation/md.txt +24 −0 Original line number Diff line number Diff line Loading @@ -51,6 +51,30 @@ superblock can be autodetected and run at boot time. The kernel parameter "raid=partitionable" (or "raid=part") means 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 ------------------ Loading
drivers/md/md.c +4 −0 Original line number Diff line number Diff line Loading @@ -1937,6 +1937,7 @@ static void md_safemode_timeout(unsigned long data) md_wakeup_thread(mddev->thread); } static int start_dirty_degraded; static int do_md_run(mddev_t * mddev) { Loading Loading @@ -2048,6 +2049,7 @@ static int do_md_run(mddev_t * mddev) mddev->recovery = 0; mddev->resync_max_sectors = mddev->size << 1; /* may be over-ridden by personality */ mddev->barriers_work = 1; mddev->ok_start_degraded = start_dirty_degraded; if (start_readonly) mddev->ro = 2; /* read-only, but switch on first write */ Loading Loading @@ -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(start_dirty_degraded, int, 0644); EXPORT_SYMBOL(register_md_personality); EXPORT_SYMBOL(unregister_md_personality); Loading
drivers/md/raid5.c +11 −4 Original line number Diff line number Diff line Loading @@ -1904,11 +1904,18 @@ static int run(mddev_t *mddev) if (mddev->degraded == 1 && 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 "raid5: cannot start dirty degraded array for %s\n", mdname(mddev)); goto abort; } } { mddev->thread = md_register_thread(raid5d, mddev, "%s_raid5"); Loading
drivers/md/raid6main.c +9 −4 Original line number Diff line number Diff line Loading @@ -1929,13 +1929,18 @@ static int run(mddev_t *mddev) goto abort; } #if 0 /* FIX: For now */ if (mddev->degraded > 0 && 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; } #endif } { mddev->thread = md_register_thread(raid6d, mddev, "%s_raid6"); Loading
include/linux/raid/md_k.h +1 −0 Original line number Diff line number Diff line Loading @@ -183,6 +183,7 @@ struct mddev_s sector_t resync_mismatches; /* count of sectors where * parity/replica mismatch found */ int ok_start_degraded; /* recovery/resync flags * NEEDED: we might need to start a resync/recover * RUNNING: a thread is running, or about to be started Loading