pmt: initial 3.0.2 update
This commit is contained in:
237
jni/parted/libparted/labels/aix.c
Executable file
237
jni/parted/libparted/labels/aix.c
Executable file
@@ -0,0 +1,237 @@
|
||||
/* -*- 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 <parted/parted.h>
|
||||
#include <parted/debug.h>
|
||||
#include <parted/endian.h>
|
||||
#include <stdbool.h>
|
||||
#include "pt-tools.h"
|
||||
|
||||
#if ENABLE_NLS
|
||||
# include <libintl.h>
|
||||
# define _(String) dgettext (PACKAGE, String)
|
||||
#else
|
||||
# define _(String) (String)
|
||||
#endif /* ENABLE_NLS */
|
||||
|
||||
#define AIX_LABEL_MAGIC (0xc9c2d4c1UL)
|
||||
#define MAX_TOTAL_PART 16
|
||||
|
||||
static PedDiskType aix_disk_type;
|
||||
|
||||
static int
|
||||
aix_probe (const PedDevice *dev)
|
||||
{
|
||||
PED_ASSERT (dev != NULL);
|
||||
|
||||
void *label;
|
||||
if (!ptt_read_sector (dev, 0, &label))
|
||||
return 0;
|
||||
bool found = PED_BE32_TO_CPU(*(uint32_t *)label) == AIX_LABEL_MAGIC;
|
||||
free (label);
|
||||
return found;
|
||||
}
|
||||
|
||||
static PedDisk*
|
||||
aix_alloc (const PedDevice* dev)
|
||||
{
|
||||
PedDisk* disk;
|
||||
|
||||
disk = _ped_disk_alloc (dev, &aix_disk_type);
|
||||
if (!disk)
|
||||
return NULL;
|
||||
|
||||
return disk;
|
||||
}
|
||||
|
||||
static PedDisk*
|
||||
aix_duplicate (const PedDisk* disk)
|
||||
{
|
||||
PedDisk* new_disk;
|
||||
|
||||
new_disk = ped_disk_new_fresh (disk->dev, &aix_disk_type);
|
||||
if (!new_disk)
|
||||
return NULL;
|
||||
|
||||
return new_disk;
|
||||
}
|
||||
|
||||
static void
|
||||
aix_free (PedDisk *disk)
|
||||
{
|
||||
_ped_disk_free (disk);
|
||||
}
|
||||
|
||||
static int
|
||||
aix_read (PedDisk* disk)
|
||||
{
|
||||
ped_disk_delete_all (disk);
|
||||
ped_exception_throw (PED_EXCEPTION_NO_FEATURE,
|
||||
PED_EXCEPTION_CANCEL,
|
||||
_("Support for reading AIX disk labels is "
|
||||
"is not implemented yet."));
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifndef DISCOVER_ONLY
|
||||
static int
|
||||
aix_write (const PedDisk* disk)
|
||||
{
|
||||
ped_exception_throw (PED_EXCEPTION_NO_FEATURE,
|
||||
PED_EXCEPTION_CANCEL,
|
||||
_("Support for writing AIX disk labels is "
|
||||
"is not implemented yet."));
|
||||
return 0;
|
||||
}
|
||||
#endif /* !DISCOVER_ONLY */
|
||||
|
||||
static PedPartition*
|
||||
aix_partition_new (const PedDisk* disk, PedPartitionType part_type,
|
||||
const PedFileSystemType* fs_type,
|
||||
PedSector start, PedSector end)
|
||||
{
|
||||
ped_exception_throw (PED_EXCEPTION_NO_FEATURE,
|
||||
PED_EXCEPTION_CANCEL,
|
||||
_("Support for adding partitions to AIX disk "
|
||||
"labels is not implemented yet."));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static PedPartition*
|
||||
aix_partition_duplicate (const PedPartition* part)
|
||||
{
|
||||
ped_exception_throw (PED_EXCEPTION_NO_FEATURE,
|
||||
PED_EXCEPTION_CANCEL,
|
||||
_("Support for duplicating partitions in AIX "
|
||||
"disk labels is not implemented yet."));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
aix_partition_destroy (PedPartition* part)
|
||||
{
|
||||
PED_ASSERT (part != NULL);
|
||||
|
||||
_ped_partition_free (part);
|
||||
}
|
||||
|
||||
static int
|
||||
aix_partition_set_system (PedPartition* part, const PedFileSystemType* fs_type)
|
||||
{
|
||||
ped_exception_throw (PED_EXCEPTION_NO_FEATURE,
|
||||
PED_EXCEPTION_CANCEL,
|
||||
_("Support for setting system type of partitions "
|
||||
"in AIX disk labels is not implemented yet."));
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
aix_partition_set_flag (PedPartition* part, PedPartitionFlag flag, int state)
|
||||
{
|
||||
ped_exception_throw (PED_EXCEPTION_NO_FEATURE,
|
||||
PED_EXCEPTION_CANCEL,
|
||||
_("Support for setting flags "
|
||||
"in AIX disk labels is not implemented yet."));
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int _GL_ATTRIBUTE_CONST
|
||||
aix_partition_get_flag (const PedPartition* part, PedPartitionFlag flag)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
aix_partition_is_flag_available (const PedPartition* part,
|
||||
PedPartitionFlag flag)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
aix_get_max_primary_partition_count (const PedDisk* disk)
|
||||
{
|
||||
return 4;
|
||||
}
|
||||
|
||||
static bool
|
||||
aix_get_max_supported_partition_count (const PedDisk* disk, int *max_n)
|
||||
{
|
||||
*max_n = MAX_TOTAL_PART;
|
||||
return true;
|
||||
}
|
||||
|
||||
static int _GL_ATTRIBUTE_PURE
|
||||
aix_partition_align (PedPartition* part, const PedConstraint* constraint)
|
||||
{
|
||||
PED_ASSERT (part != NULL);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int _GL_ATTRIBUTE_PURE
|
||||
aix_partition_enumerate (PedPartition* part)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int _GL_ATTRIBUTE_PURE
|
||||
aix_alloc_metadata (PedDisk* disk)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
#include "pt-common.h"
|
||||
PT_define_limit_functions (aix)
|
||||
|
||||
static PedDiskOps aix_disk_ops = {
|
||||
clobber: NULL,
|
||||
write: NULL_IF_DISCOVER_ONLY (aix_write),
|
||||
|
||||
partition_set_name: NULL,
|
||||
partition_get_name: NULL,
|
||||
|
||||
PT_op_function_initializers (aix)
|
||||
};
|
||||
|
||||
static PedDiskType aix_disk_type = {
|
||||
next: NULL,
|
||||
name: "aix",
|
||||
ops: &aix_disk_ops,
|
||||
features: 0
|
||||
};
|
||||
|
||||
void
|
||||
ped_disk_aix_init ()
|
||||
{
|
||||
ped_disk_type_register (&aix_disk_type);
|
||||
}
|
||||
|
||||
void
|
||||
ped_disk_aix_done ()
|
||||
{
|
||||
ped_disk_type_unregister (&aix_disk_type);
|
||||
}
|
||||
1975
jni/parted/libparted/labels/atari.c
Executable file
1975
jni/parted/libparted/labels/atari.c
Executable file
File diff suppressed because it is too large
Load Diff
654
jni/parted/libparted/labels/bsd.c
Executable file
654
jni/parted/libparted/labels/bsd.c
Executable file
@@ -0,0 +1,654 @@
|
||||
/* -*- 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);
|
||||
}
|
||||
1032
jni/parted/libparted/labels/dasd.c
Executable file
1032
jni/parted/libparted/labels/dasd.c
Executable file
File diff suppressed because it is too large
Load Diff
2612
jni/parted/libparted/labels/dos.c
Executable file
2612
jni/parted/libparted/labels/dos.c
Executable file
File diff suppressed because it is too large
Load Diff
896
jni/parted/libparted/labels/dvh.c
Executable file
896
jni/parted/libparted/labels/dvh.c
Executable file
@@ -0,0 +1,896 @@
|
||||
/*
|
||||
libparted - a library for manipulating disk partitions
|
||||
Copyright (C) 2001-2002, 2005, 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/>.
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
#include <parted/parted.h>
|
||||
#include <parted/debug.h>
|
||||
#include <parted/endian.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#include "dvh.h"
|
||||
#include "pt-tools.h"
|
||||
|
||||
#if ENABLE_NLS
|
||||
# include <libintl.h>
|
||||
# define _(String) dgettext (PACKAGE, String)
|
||||
#else
|
||||
# define _(String) (String)
|
||||
#endif /* ENABLE_NLS */
|
||||
|
||||
/* Default size for volhdr part, same val as IRIX's fx uses */
|
||||
#define PTYPE_VOLHDR_DFLTSZ 4096
|
||||
|
||||
/* Partition numbers that seem to be strongly held convention */
|
||||
#define PNUM_VOLHDR 8
|
||||
#define PNUM_VOLUME 10
|
||||
|
||||
/* Other notes of interest:
|
||||
* PED_PARTITION_EXTENDED is used for volume headers
|
||||
* PED_PARTITION_LOGICAL is used for bootfiles
|
||||
* PED_PARTITION_NORMAL is used for all else
|
||||
*/
|
||||
|
||||
typedef struct _DVHDiskData {
|
||||
struct device_parameters dev_params;
|
||||
int swap; /* part num of swap, 0=none */
|
||||
int root; /* part num of root, 0=none */
|
||||
int boot; /* part num of boot, 0=none */
|
||||
} DVHDiskData;
|
||||
|
||||
typedef struct _DVHPartData {
|
||||
int type;
|
||||
char name[VDNAMESIZE + 1]; /* boot volumes only */
|
||||
int real_file_size; /* boot volumes only */
|
||||
} DVHPartData;
|
||||
|
||||
static PedDiskType dvh_disk_type;
|
||||
|
||||
static int
|
||||
dvh_probe (const PedDevice *dev)
|
||||
{
|
||||
struct volume_header *vh;
|
||||
|
||||
void *label;
|
||||
if (!ptt_read_sector (dev, 0, &label))
|
||||
return 0;
|
||||
|
||||
vh = (struct volume_header *) label;
|
||||
|
||||
bool found = PED_BE32_TO_CPU (vh->vh_magic) == VHMAGIC;
|
||||
free (label);
|
||||
return found;
|
||||
}
|
||||
|
||||
static PedDisk*
|
||||
dvh_alloc (const PedDevice* dev)
|
||||
{
|
||||
PedDisk* disk;
|
||||
DVHDiskData* dvh_disk_data;
|
||||
PedPartition* volume_part;
|
||||
PedConstraint* constraint_any;
|
||||
|
||||
disk = _ped_disk_alloc (dev, &dvh_disk_type);
|
||||
if (!disk)
|
||||
goto error;
|
||||
|
||||
disk->disk_specific = dvh_disk_data
|
||||
= ped_malloc (sizeof (DVHDiskData));
|
||||
if (!dvh_disk_data)
|
||||
goto error_free_disk;
|
||||
|
||||
memset (&dvh_disk_data->dev_params, 0,
|
||||
sizeof (struct device_parameters));
|
||||
dvh_disk_data->swap = 0;
|
||||
dvh_disk_data->root = 0;
|
||||
dvh_disk_data->boot = 0;
|
||||
|
||||
volume_part = ped_partition_new (disk, PED_PARTITION_EXTENDED, NULL,
|
||||
0, PTYPE_VOLHDR_DFLTSZ - 1);
|
||||
if (!volume_part)
|
||||
goto error_free_disk_specific;
|
||||
volume_part->num = PNUM_VOLHDR + 1;
|
||||
constraint_any = ped_constraint_any (dev);
|
||||
if (!ped_disk_add_partition (disk, volume_part, constraint_any))
|
||||
goto error_destroy_constraint_any;
|
||||
ped_constraint_destroy (constraint_any);
|
||||
return disk;
|
||||
|
||||
error_destroy_constraint_any:
|
||||
ped_constraint_destroy (constraint_any);
|
||||
ped_partition_destroy (volume_part);
|
||||
error_free_disk_specific:
|
||||
free (disk->disk_specific);
|
||||
error_free_disk:
|
||||
free (disk);
|
||||
error:
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static PedDisk*
|
||||
dvh_duplicate (const PedDisk* disk)
|
||||
{
|
||||
PedDisk* new_disk;
|
||||
DVHDiskData* new_dvh_disk_data;
|
||||
DVHDiskData* old_dvh_disk_data = disk->disk_specific;
|
||||
|
||||
PED_ASSERT (old_dvh_disk_data != NULL);
|
||||
|
||||
new_disk = ped_disk_new_fresh (disk->dev, &dvh_disk_type);
|
||||
if (!new_disk)
|
||||
goto error;
|
||||
|
||||
new_disk->disk_specific = new_dvh_disk_data
|
||||
= ped_malloc (sizeof (DVHDiskData));
|
||||
if (!new_dvh_disk_data)
|
||||
goto error_free_new_disk;
|
||||
|
||||
new_dvh_disk_data->dev_params = old_dvh_disk_data->dev_params;
|
||||
return new_disk;
|
||||
|
||||
error_free_new_disk:
|
||||
free (new_disk);
|
||||
error:
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
dvh_free (PedDisk* disk)
|
||||
{
|
||||
free (disk->disk_specific);
|
||||
_ped_disk_free (disk);
|
||||
}
|
||||
|
||||
/* two's complement 32-bit checksum */
|
||||
static uint32_t _GL_ATTRIBUTE_PURE
|
||||
_checksum (const uint32_t* base, size_t size)
|
||||
{
|
||||
uint32_t sum = 0;
|
||||
size_t i;
|
||||
|
||||
for (i = 0; i < size / sizeof (uint32_t); i++)
|
||||
sum = sum - PED_BE32_TO_CPU (base[i]);
|
||||
|
||||
return sum;
|
||||
}
|
||||
|
||||
/* try to make a reasonable volume header partition... */
|
||||
static PedExceptionOption
|
||||
_handle_no_volume_header (PedDisk* disk)
|
||||
{
|
||||
PedExceptionOption ret;
|
||||
PedPartition* part;
|
||||
PedConstraint* constraint;
|
||||
|
||||
switch (ped_exception_throw (
|
||||
PED_EXCEPTION_WARNING,
|
||||
PED_EXCEPTION_FIX + PED_EXCEPTION_CANCEL,
|
||||
_("%s has no extended partition (volume header partition)."),
|
||||
disk->dev->path)) {
|
||||
case PED_EXCEPTION_UNHANDLED:
|
||||
case PED_EXCEPTION_FIX:
|
||||
default:
|
||||
part = ped_partition_new (
|
||||
disk, PED_PARTITION_EXTENDED, NULL,
|
||||
0, PTYPE_VOLHDR_DFLTSZ - 1);
|
||||
if (!part)
|
||||
goto error;
|
||||
part->num = PNUM_VOLHDR + 1;
|
||||
constraint = ped_constraint_any (part->disk->dev);
|
||||
if (!constraint)
|
||||
goto error_destroy_part;
|
||||
if (!ped_disk_add_partition (disk, part, constraint))
|
||||
goto error_destroy_constraint;
|
||||
ped_constraint_destroy (constraint);
|
||||
ret = PED_EXCEPTION_FIX;
|
||||
break;
|
||||
|
||||
case PED_EXCEPTION_CANCEL:
|
||||
goto error;
|
||||
}
|
||||
return ret;
|
||||
|
||||
error_destroy_constraint:
|
||||
ped_constraint_destroy (constraint);
|
||||
error_destroy_part:
|
||||
ped_partition_destroy (part);
|
||||
error:
|
||||
return PED_EXCEPTION_CANCEL;
|
||||
}
|
||||
|
||||
static PedPartition*
|
||||
_parse_partition (PedDisk* disk, struct partition_table* pt)
|
||||
{
|
||||
PedPartition* part;
|
||||
DVHPartData* dvh_part_data;
|
||||
PedSector start = PED_BE32_TO_CPU (pt->pt_firstlbn);
|
||||
PedSector length = PED_BE32_TO_CPU (pt->pt_nblks);
|
||||
|
||||
part = ped_partition_new (disk,
|
||||
pt->pt_type ? 0 : PED_PARTITION_EXTENDED,
|
||||
NULL,
|
||||
start, start + length - 1);
|
||||
if (!part)
|
||||
return NULL;
|
||||
|
||||
dvh_part_data = part->disk_specific;
|
||||
dvh_part_data->type = PED_BE32_TO_CPU (pt->pt_type);
|
||||
strcpy (dvh_part_data->name, "");
|
||||
|
||||
return part;
|
||||
}
|
||||
|
||||
static PedPartition*
|
||||
_parse_boot_file (PedDisk* disk, struct volume_directory* vd)
|
||||
{
|
||||
PedPartition* part;
|
||||
DVHPartData* dvh_part_data;
|
||||
PedSector start = PED_BE32_TO_CPU (vd->vd_lbn);
|
||||
int length = PED_BE32_TO_CPU (vd->vd_nbytes);
|
||||
|
||||
part = ped_partition_new (disk, PED_PARTITION_LOGICAL, NULL,
|
||||
start, start + length/512 - 1);
|
||||
if (!part)
|
||||
return NULL;
|
||||
|
||||
dvh_part_data = part->disk_specific;
|
||||
dvh_part_data->real_file_size = length;
|
||||
|
||||
memcpy (dvh_part_data->name, vd->vd_name, VDNAMESIZE);
|
||||
dvh_part_data->name[VDNAMESIZE] = 0;
|
||||
return part;
|
||||
}
|
||||
|
||||
static int dvh_write (const PedDisk* disk);
|
||||
|
||||
/* YUCK
|
||||
*
|
||||
* If you remove a boot/root/swap partition, the disk->disk_specific
|
||||
* thing isn't updated. (Probably reflects a design bug somewhere...)
|
||||
* Anyway, the workaround is: flush stale flags whenever we allocate
|
||||
* new partition numbers, and before we write to disk.
|
||||
*/
|
||||
static void
|
||||
_flush_stale_flags (const PedDisk* disk)
|
||||
{
|
||||
DVHDiskData* dvh_disk_data = disk->disk_specific;
|
||||
|
||||
if (dvh_disk_data->root
|
||||
&& !ped_disk_get_partition (disk, dvh_disk_data->root))
|
||||
dvh_disk_data->root = 0;
|
||||
if (dvh_disk_data->swap
|
||||
&& !ped_disk_get_partition (disk, dvh_disk_data->swap))
|
||||
dvh_disk_data->swap = 0;
|
||||
if (dvh_disk_data->boot
|
||||
&& !ped_disk_get_partition (disk, dvh_disk_data->boot))
|
||||
dvh_disk_data->boot = 0;
|
||||
}
|
||||
|
||||
static int
|
||||
dvh_read (PedDisk* disk)
|
||||
{
|
||||
DVHDiskData* dvh_disk_data = disk->disk_specific;
|
||||
int i;
|
||||
struct volume_header vh;
|
||||
char boot_name [BFNAMESIZE + 1];
|
||||
#ifndef DISCOVER_ONLY
|
||||
int write_back = 0;
|
||||
#endif
|
||||
|
||||
PED_ASSERT (dvh_disk_data != NULL);
|
||||
|
||||
ped_disk_delete_all (disk);
|
||||
|
||||
void *s0;
|
||||
if (!ptt_read_sector (disk->dev, 0, &s0))
|
||||
return 0;
|
||||
memcpy (&vh, s0, sizeof vh);
|
||||
free (s0);
|
||||
|
||||
if (_checksum ((uint32_t*) &vh, sizeof (struct volume_header))) {
|
||||
if (ped_exception_throw (
|
||||
PED_EXCEPTION_ERROR,
|
||||
PED_EXCEPTION_IGNORE_CANCEL,
|
||||
_("Checksum is wrong, indicating the partition "
|
||||
"table is corrupt."))
|
||||
== PED_EXCEPTION_CANCEL)
|
||||
return 0;
|
||||
}
|
||||
|
||||
PED_ASSERT (PED_BE32_TO_CPU (vh.vh_magic) == VHMAGIC);
|
||||
|
||||
dvh_disk_data->dev_params = vh.vh_dp;
|
||||
boot_name[BFNAMESIZE] = 0;
|
||||
strncpy (boot_name, vh.vh_bootfile, BFNAMESIZE);
|
||||
|
||||
/* normal partitions */
|
||||
for (i = 0; i < NPARTAB; i++) {
|
||||
PedPartition* part;
|
||||
|
||||
if (!vh.vh_pt[i].pt_nblks)
|
||||
continue;
|
||||
/* Skip the whole-disk partition, parted disklikes overlap */
|
||||
if (PED_BE32_TO_CPU (vh.vh_pt[i].pt_type) == PTYPE_VOLUME)
|
||||
continue;
|
||||
|
||||
part = _parse_partition (disk, &vh.vh_pt[i]);
|
||||
if (!part)
|
||||
goto error_delete_all;
|
||||
|
||||
part->fs_type = ped_file_system_probe (&part->geom);
|
||||
part->num = i + 1;
|
||||
|
||||
if (PED_BE16_TO_CPU (vh.vh_rootpt) == i)
|
||||
ped_partition_set_flag (part, PED_PARTITION_ROOT, 1);
|
||||
if (PED_BE16_TO_CPU (vh.vh_swappt) == i)
|
||||
ped_partition_set_flag (part, PED_PARTITION_SWAP, 1);
|
||||
|
||||
PedConstraint *constraint_exact
|
||||
= ped_constraint_exact (&part->geom);
|
||||
bool ok = ped_disk_add_partition (disk, part, constraint_exact);
|
||||
ped_constraint_destroy (constraint_exact);
|
||||
if (!ok) {
|
||||
ped_partition_destroy (part);
|
||||
goto error_delete_all;
|
||||
}
|
||||
}
|
||||
|
||||
if (!ped_disk_extended_partition (disk)) {
|
||||
#ifdef DISCOVER_ONLY
|
||||
return 1;
|
||||
#else
|
||||
switch (_handle_no_volume_header (disk)) {
|
||||
case PED_EXCEPTION_CANCEL:
|
||||
return 0;
|
||||
case PED_EXCEPTION_IGNORE:
|
||||
return 1;
|
||||
case PED_EXCEPTION_FIX:
|
||||
write_back = 1;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/* boot partitions */
|
||||
for (i = 0; i < NVDIR; i++) {
|
||||
PedPartition* part;
|
||||
|
||||
if (!vh.vh_vd[i].vd_nbytes)
|
||||
continue;
|
||||
|
||||
part = _parse_boot_file (disk, &vh.vh_vd[i]);
|
||||
if (!part)
|
||||
goto error_delete_all;
|
||||
|
||||
part->fs_type = ped_file_system_probe (&part->geom);
|
||||
part->num = NPARTAB + i + 1;
|
||||
|
||||
if (!strcmp (boot_name, ped_partition_get_name (part)))
|
||||
ped_partition_set_flag (part, PED_PARTITION_BOOT, 1);
|
||||
|
||||
PedConstraint *constraint_exact
|
||||
= ped_constraint_exact (&part->geom);
|
||||
bool ok = ped_disk_add_partition (disk, part, constraint_exact);
|
||||
ped_constraint_destroy (constraint_exact);
|
||||
if (!ok) {
|
||||
ped_partition_destroy (part);
|
||||
goto error_delete_all;
|
||||
}
|
||||
}
|
||||
#ifndef DISCOVER_ONLY
|
||||
if (write_back)
|
||||
dvh_write (disk);
|
||||
#endif
|
||||
return 1;
|
||||
|
||||
error_delete_all:
|
||||
ped_disk_delete_all (disk);
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifndef DISCOVER_ONLY
|
||||
static void
|
||||
_generate_partition (PedPartition* part, struct partition_table* pt)
|
||||
{
|
||||
DVHPartData* dvh_part_data = part->disk_specific;
|
||||
|
||||
/* Assert not a bootfile */
|
||||
PED_ASSERT ((part->type & PED_PARTITION_LOGICAL) == 0);
|
||||
|
||||
pt->pt_nblks = PED_CPU_TO_BE32 (part->geom.length);
|
||||
pt->pt_firstlbn = PED_CPU_TO_BE32 (part->geom.start);
|
||||
pt->pt_type = PED_CPU_TO_BE32 (dvh_part_data->type);
|
||||
}
|
||||
|
||||
static void
|
||||
_generate_boot_file (PedPartition* part, struct volume_directory* vd)
|
||||
{
|
||||
DVHPartData* dvh_part_data = part->disk_specific;
|
||||
|
||||
/* Assert it's a bootfile */
|
||||
PED_ASSERT ((part->type & PED_PARTITION_LOGICAL) != 0);
|
||||
|
||||
vd->vd_nbytes = PED_CPU_TO_BE32 (dvh_part_data->real_file_size);
|
||||
vd->vd_lbn = PED_CPU_TO_BE32 (part->geom.start);
|
||||
|
||||
memset (vd->vd_name, 0, VDNAMESIZE);
|
||||
memcpy (vd->vd_name, dvh_part_data->name, VDNAMESIZE);
|
||||
}
|
||||
|
||||
static int
|
||||
dvh_write (const PedDisk* disk)
|
||||
{
|
||||
DVHDiskData* dvh_disk_data = disk->disk_specific;
|
||||
struct volume_header vh;
|
||||
int i;
|
||||
|
||||
PED_ASSERT (dvh_disk_data != NULL);
|
||||
|
||||
_flush_stale_flags (disk);
|
||||
|
||||
memset (&vh, 0, sizeof (struct volume_header));
|
||||
|
||||
vh.vh_magic = PED_CPU_TO_BE32 (VHMAGIC);
|
||||
vh.vh_rootpt = PED_CPU_TO_BE16 (dvh_disk_data->root - 1);
|
||||
vh.vh_swappt = PED_CPU_TO_BE16 (dvh_disk_data->swap - 1);
|
||||
|
||||
if (dvh_disk_data->boot) {
|
||||
PedPartition* boot_part;
|
||||
boot_part = ped_disk_get_partition (disk, dvh_disk_data->boot);
|
||||
strcpy (vh.vh_bootfile, ped_partition_get_name (boot_part));
|
||||
}
|
||||
|
||||
vh.vh_dp = dvh_disk_data->dev_params;
|
||||
/* Set up rudimentary device geometry */
|
||||
vh.vh_dp.dp_cyls
|
||||
= PED_CPU_TO_BE16 ((short)disk->dev->bios_geom.cylinders);
|
||||
vh.vh_dp.dp_trks0 = PED_CPU_TO_BE16 ((short)disk->dev->bios_geom.heads);
|
||||
vh.vh_dp.dp_secs
|
||||
= PED_CPU_TO_BE16 ((short)disk->dev->bios_geom.sectors);
|
||||
vh.vh_dp.dp_secbytes = PED_CPU_TO_BE16 ((short)disk->dev->sector_size);
|
||||
|
||||
for (i = 0; i < NPARTAB; i++) {
|
||||
PedPartition* part = ped_disk_get_partition (disk, i + 1);
|
||||
if (part)
|
||||
_generate_partition (part, &vh.vh_pt[i]);
|
||||
}
|
||||
|
||||
/* whole disk partition
|
||||
* This is only ever written here, and never modified
|
||||
* (or even shown) as it must contain the entire disk,
|
||||
* and parted does not like overlapping partitions
|
||||
*/
|
||||
vh.vh_pt[PNUM_VOLUME].pt_nblks = PED_CPU_TO_BE32 (disk->dev->length);
|
||||
vh.vh_pt[PNUM_VOLUME].pt_firstlbn = PED_CPU_TO_BE32 (0);
|
||||
vh.vh_pt[PNUM_VOLUME].pt_type = PED_CPU_TO_BE32 (PTYPE_VOLUME);
|
||||
|
||||
for (i = 0; i < NVDIR; i++) {
|
||||
PedPartition* part = ped_disk_get_partition (disk,
|
||||
i + 1 + NPARTAB);
|
||||
if (part)
|
||||
_generate_boot_file (part, &vh.vh_vd[i]);
|
||||
}
|
||||
|
||||
vh.vh_csum = 0;
|
||||
vh.vh_csum = PED_CPU_TO_BE32 (_checksum ((uint32_t*) &vh,
|
||||
sizeof (struct volume_header)));
|
||||
|
||||
return (ptt_write_sector (disk, &vh, sizeof vh)
|
||||
&& ped_device_sync (disk->dev));
|
||||
}
|
||||
#endif /* !DISCOVER_ONLY */
|
||||
|
||||
static PedPartition*
|
||||
dvh_partition_new (const PedDisk* disk, PedPartitionType part_type,
|
||||
const PedFileSystemType* fs_type,
|
||||
PedSector start, PedSector end)
|
||||
{
|
||||
PedPartition* part;
|
||||
DVHPartData* dvh_part_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 = NULL;
|
||||
return part;
|
||||
}
|
||||
|
||||
dvh_part_data = part->disk_specific =
|
||||
ped_malloc (sizeof (DVHPartData));
|
||||
if (!dvh_part_data)
|
||||
goto error_free_part;
|
||||
|
||||
dvh_part_data->type = (part_type == PED_PARTITION_EXTENDED)
|
||||
? PTYPE_VOLHDR
|
||||
: PTYPE_RAW;
|
||||
strcpy (dvh_part_data->name, "");
|
||||
dvh_part_data->real_file_size = part->geom.length * 512;
|
||||
return part;
|
||||
|
||||
error_free_part:
|
||||
_ped_partition_free (part);
|
||||
error:
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static PedPartition*
|
||||
dvh_partition_duplicate (const PedPartition* part)
|
||||
{
|
||||
PedPartition* result;
|
||||
DVHPartData* part_data = part->disk_specific;
|
||||
DVHPartData* result_data;
|
||||
|
||||
result = _ped_partition_alloc (part->disk, part->type, part->fs_type,
|
||||
part->geom.start, part->geom.end);
|
||||
if (!result)
|
||||
goto error;
|
||||
result->num = part->num;
|
||||
|
||||
if (!ped_partition_is_active (part)) {
|
||||
result->disk_specific = NULL;
|
||||
return result;
|
||||
}
|
||||
|
||||
result_data = result->disk_specific =
|
||||
ped_malloc (sizeof (DVHPartData));
|
||||
if (!result_data)
|
||||
goto error_free_part;
|
||||
|
||||
result_data->type = part_data->type;
|
||||
strcpy (result_data->name, part_data->name);
|
||||
result_data->real_file_size = part_data->real_file_size;
|
||||
return result;
|
||||
|
||||
error_free_part:
|
||||
_ped_partition_free (result);
|
||||
error:
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
dvh_partition_destroy (PedPartition* part)
|
||||
{
|
||||
if (ped_partition_is_active (part)) {
|
||||
PED_ASSERT (part->disk_specific != NULL);
|
||||
free (part->disk_specific);
|
||||
}
|
||||
_ped_partition_free (part);
|
||||
}
|
||||
|
||||
static int
|
||||
dvh_partition_set_system (PedPartition* part, const PedFileSystemType* fs_type)
|
||||
{
|
||||
DVHPartData* dvh_part_data = part->disk_specific;
|
||||
|
||||
part->fs_type = fs_type;
|
||||
|
||||
if (part->type == PED_PARTITION_EXTENDED) {
|
||||
dvh_part_data->type = PTYPE_VOLHDR;
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Is this a bootfile? */
|
||||
if (part->type == PED_PARTITION_LOGICAL)
|
||||
return 1;
|
||||
|
||||
if (fs_type && !strcmp (fs_type->name, "xfs"))
|
||||
dvh_part_data->type = PTYPE_XFS;
|
||||
else
|
||||
dvh_part_data->type = PTYPE_RAW;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int
|
||||
dvh_partition_set_flag (PedPartition* part, PedPartitionFlag flag, int state)
|
||||
{
|
||||
DVHDiskData* dvh_disk_data = part->disk->disk_specific;
|
||||
|
||||
switch (flag) {
|
||||
case PED_PARTITION_ROOT:
|
||||
if (part->type != 0 && state) {
|
||||
#ifndef DISCOVER_ONLY
|
||||
ped_exception_throw (
|
||||
PED_EXCEPTION_ERROR,
|
||||
PED_EXCEPTION_CANCEL,
|
||||
_("Only primary partitions can be root "
|
||||
"partitions."));
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
dvh_disk_data->root = state ? part->num : 0;
|
||||
break;
|
||||
|
||||
case PED_PARTITION_SWAP:
|
||||
if (part->type != 0 && state) {
|
||||
#ifndef DISCOVER_ONLY
|
||||
ped_exception_throw (
|
||||
PED_EXCEPTION_ERROR,
|
||||
PED_EXCEPTION_CANCEL,
|
||||
_("Only primary partitions can be swap "
|
||||
"partitions."));
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
dvh_disk_data->swap = state ? part->num : 0;
|
||||
break;
|
||||
|
||||
case PED_PARTITION_BOOT:
|
||||
if (part->type != PED_PARTITION_LOGICAL && state) {
|
||||
#ifndef DISCOVER_ONLY
|
||||
ped_exception_throw (
|
||||
PED_EXCEPTION_ERROR,
|
||||
PED_EXCEPTION_CANCEL,
|
||||
_("Only logical partitions can be a boot "
|
||||
"file."));
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
dvh_disk_data->boot = state ? part->num : 0;
|
||||
break;
|
||||
|
||||
case PED_PARTITION_LVM:
|
||||
case PED_PARTITION_LBA:
|
||||
case PED_PARTITION_HIDDEN:
|
||||
case PED_PARTITION_RAID:
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int _GL_ATTRIBUTE_PURE
|
||||
dvh_partition_get_flag (const PedPartition* part, PedPartitionFlag flag)
|
||||
{
|
||||
DVHDiskData* dvh_disk_data = part->disk->disk_specific;
|
||||
|
||||
switch (flag) {
|
||||
case PED_PARTITION_ROOT:
|
||||
return dvh_disk_data->root == part->num;
|
||||
|
||||
case PED_PARTITION_SWAP:
|
||||
return dvh_disk_data->swap == part->num;
|
||||
|
||||
case PED_PARTITION_BOOT:
|
||||
return dvh_disk_data->boot == part->num;
|
||||
|
||||
case PED_PARTITION_LVM:
|
||||
case PED_PARTITION_LBA:
|
||||
case PED_PARTITION_HIDDEN:
|
||||
case PED_PARTITION_RAID:
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int
|
||||
dvh_partition_is_flag_available (const PedPartition* part,
|
||||
PedPartitionFlag flag)
|
||||
{
|
||||
switch (flag) {
|
||||
case PED_PARTITION_ROOT:
|
||||
case PED_PARTITION_SWAP:
|
||||
case PED_PARTITION_BOOT:
|
||||
return 1;
|
||||
|
||||
case PED_PARTITION_LVM:
|
||||
case PED_PARTITION_LBA:
|
||||
case PED_PARTITION_HIDDEN:
|
||||
case PED_PARTITION_RAID:
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void
|
||||
dvh_partition_set_name (PedPartition* part, const char* name)
|
||||
{
|
||||
DVHPartData* dvh_part_data = part->disk_specific;
|
||||
|
||||
if (part->type == PED_PARTITION_LOGICAL) {
|
||||
/* Bootfile */
|
||||
memcpy (dvh_part_data->name, name, VDNAMESIZE);
|
||||
dvh_part_data->name[VDNAMESIZE] = 0;
|
||||
} else {
|
||||
#ifndef DISCOVER_ONLY
|
||||
ped_exception_throw (
|
||||
PED_EXCEPTION_ERROR,
|
||||
PED_EXCEPTION_CANCEL,
|
||||
_("failed to set dvh partition name to %s:\n"
|
||||
"Only logical partitions (boot files) have a name."),
|
||||
name);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
static const char*
|
||||
dvh_partition_get_name (const PedPartition* part)
|
||||
{
|
||||
DVHPartData* dvh_part_data = part->disk_specific;
|
||||
return dvh_part_data->name;
|
||||
}
|
||||
|
||||
/* The constraint for the volume header partition is different, because it must
|
||||
* contain the first sector of the disk.
|
||||
*/
|
||||
static PedConstraint*
|
||||
_get_extended_constraint (PedDisk* disk)
|
||||
{
|
||||
PedGeometry min_geom;
|
||||
if (!ped_geometry_init (&min_geom, disk->dev, 0, 1))
|
||||
return NULL;
|
||||
return ped_constraint_new_from_min (&min_geom);
|
||||
}
|
||||
|
||||
static PedConstraint*
|
||||
_get_primary_constraint (PedDisk* disk)
|
||||
{
|
||||
PedGeometry max_geom;
|
||||
if (!ped_geometry_init (&max_geom, disk->dev, 1, disk->dev->length - 1))
|
||||
return NULL;
|
||||
return ped_constraint_new_from_max (&max_geom);
|
||||
}
|
||||
|
||||
static int
|
||||
dvh_partition_align (PedPartition* part, const PedConstraint* constraint)
|
||||
{
|
||||
PED_ASSERT (part != NULL);
|
||||
|
||||
if (_ped_partition_attempt_align (
|
||||
part, constraint,
|
||||
(part->type == PED_PARTITION_EXTENDED)
|
||||
? _get_extended_constraint (part->disk)
|
||||
: _get_primary_constraint (part->disk)))
|
||||
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
|
||||
dvh_partition_enumerate (PedPartition* part)
|
||||
{
|
||||
int i;
|
||||
|
||||
/* never change the partition numbers */
|
||||
if (part->num != -1)
|
||||
return 1;
|
||||
|
||||
_flush_stale_flags (part->disk);
|
||||
|
||||
if (part->type & PED_PARTITION_LOGICAL) {
|
||||
/* Bootfile */
|
||||
for (i = 1 + NPARTAB; i <= NPARTAB + NVDIR; i++) {
|
||||
if (!ped_disk_get_partition (part->disk, i)) {
|
||||
part->num = i;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
PED_ASSERT (0);
|
||||
} else if (part->type & PED_PARTITION_EXTENDED) {
|
||||
/* Volheader */
|
||||
part->num = PNUM_VOLHDR + 1;
|
||||
} else {
|
||||
for (i = 1; i <= NPARTAB; i++) {
|
||||
/* reserved for full volume partition */
|
||||
if (i == PNUM_VOLUME + 1)
|
||||
continue;
|
||||
|
||||
if (!ped_disk_get_partition (part->disk, i)) {
|
||||
part->num = i;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
ped_exception_throw (
|
||||
PED_EXCEPTION_ERROR,
|
||||
PED_EXCEPTION_CANCEL,
|
||||
_("Too many primary partitions"));
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
dvh_get_max_primary_partition_count (const PedDisk* disk)
|
||||
{
|
||||
return NPARTAB;
|
||||
}
|
||||
|
||||
static bool
|
||||
dvh_get_max_supported_partition_count (const PedDisk* disk, int *max_n)
|
||||
{
|
||||
*max_n = NPARTAB;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
dvh_alloc_metadata (PedDisk* disk)
|
||||
{
|
||||
PedPartition* part;
|
||||
PedPartition* extended_part;
|
||||
PedPartitionType metadata_type;
|
||||
PED_ASSERT(disk != NULL);
|
||||
|
||||
/* We don't need to "protect" the start of the disk from the volume
|
||||
* header.
|
||||
*/
|
||||
extended_part = ped_disk_extended_partition (disk);
|
||||
if (extended_part && extended_part->geom.start == 0)
|
||||
metadata_type = PED_PARTITION_METADATA | PED_PARTITION_LOGICAL;
|
||||
else
|
||||
metadata_type = PED_PARTITION_METADATA;
|
||||
|
||||
part = ped_partition_new (disk, metadata_type, NULL, 0, 0);
|
||||
if (!part)
|
||||
goto error;
|
||||
|
||||
PedConstraint *constraint_exact
|
||||
= ped_constraint_exact (&part->geom);
|
||||
bool ok = ped_disk_add_partition (disk, part, constraint_exact);
|
||||
ped_constraint_destroy (constraint_exact);
|
||||
if (ok)
|
||||
return 1;
|
||||
|
||||
ped_partition_destroy (part);
|
||||
error:
|
||||
return 0;
|
||||
}
|
||||
|
||||
#include "pt-common.h"
|
||||
PT_define_limit_functions (dvh)
|
||||
|
||||
static PedDiskOps dvh_disk_ops = {
|
||||
clobber: NULL,
|
||||
write: NULL_IF_DISCOVER_ONLY (dvh_write),
|
||||
|
||||
partition_set_name: dvh_partition_set_name,
|
||||
partition_get_name: dvh_partition_get_name,
|
||||
PT_op_function_initializers (dvh)
|
||||
};
|
||||
|
||||
static PedDiskType dvh_disk_type = {
|
||||
next: NULL,
|
||||
name: "dvh",
|
||||
ops: &dvh_disk_ops,
|
||||
features: PED_DISK_TYPE_PARTITION_NAME | PED_DISK_TYPE_EXTENDED
|
||||
};
|
||||
|
||||
void
|
||||
ped_disk_dvh_init ()
|
||||
{
|
||||
PED_ASSERT (sizeof (struct volume_header) == 512);
|
||||
|
||||
ped_disk_type_register (&dvh_disk_type);
|
||||
}
|
||||
|
||||
void
|
||||
ped_disk_dvh_done ()
|
||||
{
|
||||
ped_disk_type_unregister (&dvh_disk_type);
|
||||
}
|
||||
178
jni/parted/libparted/labels/dvh.h
Executable file
178
jni/parted/libparted/labels/dvh.h
Executable file
@@ -0,0 +1,178 @@
|
||||
/*
|
||||
Copyright (C) 1985 MIPS Computer Systems, Inc.
|
||||
Copyright (C) 2000 Silicon Graphics Computer Systems, 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/>.
|
||||
*/
|
||||
|
||||
#ifndef _SYS_DVH_H
|
||||
#define _SYS_DVH_H
|
||||
|
||||
/*
|
||||
* Format for volume header information
|
||||
*
|
||||
* The volume header is a block located at the beginning of all disk
|
||||
* media (sector 0). It contains information pertaining to physical
|
||||
* device parameters and logical partition information.
|
||||
*
|
||||
* The volume header is manipulated by disk formatters/verifiers,
|
||||
* partition builders (e.g. fx, dvhtool, and mkfs), and disk drivers.
|
||||
*
|
||||
* Previous versions of IRIX wrote a copy of the volume header is
|
||||
* located at sector 0 of each track of cylinder 0. These copies were
|
||||
* never used, and reduced the capacity of the volume header to hold large
|
||||
* files, so this practice was discontinued.
|
||||
* The volume header is constrained to be less than or equal to 512
|
||||
* bytes long. A particular copy is assumed valid if no drive errors
|
||||
* are detected, the magic number is correct, and the 32 bit 2's complement
|
||||
* of the volume header is correct. The checksum is calculated by initially
|
||||
* zeroing vh_csum, summing the entire structure and then storing the
|
||||
* 2's complement of the sum. Thus a checksum to verify the volume header
|
||||
* should be 0.
|
||||
*
|
||||
* The error summary table, bad sector replacement table, and boot blocks are
|
||||
* located by searching the volume directory within the volume header.
|
||||
*
|
||||
* Tables are sized simply by the integral number of table records that
|
||||
* will fit in the space indicated by the directory entry.
|
||||
*
|
||||
* The amount of space allocated to the volume header, replacement blocks,
|
||||
* and other tables is user defined when the device is formatted.
|
||||
*/
|
||||
|
||||
/*
|
||||
* device parameters are in the volume header to determine mapping
|
||||
* from logical block numbers to physical device addresses
|
||||
*
|
||||
* Linux doesn't care ...
|
||||
*/
|
||||
struct device_parameters {
|
||||
unsigned char dp_skew; /* spiral addressing skew */
|
||||
unsigned char dp_gap1; /* words of 0 before header */
|
||||
unsigned char dp_gap2; /* words of 0 between hdr and data */
|
||||
unsigned char dp_spares_cyl; /* This is for drives (such as SCSI
|
||||
that support zone oriented sparing, where the zone is larger
|
||||
than one track. It gets subracteded from the cylinder size
|
||||
( dp_trks0 * dp_sec) when doing partition size calculations */
|
||||
unsigned short dp_cyls; /* number of usable cylinders (i.e.,
|
||||
doesn't include cylinders reserved by the drive for badblocks,
|
||||
etc.). For drives with variable geometry, this number may be
|
||||
decreased so that:
|
||||
dp_cyls * ((dp_heads * dp_trks0) - dp_spares_cyl) <= actualcapacity
|
||||
This happens on SCSI drives such as the Wren IV and Toshiba 156
|
||||
Also see dp_cylshi below */
|
||||
unsigned short dp_shd0; /* starting head vol 0 */
|
||||
unsigned short dp_trks0; /* number of tracks / cylinder vol 0*/
|
||||
unsigned char dp_ctq_depth; /* Depth of CTQ queue */
|
||||
unsigned char dp_cylshi; /* high byte of 24 bits of cylinder count */
|
||||
unsigned short dp_unused; /* not used */
|
||||
unsigned short dp_secs; /* number of sectors/track */
|
||||
unsigned short dp_secbytes; /* length of sector in bytes */
|
||||
unsigned short dp_interleave; /* sector interleave */
|
||||
int dp_flags; /* controller characteristics */
|
||||
int dp_datarate; /* bytes/sec for kernel stats */
|
||||
int dp_nretries; /* max num retries on data error */
|
||||
int dp_mspw; /* ms per word to xfer, for iostat */
|
||||
unsigned short dp_xgap1; /* Gap 1 for xylogics controllers */
|
||||
unsigned short dp_xsync; /* sync delay for xylogics controllers */
|
||||
unsigned short dp_xrdly; /* read delay for xylogics controllers */
|
||||
unsigned short dp_xgap2; /* gap 2 for xylogics controllers */
|
||||
unsigned short dp_xrgate; /* read gate for xylogics controllers */
|
||||
unsigned short dp_xwcont; /* write continuation for xylogics */
|
||||
};
|
||||
|
||||
/*
|
||||
* Device characterization flags
|
||||
* (dp_flags)
|
||||
*/
|
||||
#define DP_SECTSLIP 0x00000001 /* sector slip to spare sector */
|
||||
#define DP_SECTFWD 0x00000002 /* forward to replacement sector */
|
||||
#define DP_TRKFWD 0x00000004 /* forward to replacement track */
|
||||
#define DP_MULTIVOL 0x00000008 /* multiple volumes per spindle */
|
||||
#define DP_IGNOREERRORS 0x00000010 /* transfer data regardless of errors */
|
||||
#define DP_RESEEK 0x00000020 /* recalibrate as last resort */
|
||||
#define DP_CTQ_EN 0x00000040 /* enable command tag queueing */
|
||||
|
||||
/*
|
||||
* Boot blocks, bad sector tables, and the error summary table, are located
|
||||
* via the volume_directory.
|
||||
*/
|
||||
#define VDNAMESIZE 8
|
||||
|
||||
struct volume_directory {
|
||||
char vd_name[VDNAMESIZE]; /* name */
|
||||
unsigned int vd_lbn; /* logical block number */
|
||||
unsigned int vd_nbytes; /* file length in bytes */
|
||||
};
|
||||
|
||||
/*
|
||||
* partition table describes logical device partitions
|
||||
* (device drivers examine this to determine mapping from logical units
|
||||
* to cylinder groups, device formatters/verifiers examine this to determine
|
||||
* location of replacement tracks/sectors, etc)
|
||||
*
|
||||
* NOTE: pt_firstlbn SHOULD BE CYLINDER ALIGNED
|
||||
*/
|
||||
struct partition_table { /* one per logical partition */
|
||||
unsigned int pt_nblks; /* # of logical blks in partition */
|
||||
unsigned int pt_firstlbn; /* first lbn of partition */
|
||||
int pt_type; /* use of partition */
|
||||
};
|
||||
|
||||
#define PTYPE_VOLHDR 0 /* partition is volume header */
|
||||
#define PTYPE_TRKREPL 1 /* partition is used for repl trks */
|
||||
#define PTYPE_SECREPL 2 /* partition is used for repl secs */
|
||||
#define PTYPE_RAW 3 /* partition is used for data */
|
||||
#define PTYPE_BSD42 4 /* partition is 4.2BSD file system */
|
||||
#define PTYPE_BSD 4 /* partition is 4.2BSD file system */
|
||||
#define PTYPE_SYSV 5 /* partition is SysV file system */
|
||||
#define PTYPE_VOLUME 6 /* partition is entire volume */
|
||||
#define PTYPE_EFS 7 /* partition is sgi EFS */
|
||||
#define PTYPE_LVOL 8 /* partition is part of a logical vol */
|
||||
#define PTYPE_RLVOL 9 /* part of a "raw" logical vol */
|
||||
#define PTYPE_XFS 10 /* partition is sgi XFS */
|
||||
#define PTYPE_XFSLOG 11 /* partition is sgi XFS log */
|
||||
#define PTYPE_XLV 12 /* partition is part of an XLV vol */
|
||||
#define PTYPE_XVM 13 /* partition is sgi XVM */
|
||||
#define NPTYPES 16
|
||||
|
||||
#define VHMAGIC 0xbe5a941 /* randomly chosen value */
|
||||
#define NPARTAB 16 /* 16 unix partitions */
|
||||
#define NVDIR 15 /* max of 15 directory entries */
|
||||
#define BFNAMESIZE 16 /* max 16 chars in boot file name */
|
||||
|
||||
/* Partition types for ARCS */
|
||||
#define NOT_USED 0 /* Not used */
|
||||
#define FAT_SHORT 1 /* FAT file system, 12-bit FAT entries */
|
||||
#define FAT_LONG 4 /* FAT file system, 16-bit FAT entries */
|
||||
#define EXTENDED 5 /* extended partition */
|
||||
#define HUGE 6 /* huge partition- MS/DOS 4.0 and later */
|
||||
|
||||
/* Active flags for ARCS */
|
||||
#define BOOTABLE 0x00;
|
||||
#define NOT_BOOTABLE 0x80;
|
||||
|
||||
struct volume_header {
|
||||
int vh_magic; /* identifies volume header */
|
||||
short vh_rootpt; /* root partition number */
|
||||
short vh_swappt; /* swap partition number */
|
||||
char vh_bootfile[BFNAMESIZE]; /* name of file to boot */
|
||||
struct device_parameters vh_dp; /* device parameters */
|
||||
struct volume_directory vh_vd[NVDIR]; /* other vol hdr contents */
|
||||
struct partition_table vh_pt[NPARTAB]; /* device partition layout */
|
||||
int vh_csum; /* volume header checksum */
|
||||
int vh_fill; /* fill out to 512 bytes */
|
||||
};
|
||||
|
||||
#endif /* _SYS_DVH_H */
|
||||
126
jni/parted/libparted/labels/efi_crc32.c
Executable file
126
jni/parted/libparted/labels/efi_crc32.c
Executable file
@@ -0,0 +1,126 @@
|
||||
/*
|
||||
* Dec 5, 2000 Matt Domsch <Matt_Domsch@dell.com>
|
||||
* - Copied crc32.c from the linux/drivers/net/cipe directory.
|
||||
* - Now pass seed as an arg
|
||||
* - changed unsigned long to uint32_t, added #include<stdint.h>
|
||||
* - changed len to be an unsigned long
|
||||
* - changed crc32val to be a register
|
||||
* - License remains unchanged! It's still GPL-compatable!
|
||||
*/
|
||||
|
||||
/* ============================================================= */
|
||||
/* COPYRIGHT (C) 1986 Gary S. Brown. You may use this program, or */
|
||||
/* code or tables extracted from it, as desired without restriction. */
|
||||
/* */
|
||||
/* First, the polynomial itself and its table of feedback terms. The */
|
||||
/* polynomial is */
|
||||
/* X^32+X^26+X^23+X^22+X^16+X^12+X^11+X^10+X^8+X^7+X^5+X^4+X^2+X^1+X^0 */
|
||||
/* */
|
||||
/* Note that we take it "backwards" and put the highest-order term in */
|
||||
/* the lowest-order bit. The X^32 term is "implied"; the LSB is the */
|
||||
/* X^31 term, etc. The X^0 term (usually shown as "+1") results in */
|
||||
/* the MSB being 1. */
|
||||
/* */
|
||||
/* Note that the usual hardware shift register implementation, which */
|
||||
/* is what we're using (we're merely optimizing it by doing eight-bit */
|
||||
/* chunks at a time) shifts bits into the lowest-order term. In our */
|
||||
/* implementation, that means shifting towards the right. Why do we */
|
||||
/* do it this way? Because the calculated CRC must be transmitted in */
|
||||
/* order from highest-order term to lowest-order term. UARTs transmit */
|
||||
/* characters in order from LSB to MSB. By storing the CRC this way, */
|
||||
/* we hand it to the UART in the order low-byte to high-byte; the UART */
|
||||
/* sends each low-bit to hight-bit; and the result is transmission bit */
|
||||
/* by bit from highest- to lowest-order term without requiring any bit */
|
||||
/* shuffling on our part. Reception works similarly. */
|
||||
/* */
|
||||
/* The feedback terms table consists of 256, 32-bit entries. Notes: */
|
||||
/* */
|
||||
/* The table can be generated at runtime if desired; code to do so */
|
||||
/* is shown later. It might not be obvious, but the feedback */
|
||||
/* terms simply represent the results of eight shift/xor opera- */
|
||||
/* tions for all combinations of data and CRC register values. */
|
||||
/* */
|
||||
/* The values must be right-shifted by eight bits by the "updcrc" */
|
||||
/* logic; the shift must be unsigned (bring in zeroes). On some */
|
||||
/* hardware you could probably optimize the shift in assembler by */
|
||||
/* using byte-swap instructions. */
|
||||
/* polynomial $edb88320 */
|
||||
/* */
|
||||
/* -------------------------------------------------------------------- */
|
||||
|
||||
#include <config.h>
|
||||
#include <stdint.h>
|
||||
|
||||
static const uint32_t crc32_tab[] = {
|
||||
0x00000000L, 0x77073096L, 0xee0e612cL, 0x990951baL, 0x076dc419L,
|
||||
0x706af48fL, 0xe963a535L, 0x9e6495a3L, 0x0edb8832L, 0x79dcb8a4L,
|
||||
0xe0d5e91eL, 0x97d2d988L, 0x09b64c2bL, 0x7eb17cbdL, 0xe7b82d07L,
|
||||
0x90bf1d91L, 0x1db71064L, 0x6ab020f2L, 0xf3b97148L, 0x84be41deL,
|
||||
0x1adad47dL, 0x6ddde4ebL, 0xf4d4b551L, 0x83d385c7L, 0x136c9856L,
|
||||
0x646ba8c0L, 0xfd62f97aL, 0x8a65c9ecL, 0x14015c4fL, 0x63066cd9L,
|
||||
0xfa0f3d63L, 0x8d080df5L, 0x3b6e20c8L, 0x4c69105eL, 0xd56041e4L,
|
||||
0xa2677172L, 0x3c03e4d1L, 0x4b04d447L, 0xd20d85fdL, 0xa50ab56bL,
|
||||
0x35b5a8faL, 0x42b2986cL, 0xdbbbc9d6L, 0xacbcf940L, 0x32d86ce3L,
|
||||
0x45df5c75L, 0xdcd60dcfL, 0xabd13d59L, 0x26d930acL, 0x51de003aL,
|
||||
0xc8d75180L, 0xbfd06116L, 0x21b4f4b5L, 0x56b3c423L, 0xcfba9599L,
|
||||
0xb8bda50fL, 0x2802b89eL, 0x5f058808L, 0xc60cd9b2L, 0xb10be924L,
|
||||
0x2f6f7c87L, 0x58684c11L, 0xc1611dabL, 0xb6662d3dL, 0x76dc4190L,
|
||||
0x01db7106L, 0x98d220bcL, 0xefd5102aL, 0x71b18589L, 0x06b6b51fL,
|
||||
0x9fbfe4a5L, 0xe8b8d433L, 0x7807c9a2L, 0x0f00f934L, 0x9609a88eL,
|
||||
0xe10e9818L, 0x7f6a0dbbL, 0x086d3d2dL, 0x91646c97L, 0xe6635c01L,
|
||||
0x6b6b51f4L, 0x1c6c6162L, 0x856530d8L, 0xf262004eL, 0x6c0695edL,
|
||||
0x1b01a57bL, 0x8208f4c1L, 0xf50fc457L, 0x65b0d9c6L, 0x12b7e950L,
|
||||
0x8bbeb8eaL, 0xfcb9887cL, 0x62dd1ddfL, 0x15da2d49L, 0x8cd37cf3L,
|
||||
0xfbd44c65L, 0x4db26158L, 0x3ab551ceL, 0xa3bc0074L, 0xd4bb30e2L,
|
||||
0x4adfa541L, 0x3dd895d7L, 0xa4d1c46dL, 0xd3d6f4fbL, 0x4369e96aL,
|
||||
0x346ed9fcL, 0xad678846L, 0xda60b8d0L, 0x44042d73L, 0x33031de5L,
|
||||
0xaa0a4c5fL, 0xdd0d7cc9L, 0x5005713cL, 0x270241aaL, 0xbe0b1010L,
|
||||
0xc90c2086L, 0x5768b525L, 0x206f85b3L, 0xb966d409L, 0xce61e49fL,
|
||||
0x5edef90eL, 0x29d9c998L, 0xb0d09822L, 0xc7d7a8b4L, 0x59b33d17L,
|
||||
0x2eb40d81L, 0xb7bd5c3bL, 0xc0ba6cadL, 0xedb88320L, 0x9abfb3b6L,
|
||||
0x03b6e20cL, 0x74b1d29aL, 0xead54739L, 0x9dd277afL, 0x04db2615L,
|
||||
0x73dc1683L, 0xe3630b12L, 0x94643b84L, 0x0d6d6a3eL, 0x7a6a5aa8L,
|
||||
0xe40ecf0bL, 0x9309ff9dL, 0x0a00ae27L, 0x7d079eb1L, 0xf00f9344L,
|
||||
0x8708a3d2L, 0x1e01f268L, 0x6906c2feL, 0xf762575dL, 0x806567cbL,
|
||||
0x196c3671L, 0x6e6b06e7L, 0xfed41b76L, 0x89d32be0L, 0x10da7a5aL,
|
||||
0x67dd4accL, 0xf9b9df6fL, 0x8ebeeff9L, 0x17b7be43L, 0x60b08ed5L,
|
||||
0xd6d6a3e8L, 0xa1d1937eL, 0x38d8c2c4L, 0x4fdff252L, 0xd1bb67f1L,
|
||||
0xa6bc5767L, 0x3fb506ddL, 0x48b2364bL, 0xd80d2bdaL, 0xaf0a1b4cL,
|
||||
0x36034af6L, 0x41047a60L, 0xdf60efc3L, 0xa867df55L, 0x316e8eefL,
|
||||
0x4669be79L, 0xcb61b38cL, 0xbc66831aL, 0x256fd2a0L, 0x5268e236L,
|
||||
0xcc0c7795L, 0xbb0b4703L, 0x220216b9L, 0x5505262fL, 0xc5ba3bbeL,
|
||||
0xb2bd0b28L, 0x2bb45a92L, 0x5cb36a04L, 0xc2d7ffa7L, 0xb5d0cf31L,
|
||||
0x2cd99e8bL, 0x5bdeae1dL, 0x9b64c2b0L, 0xec63f226L, 0x756aa39cL,
|
||||
0x026d930aL, 0x9c0906a9L, 0xeb0e363fL, 0x72076785L, 0x05005713L,
|
||||
0x95bf4a82L, 0xe2b87a14L, 0x7bb12baeL, 0x0cb61b38L, 0x92d28e9bL,
|
||||
0xe5d5be0dL, 0x7cdcefb7L, 0x0bdbdf21L, 0x86d3d2d4L, 0xf1d4e242L,
|
||||
0x68ddb3f8L, 0x1fda836eL, 0x81be16cdL, 0xf6b9265bL, 0x6fb077e1L,
|
||||
0x18b74777L, 0x88085ae6L, 0xff0f6a70L, 0x66063bcaL, 0x11010b5cL,
|
||||
0x8f659effL, 0xf862ae69L, 0x616bffd3L, 0x166ccf45L, 0xa00ae278L,
|
||||
0xd70dd2eeL, 0x4e048354L, 0x3903b3c2L, 0xa7672661L, 0xd06016f7L,
|
||||
0x4969474dL, 0x3e6e77dbL, 0xaed16a4aL, 0xd9d65adcL, 0x40df0b66L,
|
||||
0x37d83bf0L, 0xa9bcae53L, 0xdebb9ec5L, 0x47b2cf7fL, 0x30b5ffe9L,
|
||||
0xbdbdf21cL, 0xcabac28aL, 0x53b39330L, 0x24b4a3a6L, 0xbad03605L,
|
||||
0xcdd70693L, 0x54de5729L, 0x23d967bfL, 0xb3667a2eL, 0xc4614ab8L,
|
||||
0x5d681b02L, 0x2a6f2b94L, 0xb40bbe37L, 0xc30c8ea1L, 0x5a05df1bL,
|
||||
0x2d02ef8dL
|
||||
};
|
||||
|
||||
/* Return a 32-bit CRC of the contents of the buffer. */
|
||||
|
||||
uint32_t _GL_ATTRIBUTE_PURE
|
||||
__efi_crc32(const void *buf, unsigned long len, uint32_t seed)
|
||||
{
|
||||
unsigned long i;
|
||||
register uint32_t crc32val;
|
||||
const unsigned char *s = buf;
|
||||
|
||||
crc32val = seed;
|
||||
for (i = 0; i < len; i ++)
|
||||
{
|
||||
crc32val =
|
||||
crc32_tab[(crc32val ^ s[i]) & 0xff] ^
|
||||
(crc32val >> 8);
|
||||
}
|
||||
return crc32val;
|
||||
}
|
||||
1442
jni/parted/libparted/labels/fdasd.c
Executable file
1442
jni/parted/libparted/labels/fdasd.c
Executable file
File diff suppressed because it is too large
Load Diff
1941
jni/parted/libparted/labels/gpt.c
Executable file
1941
jni/parted/libparted/labels/gpt.c
Executable file
File diff suppressed because it is too large
Load Diff
316
jni/parted/libparted/labels/loop.c
Executable file
316
jni/parted/libparted/labels/loop.c
Executable file
@@ -0,0 +1,316 @@
|
||||
/*
|
||||
libparted - a library for manipulating disk partitions
|
||||
Copyright (C) 1999-2000, 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/>.
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#include <parted/parted.h>
|
||||
#include <parted/debug.h>
|
||||
#include <parted/endian.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#include "pt-tools.h"
|
||||
|
||||
#if ENABLE_NLS
|
||||
# include <libintl.h>
|
||||
# define _(String) dgettext (PACKAGE, String)
|
||||
#else
|
||||
# define _(String) (String)
|
||||
#endif /* ENABLE_NLS */
|
||||
|
||||
#define LOOP_SIGNATURE "GNU Parted Loopback 0"
|
||||
|
||||
static PedDiskType loop_disk_type;
|
||||
|
||||
static PedDisk* loop_alloc (const PedDevice* dev);
|
||||
static void loop_free (PedDisk* disk);
|
||||
|
||||
static int
|
||||
loop_probe (const PedDevice* dev)
|
||||
{
|
||||
PedDisk *disk = loop_alloc (dev);
|
||||
if (!disk)
|
||||
goto error;
|
||||
|
||||
void *buf;
|
||||
if (!ptt_read_sector (dev, 0, &buf))
|
||||
goto error_destroy_disk;
|
||||
int found_sig = !strncmp (buf, LOOP_SIGNATURE, strlen (LOOP_SIGNATURE));
|
||||
free (buf);
|
||||
|
||||
int result;
|
||||
if (found_sig) {
|
||||
result = 1;
|
||||
} else {
|
||||
PedGeometry* geom;
|
||||
|
||||
geom = ped_geometry_new (dev, 0, disk->dev->length);
|
||||
if (!geom)
|
||||
goto error_destroy_disk;
|
||||
result = ped_file_system_probe (geom) != NULL;
|
||||
ped_geometry_destroy (geom);
|
||||
}
|
||||
loop_free (disk);
|
||||
return result;
|
||||
|
||||
error_destroy_disk:
|
||||
loop_free (disk);
|
||||
error:
|
||||
return 0;
|
||||
}
|
||||
|
||||
static PedDisk*
|
||||
loop_alloc (const PedDevice* dev)
|
||||
{
|
||||
PED_ASSERT (dev != NULL);
|
||||
|
||||
if (dev->length < 256)
|
||||
return NULL;
|
||||
PedDisk *disk = _ped_disk_alloc ((PedDevice*)dev, &loop_disk_type);
|
||||
PED_ASSERT (disk != NULL);
|
||||
PedGeometry *geom = ped_geometry_new (dev, 0, dev->length);
|
||||
PED_ASSERT (geom != NULL);
|
||||
PedPartition *part = ped_partition_new (disk, PED_PARTITION_NORMAL,
|
||||
NULL, geom->start, geom->end);
|
||||
PED_ASSERT (part != NULL);
|
||||
ped_geometry_destroy (geom);
|
||||
PedConstraint *constraint_any = ped_constraint_any (dev);
|
||||
if (!ped_disk_add_partition (disk, part, constraint_any))
|
||||
goto error;
|
||||
ped_constraint_destroy (constraint_any);
|
||||
return disk;
|
||||
error:
|
||||
ped_constraint_destroy (constraint_any);
|
||||
ped_disk_destroy (disk);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static PedDisk*
|
||||
loop_duplicate (const PedDisk* disk)
|
||||
{
|
||||
return ped_disk_new_fresh (disk->dev, &loop_disk_type);
|
||||
}
|
||||
|
||||
static void
|
||||
loop_free (PedDisk* disk)
|
||||
{
|
||||
PED_ASSERT (disk != NULL);
|
||||
|
||||
_ped_disk_free (disk);
|
||||
}
|
||||
|
||||
static int
|
||||
loop_read (PedDisk* disk)
|
||||
{
|
||||
PedDevice* dev = NULL;
|
||||
PedGeometry* geom;
|
||||
PedFileSystemType* fs_type;
|
||||
PedPartition* part;
|
||||
PedConstraint* constraint_any;
|
||||
|
||||
PED_ASSERT (disk != NULL);
|
||||
dev = disk->dev;
|
||||
constraint_any = ped_constraint_any (dev);
|
||||
|
||||
ped_disk_delete_all (disk);
|
||||
|
||||
void *buf;
|
||||
if (!ptt_read_sector (dev, 0, &buf))
|
||||
goto error;
|
||||
|
||||
int found_sig = !strncmp (buf, LOOP_SIGNATURE, strlen (LOOP_SIGNATURE));
|
||||
free (buf);
|
||||
geom = ped_geometry_new (dev, 0, dev->length);
|
||||
if (!geom)
|
||||
goto error;
|
||||
|
||||
fs_type = ped_file_system_probe (geom);
|
||||
if (!fs_type && !found_sig)
|
||||
goto error_free_geom;
|
||||
|
||||
part = ped_partition_new (disk, PED_PARTITION_NORMAL,
|
||||
fs_type, geom->start, geom->end);
|
||||
ped_geometry_destroy (geom);
|
||||
if (!part)
|
||||
goto error;
|
||||
|
||||
if (!ped_disk_add_partition (disk, part, constraint_any))
|
||||
goto error;
|
||||
ped_constraint_destroy (constraint_any);
|
||||
return 1;
|
||||
|
||||
error_free_geom:
|
||||
ped_geometry_destroy (geom);
|
||||
error:
|
||||
ped_constraint_destroy (constraint_any);
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifndef DISCOVER_ONLY
|
||||
static int
|
||||
loop_write (const PedDisk* disk)
|
||||
{
|
||||
size_t buflen = disk->dev->sector_size;
|
||||
char *buf = alloca (buflen);
|
||||
PedPartition *part = ped_disk_get_partition (disk, 1);
|
||||
/* if there is already a filesystem on the disk, we don't need to write the signature */
|
||||
if (part && part->fs_type)
|
||||
return 1;
|
||||
if (!ped_device_read (disk->dev, buf, 0, 1))
|
||||
return 0;
|
||||
strcpy (buf, LOOP_SIGNATURE);
|
||||
|
||||
return ped_device_write (disk->dev, buf, 0, 1);
|
||||
}
|
||||
#endif /* !DISCOVER_ONLY */
|
||||
|
||||
static PedPartition*
|
||||
loop_partition_new (const PedDisk* disk, PedPartitionType part_type,
|
||||
const PedFileSystemType* fs_type,
|
||||
PedSector start, PedSector end)
|
||||
{
|
||||
PedPartition* part;
|
||||
|
||||
part = _ped_partition_alloc (disk, part_type, fs_type, start, end);
|
||||
if (!part)
|
||||
return NULL;
|
||||
part->disk_specific = NULL;
|
||||
return part;
|
||||
}
|
||||
|
||||
static PedPartition*
|
||||
loop_partition_duplicate (const PedPartition* part)
|
||||
{
|
||||
PedPartition* result;
|
||||
|
||||
result = ped_partition_new (part->disk, part->type, part->fs_type,
|
||||
part->geom.start, part->geom.end);
|
||||
if (result == NULL)
|
||||
return NULL;
|
||||
result->num = part->num;
|
||||
return result;
|
||||
}
|
||||
|
||||
static void
|
||||
loop_partition_destroy (PedPartition* part)
|
||||
{
|
||||
free (part);
|
||||
}
|
||||
|
||||
static int
|
||||
loop_partition_set_system (PedPartition* part, const PedFileSystemType* fs_type)
|
||||
{
|
||||
part->fs_type = fs_type;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int
|
||||
loop_partition_set_flag (PedPartition* part, PedPartitionFlag flag, int state)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
loop_partition_get_flag (const PedPartition* part, PedPartitionFlag flag)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
loop_partition_align (PedPartition* part, const PedConstraint* constraint)
|
||||
{
|
||||
PedGeometry* new_geom;
|
||||
|
||||
new_geom = ped_constraint_solve_nearest (constraint, &part->geom);
|
||||
if (!new_geom) {
|
||||
ped_exception_throw (
|
||||
PED_EXCEPTION_ERROR,
|
||||
PED_EXCEPTION_CANCEL,
|
||||
_("Unable to satisfy all constraints on the "
|
||||
"partition."));
|
||||
return 0;
|
||||
}
|
||||
ped_geometry_set (&part->geom, new_geom->start, new_geom->length);
|
||||
ped_geometry_destroy (new_geom);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int
|
||||
loop_partition_is_flag_available (const PedPartition* part,
|
||||
PedPartitionFlag flag)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
loop_partition_enumerate (PedPartition* part)
|
||||
{
|
||||
part->num = 1;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int
|
||||
loop_alloc_metadata (PedDisk* disk)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int
|
||||
loop_get_max_primary_partition_count (const PedDisk* disk)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
static bool
|
||||
loop_get_max_supported_partition_count (const PedDisk* disk, int *max_n)
|
||||
{
|
||||
*max_n = 1;
|
||||
return true;
|
||||
}
|
||||
|
||||
#include "pt-common.h"
|
||||
PT_define_limit_functions (loop)
|
||||
|
||||
static PedDiskOps loop_disk_ops = {
|
||||
clobber: NULL,
|
||||
write: NULL_IF_DISCOVER_ONLY (loop_write),
|
||||
|
||||
partition_set_name: NULL,
|
||||
partition_get_name: NULL,
|
||||
|
||||
PT_op_function_initializers (loop)
|
||||
};
|
||||
|
||||
static PedDiskType loop_disk_type = {
|
||||
next: NULL,
|
||||
name: "loop",
|
||||
ops: &loop_disk_ops,
|
||||
features: 0
|
||||
};
|
||||
|
||||
void
|
||||
ped_disk_loop_init ()
|
||||
{
|
||||
ped_disk_type_register (&loop_disk_type);
|
||||
}
|
||||
|
||||
void
|
||||
ped_disk_loop_done ()
|
||||
{
|
||||
ped_disk_type_unregister (&loop_disk_type);
|
||||
}
|
||||
1604
jni/parted/libparted/labels/mac.c
Executable file
1604
jni/parted/libparted/labels/mac.c
Executable file
File diff suppressed because it is too large
Load Diff
48
jni/parted/libparted/labels/misc.h
Executable file
48
jni/parted/libparted/labels/misc.h
Executable file
@@ -0,0 +1,48 @@
|
||||
/* -*- Mode: c; indent-tabs-mode: nil -*-
|
||||
|
||||
libparted - a library for manipulating disk partitions
|
||||
Copyright (C) 2007, 2009-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/>. */
|
||||
|
||||
#include <inttypes.h>
|
||||
#include <uuid/uuid.h>
|
||||
|
||||
/* hack: use the ext2 uuid library to generate a reasonably random (hopefully
|
||||
* with /dev/random) number. Unfortunately, we can only use 4 bytes of it.
|
||||
* We make sure to avoid returning zero which may be interpreted as no FAT
|
||||
* serial number or no MBR signature.
|
||||
*/
|
||||
static inline uint32_t
|
||||
generate_random_uint32 (void)
|
||||
{
|
||||
union {
|
||||
uuid_t uuid;
|
||||
uint32_t i;
|
||||
} uu32;
|
||||
|
||||
uuid_generate (uu32.uuid);
|
||||
|
||||
return uu32.i > 0 ? uu32.i : 0xffffffff;
|
||||
}
|
||||
|
||||
/* Return nonzero if FS_TYPE_NAME starts with "linux-swap".
|
||||
This must match the NUL-terminated "linux-swap" as well
|
||||
as "linux-swap(v0)" and "linux-swap(v1)". */
|
||||
static inline int
|
||||
is_linux_swap (char const *fs_type_name)
|
||||
{
|
||||
char const *prefix = "linux-swap";
|
||||
return strncmp (fs_type_name, prefix, strlen (prefix)) == 0;
|
||||
}
|
||||
813
jni/parted/libparted/labels/pc98.c
Executable file
813
jni/parted/libparted/labels/pc98.c
Executable file
@@ -0,0 +1,813 @@
|
||||
/*
|
||||
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/>.
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#include <parted/parted.h>
|
||||
#include <parted/debug.h>
|
||||
#include <parted/endian.h>
|
||||
|
||||
#include "pt-tools.h"
|
||||
|
||||
#if ENABLE_NLS
|
||||
# include <libintl.h>
|
||||
# define _(String) dgettext (PACKAGE, String)
|
||||
#else
|
||||
# define _(String) (String)
|
||||
#endif /* ENABLE_NLS */
|
||||
|
||||
/* hacked from Linux/98 source: fs/partitions/nec98.h
|
||||
*
|
||||
* See also:
|
||||
* http://people.FreeBSD.org/~kato/pc98.html
|
||||
* http://www.kmc.kyoto-u.ac.jp/proj/linux98/index-english.html
|
||||
*
|
||||
* Partition types:
|
||||
*
|
||||
* id0(mid):
|
||||
* bit 7: 1=bootable, 0=not bootable
|
||||
* # Linux uses this flag to make a distinction between ext2 and swap.
|
||||
* bit 6--0:
|
||||
* 00H : N88-BASIC(data)?, PC-UX(data)?
|
||||
* 04H : PC-UX(data)
|
||||
* 06H : N88-BASIC
|
||||
* 10H : N88-BASIC
|
||||
* 14H : *BSD, PC-UX
|
||||
* 20H : DOS(data), Windows95/98/NT, Linux
|
||||
* 21H..2FH : DOS(system#1 .. system#15)
|
||||
* 40H : Minix
|
||||
*
|
||||
* id1(sid):
|
||||
* bit 7: 1=active, 0=sleep(hidden)
|
||||
* # PC-UX uses this flag to make a distinction between its file system
|
||||
* # and its swap.
|
||||
* bit 6--0:
|
||||
* 01H: FAT12
|
||||
* 11H: FAT16, <32MB [accessible to DOS 3.3]
|
||||
* 21H: FAT16, >=32MB [Large Partition]
|
||||
* 31H: NTFS
|
||||
* 28H: Windows NT (Volume/Stripe Set?)
|
||||
* 41H: Windows NT (Volume/Stripe Set?)
|
||||
* 48H: Windows NT (Volume/Stripe Set?)
|
||||
* 61H: FAT32
|
||||
* 04H: PC-UX
|
||||
* 06H: N88-BASIC
|
||||
* 44H: *BSD
|
||||
* 62H: ext2, linux-swap
|
||||
*/
|
||||
|
||||
#define MAX_PART_COUNT 16
|
||||
#define PC9800_EXTFMT_MAGIC 0xAA55
|
||||
|
||||
#define BIT(x) (1 << (x))
|
||||
#define GET_BIT(n,bit) (((n) & BIT(bit)) != 0)
|
||||
#define SET_BIT(n,bit,val) n = (val)? (n | BIT(bit)) : (n & ~BIT(bit))
|
||||
|
||||
typedef struct _PC98RawPartition PC98RawPartition;
|
||||
typedef struct _PC98RawTable PC98RawTable;
|
||||
|
||||
/* ripped from Linux/98 source */
|
||||
struct _PC98RawPartition {
|
||||
uint8_t mid; /* 0x80 - boot */
|
||||
uint8_t sid; /* 0x80 - active */
|
||||
uint8_t dum1; /* dummy for padding */
|
||||
uint8_t dum2; /* dummy for padding */
|
||||
uint8_t ipl_sect; /* IPL sector */
|
||||
uint8_t ipl_head; /* IPL head */
|
||||
uint16_t ipl_cyl; /* IPL cylinder */
|
||||
uint8_t sector; /* starting sector */
|
||||
uint8_t head; /* starting head */
|
||||
uint16_t cyl; /* starting cylinder */
|
||||
uint8_t end_sector; /* end sector */
|
||||
uint8_t end_head; /* end head */
|
||||
uint16_t end_cyl; /* end cylinder */
|
||||
char name[16];
|
||||
} __attribute__((packed));
|
||||
|
||||
struct _PC98RawTable {
|
||||
uint8_t boot_code [510];
|
||||
uint16_t magic;
|
||||
PC98RawPartition partitions [MAX_PART_COUNT];
|
||||
} __attribute__((packed));
|
||||
|
||||
typedef struct {
|
||||
PedSector ipl_sector;
|
||||
int system;
|
||||
int boot;
|
||||
int hidden;
|
||||
char name [17];
|
||||
} PC98PartitionData;
|
||||
|
||||
/* this MBR boot code is dummy */
|
||||
static const char MBR_BOOT_CODE[] = {
|
||||
0xcb, /* retf */
|
||||
0x00, 0x00, 0x00, /* */
|
||||
0x49, 0x50, 0x4c, 0x31 /* "IPL1" */
|
||||
};
|
||||
|
||||
static PedDiskType pc98_disk_type;
|
||||
|
||||
static PedSector chs_to_sector (const PedDevice* dev, int c, int h, int s);
|
||||
static void sector_to_chs (const PedDevice* dev, PedSector sector,
|
||||
int* c, int* h, int* s);
|
||||
|
||||
/* magic(?) check */
|
||||
static int
|
||||
pc98_check_magic (const PC98RawTable *part_table)
|
||||
{
|
||||
/* check "extended-format" (have partition table?) */
|
||||
if (PED_LE16_TO_CPU(part_table->magic) != PC9800_EXTFMT_MAGIC)
|
||||
return 0;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int
|
||||
pc98_check_ipl_signature (const PC98RawTable *part_table)
|
||||
{
|
||||
if (memcmp (part_table->boot_code + 4, "IPL1", 4) == 0)
|
||||
return 1;
|
||||
else if (memcmp (part_table->boot_code + 4, "Linux 98", 8) == 0)
|
||||
return 1;
|
||||
else if (memcmp (part_table->boot_code + 4, "GRUB/98 ", 8) == 0)
|
||||
return 1;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
pc98_probe (const PedDevice *dev)
|
||||
{
|
||||
PC98RawTable part_table;
|
||||
|
||||
PED_ASSERT (dev != NULL);
|
||||
|
||||
if (dev->sector_size != 512)
|
||||
return 0;
|
||||
|
||||
if (!ped_device_read (dev, &part_table, 0, 2))
|
||||
return 0;
|
||||
|
||||
/* check magic */
|
||||
if (!pc98_check_magic (&part_table))
|
||||
return 0;
|
||||
|
||||
/* check for boot loader signatures */
|
||||
return pc98_check_ipl_signature (&part_table);
|
||||
}
|
||||
|
||||
static PedDisk*
|
||||
pc98_alloc (const PedDevice* dev)
|
||||
{
|
||||
PED_ASSERT (dev != NULL);
|
||||
|
||||
return _ped_disk_alloc (dev, &pc98_disk_type);
|
||||
}
|
||||
|
||||
static PedDisk*
|
||||
pc98_duplicate (const PedDisk* disk)
|
||||
{
|
||||
return ped_disk_new_fresh (disk->dev, &pc98_disk_type);
|
||||
}
|
||||
|
||||
static void
|
||||
pc98_free (PedDisk* disk)
|
||||
{
|
||||
PED_ASSERT (disk != NULL);
|
||||
|
||||
_ped_disk_free (disk);
|
||||
}
|
||||
|
||||
static PedSector _GL_ATTRIBUTE_PURE
|
||||
chs_to_sector (const PedDevice* dev, int c, int h, int s)
|
||||
{
|
||||
PED_ASSERT (dev != NULL);
|
||||
return (c * dev->hw_geom.heads + h) * dev->hw_geom.sectors + s;
|
||||
}
|
||||
|
||||
static void
|
||||
sector_to_chs (const PedDevice* dev, PedSector sector, int* c, int* h, int* s)
|
||||
{
|
||||
PedSector cyl_size;
|
||||
|
||||
PED_ASSERT (dev != NULL);
|
||||
PED_ASSERT (c != NULL);
|
||||
PED_ASSERT (h != NULL);
|
||||
PED_ASSERT (s != NULL);
|
||||
|
||||
cyl_size = dev->hw_geom.heads * dev->hw_geom.sectors;
|
||||
|
||||
*c = sector / cyl_size;
|
||||
*h = (sector) % cyl_size / dev->hw_geom.sectors;
|
||||
*s = (sector) % cyl_size % dev->hw_geom.sectors;
|
||||
}
|
||||
|
||||
static PedSector _GL_ATTRIBUTE_PURE
|
||||
legacy_start (const PedDisk* disk, const PC98RawPartition* raw_part)
|
||||
{
|
||||
PED_ASSERT (disk != NULL);
|
||||
PED_ASSERT (raw_part != NULL);
|
||||
|
||||
return chs_to_sector (disk->dev, PED_LE16_TO_CPU(raw_part->cyl),
|
||||
raw_part->head, raw_part->sector);
|
||||
}
|
||||
|
||||
static PedSector _GL_ATTRIBUTE_PURE
|
||||
legacy_end (const PedDisk* disk, const PC98RawPartition* raw_part)
|
||||
{
|
||||
PED_ASSERT (disk != NULL);
|
||||
PED_ASSERT (raw_part != NULL);
|
||||
|
||||
if (raw_part->end_head == 0 && raw_part->end_sector == 0) {
|
||||
return chs_to_sector (disk->dev,
|
||||
PED_LE16_TO_CPU(raw_part->end_cyl),
|
||||
disk->dev->hw_geom.heads - 1,
|
||||
disk->dev->hw_geom.sectors - 1);
|
||||
} else {
|
||||
return chs_to_sector (disk->dev,
|
||||
PED_LE16_TO_CPU(raw_part->end_cyl),
|
||||
raw_part->end_head,
|
||||
raw_part->end_sector);
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
is_unused_partition(const PC98RawPartition* raw_part)
|
||||
{
|
||||
if (raw_part->mid || raw_part->sid
|
||||
|| raw_part->ipl_sect
|
||||
|| raw_part->ipl_head
|
||||
|| PED_LE16_TO_CPU(raw_part->ipl_cyl)
|
||||
|| raw_part->sector
|
||||
|| raw_part->head
|
||||
|| PED_LE16_TO_CPU(raw_part->cyl)
|
||||
|| raw_part->end_sector
|
||||
|| raw_part->end_head
|
||||
|| PED_LE16_TO_CPU(raw_part->end_cyl))
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int
|
||||
read_table (PedDisk* disk)
|
||||
{
|
||||
int i;
|
||||
PC98RawTable table;
|
||||
PedConstraint* constraint_any;
|
||||
|
||||
PED_ASSERT (disk != NULL);
|
||||
PED_ASSERT (disk->dev != NULL);
|
||||
|
||||
constraint_any = ped_constraint_any (disk->dev);
|
||||
|
||||
if (!ped_device_read (disk->dev, (void*) &table, 0, 2))
|
||||
goto error;
|
||||
|
||||
if (!pc98_check_magic(&table)) {
|
||||
if (ped_exception_throw (
|
||||
PED_EXCEPTION_ERROR, PED_EXCEPTION_IGNORE_CANCEL,
|
||||
_("Invalid partition table on %s."),
|
||||
disk->dev->path))
|
||||
goto error;
|
||||
}
|
||||
|
||||
for (i = 0; i < MAX_PART_COUNT; i++) {
|
||||
PC98RawPartition* raw_part;
|
||||
PedPartition* part;
|
||||
PC98PartitionData* pc98_data;
|
||||
PedSector part_start;
|
||||
PedSector part_end;
|
||||
|
||||
raw_part = &table.partitions [i];
|
||||
|
||||
if (is_unused_partition(raw_part))
|
||||
continue;
|
||||
|
||||
part_start = legacy_start (disk, raw_part);
|
||||
part_end = legacy_end (disk, raw_part);
|
||||
|
||||
part = ped_partition_new (disk, PED_PARTITION_NORMAL,
|
||||
NULL, part_start, part_end);
|
||||
if (!part)
|
||||
goto error;
|
||||
pc98_data = part->disk_specific;
|
||||
PED_ASSERT (pc98_data != NULL);
|
||||
|
||||
pc98_data->system = (raw_part->mid << 8) | raw_part->sid;
|
||||
pc98_data->boot = GET_BIT(raw_part->mid, 7);
|
||||
pc98_data->hidden = !GET_BIT(raw_part->sid, 7);
|
||||
|
||||
ped_partition_set_name (part, raw_part->name);
|
||||
|
||||
pc98_data->ipl_sector = chs_to_sector (
|
||||
disk->dev,
|
||||
PED_LE16_TO_CPU(raw_part->ipl_cyl),
|
||||
raw_part->ipl_head,
|
||||
raw_part->ipl_sect);
|
||||
|
||||
/* hack */
|
||||
if (pc98_data->ipl_sector == part->geom.start)
|
||||
pc98_data->ipl_sector = 0;
|
||||
|
||||
part->num = i + 1;
|
||||
|
||||
if (!ped_disk_add_partition (disk, part, constraint_any))
|
||||
goto error;
|
||||
|
||||
if (part->geom.start != part_start
|
||||
|| part->geom.end != part_end) {
|
||||
ped_exception_throw (
|
||||
PED_EXCEPTION_NO_FEATURE,
|
||||
PED_EXCEPTION_CANCEL,
|
||||
_("Partition %d isn't aligned to cylinder "
|
||||
"boundaries. This is still unsupported."),
|
||||
part->num);
|
||||
goto error;
|
||||
}
|
||||
|
||||
part->fs_type = ped_file_system_probe (&part->geom);
|
||||
}
|
||||
|
||||
ped_constraint_destroy (constraint_any);
|
||||
return 1;
|
||||
|
||||
error:
|
||||
ped_disk_delete_all (disk);
|
||||
ped_constraint_destroy (constraint_any);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
pc98_read (PedDisk* disk)
|
||||
{
|
||||
PED_ASSERT (disk != NULL);
|
||||
PED_ASSERT (disk->dev != NULL);
|
||||
|
||||
ped_disk_delete_all (disk);
|
||||
return read_table (disk);
|
||||
}
|
||||
|
||||
#ifndef DISCOVER_ONLY
|
||||
static int
|
||||
fill_raw_part (PC98RawPartition* raw_part, const PedPartition* part)
|
||||
{
|
||||
PC98PartitionData* pc98_data;
|
||||
int c, h, s;
|
||||
const char* name;
|
||||
|
||||
PED_ASSERT (raw_part != NULL);
|
||||
PED_ASSERT (part != NULL);
|
||||
PED_ASSERT (part->disk_specific != NULL);
|
||||
|
||||
pc98_data = part->disk_specific;
|
||||
raw_part->mid = (pc98_data->system >> 8) & 0xFF;
|
||||
raw_part->sid = pc98_data->system & 0xFF;
|
||||
|
||||
SET_BIT(raw_part->mid, 7, pc98_data->boot);
|
||||
SET_BIT(raw_part->sid, 7, !pc98_data->hidden);
|
||||
|
||||
memset (raw_part->name, ' ', sizeof(raw_part->name));
|
||||
name = ped_partition_get_name (part);
|
||||
PED_ASSERT (name != NULL);
|
||||
PED_ASSERT (strlen (name) <= 16);
|
||||
if (!strlen (name) && part->fs_type)
|
||||
name = part->fs_type->name;
|
||||
memcpy (raw_part->name, name, strlen (name));
|
||||
|
||||
sector_to_chs (part->disk->dev, part->geom.start, &c, &h, &s);
|
||||
raw_part->cyl = PED_CPU_TO_LE16(c);
|
||||
raw_part->head = h;
|
||||
raw_part->sector = s;
|
||||
|
||||
if (pc98_data->ipl_sector) {
|
||||
sector_to_chs (part->disk->dev, pc98_data->ipl_sector,
|
||||
&c, &h, &s);
|
||||
raw_part->ipl_cyl = PED_CPU_TO_LE16(c);
|
||||
raw_part->ipl_head = h;
|
||||
raw_part->ipl_sect = s;
|
||||
} else {
|
||||
raw_part->ipl_cyl = raw_part->cyl;
|
||||
raw_part->ipl_head = raw_part->head;
|
||||
raw_part->ipl_sect = raw_part->sector;
|
||||
}
|
||||
|
||||
sector_to_chs (part->disk->dev, part->geom.end, &c, &h, &s);
|
||||
if (h != part->disk->dev->hw_geom.heads - 1
|
||||
|| s != part->disk->dev->hw_geom.sectors - 1) {
|
||||
ped_exception_throw (
|
||||
PED_EXCEPTION_NO_FEATURE,
|
||||
PED_EXCEPTION_CANCEL,
|
||||
_("Partition %d isn't aligned to cylinder "
|
||||
"boundaries. This is still unsupported."),
|
||||
part->num);
|
||||
return 0;
|
||||
}
|
||||
raw_part->end_cyl = PED_CPU_TO_LE16(c);
|
||||
raw_part->end_head = 0;
|
||||
raw_part->end_sector = 0;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int
|
||||
pc98_write (const PedDisk* disk)
|
||||
{
|
||||
PedPartition* part;
|
||||
int i;
|
||||
|
||||
PED_ASSERT (disk != NULL);
|
||||
PED_ASSERT (disk->dev != NULL);
|
||||
|
||||
void *s0;
|
||||
if (!ptt_read_sectors (disk->dev, 0, 2, &s0))
|
||||
return 0;
|
||||
PC98RawTable *table = s0;
|
||||
|
||||
if (!pc98_check_ipl_signature (table)) {
|
||||
memset (table->boot_code, 0, sizeof(table->boot_code));
|
||||
memcpy (table->boot_code, MBR_BOOT_CODE, sizeof(MBR_BOOT_CODE));
|
||||
}
|
||||
|
||||
memset (table->partitions, 0, sizeof (table->partitions));
|
||||
table->magic = PED_CPU_TO_LE16(PC9800_EXTFMT_MAGIC);
|
||||
|
||||
for (i = 1; i <= MAX_PART_COUNT; i++) {
|
||||
part = ped_disk_get_partition (disk, i);
|
||||
if (!part)
|
||||
continue;
|
||||
|
||||
if (!fill_raw_part (&table->partitions [i - 1], part))
|
||||
return 0;
|
||||
}
|
||||
|
||||
int write_ok = ped_device_write (disk->dev, table, 0, 2);
|
||||
free (s0);
|
||||
if (!write_ok)
|
||||
return 0;
|
||||
return ped_device_sync (disk->dev);
|
||||
}
|
||||
#endif /* !DISCOVER_ONLY */
|
||||
|
||||
static PedPartition*
|
||||
pc98_partition_new (
|
||||
const PedDisk* disk, PedPartitionType part_type,
|
||||
const PedFileSystemType* fs_type, PedSector start, PedSector end)
|
||||
{
|
||||
PedPartition* part;
|
||||
PC98PartitionData* pc98_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
|
||||
= pc98_data = ped_malloc (sizeof (PC98PartitionData));
|
||||
if (!pc98_data)
|
||||
goto error_free_part;
|
||||
pc98_data->ipl_sector = 0;
|
||||
pc98_data->hidden = 0;
|
||||
pc98_data->boot = 0;
|
||||
strcpy (pc98_data->name, "");
|
||||
} else {
|
||||
part->disk_specific = NULL;
|
||||
}
|
||||
return part;
|
||||
|
||||
error_free_part:
|
||||
free (part);
|
||||
error:
|
||||
return 0;
|
||||
}
|
||||
|
||||
static PedPartition*
|
||||
pc98_partition_duplicate (const PedPartition* part)
|
||||
{
|
||||
PedPartition* new_part;
|
||||
PC98PartitionData* new_pc98_data;
|
||||
PC98PartitionData* old_pc98_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_pc98_data = (PC98PartitionData*) part->disk_specific;
|
||||
new_pc98_data = (PC98PartitionData*) new_part->disk_specific;
|
||||
|
||||
/* ugly, but C is ugly :p */
|
||||
memcpy (new_pc98_data, old_pc98_data, sizeof (PC98PartitionData));
|
||||
return new_part;
|
||||
}
|
||||
|
||||
static void
|
||||
pc98_partition_destroy (PedPartition* part)
|
||||
{
|
||||
PED_ASSERT (part != NULL);
|
||||
|
||||
if (ped_partition_is_active (part))
|
||||
free (part->disk_specific);
|
||||
free (part);
|
||||
}
|
||||
|
||||
static int
|
||||
pc98_partition_set_system (PedPartition* part, const PedFileSystemType* fs_type)
|
||||
{
|
||||
PC98PartitionData* pc98_data = part->disk_specific;
|
||||
|
||||
part->fs_type = fs_type;
|
||||
|
||||
pc98_data->system = 0x2062;
|
||||
if (fs_type) {
|
||||
if (!strcmp (fs_type->name, "fat16")) {
|
||||
if (part->geom.length * 512 >= 32 * 1024 * 1024)
|
||||
pc98_data->system = 0x2021;
|
||||
else
|
||||
pc98_data->system = 0x2011;
|
||||
} else if (!strcmp (fs_type->name, "fat32")) {
|
||||
pc98_data->system = 0x2061;
|
||||
} else if (!strcmp (fs_type->name, "ntfs")) {
|
||||
pc98_data->system = 0x2031;
|
||||
} else if (!strncmp (fs_type->name, "ufs", 3)) {
|
||||
pc98_data->system = 0x2044;
|
||||
} else { /* ext2, reiser, xfs, etc. */
|
||||
/* ext2 partitions must be marked boot */
|
||||
pc98_data->boot = 1;
|
||||
pc98_data->system = 0xa062;
|
||||
}
|
||||
}
|
||||
|
||||
if (pc98_data->boot)
|
||||
pc98_data->system |= 0x8000;
|
||||
if (!pc98_data->hidden)
|
||||
pc98_data->system |= 0x0080;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int
|
||||
pc98_partition_set_flag (PedPartition* part, PedPartitionFlag flag, int state)
|
||||
{
|
||||
PC98PartitionData* pc98_data;
|
||||
|
||||
PED_ASSERT (part != NULL);
|
||||
PED_ASSERT (part->disk_specific != NULL);
|
||||
|
||||
pc98_data = part->disk_specific;
|
||||
|
||||
switch (flag) {
|
||||
case PED_PARTITION_HIDDEN:
|
||||
pc98_data->hidden = state;
|
||||
return ped_partition_set_system (part, part->fs_type);
|
||||
|
||||
case PED_PARTITION_BOOT:
|
||||
pc98_data->boot = state;
|
||||
return ped_partition_set_system (part, part->fs_type);
|
||||
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
static int _GL_ATTRIBUTE_PURE
|
||||
pc98_partition_get_flag (const PedPartition* part, PedPartitionFlag flag)
|
||||
{
|
||||
PC98PartitionData* pc98_data;
|
||||
|
||||
PED_ASSERT (part != NULL);
|
||||
PED_ASSERT (part->disk_specific != NULL);
|
||||
|
||||
pc98_data = part->disk_specific;
|
||||
switch (flag) {
|
||||
case PED_PARTITION_HIDDEN:
|
||||
return pc98_data->hidden;
|
||||
|
||||
case PED_PARTITION_BOOT:
|
||||
return pc98_data->boot;
|
||||
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
pc98_partition_is_flag_available (
|
||||
const PedPartition* part, PedPartitionFlag flag)
|
||||
{
|
||||
switch (flag) {
|
||||
case PED_PARTITION_HIDDEN:
|
||||
case PED_PARTITION_BOOT:
|
||||
return 1;
|
||||
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
pc98_partition_set_name (PedPartition* part, const char* name)
|
||||
{
|
||||
PC98PartitionData* pc98_data;
|
||||
int i;
|
||||
|
||||
PED_ASSERT (part != NULL);
|
||||
PED_ASSERT (part->disk_specific != NULL);
|
||||
pc98_data = part->disk_specific;
|
||||
|
||||
strncpy (pc98_data->name, name, 16);
|
||||
pc98_data->name [16] = 0;
|
||||
for (i = strlen (pc98_data->name) - 1; pc98_data->name[i] == ' '; i--)
|
||||
pc98_data->name [i] = 0;
|
||||
}
|
||||
|
||||
static const char* _GL_ATTRIBUTE_PURE
|
||||
pc98_partition_get_name (const PedPartition* part)
|
||||
{
|
||||
PC98PartitionData* pc98_data;
|
||||
|
||||
PED_ASSERT (part != NULL);
|
||||
PED_ASSERT (part->disk_specific != NULL);
|
||||
pc98_data = part->disk_specific;
|
||||
|
||||
return pc98_data->name;
|
||||
}
|
||||
|
||||
static PedAlignment*
|
||||
pc98_get_partition_alignment(const PedDisk *disk)
|
||||
{
|
||||
PedSector cylinder_size =
|
||||
disk->dev->hw_geom.sectors * disk->dev->hw_geom.heads;
|
||||
|
||||
return ped_alignment_new(0, cylinder_size);
|
||||
}
|
||||
|
||||
static PedConstraint*
|
||||
_primary_constraint (PedDisk* disk)
|
||||
{
|
||||
PedDevice* dev = disk->dev;
|
||||
PedAlignment start_align;
|
||||
PedAlignment end_align;
|
||||
PedGeometry max_geom;
|
||||
PedSector cylinder_size;
|
||||
|
||||
cylinder_size = dev->hw_geom.sectors * dev->hw_geom.heads;
|
||||
|
||||
if (!ped_alignment_init (&start_align, 0, cylinder_size))
|
||||
return NULL;
|
||||
if (!ped_alignment_init (&end_align, -1, cylinder_size))
|
||||
return NULL;
|
||||
if (!ped_geometry_init (&max_geom, dev, cylinder_size,
|
||||
dev->length - cylinder_size))
|
||||
return NULL;
|
||||
|
||||
return ped_constraint_new (&start_align, &end_align, &max_geom,
|
||||
&max_geom, 1, dev->length);
|
||||
}
|
||||
|
||||
static int
|
||||
pc98_partition_align (PedPartition* part, const PedConstraint* constraint)
|
||||
{
|
||||
PED_ASSERT (part != NULL);
|
||||
|
||||
if (_ped_partition_attempt_align (part, constraint,
|
||||
_primary_constraint (part->disk)))
|
||||
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
|
||||
next_primary (PedDisk* disk)
|
||||
{
|
||||
int i;
|
||||
for (i=1; i<=MAX_PART_COUNT; i++) {
|
||||
if (!ped_disk_get_partition (disk, i))
|
||||
return i;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
pc98_partition_enumerate (PedPartition* part)
|
||||
{
|
||||
PED_ASSERT (part != NULL);
|
||||
PED_ASSERT (part->disk != NULL);
|
||||
|
||||
/* don't re-number a partition */
|
||||
if (part->num != -1)
|
||||
return 1;
|
||||
|
||||
PED_ASSERT (ped_partition_is_active (part));
|
||||
|
||||
part->num = next_primary (part->disk);
|
||||
if (!part->num) {
|
||||
ped_exception_throw (PED_EXCEPTION_ERROR,
|
||||
PED_EXCEPTION_CANCEL,
|
||||
_("Can't add another partition."));
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int
|
||||
pc98_alloc_metadata (PedDisk* disk)
|
||||
{
|
||||
PedPartition* new_part;
|
||||
PedConstraint* constraint_any = NULL;
|
||||
PedSector cyl_size;
|
||||
|
||||
PED_ASSERT (disk != NULL);
|
||||
PED_ASSERT (disk->dev != NULL);
|
||||
|
||||
constraint_any = ped_constraint_any (disk->dev);
|
||||
|
||||
cyl_size = disk->dev->hw_geom.sectors * disk->dev->hw_geom.heads;
|
||||
new_part = ped_partition_new (disk, PED_PARTITION_METADATA, NULL,
|
||||
0, cyl_size - 1);
|
||||
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;
|
||||
}
|
||||
|
||||
static int
|
||||
pc98_get_max_primary_partition_count (const PedDisk* disk)
|
||||
{
|
||||
return MAX_PART_COUNT;
|
||||
}
|
||||
|
||||
static bool
|
||||
pc98_get_max_supported_partition_count (const PedDisk* disk, int *max_n)
|
||||
{
|
||||
*max_n = MAX_PART_COUNT;
|
||||
return true;
|
||||
}
|
||||
|
||||
#include "pt-common.h"
|
||||
PT_define_limit_functions (pc98)
|
||||
|
||||
static PedDiskOps pc98_disk_ops = {
|
||||
clobber: NULL,
|
||||
write: NULL_IF_DISCOVER_ONLY (pc98_write),
|
||||
|
||||
partition_set_name: pc98_partition_set_name,
|
||||
partition_get_name: pc98_partition_get_name,
|
||||
|
||||
get_partition_alignment: pc98_get_partition_alignment,
|
||||
|
||||
PT_op_function_initializers (pc98)
|
||||
};
|
||||
|
||||
static PedDiskType pc98_disk_type = {
|
||||
next: NULL,
|
||||
name: "pc98",
|
||||
ops: &pc98_disk_ops,
|
||||
features: PED_DISK_TYPE_PARTITION_NAME
|
||||
};
|
||||
|
||||
void
|
||||
ped_disk_pc98_init ()
|
||||
{
|
||||
PED_ASSERT (sizeof (PC98RawTable) == 512 * 2);
|
||||
ped_disk_type_register (&pc98_disk_type);
|
||||
}
|
||||
|
||||
void
|
||||
ped_disk_pc98_done ()
|
||||
{
|
||||
ped_disk_type_unregister (&pc98_disk_type);
|
||||
}
|
||||
55
jni/parted/libparted/labels/pt-common.h
Executable file
55
jni/parted/libparted/labels/pt-common.h
Executable file
@@ -0,0 +1,55 @@
|
||||
/* Factor some of the duplication out of *.c. */
|
||||
|
||||
#ifdef DISCOVER_ONLY
|
||||
# define NULL_IF_DISCOVER_ONLY(val) NULL
|
||||
#else
|
||||
# define NULL_IF_DISCOVER_ONLY(val) val
|
||||
#endif
|
||||
|
||||
#define PT_define_limit_functions(PT_type) \
|
||||
\
|
||||
static bool \
|
||||
PT_type##_partition_check (const PedPartition *part) \
|
||||
{ \
|
||||
return ptt_partition_max_start_len (#PT_type, part); \
|
||||
} \
|
||||
\
|
||||
static PedSector \
|
||||
PT_type##_partition_max_start_sector (void) \
|
||||
{ \
|
||||
PedSector max; \
|
||||
int err = ptt_partition_max_start_sector (#PT_type, &max); \
|
||||
PED_ASSERT (err == 0); \
|
||||
return max; \
|
||||
} \
|
||||
\
|
||||
static PedSector \
|
||||
PT_type##_partition_max_length (void) \
|
||||
{ \
|
||||
PedSector max; \
|
||||
int err = ptt_partition_max_length (#PT_type, &max); \
|
||||
PED_ASSERT (err == 0); \
|
||||
return max; \
|
||||
}
|
||||
|
||||
#define PT_op_function_initializers(PT_type) \
|
||||
probe: PT_type##_probe, \
|
||||
alloc: PT_type##_alloc, \
|
||||
duplicate: PT_type##_duplicate, \
|
||||
free: PT_type##_free, \
|
||||
read: PT_type##_read, \
|
||||
partition_new: PT_type##_partition_new, \
|
||||
partition_duplicate: PT_type##_partition_duplicate, \
|
||||
partition_set_flag: PT_type##_partition_set_flag, \
|
||||
partition_get_flag: PT_type##_partition_get_flag, \
|
||||
partition_set_system: PT_type##_partition_set_system, \
|
||||
partition_is_flag_available: PT_type##_partition_is_flag_available, \
|
||||
partition_align: PT_type##_partition_align, \
|
||||
partition_destroy: PT_type##_partition_destroy, \
|
||||
partition_enumerate: PT_type##_partition_enumerate, \
|
||||
alloc_metadata: PT_type##_alloc_metadata, \
|
||||
get_max_primary_partition_count: PT_type##_get_max_primary_partition_count, \
|
||||
get_max_supported_partition_count:PT_type##_get_max_supported_partition_count,\
|
||||
partition_check: PT_type##_partition_check, \
|
||||
max_length: PT_type##_partition_max_length, \
|
||||
max_start_sector: PT_type##_partition_max_start_sector
|
||||
163
jni/parted/libparted/labels/pt-limit.c
Executable file
163
jni/parted/libparted/labels/pt-limit.c
Executable file
@@ -0,0 +1,163 @@
|
||||
/* ANSI-C code produced by gperf version 3.1 */
|
||||
/* Command-line: /data/data/com.termux/files/usr/bin/gperf -C -N pt_limit_lookup -n -t -s 6 -k '*' --language=ANSI-C pt-limit.gperf */
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
#if !((' ' == 32) && ('!' == 33) && ('"' == 34) && ('#' == 35) \
|
||||
&& ('%' == 37) && ('&' == 38) && ('\'' == 39) && ('(' == 40) \
|
||||
&& (')' == 41) && ('*' == 42) && ('+' == 43) && (',' == 44) \
|
||||
&& ('-' == 45) && ('.' == 46) && ('/' == 47) && ('0' == 48) \
|
||||
&& ('1' == 49) && ('2' == 50) && ('3' == 51) && ('4' == 52) \
|
||||
&& ('5' == 53) && ('6' == 54) && ('7' == 55) && ('8' == 56) \
|
||||
&& ('9' == 57) && (':' == 58) && (';' == 59) && ('<' == 60) \
|
||||
&& ('=' == 61) && ('>' == 62) && ('?' == 63) && ('A' == 65) \
|
||||
&& ('B' == 66) && ('C' == 67) && ('D' == 68) && ('E' == 69) \
|
||||
&& ('F' == 70) && ('G' == 71) && ('H' == 72) && ('I' == 73) \
|
||||
&& ('J' == 74) && ('K' == 75) && ('L' == 76) && ('M' == 77) \
|
||||
&& ('N' == 78) && ('O' == 79) && ('P' == 80) && ('Q' == 81) \
|
||||
&& ('R' == 82) && ('S' == 83) && ('T' == 84) && ('U' == 85) \
|
||||
&& ('V' == 86) && ('W' == 87) && ('X' == 88) && ('Y' == 89) \
|
||||
&& ('Z' == 90) && ('[' == 91) && ('\\' == 92) && (']' == 93) \
|
||||
&& ('^' == 94) && ('_' == 95) && ('a' == 97) && ('b' == 98) \
|
||||
&& ('c' == 99) && ('d' == 100) && ('e' == 101) && ('f' == 102) \
|
||||
&& ('g' == 103) && ('h' == 104) && ('i' == 105) && ('j' == 106) \
|
||||
&& ('k' == 107) && ('l' == 108) && ('m' == 109) && ('n' == 110) \
|
||||
&& ('o' == 111) && ('p' == 112) && ('q' == 113) && ('r' == 114) \
|
||||
&& ('s' == 115) && ('t' == 116) && ('u' == 117) && ('v' == 118) \
|
||||
&& ('w' == 119) && ('x' == 120) && ('y' == 121) && ('z' == 122) \
|
||||
&& ('{' == 123) && ('|' == 124) && ('}' == 125) && ('~' == 126))
|
||||
/* The character set is not based on ISO-646. */
|
||||
#error "gperf generated tables don't work with this execution character set. Please report a bug to <bug-gperf@gnu.org>."
|
||||
#endif
|
||||
|
||||
#line 1 "pt-limit.gperf"
|
||||
struct partition_limit
|
||||
{
|
||||
char const *name;
|
||||
uint64_t max_start_sector;
|
||||
uint64_t max_length;
|
||||
};
|
||||
|
||||
#define TOTAL_KEYWORDS 11
|
||||
#define MIN_WORD_LENGTH 3
|
||||
#define MAX_WORD_LENGTH 5
|
||||
#define MIN_HASH_VALUE 5
|
||||
#define MAX_HASH_VALUE 55
|
||||
/* maximum key range = 51, duplicates = 0 */
|
||||
|
||||
#ifdef __GNUC__
|
||||
__inline
|
||||
#else
|
||||
#ifdef __cplusplus
|
||||
inline
|
||||
#endif
|
||||
#endif
|
||||
static unsigned int
|
||||
hash (register const char *str, register size_t len)
|
||||
{
|
||||
static const unsigned char asso_values[] =
|
||||
{
|
||||
56, 56, 56, 56, 56, 56, 56, 56, 56, 56,
|
||||
56, 56, 56, 56, 56, 56, 56, 56, 56, 56,
|
||||
56, 56, 56, 56, 56, 56, 56, 56, 56, 56,
|
||||
56, 56, 56, 56, 56, 56, 56, 56, 56, 56,
|
||||
56, 56, 56, 56, 56, 56, 56, 56, 56, 56,
|
||||
56, 56, 56, 56, 56, 56, 10, 5, 56, 56,
|
||||
56, 56, 56, 56, 56, 56, 56, 56, 56, 56,
|
||||
56, 56, 56, 56, 56, 56, 56, 56, 56, 56,
|
||||
56, 56, 56, 56, 56, 56, 56, 56, 56, 56,
|
||||
56, 56, 56, 56, 56, 56, 56, 5, 40, 40,
|
||||
5, 56, 56, 5, 20, 0, 56, 56, 15, 0,
|
||||
15, 10, 0, 56, 0, 5, 0, 10, 15, 56,
|
||||
56, 56, 56, 56, 56, 56, 56, 56, 56, 56,
|
||||
56, 56, 56, 56, 56, 56, 56, 56, 56, 56,
|
||||
56, 56, 56, 56, 56, 56, 56, 56, 56, 56,
|
||||
56, 56, 56, 56, 56, 56, 56, 56, 56, 56,
|
||||
56, 56, 56, 56, 56, 56, 56, 56, 56, 56,
|
||||
56, 56, 56, 56, 56, 56, 56, 56, 56, 56,
|
||||
56, 56, 56, 56, 56, 56, 56, 56, 56, 56,
|
||||
56, 56, 56, 56, 56, 56, 56, 56, 56, 56,
|
||||
56, 56, 56, 56, 56, 56, 56, 56, 56, 56,
|
||||
56, 56, 56, 56, 56, 56, 56, 56, 56, 56,
|
||||
56, 56, 56, 56, 56, 56, 56, 56, 56, 56,
|
||||
56, 56, 56, 56, 56, 56, 56, 56, 56, 56,
|
||||
56, 56, 56, 56, 56, 56, 56, 56, 56, 56,
|
||||
56, 56, 56, 56, 56, 56
|
||||
};
|
||||
register unsigned int hval = 0;
|
||||
|
||||
switch (len)
|
||||
{
|
||||
default:
|
||||
hval += asso_values[(unsigned char)str[4]];
|
||||
/*FALLTHROUGH*/
|
||||
case 4:
|
||||
hval += asso_values[(unsigned char)str[3]];
|
||||
/*FALLTHROUGH*/
|
||||
case 3:
|
||||
hval += asso_values[(unsigned char)str[2]];
|
||||
/*FALLTHROUGH*/
|
||||
case 2:
|
||||
hval += asso_values[(unsigned char)str[1]];
|
||||
/*FALLTHROUGH*/
|
||||
case 1:
|
||||
hval += asso_values[(unsigned char)str[0]];
|
||||
break;
|
||||
}
|
||||
return hval;
|
||||
}
|
||||
|
||||
const struct partition_limit *
|
||||
pt_limit_lookup (register const char *str, register size_t len)
|
||||
{
|
||||
static const struct partition_limit wordlist[] =
|
||||
{
|
||||
{""}, {""}, {""}, {""}, {""},
|
||||
#line 10 "pt-limit.gperf"
|
||||
{"gpt",UINT64_MAX,UINT64_MAX},
|
||||
{""}, {""}, {""}, {""},
|
||||
#line 28 "pt-limit.gperf"
|
||||
{"atari",INT32_MAX,INT32_MAX},
|
||||
{""}, {""}, {""}, {""},
|
||||
#line 27 "pt-limit.gperf"
|
||||
{"amiga",UINT32_MAX,UINT32_MAX},
|
||||
{""}, {""}, {""}, {""},
|
||||
#line 8 "pt-limit.gperf"
|
||||
{"dasd",UINT32_MAX,UINT32_MAX},
|
||||
{""}, {""}, {""}, {""},
|
||||
#line 12 "pt-limit.gperf"
|
||||
{"msdos",UINT32_MAX,UINT32_MAX},
|
||||
{""}, {""}, {""}, {""},
|
||||
#line 18 "pt-limit.gperf"
|
||||
{"sun",128ULL*UINT32_MAX,UINT32_MAX},
|
||||
{""}, {""}, {""}, {""},
|
||||
#line 23 "pt-limit.gperf"
|
||||
{"loop",UINT64_MAX,UINT64_MAX},
|
||||
{""}, {""}, {""}, {""},
|
||||
#line 9 "pt-limit.gperf"
|
||||
{"dvh",UINT32_MAX,UINT32_MAX},
|
||||
{""}, {""}, {""}, {""},
|
||||
#line 11 "pt-limit.gperf"
|
||||
{"mac",UINT32_MAX,UINT32_MAX},
|
||||
{""}, {""}, {""}, {""},
|
||||
#line 20 "pt-limit.gperf"
|
||||
{"bsd",UINT32_MAX,UINT32_MAX},
|
||||
{""}, {""}, {""}, {""},
|
||||
#line 24 "pt-limit.gperf"
|
||||
{"pc98",UINT32_MAX,UINT32_MAX}
|
||||
};
|
||||
|
||||
if (len <= MAX_WORD_LENGTH && len >= MIN_WORD_LENGTH)
|
||||
{
|
||||
register unsigned int key = hash (str, len);
|
||||
|
||||
if (key <= MAX_HASH_VALUE)
|
||||
{
|
||||
register const char *s = wordlist[key].name;
|
||||
|
||||
if (*str == *s && !strcmp (str + 1, s + 1))
|
||||
return &wordlist[key];
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
186
jni/parted/libparted/labels/pt-tools.c
Executable file
186
jni/parted/libparted/labels/pt-tools.c
Executable file
@@ -0,0 +1,186 @@
|
||||
/* partition table tools
|
||||
Copyright (C) 2008-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/>. */
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <parted/parted.h>
|
||||
#include <parted/debug.h>
|
||||
|
||||
#include "pt-tools.h"
|
||||
|
||||
#if ENABLE_NLS
|
||||
# include <libintl.h>
|
||||
# define _(String) dgettext (PACKAGE, String)
|
||||
#else
|
||||
# define _(String) (String)
|
||||
#endif /* ENABLE_NLS */
|
||||
|
||||
static char zero[16 * 1024];
|
||||
|
||||
/* Write a single sector to DISK, filling the first BUFLEN
|
||||
bytes of that sector with data from BUF, and NUL-filling
|
||||
any remaining bytes. Return nonzero to indicate success,
|
||||
zero otherwise. */
|
||||
int
|
||||
ptt_write_sector (PedDisk const *disk, void const *buf, size_t buflen)
|
||||
{
|
||||
PED_ASSERT (buflen <= disk->dev->sector_size);
|
||||
/* Allocate a big enough buffer for ped_device_write. */
|
||||
char *s0 = ped_malloc (disk->dev->sector_size);
|
||||
if (s0 == NULL)
|
||||
return 0;
|
||||
/* Copy boot_code into the first part. */
|
||||
memcpy (s0, buf, buflen);
|
||||
char *p = s0 + buflen;
|
||||
/* Fill the rest with zeros. */
|
||||
memset (p, 0, disk->dev->sector_size - buflen);
|
||||
int write_ok = ped_device_write (disk->dev, s0, 0, 1);
|
||||
free (s0);
|
||||
|
||||
return write_ok;
|
||||
}
|
||||
|
||||
/* Read N sectors, starting with sector SECTOR_NUM (which has length
|
||||
DEV->sector_size) into malloc'd storage. If the read fails, free
|
||||
the memory and return zero without modifying *BUF. Otherwise, set
|
||||
*BUF to the new buffer and return 1. */
|
||||
int
|
||||
ptt_read_sectors (PedDevice const *dev, PedSector start_sector,
|
||||
PedSector n_sectors, void **buf)
|
||||
{
|
||||
char *b = ped_malloc (n_sectors * dev->sector_size);
|
||||
PED_ASSERT (b != NULL);
|
||||
if (!ped_device_read (dev, b, start_sector, n_sectors)) {
|
||||
free (b);
|
||||
return 0;
|
||||
}
|
||||
*buf = b;
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Read sector, SECTOR_NUM (which has length DEV->sector_size) into malloc'd
|
||||
storage. If the read fails, free the memory and return zero without
|
||||
modifying *BUF. Otherwise, set *BUF to the new buffer and return 1. */
|
||||
int
|
||||
ptt_read_sector (PedDevice const *dev, PedSector sector_num, void **buf)
|
||||
{
|
||||
return ptt_read_sectors (dev, sector_num, 1, buf);
|
||||
}
|
||||
|
||||
/* Zero N sectors of DEV, starting with START.
|
||||
Return nonzero to indicate success, zero otherwise. */
|
||||
int
|
||||
ptt_clear_sectors (PedDevice *dev, PedSector start, PedSector n)
|
||||
{
|
||||
PED_ASSERT (dev->sector_size <= sizeof zero);
|
||||
PedSector n_z_sectors = sizeof zero / dev->sector_size;
|
||||
PedSector n_full = n / n_z_sectors;
|
||||
PedSector i;
|
||||
for (i = 0; i < n_full; i++)
|
||||
{
|
||||
if (!ped_device_write (dev, zero, start + n_z_sectors * i, n_z_sectors))
|
||||
return 0;
|
||||
}
|
||||
|
||||
PedSector rem = n - n_z_sectors * i;
|
||||
return (rem == 0
|
||||
? 1 : ped_device_write (dev, zero, start + n_z_sectors * i, rem));
|
||||
}
|
||||
|
||||
/* Zero N sectors of GEOM->dev, starting with GEOM->start + START.
|
||||
Return nonzero to indicate success, zero otherwise. */
|
||||
int
|
||||
ptt_geom_clear_sectors (PedGeometry *geom, PedSector start, PedSector n)
|
||||
{
|
||||
return ptt_clear_sectors (geom->dev, geom->start + start, n);
|
||||
}
|
||||
|
||||
#define pt_limit_lookup _GL_ATTRIBUTE_PURE __pt_limit_lookup
|
||||
#include "pt-limit.c"
|
||||
|
||||
/* Throw an exception and return 0 if PART's starting sector number or
|
||||
its length is greater than the maximum allowed value for LABEL_TYPE.
|
||||
Otherwise, return 1. */
|
||||
int
|
||||
ptt_partition_max_start_len (char const *pt_type, const PedPartition *part)
|
||||
{
|
||||
struct partition_limit const *pt_lim
|
||||
= __pt_limit_lookup (pt_type, strlen (pt_type));
|
||||
|
||||
/* If we don't have info on the type, return "true". */
|
||||
if (pt_lim == NULL)
|
||||
return 1;
|
||||
|
||||
/* If the length in sectors exceeds the limit, you lose. */
|
||||
if (part->geom.length > pt_lim->max_length)
|
||||
{
|
||||
ped_exception_throw (PED_EXCEPTION_ERROR, PED_EXCEPTION_CANCEL,
|
||||
_("partition length of %jd sectors exceeds"
|
||||
" the %s-partition-table-imposed maximum"
|
||||
" of %jd"),
|
||||
part->geom.length,
|
||||
pt_type,
|
||||
pt_lim->max_length);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* If the starting sector exceeds the limit, you lose. */
|
||||
if (part->geom.start > pt_lim->max_start_sector) {
|
||||
ped_exception_throw (
|
||||
PED_EXCEPTION_ERROR, PED_EXCEPTION_CANCEL,
|
||||
_("starting sector number, %jd exceeds"
|
||||
" the %s-partition-table-imposed maximum"
|
||||
" of %jd"),
|
||||
part->geom.start,
|
||||
pt_type,
|
||||
pt_lim->max_start_sector);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Set *MAX to the largest representation-imposed starting sector number
|
||||
of a partition of type PT_TYPE and return 0. If PT_TYPE is not
|
||||
recognized, return -1. */
|
||||
int
|
||||
ptt_partition_max_start_sector (char const *pt_type, PedSector *max)
|
||||
{
|
||||
struct partition_limit const *pt_lim
|
||||
= __pt_limit_lookup (pt_type, strlen (pt_type));
|
||||
if (pt_lim == NULL)
|
||||
return -1;
|
||||
|
||||
*max = pt_lim->max_start_sector;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Set *MAX to the maximum representable length of a partition of type
|
||||
PT_TYPE and return 0. If PT_TYPE is not recognized, return -1. */
|
||||
int
|
||||
ptt_partition_max_length (char const *pt_type, PedSector *max)
|
||||
{
|
||||
struct partition_limit const *pt_lim
|
||||
= __pt_limit_lookup (pt_type, strlen (pt_type));
|
||||
if (pt_lim == NULL)
|
||||
return -1;
|
||||
|
||||
*max = pt_lim->max_length;
|
||||
return 0;
|
||||
}
|
||||
31
jni/parted/libparted/labels/pt-tools.h
Executable file
31
jni/parted/libparted/labels/pt-tools.h
Executable file
@@ -0,0 +1,31 @@
|
||||
/* libparted - a library for manipulating disk partitions
|
||||
Copyright (C) 2008-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/>. */
|
||||
|
||||
#include <stddef.h>
|
||||
#include <parted/disk.h>
|
||||
|
||||
int ptt_write_sector (PedDisk const *disk, void const *buf, size_t buflen);
|
||||
int ptt_read_sector (PedDevice const *dev, PedSector sector_num, void **buf);
|
||||
int ptt_read_sectors (PedDevice const *dev, PedSector start_sector,
|
||||
PedSector n_sectors, void **buf);
|
||||
int ptt_clear_sectors (PedDevice *dev, PedSector start, PedSector count);
|
||||
int ptt_geom_clear_sectors (PedGeometry *geom, PedSector start,
|
||||
PedSector count);
|
||||
int ptt_partition_max_start_len (char const *label_type,
|
||||
const PedPartition *part);
|
||||
|
||||
int ptt_partition_max_start_sector (char const *pt_type, PedSector *max);
|
||||
int ptt_partition_max_length (char const *pt_type, PedSector *max);
|
||||
1167
jni/parted/libparted/labels/rdb.c
Executable file
1167
jni/parted/libparted/labels/rdb.c
Executable file
File diff suppressed because it is too large
Load Diff
910
jni/parted/libparted/labels/sun.c
Executable file
910
jni/parted/libparted/labels/sun.c
Executable file
@@ -0,0 +1,910 @@
|
||||
/* -*- Mode: c; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
|
||||
|
||||
libparted - a library for manipulating disk partitions
|
||||
Copyright (C) 2000-2001, 2005, 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: Ben Collins <bcollins@debian.org>
|
||||
*/
|
||||
|
||||
#include <config.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"
|
||||
#include "verify.h"
|
||||
|
||||
/* Most of this came from util-linux's sun support, which was mostly done
|
||||
by Jakub Jelinek. */
|
||||
|
||||
#define SUN_DISK_MAGIC 0xDABE /* Disk magic number */
|
||||
#define SUN_DISK_MAXPARTITIONS 8
|
||||
|
||||
#define SUN_VTOC_VERSION 1
|
||||
#define SUN_VTOC_SANITY 0x600DDEEE
|
||||
|
||||
#define WHOLE_DISK_ID 0x05
|
||||
#define WHOLE_DISK_PART 2 /* as in 0, 1, 2 (3rd partition) */
|
||||
#define LINUX_SWAP_ID 0x82
|
||||
|
||||
typedef struct _SunRawPartition SunRawPartition;
|
||||
typedef struct _SunPartitionInfo SunPartitionInfo;
|
||||
typedef struct _SunRawLabel SunRawLabel;
|
||||
typedef struct _SunPartitionData SunPartitionData;
|
||||
typedef struct _SunDiskData SunDiskData;
|
||||
|
||||
struct __attribute__ ((packed)) _SunRawPartition {
|
||||
u_int32_t start_cylinder; /* where the part starts... */
|
||||
u_int32_t num_sectors; /* ...and it's length */
|
||||
};
|
||||
|
||||
struct __attribute__ ((packed)) _SunPartitionInfo {
|
||||
u_int8_t spare1;
|
||||
u_int8_t id; /* Partition type */
|
||||
u_int8_t spare2;
|
||||
u_int8_t flags; /* Partition flags */
|
||||
};
|
||||
|
||||
struct __attribute__ ((packed, aligned(2))) _SunRawLabel {
|
||||
char info[128]; /* Informative text string */
|
||||
u_int32_t version; /* Layout version */
|
||||
u_int8_t volume[8]; /* Volume name */
|
||||
u_int16_t nparts; /* Number of partitions */
|
||||
SunPartitionInfo infos[SUN_DISK_MAXPARTITIONS];
|
||||
u_int16_t padding; /* Alignment padding */
|
||||
u_int32_t bootinfo[3]; /* Info needed by mboot */
|
||||
u_int32_t sanity; /* To verify vtoc sanity */
|
||||
u_int32_t reserved[10]; /* Free space */
|
||||
u_int32_t timestamp[8]; /* Partition timestamp */
|
||||
u_int32_t write_reinstruct; /* sectors to skip, writes */
|
||||
u_int32_t read_reinstruct; /* sectors to skip, reads */
|
||||
u_int8_t spare1[148]; /* Padding */
|
||||
u_int16_t rspeed; /* Disk rotational speed */
|
||||
u_int16_t pcylcount; /* Physical cylinder count */
|
||||
u_int16_t sparecyl; /* extra sects per cylinder */
|
||||
u_int8_t spare2[4]; /* More magic... */
|
||||
u_int16_t ilfact; /* Interleave factor */
|
||||
u_int16_t ncyl; /* Data cylinder count */
|
||||
u_int16_t nacyl; /* Alt. cylinder count */
|
||||
u_int16_t ntrks; /* Tracks per cylinder */
|
||||
u_int16_t nsect; /* Sectors per track */
|
||||
u_int8_t spare3[4]; /* Even more magic... */
|
||||
SunRawPartition partitions[SUN_DISK_MAXPARTITIONS];
|
||||
u_int16_t magic; /* Magic number */
|
||||
u_int16_t csum; /* Label xor'd checksum */
|
||||
};
|
||||
|
||||
struct _SunPartitionData {
|
||||
u_int8_t type;
|
||||
int is_boot;
|
||||
int is_root;
|
||||
int is_lvm;
|
||||
int is_raid;
|
||||
};
|
||||
|
||||
struct _SunDiskData {
|
||||
PedSector length; /* This is based on cyl - alt-cyl */
|
||||
SunRawLabel raw_label;
|
||||
};
|
||||
|
||||
static PedDiskType sun_disk_type;
|
||||
|
||||
/* Checksum computation */
|
||||
static void
|
||||
sun_compute_checksum (SunRawLabel *label)
|
||||
{
|
||||
u_int16_t *ush = (u_int16_t *)label;
|
||||
u_int16_t csum = 0;
|
||||
|
||||
while(ush < (u_int16_t *)(&label->csum))
|
||||
csum ^= *ush++;
|
||||
label->csum = csum;
|
||||
}
|
||||
|
||||
/* Checksum Verification */
|
||||
static int
|
||||
sun_verify_checksum (SunRawLabel const *label)
|
||||
{
|
||||
u_int16_t *ush = ((u_int16_t *)(label + 1)) - 1;
|
||||
u_int16_t csum = 0;
|
||||
|
||||
while (ush >= (u_int16_t *)label)
|
||||
csum ^= *ush--;
|
||||
|
||||
return !csum;
|
||||
}
|
||||
|
||||
static int
|
||||
sun_probe (const PedDevice *dev)
|
||||
{
|
||||
PED_ASSERT (dev != NULL);
|
||||
|
||||
void *s0;
|
||||
if (!ptt_read_sector (dev, 0, &s0))
|
||||
return 0;
|
||||
SunRawLabel const *label = (void const *) s0;
|
||||
|
||||
int ok = 1;
|
||||
/* check magic */
|
||||
if (PED_BE16_TO_CPU (label->magic) != SUN_DISK_MAGIC) {
|
||||
ok = 0;
|
||||
} else {
|
||||
#ifndef DISCOVER_ONLY
|
||||
if (!sun_verify_checksum(label)) {
|
||||
ok = 0;
|
||||
ped_exception_throw (
|
||||
PED_EXCEPTION_ERROR,
|
||||
PED_EXCEPTION_CANCEL,
|
||||
_("Corrupted Sun disk label detected."));
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
free (s0);
|
||||
return ok;
|
||||
}
|
||||
|
||||
static PedDisk*
|
||||
sun_alloc (const PedDevice* dev)
|
||||
{
|
||||
PedDisk* disk;
|
||||
SunRawLabel* label;
|
||||
SunDiskData* sun_specific;
|
||||
const PedCHSGeometry* bios_geom = &dev->bios_geom;
|
||||
PedSector cyl_size = bios_geom->sectors * bios_geom->heads;
|
||||
PED_ASSERT (cyl_size != 0);
|
||||
|
||||
disk = _ped_disk_alloc (dev, &sun_disk_type);
|
||||
if (!disk)
|
||||
goto error;
|
||||
|
||||
disk->disk_specific = (SunDiskData*) ped_malloc (sizeof (SunDiskData));
|
||||
if (!disk->disk_specific)
|
||||
goto error_free_disk;
|
||||
sun_specific = (SunDiskData*) disk->disk_specific;
|
||||
|
||||
PED_ASSERT (bios_geom->cylinders == (PedSector) (dev->length / cyl_size));
|
||||
sun_specific->length = ped_round_down_to (dev->length, cyl_size);
|
||||
|
||||
label = &sun_specific->raw_label;
|
||||
memset(label, 0, sizeof(SunRawLabel));
|
||||
|
||||
/* #gentoo-sparc people agree that nacyl = 0 is the best option */
|
||||
label->magic = PED_CPU_TO_BE16 (SUN_DISK_MAGIC);
|
||||
label->nacyl = 0;
|
||||
label->pcylcount = PED_CPU_TO_BE16 (bios_geom->cylinders);
|
||||
label->rspeed = PED_CPU_TO_BE16 (5400);
|
||||
label->ilfact = PED_CPU_TO_BE16 (1);
|
||||
label->sparecyl = 0;
|
||||
label->ntrks = PED_CPU_TO_BE16 (bios_geom->heads);
|
||||
label->nsect = PED_CPU_TO_BE16 (bios_geom->sectors);
|
||||
label->ncyl = PED_CPU_TO_BE16 (dev->length / cyl_size);
|
||||
|
||||
label->sanity = PED_CPU_TO_BE32 (SUN_VTOC_SANITY);
|
||||
label->version = PED_CPU_TO_BE32 (SUN_VTOC_VERSION);
|
||||
label->nparts = PED_CPU_TO_BE16 (SUN_DISK_MAXPARTITIONS);
|
||||
|
||||
/* Add a whole disk partition at a minimum */
|
||||
label->infos[WHOLE_DISK_PART].id = WHOLE_DISK_ID;
|
||||
label->partitions[WHOLE_DISK_PART].start_cylinder = 0;
|
||||
label->partitions[WHOLE_DISK_PART].num_sectors =
|
||||
PED_CPU_TO_BE32(sun_specific->length);
|
||||
|
||||
/* Now a neato string to describe this label */
|
||||
snprintf(label->info, sizeof(label->info) - 1,
|
||||
"GNU Parted Custom cyl %d alt %d hd %d sec %d",
|
||||
PED_BE16_TO_CPU(label->ncyl),
|
||||
PED_BE16_TO_CPU(label->nacyl),
|
||||
PED_BE16_TO_CPU(label->ntrks),
|
||||
PED_BE16_TO_CPU(label->nsect));
|
||||
|
||||
sun_compute_checksum(label);
|
||||
return disk;
|
||||
|
||||
error_free_disk:
|
||||
_ped_disk_free (disk);
|
||||
error:
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static PedDisk*
|
||||
sun_duplicate (const PedDisk* disk)
|
||||
{
|
||||
PedDisk* new_disk;
|
||||
SunDiskData* new_sun_data;
|
||||
SunDiskData* old_sun_data = (SunDiskData*) disk->disk_specific;
|
||||
|
||||
new_disk = ped_disk_new_fresh (disk->dev, &sun_disk_type);
|
||||
if (!new_disk)
|
||||
return NULL;
|
||||
|
||||
new_sun_data = (SunDiskData*) new_disk->disk_specific;
|
||||
memcpy (new_sun_data, old_sun_data, sizeof (SunDiskData));
|
||||
return new_disk;
|
||||
}
|
||||
|
||||
static void
|
||||
sun_free (PedDisk *disk)
|
||||
{
|
||||
free (disk->disk_specific);
|
||||
_ped_disk_free (disk);
|
||||
}
|
||||
|
||||
static int
|
||||
_check_geometry_sanity (PedDisk* disk, SunRawLabel* label)
|
||||
{
|
||||
PedDevice* dev = disk->dev;
|
||||
|
||||
if (PED_BE16_TO_CPU(label->nsect) == dev->hw_geom.sectors &&
|
||||
PED_BE16_TO_CPU(label->ntrks) == dev->hw_geom.heads)
|
||||
dev->bios_geom = dev->hw_geom;
|
||||
|
||||
if (!!PED_BE16_TO_CPU(label->pcylcount)
|
||||
* !!PED_BE16_TO_CPU(label->ntrks)
|
||||
* !!PED_BE16_TO_CPU(label->nsect) == 0)
|
||||
return 0;
|
||||
|
||||
if (PED_BE16_TO_CPU(label->nsect) != dev->bios_geom.sectors ||
|
||||
PED_BE16_TO_CPU(label->ntrks) != dev->bios_geom.heads) {
|
||||
#ifndef DISCOVER_ONLY
|
||||
if (ped_exception_throw (
|
||||
PED_EXCEPTION_WARNING,
|
||||
PED_EXCEPTION_IGNORE_CANCEL,
|
||||
_("The disk CHS geometry (%d,%d,%d) reported "
|
||||
"by the operating system does not match "
|
||||
"the geometry stored on the disk label "
|
||||
"(%d,%d,%d)."),
|
||||
dev->bios_geom.cylinders,
|
||||
dev->bios_geom.heads,
|
||||
dev->bios_geom.sectors,
|
||||
PED_BE16_TO_CPU(label->pcylcount),
|
||||
PED_BE16_TO_CPU(label->ntrks),
|
||||
PED_BE16_TO_CPU(label->nsect))
|
||||
== PED_EXCEPTION_CANCEL)
|
||||
return 0;
|
||||
#endif
|
||||
dev->bios_geom.sectors = PED_BE16_TO_CPU(label->nsect);
|
||||
dev->bios_geom.heads = PED_BE16_TO_CPU(label->ntrks);
|
||||
dev->bios_geom.cylinders = PED_BE16_TO_CPU(label->pcylcount);
|
||||
|
||||
if (dev->bios_geom.sectors * dev->bios_geom.heads
|
||||
* dev->bios_geom.cylinders > dev->length) {
|
||||
if (ped_exception_throw (
|
||||
PED_EXCEPTION_WARNING,
|
||||
PED_EXCEPTION_IGNORE_CANCEL,
|
||||
_("The disk label describes a disk bigger than "
|
||||
"%s."),
|
||||
dev->path)
|
||||
!= PED_EXCEPTION_IGNORE)
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int
|
||||
sun_read (PedDisk* disk)
|
||||
{
|
||||
SunPartitionData* sun_data;
|
||||
SunDiskData* disk_data;
|
||||
int i;
|
||||
PedPartition* part;
|
||||
PedSector end, start, block;
|
||||
|
||||
PED_ASSERT (disk != NULL);
|
||||
PED_ASSERT (disk->dev != NULL);
|
||||
PED_ASSERT (disk->disk_specific != NULL);
|
||||
|
||||
disk_data = (SunDiskData*) disk->disk_specific;
|
||||
|
||||
ped_disk_delete_all (disk);
|
||||
|
||||
void *s0;
|
||||
if (!ptt_read_sector (disk->dev, 0, &s0))
|
||||
goto error;
|
||||
|
||||
SunRawLabel *label = &disk_data->raw_label;
|
||||
verify (sizeof (*label) == 512);
|
||||
memcpy (label, s0, sizeof (*label));
|
||||
free (s0);
|
||||
|
||||
if (!_check_geometry_sanity (disk, label))
|
||||
goto error;
|
||||
|
||||
block = disk->dev->bios_geom.sectors * disk->dev->bios_geom.heads;
|
||||
disk_data->length = block * disk->dev->bios_geom.cylinders;
|
||||
|
||||
for (i = 0; i < SUN_DISK_MAXPARTITIONS; i++) {
|
||||
if (!PED_BE32_TO_CPU(label->partitions[i].num_sectors))
|
||||
continue;
|
||||
if (!label->infos[i].id)
|
||||
continue;
|
||||
if (label->infos[i].id == WHOLE_DISK_ID)
|
||||
continue;
|
||||
|
||||
start = PED_BE32_TO_CPU(label->partitions[i].start_cylinder)
|
||||
* block;
|
||||
end = start
|
||||
+ PED_BE32_TO_CPU(label->partitions[i].num_sectors) - 1;
|
||||
|
||||
part = ped_partition_new (disk, PED_PARTITION_NORMAL, NULL,
|
||||
start, end);
|
||||
if (!part)
|
||||
goto error;
|
||||
|
||||
sun_data = part->disk_specific;
|
||||
sun_data->type = label->infos[i].id;
|
||||
sun_data->is_boot = sun_data->type == 0x1;
|
||||
sun_data->is_root = sun_data->type == 0x2;
|
||||
sun_data->is_lvm = sun_data->type == 0x8e;
|
||||
sun_data->is_raid = sun_data->type == 0xfd;
|
||||
|
||||
part->num = i + 1;
|
||||
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;
|
||||
}
|
||||
|
||||
#ifndef DISCOVER_ONLY
|
||||
static int
|
||||
_use_old_info (const PedDisk* disk, const void *sector_0)
|
||||
{
|
||||
SunRawLabel const *old_label = sector_0;
|
||||
|
||||
if (old_label->info[0]
|
||||
&& PED_BE16_TO_CPU (old_label->magic) == SUN_DISK_MAGIC) {
|
||||
SunDiskData *sun_specific = disk->disk_specific;
|
||||
memcpy (&sun_specific->raw_label, sector_0,
|
||||
sizeof (sun_specific->raw_label));
|
||||
verify (sizeof (sun_specific->raw_label) == 512);
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int
|
||||
sun_write (const PedDisk* disk)
|
||||
{
|
||||
SunRawLabel* label;
|
||||
SunPartitionData* sun_data;
|
||||
SunDiskData* disk_data;
|
||||
PedPartition* part;
|
||||
int i;
|
||||
|
||||
PED_ASSERT (disk != NULL);
|
||||
PED_ASSERT (disk->dev != NULL);
|
||||
|
||||
void *s0;
|
||||
if (!ptt_read_sector (disk->dev, 0, &s0))
|
||||
return 0;
|
||||
|
||||
/* Calling _use_old_info here in sun_write
|
||||
above seems wrong, because it modifies *DISK.
|
||||
FIXME: maybe later. */
|
||||
if (!_use_old_info (disk, s0)) {
|
||||
free (s0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
disk_data = (SunDiskData*) disk->disk_specific;
|
||||
label = &disk_data->raw_label;
|
||||
|
||||
memset (label->partitions, 0,
|
||||
sizeof (SunRawPartition) * SUN_DISK_MAXPARTITIONS);
|
||||
memset (label->infos, 0,
|
||||
sizeof (SunPartitionInfo) * SUN_DISK_MAXPARTITIONS);
|
||||
|
||||
for (i = 0; i < SUN_DISK_MAXPARTITIONS; i++) {
|
||||
part = ped_disk_get_partition (disk, i + 1);
|
||||
|
||||
if (!part && i == WHOLE_DISK_PART) {
|
||||
/* Ok, nothing explicitly in the whole disk
|
||||
partition, so let's put it there for safety
|
||||
sake. */
|
||||
|
||||
label->infos[i].id = WHOLE_DISK_ID;
|
||||
label->partitions[i].start_cylinder = 0;
|
||||
label->partitions[i].num_sectors =
|
||||
PED_CPU_TO_BE32(disk_data->length);
|
||||
continue;
|
||||
}
|
||||
if (!part)
|
||||
continue;
|
||||
|
||||
sun_data = part->disk_specific;
|
||||
label->infos[i].id = sun_data->type;
|
||||
label->partitions[i].start_cylinder
|
||||
= PED_CPU_TO_BE32 (part->geom.start
|
||||
/ (disk->dev->bios_geom.sectors
|
||||
* disk->dev->bios_geom.heads));
|
||||
label->partitions[i].num_sectors
|
||||
= PED_CPU_TO_BE32 (part->geom.end
|
||||
- part->geom.start + 1);
|
||||
}
|
||||
|
||||
/* We assume the harddrive is always right, and that the label may
|
||||
be wrong. I don't think this will cause any problems, since the
|
||||
cylinder count is always enforced by our alignment, and we
|
||||
sanity checked the sectors/heads when we detected the device. The
|
||||
worst that could happen here is that the drive seems bigger or
|
||||
smaller than it really is, but we'll have that problem even if we
|
||||
don't do this. */
|
||||
|
||||
if (disk->dev->bios_geom.cylinders > 65536) {
|
||||
ped_exception_throw (
|
||||
PED_EXCEPTION_WARNING,
|
||||
PED_EXCEPTION_IGNORE,
|
||||
_("The disk has %d cylinders, which is greater than "
|
||||
"the maximum of 65536."),
|
||||
disk->dev->bios_geom.cylinders);
|
||||
}
|
||||
|
||||
label->pcylcount = PED_CPU_TO_BE16 (disk->dev->bios_geom.cylinders);
|
||||
label->ncyl = PED_CPU_TO_BE16 (disk->dev->bios_geom.cylinders
|
||||
- PED_BE16_TO_CPU (label->nacyl));
|
||||
|
||||
sun_compute_checksum (label);
|
||||
|
||||
verify (sizeof *label == 512);
|
||||
memcpy (s0, label, sizeof *label);
|
||||
int write_ok = ped_device_write (disk->dev, s0, 0, 1);
|
||||
free (s0);
|
||||
|
||||
if (write_ok)
|
||||
return ped_device_sync (disk->dev);
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif /* !DISCOVER_ONLY */
|
||||
|
||||
static PedPartition*
|
||||
sun_partition_new (const PedDisk* disk, PedPartitionType part_type,
|
||||
const PedFileSystemType* fs_type,
|
||||
PedSector start, PedSector end)
|
||||
{
|
||||
PedPartition* part;
|
||||
SunPartitionData* sun_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
|
||||
= sun_data = ped_malloc (sizeof (SunPartitionData));
|
||||
if (!sun_data)
|
||||
goto error_free_part;
|
||||
sun_data->type = 0;
|
||||
sun_data->is_boot = 0;
|
||||
sun_data->is_root = 0;
|
||||
sun_data->is_lvm = 0;
|
||||
sun_data->is_raid = 0;
|
||||
} else {
|
||||
part->disk_specific = NULL;
|
||||
}
|
||||
|
||||
return part;
|
||||
|
||||
error_free_part:
|
||||
free (part);
|
||||
error:
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static PedPartition*
|
||||
sun_partition_duplicate (const PedPartition* part)
|
||||
{
|
||||
PedPartition* new_part;
|
||||
SunPartitionData* new_sun_data;
|
||||
SunPartitionData* old_sun_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_sun_data = (SunPartitionData*) part->disk_specific;
|
||||
new_sun_data = (SunPartitionData*) new_part->disk_specific;
|
||||
new_sun_data->type = old_sun_data->type;
|
||||
new_sun_data->is_boot = old_sun_data->is_boot;
|
||||
new_sun_data->is_root = old_sun_data->is_root;
|
||||
new_sun_data->is_lvm = old_sun_data->is_lvm;
|
||||
new_sun_data->is_raid = old_sun_data->is_raid;
|
||||
return new_part;
|
||||
}
|
||||
|
||||
static void
|
||||
sun_partition_destroy (PedPartition* part)
|
||||
{
|
||||
PED_ASSERT (part != NULL);
|
||||
|
||||
if (ped_partition_is_active (part))
|
||||
free (part->disk_specific);
|
||||
free (part);
|
||||
}
|
||||
|
||||
static int
|
||||
sun_partition_set_system (PedPartition* part, const PedFileSystemType* fs_type)
|
||||
{
|
||||
SunPartitionData* sun_data = part->disk_specific;
|
||||
|
||||
part->fs_type = fs_type;
|
||||
|
||||
if (sun_data->is_boot) {
|
||||
sun_data->type = 0x1;
|
||||
return 1;
|
||||
}
|
||||
if (sun_data->is_root) {
|
||||
sun_data->type = 0x2;
|
||||
return 1;
|
||||
}
|
||||
if (sun_data->is_lvm) {
|
||||
sun_data->type = 0x8e;
|
||||
return 1;
|
||||
}
|
||||
if (sun_data->is_raid) {
|
||||
sun_data->type = 0xfd;
|
||||
return 1;
|
||||
}
|
||||
|
||||
sun_data->type = 0x83;
|
||||
if (fs_type) {
|
||||
if (is_linux_swap (fs_type->name))
|
||||
sun_data->type = 0x82;
|
||||
else if (!strcmp (fs_type->name, "ufs"))
|
||||
sun_data->type = 0x6;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int
|
||||
sun_partition_set_flag (PedPartition* part, PedPartitionFlag flag, int state)
|
||||
{
|
||||
SunPartitionData* sun_data;
|
||||
|
||||
PED_ASSERT (part != NULL);
|
||||
PED_ASSERT (part->disk_specific != NULL);
|
||||
PED_ASSERT (ped_partition_is_flag_available (part, flag));
|
||||
|
||||
sun_data = part->disk_specific;
|
||||
|
||||
switch (flag) {
|
||||
case PED_PARTITION_BOOT:
|
||||
sun_data->is_boot = state;
|
||||
if (state) {
|
||||
sun_data->is_lvm = 0;
|
||||
sun_data->is_raid = 0;
|
||||
sun_data->is_root = 0;
|
||||
}
|
||||
return ped_partition_set_system (part, part->fs_type);
|
||||
|
||||
case PED_PARTITION_ROOT:
|
||||
sun_data->is_root = state;
|
||||
if (state) {
|
||||
sun_data->is_boot = 0;
|
||||
sun_data->is_lvm = 0;
|
||||
sun_data->is_raid = 0;
|
||||
}
|
||||
return ped_partition_set_system (part, part->fs_type);
|
||||
|
||||
case PED_PARTITION_LVM:
|
||||
sun_data->is_lvm = state;
|
||||
if (state) {
|
||||
sun_data->is_boot = 0;
|
||||
sun_data->is_raid = 0;
|
||||
sun_data->is_root = 0;
|
||||
}
|
||||
return ped_partition_set_system (part, part->fs_type);
|
||||
|
||||
case PED_PARTITION_RAID:
|
||||
sun_data->is_raid = state;
|
||||
if (state) {
|
||||
sun_data->is_boot = 0;
|
||||
sun_data->is_lvm = 0;
|
||||
sun_data->is_root = 0;
|
||||
}
|
||||
return ped_partition_set_system (part, part->fs_type);
|
||||
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static int _GL_ATTRIBUTE_PURE
|
||||
sun_partition_get_flag (const PedPartition* part, PedPartitionFlag flag)
|
||||
{
|
||||
SunPartitionData* sun_data;
|
||||
|
||||
PED_ASSERT (part != NULL);
|
||||
PED_ASSERT (part->disk_specific != NULL);
|
||||
|
||||
sun_data = part->disk_specific;
|
||||
|
||||
switch (flag) {
|
||||
case PED_PARTITION_BOOT:
|
||||
return sun_data->is_boot;
|
||||
case PED_PARTITION_ROOT:
|
||||
return sun_data->is_root;
|
||||
case PED_PARTITION_LVM:
|
||||
return sun_data->is_lvm;
|
||||
case PED_PARTITION_RAID:
|
||||
return sun_data->is_raid;
|
||||
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
sun_partition_is_flag_available (const PedPartition* part,
|
||||
PedPartitionFlag flag)
|
||||
{
|
||||
switch (flag) {
|
||||
case PED_PARTITION_BOOT:
|
||||
case PED_PARTITION_ROOT:
|
||||
case PED_PARTITION_LVM:
|
||||
case PED_PARTITION_RAID:
|
||||
return 1;
|
||||
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
static bool
|
||||
sun_get_max_supported_partition_count (const PedDisk* disk, int *max_n)
|
||||
{
|
||||
*max_n = SUN_DISK_MAXPARTITIONS;
|
||||
return true;
|
||||
}
|
||||
|
||||
static int
|
||||
sun_get_max_primary_partition_count (const PedDisk* disk)
|
||||
{
|
||||
return SUN_DISK_MAXPARTITIONS;
|
||||
}
|
||||
|
||||
static PedAlignment*
|
||||
sun_get_partition_alignment(const PedDisk *disk)
|
||||
{
|
||||
PedSector block =
|
||||
disk->dev->hw_geom.sectors * disk->dev->hw_geom.heads;
|
||||
|
||||
return ped_alignment_new(0, block);
|
||||
}
|
||||
|
||||
static PedConstraint*
|
||||
_get_strict_constraint (PedDisk* disk)
|
||||
{
|
||||
PedDevice* dev = disk->dev;
|
||||
PedAlignment start_align;
|
||||
PedAlignment end_align;
|
||||
PedGeometry max_geom;
|
||||
SunDiskData* disk_data = disk->disk_specific;
|
||||
PedSector block = dev->bios_geom.sectors * dev->bios_geom.heads;
|
||||
|
||||
if (!ped_alignment_init (&start_align, 0, block))
|
||||
return NULL;
|
||||
if (!ped_alignment_init (&end_align, -1, block))
|
||||
return NULL;
|
||||
if (!ped_geometry_init (&max_geom, dev, 0, disk_data->length))
|
||||
return NULL;
|
||||
|
||||
return ped_constraint_new (&start_align, &end_align, &max_geom,
|
||||
&max_geom, 1, dev->length);
|
||||
}
|
||||
|
||||
static PedConstraint*
|
||||
_get_lax_constraint (PedDisk* disk)
|
||||
{
|
||||
PedDevice* dev = disk->dev;
|
||||
PedAlignment start_align;
|
||||
PedGeometry max_geom;
|
||||
SunDiskData* disk_data = disk->disk_specific;
|
||||
PedSector block = dev->bios_geom.sectors * dev->bios_geom.heads;
|
||||
|
||||
if (!ped_alignment_init (&start_align, 0, block))
|
||||
return NULL;
|
||||
if (!ped_geometry_init (&max_geom, dev, 0, disk_data->length))
|
||||
return NULL;
|
||||
|
||||
return ped_constraint_new (&start_align, ped_alignment_any, &max_geom,
|
||||
&max_geom, 1, dev->length);
|
||||
}
|
||||
|
||||
/* _get_strict_constraint() will align the partition to the end of the cylinder.
|
||||
* This isn't required, but since partitions must start at the start of the
|
||||
* cylinder, space between the end of a partition and the end of a cylinder
|
||||
* is unusable, so there's no point wasting space!
|
||||
* However, if they really insist (via constraint)... which they will
|
||||
* if they're reading a weird table of the disk... then we allow the end to
|
||||
* be anywhere, with _get_lax_constraint()
|
||||
*/
|
||||
static int
|
||||
sun_partition_align (PedPartition* part, const PedConstraint* constraint)
|
||||
{
|
||||
PED_ASSERT (part != NULL);
|
||||
|
||||
if (_ped_partition_attempt_align (part, constraint,
|
||||
_get_strict_constraint (part->disk)))
|
||||
return 1;
|
||||
if (_ped_partition_attempt_align (part, constraint,
|
||||
_get_lax_constraint (part->disk)))
|
||||
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
|
||||
sun_partition_enumerate (PedPartition* part)
|
||||
{
|
||||
int i;
|
||||
PedPartition* p;
|
||||
|
||||
/* never change the partition numbers */
|
||||
if (part->num != -1)
|
||||
return 1;
|
||||
for (i = 1; i <= SUN_DISK_MAXPARTITIONS; i++) {
|
||||
/* skip the Whole Disk partition for now */
|
||||
if (i == WHOLE_DISK_PART + 1)
|
||||
continue;
|
||||
p = ped_disk_get_partition (part->disk, i);
|
||||
if (!p) {
|
||||
part->num = i;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
#ifndef DISCOVER_ONLY
|
||||
/* Ok, now allocate the Whole disk if it isn't already */
|
||||
p = ped_disk_get_partition (part->disk, WHOLE_DISK_PART + 1);
|
||||
if (!p) {
|
||||
int j = ped_exception_throw (
|
||||
PED_EXCEPTION_WARNING,
|
||||
PED_EXCEPTION_IGNORE_CANCEL,
|
||||
_("The Whole Disk partition is the only "
|
||||
"available one left. Generally, it is not a "
|
||||
"good idea to overwrite this partition with "
|
||||
"a real one. Solaris may not be able to "
|
||||
"boot without it, and SILO (the sparc boot "
|
||||
"loader) appreciates it as well."));
|
||||
if (j == PED_EXCEPTION_IGNORE) {
|
||||
/* bad bad bad...you will suffer your own fate */
|
||||
part->num = WHOLE_DISK_PART + 1;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
/* failed to allocate a number, this means we are full */
|
||||
ped_exception_throw (PED_EXCEPTION_ERROR, PED_EXCEPTION_CANCEL,
|
||||
_("Sun disk label is full."));
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
sun_alloc_metadata (PedDisk* disk)
|
||||
{
|
||||
PedPartition* new_part;
|
||||
SunDiskData* disk_data;
|
||||
PedConstraint* constraint_any;
|
||||
|
||||
PED_ASSERT (disk != NULL);
|
||||
PED_ASSERT (disk->disk_specific != NULL);
|
||||
PED_ASSERT (disk->dev != NULL);
|
||||
|
||||
constraint_any = ped_constraint_any (disk->dev);
|
||||
|
||||
/* Sun disk label does not need to allocate a sector. The disk
|
||||
label is contained within the first 512 bytes, which should not
|
||||
be overwritten by any boot loader or superblock. It is safe for
|
||||
most partitions to start at sector 0. We do however, allocate
|
||||
the space used by alt-cyl's, since we cannot use those. Put them
|
||||
at the end of the disk. */
|
||||
|
||||
disk_data = disk->disk_specific;
|
||||
|
||||
if (disk->dev->length <= 0 ||
|
||||
disk_data->length <= 0 ||
|
||||
disk->dev->length == disk_data->length)
|
||||
goto error;
|
||||
|
||||
new_part = ped_partition_new (disk, PED_PARTITION_METADATA, NULL,
|
||||
disk_data->length, disk->dev->length - 1);
|
||||
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 (sun)
|
||||
|
||||
static PedDiskOps sun_disk_ops = {
|
||||
clobber: NULL,
|
||||
write: NULL_IF_DISCOVER_ONLY (sun_write),
|
||||
|
||||
get_partition_alignment: sun_get_partition_alignment,
|
||||
|
||||
partition_set_name: NULL,
|
||||
partition_get_name: NULL,
|
||||
|
||||
PT_op_function_initializers (sun)
|
||||
};
|
||||
|
||||
static PedDiskType sun_disk_type = {
|
||||
next: NULL,
|
||||
name: "sun",
|
||||
ops: &sun_disk_ops,
|
||||
features: 0
|
||||
};
|
||||
|
||||
void
|
||||
ped_disk_sun_init ()
|
||||
{
|
||||
PED_ASSERT (sizeof (SunRawLabel) == 512);
|
||||
ped_disk_type_register (&sun_disk_type);
|
||||
}
|
||||
|
||||
void
|
||||
ped_disk_sun_done ()
|
||||
{
|
||||
ped_disk_type_unregister (&sun_disk_type);
|
||||
}
|
||||
1329
jni/parted/libparted/labels/vtoc.c
Executable file
1329
jni/parted/libparted/labels/vtoc.c
Executable file
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user