1# Copyright (C) 2009 Red Hat, Inc. All rights reserved.
2#
3# This copyrighted material is made available to anyone wishing to use,
4# modify, copy, or redistribute it subject to the terms and conditions
5# of the GNU General Public License v.2.
6#
7# You should have received a copy of the GNU General Public License
8# along with this program; if not, write to the Free Software Foundation,
9# Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
10
11# skip this test if mdadm or sfdisk (or others) aren't available
12which mdadm || exit 200
13which sfdisk || exit 200
14which perl || exit 200
15which awk || exit 200
16which cut || exit 200
17test -f /proc/mdstat || exit 200
18
19. ./test-utils.sh
20
21prepare_lvmconf '[ "a|/dev/md.*|", "a/dev\/mapper\/.*$/", "r/.*/" ]'
22aux prepare_devs 2
23
24# Have MD use a non-standard name to avoid colliding with an existing MD device
25# - mdadm >= 3.0 requires that non-standard device names be in /dev/md/
26# - newer mdadm _completely_ defers to udev to create the associated device node
27mdadm_maj=$(mdadm --version 2>&1 | perl -pi -e 's|.* v(\d+).*|\1|')
28[ $mdadm_maj -ge 3 ] && \
29    mddev=/dev/md/md_lvm_test0 || \
30    mddev=/dev/md_lvm_test0
31
32cleanup_md() {
33    # sleeps offer hack to defeat: 'md: md127 still in use'
34    # see: https://bugzilla.redhat.com/show_bug.cgi?id=509908#c25
35    sleep 2
36    mdadm --stop $mddev
37    if [ -b "$mddev" ]; then
38        # mdadm doesn't always cleanup the device node
39	sleep 2
40	rm -f $mddev
41    fi
42    teardown_
43}
44
45# create 2 disk MD raid0 array (stripe_width=128K)
46[ -b "$mddev" ] && exit 200
47mdadm --create $mddev --auto=md --level 0 --raid-devices=2 --chunk 64 $dev1 $dev2
48trap 'aux cleanup_md' EXIT # cleanup this MD device at the end of the test
49
50# Test alignment of PV on MD without any MD-aware or topology-aware detection
51# - should treat $mddev just like any other block device
52pv_align="192.00k"
53pvcreate --metadatasize 128k \
54    --config 'devices {md_chunk_alignment=0 data_alignment_detection=0 data_alignment_offset_detection=0}' \
55    $mddev
56check_pv_field_ $mddev pe_start $pv_align
57
58# Test md_chunk_alignment independent of topology-aware detection
59pv_align="256.00k"
60pvcreate --metadatasize 128k \
61    --config 'devices {data_alignment_detection=0 data_alignment_offset_detection=0}' \
62    $mddev
63check_pv_field_ $mddev pe_start $pv_align
64
65# Get linux minor version
66linux_minor=$(echo `uname -r` | cut -d'.' -f3 | cut -d'-' -f1)
67
68# Test newer topology-aware alignment detection
69if [ $linux_minor -gt 31 ]; then
70    pv_align="256.00k"
71    pvcreate --metadatasize 128k \
72	--config 'devices { md_chunk_alignment=0 }' $mddev
73    check_pv_field_ $mddev pe_start $pv_align
74fi
75
76# partition MD array directly, depends on blkext in Linux >= 2.6.28
77if [ $linux_minor -gt 27 ]; then
78    # create one partition
79    sfdisk $mddev <<EOF
80,,83
81EOF
82    # make sure partition on MD is _not_ removed
83    # - tests partition -> parent lookup via sysfs paths
84    not pvcreate --metadatasize 128k $mddev
85
86    # verify alignment_offset is accounted for in pe_start
87    # - topology infrastructure is available in Linux >= 2.6.31
88    # - also tests partition -> parent lookup via sysfs paths
89
90    # Oh joy: need to lookup /sys/block/md127 rather than /sys/block/md_lvm_test0
91    mddev_maj_min=$(ls -lL $mddev | awk '{ print $5 $6 }' | perl -pi -e 's|,|:|')
92    mddev_p_sysfs_name=$(echo /sys/dev/block/${mddev_maj_min}/*p1)
93    base_mddev_p=`basename $mddev_p_sysfs_name`
94    mddev_p=/dev/${base_mddev_p}
95
96    # Checking for 'alignment_offset' in sysfs implies Linux >= 2.6.31
97    sysfs_alignment_offset=/sys/dev/block/${mddev_maj_min}/${base_mddev_p}/alignment_offset
98    [ -f $sysfs_alignment_offset ] && \
99	alignment_offset=`cat $sysfs_alignment_offset` || \
100	alignment_offset=0
101
102    if [ "$alignment_offset" = "512" ]; then
103	pv_align="256.50k"
104	pvcreate --metadatasize 128k $mddev_p
105	check_pv_field_ $mddev_p pe_start $pv_align
106	pvremove $mddev_p
107    elif [ "$alignment_offset" = "2048" ]; then
108	pv_align="258.00k"
109	pvcreate --metadatasize 128k $mddev_p
110	check_pv_field_ $mddev_p pe_start $pv_align
111	pvremove $mddev_p
112    fi
113fi
114