libpod: add GetConfigNoCopy()

Add a new function to libpod to directly access the runtime
configuration without creating an expensive deep copy.  Further migrate
a number of callers to this new function.

This drops the number of calls to JSONDeepCopy from 4 to 1 in a simple
`podman run --rm -d busybox top`.

Future work: Please note that there are more callers of GetConfig() that
can me migrated to GetConfigNoCopy().

[NO TESTS NEEDED]

Signed-off-by: Valentin Rothberg <rothberg@redhat.com>
This commit is contained in:
Valentin Rothberg
2021-09-29 13:25:05 +02:00
parent 30bf31010e
commit 5ea369adef
4 changed files with 19 additions and 6 deletions

View File

@ -706,19 +706,32 @@ func (r *Runtime) TmpDir() (string, error) {
return r.config.Engine.TmpDir, nil return r.config.Engine.TmpDir, nil
} }
// GetConfig returns a copy of the configuration used by the runtime // GetConfig returns the configuration used by the runtime.
func (r *Runtime) GetConfig() (*config.Config, error) { // Note that the returned value is not a copy and must hence
// only be used in a reading fashion.
func (r *Runtime) GetConfigNoCopy() (*config.Config, error) {
r.lock.RLock() r.lock.RLock()
defer r.lock.RUnlock() defer r.lock.RUnlock()
if !r.valid { if !r.valid {
return nil, define.ErrRuntimeStopped return nil, define.ErrRuntimeStopped
} }
return r.config, nil
}
// GetConfig returns a copy of the configuration used by the runtime.
// Please use GetConfigNoCopy() in case you only want to read from
// but not write to the returned config.
func (r *Runtime) GetConfig() (*config.Config, error) {
rtConfig, err := r.GetConfigNoCopy()
if err != nil {
return nil, err
}
config := new(config.Config) config := new(config.Config)
// Copy so the caller won't be able to modify the actual config // Copy so the caller won't be able to modify the actual config
if err := JSONDeepCopy(r.config, config); err != nil { if err := JSONDeepCopy(rtConfig, config); err != nil {
return nil, errors.Wrapf(err, "error copying config") return nil, errors.Wrapf(err, "error copying config")
} }

View File

@ -21,7 +21,7 @@ func (ic *ContainerEngine) SecretCreate(ctx context.Context, name string, reader
// set defaults from config for the case they are not set by an upper layer // set defaults from config for the case they are not set by an upper layer
// (-> i.e. tests that talk directly to the api) // (-> i.e. tests that talk directly to the api)
cfg, err := ic.Libpod.GetConfig() cfg, err := ic.Libpod.GetConfigNoCopy()
if err != nil { if err != nil {
return nil, err return nil, err
} }

View File

@ -54,7 +54,7 @@ func CompleteSpec(ctx context.Context, r *libpod.Runtime, s *specgen.SpecGenerat
} }
} }
rtc, err := r.GetConfig() rtc, err := r.GetConfigNoCopy()
if err != nil { if err != nil {
return nil, err return nil, err
} }

View File

@ -23,7 +23,7 @@ import (
// Returns the created, container and any warnings resulting from creating the // Returns the created, container and any warnings resulting from creating the
// container, or an error. // container, or an error.
func MakeContainer(ctx context.Context, rt *libpod.Runtime, s *specgen.SpecGenerator) (*spec.Spec, *specgen.SpecGenerator, []libpod.CtrCreateOption, error) { func MakeContainer(ctx context.Context, rt *libpod.Runtime, s *specgen.SpecGenerator) (*spec.Spec, *specgen.SpecGenerator, []libpod.CtrCreateOption, error) {
rtc, err := rt.GetConfig() rtc, err := rt.GetConfigNoCopy()
if err != nil { if err != nil {
return nil, nil, nil, err return nil, nil, nil, err
} }