Code change:
Minimal Repro: Create 2 different disks Create 2 Pods each using one of the disks Start both pods on the same node You will notice one of the disks gets ed to a path: , then both disks are ed from to a target path: which is similar but at least uses the pod . Both of these volumes are being treated as the same volume in the Kubelet even though they are definitely not the same volume. Note: it may not be "treated" as the same volume - it may just be that since the paths are the same the following volumes see that the path is already a mountpoint and skip the step. This is the more likely scenario based on observations. The value is the "name" of the inline-volume. These can obviously be the same across different pods - we should actually be placing it in a more unique directory (based off the translated maybe?). /cc
/sig storage
The inline volume example I'm using (ignore the fact that is a complete misnomer): I've confirmed that changing the "name" makes inline volumes work well since there is no longer a collision on the paths
/assign
Alright, problem is sort of twofold: The referred to above for inline-volumes is set here: As we can see from the comment: it is set to the because the in-tree CSI Plugin makes a lot of naming assumptions based on the which for PVC/PVs is the PV name (unique in a cluster). Primarily, during unmount the CSI Plugin tries to from a "well known ": which happens to be some path based on the which for the inline volume is just the ( above). So we run into the problem that if we use the directory is not sufficiently unique for different disks. And if we use something else like then the unmount pathway is unable to find the . I think using is a no-go. So we need to use something sufficiently unique (like ) for the ( above) and fix up some of the other codepaths to either use different "well-known paths" to write to, or to fix up path generation code so they give us the correct locations. I'm also going to check to see whether 's refactor fixes this issue (because it might since it translates things earlier)
OK. Really good news. your refactor in its current state actually fixes this issue if we set the to something unique here: Looks like the early translation is also making the pathway from the "correct" dir for inline migration. So I will create a PR that fixes this issue that should merge after

Related discussion:
text: } } <ins> func TestTranslateInTreeInlineVolumeToCSINameUniqueness(t *testing.T) { for driverName := range inTreePlugins { t.Run(driverName, func(t *testing.T) { ctl := New() vs1, err := generateUniqueVolumeSource(driverName) if err != nil { t.Fatalf("Couldn't generate random source: %v", err) } pv1, err := ctl.TranslateInTreeInlineVolumeToCSI(&v1.Volume{ VolumeSource: vs1, }) if err != nil { t.Fatalf("Error when translating to CSI: %v", err) } vs2, err := generateUniqueVolumeSource(driverName) if err != nil { t.Fatalf("Couldn't generate random source: %v", err) } pv2, err := ctl.TranslateInTreeInlineVolumeToCSI(&v1.Volume{ VolumeSource: vs2, }) if err != nil { t.Fatalf("Error when translating to CSI: %v", err) } if pv1 == nil || pv2 == nil { t.Fatalf("Did not expect either pv1: %v or pv2: %v to be nil", pv1, pv2) } if pv1.Name == pv2.Name { t.Errorf("PV name %s not sufficiently unique for different volumes", pv1.Name) } }) } } func generateUniqueVolumeSource(driverName string) (v1.VolumeSource, error) { switch driverName { case plugins.GCEPDDriverName: return v1.VolumeSource{ GCEPersistentDisk: &v1.GCEPersistentDiskVolumeSource{ PDName: string(uuid.NewUUID()), }, }, nil case plugins.AWSEBSDriverName: return v1.VolumeSource{ AWSElasticBlockStore: &v1.AWSElasticBlockStoreVolumeSource{ VolumeID: string(uuid.NewUUID()), }, }, nil case plugins.CinderDriverName: return v1.VolumeSource{ Cinder: &v1.CinderVolumeSource{ VolumeID: string(uuid.NewUUID()), }, }, nil case plugins.AzureDiskDriverName: return v1.VolumeSource{ AzureDisk: &v1.AzureDiskVolumeSource{ DiskName:    string(uuid.NewUUID()), DataDiskURI: string(uuid.NewUUID()), }, }, nil case plugins.AzureFileDriverName: return v1.VolumeSource{ AzureFile: &v1.AzureFileVolumeSource{ SecretName: string(uuid.NewUUID()), ShareName:  string(uuid.NewUUID()), }, }, nil default: return v1.VolumeSource{}, fmt.Errorf("couldn't find logic for driver: %v", driverName) } } </ins> func TestPluginNameMappings(t *testing.T) { testCases := []struct { name             string