@@ -3650,19 +3650,73 @@ func (o *TridentOrchestrator) unpublishVolume(ctx context.Context, volumeName, n
36503650 }
36513651
36523652 // Build list of nodes to which the volume remains published.
3653+ // For read-only clones, we need to also consider publications of the source volume
3654+ // since they share the same export policy.
36533655 nodeMap := make (map [string ]* models.Node )
3654- for _ , pub := range o .listVolumePublicationsForVolumeAndSubordinates (ctx , volume .Config .Name ) {
36553656
3656- // Exclude the publication we are unpublishing.
3657- if pub .VolumeName == volumeName && pub .NodeName == nodeName {
3658- continue
3657+ // Collect all volume names whose publications should be considered
3658+ volumeNamesToCheck := []string {volume .Config .Name }
3659+ unpublishVolumeName := volumeName
3660+
3661+ // If this is a read-only clone, also check the source volume's publications
3662+ sourceVolumeName := ""
3663+ if volume .Config .ReadOnlyClone && volume .Config .CloneSourceVolume != "" {
3664+ sourceVolumeName = volume .Config .CloneSourceVolume
3665+ // Verify the source volume still exists before checking its publications
3666+ if _ , found := o .volumes [sourceVolumeName ]; found {
3667+ volumeNamesToCheck = append (volumeNamesToCheck , sourceVolumeName )
3668+ Logc (ctx ).WithFields (LogFields {
3669+ "clone" : unpublishVolumeName ,
3670+ "source" : sourceVolumeName ,
3671+ }).Debug ("Read-only clone detected; checking source volume publications too." )
3672+ } else {
3673+ Logc (ctx ).WithFields (LogFields {
3674+ "clone" : unpublishVolumeName ,
3675+ "source" : sourceVolumeName ,
3676+ }).Warn ("Source volume for read-only clone not found; may have been deleted." )
36593677 }
3678+ }
36603679
3661- if n := o .nodes .Get (pub .NodeName ); n == nil {
3662- Logc (ctx ).WithField ("node" , pub .NodeName ).Warning ("Node not found during volume unpublish." )
3680+ // Single loop to find:
3681+ // 1. Sibling read-only clones (if this is a clone) - other clones of the same source
3682+ // 2. Child read-only clones (if this is a source) - clones that have this volume as their source
3683+ for volName , vol := range o .volumes {
3684+ if ! vol .Config .ReadOnlyClone || volName == unpublishVolumeName {
36633685 continue
3664- } else {
3665- nodeMap [pub .NodeName ] = n
3686+ }
3687+
3688+ // Check if this is a sibling clone (same source as the volume being unpublished)
3689+ if sourceVolumeName != "" && vol .Config .CloneSourceVolume == sourceVolumeName {
3690+ volumeNamesToCheck = append (volumeNamesToCheck , volName )
3691+ Logc (ctx ).WithFields (LogFields {
3692+ "clone" : unpublishVolumeName ,
3693+ "sibling" : volName ,
3694+ "source" : sourceVolumeName ,
3695+ }).Debug ("Found sibling read-only clone; checking its publications too." )
3696+ } else if vol .Config .CloneSourceVolume == unpublishVolumeName {
3697+ // Check if the volume being unpublished is the source of a clone
3698+ volumeNamesToCheck = append (volumeNamesToCheck , volName )
3699+ Logc (ctx ).WithFields (LogFields {
3700+ "source" : unpublishVolumeName ,
3701+ "clone" : volName ,
3702+ }).Debug ("Found read-only clone of this volume; checking its publications too." )
3703+ }
3704+ }
3705+
3706+ // Collect publications from all related volumes
3707+ for _ , volName := range volumeNamesToCheck {
3708+ for _ , pub := range o .listVolumePublicationsForVolumeAndSubordinates (ctx , volName ) {
3709+ // Exclude the publication we are unpublishing.
3710+ if pub .VolumeName == unpublishVolumeName && pub .NodeName == nodeName {
3711+ continue
3712+ }
3713+
3714+ if n := o .nodes .Get (pub .NodeName ); n == nil {
3715+ Logc (ctx ).WithField ("node" , pub .NodeName ).Warning ("Node not found during volume unpublish." )
3716+ continue
3717+ } else {
3718+ nodeMap [pub .NodeName ] = n
3719+ }
36663720 }
36673721 }
36683722
0 commit comments