Use mount.Target to specify subdirectory of rootfs mount

- Add Target to mount.Mount.
- Add UnmountMounts to unmount a list of mounts in reverse order.
- Add UnmountRecursive to unmount deepest mount first for a given target, using
moby/sys/mountinfo.

Signed-off-by: Edgar Lee <edgarhinshunlee@gmail.com>
This commit is contained in:
Edgar Lee
2023-01-23 13:36:28 -05:00
parent 753bfd6575
commit 34d5878185
26 changed files with 282 additions and 65 deletions

View File

@@ -130,7 +130,7 @@ func (b *Bundle) Delete() error {
work, werr := os.Readlink(filepath.Join(b.Path, "work"))
rootfs := filepath.Join(b.Path, "rootfs")
if runtime.GOOS != "darwin" {
if err := mount.UnmountAll(rootfs, 0); err != nil {
if err := mount.UnmountRecursive(rootfs, 0); err != nil {
return fmt.Errorf("unmount rootfs %s: %w", rootfs, err)
}
}

View File

@@ -59,9 +59,9 @@ func NewContainer(ctx context.Context, platform stdio.Platform, r *task.CreateTa
}
}
var mounts []process.Mount
var pmounts []process.Mount
for _, m := range r.Rootfs {
mounts = append(mounts, process.Mount{
pmounts = append(pmounts, process.Mount{
Type: m.Type,
Source: m.Source,
Target: m.Target,
@@ -70,7 +70,7 @@ func NewContainer(ctx context.Context, platform stdio.Platform, r *task.CreateTa
}
rootfs := ""
if len(mounts) > 0 {
if len(pmounts) > 0 {
rootfs = filepath.Join(r.Bundle, "rootfs")
if err := os.Mkdir(rootfs, 0711); err != nil && !os.IsExist(err) {
return nil, err
@@ -81,7 +81,7 @@ func NewContainer(ctx context.Context, platform stdio.Platform, r *task.CreateTa
ID: r.ID,
Bundle: r.Bundle,
Runtime: opts.BinaryName,
Rootfs: mounts,
Rootfs: pmounts,
Terminal: r.Terminal,
Stdin: r.Stdin,
Stdout: r.Stdout,
@@ -98,22 +98,25 @@ func NewContainer(ctx context.Context, platform stdio.Platform, r *task.CreateTa
if err := WriteRuntime(r.Bundle, opts.BinaryName); err != nil {
return nil, err
}
var mounts []mount.Mount
for _, pm := range pmounts {
mounts = append(mounts, mount.Mount{
Type: pm.Type,
Source: pm.Source,
Target: pm.Target,
Options: pm.Options,
})
}
defer func() {
if retErr != nil {
if err := mount.UnmountAll(rootfs, 0); err != nil {
if err := mount.UnmountMounts(mounts, rootfs, 0); err != nil {
logrus.WithError(err).Warn("failed to cleanup rootfs mount")
}
}
}()
for _, rm := range mounts {
m := &mount.Mount{
Type: rm.Type,
Source: rm.Source,
Options: rm.Options,
}
if err := m.Mount(rootfs); err != nil {
return nil, fmt.Errorf("failed to mount rootfs component %v: %w", m, err)
}
if err := mount.All(mounts, rootfs); err != nil {
return nil, fmt.Errorf("failed to mount rootfs component: %w", err)
}
p, err := newInit(

View File

@@ -255,7 +255,7 @@ func (manager) Stop(ctx context.Context, id string) (shim.StopStatus, error) {
}); err != nil {
log.G(ctx).WithError(err).Warn("failed to remove runc container")
}
if err := mount.UnmountAll(filepath.Join(path, "rootfs"), 0); err != nil {
if err := mount.UnmountRecursive(filepath.Join(path, "rootfs"), 0); err != nil {
log.G(ctx).WithError(err).Warn("failed to cleanup rootfs mount")
}
pid, err := runcC.ReadPidFile(filepath.Join(path, process.InitPidFile))

View File

@@ -254,7 +254,7 @@ func (s *service) Cleanup(ctx context.Context) (*taskAPI.DeleteResponse, error)
}); err != nil {
logrus.WithError(err).Warn("failed to remove runc container")
}
if err := mount.UnmountAll(filepath.Join(path, "rootfs"), 0); err != nil {
if err := mount.UnmountRecursive(filepath.Join(path, "rootfs"), 0); err != nil {
logrus.WithError(err).Warn("failed to cleanup rootfs mount")
}

View File

@@ -350,6 +350,7 @@ func (s *shimTask) Create(ctx context.Context, opts runtime.CreateOpts) (runtime
request.Rootfs = append(request.Rootfs, &types.Mount{
Type: m.Type,
Source: m.Source,
Target: m.Target,
Options: m.Options,
})
}

View File

@@ -110,7 +110,7 @@ func (m *ShimManager) loadShims(ctx context.Context) error {
container, err := m.containers.Get(ctx, id)
if err != nil {
log.G(ctx).WithError(err).Errorf("loading container %s", id)
if err := mount.UnmountAll(filepath.Join(bundle.Path, "rootfs"), 0); err != nil {
if err := mount.UnmountRecursive(filepath.Join(bundle.Path, "rootfs"), 0); err != nil {
log.G(ctx).WithError(err).Errorf("failed to unmount of rootfs %s", id)
}
bundle.Delete()