コード例 #1
0
ファイル: xfs.c プロジェクト: inteos/WBSAirback
static PedGeometry*
xfs_probe (PedGeometry* geom)
{
	PedSector	block_size;
	PedSector	block_count;
	union {
		struct xfs_sb	sb;
		char		bytes [512];
	} buf;

	if (geom->length < XFS_SB_DADDR + 1)
		return NULL;
	if (!ped_geometry_read (geom, &buf, XFS_SB_DADDR, 1))
		return NULL;

	if (PED_LE32_TO_CPU (buf.sb.sb_magicnum) == XFS_SB_MAGIC) {
		block_size = PED_LE32_TO_CPU (buf.sb.sb_blocksize) / 512;
		block_count = PED_LE64_TO_CPU (buf.sb.sb_dblocks);

		return ped_geometry_new (geom->dev, geom->start,
					 block_size * block_count);
	}

	if (PED_BE32_TO_CPU (buf.sb.sb_magicnum) == XFS_SB_MAGIC) {
		block_size = PED_BE32_TO_CPU (buf.sb.sb_blocksize) / 512;
		block_count = PED_BE64_TO_CPU (buf.sb.sb_dblocks);

		return ped_geometry_new (geom->dev, geom->start,
					 block_size * block_count);
	}

	return NULL;
}
コード例 #2
0
ファイル: ufs.c プロジェクト: Excito/parted
static PedGeometry*
ufs_probe_sun (PedGeometry* geom)
{
	int8_t buf[512 * 3];
	struct ufs_super_block *sb;

	if (geom->length < 5)
		return 0;
	if (!ped_geometry_read (geom, buf, 16, 3))
		return 0;

	sb = (struct ufs_super_block *)buf;

	if (PED_BE32_TO_CPU(sb->fs_magic) == UFS_MAGIC) {
		PedSector block_size = PED_BE32_TO_CPU(sb->fs_bsize) / 512;
		PedSector block_count = PED_BE32_TO_CPU(sb->fs_size);
		return ped_geometry_new (geom->dev, geom->start,
					 block_size * block_count);
	}
	if (PED_LE32_TO_CPU(sb->fs_magic) == UFS_MAGIC) {
		PedSector block_size = PED_LE32_TO_CPU(sb->fs_bsize) / 512;
		PedSector block_count = PED_LE32_TO_CPU(sb->fs_size);
		return ped_geometry_new (geom->dev, geom->start,
					 block_size * block_count);
	}
	return NULL;
}
コード例 #3
0
bool LibPartedPartitionTable::resizeFileSystem(Report& report, const Partition& partition, qint64 newLength)
{
    bool rval = false;

#if defined LIBPARTED_FS_RESIZE_LIBRARY_SUPPORT
    if (PedGeometry* originalGeometry = ped_geometry_new(pedDevice(), partition.fileSystem().firstSector(), partition.fileSystem().length())) {
        if (PedFileSystem* pedFileSystem = ped_file_system_open(originalGeometry)) {
            if (PedGeometry* resizedGeometry = ped_geometry_new(pedDevice(), partition.fileSystem().firstSector(), newLength)) {
                PedTimer* pedTimer = ped_timer_new(pedTimerHandler, nullptr);
                rval = ped_file_system_resize(pedFileSystem, resizedGeometry, pedTimer);
                ped_timer_destroy(pedTimer);

                if (!rval)
                    report.line() << xi18nc("@info:progress", "Could not resize file system on partition <filename>%1</filename>.", partition.deviceNode());
                ped_geometry_destroy(resizedGeometry);
            } else
                report.line() << xi18nc("@info:progress", "Could not get geometry for resized partition <filename>%1</filename> while trying to resize the file system.", partition.deviceNode());

            ped_file_system_close(pedFileSystem);
        } else
            report.line() << xi18nc("@info:progress", "Could not open partition <filename>%1</filename> while trying to resize the file system.", partition.deviceNode());
        ped_geometry_destroy(originalGeometry);
    } else
        report.line() << xi18nc("@info:progress", "Could not read geometry for partition <filename>%1</filename> while trying to resize the file system.", partition.deviceNode());
#else
    Q_UNUSED(report);
    Q_UNUSED(partition);
    Q_UNUSED(newLength);
#endif

    return rval;
}
コード例 #4
0
ファイル: hfs.c プロジェクト: Excito/parted
static int
hfsplus_clobber (PedGeometry* geom)
{
	unsigned int i = 1;
	uint8_t				buf[PED_SECTOR_SIZE_DEFAULT];
	HfsMasterDirectoryBlock		*mdb;

	mdb = (HfsMasterDirectoryBlock *) buf;

	if (!ped_geometry_read (geom, buf, 2, 1))
		return 0;

	if (PED_BE16_TO_CPU (mdb->signature) == HFS_SIGNATURE) {
		/* embedded hfs+ */
		PedGeometry	*embedded;

		i = PED_BE32_TO_CPU(mdb->block_size) / PED_SECTOR_SIZE_DEFAULT;
		embedded = ped_geometry_new (
		    geom->dev,
		    (PedSector) geom->start
		     + PED_BE16_TO_CPU (mdb->start_block)
		     + (PedSector) PED_BE16_TO_CPU (
			mdb->old_new.embedded.location.start_block ) * i,
		    (PedSector) PED_BE16_TO_CPU (
			mdb->old_new.embedded.location.block_count ) * i );
		if (!embedded) i = 0;
		else {
			i = hfs_clobber (embedded);
			ped_geometry_destroy (embedded);
		}
	}

	/* non-embedded or envelop destroy as hfs */
	return ( hfs_clobber (geom) && i );
}
コード例 #5
0
ファイル: loop.c プロジェクト: Excito/parted
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;
}
コード例 #6
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;
}
コード例 #7
0
/**
 * Return the nearest region to \p geom that satisfy a \p constraint.
 *
 * Note that "nearest" is somewhat ambiguous.  This function makes
 * no guarantees about how this ambiguity is resovled.
 *
 * \return PedGeometry, or NULL when a \p constrain cannot be satisfied
 */
