655 lines
16 KiB
C
Executable File
655 lines
16 KiB
C
Executable File
/* -*- Mode: c; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
|
|
|
|
libparted - a library for manipulating disk partitions
|
|
Copyright (C) 2000-2001, 2007-2014, 2019-2023 Free Software Foundation,
|
|
Inc.
|
|
|
|
This program is free software; you can redistribute it and/or modify
|
|
it under the terms of the GNU General Public License as published by
|
|
the Free Software Foundation; either version 3 of the License, or
|
|
(at your option) any later version.
|
|
|
|
This program is distributed in the hope that it will be useful,
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
GNU General Public License for more details.
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
Contributor: Matt Wilson <msw@redhat.com>
|
|
*/
|
|
|
|
#include <config.h>
|
|
|
|
#include <stdbool.h>
|
|
#include <parted/parted.h>
|
|
#include <parted/debug.h>
|
|
#include <parted/endian.h>
|
|
#include <stdbool.h>
|
|
|
|
#if ENABLE_NLS
|
|
# include <libintl.h>
|
|
# define _(String) dgettext (PACKAGE, String)
|
|
#else
|
|
# define _(String) (String)
|
|
#endif /* ENABLE_NLS */
|
|
|
|
#include "misc.h"
|
|
#include "pt-tools.h"
|
|
|
|
/* struct's & #define's stolen from libfdisk, which probably came from
|
|
* Linux...
|
|
*/
|
|
|
|
#define BSD_DISKMAGIC (0x82564557UL) /* The disk magic number */
|
|
#define BSD_MAXPARTITIONS 8
|
|
#define BSD_FS_UNUSED 0 /* disklabel unused partition entry ID */
|
|
|
|
#define BSD_DTYPE_SMD 1 /* SMD, XSMD; VAX hp/up */
|
|
#define BSD_DTYPE_MSCP 2 /* MSCP */
|
|
#define BSD_DTYPE_DEC 3 /* other DEC (rk, rl) */
|
|
#define BSD_DTYPE_SCSI 4 /* SCSI */
|
|
#define BSD_DTYPE_ESDI 5 /* ESDI interface */
|
|
#define BSD_DTYPE_ST506 6 /* ST506 etc. */
|
|
#define BSD_DTYPE_HPIB 7 /* CS/80 on HP-IB */
|
|
#define BSD_DTYPE_HPFL 8 /* HP Fiber-link */
|
|
#define BSD_DTYPE_FLOPPY 10 /* floppy */
|
|
|
|
#define BSD_BBSIZE 8192 /* size of boot area, with label */
|
|
#define BSD_SBSIZE 8192 /* max size of fs superblock */
|
|
|
|
typedef struct _BSDRawPartition BSDRawPartition;
|
|
typedef struct _BSDRawLabel BSDRawLabel;
|
|
typedef struct _BSDDiskData BSDDiskData;
|
|
|
|
struct _BSDRawPartition { /* the partition table */
|
|
uint32_t p_size; /* number of sectors in partition */
|
|
uint32_t p_offset; /* starting sector */
|
|
uint32_t p_fsize; /* file system basic fragment size */
|
|
uint8_t p_fstype; /* file system type, see below */
|
|
uint8_t p_frag; /* file system fragments per block */
|
|
uint16_t p_cpg; /* file system cylinders per group */
|
|
} __attribute__((packed));
|
|
|
|
struct _BSDRawLabel {
|
|
uint32_t d_magic; /* the magic number */
|
|
int16_t d_type; /* drive type */
|
|
int16_t d_subtype; /* controller/d_type specific */
|
|
int8_t d_typename[16]; /* type name, e.g. "eagle" */
|
|
int8_t d_packname[16]; /* pack identifier */
|
|
uint32_t d_secsize; /* # of bytes per sector */
|
|
uint32_t d_nsectors; /* # of data sectors per track */
|
|
uint32_t d_ntracks; /* # of tracks per cylinder */
|
|
uint32_t d_ncylinders; /* # of data cylinders per unit */
|
|
uint32_t d_secpercyl; /* # of data sectors per cylinder */
|
|
uint32_t d_secperunit; /* # of data sectors per unit */
|
|
uint16_t d_sparespertrack; /* # of spare sectors per track */
|
|
uint16_t d_sparespercyl; /* # of spare sectors per cylinder */
|
|
uint32_t d_acylinders; /* # of alt. cylinders per unit */
|
|
uint16_t d_rpm; /* rotational speed */
|
|
uint16_t d_interleave; /* hardware sector interleave */
|
|
uint16_t d_trackskew; /* sector 0 skew, per track */
|
|
uint16_t d_cylskew; /* sector 0 skew, per cylinder */
|
|
uint32_t d_headswitch; /* head switch time, usec */
|
|
uint32_t d_trkseek; /* track-to-track seek, usec */
|
|
uint32_t d_flags; /* generic flags */
|
|
#define NDDATA 5
|
|
uint32_t d_drivedata[NDDATA]; /* drive-type specific information */
|
|
#define NSPARE 5
|
|
uint32_t d_spare[NSPARE]; /* reserved for future use */
|
|
uint32_t d_magic2; /* the magic number (again) */
|
|
uint16_t d_checksum; /* xor of data incl. partitions */
|
|
|
|
/* file system and partition information: */
|
|
uint16_t d_npartitions; /* number of partitions in following */
|
|
uint32_t d_bbsize; /* size of boot area at sn0, bytes */
|
|
uint32_t d_sbsize; /* max size of fs superblock, bytes */
|
|
#define D_PARTITIONS_WORDS 59
|
|
BSDRawPartition d_partitions[BSD_MAXPARTITIONS]; /* actually may be more */
|
|
} __attribute__((packed, aligned(2)));
|
|
|
|
struct _BSDDiskData {
|
|
char boot_code[64];
|
|
BSDRawLabel label; /* label is offset by 64 bytes */
|
|
char unused[172]; /* May contain more partitions */
|
|
} __attribute__((packed, aligned(2)));
|
|
|
|
typedef struct {
|
|
uint8_t type;
|
|
int boot;
|
|
int raid;
|
|
int lvm;
|
|
} BSDPartitionData;
|
|
|
|
static PedDiskType bsd_disk_type;
|
|
|
|
/* XXX fixme: endian? */
|
|
static unsigned short
|
|
xbsd_dkcksum (BSDRawLabel *lp) {
|
|
const u_short* word = (u_short*)(lp);
|
|
const u_short* end = word + D_PARTITIONS_WORDS + PED_LE16_TO_CPU(lp->d_npartitions);
|
|
u_short sum;
|
|
|
|
lp->d_checksum = 0;
|
|
for(sum=0; word < end; word++)
|
|
sum ^= PED_LE16_TO_CPU(*word);
|
|
return sum;
|
|
}
|
|
|
|
/* XXX fixme: endian? */
|
|
static void
|
|
alpha_bootblock_checksum (void *boot) {
|
|
uint64_t* dp = (uint64_t *)boot;
|
|
uint64_t sum=0;
|
|
int i;
|
|
|
|
for (i = 0; i < 63; i++)
|
|
sum += dp[i];
|
|
dp[63] = sum;
|
|
}
|
|
|
|
static int
|
|
bsd_probe (const PedDevice *dev)
|
|
{
|
|
BSDRawLabel *label;
|
|
|
|
PED_ASSERT (dev != NULL);
|
|
|
|
if (dev->sector_size < 512)
|
|
return 0;
|
|
|
|
void *s0;
|
|
if (!ptt_read_sector (dev, 0, &s0))
|
|
return 0;
|
|
|
|
label = &((BSDDiskData*) s0)->label;
|
|
|
|
/* check magic */
|
|
bool found = PED_LE32_TO_CPU (label->d_magic) == BSD_DISKMAGIC;
|
|
free (s0);
|
|
return found;
|
|
}
|
|
|
|
static PedDisk*
|
|
bsd_alloc (const PedDevice* dev)
|
|
{
|
|
PedDisk* disk;
|
|
BSDDiskData* bsd_specific;
|
|
BSDRawLabel *label;
|
|
|
|
PED_ASSERT(dev->sector_size % PED_SECTOR_SIZE_DEFAULT == 0);
|
|
|
|
disk = _ped_disk_alloc ((PedDevice*)dev, &bsd_disk_type);
|
|
if (!disk)
|
|
goto error;
|
|
disk->disk_specific = bsd_specific = ped_calloc (sizeof (BSDDiskData));
|
|
if (!bsd_specific)
|
|
goto error_free_disk;
|
|
|
|
/* Initialize the disk label's default values */
|
|
label = &bsd_specific->label;
|
|
label->d_magic = PED_CPU_TO_LE32 (BSD_DISKMAGIC);
|
|
label->d_type = PED_CPU_TO_LE16 (BSD_DTYPE_SCSI);
|
|
label->d_flags = 0;
|
|
label->d_secsize = PED_CPU_TO_LE16 (dev->sector_size);
|
|
label->d_nsectors = PED_CPU_TO_LE32 (dev->bios_geom.sectors);
|
|
label->d_ntracks = PED_CPU_TO_LE32 (dev->bios_geom.heads);
|
|
label->d_ncylinders = PED_CPU_TO_LE32 (dev->bios_geom.cylinders);
|
|
label->d_secpercyl = PED_CPU_TO_LE32 (dev->bios_geom.sectors
|
|
* dev->bios_geom.heads);
|
|
label->d_secperunit
|
|
= PED_CPU_TO_LE32 (dev->bios_geom.sectors
|
|
* dev->bios_geom.heads
|
|
* dev->bios_geom.cylinders);
|
|
|
|
label->d_rpm = PED_CPU_TO_LE16 (3600);
|
|
label->d_interleave = PED_CPU_TO_LE16 (1);
|
|
label->d_trackskew = 0;
|
|
label->d_cylskew = 0;
|
|
label->d_headswitch = 0;
|
|
label->d_trkseek = 0;
|
|
|
|
label->d_magic2 = PED_CPU_TO_LE32 (BSD_DISKMAGIC);
|
|
label->d_bbsize = PED_CPU_TO_LE32 (BSD_BBSIZE);
|
|
label->d_sbsize = PED_CPU_TO_LE32 (BSD_SBSIZE);
|
|
|
|
label->d_npartitions = 0;
|
|
label->d_checksum = xbsd_dkcksum (label);
|
|
|
|
return disk;
|
|
|
|
error_free_disk:
|
|
free (disk);
|
|
error:
|
|
return NULL;
|
|
}
|
|
|
|
static PedDisk*
|
|
bsd_duplicate (const PedDisk* disk)
|
|
{
|
|
PedDisk* new_disk;
|
|
BSDDiskData* new_bsd_data;
|
|
BSDDiskData* old_bsd_data = (BSDDiskData*) disk->disk_specific;
|
|
|
|
new_disk = ped_disk_new_fresh (disk->dev, &bsd_disk_type);
|
|
if (!new_disk)
|
|
return NULL;
|
|
|
|
new_bsd_data = (BSDDiskData*) new_disk->disk_specific;
|
|
memcpy (new_bsd_data, old_bsd_data, sizeof(BSDDiskData));
|
|
return new_disk;
|
|
}
|
|
|
|
static void
|
|
bsd_free (PedDisk* disk)
|
|
{
|
|
free (disk->disk_specific);
|
|
_ped_disk_free (disk);
|
|
}
|
|
|
|
static int
|
|
bsd_read (PedDisk* disk)
|
|
{
|
|
BSDDiskData* bsd_specific = (BSDDiskData*) disk->disk_specific;
|
|
BSDRawLabel* label;
|
|
int i;
|
|
|
|
ped_disk_delete_all (disk);
|
|
|
|
void *s0;
|
|
if (!ptt_read_sector (disk->dev, 0, &s0))
|
|
return 0;
|
|
|
|
memcpy (bsd_specific, s0, sizeof (BSDDiskData));
|
|
free (s0);
|
|
|
|
label = &bsd_specific->label;
|
|
|
|
for (i = 1; i <= BSD_MAXPARTITIONS; i++) {
|
|
PedPartition* part;
|
|
BSDPartitionData* bsd_part_data;
|
|
PedSector start;
|
|
PedSector end;
|
|
|
|
if (!label->d_partitions[i - 1].p_size
|
|
|| !label->d_partitions[i - 1].p_fstype)
|
|
continue;
|
|
start = PED_LE32_TO_CPU(label->d_partitions[i - 1].p_offset);
|
|
end = PED_LE32_TO_CPU(label->d_partitions[i - 1].p_offset)
|
|
+ PED_LE32_TO_CPU(label->d_partitions[i - 1].p_size) - 1;
|
|
part = ped_partition_new (disk, PED_PARTITION_NORMAL,
|
|
NULL, start, end);
|
|
if (!part)
|
|
goto error;
|
|
bsd_part_data = part->disk_specific;
|
|
bsd_part_data->type = label->d_partitions[i - 1].p_fstype;
|
|
part->num = i;
|
|
part->fs_type = ped_file_system_probe (&part->geom);
|
|
|
|
PedConstraint *constraint_exact
|
|
= ped_constraint_exact (&part->geom);
|
|
if (constraint_exact == NULL)
|
|
goto error;
|
|
bool ok = ped_disk_add_partition (disk, part, constraint_exact);
|
|
ped_constraint_destroy (constraint_exact);
|
|
if (!ok)
|
|
goto error;
|
|
}
|
|
|
|
return 1;
|
|
|
|
error:
|
|
return 0;
|
|
}
|
|
|
|
static void
|
|
_probe_and_add_boot_code (const PedDisk* disk)
|
|
{
|
|
BSDDiskData *old_data;
|
|
|
|
void *s0;
|
|
if (!ptt_read_sector (disk->dev, 0, &s0))
|
|
return;
|
|
old_data = (BSDDiskData*) s0;
|
|
if (old_data->boot_code [0]
|
|
&& old_data->label.d_magic == PED_CPU_TO_LE32 (BSD_DISKMAGIC)) {
|
|
BSDDiskData *bsd_specific = (BSDDiskData*) disk->disk_specific;
|
|
memcpy (bsd_specific, old_data, sizeof (BSDDiskData));
|
|
}
|
|
free (s0);
|
|
}
|
|
|
|
#ifndef DISCOVER_ONLY
|
|
static int
|
|
bsd_write (const PedDisk* disk)
|
|
{
|
|
BSDDiskData* bsd_specific;
|
|
BSDRawLabel* label;
|
|
BSDPartitionData* bsd_data;
|
|
PedPartition* part;
|
|
int i;
|
|
int max_part = 0;
|
|
|
|
PED_ASSERT (disk != NULL);
|
|
PED_ASSERT (disk->dev != NULL);
|
|
|
|
bsd_specific = (BSDDiskData*) disk->disk_specific;
|
|
label = &bsd_specific->label;
|
|
|
|
if (!bsd_specific->boot_code[0])
|
|
_probe_and_add_boot_code (disk);
|
|
|
|
memset (label->d_partitions, 0,
|
|
sizeof (BSDRawPartition) * BSD_MAXPARTITIONS);
|
|
|
|
for (i = 1; i <= BSD_MAXPARTITIONS; i++) {
|
|
part = ped_disk_get_partition (disk, i);
|
|
if (!part)
|
|
continue;
|
|
bsd_data = part->disk_specific;
|
|
label->d_partitions[i - 1].p_fstype = bsd_data->type;
|
|
label->d_partitions[i - 1].p_offset
|
|
= PED_CPU_TO_LE32 (part->geom.start);
|
|
label->d_partitions[i - 1].p_size
|
|
= PED_CPU_TO_LE32 (part->geom.length);
|
|
max_part = i;
|
|
}
|
|
|
|
label->d_npartitions = PED_CPU_TO_LE16 (max_part + 1);
|
|
label->d_checksum = xbsd_dkcksum (label);
|
|
|
|
alpha_bootblock_checksum (bsd_specific);
|
|
|
|
if (!ptt_write_sector (disk, bsd_specific,
|
|
sizeof (BSDDiskData)))
|
|
goto error;
|
|
return ped_device_sync (disk->dev);
|
|
|
|
error:
|
|
return 0;
|
|
}
|
|
#endif /* !DISCOVER_ONLY */
|
|
|
|
static PedPartition*
|
|
bsd_partition_new (const PedDisk* disk, PedPartitionType part_type,
|
|
const PedFileSystemType* fs_type,
|
|
PedSector start, PedSector end)
|
|
{
|
|
PedPartition* part;
|
|
BSDPartitionData* bsd_data;
|
|
|
|
part = _ped_partition_alloc (disk, part_type, fs_type, start, end);
|
|
if (!part)
|
|
goto error;
|
|
|
|
if (ped_partition_is_active (part)) {
|
|
part->disk_specific
|
|
= bsd_data = ped_malloc (sizeof (BSDPartitionData));
|
|
if (!bsd_data)
|
|
goto error_free_part;
|
|
bsd_data->type = 0;
|
|
bsd_data->boot = 0;
|
|
bsd_data->raid = 0;
|
|
bsd_data->lvm = 0;
|
|
} else {
|
|
part->disk_specific = NULL;
|
|
}
|
|
return part;
|
|
|
|
error_free_part:
|
|
free (part);
|
|
error:
|
|
return 0;
|
|
}
|
|
|
|
static PedPartition*
|
|
bsd_partition_duplicate (const PedPartition* part)
|
|
{
|
|
PedPartition* new_part;
|
|
BSDPartitionData* new_bsd_data;
|
|
BSDPartitionData* old_bsd_data;
|
|
|
|
new_part = ped_partition_new (part->disk, part->type,
|
|
part->fs_type, part->geom.start,
|
|
part->geom.end);
|
|
if (!new_part)
|
|
return NULL;
|
|
new_part->num = part->num;
|
|
|
|
old_bsd_data = (BSDPartitionData*) part->disk_specific;
|
|
new_bsd_data = (BSDPartitionData*) new_part->disk_specific;
|
|
new_bsd_data->type = old_bsd_data->type;
|
|
new_bsd_data->boot = old_bsd_data->boot;
|
|
new_bsd_data->raid = old_bsd_data->raid;
|
|
new_bsd_data->lvm = old_bsd_data->lvm;
|
|
return new_part;
|
|
}
|
|
|
|
static void
|
|
bsd_partition_destroy (PedPartition* part)
|
|
{
|
|
PED_ASSERT (part != NULL);
|
|
|
|
if (ped_partition_is_active (part))
|
|
free (part->disk_specific);
|
|
_ped_partition_free (part);
|
|
}
|
|
|
|
static int
|
|
bsd_partition_set_system (PedPartition* part, const PedFileSystemType* fs_type)
|
|
{
|
|
BSDPartitionData* bsd_data = part->disk_specific;
|
|
|
|
part->fs_type = fs_type;
|
|
|
|
if (!fs_type)
|
|
bsd_data->type = 0x8;
|
|
else if (is_linux_swap (fs_type->name))
|
|
bsd_data->type = 0x1;
|
|
else
|
|
bsd_data->type = 0x8;
|
|
|
|
return 1;
|
|
}
|
|
|
|
static int
|
|
bsd_partition_set_flag (PedPartition* part, PedPartitionFlag flag, int state)
|
|
{
|
|
BSDPartitionData* bsd_data;
|
|
|
|
PED_ASSERT (part != NULL);
|
|
PED_ASSERT (part->disk_specific != NULL);
|
|
PED_ASSERT (part->disk != NULL);
|
|
|
|
bsd_data = part->disk_specific;
|
|
|
|
switch (flag) {
|
|
case PED_PARTITION_BOOT:
|
|
bsd_data->boot = state;
|
|
return 1;
|
|
case PED_PARTITION_RAID:
|
|
if (state) {
|
|
bsd_data->lvm = 0;
|
|
}
|
|
bsd_data->raid = state;
|
|
return 1;
|
|
case PED_PARTITION_LVM:
|
|
if (state) {
|
|
bsd_data->raid = 0;
|
|
}
|
|
bsd_data->lvm = state;
|
|
return 1;
|
|
default:
|
|
;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
static int _GL_ATTRIBUTE_PURE
|
|
bsd_partition_get_flag (const PedPartition* part, PedPartitionFlag flag)
|
|
{
|
|
BSDPartitionData* bsd_data;
|
|
|
|
PED_ASSERT (part != NULL);
|
|
PED_ASSERT (part->disk_specific != NULL);
|
|
|
|
bsd_data = part->disk_specific;
|
|
switch (flag) {
|
|
case PED_PARTITION_BOOT:
|
|
return bsd_data->boot;
|
|
|
|
case PED_PARTITION_RAID:
|
|
return bsd_data->raid;
|
|
|
|
case PED_PARTITION_LVM:
|
|
return bsd_data->lvm;
|
|
|
|
default:
|
|
;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
static int
|
|
bsd_partition_is_flag_available (const PedPartition* part,
|
|
PedPartitionFlag flag)
|
|
{
|
|
switch (flag) {
|
|
case PED_PARTITION_BOOT:
|
|
case PED_PARTITION_RAID:
|
|
case PED_PARTITION_LVM:
|
|
return 1;
|
|
default:
|
|
;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
|
|
static int
|
|
bsd_get_max_primary_partition_count (const PedDisk* disk)
|
|
{
|
|
return BSD_MAXPARTITIONS;
|
|
}
|
|
|
|
static bool
|
|
bsd_get_max_supported_partition_count(const PedDisk* disk, int *max_n)
|
|
{
|
|
*max_n = BSD_MAXPARTITIONS;
|
|
return true;
|
|
}
|
|
|
|
static PedConstraint*
|
|
_get_constraint (const PedDevice* dev)
|
|
{
|
|
PedGeometry max;
|
|
|
|
ped_geometry_init (&max, dev, 1, dev->length - 1);
|
|
return ped_constraint_new_from_max (&max);
|
|
}
|
|
|
|
static int
|
|
bsd_partition_align (PedPartition* part, const PedConstraint* constraint)
|
|
{
|
|
if (_ped_partition_attempt_align (part, constraint,
|
|
_get_constraint (part->disk->dev)))
|
|
return 1;
|
|
|
|
#ifndef DISCOVER_ONLY
|
|
ped_exception_throw (
|
|
PED_EXCEPTION_ERROR,
|
|
PED_EXCEPTION_CANCEL,
|
|
_("Unable to satisfy all constraints on the partition."));
|
|
#endif
|
|
return 0;
|
|
}
|
|
|
|
static int
|
|
bsd_partition_enumerate (PedPartition* part)
|
|
{
|
|
int i;
|
|
PedPartition* p;
|
|
|
|
/* never change the partition numbers */
|
|
if (part->num != -1)
|
|
return 1;
|
|
for (i = 1; i <= BSD_MAXPARTITIONS; i++) {
|
|
p = ped_disk_get_partition (part->disk, i);
|
|
if (!p) {
|
|
part->num = i;
|
|
return 1;
|
|
}
|
|
}
|
|
|
|
/* failed to allocate a number */
|
|
#ifndef DISCOVER_ONLY
|
|
ped_exception_throw (PED_EXCEPTION_ERROR, PED_EXCEPTION_CANCEL,
|
|
_("Unable to allocate a bsd disklabel slot."));
|
|
#endif
|
|
return 0;
|
|
}
|
|
|
|
static int
|
|
bsd_alloc_metadata (PedDisk* disk)
|
|
{
|
|
PedPartition* new_part;
|
|
PedConstraint* constraint_any = NULL;
|
|
|
|
PED_ASSERT (disk != NULL);
|
|
PED_ASSERT (disk->dev != NULL);
|
|
|
|
constraint_any = ped_constraint_any (disk->dev);
|
|
|
|
/* allocate 1 sector for the disk label at the start */
|
|
new_part = ped_partition_new (disk, PED_PARTITION_METADATA, NULL, 0, 0);
|
|
if (!new_part)
|
|
goto error;
|
|
|
|
if (!ped_disk_add_partition (disk, new_part, constraint_any)) {
|
|
ped_partition_destroy (new_part);
|
|
goto error;
|
|
}
|
|
|
|
ped_constraint_destroy (constraint_any);
|
|
return 1;
|
|
error:
|
|
ped_constraint_destroy (constraint_any);
|
|
return 0;
|
|
}
|
|
|
|
#include "pt-common.h"
|
|
PT_define_limit_functions (bsd)
|
|
|
|
static PedDiskOps bsd_disk_ops = {
|
|
clobber: NULL,
|
|
write: NULL_IF_DISCOVER_ONLY (bsd_write),
|
|
|
|
partition_set_name: NULL,
|
|
partition_get_name: NULL,
|
|
|
|
PT_op_function_initializers (bsd)
|
|
};
|
|
|
|
static PedDiskType bsd_disk_type = {
|
|
next: NULL,
|
|
name: "bsd",
|
|
ops: &bsd_disk_ops,
|
|
features: 0
|
|
};
|
|
|
|
void
|
|
ped_disk_bsd_init ()
|
|
{
|
|
PED_ASSERT (sizeof (BSDRawPartition) == 16);
|
|
PED_ASSERT (sizeof (BSDRawLabel) == 276);
|
|
|
|
ped_disk_type_register (&bsd_disk_type);
|
|
}
|
|
|
|
void
|
|
ped_disk_bsd_done ()
|
|
{
|
|
ped_disk_type_unregister (&bsd_disk_type);
|
|
}
|