Ejemplo n.º 1
0
    def task_worker(self, stopping_event, sfp_error_event, y_cable_presence):
        helper_logger.log_info("Start Ycable monitoring loop")

        # Connect to STATE_DB and listen to ycable transceiver status update tables
        state_db, status_tbl = {}, {}
        port_dict = {}

        sel = swsscommon.Select()

        # Get the namespaces in the platform
        namespaces = multi_asic.get_front_end_namespaces()
        for namespace in namespaces:
            asic_id = multi_asic.get_asic_index_from_namespace(namespace)
            state_db[asic_id] = daemon_base.db_connect("STATE_DB", namespace)
            status_tbl[asic_id] = swsscommon.SubscriberStateTable(
                state_db[asic_id], TRANSCEIVER_STATUS_TABLE)
            sel.addSelectable(status_tbl[asic_id])

        while True:

            if self.task_stopping_event.is_set():
                break

            (state, selectableObj) = sel.select(SELECT_TIMEOUT)

            if state == swsscommon.Select.TIMEOUT:
                # Do not flood log when select times out
                continue
            if state != swsscommon.Select.OBJECT:
                helper_logger.log_warning(
                    "sel.select() did not  return swsscommon.Select.OBJECT for sonic_y_cable updates"
                )
                continue

            # Get the redisselect object  from selectable object
            redisSelectObj = swsscommon.CastSelectableToRedisSelectObj(
                selectableObj)
            # Get the corresponding namespace from redisselect db connector object
            namespace = redisSelectObj.getDbConnector().getNamespace()
            asic_index = multi_asic.get_asic_index_from_namespace(namespace)

            while True:
                (port, op, fvp) = status_tbl[asic_index].pop()
                if not port:
                    break

                if fvp:
                    fvp_dict = dict(fvp)

                if not fvp_dict:
                    continue

                port_dict[port] = fvp_dict.get('status', None)

                y_cable_helper.change_ports_status_for_y_cable_change_event(
                    port_dict, y_cable_presence, stopping_event)
