diff --git a/SOURCES/0049-partprobe-always-close-dev-when-probing-disks.patch b/SOURCES/0049-partprobe-always-close-dev-when-probing-disks.patch
new file mode 100644
index 0000000..5dd6513
--- /dev/null
+++ b/SOURCES/0049-partprobe-always-close-dev-when-probing-disks.patch
@@ -0,0 +1,34 @@
+From da41227259c5e301e26a9983b714e521d4599575 Mon Sep 17 00:00:00 2001
+From: "Brian C. Lane" <bcl@redhat.com>
+Date: Mon, 25 Feb 2019 16:07:39 -0800
+Subject: [PATCH 49/50] partprobe: always close dev when probing disks
+
+Resolves: rhbz#1551411
+---
+ partprobe/partprobe.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/partprobe/partprobe.c b/partprobe/partprobe.c
+index c5260c6..ccda141 100644
+--- a/partprobe/partprobe.c
++++ b/partprobe/partprobe.c
+@@ -113,7 +113,7 @@ process_dev (PedDevice* dev)
+ 
+ 	disk_type = ped_disk_probe (dev);
+ 	if (!disk_type || !strcmp (disk_type->name, "loop"))
+-		return 1;
++		goto skip_dev;
+ 
+ 	disk = ped_disk_new (dev);
+ 	if (!disk)
+@@ -125,6 +125,7 @@ process_dev (PedDevice* dev)
+ 	if (opt_summary)
+ 		summary (disk);
+ 	ped_disk_destroy (disk);
++skip_dev:
+ 	ped_device_close (dev);
+ 	return 1;
+ 
+-- 
+2.20.1
+
diff --git a/SOURCES/0050-tests-Add-t4201-to-test-partprobe-with-1025-devices.patch b/SOURCES/0050-tests-Add-t4201-to-test-partprobe-with-1025-devices.patch
new file mode 100644
index 0000000..99e0f70
--- /dev/null
+++ b/SOURCES/0050-tests-Add-t4201-to-test-partprobe-with-1025-devices.patch
@@ -0,0 +1,86 @@
+From bbe5e56e7c8718f416610b48afadada543e1d58e Mon Sep 17 00:00:00 2001
+From: "Brian C. Lane" <bcl@redhat.com>
+Date: Mon, 25 Feb 2019 16:20:14 -0800
+Subject: [PATCH 50/50] tests: Add t4201 to test partprobe with 1025 devices
+
+This makes sure partprobe is closing the device and doesn't run out of
+file descriptors. Uses scsi_debug to create 1025 devices (descriptor
+limit is 1024).
+
+Also adds partprobe to the TESTS_ENVIRONMENT PATH, otherwise it will use
+the partprobe installed on the system when running the tests.
+
+Related: rhbz#1551411
+---
+ tests/Makefile.am                   |  3 ++-
+ tests/t4201-partprobe-1025-disks.sh | 37 +++++++++++++++++++++++++++++
+ 2 files changed, 39 insertions(+), 1 deletion(-)
+ create mode 100755 tests/t4201-partprobe-1025-disks.sh
+
+diff --git a/tests/Makefile.am b/tests/Makefile.am
+index 29fa280..f11be8a 100644
+--- a/tests/Makefile.am
++++ b/tests/Makefile.am
+@@ -52,6 +52,7 @@ TESTS = \
+   t4100-msdos-partition-limits.sh \
+   t4100-msdos-starting-sector.sh \
+   t4200-partprobe.sh \
++  t4201-partprobe-1025-disks.sh \
+   t4300-nilfs2-tiny.sh \
+   t5000-tags.sh \
+   t6000-dm.sh \
+@@ -120,7 +121,7 @@ TESTS_ENVIRONMENT =				\
+   PERL='$(PERL)'				\
+   PREFERABLY_POSIX_SHELL='$(PREFERABLY_POSIX_SHELL)' \
+   REPLACE_GETCWD=$(REPLACE_GETCWD)		\
+-  PATH='$(abs_top_builddir)/parted$(PATH_SEPARATOR)'"$$PATH" \
++  PATH='$(abs_top_builddir)/parted$(PATH_SEPARATOR)$(abs_top_builddir)/partprobe$(PATH_SEPARATOR)'"$$PATH" \
+   VERSION=$(VERSION)				\
+   ; 9>&2
+ 
+diff --git a/tests/t4201-partprobe-1025-disks.sh b/tests/t4201-partprobe-1025-disks.sh
+new file mode 100755
+index 0000000..f6cdec5
+--- /dev/null
++++ b/tests/t4201-partprobe-1025-disks.sh
+@@ -0,0 +1,37 @@
++#!/bin/sh
++# Make sure partprobe is closing the devices
++
++# Copyright (C) 2008-2012 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/>.
++
++. "${srcdir=.}/init.sh"; path_prepend_ ../parted
++require_root_
++require_scsi_debug_module_
++ss=$sector_size_
++
++scsi_debug_acquire_lock_
++
++# load scsi_debug directly, using scsi_debug_setup_ fails with all the unexpected devices
++modprobe scsi_debug dev_size_mb=1 num_tgts=1025 > dev-name ||
++  skip_ 'failed to create scsi_debug device'
++
++# So that scsi_debug_cleanup_ will run
++scsi_debug_modprobe_succeeded_=1
++
++# ensure that partprobe succeeds and produces no output"
++partprobe > out 2>err || fail=1
++compare /dev/null err || fail=1
++
++Exit $fail
+-- 
+2.20.1
+
diff --git a/SOURCES/0051-fdasd-geometry-handling-updated-from-upstream-s390-t.patch b/SOURCES/0051-fdasd-geometry-handling-updated-from-upstream-s390-t.patch
new file mode 100644
index 0000000..9f8f3a5
--- /dev/null
+++ b/SOURCES/0051-fdasd-geometry-handling-updated-from-upstream-s390-t.patch
@@ -0,0 +1,286 @@
+From 42944dd6be000d49d5e1178a576e269aac6f6335 Mon Sep 17 00:00:00 2001
+From: Viktor Mihajlovski <mihajlov@linux.vnet.ibm.com>
+Date: Thu, 17 Sep 2015 15:33:28 +0200
+Subject: [PATCH 51/54] fdasd: geometry handling updated from upstream
+ s390-tools
+
+Remove the necessity for DASD-specific ioctls for partition handling.
+This allows to correctly handle DASD-backed virtio block devices.
+
+Note that this is necessary because virtio is just the transport.
+A DASD, even if provided via virtio, still has it's unique
+characteristics, which means that only traditional DASD partition
+table formats can be used (no MBR, GPT, or similar).
+
+Use bzero for initialization to make sure all struct members are
+properly cleared. Also changed partition list handling code to be
+more similar to upstream s390-tools fdasd.
+
+Further, enhanced error handling capabilities by providing a
+return code by fdasd_get_geometry.
+
+Code is largely backported from s390-tools project.
+
+Signed-off-by: Viktor Mihajlovski <mihajlov@linux.vnet.ibm.com>
+Acked-by: Stefan Haberland <stefan.haberland@de.ibm.com>
+Signed-off-by: Hendrik Brueckner <brueckner@linux.vnet.ibm.com>
+Signed-off-by: Brian C. Lane <bcl@redhat.com>
+
+(cherry picked from commit 4d480d980a9b69b432b8d60df3c4397ba8cdc965)
+
+Resolves: rhbz#1676604
+---
+ include/parted/fdasd.h   |   4 +-
+ libparted/labels/fdasd.c | 166 +++++++++++++++++++++++++++------------
+ 2 files changed, 119 insertions(+), 51 deletions(-)
+
+diff --git a/include/parted/fdasd.h b/include/parted/fdasd.h
+index 6f6a7e0..4e351c4 100644
+--- a/include/parted/fdasd.h
++++ b/include/parted/fdasd.h
+@@ -190,6 +190,8 @@ typedef struct format_data_t {
+ #define BLKRRPART  _IO(0x12,95)
+ /* get block device sector size */
+ #define BLKSSZGET  _IO(0x12,104)
++/* device size in bytes (u64 *arg)*/
++#define BLKGETSIZE64 _IOR(0x12,114,size_t)
+ /* get device geometry */
+ #define HDIO_GETGEO		0x0301
+ 
+@@ -285,7 +287,7 @@ enum fdasd_failure {
+ 
+ void fdasd_cleanup (fdasd_anchor_t *anchor);
+ void fdasd_initialize_anchor (fdasd_anchor_t * anc);
+-void fdasd_get_geometry (const PedDevice *dev, fdasd_anchor_t *anc, int fd);
++int 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/labels/fdasd.c b/libparted/labels/fdasd.c
+index 1f87937..7e6a77a 100644
+--- a/libparted/labels/fdasd.c
++++ b/libparted/labels/fdasd.c
+@@ -210,27 +210,7 @@ fdasd_initialize_anchor (fdasd_anchor_t * anc)
+ 	partition_info_t *p = NULL;
+ 	partition_info_t *q = NULL;
+ 
+-	anc->devno             = 0;
+-	anc->dev_type          = 0;
+-	anc->used_partitions   = 0;
+-
+-	anc->silent            = 0;
+-	anc->verbose           = 0;
+-	anc->big_disk          = 0;
+-	anc->volid_specified   = 0;
+-	anc->config_specified  = 0;
+-	anc->auto_partition    = 0;
+-	anc->devname_specified = 0;
+-	anc->print_table       = 0;
+-
+-	anc->option_reuse      = 0;
+-	anc->option_recreate   = 0;
+-
+-	anc->vlabel_changed    = 0;
+-	anc->vtoc_changed      = 0;
+-	anc->blksize           = 0;
+-	anc->fspace_trk        = 0;
+-	anc->label_pos         = 0;
++	bzero(anc, sizeof(fdasd_anchor_t));
+ 
+ 	for (i=0; i<USABLE_PARTITIONS; i++)
+ 		setpos(anc, i, -1);
+@@ -272,24 +252,18 @@ fdasd_initialize_anchor (fdasd_anchor_t * anc)
+ 		if (p == NULL)
+ 			fdasd_error(anc, malloc_failed,
+ 				    _("No room for partition info."));
+-		p->used       = 0x00;
+-		p->len_trk    = 0;
+-		p->start_trk  = 0;
+-		p->fspace_trk = 0;
+-		p->type       = 0;
++		bzero(p, sizeof(partition_info_t));
+ 
+ 		/* add p to double pointered list */
+ 		if (i == 1) {
+-	        anc->first = p;
+-			p->prev = NULL;
++		        anc->first = p;
+ 		} else if (i == USABLE_PARTITIONS) {
+-	        anc->last = p;
+-	        p->next = NULL;
++		        anc->last = p;
+ 			p->prev = q;
+ 			q->next = p;
+ 		} else {
+-	        p->prev = q;
+-	        q->next = p;
++	                p->prev = q;
++	                q->next = p;
+ 		}
+ 
+ 		p->f1 = malloc(sizeof(format1_label_t));
+@@ -946,16 +920,78 @@ fdasd_check_api_version (fdasd_anchor_t *anc, int f)
+ 	}
+ }
+ 
++/*
++ * The following two functions match those in the DASD ECKD device driver.
++ * They are used to compute how many records of a given size can be stored
++ * in one track.
++ */
++static unsigned int ceil_quot(unsigned int d1, unsigned int d2)
++{
++	return (d1 + (d2 - 1)) / d2;
++}
++
++/* kl: key length, dl: data length */
++static unsigned int recs_per_track(unsigned short dev_type, unsigned int kl,
++				   unsigned int dl)
++{
++	unsigned int dn, kn;
++
++	switch (dev_type) {
++	case DASD_3380_TYPE:
++		if (kl)
++			return 1499 / (15 + 7 + ceil_quot(kl + 12, 32) +
++				       ceil_quot(dl + 12, 32));
++		else
++			return 1499 / (15 + ceil_quot(dl + 12, 32));
++	case DASD_3390_TYPE:
++		dn = ceil_quot(dl + 6, 232) + 1;
++		if (kl) {
++			kn = ceil_quot(kl + 6, 232) + 1;
++			return 1729 / (10 + 9 + ceil_quot(kl + 6 * kn, 34) +
++				       9 + ceil_quot(dl + 6 * dn, 34));
++		} else
++			return 1729 / (10 + 9 + ceil_quot(dl + 6 * dn, 34));
++	case DASD_9345_TYPE:
++		dn = ceil_quot(dl + 6, 232) + 1;
++		if (kl) {
++			kn = ceil_quot(kl + 6, 232) + 1;
++			return 1420 / (18 + 7 + ceil_quot(kl + 6 * kn, 34) +
++				       ceil_quot(dl + 6 * dn, 34));
++		} else
++			return 1420 / (18 + 7 + ceil_quot(dl + 6 * dn, 34));
++	}
++	return 0;
++}
++
++/*
++ * Verify that number of tracks (heads) per cylinder and number of
++ * sectors per track match the expected values for a given device type
++ * and block size.
++ * Returns 1 for a valid match and 0 otherwise.
++ */
++static int fdasd_verify_geometry(unsigned short dev_type, int blksize,
++				 struct fdasd_hd_geometry *geometry)
++{
++	unsigned int expected_sectors;
++	if (geometry->heads != 15)
++		return 0;
++	expected_sectors = recs_per_track(dev_type, 0, blksize);
++	if (geometry->sectors == expected_sectors)
++		return 1;
++	return 0;
++}
++
+ /*
+  * reads dasd geometry data
+  */
+-void
++int
+ fdasd_get_geometry (const PedDevice *dev, fdasd_anchor_t *anc, int f)
+ {
+ 	PDEBUG
+ 	int blksize = 0;
+ 	dasd_information_t dasd_info;
+ 	struct dasd_eckd_characteristics *characteristics;
++	unsigned long long size_in_bytes;
+ 
+ 	/* We can't get geometry from a regular file,
+ 	   so simulate something usable, for the sake of testing.  */
+@@ -979,6 +1015,12 @@ fdasd_get_geometry (const PedDevice *dev, fdasd_anchor_t *anc, int f)
+ 				anc->geo.heads;
+ 	    anc->is_file = 1;
+ 	} else {
++	        if (ioctl(f, BLKGETSIZE64, &size_in_bytes) != 0) {
++		        fdasd_error(anc, unable_to_ioctl,
++				    _("Could not retrieve disk size."));
++			goto error;
++		}
++
+ 		if (ioctl(f, HDIO_GETGEO, &anc->geo) != 0)
+ 			fdasd_error(anc, unable_to_ioctl,
+ 			    _("Could not retrieve disk geometry information."));
+@@ -988,27 +1030,51 @@ fdasd_get_geometry (const PedDevice *dev, fdasd_anchor_t *anc, int f)
+ 			    _("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."));
+-
+-		characteristics = (struct dasd_eckd_characteristics *)
+-					&dasd_info.characteristics;
+-		if (characteristics->no_cyl == LV_COMPAT_CYL &&
+-		    characteristics->long_no_cyl)
+-			anc->hw_cylinders = characteristics->long_no_cyl;
+-		else
+-			anc->hw_cylinders = characteristics->no_cyl;
++		if (ioctl(f, BIODASDINFO, &dasd_info) != 0) {
++		        /* verify that the geometry matches a 3390 DASD */
++		        if (!fdasd_verify_geometry(DASD_3390_TYPE, blksize,
++						   &anc->geo)) {
++			        fdasd_error(anc, wrong_disk_type,
++					    _("Disk geometry does not match a " \
++					      "DASD device of type 3390."));
++				goto error;
++			}
++			anc->dev_type = DASD_3390_TYPE;
++			anc->hw_cylinders =
++			        size_in_bytes / (blksize * anc->geo.heads * anc->geo.sectors);
++			/* The VOL1 label on a CDL formatted ECKD DASD is in block 2
++			 * It will be verified later, if this position actually holds a
++			 * valid label record.
++			 */
++			anc->label_pos = 2 * blksize;
++			/* A devno 0 is actually a valid devno, which could exist
++			 * in the system. Since we use this number only to create
++			 * a default volume serial, there is no serious conflict.
++			 */
++			anc->devno = 0;
++		} else {
++		        characteristics = (struct dasd_eckd_characteristics *)
++			        &dasd_info.characteristics;
++			if (characteristics->no_cyl == LV_COMPAT_CYL &&
++			        characteristics->long_no_cyl)
++		                anc->hw_cylinders = characteristics->long_no_cyl;
++			else
++		                anc->hw_cylinders = characteristics->no_cyl;
++			anc->dev_type = dasd_info.dev_type;
++			anc->label_pos = dasd_info.label_block * blksize;
++			anc->devno = dasd_info.devno;
++			anc->label_block = dasd_info.label_block;
++			anc->FBA_layout = dasd_info.FBA_layout;
++		}
+ 
+ 		anc->is_file = 0;
+ 	}
+ 
+-	anc->dev_type   = dasd_info.dev_type;
+-	anc->blksize    = blksize;
+-	anc->label_pos  = dasd_info.label_block * blksize;
+-	anc->devno      = dasd_info.devno;
+-	anc->label_block = dasd_info.label_block;
+-	anc->FBA_layout = dasd_info.FBA_layout;
++	anc->blksize = blksize;
++	return 1;
++
++ error:
++	return 0;
+ }
+ 
+ /*
+-- 
+2.20.1
+
diff --git a/SOURCES/0052-dasd-enhance-device-probing.patch b/SOURCES/0052-dasd-enhance-device-probing.patch
new file mode 100644
index 0000000..9f78667
--- /dev/null
+++ b/SOURCES/0052-dasd-enhance-device-probing.patch
@@ -0,0 +1,242 @@
+From 75958b299ed01eadbbcf1df31dacacfcaf8bc13a Mon Sep 17 00:00:00 2001
+From: Viktor Mihajlovski <mihajlov@linux.vnet.ibm.com>
+Date: Thu, 17 Sep 2015 15:33:29 +0200
+Subject: [PATCH 52/54] dasd: enhance device probing
+
+Probe for all device/transport types as every block device
+could be a DASD on s390.
+
+Since the calculation of the minimum and optimum alignment
+is different between DASDs and common fixed block disks
+we need a means other than dev->type == PED_DEVICE_DASD.
+For that purpose a static function _ped_device_like_dasd()
+offering a DASD detection heuristic has been added to
+arch/linux.c.
+
+By always providing arch-specific alignment functions the
+need for DASD-specific code could be removed from device.c.
+
+Observe fdasd_get_geometry return code for proper error
+handling.
+
+Remove the obsolete API check as we no longer require the
+DASD-specific IOCTLs.
+
+Signed-off-by: Viktor Mihajlovski <mihajlov@linux.vnet.ibm.com>
+Acked-by: Stefan Haberland <stefan.haberland@de.ibm.com>
+Signed-off-by: Hendrik Brueckner <brueckner@linux.vnet.ibm.com>
+Signed-off-by: Brian C. Lane <bcl@redhat.com>
+
+(cherry picked from commit 834713b5aee1edc004f863231dd489ee3a79f536)
+
+Related: rhbz#1676604
+---
+ libparted/arch/linux.c  | 85 +++++++++++++++++++++++++++++++++--------
+ libparted/device.c      | 14 ++-----
+ libparted/labels/dasd.c | 18 ++++-----
+ 3 files changed, 82 insertions(+), 35 deletions(-)
+
+diff --git a/libparted/arch/linux.c b/libparted/arch/linux.c
+index 6e78faf..56cfe6f 100644
+--- a/libparted/arch/linux.c
++++ b/libparted/arch/linux.c
+@@ -727,9 +727,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
+@@ -3112,19 +3116,72 @@ linux_disk_commit (PedDisk* disk)
+ {
+         if (disk->dev->type != PED_DEVICE_FILE) {
+ 
+-		/* We now require BLKPG support.  If this assertion fails,
+-		   please write to the mailing list describing your system.
+-		   Assuming it's never triggered, ...
+-		   FIXME: remove this assertion in 2012.  */
+-		assert (_have_blkpg ());
++                /* We now require BLKPG support.  If this assertion fails,
++                   please write to the mailing list describing your system.
++                   Assuming it's never triggered, ...
++                   FIXME: remove this assertion in 2012.  */
++                assert (_have_blkpg ());
+ 
+-		if (!_disk_sync_part_table (disk))
+-			return 0;
++                if (!_disk_sync_part_table (disk))
++                        return 0;
+         }
+ 
+         return 1;
+ }
+ 
++#if defined __s390__ || defined __s390x__
++/**
++ * 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
++ */
++static int
++_ped_device_like_dasd(const PedDevice *dev)
++{
++        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));
++}
++
++
++
++static PedAlignment*
++s390_get_minimum_alignment(const PedDevice *dev)
++{
++#if USE_BLKID
++        return linux_get_minimum_alignment(dev);
++#else
++        return ped_alignment_new(0,
++                                 dev->phys_sector_size
++                                 / dev->sector_size);
++#endif
++}
++
++static PedAlignment*
++s390_get_optimum_alignment(const PedDevice *dev)
++{
++        /* DASD needs to use minimum alignment */
++        if (_ped_device_like_dasd(dev))
++                return s390_get_minimum_alignment(dev);
++#if USE_BLKID
++        return linux_get_optimum_alignment(dev);
++#else
++        return NULL;
++#endif
++}
++#endif
++
+ #if USE_BLKID
+ static PedAlignment*
+ linux_get_minimum_alignment(const PedDevice *dev)
+@@ -3165,15 +3222,10 @@ linux_get_optimum_alignment(const PedDevice *dev)
+ 		&& PED_DEFAULT_ALIGNMENT % optimal_io == 0)
+ 	    || (!optimal_io && minimum_io
+ 		&& PED_DEFAULT_ALIGNMENT % minimum_io == 0)
+-           ) {
+-            /* DASD needs to use minimum alignment */
+-            if (dev->type == PED_DEVICE_DASD)
+-                return linux_get_minimum_alignment(dev);
+-
++           )
+             return ped_alignment_new(
+                     blkid_topology_get_alignment_offset(tp) / dev->sector_size,
+                     PED_DEFAULT_ALIGNMENT / dev->sector_size);
+-        }
+ 
+         /* If optimal_io_size is 0 and we don't meet the other criteria
+            for using the device.c default, return the minimum alignment. */
+@@ -3200,7 +3252,10 @@ static PedDeviceArchOps linux_dev_ops = {
+         sync:           linux_sync,
+         sync_fast:      linux_sync_fast,
+         probe_all:      linux_probe_all,
+-#if USE_BLKID
++#if defined __s390__ || defined __s390x__
++        get_minimum_alignment:	s390_get_minimum_alignment,
++        get_optimum_alignment:	s390_get_optimum_alignment,
++#elif USE_BLKID
+         get_minimum_alignment:	linux_get_minimum_alignment,
+         get_optimum_alignment:	linux_get_optimum_alignment,
+ #endif
+diff --git a/libparted/device.c b/libparted/device.c
+index cdcc117..36fecd2 100644
+--- a/libparted/device.c
++++ b/libparted/device.c
+@@ -550,16 +550,10 @@ 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:
+-                        align = ped_device_get_minimum_alignment(dev);
+-                        break;
+-                default:
+-                        /* Align to a grain of 1MiB (like vista / win7) */
+-                        align = ped_alignment_new(0,
+-                                                  (PED_DEFAULT_ALIGNMENT
+-						   / dev->sector_size));
+-                }
++                /* Align to a grain of 1MiB (like vista / win7) */
++                align = ped_alignment_new(0,
++                                          (PED_DEFAULT_ALIGNMENT
++                                           / dev->sector_size));
+         }
+ 
+         return align;
+diff --git a/libparted/labels/dasd.c b/libparted/labels/dasd.c
+index 5bffda7..a4be1fd 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++;
+-- 
+2.20.1
+
diff --git a/SOURCES/0053-parted-fix-build-error-on-s390.patch b/SOURCES/0053-parted-fix-build-error-on-s390.patch
new file mode 100644
index 0000000..0cd849b
--- /dev/null
+++ b/SOURCES/0053-parted-fix-build-error-on-s390.patch
@@ -0,0 +1,147 @@
+From f0d72664c7c121bd4f4002356d8a9b75860418d4 Mon Sep 17 00:00:00 2001
+From: Colin Watson <cjwatson@ubuntu.com>
+Date: Thu, 29 Oct 2015 21:12:01 +0100
+Subject: [PATCH 53/54] parted: fix build error on s390
+
+The preceding dasd probing patches have introduced a compile error
+when building with blkid support. Fixed by reordering function
+definitions.
+
+Signed-off-by: Colin Watson <cjwatson@ubuntu.com>
+Signed-off-by: Viktor Mihajlovski <mihajlov@linux.vnet.ibm.com>
+Signed-off-by: Brian C. Lane <bcl@redhat.com>
+
+(cherry picked from commit 388bab890a4e09b09d2428c0e773ed083295f91b)
+
+Related: rhbz#1676604
+---
+ libparted/arch/linux.c | 106 ++++++++++++++++++++---------------------
+ 1 file changed, 53 insertions(+), 53 deletions(-)
+
+diff --git a/libparted/arch/linux.c b/libparted/arch/linux.c
+index 56cfe6f..cc40a1a 100644
+--- a/libparted/arch/linux.c
++++ b/libparted/arch/linux.c
+@@ -3129,59 +3129,6 @@ linux_disk_commit (PedDisk* disk)
+         return 1;
+ }
+ 
+-#if defined __s390__ || defined __s390x__
+-/**
+- * 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
+- */
+-static int
+-_ped_device_like_dasd(const PedDevice *dev)
+-{
+-        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));
+-}
+-
+-
+-
+-static PedAlignment*
+-s390_get_minimum_alignment(const PedDevice *dev)
+-{
+-#if USE_BLKID
+-        return linux_get_minimum_alignment(dev);
+-#else
+-        return ped_alignment_new(0,
+-                                 dev->phys_sector_size
+-                                 / dev->sector_size);
+-#endif
+-}
+-
+-static PedAlignment*
+-s390_get_optimum_alignment(const PedDevice *dev)
+-{
+-        /* DASD needs to use minimum alignment */
+-        if (_ped_device_like_dasd(dev))
+-                return s390_get_minimum_alignment(dev);
+-#if USE_BLKID
+-        return linux_get_optimum_alignment(dev);
+-#else
+-        return NULL;
+-#endif
+-}
+-#endif
+-
+ #if USE_BLKID
+ static PedAlignment*
+ linux_get_minimum_alignment(const PedDevice *dev)
+@@ -3238,6 +3185,59 @@ linux_get_optimum_alignment(const PedDevice *dev)
+ }
+ #endif
+ 
++#if defined __s390__ || defined __s390x__
++/**
++ * 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
++ */
++static int
++_ped_device_like_dasd(const PedDevice *dev)
++{
++        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));
++}
++
++
++
++static PedAlignment*
++s390_get_minimum_alignment(const PedDevice *dev)
++{
++#if USE_BLKID
++        return linux_get_minimum_alignment(dev);
++#else
++        return ped_alignment_new(0,
++                                 dev->phys_sector_size
++                                 / dev->sector_size);
++#endif
++}
++
++static PedAlignment*
++s390_get_optimum_alignment(const PedDevice *dev)
++{
++        /* DASD needs to use minimum alignment */
++        if (_ped_device_like_dasd(dev))
++                return s390_get_minimum_alignment(dev);
++#if USE_BLKID
++        return linux_get_optimum_alignment(dev);
++#else
++        return NULL;
++#endif
++}
++#endif
++
+ static PedDeviceArchOps linux_dev_ops = {
+         _new:           linux_new,
+         destroy:        linux_destroy,
+-- 
+2.20.1
+
diff --git a/SOURCES/0054-fdasd.c-Safeguard-against-geometry-misprobing.patch b/SOURCES/0054-fdasd.c-Safeguard-against-geometry-misprobing.patch
new file mode 100644
index 0000000..e38ffe7
--- /dev/null
+++ b/SOURCES/0054-fdasd.c-Safeguard-against-geometry-misprobing.patch
@@ -0,0 +1,52 @@
+From ef7c01a23e2cacecbf86c02e7657d8a9d6cc48dd Mon Sep 17 00:00:00 2001
+From: Viktor Mihajlovski <mihajlov@linux.vnet.ibm.com>
+Date: Fri, 5 Feb 2016 14:47:11 +0100
+Subject: [PATCH 54/54] fdasd.c: Safeguard against geometry misprobing
+
+Fixes an issue with parted print being run against a logical
+volume realised by extents on a physical volume residing on
+a DASD.
+We must make sure that geometry, device blocksize and DASD
+attributes are present before we start format verifications
+If any of it is missing this is not a DASD.
+
+Signed-off-by: Viktor Mihajlovski <mihajlov@linux.vnet.ibm.com>
+Signed-off-by: Brian C. Lane <bcl@redhat.com>
+
+(cherry picked from commit 8c6de55e4375bd63ae0d0dc7dd7104a7c2290cac)
+
+Related: rhbz#1676604
+---
+ libparted/labels/fdasd.c | 11 +++++++++--
+ 1 file changed, 9 insertions(+), 2 deletions(-)
+
+diff --git a/libparted/labels/fdasd.c b/libparted/labels/fdasd.c
+index 7e6a77a..968b332 100644
+--- a/libparted/labels/fdasd.c
++++ b/libparted/labels/fdasd.c
+@@ -1021,13 +1021,20 @@ fdasd_get_geometry (const PedDevice *dev, fdasd_anchor_t *anc, int f)
+ 			goto error;
+ 		}
+ 
+-		if (ioctl(f, HDIO_GETGEO, &anc->geo) != 0)
++		if (ioctl(f, HDIO_GETGEO, &anc->geo) != 0 ||
++		        anc->geo.heads == 0 ||
++		        anc->geo.sectors == 0 ||
++		        anc->geo.cylinders == 0 ) {
+ 			fdasd_error(anc, unable_to_ioctl,
+ 			    _("Could not retrieve disk geometry information."));
++			goto error;
++		}
+ 
+-		if (ioctl(f, BLKSSZGET, &blksize) != 0)
++		if (ioctl(f, BLKSSZGET, &blksize) != 0) {
+ 			fdasd_error(anc, unable_to_ioctl,
+ 			    _("Could not retrieve blocksize information."));
++			goto error;
++		}
+ 
+ 		/* get disk type */
+ 		if (ioctl(f, BIODASDINFO, &dasd_info) != 0) {
+-- 
+2.20.1
+
diff --git a/SOURCES/0055-Add-part-label-documentation-to-mkpart-command.patch b/SOURCES/0055-Add-part-label-documentation-to-mkpart-command.patch
new file mode 100644
index 0000000..9165347
--- /dev/null
+++ b/SOURCES/0055-Add-part-label-documentation-to-mkpart-command.patch
@@ -0,0 +1,36 @@
+From 5d2ebcc83aecad33805559f202aeb1a6f36f5ecd Mon Sep 17 00:00:00 2001
+From: Fedora Ninjas <parted-owner@fedoraproject.org>
+Date: Wed, 27 Mar 2019 09:12:19 -0700
+Subject: [PATCH] Add part-label documentation to mkpart command
+
+The documentation was not clear that the first field is a partition type
+on MBR and a label on GPT.
+
+Resolves: rhbz#1686659
+---
+ doc/C/parted.8 | 5 +++--
+ 1 file changed, 3 insertions(+), 2 deletions(-)
+
+diff --git a/doc/C/parted.8 b/doc/C/parted.8
+index 5a24c94..080a8cf 100644
+--- a/doc/C/parted.8
++++ b/doc/C/parted.8
+@@ -73,12 +73,13 @@ Create a new disklabel (partition table) of \fIlabel-type\fP.  \fIlabel-type\fP
+ should be one of "aix", "amiga", "bsd", "dvh", "gpt", "loop", "mac", "msdos",
+ "pc98", or "sun".
+ .TP
+-.B mkpart \fIpart-type\fP \fI[fs-type]\fP \fIstart\fP \fIend\fP
++.B mkpart \fI[part-type|part-label]\fP \fI[fs-type]\fP \fIstart\fP \fIend\fP
+ Make a \fIpart-type\fP partition for filesystem \fIfs-type\fP (if specified),
+ beginning at \fIstart\fP and ending at \fIend\fP (by default in megabytes).
+ \fIfs-type\fP can be one of "btrfs", "ext2", "ext3", "ext4", "fat16", "fat32",
+ "hfs", "hfs+", "linux-swap", "ntfs", "reiserfs", or "xfs".
+-\fIpart-type\fP should be one of "primary", "logical", or "extended".
++For MBR labeled devices \fIpart-type\fP should be one of "primary", "logical", or "extended".
++For GPT labeled devices \fIpart-label\fP is used instead, and can be any short alphanumeric string.
+ .TP
+ .B name \fIpartition\fP \fIname\fP
+ Set the name of \fIpartition\fP to \fIname\fP. This option works only on Mac,
+-- 
+2.20.1
+
diff --git a/SPECS/parted.spec b/SPECS/parted.spec
index 1f453cb..43d206f 100644
--- a/SPECS/parted.spec
+++ b/SPECS/parted.spec
@@ -4,7 +4,7 @@
 Summary: The GNU disk partition manipulation program
 Name:    parted
 Version: 3.1
-Release: 29%{?dist}
+Release: 31%{?dist}
 License: GPLv3+
 Group:   Applications/System
 URL:     http://www.gnu.org/software/parted
@@ -64,6 +64,13 @@ Patch45: 0045-parted-Add-stub-resize-command-for-backward-compatib.patch
 Patch46: 0046-libparted-Backport-partition-resize-code.patch
 Patch47: 0047-tests-excersise-resize-command.patch
 Patch48: 0048-parted-add-resizepart-command.patch
+Patch49: 0049-partprobe-always-close-dev-when-probing-disks.patch
+Patch50: 0050-tests-Add-t4201-to-test-partprobe-with-1025-devices.patch
+Patch51: 0051-fdasd-geometry-handling-updated-from-upstream-s390-t.patch
+Patch52: 0052-dasd-enhance-device-probing.patch
+Patch53: 0053-parted-fix-build-error-on-s390.patch
+Patch54: 0054-fdasd.c-Safeguard-against-geometry-misprobing.patch
+Patch55: 0055-Add-part-label-documentation-to-mkpart-command.patch
 
 Buildroot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n)
 BuildRequires: e2fsprogs-devel
@@ -200,6 +207,22 @@ fi
 
 
 %changelog
+* Wed Mar 27 2019 Brian C. Lane <bcl@redhat.com> - 3.1-31
+- Backport patches for dasd on virtio
+  fdasd: geometry handling updated from upstream s390-tools
+  dasd: enhance device probing
+  parted: fix build error on s390
+  fdasd.c: Safeguard against geometry misprobing
+  Resolves: rhbz#1676604
+- Add part-label documentation to mkpart command
+  Resolves: rhbz#1686659
+
+* Tue Feb 26 2019 Brian C. Lane <bcl@redhat.com> - 3.1-30
+- partprobe: always close dev when probing disks
+  Resolves: rhbz#1551411
+- tests: Add t4201 to test partprobe with 1025 devices
+  Related: rhbz#1551411
+
 * Thu Aug 10 2017 Brian C. Lane <bcl@redhat.com> - 3.1-29
 - Add support for NVMe devices
   Resolves: rhbz#1316239