mirror of
https://github.com/containers/podman.git
synced 2025-12-13 02:09:16 +08:00
Update vendor of containers/(storage,image)
Signed-off-by: Daniel J Walsh <dwalsh@redhat.com>
This commit is contained in:
82
vendor/github.com/containers/storage/pkg/lockfile/lastwrite.go
generated
vendored
Normal file
82
vendor/github.com/containers/storage/pkg/lockfile/lastwrite.go
generated
vendored
Normal file
@@ -0,0 +1,82 @@
|
||||
package lockfile
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
cryptorand "crypto/rand"
|
||||
"encoding/binary"
|
||||
"os"
|
||||
"sync/atomic"
|
||||
"time"
|
||||
)
|
||||
|
||||
// LastWrite is an opaque identifier of the last write to some *LockFile.
|
||||
// It can be used by users of a *LockFile to determine if the lock indicates changes
|
||||
// since the last check.
|
||||
//
|
||||
// Never construct a LastWrite manually; only accept it from *LockFile methods, and pass it back.
|
||||
type LastWrite struct {
|
||||
// Never modify fields of a LastWrite object; it has value semantics.
|
||||
state []byte // Contents of the lock file.
|
||||
}
|
||||
|
||||
var lastWriterIDCounter uint64 // Private state for newLastWriterID
|
||||
|
||||
const lastWriterIDSize = 64 // This must be the same as len(stringid.GenerateRandomID)
|
||||
// newLastWrite returns a new "last write" ID.
|
||||
// The value must be different on every call, and also differ from values
|
||||
// generated by other processes.
|
||||
func newLastWrite() LastWrite {
|
||||
// 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 LastWrite{
|
||||
state: res,
|
||||
}
|
||||
}
|
||||
|
||||
// serialize returns bytes to write to the lock file to represent the specified write.
|
||||
func (lw LastWrite) serialize() []byte {
|
||||
if lw.state == nil {
|
||||
panic("LastWrite.serialize on an uninitialized object")
|
||||
}
|
||||
return lw.state
|
||||
}
|
||||
|
||||
// Equals returns true if lw matches other
|
||||
func (lw LastWrite) equals(other LastWrite) bool {
|
||||
if lw.state == nil {
|
||||
panic("LastWrite.equals on an uninitialized object")
|
||||
}
|
||||
if other.state == nil {
|
||||
panic("LastWrite.equals with an uninitialized counterparty")
|
||||
}
|
||||
return bytes.Equal(lw.state, other.state)
|
||||
}
|
||||
|
||||
// newLastWriteFromData returns a LastWrite corresponding to data that came from a previous LastWrite.serialize
|
||||
func newLastWriteFromData(serialized []byte) LastWrite {
|
||||
if serialized == nil {
|
||||
panic("newLastWriteFromData with nil data")
|
||||
}
|
||||
return LastWrite{
|
||||
state: serialized,
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user