diff --git a/pkg/pillar/cmd/baseosmgr/handlebaseos.go b/pkg/pillar/cmd/baseosmgr/handlebaseos.go index c548abbcd5..f6a09283cc 100644 --- a/pkg/pillar/cmd/baseosmgr/handlebaseos.go +++ b/pkg/pillar/cmd/baseosmgr/handlebaseos.go @@ -259,6 +259,33 @@ func doBaseOsActivate(ctx *baseOsMgrContext, uuidStr string, log.Functionf("doBaseOsActivate: %s activating", uuidStr) + // Before writing to partition lets make sure we have enough space on the partition + // 1. Get the size of the image using contenttree status + // 2. Get the size of the partition using zboot + // 3. If partition size is < image size, error out + + cts := lookupContentTreeStatus(ctx, status.ContentTreeUUID) + + if cts == nil { + errString := fmt.Sprintf("doBaseOsActivate: ContentTreeStatus not found for %s", status.ContentTreeUUID) + log.Error(errString) + status.SetErrorNow(errString) + changed = true + return changed + } + + if cts.State == types.LOADED { + partSize := zboot.GetPartitionSizeInBytes(status.PartitionLabel) + imageSize := cts.MaxDownloadSize + if partSize < imageSize { + errString := fmt.Sprintf("doBaseOsActivate: Image size %v bytes greater than partition size %v bytes", imageSize, partSize) + log.Error(errString) + status.SetErrorNow(errString) + changed = true + return changed + } + } + // install the image at proper partition; dd etc changed, proceed, err = installDownloadedObjects(ctx, uuidStr, status.PartitionLabel, status.ContentTreeUUID) diff --git a/pkg/pillar/zboot/zboot.go b/pkg/pillar/zboot/zboot.go index 41849a0cbf..ab9104d9d7 100644 --- a/pkg/pillar/zboot/zboot.go +++ b/pkg/pillar/zboot/zboot.go @@ -7,11 +7,11 @@ package zboot import ( "context" - "encoding/binary" "errors" "fmt" "os" "os/exec" + "strconv" "strings" "sync" "syscall" @@ -256,11 +256,20 @@ func GetPartitionSizeInBytes(partName string) uint64 { validatePartitionName(partName) _, ok := partDev[partName] if ok { - partsize, err := execWithRetry(nil, "zboot", "partdevsize", partName) + ret, err := execWithRetry(nil, "zboot", "partdevsize", partName) if err != nil { logrus.Fatalf("zboot partdevsize %s: err %v\n", partName, err) } - return binary.BigEndian.Uint64(partsize) + partsize := string(ret) + partsize = strings.TrimSpace(partsize) + logrus.Infof("partsize in bytes %s", partsize) + value, err := strconv.ParseUint(partsize, 10, 64) + if err != nil { + logrus.Errorf("Strconv failed for partsize err %v\n", err) + return 0 + } + + return value } // Invalid partition