Esempio n. 1
0
static PedConstraint *reiserfs_get_resize_constraint(const PedFileSystem *
						     fs)
{
	PedDevice *dev;
	PedSector min_size;
	PedGeometry full_disk;
	reiserfs_fs_t *fs_info;
	PedAlignment start_align;
	PedGeometry start_sector;

	PED_ASSERT(fs != NULL);

	fs_info = fs->type_specific;
	dev = fs->geom->dev;

	if (!ped_alignment_init(&start_align, fs->geom->start, 0))
		return NULL;
	if (!ped_geometry_init(&full_disk, dev, 0, dev->length - 1))
		return NULL;
	if (!ped_geometry_init(&start_sector, dev, fs->geom->start, 1))
		return NULL;

	/*
	   Minsize for reiserfs is area occupied by data blocks and
	   metadata blocks minus free space blocks and minus bitmap
	   blocks which describes free space blocks.
	 */
	min_size = reiserfs_fs_min_size(fs_info) *
	    (reiserfs_fs_block_size(fs_info) / PED_SECTOR_SIZE_DEFAULT);

	return ped_constraint_new(&start_align, ped_alignment_any,
				  &start_sector, &full_disk, min_size,
				  dev->length);
}
Esempio n. 2
0
/**
 * Return a constraint that only the given region will satisfy.
 */
PedConstraint*
ped_constraint_exact (const PedGeometry* geom)
{
	PedAlignment	start_align;
	PedAlignment	end_align;
	PedGeometry	start_sector;
	PedGeometry	end_sector;
	int ok;

	/* With grain size of 0, it always succeeds.  */
	ok = ped_alignment_init (&start_align, geom->start, 0);
	assert (ok);
	ok = ped_alignment_init (&end_align, geom->end, 0);
	assert (ok);

	ok = ped_geometry_init (&start_sector, geom->dev, geom->start, 1);
	if (!ok)
	  return NULL;
	ok = ped_geometry_init (&end_sector, geom->dev, geom->end, 1);
	if (!ok)
	  return NULL;

	return ped_constraint_new (&start_align, &end_align,
				   &start_sector, &end_sector, 1,
				   geom->dev->length);
}
Esempio n. 3
0
File: dasd.c Progetto: bcl/parted
static PedConstraint*
_primary_constraint (PedDisk* disk)
{
	PedAlignment start_align;
	PedAlignment end_align;
	PedGeometry	max_geom;
	PedSector sector_size;
	LinuxSpecific* arch_specific;
	DasdDiskSpecific* disk_specific;
	PedSector start;

	PDEBUG;

	arch_specific = LINUX_SPECIFIC (disk->dev);
	disk_specific = disk->disk_specific;
	sector_size = arch_specific->real_sector_size / disk->dev->sector_size;

	if (!ped_alignment_init (&start_align, 0,
							 disk->dev->hw_geom.sectors * sector_size))
		return NULL;
	if (!ped_alignment_init (&end_align, -1,
						     disk->dev->hw_geom.sectors * sector_size))
		return NULL;

	start = (FIRST_USABLE_TRK * (long long) disk->dev->hw_geom.sectors
			    * (long long) arch_specific->real_sector_size
			    / (long long) disk->dev->sector_size);

	if (!ped_geometry_init (&max_geom, disk->dev, start, disk->dev->length))
		return NULL;

	return ped_constraint_new(&start_align, &end_align, &max_geom,
							  &max_geom, 1, disk->dev->length);
}
Esempio n. 4
0
/**
 * Return a constraint that requires a region to be entirely contained inside
 * \p max.
 *
 * \return \c NULL on failure.
 */
PedConstraint*
ped_constraint_new_from_max (const PedGeometry* max)
{
	PED_ASSERT (max != NULL);

	return ped_constraint_new (
			ped_alignment_any, ped_alignment_any,
			max, max, 1, max->length);
}
Esempio n. 5
0
/**
 * Return a constraint that requires a region to satisfy both \p a and \p b.
 *
 * Moreover, any region satisfying \p a and \p b will also satisfy the returned
 * constraint.
 *
 * \return \c NULL if no solution could be found (note that \c NULL is a valid
 *         PedConstraint).
 */
