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