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); }
/** * 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); }
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); }
/** * 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); }
/** * 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; }
/** * 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); }
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); }
/* _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; }
/** * 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); }
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); }
/** * 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); }
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); }
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); }
/** * 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); }
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); }
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); }
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; }
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; }
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; }