summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--libpod/options.go20
-rw-r--r--libpod/runtime.go17
-rw-r--r--libpod/runtime_renumber.go29
3 files changed, 37 insertions, 29 deletions
diff --git a/libpod/options.go b/libpod/options.go
index 06737776b..4a3dd582d 100644
--- a/libpod/options.go
+++ b/libpod/options.go
@@ -394,6 +394,26 @@ func WithDefaultInfraCommand(cmd string) RuntimeOption {
}
}
+// WithRenumber instructs libpod to perform a lock renumbering instead of a
+// normal init.
+// When this is specified, no valid runtime will be returned by NewRuntime.
+// Instead, libpod will reinitialize lock numbers on all pods and containers,
+// shut down the runtime, and return.
+// Renumber is intended to be used from a dedicated entrypoint, where it will
+// handle a changed maximum number of locks and return, with the program
+// exiting after that.
+func WithRenumber() RuntimeOption {
+ return func(rt *Runtime) error {
+ if rt.valid {
+ return ErrRuntimeFinalized
+ }
+
+ rt.doRenumber = true
+
+ return nil
+ }
+}
+
// Container Creation Options
// WithShmDir sets the directory that should be mounted on /dev/shm.
diff --git a/libpod/runtime.go b/libpod/runtime.go
index 4f5d1e292..bc7c061c4 100644
--- a/libpod/runtime.go
+++ b/libpod/runtime.go
@@ -79,7 +79,8 @@ type RuntimeOption func(*Runtime) error
// Runtime is the core libpod runtime
type Runtime struct {
- config *RuntimeConfig
+ config *RuntimeConfig
+
state State
store storage.Store
storageService *storageService
@@ -88,12 +89,15 @@ type Runtime struct {
netPlugin ocicni.CNIPlugin
ociRuntimePath OCIRuntimePath
conmonPath string
- valid bool
- lock sync.RWMutex
imageRuntime *image.Runtime
firewallBackend firewall.FirewallBackend
lockManager lock.Manager
configuredFrom *runtimeConfiguredFrom
+
+ doRenumber bool
+
+ valid bool
+ lock sync.RWMutex
}
// OCIRuntimePath contains information about an OCI runtime.
@@ -753,6 +757,13 @@ func makeRuntime(runtime *Runtime) (err error) {
aliveLock.Unlock()
}
}()
+ // If we're renumbering locks, do it now.
+ // It breaks out of normal runtime init, and will not return a valid
+ // runtime.
+ if runtime.doRenumber {
+ return runtime.renumberLocks()
+ }
+
_, err = os.Stat(runtimeAliveFile)
if err != nil {
// If the file doesn't exist, we need to refresh the state
diff --git a/libpod/runtime_renumber.go b/libpod/runtime_renumber.go
index d5279934e..04abc84d1 100644
--- a/libpod/runtime_renumber.go
+++ b/libpod/runtime_renumber.go
@@ -1,14 +1,11 @@
package libpod
import (
- "path/filepath"
-
- "github.com/containers/storage"
"github.com/pkg/errors"
)
-// RenumberLocks reassigns lock numbers for all containers, pods, and volumes in
-// the state.
+// renumberLocks reassigns lock numbers for all containers and pods in the
+// state.
// It renders the runtime it is called on, and all container/pod/volume structs
// from that runtime, unusable, and requires that a new runtime be initialized
// after it is called.
@@ -18,24 +15,7 @@ import (
// lock as read, renumber attempting to take a write lock?
// The alternative is some sort of session tracking, and I don't know how
// reliable that can be.
-func (r *Runtime) RenumberLocks() error {
- r.lock.Lock()
- locked := true
- defer func() {
- if locked {
- r.lock.Unlock()
- }
- }()
-
- runtimeAliveLock := filepath.Join(r.config.TmpDir, "alive.lck")
- aliveLock, err := storage.GetLockfile(runtimeAliveLock)
- if err != nil {
- return errors.Wrapf(err, "error acquiring runtime init lock")
- }
- aliveLock.Lock()
- // It's OK to defer until Shutdown() has run, so no need to check locked
- defer aliveLock.Unlock()
-
+func (r *Runtime) renumberLocks() error {
// Start off by deallocating all locks
if err := r.lockManager.FreeAllLocks(); err != nil {
return err
@@ -76,8 +56,5 @@ func (r *Runtime) RenumberLocks() error {
}
}
- r.lock.Unlock()
- locked = false
-
return r.Shutdown(false)
}