disk: clone partition table before modifying it

The partition table is modified `CreatePartitionTable`, which is
not a problem for the table itself since it is currently passed
by value. However, all shallow copies share the same file system
pointers and `CreatePartitionTable` will modify those as well.
As there is a data race where two concurrent thread modify the
content of the Fileystem object at the same time before writing
the uuids out to the manifest via the stage options and thus the
resulting manifest would be broken.
Therefore we use the new `Clone` methods to make a dee@ copy of
the `PartitionTable` object in the `CreatePartitionTable` method;
This will allow us to pass the `basePartitionTable` object by val
and also return the resulting `PartitionTable` as a pointer.
This commit is contained in:
Christian Kellner 2021-11-10 13:55:18 +00:00 committed by Tom Gundersen
parent d7df6b3d5c
commit fb7f92aa95

View file

@ -31,7 +31,12 @@ func CreatePartitionTable(
rng *rand.Rand,
) PartitionTable {
if bootPartition := basePartitionTable.BootPartition(); bootPartition != nil {
// we are modifying the contents of the base partition table,
// including the file systems, which are shared among shallow
// copies of the partition table, so make a copy first
table := basePartitionTable.Clone()
if bootPartition := table.BootPartition(); bootPartition != nil {
// the boot partition UUID needs to be set since this
// needs to be randomly generated
bootPartition.Filesystem.UUID = uuid.Must(newRandomUUIDFromReader(rng)).String()
@ -40,27 +45,27 @@ func CreatePartitionTable(
for _, m := range mountpoints {
if m.Mountpoint != "/" {
partitionSize := m.MinSize / sectorSize
basePartitionTable.createFilesystem(m.Mountpoint, partitionSize, rng)
table.createFilesystem(m.Mountpoint, partitionSize, rng)
}
}
if tableSize := basePartitionTable.getPartitionTableSize(); imageSize < tableSize {
if tableSize := table.getPartitionTableSize(); imageSize < tableSize {
imageSize = tableSize
}
basePartitionTable.Size = imageSize
table.Size = imageSize
// start point for all of the arches is
// 2048 sectors.
var start uint64 = basePartitionTable.updatePartitionStartPointOffsets(2048)
var start uint64 = table.updatePartitionStartPointOffsets(2048)
// treat the root partition as a special case
// by setting the size dynamically
rootPartition := basePartitionTable.RootPartition()
rootPartition := table.RootPartition()
rootPartition.Size = ((imageSize / sectorSize) - start - 100)
rootPartition.Filesystem.UUID = uuid.Must(newRandomUUIDFromReader(rng)).String()
return basePartitionTable
return *table
}
func (pt *PartitionTable) createFilesystem(mountpoint string, size uint64, rng *rand.Rand) {