// DeleteL3n4AddrIDBySHA256 deletes the L3n4AddrID that belong to the serviceL4ID' // sha256Sum. func (d *Daemon) DeleteL3n4AddrIDBySHA256(sha256Sum string) error { if sha256Sum == "" { return nil } svcPath := path.Join(common.ServicesKeyPath, sha256Sum) // Lock that sha256Sum lockKey, err := d.kvClient.LockPath(svcPath) if err != nil { return err } defer lockKey.Unlock() // After lock complete, get label's path rmsg, err := d.kvClient.GetValue(svcPath) if err != nil { return err } if rmsg == nil { return nil } var l3n4AddrID types.L3n4AddrID if err := json.Unmarshal(rmsg, &l3n4AddrID); err != nil { return err } oldL3n4ID := l3n4AddrID.ID l3n4AddrID.ID = 0 // update the value in the kvstore if err := d.updateL3n4AddrIDRef(oldL3n4ID, l3n4AddrID); err != nil { return err } return d.kvClient.SetValue(svcPath, l3n4AddrID) }
func (c *ConsulClient) GASNewL3n4AddrID(basePath string, baseID uint32, lAddrID *types.L3n4AddrID) error { setIDtoL3n4Addr := func(lockPair *consulAPI.KVPair) error { defer c.KV().Release(lockPair, nil) lAddrID.ID = types.ServiceID(baseID) keyPath := path.Join(basePath, strconv.FormatUint(uint64(lAddrID.ID), 10)) if err := c.SetValue(keyPath, lAddrID); err != nil { return err } return c.setMaxL3n4AddrID(baseID + 1) } session, _, err := c.Session().CreateNoChecks(nil, nil) if err != nil { return err } beginning := baseID for { log.Debugf("Trying to aquire a new free ID %d", baseID) keyPath := path.Join(basePath, strconv.FormatUint(uint64(baseID), 10)) lockPair := &consulAPI.KVPair{Key: GetLockPath(keyPath), Session: session} acq, _, err := c.KV().Acquire(lockPair, nil) if err != nil { return err } if acq { svcKey, _, err := c.KV().Get(keyPath, nil) if err != nil { c.KV().Release(lockPair, nil) return err } if svcKey == nil { return setIDtoL3n4Addr(lockPair) } var consulL3n4AddrID types.L3n4AddrID if err := json.Unmarshal(svcKey.Value, &consulL3n4AddrID); err != nil { c.KV().Release(lockPair, nil) return err } if consulL3n4AddrID.ID == 0 { log.Infof("Recycling Service ID %d", baseID) return setIDtoL3n4Addr(lockPair) } c.KV().Release(lockPair, nil) } baseID++ if baseID > common.MaxSetOfServiceID { baseID = common.FirstFreeServiceID } if beginning == baseID { return fmt.Errorf("reached maximum set of serviceIDs available.") } } }
// GASNewL3n4AddrID gets the next available ServiceID and sets it in lAddrID. After // assigning the ServiceID to lAddrID it sets the ServiceID + 1 in // common.LastFreeServiceIDKeyPath path. func (e *EtcdClient) GASNewL3n4AddrID(basePath string, baseID uint32, lAddrID *types.L3n4AddrID) error { setIDtoL3n4Addr := func(id uint32) error { lAddrID.ID = types.ServiceID(id) keyPath := path.Join(basePath, strconv.FormatUint(uint64(lAddrID.ID), 10)) if err := e.SetValue(keyPath, lAddrID); err != nil { return err } return e.setMaxL3n4AddrID(id + 1) } acquireFreeID := func(firstID uint32, incID *uint32) error { log.Debugf("Trying to acquire a new free ID %d", *incID) keyPath := path.Join(basePath, strconv.FormatUint(uint64(*incID), 10)) locker, err := e.LockPath(GetLockPath(keyPath)) if err != nil { return err } defer locker.Unlock() value, err := e.GetValue(keyPath) if err != nil { return err } if value == nil { return setIDtoL3n4Addr(*incID) } var consulL3n4AddrID types.L3n4AddrID if err := json.Unmarshal(value, &consulL3n4AddrID); err != nil { return err } if consulL3n4AddrID.ID == 0 { log.Infof("Recycling Service ID %d", *incID) return setIDtoL3n4Addr(*incID) } *incID++ if *incID > common.MaxSetOfServiceID { *incID = common.FirstFreeServiceID } if firstID == *incID { return fmt.Errorf("reached maximum set of serviceIDs available.") } return nil } var err error beginning := baseID for { if err = acquireFreeID(beginning, &baseID); err != nil { return err } else if beginning == baseID { return nil } } }