[parted-devel] [PATCH 2/2] dasd: enhance device probing

Hendrik Brueckner brueckner at linux.vnet.ibm.com
Tue Sep 15 13:02:55 UTC 2015


From: Viktor Mihajlovski <mihajlov at linux.vnet.ibm.com>

Probe for all device/transport types as every block device
could be a DASD on s390.

Observe fdasd_get_geometry return code for proper error
handling.

Remove the obsolete API check as we no longer require the
DASD-specific IOCTLs.

We can't rely on PED_DEVICE_DASD to be set for non-native DASDs
so we use a heuristic on s390x implemented in ped_device_like_dasd()

Signed-off-by: Viktor Mihajlovski <mihajlov at linux.vnet.ibm.com>
Acked-by: Stefan Haberland <stefan.haberland at de.ibm.com>
Signed-off-by: Hendrik Brueckner <brueckner at linux.vnet.ibm.com>
---
 include/parted/device.in.h |    2 ++
 libparted/arch/linux.c     |    8 ++++++--
 libparted/device.c         |   32 ++++++++++++++++++++++++++++----
 libparted/labels/dasd.c    |   18 ++++++++----------
 4 files changed, 44 insertions(+), 16 deletions(-)

diff --git a/include/parted/device.in.h b/include/parted/device.in.h
index 82d4104..85b1567 100644
--- a/include/parted/device.in.h
+++ b/include/parted/device.in.h
@@ -156,6 +156,8 @@ extern PedConstraint *ped_device_get_optimal_aligned_constraint(
 extern PedAlignment *ped_device_get_minimum_alignment(const PedDevice *dev);
 extern PedAlignment *ped_device_get_optimum_alignment(const PedDevice *dev);
 
+extern int ped_device_like_dasd(const PedDevice *dev);
+
 /* private stuff ;-) */
 
 extern void _ped_device_probe (const char* path);
diff --git a/libparted/arch/linux.c b/libparted/arch/linux.c
index 906298f..7eb6a9a 100644
--- a/libparted/arch/linux.c
+++ b/libparted/arch/linux.c
@@ -783,9 +783,13 @@ _device_set_sector_size (PedDevice* dev)
 #endif
 
 #if defined __s390__ || defined __s390x__
+        /* The real_sector_size is currently needed for DASD layouts,
+         * so we set it unconditionally. In the long run it should
+         * be considered to use the dev->phys_sector_size in label/dasd.c.
+         */
+        arch_specific->real_sector_size = dev->sector_size;
         /* Return PED_SECTOR_SIZE_DEFAULT for DASDs. */
         if (dev->type == PED_DEVICE_DASD) {
-                arch_specific->real_sector_size = dev->sector_size;
                 dev->sector_size = PED_SECTOR_SIZE_DEFAULT;
         }
 #endif
@@ -3196,7 +3200,7 @@ linux_get_optimum_alignment(const PedDevice *dev)
 		&& PED_DEFAULT_ALIGNMENT % minimum_io == 0)
            ) {
             /* DASD needs to use minimum alignment */
-            if (dev->type == PED_DEVICE_DASD)
+            if (ped_device_like_dasd(dev))
                 return linux_get_minimum_alignment(dev);
 
             return ped_alignment_new(
diff --git a/libparted/device.c b/libparted/device.c
index cdcc117..b207593 100644
--- a/libparted/device.c
+++ b/libparted/device.c
@@ -550,11 +550,9 @@ ped_device_get_optimum_alignment(const PedDevice *dev)
         /* If the arch specific code could not give as an alignment
            return a default value based on the type of device. */
         if (align == NULL) {
-                switch (dev->type) {
-                case PED_DEVICE_DASD:
+                if (ped_device_like_dasd(dev))
                         align = ped_device_get_minimum_alignment(dev);
-                        break;
-                default:
+                else {
                         /* Align to a grain of 1MiB (like vista / win7) */
                         align = ped_alignment_new(0,
                                                   (PED_DEFAULT_ALIGNMENT
@@ -565,4 +563,30 @@ ped_device_get_optimum_alignment(const PedDevice *dev)
         return align;
 }
 
+/**
+ * Check whether this device could be a DASD
+ *
+ * The device probing yields PED_DEVICE_DASD for native DASD transport
+ * If the block device uses a different transport (e.g. virtio)
+ * a simplified heuristic (assuming a model 3390 with 4K sectors)
+ * is applied (only) on s390x systems for this check.
+ *
+ * \return 1 if the geometry indicates this could be a DASD
+ *         and 0 otherwise
+ */
+int ped_device_like_dasd(const PedDevice *dev)
+{
+#if defined __s390__ || defined __s390x__
+        return (dev->type == PED_DEVICE_DASD) ||
+	  (dev->hw_geom.heads == 15 &&
+           dev->hw_geom.sectors == 12 &&
+           (dev->hw_geom.cylinders *
+            dev->hw_geom.heads *
+            dev->hw_geom.sectors * dev->phys_sector_size ==
+            dev->length * dev->sector_size));
+#else
+	return 0;
+#endif
+}
+
 /** @} */
diff --git a/libparted/labels/dasd.c b/libparted/labels/dasd.c
index fa9414f..bb32d66 100644
--- a/libparted/labels/dasd.c
+++ b/libparted/labels/dasd.c
@@ -214,19 +214,13 @@ dasd_probe (const PedDevice *dev)
 
 	PED_ASSERT(dev != NULL);
 
-	if (!(dev->type == PED_DEVICE_DASD
-              || dev->type == PED_DEVICE_VIODASD
-              || dev->type == PED_DEVICE_FILE))
-		return 0;
-
 	arch_specific = LINUX_SPECIFIC(dev);
 
 	/* add partition test here */
 	fdasd_initialize_anchor(&anchor);
 
-	fdasd_get_geometry(dev, &anchor, arch_specific->fd);
-
-	fdasd_check_api_version(&anchor, arch_specific->fd);
+	if (fdasd_get_geometry(dev, &anchor, arch_specific->fd) == 0)
+                goto error_cleanup;
 
 	/* Labels are required on CDL formatted DASDs. */
 	if (fdasd_check_volume(&anchor, arch_specific->fd) &&
@@ -276,7 +270,9 @@ dasd_read (PedDisk* disk)
 
 	fdasd_initialize_anchor(&anchor);
 
-	fdasd_get_geometry(disk->dev, &anchor, arch_specific->fd);
+	if (fdasd_get_geometry(disk->dev, &anchor, arch_specific->fd) == 0)
+                goto error_close_dev;
+
 	disk_specific->label_block = anchor.label_block;
 
 	if ((anchor.geo.cylinders * anchor.geo.heads) > BIG_DISK_SIZE)
@@ -630,7 +626,9 @@ dasd_write (const PedDisk* disk)
 
 	/* initialize the anchor */
 	fdasd_initialize_anchor(&anchor);
-	fdasd_get_geometry(disk->dev, &anchor, arch_specific->fd);
+	if (fdasd_get_geometry(disk->dev, &anchor, arch_specific->fd) == 0)
+                goto error;
+
 	fdasd_check_volume(&anchor, arch_specific->fd);
 	memcpy(anchor.vlabel, &disk_specific->vlabel, sizeof(volume_label_t));
 	anchor.vlabel_changed++;
-- 
1.7.1




More information about the parted-devel mailing list