Ejemplo n.º 1
0
static int
amiga_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 space for the RDB */
	new_part = ped_partition_new (disk, PED_PARTITION_METADATA, NULL,
	                              0, MAX_RDB_BLOCK);
	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;
}
Ejemplo n.º 2
0
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;
}
Ejemplo n.º 3
0
Archivo: pc98.c Proyecto: Excito/parted
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;
}
Ejemplo n.º 4
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;
}
Ejemplo n.º 5
0
/**
 * Creates the boot- and the linux partition and formats the linux
 * partition with an ext2 filesystem
 *
 */
int create_partitions(const char* dev, unsigned long bootsector_size) {
  PedDisk* disk;
  PedDevice* device;
  PedPartition* boot_part;
  PedPartition* linux_part;
  PedFileSystemType* fs_type;
  PedTimer* timer;

  // get device from string e.g. "/dev/sdd"
  device = ped_device_get(dev);
  if(device == NULL) {
    return 0;
  }

  // create new partition table
  disk = ped_disk_new_fresh(device, ped_disk_type_get("msdos"));
  if(disk == NULL) {
    ped_device_destroy(device);
    return 0;
  }

  // get file system type (ext2)
  fs_type = ped_file_system_type_get(FILE_SYSTEM);

  // create partitions
  boot_part = ped_partition_new(disk, PED_PARTITION_NORMAL, fs_type, 0, bootsector_size / device->sector_size);
  linux_part = ped_partition_new(disk, PED_PARTITION_NORMAL, fs_type, bootsector_size / device->sector_size, device->length - 1);

  // add partitions to partition table
  PedConstraint* constraint = ped_constraint_any(device);
  ped_disk_add_partition(disk, linux_part, constraint);
  ped_disk_add_partition(disk, boot_part, constraint);
  ped_constraint_destroy(constraint);

  // create timer
  timer = ped_timer_new(create_ext2_timer, NULL);

  // create filesystem
  ped_file_system_create(&linux_part->geom, fs_type, timer);

  // commit to hardware
  ped_disk_commit_to_dev(disk);
  ped_disk_commit_to_os(disk);

  return 1;
}
Ejemplo n.º 6
0
QString LibPartedPartitionTable::createPartition(Report& report, const Partition& partition)
{
    Q_ASSERT(partition.devicePath() == QString::fromUtf8(pedDevice()->path));

    QString rval = QString();

    // According to libParted docs, PedPartitionType can be "nullptr if unknown". That's obviously wrong,
    // it's a typedef for an enum. So let's use something the libparted devs will hopefully never
    // use...
    PedPartitionType pedType = static_cast<PedPartitionType>(0xffffffff);

    if (partition.roles().has(PartitionRole::Extended))
        pedType = PED_PARTITION_EXTENDED;
    else if (partition.roles().has(PartitionRole::Logical))
        pedType = PED_PARTITION_LOGICAL;
    else if (partition.roles().has(PartitionRole::Primary))
        pedType = PED_PARTITION_NORMAL;

    if (pedType == static_cast<int>(0xffffffff)) {
        report.line() << xi18nc("@info:progress", "Unknown partition role for new partition <filename>%1</filename> (roles: %2)", partition.deviceNode(), partition.roles().toString());
        return QString();
    }

    PedFileSystemType* pedFsType = (partition.roles().has(PartitionRole::Extended) || partition.fileSystem().type() == FileSystem::Unformatted) ? nullptr : getPedFileSystemType(partition.fileSystem().type());

    PedPartition* pedPartition = ped_partition_new(pedDisk(), pedType, pedFsType, partition.firstSector(), partition.lastSector());

    if (pedPartition == nullptr) {
        report.line() << xi18nc("@info:progress", "Failed to create new partition <filename>%1</filename>.", partition.deviceNode());
        return QString();
    }

    PedConstraint* pedConstraint = nullptr;
    PedGeometry* pedGeometry = ped_geometry_new(pedDevice(), partition.firstSector(), partition.length());

    if (pedGeometry)
        pedConstraint = ped_constraint_exact(pedGeometry);
    ped_geometry_destroy(pedGeometry);

    if (pedConstraint == nullptr) {
        report.line() << i18nc("@info:progress", "Failed to create a new partition: could not get geometry for constraint.");
        return QString();
    }

    if (ped_disk_add_partition(pedDisk(), pedPartition, pedConstraint)) {
        char *pedPath = ped_partition_get_path(pedPartition);
        rval = QString::fromUtf8(pedPath);
        free(pedPath);
    }
    else {
        report.line() << xi18nc("@info:progress", "Failed to add partition <filename>%1</filename> to device <filename>%2</filename>.", partition.deviceNode(), QString::fromUtf8(pedDisk()->dev->path));
        report.line() << LibPartedBackend::lastPartedExceptionMessage();
    }

    ped_constraint_destroy(pedConstraint);

    return rval;
}
Ejemplo n.º 7
0
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);
	result->num = part->num;
	return result;
}
Ejemplo n.º 8
0
int main(int argc, char *argv[])
{
	PedDevice *dev;
	PedDisk *disk;
	PedPartition *part;
	PedConstraint *constraint;

	/*
	 * argv [1] device
	 *      [2] udv_name
	 *      [3] start
	 *      [4] end
	 */

	dev = ped_device_get(argv[1]);
	if (!dev)
	{
		perror("get_device");
		return -1;
	}

	//disk = _create_disk_label(dev, ped_disk_type_get("gpt"));
	disk = ped_disk_new(dev);
	if (!disk)
	{
		fprintf(stderr, "fail to create disk label gpt\n");
		return -2;
	}
	constraint = ped_constraint_any(dev);

	// part1: 17.4Kb ~ 15MB
	/*
	part = ped_partition_new(disk, PED_PARTITION_NORMAL,
				NULL,
				34, 29296);
	ped_disk_add_partition(disk, part, constraint);
	*/

	// part2: 15MB ~ 35MB
	part = ped_partition_new(disk, PED_PARTITION_NORMAL,
				NULL,
				(int)(atoll(argv[3])/512),
				(int)(atoll(argv[4])/512));
	ped_partition_set_name(part, argv[2]);
	ped_disk_add_partition(disk, part, constraint);

	ped_disk_commit(disk);

	ped_constraint_destroy(constraint);
	ped_disk_destroy(disk);
	ped_device_destroy(dev);

	return 0;
}
Ejemplo n.º 9
0
Archivo: loop.c Proyecto: Excito/parted
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);

        if (found_sig) {
		ped_constraint_destroy (constraint_any);
		return 1;
        }

	geom = ped_geometry_new (dev, 0, dev->length);
	if (!geom)
		goto error;

	fs_type = ped_file_system_probe (geom);
	if (!fs_type)
		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;
	part->fs_type = fs_type;

	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;
}
Ejemplo n.º 10
0
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->boot_code, s0, sizeof (bsd_specific->boot_code));
	free (s0);

	label = (BSDRawLabel *) (bsd_specific->boot_code + BSD_LABEL_OFFSET);

	for (i = 1; i <= BSD_MAXPARTITIONS; i++) {
		PedPartition* 		part;
		BSDPartitionData*	bsd_part_data;
		PedSector		start;
		PedSector		end;
		PedConstraint*		constraint_exact;

		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);

		constraint_exact = ped_constraint_exact (&part->geom);
		if (!ped_disk_add_partition (disk, part, constraint_exact))
			goto error;
		ped_constraint_destroy (constraint_exact);
	}

	return 1;

