func (h HealthChecker) Rcv(msg bh.Msg, ctx bh.RcvContext) error { db := msg.From() dict := ctx.Dict(driversDict) dict.ForEach(func(k string, v interface{}) { nd := v.(nodeDrivers) updated := false for i := range nd.Drivers { if nd.Drivers[i].BeeID == db { nd.Drivers[i].LastSeen = time.Now() // TODO(soheil): Maybe if outpings was more than MaxPings we // should emit a connected message. nd.Drivers[i].OutPings-- updated = true } } if !updated { return } if err := dict.Put(k, nd); err != nil { glog.Warningf("error in encoding drivers: %v", err) } }) return nil }
func (p Poller) Rcv(msg bh.Msg, ctx bh.RcvContext) error { dict := ctx.Dict(driversDict) dict.ForEach(func(k string, v interface{}) { node := nom.UID(k) query := nom.FlowStatsQuery{ Node: node, } sendToMaster(query, node, ctx) nd := v.(nodeDrivers) for i := range nd.Drivers { // TODO(soheil): remove the hardcoded value. if nd.Drivers[i].OutPings > MaxPings { ctx.SendToBee(nom.NodeDisconnected{ Node: nom.Node{ID: nom.NodeID(node)}, Driver: nd.Drivers[i].Driver, }, ctx.ID()) continue } ctx.SendToBee(nom.Ping{}, nd.Drivers[i].BeeID) nd.Drivers[i].OutPings++ } if err := dict.Put(k, nd); err != nil { glog.Warningf("error in encoding drivers: %v", err) } }) return nil }
func (t *Transactional) Save() ([]byte, error) { if t.status == TxOpen { glog.Warningf("transactional has an open tx when the snapshot is taken") } return t.State.Save() }
func (h portStatusHandler) Rcv(msg bh.Msg, ctx bh.RcvContext) error { // FIXME(soheil): This implementation is very naive and cannot tolerate // faults. We need to first check if the driver is the mater, and then apply // the change. Otherwise, we need to enque this message for that driver and // make sure we apply the log to the port status data := msg.Data().(nom.PortStatusChanged) dict := ctx.Dict(driversDict) k := string(data.Port.Node) v, err := dict.Get(k) if err != nil { return fmt.Errorf("NOMController: node %v not found", data.Port.Node) } n := v.(nodeDrivers) if !n.isMaster(data.Driver) { glog.Warningf("NOMController: %v ignored, %v is not master, master is %v", data.Port, data.Driver, n.master()) return nil } if p, ok := n.Ports.GetPort(data.Port.UID()); ok { if p == data.Port { return fmt.Errorf("NOMController: duplicate port status change for %v", data.Port) } n.Ports.DelPort(p) } n.Ports.AddPort(data.Port) ctx.Emit(nom.PortUpdated(data.Port)) return nil }
func (h *portUpdateHandler) Rcv(msg bh.Msg, ctx bh.RcvContext) error { p := nom.Port(msg.Data().(nom.PortUpdated)) d := ctx.Dict(nodeDict) k := string(p.Node) v, err := d.Get(k) if err != nil { glog.Warningf("%v added before its node", p) ctx.Snooze(1 * time.Second) return nil } np := v.(nodePortsAndLinks) if np.hasPort(p) { glog.Warningf("%v readded") np.removePort(p) } sendLLDPPacket(np.N, p, ctx) np.P = append(np.P, p) return d.Put(k, np) }
func (of *of12Driver) handlePacketIn(in of12.PacketIn, c *ofConn) error { m := in.Match() if m.Type() == uint16(of12.PMT_STANDARD) { glog.Warningf("standard matches are not supported") return nil } var inPort uint32 hasInPort := false xm, _ := of12.ToOXMatch(in.Match()) for _, f := range xm.Fields() { if of12.IsOxmInPort(f) { xp, _ := of12.ToOxmInPort(f) inPort = xp.InPort() hasInPort = true } } if !hasInPort { glog.V(2).Infof("packet in does not have an input port") return nil } // Ignore packet-ins on switch specific ports. if inPort > uint32(of12.PP_MAX) { glog.V(2).Infof("ignoring packet-in on %v", inPort) return nil } port, ok := of.ofPorts[inPort] if !ok { return fmt.Errorf("of12Driver: port not found %v", inPort) } if glog.V(2) { glog.Infof("packet received: %v", in) } nomIn := nom.PacketIn{ Node: c.node.UID(), InPort: port.UID(), BufferID: nom.PacketBufferID(in.BufferId()), } nomIn.Packet = nom.Packet(in.Data()) c.ctx.Emit(nomIn) return nil }
func (h *nodeJoinedHandler) Rcv(msg bh.Msg, ctx bh.RcvContext) error { joined := msg.Data().(nom.NodeJoined) d := ctx.Dict(nodeDict) n := nom.Node(joined) k := string(n.UID()) var np nodePortsAndLinks if v, err := d.Get(k); err != nil { glog.Warningf("%v rejoins", n) } else { np = v.(nodePortsAndLinks) } np.N = n // TODO(soheil): Add a flow entry to forward lldp packets to the controller. return d.Put(k, np) }
func (b *bee) maybeRecruitFollowers() error { if b.detached { return nil } c := b.colony() if c.Leader != b.ID() { return ErrIsNotMaster } if n := len(c.Followers) + 1; n < b.app.replFactor { newf := b.doRecruitFollowers() if newf+n < b.app.replFactor { glog.Warningf("%v can replicate only on %v node(s)", b, n) } } return nil }
func (h *nodeJoinedHandler) Rcv(msg bh.Msg, ctx bh.RcvContext) error { joined := msg.Data().(nom.NodeJoined) d := ctx.Dict(nodeDict) n := nom.Node(joined) k := string(n.UID()) var np nodePortsAndLinks if v, err := d.Get(k); err != nil { glog.Warningf("%v rejoins", n) } else { np = v.(nodePortsAndLinks) } np.N = n // Add a flow entry to forward arp packets to the controller mt := nom.Match{} mt.AddField(nom.EthType(nom.EthTypeARP)) acs := []nom.Action{ nom.ActionSendToController{ MaxLen: 0xffff, }, } fe := nom.FlowEntry{ ID: "Discovery-Host-ARP", Node: n.UID(), Priority: 0, Match: mt, Actions: acs, } afe := nom.AddFlowEntry{ Flow: fe, Subscriber: bh.AppCellKey{ App: ctx.App(), Key: k, Dict: nodeDict, }, } ctx.Emit(afe) // Add a flow entry to forward lldp packets to the controller mt = nom.Match{} mt.AddField(nom.EthType(nom.EthTypeLLDP)) acs = []nom.Action{ nom.ActionSendToController{ MaxLen: 0xffff, }, } fe = nom.FlowEntry{ ID: "Discovery-Topo-LLDP", Node: n.UID(), Priority: 0, Match: mt, Actions: acs, } afe = nom.AddFlowEntry{ Flow: fe, Subscriber: bh.AppCellKey{ App: ctx.App(), Key: k, Dict: nodeDict, }, } ctx.Emit(afe) return d.Put(k, np) }
func (q *qee) handleCmd(cc cmdAndChannel) { if cc.cmd.Bee != Nil { if b, ok := q.beeByID(cc.cmd.Bee); ok { b.enqueCmd(cc) return } // If the bee is a proxy we should try to relay the message. if info, err := q.hive.registry.bee(cc.cmd.Bee); err == nil && !q.isLocalBee(info) { b, err := q.newProxyBee(info) if err == nil { b.enqueCmd(cc) return } glog.Warningf("%v cannot create proxy to %#v: %v", q, info, err) } if cc.ch != nil { cc.ch <- cmdResult{ Err: fmt.Errorf("%v cannot find bee %v", q, cc.cmd.Bee), } } return } glog.V(2).Infof("%v handles command %#v", q, cc.cmd.Data) var err error var res interface{} switch cmd := cc.cmd.Data.(type) { case cmdStop: q.stopped = true glog.V(3).Infof("stopping bees of %p", q) q.stopBees() case cmdFindBee: id := cmd.ID r, ok := q.beeByID(id) if !ok { err = fmt.Errorf("%v cannot find bee %v", q, id) break } res = r case cmdCreateBee: var b *bee b, err = q.newLocalBee(false) if err != nil { break } res = b.ID() glog.V(2).Infof("created a new local bee %v", b) case cmdReloadBee: _, err = q.reloadBee(cmd.ID, cmd.Colony) case cmdStartDetached: var b *bee b, err = q.newDetachedBee(cmd.Handler) if b != nil { res = b.ID() } case cmdMigrate: res, err = q.migrate(cmd.Bee, cmd.To) default: err = fmt.Errorf("unknown queen bee command %#v", cmd) } if err != nil { glog.Errorf("%v cannot handle %v: %v", q, cc.cmd, err) } if cc.ch != nil { cc.ch <- cmdResult{ Err: err, Data: res, } } }
func (b *bee) doRecruitFollowers() (recruited int) { c := b.colony() r := b.app.replFactor - len(c.Followers) if r == 1 { return 0 } blacklist := []uint64{b.hive.ID()} for _, f := range c.Followers { fb, err := b.hive.registry.bee(f) if err != nil { glog.Fatalf("%v cannot find the hive of follower %v: %v", b, f, err) } blacklist = append(blacklist, fb.Hive) } for r != 1 { hives := b.hive.replStrategy.selectHives(blacklist, r-1) if len(hives) == 0 { glog.Warningf("can only find %v hives to create followers for %v", len(c.Followers), b) break } fch := make(chan BeeInfo) tries := r - 1 if len(hives) < tries { tries = len(hives) } for i := 0; i < tries; i++ { blacklist = append(blacklist, hives[i]) go func(i int) { glog.V(2).Infof("trying to create a new follower for %v on hive %v", b, hives[0]) cmd := cmd{ Hive: hives[i], App: b.app.Name(), Data: cmdCreateBee{}, } res, err := b.hive.client.sendCmd(cmd) if err != nil { glog.Errorf("%v cannot create a new bee on %v: %v", b, hives[0], err) fch <- BeeInfo{} return } fch <- BeeInfo{ ID: res.(uint64), Hive: hives[i], } }(i) } for i := 0; i < tries; i++ { finf := <-fch if finf.ID == 0 { continue } if err := b.addFollower(finf.ID, finf.Hive); err != nil { glog.Errorf("%v cannot add %v as a follower: %v", b, finf.ID, err) continue } recruited++ r-- } } glog.V(2).Infof("%v recruited %d followers", b, recruited) return recruited }