Skip to content

Commit e4a2341

Browse files
committed
fix: skip writing the file if the contents haven't changed
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 <andrey.smirnov@siderolabs.com> (cherry picked from commit dbf274d)
1 parent 8516708 commit e4a2341

File tree

1 file changed

+13
-1
lines changed
  • internal/app/machined/pkg/controllers/files

1 file changed

+13
-1
lines changed

internal/app/machined/pkg/controllers/files/etcfile.go

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
package files
66

77
import (
8+
"bytes"
89
"context"
910
"errors"
1011
"fmt"
@@ -132,7 +133,7 @@ func (ctrl *EtcFileController) Run(ctx context.Context, r controller.Runtime, lo
132133

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

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

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

191192
return nil
192193
}
194+
195+
// updateFile is like `os.WriteFile`, but it will only update the file if the
196+
// contents have changed.
197+
func updateFile(filename string, contents []byte, mode os.FileMode) error {
198+
oldContents, err := os.ReadFile(filename)
199+
if err == nil && bytes.Equal(oldContents, contents) {
200+
return nil
201+
}
202+
203+
return os.WriteFile(filename, contents, mode)
204+
}

0 commit comments

Comments
 (0)