Merge branch 'issue-1327' into calamares

FIXES #1327
FIXES #1267

Generally, flags-manipulation was a mess and restoring the
value-on-disk impossible.
This commit is contained in:
Adriaan de Groot 2020-11-04 13:20:14 +01:00
commit 2535d8ccbd
4 changed files with 52 additions and 22 deletions

View File

@ -439,11 +439,14 @@ isEfiSystem()
bool bool
isEfiBootable( const Partition* candidate ) isEfiBootable( const Partition* candidate )
{ {
cDebug() << "Check EFI bootable" << convenienceName( candidate ) << candidate->devicePath(); const auto flags = PartitionInfo::flags( candidate );
cDebug() << Logger::SubEntry << "flags" << candidate->activeFlags();
auto flags = PartitionInfo::flags( candidate );
// TODO: with KPMCore 4, this comment is wrong: the flags
// are remapped, and the ESP flag is the same as Boot.
#if defined( WITH_KPMCORE4API )
static_assert( KPM_PARTITION_FLAG_ESP == KPM_PARTITION_FLAG( Boot ), "KPMCore API enum changed" );
return flags.testFlag( KPM_PARTITION_FLAG_ESP );
#else
/* If bit 17 is set, old-style Esp flag, it's OK */ /* If bit 17 is set, old-style Esp flag, it's OK */
if ( flags.testFlag( KPM_PARTITION_FLAG_ESP ) ) if ( flags.testFlag( KPM_PARTITION_FLAG_ESP ) )
{ {
@ -455,19 +458,28 @@ isEfiBootable( const Partition* candidate )
while ( root && !root->isRoot() ) while ( root && !root->isRoot() )
{ {
root = root->parent(); root = root->parent();
cDebug() << Logger::SubEntry << "moved towards root" << Logger::Pointer( root );
} }
// Strange case: no root found, no partition table node? // Strange case: no root found, no partition table node?
if ( !root ) if ( !root )
{ {
cWarning() << "No root of partition table found.";
return false; return false;
} }
const PartitionTable* table = dynamic_cast< const PartitionTable* >( root ); const PartitionTable* table = dynamic_cast< const PartitionTable* >( root );
cDebug() << Logger::SubEntry << "partition table" << Logger::Pointer( table ) << "type" if ( !table )
<< ( table ? table->type() : PartitionTable::TableType::unknownTableType ); {
return table && ( table->type() == PartitionTable::TableType::gpt ) && flags.testFlag( KPM_PARTITION_FLAG( Boot ) ); cWarning() << "Root of partition table is not a PartitionTable object";
return false;
}
if ( table->type() == PartitionTable::TableType::gpt )
{
const auto bootFlag = KPM_PARTITION_FLAG( Boot );
return flags.testFlag( bootFlag );
}
return false;
#endif
} }
QString QString

View File

@ -716,6 +716,8 @@ PartitionCoreModule::updateIsDirty()
void void
PartitionCoreModule::scanForEfiSystemPartitions() PartitionCoreModule::scanForEfiSystemPartitions()
{ {
const bool wasEmpty = m_efiSystemPartitions.isEmpty();
m_efiSystemPartitions.clear(); m_efiSystemPartitions.clear();
QList< Device* > devices; QList< Device* > devices;
@ -732,6 +734,11 @@ PartitionCoreModule::scanForEfiSystemPartitions()
{ {
cWarning() << "system is EFI but no EFI system partitions found."; cWarning() << "system is EFI but no EFI system partitions found.";
} }
else if ( wasEmpty )
{
// But it isn't empty anymore, so whatever problem has been solved
cDebug() << "system is EFI and new EFI system partition has been found.";
}
m_efiSystemPartitions = efiSystemPartitions; m_efiSystemPartitions = efiSystemPartitions;
} }

View File

@ -52,7 +52,15 @@ PartitionTable::Flags
flags( const Partition* partition ) flags( const Partition* partition )
{ {
auto v = partition->property( FLAGS_PROPERTY ); auto v = partition->property( FLAGS_PROPERTY );
if ( v.type() == QVariant::Int ) if ( !v.isValid() )
{
return partition->activeFlags();
}
// The underlying type of PartitionTable::Flags can be int or uint
// (see qflags.h) and so setting those flags can create a QVariant
// of those types; we don't just want to check QVariant::canConvert()
// here because that will also accept QByteArray and some other things.
if ( v.type() == QVariant::Int || v.type() == QVariant::UInt )
{ {
return static_cast< PartitionTable::Flags >( v.toInt() ); return static_cast< PartitionTable::Flags >( v.toInt() );
} }

View File

@ -136,8 +136,8 @@ EditExistingPartitionDialog::applyChanges( PartitionCoreModule* core )
bool partResizedMoved = newFirstSector != m_partition->firstSector() || newLastSector != m_partition->lastSector(); bool partResizedMoved = newFirstSector != m_partition->firstSector() || newLastSector != m_partition->lastSector();
cDebug() << "old boundaries:" << m_partition->firstSector() << m_partition->lastSector() << m_partition->length(); cDebug() << "old boundaries:" << m_partition->firstSector() << m_partition->lastSector() << m_partition->length();
cDebug() << "new boundaries:" << newFirstSector << newLastSector; cDebug() << Logger::SubEntry << "new boundaries:" << newFirstSector << newLastSector;
cDebug() << "dirty status:" << m_partitionSizeController->isDirty(); cDebug() << Logger::SubEntry << "dirty status:" << m_partitionSizeController->isDirty();
FileSystem::Type fsType = FileSystem::Unknown; FileSystem::Type fsType = FileSystem::Unknown;
if ( m_ui->formatRadioButton->isChecked() ) if ( m_ui->formatRadioButton->isChecked() )
@ -147,6 +147,9 @@ EditExistingPartitionDialog::applyChanges( PartitionCoreModule* core )
: FileSystem::typeForName( m_ui->fileSystemComboBox->currentText() ); : FileSystem::typeForName( m_ui->fileSystemComboBox->currentText() );
} }
const auto resultFlags = newFlags();
const auto currentFlags = PartitionInfo::flags( m_partition );
if ( partResizedMoved ) if ( partResizedMoved )
{ {
if ( m_ui->formatRadioButton->isChecked() ) if ( m_ui->formatRadioButton->isChecked() )
@ -157,20 +160,20 @@ EditExistingPartitionDialog::applyChanges( PartitionCoreModule* core )
fsType, fsType,
newFirstSector, newFirstSector,
newLastSector, newLastSector,
newFlags() ); resultFlags );
PartitionInfo::setMountPoint( newPartition, PartitionInfo::mountPoint( m_partition ) ); PartitionInfo::setMountPoint( newPartition, PartitionInfo::mountPoint( m_partition ) );
PartitionInfo::setFormat( newPartition, true ); PartitionInfo::setFormat( newPartition, true );
core->deletePartition( m_device, m_partition ); core->deletePartition( m_device, m_partition );
core->createPartition( m_device, newPartition ); core->createPartition( m_device, newPartition );
core->setPartitionFlags( m_device, newPartition, newFlags() ); core->setPartitionFlags( m_device, newPartition, resultFlags );
} }
else else
{ {
core->resizePartition( m_device, m_partition, newFirstSector, newLastSector ); core->resizePartition( m_device, m_partition, newFirstSector, newLastSector );
if ( m_partition->activeFlags() != newFlags() ) if ( currentFlags != resultFlags )
{ {
core->setPartitionFlags( m_device, m_partition, newFlags() ); core->setPartitionFlags( m_device, m_partition, resultFlags );
} }
} }
} }
@ -183,9 +186,9 @@ EditExistingPartitionDialog::applyChanges( PartitionCoreModule* core )
if ( m_partition->fileSystem().type() == fsType ) if ( m_partition->fileSystem().type() == fsType )
{ {
core->formatPartition( m_device, m_partition ); core->formatPartition( m_device, m_partition );
if ( m_partition->activeFlags() != newFlags() ) if ( currentFlags != resultFlags )
{ {
core->setPartitionFlags( m_device, m_partition, newFlags() ); core->setPartitionFlags( m_device, m_partition, resultFlags );
} }
} }
else // otherwise, we delete and recreate the partition with new fs type else // otherwise, we delete and recreate the partition with new fs type
@ -196,22 +199,22 @@ EditExistingPartitionDialog::applyChanges( PartitionCoreModule* core )
fsType, fsType,
m_partition->firstSector(), m_partition->firstSector(),
m_partition->lastSector(), m_partition->lastSector(),
newFlags() ); resultFlags );
PartitionInfo::setMountPoint( newPartition, PartitionInfo::mountPoint( m_partition ) ); PartitionInfo::setMountPoint( newPartition, PartitionInfo::mountPoint( m_partition ) );
PartitionInfo::setFormat( newPartition, true ); PartitionInfo::setFormat( newPartition, true );
core->deletePartition( m_device, m_partition ); core->deletePartition( m_device, m_partition );
core->createPartition( m_device, newPartition ); core->createPartition( m_device, newPartition );
core->setPartitionFlags( m_device, newPartition, newFlags() ); core->setPartitionFlags( m_device, newPartition, resultFlags );
} }
} }
else else
{ {
core->refreshPartition( m_device, m_partition ); if ( currentFlags != resultFlags )
if ( m_partition->activeFlags() != newFlags() )
{ {
core->setPartitionFlags( m_device, m_partition, newFlags() ); core->setPartitionFlags( m_device, m_partition, resultFlags );
} }
core->refreshPartition( m_device, m_partition );
} }
} }
} }