mirror of
https://github.com/containers/podman.git
synced 2026-03-13 08:01:19 +08:00
Convert pods to SHM locks
Signed-off-by: Matthew Heon <matthew.heon@gmail.com>
This commit is contained in:
committed by
Matthew Heon
parent
3de560053f
commit
d4b2f11601
@@ -323,10 +323,9 @@ func (s *BoltState) getPodFromDB(id []byte, pod *Pod, podBkt *bolt.Bucket) error
|
||||
}
|
||||
|
||||
// Get the lock
|
||||
lockPath := filepath.Join(s.runtime.lockDir, string(id))
|
||||
lock, err := storage.GetLockfile(lockPath)
|
||||
lock, err := s.runtime.lockManager.RetrieveLock(pod.config.LockID)
|
||||
if err != nil {
|
||||
return errors.Wrapf(err, "error retrieving lockfile for pod %s", string(id))
|
||||
return errors.Wrapf(err, "error retrieving lock for pod %s", string(id))
|
||||
}
|
||||
pod.lock = lock
|
||||
|
||||
|
||||
@@ -451,12 +451,11 @@ func (c *Container) refresh() error {
|
||||
}
|
||||
|
||||
// We need to pick up a new lock
|
||||
lock, err := c.runtime.lockManager.AllocateLock()
|
||||
lock, err := c.runtime.lockManager.RetrieveLock(c.config.LockID)
|
||||
if err != nil {
|
||||
return errors.Wrapf(err, "error acquiring lock for container %s", c.ID())
|
||||
}
|
||||
c.lock = lock
|
||||
c.config.LockID = c.lock.ID()
|
||||
|
||||
if err := c.save(); err != nil {
|
||||
return errors.Wrapf(err, "error refreshing state for container %s", c.ID())
|
||||
|
||||
@@ -18,7 +18,7 @@ import (
|
||||
// We can at least verify that the locks work within the local process.
|
||||
|
||||
// 4 * BITMAP_SIZE to ensure we have to traverse bitmaps
|
||||
const numLocks uint32 = 4 * BitmapSize
|
||||
var numLocks uint32 = 4 * BitmapSize
|
||||
|
||||
const lockPath = "/libpod_test"
|
||||
|
||||
@@ -155,7 +155,8 @@ func TestAllocateTwoLocksGetsDifferentLocks(t *testing.T) {
|
||||
func TestAllocateAllLocksSucceeds(t *testing.T) {
|
||||
runLockTest(t, func(t *testing.T, locks *SHMLocks) {
|
||||
sems := make(map[uint32]bool)
|
||||
for i := 0; i < numLocks; i++ {
|
||||
var i uint32
|
||||
for i = 0; i < numLocks; i++ {
|
||||
sem, err := locks.AllocateSemaphore()
|
||||
assert.NoError(t, err)
|
||||
|
||||
@@ -172,7 +173,8 @@ func TestAllocateAllLocksSucceeds(t *testing.T) {
|
||||
func TestAllocateTooManyLocksFails(t *testing.T) {
|
||||
runLockTest(t, func(t *testing.T, locks *SHMLocks) {
|
||||
// Allocate all locks
|
||||
for i := 0; i < numLocks; i++ {
|
||||
var i uint32
|
||||
for i = 0; i < numLocks; i++ {
|
||||
_, err := locks.AllocateSemaphore()
|
||||
assert.NoError(t, err)
|
||||
}
|
||||
@@ -187,7 +189,8 @@ func TestAllocateTooManyLocksFails(t *testing.T) {
|
||||
func TestAllocateDeallocateCycle(t *testing.T) {
|
||||
runLockTest(t, func(t *testing.T, locks *SHMLocks) {
|
||||
// Allocate all locks
|
||||
for i := 0; i < numLocks; i++ {
|
||||
var i uint32
|
||||
for i = 0; i < numLocks; i++ {
|
||||
_, err := locks.AllocateSemaphore()
|
||||
assert.NoError(t, err)
|
||||
}
|
||||
|
||||
@@ -3,7 +3,7 @@ package libpod
|
||||
import (
|
||||
"time"
|
||||
|
||||
"github.com/containers/storage"
|
||||
"github.com/containers/libpod/libpod/lock"
|
||||
"github.com/cri-o/ocicni/pkg/ocicni"
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
@@ -26,7 +26,7 @@ type Pod struct {
|
||||
|
||||
valid bool
|
||||
runtime *Runtime
|
||||
lock storage.Locker
|
||||
lock lock.Locker
|
||||
}
|
||||
|
||||
// PodConfig represents a pod's static configuration
|
||||
@@ -60,6 +60,9 @@ type PodConfig struct {
|
||||
|
||||
// Time pod was created
|
||||
CreatedTime time.Time `json:"created"`
|
||||
|
||||
// ID of the pod's lock
|
||||
LockID uint32 `json:"lockID"`
|
||||
}
|
||||
|
||||
// podState represents a pod's state
|
||||
|
||||
@@ -501,6 +501,8 @@ func easyjsonBe091417DecodeGithubComContainersLibpodLibpod4(in *jlexer.Lexer, ou
|
||||
if data := in.Raw(); in.Ok() {
|
||||
in.AddError((out.CreatedTime).UnmarshalJSON(data))
|
||||
}
|
||||
case "lockID":
|
||||
out.LockID = uint32(in.Uint32())
|
||||
default:
|
||||
in.SkipRecursive()
|
||||
}
|
||||
@@ -675,6 +677,16 @@ func easyjsonBe091417EncodeGithubComContainersLibpodLibpod4(out *jwriter.Writer,
|
||||
}
|
||||
out.Raw((in.CreatedTime).MarshalJSON())
|
||||
}
|
||||
{
|
||||
const prefix string = ",\"lockID\":"
|
||||
if first {
|
||||
first = false
|
||||
out.RawString(prefix[1:])
|
||||
} else {
|
||||
out.RawString(prefix)
|
||||
}
|
||||
out.Uint32(uint32(in.LockID))
|
||||
}
|
||||
out.RawByte('}')
|
||||
}
|
||||
|
||||
|
||||
@@ -7,7 +7,6 @@ import (
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/containers/storage"
|
||||
"github.com/containers/storage/pkg/stringid"
|
||||
"github.com/pkg/errors"
|
||||
"github.com/sirupsen/logrus"
|
||||
@@ -24,15 +23,6 @@ func newPod(lockDir string, runtime *Runtime) (*Pod, error) {
|
||||
pod.state = new(podState)
|
||||
pod.runtime = runtime
|
||||
|
||||
// Path our lock file will reside at
|
||||
lockPath := filepath.Join(lockDir, pod.config.ID)
|
||||
// Grab a lockfile at the given path
|
||||
lock, err := storage.GetLockfile(lockPath)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "error creating lockfile for new pod")
|
||||
}
|
||||
pod.lock = lock
|
||||
|
||||
return pod, nil
|
||||
}
|
||||
|
||||
@@ -55,6 +45,8 @@ func (p *Pod) save() error {
|
||||
}
|
||||
|
||||
// Refresh a pod's state after restart
|
||||
// This cannot lock any other pod, but may lock individual containers, as those
|
||||
// will have refreshed by the time pod refresh runs.
|
||||
func (p *Pod) refresh() error {
|
||||
// Need to to an update from the DB to pull potentially-missing state
|
||||
if err := p.runtime.state.UpdatePod(p); err != nil {
|
||||
@@ -65,6 +57,13 @@ func (p *Pod) refresh() error {
|
||||
return ErrPodRemoved
|
||||
}
|
||||
|
||||
// Retrieve the pod's lock
|
||||
lock, err := p.runtime.lockManager.RetrieveLock(p.config.LockID)
|
||||
if err != nil {
|
||||
return errors.Wrapf(err, "error retrieving lock for pod %s", p.ID())
|
||||
}
|
||||
p.lock = lock
|
||||
|
||||
// We need to recreate the pod's cgroup
|
||||
if p.config.UsePodCgroup {
|
||||
switch p.runtime.config.CgroupManager {
|
||||
|
||||
@@ -81,7 +81,11 @@ func (r *Runtime) newContainer(ctx context.Context, rSpec *spec.Spec, options ..
|
||||
return nil, errors.Wrapf(err, "error allocating lock for new container")
|
||||
}
|
||||
ctr.lock = lock
|
||||
ctr.config.LockID = c.lock.ID()
|
||||
ctr.config.LockID = ctr.lock.ID()
|
||||
|
||||
ctr.valid = true
|
||||
ctr.state.State = ContainerStateConfigured
|
||||
ctr.runtime = r
|
||||
|
||||
ctr.valid = true
|
||||
ctr.state.State = ContainerStateConfigured
|
||||
|
||||
@@ -48,6 +48,14 @@ func (r *Runtime) NewPod(ctx context.Context, options ...PodCreateOption) (*Pod,
|
||||
pod.config.Name = name
|
||||
}
|
||||
|
||||
// Allocate a lock for the pod
|
||||
lock, err := r.lockManager.AllocateLock()
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "error allocating lock for new pod")
|
||||
}
|
||||
pod.lock = lock
|
||||
pod.config.LockID = pod.lock.ID()
|
||||
|
||||
pod.valid = true
|
||||
|
||||
// Check CGroup parent sanity, and set it if it was not set
|
||||
|
||||
Reference in New Issue
Block a user