From 743a5006e595f36761786f6939b24eea8bfa50fc Mon Sep 17 00:00:00 2001 From: Daniel J Walsh Date: Fri, 21 May 2021 06:25:24 -0400 Subject: [PATCH] Add Dev, Nlink, and Ino to pkg/system/Stat struct podman needs to look at the Device, Inode and number of links of a file, but needs this to work on Windows and Darwin. We are using this information to determine if a file is a hard link whe tarring it up. Add new function FileInfoToStatT to transate a FileInfor into the StatT struct. Signed-off-by: Daniel J Walsh --- pkg/system/lstat_windows.go | 2 +- pkg/system/stat_darwin.go | 13 ++++++++----- pkg/system/stat_linux.go | 13 ++++++++----- pkg/system/stat_unix.go | 35 +++++++++++++++++++++++++++++------ pkg/system/stat_unix_test.go | 9 +++++++++ pkg/system/stat_windows.go | 36 +++++++++++++++++++++++++++--------- 6 files changed, 82 insertions(+), 26 deletions(-) diff --git a/pkg/system/lstat_windows.go b/pkg/system/lstat_windows.go index e51df0dafe..55820f5614 100644 --- a/pkg/system/lstat_windows.go +++ b/pkg/system/lstat_windows.go @@ -10,5 +10,5 @@ func Lstat(path string) (*StatT, error) { return nil, err } - return fromStatT(&fi) + return FileInfoToStatT(fi) } diff --git a/pkg/system/stat_darwin.go b/pkg/system/stat_darwin.go index 715f05b938..851697a6bc 100644 --- a/pkg/system/stat_darwin.go +++ b/pkg/system/stat_darwin.go @@ -5,9 +5,12 @@ import "syscall" // fromStatT converts a syscall.Stat_t type to a system.Stat_t type func fromStatT(s *syscall.Stat_t) (*StatT, error) { return &StatT{size: s.Size, - mode: uint32(s.Mode), - uid: s.Uid, - gid: s.Gid, - rdev: uint64(s.Rdev), - mtim: s.Mtimespec}, nil + mode: uint32(s.Mode), + uid: s.Uid, + gid: s.Gid, + rdev: uint64(s.Rdev), + dev: uint64(s.Dev), + ino: s.Ino, + nlink: uint64(s.Nlink), + mtim: s.Mtimespec}, nil } diff --git a/pkg/system/stat_linux.go b/pkg/system/stat_linux.go index af7af20fa4..88d317065f 100644 --- a/pkg/system/stat_linux.go +++ b/pkg/system/stat_linux.go @@ -5,11 +5,14 @@ import "syscall" // fromStatT converts a syscall.Stat_t type to a system.Stat_t type func fromStatT(s *syscall.Stat_t) (*StatT, error) { return &StatT{size: s.Size, - mode: s.Mode, - uid: s.Uid, - gid: s.Gid, - rdev: uint64(s.Rdev), - mtim: s.Mtim}, nil + mode: s.Mode, + uid: s.Uid, + gid: s.Gid, + rdev: uint64(s.Rdev), + dev: s.Dev, + ino: s.Ino, + nlink: s.Nlink, + mtim: s.Mtim}, nil } // FromStatT converts a syscall.Stat_t type to a system.Stat_t type diff --git a/pkg/system/stat_unix.go b/pkg/system/stat_unix.go index 2fac918bfc..f24cb229d9 100644 --- a/pkg/system/stat_unix.go +++ b/pkg/system/stat_unix.go @@ -11,12 +11,15 @@ import ( // StatT type contains status of a file. It contains metadata // like permission, owner, group, size, etc about a file. type StatT struct { - mode uint32 - uid uint32 - gid uint32 - rdev uint64 - size int64 - mtim syscall.Timespec + mode uint32 + uid uint32 + gid uint32 + rdev uint64 + size int64 + mtim syscall.Timespec + dev uint64 + ino uint64 + nlink uint64 } // Mode returns file's permission mode. @@ -72,3 +75,23 @@ func Fstat(fd int) (*StatT, error) { } return fromStatT(s) } + +// Dev returns device identifier the file is stored on +func (s StatT) Dev() uint64 { + return s.dev +} + +// Ino returns inode the file is stored on +func (s StatT) Ino() uint64 { + return s.ino +} + +// Nlink returns number of hard links to the file +func (s StatT) Nlink() uint64 { + return s.nlink +} + +// StatT converts a syscall.Stat_t type to a system.Stat_t type +func FileInfoToStatT(fi os.FileInfo) (*StatT, error) { + return fromStatT(fi.Sys().(*syscall.Stat_t)) +} diff --git a/pkg/system/stat_unix_test.go b/pkg/system/stat_unix_test.go index a435d1a207..6a60e922cb 100644 --- a/pkg/system/stat_unix_test.go +++ b/pkg/system/stat_unix_test.go @@ -38,4 +38,13 @@ func TestFromStatT(t *testing.T) { if stat.Mtim != s.Mtim() { t.Fatal("got invalid mtim") } + if stat.Dev != s.Dev() { + t.Fatal("got invalid dev") + } + if stat.Nlink != s.Nlink() { + t.Fatal("got invalid nlink") + } + if stat.Ino != s.Ino() { + t.Fatal("got invalid inode") + } } diff --git a/pkg/system/stat_windows.go b/pkg/system/stat_windows.go index d306360520..28a6747707 100644 --- a/pkg/system/stat_windows.go +++ b/pkg/system/stat_windows.go @@ -8,9 +8,27 @@ import ( // StatT type contains status of a file. It contains metadata // like permission, size, etc about a file. type StatT struct { - mode os.FileMode - size int64 - mtim time.Time + mode os.FileMode + size int64 + mtim time.Time + dev uint64 + ino uint64 + nlink uint64 +} + +// Dev returns device identifier the file is stored on +func (s StatT) Dev() uint64 { + return s.dev +} + +// Ino returns inode the file is stored on +func (s StatT) Ino() uint64 { + return s.ino +} + +// Nlink returns number of hard links to the file +func (s StatT) Nlink() uint64 { + return s.nlink } // Size returns file's size. @@ -51,13 +69,13 @@ func Stat(path string) (*StatT, error) { if err != nil { return nil, err } - return fromStatT(&fi) + return FileInfoToStatT(fi) } -// fromStatT converts a os.FileInfo type to a system.StatT type -func fromStatT(fi *os.FileInfo) (*StatT, error) { +// FileInfoToStatT converts a os.FileInfo type to a system.StatT type +func FileInfoToStatT(fi os.FileInfo) (*StatT, error) { return &StatT{ - size: (*fi).Size(), - mode: (*fi).Mode(), - mtim: (*fi).ModTime()}, nil + size: fi.Size(), + mode: fi.Mode(), + mtim: fi.ModTime()}, nil }