diff options
author | Jim Meyering <meyering@redhat.com> | 2009-11-12 16:00:41 +0100 |
---|---|---|
committer | Jim Meyering <meyering@redhat.com> | 2009-11-27 11:08:12 +0100 |
commit | 50b1d2bb1a4e199ca6ecdb73be2d15677600c76d (patch) | |
tree | bd60e3d86d09c30a9ae04f2352fd212c2eeab3d2 /libparted/labels/fdasd.c | |
parent | 3938eca7eb771a1f05d1f3acd994a490a55406b5 (diff) | |
download | parted-50b1d2bb1a4e199ca6ecdb73be2d15677600c76d.tar.gz |
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@redhat.com>
Diffstat (limited to 'libparted/labels/fdasd.c')
-rw-r--r-- | libparted/labels/fdasd.c | 61 |
1 files changed, 43 insertions, 18 deletions
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, |