error:
	return 0;
}
Ejemplo n.º 11
0
PedPartition* create_and_add_partition(PedDisk* disk, PedPartitionType type,
                                       const PedFileSystemType* fs,
                                       PedSector start, PedSector end)
{
    PedPartition* part = ped_partition_new (disk, type, fs, start, end);
    g_return_val_if_fail(part != NULL, FALSE);
    PedGeometry* geom = ped_geometry_new (disk->dev, start, end - start + 1);
    g_assert(geom != NULL);
    PedConstraint* constraint = ped_constraint_new_from_max (geom);
    g_assert(constraint != NULL);
    ped_disk_add_partition(disk, part, constraint);
    ped_constraint_destroy (constraint);
    ped_geometry_destroy (geom);
    return part;
}
Ejemplo n.º 12
0
Archivo: dasd.c Proyecto: bcl/parted
static PedPartition*
dasd_partition_duplicate (const PedPartition *part)
{
	PedPartition *new_part;

	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;

	memcpy(new_part->disk_specific, part->disk_specific,
	       sizeof(DasdPartitionData));

	return new_part;
}
Ejemplo n.º 13
0
void
gnome_format_create_partition(gchar *block_dev, gchar *fs, GError **error) {

        PedDevice *device;
        PedDisk *disk;
        PedFileSystemType *fs_type;
        PedPartition *part;
        
        ped_exception_set_handler(parted_exception_handler);
        
        try(device = ped_device_get(block_dev));
        try(disk = ped_disk_new(device));
        
        int last_part_num = ped_disk_get_last_partition_num(disk);
        if (last_part_num != -1) {
                // if partitions exist, delete them
                try(ped_disk_delete_all(disk));
        }

        long long end = device->length - 1;

        try(fs_type = ped_file_system_type_get(fs));
        
        // create new partition
        try(part = ped_partition_new(disk, PED_PARTITION_NORMAL, fs_type, 1, end));
        try(ped_disk_add_partition(disk, part, ped_constraint_any(device)));

        try(ped_file_system_create(&part->geom, fs_type, NULL));
                
        // commit changes
        try(ped_disk_commit_to_dev(disk));
        
        // this needs root priviliges
//        try(ped_disk_commit_to_os(disk));

#ifdef DEBUG
        printf("device.sector_size: %lld\n", device->sector_size);
        printf("device.length: %lld\n", device->length);
        printf("end: %lld\n", end);
#endif
        
        // free stuff
        ped_disk_destroy(disk);
        ped_device_destroy(device);
}
Ejemplo n.º 14
0
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;
}
Ejemplo n.º 15
0
/* 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;
}
Ejemplo n.º 16
0
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;

	strncpy (dvh_part_data->name, vd->vd_name, VDNAMESIZE);
	dvh_part_data->name[VDNAMESIZE] = 0;
	return part;
}
Ejemplo n.º 17
0
Archivo: pc98.c Proyecto: Excito/parted
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;
}
Ejemplo n.º 18
0
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;
}
Ejemplo n.º 19
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;
}
Ejemplo n.º 20
0
static PedPartition*
amiga_partition_duplicate (const PedPartition* part)
{
	PedPartition *new_part;
	struct PartitionBlock *new_amiga_part;
	struct PartitionBlock *old_amiga_part;

	PED_ASSERT(part != NULL);
	PED_ASSERT(part->disk != NULL);
	PED_ASSERT(part->disk_specific != NULL);
	old_amiga_part = (struct PartitionBlock *) part->disk_specific;

	new_part = ped_partition_new (part->disk, part->type,
				      part->fs_type, part->geom.start,
				      part->geom.end);
	if (!new_part)
		return NULL;

	new_amiga_part = (struct PartitionBlock *) new_part->disk_specific;
	memcpy (new_amiga_part, old_amiga_part, 256);

	return new_part;
}
Ejemplo n.º 21
0
static gboolean
part_add_change_partition (char *device_file, 
			   guint64 start, guint64 size, 
			   guint64 new_start, guint64 new_size, 
			   guint64 *out_start, guint64 *out_size, 
			   char *type, char *label, char **flags,
			   int geometry_hps, int geometry_spt)
{
	int n;
	gboolean is_change;
	gboolean res;
	PedDevice *device;
	PedDisk *disk;
	PedPartition *part;
	PedConstraint* constraint;
	PedPartitionType ped_type;
	guint64 start_sector;
	guint64 end_sector;
	guint64 new_start_sector;
	guint64 new_end_sector;
	PartitionTable *p;
	PartitionTable *container_p;
	int container_entry;
	PartitionScheme scheme;
	guint8 mbr_flags = 0;
	guint8 mbr_part_type = 0;
	char *endp;
	guint64 gpt_attributes = 0;
	guint32 apm_status = 0;

	res = FALSE;

	is_change = FALSE;
	if (size == 0) {
		is_change = TRUE;
	}

	if (is_change) {
		HAL_INFO (("In part_change_partition: device_file=%s, start=%lld, new_start=%lld, new_size=%lld, type=%s", device_file, start, new_start, new_size, type));
	} else {
		HAL_INFO (("In part_add_partition: device_file=%s, start=%lld, size=%lld, type=%s", device_file, start, size, type));
	}

	/* first, find the kind of (embedded) partition table the new partition is going to be part of */
	p = part_table_load_from_disk (device_file);
	if (p == NULL) {
		HAL_INFO (("Cannot load partition table from %s", device_file));
		goto out;
	}

	part_table_find (p, start + 512, &container_p, &container_entry);
	scheme = part_table_get_scheme (container_p);

	if (is_change) {
		/* if changing, make sure there is a partition to change */
		if (container_entry < 0) {
			HAL_INFO (("Couldn't find partition to change"));
			goto out;
		}
	} else {
		/* if adding, make sure there is no partition in the way... */
		if (container_entry >= 0) {
			char *part_type;
			
			/* this might be Apple_Free if we're on PART_TYPE_APPLE */
			part_type = part_table_entry_get_type (p, container_entry);
			if (! (p->scheme == PART_TYPE_APPLE && part_type != NULL && (strcmp (part_type, "Apple_Free") == 0))) {
				part_table_free (p);
				HAL_INFO (("There is a partition in the way on %s", device_file));
				goto out;
			}
		}
	}

	HAL_INFO (("containing partition table scheme = %d", scheme));

	part_table_free (p);
	p = NULL;

	if (!is_change) {
		if (type == NULL) {
			HAL_INFO (("No type specified"));
			goto out;
		}
	}

	/* now that we know the partitoning scheme, sanity check type and flags */
	switch (scheme) {
	case PART_TYPE_MSDOS:
	case PART_TYPE_MSDOS_EXTENDED:
		mbr_flags = 0;
		if (flags != NULL) {
			for (n = 0; flags[n] != NULL; n++) {
				if (strcmp (flags[n], "boot") == 0) {
					mbr_flags |= 0x80;
				} else {
					HAL_INFO (("unknown flag '%s'", flags[n]));
					goto out;
				}
			}
		}

		if (type != NULL) {
			mbr_part_type = (guint8) (strtol (type, &endp, 0));
			if (*endp != '\0') {
				HAL_INFO (("invalid type '%s' given", type));
				goto out;
			}
		}

		if (label != NULL) {
			HAL_INFO (("labeled partitions not supported on MSDOS or MSDOS_EXTENDED"));
			goto out;
		}
		
		break;

	case PART_TYPE_GPT:
		gpt_attributes = 0;
		if (flags != NULL) {
			for (n = 0; flags[n] != NULL; n++) {
				if (strcmp (flags[n], "required") == 0) {
					gpt_attributes |= 1;
				} else {
					HAL_INFO (("unknown flag '%s'", flags[n]));
					goto out;
				}
			}
		}
		break;

	case PART_TYPE_APPLE:
		apm_status = 0;
		if (flags != NULL) {
			for (n = 0; flags[n] != NULL; n++) {
				if (strcmp (flags[n], "allocated") == 0) {
					apm_status |= (1<<1);
				} else if (strcmp (flags[n], "in_use") == 0) {
					apm_status |= (1<<2);
				} else if (strcmp (flags[n], "boot") == 0) {
					apm_status |= (1<<3);
				} else if (strcmp (flags[n], "allow_read") == 0) {
					apm_status |= (1<<4);
				} else if (strcmp (flags[n], "allow_write") == 0) {
					apm_status |= (1<<5);
				} else if (strcmp (flags[n], "boot_code_is_pic") == 0) {
					apm_status |= (1<<6);
				} else {
					HAL_INFO (("unknown flag '%s'", flags[n]));
					goto out;
				}
			}
		}
		break;

	default:
		HAL_INFO (("partitioning scheme %d not supported", scheme));
		goto out;
	}

	switch (scheme) {
	case PART_TYPE_MSDOS:
		if (mbr_part_type == 0x05 || mbr_part_type == 0x85 || mbr_part_type == 0x0f) {
			ped_type = PED_PARTITION_EXTENDED;
		} else {
			ped_type = PED_PARTITION_NORMAL;
		}
		break;

	case PART_TYPE_MSDOS_EXTENDED:
		ped_type = PED_PARTITION_LOGICAL;
		if (mbr_part_type == 0x05 || mbr_part_type == 0x85 || mbr_part_type == 0x0f) {
			HAL_INFO (("Cannot create an extended partition inside an extended partition"));
			goto out;
		}
		break;

	default:
		ped_type = PED_PARTITION_NORMAL;
		break;
	}

	/* now, create the partition */

	start_sector = start / 512;
	end_sector = (start + size) / 512 - 1;
	new_start_sector = new_start / 512;
	new_end_sector = (new_start + new_size) / 512 - 1;

	device = ped_device_get (device_file);
	if (device == NULL) {
		HAL_INFO (("ped_device_get() failed"));
		goto out;
	}
	HAL_INFO (("got it"));

	/* set drive geometry on libparted object if the user requested it */
	if (geometry_hps > 0 && geometry_spt > 0 ) {
		/* not sure this is authorized use of libparted, but, eh, it seems to work */
		device->hw_geom.cylinders = device->bios_geom.cylinders = device->length / geometry_hps / geometry_spt;
		device->hw_geom.heads = device->bios_geom.heads = geometry_hps;
		device->hw_geom.sectors = device->bios_geom.sectors = geometry_spt;
	}

	disk = ped_disk_new (device);
	if (disk == NULL) {
		HAL_INFO (("ped_disk_new() failed"));
		goto out_ped_device;
	}
	HAL_INFO (("got disk"));

	if (!is_change) {
		part = ped_partition_new (disk, 
					  ped_type,
					  NULL,
					  start_sector,
					  end_sector);
		if (part == NULL) {
			HAL_INFO (("ped_partition_new() failed"));
			goto out_ped_disk;
		}
		HAL_INFO (("new partition"));
	} else {
		part = ped_disk_get_partition_by_sector (disk,
							 start_sector);
		if (part == NULL) {
			HAL_INFO (("ped_partition_get_by_sector() failed"));
			goto out_ped_disk;
		}
		HAL_INFO (("got partition"));
	}
				  

	/* TODO HACK XXX FIXME UGLY BAD: This is super ugly abuse of
	 * libparted - we poke at their internal data structures - but
	 * there ain't nothing we can do about it until libparted
	 * provides API for this...
	 */
	if (scheme == PART_TYPE_GPT) {
		struct {
			efi_guid	type;
			efi_guid	uuid;
			char		name[37];
			int		lvm;
			int		raid;
			int		boot;
			int		hp_service;
			int             hidden;
			/* more stuff */
		} *gpt_data = (void *) part->disk_specific;

		if (type != NULL) {
			if (!set_le_guid ((guint8*) &gpt_data->type, type)) {
				HAL_INFO (("type '%s' for GPT appear to be malformed", type));
				goto out_ped_partition;
			}
		}

		if (flags != NULL) {
			if (gpt_attributes & 1) {
				gpt_data->hidden = 1;
			} else {
				gpt_data->hidden = 0;
			}
		}

	} else if (scheme == PART_TYPE_MSDOS || scheme == PART_TYPE_MSDOS_EXTENDED) {
		struct {
			unsigned char	system;
			int		boot;
			/* more stuff */
		} *dos_data = (void *) part->disk_specific;

		if (type != NULL) {
			dos_data->system = mbr_part_type;
		}
		if (flags != NULL) {
			if (mbr_flags & 0x80) {
				dos_data->boot = 1;
			} else {
				dos_data->boot = 0;
			}
		}

	} else if (scheme == PART_TYPE_APPLE) {
		struct {
			char            volume_name[33];	/* eg: "Games" */
			char            system_name[33];	/* eg: "Apple_Unix_SVR2" */
			char            processor_name[17];
			int             is_boot;
			int             is_driver;
			int             has_driver;
			int             is_root;
			int             is_swap;
			int             is_lvm;
			int             is_raid;
			PedSector       data_region_length;
			PedSector       boot_region_length;
			guint32         boot_base_address;
			guint32         boot_entry_address;
			guint32         boot_checksum;
			guint32         status;
			/* more stuff */
		} *mac_data = (void *) part->disk_specific;

		if (type != NULL) {
			memset (mac_data->system_name, 0, 33);
			strncpy (mac_data->system_name, type, 32);
		}

		if (flags != NULL) {
			mac_data->status = apm_status;
		}
	}

	if (label != NULL) {
		ped_partition_set_name (part, label);
	}

	if (geometry_hps > 0 && geometry_spt > 0 ) {
		/* respect drive geometry */
		constraint = ped_constraint_any (device);
	} else if (geometry_hps == -1 && geometry_spt == -1 ) {

		/* undocumented (or is it?) libparted usage again.. it appears that
		 * the probed geometry is stored in hw_geom
		 */
		device->bios_geom.cylinders = device->hw_geom.cylinders;
		device->bios_geom.heads     = device->hw_geom.heads;
		device->bios_geom.sectors   = device->hw_geom.sectors;

		constraint = ped_constraint_any (device);
	} else {
		PedGeometry *geo_start;
		PedGeometry *geo_end;

		/* ignore drive geometry */
		if (is_change) {
			geo_start = ped_geometry_new (device, new_start_sector, 1);
			geo_end = ped_geometry_new (device, new_end_sector, 1);
		} else {
			geo_start = ped_geometry_new (device, start_sector, 1);
			geo_end = ped_geometry_new (device, end_sector, 1);
		}

		constraint = ped_constraint_new (ped_alignment_any, ped_alignment_any,
						 geo_start, geo_end, 1, device->length);
	}

