github-vet / github-vet/rangeloop-pointer-findings
kubernetes-sigs/multi-tenancy: incubator/virtualcluster/pkg/syncer/resources/pod/checker.go; 89 LoC
- Dominant language
- No language data
- Stars
- 0
- Forks
- 0
- PR merge metrics
- PR metrics pending
Description
Found a possible issue in [kubernetes-sigs/multi-tenancy](https://www.github.com/kubernetes-sigs/multi-tenancy) at [incubator/virtualcluster/pkg/syncer/resources/pod/checker.go](https://github.com/kubernetes-sigs/multi-tenancy/blob/8a26b45b876480638d18fa44328143b19e95e2c7/incubator/virtualcluster/pkg/syncer/resources/pod/checker.go#L245-L333)
Below is the message reported by the analyzer for this snippet of code. Beware that the analyzer only reports the first issue it finds, so please do not limit your consideration to the contents of the below message.
> function call which takes a reference to vPod at line 261 may start a goroutine
[Click here to see the code in its original context.](https://github.com/kubernetes-sigs/multi-tenancy/blob/8a26b45b876480638d18fa44328143b19e95e2c7/incubator/virtualcluster/pkg/syncer/resources/pod/checker.go#L245-L333)
Click here to show the 89 line(s) of Go which triggered the analyzer.
```go
for i, vPod := range podList.Items {
if vPod.Spec.NodeName != "" && !isPodScheduled(&vPod) {
// We should skip pods with NodeName set in the spec
continue
}
// Ensure the ClusterVNodePodMap is consistent
if vPod.Spec.NodeName != "" && !c.checkClusterVNodePodMap(clusterName, vPod.Spec.NodeName, string(vPod.UID)) {
klog.Errorf("Found vPod %s/%s in cluster %s is missing in ClusterVNodePodMap, added back!", vPod.Namespace, vPod.Name, clusterName)
c.updateClusterVNodePodMap(clusterName, vPod.Spec.NodeName, string(vPod.UID), reconciler.UpdateEvent)
}
targetNamespace := conversion.ToSuperMasterNamespace(clusterName, vPod.Namespace)
pPod, err := c.podLister.Pods(targetNamespace).Get(vPod.Name)
if errors.IsNotFound(err) {
// pPod not found and vPod is under deletion, we need to delete vPod manually
if vPod.DeletionTimestamp != nil {
// since pPod not found in super master, we can force delete vPod
c.forceDeletevPod(clusterName, &vPod, false)
} else {
// pPod not found and vPod still exists, the pPod may be deleted manually or by controller pod eviction.
// If the vPod has not been bound yet, we can create pPod again.
// If the vPod has been bound, we'd better delete the vPod since the new pPod may have a different nodename.
if isPodScheduled(&vPod) {
c.forceDeletevPod(clusterName, &vPod, false)
metrics.CheckerRemedyStats.WithLabelValues("DeletedTenantPodsDueToSuperEviction").Inc()
} else {
if err := c.multiClusterPodController.RequeueObject(clusterName, &podList.Items[i]); err != nil {
klog.Errorf("error requeue vpod %v/%v in cluster %s: %v", vPod.Namespace, vPod.Name, clusterName, err)
} else {
metrics.CheckerRemedyStats.WithLabelValues("RequeuedTenantPods").Inc()
}
}
}
continue
}
if err != nil {
klog.Errorf("error getting pPod %s/%s from super master cache: %v", targetNamespace, vPod.Name, err)
continue
}
if pPod.Annotations[constants.LabelUID] != string(vPod.UID) {
klog.Errorf("Found pPod %s/%s delegated UID is different from tenant object.", targetNamespace, pPod.Name)
continue
}
if pPod.Spec.NodeName != "" && vPod.Spec.NodeName != "" && pPod.Spec.NodeName != vPod.Spec.NodeName {
// If pPod can be deleted arbitrarily, e.g., evicted by node controller, this inconsistency may happen.
// For example, if pPod is deleted just before uws tries to bind the vPod and dws gets a request from checker or
// user update at the same time, a new pPod is going to be created potentially in a different node.
// However, uws bound vPod to a wrong node already. There is no easy remediation besides deleting tenant pod.
c.forceDeletevPod(clusterName, &vPod, true)
klog.Errorf("Found pPod %s/%s nodename is different from tenant pod nodename, delete the vPod.", targetNamespace, pPod.Name)
metrics.CheckerRemedyStats.WithLabelValues("DeletedTenantPodsDueToNodeMissMatch").Inc()
continue
}
spec, err := c.multiClusterPodController.GetSpec(clusterName)
if err != nil {
klog.Errorf("fail to get cluster spec : %s", clusterName)
continue
}
updatedPod := conversion.Equality(c.config, spec).CheckPodEquality(pPod, &podList.Items[i])
if updatedPod != nil {
atomic.AddUint64(&numSpecMissMatchedPods, 1)
klog.Warningf("spec of pod %v/%v diff in super&tenant master", vPod.Namespace, vPod.Name)
if err := c.multiClusterPodController.RequeueObject(clusterName, &podList.Items[i]); err != nil {
klog.Errorf("error requeue vpod %v/%v in cluster %s: %v", vPod.Namespace, vPod.Name, clusterName, err)
} else {
metrics.CheckerRemedyStats.WithLabelValues("RequeuedTenantPods").Inc()
}
}
updatedPodStatus := conversion.CheckDWPodConditionEquality(pPod, &podList.Items[i])
if updatedPodStatus != nil {
atomic.AddUint64(&numSpecMissMatchedPods, 1)
klog.Warningf("DWStatus of pod %v/%v diff in super&tenant master", vPod.Namespace, vPod.Name)
if err := c.multiClusterPodController.RequeueObject(clusterName, &podList.Items[i]); err != nil {
klog.Errorf("error requeue vpod %v/%v in cluster %s: %v", vPod.Namespace, vPod.Name, clusterName, err)
} else {
metrics.CheckerRemedyStats.WithLabelValues("RequeuedTenantPods").Inc()
}
}
updatedMeta := conversion.Equality(c.config, spec).CheckUWObjectMetaEquality(&pPod.ObjectMeta, &podList.Items[i].ObjectMeta)
if updatedMeta != nil {
atomic.AddUint64(&numUWMetaMissMatchedPods, 1)
klog.Warningf("UWObjectMeta of pod %v/%v diff in super&tenant master", vPod.Namespace, vPod.Name)
if assignedPod(pPod) {
c.enqueuePod(pPod)
}
}
}
```
Click here to show extra information the analyzer produced.
```
The following graphviz dot graph describes paths through the callgraph that could lead to a function calling a goroutine:
digraph G {
"(parse, 1)" -> {"(append, 1)";}
"(Run, 1)" -> {"(Run, 2)";"(Deliver, 3)";}
"(DialURL, 3)" -> {"(Dial, 3)";}
"(Set, 1)" -> {"(New, 1)";"(Count, 2)";"(Add, 1)";}
"(get, 4)" -> {"(New, 1)";}
"(globalReferrersPkgLevel, 3)" -> {}
"(didChange, 2)" -> {}
"(addConnIfNeeded, 3)" -> {}
"(NewClientConn, 3)" -> {"(clientHandshake, 2)";}
"(ConnectWithRedirects, 6)" -> {"(Dial, 1)";}
"(New, 1)" -> {"(get, 1)";"(Run, 2)";"(enableCSM, 3)";"(parse, 1)";"(Start, 1)";"(Run, 1)";}
"(Do, 1)" -> {"(Decode, 1)";"(Put, 1)";"(transformResponse, 2)";}
"(WriteTo, 1)" -> {"(Write, 1)";}
"(SetTransportDefaults, 1)" -> {"(ConfigureTransport, 1)";}
"(DidOpen, 2)" -> {"(didOpen, 2)";}
"(get, 1)" -> {"(SetTransportDefaults, 1)";"(Run, 1)";}
"(Start, 3)" -> {}
"(configureTransport, 1)" -> {"(addConnIfNeeded, 3)";}
"(check, 1)" -> {}
"(receive, 4)" -> {"(newMessageIterator, 3)";}
"(RoundTrip, 1)" -> {"(roundTrip, 1)";"(RoundTripOpt, 2)";"(Dial, 1)";"(ConnectWithRedirects, 6)";}
"(RoundTripOpt, 2)" -> {"(roundTrip, 1)";}
"(ForEachPackage, 2)" -> {"(allPackages, 3)";}
"(Decode, 1)" -> {"(New, 1)";"(Count, 2)";}
"(run, 3)" -> {}
"(awaitOpenSlotForRequest, 1)" -> {}
"(forceDeletevPod, 3)" -> {"(Delete, 3)";}
"(Decode, 2)" -> {"(f, 2)";}
"(Receive, 2)" -> {"(receive, 4)";}
"(Add, 1)" -> {"(New, 1)";"(Start, 1)";}
"(roundTrip, 1)" -> {"(awaitOpenSlotForRequest, 1)";}
"(dialWithoutProxy, 2)" -> {"(Dial, 3)";}
"(Delete, 3)" -> {"(Delete, 1)";"(Get, 3)";"(Encode, 2)";"(Do, 1)";"(Delete, 2)";}
"(Put, 1)" -> {"(Put, 2)";}
"(Transform, 3)" -> {"(check, 1)";}
"(implements, 1)" -> {"(Build, 1)";}
"(allPackages, 3)" -> {}
"(dial, 1)" -> {"(dialWithoutProxy, 2)";}
"(Get, 1)" -> {"(get, 1)";}
"(startSyncer, 4)" -> {}
"(append, 1)" -> {}
"(Rename, 2)" -> {"(check, 1)";}
"(newMessageIterator, 3)" -> {}
"(Do, 2)" -> {}
"(Run, 2)" -> {"(startSyncer, 4)";"(run, 3)";"(implements, 1)";"(referrers, 1)";}
"(Delete, 2)" -> {"(Add, 1)";}
"(referrers, 1)" -> {"(globalReferrersPkgLevel, 3)";}
"(Deliver, 3)" -> {"(DidOpen, 2)";"(DidChange, 2)";}
"(Get, 2)" -> {"(handle, 2)";"(Decode, 2)";"(Run, 1)";}
"(enableCSM, 3)" -> {"(Start, 2)";}
"(Write, 1)" -> {"(Rename, 2)";"(append, 1)";"(Transform, 3)";}
"(Put, 2)" -> {"(handle, 2)";}
"(Count, 2)" -> {"(Run, 2)";}
"(Start, 2)" -> {"(Receive, 2)";}
"(DidChange, 2)" -> {"(didChange, 2)";}
"(clientHandshake, 2)" -> {"(newClientTransport, 6)";}
"(f, 2)" -> {}
"(Encode, 2)" -> {"(Write, 1)";"(WriteTo, 1)";}
"(dial, 2)" -> {"(DialURL, 3)";}
"(Build, 1)" -> {"(ForEachPackage, 2)";}
"(didOpen, 2)" -> {}
"(Dial, 1)" -> {"(dial, 1)";"(dial, 2)";}
"(newClientTransport, 6)" -> {}
"(transformResponse, 2)" -> {"(Get, 1)";}
"(Request, 3)" -> {"(New, 1)";"(Get, 1)";}
"(Delete, 1)" -> {"(Do, 2)";}
"(ConfigureTransport, 1)" -> {"(configureTransport, 1)";}
"(Start, 1)" -> {"(Start, 3)";"(Run, 1)";}
"(Dial, 3)" -> {"(NewClientConn, 3)";}
"(Get, 3)" -> {"(Decode, 2)";"(Request, 3)";"(Set, 1)";"(get, 4)";"(Add, 1)";"(New, 1)";"(Get, 2)";"(RoundTrip, 1)";"(Put, 1)";}
"(handle, 2)" -> {}
}
```
Leave a reaction on this issue to contribute to the project by classifying this instance as a **Bug** :-1:, **Mitigated** :+1:, or **Desirable Behavior** :rocket:
See the descriptions of the classifications [here](https://github.com/github-vet/rangeclosure-findings#how-can-i-help) for more information.
commit ID: 8a26b45b876480638d18fa44328143b19e95e2c7
Contributor guide
No contributing guide indexed for this repository
Assessment
This issue has not been assessed yet.