mirror of https://github.com/containers/podman.git
Switch all calls to filepath.Walk to filepath.WalkDir
WalkDir should be faster the Walk, since we often do not need to stat files. [NO NEW TESTS NEEDED] Existing tests should find errors. Signed-off-by: Daniel J Walsh <dwalsh@redhat.com>
This commit is contained in:
parent
56b2937f87
commit
d106b294b4
|
@ -99,15 +99,8 @@ func (c *Container) rootFsSize() (int64, error) {
|
||||||
// rwSize gets the size of the mutable top layer of the container.
|
// rwSize gets the size of the mutable top layer of the container.
|
||||||
func (c *Container) rwSize() (int64, error) {
|
func (c *Container) rwSize() (int64, error) {
|
||||||
if c.config.Rootfs != "" {
|
if c.config.Rootfs != "" {
|
||||||
var size int64
|
size, err := util.SizeOfPath(c.config.Rootfs)
|
||||||
err := filepath.Walk(c.config.Rootfs, func(path string, info os.FileInfo, err error) error {
|
return int64(size), err
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
size += info.Size()
|
|
||||||
return nil
|
|
||||||
})
|
|
||||||
return size, err
|
|
||||||
}
|
}
|
||||||
|
|
||||||
container, err := c.runtime.store.Container(c.ID())
|
container, err := c.runtime.store.Container(c.ID())
|
||||||
|
|
|
@ -1,13 +1,12 @@
|
||||||
package libpod
|
package libpod
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"os"
|
|
||||||
"path/filepath"
|
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/containers/podman/v4/libpod/define"
|
"github.com/containers/podman/v4/libpod/define"
|
||||||
"github.com/containers/podman/v4/libpod/lock"
|
"github.com/containers/podman/v4/libpod/lock"
|
||||||
"github.com/containers/podman/v4/libpod/plugin"
|
"github.com/containers/podman/v4/libpod/plugin"
|
||||||
|
"github.com/containers/podman/v4/pkg/util"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Volume is a libpod named volume.
|
// Volume is a libpod named volume.
|
||||||
|
@ -93,14 +92,7 @@ func (v *Volume) Name() string {
|
||||||
|
|
||||||
// Returns the size on disk of volume
|
// Returns the size on disk of volume
|
||||||
func (v *Volume) Size() (uint64, error) {
|
func (v *Volume) Size() (uint64, error) {
|
||||||
var size uint64
|
return util.SizeOfPath(v.config.MountPoint)
|
||||||
err := filepath.Walk(v.config.MountPoint, func(path string, info os.FileInfo, err error) error {
|
|
||||||
if err == nil && !info.IsDir() {
|
|
||||||
size += (uint64)(info.Size())
|
|
||||||
}
|
|
||||||
return err
|
|
||||||
})
|
|
||||||
return size, err
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Driver retrieves the volume's driver.
|
// Driver retrieves the volume's driver.
|
||||||
|
|
|
@ -7,6 +7,7 @@ import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
|
"io/fs"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"net/http"
|
"net/http"
|
||||||
"net/url"
|
"net/url"
|
||||||
|
@ -557,14 +558,14 @@ func nTar(excludes []string, sources ...string) (io.ReadCloser, error) {
|
||||||
merr = multierror.Append(merr, err)
|
merr = multierror.Append(merr, err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
err = filepath.Walk(s, func(path string, info os.FileInfo, err error) error {
|
err = filepath.WalkDir(s, func(path string, d fs.DirEntry, err error) error {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
// check if what we are given is an empty dir, if so then continue w/ it. Else return.
|
// check if what we are given is an empty dir, if so then continue w/ it. Else return.
|
||||||
// if we are given a file or a symlink, we do not want to exclude it.
|
// if we are given a file or a symlink, we do not want to exclude it.
|
||||||
if info.IsDir() && s == path {
|
if d.IsDir() && s == path {
|
||||||
var p *os.File
|
var p *os.File
|
||||||
p, err = os.Open(path)
|
p, err = os.Open(path)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -588,7 +589,11 @@ func nTar(excludes []string, sources ...string) (io.ReadCloser, error) {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
if info.Mode().IsRegular() { // add file item
|
if d.Type().IsRegular() { // add file item
|
||||||
|
info, err := d.Info()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
di, isHardLink := checkHardLink(info)
|
di, isHardLink := checkHardLink(info)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
@ -624,7 +629,11 @@ func nTar(excludes []string, sources ...string) (io.ReadCloser, error) {
|
||||||
seen[di] = name
|
seen[di] = name
|
||||||
}
|
}
|
||||||
return err
|
return err
|
||||||
} else if info.Mode().IsDir() { // add folders
|
} else if d.IsDir() { // add folders
|
||||||
|
info, err := d.Info()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
hdr, lerr := tar.FileInfoHeader(info, name)
|
hdr, lerr := tar.FileInfoHeader(info, name)
|
||||||
if lerr != nil {
|
if lerr != nil {
|
||||||
return lerr
|
return lerr
|
||||||
|
@ -634,11 +643,15 @@ func nTar(excludes []string, sources ...string) (io.ReadCloser, error) {
|
||||||
if lerr := tw.WriteHeader(hdr); lerr != nil {
|
if lerr := tw.WriteHeader(hdr); lerr != nil {
|
||||||
return lerr
|
return lerr
|
||||||
}
|
}
|
||||||
} else if info.Mode()&os.ModeSymlink != 0 { // add symlinks as it, not content
|
} else if d.Type()&os.ModeSymlink != 0 { // add symlinks as it, not content
|
||||||
link, err := os.Readlink(path)
|
link, err := os.Readlink(path)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
info, err := d.Info()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
hdr, lerr := tar.FileInfoHeader(info, link)
|
hdr, lerr := tar.FileInfoHeader(info, link)
|
||||||
if lerr != nil {
|
if lerr != nil {
|
||||||
return lerr
|
return lerr
|
||||||
|
|
|
@ -6,7 +6,6 @@ import (
|
||||||
"net/url"
|
"net/url"
|
||||||
"os"
|
"os"
|
||||||
"os/exec"
|
"os/exec"
|
||||||
"path/filepath"
|
|
||||||
|
|
||||||
"github.com/containers/common/pkg/cgroups"
|
"github.com/containers/common/pkg/cgroups"
|
||||||
"github.com/containers/common/pkg/config"
|
"github.com/containers/common/pkg/config"
|
||||||
|
@ -269,7 +268,7 @@ func (ic *ContainerEngine) SystemDf(ctx context.Context, options entities.System
|
||||||
}
|
}
|
||||||
|
|
||||||
dfVolumes := make([]*entities.SystemDfVolumeReport, 0, len(vols))
|
dfVolumes := make([]*entities.SystemDfVolumeReport, 0, len(vols))
|
||||||
var reclaimableSize int64
|
var reclaimableSize uint64
|
||||||
for _, v := range vols {
|
for _, v := range vols {
|
||||||
var consInUse int
|
var consInUse int
|
||||||
mountPoint, err := v.MountPoint()
|
mountPoint, err := v.MountPoint()
|
||||||
|
@ -282,7 +281,7 @@ func (ic *ContainerEngine) SystemDf(ctx context.Context, options entities.System
|
||||||
// TODO: fix this.
|
// TODO: fix this.
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
volSize, err := sizeOfPath(mountPoint)
|
volSize, err := util.SizeOfPath(mountPoint)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
@ -301,8 +300,8 @@ func (ic *ContainerEngine) SystemDf(ctx context.Context, options entities.System
|
||||||
report := entities.SystemDfVolumeReport{
|
report := entities.SystemDfVolumeReport{
|
||||||
VolumeName: v.Name(),
|
VolumeName: v.Name(),
|
||||||
Links: consInUse,
|
Links: consInUse,
|
||||||
Size: volSize,
|
Size: int64(volSize),
|
||||||
ReclaimableSize: reclaimableSize,
|
ReclaimableSize: int64(reclaimableSize),
|
||||||
}
|
}
|
||||||
dfVolumes = append(dfVolumes, &report)
|
dfVolumes = append(dfVolumes, &report)
|
||||||
}
|
}
|
||||||
|
@ -313,19 +312,6 @@ func (ic *ContainerEngine) SystemDf(ctx context.Context, options entities.System
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// sizeOfPath determines the file usage of a given path. it was called volumeSize in v1
|
|
||||||
// and now is made to be generic and take a path instead of a libpod volume
|
|
||||||
func sizeOfPath(path string) (int64, error) {
|
|
||||||
var size int64
|
|
||||||
err := filepath.Walk(path, func(path string, info os.FileInfo, err error) error {
|
|
||||||
if err == nil && !info.IsDir() {
|
|
||||||
size += info.Size()
|
|
||||||
}
|
|
||||||
return err
|
|
||||||
})
|
|
||||||
return size, err
|
|
||||||
}
|
|
||||||
|
|
||||||
func (se *SystemEngine) Reset(ctx context.Context) error {
|
func (se *SystemEngine) Reset(ctx context.Context) error {
|
||||||
return se.Libpod.Reset(ctx)
|
return se.Libpod.Reset(ctx)
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,6 +6,7 @@ package machine
|
||||||
import (
|
import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"io/fs"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"net/url"
|
"net/url"
|
||||||
"os"
|
"os"
|
||||||
|
@ -507,8 +508,8 @@ func getCerts(certsDir string, isDir bool) []File {
|
||||||
)
|
)
|
||||||
|
|
||||||
if isDir {
|
if isDir {
|
||||||
err := filepath.Walk(certsDir, func(path string, info os.FileInfo, err error) error {
|
err := filepath.WalkDir(certsDir, func(path string, d fs.DirEntry, err error) error {
|
||||||
if err == nil && !info.IsDir() {
|
if err == nil && !d.IsDir() {
|
||||||
certPath, err := filepath.Rel(certsDir, path)
|
certPath, err := filepath.Rel(certsDir, path)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logrus.Warnf("%s", err)
|
logrus.Warnf("%s", err)
|
||||||
|
|
|
@ -895,10 +895,10 @@ func GetVMInfos() ([]*machine.ListResponse, error) {
|
||||||
|
|
||||||
var listed []*machine.ListResponse
|
var listed []*machine.ListResponse
|
||||||
|
|
||||||
if err = filepath.Walk(vmConfigDir, func(path string, info os.FileInfo, err error) error {
|
if err = filepath.WalkDir(vmConfigDir, func(path string, d fs.DirEntry, err error) error {
|
||||||
vm := new(MachineVM)
|
vm := new(MachineVM)
|
||||||
if strings.HasSuffix(info.Name(), ".json") {
|
if strings.HasSuffix(d.Name(), ".json") {
|
||||||
fullPath := filepath.Join(vmConfigDir, info.Name())
|
fullPath := filepath.Join(vmConfigDir, d.Name())
|
||||||
b, err := ioutil.ReadFile(fullPath)
|
b, err := ioutil.ReadFile(fullPath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
|
|
@ -8,6 +8,7 @@ import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
|
"io/fs"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"net/url"
|
"net/url"
|
||||||
"os"
|
"os"
|
||||||
|
@ -1175,10 +1176,10 @@ func GetVMInfos() ([]*machine.ListResponse, error) {
|
||||||
|
|
||||||
var listed []*machine.ListResponse
|
var listed []*machine.ListResponse
|
||||||
|
|
||||||
if err = filepath.Walk(vmConfigDir, func(path string, info os.FileInfo, err error) error {
|
if err = filepath.WalkDir(vmConfigDir, func(path string, d fs.DirEntry, err error) error {
|
||||||
vm := new(MachineVM)
|
vm := new(MachineVM)
|
||||||
if strings.HasSuffix(info.Name(), ".json") {
|
if strings.HasSuffix(d.Name(), ".json") {
|
||||||
fullPath := filepath.Join(vmConfigDir, info.Name())
|
fullPath := filepath.Join(vmConfigDir, d.Name())
|
||||||
b, err := ioutil.ReadFile(fullPath)
|
b, err := ioutil.ReadFile(fullPath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
|
|
@ -2,6 +2,7 @@ package generate
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"io/fs"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"os"
|
"os"
|
||||||
"path"
|
"path"
|
||||||
|
@ -101,8 +102,8 @@ func DevicesFromPath(g *generate.Generator, devicePath string) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
// mount the internal devices recursively
|
// mount the internal devices recursively
|
||||||
if err := filepath.Walk(resolvedDevicePath, func(dpath string, f os.FileInfo, e error) error {
|
if err := filepath.WalkDir(resolvedDevicePath, func(dpath string, d fs.DirEntry, e error) error {
|
||||||
if f.Mode()&os.ModeDevice == os.ModeDevice {
|
if d.Type()&os.ModeDevice == os.ModeDevice {
|
||||||
found = true
|
found = true
|
||||||
device := fmt.Sprintf("%s:%s", dpath, filepath.Join(dest, strings.TrimPrefix(dpath, src)))
|
device := fmt.Sprintf("%s:%s", dpath, filepath.Join(dest, strings.TrimPrefix(dpath, src)))
|
||||||
if devmode != "" {
|
if devmode != "" {
|
||||||
|
|
|
@ -3,6 +3,7 @@ package util
|
||||||
import (
|
import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"io/fs"
|
||||||
"math"
|
"math"
|
||||||
"os"
|
"os"
|
||||||
"os/user"
|
"os/user"
|
||||||
|
@ -731,3 +732,20 @@ func LookupUser(name string) (*user.User, error) {
|
||||||
}
|
}
|
||||||
return user.Lookup(name)
|
return user.Lookup(name)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// SizeOfPath determines the file usage of a given path. it was called volumeSize in v1
|
||||||
|
// and now is made to be generic and take a path instead of a libpod volume
|
||||||
|
func SizeOfPath(path string) (uint64, error) {
|
||||||
|
var size uint64
|
||||||
|
err := filepath.WalkDir(path, func(path string, d fs.DirEntry, err error) error {
|
||||||
|
if err == nil && !d.IsDir() {
|
||||||
|
info, err := d.Info()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
size += uint64(info.Size())
|
||||||
|
}
|
||||||
|
return err
|
||||||
|
})
|
||||||
|
return size, err
|
||||||
|
}
|
||||||
|
|
|
@ -2,6 +2,7 @@ package util
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"io/fs"
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"syscall"
|
"syscall"
|
||||||
|
@ -23,17 +24,21 @@ func GetContainerPidInformationDescriptors() ([]string, error) {
|
||||||
// Symlinks to nodes are ignored.
|
// Symlinks to nodes are ignored.
|
||||||
func FindDeviceNodes() (map[string]string, error) {
|
func FindDeviceNodes() (map[string]string, error) {
|
||||||
nodes := make(map[string]string)
|
nodes := make(map[string]string)
|
||||||
err := filepath.Walk("/dev", func(path string, info os.FileInfo, err error) error {
|
err := filepath.WalkDir("/dev", func(path string, d fs.DirEntry, err error) error {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logrus.Warnf("Error descending into path %s: %v", path, err)
|
logrus.Warnf("Error descending into path %s: %v", path, err)
|
||||||
return filepath.SkipDir
|
return filepath.SkipDir
|
||||||
}
|
}
|
||||||
|
|
||||||
// If we aren't a device node, do nothing.
|
// If we aren't a device node, do nothing.
|
||||||
if info.Mode()&(os.ModeDevice|os.ModeCharDevice) == 0 {
|
if d.Type()&(os.ModeDevice|os.ModeCharDevice) == 0 {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
info, err := d.Info()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
// We are a device node. Get major/minor.
|
// We are a device node. Get major/minor.
|
||||||
sysstat, ok := info.Sys().(*syscall.Stat_t)
|
sysstat, ok := info.Sys().(*syscall.Stat_t)
|
||||||
if !ok {
|
if !ok {
|
||||||
|
|
|
@ -2,6 +2,7 @@ package integration
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"io/fs"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
|
@ -46,14 +47,14 @@ var _ = Describe("Podman pod rm", func() {
|
||||||
Expect(result).Should(Exit(0))
|
Expect(result).Should(Exit(0))
|
||||||
|
|
||||||
// Also check that we don't leak cgroups
|
// Also check that we don't leak cgroups
|
||||||
err := filepath.Walk("/sys/fs/cgroup", func(path string, info os.FileInfo, err error) error {
|
err := filepath.WalkDir("/sys/fs/cgroup", func(path string, d fs.DirEntry, err error) error {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if !info.IsDir() {
|
if !d.IsDir() {
|
||||||
Expect(err).To(BeNil())
|
Expect(err).To(BeNil())
|
||||||
}
|
}
|
||||||
if strings.Contains(info.Name(), podid) {
|
if strings.Contains(d.Name(), podid) {
|
||||||
return fmt.Errorf("leaking cgroup path %s", path)
|
return fmt.Errorf("leaking cgroup path %s", path)
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
|
|
Loading…
Reference in New Issue