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

Jim Meyering meyering at alioth.debian.org
Fri Nov 27 10:12:59 UTC 2009


 include/parted/disk.h                 |    2 
 include/parted/fdasd.h                |    2 
 libparted/arch/linux.c                |    3 -
 libparted/disk.c                      |   83 +++++++++++++++++++---------------
 libparted/labels/dasd.c               |   17 ++++--
 libparted/labels/fdasd.c              |   61 +++++++++++++++++-------
 libparted/labels/loop.c               |    8 ---
 scripts/data/abi/baseline_symbols.txt |    1 
 8 files changed, 106 insertions(+), 71 deletions(-)

New commits:
commit 424f06a688004bdb5fb676c670e65f8bd0d7ee9d
Author: Jim Meyering <meyering at redhat.com>
Date:   Thu Nov 26 14:40:04 2009 +0100

    libparted: ped_disk_clobber_exclude: remove now-unused function
    
    I see no utility in ped_disk_clobber_exclude (just a thin wrapper
    around ped_disk_clobber), so am removing the interface.
    * include/parted/disk.h (ped_disk_clobber_exclude): Remove prototype.
    * libparted/disk.c (ped_disk_clobber_exclude): Remove function.
    Now that all callers use NULL as 2nd argument, replace each call
    with one to ped_disk_clobber.
    * scripts/data/abi/baseline_symbols.txt: Remove it.
    
    Reviewed-by: Karel Zak <kzak at redhat.com>

