Skip to content
This repository was archived by the owner on May 12, 2021. It is now read-only.

Commit 7739905

Browse files
bergwolfegernst
authored andcommitted
runtime: mount shared mountpoint readonly
bindmount remount events are not propagated through mount subtrees, so we have to remount the shared dir mountpoint directly. E.g., ``` mkdir -p source dest foo source/foo mount -o bind --make-shared source dest mount -o bind foo source/foo echo bind mount rw mount | grep foo echo remount ro mount -o remount,bind,ro source/foo mount | grep foo ``` would result in: ``` bind mount rw /dev/xvda1 on /home/ubuntu/source/foo type ext4 (rw,relatime,discard,data=ordered) /dev/xvda1 on /home/ubuntu/dest/foo type ext4 (rw,relatime,discard,data=ordered) remount ro /dev/xvda1 on /home/ubuntu/source/foo type ext4 (ro,relatime,discard,data=ordered) /dev/xvda1 on /home/ubuntu/dest/foo type ext4 (rw,relatime,discard,data=ordered) ``` The reason is that bind mount creats new mount structs and attaches them to different mount subtrees. However, MS_REMOUNT only looks for existing mount structs to modify and does not try to propagate the change to mount structs in other subtrees. Fixes: #3041 Signed-off-by: Peng Tao <[email protected]>
1 parent 509eb6f commit 7739905

File tree

4 files changed

+18
-6
lines changed

4 files changed

+18
-6
lines changed

virtcontainers/container.go

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -446,7 +446,7 @@ func (c *Container) setContainerState(state types.StateString) error {
446446
return nil
447447
}
448448

449-
func (c *Container) shareFiles(m Mount, idx int, hostSharedDir, guestSharedDir string) (string, bool, error) {
449+
func (c *Container) shareFiles(m Mount, idx int, hostSharedDir, hostMountDir, guestSharedDir string) (string, bool, error) {
450450
randBytes, err := utils.GenerateRandomBytes(8)
451451
if err != nil {
452452
return "", false, err
@@ -480,12 +480,19 @@ func (c *Container) shareFiles(m Mount, idx int, hostSharedDir, guestSharedDir s
480480
}
481481
} else {
482482
// These mounts are created in the shared dir
483-
mountDest := filepath.Join(hostSharedDir, filename)
483+
mountDest := filepath.Join(hostMountDir, filename)
484484
if err := bindMount(c.ctx, m.Source, mountDest, m.ReadOnly, "private"); err != nil {
485485
return "", false, err
486486
}
487487
// Save HostPath mount value into the mount list of the container.
488488
c.mounts[idx].HostPath = mountDest
489+
// bindmount remount event is not propagated to mount subtrees, so we have to remount the shared dir mountpoint directly.
490+
if m.ReadOnly {
491+
mountDest = filepath.Join(hostSharedDir, filename)
492+
if err := remountRo(c.ctx, mountDest); err != nil {
493+
return "", false, err
494+
}
495+
}
489496
}
490497

491498
return guestDest, false, nil
@@ -496,7 +503,7 @@ func (c *Container) shareFiles(m Mount, idx int, hostSharedDir, guestSharedDir s
496503
// It also updates the container mount list with the HostPath info, and store
497504
// container mounts to the storage. This way, we will have the HostPath info
498505
// available when we will need to unmount those mounts.
499-
func (c *Container) mountSharedDirMounts(hostSharedDir, guestSharedDir string) (sharedDirMounts map[string]Mount, ignoredMounts map[string]Mount, err error) {
506+
func (c *Container) mountSharedDirMounts(hostSharedDir, hostMountDir, guestSharedDir string) (sharedDirMounts map[string]Mount, ignoredMounts map[string]Mount, err error) {
500507
sharedDirMounts = make(map[string]Mount)
501508
ignoredMounts = make(map[string]Mount)
502509
var devicesToDetach []string
@@ -546,7 +553,7 @@ func (c *Container) mountSharedDirMounts(hostSharedDir, guestSharedDir string) (
546553

547554
var ignore bool
548555
var guestDest string
549-
guestDest, ignore, err = c.shareFiles(m, idx, hostSharedDir, guestSharedDir)
556+
guestDest, ignore, err = c.shareFiles(m, idx, hostSharedDir, hostMountDir, guestSharedDir)
550557
if err != nil {
551558
return nil, nil, err
552559
}

virtcontainers/kata_agent.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1419,7 +1419,7 @@ func (k *kataAgent) createContainer(sandbox *Sandbox, c *Container) (p *Process,
14191419
}
14201420

14211421
// Handle container mounts
1422-
newMounts, ignoredMounts, err := c.mountSharedDirMounts(getMountPath(sandbox.id), kataGuestSharedDir())
1422+
newMounts, ignoredMounts, err := c.mountSharedDirMounts(getSharePath(sandbox.id), getMountPath(sandbox.id), kataGuestSharedDir())
14231423
if err != nil {
14241424
return nil, err
14251425
}

virtcontainers/mount.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -273,6 +273,11 @@ func remount(ctx context.Context, mountflags uintptr, src string) error {
273273
return nil
274274
}
275275

276+
// remount a mount point as readonly
277+
func remountRo(ctx context.Context, src string) error {
278+
return remount(ctx, syscall.MS_BIND|syscall.MS_RDONLY, src)
279+
}
280+
276281
// bindMountContainerRootfs bind mounts a container rootfs into a 9pfs shared
277282
// directory between the guest and the host.
278283
func bindMountContainerRootfs(ctx context.Context, shareDir, cid, cRootFs string, readonly bool) error {

virtcontainers/sandbox_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1177,7 +1177,7 @@ func TestPreAddDevice(t *testing.T) {
11771177
},
11781178
}
11791179

1180-
mounts, ignoreMounts, err := container.mountSharedDirMounts("", "")
1180+
mounts, ignoreMounts, err := container.mountSharedDirMounts("", "", "")
11811181
assert.Nil(t, err)
11821182
assert.Equal(t, len(mounts), 0,
11831183
"mounts should contain nothing because it only contains a block device")

0 commit comments

Comments
 (0)