Example #1
0
bool LibPartedPartitionTable::updateGeometry(Report& report, const Partition& partition, qint64 sector_start, qint64 sector_end)
{
    Q_ASSERT(partition.devicePath() == QString::fromUtf8(pedDevice()->path));

    bool rval = false;

    PedPartition* pedPartition = (partition.roles().has(PartitionRole::Extended))
                                 ? ped_disk_extended_partition(pedDisk())
                                 : ped_disk_get_partition_by_sector(pedDisk(), partition.firstSector());

    if (pedPartition) {
        if (PedGeometry* pedGeometry = ped_geometry_new(pedDevice(), sector_start, sector_end - sector_start + 1)) {
            if (PedConstraint* pedConstraint = ped_constraint_exact(pedGeometry)) {
                if (ped_disk_set_partition_geom(pedDisk(), pedPartition, pedConstraint, sector_start, sector_end))
                    rval = true;
                else
                    report.line() << xi18nc("@info:progress", "Could not set geometry for partition <filename>%1</filename> while trying to resize/move it.", partition.deviceNode());
                ped_constraint_destroy(pedConstraint);
            } else
                report.line() << xi18nc("@info:progress", "Could not get constraint for partition <filename>%1</filename> while trying to resize/move it.", partition.deviceNode());
            ped_geometry_destroy(pedGeometry);
        } else
            report.line() << xi18nc("@info:progress", "Could not get geometry for partition <filename>%1</filename> while trying to resize/move it.", partition.deviceNode());
    } else
        report.line() << xi18nc("@info:progress", "Could not open partition <filename>%1</filename> while trying to resize/move it.", partition.deviceNode());

    return rval;
}
Example #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;
}
Example #3
0
PyObject *py_ped_constraint_exact(PyObject *s, PyObject *args) {
    PyObject *in_geometry = NULL;
    PedGeometry *out_geometry = NULL;
    PedConstraint *constraint = NULL;
    _ped_Constraint *ret = NULL;

    if (!PyArg_ParseTuple(args, "O!", &_ped_Geometry_Type_obj, &in_geometry)) {
        return NULL;
    }

    out_geometry = _ped_Geometry2PedGeometry(in_geometry);
    if (out_geometry == NULL) {
        return NULL;
    }

    constraint = ped_constraint_exact(out_geometry);
    if (constraint) {
        ret = PedConstraint2_ped_Constraint(constraint);
    }
    else {
        PyErr_SetString(CreateException, "Could not create exact constraint");
        return NULL;
    }

    ped_constraint_destroy(constraint);

    return (PyObject *) ret;
}
Example #4
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;
}
bool MParted::MParted_Core::resizePartition(MParted::Partition & partition_old, MParted::Partition & partition_new) {
    if (partition_new.getSectorLength() == partition_old.getSectorLength()
            && partition_new.sector_start == partition_old.sector_start)
        return true; // New and old partition have the same size and position. Hence skipping this operation

    bool return_value = false;

    PedConstraint *constraint = NULL;
    PedPartition *pedPartition = NULL;

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


    if (partition_old.type == MParted::TYPE_EXTENDED)
        pedPartition = ped_disk_extended_partition(pedDisk);
    else
        pedPartition = ped_disk_get_partition_by_sector(pedDisk, partition_old.getSector());

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

        if (constraint) {
            if (ped_disk_set_partition_geom(pedDisk,
                              pedPartition,
                              constraint,
                              partition_new.sector_start,
                              partition_new.sector_end)
                    && commit())
            {
                partition_new.sector_start = pedPartition->geom.start;
                partition_new.sector_end = pedPartition->geom.end;

                return_value = true;
            }

            ped_constraint_destroy(constraint);
        }
    }

    closeDeviceAndDisk();

    return return_value;
}
Example #6
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;
}
Example #7
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;
}
Example #8
0
File: dasd.c Project: 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;
}
Example #9
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;
	strncpy (boot_name, vh.vh_bootfile, BFNAMESIZE);
	boot_name[BFNAMESIZE] = 0;

	/* 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;
}
Example #10
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;
}
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);
}