Uploaded image for project: 'Red Hat OpenShift Control Planes'
  1. Red Hat OpenShift Control Planes
  2. CNTRLPLANE-2842

Context cancel function accumulates in loop in imagemetadata.go getMirrorFromICSPOrIDMS

XMLWordPrintable

    • Icon: Bug Bug
    • Resolution: Unresolved
    • Icon: Normal Normal
    • None
    • openshift-4.22
    • HyperShift
    • None
    • False
    • Hide

      None

      Show
      None
    • None
    • None
    • None
    • None
    • None
    • None
    • None
    • None

      Description (en formato Wiki markup para Jira):

      Description of problem

      In support/util/imagemetadata.go, the function getMirrorFromICSPOrIDMS calls context.WithTimeout inside a for loop (line 545) and uses defer cancel() to release the context. However, defer

      only executes when the enclosing function returns, not at the end of each loop iteration. This means that for every mirror iterated, a new context is created but never cancelled until the function exits, causing

      context accumulation and potential resource leaks proportional to the number of mirrors configured.

      Version-Release number of selected component (if applicable)

      4.20, 4.21 (present in main branch as well)

      How reproducible

      Always

      Steps to Reproduce

      1. Configure multiple ImageContentSourcePolicies (ICSP) or ImageDigestMirrorSets (IDMS) with several mirror entries
      2. Trigger image metadata resolution that calls getMirrorFromICSPOrIDMS
      3. Observe that each loop iteration creates a new context via context.WithTimeout but defers the cancel

      Actual results

      The cancel() function is deferred inside the loop, so it accumulates for each mirror entry. All cancel functions are only called when the outer function returns, leading to unnecessary context and resource accumulation.

       

        // Cache miss - verify mirror availability with 15s timeout
        verifyCtx, cancel := context.WithTimeout(ctx, 15*time.Second)
        defer cancel()  // BUG: this accumulates, not called until function returns
      
        if _, _, _, err = getMetadata(verifyCtx, mirrorURL, pullSecret); err == nil {
        

      Expected results

      The cancel() function should be called immediately after the getMetadata call, or the code should be wrapped in an inline function so that defer cancel() runs at each iteration.

      Additional info

      Found by @csrwng during review of backport PR:

              jparrill@redhat.com Juan Manuel Parrilla Madrid
              jparrill@redhat.com Juan Manuel Parrilla Madrid
              Votes:
              0 Vote for this issue
              Watchers:
              1 Start watching this issue

                Created:
                Updated: