Skip to content

Commit

Permalink
Moving files between filesystems too
Browse files Browse the repository at this point in the history
  • Loading branch information
sebasmannem committed May 12, 2022
1 parent a5148b8 commit 2d4cefb
Show file tree
Hide file tree
Showing 2 changed files with 84 additions and 20 deletions.
24 changes: 4 additions & 20 deletions internal/postgresql/postgresql.go
Original file line number Diff line number Diff line change
Expand Up @@ -326,30 +326,14 @@ func (p *Manager) moveWal() (err error) {
}
// We use tmpPath here first and (if needed) mv tmpPath to desiredPath when all is copied.
// This allows stolon-keeper to re-read symlink dest and continue should stolon-keeper be restarted while copying.
log.Debugf("creating %s", tmpPath)
if err = os.MkdirAll(tmpPath, 0700); err != nil && !os.IsExist(err) {
log.Errorf("could not create new dest folder %s: %e", tmpPath, err)
if err = moveDirRecursive(curPath, tmpPath); err != nil {
return err
}
log.Debugf("moving WAL files from %s to %s", curPath, tmpPath)
var entries []fs.FileInfo
if entries, err = ioutil.ReadDir(curPath); err != nil {
log.Errorf("could not read contents of folder %s: %e", curPath, err)
return err
} else {
for _, entry := range entries {
srcEntry := filepath.Join(curPath, entry.Name())
dstEntry := filepath.Join(tmpPath, entry.Name())
log.Debugf("moving %s to %s", srcEntry, dstEntry)
if err = os.Rename(srcEntry, dstEntry); err != nil {
log.Errorf("could not move %s to %s: %e", srcEntry, dstEntry, err)
return err
}
}
}

var symlinkStat fs.FileInfo
if symlinkStat, err = os.Lstat(symlinkPath); err != nil {
if symlinkStat, err = os.Lstat(symlinkPath); errors.Is(err, os.ErrNotExist) {
// File or folder already removed
} else if err != nil {
log.Errorf("could not get info on current pg_wal folder/symlink %s: %e", symlinkPath, err)
return err
} else if symlinkStat.Mode()&os.ModeSymlink != 0 {
Expand Down
80 changes: 80 additions & 0 deletions internal/postgresql/utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,16 @@ import (
"bufio"
"context"
"database/sql"
"errors"
"fmt"
"io"
"io/fs"
"io/ioutil"
"path/filepath"
"regexp"
"strconv"
"strings"
"syscall"

"github.com/sorintlab/stolon/internal/common"

Expand Down Expand Up @@ -556,3 +562,77 @@ func WalFileNameNoTimeLine(name string) (string, error) {
}
return name[8:24], nil
}

func moveFile(sourcePath, destPath string) error {
// using os.Rename is faster when on same filesystem
if err := os.Rename(sourcePath, destPath); err == nil {
return nil
}
// Error. Let's try to write
inputFile, err := os.Open(sourcePath)
if err != nil {
return fmt.Errorf("Couldn't open source file: %s", err)
}
inFileStat, err := inputFile.Stat()
if err != nil {
return err
}
flag := os.O_WRONLY | os.O_CREATE | os.O_TRUNC
perm := inFileStat.Mode() & os.ModePerm
outputFile, err := os.OpenFile(destPath, flag, perm)
if err != nil {
return err
}
defer outputFile.Close()
_, err = io.Copy(outputFile, inputFile)
inputFile.Close()
if err != nil {
return fmt.Errorf("Writing to output file failed: %s", err)
}
// The copy was successful, so now delete the original file
err = os.Remove(sourcePath)
if err != nil {
return fmt.Errorf("Failed removing original file: %s", err)
}
return nil
}

func moveDirRecursive(src string, dest string) error {
log.Infof("Moving %s to %s", src, dest)
if stat, err := os.Stat(src); err != nil {
log.Errorf("could not get stat of %s: %e", src, err)
return err
} else if stat.IsDir() {
// Make the dir if it doesn't exist
if _, err := os.Stat(dest); errors.Is(err, os.ErrNotExist) {
if err := os.MkdirAll(dest, stat.Mode() & os.ModePerm); err != nil {
return err
}
} else if err != nil {
log.Errorf("could not get stat of %s: %e", dest, err)
return err
}
// Copy all files and folders in this folder
var entries []fs.FileInfo
if entries, err = ioutil.ReadDir(src); err != nil {
log.Errorf("could not read contents of folder %s: %e", src, err)
return err
} else {
for _, entry := range entries {
srcEntry := filepath.Join(src, entry.Name())
dstEntry := filepath.Join(dest, entry.Name())
if err := moveDirRecursive(srcEntry, dstEntry); err != nil {
return err
}
}
}
// Remove this folder, which is now supposedly empty
if err := syscall.Rmdir(src); err != nil {
log.Errorf("could not remove folder %s: %e", src, err)
return err
}
} else {
return moveFile(src, dest)
}
return nil
}

0 comments on commit 2d4cefb

Please sign in to comment.