1
0
Fork 0
mirror of https://github.com/moby/moby.git synced 2022-11-09 12:21:53 -05:00

avoid re-reading json files when copying containers

Signed-off-by: Fabio Kung <fabio.kung@gmail.com>
This commit is contained in:
Fabio Kung 2017-04-06 10:43:10 -07:00
parent 9134e87afc
commit a43be3431e
4 changed files with 55 additions and 32 deletions

View file

@ -1,6 +1,7 @@
package container
import (
"bytes"
"encoding/json"
"fmt"
"io"
@ -14,8 +15,6 @@ import (
"syscall"
"time"
"golang.org/x/net/context"
"github.com/Sirupsen/logrus"
containertypes "github.com/docker/docker/api/types/container"
mounttypes "github.com/docker/docker/api/types/mount"
@ -45,6 +44,7 @@ import (
"github.com/docker/libnetwork/options"
"github.com/docker/libnetwork/types"
agentexec "github.com/docker/swarmkit/agent/exec"
"golang.org/x/net/context"
)
const configFileName = "config.v2.json"
@ -154,36 +154,48 @@ func (container *Container) FromDisk() error {
return container.readHostConfig()
}
// ToDisk saves the container configuration on disk.
func (container *Container) toDisk() error {
// toDisk saves the container configuration on disk and returns a deep copy.
func (container *Container) toDisk() (*Container, error) {
var (
buf bytes.Buffer
deepCopy Container
)
pth, err := container.ConfigPath()
if err != nil {
return err
return nil, err
}
jsonSource, err := ioutils.NewAtomicFileWriter(pth, 0644)
if err != nil {
return err
}
defer jsonSource.Close()
enc := json.NewEncoder(jsonSource)
// Save container settings
if err := enc.Encode(container); err != nil {
return err
f, err := ioutils.NewAtomicFileWriter(pth, 0644)
if err != nil {
return nil, err
}
defer f.Close()
w := io.MultiWriter(&buf, f)
if err := json.NewEncoder(w).Encode(container); err != nil {
return nil, err
}
return container.WriteHostConfig()
if err := json.NewDecoder(&buf).Decode(&deepCopy); err != nil {
return nil, err
}
deepCopy.HostConfig, err = container.WriteHostConfig()
if err != nil {
return nil, err
}
return &deepCopy, nil
}
// CheckpointTo makes the Container's current state visible to queries, and persists state.
// Callers must hold a Container lock.
func (container *Container) CheckpointTo(store ViewDB) error {
if err := container.toDisk(); err != nil {
deepCopy, err := container.toDisk()
if err != nil {
return err
}
return store.Save(container)
return store.Save(deepCopy)
}
// readHostConfig reads the host configuration from disk for the container.
@ -215,20 +227,34 @@ func (container *Container) readHostConfig() error {
return nil
}
// WriteHostConfig saves the host configuration on disk for the container.
func (container *Container) WriteHostConfig() error {
// WriteHostConfig saves the host configuration on disk for the container,
// and returns a deep copy of the saved object. Callers must hold a Container lock.
func (container *Container) WriteHostConfig() (*containertypes.HostConfig, error) {
var (
buf bytes.Buffer
deepCopy containertypes.HostConfig
)
pth, err := container.HostConfigPath()
if err != nil {
return err
return nil, err
}
f, err := ioutils.NewAtomicFileWriter(pth, 0644)
if err != nil {
return err
return nil, err
}
defer f.Close()
return json.NewEncoder(f).Encode(&container.HostConfig)
w := io.MultiWriter(&buf, f)
if err := json.NewEncoder(w).Encode(&container.HostConfig); err != nil {
return nil, err
}
if err := json.NewDecoder(&buf).Decode(&deepCopy); err != nil {
return nil, err
}
return &deepCopy, nil
}
// SetupWorkingDirectory sets up the container's working directory as set in container.Config.WorkingDir

View file

@ -90,16 +90,12 @@ func (db *memDB) Snapshot(index *registrar.Registrar) View {
}
}
// Save atomically updates the in-memory store from the current on-disk state of a Container.
// Save atomically updates the in-memory store state for a Container.
// Only read only (deep) copies of containers may be passed in.
func (db *memDB) Save(c *Container) error {
txn := db.store.Txn(true)
defer txn.Commit()
deepCopy := NewBaseContainer(c.ID, c.Root)
err := deepCopy.FromDisk()
if err != nil {
return err
}
return txn.Insert(memdbTable, deepCopy)
return txn.Insert(memdbTable, c)
}
// Delete removes an item by ID

View file

@ -579,7 +579,7 @@ func (daemon *Daemon) allocateNetwork(container *container.Container) error {
}
if err := container.WriteHostConfig(); err != nil {
if _, err := container.WriteHostConfig(); err != nil {
return err
}
networkActions.WithValues("allocate").UpdateSince(start)

View file

@ -1146,7 +1146,8 @@ func (daemon *Daemon) registerLinks(container *container.Container, hostConfig *
// After we load all the links into the daemon
// set them to nil on the hostconfig
return container.WriteHostConfig()
_, err := container.WriteHostConfig()
return err
}
// conditionalMountOnStart is a platform specific helper function during the