func TestDevmapperMountLeaks(t *testing.T) {
	if !kernel.CheckKernelVersion(3, 18, 0) {
		t.Skipf("kernel version <3.18.0 and so is missing torvalds/linux@8ed936b5671bfb33d89bc60bdcc7cf0470ba52fe.")
	}
	driver := graphtest.GetDriver(t, "devicemapper", "test=1", "dm.use_deferred_removal=false", "dm.use_deferred_deletion=false").(*graphtest.Driver).Driver.(*graphdriver.NaiveDiffDriver).ProtoDriver.(*Driver)
	defer graphtest.PutDriver(t)
	if err := driver.Create("some-layer", "", nil); err != nil {
		t.Fatalf("setting up some-layer: %v", err)
	}
	_, err := driver.Get("some-layer", graphdriver.MountOpts{})
	if err != nil {
		t.Fatalf("mounting some-layer: %v", err)
	}
	cmd := exec.Cmd{
		Path: "/bin/sh",
		Args: []string{
			"/bin/sh", "-c",
			"mount --make-rprivate / && sleep 1000s",
		},
		SysProcAttr: &syscall.SysProcAttr{
			Unshareflags: syscall.CLONE_NEWNS,
		},
	}
	if err := cmd.Start(); err != nil {
		t.Fatalf("starting sub-command: %v", err)
	}
	defer func() {
		unix.Kill(cmd.Process.Pid, unix.SIGKILL)
		cmd.Wait()
	}()
	if err := driver.Put("some-layer"); err != nil {
		t.Fatalf("unmounting some-layer: %v", err)
	}
}
Ensure that mounts aren't leakedriver. It's non-trivial for us to test the full
reproducer of #34573 in a unit test, but we can at least make sure that a
simple command run in a new namespace doesn't break things horribly.
package devmapper
import (
	"fmt"
	"os"
	"os/exec"
	"syscall"
	"testing"
	"time"
	graphdriver "github.com/containers/storage/drivers"
	"github.com/containers/storage/drivers/graphtest"
	"github.com/containers/storage/pkg/parsers/kernel"
	"golang.org/x/sys/unix"
)
func init() {
	defaultDataLoopbackSize = 300 * 1024 * 1024
	defaultMetaDataLoopbackSize = 200 * 1024 * 1024
	defaultBaseFsSize = 300 * 1024 * 1024
	defaultUdevSyncOverride = true
	if err := initLoopbacks(); err != nil {
		panic(err)
	}
}
func initLoopbacks() error {
	statT, err := getBaseLoopStats()
	if err != nil {
		return err
	}
	for i := 0; i < 128; i++ {
		loopPath := fmt.Sprintf("/dev/loop%d", i)
		if _, err := os.Stat(loopPath); err != nil {
			if mkerr := syscall.Mknod(loopPath,
				uint32(statT.Mode|syscall.S_IFBLK), int((7<<8)|(i&0xff)|((i&0xfff00)<<12))); mkerr != nil {
				return mkerr
			}
			os.Chown(loopPath, int(statT.Uid), int(statT.Gid))
		}
	}
	return nil
}
func getBaseLoopStats() (*syscall.Stat_t, error) {
	loop0, err := os.Stat("/dev/loop0")
	if err != nil {
		if os.IsNotExist(err) {
			return &syscall.Stat_t{
				Uid:  0,
				Gid:  0,
				Mode: 0660,
			}, nil
		}
		return nil, err
	}
	return loop0.Sys().(*syscall.Stat_t), nil
}
func TestDevmapperSetup(t *testing.T) {
	graphtest.GetDriver(t, "devicemapper", "test=1")
}
func TestDevmapperCreateEmpty(t *testing.T) {
	graphtest.DriverTestCreateEmpty(t, "devicemapper", "test=1")
}
func TestDevmapperCreateBase(t *testing.T) {
	graphtest.DriverTestCreateBase(t, "devicemapper", "test=1")
}
func TestDevmapperCreateSnap(t *testing.T) {
	graphtest.DriverTestCreateSnap(t, "devicemapper", "test=1")
}
func TestDevmapperCreateFromTemplate(t *testing.T) {
	graphtest.DriverTestCreateFromTemplate(t, "devicemapper", "test=1")
}
func TestDevmapperTeardown(t *testing.T) {
	graphtest.PutDriver(t)
}
func TestDevmapperEcho(t *testing.T) {
	graphtest.DriverTestEcho(t, "devicemapper", "test=1")
}
func TestDevmapperReduceLoopBackSize(t *testing.T) {
	tenMB := int64(10 * 1024 * 1024)
	testChangeLoopBackSize(t, -tenMB, defaultDataLoopbackSize, defaultMetaDataLoopbackSize)
}
func TestDevmapperIncreaseLoopBackSize(t *testing.T) {
	tenMB := int64(10 * 1024 * 1024)
	testChangeLoopBackSize(t, tenMB, defaultDataLoopbackSize+tenMB, defaultMetaDataLoopbackSize+tenMB)
}
func testChangeLoopBackSize(t *testing.T, delta, expectDataSize, expectMetaDataSize int64) {
	driver := graphtest.GetDriver(t, "devicemapper", "test=1").(*graphtest.Driver).Driver.(*graphdriver.NaiveDiffDriver).ProtoDriver.(*Driver)
	defer graphtest.PutDriver(t)
	if s := driver.DeviceSet.Status(); s.Data.Total != uint64(defaultDataLoopbackSize) || s.Metadata.Total != uint64(defaultMetaDataLoopbackSize) {
		t.Fatal("data or metadata loop back size is incorrect")
	}
	if err := driver.Cleanup(); err != nil {
		t.Fatal(err)
	}
	d, err := Init(driver.home, graphdriver.Options{DriverOptions: []string{
		fmt.Sprintf("dm.loopdatasize=%d", defaultDataLoopbackSize+delta),
		fmt.Sprintf("dm.loopmetadatasize=%d", defaultMetaDataLoopbackSize+delta),
		"test=1",
	}})
	if err != nil {
		t.Fatalf("error creating devicemapper driver: %v", err)
	}
	driver = d.(*graphdriver.NaiveDiffDriver).ProtoDriver.(*Driver)
	if s := driver.DeviceSet.Status(); s.Data.Total != uint64(expectDataSize) || s.Metadata.Total != uint64(expectMetaDataSize) {
		t.Fatal("data or metadata loop back size is incorrect")
	}
	if err := driver.Cleanup(); err != nil {
		t.Fatal(err)
	}
}
func TestDevmapperLockReleasedDeviceDeletion(t *testing.T) {
	driver := graphtest.GetDriver(t, "devicemapper", "test=1").(*graphtest.Driver).Driver.(*graphdriver.NaiveDiffDriver).ProtoDriver.(*Driver)
	defer graphtest.PutDriver(t)
	driver.DeviceSet.cleanupDeletedDevices()
	doneChan := make(chan bool)
	go func() {
		driver.DeviceSet.Lock()
		defer driver.DeviceSet.Unlock()
		doneChan <- true
	}()
	select {
	case <-time.After(time.Second * 5):
		driver.DeviceSet.Unlock()
		t.Fatal("Could not acquire devices lock after call to cleanupDeletedDevices()")
	case <-doneChan:
	}
}