コード例 #1
0
ファイル: health.go プロジェクト: jaminp/beehive-netctrl
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
}
コード例 #2
0
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
}
コード例 #3
0
ファイル: tx.go プロジェクト: jyzhe/beehive
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()
}
コード例 #4
0
ファイル: port.go プロジェクト: dknyxh/beehive-netctrl
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
}
コード例 #5
0
ファイル: nodelink.go プロジェクト: 1995parham/FlyNest
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)
}
コード例 #6
0
ファイル: packetin.go プロジェクト: 1995parham/FlyNest
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
}
コード例 #7
0
ファイル: discovery.go プロジェクト: jaminp/beehive-netctrl
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)
}
コード例 #8
0
ファイル: bee.go プロジェクト: jyzhe/beehive
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
}
コード例 #9
0
ファイル: nodelink.go プロジェクト: 1995parham/FlyNest
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)
}
コード例 #10
0
ファイル: queen.go プロジェクト: kandoo/beehive
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,
		}
	}
}
コード例 #11
0
ファイル: bee.go プロジェクト: jyzhe/beehive
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
}