mirror of
https://github.com/kata-containers/kata-containers.git
synced 2025-08-11 12:52:23 +00:00
Merge pull request #1069 from sboeuf/fix_fc_k8s
mounts: Ignore existing mounts if they cannot be honored
This commit is contained in:
commit
1e8f84854c
@ -431,10 +431,10 @@ func (c *Container) createContainersDirs() error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Container) shareFiles(m Mount, idx int, hostSharedDir, guestSharedDir string) (string, error) {
|
func (c *Container) shareFiles(m Mount, idx int, hostSharedDir, guestSharedDir string) (string, bool, error) {
|
||||||
randBytes, err := utils.GenerateRandomBytes(8)
|
randBytes, err := utils.GenerateRandomBytes(8)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", false, err
|
||||||
}
|
}
|
||||||
|
|
||||||
filename := fmt.Sprintf("%s-%s-%s", c.id, hex.EncodeToString(randBytes), filepath.Base(m.Destination))
|
filename := fmt.Sprintf("%s-%s-%s", c.id, hex.EncodeToString(randBytes), filepath.Base(m.Destination))
|
||||||
@ -445,20 +445,35 @@ func (c *Container) shareFiles(m Mount, idx int, hostSharedDir, guestSharedDir s
|
|||||||
caps := c.sandbox.hypervisor.capabilities()
|
caps := c.sandbox.hypervisor.capabilities()
|
||||||
if !caps.isFsSharingSupported() {
|
if !caps.isFsSharingSupported() {
|
||||||
c.Logger().Debug("filesystem sharing is not supported, files will be copied")
|
c.Logger().Debug("filesystem sharing is not supported, files will be copied")
|
||||||
|
|
||||||
|
fileInfo, err := os.Stat(m.Source)
|
||||||
|
if err != nil {
|
||||||
|
return "", false, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Ignore the mount if this is not a regular file (excludes
|
||||||
|
// directory, socket, device, ...) as it cannot be handled by
|
||||||
|
// a simple copy. But this should not be treated as an error,
|
||||||
|
// only as a limitation.
|
||||||
|
if !fileInfo.Mode().IsRegular() {
|
||||||
|
c.Logger().WithField("ignored-file", m.Source).Debug("Ignoring non-regular file as FS sharing not supported")
|
||||||
|
return "", true, nil
|
||||||
|
}
|
||||||
|
|
||||||
if err := c.sandbox.agent.copyFile(m.Source, guestDest); err != nil {
|
if err := c.sandbox.agent.copyFile(m.Source, guestDest); err != nil {
|
||||||
return "", err
|
return "", false, err
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// These mounts are created in the shared dir
|
// These mounts are created in the shared dir
|
||||||
mountDest := filepath.Join(hostSharedDir, c.sandbox.id, filename)
|
mountDest := filepath.Join(hostSharedDir, c.sandbox.id, filename)
|
||||||
if err := bindMount(c.ctx, m.Source, mountDest, false); err != nil {
|
if err := bindMount(c.ctx, m.Source, mountDest, false); err != nil {
|
||||||
return "", err
|
return "", false, err
|
||||||
}
|
}
|
||||||
// Save HostPath mount value into the mount list of the container.
|
// Save HostPath mount value into the mount list of the container.
|
||||||
c.mounts[idx].HostPath = mountDest
|
c.mounts[idx].HostPath = mountDest
|
||||||
}
|
}
|
||||||
|
|
||||||
return guestDest, nil
|
return guestDest, false, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// mountSharedDirMounts handles bind-mounts by bindmounting to the host shared
|
// mountSharedDirMounts handles bind-mounts by bindmounting to the host shared
|
||||||
@ -466,8 +481,9 @@ func (c *Container) shareFiles(m Mount, idx int, hostSharedDir, guestSharedDir s
|
|||||||
// It also updates the container mount list with the HostPath info, and store
|
// It also updates the container mount list with the HostPath info, and store
|
||||||
// container mounts to the storage. This way, we will have the HostPath info
|
// container mounts to the storage. This way, we will have the HostPath info
|
||||||
// available when we will need to unmount those mounts.
|
// available when we will need to unmount those mounts.
|
||||||
func (c *Container) mountSharedDirMounts(hostSharedDir, guestSharedDir string) ([]Mount, error) {
|
func (c *Container) mountSharedDirMounts(hostSharedDir, guestSharedDir string) ([]Mount, []Mount, error) {
|
||||||
var sharedDirMounts []Mount
|
var sharedDirMounts []Mount
|
||||||
|
var ignoredMounts []Mount
|
||||||
for idx, m := range c.mounts {
|
for idx, m := range c.mounts {
|
||||||
if isSystemMount(m.Destination) || m.Type != "bind" {
|
if isSystemMount(m.Destination) || m.Type != "bind" {
|
||||||
continue
|
continue
|
||||||
@ -485,12 +501,12 @@ func (c *Container) mountSharedDirMounts(hostSharedDir, guestSharedDir string) (
|
|||||||
if len(m.BlockDeviceID) > 0 {
|
if len(m.BlockDeviceID) > 0 {
|
||||||
// Attach this block device, all other devices passed in the config have been attached at this point
|
// Attach this block device, all other devices passed in the config have been attached at this point
|
||||||
if err := c.sandbox.devManager.AttachDevice(m.BlockDeviceID, c.sandbox); err != nil {
|
if err := c.sandbox.devManager.AttachDevice(m.BlockDeviceID, c.sandbox); err != nil {
|
||||||
return nil, err
|
return nil, nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := c.sandbox.storeSandboxDevices(); err != nil {
|
if err := c.sandbox.storeSandboxDevices(); err != nil {
|
||||||
//TODO: roll back?
|
//TODO: roll back?
|
||||||
return nil, err
|
return nil, nil, err
|
||||||
}
|
}
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
@ -502,9 +518,15 @@ func (c *Container) mountSharedDirMounts(hostSharedDir, guestSharedDir string) (
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
guestDest, err := c.shareFiles(m, idx, hostSharedDir, guestSharedDir)
|
guestDest, ignore, err := c.shareFiles(m, idx, hostSharedDir, guestSharedDir)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Expand the list of mounts to ignore.
|
||||||
|
if ignore {
|
||||||
|
ignoredMounts = append(ignoredMounts, Mount{Source: m.Source})
|
||||||
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check if mount is readonly, let the agent handle the readonly mount
|
// Check if mount is readonly, let the agent handle the readonly mount
|
||||||
@ -528,10 +550,10 @@ func (c *Container) mountSharedDirMounts(hostSharedDir, guestSharedDir string) (
|
|||||||
}
|
}
|
||||||
|
|
||||||
if err := c.storeMounts(); err != nil {
|
if err := c.storeMounts(); err != nil {
|
||||||
return nil, err
|
return nil, nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
return sharedDirMounts, nil
|
return sharedDirMounts, ignoredMounts, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Container) unmountHostMounts() error {
|
func (c *Container) unmountHostMounts() error {
|
||||||
|
@ -549,7 +549,7 @@ func (h *hyper) startOneContainer(sandbox *Sandbox, c *Container) error {
|
|||||||
//TODO : Enter mount namespace
|
//TODO : Enter mount namespace
|
||||||
|
|
||||||
// Handle container mounts
|
// Handle container mounts
|
||||||
newMounts, err := c.mountSharedDirMounts(defaultSharedDir, "")
|
newMounts, _, err := c.mountSharedDirMounts(defaultSharedDir, "")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
bindUnmountAllRootfs(c.ctx, defaultSharedDir, sandbox)
|
bindUnmountAllRootfs(c.ctx, defaultSharedDir, sandbox)
|
||||||
return err
|
return err
|
||||||
|
@ -719,6 +719,30 @@ func (k *kataAgent) replaceOCIMountSource(spec *specs.Spec, guestMounts []Mount)
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (k *kataAgent) removeIgnoredOCIMount(spec *specs.Spec, ignoredMounts []Mount) error {
|
||||||
|
var mounts []specs.Mount
|
||||||
|
|
||||||
|
for _, m := range spec.Mounts {
|
||||||
|
found := false
|
||||||
|
for _, ignoredMount := range ignoredMounts {
|
||||||
|
if ignoredMount.Source == m.Source {
|
||||||
|
k.Logger().WithField("removed-mount", m.Source).Debug("Removing OCI mount")
|
||||||
|
found = true
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if !found {
|
||||||
|
mounts = append(mounts, m)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Replace the OCI mounts with the updated list.
|
||||||
|
spec.Mounts = mounts
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
func (k *kataAgent) replaceOCIMountsForStorages(spec *specs.Spec, volumeStorages []*grpc.Storage) error {
|
func (k *kataAgent) replaceOCIMountsForStorages(spec *specs.Spec, volumeStorages []*grpc.Storage) error {
|
||||||
ociMounts := spec.Mounts
|
ociMounts := spec.Mounts
|
||||||
var index int
|
var index int
|
||||||
@ -981,7 +1005,7 @@ func (k *kataAgent) createContainer(sandbox *Sandbox, c *Container) (p *Process,
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Handle container mounts
|
// Handle container mounts
|
||||||
newMounts, err := c.mountSharedDirMounts(kataHostSharedDir, kataGuestSharedDir)
|
newMounts, ignoredMounts, err := c.mountSharedDirMounts(kataHostSharedDir, kataGuestSharedDir)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@ -995,6 +1019,11 @@ func (k *kataAgent) createContainer(sandbox *Sandbox, c *Container) (p *Process,
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Remove all mounts that should be ignored from the spec
|
||||||
|
if err = k.removeIgnoredOCIMount(ociSpec, ignoredMounts); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
// Append container devices for block devices passed with --device.
|
// Append container devices for block devices passed with --device.
|
||||||
ctrDevices = k.appendDevices(ctrDevices, c)
|
ctrDevices = k.appendDevices(ctrDevices, c)
|
||||||
|
|
||||||
@ -1769,6 +1798,12 @@ func (k *kataAgent) copyFile(src, dst string) error {
|
|||||||
Gid: int32(st.Gid),
|
Gid: int32(st.Gid),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Handle the special case where the file is empty
|
||||||
|
if fileSize == 0 {
|
||||||
|
_, err = k.sendReq(cpReq)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
// Copy file by parts if it's needed
|
// Copy file by parts if it's needed
|
||||||
remainingBytes := fileSize
|
remainingBytes := fileSize
|
||||||
offset := int64(0)
|
offset := int64(0)
|
||||||
|
@ -1706,10 +1706,12 @@ func TestPreAddDevice(t *testing.T) {
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
mounts, err := container.mountSharedDirMounts("", "")
|
mounts, ignoreMounts, err := container.mountSharedDirMounts("", "")
|
||||||
assert.Nil(t, err)
|
assert.Nil(t, err)
|
||||||
assert.Equal(t, len(mounts), 0,
|
assert.Equal(t, len(mounts), 0,
|
||||||
"mounts should contain nothing because it only contains a block device")
|
"mounts should contain nothing because it only contains a block device")
|
||||||
|
assert.Equal(t, len(ignoreMounts), 0,
|
||||||
|
"ignoreMounts should contain nothing because it only contains a block device")
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestGetNetNs(t *testing.T) {
|
func TestGetNetNs(t *testing.T) {
|
||||||
|
Loading…
Reference in New Issue
Block a user