diff --git a/include/parted/disk.h b/include/parted/disk.h
index 434f0d3..3f383e2 100644
--- a/include/parted/disk.h
+++ b/include/parted/disk.h
@@ -246,8 +246,6 @@ extern int ped_disk_type_check_feature (const PedDiskType* disk_type,
 
 extern PedDiskType* ped_disk_probe (PedDevice* dev);
 extern int ped_disk_clobber (PedDevice* dev);
-extern int ped_disk_clobber_exclude (PedDevice* dev,
-                                     const PedDiskType* exclude);
 extern PedDisk* ped_disk_new (PedDevice* dev);
 extern PedDisk* ped_disk_new_fresh (PedDevice* dev,
                                     const PedDiskType* disk_type);
diff --git a/libparted/disk.c b/libparted/disk.c
index 3127e03..89476a7 100644
--- a/libparted/disk.c
+++ b/libparted/disk.c
@@ -293,14 +293,13 @@ find_disk_type (char const *name)
 
 /**
  * Remove all identifying signatures of a partition table,
- * except for partition tables of a given type.
  *
  * \return 0 on error, 1 otherwise.
  *
  * \sa ped_disk_clobber()
  */
 int
-ped_disk_clobber_exclude (PedDevice* dev, const PedDiskType* exclude)
+ped_disk_clobber (PedDevice* dev)
 {
 	PED_ASSERT (dev != NULL, goto error);
 
@@ -349,19 +348,6 @@ error:
 }
 
 /**
- * Remove all identifying signatures of a partition table,
- *
- * \return 0 on error, 1 otherwise.
- *
- * \sa ped_disk_clobber_exclude()
- */
-int
-ped_disk_clobber (PedDevice* dev)
-{
-	return ped_disk_clobber_exclude (dev, NULL);
-}
-
-/**
  * Create a new partition table on \p dev.
  *
  * This new partition table is only created in-memory, and nothing is written
@@ -496,7 +482,7 @@ ped_disk_commit_to_dev (PedDisk* disk)
 		goto error;
 
 	if (disk->needs_clobber) {
-		if (!ped_disk_clobber_exclude (disk->dev, NULL))
+		if (!ped_disk_clobber (disk->dev))
 			goto error_close_dev;
 		disk->needs_clobber = 0;
 	}
diff --git a/scripts/data/abi/baseline_symbols.txt b/scripts/data/abi/baseline_symbols.txt
index e375512..010a55e 100644
--- a/scripts/data/abi/baseline_symbols.txt
+++ b/scripts/data/abi/baseline_symbols.txt
@@ -256,7 +256,6 @@ FUNC:ped_disk_bsd_done
 FUNC:ped_disk_bsd_init
 FUNC:ped_disk_check
 FUNC:ped_disk_clobber
-FUNC:ped_disk_clobber_exclude
 FUNC:ped_disk_commit
 FUNC:ped_disk_commit_to_dev
 FUNC:ped_disk_commit_to_os

commit 376b14304547d836399e16991b5551b60b277fc2
Author: Jim Meyering <meyering at redhat.com>
Date:   Fri Nov 13 11:37:39 2009 +0100

    ped_disk_clobber: change semantics
    
    Why?  Because if we're going to clobber a partition table,
    it is wasteful and error prone to try to interpret as a partition
    table whatever existing data there may be.  It may be corrupt, or
    a mix of two or more types.  It is far cleaner just to zero out
    the key sectors.
    
    The previous mechanism was like this:
    for each partition table type, T,
        # See if the device has a partition of type T.
        # If so, run the partition-table-specific code to clear it.
        if t->ops->probe (dev)
          t->ops->clobber (dev)
    Instead, simply zero out the first few and last few sectors.
    Except for GPT, for which we exempt the first sector (the pMBR).
    In order to zero out even the bits DASD uses for its identifying
    strings, we have to clobber at least the 8.5KiB at the beginning
    of the disk, so round up to 9KiB.
    * libparted/disk.c: Include "labels/pt-tools.h".
    (find_disk_type): New helper function.
    (ped_disk_clobber_exclude):
    
    Reviewed-by: Karel Zak <kzak at redhat.com>

diff --git a/libparted/disk.c b/libparted/disk.c
index 8c4b229..3127e03 100644
--- a/libparted/disk.c
+++ b/libparted/disk.c
@@ -39,6 +39,7 @@
 
 #include "architecture.h"
 #include "intprops.h"
+#include "labels/pt-tools.h"
 
 #if ENABLE_NLS
 #  include <libintl.h>
@@ -276,6 +277,20 @@ error:
 	return NULL;
 }
 
+/* Given a partition table type NAME, e.g., "gpt", return its PedDiskType
+   handle.  If no known type has a name matching NAME, return NULL.  */
+static PedDiskType const *
+find_disk_type (char const *name)
+{
+  PedDiskType const *t;
+  for (t = ped_disk_type_get_next (NULL); t; t = ped_disk_type_get_next (t))
+    {
+      if (strcmp (t->name, name) == 0)
+        return t;
+    }
+  return NULL;
+}
+
 /**
  * Remove all identifying signatures of a partition table,
  * except for partition tables of a given type.
@@ -287,31 +302,43 @@ error:
 int
 ped_disk_clobber_exclude (PedDevice* dev, const PedDiskType* exclude)
 {
-	PedDiskType*	walk;
-
 	PED_ASSERT (dev != NULL, goto error);
 
 	if (!ped_device_open (dev))
 		goto error;
 
-	for (walk = ped_disk_type_get_next (NULL); walk;
-	     walk = ped_disk_type_get_next (walk)) {
-		int	probed;
+        PedDiskType const *gpt = find_disk_type ("gpt");
+	PED_ASSERT (gpt != NULL, goto error);
+
+        /* If there is a GPT table, don't clobber the protective MBR.  */
+        bool is_gpt = gpt->ops->probe (dev);
+        PedSector first_sector = (is_gpt ? 1 : 0);
+
+	/* How many sectors to zero out at each end.
+	   This must be large enough to zero out the magic bytes
+	   starting at offset 8KiB on a DASD partition table.
+	   Doing the same from the end of the disk is probably
+	   overkill, but at least on GPT, we do need to zero out
+	   the final sector.  */
+	const PedSector n_sectors = 9 * 1024 / dev->sector_size + 1;
+
+	/* Clear the first few.  */
+	PedSector n = n_sectors;
+	if (dev->length < first_sector + n_sectors)
+	  n = dev->length - first_sector;
+        if (!ptt_clear_sectors (dev, first_sector, n))
+          goto error_close_dev;
+
+	/* Clear the last few.  */
+	PedSector t = (dev->length -
+		       (n_sectors < dev->length ? n_sectors : 1));
+
+        /* Don't clobber the pMBR if we have a pathologically small disk.  */
+        if (t < first_sector)
+          t = first_sector;
+        if (!ptt_clear_sectors (dev, t, dev->length - t))
+          goto error_close_dev;
 
-		if (walk == exclude)
-			continue;
-
-		ped_exception_fetch_all ();
-		probed = walk->ops->probe (dev);
-		if (!probed)
-			ped_exception_catch ();
-		ped_exception_leave_all ();
-
-		if (probed && walk->ops->clobber) {
-			if (!walk->ops->clobber (dev))
-				goto error_close_dev;
-		}
-	}
 	ped_device_close (dev);
 	return 1;
 
