Ejemplo n.º 1
0
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;
}
Ejemplo n.º 2
0
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;
}
Ejemplo n.º 3
0
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;
}
Ejemplo n.º 4
0
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 );
        }
    }
}