Skip to content

Commit b3a68b9

Browse files
committed
Prevent leaking file descriptor during snapshotting and provide better logging of errors
Signed-off-by: Marek Siarkowicz <[email protected]>
1 parent 9fa35e5 commit b3a68b9

File tree

1 file changed

+29
-8
lines changed

1 file changed

+29
-8
lines changed

client/v3/snapshot/v3_snapshot.go

Lines changed: 29 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ package snapshot
1717
import (
1818
"context"
1919
"crypto/sha256"
20+
"errors"
2021
"fmt"
2122
"io"
2223
"os"
@@ -54,38 +55,58 @@ func SaveWithVersion(ctx context.Context, lg *zap.Logger, cfg clientv3.Config, d
5455
if err != nil {
5556
return "", err
5657
}
57-
defer cli.Close()
58+
defer func() {
59+
err := cli.Close()
60+
if err != nil {
61+
lg.Error("Failed to close client", zap.Error(err))
62+
}
63+
}()
5864

5965
partpath := dbPath + ".part"
60-
defer os.RemoveAll(partpath)
66+
defer func() {
67+
err := os.RemoveAll(partpath)
68+
if err != nil {
69+
lg.Error("Failed to cleanup .part file", zap.Error(err))
70+
}
71+
}()
6172

62-
var f *os.File
63-
f, err = os.OpenFile(partpath, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, fileutil.PrivateFileMode)
73+
f, err := os.OpenFile(partpath, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, fileutil.PrivateFileMode)
6474
if err != nil {
6575
return "", fmt.Errorf("could not open %s (%w)", partpath, err)
6676
}
77+
defer func() {
78+
err := f.Close()
79+
if err != nil && !errors.Is(err, os.ErrClosed) {
80+
lg.Error("Could not close file descriptor", zap.Error(err))
81+
}
82+
}()
6783
lg.Info("created temporary db file", zap.String("path", partpath))
6884

6985
start := time.Now()
7086
resp, err := cli.SnapshotWithVersion(ctx)
7187
if err != nil {
7288
return "", err
7389
}
74-
defer resp.Snapshot.Close()
90+
defer func() {
91+
err := resp.Snapshot.Close()
92+
if err != nil {
93+
lg.Error("Could not close snapshot stream", zap.Error(err))
94+
}
95+
}()
7596
lg.Info("fetching snapshot", zap.String("endpoint", cfg.Endpoints[0]))
7697
var size int64
7798
size, err = io.Copy(f, resp.Snapshot)
7899
if err != nil {
79-
return resp.Version, err
100+
return resp.Version, fmt.Errorf("could not write snapshot: %w", err)
80101
}
81102
if !hasChecksum(size) {
82103
return resp.Version, fmt.Errorf("sha256 checksum not found [bytes: %d]", size)
83104
}
84105
if err = fileutil.Fsync(f); err != nil {
85-
return resp.Version, err
106+
return resp.Version, fmt.Errorf("could not fsync snapshot: %w", err)
86107
}
87108
if err = f.Close(); err != nil {
88-
return resp.Version, err
109+
return resp.Version, fmt.Errorf("could not close file descriptor: %w", err)
89110
}
90111
lg.Info("fetched snapshot",
91112
zap.String("endpoint", cfg.Endpoints[0]),

0 commit comments

Comments
 (0)