@@ -469,7 +496,7 @@ ped_disk_commit_to_dev (PedDisk* disk)
 		goto error;
 
 	if (disk->needs_clobber) {
-		if (!ped_disk_clobber_exclude (disk->dev, disk->type))
+		if (!ped_disk_clobber_exclude (disk->dev, NULL))
 			goto error_close_dev;
 		disk->needs_clobber = 0;
 	}

commit 50b1d2bb1a4e199ca6ecdb73be2d15677600c76d
Author: Jim Meyering <meyering at redhat.com>
Date:   Thu Nov 12 16:00:41 2009 +0100

    dasd: allow the use of a *regular* backing file
    
    Before this change, dasd partition tables had to be associated with
    very specialized block devices available only on IBM s390 systems.
    This made testing especially hard.  Not only did you need access
    to one of those relatively uncommon systems, but you also needed
    access to a spare block device.  In addition, many of Parted's
    tests may be run as a non-privileged user, using regular files,
    and those tests would fail when run on an s390.
    
    This change makes it so you may now write a DASD partition table
    to a regular backing file, just as you may with any other supported
    partition table type.  However, note that even now, DASD support
    is conditionally compiled and hence enabled only when compiling
    for an s390 target.
    
    * libparted/arch/linux.c (_device_set_sector_size) [__s390__]:
    Allow operation on a device of type PED_DEVICE_FILE, as well as
    those of type PED_DEVICE_DASD.
    * libparted/labels/fdasd.c: Include <parted/device.h>.
    (fdasd_get_geometry): Add a new "dev" parameter, required for
    dev-phys-sector_size, which is needed in order to initialize
    the "anc" structure without using the device-specific ioctls.
    When file descriptor "f" refers to a regular file, initialize
    "anc", "dasd_info", etc. from other sources (fstat and dev->).
    Update all callers to reflect added parameter.
    (fdasd_check_api_version): Skip ioctl-calling tests when "f" is
    a regular file.
    * include/parted/fdasd.h: Update fdasd_get_geometry prototype.
    * libparted/labels/dasd.c (dasd_probe): Also allow PED_DEVICE_FILE.
    (dasd_alloc_metadata): Initialize arch_specific->real_sector_size,
    which is used in calculating vtoc_end.
    
    Reviewed-by: Karel Zak <kzak at redhat.com>

