tests: Add a test of relative paths, to make sure we don't break them.

In some places we turn relative paths passed by the caller into
absolute paths: for example in the libvirt backend, all relative paths
to disk images have to be turned into absolute paths (by calling
realpath) because otherwise libvirt doesn't work.

This has the potential to break things, especially considering that
qemu uses the path passed to it in order to resolve the relative paths
of backing files.

For example consider the case where 'overlay' is a symbolic link to
/dev/dm-1, but /dev/dm-1 contains a qcow2 which references './backing'
as its backing file.  If we rewrote 'overlay' to '/dev/dm-1', then
qemu would try to look up '/dev/backing' for the backing file and
fail.

See also:

https://bugzilla.redhat.com/show_bug.cgi?id=1053684
https://www.redhat.com/archives/libguestfs/2014-January/thread.html#00087
This commit is contained in:
Richard W.M. Jones
2014-01-17 15:07:55 +00:00
parent 96737fc5b7
commit e22bd2dcd2
4 changed files with 183 additions and 0 deletions

View File

@@ -62,6 +62,7 @@ SUBDIRS += tests/http
SUBDIRS += tests/syslinux
SUBDIRS += tests/journal
SUBDIRS += tests/fuzz
SUBDIRS += tests/relative-paths
SUBDIRS += tests/regressions
endif

View File

@@ -1767,6 +1767,7 @@ AC_CONFIG_FILES([Makefile
tests/protocol/Makefile
tests/qemu/Makefile
tests/regressions/Makefile
tests/relative-paths/Makefile
tests/rsync/Makefile
tests/selinux/Makefile
tests/syslinux/Makefile

View File

@@ -0,0 +1,37 @@
# libguestfs
# Copyright (C) 2014 Red Hat Inc.
#
# 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; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will 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 to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
# Test relative paths to backing files. Mainly this is a test that we
# don't break this.
#
# See eg:
# https://bugzilla.redhat.com/show_bug.cgi?id=1053684
# https://www.redhat.com/archives/libguestfs/2014-January/thread.html#00087
# (and more)
include $(top_srcdir)/subdir-rules.mk
TESTS = \
test-relative-paths.sh
TESTS_ENVIRONMENT = $(top_builddir)/run --test
check-valgrind:
$(MAKE) VG="$(top_builddir)/run @VG@" check
EXTRA_DIST = \
$(TESTS)

View File

@@ -0,0 +1,144 @@
#!/bin/bash -
# libguestfs
# Copyright (C) 2014 Red Hat Inc.
#
# 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; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will 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 to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
set -e
if [ -n "$SKIP_TEST_RELATIVE_PATHS_SH" ]; then
echo "$0: skipped (environment variable set)"
exit 77
fi
# UML doesn't support qcow2. Conceivably there might be a similar
# problem with UML COW images which would require a separate test.
if [ "$($guestfish get-backend)" = "uml" ]; then
echo "$0: skipping test because uml backend does not support qcow2"
exit 77
fi
rm -f backing*
rm -f overlay*
rm -f link*
rm -rf dir1
# Set up a set of disk images involving relative paths.
mkdir -p dir1/dir2
# Regular overlay files.
qemu-img create -f qcow2 backing1 10M
qemu-img create -f qcow2 -b $(pwd)/backing1 overlay1
qemu-img create -f qcow2 backing2 10M
qemu-img create -f qcow2 -b backing2 overlay2
qemu-img create -f qcow2 backing3 10M
qemu-img create -f qcow2 -b ./backing3 overlay3
qemu-img create -f qcow2 backing4 10M
qemu-img create -f qcow2 -b ../../tests/relative-paths/backing4 overlay4
qemu-img create -f qcow2 backing5 10M
pushd dir1
qemu-img create -f qcow2 -b ../backing5 overlay5
popd
qemu-img create -f qcow2 backing6 10M
pushd dir1/dir2
qemu-img create -f qcow2 -b ../../backing6 overlay6
popd
qemu-img create -f qcow2 dir1/backing7 10M
qemu-img create -f qcow2 -b dir1/backing7 overlay7
qemu-img create -f qcow2 dir1/dir2/backing8 10M
qemu-img create -f qcow2 -b dir1/dir2/backing8 overlay8
qemu-img create -f qcow2 dir1/dir2/backing9 10M
pushd dir1
qemu-img create -f qcow2 -b dir2/backing9 overlay9
popd
qemu-img create -f qcow2 dir1/backing10 10M
pushd dir1/dir2
qemu-img create -f qcow2 -b ../backing10 overlay10
popd
qemu-img create -f qcow2 dir1/backing11 10M
pushd dir1
qemu-img create -f qcow2 -b backing11 overlay11
popd
# Symbolic links.
qemu-img create -f qcow2 backing12 10M
qemu-img create -f qcow2 -b backing12 overlay12
ln -s overlay12 link12
qemu-img create -f qcow2 dir1/backing13 10M
pushd dir1
qemu-img create -f qcow2 -b backing13 overlay13
popd
ln -s dir1/overlay13 link13
qemu-img create -f qcow2 dir1/dir2/backing14 10M
pushd dir1
qemu-img create -f qcow2 -b dir2/backing14 overlay14
popd
pushd dir1/dir2
ln -s ../overlay14 link14
popd
qemu-img create -f qcow2 dir1/backing15 10M
pushd dir1/dir2
qemu-img create -f qcow2 -b ../backing15 overlay15
popd
pushd dir1
ln -s dir2/overlay15 link15
popd
# Note that add-drive readonly/readwrite are substantially different
# codepaths in most backends, so we should test each separately.
for ro in readonly:true readonly:false; do
for prefix in "./" "" "$(pwd)/"; do
$VG ../../fish/guestfish <<EOF
add-drive ${prefix}overlay1 $ro format:qcow2
add-drive ${prefix}overlay2 $ro format:qcow2
add-drive ${prefix}overlay3 $ro format:qcow2
add-drive ${prefix}overlay4 $ro format:qcow2
add-drive ${prefix}dir1/overlay5 $ro format:qcow2
add-drive ${prefix}dir1/dir2/overlay6 $ro format:qcow2
add-drive ${prefix}overlay7 $ro format:qcow2
add-drive ${prefix}overlay8 $ro format:qcow2
add-drive ${prefix}dir1/overlay9 $ro format:qcow2
add-drive ${prefix}dir1/dir2/overlay10 $ro format:qcow2
add-drive ${prefix}dir1/overlay11 $ro format:qcow2
add-drive ${prefix}link12 $ro format:qcow2
add-drive ${prefix}link13 $ro format:qcow2
add-drive ${prefix}dir1/dir2/link14 $ro format:qcow2
add-drive ${prefix}dir1/link15 $ro format:qcow2
run
# Just forces the drives to be opened.
<! for n in a b c d e f g h i j k l m n o; do echo blockdev-getsize64 /dev/sd\$n; done
EOF
done
done
rm -r dir1
rm backing*
rm overlay*
rm link*