func()

in pkg/ipamd/datastore/data_store.go [327:402]


func (ds *DataStore) ReadBackingStore(isv6Enabled bool) error {
	var data CheckpointData

	// Read from checkpoint file
	ds.log.Infof("Begin ipam state recovery from backing store")

	if err := ds.backingStore.Restore(&data); err != nil {
		// Assume that no file == no containers are currently in use, e.g. a fresh reboot just cleared everything out.
		// This is ok, and no-op.
		if os.IsNotExist(err) {
			ds.log.Debugf("backing store doesn't exists, assuming bootstrap on a new node")
			return nil
		}
		return errors.Wrap(err, "failed ipam state recovery from backing store")
	}
	if data.Version != CheckpointFormatVersion {
		return errors.Errorf("failed ipam state recovery due to unexpected checkpointVersion: %v/%v", data.Version, CheckpointFormatVersion)
	}
	if normalizedData, err := ds.normalizeCheckpointDataByPodVethExistence(data); err != nil {
		return errors.Wrap(err, "failed normalize checkpoint data with veth check")
	} else {
		data = normalizedData
	}

	ds.lock.Lock()
	defer ds.lock.Unlock()

	for _, allocation := range data.Allocations {
		ipv4Addr := net.ParseIP(allocation.IPv4)
		ipv6Addr := net.ParseIP(allocation.IPv6)
		var ipAddr net.IP
		found := false
	eniloop:
		for _, eni := range ds.eniPool {
			eniCidrs := eni.AvailableIPv4Cidrs
			ipAddr = ipv4Addr
			if isv6Enabled {
				ds.log.Debugf("v6 is enabled")
				eniCidrs = eni.IPv6Cidrs
				ipAddr = ipv6Addr
			}
			for _, cidr := range eniCidrs {
				ds.log.Debugf("Checking if IP: %v belongs to CIDR: %v", ipAddr, cidr.Cidr)
				if cidr.Cidr.Contains(ipAddr) {
					// Found!
					found = true
					if _, ok := cidr.IPAddresses[ipAddr.String()]; ok {
						return errors.New(IPAlreadyInStoreError)
					}
					addr := &AddressInfo{Address: ipAddr.String()}
					cidr.IPAddresses[ipAddr.String()] = addr
					ds.assignPodIPAddressUnsafe(addr, allocation.IPAMKey, allocation.Metadata, time.Unix(0, allocation.AllocationTimestamp))
					ds.log.Debugf("Recovered %s => %s/%s", allocation.IPAMKey, eni.ID, addr.Address)
					// Increment ENI IP usage upon finding assigned ips
					prometheusmetrics.EniIPsInUse.WithLabelValues(eni.ID).Inc()
					// Update prometheus for ips per cidr
					// Secondary IP mode will have /32:1 and Prefix mode will have /28:<number of /32s>
					prometheusmetrics.IpsPerCidr.With(prometheus.Labels{"cidr": cidr.Cidr.String()}).Inc()
					break eniloop
				}
			}
		}
		if !found {
			ds.log.Infof("datastore: Sandbox %s uses unknown IP Address %s - presuming stale/dead",
				allocation.IPAMKey, ipAddr.String())
		}
	}

	// Some entries may have been purged during recovery, so write to backing store
	if err := ds.writeBackingStoreUnsafe(); err != nil {
		ds.log.Warnf("Unable to update backing store after restoration: %v", err)
	}

	ds.log.Debugf("Completed ipam state recovery")
	return nil
}