int main(int argc, char *argv[]) { PedDevice *dev; PedDisk *disk; PedPartition *part; PedConstraint *constraint; /* * argv [1] device * [2] udv_name * [3] start * [4] end */ dev = ped_device_get(argv[1]); if (!dev) { perror("get_device"); return -1; } //disk = _create_disk_label(dev, ped_disk_type_get("gpt")); disk = ped_disk_new(dev); if (!disk) { fprintf(stderr, "fail to create disk label gpt\n"); return -2; } constraint = ped_constraint_any(dev); // part1: 17.4Kb ~ 15MB /* part = ped_partition_new(disk, PED_PARTITION_NORMAL, NULL, 34, 29296); ped_disk_add_partition(disk, part, constraint); */ // part2: 15MB ~ 35MB part = ped_partition_new(disk, PED_PARTITION_NORMAL, NULL, (int)(atoll(argv[3])/512), (int)(atoll(argv[4])/512)); ped_partition_set_name(part, argv[2]); ped_disk_add_partition(disk, part, constraint); ped_disk_commit(disk); ped_constraint_destroy(constraint); ped_disk_destroy(disk); ped_device_destroy(dev); return 0; }
PartitionState do_test1(PedDevice *dev, label_type labelType) { PartitionState state; //PedGeometry geom; PedDisk *disk; PedPartition *part; PedPartition *grub_partition = 0, *boot_partition = 0, *root_partition = 0; PedDiskType *type = 0; PedFileSystemType *ext4 = ped_file_system_type_get("ext4"); bool dirty = false; PedSector start = 0, end = 0; /*if (!ped_geometry_init(&geom,dev,0,dev->length)) { qDebug() << "unable to init geom"; return; }*/ disk = ped_disk_new(dev); /*type = ped_disk_probe(dev); if (type) { qDebug() << "current partition type:" << type->name; disk = type->ops->alloc(dev); if (!type->ops->read(disk)) { qDebug() << "failed to read gpt tables"; return; } }*/ if (!disk) { qDebug() << "no tables detected"; if (labelType == label_type::gpt) { type = ped_disk_type_get("gpt"); } else if (labelType == label_type::mbr) { type = ped_disk_type_get("msdos"); } disk = ped_disk_new_fresh(dev,type); ped_disk_commit(disk); } if (disk) { for (part = ped_disk_next_partition(disk,NULL); part; part = ped_disk_next_partition(disk,part)) { if (!ped_partition_is_active(part)) continue; QString name(ped_partition_get_name(part)); qDebug() << "partition" << part->num << name; if (name == "boot") boot_partition = part; if (name == "root") root_partition = part; if (ped_partition_get_flag(part,PED_PARTITION_BIOS_GRUB)) grub_partition = part; for (int f = PED_PARTITION_FIRST_FLAG; f < PED_PARTITION_LAST_FLAG; f++) { if (ped_partition_get_flag(part,(PedPartitionFlag)f)) { QString flag_name(ped_partition_flag_get_name((PedPartitionFlag)f)); qDebug() << "flag" << flag_name << "is set"; } } } PedConstraint *constraint = ped_constraint_any(dev); if (!grub_partition) { start = (1024*1024) / dev->sector_size; end = ((1024*1024) / dev->sector_size) + start; qDebug() << "creating" << start << end; grub_partition = ped_partition_new(disk,PED_PARTITION_NORMAL,ext4,start,end); if (labelType == label_type::gpt) { ped_partition_set_name(grub_partition,"bios boot"); ped_partition_set_flag(grub_partition,PED_PARTITION_BIOS_GRUB,1); } if (!ped_disk_add_partition(disk,grub_partition,constraint)) { qDebug() << "error adding partition"; } dirty = true; } if (!boot_partition) { start = (1024*1024*2) / dev->sector_size; end = ((1024*1024*128) / dev->sector_size) + start; qDebug() << "creating" << start << end; boot_partition = ped_partition_new(disk,PED_PARTITION_NORMAL,NULL,start,end); if (labelType == label_type::gpt) { ped_partition_set_name(boot_partition,"boot"); } //ped_partition_set_flag(boot_partition,PED_PARTITION_BOOT,1); if (!ped_disk_add_partition(disk,boot_partition,constraint)) { qDebug() << "error adding partition"; } dirty = true; } if (!root_partition) { start = (1024*1024*129) / dev->sector_size; end = dev->length; qDebug() << "creating" << start << end; root_partition = ped_partition_new(disk,PED_PARTITION_NORMAL,ext4,start,end); if (labelType == label_type::gpt) { ped_partition_set_name(root_partition,"root"); //ped_partition_set_flag(root_partition,PED_PARTITION_ROOT,1); } if (!ped_disk_add_partition(disk,root_partition,constraint)) { qDebug() << "error adding partition"; } dirty = true; } ped_constraint_destroy(constraint); } if (dirty) ped_disk_commit(disk); state.boot_path = ped_partition_get_path(boot_partition); state.root_path = ped_partition_get_path(root_partition); return state; }
static int read_table (PedDisk* disk) { int i; PC98RawTable table; PedConstraint* constraint_any; PED_ASSERT (disk != NULL); PED_ASSERT (disk->dev != NULL); constraint_any = ped_constraint_any (disk->dev); if (!ped_device_read (disk->dev, (void*) &table, 0, 2)) goto error; if (!pc98_check_magic(&table)) { if (ped_exception_throw ( PED_EXCEPTION_ERROR, PED_EXCEPTION_IGNORE_CANCEL, _("Invalid partition table on %s."), disk->dev->path)) goto error; } for (i = 0; i < MAX_PART_COUNT; i++) { PC98RawPartition* raw_part; PedPartition* part; PC98PartitionData* pc98_data; PedSector part_start; PedSector part_end; raw_part = &table.partitions [i]; if (is_unused_partition(raw_part)) continue; part_start = legacy_start (disk, raw_part); part_end = legacy_end (disk, raw_part); part = ped_partition_new (disk, PED_PARTITION_NORMAL, NULL, part_start, part_end); if (!part) goto error; pc98_data = part->disk_specific; PED_ASSERT (pc98_data != NULL); pc98_data->system = (raw_part->mid << 8) | raw_part->sid; pc98_data->boot = GET_BIT(raw_part->mid, 7); pc98_data->hidden = !GET_BIT(raw_part->sid, 7); ped_partition_set_name (part, raw_part->name); pc98_data->ipl_sector = chs_to_sector ( disk->dev, PED_LE16_TO_CPU(raw_part->ipl_cyl), raw_part->ipl_head, raw_part->ipl_sect); /* hack */ if (pc98_data->ipl_sector == part->geom.start) pc98_data->ipl_sector = 0; part->num = i + 1; if (!ped_disk_add_partition (disk, part, constraint_any)) goto error; if (part->geom.start != part_start || part->geom.end != part_end) { ped_exception_throw ( PED_EXCEPTION_NO_FEATURE, PED_EXCEPTION_CANCEL, _("Partition %d isn't aligned to cylinder " "boundaries. This is still unsupported."), part->num); goto error; } part->fs_type = ped_file_system_probe (&part->geom); } ped_constraint_destroy (constraint_any); return 1; error: ped_disk_delete_all (disk); ped_constraint_destroy (constraint_any); return 0; }
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; }