Repository: google/gvisor
File: runsc/container/container.go (Go)

Code before:
	case config.SelfOverlay:
		mountSrcInfo, err := os.Stat(mountSrc)
		if err != nil {
			return boot.GoferMountConf{}, fmt.Errorf("failed to stat mount %q to see if it were a directory: %v", mountSrc, err)
		}
		if !mountSrcInfo.IsDir() {
			log.Warningf("self filestore is only supported for directory mounts, but mount %q is not a directory, falling back to memory", mountSrc)
			return boot.GoferMountConf{Lower: lower, Upper: boot.MemoryOverlay, UpperSize: overlaySize}, nil
		}
		return boot.GoferMountConf{Lower: lower, Upper: boot.SelfOverlay, UpperSize: overlaySize}, nil
	default:
		if overlayMedium.IsBackedByAnon() {
			return boot.GoferMountConf{Lower: lower, Upper: boot.AnonOverlay, UpperSize: overlaySize}, nil
		}
		return boot.GoferMountConf{}, fmt.Errorf("unexpected overlay medium %q", overlayMedium)
	}
}

// initGoferConfs initializes c.GoferMountConfs with all the gofer configs that
// dictate how each gofer mount should be configured.
func (c *Container) initGoferConfs(ovlConf config.Overlay2, mountHints *boot.PodMountHints, rootfsHint *boot.RootfsHint) error {
	// Handle root mount first.
	overlayMedium := ovlConf.RootOverlayMedium()
	overlaySize := ovlConf.RootOverlaySize()
	mountType := boot.Bind
	if rootfsHint != nil {
		overlayMedium = rootfsHint.Overlay
		if !specutils.IsGoferMount(rootfsHint.Mount) {
			mountType = rootfsHint.Mount.Type
		}
	}
	if c.Spec.Root.Readonly {
		overlayMedium = config.NoOverlay
	}
	goferConf, err := createGoferConf(overlayMedium, overlaySize, mountType, c.Spec.Root.Path)
	if err != nil {
		return err
	}
	c.GoferMountConfs = append(c.GoferMountConfs, goferConf)

	// Handle bind mounts.
	for i := range c.Spec.Mounts {
		if !specutils.IsGoferMount(c.Spec.Mounts[i]) {
			continue
		}
		overlayMedium := ovlConf.SubMountOverlayMedium()
		overlaySize := ovlConf.SubMountOverlaySize()
		mountType = boot.Bind
		if specutils.IsReadonlyMount(c.Spec.Mounts[i].Options) {
			overlayMedium = config.NoOverlay
		}

Review comment (suggestion):
For similar reasons as mentioned below, if rootfs is being configured by the rootfs annotations (rootfsHint != nil), then overlaySize should be reset.

Also, I think we should extend the rootfs annotation to include specifying size: https://github.com/google/gvisor/blob/d19c3bc9bcdf36fc592d634e9337dd4f84bec02d/runsc/boot/mount_hints.go#L230

Maybe `dev.gvisor.spec.rootfs.options` which has value like `size=...`. Later we can extend this to support more tmpfs options if need be.

Code after:
	case config.SelfOverlay:
		mountSrcInfo, err := os.Stat(mountSrc)
		if err != nil {
			return boot.GoferMountConf{}, fmt.Errorf("failed to stat mount %q to see if it were a directory: %v", mountSrc, err)
		}
		if !mountSrcInfo.IsDir() {
			log.Warningf("self filestore is only supported for directory mounts, but mount %q is not a directory, falling back to memory", mountSrc)
			return boot.GoferMountConf{Lower: lower, Upper: boot.MemoryOverlay, Size: overlaySize}, nil
		}
		return boot.GoferMountConf{Lower: lower, Upper: boot.SelfOverlay, Size: overlaySize}, nil
	default:
		if overlayMedium.IsBackedByAnon() {
			return boot.GoferMountConf{Lower: lower, Upper: boot.AnonOverlay, Size: overlaySize}, nil
		}
		return boot.GoferMountConf{}, fmt.Errorf("unexpected overlay medium %q", overlayMedium)
	}
}

// initGoferConfs initializes c.GoferMountConfs with all the gofer configs that
// dictate how each gofer mount should be configured.
func (c *Container) initGoferConfs(ovlConf config.Overlay2, mountHints *boot.PodMountHints, rootfsHint *boot.RootfsHint) error {
	// Handle root mount first.
	overlayMedium := ovlConf.RootOverlayMedium()
	overlaySize := ovlConf.RootOverlaySize()
	mountType := boot.Bind
	if rootfsHint != nil {
		overlayMedium = rootfsHint.Overlay
		if !specutils.IsGoferMount(rootfsHint.Mount) {
			mountType = rootfsHint.Mount.Type
		}
		overlaySize = rootfsHint.Size
	}
	if c.Spec.Root.Readonly {
		overlayMedium = config.NoOverlay
	}
	goferConf, err := createGoferConf(overlayMedium, overlaySize, mountType, c.Spec.Root.Path)
	if err != nil {
		return err
	}
	c.GoferMountConfs = append(c.GoferMountConfs, goferConf)

	// Handle bind mounts.
	for i := range c.Spec.Mounts {
		if !specutils.IsGoferMount(c.Spec.Mounts[i]) {
			continue
		}
		overlayMedium := ovlConf.SubMountOverlayMedium()
		overlaySize := ovlConf.SubMountOverlaySize()
		mountType = boot.Bind
		if specutils.IsReadonlyMount(c.Spec.Mounts[i].Options) {
			overlayMedium = config.NoOverlay