Skip to content

Commit

Permalink
copy: should not mount rootfs again
Browse files Browse the repository at this point in the history
for the copy command, we need to copy thing into container. But we can't
mount/umount the rootfs again, because it will impact /home and /tmp in
running container. Align with moby behaviour, we use the host rootfs
directly for running container without mount/unmount.

Signed-off-by: Wei Fu <fuweid89@gmail.com>
  • Loading branch information
fuweid authored and ZYecho committed Jun 10, 2019
1 parent 77659ab commit cdcf3ea
Show file tree
Hide file tree
Showing 2 changed files with 56 additions and 77 deletions.
78 changes: 40 additions & 38 deletions daemon/mgr/container_copy.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,28 +35,27 @@ func (mgr *ContainerManager) StatPath(ctx context.Context, name, path string) (s
}

running := c.IsRunningOrPaused()
err = mgr.Mount(ctx, c, false)
if err != nil {
return nil, pkgerrors.Wrapf(err, "failed to mount cid(%s)", c.ID)
}
if !running {
if err := mgr.Mount(ctx, c); err != nil {
return nil, pkgerrors.Wrapf(err, "failed to mount cid(%s)", c.ID)
}

defer mgr.Unmount(ctx, c, false, !running)
defer mgr.Unmount(ctx, c)

if !running {
err = mgr.attachVolumes(ctx, c)
if err != nil {
return nil, pkgerrors.Wrapf(err, "failed to attachVolumes cid(%s)", c.ID)
}
defer mgr.detachVolumes(ctx, c, false)
}

err = c.mountVolumes()
err = c.mountVolumes(running)
if err != nil {
return nil, pkgerrors.Wrapf(err, "failed to mountVolumes cid(%s)", c.ID)
}
defer c.unmountVolumes()
defer c.unmountVolumes(running)

resolvedPath, absPath := c.getResolvedPath(path)
resolvedPath, absPath := c.getResolvedPath(path, running)
lstat, err := os.Lstat(resolvedPath)

if err != nil {
Expand Down Expand Up @@ -90,17 +89,16 @@ func (mgr *ContainerManager) ArchivePath(ctx context.Context, name, path string)
}

running := c.IsRunningOrPaused()
err = mgr.Mount(ctx, c, false)
if err != nil {
return nil, nil, pkgerrors.Wrapf(err, "failed to mount cid(%s)", c.ID)
}
defer func() {
if err0 != nil {
mgr.Unmount(ctx, c, false, !running)
if !running {
if err := mgr.Mount(ctx, c); err != nil {
return nil, nil, pkgerrors.Wrapf(err, "failed to mount cid(%s)", c.ID)
}
}()
defer func() {
if err0 != nil {
mgr.Unmount(ctx, c)
}
}()

if !running {
err = mgr.attachVolumes(ctx, c)
if err != nil {
return nil, nil, pkgerrors.Wrapf(err, "failed to attachVolumes cid(%s)", c.ID)
Expand All @@ -112,17 +110,17 @@ func (mgr *ContainerManager) ArchivePath(ctx context.Context, name, path string)
}()
}

err = c.mountVolumes()
err = c.mountVolumes(running)
if err != nil {
return nil, nil, pkgerrors.Wrapf(err, "failed to mountVolumes cid(%s)", c.ID)
}
defer func() {
if err0 != nil {
defer c.unmountVolumes()
c.unmountVolumes(running)
}
}()

resolvedPath, absPath := c.getResolvedPath(path)
resolvedPath, absPath := c.getResolvedPath(path, running)
lstat, err := os.Lstat(resolvedPath)
if err != nil {
return nil, nil, err
Expand Down Expand Up @@ -151,8 +149,8 @@ func (mgr *ContainerManager) ArchivePath(ctx context.Context, name, path string)
if !running {
mgr.detachVolumes(ctx, c, false)
}
c.unmountVolumes()
mgr.Unmount(ctx, c, false, !running)
c.unmountVolumes(running)
mgr.Unmount(ctx, c)
c.Unlock()
return err
})
Expand All @@ -174,27 +172,26 @@ func (mgr *ContainerManager) ExtractToDir(ctx context.Context, name, path string
}

running := c.IsRunningOrPaused()
err = mgr.Mount(ctx, c, false)
if err != nil {
return pkgerrors.Wrapf(err, "failed to mount cid(%s)", c.ID)
}
defer mgr.Unmount(ctx, c, false, !running)

if !running {
if err := mgr.Mount(ctx, c); err != nil {
return pkgerrors.Wrapf(err, "failed to mount cid(%s)", c.ID)
}
defer mgr.Unmount(ctx, c)

err = mgr.attachVolumes(ctx, c)
if err != nil {
return pkgerrors.Wrapf(err, "failed to attachVolumes cid(%s)", c.ID)
}
defer mgr.detachVolumes(ctx, c, false)
}

err = c.mountVolumes()
err = c.mountVolumes(running)
if err != nil {
return pkgerrors.Wrapf(err, "failed to mountVolumes cid(%s)", c.ID)
}
defer c.unmountVolumes()
defer c.unmountVolumes(running)

resolvedPath, _ := c.getResolvedPath(path)
resolvedPath, _ := c.getResolvedPath(path, running)

lstat, err := os.Lstat(resolvedPath)
if err != nil {
Expand Down Expand Up @@ -230,21 +227,26 @@ func (mgr *ContainerManager) ExtractToDir(ctx context.Context, name, path string
return chrootarchive.Untar(content, resolvedPath, opts)
}

func (c *Container) getResolvedPath(path string) (resolvedPath, absPath string) {
func (c *Container) getResolvedPath(path string, running bool) (resolvedPath, absPath string) {
// consider the given path as an absolute path in the container.
absPath = path
if !filepath.IsAbs(absPath) {
absPath = archive.PreserveTrailingDotOrSeparator(filepath.Join(string(os.PathSeparator), path), path, os.PathSeparator)
}

rootfs := c.MountFS
if running {
rootfs = c.BaseFS
}

// get the real path on the host
resolvedPath = filepath.Join(c.BaseFS, absPath)
resolvedPath = filepath.Join(rootfs, absPath)
resolvedPath = filepath.Clean(resolvedPath)

return resolvedPath, absPath
}

func (c *Container) mountVolumes() (err0 error) {
func (c *Container) mountVolumes(running bool) (err0 error) {
rollbackMounts := make([]string, 0, len(c.Mounts))

defer func() {
Expand All @@ -260,7 +262,7 @@ func (c *Container) mountVolumes() (err0 error) {
}()

for _, m := range c.Mounts {
dest, _ := c.getResolvedPath(m.Destination)
dest, _ := c.getResolvedPath(m.Destination, running)

logrus.Debugf("try to mount volume(source %s -> dest %s", m.Source, dest)

Expand Down Expand Up @@ -303,9 +305,9 @@ func (c *Container) mountVolumes() (err0 error) {
return nil
}

func (c *Container) unmountVolumes() error {
func (c *Container) unmountVolumes(running bool) error {
for _, m := range c.Mounts {
dest, _ := c.getResolvedPath(m.Destination)
dest, _ := c.getResolvedPath(m.Destination, running)

if err := mount.Unmount(dest); err != nil {
return err
Expand Down
55 changes: 16 additions & 39 deletions daemon/mgr/container_storage.go
Original file line number Diff line number Diff line change
Expand Up @@ -704,9 +704,7 @@ func (mgr *ContainerManager) setMountFS(ctx context.Context, c *Container) {
}

// Mount sets the container rootfs
// preCreate = false, mount rootfs at c.BaseFS
// preCreate = true, pouchd does some initial job before container created, so we mount rootfs at c.MountFS
func (mgr *ContainerManager) Mount(ctx context.Context, c *Container, preCreate bool) error {
func (mgr *ContainerManager) Mount(ctx context.Context, c *Container) error {

mounts, err := mgr.Client.GetMounts(ctx, c.ID)
if err != nil {
Expand All @@ -715,58 +713,37 @@ func (mgr *ContainerManager) Mount(ctx context.Context, c *Container, preCreate
return fmt.Errorf("failed to get snapshot %s mounts: not equals 1", c.ID)
}

rootfs := c.BaseFS

if preCreate {
if c.MountFS == "" {
mgr.setMountFS(ctx, c)
}
rootfs = c.MountFS
if c.MountFS == "" {
mgr.setMountFS(ctx, c)
}

err = os.MkdirAll(rootfs, 0755)
err = os.MkdirAll(c.MountFS, 0755)
if err != nil && !os.IsExist(err) {
return err
}

return mounts[0].Mount(rootfs)
return mounts[0].Mount(c.MountFS)
}

// Unmount unsets the container rootfs
// cleanup decides whether to clean up the dir or not
func (mgr *ContainerManager) Unmount(ctx context.Context, c *Container, preCreate bool, cleanup bool) error {
func (mgr *ContainerManager) Unmount(ctx context.Context, c *Container) error {
// TODO: if umount is failed, and how to deal it.
rootfs := c.MountFS
if !preCreate {
rootfs = c.BaseFS
}
var err error
err = mount.Unmount(rootfs, 0)

err := mount.Unmount(c.MountFS, 0)
if err != nil {
return errors.Wrapf(err, "failed to umount rootfs(%s)", rootfs)
}

if cleanup {
if preCreate {
return os.RemoveAll(rootfs)
}
// also need to remove dir named by container ID
cleanPath, _ := filepath.Split(rootfs)
logrus.Debugf("clean path of unmount is %s", cleanPath)
return os.RemoveAll(cleanPath)
return errors.Wrapf(err, "failed to umount mountfs(%s)", c.MountFS)
}

return err
return os.RemoveAll(c.MountFS)
}

func (mgr *ContainerManager) initContainerStorage(ctx context.Context, c *Container) (err error) {
if err = mgr.Mount(ctx, c, true); err != nil {
return errors.Wrapf(err, "failed to mount rootfs(%s)", c.MountFS)
if err = mgr.Mount(ctx, c); err != nil {
return errors.Wrapf(err, "failed to mount mountfs(%s)", c.MountFS)
}

defer func() {
if umountErr := mgr.Unmount(ctx, c, true, true); umountErr != nil {
if umountErr := mgr.Unmount(ctx, c); umountErr != nil {
if err != nil {
err = errors.Wrapf(err, "failed to umount rootfs(%s), err(%v)", c.MountFS, umountErr)
} else {
Expand Down Expand Up @@ -833,14 +810,14 @@ func (mgr *ContainerManager) getRootfs(ctx context.Context, c *Container, mounte
}
rootfs = basefs
} else if !mounted {
if err = mgr.Mount(ctx, c, true); err != nil {
return "", errors.Wrapf(err, "failed to mount rootfs: (%s)", c.MountFS)
if err = mgr.Mount(ctx, c); err != nil {
return "", errors.Wrapf(err, "failed to mount mountfs: (%s)", c.MountFS)
}
rootfs = c.MountFS

defer func() {
if err = mgr.Unmount(ctx, c, true, true); err != nil {
logrus.Errorf("failed to umount rootfs: (%s), err: (%v)", c.MountFS, err)
if err = mgr.Unmount(ctx, c); err != nil {
logrus.Errorf("failed to umount mountfs: (%s), err: (%v)", c.MountFS, err)
}
}()
} else {
Expand Down

0 comments on commit cdcf3ea

Please sign in to comment.