summaryrefslogtreecommitdiffstats
path: root/tests/m_rootgnutar/script
blob: 79fd2225b4e763858a61900737130eb6e2061b35 (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
# vim: filetype=sh

use_mkgnutar=

test_description="create fs image from GNU tarball"
if ! test -x "$DEBUGFS_EXE"; then
	echo "$test_name: $test_description: skipped (no debugfs)"
	return 0
fi
if [ "$(grep -c 'define HAVE_ARCHIVE_H' ../lib/config.h)" -eq 0 ]; then
	echo "$test_name: $test_description: skipped (no libarchive)"
	exit 0
fi

if test -z "$use_mkgnutar" ; then
    if type ztar > /dev/null 2>&1 && \
	    tar --version 2>&1 | head -1 | grep -q "GNU tar" ; then
	TAR=tar
    elif type gtar > /dev/null 2>&1 && \
	    gtar --version 2>&1 | head -1 | grep -q "GNU tar" ; then
	TAR=gtar
    else
	# if GNU tar is not available, fall back to using mkgnutar.pl
	use_mkgnutar=yes
#	echo "$test_name: $test_description: skipped (no GNU tar)"
#	exit 0
    fi
fi

MKFS_TAR="$TMPFILE.tar"
MKFS_DIR="$TMPFILE.dir"
OUT="$test_name.log"
EXP="$test_dir/expect"
DEBUGFS_EXE_MTIME=$(perl -e 'print((stat ($ARGV[0]))[9])' "$DEBUGFS_EXE")

# we put everything in a subdir because we cannot rdump the root as that would
# require permissions to changing ownership of /lost+found
rm -rf "$MKFS_DIR"
mkdir -p "$MKFS_DIR/test"
touch "$MKFS_DIR/test/emptyfile"
dd if=/dev/zero bs=1024 count=32 2> /dev/null | tr '\0' 'a' > "$MKFS_DIR/test/bigfile"
dd if=/dev/zero of="$MKFS_DIR/test/zerofile" bs=1 count=1 seek=1024 2> /dev/null
ln -s /silly_bs_link "$MKFS_DIR/test/silly_bs_link"
mkdir "$MKFS_DIR/test/emptydir"
mkdir "$MKFS_DIR/test/dir"
echo "will be overwritten" > "$MKFS_DIR/test/dir/file"

if test -z "$use_mkgnutar"; then
	# debugfs rdump does not preserve the timestamps when it extracts the
	# files so we ignore them by using tar --clamp-mtime
	# first write a partial tar
    $TAR --sort=name -C "$MKFS_DIR" --mtime="$DEBUGFS_EXE" --clamp-mtime \
	 --format=gnu -cf "$MKFS_TAR.dupl" test
	# now overwrite the contents of a file
	echo "Test me" > "$MKFS_DIR/test/dir/file"
	# and update the tar so that it contains two entries for the same file
	# we need this to test the code path that first unlinks and then overwrites an
	# existing file
	$TAR -C "$MKFS_DIR" --mtime="$DEBUGFS_EXE" --clamp-mtime \
	     --format=gnu -rf "$MKFS_TAR.dupl" test/dir/file
	# also add a duplicate directory entry because those must not be unlinked
	echo test | $TAR -C "$MKFS_DIR" --mtime="$DEBUGFS_EXE" --clamp-mtime \
			 --format=gnu -rf "$MKFS_TAR.dupl" --no-recursion \
			 --verbatim-files-from --files-from=-
	# also create a tarball of the directory with only one entry per file
	$TAR --sort=name -C "$MKFS_DIR" --mtime="$DEBUGFS_EXE" --clamp-mtime \
	     --format=gnu -cf "$MKFS_TAR.uniq" test
else
	# same as above but without using GNU tar
	perl $test_dir/mkgnutar.pl --nopadding --directory="$MKFS_DIR" --mtime "$DEBUGFS_EXE_MTIME" test > "$MKFS_TAR.dupl"
	echo "Test me" > "$MKFS_DIR/test/dir/file"
	perl $test_dir/mkgnutar.pl --nopadding --directory="$MKFS_DIR" --mtime "$DEBUGFS_EXE_MTIME" test/dir/file >> "$MKFS_TAR.dupl"
	perl $test_dir/mkgnutar.pl --nopadding --directory="$MKFS_DIR" --mtime "$DEBUGFS_EXE_MTIME" --no-recursion test/ >> "$MKFS_TAR.dupl"
	# add end-of-archive entry
	truncate -s +1024 "$MKFS_TAR.dupl"
	# pad to a multiple of the record size
	truncate -s %10240 "$MKFS_TAR.dupl"
	perl $test_dir/mkgnutar.pl --directory="$MKFS_DIR" --mtime "$DEBUGFS_EXE_MTIME" test > "$MKFS_TAR.uniq"
fi

rm -r "$MKFS_DIR"

cat > "$TMPFILE.cmd1" << ENDL
stat /test/emptyfile
stat /test/bigfile
stat /test/zerofile
stat /test/silly_bs_link
stat /test/emptydir
stat /test/dir
stat /test/dir/file
ENDL

cat > "$TMPFILE.cmd2" << ENDL
ex /test/emptyfile
ex /test/bigfile
ex /test/zerofile
ex /test/silly_bs_link
ex /test/emptydir
ex /test/dir
ex /test/dir/file
ENDL

# Create two file systems, one for each tar that was created above. The
# tarballs differ but should result in the same filesystem contents
#
for ext in uniq dupl; do
	mkdir "$MKFS_DIR"
	{
		$MKE2FS -q -F -o Linux -T ext4 -O metadata_csum,64bit -E lazy_itable_init=1 -b 1024 -d "$MKFS_TAR.$ext" "$TMPFILE.$ext" 16384 2>&1;
		echo Exit status is $?;
		$DUMPE2FS "$TMPFILE.$ext" 2>&1;
		echo Exit status is $?;
		$DEBUGFS -f "$TMPFILE.cmd1" "$TMPFILE.$ext" 2>&1 | grep -E "(stat|Size:|Type:|Links:|Blockcount:)"
		echo Exit status is $?;
		$DEBUGFS -f "$TMPFILE.cmd2" "$TMPFILE.$ext" 2>&1;
		echo Exit status is $?;
		$DEBUGFS -R "dump /test/dir/file $TMPFILE.testme" "$TMPFILE.$ext" 2>&1;
		echo Exit status is $?;
		# extract the files and directories from the image and tar them
		# again to make sure that a tarball from the image contents is
		# bit-by-bit identical to the tarball the image was created
		# from -- essentially this checks whether a roundtrip from tar
		# to ext4 to tar remains identical
		$DEBUGFS -R "rdump /test $MKFS_DIR" "$TMPFILE.$ext" 2>&1;
		echo Exit status is $?;
		# debugfs rdump does not preserve the timestamps when it extracts the
		if test -z "$use_mkgnutar"; then
			# files so we ignore them by using tar --clamp-mtime
		    $TAR --sort=name -C "$MKFS_DIR" \
			 --mtime="$DEBUGFS_EXE" --clamp-mtime --format=gnu \
			 -cvf "$TMPFILE.new.tar" test 2>&1;
		else
			perl $test_dir/mkgnutar.pl --verbose --directory="$MKFS_DIR" --mtime "$DEBUGFS_EXE_MTIME" test 2>&1 > "$TMPFILE.new.tar";
		fi;
		echo Exit status is $?;
		$FSCK -f -n "$TMPFILE.$ext" 2>&1;
		echo Exit status is $?;
		# independent from which tarball the ext4 image was created,
		# the tarball created from the files in it should be bit-by-bit
		# identical to the tarball without duplicate entries
		cmp "$MKFS_TAR.uniq" "$TMPFILE.new.tar" 2>&1;
		echo Exit status is $?;
	} | sed -f "$cmd_dir/filter.sed" -f "$test_dir/output.sed" -e "s;$TMPFILE.$ext;test.img;" | {
		# In the first pass, store the output and append to the log
		# file. In the second pass, compare the output to the output
		# to the one from the first.
		case $ext in
			uniq) tee "$TMPFILE.log" >> "$OUT";;
			dupl) cmp - "$TMPFILE.log" >> "$OUT" 2>&1 || echo "cmp failed" >> "$OUT";;
		esac
	}
	rm -r "$MKFS_DIR" "$TMPFILE.new.tar"
done

# Do the verification
cmp -s "$OUT" "$EXP"
status=$?

if [ "$status" = 0 ] ; then
	echo "$test_name: $test_description: ok"
	touch "$test_name.ok"
else
	echo "$test_name: $test_description: failed"
	diff $DIFF_OPTS "$EXP" "$OUT" > "$test_name.failed"
fi

rm -rf "$MKFS_TAR.dupl" "$MKFS_TAR.uniq" "$TMPFILE.cmd1" "$TMPFILE.cmd2" \
   "$TMPFILE.log" "$TMPFILE.dupl" "$TMPFILE.uniq" "$TMPFILE.testme"
unset MKFS_TAR MKFS_DIR OUT EXP