Exemple #1
0
    def _check_bond_interface_change(self, phy_interface, attr_obj):
        """Check if there's any change in bond interface.

        First check if the interface passed itself is a bond-interface and then
        retrieve the member list and compare.
        Next, check if the interface passed is a part of the bond interface and
        then retrieve the member list and compare.
        """
        bond_phy = sys_utils.get_bond_intf(phy_interface)
        if sys_utils.is_intf_bond(phy_interface):
            bond_intf = phy_interface
        else:
            bond_intf = bond_phy
        # This can be an addition or removal of the interface to a bond.
        bond_intf_change = attr_obj.cmp_update_bond_intf(bond_intf)
        return bond_intf_change
Exemple #2
0
    def uplink_bond_intf_process(self):
        """Process the case when uplink interface becomes part of a bond.

        This is called to check if the phy interface became a part of the
        bond. If the below condition is True, this means, a physical
        interface that was not a part of a bond was earlier discovered as
        uplink and now that interface became part of the bond.
        Usually, this doesn't happen as LLDP and in turn this function will
        first detect a 'down' followed by an 'up'. When regular interface
        becomes part of bond, it's rare for it to hit this 'normal' case.
        But, still providing the functionality if it happens.
        The following is done :
        a. Bring down the physical interface by sending a 'down' event
        b. Add the bond interface by sending an 'up' event
        Consquently, when bond is added that will be assigned to
        self.phy_uplink. Then, the below condition will be False. i.e..
        'get_bond_intf' will return False, when the argument is 'bond0'.
        """
        bond_intf = sys_utils.get_bond_intf(self.phy_uplink)
        if bond_intf is None:
            return False
        self.save_uplink(
            fail_reason=constants.port_transition_bond_down_reason)
        self.process_uplink_ongoing = True
        upl_msg = VdpQueMsg(constants.UPLINK_MSG_TYPE, status='down',
                            phy_uplink=self.phy_uplink,
                            br_int=self.br_integ, br_ex=self.br_ex,
                            root_helper=self.root_helper)
        self.que.enqueue(constants.Q_UPL_PRIO, upl_msg)
        self.phy_uplink = None
        self.veth_intf = None
        self.uplink_det_compl = False

        # No veth interface
        self.save_uplink(
            uplink=bond_intf,
            fail_reason=constants.port_transition_bond_up_reason)
        self.phy_uplink = bond_intf
        self.process_uplink_ongoing = True
        upl_msg = VdpQueMsg(constants.UPLINK_MSG_TYPE, status='up',
                            phy_uplink=self.phy_uplink,
                            br_int=self.br_integ, br_ex=self.br_ex,
                            root_helper=self.root_helper)
        self.que.enqueue(constants.Q_UPL_PRIO, upl_msg)
        return True
