bool LibPartedPartitionTable::updateGeometry(Report& report, const Partition& partition, qint64 sector_start, qint64 sector_end) { Q_ASSERT(partition.devicePath() == QString::fromUtf8(pedDevice()->path)); bool rval = false; PedPartition* pedPartition = (partition.roles().has(PartitionRole::Extended)) ? ped_disk_extended_partition(pedDisk()) : ped_disk_get_partition_by_sector(pedDisk(), partition.firstSector()); if (pedPartition) { if (PedGeometry* pedGeometry = ped_geometry_new(pedDevice(), sector_start, sector_end - sector_start + 1)) { if (PedConstraint* pedConstraint = ped_constraint_exact(pedGeometry)) { if (ped_disk_set_partition_geom(pedDisk(), pedPartition, pedConstraint, sector_start, sector_end)) rval = true; else report.line() << xi18nc("@info:progress", "Could not set geometry for partition <filename>%1</filename> while trying to resize/move it.", partition.deviceNode()); ped_constraint_destroy(pedConstraint); } else report.line() << xi18nc("@info:progress", "Could not get constraint for partition <filename>%1</filename> while trying to resize/move it.", partition.deviceNode()); ped_geometry_destroy(pedGeometry); } else report.line() << xi18nc("@info:progress", "Could not get geometry for partition <filename>%1</filename> while trying to resize/move it.", partition.deviceNode()); } else report.line() << xi18nc("@info:progress", "Could not open partition <filename>%1</filename> while trying to resize/move it.", partition.deviceNode()); return rval; }
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; }
bool LibPartedPartitionTable::deletePartition(Report& report, const Partition& partition) { Q_ASSERT(partition.devicePath() == QString::fromUtf8(pedDevice()->path)); bool rval = false; PedPartition* pedPartition = partition.roles().has(PartitionRole::Extended) ? ped_disk_extended_partition(pedDisk()) : ped_disk_get_partition_by_sector(pedDisk(), partition.firstSector()); if (pedPartition) { rval = ped_disk_delete_partition(pedDisk(), pedPartition); if (!rval) report.line() << xi18nc("@info:progress", "Could not delete partition <filename>%1</filename>.", partition.deviceNode()); } else report.line() << xi18nc("@info:progress", "Deleting partition failed: Partition to delete (<filename>%1</filename>) not found on disk.", partition.deviceNode()); return rval; }
void ReplaceWidget::onPartitionSelected() { if ( Calamares::JobQueue::instance()->globalStorage()->value( "firmwareType" ) == "efi" ) m_isEfi = true; if ( m_ui->partitionTreeView->currentIndex() == QModelIndex() ) { updateStatus( CalamaresUtils::PartitionPartition, tr( "Select where to install %1.<br/>" "<font color=\"red\">Warning: </font>this will delete all files " "on the selected partition." ) .arg( *Calamares::Branding::VersionedName ) ); setNextEnabled( false ); return; } bool ok = false; double requiredSpaceB = Calamares::JobQueue::instance() ->globalStorage() ->value( "requiredStorageGB" ) .toDouble( &ok ) * 1024 * 1024 * 1024; PartitionModel* model = qobject_cast< PartitionModel* >( m_ui->partitionTreeView->model() ); if ( model && ok ) { const QStringList osproberLines = Calamares::JobQueue::instance() ->globalStorage() ->value( "osproberLines" ).toStringList(); Partition* partition = model->partitionForIndex( m_ui->partitionTreeView->currentIndex() ); if ( !partition || partition->state() != Partition::StateNone ) { updateStatus( CalamaresUtils::Fail, tr( "The selected item does not appear to be a valid partition." ) ); setNextEnabled( false ); return; } if ( partition->roles().has( PartitionRole::Unallocated ) ) { updateStatus( CalamaresUtils::Fail, tr( "%1 cannot be installed on empty space. Please select an " "existing partition." ) .arg( *Calamares::Branding::VersionedName ) ); setNextEnabled( false ); return; } if ( partition->roles().has( PartitionRole::Extended ) ) { updateStatus( CalamaresUtils::Fail, tr( "%1 cannot be installed on an extended partition. Please select an " "existing primary or logical partition." ) .arg( *Calamares::Branding::VersionedName ) ); setNextEnabled( false ); return; } if ( partition->partitionPath().isEmpty() ) { updateStatus( CalamaresUtils::Fail, tr( "%1 cannot be installed on this partition." ) .arg( *Calamares::Branding::VersionedName ) ); setNextEnabled( false ); return; } QString prettyName = tr( "Data partition (%1)" ) .arg( partition->fileSystem().name() ); for ( const QString& line : osproberLines ) { QStringList lineColumns = line.split( ':' ); QString path = lineColumns.value( 0 ).simplified(); if ( path == partition->partitionPath() ) { QString osName; if ( !lineColumns.value( 1 ).simplified().isEmpty() ) osName = lineColumns.value( 1 ).simplified(); else if ( !lineColumns.value( 2 ).simplified().isEmpty() ) osName = lineColumns.value( 2 ).simplified(); if ( osName.isEmpty() ) { prettyName = tr( "Unknown system partition (%1)" ) .arg( partition->fileSystem().name() ); } else { prettyName = tr ( "%1 system partition (%2)" ) .arg( osName.replace( 0, 1, osName.at( 0 ).toUpper() ) ) .arg( partition->fileSystem().name() ); } break; } } if ( partition->capacity() < requiredSpaceB ) { updateStatus( CalamaresUtils::Fail, tr( "<strong>%4</strong><br/><br/>" "The partition %1 is too small for %2. Please select a partition " "with capacity at least %3 GiB." ) .arg( partition->partitionPath() ) .arg( *Calamares::Branding::VersionedName ) .arg( requiredSpaceB / ( 1024. * 1024. * 1024. ), 0, 'f', 1 ) .arg( prettyName ) ); setNextEnabled( false ); return; } m_ui->bootComboBox->hide(); m_ui->bootComboBox->clear(); m_ui->bootStatusLabel->hide(); m_ui->bootStatusLabel->clear(); if ( m_isEfi ) { QList< Partition* > efiSystemPartitions = m_core->efiSystemPartitions(); if ( efiSystemPartitions.count() == 0 ) { updateStatus( CalamaresUtils::Fail, tr( "<strong>%2</strong><br/><br/>" "An EFI system partition cannot be found anywhere " "on this system. Please go back and use manual " "partitioning to set up %1." ) .arg( *Calamares::Branding::ShortProductName ) .arg( prettyName ) ); setNextEnabled( false ); } else if ( efiSystemPartitions.count() == 1 ) { updateStatus( CalamaresUtils::PartitionPartition, tr( "<strong>%3</strong><br/><br/>" "%1 will be installed on %2.<br/>" "<font color=\"red\">Warning: </font>all data on partition " "%2 will be lost.") .arg( *Calamares::Branding::VersionedName ) .arg( partition->partitionPath() ) .arg( prettyName ) ); m_ui->bootStatusLabel->show(); m_ui->bootStatusLabel->setText( tr( "The EFI system partition at %1 will be used for starting %2." ) .arg( efiSystemPartitions.first()->partitionPath() ) .arg( *Calamares::Branding::ShortProductName ) ); setNextEnabled( true ); } else { updateStatus( CalamaresUtils::PartitionPartition, tr( "<strong>%3</strong><br/><br/>" "%1 will be installed on %2.<br/>" "<font color=\"red\">Warning: </font>all data on partition " "%2 will be lost.") .arg( *Calamares::Branding::VersionedName ) .arg( partition->partitionPath() ) .arg( prettyName ) ); m_ui->bootStatusLabel->show(); m_ui->bootStatusLabel->setText( tr( "EFI system partition:" ) ); m_ui->bootComboBox->show(); for ( int i = 0; i < efiSystemPartitions.count(); ++i ) { Partition* efiPartition = efiSystemPartitions.at( i ); m_ui->bootComboBox->addItem( efiPartition->partitionPath(), i ); if ( efiPartition->devicePath() == partition->devicePath() && efiPartition->number() == 1 ) m_ui->bootComboBox->setCurrentIndex( i ); } setNextEnabled( true ); } } else { updateStatus( CalamaresUtils::PartitionPartition, tr( "<strong>%3</strong><br/><br/>" "%1 will be installed on %2.<br/>" "<font color=\"red\">Warning: </font>all data on partition " "%2 will be lost.") .arg( *Calamares::Branding::VersionedName ) .arg( partition->partitionPath() ) .arg( prettyName ) ); setNextEnabled( true ); } } }