summaryrefslogtreecommitdiff
path: root/libparted/labels/fdasd.c
diff options
context:
space:
mode:
authorJim Meyering <meyering@redhat.com>2009-11-12 16:00:41 +0100
committerJim Meyering <meyering@redhat.com>2009-11-27 11:08:12 +0100
commit50b1d2bb1a4e199ca6ecdb73be2d15677600c76d (patch)
treebd60e3d86d09c30a9ae04f2352fd212c2eeab3d2 /libparted/labels/fdasd.c
parent3938eca7eb771a1f05d1f3acd994a490a55406b5 (diff)
downloadparted-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.c61
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,