diff --git a/internal/layers/layers.go b/internal/layers/layers.go index fb5429bcc0..dcdce43617 100644 --- a/internal/layers/layers.go +++ b/internal/layers/layers.go @@ -154,7 +154,16 @@ func MountContainerLayers(ctx context.Context, layerFolders []string, guestRoot if err != nil { return "", fmt.Errorf("failed to add SCSI scratch VHD: %s", err) } - containerScratchPathInUVM = scsiMount.UVMPath + + // This handles the case where we want to share a scratch disk for multiple containers instead + // of mounting a new one. Pass a unique value for `ScratchPath` to avoid container upper and + // work directories colliding in the UVM. + if scsiMount.RefCount() > 1 && uvm.OS() == "linux" { + scratchFmt := fmt.Sprintf("container_%s", filepath.Base(containerScratchPathInUVM)) + containerScratchPathInUVM = ospath.Join("linux", scsiMount.UVMPath, scratchFmt) + } else { + containerScratchPathInUVM = scsiMount.UVMPath + } defer func() { if err != nil { diff --git a/internal/uvm/scsi.go b/internal/uvm/scsi.go index 119c9a1088..4444066e21 100644 --- a/internal/uvm/scsi.go +++ b/internal/uvm/scsi.go @@ -69,6 +69,11 @@ type SCSIMount struct { refCount uint32 } +// RefCount returns the current refcount for the SCSI mount. +func (sm *SCSIMount) RefCount() uint32 { + return sm.refCount +} + func (sm *SCSIMount) logFormat() logrus.Fields { return logrus.Fields{ "HostPath": sm.HostPath, diff --git a/test/cri-containerd/container_virtual_device_test.go b/test/cri-containerd/container_virtual_device_test.go index b3c7ae4f3b..747da4d4c3 100644 --- a/test/cri-containerd/container_virtual_device_test.go +++ b/test/cri-containerd/container_virtual_device_test.go @@ -209,7 +209,7 @@ func Test_RunContainer_VirtualDevice_GPU_LCOW(t *testing.T) { t.Fatalf("skipping test, failed to find assignable nvidia gpu on host with: %v", err) } if testDeviceInstanceID == "" { - t.Fatalf("skipping test, host has no assignable nvidia gpu devices") + t.Fatal("skipping test, host has no assignable nvidia gpu devices") } pullRequiredLcowImages(t, []string{imageLcowK8sPause, imageLcowAlpine}) @@ -250,7 +250,7 @@ func Test_RunContainer_VirtualDevice_GPU_Multiple_LCOW(t *testing.T) { t.Fatalf("skipping test, failed to find assignable nvidia gpu on host with: %v", err) } if testDeviceInstanceID == "" { - t.Fatalf("skipping test, host has no assignable nvidia gpu devices") + t.Fatal("skipping test, host has no assignable nvidia gpu devices") } pullRequiredLcowImages(t, []string{imageLcowK8sPause, imageLcowAlpine}) @@ -295,10 +295,10 @@ func Test_RunContainer_VirtualDevice_GPU_and_NoGPU_LCOW(t *testing.T) { testDeviceInstanceID, err := findTestNvidiaGPUDevice() if err != nil { - t.Skipf("skipping test, failed to find assignable nvidia gpu on host with: %v", err) + t.Fatalf("skipping test, failed to find assignable nvidia gpu on host with: %v", err) } if testDeviceInstanceID == "" { - t.Skipf("skipping test, host has no assignable nvidia gpu devices") + t.Fatal("skipping test, host has no assignable nvidia gpu devices") } pullRequiredLcowImages(t, []string{imageLcowK8sPause, imageLcowAlpine}) @@ -364,10 +364,10 @@ func Test_RunContainer_VirtualDevice_GPU_Multiple_Removal_LCOW(t *testing.T) { testDeviceInstanceID, err := findTestNvidiaGPUDevice() if err != nil { - t.Skipf("skipping test, failed to find assignable nvidia gpu on host with: %v", err) + t.Fatalf("skipping test, failed to find assignable nvidia gpu on host with: %v", err) } if testDeviceInstanceID == "" { - t.Skipf("skipping test, host has no assignable nvidia gpu devices") + t.Fatal("skipping test, host has no assignable nvidia gpu devices") } pullRequiredLcowImages(t, []string{imageLcowK8sPause, imageLcowAlpine}) @@ -413,7 +413,7 @@ func Test_RunContainer_VirtualDevice_LocationPath_WCOW_Process(t *testing.T) { t.Fatalf("skipping test, failed to retrieve assignable device on host with: %v", err) } if testDeviceLocationPath == "" { - t.Fatalf("skipping test, host has no assignable devices") + t.Fatal("skipping test, host has no assignable devices") } pullRequiredImages(t, []string{imageWindowsNanoserver}) @@ -451,7 +451,7 @@ func Test_RunContainer_VirtualDevice_ClassGUID_WCOW_Process(t *testing.T) { t.Fatalf("skipping test, failed to retrieve assignable device on host with: %v", err) } if instanceID == "" { - t.Fatalf("skipping test, host has no assignable devices") + t.Fatal("skipping test, host has no assignable devices") } // use fixed GPU class guid @@ -495,7 +495,7 @@ func Test_RunContainer_VirtualDevice_GPU_WCOW_Hypervisor(t *testing.T) { t.Fatalf("skipping test, failed to retrieve assignable device on host with: %v", err) } if testDeviceInstanceID == "" { - t.Fatalf("skipping test, host has no assignable devices") + t.Fatal("skipping test, host has no assignable devices") } pullRequiredImages(t, []string{imageWindowsNanoserver}) @@ -540,7 +540,7 @@ func Test_RunContainer_VirtualDevice_GPU_and_NoGPU_WCOW_Hypervisor(t *testing.T) t.Fatalf("skipping test, failed to retrieve assignable device on host with: %v", err) } if testDeviceInstanceID == "" { - t.Fatalf("skipping test, host has no assignable devices") + t.Fatal("skipping test, host has no assignable devices") } pullRequiredImages(t, []string{imageWindowsNanoserver}) @@ -602,7 +602,7 @@ func Test_RunContainer_VirtualDevice_GPU_Multiple_WCOW_Hypervisor(t *testing.T) t.Fatalf("skipping test, failed to retrieve assignable device on host with: %v", err) } if testDeviceInstanceID == "" { - t.Fatalf("skipping test, host has no assignable devices") + t.Fatal("skipping test, host has no assignable devices") } pullRequiredImages(t, []string{imageWindowsNanoserver}) @@ -654,7 +654,7 @@ func Test_RunContainer_VirtualDevice_GPU_Multiple_Removal_WCOW_Hypervisor(t *tes t.Fatalf("skipping test, failed to retrieve assignable device on host with: %v", err) } if testDeviceInstanceID == "" { - t.Fatalf("skipping test, host has no assignable devices") + t.Fatal("skipping test, host has no assignable devices") } pullRequiredImages(t, []string{imageWindowsNanoserver})