Use batched operations in ps
Because the podman ps command has to collection a lot of information
from various places, many of which are controlled by locks, it is a
good candidate for doing batch operations under a single lock.
@@ -373,23 +373,38 @@ func (p *psTemplateParams) headerMap() map[string]string {
// getTemplateOutput returns the modified container information
func getTemplateOutput(containers []*libpod.Container, opts psOptions) ([]psTemplateParams, error) {
- var psOutput []psTemplateParams
- var status string
+ var (
+ psOutput []psTemplateParams
+ status, ctrID string
+ conConfig *libpod.ContainerConfig
+ conState libpod.ContainerStatus
+ err error
+ exitCode int32
+ pid int
+ )
+
for _, ctr := range containers {
- ctrID := ctr.ID()
- conConfig := ctr.Config()
- conState, err := ctr.State()
+ batchErr := ctr.Batch(func(c *libpod.Container) error {
+ ctrID = c.ID()
+ conConfig = c.Config()
+ conState, err = c.State()
if err != nil {
- return psOutput, errors.Wrapf(err, "unable to obtain container state")
+ return errors.Wrapf(err, "unable to obtain container state")
}
- exitCode, err := ctr.ExitCode()
+ exitCode, err = c.ExitCode()
if err != nil {
- return psOutput, errors.Wrapf(err, "unable to obtain container exit code")
+ return errors.Wrapf(err, "unable to obtain container exit code")
}
- pid, err := ctr.PID()
+ pid, err = c.PID()
if err != nil {
- return psOutput, errors.Wrapf(err, "unable to obtain container pid")
+ return errors.Wrapf(err, "unable to obtain container pid")
}
+ return nil
+ })
+ if batchErr != nil {
+ return nil, err
+ }
+
runningFor := units.HumanDuration(time.Since(conConfig.CreatedTime))
createdAt := runningFor + " ago"
imageName := conConfig.RootfsImageName
