summaryrefslogtreecommitdiff
path: root/common/filestreams
blob: b3aee27099928c44a1d7e0c89a516f2fcaea6bf6 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
##/bin/bash
#
# Copyright (c) 2007 Silicon Graphics, Inc.  All Rights Reserved.
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License as
# published by the Free Software Foundation.
#
# This program is distributed in the hope that it would be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write the Free Software Foundation,
# Inc.,  51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
#
#
# Core of filestreams tests.
#

_check_filestreams_support()
{
	local irix_timeout_sysvar="xfs_mfstream_timeout"
	local linux_timeout_procvar="/proc/sys/fs/xfs/filestream_centisecs"
	local streams_avail=""
	if [ "$HOSTOS" == "IRIX" ]; then
		# check for the filestreams timeout systune variable in irix
		streams_avail=`systune $irix_timeout_sysvar 2>&1 |
			perl -ne 'if (/'$irix_timeout_sysvar'\s+=\s+\d+/) {print "true"}'`
	else
		# check for the filestreams timeout proc entry in linux
		[ -f $linux_timeout_procvar ] && streams_avail="true"
	fi

	if [ "$streams_avail" == "true" ]; then
		return 0
	else
		return 1
	fi
}

_set_stream_timeout_centisecs()
{
	local new_timeout_csecs=$1
	local irix_timeout_sysvar="xfs_mfstream_timeout"
	local linux_timeout_procvar="/proc/sys/fs/xfs/filestream_centisecs"
	if [ "$HOSTOS" == "IRIX" ]; then
		echo y | systune -r $irix_timeout_sysvar $new_timeout_csecs >/dev/null
	else
		echo $new_timeout_csecs > $linux_timeout_procvar
	fi
}

_do_stream()
{
	local directory_name=$1
	local files=$2
	local file_size=$3
	local bsize=$4
	local iflag=$5
	local dio=$6
	local blocks_in_file=`expr $file_size / $bsize`

	mkdir $directory_name
	if [ "$iflag" = "1" -a "$HOSTOS" != "IRIX" ]; then
		$XFS_IO_PROG -x -c "chattr +S" $directory_name \
			|| _fail "chattr of filestream flag"
	fi
	cd $directory_name

	local dd_cmd=""
	if [ "$HOSTOS" == "IRIX" ]; then
		# for irix use lmdd
		dd_cmd="lmdd"
		[ "$dio" = "1" ] && dd_cmd="$dd_cmd odirect=1"
	else
		# for linux use dd
		dd_cmd="dd"
		[ "$dio" = "1" ] && dd_cmd="$dd_cmd oflag=direct"
	fi
	dd_cmd="$dd_cmd if=/dev/zero bs=${bsize} count=${blocks_in_file}"

	local i=1
	while [ $i -le $files ]; do
		$dd_cmd of=frame-${i} 2>&1 | grep -v records | grep -v secs
		i=`expr $i + 1`
	done
}

_filter_agno()
{
        # the ag number is in column 4 of xfs_bmap output
        perl -ne '
                $ag = (split /\s+/)[4] ;
		if ($ag =~ /\d+/) {print "$ag "} ;
        '
}

_get_stream_ags()
{
        local directory_name=$1
        local stream_ags=`xfs_bmap -vp ${directory_name}/* | _filter_agno`
        echo $stream_ags
}

_check_for_dupes()
{
        # check for duplicate numbers between two space seperated vars
        local num_str_one=$1
        local num_str_two=$2

        local this_num_one
        local this_num_two
        for this_num_one in $num_str_one; do
                for this_num_two in $num_str_two; do
                        if [ "$this_num_one" == "$this_num_two" ]; then
				echo "duplicate AG $this_num_one found" \
					>> $RESULT_DIR/$seq.full
				return 1
			fi
                done
        done
        return 0
}

_test_streams() {

	echo "# testing $* ...."
	local agcount="$1"
	local agsize="$2" # in MB
	local stream_count="$3"
	local stream_files="$4"
	local stream_file_size=`expr $5 \* 1024 \* 1024`
	local use_iflag="$6"
	local use_directio="$7"
	local expected_result="$8"	# "fail" if failure is expected

	local size=`expr $agsize \* 1024 \* 1024 \* $agcount`
	_scratch_mkfs_xfs -dsize=$size,agcount=$agcount >/dev/null 2>&1 \
		|| _fail "mkfs failed"

	if [ "$use_iflag" = "0" -o "$HOSTOS" == "IRIX" ]; then
		# mount using filestreams mount option
		_scratch_mount "-o filestreams" \
			|| _fail "filestreams mount failed"
	else
		# test will set inode flag
		_scratch_mount || _fail "mount failed"
	fi

	cd $SCRATCH_MNT

	# start $stream_count streams
	# each stream writes ($stream_files x $stream_file_size)M
	echo "# streaming"
	local stream_pids=""
	local stream_index=1
	while [ $stream_index -le $stream_count ]; do
		_do_stream stream${stream_index}-dir $stream_files \
			$stream_file_size 1048576 $use_iflag $use_directio &
		stream_pids="$stream_pids $!"
		stream_index=`expr $stream_index + 1`
	done

	# wait for streams to finish
	# XXX wait here not needed? -dgc
	wait $stream_pids

	# sync the buffered streams out in parallel
	# _get_stream_ags does a xfs_bmap which syncs delayed allocations
	echo "# sync AGs..."
	local ag_sync_pids=""
	stream_index=1
	while [ $stream_index -le $stream_count ]; do
		_get_stream_ags stream${stream_index}-dir > /dev/null 2>&1 &
		ag_sync_pids="$ag_sync_pids $!"
		stream_index=`expr $stream_index + 1`
	done

	# wait for syncs to finish
	wait $ag_sync_pids

	# confirm streams are in seperate AGs
	echo "# checking stream AGs..."
	local this_stream_ags=""
	local ags_seen=""
	local num_streams_with_matching_ags=0
	stream_index=1
	while [ $stream_index -le $stream_count ]; do
		this_stream_ags=`_get_stream_ags stream${stream_index}-dir`
		echo "stream $stream_index AGs: $this_stream_ags" >> $RESULT_DIR/$seq.full
		_check_for_dupes "$ags_seen" "$this_stream_ags"
		if [ $? -ne 0 ]; then
			# this stream is not in seperate AGs to previous streams
			num_streams_with_matching_ags=`expr $num_streams_with_matching_ags + 1`
		fi
		ags_seen="$ags_seen $this_stream_ags"
		stream_index=`expr $stream_index + 1`
	done

	_cleanup_streams_umount
	if [ "$expected_result" != "fail" ]; then
		if [ $num_streams_with_matching_ags -eq 0 ]; then
			# all streams in seperate AGs, as expected
			echo "+ passed, streams are in seperate AGs"
		else
			# streams with matching AGs, should be seperate
			_fail "- failed, $num_streams_with_matching_ags streams with matching AGs"
		fi
	else
		# expecting streams to have overlapped
		if [ $num_streams_with_matching_ags -eq 0 ]; then
			# all streams in seperate AGs, should have overlapped
			_fail "- streams are in seperate AGs, expected _matching_"
		else
			# streams with matching AGs, as expected
			echo "+ expected failure, matching AGs"
		fi
	fi
	return 0
}

_cleanup_streams_umount()
{
	cd /
	rm -rf ${SCRATCH_MNT}/stream*
	umount $SCRATCH_DEV 2>/dev/null
}