2013-04-12 00:33:59 +04:00
#!/bin/sh
# Copyright (C) 2013 Red Hat, Inc. All rights reserved.
#
# This copyrighted material is made available to anyone wishing to use,
# modify, copy, or redistribute it subject to the terms and conditions
# of the GNU General Public License v.2.
#
# 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
. lib/test
RAID: Add writemostly/writebehind support for RAID1
'lvchange' is used to alter a RAID 1 logical volume's write-mostly and
write-behind characteristics. The '--writemostly' parameter takes a
PV as an argument with an optional trailing character to specify whether
to set ('y'), unset ('n'), or toggle ('t') the value. If no trailing
character is given, it will set the flag.
Synopsis:
lvchange [--writemostly <PV>:{t|y|n}] [--writebehind <count>] vg/lv
Example:
lvchange --writemostly /dev/sdb1:y --writebehind 512 vg/raid1_lv
The last character in the 'lv_attr' field is used to show whether a device
has the WriteMostly flag set. It is signified with a 'w'. If the device
has failed, the 'p'artial flag has priority.
Example ("nosync" raid1 with mismatch_cnt and writemostly):
[~]# lvs -a --segment vg
LV VG Attr #Str Type SSize
raid1 vg Rwi---r-m 2 raid1 500.00m
[raid1_rimage_0] vg Iwi---r-- 1 linear 500.00m
[raid1_rimage_1] vg Iwi---r-w 1 linear 500.00m
[raid1_rmeta_0] vg ewi---r-- 1 linear 4.00m
[raid1_rmeta_1] vg ewi---r-- 1 linear 4.00m
Example (raid1 with mismatch_cnt, writemostly - but failed drive):
[~]# lvs -a --segment vg
LV VG Attr #Str Type SSize
raid1 vg rwi---r-p 2 raid1 500.00m
[raid1_rimage_0] vg Iwi---r-- 1 linear 500.00m
[raid1_rimage_1] vg Iwi---r-p 1 linear 500.00m
[raid1_rmeta_0] vg ewi---r-- 1 linear 4.00m
[raid1_rmeta_1] vg ewi---r-p 1 linear 4.00m
A new reportable field has been added for writebehind as well. If
write-behind has not been set or the LV is not RAID1, the field will
be blank.
Example (writebehind is set):
[~]# lvs -a -o name,attr,writebehind vg
LV Attr WBehind
lv rwi-a-r-- 512
[lv_rimage_0] iwi-aor-w
[lv_rimage_1] iwi-aor--
[lv_rmeta_0] ewi-aor--
[lv_rmeta_1] ewi-aor--
Example (writebehind is not set):
[~]# lvs -a -o name,attr,writebehind vg
LV Attr WBehind
lv rwi-a-r--
[lv_rimage_0] iwi-aor-w
[lv_rimage_1] iwi-aor--
[lv_rmeta_0] ewi-aor--
[lv_rmeta_1] ewi-aor--
2013-04-15 22:59:46 +04:00
# dm-raid v1.4.1+ contains RAID10 support
aux target_at_least dm-raid 1 4 1 || skip
2013-04-12 00:33:59 +04:00
2013-06-20 20:48:15 +04:00
aux prepare_vg 6
2013-04-12 00:33:59 +04:00
RAID: Add writemostly/writebehind support for RAID1
'lvchange' is used to alter a RAID 1 logical volume's write-mostly and
write-behind characteristics. The '--writemostly' parameter takes a
PV as an argument with an optional trailing character to specify whether
to set ('y'), unset ('n'), or toggle ('t') the value. If no trailing
character is given, it will set the flag.
Synopsis:
lvchange [--writemostly <PV>:{t|y|n}] [--writebehind <count>] vg/lv
Example:
lvchange --writemostly /dev/sdb1:y --writebehind 512 vg/raid1_lv
The last character in the 'lv_attr' field is used to show whether a device
has the WriteMostly flag set. It is signified with a 'w'. If the device
has failed, the 'p'artial flag has priority.
Example ("nosync" raid1 with mismatch_cnt and writemostly):
[~]# lvs -a --segment vg
LV VG Attr #Str Type SSize
raid1 vg Rwi---r-m 2 raid1 500.00m
[raid1_rimage_0] vg Iwi---r-- 1 linear 500.00m
[raid1_rimage_1] vg Iwi---r-w 1 linear 500.00m
[raid1_rmeta_0] vg ewi---r-- 1 linear 4.00m
[raid1_rmeta_1] vg ewi---r-- 1 linear 4.00m
Example (raid1 with mismatch_cnt, writemostly - but failed drive):
[~]# lvs -a --segment vg
LV VG Attr #Str Type SSize
raid1 vg rwi---r-p 2 raid1 500.00m
[raid1_rimage_0] vg Iwi---r-- 1 linear 500.00m
[raid1_rimage_1] vg Iwi---r-p 1 linear 500.00m
[raid1_rmeta_0] vg ewi---r-- 1 linear 4.00m
[raid1_rmeta_1] vg ewi---r-p 1 linear 4.00m
A new reportable field has been added for writebehind as well. If
write-behind has not been set or the LV is not RAID1, the field will
be blank.
Example (writebehind is set):
[~]# lvs -a -o name,attr,writebehind vg
LV Attr WBehind
lv rwi-a-r-- 512
[lv_rimage_0] iwi-aor-w
[lv_rimage_1] iwi-aor--
[lv_rmeta_0] ewi-aor--
[lv_rmeta_1] ewi-aor--
Example (writebehind is not set):
[~]# lvs -a -o name,attr,writebehind vg
LV Attr WBehind
lv rwi-a-r--
[lv_rimage_0] iwi-aor-w
[lv_rimage_1] iwi-aor--
[lv_rmeta_0] ewi-aor--
[lv_rmeta_1] ewi-aor--
2013-04-15 22:59:46 +04:00
# run_writemostly_check <VG> <LV>
run_writemostly_check( ) {
2013-06-20 20:48:15 +04:00
local d0
local d1
printf "#\n#\n#\n# %s/%s (%s): run_writemostly_check\n#\n#\n#\n" \
$1 $2 ` lvs --noheadings -o segtype $1 /$2 `
RAID: Add writemostly/writebehind support for RAID1
'lvchange' is used to alter a RAID 1 logical volume's write-mostly and
write-behind characteristics. The '--writemostly' parameter takes a
PV as an argument with an optional trailing character to specify whether
to set ('y'), unset ('n'), or toggle ('t') the value. If no trailing
character is given, it will set the flag.
Synopsis:
lvchange [--writemostly <PV>:{t|y|n}] [--writebehind <count>] vg/lv
Example:
lvchange --writemostly /dev/sdb1:y --writebehind 512 vg/raid1_lv
The last character in the 'lv_attr' field is used to show whether a device
has the WriteMostly flag set. It is signified with a 'w'. If the device
has failed, the 'p'artial flag has priority.
Example ("nosync" raid1 with mismatch_cnt and writemostly):
[~]# lvs -a --segment vg
LV VG Attr #Str Type SSize
raid1 vg Rwi---r-m 2 raid1 500.00m
[raid1_rimage_0] vg Iwi---r-- 1 linear 500.00m
[raid1_rimage_1] vg Iwi---r-w 1 linear 500.00m
[raid1_rmeta_0] vg ewi---r-- 1 linear 4.00m
[raid1_rmeta_1] vg ewi---r-- 1 linear 4.00m
Example (raid1 with mismatch_cnt, writemostly - but failed drive):
[~]# lvs -a --segment vg
LV VG Attr #Str Type SSize
raid1 vg rwi---r-p 2 raid1 500.00m
[raid1_rimage_0] vg Iwi---r-- 1 linear 500.00m
[raid1_rimage_1] vg Iwi---r-p 1 linear 500.00m
[raid1_rmeta_0] vg ewi---r-- 1 linear 4.00m
[raid1_rmeta_1] vg ewi---r-p 1 linear 4.00m
A new reportable field has been added for writebehind as well. If
write-behind has not been set or the LV is not RAID1, the field will
be blank.
Example (writebehind is set):
[~]# lvs -a -o name,attr,writebehind vg
LV Attr WBehind
lv rwi-a-r-- 512
[lv_rimage_0] iwi-aor-w
[lv_rimage_1] iwi-aor--
[lv_rmeta_0] ewi-aor--
[lv_rmeta_1] ewi-aor--
Example (writebehind is not set):
[~]# lvs -a -o name,attr,writebehind vg
LV Attr WBehind
lv rwi-a-r--
[lv_rimage_0] iwi-aor-w
[lv_rimage_1] iwi-aor--
[lv_rmeta_0] ewi-aor--
[lv_rmeta_1] ewi-aor--
2013-04-15 22:59:46 +04:00
d0 = ` lvs -a --noheadings -o devices $1 /${ 2 } _rimage_0 | sed s/\( .\) //`
d0 = $( sed s/^[ [ :space:] ] *// <<< " $d0 " )
d1 = ` lvs -a --noheadings -o devices $1 /${ 2 } _rimage_1 | sed s/\( .\) //`
d1 = $( sed s/^[ [ :space:] ] *// <<< " $d1 " )
# No writemostly flag should be there yet.
lvs -a --noheadings -o lv_attr $1 /${ 2 } _rimage_0 | grep '.*-$'
lvs -a --noheadings -o lv_attr $1 /${ 2 } _rimage_1 | grep '.*-$'
if [ ` lvs --noheadings -o segtype $1 /$2 ` != "raid1" ] ; then
not lvchange --writemostly $d0 $1 /$2
return
fi
# Set the flag
lvchange --writemostly $d0 $1 /$2
lvs -a --noheadings -o lv_attr $1 /${ 2 } _rimage_0 | grep '.*w$'
# Running again should leave it set (not toggle)
lvchange --writemostly $d0 $1 /$2
lvs -a --noheadings -o lv_attr $1 /${ 2 } _rimage_0 | grep '.*w$'
# Running again with ':y' should leave it set
lvchange --writemostly $d0 :y $1 /$2
lvs -a --noheadings -o lv_attr $1 /${ 2 } _rimage_0 | grep '.*w$'
# ':n' should unset it
lvchange --writemostly $d0 :n $1 /$2
lvs -a --noheadings -o lv_attr $1 /${ 2 } _rimage_0 | grep '.*-$'
# ':n' again should leave it unset
lvchange --writemostly $d0 :n $1 /$2
lvs -a --noheadings -o lv_attr $1 /${ 2 } _rimage_0 | grep '.*-$'
# ':t' toggle to set
lvchange --writemostly $d0 :t $1 /$2
lvs -a --noheadings -o lv_attr $1 /${ 2 } _rimage_0 | grep '.*w$'
# ':t' toggle to unset
lvchange --writemostly $d0 :t $1 /$2
lvs -a --noheadings -o lv_attr $1 /${ 2 } _rimage_0 | grep '.*-$'
# ':y' to set
lvchange --writemostly $d0 :y $1 /$2
lvs -a --noheadings -o lv_attr $1 /${ 2 } _rimage_0 | grep '.*w$'
# Toggle both at once
lvchange --writemostly $d0 :t --writemostly $d1 :t $1 /$2
lvs -a --noheadings -o lv_attr $1 /${ 2 } _rimage_0 | grep '.*-$'
lvs -a --noheadings -o lv_attr $1 /${ 2 } _rimage_1 | grep '.*w$'
# Toggle both at once again
lvchange --writemostly $d0 :t --writemostly $d1 :t $1 /$2
lvs -a --noheadings -o lv_attr $1 /${ 2 } _rimage_0 | grep '.*w$'
lvs -a --noheadings -o lv_attr $1 /${ 2 } _rimage_1 | grep '.*-$'
# Toggle one, unset the other
lvchange --writemostly $d0 :n --writemostly $d1 :t $1 /$2
lvs -a --noheadings -o lv_attr $1 /${ 2 } _rimage_0 | grep '.*-$'
lvs -a --noheadings -o lv_attr $1 /${ 2 } _rimage_1 | grep '.*w$'
# Toggle one, set the other
lvchange --writemostly $d0 :y --writemostly $d1 :t $1 /$2
lvs -a --noheadings -o lv_attr $1 /${ 2 } _rimage_0 | grep '.*w$'
lvs -a --noheadings -o lv_attr $1 /${ 2 } _rimage_1 | grep '.*-$'
# Partial flag supercedes writemostly flag
aux disable_dev $d0
lvs -a --noheadings -o lv_attr $1 /${ 2 } _rimage_0 | grep '.*p$'
aux enable_dev $d0
lvs -a --noheadings -o lv_attr $1 /${ 2 } _rimage_0 | grep '.*w$'
# Catch Bad writebehind values
not lvchange --writebehind "invalid" $1 /$2
not lvchange --writebehind -256 $1 /$2
# Set writebehind
[ ! ` lvs --noheadings -o writebehind $1 /$2 ` ]
lvchange --writebehind 512 $1 /$2
[ ` lvs --noheadings -o writebehind $1 /$2 ` -eq 512 ]
# Converting to linear should clear flags and writebehind
lvconvert -m 0 $1 /$2 $d1
lvconvert --type raid1 -m 1 $1 /$2 $d1
[ ! ` lvs --noheadings -o writebehind $1 /$2 ` ]
lvs -a --noheadings -o lv_attr $1 /${ 2 } _rimage_0 | grep '.*-$'
lvs -a --noheadings -o lv_attr $1 /${ 2 } _rimage_1 | grep '.*-$'
}
2013-04-12 00:33:59 +04:00
# run_syncaction_check <VG> <LV>
run_syncaction_check( ) {
local device
local seek
local size
2013-06-20 20:48:15 +04:00
local tmp
2013-04-12 00:33:59 +04:00
2013-06-20 20:48:15 +04:00
printf "#\n#\n#\n# %s/%s (%s): run_syncaction_check\n#\n#\n#\n" \
$1 $2 ` lvs --noheadings -o segtype $1 /$2 `
2013-04-12 00:33:59 +04:00
aux wait_for_sync $1 $2
device = ` lvs -a --noheadings -o devices $1 /${ 2 } _rimage_1 | sed s/\( .\) //`
device = $( sed s/^[ [ :space:] ] *// <<< " $device " )
2013-06-20 20:48:15 +04:00
size = ` lvs -a --noheadings -o size --units 1k $1 /${ 2 } _rimage_1 | sed s/\. 00k//`
2013-04-12 00:33:59 +04:00
size = $( sed s/^[ [ :space:] ] *// <<< " $size " )
size = $(( $size / 2 ))
2013-06-20 20:48:15 +04:00
tmp = ` pvs --noheadings -o mda_size --units 1k $device | sed s/\. 00k//`
tmp = $( sed s/^[ [ :space:] ] *// <<< " $tmp " )
seek = $tmp # Jump over MDA
tmp = ` lvs -a --noheadings -o size --units 1k $1 /${ 2 } _rmeta_1 | sed s/\. 00k//`
tmp = $( sed s/^[ [ :space:] ] *// <<< " $tmp " )
seek = $(( $seek + $tmp )) # Jump over RAID metadata image
seek = $(( $seek + $size )) # Jump halfway through the RAID image
2013-04-12 00:33:59 +04:00
# Check all is normal
if ! lvs --noheadings -o lv_attr $1 /$2 | grep '.*-$' ||
[ ` lvs --noheadings -o mismatches $1 /$2 ` != 0 ] ; then
2013-06-20 20:48:15 +04:00
2013-04-12 00:33:59 +04:00
# I think this is a kernel bug. It happens randomly after
# a RAID device creation. I think the mismatch count
# should not be set unless a check or repair is run.
#
2013-06-20 20:48:15 +04:00
# Neil Brown disagrees that it is a bug. Says mismatch
# count can be anything until a 'check' or 'repair' is
# run.
2013-04-12 00:33:59 +04:00
echo "Strange... RAID has mismatch count after creation."
# Run "check" should turn up clean
lvchange --syncaction check $1 /$2
2013-06-15 13:21:03 +04:00
aux wait_for_sync $1 $2
sync
2013-04-12 00:33:59 +04:00
fi
2013-06-15 13:21:03 +04:00
2013-04-12 00:33:59 +04:00
lvs --noheadings -o lv_attr $1 /$2 | grep '.*-$'
[ ` lvs --noheadings -o mismatches $1 /$2 ` = = 0 ]
# Overwrite the last half of one of the PVs with crap
dd if = /dev/urandom of = $device bs = 1k count = $size seek = $seek
# FIXME: Why is this necessary? caching effects?
# I don't need to do this when testing "real" devices...
lvchange -an $1 /$2 ; lvchange -ay $1 /$2
# "check" should find discrepancies but not change them
# 'lvs' should show results
lvchange --syncaction check $1 /$2
aux wait_for_sync $1 $2
lvs --noheadings -o lv_attr $1 /$2 | grep '.*m$'
[ ` lvs --noheadings -o mismatches $1 /$2 ` != 0 ]
# "repair" will fix discrepancies and record number fixed
lvchange --syncaction repair $1 /$2
aux wait_for_sync $1 $2
lvs --noheadings -o lv_attr $1 /$2 | grep '.*m$'
[ ` lvs --noheadings -o mismatches $1 /$2 ` != 0 ]
# Final "check" should show no mismatches
# 'lvs' should show results
lvchange --syncaction check $1 /$2
aux wait_for_sync $1 $2
lvs --noheadings -o lv_attr $1 /$2 | grep '.*-$'
[ ` lvs --noheadings -o mismatches $1 /$2 ` = = 0 ]
}
# run_refresh_check <VG> <LV>
# Assumes "$dev2" is in the array
run_refresh_check( ) {
2013-06-17 21:38:09 +04:00
local size
2013-06-20 20:48:15 +04:00
printf "#\n#\n#\n# %s/%s (%s): run_refresh_check\n#\n#\n#\n" \
$1 $2 ` lvs --noheadings -o segtype $1 /$2 `
2013-04-12 00:33:59 +04:00
aux wait_for_sync $1 $2
2013-06-17 21:38:09 +04:00
size = ` lvs -a --noheadings -o size --units 1k $1 /$2 | sed s/\. 00k//`
size = $( sed s/^[ [ :space:] ] *// <<< " $size " )
2013-04-12 00:33:59 +04:00
# Disable dev2 and do some I/O to make the kernel notice
aux disable_dev " $dev2 "
2013-06-17 21:38:09 +04:00
dd if = /dev/urandom of = /dev/$1 /$2 bs = 1k count = $size
2013-04-12 00:33:59 +04:00
# Check for 'p'artial flag
lvs --noheadings -o lv_attr $1 /$2 | grep '.*p$'
aux enable_dev " $dev2 "
# Check for 'r'efresh flag
lvs --noheadings -o lv_attr $1 /$2 | grep '.*r$'
lvchange --refresh $1 /$2
2013-06-20 20:48:15 +04:00
aux wait_for_sync $1 $2
lvs --noheadings -o lv_attr $1 /$2 | grep '.*-$'
2013-04-12 00:33:59 +04:00
# Writing random data above should mean that the devices
# were out-of-sync. The refresh should have taken care
# of properly reintegrating the device. If any mismatches
# are repaired, it will show up in the 'lvs' output.
lvchange --syncaction repair $1 /$2
aux wait_for_sync $1 $2
lvs --noheadings -o lv_attr $1 /$2 | grep '.*-$'
}
2013-06-20 20:48:15 +04:00
# run_checks <VG> <LV> [snapshot_dev]
2013-04-12 00:33:59 +04:00
run_checks( ) {
2013-06-20 20:48:15 +04:00
# Without snapshots
RAID: Add writemostly/writebehind support for RAID1
'lvchange' is used to alter a RAID 1 logical volume's write-mostly and
write-behind characteristics. The '--writemostly' parameter takes a
PV as an argument with an optional trailing character to specify whether
to set ('y'), unset ('n'), or toggle ('t') the value. If no trailing
character is given, it will set the flag.
Synopsis:
lvchange [--writemostly <PV>:{t|y|n}] [--writebehind <count>] vg/lv
Example:
lvchange --writemostly /dev/sdb1:y --writebehind 512 vg/raid1_lv
The last character in the 'lv_attr' field is used to show whether a device
has the WriteMostly flag set. It is signified with a 'w'. If the device
has failed, the 'p'artial flag has priority.
Example ("nosync" raid1 with mismatch_cnt and writemostly):
[~]# lvs -a --segment vg
LV VG Attr #Str Type SSize
raid1 vg Rwi---r-m 2 raid1 500.00m
[raid1_rimage_0] vg Iwi---r-- 1 linear 500.00m
[raid1_rimage_1] vg Iwi---r-w 1 linear 500.00m
[raid1_rmeta_0] vg ewi---r-- 1 linear 4.00m
[raid1_rmeta_1] vg ewi---r-- 1 linear 4.00m
Example (raid1 with mismatch_cnt, writemostly - but failed drive):
[~]# lvs -a --segment vg
LV VG Attr #Str Type SSize
raid1 vg rwi---r-p 2 raid1 500.00m
[raid1_rimage_0] vg Iwi---r-- 1 linear 500.00m
[raid1_rimage_1] vg Iwi---r-p 1 linear 500.00m
[raid1_rmeta_0] vg ewi---r-- 1 linear 4.00m
[raid1_rmeta_1] vg ewi---r-p 1 linear 4.00m
A new reportable field has been added for writebehind as well. If
write-behind has not been set or the LV is not RAID1, the field will
be blank.
Example (writebehind is set):
[~]# lvs -a -o name,attr,writebehind vg
LV Attr WBehind
lv rwi-a-r-- 512
[lv_rimage_0] iwi-aor-w
[lv_rimage_1] iwi-aor--
[lv_rmeta_0] ewi-aor--
[lv_rmeta_1] ewi-aor--
Example (writebehind is not set):
[~]# lvs -a -o name,attr,writebehind vg
LV Attr WBehind
lv rwi-a-r--
[lv_rimage_0] iwi-aor-w
[lv_rimage_1] iwi-aor--
[lv_rmeta_0] ewi-aor--
[lv_rmeta_1] ewi-aor--
2013-04-15 22:59:46 +04:00
if aux target_at_least dm-raid 1 1 0; then
run_writemostly_check $1 $2
fi
2013-04-12 00:33:59 +04:00
if aux target_at_least dm-raid 1 5 0; then
run_syncaction_check $1 $2
fi
if aux target_at_least dm-raid 1 5 1; then
run_refresh_check $1 $2
fi
2013-06-20 20:48:15 +04:00
# With snapshots
if [ ! -z $3 ] ; then
lvcreate -s $1 /$2 -l 4 -n snap $3
if aux target_at_least dm-raid 1 1 0; then
run_writemostly_check $1 $2
fi
if aux target_at_least dm-raid 1 5 0; then
run_syncaction_check $1 $2
fi
if aux target_at_least dm-raid 1 5 1; then
run_refresh_check $1 $2
fi
lvremove -ff $1 /snap
fi
2013-04-12 00:33:59 +04:00
}
########################################################
# MAIN
########################################################
lvcreate --type raid1 -m 1 -l 2 -n $lv1 $vg " $dev1 " " $dev2 "
2013-06-20 20:48:15 +04:00
run_checks $vg $lv1 " $dev3 "
2013-04-12 00:33:59 +04:00
lvremove -ff $vg
lvcreate --type raid4 -i 2 -l 4 -n $lv1 $vg " $dev1 " " $dev2 " " $dev3 " " $dev4 "
2013-06-20 20:48:15 +04:00
run_checks $vg $lv1 " $dev5 "
2013-04-12 00:33:59 +04:00
lvremove -ff $vg
lvcreate --type raid5 -i 2 -l 4 -n $lv1 $vg " $dev1 " " $dev2 " " $dev3 " " $dev4 "
2013-06-20 20:48:15 +04:00
run_checks $vg $lv1 " $dev5 "
2013-04-12 00:33:59 +04:00
lvremove -ff $vg
lvcreate --type raid6 -i 3 -l 6 -n $lv1 $vg \
" $dev1 " " $dev2 " " $dev3 " " $dev4 " " $dev5 "
2013-06-20 20:48:15 +04:00
run_checks $vg $lv1 " $dev6 "
2013-04-12 00:33:59 +04:00
lvremove -ff $vg
lvcreate --type raid10 -m 1 -i 2 -l 4 -n $lv1 $vg \
" $dev1 " " $dev2 " " $dev3 " " $dev4 "
2013-06-20 20:48:15 +04:00
run_checks $vg $lv1 " $dev5 "
2013-04-12 00:33:59 +04:00
lvremove -ff $vg