PedConstraint*
ped_constraint_intersect (const PedConstraint* a, const PedConstraint* b)
{
	PedAlignment*	start_align;
	PedAlignment*	end_align;
	PedGeometry*	start_range;
	PedGeometry*	end_range;
	PedSector	min_size;
	PedSector	max_size;
	PedConstraint*	constraint;

	if (!a || !b)
		return NULL;

	start_align = ped_alignment_intersect (a->start_align, b->start_align);
	if (!start_align)
		goto empty;
	end_align = ped_alignment_intersect (a->end_align, b->end_align);
	if (!end_align)
		goto empty_destroy_start_align;
	start_range = ped_geometry_intersect (a->start_range, b->start_range);
	if (!start_range)
		goto empty_destroy_end_align;
	end_range = ped_geometry_intersect (a->end_range, b->end_range);
	if (!end_range)
		goto empty_destroy_start_range;
	min_size = PED_MAX (a->min_size, b->min_size);
	max_size = PED_MIN (a->max_size, b->max_size);

	constraint = ped_constraint_new (
			start_align, end_align, start_range, end_range,
			min_size, max_size);
	if (!constraint)
		goto empty_destroy_end_range;

	ped_alignment_destroy (start_align);
	ped_alignment_destroy (end_align);
	ped_geometry_destroy (start_range);
	ped_geometry_destroy (end_range);
	return constraint;

empty_destroy_end_range:
	ped_geometry_destroy (end_range);
empty_destroy_start_range:
	ped_geometry_destroy (start_range);
empty_destroy_end_align:
	ped_alignment_destroy (end_align);
empty_destroy_start_align:
	ped_alignment_destroy (start_align);
empty:
	return NULL;
}
Esempio n. 6
0
/**
 * Duplicate a constraint.
 *
 * \return \c NULL on failure.
 */
PedConstraint*
ped_constraint_duplicate (const PedConstraint* constraint)
{
	PED_ASSERT (constraint != NULL);

	return ped_constraint_new (
		constraint->start_align,
		constraint->end_align,
		constraint->start_range,
		constraint->end_range,
		constraint->min_size,
		constraint->max_size);
}
Esempio n. 7
0
static PedConstraint *reiserfs_get_create_constraint(const PedDevice *dev)
{
	PedGeometry full_dev;
	PedSector min_blks = (SUPER_OFFSET_IN_BYTES / DEFAULT_BLOCK_SIZE)
			     + 2 + DEFAULT_JOURNAL_SIZE + 1 + 100 + 1;

	if (!ped_geometry_init(&full_dev, dev, 0, dev->length - 1))
		return NULL;

	return ped_constraint_new(ped_alignment_any, ped_alignment_any,
				  &full_dev, &full_dev,
				  min_blks * (DEFAULT_BLOCK_SIZE / 512),
				  dev->length);
}
Esempio n. 8
0
/* _ped_Constraint -> PedConstraint functions */
PedConstraint *_ped_Constraint2PedConstraint(PyObject *s) {
    PedConstraint *ret = NULL;
    PedAlignment *start_align = NULL, *end_align = NULL;
    PedGeometry *start_range = NULL, *end_range = NULL;
    _ped_Constraint *constraint = (_ped_Constraint *) s;

    if (constraint == NULL) {
        PyErr_SetString(PyExc_TypeError, "Empty _ped.Constraint()");
        return NULL;
    }

    start_align = _ped_Alignment2PedAlignment(constraint->start_align);
    if (start_align == NULL) {
        return NULL;
    }

    end_align = _ped_Alignment2PedAlignment(constraint->end_align);
    if (end_align == NULL) {
        ped_alignment_destroy(start_align);
        return NULL;
    }

    start_range = _ped_Geometry2PedGeometry(constraint->start_range);
    if (start_range == NULL) {
        ped_alignment_destroy(start_align);
        ped_alignment_destroy(end_align);
        return NULL;
    }

    end_range = _ped_Geometry2PedGeometry(constraint->end_range);
    if (end_range == NULL) {
        ped_alignment_destroy(start_align);
        ped_alignment_destroy(end_align);
        return NULL;
    }

    ret = ped_constraint_new(start_align, end_align, start_range, end_range,
                             constraint->min_size, constraint->max_size);
    if (ret == NULL) {
        /* Fall through to clean up memory, but set the error condition now. */
        PyErr_NoMemory();
    }

    ped_alignment_destroy(start_align);
    ped_alignment_destroy(end_align);

    return ret;
}
Esempio n. 9
0
/**
 * Return a constraint that any region on the given device will satisfy.
 */
