mirror of
https://github.com/VictoriaMetrics/VictoriaMetrics.git
synced 2024-11-21 14:44:00 +00:00
lib/{fs,mergeset,storage}: substitute os.Open()+os.File.Readdir() with os.ReadDir()
This simplifies code a bit
This commit is contained in:
parent
8fdd613f25
commit
a26c6628fd
5 changed files with 51 additions and 112 deletions
41
lib/fs/fs.go
41
lib/fs/fs.go
|
@ -247,21 +247,16 @@ var atomicDirRemoveCounter = uint64(time.Now().UnixNano())
|
||||||
//
|
//
|
||||||
// Such directories may be left on unclean shutdown during MustRemoveDirAtomic call.
|
// Such directories may be left on unclean shutdown during MustRemoveDirAtomic call.
|
||||||
func MustRemoveTemporaryDirs(dir string) {
|
func MustRemoveTemporaryDirs(dir string) {
|
||||||
d, err := os.Open(dir)
|
des, err := os.ReadDir(dir)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logger.Panicf("FATAL: cannot open dir: %s", err)
|
logger.Panicf("FATAL: cannot read dir: %s", err)
|
||||||
}
|
}
|
||||||
defer MustClose(d)
|
for _, de := range des {
|
||||||
fis, err := d.Readdir(-1)
|
if !IsDirOrSymlink(de) {
|
||||||
if err != nil {
|
|
||||||
logger.Panicf("FATAL: cannot read dir %q: %s", dir, err)
|
|
||||||
}
|
|
||||||
for _, fi := range fis {
|
|
||||||
if !IsDirOrSymlink(fi) {
|
|
||||||
// Skip non-directories
|
// Skip non-directories
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
dirName := fi.Name()
|
dirName := de.Name()
|
||||||
if IsScheduledForRemoval(dirName) {
|
if IsScheduledForRemoval(dirName) {
|
||||||
fullPath := dir + "/" + dirName
|
fullPath := dir + "/" + dirName
|
||||||
MustRemoveAll(fullPath)
|
MustRemoveAll(fullPath)
|
||||||
|
@ -276,26 +271,16 @@ func HardLinkFiles(srcDir, dstDir string) error {
|
||||||
return fmt.Errorf("cannot create dstDir=%q: %w", dstDir, err)
|
return fmt.Errorf("cannot create dstDir=%q: %w", dstDir, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
d, err := os.Open(srcDir)
|
des, err := os.ReadDir(srcDir)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("cannot open srcDir: %w", err)
|
return fmt.Errorf("cannot read files in scrDir: %w", err)
|
||||||
}
|
}
|
||||||
defer func() {
|
for _, de := range des {
|
||||||
if err := d.Close(); err != nil {
|
if IsDirOrSymlink(de) {
|
||||||
logger.Panicf("FATAL: cannot close %q: %s", srcDir, err)
|
|
||||||
}
|
|
||||||
}()
|
|
||||||
|
|
||||||
fis, err := d.Readdir(-1)
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("cannot read files in scrDir=%q: %w", srcDir, err)
|
|
||||||
}
|
|
||||||
for _, fi := range fis {
|
|
||||||
if IsDirOrSymlink(fi) {
|
|
||||||
// Skip directories.
|
// Skip directories.
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
fn := fi.Name()
|
fn := de.Name()
|
||||||
srcPath := srcDir + "/" + fn
|
srcPath := srcDir + "/" + fn
|
||||||
dstPath := dstDir + "/" + fn
|
dstPath := dstDir + "/" + fn
|
||||||
if err := os.Link(srcPath, dstPath); err != nil {
|
if err := os.Link(srcPath, dstPath); err != nil {
|
||||||
|
@ -307,9 +292,9 @@ func HardLinkFiles(srcDir, dstDir string) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// IsDirOrSymlink returns true if fi is directory or symlink.
|
// IsDirOrSymlink returns true if de is directory or symlink.
|
||||||
func IsDirOrSymlink(fi os.FileInfo) bool {
|
func IsDirOrSymlink(de os.DirEntry) bool {
|
||||||
return fi.IsDir() || (fi.Mode()&os.ModeSymlink == os.ModeSymlink)
|
return de.IsDir() || (de.Type()&os.ModeSymlink == os.ModeSymlink)
|
||||||
}
|
}
|
||||||
|
|
||||||
// SymlinkRelative creates relative symlink for srcPath in dstPath.
|
// SymlinkRelative creates relative symlink for srcPath in dstPath.
|
||||||
|
|
|
@ -1426,11 +1426,6 @@ func openParts(path string) ([]*partWrapper, error) {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
fs.MustRemoveTemporaryDirs(path)
|
fs.MustRemoveTemporaryDirs(path)
|
||||||
d, err := os.Open(path)
|
|
||||||
if err != nil {
|
|
||||||
return nil, fmt.Errorf("cannot open difrectory: %w", err)
|
|
||||||
}
|
|
||||||
defer fs.MustClose(d)
|
|
||||||
|
|
||||||
// Run remaining transactions and cleanup /txn and /tmp directories.
|
// Run remaining transactions and cleanup /txn and /tmp directories.
|
||||||
// Snapshots cannot be created yet, so use fakeSnapshotLock.
|
// Snapshots cannot be created yet, so use fakeSnapshotLock.
|
||||||
|
@ -1454,17 +1449,17 @@ func openParts(path string) ([]*partWrapper, error) {
|
||||||
fs.MustSyncPath(path)
|
fs.MustSyncPath(path)
|
||||||
|
|
||||||
// Open parts.
|
// Open parts.
|
||||||
fis, err := d.Readdir(-1)
|
des, err := os.ReadDir(path)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("cannot read directory: %w", err)
|
return nil, fmt.Errorf("cannot read directory: %w", err)
|
||||||
}
|
}
|
||||||
var pws []*partWrapper
|
var pws []*partWrapper
|
||||||
for _, fi := range fis {
|
for _, de := range des {
|
||||||
if !fs.IsDirOrSymlink(fi) {
|
if !fs.IsDirOrSymlink(de) {
|
||||||
// Skip non-directories.
|
// Skip non-directories.
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
fn := fi.Name()
|
fn := de.Name()
|
||||||
if isSpecialDir(fn) {
|
if isSpecialDir(fn) {
|
||||||
// Skip special dirs.
|
// Skip special dirs.
|
||||||
continue
|
continue
|
||||||
|
@ -1538,24 +1533,18 @@ func (tb *Table) CreateSnapshotAt(dstDir string, deadline uint64) error {
|
||||||
return fmt.Errorf("cannot create snapshot dir %q: %w", dstDir, err)
|
return fmt.Errorf("cannot create snapshot dir %q: %w", dstDir, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
d, err := os.Open(srcDir)
|
des, err := os.ReadDir(srcDir)
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("cannot open difrectory: %w", err)
|
|
||||||
}
|
|
||||||
defer fs.MustClose(d)
|
|
||||||
|
|
||||||
fis, err := d.Readdir(-1)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("cannot read directory: %w", err)
|
return fmt.Errorf("cannot read directory: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, fi := range fis {
|
for _, de := range des {
|
||||||
if deadline > 0 && fasttime.UnixTimestamp() > deadline {
|
if deadline > 0 && fasttime.UnixTimestamp() > deadline {
|
||||||
return fmt.Errorf("cannot create snapshot for %q: timeout exceeded", tb.path)
|
return fmt.Errorf("cannot create snapshot for %q: timeout exceeded", tb.path)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn := fi.Name()
|
fn := de.Name()
|
||||||
if !fs.IsDirOrSymlink(fi) {
|
if !fs.IsDirOrSymlink(de) {
|
||||||
// Skip non-directories.
|
// Skip non-directories.
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
@ -1586,27 +1575,21 @@ func runTransactions(txnLock *sync.RWMutex, path string) error {
|
||||||
defer pendingTxnDeletionsWG.Wait()
|
defer pendingTxnDeletionsWG.Wait()
|
||||||
|
|
||||||
txnDir := path + "/txn"
|
txnDir := path + "/txn"
|
||||||
d, err := os.Open(txnDir)
|
des, err := os.ReadDir(txnDir)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if os.IsNotExist(err) {
|
if os.IsNotExist(err) {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
return fmt.Errorf("cannot open transaction dir: %w", err)
|
return fmt.Errorf("cannot read transaction dir: %w", err)
|
||||||
}
|
|
||||||
defer fs.MustClose(d)
|
|
||||||
|
|
||||||
fis, err := d.Readdir(-1)
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("cannot read directory %q: %w", d.Name(), err)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Sort transaction files by id, since transactions must be ordered.
|
// Sort transaction files by id, since transactions must be ordered.
|
||||||
sort.Slice(fis, func(i, j int) bool {
|
sort.Slice(des, func(i, j int) bool {
|
||||||
return fis[i].Name() < fis[j].Name()
|
return des[i].Name() < des[j].Name()
|
||||||
})
|
})
|
||||||
|
|
||||||
for _, fi := range fis {
|
for _, de := range des {
|
||||||
fn := fi.Name()
|
fn := de.Name()
|
||||||
if fs.IsTemporaryFileName(fn) {
|
if fs.IsTemporaryFileName(fn) {
|
||||||
// Skip temporary files, which could be left after unclean shutdown.
|
// Skip temporary files, which could be left after unclean shutdown.
|
||||||
continue
|
continue
|
||||||
|
|
|
@ -1889,11 +1889,6 @@ func openParts(pathPrefix1, pathPrefix2, path string) ([]*partWrapper, error) {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
fs.MustRemoveTemporaryDirs(path)
|
fs.MustRemoveTemporaryDirs(path)
|
||||||
d, err := os.Open(path)
|
|
||||||
if err != nil {
|
|
||||||
return nil, fmt.Errorf("cannot open partition directory: %w", err)
|
|
||||||
}
|
|
||||||
defer fs.MustClose(d)
|
|
||||||
|
|
||||||
// Run remaining transactions and cleanup /txn and /tmp directories.
|
// Run remaining transactions and cleanup /txn and /tmp directories.
|
||||||
// Snapshots cannot be created yet, so use fakeSnapshotLock.
|
// Snapshots cannot be created yet, so use fakeSnapshotLock.
|
||||||
|
@ -1911,17 +1906,17 @@ func openParts(pathPrefix1, pathPrefix2, path string) ([]*partWrapper, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Open parts.
|
// Open parts.
|
||||||
fis, err := d.Readdir(-1)
|
des, err := os.ReadDir(path)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("cannot read directory %q: %w", d.Name(), err)
|
return nil, fmt.Errorf("cannot read partition directory: %w", err)
|
||||||
}
|
}
|
||||||
var pws []*partWrapper
|
var pws []*partWrapper
|
||||||
for _, fi := range fis {
|
for _, de := range des {
|
||||||
if !fs.IsDirOrSymlink(fi) {
|
if !fs.IsDirOrSymlink(de) {
|
||||||
// Skip non-directories.
|
// Skip non-directories.
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
fn := fi.Name()
|
fn := de.Name()
|
||||||
if fn == "snapshots" {
|
if fn == "snapshots" {
|
||||||
// "snapshots" dir is skipped for backwards compatibility. Now it is unused.
|
// "snapshots" dir is skipped for backwards compatibility. Now it is unused.
|
||||||
continue
|
continue
|
||||||
|
@ -2000,19 +1995,13 @@ func (pt *partition) createSnapshot(srcDir, dstDir string) error {
|
||||||
return fmt.Errorf("cannot create snapshot dir %q: %w", dstDir, err)
|
return fmt.Errorf("cannot create snapshot dir %q: %w", dstDir, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
d, err := os.Open(srcDir)
|
des, err := os.ReadDir(srcDir)
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("cannot open partition difrectory: %w", err)
|
|
||||||
}
|
|
||||||
defer fs.MustClose(d)
|
|
||||||
|
|
||||||
fis, err := d.Readdir(-1)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("cannot read partition directory: %w", err)
|
return fmt.Errorf("cannot read partition directory: %w", err)
|
||||||
}
|
}
|
||||||
for _, fi := range fis {
|
for _, de := range des {
|
||||||
fn := fi.Name()
|
fn := de.Name()
|
||||||
if !fs.IsDirOrSymlink(fi) {
|
if !fs.IsDirOrSymlink(de) {
|
||||||
if fn == "appliedRetention.txt" {
|
if fn == "appliedRetention.txt" {
|
||||||
// Copy the appliedRetention.txt file to dstDir.
|
// Copy the appliedRetention.txt file to dstDir.
|
||||||
// This file can be created by VictoriaMetrics enterprise.
|
// This file can be created by VictoriaMetrics enterprise.
|
||||||
|
@ -2052,27 +2041,21 @@ func runTransactions(txnLock *sync.RWMutex, pathPrefix1, pathPrefix2, path strin
|
||||||
defer pendingTxnDeletionsWG.Wait()
|
defer pendingTxnDeletionsWG.Wait()
|
||||||
|
|
||||||
txnDir := path + "/txn"
|
txnDir := path + "/txn"
|
||||||
d, err := os.Open(txnDir)
|
des, err := os.ReadDir(txnDir)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if os.IsNotExist(err) {
|
if os.IsNotExist(err) {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
return fmt.Errorf("cannot open transaction directory: %w", err)
|
return fmt.Errorf("cannot read transaction directory: %w", err)
|
||||||
}
|
|
||||||
defer fs.MustClose(d)
|
|
||||||
|
|
||||||
fis, err := d.Readdir(-1)
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("cannot read directory %q: %w", d.Name(), err)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Sort transaction files by id.
|
// Sort transaction files by id.
|
||||||
sort.Slice(fis, func(i, j int) bool {
|
sort.Slice(des, func(i, j int) bool {
|
||||||
return fis[i].Name() < fis[j].Name()
|
return des[i].Name() < des[j].Name()
|
||||||
})
|
})
|
||||||
|
|
||||||
for _, fi := range fis {
|
for _, de := range des {
|
||||||
fn := fi.Name()
|
fn := de.Name()
|
||||||
if fs.IsTemporaryFileName(fn) {
|
if fs.IsTemporaryFileName(fn) {
|
||||||
// Skip temporary files, which could be left after unclean shutdown.
|
// Skip temporary files, which could be left after unclean shutdown.
|
||||||
continue
|
continue
|
||||||
|
|
|
@ -2339,25 +2339,19 @@ func (s *Storage) openIndexDBTables(path string) (curr, prev *indexDB, err error
|
||||||
}
|
}
|
||||||
fs.MustRemoveTemporaryDirs(path)
|
fs.MustRemoveTemporaryDirs(path)
|
||||||
|
|
||||||
d, err := os.Open(path)
|
|
||||||
if err != nil {
|
|
||||||
return nil, nil, fmt.Errorf("cannot open directory: %w", err)
|
|
||||||
}
|
|
||||||
defer fs.MustClose(d)
|
|
||||||
|
|
||||||
// Search for the two most recent tables - the last one is active,
|
// Search for the two most recent tables - the last one is active,
|
||||||
// the previous one contains backup data.
|
// the previous one contains backup data.
|
||||||
fis, err := d.Readdir(-1)
|
des, err := os.ReadDir(path)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, nil, fmt.Errorf("cannot read directory: %w", err)
|
return nil, nil, fmt.Errorf("cannot read directory: %w", err)
|
||||||
}
|
}
|
||||||
var tableNames []string
|
var tableNames []string
|
||||||
for _, fi := range fis {
|
for _, de := range des {
|
||||||
if !fs.IsDirOrSymlink(fi) {
|
if !fs.IsDirOrSymlink(de) {
|
||||||
// Skip non-directories.
|
// Skip non-directories.
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
tableName := fi.Name()
|
tableName := de.Name()
|
||||||
if !indexDBTableNameRegexp.MatchString(tableName) {
|
if !indexDBTableNameRegexp.MatchString(tableName) {
|
||||||
// Skip invalid directories.
|
// Skip invalid directories.
|
||||||
continue
|
continue
|
||||||
|
|
|
@ -535,22 +535,16 @@ func openPartitions(smallPartitionsPath, bigPartitionsPath string, s *Storage) (
|
||||||
}
|
}
|
||||||
|
|
||||||
func populatePartitionNames(partitionsPath string, ptNames map[string]bool) error {
|
func populatePartitionNames(partitionsPath string, ptNames map[string]bool) error {
|
||||||
d, err := os.Open(partitionsPath)
|
des, err := os.ReadDir(partitionsPath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("cannot open directory with partitions: %w", err)
|
return fmt.Errorf("cannot read directory with partitions: %w", err)
|
||||||
}
|
}
|
||||||
defer fs.MustClose(d)
|
for _, de := range des {
|
||||||
|
if !fs.IsDirOrSymlink(de) {
|
||||||
fis, err := d.Readdir(-1)
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("cannot read directory with partitions %q: %w", partitionsPath, err)
|
|
||||||
}
|
|
||||||
for _, fi := range fis {
|
|
||||||
if !fs.IsDirOrSymlink(fi) {
|
|
||||||
// Skip non-directories
|
// Skip non-directories
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
ptName := fi.Name()
|
ptName := de.Name()
|
||||||
if ptName == "snapshots" {
|
if ptName == "snapshots" {
|
||||||
// Skip directory with snapshots
|
// Skip directory with snapshots
|
||||||
continue
|
continue
|
||||||
|
|
Loading…
Reference in a new issue