[parted-devel] [PATCH] delete driver partitions correctly from
disks with mac label
Olaf Hering
olh at suse.de
Sat Apr 8 14:22:52 UTC 2006
'parted $device rm 2' to remove a driver partition does not work correctly.
The partition block0 has an entry for the number of available driver partitions.
At the end, block0 has a list of block ranges and types of these drivers.
parted removes just the entries from the partition table, but it does not update the
list in block0. When MacOS 9 tries to access such a disk, it just crashes very early in boot.
This patch updates the block struct and related comments.
The check wether a partition is_driver or not did just match partition types.
But as shown in the list below, it would match partitions that do not hold drivers
listed in the block0 driver table. Also, the ->is_driver range check would trigger for
Apple_Driver_IOKit and Apple_FWDriver. But these partitions have no drivers.
Avoid the incorrect assert for these partition types.
pdisk -l /dev/sda
Partition map (with 512 byte blocks) on '/dev/sda'
#: type name length base ( size )
1: Apple_partition_map 'Apple ' 63 @ 1
2: Apple_Driver43*'Macintosh ' 54 @ 64
3: Apple_Driver43*'Macintosh ' 74 @ 118
4: Apple_Driver_IOKit 'Macintosh ' 512 @ 192
5: Apple_Patches 'Patch Partition' 512 @ 704
6: Apple_HFS 'untitled ' 17848774 @ 1216 ( 8.5G)
7: Apple_Free 'Extra ' 10 @ 17849990
Device block size=512, Number of Blocks=17849999 (8.5G)
DeviceType=0x0, DeviceId=0x0
Drivers-
1: 22 @ 64, type=0x1
2: 36 @ 118, type=0xffff
nectarine:~ # pdisk -l /dev/hdb
Partition map (with 512 byte blocks) on '/dev/hdb'
#: type name length base ( size )
1: Apple_partition_map 'Apple ' 63 @ 1
2: Apple_Driver43*'Macintosh ' 56 @ 64
3: Apple_Driver43*'Macintosh ' 56 @ 120
4: Apple_Driver_ATA*'Macintosh ' 56 @ 176
5: Apple_Driver_ATA*'Macintosh ' 56 @ 232
6: Apple_FWDriver 'Macintosh ' 512 @ 288
7: Apple_Driver_IOKit 'Macintosh ' 512 @ 800
8: Apple_Patches 'Patch Partition' 512 @ 1312
9: Apple_HFS 'Untitled ' 66721 @ 1824 ( 32.6M)
10: Apple_UNIX_SVR2 'swap ' 800352 @ 68545 (390.8M)
11: Apple_UNIX_SVR2 'untitled ' 52595423 @ 868897 ( 25.1G)
Device block size=512, Number of Blocks=53464320 (25.5G)
DeviceType=0x0, DeviceId=0x0
Drivers-
1: 23 @ 64, type=0x1
2: 36 @ 120, type=0xffff
3: 21 @ 176, type=0x701
4: 34 @ 232, type=0xf8ff
nectarine:~ # pdisk -l /dev/hdc
Partition map (with 512 byte blocks) on '/dev/hdc'
#: type name length base ( size )
1: Apple_partition_map 'Apple ' 63 @ 1
2: Apple_Driver43_CD*'Macintosh ' 120 @ 196
3: Apple_Driver_ATAPI*'Macintosh ' 56 @ 316
4: Apple_Driver43 'Macintosh ' 14 @ 16
5: Apple_Driver_ATAPI*'Macintosh ' 120 @ 372
6: Apple_Patches 'Patch Partition' 512 @ 492
7: Apple_HFS 'Mac OS 9 ' 1310720 @ 1004 (640.0M)
8: Apple_Driver43 'Macintosh ' 19 @ 30
9: Apple_Free ' ' 15284 @ 1311724 ( 7.5M)
Device block size=2048, Number of Blocks=331752 (648.0M)
DeviceType=0x1, DeviceId=0x1
Drivers-
1: 5 @ 16, (20 at 64) type=0x1
2: 25 @ 49, (100 at 196) type=0xffff
3: 5 @ 79, (20 at 316) type=0x701
4: 26 @ 93, (104 at 372) type=0xf8ff
---
libparted/labels/mac.c | 110 +++++++++++++++++++++++++++++++++++++++++++------
1 file changed, 97 insertions(+), 13 deletions(-)
Index: parted-mainline/libparted/labels/mac.c
===================================================================
--- parted-mainline.orig/libparted/labels/mac.c
+++ parted-mainline/libparted/labels/mac.c
@@ -113,20 +113,24 @@ typedef struct {
uint16_t dev_id; /* reserved */
uint32_t data; /* reserved */
uint16_t driver_count; /* # of driver descriptor entries */
- uint32_t start; /* first driver's starting block */
- uint16_t size; /* size of driver in blocks */
- uint16_t os_type; /* operating system type (MacOS = 1) */
- uint16_t specific[242]; /* info about additional drivers */
- uint16_t unused; /* pad to 512 bytes */
+ uint8_t driverlist[488]; /* info about available drivers */
+ uint16_t padding[3]; /* pad to 512 bytes */
} __attribute__ ((packed)) MacRawDisk;
typedef struct {
+ uint32_t block; /* startblock in MacRawDisk->block_size units */
+ uint16_t size; /* size in 512 byte units */
+ uint16_t type; /* operating system type (MacOS = 1) */
+} __attribute__ ((packed)) MacDeviceDriver;
+
+typedef struct {
char volume_name[33]; /* eg: "Games" */
char system_name[33]; /* eg: "Apple_Unix_SVR2" */
char processor_name[17];
int is_boot;
int is_driver;
+ int has_driver;
int is_root;
int is_swap;
int is_lvm;
@@ -151,6 +155,10 @@ typedef struct {
int active_part_entry_count; /* # real partitions */
int free_part_entry_count; /* # free space */
int last_part_entry_num; /* last entry number */
+
+ uint16_t block_size; /* physical sector size */
+ uint16_t driver_count;
+ MacDeviceDriver driverlist[1 + 60]; /* 488 bytes */
} MacDiskData;
static PedDiskType mac_disk_type;
@@ -275,6 +283,9 @@ mac_alloc (const PedDevice* dev)
mac_disk_data->active_part_entry_count = 0;
mac_disk_data->free_part_entry_count = 1;
mac_disk_data->last_part_entry_num = 1;
+ mac_disk_data->block_size = 0;
+ mac_disk_data->driver_count = 0;
+ memset(&mac_disk_data->driverlist[0], 0, sizeof(mac_disk_data->driverlist));
if (!_disk_add_part_map_entry (disk, 0))
goto error_free_disk;
@@ -410,6 +421,26 @@ _rawpart_is_driver (MacRawPartition* raw
}
static int
+_rawpart_has_driver (MacRawPartition* raw_part, MacDiskData* mac_disk_data)
+{
+ MacDeviceDriver *driverlist;
+ uint16_t i, bsz;
+ uint32_t driver_bs, driver_be, part_be;
+
+ driverlist = &mac_disk_data->driverlist[0];
+ bsz = mac_disk_data->block_size / 512;
+ for (i = 0; i < mac_disk_data->driver_count; i++) {
+ driver_bs = driverlist->block * bsz;
+ driver_be = driver_bs + driverlist->size;
+ part_be = raw_part->start_block + raw_part->block_count;
+ if (driver_bs >= raw_part->start_block && driver_be <= part_be)
+ return 1;
+ driverlist++;
+ }
+ return 0;
+}
+
+static int
_rawpart_is_root (MacRawPartition* raw_part)
{
if (!_rawpart_cmp_type (raw_part, "Apple_UNIX_SVR2"))
@@ -523,6 +554,8 @@ _rawpart_analyse (MacRawPartition* raw_p
mac_part_data->is_boot = _rawpart_is_boot (raw_part);
mac_part_data->is_driver = _rawpart_is_driver (raw_part);
+ if (mac_part_data->is_driver)
+ mac_part_data->has_driver = _rawpart_has_driver(raw_part, mac_disk_data);
mac_part_data->is_root = _rawpart_is_root (raw_part);
mac_part_data->is_swap = _rawpart_is_swap (raw_part);
mac_part_data->is_lvm = _rawpart_is_lvm (raw_part);
@@ -560,7 +593,7 @@ _rawpart_analyse (MacRawPartition* raw_p
= PED_BE32_TO_CPU (raw_part->boot_count) * block_size;
#ifndef DISCOVER_ONLY
- if (mac_part_data->is_driver) {
+ if (mac_part_data->has_driver) {
if (mac_part_data->boot_region_length < part->geom.length) {
if (ped_exception_throw (
PED_EXCEPTION_ERROR,
@@ -725,6 +758,13 @@ mac_read (PedDisk* disk)
if (!ped_disk_delete_all (disk))
goto error;
+ if (raw_disk.driver_count && raw_disk.driver_count < 62) {
+ memcpy(&mac_disk_data->driverlist[0], &raw_disk.driverlist[0],
+ sizeof(mac_disk_data->driverlist));
+ mac_disk_data->driver_count = raw_disk.driver_count;
+ mac_disk_data->block_size = raw_disk.block_size;
+ }
+
for (num=1; num==1 || num <= last_part_entry_num; num++) {
if (!ped_device_read (disk->dev, &raw_part,
num * ghost_size, 1))
@@ -818,9 +858,37 @@ _pad_raw_part (PedDisk* disk, int num, M
return 1;
}
+static void
+_update_driver_count (MacRawPartition* part_map_entry,
+ MacDiskData *mac_driverdata, const MacDiskData* mac_disk_data)
+{
+ uint16_t i, count_orig, count_cur, bsz;
+ uint32_t driver_bs, driver_be, part_be;
+
+ bsz = mac_disk_data->block_size / 512;
+ count_cur = mac_driverdata->driver_count;
+ count_orig = mac_disk_data->driver_count;
+ for (i = 0; i < count_orig; i++) {
+ driver_bs = mac_disk_data->driverlist[i].block * bsz;
+ driver_be = driver_bs + mac_disk_data->driverlist[i].size;
+ part_be = part_map_entry->start_block + part_map_entry->block_count;
+ if (driver_bs >= part_map_entry->start_block
+ && driver_be <= part_be) {
+ mac_driverdata->driverlist[count_cur].block
+ = mac_disk_data->driverlist[i].block;
+ mac_driverdata->driverlist[count_cur].size
+ = mac_disk_data->driverlist[i].size;
+ mac_driverdata->driverlist[count_cur].type
+ = mac_disk_data->driverlist[i].type;
+ mac_driverdata->driver_count++;
+ break;
+ }
+ }
+}
+
static int
_generate_raw_part (PedDisk* disk, PedPartition* part,
- MacRawPartition* part_map)
+ MacRawPartition* part_map, MacDiskData *mac_driverdata)
{
MacDiskData* mac_disk_data;
MacPartitionData* mac_part_data;
@@ -844,9 +912,12 @@ _generate_raw_part (PedDisk* disk, PedPa
strcpy (part_map_entry->name, mac_part_data->volume_name);
strcpy (part_map_entry->type, mac_part_data->system_name);
- if (mac_part_data->is_driver)
+ if (mac_part_data->is_driver) {
mac_part_data->boot_region_length = part->geom.length;
- else
+ if (mac_part_data->has_driver)
+ _update_driver_count(part_map_entry, mac_driverdata,
+ mac_disk_data);
+ } else
mac_part_data->data_region_length = part->geom.length;
part_map_entry->data_count = PED_CPU_TO_BE32 (
mac_part_data->data_region_length / block_size);
@@ -942,7 +1013,7 @@ _get_first_empty_part_entry (PedDisk* di
}
static int
-write_block_zero (PedDisk* disk)
+write_block_zero (PedDisk* disk, MacDiskData* mac_driverdata)
{
PedDevice* dev = disk->dev;
MacRawDisk raw_disk;
@@ -955,6 +1026,10 @@ write_block_zero (PedDisk* disk)
raw_disk.block_count
= PED_CPU_TO_BE32 (dev->length / (dev->sector_size / 512));
+ raw_disk.driver_count = mac_driverdata->driver_count;
+ memcpy(&raw_disk.driverlist[0], &mac_driverdata->driverlist[0],
+ sizeof(raw_disk.driverlist));
+
return ped_device_write (dev, &raw_disk, 0, 1);
}
@@ -963,6 +1038,7 @@ mac_write (PedDisk* disk)
{
MacRawPartition* part_map;
MacDiskData* mac_disk_data;
+ MacDiskData* mac_driverdata; /* updated driver list */
PedPartition* part;
int num;
@@ -978,10 +1054,15 @@ mac_write (PedDisk* disk)
goto error;
}
+ mac_driverdata = ped_malloc(sizeof(MacDiskData));
+ if (!mac_driverdata)
+ goto error;
+ memset (mac_driverdata, 0, sizeof(MacDiskData));
+
part_map = (MacRawPartition*)
ped_malloc (mac_disk_data->part_map_entry_count * 512);
if (!part_map)
- goto error;
+ goto error_free_driverdata;
memset (part_map, 0, mac_disk_data->part_map_entry_count * 512);
/* write (to memory) the "real" partitions */
@@ -989,7 +1070,7 @@ mac_write (PedDisk* disk)
part = ped_disk_next_partition (disk, part)) {
if (!ped_partition_is_active (part))
continue;
- if (!_generate_raw_part (disk, part, part_map))
+ if (!_generate_raw_part (disk, part, part_map, mac_driverdata))
goto error_free_part_map;
}
@@ -1014,10 +1095,12 @@ mac_write (PedDisk* disk)
mac_disk_data->part_map_entry_count))
goto error_free_part_map;
ped_free (part_map);
- return write_block_zero (disk);
+ return write_block_zero (disk, mac_driverdata);
error_free_part_map:
ped_free (part_map);
+error_free_driverdata:
+ ped_free (mac_driverdata);
error:
return 0;
}
@@ -1046,6 +1129,7 @@ mac_partition_new (
mac_data->data_region_length = 0;
mac_data->boot_region_length = 0;
mac_data->is_driver = 0;
+ mac_data->has_driver = 0;
mac_data->is_boot = 0;
mac_data->is_root = 0;
mac_data->is_swap = 0;
More information about the parted-devel
mailing list