diff --git a/internal/controller/nnf_access_controller.go b/internal/controller/nnf_access_controller.go index b7b335b43..b2c4240a0 100644 --- a/internal/controller/nnf_access_controller.go +++ b/internal/controller/nnf_access_controller.go @@ -625,8 +625,24 @@ func (r *NnfAccessReconciler) mapClientLocalStorage(ctx context.Context, access // If no ClientReference exists, then the mounts are for the Rabbit nodes. Use references // to the NnfNodeStorage resource so the client mounter can access the swordfish objects if access.Spec.ClientReference == (corev1.ObjectReference{}) { + // For rabbit mounts, use unique index mount directories that consist of + // -. These unique directories guard against potential data + // loss when doing copy out data movement operations. Having the namespace + // (rabbit name) included in the mount path ensures that these individual + // compute mount points are always unique. + // + // Ex: /mnt/nnf/7b5dda61-9d91-4b50-a0d3-f863d0aac25b-0/rabbit-node-1-0 + // /mnt/nnf/7b5dda61-9d91-4b50-a0d3-f863d0aac25b-0/rabbit-node-2-0 + // If you did not include the namespace, then the paths would be: + // /mnt/nnf/7b5dda61-9d91-4b50-a0d3-f863d0aac25b-0/0 + // /mnt/nnf/7b5dda61-9d91-4b50-a0d3-f863d0aac25b-0/0 + // When data movement copies the MountPathPrefix to global lustre, then the + // contents of these directories are merged together and potential data loss can + // occur if the contents do not have unique filenames. + indexMountDir := fmt.Sprintf("%s-%s", nnfNodeStorage.Namespace, strconv.Itoa(i)) + mountInfo.MountPath = filepath.Join(access.Spec.MountPathPrefix, indexMountDir) + mountInfo.Device.Type = dwsv1alpha2.ClientMountDeviceTypeReference - mountInfo.MountPath = filepath.Join(access.Spec.MountPathPrefix, strconv.Itoa(i)) } else { mountInfo.MountPath = access.Spec.MountPath mountInfo.Device.Type = dwsv1alpha2.ClientMountDeviceTypeLVM