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
|