317 lines
11 KiB
Diff
317 lines
11 KiB
Diff
|
From bc854d48563ff30ba4c55914baa8db0a271790e5 Mon Sep 17 00:00:00 2001
|
||
|
From: Joel Granados Moreno <jgranado@redhat.com>
|
||
|
Date: Thu, 16 Jul 2009 20:16:43 +0200
|
||
|
Subject: [PATCH] Add duplicate functionality to dasd type lables.
|
||
|
|
||
|
* libparted/labels/dasd.c (dasd_alloc): Add the errno to the exception
|
||
|
message to ease debugging.
|
||
|
(dasd_partition_duplicate): New function.
|
||
|
(dasd_duplicate): Include all the dasd specific structures in the
|
||
|
duplicate disk.
|
||
|
(dasd_partition_new): Handle the case when malloc fails because of lack
|
||
|
of memory.
|
||
|
(dasd_disk_ops): Add the new dasd_partition_duplicate hook.
|
||
|
---
|
||
|
libparted/labels/dasd.c | 234 ++++++++++++++++++++++++++++++++++++++++++++---
|
||
|
1 files changed, 222 insertions(+), 12 deletions(-)
|
||
|
|
||
|
diff --git a/libparted/labels/dasd.c b/libparted/labels/dasd.c
|
||
|
index ec73d09..e87daba 100644
|
||
|
--- a/libparted/labels/dasd.c
|
||
|
+++ b/libparted/labels/dasd.c
|
||
|
@@ -23,6 +23,7 @@
|
||
|
#include <config.h>
|
||
|
|
||
|
#include <stdio.h>
|
||
|
+#include <string.h>
|
||
|
#include <errno.h>
|
||
|
#include <ctype.h>
|
||
|
#include <time.h>
|
||
|
@@ -58,6 +59,9 @@
|
||
|
|
||
|
extern void ped_disk_dasd_init ();
|
||
|
extern void ped_disk_dasd_done ();
|
||
|
+static PedPartition* dasd_partition_new (const PedDisk*, PedPartitionType,
|
||
|
+ const PedFileSystemType*,
|
||
|
+ PedSector, PedSector);
|
||
|
|
||
|
#define DASD_NAME "dasd"
|
||
|
|
||
|
@@ -104,7 +108,8 @@ dasd_alloc (const PedDevice* dev)
|
||
|
&disk_specific->real_sector_size) == -1) {
|
||
|
ped_exception_throw(PED_EXCEPTION_ERROR, PED_EXCEPTION_CANCEL,
|
||
|
_("Unable to determine the block "
|
||
|
- "size of this dasd"));
|
||
|
+ "size of this dasd - %s"),
|
||
|
+ strerror(errno));
|
||
|
free(disk_specific);
|
||
|
free(disk);
|
||
|
return NULL;
|
||
|
@@ -113,19 +118,216 @@ dasd_alloc (const PedDevice* dev)
|
||
|
return disk;
|
||
|
}
|
||
|
|
||
|
+static PedPartition*
|
||
|
+dasd_partition_duplicate (const PedPartition* part, PedDisk* disk)
|
||
|
+{
|
||
|
+ PedPartition* walk;
|
||
|
+ PedPartition* new_part;
|
||
|
+ format1_label_t* new_format1;
|
||
|
+ partition_info_t* new_part_info;
|
||
|
+ partition_info_t* old_part_info;
|
||
|
+ DasdPartitionData* old_dasd_data;
|
||
|
+ DasdPartitionData* temp_dasd_data;
|
||
|
+ DasdDiskSpecific* old_disk_specific;
|
||
|
+ partition_info_t* old_anchor_first;
|
||
|
+ partition_info_t* old_anchor_last;
|
||
|
+ char* error_message;
|
||
|
+
|
||
|
+ /* Initialize old_* variables. */
|
||
|
+ old_dasd_data = (DasdPartitionData*) part->disk_specific;
|
||
|
+ old_part_info = (partition_info_t*) old_dasd_data->part_info;
|
||
|
+ old_disk_specific = (DasdDiskSpecific*) part->disk->disk_specific;
|
||
|
+ old_anchor_first = (partition_info_t*) old_disk_specific->anchor->first;
|
||
|
+ old_anchor_last = (partition_info_t*) old_disk_specific->anchor->last;
|
||
|
+ /* The default error message. */
|
||
|
+ error_message = "Could not allocate memory for dasd specific structure.";
|
||
|
+
|
||
|
+ /* Handle the DasdPartitionData->partition_info_t->format1_label_t pointer. */
|
||
|
+ new_format1 = (format1_label_t*) ped_malloc (sizeof (format1_label_t));
|
||
|
+ if (!new_format1)
|
||
|
+ goto error;
|
||
|
+ memcpy (new_format1, old_part_info->f1, sizeof (format1_label_t));
|
||
|
+
|
||
|
+ /* Handle the DasdPartitionData->partition_info_t pointer. */
|
||
|
+ new_part_info = (partition_info_t*) ped_malloc (sizeof (partition_info_t));
|
||
|
+ if (!new_part_info)
|
||
|
+ goto error_free_format1;
|
||
|
+ memcpy (new_part_info, old_part_info, sizeof (partition_info_t));
|
||
|
+ new_part_info->f1 = new_format1;
|
||
|
+ new_part_info->next = NULL;
|
||
|
+ new_part_info->prev = NULL;
|
||
|
+
|
||
|
+ /* Try to set new_part_info->next, new_part_info->prev,
|
||
|
+ * disk->disk_specific->anchor->first & disk->disk_specific->anchor->last
|
||
|
+ * when disk is not NULL.
|
||
|
+ */
|
||
|
+ if (disk)
|
||
|
+ {
|
||
|
+ /* Handle the next and prev pointers. */
|
||
|
+ /* Look for the prev. */
|
||
|
+ if (old_part_info->prev == NULL || part->prev == NULL)
|
||
|
+ new_part_info->prev = NULL;
|
||
|
+ else
|
||
|
+ {
|
||
|
+ for (walk = disk->part_list ; walk ; walk = walk->next)
|
||
|
+ {
|
||
|
+ /* Identify the partition by start and length sectors. */
|
||
|
+ if (walk->geom.start == part->prev->geom.start
|
||
|
+ && walk->geom.length == part->prev->geom.length)
|
||
|
+ {
|
||
|
+ /* Verify the new_part_info->prev and the walk->next. */
|
||
|
+ temp_dasd_data = (DasdPartitionData*) walk->disk_specific;
|
||
|
+ new_part_info->prev = (partition_info_t*) temp_dasd_data->part_info;
|
||
|
+ ((partition_info_t*)temp_dasd_data->part_info)->next = new_part_info;
|
||
|
+ break;
|
||
|
+ }
|
||
|
+ }
|
||
|
+ }
|
||
|
+
|
||
|
+ /* Look for the next. */
|
||
|
+ if (old_part_info->next == NULL || part->next == NULL)
|
||
|
+ new_part_info->next = NULL;
|
||
|
+ else
|
||
|
+ {
|
||
|
+ for (walk = disk->part_list ; walk ; walk = walk->next)
|
||
|
+ {
|
||
|
+ /* Identify the partition by start and length sectors. */
|
||
|
+ if (walk->geom.start == part->next->geom.start
|
||
|
+ && walk->geom.length == part->next->geom.length)
|
||
|
+ {
|
||
|
+ /* Verify the new_part_info->next and the walk->prev. */
|
||
|
+ temp_dasd_data = (DasdPartitionData*) walk->disk_specific;
|
||
|
+ new_part_info->next = (partition_info_t*) temp_dasd_data->part_info;
|
||
|
+ ((partition_info_t*)temp_dasd_data->part_info)->prev = new_part_info;
|
||
|
+ break;
|
||
|
+ }
|
||
|
+ }
|
||
|
+ }
|
||
|
+
|
||
|
+ /* Handle the DasdDiskSpecific->fdasd_anchor->last &&
|
||
|
+ * Handle the DasdDiskSpecific->fdasd_anchor->first. */
|
||
|
+ if ( old_anchor_first->start_trk == new_part_info->start_trk
|
||
|
+ && old_anchor_first->len_trk == new_part_info->len_trk)
|
||
|
+ ((DasdDiskSpecific*) disk->disk_specific)->anchor->first = new_part_info;
|
||
|
+ else if ( old_anchor_last->start_trk == new_part_info->start_trk
|
||
|
+ && old_anchor_last->len_trk == new_part_info->len_trk)
|
||
|
+ ((DasdDiskSpecific*) disk->disk_specific)->anchor->last = new_part_info;
|
||
|
+ }
|
||
|
+
|
||
|
+ /* Create new partition. Allocates memory for DasdPartitionData. */
|
||
|
+ new_part = dasd_partition_new (part->disk, part->type, part->fs_type,
|
||
|
+ part->geom.start, part->geom.end);
|
||
|
+ if (!new_part)
|
||
|
+ goto error_free_part_info;
|
||
|
+ new_part->num = part->num;
|
||
|
+
|
||
|
+ /* Handle the DasdPartitionData pointer. */
|
||
|
+ memcpy (new_part->disk_specific, old_dasd_data, sizeof (DasdPartitionData));
|
||
|
+ ((DasdPartitionData*)new_part->disk_specific)->part_info = new_part_info;
|
||
|
+
|
||
|
+ return new_part;
|
||
|
+
|
||
|
+error_free_part_info:
|
||
|
+ free(new_part_info);
|
||
|
+error_free_format1:
|
||
|
+ free(new_format1);
|
||
|
+error:
|
||
|
+ ped_exception_throw(PED_EXCEPTION_ERROR, PED_EXCEPTION_CANCEL,
|
||
|
+ _(error_message));
|
||
|
+ return NULL;
|
||
|
+}
|
||
|
+
|
||
|
static PedDisk*
|
||
|
dasd_duplicate (const PedDisk* disk)
|
||
|
{
|
||
|
- PedDisk* new_disk;
|
||
|
-
|
||
|
- new_disk = ped_disk_new_fresh(disk->dev, &dasd_disk_type);
|
||
|
-
|
||
|
- if (!new_disk)
|
||
|
- return NULL;
|
||
|
-
|
||
|
- new_disk->disk_specific = NULL;
|
||
|
-
|
||
|
- return new_disk;
|
||
|
+ PedDisk* new_disk;
|
||
|
+ DasdDiskSpecific* old_disk_specific;
|
||
|
+ fdasd_anchor_t* new_anchor;
|
||
|
+ fdasd_anchor_t* old_anchor;
|
||
|
+ format4_label_t* new_format4;
|
||
|
+ format5_label_t* new_format5;
|
||
|
+ format7_label_t* new_format7;
|
||
|
+ volume_label_t* new_volume;
|
||
|
+ char* error_message;
|
||
|
+
|
||
|
+ /* Initialize old_* variables. */
|
||
|
+ old_disk_specific = disk->disk_specific;
|
||
|
+ old_anchor = old_disk_specific->anchor;
|
||
|
+ /* The default error message. */
|
||
|
+ error_message = "Could not allocate memory for dasd specific structure.";
|
||
|
+
|
||
|
+ /* Handle DasdDiskSpecific->fdasd_anchor->format4_label_t. */
|
||
|
+ new_format4 = (format4_label_t*) ped_malloc (sizeof (format4_label_t));
|
||
|
+ if (!new_format4)
|
||
|
+ goto error;
|
||
|
+ memcpy (new_format4, old_disk_specific->anchor->f4, sizeof (format4_label_t));
|
||
|
+
|
||
|
+ /* Handle DasdDiskSpecific->fdasd_anchor->format5_label_t. */
|
||
|
+ new_format5 = (format5_label_t*) ped_malloc (sizeof (format5_label_t));
|
||
|
+ if (!new_format5)
|
||
|
+ goto error_free_format4;
|
||
|
+ memcpy (new_format5, old_disk_specific->anchor->f5, sizeof (format5_label_t));
|
||
|
+
|
||
|
+ /* Handle DasdDiskSpecific->fdasd_anchor->format7_label_t. */
|
||
|
+ new_format7 = (format7_label_t*) ped_malloc (sizeof (format7_label_t));
|
||
|
+ if (!new_format7)
|
||
|
+ goto error_free_format5;
|
||
|
+ memcpy (new_format7, old_disk_specific->anchor->f7, sizeof (format7_label_t));
|
||
|
+
|
||
|
+ /* Handle DasdDiskSpecific->fdasd_anchor->volume_label_t. */
|
||
|
+ new_volume = (volume_label_t*) ped_malloc (sizeof (volume_label_t));
|
||
|
+ if (!new_volume)
|
||
|
+ goto error_free_format7;
|
||
|
+ memcpy (new_volume, old_disk_specific->anchor->vlabel,
|
||
|
+ sizeof (volume_label_t));
|
||
|
+
|
||
|
+ /* Handle DasdDiskSpecific->fdasd_anchor. */
|
||
|
+ if (! (new_anchor = (fdasd_anchor_t*) ped_malloc (sizeof (fdasd_anchor_t))))
|
||
|
+ goto error_free_volume;
|
||
|
+ memcpy (new_anchor, old_anchor, sizeof (fdasd_anchor_t));
|
||
|
+ new_anchor->f4 = new_format4;
|
||
|
+ new_anchor->f5 = new_format5;
|
||
|
+ new_anchor->f7 = new_format7;
|
||
|
+ new_anchor->vlabel = new_volume;
|
||
|
+ /* We dont have last and first info yet. */
|
||
|
+ new_anchor->last = NULL;
|
||
|
+ new_anchor->first = NULL;
|
||
|
+
|
||
|
+ /* Handle new disk creation. ped_disk_new_fresh allocates memory for
|
||
|
+ * new_disk->disk_specific. */
|
||
|
+ /* We need to make sure that the device is open for reading. */
|
||
|
+ if (!ped_device_open(disk->dev))
|
||
|
+ {
|
||
|
+ error_message = "Could not open device for dasd disk duplication";
|
||
|
+ goto error_free_anchor;
|
||
|
+ }
|
||
|
+ new_disk = ped_disk_new_fresh (disk->dev, &dasd_disk_type);
|
||
|
+ if (!ped_device_close(disk->dev))
|
||
|
+ {
|
||
|
+ error_message = "Could not close device for dasd disk duplication";
|
||
|
+ goto error_free_anchor;
|
||
|
+ }
|
||
|
+ if (!new_disk)
|
||
|
+ goto error_free_anchor;
|
||
|
+ memcpy (new_disk->disk_specific, old_disk_specific, sizeof(DasdDiskSpecific));
|
||
|
+ ((DasdDiskSpecific*)new_disk->disk_specific)->anchor = new_anchor;
|
||
|
+
|
||
|
+ return new_disk;
|
||
|
+
|
||
|
+error_free_anchor:
|
||
|
+ free(new_anchor);
|
||
|
+error_free_volume:
|
||
|
+ free(new_volume);
|
||
|
+error_free_format7:
|
||
|
+ free(new_format7);
|
||
|
+error_free_format5:
|
||
|
+ free(new_format5);
|
||
|
+error_free_format4:
|
||
|
+ free(new_format4);
|
||
|
+error:
|
||
|
+ ped_exception_throw(PED_EXCEPTION_ERROR, PED_EXCEPTION_CANCEL,
|
||
|
+ _(error_message));
|
||
|
+ return NULL;
|
||
|
}
|
||
|
|
||
|
static void
|
||
|
@@ -551,12 +753,20 @@ dasd_partition_new (const PedDisk* disk, PedPartitionType part_type,
|
||
|
goto error;
|
||
|
|
||
|
part->disk_specific = ped_malloc (sizeof (DasdPartitionData));
|
||
|
+ if (!part->disk_specific)
|
||
|
+ goto error_free_part;
|
||
|
return part;
|
||
|
|
||
|
+error_free_part:
|
||
|
+ free(part);
|
||
|
error:
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
+/*
|
||
|
+ * Frees the memory of an active partition. Active here is whatever
|
||
|
+ * ped_partition_is_active returns.
|
||
|
+ */
|
||
|
static void
|
||
|
dasd_partition_destroy (PedPartition* part)
|
||
|
{
|
||
|
@@ -818,6 +1028,7 @@ static PedDiskOps dasd_disk_ops = {
|
||
|
partition_set_system: dasd_partition_set_system,
|
||
|
|
||
|
partition_new: dasd_partition_new,
|
||
|
+ partition_duplicate: dasd_partition_duplicate,
|
||
|
partition_destroy: dasd_partition_destroy,
|
||
|
partition_set_flag: dasd_partition_set_flag,
|
||
|
partition_get_flag: dasd_partition_get_flag,
|
||
|
@@ -831,7 +1042,6 @@ static PedDiskOps dasd_disk_ops = {
|
||
|
get_max_primary_partition_count: dasd_get_max_primary_partition_count,
|
||
|
get_max_supported_partition_count: dasd_get_max_supported_partition_count,
|
||
|
|
||
|
- partition_duplicate: NULL
|
||
|
};
|
||
|
|
||
|
static PedDiskType dasd_disk_type = {
|
||
|
--
|
||
|
1.6.0.6
|
||
|
|