try_change_again:
	if (is_change) {
		if (ped_disk_set_partition_geom (disk,
						 part,
						 constraint,
						 new_start_sector, new_end_sector) == 0) {
			HAL_INFO (("ped_disk_set_partition_geom() failed"));
			goto out_ped_constraint;
		}
	} else {
		if (ped_disk_add_partition (disk,
					    part,
					    constraint) == 0) {
			HAL_INFO (("ped_disk_add_partition() failed"));
			goto out_ped_constraint;
		}
	}

	*out_start = part->geom.start * 512;
	*out_size = part->geom.length * 512;

	if (is_change) {
		/* make sure the resulting size is never smaller than requested
		 * (this is because one will resize the FS and *then* change the partition table)
		 */
		if (*out_size < new_size) {
			HAL_INFO (("new_size=%lld but resulting size, %lld, smaller than requested", new_size, *out_size));
			new_end_sector++;
			goto try_change_again;
		} else {
			HAL_INFO (("changed partition to start=%lld size=%lld", *out_start, *out_size));
		}
	} else {
		HAL_INFO (("added partition start=%lld size=%lld", *out_start, *out_size));
	}


	/* hmm, if we don't do this libparted crashes.. I assume that
	 * ped_disk_add_partition assumes ownership of the
	 * PedPartition when adding it... sadly this is not documented
	 * anywhere.. sigh..
	 */
	part = NULL;

	/* use commit_to_dev rather than just commit to avoid
	 * libparted sending BLKRRPART to the kernel - we want to do
	 * this ourselves... 
	 */
	if (ped_disk_commit_to_dev (disk) == 0) {
		HAL_INFO (("ped_disk_commit_to_dev() failed"));
		goto out_ped_constraint;
	}
	HAL_INFO (("committed to disk"));

	res = TRUE;

	ped_constraint_destroy (constraint);
	ped_disk_destroy (disk);
	ped_device_destroy (device);
	goto out;

