[Parted-commits] GNU Parted Official Repository: Changes to 'master'

Jim Meyering meyering at alioth.debian.org
Sat Nov 20 08:08:21 UTC 2010


 NEWS                             |    3 +
 bootstrap.conf                   |    1 
 configure.ac                     |    3 +
 libparted/arch/linux.c           |   14 +++++++
 libparted/tests/Makefile.am      |    9 +++-
 libparted/tests/t2100-zerolen.sh |   75 +++++++++++++++++++++++++++++++++++++++
 libparted/tests/zerolen.c        |   52 +++++++++++++++++++++++++++
 tests/test-lib.sh                |   16 ++++++++
 8 files changed, 170 insertions(+), 3 deletions(-)

New commits:
commit 783b762aefde2c25f546ba753ac0423a28aaa845
Author: Colin Watson <cjwatson at ubuntu.com>
Date:   Wed Nov 17 15:14:50 2010 +0000

    libparted: ignore zero-length devices
    
    * bootstrap.conf (gnulib_modules): Add xstrtoll.
    * configure.ac: Create DYNAMIC_LOADING output variable.
    * libparted/arch/linux.c (_device_get_length): Return the value of
    PARTED_TEST_DEVICE_LENGTH if set in the environment, strictly for use by
    the test suite.
    (init_generic): If geometry probing fails because the device was
    zero-length, return quietly rather than throwing an exception.  This has
    been observed in the wild with cciss devices, and it's difficult for
    partitioners to tell the difference between that and more serious
    errors.
    * libparted/tests/Makefile.am (TESTS): Add t2100-zerolen.sh.
    (check_PROGRAMS): Add zerolen.
    (zerolen_SOURCES): Add.
    (TESTS_ENVIRONMENT): Add DYNAMIC_LOADING and ENABLE_DEVICE_MAPPER.
    * libparted/tests/t2100-zerolen.sh: New file.
    * libparted/tests/zerolen.c: New file.
    * tests/test-lib.sh (wait_for_dev_to_appear_): New function, copied from
    tests/t-local.sh.
    * NEWS (Bug fixes): Mention it.

diff --git a/NEWS b/NEWS
index 4979b90..65e5a69 100644
--- a/NEWS
+++ b/NEWS
@@ -17,6 +17,9 @@ GNU parted NEWS                                    -*- outline -*-
   an msdos partition table on a very small device (smaller than one cylinder)
   is now recognized.  [bug introduced in parted-2.2]
 
+  libparted: zero-length devices (other than files) are ignored rather than
+  throwing an exception.
+
 
 * Noteworthy changes in release 2.3 (2010-05-28) [stable]
 
diff --git a/bootstrap.conf b/bootstrap.conf
index 01f354b..773c6c5 100644
--- a/bootstrap.conf
+++ b/bootstrap.conf
@@ -68,6 +68,7 @@ gnulib_modules="
   version-etc-fsf
   warnings
   xstrtol
+  xstrtoll
 "
 
 # Additional xgettext options to use.  Use "\\\newline" to break lines.
diff --git a/configure.ac b/configure.ac
index 54d3ec1..25960a7 100644
--- a/configure.ac
+++ b/configure.ac
@@ -310,10 +310,13 @@ fi
 
 dnl Check for libdl, if we are doing dynamic loading
 DL_LIBS=""
