diff --git a/0001-fdasd-geometry-handling-updated-from-upstream-s390-t.patch b/0001-fdasd-geometry-handling-updated-from-upstream-s390-t.patch new file mode 100644 index 0000000..f2d591c --- /dev/null +++ b/0001-fdasd-geometry-handling-updated-from-upstream-s390-t.patch @@ -0,0 +1,276 @@ +From: Viktor Mihajlovski +Date: Thu, 17 Sep 2015 15:33:28 +0200 +Subject: fdasd: geometry handling updated from upstream s390-tools +References: fate#320525 / bsc#935127 +Patch-mainline: v3.3 +Git-commit: 4d480d980a9b69b432b8d60df3c4397ba8cdc965 + +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 +Acked-by: Stefan Haberland +Signed-off-by: Hendrik Brueckner +Signed-off-by: Brian C. Lane +Acked-by: Sebastian Parschauer +--- + include/parted/fdasd.in.h | 4 +- + libparted/labels/fdasd.c | 166 ++++++++++++++++++++++++++++++++-------------- + 2 files changed, 119 insertions(+), 51 deletions(-) + +--- a/include/parted/fdasd.in.h ++++ b/include/parted/fdasd.in.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); +--- a/libparted/labels/fdasd.c ++++ b/libparted/labels/fdasd.c +@@ -210,27 +210,7 @@ fdasd_initialize_anchor (fdasd_anchor_t + 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; iused = 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)); +@@ -947,15 +921,77 @@ fdasd_check_api_version (fdasd_anchor_t + } + + /* ++ * 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 + 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 + _("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; + } + + /* diff --git a/0002-dasd-enhance-device-probing.patch b/0002-dasd-enhance-device-probing.patch new file mode 100644 index 0000000..2e1cb7c --- /dev/null +++ b/0002-dasd-enhance-device-probing.patch @@ -0,0 +1,213 @@ +From: Viktor Mihajlovski +Date: Thu, 17 Sep 2015 15:33:29 +0200 +Subject: dasd: enhance device probing +References: fate#320525 / bsc#935127 +Patch-mainline: v3.3 +Git-commit: 834713b5aee1edc004f863231dd489ee3a79f536 + +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 +Acked-by: Stefan Haberland +Signed-off-by: Hendrik Brueckner +Signed-off-by: Brian C. Lane +Acked-by: Sebastian Parschauer +--- + libparted/arch/linux.c | 72 ++++++++++++++++++++++++++++++++++++++++++------ + libparted/device.c | 14 ++------- + libparted/labels/dasd.c | 18 +++++------- + 3 files changed, 76 insertions(+), 28 deletions(-) + +--- a/libparted/arch/linux.c ++++ b/libparted/arch/linux.c +@@ -814,9 +814,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 +@@ -3259,6 +3263,60 @@ 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) +@@ -3299,15 +3357,10 @@ linux_get_optimum_alignment(const PedDev + && 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. */ +@@ -3372,7 +3425,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, + wipe_signatures: linux_wipe_signatures, +--- a/libparted/device.c ++++ b/libparted/device.c +@@ -550,16 +550,10 @@ ped_device_get_optimum_alignment(const P + /* 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; +--- a/libparted/labels/dasd.c ++++ b/libparted/labels/dasd.c +@@ -224,19 +224,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) && +@@ -286,7 +280,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) +@@ -645,7 +641,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++; diff --git a/0003-parted-fix-build-error-on-s390.patch b/0003-parted-fix-build-error-on-s390.patch new file mode 100644 index 0000000..f5c358e --- /dev/null +++ b/0003-parted-fix-build-error-on-s390.patch @@ -0,0 +1,142 @@ +From: Colin Watson +Date: Thu, 29 Oct 2015 21:12:01 +0100 +Subject: parted: fix build error on s390 +References: fate#320525 / bsc#935127 +Patch-mainline: v3.3 +Git-commit: 388bab890a4e09b09d2428c0e773ed083295f91b + +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 +Signed-off-by: Viktor Mihajlovski +Signed-off-by: Brian C. Lane +Acked-by: Sebastian Parschauer +--- + libparted/arch/linux.c | 107 ++++++++++++++++++++++++------------------------- + 1 file changed, 54 insertions(+), 53 deletions(-) + +--- a/libparted/arch/linux.c ++++ b/libparted/arch/linux.c +@@ -3263,59 +3263,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* +@@ -3411,6 +3358,60 @@ error: + } + #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, diff --git a/0004-fdasd.c-Safeguard-against-geometry-misprobing.patch b/0004-fdasd.c-Safeguard-against-geometry-misprobing.patch new file mode 100644 index 0000000..dda7b43 --- /dev/null +++ b/0004-fdasd.c-Safeguard-against-geometry-misprobing.patch @@ -0,0 +1,46 @@ +From: Viktor Mihajlovski +Date: Fri, 5 Feb 2016 14:47:11 +0100 +Subject: fdasd.c: Safeguard against geometry misprobing +References: fate#320525 / bsc#935127 +Patch-mainline: v3.3 +Git-commit: 8c6de55e4375bd63ae0d0dc7dd7104a7c2290cac + +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 +Signed-off-by: Brian C. Lane +Acked-by: Sebastian Parschauer +--- + libparted/labels/fdasd.c | 11 +++++++++-- + 1 file changed, 9 insertions(+), 2 deletions(-) + +--- a/libparted/labels/fdasd.c ++++ b/libparted/labels/fdasd.c +@@ -1021,13 +1021,20 @@ fdasd_get_geometry (const PedDevice *dev + 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) { diff --git a/0005-libparted-Remove-fdasd-geometry-code-from-alloc_meta.patch b/0005-libparted-Remove-fdasd-geometry-code-from-alloc_meta.patch new file mode 100644 index 0000000..daf8b3a --- /dev/null +++ b/0005-libparted-Remove-fdasd-geometry-code-from-alloc_meta.patch @@ -0,0 +1,46 @@ +From: "Brian C. Lane" +Date: Mon, 11 Apr 2016 15:10:51 -0700 +Subject: libparted: Remove fdasd geometry code from alloc_metadata + (#1244833) +References: fate#320525 / bsc#935127 +Patch-mainline: v3.3 +Git-commit: c58f816ffbc0bc4eacfb57d492cbe3b7497ede9f + +commit db20944f changed how the trailing_metadata_end is calculated in +dasd_alloc_metadata, removing the need for setting up the anchor struct. +But dasd_alloc_metadata can be called in various contexts, and the +arch_specific->fd may or may not be valid during these calls. This can +result in unpredictable crashes when it uses a stale fd and tries to run +the file image code in fdasd_get_geometry instead of the device code. + +The solution is to just drop the unneeded code, and to remember that +arch_specific->fd should only be used when ped_device_open has first +been called. + +Resolves: rhbz#1244833 +Acked-by: Sebastian Parschauer +--- + libparted/labels/dasd.c | 4 ---- + 1 file changed, 4 deletions(-) + +--- a/libparted/labels/dasd.c ++++ b/libparted/labels/dasd.c +@@ -998,7 +998,6 @@ dasd_alloc_metadata (PedDisk* disk) + PedPartition* part = NULL; /* initialize solely to placate gcc */ + PedPartition* new_part2; + PedSector trailing_meta_start, trailing_meta_end; +- struct fdasd_anchor anchor; + + PED_ASSERT (disk != NULL); + PED_ASSERT (disk->dev != NULL); +@@ -1048,10 +1047,7 @@ dasd_alloc_metadata (PedDisk* disk) + backed up, then restored to a larger size disk, etc. + */ + trailing_meta_start = part->geom.end + 1; +- fdasd_initialize_anchor(&anchor); +- fdasd_get_geometry(disk->dev, &anchor, arch_specific->fd); + trailing_meta_end = (long long) disk->dev->length - 1; +- fdasd_cleanup(&anchor); + if (trailing_meta_end >= trailing_meta_start) { + new_part2 = ped_partition_new (disk,PED_PARTITION_METADATA, + NULL, trailing_meta_start, trailing_meta_end); diff --git a/libparted-Add-support-for-RAM-drives.patch b/libparted-Add-support-for-RAM-drives.patch new file mode 100644 index 0000000..e92236b --- /dev/null +++ b/libparted-Add-support-for-RAM-drives.patch @@ -0,0 +1,95 @@ +From: Sebastian Parschauer +Date: Tue, 14 Mar 2017 16:40:00 +0100 +Subject: Add support for RAM drives +References: bsc#1006834 +Patch-mainline: v3.3 +Git-commit: 21131f62c6f508a5d0c080e025cf7db5df43fc7d + +Recognize RAM drives, so "parted -s /dev/ram0 p" now prints +"RAM Drive (brd)" instead of "Model: Unknown (unknown)". + +In order for a device to be recognized as RAM drive, it has to +have major number 1. Also the BLKFLSBUF ioctl shouldn't be used +on RAM drives as it is used to zero the device. + +* NEWS: Mention the change +* include/parted/device.h.in(PedDeviceType): Add PED_DEVICE_RAM. +* libparted/arch/linux.c(RAM_MAJOR): New define. +* libparted/arch/linux.c(_device_probe_type): Recognize RAM drives. +* libparted/arch/linux.c(linux_new): Handle RAM drives. +* libparted/arch/linux.c(_flush_cache): Skip RAM drives. +* parted/parted.c(do_print): Add "brd" to list of transports. + +Signed-off-by: Sebastian Parschauer +--- + include/parted/device.in.h | 3 ++- + libparted/arch/linux.c | 12 ++++++++++-- + parted/parted.c | 2 +- + 3 files changed, 13 insertions(+), 4 deletions(-) + +--- a/include/parted/device.in.h ++++ b/include/parted/device.in.h +@@ -50,7 +50,8 @@ typedef enum { + PED_DEVICE_AOE = 16, + PED_DEVICE_MD = 17, + PED_DEVICE_LOOP = 18, +- PED_DEVICE_NVME = 19 ++ PED_DEVICE_NVME = 19, ++ PED_DEVICE_RAM = 20 + } PedDeviceType; + + typedef struct _PedDevice PedDevice; +--- a/libparted/arch/linux.c ++++ b/libparted/arch/linux.c +@@ -280,6 +280,7 @@ struct blkdev_ioctl_param { + #define LOOP_MAJOR 7 + #define MD_MAJOR 9 + #define BLKEXT_MAJOR 259 ++#define RAM_MAJOR 1 + + #define SCSI_BLK_MAJOR(M) ( \ + (M) == SCSI_DISK0_MAJOR \ +@@ -721,6 +722,8 @@ _device_probe_type (PedDevice* dev) + dev->type = PED_DEVICE_MD; + } else if (_is_blkext_major(dev_major) && dev->path && strstr(dev->path, "nvme")) { + dev->type = PED_DEVICE_NVME; ++ } else if (dev_major == RAM_MAJOR) { ++ dev->type = PED_DEVICE_RAM; + } else { + dev->type = PED_DEVICE_UNKNOWN; + } +@@ -1553,6 +1556,11 @@ linux_new (const char* path) + goto error_free_arch_specific; + break; + ++ case PED_DEVICE_RAM: ++ if (!init_generic (dev, _("RAM Drive"))) ++ goto error_free_arch_specific; ++ break; ++ + default: + ped_exception_throw (PED_EXCEPTION_NO_FEATURE, + PED_EXCEPTION_CANCEL, +@@ -1625,9 +1633,9 @@ _flush_cache (PedDevice* dev) + { + LinuxSpecific* arch_specific = LINUX_SPECIFIC (dev); + int i; +- int lpn = _device_get_partition_range(dev); ++ int lpn = _device_get_partition_range(dev); + +- if (dev->read_only) ++ if (dev->read_only || dev->type == PED_DEVICE_RAM) + return; + dev->dirty = 0; + +--- a/parted/parted.c ++++ b/parted/parted.c +@@ -1035,7 +1035,7 @@ _print_disk_info (const PedDevice *dev, + "cpqarray", "file", "ataraid", "i2o", + "ubd", "dasd", "viodasd", "sx8", "dm", + "xvd", "sd/mmc", "virtblk", "aoe", +- "md", "loopback", "nvme"}; ++ "md", "loopback", "nvme", "brd"}; + + char* start = ped_unit_format (dev, 0); + PedUnit default_unit = ped_unit_get_default (); diff --git a/libparted-dasd-add-new-fdasd-functions.patch b/libparted-dasd-add-new-fdasd-functions.patch index fe063a2..44b50e0 100644 --- a/libparted-dasd-add-new-fdasd-functions.patch +++ b/libparted-dasd-add-new-fdasd-functions.patch @@ -25,7 +25,7 @@ Acked-by: Sebastian Parschauer --- a/include/parted/fdasd.in.h +++ b/include/parted/fdasd.in.h -@@ -291,5 +291,9 @@ void fdasd_recreate_vtoc(fdasd_anchor_t +@@ -293,5 +293,9 @@ void fdasd_recreate_vtoc(fdasd_anchor_t partition_info_t * fdasd_add_partition (fdasd_anchor_t *anc, unsigned int start, unsigned int stop); int fdasd_prepare_labels (fdasd_anchor_t *anc, int fd) ; @@ -37,7 +37,7 @@ Acked-by: Sebastian Parschauer #endif /* FDASD_H */ --- a/libparted/labels/fdasd.c +++ b/libparted/labels/fdasd.c -@@ -1247,4 +1247,127 @@ fdasd_add_partition (fdasd_anchor_t *anc +@@ -1320,4 +1320,127 @@ fdasd_add_partition (fdasd_anchor_t *anc return p; } diff --git a/libparted-dasd-update-and-improve-fdasd-functions.patch b/libparted-dasd-update-and-improve-fdasd-functions.patch index 4cc1caa..3a84f3a 100644 --- a/libparted-dasd-update-and-improve-fdasd-functions.patch +++ b/libparted-dasd-update-and-improve-fdasd-functions.patch @@ -29,7 +29,7 @@ Acked-by: Sebastian Parschauer /* re-read partition table */ #define BLKRRPART _IO(0x12,95) /* get block device sector size */ -@@ -196,15 +197,14 @@ typedef struct format_data_t { +@@ -198,15 +199,14 @@ typedef struct format_data_t { /***************************************************************************** * SECTION: FDASD internal types * *****************************************************************************/ @@ -48,7 +48,7 @@ Acked-by: Sebastian Parschauer #define DEVICE "device" #define DISC "disc" #define PART "part" -@@ -231,9 +231,6 @@ typedef struct config_data { +@@ -233,9 +233,6 @@ typedef struct config_data { typedef struct fdasd_anchor { int vlabel_changed; int vtoc_changed; @@ -58,7 +58,7 @@ Acked-by: Sebastian Parschauer int auto_partition; int print_table; int big_disk; -@@ -280,7 +277,8 @@ enum fdasd_failure { +@@ -282,7 +279,8 @@ enum fdasd_failure { vlabel_corrupted, dsname_corrupted, malloc_failed, @@ -125,7 +125,7 @@ Acked-by: Sebastian Parschauer default: sprintf(error, "fdasd: %s: %s\n", _("Fatal error"), str); } -@@ -313,7 +314,7 @@ fdasd_write_vtoc_labels (fdasd_anchor_t +@@ -287,7 +288,7 @@ fdasd_write_vtoc_labels (fdasd_anchor_t PDEBUG partition_info_t *p; unsigned long b, maxblk; @@ -134,7 +134,7 @@ Acked-by: Sebastian Parschauer int i = 0, k = 0; cchhb_t f9addr; format1_label_t emptyf1; -@@ -545,7 +546,6 @@ fdasd_recreate_vtoc (fdasd_anchor_t *anc +@@ -519,7 +520,6 @@ fdasd_recreate_vtoc (fdasd_anchor_t *anc int i; vtoc_init_format4_label(anc->f4, @@ -142,7 +142,7 @@ Acked-by: Sebastian Parschauer anc->geo.cylinders, anc->formatted_cylinders, anc->geo.heads, -@@ -793,7 +793,7 @@ fdasd_invalid_vtoc_pointer(fdasd_anchor_ +@@ -767,7 +767,7 @@ fdasd_invalid_vtoc_pointer(fdasd_anchor_ anc->formatted_cylinders = anc->hw_cylinders; anc->fspace_trk = anc->formatted_cylinders * anc->geo.heads - FIRST_USABLE_TRK; @@ -151,7 +151,7 @@ Acked-by: Sebastian Parschauer anc->geo.cylinders, anc->formatted_cylinders, anc->geo.heads, anc->geo.sectors, anc->blksize, anc->dev_type); -@@ -807,6 +807,8 @@ fdasd_invalid_vtoc_pointer(fdasd_anchor_ +@@ -781,6 +781,8 @@ fdasd_invalid_vtoc_pointer(fdasd_anchor_ anc->formatted_cylinders, anc->geo.heads); vtoc_set_cchhb(&anc->vlabel->vtoc, VTOC_START_CC, VTOC_START_HH, 0x01); @@ -160,7 +160,7 @@ Acked-by: Sebastian Parschauer } /* -@@ -818,7 +820,7 @@ fdasd_process_invalid_vtoc(fdasd_anchor_ +@@ -792,7 +794,7 @@ fdasd_process_invalid_vtoc(fdasd_anchor_ anc->formatted_cylinders = anc->hw_cylinders; anc->fspace_trk = anc->formatted_cylinders * anc->geo.heads - FIRST_USABLE_TRK; @@ -169,7 +169,7 @@ Acked-by: Sebastian Parschauer anc->geo.cylinders, anc->formatted_cylinders, anc->geo.heads, anc->geo.sectors, anc->blksize, anc->dev_type); -@@ -829,6 +831,8 @@ fdasd_process_invalid_vtoc(fdasd_anchor_ +@@ -803,6 +805,8 @@ fdasd_process_invalid_vtoc(fdasd_anchor_ FIRST_USABLE_TRK, anc->formatted_cylinders * anc->geo.heads - 1, anc->formatted_cylinders, anc->geo.heads); @@ -178,7 +178,7 @@ Acked-by: Sebastian Parschauer } -@@ -901,7 +905,7 @@ fdasd_check_volume (fdasd_anchor_t *anc, +@@ -875,7 +879,7 @@ fdasd_check_volume (fdasd_anchor_t *anc, fdasd_init_volume_label(anc, fd); @@ -187,7 +187,7 @@ Acked-by: Sebastian Parschauer anc->geo.cylinders, anc->formatted_cylinders, anc->geo.heads, anc->geo.sectors, anc->blksize, anc->dev_type); -@@ -1213,12 +1217,10 @@ fdasd_add_partition (fdasd_anchor_t *anc +@@ -1286,12 +1290,10 @@ fdasd_add_partition (fdasd_anchor_t *anc return 0; if (anc->formatted_cylinders > LV_COMPAT_CYL) { diff --git a/parted.changes b/parted.changes index e0073a8..84d83a2 100644 --- a/parted.changes +++ b/parted.changes @@ -1,3 +1,22 @@ +------------------------------------------------------------------- +Tue May 16 15:28:47 CEST 2017 - sparschauer@suse.de + +- Enhance fdasd detection and probing (bsc#935127, fate#320525) + - add: 0001-fdasd-geometry-handling-updated-from-upstream-s390-t.patch + - add: 0002-dasd-enhance-device-probing.patch + - add: 0003-parted-fix-build-error-on-s390.patch + - add: 0004-fdasd.c-Safeguard-against-geometry-misprobing.patch + - add: 0005-libparted-Remove-fdasd-geometry-code-from-alloc_meta.patch + - refresh: libparted-dasd-update-and-improve-fdasd-functions.patch + - refresh: libparted-dasd-add-new-fdasd-functions.patch + +------------------------------------------------------------------- +Thu May 11 12:53:20 CEST 2017 - sparschauer@suse.de + +- Add support for RAM drives for not erasing them when printing + their partitions (bsc#1006834) + - add: libparted-Add-support-for-RAM-drives.patch + ------------------------------------------------------------------- Tue May 2 10:45:37 CEST 2017 - sparschauer@suse.de diff --git a/parted.spec b/parted.spec index edd31e0..f1d264d 100644 --- a/parted.spec +++ b/parted.spec @@ -63,10 +63,17 @@ Patch34: parted-implement-wipesignatures-option.patch Patch35: libparted-Add-support-for-NVMe-devices.patch Patch36: libparted-fix-nvme-partition-naming.patch Patch37: libparted-dont-warn-if-no-HDIO_GET_IDENTITY.patch +# fate#320525 / bsc#935127 +Patch38: 0001-fdasd-geometry-handling-updated-from-upstream-s390-t.patch +Patch39: 0002-dasd-enhance-device-probing.patch +Patch40: 0003-parted-fix-build-error-on-s390.patch +Patch41: 0004-fdasd.c-Safeguard-against-geometry-misprobing.patch +Patch42: 0005-libparted-Remove-fdasd-geometry-code-from-alloc_meta.patch # fate#321531 -Patch38: libparted-dasd-unify-vtoc-handling-for-cdl-ldl.patch -Patch39: libparted-dasd-update-and-improve-fdasd-functions.patch -Patch40: libparted-dasd-add-new-fdasd-functions.patch +Patch43: libparted-dasd-unify-vtoc-handling-for-cdl-ldl.patch +Patch44: libparted-dasd-update-and-improve-fdasd-functions.patch +Patch45: libparted-dasd-add-new-fdasd-functions.patch +Patch46: libparted-Add-support-for-RAM-drives.patch Patch100: parted-fatresize-autoconf.patch BuildRequires: check-devel BuildRequires: device-mapper-devel >= 1.02.33 @@ -150,6 +157,12 @@ to develop applications that require these. %patch38 -p1 %patch39 -p1 %patch40 -p1 +%patch41 -p1 +%patch42 -p1 +%patch43 -p1 +%patch44 -p1 +%patch45 -p1 +%patch46 -p1 %patch100 -p1 %build