Ejemplo n.º 2
0
def update_and_get_response_for_xcvr_cmd(cmd_name,
                                         rsp_name,
                                         exp_rsp,
                                         cmd_table_name,
                                         rsp_table_name,
                                         port,
                                         cmd_timeout_secs,
                                         arg=None):

    res_dict = {}
    state_db, appl_db = {}, {}
    firmware_rsp_tbl, firmware_rsp_tbl_keys = {}, {}
    firmware_rsp_sub_tbl = {}
    firmware_cmd_tbl = {}

    CMD_TIMEOUT_SECS = cmd_timeout_secs

    time_start = time.time()

    sel = swsscommon.Select()
    namespaces = multi_asic.get_front_end_namespaces()
    for namespace in namespaces:
        asic_id = multi_asic.get_asic_index_from_namespace(namespace)
        state_db[asic_id] = db_connect("STATE_DB", namespace)
        appl_db[asic_id] = db_connect("APPL_DB", namespace)
        firmware_cmd_tbl[asic_id] = swsscommon.Table(appl_db[asic_id],
                                                     cmd_table_name)
        firmware_rsp_sub_tbl[asic_id] = swsscommon.SubscriberStateTable(
            state_db[asic_id], rsp_table_name)
        firmware_rsp_tbl[asic_id] = swsscommon.Table(state_db[asic_id],
                                                     rsp_table_name)
        firmware_rsp_tbl_keys[asic_id] = firmware_rsp_tbl[asic_id].getKeys()
        for key in firmware_rsp_tbl_keys[asic_id]:
            firmware_rsp_tbl[asic_id]._del(key)
        sel.addSelectable(firmware_rsp_sub_tbl[asic_id])

    rc = CONFIG_FAIL
    res_dict[0] = CONFIG_FAIL
    res_dict[1] = 'unknown'

    logical_port_list = platform_sfputil_helper.get_logical_list()
    if port not in logical_port_list:
        click.echo("ERR: This is not a valid port, valid ports ({})".format(
            ", ".join(logical_port_list)))
        res_dict[0] = rc
        return res_dict

    asic_index = None
    if platform_sfputil is not None:
        asic_index = platform_sfputil_helper.get_asic_id_for_logical_port(port)
    if asic_index is None:
        # TODO this import is only for unit test purposes, and should be removed once sonic_platform_base
        # is fully mocked
        import sonic_platform_base.sonic_sfp.sfputilhelper
        asic_index = sonic_platform_base.sonic_sfp.sfputilhelper.SfpUtilHelper(
        ).get_asic_id_for_logical_port(port)
        if asic_index is None:
            click.echo(
                "Got invalid asic index for port {}, cant perform firmware cmd"
                .format(port))
            res_dict[0] = rc
            return res_dict

    if arg is None:
        cmd_arg = "null"
    else:
        cmd_arg = str(arg)

    fvs = swsscommon.FieldValuePairs([(cmd_name, cmd_arg)])
    firmware_cmd_tbl[asic_index].set(port, fvs)

    # Listen indefinitely for changes to the HW_MUX_CABLE_TABLE in the Application DB's
    while True:
        # Use timeout to prevent ignoring the signals we want to handle
        # in signal_handler() (e.g. SIGTERM for graceful shutdown)

        (state, selectableObj) = sel.select(SELECT_TIMEOUT)

        time_now = time.time()
        time_diff = time_now - time_start
        if time_diff >= CMD_TIMEOUT_SECS:
            return res_dict

        if state == swsscommon.Select.TIMEOUT:
            # Do not flood log when select times out
            continue
        if state != swsscommon.Select.OBJECT:
            click.echo(
                "sel.select() did not  return swsscommon.Select.OBJECT for sonic_y_cable updates"
            )
            continue

        # Get the redisselect object  from selectable object
        redisSelectObj = swsscommon.CastSelectableToRedisSelectObj(
            selectableObj)
        # Get the corresponding namespace from redisselect db connector object
        namespace = redisSelectObj.getDbConnector().getNamespace()
        asic_index = multi_asic.get_asic_index_from_namespace(namespace)

        (port_m, op_m, fvp_m) = firmware_rsp_sub_tbl[asic_index].pop()

        if not port_m:
            click.echo("Did not receive a port response {}".format(port))
            res_dict[1] = 'unknown'
            res_dict[0] = CONFIG_FAIL
            firmware_rsp_tbl[asic_index]._del(port)
            break

        if port_m != port:

            res_dict[1] = 'unknown'
            res_dict[0] = CONFIG_FAIL
            firmware_rsp_tbl[asic_index]._del(port)
            continue

        if fvp_m:

            fvp_dict = dict(fvp_m)
            if rsp_name in fvp_dict:
                # check if xcvrd got a probe command
                result = fvp_dict[rsp_name]

                if result == exp_rsp:
                    res_dict[1] = result
                    res_dict[0] = 0
                else:
                    res_dict[1] = result
                    res_dict[0] = CONFIG_FAIL

                firmware_rsp_tbl[asic_index]._del(port)
                break
            else:
                res_dict[1] = 'unknown'
                res_dict[0] = CONFIG_FAIL
                firmware_rsp_tbl[asic_index]._del(port)
                break
        else:
            res_dict[1] = 'unknown'
            res_dict[0] = CONFIG_FAIL
            firmware_rsp_tbl[asic_index]._del(port)
            break

    delete_all_keys_in_db_table("STATE_DB", rsp_table_name)

    return res_dict