+AC_SUBST([DYNAMIC_LOADING])
+DYNAMIC_LOADING=no
 if test "$enable_dynamic_loading" = yes; then
 	AC_CHECK_LIB([dl], [dlopen],
 		DL_LIBS="-ldl"
 		PARTED_LIBS="$PARTED_LIBS -ldl"
+		DYNAMIC_LOADING=yes
 		AC_DEFINE([DYNAMIC_LOADING], [1], [Lazy linking to fs libs]),
 		AC_MSG_ERROR(
 			[-ldl not found!  Try using --disable-dynamic-loading]
diff --git a/libparted/arch/linux.c b/libparted/arch/linux.c
index b1f7dc9..a5ae10c 100644
--- a/libparted/arch/linux.c
+++ b/libparted/arch/linux.c
@@ -46,6 +46,7 @@
 
 #include "../architecture.h"
 #include "dirname.h"
+#include "xstrtol.h"
 
 #if ENABLE_NLS
 #  include <libintl.h>
@@ -719,11 +720,18 @@ _device_get_length (PedDevice* dev)
         unsigned long           size;
         LinuxSpecific*          arch_specific = LINUX_SPECIFIC (dev);
         uint64_t bytes=0;
+        const char*             test_str;
+        PedSector               test_size;
 
 
         PED_ASSERT (dev->open_count > 0, return 0);
         PED_ASSERT (dev->sector_size % PED_SECTOR_SIZE_DEFAULT == 0, return 0);
 
+        test_str = getenv ("PARTED_TEST_DEVICE_LENGTH");
+        if (test_str
+            && xstrtoll (test_str, NULL, 10, &test_size, NULL) == LONGINT_OK)
+                return test_size;
+
         if (_kernel_has_blkgetsize64()) {
                 if (ioctl(arch_specific->fd, BLKGETSIZE64, &bytes) == 0) {
                         return bytes / dev->sector_size;
@@ -1189,6 +1197,12 @@ init_generic (PedDevice* dev, const char* model_name)
         if (_device_probe_geometry (dev)) {
                 ped_exception_leave_all ();
         } else {
+		if (!_device_get_length (dev)) {
+			ped_exception_catch ();
+			ped_exception_leave_all ();
+			goto error_close_dev;
+		}
+
                 /* hack to allow use of files, for testing */
                 ped_exception_catch ();
                 ped_exception_leave_all ();
diff --git a/libparted/tests/Makefile.am b/libparted/tests/Makefile.am
index 2a60023..937cab8 100644
--- a/libparted/tests/Makefile.am
+++ b/libparted/tests/Makefile.am
@@ -3,9 +3,9 @@
 #
 # This file may be modified and/or distributed without restriction.
 
-TESTS = t1000-label.sh t2000-disk.sh t3000-symlink.sh
+TESTS = t1000-label.sh t2000-disk.sh t2100-zerolen.sh t3000-symlink.sh
 EXTRA_DIST = $(TESTS)
-check_PROGRAMS = label disk symlink
+check_PROGRAMS = label disk zerolen symlink
 AM_CFLAGS = $(WARN_CFLAGS) $(WERROR_CFLAGS)
 
 LDADD = \
@@ -19,6 +19,7 @@ AM_CPPFLAGS = \
 
 label_SOURCES = common.h common.c label.c
 disk_SOURCES  = common.h common.c disk.c
+zerolen_SOURCES = common.h common.c zerolen.c
 symlink_SOURCES = common.h common.c symlink.c
 
 MAINTAINERCLEANFILES = Makefile.in
@@ -34,4 +35,6 @@ old-init.sh: Makefile.in
 	mv $@-t $@
 
 TESTS_ENVIRONMENT = \
-  top_srcdir='$(top_srcdir)'
+  top_srcdir='$(top_srcdir)' \
+  DYNAMIC_LOADING=$(DYNAMIC_LOADING) \
+  ENABLE_DEVICE_MAPPER=$(ENABLE_DEVICE_MAPPER)
diff --git a/libparted/tests/t2100-zerolen.sh b/libparted/tests/t2100-zerolen.sh
new file mode 100755
index 0000000..77d51de
--- /dev/null
+++ b/libparted/tests/t2100-zerolen.sh
@@ -0,0 +1,75 @@
+#!/bin/sh
+
+# Copyright (C) 2007-2010 Free Software Foundation, 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 3 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, see <http://www.gnu.org/licenses/>.
+
+test_description='run the zerolen unit tests in a directory supporting O_DIRECT'
+
+# Need root privileges to create a device-mapper device.
+privileges_required_=1
+device_mapper_required_=1
+
+: ${top_srcdir=../..}
+. "$top_srcdir/tests/test-lib.sh"
+
+init_root_dir_
+
+# This test only makes sense on Linux.
+test "$(uname -s)" = Linux \
+  || skip_test_ "not on Linux"
+
+test "x$DYNAMIC_LOADING" = xyes \
+  || skip_test_ "no dynamic loading support"
+
+test "x$ENABLE_DEVICE_MAPPER" = xyes \
+  || skip_test_ "no device-mapper support"
+
+# Device map name - should be random to not conflict with existing ones on
+# the system
+linear_=plinear-$$
+
+cleanup_()
+{
+  # 'dmsetup remove' may fail because udev is still processing the device.
+  # Try it repeatedly for 2s.
+  i=0
+  incr=1
+  while :; do
+    dmsetup remove $linear_ > /dev/null 2>&1 && break
+    sleep .1 2>/dev/null || { sleep 1; incr=10; }
+    i=$(expr $i + $incr); test $i = 20 && break
+  done
+  if test $i = 20; then
+    dmsetup remove $linear_
+  fi
+
+  test -n "$d1" && losetup -d "$d1"
+  rm -f "$f1"
+}
+
+f1=$(pwd)/1
+d1=$(loop_setup_ "$f1") \
+  || skip_test_ "is this partition mounted with 'nodev'?"
+
+echo "0 1024 linear $d1 0" | dmsetup create "$linear_" \
+  || skip_test_ "unable to create dm device"
+
+wait_for_dev_to_appear_ "/dev/mapper/$linear_" \
+  || skip_test_ "dm device did not appear"
+
+test_expect_success \
+    'run the actual tests' "zerolen /dev/mapper/$linear_"
+
+test_done
diff --git a/libparted/tests/zerolen.c b/libparted/tests/zerolen.c
new file mode 100644
index 0000000..cf2bd1c
--- /dev/null
+++ b/libparted/tests/zerolen.c
@@ -0,0 +1,52 @@
+#include <config.h>
+#include <unistd.h>
+
+#include <check.h>
+
+#include <parted/parted.h>
+
+#include "common.h"
+#include "progname.h"
+
+static const char* temporary_disk;
+
+/* TEST: Probe a zero-length disk image without raising an exception */
+START_TEST (test_probe)
+{
+        PedDevice* dev = ped_device_get (temporary_disk);
+        if (dev)
+                ped_device_destroy (dev);
+}
+END_TEST
+
+int
+main (int argc, char **argv)
+{
+        set_program_name (argv[0]);
+        int number_failed;
+        Suite* suite = suite_create ("ZeroLen");
+        TCase* tcase_probe = tcase_create ("Probe");
+
+        if (argc < 2) {
+                fail ("Insufficient arguments");
+                return EXIT_FAILURE;
+        }
+        temporary_disk = argv[1];
+        setenv ("PARTED_TEST_DEVICE_LENGTH", "0", 1);
+
+        /* Fail when an exception is raised */
+        ped_exception_set_handler (_test_exception_handler);
+
+        tcase_add_test (tcase_probe, test_probe);
+        /* Disable timeout for this test */
+        tcase_set_timeout (tcase_probe, 0);
+        suite_add_tcase (suite, tcase_probe);
+
+        SRunner* srunner = srunner_create (suite);
+        srunner_run_all (srunner, CK_VERBOSE);
+
+        number_failed = srunner_ntests_failed (srunner);
+        srunner_free (srunner);
+
+        return (number_failed == 0) ? EXIT_SUCCESS : EXIT_FAILURE;
+}
diff --git a/tests/test-lib.sh b/tests/test-lib.sh
index 8ed9b01..c9b6f37 100644
--- a/tests/test-lib.sh
+++ b/tests/test-lib.sh
@@ -390,4 +390,20 @@ require_xfs_()
     }
 }
 
+# Helper function: wait 2s (via .1s increments) for FILE to appear.
+# Usage: wait_for_dev_to_appear_ /dev/sdg
+# Return 0 upon success, 1 upon failure.
+wait_for_dev_to_appear_()
+{
+  local file=$1
+  local i=0
+  local incr=1
+  while :; do
+    ls "$file" > /dev/null 2>&1 && return 0
+    sleep .1 2>/dev/null || { sleep 1; incr=10; }
+    i=$(expr $i + $incr); test $i = 20 && break
+  done
+  return 1
+}
+
 sector_size_=${PARTED_SECTOR_SIZE:-512}



More information about the Parted-commits mailing list