mirror of
https://github.com/VictoriaMetrics/VictoriaMetrics.git
synced 2025-03-11 15:34:56 +00:00
lib/fs: remove logging redundant path values in a single error message
This commit is contained in:
parent
dc890ab80c
commit
81400c80f0
4 changed files with 43 additions and 24 deletions
57
lib/fs/fs.go
57
lib/fs/fs.go
|
@ -25,11 +25,38 @@ func MustSyncPath(path string) {
|
||||||
mustSyncPath(path)
|
mustSyncPath(path)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// WriteFileAndSync writes data to the file at path and then calls fsync on the created file.
|
||||||
|
//
|
||||||
|
// The fsync guarantees that the written data survives hardware reset after successful call.
|
||||||
|
//
|
||||||
|
// This function may leave the file at the path in inconsistent state on app crash
|
||||||
|
// in the middle of the write.
|
||||||
|
// Use WriteFileAtomically if the file at the path must be either written in full
|
||||||
|
// or not written at all on app crash in the middle of the write.
|
||||||
|
func WriteFileAndSync(path string, data []byte) error {
|
||||||
|
f, err := filestream.Create(path, false)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if _, err := f.Write(data); err != nil {
|
||||||
|
f.MustClose()
|
||||||
|
// Do not call MustRemoveAll(path), so the user could inpsect
|
||||||
|
// the file contents during investigation of the issue.
|
||||||
|
return fmt.Errorf("cannot write %d bytes to %q: %w", len(data), path, err)
|
||||||
|
}
|
||||||
|
// Sync and close the file.
|
||||||
|
f.MustClose()
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
// WriteFileAtomically atomically writes data to the given file path.
|
// WriteFileAtomically atomically writes data to the given file path.
|
||||||
//
|
//
|
||||||
// WriteFileAtomically returns only after the file is fully written and synced
|
// This function returns only after the file is fully written and synced
|
||||||
// to the underlying storage.
|
// to the underlying storage.
|
||||||
//
|
//
|
||||||
|
// This function guarantees that the file at path either fully written or not written at all on app crash
|
||||||
|
// in the middle of the write.
|
||||||
|
//
|
||||||
// If the file at path already exists, then the file is overwritten atomically if canOverwrite is true.
|
// If the file at path already exists, then the file is overwritten atomically if canOverwrite is true.
|
||||||
// Otherwise error is returned.
|
// Otherwise error is returned.
|
||||||
func WriteFileAtomically(path string, data []byte, canOverwrite bool) error {
|
func WriteFileAtomically(path string, data []byte, canOverwrite bool) error {
|
||||||
|
@ -40,26 +67,18 @@ func WriteFileAtomically(path string, data []byte, canOverwrite bool) error {
|
||||||
return fmt.Errorf("cannot create file %q, since it already exists", path)
|
return fmt.Errorf("cannot create file %q, since it already exists", path)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Write data to a temporary file.
|
||||||
n := atomic.AddUint64(&tmpFileNum, 1)
|
n := atomic.AddUint64(&tmpFileNum, 1)
|
||||||
tmpPath := fmt.Sprintf("%s.tmp.%d", path, n)
|
tmpPath := fmt.Sprintf("%s.tmp.%d", path, n)
|
||||||
f, err := filestream.Create(tmpPath, false)
|
if err := WriteFileAndSync(tmpPath, data); err != nil {
|
||||||
if err != nil {
|
return fmt.Errorf("cannot write data to temporary file: %w", err)
|
||||||
return fmt.Errorf("cannot create file %q: %w", tmpPath, err)
|
|
||||||
}
|
|
||||||
if _, err := f.Write(data); err != nil {
|
|
||||||
f.MustClose()
|
|
||||||
MustRemoveAll(tmpPath)
|
|
||||||
return fmt.Errorf("cannot write %d bytes to file %q: %w", len(data), tmpPath, err)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Sync and close the file.
|
// Atomically move the temporary file from tmpPath to path.
|
||||||
f.MustClose()
|
|
||||||
|
|
||||||
// Atomically move the file from tmpPath to path.
|
|
||||||
if err := os.Rename(tmpPath, path); err != nil {
|
if err := os.Rename(tmpPath, path); err != nil {
|
||||||
// do not call MustRemoveAll(tmpPath) here, so the user could inspect
|
// do not call MustRemoveAll(tmpPath) here, so the user could inspect
|
||||||
// the file contents during investigating the issue.
|
// the file contents during investigation of the issue.
|
||||||
return fmt.Errorf("cannot move %q to %q: %w", tmpPath, path, err)
|
return fmt.Errorf("cannot move temporary file %q to %q: %w", tmpPath, path, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Sync the containing directory, so the file is guaranteed to appear in the directory.
|
// Sync the containing directory, so the file is guaranteed to appear in the directory.
|
||||||
|
@ -123,7 +142,7 @@ func RemoveDirContents(dir string) {
|
||||||
}
|
}
|
||||||
d, err := os.Open(dir)
|
d, err := os.Open(dir)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logger.Panicf("FATAL: cannot open dir %q: %s", dir, err)
|
logger.Panicf("FATAL: cannot open dir: %s", err)
|
||||||
}
|
}
|
||||||
defer MustClose(d)
|
defer MustClose(d)
|
||||||
names, err := d.Readdirnames(-1)
|
names, err := d.Readdirnames(-1)
|
||||||
|
@ -185,7 +204,7 @@ func IsEmptyDir(path string) bool {
|
||||||
// See https://stackoverflow.com/a/30708914/274937
|
// See https://stackoverflow.com/a/30708914/274937
|
||||||
f, err := os.Open(path)
|
f, err := os.Open(path)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logger.Panicf("FATAL: unexpected error when opening directory %q: %s", path, err)
|
logger.Panicf("FATAL: cannot open dir: %s", err)
|
||||||
}
|
}
|
||||||
_, err = f.Readdirnames(1)
|
_, err = f.Readdirnames(1)
|
||||||
MustClose(f)
|
MustClose(f)
|
||||||
|
@ -230,7 +249,7 @@ var atomicDirRemoveCounter = uint64(time.Now().UnixNano())
|
||||||
func MustRemoveTemporaryDirs(dir string) {
|
func MustRemoveTemporaryDirs(dir string) {
|
||||||
d, err := os.Open(dir)
|
d, err := os.Open(dir)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logger.Panicf("FATAL: cannot open dir %q: %s", dir, err)
|
logger.Panicf("FATAL: cannot open dir: %s", err)
|
||||||
}
|
}
|
||||||
defer MustClose(d)
|
defer MustClose(d)
|
||||||
fis, err := d.Readdir(-1)
|
fis, err := d.Readdir(-1)
|
||||||
|
@ -259,7 +278,7 @@ func HardLinkFiles(srcDir, dstDir string) error {
|
||||||
|
|
||||||
d, err := os.Open(srcDir)
|
d, err := os.Open(srcDir)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("cannot open srcDir=%q: %w", srcDir, err)
|
return fmt.Errorf("cannot open srcDir: %w", err)
|
||||||
}
|
}
|
||||||
defer func() {
|
defer func() {
|
||||||
if err := d.Close(); err != nil {
|
if err := d.Close(); err != nil {
|
||||||
|
|
|
@ -19,7 +19,7 @@ func mUnmap(data []byte) error {
|
||||||
func mustSyncPath(path string) {
|
func mustSyncPath(path string) {
|
||||||
d, err := os.Open(path)
|
d, err := os.Open(path)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logger.Panicf("FATAL: cannot open %q: %s", path, err)
|
logger.Panicf("FATAL: cannot open file for fsync: %s", err)
|
||||||
}
|
}
|
||||||
if err := d.Sync(); err != nil {
|
if err := d.Sync(); err != nil {
|
||||||
_ = d.Close()
|
_ = d.Close()
|
||||||
|
@ -51,7 +51,7 @@ func createFlockFile(flockFile string) (*os.File, error) {
|
||||||
func mustGetFreeSpace(path string) uint64 {
|
func mustGetFreeSpace(path string) uint64 {
|
||||||
d, err := os.Open(path)
|
d, err := os.Open(path)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logger.Panicf("FATAL: cannot determine free disk space on %q: %s", path, err)
|
logger.Panicf("FATAL: cannot open dir for determining free disk space: %s", err)
|
||||||
}
|
}
|
||||||
defer MustClose(d)
|
defer MustClose(d)
|
||||||
|
|
||||||
|
|
|
@ -22,7 +22,7 @@ func mUnmap(data []byte) error {
|
||||||
func mustSyncPath(path string) {
|
func mustSyncPath(path string) {
|
||||||
d, err := os.Open(path)
|
d, err := os.Open(path)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logger.Panicf("FATAL: cannot open %q: %s", path, err)
|
logger.Panicf("FATAL: cannot open file for fsync: %s", err)
|
||||||
}
|
}
|
||||||
if err := d.Sync(); err != nil {
|
if err := d.Sync(); err != nil {
|
||||||
_ = d.Close()
|
_ = d.Close()
|
||||||
|
@ -47,7 +47,7 @@ func createFlockFile(flockFile string) (*os.File, error) {
|
||||||
func mustGetFreeSpace(path string) uint64 {
|
func mustGetFreeSpace(path string) uint64 {
|
||||||
d, err := os.Open(path)
|
d, err := os.Open(path)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logger.Panicf("FATAL: cannot determine free disk space on %q: %s", path, err)
|
logger.Panicf("FATAL: cannot open dir for determining free disk space: %s", err)
|
||||||
}
|
}
|
||||||
defer MustClose(d)
|
defer MustClose(d)
|
||||||
|
|
||||||
|
|
|
@ -89,7 +89,7 @@ func (r *ReaderAt) MustFadviseSequentialRead(prefetch bool) {
|
||||||
func MustOpenReaderAt(path string) *ReaderAt {
|
func MustOpenReaderAt(path string) *ReaderAt {
|
||||||
f, err := os.Open(path)
|
f, err := os.Open(path)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logger.Panicf("FATAL: cannot open file %q for reading: %s", path, err)
|
logger.Panicf("FATAL: cannot open file for reading: %s", err)
|
||||||
}
|
}
|
||||||
var r ReaderAt
|
var r ReaderAt
|
||||||
r.f = f
|
r.f = f
|
||||||
|
|
Loading…
Reference in a new issue