mirror of
https://github.com/kata-containers/kata-containers.git
synced 2025-06-22 21:49:41 +00:00
shimv2: move container rootfs mounted flag to container level
It is in fact a container specific info not sandbox level info. We are assuming that all containers use the same snapshotter but it may not be the fact in reality. Fixes: #2532 Signed-off-by: Peng Tao <bergwolf@hyper.sh>
This commit is contained in:
parent
2d89766d3a
commit
d0a730c6e8
@ -33,9 +33,10 @@ type container struct {
|
|||||||
exit uint32
|
exit uint32
|
||||||
status task.Status
|
status task.Status
|
||||||
terminal bool
|
terminal bool
|
||||||
|
mounted bool
|
||||||
}
|
}
|
||||||
|
|
||||||
func newContainer(s *service, r *taskAPI.CreateTaskRequest, containerType vc.ContainerType, spec *specs.Spec) (*container, error) {
|
func newContainer(s *service, r *taskAPI.CreateTaskRequest, containerType vc.ContainerType, spec *specs.Spec, mounted bool) (*container, error) {
|
||||||
if r == nil {
|
if r == nil {
|
||||||
return nil, errdefs.ToGRPCf(errdefs.ErrInvalidArgument, " CreateTaskRequest points to nil")
|
return nil, errdefs.ToGRPCf(errdefs.ErrInvalidArgument, " CreateTaskRequest points to nil")
|
||||||
}
|
}
|
||||||
@ -59,6 +60,7 @@ func newContainer(s *service, r *taskAPI.CreateTaskRequest, containerType vc.Con
|
|||||||
status: task.StatusCreated,
|
status: task.StatusCreated,
|
||||||
exitIOch: make(chan struct{}),
|
exitIOch: make(chan struct{}),
|
||||||
exitCh: make(chan uint32, 1),
|
exitCh: make(chan uint32, 1),
|
||||||
|
mounted: mounted,
|
||||||
}
|
}
|
||||||
return c, nil
|
return c, nil
|
||||||
}
|
}
|
||||||
|
@ -6,15 +6,16 @@
|
|||||||
package containerdshim
|
package containerdshim
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"testing"
|
||||||
|
|
||||||
taskAPI "github.com/containerd/containerd/runtime/v2/task"
|
taskAPI "github.com/containerd/containerd/runtime/v2/task"
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
"testing"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestNewContainer(t *testing.T) {
|
func TestNewContainer(t *testing.T) {
|
||||||
assert := assert.New(t)
|
assert := assert.New(t)
|
||||||
|
|
||||||
_, err := newContainer(nil, nil, "", nil)
|
_, err := newContainer(nil, nil, "", nil, false)
|
||||||
|
|
||||||
assert.Error(err)
|
assert.Error(err)
|
||||||
}
|
}
|
||||||
@ -24,7 +25,7 @@ func TestGetExec(t *testing.T) {
|
|||||||
|
|
||||||
r := &taskAPI.CreateTaskRequest{}
|
r := &taskAPI.CreateTaskRequest{}
|
||||||
|
|
||||||
c, err := newContainer(nil, r, "", nil)
|
c, err := newContainer(nil, r, "", nil, true)
|
||||||
assert.NoError(err)
|
assert.NoError(err)
|
||||||
|
|
||||||
_, err = c.getExec("")
|
_, err = c.getExec("")
|
||||||
|
@ -20,6 +20,7 @@ import (
|
|||||||
"github.com/opencontainers/runtime-spec/specs-go"
|
"github.com/opencontainers/runtime-spec/specs-go"
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
"github.com/sirupsen/logrus"
|
"github.com/sirupsen/logrus"
|
||||||
|
|
||||||
// only register the proto type
|
// only register the proto type
|
||||||
_ "github.com/containerd/containerd/runtime/linux/runctypes"
|
_ "github.com/containerd/containerd/runtime/linux/runctypes"
|
||||||
crioption "github.com/containerd/cri-containerd/pkg/api/runtimeoptions/v1"
|
crioption "github.com/containerd/cri-containerd/pkg/api/runtimeoptions/v1"
|
||||||
@ -31,7 +32,7 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func create(ctx context.Context, s *service, r *taskAPI.CreateTaskRequest) (*container, error) {
|
func create(ctx context.Context, s *service, r *taskAPI.CreateTaskRequest) (*container, error) {
|
||||||
rootFs := vc.RootFs{Mounted: s.mount}
|
rootFs := vc.RootFs{}
|
||||||
if len(r.Rootfs) == 1 {
|
if len(r.Rootfs) == 1 {
|
||||||
m := r.Rootfs[0]
|
m := r.Rootfs[0]
|
||||||
rootFs.Source = m.Source
|
rootFs.Source = m.Source
|
||||||
@ -64,21 +65,18 @@ func create(ctx context.Context, s *service, r *taskAPI.CreateTaskRequest) (*con
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if rootFs.Mounted, err = checkAndMount(s, r); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
defer func() {
|
defer func() {
|
||||||
if err != nil && s.mount {
|
if err != nil && rootFs.Mounted {
|
||||||
if err2 := mount.UnmountAll(rootfs, 0); err2 != nil {
|
if err2 := mount.UnmountAll(rootfs, 0); err2 != nil {
|
||||||
logrus.WithError(err2).Warn("failed to cleanup rootfs mount")
|
logrus.WithError(err2).Warn("failed to cleanup rootfs mount")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
|
|
||||||
s.mount = true
|
|
||||||
if err = checkAndMount(s, r); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
rootFs.Mounted = s.mount
|
|
||||||
|
|
||||||
katautils.HandleFactory(ctx, vci, s.config)
|
katautils.HandleFactory(ctx, vci, s.config)
|
||||||
|
|
||||||
// Pass service's context instead of local ctx to CreateSandbox(), since local
|
// Pass service's context instead of local ctx to CreateSandbox(), since local
|
||||||
@ -96,27 +94,25 @@ func create(ctx context.Context, s *service, r *taskAPI.CreateTaskRequest) (*con
|
|||||||
return nil, fmt.Errorf("BUG: Cannot start the container, since the sandbox hasn't been created")
|
return nil, fmt.Errorf("BUG: Cannot start the container, since the sandbox hasn't been created")
|
||||||
}
|
}
|
||||||
|
|
||||||
if s.mount {
|
if rootFs.Mounted, err = checkAndMount(s, r); err != nil {
|
||||||
defer func() {
|
return nil, err
|
||||||
if err != nil {
|
|
||||||
if err2 := mount.UnmountAll(rootfs, 0); err2 != nil {
|
|
||||||
logrus.WithError(err2).Warn("failed to cleanup rootfs mount")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}()
|
|
||||||
|
|
||||||
if err = doMount(r.Rootfs, rootfs); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
defer func() {
|
||||||
|
if err != nil && rootFs.Mounted {
|
||||||
|
if err2 := mount.UnmountAll(rootfs, 0); err2 != nil {
|
||||||
|
logrus.WithError(err2).Warn("failed to cleanup rootfs mount")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
|
||||||
_, err = katautils.CreateContainer(ctx, vci, s.sandbox, *ociSpec, rootFs, r.ID, bundlePath, "", disableOutput, true)
|
_, err = katautils.CreateContainer(ctx, vci, s.sandbox, *ociSpec, rootFs, r.ID, bundlePath, "", disableOutput, true)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
container, err := newContainer(s, r, containerType, ociSpec)
|
container, err := newContainer(s, r, containerType, ociSpec, rootFs.Mounted)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@ -184,20 +180,19 @@ func loadRuntimeConfig(s *service, r *taskAPI.CreateTaskRequest, anno map[string
|
|||||||
return &runtimeConfig, nil
|
return &runtimeConfig, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func checkAndMount(s *service, r *taskAPI.CreateTaskRequest) error {
|
func checkAndMount(s *service, r *taskAPI.CreateTaskRequest) (bool, error) {
|
||||||
if len(r.Rootfs) == 1 {
|
if len(r.Rootfs) == 1 {
|
||||||
m := r.Rootfs[0]
|
m := r.Rootfs[0]
|
||||||
|
|
||||||
if katautils.IsBlockDevice(m.Source) && !s.config.HypervisorConfig.DisableBlockDeviceUse {
|
if katautils.IsBlockDevice(m.Source) && !s.config.HypervisorConfig.DisableBlockDeviceUse {
|
||||||
s.mount = false
|
return false, nil
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
rootfs := filepath.Join(r.Bundle, "rootfs")
|
rootfs := filepath.Join(r.Bundle, "rootfs")
|
||||||
if err := doMount(r.Rootfs, rootfs); err != nil {
|
if err := doMount(r.Rootfs, rootfs); err != nil {
|
||||||
return err
|
return false, err
|
||||||
}
|
}
|
||||||
return nil
|
return true, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func doMount(mounts []*containerd_types.Mount, rootfs string) error {
|
func doMount(mounts []*containerd_types.Mount, rootfs string) error {
|
||||||
|
@ -39,7 +39,7 @@ func deleteContainer(ctx context.Context, s *service, c *container) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
if s.mount {
|
if c.mounted {
|
||||||
rootfs := path.Join(c.bundle, "rootfs")
|
rootfs := path.Join(c.bundle, "rootfs")
|
||||||
if err := mount.UnmountAll(rootfs, 0); err != nil {
|
if err := mount.UnmountAll(rootfs, 0); err != nil {
|
||||||
logrus.WithError(err).Warn("failed to cleanup rootfs mount")
|
logrus.WithError(err).Warn("failed to cleanup rootfs mount")
|
||||||
|
@ -40,7 +40,7 @@ func TestDeleteContainerSuccessAndFail(t *testing.T) {
|
|||||||
reqCreate := &taskAPI.CreateTaskRequest{
|
reqCreate := &taskAPI.CreateTaskRequest{
|
||||||
ID: testContainerID,
|
ID: testContainerID,
|
||||||
}
|
}
|
||||||
s.containers[testContainerID], err = newContainer(s, reqCreate, "", nil)
|
s.containers[testContainerID], err = newContainer(s, reqCreate, "", nil, true)
|
||||||
assert.NoError(err)
|
assert.NoError(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -36,7 +36,7 @@ func TestExecNoSpecFail(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var err error
|
var err error
|
||||||
s.containers[testContainerID], err = newContainer(s, reqCreate, "", nil)
|
s.containers[testContainerID], err = newContainer(s, reqCreate, "", nil, false)
|
||||||
assert.NoError(err)
|
assert.NoError(err)
|
||||||
|
|
||||||
reqExec := &taskAPI.ExecProcessRequest{
|
reqExec := &taskAPI.ExecProcessRequest{
|
||||||
|
@ -57,7 +57,7 @@ func TestPauseContainerSuccess(t *testing.T) {
|
|||||||
reqCreate := &taskAPI.CreateTaskRequest{
|
reqCreate := &taskAPI.CreateTaskRequest{
|
||||||
ID: testContainerID,
|
ID: testContainerID,
|
||||||
}
|
}
|
||||||
s.containers[testContainerID], err = newContainer(s, reqCreate, "", nil)
|
s.containers[testContainerID], err = newContainer(s, reqCreate, "", nil, true)
|
||||||
assert.NoError(err)
|
assert.NoError(err)
|
||||||
|
|
||||||
reqPause := &taskAPI.PauseRequest{
|
reqPause := &taskAPI.PauseRequest{
|
||||||
@ -149,7 +149,7 @@ func TestResumeContainerSuccess(t *testing.T) {
|
|||||||
reqCreate := &taskAPI.CreateTaskRequest{
|
reqCreate := &taskAPI.CreateTaskRequest{
|
||||||
ID: testContainerID,
|
ID: testContainerID,
|
||||||
}
|
}
|
||||||
s.containers[testContainerID], err = newContainer(s, reqCreate, "", nil)
|
s.containers[testContainerID], err = newContainer(s, reqCreate, "", nil, true)
|
||||||
assert.NoError(err)
|
assert.NoError(err)
|
||||||
|
|
||||||
reqResume := &taskAPI.ResumeRequest{
|
reqResume := &taskAPI.ResumeRequest{
|
||||||
|
@ -82,7 +82,6 @@ func New(ctx context.Context, id string, publisher events.Publisher) (cdshim.Shi
|
|||||||
events: make(chan interface{}, chSize),
|
events: make(chan interface{}, chSize),
|
||||||
ec: make(chan exit, bufferSize),
|
ec: make(chan exit, bufferSize),
|
||||||
cancel: cancel,
|
cancel: cancel,
|
||||||
mount: false,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
go s.processExits()
|
go s.processExits()
|
||||||
@ -110,10 +109,6 @@ type service struct {
|
|||||||
// pid directly.
|
// pid directly.
|
||||||
pid uint32
|
pid uint32
|
||||||
|
|
||||||
// if the container's rootfs is block device backed, kata shimv2
|
|
||||||
// will not do the rootfs mount.
|
|
||||||
mount bool
|
|
||||||
|
|
||||||
ctx context.Context
|
ctx context.Context
|
||||||
sandbox vc.VCSandbox
|
sandbox vc.VCSandbox
|
||||||
containers map[string]*container
|
containers map[string]*container
|
||||||
|
@ -50,7 +50,7 @@ func TestStartStartSandboxSuccess(t *testing.T) {
|
|||||||
reqCreate := &taskAPI.CreateTaskRequest{
|
reqCreate := &taskAPI.CreateTaskRequest{
|
||||||
ID: testSandboxID,
|
ID: testSandboxID,
|
||||||
}
|
}
|
||||||
s.containers[testSandboxID], err = newContainer(s, reqCreate, vc.PodSandbox, nil)
|
s.containers[testSandboxID], err = newContainer(s, reqCreate, vc.PodSandbox, nil, false)
|
||||||
assert.NoError(err)
|
assert.NoError(err)
|
||||||
|
|
||||||
reqStart := &taskAPI.StartRequest{
|
reqStart := &taskAPI.StartRequest{
|
||||||
@ -98,7 +98,7 @@ func TestStartMissingAnnotation(t *testing.T) {
|
|||||||
reqCreate := &taskAPI.CreateTaskRequest{
|
reqCreate := &taskAPI.CreateTaskRequest{
|
||||||
ID: testSandboxID,
|
ID: testSandboxID,
|
||||||
}
|
}
|
||||||
s.containers[testSandboxID], err = newContainer(s, reqCreate, "", nil)
|
s.containers[testSandboxID], err = newContainer(s, reqCreate, "", nil, false)
|
||||||
assert.NoError(err)
|
assert.NoError(err)
|
||||||
|
|
||||||
reqStart := &taskAPI.StartRequest{
|
reqStart := &taskAPI.StartRequest{
|
||||||
@ -164,7 +164,7 @@ func TestStartStartContainerSucess(t *testing.T) {
|
|||||||
reqCreate := &taskAPI.CreateTaskRequest{
|
reqCreate := &taskAPI.CreateTaskRequest{
|
||||||
ID: testContainerID,
|
ID: testContainerID,
|
||||||
}
|
}
|
||||||
s.containers[testContainerID], err = newContainer(s, reqCreate, vc.PodContainer, nil)
|
s.containers[testContainerID], err = newContainer(s, reqCreate, vc.PodContainer, nil, false)
|
||||||
assert.NoError(err)
|
assert.NoError(err)
|
||||||
|
|
||||||
reqStart := &taskAPI.StartRequest{
|
reqStart := &taskAPI.StartRequest{
|
||||||
|
@ -112,13 +112,14 @@ func watchSandbox(s *service) {
|
|||||||
logrus.WithError(err).Warn("delete sandbox failed")
|
logrus.WithError(err).Warn("delete sandbox failed")
|
||||||
}
|
}
|
||||||
|
|
||||||
if s.mount {
|
for _, c := range s.containers {
|
||||||
for _, c := range s.containers {
|
if !c.mounted {
|
||||||
rootfs := path.Join(c.bundle, "rootfs")
|
continue
|
||||||
logrus.WithField("rootfs", rootfs).WithField("id", c.id).Debug("container umount rootfs")
|
}
|
||||||
if err := mount.UnmountAll(rootfs, 0); err != nil {
|
rootfs := path.Join(c.bundle, "rootfs")
|
||||||
logrus.WithError(err).Warn("failed to cleanup rootfs mount")
|
logrus.WithField("rootfs", rootfs).WithField("id", c.id).Debug("container umount rootfs")
|
||||||
}
|
if err := mount.UnmountAll(rootfs, 0); err != nil {
|
||||||
|
logrus.WithError(err).Warn("failed to cleanup rootfs mount")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user