Skip to content

Commit dc7971f

Browse files
committed
internal/filesystem minor fix
In case of error during write, the destination is being removed (before being possibly restored). This may lead to certain (failure) scenarios where the inode would change, effectively breaking container mounted files. Signed-off-by: apostasie <[email protected]>
1 parent 599681f commit dc7971f

File tree

2 files changed

+17
-10
lines changed

2 files changed

+17
-10
lines changed

pkg/internal/filesystem/helpers.go

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ func ensureRecovery(filename string) (err error) {
5454
if err = backupRestore(filename); err != nil {
5555
return err
5656
}
57+
_ = backupRemove(filename)
5758
} else {
5859
// We do not see a backup.
5960
// Do we have a final destination then?
@@ -101,6 +102,10 @@ func backupRestore(path string) error {
101102
return err
102103
}
103104

105+
func backupRemove(path string) error {
106+
return os.Remove(backupLocation(path))
107+
}
108+
104109
// backupExists checks if a backup file exists for file located at `path`.
105110
func backupExists(path string) (bool, error) {
106111
_, err := os.Stat(backupLocation(path))
@@ -190,16 +195,16 @@ func internalCopy(sourcePath, destinationPath string) (err error) {
190195
return err
191196
}
192197

198+
defer func() {
199+
err = errors.Join(err, source.Close())
200+
}()
201+
193202
// Read file length
194203
srcInfo, err := source.Stat()
195204
if err != nil {
196205
return err
197206
}
198207

199-
defer func() {
200-
err = errors.Join(err, source.Close())
201-
}()
202-
203208
return fileWrite(source, srcInfo.Size(), destinationPath, privateFilePermission, srcInfo.ModTime())
204209
}
205210

@@ -220,11 +225,6 @@ func fileWrite(source io.Reader, size int64, destinationPath string, perm os.Fil
220225
if mustClose {
221226
err = errors.Join(err, destination.Close())
222227
}
223-
224-
// Remove destination if we failed anywhere. Ignore removal failures.
225-
if err != nil {
226-
_ = os.Remove(destinationPath)
227-
}
228228
}()
229229

230230
// Copy over

pkg/internal/filesystem/writefile_rollback.go

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,15 +61,22 @@ func WriteFileWithRollback(filename string, data []byte, perm os.FileMode) (roll
6161
}
6262
}
6363

64+
// Make sure no leftover backup file is here
65+
// Note: this happens after a successful write. Generally not a problem, except if the file is then deleted,
66+
// then written to again, and that second write would fail.
67+
_ = backupRemove(filename)
68+
6469
// Create the marker. Failure to do so is a hard error.
6570
if err = markerCreate(filename, markerData); err != nil {
6671
return nil, err
6772
}
6873

6974
// If the file exists, we need to back it up.
7075
if markerData == "" {
71-
// Back it up now.
76+
// Back it up now. Remove on failure.
7277
if err = backupSave(filename); err != nil {
78+
_ = backupRemove(filename)
79+
_ = markerRemove(filename)
7380
return nil, err
7481
}
7582
}

0 commit comments

Comments
 (0)