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
// it with Register.
// 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)}
if err := container.FromDisk(); err != nil {
return nil, err
@ -145,9 +145,6 @@ func (runtime *Runtime) Load(id string) (*Container, error) {
if container.State.Running {
container.State.Ghost = true
}
if err := runtime.Register(container); err != nil {
return nil, err
}
return container, nil
}
@ -289,9 +286,14 @@ func (runtime *Runtime) restore() error {
if err != nil {
return err
}
deviceSet := runtime.deviceSet
containers := []*Container{}
containersToMigrate := []*Container{}
for i, v := range dir {
id := v.Name()
container, err := runtime.Load(id)
container, err := runtime.load(id)
if i%21 == 0 && os.Getenv("DEBUG") == "" && os.Getenv("TEST") == "" {
fmt.Printf("\b%c", wheel[i%4])
}
@ -300,10 +302,93 @@ func (runtime *Runtime) restore() error {
continue
}
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") == "" {
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
}

View File

@ -154,7 +154,7 @@ func init() {
deviceset := devmapper.NewDeviceSetDM(unitTestStoreDevicesBase)
// Create a device, which triggers the initiation of the base FS
// This avoids other tests doing this and timing out
deviceset.AddDevice("init","")
deviceset.AddDevice("init", "")
// Make it our Store root
if runtime, err := NewRuntimeFromDirectory(unitTestStoreBase, deviceset, false); err != nil {