diff --git a/include/parted/fdasd.h b/include/parted/fdasd.h
index a893ba8..ac30134 100644
--- a/include/parted/fdasd.h
+++ b/include/parted/fdasd.h
@@ -217,7 +217,7 @@ enum fdasd_failure {
 
 void fdasd_cleanup (fdasd_anchor_t *anchor);
 void fdasd_initialize_anchor (fdasd_anchor_t * anc);
-void fdasd_get_geometry (fdasd_anchor_t *anc, int fd);
+void fdasd_get_geometry (const PedDevice *dev, fdasd_anchor_t *anc, int fd);
 void fdasd_check_api_version (fdasd_anchor_t *anc, int fd);
 int fdasd_check_volume (fdasd_anchor_t *anc, int fd);
 int fdasd_write_labels (fdasd_anchor_t *anc, int fd);
diff --git a/libparted/arch/linux.c b/libparted/arch/linux.c
index 4fe48ec..94cbae9 100644
--- a/libparted/arch/linux.c
+++ b/libparted/arch/linux.c
@@ -672,7 +672,8 @@ _device_set_sector_size (PedDevice* dev)
 
 #if defined __s390__ || defined __s390x__
         /* Return PED_SECTOR_SIZE_DEFAULT for DASDs. */
-        if (dev->type == PED_DEVICE_DASD) {
+        if (dev->type == PED_DEVICE_DASD
+            || dev->type == PED_DEVICE_FILE) {
                 arch_specific->real_sector_size = dev->sector_size;
                 dev->sector_size = PED_SECTOR_SIZE_DEFAULT;
         }
diff --git a/libparted/labels/dasd.c b/libparted/labels/dasd.c
index fc0695c..dd492f2 100644
--- a/libparted/labels/dasd.c
+++ b/libparted/labels/dasd.c
@@ -230,7 +230,9 @@ dasd_probe (const PedDevice *dev)
 
 	PED_ASSERT(dev != NULL, return 0);
 
-	if (!(dev->type == PED_DEVICE_DASD || dev->type == PED_DEVICE_VIODASD))
+	if (!(dev->type == PED_DEVICE_DASD
+              || dev->type == PED_DEVICE_VIODASD
+              || dev->type == PED_DEVICE_FILE))
 		return 0;
 
 	arch_specific = LINUX_SPECIFIC(dev);
@@ -238,7 +240,7 @@ dasd_probe (const PedDevice *dev)
 	/* add partition test here */
 	fdasd_initialize_anchor(&anchor);
 
-	fdasd_get_geometry(&anchor, arch_specific->fd);
+	fdasd_get_geometry(dev, &anchor, arch_specific->fd);
 
 	fdasd_check_api_version(&anchor, arch_specific->fd);
 
@@ -268,7 +270,7 @@ dasd_clobber (PedDevice* dev)
 	arch_specific = LINUX_SPECIFIC(dev);
 
 	fdasd_initialize_anchor(&anchor);
-	fdasd_get_geometry(&anchor, arch_specific->fd);
+	fdasd_get_geometry(dev, &anchor, arch_specific->fd);
 
 	fdasd_recreate_vtoc(&anchor);
 	fdasd_write_labels(&anchor, arch_specific->fd);
@@ -309,7 +311,7 @@ dasd_read (PedDisk* disk)
 
 	fdasd_initialize_anchor(&anchor);
 
-	fdasd_get_geometry(&anchor, arch_specific->fd);
+	fdasd_get_geometry(disk->dev, &anchor, arch_specific->fd);
 
 	/* check dasd for labels and vtoc */
 	if (fdasd_check_volume(&anchor, arch_specific->fd))
@@ -577,7 +579,7 @@ dasd_write (const PedDisk* disk)
 
 	/* initialize the anchor */
 	fdasd_initialize_anchor(&anchor);
-	fdasd_get_geometry(&anchor, arch_specific->fd);
+	fdasd_get_geometry(disk->dev, &anchor, arch_specific->fd);
 	memcpy(anchor.vlabel, &disk_specific->vlabel, sizeof(volume_label_t));
 	anchor.vlabel_changed++;
 
@@ -905,11 +907,14 @@ dasd_alloc_metadata (PedDisk* disk)
 	/* If formated in LDL, the real partition starts at sector 24. */
 	if (disk_specific->format_type == 1)
 		vtoc_end = 23;
-	else
+	else {
+                if (disk->dev->type == PED_DEVICE_FILE)
+                        arch_specific->real_sector_size = disk->dev->sector_size;
         /* Mark the start of the disk as metadata. */
 		vtoc_end = (FIRST_USABLE_TRK * (long long) disk->dev->hw_geom.sectors
 				   * (long long) arch_specific->real_sector_size
 				   / (long long) disk->dev->sector_size) - 1;
+        }
 
 	new_part = ped_partition_new (disk,PED_PARTITION_METADATA,NULL,0,vtoc_end);
 	if (!new_part)
diff --git a/libparted/labels/fdasd.c b/libparted/labels/fdasd.c
index b116a69..6397f27 100644
--- a/libparted/labels/fdasd.c
+++ b/libparted/labels/fdasd.c
@@ -19,6 +19,7 @@
 #include <config.h>
 #include <arch/linux.h>
 #include <parted/vtoc.h>
+#include <parted/device.h>
 #include <parted/fdasd.h>
 
 #include <parted/parted.h>
@@ -753,15 +754,21 @@ fdasd_check_api_version (fdasd_anchor_t *anc, int f)
 	int api;
 	char s[LINE_LENGTH];
 
-	if (ioctl(f, DASDAPIVER, &api) != 0)
-		fdasd_error(anc, unable_to_ioctl,
-			    _("Could not retrieve API version."));
-
-	if (api != DASD_MIN_API_VERSION) {
-		sprintf(s, _("The current API version '%d' doesn't " \
-				"match dasd driver API version " \
-				"'%d'!"), api, DASD_MIN_API_VERSION);
-		fdasd_error(anc, api_version_mismatch, s);
+        struct stat st;
+        if (fstat (f, &st) == 0 && S_ISREG (st.st_mode)) {
+		/* skip these tests when F is a regular file.  */
+	}
+	else {
+		if (ioctl(f, DASDAPIVER, &api) != 0)
+			fdasd_error(anc, unable_to_ioctl,
+				    _("Could not retrieve API version."));
+
+		if (api != DASD_MIN_API_VERSION) {
+			sprintf(s, _("The current API version '%d' doesn't " \
+					"match dasd driver API version " \
+					"'%d'!"), api, DASD_MIN_API_VERSION);
+			fdasd_error(anc, api_version_mismatch, s);
+		}
 	}
 }
 
@@ -769,24 +776,42 @@ fdasd_check_api_version (fdasd_anchor_t *anc, int f)
  * reads dasd geometry data
  */
 void
-fdasd_get_geometry (fdasd_anchor_t *anc, int f)
+fdasd_get_geometry (const PedDevice *dev, fdasd_anchor_t *anc, int f)
 {
 	PDEBUG
 	int blksize = 0;
 	dasd_information_t dasd_info;
 
-	if (ioctl(f, HDIO_GETGEO, &anc->geo) != 0)
-		fdasd_error(anc, unable_to_ioctl,
+	/* We can't get geometry from a regular file,
+	   so simulate something usable, for the sake of testing.  */
+	struct stat st;
+	if (fstat (f, &st) == 0 && S_ISREG (st.st_mode)) {
+	    PedSector n_sectors = st.st_size / dev->sector_size;
+	    anc->geo.heads = 15;
+	    anc->geo.sectors = 12;
+	    anc->geo.cylinders
+	      = (n_sectors / (anc->geo.heads * anc->geo.sectors
+			      * (dev->sector_size / dev->phys_sector_size)));
+	    anc->geo.start = 0;
+	    blksize = 4096;
+	    memcpy (dasd_info.type, "ECKD", 4);
+	    dasd_info.dev_type = 13200;
+	    dasd_info.label_block = 2;
+	    dasd_info.devno = 513;
+	} else {
+		if (ioctl(f, HDIO_GETGEO, &anc->geo) != 0)
+			fdasd_error(anc, unable_to_ioctl,
 			    _("Could not retrieve disk geometry information."));
 
-	if (ioctl(f, BLKSSZGET, &blksize) != 0)
-		fdasd_error(anc, unable_to_ioctl,
+		if (ioctl(f, BLKSSZGET, &blksize) != 0)
+			fdasd_error(anc, unable_to_ioctl,
 			    _("Could not retrieve blocksize information."));
 
-	/* get disk type */
-	if (ioctl(f, BIODASDINFO, &dasd_info) != 0)
-		fdasd_error(anc, unable_to_ioctl,
-			    _("Could not retrieve disk information."));
+		/* get disk type */
+		if (ioctl(f, BIODASDINFO, &dasd_info) != 0)
+			fdasd_error(anc, unable_to_ioctl,
+				    _("Could not retrieve disk information."));
+	}
 
 	if (strncmp(dasd_info.type, "ECKD", 4) != 0)
 		fdasd_error(anc, wrong_disk_type,

commit 3938eca7eb771a1f05d1f3acd994a490a55406b5
Author: Jim Meyering <meyering at redhat.com>
Date:   Tue Nov 24 15:55:35 2009 +0100

    loop: simplify/correct loop_clobber
    
    Before, it would clear a sector only if it recognized its own
    signature.  In addition, it would continue clearing subsequent
    sectors as long as loop_probe succeeded.  Now we simply clear
    the first sector.
    * libparted/labels/loop.c (loop_clobber): Simplify.
    
    Reviewed-by: Karel Zak <kzak at redhat.com>

diff --git a/libparted/labels/loop.c b/libparted/labels/loop.c
index b08a04e..76a99af 100644
--- a/libparted/labels/loop.c
+++ b/libparted/labels/loop.c
@@ -78,13 +78,7 @@ static int
 loop_clobber (PedDevice* dev)
 {
 	PED_ASSERT (dev != NULL, return 0);
-
-	PedSector i = 0;
-	while (loop_probe (dev)) {
-		if (!ptt_clear_sectors (dev, i++, 1))
-			return 0;
-	}
-	return 1;
+        return ptt_clear_sectors (dev, 0, 1);
 }
 #endif /* !DISCOVER_ONLY */
 



More information about the Parted-commits mailing list