summaryrefslogtreecommitdiff
path: root/common/filestreams
blob: 62acb47cb695a247f2f70653cb5687d5df65ccb2 (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
##/bin/bash
# SPDX-License-Identifier: GPL-2.0
# Copyright (c) 2007 Silicon Graphics, Inc.  All Rights Reserved.
#
# Core of filestreams tests.

_check_filestreams_support()
{
	[ -f /proc/sys/fs/xfs/filestream_centisecs ]
}

_set_stream_timeout_centisecs()
{
	echo $1 > /proc/sys/fs/xfs/filestream_centisecs
}

_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" ]; then
		$XFS_IO_PROG -x -c "chattr +S" $directory_name \
			|| _fail "chattr of filestream flag"
	fi
	cd $directory_name

	local dd_cmd="dd"
	[ "$dio" = "1" ] && dd_cmd="$dd_cmd oflag=direct"
	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" \
					>> $seqres.full
				return 1
			fi
                done
        done
        return 0
}

_test_streams() {

	echo "# testing $* ...." | tee -a $seqres.full
	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

	# Disable the scratch rt device to avoid test failures relating to the
	# rt bitmap consuming free space in our small data device and throwing
	# off the filestreams allocator.
	unset SCRATCH_RTDEV

	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" ]; then
		# mount using filestreams mount option
		_try_scratch_mount "-o filestreams" \
			|| _fail "filestreams mount failed"
	else
		# test will set inode flag
		_scratch_mount
	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" >> $seqres.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*
	_scratch_unmount 2>/dev/null
}