Ejemplo n.º 3
0
    def task_worker(self):

        # Connect to STATE_DB and APPL_DB and get both the HW_MUX_STATUS_TABLE info
        appl_db, state_db, status_tbl, y_cable_tbl = {}, {}, {}, {}
        y_cable_tbl_keys = {}
        mux_cable_command_tbl = {}

        sel = swsscommon.Select()

        # Get the namespaces in the platform
        namespaces = multi_asic.get_front_end_namespaces()
        for namespace in namespaces:
            # Open a handle to the Application database, in all namespaces
            asic_id = multi_asic.get_asic_index_from_namespace(namespace)
            appl_db[asic_id] = daemon_base.db_connect("APPL_DB", namespace)
            status_tbl[asic_id] = swsscommon.SubscriberStateTable(
                appl_db[asic_id], swsscommon.APP_HW_MUX_CABLE_TABLE_NAME)
            mux_cable_command_tbl[asic_id] = swsscommon.SubscriberStateTable(
                appl_db[asic_id], swsscommon.APP_MUX_CABLE_COMMAND_TABLE_NAME)
            state_db[asic_id] = daemon_base.db_connect("STATE_DB", namespace)
            y_cable_tbl[asic_id] = swsscommon.Table(
                state_db[asic_id], swsscommon.STATE_HW_MUX_CABLE_TABLE_NAME)
            y_cable_tbl_keys[asic_id] = y_cable_tbl[asic_id].getKeys()
            sel.addSelectable(status_tbl[asic_id])
            sel.addSelectable(mux_cable_command_tbl[asic_id])

        # Listen indefinitely for changes to the HW_MUX_CABLE_TABLE in the Application DB's
        while True:
            # Use timeout to prevent ignoring the signals we want to handle
            # in signal_handler() (e.g. SIGTERM for graceful shutdown)
            (state, selectableObj) = sel.select(SELECT_TIMEOUT)

            if state == swsscommon.Select.TIMEOUT:
                # Do not flood log when select times out
                continue
            if state != swsscommon.Select.OBJECT:
                helper_logger.log_warning(
                    "sel.select() did not  return swsscommon.Select.OBJECT for sonic_y_cable updates"
                )
                continue

            # Get the redisselect object  from selectable object
            redisSelectObj = swsscommon.CastSelectableToRedisSelectObj(
                selectableObj)
            # Get the corresponding namespace from redisselect db connector object
            namespace = redisSelectObj.getDbConnector().getNamespace()
            asic_index = multi_asic.get_asic_index_from_namespace(namespace)

            (port, op, fvp) = status_tbl[asic_index].pop()
            if fvp:
                # This check might be redundant, to check, the presence of this Port in keys
                # in logical_port_list but keep for now for coherency
                # also skip checking in logical_port_list inside sfp_util
                if port not in y_cable_tbl_keys[asic_index]:
                    continue

                fvp_dict = dict(fvp)

                if "status" in fvp_dict:
                    # got a status change
                    new_status = fvp_dict["status"]
                    (status, fvs) = y_cable_tbl[asic_index].get(port)
                    if status is False:
                        helper_logger.log_warning(
                            "Could not retreive fieldvalue pairs for {}, inside state_db table {}"
                            .format(port, y_cable_tbl[asic_index]))
                        continue
                    mux_port_dict = dict(fvs)
                    old_status = mux_port_dict.get("status")
                    read_side = mux_port_dict.get("read_side")
                    prev_active_side = mux_port_dict.get("active_side")
                    # Now if the old_status does not match new_status toggle the mux appropriately
                    if old_status != new_status:
                        active_side = update_tor_active_side(
                            read_side, new_status, port)
                        fvs_updated = swsscommon.FieldValuePairs([
                            ('status', new_status), ('read_side', read_side),
                            ('active_side', str(active_side))
                        ])
                        y_cable_tbl[asic_index].set(port, fvs_updated)
                        # nothing to do since no status change
                    else:
                        helper_logger.log_warning(
                            "Got a change event on that does not toggle the TOR active side for port  {} status {} active linked side = {} "
                            .format(port, old_status, prev_active_side))
                else:
                    helper_logger.log_info(
                        "Got a change event on port {} of table {} that does not contain status "
                        .format(port, swsscommon.APP_HW_MUX_CABLE_TABLE_NAME))

            (port_m, op_m, fvp_m) = mux_cable_command_tbl[asic_index].pop()
            if fvp_m:

                fvp_dict = dict(fvp_m)

                if "command" in fvp_dict:
                    #check if xcvrd got a probe command
                    probe_identifier = fvp_dict["command"]

                    if probe_identifier == "probe":
                        update_appdb_port_mux_cable_response_table(
                            port_m, asic_index, appl_db)
