dasd_write(), was reading the volume label from the disk (trough
fdasd_check_volume()) and later writing it back again, this is fine for
existing dasd labels, but when creating a fresh label, this would
also cause the old volume label to be re-used, and if the old label
was corrupt, it would cause fdasd_check_volume() and thus dasd_write()
to fail. Reported here: http://bugzilla.redhat.com/533808
* libparted/arch/linux.c: include fdasd.h.
(init_dasd): Do BIODASDINFO ioctl, and store the dasd devno in
arch_specific.
(init_dasd): Remove dead (never reached) code.
* libparted/arch/linux.h (struct _LinuxSpecific): Add devno member.
* libparted/labels/dasd.c (DasdDiskSpecific): add vlabel member.
(dasd_alloc): Init DasdDiskSpecific.vlabel for fresh disks
(dasd_read): Store read vlabel in DasdDiskSpecific.vlabel.
(dasd_write): Write DasdDiskSpecific.vlabel instead of on disk vlabel.
#include <parted/parted.h>
#include <parted/debug.h>
#include <parted/parted.h>
#include <parted/debug.h>
+#if defined __s390__ || defined __s390x__
+#include <parted/fdasd.h>
+#endif
#include <ctype.h>
#include <errno.h>
#include <ctype.h>
#include <errno.h>
{
struct stat dev_stat;
struct hd_geometry geo;
{
struct stat dev_stat;
struct hd_geometry geo;
+ dasd_information_t dasd_info;
if (!_device_stat (dev, &dev_stat))
goto error;
if (!_device_stat (dev, &dev_stat))
goto error;
dev->hw_geom = dev->bios_geom;
}
dev->hw_geom = dev->bios_geom;
}
+ if (!ioctl(arch_specific->fd, BIODASDINFO, &dasd_info)) {
+ arch_specific->devno = dasd_info.devno;
+ } else {
+ arch_specific->devno = arch_specific->major * 256 +
+ arch_specific->minor;
+ }
+
dev->model = strdup (model_name);
ped_device_close (dev);
return 1;
dev->model = strdup (model_name);
ped_device_close (dev);
return 1;
- ped_exception_throw ( PED_EXCEPTION_ERROR,
- PED_EXCEPTION_IGNORE_CANCEL,
- errstr );
-
error_close_dev:
ped_device_close (dev);
error:
error_close_dev:
ped_device_close (dev);
error:
char* dmtype; /**< device map target type */
#if defined __s390__ || defined __s390x__
unsigned int real_sector_size;
char* dmtype; /**< device map target type */
#if defined __s390__ || defined __s390x__
unsigned int real_sector_size;
#endif
#if USE_BLKID
blkid_probe probe;
#endif
#if USE_BLKID
blkid_probe probe;
typedef struct {
unsigned int format_type;
typedef struct {
unsigned int format_type;
} DasdDiskSpecific;
static int dasd_probe (const PedDevice *dev);
} DasdDiskSpecific;
static int dasd_probe (const PedDevice *dev);
PedDisk* disk;
LinuxSpecific* arch_specific;
DasdDiskSpecific *disk_specific;
PedDisk* disk;
LinuxSpecific* arch_specific;
DasdDiskSpecific *disk_specific;
PED_ASSERT (dev != NULL, return NULL);
PED_ASSERT (dev != NULL, return NULL);
/* CDL format, newer */
disk_specific->format_type = 2;
/* CDL format, newer */
disk_specific->format_type = 2;
+ /* Setup volume label (for fresh disks) */
+ snprintf(volser, sizeof(volser), "0X%04X", arch_specific->devno);
+ vtoc_volume_label_init(&disk_specific->vlabel);
+ vtoc_volume_label_set_key(&disk_specific->vlabel, "VOL1");
+ vtoc_volume_label_set_label(&disk_specific->vlabel, "VOL1");
+ vtoc_volume_label_set_volser(&disk_specific->vlabel, volser);
+ vtoc_set_cchhb(&disk_specific->vlabel.vtoc,
+ VTOC_START_CC, VTOC_START_HH, 0x01);
+
if (fdasd_check_volume(&anchor, arch_specific->fd))
goto error_close_dev;
if (fdasd_check_volume(&anchor, arch_specific->fd))
goto error_close_dev;
+ /* Save volume label (read by fdasd_check_volume) for writing */
+ memcpy(&disk_specific->vlabel, anchor.vlabel, sizeof(volume_label_t));
+
if ((anchor.geo.cylinders * anchor.geo.heads) > BIG_DISK_SIZE)
anchor.big_disk++;
if ((anchor.geo.cylinders * anchor.geo.heads) > BIG_DISK_SIZE)
anchor.big_disk++;
/* initialize the anchor */
fdasd_initialize_anchor(&anchor);
fdasd_get_geometry(&anchor, arch_specific->fd);
/* initialize the anchor */
fdasd_initialize_anchor(&anchor);
fdasd_get_geometry(&anchor, arch_specific->fd);
-
- /* check dasd for labels and vtoc */
- if (fdasd_check_volume(&anchor, arch_specific->fd))
- goto error;
+ memcpy(anchor.vlabel, &disk_specific->vlabel, sizeof(volume_label_t));
+ anchor.vlabel_changed++;
if ((anchor.geo.cylinders * anchor.geo.heads) > BIG_DISK_SIZE)
anchor.big_disk++;
if ((anchor.geo.cylinders * anchor.geo.heads) > BIG_DISK_SIZE)
anchor.big_disk++;