Skip to content

Commit

Permalink
Merge branch 'issue-2018' into calamares
Browse files Browse the repository at this point in the history
  • Loading branch information
adriaandegroot committed Nov 12, 2023
2 parents 2b0c416 + 196dd55 commit 1e1e12f
Show file tree
Hide file tree
Showing 17 changed files with 444 additions and 73 deletions.
7 changes: 7 additions & 0 deletions src/libcalamares/GlobalStorage.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,13 @@ GlobalStorage::remove( const QString& key )
return nItems;
}

void
GlobalStorage::clear()
{
WriteLock l( this );
m.clear();
}

QVariant
GlobalStorage::value( const QString& key ) const
{
Expand Down
3 changes: 3 additions & 0 deletions src/libcalamares/GlobalStorage.h
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,9 @@ class GlobalStorage : public QObject
*/
int remove( const QString& key );

/// @brief Clears all keys in this GS object
void clear();

/** @brief dump keys and values to the debug log
*
* All the keys and their values are written to the debug log.
Expand Down
71 changes: 49 additions & 22 deletions src/modules/partition/Config.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -274,39 +274,66 @@ fillGSConfigurationEFI( Calamares::GlobalStorage* gs, const QVariantMap& configu
QString firmwareType( PartUtils::isEfiSystem() ? QStringLiteral( "efi" ) : QStringLiteral( "bios" ) );
gs->insert( "firmwareType", firmwareType );

gs->insert( "efiSystemPartition",
Calamares::getString( configurationMap, "efiSystemPartition", QStringLiteral( "/boot/efi" ) ) );
bool ok = false;
auto efiConfiguration = Calamares::getSubMap( configurationMap, "efi", ok );

// Read and parse key efiSystemPartitionSize
if ( configurationMap.contains( "efiSystemPartitionSize" ) )
// Mount Point
{
const QString sizeString = Calamares::getString( configurationMap, "efiSystemPartitionSize" );
Calamares::Partition::PartitionSize part_size = Calamares::Partition::PartitionSize( sizeString );
if ( part_size.isValid() )
const auto efiSystemPartition = Calamares::getString(
efiConfiguration,
"mountPoint",
Calamares::getString( configurationMap, "efiSystemPartition", QStringLiteral( "/boot/efi" ) ) );
// This specific GS key is also used by bootloader and grubcfg modules,
// as well as partition module internalls.
gs->insert( "efiSystemPartition", efiSystemPartition );
}

// Sizes
{
const auto efiRecommendedSize = Calamares::getString(
efiConfiguration, "recommendedSize", Calamares::getString( configurationMap, "efiSystemPartitionSize" ) );
if ( !efiRecommendedSize.isEmpty() )
{
// Insert once as string, once as a size-in-bytes;
// changes to these keys should be synchronized with PartUtils.cpp
gs->insert( "efiSystemPartitionSize", sizeString );
gs->insert( "efiSystemPartitionSize_i", part_size.toBytes() );

// Assign long long int to long unsigned int to prevent compilation warning
auto byte_part_size = part_size.toBytes();
if ( byte_part_size != PartUtils::efiFilesystemMinimumSize() )
Calamares::Partition::PartitionSize part_size = Calamares::Partition::PartitionSize( efiRecommendedSize );
if ( part_size.isValid() )
{
cWarning() << "EFI partition size" << sizeString << "has been adjusted to"
<< PartUtils::efiFilesystemMinimumSize() << "bytes";
gs->insert( PartUtils::efiFilesystemRecommendedSizeGSKey(), part_size.toBytes() );

// Assign long long int to long unsigned int to prevent compilation warning,
// checks for loss-of-precision in the conversion.
auto byte_part_size = part_size.toBytes();
if ( byte_part_size != PartUtils::efiFilesystemRecommendedSize() )
{
cWarning() << "EFI partition size" << efiRecommendedSize << "has been adjusted to"
<< PartUtils::efiFilesystemRecommendedSize() << "bytes";
}
}
else
{
cWarning() << "EFI partition size" << efiRecommendedSize << "is invalid, ignored";
}
}
else

const auto efiMinimumSize = Calamares::getString( efiConfiguration, "minimumSize" );
if ( !efiMinimumSize.isEmpty() )
{
cWarning() << "EFI partition size" << sizeString << "is invalid, ignored";
Calamares::Partition::PartitionSize part_size = Calamares::Partition::PartitionSize( efiMinimumSize );
if ( part_size.isValid() )
{
gs->insert( PartUtils::efiFilesystemMinimumSizeGSKey(), part_size.toBytes() );
}
}
}

// Read and parse key efiSystemPartitionName
if ( configurationMap.contains( "efiSystemPartitionName" ) )
// Name (label) of partition
{
gs->insert( "efiSystemPartitionName", Calamares::getString( configurationMap, "efiSystemPartitionName" ) );
const auto efiLabel = Calamares::getString(
efiConfiguration, "label", Calamares::getString( configurationMap, "efiSystemPartitionName" ) );

if ( !efiLabel.isEmpty() )
{
gs->insert( "efiSystemPartitionName", efiLabel );
}
}
}

Expand Down
21 changes: 9 additions & 12 deletions src/modules/partition/PartitionViewStep.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -527,8 +527,8 @@ PartitionViewStep::onLeave()
Logger::Once o;

const bool okType = esp && PartUtils::isEfiFilesystemSuitableType( esp );
const bool okRecommendedSize = esp && PartUtils::isEfiFilesystemSuitableSize( esp );
const bool okMinimumSize = esp && PartUtils::isEfiFilesystemSuitableMinimumSize( esp );
const bool okRecommendedSize = esp && PartUtils::isEfiFilesystemRecommendedSize( esp );
const bool okMinimumSize = esp && PartUtils::isEfiFilesystemMinimumSize( esp );
const bool okFlag = esp && PartUtils::isEfiBootable( esp );

const bool espExistsButIsWrong = esp && !( okType && okMinimumSize && okFlag );
Expand All @@ -552,24 +552,21 @@ PartitionViewStep::onLeave()
const QString wrongFlagMessage = tr( "The filesystem must have flag <strong>%1</strong> set." )
.arg( PartitionTable::flagName( PartitionTable::Flag::Boot ) );

// Three flavors of size-is-wrong
using Calamares::Units::operator""_MiB;

const qint64 atLeastBytes = static_cast< qint64 >( PartUtils::efiFilesystemMinimumSize() );
const auto atLeastMiB = Calamares::BytesToMiB( atLeastBytes );
const auto recommendedMiB = Calamares::BytesToMiB( PartUtils::efiFilesystemRecommendedSize() );
const auto minimumMiB = Calamares::BytesToMiB( PartUtils::efiFilesystemMinimumSize() );

// Three flavors of size-is-wrong
const QString requireConfiguredSize
= tr( "The filesystem must be at least %1 MiB in size." ).arg( atLeastMiB );
= tr( "The filesystem must be at least %1 MiB in size." ).arg( recommendedMiB );
const QString requiredMinimumSize
= tr( "The filesystem must be at least %1 MiB in size." ).arg( Calamares::BytesToMiB( 32_MiB ) );
= tr( "The filesystem must be at least %1 MiB in size." ).arg( minimumMiB );
const QString suggestConfiguredSize
= tr( "The minimum recommended size for the filesystem is %1 MiB." ).arg( atLeastMiB );

= tr( "The minimum recommended size for the filesystem is %1 MiB." ).arg( recommendedMiB );

const QString mayFail = tr( "You can continue without setting up an EFI system "
"partition but your system may fail to start." );
const QString possibleFail = tr( "You can continue with this EFI system "
"partition configuration but your system may fail to start." );
"partition configuration but your system may fail to start." );

const QString startList = QStringLiteral( "<br/><br/><ul>" );
const QString endList = QStringLiteral( "</ul><br/><br/>" );
Expand Down
65 changes: 54 additions & 11 deletions src/modules/partition/core/PartUtils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,10 @@
using Calamares::Partition::isPartitionFreeSpace;
using Calamares::Partition::isPartitionNew;

using Calamares::Units::operator""_MiB;

static constexpr qint64 efiSpecificationHardMinimumSize = 32_MiB;

namespace PartUtils
{

Expand Down Expand Up @@ -471,15 +475,15 @@ isEfiFilesystemSuitableType( const Partition* candidate )
}

bool
isEfiFilesystemSuitableSize( const Partition* candidate )
isEfiFilesystemRecommendedSize( const Partition* candidate )
{
auto size = candidate->capacity(); // bytes
if ( size <= 0 )
{
return false;
}

if ( size >= efiFilesystemMinimumSize() )
if ( size >= efiFilesystemRecommendedSize() )
{
return true;
}
Expand All @@ -491,7 +495,7 @@ isEfiFilesystemSuitableSize( const Partition* candidate )
}

bool
isEfiFilesystemSuitableMinimumSize( const Partition* candidate )
isEfiFilesystemMinimumSize( const Partition* candidate )
{
using Calamares::Units::operator""_MiB;

Expand All @@ -500,8 +504,12 @@ isEfiFilesystemSuitableMinimumSize( const Partition* candidate )
{
return false;
}
if ( size < efiSpecificationHardMinimumSize )
{
return false;
}

if ( size >= 32_MiB )
if ( size >= efiFilesystemMinimumSize() )
{
return true;
}
Expand All @@ -522,28 +530,63 @@ isEfiBootable( const Partition* candidate )
return flags.testFlag( KPM_PARTITION_FLAG_ESP );
}

// TODO: this is configurable via the config file **already**
QString
efiFilesystemRecommendedSizeGSKey()
{
return QStringLiteral( "efiSystemPartitionSize_i" );
}

qint64
efiFilesystemMinimumSize()
efiFilesystemRecommendedSize()
{
using Calamares::Units::operator""_MiB;
const QString key = efiFilesystemRecommendedSizeGSKey();

qint64 uefisys_part_sizeB = 300_MiB;

// The default can be overridden; the key used here comes
// from the partition module Config.cpp
auto* gs = Calamares::JobQueue::instance()->globalStorage();
if ( gs->contains( "efiSystemPartitionSize_i" ) )
if ( gs->contains( key ) )
{
qint64 v = gs->value( key ).toLongLong();
uefisys_part_sizeB = v > 0 ? v : 0;
}
// There is a lower limit of what can be configured
if ( uefisys_part_sizeB < efiSpecificationHardMinimumSize )
{
uefisys_part_sizeB = efiSpecificationHardMinimumSize;
}
return uefisys_part_sizeB;
}

QString
efiFilesystemMinimumSizeGSKey()
{
return QStringLiteral( "efiSystemPartitionMinimumSize_i" );
}

qint64
efiFilesystemMinimumSize()
{
const QString key = efiFilesystemMinimumSizeGSKey();

qint64 uefisys_part_sizeB = efiFilesystemRecommendedSize();

// The default can be overridden; the key used here comes
// from the partition module Config.cpp
auto* gs = Calamares::JobQueue::instance()->globalStorage();
if ( gs->contains( key ) )
{
qint64 v = gs->value( "efiSystemPartitionSize_i" ).toLongLong();
qint64 v = gs->value( key ).toLongLong();
uefisys_part_sizeB = v > 0 ? v : 0;
}
// There is a lower limit of what can be configured
if ( uefisys_part_sizeB < 32_MiB )
if ( uefisys_part_sizeB < efiSpecificationHardMinimumSize )
{
uefisys_part_sizeB = 32_MiB;
uefisys_part_sizeB = efiSpecificationHardMinimumSize;
}
return uefisys_part_sizeB;
return efiSpecificationHardMinimumSize;
}

QString
Expand Down
22 changes: 17 additions & 5 deletions src/modules/partition/core/PartUtils.h
Original file line number Diff line number Diff line change
Expand Up @@ -95,15 +95,15 @@ bool isEfiFilesystemSuitableType( const Partition* candidate );

/**
* @brief Is the @p partition suitable as an EFI boot partition?
* Checks for filesystem size (300MiB, see efiFilesystemMinimumSize).
* Checks for filesystem size (300MiB, see efi.recommendedSize).
*/
bool isEfiFilesystemSuitableSize( const Partition* candidate );
bool isEfiFilesystemRecommendedSize( const Partition* candidate );

/**
* @brief Is the @p candidate suitable as an EFI boot partition?
* This checks the bonkers-small minimum of 32MiB.
* Checks for filesystem size (32MiB at least, see efi.minimumSize).
*/
bool isEfiFilesystemSuitableMinimumSize( const Partition* candidate );
bool isEfiFilesystemMinimumSize( const Partition* candidate );

/** @brief Returns the minimum size of an EFI boot partition in bytes.
*
Expand All @@ -113,13 +113,25 @@ bool isEfiFilesystemSuitableMinimumSize( const Partition* candidate );
* by the standard and how all of those are different).
*
* This can be configured through the `partition.conf` file,
* key *efiSystemPartitionSize*, which will then apply to both
* key *efi.recommendedSize*, which will then apply to both
* automatic partitioning **and** the warning for manual partitioning.
*
* A minimum of 32MiB (which is bonkers-small) is enforced.
*/
qint64 efiFilesystemRecommendedSize();

// Helper for consistency: the GS key used to share the recommended size
QString efiFilesystemRecommendedSizeGSKey();

/** @brief Returns the hard-minimum size of an EFI boot partition in bytes.
*
* This is 32MiB, based on the FAT32 standard and EFI documentation.
*/
qint64 efiFilesystemMinimumSize();

// Helper for consistency: the GS key used to share the minimum size
QString efiFilesystemMinimumSizeGSKey();

/**
* @brief Is the given @p partition bootable in EFI? Depending on
* the partition table layout, this may mean different flags.
Expand Down
2 changes: 1 addition & 1 deletion src/modules/partition/core/PartitionActions.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,7 @@ doAutopartition( PartitionCoreModule* core, Device* dev, Choices::AutoPartitionO

if ( isEfi )
{
qint64 uefisys_part_sizeB = PartUtils::efiFilesystemMinimumSize();
qint64 uefisys_part_sizeB = PartUtils::efiFilesystemRecommendedSize();
qint64 efiSectorCount = Calamares::bytesToSectors( uefisys_part_sizeB, dev->logicalSize() );
Q_ASSERT( efiSectorCount > 0 );

Expand Down
Loading

0 comments on commit 1e1e12f

Please sign in to comment.