PedGeometry*
ped_constraint_solve_nearest (
	const PedConstraint* constraint, const PedGeometry* geom)
{
	PedSector	start;
	PedSector	end;
	PedGeometry*	result;

	if (constraint == NULL)
		return NULL;

	PED_ASSERT (geom != NULL);
	PED_ASSERT (constraint->start_range->dev == geom->dev);

	start = _constraint_get_nearest_start_soln (constraint, geom->start);
	if (start == -1)
		return NULL;
	end = _constraint_get_nearest_end_soln (constraint, start, geom->end);
	if (end == -1)
		return NULL;

	result = ped_geometry_new (geom->dev, start, end - start + 1);
	if (!result)
		return NULL;
	PED_ASSERT (ped_constraint_is_solution (constraint, result));
	return result;
}
コード例 #8
0
ファイル: reiserfs.c プロジェクト: NekPoN/parted
static PedGeometry *reiserfs_probe(PedGeometry *geom)
{
	int i;
	reiserfs_super_block_t sb;

	PED_ASSERT(geom != NULL);

	for (i = 0; reiserfs_super_offset[i] != -1; i++) {
		if (reiserfs_super_offset[i] >= geom->length)
			continue;
		if (!ped_geometry_read (geom, &sb, reiserfs_super_offset[i], 1))
			continue;

		if (strncmp(REISERFS_SIGNATURE, sb.s_magic,
		            strlen(REISERFS_SIGNATURE)) == 0
		    || strncmp(REISER2FS_SIGNATURE, sb.s_magic,
			       strlen(REISER2FS_SIGNATURE)) == 0
		    || strncmp(REISER3FS_SIGNATURE, sb.s_magic,
			       strlen(REISER3FS_SIGNATURE)) == 0) {
			PedSector block_size;
			PedSector block_count;

			block_size = PED_LE16_TO_CPU(sb.s_blocksize)
					/ PED_SECTOR_SIZE_DEFAULT;
			block_count = PED_LE32_TO_CPU(sb.s_block_count);

			return ped_geometry_new(geom->dev, geom->start,
						block_size * block_count);
		}
	}
	return NULL;
}
コード例 #9
0
ファイル: jfs.c プロジェクト: unsound/parted-freebsd
static PedGeometry*
jfs_probe (PedGeometry* geom)
{
	union {
		struct superblock	sb;
		char			bytes[512];
	} buf;

        /* FIXME: for now, don't even try to deal with larger sector size.  */
	if (geom->dev->sector_size != PED_SECTOR_SIZE_DEFAULT)
		return NULL;

	if (geom->length < JFS_SUPER_SECTOR + 1)
		return NULL;
	if (!ped_geometry_read (geom, &buf, JFS_SUPER_SECTOR, 1))
		return NULL;

	if (strncmp (buf.sb.s_magic, JFS_MAGIC, 4) == 0) {
		PedSector block_size = PED_LE32_TO_CPU (buf.sb.s_pbsize) / 512;
		PedSector block_count = PED_LE64_TO_CPU (buf.sb.s_size);

		return ped_geometry_new (geom->dev, geom->start,
					 block_size * block_count);
	} else {
		return NULL;
	}
}
コード例 #10
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;
}
コード例 #11
0
ファイル: unit.c プロジェクト: Excito/parted
static PedGeometry*
geometry_from_centre_radius (const PedDevice* dev,
                             PedSector sector, PedSector radius)
{
	PedSector start = clip (dev, sector - radius);
	PedSector end = clip (dev, sector + radius);
	if (sector - end > radius || start - sector > radius)
		return NULL;
	return ped_geometry_new (dev, start, end - start + 1);
}
コード例 #12
0
ファイル: loop.c プロジェクト: 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;
}
コード例 #13
0
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;
}
コード例 #14
0
ファイル: ufs.c プロジェクト: Excito/parted
static PedGeometry*
ufs_probe_hp (PedGeometry* geom)
{
	int8_t buf[1536];
	struct ufs_super_block *sb;
	PedSector block_size;
	PedSector block_count;

	if (geom->length < 5)
		return 0;
	if (!ped_geometry_read (geom, buf, 16, 3))
		return 0;

	sb = (struct ufs_super_block *)buf;

	/* Try sane bytesex */
	switch (PED_BE32_TO_CPU(sb->fs_magic)) {
		case UFS_MAGIC_LFN:
		case UFS_MAGIC_FEA:
		case UFS_MAGIC_4GB:
			block_size = PED_BE32_TO_CPU(sb->fs_bsize) / 512;
			block_count = PED_BE32_TO_CPU(sb->fs_size);
			return ped_geometry_new (geom->dev, geom->start,
						 block_size * block_count);
	}

	/* Try perverted bytesex */
	switch (PED_LE32_TO_CPU(sb->fs_magic)) {
		case UFS_MAGIC_LFN:
		case UFS_MAGIC_FEA:
		case UFS_MAGIC_4GB:
			block_size = PED_LE32_TO_CPU(sb->fs_bsize) / 512;
			block_count = PED_LE32_TO_CPU(sb->fs_size);
			return ped_geometry_new (geom->dev, geom->start,
						 block_size * block_count);
	}
	return NULL;
}
コード例 #15
0
ファイル: pygeom.c プロジェクト: KaneVanguard/pyparted
int _ped_Geometry_init(_ped_Geometry *self, PyObject *args, PyObject *kwds) {
    static char *kwlist[] = {"dev", "start", "length", "end", NULL};
    PedDevice *device = NULL;
    long long start, length, end;

    self->dev = NULL;
    self->ped_geometry = NULL;

    if (kwds == NULL) {
        if (!PyArg_ParseTuple(args, "O!LL|L", &_ped_Device_Type_obj, &self->dev,
                              &start, &length, &end)) {
            self->dev = NULL;
            return -1;
        }
    } else {
        if (!PyArg_ParseTupleAndKeywords(args, kwds, "O!LL|L", kwlist,
                                         &_ped_Device_Type_obj, &self->dev,
                                         &start, &length, &end)) {
            self->dev = NULL;
            return -2;
        }
    }

    device = _ped_Device2PedDevice(self->dev);
    if (device == NULL) {
        self->dev = NULL;
        return -3;
    }
    self->ped_geometry = ped_geometry_new(device, start, length);

    if (self->ped_geometry == NULL) {
        if (partedExnRaised) {
            partedExnRaised = 0;

            if (!PyErr_ExceptionMatches(PartedException) &&
                    !PyErr_ExceptionMatches(PyExc_NotImplementedError)) {
                PyErr_SetString(CreateException, partedExnMessage);
            }
        } else {
            PyErr_SetString(CreateException, "Could not create new geometry");
        }

        self->dev = NULL;
        return -3;
    }

    Py_INCREF(self->dev);

    return 0;
}
コード例 #16
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;
}
コード例 #17
0
ファイル: ntfs.c プロジェクト: schidler/flyzjhz-rt-n56u
static PedGeometry*
ntfs_probe (PedGeometry* geom)
{
    char	buf[512];

    if (!ped_geometry_read (geom, buf, 0, 1))
        return 0;

    if (strncmp (NTFS_SIGNATURE, buf + 3, strlen (NTFS_SIGNATURE)) == 0)
        return ped_geometry_new (geom->dev, geom->start,
                                 PED_LE64_TO_CPU (*(uint64_t*)
                                         (buf + 0x28)));
    else
        return NULL;
}
コード例 #18
0
ファイル: ui.c プロジェクト: bcl/parted
int
command_line_get_sector (const char* prompt, PedDevice* dev, PedSector* value,
                         PedGeometry** range, char** raw_input)
{
        char*    def_str;
        char*    input;
        int      valid;

        def_str = ped_unit_format (dev, *value);
        input = command_line_get_word (prompt, *value ? def_str : NULL,
                                       NULL, 1);

        /* def_str might have rounded *value a little bit.  If the user picked
         * the default, make sure the selected sector is identical to the
         * default.
         */
        if (input && *value && !strcmp (input, def_str)) {
                if (range) {
                        *range = ped_geometry_new (dev, *value, 1);
                        free (def_str);
                        free (input);
                        return *range != NULL;
                }

                free (def_str);
                free (input);
                return 1;
        }

        free (def_str);
        if (!input) {
                *value = 0;
                if (range)
                        *range = NULL;
                return 0;
        }

        valid = ped_unit_parse (input, dev, value, range);

        if (raw_input)
            *raw_input = input;
        else
            free (input);
        return valid;
}
コード例 #19
0
static PedGeometry*
jfs_probe (PedGeometry* geom)
{
	union {
		struct superblock	sb;
		char			bytes[512];
	} buf;

	if (geom->length < JFS_SUPER_SECTOR + 1)
		return NULL;
	if (!ped_geometry_read (geom, &buf, JFS_SUPER_SECTOR, 1))
		return NULL;

	if (strncmp (buf.sb.s_magic, JFS_MAGIC, 4) == 0) {
		PedSector block_size = PED_LE32_TO_CPU (buf.sb.s_pbsize) / 512;
		PedSector block_count = PED_LE64_TO_CPU (buf.sb.s_size);

		return ped_geometry_new (geom->dev, geom->start,
					 block_size * block_count);
	} else {
		return NULL;
	}
}
コード例 #20
0
ファイル: probe.c プロジェクト: Excito/parted
/* Used by hfsplus_probe and hfs_probe */
PedGeometry*
hfs_and_wrapper_probe (PedGeometry* geom)
{
	uint8_t		buf[PED_SECTOR_SIZE_DEFAULT];
	HfsMasterDirectoryBlock	*mdb;
	PedGeometry*	geom_ret;
	PedSector	search, max;

	PED_ASSERT (geom != NULL);
	PED_ASSERT (hfsc_can_use_geom (geom));

	mdb = (HfsMasterDirectoryBlock *) buf;

	/* is 5 an intelligent value ? */
	if ((geom->length < 5)
	    || (!ped_geometry_read (geom, buf, 2, 1))
	    || (mdb->signature != PED_CPU_TO_BE16 (HFS_SIGNATURE)) )
		return NULL;

	search = ((PedSector) PED_BE16_TO_CPU (mdb->start_block)
		  + ((PedSector) PED_BE16_TO_CPU (mdb->total_blocks)
		     * (PED_BE32_TO_CPU (mdb->block_size) / PED_SECTOR_SIZE_DEFAULT )));
	max = search + (PED_BE32_TO_CPU (mdb->block_size) / PED_SECTOR_SIZE_DEFAULT);
	if (!(geom_ret = ped_geometry_new (geom->dev, geom->start, search + 2)))
		return NULL;

	for (; search < max; search++) {
		if (!ped_geometry_set (geom_ret, geom_ret->start, search + 2)
		    || !ped_geometry_read (geom_ret, buf, search, 1))
			break;
		if (mdb->signature == PED_CPU_TO_BE16 (HFS_SIGNATURE))
			return geom_ret;
	}

	ped_geometry_destroy (geom_ret);
	return NULL;
}
コード例 #21
0
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();
}
コード例 #22
0
ファイル: disk.c プロジェクト: markdryan/clr-cloud-init
gboolean disk_resize_grow(const gchar* disk_path, GChildWatchFunc async_func_watcher, gpointer data) {
	char command[LINE_MAX] = { 0 };
	int last_partition_num;
	const gchar* partition_path;
	PedDevice* dev = NULL;
	PedDisk* disk = NULL;
	gboolean result = false;
	PedPartition* partition;
	PedSector start;
	PedSector end;
	PedGeometry geometry_start;
	PedGeometry* geometry_end;
	PedConstraint* constraint;

	resize_fs = false;

	/* to handle exceptions, i.e Fix PMBR */
	ped_exception_set_handler(disk_exception_handler);

	if (!disk_path) {
		LOG(MOD "Disk path is empty\n");
		return false;
	}

	dev = ped_device_get(disk_path);

	if (!dev) {
		LOG(MOD "Cannot get device '%s'\n", disk_path);
		return false;
	}

	/*
	* verify disk, disk_exception_handler will called
	* if the disk has problems and it needs to be fixed
	* and resized
	*/
	disk = ped_disk_new(dev);

	if (!disk) {
		LOG(MOD "Cannot create a new disk '%s'\n", disk_path);
		return false;
	}

	if (!resize_fs) {
		/* do not resize filesystem, it is ok */
		LOG(MOD "Nothing to do with '%s' disk\n", disk_path);
		return false;
	}

	LOG(MOD "Resizing filesystem disk '%s'\n", disk_path);

	last_partition_num = ped_disk_get_last_partition_num(disk);
	partition = ped_disk_get_partition(disk, last_partition_num);

	if (!partition) {
		LOG(MOD "Cannot get partition '%d' disk '%s'\n", last_partition_num, disk_path);
		return false;
	}

	start = partition->geom.start;
	end = (-PED_MEGABYTE_SIZE) / dev->sector_size + dev->length;

	geometry_start.dev = dev;
	geometry_start.start = start;
	geometry_start.end = end;
	geometry_start.length = 1;

	geometry_end = ped_geometry_new(dev, end, 1);

	if (!geometry_end) {
		LOG(MOD "Cannot get partition '%d' disk '%s'\n", last_partition_num, disk_path);
		return false;
	}

	constraint = ped_constraint_new(ped_alignment_any, ped_alignment_any, &geometry_start, geometry_end, 1, dev->length);

	if (!constraint) {
		LOG(MOD "Cannot create a new constraint disk '%s'\n", disk_path);
		goto fail1;
	}

	if (!ped_disk_set_partition_geom(disk, partition, constraint, start, end)) {
		LOG(MOD "Cannot set partition geometry disk '%s'\n", disk_path);
		goto fail2;
	}

	if (!ped_disk_commit(disk)) {
		LOG(MOD "Cannot write the partition table to disk '%s'\n", disk_path);
		goto fail2;
	}

	partition_path = ped_partition_get_path(partition);

	if (!partition_path) {
		LOG(MOD "Cannot get partition path disk '%s'\n", disk_path);
		goto fail2;
	}

	snprintf(command, LINE_MAX, RESIZEFS_PATH " %s", partition_path);
	exec_task_async(command, async_func_watcher, data);

	result = true;
	LOG(MOD "Resizing filesystem done\n");

fail2:
	ped_constraint_destroy (constraint);
fail1:
	ped_geometry_destroy (geometry_end);
	return result;
}
コード例 #23
0
ファイル: unit.c プロジェクト: Excito/parted
static int
parse_chs (const char* str, const PedDevice* dev, PedSector* sector,
		PedGeometry** range)
{
	PedSector cyl_size = dev->bios_geom.heads * dev->bios_geom.sectors;
	PedCHSGeometry chs;

	char* copy = ped_strdup (str);
	if (!copy)
		return 0;
	strip_string (copy);
	remove_punct (copy);

	if (sscanf (copy, "%d %d %d",
		    &chs.cylinders, &chs.heads, &chs.sectors) != 3) {
		ped_exception_throw (
				PED_EXCEPTION_ERROR, PED_EXCEPTION_CANCEL,
				_("\"%s\" has invalid syntax for locations."),
				copy);
		goto error_free_copy;
	}

	if (chs.heads >= dev->bios_geom.heads) {
		ped_exception_throw (
				PED_EXCEPTION_ERROR, PED_EXCEPTION_CANCEL,
				_("The maximum head value is %d."),
				dev->bios_geom.heads - 1);
		goto error_free_copy;
	}
	if (chs.sectors >= dev->bios_geom.sectors) {
		ped_exception_throw (
				PED_EXCEPTION_ERROR, PED_EXCEPTION_CANCEL,
				_("The maximum sector value is %d."),
				dev->bios_geom.sectors - 1);
		goto error_free_copy;
	}

	*sector = 1LL * chs.cylinders * cyl_size
		+ chs.heads * dev->bios_geom.sectors
		+ chs.sectors;

	if (*sector >= dev->length) {
		ped_exception_throw (
				PED_EXCEPTION_ERROR, PED_EXCEPTION_CANCEL,
				_("The location %s is outside of the "
				  "device %s."),
				str, dev->path);
		goto error_free_copy;
	}
	if (range)
		*range = ped_geometry_new (dev, *sector, 1);
	free (copy);
	return !range || *range != NULL;

error_free_copy:
	free (copy);
	*sector = 0;
	if (range)
		*range = NULL;
	return 0;
}
コード例 #24
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);
}
コード例 #25
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;
}
コード例 #26
0
ファイル: hfs.c プロジェクト: Excito/parted
int
hfsplus_resize (PedFileSystem* fs, PedGeometry* geom, PedTimer* timer)
{
	HfsPPrivateFSData* 	priv_data;
	PedTimer*		timer_plus;
	PedGeometry*		embedded_geom;
	PedSector		hgms;

	/* check preconditions */
	PED_ASSERT (fs != NULL);
	PED_ASSERT (fs->geom != NULL);
	PED_ASSERT (geom != NULL);
	PED_ASSERT (fs->geom->dev == geom->dev);
#ifdef DEBUG
        PED_ASSERT ((hgms = hfsplus_get_min_size (fs)) != 0);
#else
        if ((hgms = hfsplus_get_min_size (fs)) == 0)
                return 0;
#endif

	if (ped_geometry_test_equal(fs->geom, geom))
		return 1;

	priv_data = (HfsPPrivateFSData*) fs->type_specific;

	if (fs->geom->start != geom->start
	    || geom->length > fs->geom->length
	    || geom->length < hgms) {
		ped_exception_throw (
			PED_EXCEPTION_NO_FEATURE,
			PED_EXCEPTION_CANCEL,
			_("Sorry, HFS+ cannot be resized that way yet."));
		return 0;
	}

	if (priv_data->wrapper) {
		PedSector		red, hgee;
		HfsPrivateFSData* 	hfs_priv_data = (HfsPrivateFSData*)
					    priv_data->wrapper->type_specific;
		unsigned int		hfs_sect_block =
			    PED_BE32_TO_CPU (hfs_priv_data->mdb->block_size)
			    / PED_SECTOR_SIZE_DEFAULT;

		/* There is a wrapper so we must calculate the new geometry
		   of the embedded HFS+ volume */
		red = ( (fs->geom->length - geom->length + hfs_sect_block - 1)
			/ hfs_sect_block ) * hfs_sect_block;
		/* Can't we shrink the hfs+ volume by the desired size ? */
		hgee = hfsplus_get_empty_end (fs);
		if (!hgee) return 0;
		if (red > priv_data->plus_geom->length - hgee) {
			/* No, shrink hfs+ by the greatest possible value */
			hgee = ((hgee + hfs_sect_block - 1) / hfs_sect_block)
			       * hfs_sect_block;
			red = priv_data->plus_geom->length - hgee;
		}
		embedded_geom = ped_geometry_new (geom->dev,
						  priv_data->plus_geom->start,
						  priv_data->plus_geom->length
						  - red);

		/* There is a wrapper so the resize process is a two stages
		   process (embedded resizing then wrapper resizing) :
		   we create a sub timer */
		ped_timer_reset (timer);
		ped_timer_set_state_name (timer,
					  _("shrinking embedded HFS+ volume"));
		ped_timer_update(timer, 0.0);
		timer_plus = ped_timer_new_nested (timer, 0.98);
	} else {
		/* No wrapper : the desired geometry is the desired
		   HFS+ volume geometry */
		embedded_geom = geom;
		timer_plus = timer;
	}

	/* Resize the HFS+ volume */
	if (!hfsplus_volume_resize (fs, embedded_geom, timer_plus)) {
		if (timer_plus != timer) ped_timer_destroy_nested (timer_plus);
		ped_exception_throw (
			PED_EXCEPTION_ERROR,
			PED_EXCEPTION_CANCEL,
			_("Resizing the HFS+ volume has failed."));
		return 0;
	}

	if (priv_data->wrapper) {
		ped_geometry_destroy (embedded_geom);
		ped_timer_destroy_nested (timer_plus);
		ped_timer_set_state_name(timer, _("shrinking HFS wrapper"));
		timer_plus = ped_timer_new_nested (timer, 0.02);
		/* There's a wrapper : second stage = resizing it */
		if (!hfsplus_wrapper_update (fs)
		    || !hfs_resize (priv_data->wrapper, geom, timer_plus)) {
			ped_timer_destroy_nested (timer_plus);
			ped_exception_throw (
				PED_EXCEPTION_ERROR,
				PED_EXCEPTION_CANCEL,
				_("Updating the HFS wrapper has failed."));
			return 0;
		}
		ped_timer_destroy_nested (timer_plus);
	}
	ped_timer_update(timer, 1.0);

	return 1;
}
コード例 #27
0
ファイル: hfs.c プロジェクト: Excito/parted
PedFileSystem*
hfsplus_open (PedGeometry* geom)
{
	uint8_t			buf[PED_SECTOR_SIZE_DEFAULT];
	PedFileSystem*		fs;
	HfsPVolumeHeader*	vh;
	HfsPPrivateFSData* 	priv_data;
	PedGeometry*		wrapper_geom;
	unsigned int		map_sectors;

	if (!hfsc_can_use_geom (geom))
		return NULL;

	fs = (PedFileSystem*) ped_malloc (sizeof (PedFileSystem));
	if (!fs) goto hpo;
	vh = (HfsPVolumeHeader*) ped_malloc (sizeof (HfsPVolumeHeader));
	if (!vh) goto hpo_fs;
	priv_data = (HfsPPrivateFSData*)ped_malloc (sizeof (HfsPPrivateFSData));
	if (!priv_data) goto hpo_vh;

	fs->geom = ped_geometry_duplicate (geom);
	if (!fs->geom) goto hpo_pd;
	fs->type_specific = (void*) priv_data;

	if ((wrapper_geom = hfs_and_wrapper_probe (geom))) {
		HfsPrivateFSData* 	hfs_priv_data;
		PedSector		abs_sect, length;
		unsigned int		bs;

		ped_geometry_destroy (wrapper_geom);
		priv_data->wrapper = hfs_open(geom);
		if (!priv_data->wrapper) goto hpo_gm;
		hfs_priv_data = (HfsPrivateFSData*)
			priv_data->wrapper->type_specific;
		bs = PED_BE32_TO_CPU (hfs_priv_data->mdb->block_size)
		     / PED_SECTOR_SIZE_DEFAULT;
		abs_sect = (PedSector) geom->start
			   + (PedSector) PED_BE16_TO_CPU (
					    hfs_priv_data->mdb->start_block)
			   + (PedSector) PED_BE16_TO_CPU (
					    hfs_priv_data->mdb->old_new
					    .embedded.location.start_block )
			                 * bs;
		length = (PedSector) PED_BE16_TO_CPU (
					    hfs_priv_data->mdb->old_new
					    .embedded.location.block_count)
				     * bs;
		priv_data->plus_geom = ped_geometry_new (geom->dev, abs_sect,
							 length);
		if (!priv_data->plus_geom) goto hpo_wr;
		priv_data->free_geom = 1;
	} else {
		priv_data->wrapper = NULL;
		priv_data->plus_geom = fs->geom;
		priv_data->free_geom = 0;
	}

	if (!ped_geometry_read (priv_data->plus_geom, buf, 2, 1)) goto hpo_pg;
	memcpy (vh, buf, sizeof (HfsPVolumeHeader));
	priv_data->vh = vh;

	if (vh->signature != PED_CPU_TO_BE16(HFSP_SIGNATURE)
	    && vh->signature != PED_CPU_TO_BE16(HFSX_SIGNATURE)) {
		ped_exception_throw (
			PED_EXCEPTION_BUG,
			PED_EXCEPTION_CANCEL,
			_("No valid HFS[+X] signature has been found while "
			  "opening."));
		goto hpo_pg;
	}

	if (vh->signature == PED_CPU_TO_BE16(HFSP_SIGNATURE)
	    && vh->version != PED_CPU_TO_BE16(HFSP_VERSION)) {
		if (ped_exception_throw (
			PED_EXCEPTION_NO_FEATURE,
			PED_EXCEPTION_IGNORE_CANCEL,
			_("Version %d of HFS+ isn't supported."),
			PED_BE16_TO_CPU(vh->version))
				!= PED_EXCEPTION_IGNORE)
			goto hpo_pg;
	}

	if (vh->signature == PED_CPU_TO_BE16(HFSX_SIGNATURE)
	    && vh->version != PED_CPU_TO_BE16(HFSX_VERSION)) {
		if (ped_exception_throw (
			PED_EXCEPTION_NO_FEATURE,
			PED_EXCEPTION_IGNORE_CANCEL,
			_("Version %d of HFSX isn't supported."),
			PED_BE16_TO_CPU(vh->version))
				!= PED_EXCEPTION_IGNORE)
			goto hpo_pg;
	}

	priv_data->jib_start_block = 0;
	priv_data->jl_start_block = 0;
	if (vh->attributes & PED_CPU_TO_BE32(1<<HFSP_JOURNALED)) {
		if (!hfsj_replay_journal(fs))
			goto hpo_pg;
	}

	priv_data->bad_blocks_loaded = 0;
	priv_data->bad_blocks_xtent_nb = 0;
	priv_data->bad_blocks_xtent_list = NULL;
	priv_data->extents_file =
		hfsplus_file_open (fs, PED_CPU_TO_BE32 (HFS_XTENT_ID),
				   vh->extents_file.extents,
				   PED_BE64_TO_CPU (
					vh->extents_file.logical_size )
				   / PED_SECTOR_SIZE_DEFAULT);
	if (!priv_data->extents_file) goto hpo_pg;
	priv_data->catalog_file =
		hfsplus_file_open (fs, PED_CPU_TO_BE32 (HFS_CATALOG_ID),
				   vh->catalog_file.extents,
				   PED_BE64_TO_CPU (
					vh->catalog_file.logical_size )
				   / PED_SECTOR_SIZE_DEFAULT);
	if (!priv_data->catalog_file) goto hpo_ce;
	priv_data->attributes_file =
		hfsplus_file_open (fs, PED_CPU_TO_BE32 (HFSP_ATTRIB_ID),
				   vh->attributes_file.extents,
				   PED_BE64_TO_CPU (
					vh->attributes_file.logical_size)
				   / PED_SECTOR_SIZE_DEFAULT);
	if (!priv_data->attributes_file) goto hpo_cc;

	map_sectors = ( PED_BE32_TO_CPU (vh->total_blocks)
	                + PED_SECTOR_SIZE_DEFAULT * 8 - 1 )
		      / (PED_SECTOR_SIZE_DEFAULT * 8);
	priv_data->dirty_alloc_map = (uint8_t*)
		ped_malloc ((map_sectors + 7) / 8);
	if (!priv_data->dirty_alloc_map) goto hpo_cl;
	memset(priv_data->dirty_alloc_map, 0, (map_sectors + 7) / 8);
	priv_data->alloc_map = (uint8_t*)
		ped_malloc (map_sectors * PED_SECTOR_SIZE_DEFAULT);
	if (!priv_data->alloc_map) goto hpo_dm;

	priv_data->allocation_file =
		hfsplus_file_open (fs, PED_CPU_TO_BE32 (HFSP_ALLOC_ID),
				   vh->allocation_file.extents,
				   PED_BE64_TO_CPU (
					vh->allocation_file.logical_size)
				   / PED_SECTOR_SIZE_DEFAULT);
	if (!priv_data->allocation_file) goto hpo_am;
	if (!hfsplus_file_read (priv_data->allocation_file,
				priv_data->alloc_map, 0, map_sectors)) {
		hfsplus_close(fs);
		return NULL;
	}

	fs->type = &hfsplus_type;
	fs->checked = ((PED_BE32_TO_CPU (vh->attributes) >> HFS_UNMOUNTED) & 1)
	      && !((PED_BE32_TO_CPU (vh->attributes) >> HFSP_INCONSISTENT) & 1);

	return fs;

/*--- clean error handling ---*/
hpo_am: free(priv_data->alloc_map);
hpo_dm: free(priv_data->dirty_alloc_map);
hpo_cl: hfsplus_file_close (priv_data->attributes_file);
hpo_cc:	hfsplus_file_close (priv_data->catalog_file);
hpo_ce:	hfsplus_file_close (priv_data->extents_file);
hpo_pg: if (priv_data->free_geom) ped_geometry_destroy (priv_data->plus_geom);
hpo_wr: if (priv_data->wrapper) hfs_close(priv_data->wrapper);
hpo_gm: ped_geometry_destroy (fs->geom);
hpo_pd: free(priv_data);
hpo_vh: free(vh);
hpo_fs: free(fs);
hpo:	return NULL;
}
コード例 #28
0
ファイル: partutil.c プロジェクト: paulcbetts/gformat
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;
}