Exemple #3
0
    def vdp_uplink_proc(self):
        """Periodic handler to detect the uplink interface to the switch.

        -> restart_uplink_called: should be called by agent initially to set
        the stored uplink and veth from DB
        -> process_uplink_ongoing: Will be set when uplink message is enqueue
        and reset when dequeued and processed completely
        -> uplink_det_compl: Will be set to True when a valid uplink is
        detected and object created. Will be reset when uplink is down
        -> phy_uplink: Is the uplink interface
        -> veth_intf : Signifies the veth interface.
        """
        LOG.info("In Periodic Uplink Task")
        if not self.is_os_run:
            if not self.is_openstack_running():
                LOG.info("OpenStack is not running")
                return
            else:
                self.is_os_run = True
        if not self.restart_uplink_called or self.process_uplink_ongoing:
            LOG.info("Uplink before restart not refreshed yet..states "
                     "%(ruc)d %(puo)d",
                     {'ruc': self.restart_uplink_called,
                      'puo': self.process_uplink_ongoing})
            return
        if self.phy_uplink is not None:
            if (self.uplink_det_compl and (
               self.phy_uplink not in self.ovs_vdp_obj_dict)):
                LOG.error("Not Initialized for phy %s", self.phy_uplink)
                return
            if self.phy_uplink in self.ovs_vdp_obj_dict:
                self.veth_intf = (self.ovs_vdp_obj_dict[self.phy_uplink].
                                  get_lldp_local_bridge_port())
            # The below logic has a bug when agent is started
            # and openstack is not running fixme(padkrish)
            else:
                if self.veth_intf is None:
                    LOG.error("Incorrect state, Bug")
                    return
        if self.static_uplink:
            ret = self.static_uplink_detect(self.veth_intf)
        else:
            ret = uplink_det.detect_uplink(self.veth_intf)
        if ret is 'down':
            if self.phy_uplink is None:
                LOG.error("Wrong status down")
                return
            # Call API to set the uplink as "" DOWN event
            self.uplink_down_cnt = self.uplink_down_cnt + 1
            if not self.static_uplink and (
               self.uplink_down_cnt < constants.UPLINK_DOWN_THRES):
                return
            self.process_uplink_ongoing = True
            upl_msg = VdpQueMsg(constants.UPLINK_MSG_TYPE,
                                status='down',
                                phy_uplink=self.phy_uplink,
                                br_int=self.br_integ, br_ex=self.br_ex,
                                root_helper=self.root_helper)
            self.que.enqueue(constants.Q_UPL_PRIO, upl_msg)
            self.phy_uplink = None
            self.veth_intf = None
            self.uplink_det_compl = False
            self.uplink_down_cnt = 0
        elif ret is None:
            if self.veth_intf is not None:
                LOG.error("Wrong status None")
                return
            # Call API to set the uplink as "" Uplink not discovered yet
            self.save_uplink(fail_reason=constants.uplink_undiscovered_reason)
        elif ret is 'normal':
            if self.veth_intf is None:
                LOG.error("Wrong status Normal")
                return
            # Uplink already discovered, nothing to be done here
            # Resetting it back, happens when uplink was down for a very short
            # time and no need to remove flows
            self.uplink_down_cnt = 0
            bond_det = self.uplink_bond_intf_process()
            # Revisit this logic.
            # If uplink detection fails, it will be put in Error queue, which
            # will dequeue and put it back in the main queue
            # At the same time this periodic task will also hit this normal
            # state and will put the message in main queue. fixme(padkrish)
            # The below lines are put here because after restart when
            # eth/veth are passed to uplink script, it will return normal
            # But OVS object would not have been created for the first time,
            # so the below lines ensures it's done.
            if not self.uplink_det_compl and not bond_det:
                if self.phy_uplink is None:
                    LOG.error("Incorrect state, bug")
                    return
                self.process_uplink_ongoing = True
                upl_msg = VdpQueMsg(constants.UPLINK_MSG_TYPE,
                                    status='up',
                                    phy_uplink=self.phy_uplink,
                                    br_int=self.br_integ, br_ex=self.br_ex,
                                    root_helper=self.root_helper)
                self.que.enqueue(constants.Q_UPL_PRIO, upl_msg)
                # yield
                LOG.info("Enqueued Uplink Msg from normal")
            self.check_periodic_bulk_vm_notif_rcvd()
        else:
            LOG.info("In Periodic Uplink Task uplink found %s", ret)
            bond_intf = sys_utils.get_bond_intf(ret)
            if bond_intf is not None:
                ret = bond_intf
                LOG.info("Interface %(memb)s part of bond %(bond)s" %
                         {'memb': ret, 'bond': bond_intf})
            # Call API to set the uplink as ret
            self.save_uplink(uplink=ret, veth_intf=self.veth_intf)
            self.phy_uplink = ret
            self.process_uplink_ongoing = True
            upl_msg = VdpQueMsg(constants.UPLINK_MSG_TYPE,
                                status='up',
                                phy_uplink=self.phy_uplink,
                                br_int=self.br_integ, br_ex=self.br_ex,
                                root_helper=self.root_helper)
            self.que.enqueue(constants.Q_UPL_PRIO, upl_msg)
            # yield
            LOG.info("Enqueued Uplink Msg")