out_ped_constraint:
	ped_constraint_destroy (constraint);

out_ped_partition:
	if (part != NULL) {
		ped_partition_destroy (part);
	}

out_ped_disk:
	ped_disk_destroy (disk);

out_ped_device:
	ped_device_destroy (device);

out:
	return res;
}
Ejemplo n.º 22
0
PartitionState do_test1(PedDevice *dev, label_type labelType) {
    PartitionState state;
    //PedGeometry geom;
    PedDisk *disk;
    PedPartition *part;
    PedPartition *grub_partition = 0, *boot_partition = 0, *root_partition = 0;
    PedDiskType *type = 0;
    PedFileSystemType *ext4 = ped_file_system_type_get("ext4");
    bool dirty = false;
    PedSector start = 0, end = 0;

    /*if (!ped_geometry_init(&geom,dev,0,dev->length)) {
        qDebug() << "unable to init geom";
        return;
    }*/

    disk = ped_disk_new(dev);
    /*type = ped_disk_probe(dev);
    if (type) {
        qDebug() << "current partition type:" << type->name;
        disk = type->ops->alloc(dev);
        if (!type->ops->read(disk)) {
            qDebug() << "failed to read gpt tables";
            return;
        }
    }*/
    if (!disk) {
        qDebug() << "no tables detected";
        if (labelType == label_type::gpt) {
            type = ped_disk_type_get("gpt");
        } else if (labelType == label_type::mbr) {
            type = ped_disk_type_get("msdos");
        }
        disk = ped_disk_new_fresh(dev,type);
        ped_disk_commit(disk);
    }
    if (disk) {
        for (part = ped_disk_next_partition(disk,NULL);
             part;
             part = ped_disk_next_partition(disk,part)) {
            if (!ped_partition_is_active(part)) continue;
            QString name(ped_partition_get_name(part));
            qDebug() << "partition" << part->num << name;
            if (name == "boot") boot_partition = part;
            if (name == "root") root_partition = part;
            if (ped_partition_get_flag(part,PED_PARTITION_BIOS_GRUB)) grub_partition = part;
            for (int f = PED_PARTITION_FIRST_FLAG; f < PED_PARTITION_LAST_FLAG; f++) {
                if (ped_partition_get_flag(part,(PedPartitionFlag)f)) {
                    QString flag_name(ped_partition_flag_get_name((PedPartitionFlag)f));
                    qDebug() << "flag" << flag_name << "is set";
                }
            }
        }

        PedConstraint *constraint = ped_constraint_any(dev);
        if (!grub_partition) {
            start = (1024*1024) / dev->sector_size;
            end = ((1024*1024) / dev->sector_size) + start;
            qDebug() << "creating" << start << end;
            grub_partition = ped_partition_new(disk,PED_PARTITION_NORMAL,ext4,start,end);
            if (labelType == label_type::gpt) {
                ped_partition_set_name(grub_partition,"bios boot");
                ped_partition_set_flag(grub_partition,PED_PARTITION_BIOS_GRUB,1);
            }
            if (!ped_disk_add_partition(disk,grub_partition,constraint)) {
                qDebug() << "error adding partition";
            }
            dirty = true;
        }

        if (!boot_partition) {
            start = (1024*1024*2) / dev->sector_size;
            end = ((1024*1024*128) / dev->sector_size) + start;
            qDebug() << "creating" << start << end;
            boot_partition = ped_partition_new(disk,PED_PARTITION_NORMAL,NULL,start,end);
            if (labelType == label_type::gpt) {
                ped_partition_set_name(boot_partition,"boot");
            }
            //ped_partition_set_flag(boot_partition,PED_PARTITION_BOOT,1);
            if (!ped_disk_add_partition(disk,boot_partition,constraint)) {
                qDebug() << "error adding partition";
            }
            dirty = true;
        }
        if (!root_partition) {
            start = (1024*1024*129) / dev->sector_size;
            end = dev->length;
            qDebug() << "creating" << start << end;
            root_partition = ped_partition_new(disk,PED_PARTITION_NORMAL,ext4,start,end);
            if (labelType == label_type::gpt) {
                ped_partition_set_name(root_partition,"root");
                //ped_partition_set_flag(root_partition,PED_PARTITION_ROOT,1);
            }
            if (!ped_disk_add_partition(disk,root_partition,constraint)) {
                qDebug() << "error adding partition";
            }
            dirty = true;
        }
        ped_constraint_destroy(constraint);
    }
    if (dirty) ped_disk_commit(disk);
    state.boot_path = ped_partition_get_path(boot_partition);
    state.root_path = ped_partition_get_path(root_partition);
    return state;
}
void SystemPartitioner::init()
{
#if NONDESTRUCTIVE
	emit done();
	return;
#endif
	// Check # of harddisks to see if RAID0-ing them makes any sense
	ped_device_probe_all();
	PedDevice *tmp=NULL;
	int disks=0;
	QString installsource(getenv("INSTALLSOURCE"));
	MSG("Install source is " + installsource);
	while((tmp=ped_device_get_next(tmp))) {
		// FIXME workaround for parted breakage
		// Skip CD-ROMs parted accidentally marks as harddisk
		QString p(tmp->path);
		if(!p.startsWith("/dev/sd") && (p.contains("/dev/scd") || p.contains("/dev/sr") || access(QFile::encodeName("/proc/ide/" + p.section('/', 2, 2) + "/cache"), R_OK)))
			continue;
		// It's not a good idea to install on a USB stick we're installing from...
		if(installsource.startsWith(p))
			continue;
		MSG(QString("Found disk: ") + QString(tmp->path) + ":" + "/proc/ide/" + p.section('/', 2, 2) + "/" + "cache" + ":" + QString::number(access(QFile::encodeName("/proc/ide/" + p.section('/', 2, 2) + "/cache"), R_OK)));
#if 0
		// Check if the drive is actually there -- some empty CF
		// readers misidentify themselves...
		int fd=open(tmp->path, O_RDONLY);
		if(fd < 0)
			continue;
		char test;
		if(read(fd, &test, 1) <= 0) {
			close(fd);
			continue;
		}
		close(fd);
#endif
		disks++;
	}
	ped_device_free_all();

	// Grab all disks
	ped_device_probe_all();

	PedFileSystemType const *ext3=ped_file_system_type_get("ext2"); // parted doesn't support ext3 creation yet, so we need this hack
	PedFileSystemType const *bootext3=ped_file_system_type_get("ext2");
	PedFileSystemType const *swap=ped_file_system_type_get("linux-swap");

	Meminfo m;
	unsigned long long swapsize=m.suggested_swap();
	QStringList raidPartitions;

	PedDevice *dev=NULL;
	PedPartition *fspart=NULL;
	PedGeometry *fsgeo=NULL;
	setHelp(tr("Removing other OSes..."));
	resizeEvent(0);

	uint32_t bootsize=0;
#ifndef NO_RAID0
	if(disks>1)
		bootsize=32*1024*2; /* size is in 512 kB blocks --> we use 32 MB */
#endif
	while((dev=ped_device_get_next(dev))) {
		// FIXME workaround for parted breakage
		QString p(dev->path);
		if(!p.startsWith("/dev/sd") && (p.contains("/dev/scd") || p.contains("/dev/sr") || access(QFile::encodeName("/proc/ide/" + p.section('/', 2, 2) + "/cache"), R_OK)))
			continue;
		// It's not a good idea to install on a USB stick we're installing from...
		if(installsource.startsWith(p))
			continue;
		//unsigned long long disksize=dev->length*dev->sector_size;
		PedDiskType *type=ped_disk_type_get("msdos");
		PedDisk *disk=ped_disk_new_fresh(dev, type);

		PedGeometry *part=ped_geometry_new(dev, 0, dev->length);
		if(swapsize && _swap.isEmpty() && ((unsigned long long)part->length > swapsize + bootsize)) {
			// Split disk in swap and fs partitions
			PedGeometry *swapgeo=ped_geometry_new(dev, 0, swapsize);
			PedGeometry *bootgeo=NULL;
			uint32_t fssize=part->end - swapsize;
			uint32_t fsstart=swapsize+1;
			if(bootsize) {
				bootgeo=ped_geometry_new(dev, swapsize+1, bootsize);
				fssize -= bootsize;
				fsstart += bootsize;
			}
			fsgeo=ped_geometry_new(dev, fsstart, fssize);

			PedPartition *swappart=ped_partition_new(disk, (PedPartitionType)0, swap, swapgeo->start, swapgeo->end);
			PedPartition *bootpart=NULL;
			if(bootsize)
				bootpart=ped_partition_new(disk, (PedPartitionType)0, bootext3, bootgeo->start, bootgeo->end);

			fspart=ped_partition_new(disk, (PedPartitionType)0, ext3, fsgeo->start, fsgeo->end);
			if(bootsize)
				ped_partition_set_flag(fspart, PED_PARTITION_RAID, 1);
			ped_disk_add_partition(disk, swappart, ped_constraint_any(dev));
			ped_disk_commit(disk);

			ped_geometry_destroy(swapgeo);
			
			setHelp(tr("Creating swap filesystem"));
			PedFileSystem *swapfs=ped_file_system_create(&(swappart->geom), swap, NULL /*timer->timer()*/);
			ped_file_system_close(swapfs);
			_swap = dev->path + QString::number(swappart->num);

			// Parted's swap creator is buggy
			QProcess::execute("/sbin/mkswap " + _swap);

			if(bootpart) {
				setHelp(tr("Creating boot filesystem"));
				ped_disk_add_partition(disk, bootpart, ped_constraint_any(dev));
				ped_disk_commit(disk);
				PedFileSystem *bootfs=ped_file_system_create(&(bootpart->geom), bootext3, timer->timer());
				ped_file_system_close(bootfs);
				ped_partition_set_flag(bootpart, PED_PARTITION_BOOT, 1);
				ped_geometry_destroy(bootgeo);

				QString devname=dev->path + QString::number(bootpart->num);
				_size.insert(devname, bootpart->geom.length);
				if(_rootfs == "ext3") {
					Ext3FS e3(devname);
					e3.addJournal(0);
					e3.setCheckInterval(0);
					e3.setCheckMountcount(-1);
					e3.setDirIndex();
				} else {
					QProcess::execute("/sbin/mkfs." + _rootfs + " " + _mkfsopts + " " + devname);
				}
				if(!_postmkfs.isEmpty())
					QProcess::execute(_postmkfs + " " + devname);

				_partitions.insert(devname, FileSystem("/boot", _rootfs));
			}
		} else {
			// Grab the whole disk for filesystem
			fsgeo=ped_constraint_solve_max(ped_constraint_any(dev));
			fspart=ped_partition_new(disk, (PedPartitionType)0, ext3, part->start, part->end);
			if(bootsize)
				ped_partition_set_flag(fspart, PED_PARTITION_RAID, 1);
		}
		ped_disk_add_partition(disk, fspart, ped_constraint_any(dev));
		if(!bootsize)
			ped_partition_set_flag(fspart, PED_PARTITION_BOOT, 1);
		ped_disk_commit(disk);
		if(!bootsize) {
			setHelp(tr("Creating Linux filesystem"));
			PedFileSystem *fs=ped_file_system_create(&(fspart->geom), ext3, timer->timer());
			_totalSize += fspart->geom.length;
			ped_file_system_close(fs);
		}
		ped_geometry_destroy(fsgeo);
		// Convert to ext3 and turn off checking
		QString devname=dev->path + QString::number(fspart->num);
		if(bootsize)
			raidPartitions.append(devname);
		else if(!_partitions.hasMountpoint("/"))
			_partitions.insert(devname, FileSystem("/", _rootfs));
		else {
			QString mp(devname);
			mp.replace("/dev", "/mnt");
			_partitions.insert(devname, FileSystem(mp, _rootfs));
		}
		_size.insert(devname, fspart->geom.length);
		if(!bootsize) {
			if(_rootfs == "ext3") {
				Ext3FS e3(devname);
				e3.addJournal(0);
				e3.setCheckInterval(0);
				e3.setCheckMountcount(-1);
				e3.setDirIndex();
			} else {
				QProcess::execute("/sbin/mkfs." + _rootfs + " " + _mkfsopts + " " + devname);
			}
			if(!_postmkfs.isEmpty())
				QProcess::execute(_postmkfs + " " + devname);
			ped_disk_destroy(disk);
		}
	}

	if(bootsize) {
		setHelp(tr("Combining disks..."));
		// Make sure we can read the array we're building first...
		Modules::instance()->loadWithDeps("md");
		Modules::instance()->loadWithDeps("raid0");
		// Now create it
		FILE *f=fopen("/tmp/mdadm.conf", "w");
		if(!f)
			QMessageBox::information(0, "debug", QString("Failed to create mdadm.conf: ") + strerror(errno));
		fprintf(f, "DEVICE partitions");
		fprintf(f, "ARRAY /dev/md0 name=ArkLinux devices=%s level=0 num-devices=%u\n", qPrintable(raidPartitions.join(",")), raidPartitions.count());
		fprintf(f, "MAILADDR root@localhost\n");
		fclose(f);

		QString command="/sbin/mdadm --create -e 1.2 --chunk=32 --level=0 --raid-devices=" + QString::number(raidPartitions.count()) + " --name=ArkLinux --force /dev/md0 " + raidPartitions.join(" ");
		QProcess::execute(command);
		
		if(_rootfs == "ext3") {
			QProcess::execute("/sbin/mke2fs -j /dev/md0");
			Ext3FS e3("/dev/md0");
			e3.setCheckInterval(0);
			e3.setCheckMountcount(-1);
			e3.setDirIndex();
		} else {
			QProcess::execute("/sbin/mkfs." + _rootfs + " " + _mkfsopts + " /dev/md0");
		}
		if(!_postmkfs.isEmpty())
			QProcess::execute(_postmkfs + " /dev/md0");

		_partitions.insert("/dev/md0", FileSystem("/", _rootfs));
		_size.clear();
		_size.insert("/dev/md0", _totalSize);
	}

	// We don't need a UI to take the whole system - we're done.
	emit done();
}
Ejemplo n.º 24
0
bool CreatePartitionJob::run(Report& parent)
{
	Q_ASSERT(partition().devicePath() == device().deviceNode());

	bool rval = false;

	Report* report = jobStarted(parent);

	// According to libParted docs, PedPartitionType can be "NULL if unknown". That's obviously wrong,
	// it's a typedef for an enum. So let's use something the libparted devs will hopefully never
	// use...
	PedPartitionType pedType = static_cast<PedPartitionType>(0xffffffff);

	if (partition().roles().has(PartitionRole::Extended))
		pedType = PED_PARTITION_EXTENDED;
	else if (partition().roles().has(PartitionRole::Logical))
		pedType = PED_PARTITION_LOGICAL;
	else if (partition().roles().has(PartitionRole::Primary))
		pedType = PED_PARTITION_NORMAL;
			
	if (pedType == static_cast<int>(0xffffffff))
	{
		report->line() << i18nc("@info/plain", "Unknown partition role for new partition <filename>%1</filename> (roles: %2)", partition().deviceNode(), partition().roles().toString());
	}
	else if (openPed(device().deviceNode()))
	{
		PedFileSystemType* pedFsType = (partition().roles().has(PartitionRole::Extended) || partition().fileSystem().type() == FileSystem::Unformatted) ? NULL : getPedFileSystemType(partition().fileSystem().type());

		PedPartition* pedPartition = ped_partition_new(pedDisk(), pedType, pedFsType, partition().firstSector(), partition().lastSector());

		if (pedPartition)
		{
			PedConstraint* pedConstraint = NULL;
			PedGeometry* pedGeometry = ped_geometry_new(pedDevice(), partition().firstSector(), partition().length());

			if (pedGeometry)
				pedConstraint = ped_constraint_exact(pedGeometry);

			if (pedConstraint)
			{
				if (ped_disk_add_partition(pedDisk(), pedPartition, pedConstraint) && commit())
				{
					partition().setNumber(pedPartition->num);
					partition().setState(Partition::StateNone);

					partition().setFirstSector(pedPartition->geom.start);
					partition().setLastSector(pedPartition->geom.end);

					rval = true;
				}
				else
					report->line() << i18nc("@info/plain", "Failed to add partition <filename>%1</filename> to device <filename>%2</filename>.", partition().deviceNode(), device().deviceNode());

				ped_constraint_destroy(pedConstraint);
			}
			else
				report->line() << i18nc("@info/plain", "Failed to create a new partition: could not get geometry for constraint.");
		}
		else
			report->line() << i18nc("@info/plain", "Failed to create new partition <filename>%1</filename>.", partition().deviceNode());
	
		closePed();
	}
	else
		report->line() << i18nc("@info/plain", "Could not open device <filename>%1</filename> to create new partition <filename>%2</filename>.", device().deviceNode(), partition().deviceNode());
	
	jobFinished(*report, rval);
	
	return rval;
}
Ejemplo n.º 25
0
Archivo: dasd.c Proyecto: bcl/parted
static int
dasd_alloc_metadata (PedDisk* disk)
{
	PedPartition* new_part;
	PedConstraint* constraint_any = NULL;
	PedSector vtoc_end;
	LinuxSpecific* arch_specific;
	DasdDiskSpecific* disk_specific;
	PedPartition* part = NULL; /* initialize solely to placate gcc */
	PedPartition* new_part2;
	PedSector trailing_meta_start, trailing_meta_end;

	PED_ASSERT (disk != NULL);
	PED_ASSERT (disk->dev != NULL);

	arch_specific = LINUX_SPECIFIC (disk->dev);
	disk_specific = disk->disk_specific;

	constraint_any = ped_constraint_any (disk->dev);

	/* For LDL or CMS, the leading metadata ends at the sector before
	   the start of the first partition */
	if (disk_specific->format_type == 1) {
	        part = ped_disk_get_partition(disk, 1);
		if (part)
			vtoc_end = part->geom.start - 1;
		else
			vtoc_end = (PedSector) arch_specific->real_sector_size /
				   (PedSector) disk->dev->sector_size *
				   (PedSector) disk_specific->label_block;
	}
	else {
                if (disk->dev->type == PED_DEVICE_FILE)
                        arch_specific->real_sector_size = disk->dev->sector_size;
        /* Mark the start of the disk as metadata. */
		vtoc_end = (FIRST_USABLE_TRK * (long long) disk->dev->hw_geom.sectors
				   * (long long) arch_specific->real_sector_size
				   / (long long) disk->dev->sector_size) - 1;
        }

	new_part = ped_partition_new (disk,PED_PARTITION_METADATA,NULL,0,vtoc_end);
	if (!new_part)
		goto error;

	if (!ped_disk_add_partition (disk, new_part, constraint_any)) {
		ped_partition_destroy (new_part);
		goto error;
	}

	if (disk_specific->format_type == 1 && part) {
	   /*
	      For LDL or CMS there may be trailing metadata as well.
	      For example: the last block of a CMS reserved file,
	      the "recomp" area of a CMS minidisk that has been
	      formatted and then formatted again with the RECOMP
	      option specifying fewer than the maximum number of
	      cylinders, a disk that was formatted at one size,
	      backed up, then restored to a larger size disk, etc.
	   */
	   trailing_meta_start = part->geom.end + 1;
	   trailing_meta_end = (long long) disk->dev->length - 1;
	   if (trailing_meta_end >= trailing_meta_start) {
		new_part2 = ped_partition_new (disk,PED_PARTITION_METADATA,
		   NULL, trailing_meta_start, trailing_meta_end);
		if (!new_part2) {
		   ped_partition_destroy (new_part);
		   goto error;
		}
		if (!ped_disk_add_partition (disk, new_part2,
		   constraint_any)) {
		   ped_partition_destroy (new_part2);
		   ped_partition_destroy (new_part);
		   goto error;
		}
	   }
	}

	ped_constraint_destroy (constraint_any);
	return 1;

error:
	ped_constraint_destroy (constraint_any);
	return 0;
}
Ejemplo n.º 26
0
Archivo: dasd.c Proyecto: bcl/parted
static int
dasd_read (PedDisk* disk)
{
	int i;
	char str[20];
	PedDevice* dev;
	PedPartition* part;
	PedFileSystemType *fs;
	PedSector start, end;
	PedConstraint* constraint_exact;
	partition_info_t *p;
	LinuxSpecific* arch_specific;
	DasdDiskSpecific* disk_specific;
	struct fdasd_anchor anchor;

	PDEBUG;

	PED_ASSERT (disk != NULL);
	PDEBUG;
	PED_ASSERT (disk->dev != NULL);
	PDEBUG;

	dev = disk->dev;

	arch_specific = LINUX_SPECIFIC(dev);
	disk_specific = disk->disk_specific;

	PDEBUG;

	fdasd_initialize_anchor(&anchor);

	if (fdasd_get_geometry(disk->dev, &anchor, arch_specific->fd) == 0)
                goto error_close_dev;

	disk_specific->label_block = anchor.label_block;

	if ((anchor.geo.cylinders * anchor.geo.heads) > BIG_DISK_SIZE)
		anchor.big_disk++;

	/* check dasd for labels and vtoc */
	if (fdasd_check_volume(&anchor, arch_specific->fd)) {
		DasdPartitionData* dasd_data;

		/* Kernel partitioning code will report 'implicit' partitions
		 * for non-CDL format DASDs even when there is no
		 * label/VTOC.  */
		if (anchor.FBA_layout == 0)
			goto error_close_dev;

		disk_specific->format_type = 1;

		/* Register implicit partition */
		ped_disk_delete_all (disk);

		start = (PedSector) arch_specific->real_sector_size /
			(PedSector) disk->dev->sector_size *
			(PedSector) (anchor.label_block + 1);
		end = disk->dev->length - 1;
		part = ped_partition_new (disk, PED_PARTITION_NORMAL, NULL,
					  start, end);
		if (!part)
			goto error_close_dev;

		part->num = 1;
		part->fs_type = ped_file_system_probe (&part->geom);
		dasd_data = part->disk_specific;
		dasd_data->raid = 0;
		dasd_data->lvm = 0;
		dasd_data->type = 0;

		if (!ped_disk_add_partition (disk, part, NULL))
			goto error_close_dev;

		fdasd_cleanup(&anchor);

		return 1;
	}

	/* Save volume label (read by fdasd_check_volume) for writing */
	memcpy(&disk_specific->vlabel, anchor.vlabel, sizeof(volume_label_t));

	ped_disk_delete_all (disk);

	bool is_ldl = strncmp(anchor.vlabel->volkey,
			 vtoc_ebcdic_enc("LNX1", str, 4), 4) == 0;
	bool is_cms = strncmp(anchor.vlabel->volkey,
			 vtoc_ebcdic_enc("CMS1", str, 4), 4) == 0;
	if (is_ldl || is_cms) {
		DasdPartitionData* dasd_data;

		union vollabel {
			volume_label_t ldl;
			cms_volume_label_t cms;
		};
		union vollabel *cms_ptr1 = (union vollabel *) anchor.vlabel;
		cms_volume_label_t *cms_ptr = &cms_ptr1->cms;
		volume_label_t *ldl_ptr = &cms_ptr1->ldl;
		int partition_start_block;

		disk_specific->format_type = 1;

		if (is_cms && cms_ptr->usable_count >= cms_ptr->block_count)
			partition_start_block = 2;   /* FBA DASD */
		else
			partition_start_block = 3;   /* CKD DASD */

		if (is_ldl)
			start = (long long) arch_specific->real_sector_size
				/ (long long) disk->dev->sector_size
				* (long long) partition_start_block;
		else if (cms_ptr->disk_offset == 0)
			start = (long long) cms_ptr->block_size
				/ (long long) disk->dev->sector_size
				* (long long) partition_start_block;
		else
			start = (long long) cms_ptr->block_size
				/ (long long) disk->dev->sector_size
				* (long long) cms_ptr->disk_offset;

		if (is_ldl)
		   if (ldl_ptr->ldl_version >= 0xf2)
		      end = (long long) arch_specific->real_sector_size
			    / (long long) disk->dev->sector_size
			    * (long long) ldl_ptr->formatted_blocks - 1;
		   else
		      end = disk->dev->length - 1;
		else
		   if (cms_ptr->disk_offset == 0)
		      end = (long long) cms_ptr->block_size
			    / (long long) disk->dev->sector_size
			    * (long long) cms_ptr->block_count - 1;
		   else
		      /*
			 Frankly, I do not understand why the last block
			 of the CMS reserved file is not included in the
			 partition; but this is the algorithm used by the
			 Linux kernel.  See fs/partitions/ibm.c in the
			 Linux kernel source code.
		      */
		      end = (long long) cms_ptr->block_size
			    / (long long) disk->dev->sector_size
			    * (long long) (cms_ptr->block_count - 1) - 1;

		part = ped_partition_new (disk, PED_PARTITION_NORMAL, NULL, start, end);
		if (!part)
			goto error_close_dev;

		part->num = 1;
		part->fs_type = ped_file_system_probe (&part->geom);
		dasd_data = part->disk_specific;
		dasd_data->raid = 0;
		dasd_data->lvm = 0;
		dasd_data->type = 0;

		if (!ped_disk_add_partition (disk, part, NULL))
			goto error_close_dev;

		fdasd_cleanup(&anchor);

		return 1;
	}

	/* CDL format, newer */
	disk_specific->format_type = 2;

	p = anchor.first;
	PDEBUG;

	for (i = 1 ; i <= USABLE_PARTITIONS; i++) {
		char *ch = p->f1->DS1DSNAM;
		DasdPartitionData* dasd_data;


		if (p->used != 0x01)
			continue;

        PDEBUG;

		start = (long long)(long long) p->start_trk
				* (long long) disk->dev->hw_geom.sectors
				* (long long) arch_specific->real_sector_size
				/ (long long) disk->dev->sector_size;
		end   = (long long)((long long) p->end_trk + 1)
				* (long long) disk->dev->hw_geom.sectors
				* (long long) arch_specific->real_sector_size
				/ (long long) disk->dev->sector_size - 1;
		part = ped_partition_new(disk, PED_PARTITION_NORMAL, NULL,
                                         start, end);
        PDEBUG;

		if (!part)
			goto error_close_dev;

        PDEBUG;

		part->num = i;
		part->fs_type = ped_file_system_probe(&part->geom);

		vtoc_ebcdic_dec(p->f1->DS1DSNAM, p->f1->DS1DSNAM, 44);
		ch = strstr(p->f1->DS1DSNAM, "PART");

		if (ch != NULL) {
			strncpy(str, ch+9, 6);
			str[6] = '\0';
		}

		dasd_data = part->disk_specific;

		if ((strncmp(PART_TYPE_RAID, str, 6) == 0) &&
		    (ped_file_system_probe(&part->geom) == NULL))
			ped_partition_set_flag(part, PED_PARTITION_RAID, 1);
		else
			ped_partition_set_flag(part, PED_PARTITION_RAID, 0);

		if ((strncmp(PART_TYPE_LVM, str, 6) == 0) &&
		    (ped_file_system_probe(&part->geom) == NULL))
			ped_partition_set_flag(part, PED_PARTITION_LVM, 1);
		else
			ped_partition_set_flag(part, PED_PARTITION_LVM, 0);

		if (strncmp(PART_TYPE_SWAP, str, 6) == 0) {
			fs = ped_file_system_probe(&part->geom);
			if (fs && is_linux_swap(fs->name)) {
				dasd_data->system = PARTITION_LINUX_SWAP;
				PDEBUG;
			}
		}

		vtoc_ebcdic_enc(p->f1->DS1DSNAM, p->f1->DS1DSNAM, 44);

		dasd_data->type = 0;

		constraint_exact = ped_constraint_exact (&part->geom);
		if (!constraint_exact)
			goto error_close_dev;
		if (!ped_disk_add_partition(disk, part, constraint_exact)) {
			ped_constraint_destroy(constraint_exact);
			goto error_close_dev;
		}
		ped_constraint_destroy(constraint_exact);

		if (p->fspace_trk > 0) {
			start = (long long)((long long) p->end_trk + 1)
					* (long long) disk->dev->hw_geom.sectors
					* (long long) arch_specific->real_sector_size
					/ (long long) disk->dev->sector_size;
			end   = (long long)((long long) p->end_trk + 1 + p->fspace_trk)
					* (long long) disk->dev->hw_geom.sectors
					* (long long) arch_specific->real_sector_size
					/ (long long) disk->dev->sector_size - 1;
			part = ped_partition_new (disk, PED_PARTITION_NORMAL,
                                                  NULL, start, end);

			if (!part)
				goto error_close_dev;

			part->type = PED_PARTITION_FREESPACE;
			constraint_exact = ped_constraint_exact(&part->geom);

			if (!constraint_exact)
				goto error_close_dev;
			if (!ped_disk_add_partition(disk, part, constraint_exact)) {
				ped_constraint_destroy(constraint_exact);
				goto error_close_dev;
			}

			ped_constraint_destroy (constraint_exact);
		}

		p = p->next;
	}

	PDEBUG;
	fdasd_cleanup(&anchor);
	return 1;

error_close_dev:
	PDEBUG;
	fdasd_cleanup(&anchor);
	return 0;
}
Ejemplo n.º 27
0
bool MParted::MParted_Core::createPartition(MParted::Partition & new_partition, MParted::Sector min_size) {
    new_partition.partitionNumber = 0;

    if (!openDeviceAndDisk(new_partition.devicePath))
        return false;

    PedPartitionType type;
    PedPartition *pedPartition = NULL;
    PedConstraint *constraint = NULL;
    PedFileSystemType* fs_type = NULL;

    //create new partition
    switch (new_partition.type) {
        case MParted::TYPE_PRIMARY:
            type = PED_PARTITION_NORMAL;
            break;
        case MParted::TYPE_LOGICAL:
            type = PED_PARTITION_LOGICAL;
            break;
        case MParted::TYPE_EXTENDED:
            type = PED_PARTITION_EXTENDED;
            break;

        default:
            type = PED_PARTITION_FREESPACE;
    }

    if (new_partition.type != MParted::TYPE_EXTENDED)
        fs_type = ped_file_system_type_get("ext2");

    pedPartition = ped_partition_new(pedDisk, type, fs_type,
                                     new_partition.sector_start,
                                     new_partition.sector_end);

    if (!pedPartition) {
        // Clean up
        closeDeviceAndDisk();
        return false;
    }

    if (new_partition.alignment == MParted::ALIGN_MEBIBYTE) {
        PedGeometry *geom = ped_geometry_new(pedDevice,
                                             new_partition.sector_start,
                                             new_partition.getSectorLength());
        if (geom)
            constraint = ped_constraint_exact(geom);
    }
    else {
        constraint = ped_constraint_any(pedDevice);
    }


    if (constraint) {
        if (min_size > 0
                && new_partition.filesystem != MParted::FS_XFS) // Permit copying to smaller xfs partition
            constraint->min_size = min_size;

        if (ped_disk_add_partition(pedDisk, pedPartition, constraint) && commit()) {
            // Get partition path
            new_partition.path = Utils::charToStringFree(ped_partition_get_path(pedPartition)); // we have to free the result of ped_partition_get_path()

            new_partition.partitionNumber = pedPartition->num;
            new_partition.sector_start = pedPartition->geom.start;
            new_partition.sector_end = pedPartition->geom.end;
        }

        ped_constraint_destroy(constraint);
    }

    // Clean up
    closeDeviceAndDisk();


    return (new_partition.partitionNumber > 0);
}
Ejemplo n.º 28
0
Archivo: pc98.c Proyecto: Excito/parted
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;
}
Ejemplo n.º 29
0
/* We have already allocated a rdb, we are now reading it from the disk */
static int
amiga_read (PedDisk* disk)
{
	struct RigidDiskBlock *rdb;
	struct PartitionBlock *partition;
	uint32_t partblock;
	uint32_t partlist[AMIGA_MAX_PARTITIONS];
	PedSector cylblocks;
	int i;

	PED_ASSERT(disk != NULL);
	PED_ASSERT(disk->dev != NULL);
	PED_ASSERT(disk->dev->sector_size % PED_SECTOR_SIZE_DEFAULT == 0);
	PED_ASSERT(disk->disk_specific != NULL);
	rdb = RDSK(disk->disk_specific);

	if (_amiga_find_rdb (disk->dev, rdb) == AMIGA_RDB_NOT_FOUND) {
		ped_exception_throw(PED_EXCEPTION_ERROR, PED_EXCEPTION_CANCEL,
			_("%s : Didn't find rdb block, should never happen."), __func__);
		return 0;
	}

	/* Let's copy the rdb read geometry to the dev */
	/* FIXME: should this go into disk->dev->bios_geom instead? */
	disk->dev->hw_geom.cylinders = PED_BE32_TO_CPU (rdb->rdb_Cylinders);
	disk->dev->hw_geom.heads = PED_BE32_TO_CPU (rdb->rdb_Heads);
	disk->dev->hw_geom.sectors = PED_BE32_TO_CPU (rdb->rdb_Sectors);
	cylblocks = (PedSector) PED_BE32_TO_CPU (rdb->rdb_Heads) *
		(PedSector) PED_BE32_TO_CPU (rdb->rdb_Sectors);

	/* Remove all partitions in the former in memory table */
	ped_disk_delete_all (disk);

	/* Let's allocate a partition block */
	if (!(partition = ped_malloc (disk->dev->sector_size)))
		return 0;

	/* We initialize the hardblock free list to detect loops */
	for (i = 0; i < AMIGA_MAX_PARTITIONS; i++) partlist[i] = LINK_END;

	for (i = 1, partblock = PED_BE32_TO_CPU(rdb->rdb_PartitionList);
		i < AMIGA_MAX_PARTITIONS && partblock != LINK_END;
		i++, partblock = PED_BE32_TO_CPU(partition->pb_Next))
	{
		PedPartition *part;
		PedSector start, end;

		/* Let's look for loops in the partition table */
		if (_amiga_loop_check(partblock, partlist, i)) {
			break;
		}

		/* Let's allocate and read a partition block to get its geometry*/
		if (!_amiga_read_block (disk->dev, AMIGA(partition),
		                        (PedSector)partblock, NULL)) {
			free(partition);
			return 0;
		}

		start = ((PedSector) PED_BE32_TO_CPU (partition->de_LowCyl))
			* cylblocks;
		end = (((PedSector) PED_BE32_TO_CPU (partition->de_HighCyl))
			+ 1) * cylblocks - 1;

		/* We can now construct a new partition */
		if (!(part = ped_partition_new (disk, PED_PARTITION_NORMAL,
                                                NULL, start, end))) {
			free(partition);
			return 0;
		}
		/* And copy over the partition block */
		memcpy(part->disk_specific, partition, 256);

		part->num = i;
		part->type = 0;
		/* Let's probe what file system is present on the disk */
		part->fs_type = ped_file_system_probe (&part->geom);

		PedConstraint *constraint_exact
			= ped_constraint_exact (&part->geom);
		if (constraint_exact == NULL)
			return 0;
		bool ok = ped_disk_add_partition (disk, part, constraint_exact);
		ped_constraint_destroy (constraint_exact);
		if (!ok) {
			ped_partition_destroy(part);
			free(partition);
			return 0;
		}
	}
	free(partition);
	return 1;
}