blob: 79fd2225b4e763858a61900737130eb6e2061b35 [file] [log] [blame]
# 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