Merge pull request #2183 from dotcloud/migrate-aufs

Migrate aufs to new device mapper backend
This commit is contained in:
Solomon Hykes 2013-10-14 12:28:28 -07:00
commit 4dedd9a9aa
2 changed files with 91 additions and 6 deletions

View File

@ -134,7 +134,7 @@ func (runtime *Runtime) containerRoot(id string) string {
// Load reads the contents of a container from disk and registers // Load reads the contents of a container from disk and registers
// it with Register. // it with Register.
// This is typically done at startup. // This is typically done at startup.
func (runtime *Runtime) Load(id string) (*Container, error) { func (runtime *Runtime) load(id string) (*Container, error) {
container := &Container{root: runtime.containerRoot(id)} container := &Container{root: runtime.containerRoot(id)}
if err := container.FromDisk(); err != nil { if err := container.FromDisk(); err != nil {
return nil, err return nil, err
@ -145,9 +145,6 @@ func (runtime *Runtime) Load(id string) (*Container, error) {
if container.State.Running { if container.State.Running {
container.State.Ghost = true container.State.Ghost = true
} }
if err := runtime.Register(container); err != nil {
return nil, err
}
return container, nil return container, nil
} }
@ -289,9 +286,14 @@ func (runtime *Runtime) restore() error {
if err != nil { if err != nil {
return err return err
} }
deviceSet := runtime.deviceSet
containers := []*Container{}
containersToMigrate := []*Container{}
for i, v := range dir { for i, v := range dir {
id := v.Name() id := v.Name()
container, err := runtime.Load(id) container, err := runtime.load(id)
if i%21 == 0 && os.Getenv("DEBUG") == "" && os.Getenv("TEST") == "" { if i%21 == 0 && os.Getenv("DEBUG") == "" && os.Getenv("TEST") == "" {
fmt.Printf("\b%c", wheel[i%4]) fmt.Printf("\b%c", wheel[i%4])
} }
@ -300,10 +302,93 @@ func (runtime *Runtime) restore() error {
continue continue
} }
utils.Debugf("Loaded container %v", container.ID) utils.Debugf("Loaded container %v", container.ID)
containers = append(containers, container)
if !deviceSet.HasDevice(container.ID) {
containersToMigrate = append(containersToMigrate, container)
}
}
// Migrate AUFS containers to device mapper
if len(containersToMigrate) > 0 {
if err := migrateToDeviceMapper(runtime, containersToMigrate); err != nil {
return err
}
}
for _, container := range containers {
if err := runtime.Register(container); err != nil {
utils.Debugf("Failed to register container %s: %s", container.ID, err)
continue
}
} }
if os.Getenv("DEBUG") == "" && os.Getenv("TEST") == "" { if os.Getenv("DEBUG") == "" && os.Getenv("TEST") == "" {
fmt.Printf("\bdone.\n") fmt.Printf("\bdone.\n")
} }
return nil
}
func migrateToDeviceMapper(runtime *Runtime, containers []*Container) error {
var (
image *Image
contents []os.FileInfo
err error
)
fmt.Printf("Migrating %d containers to new storage backend\n", len(containers))
for _, container := range containers {
if container.State.Running {
fmt.Printf("WARNING - Cannot migrate %s because the container is running. Please stop the container and relaunch the daemon!")
continue
}
fmt.Printf("Migrating %s\n", container.ID)
if contents, err = ioutil.ReadDir(container.rwPath()); err != nil {
if !os.IsNotExist(err) {
fmt.Printf("Error reading rw dir %s\n", err)
}
continue
}
if len(contents) == 0 {
fmt.Printf("Skipping migration of %s because rw layer contains no changes\n")
continue
}
if image, err = runtime.graph.Get(container.Image); err != nil {
fmt.Printf("Failed to fetch image %s\n", err)
continue
}
unmount := func() {
if err = image.Unmount(runtime, container.RootfsPath(), container.ID); err != nil {
fmt.Printf("Failed to unmount image %s\n", err)
}
}
if err = image.Mount(runtime, container.RootfsPath(), container.rwPath(), container.ID); err != nil {
fmt.Printf("Failed to mount image %s\n", err)
continue
}
if err = image.applyLayer(container.rwPath(), container.RootfsPath()); err != nil {
fmt.Printf("Failed to apply layer in storage backend %s\n", err)
unmount()
continue
}
unmount()
if err = os.RemoveAll(container.rwPath()); err != nil {
fmt.Printf("Failed to remove rw layer %s\n", err)
}
fmt.Printf("Successful migration for %s\n", container.ID)
}
fmt.Printf("Migration complete\n")
return nil return nil
} }