diff --git a/cmd/rofl/build/artifacts.go b/cmd/rofl/build/artifacts.go index b4a3054..1e09753 100644 --- a/cmd/rofl/build/artifacts.go +++ b/cmd/rofl/build/artifacts.go @@ -364,6 +364,22 @@ func concatFiles(a, b string) error { return err } +// padWithEmptySpace pads the given file with empty space to make it the given size. See +// `appendEmptySpace` for details. +func padWithEmptySpace(fn string, size uint64) error { + fi, err := os.Stat(fn) + if err != nil { + return err + } + + currentSize := uint64(fi.Size()) + if currentSize >= size { + return nil + } + _, err = appendEmptySpace(fn, size - currentSize, 1) + return err +} + // appendEmptySpace appends empty space to the given file. If the filesystem supports sparse files, // this should not actually take any extra space. // diff --git a/cmd/rofl/build/tdx.go b/cmd/rofl/build/tdx.go index 786a61a..36d817b 100644 --- a/cmd/rofl/build/tdx.go +++ b/cmd/rofl/build/tdx.go @@ -244,26 +244,32 @@ func tdxBundleComponent( fmt.Sprintf("oasis.stage2.storage_size=%d", manifest.Resources.Storage.Size*1024*1024), ) case buildRofl.StorageKindDiskEphemeral, buildRofl.StorageKindDiskPersistent: - // Allocate some space after regular stage2. - const sectorSize = 512 - storageSize := manifest.Resources.Storage.Size * 1024 * 1024 - storageOffset, err := appendEmptySpace(stage2.fn, storageSize, sectorSize) - if err != nil { - return err - } - var storageMode string switch storageKind { case buildRofl.StorageKindDiskPersistent: // Persistent storage needs to be set up by stage 2. storageMode = "custom" + // Add some sparse padding to allow for growth of the root partition during upgrades. + // Note that this will not actually take any space so it could be arbitrarily large. + if err := padWithEmptySpace(stage2.fn, 256*1024*1024); err != nil { + return err + } + // TODO: (Oasis Core 25.0+) Set comp.TDX.Stage2Persist = true case buildRofl.StorageKindDiskEphemeral: // Ephemeral storage can be set up by stage 1 directly. storageMode = "disk" } + // Allocate some space after regular stage2. + const sectorSize = 512 + storageSize := manifest.Resources.Storage.Size * 1024 * 1024 + storageOffset, err := appendEmptySpace(stage2.fn, storageSize, sectorSize) + if err != nil { + return err + } + comp.TDX.ExtraKernelOptions = append(comp.TDX.ExtraKernelOptions, fmt.Sprintf("oasis.stage2.storage_mode=%s", storageMode), fmt.Sprintf("oasis.stage2.storage_size=%d", storageSize/sectorSize),