PedConstraint*
ped_constraint_any (const PedDevice* dev)
{
	PedGeometry	full_dev;

	if (!ped_geometry_init (&full_dev, dev, 0, dev->length))
		return NULL;

	return ped_constraint_new (
			ped_alignment_any,
		       	ped_alignment_any,
			&full_dev,
			&full_dev,
		       	1,
			dev->length);
}
Esempio n. 10
0
static PedConstraint *reiserfs_get_copy_constraint(const PedFileSystem *fs,
						   const PedDevice *dev)
{
	PedGeometry full_dev;

	PED_ASSERT(fs != NULL);
	PED_ASSERT(dev != NULL);

	if (!ped_geometry_init(&full_dev, dev, 0, dev->length - 1))
		return NULL;

	return ped_constraint_new(ped_alignment_any, ped_alignment_any,
				  &full_dev, &full_dev,
				  reiserfs_fs_bitmap_used(fs->type_specific),
				  dev->length);
}
Esempio n. 11
0
/**
 * Return a constraint that only the given region will satisfy.
 */
PedConstraint*
ped_constraint_exact (const PedGeometry* geom)
{
	PedAlignment	start_align;
	PedAlignment	end_align;
	PedGeometry	start_sector;
	PedGeometry	end_sector;

	ped_alignment_init (&start_align, geom->start, 0);
	ped_alignment_init (&end_align, geom->end, 0);
	ped_geometry_init (&start_sector, geom->dev, geom->start, 1);
	ped_geometry_init (&end_sector, geom->dev, geom->end, 1);

	return ped_constraint_new (&start_align, &end_align,
				   &start_sector, &end_sector, 1,
				   geom->dev->length);
}
Esempio n. 12
0
static PedConstraint*
_amiga_get_constraint (const PedDisk *disk)
{
	PedDevice *dev = disk->dev;
	PedAlignment start_align, end_align;
	PedGeometry max_geom;
	PedSector cyl_size = dev->hw_geom.sectors * dev->hw_geom.heads;

	if (!ped_alignment_init(&start_align, 0, cyl_size))
		return NULL;
	if (!ped_alignment_init(&end_align, -1, cyl_size))
		return NULL;
	if (!ped_geometry_init(&max_geom, dev, MAX_RDB_BLOCK + 1,
			       dev->length - MAX_RDB_BLOCK - 1))
		return NULL;

	return ped_constraint_new (&start_align, &end_align,
		&max_geom, &max_geom, 1, dev->length);
}
Esempio n. 13
0
File: pc98.c Progetto: Excito/parted
static PedConstraint*
_primary_constraint (PedDisk* disk)
{
	PedDevice*	dev = disk->dev;
	PedAlignment	start_align;
	PedAlignment	end_align;
	PedGeometry	max_geom;
	PedSector	cylinder_size;

	cylinder_size = dev->hw_geom.sectors * dev->hw_geom.heads;

	if (!ped_alignment_init (&start_align, 0, cylinder_size))
		return NULL;
	if (!ped_alignment_init (&end_align, -1, cylinder_size))
		return NULL;
	if (!ped_geometry_init (&max_geom, dev, cylinder_size,
			       	dev->length - cylinder_size))
		return NULL;

	return ped_constraint_new (&start_align, &end_align, &max_geom,
				   &max_geom, 1, dev->length);
}
Esempio n. 14
0
/**
 * Return a constraint that requires a region to be entirely contained inside
 * \p max, and to entirely contain \p min.
 *
 * \return \c NULL on failure.
 */
