Bump github.com/containers/storage from 1.41.0 to 1.42.0

Bumps [github.com/containers/storage](https://github.com/containers/storage) from 1.41.0 to 1.42.0.
- [Release notes](https://github.com/containers/storage/releases)
- [Changelog](https://github.com/containers/storage/blob/main/docs/containers-storage-changes.md)
- [Commits](https://github.com/containers/storage/compare/v1.41.0...v1.42.0)

---
updated-dependencies:
- dependency-name: github.com/containers/storage
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
This commit is contained in:
dependabot[bot]
2022-07-22 08:17:06 +00:00
committed by GitHub
parent ad12a292a3
commit b42e664854
133 changed files with 5213 additions and 2557 deletions

View File

@@ -1,11 +1,10 @@
package lockfile
import (
"fmt"
"path/filepath"
"sync"
"time"
"github.com/pkg/errors"
)
// A Locker represents a file lock where the file is used to cache an
@@ -87,14 +86,14 @@ func getLockfile(path string, ro bool) (Locker, error) {
}
cleanPath, err := filepath.Abs(path)
if err != nil {
return nil, errors.Wrapf(err, "error ensuring that path %q is an absolute path", path)
return nil, fmt.Errorf("ensuring that path %q is an absolute path: %w", path, err)
}
if locker, ok := lockfiles[cleanPath]; ok {
if ro && locker.IsReadWrite() {
return nil, errors.Errorf("lock %q is not a read-only lock", cleanPath)
return nil, fmt.Errorf("lock %q is not a read-only lock", cleanPath)
}
if !ro && !locker.IsReadWrite() {
return nil, errors.Errorf("lock %q is not a read-write lock", cleanPath)
return nil, fmt.Errorf("lock %q is not a read-write lock", cleanPath)
}
return locker, nil
}

View File

@@ -1,17 +1,20 @@
//go:build linux || solaris || darwin || freebsd
// +build linux solaris darwin freebsd
package lockfile
import (
"bytes"
cryptorand "crypto/rand"
"encoding/binary"
"fmt"
"os"
"path/filepath"
"sync"
"sync/atomic"
"time"
"github.com/containers/storage/pkg/stringid"
"github.com/containers/storage/pkg/system"
"github.com/pkg/errors"
"golang.org/x/sys/unix"
)
@@ -23,13 +26,44 @@ type lockfile struct {
counter int64
file string
fd uintptr
lw string
lw []byte // "last writer"-unique value valid as of the last .Touch() or .Modified(), generated by newLastWriterID()
locktype int16
locked bool
ro bool
recursive bool
}
const lastWriterIDSize = 64 // This must be the same as len(stringid.GenerateRandomID)
var lastWriterIDCounter uint64 // Private state for newLastWriterID
// newLastWriterID returns a new "last writer" ID.
// The value must be different on every call, and also differ from values
// generated by other processes.
func newLastWriterID() []byte {
// The ID is (PID, time, per-process counter, random)
// PID + time represents both a unique process across reboots,
// and a specific time within the process; the per-process counter
// is an extra safeguard for in-process concurrency.
// The random part disambiguates across process namespaces
// (where PID values might collide), serves as a general-purpose
// extra safety, _and_ is used to pad the output to lastWriterIDSize,
// because other versions of this code exist and they don't work
// efficiently if the size of the value changes.
pid := os.Getpid()
tm := time.Now().UnixNano()
counter := atomic.AddUint64(&lastWriterIDCounter, 1)
res := make([]byte, lastWriterIDSize)
binary.LittleEndian.PutUint64(res[0:8], uint64(tm))
binary.LittleEndian.PutUint64(res[8:16], counter)
binary.LittleEndian.PutUint32(res[16:20], uint32(pid))
if n, err := cryptorand.Read(res[20:lastWriterIDSize]); err != nil || n != lastWriterIDSize-20 {
panic(err) // This shouldn't happen
}
return res
}
// openLock opens the file at path and returns the corresponding file
// descriptor. Note that the path is opened read-only when ro is set. If ro
// is unset, openLock will open the path read-write and create the file if
@@ -51,7 +85,7 @@ func openLock(path string, ro bool) (fd int, err error) {
// the directory of the lockfile seems to be removed, try to create it
if os.IsNotExist(err) {
if err := os.MkdirAll(filepath.Dir(path), 0700); err != nil {
return fd, errors.Wrap(err, "creating locker directory")
return fd, fmt.Errorf("creating locker directory: %w", err)
}
return openLock(path, ro)
@@ -77,7 +111,7 @@ func createLockerForPath(path string, ro bool) (Locker, error) {
// Check if we can open the lock.
fd, err := openLock(path, ro)
if err != nil {
return nil, errors.Wrapf(err, "error opening %q", path)
return nil, err
}
unix.Close(fd)
@@ -89,7 +123,7 @@ func createLockerForPath(path string, ro bool) (Locker, error) {
stateMutex: &sync.Mutex{},
rwMutex: &sync.RWMutex{},
file: path,
lw: stringid.GenerateRandomID(),
lw: newLastWriterID(),
locktype: int16(locktype),
locked: false,
ro: ro}, nil
@@ -212,13 +246,12 @@ func (l *lockfile) Touch() error {
panic("attempted to update last-writer in lockfile without the write lock")
}
defer l.stateMutex.Unlock()
l.lw = stringid.GenerateRandomID()
id := []byte(l.lw)
n, err := unix.Pwrite(int(l.fd), id, 0)
l.lw = newLastWriterID()
n, err := unix.Pwrite(int(l.fd), l.lw, 0)
if err != nil {
return err
}
if n != len(id) {
if n != len(l.lw) {
return unix.ENOSPC
}
return nil
@@ -228,21 +261,21 @@ func (l *lockfile) Touch() error {
// was loaded.
func (l *lockfile) Modified() (bool, error) {
l.stateMutex.Lock()
id := []byte(l.lw)
if !l.locked {
panic("attempted to check last-writer in lockfile without locking it first")
}
defer l.stateMutex.Unlock()
n, err := unix.Pread(int(l.fd), id, 0)
currentLW := make([]byte, len(l.lw))
n, err := unix.Pread(int(l.fd), currentLW, 0)
if err != nil {
return true, err
}
if n != len(id) {
if n != len(l.lw) {
return true, nil
}
lw := l.lw
l.lw = string(id)
return l.lw != lw, nil
oldLW := l.lw
l.lw = currentLW
return !bytes.Equal(currentLW, oldLW), nil
}
// IsReadWriteLock indicates if the lock file is a read-write lock.