From f75b1b7a5362b4308b364d0a8d1918907ab26a71 Mon Sep 17 00:00:00 2001 From: Aliaksandr Valialkin Date: Thu, 13 Apr 2023 23:02:55 -0700 Subject: [PATCH] lib/fs: add Must prefix to CopyDirectory and CopyFile functions Callers of these functions log the returned error and then exit. Let's log the error with the call stack inside the function itself. This simplifies the code at callers' side, while leaving the same level of debuggability in case of errors. --- lib/fs/fs.go | 22 +++++++++------------- lib/storage/partition.go | 25 +++++++------------------ lib/storage/storage.go | 4 +--- lib/storage/table.go | 6 +----- 4 files changed, 18 insertions(+), 39 deletions(-) diff --git a/lib/fs/fs.go b/lib/fs/fs.go index 5c4bb3ed46..11e46d80f6 100644 --- a/lib/fs/fs.go +++ b/lib/fs/fs.go @@ -300,11 +300,11 @@ func MustSymlinkRelative(srcPath, dstPath string) { } } -// CopyDirectory copies all the files in srcPath to dstPath. -func CopyDirectory(srcPath, dstPath string) error { +// MustCopyDirectory copies all the files in srcPath to dstPath. +func MustCopyDirectory(srcPath, dstPath string) { des, err := os.ReadDir(srcPath) if err != nil { - return err + logger.Panicf("FATAL: cannot read srcDir: %s", err) } MustMkdirIfNotExist(dstPath) for _, de := range des { @@ -314,31 +314,27 @@ func CopyDirectory(srcPath, dstPath string) error { } src := filepath.Join(srcPath, de.Name()) dst := filepath.Join(dstPath, de.Name()) - if err := CopyFile(src, dst); err != nil { - return err - } + MustCopyFile(src, dst) } MustSyncPath(dstPath) - return nil } -// CopyFile copies the file from srcPath to dstPath. -func CopyFile(srcPath, dstPath string) error { +// MustCopyFile copies the file from srcPath to dstPath. +func MustCopyFile(srcPath, dstPath string) { src, err := os.Open(srcPath) if err != nil { - return err + logger.Panicf("FATAL: cannot open srcPath: %s", err) } defer MustClose(src) dst, err := os.Create(dstPath) if err != nil { - return err + logger.Panicf("FATAL: cannot create dstPath: %s", err) } defer MustClose(dst) if _, err := io.Copy(dst, src); err != nil { - return err + logger.Panicf("FATAL: cannot copy %q to %q: %s", srcPath, dstPath, err) } MustSyncPath(dstPath) - return nil } // ReadFullData reads len(data) bytes from r. diff --git a/lib/storage/partition.go b/lib/storage/partition.go index 5761a54731..ffbb74b76e 100644 --- a/lib/storage/partition.go +++ b/lib/storage/partition.go @@ -1849,10 +1849,10 @@ func mustCloseParts(pws []*partWrapper) { } } -// CreateSnapshotAt creates pt snapshot at the given smallPath and bigPath dirs. +// MustCreateSnapshotAt creates pt snapshot at the given smallPath and bigPath dirs. // // Snapshot is created using linux hard links, so it is usually created very quickly. -func (pt *partition) CreateSnapshotAt(smallPath, bigPath string) error { +func (pt *partition) MustCreateSnapshotAt(smallPath, bigPath string) { logger.Infof("creating partition snapshot of %q and %q...", pt.smallPartsPath, pt.bigPartsPath) startTime := time.Now() @@ -1877,22 +1877,15 @@ func (pt *partition) CreateSnapshotAt(smallPath, bigPath string) error { // Create a file with part names at smallPath mustWritePartNames(pwsSmall, pwsBig, smallPath) - if err := pt.createSnapshot(pt.smallPartsPath, smallPath, pwsSmall); err != nil { - return fmt.Errorf("cannot create snapshot for %q: %w", pt.smallPartsPath, err) - } - if err := pt.createSnapshot(pt.bigPartsPath, bigPath, pwsBig); err != nil { - return fmt.Errorf("cannot create snapshot for %q: %w", pt.bigPartsPath, err) - } + pt.mustCreateSnapshot(pt.smallPartsPath, smallPath, pwsSmall) + pt.mustCreateSnapshot(pt.bigPartsPath, bigPath, pwsBig) logger.Infof("created partition snapshot of %q and %q at %q and %q in %.3f seconds", pt.smallPartsPath, pt.bigPartsPath, smallPath, bigPath, time.Since(startTime).Seconds()) - return nil } -// createSnapshot creates a snapshot from srcDir to dstDir. -// -// The caller is responsible for deleting dstDir if createSnapshot() returns error. -func (pt *partition) createSnapshot(srcDir, dstDir string, pws []*partWrapper) error { +// mustCreateSnapshot creates a snapshot from srcDir to dstDir. +func (pt *partition) mustCreateSnapshot(srcDir, dstDir string, pws []*partWrapper) { // Make hardlinks for pws at dstDir for _, pw := range pws { srcPartPath := pw.p.path @@ -1907,16 +1900,12 @@ func (pt *partition) createSnapshot(srcDir, dstDir string, pws []*partWrapper) e srcPath := filepath.Join(srcDir, appliedRetentionFilename) if fs.IsPathExist(srcPath) { dstPath := filepath.Join(dstDir, filepath.Base(srcPath)) - if err := fs.CopyFile(srcPath, dstPath); err != nil { - return fmt.Errorf("cannot copy %q to %q: %w", srcPath, dstPath, err) - } + fs.MustCopyFile(srcPath, dstPath) } fs.MustSyncPath(dstDir) parentDir := filepath.Dir(dstDir) fs.MustSyncPath(parentDir) - - return nil } type partNamesJSON struct { diff --git a/lib/storage/storage.go b/lib/storage/storage.go index b89e53f060..f34cffd9ab 100644 --- a/lib/storage/storage.go +++ b/lib/storage/storage.go @@ -356,9 +356,7 @@ func (s *Storage) CreateSnapshot(deadline uint64) (string, error) { srcMetadataDir := filepath.Join(srcDir, metadataDirname) dstMetadataDir := filepath.Join(dstDir, metadataDirname) - if err := fs.CopyDirectory(srcMetadataDir, dstMetadataDir); err != nil { - return "", fmt.Errorf("cannot copy metadata: %w", err) - } + fs.MustCopyDirectory(srcMetadataDir, dstMetadataDir) idbSnapshot := filepath.Join(srcDir, indexdbDirname, snapshotsDirname, snapshotName) idb := s.idb() diff --git a/lib/storage/table.go b/lib/storage/table.go index 6bb4afa437..37799347fc 100644 --- a/lib/storage/table.go +++ b/lib/storage/table.go @@ -158,11 +158,7 @@ func (tb *table) CreateSnapshot(snapshotName string, deadline uint64) (string, s smallPath := filepath.Join(dstSmallDir, ptw.pt.name) bigPath := filepath.Join(dstBigDir, ptw.pt.name) - if err := ptw.pt.CreateSnapshotAt(smallPath, bigPath); err != nil { - fs.MustRemoveAll(dstSmallDir) - fs.MustRemoveAll(dstBigDir) - return "", "", fmt.Errorf("cannot create snapshot for partition %q in %q: %w", ptw.pt.name, tb.path, err) - } + ptw.pt.MustCreateSnapshotAt(smallPath, bigPath) } fs.MustSyncPath(dstSmallDir)