PedConstraint*
ped_constraint_new_from_min_max (
	const PedGeometry* min,
	const PedGeometry* max)
{
	PedGeometry	start_range;
	PedGeometry	end_range;

	PED_ASSERT (min != NULL);
	PED_ASSERT (max != NULL);
	PED_ASSERT (ped_geometry_test_inside (max, min));

	ped_geometry_init (&start_range, min->dev, max->start,
			   min->start - max->start + 1);
	ped_geometry_init (&end_range, min->dev, min->end,
			   max->end - min->end + 1);

	return ped_constraint_new (
			ped_alignment_any, ped_alignment_any,
			&start_range, &end_range,
			min->length, max->length);
}
Esempio n. 15
0
File: hfs.c Progetto: Excito/parted
PedConstraint *
hfsplus_get_resize_constraint (const PedFileSystem *fs)
{
	PedDevice*	dev = fs->geom->dev;
	PedAlignment	start_align;
	PedGeometry	start_sector;
	PedGeometry	full_dev;
	PedSector	min_size;

	if (!ped_alignment_init (&start_align, fs->geom->start, 0))
		return NULL;
	if (!ped_geometry_init (&start_sector, dev, fs->geom->start, 1))
		return NULL;
	if (!ped_geometry_init (&full_dev, dev, 0, dev->length - 1))
		return NULL;

	min_size = hfsplus_get_min_size (fs);
	if (!min_size) return NULL;

	return ped_constraint_new (&start_align, ped_alignment_any,
				   &start_sector, &full_dev, min_size,
				   fs->geom->length);
}
Esempio n. 16
0
File: hfs.c Progetto: Excito/parted
PedConstraint *
hfs_get_resize_constraint (const PedFileSystem *fs)
{
	PedDevice*	dev = fs->geom->dev;
	PedAlignment	start_align;
	PedGeometry	start_sector;
	PedGeometry	full_dev;
	PedSector	min_size;

	if (!ped_alignment_init (&start_align, fs->geom->start, 0))
		return NULL;
	if (!ped_geometry_init (&start_sector, dev, fs->geom->start, 1))
		return NULL;
	if (!ped_geometry_init (&full_dev, dev, 0, dev->length - 1))
		return NULL;
	/* 2 = last two sectors (alternate MDB and unused sector) */
	min_size = hfs_get_empty_end(fs) + 2;
	if (min_size == 2) return NULL;

	return ped_constraint_new (&start_align, ped_alignment_any,
				   &start_sector, &full_dev, min_size,
				   fs->geom->length);
}
Esempio n. 17
0
int _ped_Constraint_init(_ped_Constraint *self, PyObject *args,
                         PyObject *kwds) {
    static char *kwlist[] = {"start_align", "end_align", "start_range",
                             "end_range", "min_size", "max_size", NULL};
    PedConstraint *constraint = NULL;
    PedAlignment *start_align = NULL, *end_align = NULL;
    PedGeometry *start_range = NULL, *end_range = NULL;

    if (kwds == NULL) {
        if (!PyArg_ParseTuple(args, "O!O!O!O!LL",
                              &_ped_Alignment_Type_obj, &self->start_align,
                              &_ped_Alignment_Type_obj, &self->end_align,
                              &_ped_Geometry_Type_obj, &self->start_range,
                              &_ped_Geometry_Type_obj, &self->end_range,
                              &self->min_size, &self->max_size)) {
            self->start_align = self->end_align = NULL;
            self->start_range = self->end_range = NULL;
            return -1;
        }
    } else {
        if (!PyArg_ParseTupleAndKeywords(args, kwds, "O!O!O!O!LL", kwlist,
                                         &_ped_Alignment_Type_obj,
                                         &self->start_align,
                                         &_ped_Alignment_Type_obj,
                                         &self->end_align,
                                         &_ped_Geometry_Type_obj,
                                         &self->start_range,
                                         &_ped_Geometry_Type_obj,
                                         &self->end_range,
                                         &self->min_size,
                                         &self->max_size)) {
            self->start_align = self->end_align = NULL;
            self->start_range = self->end_range = NULL;
            return -2;
        }
    }

    /*
     * try to call libparted with provided information,
     * on failure, raise an exception
     */
    start_align = _ped_Alignment2PedAlignment(self->start_align);
    end_align = _ped_Alignment2PedAlignment(self->end_align);
    start_range = _ped_Geometry2PedGeometry(self->start_range);
    end_range = _ped_Geometry2PedGeometry(self->end_range);

    constraint = ped_constraint_new(start_align, end_align,
                                    start_range, end_range,
                                    self->min_size, self->max_size);
    if (constraint == NULL) {
        PyErr_SetString(CreateException, "Could not create new constraint");

        ped_alignment_destroy(start_align);
        ped_alignment_destroy(end_align);
        self->start_align = NULL;
        self->end_align = NULL;
        self->start_range = NULL;
        self->end_range = NULL;
        return -3;
    }

    /* increment reference count for PyObjects read by PyArg_ParseTuple */
    Py_INCREF(self->start_align);
    Py_INCREF(self->end_align);
    Py_INCREF(self->start_range);
    Py_INCREF(self->end_range);

    /* clean up libparted objects we created */
    ped_alignment_destroy(start_align);
    ped_alignment_destroy(end_align);
    ped_constraint_destroy(constraint);
    return 0;
}
Esempio n. 18
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;
}
Esempio n. 19
0
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;
}