Skip to content

Commit

Permalink
fix: skip writing the file if the contents haven't changed
Browse files Browse the repository at this point in the history
As the controller reconciles every /etc file present, it might be called
multiple times for the same file, even if the actual contents haven't
changed.

Rewriting the file might lead to some concurrent process seeing
incomplete file contents more often than needed.

Signed-off-by: Andrey Smirnov <[email protected]>
(cherry picked from commit dbf274d)
  • Loading branch information
smira committed Dec 8, 2023
1 parent ecee92c commit cc16b96
Showing 1 changed file with 13 additions and 1 deletion.
14 changes: 13 additions & 1 deletion internal/app/machined/pkg/controllers/files/etcfile.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
package files

import (
"bytes"
"context"
"errors"
"fmt"
Expand Down Expand Up @@ -132,7 +133,7 @@ func (ctrl *EtcFileController) Run(ctx context.Context, r controller.Runtime, lo

logger.Debug("writing file contents", zap.String("dst", dst), zap.Stringer("version", spec.Metadata().Version()))

if err = os.WriteFile(dst, spec.TypedSpec().Contents, spec.TypedSpec().Mode); err != nil {
if err = updateFile(dst, spec.TypedSpec().Contents, spec.TypedSpec().Mode); err != nil {
return fmt.Errorf("error updating %q: %w", dst, err)
}

Expand Down Expand Up @@ -190,3 +191,14 @@ func createBindMount(src, dst string, mode os.FileMode) (err error) {

return nil
}

// updateFile is like `os.WriteFile`, but it will only update the file if the
// contents have changed.
func updateFile(filename string, contents []byte, mode os.FileMode) error {
oldContents, err := os.ReadFile(filename)
if err == nil && bytes.Equal(oldContents, contents) {
return nil
}

return os.WriteFile(filename, contents, mode)
}

0 comments on commit cc16b96

Please sign in to comment.