Ejemplo n.º 4
0
def get_single_port_firmware_version(port, res_dict, mux_info_dict):

    state_db, appl_db = {}, {}
    xcvrd_show_fw_rsp_sts_tbl_keys = {}
    xcvrd_show_fw_rsp_sts_tbl = {}
    xcvrd_show_fw_rsp_tbl = {}
    xcvrd_show_fw_cmd_tbl, xcvrd_show_fw_res_tbl = {}, {}

    sel = swsscommon.Select()
    namespaces = multi_asic.get_front_end_namespaces()
    for namespace in namespaces:
        asic_id = multi_asic.get_asic_index_from_namespace(namespace)
        state_db[asic_id] = db_connect("STATE_DB", namespace)
        appl_db[asic_id] = db_connect("APPL_DB", namespace)
        xcvrd_show_fw_cmd_tbl[asic_id] = swsscommon.Table(appl_db[asic_id], "XCVRD_SHOW_FW_CMD")
        xcvrd_show_fw_rsp_tbl[asic_id] = swsscommon.SubscriberStateTable(state_db[asic_id], "XCVRD_SHOW_FW_RSP")
        xcvrd_show_fw_rsp_sts_tbl[asic_id] = swsscommon.Table(state_db[asic_id], "XCVRD_SHOW_FW_RSP")
        xcvrd_show_fw_res_tbl[asic_id] = swsscommon.Table(state_db[asic_id], "XCVRD_SHOW_FW_RES")
        xcvrd_show_fw_rsp_sts_tbl_keys[asic_id] = xcvrd_show_fw_rsp_sts_tbl[asic_id].getKeys()
        for key in xcvrd_show_fw_rsp_sts_tbl_keys[asic_id]:
            xcvrd_show_fw_rsp_sts_tbl[asic_id]._del(key)
        sel.addSelectable(xcvrd_show_fw_rsp_tbl[asic_id])

    rc = 0
    res_dict[0] = 'unknown'

    logical_port_list = platform_sfputil_helper.get_logical_list()
    if port not in logical_port_list:
        click.echo("ERR: This is not a valid port, valid ports ({})".format(", ".join(logical_port_list)))
        rc = EXIT_FAIL
        res_dict[1] = rc
        return

    asic_index = None
    if platform_sfputil is not None:
        asic_index = platform_sfputil_helper.get_asic_id_for_logical_port(port)
    if asic_index is None:
        # TODO this import is only for unit test purposes, and should be removed once sonic_platform_base
        # is fully mocked
        import sonic_platform_base.sonic_sfp.sfputilhelper
        asic_index = sonic_platform_base.sonic_sfp.sfputilhelper.SfpUtilHelper().get_asic_id_for_logical_port(port)
        if asic_index is None:
            click.echo("Got invalid asic index for port {}, cant retreive mux status".format(port))
            rc = CONFIG_FAIL
            res_dict[1] = rc
            return

    fvs = swsscommon.FieldValuePairs([('firmware_version', 'probe')])
    xcvrd_show_fw_cmd_tbl[asic_index].set(port, fvs)

    # Listen indefinitely for changes to the HW_MUX_CABLE_TABLE in the Application DB's
    while True:
        # Use timeout to prevent ignoring the signals we want to handle
        # in signal_handler() (e.g. SIGTERM for graceful shutdown)

        (state, selectableObj) = sel.select(SELECT_TIMEOUT)

        if state == swsscommon.Select.TIMEOUT:
            # Do not flood log when select times out
            continue
        if state != swsscommon.Select.OBJECT:
            click.echo("sel.select() did not  return swsscommon.Select.OBJECT for sonic_y_cable updates")
            continue

        # Get the redisselect object  from selectable object
        redisSelectObj = swsscommon.CastSelectableToRedisSelectObj(
            selectableObj)
        # Get the corresponding namespace from redisselect db connector object
        namespace = redisSelectObj.getDbConnector().getNamespace()
        asic_index = multi_asic.get_asic_index_from_namespace(namespace)

        (port_m, op_m, fvp_m) = xcvrd_show_fw_rsp_tbl[asic_index].pop()

        if not port_m:
            click.echo("Did not receive a port response {}".format(port))
            res_dict[0] = 'False'
            res_dict[1] = EXIT_FAIL
            xcvrd_show_fw_rsp_sts_tbl[asic_index]._del(port)
            break

        if port_m != port:

            res_dict[0] = 'False'
            res_dict[1] = EXIT_FAIL
            xcvrd_show_fw_rsp_sts_tbl[asic_index]._del(port)
            continue

        if fvp_m:

            fvp_dict = dict(fvp_m)
            if "status" in fvp_dict:
                # check if xcvrd got a probe command
                state = fvp_dict["status"]

                res_dict[0] = state
                res_dict[1] = EXIT_FAIL
                xcvrd_show_fw_rsp_sts_tbl[asic_index]._del(port)
                (status, fvp) = xcvrd_show_fw_res_tbl[asic_index].get(port)
                res_dir = dict(fvp)
                mux_info_dict["version_nic_active"] = res_dir.get("version_nic_active", None)
                mux_info_dict["version_nic_inactive"] = res_dir.get("version_nic_inactive", None)
                mux_info_dict["version_nic_next"] = res_dir.get("version_nic_next", None)
                mux_info_dict["version_peer_active"] = res_dir.get("version_peer_active", None)
                mux_info_dict["version_peer_inactive"] = res_dir.get("version_peer_inactive", None)
                mux_info_dict["version_peer_next"] = res_dir.get("version_peer_next", None)
                mux_info_dict["version_self_active"] = res_dir.get("version_self_active", None)
                mux_info_dict["version_self_inactive"] = res_dir.get("version_self_inactive", None)
                mux_info_dict["version_self_next"] = res_dir.get("version_self_next", None)
                break
            else:
                res_dict[0] = 'False'
                res_dict[1] = EXIT_FAIL
                xcvrd_show_fw_rsp_sts_tbl[asic_index]._del(port)
                break
        else:
            res_dict[0] = 'False'
            res_dict[1] = EXIT_FAIL
            xcvrd_show_fw_rsp_sts_tbl[asic_index]._del(port)
            break


    delete_all_keys_in_db_table("STATE_DB", "XCVRD_SHOW_FW_RSP")
    delete_all_keys_in_db_table("STATE_DB", "XCVRD_SHOW_FW_RES")

    return
    def task_worker(self):

        # Connect to STATE_DB and create transceiver dom info table
        app_db, state_db, status_tbl,y_cable_tbl = {}, {}, {},{}
        y_cable_tbl_keys = {}

        # Get the namespaces in the platform
        sel = swsscommon.Select()

        #logical_port_list = platform_sfputil.logical
        namespaces = multi_asic.get_front_end_namespaces()
        for namespace in namespaces:
            # Open a handle to the Application database, in all namespaces
            asic_id = multi_asic.get_asic_index_from_namespace(namespace)
            app_db[asic_id] = daemon_base.db_connect("APPL_DB", namespace)
            status_tbl[asic_id] = swsscommon.SubscriberStateTable(appl_db[asic_id], swsscommon.APP_HW_MUX_CABLE_TABLE_NAME)
            state_db[asic_id] = daemon_base.db_connect("STATE_DB", namespace)
            y_cable_tbl[asic_id] = swsscommon.Table(state_db[asic_id], swsscommon.STATE_HW_MUX_CABLE_TABLE_NAME)
            sel.addSelectable(status_tbl[asic_id])


        # Listen indefinitely for changes to the APP_MUX_CABLE_TABLE in the Application DB's
        while True:
            # Use timeout to prevent ignoring the signals we want to handle
            # in signal_handler() (e.g. SIGTERM for graceful shutdown)
            (state, selectableObj) = sel.select(SELECT_TIMEOUT)

            if state == swsscommon.Select.TIMEOUT:
                # Do not flood log when select times out
                continue
            if state != swsscommon.Select.OBJECT:
                self.log_warning("sel.select() did not  return swsscommon.Select.OBJECT")
                continue

            # Get the redisselect object  from selectable object
            redisSelectObj = swsscommon.CastSelectableToRedisSelectObj(selectableObj)
            # Get the corresponding namespace from redisselect db connector object
            namespace = redisSelectObj.getDbConnector().getNamespace()
            asic_index = multi_asic.get_asic_index_from_namespace(namespace)
            y_cable_tbl_keys[asic_id] = state_db[asic_index].get_keys(swsscommon.STATE_HW_MUX_CABLE_TABLE_NAME)

            (port, op, fvp) = status_tbl[asic_id].pop()
            if fvp:
                #Might need to check the presence of this Port
                #in logical_port_list but keep for now for coherency
                if port not in y_cable_table_keys[asic_id]:
                    continue

                fvp_dict = dict(fvp)

                if op == "status" in fvp_dict:
                    #got a status change
                    new_status = fvp_dict["status"]
                    (status, fvs) = y_cable_tbl[asic_index].get(port)
                    if status is False:
                        logger.log_warning("Could not retreive fieldvalue pairs for {}, inside config_db".format(logical_port_name))
                        continue
                    mux_port_dict = dict(fvs)
                    old_status = mux_port_dict.get("status") 
                    read_side = mux_port_dict.get("read_side")
                    active_side = mux_port_dict.get("active_side")
                    if old_status != new_staus:
                        update_tor_active_side(read_side, new_status, port)
                        fvs_updated = swsscommon.FieldValuePairs([('status', new_status),
                                                          ('read_side', read_side),
                                                      ('active_side',active_side)])
                        mux_config_tbl.set(logical_port_name, fvs_updated)
                        #nothing to do since no status change
                    else:
                        logger.log_warning("Got a change event on _MUX_TABLE that does not update the current status".format(logical_port_name))