Skip to content

Commit

Permalink
[Upgrade Details] Fix corruption when writing upgrade marker file (#3948
Browse files Browse the repository at this point in the history
) (#3951)

* Truncate marker file before writing

* Add unit test for truncation

(cherry picked from commit 8f543bb)

Co-authored-by: Shaunak Kashyap <[email protected]>
  • Loading branch information
2 people authored and cmacknz committed Jan 17, 2024
1 parent 75d44e0 commit b9960ab
Show file tree
Hide file tree
Showing 2 changed files with 57 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import (
)

func writeMarkerFileCommon(markerFile string, markerBytes []byte, shouldFsync bool) error {
f, err := os.OpenFile(markerFile, os.O_WRONLY|os.O_CREATE, 0600)
f, err := os.OpenFile(markerFile, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0600)
if err != nil {
return fmt.Errorf("failed to open upgrade marker file for writing: %w", err)
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
// Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
// or more contributor license agreements. Licensed under the Elastic License;
// you may not use this file except in compliance with the Elastic License.

package upgrade

import (
"math/rand"
"os"
"path/filepath"
"testing"

"github.com/stretchr/testify/require"
)

func TestWriteMarkerFileWithTruncation(t *testing.T) {
tmpDir := t.TempDir()
testMarkerFile := filepath.Join(tmpDir, markerFilename)

// Write a long marker file
err := writeMarkerFileCommon(testMarkerFile, randomBytes(40), true)
require.NoError(t, err)

// Get length of file
fileInfo, err := os.Stat(testMarkerFile)
require.NoError(t, err)
originalSize := fileInfo.Size()

// Write a shorter marker file
err = writeMarkerFileCommon(testMarkerFile, randomBytes(25), true)
require.NoError(t, err)

// Get length of file
fileInfo, err = os.Stat(testMarkerFile)
require.NoError(t, err)
newSize := fileInfo.Size()

// Make sure shorter file has is smaller in length than
// the original long marker file
require.Less(t, newSize, originalSize)
}

func randomBytes(length int) []byte {
chars := []rune("ABCDEFGHIJKLMNOPQRSTUVWXYZÅÄÖ" +
"abcdefghijklmnopqrstuvwxyzåäö" +
"0123456789" +
"~=+%^*/()[]{}/!@#$?|")

var b []byte
for i := 0; i < length; i++ {
rune := chars[rand.Intn(len(chars))]
b = append(b, byte(rune))
}

return b
}

0 comments on commit b9960ab

Please sign in to comment.