int partdetails(PedPartition *part, int noswap) { char *pname, *ptype, *ptr; PedFileSystemType *type; if ((type = ped_file_system_probe (&part->geom)) == NULL) // prevent a nice segfault ptype = strdup("unknown"); else ptype = (char*)type->name; if(noswap && !strncmp("linux-swap", ptype, 10)) return(0); pname = ped_partition_get_path(part); // remove the unnecessary "p-1" suffix from sw raid device names if((ptr = strstr(pname, "p-1"))!=NULL) *ptr='\0'; // for dialog menus parts = g_list_append(parts, pname); ptr = fsize(part->geom.length); parts = g_list_append(parts, g_strdup_printf("%s\t%s", ptr, ptype)); // for dialog checklists partschk = g_list_append(partschk, pname); partschk = g_list_append(partschk, g_strdup_printf("%s %s", ptr, ptype)); FREE(ptr); partschk = g_list_append(partschk, strdup("Off")); return(0); }
bool MParted::MParted_Core::calibratePartition(MParted::Partition & partition) { if (partition.type != MParted::TYPE_PRIMARY && partition.type != MParted::TYPE_LOGICAL && partition.type != MParted::TYPE_EXTENDED) return true; //nothing to calibrate... bool success = false; PedPartition *pedPartition = NULL; if (openDeviceAndDisk(partition.devicePath)) { if (partition.type == MParted::TYPE_EXTENDED) pedPartition = ped_disk_extended_partition(pedDisk); else pedPartition = ped_disk_get_partition_by_sector(pedDisk, partition.getSector()); // Check to see if pedPartition->type matches partition.type if (pedPartition && ((pedPartition->type == PED_PARTITION_NORMAL && partition.type == MParted::TYPE_PRIMARY) || (pedPartition->type == PED_PARTITION_LOGICAL && partition.type == MParted::TYPE_LOGICAL) || (pedPartition->type == PED_PARTITION_EXTENDED && partition.type == MParted::TYPE_EXTENDED))) { // Get partition path partition.path = Utils::charToStringFree(ped_partition_get_path(pedPartition)); // we have to free the result of ped_partition_get_path() partition.sector_start = pedPartition->geom.start; partition.sector_end = pedPartition->geom.end; if (!partition.path.isEmpty()) success = true; } closeDeviceAndDisk(); } return success; }
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; }
int has_efi_directory(PedPartition* part) { int is_busy = ped_partition_is_busy(part); GError* error = NULL; char* mount_point = NULL; char *path = ped_partition_get_path(part); if (!is_busy) { mount_point = g_dir_make_tmp("efi_detectorXXXXXX", &error); if (error != NULL) { g_warning("[%s] create efi_detector failed :%s\n", __func__, error->message); g_error_free(error); error = NULL; } char* cmd = g_strdup_printf ("mount -t vfat %s %s", path, mount_point); g_spawn_command_line_sync (cmd, NULL, NULL, NULL, &error); g_free(cmd); if (error != NULL) { g_warning("[%s] Can't detect whether is $ESP, cmd: %s, error: %s", __func__, cmd, error->message); g_error_free(error); error = NULL; return FALSE; } } if (mount_point == NULL) { mount_point = get_partition_mount_point(path); } g_free(path); char* esp_path = g_build_filename(mount_point, "EFI", NULL); int is_esp = g_file_test (esp_path, G_FILE_TEST_IS_DIR); g_free(esp_path); if (!is_busy) { char* cmd = g_strdup_printf ("umount -l %s", mount_point); g_spawn_command_line_sync (cmd, NULL, NULL, NULL, &error); g_free(cmd); if (error != NULL) { g_warning("[%s] Can't detect whether is $ESP, cmd: %s, error: %s", __func__, cmd, error->message); g_error_free(error); g_free(mount_point); return is_esp; } //don't rm the dir if umount failed. g_rmdir(mount_point); g_free(mount_point); } return is_esp; }
char* query_esp_path_by_disk(const char* path) { g_message("[%s], path: %s\n", __func__, path); PedDevice* device = ped_device_get(path); PedDiskType *type = ped_disk_probe(device); if (type == 0) { return NULL; } if (strncmp(type->name, "loop", 5) == 0) { return NULL; } PedDisk* disk = ped_disk_new(device); if (disk == 0) { return NULL; } PedPartition* part = 0; for (part = ped_disk_next_partition(disk, NULL); part; part = ped_disk_next_partition(disk, part)) { if (part->num < 0) { continue; } if (part->fs_type == 0 || strncmp(part->fs_type->name, "fat32", 5) != 0) { continue; } int is_esp = has_efi_directory(part); g_debug("[%s] %s is ESP ? : %d\n", __func__, ped_partition_get_path(part), is_esp); if (is_esp) { return ped_partition_get_path(part); } } return NULL; }
gboolean partition_filter_by_path(PedPartition* part, const char* path) { char* part_path = ped_partition_get_path(part); if (part_path == NULL) { return FALSE; } if (g_strcmp0(part_path , path) == 0) { g_free(part_path); return TRUE; } else { g_free(part_path); return FALSE; } }
FileSystem::Type LibPartedPartitionTable::detectFileSystemBySector(Report& report, const Device& device, qint64 sector) { PedPartition* pedPartition = ped_disk_get_partition_by_sector(pedDisk(), sector); char* pedPath = ped_partition_get_path(pedPartition); FileSystem::Type type = FileSystem::Unknown; if (pedPartition && pedPath) type = CoreBackendManager::self()->backend()->detectFileSystem(QString::fromUtf8(pedPath)); else report.line() << xi18nc("@info:progress", "Could not determine file system of partition at sector %1 on device <filename>%2</filename>.", sector, device.deviceNode()); free(pedPath); return type; }
int main(int argc, char *argv[]) { PedDevice *dev; // use "-l" to list all prep partitions found (not just the first one). int list = (argc == 2 && !strncmp(argv[1], "-l", strlen("-l"))); ped_exception_fetch_all(); ped_device_probe_all(); for (dev = ped_device_get_next(NULL); dev; dev = ped_device_get_next(dev)) { PedDisk *disk; PedPartition *part; disk = ped_disk_new(dev); if (!disk) continue; for (part = ped_disk_next_partition(disk, NULL); part; part = ped_disk_next_partition(disk, part)) { if (ped_partition_is_active(part) && ped_partition_get_flag(part, PED_PARTITION_PREP)) { char *path; path = ped_partition_get_path(part); if (path) { printf("%s\n", path); if (!list) { free(path); return 0; } } free(path); } } } return 0; }
char* query_esp_path_by_disk_path(const char* path) { PedDevice* device = ped_device_get(path); PedDiskType *type = ped_disk_probe(device); if (type == 0) { return NULL; } if (strncmp(type->name, "loop", 5) == 0) { return NULL; } PedDisk* disk = ped_disk_new(device); if (disk == 0) { return NULL; } PedPartition* esp = find_partition(disk, (PartitionFilter)filter_partition_by_esp, NULL, NULL); if (esp != NULL) { return ped_partition_get_path(esp); } return NULL; }
bool Ext2::resize(PedPartition *partition, PedSector size, string *results) { if (!can_resize) return false; string output = get_tmp_file(); return (system("resize2fs " + string(ped_partition_get_path(partition)) + IntToStr((long long) (size*partition->disk->dev->sector_size)/1024) + "K")==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; }
int get_all_partitions(struct partition *parts[], const int max_parts, bool ignore_fs_type, PedPartitionFlag require_flag) { struct partition *p; int part_count = 0; PedDevice *dev = NULL; PedDisk *disk; PedPartition *part; ped_device_probe_all(); while ((dev = ped_device_get_next(dev)) != NULL) { if (dev->read_only) continue; if (strstr(dev->path, "/dev/mtd") == dev->path) continue; if (!ped_disk_probe(dev)) continue; disk = ped_disk_new(dev); part = NULL; while ((part = ped_disk_next_partition(disk, part)) != NULL) { if (part->type & (PED_PARTITION_METADATA | PED_PARTITION_FREESPACE | PED_PARTITION_EXTENDED)) continue; if (part_count >= max_parts) break; #ifndef FIND_PARTS_MAIN /* allow other udebs to block partitions */ if(block_partition(ped_partition_get_path(part)) != 0) continue; #endif if (require_flag && !ped_partition_get_flag(part, require_flag)) continue; p = malloc(sizeof(*p)); p->path = ped_partition_get_path(part); if (strstr(p->path, "/dev/hd") == p->path) { static char *targets[] = { "master", "slave" }; char drive; int part; if (sscanf(p->path, "/dev/hd%c%d", &drive, &part) == 2 && drive >= 'a' && drive <= 'z') asprintf(&p->description, "IDE%d %s\\, part. %d", (drive - 'a') / 2 + 1, targets[(drive - 'a') % 2], part); else p->description = strdup(p->path); } else if (strstr(p->path, "/dev/sd") == p->path) { char drive; int host, bus, target, lun, part; int done = 0; if (sscanf(p->path, "/dev/sd%c%d", &drive, &part) == 2 && drive >= 'a' && drive <= 'z') { struct stat st; char *disk, *disk_pos, *sys_device; disk = strdup(p->path + 5); for (disk_pos = disk + strlen(disk) - 1; disk_pos > disk; --disk_pos) { if (*disk_pos >= '0' && *disk_pos <= '9') *disk_pos = 0; else break; } sys_device = malloc(strlen(disk) + 19); sprintf(sys_device, "/sys/block/%s/device", disk); /* TODO: device symlinks are allegedly slated to go * away, but it's not entirely clear what their * replacement will be yet ... */ if (lstat(sys_device, &st) == 0 && S_ISLNK(st.st_mode)) { char buf[512]; memset(buf, 0, 512); if (readlink(sys_device, buf, 511) > 0) { const char *bus_id = basename(buf); if (sscanf(bus_id, "%d:%d:%d:%d", &host, &bus, &target, &lun) == 4) { asprintf(&p->description, "SCSI%d (%d\\,%d\\,%d) part. %d", host + 1, bus, target, lun, part); done = 1; } } } } if (!done) p->description = strdup(p->path); } else p->description = strdup(p->path); p->fstype = NULL; p->fsid = NULL; p->size = 0L; p->op.filesystem = NULL; p->op.mountpoint = NULL; p->op.done = 0; test_lvm(p); test_evms(p); test_raid(p); /* FIXME: Other tests? */ get_partition_info(p, part, dev, ignore_fs_type); parts[part_count++] = p; } if (part_count >= max_parts) break; } return part_count; }
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); }
void MParted::MParted_Core::scanDevicePartitions(MParted::Device &device) { device.partitions.clear(); // Initialise PedPartition *pedPartition = NULL; MParted::Partition *extendedPartition = NULL; while ((pedPartition = ped_disk_next_partition(pedDisk, pedPartition))) { //if there's no end, there's no partition ;) if (pedPartition->geom.end <= -1) continue; MParted::Partition partition; partition.devicePath = device.path; partition.sector_size = device.sector_size; partition.busy = ped_partition_is_busy(pedPartition); partition.partitionNumber = pedPartition->num; partition.sector_start = pedPartition->geom.start; partition.sector_end = pedPartition->geom.end; // Get partition path partition.path = Utils::charToStringFree(ped_partition_get_path(pedPartition)); // we have to free the result of ped_partition_get_path() if (partition.path.isEmpty()) partition.path = "Partition path not found"; switch (pedPartition->type) { case PED_PARTITION_LOGICAL: partition.insideExtended = true; case PED_PARTITION_NORMAL: partition.type = pedPartition->type == 0 ? MParted::TYPE_PRIMARY : MParted::TYPE_LOGICAL; partition.filesystem = getFilesystem(pedPartition); // Find filesystem class and set used sectors, label and uuid for (int i = 0; i < filesystems.size(); i++) { MParted::Filesystem *fs = filesystems[i]; if (fs->getFilesystemType() != partition.filesystem) continue; fs->setUsedSectors(partition); fs->readLabel(partition); fs->readUUID(partition); break; } break ; case PED_PARTITION_EXTENDED: partition.type = MParted::TYPE_EXTENDED; partition.filesystem = MParted::FS_EXTENDED; break ; default: continue; } // Add partition to list if (partition.type == MParted::TYPE_LOGICAL && extendedPartition != NULL) extendedPartition->logicals.append(partition); else device.partitions.append(partition); // Save pointer of extended partition, if it is one if (partition.type == MParted::TYPE_EXTENDED) extendedPartition = &device.partitions.last(); } // Update unallocated space UnallocatedUtils::updateUnallocated(device); }
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; }