From a66941a6cec22416a09ff72f313962caab73f4db Mon Sep 17 00:00:00 2001 From: Stepan Blyshchak <38952541+stepanblyschak@users.noreply.github.com> Date: Mon, 15 Aug 2022 23:35:34 +0300 Subject: [PATCH 001/151] [syncd.sh] 'sxdkernel start' => 'sxdkernel restart' (#11718) Change `sxdkernel start` to `sxdkernel restart`. If `syncd` service crashes in `ExecStartPre` systemd will not call `ExecStop` and thus will not call `sxdkernel stop`. Use of `sxdkernel restart` is more robust in terms of guarantees to restore the system after unexpected crashes. Signed-off-by: Stepan Blyschak Signed-off-by: Stepan Blyschak --- files/scripts/syncd.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/files/scripts/syncd.sh b/files/scripts/syncd.sh index 10535a8ff448..812cf30e4001 100755 --- a/files/scripts/syncd.sh +++ b/files/scripts/syncd.sh @@ -24,7 +24,7 @@ function startplatform() { debug "Starting Firmware update procedure" /usr/bin/mst start --with_i2cdev /usr/bin/mlnx-fw-upgrade.sh - /etc/init.d/sxdkernel start + /etc/init.d/sxdkernel restart debug "Firmware update procedure ended" fi From 485edbfd67530744f9ce39c2e6878731a33ef1ae Mon Sep 17 00:00:00 2001 From: bingwang-ms <66248323+bingwang-ms@users.noreply.github.com> Date: Tue, 16 Aug 2022 07:50:04 +0800 Subject: [PATCH 002/151] Disable tunnel qos remap on KVM (#11735) --- src/sonic-config-engine/minigraph.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/sonic-config-engine/minigraph.py b/src/sonic-config-engine/minigraph.py index d267c24976bf..9518678bb5b7 100644 --- a/src/sonic-config-engine/minigraph.py +++ b/src/sonic-config-engine/minigraph.py @@ -1460,7 +1460,9 @@ def parse_xml(filename, platform=None, port_config_file=None, asic_name=None, hw # Enable tunnel_qos_remap if downstream_redundancy_types(T1) or redundancy_type(T0) = Gemini/Libra enable_tunnel_qos_map = False - if results['DEVICE_METADATA']['localhost']['type'].lower() == 'leafrouter' and ('gemini' in str(downstream_redundancy_types).lower() or 'libra' in str(downstream_redundancy_types).lower()): + if platform and 'kvm' in platform: + enable_tunnel_qos_map = False + elif results['DEVICE_METADATA']['localhost']['type'].lower() == 'leafrouter' and ('gemini' in str(downstream_redundancy_types).lower() or 'libra' in str(downstream_redundancy_types).lower()): enable_tunnel_qos_map = True elif results['DEVICE_METADATA']['localhost']['type'].lower() == 'torrouter' and ('gemini' in str(redundancy_type).lower() or 'libra' in str(redundancy_type).lower()): enable_tunnel_qos_map = True From 6f9f765f1e3f25c17eb5543483129a1bcfa441ab Mon Sep 17 00:00:00 2001 From: vmittal-msft <46945843+vmittal-msft@users.noreply.github.com> Date: Tue, 16 Aug 2022 09:11:45 -0700 Subject: [PATCH 003/151] Updating sonic-swss pointer to latest (#11690) --- src/sonic-swss | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sonic-swss b/src/sonic-swss index d36c17d62c17..fd0c585d34de 160000 --- a/src/sonic-swss +++ b/src/sonic-swss @@ -1 +1 @@ -Subproject commit d36c17d62c17b7ae2617868989891bc7bb8c72f8 +Subproject commit fd0c585d34de63dc9cca57bb7d508cadfe1125d4 From 055b7d5fad0c40f5b4d1f0fe0b056e569799ab7c Mon Sep 17 00:00:00 2001 From: Michael Li <52540620+michaelli10@users.noreply.github.com> Date: Tue, 16 Aug 2022 11:46:03 -0700 Subject: [PATCH 004/151] =?UTF-8?q?Update=20BRCM=20KNET=20modules=20to=20s?= =?UTF-8?q?upport=20new=20psample=20definitions=20from=20sflow=E2=80=A6=20?= =?UTF-8?q?(#11709)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Update BRCM KNET module to support new psample definitions from sflow dropmon feature * Update BRCM KNET module to support new psample definitions from sflow dropmon feature * Advance saibcm-modules-dnx --- platform/broadcom/saibcm-modules-dnx | 2 +- .../debian/opennsl-modules.init | 11 +- .../broadcom/saibcm-modules/sdklt/Makefile | 17 +- .../sdklt/linux/include/net/psample.h | 24 -- .../sdklt/linux/include/uapi/linux/psample.h | 35 -- .../sdklt/linux/knetcb/psample-cb.c | 10 +- .../saibcm-modules/sdklt/linux/psample/Kbuild | 18 -- .../sdklt/linux/psample/Makefile | 21 -- .../sdklt/linux/psample/psample.c | 302 ----------------- .../kernel/modules/include/net/psample.h | 24 -- .../modules/include/uapi/linux/psample.h | 35 -- .../linux/kernel/modules/knet-cb/Makefile | 6 - .../linux/kernel/modules/knet-cb/psample-cb.c | 12 +- .../linux/kernel/modules/psample/Makefile | 64 ---- .../linux/kernel/modules/psample/psample.c | 304 ------------------ .../systems/linux/user/common/Makefile | 16 +- src/sonic-linux-kernel | 2 +- 17 files changed, 22 insertions(+), 881 deletions(-) delete mode 100644 platform/broadcom/saibcm-modules/sdklt/linux/include/net/psample.h delete mode 100644 platform/broadcom/saibcm-modules/sdklt/linux/include/uapi/linux/psample.h delete mode 100644 platform/broadcom/saibcm-modules/sdklt/linux/psample/Kbuild delete mode 100644 platform/broadcom/saibcm-modules/sdklt/linux/psample/Makefile delete mode 100644 platform/broadcom/saibcm-modules/sdklt/linux/psample/psample.c delete mode 100644 platform/broadcom/saibcm-modules/systems/linux/kernel/modules/include/net/psample.h delete mode 100644 platform/broadcom/saibcm-modules/systems/linux/kernel/modules/include/uapi/linux/psample.h delete mode 100644 platform/broadcom/saibcm-modules/systems/linux/kernel/modules/psample/Makefile delete mode 100644 platform/broadcom/saibcm-modules/systems/linux/kernel/modules/psample/psample.c diff --git a/platform/broadcom/saibcm-modules-dnx b/platform/broadcom/saibcm-modules-dnx index 8771baa40be8..65bce4ea8315 160000 --- a/platform/broadcom/saibcm-modules-dnx +++ b/platform/broadcom/saibcm-modules-dnx @@ -1 +1 @@ -Subproject commit 8771baa40be8392c2cf662648fc166929efa4b64 +Subproject commit 65bce4ea8315a7cd0875b3ea2f5c35423f32f868 diff --git a/platform/broadcom/saibcm-modules/debian/opennsl-modules.init b/platform/broadcom/saibcm-modules/debian/opennsl-modules.init index 62274eaa36aa..e8e9e23f2815 100755 --- a/platform/broadcom/saibcm-modules/debian/opennsl-modules.init +++ b/platform/broadcom/saibcm-modules/debian/opennsl-modules.init @@ -45,17 +45,14 @@ function create_devices() function load_kernel_modules() { if [[ $is_ltsw_chip -eq 1 ]]; then - insmod /lib/modules/$(uname -r)/extra/psample.ko + modprobe psample modprobe linux_ngbde modprobe linux_ngknet modprobe linux_ngknetcb else modprobe linux-kernel-bde dmasize=$dmasize maxpayload=128 debug=4 dma_debug=1 usemsi=$usemsi modprobe linux-user-bde - - # Using insmod with absolute path for psample to make sure bcm psample is loaded. - # There is a different psample.ko module getting created at net/psample/psample.ko - insmod /lib/modules/$(uname -r)/extra/psample.ko + modprobe psample modprobe linux-bcm-knet use_rx_skb=1 rx_buffer_size=9238 debug=0x5020 default_mtu=9100 modprobe linux-knet-cb @@ -69,9 +66,9 @@ function remove_kernel_modules() rmmod linux_ngknetcb rmmod linux_ngknet rmmod linux_ngbde - rmmod psample.ko + rmmod psample else - rmmod psample.ko + rmmod psample rmmod linux-knet-cb rmmod linux-bcm-knet rmmod linux-user-bde diff --git a/platform/broadcom/saibcm-modules/sdklt/Makefile b/platform/broadcom/saibcm-modules/sdklt/Makefile index 83a77ebcd1e0..1ce04c788a32 100644 --- a/platform/broadcom/saibcm-modules/sdklt/Makefile +++ b/platform/broadcom/saibcm-modules/sdklt/Makefile @@ -44,12 +44,7 @@ export CROSS_COMPILE override SDK := $(CURDIR) -ifeq ($(BUILD_PSAMPLE),1) -PSAMPLE=psample -PSAMPLE_SYMVERS=$(SDK)/linux/psample/Module.symvers -endif - -kmod: bde knet knetcb $(PSAMPLE) +kmod: bde knet knetcb bde: $(MAKE) -C $(SDK)/linux/bde SDK=$(SDK) \ @@ -62,20 +57,12 @@ knet: bde $(TARGET) ln -sf $(SDK)/linux/knet/*.ko -knetcb: knet $(PSAMPLE) +knetcb: knet $(MAKE) -C $(SDK)/linux/knetcb SDK=$(SDK) \ KBUILD_EXTRA_SYMBOLS=$(SDK)/linux/knet/Module.symvers \ - KBUILD_EXTRA_SYMBOLS+=$(PSAMPLE_SYMVERS) \ $(TARGET) ln -sf $(SDK)/linux/knetcb/*.ko -ifeq ($(BUILD_PSAMPLE),1) -$(PSAMPLE): - $(MAKE) -C $(SDK)/linux/psample SDK=$(SDK) \ - $(TARGET) - ln -sf $(SDK)/linux/psample/*.ko -endif - clean: $(MAKE) kmod TARGET=clean rm -f *.ko diff --git a/platform/broadcom/saibcm-modules/sdklt/linux/include/net/psample.h b/platform/broadcom/saibcm-modules/sdklt/linux/include/net/psample.h deleted file mode 100644 index 64188c95daeb..000000000000 --- a/platform/broadcom/saibcm-modules/sdklt/linux/include/net/psample.h +++ /dev/null @@ -1,24 +0,0 @@ -#ifndef __NET_PSAMPLE_H -#define __NET_PSAMPLE_H - -#include -#include -#include -#include - -struct psample_group { - struct list_head list; - struct net *net; - u32 group_num; - u32 refcount; - u32 seq; -}; - -extern struct psample_group *psample_group_get(struct net *net, u32 group_num); -extern void psample_group_put(struct psample_group *group); - -extern void psample_sample_packet(struct psample_group *group, struct sk_buff *skb, - u32 trunc_size, int in_ifindex, int out_ifindex, - u32 sample_rate); - -#endif /* __NET_PSAMPLE_H */ diff --git a/platform/broadcom/saibcm-modules/sdklt/linux/include/uapi/linux/psample.h b/platform/broadcom/saibcm-modules/sdklt/linux/include/uapi/linux/psample.h deleted file mode 100644 index ed48996ec0e8..000000000000 --- a/platform/broadcom/saibcm-modules/sdklt/linux/include/uapi/linux/psample.h +++ /dev/null @@ -1,35 +0,0 @@ -#ifndef __UAPI_PSAMPLE_H -#define __UAPI_PSAMPLE_H - -enum { - /* sampled packet metadata */ - PSAMPLE_ATTR_IIFINDEX, - PSAMPLE_ATTR_OIFINDEX, - PSAMPLE_ATTR_ORIGSIZE, - PSAMPLE_ATTR_SAMPLE_GROUP, - PSAMPLE_ATTR_GROUP_SEQ, - PSAMPLE_ATTR_SAMPLE_RATE, - PSAMPLE_ATTR_DATA, - - /* commands attributes */ - PSAMPLE_ATTR_GROUP_REFCOUNT, - - __PSAMPLE_ATTR_MAX -}; - -enum psample_command { - PSAMPLE_CMD_SAMPLE, - PSAMPLE_CMD_GET_GROUP, - PSAMPLE_CMD_NEW_GROUP, - PSAMPLE_CMD_DEL_GROUP, -}; - -/* Can be overridden at runtime by module option */ -#define PSAMPLE_ATTR_MAX (__PSAMPLE_ATTR_MAX - 1) - -#define PSAMPLE_NL_MCGRP_CONFIG_NAME "config" -#define PSAMPLE_NL_MCGRP_SAMPLE_NAME "packets" -#define PSAMPLE_GENL_NAME "psample" -#define PSAMPLE_GENL_VERSION 1 - -#endif diff --git a/platform/broadcom/saibcm-modules/sdklt/linux/knetcb/psample-cb.c b/platform/broadcom/saibcm-modules/sdklt/linux/knetcb/psample-cb.c index a35c21cf37f4..142357134ff1 100644 --- a/platform/broadcom/saibcm-modules/sdklt/linux/knetcb/psample-cb.c +++ b/platform/broadcom/saibcm-modules/sdklt/linux/knetcb/psample-cb.c @@ -251,6 +251,7 @@ psample_task(struct work_struct *work) unsigned long flags; struct list_head *list_ptr, *list_next; psample_pkt_t *pkt; + struct psample_metadata md = {0}; spin_lock_irqsave(&psample_work->lock, flags); list_for_each_safe(list_ptr, list_next, &psample_work->pkt_list) { @@ -267,12 +268,13 @@ psample_task(struct work_struct *work) pkt->meta.trunc_size, pkt->meta.src_ifindex, pkt->meta.dst_ifindex, pkt->meta.sample_rate); + md.trunc_size = pkt->meta.trunc_size; + md.in_ifindex = pkt->meta.src_ifindex; + md.out_ifindex = pkt->meta.dst_ifindex; psample_sample_packet(pkt->group, pkt->skb, - pkt->meta.trunc_size, - pkt->meta.src_ifindex, - pkt->meta.dst_ifindex, - pkt->meta.sample_rate); + pkt->meta.sample_rate, + &md); g_psample_stats.pkts_f_psample_mod++; dev_kfree_skb_any(pkt->skb); diff --git a/platform/broadcom/saibcm-modules/sdklt/linux/psample/Kbuild b/platform/broadcom/saibcm-modules/sdklt/linux/psample/Kbuild deleted file mode 100644 index 0049e399076b..000000000000 --- a/platform/broadcom/saibcm-modules/sdklt/linux/psample/Kbuild +++ /dev/null @@ -1,18 +0,0 @@ -# -*- Kbuild -*- -# -# Linux psample module. -# -# $Copyright: (c) 2020 Broadcom. -# Broadcom Proprietary and Confidential. All rights reserved.$ -# - -obj-m := linux_psample.o - -ccflags-y := $(LKM_CFLAGS) \ - -I$(SDK)/shr/include \ - -I$(SDK)/bcmdrd/include \ - -I$(SDK)/linux/include \ - -I$(SDK)/linux/knet/include \ - -I$(SDK)/linux/knet - -linux_psample-y := psample.o diff --git a/platform/broadcom/saibcm-modules/sdklt/linux/psample/Makefile b/platform/broadcom/saibcm-modules/sdklt/linux/psample/Makefile deleted file mode 100644 index b37b8ebb1c29..000000000000 --- a/platform/broadcom/saibcm-modules/sdklt/linux/psample/Makefile +++ /dev/null @@ -1,21 +0,0 @@ -# -*- Makefile -*- -# -# Linux psample module. -# -# $Copyright: (c) 2020 Broadcom. -# Broadcom Proprietary and Confidential. All rights reserved.$ -# - -include Kbuild - -ifeq ($(KERNELRELEASE),) - -MOD_NAME = linux_psample - -include $(SDK)/make/lkm.mk - -endif - -.PHONY: distclean - -distclean: diff --git a/platform/broadcom/saibcm-modules/sdklt/linux/psample/psample.c b/platform/broadcom/saibcm-modules/sdklt/linux/psample/psample.c deleted file mode 100644 index f0c9beab5784..000000000000 --- a/platform/broadcom/saibcm-modules/sdklt/linux/psample/psample.c +++ /dev/null @@ -1,302 +0,0 @@ -/* - * net/psample/psample.c - Netlink channel for packet sampling - * Copyright (c) 2017 Yotam Gigi - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define PSAMPLE_MAX_PACKET_SIZE 0xffff - -static LIST_HEAD(psample_groups_list); -static DEFINE_SPINLOCK(psample_groups_lock); - -/* multicast groups */ -enum psample_nl_multicast_groups { - PSAMPLE_NL_MCGRP_CONFIG, - PSAMPLE_NL_MCGRP_SAMPLE, -}; - -static const struct genl_multicast_group psample_nl_mcgrps[] = { - [PSAMPLE_NL_MCGRP_CONFIG] = { .name = PSAMPLE_NL_MCGRP_CONFIG_NAME }, - [PSAMPLE_NL_MCGRP_SAMPLE] = { .name = PSAMPLE_NL_MCGRP_SAMPLE_NAME }, -}; - -static struct genl_family psample_nl_family; - -static int psample_group_nl_fill(struct sk_buff *msg, - struct psample_group *group, - enum psample_command cmd, u32 portid, u32 seq, - int flags) -{ - void *hdr; - int ret; - - hdr = genlmsg_put(msg, portid, seq, &psample_nl_family, flags, cmd); - if (!hdr) - return -EMSGSIZE; - - ret = nla_put_u32(msg, PSAMPLE_ATTR_SAMPLE_GROUP, group->group_num); - if (ret < 0) - goto error; - - ret = nla_put_u32(msg, PSAMPLE_ATTR_GROUP_REFCOUNT, group->refcount); - if (ret < 0) - goto error; - - ret = nla_put_u32(msg, PSAMPLE_ATTR_GROUP_SEQ, group->seq); - if (ret < 0) - goto error; - - genlmsg_end(msg, hdr); - return 0; - -error: - genlmsg_cancel(msg, hdr); - return -EMSGSIZE; -} - -static int psample_nl_cmd_get_group_dumpit(struct sk_buff *msg, - struct netlink_callback *cb) -{ - struct psample_group *group; - int start = cb->args[0]; - int idx = 0; - int err; - - spin_lock(&psample_groups_lock); - list_for_each_entry(group, &psample_groups_list, list) { - if (!net_eq(group->net, sock_net(msg->sk))) - continue; - if (idx < start) { - idx++; - continue; - } - err = psample_group_nl_fill(msg, group, PSAMPLE_CMD_NEW_GROUP, - NETLINK_CB(cb->skb).portid, - cb->nlh->nlmsg_seq, NLM_F_MULTI); - if (err) - break; - idx++; - } - - spin_unlock(&psample_groups_lock); - cb->args[0] = idx; - return msg->len; -} - -static const struct genl_ops psample_nl_ops[] = { - { - .cmd = PSAMPLE_CMD_GET_GROUP, - .dumpit = psample_nl_cmd_get_group_dumpit, - /* can be retrieved by unprivileged users */ - } -}; - -static struct genl_family psample_nl_family = { - .name = PSAMPLE_GENL_NAME, - .version = PSAMPLE_GENL_VERSION, - .maxattr = PSAMPLE_ATTR_MAX, - .netnsok = true, - .module = THIS_MODULE, - .mcgrps = psample_nl_mcgrps, - .ops = psample_nl_ops, - .n_ops = ARRAY_SIZE(psample_nl_ops), - .n_mcgrps = ARRAY_SIZE(psample_nl_mcgrps), -}; - -static void psample_group_notify(struct psample_group *group, - enum psample_command cmd) -{ - struct sk_buff *msg; - int err; - - msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_ATOMIC); - if (!msg) - return; - - err = psample_group_nl_fill(msg, group, cmd, 0, 0, NLM_F_MULTI); - if (!err) - genlmsg_multicast_netns(&psample_nl_family, group->net, msg, 0, - PSAMPLE_NL_MCGRP_CONFIG, GFP_ATOMIC); - else - nlmsg_free(msg); -} - -static struct psample_group *psample_group_create(struct net *net, - u32 group_num) -{ - struct psample_group *group; - - group = kzalloc(sizeof(*group), GFP_ATOMIC); - if (!group) - return NULL; - - group->net = net; - group->group_num = group_num; - list_add_tail(&group->list, &psample_groups_list); - - psample_group_notify(group, PSAMPLE_CMD_NEW_GROUP); - return group; -} - -static void psample_group_destroy(struct psample_group *group) -{ - psample_group_notify(group, PSAMPLE_CMD_DEL_GROUP); - list_del(&group->list); - kfree(group); -} - -static struct psample_group * -psample_group_lookup(struct net *net, u32 group_num) -{ - struct psample_group *group; - - list_for_each_entry(group, &psample_groups_list, list) - if ((group->group_num == group_num) && (group->net == net)) - return group; - return NULL; -} - -struct psample_group *psample_group_get(struct net *net, u32 group_num) -{ - struct psample_group *group; - - spin_lock(&psample_groups_lock); - - group = psample_group_lookup(net, group_num); - if (!group) { - group = psample_group_create(net, group_num); - if (!group) - goto out; - } - group->refcount++; - -out: - spin_unlock(&psample_groups_lock); - return group; -} -EXPORT_SYMBOL_GPL(psample_group_get); - -void psample_group_put(struct psample_group *group) -{ - spin_lock(&psample_groups_lock); - - if (--group->refcount == 0) - psample_group_destroy(group); - - spin_unlock(&psample_groups_lock); -} -EXPORT_SYMBOL_GPL(psample_group_put); - -void psample_sample_packet(struct psample_group *group, struct sk_buff *skb, - u32 trunc_size, int in_ifindex, int out_ifindex, - u32 sample_rate) -{ - struct sk_buff *nl_skb; - int data_len; - int meta_len; - void *data; - int ret; - - meta_len = (in_ifindex ? nla_total_size(sizeof(u16)) : 0) + - (out_ifindex ? nla_total_size(sizeof(u16)) : 0) + - nla_total_size(sizeof(u32)) + /* sample_rate */ - nla_total_size(sizeof(u32)) + /* orig_size */ - nla_total_size(sizeof(u32)) + /* group_num */ - nla_total_size(sizeof(u32)); /* seq */ - - data_len = min(skb->len, trunc_size); - if (meta_len + nla_total_size(data_len) > PSAMPLE_MAX_PACKET_SIZE) - data_len = PSAMPLE_MAX_PACKET_SIZE - meta_len - NLA_HDRLEN - - NLA_ALIGNTO; - - nl_skb = genlmsg_new(meta_len + nla_total_size(data_len), GFP_ATOMIC); - if (unlikely(!nl_skb)) - return; - - data = genlmsg_put(nl_skb, 0, 0, &psample_nl_family, 0, - PSAMPLE_CMD_SAMPLE); - if (unlikely(!data)) - goto error; - - if (in_ifindex) { - ret = nla_put_u16(nl_skb, PSAMPLE_ATTR_IIFINDEX, in_ifindex); - if (unlikely(ret < 0)) - goto error; - } - - if (out_ifindex) { - ret = nla_put_u16(nl_skb, PSAMPLE_ATTR_OIFINDEX, out_ifindex); - if (unlikely(ret < 0)) - goto error; - } - - ret = nla_put_u32(nl_skb, PSAMPLE_ATTR_SAMPLE_RATE, sample_rate); - if (unlikely(ret < 0)) - goto error; - - ret = nla_put_u32(nl_skb, PSAMPLE_ATTR_ORIGSIZE, skb->len); - if (unlikely(ret < 0)) - goto error; - - ret = nla_put_u32(nl_skb, PSAMPLE_ATTR_SAMPLE_GROUP, group->group_num); - if (unlikely(ret < 0)) - goto error; - - ret = nla_put_u32(nl_skb, PSAMPLE_ATTR_GROUP_SEQ, group->seq++); - if (unlikely(ret < 0)) - goto error; - - if (data_len) { - int nla_len = nla_total_size(data_len); - struct nlattr *nla; - - nla = (struct nlattr *)skb_put(nl_skb, nla_len); - nla->nla_type = PSAMPLE_ATTR_DATA; - nla->nla_len = nla_attr_size(data_len); - - if (skb_copy_bits(skb, 0, nla_data(nla), data_len)) - goto error; - } - - genlmsg_end(nl_skb, data); - genlmsg_multicast_netns(&psample_nl_family, group->net, nl_skb, 0, - PSAMPLE_NL_MCGRP_SAMPLE, GFP_ATOMIC); - - return; -error: - pr_err_ratelimited("Could not create psample log message\n"); - nlmsg_free(nl_skb); -} -EXPORT_SYMBOL_GPL(psample_sample_packet); - -static int __init psample_module_init(void) -{ - return genl_register_family(&psample_nl_family); -} - -static void __exit psample_module_exit(void) -{ - genl_unregister_family(&psample_nl_family); -} - -module_init(psample_module_init); -module_exit(psample_module_exit); - -MODULE_AUTHOR("Yotam Gigi "); -MODULE_DESCRIPTION("netlink channel for packet sampling"); -MODULE_LICENSE("GPL v2"); diff --git a/platform/broadcom/saibcm-modules/systems/linux/kernel/modules/include/net/psample.h b/platform/broadcom/saibcm-modules/systems/linux/kernel/modules/include/net/psample.h deleted file mode 100644 index 57c000785e9c..000000000000 --- a/platform/broadcom/saibcm-modules/systems/linux/kernel/modules/include/net/psample.h +++ /dev/null @@ -1,24 +0,0 @@ -#ifndef __NET_PSAMPLE_H -#define __NET_PSAMPLE_H - -#include -#include -#include -#include - -struct psample_group { - struct list_head list; - struct net *net; - u32 group_num; - u32 refcount; - u32 seq; -}; - -extern struct psample_group *psample_group_get(struct net *net, u32 group_num); -extern void psample_group_put(struct psample_group *group); - -extern void psample_sample_packet(struct psample_group *group, struct sk_buff *skb, - u32 trunc_size, int in_ifindex, int out_ifindex, - u32 sample_rate); - -#endif /* __NET_PSAMPLE_H */ diff --git a/platform/broadcom/saibcm-modules/systems/linux/kernel/modules/include/uapi/linux/psample.h b/platform/broadcom/saibcm-modules/systems/linux/kernel/modules/include/uapi/linux/psample.h deleted file mode 100644 index ed48996ec0e8..000000000000 --- a/platform/broadcom/saibcm-modules/systems/linux/kernel/modules/include/uapi/linux/psample.h +++ /dev/null @@ -1,35 +0,0 @@ -#ifndef __UAPI_PSAMPLE_H -#define __UAPI_PSAMPLE_H - -enum { - /* sampled packet metadata */ - PSAMPLE_ATTR_IIFINDEX, - PSAMPLE_ATTR_OIFINDEX, - PSAMPLE_ATTR_ORIGSIZE, - PSAMPLE_ATTR_SAMPLE_GROUP, - PSAMPLE_ATTR_GROUP_SEQ, - PSAMPLE_ATTR_SAMPLE_RATE, - PSAMPLE_ATTR_DATA, - - /* commands attributes */ - PSAMPLE_ATTR_GROUP_REFCOUNT, - - __PSAMPLE_ATTR_MAX -}; - -enum psample_command { - PSAMPLE_CMD_SAMPLE, - PSAMPLE_CMD_GET_GROUP, - PSAMPLE_CMD_NEW_GROUP, - PSAMPLE_CMD_DEL_GROUP, -}; - -/* Can be overridden at runtime by module option */ -#define PSAMPLE_ATTR_MAX (__PSAMPLE_ATTR_MAX - 1) - -#define PSAMPLE_NL_MCGRP_CONFIG_NAME "config" -#define PSAMPLE_NL_MCGRP_SAMPLE_NAME "packets" -#define PSAMPLE_GENL_NAME "psample" -#define PSAMPLE_GENL_VERSION 1 - -#endif diff --git a/platform/broadcom/saibcm-modules/systems/linux/kernel/modules/knet-cb/Makefile b/platform/broadcom/saibcm-modules/systems/linux/kernel/modules/knet-cb/Makefile index d888820fafba..52b776f82b6c 100644 --- a/platform/broadcom/saibcm-modules/systems/linux/kernel/modules/knet-cb/Makefile +++ b/platform/broadcom/saibcm-modules/systems/linux/kernel/modules/knet-cb/Makefile @@ -48,9 +48,6 @@ build: $(MODULE) $(KMODULE) endif KBUILD_EXTRA_SYMBOLS := ${BLDDIR}/../bcm-knet/kernel_module/Module.symvers -ifeq ($(BUILD_PSAMPLE),1) -KBUILD_EXTRA_SYMBOLS += ${BLDDIR}/../psample/kernel_module/Module.symvers -endif # BCM Network Device @@ -61,9 +58,6 @@ $(KMODULE): $(MODULE) rm -fr $(BLDDIR)/$(KERNEL_MODULE_DIR) mkdir $(BLDDIR)/$(KERNEL_MODULE_DIR) cp ${SDK}/make/Makefile.linux-kmodule $(BLDDIR)/$(KERNEL_MODULE_DIR)/Makefile -ifeq ($(BUILD_PSAMPLE),1) - sed -i 's/0x......../0x00000000/' ${BLDDIR}/../psample/kernel_module/Module.symvers -endif cat ${KBUILD_EXTRA_SYMBOLS} > $(BLDDIR)/$(KERNEL_MODULE_DIR)/Module.symvers MOD_NAME=$(THIS_MOD_NAME) KBUILD_EXTRA_SYMBOLS="${KBUILD_EXTRA_SYMBOLS}" $(MAKE) -C $(BLDDIR)/$(KERNEL_MODULE_DIR) $(THIS_MOD_NAME).ko endif diff --git a/platform/broadcom/saibcm-modules/systems/linux/kernel/modules/knet-cb/psample-cb.c b/platform/broadcom/saibcm-modules/systems/linux/kernel/modules/knet-cb/psample-cb.c index 628ee1780c09..2228eb44d5d3 100644 --- a/platform/broadcom/saibcm-modules/systems/linux/kernel/modules/knet-cb/psample-cb.c +++ b/platform/broadcom/saibcm-modules/systems/linux/kernel/modules/knet-cb/psample-cb.c @@ -394,6 +394,7 @@ psample_task(struct work_struct *work) unsigned long flags; struct list_head *list_ptr, *list_next; psample_pkt_t *pkt; + struct psample_metadata md = {0}; spin_lock_irqsave(&psample_work->lock, flags); list_for_each_safe(list_ptr, list_next, &psample_work->pkt_list) { @@ -410,12 +411,13 @@ psample_task(struct work_struct *work) pkt->meta.trunc_size, pkt->meta.src_ifindex, pkt->meta.dst_ifindex, pkt->meta.sample_rate); + md.trunc_size = pkt->meta.trunc_size; + md.in_ifindex = pkt->meta.src_ifindex; + md.out_ifindex = pkt->meta.dst_ifindex; psample_sample_packet(pkt->group, - pkt->skb, - pkt->meta.trunc_size, - pkt->meta.src_ifindex, - pkt->meta.dst_ifindex, - pkt->meta.sample_rate); + pkt->skb, + pkt->meta.sample_rate, + &md); g_psample_stats.pkts_f_psample_mod++; dev_kfree_skb_any(pkt->skb); diff --git a/platform/broadcom/saibcm-modules/systems/linux/kernel/modules/psample/Makefile b/platform/broadcom/saibcm-modules/systems/linux/kernel/modules/psample/Makefile deleted file mode 100644 index 53293a7ac93b..000000000000 --- a/platform/broadcom/saibcm-modules/systems/linux/kernel/modules/psample/Makefile +++ /dev/null @@ -1,64 +0,0 @@ -# -# Copyright 2017 Broadcom -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License, version 2, as -# published by the Free Software Foundation (the "GPL"). -# -# This program is distributed in the hope that it will be useful, but -# WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# General Public License version 2 (GPLv2) for more details. -# -# You should have received a copy of the GNU General Public License -# version 2 (GPLv2) along with this source code. -# -# -*- Makefile -*- -# $Id: Makefile,v 1.3 Broadcom SDK $ -# $Copyright: (c) 2005 Broadcom Corp. -# All Rights Reserved.$ -# -LOCALDIR = systems/linux/kernel/modules/psample - -include ${SDK}/make/Make.config - -LIBS = $(LIBDIR)/libkern.a - -ifeq ($(kernel_version),2_4) -MODULE = $(LIBDIR)/psample.o -else -KERNEL_MODULE_DIR = kernel_module - -THIS_MOD_NAME := psample -MODULE = $(LIBDIR)/$(THIS_MOD_NAME).o -KMODULE = $(LIBDIR)/$(THIS_MOD_NAME).ko - -build: $(MODULE) $(KMODULE) -endif - -KBUILD_EXTRA_SYMBOLS := ${BLDDIR}/../bcm-knet/kernel_module/Module.symvers - -# BCM Network Device - -$(MODULE): $(BLDDIR)/.tree $(BOBJS) $(LIBS) - $(LD) $(MODULE_LDFLAGS) -r -d $(BOBJS) $(LIBS) -o $@ -ifneq ($(kernel_version),2_4) -$(KMODULE): $(MODULE) - rm -fr $(BLDDIR)/$(KERNEL_MODULE_DIR) - mkdir $(BLDDIR)/$(KERNEL_MODULE_DIR) - cp ${SDK}/make/Makefile.linux-kmodule $(BLDDIR)/$(KERNEL_MODULE_DIR)/Makefile - cat ${KBUILD_EXTRA_SYMBOLS} > $(BLDDIR)/$(KERNEL_MODULE_DIR)/Module.symvers - MOD_NAME=$(THIS_MOD_NAME) KBUILD_EXTRA_SYMBOLS="${KBUILD_EXTRA_SYMBOLS}" $(MAKE) -C $(BLDDIR)/$(KERNEL_MODULE_DIR) $(THIS_MOD_NAME).ko -endif - -# Make.depend is before clean:: so that Make.depend's clean:: runs first. - -include ${SDK}/make/Make.depend - -clean:: - $(RM) $(BLDDIR)/version.c $(BLDDIR)/version.o - $(RM) $(BOBJS) $(MODULE) - -ifneq ($(kernel_version),2_4) -.PHONY: build -endif diff --git a/platform/broadcom/saibcm-modules/systems/linux/kernel/modules/psample/psample.c b/platform/broadcom/saibcm-modules/systems/linux/kernel/modules/psample/psample.c deleted file mode 100644 index 46a84c7f7c4a..000000000000 --- a/platform/broadcom/saibcm-modules/systems/linux/kernel/modules/psample/psample.c +++ /dev/null @@ -1,304 +0,0 @@ -/* - * net/psample/psample.c - Netlink channel for packet sampling - * Copyright (c) 2017 Yotam Gigi - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define PSAMPLE_MAX_PACKET_SIZE 0xffff - -static LIST_HEAD(psample_groups_list); -static DEFINE_SPINLOCK(psample_groups_lock); - -/* multicast groups */ -enum psample_nl_multicast_groups { - PSAMPLE_NL_MCGRP_CONFIG, - PSAMPLE_NL_MCGRP_SAMPLE, -}; - -static const struct genl_multicast_group psample_nl_mcgrps[] = { - [PSAMPLE_NL_MCGRP_CONFIG] = { .name = PSAMPLE_NL_MCGRP_CONFIG_NAME }, - [PSAMPLE_NL_MCGRP_SAMPLE] = { .name = PSAMPLE_NL_MCGRP_SAMPLE_NAME }, -}; - -static struct genl_family psample_nl_family; - -static int psample_group_nl_fill(struct sk_buff *msg, - struct psample_group *group, - enum psample_command cmd, u32 portid, u32 seq, - int flags) -{ - void *hdr; - int ret; - - hdr = genlmsg_put(msg, portid, seq, &psample_nl_family, flags, cmd); - if (!hdr) - return -EMSGSIZE; - - ret = nla_put_u32(msg, PSAMPLE_ATTR_SAMPLE_GROUP, group->group_num); - if (ret < 0) - goto error; - - ret = nla_put_u32(msg, PSAMPLE_ATTR_GROUP_REFCOUNT, group->refcount); - if (ret < 0) - goto error; - - ret = nla_put_u32(msg, PSAMPLE_ATTR_GROUP_SEQ, group->seq); - if (ret < 0) - goto error; - - genlmsg_end(msg, hdr); - return 0; - -error: - genlmsg_cancel(msg, hdr); - return -EMSGSIZE; -} - -static int psample_nl_cmd_get_group_dumpit(struct sk_buff *msg, - struct netlink_callback *cb) -{ - struct psample_group *group; - int start = cb->args[0]; - int idx = 0; - int err; - - spin_lock(&psample_groups_lock); - list_for_each_entry(group, &psample_groups_list, list) { - if (!net_eq(group->net, sock_net(msg->sk))) - continue; - if (idx < start) { - idx++; - continue; - } - err = psample_group_nl_fill(msg, group, PSAMPLE_CMD_NEW_GROUP, - NETLINK_CB(cb->skb).portid, - cb->nlh->nlmsg_seq, NLM_F_MULTI); - if (err) - break; - idx++; - } - - spin_unlock(&psample_groups_lock); - cb->args[0] = idx; - return msg->len; -} - -static const struct genl_ops psample_nl_ops[] = { - { - .cmd = PSAMPLE_CMD_GET_GROUP, - .dumpit = psample_nl_cmd_get_group_dumpit, - /* can be retrieved by unprivileged users */ - } -}; - -static struct genl_family psample_nl_family = { - .name = PSAMPLE_GENL_NAME, - .version = PSAMPLE_GENL_VERSION, - .maxattr = PSAMPLE_ATTR_MAX, - .netnsok = true, - .module = THIS_MODULE, - .mcgrps = psample_nl_mcgrps, - .ops = psample_nl_ops, - .n_ops = ARRAY_SIZE(psample_nl_ops), - .n_mcgrps = ARRAY_SIZE(psample_nl_mcgrps), -}; - -static void psample_group_notify(struct psample_group *group, - enum psample_command cmd) -{ - struct sk_buff *msg; - int err; - - msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_ATOMIC); - if (!msg) - return; - - err = psample_group_nl_fill(msg, group, cmd, 0, 0, NLM_F_MULTI); - if (!err) - genlmsg_multicast_netns(&psample_nl_family, group->net, msg, 0, - PSAMPLE_NL_MCGRP_CONFIG, GFP_ATOMIC); - else - nlmsg_free(msg); -} - -static struct psample_group *psample_group_create(struct net *net, - u32 group_num) -{ - struct psample_group *group; - - group = kzalloc(sizeof(*group), GFP_ATOMIC); - if (!group) - return NULL; - - group->net = net; - group->group_num = group_num; - list_add_tail(&group->list, &psample_groups_list); - - psample_group_notify(group, PSAMPLE_CMD_NEW_GROUP); - return group; -} - -static void psample_group_destroy(struct psample_group *group) -{ - psample_group_notify(group, PSAMPLE_CMD_DEL_GROUP); - list_del(&group->list); - kfree(group); -} - -static struct psample_group * -psample_group_lookup(struct net *net, u32 group_num) -{ - struct psample_group *group; - - list_for_each_entry(group, &psample_groups_list, list) - if ((group->group_num == group_num) && (group->net == net)) - return group; - return NULL; -} - -struct psample_group *psample_group_get(struct net *net, u32 group_num) -{ - struct psample_group *group; - - spin_lock(&psample_groups_lock); - - group = psample_group_lookup(net, group_num); - if (!group) { - group = psample_group_create(net, group_num); - if (!group) - goto out; - } - group->refcount++; - -out: - spin_unlock(&psample_groups_lock); - return group; -} -EXPORT_SYMBOL_GPL(psample_group_get); - -void psample_group_put(struct psample_group *group) -{ - spin_lock(&psample_groups_lock); - - if (--group->refcount == 0) - psample_group_destroy(group); - - spin_unlock(&psample_groups_lock); -} -EXPORT_SYMBOL_GPL(psample_group_put); - -#if IS_ENABLED(CONFIG_PSAMPLE) /* FIXUP:- Remove after GTS kernel is recompiled with change in CONFIG_PSAMPLE flag */ -void psample_sample_packet(struct psample_group *group, struct sk_buff *skb, - u32 trunc_size, int in_ifindex, int out_ifindex, - u32 sample_rate) -{ - struct sk_buff *nl_skb; - int data_len; - int meta_len; - void *data; - int ret; - - meta_len = (in_ifindex ? nla_total_size(sizeof(u16)) : 0) + - (out_ifindex ? nla_total_size(sizeof(u16)) : 0) + - nla_total_size(sizeof(u32)) + /* sample_rate */ - nla_total_size(sizeof(u32)) + /* orig_size */ - nla_total_size(sizeof(u32)) + /* group_num */ - nla_total_size(sizeof(u32)); /* seq */ - - data_len = min(skb->len, trunc_size); - if (meta_len + nla_total_size(data_len) > PSAMPLE_MAX_PACKET_SIZE) - data_len = PSAMPLE_MAX_PACKET_SIZE - meta_len - NLA_HDRLEN - - NLA_ALIGNTO; - - nl_skb = genlmsg_new(meta_len + nla_total_size(data_len), GFP_ATOMIC); - if (unlikely(!nl_skb)) - return; - - data = genlmsg_put(nl_skb, 0, 0, &psample_nl_family, 0, - PSAMPLE_CMD_SAMPLE); - if (unlikely(!data)) - goto error; - - if (in_ifindex) { - ret = nla_put_u16(nl_skb, PSAMPLE_ATTR_IIFINDEX, in_ifindex); - if (unlikely(ret < 0)) - goto error; - } - - if (out_ifindex) { - ret = nla_put_u16(nl_skb, PSAMPLE_ATTR_OIFINDEX, out_ifindex); - if (unlikely(ret < 0)) - goto error; - } - - ret = nla_put_u32(nl_skb, PSAMPLE_ATTR_SAMPLE_RATE, sample_rate); - if (unlikely(ret < 0)) - goto error; - - ret = nla_put_u32(nl_skb, PSAMPLE_ATTR_ORIGSIZE, skb->len); - if (unlikely(ret < 0)) - goto error; - - ret = nla_put_u32(nl_skb, PSAMPLE_ATTR_SAMPLE_GROUP, group->group_num); - if (unlikely(ret < 0)) - goto error; - - ret = nla_put_u32(nl_skb, PSAMPLE_ATTR_GROUP_SEQ, group->seq++); - if (unlikely(ret < 0)) - goto error; - - if (data_len) { - int nla_len = nla_total_size(data_len); - struct nlattr *nla; - - nla = (struct nlattr *)skb_put(nl_skb, nla_len); - nla->nla_type = PSAMPLE_ATTR_DATA; - nla->nla_len = nla_attr_size(data_len); - - if (skb_copy_bits(skb, 0, nla_data(nla), data_len)) - goto error; - } - - genlmsg_end(nl_skb, data); - genlmsg_multicast_netns(&psample_nl_family, group->net, nl_skb, 0, - PSAMPLE_NL_MCGRP_SAMPLE, GFP_ATOMIC); - - return; -error: - pr_err_ratelimited("Could not create psample log message\n"); - nlmsg_free(nl_skb); -} -EXPORT_SYMBOL_GPL(psample_sample_packet); -#endif - -static int __init psample_module_init(void) -{ - return genl_register_family(&psample_nl_family); -} - -static void __exit psample_module_exit(void) -{ - genl_unregister_family(&psample_nl_family); -} - -module_init(psample_module_init); -module_exit(psample_module_exit); - -MODULE_AUTHOR("Yotam Gigi "); -MODULE_DESCRIPTION("netlink channel for packet sampling"); -MODULE_LICENSE("GPL v2"); diff --git a/platform/broadcom/saibcm-modules/systems/linux/user/common/Makefile b/platform/broadcom/saibcm-modules/systems/linux/user/common/Makefile index 7a342f6ef60e..a72dba96f6e2 100644 --- a/platform/broadcom/saibcm-modules/systems/linux/user/common/Makefile +++ b/platform/broadcom/saibcm-modules/systems/linux/user/common/Makefile @@ -106,9 +106,6 @@ KNET_CB := $(DEST_DIR)/$(KNET_CB_LOCAL) BCM_KNET_LOCAL :=linux-bcm-knet.$(KOBJ) BCM_KNET=$(DEST_DIR)/$(BCM_KNET_LOCAL) -PSAMPLE_LOCAL := psample.$(KOBJ) -PSAMPLE := $(DEST_DIR)/$(PSAMPLE_LOCAL) - ifeq (,$(findstring DELIVER,$(MAKECMDGOALS))) .DEFAULT_GOAL := all all_targets := kernel_modules $(KERNEL_BDE) $(USER_BDE) @@ -145,7 +142,6 @@ endif endif ifdef BUILD_PSAMPLE -all_targets += $(PSAMPLE) ADD_TO_CFLAGS += -DPSAMPLE_SUPPORT endif ADD_TO_CFLAGS += -I$(SDK)/systems/linux/kernel/modules/include @@ -178,10 +174,6 @@ kernel_modules: ifeq ($(BUILD_KNET),1) $(MAKE) -C $(SDK)/systems/linux/kernel/modules kernel_version=$(kernel_version) \ subdirs="shared bcm-knet" override-target=linux-$(platform) CFLAGS="$(CFLAGS)" -ifdef BUILD_PSAMPLE - $(MAKE) -C $(SDK)/systems/linux/kernel/modules kernel_version=$(kernel_version) \ - subdirs="psample" override-target=linux-$(platform) CFLAGS="$(CFLAGS)" -endif ifdef BUILD_KNET_CB $(MAKE) -C $(SDK)/systems/linux/kernel/modules kernel_version=$(kernel_version) \ subdirs="knet-cb" override-target=linux-$(platform) CFLAGS="$(CFLAGS)" @@ -201,11 +193,6 @@ $(BCM_KNET): $(KERN_BLDROOT)/linux-bcm-knet.$(KOBJ) $(KNET_CB): $(KERN_BLDROOT)/linux-knet-cb.$(KOBJ) $(OBJCOPY) --strip-debug $< $@ -$(PSAMPLE): $(KERN_BLDROOT)/psample.$(KOBJ) - $(OBJCOPY) --strip-debug $< $@ - - - ifeq ($(NO_LOCAL_TARGETS),) $(foreach targ,$(LOCAL_TARGETS),$(eval $(call LOCAL_TARGET_DEF,$(targ)))) endif @@ -214,7 +201,7 @@ clean:: $(MAKE) -C $(SDK)/systems/bde/linux/kernel $@ $(MAKE) -C $(SDK)/systems/bde/linux/user/kernel $@ $(MAKE) -C $(SDK)/systems/linux/kernel/modules \ - subdirs="shared bcm-knet knet-cb psample" \ + subdirs="shared bcm-knet knet-cb" \ override-target=linux-$(platform) $@ $(RM) $(KERNEL_BDE) $(USER_BDE) $(RM) $(BCM_KNET) $(KNET_CB) $(PSAMPLE) @@ -222,7 +209,6 @@ clean:: $(RM) $(KERN_BLDROOT)/linux-user-bde.$(KOBJ) $(RM) $(KERN_BLDROOT)/linux-bcm-knet.$(KOBJ) $(RM) $(KERN_BLDROOT)/linux-knet-cb.$(KOBJ) - $(RM) $(KERN_BLDROOT)/psample.$(KOBJ) $(RM) $(LOCAL_TARGETS) distclean:: clean diff --git a/src/sonic-linux-kernel b/src/sonic-linux-kernel index b9083b1a271e..fdd9bac78cfc 160000 --- a/src/sonic-linux-kernel +++ b/src/sonic-linux-kernel @@ -1 +1 @@ -Subproject commit b9083b1a271e63757bef4fcd914ed524bd3c35c9 +Subproject commit fdd9bac78cfc2bbe932833b38c2191b1d382ed07 From 53a281008a96edcc22d0536ca4357a18f071c04e Mon Sep 17 00:00:00 2001 From: bingwang-ms <66248323+bingwang-ms@users.noreply.github.com> Date: Wed, 17 Aug 2022 08:58:35 +0800 Subject: [PATCH 005/151] Update Yang for pfc_enable field (#11747) Why I did it This PR is to update Yang model for pfc_enable and pfcwd_sw_enable fields to support more than 2 queues, like 2,3,4,6. Before this change, the regex "[0-7](,[0-7])?" accepts only no more than 2 queues. How I did it Update the regex pattern for pfc_enable and pfcwd_sw_enable, from "[0-7](,[0-7])?" to "[0-7](,[0-7])* How to verify it The change is verified by UT. The test input is updated to cover the change. collected 3 items tests/test_sonic_yang_models.py .. [ 66%] tests/yang_model_tests/test_yang_model.py . --- .../tests/yang_model_tests/tests_config/qosmaps.json | 4 ++-- src/sonic-yang-models/yang-models/sonic-port-qos-map.yang | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/sonic-yang-models/tests/yang_model_tests/tests_config/qosmaps.json b/src/sonic-yang-models/tests/yang_model_tests/tests_config/qosmaps.json index a05d80631f1f..0992f8776df8 100644 --- a/src/sonic-yang-models/tests/yang_model_tests/tests_config/qosmaps.json +++ b/src/sonic-yang-models/tests/yang_model_tests/tests_config/qosmaps.json @@ -669,8 +669,8 @@ "pfc_to_pg_map": "map1", "dscp_to_tc_map": "map1", "dot1p_to_tc_map": "map1", - "pfc_enable": "3,4", - "pfcwd_sw_enable" : "3,4" + "pfc_enable": "2,3,4,6", + "pfcwd_sw_enable" : "2,3,4,6" } ] } diff --git a/src/sonic-yang-models/yang-models/sonic-port-qos-map.yang b/src/sonic-yang-models/yang-models/sonic-port-qos-map.yang index 53ef7f48f5b7..09dcb7ce9c39 100644 --- a/src/sonic-yang-models/yang-models/sonic-port-qos-map.yang +++ b/src/sonic-yang-models/yang-models/sonic-port-qos-map.yang @@ -82,13 +82,13 @@ module sonic-port-qos-map { leaf pfc_enable { type string { - pattern "[0-7](,[0-7])?"; + pattern "[0-7](,[0-7])*"; } } leaf pfcwd_sw_enable { type string { - pattern "[0-7](,[0-7])?"; + pattern "[0-7](,[0-7])*"; } description "Specify the queue(s) on which software pfc watchdog are enabled."; From abda50c791d21f94e331ff50b8eb692b6c191ba1 Mon Sep 17 00:00:00 2001 From: Junhua Zhai Date: Wed, 17 Aug 2022 04:48:40 +0000 Subject: [PATCH 006/151] Correct port index in Arista-720DT-48S/phy24_config.json (#11699) Port index 22 is associated with phy23_config.json, then same port index 22 in phy24_config.json may cause gearbox port creation error. Port Ethernet22 maps to index 23. --- .../x86_64-arista_720dt_48s/Arista-720DT-48S/phy24_config.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/device/arista/x86_64-arista_720dt_48s/Arista-720DT-48S/phy24_config.json b/device/arista/x86_64-arista_720dt_48s/Arista-720DT-48S/phy24_config.json index 2a781875b0b2..31b86a0bc5cb 100644 --- a/device/arista/x86_64-arista_720dt_48s/Arista-720DT-48S/phy24_config.json +++ b/device/arista/x86_64-arista_720dt_48s/Arista-720DT-48S/phy24_config.json @@ -14,7 +14,7 @@ ], "ports": [ { - "index": 22, + "index": 23, "mdio_addr": "", "system_speed": 1000, "system_fec": "none", From 5846cdddfefd8a8ab6fe479a62a43fe1559103fe Mon Sep 17 00:00:00 2001 From: jingwenxie Date: Wed, 17 Aug 2022 14:17:46 +0800 Subject: [PATCH 007/151] Add yang_config_validation in device_info (#11715) Why I did it Put yang_config_validation in common lib and make it reusabe How I did it Move the definition to device_info.py --- src/sonic-py-common/sonic_py_common/device_info.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/sonic-py-common/sonic_py_common/device_info.py b/src/sonic-py-common/sonic_py_common/device_info.py index 73654b8819b8..6126dd6dd284 100644 --- a/src/sonic-py-common/sonic_py_common/device_info.py +++ b/src/sonic-py-common/sonic_py_common/device_info.py @@ -403,6 +403,10 @@ def get_chassis_info(): return chassis_info_dict + +def is_yang_config_validation_enabled(config_db): + return get_localhost_info('yang_config_validation', config_db) == 'enable' + # # Multi-NPU functionality # From 2bb8306d8e20d798f89535eff9ab57f6f5b2e177 Mon Sep 17 00:00:00 2001 From: suresh-rupanagudi <52159821+suresh-rupanagudi@users.noreply.github.com> Date: Thu, 18 Aug 2022 01:59:40 +0530 Subject: [PATCH 008/151] upstream snmp sonic-yang files (#10828) Fix #10549 Fix #10550 #### Why I did it Create sonic yang model for SNMP Tables:SNMP, SNMP_COMMUNITY #### How I did it Defined yang models based for SNMP based on snmp.yml #### How to verify it Added test cases to verify --- src/sonic-yang-models/setup.py | 2 + .../tests/files/sample_config_db.json | 20 ++++- .../tests/yang_model_tests/tests/snmp.json | 28 +++++++ .../yang_model_tests/tests_config/snmp.json | 83 +++++++++++++++++++ .../yang-models/sonic-snmp.yang | 74 +++++++++++++++++ 5 files changed, 206 insertions(+), 1 deletion(-) create mode 100644 src/sonic-yang-models/tests/yang_model_tests/tests/snmp.json create mode 100644 src/sonic-yang-models/tests/yang_model_tests/tests_config/snmp.json create mode 100644 src/sonic-yang-models/yang-models/sonic-snmp.yang diff --git a/src/sonic-yang-models/setup.py b/src/sonic-yang-models/setup.py index 6e998737636e..ee4f7e55bca8 100644 --- a/src/sonic-yang-models/setup.py +++ b/src/sonic-yang-models/setup.py @@ -128,6 +128,7 @@ def run(self): './yang-models/sonic-route-map.yang', './yang-models/sonic-routing-policy-sets.yang', './yang-models/sonic-sflow.yang', + './yang-models/sonic-snmp.yang', './yang-models/sonic-syslog.yang', './yang-models/sonic-system-aaa.yang', './yang-models/sonic-system-tacacs.yang', @@ -190,6 +191,7 @@ def run(self): './cvlyang-models/sonic-route-map.yang', './cvlyang-models/sonic-routing-policy-sets.yang', './cvlyang-models/sonic-sflow.yang', + './cvlyang-models/sonic-snmp.yang', './cvlyang-models/sonic-system-aaa.yang', './cvlyang-models/sonic-system-tacacs.yang', './cvlyang-models/sonic-telemetry.yang', diff --git a/src/sonic-yang-models/tests/files/sample_config_db.json b/src/sonic-yang-models/tests/files/sample_config_db.json index 332172d925c1..db7798f31835 100644 --- a/src/sonic-yang-models/tests/files/sample_config_db.json +++ b/src/sonic-yang-models/tests/files/sample_config_db.json @@ -1924,10 +1924,28 @@ ] } }, + + "SNMP": { + "CONTACT": { + "Contact": "testuser@contoso.com" + }, + "LOCATION": { + "Location": "SNMP Server Location" + } + }, + "SNMP_COMMUNITY": { + "public": { + "TYPE": "RO" + }, + "private": { + "TYPE": "RW" + } + }, + "SYSTEM_DEFAULTS": { "tunnel_qos_remap": { "status": "enabled" - } + } }, "LOSSLESS_TRAFFIC_PATTERN": { "AZURE": { diff --git a/src/sonic-yang-models/tests/yang_model_tests/tests/snmp.json b/src/sonic-yang-models/tests/yang_model_tests/tests/snmp.json new file mode 100644 index 000000000000..8c4754462830 --- /dev/null +++ b/src/sonic-yang-models/tests/yang_model_tests/tests/snmp.json @@ -0,0 +1,28 @@ +{ + "SNMP_SYSTEM_TEST": { + "desc": "Load SNMP sysContact and sysLocation." + }, + "SNMP_SYSTEM_CONTACT_NEG_TEST": { + "desc": "Load SNMP sysContact with empty string", + "eStrKey": "Range" + }, + "SNMP_SYSTEM_LOCATION_NEG_TEST": { + "desc": "Load SNMP sysContact with empty string", + "eStrKey": "Range" + }, + "SNMP_COMMUNITY_TEST": { + "desc": "Load SNMP community string." + }, + "SNMP_COMMUNITY_MIN_NEG_TEST": { + "desc": "Load SNMP community string of length < 3.", + "eStrKey": "Range" + }, + "SNMP_COMMUNITY_MAX_NEG_TEST": { + "desc": "Load SNMP community string of lenth > 32.", + "eStrKey": "Range" + }, + "SNMP_COMMUNITY_WRONG_TYPE_TEST": { + "desc": "Load SNMP community string with un supported type.", + "eStrKey": "InvalidValue" + } +} diff --git a/src/sonic-yang-models/tests/yang_model_tests/tests_config/snmp.json b/src/sonic-yang-models/tests/yang_model_tests/tests_config/snmp.json new file mode 100644 index 000000000000..31c2f838d343 --- /dev/null +++ b/src/sonic-yang-models/tests/yang_model_tests/tests_config/snmp.json @@ -0,0 +1,83 @@ +{ + "SNMP_SYSTEM_TEST": { + "sonic-snmp:sonic-snmp": { + "sonic-snmp:SNMP": { + "CONTACT": { + "Contact": "support@xyz.com" + }, + "LOCATION": { + "Location": "Test location" + } + } + } + }, + "SNMP_SYSTEM_CONTACT_NEG_TEST": { + "sonic-snmp:sonic-snmp": { + "sonic-snmp:SNMP": { + "CONTACT": { + "Contact": "" + } + } + } + }, + "SNMP_SYSTEM_LOCATION_NEG_TEST": { + "sonic-snmp:sonic-snmp": { + "sonic-snmp:SNMP": { + "LOCATION": { + "Location": "" + } + } + } + }, + + "SNMP_COMMUNITY_TEST": { + "sonic-snmp:sonic-snmp": { + "sonic-snmp:SNMP_COMMUNITY": { + "SNMP_COMMUNITY_LIST": [ + { + "name": "sonicSnmp", + "TYPE": "RO" + }, + { + "name": "sonicSnmpRW", + "TYPE": "RW" + } + ] + } + } + }, + "SNMP_COMMUNITY_MIN_NEG_TEST": { + "sonic-snmp:sonic-snmp": { + "sonic-snmp:SNMP_COMMUNITY": { + "SNMP_COMMUNITY_LIST": [ + { + "name": "abc" + } + ] + } + } + }, + "SNMP_COMMUNITY_MAX_NEG_TEST": { + "sonic-snmp:sonic-snmp": { + "sonic-snmp:SNMP_COMMUNITY": { + "SNMP_COMMUNITY_LIST": [ + { + "name": "01234567890123456789012345678901234" + } + ] + } + } + }, + "SNMP_COMMUNITY_WRONG_TYPE_TEST": { + "sonic-snmp:sonic-snmp": { + "sonic-snmp:SNMP_COMMUNITY": { + "SNMP_COMMUNITY_LIST": [ + { + "name": "sonicSnmp", + "TYPE": "RR" + } + ] + } + } + } +} diff --git a/src/sonic-yang-models/yang-models/sonic-snmp.yang b/src/sonic-yang-models/yang-models/sonic-snmp.yang new file mode 100644 index 000000000000..7e3db7b5dd09 --- /dev/null +++ b/src/sonic-yang-models/yang-models/sonic-snmp.yang @@ -0,0 +1,74 @@ +module sonic-snmp { + namespace "http://github.com/Azure/sonic-snmp"; + prefix ssnmp; + yang-version 1.1; + + + organization + "SONiC"; + + contact + "SONiC"; + + description + "SONIC SNMP"; + + revision 2022-05-13 { + description + "Initial revision."; + } + + + container sonic-snmp { + + container SNMP { + container CONTACT { + leaf Contact { + type string { + length "1..255"; + } + description + "SNMP System Contact."; + } + } + container LOCATION { + leaf Location { + type string { + length "1..255"; + } + description + "SNMP System Location."; + } + + } + } + + container SNMP_COMMUNITY { + list SNMP_COMMUNITY_LIST { + key name; + description + "List of communities."; + + leaf name { + type string { + length "4..32"; + pattern '[^ @,\\' +"']*" { + error-message 'Invalid snmp community string (Valid chars are ASCII printable except SPACE, single quote,"@", "," and "\")'; + } + } + description + "Index into the community list which must be the community name."; + } + + leaf TYPE { + type enumeration { + enum RO; + enum RW; + } + description + "Type of community, read-only or read-write."; + } + } + } + } +} From 535612f808a29960233813831575e844307c54f6 Mon Sep 17 00:00:00 2001 From: abdosi <58047199+abdosi@users.noreply.github.com> Date: Wed, 17 Aug 2022 14:02:21 -0700 Subject: [PATCH 009/151] Added support to add gbsyncd in Feature Table of Host Config DB (#11754) Why I did: In case of multi-asic platforms gbsyncd is not getting added to Feature Table of Host Config DB. Without this container_checker complains of not needed gbsyncd container's are running. How I did: Update Both Host and Namespace config db when gbsyncd docker is starting. How I verify: Verified on Multi-asic platforms. --- files/scripts/gbsyncd.sh | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/files/scripts/gbsyncd.sh b/files/scripts/gbsyncd.sh index 0990de5d8257..a7eaaced0cd6 100755 --- a/files/scripts/gbsyncd.sh +++ b/files/scripts/gbsyncd.sh @@ -3,11 +3,15 @@ . /usr/local/bin/syncd_common.sh function startplatform() { - # Add gbsyncd to FEATURE table, if not in. It did have same config as syncd. - if [ -z $($SONIC_DB_CLI CONFIG_DB HGET 'FEATURE|gbsyncd' state) ]; then - local CMD="local r=redis.call('DUMP', KEYS[1]); redis.call('RESTORE', KEYS[2], 0, r)" - $SONIC_DB_CLI CONFIG_DB EVAL "$CMD" 2 'FEATURE|syncd' 'FEATURE|gbsyncd' - fi + + declare -a DbCliArray=($SONIC_DB_CLI $SONIC_DB_NS_CLI) + for DB_CLI in ${DbCliArray[@]}; do + # Add gbsyncd to FEATURE table, if not in. It did have same config as syncd. + if [ -z $($DB_CLI CONFIG_DB HGET 'FEATURE|gbsyncd' state) ]; then + local CMD="local r=redis.call('DUMP', KEYS[1]); redis.call('RESTORE', KEYS[2], 0, r)" + $DB_CLI CONFIG_DB EVAL "$CMD" 2 'FEATURE|syncd' 'FEATURE|gbsyncd' + fi + done } function waitplatform() { @@ -30,12 +34,11 @@ PEER="swss" DEBUGLOG="/tmp/swss-$SERVICE-debug$DEV.log" LOCKFILE="/tmp/swss-$SERVICE-lock$DEV" NAMESPACE_PREFIX="asic" +SONIC_DB_CLI="sonic-db-cli" +SONIC_DB_NS_CLI="sonic-db-cli" if [ "$DEV" ]; then NET_NS="$NAMESPACE_PREFIX$DEV" #name of the network namespace - SONIC_DB_CLI="sonic-db-cli -n $NET_NS" -else - NET_NS="" - SONIC_DB_CLI="sonic-db-cli" + SONIC_DB_NS_CLI="sonic-db-cli -n $NET_NS" fi case "$1" in From 5d9a46369593c623be9dab794bed1e96bac3bcfd Mon Sep 17 00:00:00 2001 From: Mai Bui Date: Wed, 17 Aug 2022 17:30:58 -0400 Subject: [PATCH 010/151] Replace strtok in systemd-sonic-generator (#11710) Signed-off-by: maipbui #### Why I did it Replace unsafe functions to safe functions #### How I did it Replace `strtok()` by `strtok_r()` #### How to verify it #### Which release branch to backport (provide reason below if selected) - [ ] 201811 - [ ] 201911 - [ ] 202006 - [ ] 202012 - [ ] 202106 - [ ] 202111 - [ ] 202205 #### Description for the changelog #### Link to config_db schema for YANG module changes #### A picture of a cute animal (not mandatory but encouraged) --- .../systemd-sonic-generator.c | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/src/systemd-sonic-generator/systemd-sonic-generator.c b/src/systemd-sonic-generator/systemd-sonic-generator.c index 96193b9fe3e3..0c419893c35b 100644 --- a/src/systemd-sonic-generator/systemd-sonic-generator.c +++ b/src/systemd-sonic-generator/systemd-sonic-generator.c @@ -121,6 +121,7 @@ static int get_install_targets_from_line(char* target_string, char* install_type ***/ char* token; char* target; + char* saveptr; char final_target[PATH_MAX]; int num_targets = 0; @@ -135,8 +136,8 @@ static int get_install_targets_from_line(char* target_string, char* install_type strip_trailing_newline(target); if (strstr(target, "%") != NULL) { - char* prefix = strtok(target, "."); - char* suffix = strtok(NULL, "."); + char* prefix = strtok_r(target, ".", &saveptr); + char* suffix = strtok_r(NULL, ".", &saveptr); int prefix_len = strlen(prefix); strncpy(final_target, prefix, prefix_len - 2); @@ -516,6 +517,7 @@ int get_num_of_asic() { char *line = NULL; char* token; char* platform; + char* saveptr; size_t len = 0; ssize_t nread; bool ans; @@ -534,8 +536,8 @@ int get_num_of_asic() { while ((nread = getline(&line, &len, fp)) != -1) { if ((strstr(line, "onie_platform") != NULL) || (strstr(line, "aboot_platform") != NULL)) { - token = strtok(line, "="); - platform = strtok(NULL, "="); + token = strtok_r(line, "=", &saveptr); + platform = strtok_r(NULL, "=", &saveptr); strip_trailing_newline(platform); break; } @@ -547,8 +549,8 @@ int get_num_of_asic() { if (fp != NULL) { while ((nread = getline(&line, &len, fp)) != -1) { if (strstr(line, "NUM_ASIC") != NULL) { - token = strtok(line, "="); - str_num_asic = strtok(NULL, "="); + token = strtok_r(line, "=", &saveptr); + str_num_asic = strtok_r(NULL, "=", &saveptr); strip_trailing_newline(str_num_asic); if (str_num_asic != NULL){ sscanf(str_num_asic, "%d",&num_asic); @@ -571,6 +573,7 @@ int ssg_main(int argc, char **argv) { char* unit_instance; char* prefix; char* suffix; + char* saveptr; int num_unit_files; int num_targets; int r; @@ -589,8 +592,8 @@ int ssg_main(int argc, char **argv) { for (int i = 0; i < num_unit_files; i++) { unit_instance = strdup(unit_files[i]); if ((num_asics == 1) && strstr(unit_instance, "@") != NULL) { - prefix = strtok(unit_instance, "@"); - suffix = strtok(NULL, "@"); + prefix = strtok_r(unit_instance, "@", &saveptr); + suffix = strtok_r(NULL, "@", &saveptr); strcpy(unit_instance, prefix); strcat(unit_instance, suffix); From 3e427419eef2404e82611b151892dcd696f7b527 Mon Sep 17 00:00:00 2001 From: Jing Zhang Date: Wed, 17 Aug 2022 21:34:19 -0700 Subject: [PATCH 011/151] [master][sonic-linkmgrd] submodule update (#11749) [master][sonic-linkmgrd] submodule update 4bf8b3d Jing Zhang Fri Aug 12 12:07:40 2022 -0700 wait for handler to be completed (#114) cf849a0 Longxiang Lyu Fri Aug 12 17:21:43 2022 +0800 Use table to toggle peer forwarding state (#108) d4540ba Jing Zhang Thu Aug 11 16:08:03 2022 -0700 Adjust DbInterfaceRaceConditionCheck to Wait Longer for Handlers to be executed (#111) d5c47b3 Jing Zhang Thu Aug 11 15:31:22 2022 -0700 [lgtm]: add uuid-dev to lgtm prepare (#112) f4bb5d5 Jing Zhang Thu Aug 11 10:03:05 2022 -0700 Backoff mux probing for server down scenario (#106) 3f7a6f2 Jing Zhang Tue Aug 9 10:42:51 2022 -0700 Fix race condition caused by strand wrap method (#104) 4cff43f Jing Zhang Mon Aug 8 10:36:18 2022 -0700 [Active-Standby]Remove unnecessary handleMuxWaitTimeout logs (#100) 3b22533 Jing Zhang Tue Aug 2 13:18:01 2022 -0700 [active-active] Update unhealthy label definition (#102) sign-off: Jing Zhang zhangjing@microsoft.com --- src/linkmgrd | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/linkmgrd b/src/linkmgrd index 60b370dee69e..4bf8b3df8bde 160000 --- a/src/linkmgrd +++ b/src/linkmgrd @@ -1 +1 @@ -Subproject commit 60b370dee69e937cf15de24985875e089974c89d +Subproject commit 4bf8b3df8bdebf1633b2dd54100aa1c6939fa7d8 From ca546ddec380c77c7d30558435f40c0e2460ca4c Mon Sep 17 00:00:00 2001 From: jerseyang <48576574+jerseyang@users.noreply.github.com> Date: Thu, 18 Aug 2022 12:56:04 +0800 Subject: [PATCH 012/151] Sync platform-modules-belgite deb's kernel version 5.10.0-8-2 with master runtime kernel version 5.10.0-12-2 (#10946) # Why I did it platform-modules-belgite's deb requests linux-image-5.10.0-8-2-amd64-unsigned, which does not match the runtime kernel version # How I did it update the belgite's deb configuration in deb's control # How to verify it check the firsttime boot log in belgite platform Co-authored-by: nicwu-cel --- device/celestica/x86_64-cel_belgite-r0/installer.conf | 2 +- platform/broadcom/platform-modules-cel.mk | 2 +- platform/broadcom/sonic-platform-modules-cel/debian/control | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/device/celestica/x86_64-cel_belgite-r0/installer.conf b/device/celestica/x86_64-cel_belgite-r0/installer.conf index 61846e4455e0..430473933330 100644 --- a/device/celestica/x86_64-cel_belgite-r0/installer.conf +++ b/device/celestica/x86_64-cel_belgite-r0/installer.conf @@ -1,4 +1,4 @@ CONSOLE_PORT=0x3f8 CONSOLE_DEV=0 CONSOLE_SPEED=9600 -ONIE_PLATFORM_EXTRA_CMDLINE_LINUX="intel_iommu=off module_blacklist=gpio_ich crashkernel=0M-2G:256M,2G-4G:320M,4G-8G:384M,8G-:448M acpi_no_watchdog" +ONIE_PLATFORM_EXTRA_CMDLINE_LINUX="intel_iommu=off modprobe.blacklist=gpio_ich,i2c-ismt,i2c_ismt,i2c-i801,i2c_i801 crashkernel=0M-2G:256M,2G-4G:320M,4G-8G:384M,8G-:448M acpi_no_watchdog" diff --git a/platform/broadcom/platform-modules-cel.mk b/platform/broadcom/platform-modules-cel.mk index d485f128c6c2..b25aeb7c0900 100644 --- a/platform/broadcom/platform-modules-cel.mk +++ b/platform/broadcom/platform-modules-cel.mk @@ -14,7 +14,7 @@ export CEL_BELGITE_PLATFORM_MODULE_VERSION CEL_DX010_PLATFORM_MODULE = platform-modules-dx010_$(CEL_DX010_PLATFORM_MODULE_VERSION)_amd64.deb $(CEL_DX010_PLATFORM_MODULE)_SRC_PATH = $(PLATFORM_PATH)/sonic-platform-modules-cel -$(CEL_DX010_PLATFORM_MODULE)_DEPENDS += $(LINUX_HEADERS) $(LINUX_HEADERS_COMMON) +$(CEL_DX010_PLATFORM_MODULE)_DEPENDS += $(LINUX_HEADERS) $(LINUX_HEADERS_COMMON) $(PDDF_PLATFORM_MODULE_SYM) $(CEL_DX010_PLATFORM_MODULE)_PLATFORM = x86_64-cel_seastone-r0 SONIC_DPKG_DEBS += $(CEL_DX010_PLATFORM_MODULE) diff --git a/platform/broadcom/sonic-platform-modules-cel/debian/control b/platform/broadcom/sonic-platform-modules-cel/debian/control index 2ba492829d26..a47dae2639a4 100644 --- a/platform/broadcom/sonic-platform-modules-cel/debian/control +++ b/platform/broadcom/sonic-platform-modules-cel/debian/control @@ -28,5 +28,5 @@ Description: kernel modules for platform devices such as led, sfp. Package: platform-modules-belgite Architecture: amd64 -Depends: linux-image-5.10.0-8-2-amd64-unsigned +Depends: linux-image-5.10.0-12-2-amd64-unsigned Description: kernel modules for platform devices such as led, sfp From 46ebd06403172e3dee3b43d27f09f9813c9d6bce Mon Sep 17 00:00:00 2001 From: Junchao-Mellanox <57339448+Junchao-Mellanox@users.noreply.github.com> Date: Thu, 18 Aug 2022 18:07:38 +0800 Subject: [PATCH 013/151] [Mellanox] Fix issue: set lpmode by platform API does not work (#11732) - Why I did it Fix issue: set lpmode by platform API does not work - How I did it Fix miss return value in code - How to verify it Manual test --- platform/mellanox/mlnx-platform-api/sonic_platform/sfp.py | 4 +++- platform/mellanox/mlnx-platform-api/tests/test_sfp.py | 8 ++++++++ 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/platform/mellanox/mlnx-platform-api/sonic_platform/sfp.py b/platform/mellanox/mlnx-platform-api/sonic_platform/sfp.py index 3ee8b348ce00..617b4f33d636 100644 --- a/platform/mellanox/mlnx-platform-api/sonic_platform/sfp.py +++ b/platform/mellanox/mlnx-platform-api/sonic_platform/sfp.py @@ -53,6 +53,8 @@ SX_PORT_MODULE_STATUS_UNPLUGGED = 2 SX_PORT_MODULE_STATUS_PLUGGED_WITH_ERROR = 3 SX_PORT_MODULE_STATUS_PLUGGED_DISABLED = 4 + SX_PORT_ADMIN_STATUS_UP = True + SX_PORT_ADMIN_STATUS_DOWN = False except KeyError: pass @@ -571,7 +573,7 @@ def _fetch_port_status(cls, sdk_handle, log_port): @classmethod def is_port_admin_status_up(cls, sdk_handle, log_port): _, admin_state = cls._fetch_port_status(sdk_handle, log_port); - admin_state == SX_PORT_ADMIN_STATUS_UP + return admin_state == SX_PORT_ADMIN_STATUS_UP @classmethod diff --git a/platform/mellanox/mlnx-platform-api/tests/test_sfp.py b/platform/mellanox/mlnx-platform-api/tests/test_sfp.py index b932856fa38c..f599e0241d25 100644 --- a/platform/mellanox/mlnx-platform-api/tests/test_sfp.py +++ b/platform/mellanox/mlnx-platform-api/tests/test_sfp.py @@ -111,3 +111,11 @@ def test_sfp_read_eeprom(self): sfp = SFP(0) assert output_sfp.y_cable_part_number == sfp.read_eeprom(offset, 16).decode() MlxregManager.read_mlxred_eeprom.assert_called_with(132, 4, 16) + + @mock.patch('sonic_platform.sfp.SFP._fetch_port_status') + def test_is_port_admin_status_up(self, mock_port_status): + mock_port_status.return_value = (0, True) + assert SFP.is_port_admin_status_up(None, None) + + mock_port_status.return_value = (0, False) + assert not SFP.is_port_admin_status_up(None, None) From 3ea5e83332b2aa2b0c2bc77c41b7e90eaa01be9f Mon Sep 17 00:00:00 2001 From: Muhammad Danish <88161975+mdanish-kh@users.noreply.github.com> Date: Fri, 19 Aug 2022 03:19:54 +0500 Subject: [PATCH 014/151] [doc] Update README.md (#11647) #### Why I did it - Building `sonic-$PLATFORM.img.gz` fails if KVM support is not enabled. - Repos have been transferred over from Azure to sonic-net domain - sonic-net repos no longer use Microsoft CLA, so updated the README to point towards Linux foundation CLA - p4 platform is no longer supported. Reference: https://github.com/sonic-net/sonic-buildimage/issues/2591#issuecomment-649425081 --- README.md | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index a3ca0cdb4e30..92684138845d 100644 --- a/README.md +++ b/README.md @@ -88,7 +88,7 @@ # Description -Following is the instruction on how to build an [(ONIE)](https://github.com/opencomputeproject/onie) compatible network operating system (NOS) installer image for network switches, and also how to build docker images running inside the NOS. Note that SONiC image are build per ASIC platform. Switches using the same ASIC platform share a common image. For a list of supported switches and ASIC, please refer to this [list](https://github.com/Azure/SONiC/wiki/Supported-Devices-and-Platforms) +Following is the instruction on how to build an [(ONIE)](https://github.com/opencomputeproject/onie) compatible network operating system (NOS) installer image for network switches, and also how to build docker images running inside the NOS. Note that SONiC image are build per ASIC platform. Switches using the same ASIC platform share a common image. For a list of supported switches and ASIC, please refer to this [list](https://github.com/sonic-net/SONiC/wiki/Supported-Devices-and-Platforms) # Hardware @@ -97,6 +97,8 @@ Any server can be a build image server as long as it has: * Multiple cores to increase build speed * Plenty of RAM (less than 8 GiB is likely to cause issues) * 300G of free disk space + * KVM Virtualization Support. +> Note: If you are in a VM, make sure you have support for nested virtualization. A good choice of OS for building SONiC is currently Ubuntu 20.04. @@ -116,7 +118,7 @@ sudo pip3 install j2cli ## Clone or fetch the code repository with all git submodules To clone the code repository recursively, assuming git version 1.9 or newer: - git clone https://github.com/Azure/sonic-buildimage.git + git clone https://github.com/sonic-net/sonic-buildimage.git ## Usage @@ -151,7 +153,6 @@ To build SONiC installer image and docker images, run the following commands: - PLATFORM=centec - PLATFORM=nephos - PLATFORM=innovium -- PLATFORM=p4 - PLATFORM=vs ## Usage for ARM Architecture @@ -238,10 +239,10 @@ Every target has a clean target, so in order to clean swss, execute: It is recommended to use clean targets to clean all packages that are built together, like dev packages for instance. In order to be more familiar with build process and make some changes to it, it is recommended to read this short [Documentation](README.buildsystem.md). ## Build debug dockers and debug SONiC installer image: -SONiC build system supports building dockers and ONIE-image with debug tools and debug symbols, to help with live & core debugging. For details refer to [(SONiC Buildimage Guide)](https://github.com/Azure/sonic-buildimage/blob/master/README.buildsystem.md). +SONiC build system supports building dockers and ONIE-image with debug tools and debug symbols, to help with live & core debugging. For details refer to [(SONiC Buildimage Guide)](https://github.com/sonic-net/sonic-buildimage/blob/master/README.buildsystem.md). ## SAI Version -Please refer to [SONiC roadmap](https://github.com/Azure/SONiC/wiki/Sonic-Roadmap-Planning) on the SAI version for each SONiC release. +Please refer to [SONiC roadmap](https://github.com/sonic-net/SONiC/wiki/Sonic-Roadmap-Planning) on the SAI version for each SONiC release. ## Notes: - If you are running make for the first time, a sonic-slave-${USER} docker image will be built automatically. @@ -263,11 +264,11 @@ This may take a while, but it is a one-time action, so please be patient. - docker-syncd-invm.gz: docker image for the daemon to sync database and Innovium switch ASIC (gzip tar archive) - docker-sonic-p4.gz: docker image for all-in-one for p4 software switch (gzip tar archive) - docker-sonic-vs.gz: docker image for all-in-one for software virtual switch (gzip tar archive) - - docker-sonic-mgmt.gz: docker image for [managing, configuring and monitoring SONiC](https://github.com/Azure/sonic-mgmt) (gzip tar archive) + - docker-sonic-mgmt.gz: docker image for [managing, configuring and monitoring SONiC](https://github.com/sonic-net/sonic-mgmt) (gzip tar archive) ## Contribution Guide -All contributors must sign a contribution license agreement before contributions can be accepted. Contact [sonic-cla-agreements@microsoft.com](mailto:sonic-cla-agreements@microsoft.com). +All contributors must sign a contribution license agreement before contributions can be accepted. Visit [EasyCLA - Linux Foundation](https://easycla.lfx.linuxfoundation.org). ## GitHub Workflow From 56a679dc09081b41f55e3671a914eb9c7e4b0d8f Mon Sep 17 00:00:00 2001 From: geogchen <106694330+geogchen@users.noreply.github.com> Date: Fri, 19 Aug 2022 01:40:08 -0700 Subject: [PATCH 015/151] [Bgpcfgd] Enhance add_peer/add_peer_ipv6 unit tests (#11651) * [Bgpcfgd] Enhance add_peer/add_peer_ipv6 unit tests Why I did it The current input to add_peer/add_peer_ipv6 is admin status change, update the UT to supply new peer information. Current UT does not check for case when check_neig_meta is true, update UT to check for this case How I did it By changing the input to add_peer/add_peer_ipv6 By modifying load_constants/constructor to take constants path as an input, and add two UT that uses a version of constants.yml that sets check_neig_meta to true. How to verify it UT failing before the change, and passing after the change. --- .../data/constants/constants_use_neig.yml | 60 ++++++++++ src/sonic-bgpcfgd/tests/test_bgp.py | 109 +++++++++++------- src/sonic-bgpcfgd/tests/util.py | 4 +- 3 files changed, 129 insertions(+), 44 deletions(-) create mode 100644 src/sonic-bgpcfgd/tests/data/constants/constants_use_neig.yml diff --git a/src/sonic-bgpcfgd/tests/data/constants/constants_use_neig.yml b/src/sonic-bgpcfgd/tests/data/constants/constants_use_neig.yml new file mode 100644 index 000000000000..12144a8783b9 --- /dev/null +++ b/src/sonic-bgpcfgd/tests/data/constants/constants_use_neig.yml @@ -0,0 +1,60 @@ +constants: + deployment_id_asn_map: + "1" : 65432 + "2" : 65433 + bgp: + traffic_shift_community: 12345:12345 + families: + - ipv4 + - ipv6 + use_deployment_id: false + use_neighbors_meta: true + graceful_restart: + enabled: true + restart_time: 240 + multipath_relax: + enabled: true + maximum_paths: + enabled: true + ipv4: 64 + ipv6: 64 + allow_list: + enabled: true + default_action: "permit" # or "deny" + drop_community: 5060:12345 # value of the community to identify a prefix to drop. Make sense only with allow_list_default_action equal to 'permit' + default_pl_rules: + v4: + - "deny 0.0.0.0/0 le 17" + - "permit 127.0.0.1/32" + v6: + - "deny 0::/0 le 59" + - "deny 0::/0 ge 65" + bbr: + enabled: true + default_state: "disabled" + peers: + general: # peer_type + db_table: "BGP_NEIGHBOR" + template_dir: "general" + bbr: + PEER_V4: + - ipv4 + PEER_V6: + - ipv6 + internal: # peer_type + db_table: "BGP_INTERNAL_NEIGHBOR" + template_dir: "internal" + monitors: # peer_type + enabled: true + db_table: "BGP_MONITORS" + peer_group: "BGPMON" + template_dir: "monitors" + dynamic: # peer_type + enabled: true + db_table: "BGP_PEER_RANGE" + peer_group: "BGP_SPEAKER" + template_dir: "dynamic" + voq_chassis: # peer_type + enabled: true + db_table: "BGP_VOQ_CHASSIS_NEIGHBOR" + template_dir: "voq_chassis" diff --git a/src/sonic-bgpcfgd/tests/test_bgp.py b/src/sonic-bgpcfgd/tests/test_bgp.py index a4c5ef997725..d332dc4348ba 100644 --- a/src/sonic-bgpcfgd/tests/test_bgp.py +++ b/src/sonic-bgpcfgd/tests/test_bgp.py @@ -10,9 +10,20 @@ TEMPLATE_PATH = os.path.abspath('../../dockers/docker-fpm-frr/frr') -def constructor(): +def load_constant_files(): + paths = ["tests/data/constants", "../../files/image_config/constants"] + constant_files = [] + + for path in paths: + constant_files += [os.path.abspath(os.path.join(path, name)) for name in os.listdir(path) + if os.path.isfile(os.path.join(path, name)) and name.startswith("constants")] + + return constant_files + + +def constructor(constants_path): cfg_mgr = MagicMock() - constants = load_constants()['constants'] + constants = load_constants(constants_path)['constants'] common_objs = { 'directory': Directory(), 'cfg_mgr': cfg_mgr, @@ -38,75 +49,89 @@ def constructor(): m.directory.put("LOCAL", "interfaces", "Ethernet4|30.30.30.30/24", {"anything": "anything"}) m.directory.put("LOCAL", "interfaces", "Ethernet8|fc00:20::20/96", {"anything": "anything"}) + if m.check_neig_meta: + m.directory.put("CONFIG_DB", swsscommon.CFG_DEVICE_NEIGHBOR_METADATA_TABLE_NAME, "TOR", {}) + return m @patch('bgpcfgd.managers_bgp.log_info') def test_update_peer_up(mocked_log_info): - m = constructor() - res = m.set_handler("10.10.10.1", {"admin_status": "up"}) - assert res, "Expect True return value for peer update" - mocked_log_info.assert_called_with("Peer 'default|10.10.10.1' admin state is set to 'up'") + for constant in load_constant_files(): + m = constructor(constant) + res = m.set_handler("10.10.10.1", {"admin_status": "up"}) + assert res, "Expect True return value for peer update" + mocked_log_info.assert_called_with("Peer 'default|10.10.10.1' admin state is set to 'up'") @patch('bgpcfgd.managers_bgp.log_info') def test_update_peer_up_ipv6(mocked_log_info): - m = constructor() - res = m.set_handler("fc00:10::1", {"admin_status": "up"}) - assert res, "Expect True return value for peer update" - mocked_log_info.assert_called_with("Peer 'default|fc00:10::1' admin state is set to 'up'") + for constant in load_constant_files(): + m = constructor(constant) + res = m.set_handler("fc00:10::1", {"admin_status": "up"}) + assert res, "Expect True return value for peer update" + mocked_log_info.assert_called_with("Peer 'default|fc00:10::1' admin state is set to 'up'") @patch('bgpcfgd.managers_bgp.log_info') def test_update_peer_down(mocked_log_info): - m = constructor() - res = m.set_handler("10.10.10.1", {"admin_status": "down"}) - assert res, "Expect True return value for peer update" - mocked_log_info.assert_called_with("Peer 'default|10.10.10.1' admin state is set to 'down'") + for constant in load_constant_files(): + m = constructor(constant) + res = m.set_handler("10.10.10.1", {"admin_status": "down"}) + assert res, "Expect True return value for peer update" + mocked_log_info.assert_called_with("Peer 'default|10.10.10.1' admin state is set to 'down'") @patch('bgpcfgd.managers_bgp.log_err') def test_update_peer_no_admin_status(mocked_log_err): - m = constructor() - res = m.set_handler("10.10.10.1", {"anything": "anything"}) - assert res, "Expect True return value for peer update" - mocked_log_err.assert_called_with("Peer '(default|10.10.10.1)': Can't update the peer. Only 'admin_status' attribute is supported") + for constant in load_constant_files(): + m = constructor(constant) + res = m.set_handler("10.10.10.1", {"anything": "anything"}) + assert res, "Expect True return value for peer update" + mocked_log_err.assert_called_with("Peer '(default|10.10.10.1)': Can't update the peer. Only 'admin_status' attribute is supported") @patch('bgpcfgd.managers_bgp.log_err') def test_update_peer_invalid_admin_status(mocked_log_err): - m = constructor() - res = m.set_handler("10.10.10.1", {"admin_status": "invalid"}) - assert res, "Expect True return value for peer update" - mocked_log_err.assert_called_with("Peer 'default|10.10.10.1': Can't update the peer. It has wrong attribute value attr['admin_status'] = 'invalid'") + for constant in load_constant_files(): + m = constructor(constant) + res = m.set_handler("10.10.10.1", {"admin_status": "invalid"}) + assert res, "Expect True return value for peer update" + mocked_log_err.assert_called_with("Peer 'default|10.10.10.1': Can't update the peer. It has wrong attribute value attr['admin_status'] = 'invalid'") def test_add_peer(): - m = constructor() - res = m.set_handler("30.30.30.1", {"local_addr": "30.30.30.30", "admin_status": "up"}) - assert res, "Expect True return value" + for constant in load_constant_files(): + m = constructor(constant) + res = m.set_handler("30.30.30.1", {'asn': '65200', 'holdtime': '180', 'keepalive': '60', 'local_addr': '30.30.30.30', 'name': 'TOR', 'nhopself': '0', 'rrclient': '0'}) + assert res, "Expect True return value" def test_add_peer_ipv6(): - m = constructor() - res = m.set_handler("fc00:20::1", {"local_addr": "fc00:20::20", "admin_status": "up"}) - assert res, "Expect True return value" + for constant in load_constant_files(): + m = constructor(constant) + res = m.set_handler("fc00:20::1", {'asn': '65200', 'holdtime': '180', 'keepalive': '60', 'local_addr': 'fc00:20::20', 'name': 'TOR', 'nhopself': '0', 'rrclient': '0'}) + assert res, "Expect True return value" @patch('bgpcfgd.managers_bgp.log_warn') def test_add_peer_no_local_addr(mocked_log_warn): - m = constructor() - res = m.set_handler("30.30.30.1", {"admin_status": "up"}) - assert res, "Expect True return value" - mocked_log_warn.assert_called_with("Peer 30.30.30.1. Missing attribute 'local_addr'") + for constant in load_constant_files(): + m = constructor(constant) + res = m.set_handler("30.30.30.1", {"admin_status": "up"}) + assert res, "Expect True return value" + mocked_log_warn.assert_called_with("Peer 30.30.30.1. Missing attribute 'local_addr'") @patch('bgpcfgd.managers_bgp.log_debug') def test_add_peer_invalid_local_addr(mocked_log_debug): - m = constructor() - res = m.set_handler("30.30.30.1", {"local_addr": "40.40.40.40", "admin_status": "up"}) - assert not res, "Expect False return value" - mocked_log_debug.assert_called_with("Peer '30.30.30.1' with local address '40.40.40.40' wait for the corresponding interface to be set") + for constant in load_constant_files(): + m = constructor(constant) + res = m.set_handler("30.30.30.1", {"local_addr": "40.40.40.40", "admin_status": "up"}) + assert not res, "Expect False return value" + mocked_log_debug.assert_called_with("Peer '30.30.30.1' with local address '40.40.40.40' wait for the corresponding interface to be set") @patch('bgpcfgd.managers_bgp.log_info') def test_del_handler(mocked_log_info): - m = constructor() - m.del_handler("10.10.10.1") - mocked_log_info.assert_called_with("Peer '(default|10.10.10.1)' has been removed") + for constant in load_constant_files(): + m = constructor(constant) + m.del_handler("10.10.10.1") + mocked_log_info.assert_called_with("Peer '(default|10.10.10.1)' has been removed") @patch('bgpcfgd.managers_bgp.log_warn') def test_del_handler_nonexist_peer(mocked_log_warn): - m = constructor() - m.del_handler("40.40.40.1") - mocked_log_warn.assert_called_with("Peer '(default|40.40.40.1)' has not been found") + for constant in load_constant_files(): + m = constructor(constant) + m.del_handler("40.40.40.1") + mocked_log_warn.assert_called_with("Peer '(default|40.40.40.1)' has not been found") diff --git a/src/sonic-bgpcfgd/tests/util.py b/src/sonic-bgpcfgd/tests/util.py index a328a272c836..d9b3273865cb 100644 --- a/src/sonic-bgpcfgd/tests/util.py +++ b/src/sonic-bgpcfgd/tests/util.py @@ -13,8 +13,8 @@ def load_constants_dir_mappings(): result[name] = value["template_dir"] return result -def load_constants(): - with open(CONSTANTS_PATH) as f: +def load_constants(constants = CONSTANTS_PATH): + with open(constants) as f: data = yaml.load(f) # FIXME" , Loader=yaml.FullLoader) assert "constants" in data, "'constants' key not found in constants.yml" return data From 5bb6d0deba7aa77bb4a28868125077118206ca53 Mon Sep 17 00:00:00 2001 From: Saikrishna Arcot Date: Fri, 19 Aug 2022 11:20:00 -0700 Subject: [PATCH 016/151] [snmpd]: Update to 5.9+dfsg-4+deb11u1 to match Debian version (#11763) * [snmpd]: Update to 5.9+dfsg-4+deb11u1 to match Debian version This brings in some security fixes. Signed-off-by: Saikrishna Arcot * Update snmpd makefile Signed-off-by: Saikrishna Arcot * Remove binNMU for snmpd Signed-off-by: Saikrishna Arcot Signed-off-by: Saikrishna Arcot --- rules/snmpd.mk | 2 +- src/snmpd/Makefile | 14 -------------- 2 files changed, 1 insertion(+), 15 deletions(-) diff --git a/rules/snmpd.mk b/rules/snmpd.mk index 52be51d1c549..e9e498556c5e 100644 --- a/rules/snmpd.mk +++ b/rules/snmpd.mk @@ -2,7 +2,7 @@ ifeq ($(BLDENV),bullseye) SNMPD_VERSION = 5.9+dfsg -SNMPD_VERSION_FULL = $(SNMPD_VERSION)-3+b1 +SNMPD_VERSION_FULL = $(SNMPD_VERSION)-4+deb11u1 else SNMPD_VERSION = 5.7.3+dfsg SNMPD_VERSION_FULL = $(SNMPD_VERSION)-5 diff --git a/src/snmpd/Makefile b/src/snmpd/Makefile index 0445b1ed6bee..ce14d6a42d88 100644 --- a/src/snmpd/Makefile +++ b/src/snmpd/Makefile @@ -31,27 +31,13 @@ $(addprefix $(DEST)/, $(MAIN_TARGET)): $(DEST)/% : rm -rf net-snmp-$(SNMPD_VERSION) # download debian net-snmp -ifneq (,$(findstring 5.9,$(SNMPD_VERSION))) - dget -u https://sonicstorage.blob.core.windows.net/debian/pool/main/n/net-snmp/net-snmp_$(SNMPD_VERSION)-3.dsc -else dget -u https://sonicstorage.blob.core.windows.net/debian/pool/main/n/net-snmp/net-snmp_$(SNMPD_VERSION_FULL).dsc -endif pushd net-snmp-$(SNMPD_VERSION) git init git add -f * git commit -m "unmodified snmpd source" -ifneq (,$(findstring 5.9,$(SNMPD_VERSION))) - # Looks like Debian did a binNMU (binary non-maintainer upload), so the latest dsc - # file that we can get doesn't actually have the exact version number that Debian's - # repos have. - DEBEMAIL="$(shell git config --get user.name) <$(shell git config --get user.email)>" dch --bin-nmu "Rebuild against perl 5.32.0" - dch -r "" - git add debian/changelog - git commit -m "fix package version" -endif - # Apply patches stg init stg import -s ../patch-$(SNMPD_VERSION)/series From 9753f28d1798eb556ead1a26dea6c3a8dfc2a7e4 Mon Sep 17 00:00:00 2001 From: Saikrishna Arcot Date: Fri, 19 Aug 2022 11:20:17 -0700 Subject: [PATCH 017/151] Upgrade snmp docker to Bullseye (#11741) Signed-off-by: Saikrishna Arcot Signed-off-by: Saikrishna Arcot --- dockers/docker-snmp/Dockerfile.j2 | 2 +- rules/docker-snmp.mk | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/dockers/docker-snmp/Dockerfile.j2 b/dockers/docker-snmp/Dockerfile.j2 index 944a8ed41385..1eb4ec4b7c8b 100644 --- a/dockers/docker-snmp/Dockerfile.j2 +++ b/dockers/docker-snmp/Dockerfile.j2 @@ -1,5 +1,5 @@ {% from "dockers/dockerfile-macros.j2" import install_debian_packages, install_python3_wheels, copy_files %} -FROM docker-config-engine-buster-{{DOCKER_USERNAME}}:{{DOCKER_USERTAG}} +FROM docker-config-engine-bullseye-{{DOCKER_USERNAME}}:{{DOCKER_USERTAG}} ARG docker_container_name ARG image_version diff --git a/rules/docker-snmp.mk b/rules/docker-snmp.mk index af90cf3664e8..e0f7719c6034 100644 --- a/rules/docker-snmp.mk +++ b/rules/docker-snmp.mk @@ -9,13 +9,13 @@ $(DOCKER_SNMP)_PATH = $(DOCKERS_PATH)/docker-snmp ## TODO: remove LIBPY3_DEV if we can get pip3 directly $(DOCKER_SNMP)_DEPENDS += $(SNMP) $(SNMPD) -$(DOCKER_SNMP)_DBG_DEPENDS = $($(DOCKER_CONFIG_ENGINE_BUSTER)_DBG_DEPENDS) +$(DOCKER_SNMP)_DBG_DEPENDS = $($(DOCKER_CONFIG_ENGINE_BULLSEYE)_DBG_DEPENDS) $(DOCKER_SNMP)_DBG_DEPENDS += $(SNMP_DBG) $(SNMPD_DBG) $(LIBSNMP_DBG) -$(DOCKER_SNMP)_DBG_IMAGE_PACKAGES = $($(DOCKER_CONFIG_ENGINE_BUSTER)_DBG_IMAGE_PACKAGES) +$(DOCKER_SNMP)_DBG_IMAGE_PACKAGES = $($(DOCKER_CONFIG_ENGINE_BULLSEYE)_DBG_IMAGE_PACKAGES) $(DOCKER_SNMP)_PYTHON_WHEELS += $(SONIC_PY_COMMON_PY3) $(SONIC_PLATFORM_COMMON_PY3) $(SWSSSDK_PY3) $(ASYNCSNMP_PY3) -$(DOCKER_SNMP)_LOAD_DOCKERS += $(DOCKER_CONFIG_ENGINE_BUSTER) +$(DOCKER_SNMP)_LOAD_DOCKERS += $(DOCKER_CONFIG_ENGINE_BULLSEYE) $(DOCKER_SNMP)_VERSION = 1.0.0 $(DOCKER_SNMP)_PACKAGE_NAME = snmp @@ -32,5 +32,5 @@ $(DOCKER_SNMP)_RUN_OPT += -v /etc/sonic:/etc/sonic:ro $(DOCKER_SNMP)_RUN_OPT += -v /usr/share/sonic/scripts:/usr/share/sonic/scripts:ro $(DOCKER_SNMP)_FILES += $(SUPERVISOR_PROC_EXIT_LISTENER_SCRIPT) -SONIC_BUSTER_DOCKERS += $(DOCKER_SNMP) -SONIC_BUSTER_DBG_DOCKERS += $(DOCKER_SNMP_DBG) +SONIC_BULLSEYE_DOCKERS += $(DOCKER_SNMP) +SONIC_BULLSEYE_DBG_DOCKERS += $(DOCKER_SNMP_DBG) From 0f50835c1196debd61eeb3fe16051e471aae3a65 Mon Sep 17 00:00:00 2001 From: Dmytro Lytvynenko Date: Sat, 20 Aug 2022 02:02:01 +0300 Subject: [PATCH 018/151] [BFN] Upgrade syncd container to deb11 (#11374) * draft upgrade to deb11 of syncd and syncd-rpc * upgrade to python3 * revert workaround with libsaithrift * Provide urls for sai and platform debs * Downgrade python3 to python2 * Remove saithrift-patches * Upgrade modules * remove unnecessary lib * remove more unnecessary modules * Update sdk reference * remove unnecessary packages from syncd-rpc --- platform/barefoot/bfn-platform.mk | 2 +- platform/barefoot/bfn-sai.mk | 2 +- platform/barefoot/docker-syncd-bfn-rpc.mk | 2 +- .../docker-syncd-bfn-rpc/Dockerfile.j2 | 22 ++++++++----------- platform/barefoot/docker-syncd-bfn.mk | 4 ++-- .../barefoot/docker-syncd-bfn/Dockerfile.j2 | 8 +++---- 6 files changed, 17 insertions(+), 23 deletions(-) diff --git a/platform/barefoot/bfn-platform.mk b/platform/barefoot/bfn-platform.mk index a35795dda6c2..53e4ab9f807a 100644 --- a/platform/barefoot/bfn-platform.mk +++ b/platform/barefoot/bfn-platform.mk @@ -1,4 +1,4 @@ -BFN_PLATFORM = bfnplatform_20220512_sai_1.10.2_deb10.deb +BFN_PLATFORM = bfnplatform_20220815_sai_1.10_deb11.deb $(BFN_PLATFORM)_URL = "https://github.com/barefootnetworks/sonic-release-pkgs/raw/dev/$(BFN_PLATFORM)" SONIC_ONLINE_DEBS += $(BFN_PLATFORM) diff --git a/platform/barefoot/bfn-sai.mk b/platform/barefoot/bfn-sai.mk index 13f2800c0b9a..b8888b59457b 100644 --- a/platform/barefoot/bfn-sai.mk +++ b/platform/barefoot/bfn-sai.mk @@ -1,4 +1,4 @@ -BFN_SAI = bfnsdk_20220512_sai_1.10.2_deb10.deb +BFN_SAI = bfnsdk_20220815_sai_1.10_deb11.deb $(BFN_SAI)_URL = "https://github.com/barefootnetworks/sonic-release-pkgs/raw/dev/$(BFN_SAI)" $(BFN_SAI)_DEPENDS += $(LIBNL_GENL3_DEV) diff --git a/platform/barefoot/docker-syncd-bfn-rpc.mk b/platform/barefoot/docker-syncd-bfn-rpc.mk index a2a741cea1e1..6e1359d59ccf 100644 --- a/platform/barefoot/docker-syncd-bfn-rpc.mk +++ b/platform/barefoot/docker-syncd-bfn-rpc.mk @@ -12,7 +12,7 @@ $(DOCKER_SYNCD_BFN_RPC)_DEPENDS += $(SYNCD_RPC_DBG) \ endif $(DOCKER_SYNCD_BFN_RPC)_LOAD_DOCKERS += $(DOCKER_SYNCD_BASE) SONIC_DOCKER_IMAGES += $(DOCKER_SYNCD_BFN_RPC) -SONIC_BUSTER_DOCKERS += $(DOCKER_SYNCD_BFN_RPC) +SONIC_BULLSEYE_DOCKERS += $(DOCKER_SYNCD_BFN_RPC) ifeq ($(ENABLE_SYNCD_RPC),y) SONIC_INSTALL_DOCKER_IMAGES += $(DOCKER_SYNCD_BFN_RPC) endif diff --git a/platform/barefoot/docker-syncd-bfn-rpc/Dockerfile.j2 b/platform/barefoot/docker-syncd-bfn-rpc/Dockerfile.j2 index e520c55f9c39..5e1f4511ec9f 100644 --- a/platform/barefoot/docker-syncd-bfn-rpc/Dockerfile.j2 +++ b/platform/barefoot/docker-syncd-bfn-rpc/Dockerfile.j2 @@ -12,20 +12,16 @@ debs/ RUN apt-get purge -y syncd ## Pre-install the fundamental packages -RUN apt-get update \ +RUN apt-get update \ && apt-get -y install \ - net-tools \ - python-pip \ - python-setuptools \ - build-essential \ - libssl-dev \ - libffi-dev \ - python-dev \ wget \ cmake \ libqt5core5a \ libqt5network5 \ - libboost-atomic1.71.0 + python3-setuptools \ + python3-pip \ + python-is-python3 \ + libboost-atomic1.74.0 RUN dpkg_apt() { [ -f $1 ] && { dpkg -i $1 || apt-get -y install -f; } || return 1; } ; \ {% for deb in docker_syncd_bfn_rpc_debs.split(' ') -%} @@ -42,10 +38,10 @@ RUN wget https://github.com/nanomsg/nanomsg/archive/1.0.0.tar.gz \ && cd .. \ && rm -fr nanomsg-1.0.0 \ && rm -f 1.0.0.tar.gz \ - && pip2 install cffi==1.7.0 \ - && pip2 install --upgrade cffi==1.7.0 \ - && pip2 install wheel \ - && pip2 install nnpy \ + && pip3 install cffi==1.7.0 \ + && pip3 install --upgrade cffi==1.7.0 \ + && pip3 install wheel \ + && pip3 install nnpy \ && mkdir -p /opt \ && cd /opt \ && wget https://raw.githubusercontent.com/p4lang/ptf/master/ptf_nn/ptf_nn_agent.py \ diff --git a/platform/barefoot/docker-syncd-bfn.mk b/platform/barefoot/docker-syncd-bfn.mk index c1cda4e3bef1..55303557c345 100644 --- a/platform/barefoot/docker-syncd-bfn.mk +++ b/platform/barefoot/docker-syncd-bfn.mk @@ -1,7 +1,7 @@ # docker image for syncd DOCKER_SYNCD_PLATFORM_CODE = bfn -include $(PLATFORM_PATH)/../template/docker-syncd-base.mk +include $(PLATFORM_PATH)/../template/docker-syncd-bullseye.mk $(DOCKER_SYNCD_BASE)_DEPENDS += $(SYNCD) @@ -16,4 +16,4 @@ $(DOCKER_SYNCD_BASE)_PACKAGE_NAME = syncd $(DOCKER_SYNCD_BASE)_RUN_OPT += -v /host/warmboot:/var/warmboot -SONIC_BUSTER_DOCKERS += $(DOCKER_SYNCD_BASE) +SONIC_BULLSEYE_DOCKERS += $(DOCKER_SYNCD_BASE) diff --git a/platform/barefoot/docker-syncd-bfn/Dockerfile.j2 b/platform/barefoot/docker-syncd-bfn/Dockerfile.j2 index 8fa30bc29874..2bb6e7a97287 100755 --- a/platform/barefoot/docker-syncd-bfn/Dockerfile.j2 +++ b/platform/barefoot/docker-syncd-bfn/Dockerfile.j2 @@ -1,4 +1,4 @@ -FROM docker-config-engine-buster-{{DOCKER_USERNAME}}:{{DOCKER_USERTAG}} +FROM docker-config-engine-bullseye-{{DOCKER_USERNAME}}:{{DOCKER_USERTAG}} ARG docker_container_name @@ -16,11 +16,9 @@ debs/ RUN apt-get install -y \ libxml2 \ libpcap-dev \ - libusb-1.0-0-dev \ - libcurl4 \ - libcurl4-gnutls-dev \ + libusb-1.0-0 \ + libcurl3-gnutls \ libunwind8-dev \ - libpython3.4 \ libc-ares2 \ libedit2 \ libgoogle-perftools4 From cafa829ace8002fa292d9825f9fc171c17c5dbfe Mon Sep 17 00:00:00 2001 From: Dror Prital <76714716+dprital@users.noreply.github.com> Date: Sat, 20 Aug 2022 14:43:51 +0300 Subject: [PATCH 019/151] Change submodule path from Azure to sonic-net (#11700) Why I did it Change the path of sonic submodules that point to "Azure" to point to "sonic-net" How I did it Replace "Azure" with "sonic-net" on all relevant paths of sonic submodules --- .gitmodules | 40 ++++++++++++++++++++-------------------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/.gitmodules b/.gitmodules index eba302a62912..09ebc6da2373 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,15 +1,15 @@ [submodule "sonic-swss-common"] path = src/sonic-swss-common - url = https://github.com/Azure/sonic-swss-common + url = https://github.com/sonic-net/sonic-swss-common [submodule "sonic-linux-kernel"] path = src/sonic-linux-kernel - url = https://github.com/Azure/sonic-linux-kernel + url = https://github.com/sonic-net/sonic-linux-kernel [submodule "sonic-sairedis"] path = src/sonic-sairedis - url = https://github.com/Azure/sonic-sairedis + url = https://github.com/sonic-net/sonic-sairedis [submodule "sonic-swss"] path = src/sonic-swss - url = https://github.com/Azure/sonic-swss + url = https://github.com/sonic-net/sonic-swss [submodule "src/p4c-bm/p4c-bm"] path = platform/p4/p4c-bm/p4c-bm url = https://github.com/krambn/p4c-bm @@ -18,34 +18,34 @@ url = https://github.com/p4lang/p4-hlir [submodule "sonic-dbsyncd"] path = src/sonic-dbsyncd - url = https://github.com/Azure/sonic-dbsyncd + url = https://github.com/sonic-net/sonic-dbsyncd [submodule "src/sonic-py-swsssdk"] path = src/sonic-py-swsssdk - url = https://github.com/Azure/sonic-py-swsssdk.git + url = https://github.com/sonic-net/sonic-py-swsssdk.git [submodule "src/sonic-snmpagent"] path = src/sonic-snmpagent - url = https://github.com/Azure/sonic-snmpagent + url = https://github.com/sonic-net/sonic-snmpagent [submodule "src/ptf"] path = src/ptf url = https://github.com/p4lang/ptf.git [submodule "src/sonic-utilities"] path = src/sonic-utilities - url = https://github.com/Azure/sonic-utilities + url = https://github.com/sonic-net/sonic-utilities [submodule "platform/broadcom/sonic-platform-modules-arista"] path = platform/broadcom/sonic-platform-modules-arista url = https://github.com/aristanetworks/sonic [submodule "src/sonic-platform-common"] path = src/sonic-platform-common - url = https://github.com/Azure/sonic-platform-common + url = https://github.com/sonic-net/sonic-platform-common [submodule "src/sonic-platform-daemons"] path = src/sonic-platform-daemons - url = https://github.com/Azure/sonic-platform-daemons + url = https://github.com/sonic-net/sonic-platform-daemons [submodule "src/sonic-platform-pde"] path = src/sonic-platform-pde - url = https://github.com/Azure/sonic-platform-pdk-pde + url = https://github.com/sonic-net/sonic-platform-pdk-pde [submodule "src/sonic-frr/frr"] path = src/sonic-frr/frr - url = https://github.com/Azure/sonic-frr.git + url = https://github.com/sonic-net/sonic-frr.git branch = frr/8.2 [submodule "platform/p4/p4-hlir/p4-hlir-v1.1"] path = platform/p4/p4-hlir/p4-hlir-v1.1 @@ -70,36 +70,36 @@ url = https://github.com/Mellanox/SAI-Implementation [submodule "src/sonic-mgmt-framework"] path = src/sonic-mgmt-framework - url = https://github.com/Azure/sonic-mgmt-framework + url = https://github.com/sonic-net/sonic-mgmt-framework [submodule "Switch-SDK-drivers"] path = platform/mellanox/sdk-src/sx-kernel/Switch-SDK-drivers url = https://github.com/Mellanox/Switch-SDK-drivers [submodule "src/sonic-ztp"] path = src/sonic-ztp - url = https://github.com/Azure/sonic-ztp + url = https://github.com/sonic-net/sonic-ztp [submodule "src/sonic-restapi"] path = src/sonic-restapi - url = https://github.com/Azure/sonic-restapi.git + url = https://github.com/sonic-net/sonic-restapi.git branch = master [submodule "src/sonic-mgmt-common"] path = src/sonic-mgmt-common - url = https://github.com/Azure/sonic-mgmt-common.git + url = https://github.com/sonic-net/sonic-mgmt-common.git [submodule "src/wpasupplicant/sonic-wpa-supplicant"] path = src/wpasupplicant/sonic-wpa-supplicant - url = https://github.com/Azure/sonic-wpa-supplicant.git + url = https://github.com/sonic-net/sonic-wpa-supplicant.git [submodule "platform/broadcom/saibcm-modules-dnx"] path = platform/broadcom/saibcm-modules-dnx - url = https://github.com/Azure/saibcm-modules.git + url = https://github.com/sonic-net/saibcm-modules.git branch = sdk-6.5.22-gpl-dnx [submodule "platform/broadcom/sonic-platform-modules-nokia"] path = platform/broadcom/sonic-platform-modules-nokia url = https://github.com/nokia/sonic-platform.git [submodule "src/linkmgrd"] path = src/linkmgrd - url = https://github.com/Azure/sonic-linkmgrd.git + url = https://github.com/sonic-net/sonic-linkmgrd.git [submodule "src/sonic-p4rt/sonic-pins"] path = src/sonic-p4rt/sonic-pins - url = https://github.com/Azure/sonic-pins.git + url = https://github.com/sonic-net/sonic-pins.git [submodule "src/ptf-py3"] path = src/ptf-py3 url = https://github.com/p4lang/ptf.git From 946bc3b969d1960261f806b16db6d2f3d6c4ecee Mon Sep 17 00:00:00 2001 From: Ying Xie Date: Sat, 20 Aug 2022 18:09:04 -0700 Subject: [PATCH 020/151] [arping] install arping utility in the base image (#11791) Signed-off-by: Ying Xie Signed-off-by: Ying Xie --- build_debian.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/build_debian.sh b/build_debian.sh index 927b051d2887..1db8f3b91ca1 100755 --- a/build_debian.sh +++ b/build_debian.sh @@ -344,6 +344,7 @@ sudo LANG=C DEBIAN_FRONTEND=noninteractive chroot $FILESYSTEM_ROOT apt-get -y in python3-apt \ traceroute \ iputils-ping \ + arping \ net-tools \ bsdmainutils \ ca-certificates \ From 2d4ab9e9792c41dd403f4345454bd83db3dfdf36 Mon Sep 17 00:00:00 2001 From: Hasan Naqvi <56742004+hasan-brcm@users.noreply.github.com> Date: Sun, 21 Aug 2022 17:04:47 -0700 Subject: [PATCH 021/151] Bullseye frr (#11777) Why I did it Migrate FRR to bullseye How I did it Makefile and docker config changes to refer to bullseye instead of buster. How to verify it Build bullseye frr docker. Co-authored-by: Rajendra Dendukuri --- dockers/docker-fpm-frr/Dockerfile.j2 | 3 +-- rules/docker-fpm-frr.mk | 10 +++++----- 2 files changed, 6 insertions(+), 7 deletions(-) diff --git a/dockers/docker-fpm-frr/Dockerfile.j2 b/dockers/docker-fpm-frr/Dockerfile.j2 index f885180c37d4..ad665e71ceae 100644 --- a/dockers/docker-fpm-frr/Dockerfile.j2 +++ b/dockers/docker-fpm-frr/Dockerfile.j2 @@ -1,5 +1,5 @@ {% from "dockers/dockerfile-macros.j2" import install_debian_packages, install_python_wheels, copy_files %} -FROM docker-swss-layer-buster-{{DOCKER_USERNAME}}:{{DOCKER_USERTAG}} +FROM docker-swss-layer-bullseye-{{DOCKER_USERNAME}}:{{DOCKER_USERTAG}} ARG docker_container_name ARG frr_user_uid @@ -16,7 +16,6 @@ RUN apt-get update && \ apt-get install -y \ libc-ares2 \ iproute2 \ - libjson-c3 \ logrotate \ libunwind8 diff --git a/rules/docker-fpm-frr.mk b/rules/docker-fpm-frr.mk index ff594288419c..861e1d8e8b41 100644 --- a/rules/docker-fpm-frr.mk +++ b/rules/docker-fpm-frr.mk @@ -8,13 +8,13 @@ $(DOCKER_FPM_FRR)_PATH = $(DOCKERS_PATH)/$(DOCKER_FPM_FRR_STEM) $(DOCKER_FPM_FRR)_PYTHON_WHEELS += $(SONIC_BGPCFGD) $(SONIC_FRR_MGMT_FRAMEWORK) $(DOCKER_FPM_FRR)_DEPENDS += $(FRR) $(FRR_SNMP) $(SWSS) $(LIBYANG2) -$(DOCKER_FPM_FRR)_DBG_DEPENDS = $($(DOCKER_SWSS_LAYER_BUSTER)_DBG_DEPENDS) +$(DOCKER_FPM_FRR)_DBG_DEPENDS = $($(DOCKER_SWSS_LAYER_BULLSEYE)_DBG_DEPENDS) $(DOCKER_FPM_FRR)_DBG_DEPENDS += $(SWSS_DBG) $(LIBSWSSCOMMON_DBG) \ $(FRR_DBG) $(FRR_SNMP_DBG) $(LIBYANG2_DBG) -$(DOCKER_FPM_FRR)_DBG_IMAGE_PACKAGES = $($(DOCKER_SWSS_LAYER_BUSTER)_DBG_IMAGE_PACKAGES) +$(DOCKER_FPM_FRR)_DBG_IMAGE_PACKAGES = $($(DOCKER_SWSS_LAYER_BULLSEYE)_DBG_IMAGE_PACKAGES) -$(DOCKER_FPM_FRR)_LOAD_DOCKERS += $(DOCKER_SWSS_LAYER_BUSTER) +$(DOCKER_FPM_FRR)_LOAD_DOCKERS += $(DOCKER_SWSS_LAYER_BULLSEYE) $(DOCKER_FPM_FRR)_VERSION = 1.0.0 $(DOCKER_FPM_FRR)_PACKAGE_NAME = fpm-frr @@ -40,5 +40,5 @@ $(DOCKER_FPM_FRR)_BASE_IMAGE_FILES += TSB:/usr/bin/TSB $(DOCKER_FPM_FRR)_BASE_IMAGE_FILES += TSC:/usr/bin/TSC $(DOCKER_FPM_FRR)_BASE_IMAGE_FILES += TS:/usr/bin/TS -SONIC_BUSTER_DOCKERS += $(DOCKER_FPM_FRR) -SONIC_BUSTER_DBG_DOCKERS += $(DOCKER_FPM_FRR_DBG) +SONIC_BULLSEYE_DOCKERS += $(DOCKER_FPM_FRR) +SONIC_BULLSEYE_DBG_DOCKERS += $(DOCKER_FPM_FRR_DBG) From f404ce60e01214f7eec7a2d36946b3c5bad3eb11 Mon Sep 17 00:00:00 2001 From: anamehra <54692434+anamehra@users.noreply.github.com> Date: Mon, 22 Aug 2022 10:08:29 -0700 Subject: [PATCH 022/151] container_checker on supervisor should check containers based on asic presence (#11442) Why I did it On a supervisor card in a chassis, syncd/teamd/swss/lldp etc dockers are created for each Switch Fabric card. However, not all chassis would have all the switch fabric cards present. In this case, only dockers for Switch Fabrics present would be created. The monit 'container_checker' fails in this scenario as it is expecting dockers for all Switch Fabrics (based on NUM_ASIC defined in asic.conf file). --- files/image_config/monit/container_checker | 22 ++++++++++--- .../sonic_py_common/multi_asic.py | 31 ++++++++++++++++++- 2 files changed, 48 insertions(+), 5 deletions(-) diff --git a/files/image_config/monit/container_checker b/files/image_config/monit/container_checker index a67a96a0c18c..c6271d26c8b1 100755 --- a/files/image_config/monit/container_checker +++ b/files/image_config/monit/container_checker @@ -23,7 +23,6 @@ import swsssdk from sonic_py_common import multi_asic, device_info from swsscommon import swsscommon - def get_expected_running_containers(): """ @summary: This function will get the expected running & always-enabled containers by following the rule: @@ -41,7 +40,19 @@ def get_expected_running_containers(): expected_running_containers = set() always_running_containers = set() - + + # Get current asic presence list. For multi_asic system, multi instance containers + # should be checked only for asics present. + asics_id_presence = multi_asic.get_asic_presence_list() + + # Some services may run all the instances irrespective of asic presence. + # Add those to exception list. + # database service: Currently services have dependency on all database services to + # be up irrespective of asic presence. + # bgp service: Currently bgp runs all instances. Once this is fixed to be config driven, + # it will be removed from exception list. + run_all_instance_list = ['database', 'bgp'] + for container_name in feature_table.keys(): if feature_table[container_name]["state"] not in ["disabled", "always_disabled"]: if multi_asic.is_multi_asic(): @@ -50,7 +61,8 @@ def get_expected_running_containers(): if feature_table[container_name]["has_per_asic_scope"] == "True": num_asics = multi_asic.get_num_asics() for asic_id in range(num_asics): - expected_running_containers.add(container_name + str(asic_id)) + if asic_id in asics_id_presence or container_name in run_all_instance_list: + expected_running_containers.add(container_name + str(asic_id)) else: expected_running_containers.add(container_name) if feature_table[container_name]["state"] == 'always_enabled': @@ -60,9 +72,11 @@ def get_expected_running_containers(): if feature_table[container_name]["has_per_asic_scope"] == "True": num_asics = multi_asic.get_num_asics() for asic_id in range(num_asics): - always_running_containers.add(container_name + str(asic_id)) + if asic_id in asics_id_presence or container_name in run_all_instance_list: + always_running_containers.add(container_name + str(asic_id)) else: always_running_containers.add(container_name) + if device_info.is_supervisor(): always_running_containers.add("database-chassis") return expected_running_containers, always_running_containers diff --git a/src/sonic-py-common/sonic_py_common/multi_asic.py b/src/sonic-py-common/sonic_py_common/multi_asic.py index 8ba409165f8b..e08746be0367 100644 --- a/src/sonic-py-common/sonic_py_common/multi_asic.py +++ b/src/sonic-py-common/sonic_py_common/multi_asic.py @@ -22,7 +22,8 @@ NEIGH_DEVICE_METADATA_CFG_DB_TABLE = 'DEVICE_NEIGHBOR_METADATA' DEFAULT_NAMESPACE = '' PORT_ROLE = 'role' - +CHASSIS_STATE_DB='CHASSIS_STATE_DB' +CHASSIS_ASIC_INFO_TABLE='CHASSIS_ASIC_TABLE' # Dictionary to cache config_db connection handle per namespace # to prevent duplicate connections from being opened @@ -451,3 +452,31 @@ def validate_namespace(namespace): return True else: return False + +def get_asic_presence_list(): + """ + @summary: This function will get the asic presence list. On Supervisor, the list includes only the asics + for inserted and detected fabric cards. For non-supervisor cards, e.g. line card, the list should + contain all supported asics by the card. The function gets the asic list from CHASSIS_ASIC_TABLE from + CHASSIS_STATE_DB. The function assumes that the first N asic ids (asic0 to asic(N-1)) in + CHASSIS_ASIC_TABLE belongs to the supervisor, where N is the max number of asics supported by the Chassis + @return: List of asics present + """ + asics_list = [] + if is_multi_asic(): + if not is_supervisor(): + # This is not supervisor, all asics should be present. Assuming that asics + # are not removable entity on Line Cards. Add all asics, 0 - num_asics to the list. + asics_list = list(range(0, get_num_asics())) + else: + # This is supervisor card. Some fabric cards may not be inserted. + # Get asic list from CHASSIS_ASIC_TABLE which lists only the asics + # present based on Fabric card detection by the platform. + db = swsscommon.DBConnector(CHASSIS_STATE_DB, 0, True) + asic_table = swsscommon.Table(db, CHASSIS_ASIC_INFO_TABLE) + if asic_table: + asics_presence_list = list(asic_table.getKeys()) + for asic in asics_presence_list: + # asic is asid id: asic0, asic1.... asicN. Get the numeric value. + asics_list.append(int(get_asic_id_from_name(asic))) + return asics_list From 2501d1f6737f498877d743151a63e93733612906 Mon Sep 17 00:00:00 2001 From: vmittal-msft <46945843+vmittal-msft@users.noreply.github.com> Date: Mon, 22 Aug 2022 16:24:51 -0700 Subject: [PATCH 023/151] PFCWD fix for multi port multi priority scenario for HWSKU Dell Z9332 (#11640) PFCWD fix for multi port multi priority scenario for HWSKU Dell Z9332 --- .../th3-z9332f-16x400G-64x100G.config.bcm | 4 ++++ .../DellEMC-Z9332f-O32/th3-z9332f-32x400G.config.bcm | 4 ++++ src/sonic-device-data/tests/permitted_list | 2 ++ 3 files changed, 10 insertions(+) diff --git a/device/dell/x86_64-dellemc_z9332f_d1508-r0/DellEMC-Z9332f-M-O16C64/th3-z9332f-16x400G-64x100G.config.bcm b/device/dell/x86_64-dellemc_z9332f_d1508-r0/DellEMC-Z9332f-M-O16C64/th3-z9332f-16x400G-64x100G.config.bcm index 1433de4d3b6c..cef161ded3cb 100644 --- a/device/dell/x86_64-dellemc_z9332f_d1508-r0/DellEMC-Z9332f-M-O16C64/th3-z9332f-16x400G-64x100G.config.bcm +++ b/device/dell/x86_64-dellemc_z9332f_d1508-r0/DellEMC-Z9332f-M-O16C64/th3-z9332f-16x400G-64x100G.config.bcm @@ -53,6 +53,10 @@ l2xlrn_intr_en=0 sai_optimized_mmu=1 mmu_init_config="TH3-MSFT-T0" +hybrid_pfc_deadlock_enable=1 +pfc_deadlock_seq_control=1 +sai_pfc_dlr_init_capability=1 + pbmp_xport_xe=0xffffffFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE phy_an_c73=3 diff --git a/device/dell/x86_64-dellemc_z9332f_d1508-r0/DellEMC-Z9332f-O32/th3-z9332f-32x400G.config.bcm b/device/dell/x86_64-dellemc_z9332f_d1508-r0/DellEMC-Z9332f-O32/th3-z9332f-32x400G.config.bcm index a46ac765bb66..59d767df3104 100644 --- a/device/dell/x86_64-dellemc_z9332f_d1508-r0/DellEMC-Z9332f-O32/th3-z9332f-32x400G.config.bcm +++ b/device/dell/x86_64-dellemc_z9332f_d1508-r0/DellEMC-Z9332f-O32/th3-z9332f-32x400G.config.bcm @@ -53,6 +53,10 @@ l2xlrn_intr_en=0 sai_optimized_mmu=1 mmu_init_config="TH3-MSFT-T1" +hybrid_pfc_deadlock_enable=1 +pfc_deadlock_seq_control=1 +sai_pfc_dlr_init_capability=1 + pbmp_xport_xe=0xffffffFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE phy_an_c73=3 diff --git a/src/sonic-device-data/tests/permitted_list b/src/sonic-device-data/tests/permitted_list index 41932882a32a..01ed79c41ff8 100644 --- a/src/sonic-device-data/tests/permitted_list +++ b/src/sonic-device-data/tests/permitted_list @@ -320,3 +320,5 @@ xflow_macsec_secure_chan_to_num_secure_assoc_encrypt xflow_macsec_secure_chan_to_num_secure_assoc_decrypt sai_mdio_access_clause22 cmic_dma_abort_in_cold_boot +hybrid_pfc_deadlock_enable +sai_pfc_dlr_init_capability From 770cb80017861b2c33911c37b4cdd7b244726d3a Mon Sep 17 00:00:00 2001 From: Junhua Zhai Date: Tue, 23 Aug 2022 04:34:04 +0000 Subject: [PATCH 024/151] [BRCM SAI 7.1.7.2] catch up CS00012257483 patch (#11768) Why I did it It solves a swss orchagent crash issue on PikeZ device, due to link-training setting of external PHY port. How I did it Catch up the fix for CS00012257483 in version 7.1.7.2. --- platform/broadcom/sai.mk | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/platform/broadcom/sai.mk b/platform/broadcom/sai.mk index 8d78a89a97a5..6de969a662bc 100644 --- a/platform/broadcom/sai.mk +++ b/platform/broadcom/sai.mk @@ -1,5 +1,5 @@ -LIBSAIBCM_XGS_VERSION = 7.1.7.1 -LIBSAIBCM_DNX_VERSION = 7.1.7.1 +LIBSAIBCM_XGS_VERSION = 7.1.7.2 +LIBSAIBCM_DNX_VERSION = 7.1.7.2 LIBSAIBCM_BRANCH_NAME = REL_7.0 LIBSAIBCM_XGS_URL_PREFIX = "https://sonicstorage.blob.core.windows.net/public/sai/bcmsai/$(LIBSAIBCM_BRANCH_NAME)/$(LIBSAIBCM_XGS_VERSION)" LIBSAIBCM_DNX_URL_PREFIX = "https://sonicstorage.blob.core.windows.net/public/sai/bcmsai/$(LIBSAIBCM_BRANCH_NAME)/$(LIBSAIBCM_DNX_VERSION)" From fb774dd46aaa1c7bb2f5372bef9c1936054ccda8 Mon Sep 17 00:00:00 2001 From: Junhua Zhai Date: Tue, 23 Aug 2022 04:38:08 +0000 Subject: [PATCH 025/151] [gbsyncd] Build docker-gbsyncd-broncos image (#11748) The libsaibroncos debian package is published at $(LIBSAI_BRONCOS)_URL. Enable building docker-gbsyncd-broncos image on PLATFORM broadcom. --- platform/broadcom/rules.dep | 2 -- platform/broadcom/rules.mk | 2 -- platform/components/docker-gbsyncd-broncos.mk | 7 +++++-- platform/components/docker-gbsyncd-broncos/Dockerfile.j2 | 2 +- 4 files changed, 6 insertions(+), 7 deletions(-) diff --git a/platform/broadcom/rules.dep b/platform/broadcom/rules.dep index 220ee8019943..075636a8dedd 100644 --- a/platform/broadcom/rules.dep +++ b/platform/broadcom/rules.dep @@ -30,6 +30,4 @@ include $(PLATFORM_PATH)/libsaithrift-dev.dep include $(PLATFORM_PATH)/docker-syncd-brcm-dnx.dep include $(PLATFORM_PATH)/docker-syncd-brcm-dnx-rpc.dep include $(PLATFORM_PATH)/../components/docker-gbsyncd-credo.dep -ifeq ($(INCLUDE_GBSYNCD_BRONCOS), y) include $(PLATFORM_PATH)/../components/docker-gbsyncd-broncos.dep -endif diff --git a/platform/broadcom/rules.mk b/platform/broadcom/rules.mk index 0b46bb1c8ec4..c43a66ee43e3 100644 --- a/platform/broadcom/rules.mk +++ b/platform/broadcom/rules.mk @@ -29,9 +29,7 @@ include $(PLATFORM_PATH)/libsaithrift-dev.mk include $(PLATFORM_PATH)/docker-syncd-brcm-dnx.mk include $(PLATFORM_PATH)/docker-syncd-brcm-dnx-rpc.mk include $(PLATFORM_PATH)/../components/docker-gbsyncd-credo.mk -ifeq ($(INCLUDE_GBSYNCD_BRONCOS), y) include $(PLATFORM_PATH)/../components/docker-gbsyncd-broncos.mk -endif BCMCMD = bcmcmd $(BCMCMD)_URL = "https://sonicstorage.blob.core.windows.net/packages/20190307/bcmcmd?sv=2015-04-05&sr=b&sig=sUdbU7oVbh5exbXXHVL5TDFBTWDDBASHeJ8Cp0B0TIc%3D&se=2038-05-06T22%3A34%3A19Z&sp=r" diff --git a/platform/components/docker-gbsyncd-broncos.mk b/platform/components/docker-gbsyncd-broncos.mk index 6e280ee5a655..1aad33f9680d 100644 --- a/platform/components/docker-gbsyncd-broncos.mk +++ b/platform/components/docker-gbsyncd-broncos.mk @@ -1,5 +1,8 @@ -LIBSAI_BRONCOS = libsaibroncos_0.0.1_amd64.deb -$(LIBSAI_BRONCOS)_URL = +LIBSAI_BRONCOS_VERSION = 3.8 +LIBSAI_BRONCOS_BRANCH_NAME = REL_3.8 +LIBSAI_BRONCOS_URL_PREFIX = "https://sonicstorage.blob.core.windows.net/public/sai/bcmpai/$(LIBSAI_BRONCOS_BRANCH_NAME)/$(LIBSAI_BRONCOS_VERSION)" +LIBSAI_BRONCOS = libsaibroncos_$(LIBSAI_BRONCOS_VERSION)_amd64.deb +$(LIBSAI_BRONCOS)_URL = "$(LIBSAI_BRONCOS_URL_PREFIX)/$(LIBSAI_BRONCOS)" ifneq ($($(LIBSAI_BRONCOS)_URL),) diff --git a/platform/components/docker-gbsyncd-broncos/Dockerfile.j2 b/platform/components/docker-gbsyncd-broncos/Dockerfile.j2 index f114679c6888..154c7735ce97 100644 --- a/platform/components/docker-gbsyncd-broncos/Dockerfile.j2 +++ b/platform/components/docker-gbsyncd-broncos/Dockerfile.j2 @@ -1,4 +1,4 @@ -FROM docker-config-engine-bullseye +FROM docker-config-engine-bullseye-{{DOCKER_USERNAME}}:{{DOCKER_USERTAG}} ARG docker_container_name RUN [ -f /etc/rsyslog.conf ] && sed -ri "s/%syslogtag%/$docker_container_name#%syslogtag%/;" /etc/rsyslog.conf From 0f4bca426eb0356fc88dc87c355a17ef4b85dfe1 Mon Sep 17 00:00:00 2001 From: Mai Bui Date: Tue, 23 Aug 2022 09:48:42 -0400 Subject: [PATCH 026/151] [device/ruijie] Mitigation for security vulnerability #11779 Signed-off-by: maipbui maibui@microsoft.com Why I did it The xml.etree.ElementTree module is not secure against maliciously constructed data. How I did it Remove xml. Use lxml XML parsers package that prevent potentially malicious operation. --- device/ruijie/x86_64-ruijie_b6510-48vs8cq-r0/monitor.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/device/ruijie/x86_64-ruijie_b6510-48vs8cq-r0/monitor.py b/device/ruijie/x86_64-ruijie_b6510-48vs8cq-r0/monitor.py index f9cbb31be401..103a2f30ac29 100755 --- a/device/ruijie/x86_64-ruijie_b6510-48vs8cq-r0/monitor.py +++ b/device/ruijie/x86_64-ruijie_b6510-48vs8cq-r0/monitor.py @@ -6,8 +6,8 @@ * PSU """ import os -import xml.etree.ElementTree as ET import glob +from lxml import etree as ET MAILBOX_DIR = "/sys/bus/i2c/devices/" PORTS_DIR = "/sys/class/net/" From 234b4973cddb0d3db550341b42c20785e9a0108c Mon Sep 17 00:00:00 2001 From: roberthong-qct <79961212+roberthong-qct@users.noreply.github.com> Date: Wed, 24 Aug 2022 01:10:08 +0800 Subject: [PATCH 027/151] [Quanta] Update files for Bullseye and kernel 5.10 with enhancements (#11755) * [Quanta][device][platform] Update files for IX7 Signed-off-by: roberthong-qct <10606901@qcttw.com> * [Quanta][device][platform] Update files for IX7_BDE Signed-off-by: roberthong-qct <10606901@qcttw.com> * [Quanta][device][platform] Update files for IX8 Signed-off-by: roberthong-qct <10606901@qcttw.com> * [Quanta][device][platform] Update files for IX8A_BDE Signed-off-by: roberthong-qct <10606901@qcttw.com> * [Quanta][device][platform] Update files for IX8C Signed-off-by: roberthong-qct <10606901@qcttw.com> * [Quanta][device][platform] Update files for IX9 Signed-off-by: roberthong-qct <10606901@qcttw.com> Signed-off-by: roberthong-qct <10606901@qcttw.com> --- .../media_settings.json | 254 ++++++++ .../preemphasis-32x100G.soc | 491 +++++++------- .../media_settings.json | 254 ++++++++ .../preemphasis-32x100G.soc | 515 ++++++++------- .../media_settings.json | 31 + .../preemphasis-48x25_8x100.soc | 224 +++---- .../media_settings.json | 21 + .../td3-ix8c-48x25G+8x100G.config.bcm | 161 +++-- .../led_proc_init.soc | 4 +- .../media_settings.json | 72 +++ .../Quanta-IX9-32X/hwsku.json | 132 ++++ .../Quanta-IX9-32X/th3-ix9-32x400G.config.bcm | 3 + .../x86_64-quanta_ix9_bwde-r0/custom_led.bin | Bin 204 -> 416 bytes .../led_proc_init.soc | 2 - .../media_settings.json | 132 ++++ .../x86_64-quanta_ix9_bwde-r0/platform.json | 600 ++++++++++++++++++ platform/broadcom/rules.mk | 2 +- .../ix7-32x/modules/qci_cpld_led.c | 2 +- .../ix7-32x/modules/quanta_hwmon_ipmi.c | 33 +- .../ix7-32x/modules/quanta_platform_ix7.c | 30 +- .../ix7-32x/sonic_platform/chassis.py | 25 +- .../ix7-32x/sonic_platform/component.py | 202 ++++++ .../ix7-32x/sonic_platform/fan_drawer.py | 2 +- .../ix7-32x/sonic_platform/psu.py | 4 +- .../ix7-32x/sonic_platform/sfp.py | 50 +- .../ix7-32x/sonic_platform/thermal.py | 4 +- .../ix7-32x/sonic_platform/watchdog.py | 15 +- .../ix7-32x/utils/quanta_ix7_util.py | 109 ++-- .../ix7-bwde-32x/modules/qci_cpld_led.c | 2 +- .../ix7-bwde-32x/modules/quanta_hwmon_ipmi.c | 33 +- .../modules/quanta_platform_ix7_bwde.c | 28 +- .../ix7-bwde-32x/sonic_platform/chassis.py | 45 +- .../ix7-bwde-32x/sonic_platform/component.py | 203 ++++++ .../ix7-bwde-32x/sonic_platform/fan.py | 91 +-- .../ix7-bwde-32x/sonic_platform/fan_drawer.py | 2 +- .../ix7-bwde-32x/sonic_platform/psu.py | 149 +++-- .../ix7-bwde-32x/sonic_platform/sfp.py | 50 +- .../ix7-bwde-32x/sonic_platform/thermal.py | 120 ++-- .../ix7-bwde-32x/sonic_platform/watchdog.py | 241 +++++++ .../utils/quanta_ix7_bwde_util.py | 109 ++-- .../ix8-56x/modules/qci_cpld_led.c | 2 +- .../ix8-56x/modules/qci_platform_ix8.c | 42 +- .../ix8-56x/modules/quanta_hwmon_ipmi.c | 37 +- .../ix8-56x/sonic_platform/chassis.py | 25 +- .../ix8-56x/sonic_platform/component.py | 203 ++++++ .../ix8-56x/sonic_platform/fan_drawer.py | 2 +- .../ix8-56x/sonic_platform/psu.py | 4 +- .../ix8-56x/sonic_platform/sfp.py | 50 +- .../ix8-56x/sonic_platform/thermal.py | 2 +- .../ix8-56x/sonic_platform/watchdog.py | 15 +- .../ix8-56x/utils/quanta_ix8_util.py | 117 ++-- .../ix8a-bwde-56x/modules/qci_cpld_led.c | 2 +- .../modules/qci_platform_ix8a_bwde.c | 40 +- .../ix8a-bwde-56x/modules/quanta_hwmon_ipmi.c | 145 ++++- .../ix8a-bwde-56x/sonic_platform/chassis.py | 25 +- .../ix8a-bwde-56x/sonic_platform/component.py | 204 ++++++ .../ix8a-bwde-56x/sonic_platform/fan.py | 75 ++- .../sonic_platform/fan_drawer.py | 2 +- .../ix8a-bwde-56x/sonic_platform/psu.py | 148 ++--- .../ix8a-bwde-56x/sonic_platform/sfp.py | 50 +- .../ix8a-bwde-56x/sonic_platform/thermal.py | 138 ++-- .../ix8a-bwde-56x/sonic_platform/watchdog.py | 15 +- .../utils/quanta_ix8a_bwde_util.py | 87 ++- .../ix8c-56x/modules/qci_cpld_led.c | 2 +- .../ix8c-56x/modules/qci_platform_ix8c.c | 40 +- .../ix8c-56x/modules/quanta_hwmon_ipmi.c | 135 +++- .../ix8c-56x/sonic_platform/chassis.py | 37 +- .../ix8c-56x/sonic_platform/component.py | 204 ++++++ .../ix8c-56x/sonic_platform/fan.py | 77 ++- .../ix8c-56x/sonic_platform/fan_drawer.py | 2 +- .../ix8c-56x/sonic_platform/psu.py | 190 ++++-- .../ix8c-56x/sonic_platform/sfp.py | 50 +- .../ix8c-56x/sonic_platform/thermal.py | 131 +++- .../ix8c-56x/sonic_platform/watchdog.py | 241 +++++++ .../ix8c-56x/utils/quanta_ix8c_util.py | 110 ++-- .../ix9-32x/modules/qci_cpld_led.c | 2 +- .../ix9-32x/modules/qci_platform_ix9.c | 28 +- .../ix9-32x/modules/quanta_hwmon_ipmi.c | 15 +- .../ix9-32x/sonic_platform/chassis.py | 35 +- .../ix9-32x/sonic_platform/component.py | 203 ++++++ .../ix9-32x/sonic_platform/fan.py | 75 ++- .../ix9-32x/sonic_platform/fan_drawer.py | 2 +- .../ix9-32x/sonic_platform/psu.py | 148 ++--- .../ix9-32x/sonic_platform/sfp.py | 61 +- .../ix9-32x/sonic_platform/thermal.py | 122 ++-- .../ix9-32x/sonic_platform/watchdog.py | 15 +- .../ix9-32x/utils/quanta_ix9_util.py | 132 ++-- 87 files changed, 5856 insertions(+), 2078 deletions(-) create mode 100644 device/quanta/x86_64-quanta_ix7_bwde-r0/media_settings.json create mode 100644 device/quanta/x86_64-quanta_ix7_rglbmc-r0/media_settings.json create mode 100644 device/quanta/x86_64-quanta_ix8_rglbmc-r0/media_settings.json create mode 100644 device/quanta/x86_64-quanta_ix8a_bwde-r0/media_settings.json create mode 100644 device/quanta/x86_64-quanta_ix8c_bwde-r0/media_settings.json create mode 100755 device/quanta/x86_64-quanta_ix9_bwde-r0/Quanta-IX9-32X/hwsku.json create mode 100644 device/quanta/x86_64-quanta_ix9_bwde-r0/media_settings.json create mode 100644 device/quanta/x86_64-quanta_ix9_bwde-r0/platform.json create mode 100644 platform/broadcom/sonic-platform-modules-quanta/ix7-32x/sonic_platform/component.py create mode 100644 platform/broadcom/sonic-platform-modules-quanta/ix7-bwde-32x/sonic_platform/component.py create mode 100644 platform/broadcom/sonic-platform-modules-quanta/ix7-bwde-32x/sonic_platform/watchdog.py create mode 100644 platform/broadcom/sonic-platform-modules-quanta/ix8-56x/sonic_platform/component.py create mode 100644 platform/broadcom/sonic-platform-modules-quanta/ix8a-bwde-56x/sonic_platform/component.py create mode 100644 platform/broadcom/sonic-platform-modules-quanta/ix8c-56x/sonic_platform/component.py create mode 100644 platform/broadcom/sonic-platform-modules-quanta/ix8c-56x/sonic_platform/watchdog.py create mode 100644 platform/broadcom/sonic-platform-modules-quanta/ix9-32x/sonic_platform/component.py diff --git a/device/quanta/x86_64-quanta_ix7_bwde-r0/media_settings.json b/device/quanta/x86_64-quanta_ix7_bwde-r0/media_settings.json new file mode 100644 index 000000000000..0ea47167be6a --- /dev/null +++ b/device/quanta/x86_64-quanta_ix7_bwde-r0/media_settings.json @@ -0,0 +1,254 @@ +{ + "GLOBAL_MEDIA_SETTINGS": { + "1-1": { + "Default": { + "preemphasis": { + "lane0": "0x114D06", + "lane1": "0x0F4F06", + "lane2": "0x0F4F06", + "lane3": "0x104E06" + } + } + }, + "2,4": { + "Default": { + "preemphasis": { + "lane0": "0x104E06", + "lane1": "0x104E06", + "lane2": "0x114D06", + "lane3": "0x104E06" + } + } + }, + "3-3": { + "Default": { + "preemphasis": { + "lane0": "0x104E06", + "lane1": "0x104E06", + "lane2": "0x104E06", + "lane3": "0x104E06" + } + } + }, + "5-5": { + "Default": { + "preemphasis": { + "lane0": "0x104E06", + "lane1": "0x114D06", + "lane2": "0x0F4F06", + "lane3": "0x114D06" + } + } + }, + "6-6": { + "Default": { + "preemphasis": { + "lane0": "0x0F4F06", + "lane1": "0x0F4F06", + "lane2": "0x104E06", + "lane3": "0x114D06" + } + } + }, + "7-7": { + "Default": { + "preemphasis": { + "lane0": "0x0F4F06", + "lane1": "0x0F4F06", + "lane2": "0x0D5106", + "lane3": "0x0F4F06" + } + } + }, + "8-8": { + "Default": { + "preemphasis": { + "lane0": "0x0D5106", + "lane1": "0x0D5106", + "lane2": "0x0D5106", + "lane3": "0x0E5006" + } + } + }, + "9,23": { + "Default": { + "preemphasis": { + "lane0": "0x0C5206", + "lane1": "0x0C5206", + "lane2": "0x0C5206", + "lane3": "0x0C5206" + } + } + }, + "10-10": { + "Default": { + "preemphasis": { + "lane0": "0x0A5406", + "lane1": "0x0C5206", + "lane2": "0x0A5406", + "lane3": "0x0C5206" + } + } + }, + "11,13": { + "Default": { + "preemphasis": { + "lane0": "0x0A5406", + "lane1": "0x0B5306", + "lane2": "0x0A5406", + "lane3": "0x0B5306" + } + } + }, + "12,14": { + "Default": { + "preemphasis": { + "lane0": "0x0A5406", + "lane1": "0x0B5306", + "lane2": "0x0A5406", + "lane3": "0x0A5406" + } + } + }, + "15,17": { + "Default": { + "preemphasis": { + "lane0": "0x095506", + "lane1": "0x095506", + "lane2": "0x095506", + "lane3": "0x095506" + } + } + }, + "16-16": { + "Default": { + "preemphasis": { + "lane0": "0x0A5406", + "lane1": "0x0A5406", + "lane2": "0x0A5406", + "lane3": "0x095506" + } + } + }, + "18,19": { + "Default": { + "preemphasis": { + "lane0": "0x0A5406", + "lane1": "0x0A5406", + "lane2": "0x0A5406", + "lane3": "0x0A5406" + } + } + }, + "20-20": { + "Default": { + "preemphasis": { + "lane0": "0x0B5306", + "lane1": "0x0C5206", + "lane2": "0x0A5406", + "lane3": "0x0C5206" + } + } + }, + "21-21": { + "Default": { + "preemphasis": { + "lane0": "0x0B5306", + "lane1": "0x0B5306", + "lane2": "0x0B5306", + "lane3": "0x0B5306" + } + } + }, + "22-22": { + "Default": { + "preemphasis": { + "lane0": "0x0B5306", + "lane1": "0x0C5206", + "lane2": "0x0A5406", + "lane3": "0x0A5406" + } + } + }, + "24-24": { + "Default": { + "preemphasis": { + "lane0": "0x0C5206", + "lane1": "0x0C5206", + "lane2": "0x0B5306", + "lane3": "0x0C5206" + } + } + }, + "25-25": { + "Default": { + "preemphasis": { + "lane0": "0x0E5006", + "lane1": "0x0D5106", + "lane2": "0x0D5106", + "lane3": "0x0D5106" + } + } + }, + "26-26": { + "Default": { + "preemphasis": { + "lane0": "0x0E5006", + "lane1": "0x0E5006", + "lane2": "0x0D5106", + "lane3": "0x0E5006" + } + } + }, + "27-27": { + "Default": { + "preemphasis": { + "lane0": "0x0F4F06", + "lane1": "0x114D06", + "lane2": "0x104E06", + "lane3": "0x114D06" + } + } + }, + "28,31": { + "Default": { + "preemphasis": { + "lane0": "0x104E06", + "lane1": "0x114D06", + "lane2": "0x104E06", + "lane3": "0x114D06" + } + } + }, + "29-29": { + "Default": { + "preemphasis": { + "lane0": "0x0F4F06", + "lane1": "0x104E06", + "lane2": "0x104E06", + "lane3": "0x104E06" + } + } + }, + "30-30": { + "Default": { + "preemphasis": { + "lane0": "0x114D06", + "lane1": "0x114D06", + "lane2": "0x114D06", + "lane3": "0x114D06" + } + } + }, + "32-32": { + "Default": { + "preemphasis": { + "lane0": "0x104E06", + "lane1": "0x104E06", + "lane2": "0x114D06", + "lane3": "0x114D06" + } + } + } + } +} diff --git a/device/quanta/x86_64-quanta_ix7_bwde-r0/preemphasis-32x100G.soc b/device/quanta/x86_64-quanta_ix7_bwde-r0/preemphasis-32x100G.soc index 986bb271ca1b..f092f6c29aa3 100644 --- a/device/quanta/x86_64-quanta_ix7_bwde-r0/preemphasis-32x100G.soc +++ b/device/quanta/x86_64-quanta_ix7_bwde-r0/preemphasis-32x100G.soc @@ -1,546 +1,545 @@ # Pre-emphasis phy raw c45 0xa5 0x1 0xffde 0 -phy raw c45 0xa5 0x1 0xd130 0x4d -phy raw c45 0xa5 0x1 0xd131 0x0611 +phy raw c45 0xa5 0x1 0xd130 0x4D +phy raw c45 0xa5 0x1 0xd131 0x611 phy raw c45 0xa5 0x1 0xd134 1 phy raw c45 0xa5 0x1 0xffde 1 -phy raw c45 0xa5 0x1 0xd130 0x4d -phy raw c45 0xa5 0x1 0xd131 0x0611 +phy raw c45 0xa5 0x1 0xd130 0x4F +phy raw c45 0xa5 0x1 0xd131 0x60F phy raw c45 0xa5 0x1 0xd134 1 phy raw c45 0xa5 0x1 0xffde 2 -phy raw c45 0xa5 0x1 0xd130 0x4e -phy raw c45 0xa5 0x1 0xd131 0x0610 +phy raw c45 0xa5 0x1 0xd130 0x4F +phy raw c45 0xa5 0x1 0xd131 0x60F phy raw c45 0xa5 0x1 0xd134 1 phy raw c45 0xa5 0x1 0xffde 3 -phy raw c45 0xa5 0x1 0xd130 0x4e -phy raw c45 0xa5 0x1 0xd131 0x0610 +phy raw c45 0xa5 0x1 0xd130 0x4E +phy raw c45 0xa5 0x1 0xd131 0x610 phy raw c45 0xa5 0x1 0xd134 1 phy raw c45 0xa9 0x1 0xffde 0 -phy raw c45 0xa9 0x1 0xd130 0x4e -phy raw c45 0xa9 0x1 0xd131 0x0610 +phy raw c45 0xa9 0x1 0xd130 0x4E +phy raw c45 0xa9 0x1 0xd131 0x610 phy raw c45 0xa9 0x1 0xd134 1 phy raw c45 0xa9 0x1 0xffde 1 -phy raw c45 0xa9 0x1 0xd130 0x4e -phy raw c45 0xa9 0x1 0xd131 0x0610 +phy raw c45 0xa9 0x1 0xd130 0x4E +phy raw c45 0xa9 0x1 0xd131 0x610 phy raw c45 0xa9 0x1 0xd134 1 phy raw c45 0xa9 0x1 0xffde 2 -phy raw c45 0xa9 0x1 0xd130 0x4e -phy raw c45 0xa9 0x1 0xd131 0x0610 +phy raw c45 0xa9 0x1 0xd130 0x4D +phy raw c45 0xa9 0x1 0xd131 0x611 phy raw c45 0xa9 0x1 0xd134 1 phy raw c45 0xa9 0x1 0xffde 3 -phy raw c45 0xa9 0x1 0xd130 0x4e -phy raw c45 0xa9 0x1 0xd131 0x0610 +phy raw c45 0xa9 0x1 0xd130 0x4E +phy raw c45 0xa9 0x1 0xd131 0x610 phy raw c45 0xa9 0x1 0xd134 1 phy raw c45 0xc1 0x1 0xffde 0 -phy raw c45 0xc1 0x1 0xd130 0x4e -phy raw c45 0xc1 0x1 0xd131 0x0610 +phy raw c45 0xc1 0x1 0xd130 0x4E +phy raw c45 0xc1 0x1 0xd131 0x610 phy raw c45 0xc1 0x1 0xd134 1 phy raw c45 0xc1 0x1 0xffde 1 -phy raw c45 0xc1 0x1 0xd130 0x4d -phy raw c45 0xc1 0x1 0xd131 0x0611 +phy raw c45 0xc1 0x1 0xd130 0x4E +phy raw c45 0xc1 0x1 0xd131 0x610 phy raw c45 0xc1 0x1 0xd134 1 phy raw c45 0xc1 0x1 0xffde 2 -phy raw c45 0xc1 0x1 0xd130 0x4e -phy raw c45 0xc1 0x1 0xd131 0x0610 +phy raw c45 0xc1 0x1 0xd130 0x4E +phy raw c45 0xc1 0x1 0xd131 0x610 phy raw c45 0xc1 0x1 0xd134 1 phy raw c45 0xc1 0x1 0xffde 3 -phy raw c45 0xc1 0x1 0xd130 0x4e -phy raw c45 0xc1 0x1 0xd131 0x0610 +phy raw c45 0xc1 0x1 0xd130 0x4E +phy raw c45 0xc1 0x1 0xd131 0x610 phy raw c45 0xc1 0x1 0xd134 1 phy raw c45 0xc5 0x1 0xffde 0 -phy raw c45 0xc5 0x1 0xd130 0x4e -phy raw c45 0xc5 0x1 0xd131 0x0610 +phy raw c45 0xc5 0x1 0xd130 0x4E +phy raw c45 0xc5 0x1 0xd131 0x610 phy raw c45 0xc5 0x1 0xd134 1 phy raw c45 0xc5 0x1 0xffde 1 -phy raw c45 0xc5 0x1 0xd130 0x4e -phy raw c45 0xc5 0x1 0xd131 0x0610 +phy raw c45 0xc5 0x1 0xd130 0x4E +phy raw c45 0xc5 0x1 0xd131 0x610 phy raw c45 0xc5 0x1 0xd134 1 phy raw c45 0xc5 0x1 0xffde 2 -phy raw c45 0xc5 0x1 0xd130 0x4d -phy raw c45 0xc5 0x1 0xd131 0x0611 +phy raw c45 0xc5 0x1 0xd130 0x4D +phy raw c45 0xc5 0x1 0xd131 0x611 phy raw c45 0xc5 0x1 0xd134 1 phy raw c45 0xc5 0x1 0xffde 3 -phy raw c45 0xc5 0x1 0xd130 0x4e -phy raw c45 0xc5 0x1 0xd131 0x0610 +phy raw c45 0xc5 0x1 0xd130 0x4E +phy raw c45 0xc5 0x1 0xd131 0x610 phy raw c45 0xc5 0x1 0xd134 1 phy raw c45 0x81 0x1 0xffde 0 -phy raw c45 0x81 0x1 0xd130 0x4e -phy raw c45 0x81 0x1 0xd131 0x0610 +phy raw c45 0x81 0x1 0xd130 0x4E +phy raw c45 0x81 0x1 0xd131 0x610 phy raw c45 0x81 0x1 0xd134 1 phy raw c45 0x81 0x1 0xffde 1 -phy raw c45 0x81 0x1 0xd130 0x4d -phy raw c45 0x81 0x1 0xd131 0x0611 +phy raw c45 0x81 0x1 0xd130 0x4D +phy raw c45 0x81 0x1 0xd131 0x611 phy raw c45 0x81 0x1 0xd134 1 phy raw c45 0x81 0x1 0xffde 2 -phy raw c45 0x81 0x1 0xd130 0x4e -phy raw c45 0x81 0x1 0xd131 0x0610 +phy raw c45 0x81 0x1 0xd130 0x4F +phy raw c45 0x81 0x1 0xd131 0x60F phy raw c45 0x81 0x1 0xd134 1 phy raw c45 0x81 0x1 0xffde 3 -phy raw c45 0x81 0x1 0xd130 0x4e -phy raw c45 0x81 0x1 0xd131 0x0610 +phy raw c45 0x81 0x1 0xd130 0x4D +phy raw c45 0x81 0x1 0xd131 0x611 phy raw c45 0x81 0x1 0xd134 1 phy raw c45 0x85 0x1 0xffde 0 -phy raw c45 0x85 0x1 0xd130 0x4e -phy raw c45 0x85 0x1 0xd131 0x0610 +phy raw c45 0x85 0x1 0xd130 0x4F +phy raw c45 0x85 0x1 0xd131 0x60F phy raw c45 0x85 0x1 0xd134 1 phy raw c45 0x85 0x1 0xffde 1 -phy raw c45 0x85 0x1 0xd130 0x4e -phy raw c45 0x85 0x1 0xd131 0x0610 +phy raw c45 0x85 0x1 0xd130 0x4F +phy raw c45 0x85 0x1 0xd131 0x60F phy raw c45 0x85 0x1 0xd134 1 phy raw c45 0x85 0x1 0xffde 2 -phy raw c45 0x85 0x1 0xd130 0x4e -phy raw c45 0x85 0x1 0xd131 0x0610 +phy raw c45 0x85 0x1 0xd130 0x4E +phy raw c45 0x85 0x1 0xd131 0x610 phy raw c45 0x85 0x1 0xd134 1 phy raw c45 0x85 0x1 0xffde 3 -phy raw c45 0x85 0x1 0xd130 0x4d -phy raw c45 0x85 0x1 0xd131 0x0611 +phy raw c45 0x85 0x1 0xd130 0x4D +phy raw c45 0x85 0x1 0xd131 0x611 phy raw c45 0x85 0x1 0xd134 1 phy raw c45 0x89 0x1 0xffde 0 -phy raw c45 0x89 0x1 0xd130 0x50 -phy raw c45 0x89 0x1 0xd131 0x060e +phy raw c45 0x89 0x1 0xd130 0x4F +phy raw c45 0x89 0x1 0xd131 0x60F phy raw c45 0x89 0x1 0xd134 1 phy raw c45 0x89 0x1 0xffde 1 -phy raw c45 0x89 0x1 0xd130 0x50 -phy raw c45 0x89 0x1 0xd131 0x060e +phy raw c45 0x89 0x1 0xd130 0x4F +phy raw c45 0x89 0x1 0xd131 0x60F phy raw c45 0x89 0x1 0xd134 1 phy raw c45 0x89 0x1 0xffde 2 -phy raw c45 0x89 0x1 0xd130 0x50 -phy raw c45 0x89 0x1 0xd131 0x060e +phy raw c45 0x89 0x1 0xd130 0x51 +phy raw c45 0x89 0x1 0xd131 0x60D phy raw c45 0x89 0x1 0xd134 1 phy raw c45 0x89 0x1 0xffde 3 -phy raw c45 0x89 0x1 0xd130 0x50 -phy raw c45 0x89 0x1 0xd131 0x060e +phy raw c45 0x89 0x1 0xd130 0x4F +phy raw c45 0x89 0x1 0xd131 0x60F phy raw c45 0x89 0x1 0xd134 1 phy raw c45 0x8d 0x1 0xffde 0 -phy raw c45 0x8d 0x1 0xd130 0x4f -phy raw c45 0x8d 0x1 0xd131 0x060f +phy raw c45 0x8d 0x1 0xd130 0x51 +phy raw c45 0x8d 0x1 0xd131 0x60D phy raw c45 0x8d 0x1 0xd134 1 phy raw c45 0x8d 0x1 0xffde 1 -phy raw c45 0x8d 0x1 0xd130 0x4f -phy raw c45 0x8d 0x1 0xd131 0x060f +phy raw c45 0x8d 0x1 0xd130 0x51 +phy raw c45 0x8d 0x1 0xd131 0x60D phy raw c45 0x8d 0x1 0xd134 1 phy raw c45 0x8d 0x1 0xffde 2 -phy raw c45 0x8d 0x1 0xd130 0x4f -phy raw c45 0x8d 0x1 0xd131 0x060f +phy raw c45 0x8d 0x1 0xd130 0x51 +phy raw c45 0x8d 0x1 0xd131 0x60D phy raw c45 0x8d 0x1 0xd134 1 phy raw c45 0x8d 0x1 0xffde 3 -phy raw c45 0x8d 0x1 0xd130 0x4f -phy raw c45 0x8d 0x1 0xd131 0x060f +phy raw c45 0x8d 0x1 0xd130 0x50 +phy raw c45 0x8d 0x1 0xd131 0x60E phy raw c45 0x8d 0x1 0xd134 1 phy raw c45 0x91 0x1 0xffde 0 -phy raw c45 0x91 0x1 0xd130 0x50 -phy raw c45 0x91 0x1 0xd131 0x060e +phy raw c45 0x91 0x1 0xd130 0x52 +phy raw c45 0x91 0x1 0xd131 0x60C phy raw c45 0x91 0x1 0xd134 1 phy raw c45 0x91 0x1 0xffde 1 -phy raw c45 0x91 0x1 0xd130 0x50 -phy raw c45 0x91 0x1 0xd131 0x060e +phy raw c45 0x91 0x1 0xd130 0x52 +phy raw c45 0x91 0x1 0xd131 0x60C phy raw c45 0x91 0x1 0xd134 1 phy raw c45 0x91 0x1 0xffde 2 -phy raw c45 0x91 0x1 0xd130 0x50 -phy raw c45 0x91 0x1 0xd131 0x060e +phy raw c45 0x91 0x1 0xd130 0x52 +phy raw c45 0x91 0x1 0xd131 0x60C phy raw c45 0x91 0x1 0xd134 1 phy raw c45 0x91 0x1 0xffde 3 -phy raw c45 0x91 0x1 0xd130 0x50 -phy raw c45 0x91 0x1 0xd131 0x060e +phy raw c45 0x91 0x1 0xd130 0x52 +phy raw c45 0x91 0x1 0xd131 0x60C phy raw c45 0x91 0x1 0xd134 1 phy raw c45 0x95 0x1 0xffde 0 -phy raw c45 0x95 0x1 0xd130 0x52 -phy raw c45 0x95 0x1 0xd131 0x060c +phy raw c45 0x95 0x1 0xd130 0x54 +phy raw c45 0x95 0x1 0xd131 0x60A phy raw c45 0x95 0x1 0xd134 1 phy raw c45 0x95 0x1 0xffde 1 phy raw c45 0x95 0x1 0xd130 0x52 -phy raw c45 0x95 0x1 0xd131 0x060c +phy raw c45 0x95 0x1 0xd131 0x60C phy raw c45 0x95 0x1 0xd134 1 phy raw c45 0x95 0x1 0xffde 2 -phy raw c45 0x95 0x1 0xd130 0x52 -phy raw c45 0x95 0x1 0xd131 0x060c +phy raw c45 0x95 0x1 0xd130 0x54 +phy raw c45 0x95 0x1 0xd131 0x60A phy raw c45 0x95 0x1 0xd134 1 phy raw c45 0x95 0x1 0xffde 3 phy raw c45 0x95 0x1 0xd130 0x52 -phy raw c45 0x95 0x1 0xd131 0x060c +phy raw c45 0x95 0x1 0xd131 0x60C phy raw c45 0x95 0x1 0xd134 1 phy raw c45 0xa1 0x1 0xffde 0 -phy raw c45 0xa1 0x1 0xd130 0x52 -phy raw c45 0xa1 0x1 0xd131 0x060c +phy raw c45 0xa1 0x1 0xd130 0x54 +phy raw c45 0xa1 0x1 0xd131 0x60A phy raw c45 0xa1 0x1 0xd134 1 phy raw c45 0xa1 0x1 0xffde 1 -phy raw c45 0xa1 0x1 0xd130 0x52 -phy raw c45 0xa1 0x1 0xd131 0x060c +phy raw c45 0xa1 0x1 0xd130 0x53 +phy raw c45 0xa1 0x1 0xd131 0x60B phy raw c45 0xa1 0x1 0xd134 1 phy raw c45 0xa1 0x1 0xffde 2 -phy raw c45 0xa1 0x1 0xd130 0x52 -phy raw c45 0xa1 0x1 0xd131 0x060c +phy raw c45 0xa1 0x1 0xd130 0x54 +phy raw c45 0xa1 0x1 0xd131 0x60A phy raw c45 0xa1 0x1 0xd134 1 phy raw c45 0xa1 0x1 0xffde 3 -phy raw c45 0xa1 0x1 0xd130 0x52 -phy raw c45 0xa1 0x1 0xd131 0x060c +phy raw c45 0xa1 0x1 0xd130 0x53 +phy raw c45 0xa1 0x1 0xd131 0x60B phy raw c45 0xa1 0x1 0xd134 1 phy raw c45 0xad 0x1 0xffde 0 -phy raw c45 0xad 0x1 0xd130 0x53 -phy raw c45 0xad 0x1 0xd131 0x060b +phy raw c45 0xad 0x1 0xd130 0x54 +phy raw c45 0xad 0x1 0xd131 0x60A phy raw c45 0xad 0x1 0xd134 1 phy raw c45 0xad 0x1 0xffde 1 phy raw c45 0xad 0x1 0xd130 0x53 -phy raw c45 0xad 0x1 0xd131 0x060b +phy raw c45 0xad 0x1 0xd131 0x60B phy raw c45 0xad 0x1 0xd134 1 phy raw c45 0xad 0x1 0xffde 2 -phy raw c45 0xad 0x1 0xd130 0x53 -phy raw c45 0xad 0x1 0xd131 0x060b +phy raw c45 0xad 0x1 0xd130 0x54 +phy raw c45 0xad 0x1 0xd131 0x60A phy raw c45 0xad 0x1 0xd134 1 phy raw c45 0xad 0x1 0xffde 3 -phy raw c45 0xad 0x1 0xd130 0x53 -phy raw c45 0xad 0x1 0xd131 0x060b +phy raw c45 0xad 0x1 0xd130 0x54 +phy raw c45 0xad 0x1 0xd131 0x60A phy raw c45 0xad 0x1 0xd134 1 phy raw c45 0xc9 0x1 0xffde 0 -phy raw c45 0xc9 0x1 0xd130 0x53 -phy raw c45 0xc9 0x1 0xd131 0x060b +phy raw c45 0xc9 0x1 0xd130 0x54 +phy raw c45 0xc9 0x1 0xd131 0x60A phy raw c45 0xc9 0x1 0xd134 1 phy raw c45 0xc9 0x1 0xffde 1 phy raw c45 0xc9 0x1 0xd130 0x53 -phy raw c45 0xc9 0x1 0xd131 0x060b +phy raw c45 0xc9 0x1 0xd131 0x60B phy raw c45 0xc9 0x1 0xd134 1 phy raw c45 0xc9 0x1 0xffde 2 -phy raw c45 0xc9 0x1 0xd130 0x53 -phy raw c45 0xc9 0x1 0xd131 0x060b +phy raw c45 0xc9 0x1 0xd130 0x54 +phy raw c45 0xc9 0x1 0xd131 0x60A phy raw c45 0xc9 0x1 0xd134 1 phy raw c45 0xc9 0x1 0xffde 3 phy raw c45 0xc9 0x1 0xd130 0x53 -phy raw c45 0xc9 0x1 0xd131 0x060b +phy raw c45 0xc9 0x1 0xd131 0x60B phy raw c45 0xc9 0x1 0xd134 1 phy raw c45 0xcd 0x1 0xffde 0 phy raw c45 0xcd 0x1 0xd130 0x54 -phy raw c45 0xcd 0x1 0xd131 0x060a +phy raw c45 0xcd 0x1 0xd131 0x60A phy raw c45 0xcd 0x1 0xd134 1 phy raw c45 0xcd 0x1 0xffde 1 -phy raw c45 0xcd 0x1 0xd130 0x54 -phy raw c45 0xcd 0x1 0xd131 0x060a +phy raw c45 0xcd 0x1 0xd130 0x53 +phy raw c45 0xcd 0x1 0xd131 0x60B phy raw c45 0xcd 0x1 0xd134 1 phy raw c45 0xcd 0x1 0xffde 2 phy raw c45 0xcd 0x1 0xd130 0x54 -phy raw c45 0xcd 0x1 0xd131 0x060a +phy raw c45 0xcd 0x1 0xd131 0x60A phy raw c45 0xcd 0x1 0xd134 1 phy raw c45 0xcd 0x1 0xffde 3 phy raw c45 0xcd 0x1 0xd130 0x54 -phy raw c45 0xcd 0x1 0xd131 0x060a +phy raw c45 0xcd 0x1 0xd131 0x60A phy raw c45 0xcd 0x1 0xd134 1 phy raw c45 0xd1 0x1 0xffde 0 -phy raw c45 0xd1 0x1 0xd130 0x56 -phy raw c45 0xd1 0x1 0xd131 0x0608 +phy raw c45 0xd1 0x1 0xd130 0x55 +phy raw c45 0xd1 0x1 0xd131 0x609 phy raw c45 0xd1 0x1 0xd134 1 phy raw c45 0xd1 0x1 0xffde 1 -phy raw c45 0xd1 0x1 0xd130 0x56 -phy raw c45 0xd1 0x1 0xd131 0x0608 +phy raw c45 0xd1 0x1 0xd130 0x55 +phy raw c45 0xd1 0x1 0xd131 0x609 phy raw c45 0xd1 0x1 0xd134 1 phy raw c45 0xd1 0x1 0xffde 2 -phy raw c45 0xd1 0x1 0xd130 0x56 -phy raw c45 0xd1 0x1 0xd131 0x0608 +phy raw c45 0xd1 0x1 0xd130 0x55 +phy raw c45 0xd1 0x1 0xd131 0x609 phy raw c45 0xd1 0x1 0xd134 1 phy raw c45 0xd1 0x1 0xffde 3 -phy raw c45 0xd1 0x1 0xd130 0x56 -phy raw c45 0xd1 0x1 0xd131 0x0608 +phy raw c45 0xd1 0x1 0xd130 0x55 +phy raw c45 0xd1 0x1 0xd131 0x609 phy raw c45 0xd1 0x1 0xd134 1 phy raw c45 0xd5 0x1 0xffde 0 -phy raw c45 0xd5 0x1 0xd130 0x55 -phy raw c45 0xd5 0x1 0xd131 0x0609 +phy raw c45 0xd5 0x1 0xd130 0x54 +phy raw c45 0xd5 0x1 0xd131 0x60A phy raw c45 0xd5 0x1 0xd134 1 phy raw c45 0xd5 0x1 0xffde 1 -phy raw c45 0xd5 0x1 0xd130 0x55 -phy raw c45 0xd5 0x1 0xd131 0x0609 +phy raw c45 0xd5 0x1 0xd130 0x54 +phy raw c45 0xd5 0x1 0xd131 0x60A phy raw c45 0xd5 0x1 0xd134 1 phy raw c45 0xd5 0x1 0xffde 2 -phy raw c45 0xd5 0x1 0xd130 0x55 -phy raw c45 0xd5 0x1 0xd131 0x0609 +phy raw c45 0xd5 0x1 0xd130 0x54 +phy raw c45 0xd5 0x1 0xd131 0x60A phy raw c45 0xd5 0x1 0xd134 1 phy raw c45 0xd5 0x1 0xffde 3 phy raw c45 0xd5 0x1 0xd130 0x55 -phy raw c45 0xd5 0x1 0xd131 0x0609 +phy raw c45 0xd5 0x1 0xd131 0x609 phy raw c45 0xd5 0x1 0xd134 1 phy raw c45 0xe1 0x1 0xffde 0 -phy raw c45 0xe1 0x1 0xd130 0x56 -phy raw c45 0xe1 0x1 0xd131 0x0608 +phy raw c45 0xe1 0x1 0xd130 0x55 +phy raw c45 0xe1 0x1 0xd131 0x609 phy raw c45 0xe1 0x1 0xd134 1 phy raw c45 0xe1 0x1 0xffde 1 -phy raw c45 0xe1 0x1 0xd130 0x56 -phy raw c45 0xe1 0x1 0xd131 0x0608 +phy raw c45 0xe1 0x1 0xd130 0x55 +phy raw c45 0xe1 0x1 0xd131 0x609 phy raw c45 0xe1 0x1 0xd134 1 phy raw c45 0xe1 0x1 0xffde 2 -phy raw c45 0xe1 0x1 0xd130 0x56 -phy raw c45 0xe1 0x1 0xd131 0x0608 +phy raw c45 0xe1 0x1 0xd130 0x55 +phy raw c45 0xe1 0x1 0xd131 0x609 phy raw c45 0xe1 0x1 0xd134 1 phy raw c45 0xe1 0x1 0xffde 3 -phy raw c45 0xe1 0x1 0xd130 0x56 -phy raw c45 0xe1 0x1 0xd131 0x0608 +phy raw c45 0xe1 0x1 0xd130 0x55 +phy raw c45 0xe1 0x1 0xd131 0x609 phy raw c45 0xe1 0x1 0xd134 1 phy raw c45 0xe5 0x1 0xffde 0 -phy raw c45 0xe5 0x1 0xd130 0x55 -phy raw c45 0xe5 0x1 0xd131 0x0609 +phy raw c45 0xe5 0x1 0xd130 0x54 +phy raw c45 0xe5 0x1 0xd131 0x60A phy raw c45 0xe5 0x1 0xd134 1 phy raw c45 0xe5 0x1 0xffde 1 -phy raw c45 0xe5 0x1 0xd130 0x55 -phy raw c45 0xe5 0x1 0xd131 0x0609 +phy raw c45 0xe5 0x1 0xd130 0x54 +phy raw c45 0xe5 0x1 0xd131 0x60A phy raw c45 0xe5 0x1 0xd134 1 phy raw c45 0xe5 0x1 0xffde 2 -phy raw c45 0xe5 0x1 0xd130 0x55 -phy raw c45 0xe5 0x1 0xd131 0x0609 +phy raw c45 0xe5 0x1 0xd130 0x54 +phy raw c45 0xe5 0x1 0xd131 0x60A phy raw c45 0xe5 0x1 0xd134 1 phy raw c45 0xe5 0x1 0xffde 3 -phy raw c45 0xe5 0x1 0xd130 0x55 -phy raw c45 0xe5 0x1 0xd131 0x0609 +phy raw c45 0xe5 0x1 0xd130 0x54 +phy raw c45 0xe5 0x1 0xd131 0x60A phy raw c45 0xe5 0x1 0xd134 1 phy raw c45 0xe9 0x1 0xffde 0 -phy raw c45 0xe9 0x1 0xd130 0x56 -phy raw c45 0xe9 0x1 0xd131 0x0608 +phy raw c45 0xe9 0x1 0xd130 0x54 +phy raw c45 0xe9 0x1 0xd131 0x60A phy raw c45 0xe9 0x1 0xd134 1 phy raw c45 0xe9 0x1 0xffde 1 -phy raw c45 0xe9 0x1 0xd130 0x56 -phy raw c45 0xe9 0x1 0xd131 0x0608 +phy raw c45 0xe9 0x1 0xd130 0x54 +phy raw c45 0xe9 0x1 0xd131 0x60A phy raw c45 0xe9 0x1 0xd134 1 phy raw c45 0xe9 0x1 0xffde 2 -phy raw c45 0xe9 0x1 0xd130 0x56 -phy raw c45 0xe9 0x1 0xd131 0x0608 +phy raw c45 0xe9 0x1 0xd130 0x54 +phy raw c45 0xe9 0x1 0xd131 0x60A phy raw c45 0xe9 0x1 0xd134 1 phy raw c45 0xe9 0x1 0xffde 3 -phy raw c45 0xe9 0x1 0xd130 0x56 -phy raw c45 0xe9 0x1 0xd131 0x0608 +phy raw c45 0xe9 0x1 0xd130 0x54 +phy raw c45 0xe9 0x1 0xd131 0x60A phy raw c45 0xe9 0x1 0xd134 1 phy raw c45 0xed 0x1 0xffde 0 -phy raw c45 0xed 0x1 0xd130 0x55 -phy raw c45 0xed 0x1 0xd131 0x0609 +phy raw c45 0xed 0x1 0xd130 0x53 +phy raw c45 0xed 0x1 0xd131 0x60B phy raw c45 0xed 0x1 0xd134 1 phy raw c45 0xed 0x1 0xffde 1 -phy raw c45 0xed 0x1 0xd130 0x53 -phy raw c45 0xed 0x1 0xd131 0x060b +phy raw c45 0xed 0x1 0xd130 0x52 +phy raw c45 0xed 0x1 0xd131 0x60C phy raw c45 0xed 0x1 0xd134 1 phy raw c45 0xed 0x1 0xffde 2 phy raw c45 0xed 0x1 0xd130 0x54 -phy raw c45 0xed 0x1 0xd131 0x060a +phy raw c45 0xed 0x1 0xd131 0x60A phy raw c45 0xed 0x1 0xd134 1 phy raw c45 0xed 0x1 0xffde 3 -phy raw c45 0xed 0x1 0xd130 0x54 -phy raw c45 0xed 0x1 0xd131 0x060a +phy raw c45 0xed 0x1 0xd130 0x52 +phy raw c45 0xed 0x1 0xd131 0x60C phy raw c45 0xed 0x1 0xd134 1 phy raw c45 0x185 0x1 0xffde 0 -phy raw c45 0x185 0x1 0xd130 0x55 -phy raw c45 0x185 0x1 0xd131 0x0609 +phy raw c45 0x185 0x1 0xd130 0x53 +phy raw c45 0x185 0x1 0xd131 0x60B phy raw c45 0x185 0x1 0xd134 1 phy raw c45 0x185 0x1 0xffde 1 -phy raw c45 0x185 0x1 0xd130 0x55 -phy raw c45 0x185 0x1 0xd131 0x0609 +phy raw c45 0x185 0x1 0xd130 0x53 +phy raw c45 0x185 0x1 0xd131 0x60B phy raw c45 0x185 0x1 0xd134 1 phy raw c45 0x185 0x1 0xffde 2 -phy raw c45 0x185 0x1 0xd130 0x55 -phy raw c45 0x185 0x1 0xd131 0x0609 +phy raw c45 0x185 0x1 0xd130 0x53 +phy raw c45 0x185 0x1 0xd131 0x60B phy raw c45 0x185 0x1 0xd134 1 phy raw c45 0x185 0x1 0xffde 3 -phy raw c45 0x185 0x1 0xd130 0x55 -phy raw c45 0x185 0x1 0xd131 0x0609 +phy raw c45 0x185 0x1 0xd130 0x53 +phy raw c45 0x185 0x1 0xd131 0x60B phy raw c45 0x185 0x1 0xd134 1 phy raw c45 0x18d 0x1 0xffde 0 -phy raw c45 0x18d 0x1 0xd130 0x54 -phy raw c45 0x18d 0x1 0xd131 0x060a +phy raw c45 0x18d 0x1 0xd130 0x53 +phy raw c45 0x18d 0x1 0xd131 0x60B phy raw c45 0x18d 0x1 0xd134 1 phy raw c45 0x18d 0x1 0xffde 1 -phy raw c45 0x18d 0x1 0xd130 0x53 -phy raw c45 0x18d 0x1 0xd131 0x060b +phy raw c45 0x18d 0x1 0xd130 0x52 +phy raw c45 0x18d 0x1 0xd131 0x60C phy raw c45 0x18d 0x1 0xd134 1 phy raw c45 0x18d 0x1 0xffde 2 -phy raw c45 0x18d 0x1 0xd130 0x53 -phy raw c45 0x18d 0x1 0xd131 0x060b +phy raw c45 0x18d 0x1 0xd130 0x54 +phy raw c45 0x18d 0x1 0xd131 0x60A phy raw c45 0x18d 0x1 0xd134 1 phy raw c45 0x18d 0x1 0xffde 3 -phy raw c45 0x18d 0x1 0xd130 0x53 -phy raw c45 0x18d 0x1 0xd131 0x060b +phy raw c45 0x18d 0x1 0xd130 0x54 +phy raw c45 0x18d 0x1 0xd131 0x60A phy raw c45 0x18d 0x1 0xd134 1 phy raw c45 0x1a1 0x1 0xffde 0 -phy raw c45 0x1a1 0x1 0xd130 0x55 -phy raw c45 0x1a1 0x1 0xd131 0x0609 +phy raw c45 0x1a1 0x1 0xd130 0x52 +phy raw c45 0x1a1 0x1 0xd131 0x60C phy raw c45 0x1a1 0x1 0xd134 1 phy raw c45 0x1a1 0x1 0xffde 1 -phy raw c45 0x1a1 0x1 0xd130 0x54 -phy raw c45 0x1a1 0x1 0xd131 0x060a +phy raw c45 0x1a1 0x1 0xd130 0x52 +phy raw c45 0x1a1 0x1 0xd131 0x60C phy raw c45 0x1a1 0x1 0xd134 1 phy raw c45 0x1a1 0x1 0xffde 2 -phy raw c45 0x1a1 0x1 0xd130 0x55 -phy raw c45 0x1a1 0x1 0xd131 0x0609 +phy raw c45 0x1a1 0x1 0xd130 0x52 +phy raw c45 0x1a1 0x1 0xd131 0x60C phy raw c45 0x1a1 0x1 0xd134 1 phy raw c45 0x1a1 0x1 0xffde 3 -phy raw c45 0x1a1 0x1 0xd130 0x53 -phy raw c45 0x1a1 0x1 0xd131 0x060b +phy raw c45 0x1a1 0x1 0xd130 0x52 +phy raw c45 0x1a1 0x1 0xd131 0x60C phy raw c45 0x1a1 0x1 0xd134 1 phy raw c45 0x1a5 0x1 0xffde 0 -phy raw c45 0x1a5 0x1 0xd130 0x54 -phy raw c45 0x1a5 0x1 0xd131 0x060a +phy raw c45 0x1a5 0x1 0xd130 0x52 +phy raw c45 0x1a5 0x1 0xd131 0x60C phy raw c45 0x1a5 0x1 0xd134 1 phy raw c45 0x1a5 0x1 0xffde 1 -phy raw c45 0x1a5 0x1 0xd130 0x53 -phy raw c45 0x1a5 0x1 0xd131 0x060b +phy raw c45 0x1a5 0x1 0xd130 0x52 +phy raw c45 0x1a5 0x1 0xd131 0x60C phy raw c45 0x1a5 0x1 0xd134 1 phy raw c45 0x1a5 0x1 0xffde 2 phy raw c45 0x1a5 0x1 0xd130 0x53 -phy raw c45 0x1a5 0x1 0xd131 0x060b +phy raw c45 0x1a5 0x1 0xd131 0x60B phy raw c45 0x1a5 0x1 0xd134 1 phy raw c45 0x1a5 0x1 0xffde 3 -phy raw c45 0x1a5 0x1 0xd130 0x53 -phy raw c45 0x1a5 0x1 0xd131 0x060b +phy raw c45 0x1a5 0x1 0xd130 0x52 +phy raw c45 0x1a5 0x1 0xd131 0x60C phy raw c45 0x1a5 0x1 0xd134 1 phy raw c45 0x1a9 0x1 0xffde 0 -phy raw c45 0x1a9 0x1 0xd130 0x54 -phy raw c45 0x1a9 0x1 0xd131 0x060a +phy raw c45 0x1a9 0x1 0xd130 0x50 +phy raw c45 0x1a9 0x1 0xd131 0x60E phy raw c45 0x1a9 0x1 0xd134 1 phy raw c45 0x1a9 0x1 0xffde 1 phy raw c45 0x1a9 0x1 0xd130 0x51 -phy raw c45 0x1a9 0x1 0xd131 0x060d +phy raw c45 0x1a9 0x1 0xd131 0x60D phy raw c45 0x1a9 0x1 0xd134 1 phy raw c45 0x1a9 0x1 0xffde 2 -phy raw c45 0x1a9 0x1 0xd130 0x52 -phy raw c45 0x1a9 0x1 0xd131 0x060c +phy raw c45 0x1a9 0x1 0xd130 0x51 +phy raw c45 0x1a9 0x1 0xd131 0x60D phy raw c45 0x1a9 0x1 0xd134 1 phy raw c45 0x1a9 0x1 0xffde 3 -phy raw c45 0x1a9 0x1 0xd130 0x52 -phy raw c45 0x1a9 0x1 0xd131 0x060c +phy raw c45 0x1a9 0x1 0xd130 0x51 +phy raw c45 0x1a9 0x1 0xd131 0x60D phy raw c45 0x1a9 0x1 0xd134 1 phy raw c45 0x1ad 0x1 0xffde 0 -phy raw c45 0x1ad 0x1 0xd130 0x51 -phy raw c45 0x1ad 0x1 0xd131 0x060d +phy raw c45 0x1ad 0x1 0xd130 0x50 +phy raw c45 0x1ad 0x1 0xd131 0x60E phy raw c45 0x1ad 0x1 0xd134 1 phy raw c45 0x1ad 0x1 0xffde 1 -phy raw c45 0x1ad 0x1 0xd130 0x4f -phy raw c45 0x1ad 0x1 0xd131 0x060f +phy raw c45 0x1ad 0x1 0xd130 0x50 +phy raw c45 0x1ad 0x1 0xd131 0x60E phy raw c45 0x1ad 0x1 0xd134 1 phy raw c45 0x1ad 0x1 0xffde 2 -phy raw c45 0x1ad 0x1 0xd130 0x4f -phy raw c45 0x1ad 0x1 0xd131 0x060f +phy raw c45 0x1ad 0x1 0xd130 0x51 +phy raw c45 0x1ad 0x1 0xd131 0x60D phy raw c45 0x1ad 0x1 0xd134 1 phy raw c45 0x1ad 0x1 0xffde 3 -phy raw c45 0x1ad 0x1 0xd130 0x4f -phy raw c45 0x1ad 0x1 0xd131 0x060f +phy raw c45 0x1ad 0x1 0xd130 0x50 +phy raw c45 0x1ad 0x1 0xd131 0x60E phy raw c45 0x1ad 0x1 0xd134 1 phy raw c45 0x1b1 0x1 0xffde 0 -phy raw c45 0x1b1 0x1 0xd130 0x4f -phy raw c45 0x1b1 0x1 0xd131 0x060f +phy raw c45 0x1b1 0x1 0xd130 0x4F +phy raw c45 0x1b1 0x1 0xd131 0x60F phy raw c45 0x1b1 0x1 0xd134 1 phy raw c45 0x1b1 0x1 0xffde 1 -phy raw c45 0x1b1 0x1 0xd130 0x4f -phy raw c45 0x1b1 0x1 0xd131 0x060f +phy raw c45 0x1b1 0x1 0xd130 0x4D +phy raw c45 0x1b1 0x1 0xd131 0x611 phy raw c45 0x1b1 0x1 0xd134 1 phy raw c45 0x1b1 0x1 0xffde 2 -phy raw c45 0x1b1 0x1 0xd130 0x4f -phy raw c45 0x1b1 0x1 0xd131 0x060f +phy raw c45 0x1b1 0x1 0xd130 0x4E +phy raw c45 0x1b1 0x1 0xd131 0x610 phy raw c45 0x1b1 0x1 0xd134 1 phy raw c45 0x1b1 0x1 0xffde 3 -phy raw c45 0x1b1 0x1 0xd130 0x4f -phy raw c45 0x1b1 0x1 0xd131 0x060f +phy raw c45 0x1b1 0x1 0xd130 0x4D +phy raw c45 0x1b1 0x1 0xd131 0x611 phy raw c45 0x1b1 0x1 0xd134 1 phy raw c45 0x1b5 0x1 0xffde 0 -phy raw c45 0x1b5 0x1 0xd130 0x4e -phy raw c45 0x1b5 0x1 0xd131 0x0610 +phy raw c45 0x1b5 0x1 0xd130 0x4E +phy raw c45 0x1b5 0x1 0xd131 0x610 phy raw c45 0x1b5 0x1 0xd134 1 phy raw c45 0x1b5 0x1 0xffde 1 -phy raw c45 0x1b5 0x1 0xd130 0x4d -phy raw c45 0x1b5 0x1 0xd131 0x0611 +phy raw c45 0x1b5 0x1 0xd130 0x4D +phy raw c45 0x1b5 0x1 0xd131 0x611 phy raw c45 0x1b5 0x1 0xd134 1 phy raw c45 0x1b5 0x1 0xffde 2 -phy raw c45 0x1b5 0x1 0xd130 0x4d -phy raw c45 0x1b5 0x1 0xd131 0x0611 +phy raw c45 0x1b5 0x1 0xd130 0x4E +phy raw c45 0x1b5 0x1 0xd131 0x610 phy raw c45 0x1b5 0x1 0xd134 1 phy raw c45 0x1b5 0x1 0xffde 3 -phy raw c45 0x1b5 0x1 0xd130 0x4d -phy raw c45 0x1b5 0x1 0xd131 0x0611 +phy raw c45 0x1b5 0x1 0xd130 0x4D +phy raw c45 0x1b5 0x1 0xd131 0x611 phy raw c45 0x1b5 0x1 0xd134 1 phy raw c45 0xf1 0x1 0xffde 0 -phy raw c45 0xf1 0x1 0xd130 0x4f -phy raw c45 0xf1 0x1 0xd131 0x060f +phy raw c45 0xf1 0x1 0xd130 0x4F +phy raw c45 0xf1 0x1 0xd131 0x60F phy raw c45 0xf1 0x1 0xd134 1 phy raw c45 0xf1 0x1 0xffde 1 -phy raw c45 0xf1 0x1 0xd130 0x4f -phy raw c45 0xf1 0x1 0xd131 0x060f +phy raw c45 0xf1 0x1 0xd130 0x4E +phy raw c45 0xf1 0x1 0xd131 0x610 phy raw c45 0xf1 0x1 0xd134 1 phy raw c45 0xf1 0x1 0xffde 2 -phy raw c45 0xf1 0x1 0xd130 0x4f -phy raw c45 0xf1 0x1 0xd131 0x060f +phy raw c45 0xf1 0x1 0xd130 0x4E +phy raw c45 0xf1 0x1 0xd131 0x610 phy raw c45 0xf1 0x1 0xd134 1 phy raw c45 0xf1 0x1 0xffde 3 -phy raw c45 0xf1 0x1 0xd130 0x4f -phy raw c45 0xf1 0x1 0xd131 0x060f +phy raw c45 0xf1 0x1 0xd130 0x4E +phy raw c45 0xf1 0x1 0xd131 0x610 phy raw c45 0xf1 0x1 0xd134 1 phy raw c45 0xf5 0x1 0xffde 0 -phy raw c45 0xf5 0x1 0xd130 0x4d -phy raw c45 0xf5 0x1 0xd131 0x0611 +phy raw c45 0xf5 0x1 0xd130 0x4D +phy raw c45 0xf5 0x1 0xd131 0x611 phy raw c45 0xf5 0x1 0xd134 1 phy raw c45 0xf5 0x1 0xffde 1 -phy raw c45 0xf5 0x1 0xd130 0x4d -phy raw c45 0xf5 0x1 0xd131 0x0611 +phy raw c45 0xf5 0x1 0xd130 0x4D +phy raw c45 0xf5 0x1 0xd131 0x611 phy raw c45 0xf5 0x1 0xd134 1 phy raw c45 0xf5 0x1 0xffde 2 -phy raw c45 0xf5 0x1 0xd130 0x4d -phy raw c45 0xf5 0x1 0xd131 0x0611 +phy raw c45 0xf5 0x1 0xd130 0x4D +phy raw c45 0xf5 0x1 0xd131 0x611 phy raw c45 0xf5 0x1 0xd134 1 phy raw c45 0xf5 0x1 0xffde 3 -phy raw c45 0xf5 0x1 0xd130 0x4d -phy raw c45 0xf5 0x1 0xd131 0x0611 +phy raw c45 0xf5 0x1 0xd130 0x4D +phy raw c45 0xf5 0x1 0xd131 0x611 phy raw c45 0xf5 0x1 0xd134 1 phy raw c45 0x181 0x1 0xffde 0 -phy raw c45 0x181 0x1 0xd130 0x4e -phy raw c45 0x181 0x1 0xd131 0x0610 +phy raw c45 0x181 0x1 0xd130 0x4E +phy raw c45 0x181 0x1 0xd131 0x610 phy raw c45 0x181 0x1 0xd134 1 phy raw c45 0x181 0x1 0xffde 1 -phy raw c45 0x181 0x1 0xd130 0x4e -phy raw c45 0x181 0x1 0xd131 0x0610 +phy raw c45 0x181 0x1 0xd130 0x4D +phy raw c45 0x181 0x1 0xd131 0x611 phy raw c45 0x181 0x1 0xd134 1 phy raw c45 0x181 0x1 0xffde 2 -phy raw c45 0x181 0x1 0xd130 0x4e -phy raw c45 0x181 0x1 0xd131 0x0610 +phy raw c45 0x181 0x1 0xd130 0x4E +phy raw c45 0x181 0x1 0xd131 0x610 phy raw c45 0x181 0x1 0xd134 1 phy raw c45 0x181 0x1 0xffde 3 -phy raw c45 0x181 0x1 0xd130 0x4e -phy raw c45 0x181 0x1 0xd131 0x0610 +phy raw c45 0x181 0x1 0xd130 0x4D +phy raw c45 0x181 0x1 0xd131 0x611 phy raw c45 0x181 0x1 0xd134 1 phy raw c45 0x189 0x1 0xffde 0 -phy raw c45 0x189 0x1 0xd130 0x4d -phy raw c45 0x189 0x1 0xd131 0x0611 +phy raw c45 0x189 0x1 0xd130 0x4E +phy raw c45 0x189 0x1 0xd131 0x610 phy raw c45 0x189 0x1 0xd134 1 phy raw c45 0x189 0x1 0xffde 1 -phy raw c45 0x189 0x1 0xd130 0x4d -phy raw c45 0x189 0x1 0xd131 0x0611 +phy raw c45 0x189 0x1 0xd130 0x4E +phy raw c45 0x189 0x1 0xd131 0x610 phy raw c45 0x189 0x1 0xd134 1 phy raw c45 0x189 0x1 0xffde 2 -phy raw c45 0x189 0x1 0xd130 0x4d -phy raw c45 0x189 0x1 0xd131 0x0611 +phy raw c45 0x189 0x1 0xd130 0x4D +phy raw c45 0x189 0x1 0xd131 0x611 phy raw c45 0x189 0x1 0xd134 1 phy raw c45 0x189 0x1 0xffde 3 -phy raw c45 0x189 0x1 0xd130 0x4d -phy raw c45 0x189 0x1 0xd131 0x0611 -phy raw c45 0x189 0x1 0xd134 1 - +phy raw c45 0x189 0x1 0xd130 0x4D +phy raw c45 0x189 0x1 0xd131 0x611 +phy raw c45 0x189 0x1 0xd134 1 \ No newline at end of file diff --git a/device/quanta/x86_64-quanta_ix7_rglbmc-r0/media_settings.json b/device/quanta/x86_64-quanta_ix7_rglbmc-r0/media_settings.json new file mode 100644 index 000000000000..0ea47167be6a --- /dev/null +++ b/device/quanta/x86_64-quanta_ix7_rglbmc-r0/media_settings.json @@ -0,0 +1,254 @@ +{ + "GLOBAL_MEDIA_SETTINGS": { + "1-1": { + "Default": { + "preemphasis": { + "lane0": "0x114D06", + "lane1": "0x0F4F06", + "lane2": "0x0F4F06", + "lane3": "0x104E06" + } + } + }, + "2,4": { + "Default": { + "preemphasis": { + "lane0": "0x104E06", + "lane1": "0x104E06", + "lane2": "0x114D06", + "lane3": "0x104E06" + } + } + }, + "3-3": { + "Default": { + "preemphasis": { + "lane0": "0x104E06", + "lane1": "0x104E06", + "lane2": "0x104E06", + "lane3": "0x104E06" + } + } + }, + "5-5": { + "Default": { + "preemphasis": { + "lane0": "0x104E06", + "lane1": "0x114D06", + "lane2": "0x0F4F06", + "lane3": "0x114D06" + } + } + }, + "6-6": { + "Default": { + "preemphasis": { + "lane0": "0x0F4F06", + "lane1": "0x0F4F06", + "lane2": "0x104E06", + "lane3": "0x114D06" + } + } + }, + "7-7": { + "Default": { + "preemphasis": { + "lane0": "0x0F4F06", + "lane1": "0x0F4F06", + "lane2": "0x0D5106", + "lane3": "0x0F4F06" + } + } + }, + "8-8": { + "Default": { + "preemphasis": { + "lane0": "0x0D5106", + "lane1": "0x0D5106", + "lane2": "0x0D5106", + "lane3": "0x0E5006" + } + } + }, + "9,23": { + "Default": { + "preemphasis": { + "lane0": "0x0C5206", + "lane1": "0x0C5206", + "lane2": "0x0C5206", + "lane3": "0x0C5206" + } + } + }, + "10-10": { + "Default": { + "preemphasis": { + "lane0": "0x0A5406", + "lane1": "0x0C5206", + "lane2": "0x0A5406", + "lane3": "0x0C5206" + } + } + }, + "11,13": { + "Default": { + "preemphasis": { + "lane0": "0x0A5406", + "lane1": "0x0B5306", + "lane2": "0x0A5406", + "lane3": "0x0B5306" + } + } + }, + "12,14": { + "Default": { + "preemphasis": { + "lane0": "0x0A5406", + "lane1": "0x0B5306", + "lane2": "0x0A5406", + "lane3": "0x0A5406" + } + } + }, + "15,17": { + "Default": { + "preemphasis": { + "lane0": "0x095506", + "lane1": "0x095506", + "lane2": "0x095506", + "lane3": "0x095506" + } + } + }, + "16-16": { + "Default": { + "preemphasis": { + "lane0": "0x0A5406", + "lane1": "0x0A5406", + "lane2": "0x0A5406", + "lane3": "0x095506" + } + } + }, + "18,19": { + "Default": { + "preemphasis": { + "lane0": "0x0A5406", + "lane1": "0x0A5406", + "lane2": "0x0A5406", + "lane3": "0x0A5406" + } + } + }, + "20-20": { + "Default": { + "preemphasis": { + "lane0": "0x0B5306", + "lane1": "0x0C5206", + "lane2": "0x0A5406", + "lane3": "0x0C5206" + } + } + }, + "21-21": { + "Default": { + "preemphasis": { + "lane0": "0x0B5306", + "lane1": "0x0B5306", + "lane2": "0x0B5306", + "lane3": "0x0B5306" + } + } + }, + "22-22": { + "Default": { + "preemphasis": { + "lane0": "0x0B5306", + "lane1": "0x0C5206", + "lane2": "0x0A5406", + "lane3": "0x0A5406" + } + } + }, + "24-24": { + "Default": { + "preemphasis": { + "lane0": "0x0C5206", + "lane1": "0x0C5206", + "lane2": "0x0B5306", + "lane3": "0x0C5206" + } + } + }, + "25-25": { + "Default": { + "preemphasis": { + "lane0": "0x0E5006", + "lane1": "0x0D5106", + "lane2": "0x0D5106", + "lane3": "0x0D5106" + } + } + }, + "26-26": { + "Default": { + "preemphasis": { + "lane0": "0x0E5006", + "lane1": "0x0E5006", + "lane2": "0x0D5106", + "lane3": "0x0E5006" + } + } + }, + "27-27": { + "Default": { + "preemphasis": { + "lane0": "0x0F4F06", + "lane1": "0x114D06", + "lane2": "0x104E06", + "lane3": "0x114D06" + } + } + }, + "28,31": { + "Default": { + "preemphasis": { + "lane0": "0x104E06", + "lane1": "0x114D06", + "lane2": "0x104E06", + "lane3": "0x114D06" + } + } + }, + "29-29": { + "Default": { + "preemphasis": { + "lane0": "0x0F4F06", + "lane1": "0x104E06", + "lane2": "0x104E06", + "lane3": "0x104E06" + } + } + }, + "30-30": { + "Default": { + "preemphasis": { + "lane0": "0x114D06", + "lane1": "0x114D06", + "lane2": "0x114D06", + "lane3": "0x114D06" + } + } + }, + "32-32": { + "Default": { + "preemphasis": { + "lane0": "0x104E06", + "lane1": "0x104E06", + "lane2": "0x114D06", + "lane3": "0x114D06" + } + } + } + } +} diff --git a/device/quanta/x86_64-quanta_ix7_rglbmc-r0/preemphasis-32x100G.soc b/device/quanta/x86_64-quanta_ix7_rglbmc-r0/preemphasis-32x100G.soc index 5837a6fdce87..f092f6c29aa3 100644 --- a/device/quanta/x86_64-quanta_ix7_rglbmc-r0/preemphasis-32x100G.soc +++ b/device/quanta/x86_64-quanta_ix7_rglbmc-r0/preemphasis-32x100G.soc @@ -1,546 +1,545 @@ # Pre-emphasis phy raw c45 0xa5 0x1 0xffde 0 -phy raw c45 0xa5 0x1 0xd130 0x41 -phy raw c45 0xa5 0x1 0xd131 0xd +phy raw c45 0xa5 0x1 0xd130 0x4D +phy raw c45 0xa5 0x1 0xd131 0x611 phy raw c45 0xa5 0x1 0xd134 1 phy raw c45 0xa5 0x1 0xffde 1 -phy raw c45 0xa5 0x1 0xd130 0x41 -phy raw c45 0xa5 0x1 0xd131 0xd +phy raw c45 0xa5 0x1 0xd130 0x4F +phy raw c45 0xa5 0x1 0xd131 0x60F phy raw c45 0xa5 0x1 0xd134 1 phy raw c45 0xa5 0x1 0xffde 2 -phy raw c45 0xa5 0x1 0xd130 0x41 -phy raw c45 0xa5 0x1 0xd131 0xd +phy raw c45 0xa5 0x1 0xd130 0x4F +phy raw c45 0xa5 0x1 0xd131 0x60F phy raw c45 0xa5 0x1 0xd134 1 phy raw c45 0xa5 0x1 0xffde 3 -phy raw c45 0xa5 0x1 0xd130 0x41 -phy raw c45 0xa5 0x1 0xd131 0xd +phy raw c45 0xa5 0x1 0xd130 0x4E +phy raw c45 0xa5 0x1 0xd131 0x610 phy raw c45 0xa5 0x1 0xd134 1 phy raw c45 0xa9 0x1 0xffde 0 -phy raw c45 0xa9 0x1 0xd130 0x41 -phy raw c45 0xa9 0x1 0xd131 0xd +phy raw c45 0xa9 0x1 0xd130 0x4E +phy raw c45 0xa9 0x1 0xd131 0x610 phy raw c45 0xa9 0x1 0xd134 1 phy raw c45 0xa9 0x1 0xffde 1 -phy raw c45 0xa9 0x1 0xd130 0x41 -phy raw c45 0xa9 0x1 0xd131 0xd +phy raw c45 0xa9 0x1 0xd130 0x4E +phy raw c45 0xa9 0x1 0xd131 0x610 phy raw c45 0xa9 0x1 0xd134 1 phy raw c45 0xa9 0x1 0xffde 2 -phy raw c45 0xa9 0x1 0xd130 0x41 -phy raw c45 0xa9 0x1 0xd131 0xd +phy raw c45 0xa9 0x1 0xd130 0x4D +phy raw c45 0xa9 0x1 0xd131 0x611 phy raw c45 0xa9 0x1 0xd134 1 phy raw c45 0xa9 0x1 0xffde 3 -phy raw c45 0xa9 0x1 0xd130 0x41 -phy raw c45 0xa9 0x1 0xd131 0xd +phy raw c45 0xa9 0x1 0xd130 0x4E +phy raw c45 0xa9 0x1 0xd131 0x610 phy raw c45 0xa9 0x1 0xd134 1 phy raw c45 0xc1 0x1 0xffde 0 -phy raw c45 0xc1 0x1 0xd130 0x41 -phy raw c45 0xc1 0x1 0xd131 0xd +phy raw c45 0xc1 0x1 0xd130 0x4E +phy raw c45 0xc1 0x1 0xd131 0x610 phy raw c45 0xc1 0x1 0xd134 1 phy raw c45 0xc1 0x1 0xffde 1 -phy raw c45 0xc1 0x1 0xd130 0x41 -phy raw c45 0xc1 0x1 0xd131 0xd +phy raw c45 0xc1 0x1 0xd130 0x4E +phy raw c45 0xc1 0x1 0xd131 0x610 phy raw c45 0xc1 0x1 0xd134 1 phy raw c45 0xc1 0x1 0xffde 2 -phy raw c45 0xc1 0x1 0xd130 0x41 -phy raw c45 0xc1 0x1 0xd131 0xd +phy raw c45 0xc1 0x1 0xd130 0x4E +phy raw c45 0xc1 0x1 0xd131 0x610 phy raw c45 0xc1 0x1 0xd134 1 phy raw c45 0xc1 0x1 0xffde 3 -phy raw c45 0xc1 0x1 0xd130 0x41 -phy raw c45 0xc1 0x1 0xd131 0xd +phy raw c45 0xc1 0x1 0xd130 0x4E +phy raw c45 0xc1 0x1 0xd131 0x610 phy raw c45 0xc1 0x1 0xd134 1 phy raw c45 0xc5 0x1 0xffde 0 -phy raw c45 0xc5 0x1 0xd130 0x41 -phy raw c45 0xc5 0x1 0xd131 0xd +phy raw c45 0xc5 0x1 0xd130 0x4E +phy raw c45 0xc5 0x1 0xd131 0x610 phy raw c45 0xc5 0x1 0xd134 1 phy raw c45 0xc5 0x1 0xffde 1 -phy raw c45 0xc5 0x1 0xd130 0x41 -phy raw c45 0xc5 0x1 0xd131 0xd +phy raw c45 0xc5 0x1 0xd130 0x4E +phy raw c45 0xc5 0x1 0xd131 0x610 phy raw c45 0xc5 0x1 0xd134 1 phy raw c45 0xc5 0x1 0xffde 2 -phy raw c45 0xc5 0x1 0xd130 0x41 -phy raw c45 0xc5 0x1 0xd131 0xd +phy raw c45 0xc5 0x1 0xd130 0x4D +phy raw c45 0xc5 0x1 0xd131 0x611 phy raw c45 0xc5 0x1 0xd134 1 phy raw c45 0xc5 0x1 0xffde 3 -phy raw c45 0xc5 0x1 0xd130 0x41 -phy raw c45 0xc5 0x1 0xd131 0xd +phy raw c45 0xc5 0x1 0xd130 0x4E +phy raw c45 0xc5 0x1 0xd131 0x610 phy raw c45 0xc5 0x1 0xd134 1 phy raw c45 0x81 0x1 0xffde 0 -phy raw c45 0x81 0x1 0xd130 0x41 -phy raw c45 0x81 0x1 0xd131 0xd +phy raw c45 0x81 0x1 0xd130 0x4E +phy raw c45 0x81 0x1 0xd131 0x610 phy raw c45 0x81 0x1 0xd134 1 phy raw c45 0x81 0x1 0xffde 1 -phy raw c45 0x81 0x1 0xd130 0x41 -phy raw c45 0x81 0x1 0xd131 0xd +phy raw c45 0x81 0x1 0xd130 0x4D +phy raw c45 0x81 0x1 0xd131 0x611 phy raw c45 0x81 0x1 0xd134 1 phy raw c45 0x81 0x1 0xffde 2 -phy raw c45 0x81 0x1 0xd130 0x41 -phy raw c45 0x81 0x1 0xd131 0xd +phy raw c45 0x81 0x1 0xd130 0x4F +phy raw c45 0x81 0x1 0xd131 0x60F phy raw c45 0x81 0x1 0xd134 1 phy raw c45 0x81 0x1 0xffde 3 -phy raw c45 0x81 0x1 0xd130 0x41 -phy raw c45 0x81 0x1 0xd131 0xd +phy raw c45 0x81 0x1 0xd130 0x4D +phy raw c45 0x81 0x1 0xd131 0x611 phy raw c45 0x81 0x1 0xd134 1 phy raw c45 0x85 0x1 0xffde 0 -phy raw c45 0x85 0x1 0xd130 0x41 -phy raw c45 0x85 0x1 0xd131 0xd +phy raw c45 0x85 0x1 0xd130 0x4F +phy raw c45 0x85 0x1 0xd131 0x60F phy raw c45 0x85 0x1 0xd134 1 phy raw c45 0x85 0x1 0xffde 1 -phy raw c45 0x85 0x1 0xd130 0x41 -phy raw c45 0x85 0x1 0xd131 0xd +phy raw c45 0x85 0x1 0xd130 0x4F +phy raw c45 0x85 0x1 0xd131 0x60F phy raw c45 0x85 0x1 0xd134 1 phy raw c45 0x85 0x1 0xffde 2 -phy raw c45 0x85 0x1 0xd130 0x41 -phy raw c45 0x85 0x1 0xd131 0xd +phy raw c45 0x85 0x1 0xd130 0x4E +phy raw c45 0x85 0x1 0xd131 0x610 phy raw c45 0x85 0x1 0xd134 1 phy raw c45 0x85 0x1 0xffde 3 -phy raw c45 0x85 0x1 0xd130 0x41 -phy raw c45 0x85 0x1 0xd131 0xd +phy raw c45 0x85 0x1 0xd130 0x4D +phy raw c45 0x85 0x1 0xd131 0x611 phy raw c45 0x85 0x1 0xd134 1 phy raw c45 0x89 0x1 0xffde 0 -phy raw c45 0x89 0x1 0xd130 0x41 -phy raw c45 0x89 0x1 0xd131 0xd +phy raw c45 0x89 0x1 0xd130 0x4F +phy raw c45 0x89 0x1 0xd131 0x60F phy raw c45 0x89 0x1 0xd134 1 phy raw c45 0x89 0x1 0xffde 1 -phy raw c45 0x89 0x1 0xd130 0x41 -phy raw c45 0x89 0x1 0xd131 0xd +phy raw c45 0x89 0x1 0xd130 0x4F +phy raw c45 0x89 0x1 0xd131 0x60F phy raw c45 0x89 0x1 0xd134 1 phy raw c45 0x89 0x1 0xffde 2 -phy raw c45 0x89 0x1 0xd130 0x41 -phy raw c45 0x89 0x1 0xd131 0xd +phy raw c45 0x89 0x1 0xd130 0x51 +phy raw c45 0x89 0x1 0xd131 0x60D phy raw c45 0x89 0x1 0xd134 1 phy raw c45 0x89 0x1 0xffde 3 -phy raw c45 0x89 0x1 0xd130 0x41 -phy raw c45 0x89 0x1 0xd131 0xd +phy raw c45 0x89 0x1 0xd130 0x4F +phy raw c45 0x89 0x1 0xd131 0x60F phy raw c45 0x89 0x1 0xd134 1 phy raw c45 0x8d 0x1 0xffde 0 -phy raw c45 0x8d 0x1 0xd130 0x41 -phy raw c45 0x8d 0x1 0xd131 0xd +phy raw c45 0x8d 0x1 0xd130 0x51 +phy raw c45 0x8d 0x1 0xd131 0x60D phy raw c45 0x8d 0x1 0xd134 1 phy raw c45 0x8d 0x1 0xffde 1 -phy raw c45 0x8d 0x1 0xd130 0x41 -phy raw c45 0x8d 0x1 0xd131 0xd +phy raw c45 0x8d 0x1 0xd130 0x51 +phy raw c45 0x8d 0x1 0xd131 0x60D phy raw c45 0x8d 0x1 0xd134 1 phy raw c45 0x8d 0x1 0xffde 2 -phy raw c45 0x8d 0x1 0xd130 0x41 -phy raw c45 0x8d 0x1 0xd131 0xd +phy raw c45 0x8d 0x1 0xd130 0x51 +phy raw c45 0x8d 0x1 0xd131 0x60D phy raw c45 0x8d 0x1 0xd134 1 phy raw c45 0x8d 0x1 0xffde 3 -phy raw c45 0x8d 0x1 0xd130 0x41 -phy raw c45 0x8d 0x1 0xd131 0xd +phy raw c45 0x8d 0x1 0xd130 0x50 +phy raw c45 0x8d 0x1 0xd131 0x60E phy raw c45 0x8d 0x1 0xd134 1 phy raw c45 0x91 0x1 0xffde 0 -phy raw c45 0x91 0x1 0xd130 0x41 -phy raw c45 0x91 0x1 0xd131 0x0408 +phy raw c45 0x91 0x1 0xd130 0x52 +phy raw c45 0x91 0x1 0xd131 0x60C phy raw c45 0x91 0x1 0xd134 1 phy raw c45 0x91 0x1 0xffde 1 -phy raw c45 0x91 0x1 0xd130 0x41 -phy raw c45 0x91 0x1 0xd131 0x0408 +phy raw c45 0x91 0x1 0xd130 0x52 +phy raw c45 0x91 0x1 0xd131 0x60C phy raw c45 0x91 0x1 0xd134 1 phy raw c45 0x91 0x1 0xffde 2 -phy raw c45 0x91 0x1 0xd130 0x41 -phy raw c45 0x91 0x1 0xd131 0x0408 +phy raw c45 0x91 0x1 0xd130 0x52 +phy raw c45 0x91 0x1 0xd131 0x60C phy raw c45 0x91 0x1 0xd134 1 phy raw c45 0x91 0x1 0xffde 3 -phy raw c45 0x91 0x1 0xd130 0x41 -phy raw c45 0x91 0x1 0xd131 0x0408 +phy raw c45 0x91 0x1 0xd130 0x52 +phy raw c45 0x91 0x1 0xd131 0x60C phy raw c45 0x91 0x1 0xd134 1 phy raw c45 0x95 0x1 0xffde 0 -phy raw c45 0x95 0x1 0xd130 0x41 -phy raw c45 0x95 0x1 0xd131 0x0307 +phy raw c45 0x95 0x1 0xd130 0x54 +phy raw c45 0x95 0x1 0xd131 0x60A phy raw c45 0x95 0x1 0xd134 1 phy raw c45 0x95 0x1 0xffde 1 -phy raw c45 0x95 0x1 0xd130 0x41 -phy raw c45 0x95 0x1 0xd131 0x0307 +phy raw c45 0x95 0x1 0xd130 0x52 +phy raw c45 0x95 0x1 0xd131 0x60C phy raw c45 0x95 0x1 0xd134 1 phy raw c45 0x95 0x1 0xffde 2 -phy raw c45 0x95 0x1 0xd130 0x41 -phy raw c45 0x95 0x1 0xd131 0x0307 +phy raw c45 0x95 0x1 0xd130 0x54 +phy raw c45 0x95 0x1 0xd131 0x60A phy raw c45 0x95 0x1 0xd134 1 phy raw c45 0x95 0x1 0xffde 3 -phy raw c45 0x95 0x1 0xd130 0x41 -phy raw c45 0x95 0x1 0xd131 0x0307 +phy raw c45 0x95 0x1 0xd130 0x52 +phy raw c45 0x95 0x1 0xd131 0x60C phy raw c45 0x95 0x1 0xd134 1 phy raw c45 0xa1 0x1 0xffde 0 -phy raw c45 0xa1 0x1 0xd130 0x41 -phy raw c45 0xa1 0x1 0xd131 0x0307 +phy raw c45 0xa1 0x1 0xd130 0x54 +phy raw c45 0xa1 0x1 0xd131 0x60A phy raw c45 0xa1 0x1 0xd134 1 phy raw c45 0xa1 0x1 0xffde 1 -phy raw c45 0xa1 0x1 0xd130 0x41 -phy raw c45 0xa1 0x1 0xd131 0x0307 +phy raw c45 0xa1 0x1 0xd130 0x53 +phy raw c45 0xa1 0x1 0xd131 0x60B phy raw c45 0xa1 0x1 0xd134 1 phy raw c45 0xa1 0x1 0xffde 2 -phy raw c45 0xa1 0x1 0xd130 0x41 -phy raw c45 0xa1 0x1 0xd131 0x0307 +phy raw c45 0xa1 0x1 0xd130 0x54 +phy raw c45 0xa1 0x1 0xd131 0x60A phy raw c45 0xa1 0x1 0xd134 1 phy raw c45 0xa1 0x1 0xffde 3 -phy raw c45 0xa1 0x1 0xd130 0x41 -phy raw c45 0xa1 0x1 0xd131 0x0307 +phy raw c45 0xa1 0x1 0xd130 0x53 +phy raw c45 0xa1 0x1 0xd131 0x60B phy raw c45 0xa1 0x1 0xd134 1 phy raw c45 0xad 0x1 0xffde 0 -phy raw c45 0xad 0x1 0xd130 0x41 -phy raw c45 0xad 0x1 0xd131 0x0307 +phy raw c45 0xad 0x1 0xd130 0x54 +phy raw c45 0xad 0x1 0xd131 0x60A phy raw c45 0xad 0x1 0xd134 1 phy raw c45 0xad 0x1 0xffde 1 -phy raw c45 0xad 0x1 0xd130 0x41 -phy raw c45 0xad 0x1 0xd131 0x0307 +phy raw c45 0xad 0x1 0xd130 0x53 +phy raw c45 0xad 0x1 0xd131 0x60B phy raw c45 0xad 0x1 0xd134 1 phy raw c45 0xad 0x1 0xffde 2 -phy raw c45 0xad 0x1 0xd130 0x41 -phy raw c45 0xad 0x1 0xd131 0x0307 +phy raw c45 0xad 0x1 0xd130 0x54 +phy raw c45 0xad 0x1 0xd131 0x60A phy raw c45 0xad 0x1 0xd134 1 phy raw c45 0xad 0x1 0xffde 3 -phy raw c45 0xad 0x1 0xd130 0x41 -phy raw c45 0xad 0x1 0xd131 0x0307 +phy raw c45 0xad 0x1 0xd130 0x54 +phy raw c45 0xad 0x1 0xd131 0x60A phy raw c45 0xad 0x1 0xd134 1 phy raw c45 0xc9 0x1 0xffde 0 -phy raw c45 0xc9 0x1 0xd130 0x41 -phy raw c45 0xc9 0x1 0xd131 0x0307 +phy raw c45 0xc9 0x1 0xd130 0x54 +phy raw c45 0xc9 0x1 0xd131 0x60A phy raw c45 0xc9 0x1 0xd134 1 phy raw c45 0xc9 0x1 0xffde 1 -phy raw c45 0xc9 0x1 0xd130 0x41 -phy raw c45 0xc9 0x1 0xd131 0x0307 +phy raw c45 0xc9 0x1 0xd130 0x53 +phy raw c45 0xc9 0x1 0xd131 0x60B phy raw c45 0xc9 0x1 0xd134 1 phy raw c45 0xc9 0x1 0xffde 2 -phy raw c45 0xc9 0x1 0xd130 0x41 -phy raw c45 0xc9 0x1 0xd131 0x0307 +phy raw c45 0xc9 0x1 0xd130 0x54 +phy raw c45 0xc9 0x1 0xd131 0x60A phy raw c45 0xc9 0x1 0xd134 1 phy raw c45 0xc9 0x1 0xffde 3 -phy raw c45 0xc9 0x1 0xd130 0x41 -phy raw c45 0xc9 0x1 0xd131 0x0307 +phy raw c45 0xc9 0x1 0xd130 0x53 +phy raw c45 0xc9 0x1 0xd131 0x60B phy raw c45 0xc9 0x1 0xd134 1 phy raw c45 0xcd 0x1 0xffde 0 -phy raw c45 0xcd 0x1 0xd130 0x41 -phy raw c45 0xcd 0x1 0xd131 0x0307 +phy raw c45 0xcd 0x1 0xd130 0x54 +phy raw c45 0xcd 0x1 0xd131 0x60A phy raw c45 0xcd 0x1 0xd134 1 phy raw c45 0xcd 0x1 0xffde 1 -phy raw c45 0xcd 0x1 0xd130 0x41 -phy raw c45 0xcd 0x1 0xd131 0x0307 +phy raw c45 0xcd 0x1 0xd130 0x53 +phy raw c45 0xcd 0x1 0xd131 0x60B phy raw c45 0xcd 0x1 0xd134 1 phy raw c45 0xcd 0x1 0xffde 2 -phy raw c45 0xcd 0x1 0xd130 0x41 -phy raw c45 0xcd 0x1 0xd131 0x0307 +phy raw c45 0xcd 0x1 0xd130 0x54 +phy raw c45 0xcd 0x1 0xd131 0x60A phy raw c45 0xcd 0x1 0xd134 1 phy raw c45 0xcd 0x1 0xffde 3 -phy raw c45 0xcd 0x1 0xd130 0x41 -phy raw c45 0xcd 0x1 0xd131 0x0307 +phy raw c45 0xcd 0x1 0xd130 0x54 +phy raw c45 0xcd 0x1 0xd131 0x60A phy raw c45 0xcd 0x1 0xd134 1 phy raw c45 0xd1 0x1 0xffde 0 -phy raw c45 0xd1 0x1 0xd130 0x41 -phy raw c45 0xd1 0x1 0xd131 0x0307 +phy raw c45 0xd1 0x1 0xd130 0x55 +phy raw c45 0xd1 0x1 0xd131 0x609 phy raw c45 0xd1 0x1 0xd134 1 phy raw c45 0xd1 0x1 0xffde 1 -phy raw c45 0xd1 0x1 0xd130 0x41 -phy raw c45 0xd1 0x1 0xd131 0x0307 +phy raw c45 0xd1 0x1 0xd130 0x55 +phy raw c45 0xd1 0x1 0xd131 0x609 phy raw c45 0xd1 0x1 0xd134 1 phy raw c45 0xd1 0x1 0xffde 2 -phy raw c45 0xd1 0x1 0xd130 0x41 -phy raw c45 0xd1 0x1 0xd131 0x0307 +phy raw c45 0xd1 0x1 0xd130 0x55 +phy raw c45 0xd1 0x1 0xd131 0x609 phy raw c45 0xd1 0x1 0xd134 1 phy raw c45 0xd1 0x1 0xffde 3 -phy raw c45 0xd1 0x1 0xd130 0x41 -phy raw c45 0xd1 0x1 0xd131 0x0307 +phy raw c45 0xd1 0x1 0xd130 0x55 +phy raw c45 0xd1 0x1 0xd131 0x609 phy raw c45 0xd1 0x1 0xd134 1 phy raw c45 0xd5 0x1 0xffde 0 -phy raw c45 0xd5 0x1 0xd130 0x41 -phy raw c45 0xd5 0x1 0xd131 0x0307 +phy raw c45 0xd5 0x1 0xd130 0x54 +phy raw c45 0xd5 0x1 0xd131 0x60A phy raw c45 0xd5 0x1 0xd134 1 phy raw c45 0xd5 0x1 0xffde 1 -phy raw c45 0xd5 0x1 0xd130 0x41 -phy raw c45 0xd5 0x1 0xd131 0x0307 +phy raw c45 0xd5 0x1 0xd130 0x54 +phy raw c45 0xd5 0x1 0xd131 0x60A phy raw c45 0xd5 0x1 0xd134 1 phy raw c45 0xd5 0x1 0xffde 2 -phy raw c45 0xd5 0x1 0xd130 0x41 -phy raw c45 0xd5 0x1 0xd131 0x0307 +phy raw c45 0xd5 0x1 0xd130 0x54 +phy raw c45 0xd5 0x1 0xd131 0x60A phy raw c45 0xd5 0x1 0xd134 1 phy raw c45 0xd5 0x1 0xffde 3 -phy raw c45 0xd5 0x1 0xd130 0x41 -phy raw c45 0xd5 0x1 0xd131 0x0307 +phy raw c45 0xd5 0x1 0xd130 0x55 +phy raw c45 0xd5 0x1 0xd131 0x609 phy raw c45 0xd5 0x1 0xd134 1 phy raw c45 0xe1 0x1 0xffde 0 -phy raw c45 0xe1 0x1 0xd130 0x41 -phy raw c45 0xe1 0x1 0xd131 0x0307 +phy raw c45 0xe1 0x1 0xd130 0x55 +phy raw c45 0xe1 0x1 0xd131 0x609 phy raw c45 0xe1 0x1 0xd134 1 phy raw c45 0xe1 0x1 0xffde 1 -phy raw c45 0xe1 0x1 0xd130 0x41 -phy raw c45 0xe1 0x1 0xd131 0x0307 +phy raw c45 0xe1 0x1 0xd130 0x55 +phy raw c45 0xe1 0x1 0xd131 0x609 phy raw c45 0xe1 0x1 0xd134 1 phy raw c45 0xe1 0x1 0xffde 2 -phy raw c45 0xe1 0x1 0xd130 0x41 -phy raw c45 0xe1 0x1 0xd131 0x0307 +phy raw c45 0xe1 0x1 0xd130 0x55 +phy raw c45 0xe1 0x1 0xd131 0x609 phy raw c45 0xe1 0x1 0xd134 1 phy raw c45 0xe1 0x1 0xffde 3 -phy raw c45 0xe1 0x1 0xd130 0x41 -phy raw c45 0xe1 0x1 0xd131 0x0307 +phy raw c45 0xe1 0x1 0xd130 0x55 +phy raw c45 0xe1 0x1 0xd131 0x609 phy raw c45 0xe1 0x1 0xd134 1 phy raw c45 0xe5 0x1 0xffde 0 -phy raw c45 0xe5 0x1 0xd130 0x41 -phy raw c45 0xe5 0x1 0xd131 0x0307 +phy raw c45 0xe5 0x1 0xd130 0x54 +phy raw c45 0xe5 0x1 0xd131 0x60A phy raw c45 0xe5 0x1 0xd134 1 phy raw c45 0xe5 0x1 0xffde 1 -phy raw c45 0xe5 0x1 0xd130 0x41 -phy raw c45 0xe5 0x1 0xd131 0x0307 +phy raw c45 0xe5 0x1 0xd130 0x54 +phy raw c45 0xe5 0x1 0xd131 0x60A phy raw c45 0xe5 0x1 0xd134 1 phy raw c45 0xe5 0x1 0xffde 2 -phy raw c45 0xe5 0x1 0xd130 0x41 -phy raw c45 0xe5 0x1 0xd131 0x0307 +phy raw c45 0xe5 0x1 0xd130 0x54 +phy raw c45 0xe5 0x1 0xd131 0x60A phy raw c45 0xe5 0x1 0xd134 1 phy raw c45 0xe5 0x1 0xffde 3 -phy raw c45 0xe5 0x1 0xd130 0x41 -phy raw c45 0xe5 0x1 0xd131 0x0307 +phy raw c45 0xe5 0x1 0xd130 0x54 +phy raw c45 0xe5 0x1 0xd131 0x60A phy raw c45 0xe5 0x1 0xd134 1 phy raw c45 0xe9 0x1 0xffde 0 -phy raw c45 0xe9 0x1 0xd130 0x41 -phy raw c45 0xe9 0x1 0xd131 0x0307 +phy raw c45 0xe9 0x1 0xd130 0x54 +phy raw c45 0xe9 0x1 0xd131 0x60A phy raw c45 0xe9 0x1 0xd134 1 phy raw c45 0xe9 0x1 0xffde 1 -phy raw c45 0xe9 0x1 0xd130 0x41 -phy raw c45 0xe9 0x1 0xd131 0x0307 +phy raw c45 0xe9 0x1 0xd130 0x54 +phy raw c45 0xe9 0x1 0xd131 0x60A phy raw c45 0xe9 0x1 0xd134 1 phy raw c45 0xe9 0x1 0xffde 2 -phy raw c45 0xe9 0x1 0xd130 0x41 -phy raw c45 0xe9 0x1 0xd131 0x0307 +phy raw c45 0xe9 0x1 0xd130 0x54 +phy raw c45 0xe9 0x1 0xd131 0x60A phy raw c45 0xe9 0x1 0xd134 1 phy raw c45 0xe9 0x1 0xffde 3 -phy raw c45 0xe9 0x1 0xd130 0x41 -phy raw c45 0xe9 0x1 0xd131 0x0307 +phy raw c45 0xe9 0x1 0xd130 0x54 +phy raw c45 0xe9 0x1 0xd131 0x60A phy raw c45 0xe9 0x1 0xd134 1 phy raw c45 0xed 0x1 0xffde 0 -phy raw c45 0xed 0x1 0xd130 0x41 -phy raw c45 0xed 0x1 0xd131 0xb +phy raw c45 0xed 0x1 0xd130 0x53 +phy raw c45 0xed 0x1 0xd131 0x60B phy raw c45 0xed 0x1 0xd134 1 phy raw c45 0xed 0x1 0xffde 1 -phy raw c45 0xed 0x1 0xd130 0x41 -phy raw c45 0xed 0x1 0xd131 0xb +phy raw c45 0xed 0x1 0xd130 0x52 +phy raw c45 0xed 0x1 0xd131 0x60C phy raw c45 0xed 0x1 0xd134 1 phy raw c45 0xed 0x1 0xffde 2 -phy raw c45 0xed 0x1 0xd130 0x41 -phy raw c45 0xed 0x1 0xd131 0xb +phy raw c45 0xed 0x1 0xd130 0x54 +phy raw c45 0xed 0x1 0xd131 0x60A phy raw c45 0xed 0x1 0xd134 1 phy raw c45 0xed 0x1 0xffde 3 -phy raw c45 0xed 0x1 0xd130 0x41 -phy raw c45 0xed 0x1 0xd131 0xb +phy raw c45 0xed 0x1 0xd130 0x52 +phy raw c45 0xed 0x1 0xd131 0x60C phy raw c45 0xed 0x1 0xd134 1 phy raw c45 0x185 0x1 0xffde 0 -phy raw c45 0x185 0x1 0xd130 0x41 -phy raw c45 0x185 0x1 0xd131 0x0307 +phy raw c45 0x185 0x1 0xd130 0x53 +phy raw c45 0x185 0x1 0xd131 0x60B phy raw c45 0x185 0x1 0xd134 1 phy raw c45 0x185 0x1 0xffde 1 -phy raw c45 0x185 0x1 0xd130 0x41 -phy raw c45 0x185 0x1 0xd131 0x0307 +phy raw c45 0x185 0x1 0xd130 0x53 +phy raw c45 0x185 0x1 0xd131 0x60B phy raw c45 0x185 0x1 0xd134 1 phy raw c45 0x185 0x1 0xffde 2 -phy raw c45 0x185 0x1 0xd130 0x41 -phy raw c45 0x185 0x1 0xd131 0x0307 +phy raw c45 0x185 0x1 0xd130 0x53 +phy raw c45 0x185 0x1 0xd131 0x60B phy raw c45 0x185 0x1 0xd134 1 phy raw c45 0x185 0x1 0xffde 3 -phy raw c45 0x185 0x1 0xd130 0x41 -phy raw c45 0x185 0x1 0xd131 0x0307 +phy raw c45 0x185 0x1 0xd130 0x53 +phy raw c45 0x185 0x1 0xd131 0x60B phy raw c45 0x185 0x1 0xd134 1 phy raw c45 0x18d 0x1 0xffde 0 -phy raw c45 0x18d 0x1 0xd130 0x41 -phy raw c45 0x18d 0x1 0xd131 0x0307 +phy raw c45 0x18d 0x1 0xd130 0x53 +phy raw c45 0x18d 0x1 0xd131 0x60B phy raw c45 0x18d 0x1 0xd134 1 phy raw c45 0x18d 0x1 0xffde 1 -phy raw c45 0x18d 0x1 0xd130 0x41 -phy raw c45 0x18d 0x1 0xd131 0x0307 +phy raw c45 0x18d 0x1 0xd130 0x52 +phy raw c45 0x18d 0x1 0xd131 0x60C phy raw c45 0x18d 0x1 0xd134 1 phy raw c45 0x18d 0x1 0xffde 2 -phy raw c45 0x18d 0x1 0xd130 0x41 -phy raw c45 0x18d 0x1 0xd131 0x0307 +phy raw c45 0x18d 0x1 0xd130 0x54 +phy raw c45 0x18d 0x1 0xd131 0x60A phy raw c45 0x18d 0x1 0xd134 1 phy raw c45 0x18d 0x1 0xffde 3 -phy raw c45 0x18d 0x1 0xd130 0x41 -phy raw c45 0x18d 0x1 0xd131 0x0307 +phy raw c45 0x18d 0x1 0xd130 0x54 +phy raw c45 0x18d 0x1 0xd131 0x60A phy raw c45 0x18d 0x1 0xd134 1 phy raw c45 0x1a1 0x1 0xffde 0 -phy raw c45 0x1a1 0x1 0xd130 0x41 -phy raw c45 0x1a1 0x1 0xd131 0x0408 +phy raw c45 0x1a1 0x1 0xd130 0x52 +phy raw c45 0x1a1 0x1 0xd131 0x60C phy raw c45 0x1a1 0x1 0xd134 1 phy raw c45 0x1a1 0x1 0xffde 1 -phy raw c45 0x1a1 0x1 0xd130 0x41 -phy raw c45 0x1a1 0x1 0xd131 0x0408 +phy raw c45 0x1a1 0x1 0xd130 0x52 +phy raw c45 0x1a1 0x1 0xd131 0x60C phy raw c45 0x1a1 0x1 0xd134 1 phy raw c45 0x1a1 0x1 0xffde 2 -phy raw c45 0x1a1 0x1 0xd130 0x41 -phy raw c45 0x1a1 0x1 0xd131 0x0408 +phy raw c45 0x1a1 0x1 0xd130 0x52 +phy raw c45 0x1a1 0x1 0xd131 0x60C phy raw c45 0x1a1 0x1 0xd134 1 phy raw c45 0x1a1 0x1 0xffde 3 -phy raw c45 0x1a1 0x1 0xd130 0x41 -phy raw c45 0x1a1 0x1 0xd131 0x0408 +phy raw c45 0x1a1 0x1 0xd130 0x52 +phy raw c45 0x1a1 0x1 0xd131 0x60C phy raw c45 0x1a1 0x1 0xd134 1 phy raw c45 0x1a5 0x1 0xffde 0 -phy raw c45 0x1a5 0x1 0xd130 0x41 -phy raw c45 0x1a5 0x1 0xd131 0x0408 +phy raw c45 0x1a5 0x1 0xd130 0x52 +phy raw c45 0x1a5 0x1 0xd131 0x60C phy raw c45 0x1a5 0x1 0xd134 1 phy raw c45 0x1a5 0x1 0xffde 1 -phy raw c45 0x1a5 0x1 0xd130 0x41 -phy raw c45 0x1a5 0x1 0xd131 0x0408 +phy raw c45 0x1a5 0x1 0xd130 0x52 +phy raw c45 0x1a5 0x1 0xd131 0x60C phy raw c45 0x1a5 0x1 0xd134 1 phy raw c45 0x1a5 0x1 0xffde 2 -phy raw c45 0x1a5 0x1 0xd130 0x41 -phy raw c45 0x1a5 0x1 0xd131 0x0408 +phy raw c45 0x1a5 0x1 0xd130 0x53 +phy raw c45 0x1a5 0x1 0xd131 0x60B phy raw c45 0x1a5 0x1 0xd134 1 phy raw c45 0x1a5 0x1 0xffde 3 -phy raw c45 0x1a5 0x1 0xd130 0x41 -phy raw c45 0x1a5 0x1 0xd131 0x0408 +phy raw c45 0x1a5 0x1 0xd130 0x52 +phy raw c45 0x1a5 0x1 0xd131 0x60C phy raw c45 0x1a5 0x1 0xd134 1 phy raw c45 0x1a9 0x1 0xffde 0 -phy raw c45 0x1a9 0x1 0xd130 0x41 -phy raw c45 0x1a9 0x1 0xd131 0xb +phy raw c45 0x1a9 0x1 0xd130 0x50 +phy raw c45 0x1a9 0x1 0xd131 0x60E phy raw c45 0x1a9 0x1 0xd134 1 phy raw c45 0x1a9 0x1 0xffde 1 -phy raw c45 0x1a9 0x1 0xd130 0x41 -phy raw c45 0x1a9 0x1 0xd131 0xb +phy raw c45 0x1a9 0x1 0xd130 0x51 +phy raw c45 0x1a9 0x1 0xd131 0x60D phy raw c45 0x1a9 0x1 0xd134 1 phy raw c45 0x1a9 0x1 0xffde 2 -phy raw c45 0x1a9 0x1 0xd130 0x41 -phy raw c45 0x1a9 0x1 0xd131 0xb +phy raw c45 0x1a9 0x1 0xd130 0x51 +phy raw c45 0x1a9 0x1 0xd131 0x60D phy raw c45 0x1a9 0x1 0xd134 1 phy raw c45 0x1a9 0x1 0xffde 3 -phy raw c45 0x1a9 0x1 0xd130 0x41 -phy raw c45 0x1a9 0x1 0xd131 0xb +phy raw c45 0x1a9 0x1 0xd130 0x51 +phy raw c45 0x1a9 0x1 0xd131 0x60D phy raw c45 0x1a9 0x1 0xd134 1 phy raw c45 0x1ad 0x1 0xffde 0 -phy raw c45 0x1ad 0x1 0xd130 0x41 -phy raw c45 0x1ad 0x1 0xd131 0xc +phy raw c45 0x1ad 0x1 0xd130 0x50 +phy raw c45 0x1ad 0x1 0xd131 0x60E phy raw c45 0x1ad 0x1 0xd134 1 phy raw c45 0x1ad 0x1 0xffde 1 -phy raw c45 0x1ad 0x1 0xd130 0x41 -phy raw c45 0x1ad 0x1 0xd131 0xc +phy raw c45 0x1ad 0x1 0xd130 0x50 +phy raw c45 0x1ad 0x1 0xd131 0x60E phy raw c45 0x1ad 0x1 0xd134 1 phy raw c45 0x1ad 0x1 0xffde 2 -phy raw c45 0x1ad 0x1 0xd130 0x41 -phy raw c45 0x1ad 0x1 0xd131 0xc +phy raw c45 0x1ad 0x1 0xd130 0x51 +phy raw c45 0x1ad 0x1 0xd131 0x60D phy raw c45 0x1ad 0x1 0xd134 1 phy raw c45 0x1ad 0x1 0xffde 3 -phy raw c45 0x1ad 0x1 0xd130 0x41 -phy raw c45 0x1ad 0x1 0xd131 0xc +phy raw c45 0x1ad 0x1 0xd130 0x50 +phy raw c45 0x1ad 0x1 0xd131 0x60E phy raw c45 0x1ad 0x1 0xd134 1 phy raw c45 0x1b1 0x1 0xffde 0 -phy raw c45 0x1b1 0x1 0xd130 0x41 -phy raw c45 0x1b1 0x1 0xd131 0xd +phy raw c45 0x1b1 0x1 0xd130 0x4F +phy raw c45 0x1b1 0x1 0xd131 0x60F phy raw c45 0x1b1 0x1 0xd134 1 phy raw c45 0x1b1 0x1 0xffde 1 -phy raw c45 0x1b1 0x1 0xd130 0x41 -phy raw c45 0x1b1 0x1 0xd131 0xd +phy raw c45 0x1b1 0x1 0xd130 0x4D +phy raw c45 0x1b1 0x1 0xd131 0x611 phy raw c45 0x1b1 0x1 0xd134 1 phy raw c45 0x1b1 0x1 0xffde 2 -phy raw c45 0x1b1 0x1 0xd130 0x41 -phy raw c45 0x1b1 0x1 0xd131 0xd +phy raw c45 0x1b1 0x1 0xd130 0x4E +phy raw c45 0x1b1 0x1 0xd131 0x610 phy raw c45 0x1b1 0x1 0xd134 1 phy raw c45 0x1b1 0x1 0xffde 3 -phy raw c45 0x1b1 0x1 0xd130 0x41 -phy raw c45 0x1b1 0x1 0xd131 0xd +phy raw c45 0x1b1 0x1 0xd130 0x4D +phy raw c45 0x1b1 0x1 0xd131 0x611 phy raw c45 0x1b1 0x1 0xd134 1 phy raw c45 0x1b5 0x1 0xffde 0 -phy raw c45 0x1b5 0x1 0xd130 0x41 -phy raw c45 0x1b5 0x1 0xd131 0xf +phy raw c45 0x1b5 0x1 0xd130 0x4E +phy raw c45 0x1b5 0x1 0xd131 0x610 phy raw c45 0x1b5 0x1 0xd134 1 phy raw c45 0x1b5 0x1 0xffde 1 -phy raw c45 0x1b5 0x1 0xd130 0x41 -phy raw c45 0x1b5 0x1 0xd131 0xf +phy raw c45 0x1b5 0x1 0xd130 0x4D +phy raw c45 0x1b5 0x1 0xd131 0x611 phy raw c45 0x1b5 0x1 0xd134 1 phy raw c45 0x1b5 0x1 0xffde 2 -phy raw c45 0x1b5 0x1 0xd130 0x41 -phy raw c45 0x1b5 0x1 0xd131 0xf +phy raw c45 0x1b5 0x1 0xd130 0x4E +phy raw c45 0x1b5 0x1 0xd131 0x610 phy raw c45 0x1b5 0x1 0xd134 1 phy raw c45 0x1b5 0x1 0xffde 3 -phy raw c45 0x1b5 0x1 0xd130 0x41 -phy raw c45 0x1b5 0x1 0xd131 0xf +phy raw c45 0x1b5 0x1 0xd130 0x4D +phy raw c45 0x1b5 0x1 0xd131 0x611 phy raw c45 0x1b5 0x1 0xd134 1 phy raw c45 0xf1 0x1 0xffde 0 -phy raw c45 0xf1 0x1 0xd130 0x41 -phy raw c45 0xf1 0x1 0xd131 0xd +phy raw c45 0xf1 0x1 0xd130 0x4F +phy raw c45 0xf1 0x1 0xd131 0x60F phy raw c45 0xf1 0x1 0xd134 1 phy raw c45 0xf1 0x1 0xffde 1 -phy raw c45 0xf1 0x1 0xd130 0x41 -phy raw c45 0xf1 0x1 0xd131 0xd +phy raw c45 0xf1 0x1 0xd130 0x4E +phy raw c45 0xf1 0x1 0xd131 0x610 phy raw c45 0xf1 0x1 0xd134 1 phy raw c45 0xf1 0x1 0xffde 2 -phy raw c45 0xf1 0x1 0xd130 0x41 -phy raw c45 0xf1 0x1 0xd131 0xd +phy raw c45 0xf1 0x1 0xd130 0x4E +phy raw c45 0xf1 0x1 0xd131 0x610 phy raw c45 0xf1 0x1 0xd134 1 phy raw c45 0xf1 0x1 0xffde 3 -phy raw c45 0xf1 0x1 0xd130 0x41 -phy raw c45 0xf1 0x1 0xd131 0xd +phy raw c45 0xf1 0x1 0xd130 0x4E +phy raw c45 0xf1 0x1 0xd131 0x610 phy raw c45 0xf1 0x1 0xd134 1 phy raw c45 0xf5 0x1 0xffde 0 -phy raw c45 0xf5 0x1 0xd130 0x41 -phy raw c45 0xf5 0x1 0xd131 0xf +phy raw c45 0xf5 0x1 0xd130 0x4D +phy raw c45 0xf5 0x1 0xd131 0x611 phy raw c45 0xf5 0x1 0xd134 1 phy raw c45 0xf5 0x1 0xffde 1 -phy raw c45 0xf5 0x1 0xd130 0x41 -phy raw c45 0xf5 0x1 0xd131 0xf +phy raw c45 0xf5 0x1 0xd130 0x4D +phy raw c45 0xf5 0x1 0xd131 0x611 phy raw c45 0xf5 0x1 0xd134 1 phy raw c45 0xf5 0x1 0xffde 2 -phy raw c45 0xf5 0x1 0xd130 0x41 -phy raw c45 0xf5 0x1 0xd131 0xf +phy raw c45 0xf5 0x1 0xd130 0x4D +phy raw c45 0xf5 0x1 0xd131 0x611 phy raw c45 0xf5 0x1 0xd134 1 phy raw c45 0xf5 0x1 0xffde 3 -phy raw c45 0xf5 0x1 0xd130 0x41 -phy raw c45 0xf5 0x1 0xd131 0xf +phy raw c45 0xf5 0x1 0xd130 0x4D +phy raw c45 0xf5 0x1 0xd131 0x611 phy raw c45 0xf5 0x1 0xd134 1 phy raw c45 0x181 0x1 0xffde 0 -phy raw c45 0x181 0x1 0xd130 0x41 -phy raw c45 0x181 0x1 0xd131 0xd +phy raw c45 0x181 0x1 0xd130 0x4E +phy raw c45 0x181 0x1 0xd131 0x610 phy raw c45 0x181 0x1 0xd134 1 phy raw c45 0x181 0x1 0xffde 1 -phy raw c45 0x181 0x1 0xd130 0x41 -phy raw c45 0x181 0x1 0xd131 0xd +phy raw c45 0x181 0x1 0xd130 0x4D +phy raw c45 0x181 0x1 0xd131 0x611 phy raw c45 0x181 0x1 0xd134 1 phy raw c45 0x181 0x1 0xffde 2 -phy raw c45 0x181 0x1 0xd130 0x41 -phy raw c45 0x181 0x1 0xd131 0xd +phy raw c45 0x181 0x1 0xd130 0x4E +phy raw c45 0x181 0x1 0xd131 0x610 phy raw c45 0x181 0x1 0xd134 1 phy raw c45 0x181 0x1 0xffde 3 -phy raw c45 0x181 0x1 0xd130 0x41 -phy raw c45 0x181 0x1 0xd131 0xd +phy raw c45 0x181 0x1 0xd130 0x4D +phy raw c45 0x181 0x1 0xd131 0x611 phy raw c45 0x181 0x1 0xd134 1 phy raw c45 0x189 0x1 0xffde 0 -phy raw c45 0x189 0x1 0xd130 0x41 -phy raw c45 0x189 0x1 0xd131 0xe +phy raw c45 0x189 0x1 0xd130 0x4E +phy raw c45 0x189 0x1 0xd131 0x610 phy raw c45 0x189 0x1 0xd134 1 phy raw c45 0x189 0x1 0xffde 1 -phy raw c45 0x189 0x1 0xd130 0x41 -phy raw c45 0x189 0x1 0xd131 0xe +phy raw c45 0x189 0x1 0xd130 0x4E +phy raw c45 0x189 0x1 0xd131 0x610 phy raw c45 0x189 0x1 0xd134 1 phy raw c45 0x189 0x1 0xffde 2 -phy raw c45 0x189 0x1 0xd130 0x41 -phy raw c45 0x189 0x1 0xd131 0xe +phy raw c45 0x189 0x1 0xd130 0x4D +phy raw c45 0x189 0x1 0xd131 0x611 phy raw c45 0x189 0x1 0xd134 1 phy raw c45 0x189 0x1 0xffde 3 -phy raw c45 0x189 0x1 0xd130 0x41 -phy raw c45 0x189 0x1 0xd131 0xe -phy raw c45 0x189 0x1 0xd134 1 - +phy raw c45 0x189 0x1 0xd130 0x4D +phy raw c45 0x189 0x1 0xd131 0x611 +phy raw c45 0x189 0x1 0xd134 1 \ No newline at end of file diff --git a/device/quanta/x86_64-quanta_ix8_rglbmc-r0/media_settings.json b/device/quanta/x86_64-quanta_ix8_rglbmc-r0/media_settings.json new file mode 100644 index 000000000000..9b69cade2898 --- /dev/null +++ b/device/quanta/x86_64-quanta_ix8_rglbmc-r0/media_settings.json @@ -0,0 +1,31 @@ +{ + "GLOBAL_MEDIA_SETTINGS": { + "1-48": { + "Default": { + "preemphasis": { + "lane0": "0x0a5503" + } + } + }, + "49,51-56": { + "Default": { + "preemphasis": { + "lane0": "0x0a5703", + "lane1": "0x0a5703", + "lane2": "0x0a5703", + "lane3": "0x0a5703" + } + } + }, + "50-50": { + "Default": { + "preemphasis": { + "lane0": "0x0a5003", + "lane1": "0x0a5003", + "lane2": "0x0a5003", + "lane3": "0x0a5003" + } + } + } + } +} diff --git a/device/quanta/x86_64-quanta_ix8_rglbmc-r0/preemphasis-48x25_8x100.soc b/device/quanta/x86_64-quanta_ix8_rglbmc-r0/preemphasis-48x25_8x100.soc index 3a0193b73da5..fe049e4c1356 100644 --- a/device/quanta/x86_64-quanta_ix8_rglbmc-r0/preemphasis-48x25_8x100.soc +++ b/device/quanta/x86_64-quanta_ix8_rglbmc-r0/preemphasis-48x25_8x100.soc @@ -6,320 +6,320 @@ linkscan off phy raw c45 0xd1 0x1 0xffde 0 phy raw c45 0xd1 0x1 0xd130 0x55 -phy raw c45 0xd1 0x1 0xd131 0x303 +phy raw c45 0xd1 0x1 0xd131 0x30a phy raw c45 0xd1 0x1 0xd134 0x1 phy raw c45 0xd1 0x1 0xffde 1 phy raw c45 0xd1 0x1 0xd130 0x55 -phy raw c45 0xd1 0x1 0xd131 0x303 +phy raw c45 0xd1 0x1 0xd131 0x30a phy raw c45 0xd1 0x1 0xd134 0x1 phy raw c45 0xd1 0x1 0xffde 2 phy raw c45 0xd1 0x1 0xd130 0x55 -phy raw c45 0xd1 0x1 0xd131 0x303 +phy raw c45 0xd1 0x1 0xd131 0x30a phy raw c45 0xd1 0x1 0xd134 0x1 phy raw c45 0xd1 0x1 0xffde 3 phy raw c45 0xd1 0x1 0xd130 0x55 -phy raw c45 0xd1 0x1 0xd131 0x303 +phy raw c45 0xd1 0x1 0xd131 0x30a phy raw c45 0xd1 0x1 0xd134 0x1 phy raw c45 0xd5 0x1 0xffde 0 phy raw c45 0xd5 0x1 0xd130 0x55 -phy raw c45 0xd5 0x1 0xd131 0x303 +phy raw c45 0xd5 0x1 0xd131 0x30a phy raw c45 0xd5 0x1 0xd134 0x1 phy raw c45 0xd5 0x1 0xffde 1 phy raw c45 0xd5 0x1 0xd130 0x55 -phy raw c45 0xd5 0x1 0xd131 0x303 +phy raw c45 0xd5 0x1 0xd131 0x30a phy raw c45 0xd5 0x1 0xd134 0x1 phy raw c45 0xd5 0x1 0xffde 2 phy raw c45 0xd5 0x1 0xd130 0x55 -phy raw c45 0xd5 0x1 0xd131 0x303 +phy raw c45 0xd5 0x1 0xd131 0x30a phy raw c45 0xd5 0x1 0xd134 0x1 phy raw c45 0xd5 0x1 0xffde 3 phy raw c45 0xd5 0x1 0xd130 0x55 -phy raw c45 0xd5 0x1 0xd131 0x303 +phy raw c45 0xd5 0x1 0xd131 0x30a phy raw c45 0xd5 0x1 0xd134 0x1 phy raw c45 0xc9 0x1 0xffde 0 phy raw c45 0xc9 0x1 0xd130 0x55 -phy raw c45 0xc9 0x1 0xd131 0x303 +phy raw c45 0xc9 0x1 0xd131 0x30a phy raw c45 0xc9 0x1 0xd134 0x1 phy raw c45 0xc9 0x1 0xffde 1 phy raw c45 0xc9 0x1 0xd130 0x55 -phy raw c45 0xc9 0x1 0xd131 0x303 +phy raw c45 0xc9 0x1 0xd131 0x30a phy raw c45 0xc9 0x1 0xd134 0x1 phy raw c45 0xc9 0x1 0xffde 2 phy raw c45 0xc9 0x1 0xd130 0x55 -phy raw c45 0xc9 0x1 0xd131 0x303 +phy raw c45 0xc9 0x1 0xd131 0x30a phy raw c45 0xc9 0x1 0xd134 0x1 phy raw c45 0xc9 0x1 0xffde 3 phy raw c45 0xc9 0x1 0xd130 0x55 -phy raw c45 0xc9 0x1 0xd131 0x303 +phy raw c45 0xc9 0x1 0xd131 0x30a phy raw c45 0xc9 0x1 0xd134 0x1 phy raw c45 0x81 0x1 0xffde 0 phy raw c45 0x81 0x1 0xd130 0x55 -phy raw c45 0x81 0x1 0xd131 0x303 +phy raw c45 0x81 0x1 0xd131 0x30a phy raw c45 0x81 0x1 0xd134 0x1 phy raw c45 0x81 0x1 0xffde 1 phy raw c45 0x81 0x1 0xd130 0x55 -phy raw c45 0x81 0x1 0xd131 0x303 +phy raw c45 0x81 0x1 0xd131 0x30a phy raw c45 0x81 0x1 0xd134 0x1 phy raw c45 0x81 0x1 0xffde 2 phy raw c45 0x81 0x1 0xd130 0x55 -phy raw c45 0x81 0x1 0xd131 0x303 +phy raw c45 0x81 0x1 0xd131 0x30a phy raw c45 0x81 0x1 0xd134 0x1 phy raw c45 0x81 0x1 0xffde 3 phy raw c45 0x81 0x1 0xd130 0x55 -phy raw c45 0x81 0x1 0xd131 0x303 +phy raw c45 0x81 0x1 0xd131 0x30a phy raw c45 0x81 0x1 0xd134 0x1 phy raw c45 0x85 0x1 0xffde 0 phy raw c45 0x85 0x1 0xd130 0x55 -phy raw c45 0x85 0x1 0xd131 0x303 +phy raw c45 0x85 0x1 0xd131 0x30a phy raw c45 0x85 0x1 0xd134 0x1 phy raw c45 0x85 0x1 0xffde 1 phy raw c45 0x85 0x1 0xd130 0x55 -phy raw c45 0x85 0x1 0xd131 0x303 +phy raw c45 0x85 0x1 0xd131 0x30a phy raw c45 0x85 0x1 0xd134 0x1 phy raw c45 0x85 0x1 0xffde 2 phy raw c45 0x85 0x1 0xd130 0x55 -phy raw c45 0x85 0x1 0xd131 0x303 +phy raw c45 0x85 0x1 0xd131 0x30a phy raw c45 0x85 0x1 0xd134 0x1 phy raw c45 0x85 0x1 0xffde 3 phy raw c45 0x85 0x1 0xd130 0x55 -phy raw c45 0x85 0x1 0xd131 0x303 +phy raw c45 0x85 0x1 0xd131 0x30a phy raw c45 0x85 0x1 0xd134 0x1 phy raw c45 0x8d 0x1 0xffde 0 phy raw c45 0x8d 0x1 0xd130 0x55 -phy raw c45 0x8d 0x1 0xd131 0x303 +phy raw c45 0x8d 0x1 0xd131 0x30a phy raw c45 0x8d 0x1 0xd134 0x1 phy raw c45 0x8d 0x1 0xffde 1 phy raw c45 0x8d 0x1 0xd130 0x55 -phy raw c45 0x8d 0x1 0xd131 0x303 +phy raw c45 0x8d 0x1 0xd131 0x30a phy raw c45 0x8d 0x1 0xd134 0x1 phy raw c45 0x8d 0x1 0xffde 2 phy raw c45 0x8d 0x1 0xd130 0x55 -phy raw c45 0x8d 0x1 0xd131 0x303 +phy raw c45 0x8d 0x1 0xd131 0x30a phy raw c45 0x8d 0x1 0xd134 0x1 phy raw c45 0x8d 0x1 0xffde 3 phy raw c45 0x8d 0x1 0xd130 0x55 -phy raw c45 0x8d 0x1 0xd131 0x303 +phy raw c45 0x8d 0x1 0xd131 0x30a phy raw c45 0x8d 0x1 0xd134 0x1 phy raw c45 0x95 0x1 0xffde 0 phy raw c45 0x95 0x1 0xd130 0x55 -phy raw c45 0x95 0x1 0xd131 0x303 +phy raw c45 0x95 0x1 0xd131 0x30a phy raw c45 0x95 0x1 0xd134 0x1 phy raw c45 0x95 0x1 0xffde 1 phy raw c45 0x95 0x1 0xd130 0x55 -phy raw c45 0x95 0x1 0xd131 0x303 +phy raw c45 0x95 0x1 0xd131 0x30a phy raw c45 0x95 0x1 0xd134 0x1 phy raw c45 0x95 0x1 0xffde 2 phy raw c45 0x95 0x1 0xd130 0x55 -phy raw c45 0x95 0x1 0xd131 0x303 +phy raw c45 0x95 0x1 0xd131 0x30a phy raw c45 0x95 0x1 0xd134 0x1 phy raw c45 0x95 0x1 0xffde 3 phy raw c45 0x95 0x1 0xd130 0x55 -phy raw c45 0x95 0x1 0xd131 0x303 +phy raw c45 0x95 0x1 0xd131 0x30a phy raw c45 0x95 0x1 0xd134 0x1 phy raw c45 0xa5 0x1 0xffde 0 phy raw c45 0xa5 0x1 0xd130 0x55 -phy raw c45 0xa5 0x1 0xd131 0x303 +phy raw c45 0xa5 0x1 0xd131 0x30a phy raw c45 0xa5 0x1 0xd134 0x1 phy raw c45 0xa5 0x1 0xffde 1 phy raw c45 0xa5 0x1 0xd130 0x55 -phy raw c45 0xa5 0x1 0xd131 0x303 +phy raw c45 0xa5 0x1 0xd131 0x30a phy raw c45 0xa5 0x1 0xd134 0x1 phy raw c45 0xa5 0x1 0xffde 2 phy raw c45 0xa5 0x1 0xd130 0x55 -phy raw c45 0xa5 0x1 0xd131 0x303 +phy raw c45 0xa5 0x1 0xd131 0x30a phy raw c45 0xa5 0x1 0xd134 0x1 phy raw c45 0xa5 0x1 0xffde 3 phy raw c45 0xa5 0x1 0xd130 0x55 -phy raw c45 0xa5 0x1 0xd131 0x303 +phy raw c45 0xa5 0x1 0xd131 0x30a phy raw c45 0xa5 0x1 0xd134 0x1 phy raw c45 0xa9 0x1 0xffde 0 phy raw c45 0xa9 0x1 0xd130 0x55 -phy raw c45 0xa9 0x1 0xd131 0x303 +phy raw c45 0xa9 0x1 0xd131 0x30a phy raw c45 0xa9 0x1 0xd134 0x1 phy raw c45 0xa9 0x1 0xffde 1 phy raw c45 0xa9 0x1 0xd130 0x55 -phy raw c45 0xa9 0x1 0xd131 0x303 +phy raw c45 0xa9 0x1 0xd131 0x30a phy raw c45 0xa9 0x1 0xd134 0x1 phy raw c45 0xa9 0x1 0xffde 2 phy raw c45 0xa9 0x1 0xd130 0x55 -phy raw c45 0xa9 0x1 0xd131 0x303 +phy raw c45 0xa9 0x1 0xd131 0x30a phy raw c45 0xa9 0x1 0xd134 0x1 phy raw c45 0xa9 0x1 0xffde 3 phy raw c45 0xa9 0x1 0xd130 0x55 -phy raw c45 0xa9 0x1 0xd131 0x303 +phy raw c45 0xa9 0x1 0xd131 0x30a phy raw c45 0xa9 0x1 0xd134 0x1 phy raw c45 0xc1 0x1 0xffde 0 phy raw c45 0xc1 0x1 0xd130 0x55 -phy raw c45 0xc1 0x1 0xd131 0x303 +phy raw c45 0xc1 0x1 0xd131 0x30a phy raw c45 0xc1 0x1 0xd134 0x1 phy raw c45 0xc1 0x1 0xffde 1 phy raw c45 0xc1 0x1 0xd130 0x55 -phy raw c45 0xc1 0x1 0xd131 0x303 +phy raw c45 0xc1 0x1 0xd131 0x30a phy raw c45 0xc1 0x1 0xd134 0x1 phy raw c45 0xc1 0x1 0xffde 2 phy raw c45 0xc1 0x1 0xd130 0x55 -phy raw c45 0xc1 0x1 0xd131 0x303 +phy raw c45 0xc1 0x1 0xd131 0x30a phy raw c45 0xc1 0x1 0xd134 0x1 phy raw c45 0xc1 0x1 0xffde 3 phy raw c45 0xc1 0x1 0xd130 0x55 -phy raw c45 0xc1 0x1 0xd131 0x303 +phy raw c45 0xc1 0x1 0xd131 0x30a phy raw c45 0xc1 0x1 0xd134 0x1 phy raw c45 0xf5 0x1 0xffde 0 phy raw c45 0xf5 0x1 0xd130 0x55 -phy raw c45 0xf5 0x1 0xd131 0x303 +phy raw c45 0xf5 0x1 0xd131 0x30a phy raw c45 0xf5 0x1 0xd134 0x1 phy raw c45 0xf5 0x1 0xffde 1 phy raw c45 0xf5 0x1 0xd130 0x55 -phy raw c45 0xf5 0x1 0xd131 0x303 +phy raw c45 0xf5 0x1 0xd131 0x30a phy raw c45 0xf5 0x1 0xd134 0x1 phy raw c45 0xf5 0x1 0xffde 2 phy raw c45 0xf5 0x1 0xd130 0x55 -phy raw c45 0xf5 0x1 0xd131 0x303 +phy raw c45 0xf5 0x1 0xd131 0x30a phy raw c45 0xf5 0x1 0xd134 0x1 phy raw c45 0xf5 0x1 0xffde 3 phy raw c45 0xf5 0x1 0xd130 0x55 -phy raw c45 0xf5 0x1 0xd131 0x303 +phy raw c45 0xf5 0x1 0xd131 0x30a phy raw c45 0xf5 0x1 0xd134 0x1 phy raw c45 0x185 0x1 0xffde 0 phy raw c45 0x185 0x1 0xd130 0x55 -phy raw c45 0x185 0x1 0xd131 0x303 +phy raw c45 0x185 0x1 0xd131 0x30a phy raw c45 0x185 0x1 0xd134 0x1 phy raw c45 0x185 0x1 0xffde 1 phy raw c45 0x185 0x1 0xd130 0x55 -phy raw c45 0x185 0x1 0xd131 0x303 +phy raw c45 0x185 0x1 0xd131 0x30a phy raw c45 0x185 0x1 0xd134 0x1 phy raw c45 0x185 0x1 0xffde 2 phy raw c45 0x185 0x1 0xd130 0x55 -phy raw c45 0x185 0x1 0xd131 0x303 +phy raw c45 0x185 0x1 0xd131 0x30a phy raw c45 0x185 0x1 0xd134 0x1 phy raw c45 0x185 0x1 0xffde 3 phy raw c45 0x185 0x1 0xd130 0x55 -phy raw c45 0x185 0x1 0xd131 0x303 +phy raw c45 0x185 0x1 0xd131 0x30a phy raw c45 0x185 0x1 0xd134 0x1 # Start of 8x100G phy raw c45 0xe1 0x1 0xffde 0 -phy raw c45 0xe1 0x1 0xd130 0x55 -phy raw c45 0xe1 0x1 0xd131 0x303 +phy raw c45 0xe1 0x1 0xd130 0x57 +phy raw c45 0xe1 0x1 0xd131 0x30a phy raw c45 0xe1 0x1 0xffde 1 -phy raw c45 0xe1 0x1 0xd130 0x55 -phy raw c45 0xe1 0x1 0xd131 0x303 +phy raw c45 0xe1 0x1 0xd130 0x57 +phy raw c45 0xe1 0x1 0xd131 0x30a phy raw c45 0xe1 0x1 0xffde 2 -phy raw c45 0xe1 0x1 0xd130 0x55 -phy raw c45 0xe1 0x1 0xd131 0x303 +phy raw c45 0xe1 0x1 0xd130 0x57 +phy raw c45 0xe1 0x1 0xd131 0x30a phy raw c45 0xe1 0x1 0xffde 3 -phy raw c45 0xe1 0x1 0xd130 0x59 -phy raw c45 0xe1 0x1 0xd131 0x505 +phy raw c45 0xe1 0x1 0xd130 0x57 +phy raw c45 0xe1 0x1 0xd131 0x30a phy raw c45 0xe1 0x1 0xd134 0x1 phy raw c45 0xe5 0x1 0xffde 0 -phy raw c45 0xe5 0x1 0xd130 0x59 -phy raw c45 0xe5 0x1 0xd131 0x502 +phy raw c45 0xe5 0x1 0xd130 0x50 +phy raw c45 0xe5 0x1 0xd131 0x30a phy raw c45 0xe5 0x1 0xffde 1 -phy raw c45 0xe5 0x1 0xd130 0x59 -phy raw c45 0xe5 0x1 0xd131 0x502 +phy raw c45 0xe5 0x1 0xd130 0x50 +phy raw c45 0xe5 0x1 0xd131 0x30a phy raw c45 0xe5 0x1 0xffde 2 -phy raw c45 0xe5 0x1 0xd130 0x59 -phy raw c45 0xe5 0x1 0xd131 0x502 +phy raw c45 0xe5 0x1 0xd130 0x50 +phy raw c45 0xe5 0x1 0xd131 0x30a phy raw c45 0xe5 0x1 0xffde 3 -phy raw c45 0xe5 0x1 0xd130 0x59 -phy raw c45 0xe5 0x1 0xd131 0x502 +phy raw c45 0xe5 0x1 0xd130 0x50 +phy raw c45 0xe5 0x1 0xd131 0x30a phy raw c45 0xe5 0x1 0xd134 0x1 phy raw c45 0xed 0x1 0xffde 0 -phy raw c45 0xed 0x1 0xd130 0x59 -phy raw c45 0xed 0x1 0xd131 0x502 +phy raw c45 0xed 0x1 0xd130 0x57 +phy raw c45 0xed 0x1 0xd131 0x30a phy raw c45 0xed 0x1 0xffde 1 -phy raw c45 0xed 0x1 0xd130 0x59 -phy raw c45 0xed 0x1 0xd131 0x502 +phy raw c45 0xed 0x1 0xd130 0x57 +phy raw c45 0xed 0x1 0xd131 0x30a phy raw c45 0xed 0x1 0xffde 2 -phy raw c45 0xed 0x1 0xd130 0x59 -phy raw c45 0xed 0x1 0xd131 0x502 +phy raw c45 0xed 0x1 0xd130 0x57 +phy raw c45 0xed 0x1 0xd131 0x30a phy raw c45 0xed 0x1 0xffde 3 -phy raw c45 0xed 0x1 0xd130 0x59 -phy raw c45 0xed 0x1 0xd131 0x502 +phy raw c45 0xed 0x1 0xd130 0x57 +phy raw c45 0xed 0x1 0xd131 0x30a phy raw c45 0xed 0x1 0xd134 0x1 phy raw c45 0x189 0x1 0xffde 0 -phy raw c45 0x189 0x1 0xd130 0x59 -phy raw c45 0x189 0x1 0xd131 0x502 +phy raw c45 0x189 0x1 0xd130 0x57 +phy raw c45 0x189 0x1 0xd131 0x30a phy raw c45 0x189 0x1 0xffde 1 -phy raw c45 0x189 0x1 0xd130 0x59 -phy raw c45 0x189 0x1 0xd131 0x502 +phy raw c45 0x189 0x1 0xd130 0x57 +phy raw c45 0x189 0x1 0xd131 0x30a phy raw c45 0x189 0x1 0xffde 2 -phy raw c45 0x189 0x1 0xd130 0x59 -phy raw c45 0x189 0x1 0xd131 0x502 +phy raw c45 0x189 0x1 0xd130 0x57 +phy raw c45 0x189 0x1 0xd131 0x30a phy raw c45 0x189 0x1 0xffde 3 -phy raw c45 0x189 0x1 0xd130 0x59 -phy raw c45 0x189 0x1 0xd131 0x502 +phy raw c45 0x189 0x1 0xd130 0x57 +phy raw c45 0x189 0x1 0xd131 0x30a phy raw c45 0x189 0x1 0xd134 0x1 phy raw c45 0x1a1 0x1 0xffde 0 -phy raw c45 0x1a1 0x1 0xd130 0x59 -phy raw c45 0x1a1 0x1 0xd131 0x502 +phy raw c45 0x1a1 0x1 0xd130 0x57 +phy raw c45 0x1a1 0x1 0xd131 0x30a phy raw c45 0x1a1 0x1 0xffde 1 -phy raw c45 0x1a1 0x1 0xd130 0x59 -phy raw c45 0x1a1 0x1 0xd131 0x502 +phy raw c45 0x1a1 0x1 0xd130 0x57 +phy raw c45 0x1a1 0x1 0xd131 0x30a phy raw c45 0x1a1 0x1 0xffde 2 -phy raw c45 0x1a1 0x1 0xd130 0x59 -phy raw c45 0x1a1 0x1 0xd131 0x502 +phy raw c45 0x1a1 0x1 0xd130 0x57 +phy raw c45 0x1a1 0x1 0xd131 0x30a phy raw c45 0x1a1 0x1 0xffde 3 -phy raw c45 0x1a1 0x1 0xd130 0x59 -phy raw c45 0x1a1 0x1 0xd131 0x502 +phy raw c45 0x1a1 0x1 0xd130 0x57 +phy raw c45 0x1a1 0x1 0xd131 0x30a phy raw c45 0x1a1 0x1 0xd134 0x1 phy raw c45 0x1a9 0x1 0xffde 0 -phy raw c45 0x1a9 0x1 0xd130 0x59 -phy raw c45 0x1a9 0x1 0xd131 0x502 +phy raw c45 0x1a9 0x1 0xd130 0x57 +phy raw c45 0x1a9 0x1 0xd131 0x30a phy raw c45 0x1a9 0x1 0xffde 1 -phy raw c45 0x1a9 0x1 0xd130 0x59 -phy raw c45 0x1a9 0x1 0xd131 0x502 +phy raw c45 0x1a9 0x1 0xd130 0x57 +phy raw c45 0x1a9 0x1 0xd131 0x30a phy raw c45 0x1a9 0x1 0xffde 2 -phy raw c45 0x1a9 0x1 0xd130 0x59 -phy raw c45 0x1a9 0x1 0xd131 0x502 +phy raw c45 0x1a9 0x1 0xd130 0x57 +phy raw c45 0x1a9 0x1 0xd131 0x30a phy raw c45 0x1a9 0x1 0xffde 3 -phy raw c45 0x1a9 0x1 0xd130 0x59 -phy raw c45 0x1a9 0x1 0xd131 0x502 +phy raw c45 0x1a9 0x1 0xd130 0x57 +phy raw c45 0x1a9 0x1 0xd131 0x30a phy raw c45 0x1a9 0x1 0xd134 0x1 phy raw c45 0x1b1 0x1 0xffde 0 -phy raw c45 0x1b1 0x1 0xd130 0x59 -phy raw c45 0x1b1 0x1 0xd131 0x502 +phy raw c45 0x1b1 0x1 0xd130 0x57 +phy raw c45 0x1b1 0x1 0xd131 0x30a phy raw c45 0x1b1 0x1 0xffde 1 -phy raw c45 0x1b1 0x1 0xd130 0x59 -phy raw c45 0x1b1 0x1 0xd131 0x502 +phy raw c45 0x1b1 0x1 0xd130 0x57 +phy raw c45 0x1b1 0x1 0xd131 0x30a phy raw c45 0x1b1 0x1 0xffde 2 -phy raw c45 0x1b1 0x1 0xd130 0x59 -phy raw c45 0x1b1 0x1 0xd131 0x502 +phy raw c45 0x1b1 0x1 0xd130 0x57 +phy raw c45 0x1b1 0x1 0xd131 0x30a phy raw c45 0x1b1 0x1 0xffde 3 -phy raw c45 0x1b1 0x1 0xd130 0x59 -phy raw c45 0x1b1 0x1 0xd131 0x502 +phy raw c45 0x1b1 0x1 0xd130 0x57 +phy raw c45 0x1b1 0x1 0xd131 0x30a phy raw c45 0x1b1 0x1 0xd134 0x1 phy raw c45 0x1b5 0x1 0xffde 0 -phy raw c45 0x1b5 0x1 0xd130 0x59 -phy raw c45 0x1b5 0x1 0xd131 0x502 +phy raw c45 0x1b5 0x1 0xd130 0x57 +phy raw c45 0x1b5 0x1 0xd131 0x30a phy raw c45 0x1b5 0x1 0xffde 1 -phy raw c45 0x1b5 0x1 0xd130 0x59 -phy raw c45 0x1b5 0x1 0xd131 0x502 +phy raw c45 0x1b5 0x1 0xd130 0x57 +phy raw c45 0x1b5 0x1 0xd131 0x30a phy raw c45 0x1b5 0x1 0xffde 2 -phy raw c45 0x1b5 0x1 0xd130 0x59 -phy raw c45 0x1b5 0x1 0xd131 0x502 +phy raw c45 0x1b5 0x1 0xd130 0x57 +phy raw c45 0x1b5 0x1 0xd131 0x30a phy raw c45 0x1b5 0x1 0xffde 3 -phy raw c45 0x1b5 0x1 0xd130 0x59 -phy raw c45 0x1b5 0x1 0xd131 0x502 +phy raw c45 0x1b5 0x1 0xd130 0x57 +phy raw c45 0x1b5 0x1 0xd131 0x30a phy raw c45 0x1b5 0x1 0xd134 0x1 linkscan on \ No newline at end of file diff --git a/device/quanta/x86_64-quanta_ix8a_bwde-r0/media_settings.json b/device/quanta/x86_64-quanta_ix8a_bwde-r0/media_settings.json new file mode 100644 index 000000000000..2f6b52abea75 --- /dev/null +++ b/device/quanta/x86_64-quanta_ix8a_bwde-r0/media_settings.json @@ -0,0 +1,21 @@ +{ + "GLOBAL_MEDIA_SETTINGS": { + "1-48": { + "Default": { + "preemphasis": { + "lane0": "0x063203" + } + } + }, + "49-56": { + "Default": { + "preemphasis": { + "lane0": "0x0a500a", + "lane1": "0x0a500a", + "lane2": "0x0a500a", + "lane3": "0x0a500a" + } + } + } + } +} \ No newline at end of file diff --git a/device/quanta/x86_64-quanta_ix8c_bwde-r0/Quanta-IX8C-56X/td3-ix8c-48x25G+8x100G.config.bcm b/device/quanta/x86_64-quanta_ix8c_bwde-r0/Quanta-IX8C-56X/td3-ix8c-48x25G+8x100G.config.bcm index aa8c6d02c57d..a5dc7f6f433d 100644 --- a/device/quanta/x86_64-quanta_ix8c_bwde-r0/Quanta-IX8C-56X/td3-ix8c-48x25G+8x100G.config.bcm +++ b/device/quanta/x86_64-quanta_ix8c_bwde-r0/Quanta-IX8C-56X/td3-ix8c-48x25G+8x100G.config.bcm @@ -479,84 +479,83 @@ phy_chain_rx_polarity_flip_physical{131.0}=0x0 phy_chain_rx_polarity_flip_physical{132.0}=0x0 -serdes_preemphasis_1=0x35503 -serdes_preemphasis_2=0x35503 -serdes_preemphasis_3=0x35503 -serdes_preemphasis_4=0x35503 -serdes_preemphasis_5=0x35503 -serdes_preemphasis_6=0x35503 -serdes_preemphasis_7=0x35503 -serdes_preemphasis_8=0x35503 -serdes_preemphasis_13=0x35503 -serdes_preemphasis_14=0x35503 -serdes_preemphasis_15=0x35503 -serdes_preemphasis_16=0x35503 -serdes_preemphasis_21=0x35503 -serdes_preemphasis_22=0x35503 -serdes_preemphasis_23=0x35503 -serdes_preemphasis_24=0x35503 -serdes_preemphasis_29=0x35503 -serdes_preemphasis_30=0x35503 -serdes_preemphasis_31=0x35503 -serdes_preemphasis_32=0x35503 -serdes_preemphasis_33=0x35503 -serdes_preemphasis_34=0x35503 -serdes_preemphasis_35=0x35503 -serdes_preemphasis_36=0x35503 -serdes_preemphasis_41=0x35503 -serdes_preemphasis_42=0x35503 -serdes_preemphasis_43=0x35503 -serdes_preemphasis_44=0x35503 -serdes_preemphasis_49=0x35503 -serdes_preemphasis_50=0x35503 -serdes_preemphasis_51=0x35503 -serdes_preemphasis_52=0x35503 -serdes_preemphasis_57=0x35503 -serdes_preemphasis_58=0x35503 -serdes_preemphasis_59=0x35503 -serdes_preemphasis_60=0x35503 -serdes_preemphasis_61=0x35503 -serdes_preemphasis_62=0x35503 -serdes_preemphasis_63=0x35503 -serdes_preemphasis_64=0x35503 -serdes_preemphasis_lane0_67=0x25905 -serdes_preemphasis_lane1_67=0x25905 -serdes_preemphasis_lane2_67=0x25905 -serdes_preemphasis_lane3_67=0x25905 -serdes_preemphasis_lane0_71=0x25905 -serdes_preemphasis_lane1_71=0x25905 -serdes_preemphasis_lane2_71=0x25905 -serdes_preemphasis_lane3_71=0x25905 -serdes_preemphasis_lane0_79=0x25905 -serdes_preemphasis_lane1_79=0x25905 -serdes_preemphasis_lane2_79=0x25905 -serdes_preemphasis_lane3_79=0x25905 -serdes_preemphasis_87=0x35503 -serdes_preemphasis_88=0x35503 -serdes_preemphasis_89=0x35503 -serdes_preemphasis_90=0x35503 -serdes_preemphasis_95=0x35503 -serdes_preemphasis_96=0x35503 -serdes_preemphasis_97=0x35503 -serdes_preemphasis_98=0x35503 -serdes_preemphasis_lane0_99=0x35503 -serdes_preemphasis_lane1_99=0x35503 -serdes_preemphasis_lane2_99=0x35503 -serdes_preemphasis_lane3_99=0x55905 -serdes_preemphasis_lane0_107=0x25905 -serdes_preemphasis_lane1_107=0x25905 -serdes_preemphasis_lane2_107=0x25905 -serdes_preemphasis_lane3_107=0x25905 -serdes_preemphasis_lane0_115=0x25905 -serdes_preemphasis_lane1_115=0x25905 -serdes_preemphasis_lane2_115=0x25905 -serdes_preemphasis_lane3_115=0x25905 -serdes_preemphasis_lane0_123=0x25905 -serdes_preemphasis_lane1_123=0x25905 -serdes_preemphasis_lane2_123=0x25905 -serdes_preemphasis_lane3_123=0x25905 -serdes_preemphasis_lane0_127=0x25905 -serdes_preemphasis_lane1_127=0x25905 -serdes_preemphasis_lane2_127=0x25905 -serdes_preemphasis_lane3_127=0x25905 - +serdes_preemphasis_60=0x0c5602 +serdes_preemphasis_59=0x0c5602 +serdes_preemphasis_58=0x0c5602 +serdes_preemphasis_57=0x0c5602 +serdes_preemphasis_64=0x0c5602 +serdes_preemphasis_63=0x0c5602 +serdes_preemphasis_62=0x0c5602 +serdes_preemphasis_61=0x0c5602 +serdes_preemphasis_49=0x0c5602 +serdes_preemphasis_50=0x0c5602 +serdes_preemphasis_51=0x0c5602 +serdes_preemphasis_52=0x0c5602 +serdes_preemphasis_4=0x0c5602 +serdes_preemphasis_3=0x0c5602 +serdes_preemphasis_2=0x085804 +serdes_preemphasis_1=0x0c5602 +serdes_preemphasis_8=0x085804 +serdes_preemphasis_7=0x085804 +serdes_preemphasis_6=0x085804 +serdes_preemphasis_5=0x085804 +serdes_preemphasis_16=0x065806 +serdes_preemphasis_15=0x085804 +serdes_preemphasis_14=0x085804 +serdes_preemphasis_13=0x085804 +serdes_preemphasis_24=0x065806 +serdes_preemphasis_23=0x065806 +serdes_preemphasis_22=0x065806 +serdes_preemphasis_21=0x065806 +serdes_preemphasis_32=0x065806 +serdes_preemphasis_31=0x065806 +serdes_preemphasis_30=0x065806 +serdes_preemphasis_29=0x075805 +serdes_preemphasis_36=0x075805 +serdes_preemphasis_35=0x075805 +serdes_preemphasis_34=0x065806 +serdes_preemphasis_33=0x085804 +serdes_preemphasis_44=0x085804 +serdes_preemphasis_43=0x085804 +serdes_preemphasis_42=0x085804 +serdes_preemphasis_41=0x085804 +serdes_preemphasis_88=0x085804 +serdes_preemphasis_87=0x085804 +serdes_preemphasis_90=0x085804 +serdes_preemphasis_89=0x085804 +serdes_preemphasis_96=0x085804 +serdes_preemphasis_95=0x085804 +serdes_preemphasis_98=0x085804 +serdes_preemphasis_97=0x085804 +serdes_preemphasis_lane0_99=0x0c5404 +serdes_preemphasis_lane1_99=0x0c5404 +serdes_preemphasis_lane2_99=0x0c5404 +serdes_preemphasis_lane3_99=0x0c5404 +serdes_preemphasis_lane0_107=0x0c5404 +serdes_preemphasis_lane1_107=0x0c5404 +serdes_preemphasis_lane2_107=0x0c5404 +serdes_preemphasis_lane3_107=0x0c5404 +serdes_preemphasis_lane0_115=0x105202 +serdes_preemphasis_lane1_115=0x105202 +serdes_preemphasis_lane2_115=0x105202 +serdes_preemphasis_lane3_115=0x105202 +serdes_preemphasis_lane0_123=0x0c5404 +serdes_preemphasis_lane1_123=0x0c5404 +serdes_preemphasis_lane2_123=0x0c5404 +serdes_preemphasis_lane3_123=0x0c5404 +serdes_preemphasis_lane0_79=0x0d5205 +serdes_preemphasis_lane1_79=0x0d5205 +serdes_preemphasis_lane2_79=0x0d5205 +serdes_preemphasis_lane3_79=0x0d5205 +serdes_preemphasis_lane0_67=0x105202 +serdes_preemphasis_lane1_67=0x105202 +serdes_preemphasis_lane2_67=0x105202 +serdes_preemphasis_lane3_67=0x105202 +serdes_preemphasis_lane0_71=0x115201 +serdes_preemphasis_lane1_71=0x115201 +serdes_preemphasis_lane2_71=0x115201 +serdes_preemphasis_lane3_71=0x115201 +serdes_preemphasis_lane0_127=0x105202 +serdes_preemphasis_lane1_127=0x105202 +serdes_preemphasis_lane2_127=0x105202 +serdes_preemphasis_lane3_127=0x105202 diff --git a/device/quanta/x86_64-quanta_ix8c_bwde-r0/led_proc_init.soc b/device/quanta/x86_64-quanta_ix8c_bwde-r0/led_proc_init.soc index 49f097daca34..8470ab26efeb 100644 --- a/device/quanta/x86_64-quanta_ix8c_bwde-r0/led_proc_init.soc +++ b/device/quanta/x86_64-quanta_ix8c_bwde-r0/led_proc_init.soc @@ -1,4 +1,2 @@ -sleep 10 -m0 Load 0 0x3800 /usr/share/sonic/platform/custom_led.bin -led auto on +m0 load 0 0x3800 /usr/share/sonic/platform/custom_led.bin led start diff --git a/device/quanta/x86_64-quanta_ix8c_bwde-r0/media_settings.json b/device/quanta/x86_64-quanta_ix8c_bwde-r0/media_settings.json new file mode 100644 index 000000000000..31a774aee28b --- /dev/null +++ b/device/quanta/x86_64-quanta_ix8c_bwde-r0/media_settings.json @@ -0,0 +1,72 @@ +{ + "GLOBAL_MEDIA_SETTINGS": { + "1-14,16": { + "Default": { + "preemphasis": { + "lane0": "0x0c5602" + } + } + }, + "15,17-20,22-24,36-48": { + "Default": { + "preemphasis": { + "lane0": "0x085804" + } + } + }, + "21,25-31,35": { + "Default": { + "preemphasis": { + "lane0": "0x065806" + } + } + }, + "32-34": { + "Default": { + "preemphasis": { + "lane0": "0x075805" + } + } + }, + "49,50,52": { + "Default": { + "preemphasis": { + "lane0": "0x0c5404", + "lane1": "0x0c5404", + "lane2": "0x0c5404", + "lane3": "0x0c5404" + } + } + }, + "51,54,56": { + "Default": { + "preemphasis": { + "lane0": "0x105202", + "lane1": "0x105202", + "lane2": "0x105202", + "lane3": "0x105202" + } + } + }, + "53-53": { + "Default": { + "preemphasis": { + "lane0": "0x0d5205", + "lane1": "0x0d5205", + "lane2": "0x0d5205", + "lane3": "0x0d5205" + } + } + }, + "55-55": { + "Default": { + "preemphasis": { + "lane0": "0x115201", + "lane1": "0x115201", + "lane2": "0x115201", + "lane3": "0x115201" + } + } + } + } +} \ No newline at end of file diff --git a/device/quanta/x86_64-quanta_ix9_bwde-r0/Quanta-IX9-32X/hwsku.json b/device/quanta/x86_64-quanta_ix9_bwde-r0/Quanta-IX9-32X/hwsku.json new file mode 100755 index 000000000000..f2d75a388a24 --- /dev/null +++ b/device/quanta/x86_64-quanta_ix9_bwde-r0/Quanta-IX9-32X/hwsku.json @@ -0,0 +1,132 @@ +{ + "interfaces": { + "Ethernet0": { + "default_brkout_mode": "1x400G", + "fec":"rs" + }, + "Ethernet8": { + "default_brkout_mode": "1x400G", + "fec":"rs" + }, + "Ethernet16": { + "default_brkout_mode": "1x400G", + "fec":"rs" + }, + "Ethernet24": { + "default_brkout_mode": "1x400G", + "fec":"rs" + }, + "Ethernet32": { + "default_brkout_mode": "1x400G", + "fec":"rs" + }, + "Ethernet40": { + "default_brkout_mode": "1x400G", + "fec":"rs" + }, + "Ethernet48": { + "default_brkout_mode": "1x400G", + "fec":"rs" + }, + "Ethernet56": { + "default_brkout_mode": "1x400G", + "fec":"rs" + }, + "Ethernet64": { + "default_brkout_mode": "1x400G", + "fec":"rs" + }, + "Ethernet72": { + "default_brkout_mode": "1x400G", + "fec":"rs" + }, + "Ethernet80": { + "default_brkout_mode": "1x400G", + "fec":"rs" + }, + "Ethernet88": { + "default_brkout_mode": "1x400G", + "fec":"rs" + }, + "Ethernet96": { + "default_brkout_mode": "1x400G", + "fec":"rs" + }, + "Ethernet104": { + "default_brkout_mode": "1x400G", + "fec":"rs" + }, + "Ethernet112": { + "default_brkout_mode": "1x400G", + "fec":"rs" + }, + "Ethernet120": { + "default_brkout_mode": "1x400G", + "fec":"rs" + }, + "Ethernet128": { + "default_brkout_mode": "1x400G", + "fec":"rs" + }, + "Ethernet136": { + "default_brkout_mode": "1x400G", + "fec":"rs" + }, + "Ethernet144": { + "default_brkout_mode": "1x400G", + "fec":"rs" + }, + "Ethernet152": { + "default_brkout_mode": "1x400G", + "fec":"rs" + }, + "Ethernet160": { + "default_brkout_mode": "1x400G", + "fec":"rs" + }, + "Ethernet168": { + "default_brkout_mode": "1x400G", + "fec":"rs" + }, + "Ethernet176": { + "default_brkout_mode": "1x400G", + "fec":"rs" + }, + "Ethernet184": { + "default_brkout_mode": "1x400G", + "fec":"rs" + }, + "Ethernet192": { + "default_brkout_mode": "1x400G", + "fec":"rs" + }, + "Ethernet200": { + "default_brkout_mode": "1x400G", + "fec":"rs" + }, + "Ethernet208": { + "default_brkout_mode": "1x400G", + "fec":"rs" + }, + "Ethernet216": { + "default_brkout_mode": "1x400G", + "fec":"rs" + }, + "Ethernet224": { + "default_brkout_mode": "1x400G", + "fec":"rs" + }, + "Ethernet232": { + "default_brkout_mode": "1x400G", + "fec":"rs" + }, + "Ethernet240": { + "default_brkout_mode": "1x400G", + "fec":"rs" + }, + "Ethernet248": { + "default_brkout_mode": "1x400G", + "fec":"rs" + } + } +} diff --git a/device/quanta/x86_64-quanta_ix9_bwde-r0/Quanta-IX9-32X/th3-ix9-32x400G.config.bcm b/device/quanta/x86_64-quanta_ix9_bwde-r0/Quanta-IX9-32X/th3-ix9-32x400G.config.bcm index 93937398e832..c45c402b7277 100644 --- a/device/quanta/x86_64-quanta_ix9_bwde-r0/Quanta-IX9-32X/th3-ix9-32x400G.config.bcm +++ b/device/quanta/x86_64-quanta_ix9_bwde-r0/Quanta-IX9-32X/th3-ix9-32x400G.config.bcm @@ -1,6 +1,7 @@ phy_null=1 pll_bypass=1 +sai_tunnel_global_sip_mask_enable=1 core_clock_frequency=1325 dpr_clock_frequency=1000 device_clock_frequency=1325 @@ -235,6 +236,8 @@ dport_map_port_132=125 dport_map_port_133=126 dport_map_port_134=127 dport_map_port_135=128 +dport_map_port_136=129 +dport_map_port_137=130 ### lane swap and polarity follow front port order ### phy_chain_tx_lane_map_physical{33.0}=0x75206431 diff --git a/device/quanta/x86_64-quanta_ix9_bwde-r0/custom_led.bin b/device/quanta/x86_64-quanta_ix9_bwde-r0/custom_led.bin index 1f12caa4fa08118ecc4d4be3e4ae5ffd5340a16c..2f86cb209d2e0000e6b6b9386efcf0042d9eb634 100644 GIT binary patch literal 416 zcmeycHQp`E&DYJv?ZcMl4J~dA3XBsN)ESi~yD=-za${2Fc8GEcc8qpnm|XrqrsDx; zoST6|n46jt;{}E}3J$E!er^RZA~F-47;du2EZW3k%xKuTX}8nMi|%f$R+BfeY3tmW z#o*>WJ7T^YzhZ)$L&m{i^#_S=o*7jV{K^cv3>R3Hg&X7^B)dgt{DO)Ey9qalK1gv( z$*_`ys9^%C;dzkeR+g~~DiRG;!~6hdBFMaI34Wzn4Io|ClKg6NjUc~<@GK{>@uIniD@Igv$qapI#y2SvrCdd0+~ z#YvBn8Wa_i_bVnQFHU}xd_YMl<-bx=%HkB}4K{lwxXpB1E428JvP2rhxr MZ9sYk5U&Da04}VBh5!Hn literal 204 zcmeycHQde5&DHI}76#RoZj9>8YD~)94pC0Qj?qpt-1wE}xamBQ>^Q|~<-q5}c)`() z%R$7M#W>jY%SGpmR}#r?3_1)K*p-DF95b>dlH6v2X{kmKZx)!8Y67#tq*ODQ-K=2R zpnRKQt`pk@ri@@o1*0IzNp3!Fr=K$_9ZFzOW=^zMc1~nbZcaRu=%C1$RIlim)SPrE osX>u3dB37#a&z*b9)x2!`=gK0AzJVhX4Qo diff --git a/device/quanta/x86_64-quanta_ix9_bwde-r0/led_proc_init.soc b/device/quanta/x86_64-quanta_ix9_bwde-r0/led_proc_init.soc index b6c5d5073931..05022542de4b 100644 --- a/device/quanta/x86_64-quanta_ix9_bwde-r0/led_proc_init.soc +++ b/device/quanta/x86_64-quanta_ix9_bwde-r0/led_proc_init.soc @@ -1,6 +1,4 @@ -sleep 10 m0 Load 0 0x3800 /usr/share/sonic/platform/custom_led.bin -led auto on led start rcload /usr/share/sonic/platform/preemphasis-32x400G.soc diff --git a/device/quanta/x86_64-quanta_ix9_bwde-r0/media_settings.json b/device/quanta/x86_64-quanta_ix9_bwde-r0/media_settings.json new file mode 100644 index 000000000000..989ccb756003 --- /dev/null +++ b/device/quanta/x86_64-quanta_ix9_bwde-r0/media_settings.json @@ -0,0 +1,132 @@ +{ + "GLOBAL_MEDIA_SETTINGS": { + "1,3-32": { + "Default": { + "main":{ + "lane0": "0x00000098", + "lane1": "0x00000098", + "lane2": "0x00000098", + "lane3": "0x00000098", + "lane4": "0x00000098", + "lane5": "0x00000098", + "lane6": "0x00000098", + "lane7": "0x00000098" + }, + "post1":{ + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "post2":{ + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "post3":{ + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "pre1":{ + "lane0": "0xfffffff0", + "lane1": "0xfffffff0", + "lane2": "0xfffffff0", + "lane3": "0xfffffff0", + "lane4": "0xfffffff0", + "lane5": "0xfffffff0", + "lane6": "0xfffffff0", + "lane7": "0xfffffff0" + }, + "pre2":{ + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + } + } + }, + "2-2": { + "Default": { + "main":{ + "lane0": "0x00000098", + "lane1": "0x00000098", + "lane2": "0x00000098", + "lane3": "0x00000098", + "lane4": "0x00000098", + "lane5": "0x00000098", + "lane6": "0x00000098", + "lane7": "0x00000090" + }, + "post1":{ + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0xfffffffc" + }, + "post2":{ + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "post3":{ + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "pre1":{ + "lane0": "0xfffffff0", + "lane1": "0xfffffff0", + "lane2": "0xfffffff0", + "lane3": "0xfffffff0", + "lane4": "0xfffffff0", + "lane5": "0xfffffff0", + "lane6": "0xfffffff0", + "lane7": "0xffffffee" + }, + "pre2":{ + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + } + } + } + } +} \ No newline at end of file diff --git a/device/quanta/x86_64-quanta_ix9_bwde-r0/platform.json b/device/quanta/x86_64-quanta_ix9_bwde-r0/platform.json new file mode 100644 index 000000000000..306a8ddaab3a --- /dev/null +++ b/device/quanta/x86_64-quanta_ix9_bwde-r0/platform.json @@ -0,0 +1,600 @@ +{ + "chassis": { + "name": "T9032-IX9", + "components": [ + { + "name": "BIOS" + }, + { + "name": "BMC" + }, + { + "name": "BOOT_CPLD" + }, + { + "name": "FAN_CPLD" + }, + { + "name": "MB_CPLD_IO_1" + }, + { + "name": "MB_CPLD_IO_2" + }, + { + "name": "MB_CPLD_LED_1" + }, + { + "name": "MB_CPLD_LED_2" + }, + { + "name": "PCIe" + } + ], + "fans": [ + { + "name": "Fantray1_1" + }, + { + "name": "Fantray1_2" + }, + { + "name": "Fantray2_1" + }, + { + "name": "Fantray2_2" + }, + { + "name": "Fantray3_1" + }, + { + "name": "Fantray3_2" + }, + { + "name": "Fantray4_1" + }, + { + "name": "Fantray4_2" + }, + { + "name": "Fantray5_1" + }, + { + "name": "Fantray5_2" + }, + { + "name": "Fantray6_1" + }, + { + "name": "Fantray6_2" + } + ], + "fan_drawers": [ + { + "name": "Fantray1", + "fans": [ + { + "name": "Fantray1_1" + }, + { + "name": "Fantray1_2" + } + ] + }, + { + "name": "Fantray2", + "fans": [ + { + "name": "Fantray2_1" + }, + { + "name": "Fantray2_2" + } + ] + }, + { + "name": "Fantray3", + "fans": [ + { + "name": "Fantray3_1" + }, + { + "name": "Fantray3_2" + } + ] + }, + { + "name": "Fantray4", + "fans": [ + { + "name": "Fantray4_1" + }, + { + "name": "Fantray4_2" + } + ] + }, + { + "name": "Fantray5", + "fans": [ + { + "name": "Fantray5_1" + }, + { + "name": "Fantray5_2" + } + ] + }, + { + "name": "Fantray6", + "fans": [ + { + "name": "Fantray6_1" + }, + { + "name": "Fantray6_2" + } + ] + } + ], + "psus": [ + { + "name": "PSU 1", + "fans": [ + { + "name": "PSU-1_FAN" + } + ] + }, + { + "name": "PSU 2", + "fans": [ + { + "name": "PSU-2_FAN" + } + ] + } + ], + "thermals": [ + { + "name": "PSU1_TEMP1" + }, + { + "name": "PSU1_TEMP2" + }, + { + "name": "PSU1_TEMP3" + }, + { + "name": "PSU2_TEMP1" + }, + { + "name": "PSU2_TEMP2" + }, + { + "name": "PSU2_TEMP3" + }, + { + "name": "Temp_1V05_PCH_VR" + }, + { + "name": "Temp_Ambient_0" + }, + { + "name": "Temp_Ambient_1" + }, + { + "name": "Temp_Ambient_2" + }, + { + "name": "Temp_Ambient_3" + }, + { + "name": "Temp_Ambient_4" + }, + { + "name": "Temp_Ambient_5" + }, + { + "name": "Temp_CPU" + }, + { + "name": "Temp_DDRAB_VR" + }, + { + "name": "Temp_SOC_DIMMA0" + }, + { + "name": "Temp_VCCGBE_VR" + }, + { + "name": "Temp_VCCIN_VR" + } + ], + "sfps": [ + { + "name": "Ethernet0" + }, + { + "name": "Ethernet8" + }, + { + "name": "Ethernet16" + }, + { + "name": "Ethernet24" + }, + { + "name": "Ethernet32" + }, + { + "name": "Ethernet40" + }, + { + "name": "Ethernet48" + }, + { + "name": "Ethernet56" + }, + { + "name": "Ethernet64" + }, + { + "name": "Ethernet72" + }, + { + "name": "Ethernet80" + }, + { + "name": "Ethernet88" + }, + { + "name": "Ethernet96" + }, + { + "name": "Ethernet104" + }, + { + "name": "Ethernet112" + }, + { + "name": "Ethernet120" + }, + { + "name": "Ethernet128" + }, + { + "name": "Ethernet136" + }, + { + "name": "Ethernet144" + }, + { + "name": "Ethernet152" + }, + { + "name": "Ethernet160" + }, + { + "name": "Ethernet168" + }, + { + "name": "Ethernet176" + }, + { + "name": "Ethernet184" + }, + { + "name": "Ethernet192" + }, + { + "name": "Ethernet200" + }, + { + "name": "Ethernet208" + }, + { + "name": "Ethernet216" + }, + { + "name": "Ethernet224" + }, + { + "name": "Ethernet232" + }, + { + "name": "Ethernet240" + }, + { + "name": "Ethernet248" + } + ] + }, + "interfaces": { + "Ethernet0": { + "breakout_modes": { + "1x400G": ["Eth1/1"], + "2x200G[100G]": ["Eth1/1/1", "Eth1/1/2"], + "4x100G[50G]": ["Eth1/1/1", "Eth1/1/2", "Eth1/1/3", "Eth1/1/4"] + }, + "index": "1,1,1,1,1,1,1,1", + "lanes": "33,34,35,36,37,38,39,40" + }, + "Ethernet8": { + "breakout_modes": { + "1x400G": ["Eth1/2"], + "2x200G[100G]": ["Eth1/2/1", "Eth1/2/2"], + "4x100G[50G]": ["Eth1/2/1", "Eth1/2/2", "Eth1/2/3", "Eth1/2/4"] + }, + "index": "2,2,2,2,2,2,2,2", + "lanes": "25,26,27,28,29,30,31,32" + }, + "Ethernet16": { + "breakout_modes": { + "1x400G": ["Eth1/3"], + "2x200G[100G]": ["Eth1/3/1", "Eth1/3/2"], + "4x100G[50G]": ["Eth1/3/1", "Eth1/3/2", "Eth1/3/3", "Eth1/3/4"] + }, + "index": "3,3,3,3,3,3,3,3", + "lanes": "49,50,51,52,53,54,55,56" + }, + "Ethernet24": { + "breakout_modes": { + "1x400G": ["Eth1/4"], + "2x200G[100G]": ["Eth1/4/1", "Eth1/4/2"], + "4x100G[50G]": ["Eth1/4/1", "Eth1/4/2", "Eth1/4/3", "Eth1/4/4"] + }, + "index": "4,4,4,4,4,4,4,4", + "lanes": "57,58,59,60,61,62,63,64" + }, + "Ethernet32": { + "breakout_modes": { + "1x400G": ["Eth1/5"], + "2x200G[100G]": ["Eth1/5/1", "Eth1/5/2"], + "4x100G[50G]": ["Eth1/5/1", "Eth1/5/2", "Eth1/5/3", "Eth1/5/4"] + }, + "index": "5,5,5,5,5,5,5,5", + "lanes": "65,66,67,68,69,70,71,72" + }, + "Ethernet40": { + "breakout_modes": { + "1x400G": ["Eth1/6"], + "2x200G[100G]": ["Eth1/6/1", "Eth1/6/2"], + "4x100G[50G]": ["Eth1/6/1", "Eth1/6/2", "Eth1/6/3", "Eth1/6/4"] + }, + "index": "6,6,6,6,6,6,6,6", + "lanes": "73,74,75,76,77,78,79,80" + }, + "Ethernet48": { + "breakout_modes": { + "1x400G": ["Eth1/7"], + "2x200G[100G]": ["Eth1/7/1", "Eth1/7/2"], + "4x100G[50G]": ["Eth1/7/1", "Eth1/7/2", "Eth1/7/3", "Eth1/7/4"] + }, + "index": "7,7,7,7,7,7,7,7", + "lanes": "81,82,83,84,85,86,87,88" + }, + "Ethernet56": { + "breakout_modes": { + "1x400G": ["Eth1/8"], + "2x200G[100G]": ["Eth1/8/1", "Eth1/8/2"], + "4x100G[50G]": ["Eth1/8/1", "Eth1/8/2", "Eth1/8/3", "Eth1/8/4"] + }, + "index": "8,8,8,8,8,8,8,8", + "lanes": "89,90,91,92,93,94,95,96" + }, + "Ethernet64": { + "breakout_modes": { + "1x400G": ["Eth1/9"], + "2x200G[100G]": ["Eth1/9/1", "Eth1/9/2"], + "4x100G[50G]": ["Eth1/9/1", "Eth1/9/2", "Eth1/9/3", "Eth1/9/4"] + }, + "index": "9,9,9,9,9,9,9,9", + "lanes": "17,18,19,20,21,22,23,24" + }, + "Ethernet72": { + "breakout_modes": { + "1x400G": ["Eth1/10"], + "2x200G[100G]": ["Eth1/10/1", "Eth1/10/2"], + "4x100G[50G]": ["Eth1/10/1", "Eth1/10/2", "Eth1/10/3", "Eth1/10/4"] + }, + "index": "10,10,10,10,10,10,10,10", + "lanes": "97,98,99,100,101,102,103,104" + }, + "Ethernet80": { + "breakout_modes": { + "1x400G": ["Eth1/11"], + "2x200G[100G]": ["Eth1/11/1", "Eth1/11/2"], + "4x100G[50G]": ["Eth1/11/1", "Eth1/11/2", "Eth1/11/3", "Eth1/11/4"] + }, + "index": "11,11,11,11,11,11,11,11", + "lanes": "9,10,11,12,13,14,15,16" + }, + "Ethernet88": { + "breakout_modes": { + "1x400G": ["Eth1/12"], + "2x200G[100G]": ["Eth1/12/1", "Eth1/12/2"], + "4x100G[50G]": ["Eth1/12/1", "Eth1/12/2", "Eth1/12/3", "Eth1/12/4"] + }, + "index": "12,12,12,12,12,12,12,12", + "lanes": "41,42,43,44,45,46,47,48" + }, + "Ethernet96": { + "breakout_modes": { + "1x400G": ["Eth1/13"], + "2x200G[100G]": ["Eth1/13/1", "Eth1/13/2"], + "4x100G[50G]": ["Eth1/13/1", "Eth1/13/2", "Eth1/13/3", "Eth1/13/4"] + }, + "index": "13,13,13,13,13,13,13,13", + "lanes": "113,114,115,116,117,118,119,120" + }, + "Ethernet104": { + "breakout_modes": { + "1x400G": ["Eth1/14"], + "2x200G[100G]": ["Eth1/14/1", "Eth1/14/2"], + "4x100G[50G]": ["Eth1/14/1", "Eth1/14/2", "Eth1/14/3", "Eth1/14/4"] + }, + "index": "14,14,14,14,14,14,14,14", + "lanes": "105,106,107,108,109,110,111,112" + }, + "Ethernet112": { + "breakout_modes": { + "1x400G": ["Eth1/15"], + "2x200G[100G]": ["Eth1/15/1", "Eth1/15/2"], + "4x100G[50G]": ["Eth1/15/1", "Eth1/15/2", "Eth1/15/3", "Eth1/15/4"] + }, + "index": "15,15,15,15,15,15,15,15", + "lanes": "121,122,123,124,125,126,127,128" + }, + "Ethernet120": { + "breakout_modes": { + "1x400G": ["Eth1/16"], + "2x200G[100G]": ["Eth1/16/1", "Eth1/16/2"], + "4x100G[50G]": ["Eth1/16/1", "Eth1/16/2", "Eth1/16/3", "Eth1/16/4"] + }, + "index": "16,16,16,16,16,16,16,16", + "lanes": "1,2,3,4,5,6,7,8" + }, + "Ethernet128": { + "breakout_modes": { + "1x400G": ["Eth1/17"], + "2x200G[100G]": ["Eth1/17/1", "Eth1/17/2"], + "4x100G[50G]": ["Eth1/17/1", "Eth1/17/2", "Eth1/17/3", "Eth1/17/4"] + }, + "index": "17,17,17,17,17,17,17,17", + "lanes": "137,138,139,140,141,142,143,144" + }, + "Ethernet136": { + "breakout_modes": { + "1x400G": ["Eth1/18"], + "2x200G[100G]": ["Eth1/18/1", "Eth1/18/2"], + "4x100G[50G]": ["Eth1/18/1", "Eth1/18/2", "Eth1/18/3", "Eth1/18/4"] + }, + "index": "18,18,18,18,18,18,18,18", + "lanes": "129,130,131,132,133,134,135,136" + }, + "Ethernet144": { + "breakout_modes": { + "1x400G": ["Eth1/19"], + "2x200G[100G]": ["Eth1/19/1", "Eth1/19/2"], + "4x100G[50G]": ["Eth1/19/1", "Eth1/19/2", "Eth1/19/3", "Eth1/19/4"] + }, + "index": "19,19,19,19,19,19,19,19", + "lanes": "241,242,243,244,245,246,247,248" + }, + "Ethernet152": { + "breakout_modes": { + "1x400G": ["Eth1/20"], + "2x200G[100G]": ["Eth1/20/1", "Eth1/20/2"], + "4x100G[50G]": ["Eth1/20/1", "Eth1/20/2", "Eth1/20/3", "Eth1/20/4"] + }, + "index": "20,20,20,20,20,20,20,20", + "lanes": "249,250,251,252,253,254,255,256" + }, + "Ethernet160": { + "breakout_modes": { + "1x400G": ["Eth1/21"], + "2x200G[100G]": ["Eth1/21/1", "Eth1/21/2"], + "4x100G[50G]": ["Eth1/21/1", "Eth1/21/2", "Eth1/21/3", "Eth1/21/4"] + }, + "index": "21,21,21,21,21,21,21,21", + "lanes": "225,226,227,228,229,230,231,232" + }, + "Ethernet168": { + "breakout_modes": { + "1x400G": ["Eth1/22"], + "2x200G[100G]": ["Eth1/22/1", "Eth1/22/2"], + "4x100G[50G]": ["Eth1/22/1", "Eth1/22/2", "Eth1/22/3", "Eth1/22/4"] + }, + "index": "22,22,22,22,22,22,22,22", + "lanes": "145,146,147,148,149,150,151,152" + }, + "Ethernet176": { + "breakout_modes": { + "1x400G": ["Eth1/23"], + "2x200G[100G]": ["Eth1/23/1", "Eth1/23/2"], + "4x100G[50G]": ["Eth1/23/1", "Eth1/23/2", "Eth1/23/3", "Eth1/23/4"] + }, + "index": "23,23,23,23,23,23,23,23", + "lanes": "153,154,155,156,157,158,159,160" + }, + "Ethernet184": { + "breakout_modes": { + "1x400G": ["Eth1/24"], + "2x200G[100G]": ["Eth1/24/1", "Eth1/24/2"], + "4x100G[50G]": ["Eth1/24/1", "Eth1/24/2", "Eth1/24/3", "Eth1/24/4"] + }, + "index": "24,24,24,24,24,24,24,24", + "lanes": "233,234,235,236,237,238,239,240" + }, + "Ethernet192": { + "breakout_modes": { + "1x400G": ["Eth1/25"], + "2x200G[100G]": ["Eth1/25/1", "Eth1/25/2"], + "4x100G[50G]": ["Eth1/25/1", "Eth1/25/2", "Eth1/25/3", "Eth1/25/4"] + }, + "index": "25,25,25,25,25,25,25,25", + "lanes": "161,162,163,164,165,166,167,168" + }, + "Ethernet200": { + "breakout_modes": { + "1x400G": ["Eth1/26"], + "2x200G[100G]": ["Eth1/26/1", "Eth1/26/2"], + "4x100G[50G]": ["Eth1/26/1", "Eth1/26/2", "Eth1/26/3", "Eth1/26/4"] + }, + "index": "26,26,26,26,26,26,26,26", + "lanes": "169,170,171,172,173,174,175,176" + }, + "Ethernet208": { + "breakout_modes": { + "1x400G": ["Eth1/27"], + "2x200G[100G]": ["Eth1/27/1", "Eth1/27/2"], + "4x100G[50G]": ["Eth1/27/1", "Eth1/27/2", "Eth1/27/3", "Eth1/27/4"] + }, + "index": "27,27,27,27,27,27,27,27", + "lanes": "177,178,179,180,181,182,183,184" + }, + "Ethernet216": { + "breakout_modes": { + "1x400G": ["Eth1/28"], + "2x200G[100G]": ["Eth1/28/1", "Eth1/28/2"], + "4x100G[50G]": ["Eth1/28/1", "Eth1/28/2", "Eth1/28/3", "Eth1/28/4"] + }, + "index": "28,28,28,28,28,28,28,28", + "lanes": "185,186,187,188,189,190,191,192" + }, + "Ethernet224": { + "breakout_modes": { + "1x400G": ["Eth1/29"] + }, + "index": "29,29,29,29,29,29,29,29", + "lanes": "193,194,195,196,197,198,199,200" + }, + "Ethernet232": { + "breakout_modes": { + "1x400G": ["Eth1/30"] + }, + "index": "30,30,30,30,30,30,30,30", + "lanes": "201,202,203,204,205,206,207,208" + }, + "Ethernet240": { + "breakout_modes": { + "1x400G": ["Eth1/31"], + "2x200G[100G]": ["Eth1/31/1", "Eth1/31/2"], + "4x100G[50G]": ["Eth1/31/1", "Eth1/31/2", "Eth1/31/3", "Eth1/31/4"], + "8x50G[25G][10G]": ["Eth1/31/1", "Eth1/31/2", "Eth1/31/3", "Eth1/31/4", "Eth1/31/5", "Eth1/31/6", "Eth1/31/7", "Eth1/31/8"] + }, + "index": "31,31,31,31,31,31,31,31", + "lanes": "209,210,211,212,213,214,215,216" + }, + "Ethernet248": { + "breakout_modes": { + "1x400G": ["Eth1/32"], + "2x200G[100G]": ["Eth1/32/1", "Eth1/32/2"], + "4x100G[50G]": ["Eth1/32/1", "Eth1/32/2", "Eth1/32/3", "Eth1/32/4"], + "8x50G[25G][10G]": ["Eth1/31/1", "Eth1/31/2", "Eth1/31/3", "Eth1/31/4", "Eth1/31/5", "Eth1/31/6", "Eth1/31/7", "Eth1/31/8"] + }, + "index": "32,32,32,32,32,32,32,32", + "lanes": "217,218,219,220,221,222,223,224" + } + } +} diff --git a/platform/broadcom/rules.mk b/platform/broadcom/rules.mk index c43a66ee43e3..c7c7381b9735 100644 --- a/platform/broadcom/rules.mk +++ b/platform/broadcom/rules.mk @@ -9,7 +9,7 @@ include $(PLATFORM_PATH)/platform-modules-accton.mk #include $(PLATFORM_PATH)/platform-modules-inventec.mk include $(PLATFORM_PATH)/platform-modules-cel.mk #include $(PLATFORM_PATH)/platform-modules-delta.mk -#include $(PLATFORM_PATH)/platform-modules-quanta.mk +include $(PLATFORM_PATH)/platform-modules-quanta.mk ##include $(PLATFORM_PATH)/platform-modules-mitac.mk include $(PLATFORM_PATH)/platform-modules-juniper.mk #include $(PLATFORM_PATH)/platform-modules-brcm-xlr-gts.mk diff --git a/platform/broadcom/sonic-platform-modules-quanta/ix7-32x/modules/qci_cpld_led.c b/platform/broadcom/sonic-platform-modules-quanta/ix7-32x/modules/qci_cpld_led.c index 64841e8538f6..147a2a7f8611 100644 --- a/platform/broadcom/sonic-platform-modules-quanta/ix7-32x/modules/qci_cpld_led.c +++ b/platform/broadcom/sonic-platform-modules-quanta/ix7-32x/modules/qci_cpld_led.c @@ -49,7 +49,7 @@ static struct class *cpld_class = NULL; struct cpld_data { struct i2c_client *cpld_client; - char name[8]; + char name[16]; u8 cpld_id; }; diff --git a/platform/broadcom/sonic-platform-modules-quanta/ix7-32x/modules/quanta_hwmon_ipmi.c b/platform/broadcom/sonic-platform-modules-quanta/ix7-32x/modules/quanta_hwmon_ipmi.c index 08d6a97d9a09..29b439f290ae 100644 --- a/platform/broadcom/sonic-platform-modules-quanta/ix7-32x/modules/quanta_hwmon_ipmi.c +++ b/platform/broadcom/sonic-platform-modules-quanta/ix7-32x/modules/quanta_hwmon_ipmi.c @@ -86,6 +86,8 @@ #define IPMI_TIMEOUT (4 * HZ) #define IPMI_MAX_WAIT_QUEUE 1 +typedef struct ipmi_user *ipmi_user_t; + struct quanta_hwmon_ipmi_data { struct platform_device *ipmi_platform_dev; @@ -1829,7 +1831,7 @@ static int32_t __init quanta_hwmon_ipmi_init(void) goto device_reg_err; } - data->ipmi_hwmon_dev = hwmon_device_register_with_groups(NULL, DRVNAME, NULL, + data->ipmi_hwmon_dev = hwmon_device_register_with_groups(&data->ipmi_platform_dev->dev, DRVNAME, NULL, NULL); err = IS_ERR(data->ipmi_hwmon_dev); if (err) @@ -1856,21 +1858,15 @@ static int32_t __init quanta_hwmon_ipmi_init(void) return 0; init_sensor_err: - if (g_sensor_data) - { - kfree(g_sensor_data); - g_sensor_data = NULL; - } + kfree(g_sensor_data); + g_sensor_data = NULL; ipmi_create_err: hwmon_device_unregister(data->ipmi_hwmon_dev); hwmon_register_err: platform_device_unregister(data->ipmi_platform_dev); device_reg_err: - if (data) - { - kfree(data); - data = NULL; - } + kfree(data); + data = NULL; alloc_err: return err; } @@ -1886,17 +1882,10 @@ static void __exit quanta_hwmon_ipmi_exit(void) platform_device_unregister(data->ipmi_platform_dev); - if (g_sensor_data) - { - kfree(g_sensor_data); - g_sensor_data = NULL; - } - - if (data) - { - kfree(data); - data = NULL; - } + kfree(g_sensor_data); + g_sensor_data = NULL; + kfree(data); + data = NULL; } module_init(quanta_hwmon_ipmi_init); diff --git a/platform/broadcom/sonic-platform-modules-quanta/ix7-32x/modules/quanta_platform_ix7.c b/platform/broadcom/sonic-platform-modules-quanta/ix7-32x/modules/quanta_platform_ix7.c index 02705e37d828..742b6b6e7daf 100644 --- a/platform/broadcom/sonic-platform-modules-quanta/ix7-32x/modules/quanta_platform_ix7.c +++ b/platform/broadcom/sonic-platform-modules-quanta/ix7-32x/modules/quanta_platform_ix7.c @@ -151,9 +151,9 @@ static int __init ix7_platform_init(void) } else { - g_client[0] = i2c_new_device(adapter, &ix7_i2c_devices[0]); // pca9546 - g_client[1] = i2c_new_device(adapter, &ix7_i2c_devices[1]); // pca9548 - g_client[2] = i2c_new_device(adapter, &ix7_i2c_devices[10]); // pca9546 in CPU board + g_client[0] = i2c_new_client_device(adapter, &ix7_i2c_devices[0]); // pca9546 + g_client[1] = i2c_new_client_device(adapter, &ix7_i2c_devices[1]); // pca9548 + g_client[2] = i2c_new_client_device(adapter, &ix7_i2c_devices[10]); // pca9546 in CPU board i2c_put_adapter(adapter); } @@ -164,7 +164,7 @@ static int __init ix7_platform_init(void) } else { - g_client[3] = i2c_new_device(adapter, &ix7_i2c_devices[11]); // CPU Board Data + g_client[3] = i2c_new_client_device(adapter, &ix7_i2c_devices[11]); // CPU Board Data i2c_put_adapter(adapter); } @@ -175,8 +175,8 @@ static int __init ix7_platform_init(void) } else { - g_client[4] = i2c_new_device(adapter, &ix7_i2c_devices[8]); // CPLD2 - g_client[5] = i2c_new_device(adapter, &ix7_i2c_devices[13]); // CPLD_led_1 + g_client[4] = i2c_new_client_device(adapter, &ix7_i2c_devices[8]); // CPLD2 + g_client[5] = i2c_new_client_device(adapter, &ix7_i2c_devices[13]); // CPLD_led_1 i2c_put_adapter(adapter); } @@ -187,8 +187,8 @@ static int __init ix7_platform_init(void) } else { - g_client[6] = i2c_new_device(adapter, &ix7_i2c_devices[9]); // CPLD3 - g_client[7] = i2c_new_device(adapter, &ix7_i2c_devices[14]); // CPLD_led_2 + g_client[6] = i2c_new_client_device(adapter, &ix7_i2c_devices[9]); // CPLD3 + g_client[7] = i2c_new_client_device(adapter, &ix7_i2c_devices[14]); // CPLD_led_2 i2c_put_adapter(adapter); } @@ -199,7 +199,7 @@ static int __init ix7_platform_init(void) } else { - g_client[8] = i2c_new_device(adapter, &ix7_i2c_devices[2]); // MB_BOARDINFO_EEPROM + g_client[8] = i2c_new_client_device(adapter, &ix7_i2c_devices[2]); // MB_BOARDINFO_EEPROM i2c_put_adapter(adapter); } @@ -210,7 +210,7 @@ static int __init ix7_platform_init(void) } else { - g_client[9] = i2c_new_device(adapter, &ix7_i2c_devices[7]); // pca9555 MB Board Data + g_client[9] = i2c_new_client_device(adapter, &ix7_i2c_devices[7]); // pca9555 MB Board Data i2c_put_adapter(adapter); } @@ -221,7 +221,7 @@ static int __init ix7_platform_init(void) } else { - g_client[10] = i2c_new_device(adapter, &ix7_i2c_devices[3]); // pca9548_1 SFP + g_client[10] = i2c_new_client_device(adapter, &ix7_i2c_devices[3]); // pca9548_1 SFP i2c_put_adapter(adapter); } @@ -232,7 +232,7 @@ static int __init ix7_platform_init(void) } else { - g_client[11] = i2c_new_device(adapter, &ix7_i2c_devices[4]); // pca9548_2 SFP + g_client[11] = i2c_new_client_device(adapter, &ix7_i2c_devices[4]); // pca9548_2 SFP i2c_put_adapter(adapter); } @@ -243,7 +243,7 @@ static int __init ix7_platform_init(void) } else { - g_client[12] = i2c_new_device(adapter, &ix7_i2c_devices[5]); // pca9548_3 SFP + g_client[12] = i2c_new_client_device(adapter, &ix7_i2c_devices[5]); // pca9548_3 SFP i2c_put_adapter(adapter); } @@ -254,7 +254,7 @@ static int __init ix7_platform_init(void) } else { - g_client[13] = i2c_new_device(adapter, &ix7_i2c_devices[6]); // pca9548_4 SFP + g_client[13] = i2c_new_client_device(adapter, &ix7_i2c_devices[6]); // pca9548_4 SFP i2c_put_adapter(adapter); } @@ -266,7 +266,7 @@ static int __init ix7_platform_init(void) } else { - g_client_port[i - 17] = i2c_new_device(adapter, &ix7_i2c_devices[12]); + g_client_port[i - 17] = i2c_new_client_device(adapter, &ix7_i2c_devices[12]); i2c_put_adapter(adapter); } } diff --git a/platform/broadcom/sonic-platform-modules-quanta/ix7-32x/sonic_platform/chassis.py b/platform/broadcom/sonic-platform-modules-quanta/ix7-32x/sonic_platform/chassis.py index 58d44f4c553e..a14eb81b7df5 100644 --- a/platform/broadcom/sonic-platform-modules-quanta/ix7-32x/sonic_platform/chassis.py +++ b/platform/broadcom/sonic-platform-modules-quanta/ix7-32x/sonic_platform/chassis.py @@ -72,6 +72,13 @@ def __init__(self): for index in range(1, self.__num_of_ports + 1): self.__xcvr_presence[index] = self._sfp_list[index-1].get_presence() + # Initialize components + from sonic_platform.component import ComponentBIOS, ComponentBMC, ComponentCPLD, ComponentPCIE + self._component_list.append(ComponentBIOS()) + self._component_list.append(ComponentBMC()) + self._component_list.extend(ComponentCPLD.get_component_list()) + self._component_list.append(ComponentPCIE()) + ############################################## # Device methods ############################################## @@ -189,19 +196,7 @@ def get_reboot_cause(self): is "REBOOT_CAUSE_HARDWARE_OTHER", the second string can be used to pass a description of the reboot cause. """ - hw_reboot_cause = "" - with open("/sys/class/watchdog/watchdog0/reboot_reason", "r") as f: - hw_reboot_cause = f.read().strip('\n') - - if hw_reboot_cause == "2": - reboot_cause = self.REBOOT_CAUSE_WATCHDOG - description = 'Hardware Watchdog Reset' - else: - reboot_cause = self.REBOOT_CAUSE_NON_HARDWARE - description = 'Unknown reason' - - return (reboot_cause, description) - + return (ChassisBase.REBOOT_CAUSE_HARDWARE_OTHER, "Invalid Reason") ############################################## # Other methods @@ -239,10 +234,10 @@ def get_change_event(self, timeout=0): cur_xcvr_presence = self._sfp_list[index-1].get_presence() if cur_xcvr_presence != self.__xcvr_presence[index]: if cur_xcvr_presence is True: - xcvr_change_event_dict[str(index)] = '1' + xcvr_change_event_dict[index] = '1' self.__xcvr_presence[index] = True elif cur_xcvr_presence is False: - xcvr_change_event_dict[str(index)] = '0' + xcvr_change_event_dict[index] = '0' self.__xcvr_presence[index] = False event = True diff --git a/platform/broadcom/sonic-platform-modules-quanta/ix7-32x/sonic_platform/component.py b/platform/broadcom/sonic-platform-modules-quanta/ix7-32x/sonic_platform/component.py new file mode 100644 index 000000000000..9f5f69f422a9 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-quanta/ix7-32x/sonic_platform/component.py @@ -0,0 +1,202 @@ +#!/usr/bin/env python + +######################################################################## +# Quanta IX7 +# +# Name: component.py, version: 1.3 +# Module contains an implementation of SONiC Platform Base API and +# provides the Components' (e.g., BIOS, CPLD, FPGA, etc.) available in +# the platform +# +######################################################################## + +try: + import subprocess + from sonic_platform_base.component_base import ComponentBase + from collections import namedtuple +except ImportError as e: + raise ImportError(str(e) + "- required module not found") + + +class Component(ComponentBase): + def __init__(self): + ComponentBase.__init__(self) + self.name = None + self.description = None + + def get_name(self): + return self.name + + def get_description(self): + return self.description + + def install_firmware(self, image_path): + """ + Installs firmware to the component + + Args: + image_path: A string, path to firmware image + + Returns: + A boolean, True if install was successful, False if not + """ + return False + + @staticmethod + def _get_command_result(cmdline): + try: + proc = subprocess.Popen(cmdline, + stdout=subprocess.PIPE, + shell=True, stderr=subprocess.STDOUT, + universal_newlines=True) + stdout = proc.communicate()[0] + rc = proc.wait() + result = stdout.rstrip('\n') + if rc != 0: + raise RuntimeError("Failed to execute command {}, return code {}, {}".format(cmdline, rc, stdout)) + + except OSError as e: + raise RuntimeError("Failed to execute command {} due to {}".format(cmdline, repr(e))) + + return result + + +class ComponentBIOS(Component): + COMPONENT_NAME = 'BIOS' + COMPONENT_DESCRIPTION = 'BIOS - Basic Input/Output System' + + BIOS_QUERY_VERSION_COMMAND = "dmidecode -s bios-version" + + def __init__(self): + super(ComponentBIOS, self).__init__() + + self.name = self.COMPONENT_NAME + self.description = self.COMPONENT_DESCRIPTION + + def get_firmware_version(self): + """ + Retrieves the firmware version of the component + + Returns: + A string containing the firmware version of the component + """ + bios_ver = self._get_command_result(self.BIOS_QUERY_VERSION_COMMAND) + if not bios_ver: + return 'ERR' + else: + return bios_ver + + +class ComponentBMC(Component): + COMPONENT_NAME = 'BMC' + COMPONENT_DESCRIPTION = 'BMC - Board Management Controller' + BMC_QUERY_VERSION_COMMAND = "ipmitool mc info | grep 'Firmware Revision'" + + def __init__(self): + super(ComponentBMC, self).__init__() + + self.name = self.COMPONENT_NAME + self.description = self.COMPONENT_DESCRIPTION + + def get_firmware_version(self): + """ + Retrieves the firmware version of the component + + Returns: + A string containing the firmware version of the component + """ + bmc_ver = self._get_command_result(self.BMC_QUERY_VERSION_COMMAND) + if not bmc_ver: + return 'ERR' + else: + bmc_ver = bmc_ver.split(": ")[1] + return bmc_ver.strip() + + +class ComponentCPLD(Component): + Cpld = namedtuple("Cpld", ['name', 'cmd_index', 'description']) + + cplds = { + 1: Cpld("UART_CPLD", 1, "UART"), + 2: Cpld("BOOT_CPLD", 2, "Power sequence"), + 3: Cpld("FAN_CPLD", 3, "Fan"), + 4: Cpld("MB_CPLD_IO_1", 5, "Port IO-1"), + 5: Cpld("MB_CPLD_IO_2", 6, "Port IO-2"), + 6: Cpld("MB_CPLD_LED_1", 4, "Port LED-1"), + 7: Cpld("MB_CPLD_LED_2", 7, "Port LED-2"), + } + + def __init__(self, component_index): + super(ComponentCPLD, self).__init__() + self.index = component_index + + def get_name(self): + """ + Retrieves the name of the component + + Returns: + A string containing the name of the component + """ + self.name = self.cplds[self.index].name + + return self.name + + def get_description(self): + """ + Retrieves the description of the component + + Returns: + A string containing the description of the component + """ + self.description = self.cplds[self.index].description + + return self.description + + def get_firmware_version(self): + """ + Retrieves the firmware version of the component + + Returns: + A string containing the firmware version of the component + """ + res = self._get_command_result("ipmitool raw 0x32 0xff 0x02 {}".format(self.cplds[self.index].cmd_index)) + if not res: + return 'ERR' + else: + return res.split()[3].upper() + res.split()[2].upper() + res.split()[1].upper() + res.split()[0].upper() + + @classmethod + def get_component_list(cls): + component_list = [] + cpld_number = len(cls.cplds) + + for cpld_idx in range(1, cpld_number + 1): + component_list.append(cls(cpld_idx)) + + return component_list + + +class ComponentPCIE(Component): + COMPONENT_NAME = 'PCIe' + COMPONENT_DESCRIPTION = 'ASIC PCIe Firmware' + PCIE_QUERY_VERSION_COMMAND = "bcmcmd 'pciephy fw version' | grep 'FW version'" + + def __init__(self): + super(ComponentPCIE, self).__init__() + + self.name = self.COMPONENT_NAME + self.description = self.COMPONENT_DESCRIPTION + + def get_firmware_version(self): + """ + Retrieves the firmware version of the component + + Returns: + A string containing the firmware version of the component + """ + version = self._get_command_result(self.PCIE_QUERY_VERSION_COMMAND) + if not version: + return 'ERR' + else: + version = version.split(": ")[1] + return version.strip() diff --git a/platform/broadcom/sonic-platform-modules-quanta/ix7-32x/sonic_platform/fan_drawer.py b/platform/broadcom/sonic-platform-modules-quanta/ix7-32x/sonic_platform/fan_drawer.py index 75e954576a28..3d5f767477ee 100644 --- a/platform/broadcom/sonic-platform-modules-quanta/ix7-32x/sonic_platform/fan_drawer.py +++ b/platform/broadcom/sonic-platform-modules-quanta/ix7-32x/sonic_platform/fan_drawer.py @@ -28,7 +28,7 @@ def get_name(self): Returns: string: The name of the device """ - return 'Fan {}'.format(self._index) + return 'Fantray{}'.format(self._index) def get_presence(self): """ diff --git a/platform/broadcom/sonic-platform-modules-quanta/ix7-32x/sonic_platform/psu.py b/platform/broadcom/sonic-platform-modules-quanta/ix7-32x/sonic_platform/psu.py index 49846fff48ff..3ef0c6816cfb 100644 --- a/platform/broadcom/sonic-platform-modules-quanta/ix7-32x/sonic_platform/psu.py +++ b/platform/broadcom/sonic-platform-modules-quanta/ix7-32x/sonic_platform/psu.py @@ -213,10 +213,10 @@ def get_current(self): def get_input_voltage(self): """ - Retrieves current PSU voltage output + Retrieves current PSU voltage input Returns: - A float number, the output voltage in volts, + A float number, the input voltage in volts, e.g. 12.1 """ voltage_in = 0.0 diff --git a/platform/broadcom/sonic-platform-modules-quanta/ix7-32x/sonic_platform/sfp.py b/platform/broadcom/sonic-platform-modules-quanta/ix7-32x/sonic_platform/sfp.py index a00fc8f2977c..c8336473051e 100644 --- a/platform/broadcom/sonic-platform-modules-quanta/ix7-32x/sonic_platform/sfp.py +++ b/platform/broadcom/sonic-platform-modules-quanta/ix7-32x/sonic_platform/sfp.py @@ -10,13 +10,10 @@ import os import time -#import subprocess -#import sonic_device_util from ctypes import create_string_buffer try: from sonic_platform_base.sfp_base import SfpBase -# from sonic_platform_base.sonic_eeprom import eeprom_dts from sonic_platform_base.sonic_sfp.sff8472 import sff8472InterfaceId from sonic_platform_base.sonic_sfp.sff8472 import sff8472Dom from sonic_platform_base.sonic_sfp.sff8436 import sff8436InterfaceId @@ -175,7 +172,6 @@ def __init__(self, sfp_index, sfp_type): # Init index self.index = sfp_index self.port_num = self.index - #self.dom_supported = False self.sfp_type = sfp_type self.lpmode_path = "/sys/class/cpld-qsfp28/port-"+str(self.port_num)+"/lpmode" self.reset_path = "/sys/class/cpld-qsfp28/port-"+str(self.port_num)+"/reset" @@ -262,15 +258,6 @@ def _convert_string_to_num(self, value_str): else: return 'N/A' - def __read_txt_file(self, file_path): - try: - with open(file_path, 'r') as fd: - data = fd.read() - return data.strip() - except IOError: - pass - return "" - def __is_host(self): return os.system(self.HOST_CHK_CMD) == 0 @@ -325,26 +312,6 @@ def __read_eeprom_specific_bytes(self, offset, num_bytes): return eeprom_raw - def __convert_string_to_num(self, value_str): - if "-inf" in value_str: - return 'N/A' - elif "Unknown" in value_str: - return 'N/A' - elif 'dBm' in value_str: - t_str = value_str.rstrip('dBm') - return float(t_str) - elif 'mA' in value_str: - t_str = value_str.rstrip('mA') - return float(t_str) - elif 'C' in value_str: - t_str = value_str.rstrip('C') - return float(t_str) - elif 'Volts' in value_str: - t_str = value_str.rstrip('Volts') - return float(t_str) - else: - return 'N/A' - def _dom_capability_detect(self): if not self.get_presence(): self.dom_supported = False @@ -503,9 +470,7 @@ def get_transceiver_info(self): else: if not self.get_presence(): return transceiver_info_dict - elif i == max_retry-1: - pass - else: + elif i < max_retry-1: time.sleep(0.5) if sfp_interface_bulk_raw is None: @@ -560,7 +525,8 @@ def get_transceiver_info(self): ['data']['Extended Identifier']['value'] transceiver_info_dict['ext_rateselect_compliance'] = sfp_interface_bulk_data \ ['data']['RateIdentifier']['value'] - transceiver_info_dict['type_abbrv_name'] = 'N/A' + transceiver_info_dict['type_abbrv_name'] = sfp_interface_bulk_data \ + ['data']['type_abbrv_name']['value'] if self.sfp_type == QSFP_TYPE: for key in qsfp_cable_length_tup: if key in sfp_interface_bulk_data['data']: @@ -830,7 +796,7 @@ def get_transceiver_threshold_info(self): transceiver_dom_threshold_dict['txbiaslowwarning'] = channel_threshold_data['TxBiasLowWarning']['value'] for key in transceiver_dom_threshold_dict: - transceiver_dom_threshold_dict[key] = self.__convert_string_to_num(transceiver_dom_threshold_dict[key]) + transceiver_dom_threshold_dict[key] = self._convert_string_to_num(transceiver_dom_threshold_dict[key]) return transceiver_dom_threshold_dict @@ -878,7 +844,7 @@ def get_transceiver_threshold_info(self): transceiver_dom_threshold_info_dict['rxpowerlowwarning'] = dom_module_threshold_data['data']['RXPowerLowWarning']['value'] for key in transceiver_dom_threshold_info_dict: - transceiver_dom_threshold_info_dict[key] = self.__convert_string_to_num(transceiver_dom_threshold_info_dict[key]) + transceiver_dom_threshold_info_dict[key] = self._convert_string_to_num(transceiver_dom_threshold_info_dict[key]) return transceiver_dom_threshold_info_dict @@ -1425,7 +1391,7 @@ def tx_disable(self, tx_disable): sysfsfile_eeprom = open( sysfs_sfp_i2c_client_eeprom_path, mode="r+b", buffering=0) buffer = create_string_buffer(1) - buffer[0] = chr(tx_disable_ctl) + buffer[0] = tx_disable_ctl # Write to eeprom sysfsfile_eeprom.seek(offset + SFP_STATUS_CONTROL_OFFSET) sysfsfile_eeprom.write(buffer[0]) @@ -1478,7 +1444,7 @@ def tx_disable_channel(self, channel, disable): else: tx_disable_ctl = channel_state & (~channel) buffer = create_string_buffer(1) - buffer[0] = chr(tx_disable_ctl) + buffer[0] = tx_disable_ctl # Write to eeprom sysfsfile_eeprom = open( self.port_to_eeprom_mapping[self.port_num], "r+b") @@ -1565,7 +1531,7 @@ def set_power_override(self, power_override, power_set): power_set_bit |= 1 << 1 buffer = create_string_buffer(1) - buffer[0] = chr(power_override_bit | power_set_bit) + buffer[0] = power_override_bit | power_set_bit # Write to eeprom sysfsfile_eeprom = open(self.port_to_eeprom_mapping[self.port_num], "r+b") sysfsfile_eeprom.seek(QSFP_POWEROVERRIDE_OFFSET) diff --git a/platform/broadcom/sonic-platform-modules-quanta/ix7-32x/sonic_platform/thermal.py b/platform/broadcom/sonic-platform-modules-quanta/ix7-32x/sonic_platform/thermal.py index bf5757c9fa22..238d15fbeae8 100644 --- a/platform/broadcom/sonic-platform-modules-quanta/ix7-32x/sonic_platform/thermal.py +++ b/platform/broadcom/sonic-platform-modules-quanta/ix7-32x/sonic_platform/thermal.py @@ -1,7 +1,7 @@ #!/usr/bin/env python ############################################################################# -# Quanta +# Quanta IX7 # # Module contains an implementation of SONiC Platform Base API and # provides the Thermal information @@ -57,7 +57,7 @@ def __get_attr_value(self, attr_path): with open(attr_path, 'r') as fd: retval = fd.read() except Exception as error: - logging.error("Unable to open ", attr_path, " file !") + logging.error("Unable to open " + attr_path + " file !") retval = retval.rstrip(' \t\n\r') return retval diff --git a/platform/broadcom/sonic-platform-modules-quanta/ix7-32x/sonic_platform/watchdog.py b/platform/broadcom/sonic-platform-modules-quanta/ix7-32x/sonic_platform/watchdog.py index 282f356f4e73..0e63d9368cb0 100644 --- a/platform/broadcom/sonic-platform-modules-quanta/ix7-32x/sonic_platform/watchdog.py +++ b/platform/broadcom/sonic-platform-modules-quanta/ix7-32x/sonic_platform/watchdog.py @@ -48,12 +48,16 @@ WDT_SYSFS_PATH = "/sys/class/watchdog/" DEFAULT_TIMEOUT=180 +watchdog=0 class Watchdog(WatchdogBase): def __init__(self): self.watchdog, self.wdt_main_dev_name = self._get_wdt() + if self.wdt_main_dev_name is None: + raise Exception("Watchdog device is not instantiated") + self.status_path = "/sys/class/watchdog/%s/status" % self.wdt_main_dev_name self.state_path = "/sys/class/watchdog/%s/state" % self.wdt_main_dev_name self.timeout_path = "/sys/class/watchdog/%s/timeout" % self.wdt_main_dev_name @@ -74,14 +78,16 @@ def _get_wdt(self): """ Retrieves watchdog device """ + global watchdog wdt_main_dev_list = [dev for dev in os.listdir( "/dev/") if dev.startswith("watchdog") and self._is_wd_main(dev)] if not wdt_main_dev_list: - return None + return (None, None) wdt_main_dev_name = wdt_main_dev_list[0] watchdog_device_path = "/dev/{}".format(wdt_main_dev_name) - self.watchdog = os.open(watchdog_device_path, os.O_RDWR) - return self.watchdog, wdt_main_dev_name + if not watchdog: + watchdog = os.open(watchdog_device_path, os.O_RDWR) + return watchdog, wdt_main_dev_name def _read_file(self, file_path): """ @@ -228,7 +234,8 @@ def __del__(self): Close watchdog """ - os.close(self.watchdog) + if self.watchdog is not None : + os.close(self.watchdog) diff --git a/platform/broadcom/sonic-platform-modules-quanta/ix7-32x/utils/quanta_ix7_util.py b/platform/broadcom/sonic-platform-modules-quanta/ix7-32x/utils/quanta_ix7_util.py index 901f7ba1ae86..4196e24f4625 100755 --- a/platform/broadcom/sonic-platform-modules-quanta/ix7-32x/utils/quanta_ix7_util.py +++ b/platform/broadcom/sonic-platform-modules-quanta/ix7-32x/utils/quanta_ix7_util.py @@ -28,7 +28,7 @@ """ import os -import commands +import subprocess import sys, getopt import logging import time @@ -38,18 +38,16 @@ FORCE = 0 i2c_prefix = '/sys/bus/i2c/devices/' - if DEBUG == True: - print sys.argv[0] - print 'ARGV :', sys.argv[1:] - + print(sys.argv[0]) + print('ARGV :', sys.argv[1:]) def main(): global DEBUG global args global FORCE - if len(sys.argv)<2: + if len(sys.argv) < 2: show_help() options, args = getopt.getopt(sys.argv[1:], 'hdf', ['help', @@ -57,9 +55,9 @@ def main(): 'force', ]) if DEBUG == True: - print options - print args - print len(sys.argv) + print(options) + print(args) + print(len(sys.argv)) for opt, arg in options: if opt in ('-h', '--help'): @@ -73,34 +71,43 @@ def main(): logging.info('no option') for arg in args: if arg == 'install': - install() + install() elif arg == 'clean': - uninstall() + uninstall() else: show_help() - return 0 def show_help(): - print __doc__ % {'scriptName' : sys.argv[0].split("/")[-1]} + print(__doc__ % {'scriptName' : sys.argv[0].split("/")[-1]}) sys.exit(0) def show_log(txt): if DEBUG == True: - print "[IX7-32X]"+txt + print("[IX7-32X]" + txt) return def exec_cmd(cmd, show): - logging.info('Run :'+cmd) - status, output = commands.getstatusoutput(cmd) + logging.info('Run :' + cmd) + status, output = subprocess.getstatusoutput(cmd) show_log (cmd +"with result:" + str(status)) - show_log (" output:"+output) + show_log (" output:" + output) if status: - logging.info('Failed :'+cmd) + logging.info('Failed :' + cmd) if show: - print('Failed :'+cmd) - return status, output + print('Failed :' + cmd) + return status, output + +pca954x_bus_addr =[ +'0-0071', +'0-0072', +'0-0077', +'5-0073', +'6-0073', +'7-0073', +'8-0073' +] instantiate =[ #Enable front-ports LED decoding @@ -119,7 +126,7 @@ def exec_cmd(cmd, show): 'lpc_ich', 'i2c-i801', 'i2c-dev', -'i2c-mux-pca954x force_deselect_on_exit=1', +'i2c-mux-pca954x', 'gpio-pca953x', 'optoe', 'qci_cpld', @@ -155,11 +162,24 @@ def system_install(): exec_cmd("depmod -a ", 1) #install drivers for i in range(0,len(drivers)): - status, output = exec_cmd("modprobe "+drivers[i], 1) - if status: - print output - if FORCE == 0: - return status + status, output = exec_cmd("modprobe " + drivers[i], 1) + if status: + print(output) + #retry quanta_hwmon_ipmi in case it init failed due to ipmi_msghandler init uncompleted + if drivers[i] == 'quanta_hwmon_ipmi': + for _ in range(0, 3): + time.sleep(3) + ret, out = exec_cmd("modprobe quanta_hwmon_ipmi ", 1) + if ret == 0: + break + if ret and FORCE == 0: + return ret + elif FORCE == 0: + return status + + # set pca954x idle_state as -2: MUX_IDLE_DISCONNECT + for i in range(0,len(pca954x_bus_addr)): + exec_cmd("echo -2 > /sys/bus/i2c/drivers/pca954x/{}/idle_state".format(pca954x_bus_addr[i]), 1) #turn on module power exec_cmd("echo 21 > /sys/class/gpio/export ", 1) @@ -174,15 +194,15 @@ def system_install(): exec_cmd("echo 1 >/sys/class/gpio/gpio33/value", 1) #instantiate devices - for i in range(0,len(instantiate)): + for i in range(0, len(instantiate)): status, output = exec_cmd(instantiate[i], 1) - if status: - print output - if FORCE == 0: - return status + if status: + print(output) + if FORCE == 0: + return status #QSFP for 1~32 port - for port_number in range(1,33): + for port_number in range(1, 33): bus_number = port_number + 16 os.system("echo %d >/sys/bus/i2c/devices/%d-0050/port_name" % (port_number, bus_number)) return @@ -195,36 +215,37 @@ def system_ready(): def install(): if not device_found(): - print "No device, installing...." + print("No device, installing....") status = system_install() if status: if FORCE == 0: - return status + return status status, output = exec_cmd("pip3 install /usr/share/sonic/device/x86_64-quanta_ix7_rglbmc-r0/sonic_platform-1.0-py3-none-any.whl",1) if status: - print output - if FORCE == 0: - return status + print(output) + if FORCE == 0: + return status else: - print " ix7 driver already installed...." + print(" ix7 driver already installed....") return def uninstall(): global FORCE #uninstall drivers - for i in range(len(un_drivers)-1,-1,-1): - status, output = exec_cmd("rmmod "+un_drivers[i], 1) + for i in range(len(un_drivers) - 1, -1, -1): + status, output = exec_cmd("rmmod " + un_drivers[i], 1) if status: - print output + print(output) if FORCE == 0: return status status, output = exec_cmd("pip3 uninstall sonic-platform -y ",1) if status: - print output - if FORCE == 0: - return status + print(output) + if FORCE == 0: + return status + return def device_found(): diff --git a/platform/broadcom/sonic-platform-modules-quanta/ix7-bwde-32x/modules/qci_cpld_led.c b/platform/broadcom/sonic-platform-modules-quanta/ix7-bwde-32x/modules/qci_cpld_led.c index d924f51ebc29..7354e9071c7b 100644 --- a/platform/broadcom/sonic-platform-modules-quanta/ix7-bwde-32x/modules/qci_cpld_led.c +++ b/platform/broadcom/sonic-platform-modules-quanta/ix7-bwde-32x/modules/qci_cpld_led.c @@ -51,7 +51,7 @@ static struct class *cpld_class = NULL; struct cpld_data { struct i2c_client *cpld_client; - char name[8]; + char name[16]; u8 cpld_id; }; diff --git a/platform/broadcom/sonic-platform-modules-quanta/ix7-bwde-32x/modules/quanta_hwmon_ipmi.c b/platform/broadcom/sonic-platform-modules-quanta/ix7-bwde-32x/modules/quanta_hwmon_ipmi.c index 08d6a97d9a09..29b439f290ae 100644 --- a/platform/broadcom/sonic-platform-modules-quanta/ix7-bwde-32x/modules/quanta_hwmon_ipmi.c +++ b/platform/broadcom/sonic-platform-modules-quanta/ix7-bwde-32x/modules/quanta_hwmon_ipmi.c @@ -86,6 +86,8 @@ #define IPMI_TIMEOUT (4 * HZ) #define IPMI_MAX_WAIT_QUEUE 1 +typedef struct ipmi_user *ipmi_user_t; + struct quanta_hwmon_ipmi_data { struct platform_device *ipmi_platform_dev; @@ -1829,7 +1831,7 @@ static int32_t __init quanta_hwmon_ipmi_init(void) goto device_reg_err; } - data->ipmi_hwmon_dev = hwmon_device_register_with_groups(NULL, DRVNAME, NULL, + data->ipmi_hwmon_dev = hwmon_device_register_with_groups(&data->ipmi_platform_dev->dev, DRVNAME, NULL, NULL); err = IS_ERR(data->ipmi_hwmon_dev); if (err) @@ -1856,21 +1858,15 @@ static int32_t __init quanta_hwmon_ipmi_init(void) return 0; init_sensor_err: - if (g_sensor_data) - { - kfree(g_sensor_data); - g_sensor_data = NULL; - } + kfree(g_sensor_data); + g_sensor_data = NULL; ipmi_create_err: hwmon_device_unregister(data->ipmi_hwmon_dev); hwmon_register_err: platform_device_unregister(data->ipmi_platform_dev); device_reg_err: - if (data) - { - kfree(data); - data = NULL; - } + kfree(data); + data = NULL; alloc_err: return err; } @@ -1886,17 +1882,10 @@ static void __exit quanta_hwmon_ipmi_exit(void) platform_device_unregister(data->ipmi_platform_dev); - if (g_sensor_data) - { - kfree(g_sensor_data); - g_sensor_data = NULL; - } - - if (data) - { - kfree(data); - data = NULL; - } + kfree(g_sensor_data); + g_sensor_data = NULL; + kfree(data); + data = NULL; } module_init(quanta_hwmon_ipmi_init); diff --git a/platform/broadcom/sonic-platform-modules-quanta/ix7-bwde-32x/modules/quanta_platform_ix7_bwde.c b/platform/broadcom/sonic-platform-modules-quanta/ix7-bwde-32x/modules/quanta_platform_ix7_bwde.c index 4658cee28583..01f116993984 100644 --- a/platform/broadcom/sonic-platform-modules-quanta/ix7-bwde-32x/modules/quanta_platform_ix7_bwde.c +++ b/platform/broadcom/sonic-platform-modules-quanta/ix7-bwde-32x/modules/quanta_platform_ix7_bwde.c @@ -148,9 +148,9 @@ static int __init ix7_bwde_platform_init(void) } else { - g_client[0] = i2c_new_device(adapter, &ix7_bwde_i2c_devices[0]); // pca9546 - g_client[1] = i2c_new_device(adapter, &ix7_bwde_i2c_devices[1]); // pca9548 - g_client[2] = i2c_new_device(adapter, &ix7_bwde_i2c_devices[10]); // CPU Board Data + g_client[0] = i2c_new_client_device(adapter, &ix7_bwde_i2c_devices[0]); // pca9546 + g_client[1] = i2c_new_client_device(adapter, &ix7_bwde_i2c_devices[1]); // pca9548 + g_client[2] = i2c_new_client_device(adapter, &ix7_bwde_i2c_devices[10]); // CPU Board Data i2c_put_adapter(adapter); } @@ -161,8 +161,8 @@ static int __init ix7_bwde_platform_init(void) } else { - g_client[3] = i2c_new_device(adapter, &ix7_bwde_i2c_devices[8]); // CPLD2 - g_client[4] = i2c_new_device(adapter, &ix7_bwde_i2c_devices[12]); // CPLD_led_1 + g_client[3] = i2c_new_client_device(adapter, &ix7_bwde_i2c_devices[8]); // CPLD2 + g_client[4] = i2c_new_client_device(adapter, &ix7_bwde_i2c_devices[12]); // CPLD_led_1 i2c_put_adapter(adapter); } @@ -173,8 +173,8 @@ static int __init ix7_bwde_platform_init(void) } else { - g_client[5] = i2c_new_device(adapter, &ix7_bwde_i2c_devices[9]); // CPLD3 - g_client[6] = i2c_new_device(adapter, &ix7_bwde_i2c_devices[13]); // CPLD_led_2 + g_client[5] = i2c_new_client_device(adapter, &ix7_bwde_i2c_devices[9]); // CPLD3 + g_client[6] = i2c_new_client_device(adapter, &ix7_bwde_i2c_devices[13]); // CPLD_led_2 i2c_put_adapter(adapter); } @@ -185,7 +185,7 @@ static int __init ix7_bwde_platform_init(void) } else { - g_client[7] = i2c_new_device(adapter, &ix7_bwde_i2c_devices[2]); // MB_BOARDINFO_EEPROM + g_client[7] = i2c_new_client_device(adapter, &ix7_bwde_i2c_devices[2]); // MB_BOARDINFO_EEPROM i2c_put_adapter(adapter); } @@ -196,7 +196,7 @@ static int __init ix7_bwde_platform_init(void) } else { - g_client[8] = i2c_new_device(adapter, &ix7_bwde_i2c_devices[7]); // pca9555 MB Board Data + g_client[8] = i2c_new_client_device(adapter, &ix7_bwde_i2c_devices[7]); // pca9555 MB Board Data i2c_put_adapter(adapter); } @@ -207,7 +207,7 @@ static int __init ix7_bwde_platform_init(void) } else { - g_client[9] = i2c_new_device(adapter, &ix7_bwde_i2c_devices[3]); // pca9548_1 SFP + g_client[9] = i2c_new_client_device(adapter, &ix7_bwde_i2c_devices[3]); // pca9548_1 SFP i2c_put_adapter(adapter); } @@ -218,7 +218,7 @@ static int __init ix7_bwde_platform_init(void) } else { - g_client[10] = i2c_new_device(adapter, &ix7_bwde_i2c_devices[4]); // pca9548_2 SFP + g_client[10] = i2c_new_client_device(adapter, &ix7_bwde_i2c_devices[4]); // pca9548_2 SFP i2c_put_adapter(adapter); } @@ -229,7 +229,7 @@ static int __init ix7_bwde_platform_init(void) } else { - g_client[11] = i2c_new_device(adapter, &ix7_bwde_i2c_devices[5]); // pca9548_3 SFP + g_client[11] = i2c_new_client_device(adapter, &ix7_bwde_i2c_devices[5]); // pca9548_3 SFP i2c_put_adapter(adapter); } @@ -240,7 +240,7 @@ static int __init ix7_bwde_platform_init(void) } else { - g_client[12] = i2c_new_device(adapter, &ix7_bwde_i2c_devices[6]); // pca9548_4 SFP + g_client[12] = i2c_new_client_device(adapter, &ix7_bwde_i2c_devices[6]); // pca9548_4 SFP i2c_put_adapter(adapter); } @@ -252,7 +252,7 @@ static int __init ix7_bwde_platform_init(void) } else { - g_client_port[i - 13] = i2c_new_device(adapter, &ix7_bwde_i2c_devices[11]); + g_client_port[i - 13] = i2c_new_client_device(adapter, &ix7_bwde_i2c_devices[11]); i2c_put_adapter(adapter); } } diff --git a/platform/broadcom/sonic-platform-modules-quanta/ix7-bwde-32x/sonic_platform/chassis.py b/platform/broadcom/sonic-platform-modules-quanta/ix7-bwde-32x/sonic_platform/chassis.py index 92a8c433ce80..bcd0739e5ff6 100644 --- a/platform/broadcom/sonic-platform-modules-quanta/ix7-bwde-32x/sonic_platform/chassis.py +++ b/platform/broadcom/sonic-platform-modules-quanta/ix7-bwde-32x/sonic_platform/chassis.py @@ -8,6 +8,7 @@ try: import sys import time + import syslog from sonic_platform_base.chassis_base import ChassisBase from sonic_platform.eeprom import Eeprom from sonic_platform.psu import Psu @@ -71,6 +72,13 @@ def __init__(self): for index in range(1, self.__num_of_ports + 1): self.__xcvr_presence[index] = self._sfp_list[index-1].get_presence() + # Initialize components + from sonic_platform.component import ComponentBIOS, ComponentBMC, ComponentCPLD, ComponentPCIE + self._component_list.append(ComponentBIOS()) + self._component_list.append(ComponentBMC()) + self._component_list.extend(ComponentCPLD.get_component_list()) + self._component_list.append(ComponentPCIE()) + ############################################## # Device methods ############################################## @@ -178,6 +186,39 @@ def get_system_eeprom_info(self): """ return self._eeprom.system_eeprom_info() + def get_reboot_cause(self): + """ + Retrieves the cause of the previous reboot + Returns: + A tuple (string, string) where the first element is a string + containing the cause of the previous reboot. This string must be + one of the predefined strings in this class. If the first string + is "REBOOT_CAUSE_HARDWARE_OTHER", the second string can be used + to pass a description of the reboot cause. + """ + return (ChassisBase.REBOOT_CAUSE_HARDWARE_OTHER, "Invalid Reason") + + ############################################## + # Other methods + ############################################## + def get_watchdog(self): + """ + Retreives hardware watchdog device on this chassis + + Returns: + An object derived from WatchdogBase representing the hardware + watchdog device + """ + try: + if self._watchdog is None: + from sonic_platform.watchdog import Watchdog + # Create the watchdog Instance + self._watchdog = Watchdog() + + except Exception as e: + syslog.syslog(syslog.LOG_ERR, "Fail to load watchdog due to {}".format(e)) + return self._watchdog + def get_change_event(self, timeout=0): """ Currently only support transceiver change events @@ -193,10 +234,10 @@ def get_change_event(self, timeout=0): cur_xcvr_presence = self._sfp_list[index-1].get_presence() if cur_xcvr_presence != self.__xcvr_presence[index]: if cur_xcvr_presence is True: - xcvr_change_event_dict[str(index)] = '1' + xcvr_change_event_dict[index] = '1' self.__xcvr_presence[index] = True elif cur_xcvr_presence is False: - xcvr_change_event_dict[str(index)] = '0' + xcvr_change_event_dict[index] = '0' self.__xcvr_presence[index] = False event = True diff --git a/platform/broadcom/sonic-platform-modules-quanta/ix7-bwde-32x/sonic_platform/component.py b/platform/broadcom/sonic-platform-modules-quanta/ix7-bwde-32x/sonic_platform/component.py new file mode 100644 index 000000000000..ae0c25228930 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-quanta/ix7-bwde-32x/sonic_platform/component.py @@ -0,0 +1,203 @@ +#!/usr/bin/env python + +######################################################################## +# Quanta IX7_BDE +# +# Name: component.py, version: 1.3 +# Module contains an implementation of SONiC Platform Base API and +# provides the Components' (e.g., BIOS, CPLD, FPGA, etc.) available in +# the platform +# +######################################################################## + +try: + import subprocess + from sonic_platform_base.component_base import ComponentBase + from collections import namedtuple +except ImportError as e: + raise ImportError(str(e) + "- required module not found") + + +class Component(ComponentBase): + def __init__(self): + ComponentBase.__init__(self) + self.name = None + self.description = None + + def get_name(self): + return self.name + + def get_description(self): + return self.description + + def install_firmware(self, image_path): + """ + Installs firmware to the component + + Args: + image_path: A string, path to firmware image + + Returns: + A boolean, True if install was successful, False if not + """ + return False + + @staticmethod + def _get_command_result(cmdline): + try: + proc = subprocess.Popen(cmdline, + stdout=subprocess.PIPE, + shell=True, stderr=subprocess.STDOUT, + universal_newlines=True) + stdout = proc.communicate()[0] + rc = proc.wait() + result = stdout.rstrip('\n') + if rc != 0: + raise RuntimeError("Failed to execute command {}, return code {}, {}".format(cmdline, rc, stdout)) + + except OSError as e: + raise RuntimeError("Failed to execute command {} due to {}".format(cmdline, repr(e))) + + return result + + +class ComponentBIOS(Component): + COMPONENT_NAME = 'BIOS' + COMPONENT_DESCRIPTION = 'BIOS - Basic Input/Output System' + + BIOS_QUERY_VERSION_COMMAND = "dmidecode -s bios-version" + + def __init__(self): + super(ComponentBIOS, self).__init__() + + self.name = self.COMPONENT_NAME + self.description = self.COMPONENT_DESCRIPTION + + def get_firmware_version(self): + """ + Retrieves the firmware version of the component + + Returns: + A string containing the firmware version of the component + """ + bios_ver = self._get_command_result(self.BIOS_QUERY_VERSION_COMMAND) + if not bios_ver: + return 'ERR' + else: + return bios_ver + + +class ComponentBMC(Component): + COMPONENT_NAME = 'BMC' + COMPONENT_DESCRIPTION = 'BMC - Board Management Controller' + BMC_QUERY_VERSION_COMMAND = "ipmitool mc info | grep 'Firmware Revision'" + + def __init__(self): + super(ComponentBMC, self).__init__() + + self.name = self.COMPONENT_NAME + self.description = self.COMPONENT_DESCRIPTION + + def get_firmware_version(self): + """ + Retrieves the firmware version of the component + + Returns: + A string containing the firmware version of the component + """ + bmc_ver = self._get_command_result(self.BMC_QUERY_VERSION_COMMAND) + if not bmc_ver: + return 'ERR' + else: + bmc_ver = bmc_ver.split(": ")[1] + return bmc_ver.strip() + + +class ComponentCPLD(Component): + Cpld = namedtuple("Cpld", ['name', 'cmd_index', 'description']) + + cplds = { + 1: Cpld("BOOT_CPLD", 1, "Power sequence"), + 2: Cpld("FAN_CPLD", 2, "Fan"), + 3: Cpld("MB_CPLD_IO_1", 4, "Port IO-1"), + 4: Cpld("MB_CPLD_IO_2", 5, "Port IO-2"), + 5: Cpld("MB_CPLD_LED_1", 3, "Port LED-1"), + 6: Cpld("MB_CPLD_LED_2", 6, "Port LED-2"), + } + + def __init__(self, component_index): + super(ComponentCPLD, self).__init__() + self.index = component_index + + def get_name(self): + """ + Retrieves the name of the component + + Returns: + A string containing the name of the component + """ + self.name = self.cplds[self.index].name + + return self.name + + def get_description(self): + """ + Retrieves the description of the component + + Returns: + A string containing the description of the component + """ + self.description = self.cplds[self.index].description + + return self.description + + def get_firmware_version(self): + """ + Retrieves the firmware version of the component + + Returns: + A string containing the firmware version of the component + """ + self._get_command_result("ipmitool raw 0x30 0xe0 0xd0 0x01 0x01") + res = self._get_command_result("ipmitool raw 0x32 0xff 0x02 {}".format(self.cplds[self.index].cmd_index)) + self._get_command_result("ipmitool raw 0x30 0xe0 0xd0 0x01 0x00") + if not res: + return 'ERR' + else: + return res.split()[3].upper() + res.split()[2].upper() + res.split()[1].upper() + res.split()[0].upper() + + @classmethod + def get_component_list(cls): + component_list = [] + cpld_number = len(cls.cplds) + + for cpld_idx in range(1, cpld_number + 1): + component_list.append(cls(cpld_idx)) + + return component_list + + +class ComponentPCIE(Component): + COMPONENT_NAME = 'PCIe' + COMPONENT_DESCRIPTION = 'ASIC PCIe Firmware' + PCIE_QUERY_VERSION_COMMAND = "bcmcmd 'pciephy fw version' | grep 'FW version'" + + def __init__(self): + super(ComponentPCIE, self).__init__() + + self.name = self.COMPONENT_NAME + self.description = self.COMPONENT_DESCRIPTION + + def get_firmware_version(self): + """ + Retrieves the firmware version of the component + + Returns: + A string containing the firmware version of the component + """ + version = self._get_command_result(self.PCIE_QUERY_VERSION_COMMAND) + if not version: + return 'ERR' + else: + version = version.split(": ")[1] + return version.strip() diff --git a/platform/broadcom/sonic-platform-modules-quanta/ix7-bwde-32x/sonic_platform/fan.py b/platform/broadcom/sonic-platform-modules-quanta/ix7-bwde-32x/sonic_platform/fan.py index 5567eaff9395..fbd8004ce713 100644 --- a/platform/broadcom/sonic-platform-modules-quanta/ix7-bwde-32x/sonic_platform/fan.py +++ b/platform/broadcom/sonic-platform-modules-quanta/ix7-bwde-32x/sonic_platform/fan.py @@ -1,7 +1,7 @@ #!/usr/bin/env python ############################################################################# -# Quanta IX7 +# Quanta IX7_BDE # # Module contains an implementation of SONiC Platform Base API and # provides the FAN information @@ -11,6 +11,7 @@ try: import logging import os + import glob from sonic_platform_base.fan_base import FanBase except ImportError as e: raise ImportError(str(e) + "- required module not found") @@ -19,9 +20,7 @@ ############### # Global ############### -HWMON_DIR = "/sys/class/hwmon/hwmon2/" -FAN_INDEX_START = 18 -NUM_FANTRAYS = 6 +HWMON_IPMI_DIR = "/sys/devices/platform/quanta_hwmon_ipmi/hwmon/hwmon*/" FANS_PERTRAY = 2 class Fan(FanBase): @@ -30,30 +29,46 @@ class Fan(FanBase): def __init__(self, index, is_psu_fan=False): self.is_psu_fan = is_psu_fan self.fan_index = index - self.psu_fan_index_mapping = { - 1:37, - 2:47, - } - self.psu_index_mapping = { - 1:39, - 2:49, - } + hwmon_dir=glob.glob(HWMON_IPMI_DIR)[0] + if self.is_psu_fan: - self.fan_presence_attr = "power{}_present".format(self.psu_index_mapping[index]) - self.fan_pwm_attr = "fan{}_pwm".format(self.psu_fan_index_mapping[index]) - self.fan_rpm_attr = "fan{}_input".format(self.psu_fan_index_mapping[index]) - self.fan_direction_attr = "fan{}_direction".format(self.psu_fan_index_mapping[index]) + power_out_prefix = self.__get_hwmon_attr_prefix(hwmon_dir, "PSU{}_POWER_OUT".format(self.fan_index), 'power') + fan_prefix = self.__get_hwmon_attr_prefix(hwmon_dir, "PSU{}_Fan".format(self.fan_index), 'fan') + self.fan_presence_attr = power_out_prefix + 'present' + self.fan_pwm_attr = fan_prefix + 'pwm' + self.fan_rpm_attr = fan_prefix + 'input' + self.fan_direction_attr = fan_prefix + 'direction' else: - self.fan_presence_attr = "fan{}_present".format(FAN_INDEX_START+(index-1)) - self.fan_pwm_attr = "fan{}_pwm".format(FAN_INDEX_START+(index-1)) - self.fan_rpm_attr = "fan{}_input".format(FAN_INDEX_START+(index-1)) - self.fan_direction_attr = "fan{}_direction".format(FAN_INDEX_START+(index-1)) + fantray_index = (self.fan_index-1)//FANS_PERTRAY+1 + fan_index_intray = self.fan_index - ((fantray_index-1)*FANS_PERTRAY) + fan_prefix = self.__get_hwmon_attr_prefix(hwmon_dir, "Fan_SYS_{}_{}".format(fantray_index, fan_index_intray), 'fan') + self.fan_presence_attr = fan_prefix + 'present' + self.fan_pwm_attr = fan_prefix + 'pwm' + self.fan_rpm_attr = fan_prefix + 'input' + self.fan_direction_attr = fan_prefix + 'direction' ####################### # private function ####################### + def __get_hwmon_attr_prefix(self, dir, label, type): + + retval = 'ERR' + if not os.path.isdir(dir): + return retval + + try: + for filename in os.listdir(dir): + if filename[-5:] == 'label' and type in filename: + file_path = os.path.join(dir, filename) + if os.path.isfile(file_path) and label == self.__get_attr_value(file_path): + return file_path[0:-5] + except Exception as error: + logging.error("Error when getting {} label path: {}".format(label, error)) + + return retval + def __get_attr_value(self, attr_path): retval = 'ERR' @@ -64,7 +79,7 @@ def __get_attr_value(self, attr_path): with open(attr_path, 'r') as fd: retval = fd.read() except Exception as error: - logging.error("Unable to open " + attr_path + " file !") + logging.error("Unable to open {} file: {}".format(attr_path, error)) retval = retval.rstrip(' \t\n\r') return retval @@ -95,8 +110,7 @@ def get_presence(self): Returns: bool: True if device is present, False if not """ - attr_path = HWMON_DIR + self.fan_presence_attr - attr_rv = self.__get_attr_value(attr_path) + attr_rv = self.__get_attr_value(self.fan_presence_attr) if (attr_rv != 'ERR'): if (attr_rv == '1'): return True @@ -112,11 +126,13 @@ def get_status(self): Returns: A boolean value, True if device is operating properly, False if not """ - attr_path = HWMON_DIR + self.fan_rpm_attr - attr_rv = self.__get_attr_value(attr_path) + if self.get_presence(): + attr_rv = self.__get_attr_value(self.fan_rpm_attr) - if (attr_rv != 'ERR' and attr_rv != '0.0'): - return True + if (attr_rv != 'ERR' and attr_rv != '0.0'): + return True + else: + return False else: return False @@ -132,8 +148,7 @@ def get_direction(self): A string, either FAN_DIRECTION_INTAKE or FAN_DIRECTION_EXHAUST depending on fan direction """ - attr_path = HWMON_DIR + self.fan_direction_attr - attr_rv = self.__get_attr_value(attr_path) + attr_rv = self.__get_attr_value(self.fan_direction_attr) if attr_rv == '2': return self.FAN_DIRECTION_INTAKE @@ -148,13 +163,15 @@ def get_speed(self): An integer, the percentage of full fan speed, in the range 0 (off) to 100 (full speed) """ - attr_path = HWMON_DIR + self.fan_pwm_attr - attr_rv = self.__get_attr_value(attr_path) + if self.get_presence(): + attr_rv = self.__get_attr_value(self.fan_pwm_attr) - if (attr_rv != 'ERR'): - return int(float(attr_rv)) + if (attr_rv != 'ERR'): + return int(float(attr_rv)) + else: + return False else: - return False + return 0 def get_speed_rpm(self): """ @@ -163,8 +180,7 @@ def get_speed_rpm(self): Returns: An integer, speed of the fan in RPM """ - attr_path = HWMON_DIR + self.fan_rpm_attr - attr_rv = self.__get_attr_value(attr_path) + attr_rv = self.__get_attr_value(self.fan_rpm_attr) if (attr_rv != 'ERR'): return int(float(attr_rv)) @@ -179,8 +195,7 @@ def get_target_speed(self): An integer, the percentage of full fan speed, in the range 0 (off) to 100 (full speed) """ - attr_path = HWMON_DIR + self.fan_pwm_attr - attr_rv = self.__get_attr_value(attr_path) + attr_rv = self.__get_attr_value(self.fan_pwm_attr) if (attr_rv != 'ERR'): return int(float(attr_rv)) diff --git a/platform/broadcom/sonic-platform-modules-quanta/ix7-bwde-32x/sonic_platform/fan_drawer.py b/platform/broadcom/sonic-platform-modules-quanta/ix7-bwde-32x/sonic_platform/fan_drawer.py index 75e954576a28..3d5f767477ee 100644 --- a/platform/broadcom/sonic-platform-modules-quanta/ix7-bwde-32x/sonic_platform/fan_drawer.py +++ b/platform/broadcom/sonic-platform-modules-quanta/ix7-bwde-32x/sonic_platform/fan_drawer.py @@ -28,7 +28,7 @@ def get_name(self): Returns: string: The name of the device """ - return 'Fan {}'.format(self._index) + return 'Fantray{}'.format(self._index) def get_presence(self): """ diff --git a/platform/broadcom/sonic-platform-modules-quanta/ix7-bwde-32x/sonic_platform/psu.py b/platform/broadcom/sonic-platform-modules-quanta/ix7-bwde-32x/sonic_platform/psu.py index 3fcb9e979ab5..6188c95c7692 100644 --- a/platform/broadcom/sonic-platform-modules-quanta/ix7-bwde-32x/sonic_platform/psu.py +++ b/platform/broadcom/sonic-platform-modules-quanta/ix7-bwde-32x/sonic_platform/psu.py @@ -8,58 +8,61 @@ try: import logging import os + import glob from sonic_platform_base.psu_base import PsuBase from sonic_platform.fan import Fan except ImportError as e: raise ImportError(str(e) + "- required module not found") -HWMON_DIR = "/sys/class/hwmon/hwmon2/" - +HWMON_IPMI_DIR = "/sys/devices/platform/quanta_hwmon_ipmi/hwmon/hwmon*/" class Psu(PsuBase): def __init__(self, index): PsuBase.__init__(self) fan = Fan(index, True) self._fan_list.append(fan) + self.index = index + hwmon_dir=glob.glob(HWMON_IPMI_DIR)[0] + + current_in_prefix = self.__get_hwmon_attr_prefix(hwmon_dir, "PSU{}_CURRENT_IN".format(self.index), 'curr') + current_out_prefix = self.__get_hwmon_attr_prefix(hwmon_dir, "PSU{}_CURRENT_OUT".format(self.index), 'curr') + power_in_prefix = self.__get_hwmon_attr_prefix(hwmon_dir, "PSU{}_POWER_IN".format(self.index), 'power') + power_out_prefix = self.__get_hwmon_attr_prefix(hwmon_dir, "PSU{}_POWER_OUT".format(self.index), 'power') + voltage_in_prefix = self.__get_hwmon_attr_prefix(hwmon_dir, "PSU{}_VOLTAGE_IN".format(self.index), 'in') + voltage_out_prefix = self.__get_hwmon_attr_prefix(hwmon_dir, "PSU{}_VOLTAGE_OUT".format(self.index), 'in') + temp1_prefix = self.__get_hwmon_attr_prefix(hwmon_dir, "PSU{}_TEMP1".format(self.index), 'temp') + + self.psu_current_in_attr = current_in_prefix + 'input' + self.psu_current_out_attr = current_out_prefix + 'input' + self.psu_power_in_attr = power_in_prefix + 'input' + self.psu_power_out_attr = power_out_prefix + 'input' + self.psu_voltage_in_attr = voltage_in_prefix + 'input' + self.psu_voltage_out_attr = voltage_out_prefix + 'input' + self.psu_status_attr = current_out_prefix + 'input' + self.psu_presence_attr = power_out_prefix + 'present' + self.psu_serial_attr = power_out_prefix + 'sn' + self.psu_model_attr = power_out_prefix + 'model' + self.psu_mfr_id_attr = power_out_prefix + 'mfrid' + self.psu_capacity_attr = power_out_prefix + 'pout_max' + self.psu_type_attr = power_out_prefix + 'vin_type' + self.psu_temp_attr = temp1_prefix + 'input' + + def __get_hwmon_attr_prefix(self, dir, label, type): + + retval = 'ERR' + if not os.path.isdir(dir): + return retval + + try: + for filename in os.listdir(dir): + if filename[-5:] == 'label' and type in filename: + file_path = os.path.join(dir, filename) + if os.path.isfile(file_path) and label == self.__get_attr_value(file_path): + return file_path[0:-5] + except Exception as error: + logging.error("Error when getting {} label path: {}".format(label, error)) - self.psu_index_mapping = { - 1:39, - 2:49, - } - self.psu_powerin_index_mapping = { - 1:38, - 2:48, - } - self.psu_currentout_index_mapping = { - 1:36, - 2:46, - } - self.psu_currentin_index_mapping = { - 1:35, - 2:45, - } - self.psu_voltageout_index_mapping = { - 1:44, - 2:54, - } - self.psu_voltagein_index_mapping = { - 1:43, - 2:53, - } - self.index = index - self.psu_presence_attr = "power{}_present".format(self.psu_index_mapping[self.index]) - self.psu_status_attr = "curr{}_input".format(self.psu_currentout_index_mapping[self.index]) - self.psu_power_in_attr = "power{}_input".format(self.psu_powerin_index_mapping[self.index]) - self.psu_power_out_attr = "power{}_input".format(self.psu_index_mapping[self.index]) - self.psu_voltage_out_attr = "in{}_input".format(self.psu_voltageout_index_mapping[self.index]) - self.psu_current_out_attr = "curr{}_input".format(self.psu_currentout_index_mapping[self.index]) - self.psu_voltage_in_attr = "in{}_input".format(self.psu_voltagein_index_mapping[self.index]) - self.psu_current_in_attr = "curr{}_input".format(self.psu_currentin_index_mapping[self.index]) - self.psu_serial_attr = "power{}_sn".format(self.psu_index_mapping[self.index]) - self.psu_model_attr = "power{}_model".format(self.psu_index_mapping[self.index]) - self.psu_mfr_id_attr = "power{}_mfrid".format(self.psu_index_mapping[self.index]) - self.psu_capacity_attr = "power{}_pout_max".format(self.psu_index_mapping[self.index]) - self.psu_type_attr = "power{}_vin_type".format(self.psu_index_mapping[self.index]) + return retval def __get_attr_value(self, attr_path): @@ -71,10 +74,9 @@ def __get_attr_value(self, attr_path): with open(attr_path, 'r') as fd: retval = fd.read() except Exception as error: - logging.error("Unable to open " + attr_path + " file !") + logging.error("Unable to open {} file: {}".format(attr_path, error)) retval = retval.rstrip(' \t\n\r') - fd.close() return retval ############################################## @@ -98,10 +100,9 @@ def get_presence(self): bool: True if device is present, False if not """ presence = False - attr_path = HWMON_DIR+self.psu_presence_attr attr_normal = '1' - attr_rv = self.__get_attr_value(attr_path) + attr_rv = self.__get_attr_value(self.psu_presence_attr) if (attr_rv != 'ERR'): if (attr_rv == attr_normal): presence = True @@ -116,8 +117,7 @@ def get_model(self): string: Model/part number of device """ model = "N/A" - attr_path = HWMON_DIR+self.psu_model_attr - attr_rv = self.__get_attr_value(attr_path) + attr_rv = self.__get_attr_value(self.psu_model_attr) if (attr_rv != 'ERR'): model = attr_rv @@ -131,8 +131,7 @@ def get_mfr_id(self): string: Manufacturer's id of device """ mfr_id = "N/A" - attr_path = HWMON_DIR+self.psu_mfr_id_attr - attr_rv = self.__get_attr_value(attr_path) + attr_rv = self.__get_attr_value(self.psu_mfr_id_attr) if (attr_rv != 'ERR'): mfr_id = attr_rv @@ -146,9 +145,7 @@ def get_serial(self): string: Serial number of device """ serial = "N/A" - attr_path = HWMON_DIR+self.psu_serial_attr - - attr_rv = self.__get_attr_value(attr_path) + attr_rv = self.__get_attr_value(self.psu_serial_attr) if (attr_rv != 'ERR'): serial = attr_rv @@ -162,9 +159,7 @@ def get_status(self): A boolean value, True if device is operating properly, False if not """ status = False - attr_path = HWMON_DIR+self.psu_status_attr - - attr_rv = self.__get_attr_value(attr_path) + attr_rv = self.__get_attr_value(self.psu_status_attr) if (attr_rv != 'ERR'): attr_rv, dummy = attr_rv.split('.', 1) if (int(attr_rv) != 0): @@ -185,9 +180,7 @@ def get_voltage(self): e.g. 12.1 """ voltage_out = 0.0 - attr_path = HWMON_DIR+self.psu_voltage_out_attr - - attr_rv = self.__get_attr_value(attr_path) + attr_rv = self.__get_attr_value(self.psu_voltage_out_attr) if (attr_rv != 'ERR'): attr_rv, dummy = attr_rv.split('.', 1) voltage_out = float(attr_rv) / 1000 @@ -202,9 +195,7 @@ def get_current(self): A float number, the electric current in amperes, e.g 15.4 """ current_out = 0.0 - attr_path = HWMON_DIR+self.psu_current_out_attr - - attr_rv = self.__get_attr_value(attr_path) + attr_rv = self.__get_attr_value(self.psu_current_out_attr) if (attr_rv != 'ERR'): attr_rv, dummy = attr_rv.split('.', 1) current_out = float(attr_rv) / 1000 @@ -213,16 +204,14 @@ def get_current(self): def get_input_voltage(self): """ - Retrieves current PSU voltage output + Retrieves current PSU voltage input Returns: - A float number, the output voltage in volts, + A float number, the input voltage in volts, e.g. 12.1 """ voltage_in = 0.0 - attr_path = HWMON_DIR+self.psu_voltage_in_attr - - attr_rv = self.__get_attr_value(attr_path) + attr_rv = self.__get_attr_value(self.psu_voltage_in_attr) if (attr_rv != 'ERR'): attr_rv, dummy = attr_rv.split('.', 1) voltage_in = float(attr_rv) / 1000 @@ -237,9 +226,7 @@ def get_input_current(self): A float number, the electric current in amperes, e.g 15.4 """ current_in = 0.0 - attr_path = HWMON_DIR+self.psu_current_in_attr - - attr_rv = self.__get_attr_value(attr_path) + attr_rv = self.__get_attr_value(self.psu_current_in_attr) if (attr_rv != 'ERR'): attr_rv, dummy = attr_rv.split('.', 1) current_in = float(attr_rv) / 1000 @@ -254,9 +241,7 @@ def get_power(self): A float number, the power in watts, e.g. 302.6 """ power_out = 0.0 - attr_path = HWMON_DIR+self.psu_power_out_attr - - attr_rv = self.__get_attr_value(attr_path) + attr_rv = self.__get_attr_value(self.psu_power_out_attr) if (attr_rv != 'ERR'): attr_rv, dummy = attr_rv.split('.', 1) power_out = float(attr_rv) / 1000 @@ -293,8 +278,7 @@ def get_type(self): A string, the type of PSU (AC/DC) """ type = "AC" - attr_path = HWMON_DIR+self.psu_type_attr - attr_rv = self.__get_attr_value(attr_path) + attr_rv = self.__get_attr_value(self.psu_type_attr) if (attr_rv != 'ERR'): type = attr_rv @@ -308,8 +292,7 @@ def get_capacity(self): An integer, the capacity of PSU """ capacity = 0 - attr_path = HWMON_DIR+self.psu_capacity_attr - attr_rv = self.__get_attr_value(attr_path) + attr_rv = self.__get_attr_value(self.psu_capacity_attr) if (attr_rv != 'ERR'): try: capacity = int(attr_rv) @@ -318,3 +301,19 @@ def get_capacity(self): return capacity + def get_temperature(self): + """ + Retrieves current temperature reading from PSU + Returns: + A float number of current temperature in Celsius up to nearest thousandth + of one degree Celsius, e.g. 30.125 + """ + + tout = 0.0 + attr_rv = self.__get_attr_value(self.psu_temp_attr) + if (attr_rv != 'ERR'): + tout = float(attr_rv) + + # tout is in milli degree celcius + return float(tout/1000.0) + diff --git a/platform/broadcom/sonic-platform-modules-quanta/ix7-bwde-32x/sonic_platform/sfp.py b/platform/broadcom/sonic-platform-modules-quanta/ix7-bwde-32x/sonic_platform/sfp.py index 759fa99a4bea..1faf552c7b56 100644 --- a/platform/broadcom/sonic-platform-modules-quanta/ix7-bwde-32x/sonic_platform/sfp.py +++ b/platform/broadcom/sonic-platform-modules-quanta/ix7-bwde-32x/sonic_platform/sfp.py @@ -10,13 +10,10 @@ import os import time -#import subprocess -#import sonic_device_util from ctypes import create_string_buffer try: from sonic_platform_base.sfp_base import SfpBase -# from sonic_platform_base.sonic_eeprom import eeprom_dts from sonic_platform_base.sonic_sfp.sff8472 import sff8472InterfaceId from sonic_platform_base.sonic_sfp.sff8472 import sff8472Dom from sonic_platform_base.sonic_sfp.sff8436 import sff8436InterfaceId @@ -175,7 +172,6 @@ def __init__(self, sfp_index, sfp_type): # Init index self.index = sfp_index self.port_num = self.index - #self.dom_supported = False self.sfp_type = sfp_type self.lpmode_path = "/sys/class/cpld-qsfp28/port-"+str(self.port_num)+"/lpmode" self.reset_path = "/sys/class/cpld-qsfp28/port-"+str(self.port_num)+"/reset" @@ -262,15 +258,6 @@ def _convert_string_to_num(self, value_str): else: return 'N/A' - def __read_txt_file(self, file_path): - try: - with open(file_path, 'r') as fd: - data = fd.read() - return data.strip() - except IOError: - pass - return "" - def __is_host(self): return os.system(self.HOST_CHK_CMD) == 0 @@ -325,26 +312,6 @@ def __read_eeprom_specific_bytes(self, offset, num_bytes): return eeprom_raw - def __convert_string_to_num(self, value_str): - if "-inf" in value_str: - return 'N/A' - elif "Unknown" in value_str: - return 'N/A' - elif 'dBm' in value_str: - t_str = value_str.rstrip('dBm') - return float(t_str) - elif 'mA' in value_str: - t_str = value_str.rstrip('mA') - return float(t_str) - elif 'C' in value_str: - t_str = value_str.rstrip('C') - return float(t_str) - elif 'Volts' in value_str: - t_str = value_str.rstrip('Volts') - return float(t_str) - else: - return 'N/A' - def _dom_capability_detect(self): if not self.get_presence(): self.dom_supported = False @@ -503,9 +470,7 @@ def get_transceiver_info(self): else: if not self.get_presence(): return transceiver_info_dict - elif i == max_retry-1: - pass - else: + elif i < max_retry-1: time.sleep(0.5) if sfp_interface_bulk_raw is None: @@ -560,7 +525,8 @@ def get_transceiver_info(self): ['data']['Extended Identifier']['value'] transceiver_info_dict['ext_rateselect_compliance'] = sfp_interface_bulk_data \ ['data']['RateIdentifier']['value'] - transceiver_info_dict['type_abbrv_name'] = 'N/A' + transceiver_info_dict['type_abbrv_name'] = sfp_interface_bulk_data \ + ['data']['type_abbrv_name']['value'] if self.sfp_type == QSFP_TYPE: for key in qsfp_cable_length_tup: if key in sfp_interface_bulk_data['data']: @@ -830,7 +796,7 @@ def get_transceiver_threshold_info(self): transceiver_dom_threshold_dict['txbiaslowwarning'] = channel_threshold_data['TxBiasLowWarning']['value'] for key in transceiver_dom_threshold_dict: - transceiver_dom_threshold_dict[key] = self.__convert_string_to_num(transceiver_dom_threshold_dict[key]) + transceiver_dom_threshold_dict[key] = self._convert_string_to_num(transceiver_dom_threshold_dict[key]) return transceiver_dom_threshold_dict @@ -878,7 +844,7 @@ def get_transceiver_threshold_info(self): transceiver_dom_threshold_info_dict['rxpowerlowwarning'] = dom_module_threshold_data['data']['RXPowerLowWarning']['value'] for key in transceiver_dom_threshold_info_dict: - transceiver_dom_threshold_info_dict[key] = self.__convert_string_to_num(transceiver_dom_threshold_info_dict[key]) + transceiver_dom_threshold_info_dict[key] = self._convert_string_to_num(transceiver_dom_threshold_info_dict[key]) return transceiver_dom_threshold_info_dict @@ -1425,7 +1391,7 @@ def tx_disable(self, tx_disable): sysfsfile_eeprom = open( sysfs_sfp_i2c_client_eeprom_path, mode="r+b", buffering=0) buffer = create_string_buffer(1) - buffer[0] = chr(tx_disable_ctl) + buffer[0] = tx_disable_ctl # Write to eeprom sysfsfile_eeprom.seek(offset + SFP_STATUS_CONTROL_OFFSET) sysfsfile_eeprom.write(buffer[0]) @@ -1478,7 +1444,7 @@ def tx_disable_channel(self, channel, disable): else: tx_disable_ctl = channel_state & (~channel) buffer = create_string_buffer(1) - buffer[0] = chr(tx_disable_ctl) + buffer[0] = tx_disable_ctl # Write to eeprom sysfsfile_eeprom = open( self.port_to_eeprom_mapping[self.port_num], "r+b") @@ -1565,7 +1531,7 @@ def set_power_override(self, power_override, power_set): power_set_bit |= 1 << 1 buffer = create_string_buffer(1) - buffer[0] = chr(power_override_bit | power_set_bit) + buffer[0] = power_override_bit | power_set_bit # Write to eeprom sysfsfile_eeprom = open(self.port_to_eeprom_mapping[self.port_num], "r+b") sysfsfile_eeprom.seek(QSFP_POWEROVERRIDE_OFFSET) diff --git a/platform/broadcom/sonic-platform-modules-quanta/ix7-bwde-32x/sonic_platform/thermal.py b/platform/broadcom/sonic-platform-modules-quanta/ix7-bwde-32x/sonic_platform/thermal.py index a80a07a999ba..cf6073438d3e 100644 --- a/platform/broadcom/sonic-platform-modules-quanta/ix7-bwde-32x/sonic_platform/thermal.py +++ b/platform/broadcom/sonic-platform-modules-quanta/ix7-bwde-32x/sonic_platform/thermal.py @@ -1,7 +1,7 @@ #!/usr/bin/env python ############################################################################# -# Quanta +# Quanta IX7_BDE # # Module contains an implementation of SONiC Platform Base API and # provides the Thermal information @@ -10,45 +10,68 @@ import logging import os +import glob try: from sonic_platform_base.thermal_base import ThermalBase except ImportError as e: raise ImportError(str(e) + "- required module not found") -HWMON_DIR = "/sys/class/hwmon/hwmon2/" +HWMON_IPMI_DIR = "/sys/devices/platform/quanta_hwmon_ipmi/hwmon/hwmon*/" thermal_index_mapping = { - 1:40, - 2:41, - 3:42, - 4:50, - 5:51, - 6:52, - 7:73, - 8:74, - 9:75, - 10:76, - 11:77, - 12:78, - 13:79, - 14:80, - 15:81, - 16:82, - 17:83, - 18:84 + 1:'PSU1_TEMP1', + 2:'PSU1_TEMP2', + 3:'PSU1_TEMP3', + 4:'PSU2_TEMP1', + 5:'PSU2_TEMP2', + 6:'PSU2_TEMP3', + 7:'Temp_1V05_PCH_VR', + 8:'Temp_Ambient_1', + 9:'Temp_Ambient_2', + 10:'Temp_Ambient_3', + 11:'Temp_Ambient_4', + 12:'Temp_Ambient_5', + 13:'Temp_Ambient_6', + 14:'Temp_CPU', + 15:'Temp_DDRAB_VR', + 16:'Temp_SOC_DIMMA0', + 17:'Temp_VCCGBE_VR', + 18:'Temp_VCCIN_VR' } + + class Thermal(ThermalBase): """Platform-specific Thermal class""" def __init__(self, thermal_index): - self.index = thermal_index - self.temp_attr = "temp{}_input".format(thermal_index_mapping[self.index]) - self.high_th_attr = "temp{}_ncrit".format(thermal_index_mapping[self.index]) - self.high_crit_th_attr = "temp{}_crit".format(thermal_index_mapping[self.index]) - self.name_attr = "temp{}_label".format(thermal_index_mapping[self.index]) + self.index = thermal_index + hwmon_dir=glob.glob(HWMON_IPMI_DIR)[0] + thermal_prefix = self.__get_hwmon_attr_prefix(hwmon_dir, thermal_index_mapping[self.index], 'temp') + self.temp_attr = "{}input".format(thermal_prefix) + self.high_th_attr = "{}ncrit".format(thermal_prefix) + self.high_crit_th_attr = "{}crit".format(thermal_prefix) + self.low_th_attr = "{}lncrit".format(thermal_prefix) + self.low_crit_th_attr = "{}lcrit".format(thermal_prefix) + self.name_attr = "{}label".format(thermal_prefix) + + def __get_hwmon_attr_prefix(self, dir, label, type): + + retval = 'ERR' + if not os.path.isdir(dir): + return retval + + try: + for filename in os.listdir(dir): + if filename[-5:] == 'label' and type in filename: + file_path = os.path.join(dir, filename) + if os.path.isfile(file_path) and label == self.__get_attr_value(file_path): + return file_path[0:-5] + except Exception as error: + logging.error("Error when getting {} label path: {}".format(label, error)) + return retval def __get_attr_value(self, attr_path): @@ -60,7 +83,7 @@ def __get_attr_value(self, attr_path): with open(attr_path, 'r') as fd: retval = fd.read() except Exception as error: - logging.error("Unable to open ", attr_path, " file !") + logging.error("Unable to open {} file: {}".format(attr_path, error)) retval = retval.rstrip(' \t\n\r') return retval @@ -72,8 +95,7 @@ def get_name(self): Returns: string: The name of the device """ - attr_path = HWMON_DIR + self.name_attr - attr_rv = self.__get_attr_value(attr_path) + attr_rv = self.__get_attr_value(self.name_attr) if (attr_rv != 'ERR'): return attr_rv @@ -87,8 +109,7 @@ def get_presence(self): Returns: bool: True if device is present, False if not """ - attr_path = HWMON_DIR + self.name_attr - attr_rv = self.__get_attr_value(attr_path) + attr_rv = self.__get_attr_value(self.name_attr) if (attr_rv != 'ERR'): return True @@ -115,8 +136,37 @@ def get_temperature(self): A float number of current temperature in Celsius up to nearest thousandth of one degree Celsius, e.g. 30.125 """ - attr_path = HWMON_DIR + self.temp_attr - attr_rv = self.__get_attr_value(attr_path) + attr_rv = self.__get_attr_value(self.temp_attr) + + if (attr_rv != 'ERR'): + return float(attr_rv) / 1000 + else: + return None + + def get_low_threshold(self): + """ + Retrieves the low threshold temperature of thermal + + Returns: + A float number, the low threshold temperature of thermal in Celsius + up to nearest thousandth of one degree Celsius, e.g. 30.125 + """ + attr_rv = self.__get_attr_value(self.low_th_attr) + + if (attr_rv != 'ERR'): + return float(attr_rv) / 1000 + else: + return None + + def get_low_critical_threshold(self): + """ + Retrieves the low critical threshold temperature of thermal + + Returns: + A float number, the low critical threshold temperature of thermal in Celsius + up to nearest thousandth of one degree Celsius, e.g. 30.125 + """ + attr_rv = self.__get_attr_value(self.low_crit_th_attr) if (attr_rv != 'ERR'): return float(attr_rv) / 1000 @@ -131,8 +181,7 @@ def get_high_threshold(self): A float number, the high threshold temperature of thermal in Celsius up to nearest thousandth of one degree Celsius, e.g. 30.125 """ - attr_path = HWMON_DIR + self.high_th_attr - attr_rv = self.__get_attr_value(attr_path) + attr_rv = self.__get_attr_value(self.high_th_attr) if (attr_rv != 'ERR'): return float(attr_rv) / 1000 @@ -147,8 +196,7 @@ def get_high_critical_threshold(self): A float number, the high threshold temperature of thermal in Celsius up to nearest thousandth of one degree Celsius, e.g. 30.125 """ - attr_path = HWMON_DIR + self.high_crit_th_attr - attr_rv = self.__get_attr_value(attr_path) + attr_rv = self.__get_attr_value(self.high_crit_th_attr) if (attr_rv != 'ERR'): return float(attr_rv) / 1000 diff --git a/platform/broadcom/sonic-platform-modules-quanta/ix7-bwde-32x/sonic_platform/watchdog.py b/platform/broadcom/sonic-platform-modules-quanta/ix7-bwde-32x/sonic_platform/watchdog.py new file mode 100644 index 000000000000..0e63d9368cb0 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-quanta/ix7-bwde-32x/sonic_platform/watchdog.py @@ -0,0 +1,241 @@ +#!/usr/bin/env python + +############################################################################# +# +# Watchdog contains an implementation of SONiC Platform Base Watchdog API +# +############################################################################# +import fcntl +import os +import array + +try: + from sonic_platform_base.watchdog_base import WatchdogBase +except ImportError as e: + raise ImportError(str(e) + "- required module not found") + +""" ioctl constants """ +IO_WRITE = 0x40000000 +IO_READ = 0x80000000 +IO_READ_WRITE = 0xC0000000 +IO_SIZE_INT = 0x00040000 +IO_SIZE_40 = 0x00280000 +IO_TYPE_WATCHDOG = ord('W') << 8 + +WDR_INT = IO_READ | IO_SIZE_INT | IO_TYPE_WATCHDOG +WDR_40 = IO_READ | IO_SIZE_40 | IO_TYPE_WATCHDOG +WDWR_INT = IO_READ_WRITE | IO_SIZE_INT | IO_TYPE_WATCHDOG + +""" Watchdog ioctl commands """ +WDIOC_GETSUPPORT = 0 | WDR_40 +WDIOC_GETSTATUS = 1 | WDR_INT +WDIOC_GETBOOTSTATUS = 2 | WDR_INT +WDIOC_GETTEMP = 3 | WDR_INT +WDIOC_SETOPTIONS = 4 | WDR_INT +WDIOC_KEEPALIVE = 5 | WDR_INT +WDIOC_SETTIMEOUT = 6 | WDWR_INT +WDIOC_GETTIMEOUT = 7 | WDR_INT +WDIOC_SETPRETIMEOUT = 8 | WDWR_INT +WDIOC_GETPRETIMEOUT = 9 | WDR_INT +WDIOC_GETTIMELEFT = 10 | WDR_INT + +""" Watchdog status constants """ +WDIOS_DISABLECARD = 0x0001 +WDIOS_ENABLECARD = 0x0002 + +WDT_COMMON_ERROR = -1 +WD_MAIN_IDENTITY = "iTCO_wdt" +WDT_SYSFS_PATH = "/sys/class/watchdog/" + +DEFAULT_TIMEOUT=180 +watchdog=0 + +class Watchdog(WatchdogBase): + + def __init__(self): + + self.watchdog, self.wdt_main_dev_name = self._get_wdt() + if self.wdt_main_dev_name is None: + raise Exception("Watchdog device is not instantiated") + + self.status_path = "/sys/class/watchdog/%s/status" % self.wdt_main_dev_name + self.state_path = "/sys/class/watchdog/%s/state" % self.wdt_main_dev_name + self.timeout_path = "/sys/class/watchdog/%s/timeout" % self.wdt_main_dev_name + # Set default value + self._disable() + self.armed = False + self.timeout = DEFAULT_TIMEOUT + + def _is_wd_main(self, dev): + """ + Checks watchdog identity + """ + identity = self._read_file( + "{}/{}/identity".format(WDT_SYSFS_PATH, dev)) + return identity == WD_MAIN_IDENTITY + + def _get_wdt(self): + """ + Retrieves watchdog device + """ + global watchdog + wdt_main_dev_list = [dev for dev in os.listdir( + "/dev/") if dev.startswith("watchdog") and self._is_wd_main(dev)] + if not wdt_main_dev_list: + return (None, None) + wdt_main_dev_name = wdt_main_dev_list[0] + watchdog_device_path = "/dev/{}".format(wdt_main_dev_name) + if not watchdog: + watchdog = os.open(watchdog_device_path, os.O_RDWR) + return watchdog, wdt_main_dev_name + + def _read_file(self, file_path): + """ + Read text file + """ + try: + with open(file_path, "r") as fd: + txt = fd.read() + except IOError: + return WDT_COMMON_ERROR + return txt.strip() + + def _enable(self): + """ + Turn on the watchdog timer + """ + req = array.array('h', [WDIOS_ENABLECARD]) + fcntl.ioctl(self.watchdog, WDIOC_SETOPTIONS, req, False) + + def _disable(self): + """ + Turn off the watchdog timer + """ + req = array.array('h', [WDIOS_DISABLECARD]) + fcntl.ioctl(self.watchdog, WDIOC_SETOPTIONS, req, False) + + def _keepalive(self): + """ + Keep alive watchdog timer + """ + fcntl.ioctl(self.watchdog, WDIOC_KEEPALIVE) + + def _settimeout(self, seconds): + """ + Set watchdog timer timeout + @param seconds - timeout in seconds + @return is the actual set timeout + """ + req = array.array('I', [seconds]) + fcntl.ioctl(self.watchdog, WDIOC_SETTIMEOUT, req, True) + return int(req[0]) + + def _gettimeout(self, timeout_path): + """ + Get watchdog timeout + @return watchdog timeout + """ + req = array.array('I', [0]) + fcntl.ioctl(self.watchdog, WDIOC_GETTIMEOUT, req, True) + + return int(req[0]) + + def _gettimeleft(self): + """ + Get time left before watchdog timer expires + @return time left in seconds + """ + req = array.array('I', [0]) + fcntl.ioctl(self.watchdog, WDIOC_GETTIMELEFT, req, True) + + return int(req[0]) + + ################################################################# + + def arm(self, seconds): + """ + Arm the hardware watchdog with a timeout of seconds. + If the watchdog is currently armed, calling this function will + simply reset the timer to the provided value. If the underlying + hardware does not support the value provided in , this + method should arm the watchdog with the *next greater* available + value. + Returns: + An integer specifying the *actual* number of seconds the watchdog + was armed with. On failure returns -1. + """ + + ret = WDT_COMMON_ERROR + if seconds < 0: + return ret + + try: + if self.timeout != seconds: + self.timeout = self._settimeout(seconds) + if self.armed: + self._keepalive() + else: + self._settimeout(seconds) + self._enable() + self.armed = True + ret = self.timeout + except IOError as e: + pass + + return ret + + def disarm(self): + """ + Disarm the hardware watchdog + Returns: + A boolean, True if watchdog is disarmed successfully, False if not + """ + disarmed = False + if self.is_armed(): + try: + self._disable() + self.armed = False + disarmed = True + except IOError: + pass + + return disarmed + + def is_armed(self): + """ + Retrieves the armed state of the hardware watchdog. + Returns: + A boolean, True if watchdog is armed, False if not + """ + + return self.armed + + def get_remaining_time(self): + """ + If the watchdog is armed, retrieve the number of seconds remaining on + the watchdog timer + Returns: + An integer specifying the number of seconds remaining on thei + watchdog timer. If the watchdog is not armed, returns -1. + """ + + timeleft = WDT_COMMON_ERROR + + if self.armed: + try: + timeleft = self._gettimeleft() + except IOError: + pass + + return timeleft + + def __del__(self): + """ + Close watchdog + """ + + if self.watchdog is not None : + os.close(self.watchdog) + + + diff --git a/platform/broadcom/sonic-platform-modules-quanta/ix7-bwde-32x/utils/quanta_ix7_bwde_util.py b/platform/broadcom/sonic-platform-modules-quanta/ix7-bwde-32x/utils/quanta_ix7_bwde_util.py index 952fc11a6816..a20aa33828e4 100755 --- a/platform/broadcom/sonic-platform-modules-quanta/ix7-bwde-32x/utils/quanta_ix7_bwde_util.py +++ b/platform/broadcom/sonic-platform-modules-quanta/ix7-bwde-32x/utils/quanta_ix7_bwde_util.py @@ -28,27 +28,26 @@ """ import os -import commands +import subprocess import sys, getopt import logging +import time DEBUG = False args = [] FORCE = 0 i2c_prefix = '/sys/bus/i2c/devices/' - if DEBUG == True: - print sys.argv[0] - print 'ARGV :', sys.argv[1:] - + print(sys.argv[0]) + print('ARGV :', sys.argv[1:]) def main(): global DEBUG global args global FORCE - if len(sys.argv)<2: + if len(sys.argv) < 2: show_help() options, args = getopt.getopt(sys.argv[1:], 'hdf', ['help', @@ -56,9 +55,9 @@ def main(): 'force', ]) if DEBUG == True: - print options - print args - print len(sys.argv) + print(options) + print(args) + print(len(sys.argv)) for opt, arg in options: if opt in ('-h', '--help'): @@ -72,34 +71,42 @@ def main(): logging.info('no option') for arg in args: if arg == 'install': - install() + install() elif arg == 'clean': - uninstall() + uninstall() else: show_help() - return 0 def show_help(): - print __doc__ % {'scriptName' : sys.argv[0].split("/")[-1]} + print(__doc__ % {'scriptName' : sys.argv[0].split("/")[-1]}) sys.exit(0) def show_log(txt): if DEBUG == True: - print "[IX7-BWDE-32X]"+txt + print("[IX7-BWDE-32X]"+txt) return def exec_cmd(cmd, show): - logging.info('Run :'+cmd) - status, output = commands.getstatusoutput(cmd) + logging.info('Run :' + cmd) + status, output = subprocess.getstatusoutput(cmd) show_log (cmd +"with result:" + str(status)) - show_log (" output:"+output) + show_log (" output:" + output) if status: - logging.info('Failed :'+cmd) + logging.info('Failed :' + cmd) if show: - print('Failed :'+cmd) - return status, output + print('Failed :' + cmd) + return status, output + +pca954x_bus_addr =[ +'0-0072', +'0-0077', +'5-0073', +'6-0073', +'7-0073', +'8-0073' +] instantiate =[ #Enable front-ports LED decoding @@ -118,7 +125,7 @@ def exec_cmd(cmd, show): 'lpc_ich', 'i2c-i801', 'i2c-dev', -'i2c-mux-pca954x force_deselect_on_exit=1', +'i2c-mux-pca954x', 'gpio-pca953x', 'optoe', 'qci_cpld', @@ -149,18 +156,30 @@ def system_install(): exec_cmd("depmod -a ", 1) #install drivers for i in range(0,len(drivers)): - status, output = exec_cmd("modprobe "+drivers[i], 1) - if status: - print output - if FORCE == 0: - return status - + status, output = exec_cmd("modprobe " + drivers[i], 1) + if status: + print(output) + #retry quanta_hwmon_ipmi in case it init failed due to ipmi_msghandler init uncompleted + if drivers[i] == 'quanta_hwmon_ipmi': + for _ in range(0, 3): + time.sleep(3) + ret, out = exec_cmd("modprobe quanta_hwmon_ipmi ", 1) + if ret == 0: + break + if ret and FORCE == 0: + return ret + elif FORCE == 0: + return status #reload ethernet drivers for correct order exec_cmd("rmmod ixgbe ", 1) exec_cmd("rmmod igb ", 1) exec_cmd("modprobe igb ", 1) exec_cmd("modprobe ixgbe ", 1) + # set pca954x idle_state as -2: MUX_IDLE_DISCONNECT + for i in range(0,len(pca954x_bus_addr)): + exec_cmd("echo -2 > /sys/bus/i2c/drivers/pca954x/{}/idle_state".format(pca954x_bus_addr[i]), 1) + #turn on module power exec_cmd("echo 21 > /sys/class/gpio/export ", 1) exec_cmd("echo high > /sys/class/gpio/gpio21/direction ", 1) @@ -174,23 +193,23 @@ def system_install(): exec_cmd("echo 1 >/sys/class/gpio/gpio33/value", 1) #instantiate devices - for i in range(0,len(instantiate)): + for i in range(0, len(instantiate)): status, output = exec_cmd(instantiate[i], 1) - if status: - print output - if FORCE == 0: - return status + if status: + print(output) + if FORCE == 0: + return status #QSFP for 1~32 port - for port_number in range(1,33): + for port_number in range(1, 33): bus_number = port_number + 12 os.system("echo %d >/sys/bus/i2c/devices/%d-0050/port_name" % (port_number, bus_number)) status, output = exec_cmd("pip3 install /usr/share/sonic/device/x86_64-quanta_ix7_bwde-r0/sonic_platform-1.0-py3-none-any.whl",1) if status: - print output - if FORCE == 0: - return status + print(output) + if FORCE == 0: + return status return @@ -202,29 +221,29 @@ def system_ready(): def install(): if not device_found(): - print "No device, installing...." + print("No device, installing....") status = system_install() if status: if FORCE == 0: - return status + return status else: - print " ix7-bwde driver already installed...." + print(" ix7-bwde driver already installed....") return def uninstall(): global FORCE #uninstall drivers - for i in range(len(un_drivers)-1,-1,-1): - status, output = exec_cmd("rmmod "+un_drivers[i], 1) + for i in range(len(un_drivers) - 1, -1, -1): + status, output = exec_cmd("rmmod " + un_drivers[i], 1) if status: - print output + print(output) if FORCE == 0: return status status, output = exec_cmd("pip3 uninstall sonic-platform -y ",1) if status: - print output - if FORCE == 0: - return status + print(output) + if FORCE == 0: + return status return def device_found(): diff --git a/platform/broadcom/sonic-platform-modules-quanta/ix8-56x/modules/qci_cpld_led.c b/platform/broadcom/sonic-platform-modules-quanta/ix8-56x/modules/qci_cpld_led.c index 64841e8538f6..147a2a7f8611 100644 --- a/platform/broadcom/sonic-platform-modules-quanta/ix8-56x/modules/qci_cpld_led.c +++ b/platform/broadcom/sonic-platform-modules-quanta/ix8-56x/modules/qci_cpld_led.c @@ -49,7 +49,7 @@ static struct class *cpld_class = NULL; struct cpld_data { struct i2c_client *cpld_client; - char name[8]; + char name[16]; u8 cpld_id; }; diff --git a/platform/broadcom/sonic-platform-modules-quanta/ix8-56x/modules/qci_platform_ix8.c b/platform/broadcom/sonic-platform-modules-quanta/ix8-56x/modules/qci_platform_ix8.c index 51876246e1a2..fe295b5dfebb 100644 --- a/platform/broadcom/sonic-platform-modules-quanta/ix8-56x/modules/qci_platform_ix8.c +++ b/platform/broadcom/sonic-platform-modules-quanta/ix8-56x/modules/qci_platform_ix8.c @@ -192,9 +192,9 @@ static int __init ix8_platform_init(void) } else { - g_client[0] = i2c_new_device(adapter, &ix8_i2c_devices[0]); // pca9546 - g_client[1] = i2c_new_device(adapter, &ix8_i2c_devices[1]); // pca9548 - g_client[2] = i2c_new_device(adapter, &ix8_i2c_devices[16]); // pca9546cpu + g_client[0] = i2c_new_client_device(adapter, &ix8_i2c_devices[0]); // pca9546 + g_client[1] = i2c_new_client_device(adapter, &ix8_i2c_devices[1]); // pca9548 + g_client[2] = i2c_new_client_device(adapter, &ix8_i2c_devices[16]); // pca9546cpu i2c_put_adapter(adapter); } @@ -205,7 +205,7 @@ static int __init ix8_platform_init(void) } else { - g_client[3] = i2c_new_device(adapter, &ix8_i2c_devices[17]); // CPU Board Data + g_client[3] = i2c_new_client_device(adapter, &ix8_i2c_devices[17]); // CPU Board Data i2c_put_adapter(adapter); } @@ -216,9 +216,9 @@ static int __init ix8_platform_init(void) } else { - g_client[4] = i2c_new_device(adapter, &ix8_i2c_devices[10]); // CPLD_1 - g_client[5] = i2c_new_device(adapter, &ix8_i2c_devices[18]); // CPLD_4 - g_client[6] = i2c_new_device(adapter, &ix8_i2c_devices[19]); // CPLD_6 + g_client[4] = i2c_new_client_device(adapter, &ix8_i2c_devices[10]); // CPLD_1 + g_client[5] = i2c_new_client_device(adapter, &ix8_i2c_devices[18]); // CPLD_4 + g_client[6] = i2c_new_client_device(adapter, &ix8_i2c_devices[19]); // CPLD_6 i2c_put_adapter(adapter); } @@ -229,7 +229,7 @@ static int __init ix8_platform_init(void) } else { - g_client[7] = i2c_new_device(adapter, &ix8_i2c_devices[11]); // CPLD_2 + g_client[7] = i2c_new_client_device(adapter, &ix8_i2c_devices[11]); // CPLD_2 i2c_put_adapter(adapter); } @@ -240,8 +240,8 @@ static int __init ix8_platform_init(void) } else { - g_client[8] = i2c_new_device(adapter, &ix8_i2c_devices[12]); // CPLD_3 - g_client[9] = i2c_new_device(adapter, &ix8_i2c_devices[2]); // MB_BOARDINFO_EEPROM + g_client[8] = i2c_new_client_device(adapter, &ix8_i2c_devices[12]); // CPLD_3 + g_client[9] = i2c_new_client_device(adapter, &ix8_i2c_devices[2]); // MB_BOARDINFO_EEPROM i2c_put_adapter(adapter); } @@ -252,8 +252,8 @@ static int __init ix8_platform_init(void) } else { - g_client[10] = i2c_new_device(adapter, &ix8_i2c_devices[13]); // MB Board Data - g_client[11] = i2c_new_device(adapter, &ix8_i2c_devices[14]); // QSFP:49~52 + g_client[10] = i2c_new_client_device(adapter, &ix8_i2c_devices[13]); // MB Board Data + g_client[11] = i2c_new_client_device(adapter, &ix8_i2c_devices[14]); // QSFP:49~52 i2c_put_adapter(adapter); } @@ -264,7 +264,7 @@ static int __init ix8_platform_init(void) } else { - g_client[12] = i2c_new_device(adapter, &ix8_i2c_devices[3]); // pca9548_1 SFP + g_client[12] = i2c_new_client_device(adapter, &ix8_i2c_devices[3]); // pca9548_1 SFP i2c_put_adapter(adapter); } @@ -275,7 +275,7 @@ static int __init ix8_platform_init(void) } else { - g_client[13] = i2c_new_device(adapter, &ix8_i2c_devices[4]); // pca9548_2 SFP + g_client[13] = i2c_new_client_device(adapter, &ix8_i2c_devices[4]); // pca9548_2 SFP i2c_put_adapter(adapter); } @@ -286,7 +286,7 @@ static int __init ix8_platform_init(void) } else { - g_client[14] = i2c_new_device(adapter, &ix8_i2c_devices[5]); // pca9548_3 SFP + g_client[14] = i2c_new_client_device(adapter, &ix8_i2c_devices[5]); // pca9548_3 SFP i2c_put_adapter(adapter); } @@ -297,7 +297,7 @@ static int __init ix8_platform_init(void) } else { - g_client[15] = i2c_new_device(adapter, &ix8_i2c_devices[6]); // pca9548_4 SFP + g_client[15] = i2c_new_client_device(adapter, &ix8_i2c_devices[6]); // pca9548_4 SFP i2c_put_adapter(adapter); } @@ -308,7 +308,7 @@ static int __init ix8_platform_init(void) } else { - g_client[16] = i2c_new_device(adapter, &ix8_i2c_devices[7]); // pca9548_5 SFP + g_client[16] = i2c_new_client_device(adapter, &ix8_i2c_devices[7]); // pca9548_5 SFP i2c_put_adapter(adapter); } @@ -319,7 +319,7 @@ static int __init ix8_platform_init(void) } else { - g_client[17] = i2c_new_device(adapter, &ix8_i2c_devices[8]); // pca9548_6 SFP + g_client[17] = i2c_new_client_device(adapter, &ix8_i2c_devices[8]); // pca9548_6 SFP i2c_put_adapter(adapter); } @@ -330,7 +330,7 @@ static int __init ix8_platform_init(void) } else { - g_client[18] = i2c_new_device(adapter, &ix8_i2c_devices[9]); // pca9548_7 QSFP + g_client[18] = i2c_new_client_device(adapter, &ix8_i2c_devices[9]); // pca9548_7 QSFP i2c_put_adapter(adapter); } @@ -342,7 +342,7 @@ static int __init ix8_platform_init(void) } else { - g_client_port[i - 17] = i2c_new_device(adapter, &ix8_i2c_devices[15]); + g_client_port[i - 17] = i2c_new_client_device(adapter, &ix8_i2c_devices[15]); i2c_put_adapter(adapter); } } @@ -355,7 +355,7 @@ static int __init ix8_platform_init(void) else { adapter = i2c_get_adapter_wait(i); - g_client_port[i - 17] = i2c_new_device(adapter, &ix8_i2c_devices[20]); + g_client_port[i - 17] = i2c_new_client_device(adapter, &ix8_i2c_devices[20]); i2c_put_adapter(adapter); } } diff --git a/platform/broadcom/sonic-platform-modules-quanta/ix8-56x/modules/quanta_hwmon_ipmi.c b/platform/broadcom/sonic-platform-modules-quanta/ix8-56x/modules/quanta_hwmon_ipmi.c index 5c9570c1035a..ce932d9b6ca8 100644 --- a/platform/broadcom/sonic-platform-modules-quanta/ix8-56x/modules/quanta_hwmon_ipmi.c +++ b/platform/broadcom/sonic-platform-modules-quanta/ix8-56x/modules/quanta_hwmon_ipmi.c @@ -86,6 +86,8 @@ #define IPMI_TIMEOUT (4 * HZ) #define IPMI_MAX_WAIT_QUEUE 1 +typedef struct ipmi_user *ipmi_user_t; + struct quanta_hwmon_ipmi_data { struct platform_device *ipmi_platform_dev; @@ -1090,7 +1092,7 @@ int32_t sdr_convert_sensor_reading(uint8_t idx, uint8_t val, result = (m * (int16_t)val) * decimal_point + b; break; default: - return; + return result; } pow_convert(&result, k2); @@ -1242,7 +1244,7 @@ int32_t ipmi_get_vin_type(uint8_t idx, uint8_t *retbuf) if (rv) { printk("BMC down at (%d)!!\n", __LINE__); } - else { + else { switch (returnData) { case 0x7: //LVDC @@ -1830,7 +1832,7 @@ static int32_t __init quanta_hwmon_ipmi_init(void) goto device_reg_err; } - data->ipmi_hwmon_dev = hwmon_device_register_with_groups(NULL, DRVNAME, NULL, + data->ipmi_hwmon_dev = hwmon_device_register_with_groups(&data->ipmi_platform_dev->dev, DRVNAME, NULL, NULL); err = IS_ERR(data->ipmi_hwmon_dev); if (err) @@ -1857,21 +1859,15 @@ static int32_t __init quanta_hwmon_ipmi_init(void) return 0; init_sensor_err: - if (g_sensor_data) - { - kfree(g_sensor_data); - g_sensor_data = NULL; - } + kfree(g_sensor_data); + g_sensor_data = NULL; ipmi_create_err: hwmon_device_unregister(data->ipmi_hwmon_dev); hwmon_register_err: platform_device_unregister(data->ipmi_platform_dev); device_reg_err: - if (data) - { - kfree(data); - data = NULL; - } + kfree(data); + data = NULL; alloc_err: return err; } @@ -1887,17 +1883,10 @@ static void __exit quanta_hwmon_ipmi_exit(void) platform_device_unregister(data->ipmi_platform_dev); - if (g_sensor_data) - { - kfree(g_sensor_data); - g_sensor_data = NULL; - } - - if (data) - { - kfree(data); - data = NULL; - } + kfree(g_sensor_data); + g_sensor_data = NULL; + kfree(data); + data = NULL; } module_init(quanta_hwmon_ipmi_init); diff --git a/platform/broadcom/sonic-platform-modules-quanta/ix8-56x/sonic_platform/chassis.py b/platform/broadcom/sonic-platform-modules-quanta/ix8-56x/sonic_platform/chassis.py index b959d6678048..5599f703f413 100644 --- a/platform/broadcom/sonic-platform-modules-quanta/ix8-56x/sonic_platform/chassis.py +++ b/platform/broadcom/sonic-platform-modules-quanta/ix8-56x/sonic_platform/chassis.py @@ -72,6 +72,13 @@ def __init__(self): for index in range(1, self.__num_of_ports + 1): self.__xcvr_presence[index] = self._sfp_list[index-1].get_presence() + # Initialize components + from sonic_platform.component import ComponentBIOS, ComponentBMC, ComponentCPLD, ComponentPCIE + self._component_list.append(ComponentBIOS()) + self._component_list.append(ComponentBMC()) + self._component_list.extend(ComponentCPLD.get_component_list()) + self._component_list.append(ComponentPCIE()) + ############################################## # Device methods ############################################## @@ -79,7 +86,7 @@ def __init__(self): def get_sfp(self, index): """ Retrieves sfp represented by (1-based) index - For Quanta IX8 the index in sfputil.py starts from 1, so override + For Quanta the index in sfputil.py starts from 1, so override Args: index: An integer, the index (1-based) of the sfp to retrieve. @@ -179,6 +186,18 @@ def get_system_eeprom_info(self): """ return self._eeprom.system_eeprom_info() + def get_reboot_cause(self): + """ + Retrieves the cause of the previous reboot + Returns: + A tuple (string, string) where the first element is a string + containing the cause of the previous reboot. This string must be + one of the predefined strings in this class. If the first string + is "REBOOT_CAUSE_HARDWARE_OTHER", the second string can be used + to pass a description of the reboot cause. + """ + return (ChassisBase.REBOOT_CAUSE_HARDWARE_OTHER, "Invalid Reason") + ############################################## # Other methods ############################################## @@ -215,10 +234,10 @@ def get_change_event(self, timeout=0): cur_xcvr_presence = self._sfp_list[index-1].get_presence() if cur_xcvr_presence != self.__xcvr_presence[index]: if cur_xcvr_presence is True: - xcvr_change_event_dict[str(index)] = '1' + xcvr_change_event_dict[index] = '1' self.__xcvr_presence[index] = True elif cur_xcvr_presence is False: - xcvr_change_event_dict[str(index)] = '0' + xcvr_change_event_dict[index] = '0' self.__xcvr_presence[index] = False event = True diff --git a/platform/broadcom/sonic-platform-modules-quanta/ix8-56x/sonic_platform/component.py b/platform/broadcom/sonic-platform-modules-quanta/ix8-56x/sonic_platform/component.py new file mode 100644 index 000000000000..95f275014f5b --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-quanta/ix8-56x/sonic_platform/component.py @@ -0,0 +1,203 @@ +#!/usr/bin/env python + +######################################################################## +# Quanta IX8 +# +# Name: component.py, version: 1.3 +# Module contains an implementation of SONiC Platform Base API and +# provides the Components' (e.g., BIOS, CPLD, FPGA, etc.) available in +# the platform +# +######################################################################## + +try: + import subprocess + from sonic_platform_base.component_base import ComponentBase + from collections import namedtuple +except ImportError as e: + raise ImportError(str(e) + "- required module not found") + + +class Component(ComponentBase): + def __init__(self): + ComponentBase.__init__(self) + self.name = None + self.description = None + + def get_name(self): + return self.name + + def get_description(self): + return self.description + + def install_firmware(self, image_path): + """ + Installs firmware to the component + + Args: + image_path: A string, path to firmware image + + Returns: + A boolean, True if install was successful, False if not + """ + return False + + @staticmethod + def _get_command_result(cmdline): + try: + proc = subprocess.Popen(cmdline, + stdout=subprocess.PIPE, + shell=True, stderr=subprocess.STDOUT, + universal_newlines=True) + stdout = proc.communicate()[0] + rc = proc.wait() + result = stdout.rstrip('\n') + if rc != 0: + raise RuntimeError("Failed to execute command {}, return code {}, {}".format(cmdline, rc, stdout)) + + except OSError as e: + raise RuntimeError("Failed to execute command {} due to {}".format(cmdline, repr(e))) + + return result + + +class ComponentBIOS(Component): + COMPONENT_NAME = 'BIOS' + COMPONENT_DESCRIPTION = 'BIOS - Basic Input/Output System' + + BIOS_QUERY_VERSION_COMMAND = "dmidecode -s bios-version" + + def __init__(self): + super(ComponentBIOS, self).__init__() + + self.name = self.COMPONENT_NAME + self.description = self.COMPONENT_DESCRIPTION + + def get_firmware_version(self): + """ + Retrieves the firmware version of the component + + Returns: + A string containing the firmware version of the component + """ + bios_ver = self._get_command_result(self.BIOS_QUERY_VERSION_COMMAND) + if not bios_ver: + return 'ERR' + else: + return bios_ver + + +class ComponentBMC(Component): + COMPONENT_NAME = 'BMC' + COMPONENT_DESCRIPTION = 'BMC - Board Management Controller' + BMC_QUERY_VERSION_COMMAND = "ipmitool mc info | grep 'Firmware Revision'" + + def __init__(self): + super(ComponentBMC, self).__init__() + + self.name = self.COMPONENT_NAME + self.description = self.COMPONENT_DESCRIPTION + + def get_firmware_version(self): + """ + Retrieves the firmware version of the component + + Returns: + A string containing the firmware version of the component + """ + bmc_ver = self._get_command_result(self.BMC_QUERY_VERSION_COMMAND) + if not bmc_ver: + return 'ERR' + else: + bmc_ver = bmc_ver.split(": ")[1] + return bmc_ver.strip() + + +class ComponentCPLD(Component): + Cpld = namedtuple("Cpld", ['name', 'cmd_index', 'description']) + + cplds = { + 1: Cpld("UART_CPLD", 1, "UART"), + 2: Cpld("BOOT_CPLD", 2, "Power sequence"), + 3: Cpld("FAN_CPLD", 3, "Fan"), + 4: Cpld("MB_CPLD_IO_1", 5, "Port IO-1"), + 5: Cpld("MB_CPLD_IO_2", 6, "Port IO-2"), + 6: Cpld("MB_CPLD_IO_3", 8, "Port IO-3"), + 7: Cpld("MB_CPLD_LED_1", 7, "Port LED-1"), + 8: Cpld("MB_CPLD_LED_2", 4, "Port LED-2"), + } + + def __init__(self, component_index): + super(ComponentCPLD, self).__init__() + self.index = component_index + + def get_name(self): + """ + Retrieves the name of the component + + Returns: + A string containing the name of the component + """ + self.name = self.cplds[self.index].name + + return self.name + + def get_description(self): + """ + Retrieves the description of the component + + Returns: + A string containing the description of the component + """ + self.description = self.cplds[self.index].description + + return self.description + + def get_firmware_version(self): + """ + Retrieves the firmware version of the component + + Returns: + A string containing the firmware version of the component + """ + res = self._get_command_result("ipmitool raw 0x32 0xff 0x02 {}".format(self.cplds[self.index].cmd_index)) + if not res: + return 'ERR' + else: + return res.split()[3].upper() + res.split()[2].upper() + res.split()[1].upper() + res.split()[0].upper() + + @classmethod + def get_component_list(cls): + component_list = [] + cpld_number = len(cls.cplds) + + for cpld_idx in range(1, cpld_number + 1): + component_list.append(cls(cpld_idx)) + + return component_list + + +class ComponentPCIE(Component): + COMPONENT_NAME = 'PCIe' + COMPONENT_DESCRIPTION = 'ASIC PCIe Firmware' + PCIE_QUERY_VERSION_COMMAND = "bcmcmd 'pciephy fw version' | grep 'FW version'" + + def __init__(self): + super(ComponentPCIE, self).__init__() + + self.name = self.COMPONENT_NAME + self.description = self.COMPONENT_DESCRIPTION + + def get_firmware_version(self): + """ + Retrieves the firmware version of the component + + Returns: + A string containing the firmware version of the component + """ + version = self._get_command_result(self.PCIE_QUERY_VERSION_COMMAND) + if not version: + return 'ERR' + else: + version = version.split(": ")[1] + return version.strip() diff --git a/platform/broadcom/sonic-platform-modules-quanta/ix8-56x/sonic_platform/fan_drawer.py b/platform/broadcom/sonic-platform-modules-quanta/ix8-56x/sonic_platform/fan_drawer.py index 75e954576a28..3d5f767477ee 100644 --- a/platform/broadcom/sonic-platform-modules-quanta/ix8-56x/sonic_platform/fan_drawer.py +++ b/platform/broadcom/sonic-platform-modules-quanta/ix8-56x/sonic_platform/fan_drawer.py @@ -28,7 +28,7 @@ def get_name(self): Returns: string: The name of the device """ - return 'Fan {}'.format(self._index) + return 'Fantray{}'.format(self._index) def get_presence(self): """ diff --git a/platform/broadcom/sonic-platform-modules-quanta/ix8-56x/sonic_platform/psu.py b/platform/broadcom/sonic-platform-modules-quanta/ix8-56x/sonic_platform/psu.py index 60e0f29740db..e03960251043 100644 --- a/platform/broadcom/sonic-platform-modules-quanta/ix8-56x/sonic_platform/psu.py +++ b/platform/broadcom/sonic-platform-modules-quanta/ix8-56x/sonic_platform/psu.py @@ -212,10 +212,10 @@ def get_current(self): def get_input_voltage(self): """ - Retrieves current PSU voltage output + Retrieves current PSU voltage input Returns: - A float number, the output voltage in volts, + A float number, the input voltage in volts, e.g. 12.1 """ voltage_in = 0.0 diff --git a/platform/broadcom/sonic-platform-modules-quanta/ix8-56x/sonic_platform/sfp.py b/platform/broadcom/sonic-platform-modules-quanta/ix8-56x/sonic_platform/sfp.py index a1a3d92f8c2d..f7a9a105a5c7 100644 --- a/platform/broadcom/sonic-platform-modules-quanta/ix8-56x/sonic_platform/sfp.py +++ b/platform/broadcom/sonic-platform-modules-quanta/ix8-56x/sonic_platform/sfp.py @@ -10,13 +10,10 @@ import os import time -#import subprocess -#import sonic_device_util from ctypes import create_string_buffer try: from sonic_platform_base.sfp_base import SfpBase -# from sonic_platform_base.sonic_eeprom import eeprom_dts from sonic_platform_base.sonic_sfp.sff8472 import sff8472InterfaceId from sonic_platform_base.sonic_sfp.sff8472 import sff8472Dom from sonic_platform_base.sonic_sfp.sff8436 import sff8436InterfaceId @@ -175,7 +172,6 @@ def __init__(self, sfp_index, sfp_type): # Init index self.index = sfp_index self.port_num = self.index - #self.dom_supported = False self.sfp_type = sfp_type # Init eeprom path eeprom_path = '/sys/bus/i2c/devices/i2c-{0}/{0}-0050/eeprom' @@ -284,15 +280,6 @@ def _convert_string_to_num(self, value_str): else: return 'N/A' - def __read_txt_file(self, file_path): - try: - with open(file_path, 'r') as fd: - data = fd.read() - return data.strip() - except IOError: - pass - return "" - def __is_host(self): return os.system(self.HOST_CHK_CMD) == 0 @@ -355,26 +342,6 @@ def __read_eeprom_specific_bytes(self, offset, num_bytes): return eeprom_raw - def __convert_string_to_num(self, value_str): - if "-inf" in value_str: - return 'N/A' - elif "Unknown" in value_str: - return 'N/A' - elif 'dBm' in value_str: - t_str = value_str.rstrip('dBm') - return float(t_str) - elif 'mA' in value_str: - t_str = value_str.rstrip('mA') - return float(t_str) - elif 'C' in value_str: - t_str = value_str.rstrip('C') - return float(t_str) - elif 'Volts' in value_str: - t_str = value_str.rstrip('Volts') - return float(t_str) - else: - return 'N/A' - def _dom_capability_detect(self): if not self.get_presence(): self.dom_supported = False @@ -533,9 +500,7 @@ def get_transceiver_info(self): else: if not self.get_presence(): return transceiver_info_dict - elif i == max_retry-1: - pass - else: + elif i < max_retry-1: time.sleep(0.5) if sfp_interface_bulk_raw is None: @@ -590,7 +555,8 @@ def get_transceiver_info(self): ['data']['Extended Identifier']['value'] transceiver_info_dict['ext_rateselect_compliance'] = sfp_interface_bulk_data \ ['data']['RateIdentifier']['value'] - transceiver_info_dict['type_abbrv_name'] = 'N/A' + transceiver_info_dict['type_abbrv_name'] = sfp_interface_bulk_data \ + ['data']['type_abbrv_name']['value'] if self.sfp_type == QSFP_TYPE: for key in qsfp_cable_length_tup: if key in sfp_interface_bulk_data['data']: @@ -860,7 +826,7 @@ def get_transceiver_threshold_info(self): transceiver_dom_threshold_dict['txbiaslowwarning'] = channel_threshold_data['TxBiasLowWarning']['value'] for key in transceiver_dom_threshold_dict: - transceiver_dom_threshold_dict[key] = self.__convert_string_to_num(transceiver_dom_threshold_dict[key]) + transceiver_dom_threshold_dict[key] = self._convert_string_to_num(transceiver_dom_threshold_dict[key]) return transceiver_dom_threshold_dict @@ -908,7 +874,7 @@ def get_transceiver_threshold_info(self): transceiver_dom_threshold_info_dict['rxpowerlowwarning'] = dom_module_threshold_data['data']['RXPowerLowWarning']['value'] for key in transceiver_dom_threshold_info_dict: - transceiver_dom_threshold_info_dict[key] = self.__convert_string_to_num(transceiver_dom_threshold_info_dict[key]) + transceiver_dom_threshold_info_dict[key] = self._convert_string_to_num(transceiver_dom_threshold_info_dict[key]) return transceiver_dom_threshold_info_dict @@ -1453,7 +1419,7 @@ def tx_disable(self, tx_disable): sysfsfile_eeprom = open( sysfs_sfp_i2c_client_eeprom_path, mode="r+b", buffering=0) buffer = create_string_buffer(1) - buffer[0] = chr(tx_disable_ctl) + buffer[0] = tx_disable_ctl # Write to eeprom sysfsfile_eeprom.seek(offset + SFP_STATUS_CONTROL_OFFSET) sysfsfile_eeprom.write(buffer[0]) @@ -1506,7 +1472,7 @@ def tx_disable_channel(self, channel, disable): else: tx_disable_ctl = channel_state & (~channel) buffer = create_string_buffer(1) - buffer[0] = chr(tx_disable_ctl) + buffer[0] = tx_disable_ctl # Write to eeprom sysfsfile_eeprom = open( self.port_to_eeprom_mapping[self.port_num], "r+b") @@ -1594,7 +1560,7 @@ def set_power_override(self, power_override, power_set): power_set_bit |= 1 << 1 buffer = create_string_buffer(1) - buffer[0] = chr(power_override_bit | power_set_bit) + buffer[0] = power_override_bit | power_set_bit # Write to eeprom sysfsfile_eeprom = open(self.port_to_eeprom_mapping[self.port_num], "r+b") sysfsfile_eeprom.seek(QSFP_POWEROVERRIDE_OFFSET) diff --git a/platform/broadcom/sonic-platform-modules-quanta/ix8-56x/sonic_platform/thermal.py b/platform/broadcom/sonic-platform-modules-quanta/ix8-56x/sonic_platform/thermal.py index f2ba18754759..770a2dfd5be5 100644 --- a/platform/broadcom/sonic-platform-modules-quanta/ix8-56x/sonic_platform/thermal.py +++ b/platform/broadcom/sonic-platform-modules-quanta/ix8-56x/sonic_platform/thermal.py @@ -1,7 +1,7 @@ #!/usr/bin/env python ############################################################################# -# Quanta +# Quanta IX8 # # Module contains an implementation of SONiC Platform Base API and # provides the Thermal information diff --git a/platform/broadcom/sonic-platform-modules-quanta/ix8-56x/sonic_platform/watchdog.py b/platform/broadcom/sonic-platform-modules-quanta/ix8-56x/sonic_platform/watchdog.py index 282f356f4e73..0e63d9368cb0 100644 --- a/platform/broadcom/sonic-platform-modules-quanta/ix8-56x/sonic_platform/watchdog.py +++ b/platform/broadcom/sonic-platform-modules-quanta/ix8-56x/sonic_platform/watchdog.py @@ -48,12 +48,16 @@ WDT_SYSFS_PATH = "/sys/class/watchdog/" DEFAULT_TIMEOUT=180 +watchdog=0 class Watchdog(WatchdogBase): def __init__(self): self.watchdog, self.wdt_main_dev_name = self._get_wdt() + if self.wdt_main_dev_name is None: + raise Exception("Watchdog device is not instantiated") + self.status_path = "/sys/class/watchdog/%s/status" % self.wdt_main_dev_name self.state_path = "/sys/class/watchdog/%s/state" % self.wdt_main_dev_name self.timeout_path = "/sys/class/watchdog/%s/timeout" % self.wdt_main_dev_name @@ -74,14 +78,16 @@ def _get_wdt(self): """ Retrieves watchdog device """ + global watchdog wdt_main_dev_list = [dev for dev in os.listdir( "/dev/") if dev.startswith("watchdog") and self._is_wd_main(dev)] if not wdt_main_dev_list: - return None + return (None, None) wdt_main_dev_name = wdt_main_dev_list[0] watchdog_device_path = "/dev/{}".format(wdt_main_dev_name) - self.watchdog = os.open(watchdog_device_path, os.O_RDWR) - return self.watchdog, wdt_main_dev_name + if not watchdog: + watchdog = os.open(watchdog_device_path, os.O_RDWR) + return watchdog, wdt_main_dev_name def _read_file(self, file_path): """ @@ -228,7 +234,8 @@ def __del__(self): Close watchdog """ - os.close(self.watchdog) + if self.watchdog is not None : + os.close(self.watchdog) diff --git a/platform/broadcom/sonic-platform-modules-quanta/ix8-56x/utils/quanta_ix8_util.py b/platform/broadcom/sonic-platform-modules-quanta/ix8-56x/utils/quanta_ix8_util.py index 19dc24e370bd..833bfe27c420 100755 --- a/platform/broadcom/sonic-platform-modules-quanta/ix8-56x/utils/quanta_ix8_util.py +++ b/platform/broadcom/sonic-platform-modules-quanta/ix8-56x/utils/quanta_ix8_util.py @@ -28,7 +28,7 @@ """ import os -import commands +import subprocess import sys, getopt import logging import time @@ -38,18 +38,16 @@ FORCE = 0 i2c_prefix = '/sys/bus/i2c/devices/' - if DEBUG == True: - print sys.argv[0] - print 'ARGV :', sys.argv[1:] - + print(sys.argv[0]) + print('ARGV :', sys.argv[1:]) def main(): global DEBUG global args global FORCE - if len(sys.argv)<2: + if len(sys.argv) < 2: show_help() options, args = getopt.getopt(sys.argv[1:], 'hdf', ['help', @@ -57,9 +55,9 @@ def main(): 'force', ]) if DEBUG == True: - print options - print args - print len(sys.argv) + print(options) + print(args) + print(len(sys.argv)) for opt, arg in options: if opt in ('-h', '--help'): @@ -73,34 +71,46 @@ def main(): logging.info('no option') for arg in args: if arg == 'install': - install() + install() elif arg == 'clean': - uninstall() + uninstall() else: show_help() - return 0 def show_help(): - print __doc__ % {'scriptName' : sys.argv[0].split("/")[-1]} + print(__doc__ % {'scriptName' : sys.argv[0].split("/")[-1]}) sys.exit(0) def show_log(txt): if DEBUG == True: - print "[IX8-56X]"+txt + print("[IX8-56X]" + txt) return def exec_cmd(cmd, show): - logging.info('Run :'+cmd) - status, output = commands.getstatusoutput(cmd) + logging.info('Run :' + cmd) + status, output = subprocess.getstatusoutput(cmd) show_log (cmd +"with result:" + str(status)) - show_log (" output:"+output) + show_log (" output:" + output) if status: - logging.info('Failed :'+cmd) + logging.info('Failed :' + cmd) if show: - print('Failed :'+cmd) - return status, output + print('Failed :' + cmd) + return status, output + +pca954x_bus_addr =[ +'0-0071', +'0-0072', +'0-0077', +'5-0073', +'6-0073', +'7-0073', +'8-0073', +'9-0073', +'10-0073', +'11-0073' +] instantiate =[ #export pca9698 for qsfp present @@ -207,7 +217,7 @@ def exec_cmd(cmd, show): 'lpc_ich', 'i2c-i801', 'i2c-dev', -'i2c-mux-pca954x force_deselect_on_exit=1', +'i2c-mux-pca954x', 'gpio-pca953x', 'optoe', 'qci_cpld_sfp28', @@ -243,11 +253,24 @@ def system_install(): exec_cmd("depmod -a ", 1) #install drivers for i in range(0,len(drivers)): - status, output = exec_cmd("modprobe "+drivers[i], 1) - if status: - print output - if FORCE == 0: - return status + status, output = exec_cmd("modprobe " + drivers[i], 1) + if status: + print(output) + #retry quanta_hwmon_ipmi in case it init failed due to ipmi_msghandler init uncompleted + if drivers[i] == 'quanta_hwmon_ipmi': + for _ in range(0, 3): + time.sleep(3) + ret, out = exec_cmd("modprobe quanta_hwmon_ipmi ", 1) + if ret == 0: + break + if ret and FORCE == 0: + return ret + elif FORCE == 0: + return status + + # set pca954x idle_state as -2: MUX_IDLE_DISCONNECT + for i in range(0,len(pca954x_bus_addr)): + exec_cmd("echo -2 > /sys/bus/i2c/drivers/pca954x/{}/idle_state".format(pca954x_bus_addr[i]), 1) #turn on module power exec_cmd("echo 21 > /sys/class/gpio/export ", 1) @@ -268,23 +291,23 @@ def system_install(): exec_cmd("echo 1 >/sys/class/gpio/gpio73/value", 1) #instantiate devices - for i in range(0,len(instantiate)): + for i in range(0, len(instantiate)): status, output = exec_cmd(instantiate[i], 1) - if status: - print output - if FORCE == 0: - return status + if status: + print(output) + if FORCE == 0: + return status #QSFP for 1~56 port - for port_number in range(1,57): + for port_number in range(1, 57): bus_number = port_number + 16 os.system("echo %d >/sys/bus/i2c/devices/%d-0050/port_name" % (port_number, bus_number)) status, output = exec_cmd("pip3 install /usr/share/sonic/device/x86_64-quanta_ix8_rglbmc-r0/sonic_platform-1.0-py3-none-any.whl",1) if status: - print output - if FORCE == 0: - return status + print(output) + if FORCE == 0: + return status #Enable front-ports LED decoding exec_cmd('echo 1 > /sys/class/cpld-led/CPLDLED-1/led_decode', 1) @@ -299,29 +322,31 @@ def system_ready(): def install(): if not device_found(): - print "No device, installing...." + print("No device, installing....") status = system_install() if status: if FORCE == 0: - return status + return status else: - print " ix8 driver already installed...." + print(" ix8 driver already installed....") return def uninstall(): global FORCE #uninstall drivers - for i in range(len(un_drivers)-1,-1,-1): - status, output = exec_cmd("rmmod "+un_drivers[i], 1) + for i in range(len(un_drivers) - 1, -1, -1): + status, output = exec_cmd("rmmod " + un_drivers[i], 1) if status: - print output - if FORCE == 0: - return status + print(output) + if FORCE == 0: + return status + status, output = exec_cmd("pip3 uninstall sonic-platform -y ",1) if status: - print output - if FORCE == 0: - return status + print(output) + if FORCE == 0: + return status + return def device_found(): diff --git a/platform/broadcom/sonic-platform-modules-quanta/ix8a-bwde-56x/modules/qci_cpld_led.c b/platform/broadcom/sonic-platform-modules-quanta/ix8a-bwde-56x/modules/qci_cpld_led.c index 9be8920f51e9..1f594e7bec6f 100644 --- a/platform/broadcom/sonic-platform-modules-quanta/ix8a-bwde-56x/modules/qci_cpld_led.c +++ b/platform/broadcom/sonic-platform-modules-quanta/ix8a-bwde-56x/modules/qci_cpld_led.c @@ -49,7 +49,7 @@ static struct class *cpld_class = NULL; struct cpld_data { struct i2c_client *cpld_client; - char name[8]; + char name[16]; u8 cpld_id; }; diff --git a/platform/broadcom/sonic-platform-modules-quanta/ix8a-bwde-56x/modules/qci_platform_ix8a_bwde.c b/platform/broadcom/sonic-platform-modules-quanta/ix8a-bwde-56x/modules/qci_platform_ix8a_bwde.c index e5f6a6529d40..2b82674e74d1 100644 --- a/platform/broadcom/sonic-platform-modules-quanta/ix8a-bwde-56x/modules/qci_platform_ix8a_bwde.c +++ b/platform/broadcom/sonic-platform-modules-quanta/ix8a-bwde-56x/modules/qci_platform_ix8a_bwde.c @@ -170,9 +170,9 @@ static int __init ix8a_bwde_platform_init(void) } else { - g_client[0] = i2c_new_device(adapter, &ix8a_bwde_i2c_devices[0]); // pca9546_1 - g_client[1] = i2c_new_device(adapter, &ix8a_bwde_i2c_devices[1]); // pca9548_1 - g_client[2] = i2c_new_device(adapter, &ix8a_bwde_i2c_devices[16]); // CPU Linking Board at CPU's I2C Bus // + g_client[0] = i2c_new_client_device(adapter, &ix8a_bwde_i2c_devices[0]); // pca9546_1 + g_client[1] = i2c_new_client_device(adapter, &ix8a_bwde_i2c_devices[1]); // pca9548_1 + g_client[2] = i2c_new_client_device(adapter, &ix8a_bwde_i2c_devices[16]); // CPU Linking Board at CPU's I2C Bus // i2c_put_adapter(adapter); } @@ -183,9 +183,9 @@ static int __init ix8a_bwde_platform_init(void) } else { - g_client[3] = i2c_new_device(adapter, &ix8a_bwde_i2c_devices[11]); // CPLD_1 - g_client[4] = i2c_new_device(adapter, &ix8a_bwde_i2c_devices[17]); // CPLD_4 // - g_client[5] = i2c_new_device(adapter, &ix8a_bwde_i2c_devices[18]); // CPLD_6 // + g_client[3] = i2c_new_client_device(adapter, &ix8a_bwde_i2c_devices[11]); // CPLD_1 + g_client[4] = i2c_new_client_device(adapter, &ix8a_bwde_i2c_devices[17]); // CPLD_4 // + g_client[5] = i2c_new_client_device(adapter, &ix8a_bwde_i2c_devices[18]); // CPLD_6 // i2c_put_adapter(adapter); } @@ -196,7 +196,7 @@ static int __init ix8a_bwde_platform_init(void) } else { - g_client[6] = i2c_new_device(adapter, &ix8a_bwde_i2c_devices[12]); // CPLD_2 + g_client[6] = i2c_new_client_device(adapter, &ix8a_bwde_i2c_devices[12]); // CPLD_2 i2c_put_adapter(adapter); } @@ -207,7 +207,7 @@ static int __init ix8a_bwde_platform_init(void) } else { - g_client[7] = i2c_new_device(adapter, &ix8a_bwde_i2c_devices[13]); // CPLD_3 + g_client[7] = i2c_new_client_device(adapter, &ix8a_bwde_i2c_devices[13]); // CPLD_3 i2c_put_adapter(adapter); } @@ -218,8 +218,8 @@ static int __init ix8a_bwde_platform_init(void) } else { - g_client[8] = i2c_new_device(adapter, &ix8a_bwde_i2c_devices[2]); // pca9539_1 - g_client[9] = i2c_new_device(adapter, &ix8a_bwde_i2c_devices[14]); // pca9698_QSFP + g_client[8] = i2c_new_client_device(adapter, &ix8a_bwde_i2c_devices[2]); // pca9539_1 + g_client[9] = i2c_new_client_device(adapter, &ix8a_bwde_i2c_devices[14]); // pca9698_QSFP i2c_put_adapter(adapter); } @@ -230,7 +230,7 @@ static int __init ix8a_bwde_platform_init(void) } else { - g_client[10] = i2c_new_device(adapter, &ix8a_bwde_i2c_devices[4]); // pca9548_1 SFP + g_client[10] = i2c_new_client_device(adapter, &ix8a_bwde_i2c_devices[4]); // pca9548_1 SFP i2c_put_adapter(adapter); } @@ -241,7 +241,7 @@ static int __init ix8a_bwde_platform_init(void) } else { - g_client[11] = i2c_new_device(adapter, &ix8a_bwde_i2c_devices[5]); // pca9548_2 SFP + g_client[11] = i2c_new_client_device(adapter, &ix8a_bwde_i2c_devices[5]); // pca9548_2 SFP i2c_put_adapter(adapter); } @@ -252,7 +252,7 @@ static int __init ix8a_bwde_platform_init(void) } else { - g_client[12] = i2c_new_device(adapter, &ix8a_bwde_i2c_devices[6]); // pca9548_3 SFP + g_client[12] = i2c_new_client_device(adapter, &ix8a_bwde_i2c_devices[6]); // pca9548_3 SFP i2c_put_adapter(adapter); } @@ -263,7 +263,7 @@ static int __init ix8a_bwde_platform_init(void) } else { - g_client[13] = i2c_new_device(adapter, &ix8a_bwde_i2c_devices[7]); // pca9548_4 SFP + g_client[13] = i2c_new_client_device(adapter, &ix8a_bwde_i2c_devices[7]); // pca9548_4 SFP i2c_put_adapter(adapter); } @@ -274,7 +274,7 @@ static int __init ix8a_bwde_platform_init(void) } else { - g_client[14] = i2c_new_device(adapter, &ix8a_bwde_i2c_devices[8]); // pca9548_5 SFP + g_client[14] = i2c_new_client_device(adapter, &ix8a_bwde_i2c_devices[8]); // pca9548_5 SFP i2c_put_adapter(adapter); } @@ -285,7 +285,7 @@ static int __init ix8a_bwde_platform_init(void) } else { - g_client[15] = i2c_new_device(adapter, &ix8a_bwde_i2c_devices[9]); // pca9548_6 SFP + g_client[15] = i2c_new_client_device(adapter, &ix8a_bwde_i2c_devices[9]); // pca9548_6 SFP i2c_put_adapter(adapter); } @@ -296,7 +296,7 @@ static int __init ix8a_bwde_platform_init(void) } else { - g_client[16] = i2c_new_device(adapter, &ix8a_bwde_i2c_devices[10]); // pca9548_7 SFP + g_client[16] = i2c_new_client_device(adapter, &ix8a_bwde_i2c_devices[10]); // pca9548_7 SFP i2c_put_adapter(adapter); } @@ -307,7 +307,7 @@ static int __init ix8a_bwde_platform_init(void) } else { - g_client[17] = i2c_new_device(adapter, &ix8a_bwde_i2c_devices[3]); // eeprom + g_client[17] = i2c_new_client_device(adapter, &ix8a_bwde_i2c_devices[3]); // eeprom i2c_put_adapter(adapter); } @@ -320,9 +320,9 @@ static int __init ix8a_bwde_platform_init(void) else { if (i < 61) // SFP28 1~48 EEPROM - g_client_port[i - 13] = i2c_new_device(adapter, &ix8a_bwde_i2c_devices[19]); + g_client_port[i - 13] = i2c_new_client_device(adapter, &ix8a_bwde_i2c_devices[19]); else // QSFP 49~56 EEPROM - g_client_port[i - 13] = i2c_new_device(adapter, &ix8a_bwde_i2c_devices[15]); + g_client_port[i - 13] = i2c_new_client_device(adapter, &ix8a_bwde_i2c_devices[15]); i2c_put_adapter(adapter); } } diff --git a/platform/broadcom/sonic-platform-modules-quanta/ix8a-bwde-56x/modules/quanta_hwmon_ipmi.c b/platform/broadcom/sonic-platform-modules-quanta/ix8a-bwde-56x/modules/quanta_hwmon_ipmi.c index 65517e5d915a..d927647b51f6 100644 --- a/platform/broadcom/sonic-platform-modules-quanta/ix8a-bwde-56x/modules/quanta_hwmon_ipmi.c +++ b/platform/broadcom/sonic-platform-modules-quanta/ix8a-bwde-56x/modules/quanta_hwmon_ipmi.c @@ -28,7 +28,7 @@ #define __TO_R_EXP(bacc) (int32_t)(tos32(((BSWAP_32(bacc) & 0xf0) >> 4), 4)) #define __TO_B_EXP(bacc) (int32_t)(tos32((BSWAP_32(bacc) & 0xf), 4)) -#define SENSOR_ATTR_MAX 17 +#define SENSOR_ATTR_MAX 19 #define SENSOR_ATTR_NAME_LENGTH 20 #define SENSOR_GET_CAP_LABEL 0x001 @@ -44,7 +44,7 @@ #define SENSOR_GET_CAP_UNR 0x100 #define SENSOR_GET_CAP_MODEL 0x200 -#define SENSOR_GET_CAP_SN 0x400 +#define SENSOR_GET_CAP_SN 0x400 #define SENSOR_GET_CAP_PWM 0x800 #define SENSOR_GET_CAP_CONMODE 0x1000 @@ -52,7 +52,9 @@ #define SENSOR_GET_CAP_FAN_PRESENT 0x4000 #define SENSOR_GET_CAP_PSU_PRESENT 0x8000 -#define SENSOR_GET_CAP_MFRID 0x10000 +#define SENSOR_GET_CAP_MFRID 0x10000 +#define SENSOR_GET_CAP_VIN_TYPE 0x20000 +#define SENSOR_GET_CAP_POUT_MAX 0x40000 #define SDR_SENSOR_TYPE_TEMP 0x01 #define SDR_SENSOR_TYPE_VOLT 0x02 @@ -84,6 +86,8 @@ #define IPMI_TIMEOUT (4 * HZ) #define IPMI_MAX_WAIT_QUEUE 1 +typedef struct ipmi_user *ipmi_user_t; + struct quanta_hwmon_ipmi_data { struct platform_device *ipmi_platform_dev; @@ -1007,6 +1011,8 @@ void ipmi_sdr_set_sensor_factor(uint8_t idx, g_sensor_data[idx].capability |= SENSOR_GET_CAP_SN; g_sensor_data[idx].capability |= SENSOR_GET_CAP_MFRID; g_sensor_data[idx].capability |= SENSOR_GET_CAP_PSU_PRESENT; + g_sensor_data[idx].capability |= SENSOR_GET_CAP_VIN_TYPE; + g_sensor_data[idx].capability |= SENSOR_GET_CAP_POUT_MAX; } sprintf(g_sensor_data[idx].attrinfo.attr_type_str, "power"); } @@ -1086,7 +1092,7 @@ int32_t sdr_convert_sensor_reading(uint8_t idx, uint8_t val, result = (m * (int16_t)val) * decimal_point + b; break; default: - return; + return result; } pow_convert(&result, k2); @@ -1218,6 +1224,82 @@ int32_t ipmi_get_psu_info(uint8_t idx, uint8_t cmd, uint8_t *retbuf) return sprintf(retbuf, "N/A\n"); } +int32_t ipmi_get_vin_type(uint8_t idx, uint8_t *retbuf) +{ + uint8_t psu_slot = 0; + int32_t rv = 0; + + uint8_t returnData = 0; + uint8_t msg_data[] = { 0x06, 0x52, 0x0f, 0x00, 0x01, 0xd8 }; // read line status + + if (strstr(g_sensor_data[idx].sensor_idstring, "PSU1")) psu_slot = 1; + else psu_slot = 2; + + msg_data[3] = (psu_slot == 1) ? 0xb0 : 0xb2; + if (ipmi_check_psu_present(psu_slot)) { + mutex_lock(&ipmi_lock); + rv = ipmi_send_system_cmd(msg_data, sizeof(msg_data), &returnData, 1); + mutex_unlock(&ipmi_lock); + + if (rv) { + printk("BMC down at (%d)!!\n", __LINE__); + } + else { + switch (returnData) + { + case 0x7: //LVDC + case 0x3: //HVDC + return sprintf(retbuf, "DC\n"); + default: + return sprintf(retbuf, "AC\n"); + } + } + } + else { + //printk("Error ! cannot detect PSU%d\n", psu_slot); + } + + return sprintf(retbuf, "N/A\n"); +} + +int32_t ipmi_get_pout_max(uint8_t idx, uint8_t *retbuf) +{ + uint8_t psu_slot = 0; + int32_t rv = 0, pout_max = 0; + + uint8_t returnData[2] = { 0 }; + uint8_t msg_data[] = { 0x06, 0x52, 0x0f, 0x00, 0x02, 0xa7 }; + + if (strstr(g_sensor_data[idx].sensor_idstring, "PSU1")) psu_slot = 1; + else psu_slot = 2; + + msg_data[3] = (psu_slot == 1) ? 0xb0 : 0xb2; + if (ipmi_check_psu_present(psu_slot)) { + mutex_lock(&ipmi_lock); + rv = ipmi_send_system_cmd(msg_data, sizeof(msg_data), returnData, 1); + mutex_unlock(&ipmi_lock); + + if (rv) { + printk("BMC down at (%d)!!\n", __LINE__); + } + else { + /* MFR_POUT_MAX has 2 data format: Direct and Linear Data (see PMbus spec). + Query command is needed to tell the data format, but since we have not use PSU + whose output power is over 0x07ff (2047), just check the first 5 bits*/ + if ((returnData[1] & 0xf8) == 0) // Direct + pout_max = (returnData[1] << 8) | returnData[0]; + else // Linear Data + pout_max = (((returnData[1] & 0x07) << 8) | returnData[0]) << ((returnData[1] & 0xf8) >> 3); + return sprintf(retbuf, "%d\n", pout_max); + } + } + else { + //printk("Error ! cannot detect PSU%d\n", psu_slot); + } + + return sprintf(retbuf, "N/A\n"); +} + void ipmi_fan_control(uint8_t cmd_data1, uint8_t cmd_data2, uint8_t *retbuf) { int32_t rv = 0; @@ -1356,6 +1438,18 @@ static ssize_t show_mfrid(struct device *dev, struct device_attribute *devattr, return ipmi_get_psu_info(attr->index + DEBUGUSE_SHIFT, 0x99, buf); } +static ssize_t show_vin_type(struct device *dev, struct device_attribute *devattr, char *buf) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); + return ipmi_get_vin_type(attr->index + DEBUGUSE_SHIFT, buf); +} + +static ssize_t show_pout_max(struct device *dev, struct device_attribute *devattr, char *buf) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); + return ipmi_get_pout_max(attr->index + DEBUGUSE_SHIFT, buf); +} + static ssize_t show_pwm(struct device *dev, struct device_attribute *devattr, char *buf) { @@ -1432,7 +1526,6 @@ static ssize_t show_fanpresent(struct device *dev, uint8_t msg_data[] = { 0x36, 0xB9, 0x4C, 0x1C, 0x00, 0x02 }; /*netfn = 0x36; cmd = 0xB9; */ struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); - struct kernel_ipmi_msg msg; fan_idx = (g_sensor_data[attr->index].sensor_idstring[8] - '0') - 1; @@ -1465,7 +1558,8 @@ static ssize_t(*const attr_show_func_ptr[SENSOR_ATTR_MAX])(struct device *dev, , show_unc, show_ucr, show_unr , show_model, show_sn, show_pwm , show_controlmode, show_direction, show_fanpresent - , show_psupresent, show_mfrid + , show_psupresent, show_mfrid, show_vin_type + , show_pout_max }; static ssize_t(*const attr_store_func_ptr[SENSOR_ATTR_MAX])(struct device *dev, @@ -1476,7 +1570,8 @@ static ssize_t(*const attr_store_func_ptr[SENSOR_ATTR_MAX])(struct device *dev, , NULL, NULL, NULL , NULL, NULL, store_pwm , store_controlmode, NULL, NULL - , NULL, NULL + , NULL, NULL, NULL + , NULL }; static const char *const sensor_attrnames[SENSOR_ATTR_MAX] = @@ -1486,7 +1581,8 @@ static const char *const sensor_attrnames[SENSOR_ATTR_MAX] = , "%s%d_ncrit", "%s%d_crit", "%s%d_max" , "%s%d_model", "%s%d_sn", "%s%d_pwm" , "%s%d_controlmode", "%s%d_direction", "%s%d_present" - , "%s%d_present", "%s%d_mfrid" + , "%s%d_present", "%s%d_mfrid", "%s%d_vin_type" + , "%s%d_pout_max" }; static int32_t create_sensor_attrs(int32_t attr_no) @@ -1735,7 +1831,7 @@ static int32_t __init quanta_hwmon_ipmi_init(void) goto device_reg_err; } - data->ipmi_hwmon_dev = hwmon_device_register_with_groups(NULL, DRVNAME, NULL, + data->ipmi_hwmon_dev = hwmon_device_register_with_groups(&data->ipmi_platform_dev->dev, DRVNAME, NULL, NULL); err = IS_ERR(data->ipmi_hwmon_dev); if (err) @@ -1762,21 +1858,15 @@ static int32_t __init quanta_hwmon_ipmi_init(void) return 0; init_sensor_err: - if (g_sensor_data) - { - kfree(g_sensor_data); - g_sensor_data = NULL; - } + kfree(g_sensor_data); + g_sensor_data = NULL; ipmi_create_err: hwmon_device_unregister(data->ipmi_hwmon_dev); hwmon_register_err: platform_device_unregister(data->ipmi_platform_dev); device_reg_err: - if (data) - { - kfree(data); - data = NULL; - } + kfree(data); + data = NULL; alloc_err: return err; } @@ -1792,23 +1882,16 @@ static void __exit quanta_hwmon_ipmi_exit(void) platform_device_unregister(data->ipmi_platform_dev); - if (g_sensor_data) - { - kfree(g_sensor_data); - g_sensor_data = NULL; - } - - if (data) - { - kfree(data); - data = NULL; - } + kfree(g_sensor_data); + g_sensor_data = NULL; + kfree(data); + data = NULL; } module_init(quanta_hwmon_ipmi_init); module_exit(quanta_hwmon_ipmi_exit); MODULE_AUTHOR("Charcar~~Charcar~Charlie li li"); -MODULE_VERSION("2.0"); +MODULE_VERSION("2.1"); MODULE_DESCRIPTION("Quanta BMC hardware monitor driver"); MODULE_LICENSE("GPL"); diff --git a/platform/broadcom/sonic-platform-modules-quanta/ix8a-bwde-56x/sonic_platform/chassis.py b/platform/broadcom/sonic-platform-modules-quanta/ix8a-bwde-56x/sonic_platform/chassis.py index c765f3734473..44528964c584 100644 --- a/platform/broadcom/sonic-platform-modules-quanta/ix8a-bwde-56x/sonic_platform/chassis.py +++ b/platform/broadcom/sonic-platform-modules-quanta/ix8a-bwde-56x/sonic_platform/chassis.py @@ -72,6 +72,13 @@ def __init__(self): for index in range(1, self.__num_of_ports + 1): self.__xcvr_presence[index] = self._sfp_list[index-1].get_presence() + # Initialize components + from sonic_platform.component import ComponentBIOS, ComponentBMC, ComponentCPLD, ComponentPCIE + self._component_list.append(ComponentBIOS()) + self._component_list.append(ComponentBMC()) + self._component_list.extend(ComponentCPLD.get_component_list()) + self._component_list.append(ComponentPCIE()) + ############################################## # Device methods ############################################## @@ -79,7 +86,7 @@ def __init__(self): def get_sfp(self, index): """ Retrieves sfp represented by (1-based) index - For Quanta IX8A the index in sfputil.py starts from 1, so override + For Quanta the index in sfputil.py starts from 1, so override Args: index: An integer, the index (1-based) of the sfp to retrieve. @@ -179,6 +186,18 @@ def get_system_eeprom_info(self): """ return self._eeprom.system_eeprom_info() + def get_reboot_cause(self): + """ + Retrieves the cause of the previous reboot + Returns: + A tuple (string, string) where the first element is a string + containing the cause of the previous reboot. This string must be + one of the predefined strings in this class. If the first string + is "REBOOT_CAUSE_HARDWARE_OTHER", the second string can be used + to pass a description of the reboot cause. + """ + return (ChassisBase.REBOOT_CAUSE_HARDWARE_OTHER, "Invalid Reason") + ############################################## # Other methods ############################################## @@ -215,10 +234,10 @@ def get_change_event(self, timeout=0): cur_xcvr_presence = self._sfp_list[index-1].get_presence() if cur_xcvr_presence != self.__xcvr_presence[index]: if cur_xcvr_presence is True: - xcvr_change_event_dict[str(index)] = '1' + xcvr_change_event_dict[index] = '1' self.__xcvr_presence[index] = True elif cur_xcvr_presence is False: - xcvr_change_event_dict[str(index)] = '0' + xcvr_change_event_dict[index] = '0' self.__xcvr_presence[index] = False event = True diff --git a/platform/broadcom/sonic-platform-modules-quanta/ix8a-bwde-56x/sonic_platform/component.py b/platform/broadcom/sonic-platform-modules-quanta/ix8a-bwde-56x/sonic_platform/component.py new file mode 100644 index 000000000000..f697f9bbe53b --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-quanta/ix8a-bwde-56x/sonic_platform/component.py @@ -0,0 +1,204 @@ +#!/usr/bin/env python + +######################################################################## +# Quanta IX8A_BDE +# +# Name: component.py, version: 1.3 +# Module contains an implementation of SONiC Platform Base API and +# provides the Components' (e.g., BIOS, CPLD, FPGA, etc.) available in +# the platform +# +######################################################################## + +try: + import subprocess + from sonic_platform_base.component_base import ComponentBase + from collections import namedtuple +except ImportError as e: + raise ImportError(str(e) + "- required module not found") + + +class Component(ComponentBase): + def __init__(self): + ComponentBase.__init__(self) + self.name = None + self.description = None + + def get_name(self): + return self.name + + def get_description(self): + return self.description + + def install_firmware(self, image_path): + """ + Installs firmware to the component + + Args: + image_path: A string, path to firmware image + + Returns: + A boolean, True if install was successful, False if not + """ + return False + + @staticmethod + def _get_command_result(cmdline): + try: + proc = subprocess.Popen(cmdline, + stdout=subprocess.PIPE, + shell=True, stderr=subprocess.STDOUT, + universal_newlines=True) + stdout = proc.communicate()[0] + rc = proc.wait() + result = stdout.rstrip('\n') + if rc != 0: + raise RuntimeError("Failed to execute command {}, return code {}, {}".format(cmdline, rc, stdout)) + + except OSError as e: + raise RuntimeError("Failed to execute command {} due to {}".format(cmdline, repr(e))) + + return result + + +class ComponentBIOS(Component): + COMPONENT_NAME = 'BIOS' + COMPONENT_DESCRIPTION = 'BIOS - Basic Input/Output System' + + BIOS_QUERY_VERSION_COMMAND = "dmidecode -s bios-version" + + def __init__(self): + super(ComponentBIOS, self).__init__() + + self.name = self.COMPONENT_NAME + self.description = self.COMPONENT_DESCRIPTION + + def get_firmware_version(self): + """ + Retrieves the firmware version of the component + + Returns: + A string containing the firmware version of the component + """ + bios_ver = self._get_command_result(self.BIOS_QUERY_VERSION_COMMAND) + if not bios_ver: + return 'ERR' + else: + return bios_ver + + +class ComponentBMC(Component): + COMPONENT_NAME = 'BMC' + COMPONENT_DESCRIPTION = 'BMC - Board Management Controller' + BMC_QUERY_VERSION_COMMAND = "ipmitool mc info | grep 'Firmware Revision'" + + def __init__(self): + super(ComponentBMC, self).__init__() + + self.name = self.COMPONENT_NAME + self.description = self.COMPONENT_DESCRIPTION + + def get_firmware_version(self): + """ + Retrieves the firmware version of the component + + Returns: + A string containing the firmware version of the component + """ + bmc_ver = self._get_command_result(self.BMC_QUERY_VERSION_COMMAND) + if not bmc_ver: + return 'ERR' + else: + bmc_ver = bmc_ver.split(": ")[1] + return bmc_ver.strip() + + +class ComponentCPLD(Component): + Cpld = namedtuple("Cpld", ['name', 'cmd_index', 'description']) + + cplds = { + 1: Cpld("BOOT_CPLD", 1, "Power sequence"), + 2: Cpld("FAN_CPLD", 2, "Fan"), + 3: Cpld("MB_CPLD_IO_1", 7, "Port IO-1"), + 4: Cpld("MB_CPLD_IO_2", 5, "Port IO-2"), + 5: Cpld("MB_CPLD_IO_3", 4, "Port IO-3"), + 6: Cpld("MB_CPLD_LED_1", 6, "Port LED-1"), + 7: Cpld("MB_CPLD_LED_2", 3, "Port LED-2"), + } + + def __init__(self, component_index): + super(ComponentCPLD, self).__init__() + self.index = component_index + + def get_name(self): + """ + Retrieves the name of the component + + Returns: + A string containing the name of the component + """ + self.name = self.cplds[self.index].name + + return self.name + + def get_description(self): + """ + Retrieves the description of the component + + Returns: + A string containing the description of the component + """ + self.description = self.cplds[self.index].description + + return self.description + + def get_firmware_version(self): + """ + Retrieves the firmware version of the component + + Returns: + A string containing the firmware version of the component + """ + self._get_command_result("ipmitool raw 0x30 0xe0 0xd0 0x01 0x01") + res = self._get_command_result("ipmitool raw 0x32 0xff 0x02 {}".format(self.cplds[self.index].cmd_index)) + self._get_command_result("ipmitool raw 0x30 0xe0 0xd0 0x01 0x00") + if not res: + return 'ERR' + else: + return res.split()[3].upper() + res.split()[2].upper() + res.split()[1].upper() + res.split()[0].upper() + + @classmethod + def get_component_list(cls): + component_list = [] + cpld_number = len(cls.cplds) + + for cpld_idx in range(1, cpld_number + 1): + component_list.append(cls(cpld_idx)) + + return component_list + + +class ComponentPCIE(Component): + COMPONENT_NAME = 'PCIe' + COMPONENT_DESCRIPTION = 'ASIC PCIe Firmware' + PCIE_QUERY_VERSION_COMMAND = "bcmcmd 'pciephy fw version' | grep 'FW version'" + + def __init__(self): + super(ComponentPCIE, self).__init__() + + self.name = self.COMPONENT_NAME + self.description = self.COMPONENT_DESCRIPTION + + def get_firmware_version(self): + """ + Retrieves the firmware version of the component + + Returns: + A string containing the firmware version of the component + """ + version = self._get_command_result(self.PCIE_QUERY_VERSION_COMMAND) + if not version: + return 'ERR' + else: + version = version.split(": ")[1] + return version.strip() diff --git a/platform/broadcom/sonic-platform-modules-quanta/ix8a-bwde-56x/sonic_platform/fan.py b/platform/broadcom/sonic-platform-modules-quanta/ix8a-bwde-56x/sonic_platform/fan.py index 8aae9147c444..934891f3702d 100644 --- a/platform/broadcom/sonic-platform-modules-quanta/ix8a-bwde-56x/sonic_platform/fan.py +++ b/platform/broadcom/sonic-platform-modules-quanta/ix8a-bwde-56x/sonic_platform/fan.py @@ -1,7 +1,7 @@ #!/usr/bin/env python ############################################################################# -# Quanta IX8A-BWDE +# Quanta IX8A_BDE # # Module contains an implementation of SONiC Platform Base API and # provides the FAN information @@ -11,6 +11,7 @@ try: import logging import os + import glob from sonic_platform_base.fan_base import FanBase except ImportError as e: raise ImportError(str(e) + "- required module not found") @@ -19,9 +20,7 @@ ############### # Global ############### -HWMON_DIR = "/sys/class/hwmon/hwmon2/" -FAN_INDEX_START = 18 -NUM_FANTRAYS = 6 +HWMON_IPMI_DIR = "/sys/devices/platform/quanta_hwmon_ipmi/hwmon/hwmon*/" FANS_PERTRAY = 2 class Fan(FanBase): @@ -30,30 +29,46 @@ class Fan(FanBase): def __init__(self, index, is_psu_fan=False): self.is_psu_fan = is_psu_fan self.fan_index = index - self.psu_fan_index_mapping = { - 1:120, - 2:132, - } - self.psu_index_mapping = { - 1:114, - 2:126, - } + hwmon_dir=glob.glob(HWMON_IPMI_DIR)[0] + if self.is_psu_fan: - self.fan_presence_attr = "power{}_present".format(self.psu_index_mapping[index]) - self.fan_pwm_attr = "fan{}_pwm".format(self.psu_fan_index_mapping[index]) - self.fan_rpm_attr = "fan{}_input".format(self.psu_fan_index_mapping[index]) - self.fan_direction_attr = "fan{}_direction".format(self.psu_fan_index_mapping[index]) + power_out_prefix = self.__get_hwmon_attr_prefix(hwmon_dir, "PSU{}_POWER_OUT".format(self.fan_index), 'power') + fan_prefix = self.__get_hwmon_attr_prefix(hwmon_dir, "PSU{}_Fan".format(self.fan_index), 'fan') + self.fan_presence_attr = power_out_prefix + 'present' + self.fan_pwm_attr = fan_prefix + 'pwm' + self.fan_rpm_attr = fan_prefix + 'input' + self.fan_direction_attr = fan_prefix + 'direction' else: - self.fan_presence_attr = "fan{}_present".format(FAN_INDEX_START+(index-1)) - self.fan_pwm_attr = "fan{}_pwm".format(FAN_INDEX_START+(index-1)) - self.fan_rpm_attr = "fan{}_input".format(FAN_INDEX_START+(index-1)) - self.fan_direction_attr = "fan{}_direction".format(FAN_INDEX_START+(index-1)) + fantray_index = (self.fan_index-1)//FANS_PERTRAY+1 + fan_index_intray = self.fan_index - ((fantray_index-1)*FANS_PERTRAY) + fan_prefix = self.__get_hwmon_attr_prefix(hwmon_dir, "Fan_SYS_{}_{}".format(fantray_index, fan_index_intray), 'fan') + self.fan_presence_attr = fan_prefix + 'present' + self.fan_pwm_attr = fan_prefix + 'pwm' + self.fan_rpm_attr = fan_prefix + 'input' + self.fan_direction_attr = fan_prefix + 'direction' ####################### # private function ####################### + def __get_hwmon_attr_prefix(self, dir, label, type): + + retval = 'ERR' + if not os.path.isdir(dir): + return retval + + try: + for filename in os.listdir(dir): + if filename[-5:] == 'label' and type in filename: + file_path = os.path.join(dir, filename) + if os.path.isfile(file_path) and label == self.__get_attr_value(file_path): + return file_path[0:-5] + except Exception as error: + logging.error("Error when getting {} label path: {}".format(label, error)) + + return retval + def __get_attr_value(self, attr_path): retval = 'ERR' @@ -64,7 +79,7 @@ def __get_attr_value(self, attr_path): with open(attr_path, 'r') as fd: retval = fd.read() except Exception as error: - logging.error("Unable to open " + attr_path + " file !") + logging.error("Unable to open {} file: {}".format(attr_path, error)) retval = retval.rstrip(' \t\n\r') return retval @@ -95,8 +110,7 @@ def get_presence(self): Returns: bool: True if device is present, False if not """ - attr_path = HWMON_DIR + self.fan_presence_attr - attr_rv = self.__get_attr_value(attr_path) + attr_rv = self.__get_attr_value(self.fan_presence_attr) if (attr_rv != 'ERR'): if (attr_rv == '1'): return True @@ -113,8 +127,7 @@ def get_status(self): A boolean value, True if device is operating properly, False if not """ if self.get_presence(): - attr_path = HWMON_DIR + self.fan_rpm_attr - attr_rv = self.__get_attr_value(attr_path) + attr_rv = self.__get_attr_value(self.fan_rpm_attr) if (attr_rv != 'ERR' and attr_rv != '0.0'): return True @@ -135,8 +148,7 @@ def get_direction(self): A string, either FAN_DIRECTION_INTAKE or FAN_DIRECTION_EXHAUST depending on fan direction """ - attr_path = HWMON_DIR + self.fan_direction_attr - attr_rv = self.__get_attr_value(attr_path) + attr_rv = self.__get_attr_value(self.fan_direction_attr) if attr_rv == '2': return self.FAN_DIRECTION_INTAKE @@ -152,8 +164,7 @@ def get_speed(self): to 100 (full speed) """ if self.get_presence(): - attr_path = HWMON_DIR + self.fan_pwm_attr - attr_rv = self.__get_attr_value(attr_path) + attr_rv = self.__get_attr_value(self.fan_pwm_attr) if (attr_rv != 'ERR'): return int(float(attr_rv)) @@ -169,8 +180,7 @@ def get_speed_rpm(self): Returns: An integer, speed of the fan in RPM """ - attr_path = HWMON_DIR + self.fan_rpm_attr - attr_rv = self.__get_attr_value(attr_path) + attr_rv = self.__get_attr_value(self.fan_rpm_attr) if (attr_rv != 'ERR'): return int(float(attr_rv)) @@ -185,8 +195,7 @@ def get_target_speed(self): An integer, the percentage of full fan speed, in the range 0 (off) to 100 (full speed) """ - attr_path = HWMON_DIR + self.fan_pwm_attr - attr_rv = self.__get_attr_value(attr_path) + attr_rv = self.__get_attr_value(self.fan_pwm_attr) if (attr_rv != 'ERR'): return int(float(attr_rv)) diff --git a/platform/broadcom/sonic-platform-modules-quanta/ix8a-bwde-56x/sonic_platform/fan_drawer.py b/platform/broadcom/sonic-platform-modules-quanta/ix8a-bwde-56x/sonic_platform/fan_drawer.py index 75e954576a28..3d5f767477ee 100644 --- a/platform/broadcom/sonic-platform-modules-quanta/ix8a-bwde-56x/sonic_platform/fan_drawer.py +++ b/platform/broadcom/sonic-platform-modules-quanta/ix8a-bwde-56x/sonic_platform/fan_drawer.py @@ -28,7 +28,7 @@ def get_name(self): Returns: string: The name of the device """ - return 'Fan {}'.format(self._index) + return 'Fantray{}'.format(self._index) def get_presence(self): """ diff --git a/platform/broadcom/sonic-platform-modules-quanta/ix8a-bwde-56x/sonic_platform/psu.py b/platform/broadcom/sonic-platform-modules-quanta/ix8a-bwde-56x/sonic_platform/psu.py index bd3f4ce8089e..6188c95c7692 100644 --- a/platform/broadcom/sonic-platform-modules-quanta/ix8a-bwde-56x/sonic_platform/psu.py +++ b/platform/broadcom/sonic-platform-modules-quanta/ix8a-bwde-56x/sonic_platform/psu.py @@ -8,57 +8,61 @@ try: import logging import os + import glob from sonic_platform_base.psu_base import PsuBase from sonic_platform.fan import Fan except ImportError as e: raise ImportError(str(e) + "- required module not found") -HWMON_DIR = "/sys/class/hwmon/hwmon2/" +HWMON_IPMI_DIR = "/sys/devices/platform/quanta_hwmon_ipmi/hwmon/hwmon*/" class Psu(PsuBase): def __init__(self, index): PsuBase.__init__(self) fan = Fan(index, True) self._fan_list.append(fan) + self.index = index + hwmon_dir=glob.glob(HWMON_IPMI_DIR)[0] + + current_in_prefix = self.__get_hwmon_attr_prefix(hwmon_dir, "PSU{}_CURRENT_IN".format(self.index), 'curr') + current_out_prefix = self.__get_hwmon_attr_prefix(hwmon_dir, "PSU{}_CURRENT_OUT".format(self.index), 'curr') + power_in_prefix = self.__get_hwmon_attr_prefix(hwmon_dir, "PSU{}_POWER_IN".format(self.index), 'power') + power_out_prefix = self.__get_hwmon_attr_prefix(hwmon_dir, "PSU{}_POWER_OUT".format(self.index), 'power') + voltage_in_prefix = self.__get_hwmon_attr_prefix(hwmon_dir, "PSU{}_VOLTAGE_IN".format(self.index), 'in') + voltage_out_prefix = self.__get_hwmon_attr_prefix(hwmon_dir, "PSU{}_VOLTAGE_OUT".format(self.index), 'in') + temp1_prefix = self.__get_hwmon_attr_prefix(hwmon_dir, "PSU{}_TEMP1".format(self.index), 'temp') + + self.psu_current_in_attr = current_in_prefix + 'input' + self.psu_current_out_attr = current_out_prefix + 'input' + self.psu_power_in_attr = power_in_prefix + 'input' + self.psu_power_out_attr = power_out_prefix + 'input' + self.psu_voltage_in_attr = voltage_in_prefix + 'input' + self.psu_voltage_out_attr = voltage_out_prefix + 'input' + self.psu_status_attr = current_out_prefix + 'input' + self.psu_presence_attr = power_out_prefix + 'present' + self.psu_serial_attr = power_out_prefix + 'sn' + self.psu_model_attr = power_out_prefix + 'model' + self.psu_mfr_id_attr = power_out_prefix + 'mfrid' + self.psu_capacity_attr = power_out_prefix + 'pout_max' + self.psu_type_attr = power_out_prefix + 'vin_type' + self.psu_temp_attr = temp1_prefix + 'input' + + def __get_hwmon_attr_prefix(self, dir, label, type): - self.psu_index_mapping = { - 1:114, - 2:126, - } - self.psu_powerin_index_mapping = { - 1:119, - 2:131, - } - self.psu_currentout_index_mapping = { - 1:130, - 2:115, - } - self.psu_currentin_index_mapping = { - 1:130, - 2:115, - } - self.psu_voltageout_index_mapping = { - 1:129, - 2:124, - } - self.psu_voltagein_index_mapping = { - 1:125, - 2:128, - } - self.index = index - self.psu_presence_attr = "power{}_present".format(self.psu_index_mapping[self.index]) - self.psu_status_attr = "curr{}_input".format(self.psu_currentout_index_mapping[self.index]) - self.psu_power_in_attr = "power{}_input".format(self.psu_powerin_index_mapping[self.index]) - self.psu_power_out_attr = "power{}_input".format(self.psu_index_mapping[self.index]) - self.psu_voltage_out_attr = "in{}_input".format(self.psu_voltageout_index_mapping[self.index]) - self.psu_current_out_attr = "curr{}_input".format(self.psu_currentout_index_mapping[self.index]) - self.psu_voltage_in_attr = "in{}_input".format(self.psu_voltagein_index_mapping[self.index]) - self.psu_current_in_attr = "curr{}_input".format(self.psu_currentin_index_mapping[self.index]) - self.psu_serial_attr = "power{}_sn".format(self.psu_index_mapping[self.index]) - self.psu_model_attr = "power{}_model".format(self.psu_index_mapping[self.index]) - self.psu_mfr_id_attr = "power{}_mfrid".format(self.psu_index_mapping[self.index]) - self.psu_capacity_attr = "power{}_pout_max".format(self.psu_index_mapping[self.index]) - self.psu_type_attr = "power{}_vin_type".format(self.psu_index_mapping[self.index]) + retval = 'ERR' + if not os.path.isdir(dir): + return retval + + try: + for filename in os.listdir(dir): + if filename[-5:] == 'label' and type in filename: + file_path = os.path.join(dir, filename) + if os.path.isfile(file_path) and label == self.__get_attr_value(file_path): + return file_path[0:-5] + except Exception as error: + logging.error("Error when getting {} label path: {}".format(label, error)) + + return retval def __get_attr_value(self, attr_path): @@ -70,10 +74,9 @@ def __get_attr_value(self, attr_path): with open(attr_path, 'r') as fd: retval = fd.read() except Exception as error: - logging.error("Unable to open " + attr_path + " file !") + logging.error("Unable to open {} file: {}".format(attr_path, error)) retval = retval.rstrip(' \t\n\r') - fd.close() return retval ############################################## @@ -97,10 +100,9 @@ def get_presence(self): bool: True if device is present, False if not """ presence = False - attr_path = HWMON_DIR+self.psu_presence_attr attr_normal = '1' - attr_rv = self.__get_attr_value(attr_path) + attr_rv = self.__get_attr_value(self.psu_presence_attr) if (attr_rv != 'ERR'): if (attr_rv == attr_normal): presence = True @@ -115,8 +117,7 @@ def get_model(self): string: Model/part number of device """ model = "N/A" - attr_path = HWMON_DIR+self.psu_model_attr - attr_rv = self.__get_attr_value(attr_path) + attr_rv = self.__get_attr_value(self.psu_model_attr) if (attr_rv != 'ERR'): model = attr_rv @@ -130,8 +131,7 @@ def get_mfr_id(self): string: Manufacturer's id of device """ mfr_id = "N/A" - attr_path = HWMON_DIR+self.psu_mfr_id_attr - attr_rv = self.__get_attr_value(attr_path) + attr_rv = self.__get_attr_value(self.psu_mfr_id_attr) if (attr_rv != 'ERR'): mfr_id = attr_rv @@ -145,9 +145,7 @@ def get_serial(self): string: Serial number of device """ serial = "N/A" - attr_path = HWMON_DIR+self.psu_serial_attr - - attr_rv = self.__get_attr_value(attr_path) + attr_rv = self.__get_attr_value(self.psu_serial_attr) if (attr_rv != 'ERR'): serial = attr_rv @@ -161,9 +159,7 @@ def get_status(self): A boolean value, True if device is operating properly, False if not """ status = False - attr_path = HWMON_DIR+self.psu_status_attr - - attr_rv = self.__get_attr_value(attr_path) + attr_rv = self.__get_attr_value(self.psu_status_attr) if (attr_rv != 'ERR'): attr_rv, dummy = attr_rv.split('.', 1) if (int(attr_rv) != 0): @@ -184,9 +180,7 @@ def get_voltage(self): e.g. 12.1 """ voltage_out = 0.0 - attr_path = HWMON_DIR+self.psu_voltage_out_attr - - attr_rv = self.__get_attr_value(attr_path) + attr_rv = self.__get_attr_value(self.psu_voltage_out_attr) if (attr_rv != 'ERR'): attr_rv, dummy = attr_rv.split('.', 1) voltage_out = float(attr_rv) / 1000 @@ -201,9 +195,7 @@ def get_current(self): A float number, the electric current in amperes, e.g 15.4 """ current_out = 0.0 - attr_path = HWMON_DIR+self.psu_current_out_attr - - attr_rv = self.__get_attr_value(attr_path) + attr_rv = self.__get_attr_value(self.psu_current_out_attr) if (attr_rv != 'ERR'): attr_rv, dummy = attr_rv.split('.', 1) current_out = float(attr_rv) / 1000 @@ -212,16 +204,14 @@ def get_current(self): def get_input_voltage(self): """ - Retrieves current PSU voltage output + Retrieves current PSU voltage input Returns: - A float number, the output voltage in volts, + A float number, the input voltage in volts, e.g. 12.1 """ voltage_in = 0.0 - attr_path = HWMON_DIR+self.psu_voltage_in_attr - - attr_rv = self.__get_attr_value(attr_path) + attr_rv = self.__get_attr_value(self.psu_voltage_in_attr) if (attr_rv != 'ERR'): attr_rv, dummy = attr_rv.split('.', 1) voltage_in = float(attr_rv) / 1000 @@ -236,9 +226,7 @@ def get_input_current(self): A float number, the electric current in amperes, e.g 15.4 """ current_in = 0.0 - attr_path = HWMON_DIR+self.psu_current_in_attr - - attr_rv = self.__get_attr_value(attr_path) + attr_rv = self.__get_attr_value(self.psu_current_in_attr) if (attr_rv != 'ERR'): attr_rv, dummy = attr_rv.split('.', 1) current_in = float(attr_rv) / 1000 @@ -253,9 +241,7 @@ def get_power(self): A float number, the power in watts, e.g. 302.6 """ power_out = 0.0 - attr_path = HWMON_DIR+self.psu_power_out_attr - - attr_rv = self.__get_attr_value(attr_path) + attr_rv = self.__get_attr_value(self.psu_power_out_attr) if (attr_rv != 'ERR'): attr_rv, dummy = attr_rv.split('.', 1) power_out = float(attr_rv) / 1000 @@ -292,8 +278,7 @@ def get_type(self): A string, the type of PSU (AC/DC) """ type = "AC" - attr_path = HWMON_DIR+self.psu_type_attr - attr_rv = self.__get_attr_value(attr_path) + attr_rv = self.__get_attr_value(self.psu_type_attr) if (attr_rv != 'ERR'): type = attr_rv @@ -307,8 +292,7 @@ def get_capacity(self): An integer, the capacity of PSU """ capacity = 0 - attr_path = HWMON_DIR+self.psu_capacity_attr - attr_rv = self.__get_attr_value(attr_path) + attr_rv = self.__get_attr_value(self.psu_capacity_attr) if (attr_rv != 'ERR'): try: capacity = int(attr_rv) @@ -317,3 +301,19 @@ def get_capacity(self): return capacity + def get_temperature(self): + """ + Retrieves current temperature reading from PSU + Returns: + A float number of current temperature in Celsius up to nearest thousandth + of one degree Celsius, e.g. 30.125 + """ + + tout = 0.0 + attr_rv = self.__get_attr_value(self.psu_temp_attr) + if (attr_rv != 'ERR'): + tout = float(attr_rv) + + # tout is in milli degree celcius + return float(tout/1000.0) + diff --git a/platform/broadcom/sonic-platform-modules-quanta/ix8a-bwde-56x/sonic_platform/sfp.py b/platform/broadcom/sonic-platform-modules-quanta/ix8a-bwde-56x/sonic_platform/sfp.py index bd7692be168b..abbebb03434a 100644 --- a/platform/broadcom/sonic-platform-modules-quanta/ix8a-bwde-56x/sonic_platform/sfp.py +++ b/platform/broadcom/sonic-platform-modules-quanta/ix8a-bwde-56x/sonic_platform/sfp.py @@ -10,13 +10,10 @@ import os import time -#import subprocess -#import sonic_device_util from ctypes import create_string_buffer try: from sonic_platform_base.sfp_base import SfpBase -# from sonic_platform_base.sonic_eeprom import eeprom_dts from sonic_platform_base.sonic_sfp.sff8472 import sff8472InterfaceId from sonic_platform_base.sonic_sfp.sff8472 import sff8472Dom from sonic_platform_base.sonic_sfp.sff8436 import sff8436InterfaceId @@ -175,7 +172,6 @@ def __init__(self, sfp_index, sfp_type): # Init index self.index = sfp_index self.port_num = self.index - #self.dom_supported = False self.sfp_type = sfp_type # Init eeprom path eeprom_path = '/sys/bus/i2c/devices/i2c-{0}/{0}-0050/eeprom' @@ -284,15 +280,6 @@ def _convert_string_to_num(self, value_str): else: return 'N/A' - def __read_txt_file(self, file_path): - try: - with open(file_path, 'r') as fd: - data = fd.read() - return data.strip() - except IOError: - pass - return "" - def __is_host(self): return os.system(self.HOST_CHK_CMD) == 0 @@ -355,26 +342,6 @@ def __read_eeprom_specific_bytes(self, offset, num_bytes): return eeprom_raw - def __convert_string_to_num(self, value_str): - if "-inf" in value_str: - return 'N/A' - elif "Unknown" in value_str: - return 'N/A' - elif 'dBm' in value_str: - t_str = value_str.rstrip('dBm') - return float(t_str) - elif 'mA' in value_str: - t_str = value_str.rstrip('mA') - return float(t_str) - elif 'C' in value_str: - t_str = value_str.rstrip('C') - return float(t_str) - elif 'Volts' in value_str: - t_str = value_str.rstrip('Volts') - return float(t_str) - else: - return 'N/A' - def _dom_capability_detect(self): if not self.get_presence(): self.dom_supported = False @@ -533,9 +500,7 @@ def get_transceiver_info(self): else: if not self.get_presence(): return transceiver_info_dict - elif i == max_retry-1: - pass - else: + elif i < max_retry-1: time.sleep(0.5) if sfp_interface_bulk_raw is None: @@ -590,7 +555,8 @@ def get_transceiver_info(self): ['data']['Extended Identifier']['value'] transceiver_info_dict['ext_rateselect_compliance'] = sfp_interface_bulk_data \ ['data']['RateIdentifier']['value'] - transceiver_info_dict['type_abbrv_name'] = 'N/A' + transceiver_info_dict['type_abbrv_name'] = sfp_interface_bulk_data \ + ['data']['type_abbrv_name']['value'] if self.sfp_type == QSFP_TYPE: for key in qsfp_cable_length_tup: if key in sfp_interface_bulk_data['data']: @@ -860,7 +826,7 @@ def get_transceiver_threshold_info(self): transceiver_dom_threshold_dict['txbiaslowwarning'] = channel_threshold_data['TxBiasLowWarning']['value'] for key in transceiver_dom_threshold_dict: - transceiver_dom_threshold_dict[key] = self.__convert_string_to_num(transceiver_dom_threshold_dict[key]) + transceiver_dom_threshold_dict[key] = self._convert_string_to_num(transceiver_dom_threshold_dict[key]) return transceiver_dom_threshold_dict @@ -908,7 +874,7 @@ def get_transceiver_threshold_info(self): transceiver_dom_threshold_info_dict['rxpowerlowwarning'] = dom_module_threshold_data['data']['RXPowerLowWarning']['value'] for key in transceiver_dom_threshold_info_dict: - transceiver_dom_threshold_info_dict[key] = self.__convert_string_to_num(transceiver_dom_threshold_info_dict[key]) + transceiver_dom_threshold_info_dict[key] = self._convert_string_to_num(transceiver_dom_threshold_info_dict[key]) return transceiver_dom_threshold_info_dict @@ -1461,7 +1427,7 @@ def tx_disable(self, tx_disable): sysfsfile_eeprom = open( sysfs_sfp_i2c_client_eeprom_path, mode="r+b", buffering=0) buffer = create_string_buffer(1) - buffer[0] = chr(tx_disable_ctl) + buffer[0] = tx_disable_ctl # Write to eeprom sysfsfile_eeprom.seek(offset + SFP_STATUS_CONTROL_OFFSET) sysfsfile_eeprom.write(buffer[0]) @@ -1514,7 +1480,7 @@ def tx_disable_channel(self, channel, disable): else: tx_disable_ctl = channel_state & (~channel) buffer = create_string_buffer(1) - buffer[0] = chr(tx_disable_ctl) + buffer[0] = tx_disable_ctl # Write to eeprom sysfsfile_eeprom = open( self.port_to_eeprom_mapping[self.port_num], "r+b") @@ -1602,7 +1568,7 @@ def set_power_override(self, power_override, power_set): power_set_bit |= 1 << 1 buffer = create_string_buffer(1) - buffer[0] = chr(power_override_bit | power_set_bit) + buffer[0] = power_override_bit | power_set_bit # Write to eeprom sysfsfile_eeprom = open(self.port_to_eeprom_mapping[self.port_num], "r+b") sysfsfile_eeprom.seek(QSFP_POWEROVERRIDE_OFFSET) diff --git a/platform/broadcom/sonic-platform-modules-quanta/ix8a-bwde-56x/sonic_platform/thermal.py b/platform/broadcom/sonic-platform-modules-quanta/ix8a-bwde-56x/sonic_platform/thermal.py index 1e07cb0e3efd..32da974f891d 100644 --- a/platform/broadcom/sonic-platform-modules-quanta/ix8a-bwde-56x/sonic_platform/thermal.py +++ b/platform/broadcom/sonic-platform-modules-quanta/ix8a-bwde-56x/sonic_platform/thermal.py @@ -1,7 +1,7 @@ #!/usr/bin/env python ############################################################################# -# Quanta +# Quanta IX8A_BDE # # Module contains an implementation of SONiC Platform Base API and # provides the Thermal information @@ -10,43 +10,44 @@ import logging import os +import glob try: from sonic_platform_base.thermal_base import ThermalBase except ImportError as e: raise ImportError(str(e) + "- required module not found") -HWMON_DIR = "/sys/class/hwmon/hwmon2/" +HWMON_IPMI_DIR = "/sys/devices/platform/quanta_hwmon_ipmi/hwmon/hwmon*/" thermal_index_mapping = { - 1:53, - 2:54, - 3:55, - 4:56, - 5:57, - 6:58, - 7:59, - 8:60, - 9:61, - 10:62, - 11:63, - 12:64, - 13:86, - 14:87, - 15:88, - 16:89, - 17:90, - 18:91, - 19:92, - 20:93, - 21:94, - 22:109, - 23:116, - 24:117, - 25:121, - 26:122, - 27:123, - 28:127 + 1:'PSU1_TEMP1', + 2:'PSU1_TEMP2', + 3:'PSU1_TEMP3', + 4:'PSU2_TEMP1', + 5:'PSU2_TEMP2', + 6:'PSU2_TEMP3', + 7:'QMACTemp_0', + 8:'QMACTemp_1', + 9:'QMACTemp_2', + 10:'QMACTemp_3', + 11:'QMACTemp_4', + 12:'QMACTemp_5', + 13:'QMACTemp_6', + 14:'QMACTemp_7', + 15:'QMACTemp_8', + 16:'QMACTemp_9', + 17:'Temp_1V05_PCH_VR', + 18:'Temp_Ambient_1', + 19:'Temp_Ambient_2', + 20:'Temp_Ambient_3', + 21:'Temp_Ambient_4', + 22:'Temp_Ambient_5', + 23:'Temp_Ambient_6', + 24:'Temp_CPU', + 25:'Temp_DDRAB_VR', + 26:'Temp_SOC_DIMMA0', + 27:'Temp_VCCGBE_VR', + 28:'Temp_VCCIN_VR' } @@ -55,12 +56,32 @@ class Thermal(ThermalBase): """Platform-specific Thermal class""" def __init__(self, thermal_index): - self.index = thermal_index - self.temp_attr = "temp{}_input".format(thermal_index_mapping[self.index]) - self.high_th_attr = "temp{}_ncrit".format(thermal_index_mapping[self.index]) - self.high_crit_th_attr = "temp{}_crit".format(thermal_index_mapping[self.index]) - self.name_attr = "temp{}_label".format(thermal_index_mapping[self.index]) + self.index = thermal_index + hwmon_dir=glob.glob(HWMON_IPMI_DIR)[0] + thermal_prefix = self.__get_hwmon_attr_prefix(hwmon_dir, thermal_index_mapping[self.index], 'temp') + self.temp_attr = "{}input".format(thermal_prefix) + self.high_th_attr = "{}ncrit".format(thermal_prefix) + self.high_crit_th_attr = "{}crit".format(thermal_prefix) + self.low_th_attr = "{}lncrit".format(thermal_prefix) + self.low_crit_th_attr = "{}lcrit".format(thermal_prefix) + self.name_attr = "{}label".format(thermal_prefix) + + def __get_hwmon_attr_prefix(self, dir, label, type): + retval = 'ERR' + if not os.path.isdir(dir): + return retval + + try: + for filename in os.listdir(dir): + if filename[-5:] == 'label' and type in filename: + file_path = os.path.join(dir, filename) + if os.path.isfile(file_path) and label == self.__get_attr_value(file_path): + return file_path[0:-5] + except Exception as error: + logging.error("Error when getting {} label path: {}".format(label, error)) + + return retval def __get_attr_value(self, attr_path): @@ -72,7 +93,7 @@ def __get_attr_value(self, attr_path): with open(attr_path, 'r') as fd: retval = fd.read() except Exception as error: - logging.error("Unable to open " + attr_path + " file !") + logging.error("Unable to open {} file: {}".format(attr_path, error)) retval = retval.rstrip(' \t\n\r') return retval @@ -84,8 +105,7 @@ def get_name(self): Returns: string: The name of the device """ - attr_path = HWMON_DIR + self.name_attr - attr_rv = self.__get_attr_value(attr_path) + attr_rv = self.__get_attr_value(self.name_attr) if (attr_rv != 'ERR'): return attr_rv @@ -99,8 +119,7 @@ def get_presence(self): Returns: bool: True if device is present, False if not """ - attr_path = HWMON_DIR + self.name_attr - attr_rv = self.__get_attr_value(attr_path) + attr_rv = self.__get_attr_value(self.name_attr) if (attr_rv != 'ERR'): return True @@ -127,8 +146,37 @@ def get_temperature(self): A float number of current temperature in Celsius up to nearest thousandth of one degree Celsius, e.g. 30.125 """ - attr_path = HWMON_DIR + self.temp_attr - attr_rv = self.__get_attr_value(attr_path) + attr_rv = self.__get_attr_value(self.temp_attr) + + if (attr_rv != 'ERR'): + return float(attr_rv) / 1000 + else: + return None + + def get_low_threshold(self): + """ + Retrieves the low threshold temperature of thermal + + Returns: + A float number, the low threshold temperature of thermal in Celsius + up to nearest thousandth of one degree Celsius, e.g. 30.125 + """ + attr_rv = self.__get_attr_value(self.low_th_attr) + + if (attr_rv != 'ERR'): + return float(attr_rv) / 1000 + else: + return None + + def get_low_critical_threshold(self): + """ + Retrieves the low critical threshold temperature of thermal + + Returns: + A float number, the low critical threshold temperature of thermal in Celsius + up to nearest thousandth of one degree Celsius, e.g. 30.125 + """ + attr_rv = self.__get_attr_value(self.low_crit_th_attr) if (attr_rv != 'ERR'): return float(attr_rv) / 1000 @@ -143,8 +191,7 @@ def get_high_threshold(self): A float number, the high threshold temperature of thermal in Celsius up to nearest thousandth of one degree Celsius, e.g. 30.125 """ - attr_path = HWMON_DIR + self.high_th_attr - attr_rv = self.__get_attr_value(attr_path) + attr_rv = self.__get_attr_value(self.high_th_attr) if (attr_rv != 'ERR'): return float(attr_rv) / 1000 @@ -159,8 +206,7 @@ def get_high_critical_threshold(self): A float number, the high threshold temperature of thermal in Celsius up to nearest thousandth of one degree Celsius, e.g. 30.125 """ - attr_path = HWMON_DIR + self.high_crit_th_attr - attr_rv = self.__get_attr_value(attr_path) + attr_rv = self.__get_attr_value(self.high_crit_th_attr) if (attr_rv != 'ERR'): return float(attr_rv) / 1000 diff --git a/platform/broadcom/sonic-platform-modules-quanta/ix8a-bwde-56x/sonic_platform/watchdog.py b/platform/broadcom/sonic-platform-modules-quanta/ix8a-bwde-56x/sonic_platform/watchdog.py index 282f356f4e73..0e63d9368cb0 100644 --- a/platform/broadcom/sonic-platform-modules-quanta/ix8a-bwde-56x/sonic_platform/watchdog.py +++ b/platform/broadcom/sonic-platform-modules-quanta/ix8a-bwde-56x/sonic_platform/watchdog.py @@ -48,12 +48,16 @@ WDT_SYSFS_PATH = "/sys/class/watchdog/" DEFAULT_TIMEOUT=180 +watchdog=0 class Watchdog(WatchdogBase): def __init__(self): self.watchdog, self.wdt_main_dev_name = self._get_wdt() + if self.wdt_main_dev_name is None: + raise Exception("Watchdog device is not instantiated") + self.status_path = "/sys/class/watchdog/%s/status" % self.wdt_main_dev_name self.state_path = "/sys/class/watchdog/%s/state" % self.wdt_main_dev_name self.timeout_path = "/sys/class/watchdog/%s/timeout" % self.wdt_main_dev_name @@ -74,14 +78,16 @@ def _get_wdt(self): """ Retrieves watchdog device """ + global watchdog wdt_main_dev_list = [dev for dev in os.listdir( "/dev/") if dev.startswith("watchdog") and self._is_wd_main(dev)] if not wdt_main_dev_list: - return None + return (None, None) wdt_main_dev_name = wdt_main_dev_list[0] watchdog_device_path = "/dev/{}".format(wdt_main_dev_name) - self.watchdog = os.open(watchdog_device_path, os.O_RDWR) - return self.watchdog, wdt_main_dev_name + if not watchdog: + watchdog = os.open(watchdog_device_path, os.O_RDWR) + return watchdog, wdt_main_dev_name def _read_file(self, file_path): """ @@ -228,7 +234,8 @@ def __del__(self): Close watchdog """ - os.close(self.watchdog) + if self.watchdog is not None : + os.close(self.watchdog) diff --git a/platform/broadcom/sonic-platform-modules-quanta/ix8a-bwde-56x/utils/quanta_ix8a_bwde_util.py b/platform/broadcom/sonic-platform-modules-quanta/ix8a-bwde-56x/utils/quanta_ix8a_bwde_util.py index ed8c5fef6bd9..c23824779373 100755 --- a/platform/broadcom/sonic-platform-modules-quanta/ix8a-bwde-56x/utils/quanta_ix8a_bwde_util.py +++ b/platform/broadcom/sonic-platform-modules-quanta/ix8a-bwde-56x/utils/quanta_ix8a_bwde_util.py @@ -28,7 +28,7 @@ """ import os -import commands +import subprocess import sys, getopt import logging import time @@ -39,8 +39,8 @@ i2c_prefix = '/sys/bus/i2c/devices/' if DEBUG == True: - print sys.argv[0] - print 'ARGV :', sys.argv[1:] + print(sys.argv[0]) + print('ARGV :', sys.argv[1:]) def main(): global DEBUG @@ -55,9 +55,9 @@ def main(): 'force', ]) if DEBUG == True: - print options - print args - print len(sys.argv) + print(options) + print(args) + print(len(sys.argv)) for opt, arg in options: if opt in ('-h', '--help'): @@ -71,26 +71,26 @@ def main(): logging.info('no option') for arg in args: if arg == 'install': - install() + install() elif arg == 'clean': - uninstall() + uninstall() else: show_help() return 0 def show_help(): - print __doc__ % {'scriptName' : sys.argv[0].split("/")[-1]} + print(__doc__ % {'scriptName' : sys.argv[0].split("/")[-1]}) sys.exit(0) def show_log(txt): if DEBUG == True: - print "[IX8A-BWDE-56X]" + txt + print("[IX8A-BWDE-56X]" + txt) return def exec_cmd(cmd, show): logging.info('Run :' + cmd) - status, output = commands.getstatusoutput(cmd) + status, output = subprocess.getstatusoutput(cmd) show_log (cmd +"with result:" + str(status)) show_log (" output:" + output) if status: @@ -99,6 +99,18 @@ def exec_cmd(cmd, show): print('Failed :' + cmd) return status, output +pca954x_bus_addr =[ +'0-0072', +'0-0077', +'5-0073', +'6-0073', +'7-0073', +'8-0073', +'9-0073', +'10-0073', +'11-0073' +] + instantiate =[ #export pca9698 for qsfp present 'echo 34 > /sys/class/gpio/export', @@ -204,7 +216,7 @@ def exec_cmd(cmd, show): 'lpc_ich', 'i2c-i801', 'i2c-dev', -'i2c-mux-pca954x force_deselect_on_exit=1', +'i2c-mux-pca954x', 'gpio-pca953x', 'optoe', 'qci_cpld_sfp28', @@ -235,11 +247,20 @@ def system_install(): exec_cmd("depmod -a ", 1) #install drivers for i in range(0,len(drivers)): - status, output = exec_cmd("modprobe " + drivers[i], 1) - if status: - print output - if FORCE == 0: - return status + status, output = exec_cmd("modprobe " + drivers[i], 1) + if status: + print(output) + #retry quanta_hwmon_ipmi in case it init failed due to ipmi_msghandler init uncompleted + if drivers[i] == 'quanta_hwmon_ipmi': + for _ in range(0, 3): + time.sleep(3) + ret, out = exec_cmd("modprobe quanta_hwmon_ipmi ", 1) + if ret == 0: + break + if ret and FORCE == 0: + return ret + elif FORCE == 0: + return status #reload ethernet drivers in correct order exec_cmd("rmmod ixgbe ", 1) @@ -247,6 +268,10 @@ def system_install(): exec_cmd("modprobe igb ", 1) exec_cmd("modprobe ixgbe ", 1) + # set pca954x idle_state as -2: MUX_IDLE_DISCONNECT + for i in range(0,len(pca954x_bus_addr)): + exec_cmd("echo -2 > /sys/bus/i2c/drivers/pca954x/{}/idle_state".format(pca954x_bus_addr[i]), 1) + #turn on module power exec_cmd("echo 21 > /sys/class/gpio/export ", 1) exec_cmd("echo high > /sys/class/gpio/gpio21/direction ", 1) @@ -268,10 +293,10 @@ def system_install(): #instantiate devices for i in range(0, len(instantiate)): status, output = exec_cmd(instantiate[i], 1) - if status: - print output - if FORCE == 0: - return status + if status: + print(output) + if FORCE == 0: + return status #QSFP for 1~56 port for port_number in range(1, 57): @@ -291,35 +316,35 @@ def system_ready(): def install(): if not device_found(): - print "No device, installing...." + print("No device, installing....") status = system_install() if status: if FORCE == 0: return status status, output = exec_cmd("pip3 install /usr/share/sonic/device/x86_64-quanta_ix8a_bwde-r0/sonic_platform-1.0-py3-none-any.whl",1) if status: - print output - if FORCE == 0: - return status + print(output) + if FORCE == 0: + return status else: - print " ix8a-bwde driver already installed...." + print(" ix8a-bwde driver already installed....") return def uninstall(): global FORCE #uninstall drivers for i in range(len(un_drivers) - 1, -1, -1): - status, output = exec_cmd("rmmod " + un_drivers[i], 1) + status, output = exec_cmd("rmmod " + un_drivers[i], 1) if status: - print output + print(output) if FORCE == 0: return status status, output = exec_cmd("pip3 uninstall sonic-platform -y ",1) if status: - print output - if FORCE == 0: - return status + print(output) + if FORCE == 0: + return status return diff --git a/platform/broadcom/sonic-platform-modules-quanta/ix8c-56x/modules/qci_cpld_led.c b/platform/broadcom/sonic-platform-modules-quanta/ix8c-56x/modules/qci_cpld_led.c index 2b0fe902c4a8..23f91455f699 100644 --- a/platform/broadcom/sonic-platform-modules-quanta/ix8c-56x/modules/qci_cpld_led.c +++ b/platform/broadcom/sonic-platform-modules-quanta/ix8c-56x/modules/qci_cpld_led.c @@ -49,7 +49,7 @@ static struct class *cpld_class = NULL; struct cpld_data { struct i2c_client *cpld_client; - char name[8]; + char name[16]; u8 cpld_id; }; diff --git a/platform/broadcom/sonic-platform-modules-quanta/ix8c-56x/modules/qci_platform_ix8c.c b/platform/broadcom/sonic-platform-modules-quanta/ix8c-56x/modules/qci_platform_ix8c.c index d0ae085cd417..0dfd926a47aa 100644 --- a/platform/broadcom/sonic-platform-modules-quanta/ix8c-56x/modules/qci_platform_ix8c.c +++ b/platform/broadcom/sonic-platform-modules-quanta/ix8c-56x/modules/qci_platform_ix8c.c @@ -171,9 +171,9 @@ static int __init ix8c_platform_init(void) } else { - g_client[0] = i2c_new_device(adapter, &ix8c_i2c_devices[0]); // pca9546 - g_client[1] = i2c_new_device(adapter, &ix8c_i2c_devices[1]); // pca9548 - g_client[2] = i2c_new_device(adapter, &ix8c_i2c_devices[16]); // CPU Linking Board at CPU's I2C Bus + g_client[0] = i2c_new_client_device(adapter, &ix8c_i2c_devices[0]); // pca9546 + g_client[1] = i2c_new_client_device(adapter, &ix8c_i2c_devices[1]); // pca9548 + g_client[2] = i2c_new_client_device(adapter, &ix8c_i2c_devices[16]); // CPU Linking Board at CPU's I2C Bus i2c_put_adapter(adapter); } @@ -184,9 +184,9 @@ static int __init ix8c_platform_init(void) } else { - g_client[3] = i2c_new_device(adapter, &ix8c_i2c_devices[10]); // CPLD_1 - g_client[4] = i2c_new_device(adapter, &ix8c_i2c_devices[17]); // CPLD_4 - g_client[5] = i2c_new_device(adapter, &ix8c_i2c_devices[18]); // CPLD_6 + g_client[3] = i2c_new_client_device(adapter, &ix8c_i2c_devices[10]); // CPLD_1 + g_client[4] = i2c_new_client_device(adapter, &ix8c_i2c_devices[17]); // CPLD_4 + g_client[5] = i2c_new_client_device(adapter, &ix8c_i2c_devices[18]); // CPLD_6 i2c_put_adapter(adapter); } @@ -197,7 +197,7 @@ static int __init ix8c_platform_init(void) } else { - g_client[6] = i2c_new_device(adapter, &ix8c_i2c_devices[11]); // CPLD_2 + g_client[6] = i2c_new_client_device(adapter, &ix8c_i2c_devices[11]); // CPLD_2 i2c_put_adapter(adapter); } @@ -208,8 +208,8 @@ static int __init ix8c_platform_init(void) } else { - g_client[7] = i2c_new_device(adapter, &ix8c_i2c_devices[12]); // CPLD_3 - g_client[8] = i2c_new_device(adapter, &ix8c_i2c_devices[2]); // MB_BOARDINFO_EEPROM + g_client[7] = i2c_new_client_device(adapter, &ix8c_i2c_devices[12]); // CPLD_3 + g_client[8] = i2c_new_client_device(adapter, &ix8c_i2c_devices[2]); // MB_BOARDINFO_EEPROM i2c_put_adapter(adapter); } @@ -220,8 +220,8 @@ static int __init ix8c_platform_init(void) } else { - g_client[9] = i2c_new_device(adapter, &ix8c_i2c_devices[13]); // MB Board Data - g_client[10] = i2c_new_device(adapter, &ix8c_i2c_devices[14]); // QSFP:49~52 + g_client[9] = i2c_new_client_device(adapter, &ix8c_i2c_devices[13]); // MB Board Data + g_client[10] = i2c_new_client_device(adapter, &ix8c_i2c_devices[14]); // QSFP:49~52 i2c_put_adapter(adapter); } @@ -232,7 +232,7 @@ static int __init ix8c_platform_init(void) } else { - g_client[11] = i2c_new_device(adapter, &ix8c_i2c_devices[3]); // pca9548_1 SFP + g_client[11] = i2c_new_client_device(adapter, &ix8c_i2c_devices[3]); // pca9548_1 SFP i2c_put_adapter(adapter); } @@ -243,7 +243,7 @@ static int __init ix8c_platform_init(void) } else { - g_client[12] = i2c_new_device(adapter, &ix8c_i2c_devices[4]); // pca9548_2 SFP + g_client[12] = i2c_new_client_device(adapter, &ix8c_i2c_devices[4]); // pca9548_2 SFP i2c_put_adapter(adapter); } @@ -254,7 +254,7 @@ static int __init ix8c_platform_init(void) } else { - g_client[13] = i2c_new_device(adapter, &ix8c_i2c_devices[5]); // pca9548_3 SFP + g_client[13] = i2c_new_client_device(adapter, &ix8c_i2c_devices[5]); // pca9548_3 SFP i2c_put_adapter(adapter); } @@ -265,7 +265,7 @@ static int __init ix8c_platform_init(void) } else { - g_client[14] = i2c_new_device(adapter, &ix8c_i2c_devices[6]); // pca9548_4 SFP + g_client[14] = i2c_new_client_device(adapter, &ix8c_i2c_devices[6]); // pca9548_4 SFP i2c_put_adapter(adapter); } @@ -276,7 +276,7 @@ static int __init ix8c_platform_init(void) } else { - g_client[15] = i2c_new_device(adapter, &ix8c_i2c_devices[7]); // pca9548_5 SFP + g_client[15] = i2c_new_client_device(adapter, &ix8c_i2c_devices[7]); // pca9548_5 SFP i2c_put_adapter(adapter); } @@ -287,7 +287,7 @@ static int __init ix8c_platform_init(void) } else { - g_client[16] = i2c_new_device(adapter, &ix8c_i2c_devices[8]); // pca9548_6 SFP + g_client[16] = i2c_new_client_device(adapter, &ix8c_i2c_devices[8]); // pca9548_6 SFP i2c_put_adapter(adapter); } @@ -298,7 +298,7 @@ static int __init ix8c_platform_init(void) } else { - g_client[17] = i2c_new_device(adapter, &ix8c_i2c_devices[9]); // pca9548_7 QSFP + g_client[17] = i2c_new_client_device(adapter, &ix8c_i2c_devices[9]); // pca9548_7 QSFP i2c_put_adapter(adapter); } @@ -311,9 +311,9 @@ static int __init ix8c_platform_init(void) else { if (i < 61) // SFP28 1~48 EEPROM - g_client_port[i - 13] = i2c_new_device(adapter, &ix8c_i2c_devices[19]); + g_client_port[i - 13] = i2c_new_client_device(adapter, &ix8c_i2c_devices[19]); else // QSFP 49~56 EEPROM - g_client_port[i - 13] = i2c_new_device(adapter, &ix8c_i2c_devices[15]); + g_client_port[i - 13] = i2c_new_client_device(adapter, &ix8c_i2c_devices[15]); i2c_put_adapter(adapter); } } diff --git a/platform/broadcom/sonic-platform-modules-quanta/ix8c-56x/modules/quanta_hwmon_ipmi.c b/platform/broadcom/sonic-platform-modules-quanta/ix8c-56x/modules/quanta_hwmon_ipmi.c index 157ae94778d5..1da44bda029f 100644 --- a/platform/broadcom/sonic-platform-modules-quanta/ix8c-56x/modules/quanta_hwmon_ipmi.c +++ b/platform/broadcom/sonic-platform-modules-quanta/ix8c-56x/modules/quanta_hwmon_ipmi.c @@ -28,7 +28,7 @@ #define __TO_R_EXP(bacc) (int32_t)(tos32(((BSWAP_32(bacc) & 0xf0) >> 4), 4)) #define __TO_B_EXP(bacc) (int32_t)(tos32((BSWAP_32(bacc) & 0xf), 4)) -#define SENSOR_ATTR_MAX 17 +#define SENSOR_ATTR_MAX 19 #define SENSOR_ATTR_NAME_LENGTH 20 #define SENSOR_GET_CAP_LABEL 0x001 @@ -53,6 +53,8 @@ #define SENSOR_GET_CAP_PSU_PRESENT 0x8000 #define SENSOR_GET_CAP_MFRID 0x10000 +#define SENSOR_GET_CAP_VIN_TYPE 0x20000 +#define SENSOR_GET_CAP_POUT_MAX 0x40000 #define SDR_SENSOR_TYPE_TEMP 0x01 #define SDR_SENSOR_TYPE_VOLT 0x02 @@ -84,6 +86,8 @@ #define IPMI_TIMEOUT (4 * HZ) #define IPMI_MAX_WAIT_QUEUE 1 +typedef struct ipmi_user *ipmi_user_t; + struct quanta_hwmon_ipmi_data { struct platform_device *ipmi_platform_dev; struct device *ipmi_hwmon_dev; @@ -912,6 +916,8 @@ void ipmi_sdr_set_sensor_factor(uint8_t idx, struct sdr_record_full_sensor *sens g_sensor_data[idx].capability |= SENSOR_GET_CAP_SN; g_sensor_data[idx].capability |= SENSOR_GET_CAP_MFRID; g_sensor_data[idx].capability |= SENSOR_GET_CAP_PSU_PRESENT; + g_sensor_data[idx].capability |= SENSOR_GET_CAP_VIN_TYPE; + g_sensor_data[idx].capability |= SENSOR_GET_CAP_POUT_MAX; } sprintf(g_sensor_data[idx].attrinfo.attr_type_str, "power"); } @@ -976,7 +982,7 @@ int32_t sdr_convert_sensor_reading(uint8_t idx, uint8_t val, int32_t *point_resu result = (m * (int16_t)val) * decimal_point + b; break; default: - return; + return result; } pow_convert(&result, k2); @@ -1074,6 +1080,83 @@ int32_t ipmi_get_psu_info(uint8_t idx, uint8_t cmd, uint8_t *retbuf) return sprintf(retbuf, "N/A\n"); } +int32_t ipmi_get_vin_type(uint8_t idx, uint8_t *retbuf) +{ + uint8_t psu_slot = 0; + int32_t rv = 0; + + uint8_t returnData = 0; + uint8_t msg_data[] = { 0x06, 0x52, 0x0f, 0x00, 0x01, 0xd8 }; // read line status + + if (strstr(g_sensor_data[idx].sensor_idstring, "PSU1")) psu_slot = 1; + else psu_slot = 2; + + msg_data[3] = (psu_slot == 1) ? 0xb0 : 0xb2; + if (ipmi_check_psu_present(psu_slot)) { + mutex_lock(&ipmi_lock); + rv = ipmi_send_system_cmd(msg_data, sizeof(msg_data), &returnData, 1); + mutex_unlock(&ipmi_lock); + + if (rv) { + printk("BMC down at (%d)!!\n", __LINE__); + } + else { + switch (returnData) + { + case 0x7: //LVDC + case 0x3: //HVDC + return sprintf(retbuf, "DC\n"); + default: + return sprintf(retbuf, "AC\n"); + } + } + } + else { + //printk("Error ! cannot detect PSU%d\n", psu_slot); + } + + return sprintf(retbuf, "N/A\n"); +} + +int32_t ipmi_get_pout_max(uint8_t idx, uint8_t *retbuf) +{ + uint8_t psu_slot = 0; + int32_t rv = 0, pout_max = 0; + + uint8_t returnData[2] = { 0 }, tempData[2] = { 0 }; + uint8_t msg_data[] = { 0x06, 0x52, 0x0f, 0x00, 0x02, 0xa7 }; + + if (strstr(g_sensor_data[idx].sensor_idstring, "PSU1")) psu_slot = 1; + else psu_slot = 2; + + msg_data[3] = (psu_slot == 1) ? 0xb0 : 0xb2; + if (ipmi_check_psu_present(psu_slot)) { + mutex_lock(&ipmi_lock); + rv = ipmi_send_system_cmd(msg_data, sizeof(msg_data), returnData, 1); + mutex_unlock(&ipmi_lock); + + if (rv) { + printk("BMC down at (%d)!!\n", __LINE__); + } + else { + /* MFR_POUT_MAX has 2 data format: Direct and Linear Data (see PMbus spec). + Query command is needed to tell the data format, but since we have not use PSU + whose output power is over 0x07ff (2047), just check the first 5 bits*/ + if (returnData[1] & 0xf8 == 0) // Direct + pout_max = (returnData[1] << 8) | returnData[0]; + else // Linear Data + pout_max = (((returnData[1] & 0x07) << 8) | returnData[0]) << ((returnData[1] & 0xf8) >> 3); + return sprintf(retbuf, "%d\n", pout_max); + } + } + else { + //printk("Error ! cannot detect PSU%d\n", psu_slot); + } + + return sprintf(retbuf, "N/A\n"); +} + + void ipmi_fan_control(uint8_t cmd_data1, uint8_t cmd_data2, uint8_t *retbuf) { int32_t rv = 0; @@ -1183,6 +1266,18 @@ static ssize_t show_mfrid(struct device *dev, struct device_attribute *devattr, return ipmi_get_psu_info(attr->index + DEBUGUSE_SHIFT, 0x99, buf); } +static ssize_t show_vin_type(struct device *dev, struct device_attribute *devattr, char *buf) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); + return ipmi_get_vin_type(attr->index + DEBUGUSE_SHIFT, buf); +} + +static ssize_t show_pout_max(struct device *dev, struct device_attribute *devattr, char *buf) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); + return ipmi_get_pout_max(attr->index + DEBUGUSE_SHIFT, buf); +} + static ssize_t show_pwm(struct device *dev, struct device_attribute *devattr, char *buf) { uint8_t returnData[10] = { 0 }; @@ -1277,7 +1372,8 @@ static ssize_t(*const attr_show_func_ptr[SENSOR_ATTR_MAX]) (struct device *dev, , show_unc, show_ucr, show_unr , show_model, show_sn, show_pwm , show_controlmode, show_direction, show_fanpresent - , show_psupresent, show_mfrid + , show_psupresent, show_mfrid, show_vin_type + , show_pout_max }; static ssize_t(*const attr_store_func_ptr[SENSOR_ATTR_MAX]) (struct device *dev, struct device_attribute *devattr, const char *buf, size_t count) = @@ -1287,7 +1383,8 @@ static ssize_t(*const attr_store_func_ptr[SENSOR_ATTR_MAX]) (struct device *dev, , NULL, NULL, NULL , NULL, NULL, store_pwm , store_controlmode, NULL, NULL - , NULL, NULL + , NULL, NULL, NULL + , NULL }; static const char *const sensor_attrnames[SENSOR_ATTR_MAX] = @@ -1297,7 +1394,8 @@ static const char *const sensor_attrnames[SENSOR_ATTR_MAX] = , "%s%d_ncrit", "%s%d_crit", "%s%d_max" , "%s%d_model", "%s%d_sn", "%s%d_pwm" , "%s%d_controlmode", "%s%d_direction", "%s%d_present" - , "%s%d_present", "%s%d_mfrid" + , "%s%d_present", "%s%d_mfrid", "%s%d_vin_type" + , "%s%d_pout_max" }; static int32_t create_sensor_attrs(int32_t attr_no) @@ -1516,7 +1614,7 @@ static int32_t __init quanta_hwmon_ipmi_init(void) goto device_reg_err; } - data->ipmi_hwmon_dev = hwmon_device_register_with_groups(NULL, DRVNAME, NULL, NULL); + data->ipmi_hwmon_dev = hwmon_device_register_with_groups(&data->ipmi_platform_dev->dev, DRVNAME, NULL, NULL); err = IS_ERR(data->ipmi_hwmon_dev); if (err) { printk("hwmon register fail\n"); @@ -1539,19 +1637,15 @@ static int32_t __init quanta_hwmon_ipmi_init(void) return 0; init_sensor_err: - if (g_sensor_data) { - kfree(g_sensor_data); - g_sensor_data = NULL; - } + kfree(g_sensor_data); + g_sensor_data = NULL; ipmi_create_err: hwmon_device_unregister(data->ipmi_hwmon_dev); hwmon_register_err: platform_device_unregister(data->ipmi_platform_dev); device_reg_err: - if (data) { - kfree(data); - data = NULL; - } + kfree(data); + data = NULL; alloc_err: return err; } @@ -1567,15 +1661,10 @@ static void __exit quanta_hwmon_ipmi_exit(void) platform_device_unregister(data->ipmi_platform_dev); - if (g_sensor_data) { - kfree(g_sensor_data); - g_sensor_data = NULL; - } - - if (data) { - kfree(data); - data = NULL; - } + kfree(g_sensor_data); + g_sensor_data = NULL; + kfree(data); + data = NULL; } module_init(quanta_hwmon_ipmi_init); diff --git a/platform/broadcom/sonic-platform-modules-quanta/ix8c-56x/sonic_platform/chassis.py b/platform/broadcom/sonic-platform-modules-quanta/ix8c-56x/sonic_platform/chassis.py index 544a3ee27c64..7cb5c4c1e6ae 100644 --- a/platform/broadcom/sonic-platform-modules-quanta/ix8c-56x/sonic_platform/chassis.py +++ b/platform/broadcom/sonic-platform-modules-quanta/ix8c-56x/sonic_platform/chassis.py @@ -8,6 +8,7 @@ try: import sys import time + import syslog from sonic_platform_base.chassis_base import ChassisBase from sonic_platform.eeprom import Eeprom from sonic_platform.psu import Psu @@ -71,6 +72,13 @@ def __init__(self): for index in range(1, self.__num_of_ports + 1): self.__xcvr_presence[index] = self._sfp_list[index-1].get_presence() + # Initialize components + from sonic_platform.component import ComponentBIOS, ComponentBMC, ComponentCPLD, ComponentPCIE + self._component_list.append(ComponentBIOS()) + self._component_list.append(ComponentBMC()) + self._component_list.extend(ComponentCPLD.get_component_list()) + self._component_list.append(ComponentPCIE()) + ############################################## # Device methods ############################################## @@ -78,7 +86,7 @@ def __init__(self): def get_sfp(self, index): """ Retrieves sfp represented by (1-based) index - For Quanta IX8C the index in sfputil.py starts from 1, so override + For Quanta the index in sfputil.py starts from 1, so override Args: index: An integer, the index (1-based) of the sfp to retrieve. @@ -188,13 +196,34 @@ def get_reboot_cause(self): is "REBOOT_CAUSE_HARDWARE_OTHER", the second string can be used to pass a description of the reboot cause. """ - #raise NotImplementedError return (ChassisBase.REBOOT_CAUSE_HARDWARE_OTHER, "Invalid Reason") + ############################################## + # Other methods + ############################################## + def get_watchdog(self): + """ + Retreives hardware watchdog device on this chassis + + Returns: + An object derived from WatchdogBase representing the hardware + watchdog device + """ + try: + if self._watchdog is None: + from sonic_platform.watchdog import Watchdog + # Create the watchdog Instance + self._watchdog = Watchdog() + + except Exception as e: + syslog.syslog(syslog.LOG_ERR, "Fail to load watchdog due to {}".format(e)) + return self._watchdog + def get_change_event(self, timeout=0): """ Currently only support transceiver change events """ + start_ms = time.time() * 1000 xcvr_change_event_dict = {} event = False @@ -205,10 +234,10 @@ def get_change_event(self, timeout=0): cur_xcvr_presence = self._sfp_list[index-1].get_presence() if cur_xcvr_presence != self.__xcvr_presence[index]: if cur_xcvr_presence is True: - xcvr_change_event_dict[str(index)] = '1' + xcvr_change_event_dict[index] = '1' self.__xcvr_presence[index] = True elif cur_xcvr_presence is False: - xcvr_change_event_dict[str(index)] = '0' + xcvr_change_event_dict[index] = '0' self.__xcvr_presence[index] = False event = True diff --git a/platform/broadcom/sonic-platform-modules-quanta/ix8c-56x/sonic_platform/component.py b/platform/broadcom/sonic-platform-modules-quanta/ix8c-56x/sonic_platform/component.py new file mode 100644 index 000000000000..75066275d2c3 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-quanta/ix8c-56x/sonic_platform/component.py @@ -0,0 +1,204 @@ +#!/usr/bin/env python + +######################################################################## +# Quanta IX8C +# +# Name: component.py, version: 1.3 +# Module contains an implementation of SONiC Platform Base API and +# provides the Components' (e.g., BIOS, CPLD, FPGA, etc.) available in +# the platform +# +######################################################################## + +try: + import subprocess + from sonic_platform_base.component_base import ComponentBase + from collections import namedtuple +except ImportError as e: + raise ImportError(str(e) + "- required module not found") + + +class Component(ComponentBase): + def __init__(self): + ComponentBase.__init__(self) + self.name = None + self.description = None + + def get_name(self): + return self.name + + def get_description(self): + return self.description + + def install_firmware(self, image_path): + """ + Installs firmware to the component + + Args: + image_path: A string, path to firmware image + + Returns: + A boolean, True if install was successful, False if not + """ + return False + + @staticmethod + def _get_command_result(cmdline): + try: + proc = subprocess.Popen(cmdline, + stdout=subprocess.PIPE, + shell=True, stderr=subprocess.STDOUT, + universal_newlines=True) + stdout = proc.communicate()[0] + rc = proc.wait() + result = stdout.rstrip('\n') + if rc != 0: + raise RuntimeError("Failed to execute command {}, return code {}, {}".format(cmdline, rc, stdout)) + + except OSError as e: + raise RuntimeError("Failed to execute command {} due to {}".format(cmdline, repr(e))) + + return result + + +class ComponentBIOS(Component): + COMPONENT_NAME = 'BIOS' + COMPONENT_DESCRIPTION = 'BIOS - Basic Input/Output System' + + BIOS_QUERY_VERSION_COMMAND = "dmidecode -s bios-version" + + def __init__(self): + super(ComponentBIOS, self).__init__() + + self.name = self.COMPONENT_NAME + self.description = self.COMPONENT_DESCRIPTION + + def get_firmware_version(self): + """ + Retrieves the firmware version of the component + + Returns: + A string containing the firmware version of the component + """ + bios_ver = self._get_command_result(self.BIOS_QUERY_VERSION_COMMAND) + if not bios_ver: + return 'ERR' + else: + return bios_ver + + +class ComponentBMC(Component): + COMPONENT_NAME = 'BMC' + COMPONENT_DESCRIPTION = 'BMC - Board Management Controller' + BMC_QUERY_VERSION_COMMAND = "ipmitool mc info | grep 'Firmware Revision'" + + def __init__(self): + super(ComponentBMC, self).__init__() + + self.name = self.COMPONENT_NAME + self.description = self.COMPONENT_DESCRIPTION + + def get_firmware_version(self): + """ + Retrieves the firmware version of the component + + Returns: + A string containing the firmware version of the component + """ + bmc_ver = self._get_command_result(self.BMC_QUERY_VERSION_COMMAND) + if not bmc_ver: + return 'ERR' + else: + bmc_ver = bmc_ver.split(": ")[1] + return bmc_ver.strip() + + +class ComponentCPLD(Component): + Cpld = namedtuple("Cpld", ['name', 'cmd_index', 'description']) + + cplds = { + 1: Cpld("BOOT_CPLD", 1, "Power sequence"), + 2: Cpld("FAN_CPLD", 2, "Fan"), + 3: Cpld("MB_CPLD_IO_1", 7, "Port IO-1"), + 4: Cpld("MB_CPLD_IO_2", 5, "Port IO-2"), + 5: Cpld("MB_CPLD_IO_3", 4, "Port IO-3"), + 6: Cpld("MB_CPLD_LED_1", 6, "Port LED-1"), + 7: Cpld("MB_CPLD_LED_2", 3, "Port LED-2"), + } + + def __init__(self, component_index): + super(ComponentCPLD, self).__init__() + self.index = component_index + + def get_name(self): + """ + Retrieves the name of the component + + Returns: + A string containing the name of the component + """ + self.name = self.cplds[self.index].name + + return self.name + + def get_description(self): + """ + Retrieves the description of the component + + Returns: + A string containing the description of the component + """ + self.description = self.cplds[self.index].description + + return self.description + + def get_firmware_version(self): + """ + Retrieves the firmware version of the component + + Returns: + A string containing the firmware version of the component + """ + self._get_command_result("ipmitool raw 0x30 0xe0 0xd0 0x01 0x01") + res = self._get_command_result("ipmitool raw 0x32 0xff 0x02 {}".format(self.cplds[self.index].cmd_index)) + self._get_command_result("ipmitool raw 0x30 0xe0 0xd0 0x01 0x00") + if not res: + return 'ERR' + else: + return res.split()[3].upper() + res.split()[2].upper() + res.split()[1].upper() + res.split()[0].upper() + + @classmethod + def get_component_list(cls): + component_list = [] + cpld_number = len(cls.cplds) + + for cpld_idx in range(1, cpld_number + 1): + component_list.append(cls(cpld_idx)) + + return component_list + + +class ComponentPCIE(Component): + COMPONENT_NAME = 'PCIe' + COMPONENT_DESCRIPTION = 'ASIC PCIe Firmware' + PCIE_QUERY_VERSION_COMMAND = "bcmcmd 'pciephy fw version' | grep 'FW version'" + + def __init__(self): + super(ComponentPCIE, self).__init__() + + self.name = self.COMPONENT_NAME + self.description = self.COMPONENT_DESCRIPTION + + def get_firmware_version(self): + """ + Retrieves the firmware version of the component + + Returns: + A string containing the firmware version of the component + """ + version = self._get_command_result(self.PCIE_QUERY_VERSION_COMMAND) + if not version: + return 'ERR' + else: + version = version.split(": ")[1] + return version.strip() diff --git a/platform/broadcom/sonic-platform-modules-quanta/ix8c-56x/sonic_platform/fan.py b/platform/broadcom/sonic-platform-modules-quanta/ix8c-56x/sonic_platform/fan.py index ed3a836ba150..94a9b74df8dd 100644 --- a/platform/broadcom/sonic-platform-modules-quanta/ix8c-56x/sonic_platform/fan.py +++ b/platform/broadcom/sonic-platform-modules-quanta/ix8c-56x/sonic_platform/fan.py @@ -1,7 +1,7 @@ #!/usr/bin/env python ############################################################################# -# Inventec d7264 +# Quanta IX8C # # Module contains an implementation of SONiC Platform Base API and # provides the FAN information @@ -11,6 +11,7 @@ try: import logging import os + import glob from sonic_platform_base.fan_base import FanBase except ImportError as e: raise ImportError(str(e) + "- required module not found") @@ -19,9 +20,7 @@ ############### # Global ############### -HWMON_DIR = "/sys/class/hwmon/hwmon2/" -FAN_INDEX_START = 20 -NUM_FANTRAYS = 6 +HWMON_IPMI_DIR = "/sys/devices/platform/quanta_hwmon_ipmi/hwmon/hwmon*/" FANS_PERTRAY = 2 class Fan(FanBase): @@ -30,30 +29,46 @@ class Fan(FanBase): def __init__(self, index, is_psu_fan=False): self.is_psu_fan = is_psu_fan self.fan_index = index - self.psu_fan_index_mapping = { - 1:39, - 2:49, - } - self.psu_index_mapping = { - 1:41, - 2:51, - } + hwmon_dir=glob.glob(HWMON_IPMI_DIR)[0] + if self.is_psu_fan: - self.fan_presence_attr = "power{}_present".format(self.psu_index_mapping[index]) - self.fan_pwm_attr = "fan{}_pwm".format(self.psu_fan_index_mapping[index]) - self.fan_rpm_attr = "fan{}_input".format(self.psu_fan_index_mapping[index]) - self.fan_direction_attr = "fan{}_direction".format(self.psu_fan_index_mapping[index]) + power_out_prefix = self.__get_hwmon_attr_prefix(hwmon_dir, "PSU{}_POWER_OUT".format(self.fan_index), 'power') + fan_prefix = self.__get_hwmon_attr_prefix(hwmon_dir, "PSU{}_Fan".format(self.fan_index), 'fan') + self.fan_presence_attr = power_out_prefix + 'present' + self.fan_pwm_attr = fan_prefix + 'pwm' + self.fan_rpm_attr = fan_prefix + 'input' + self.fan_direction_attr = fan_prefix + 'direction' else: - self.fan_presence_attr = "fan{}_present".format(FAN_INDEX_START+(index-1)) - self.fan_pwm_attr = "fan{}_pwm".format(FAN_INDEX_START+(index-1)) - self.fan_rpm_attr = "fan{}_input".format(FAN_INDEX_START+(index-1)) - self.fan_direction_attr = "fan{}_direction".format(FAN_INDEX_START+(index-1)) + fantray_index = (self.fan_index-1)//FANS_PERTRAY+1 + fan_index_intray = self.fan_index - ((fantray_index-1)*FANS_PERTRAY) + fan_prefix = self.__get_hwmon_attr_prefix(hwmon_dir, "Fan_SYS_{}_{}".format(fantray_index, fan_index_intray), 'fan') + self.fan_presence_attr = fan_prefix + 'present' + self.fan_pwm_attr = fan_prefix + 'pwm' + self.fan_rpm_attr = fan_prefix + 'input' + self.fan_direction_attr = fan_prefix + 'direction' ####################### # private function ####################### + def __get_hwmon_attr_prefix(self, dir, label, type): + + retval = 'ERR' + if not os.path.isdir(dir): + return retval + + try: + for filename in os.listdir(dir): + if filename[-5:] == 'label' and type in filename: + file_path = os.path.join(dir, filename) + if os.path.isfile(file_path) and label == self.__get_attr_value(file_path): + return file_path[0:-5] + except Exception as error: + logging.error("Error when getting {} label path: {}".format(label, error)) + + return retval + def __get_attr_value(self, attr_path): retval = 'ERR' @@ -64,7 +79,7 @@ def __get_attr_value(self, attr_path): with open(attr_path, 'r') as fd: retval = fd.read() except Exception as error: - logging.error("Unable to open " + attr_path + " file !") + logging.error("Unable to open {} file: {}".format(attr_path, error)) retval = retval.rstrip(' \t\n\r') return retval @@ -84,7 +99,7 @@ def get_name(self): if self.is_psu_fan: return "PSU-{}_FAN".format(self.fan_index) else: - fantray_index = (self.fan_index-1)/FANS_PERTRAY+1 + fantray_index = (self.fan_index-1)//FANS_PERTRAY+1 fan_index_intray = self.fan_index - ((fantray_index-1)*FANS_PERTRAY) return "Fantray{}_{}".format(fantray_index, fan_index_intray) @@ -95,8 +110,7 @@ def get_presence(self): Returns: bool: True if device is present, False if not """ - attr_path = HWMON_DIR + self.fan_presence_attr - attr_rv = self.__get_attr_value(attr_path) + attr_rv = self.__get_attr_value(self.fan_presence_attr) if (attr_rv != 'ERR'): if (attr_rv == '1'): return True @@ -113,8 +127,7 @@ def get_status(self): A boolean value, True if device is operating properly, False if not """ if self.get_presence(): - attr_path = HWMON_DIR + self.fan_rpm_attr - attr_rv = self.__get_attr_value(attr_path) + attr_rv = self.__get_attr_value(self.fan_rpm_attr) if (attr_rv != 'ERR' and attr_rv != '0.0'): return True @@ -135,8 +148,7 @@ def get_direction(self): A string, either FAN_DIRECTION_INTAKE or FAN_DIRECTION_EXHAUST depending on fan direction """ - attr_path = HWMON_DIR + self.fan_direction_attr - attr_rv = self.__get_attr_value(attr_path) + attr_rv = self.__get_attr_value(self.fan_direction_attr) if attr_rv == '2': return self.FAN_DIRECTION_INTAKE @@ -152,8 +164,7 @@ def get_speed(self): to 100 (full speed) """ if self.get_presence(): - attr_path = HWMON_DIR + self.fan_pwm_attr - attr_rv = self.__get_attr_value(attr_path) + attr_rv = self.__get_attr_value(self.fan_pwm_attr) if (attr_rv != 'ERR'): return int(float(attr_rv)) @@ -169,8 +180,7 @@ def get_speed_rpm(self): Returns: An integer, speed of the fan in RPM """ - attr_path = HWMON_DIR + self.fan_rpm_attr - attr_rv = self.__get_attr_value(attr_path) + attr_rv = self.__get_attr_value(self.fan_rpm_attr) if (attr_rv != 'ERR'): return int(float(attr_rv)) @@ -185,8 +195,7 @@ def get_target_speed(self): An integer, the percentage of full fan speed, in the range 0 (off) to 100 (full speed) """ - attr_path = HWMON_DIR + self.fan_pwm_attr - attr_rv = self.__get_attr_value(attr_path) + attr_rv = self.__get_attr_value(self.fan_pwm_attr) if (attr_rv != 'ERR'): return int(float(attr_rv)) diff --git a/platform/broadcom/sonic-platform-modules-quanta/ix8c-56x/sonic_platform/fan_drawer.py b/platform/broadcom/sonic-platform-modules-quanta/ix8c-56x/sonic_platform/fan_drawer.py index 75e954576a28..3d5f767477ee 100644 --- a/platform/broadcom/sonic-platform-modules-quanta/ix8c-56x/sonic_platform/fan_drawer.py +++ b/platform/broadcom/sonic-platform-modules-quanta/ix8c-56x/sonic_platform/fan_drawer.py @@ -28,7 +28,7 @@ def get_name(self): Returns: string: The name of the device """ - return 'Fan {}'.format(self._index) + return 'Fantray{}'.format(self._index) def get_presence(self): """ diff --git a/platform/broadcom/sonic-platform-modules-quanta/ix8c-56x/sonic_platform/psu.py b/platform/broadcom/sonic-platform-modules-quanta/ix8c-56x/sonic_platform/psu.py index 941d8faef4f5..6188c95c7692 100644 --- a/platform/broadcom/sonic-platform-modules-quanta/ix8c-56x/sonic_platform/psu.py +++ b/platform/broadcom/sonic-platform-modules-quanta/ix8c-56x/sonic_platform/psu.py @@ -8,44 +8,61 @@ try: import logging import os + import glob from sonic_platform_base.psu_base import PsuBase from sonic_platform.fan import Fan except ImportError as e: raise ImportError(str(e) + "- required module not found") -HWMON_DIR = "/sys/class/hwmon/hwmon2/" +HWMON_IPMI_DIR = "/sys/devices/platform/quanta_hwmon_ipmi/hwmon/hwmon*/" class Psu(PsuBase): def __init__(self, index): PsuBase.__init__(self) fan = Fan(index, True) self._fan_list.append(fan) + self.index = index + hwmon_dir=glob.glob(HWMON_IPMI_DIR)[0] + + current_in_prefix = self.__get_hwmon_attr_prefix(hwmon_dir, "PSU{}_CURRENT_IN".format(self.index), 'curr') + current_out_prefix = self.__get_hwmon_attr_prefix(hwmon_dir, "PSU{}_CURRENT_OUT".format(self.index), 'curr') + power_in_prefix = self.__get_hwmon_attr_prefix(hwmon_dir, "PSU{}_POWER_IN".format(self.index), 'power') + power_out_prefix = self.__get_hwmon_attr_prefix(hwmon_dir, "PSU{}_POWER_OUT".format(self.index), 'power') + voltage_in_prefix = self.__get_hwmon_attr_prefix(hwmon_dir, "PSU{}_VOLTAGE_IN".format(self.index), 'in') + voltage_out_prefix = self.__get_hwmon_attr_prefix(hwmon_dir, "PSU{}_VOLTAGE_OUT".format(self.index), 'in') + temp1_prefix = self.__get_hwmon_attr_prefix(hwmon_dir, "PSU{}_TEMP1".format(self.index), 'temp') + + self.psu_current_in_attr = current_in_prefix + 'input' + self.psu_current_out_attr = current_out_prefix + 'input' + self.psu_power_in_attr = power_in_prefix + 'input' + self.psu_power_out_attr = power_out_prefix + 'input' + self.psu_voltage_in_attr = voltage_in_prefix + 'input' + self.psu_voltage_out_attr = voltage_out_prefix + 'input' + self.psu_status_attr = current_out_prefix + 'input' + self.psu_presence_attr = power_out_prefix + 'present' + self.psu_serial_attr = power_out_prefix + 'sn' + self.psu_model_attr = power_out_prefix + 'model' + self.psu_mfr_id_attr = power_out_prefix + 'mfrid' + self.psu_capacity_attr = power_out_prefix + 'pout_max' + self.psu_type_attr = power_out_prefix + 'vin_type' + self.psu_temp_attr = temp1_prefix + 'input' + + def __get_hwmon_attr_prefix(self, dir, label, type): - self.psu_index_mapping = { - 1:41, - 2:51, - } - self.psu_powerin_index_mapping = { - 1:40, - 2:50, - } - self.psu_current_index_mapping = { - 1:38, - 2:48, - } - self.psu_voltageout_index_mapping = { - 1:46, - 2:56, - } - self.index = index - self.psu_presence_attr = "power{}_present".format(self.psu_index_mapping[self.index]) - self.psu_status_attr = "curr{}_input".format(self.psu_current_index_mapping[self.index]) - self.psu_power_in_attr = "power{}_input".format(self.psu_powerin_index_mapping[self.index]) - self.psu_power_out_attr = "power{}_input".format(self.psu_index_mapping[self.index]) - self.psu_voltage_out_attr = "in{}_input".format(self.psu_voltageout_index_mapping[self.index]) - self.psu_current_out_attr = "curr{}_input".format(self.psu_current_index_mapping[self.index]) - self.psu_serial_attr = "power{}_sn".format(self.psu_index_mapping[self.index]) - self.psu_model_attr = "power{}_model".format(self.psu_index_mapping[self.index]) + retval = 'ERR' + if not os.path.isdir(dir): + return retval + + try: + for filename in os.listdir(dir): + if filename[-5:] == 'label' and type in filename: + file_path = os.path.join(dir, filename) + if os.path.isfile(file_path) and label == self.__get_attr_value(file_path): + return file_path[0:-5] + except Exception as error: + logging.error("Error when getting {} label path: {}".format(label, error)) + + return retval def __get_attr_value(self, attr_path): @@ -57,10 +74,9 @@ def __get_attr_value(self, attr_path): with open(attr_path, 'r') as fd: retval = fd.read() except Exception as error: - logging.error("Unable to open " + attr_path + " file !") + logging.error("Unable to open {} file: {}".format(attr_path, error)) retval = retval.rstrip(' \t\n\r') - fd.close() return retval ############################################## @@ -84,10 +100,9 @@ def get_presence(self): bool: True if device is present, False if not """ presence = False - attr_path = HWMON_DIR+self.psu_presence_attr attr_normal = '1' - attr_rv = self.__get_attr_value(attr_path) + attr_rv = self.__get_attr_value(self.psu_presence_attr) if (attr_rv != 'ERR'): if (attr_rv == attr_normal): presence = True @@ -102,13 +117,26 @@ def get_model(self): string: Model/part number of device """ model = "N/A" - attr_path = HWMON_DIR+self.psu_model_attr - attr_rv = self.__get_attr_value(attr_path) + attr_rv = self.__get_attr_value(self.psu_model_attr) if (attr_rv != 'ERR'): model = attr_rv return model + def get_mfr_id(self): + """ + Retrieves the manufacturer's name (or id) of the device + + Returns: + string: Manufacturer's id of device + """ + mfr_id = "N/A" + attr_rv = self.__get_attr_value(self.psu_mfr_id_attr) + if (attr_rv != 'ERR'): + mfr_id = attr_rv + + return mfr_id + def get_serial(self): """ Retrieves the serial number of the device @@ -117,9 +145,7 @@ def get_serial(self): string: Serial number of device """ serial = "N/A" - attr_path = HWMON_DIR+self.psu_serial_attr - - attr_rv = self.__get_attr_value(attr_path) + attr_rv = self.__get_attr_value(self.psu_serial_attr) if (attr_rv != 'ERR'): serial = attr_rv @@ -133,9 +159,7 @@ def get_status(self): A boolean value, True if device is operating properly, False if not """ status = False - attr_path = HWMON_DIR+self.psu_status_attr - - attr_rv = self.__get_attr_value(attr_path) + attr_rv = self.__get_attr_value(self.psu_status_attr) if (attr_rv != 'ERR'): attr_rv, dummy = attr_rv.split('.', 1) if (int(attr_rv) != 0): @@ -156,9 +180,7 @@ def get_voltage(self): e.g. 12.1 """ voltage_out = 0.0 - attr_path = HWMON_DIR+self.psu_voltage_out_attr - - attr_rv = self.__get_attr_value(attr_path) + attr_rv = self.__get_attr_value(self.psu_voltage_out_attr) if (attr_rv != 'ERR'): attr_rv, dummy = attr_rv.split('.', 1) voltage_out = float(attr_rv) / 1000 @@ -173,15 +195,44 @@ def get_current(self): A float number, the electric current in amperes, e.g 15.4 """ current_out = 0.0 - attr_path = HWMON_DIR+self.psu_current_out_attr - - attr_rv = self.__get_attr_value(attr_path) + attr_rv = self.__get_attr_value(self.psu_current_out_attr) if (attr_rv != 'ERR'): attr_rv, dummy = attr_rv.split('.', 1) current_out = float(attr_rv) / 1000 return current_out + def get_input_voltage(self): + """ + Retrieves current PSU voltage input + + Returns: + A float number, the input voltage in volts, + e.g. 12.1 + """ + voltage_in = 0.0 + attr_rv = self.__get_attr_value(self.psu_voltage_in_attr) + if (attr_rv != 'ERR'): + attr_rv, dummy = attr_rv.split('.', 1) + voltage_in = float(attr_rv) / 1000 + + return voltage_in + + def get_input_current(self): + """ + Retrieves present electric current supplied by PSU + + Returns: + A float number, the electric current in amperes, e.g 15.4 + """ + current_in = 0.0 + attr_rv = self.__get_attr_value(self.psu_current_in_attr) + if (attr_rv != 'ERR'): + attr_rv, dummy = attr_rv.split('.', 1) + current_in = float(attr_rv) / 1000 + + return current_in + def get_power(self): """ Retrieves current energy supplied by PSU @@ -190,9 +241,7 @@ def get_power(self): A float number, the power in watts, e.g. 302.6 """ power_out = 0.0 - attr_path = HWMON_DIR+self.psu_power_out_attr - - attr_rv = self.__get_attr_value(attr_path) + attr_rv = self.__get_attr_value(self.psu_power_out_attr) if (attr_rv != 'ERR'): attr_rv, dummy = attr_rv.split('.', 1) power_out = float(attr_rv) / 1000 @@ -221,3 +270,50 @@ def get_status_led(self): else: return self.STATUS_LED_COLOR_OFF + def get_type(self): + """ + Gets the type of the PSU + + Returns: + A string, the type of PSU (AC/DC) + """ + type = "AC" + attr_rv = self.__get_attr_value(self.psu_type_attr) + if (attr_rv != 'ERR'): + type = attr_rv + + return type + + def get_capacity(self): + """ + Gets the capacity (maximum output power) of the PSU in watts + + Returns: + An integer, the capacity of PSU + """ + capacity = 0 + attr_rv = self.__get_attr_value(self.psu_capacity_attr) + if (attr_rv != 'ERR'): + try: + capacity = int(attr_rv) + except ValueError: + capacity = 0 + + return capacity + + def get_temperature(self): + """ + Retrieves current temperature reading from PSU + Returns: + A float number of current temperature in Celsius up to nearest thousandth + of one degree Celsius, e.g. 30.125 + """ + + tout = 0.0 + attr_rv = self.__get_attr_value(self.psu_temp_attr) + if (attr_rv != 'ERR'): + tout = float(attr_rv) + + # tout is in milli degree celcius + return float(tout/1000.0) + diff --git a/platform/broadcom/sonic-platform-modules-quanta/ix8c-56x/sonic_platform/sfp.py b/platform/broadcom/sonic-platform-modules-quanta/ix8c-56x/sonic_platform/sfp.py index e7d0146b5504..305d78aba4cc 100644 --- a/platform/broadcom/sonic-platform-modules-quanta/ix8c-56x/sonic_platform/sfp.py +++ b/platform/broadcom/sonic-platform-modules-quanta/ix8c-56x/sonic_platform/sfp.py @@ -10,13 +10,10 @@ import os import time -#import subprocess -#import sonic_device_util from ctypes import create_string_buffer try: from sonic_platform_base.sfp_base import SfpBase -# from sonic_platform_base.sonic_eeprom import eeprom_dts from sonic_platform_base.sonic_sfp.sff8472 import sff8472InterfaceId from sonic_platform_base.sonic_sfp.sff8472 import sff8472Dom from sonic_platform_base.sonic_sfp.sff8436 import sff8436InterfaceId @@ -175,7 +172,6 @@ def __init__(self, sfp_index, sfp_type): # Init index self.index = sfp_index self.port_num = self.index - #self.dom_supported = False self.sfp_type = sfp_type # Init eeprom path eeprom_path = '/sys/bus/i2c/devices/i2c-{0}/{0}-0050/eeprom' @@ -284,15 +280,6 @@ def _convert_string_to_num(self, value_str): else: return 'N/A' - def __read_txt_file(self, file_path): - try: - with open(file_path, 'r') as fd: - data = fd.read() - return data.strip() - except IOError: - pass - return "" - def __is_host(self): return os.system(self.HOST_CHK_CMD) == 0 @@ -355,26 +342,6 @@ def __read_eeprom_specific_bytes(self, offset, num_bytes): return eeprom_raw - def __convert_string_to_num(self, value_str): - if "-inf" in value_str: - return 'N/A' - elif "Unknown" in value_str: - return 'N/A' - elif 'dBm' in value_str: - t_str = value_str.rstrip('dBm') - return float(t_str) - elif 'mA' in value_str: - t_str = value_str.rstrip('mA') - return float(t_str) - elif 'C' in value_str: - t_str = value_str.rstrip('C') - return float(t_str) - elif 'Volts' in value_str: - t_str = value_str.rstrip('Volts') - return float(t_str) - else: - return 'N/A' - def _dom_capability_detect(self): if not self.get_presence(): self.dom_supported = False @@ -533,9 +500,7 @@ def get_transceiver_info(self): else: if not self.get_presence(): return transceiver_info_dict - elif i == max_retry-1: - pass - else: + elif i < max_retry-1: time.sleep(0.5) if sfp_interface_bulk_raw is None: @@ -590,7 +555,8 @@ def get_transceiver_info(self): ['data']['Extended Identifier']['value'] transceiver_info_dict['ext_rateselect_compliance'] = sfp_interface_bulk_data \ ['data']['RateIdentifier']['value'] - transceiver_info_dict['type_abbrv_name'] = 'N/A' + transceiver_info_dict['type_abbrv_name'] = sfp_interface_bulk_data \ + ['data']['type_abbrv_name']['value'] if self.sfp_type == QSFP_TYPE: for key in qsfp_cable_length_tup: if key in sfp_interface_bulk_data['data']: @@ -860,7 +826,7 @@ def get_transceiver_threshold_info(self): transceiver_dom_threshold_dict['txbiaslowwarning'] = channel_threshold_data['TxBiasLowWarning']['value'] for key in transceiver_dom_threshold_dict: - transceiver_dom_threshold_dict[key] = self.__convert_string_to_num(transceiver_dom_threshold_dict[key]) + transceiver_dom_threshold_dict[key] = self._convert_string_to_num(transceiver_dom_threshold_dict[key]) return transceiver_dom_threshold_dict @@ -908,7 +874,7 @@ def get_transceiver_threshold_info(self): transceiver_dom_threshold_info_dict['rxpowerlowwarning'] = dom_module_threshold_data['data']['RXPowerLowWarning']['value'] for key in transceiver_dom_threshold_info_dict: - transceiver_dom_threshold_info_dict[key] = self.__convert_string_to_num(transceiver_dom_threshold_info_dict[key]) + transceiver_dom_threshold_info_dict[key] = self._convert_string_to_num(transceiver_dom_threshold_info_dict[key]) return transceiver_dom_threshold_info_dict @@ -1453,7 +1419,7 @@ def tx_disable(self, tx_disable): sysfsfile_eeprom = open( sysfs_sfp_i2c_client_eeprom_path, mode="r+b", buffering=0) buffer = create_string_buffer(1) - buffer[0] = chr(tx_disable_ctl) + buffer[0] = tx_disable_ctl # Write to eeprom sysfsfile_eeprom.seek(offset + SFP_STATUS_CONTROL_OFFSET) sysfsfile_eeprom.write(buffer[0]) @@ -1506,7 +1472,7 @@ def tx_disable_channel(self, channel, disable): else: tx_disable_ctl = channel_state & (~channel) buffer = create_string_buffer(1) - buffer[0] = chr(tx_disable_ctl) + buffer[0] = tx_disable_ctl # Write to eeprom sysfsfile_eeprom = open( self.port_to_eeprom_mapping[self.port_num], "r+b") @@ -1594,7 +1560,7 @@ def set_power_override(self, power_override, power_set): power_set_bit |= 1 << 1 buffer = create_string_buffer(1) - buffer[0] = chr(power_override_bit | power_set_bit) + buffer[0] = power_override_bit | power_set_bit # Write to eeprom sysfsfile_eeprom = open(self.port_to_eeprom_mapping[self.port_num], "r+b") sysfsfile_eeprom.seek(QSFP_POWEROVERRIDE_OFFSET) diff --git a/platform/broadcom/sonic-platform-modules-quanta/ix8c-56x/sonic_platform/thermal.py b/platform/broadcom/sonic-platform-modules-quanta/ix8c-56x/sonic_platform/thermal.py index f30bdc8d71da..11be0f93acc2 100644 --- a/platform/broadcom/sonic-platform-modules-quanta/ix8c-56x/sonic_platform/thermal.py +++ b/platform/broadcom/sonic-platform-modules-quanta/ix8c-56x/sonic_platform/thermal.py @@ -1,7 +1,7 @@ #!/usr/bin/env python ############################################################################# -# Inventec d7264 +# Quanta IX8C # # Module contains an implementation of SONiC Platform Base API and # provides the Thermal information @@ -10,44 +10,68 @@ import logging import os +import glob try: from sonic_platform_base.thermal_base import ThermalBase except ImportError as e: raise ImportError(str(e) + "- required module not found") -HWMON_DIR = "/sys/class/hwmon/hwmon2/" +HWMON_IPMI_DIR = "/sys/devices/platform/quanta_hwmon_ipmi/hwmon/hwmon*/" thermal_index_mapping = { - 1:1, - 2:2, - 3:42, - 4:43, - 5:44, - 6:52, - 7:53, - 8:54, - 9:75, - 10:76, - 11:77, - 12:78, - 13:79, - 14:80, - 15:81, - 16:82, - 17:83, - 18:84, + 1:'PSU1_TEMP1', + 2:'PSU1_TEMP2', + 3:'PSU1_TEMP3', + 4:'PSU2_TEMP1', + 5:'PSU2_TEMP2', + 6:'PSU2_TEMP3', + 7:'Temp_1V05_PCH_VR', + 8:'Temp_Ambient_1', + 9:'Temp_Ambient_2', + 10:'Temp_Ambient_3', + 11:'Temp_Ambient_4', + 12:'Temp_Ambient_6', + 13:'Temp_DDRAB_VR', + 14:'Temp_SOC_DIMMA0', + 15:'Temp_VCCGBE_VR', + 16:'Temp_VCCIN_VR', + 17:'Temp_cpu', + 18:'Temp_switch' } + + class Thermal(ThermalBase): """Platform-specific Thermal class""" def __init__(self, thermal_index): - self.index = thermal_index - self.temp_attr = "temp{}_input".format(thermal_index_mapping[self.index]) - self.high_th_attr = "temp{}_crit".format(thermal_index_mapping[self.index]) - self.name_attr = "temp{}_label".format(thermal_index_mapping[self.index]) + self.index = thermal_index + hwmon_dir=glob.glob(HWMON_IPMI_DIR)[0] + thermal_prefix = self.__get_hwmon_attr_prefix(hwmon_dir, thermal_index_mapping[self.index], 'temp') + self.temp_attr = "{}input".format(thermal_prefix) + self.high_th_attr = "{}ncrit".format(thermal_prefix) + self.high_crit_th_attr = "{}crit".format(thermal_prefix) + self.low_th_attr = "{}lncrit".format(thermal_prefix) + self.low_crit_th_attr = "{}lcrit".format(thermal_prefix) + self.name_attr = "{}label".format(thermal_prefix) + + def __get_hwmon_attr_prefix(self, dir, label, type): + retval = 'ERR' + if not os.path.isdir(dir): + return retval + + try: + for filename in os.listdir(dir): + if filename[-5:] == 'label' and type in filename: + file_path = os.path.join(dir, filename) + if os.path.isfile(file_path) and label == self.__get_attr_value(file_path): + return file_path[0:-5] + except Exception as error: + logging.error("Error when getting {} label path: {}".format(label, error)) + + return retval def __get_attr_value(self, attr_path): @@ -59,7 +83,7 @@ def __get_attr_value(self, attr_path): with open(attr_path, 'r') as fd: retval = fd.read() except Exception as error: - logging.error("Unable to open ", attr_path, " file !") + logging.error("Unable to open {} file: {}".format(attr_path, error)) retval = retval.rstrip(' \t\n\r') return retval @@ -71,8 +95,7 @@ def get_name(self): Returns: string: The name of the device """ - attr_path = HWMON_DIR + self.name_attr - attr_rv = self.__get_attr_value(attr_path) + attr_rv = self.__get_attr_value(self.name_attr) if (attr_rv != 'ERR'): return attr_rv @@ -86,8 +109,7 @@ def get_presence(self): Returns: bool: True if device is present, False if not """ - attr_path = HWMON_DIR + self.name_attr - attr_rv = self.__get_attr_value(attr_path) + attr_rv = self.__get_attr_value(self.name_attr) if (attr_rv != 'ERR'): return True @@ -114,8 +136,37 @@ def get_temperature(self): A float number of current temperature in Celsius up to nearest thousandth of one degree Celsius, e.g. 30.125 """ - attr_path = HWMON_DIR + self.temp_attr - attr_rv = self.__get_attr_value(attr_path) + attr_rv = self.__get_attr_value(self.temp_attr) + + if (attr_rv != 'ERR'): + return float(attr_rv) / 1000 + else: + return None + + def get_low_threshold(self): + """ + Retrieves the low threshold temperature of thermal + + Returns: + A float number, the low threshold temperature of thermal in Celsius + up to nearest thousandth of one degree Celsius, e.g. 30.125 + """ + attr_rv = self.__get_attr_value(self.low_th_attr) + + if (attr_rv != 'ERR'): + return float(attr_rv) / 1000 + else: + return None + + def get_low_critical_threshold(self): + """ + Retrieves the low critical threshold temperature of thermal + + Returns: + A float number, the low critical threshold temperature of thermal in Celsius + up to nearest thousandth of one degree Celsius, e.g. 30.125 + """ + attr_rv = self.__get_attr_value(self.low_crit_th_attr) if (attr_rv != 'ERR'): return float(attr_rv) / 1000 @@ -130,8 +181,22 @@ def get_high_threshold(self): A float number, the high threshold temperature of thermal in Celsius up to nearest thousandth of one degree Celsius, e.g. 30.125 """ - attr_path = HWMON_DIR + self.high_th_attr - attr_rv = self.__get_attr_value(attr_path) + attr_rv = self.__get_attr_value(self.high_th_attr) + + if (attr_rv != 'ERR'): + return float(attr_rv) / 1000 + else: + return None + + def get_high_critical_threshold(self): + """ + Retrieves the high threshold temperature of thermal + + Returns: + A float number, the high threshold temperature of thermal in Celsius + up to nearest thousandth of one degree Celsius, e.g. 30.125 + """ + attr_rv = self.__get_attr_value(self.high_crit_th_attr) if (attr_rv != 'ERR'): return float(attr_rv) / 1000 diff --git a/platform/broadcom/sonic-platform-modules-quanta/ix8c-56x/sonic_platform/watchdog.py b/platform/broadcom/sonic-platform-modules-quanta/ix8c-56x/sonic_platform/watchdog.py new file mode 100644 index 000000000000..0e63d9368cb0 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-quanta/ix8c-56x/sonic_platform/watchdog.py @@ -0,0 +1,241 @@ +#!/usr/bin/env python + +############################################################################# +# +# Watchdog contains an implementation of SONiC Platform Base Watchdog API +# +############################################################################# +import fcntl +import os +import array + +try: + from sonic_platform_base.watchdog_base import WatchdogBase +except ImportError as e: + raise ImportError(str(e) + "- required module not found") + +""" ioctl constants """ +IO_WRITE = 0x40000000 +IO_READ = 0x80000000 +IO_READ_WRITE = 0xC0000000 +IO_SIZE_INT = 0x00040000 +IO_SIZE_40 = 0x00280000 +IO_TYPE_WATCHDOG = ord('W') << 8 + +WDR_INT = IO_READ | IO_SIZE_INT | IO_TYPE_WATCHDOG +WDR_40 = IO_READ | IO_SIZE_40 | IO_TYPE_WATCHDOG +WDWR_INT = IO_READ_WRITE | IO_SIZE_INT | IO_TYPE_WATCHDOG + +""" Watchdog ioctl commands """ +WDIOC_GETSUPPORT = 0 | WDR_40 +WDIOC_GETSTATUS = 1 | WDR_INT +WDIOC_GETBOOTSTATUS = 2 | WDR_INT +WDIOC_GETTEMP = 3 | WDR_INT +WDIOC_SETOPTIONS = 4 | WDR_INT +WDIOC_KEEPALIVE = 5 | WDR_INT +WDIOC_SETTIMEOUT = 6 | WDWR_INT +WDIOC_GETTIMEOUT = 7 | WDR_INT +WDIOC_SETPRETIMEOUT = 8 | WDWR_INT +WDIOC_GETPRETIMEOUT = 9 | WDR_INT +WDIOC_GETTIMELEFT = 10 | WDR_INT + +""" Watchdog status constants """ +WDIOS_DISABLECARD = 0x0001 +WDIOS_ENABLECARD = 0x0002 + +WDT_COMMON_ERROR = -1 +WD_MAIN_IDENTITY = "iTCO_wdt" +WDT_SYSFS_PATH = "/sys/class/watchdog/" + +DEFAULT_TIMEOUT=180 +watchdog=0 + +class Watchdog(WatchdogBase): + + def __init__(self): + + self.watchdog, self.wdt_main_dev_name = self._get_wdt() + if self.wdt_main_dev_name is None: + raise Exception("Watchdog device is not instantiated") + + self.status_path = "/sys/class/watchdog/%s/status" % self.wdt_main_dev_name + self.state_path = "/sys/class/watchdog/%s/state" % self.wdt_main_dev_name + self.timeout_path = "/sys/class/watchdog/%s/timeout" % self.wdt_main_dev_name + # Set default value + self._disable() + self.armed = False + self.timeout = DEFAULT_TIMEOUT + + def _is_wd_main(self, dev): + """ + Checks watchdog identity + """ + identity = self._read_file( + "{}/{}/identity".format(WDT_SYSFS_PATH, dev)) + return identity == WD_MAIN_IDENTITY + + def _get_wdt(self): + """ + Retrieves watchdog device + """ + global watchdog + wdt_main_dev_list = [dev for dev in os.listdir( + "/dev/") if dev.startswith("watchdog") and self._is_wd_main(dev)] + if not wdt_main_dev_list: + return (None, None) + wdt_main_dev_name = wdt_main_dev_list[0] + watchdog_device_path = "/dev/{}".format(wdt_main_dev_name) + if not watchdog: + watchdog = os.open(watchdog_device_path, os.O_RDWR) + return watchdog, wdt_main_dev_name + + def _read_file(self, file_path): + """ + Read text file + """ + try: + with open(file_path, "r") as fd: + txt = fd.read() + except IOError: + return WDT_COMMON_ERROR + return txt.strip() + + def _enable(self): + """ + Turn on the watchdog timer + """ + req = array.array('h', [WDIOS_ENABLECARD]) + fcntl.ioctl(self.watchdog, WDIOC_SETOPTIONS, req, False) + + def _disable(self): + """ + Turn off the watchdog timer + """ + req = array.array('h', [WDIOS_DISABLECARD]) + fcntl.ioctl(self.watchdog, WDIOC_SETOPTIONS, req, False) + + def _keepalive(self): + """ + Keep alive watchdog timer + """ + fcntl.ioctl(self.watchdog, WDIOC_KEEPALIVE) + + def _settimeout(self, seconds): + """ + Set watchdog timer timeout + @param seconds - timeout in seconds + @return is the actual set timeout + """ + req = array.array('I', [seconds]) + fcntl.ioctl(self.watchdog, WDIOC_SETTIMEOUT, req, True) + return int(req[0]) + + def _gettimeout(self, timeout_path): + """ + Get watchdog timeout + @return watchdog timeout + """ + req = array.array('I', [0]) + fcntl.ioctl(self.watchdog, WDIOC_GETTIMEOUT, req, True) + + return int(req[0]) + + def _gettimeleft(self): + """ + Get time left before watchdog timer expires + @return time left in seconds + """ + req = array.array('I', [0]) + fcntl.ioctl(self.watchdog, WDIOC_GETTIMELEFT, req, True) + + return int(req[0]) + + ################################################################# + + def arm(self, seconds): + """ + Arm the hardware watchdog with a timeout of seconds. + If the watchdog is currently armed, calling this function will + simply reset the timer to the provided value. If the underlying + hardware does not support the value provided in , this + method should arm the watchdog with the *next greater* available + value. + Returns: + An integer specifying the *actual* number of seconds the watchdog + was armed with. On failure returns -1. + """ + + ret = WDT_COMMON_ERROR + if seconds < 0: + return ret + + try: + if self.timeout != seconds: + self.timeout = self._settimeout(seconds) + if self.armed: + self._keepalive() + else: + self._settimeout(seconds) + self._enable() + self.armed = True + ret = self.timeout + except IOError as e: + pass + + return ret + + def disarm(self): + """ + Disarm the hardware watchdog + Returns: + A boolean, True if watchdog is disarmed successfully, False if not + """ + disarmed = False + if self.is_armed(): + try: + self._disable() + self.armed = False + disarmed = True + except IOError: + pass + + return disarmed + + def is_armed(self): + """ + Retrieves the armed state of the hardware watchdog. + Returns: + A boolean, True if watchdog is armed, False if not + """ + + return self.armed + + def get_remaining_time(self): + """ + If the watchdog is armed, retrieve the number of seconds remaining on + the watchdog timer + Returns: + An integer specifying the number of seconds remaining on thei + watchdog timer. If the watchdog is not armed, returns -1. + """ + + timeleft = WDT_COMMON_ERROR + + if self.armed: + try: + timeleft = self._gettimeleft() + except IOError: + pass + + return timeleft + + def __del__(self): + """ + Close watchdog + """ + + if self.watchdog is not None : + os.close(self.watchdog) + + + diff --git a/platform/broadcom/sonic-platform-modules-quanta/ix8c-56x/utils/quanta_ix8c_util.py b/platform/broadcom/sonic-platform-modules-quanta/ix8c-56x/utils/quanta_ix8c_util.py index f8e8b0f0f96b..a7e50d908fe4 100755 --- a/platform/broadcom/sonic-platform-modules-quanta/ix8c-56x/utils/quanta_ix8c_util.py +++ b/platform/broadcom/sonic-platform-modules-quanta/ix8c-56x/utils/quanta_ix8c_util.py @@ -28,7 +28,7 @@ """ import os -import commands +import subprocess import sys, getopt import logging import time @@ -39,8 +39,8 @@ i2c_prefix = '/sys/bus/i2c/devices/' if DEBUG == True: - print sys.argv[0] - print 'ARGV :', sys.argv[1:] + print(sys.argv[0]) + print('ARGV :', sys.argv[1:]) def main(): global DEBUG @@ -55,9 +55,9 @@ def main(): 'force', ]) if DEBUG == True: - print options - print args - print len(sys.argv) + print(options) + print(args) + print(len(sys.argv)) for opt, arg in options: if opt in ('-h', '--help'): @@ -71,34 +71,45 @@ def main(): logging.info('no option') for arg in args: if arg == 'install': - install() + install() elif arg == 'clean': - uninstall() + uninstall() else: show_help() - return 0 def show_help(): - print __doc__ % {'scriptName' : sys.argv[0].split("/")[-1]} + print(__doc__ % {'scriptName' : sys.argv[0].split("/")[-1]}) sys.exit(0) def show_log(txt): if DEBUG == True: - print "[IX8C-56X]"+txt + print("[IX8C-56X]" + txt) return def exec_cmd(cmd, show): - logging.info('Run :'+cmd) - status, output = commands.getstatusoutput(cmd) + logging.info('Run :' + cmd) + status, output = subprocess.getstatusoutput(cmd) show_log (cmd +"with result:" + str(status)) - show_log (" output:"+output) + show_log (" output:" + output) if status: - logging.info('Failed :'+cmd) + logging.info('Failed :' + cmd) if show: - print('Failed :'+cmd) - return status, output + print('Failed :' + cmd) + return status, output + +pca954x_bus_addr =[ +'0-0072', +'0-0077', +'5-0073', +'6-0073', +'7-0073', +'8-0073', +'9-0073', +'10-0073', +'11-0073' +] instantiate =[ #export pca9698 for qsfp present @@ -201,7 +212,7 @@ def exec_cmd(cmd, show): 'lpc_ich', 'i2c-i801', 'i2c-dev', -'i2c-mux-pca954x force_deselect_on_exit=1', +'i2c-mux-pca954x', 'gpio-pca953x', 'optoe', 'qci_cpld_sfp28', @@ -232,11 +243,20 @@ def system_install(): exec_cmd("depmod -a ", 1) #install drivers for i in range(0,len(drivers)): - status, output = exec_cmd("modprobe " + drivers[i], 1) - if status: - print output - if FORCE == 0: - return status + status, output = exec_cmd("modprobe " + drivers[i], 1) + if status: + print(output) + #retry quanta_hwmon_ipmi in case it init failed due to ipmi_msghandler init uncompleted + if drivers[i] == 'quanta_hwmon_ipmi': + for _ in range(0, 3): + time.sleep(3) + ret, out = exec_cmd("modprobe quanta_hwmon_ipmi ", 1) + if ret == 0: + break + if ret and FORCE == 0: + return ret + elif FORCE == 0: + return status #reload ethernet drivers in correct order exec_cmd("rmmod ixgbe ", 1) @@ -244,6 +264,10 @@ def system_install(): exec_cmd("modprobe igb ", 1) exec_cmd("modprobe ixgbe ", 1) + # set pca954x idle_state as -2: MUX_IDLE_DISCONNECT + for i in range(0,len(pca954x_bus_addr)): + exec_cmd("echo -2 > /sys/bus/i2c/drivers/pca954x/{}/idle_state".format(pca954x_bus_addr[i]), 1) + #turn on module power exec_cmd("echo 21 > /sys/class/gpio/export ", 1) exec_cmd("echo high > /sys/class/gpio/gpio21/direction ", 1) @@ -263,15 +287,15 @@ def system_install(): exec_cmd("echo 1 >/sys/class/gpio/gpio73/value", 1) #instantiate devices - for i in range(0,len(instantiate)): - status, output = exec_cmd(instantiate[i], 1) - if status: - print output - if FORCE == 0: - return status + for i in range(0, len(instantiate)): + status, output = exec_cmd(instantiate[i], 1) + if status: + print(output) + if FORCE == 0: + return status #QSFP for 1~56 port - for port_number in range(1,57): + for port_number in range(1, 57): bus_number = port_number + 12 os.system("echo %d >/sys/bus/i2c/devices/%d-0050/port_name" % (port_number, bus_number)) @@ -285,35 +309,35 @@ def system_ready(): def install(): if not device_found(): - print "No device, installing...." + print("No device, installing....") status = system_install() if status: if FORCE == 0: - return status + return status status, output = exec_cmd("pip3 install /usr/share/sonic/device/x86_64-quanta_ix8c_bwde-r0/sonic_platform-1.0-py3-none-any.whl",1) if status: - print output - if FORCE == 0: - return status + print(output) + if FORCE == 0: + return status else: - print " ix8c driver already installed...." + print(" ix8c driver already installed....") return def uninstall(): global FORCE #uninstall drivers for i in range(len(un_drivers) - 1, -1, -1): - status, output = exec_cmd("rmmod " + un_drivers[i], 1) + status, output = exec_cmd("rmmod " + un_drivers[i], 1) if status: - print output - if FORCE == 0: - return status + print(output) + if FORCE == 0: + return status status, output = exec_cmd("pip3 uninstall sonic-platform -y ",1) if status: - print output - if FORCE == 0: - return status + print(output) + if FORCE == 0: + return status return diff --git a/platform/broadcom/sonic-platform-modules-quanta/ix9-32x/modules/qci_cpld_led.c b/platform/broadcom/sonic-platform-modules-quanta/ix9-32x/modules/qci_cpld_led.c index fdbc6c6c1634..0f0ad02be895 100644 --- a/platform/broadcom/sonic-platform-modules-quanta/ix9-32x/modules/qci_cpld_led.c +++ b/platform/broadcom/sonic-platform-modules-quanta/ix9-32x/modules/qci_cpld_led.c @@ -51,7 +51,7 @@ static struct class *cpld_class = NULL; struct cpld_data { struct i2c_client *cpld_client; - char name[8]; + char name[16]; u8 cpld_id; }; diff --git a/platform/broadcom/sonic-platform-modules-quanta/ix9-32x/modules/qci_platform_ix9.c b/platform/broadcom/sonic-platform-modules-quanta/ix9-32x/modules/qci_platform_ix9.c index 803b2b42f495..c243bd5d5794 100644 --- a/platform/broadcom/sonic-platform-modules-quanta/ix9-32x/modules/qci_platform_ix9.c +++ b/platform/broadcom/sonic-platform-modules-quanta/ix9-32x/modules/qci_platform_ix9.c @@ -141,9 +141,9 @@ static int __init ix9_platform_init(void) } else { - g_client[0] = i2c_new_device(adapter, &ix9_i2c_devices[0]); // pca9546_1 - Address: 0x72 - g_client[1] = i2c_new_device(adapter, &ix9_i2c_devices[1]); // pca9548_1 - Address: 0x77 - g_client[2] = i2c_new_device(adapter, &ix9_i2c_devices[11]); // CPU Linking Board at CPU's I2C Bus - Address: 0x22 + g_client[0] = i2c_new_client_device(adapter, &ix9_i2c_devices[0]); // pca9546_1 - Address: 0x72 + g_client[1] = i2c_new_client_device(adapter, &ix9_i2c_devices[1]); // pca9548_1 - Address: 0x77 + g_client[2] = i2c_new_client_device(adapter, &ix9_i2c_devices[11]); // CPU Linking Board at CPU's I2C Bus - Address: 0x22 i2c_put_adapter(adapter); } @@ -154,8 +154,8 @@ static int __init ix9_platform_init(void) } else { - g_client[3] = i2c_new_device(adapter, &ix9_i2c_devices[8]); // CPLD-IO #2 - Address: 0x38 - g_client[4] = i2c_new_device(adapter, &ix9_i2c_devices[9]); // CPLD-LED #4 - Address: 0x39 + g_client[3] = i2c_new_client_device(adapter, &ix9_i2c_devices[8]); // CPLD-IO #2 - Address: 0x38 + g_client[4] = i2c_new_client_device(adapter, &ix9_i2c_devices[9]); // CPLD-LED #4 - Address: 0x39 i2c_put_adapter(adapter); } @@ -166,8 +166,8 @@ static int __init ix9_platform_init(void) } else { - g_client[5] = i2c_new_device(adapter, &ix9_i2c_devices[8]); // CPLD-IO #3 - Address: 0x38 - g_client[6] = i2c_new_device(adapter, &ix9_i2c_devices[9]); // CPLD-LED #5 - Address: 0x39 + g_client[5] = i2c_new_client_device(adapter, &ix9_i2c_devices[8]); // CPLD-IO #3 - Address: 0x38 + g_client[6] = i2c_new_client_device(adapter, &ix9_i2c_devices[9]); // CPLD-LED #5 - Address: 0x39 i2c_put_adapter(adapter); } @@ -178,7 +178,7 @@ static int __init ix9_platform_init(void) } else { - g_client[7] = i2c_new_device(adapter, &ix9_i2c_devices[3]); // MB_BOARDINFO_EEPROM - Address: 0x54 + g_client[7] = i2c_new_client_device(adapter, &ix9_i2c_devices[3]); // MB_BOARDINFO_EEPROM - Address: 0x54 i2c_put_adapter(adapter); } @@ -189,7 +189,7 @@ static int __init ix9_platform_init(void) } else { - g_client[8] = i2c_new_device(adapter, &ix9_i2c_devices[2]); // tca9539_1 Board ID and QSFP-DD PW EN/PG - Address: 0x74 + g_client[8] = i2c_new_client_device(adapter, &ix9_i2c_devices[2]); // tca9539_1 Board ID and QSFP-DD PW EN/PG - Address: 0x74 i2c_put_adapter(adapter); } @@ -200,7 +200,7 @@ static int __init ix9_platform_init(void) } else { - g_client[9] = i2c_new_device(adapter, &ix9_i2c_devices[4]); // pca9548 #1 QSFPDD - Address: 0x73 + g_client[9] = i2c_new_client_device(adapter, &ix9_i2c_devices[4]); // pca9548 #1 QSFPDD - Address: 0x73 i2c_put_adapter(adapter); } @@ -211,7 +211,7 @@ static int __init ix9_platform_init(void) } else { - g_client[10] = i2c_new_device(adapter, &ix9_i2c_devices[5]); // pca9548 #2 QSFPDD - Address: 0x73 + g_client[10] = i2c_new_client_device(adapter, &ix9_i2c_devices[5]); // pca9548 #2 QSFPDD - Address: 0x73 i2c_put_adapter(adapter); } @@ -222,7 +222,7 @@ static int __init ix9_platform_init(void) } else { - g_client[11] = i2c_new_device(adapter, &ix9_i2c_devices[6]); // pca9548 #3 QSFPDD - Address: 0x73 + g_client[11] = i2c_new_client_device(adapter, &ix9_i2c_devices[6]); // pca9548 #3 QSFPDD - Address: 0x73 i2c_put_adapter(adapter); } @@ -233,7 +233,7 @@ static int __init ix9_platform_init(void) } else { - g_client[12] = i2c_new_device(adapter, &ix9_i2c_devices[7]); // pca9548 #4 QSFPDD - Address: 0x73 + g_client[12] = i2c_new_client_device(adapter, &ix9_i2c_devices[7]); // pca9548 #4 QSFPDD - Address: 0x73 i2c_put_adapter(adapter); } @@ -246,7 +246,7 @@ static int __init ix9_platform_init(void) } else { - g_client_port[i - 13] = i2c_new_device(adapter, &ix9_i2c_devices[10]); // eeprom for loopback module - Address: 0x50 + g_client_port[i - 13] = i2c_new_client_device(adapter, &ix9_i2c_devices[10]); // eeprom for loopback module - Address: 0x50 i2c_put_adapter(adapter); } } diff --git a/platform/broadcom/sonic-platform-modules-quanta/ix9-32x/modules/quanta_hwmon_ipmi.c b/platform/broadcom/sonic-platform-modules-quanta/ix9-32x/modules/quanta_hwmon_ipmi.c index 05a9e044c75b..d49ca44856be 100644 --- a/platform/broadcom/sonic-platform-modules-quanta/ix9-32x/modules/quanta_hwmon_ipmi.c +++ b/platform/broadcom/sonic-platform-modules-quanta/ix9-32x/modules/quanta_hwmon_ipmi.c @@ -86,6 +86,8 @@ #define IPMI_TIMEOUT (4 * HZ) #define IPMI_MAX_WAIT_QUEUE 1 +typedef struct ipmi_user *ipmi_user_t; + struct quanta_hwmon_ipmi_data { struct platform_device *ipmi_platform_dev; struct device *ipmi_hwmon_dev; @@ -839,7 +841,7 @@ void ipmi_sdr_set_sensor_threshold(uint8_t idx, struct sdr_record_full_sensor *s /*refer to Table 35-, Get Sensor Event Enable*/ /* // change detect threshold method, keep it for record detail format - // in this version function input is + // in this version function input is "void ipmi_sdr_set_sensor_threshold(uint8_t idx, uint8_t *rec)" #define offset_threshold_enable 9 #define offset_threshold_data 31 @@ -1100,7 +1102,7 @@ int32_t ipmi_get_vin_type(uint8_t idx, uint8_t *retbuf) if (rv) { printk("BMC down at (%d)!!\n", __LINE__); } - else { + else { switch (returnData) { case 0x7: //LVDC @@ -1338,7 +1340,7 @@ static ssize_t show_fanpresent(struct device *dev, struct device_attribute *deva uint8_t returnData[10] = { 0 }; uint8_t msg_data[] = { 0x36, 0xB9, 0x4C, 0x1C, 0x00, 0x02 }; //netfn = 0x36; cmd = 0xB9; - struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); + struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); fan_idx = (g_sensor_data[attr->index].sensor_idstring[8] - '0') - 1; @@ -1611,7 +1613,7 @@ static int32_t __init quanta_hwmon_ipmi_init(void) goto device_reg_err; } - data->ipmi_hwmon_dev = hwmon_device_register_with_groups(NULL, DRVNAME, NULL, NULL); + data->ipmi_hwmon_dev = hwmon_device_register_with_groups(&data->ipmi_platform_dev->dev, DRVNAME, NULL, NULL); err = IS_ERR(data->ipmi_hwmon_dev); if (err) { printk("hwmon register fail\n"); @@ -1646,7 +1648,7 @@ static int32_t __init quanta_hwmon_ipmi_init(void) } static void __exit quanta_hwmon_ipmi_exit(void) -{ +{ remove_sensor_attrs(); hwmon_device_unregister(data->ipmi_hwmon_dev); platform_device_unregister(data->ipmi_platform_dev); @@ -1656,8 +1658,9 @@ static void __exit quanta_hwmon_ipmi_exit(void) mutex_unlock(&ipmi_lock); kfree(g_sensor_data); + g_sensor_data = NULL; kfree(data); - return; + data = NULL; } module_init(quanta_hwmon_ipmi_init); diff --git a/platform/broadcom/sonic-platform-modules-quanta/ix9-32x/sonic_platform/chassis.py b/platform/broadcom/sonic-platform-modules-quanta/ix9-32x/sonic_platform/chassis.py index 33f67b0b9d90..6a8b760f3762 100644 --- a/platform/broadcom/sonic-platform-modules-quanta/ix9-32x/sonic_platform/chassis.py +++ b/platform/broadcom/sonic-platform-modules-quanta/ix9-32x/sonic_platform/chassis.py @@ -8,6 +8,7 @@ try: import sys import time + import syslog from sonic_platform_base.chassis_base import ChassisBase from sonic_platform.eeprom import Eeprom from sonic_platform.psu import Psu @@ -64,6 +65,12 @@ def __init__(self): self._sfp_list.append(sfp) self.__xcvr_presence[index] = self._sfp_list[index-1].get_presence() + # Initialize components + from sonic_platform.component import ComponentBIOS, ComponentBMC, ComponentCPLD, ComponentPCIE + self._component_list.append(ComponentBIOS()) + self._component_list.append(ComponentBMC()) + self._component_list.extend(ComponentCPLD.get_component_list()) + self._component_list.append(ComponentPCIE()) ############################################## # Device methods @@ -72,7 +79,7 @@ def __init__(self): def get_sfp(self, index): """ Retrieves sfp represented by (1-based) index - For Quanta IX8C the index in sfputil.py starts from 1, so override + For Quanta the index in sfputil.py starts from 1, so override Args: index: An integer, the index (1-based) of the sfp to retrieve. @@ -182,9 +189,29 @@ def get_reboot_cause(self): is "REBOOT_CAUSE_HARDWARE_OTHER", the second string can be used to pass a description of the reboot cause. """ - #raise NotImplementedError return (ChassisBase.REBOOT_CAUSE_HARDWARE_OTHER, "Invalid Reason") + ############################################## + # Other methods + ############################################## + def get_watchdog(self): + """ + Retreives hardware watchdog device on this chassis + + Returns: + An object derived from WatchdogBase representing the hardware + watchdog device + """ + try: + if self._watchdog is None: + from sonic_platform.watchdog import Watchdog + # Create the watchdog Instance + self._watchdog = Watchdog() + + except Exception as e: + syslog.syslog(syslog.LOG_ERR, "Fail to load watchdog due to {}".format(e)) + return self._watchdog + def get_change_event(self, timeout=0): """ Currently only support transceiver change events @@ -200,10 +227,10 @@ def get_change_event(self, timeout=0): cur_xcvr_presence = self._sfp_list[index-1].get_presence() if cur_xcvr_presence != self.__xcvr_presence[index]: if cur_xcvr_presence is True: - xcvr_change_event_dict[str(index)] = '1' + xcvr_change_event_dict[index] = '1' self.__xcvr_presence[index] = True elif cur_xcvr_presence is False: - xcvr_change_event_dict[str(index)] = '0' + xcvr_change_event_dict[index] = '0' self.__xcvr_presence[index] = False event = True diff --git a/platform/broadcom/sonic-platform-modules-quanta/ix9-32x/sonic_platform/component.py b/platform/broadcom/sonic-platform-modules-quanta/ix9-32x/sonic_platform/component.py new file mode 100644 index 000000000000..49d25f31cbcc --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-quanta/ix9-32x/sonic_platform/component.py @@ -0,0 +1,203 @@ +#!/usr/bin/env python + +######################################################################## +# Quanta IX9 +# +# Name: component.py, version: 1.3 +# Module contains an implementation of SONiC Platform Base API and +# provides the Components' (e.g., BIOS, CPLD, FPGA, etc.) available in +# the platform +# +######################################################################## + +try: + import subprocess + from sonic_platform_base.component_base import ComponentBase + from collections import namedtuple +except ImportError as e: + raise ImportError(str(e) + "- required module not found") + + +class Component(ComponentBase): + def __init__(self): + ComponentBase.__init__(self) + self.name = None + self.description = None + + def get_name(self): + return self.name + + def get_description(self): + return self.description + + def install_firmware(self, image_path): + """ + Installs firmware to the component + + Args: + image_path: A string, path to firmware image + + Returns: + A boolean, True if install was successful, False if not + """ + return False + + @staticmethod + def _get_command_result(cmdline): + try: + proc = subprocess.Popen(cmdline, + stdout=subprocess.PIPE, + shell=True, stderr=subprocess.STDOUT, + universal_newlines=True) + stdout = proc.communicate()[0] + rc = proc.wait() + result = stdout.rstrip('\n') + if rc != 0: + raise RuntimeError("Failed to execute command {}, return code {}, {}".format(cmdline, rc, stdout)) + + except OSError as e: + raise RuntimeError("Failed to execute command {} due to {}".format(cmdline, repr(e))) + + return result + + +class ComponentBIOS(Component): + COMPONENT_NAME = 'BIOS' + COMPONENT_DESCRIPTION = 'BIOS - Basic Input/Output System' + + BIOS_QUERY_VERSION_COMMAND = "dmidecode -s bios-version" + + def __init__(self): + super(ComponentBIOS, self).__init__() + + self.name = self.COMPONENT_NAME + self.description = self.COMPONENT_DESCRIPTION + + def get_firmware_version(self): + """ + Retrieves the firmware version of the component + + Returns: + A string containing the firmware version of the component + """ + bios_ver = self._get_command_result(self.BIOS_QUERY_VERSION_COMMAND) + if not bios_ver: + return 'ERR' + else: + return bios_ver + + +class ComponentBMC(Component): + COMPONENT_NAME = 'BMC' + COMPONENT_DESCRIPTION = 'BMC - Board Management Controller' + BMC_QUERY_VERSION_COMMAND = "ipmitool mc info | grep 'Firmware Revision'" + + def __init__(self): + super(ComponentBMC, self).__init__() + + self.name = self.COMPONENT_NAME + self.description = self.COMPONENT_DESCRIPTION + + def get_firmware_version(self): + """ + Retrieves the firmware version of the component + + Returns: + A string containing the firmware version of the component + """ + bmc_ver = self._get_command_result(self.BMC_QUERY_VERSION_COMMAND) + if not bmc_ver: + return 'ERR' + else: + bmc_ver = bmc_ver.split(": ")[1] + return bmc_ver.strip() + + +class ComponentCPLD(Component): + Cpld = namedtuple("Cpld", ['name', 'cmd_index', 'description']) + + cplds = { + 1: Cpld("BOOT_CPLD", 1, "Power sequence"), + 2: Cpld("FAN_CPLD", 2, "Fan"), + 3: Cpld("MB_CPLD_IO_1", 3, "Port IO-1"), + 4: Cpld("MB_CPLD_IO_2", 6, "Port IO-2"), + 5: Cpld("MB_CPLD_LED_1", 4, "Port LED-1"), + 6: Cpld("MB_CPLD_LED_2", 5, "Port LED-2"), + } + + def __init__(self, component_index): + super(ComponentCPLD, self).__init__() + self.index = component_index + + def get_name(self): + """ + Retrieves the name of the component + + Returns: + A string containing the name of the component + """ + self.name = self.cplds[self.index].name + + return self.name + + def get_description(self): + """ + Retrieves the description of the component + + Returns: + A string containing the description of the component + """ + self.description = self.cplds[self.index].description + + return self.description + + def get_firmware_version(self): + """ + Retrieves the firmware version of the component + + Returns: + A string containing the firmware version of the component + """ + self._get_command_result("ipmitool raw 0x30 0xe0 0xd0 0x01 0x01") + res = self._get_command_result("ipmitool raw 0x32 0xff 0x02 {}".format(self.cplds[self.index].cmd_index)) + self._get_command_result("ipmitool raw 0x30 0xe0 0xd0 0x01 0x00") + if not res: + return 'ERR' + else: + return res.split()[3].upper() + res.split()[2].upper() + res.split()[1].upper() + res.split()[0].upper() + + @classmethod + def get_component_list(cls): + component_list = [] + cpld_number = len(cls.cplds) + + for cpld_idx in range(1, cpld_number + 1): + component_list.append(cls(cpld_idx)) + + return component_list + + +class ComponentPCIE(Component): + COMPONENT_NAME = 'PCIe' + COMPONENT_DESCRIPTION = 'ASIC PCIe Firmware' + PCIE_QUERY_VERSION_COMMAND = "bcmcmd 'pciephy fw version' | grep 'FW version'" + + def __init__(self): + super(ComponentPCIE, self).__init__() + + self.name = self.COMPONENT_NAME + self.description = self.COMPONENT_DESCRIPTION + + def get_firmware_version(self): + """ + Retrieves the firmware version of the component + + Returns: + A string containing the firmware version of the component + """ + version = self._get_command_result(self.PCIE_QUERY_VERSION_COMMAND) + if not version: + return 'ERR' + else: + version = version.split(": ")[1] + return version.strip() diff --git a/platform/broadcom/sonic-platform-modules-quanta/ix9-32x/sonic_platform/fan.py b/platform/broadcom/sonic-platform-modules-quanta/ix9-32x/sonic_platform/fan.py index e668013df900..7b63aa3aed58 100644 --- a/platform/broadcom/sonic-platform-modules-quanta/ix9-32x/sonic_platform/fan.py +++ b/platform/broadcom/sonic-platform-modules-quanta/ix9-32x/sonic_platform/fan.py @@ -11,6 +11,7 @@ try: import logging import os + import glob from sonic_platform_base.fan_base import FanBase except ImportError as e: raise ImportError(str(e) + "- required module not found") @@ -19,9 +20,7 @@ ############### # Global ############### -HWMON_DIR = "/sys/class/hwmon/hwmon2/" -FAN_INDEX_START = 18 -NUM_FANTRAYS = 6 +HWMON_IPMI_DIR = "/sys/devices/platform/quanta_hwmon_ipmi/hwmon/hwmon*/" FANS_PERTRAY = 2 class Fan(FanBase): @@ -30,30 +29,46 @@ class Fan(FanBase): def __init__(self, index, is_psu_fan=False): self.is_psu_fan = is_psu_fan self.fan_index = index - self.psu_fan_index_mapping = { - 1:37, - 2:47, - } - self.psu_index_mapping = { - 1:39, - 2:49, - } + hwmon_dir=glob.glob(HWMON_IPMI_DIR)[0] + if self.is_psu_fan: - self.fan_presence_attr = "power{}_present".format(self.psu_index_mapping[index]) - self.fan_pwm_attr = "fan{}_pwm".format(self.psu_fan_index_mapping[index]) - self.fan_rpm_attr = "fan{}_input".format(self.psu_fan_index_mapping[index]) - self.fan_direction_attr = "fan{}_direction".format(self.psu_fan_index_mapping[index]) + power_out_prefix = self.__get_hwmon_attr_prefix(hwmon_dir, "PSU{}_POWER_OUT".format(self.fan_index), 'power') + fan_prefix = self.__get_hwmon_attr_prefix(hwmon_dir, "PSU{}_Fan".format(self.fan_index), 'fan') + self.fan_presence_attr = power_out_prefix + 'present' + self.fan_pwm_attr = fan_prefix + 'pwm' + self.fan_rpm_attr = fan_prefix + 'input' + self.fan_direction_attr = fan_prefix + 'direction' else: - self.fan_presence_attr = "fan{}_present".format(FAN_INDEX_START+(index-1)) - self.fan_pwm_attr = "fan{}_pwm".format(FAN_INDEX_START+(index-1)) - self.fan_rpm_attr = "fan{}_input".format(FAN_INDEX_START+(index-1)) - self.fan_direction_attr = "fan{}_direction".format(FAN_INDEX_START+(index-1)) + fantray_index = (self.fan_index-1)//FANS_PERTRAY+1 + fan_index_intray = self.fan_index - ((fantray_index-1)*FANS_PERTRAY) + fan_prefix = self.__get_hwmon_attr_prefix(hwmon_dir, "Fan_SYS_{}_{}".format(fantray_index, fan_index_intray), 'fan') + self.fan_presence_attr = fan_prefix + 'present' + self.fan_pwm_attr = fan_prefix + 'pwm' + self.fan_rpm_attr = fan_prefix + 'input' + self.fan_direction_attr = fan_prefix + 'direction' ####################### # private function ####################### + def __get_hwmon_attr_prefix(self, dir, label, type): + + retval = 'ERR' + if not os.path.isdir(dir): + return retval + + try: + for filename in os.listdir(dir): + if filename[-5:] == 'label' and type in filename: + file_path = os.path.join(dir, filename) + if os.path.isfile(file_path) and label == self.__get_attr_value(file_path): + return file_path[0:-5] + except Exception as error: + logging.error("Error when getting {} label path: {}".format(label, error)) + + return retval + def __get_attr_value(self, attr_path): retval = 'ERR' @@ -64,7 +79,7 @@ def __get_attr_value(self, attr_path): with open(attr_path, 'r') as fd: retval = fd.read() except Exception as error: - logging.error("Unable to open " + attr_path + " file !") + logging.error("Unable to open {} file: {}".format(attr_path, error)) retval = retval.rstrip(' \t\n\r') return retval @@ -84,7 +99,7 @@ def get_name(self): if self.is_psu_fan: return "PSU-{}_FAN".format(self.fan_index) else: - fantray_index = (self.fan_index-1)/FANS_PERTRAY+1 + fantray_index = (self.fan_index-1)//FANS_PERTRAY+1 fan_index_intray = self.fan_index - ((fantray_index-1)*FANS_PERTRAY) return "Fantray{}_{}".format(fantray_index, fan_index_intray) @@ -95,8 +110,7 @@ def get_presence(self): Returns: bool: True if device is present, False if not """ - attr_path = HWMON_DIR + self.fan_presence_attr - attr_rv = self.__get_attr_value(attr_path) + attr_rv = self.__get_attr_value(self.fan_presence_attr) if (attr_rv != 'ERR'): if (attr_rv == '1'): return True @@ -113,8 +127,7 @@ def get_status(self): A boolean value, True if device is operating properly, False if not """ if self.get_presence(): - attr_path = HWMON_DIR + self.fan_rpm_attr - attr_rv = self.__get_attr_value(attr_path) + attr_rv = self.__get_attr_value(self.fan_rpm_attr) if (attr_rv != 'ERR' and attr_rv != '0.0'): return True @@ -135,8 +148,7 @@ def get_direction(self): A string, either FAN_DIRECTION_INTAKE or FAN_DIRECTION_EXHAUST depending on fan direction """ - attr_path = HWMON_DIR + self.fan_direction_attr - attr_rv = self.__get_attr_value(attr_path) + attr_rv = self.__get_attr_value(self.fan_direction_attr) if attr_rv == '2': return self.FAN_DIRECTION_INTAKE @@ -152,8 +164,7 @@ def get_speed(self): to 100 (full speed) """ if self.get_presence(): - attr_path = HWMON_DIR + self.fan_pwm_attr - attr_rv = self.__get_attr_value(attr_path) + attr_rv = self.__get_attr_value(self.fan_pwm_attr) if (attr_rv != 'ERR'): return int(float(attr_rv)) @@ -169,8 +180,7 @@ def get_speed_rpm(self): Returns: An integer, speed of the fan in RPM """ - attr_path = HWMON_DIR + self.fan_rpm_attr - attr_rv = self.__get_attr_value(attr_path) + attr_rv = self.__get_attr_value(self.fan_rpm_attr) if (attr_rv != 'ERR'): return int(float(attr_rv)) @@ -185,8 +195,7 @@ def get_target_speed(self): An integer, the percentage of full fan speed, in the range 0 (off) to 100 (full speed) """ - attr_path = HWMON_DIR + self.fan_pwm_attr - attr_rv = self.__get_attr_value(attr_path) + attr_rv = self.__get_attr_value(self.fan_pwm_attr) if (attr_rv != 'ERR'): return int(float(attr_rv)) diff --git a/platform/broadcom/sonic-platform-modules-quanta/ix9-32x/sonic_platform/fan_drawer.py b/platform/broadcom/sonic-platform-modules-quanta/ix9-32x/sonic_platform/fan_drawer.py index 75e954576a28..3d5f767477ee 100644 --- a/platform/broadcom/sonic-platform-modules-quanta/ix9-32x/sonic_platform/fan_drawer.py +++ b/platform/broadcom/sonic-platform-modules-quanta/ix9-32x/sonic_platform/fan_drawer.py @@ -28,7 +28,7 @@ def get_name(self): Returns: string: The name of the device """ - return 'Fan {}'.format(self._index) + return 'Fantray{}'.format(self._index) def get_presence(self): """ diff --git a/platform/broadcom/sonic-platform-modules-quanta/ix9-32x/sonic_platform/psu.py b/platform/broadcom/sonic-platform-modules-quanta/ix9-32x/sonic_platform/psu.py index 1043a4fe1857..6188c95c7692 100644 --- a/platform/broadcom/sonic-platform-modules-quanta/ix9-32x/sonic_platform/psu.py +++ b/platform/broadcom/sonic-platform-modules-quanta/ix9-32x/sonic_platform/psu.py @@ -8,57 +8,61 @@ try: import logging import os + import glob from sonic_platform_base.psu_base import PsuBase from sonic_platform.fan import Fan except ImportError as e: raise ImportError(str(e) + "- required module not found") -HWMON_DIR = "/sys/class/hwmon/hwmon2/" +HWMON_IPMI_DIR = "/sys/devices/platform/quanta_hwmon_ipmi/hwmon/hwmon*/" class Psu(PsuBase): def __init__(self, index): PsuBase.__init__(self) fan = Fan(index, True) self._fan_list.append(fan) + self.index = index + hwmon_dir=glob.glob(HWMON_IPMI_DIR)[0] + + current_in_prefix = self.__get_hwmon_attr_prefix(hwmon_dir, "PSU{}_CURRENT_IN".format(self.index), 'curr') + current_out_prefix = self.__get_hwmon_attr_prefix(hwmon_dir, "PSU{}_CURRENT_OUT".format(self.index), 'curr') + power_in_prefix = self.__get_hwmon_attr_prefix(hwmon_dir, "PSU{}_POWER_IN".format(self.index), 'power') + power_out_prefix = self.__get_hwmon_attr_prefix(hwmon_dir, "PSU{}_POWER_OUT".format(self.index), 'power') + voltage_in_prefix = self.__get_hwmon_attr_prefix(hwmon_dir, "PSU{}_VOLTAGE_IN".format(self.index), 'in') + voltage_out_prefix = self.__get_hwmon_attr_prefix(hwmon_dir, "PSU{}_VOLTAGE_OUT".format(self.index), 'in') + temp1_prefix = self.__get_hwmon_attr_prefix(hwmon_dir, "PSU{}_TEMP1".format(self.index), 'temp') + + self.psu_current_in_attr = current_in_prefix + 'input' + self.psu_current_out_attr = current_out_prefix + 'input' + self.psu_power_in_attr = power_in_prefix + 'input' + self.psu_power_out_attr = power_out_prefix + 'input' + self.psu_voltage_in_attr = voltage_in_prefix + 'input' + self.psu_voltage_out_attr = voltage_out_prefix + 'input' + self.psu_status_attr = current_out_prefix + 'input' + self.psu_presence_attr = power_out_prefix + 'present' + self.psu_serial_attr = power_out_prefix + 'sn' + self.psu_model_attr = power_out_prefix + 'model' + self.psu_mfr_id_attr = power_out_prefix + 'mfrid' + self.psu_capacity_attr = power_out_prefix + 'pout_max' + self.psu_type_attr = power_out_prefix + 'vin_type' + self.psu_temp_attr = temp1_prefix + 'input' + + def __get_hwmon_attr_prefix(self, dir, label, type): - self.psu_index_mapping = { - 1:39, - 2:49, - } - self.psu_powerin_index_mapping = { - 1:38, - 2:48, - } - self.psu_currentout_index_mapping = { - 1:36, - 2:46, - } - self.psu_currentin_index_mapping = { - 1:35, - 2:45, - } - self.psu_voltageout_index_mapping = { - 1:44, - 2:54, - } - self.psu_voltagein_index_mapping = { - 1:43, - 2:53, - } - self.index = index - self.psu_presence_attr = "power{}_present".format(self.psu_index_mapping[self.index]) - self.psu_status_attr = "curr{}_input".format(self.psu_currentout_index_mapping[self.index]) - self.psu_power_in_attr = "power{}_input".format(self.psu_powerin_index_mapping[self.index]) - self.psu_power_out_attr = "power{}_input".format(self.psu_index_mapping[self.index]) - self.psu_voltage_out_attr = "in{}_input".format(self.psu_voltageout_index_mapping[self.index]) - self.psu_current_out_attr = "curr{}_input".format(self.psu_currentout_index_mapping[self.index]) - self.psu_voltage_in_attr = "in{}_input".format(self.psu_voltagein_index_mapping[self.index]) - self.psu_current_in_attr = "curr{}_input".format(self.psu_currentin_index_mapping[self.index]) - self.psu_serial_attr = "power{}_sn".format(self.psu_index_mapping[self.index]) - self.psu_model_attr = "power{}_model".format(self.psu_index_mapping[self.index]) - self.psu_mfr_id_attr = "power{}_mfrid".format(self.psu_index_mapping[self.index]) - self.psu_capacity_attr = "power{}_pout_max".format(self.psu_index_mapping[self.index]) - self.psu_type_attr = "power{}_vin_type".format(self.psu_index_mapping[self.index]) + retval = 'ERR' + if not os.path.isdir(dir): + return retval + + try: + for filename in os.listdir(dir): + if filename[-5:] == 'label' and type in filename: + file_path = os.path.join(dir, filename) + if os.path.isfile(file_path) and label == self.__get_attr_value(file_path): + return file_path[0:-5] + except Exception as error: + logging.error("Error when getting {} label path: {}".format(label, error)) + + return retval def __get_attr_value(self, attr_path): @@ -70,10 +74,9 @@ def __get_attr_value(self, attr_path): with open(attr_path, 'r') as fd: retval = fd.read() except Exception as error: - logging.error("Unable to open " + attr_path + " file !") + logging.error("Unable to open {} file: {}".format(attr_path, error)) retval = retval.rstrip(' \t\n\r') - fd.close() return retval ############################################## @@ -97,10 +100,9 @@ def get_presence(self): bool: True if device is present, False if not """ presence = False - attr_path = HWMON_DIR+self.psu_presence_attr attr_normal = '1' - attr_rv = self.__get_attr_value(attr_path) + attr_rv = self.__get_attr_value(self.psu_presence_attr) if (attr_rv != 'ERR'): if (attr_rv == attr_normal): presence = True @@ -115,8 +117,7 @@ def get_model(self): string: Model/part number of device """ model = "N/A" - attr_path = HWMON_DIR+self.psu_model_attr - attr_rv = self.__get_attr_value(attr_path) + attr_rv = self.__get_attr_value(self.psu_model_attr) if (attr_rv != 'ERR'): model = attr_rv @@ -130,8 +131,7 @@ def get_mfr_id(self): string: Manufacturer's id of device """ mfr_id = "N/A" - attr_path = HWMON_DIR+self.psu_mfr_id_attr - attr_rv = self.__get_attr_value(attr_path) + attr_rv = self.__get_attr_value(self.psu_mfr_id_attr) if (attr_rv != 'ERR'): mfr_id = attr_rv @@ -145,9 +145,7 @@ def get_serial(self): string: Serial number of device """ serial = "N/A" - attr_path = HWMON_DIR+self.psu_serial_attr - - attr_rv = self.__get_attr_value(attr_path) + attr_rv = self.__get_attr_value(self.psu_serial_attr) if (attr_rv != 'ERR'): serial = attr_rv @@ -161,9 +159,7 @@ def get_status(self): A boolean value, True if device is operating properly, False if not """ status = False - attr_path = HWMON_DIR+self.psu_status_attr - - attr_rv = self.__get_attr_value(attr_path) + attr_rv = self.__get_attr_value(self.psu_status_attr) if (attr_rv != 'ERR'): attr_rv, dummy = attr_rv.split('.', 1) if (int(attr_rv) != 0): @@ -184,9 +180,7 @@ def get_voltage(self): e.g. 12.1 """ voltage_out = 0.0 - attr_path = HWMON_DIR+self.psu_voltage_out_attr - - attr_rv = self.__get_attr_value(attr_path) + attr_rv = self.__get_attr_value(self.psu_voltage_out_attr) if (attr_rv != 'ERR'): attr_rv, dummy = attr_rv.split('.', 1) voltage_out = float(attr_rv) / 1000 @@ -201,9 +195,7 @@ def get_current(self): A float number, the electric current in amperes, e.g 15.4 """ current_out = 0.0 - attr_path = HWMON_DIR+self.psu_current_out_attr - - attr_rv = self.__get_attr_value(attr_path) + attr_rv = self.__get_attr_value(self.psu_current_out_attr) if (attr_rv != 'ERR'): attr_rv, dummy = attr_rv.split('.', 1) current_out = float(attr_rv) / 1000 @@ -212,16 +204,14 @@ def get_current(self): def get_input_voltage(self): """ - Retrieves current PSU voltage output + Retrieves current PSU voltage input Returns: - A float number, the output voltage in volts, + A float number, the input voltage in volts, e.g. 12.1 """ voltage_in = 0.0 - attr_path = HWMON_DIR+self.psu_voltage_in_attr - - attr_rv = self.__get_attr_value(attr_path) + attr_rv = self.__get_attr_value(self.psu_voltage_in_attr) if (attr_rv != 'ERR'): attr_rv, dummy = attr_rv.split('.', 1) voltage_in = float(attr_rv) / 1000 @@ -236,9 +226,7 @@ def get_input_current(self): A float number, the electric current in amperes, e.g 15.4 """ current_in = 0.0 - attr_path = HWMON_DIR+self.psu_current_in_attr - - attr_rv = self.__get_attr_value(attr_path) + attr_rv = self.__get_attr_value(self.psu_current_in_attr) if (attr_rv != 'ERR'): attr_rv, dummy = attr_rv.split('.', 1) current_in = float(attr_rv) / 1000 @@ -253,9 +241,7 @@ def get_power(self): A float number, the power in watts, e.g. 302.6 """ power_out = 0.0 - attr_path = HWMON_DIR+self.psu_power_out_attr - - attr_rv = self.__get_attr_value(attr_path) + attr_rv = self.__get_attr_value(self.psu_power_out_attr) if (attr_rv != 'ERR'): attr_rv, dummy = attr_rv.split('.', 1) power_out = float(attr_rv) / 1000 @@ -292,8 +278,7 @@ def get_type(self): A string, the type of PSU (AC/DC) """ type = "AC" - attr_path = HWMON_DIR+self.psu_type_attr - attr_rv = self.__get_attr_value(attr_path) + attr_rv = self.__get_attr_value(self.psu_type_attr) if (attr_rv != 'ERR'): type = attr_rv @@ -307,8 +292,7 @@ def get_capacity(self): An integer, the capacity of PSU """ capacity = 0 - attr_path = HWMON_DIR+self.psu_capacity_attr - attr_rv = self.__get_attr_value(attr_path) + attr_rv = self.__get_attr_value(self.psu_capacity_attr) if (attr_rv != 'ERR'): try: capacity = int(attr_rv) @@ -317,3 +301,19 @@ def get_capacity(self): return capacity + def get_temperature(self): + """ + Retrieves current temperature reading from PSU + Returns: + A float number of current temperature in Celsius up to nearest thousandth + of one degree Celsius, e.g. 30.125 + """ + + tout = 0.0 + attr_rv = self.__get_attr_value(self.psu_temp_attr) + if (attr_rv != 'ERR'): + tout = float(attr_rv) + + # tout is in milli degree celcius + return float(tout/1000.0) + diff --git a/platform/broadcom/sonic-platform-modules-quanta/ix9-32x/sonic_platform/sfp.py b/platform/broadcom/sonic-platform-modules-quanta/ix9-32x/sonic_platform/sfp.py index 726e18b23153..77176ad083f5 100644 --- a/platform/broadcom/sonic-platform-modules-quanta/ix9-32x/sonic_platform/sfp.py +++ b/platform/broadcom/sonic-platform-modules-quanta/ix9-32x/sonic_platform/sfp.py @@ -278,7 +278,6 @@ def __init__(self, sfp_index, sfp_type): # Init index self.index = sfp_index self.port_num = self.index - #self.dom_supported = False self.sfp_type = sfp_type self.reset_path = "/sys/class/cpld-qsfpdd/port-"+str(self.port_num)+"/reset" self.lpmode_path = "/sys/class/cpld-qsfpdd/port-"+str(self.port_num)+"/lpmode" @@ -329,7 +328,7 @@ def __init__(self, sfp_index, sfp_type): self.info_dict_keys = ['type', 'vendor_rev', 'serial', 'manufacturer', 'model', 'connector', 'encoding', 'ext_identifier', 'ext_rateselect_compliance', 'cable_type', 'cable_length', - 'nominal_bit_rate', 'specification_compliance', 'vendor_date', 'vendor_oui', 'application_advertisement'] + 'nominal_bit_rate', 'specification_compliance', 'vendor_date', 'vendor_oui', 'application_advertisement', 'type_abbrv_name'] SfpBase.__init__(self) @@ -354,15 +353,6 @@ def _convert_string_to_num(self, value_str): else: return 'N/A' - def __read_txt_file(self, file_path): - try: - with open(file_path, 'r') as fd: - data = fd.read() - return data.strip() - except IOError: - pass - return "" - def __is_host(self): return os.system(self.HOST_CHK_CMD) == 0 @@ -425,7 +415,7 @@ def _detect_sfp_type(self, sfp_type): elif eeprom_raw[0] in QSFP_TYPE_CODE_LIST: self.sfp_type = QSFP_TYPE elif eeprom_raw[0] in QSFP_DD_TYPE_CODE_LIST: - self.sfp_type = QSFP_TYPE + self.sfp_type = QSFP_DD_TYPE else: # we don't regonize this identifier value, treat the xSFP module as the default type self.sfp_type = sfp_type @@ -437,26 +427,6 @@ def _detect_sfp_type(self, sfp_type): # in this case we treat it as the default type according to the SKU self.sfp_type = sfp_type - def __convert_string_to_num(self, value_str): - if "-inf" in value_str: - return 'N/A' - elif "Unknown" in value_str: - return 'N/A' - elif 'dBm' in value_str: - t_str = value_str.rstrip('dBm') - return float(t_str) - elif 'mA' in value_str: - t_str = value_str.rstrip('mA') - return float(t_str) - elif 'C' in value_str: - t_str = value_str.rstrip('C') - return float(t_str) - elif 'Volts' in value_str: - t_str = value_str.rstrip('Volts') - return float(t_str) - else: - return 'N/A' - def _dom_capability_detect(self): if not self.get_presence(): self.dom_supported = False @@ -544,6 +514,7 @@ def _dom_capability_detect(self): self.dom_rx_tx_power_bias_supported = False else: self.dom_supported = False + self.second_application_list = False self.dom_temp_supported = False self.dom_volt_supported = False self.dom_rx_power_supported = False @@ -620,6 +591,7 @@ def get_transceiver_info(self): return transceiver_info_dict self._detect_sfp_type(self.sfp_type) + self._dom_capability_detect() transceiver_info_dict = {} compliance_code_dict = {} @@ -638,6 +610,7 @@ def get_transceiver_info(self): sfp_type_raw = self._read_eeprom_specific_bytes((offset + OSFP_TYPE_OFFSET), XCVR_TYPE_WIDTH) if sfp_type_raw is not None: sfp_type_data = sfpi_obj.parse_sfp_type(sfp_type_raw, 0) + sfp_type_abbrv_name_data = sfpi_obj.parse_sfp_type_abbrv_name(sfp_type_raw, 0) else: return None @@ -666,6 +639,7 @@ def get_transceiver_info(self): return None transceiver_info_dict['type'] = sfp_type_data['data']['type']['value'] + transceiver_info_dict['type_abbrv_name'] = sfp_type_abbrv_name_data['data']['type_abbrv_name']['value'] transceiver_info_dict['manufacturer'] = sfp_vendor_name_data['data']['Vendor Name']['value'] transceiver_info_dict['model'] = sfp_vendor_pn_data['data']['Vendor PN']['value'] transceiver_info_dict['vendor_rev'] = sfp_vendor_rev_data['data']['Vendor Rev']['value'] @@ -703,6 +677,7 @@ def get_transceiver_info(self): sfp_type_raw = self._read_eeprom_specific_bytes((offset + QSFP_DD_TYPE_OFFSET), XCVR_TYPE_WIDTH) if sfp_type_raw is not None: sfp_type_data = sfpi_obj.parse_sfp_type(sfp_type_raw, 0) + sfp_type_abbrv_name_data = sfpi_obj.parse_sfp_type_abbrv_name(sfp_type_raw, 0) else: return None @@ -791,6 +766,7 @@ def get_transceiver_info(self): return None transceiver_info_dict['type'] = str(sfp_type_data['data']['type']['value']) + transceiver_info_dict['type_abbrv_name'] = sfp_type_abbrv_name_data['data']['type_abbrv_name']['value'] transceiver_info_dict['manufacturer'] = str(sfp_vendor_name_data['data']['Vendor Name']['value']) transceiver_info_dict['model'] = str(sfp_vendor_pn_data['data']['Vendor PN']['value']) transceiver_info_dict['vendor_rev'] = str(sfp_vendor_rev_data['data']['Vendor Rev']['value']) @@ -828,9 +804,7 @@ def get_transceiver_info(self): else: if not self.get_presence(): return transceiver_info_dict - elif i == max_retry-1: - pass - else: + elif i < max_retry-1: time.sleep(0.5) if sfp_interface_bulk_raw is None: @@ -865,6 +839,7 @@ def get_transceiver_info(self): sfp_vendor_date_data = sfpi_obj.parse_vendor_date(sfp_interface_bulk_raw[start : end], 0) transceiver_info_dict['type'] = sfp_interface_bulk_data['data']['type']['value'] + transceiver_info_dict['type_abbrv_name'] = sfp_interface_bulk_data['data']['type_abbrv_name']['value'] transceiver_info_dict['manufacturer'] = sfp_vendor_name_data['data']['Vendor Name']['value'] transceiver_info_dict['model'] = sfp_vendor_pn_data['data']['Vendor PN']['value'] transceiver_info_dict['vendor_rev'] = sfp_vendor_rev_data['data']['Vendor Rev']['value'] @@ -960,8 +935,6 @@ def get_transceiver_bulk_status(self): if not self.get_presence(): return {} - self._dom_capability_detect() - if self.sfp_type == OSFP_TYPE: pass @@ -1302,7 +1275,7 @@ def get_reset_status(self): return False elif self.sfp_type == QSFP_TYPE: return False - elif self.sfp_type == OSFP_TYPE or self.sfp_type == QSFP_DD_TYPE: + elif self.sfp_type == QSFP_DD_TYPE: try: reg_file = open(self.reset_path) except IOError as e: @@ -1509,7 +1482,7 @@ def get_lpmode(self): return False elif self.sfp_type == QSFP_TYPE: return False - elif self.sfp_type == OSFP_TYPE: + elif self.sfp_type == QSFP_DD_TYPE: try: reg_file = open(self.lpmode_path) except IOError as e: @@ -1899,7 +1872,7 @@ def reset(self): return False elif self.sfp_type == QSFP_TYPE: return False - elif self.sfp_type == OSFP_TYPE: + elif self.sfp_type == QSFP_DD_TYPE: try: reg_file = open(self.reset_path, "r+") except IOError as e: @@ -1957,7 +1930,7 @@ def tx_disable(self, tx_disable): sysfsfile_eeprom = open( sysfs_sfp_i2c_client_eeprom_path, mode="r+b", buffering=0) buffer = create_string_buffer(1) - buffer[0] = chr(tx_disable_ctl) + buffer[0] = tx_disable_ctl # Write to eeprom sysfsfile_eeprom.seek(offset + SFP_STATUS_CONTROL_OFFSET) sysfsfile_eeprom.write(buffer[0]) @@ -2010,7 +1983,7 @@ def tx_disable_channel(self, channel, disable): else: tx_disable_ctl = channel_state & (~channel) buffer = create_string_buffer(1) - buffer[0] = chr(tx_disable_ctl) + buffer[0] = tx_disable_ctl # Write to eeprom sysfsfile_eeprom = open( self.port_to_eeprom_mapping[self.port_num], "r+b") @@ -2045,7 +2018,7 @@ def set_lpmode(self, lpmode): return False elif self.sfp_type == QSFP_TYPE: return False - elif self.sfp_type == OSFP_TYPE: + elif self.sfp_type == QSFP_DD_TYPE: try: reg_file = open(self.lpmode_path, "r+") except IOError as e: @@ -2099,7 +2072,7 @@ def set_power_override(self, power_override, power_set): power_set_bit |= 1 << 1 buffer = create_string_buffer(1) - buffer[0] = chr(power_override_bit | power_set_bit) + buffer[0] = power_override_bit | power_set_bit # Write to eeprom sysfsfile_eeprom = open(self.port_to_eeprom_mapping[self.port_num], "r+b") sysfsfile_eeprom.seek(QSFP_POWEROVERRIDE_OFFSET) diff --git a/platform/broadcom/sonic-platform-modules-quanta/ix9-32x/sonic_platform/thermal.py b/platform/broadcom/sonic-platform-modules-quanta/ix9-32x/sonic_platform/thermal.py index 5fb209749223..b3e2c89b79ce 100644 --- a/platform/broadcom/sonic-platform-modules-quanta/ix9-32x/sonic_platform/thermal.py +++ b/platform/broadcom/sonic-platform-modules-quanta/ix9-32x/sonic_platform/thermal.py @@ -1,7 +1,7 @@ #!/usr/bin/env python ############################################################################# -# Quanta +# Quanta IX9 # # Module contains an implementation of SONiC Platform Base API and # provides the Thermal information @@ -10,46 +10,69 @@ import logging import os +import glob try: from sonic_platform_base.thermal_base import ThermalBase except ImportError as e: raise ImportError(str(e) + "- required module not found") -HWMON_DIR = "/sys/class/hwmon/hwmon2/" +HWMON_IPMI_DIR = "/sys/devices/platform/quanta_hwmon_ipmi/hwmon/hwmon*/" thermal_index_mapping = { - 1:40, - 2:41, - 3:42, - 4:50, - 5:51, - 6:52, - 7:73, - 8:74, - 9:75, - 10:76, - 11:77, - 12:78, - 13:79, - 14:80, - 15:81, - 16:82, - 17:83, - 18:84, - 19:85 + 1:'PSU1_TEMP1', + 2:'PSU1_TEMP2', + 3:'PSU1_TEMP3', + 4:'PSU2_TEMP1', + 5:'PSU2_TEMP2', + 6:'PSU2_TEMP3', + 7:'Temp_1V05_PCH_VR', + 8:'Temp_Ambient_0', + 9:'Temp_Ambient_1', + 10:'Temp_Ambient_2', + 11:'Temp_Ambient_3', + 12:'Temp_Ambient_4', + 13:'Temp_Ambient_5', + 14:'Temp_CPU', + 15:'Temp_DDRAB_VR', + 16:'Temp_Inlet', + 17:'Temp_SOC_DIMMA0', + 18:'Temp_VCCGBE_VR', + 19:'Temp_VCCIN_VR' } + + class Thermal(ThermalBase): """Platform-specific Thermal class""" def __init__(self, thermal_index): - self.index = thermal_index - self.temp_attr = "temp{}_input".format(thermal_index_mapping[self.index]) - self.high_th_attr = "temp{}_ncrit".format(thermal_index_mapping[self.index]) - self.high_crit_th_attr = "temp{}_crit".format(thermal_index_mapping[self.index]) - self.name_attr = "temp{}_label".format(thermal_index_mapping[self.index]) + self.index = thermal_index + hwmon_dir=glob.glob(HWMON_IPMI_DIR)[0] + thermal_prefix = self.__get_hwmon_attr_prefix(hwmon_dir, thermal_index_mapping[self.index], 'temp') + self.temp_attr = "{}input".format(thermal_prefix) + self.high_th_attr = "{}ncrit".format(thermal_prefix) + self.high_crit_th_attr = "{}crit".format(thermal_prefix) + self.low_th_attr = "{}lncrit".format(thermal_prefix) + self.low_crit_th_attr = "{}lcrit".format(thermal_prefix) + self.name_attr = "{}label".format(thermal_prefix) + + def __get_hwmon_attr_prefix(self, dir, label, type): + + retval = 'ERR' + if not os.path.isdir(dir): + return retval + + try: + for filename in os.listdir(dir): + if filename[-5:] == 'label' and type in filename: + file_path = os.path.join(dir, filename) + if os.path.isfile(file_path) and label == self.__get_attr_value(file_path): + return file_path[0:-5] + except Exception as error: + logging.error("Error when getting {} label path: {}".format(label, error)) + return retval def __get_attr_value(self, attr_path): @@ -61,7 +84,7 @@ def __get_attr_value(self, attr_path): with open(attr_path, 'r') as fd: retval = fd.read() except Exception as error: - logging.error("Unable to open " + attr_path + " file !") + logging.error("Unable to open {} file: {}".format(attr_path, error)) retval = retval.rstrip(' \t\n\r') return retval @@ -73,8 +96,7 @@ def get_name(self): Returns: string: The name of the device """ - attr_path = HWMON_DIR + self.name_attr - attr_rv = self.__get_attr_value(attr_path) + attr_rv = self.__get_attr_value(self.name_attr) if (attr_rv != 'ERR'): return attr_rv @@ -88,8 +110,7 @@ def get_presence(self): Returns: bool: True if device is present, False if not """ - attr_path = HWMON_DIR + self.name_attr - attr_rv = self.__get_attr_value(attr_path) + attr_rv = self.__get_attr_value(self.name_attr) if (attr_rv != 'ERR'): return True @@ -116,8 +137,37 @@ def get_temperature(self): A float number of current temperature in Celsius up to nearest thousandth of one degree Celsius, e.g. 30.125 """ - attr_path = HWMON_DIR + self.temp_attr - attr_rv = self.__get_attr_value(attr_path) + attr_rv = self.__get_attr_value(self.temp_attr) + + if (attr_rv != 'ERR'): + return float(attr_rv) / 1000 + else: + return None + + def get_low_threshold(self): + """ + Retrieves the low threshold temperature of thermal + + Returns: + A float number, the low threshold temperature of thermal in Celsius + up to nearest thousandth of one degree Celsius, e.g. 30.125 + """ + attr_rv = self.__get_attr_value(self.low_th_attr) + + if (attr_rv != 'ERR'): + return float(attr_rv) / 1000 + else: + return None + + def get_low_critical_threshold(self): + """ + Retrieves the low critical threshold temperature of thermal + + Returns: + A float number, the low critical threshold temperature of thermal in Celsius + up to nearest thousandth of one degree Celsius, e.g. 30.125 + """ + attr_rv = self.__get_attr_value(self.low_crit_th_attr) if (attr_rv != 'ERR'): return float(attr_rv) / 1000 @@ -132,8 +182,7 @@ def get_high_threshold(self): A float number, the high threshold temperature of thermal in Celsius up to nearest thousandth of one degree Celsius, e.g. 30.125 """ - attr_path = HWMON_DIR + self.high_th_attr - attr_rv = self.__get_attr_value(attr_path) + attr_rv = self.__get_attr_value(self.high_th_attr) if (attr_rv != 'ERR'): return float(attr_rv) / 1000 @@ -148,8 +197,7 @@ def get_high_critical_threshold(self): A float number, the high threshold temperature of thermal in Celsius up to nearest thousandth of one degree Celsius, e.g. 30.125 """ - attr_path = HWMON_DIR + self.high_crit_th_attr - attr_rv = self.__get_attr_value(attr_path) + attr_rv = self.__get_attr_value(self.high_crit_th_attr) if (attr_rv != 'ERR'): return float(attr_rv) / 1000 diff --git a/platform/broadcom/sonic-platform-modules-quanta/ix9-32x/sonic_platform/watchdog.py b/platform/broadcom/sonic-platform-modules-quanta/ix9-32x/sonic_platform/watchdog.py index 282f356f4e73..0e63d9368cb0 100644 --- a/platform/broadcom/sonic-platform-modules-quanta/ix9-32x/sonic_platform/watchdog.py +++ b/platform/broadcom/sonic-platform-modules-quanta/ix9-32x/sonic_platform/watchdog.py @@ -48,12 +48,16 @@ WDT_SYSFS_PATH = "/sys/class/watchdog/" DEFAULT_TIMEOUT=180 +watchdog=0 class Watchdog(WatchdogBase): def __init__(self): self.watchdog, self.wdt_main_dev_name = self._get_wdt() + if self.wdt_main_dev_name is None: + raise Exception("Watchdog device is not instantiated") + self.status_path = "/sys/class/watchdog/%s/status" % self.wdt_main_dev_name self.state_path = "/sys/class/watchdog/%s/state" % self.wdt_main_dev_name self.timeout_path = "/sys/class/watchdog/%s/timeout" % self.wdt_main_dev_name @@ -74,14 +78,16 @@ def _get_wdt(self): """ Retrieves watchdog device """ + global watchdog wdt_main_dev_list = [dev for dev in os.listdir( "/dev/") if dev.startswith("watchdog") and self._is_wd_main(dev)] if not wdt_main_dev_list: - return None + return (None, None) wdt_main_dev_name = wdt_main_dev_list[0] watchdog_device_path = "/dev/{}".format(wdt_main_dev_name) - self.watchdog = os.open(watchdog_device_path, os.O_RDWR) - return self.watchdog, wdt_main_dev_name + if not watchdog: + watchdog = os.open(watchdog_device_path, os.O_RDWR) + return watchdog, wdt_main_dev_name def _read_file(self, file_path): """ @@ -228,7 +234,8 @@ def __del__(self): Close watchdog """ - os.close(self.watchdog) + if self.watchdog is not None : + os.close(self.watchdog) diff --git a/platform/broadcom/sonic-platform-modules-quanta/ix9-32x/utils/quanta_ix9_util.py b/platform/broadcom/sonic-platform-modules-quanta/ix9-32x/utils/quanta_ix9_util.py index 0554ccbf1b71..ec14e10ad6d1 100755 --- a/platform/broadcom/sonic-platform-modules-quanta/ix9-32x/utils/quanta_ix9_util.py +++ b/platform/broadcom/sonic-platform-modules-quanta/ix9-32x/utils/quanta_ix9_util.py @@ -28,27 +28,26 @@ """ import os -import commands +import subprocess import sys, getopt import logging +import time DEBUG = False args = [] FORCE = 0 i2c_prefix = '/sys/bus/i2c/devices/' - if DEBUG == True: - print sys.argv[0] - print 'ARGV :', sys.argv[1:] - + print(sys.argv[0]) + print('ARGV :', sys.argv[1:]) def main(): global DEBUG global args global FORCE - if len(sys.argv)<2: + if len(sys.argv) < 2: show_help() options, args = getopt.getopt(sys.argv[1:], 'hdf', ['help', @@ -56,9 +55,9 @@ def main(): 'force', ]) if DEBUG == True: - print options - print args - print len(sys.argv) + print(options) + print(args) + print(len(sys.argv)) for opt, arg in options: if opt in ('-h', '--help'): @@ -72,44 +71,44 @@ def main(): logging.info('no option') for arg in args: if arg == 'install': - install() + install() elif arg == 'clean': - uninstall() + uninstall() else: show_help() return 0 def show_help(): - print __doc__ % {'scriptName' : sys.argv[0].split("/")[-1]} + print(__doc__ % {'scriptName' : sys.argv[0].split("/")[-1]}) sys.exit(0) def show_log(txt): if DEBUG == True: - print "[IX9-32X]"+txt + print("[IX9-32X]" + txt) return def exec_cmd(cmd, show): - logging.info('Run :'+cmd) - status, output = commands.getstatusoutput(cmd) + logging.info('Run :' + cmd) + status, output = subprocess.getstatusoutput(cmd) show_log (cmd +"with result:" + str(status)) - show_log (" output:"+output) + show_log (" output:" + output) if status: - logging.info('Failed :'+cmd) + logging.info('Failed :' + cmd) if show: - print('Failed :'+cmd) - return status, output + print('Failed :' + cmd) + return status, output + +pca954x_bus_addr =[ +'0-0072', +'0-0077', +'5-0073', +'6-0073', +'7-0073', +'8-0073' +] instantiate =[ -#turn on module power -'echo 21 > /sys/class/gpio/export', -'echo out > /sys/class/gpio/gpio21/direction', -'echo 1 >/sys/class/gpio/gpio21/value', -#Reset fron-ports LED CPLD -'echo 33 > /sys/class/gpio/export', -'echo out > /sys/class/gpio/gpio33/direction', -'echo 0 >/sys/class/gpio/gpio33/value', -'echo 1 >/sys/class/gpio/gpio33/value', #Enable front-ports LED decoding 'echo 1 > /sys/class/cpld-led/CPLDLED-1/led_decode', 'echo 1 > /sys/class/cpld-led/CPLDLED-2/led_decode', @@ -159,7 +158,7 @@ def exec_cmd(cmd, show): 'lpc_ich', 'i2c-i801', 'i2c-dev', -'i2c-mux-pca954x force_deselect_on_exit=1', +'i2c-mux-pca954x', 'gpio-pca953x', 'optoe', 'qci_cpld_qsfpdd', @@ -190,11 +189,20 @@ def system_install(): exec_cmd("depmod -a ", 1) #install drivers for i in range(0,len(drivers)): - status, output = exec_cmd("modprobe " + drivers[i], 1) - if status: - print output - if FORCE == 0: - return status + status, output = exec_cmd("modprobe " + drivers[i], 1) + if status: + print(output) + #retry quanta_hwmon_ipmi in case it init failed due to ipmi_msghandler init uncompleted + if drivers[i] == 'quanta_hwmon_ipmi': + for _ in range(0, 3): + time.sleep(3) + ret, out = exec_cmd("modprobe quanta_hwmon_ipmi ", 1) + if ret == 0: + break + if ret and FORCE == 0: + return ret + elif FORCE == 0: + return status #reload ethernet drivers in correct order exec_cmd("rmmod ixgbe ", 1) @@ -202,16 +210,32 @@ def system_install(): exec_cmd("modprobe igb ", 1) exec_cmd("modprobe ixgbe ", 1) + # set pca954x idle_state as -2: MUX_IDLE_DISCONNECT + for i in range(0,len(pca954x_bus_addr)): + exec_cmd("echo -2 > /sys/bus/i2c/drivers/pca954x/{}/idle_state".format(pca954x_bus_addr[i]), 1) + + #turn on module power + exec_cmd("echo 21 > /sys/class/gpio/export ", 1) + exec_cmd("echo high > /sys/class/gpio/gpio21/direction ", 1) + + #Reset fron-ports LED CPLD + exec_cmd("echo 33 > /sys/class/gpio/export ", 1) + status, output = exec_cmd("cat /sys/class/gpio/gpio33/value", 1) + if output != '1': + exec_cmd("echo out > /sys/class/gpio/gpio33/direction ", 1) + exec_cmd("echo 0 >/sys/class/gpio/gpio33/value", 1) + exec_cmd("echo 1 >/sys/class/gpio/gpio33/value", 1) + #instantiate devices - for i in range(0,len(instantiate)): - status, output = exec_cmd(instantiate[i], 1) - if status: - print output - if FORCE == 0: - return status + for i in range(0, len(instantiate)): + status, output = exec_cmd(instantiate[i], 1) + if status: + print(output) + if FORCE == 0: + return status #QSFPDD for 1~32 port - for port_number in range(1,33): + for port_number in range(1, 33): bus_number = port_number + 12 os.system("echo %d >/sys/bus/i2c/devices/%d-0050/port_name" % (port_number, bus_number)) @@ -224,35 +248,35 @@ def system_ready(): def install(): if not device_found(): - print "No device, installing...." + print("No device, installing....") status = system_install() if status: if FORCE == 0: - return status + return status status, output = exec_cmd("pip3 install /usr/share/sonic/device/x86_64-quanta_ix9_bwde-r0/sonic_platform-1.0-py3-none-any.whl",1) if status: - print output - if FORCE == 0: - return status + print(output) + if FORCE == 0: + return status else: - print " ix9 driver already installed...." + print(" ix9 driver already installed....") return def uninstall(): global FORCE #uninstall drivers for i in range(len(un_drivers) - 1, -1, -1): - status, output = exec_cmd("rmmod " + un_drivers[i], 1) + status, output = exec_cmd("rmmod " + un_drivers[i], 1) if status: - print output - if FORCE == 0: - return status + print(output) + if FORCE == 0: + return status status, output = exec_cmd("pip3 uninstall sonic-platform -y ",1) if status: - print output - if FORCE == 0: - return status + print(output) + if FORCE == 0: + return status return From b7aa69595f9d229ddfa8d6a08ad27e43dbb3bf7a Mon Sep 17 00:00:00 2001 From: arlakshm <55814491+arlakshm@users.noreply.github.com> Date: Tue, 23 Aug 2022 13:40:54 -0700 Subject: [PATCH 028/151] [Chassis]: filter inband and recirc ports as internal ports (#11764) Why I did it Currently the CLI commands show interface status show interface counters and show interface description displays Ethernet-IB and Ethernet-Rec ports in the output. These are internal ports should only be displayed when the option -d all is used for the above mentioned CLI commands How I did it Add the port roles Inb and Rec when classifing a port as internal port. How to verify it Verify the CLI output of the command show interface status doesnt display the Ethenet-IB and Ethernet-Rec port when -d all option in not present Before Signed-off-by: Arvindsrinivasan Lakshmi Narasimhan --- src/sonic-py-common/sonic_py_common/multi_asic.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/sonic-py-common/sonic_py_common/multi_asic.py b/src/sonic-py-common/sonic_py_common/multi_asic.py index e08746be0367..e03dc6447c90 100644 --- a/src/sonic-py-common/sonic_py_common/multi_asic.py +++ b/src/sonic-py-common/sonic_py_common/multi_asic.py @@ -15,6 +15,8 @@ BACKEND_ASIC_SUB_ROLE = 'BackEnd' EXTERNAL_PORT = 'Ext' INTERNAL_PORT = 'Int' +INBAND_PORT = 'Inb' +RECIRC_PORT ='Rec' PORT_CHANNEL_CFG_DB_TABLE = 'PORTCHANNEL' PORT_CFG_DB_TABLE = 'PORT' BGP_NEIGH_CFG_DB_TABLE = 'BGP_NEIGHBOR' @@ -323,7 +325,7 @@ def is_port_internal(port_name, namespace=None): role = get_port_role(port_name, namespace) - if role == INTERNAL_PORT: + if role in [INTERNAL_PORT, INBAND_PORT, RECIRC_PORT]: return True return False From cd33c7fc7145ac86566c69d454c26c3229245645 Mon Sep 17 00:00:00 2001 From: Hua Liu <58683130+liuh-80@users.noreply.github.com> Date: Wed, 24 Aug 2022 12:36:47 +0800 Subject: [PATCH 029/151] Replace swsssdk with swsscommon in accton device (#11348) #### Why I did it Update scripts in sonic-buildimage from py-swsssdk to swsscommon #### How I did it Remove unused swsssdk import from accton device code #### How to verify it Pass all E2E test case #### Which release branch to backport (provide reason below if selected) - [ ] 201811 - [ ] 201911 - [ ] 202006 - [ ] 202012 - [ ] 202106 - [ ] 202111 - [ ] 202205 #### Description for the changelog Remove unused swsssdk import from accton device code #### Link to config_db schema for YANG module changes #### A picture of a cute animal (not mandatory but encouraged) --- device/accton/x86_64-accton_minipack-r0/plugins/led_control.py | 1 - 1 file changed, 1 deletion(-) diff --git a/device/accton/x86_64-accton_minipack-r0/plugins/led_control.py b/device/accton/x86_64-accton_minipack-r0/plugins/led_control.py index a11a31062367..5aa00638d835 100755 --- a/device/accton/x86_64-accton_minipack-r0/plugins/led_control.py +++ b/device/accton/x86_64-accton_minipack-r0/plugins/led_control.py @@ -5,7 +5,6 @@ try: from sonic_led.led_control_base import LedControlBase - import swsssdk import threading import os import logging From 776c93b96e5e713c5cfa8a290c9266985e96ebf4 Mon Sep 17 00:00:00 2001 From: Hua Liu <58683130+liuh-80@users.noreply.github.com> Date: Wed, 24 Aug 2022 12:39:51 +0800 Subject: [PATCH 030/151] Replace swsssdk with swsscommon in centec devices. (#11350) #### Why I did it Update scripts in sonic-buildimage from py-swsssdk to swsscommon #### How I did it Replace swsssdk with swsscommon in centec devices. #### How to verify it Pass all E2E test case #### Which release branch to backport (provide reason below if selected) - [ ] 201811 - [ ] 201911 - [ ] 202006 - [ ] 202012 - [ ] 202106 - [ ] 202111 - [ ] 202205 #### Description for the changelog Replace swsssdk with swsscommon in centec devices. #### Link to config_db schema for YANG module changes #### A picture of a cute animal (not mandatory but encouraged) --- .../x86_64-centec_e582_48x2q4z-r0/plugins/led_control.py | 1 - .../centec/x86_64-centec_e582_48x6q-r0/plugins/led_control.py | 1 - .../48x2q4z/scripts/48x2q4z_platform_monitor.py | 4 ++-- .../48x6q/scripts/48x6q_platform_monitor.py | 4 ++-- 4 files changed, 4 insertions(+), 6 deletions(-) diff --git a/device/centec/x86_64-centec_e582_48x2q4z-r0/plugins/led_control.py b/device/centec/x86_64-centec_e582_48x2q4z-r0/plugins/led_control.py index 48a4d8d04eae..ed017335d6ee 100644 --- a/device/centec/x86_64-centec_e582_48x2q4z-r0/plugins/led_control.py +++ b/device/centec/x86_64-centec_e582_48x2q4z-r0/plugins/led_control.py @@ -5,7 +5,6 @@ try: from sonic_led.led_control_base import LedControlBase - import swsssdk import threading import os import logging diff --git a/device/centec/x86_64-centec_e582_48x6q-r0/plugins/led_control.py b/device/centec/x86_64-centec_e582_48x6q-r0/plugins/led_control.py index eb9e9143a9bf..abde0678743d 100644 --- a/device/centec/x86_64-centec_e582_48x6q-r0/plugins/led_control.py +++ b/device/centec/x86_64-centec_e582_48x6q-r0/plugins/led_control.py @@ -5,7 +5,6 @@ try: from sonic_led.led_control_base import LedControlBase - import swsssdk import threading import os import logging diff --git a/platform/centec/sonic-platform-modules-e582/48x2q4z/scripts/48x2q4z_platform_monitor.py b/platform/centec/sonic-platform-modules-e582/48x2q4z/scripts/48x2q4z_platform_monitor.py index 2d8d2c440a8f..5112b7e012d8 100644 --- a/platform/centec/sonic-platform-modules-e582/48x2q4z/scripts/48x2q4z_platform_monitor.py +++ b/platform/centec/sonic-platform-modules-e582/48x2q4z/scripts/48x2q4z_platform_monitor.py @@ -15,7 +15,7 @@ import logging import struct import syslog - import swsssdk + from swsscommon import swsscommon from socket import * from select import * except ImportError, e: @@ -96,7 +96,7 @@ def initialize_configdb(self): aligned_last_byte = format(int(int(str(last_byte), 16) + 1), '02x') mac_addr = mac_addr[:-2] + aligned_last_byte DBG_PRINT("start connect swss config-db to set device mac-address") - swss = swsssdk.SonicV2Connector() + swss = swsscommon.SonicV2Connector() swss.connect(swss.CONFIG_DB) swss.set(swss.CONFIG_DB, "DEVICE_METADATA|localhost", 'mac', mac_addr) mac_addr = swss.get(swss.CONFIG_DB, "DEVICE_METADATA|localhost", 'mac') diff --git a/platform/centec/sonic-platform-modules-e582/48x6q/scripts/48x6q_platform_monitor.py b/platform/centec/sonic-platform-modules-e582/48x6q/scripts/48x6q_platform_monitor.py index d08802a35f3b..9c45d3ea1a34 100644 --- a/platform/centec/sonic-platform-modules-e582/48x6q/scripts/48x6q_platform_monitor.py +++ b/platform/centec/sonic-platform-modules-e582/48x6q/scripts/48x6q_platform_monitor.py @@ -15,7 +15,7 @@ import logging import struct import syslog - import swsssdk + from swsscommon import swsscommon from socket import * from select import * except ImportError, e: @@ -96,7 +96,7 @@ def initialize_configdb(self): aligned_last_byte = format(int(int(str(last_byte), 16) + 1), '02x') mac_addr = mac_addr[:-2] + aligned_last_byte DBG_PRINT("start connect swss config-db to set device mac-address") - swss = swsssdk.SonicV2Connector() + swss = swsscommon.SonicV2Connector() swss.connect(swss.CONFIG_DB) swss.set(swss.CONFIG_DB, "DEVICE_METADATA|localhost", 'mac', mac_addr) mac_addr = swss.get(swss.CONFIG_DB, "DEVICE_METADATA|localhost", 'mac') From 3fc0fe1841b465090a1ac9584b9f36929cc1e603 Mon Sep 17 00:00:00 2001 From: Hua Liu <58683130+liuh-80@users.noreply.github.com> Date: Wed, 24 Aug 2022 12:40:12 +0800 Subject: [PATCH 031/151] Replace swsssdk with swsscommon in alphanetworks devices (#11349) #### Why I did it Update scripts in sonic-buildimage from py-swsssdk to swsscommon #### How I did it Replace swsssdk with swsscommon in alphanetworks devices code. #### How to verify it Pass all E2E test case #### Which release branch to backport (provide reason below if selected) - [ ] 201811 - [ ] 201911 - [ ] 202006 - [ ] 202012 - [ ] 202106 - [ ] 202111 - [ ] 202205 #### Description for the changelog Replace swsssdk with swsscommon in alphanetworks devices code. #### Link to config_db schema for YANG module changes #### A picture of a cute animal (not mandatory but encouraged) --- .../plugins/led_control.py | 4 ++-- .../plugins/led_control.py | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/device/alphanetworks/x86_64-alphanetworks_snh60a0_320fv2-r0/plugins/led_control.py b/device/alphanetworks/x86_64-alphanetworks_snh60a0_320fv2-r0/plugins/led_control.py index 4da72e7f7a04..7ce532554f95 100644 --- a/device/alphanetworks/x86_64-alphanetworks_snh60a0_320fv2-r0/plugins/led_control.py +++ b/device/alphanetworks/x86_64-alphanetworks_snh60a0_320fv2-r0/plugins/led_control.py @@ -3,7 +3,7 @@ # try: # from sonic_led.led_control_base import LedControlBase -# import swsssdk +# from swsscommon import swsscommon # except ImportError as e: # raise ImportError (str(e) + " - required module not found") @@ -181,7 +181,7 @@ def _port_name_to_qsfp_index(self, port_name): sonic_port_num = int(port_name[len(self.SONIC_PORT_NAME_PREFIX):]) - swss = swsssdk.SonicV2Connector() + swss = swsscommon.SonicV2Connector() swss.connect(swss.APPL_DB) lanes = swss.get( diff --git a/device/alphanetworks/x86_64-alphanetworks_snh60b0_640f-r0/plugins/led_control.py b/device/alphanetworks/x86_64-alphanetworks_snh60b0_640f-r0/plugins/led_control.py index 53cc43c6cce3..e7c8d3bc1e2d 100644 --- a/device/alphanetworks/x86_64-alphanetworks_snh60b0_640f-r0/plugins/led_control.py +++ b/device/alphanetworks/x86_64-alphanetworks_snh60b0_640f-r0/plugins/led_control.py @@ -5,7 +5,7 @@ # try: # from sonic_led.led_control_base import LedControlBase -# import swsssdk +# from swsscommon import swsscommon # except ImportError as e: # raise ImportError (str(e) + " - required module not found") @@ -148,7 +148,7 @@ def _port_name_to_qsfp_index(self, port_name): sonic_port_num = int(port_name[len(self.SONIC_PORT_NAME_PREFIX):]) - swss = swsssdk.SonicV2Connector() + swss = swsscommon.SonicV2Connector() swss.connect(swss.APPL_DB) lanes = swss.get( From d9f3e6ce4fffff55bb7e936f70dbae26c3a39df6 Mon Sep 17 00:00:00 2001 From: Kebo Liu Date: Wed, 24 Aug 2022 16:45:16 +0800 Subject: [PATCH 032/151] update Mellanox SDK/FW to 4.5.2318 2010.2318 (#11773) - Why I did it Update SDK/FW version - 4.5.2318/2010_2318 to pick up new fixes: 1. Cr space timeout on Hold and Release GW - at warm boot 2. Spectrum Port in stuck PHY_UP after peer side rebooted 3. Memory leak in sx_api_router_ecmp_update_set - How I did it Update the make file with the new version number Update submodule Switch-SDK-drivers pointer - How to verify it Run sonic regression Signed-off-by: Kebo Liu --- platform/mellanox/fw.mk | 6 +++--- platform/mellanox/sdk-src/sx-kernel/Switch-SDK-drivers | 2 +- platform/mellanox/sdk.mk | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/platform/mellanox/fw.mk b/platform/mellanox/fw.mk index 0dc3800155ea..f6beeb990bd7 100644 --- a/platform/mellanox/fw.mk +++ b/platform/mellanox/fw.mk @@ -27,17 +27,17 @@ else FW_FROM_URL = n endif -MLNX_SPC_FW_VERSION = 13.2010.2262 +MLNX_SPC_FW_VERSION = 13.2010.2318 MLNX_SPC_FW_FILE = fw-SPC-rel-$(subst .,_,$(MLNX_SPC_FW_VERSION))-EVB.mfa $(MLNX_SPC_FW_FILE)_PATH = $(MLNX_FW_BASE_PATH) $(MLNX_SPC_FW_FILE)_URL = $(MLNX_FW_BASE_URL)/$(MLNX_SPC_FW_FILE) -MLNX_SPC2_FW_VERSION = 29.2010.2262 +MLNX_SPC2_FW_VERSION = 29.2010.2318 MLNX_SPC2_FW_FILE = fw-SPC2-rel-$(subst .,_,$(MLNX_SPC2_FW_VERSION))-EVB.mfa $(MLNX_SPC2_FW_FILE)_PATH = $(MLNX_FW_BASE_PATH) $(MLNX_SPC2_FW_FILE)_URL = $(MLNX_FW_BASE_URL)/$(MLNX_SPC2_FW_FILE) -MLNX_SPC3_FW_VERSION = 30.2010.2262 +MLNX_SPC3_FW_VERSION = 30.2010.2318 MLNX_SPC3_FW_FILE = fw-SPC3-rel-$(subst .,_,$(MLNX_SPC3_FW_VERSION))-EVB.mfa $(MLNX_SPC3_FW_FILE)_PATH = $(MLNX_FW_BASE_PATH) $(MLNX_SPC3_FW_FILE)_URL = $(MLNX_FW_BASE_URL)/$(MLNX_SPC3_FW_FILE) diff --git a/platform/mellanox/sdk-src/sx-kernel/Switch-SDK-drivers b/platform/mellanox/sdk-src/sx-kernel/Switch-SDK-drivers index e9fa9a843702..7d4071a89f34 160000 --- a/platform/mellanox/sdk-src/sx-kernel/Switch-SDK-drivers +++ b/platform/mellanox/sdk-src/sx-kernel/Switch-SDK-drivers @@ -1 +1 @@ -Subproject commit e9fa9a843702aa55b13c8eb01c7a1f188e4a16a9 +Subproject commit 7d4071a89f34dc1dce4a9e832a0fd27c26acb485 diff --git a/platform/mellanox/sdk.mk b/platform/mellanox/sdk.mk index e0861ddc93f8..ad60fd1fa045 100644 --- a/platform/mellanox/sdk.mk +++ b/platform/mellanox/sdk.mk @@ -16,7 +16,7 @@ # MLNX_SDK_BASE_PATH = $(PLATFORM_PATH)/sdk-src/sx-kernel/Switch-SDK-drivers/bin/ MLNX_SDK_PKG_BASE_PATH = $(MLNX_SDK_BASE_PATH)/$(BLDENV)/$(CONFIGURED_ARCH)/ -MLNX_SDK_VERSION = 4.5.2262 +MLNX_SDK_VERSION = 4.5.2318 MLNX_SDK_ISSU_VERSION = 101 MLNX_SDK_DEB_VERSION = $(subst -,.,$(subst _,.,$(MLNX_SDK_VERSION))) From 0193c8e90cc0db40389ea958deea4b216003c1e2 Mon Sep 17 00:00:00 2001 From: Vivek Date: Wed, 24 Aug 2022 01:53:11 -0700 Subject: [PATCH 033/151] [sonic_py_common] Cache Static Information in device_info to speed up CLI response (#11696) - Why I did it Profiled the execution for the following cmd intfutil -c status - How I did it Cached the following information: 1. get_sonic_version_info() 2. get_platform_info() None of the API exposed to the user libraries (for eg: sonic-utilities) has been modified These methods involve reading text files or from redis. Thus, caching helped to improve the execution time - How to verify it Added UT's. Verified on the device Signed-off-by: Vivek Reddy Karri --- .../sonic_py_common/device_info.py | 22 ++++-- src/sonic-py-common/tests/device_info_test.py | 79 +++++++++++++++++++ 2 files changed, 95 insertions(+), 6 deletions(-) diff --git a/src/sonic-py-common/sonic_py_common/device_info.py b/src/sonic-py-common/sonic_py_common/device_info.py index 6126dd6dd284..92809474ad6a 100644 --- a/src/sonic-py-common/sonic_py_common/device_info.py +++ b/src/sonic-py-common/sonic_py_common/device_info.py @@ -39,6 +39,10 @@ CHASSIS_INFO_MODEL_FIELD = 'model' CHASSIS_INFO_REV_FIELD = 'revision' +# Cacheable Objects +sonic_ver_info = {} +hw_info_dict = {} + def get_localhost_info(field, config_db=None): try: # TODO: enforce caller to provide config_db explicitly and remove its default value @@ -333,14 +337,17 @@ def get_sonic_version_info(): if not os.path.isfile(SONIC_VERSION_YAML_PATH): return None - data = {} + global sonic_ver_info + if sonic_ver_info: + return sonic_ver_info + with open(SONIC_VERSION_YAML_PATH) as stream: if yaml.__version__ >= "5.1": - data = yaml.full_load(stream) + sonic_ver_info = yaml.full_load(stream) else: - data = yaml.load(stream) + sonic_ver_info = yaml.load(stream) - return data + return sonic_ver_info def get_sonic_version_file(): if not os.path.isfile(SONIC_VERSION_YAML_PATH): @@ -354,9 +361,12 @@ def get_platform_info(config_db=None): """ This function is used to get the HW info helper function """ - from .multi_asic import get_num_asics + global hw_info_dict - hw_info_dict = {} + if hw_info_dict: + return hw_info_dict + + from .multi_asic import get_num_asics version_info = get_sonic_version_info() diff --git a/src/sonic-py-common/tests/device_info_test.py b/src/sonic-py-common/tests/device_info_test.py index 1256037ff560..44e0d3a5b162 100644 --- a/src/sonic-py-common/tests/device_info_test.py +++ b/src/sonic-py-common/tests/device_info_test.py @@ -52,6 +52,32 @@ 'onie_kernel_version': '4.10.11' } +SONIC_VERISON_YML = """\ +--- +build_version: 'test_branch.1-a8fbac59d' +debian_version: '11.4' +kernel_version: '5.10.0-12-2-amd64' +asic_type: mellanox +asic_subtype: 'mellanox' +commit_id: 'a8fbac59d' +branch: 'test_branch' +release: 'master' +libswsscommon: 1.0.0 +sonic_utilities: 1.2""" + +SONIC_VERISON_YML_RESULT = { + 'build_version': 'test_branch.1-a8fbac59d', + 'debian_version': '11.4', + 'kernel_version': '5.10.0-12-2-amd64', + 'asic_type': 'mellanox', + 'asic_subtype': 'mellanox', + 'commit_id': 'a8fbac59d', + 'branch': 'test_branch', + 'release': 'master', + 'libswsscommon': '1.0.0', + 'sonic_utilities': 1.2 +} + class TestDeviceInfo(object): @pytest.fixture(scope="class", autouse=True) def sanitize_environment(self): @@ -83,6 +109,59 @@ def test_get_chassis_info(self): "revision": SonicV2Connector.TEST_REV} assert result == truth + @mock.patch("os.path.isfile") + def test_get_sonic_version(self, mock_isfile): + mock_isfile.return_value = True + open_mocked = mock.mock_open(read_data=SONIC_VERISON_YML) + with mock.patch("{}.open".format(BUILTINS), open_mocked): + for _ in range(0,5): + assert device_info.get_sonic_version_info() == SONIC_VERISON_YML_RESULT + # Assert the file was read only once + open_mocked.assert_called_once_with(device_info.SONIC_VERSION_YAML_PATH) + + @mock.patch("sonic_py_common.device_info.get_platform_info") + def test_is_chassis(self, mock_platform_info): + mock_platform_info.return_value = {"switch_type": "npu"} + assert device_info.is_chassis() == False + assert device_info.is_voq_chassis() == False + assert device_info.is_packet_chassis() == False + + mock_platform_info.return_value = {"switch_type": "voq"} + assert device_info.is_voq_chassis() == True + assert device_info.is_packet_chassis() == False + assert device_info.is_chassis() == True + + mock_platform_info.return_value = {"switch_type": "chassis-packet"} + assert device_info.is_voq_chassis() == False + assert device_info.is_packet_chassis() == True + assert device_info.is_chassis() == True + + mock_platform_info.return_value = {} + assert device_info.is_voq_chassis() == False + assert device_info.is_packet_chassis() == False + assert device_info.is_chassis() == False + + @mock.patch("sonic_py_common.device_info.ConfigDBConnector", autospec=True) + @mock.patch("sonic_py_common.device_info.get_sonic_version_info") + @mock.patch("sonic_py_common.device_info.get_machine_info") + @mock.patch("sonic_py_common.device_info.get_hwsku") + def test_get_platform_info(self, mock_hwsku, mock_machine_info, mock_sonic_ver, mock_cfg_db): + mock_cfg_inst = mock_cfg_db.return_value + mock_cfg_inst.get_table.return_value = {"localhost": {"switch_type": "npu"}} + mock_sonic_ver.return_value = SONIC_VERISON_YML_RESULT + mock_machine_info.return_value = {"onie_platform" : "x86_64-mlnx_msn2700-r0"} + mock_hwsku.return_value = "Mellanox-SN2700" + for _ in range(0,5): + hw_info_dict = device_info.get_platform_info() + assert hw_info_dict["asic_type"] == "mellanox" + assert hw_info_dict["platform"] == "x86_64-mlnx_msn2700-r0" + assert hw_info_dict["hwsku"] == "Mellanox-SN2700" + assert hw_info_dict["switch_type"] == "npu" + assert mock_sonic_ver.called_once() + assert mock_machine_info.called_once() + assert mock_hwsku.called_once() + mock_cfg_inst.get_table.assert_called_once_with("DEVICE_METADATA") + @classmethod def teardown_class(cls): print("TEARDOWN") From 6462f454330921c68386cd4e4b5f3cacbc3564bb Mon Sep 17 00:00:00 2001 From: Yakiv Huryk <62013282+Yakiv-Huryk@users.noreply.github.com> Date: Wed, 24 Aug 2022 11:53:54 +0300 Subject: [PATCH 034/151] [bullseye] add dependencies for saithriftv2 build (#11666) - Why I did it To support saithriftv2 build for bullseye dockers - How I did it Added the dependencies documented in the SAI docs and used in sonic-slave-buster - How to verify it Build saithriftv2 in the sonic-slave-bullseye Signed-off-by: Yakiv Huryk --- sonic-slave-bullseye/Dockerfile.j2 | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/sonic-slave-bullseye/Dockerfile.j2 b/sonic-slave-bullseye/Dockerfile.j2 index e3169f888205..1ffca8bc86c1 100644 --- a/sonic-slave-bullseye/Dockerfile.j2 +++ b/sonic-slave-bullseye/Dockerfile.j2 @@ -176,6 +176,13 @@ RUN apt-get update && apt-get install -y \ libxml-simple-perl \ graphviz \ aspell \ +# For SAI meta rpc build - make rpc + libgetopt-long-descriptive-perl \ + libconst-fast-perl \ + libtemplate-perl \ + libnamespace-autoclean-perl \ + libmoose-perl \ + libmoosex-aliases-perl \ # For linux build bc \ fakeroot \ From f3c1c14d22b345a1bdde844b0957aec0dbe78a90 Mon Sep 17 00:00:00 2001 From: Vivek Date: Wed, 24 Aug 2022 01:55:33 -0700 Subject: [PATCH 035/151] [Mellanox] [4700] Update platform capability file to support new breakout mode (#11614) - Why I did it This new breakout mode is required when a QSFP cable is used on the QSFP-DD supported 4700 port. since QSFP only uses the first 4 lanes, this mode is required to restrict the child ports to only use the first four lanes - How I did it Updated the platfrom.json file with the extended data - How to verify it Tested on one port: root@msn-4700:/home/admin# show int status Interface Lanes Speed MTU FEC Alias Vlan Oper Admin Type Asym PFC ----------- ------------------------------- ------- ----- ----- ------- ------ ------ ------- ----------------------------------------------- ---------- Ethernet0 0 25G 9100 N/A etp1a routed up up QSFP28 or later N/A Ethernet1 1 25G 9100 N/A etp1b routed down up N/A N/A Ethernet2 2 25G 9100 N/A etp1c routed down up N/A N/A Ethernet3 3 25G 9100 N/A etp1d routed down up N/A N/A Signed-off-by: Vivek Reddy Karri --- .../x86_64-mlnx_msn4700-r0/platform.json | 98 ++++++++++++------- 1 file changed, 65 insertions(+), 33 deletions(-) diff --git a/device/mellanox/x86_64-mlnx_msn4700-r0/platform.json b/device/mellanox/x86_64-mlnx_msn4700-r0/platform.json index 58fd5d08c6e1..49211914ec54 100644 --- a/device/mellanox/x86_64-mlnx_msn4700-r0/platform.json +++ b/device/mellanox/x86_64-mlnx_msn4700-r0/platform.json @@ -413,7 +413,8 @@ "breakout_modes": { "1x400G[200G,100G,50G,40G,25G,10G,1G]": ["etp1"], "2x200G[100G,50G,40G,25G,10G,1G]": ["etp1a", "etp1b"], - "4x100G[50G,25G,10G,1G]": ["etp1a", "etp1b", "etp1c", "etp1d"] + "4x100G[50G,25G,10G,1G]": ["etp1a", "etp1b", "etp1c", "etp1d"], + "4x25G(4)[10G,1G]": ["etp1a", "etp1b", "etp1c", "etp1d"] } }, "Ethernet8": { @@ -422,7 +423,8 @@ "breakout_modes": { "1x400G[200G,100G,50G,40G,25G,10G,1G]": ["etp2"], "2x200G[100G,50G,40G,25G,10G,1G]": ["etp2a", "etp2b"], - "4x100G[50G,25G,10G,1G]": ["etp2a", "etp2b", "etp2c", "etp2d"] + "4x100G[50G,25G,10G,1G]": ["etp2a", "etp2b", "etp2c", "etp2d"], + "4x25G(4)[10G,1G]": ["etp2a", "etp2b", "etp2c", "etp2d"] } }, "Ethernet16": { @@ -431,7 +433,8 @@ "breakout_modes": { "1x400G[200G,100G,50G,40G,25G,10G,1G]": ["etp3"], "2x200G[100G,50G,40G,25G,10G,1G]": ["etp3a", "etp3b"], - "4x100G[50G,25G,10G,1G]": ["etp3a", "etp3b", "etp3c", "etp3d"] + "4x100G[50G,25G,10G,1G]": ["etp3a", "etp3b", "etp3c", "etp3d"], + "4x25G(4)[10G,1G]": ["etp3a", "etp3b", "etp3c", "etp3d"] } }, "Ethernet24": { @@ -440,7 +443,8 @@ "breakout_modes": { "1x400G[200G,100G,50G,40G,25G,10G,1G]": ["etp4"], "2x200G[100G,50G,40G,25G,10G,1G]": ["etp4a", "etp4b"], - "4x100G[50G,25G,10G,1G]": ["etp4a", "etp4b", "etp4c", "etp4d"] + "4x100G[50G,25G,10G,1G]": ["etp4a", "etp4b", "etp4c", "etp4d"], + "4x25G(4)[10G,1G]": ["etp4a", "etp4b", "etp4c", "etp4d"] } }, "Ethernet32": { @@ -449,7 +453,8 @@ "breakout_modes": { "1x400G[200G,100G,50G,40G,25G,10G,1G]": ["etp5"], "2x200G[100G,50G,40G,25G,10G,1G]": ["etp5a", "etp5b"], - "4x100G[50G,25G,10G,1G]": ["etp5a", "etp5b", "etp5c", "etp5d"] + "4x100G[50G,25G,10G,1G]": ["etp5a", "etp5b", "etp5c", "etp5d"], + "4x25G(4)[10G,1G]": ["etp5a", "etp5b", "etp5c", "etp5d"] } }, "Ethernet40": { @@ -458,7 +463,8 @@ "breakout_modes": { "1x400G[200G,100G,50G,40G,25G,10G,1G]": ["etp6"], "2x200G[100G,50G,40G,25G,10G,1G]": ["etp6a", "etp6b"], - "4x100G[50G,25G,10G,1G]": ["etp6a", "etp6b", "etp6c", "etp6d"] + "4x100G[50G,25G,10G,1G]": ["etp6a", "etp6b", "etp6c", "etp6d"], + "4x25G(4)[10G,1G]": ["etp6a", "etp6b", "etp6c", "etp6d"] } }, "Ethernet48": { @@ -467,7 +473,8 @@ "breakout_modes": { "1x400G[200G,100G,50G,40G,25G,10G,1G]": ["etp7"], "2x200G[100G,50G,40G,25G,10G,1G]": ["etp7a", "etp7b"], - "4x100G[50G,25G,10G,1G]": ["etp7a", "etp7b", "etp7c", "etp7d"] + "4x100G[50G,25G,10G,1G]": ["etp7a", "etp7b", "etp7c", "etp7d"], + "4x25G(4)[10G,1G]": ["etp7a", "etp7b", "etp7c", "etp7d"] } }, "Ethernet56": { @@ -476,7 +483,8 @@ "breakout_modes": { "1x400G[200G,100G,50G,40G,25G,10G,1G]": ["etp8"], "2x200G[100G,50G,40G,25G,10G,1G]": ["etp8a", "etp8b"], - "4x100G[50G,25G,10G,1G]": ["etp8a", "etp8b", "etp8c", "etp8d"] + "4x100G[50G,25G,10G,1G]": ["etp8a", "etp8b", "etp8c", "etp8d"], + "4x25G(4)[10G,1G]": ["etp8a", "etp8b", "etp8c", "etp8d"] } }, "Ethernet64": { @@ -485,7 +493,8 @@ "breakout_modes": { "1x400G[200G,100G,50G,40G,25G,10G,1G]": ["etp9"], "2x200G[100G,50G,40G,25G,10G,1G]": ["etp9a", "etp9b"], - "4x100G[50G,25G,10G,1G]": ["etp9a", "etp9b", "etp9c", "etp9d"] + "4x100G[50G,25G,10G,1G]": ["etp9a", "etp9b", "etp9c", "etp9d"], + "4x25G(4)[10G,1G]": ["etp9a", "etp9b", "etp9c", "etp9d"] } }, "Ethernet72": { @@ -494,16 +503,18 @@ "breakout_modes": { "1x400G[200G,100G,50G,40G,25G,10G,1G]": ["etp10"], "2x200G[100G,50G,40G,25G,10G,1G]": ["etp10a", "etp10b"], - "4x100G[50G,25G,10G,1G]": ["etp10a", "etp10b", "etp10c", "etp10d"] + "4x100G[50G,25G,10G,1G]": ["etp10a", "etp10b", "etp10c", "etp10d"], + "4x25G(4)[10G,1G]": ["etp10a", "etp10b", "etp10c", "etp10d"] } - }, + }, "Ethernet80": { "index": "11,11,11,11,11,11,11,11", "lanes": "80,81,82,83,84,85,86,87", "breakout_modes": { "1x400G[200G,100G,50G,40G,25G,10G,1G]": ["etp11"], "2x200G[100G,50G,40G,25G,10G,1G]": ["etp11a", "etp11b"], - "4x100G[50G,25G,10G,1G]": ["etp11a", "etp11b", "etp11c", "etp11d"] + "4x100G[50G,25G,10G,1G]": ["etp11a", "etp11b", "etp11c", "etp11d"], + "4x25G(4)[10G,1G]": ["etp11a", "etp11b", "etp11c", "etp11d"] } }, "Ethernet88": { @@ -512,7 +523,8 @@ "breakout_modes": { "1x400G[200G,100G,50G,40G,25G,10G,1G]": ["etp12"], "2x200G[100G,50G,40G,25G,10G,1G]": ["etp12a", "etp12b"], - "4x100G[50G,25G,10G,1G]": ["etp12a", "etp12b", "etp12c", "etp12d"] + "4x100G[50G,25G,10G,1G]": ["etp12a", "etp12b", "etp12c", "etp12d"], + "4x25G(4)[10G,1G]": ["etp12a", "etp12b", "etp12c", "etp12d"] } }, "Ethernet96": { @@ -521,7 +533,8 @@ "breakout_modes": { "1x400G[200G,100G,50G,40G,25G,10G,1G]": ["etp13"], "2x200G[100G,50G,40G,25G,10G,1G]": ["etp13a", "etp13b"], - "4x100G[50G,25G,10G,1G]": ["etp13a", "etp13b", "etp13c", "etp13d"] + "4x100G[50G,25G,10G,1G]": ["etp13a", "etp13b", "etp13c", "etp13d"], + "4x25G(4)[10G,1G]": ["etp13a", "etp13b", "etp13c", "etp13d"] } }, "Ethernet104": { @@ -530,7 +543,8 @@ "breakout_modes": { "1x400G[200G,100G,50G,40G,25G,10G,1G]": ["etp14"], "2x200G[100G,50G,40G,25G,10G,1G]": ["etp14a", "etp14b"], - "4x100G[50G,25G,10G,1G]": ["etp14a", "etp14b", "etp14c", "etp14d"] + "4x100G[50G,25G,10G,1G]": ["etp14a", "etp14b", "etp14c", "etp14d"], + "4x25G(4)[10G,1G]": ["etp14a", "etp14b", "etp14c", "etp14d"] } }, "Ethernet112": { @@ -539,7 +553,8 @@ "breakout_modes": { "1x400G[200G,100G,50G,40G,25G,10G,1G]": ["etp15"], "2x200G[100G,50G,40G,25G,10G,1G]": ["etp15a", "etp15b"], - "4x100G[50G,25G,10G,1G]": ["etp15a", "etp15b", "etp15c", "etp15d"] + "4x100G[50G,25G,10G,1G]": ["etp15a", "etp15b", "etp15c", "etp15d"], + "4x25G(4)[10G,1G]": ["etp15a", "etp15b", "etp15c", "etp15d"] } }, "Ethernet120": { @@ -548,7 +563,8 @@ "breakout_modes": { "1x400G[200G,100G,50G,40G,25G,10G,1G]": ["etp16"], "2x200G[100G,50G,40G,25G,10G,1G]": ["etp16a", "etp16b"], - "4x100G[50G,25G,10G,1G]": ["etp16a", "etp16b", "etp16c", "etp16d"] + "4x100G[50G,25G,10G,1G]": ["etp16a", "etp16b", "etp16c", "etp16d"], + "4x25G(4)[10G,1G]": ["etp16a", "etp16b", "etp16c", "etp16d"] } }, "Ethernet128": { @@ -557,7 +573,8 @@ "breakout_modes": { "1x400G[200G,100G,50G,40G,25G,10G,1G]": ["etp17"], "2x200G[100G,50G,40G,25G,10G,1G]": ["etp17a", "etp17b"], - "4x100G[50G,25G,10G,1G]": ["etp17a", "etp17b", "etp17c", "etp17d"] + "4x100G[50G,25G,10G,1G]": ["etp17a", "etp17b", "etp17c", "etp17d"], + "4x25G(4)[10G,1G]": ["etp17a", "etp17b", "etp17c", "etp17d"] } }, "Ethernet136": { @@ -566,7 +583,8 @@ "breakout_modes": { "1x400G[200G,100G,50G,40G,25G,10G,1G]": ["etp18"], "2x200G[100G,50G,40G,25G,10G,1G]": ["etp18a", "etp18b"], - "4x100G[50G,25G,10G,1G]": ["etp18a", "etp18b", "etp18c", "etp18d"] + "4x100G[50G,25G,10G,1G]": ["etp18a", "etp18b", "etp18c", "etp18d"], + "4x25G(4)[10G,1G]": ["etp18a", "etp18b", "etp18c", "etp18d"] } }, "Ethernet144": { @@ -575,7 +593,8 @@ "breakout_modes": { "1x400G[200G,100G,50G,40G,25G,10G,1G]": ["etp19"], "2x200G[100G,50G,40G,25G,10G,1G]": ["etp19a", "etp19b"], - "4x100G[50G,25G,10G,1G]": ["etp19a", "etp19b", "etp19c", "etp19d"] + "4x100G[50G,25G,10G,1G]": ["etp19a", "etp19b", "etp19c", "etp19d"], + "4x25G(4)[10G,1G]": ["etp19a", "etp19b", "etp19c", "etp19d"] } }, "Ethernet152": { @@ -584,7 +603,8 @@ "breakout_modes": { "1x400G[200G,100G,50G,40G,25G,10G,1G]": ["etp20"], "2x200G[100G,50G,40G,25G,10G,1G]": ["etp20a", "etp20b"], - "4x100G[50G,25G,10G,1G]": ["etp20a", "etp20b", "etp20c", "etp20d"] + "4x100G[50G,25G,10G,1G]": ["etp20a", "etp20b", "etp20c", "etp20d"], + "4x25G(4)[10G,1G]": ["etp20a", "etp20b", "etp20c", "etp20d"] } }, "Ethernet160": { @@ -593,7 +613,8 @@ "breakout_modes": { "1x400G[200G,100G,50G,40G,25G,10G,1G]": ["etp21"], "2x200G[100G,50G,40G,25G,10G,1G]": ["etp21a", "etp21b"], - "4x100G[50G,25G,10G,1G]": ["etp21a", "etp21b", "etp21c", "etp21d"] + "4x100G[50G,25G,10G,1G]": ["etp21a", "etp21b", "etp21c", "etp21d"], + "4x25G(4)[10G,1G]": ["etp21a", "etp21b", "etp21c", "etp21d"] } }, "Ethernet168": { @@ -602,7 +623,8 @@ "breakout_modes": { "1x400G[200G,100G,50G,40G,25G,10G,1G]": ["etp22"], "2x200G[100G,50G,40G,25G,10G,1G]": ["etp22a", "etp22b"], - "4x100G[50G,25G,10G,1G]": ["etp22a", "etp22b", "etp22c", "etp22d"] + "4x100G[50G,25G,10G,1G]": ["etp22a", "etp22b", "etp22c", "etp22d"], + "4x25G(4)[10G,1G]": ["etp22a", "etp22b", "etp22c", "etp22d"] } }, "Ethernet176": { @@ -611,7 +633,8 @@ "breakout_modes": { "1x400G[200G,100G,50G,40G,25G,10G,1G]": ["etp23"], "2x200G[100G,50G,40G,25G,10G,1G]": ["etp23a", "etp23b"], - "4x100G[50G,25G,10G,1G]": ["etp23a", "etp23b", "etp23c", "etp23d"] + "4x100G[50G,25G,10G,1G]": ["etp23a", "etp23b", "etp23c", "etp23d"], + "4x25G(4)[10G,1G]": ["etp23a", "etp23b", "etp23c", "etp23d"] } }, "Ethernet184": { @@ -620,7 +643,8 @@ "breakout_modes": { "1x400G[200G,100G,50G,40G,25G,10G,1G]": ["etp24"], "2x200G[100G,50G,40G,25G,10G,1G]": ["etp24a", "etp24b"], - "4x100G[50G,25G,10G,1G]": ["etp24a", "etp24b", "etp24c", "etp24d"] + "4x100G[50G,25G,10G,1G]": ["etp24a", "etp24b", "etp24c", "etp24d"], + "4x25G(4)[10G,1G]": ["etp24a", "etp24b", "etp24c", "etp24d"] } }, "Ethernet192": { @@ -629,7 +653,8 @@ "breakout_modes": { "1x400G[200G,100G,50G,40G,25G,10G,1G]": ["etp25"], "2x200G[100G,50G,40G,25G,10G,1G]": ["etp25a", "etp25b"], - "4x100G[50G,25G,10G,1G]": ["etp25a", "etp25b", "etp25c", "etp25d"] + "4x100G[50G,25G,10G,1G]": ["etp25a", "etp25b", "etp25c", "etp25d"], + "4x25G(4)[10G,1G]": ["etp25a", "etp25b", "etp25c", "etp25d"] } }, "Ethernet200": { @@ -638,7 +663,8 @@ "breakout_modes": { "1x400G[200G,100G,50G,40G,25G,10G,1G]": ["etp26"], "2x200G[100G,50G,40G,25G,10G,1G]": ["etp26a", "etp26b"], - "4x100G[50G,25G,10G,1G]": ["etp26a", "etp26b", "etp26c", "etp26d"] + "4x100G[50G,25G,10G,1G]": ["etp26a", "etp26b", "etp26c", "etp26d"], + "4x25G(4)[10G,1G]": ["etp26a", "etp26b", "etp26c", "etp26d"] } }, "Ethernet208": { @@ -647,7 +673,8 @@ "breakout_modes": { "1x400G[200G,100G,50G,40G,25G,10G,1G]": ["etp27"], "2x200G[100G,50G,40G,25G,10G,1G]": ["etp27a", "etp27b"], - "4x100G[50G,25G,10G,1G]": ["etp27a", "etp27b", "etp27c", "etp27d"] + "4x100G[50G,25G,10G,1G]": ["etp27a", "etp27b", "etp27c", "etp27d"], + "4x25G(4)[10G,1G]": ["etp27a", "etp27b", "etp27c", "etp27d"] } }, "Ethernet216": { @@ -656,7 +683,8 @@ "breakout_modes": { "1x400G[200G,100G,50G,40G,25G,10G,1G]": ["etp28"], "2x200G[100G,50G,40G,25G,10G,1G]": ["etp28a", "etp28b"], - "4x100G[50G,25G,10G,1G]": ["etp28a", "etp28b", "etp28c", "etp28d"] + "4x100G[50G,25G,10G,1G]": ["etp28a", "etp28b", "etp28c", "etp28d"], + "4x25G(4)[10G,1G]": ["etp28a", "etp28b", "etp28c", "etp28d"] } }, "Ethernet224": { @@ -665,7 +693,8 @@ "breakout_modes": { "1x400G[200G,100G,50G,40G,25G,10G,1G]": ["etp29"], "2x200G[100G,50G,40G,25G,10G,1G]": ["etp29a", "etp29b"], - "4x100G[50G,25G,10G,1G]": ["etp29a", "etp29b", "etp29c", "etp29d"] + "4x100G[50G,25G,10G,1G]": ["etp29a", "etp29b", "etp29c", "etp29d"], + "4x25G(4)[10G,1G]": ["etp29a", "etp29b", "etp29c", "etp29d"] } }, "Ethernet232": { @@ -674,7 +703,8 @@ "breakout_modes": { "1x400G[200G,100G,50G,40G,25G,10G,1G]": ["etp30"], "2x200G[100G,50G,40G,25G,10G,1G]": ["etp30a", "etp30b"], - "4x100G[50G,25G,10G,1G]": ["etp30a", "etp30b", "etp30c", "etp30d"] + "4x100G[50G,25G,10G,1G]": ["etp30a", "etp30b", "etp30c", "etp30d"], + "4x25G(4)[10G,1G]": ["etp30a", "etp30b", "etp30c", "etp30d"] } }, "Ethernet240": { @@ -683,7 +713,8 @@ "breakout_modes": { "1x400G[200G,100G,50G,40G,25G,10G,1G]": ["etp31"], "2x200G[100G,50G,40G,25G,10G,1G]": ["etp31a", "etp31b"], - "4x100G[50G,25G,10G,1G]": ["etp31a", "etp31b", "etp31c", "etp31d"] + "4x100G[50G,25G,10G,1G]": ["etp31a", "etp31b", "etp31c", "etp31d"], + "4x25G(4)[10G,1G]": ["etp31a", "etp31b", "etp31c", "etp31d"] } }, "Ethernet248": { @@ -692,7 +723,8 @@ "breakout_modes": { "1x400G[200G,100G,50G,40G,25G,10G,1G]": ["etp32"], "2x200G[100G,50G,40G,25G,10G,1G]": ["etp32a", "etp32b"], - "4x100G[50G,25G,10G,1G]": ["etp32a", "etp32b", "etp32c", "etp32d"] + "4x100G[50G,25G,10G,1G]": ["etp32a", "etp32b", "etp32c", "etp32d"], + "4x25G(4)[10G,1G]": ["etp32a", "etp32b", "etp32c", "etp32d"] } } } From adffbd4643f721dae7d523ff84ebd72025b28ddc Mon Sep 17 00:00:00 2001 From: Saikrishna Arcot Date: Wed, 24 Aug 2022 11:42:15 -0700 Subject: [PATCH 036/151] Build the Broadcom DNX RPC container as part of the official build (#11829) With the Broadcom syncd containers getting upgraded to Bullseye, the DNX RPC container is no longer automatically built. Explicitly add a make command to build it. Signed-off-by: Saikrishna Arcot Signed-off-by: Saikrishna Arcot --- .azure-pipelines/azure-pipelines-build.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.azure-pipelines/azure-pipelines-build.yml b/.azure-pipelines/azure-pipelines-build.yml index 1b7d6225ac56..e8e74e8d1882 100644 --- a/.azure-pipelines/azure-pipelines-build.yml +++ b/.azure-pipelines/azure-pipelines-build.yml @@ -139,6 +139,9 @@ jobs: fi if [ $(docker_syncd_rpc_image) == yes ]; then make $BUILD_OPTIONS ENABLE_SYNCD_RPC=y target/docker-syncd-$(platform_rpc)-rpc.gz + if [ $(GROUP_NAME) == broadcom ]; then + make $BUILD_OPTIONS ENABLE_SYNCD_RPC=y target/docker-syncd-$(platform_rpc)-dnx-rpc.gz + fi fi if [ $(syncd_rpc_image) == yes ]; then make $BUILD_OPTIONS ENABLE_SYNCD_RPC=y target/sonic-$(GROUP_NAME).bin From e7405738925f8cd8a5faf1976cf04719deea6ced Mon Sep 17 00:00:00 2001 From: rajendra-dendukuri <47423477+rajendra-dendukuri@users.noreply.github.com> Date: Wed, 24 Aug 2022 19:42:01 -0400 Subject: [PATCH 037/151] Fix TARGET_BOOTLOADER variable assignment (#11722) - Pass TARGET_BOOTLOADER variable value to slave build infra #### Why I did it The TARGET_BOOTLOADER is always blank when referred to in the Makefiles which are executed inside the slave build container. #### How I did it Pass it on the make command invoking slave.mk explicitly similar to other environment variables. #### How to verify it kdump-tools package is installed on sonic-broadcom.bin image. --- Makefile.work | 1 + 1 file changed, 1 insertion(+) diff --git a/Makefile.work b/Makefile.work index 3f64531ab11c..139d15ed2f59 100644 --- a/Makefile.work +++ b/Makefile.work @@ -354,6 +354,7 @@ SONIC_BUILD_INSTRUCTION := make \ PLATFORM=$(PLATFORM) \ PLATFORM_ARCH=$(PLATFORM_ARCH) \ MULTIARCH_QEMU_ENVIRON=$(MULTIARCH_QEMU_ENVIRON) \ + TARGET_BOOTLOADER=$(TARGET_BOOTLOADER) \ CROSS_BUILD_ENVIRON=$(CROSS_BUILD_ENVIRON) \ BUILD_NUMBER=$(BUILD_NUMBER) \ BUILD_TIMESTAMP=$(BUILD_TIMESTAMP) \ From 214e394ac01c411b5aac228c14a30fdbe3f73ad5 Mon Sep 17 00:00:00 2001 From: Hua Liu <58683130+liuh-80@users.noreply.github.com> Date: Thu, 25 Aug 2022 08:35:51 +0800 Subject: [PATCH 038/151] Remove swsssdk from rules and image. (#11469) #### Why I did it To deprecate swsssdk, remove all dependency to it. #### How I did it Remove swsssdk from rules and build image scripts. #### How to verify it Pass all UT and E2E test case #### Which release branch to backport (provide reason below if selected) - [ ] 201811 - [ ] 201911 - [ ] 202006 - [ ] 202012 - [ ] 202106 - [ ] 202111 - [ ] 202205 #### Description for the changelog Remove swsssdk from rules and build image scripts. #### Link to config_db schema for YANG module changes #### A picture of a cute animal (not mandatory but encouraged) --- files/image_config/monit/container_checker | 3 +-- files/scripts/supervisor-proc-exit-listener | 4 ++-- rules/asyncsnmp-py3.mk | 2 +- rules/dbsyncd-py3.mk | 2 +- rules/docker-config-engine-bullseye.mk | 1 - rules/docker-config-engine-buster.mk | 1 - rules/docker-config-engine-stretch.mk | 1 - rules/docker-config-engine.mk | 1 - rules/docker-platform-monitor.mk | 1 - rules/docker-snmp.mk | 3 ++- rules/sonic-host-services.mk | 3 +-- rules/sonic-utilities.mk | 1 - rules/sonic-ztp.mk | 3 ++- 13 files changed, 10 insertions(+), 16 deletions(-) diff --git a/files/image_config/monit/container_checker b/files/image_config/monit/container_checker index c6271d26c8b1..0958368559ad 100755 --- a/files/image_config/monit/container_checker +++ b/files/image_config/monit/container_checker @@ -19,7 +19,6 @@ check program container_checker with path "/usr/bin/container_checker" import docker import sys -import swsssdk from sonic_py_common import multi_asic, device_info from swsscommon import swsscommon @@ -34,7 +33,7 @@ def get_expected_running_containers(): @return: A set which contains the expected running containers and a set that has containers marked as "always_enabled". """ - config_db = swsssdk.ConfigDBConnector() + config_db = swsscommon.ConfigDBConnector() config_db.connect() feature_table = config_db.get_table("FEATURE") diff --git a/files/scripts/supervisor-proc-exit-listener b/files/scripts/supervisor-proc-exit-listener index 7bf3059b5e9a..a17ffb7e45fa 100755 --- a/files/scripts/supervisor-proc-exit-listener +++ b/files/scripts/supervisor-proc-exit-listener @@ -10,7 +10,7 @@ import syslog import time from collections import defaultdict -import swsssdk +from swsscommon import swsscommon from supervisor import childutils @@ -87,7 +87,7 @@ def get_autorestart_state(container_name): @summary: Read the status of auto-restart feature from Config_DB. @return: Return the status of auto-restart feature. """ - config_db = swsssdk.ConfigDBConnector() + config_db = swsscommon.ConfigDBConnector() config_db.connect() features_table = config_db.get_table(FEATURE_TABLE_NAME) if not features_table: diff --git a/rules/asyncsnmp-py3.mk b/rules/asyncsnmp-py3.mk index 2592eb004ee8..60e83140374e 100644 --- a/rules/asyncsnmp-py3.mk +++ b/rules/asyncsnmp-py3.mk @@ -4,6 +4,6 @@ ASYNCSNMP_PY3 = asyncsnmp-2.1.0-py3-none-any.whl $(ASYNCSNMP_PY3)_SRC_PATH = $(SRC_PATH)/sonic-snmpagent $(ASYNCSNMP_PY3)_PYTHON_VERSION = 3 # Depends on sonic-platform-common so it is possible to import sonic_psu -$(ASYNCSNMP_PY3)_DEPENDS += $(SWSSSDK_PY3) $(SONIC_PLATFORM_COMMON_PY3) +$(ASYNCSNMP_PY3)_DEPENDS += $(SONIC_PY_COMMON_PY3) $(SONIC_PLATFORM_COMMON_PY3) $(ASYNCSNMP_PY3)_DEBS_DEPENDS += $(LIBSWSSCOMMON) $(PYTHON3_SWSSCOMMON) SONIC_PYTHON_WHEELS += $(ASYNCSNMP_PY3) diff --git a/rules/dbsyncd-py3.mk b/rules/dbsyncd-py3.mk index 12cf13cafe3b..5d05b8829920 100644 --- a/rules/dbsyncd-py3.mk +++ b/rules/dbsyncd-py3.mk @@ -3,6 +3,6 @@ DBSYNCD_PY3 = sonic_d-2.0.0-py3-none-any.whl $(DBSYNCD_PY3)_SRC_PATH = $(SRC_PATH)/sonic-dbsyncd $(DBSYNCD_PY3)_PYTHON_VERSION = 3 -$(DBSYNCD_PY3)_DEPENDS += $(SWSSSDK_PY3) +$(DBSYNCD_PY3)_DEPENDS += $(SONIC_PY_COMMON_PY3) $(DBSYNCD_PY3)_DEBS_DEPENDS += $(LIBSWSSCOMMON) $(PYTHON3_SWSSCOMMON) SONIC_PYTHON_WHEELS += $(DBSYNCD_PY3) diff --git a/rules/docker-config-engine-bullseye.mk b/rules/docker-config-engine-bullseye.mk index 0c4aad67a8d7..c125aa65b209 100644 --- a/rules/docker-config-engine-bullseye.mk +++ b/rules/docker-config-engine-bullseye.mk @@ -9,7 +9,6 @@ $(DOCKER_CONFIG_ENGINE_BULLSEYE)_DEPENDS += $(LIBSWSSCOMMON) \ $(LIBYANG_PY3) \ $(PYTHON3_SWSSCOMMON) \ $(SONIC_DB_CLI) -$(DOCKER_CONFIG_ENGINE_BULLSEYE)_PYTHON_WHEELS += $(SWSSSDK_PY3) $(DOCKER_CONFIG_ENGINE_BULLSEYE)_PYTHON_WHEELS += $(SONIC_PY_COMMON_PY3) \ $(SONIC_YANG_MGMT_PY3) \ $(SONIC_YANG_MODELS_PY3) diff --git a/rules/docker-config-engine-buster.mk b/rules/docker-config-engine-buster.mk index 079fc6dd074c..ae5589a59595 100644 --- a/rules/docker-config-engine-buster.mk +++ b/rules/docker-config-engine-buster.mk @@ -9,7 +9,6 @@ $(DOCKER_CONFIG_ENGINE_BUSTER)_DEPENDS += $(LIBSWSSCOMMON) \ $(LIBYANG_PY3) \ $(PYTHON3_SWSSCOMMON) \ $(SONIC_DB_CLI) -$(DOCKER_CONFIG_ENGINE_BUSTER)_PYTHON_WHEELS += $(SWSSSDK_PY3) $(DOCKER_CONFIG_ENGINE_BUSTER)_PYTHON_WHEELS += $(SONIC_PY_COMMON_PY3) \ $(SONIC_YANG_MGMT_PY3) \ $(SONIC_YANG_MODELS_PY3) diff --git a/rules/docker-config-engine-stretch.mk b/rules/docker-config-engine-stretch.mk index 8644102abed3..dfceb7ecdb63 100644 --- a/rules/docker-config-engine-stretch.mk +++ b/rules/docker-config-engine-stretch.mk @@ -5,7 +5,6 @@ $(DOCKER_CONFIG_ENGINE_STRETCH)_PATH = $(DOCKERS_PATH)/docker-config-engine-stre $(DOCKER_CONFIG_ENGINE_STRETCH)_DEPENDS += $(LIBSWSSCOMMON) \ $(PYTHON_SWSSCOMMON) \ $(SONIC_DB_CLI) -$(DOCKER_CONFIG_ENGINE_STRETCH)_PYTHON_WHEELS += $(SWSSSDK_PY2) $(DOCKER_CONFIG_ENGINE_STRETCH)_PYTHON_WHEELS += $(SONIC_PY_COMMON_PY2) $(DOCKER_CONFIG_ENGINE_STRETCH)_PYTHON_WHEELS += $(SONIC_CONFIG_ENGINE_PY2) $(DOCKER_CONFIG_ENGINE_STRETCH)_LOAD_DOCKERS += $(DOCKER_BASE_STRETCH) diff --git a/rules/docker-config-engine.mk b/rules/docker-config-engine.mk index 3923a970b4d6..bdb96984bd06 100644 --- a/rules/docker-config-engine.mk +++ b/rules/docker-config-engine.mk @@ -4,7 +4,6 @@ DOCKER_CONFIG_ENGINE = docker-config-engine.gz $(DOCKER_CONFIG_ENGINE)_PATH = $(DOCKERS_PATH)/docker-config-engine $(DOCKER_CONFIG_ENGINE)_DEPENDS += $(LIBSWSSCOMMON) \ $(SONIC_DB_CLI) -$(DOCKER_CONFIG_ENGINE)_PYTHON_WHEELS += $(SWSSSDK_PY2) $(DOCKER_CONFIG_ENGINE)_PYTHON_WHEELS += $(SONIC_PY_COMMON_PY2) $(DOCKER_CONFIG_ENGINE)_PYTHON_WHEELS += $(SONIC_CONFIG_ENGINE_PY2) $(DOCKER_CONFIG_ENGINE)_LOAD_DOCKERS += $(DOCKER_BASE) diff --git a/rules/docker-platform-monitor.mk b/rules/docker-platform-monitor.mk index cb9be990e61b..5c3c760f192e 100644 --- a/rules/docker-platform-monitor.mk +++ b/rules/docker-platform-monitor.mk @@ -10,7 +10,6 @@ $(DOCKER_PLATFORM_MONITOR)_DEPENDS += $(LIBSENSORS) $(LM_SENSORS) $(FANCONTROL) $(DOCKER_PLATFORM_MONITOR)_PYTHON_WHEELS += $(SONIC_PLATFORM_COMMON_PY3) -$(DOCKER_PLATFORM_MONITOR)_PYTHON_WHEELS += $(SWSSSDK_PY3) $(DOCKER_PLATFORM_MONITOR)_PYTHON_WHEELS += $(SONIC_PY_COMMON_PY3) $(DOCKER_PLATFORM_MONITOR)_PYTHON_WHEELS += $(SONIC_CONFIG_ENGINE_PY3) $(DOCKER_PLATFORM_MONITOR)_PYTHON_WHEELS += $(SONIC_PLATFORM_API_PY3) diff --git a/rules/docker-snmp.mk b/rules/docker-snmp.mk index e0f7719c6034..313b233a8557 100644 --- a/rules/docker-snmp.mk +++ b/rules/docker-snmp.mk @@ -11,10 +11,11 @@ $(DOCKER_SNMP)_DEPENDS += $(SNMP) $(SNMPD) $(DOCKER_SNMP)_DBG_DEPENDS = $($(DOCKER_CONFIG_ENGINE_BULLSEYE)_DBG_DEPENDS) $(DOCKER_SNMP)_DBG_DEPENDS += $(SNMP_DBG) $(SNMPD_DBG) $(LIBSNMP_DBG) +$(DOCKER_SNMP)_DBG_DEPENDS += $(LIBSWSSCOMMON) $(PYTHON3_SWSSCOMMON) $(DOCKER_SNMP)_DBG_IMAGE_PACKAGES = $($(DOCKER_CONFIG_ENGINE_BULLSEYE)_DBG_IMAGE_PACKAGES) -$(DOCKER_SNMP)_PYTHON_WHEELS += $(SONIC_PY_COMMON_PY3) $(SONIC_PLATFORM_COMMON_PY3) $(SWSSSDK_PY3) $(ASYNCSNMP_PY3) +$(DOCKER_SNMP)_PYTHON_WHEELS += $(SONIC_PY_COMMON_PY3) $(SONIC_PLATFORM_COMMON_PY3) $(ASYNCSNMP_PY3) $(DOCKER_SNMP)_LOAD_DOCKERS += $(DOCKER_CONFIG_ENGINE_BULLSEYE) $(DOCKER_SNMP)_VERSION = 1.0.0 diff --git a/rules/sonic-host-services.mk b/rules/sonic-host-services.mk index 87463d2ba8cc..eeb931ce5666 100644 --- a/rules/sonic-host-services.mk +++ b/rules/sonic-host-services.mk @@ -3,8 +3,7 @@ SONIC_HOST_SERVICES_PY3 = sonic_host_services-1.0-py3-none-any.whl $(SONIC_HOST_SERVICES_PY3)_SRC_PATH = $(SRC_PATH)/sonic-host-services $(SONIC_HOST_SERVICES_PY3)_PYTHON_VERSION = 3 -$(SONIC_HOST_SERVICES_PY3)_DEPENDS += $(SONIC_PY_COMMON_PY3) \ - $(SWSSSDK_PY3) +$(SONIC_HOST_SERVICES_PY3)_DEPENDS += $(SONIC_PY_COMMON_PY3) $(SONIC_HOST_SERVICES_PY3)_DEBS_DEPENDS = $(LIBSWSSCOMMON) \ $(PYTHON3_SWSSCOMMON) SONIC_PYTHON_WHEELS += $(SONIC_HOST_SERVICES_PY3) diff --git a/rules/sonic-utilities.mk b/rules/sonic-utilities.mk index 519f633cc772..9c59ebab4858 100644 --- a/rules/sonic-utilities.mk +++ b/rules/sonic-utilities.mk @@ -8,7 +8,6 @@ $(SONIC_UTILITIES_PY3)_PYTHON_VERSION = 3 $(SONIC_UTILITIES_PY3)_NAME = $(SONIC_UTILITIES_PY3_NAME) $(SONIC_UTILITIES_PY3)_VERSION = $(SONIC_UTILITIES_PY3_VERSION) $(SONIC_UTILITIES_PY3)_DEPENDS += $(SONIC_PY_COMMON_PY3) \ - $(SWSSSDK_PY3) \ $(SONIC_CONFIG_ENGINE_PY3) \ $(SONIC_PLATFORM_COMMON_PY3) \ $(SONIC_YANG_MGMT_PY3) \ diff --git a/rules/sonic-ztp.mk b/rules/sonic-ztp.mk index 0c4819ec6004..a4bcc5e285fa 100644 --- a/rules/sonic-ztp.mk +++ b/rules/sonic-ztp.mk @@ -5,7 +5,8 @@ SONIC_ZTP_VERSION = 1.0.0 SONIC_ZTP = sonic-ztp_$(SONIC_ZTP_VERSION)_all.deb $(SONIC_ZTP)_SRC_PATH = $(SRC_PATH)/sonic-ztp -$(SONIC_ZTP)_WHEEL_DEPENDS += $(SWSSSDK_PY3) +$(SONIC_ZTP)_PYTHON_VERSION = 3 +$(SONIC_ZTP)_DEBS_DEPENDS += $(LIBSWSSCOMMON) $(PYTHON3_SWSSCOMMON) SONIC_DPKG_DEBS += $(SONIC_ZTP) export SONIC_ZTP_VERSION From 30e79a1a3f0276d08893e6c0a3fe26b2b71f7ac0 Mon Sep 17 00:00:00 2001 From: Sangita Maity Date: Thu, 25 Aug 2022 00:24:53 -0700 Subject: [PATCH 039/151] [snmpd] Fixed snmpd memory leak issue (#11812) #### Why I did it This fixed memory leak in ETHERLIKE-MIB. The fix is not part of net-snmp(5.7.3 version). This PR includes the patch to fix memory leak issue. ``` ke->name in stdup-ed at line 297: n->name = strdup(RTA_DATA(tb[IFLA_IFNAME])); ``` #### How I did it patched the fix. [net-snmp] upstream fix link -> [snmpd}upstream link](https://github.com/net-snmp/net-snmp/commit/ed4e48b5fab165d1ba4c431e31e543f808a2c25f) #### How to verify it **Before The fix** used valgrind to find memory leak. ``` root@lnos-x1-a-csw06:/# grep "definitely lost" valgrind-out.txt ==493== 4 bytes in 1 blocks are definitely lost in loss record 1 of 333 ==493== 16 bytes in 1 blocks are definitely lost in loss record 25 of 333 ==493== 757 bytes in 71 blocks are definitely lost in loss record 214 of 333 ==493== 1,168 (32 direct, 1,136 indirect) bytes in 1 blocks are definitely lost in loss record 293 of 333 ==493== 1,168 (32 direct, 1,136 indirect) bytes in 1 blocks are definitely lost in loss record 294 of 333 ==493== 1,168 (32 direct, 1,136 indirect) bytes in 1 blocks are definitely lost in loss record 295 of 333 ==493== 1,168 (32 direct, 1,136 indirect) bytes in 1 blocks are definitely lost in loss record 296 of 333 ==493== definitely lost: 905 bytes in 77 blocks ``` _we can see the memory leak see in stack trace._ -> dot3stats_linux -> get_nlmsg -> strdup https://github.com/net-snmp/net-snmp/blob/v5.7.3/agent/mibgroup/etherlike-mib/data_access/dot3stats_linux.c https://github.com/net-snmp/net-snmp/blob/v5.7.3/agent/mibgroup/etherlike-mib/data_access/dot3stats_linux.c#L277 ``` n = malloc(sizeof(*n)); memset(n, 0, sizeof(*n)); n->ifindex = ifi->ifi_index; n->name = strdup(RTA_DATA(tb[IFLA_IFNAME])); memcpy(&n->stats, RTA_DATA(tb[IFLA_STATS]), sizeof(n->stats)); n->next = kern_db; kern_db = n; return 0; ``` we were not freeing space for EtherLike-MIB.AS interface mib queries were getting increased, we see memory increment. ``` kern_db = ke->next; free(ke); ``` https://github.com/net-snmp/net-snmp/blob/v5.7.3/agent/mibgroup/etherlike-mib/data_access/dot3stats_linux.c#L467 ``` ==55== 757 bytes in 71 blocks are definitely lost in loss record 186 of 299 ==55== at 0x483577F: malloc (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so) ==55== by 0x4EB6E49: strdup (strdup.c:42) ==55== by 0x493F278: get_nlmsg (dot3stats_linux.c:299) ==55== by 0x493F529: rtnl_dump_filter_l.constprop.3 (dot3stats_linux.c:370) ==55== by 0x493FD7A: rtnl_dump_filter (dot3stats_linux.c:401) ==55== by 0x493FD7A: _dot3Stats_netlink_get_errorcntrs (dot3stats_linux.c:424) ==55== by 0x494009F: interface_dot3stats_get_errorcounters (dot3stats_linux.c:530) ==55== by 0x48F6FDA: dot3StatsTable_container_load (dot3StatsTable_data_access.c:330) ==55== by 0x485E76B: _cache_load (cache_handler.c:700) ==55== by 0x485FA37: netsnmp_cache_helper_handler (cache_handler.c:638) ==55== by 0x48720BC: netsnmp_call_handler (agent_handler.c:526) ==55== by 0x48720BC: netsnmp_call_next_handler (agent_handler.c:640) ==55== by 0x4865F75: table_helper_handler (table.c:717) ==55== by 0x4871B66: netsnmp_call_handler (agent_handler.c:526) ==55== by 0x4871B66: netsnmp_call_handlers (agent_handler.c:611) 757 bytes in 71 blocks are definitely lost in loss record 214 of 333 ==493== at 0x483577F: malloc (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so) ==493== by 0x4EB6E49: strdup (strdup.c:42) ==493== by 0x493F278: ??? (in /usr/lib/x86_64-linux-gnu/libnetsnmpmibs.so.30.0.3) ==493== by 0x493F529: ??? (in /usr/lib/x86_64-linux-gnu/libnetsnmpmibs.so.30.0.3) ==493== by 0x493FD7A: _dot3Stats_netlink_get_errorcntrs (in /usr/lib/x86_64-linux-gnu/libnetsnmpmibs.so.30.0.3) ==493== by 0x494009F: interface_dot3stats_get_errorcounters (in /usr/lib/x86_64-linux-gnu/libnetsnmpmibs.so.30.0.3) ==493== by 0x48F6FDA: dot3StatsTable_container_load (in /usr/lib/x86_64-linux-gnu/libnetsnmpmibs.so.30.0.3) ==493== by 0x485E76B: _cache_load (cache_handler.c:700) ==493== by 0x485FA37: netsnmp_cache_helper_handler (cache_handler.c:638) ==493== by 0x48720BC: netsnmp_call_handler (agent_handler.c:526) ==493== by 0x48720BC: netsnmp_call_next_handler (agent_handler.c:640) ==493== by 0x4865F75: table_helper_handler (table.c:717) ==493== by 0x4871B66: netsnmp_call_handler (agent_handler.c:526) ==493== by 0x4871B66: netsnmp_call_handlers (agent_handler.c:611) ``` ``` **After The fix** no memory leak in valgrind stack trace related to etherlike MIB. ``` --- .../patch-5.7.3+dfsg/0022-etherlike-mib-memleak.patch | 9 +++++++++ src/snmpd/patch-5.7.3+dfsg/series | 1 + 2 files changed, 10 insertions(+) create mode 100644 src/snmpd/patch-5.7.3+dfsg/0022-etherlike-mib-memleak.patch diff --git a/src/snmpd/patch-5.7.3+dfsg/0022-etherlike-mib-memleak.patch b/src/snmpd/patch-5.7.3+dfsg/0022-etherlike-mib-memleak.patch new file mode 100644 index 000000000000..eb921786b444 --- /dev/null +++ b/src/snmpd/patch-5.7.3+dfsg/0022-etherlike-mib-memleak.patch @@ -0,0 +1,9 @@ +--- net-snmp-5.7.3+dfsg/agent/mibgroup/etherlike-mib/data_access/dot3stats_linux.c.org 2020-09-03 19:09:26.241863000 -0700 ++++ net-snmp-5.7.3+dfsg/agent/mibgroup/etherlike-mib/data_access/dot3stats_linux.c 2020-09-03 19:24:27.054098000 -0700 +@@ -465,6 +465,7 @@ + done = 1; + } + kern_db = ke->next; ++ free(ke->name); + free(ke); + } diff --git a/src/snmpd/patch-5.7.3+dfsg/series b/src/snmpd/patch-5.7.3+dfsg/series index 769b2938d37a..11dabe8d1d64 100644 --- a/src/snmpd/patch-5.7.3+dfsg/series +++ b/src/snmpd/patch-5.7.3+dfsg/series @@ -4,3 +4,4 @@ 0007-Linux-VRF-5.7.3-Support.patch 0008-Enable-macro-DEB_BUILD_ARCH_OS-in-order-to-build-ipv.patch cross-compile-changes.patch +0022-etherlike-mib-memleak.patch From 83704d995544c3e80c6451512f5f3d48b227b571 Mon Sep 17 00:00:00 2001 From: ShiyanWangMS Date: Thu, 25 Aug 2022 15:55:01 +0800 Subject: [PATCH 040/151] Upgrade docker-sonic-mgmt base image from Ubuntu18.04 to 20.04 (#11831) Update base image from ubuntu18.04 to ubuntu20.04 Fix necessary dependencies. After upgrade, Py2 is 2.7.18, Py3 is 3.8.10. --- dockers/docker-sonic-mgmt/Dockerfile.j2 | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/dockers/docker-sonic-mgmt/Dockerfile.j2 b/dockers/docker-sonic-mgmt/Dockerfile.j2 index 42aaa3525a64..1275a21c5af2 100755 --- a/dockers/docker-sonic-mgmt/Dockerfile.j2 +++ b/dockers/docker-sonic-mgmt/Dockerfile.j2 @@ -1,5 +1,5 @@ {% set prefix = DEFAULT_CONTAINER_REGISTRY %} -FROM {{ prefix }}ubuntu:18.04 +FROM {{ prefix }}ubuntu:20.04 ENV DEBIAN_FRONTEND=noninteractive @@ -21,8 +21,6 @@ RUN apt-get update && apt-get install -y build-essential \ psmisc \ python \ python-dev \ - python-scapy \ - python-pip \ python3-pip \ python3-venv \ rsyslog \ @@ -31,10 +29,16 @@ RUN apt-get update && apt-get install -y build-essential \ sudo \ tcpdump \ telnet \ - vim + vim \ + python-is-python2 \ + software-properties-common + +RUN add-apt-repository -y universe +RUN curl https://bootstrap.pypa.io/pip/2.7/get-pip.py --output get-pip.py \ + && python2 get-pip.py RUN pip install setuptools==44.1.1 -RUN pip install cffi==1.10.0 \ +RUN pip install cffi==1.12.0 \ contextlib2==0.6.0.post1 \ cryptography==3.3.2 \ "future>=0.16.0" \ @@ -96,7 +100,7 @@ RUN pip install cffi==1.10.0 \ && rm -f 1.0.0.tar.gz \ && pip install nnpy \ && pip install dpkt \ - && pip install scapy==2.4.5 --upgrade + && pip install scapy==2.4.5 --upgrade --ignore-installed # Install docker-ce-cli RUN apt-get update \ @@ -127,7 +131,7 @@ debs/{{ deb }}{{' '}} {%- endfor -%} debs/ -RUN dpkg -i \ +RUN dpkg --force-all -i \ {% for deb in docker_sonic_mgmt_debs.split(' ') -%} debs/{{ deb }}{{' '}} {%- endfor %} @@ -193,8 +197,7 @@ ENV PATH="$VIRTUAL_ENV/bin:$PATH" ENV LANG=C.UTF-8 LC_ALL=C.UTF-8 PYTHONIOENCODING=UTF-8 -RUN python3 -m pip install --upgrade --ignore-installed pip setuptools==58.4.0 - +RUN python3 -m pip install --upgrade --ignore-installed pip setuptools==58.4.0 wheel==0.33.6 RUN python3 -m pip install setuptools-rust \ aiohttp \ defusedxml \ @@ -237,7 +240,6 @@ RUN python3 -m pip install setuptools-rust \ tabulate \ textfsm==1.1.2 \ virtualenv \ - wheel==0.33.6 \ pysubnettree \ nnpy \ dpkt \ From 0cdef2ebc6a87a2ab93cb9c8aa177923622c4b90 Mon Sep 17 00:00:00 2001 From: Jing Zhang Date: Thu, 25 Aug 2022 08:46:45 -0700 Subject: [PATCH 041/151] [YANG] add peer switch model (#11828) Why I did it Address issue #10966 sign-off: Jing Zhang zhangjing@microsoft.com How I did it Add sonic-peer-switch.yang and unit tests. How to verify it Compile Compile target/python-wheels/sonic_yang_mgmt-1.0-py3-none-any.whl and target/python-wheels/sonic_yang_models-1.0-py3-none-any.whl. Which release branch to backport (provide reason below if selected) 201811 201911 202006 202012 202106 202111 202205 Description for the changelog Link to config_db schema for YANG module changes https://github.com/sonic-net/sonic-buildimage/blob/b721ff87b976a6a38bdd65443ea3bc686014e783/src/sonic-yang-models/doc/Configuration.md#peer-switch --- src/sonic-yang-models/doc/Configuration.md | 142 ++++++++++-------- src/sonic-yang-models/setup.py | 1 + .../tests/files/sample_config_db.json | 5 + .../yang_model_tests/tests/peer-switch.json | 13 ++ .../tests_config/peer-switch.json | 39 +++++ .../yang-models/sonic-peer-switch.yang | 49 ++++++ 6 files changed, 185 insertions(+), 64 deletions(-) create mode 100644 src/sonic-yang-models/tests/yang_model_tests/tests/peer-switch.json create mode 100644 src/sonic-yang-models/tests/yang_model_tests/tests_config/peer-switch.json create mode 100644 src/sonic-yang-models/yang-models/sonic-peer-switch.yang diff --git a/src/sonic-yang-models/doc/Configuration.md b/src/sonic-yang-models/doc/Configuration.md index 6c01344f63af..2167cab027ed 100644 --- a/src/sonic-yang-models/doc/Configuration.md +++ b/src/sonic-yang-models/doc/Configuration.md @@ -36,6 +36,7 @@ Table of Contents * [MAP_PFC_PRIORITY_TO_QUEUE](#map_pfc_priority_to_queue) * [NTP Global Configuration](#ntp-global-configuration) * [NTP and SYSLOG servers](#ntp-and-syslog-servers) + * [Peer Switch](#peer-switch) * [Policer](#policer) * [Port](#port) * [Port Channel](#port-channel) @@ -724,13 +725,13 @@ This kind of profiles will be handled by buffer manager and won't be applied to ### Data Plane L3 Interfaces -IP configuration for data plane are defined in **INTERFACE**, **VLAN_SUB_INTERFACE**, -**PORTCHANNEL_INTERFACE** and **VLAN_INTERFACE** table. The objects -in all four tables have the interface (could be physical port, port -channel, vlan or vlan sub interface) that IP address is attached to as first-level key, and -IP prefix as second-level key. IP interface address objects don't have any attributes. -IP interface attributes, resides in those tables as well, key is the interface name -and value is a list of field-values representing the interface attributes, e.g. loopback action. +IP configuration for data plane are defined in **INTERFACE**, **VLAN_SUB_INTERFACE**, +**PORTCHANNEL_INTERFACE** and **VLAN_INTERFACE** table. The objects +in all four tables have the interface (could be physical port, port +channel, vlan or vlan sub interface) that IP address is attached to as first-level key, and +IP prefix as second-level key. IP interface address objects don't have any attributes. +IP interface attributes, resides in those tables as well, key is the interface name +and value is a list of field-values representing the interface attributes, e.g. loopback action. ``` { @@ -738,27 +739,27 @@ and value is a list of field-values representing the interface attributes, e.g. "Ethernet0|10.0.0.0/31": {}, "Ethernet4|10.0.0.2/31": {}, "Ethernet8|10.0.0.4/31": {} - "Ethernet8": { - "loopback_action": "drop" - } + "Ethernet8": { + "loopback_action": "drop" + } }, - + "PORTCHANNEL_INTERFACE": { "PortChannel01|10.0.0.56/31": {}, "PortChannel01|FC00::71/126": {}, "PortChannel02|10.0.0.58/31": {}, "PortChannel02|FC00::75/126": {} }, - + "VLAN_INTERFACE": { "Vlan1000|192.168.0.1/27": {} - }, - -"VLAN_SUB_INTERFACE": { - "Ethernet4.1|10.0.0.2/31": {}, - "Ethernet4.1": { - "loopback_action": "drop" - } + }, + +"VLAN_SUB_INTERFACE": { + "Ethernet4.1|10.0.0.2/31": {}, + "Ethernet4.1": { + "loopback_action": "drop" + } } } ``` @@ -1114,51 +1115,64 @@ These information are configured in individual tables. Domain name or IP address of the server is used as object key. Currently there are no attributes in those objects. -***NTP server*** -``` -{ - "NTP_SERVER": { - "2.debian.pool.ntp.org": {}, - "1.debian.pool.ntp.org": {}, - "3.debian.pool.ntp.org": {}, - "0.debian.pool.ntp.org": {} - }, - - "NTP_SERVER": { - "23.92.29.245": {}, - "204.2.134.164": {} - } -} -``` - -***Syslog server*** -``` -{ - "SYSLOG_SERVER": { - "10.0.0.5": {}, - "10.0.0.6": {}, - "10.11.150.5": {} - }, - - "SYSLOG_SERVER" : { - "2.2.2.2": { - "source": "1.1.1.1", - "port": "514", - "vrf": "default" - }, - "4.4.4.4": { - "source": "3.3.3.3", - "port": "514", - "vrf": "mgmt" - }, - "2222::2222": { - "source": "1111::1111", - "port": "514", - "vrf": "Vrf-Data" - } - } -} -``` +***NTP server*** +``` +{ + "NTP_SERVER": { + "2.debian.pool.ntp.org": {}, + "1.debian.pool.ntp.org": {}, + "3.debian.pool.ntp.org": {}, + "0.debian.pool.ntp.org": {} + }, + + "NTP_SERVER": { + "23.92.29.245": {}, + "204.2.134.164": {} + } +} +``` + +***Syslog server*** +``` +{ + "SYSLOG_SERVER": { + "10.0.0.5": {}, + "10.0.0.6": {}, + "10.11.150.5": {} + }, + + "SYSLOG_SERVER" : { + "2.2.2.2": { + "source": "1.1.1.1", + "port": "514", + "vrf": "default" + }, + "4.4.4.4": { + "source": "3.3.3.3", + "port": "514", + "vrf": "mgmt" + }, + "2222::2222": { + "source": "1111::1111", + "port": "514", + "vrf": "Vrf-Data" + } + } +} +``` + +### Peer Switch + +Below is an exmaple of the peer switch table configuration. +``` +{ + "PEER_SWITCH": { + "vlab-05": { + "address_ipv4": "10.1.0.33" + } + } +} +``` ### Policer diff --git a/src/sonic-yang-models/setup.py b/src/sonic-yang-models/setup.py index ee4f7e55bca8..f5ff5b5fe5f2 100644 --- a/src/sonic-yang-models/setup.py +++ b/src/sonic-yang-models/setup.py @@ -152,6 +152,7 @@ def run(self): './yang-models/sonic-storm-control.yang', './yang-models/sonic-tc-priority-group-map.yang', './yang-models/sonic-tc-queue-map.yang', + './yang-models/sonic-peer-switch.yang', './yang-models/sonic-pfc-priority-queue-map.yang', './yang-models/sonic-pfc-priority-priority-group-map.yang', './yang-models/sonic-port-qos-map.yang', diff --git a/src/sonic-yang-models/tests/files/sample_config_db.json b/src/sonic-yang-models/tests/files/sample_config_db.json index db7798f31835..c7d199fa9f24 100644 --- a/src/sonic-yang-models/tests/files/sample_config_db.json +++ b/src/sonic-yang-models/tests/files/sample_config_db.json @@ -1798,6 +1798,11 @@ } }, + "PEER_SWITCH": { + "vlab-05": { + "address_ipv4": "10.1.0.33" + } + }, "POLICER": { "everflow_static_policer": { diff --git a/src/sonic-yang-models/tests/yang_model_tests/tests/peer-switch.json b/src/sonic-yang-models/tests/yang_model_tests/tests/peer-switch.json new file mode 100644 index 000000000000..b8ee10dbdf9c --- /dev/null +++ b/src/sonic-yang-models/tests/yang_model_tests/tests/peer-switch.json @@ -0,0 +1,13 @@ +{ + "PEER_SWITCH_LOAD_NORMAL": { + "desc": "Load PEER_SWITCH for dualtor device." + }, + "PEER_SWITCH_MISSING_DEVICE__NAME": { + "desc": "Load PEER_SWITCH missing PEER Device name.", + "eStrKey": "Mandatory" + }, + "PEER_SWITCH_INVALID_IP_ADDRESS": { + "desc": "Load PEER_SWITCH with invalid IPv4 Address.", + "eStrKey": "Pattern" + } +} diff --git a/src/sonic-yang-models/tests/yang_model_tests/tests_config/peer-switch.json b/src/sonic-yang-models/tests/yang_model_tests/tests_config/peer-switch.json new file mode 100644 index 000000000000..e3857fc392e8 --- /dev/null +++ b/src/sonic-yang-models/tests/yang_model_tests/tests_config/peer-switch.json @@ -0,0 +1,39 @@ +{ + "PEER_SWITCH_LOAD_NORMAL": { + "sonic-peer-switch:sonic-peer-switch": { + "sonic-peer-switch:PEER_SWITCH": { + "PEER_SWITCH_LIST": [ + { + "peer_switch": "vlab-05", + "address_ipv4": "10.1.0.33" + } + ] + } + } + }, + + "PEER_SWITCH_MISSING_DEVICE__NAME": { + "sonic-peer-switch:sonic-peer-switch": { + "sonic-peer-switch:PEER_SWITCH": { + "PEER_SWITCH_LIST": [ + { + "address_ipv4": "10.1.0.33" + } + ] + } + } + }, + + "PEER_SWITCH_INVALID_IP_ADDRESS": { + "sonic-peer-switch:sonic-peer-switch": { + "sonic-peer-switch:PEER_SWITCH": { + "PEER_SWITCH_LIST": [ + { + "peer_switch": "vlab-05", + "address_ipv4": "10.1.0.33/32" + } + ] + } + } + } +} diff --git a/src/sonic-yang-models/yang-models/sonic-peer-switch.yang b/src/sonic-yang-models/yang-models/sonic-peer-switch.yang new file mode 100644 index 000000000000..79a94c95c2c0 --- /dev/null +++ b/src/sonic-yang-models/yang-models/sonic-peer-switch.yang @@ -0,0 +1,49 @@ +module sonic-peer-switch { + yang-version 1.1; + namespace "http://github.com/Azure/sonic-peer-switch"; + prefix peer_switch; + + import ietf-inet-types { + prefix inet; + } + + import sonic-types { + prefix stypes; + } + + organization + "SONiC"; + + contact + "SONiC"; + + description + "SONiC DualToR peer switch data"; + + revision 2022-08-23 { + description + "Initial revision"; + } + + container sonic-peer-switch { + container PEER_SWITCH { + list PEER_SWITCH_LIST { + max-elements 1; + + key "peer_switch"; + + leaf peer_switch { + type stypes:hostname; + + description "SONiC DualToR peer host name."; + } + + leaf address_ipv4 { + type inet:ipv4-address; + + description "SONiC DualToR peer's IPv4 address."; + } + } + } + } +} From 8d06de37aea7b1c3c4206ecf1ff6b136ecf9dcd2 Mon Sep 17 00:00:00 2001 From: SuvarnaMeenakshi <50386592+SuvarnaMeenakshi@users.noreply.github.com> Date: Thu, 25 Aug 2022 12:39:52 -0700 Subject: [PATCH 042/151] Add support to get fabric asic namespaces list. (#11793) Why I did it VoQ chassis supervisor will have Fabric asics and the sub_role for fabric asics will be "Fabric". The fabric asics namespaces are not being returned in get_all_namespaces() and is required in caclmgrd to add right cacl to allow internal docker traffic from fabric asic namespaces. test_cacl_application fails on VoQ chassis Supervisor with the error: Failed: Missing expected iptables rules: set(['-A INPUT -s 240.127.1.1/32 -d 240.127.1.1/32 -j ACCEPT', '-A INPUT -s 240.127.1.3/32 -d 240.127.1.1/32 -j ACCEPT', '-A INPUT -s 240.127.1.2/32 -d 240.127.1.1/32 -j ACCEPT']) How I did it Update get_all_namespaces to return fabric namespaces list. How to verify it Verified on VoQ chassis. --- src/sonic-py-common/sonic_py_common/multi_asic.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/sonic-py-common/sonic_py_common/multi_asic.py b/src/sonic-py-common/sonic_py_common/multi_asic.py index e03dc6447c90..d63c698392e4 100644 --- a/src/sonic-py-common/sonic_py_common/multi_asic.py +++ b/src/sonic-py-common/sonic_py_common/multi_asic.py @@ -13,6 +13,7 @@ ASIC_CONF_FILENAME = 'asic.conf' FRONTEND_ASIC_SUB_ROLE = 'FrontEnd' BACKEND_ASIC_SUB_ROLE = 'BackEnd' +FABRIC_ASIC_SUB_ROLE = 'Fabric' EXTERNAL_PORT = 'Ext' INTERNAL_PORT = 'Int' INBAND_PORT = 'Inb' @@ -210,6 +211,7 @@ def get_all_namespaces(): """ front_ns = [] back_ns = [] + fabric_ns = [] num_asics = get_num_asics() if is_multi_asic(): @@ -224,8 +226,10 @@ def get_all_namespaces(): front_ns.append(namespace) elif metadata['localhost']['sub_role'] == BACKEND_ASIC_SUB_ROLE: back_ns.append(namespace) + elif metadata['localhost']['sub_role'] == FABRIC_ASIC_SUB_ROLE: + fabric_ns.append(namespace) - return {'front_ns': front_ns, 'back_ns': back_ns} + return {'front_ns': front_ns, 'back_ns': back_ns, 'fabric_ns': fabric_ns} def get_namespace_list(namespace=None): From 13bd63e73a4bad961e9b32f0dec11459fd0f2958 Mon Sep 17 00:00:00 2001 From: arunlk-dell <83708154+arunlk-dell@users.noreply.github.com> Date: Fri, 26 Aug 2022 05:37:23 +0530 Subject: [PATCH 043/151] DellEMC: S5296F Platform API 2.0 changes (#11162) Why I did it S5296F - Platform API 2.0 changes How I did it Implemented the functional API's needed for Platform API 2.0 How to verify it Used the API 2.0 test suite to validate the test cases. --- .../platform.json | 578 ++++++++++++++++++ .../pmon_daemon_control.json | 7 +- .../debian/platform-modules-s5296f.install | 1 + .../sonic-platform-modules-dell/debian/rules | 10 + .../s5296f/modules/dell_s5296f_fpga_ocores.c | 513 ++++++---------- .../s5296f/setup.py | 1 + .../s5296f/sonic_platform/__init__.py | 3 + .../s5296f/sonic_platform/chassis.py | 453 ++++++++++++++ .../s5296f/sonic_platform/component.py | 233 +++++++ .../s5296f/sonic_platform/eeprom.py | 133 ++++ .../s5296f/sonic_platform/fan.py | 214 +++++++ .../s5296f/sonic_platform/fan_drawer.py | 110 ++++ .../s5296f/sonic_platform/hwaccess.py | 1 + .../sonic_platform/media_settings_plugin.py | 13 + .../s5296f/sonic_platform/platform.py | 24 + .../s5296f/sonic_platform/psu.py | 325 ++++++++++ .../s5296f/sonic_platform/sfp.py | 367 +++++++++++ .../s5296f/sonic_platform/thermal.py | 189 ++++++ .../s5296f/sonic_platform/watchdog.py | 207 +++++++ 19 files changed, 3049 insertions(+), 333 deletions(-) create mode 100644 device/dell/x86_64-dellemc_s5296f_c3538-r0/platform.json create mode 120000 platform/broadcom/sonic-platform-modules-dell/s5296f/setup.py create mode 100644 platform/broadcom/sonic-platform-modules-dell/s5296f/sonic_platform/__init__.py create mode 100644 platform/broadcom/sonic-platform-modules-dell/s5296f/sonic_platform/chassis.py create mode 100644 platform/broadcom/sonic-platform-modules-dell/s5296f/sonic_platform/component.py create mode 100644 platform/broadcom/sonic-platform-modules-dell/s5296f/sonic_platform/eeprom.py create mode 100644 platform/broadcom/sonic-platform-modules-dell/s5296f/sonic_platform/fan.py create mode 100644 platform/broadcom/sonic-platform-modules-dell/s5296f/sonic_platform/fan_drawer.py create mode 120000 platform/broadcom/sonic-platform-modules-dell/s5296f/sonic_platform/hwaccess.py create mode 100644 platform/broadcom/sonic-platform-modules-dell/s5296f/sonic_platform/media_settings_plugin.py create mode 100644 platform/broadcom/sonic-platform-modules-dell/s5296f/sonic_platform/platform.py create mode 100644 platform/broadcom/sonic-platform-modules-dell/s5296f/sonic_platform/psu.py create mode 100644 platform/broadcom/sonic-platform-modules-dell/s5296f/sonic_platform/sfp.py create mode 100644 platform/broadcom/sonic-platform-modules-dell/s5296f/sonic_platform/thermal.py create mode 100644 platform/broadcom/sonic-platform-modules-dell/s5296f/sonic_platform/watchdog.py diff --git a/device/dell/x86_64-dellemc_s5296f_c3538-r0/platform.json b/device/dell/x86_64-dellemc_s5296f_c3538-r0/platform.json new file mode 100644 index 000000000000..b38f625d6270 --- /dev/null +++ b/device/dell/x86_64-dellemc_s5296f_c3538-r0/platform.json @@ -0,0 +1,578 @@ +{ + "chassis": { + "name": "S5296F-ON", + "status_led": { + "controllable": true, + "colors": ["green", "flashing green", "yellow", "flashing yellow"] + }, + "thermal_manager" : false, + "components": [ + { + "name": "BIOS" + }, + { + "name": "FPGA" + }, + { + "name": "BMC" + }, + { + "name": "System CPLD" + }, + { + "name": "Secondary CPLD 1" + }, + { + "name": "Secondary CPLD 2" + }, + { + "name": "Secondary CPLD 3" + }, + { + "name": "Secondary CPLD 4" + } + ], + "fans": [ + { + "name": "FanTray1-Fan1", + "speed": { + "controllable": false + }, + "status_led": { + "available": false + } + }, + { + "name": "FanTray2-Fan1", + "speed": { + "controllable": false + }, + "status_led": { + "available": false + } + }, + { + "name": "FanTray3-Fan1", + "speed": { + "controllable": false + }, + "status_led": { + "available": false + } + }, + { + "name": "FanTray4-Fan1", + "speed": { + "controllable": false + }, + "status_led": { + "available": false + } + } + ], + "fan_drawers":[ + { + "name": "FanTray1", + "status_led": { + "controllable": false + }, + "fans": [ + { + "name": "FanTray1-Fan1", + "speed": { + "controllable": false + }, + "status_led": { + "available": false + } + } + ] + }, + { + "name": "FanTray2", + "status_led": { + "controllable": false + }, + "fans": [ + { + "name": "FanTray2-Fan1", + "speed": { + "controllable": false + }, + "status_led": { + "available": false + } + } + ] + }, + { + "name": "FanTray3", + "status_led": { + "controllable": false + }, + "fans": [ + { + "name": "FanTray3-Fan1", + "speed": { + "controllable": false + }, + "status_led": { + "available": false + } + } + ] + }, + { + "name": "FanTray4", + "status_led": { + "controllable": false + }, + "fans": [ + { + "name": "FanTray4-Fan1", + "speed": { + "controllable": false + }, + "status_led": { + "available": false + } + } + ] + } + ], + "psus": [ + { + "name": "PSU1", + "status_led": { + "controllable": false + }, + "fans": [ + { + "name": "PSU1 Fan", + "speed": { + "controllable": false + }, + "status_led": { + "available": false + } + } + ] + }, + { + "name": "PSU2", + "status_led": { + "controllable": false + }, + "fans": [ + { + "name": "PSU2 Fan", + "speed": { + "controllable": false + }, + "status_led": { + "available": false + } + } + ] + } + ], + "thermals": [ + { + "name": "ASIC On-board", + "controllable": false, + "low-crit-threshold": false, + "minimum-recorded": false, + "maximum-recorded": false + }, + { + "name": "CPU On-board", + "controllable": false, + "low-crit-threshold": false, + "minimum-recorded": false, + "maximum-recorded": false + }, + { + "name": "Inlet Airflow Sensor", + "controllable": false, + "low-crit-threshold": false, + "high-threshold": false, + "high-crit-threshold": false, + "minimum-recorded": false, + "maximum-recorded": false + }, + { + "name": "PSU1 Airflow Sensor", + "controllable": false, + "low-crit-threshold": false, + "high-threshold": false, + "high-crit-threshold": false, + "minimum-recorded": false, + "maximum-recorded": false + }, + { + "name": "PSU1 Sensor", + "controllable": false, + "low-crit-threshold": false, + "minimum-recorded": false, + "maximum-recorded": false + }, + { + "name": "PSU2 Airflow Sensor", + "controllable": false, + "low-crit-threshold": false, + "high-threshold": false, + "high-crit-threshold": false, + "minimum-recorded": false, + "maximum-recorded": false + }, + { + "name": "PSU2 Sensor", + "controllable": false, + "low-crit-threshold": false, + "minimum-recorded": false, + "maximum-recorded": false + }, + { + "name": "PT Left Sensor", + "controllable": false, + "low-crit-threshold": false, + "minimum-recorded": false, + "maximum-recorded": false + }, + { + "name": "PT Middle Sensor", + "controllable": false, + "low-crit-threshold": false, + "high-threshold": false, + "high-crit-threshold": false, + "minimum-recorded": false, + "maximum-recorded": false + }, + { + "name": "PT Right Sensor", + "controllable": false, + "low-crit-threshold": false, + "high-threshold": false, + "high-crit-threshold": false, + "minimum-recorded": false, + "maximum-recorded": false + } + ], + "modules": [], + "sfps": [ + { + "name": "SFP/SFP+/SFP28" + }, + { + "name": "SFP/SFP+/SFP28" + }, + { + "name": "SFP/SFP+/SFP28" + }, + { + "name": "SFP/SFP+/SFP28" + }, + { + "name": "SFP/SFP+/SFP28" + }, + { + "name": "SFP/SFP+/SFP28" + }, + { + "name": "SFP/SFP+/SFP28" + }, + { + "name": "SFP/SFP+/SFP28" + }, + { + "name": "SFP/SFP+/SFP28" + }, + { + "name": "SFP/SFP+/SFP28" + }, + { + "name": "SFP/SFP+/SFP28" + }, + { + "name": "SFP/SFP+/SFP28" + }, + { + "name": "SFP/SFP+/SFP28" + }, + { + "name": "SFP/SFP+/SFP28" + }, + { + "name": "SFP/SFP+/SFP28" + }, + { + "name": "SFP/SFP+/SFP28" + }, + { + "name": "SFP/SFP+/SFP28" + }, + { + "name": "SFP/SFP+/SFP28" + }, + { + "name": "SFP/SFP+/SFP28" + }, + { + "name": "SFP/SFP+/SFP28" + }, + { + "name": "SFP/SFP+/SFP28" + }, + { + "name": "SFP/SFP+/SFP28" + }, + { + "name": "SFP/SFP+/SFP28" + }, + { + "name": "SFP/SFP+/SFP28" + }, + { + "name": "SFP/SFP+/SFP28" + }, + { + "name": "SFP/SFP+/SFP28" + }, + { + "name": "SFP/SFP+/SFP28" + }, + { + "name": "SFP/SFP+/SFP28" + }, + { + "name": "SFP/SFP+/SFP28" + }, + { + "name": "SFP/SFP+/SFP28" + }, + { + "name": "SFP/SFP+/SFP28" + }, + { + "name": "SFP/SFP+/SFP28" + }, + { + "name": "SFP/SFP+/SFP28" + }, + { + "name": "SFP/SFP+/SFP28" + }, + { + "name": "SFP/SFP+/SFP28" + }, + { + "name": "SFP/SFP+/SFP28" + }, + { + "name": "SFP/SFP+/SFP28" + }, + { + "name": "SFP/SFP+/SFP28" + }, + { + "name": "SFP/SFP+/SFP28" + }, + { + "name": "SFP/SFP+/SFP28" + }, + { + "name": "SFP/SFP+/SFP28" + }, + { + "name": "SFP/SFP+/SFP28" + }, + { + "name": "SFP/SFP+/SFP28" + }, + { + "name": "SFP/SFP+/SFP28" + }, + { + "name": "SFP/SFP+/SFP28" + }, + { + "name": "SFP/SFP+/SFP28" + }, + { + "name": "SFP/SFP+/SFP28" + }, + { + "name": "SFP/SFP+/SFP28" + }, + { + "name": "SFP/SFP+/SFP28" + }, + { + "name": "SFP/SFP+/SFP28" + }, + { + "name": "SFP/SFP+/SFP28" + }, + { + "name": "SFP/SFP+/SFP28" + }, + { + "name": "SFP/SFP+/SFP28" + }, + { + "name": "SFP/SFP+/SFP28" + }, + { + "name": "SFP/SFP+/SFP28" + }, + { + "name": "SFP/SFP+/SFP28" + }, + { + "name": "SFP/SFP+/SFP28" + }, + { + "name": "SFP/SFP+/SFP28" + }, + { + "name": "SFP/SFP+/SFP28" + }, + { + "name": "SFP/SFP+/SFP28" + }, + { + "name": "SFP/SFP+/SFP28" + }, + { + "name": "SFP/SFP+/SFP28" + }, + { + "name": "SFP/SFP+/SFP28" + }, + { + "name": "SFP/SFP+/SFP28" + }, + { + "name": "SFP/SFP+/SFP28" + }, + { + "name": "SFP/SFP+/SFP28" + }, + { + "name": "SFP/SFP+/SFP28" + }, + { + "name": "SFP/SFP+/SFP28" + }, + { + "name": "SFP/SFP+/SFP28" + }, + { + "name": "SFP/SFP+/SFP28" + }, + { + "name": "SFP/SFP+/SFP28" + }, + { + "name": "SFP/SFP+/SFP28" + }, + { + "name": "SFP/SFP+/SFP28" + }, + { + "name": "SFP/SFP+/SFP28" + }, + { + "name": "SFP/SFP+/SFP28" + }, + { + "name": "SFP/SFP+/SFP28" + }, + { + "name": "SFP/SFP+/SFP28" + }, + { + "name": "SFP/SFP+/SFP28" + }, + { + "name": "SFP/SFP+/SFP28" + }, + { + "name": "SFP/SFP+/SFP28" + }, + { + "name": "SFP/SFP+/SFP28" + }, + { + "name": "SFP/SFP+/SFP28" + }, + { + "name": "SFP/SFP+/SFP28" + }, + { + "name": "SFP/SFP+/SFP28" + }, + { + "name": "SFP/SFP+/SFP28" + }, + { + "name": "SFP/SFP+/SFP28" + }, + { + "name": "SFP/SFP+/SFP28" + }, + { + "name": "SFP/SFP+/SFP28" + }, + { + "name": "SFP/SFP+/SFP28" + }, + { + "name": "SFP/SFP+/SFP28" + }, + { + "name": "SFP/SFP+/SFP28" + }, + { + "name": "SFP/SFP+/SFP28" + }, + { + "name": "SFP/SFP+/SFP28" + }, + { + "name": "SFP/SFP+/SFP28" + }, + { + "name": "SFP/SFP+/SFP28" + }, + { + "name": "SFP/SFP+/SFP28" + }, + { + "name": "QSFP28" + }, + { + "name": "QSFP28" + }, + { + "name": "QSFP28" + }, + { + "name": "QSFP28" + }, + { + "name": "QSFP28" + }, + { + "name": "QSFP28" + }, + { + "name": "QSFP28" + }, + { + "name": "QSFP28" + } + ] + }, + "interfaces": {} +} diff --git a/device/dell/x86_64-dellemc_s5296f_c3538-r0/pmon_daemon_control.json b/device/dell/x86_64-dellemc_s5296f_c3538-r0/pmon_daemon_control.json index 72ef3c2210a2..94592fa8cebc 100644 --- a/device/dell/x86_64-dellemc_s5296f_c3538-r0/pmon_daemon_control.json +++ b/device/dell/x86_64-dellemc_s5296f_c3538-r0/pmon_daemon_control.json @@ -1,8 +1,3 @@ { - "skip_sensors": true, - "skip_fancontrol": true, - "skip_ledd": true, - "skip_psud": true, - "skip_syseepromd": true, - "skip_thermalctld": true + "skip_ledd": true } diff --git a/platform/broadcom/sonic-platform-modules-dell/debian/platform-modules-s5296f.install b/platform/broadcom/sonic-platform-modules-dell/debian/platform-modules-s5296f.install index 497554a476c1..f102aa9e318a 100644 --- a/platform/broadcom/sonic-platform-modules-dell/debian/platform-modules-s5296f.install +++ b/platform/broadcom/sonic-platform-modules-dell/debian/platform-modules-s5296f.install @@ -4,6 +4,7 @@ s5296f/scripts/sensors usr/bin s5296f/scripts/pcisysfs.py usr/bin s5296f/cfg/s5296f-modules.conf etc/modules-load.d s5296f/systemd/platform-modules-s5296f.service etc/systemd/system +s5296f/modules/sonic_platform-1.0-py3-none-any.whl usr/share/sonic/device/x86_64-dellemc_s5296f_c3538-r0 common/platform_reboot usr/share/sonic/device/x86_64-dellemc_s5296f_c3538-r0 common/fw-updater usr/local/bin common/onie_mode_set usr/local/bin diff --git a/platform/broadcom/sonic-platform-modules-dell/debian/rules b/platform/broadcom/sonic-platform-modules-dell/debian/rules index 421057fdac33..871bab3a46b0 100755 --- a/platform/broadcom/sonic-platform-modules-dell/debian/rules +++ b/platform/broadcom/sonic-platform-modules-dell/debian/rules @@ -55,6 +55,11 @@ override_dh_auto_build: cd $(MOD_SRC_DIR)/$${mod}; \ python3 setup.py bdist_wheel -d $(MOD_SRC_DIR)/$${mod}/modules; \ cd $(MOD_SRC_DIR); \ + elif [ $$mod = "s5296f" ]; then \ + cp $(COMMON_DIR)/ipmihelper.py $(MOD_SRC_DIR)/$${mod}/sonic_platform/ipmihelper.py; \ + cd $(MOD_SRC_DIR)/$${mod}; \ + python3 setup.py bdist_wheel -d $(MOD_SRC_DIR)/$${mod}/modules; \ + cd $(MOD_SRC_DIR); \ elif [ $$mod = "n3248te" ]; then \ cd $(MOD_SRC_DIR)/$${mod}; \ python3 setup.py bdist_wheel -d $(MOD_SRC_DIR)/$${mod}/modules; \ @@ -143,6 +148,11 @@ override_dh_clean: rm -f $(MOD_SRC_DIR)/$${mod}/modules/*.whl; \ rm -rf $(MOD_SRC_DIR)/$${mod}/build; \ rm -rf $(MOD_SRC_DIR)/$${mod}/build/*.egg-info; \ + elif [ $$mod = "s5296f" ]; then \ + rm -f $(MOD_SRC_DIR)/$${mod}/sonic_platform/ipmihelper.py; \ + rm -f $(MOD_SRC_DIR)/$${mod}/modules/*.whl; \ + rm -rf $(MOD_SRC_DIR)/$${mod}/build; \ + rm -rf $(MOD_SRC_DIR)/$${mod}/build/*.egg-info; \ elif [ $$mod = "z9332f" ]; then \ rm -f $(MOD_SRC_DIR)/$${mod}/sonic_platform/ipmihelper.py; \ rm -f $(MOD_SRC_DIR)/$${mod}/modules/*.whl; \ diff --git a/platform/broadcom/sonic-platform-modules-dell/s5296f/modules/dell_s5296f_fpga_ocores.c b/platform/broadcom/sonic-platform-modules-dell/s5296f/modules/dell_s5296f_fpga_ocores.c index 0673d6e9d0ac..d2bb1b6f7617 100644 --- a/platform/broadcom/sonic-platform-modules-dell/s5296f/modules/dell_s5296f_fpga_ocores.c +++ b/platform/broadcom/sonic-platform-modules-dell/s5296f/modules/dell_s5296f_fpga_ocores.c @@ -89,7 +89,7 @@ struct fpgapci_dev { unsigned int irq_first; unsigned int irq_length; unsigned int irq_assigned; - unsigned int xcvr_intr_count; + }; static int use_irq = 1; @@ -107,6 +107,13 @@ MODULE_PARM_DESC(num_bus, /* Subsystem: Xilinx Corporation Device 0007 */ //#define VENDOR 0x10EE #define DEVICE 0x7021 + +/* Altera FPGA PCIE info: + Unassigned class [ff00]: Altera Corporation Device 0004 (rev 01) + Subsystem: Altera Corporation Device 0004 */ +#define PCI_VENDOR_ID_ALTERA 0x1172 +#define PCI_DEVICE_ID_ALTERA 0x0004 + static phys_addr_t fpga_phys_addr; typedef signed char s8; @@ -190,7 +197,7 @@ struct fpgalogic_i2c { #define FPGAI2C_REG_STAT_NACK 0x80 /* SR[7:0] - Status register */ -#define FPGAI2C_REG_SR_RXACK (1 << 7) /* Receive acknowledge from slave ‘1’ = No acknowledge received*/ +#define FPGAI2C_REG_SR_RXACK (1 << 7) /* Receive acknowledge from secondary �1� = No acknowledge received*/ #define FPGAI2C_REG_SR_BUSY (1 << 6) /* Busy, I2C bus busy (as defined by start / stop bits) */ #define FPGAI2C_REG_SR_AL (1 << 5) /* Arbitration lost - fpga i2c logic lost arbitration */ #define FPGAI2C_REG_SR_TIP (1 << 1) /* Transfer in progress */ @@ -227,13 +234,6 @@ enum { #define I2C_PCI_BUS_NUM_12 12 #define I2C_PCI_BUS_NUM_16 16 -#define IRQ_LTCH_STS 0x20 -#define PRSNT_LTCH_STS 0x10 - -#define PORT_CTRL_OFFSET 0x4000 -#define PORT_STS_OFFSET 0x4004 -#define PORT_IRQ_STS_OFFSET 0x4008 -#define PORT_IRQ_EN_OFFSET 0x400C #define MB_BRD_REV_TYPE 0x0008 #define MB_BRD_REV_MASK 0x00f0 #define MB_BRD_REV_00 0x0000 @@ -256,7 +256,7 @@ enum { #define BRD_TYPE_S5232_NON_NEBS 0xc #define BRD_TYPE_S5232_NEBS 0xd -#define FPGA_CTL_REG_SIZE 0x6000 +#define FPGA_CTL_REG_SIZE 0x60 #define MSI_VECTOR_MAP_MASK 0x1f #define MSI_VECTOR_MAP1 0x58 #define I2C_CH1_MSI_MAP_VECT_8 0x00000008 @@ -292,8 +292,6 @@ enum { #define MSI_VECTOR_REV_00 16 #define MSI_VECTOR_REV_01 32 -#define FPGA_MSI_VECTOR_ID_4 4 -#define FPGA_MSI_VECTOR_ID_5 5 #define FPGA_MSI_VECTOR_ID_8 8 #define FPGA_MSI_VECTOR_ID_9 9 #define FPGA_MSI_VECTOR_ID_10 10 @@ -312,7 +310,7 @@ enum { #define FPGA_MSI_VECTOR_ID_23 23 #define FPGA_MSI_VECTOR_ID_24 24 - +#define MAX_WAIT_LOOP 10 static int total_i2c_pci_bus = 0; static uint32_t board_rev_type = 0; @@ -431,7 +429,7 @@ static int fpgai2c_poll(struct fpgalogic_i2c *i2c) } /* Error? */ - if (stat & FPGAI2C_REG_STAT_ARBLOST) { + if ((stat & FPGAI2C_REG_STAT_ARBLOST) || ( i2c->msg == NULL) || ( i2c->msg->buf == NULL)) { i2c->state = STATE_ERROR; fpgai2c_reg_set(i2c, FPGAI2C_REG_CMD, FPGAI2C_REG_CMD_STOP); return -EAGAIN; @@ -516,72 +514,6 @@ static int fpgai2c_poll(struct fpgalogic_i2c *i2c) return 0; } -static ssize_t get_mod_msi(struct device *dev, struct device_attribute *devattr, char *buf) -{ - int ind = 0, port_status=0, port_irq_status=0; - struct fpgapci_dev *fpgapci = (struct fpgapci_dev*) dev_get_drvdata(dev); - PRINT("%s:xcvr_intr_count:%u\n", __FUNCTION__, fpgapci->xcvr_intr_count); - for(ind=0;ind<64;ind++) - { - port_status = ioread32(fpga_ctl_addr + PORT_STS_OFFSET + (ind*16)); - port_irq_status = ioread32(fpga_ctl_addr + PORT_IRQ_STS_OFFSET + (ind*16)); - PRINT("%s:port:%d, port_status:%#x, port_irq_status:%#x\n", __FUNCTION__, ind, port_status, port_irq_status); - } - return sprintf(buf,"0x%04x\n",fpgapci->xcvr_intr_count); -} -static DEVICE_ATTR(port_msi, S_IRUGO, get_mod_msi, NULL); - -static struct attribute *port_attrs[] = { - &dev_attr_port_msi.attr, - NULL, -}; - -static struct attribute_group port_attr_grp = { - .attrs = port_attrs, -}; - - -static irqreturn_t fpgaport_1_32_isr(int irq, void *dev) -{ - struct pci_dev *pdev = dev; - struct fpgapci_dev *fpgapci = (struct fpgapci_dev*) dev_get_drvdata(&pdev->dev); - int ind = 0, port_status=0, port_irq_status=0; - for(ind=0;ind<32;ind++) - { - port_irq_status = ioread32(fpga_ctl_addr + PORT_IRQ_STS_OFFSET + (ind*16)); - if(port_irq_status&(IRQ_LTCH_STS|PRSNT_LTCH_STS)) - { - PRINT("%s:port:%d, port_status:%#x, port_irq_status:%#x\n", __FUNCTION__, ind, port_status, port_irq_status); - //write on clear - iowrite32( IRQ_LTCH_STS|PRSNT_LTCH_STS,fpga_ctl_addr + PORT_IRQ_STS_OFFSET + (ind*16)); - } - } - fpgapci->xcvr_intr_count++; - PRINT("%s: xcvr_intr_count:%u\n", __FUNCTION__, fpgapci->xcvr_intr_count); - sysfs_notify(&pdev->dev.kobj, NULL, "port_msi"); - return IRQ_HANDLED; -} - -static irqreturn_t fpgaport_33_64_isr(int irq, void *dev) -{ - struct pci_dev *pdev = dev; - struct fpgapci_dev *fpgapci = (struct fpgapci_dev*) dev_get_drvdata(&pdev->dev); - int ind = 0, port_status=0, port_irq_status=0; - for(ind=32;ind<64;ind++) - { - port_irq_status = ioread32(fpga_ctl_addr + PORT_IRQ_STS_OFFSET + (ind*16)); - if(port_irq_status| (IRQ_LTCH_STS|PRSNT_LTCH_STS)) - { - PRINT("%s:port:%d, port_status:%#x, port_irq_status:%#x\n", __FUNCTION__, ind, port_status, port_irq_status); - iowrite32( IRQ_LTCH_STS|PRSNT_LTCH_STS,fpga_ctl_addr + PORT_IRQ_STS_OFFSET + (ind*16)); - } - } - fpgapci->xcvr_intr_count++; - PRINT("%s: xcvr_intr_count:%u\n", __FUNCTION__, fpgapci->xcvr_intr_count); - sysfs_notify(&pdev->dev.kobj, NULL, "port_msi"); - return IRQ_HANDLED; -} - static void fpgai2c_process(struct fpgalogic_i2c *i2c) { struct i2c_msg *msg = i2c->msg; @@ -610,6 +542,12 @@ static void fpgai2c_process(struct fpgalogic_i2c *i2c) return; } + /* Spurious IRQs would lead to invocation of handler with msg being NULL. + * Skip handling them. + */ + if (msg == NULL) + return; + if ((i2c->state == STATE_START) || (i2c->state == STATE_WRITE)) { i2c->state = (msg->flags & I2C_M_RD) ? STATE_READ : STATE_WRITE; @@ -621,6 +559,11 @@ static void fpgai2c_process(struct fpgalogic_i2c *i2c) } } else { + if(( i2c->msg == NULL) || ( i2c->msg->buf == NULL) || (i2c->pos >= i2c->msg->len) ) { + printk("crash debug..1 fpgai2c_process MSG and MAS->BUFF is NULL or pos > len "); + return; + } + msg->buf[i2c->pos++] = fpgai2c_reg_get(i2c, FPGAI2C_REG_DATA); } @@ -657,12 +600,25 @@ static void fpgai2c_process(struct fpgalogic_i2c *i2c) } if (i2c->state == STATE_READ) { + + if(( i2c->msg == NULL) || ( i2c->msg->buf == NULL) || (i2c->pos >= i2c->msg->len) ) { + printk("crash debug..2 fpgai2c_process MSG and MAS->BUFF is NULL or pos > len "); + return; + } + + PRINT("fpgai2c_poll STATE_READ i2c->pos=%d msg->len-1 = 0x%x set FPGAI2C_REG_CMD = 0x%x\n",i2c->pos, msg->len-1, - i2c->pos == (msg->len-1) ? FPGAI2C_REG_CMD_READ_NACK : FPGAI2C_REG_CMD_READ_ACK); + i2c->pos == (msg->len-1) ? FPGAI2C_REG_CMD_READ_NACK : FPGAI2C_REG_CMD_READ_ACK); fpgai2c_reg_set(i2c, FPGAI2C_REG_CMD, i2c->pos == (msg->len-1) ? - FPGAI2C_REG_CMD_READ_NACK : FPGAI2C_REG_CMD_READ_ACK); + FPGAI2C_REG_CMD_READ_NACK : FPGAI2C_REG_CMD_READ_ACK); } else { PRINT("fpgai2c_process set FPGAI2C_REG_DATA(0x%x)\n",FPGAI2C_REG_DATA); + + if(( i2c->msg == NULL) || ( i2c->msg->buf == NULL) || (i2c->pos >= i2c->msg->len) ) { + printk("crash debug..3 fpgai2c_process MSG and MAS->BUFF is NULL or pos > len "); + return; + } + fpgai2c_reg_set(i2c, FPGAI2C_REG_DATA, msg->buf[i2c->pos++]); fpgai2c_reg_set(i2c, FPGAI2C_REG_CMD, FPGAI2C_REG_CMD_WRITE); } @@ -745,7 +701,7 @@ static int fpgai2c_init(struct fpgalogic_i2c *i2c) { int prescale; int diff; - u8 ctrl; + u8 ctrl = 0, stat, loop = 0; if (i2c->reg_io_width == 0) i2c->reg_io_width = 1; /* Set to default value */ @@ -776,9 +732,7 @@ static int fpgai2c_init(struct fpgalogic_i2c *i2c) } } - ctrl = fpgai2c_reg_get(i2c, FPGAI2C_REG_CONTROL); - - PRINT("%s(), line:%d\n", __func__, __LINE__); + PRINT("%s(), line:%d\n", __func__, __LINE__); PRINT("i2c->base = 0x%p\n",i2c->base); PRINT("ctrl = 0x%x\n",ctrl); @@ -806,12 +760,23 @@ static int fpgai2c_init(struct fpgalogic_i2c *i2c) fpgai2c_reg_set(i2c, FPGAI2C_REG_PREHIGH, prescale >> 8); /* Init the device */ - fpgai2c_reg_set(i2c, FPGAI2C_REG_CMD, FPGAI2C_REG_CMD_IACK); - if (!use_irq) - fpgai2c_reg_set(i2c, FPGAI2C_REG_CONTROL, ctrl | FPGAI2C_REG_CTRL_EN); - else - fpgai2c_reg_set(i2c, FPGAI2C_REG_CONTROL, ctrl | FPGAI2C_REG_CTRL_IEN | FPGAI2C_REG_CTRL_EN); - + fpgai2c_reg_set(i2c, FPGAI2C_REG_CONTROL, ctrl | FPGAI2C_REG_CTRL_EN); + if (use_irq) { + /* Clear any pending interrupts */ + fpgai2c_reg_set(i2c, FPGAI2C_REG_CMD, FPGAI2C_REG_CMD_IACK); + while (loop < MAX_WAIT_LOOP) { + stat = fpgai2c_reg_get(i2c, FPGAI2C_REG_STATUS); + if (stat & FPGAI2C_REG_STAT_IF) { + udelay(100); + loop++; + } else { + break; + } + } + if (loop >=10) { + printk("interrupts can't be cleared: loop %d\n", loop); + } + } fpgai2c_dump(i2c); /* Initialize interrupt handlers if not already done */ @@ -820,6 +785,17 @@ static int fpgai2c_init(struct fpgalogic_i2c *i2c) return 0; } +static int fpgai2c_interrupt_enable(struct fpgapci_dev *fpgapci) +{ + int i; + u8 ctrl = 0; + + /* Enable Interrupts */ + for (i = 0 ; i < total_i2c_pci_bus; i ++) { + fpgai2c_reg_set(&fpgalogic_i2c[i], FPGAI2C_REG_CONTROL, ctrl | FPGAI2C_REG_CTRL_IEN | FPGAI2C_REG_CTRL_EN); + } + return 0; +} static u32 fpgai2c_func(struct i2c_adapter *adap) { @@ -861,56 +837,17 @@ static int i2c_init_internal_data(void) } -static int i2c_pci_init (void) +static int i2c_pci_init (struct fpgapci_dev *fpgapci) { int i; - if (num_bus == 0) { - board_rev_type = ioread32(fpga_ctl_addr + MB_BRD_REV_TYPE); - - if ((board_rev_type & MB_BRD_REV_MASK) == MB_BRD_REV_00) { - num_bus = I2C_PCI_MAX_BUS_REV00; - } else if (((board_rev_type & MB_BRD_REV_MASK) == MB_BRD_REV_01) || - ((board_rev_type & MB_BRD_REV_MASK) == MB_BRD_REV_02) || - ((board_rev_type & MB_BRD_REV_MASK) == MB_BRD_REV_03)) { - switch (board_rev_type & MB_BRD_TYPE_MASK){ - case BRD_TYPE_S5212_NON_NEBS: - case BRD_TYPE_S5212_NEBS: - num_bus = I2C_PCI_BUS_NUM_5; - break; - case BRD_TYPE_S5224_NON_NEBS: - case BRD_TYPE_S5224_NEBS: - num_bus = I2C_PCI_BUS_NUM_7; - break; - case BRD_TYPE_Z9232_NON_NEBS: - case BRD_TYPE_Z9232_NEBS: - case BRD_TYPE_S5232_NON_NEBS: - case BRD_TYPE_S5232_NEBS: - num_bus = I2C_PCI_BUS_NUM_8; - break; - case BRD_TYPE_S5248_NON_NEBS: - case BRD_TYPE_S5248_NEBS: - num_bus = I2C_PCI_BUS_NUM_10; - break; - case BRD_TYPE_Z9264_NON_NEBS: - case BRD_TYPE_Z9264_NEBS: - num_bus = I2C_PCI_BUS_NUM_12; - break; - case BRD_TYPE_S5296_NON_NEBS: - case BRD_TYPE_S5296_NEBS: - num_bus = I2C_PCI_BUS_NUM_16; - break; - default: - num_bus = I2C_PCI_BUS_NUM_16; - printk("Wrong BRD_TYPE: 0x%x\n", board_rev_type); - break; - } + if ((fpgapci != NULL) && (fpgapci->pci_dev->vendor == PCI_VENDOR_ID_ALTERA)) { + num_bus = I2C_PCI_BUS_NUM_10; } else { - printk("Wrong board_rev_type 0x%x\n", board_rev_type); - } - } + num_bus = I2C_PCI_MAX_BUS; + } - printk("board_rev_type 0x%x, num_bus 0x%x\n", board_rev_type, num_bus); + printk("vendor 0x%x, num_bus 0x%x\n", fpgapci->pci_dev->vendor, num_bus); total_i2c_pci_bus = num_bus; memset (&i2c_pci_adap, 0, sizeof(i2c_pci_adap)); @@ -1100,196 +1037,119 @@ static int register_intr_handler(struct pci_dev *dev, int irq_num_id) PRINT ( ": fpgapci_dev is 0\n"); return err; } - - if ((board_rev_type & MB_BRD_REV_MASK) == MB_BRD_REV_00) { - /* Request interrupt line for unique function - * alternatively function will be called from free_irq as well - * with flag IRQF_SHARED */ - switch(irq_num_id) { - /* Currently we only support test vector 2 for FPGA Logic I2C channel - * controller 1-7 interrupt*/ - case FPGA_MSI_VECTOR_ID_4: - err = request_irq(dev->irq + irq_num_id, fpgaport_1_32_isr, IRQF_EARLY_RESUME, - FPGA_PCI_NAME, dev); - PRINT ( "%d: fpgapci_dev: irq: %d, %d\n", __LINE__, dev->irq, irq_num_id); - fpgapci->irq_assigned++; - break; - case FPGA_MSI_VECTOR_ID_5: - err = request_irq(dev->irq + irq_num_id, fpgaport_33_64_isr, IRQF_EARLY_RESUME, - FPGA_PCI_NAME, dev); - PRINT ( "%d: fpgapci_dev: irq: %d, %d\n", __LINE__, dev->irq, irq_num_id); - fpgapci->irq_assigned++; - break; - case FPGA_MSI_VECTOR_ID_8: - err = request_irq(dev->irq + irq_num_id, fpgai2c_isr, IRQF_EARLY_RESUME, + /* FPGA SPEC 4.3.1.34, First i2c channel mapped to vector 8 */ + switch (irq_num_id) { + case FPGA_MSI_VECTOR_ID_8: + err = request_irq(dev->irq + irq_num_id, fpgai2c_isr, IRQF_EARLY_RESUME, FPGA_PCI_NAME, &fpgalogic_i2c[0]); - fpgapci->irq_assigned++; - break; - case FPGA_MSI_VECTOR_ID_9: - err = request_irq(dev->irq + irq_num_id, fpgai2c_isr, IRQF_EARLY_RESUME, + fpgapci->irq_assigned++; + break; + case FPGA_MSI_VECTOR_ID_9: + err = request_irq(dev->irq + irq_num_id, fpgai2c_isr, IRQF_EARLY_RESUME, FPGA_PCI_NAME, &fpgalogic_i2c[1]); - fpgapci->irq_assigned++; - break; - case FPGA_MSI_VECTOR_ID_10: - err = request_irq(dev->irq + irq_num_id, fpgai2c_isr, IRQF_EARLY_RESUME, + fpgapci->irq_assigned++; + break; + case FPGA_MSI_VECTOR_ID_10: + err = request_irq(dev->irq + irq_num_id, fpgai2c_isr, IRQF_EARLY_RESUME, FPGA_PCI_NAME, &fpgalogic_i2c[2]); - fpgapci->irq_assigned++; - break; - case FPGA_MSI_VECTOR_ID_11: - err = request_irq(dev->irq + irq_num_id, fpgai2c_isr, IRQF_EARLY_RESUME, + fpgapci->irq_assigned++; + break; + case FPGA_MSI_VECTOR_ID_11: + err = request_irq(dev->irq + irq_num_id, fpgai2c_isr, IRQF_EARLY_RESUME, FPGA_PCI_NAME, &fpgalogic_i2c[3]); - fpgapci->irq_assigned++; - break; - case FPGA_MSI_VECTOR_ID_12: - err = request_irq(dev->irq + irq_num_id, fpgai2c_isr, IRQF_EARLY_RESUME, + fpgapci->irq_assigned++; + break; + case FPGA_MSI_VECTOR_ID_12: + err = request_irq(dev->irq + irq_num_id, fpgai2c_isr, IRQF_EARLY_RESUME, FPGA_PCI_NAME, &fpgalogic_i2c[4]); - fpgapci->irq_assigned++; - break; - case FPGA_MSI_VECTOR_ID_13: - err = request_irq(dev->irq + irq_num_id, fpgai2c_isr, IRQF_EARLY_RESUME, - FPGA_PCI_NAME, &fpgalogic_i2c[5]); - fpgapci->irq_assigned++; - break; - case FPGA_MSI_VECTOR_ID_14: - err = request_irq(dev->irq + irq_num_id, fpgai2c_isr, IRQF_EARLY_RESUME, - FPGA_PCI_NAME, &fpgalogic_i2c[6]); - fpgapci->irq_assigned++; - break; - - default: - PRINT("No more interrupt handler for number (%d)\n", + fpgapci->irq_assigned++; + break; + case FPGA_MSI_VECTOR_ID_13: + if (total_i2c_pci_bus > I2C_PCI_BUS_NUM_5) { + err = request_irq(dev->irq + irq_num_id, fpgai2c_isr, + IRQF_EARLY_RESUME, FPGA_PCI_NAME, &fpgalogic_i2c[5]); + fpgapci->irq_assigned++; + } + break; + case FPGA_MSI_VECTOR_ID_14: + if (total_i2c_pci_bus > I2C_PCI_BUS_NUM_5) { + err = request_irq(dev->irq + irq_num_id, fpgai2c_isr, + IRQF_EARLY_RESUME, FPGA_PCI_NAME, &fpgalogic_i2c[6]); + fpgapci->irq_assigned++; + } + break; + case FPGA_MSI_VECTOR_ID_15: + /*it is an external interrupt number. Ignore this case */ + break; + case FPGA_MSI_VECTOR_ID_16: + if (total_i2c_pci_bus > I2C_PCI_BUS_NUM_7) { + err = request_irq(dev->irq + irq_num_id, fpgai2c_isr, + IRQF_EARLY_RESUME, FPGA_PCI_NAME, &fpgalogic_i2c[7]); + fpgapci->irq_assigned++; + } + break; + case FPGA_MSI_VECTOR_ID_17: + if (total_i2c_pci_bus > I2C_PCI_BUS_NUM_8) { + err = request_irq(dev->irq + irq_num_id, fpgai2c_isr, + IRQF_EARLY_RESUME, FPGA_PCI_NAME, &fpgalogic_i2c[8]); + fpgapci->irq_assigned++; + } + break; + case FPGA_MSI_VECTOR_ID_18: + if (total_i2c_pci_bus > I2C_PCI_BUS_NUM_8) { + err = request_irq(dev->irq + irq_num_id, fpgai2c_isr, + IRQF_EARLY_RESUME, FPGA_PCI_NAME, &fpgalogic_i2c[9]); + fpgapci->irq_assigned++; + } + break; + case FPGA_MSI_VECTOR_ID_19: + if (total_i2c_pci_bus > I2C_PCI_BUS_NUM_10) { + err = request_irq(dev->irq + irq_num_id, fpgai2c_isr, + IRQF_EARLY_RESUME, FPGA_PCI_NAME, &fpgalogic_i2c[10]); + fpgapci->irq_assigned++; + } + break; + case FPGA_MSI_VECTOR_ID_20: + if (total_i2c_pci_bus > I2C_PCI_BUS_NUM_10) { + err = request_irq(dev->irq + irq_num_id, fpgai2c_isr, + IRQF_EARLY_RESUME, FPGA_PCI_NAME, &fpgalogic_i2c[11]); + fpgapci->irq_assigned++; + } + break; + case FPGA_MSI_VECTOR_ID_21: + if (total_i2c_pci_bus > I2C_PCI_BUS_NUM_12) { + err = request_irq(dev->irq + irq_num_id, fpgai2c_isr, + IRQF_EARLY_RESUME, FPGA_PCI_NAME, &fpgalogic_i2c[12]); + fpgapci->irq_assigned++; + } + break; + case FPGA_MSI_VECTOR_ID_22: + if (total_i2c_pci_bus > I2C_PCI_BUS_NUM_12) { + err = request_irq(dev->irq + irq_num_id, fpgai2c_isr, + IRQF_EARLY_RESUME, FPGA_PCI_NAME, &fpgalogic_i2c[13]); + fpgapci->irq_assigned++; + } + break; + case FPGA_MSI_VECTOR_ID_23: + if (total_i2c_pci_bus > I2C_PCI_BUS_NUM_12) { + err = request_irq(dev->irq + irq_num_id, fpgai2c_isr, + IRQF_EARLY_RESUME, FPGA_PCI_NAME, &fpgalogic_i2c[14]); + fpgapci->irq_assigned++; + } + break; + case FPGA_MSI_VECTOR_ID_24: + if (total_i2c_pci_bus > I2C_PCI_BUS_NUM_12) { + err = request_irq(dev->irq + irq_num_id, fpgai2c_isr, + IRQF_EARLY_RESUME, FPGA_PCI_NAME, &fpgalogic_i2c[15]); + fpgapci->irq_assigned++; + } + break; + + default: + PRINT("No more interrupt handler for number (%d)\n", dev->irq + irq_num_id); - break; - } - } else if (((board_rev_type & MB_BRD_REV_MASK) == MB_BRD_REV_01) || - ((board_rev_type & MB_BRD_REV_MASK) == MB_BRD_REV_02) || - ((board_rev_type & MB_BRD_REV_MASK) == MB_BRD_REV_03)) { - /* FPGA SPEC 4.3.1.34, First i2c channel mapped to vector 8 */ - switch (irq_num_id) { - case FPGA_MSI_VECTOR_ID_4: - err = request_irq(dev->irq + irq_num_id, fpgaport_1_32_isr, IRQF_EARLY_RESUME, - FPGA_PCI_NAME, dev); - PRINT ( "%d: fpgapci_dev: irq: %d, %d\n", __LINE__, dev->irq, irq_num_id); - fpgapci->irq_assigned++; - break; - case FPGA_MSI_VECTOR_ID_5: - err = request_irq(dev->irq + irq_num_id, fpgaport_33_64_isr, IRQF_EARLY_RESUME, - FPGA_PCI_NAME, dev); - PRINT ( "%d: fpgapci_dev: irq: %d, %d\n", __LINE__, dev->irq, irq_num_id); - fpgapci->irq_assigned++; - break; - case FPGA_MSI_VECTOR_ID_8: - err = request_irq(dev->irq + irq_num_id, fpgai2c_isr, IRQF_EARLY_RESUME, - FPGA_PCI_NAME, &fpgalogic_i2c[0]); - fpgapci->irq_assigned++; - break; - case FPGA_MSI_VECTOR_ID_9: - err = request_irq(dev->irq + irq_num_id, fpgai2c_isr, IRQF_EARLY_RESUME, - FPGA_PCI_NAME, &fpgalogic_i2c[1]); - fpgapci->irq_assigned++; - break; - case FPGA_MSI_VECTOR_ID_10: - err = request_irq(dev->irq + irq_num_id, fpgai2c_isr, IRQF_EARLY_RESUME, - FPGA_PCI_NAME, &fpgalogic_i2c[2]); - fpgapci->irq_assigned++; - break; - case FPGA_MSI_VECTOR_ID_11: - err = request_irq(dev->irq + irq_num_id, fpgai2c_isr, IRQF_EARLY_RESUME, - FPGA_PCI_NAME, &fpgalogic_i2c[3]); - fpgapci->irq_assigned++; - break; - case FPGA_MSI_VECTOR_ID_12: - err = request_irq(dev->irq + irq_num_id, fpgai2c_isr, IRQF_EARLY_RESUME, - FPGA_PCI_NAME, &fpgalogic_i2c[4]); - fpgapci->irq_assigned++; - break; - case FPGA_MSI_VECTOR_ID_13: - if (total_i2c_pci_bus > I2C_PCI_BUS_NUM_5) { - err = request_irq(dev->irq + irq_num_id, fpgai2c_isr, - IRQF_EARLY_RESUME, FPGA_PCI_NAME, &fpgalogic_i2c[5]); - fpgapci->irq_assigned++; - } - break; - case FPGA_MSI_VECTOR_ID_14: - if (total_i2c_pci_bus > I2C_PCI_BUS_NUM_5) { - err = request_irq(dev->irq + irq_num_id, fpgai2c_isr, - IRQF_EARLY_RESUME, FPGA_PCI_NAME, &fpgalogic_i2c[6]); - fpgapci->irq_assigned++; - } - break; - case FPGA_MSI_VECTOR_ID_15: - /*it is an external interrupt number. Ignore this case */ - break; - case FPGA_MSI_VECTOR_ID_16: - if (total_i2c_pci_bus > I2C_PCI_BUS_NUM_7) { - err = request_irq(dev->irq + irq_num_id, fpgai2c_isr, - IRQF_EARLY_RESUME, FPGA_PCI_NAME, &fpgalogic_i2c[7]); - fpgapci->irq_assigned++; - } - break; - case FPGA_MSI_VECTOR_ID_17: - if (total_i2c_pci_bus > I2C_PCI_BUS_NUM_8) { - err = request_irq(dev->irq + irq_num_id, fpgai2c_isr, - IRQF_EARLY_RESUME, FPGA_PCI_NAME, &fpgalogic_i2c[8]); - fpgapci->irq_assigned++; - } - break; - case FPGA_MSI_VECTOR_ID_18: - if (total_i2c_pci_bus > I2C_PCI_BUS_NUM_8) { - err = request_irq(dev->irq + irq_num_id, fpgai2c_isr, - IRQF_EARLY_RESUME, FPGA_PCI_NAME, &fpgalogic_i2c[9]); - fpgapci->irq_assigned++; - } - break; - case FPGA_MSI_VECTOR_ID_19: - if (total_i2c_pci_bus > I2C_PCI_BUS_NUM_10) { - err = request_irq(dev->irq + irq_num_id, fpgai2c_isr, - IRQF_EARLY_RESUME, FPGA_PCI_NAME, &fpgalogic_i2c[10]); - fpgapci->irq_assigned++; - } - break; - case FPGA_MSI_VECTOR_ID_20: - if (total_i2c_pci_bus > I2C_PCI_BUS_NUM_10) { - err = request_irq(dev->irq + irq_num_id, fpgai2c_isr, - IRQF_EARLY_RESUME, FPGA_PCI_NAME, &fpgalogic_i2c[11]); - fpgapci->irq_assigned++; - } - break; - case FPGA_MSI_VECTOR_ID_21: - if (total_i2c_pci_bus > I2C_PCI_BUS_NUM_12) { - err = request_irq(dev->irq + irq_num_id, fpgai2c_isr, - IRQF_EARLY_RESUME, FPGA_PCI_NAME, &fpgalogic_i2c[12]); - fpgapci->irq_assigned++; - } - break; - case FPGA_MSI_VECTOR_ID_22: - if (total_i2c_pci_bus > I2C_PCI_BUS_NUM_12) { - err = request_irq(dev->irq + irq_num_id, fpgai2c_isr, - IRQF_EARLY_RESUME, FPGA_PCI_NAME, &fpgalogic_i2c[13]); - fpgapci->irq_assigned++; - } - break; - case FPGA_MSI_VECTOR_ID_23: - if (total_i2c_pci_bus > I2C_PCI_BUS_NUM_12) { - err = request_irq(dev->irq + irq_num_id, fpgai2c_isr, - IRQF_EARLY_RESUME, FPGA_PCI_NAME, &fpgalogic_i2c[14]); - fpgapci->irq_assigned++; - } - break; - case FPGA_MSI_VECTOR_ID_24: - if (total_i2c_pci_bus > I2C_PCI_BUS_NUM_12) { - err = request_irq(dev->irq + irq_num_id, fpgai2c_isr, - IRQF_EARLY_RESUME, FPGA_PCI_NAME, &fpgalogic_i2c[15]); - fpgapci->irq_assigned++; - } - break; - - default: - PRINT("No more interrupt handler for number (%d)\n", - dev->irq + irq_num_id); - break; + break; } - } return err; } @@ -1415,7 +1275,7 @@ static int fpgapci_setup_device(struct fpgapci_dev *fpgapci,struct pci_dev *dev) goto fail_map_bars; } - i2c_pci_init(); + i2c_pci_init(fpgapci); return 0; /* ERROR HANDLING */ @@ -1491,7 +1351,6 @@ static int fpgapci_configure_msi(struct fpgapci_dev *fpgapci,struct pci_dev *dev static int fpgapci_probe(struct pci_dev *dev, const struct pci_device_id *id) { struct fpgapci_dev *fpgapci = 0; - int status = 0; #ifdef TEST PRINT ( " vendor = 0x%x, device = 0x%x, class = 0x%x, bus:slot.func = %02x:%02x.%02x\n", @@ -1508,11 +1367,6 @@ static int fpgapci_probe(struct pci_dev *dev, const struct pci_device_id *id) fpgapci->pci_dev = dev; dev_set_drvdata(&dev->dev, (void*)fpgapci); - status = sysfs_create_group(&dev->dev.kobj, &port_attr_grp); - if (status) { - printk(KERN_INFO "%s:Cannot create sysfs\n", __FUNCTION__); - } - fpgapci->upstream = find_upstream_dev (dev); if(fpgapci_setup_device(fpgapci,dev)) { @@ -1523,6 +1377,9 @@ static int fpgapci_probe(struct pci_dev *dev, const struct pci_device_id *id) if(fpgapci_configure_msi(fpgapci,dev)) { goto error_cannot_configure; } + /* Enable interrupt after config msi */ + fpgai2c_interrupt_enable(fpgapci); + } @@ -1581,6 +1438,7 @@ static void fpgapci_remove(struct pci_dev *dev) static const struct pci_device_id fpgapci_ids[] = { {PCI_DEVICE(PCI_VENDOR_ID_XILINX, DEVICE)}, + {PCI_DEVICE(PCI_VENDOR_ID_ALTERA, PCI_DEVICE_ID_ALTERA)}, {0, }, }; @@ -1624,3 +1482,4 @@ MODULE_LICENSE("GPL"); MODULE_AUTHOR("joyce_yu@dell.com"); MODULE_DESCRIPTION ("Driver for FPGA Logic I2C bus"); MODULE_SUPPORTED_DEVICE ("FPGA Logic I2C bus"); +MODULE_VERSION ("01.01"); diff --git a/platform/broadcom/sonic-platform-modules-dell/s5296f/setup.py b/platform/broadcom/sonic-platform-modules-dell/s5296f/setup.py new file mode 120000 index 000000000000..4f6de9941d96 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-dell/s5296f/setup.py @@ -0,0 +1 @@ +../s6100/setup.py \ No newline at end of file diff --git a/platform/broadcom/sonic-platform-modules-dell/s5296f/sonic_platform/__init__.py b/platform/broadcom/sonic-platform-modules-dell/s5296f/sonic_platform/__init__.py new file mode 100644 index 000000000000..28edc0b13f3b --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-dell/s5296f/sonic_platform/__init__.py @@ -0,0 +1,3 @@ +__all__ = ["platform", "chassis", "sfp", "eeprom", "component", "thermal", "psu", "fan","fan_drawer","watchdog"] +from sonic_platform import * + diff --git a/platform/broadcom/sonic-platform-modules-dell/s5296f/sonic_platform/chassis.py b/platform/broadcom/sonic-platform-modules-dell/s5296f/sonic_platform/chassis.py new file mode 100644 index 000000000000..c981e4bc7ade --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-dell/s5296f/sonic_platform/chassis.py @@ -0,0 +1,453 @@ +#!/usr/bin/env python + +############################################################################# +# DELLEMC S5296F +# +# Module contains an implementation of SONiC Platform Base API and +# provides the platform information +# +############################################################################# + +try: + import os + import time + import sys + from sonic_platform_base.chassis_base import ChassisBase + from sonic_platform.sfp import Sfp + from sonic_platform.eeprom import Eeprom + from sonic_platform.component import Component + from sonic_platform.psu import Psu + from sonic_platform.thermal import Thermal + from sonic_platform.watchdog import Watchdog + from sonic_platform.fan_drawer import FanDrawer + from sonic_platform.hwaccess import pci_get_value, pci_set_value +except ImportError as e: + raise ImportError(str(e) + "- required module not found") + +MAX_S5296F_COMPONENT = 8 # BIOS,BMC,FPGA,SYSTEM CPLD,4 SECONDARY CPLDs +MAX_S5296F_FANTRAY = 4 +MAX_S5296F_FAN = 1 +MAX_S5296F_PSU = 2 +MAX_S5296F_THERMAL = 10 +SYSTEM_LED_REG = 0x24 +SYSTEM_BEACON_LED_SET = 0x8 +SYSTEM_BEACON_LED_CLEAR = 0xFFFFFFF7 + +media_part_num_list = set([ \ +"8T47V","XTY28","MHVPK","GF76J","J6FGD","F1KMV","9DN5J","H4DHD","6MCNV","0WRX0","X7F70","5R2PT","WTRD1","WTRD1","WTRD1","WTRD1","5250G","WTRD1","C5RNH","C5RNH","FTLX8571D3BCL-FC", +"C5RNH","5250G","N8TDR","7D64H","7D64H","RN84N","RN84N","HMTNW","6K3Y6","6K3Y6","TY5FM","50M0R","PGYJT","WP2PP","85Y13","1HCGH","FP9R1","FYD0M","C6Y7M","C6Y7M","V250M","V250M", +"5CWK6","5CWK6","53HVN","53HVN","358VV","358VV","MV799","MV799","YJF03","P9GND","T1KCN","1DXKP","MT7R2","K0T7R","W5G04","7TCDN","7TCDN","7TCDN","7TCDN","7TCDN","V3XJK","0MV31", +"5FVP7","N6KM9","C41MF","77KC3","XW7J0","V4NJV","2XJHY","H93DH","H93DH","F8CG0","F8CG0","F8CG0","119N6","WFMF5","794RX","288F6","1M31V","1M31V","5NP8R","5NP8R","4TC09","4TC09", +"FC6KV","FC6KV","J90VN","J90VN","05RH0","05RH0","YDN52","0C2YV","YDN52","0C2YV","9JT65","D7M6H","6GW14","FYVFW","0VF5H","P4YPY","P4YPY","TCPM2","TCPM2","JNPF8","JNPF8","27GG5", +"27GG5","P8T4W","P8T4W","JR54Y","M6N0J","XJYD0","K44H9","035KG","P7C7N","76V43","3CC35","FN4FC","26FN3","YFNDD","YFNDD","7R9N9","035KG","P7C7N","76V43","3CC35","PLRXPLSCS43811", +"FN4FC","26FN3","YFNDD","YFNDD","7R9N9","G86YJ","V407F","V407F","9KH6T","G86YJ","V407F","9KH6T","2JVDD","D0R73","VXFJY","9X8JP","2JVDD","D0R73","VXFJY","9X8JP","2JVDD","D0R73","VXFJY", +"9X8JP","GMFC5","GMFC5","GMFC5","D7P80","3MFXG","3MFXG","0GWXJ","THPF3","THPF3","THPF3","THPF3","THPF3","PJ62G","3XCX1","JJYKG","RRRTK","16K56","86JM2","K5R6C","7MG2C","WTPPN","9HTT2", +"NKM4F","VXGGG","JC9W6","6MR8M","RP3GV","M5PPJ","XKY55","TKCXT","05J8P","5WGKD","XFDRT","NW8DM","YPKH3","5WGKD","XFDRT","NW8DM","YPKH3","71XXK","MVCX6","0XYP6","HPPVW","3GHRT","71XXK", +"MVCX6","0XYP6","HPPVW","3GHRT","2X5T6","135V2","KD5MV","2X5T6","KD5MV","HHFK0","3YWG7","5CMT2","RCVP5","X5DH4","HHFK0","3YWG7","5CMT2","RCVP5","X5DH4","3YWG7","5CMT2","RCVP5","X5DH4", +"4WJ41","4WJ41","14NV5","14NV5","14NV5","4WGYD","YKMH7","X7CCC","X7CCC","0X9CT","0CY8V","P7D7R","W4GPP","W4GPP","W4GPP","HHHCHC","07RN7","07RN7","0YR96","0YR96","JCYM9","FTLX8571D3BCL", +"DDW0X","VPFDJ","229KM","9FC7D","DDW0X","VPFDJ","6FMR5","J7K20","N3K9W","6FMR5","8R4VM","7VN5T","D9YM8","8R4VM","VYXPW","87TPX","WY6FK","VYXPW","87TPX","WY6FK","WG8C4","N8K82","2DV6Y", +"77C3C","RC0HM","77C3C","RC0HM","JHXTN","3P3PG","92YVM","4VX5M","4VX5M","6RRGD","W4JWV","22V6R","XR11M","9GMDY","JMCWK","TP2F0","6MGDY","78RHK", "C0TP5","0WDNV","FCLF8522P2BTL"\ +]) + +class Chassis(ChassisBase): + """ + DELLEMC Platform-specific Chassis class + """ + + REBOOT_CAUSE_PATH = "/host/reboot-cause/platform/reboot_reason" + OIR_FD_PATH = "/sys/bus/pci/devices/0000:04:00.0/port_msi" + PCI_RES = "/sys/bus/pci/devices/0000:04:00.0/resource0" + oir_fd = -1 + + sysled_offset = 0x0024 + SYSLED_COLOR_TO_REG = { + "blinking_green": 0x0, + "green" : 0x10, + "amber" : 0x20, + "blinking_amber": 0x30 + } + + REG_TO_SYSLED_COLOR = { + 0x0 : "blinking_green", + 0x10 : "green", + 0x20 : "amber", + 0x30 : "blinking_amber" + } + + _global_port_pres_dict = {} + + def __init__(self): + ChassisBase.__init__(self) + # sfp.py will read eeprom contents and retrive the eeprom data. + # We pass the eeprom path from chassis.py + self.PORT_START = 1 + self.PORT_END = 104 + self.SFP28_PORT_END = 96 + i2c_bus_for_port = 2 + i2c_mux_to_populate = 603 + i2c_mux_is_good = False + + PORTS_IN_BLOCK = (self.PORT_END + 1) + _sfp_port = range(1, self.SFP28_PORT_END + 1) + eeprom_base = "/sys/class/i2c-adapter/i2c-{0}/{0}-0050/eeprom" + mux_channel = "/sys/class/i2c-adapter/i2c-{0}/{0}-0074/channel-0" + + for index in range(self.PORT_START, PORTS_IN_BLOCK): + eeprom_path = "" + if index%8 == 1: # 8 buses per i2c mux + i2c_mux_is_good = True if os.path.exists(mux_channel.format(i2c_mux_to_populate)) else False + i2c_mux_to_populate += 1 + if i2c_mux_is_good: + eeprom_path = eeprom_base.format(i2c_bus_for_port) + i2c_bus_for_port += 1 + if index not in _sfp_port: + sfp_node = Sfp(index, 'QSFP', eeprom_path) + else: + sfp_node = Sfp(index, 'SFP', eeprom_path) + self._sfp_list.append(sfp_node) + self._num_sfps = len(self._sfp_list) + + self._eeprom = Eeprom() + + for i in range(MAX_S5296F_THERMAL): + self._thermal_list.append(Thermal(i)) + + for i in range(MAX_S5296F_COMPONENT): + self._component_list.append(Component(i)) + + for i in range(MAX_S5296F_PSU): + self._psu_list.append(Psu(i)) + + for i in range(MAX_S5296F_FANTRAY): + fandrawer = FanDrawer(i) + self._fan_drawer_list.append(fandrawer) + self._fan_list.extend(fandrawer._fan_list) + + self._num_fans = MAX_S5296F_FANTRAY * MAX_S5296F_FAN + + self._watchdog = Watchdog() + + def __del__(self): + if self.oir_fd != -1: + self.epoll.unregister(self.oir_fd.fileno()) + self.epoll.close() + self.oir_fd.close() + +# not needed /delete after validation + + def _get_register(self, reg_file): + retval = 'ERR' + if (not os.path.isfile(reg_file)): + print(reg_file, 'not found !') + return retval + + try: + with os.fdopen(os.open(reg_file, os.O_RDONLY)) as fd: + retval = fd.read() + except Exception as ex: + pass + retval = retval.rstrip('\r\n') + retval = retval.lstrip(" ") + return retval + +# not needed /delete after validation + + def _check_interrupts(self, port_dict): + retval = 0 + is_port_dict_updated = False + for port_num in range(self.PORT_START, (self.PORT_END + 1)): + sfp = self.get_sfp(port_num) + presence = sfp.get_presence() + if(presence and (self._global_port_pres_dict[port_num] == '0')): + is_port_dict_updated = True + self._global_port_pres_dict[port_num] = '1' + port_dict[port_num] = '1' + elif(not presence and (self._global_port_pres_dict[port_num] == '1')): + is_port_dict_updated = True + self._global_port_pres_dict[port_num] = '0' + port_dict[port_num] = '0' + return retval, is_port_dict_updated + +# check for this event change for sfp / do we need to handle timeout/sleep + + def get_change_event(self, timeout=0): + """ + Returns a nested dictionary containing all devices which have + experienced a change at chassis level + """ + start_ms = time.time() * 1000 + port_dict = {} + change_dict = {} + change_dict['sfp'] = port_dict + if not self._global_port_pres_dict: + for port_num in self._sfp_port: + presence = self.get_sfp(port_num).get_presence() + self._global_port_pres_dict[port_num] = '1' if presence else '0' + + while True: + time.sleep(0.5) + for port_num in range(self.PORT_START, (self.PORT_END + 1)): + presence = self.get_sfp(port_num).get_presence() + if(presence and self._global_port_pres_dict[port_num] == '0'): + self._global_port_pres_dict[port_num] = '1' + port_dict[port_num] = '1' + elif(not presence and + self._global_port_pres_dict[port_num] == '1'): + self._global_port_pres_dict[port_num] = '0' + port_dict[port_num] = '0' + + if(len(port_dict) > 0): + return True, change_dict + + if timeout: + now_ms = time.time() * 1000 + if (now_ms - start_ms >= timeout): + return True, change_dict + + + def get_sfp(self, index): + """ + Retrieves sfp represented by (0-based) index + + Args: + index: An integer, the index (0-based) of the sfp to retrieve. + The index should be the sequence of a physical port in a chassis, + starting from 0. + For example, 0 for Ethernet0, 1 for Ethernet4 and so on. + + Returns: + An object dervied from SfpBase representing the specified sfp + """ + sfp = None + + try: + # The 'index' is 1-based + sfp = self._sfp_list[index-1] + except IndexError: + sys.stderr.write("SFP index {} out of range (1-{})\n".format( + index, len(self._sfp_list))) + return sfp + + def get_name(self): + """ + Retrieves the name of the chassis + Returns: + string: The name of the chassis + """ + return self._eeprom.modelstr() + + def get_presence(self): + """ + Retrieves the presence of the chassis + Returns: + bool: True if chassis is present, False if not + """ + return True + + def get_model(self): + """ + Retrieves the model number (or part number) of the chassis + Returns: + string: Model/part number of chassis + """ + return self._eeprom.part_number_str() + + def get_serial(self): + """ + Retrieves the serial number of the chassis (Service tag) + Returns: + string: Serial number of chassis + """ + return self._eeprom.serial_str() + + def get_status(self): + """ + Retrieves the operational status of the chassis + Returns: + bool: A boolean value, True if chassis is operating properly + False if not + """ + return True + + def set_status_led(self, color): + """ + Sets the state of the system LED + Args: + color: A string representing the color with which to set the + system LED + Returns: + bool: True if system LED state is set successfully, False if not + """ + if color not in list(self.SYSLED_COLOR_TO_REG.keys()): + return False + + val = pci_get_value(self.PCI_RES, self.sysled_offset) + val = (val & 0xFFCF) | self.SYSLED_COLOR_TO_REG[color] + + pci_set_value(self.PCI_RES, val, self.sysled_offset) + self.sys_ledcolor = color + return True + + def get_status_led(self): + """ + Gets the state of the system LED + Returns: + A string, one of the valid LED color strings which could be + vendor specified. + """ + val = pci_get_value(self.PCI_RES, self.sysled_offset) + if val != -1: + val = val & 0x30 + return self.REG_TO_SYSLED_COLOR.get(val) + return self.sys_ledcolor + + def get_base_mac(self): + """ + Retrieves the base MAC address for the chassis + Returns: + A string containing the MAC address in the format + 'XX:XX:XX:XX:XX:XX' + """ + return self._eeprom.base_mac_addr() + + def get_serial_number(self): + """ + Retrieves the hardware serial number for the chassis + Returns: + A string containing the hardware serial number for this chassis. + """ + return self._eeprom.serial_number_str() + + def get_system_eeprom_info(self): + """ + Retrieves the full content of system EEPROM information for the chassis + Returns: + A dictionary where keys are the type code defined in + OCP ONIE TlvInfo EEPROM format and values are their corresponding + values. + """ + return self._eeprom.system_eeprom_info() + + def get_eeprom(self): + """ + Retrieves the Sys Eeprom instance for the chassis. + Returns : + The instance of the Sys Eeprom + """ + return self._eeprom + + def get_num_fans(self): + """ + Retrives the number of Fans on the chassis. + Returns : + An integer represents the number of Fans on the chassis. + """ + return self._num_fans + + def get_num_sfps(self): + """ + Retrives the numnber of Media on the chassis. + Returns: + An integer represences the number of SFPs on the chassis. + """ + return self._num_sfps + + def get_revision(self): + """ + Retrieves the revision number of the chassis (Service tag) + Returns: + string: Revision number of chassis + """ + return self._eeprom.revision_str() + + def get_reboot_cause(self): + """ + Retrieves the cause of the previous reboot + Returns: + A tuple (string, string) where the first element is a string + containing the cause of the previous reboot. This string must be + one of the predefined strings in this class. If the first string + is "REBOOT_CAUSE_HARDWARE_OTHER", the second string can be used + to pass a description of the reboot cause. + """ + try: + with open(self.REBOOT_CAUSE_PATH) as fd: + reboot_cause = int(fd.read(), 16) + except Exception as ex: + return (self.REBOOT_CAUSE_NON_HARDWARE, None) + + if reboot_cause & 0x1: + return (self.REBOOT_CAUSE_POWER_LOSS, "Power on reset") + elif reboot_cause & 0x2: + return (self.REBOOT_CAUSE_NON_HARDWARE, None) + elif reboot_cause & 0x4: + return (self.REBOOT_CAUSE_HARDWARE_OTHER, "PSU Shutdown") + elif reboot_cause & 0x8: + return (self.REBOOT_CAUSE_THERMAL_OVERLOAD_CPU, None) + elif reboot_cause & 0x10: + return (self.REBOOT_CAUSE_WATCHDOG, None) + elif reboot_cause & 0x20: + return (self.REBOOT_CAUSE_HARDWARE_OTHER, "BMC Shutdown") + elif reboot_cause & 0x40: + return (self.REBOOT_CAUSE_HARDWARE_OTHER, "Hot-Swap Shutdown") + elif reboot_cause & 0x80: + return (self.REBOOT_CAUSE_HARDWARE_OTHER, "Reset Button Shutdown") + elif reboot_cause & 0x100: + return (self.REBOOT_CAUSE_HARDWARE_OTHER, "Reset Button Cold Reboot") + else: + return (self.REBOOT_CAUSE_NON_HARDWARE, None) + + def get_qualified_media_list(self): + return media_part_num_list + + def set_locator_led(self, color): + """ + Sets the state of the Chassis Locator LED + + Args: + color: A string representing the color with which to set the Chassis Locator LED + + Returns: + bool: True if the Chassis Locator LED state is set successfully, False if not + + """ + val = pci_get_value(self.PCI_RES, SYSTEM_LED_REG) + if self.LOCATOR_LED_ON == color: + val = int(val) | SYSTEM_BEACON_LED_SET + elif self.LOCATOR_LED_OFF == color: + val = int(val) & SYSTEM_BEACON_LED_CLEAR + else: + return False + pci_set_value(self.PCI_RES, val, SYSTEM_LED_REG) + return True + + def get_locator_led(self): + """ + Gets the state of the Chassis Locator LED + + Returns: + LOCATOR_LED_ON or LOCATOR_LED_OFF + """ + val = pci_get_value(self.PCI_RES, SYSTEM_LED_REG) + val = int(val) & SYSTEM_BEACON_LED_SET + if not val: + return self.LOCATOR_LED_OFF + else: + return self.LOCATOR_LED_ON + + def get_position_in_parent(self): + """ + Retrieves 1-based relative physical position in parent device. + Returns: + integer: The 1-based relative physical position in parent + device or -1 if cannot determine the position + """ + return -1 + + def is_replaceable(self): + """ + Indicate whether Chassis is replaceable. + Returns: + bool: True if it is replaceable. + """ + return False diff --git a/platform/broadcom/sonic-platform-modules-dell/s5296f/sonic_platform/component.py b/platform/broadcom/sonic-platform-modules-dell/s5296f/sonic_platform/component.py new file mode 100644 index 000000000000..43c43e0a4ef6 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-dell/s5296f/sonic_platform/component.py @@ -0,0 +1,233 @@ +#!/usr/bin/env python + +######################################################################## +# DELLEMC S5296F +# +# Module contains an implementation of SONiC Platform Base API and +# provides the Components' (e.g., BIOS, CPLD, FPGA, BMC etc.) available in +# the platform +# +######################################################################## + + +try: + import subprocess + from sonic_platform_base.component_base import ComponentBase + import sonic_platform.hwaccess as hwaccess + +except ImportError as e: + raise ImportError(str(e) + "- required module not found") + + +def get_bios_version(): + return subprocess.check_output(['dmidecode', '-s', + 'system-version']).decode('utf-8').strip() + +def get_fpga_version(): + val = hwaccess.pci_get_value('/sys/bus/pci/devices/0000:04:00.0/resource0', 0) + return '{}.{}'.format((val >> 8) & 0xff, val & 0xff) + +def get_bmc_version(): + """ Returns BMC Version """ + bmc_ver = '' + try: + bmc_ver = subprocess.check_output( + "ipmitool mc info | awk '/Firmware Revision/ { print $NF }'", + shell=True, text=True).strip() + except (FileNotFoundError, subprocess.CalledProcessError): + pass + return bmc_ver + +def get_cpld_version(bus, i2caddr): + """ Return CPLD version """ + major = hwaccess.i2c_get(bus, i2caddr, 1) + minor = hwaccess.i2c_get(bus, i2caddr, 0) + if major != -1 and minor != -1: + return '{}.{}'.format(major, minor) + return '' + +def get_cpld0_version(): + return get_cpld_version(601, 0x31) + +def get_cpld1_version(): + return get_cpld_version(600, 0x30) + +def get_cpld2_version(): + return get_cpld_version(600, 0x31) + +def get_cpld3_version(): + return get_cpld_version(600, 0x32) + +def get_cpld4_version(): + return get_cpld_version(600, 0x33) + + +class Component(ComponentBase): + """DellEMC Platform-specific Component class""" + + CHASSIS_COMPONENTS = [ + ['BIOS', + 'Performs initialization of hardware components during booting', + get_bios_version + ], + + ['FPGA', + 'Used for managing the system LEDs', + get_fpga_version + ], + + ['BMC', + 'Platform management controller for on-board temperature monitoring, in-chassis power, Fan and LED control', + get_bmc_version + ], + + ['System CPLD', + 'Used for managing the CPU power sequence and CPU states', + get_cpld0_version + ], + + ['Secondary CPLD 1', + 'Used for managing SFP28/QSFP28 port transceivers (SFP28 1-24, QSFP28 1-4)', + get_cpld1_version + ], + + ['Secondary CPLD 2', + 'Used for managing SFP28/QSFP28 port transceivers (SFP28 25-48, QSFP28 5-8)', + get_cpld2_version + ], + + ['Secondary CPLD 3', + 'Used for managing SFP28/QSFP28 port transceivers (SFP28 49-72)', + get_cpld3_version + ], + + ['Secondary CPLD 4', + 'Used for managing SFP28/QSFP28 port transceivers (SFP28 73-96)', + get_cpld4_version + ] + ] + + def __init__(self, component_index = 0): + self.index = component_index + self.name = self.CHASSIS_COMPONENTS[self.index][0] + self.description = self.CHASSIS_COMPONENTS[self.index][1] + self.version = self.CHASSIS_COMPONENTS[self.index][2]() + + def get_name(self): + """ + Retrieves the name of the component + Returns: + A string containing the name of the component + """ + return self.name + + def get_description(self): + """ + Retrieves the description of the component + Returns: + A string containing the description of the component + """ + return self.description + + def get_firmware_version(self): + """ + Retrieves the firmware version of the component + Returns: + A string containing the firmware version of the component + """ + return self.version + + def get_presence(self): + """ + Retrieves the presence of the component + Returns: + bool: True if present, False if not + """ + return True + + def get_model(self): + """ + Retrieves the part number of the component + Returns: + string: Part number of component + """ + return 'NA' + + def get_serial(self): + """ + Retrieves the serial number of the component + Returns: + string: Serial number of component + """ + return 'NA' + + def get_status(self): + """ + Retrieves the operational status of the component + Returns: + bool: True if component is operating properly, False if not + """ + return True + + def get_position_in_parent(self): + """ + Retrieves 1-based relative physical position in parent device. + Returns: + integer: The 1-based relative physical position in parent + device or -1 if cannot determine the position + """ + return -1 + + def is_replaceable(self): + """ + Indicate whether component is replaceable. + Returns: + bool: True if it is replaceable. + """ + return False + + def install_firmware(self, image_path): + """ + Installs firmware to the component + Args: + image_path: A string, path to firmware image + Returns: + A boolean, True if install was successful, False if not + """ + return False + + def get_available_firmware_version(self, image_path): + """ + Retrieves the available firmware version of the component + Note: the firmware version will be read from image + Args: + image_path: A string, path to firmware image + Returns: + A string containing the available firmware version of the component + """ + return "N/A" + + def get_firmware_update_notification(self, image_path): + """ + Retrieves a notification on what should be done in order to complete + the component firmware update + Args: + image_path: A string, path to firmware image + Returns: + A string containing the component firmware update notification if required. + By default 'None' value will be used, which indicates that no actions are required + """ + return "None" + + def update_firmware(self, image_path): + """ + Updates firmware of the component + This API performs firmware update: it assumes firmware installation and loading in a single call. + In case platform component requires some extra steps (apart from calling Low Level Utility) + to load the installed firmware (e.g, reboot, power cycle, etc.) - this will be done automatically by API + Args: + image_path: A string, path to firmware image + Raises: + RuntimeError: update failed + """ + return False diff --git a/platform/broadcom/sonic-platform-modules-dell/s5296f/sonic_platform/eeprom.py b/platform/broadcom/sonic-platform-modules-dell/s5296f/sonic_platform/eeprom.py new file mode 100644 index 000000000000..dbe660f9de10 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-dell/s5296f/sonic_platform/eeprom.py @@ -0,0 +1,133 @@ +#!/usr/bin/env python + +############################################################################# +# DellEmc S5296F +# +# Platform and model specific eeprom subclass, inherits from the base class, +# and provides the followings: +# - the eeprom format definition +# - specific encoder/decoder if there is special need +############################################################################# + +try: + import os.path + from sonic_eeprom import eeprom_tlvinfo +except ImportError as e: + raise ImportError(str(e) + "- required module not found") + + +class Eeprom(eeprom_tlvinfo.TlvInfoDecoder): + + def __init__(self): + self.eeprom_path = None + for b in (0, 1): + f = '/sys/class/i2c-adapter/i2c-{0}/{0}-0050/eeprom'.format(b) + if os.path.exists(f): + self.eeprom_path = f + break + if self.eeprom_path is None: + return + super(Eeprom, self).__init__(self.eeprom_path, 0, '', True) + self.eeprom_tlv_dict = dict() + try: + self.eeprom_data = self.read_eeprom() + except: + self.eeprom_data = "N/A" + raise RuntimeError("Eeprom is not Programmed") + else: + eeprom = self.eeprom_data + + if not self.is_valid_tlvinfo_header(eeprom): + return + + total_length = (eeprom[9] << 8) | eeprom[10] + tlv_index = self._TLV_INFO_HDR_LEN + tlv_end = self._TLV_INFO_HDR_LEN + total_length + + while (tlv_index + 2) < len(eeprom) and tlv_index < tlv_end: + if not self.is_valid_tlv(eeprom[tlv_index:]): + break + + tlv = eeprom[tlv_index:tlv_index + 2 + + eeprom[tlv_index + 1]] + code = "0x%02X" % tlv[0] + name, value = self.decoder(None, tlv) + + self.eeprom_tlv_dict[code] = value + if eeprom[tlv_index] == self._TLV_CODE_CRC_32: + break + + tlv_index += eeprom[tlv_index+1] + 2 + + def serial_number_str(self): + """ + Returns the serial number + """ + (is_valid, results) = self.get_tlv_field( + self.eeprom_data, self._TLV_CODE_SERIAL_NUMBER) + if not is_valid: + return "N/A" + return results[2].decode('ascii') + + def base_mac_addr(self): + """ + Returns the base mac address found in the system EEPROM + """ + (is_valid, t) = self.get_tlv_field( + self.eeprom_data, self._TLV_CODE_MAC_BASE) + if not is_valid or t[1] != 6: + return super(TlvInfoDecoder, self).switchaddrstr(e) + + return ":".join(["{:02x}".format(T) for T in t[2]]).upper() + + def modelstr(self): + """ + Returns the Model name + """ + (is_valid, results) = self.get_tlv_field( + self.eeprom_data, self._TLV_CODE_PRODUCT_NAME) + if not is_valid: + return "N/A" + + return results[2].decode('ascii') + + def part_number_str(self): + """ + Returns the part number + """ + (is_valid, results) = self.get_tlv_field( + self.eeprom_data, self._TLV_CODE_PART_NUMBER) + if not is_valid: + return "N/A" + + return results[2].decode('ascii') + + def serial_str(self): + """ + Returns the servicetag number + """ + (is_valid, results) = self.get_tlv_field( + self.eeprom_data, self._TLV_CODE_SERVICE_TAG) + if not is_valid: + return "N/A" + + return results[2].decode('ascii') + + def revision_str(self): + """ + Returns the device revision + """ + (is_valid, results) = self.get_tlv_field( + self.eeprom_data, self._TLV_CODE_LABEL_REVISION) + if not is_valid: + return "N/A" + + return results[2].decode('ascii') + + def system_eeprom_info(self): + """ + Returns a dictionary, where keys are the type code defined in + ONIE EEPROM format and values are their corresponding values + found in the system EEPROM. + """ + return self.eeprom_tlv_dict diff --git a/platform/broadcom/sonic-platform-modules-dell/s5296f/sonic_platform/fan.py b/platform/broadcom/sonic-platform-modules-dell/s5296f/sonic_platform/fan.py new file mode 100644 index 000000000000..bf172a2ac2fb --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-dell/s5296f/sonic_platform/fan.py @@ -0,0 +1,214 @@ +#!/usr/bin/env python + +######################################################################## +# DellEMC S5296F +# +# Module contains an implementation of SONiC Platform Base API and +# provides the Fans' information which are available in the platform. +# +######################################################################## + +try: + from sonic_platform_base.fan_base import FanBase + from sonic_platform.ipmihelper import IpmiSensor, IpmiFru +except ImportError as e: + raise ImportError(str(e) + "- required module not found") + +FAN1_MAX_SPEED_OFFSET = 71 +PSU_FAN_MAX_SPEED_OFFSET = 50 +FAN_DIRECTION_OFFSET = 69 +PSU_FAN_DIRECTION_OFFSET = 47 + + +class Fan(FanBase): + """DellEMC Platform-specific Fan class""" + # { FAN-ID: { Sensor-Name: Sensor-ID } } + FAN_SENSOR_MAPPING = { 1: {"Prsnt": 0x53, "State": 0x5b, "Speed": 0x20}, + 2: {"Prsnt": 0x54, "State": 0x5c, "Speed": 0x21}, + 3: {"Prsnt": 0x55, "State": 0x5d, "Speed": 0x22}, + 4: {"Prsnt": 0x56, "State": 0x5e, "Speed": 0x23} + } + PSU_FAN_SENSOR_MAPPING = { 1: {"State": 0x31, "Speed": 0x28}, + 2: {"State": 0x32, "Speed": 0x29} } + + # { FANTRAY-ID: FRU-ID } + FAN_FRU_MAPPING = { 1: 3, 2: 4, 3: 5, 4: 6 } + PSU_FRU_MAPPING = { 1: 1, 2: 2 } + + def __init__(self, fantray_index=1, fan_index=1, psu_fan=False, + dependency=None): + self.is_psu_fan = psu_fan + if not self.is_psu_fan: + # API index is starting from 0, DellEMC platform index is + # starting from 1 + self.fantrayindex = fantray_index + 1 + self.fanindex = fan_index + 1 + self.max_speed_offset = FAN1_MAX_SPEED_OFFSET + self.fan_direction_offset = FAN_DIRECTION_OFFSET + self.index = self.fantrayindex + self.prsnt_sensor = IpmiSensor(self.FAN_SENSOR_MAPPING[self.index]["Prsnt"], + is_discrete = True) + self.state_sensor = IpmiSensor(self.FAN_SENSOR_MAPPING[self.index]["State"], + is_discrete = True) + self.speed_sensor = IpmiSensor(self.FAN_SENSOR_MAPPING[self.index]["Speed"]) + self.fru = IpmiFru(self.FAN_FRU_MAPPING[self.fantrayindex]) + else: + self.dependency = dependency + self.fanindex = fan_index + self.state_sensor = IpmiSensor(self.PSU_FAN_SENSOR_MAPPING[self.fanindex]["State"], + is_discrete = True) + self.speed_sensor = IpmiSensor(self.PSU_FAN_SENSOR_MAPPING[self.fanindex]["Speed"]) + self.fru = IpmiFru(self.PSU_FRU_MAPPING[self.fanindex]) + self.max_speed_offset = PSU_FAN_MAX_SPEED_OFFSET + self.fan_direction_offset = PSU_FAN_DIRECTION_OFFSET + self.max_speed = 0 + + def get_name(self): + """ + Retrieves the name of the device + Returns: + String: The name of the device + """ + if self.is_psu_fan: + return "PSU{} Fan".format(self.fanindex) + else: + return "FanTray{}-Fan{}".format(self.fantrayindex, self.fanindex) + + def get_model(self): + """ + Retrieves the part number of the FAN + Returns: + String: Part number of FAN + """ + return self.fru.get_board_part_number() + + def get_serial(self): + """ + Retrieves the serial number of the FAN + Returns: + String: Serial number of FAN + """ + return self.fru.get_board_serial() + + def get_presence(self): + """ + Retrieves the presence of the FAN + Returns: + bool: True if fan is present, False if not + """ + presence = False + if self.is_psu_fan: + return self.dependency.get_presence() + else: + is_valid, state = self.prsnt_sensor.get_reading() + if is_valid: + if (state & 0b1): + presence = True + return presence + + def get_status(self): + """ + Retrieves the operational status of the FAN + Returns: + bool: True if FAN is operating properly, False if not + """ + status = False + is_valid, state = self.state_sensor.get_reading() + if is_valid: + if not state > 1: + status = True + return status + + def get_direction(self): + """ + Retrieves the fan airfow direction + Returns: + A string, either FAN_DIRECTION_INTAKE or FAN_DIRECTION_EXHAUST + depending on fan direction + + Notes: + In DellEMC platforms, + - Forward/Exhaust : Air flows from Port side to Fan side. + - Reverse/Intake : Air flows from Fan side to Port side. + """ + direction = [self.FAN_DIRECTION_EXHAUST, self.FAN_DIRECTION_INTAKE] + fan_status = self.get_presence() + if not fan_status: + return None + is_valid, fan_direction = self.fru.get_fru_data(self.fan_direction_offset) + if is_valid and fan_direction[0] < len(direction): + return direction[fan_direction[0]] + else: + return None + + def get_speed_rpm(self): + """ + Retrieves the speed of fan in revolutions per minute (RPM) + + Returns: + An integer, speed of the fan in RPM + """ + is_valid, fan_speed = self.speed_sensor.get_reading() + return fan_speed if is_valid else None + + def get_speed(self): + """ + Retrieves the speed of the fan + Returns: + int: percentage of the max fan speed + """ + rpm = self.get_speed_rpm() + if rpm is None: + return None + if self.max_speed == 0: + is_valid, resp = self.fru.get_fru_data(self.max_speed_offset, 2) + if is_valid: + self.max_speed = (resp[1] << 8) | resp[0] + if self.max_speed == 0: + return None + return (100 * rpm) // self.max_speed + + def get_position_in_parent(self): + """ + Retrieves 1-based relative physical position in parent device. + Returns: + integer: The 1-based relative physical position in parent + device or -1 if cannot determine the position + """ + return self.fanindex + + def is_replaceable(self): + """ + Indicate whether Fan is replaceable. + Returns: + bool: True if it is replaceable. + """ + return False + + def get_speed_tolerance(self): + """ + Retrieves the speed tolerance of the fan + Returns: + An integer, the percentage of variance from target speed which is + considered tolerable + """ + if self.get_presence(): + # The tolerance value is fixed as 20% for all the DellEMC platforms + tolerance = 20 + else: + tolerance = 0 + + return tolerance + + def set_status_led(self, color): + """ + Set led to expected color + Args: + color: A string representing the color with which to set the + fan status LED + Returns: + bool: True if set success, False if fail. + """ + # Fan tray status LED controlled by HW + # Return True to avoid thermalctld alarm + return True diff --git a/platform/broadcom/sonic-platform-modules-dell/s5296f/sonic_platform/fan_drawer.py b/platform/broadcom/sonic-platform-modules-dell/s5296f/sonic_platform/fan_drawer.py new file mode 100644 index 000000000000..8cd0f3ba327d --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-dell/s5296f/sonic_platform/fan_drawer.py @@ -0,0 +1,110 @@ +#!/usr/bin/env python + +######################################################################## +# DellEMC S5296F +# +# Module contains an implementation of SONiC Platform Base API and +# provides the Fan-Drawers' information available in the platform. +# +######################################################################## + +try: + from sonic_platform_base.fan_drawer_base import FanDrawerBase + from sonic_platform.fan import Fan +except ImportError as e: + raise ImportError(str(e) + "- required module not found") + +S5296F_FANS_PER_FANTRAY = 1 + + +class FanDrawer(FanDrawerBase): + """DellEMC Platform-specific Fan class""" + + def __init__(self, fantray_index): + + FanDrawerBase.__init__(self) + # FanTray is 1-based in DellEMC platforms + self.fantrayindex = fantray_index + 1 + for i in range(S5296F_FANS_PER_FANTRAY): + self._fan_list.append(Fan(fantray_index, i)) + + def get_name(self): + """ + Retrieves the fan drawer name + Returns: + string: The name of the device + """ + return "FanTray{}".format(self.fantrayindex) + + + def get_presence(self): + """ + Retrives the presence of the fan drawer + Returns: + bool: True if fan_tray is present, False if not + """ + return self.get_fan(0).get_presence() + + def get_model(self): + """ + Retrieves the part number of the fan drawer + Returns: + string: Part number of fan drawer + """ + return "NA" + + def get_serial(self): + """ + Retrieves the serial number of the fan drawer + Returns: + string: Serial number of the fan drawer + """ + return "NA" + + def get_status(self): + """ + Retrieves the operational status of the fan drawer + Returns: + bool: True if fan drawer is operating properly, False if not + """ + return self.get_fan(0).get_status() + + def get_position_in_parent(self): + """ + Retrieves 1-based relative physical position in parent device. + Returns: + integer: The 1-based relative physical position in parent + device or -1 if cannot determine the position + """ + return self.fantrayindex + + def is_replaceable(self): + """ + Indicate whether this fan drawer is replaceable. + Returns: + bool: True if it is replaceable, False if not + """ + return True + + def set_status_led(self, color): + """ + Set led to expected color + Args: + color: A string representing the color with which to set the + fan module status LED + Returns: + bool: True if set success, False if fail. + """ + # Fan tray status LED controlled by BMC + # Return True to avoid thermalctld alarm + return True + + def get_maximum_consumed_power(self): + """ + Retrives the maximum power drawn by Fan Drawer + Returns: + A float, with value of the maximum consumable power of the + component. + """ + # Value based on the hw spec + return 54.0 diff --git a/platform/broadcom/sonic-platform-modules-dell/s5296f/sonic_platform/hwaccess.py b/platform/broadcom/sonic-platform-modules-dell/s5296f/sonic_platform/hwaccess.py new file mode 120000 index 000000000000..e8fa340a444d --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-dell/s5296f/sonic_platform/hwaccess.py @@ -0,0 +1 @@ +../../common/sonic_platform/hwaccess.py \ No newline at end of file diff --git a/platform/broadcom/sonic-platform-modules-dell/s5296f/sonic_platform/media_settings_plugin.py b/platform/broadcom/sonic-platform-modules-dell/s5296f/sonic_platform/media_settings_plugin.py new file mode 100644 index 000000000000..3b7667846eda --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-dell/s5296f/sonic_platform/media_settings_plugin.py @@ -0,0 +1,13 @@ +# Media settings key plugin +# +# Generate keys used for lookup in media_settings,json + +def get_media_settings_key(physical_port, transceiver_dict): + d = transceiver_dict[physical_port] + media_interface = d['media_interface'] + generic_key = '{}-{}'.format(d['form_factor'], media_interface) + if media_interface == 'CR': + generic_key = '{}-{}'.format(generic_key, d['cable_length_detailed']) + return ['{}-{}'.format(d['manufacturename'], d['modelname']), + generic_key + ] diff --git a/platform/broadcom/sonic-platform-modules-dell/s5296f/sonic_platform/platform.py b/platform/broadcom/sonic-platform-modules-dell/s5296f/sonic_platform/platform.py new file mode 100644 index 000000000000..996d94cf5a6e --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-dell/s5296f/sonic_platform/platform.py @@ -0,0 +1,24 @@ +#!/usr/bin/env python + +############################################################################# +# +# Module contains an implementation of SONiC Platform Base API and +# provides the platform information +# +############################################################################# + +try: + from sonic_platform_base.platform_base import PlatformBase + from sonic_platform.chassis import Chassis +except ImportError as e: + raise ImportError(str(e) + "- required module not found") + + +class Platform(PlatformBase): + """ + DELLEMC Platform-specific class + """ + + def __init__(self): + PlatformBase.__init__(self) + self._chassis = Chassis() diff --git a/platform/broadcom/sonic-platform-modules-dell/s5296f/sonic_platform/psu.py b/platform/broadcom/sonic-platform-modules-dell/s5296f/sonic_platform/psu.py new file mode 100644 index 000000000000..8e2c06f7ae74 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-dell/s5296f/sonic_platform/psu.py @@ -0,0 +1,325 @@ +#!/usr/bin/env python + +######################################################################## +# DellEMC S5296F +# +# Module contains an implementation of SONiC Platform Base API and +# provides the PSUs' information which are available in the platform +# +######################################################################## + + +try: + from sonic_platform_base.psu_base import PsuBase + from sonic_platform.ipmihelper import IpmiSensor, IpmiFru + from sonic_platform.fan import Fan +except ImportError as e: + raise ImportError(str(e) + "- required module not found") + +class Psu(PsuBase): + """DellEMC Platform-specific PSU class""" + + # { PSU-ID: { Sensor-Name: Sensor-ID } } + SENSOR_MAPPING = { 1: { "State": 0x31, "Current": 0x39, + "Power": 0x37, "Voltage": 0x38, + "InCurrent": 0x36, "InPower": 0x34, + "InVoltage": 0x35, "Temperature": 0xc }, + 2: { "State": 0x32, "Current": 0x3F, + "Power": 0x3D, "Voltage": 0x3E, + "InCurrent": 0x3C, "InPower": 0x3A, + "InVoltage": 0x3B, "Temperature": 0xd } } + # ( PSU-ID: FRU-ID } + FRU_MAPPING = { 1: 1, 2: 2 } + + def __init__(self, psu_index): + PsuBase.__init__(self) + # PSU is 1-based in DellEMC platforms + self.index = psu_index + 1 + self.state_sensor = IpmiSensor(self.SENSOR_MAPPING[self.index]["State"], + is_discrete=True) + self.voltage_sensor = IpmiSensor(self.SENSOR_MAPPING[self.index]["Voltage"]) + self.current_sensor = IpmiSensor(self.SENSOR_MAPPING[self.index]["Current"]) + self.power_sensor = IpmiSensor(self.SENSOR_MAPPING[self.index]["Power"]) + self.input_voltage_sensor = IpmiSensor(self.SENSOR_MAPPING[self.index]["InVoltage"]) + self.input_current_sensor = IpmiSensor(self.SENSOR_MAPPING[self.index]["InCurrent"]) + self.input_power_sensor = IpmiSensor(self.SENSOR_MAPPING[self.index]["InPower"]) + self.temp_sensor = IpmiSensor(self.SENSOR_MAPPING[self.index]["Temperature"]) + self.fru = IpmiFru(self.FRU_MAPPING[self.index]) + + self._fan_list.append(Fan(fan_index=self.index, psu_fan=True, + dependency=self)) + + def get_name(self): + """ + Retrieves the name of the device + + Returns: + string: The name of the device + """ + return "PSU{}".format(self.index) + + def get_presence(self): + """ + Retrieves the presence of the Power Supply Unit (PSU) + + Returns: + bool: True if PSU is present, False if not + """ + presence = False + is_valid, state = self.state_sensor.get_reading() + if is_valid: + if (state & 0b1) == 1: + presence = True + + return presence + + def get_temperature(self): + """ + Retrieves current temperature reading from thermal + Returns: + A float number of current temperature in Celcius up to + nearest thousandth of one degree celcius, e.g. 30.125 + """ + is_valid, temperature = self.temp_sensor.get_reading() + if not is_valid: + temperature = 0 + return float(temperature) + + def get_model(self): + """ + Retrieves the part number of the PSU + + Returns: + string: Part number of PSU + """ + return self.fru.get_board_part_number() + + def get_serial(self): + """ + Retrieves the serial number of the PSU + + Returns: + string: Serial number of PSU + """ + return self.fru.get_board_serial() + + def get_revision(self): + """ + Retrives thehardware revision of the device + Returns: + String: revision value of device + """ + serial = self.fru.get_board_serial() + if serial != "NA" and len(serial) == 23: + return serial[-3:] + else: + return "NA" + + def is_replaceable(self): + """ + Indicate whether this PSU is replaceable. + Returns: + bool: True if it is replaceable. + """ + return True + + def get_status(self): + """ + Retrieves the operational status of the PSU + + Returns: + bool: True if PSU is operating properly, False if not + """ + status = False + is_valid, state = self.state_sensor.get_reading() + if is_valid: + if (state == 0x01): + status = True + + return status + + def get_voltage(self): + """ + Retrieves current PSU voltage output + + Returns: + A float number, the output voltage in volts, + e.g. 12.1 + """ + is_valid, voltage = self.voltage_sensor.get_reading() + if not is_valid: + return None + return float(voltage) + + def get_current(self): + """ + Retrieves present electric current supplied by PSU + + Returns: + A float number, electric current in amperes, + e.g. 15.4 + """ + is_valid, current = self.current_sensor.get_reading() + if not is_valid: + return None + + return float(current) + + def get_power(self): + """ + Retrieves current energy supplied by PSU + + Returns: + A float number, the power in watts, + e.g. 302.6 + """ + is_valid, power = self.power_sensor.get_reading() + if not is_valid: + return None + + return float(power) + + def get_input_voltage(self): + """ + Retrieves current PSU voltage input + + Returns: + A float number, the input voltage in volts, + e.g. 12.1 + """ + is_valid, input_voltage = self.input_voltage_sensor.get_reading() + if not is_valid: + return None + + return float(input_voltage) + + def get_input_current(self): + """ + Retrieves present electric current supplied to PSU + + Returns: + A float number, electric current in amperes, + e.g. 15.4 + """ + is_valid, input_current = self.input_current_sensor.get_reading() + if not is_valid: + return None + + return float(input_current) + + def get_input_power(self): + """ + Retrieves current energy supplied to PSU + + Returns: + A float number, the power in watts, + e.g. 302.6 + """ + is_valid, input_power = self.input_power_sensor.get_reading() + if not is_valid: + return None + + return float(input_power) + + def get_powergood_status(self): + """ + Retrieves the powergood status of PSU + + Returns: + A boolean, True if PSU has stablized its output voltages and + passed all its internal self-tests, False if not. + """ + status = False + is_valid, state = self.state_sensor.get_reading() + if is_valid: + if (state == 0x01): + status = True + + return status + + def get_mfr_id(self): + """ + Retrives the Manufacturer Id of PSU + + Returns: + A string, the manunfacturer id. + """ + return self.fru.get_board_mfr_id() + + def get_type(self): + """ + Retrives the Power Type of PSU + + Returns : + A string, PSU power type + """ + board_product = self.fru.get_board_product() + if board_product is not None : + info = board_product.split(',') + if 'AC' in info : return 'AC' + if 'DC' in info : return 'DC' + return None + + def get_position_in_parent(self): + """ + Retrieves 1-based relative physical position in parent device. + Returns: + integer: The 1-based relative physical position in parent + device or -1 if cannot determine the position + """ + return self.index + + def get_temperature_high_threshold(self): + """ + Returns the high temperature threshold for PSU in Celsius + """ + is_valid, high_threshold = self.temp_sensor.get_threshold("UpperCritical") + if not is_valid: + high_threshold = 105 + high_threshold = "{:.2f}".format(high_threshold) + + return float(high_threshold) + + def get_voltage_low_threshold(self): + """ + Returns PSU low threshold in Volts + """ + is_valid, low_threshold = self.voltage_sensor.get_threshold("LowerCritical") + if not is_valid: + low_threshold = 11.4 #Revisit the value + low_threshold = "{:.2f}".format(low_threshold) + + return float(low_threshold) + + + def get_voltage_high_threshold(self): + """ + Returns PSU high threshold in Volts + """ + is_valid, high_threshold = self.voltage_sensor.get_threshold("UpperCritical") + if not is_valid: + high_threshold = 12.6 #Revisit the value + high_threshold = "{:.2f}".format(high_threshold) + + return float(high_threshold) + + def get_maximum_supplied_power(self): + """ + Retrieves the maximum supplied power by PSU + Returns: + A float number, the maximum power output in Watts. + e.g. 1200.1 + """ + return float(750) + + def set_status_led(self, color): + """ + Sets the state of the PSU status LED + Args: + color: A string representing the color with which to set the PSU status LED + Note: Only support green and off + Returns: + bool: True if status LED state is set successfully, False if not + """ + # Hardware not supported + return False diff --git a/platform/broadcom/sonic-platform-modules-dell/s5296f/sonic_platform/sfp.py b/platform/broadcom/sonic-platform-modules-dell/s5296f/sonic_platform/sfp.py new file mode 100644 index 000000000000..d87ad3db746c --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-dell/s5296f/sonic_platform/sfp.py @@ -0,0 +1,367 @@ +#!/usr/bin/env python + +############################################################################# +# DELLEMC S5296F +# +# Module contains an implementation of SONiC Platform Base API and +# provides the platform information +# +############################################################################# + +try: + import os + import time + import struct + import mmap + from sonic_platform_base.sonic_xcvr.sfp_optoe_base import SfpOptoeBase + +except ImportError as e: + raise ImportError(str(e) + "- required module not found") + +QSFP_INFO_OFFSET = 128 +SFP_INFO_OFFSET = 0 +QSFP_DD_PAGE0 = 0 + +SFP_TYPE_LIST = [ + '0x3' # SFP/SFP+/SFP28 and later +] +QSFP_TYPE_LIST = [ + '0xc', # QSFP + '0xd', # QSFP+ or later + '0x11' # QSFP28 or later +] +QSFP_DD_TYPE_LIST = [ + '0x18' #QSFP-DD Type +] + +class Sfp(SfpOptoeBase): + """ + DELLEMC Platform-specific Sfp class + """ + BASE_RES_PATH = "/sys/bus/pci/devices/0000:04:00.0/resource0" + + def __init__(self, index, sfp_type, eeprom_path): + SfpOptoeBase.__init__(self) + self.port_type = sfp_type + self.sfp_type = sfp_type + self.index = index + self.eeprom_path = eeprom_path + self._initialize_media(delay=False) + + def get_eeprom_path(self): + return self.eeprom_path + + def get_name(self): + return "SFP/SFP+/SFP28" if self.index < 96 else "QSFP28 or later" + + def pci_mem_read(self, mm, offset): + mm.seek(offset) + read_data_stream = mm.read(4) + reg_val = struct.unpack('I', read_data_stream) + mem_val = str(reg_val)[1:-2] + # print "reg_val read:%x"%reg_val + return mem_val + + def pci_mem_write(self, mm, offset, data): + mm.seek(offset) + # print "data to write:%x"%data + mm.write(struct.pack('I', data)) + + def pci_set_value(self, resource, val, offset): + fd = os.open(resource, os.O_RDWR) + mm = mmap.mmap(fd, 0) + val = self.pci_mem_write(mm, offset, val) + mm.close() + os.close(fd) + return val + + def pci_get_value(self, resource, offset): + fd = os.open(resource, os.O_RDWR) + mm = mmap.mmap(fd, 0) + val = self.pci_mem_read(mm, offset) + mm.close() + os.close(fd) + return val + + def _initialize_media(self,delay=False): + """ + Initialize the media type and eeprom driver for SFP + """ + if delay: + time.sleep(1) + self._xcvr_api = None + self.get_xcvr_api() + + self.set_media_type() + self.reinit_sfp_driver() + + def get_position_in_parent(self): + """ + Retrieves 1-based relative physical position in parent device. + Returns: + integer: The 1-based relative physical position in parent + device or -1 if cannot determine the position + """ + return self.index + + def is_replaceable(self): + """ + Indicate whether this device is replaceable. + Returns: + bool: True if it is replaceable. + """ + return True + + def get_presence(self): + """ + Retrieves the presence of the sfp + Returns : True if sfp is present and false if it is absent + """ + # Check for invalid port_num + mask = {'QSFP' : (1 << 4), 'SFP' : (1 << 0)} + # Port offset starts with 0x4004 + port_offset = 16388 + ((self.index-1) * 16) + + try: + reg_value = int(self.pci_get_value(self.BASE_RES_PATH, port_offset)) + # ModPrsL is active low + if reg_value & mask[self.port_type] == 0: + return True + except ValueError: + pass + + return False + + def get_reset_status(self): + """ + Retrives the reset status of SFP + """ + reset_status = False + if (self.port_type == 'QSFP'): + # Port offset starts with 0x4000 + port_offset = 16384 + ((self.index-1) * 16) + + reg_value = int(self.pci_get_value(self.BASE_RES_PATH, port_offset)) + + # Absence of status throws error + if (reg_value == ""): + return reset_status + + # Mask off 4th bit for reset status + mask = (1 << 4) + + if ((reg_value & mask) == 0): + reset_status = True + else: + reset_status = False + + return reset_status + + def get_lpmode(self): + """ + Retrieves the lpmode(low power mode) of this SFP + """ + lpmode_state = False + if (self.port_type == 'QSFP'): + + # Port offset starts with 0x4000 + port_offset = 16384 + ((self.index-1) * 16) + + reg_value = int(self.pci_get_value(self.BASE_RES_PATH, port_offset)) + + # Absence of status throws error + if (reg_value == ""): + return lpmode_state + + # Mask off 6th bit for lpmode + mask = (1 << 6) + + # LPMode is active high + if reg_value & mask == 0: + lpmode_state = False + else: + lpmode_state = True + + return lpmode_state + + def reset(self): + """ + Reset the SFP and returns all user settings to their default state + """ + if (self.port_type == 'QSFP'): + # Port offset starts with 0x4000 + port_offset = 16384 + ((self.index-1) * 16) + + reg_value = int(self.pci_get_value(self.BASE_RES_PATH, port_offset)) + + # Absence of status throws error + if (reg_value == ""): + return False + + # Mask off 4th bit for reset + mask = (1 << 4) + + # ResetL is active low + reg_value = reg_value & ~mask + + # Convert our register value back to a hex string and write back + self.pci_set_value(self.BASE_RES_PATH, reg_value, port_offset) + + # Sleep 1 second to allow it to settle + time.sleep(1) + + reg_value = reg_value | mask + + # Convert our register value back to a hex string and write back + self.pci_set_value(self.BASE_RES_PATH, reg_value, port_offset) + + return True + + else: + return False + + def set_lpmode(self, lpmode): + """ + Sets the lpmode(low power mode) of this SFP + """ + if (self.port_type == 'QSFP'): + # Port offset starts with 0x4000 + port_offset = 16384 + ((self.index-1) * 16) + + reg_value = int(self.pci_get_value(self.BASE_RES_PATH, port_offset)) + + # Absence of status throws error + if (reg_value == ""): + return False + + # Mask off 6th bit for lowpower mode + mask = (1 << 6) + + # LPMode is active high; set or clear the bit accordingly + if lpmode is True: + reg_value = reg_value | mask + else: + reg_value = reg_value & ~mask + + # Convert our register value back to a hex string and write back + self.pci_set_value(self.BASE_RES_PATH, reg_value, port_offset) + + return True + + else: + return False + + def get_status(self): + """ + Retrieves the operational status of the device + """ + reset = self.get_reset_status() + + if (reset == True): + status = False + else: + status = True + + return status + + def set_media_type(self): + """ + Reads optic eeprom byte to determine media type inserted + """ + eeprom_raw = [] + eeprom_raw = self._xcvr_api_factory._get_id() + if eeprom_raw is not None: + eeprom_raw = hex(eeprom_raw) + if eeprom_raw in SFP_TYPE_LIST: + self.sfp_type = 'SFP' + elif eeprom_raw in QSFP_TYPE_LIST: + self.sfp_type = 'QSFP' + elif eeprom_raw in QSFP_DD_TYPE_LIST: + self.sfp_type = 'QSFP_DD' + else: + #Set native port type if EEPROM type is not recognized/readable + self.sfp_type = self.port_type + else: + self.sfp_type = self.port_type + + return self.sfp_type + + def reinit_sfp_driver(self): + """ + Changes the driver based on media type detected + """ + del_sfp_path = "/sys/class/i2c-adapter/i2c-{0}/delete_device".format(self.index+1) + new_sfp_path = "/sys/class/i2c-adapter/i2c-{0}/new_device".format(self.index+1) + driver_path = "/sys/class/i2c-adapter/i2c-{0}/{0}-0050/name".format(self.index+1) + delete_device = "echo 0x50 >" + del_sfp_path + + if not os.path.isfile(driver_path): + print(driver_path, "does not exist") + return False + + try: + with os.fdopen(os.open(driver_path, os.O_RDONLY)) as fd: + driver_name = fd.read() + driver_name = driver_name.rstrip('\r\n') + driver_name = driver_name.lstrip(" ") + + #Avoid re-initialization of the QSFP/SFP optic on QSFP/SFP port. + if self.sfp_type == 'SFP' and driver_name in ['optoe1', 'optoe3']: + subprocess.Popen(delete_device, shell=True, stdout=subprocess.PIPE) + time.sleep(0.2) + new_device = "echo optoe2 0x50 >" + new_sfp_path + subprocess.Popen(new_device, shell=True, stdout=subprocess.PIPE) + time.sleep(2) + elif self.sfp_type == 'QSFP' and driver_name in ['optoe2', 'optoe3']: + subprocess.Popen(delete_device, shell=True, stdout=subprocess.PIPE) + time.sleep(0.2) + new_device = "echo optoe1 0x50 >" + new_sfp_path + subprocess.Popen(new_device, shell=True, stdout=subprocess.PIPE) + time.sleep(2) + elif self.sfp_type == 'QSFP_DD' and driver_name in ['optoe1', 'optoe2']: + subprocess.Popen(delete_device, shell=True, stdout=subprocess.PIPE) + time.sleep(0.2) + new_device = "echo optoe3 0x50 >" + new_sfp_path + subprocess.Popen(new_device, shell=True, stdout=subprocess.PIPE) + time.sleep(2) + + except IOError as e: + print("Error: Unable to open file: %s" % str(e)) + return False + + def get_max_port_power(self): + """ + Retrieves the maximumum power allowed on the port in watts + """ + return 5.0 if self.sfp_type == 'QSFP' else 2.5 + + def get_error_description(self): + """ + Retrives the error descriptions of the SFP module + Returns: + String that represents the current error descriptions of vendor specific errors + In case there are multiple errors, they should be joined by '|', + like: "Bad EEPROM|Unsupported cable" + """ + if not self.get_presence(): + return self.SFP_STATUS_UNPLUGGED + else: + if not os.path.isfile(self.eeprom_path): + return "EEPROM driver is not attached" + + if self.sfp_type == 'SFP': + offset = SFP_INFO_OFFSET + elif self.sfp_type == 'QSFP': + offset = QSFP_INFO_OFFSET + elif self.sfp_type == 'QSFP_DD': + offset = QSFP_DD_PAGE0 + + try: + with open(self.eeprom_path, mode="rb", buffering=0) as eeprom: + eeprom.seek(offset) + eeprom.read(1) + except OSError as e: + return "EEPROM read failed ({})".format(e.strerror) + + return self.SFP_STATUS_OK + diff --git a/platform/broadcom/sonic-platform-modules-dell/s5296f/sonic_platform/thermal.py b/platform/broadcom/sonic-platform-modules-dell/s5296f/sonic_platform/thermal.py new file mode 100644 index 000000000000..c6761ceaefb5 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-dell/s5296f/sonic_platform/thermal.py @@ -0,0 +1,189 @@ +#!/usr/bin/env python + +######################################################################## +# DellEMC S5296F +# +# Module contains an implementation of SONiC Platform Base API and +# provides the Thermals' information which are available in the platform +# +######################################################################## + + +try: + from sonic_platform_base.thermal_base import ThermalBase + from sonic_platform.ipmihelper import IpmiSensor +except ImportError as e: + raise ImportError(str(e) + "- required module not found") + + +class Thermal(ThermalBase): + """DellEMC Platform-specific Thermal class""" + + # [ Sensor-Name, Sensor-ID ] + SENSOR_MAPPING = [ + ['PT Middle Sensor', 0x1], + ['ASIC On-board', 0x2], + ['PT Left Sensor', 0x3], + ['PT Right Sensor', 0x4], + ['Inlet Airflow Sensor', 0x5], + ['PSU1 Airflow Sensor', 0x7], + ['PSU2 Airflow Sensor', 0x8], + ['PSU1 Sensor', 0xc], + ['PSU2 Sensor', 0xd], + ['CPU On-board', 0xe] + ] + + def __init__(self, thermal_index): + ThermalBase.__init__(self) + self.index = thermal_index + 1 + self.sensor = IpmiSensor(self.SENSOR_MAPPING[self.index - 1][1]) + + def get_name(self): + """ + Retrieves the name of the thermal + + Returns: + string: The name of the thermal + """ + return self.SENSOR_MAPPING[self.index - 1][0] + + def get_presence(self): + """ + Retrieves the presence of the thermal + + Returns: + bool: True if thermal is present, False if not + """ + return True + + def get_model(self): + """ + Retrieves the model number (or part number) of the Thermal + + Returns: + string: Model/part number of Thermal + """ + return 'NA' + + def get_serial(self): + """ + Retrieves the serial number of the Thermal + + Returns: + string: Serial number of Thermal + """ + return 'NA' + + def get_status(self): + """ + Retrieves the operational status of the thermal + + Returns: + A boolean value, True if thermal is operating properly, + False if not + """ + return True + + def get_temperature(self): + """ + Retrieves current temperature reading from thermal + + Returns: + A float number of current temperature in Celsius up to + nearest thousandth of one degree Celsius, e.g. 30.125 + """ + is_valid, temperature = self.sensor.get_reading() + if not is_valid: + temperature = 0 + + return float(temperature) + + def get_high_threshold(self): + """ + Retrieves the high threshold temperature of thermal + + Returns: + A float number, the high threshold temperature of thermal in + Celsius up to nearest thousandth of one degree Celsius, + e.g. 30.125 + """ + is_valid, high_threshold = self.sensor.get_threshold("UpperNonCritical") + if not is_valid: + return 0.0 + + return float(high_threshold) + + def get_high_critical_threshold(self): + """ + Retrieves the high critical threshold temperature of thermal + + Returns: + A float number, the high critical threshold temperature of thermal in + Celsius up to nearest thousandth of one degree Celsius, + e.g. 30.125 + """ + is_valid, high_crit_threshold = self.sensor.get_threshold("UpperCritical") + if not is_valid: + return 0.0 + + return float(high_crit_threshold) + + def get_low_threshold(self): + """ + Retrieves the low threshold temperature of thermal + + Returns: + A float number, the low threshold temperature of thermal in + Celsius up to nearest thousandth of one degree Celsius, + e.g. 30.125 + """ + is_valid, low_threshold = self.sensor.get_threshold("LowerNonRecoverable") + if not is_valid: + low_threshold = 0 + + return float(low_threshold) + + def set_high_threshold(self, temperature): + """ + Sets the high threshold temperature of thermal + + Args : + temperature: A float number up to nearest thousandth of one + degree Celsius, e.g. 30.125 + Returns: + A boolean, True if threshold is set successfully, False if + not + """ + # Thermal threshold values are pre-defined based on HW. + return False + + def set_low_threshold(self, temperature): + """ + Sets the low threshold temperature of thermal + + Args : + temperature: A float number up to nearest thousandth of one + degree Celsius, e.g. 30.125 + Returns: + A boolean, True if threshold is set successfully, False if + not + """ + # Thermal threshold values are pre-defined based on HW. + return False + + def get_position_in_parent(self): + """ + Retrieves 1-based relative physical position in parent device. + Returns: + integer: The 1-based relative physical position in parent + device or -1 if cannot determine the position + """ + return self.index + + def is_replaceable(self): + """ + Indicate whether this Thermal is replaceable. + Returns: + bool: True if it is replaceable. + """ + return False diff --git a/platform/broadcom/sonic-platform-modules-dell/s5296f/sonic_platform/watchdog.py b/platform/broadcom/sonic-platform-modules-dell/s5296f/sonic_platform/watchdog.py new file mode 100644 index 000000000000..491224d18c15 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-dell/s5296f/sonic_platform/watchdog.py @@ -0,0 +1,207 @@ +#!/usr/bin/env python + +######################################################################## +# +# DELLEMC S5296F +# +# Abstract base class for implementing a platform-specific class with +# which to interact with a hardware watchdog module in SONiC +# +######################################################################## + +try: + import ctypes + import subprocess + from sonic_platform_base.watchdog_base import WatchdogBase +except ImportError as e: + raise ImportError(str(e) + "- required module not found") + + +class _timespec(ctypes.Structure): + _fields_ = [ + ('tv_sec', ctypes.c_long), + ('tv_nsec', ctypes.c_long) + ] + + +class Watchdog(WatchdogBase): + """ + Abstract base class for interfacing with a hardware watchdog module + """ + + TIMERS = [15,20,30,40,50,60,65,70,80,100,120,140,160,180,210,240] + + armed_time = 0 + timeout = 0 + CLOCK_MONOTONIC = 1 + + def __init__(self): + self._librt = ctypes.CDLL('librt.so.1', use_errno=True) + self._clock_gettime = self._librt.clock_gettime + self._clock_gettime.argtypes=[ctypes.c_int, ctypes.POINTER(_timespec)] + + def _get_command_result(self, cmdline): + try: + proc = subprocess.Popen(cmdline.split(), stdout=subprocess.PIPE, + stderr=subprocess.STDOUT) + stdout = proc.communicate()[0] + proc.wait() + result = stdout.rstrip('\n'.encode()) + except OSError: + result = None + + return result + + def _get_reg_val(self): + # 0x31 = CPLD I2C Base Address + # 0x07 = Watchdog Function Register + value = self._get_command_result("/usr/sbin/i2cget -y 601 0x31 0x07") + if not value: + return None + else: + return int(value, 16) + + def _set_reg_val(self,val): + # 0x31 = CPLD I2C Base Address + # 0x07 = Watchdog Function Register + value = self._get_command_result("/usr/sbin/i2cset -y 601 0x31 0x07 %s" + % (val)) + return value + + def _get_time(self): + """ + To get clock monotonic time + """ + ts = _timespec() + if self._clock_gettime(self.CLOCK_MONOTONIC, ctypes.pointer(ts)) != 0: + self._errno = ctypes.get_errno() + return 0 + return ts.tv_sec + ts.tv_nsec * 1e-9 + + def arm(self, seconds): + """ + Arm the hardware watchdog with a timeout of seconds. + If the watchdog is currently armed, calling this function will + simply reset the timer to the provided value. If the underlying + hardware does not support the value provided in , this + method should arm the watchdog with the *next greater* + available value. + + Returns: + An integer specifying the *actual* number of seconds the + watchdog was armed with. On failure returns -1. + """ + timer_offset = -1 + for key,timer_seconds in enumerate(self.TIMERS): + if seconds > 0 and seconds <= timer_seconds: + timer_offset = key + seconds = timer_seconds + break + + if timer_offset == -1: + return -1 + +# cpld_version = Component.get_cpld0_version() +# wd_enabled_version = "0.8" + +# if cpld_version < wd_enabled_version: +# syslog.syslog(syslog.LOG_ERR, +# 'Older System CPLD ver, Update to 0.8 to support watchdog ') +# return -1 + + # Extracting 5th to 8th bits for WD timer values + reg_val = self._get_reg_val() + wd_timer_offset = (reg_val >> 4) & 0xf + + if wd_timer_offset != timer_offset: + # Setting 5th to 7th bits + # value from timer_offset + self.disarm() + self._set_reg_val((reg_val & 0x07) | (timer_offset << 4)) + + if self.is_armed(): + # Setting last bit to WD Timer punch + # Last bit = WD Timer punch + self._set_reg_val(reg_val & 0xFE) + + else: + # Setting 4th bit to enable WD + # 4th bit = Enable WD + reg_val = self._get_reg_val() + self._set_reg_val(reg_val | 0x8) + + self.armed_time = self._get_time() + self.timeout = seconds + return seconds + + def disarm(self): + """ + Disarm the hardware watchdog + + Returns: + A boolean, True if watchdog is disarmed successfully, False + if not + """ + if self.is_armed(): + # Setting 4th bit to disable WD + # 4th bit = Disable WD + reg_val = self._get_reg_val() + self._set_reg_val(reg_val & 0xF7) + + self.armed_time = 0 + self.timeout = 0 + return True + + return False + + def is_armed(self): + """ + Retrieves the armed state of the hardware watchdog. + + Returns: + A boolean, True if watchdog is armed, False if not + """ + + # Extracting 4th bit to get WD Enable/Disable status + # 0 - Disabled WD + # 1 - Enabled WD + reg_val = self._get_reg_val() + wd_offset = (reg_val >> 3) & 1 + + return bool(wd_offset) + + def get_remaining_time(self): + """ + If the watchdog is armed, retrieve the number of seconds + remaining on the watchdog timer + + Returns: + An integer specifying the number of seconds remaining on + their watchdog timer. If the watchdog is not armed, returns + -1. + + S5296F doesnot have hardware support to show remaining time. + Due to this limitation, this API is implemented in software. + This API would return correct software time difference if it + is called from the process which armed the watchdog timer. + If this API called from any other process, it would return + 0. If the watchdog is not armed, this API would return -1. + """ + if not self.is_armed(): + return -1 + + if self.armed_time > 0 and self.timeout != 0: + cur_time = self._get_time() + + if cur_time <= 0: + return 0 + + diff_time = int(cur_time - self.armed_time) + + if diff_time > self.timeout: + return self.timeout + else: + return self.timeout - diff_time + + return 0 + From 1b83e418f85694ae1a22b84f213d4cd146b227ac Mon Sep 17 00:00:00 2001 From: andywongarista <78833093+andywongarista@users.noreply.github.com> Date: Thu, 25 Aug 2022 18:30:11 -0700 Subject: [PATCH 044/151] Enable AN for Ethernet24-47 (#11839) Enable port AN ON explicitly and then port will become (oper status) UP. Somehow those ports AN are not default ON in bcm sdk. --- .../Arista-720DT-48S/hwsku.json | 26 ++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) diff --git a/device/arista/x86_64-arista_720dt_48s/Arista-720DT-48S/hwsku.json b/device/arista/x86_64-arista_720dt_48s/Arista-720DT-48S/hwsku.json index e0dc3fc5e55c..44f0a20457e1 100644 --- a/device/arista/x86_64-arista_720dt_48s/Arista-720DT-48S/hwsku.json +++ b/device/arista/x86_64-arista_720dt_48s/Arista-720DT-48S/hwsku.json @@ -98,98 +98,122 @@ }, "Ethernet24": { "default_brkout_mode": "1x1G", + "autoneg": "on", "port_type": "RJ45" }, "Ethernet25": { "default_brkout_mode": "1x1G", + "autoneg": "on", "port_type": "RJ45" }, "Ethernet26": { "default_brkout_mode": "1x1G", + "autoneg": "on", "port_type": "RJ45" }, "Ethernet27": { "default_brkout_mode": "1x1G", + "autoneg": "on", "port_type": "RJ45" }, "Ethernet28": { "default_brkout_mode": "1x1G", + "autoneg": "on", "port_type": "RJ45" }, "Ethernet29": { "default_brkout_mode": "1x1G", + "autoneg": "on", "port_type": "RJ45" }, "Ethernet30": { "default_brkout_mode": "1x1G", + "autoneg": "on", "port_type": "RJ45" }, "Ethernet31": { "default_brkout_mode": "1x1G", + "autoneg": "on", "port_type": "RJ45" }, "Ethernet32": { "default_brkout_mode": "1x1G", + "autoneg": "on", "port_type": "RJ45" }, "Ethernet33": { "default_brkout_mode": "1x1G", + "autoneg": "on", "port_type": "RJ45" }, "Ethernet34": { "default_brkout_mode": "1x1G", + "autoneg": "on", "port_type": "RJ45" }, "Ethernet35": { "default_brkout_mode": "1x1G", + "autoneg": "on", "port_type": "RJ45" }, "Ethernet36": { "default_brkout_mode": "1x1G", + "autoneg": "on", "port_type": "RJ45" }, "Ethernet37": { "default_brkout_mode": "1x1G", + "autoneg": "on", "port_type": "RJ45" }, "Ethernet38": { "default_brkout_mode": "1x1G", + "autoneg": "on", "port_type": "RJ45" }, "Ethernet39": { "default_brkout_mode": "1x1G", + "autoneg": "on", "port_type": "RJ45" }, "Ethernet40": { "default_brkout_mode": "1x1G", + "autoneg": "on", "port_type": "RJ45" }, "Ethernet41": { "default_brkout_mode": "1x1G", + "autoneg": "on", "port_type": "RJ45" }, "Ethernet42": { "default_brkout_mode": "1x1G", + "autoneg": "on", "port_type": "RJ45" }, "Ethernet43": { "default_brkout_mode": "1x1G", + "autoneg": "on", "port_type": "RJ45" }, "Ethernet44": { "default_brkout_mode": "1x1G", + "autoneg": "on", "port_type": "RJ45" }, "Ethernet45": { "default_brkout_mode": "1x1G", + "autoneg": "on", "port_type": "RJ45" }, "Ethernet46": { "default_brkout_mode": "1x1G", + "autoneg": "on", "port_type": "RJ45" }, "Ethernet47": { "default_brkout_mode": "1x1G", + "autoneg": "on", "port_type": "RJ45" }, "Ethernet48": { @@ -205,4 +229,4 @@ "default_brkout_mode": "1x10G" } } -} \ No newline at end of file +} From a1eae940d559472ee02dc2496395d169ca838966 Mon Sep 17 00:00:00 2001 From: "Richard.Yu" Date: Fri, 26 Aug 2022 13:51:53 +0800 Subject: [PATCH 045/151] [SAIServer] support saiserver v2 in bullseye (#11849) Upgrade libboost-atomic1.71 to libboost-atomic1.74 Signed-off-by: richardyu-ms Signed-off-by: richardyu-ms --- platform/broadcom/docker-saiserver-brcm/Dockerfile.j2 | 2 +- platform/mellanox/docker-saiserver-mlnx/Dockerfile.j2 | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/platform/broadcom/docker-saiserver-brcm/Dockerfile.j2 b/platform/broadcom/docker-saiserver-brcm/Dockerfile.j2 index 782320a4b39b..92914d7abbf8 100644 --- a/platform/broadcom/docker-saiserver-brcm/Dockerfile.j2 +++ b/platform/broadcom/docker-saiserver-brcm/Dockerfile.j2 @@ -11,7 +11,7 @@ ENV DEBIAN_FRONTEND=noninteractive RUN apt-get update \ && apt-get -y install \ gdb \ - libboost-atomic1.71.0 + libboost-atomic1.74.0 COPY \ {% for deb in docker_saiserver_brcm_debs.split(' ') -%} diff --git a/platform/mellanox/docker-saiserver-mlnx/Dockerfile.j2 b/platform/mellanox/docker-saiserver-mlnx/Dockerfile.j2 index 20f966eb3e83..0f6745d580ab 100644 --- a/platform/mellanox/docker-saiserver-mlnx/Dockerfile.j2 +++ b/platform/mellanox/docker-saiserver-mlnx/Dockerfile.j2 @@ -27,7 +27,7 @@ ENV DEBIAN_FRONTEND=noninteractive RUN apt-get update \ && apt-get -y install \ gdb \ - libboost-atomic1.71.0 + libboost-atomic1.74.0 COPY \ {% for deb in docker_saiserver_mlnx_debs.split(' ') -%} From 0c820a1826576bb0715d3995e27373ea276ce484 Mon Sep 17 00:00:00 2001 From: Junhua Zhai Date: Fri, 26 Aug 2022 14:00:45 +0000 Subject: [PATCH 046/151] Mount directory warmboot in docker gbsyncd (#11852) Why I did it The directory /var/warmboot as top directory for warmboot feature is also needed in docker gbsyncd. Some vendor SAI might save data under it. Without it, the SAI init/creation API failure has happened on PikeZ platform. How I did it Mount host directory /host/warmboot as /var/warmboot in docker gbsyncd, which is same as what it has done on docker syncd. --- platform/components/docker-gbsyncd-broncos.mk | 1 + platform/template/docker-gbsyncd-base.mk | 1 + 2 files changed, 2 insertions(+) diff --git a/platform/components/docker-gbsyncd-broncos.mk b/platform/components/docker-gbsyncd-broncos.mk index 1aad33f9680d..56ec6806b6b1 100644 --- a/platform/components/docker-gbsyncd-broncos.mk +++ b/platform/components/docker-gbsyncd-broncos.mk @@ -30,6 +30,7 @@ $(DOCKER_GBSYNCD_BRONCOS)_CONTAINER_NAME = gbsyncd $(DOCKER_GBSYNCD_BRONCOS)_RUN_OPT += --privileged -t $(DOCKER_GBSYNCD_BRONCOS)_RUN_OPT += -v /host/machine.conf:/etc/machine.conf $(DOCKER_GBSYNCD_BRONCOS)_RUN_OPT += -v /etc/sonic:/etc/sonic:ro +$(DOCKER_GBSYNCD_BRONCOS)_RUN_OPT += -v /host/warmboot:/var/warmboot SONIC_ONLINE_DEBS += $(LIBSAI_BRONCOS) diff --git a/platform/template/docker-gbsyncd-base.mk b/platform/template/docker-gbsyncd-base.mk index 712554405080..404b7513a980 100644 --- a/platform/template/docker-gbsyncd-base.mk +++ b/platform/template/docker-gbsyncd-base.mk @@ -27,3 +27,4 @@ $(DOCKER_GBSYNCD_BASE)_CONTAINER_NAME = gbsyncd $(DOCKER_GBSYNCD_BASE)_RUN_OPT += --privileged -t $(DOCKER_GBSYNCD_BASE)_RUN_OPT += -v /host/machine.conf:/etc/machine.conf $(DOCKER_GBSYNCD_BASE)_RUN_OPT += -v /etc/sonic:/etc/sonic:ro +$(DOCKER_GBSYNCD_BASE)_RUN_OPT += -v /host/warmboot:/var/warmboot From 0ed53bbc1ba0f0987720bf1964ebd72ca1daf1d3 Mon Sep 17 00:00:00 2001 From: abdosi <58047199+abdosi@users.noreply.github.com> Date: Fri, 26 Aug 2022 08:04:00 -0700 Subject: [PATCH 047/151] New API to support runtime metadata needed for Feature Table field jinja rendering. (#11795) Added new API to return runtime metadata dictionary as needed during Feature Table field rendering by hostcfgd. --- src/sonic-py-common/sonic_py_common/device_info.py | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/sonic-py-common/sonic_py_common/device_info.py b/src/sonic-py-common/sonic_py_common/device_info.py index 92809474ad6a..6605c798ec1a 100644 --- a/src/sonic-py-common/sonic_py_common/device_info.py +++ b/src/sonic-py-common/sonic_py_common/device_info.py @@ -442,7 +442,7 @@ def is_multi_npu(): def is_voq_chassis(): switch_type = get_platform_info().get('switch_type') - return True if switch_type and switch_type == 'voq' else False + return True if switch_type and (switch_type == 'voq' or switch_type == 'fabric') else False def is_packet_chassis(): @@ -469,6 +469,14 @@ def is_supervisor(): return True return False +def get_device_runtime_metadata(): + chassis_metadata = {} + if is_chassis(): + chassis_metadata = {'CHASSIS_METADATA': {'module_type' : 'supervisor' if is_supervisor() else 'linecard', + 'chassis_type': 'voq' if is_voq_chassis() else 'packet'}} + + port_metadata = {'ETHERNET_PORTS_PRESENT': True if get_path_to_port_config_file(hwsku=None, asic="0" if is_multi_npu() else None) else False} + return {'DEVICE_RUNTIME_METADATA': chassis_metadata | port_metadata } def get_npu_id_from_name(npu_name): if npu_name.startswith(NPU_NAME_PREFIX): From 8ccae96bfeba9b4ebcf4b0def06b25022176ef5a Mon Sep 17 00:00:00 2001 From: Samuel Angebault Date: Fri, 26 Aug 2022 18:38:45 +0200 Subject: [PATCH 048/151] [Arista] Update platform submodule (#11853) --- platform/barefoot/sonic-platform-modules-arista | 2 +- platform/broadcom/sonic-platform-modules-arista | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/platform/barefoot/sonic-platform-modules-arista b/platform/barefoot/sonic-platform-modules-arista index d570713cdf71..b65a69a9e1c2 160000 --- a/platform/barefoot/sonic-platform-modules-arista +++ b/platform/barefoot/sonic-platform-modules-arista @@ -1 +1 @@ -Subproject commit d570713cdf715ea9d722a0a8cf606148edc359f8 +Subproject commit b65a69a9e1c2c876ba5210ce8b2a1cc9b5c8b18f diff --git a/platform/broadcom/sonic-platform-modules-arista b/platform/broadcom/sonic-platform-modules-arista index d570713cdf71..b65a69a9e1c2 160000 --- a/platform/broadcom/sonic-platform-modules-arista +++ b/platform/broadcom/sonic-platform-modules-arista @@ -1 +1 @@ -Subproject commit d570713cdf715ea9d722a0a8cf606148edc359f8 +Subproject commit b65a69a9e1c2c876ba5210ce8b2a1cc9b5c8b18f From bd55b342d9f52c24da0f9d188113097499c9996f Mon Sep 17 00:00:00 2001 From: Junhua Zhai Date: Sun, 28 Aug 2022 04:48:22 +0000 Subject: [PATCH 049/151] Advance submodule sonic-sairedis (#11704) 2022-07-28 854d54e: Add support of mdio IPC server class using sai switch api and unix socket (sonic-net/sonic-sairedis#1080) (Jiahua Wang) 2022-07-27 513cb2a: [FlexCounter] Refactor FlexCounter class (sonic-net/sonic-sairedis#1073) (Junchao-Mellanox) --- src/sonic-sairedis | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sonic-sairedis b/src/sonic-sairedis index 9652ea49b22e..854d54e07fd8 160000 --- a/src/sonic-sairedis +++ b/src/sonic-sairedis @@ -1 +1 @@ -Subproject commit 9652ea49b22e5f14421e957e3c8e52a35729478b +Subproject commit 854d54e07fd8eeff9cae0410e8e7f04d6385400b From 178a30bc3bf8e4cf2dc5fac4949660d5a7c8b9c0 Mon Sep 17 00:00:00 2001 From: Zain Budhwani <99770260+zbud-msft@users.noreply.github.com> Date: Sun, 28 Aug 2022 12:28:58 -0700 Subject: [PATCH 050/151] Update swss common submodule for events api (#11858) #### Why I did it Structured events code like eventd, rsyslogplugin, requires changes made in swss-common Submodule adds these newest commits: 56b0f18 (HEAD, origin/master, origin/HEAD, master) Events: APIs to set/get global options (#672) 5467c89 Add changes to yml file to improve pytest (#674) #### How I did it Updated git submodule #### How to verify it Check new commit pointer --- src/sonic-swss-common | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sonic-swss-common b/src/sonic-swss-common index ecc13b26f70c..56b0f1877a02 160000 --- a/src/sonic-swss-common +++ b/src/sonic-swss-common @@ -1 +1 @@ -Subproject commit ecc13b26f70c22812eda4c03ddcc063ed800d8b7 +Subproject commit 56b0f1877a02c43b51595a2d7e6f09e1fabd3d32 From f2c9a3584df071d18ad4cf66721d8a449e7e2533 Mon Sep 17 00:00:00 2001 From: Samuel Angebault Date: Mon, 29 Aug 2022 04:45:24 +0200 Subject: [PATCH 051/151] [Arista] Fix content of platform.json for DCS-720DT-48S (#11855) Why I did it Content of platform.json was outdated and some platform_tests/api of sonic-mgmt were failing. How I did it Added the necessary values to platform.json How to verify it Running platform_tests/api of sonic-mgmt should yield 100% passrate. --- .../x86_64-arista_720dt_48s/platform.json | 59 +++++++++++++++---- 1 file changed, 46 insertions(+), 13 deletions(-) diff --git a/device/arista/x86_64-arista_720dt_48s/platform.json b/device/arista/x86_64-arista_720dt_48s/platform.json index 90fa1ea1f57c..625e64335278 100644 --- a/device/arista/x86_64-arista_720dt_48s/platform.json +++ b/device/arista/x86_64-arista_720dt_48s/platform.json @@ -2,15 +2,38 @@ "chassis": { "name": "CCS-720DT-48S", "components": [], - "fans": [ - { - "name": "fan1" - }, - { - "name": "fan2" + "fan_drawers": [ + { + "name": "fixed1", + "status_led": { + "controllable": false, + "available": false + }, + "fans": [ + { + "name": "fan1", + "status_led": { + "available": false + } + } + ] + }, + { + "name": "fixed2", + "status_led": { + "controllable": false, + "available": false + }, + "fans": [ + { + "name": "fan2", + "status_led": { + "available": false + } + } + ] } ], - "fan_drawers": [], "psus": [ { "name": "psu1", @@ -21,7 +44,10 @@ "temperature": false, "voltage": false, "voltage_high_threshold": false, - "voltage_low_threshold": false + "voltage_low_threshold": false, + "status_led": { + "controllable": false + } }, { "name": "psu2", @@ -32,21 +58,28 @@ "temperature": false, "voltage": false, "voltage_high_threshold": false, - "voltage_low_threshold": false + "voltage_low_threshold": false, + "status_led": { + "controllable": false + } } ], "thermals": [ { - "name": "Cpu temp sensor" + "name": "Cpu temp sensor", + "controllable": false }, { - "name": "Psu temp sensor" + "name": "Psu temp sensor", + "controllable": false }, { - "name": "SFP+ connector temp sensor" + "name": "SFP+ connector temp sensor", + "controllable": false }, { - "name": "MAC external temp sensor" + "name": "MAC external temp sensor", + "controllable": false } ], "sfps": [ From 4b4e311c14dcc94a40dcb1802348dcf2ee87c468 Mon Sep 17 00:00:00 2001 From: Liu Shilong Date: Mon, 29 Aug 2022 11:24:57 +0800 Subject: [PATCH 052/151] [actions] Update github actions label and automerge. (#11736) 1. Add auto approve step when adding label to version upgrading PR. 2. Use mssonicbld TOKEN to merge version upgrading PR instead of 'github actions' --- .github/workflows/automerge.yml | 2 +- .github/workflows/label.yml | 7 +++++++ 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/.github/workflows/automerge.yml b/.github/workflows/automerge.yml index 502f5d8987d9..ee27244bfb1f 100644 --- a/.github/workflows/automerge.yml +++ b/.github/workflows/automerge.yml @@ -15,7 +15,7 @@ jobs: - name: automerge uses: 'pascalgn/automerge-action@v0.13.1' env: - GITHUB_TOKEN: '${{ secrets.GITHUB_TOKEN }}' + GITHUB_TOKEN: '${{ secrets.TOKEN }}' MERGE_LABELS: 'automerge' MERGE_METHOD: 'squash' MERGE_FILTER_AUTHOR: 'mssonicbld' diff --git a/.github/workflows/label.yml b/.github/workflows/label.yml index 5f8c0279b7e1..307cbd86f871 100644 --- a/.github/workflows/label.yml +++ b/.github/workflows/label.yml @@ -22,6 +22,13 @@ jobs: label: runs-on: ubuntu-latest steps: + - name: approve + run: | + set -e + echo ${{ secrets.GITHUB_TOKEN }} | gh auth login --with-token + url=$(echo $GITHUB_CONTEXT | jq -r '.event.pull_request._links.html.href') + echo PR: $url + gh pr review $url --approve - uses: actions/labeler@main with: repo-token: "${{ secrets.GITHUB_TOKEN }}" From 35945c9015472fb0c2feb019c6cf9dc9479c7e9e Mon Sep 17 00:00:00 2001 From: Liu Shilong Date: Mon, 29 Aug 2022 11:26:15 +0800 Subject: [PATCH 053/151] [ci] Update reproducible build related pipeline. (#11810) --- .azure-pipelines/azure-pipelines-repd-build-variables.yml | 2 +- .azure-pipelines/official-build.yml | 2 +- azure-pipelines.yml | 5 +---- 3 files changed, 3 insertions(+), 6 deletions(-) diff --git a/.azure-pipelines/azure-pipelines-repd-build-variables.yml b/.azure-pipelines/azure-pipelines-repd-build-variables.yml index 1bd897dafb92..af77e97e2ff0 100644 --- a/.azure-pipelines/azure-pipelines-repd-build-variables.yml +++ b/.azure-pipelines/azure-pipelines-repd-build-variables.yml @@ -1,6 +1,6 @@ variables: ${{ if eq(variables['Build.Reason'],'PullRequest') }}: - VERSION_CONTROL_OPTIONS: 'SONIC_VERSION_CONTROL_COMPONENTS=$([ "$(System.PullRequest.TargetBranch)" != "master" ] && echo deb,py2,py3,web,git,docker)' + VERSION_CONTROL_OPTIONS: 'SONIC_VERSION_CONTROL_COMPONENTS=$([[ "$(System.PullRequest.TargetBranch)" =~ ^20[2-9][0-9]{3}$ ]] && echo deb,py2,py3,web,git,docker)' ${{ elseif ne(variables['Build.SourceBranchName'],'master') }}: VERSION_CONTROL_OPTIONS: 'SONIC_VERSION_CONTROL_COMPONENTS=deb,py2,py3,web,git,docker' ${{ else }}: diff --git a/.azure-pipelines/official-build.yml b/.azure-pipelines/official-build.yml index ee99d7ca3f28..c73124f2e91f 100644 --- a/.azure-pipelines/official-build.yml +++ b/.azure-pipelines/official-build.yml @@ -38,7 +38,7 @@ stages: variables: - name: CACHE_MODE value: wcache - - template: azure-pipelines-repd-build-variables.yml + - template: azure-pipelines-repd-build-variables.yml@buildimage jobs: - template: azure-pipelines-build.yml parameters: diff --git a/azure-pipelines.yml b/azure-pipelines.yml index b9653c2bc8cd..5876080411a2 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -38,10 +38,7 @@ resources: variables: - template: .azure-pipelines/azure-pipelines-repd-build-variables.yml@buildimage -- ${{ if eq(variables['Build.Reason'], 'PullRequest') }}: - - template: .azure-pipelines/template-variables.yml -- ${{ else }}: - - template: .azure-pipelines/template-variables.yml@buildimage +- template: .azure-pipelines/template-variables.yml@buildimage - name: CACHE_MODE value: rcache - name: ENABLE_FIPS From 3bf1abb2dcaa03f02a245609127fc316829a89a2 Mon Sep 17 00:00:00 2001 From: abdosi <58047199+abdosi@users.noreply.github.com> Date: Mon, 29 Aug 2022 08:19:28 -0700 Subject: [PATCH 054/151] Address Review Comment to define SONIC_GLOBAL_DB_CLI in gbsyncd.sh (#11857) As part of PR #11754 Change was added to use variable SONIC_DB_NS_CLI for namespace but that will not work since ./files/scripts/syncd_common.sh uses SONIC_DB_CLI. So revert back to use SONIC_DB_CLI and define new variable for SONIC_GLOBAL_DB_CLI for global/host db cli access Also fixed DB_CLI not working for namespace. --- files/scripts/gbsyncd.sh | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/files/scripts/gbsyncd.sh b/files/scripts/gbsyncd.sh index a7eaaced0cd6..0948aaadc199 100755 --- a/files/scripts/gbsyncd.sh +++ b/files/scripts/gbsyncd.sh @@ -4,8 +4,8 @@ function startplatform() { - declare -a DbCliArray=($SONIC_DB_CLI $SONIC_DB_NS_CLI) - for DB_CLI in ${DbCliArray[@]}; do + declare -A DbCliArray=([0]=$SONIC_GLOBAL_DB_CLI [1]=$SONIC_DB_CLI) + for DB_CLI in "${DbCliArray[@]}"; do # Add gbsyncd to FEATURE table, if not in. It did have same config as syncd. if [ -z $($DB_CLI CONFIG_DB HGET 'FEATURE|gbsyncd' state) ]; then local CMD="local r=redis.call('DUMP', KEYS[1]); redis.call('RESTORE', KEYS[2], 0, r)" @@ -34,11 +34,11 @@ PEER="swss" DEBUGLOG="/tmp/swss-$SERVICE-debug$DEV.log" LOCKFILE="/tmp/swss-$SERVICE-lock$DEV" NAMESPACE_PREFIX="asic" +SONIC_GLOBAL_DB_CLI="sonic-db-cli" SONIC_DB_CLI="sonic-db-cli" -SONIC_DB_NS_CLI="sonic-db-cli" if [ "$DEV" ]; then NET_NS="$NAMESPACE_PREFIX$DEV" #name of the network namespace - SONIC_DB_NS_CLI="sonic-db-cli -n $NET_NS" + SONIC_DB_CLI="sonic-db-cli -n $NET_NS" fi case "$1" in From a1d3d994576cfb467c19e2a7394277b6d92a4e71 Mon Sep 17 00:00:00 2001 From: xumia <59720581+xumia@users.noreply.github.com> Date: Tue, 30 Aug 2022 02:15:42 +0800 Subject: [PATCH 055/151] [Build] Increase the size of the installer image (#11869) #### Why I did it Fix the build failure caused by the installer image size too small. The installer image is only used during the build, not impact the final images. See https://dev.azure.com/mssonic/build/_build/results?buildId=139926&view=logs&j=cef3d8a9-152e-5193-620b-567dc18af272&t=359769c4-8b5e-5976-a793-85da132e0a6f ``` + fallocate -l 2048M ./sonic-installer.img + mkfs.vfat ./sonic-installer.img mkfs.fat 4.2 (2021-01-31) ++ mktemp -d + tmpdir=/tmp/tmp.TqdDSc00Cn + mount -o loop ./sonic-installer.img /tmp/tmp.TqdDSc00Cn + cp target/sonic-vs.bin /tmp/tmp.TqdDSc00Cn/onie-installer.bin cp: error writing '/tmp/tmp.TqdDSc00Cn/onie-installer.bin': No space left on device [ FAIL LOG END ] [ target/sonic-vs.img.gz ] ``` #### How I did it Increase the size from 2048M to 4096M. Why not increase to 16G like qcow2 image? The qcow2 supports the sparse disk, although a big disk size allocated, but it will not consume the real disk size. The falocate does not support the sparse disk. We do not want to allocate a very big disk, but no use at all. It will require more space to build. --- scripts/build_kvm_image.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/build_kvm_image.sh b/scripts/build_kvm_image.sh index 6e5fd7dec742..44009ed013f4 100755 --- a/scripts/build_kvm_image.sh +++ b/scripts/build_kvm_image.sh @@ -36,7 +36,7 @@ create_disk() prepare_installer_disk() { - fallocate -l 2048M $INSTALLER_DISK + fallocate -l 4096M $INSTALLER_DISK mkfs.vfat $INSTALLER_DISK From 186568a21d1998868ca0a8d8e888ef35a5d17bf8 Mon Sep 17 00:00:00 2001 From: Saikrishna Arcot Date: Mon, 29 Aug 2022 11:34:23 -0700 Subject: [PATCH 056/151] Update sensor names for msn4600c for the 5.10 kernel (#11491) * Update sensor names for msn4600c for the 5.10 kernel Looks like a sensor was removed in the 5.10 kernel for the tps53679 sensor, so the names/indexing has changed. Related to Azure/sonic-mgmt#4513. Signed-off-by: Saikrishna Arcot * Update sensors file Signed-off-by: Saikrishna Arcot Signed-off-by: Saikrishna Arcot --- .../x86_64-mlnx_msn4600c-r0/sensors.conf | 34 ++++++++++--------- 1 file changed, 18 insertions(+), 16 deletions(-) diff --git a/device/mellanox/x86_64-mlnx_msn4600c-r0/sensors.conf b/device/mellanox/x86_64-mlnx_msn4600c-r0/sensors.conf index 3ff78f15023f..b0ad1ff407b4 100644 --- a/device/mellanox/x86_64-mlnx_msn4600c-r0/sensors.conf +++ b/device/mellanox/x86_64-mlnx_msn4600c-r0/sensors.conf @@ -129,27 +129,29 @@ bus "i2c-5" "i2c-1-mux (chan_id 4)" bus "i2c-15" "i2c-1-mux (chan_id 6)" chip "tps53679-i2c-*-58" - label in1 "PMIC-8 PSU 12V Rail (in1)" - label in2 "PMIC-8 PSU 12V Rail (in2)" - label in3 "PMIC-8 COMEX 1.8V Rail (out)" - label in4 "PMIC-8 COMEX 1.05V Rail (out)" + label in1 "PMIC-8 PSU 12V Rail (in)" + label in2 "PMIC-8 COMEX 1.8V Rail (out)" + label in3 "PMIC-8 COMEX 1.05V Rail (out)" label temp1 "PMIC-8 Temp 1" label temp2 "PMIC-8 Temp 2" - label power1 "PMIC-8 COMEX 1.8V Rail Pwr (out)" - label power2 "PMIC-8 COMEX 1.05V Rail Pwr (out)" - label curr1 "PMIC-8 COMEX 1.8V Rail Curr (out)" - label curr2 "PMIC-8 COMEX 1.05V Rail Curr (out)" + ignore power1 + label power2 "PMIC-8 COMEX 1.8V Rail Pwr (out)" + label power3 "PMIC-8 COMEX 1.05V Rail Pwr (out)" + ignore curr1 + label curr2 "PMIC-8 COMEX 1.8V Rail Curr (out)" + label curr3 "PMIC-8 COMEX 1.05V Rail Curr (out)" chip "tps53679-i2c-*-61" - label in1 "PMIC-9 PSU 12V Rail (in1)" - label in2 "PMIC-9 PSU 12V Rail (in2)" - label in3 "PMIC-9 COMEX 1.2V Rail (out)" - ignore in4 + label in1 "PMIC-9 PSU 12V Rail (in)" + label in2 "PMIC-9 COMEX 1.2V Rail (out)" + ignore in3 label temp1 "PMIC-9 Temp 1" label temp2 "PMIC-9 Temp 2" - label power1 "PMIC-9 COMEX 1.2V Rail Pwr (out)" - ignore power2 - label curr1 "PMIC-9 COMEX 1.2V Rail Curr (out)" - ignore curr2 + ignore power1 + label power2 "PMIC-9 COMEX 1.2V Rail Pwr (out)" + ignore power3 + ignore curr1 + label curr2 "PMIC-9 COMEX 1.2V Rail Curr (out)" + ignore curr3 # Power supplies bus "i2c-4" "i2c-1-mux (chan_id 3)" From de54eece467452b0909cdf13a8a085b8303812ca Mon Sep 17 00:00:00 2001 From: Saikrishna Arcot Date: Mon, 29 Aug 2022 11:35:07 -0700 Subject: [PATCH 057/151] Fix error handling when failing to install a deb package (#11846) The current error handling code for when a deb package fails to be installed currently has a chain of commands linked together by && and ends with `exit 1`. The assumption is that the commands would succeed, and the last `exit 1` would end it with a non-zero return code, thus fully failing the target and causing the build to stop because of bash's -e flag. However, if one of the commands prior to `exit 1` returns a non-zero return code, then bash won't actually treat it as a terminating error. From bash's man page: ``` -e Exit immediately if a pipeline (which may consist of a single simple command), a list, or a compound command (see SHELL GRAMMAR above), exits with a non-zero status. The shell does not exit if the command that fails is part of the command list immediately following a while or until keyword, part of the test following the if or elif reserved words, part of any command executed in a && or || list except the command following the final && or ||, any command in a pipeline but the last, or if the command's return value is being inverted with !. If a compound command other than a subshell returns a non-zero status because a command failed while -e was being ignored, the shell does not exit. ``` The part `part of any command executed in a && or || list except the command following the final && or ||` says that if the failing command is not the `exit 1` that we have at the end, then bash doesn't treat it as an error and exit immediately. Additionally, since this is a compound command, but isn't in a subshell (subshell are marked by `(` and `)`, whereas `{` and `}` just tells bash to run the commands in the current environment), bash doesn't exist. The result of this is that in the deb-install target, if a package installation fails, it may be infinitely stuck in that while-loop. There are two fixes for this: change to using a subshell, or use `;` instead of `&&`. Using a subshell would, I think, require exporting any shell variables used in the subshell, so I chose to change the `&&` to `;`. In addition, at the start of the subshell, `set +e` is added in, which removes the exit-on-error handling of bash. This makes sure that all commands are run (the output of which may help for debugging) and that it still exits with 1, which will then fully fail the target. Signed-off-by: Saikrishna Arcot Signed-off-by: Saikrishna Arcot --- slave.mk | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/slave.mk b/slave.mk index e1f4a0ef80d9..7cdee954ad73 100644 --- a/slave.mk +++ b/slave.mk @@ -736,13 +736,13 @@ $(SONIC_INSTALL_DEBS) : $(DEBS_PATH)/%-install : .platform $$(addsuffix -install # put a lock here because dpkg does not allow installing packages in parallel if mkdir $(DEBS_PATH)/dpkg_lock &> /dev/null; then ifneq ($(CROSS_BUILD_ENVIRON),y) - { sudo DEBIAN_FRONTEND=noninteractive dpkg -i $(DEBS_PATH)/$* $(LOG) && rm -d $(DEBS_PATH)/dpkg_lock && break; } || { rm -d $(DEBS_PATH)/dpkg_lock && sudo lsof /var/lib/dpkg/lock-frontend && ps aux && exit 1 ; } + { sudo DEBIAN_FRONTEND=noninteractive dpkg -i $(DEBS_PATH)/$* $(LOG) && rm -d $(DEBS_PATH)/dpkg_lock && break; } || { set +e; rm -d $(DEBS_PATH)/dpkg_lock; sudo lsof /var/lib/dpkg/lock-frontend; ps aux; exit 1 ; } else # Relocate debian packages python libraries to the cross python virtual env location { sudo DEBIAN_FRONTEND=noninteractive dpkg -i $(if $(findstring $(LINUX_HEADERS),$*),--force-depends) $(DEBS_PATH)/$* $(LOG) && \ rm -rf tmp && mkdir tmp && dpkg -x $(DEBS_PATH)/$* tmp && (sudo cp -rf tmp/usr/lib/python2*/dist-packages/* $(VIRTENV_LIB_CROSS_PYTHON2)/python2*/site-packages/ 2>/dev/null || true) && \ (sudo cp -rf tmp/usr/lib/python3/dist-packages/* $(VIRTENV_LIB_CROSS_PYTHON3)/python3.*/site-packages/ 2>/dev/null || true) && \ - rm -d $(DEBS_PATH)/dpkg_lock && break; } || { rm -d $(DEBS_PATH)/dpkg_lock && sudo lsof /var/lib/dpkg/lock-frontend && ps aux && exit 1 ; } + rm -d $(DEBS_PATH)/dpkg_lock && break; } || { set +e; rm -d $(DEBS_PATH)/dpkg_lock; sudo lsof /var/lib/dpkg/lock-frontend; ps aux; exit 1 ; } endif fi sleep 10 From 4733053c53dde1c07dbfe72aeb4232e41bef54a4 Mon Sep 17 00:00:00 2001 From: xumia <59720581+xumia@users.noreply.github.com> Date: Tue, 30 Aug 2022 09:19:58 +0800 Subject: [PATCH 058/151] Fix vs check install login timeout issue (#11727) Why I did it Fix a build not stable issue: #11620 The vs vm has started successfully, but failed to wait for the message "sonic login:". There were 55 builds failed caused by the issue in the last 30 days. AzurePipelineBuildLogs | where startTime > ago(30d) | where type =~ "task" | where result =~ "failed" | where name =~ "Build sonic image" | where content contains "Timeout exceeded" | where content contains "re.compile('sonic login:')" | project-away content | extend branchName=case(reason=~"pullRequest", tostring(todynamic(parameters)['system.pullRequest.targetBranch']), replace("refs/heads/", "", sourceBranch)) | summarize FailedCount=dcount(buildId) by branchName branchName FailedCount master 37 202012 9 202106 4 202111 2 202205 1 201911 1 It is caused by the login message mixed with the output message of the /etc/rc.local, one of the examples as below: (see the message rc.local[307]: sonic+ onie_disco_subnet=255.255.255.0 login: ) The check_install.py was waiting for the message "sonic login:", and Linux console was waiting for the username input (the login message has already printed in the console). https://dev.azure.com/mssonic/build/_build/results?buildId=123294&view=logs&j=cef3d8a9-152e-5193-620b-567dc18af272&t=359769c4-8b5e-5976-a793-85da132e0a6f 2022-07-17T15:00:58.9198877Z [ 25.493855] rc.local[307]: + onie_disco_opt53=05 2022-07-17T15:00:58.9199330Z [ 25.595054] rc.local[307]: + onie_disco_router=10.0.2.2 2022-07-17T15:00:58.9199781Z [ 25.699409] rc.local[307]: + onie_disco_serverid=10.0.2.2 2022-07-17T15:00:58.9200252Z [ 25.789891] rc.local[307]: + onie_disco_siaddr=10.0.2.2 2022-07-17T15:00:58.9200622Z [ 25.880920] 2022-07-17T15:00:58.9200745Z 2022-07-17T15:00:58.9201019Z Debian GNU/Linux 10 sonic ttyS0 2022-07-17T15:00:58.9201201Z 2022-07-17T15:00:58.9201542Z rc.local[307]: sonic+ onie_disco_subnet=255.255.255.0 login: 2022-07-17T15:00:58.9202309Z [ 26.079767] rc.local[307]: + onie_exec_url=file://dev/vdb/onie-installer.bin How I did it Input a newline when finished to run the script /etc/rc.local. If entering a newline, the message "sonic login:" will prompt again. --- check_install.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/check_install.py b/check_install.py index ecd3a8ee9a3b..b8fc3936f751 100755 --- a/check_install.py +++ b/check_install.py @@ -19,6 +19,7 @@ def main(): passwd_prompt = 'Password:' cmd_prompt = "{}@sonic:~\$ $".format(args.u) grub_selection = "The highlighted entry will be executed" + firsttime_prompt = 'firsttime_exit' i = 0 while True: @@ -38,13 +39,17 @@ def main(): # bootup sonic image while True: - i = p.expect([login_prompt, passwd_prompt, cmd_prompt]) + i = p.expect([login_prompt, passwd_prompt, firsttime_prompt, cmd_prompt]) if i == 0: # send user name p.sendline(args.u) elif i == 1: # send password p.sendline(args.P) + elif i == 2: + # fix a login timeout issue, caused by the login_prompt message mixed with the output message of the rc.local + time.sleep(1) + p.sendline() else: break From cf69206d020a4b905bdd2f408c974ed4fe8cc9a2 Mon Sep 17 00:00:00 2001 From: Liu Shilong Date: Tue, 30 Aug 2022 14:23:09 +0800 Subject: [PATCH 059/151] [ci] Fix bug involved by PR 11810 which affect official build pipeline (#11891) Why I did it Fix the official build not triggered correctly issue, caused by the azp template path not existing. How I did it Change the azp template path. --- .azure-pipelines/official-build.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.azure-pipelines/official-build.yml b/.azure-pipelines/official-build.yml index c73124f2e91f..3ebb106a621b 100644 --- a/.azure-pipelines/official-build.yml +++ b/.azure-pipelines/official-build.yml @@ -38,7 +38,7 @@ stages: variables: - name: CACHE_MODE value: wcache - - template: azure-pipelines-repd-build-variables.yml@buildimage + - template: .azure-pipelines/azure-pipelines-repd-build-variables.yml@buildimage jobs: - template: azure-pipelines-build.yml parameters: From 092e0394b5bb0e74daa8b984c4ee6da5fdaac625 Mon Sep 17 00:00:00 2001 From: Arun Saravanan Balachandran <52521751+ArunSaravananBalachandran@users.noreply.github.com> Date: Tue, 30 Aug 2022 23:53:52 +0530 Subject: [PATCH 060/151] DellEMC: Z9332f - Graceful platform reboot (#10240) Why I did it To gracefully unmount filesystems and stop containers while performing a cold reboot. Unmount ONIE-BOOT if mounted during fast/soft/warm reboot How I did it Override systemd-reboot service to perform a cold reboot. Unmount ONIE-BOOT if mounted using fast/soft/warm-reboot plugins. How to verify it On reboot, verify that the container stop and filesystem unmount services have completed execution before the platform reboot. --- .../debian/platform-modules-z9332f.install | 6 ++++- .../z9332f/scripts/fast-reboot_plugin | 8 +++++++ .../z9332f/scripts/override.conf | 3 +++ .../z9332f/scripts/platform_reboot_override | 23 +++++++++++++++++++ .../z9332f/scripts/soft-reboot_plugin | 1 + .../z9332f/scripts/warm-reboot_plugin | 1 + 6 files changed, 41 insertions(+), 1 deletion(-) create mode 100755 platform/broadcom/sonic-platform-modules-dell/z9332f/scripts/fast-reboot_plugin create mode 100644 platform/broadcom/sonic-platform-modules-dell/z9332f/scripts/override.conf create mode 100755 platform/broadcom/sonic-platform-modules-dell/z9332f/scripts/platform_reboot_override create mode 120000 platform/broadcom/sonic-platform-modules-dell/z9332f/scripts/soft-reboot_plugin create mode 120000 platform/broadcom/sonic-platform-modules-dell/z9332f/scripts/warm-reboot_plugin diff --git a/platform/broadcom/sonic-platform-modules-dell/debian/platform-modules-z9332f.install b/platform/broadcom/sonic-platform-modules-dell/debian/platform-modules-z9332f.install index ad25015472da..ecbd88a6ffef 100644 --- a/platform/broadcom/sonic-platform-modules-dell/debian/platform-modules-z9332f.install +++ b/platform/broadcom/sonic-platform-modules-dell/debian/platform-modules-z9332f.install @@ -4,7 +4,11 @@ z9332f/scripts/sensors usr/bin z9332f/cfg/z9332f-modules.conf etc/modules-load.d z9332f/systemd/platform-modules-z9332f.service etc/systemd/system z9332f/modules/sonic_platform-1.0-py3-none-any.whl usr/share/sonic/device/x86_64-dellemc_z9332f_d1508-r0 -common/platform_reboot usr/share/sonic/device/x86_64-dellemc_z9332f_d1508-r0 +z9332f/scripts/platform_reboot_override usr/share/sonic/device/x86_64-dellemc_z9332f_d1508-r0 +z9332f/scripts/override.conf /etc/systemd/system/systemd-reboot.service.d +z9332f/scripts/fast-reboot_plugin usr/share/sonic/device/x86_64-dellemc_z9332f_d1508-r0 +z9332f/scripts/soft-reboot_plugin usr/share/sonic/device/x86_64-dellemc_z9332f_d1508-r0 +z9332f/scripts/warm-reboot_plugin usr/share/sonic/device/x86_64-dellemc_z9332f_d1508-r0 common/pcisysfs.py usr/bin common/io_rd_wr.py usr/local/bin common/fw-updater usr/local/bin diff --git a/platform/broadcom/sonic-platform-modules-dell/z9332f/scripts/fast-reboot_plugin b/platform/broadcom/sonic-platform-modules-dell/z9332f/scripts/fast-reboot_plugin new file mode 100755 index 000000000000..0335f71d02b5 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-dell/z9332f/scripts/fast-reboot_plugin @@ -0,0 +1,8 @@ +#!/bin/bash + +ONIE_PATH="/mnt/onie-boot" + +# Unmount ONIE partition if mounted +if grep -qs ${ONIE_PATH} /proc/mounts; then + umount ${ONIE_PATH} +fi diff --git a/platform/broadcom/sonic-platform-modules-dell/z9332f/scripts/override.conf b/platform/broadcom/sonic-platform-modules-dell/z9332f/scripts/override.conf new file mode 100644 index 000000000000..9f17da1c2335 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-dell/z9332f/scripts/override.conf @@ -0,0 +1,3 @@ +[Service] +ExecStart= +ExecStart=/usr/share/sonic/device/x86_64-dellemc_z9332f_d1508-r0/platform_reboot_override diff --git a/platform/broadcom/sonic-platform-modules-dell/z9332f/scripts/platform_reboot_override b/platform/broadcom/sonic-platform-modules-dell/z9332f/scripts/platform_reboot_override new file mode 100755 index 000000000000..ca04ac0635a7 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-dell/z9332f/scripts/platform_reboot_override @@ -0,0 +1,23 @@ +#!/usr/bin/python3 +import os +import struct + +PORT_RES = '/dev/port' + + +def portio_reg_write(resource, offset, val): + fd = os.open(resource, os.O_RDWR) + if(fd < 0): + print('file open failed %s' % resource) + return + if(os.lseek(fd, offset, os.SEEK_SET) != offset): + print('lseek failed on %s' % resource) + return + ret = os.write(fd, struct.pack('B', val)) + if(ret != 1): + print('write failed %d' % ret) + return + os.close(fd) + +if __name__ == "__main__": + portio_reg_write(PORT_RES, 0xcf9, 0xe) diff --git a/platform/broadcom/sonic-platform-modules-dell/z9332f/scripts/soft-reboot_plugin b/platform/broadcom/sonic-platform-modules-dell/z9332f/scripts/soft-reboot_plugin new file mode 120000 index 000000000000..180742bbc4d5 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-dell/z9332f/scripts/soft-reboot_plugin @@ -0,0 +1 @@ +fast-reboot_plugin \ No newline at end of file diff --git a/platform/broadcom/sonic-platform-modules-dell/z9332f/scripts/warm-reboot_plugin b/platform/broadcom/sonic-platform-modules-dell/z9332f/scripts/warm-reboot_plugin new file mode 120000 index 000000000000..180742bbc4d5 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-dell/z9332f/scripts/warm-reboot_plugin @@ -0,0 +1 @@ +fast-reboot_plugin \ No newline at end of file From 1e75abc274e019d12496ffd8c9e16a9600245ec6 Mon Sep 17 00:00:00 2001 From: saksarav-nokia Date: Tue, 30 Aug 2022 23:23:17 -0400 Subject: [PATCH 061/151] [Nokia][Nokia-IXR7250E-36x100G & Nokia-IXR7250E-36x400G] Update BCM (#11577) config to support ERSPAN egress mirror and also set flag to preserve ECN --- .../0/jr2cp-nokia-18x100g-4x25g-config.bcm | 44 +++++++++++++++++-- .../0/sai_postinit_cmd.soc | 37 +--------------- .../1/jr2cp-nokia-18x100g-4x25g-config.bcm | 44 +++++++++++++++++-- .../1/sai_postinit_cmd.soc | 7 +-- .../0/jr2cp-nokia-18x400g-config.bcm | 43 ++++++++++++++++-- .../0/sai_postinit_cmd.soc | 2 + .../1/jr2cp-nokia-18x400g-config.bcm | 43 ++++++++++++++++-- .../1/sai_postinit_cmd.soc | 2 + 8 files changed, 168 insertions(+), 54 deletions(-) diff --git a/device/nokia/x86_64-nokia_ixr7250e_36x400g-r0/Nokia-IXR7250E-36x100G/0/jr2cp-nokia-18x100g-4x25g-config.bcm b/device/nokia/x86_64-nokia_ixr7250e_36x400g-r0/Nokia-IXR7250E-36x100G/0/jr2cp-nokia-18x100g-4x25g-config.bcm index 72c101facb35..3eb3ba20a424 100644 --- a/device/nokia/x86_64-nokia_ixr7250e_36x400g-r0/Nokia-IXR7250E-36x100G/0/jr2cp-nokia-18x100g-4x25g-config.bcm +++ b/device/nokia/x86_64-nokia_ixr7250e_36x400g-r0/Nokia-IXR7250E-36x100G/0/jr2cp-nokia-18x100g-4x25g-config.bcm @@ -8,7 +8,7 @@ dma_desc_aggregator_chain_length_max.BCM8885X=1000 dma_desc_aggregator_enable_specific_MDB_LPM.BCM8885X=1 dma_desc_aggregator_timeout_usec.BCM8885X=1000 dport_map_direct.BCM8885X=1 - +sai_postinit_cmd_file=/usr/share/sonic/hwsku/sai_postinit_cmd.soc dtm_flow_mapping_mode_region_64.BCM8885X=3 dtm_flow_mapping_mode_region_65.BCM8885X=3 dtm_flow_mapping_mode_region_66.BCM8885X=3 @@ -1532,12 +1532,50 @@ ucode_port_15.BCM8885X=CGE6:core_0.15 ucode_port_16.BCM8885X=CGE4:core_0.16 ucode_port_17.BCM8885X=CGE2:core_0.17 ucode_port_18.BCM8885X=CGE0:core_0.18 - - ucode_port_19.BCM8885X=RCY0:core_0.19 ucode_port_20.BCM8885X=RCY1:core_1.20 ucode_port_21.BCM8885X=OLP:core_1.21 +ucode_port_100.BCM8885X=RCY_MIRROR.0:core_0.100 +ucode_port_101.BCM8885X=RCY_MIRROR.1:core_0.101 +ucode_port_102.BCM8885X=RCY_MIRROR.2:core_0.102 +ucode_port_103.BCM8885X=RCY_MIRROR.3:core_0.103 +ucode_port_104.BCM8885X=RCY_MIRROR.4:core_0.104 +ucode_port_105.BCM8885X=RCY_MIRROR.5:core_0.105 +ucode_port_106.BCM8885X=RCY_MIRROR.6:core_0.106 +ucode_port_107.BCM8885X=RCY_MIRROR.7:core_0.107 +ucode_port_108.BCM8885X=RCY_MIRROR.8:core_0.108 +ucode_port_109.BCM8885X=RCY_MIRROR.9:core_0.109 +ucode_port_110.BCM8885X=RCY_MIRROR.10:core_0.110 +ucode_port_111.BCM8885X=RCY_MIRROR.11:core_0.111 +ucode_port_112.BCM8885X=RCY_MIRROR.12:core_0.112 +ucode_port_113.BCM8885X=RCY_MIRROR.13:core_0.113 +ucode_port_114.BCM8885X=RCY_MIRROR.14:core_0.114 +ucode_port_115.BCM8885X=RCY_MIRROR.15:core_0.115 +ucode_port_116.BCM8885X=RCY_MIRROR.16:core_0.116 +ucode_port_117.BCM8885X=RCY_MIRROR.17:core_0.117 +ucode_port_118.BCM8885X=RCY_MIRROR.18:core_0.118 +ucode_port_119.BCM8885X=RCY_MIRROR.19:core_0.119 +ucode_port_120.BCM8885X=RCY_MIRROR.0:core_1.120 +ucode_port_121.BCM8885X=RCY_MIRROR.1:core_1.121 +ucode_port_122.BCM8885X=RCY_MIRROR.2:core_1.122 +ucode_port_123.BCM8885X=RCY_MIRROR.3:core_1.123 +ucode_port_124.BCM8885X=RCY_MIRROR.4:core_1.124 +ucode_port_125.BCM8885X=RCY_MIRROR.5:core_1.125 +ucode_port_126.BCM8885X=RCY_MIRROR.6:core_1.126 +ucode_port_127.BCM8885X=RCY_MIRROR.7:core_1.127 +ucode_port_128.BCM8885X=RCY_MIRROR.8:core_1.128 +ucode_port_129.BCM8885X=RCY_MIRROR.9:core_1.129 +ucode_port_130.BCM8885X=RCY_MIRROR.10:core_1.130 +ucode_port_131.BCM8885X=RCY_MIRROR.11:core_1.131 +ucode_port_132.BCM8885X=RCY_MIRROR.12:core_1.132 +ucode_port_133.BCM8885X=RCY_MIRROR.13:core_1.133 +ucode_port_134.BCM8885X=RCY_MIRROR.14:core_1.134 +ucode_port_135.BCM8885X=RCY_MIRROR.15:core_1.135 +ucode_port_136.BCM8885X=RCY_MIRROR.16:core_1.136 +ucode_port_137.BCM8885X=RCY_MIRROR.17:core_1.137 +ucode_port_138.BCM8885X=RCY_MIRROR.18:core_1.138 +ucode_port_139.BCM8885X=RCY_MIRROR.19:core_1.139 port_init_speed_1.BCM8885X=100000 port_init_speed_2.BCM8885X=100000 diff --git a/device/nokia/x86_64-nokia_ixr7250e_36x400g-r0/Nokia-IXR7250E-36x100G/0/sai_postinit_cmd.soc b/device/nokia/x86_64-nokia_ixr7250e_36x400g-r0/Nokia-IXR7250E-36x100G/0/sai_postinit_cmd.soc index 26466f89ae44..20e19b8faebe 100644 --- a/device/nokia/x86_64-nokia_ixr7250e_36x400g-r0/Nokia-IXR7250E-36x100G/0/sai_postinit_cmd.soc +++ b/device/nokia/x86_64-nokia_ixr7250e_36x400g-r0/Nokia-IXR7250E-36x100G/0/sai_postinit_cmd.soc @@ -1,36 +1 @@ -phy set 3 reg=0xd134 data=-8 lane=0 -phy set 3 reg=0xd135 data=132 lane=0 -phy set 3 reg=0xd136 data=-8 lane=0 -phy set 3 reg=0xd137 data=0 lane=0 -phy set 3 reg=0xd138 data=0 lane=0 -phy set 3 reg=0xd133 data=0x1802 lane=0 - -phy set 3 reg=0xd134 data=-8 lane=1 -phy set 3 reg=0xd135 data=132 lane=1 -phy set 3 reg=0xd136 data=-12 lane=1 -phy set 3 reg=0xd137 data=0 lane=1 -phy set 3 reg=0xd138 data=0 lane=1 -phy set 3 reg=0xd133 data=0x1800 lane=1 - -phy set 3 reg=0xd134 data=-8 lane=7 -phy set 3 reg=0xd135 data=132 lane=7 -phy set 3 reg=0xd136 data=-8 lane=7 -phy set 3 reg=0xd137 data=0 lane=7 -phy set 3 reg=0xd138 data=0 lane=7 -phy set 3 reg=0xd133 data=0x1804 lane=7 - - -phy set 6 reg=0xd134 data=-8 lane=1 -phy set 6 reg=0xd135 data=132 lane=1 -phy set 6 reg=0xd136 data=-8 lane=1 -phy set 6 reg=0xd137 data=0 lane=1 -phy set 6 reg=0xd138 data=0 lane=1 -phy set 6 reg=0xd133 data=0x1802 lane=1 - - -phy set 8 reg=0xd134 data=-8 lane=1 -phy set 8 reg=0xd135 data=132 lane=1 -phy set 8 reg=0xd136 data=-8 lane=1 -phy set 8 reg=0xd137 data=0 lane=1 -phy set 8 reg=0xd138 data=0 lane=1 -phy set 8 reg=0xd133 data=0x1802 lane=1 +mod ETPPC_MAP_FWD_QOS_DP_TO_TYPE_FWD 0 128 TYPE_FWD_KEEP_ECN_BITS=1 diff --git a/device/nokia/x86_64-nokia_ixr7250e_36x400g-r0/Nokia-IXR7250E-36x100G/1/jr2cp-nokia-18x100g-4x25g-config.bcm b/device/nokia/x86_64-nokia_ixr7250e_36x400g-r0/Nokia-IXR7250E-36x100G/1/jr2cp-nokia-18x100g-4x25g-config.bcm index cc6d41ea3da6..57e966b35315 100644 --- a/device/nokia/x86_64-nokia_ixr7250e_36x400g-r0/Nokia-IXR7250E-36x100G/1/jr2cp-nokia-18x100g-4x25g-config.bcm +++ b/device/nokia/x86_64-nokia_ixr7250e_36x400g-r0/Nokia-IXR7250E-36x100G/1/jr2cp-nokia-18x100g-4x25g-config.bcm @@ -8,7 +8,7 @@ dma_desc_aggregator_chain_length_max.BCM8885X=1000 dma_desc_aggregator_enable_specific_MDB_LPM.BCM8885X=1 dma_desc_aggregator_timeout_usec.BCM8885X=1000 dport_map_direct.BCM8885X=1 - +sai_postinit_cmd_file=/usr/share/sonic/hwsku/sai_postinit_cmd.soc dtm_flow_mapping_mode_region_64.BCM8885X=3 dtm_flow_mapping_mode_region_65.BCM8885X=3 dtm_flow_mapping_mode_region_66.BCM8885X=3 @@ -1551,12 +1551,50 @@ ucode_port_15.BCM8885X=CGE6:core_0.15 ucode_port_16.BCM8885X=CGE4:core_0.16 ucode_port_17.BCM8885X=CGE2:core_0.17 ucode_port_18.BCM8885X=CGE0:core_0.18 - - ucode_port_19.BCM8885X=RCY0:core_0.19 ucode_port_20.BCM8885X=RCY1:core_1.20 ucode_port_21.BCM8885X=OLP:core_1.21 +ucode_port_100.BCM8885X=RCY_MIRROR.0:core_0.100 +ucode_port_101.BCM8885X=RCY_MIRROR.1:core_0.101 +ucode_port_102.BCM8885X=RCY_MIRROR.2:core_0.102 +ucode_port_103.BCM8885X=RCY_MIRROR.3:core_0.103 +ucode_port_104.BCM8885X=RCY_MIRROR.4:core_0.104 +ucode_port_105.BCM8885X=RCY_MIRROR.5:core_0.105 +ucode_port_106.BCM8885X=RCY_MIRROR.6:core_0.106 +ucode_port_107.BCM8885X=RCY_MIRROR.7:core_0.107 +ucode_port_108.BCM8885X=RCY_MIRROR.8:core_0.108 +ucode_port_109.BCM8885X=RCY_MIRROR.9:core_0.109 +ucode_port_110.BCM8885X=RCY_MIRROR.10:core_0.110 +ucode_port_111.BCM8885X=RCY_MIRROR.11:core_0.111 +ucode_port_112.BCM8885X=RCY_MIRROR.12:core_0.112 +ucode_port_113.BCM8885X=RCY_MIRROR.13:core_0.113 +ucode_port_114.BCM8885X=RCY_MIRROR.14:core_0.114 +ucode_port_115.BCM8885X=RCY_MIRROR.15:core_0.115 +ucode_port_116.BCM8885X=RCY_MIRROR.16:core_0.116 +ucode_port_117.BCM8885X=RCY_MIRROR.17:core_0.117 +ucode_port_118.BCM8885X=RCY_MIRROR.18:core_0.118 +ucode_port_119.BCM8885X=RCY_MIRROR.19:core_0.119 +ucode_port_120.BCM8885X=RCY_MIRROR.0:core_1.120 +ucode_port_121.BCM8885X=RCY_MIRROR.1:core_1.121 +ucode_port_122.BCM8885X=RCY_MIRROR.2:core_1.122 +ucode_port_123.BCM8885X=RCY_MIRROR.3:core_1.123 +ucode_port_124.BCM8885X=RCY_MIRROR.4:core_1.124 +ucode_port_125.BCM8885X=RCY_MIRROR.5:core_1.125 +ucode_port_126.BCM8885X=RCY_MIRROR.6:core_1.126 +ucode_port_127.BCM8885X=RCY_MIRROR.7:core_1.127 +ucode_port_128.BCM8885X=RCY_MIRROR.8:core_1.128 +ucode_port_129.BCM8885X=RCY_MIRROR.9:core_1.129 +ucode_port_130.BCM8885X=RCY_MIRROR.10:core_1.130 +ucode_port_131.BCM8885X=RCY_MIRROR.11:core_1.131 +ucode_port_132.BCM8885X=RCY_MIRROR.12:core_1.132 +ucode_port_133.BCM8885X=RCY_MIRROR.13:core_1.133 +ucode_port_134.BCM8885X=RCY_MIRROR.14:core_1.134 +ucode_port_135.BCM8885X=RCY_MIRROR.15:core_1.135 +ucode_port_136.BCM8885X=RCY_MIRROR.16:core_1.136 +ucode_port_137.BCM8885X=RCY_MIRROR.17:core_1.137 +ucode_port_138.BCM8885X=RCY_MIRROR.18:core_1.138 +ucode_port_139.BCM8885X=RCY_MIRROR.19:core_1.139 port_init_speed_1.BCM8885X=100000 port_init_speed_2.BCM8885X=100000 diff --git a/device/nokia/x86_64-nokia_ixr7250e_36x400g-r0/Nokia-IXR7250E-36x100G/1/sai_postinit_cmd.soc b/device/nokia/x86_64-nokia_ixr7250e_36x400g-r0/Nokia-IXR7250E-36x100G/1/sai_postinit_cmd.soc index db5ad5ebb264..20e19b8faebe 100644 --- a/device/nokia/x86_64-nokia_ixr7250e_36x400g-r0/Nokia-IXR7250E-36x100G/1/sai_postinit_cmd.soc +++ b/device/nokia/x86_64-nokia_ixr7250e_36x400g-r0/Nokia-IXR7250E-36x100G/1/sai_postinit_cmd.soc @@ -1,6 +1 @@ -phy set 8 reg=0xd134 data=-8 lane=1 -phy set 8 reg=0xd135 data=132 lane=1 -phy set 8 reg=0xd136 data=-8 lane=1 -phy set 8 reg=0xd137 data=0 lane=1 -phy set 8 reg=0xd138 data=0 lane=1 -phy set 8 reg=0xd133 data=0x1802 lane=1 +mod ETPPC_MAP_FWD_QOS_DP_TO_TYPE_FWD 0 128 TYPE_FWD_KEEP_ECN_BITS=1 diff --git a/device/nokia/x86_64-nokia_ixr7250e_36x400g-r0/Nokia-IXR7250E-36x400G/0/jr2cp-nokia-18x400g-config.bcm b/device/nokia/x86_64-nokia_ixr7250e_36x400g-r0/Nokia-IXR7250E-36x400G/0/jr2cp-nokia-18x400g-config.bcm index 5303bb263ba2..1da65733155a 100644 --- a/device/nokia/x86_64-nokia_ixr7250e_36x400g-r0/Nokia-IXR7250E-36x400G/0/jr2cp-nokia-18x400g-config.bcm +++ b/device/nokia/x86_64-nokia_ixr7250e_36x400g-r0/Nokia-IXR7250E-36x400G/0/jr2cp-nokia-18x400g-config.bcm @@ -1551,13 +1551,50 @@ ucode_port_15.BCM8885X=CDGE3:core_0.15 ucode_port_16.BCM8885X=CDGE2:core_0.16 ucode_port_17.BCM8885X=CDGE1:core_0.17 ucode_port_18.BCM8885X=CDGE0:core_0.18 - - ucode_port_19.BCM8885X=RCY0:core_0.19 ucode_port_20.BCM8885X=RCY1:core_1.20 ucode_port_21.BCM8885X=OLP:core_1.21 - +ucode_port_100.BCM8885X=RCY_MIRROR.0:core_0.100 +ucode_port_101.BCM8885X=RCY_MIRROR.1:core_0.101 +ucode_port_102.BCM8885X=RCY_MIRROR.2:core_0.102 +ucode_port_103.BCM8885X=RCY_MIRROR.3:core_0.103 +ucode_port_104.BCM8885X=RCY_MIRROR.4:core_0.104 +ucode_port_105.BCM8885X=RCY_MIRROR.5:core_0.105 +ucode_port_106.BCM8885X=RCY_MIRROR.6:core_0.106 +ucode_port_107.BCM8885X=RCY_MIRROR.7:core_0.107 +ucode_port_108.BCM8885X=RCY_MIRROR.8:core_0.108 +ucode_port_109.BCM8885X=RCY_MIRROR.9:core_0.109 +ucode_port_110.BCM8885X=RCY_MIRROR.10:core_0.110 +ucode_port_111.BCM8885X=RCY_MIRROR.11:core_0.111 +ucode_port_112.BCM8885X=RCY_MIRROR.12:core_0.112 +ucode_port_113.BCM8885X=RCY_MIRROR.13:core_0.113 +ucode_port_114.BCM8885X=RCY_MIRROR.14:core_0.114 +ucode_port_115.BCM8885X=RCY_MIRROR.15:core_0.115 +ucode_port_116.BCM8885X=RCY_MIRROR.16:core_0.116 +ucode_port_117.BCM8885X=RCY_MIRROR.17:core_0.117 +ucode_port_118.BCM8885X=RCY_MIRROR.18:core_0.118 +ucode_port_119.BCM8885X=RCY_MIRROR.19:core_0.119 +ucode_port_120.BCM8885X=RCY_MIRROR.0:core_1.120 +ucode_port_121.BCM8885X=RCY_MIRROR.1:core_1.121 +ucode_port_122.BCM8885X=RCY_MIRROR.2:core_1.122 +ucode_port_123.BCM8885X=RCY_MIRROR.3:core_1.123 +ucode_port_124.BCM8885X=RCY_MIRROR.4:core_1.124 +ucode_port_125.BCM8885X=RCY_MIRROR.5:core_1.125 +ucode_port_126.BCM8885X=RCY_MIRROR.6:core_1.126 +ucode_port_127.BCM8885X=RCY_MIRROR.7:core_1.127 +ucode_port_128.BCM8885X=RCY_MIRROR.8:core_1.128 +ucode_port_129.BCM8885X=RCY_MIRROR.9:core_1.129 +ucode_port_130.BCM8885X=RCY_MIRROR.10:core_1.130 +ucode_port_131.BCM8885X=RCY_MIRROR.11:core_1.131 +ucode_port_132.BCM8885X=RCY_MIRROR.12:core_1.132 +ucode_port_133.BCM8885X=RCY_MIRROR.13:core_1.133 +ucode_port_134.BCM8885X=RCY_MIRROR.14:core_1.134 +ucode_port_135.BCM8885X=RCY_MIRROR.15:core_1.135 +ucode_port_136.BCM8885X=RCY_MIRROR.16:core_1.136 +ucode_port_137.BCM8885X=RCY_MIRROR.17:core_1.137 +ucode_port_138.BCM8885X=RCY_MIRROR.18:core_1.138 +ucode_port_139.BCM8885X=RCY_MIRROR.19:core_1.139 serdes_lane_config_dfe_1.BCM8885X=on serdes_lane_config_dfe_2.BCM8885X=on diff --git a/device/nokia/x86_64-nokia_ixr7250e_36x400g-r0/Nokia-IXR7250E-36x400G/0/sai_postinit_cmd.soc b/device/nokia/x86_64-nokia_ixr7250e_36x400g-r0/Nokia-IXR7250E-36x400G/0/sai_postinit_cmd.soc index 650134e7e589..fd18216d3c84 100644 --- a/device/nokia/x86_64-nokia_ixr7250e_36x400g-r0/Nokia-IXR7250E-36x400G/0/sai_postinit_cmd.soc +++ b/device/nokia/x86_64-nokia_ixr7250e_36x400g-r0/Nokia-IXR7250E-36x400G/0/sai_postinit_cmd.soc @@ -35,3 +35,5 @@ phy set 17 reg=0xd136 data=-16 lane=2 phy set 17 reg=0xd137 data=0 lane=2 phy set 17 reg=0xd138 data=0 lane=2 phy set 17 reg=0xd133 data=0x1804 lane=2 + +mod ETPPC_MAP_FWD_QOS_DP_TO_TYPE_FWD 0 128 TYPE_FWD_KEEP_ECN_BITS=1 diff --git a/device/nokia/x86_64-nokia_ixr7250e_36x400g-r0/Nokia-IXR7250E-36x400G/1/jr2cp-nokia-18x400g-config.bcm b/device/nokia/x86_64-nokia_ixr7250e_36x400g-r0/Nokia-IXR7250E-36x400G/1/jr2cp-nokia-18x400g-config.bcm index eb58c1ca42e1..4d6790d5398b 100644 --- a/device/nokia/x86_64-nokia_ixr7250e_36x400g-r0/Nokia-IXR7250E-36x400G/1/jr2cp-nokia-18x400g-config.bcm +++ b/device/nokia/x86_64-nokia_ixr7250e_36x400g-r0/Nokia-IXR7250E-36x400G/1/jr2cp-nokia-18x400g-config.bcm @@ -1551,13 +1551,50 @@ ucode_port_15.BCM8885X=CDGE3:core_0.15 ucode_port_16.BCM8885X=CDGE2:core_0.16 ucode_port_17.BCM8885X=CDGE1:core_0.17 ucode_port_18.BCM8885X=CDGE0:core_0.18 - - ucode_port_19.BCM8885X=RCY0:core_0.19 ucode_port_20.BCM8885X=RCY1:core_1.20 ucode_port_21.BCM8885X=OLP:core_1.21 - +ucode_port_100.BCM8885X=RCY_MIRROR.0:core_0.100 +ucode_port_101.BCM8885X=RCY_MIRROR.1:core_0.101 +ucode_port_102.BCM8885X=RCY_MIRROR.2:core_0.102 +ucode_port_103.BCM8885X=RCY_MIRROR.3:core_0.103 +ucode_port_104.BCM8885X=RCY_MIRROR.4:core_0.104 +ucode_port_105.BCM8885X=RCY_MIRROR.5:core_0.105 +ucode_port_106.BCM8885X=RCY_MIRROR.6:core_0.106 +ucode_port_107.BCM8885X=RCY_MIRROR.7:core_0.107 +ucode_port_108.BCM8885X=RCY_MIRROR.8:core_0.108 +ucode_port_109.BCM8885X=RCY_MIRROR.9:core_0.109 +ucode_port_110.BCM8885X=RCY_MIRROR.10:core_0.110 +ucode_port_111.BCM8885X=RCY_MIRROR.11:core_0.111 +ucode_port_112.BCM8885X=RCY_MIRROR.12:core_0.112 +ucode_port_113.BCM8885X=RCY_MIRROR.13:core_0.113 +ucode_port_114.BCM8885X=RCY_MIRROR.14:core_0.114 +ucode_port_115.BCM8885X=RCY_MIRROR.15:core_0.115 +ucode_port_116.BCM8885X=RCY_MIRROR.16:core_0.116 +ucode_port_117.BCM8885X=RCY_MIRROR.17:core_0.117 +ucode_port_118.BCM8885X=RCY_MIRROR.18:core_0.118 +ucode_port_119.BCM8885X=RCY_MIRROR.19:core_0.119 +ucode_port_120.BCM8885X=RCY_MIRROR.0:core_1.120 +ucode_port_121.BCM8885X=RCY_MIRROR.1:core_1.121 +ucode_port_122.BCM8885X=RCY_MIRROR.2:core_1.122 +ucode_port_123.BCM8885X=RCY_MIRROR.3:core_1.123 +ucode_port_124.BCM8885X=RCY_MIRROR.4:core_1.124 +ucode_port_125.BCM8885X=RCY_MIRROR.5:core_1.125 +ucode_port_126.BCM8885X=RCY_MIRROR.6:core_1.126 +ucode_port_127.BCM8885X=RCY_MIRROR.7:core_1.127 +ucode_port_128.BCM8885X=RCY_MIRROR.8:core_1.128 +ucode_port_129.BCM8885X=RCY_MIRROR.9:core_1.129 +ucode_port_130.BCM8885X=RCY_MIRROR.10:core_1.130 +ucode_port_131.BCM8885X=RCY_MIRROR.11:core_1.131 +ucode_port_132.BCM8885X=RCY_MIRROR.12:core_1.132 +ucode_port_133.BCM8885X=RCY_MIRROR.13:core_1.133 +ucode_port_134.BCM8885X=RCY_MIRROR.14:core_1.134 +ucode_port_135.BCM8885X=RCY_MIRROR.15:core_1.135 +ucode_port_136.BCM8885X=RCY_MIRROR.16:core_1.136 +ucode_port_137.BCM8885X=RCY_MIRROR.17:core_1.137 +ucode_port_138.BCM8885X=RCY_MIRROR.18:core_1.138 +ucode_port_139.BCM8885X=RCY_MIRROR.19:core_1.139 serdes_lane_config_dfe_1.BCM8885X=on serdes_lane_config_dfe_2.BCM8885X=on diff --git a/device/nokia/x86_64-nokia_ixr7250e_36x400g-r0/Nokia-IXR7250E-36x400G/1/sai_postinit_cmd.soc b/device/nokia/x86_64-nokia_ixr7250e_36x400g-r0/Nokia-IXR7250E-36x400G/1/sai_postinit_cmd.soc index b22dde093132..109b18ecaaf2 100644 --- a/device/nokia/x86_64-nokia_ixr7250e_36x400g-r0/Nokia-IXR7250E-36x400G/1/sai_postinit_cmd.soc +++ b/device/nokia/x86_64-nokia_ixr7250e_36x400g-r0/Nokia-IXR7250E-36x400G/1/sai_postinit_cmd.soc @@ -12,3 +12,5 @@ phy set 8 reg=0xd136 data=-8 lane=1 phy set 8 reg=0xd137 data=0 lane=1 phy set 8 reg=0xd138 data=0 lane=1 phy set 8 reg=0xd133 data=0x1802 lane=1 + +mod ETPPC_MAP_FWD_QOS_DP_TO_TYPE_FWD 0 128 TYPE_FWD_KEEP_ECN_BITS=1 From 402714723805baff2d49c053a9513a1ab6519f1e Mon Sep 17 00:00:00 2001 From: abdosi <58047199+abdosi@users.noreply.github.com> Date: Wed, 31 Aug 2022 10:48:15 -0700 Subject: [PATCH 062/151] Align API get_device_runtime_metadata() for python version < 3.9 (#11900) Why I did it: API get_device_runtime_metadata() added by #11795 uses merge operator for dict but that is supported only for python version >=3.9. This API will be be used by scrips eg:hostcfgd which is still build for buster which does not have python 3.9 support. --- src/sonic-py-common/sonic_py_common/device_info.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/sonic-py-common/sonic_py_common/device_info.py b/src/sonic-py-common/sonic_py_common/device_info.py index 6605c798ec1a..8173c2677275 100644 --- a/src/sonic-py-common/sonic_py_common/device_info.py +++ b/src/sonic-py-common/sonic_py_common/device_info.py @@ -476,7 +476,10 @@ def get_device_runtime_metadata(): 'chassis_type': 'voq' if is_voq_chassis() else 'packet'}} port_metadata = {'ETHERNET_PORTS_PRESENT': True if get_path_to_port_config_file(hwsku=None, asic="0" if is_multi_npu() else None) else False} - return {'DEVICE_RUNTIME_METADATA': chassis_metadata | port_metadata } + runtime_metadata = {} + runtime_metadata.update(chassis_metadata) + runtime_metadata.update(port_metadata) + return {'DEVICE_RUNTIME_METADATA': runtime_metadata } def get_npu_id_from_name(npu_name): if npu_name.startswith(NPU_NAME_PREFIX): From c601f241396bc4f4f23082fc50311fd5f69fe1a8 Mon Sep 17 00:00:00 2001 From: Dev Ojha <47282568+developfast@users.noreply.github.com> Date: Wed, 31 Aug 2022 11:08:32 -0700 Subject: [PATCH 063/151] [Arista7050cx3] TD3 SKU changes for pg headroom value after interop testing with cisco 8102 (#11901) Why I did it After PFC interop testing between 8102 and 7050cx3, data packet losses were observed on the Rx ports of the 7050cx3 (inflow from 8102) during testing. This was primarily due to the slower response times to react to PFC pause packets for the 8102, when receiving such frames from neighboring devices. To solve for the packet drops, the 7050cx3 pg headroom size has to be increased to 160kB. How I did it Modified the xoff threshold value to 160kB in the pg_profile file to allow for the buffer manager to read that value when building the image, and configuring the device How to verify it run "mmuconfig -l" once image is built Signed-off-by: dojha --- .../Arista-7050CX3-32S-C32/pg_profile_lookup.ini | 12 ++++++------ .../Arista-7050CX3-32S-D48C8/pg_profile_lookup.ini | 12 ++++++------ 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/device/arista/x86_64-arista_7050cx3_32s/Arista-7050CX3-32S-C32/pg_profile_lookup.ini b/device/arista/x86_64-arista_7050cx3_32s/Arista-7050CX3-32S-C32/pg_profile_lookup.ini index dd405301f720..5b4482bc74c7 100644 --- a/device/arista/x86_64-arista_7050cx3_32s/Arista-7050CX3-32S-C32/pg_profile_lookup.ini +++ b/device/arista/x86_64-arista_7050cx3_32s/Arista-7050CX3-32S-C32/pg_profile_lookup.ini @@ -1,8 +1,8 @@ # PG lossless profiles. # speed cable size xon xoff threshold xon_offset - 50000 5m 4608 4608 33792 0 4608 - 100000 5m 4608 4608 49408 0 4608 - 50000 40m 4608 4608 36352 0 4608 - 100000 40m 4608 4608 54528 0 4608 - 50000 300m 4608 4608 55296 0 4608 - 100000 300m 4608 4608 92672 0 4608 + 50000 5m 4608 4608 160000 0 4608 + 100000 5m 4608 4608 160000 0 4608 + 50000 40m 4608 4608 160000 0 4608 + 100000 40m 4608 4608 160000 0 4608 + 50000 300m 4608 4608 160000 0 4608 + 100000 300m 4608 4608 160000 0 4608 diff --git a/device/arista/x86_64-arista_7050cx3_32s/Arista-7050CX3-32S-D48C8/pg_profile_lookup.ini b/device/arista/x86_64-arista_7050cx3_32s/Arista-7050CX3-32S-D48C8/pg_profile_lookup.ini index 8ee7a6714b1e..5b4482bc74c7 100644 --- a/device/arista/x86_64-arista_7050cx3_32s/Arista-7050CX3-32S-D48C8/pg_profile_lookup.ini +++ b/device/arista/x86_64-arista_7050cx3_32s/Arista-7050CX3-32S-D48C8/pg_profile_lookup.ini @@ -1,8 +1,8 @@ # PG lossless profiles. # speed cable size xon xoff threshold xon_offset - 50000 5m 4608 4608 79872 0 4608 - 100000 5m 4608 4608 54528 0 4608 - 50000 40m 4608 4608 39936 0 4608 - 100000 40m 4608 4608 60416 0 4608 - 50000 300m 4608 4608 61440 0 4608 - 100000 300m 4608 4608 103680 0 4608 + 50000 5m 4608 4608 160000 0 4608 + 100000 5m 4608 4608 160000 0 4608 + 50000 40m 4608 4608 160000 0 4608 + 100000 40m 4608 4608 160000 0 4608 + 50000 300m 4608 4608 160000 0 4608 + 100000 300m 4608 4608 160000 0 4608 From 46292d71bee9378460ffed833867bf12ae10090b Mon Sep 17 00:00:00 2001 From: Junchao-Mellanox <57339448+Junchao-Mellanox@users.noreply.github.com> Date: Thu, 1 Sep 2022 04:09:36 +0800 Subject: [PATCH 064/151] Add linux perf tool to sonic image (#11906) --- build_debian.sh | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/build_debian.sh b/build_debian.sh index 1db8f3b91ca1..8dcd8596f684 100755 --- a/build_debian.sh +++ b/build_debian.sh @@ -385,7 +385,8 @@ sudo LANG=C DEBIAN_FRONTEND=noninteractive chroot $FILESYSTEM_ROOT apt-get -y in fdisk \ gpg \ jq \ - auditd + auditd \ + linux-perf # default rsyslog version is 8.2110.0 which has a bug on log rate limit, # use backport version From 6e878a36da87082788ee737a624ff66d99c86167 Mon Sep 17 00:00:00 2001 From: Longxiang Lyu <35479537+lolyu@users.noreply.github.com> Date: Thu, 1 Sep 2022 04:10:22 +0800 Subject: [PATCH 065/151] [mux] Exit to write `standby` state to `active-active` ports (#11821) [mux] Exit to write standby state to `active-active` ports Signed-off-by: Longxiang Lyu --- files/build_templates/mux.service.j2 | 2 +- files/scripts/write_standby.py | 8 +++++++- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/files/build_templates/mux.service.j2 b/files/build_templates/mux.service.j2 index abc04ab30d18..ee1f8ce75389 100644 --- a/files/build_templates/mux.service.j2 +++ b/files/build_templates/mux.service.j2 @@ -14,7 +14,7 @@ ExecStartPre=/usr/local/bin/mark_dhcp_packet.py ExecStartPre=/usr/bin/{{docker_container_name}}.sh start ExecStart=/usr/bin/{{docker_container_name}}.sh wait ExecStop=/usr/bin/{{docker_container_name}}.sh stop -ExecStopPost=/usr/local/bin/write_standby.py +ExecStopPost=/usr/local/bin/write_standby.py --shutdown mux Restart=always RestartSec=30 diff --git a/files/scripts/write_standby.py b/files/scripts/write_standby.py index 86d50737b1c5..85b6ee8b04e8 100755 --- a/files/scripts/write_standby.py +++ b/files/scripts/write_standby.py @@ -178,6 +178,12 @@ def apply_mux_config(self): parser.add_argument('-s', '--active_standby', help='state: intial state for "auto" and/or "manual" config in active-standby mode, default "standby"', type=str, required=False, default='standby') + parser.add_argument('--shutdown', help='write mux state after shutdown other services, supported: mux', + type=str, required=False, choices=['mux']) args = parser.parse_args() - mux_writer = MuxStateWriter(activeactive=args.active_active, activestandby=args.active_standby) + active_active_state = args.active_active + active_standby_state = args.active_standby + if args.shutdown == 'mux': + active_active_state = "standby" + mux_writer = MuxStateWriter(activeactive=active_active_state, activestandby=active_standby_state) mux_writer.apply_mux_config() From 353b2742b23f2529af9733ddca0c712c6f68a17b Mon Sep 17 00:00:00 2001 From: Jing Kan <672454911@qq.com> Date: Thu, 1 Sep 2022 07:58:16 +0800 Subject: [PATCH 066/151] [YANG] Create YANG Model for Console (#11806) How I did it Create YANG Model for SONiC console related features. How to verify it Add tests Signed-off-by: Jing Kan jika@microsoft.com --- src/sonic-yang-models/doc/Configuration.md | 24 +++++ src/sonic-yang-models/setup.py | 1 + .../tests/files/sample_config_db.json | 17 ++++ .../tests/yang_model_tests/tests/console.json | 40 +++++++++ .../tests_config/console.json | 88 +++++++++++++++++++ .../yang-models/sonic-console.yang | 76 ++++++++++++++++ 6 files changed, 246 insertions(+) create mode 100644 src/sonic-yang-models/tests/yang_model_tests/tests/console.json create mode 100644 src/sonic-yang-models/tests/yang_model_tests/tests_config/console.json create mode 100644 src/sonic-yang-models/yang-models/sonic-console.yang diff --git a/src/sonic-yang-models/doc/Configuration.md b/src/sonic-yang-models/doc/Configuration.md index 2167cab027ed..118fca806d0d 100644 --- a/src/sonic-yang-models/doc/Configuration.md +++ b/src/sonic-yang-models/doc/Configuration.md @@ -19,6 +19,7 @@ Table of Contents * [Buffer port egress profile list](#buffer-port-egress-profile-list) * [Cable length](#cable-length) * [COPP_TABLE](#copp_table) + * [Console](#console) * [CRM](#crm) * [Data Plane L3 Interfaces](#data-plane-l3-interfaces) * [DEFAULT_LOSSLESS_BUFFER_PARAMETER](#DEFAULT_LOSSLESS_BUFFER_PARAMETER) @@ -687,6 +688,29 @@ This kind of profiles will be handled by buffer manager and won't be applied to } ``` +### Console + +``` +{ +"CONSOLE_PORT": { + "1": { + "baud_rate": "115200", + "flow_control": "0", + "remote_device": "host-1" + }, + "2": { + "baud_rate": "9600", + "flow_control": "1" + } + }, +"CONSOLE_SWITCH": { + "console_mgmt": { + "enabled": "yes" + } + } +} +``` + ### CRM ``` diff --git a/src/sonic-yang-models/setup.py b/src/sonic-yang-models/setup.py index f5ff5b5fe5f2..790143053260 100644 --- a/src/sonic-yang-models/setup.py +++ b/src/sonic-yang-models/setup.py @@ -98,6 +98,7 @@ def run(self): './yang-models/sonic-buffer-queue.yang', './yang-models/sonic-cable-length.yang', './yang-models/sonic-copp.yang', + './yang-models/sonic-console.yang', './yang-models/sonic-crm.yang', './yang-models/sonic-default-lossless-buffer-parameter.yang', './yang-models/sonic-device_metadata.yang', diff --git a/src/sonic-yang-models/tests/files/sample_config_db.json b/src/sonic-yang-models/tests/files/sample_config_db.json index c7d199fa9f24..44724f00d5d6 100644 --- a/src/sonic-yang-models/tests/files/sample_config_db.json +++ b/src/sonic-yang-models/tests/files/sample_config_db.json @@ -1964,6 +1964,23 @@ "default_dynamic_th": "0", "over_subscribe_ratio": "0" } + }, + + "CONSOLE_PORT": { + "1": { + "baud_rate": "115200", + "flow_control": "0", + "remote_device": "host-1" + }, + "2": { + "baud_rate": "9600", + "flow_control": "1" + } + }, + "CONSOLE_SWITCH": { + "console_mgmt": { + "enabled": "yes" + } } }, "SAMPLE_CONFIG_DB_UNKNOWN": { diff --git a/src/sonic-yang-models/tests/yang_model_tests/tests/console.json b/src/sonic-yang-models/tests/yang_model_tests/tests/console.json new file mode 100644 index 000000000000..cd305e4a2086 --- /dev/null +++ b/src/sonic-yang-models/tests/yang_model_tests/tests/console.json @@ -0,0 +1,40 @@ +{ + "CONSOLE_DISABLED": { + "desc": "Verifying CONSOLE_SWITCH configuration." + }, + "CONSOLE_DEFAULT_CONSOLE_MGMT": { + "desc": "CONSOLE_SWITCH default value for console_mgmt enabled field.", + "eStrKey": "Verify", + "verify": { + "xpath": "/sonic-console:sonic-console/CONSOLE_SWITCH/console_mgmt/enabled", + "key": "sonic-console:enabled", + "value": "no" + } + }, + "CONSOLE_DISABLED_INCORRECT_PATTERN": { + "desc": "CONSOLE_SWITCH configuration pattern failure.", + "eStrKey": "Pattern" + }, + "CONSOLE_PORT_DEFAULT_FLOW_CONTROL": { + "desc": "CONSOLE_PORT default value for flow_control field.", + "eStrKey": "Verify", + "verify": { + "xpath": "/sonic-console:sonic-console/CONSOLE_PORT/CONSOLE_PORT_LIST[name='1']/flow_control", + "key": "sonic-console:flow_control", + "value": "0" + } + }, + "CONSOLE_PORT_INVALID_NAME": { + "desc": "CONSOLE_PORT invalid name failure.", + "eStrKey": "InvalidValue", + "eStr": ["name"] + }, + "CONSOLE_PORT_INVALID_BAUD": { + "desc": "CONSOLE_PORT invalid baud failure.", + "eStrKey": "InvalidValue", + "eStr": ["baud"] + }, + "CONSOLE_PORT_VALID": { + "desc": "Verifying CONSOLE_PORT configuration no failure." + } +} diff --git a/src/sonic-yang-models/tests/yang_model_tests/tests_config/console.json b/src/sonic-yang-models/tests/yang_model_tests/tests_config/console.json new file mode 100644 index 000000000000..1ccfb4a3ae11 --- /dev/null +++ b/src/sonic-yang-models/tests/yang_model_tests/tests_config/console.json @@ -0,0 +1,88 @@ +{ + "CONSOLE_DISABLED": { + "sonic-console:sonic-console": { + "sonic-console:CONSOLE_SWITCH": { + "sonic-console:console_mgmt": { + "enabled": "no" + } + } + } + }, + "CONSOLE_DEFAULT_CONSOLE_MGMT": { + "sonic-console:sonic-console": { + "sonic-console:CONSOLE_SWITCH": { + "sonic-console:console_mgmt": { + } + } + } + }, + "CONSOLE_DISABLED_INCORRECT_PATTERN": { + "sonic-console:sonic-console": { + "sonic-console:CONSOLE_SWITCH": { + "sonic-console:console_mgmt": { + "enabled": "false" + } + } + } + }, + "CONSOLE_PORT_DEFAULT_FLOW_CONTROL": { + "sonic-console:sonic-console": { + "sonic-console:CONSOLE_PORT": { + "CONSOLE_PORT_LIST": [ + { + "name": "1", + "baud_rate": "9600" + } + ] + } + } + }, + "CONSOLE_PORT_INVALID_NAME": { + "sonic-console:sonic-console": { + "sonic-console:CONSOLE_PORT": { + "CONSOLE_PORT_LIST": [ + { + "name": "invalid", + "baud_rate": "9600" + } + ] + } + } + }, + "CONSOLE_PORT_INVALID_BAUD": { + "sonic-console:sonic-console": { + "sonic-console:CONSOLE_PORT": { + "CONSOLE_PORT_LIST": [ + { + "name": "1", + "baud_rate": "invalid" + } + ] + } + } + }, + "CONSOLE_PORT_VALID": { + "sonic-console:sonic-console": { + "sonic-console:CONSOLE_PORT": { + "CONSOLE_PORT_LIST": [ + { + "name": "1", + "baud_rate": "9600", + "flow_control": "1", + "remote_device": "remote_host_1" + }, + { + "name": "2", + "baud_rate": "9600", + "flow_control": "0", + "remote_device": "remote_host_2" + }, + { + "name": "3", + "baud_rate": "9600" + } + ] + } + } + } +} diff --git a/src/sonic-yang-models/yang-models/sonic-console.yang b/src/sonic-yang-models/yang-models/sonic-console.yang new file mode 100644 index 000000000000..ed0af5390f49 --- /dev/null +++ b/src/sonic-yang-models/yang-models/sonic-console.yang @@ -0,0 +1,76 @@ +module sonic-console { + yang-version 1.1; + namespace "http://github.com/Azure/sonic-console"; + prefix console; + + import sonic-types { + prefix stypes; + } + + description "SONiC CONSOLE"; + + revision 2022-08-22 { + description "First Revision"; + } + + typedef console-mgmt-enabled { + description "configuration to set if console switch is enabled or not"; + type string { + pattern "yes|no"; + } + } + + typedef console-flow-control { + description "configuration to set if enable flow control on a console port"; + type string { + pattern "0|1"; + } + } + + container sonic-console { + container CONSOLE_PORT { + description "CONSOLE_PORT part of config_db.json"; + + list CONSOLE_PORT_LIST { + key "name"; + + leaf name { + description "Configure console port name"; + type uint16; + } + + leaf baud_rate { + description "Configure baud rate"; + type uint32; + } + + leaf flow_control { + description "Configure if enable/disable flow control"; + type console-flow-control; + default "0"; + } + + leaf remote_device { + description "Configure the remote device name"; + type stypes:hostname; + } + } + + } /* end of container CONSOLE_PORT */ + + container CONSOLE_SWITCH { + description "CONSOLE_SWITCH part of config_db.json"; + + container console_mgmt { + leaf enabled { + description "This configuration indicate if enable console management feature on SONiC"; + type console-mgmt-enabled; + default "no"; + } + } + + } /* end of container CONSOLE_SWITCH */ + + } /* end of top level container */ + +} /* end of module sonic-console */ From 88191b063bd40e27c1a7ce817487a2a7cc4e70aa Mon Sep 17 00:00:00 2001 From: Zhaohui Sun <94606222+ZhaohuiS@users.noreply.github.com> Date: Thu, 1 Sep 2022 08:13:24 +0800 Subject: [PATCH 067/151] Add python-is-python3 package for bullseye base docker (#11895) Why I did it In latest syncd container, it is installed bullseye, can't find command '/usr/bin/python'. Some scripts such as test_copp still calls /usr/bin/python in syncd. Submitted the change in #11807 for syncd docker, but it's better to add it in bullseye base docker. How I did it Install python-is-python3 package in bullseye base docker to resolve this issue, whatever run python or python3, it will run /usr/bin/python3, will not cause the error of can't find command '/usr/bin/python' How to verify it run python in syncd container. Signed-off-by: Zhaohui Sun --- dockers/docker-base-bullseye/Dockerfile.j2 | 1 + 1 file changed, 1 insertion(+) diff --git a/dockers/docker-base-bullseye/Dockerfile.j2 b/dockers/docker-base-bullseye/Dockerfile.j2 index d08316dbb4df..8d197d3c9011 100644 --- a/dockers/docker-base-bullseye/Dockerfile.j2 +++ b/dockers/docker-base-bullseye/Dockerfile.j2 @@ -48,6 +48,7 @@ RUN apt-get update && \ python3 \ python3-distutils \ python3-pip \ + python-is-python3 \ vim-tiny \ # Install redis-tools redis-tools \ From fdd9130ecf45b15ec8675f6afddb74895fabc276 Mon Sep 17 00:00:00 2001 From: Jing Zhang Date: Thu, 1 Sep 2022 11:52:02 -0700 Subject: [PATCH 068/151] [YANG] Add MUX_CABLE yang model (#11797) Why I did it Address issue #10970 sign-off: Jing Zhang zhangjing@microsoft.com How I did it Add sonic-mux-cable.yang and unit tests. How to verify it Compile Compile target/python-wheels/sonic_yang_mgmt-1.0-py3-none-any.whl and target/python-wheels/sonic_yang_models-1.0-py3-none-any.whl. Pass sonic-config-engine unit test. Which release branch to backport (provide reason below if selected) 201811 201911 202006 202012 202106 202111 202205 Description for the changelog Link to config_db schema for YANG module changes https://github.com/sonic-net/sonic-buildimage/blob/f8fe41a0238b8a7b9e32ae42262f41b63050c55f/src/sonic-yang-models/doc/Configuration.md#mux_cable --- src/sonic-yang-models/doc/Configuration.md | 21 ++++- src/sonic-yang-models/setup.py | 1 + .../tests/files/sample_config_db.json | 16 ++++ .../yang_model_tests/tests/mux_cable.json | 16 ++++ .../tests_config/mux_cable.json | 93 +++++++++++++++++++ .../yang-models/sonic-mux-cable.yang | 92 ++++++++++++++++++ 6 files changed, 238 insertions(+), 1 deletion(-) create mode 100644 src/sonic-yang-models/tests/yang_model_tests/tests/mux_cable.json create mode 100644 src/sonic-yang-models/tests/yang_model_tests/tests_config/mux_cable.json create mode 100644 src/sonic-yang-models/yang-models/sonic-mux-cable.yang diff --git a/src/sonic-yang-models/doc/Configuration.md b/src/sonic-yang-models/doc/Configuration.md index 118fca806d0d..bd7b51ce5ae2 100644 --- a/src/sonic-yang-models/doc/Configuration.md +++ b/src/sonic-yang-models/doc/Configuration.md @@ -35,9 +35,10 @@ Table of Contents * [Management port](#management-port) * [Management VRF](#management-vrf) * [MAP_PFC_PRIORITY_TO_QUEUE](#map_pfc_priority_to_queue) + * [MUX_CABLE](#muxcable) * [NTP Global Configuration](#ntp-global-configuration) * [NTP and SYSLOG servers](#ntp-and-syslog-servers) - * [Peer Switch](#peer-switch) + * [Peer Switch](#peer-switch) * [Policer](#policer) * [Port](#port) * [Port Channel](#port-channel) @@ -1090,6 +1091,24 @@ instead of data network. } } ``` +### MUX_CABLE + +The **MUX_CABLE** table is used for dualtor interface configuration. The `cable_type` and `soc_ipv4` objects are optional. + +``` +{ + "MUX_CABLE": { + "Ethernet4": { + "cable_type": "active-active", + "server_ipv4": "192.168.0.2/32", + "server_ipv6": "fc02:1000::30/128", + "soc_ipv4": "192.168.0.3/32", + "state": "auto" + } + } +} +``` + ### NTP Global Configuration These configuration options are used to modify the way that diff --git a/src/sonic-yang-models/setup.py b/src/sonic-yang-models/setup.py index 790143053260..975b84b68245 100644 --- a/src/sonic-yang-models/setup.py +++ b/src/sonic-yang-models/setup.py @@ -116,6 +116,7 @@ def run(self): './yang-models/sonic-mgmt_port.yang', './yang-models/sonic-mgmt_vrf.yang', './yang-models/sonic-mirror-session.yang', + './yang-models/sonic-mux-cable.yang', './yang-models/sonic-ntp.yang', './yang-models/sonic-nat.yang', './yang-models/sonic-nvgre-tunnel.yang', diff --git a/src/sonic-yang-models/tests/files/sample_config_db.json b/src/sonic-yang-models/tests/files/sample_config_db.json index 44724f00d5d6..b833fab06ddd 100644 --- a/src/sonic-yang-models/tests/files/sample_config_db.json +++ b/src/sonic-yang-models/tests/files/sample_config_db.json @@ -1804,6 +1804,22 @@ } }, + "MUX_CABLE": { + "Ethernet4": { + "cable_type": "active-active", + "server_ipv4": "192.168.0.2/32", + "server_ipv6": "fc02:1000::30/128", + "soc_ipv4": "192.168.0.3/32", + "state": "auto" + }, + "Ethernet0": { + "server_ipv4": "192.168.0.2/32", + "server_ipv6": "fc02:1000::30/128", + "state": "auto" + } + }, + + "POLICER": { "everflow_static_policer": { "meter_type": "bytes", diff --git a/src/sonic-yang-models/tests/yang_model_tests/tests/mux_cable.json b/src/sonic-yang-models/tests/yang_model_tests/tests/mux_cable.json new file mode 100644 index 000000000000..0d02097fdf63 --- /dev/null +++ b/src/sonic-yang-models/tests/yang_model_tests/tests/mux_cable.json @@ -0,0 +1,16 @@ +{ + "MUX_CABLE_ACTIVE_STANDBY_INTERFACE": { + "desc": "Load MUX_CABLE for active-standby interface." + }, + "MUX_CABLE_ACTIVE_ACTIVE_INTERFACE": { + "desc":"Load MUX_CABLE for active-active interface." + }, + "MUX_CABLE_INVALID_STATE": { + "desc": "Load MUX_CABLE with invalid state.", + "eStrKey": "InvalidValue" + }, + "MUX_CABLE_INVALID_IP": { + "desc": "Load MUX_CABLE with invalid server ip address.", + "eStrKey": "Pattern" + } +} \ No newline at end of file diff --git a/src/sonic-yang-models/tests/yang_model_tests/tests_config/mux_cable.json b/src/sonic-yang-models/tests/yang_model_tests/tests_config/mux_cable.json new file mode 100644 index 000000000000..815171306bdc --- /dev/null +++ b/src/sonic-yang-models/tests/yang_model_tests/tests_config/mux_cable.json @@ -0,0 +1,93 @@ +{ + "MUX_CABLE_ACTIVE_STANDBY_INTERFACE": { + "sonic-port:sonic-port": { + "sonic-port:PORT": { + "PORT_LIST": [ + { + "admin_status": "up", + "alias": "eth0", + "description": "Ethernet0", + "lanes": "65", + "mtu": "9000", + "name": "Ethernet0", + "tpid": "0x8100", + "speed": "25000" + } + ] + } + }, + "sonic-mux-cable:sonic-mux-cable": { + "sonic-mux-cable:MUX_CABLE": { + "MUX_CABLE_LIST": [ + { + "ifname": "Ethernet0", + "server_ipv4": "192.168.0.2/32", + "server_ipv6": "fc02:1000::30/128", + "state": "auto" + } + ] + + } + } + }, + + "MUX_CABLE_ACTIVE_ACTIVE_INTERFACE": { + "sonic-port:sonic-port": { + "sonic-port:PORT": { + "PORT_LIST": [ + { + "admin_status": "up", + "alias": "eth0", + "description": "Ethernet4", + "lanes": "65", + "mtu": "9000", + "name": "Ethernet4", + "tpid": "0x8100", + "speed": "25000" + } + ] + } + }, + "sonic-mux-cable:sonic-mux-cable": { + "sonic-mux-cable:MUX_CABLE": { + "MUX_CABLE_LIST": [ + { + "ifname": "Ethernet4", + "cable_type": "active-active", + "server_ipv4": "192.168.0.2/32", + "server_ipv6": "fc02:1000::30/128", + "soc_ipv4": "192.168.0.3/32", + "state": "auto" + } + ] + + } + } + }, + + "MUX_CABLE_INVALID_STATE": { + "sonic-mux-cable:sonic-mux-cable": { + "sonic-mux-cable:MUX_CABLE": { + "MUX_CABLE_LIST": [ + { + "state": "Standby" + } + ] + + } + } + }, + + "MUX_CABLE_INVALID_IP": { + "sonic-mux-cable:sonic-mux-cable": { + "sonic-mux-cable:MUX_CABLE": { + "MUX_CABLE_LIST": [ + { + "server_ipv4": "999.999.999.999/32" + } + ] + + } + } + } +} diff --git a/src/sonic-yang-models/yang-models/sonic-mux-cable.yang b/src/sonic-yang-models/yang-models/sonic-mux-cable.yang new file mode 100644 index 000000000000..a66a588c91da --- /dev/null +++ b/src/sonic-yang-models/yang-models/sonic-mux-cable.yang @@ -0,0 +1,92 @@ +module sonic-mux-cable { + namespace "http://github.com/Azure/sonic-mux-cable"; + prefix mux_cable; + yang-version 1.1; + + import ietf-inet-types { + prefix inet; + } + + import sonic-port { + prefix prt; + } + + organization + "SONiC"; + + contact + "SONiC"; + + description + "SONiC DualToR MUX CABLE confifuration data"; + + revision 2022-08-19 { + description + "Initial revision"; + } + + container sonic-mux-cable { + + container MUX_CABLE { + + list MUX_CABLE_LIST { + + key "ifname"; + + leaf ifname { + type leafref { + path "/prt:sonic-port/prt:PORT/prt:PORT_LIST/prt:name"; + } + description + "Reference of port on which MUX cable to be configured."; + } + + leaf cable_type { + type enumeration { + enum active-active; + enum active-standby; + } + default active-standby; + description "SONiC DualToR interface cable type."; + } + + leaf server_ipv4 { + type inet:ipv4-prefix; + + description "Server IPv4 Address."; + } + + leaf server_ipv6 { + type inet:ipv6-prefix; + + description "Server IPv6 Address."; + } + + leaf soc_ipv4 { + type inet:ipv4-prefix; + + description "SoC IPv4 address. Optional and for active-active ports only. "; + } + + leaf soc_ipv6 { + type inet:ipv6-prefix; + + description "SoC IPv6 address. Optional and for active-active ports only. "; + } + + leaf state { + type enumeration { + enum auto; + enum manual; + enum detach; + enum active; + enum standby; + } + + default auto; + description "MUX mode determining if auto failover is enabled. "; + } + } + } + } +} From f82c1fd8ae992ffd4dd9791f064f91ea499026eb Mon Sep 17 00:00:00 2001 From: arunlk-dell <83708154+arunlk-dell@users.noreply.github.com> Date: Fri, 2 Sep 2022 05:25:41 +0530 Subject: [PATCH 069/151] Z9432F kernel dependency of platform module (#11941) Why I did it Z9432F Update the kernel dependency of platform module How I did it Modified the kernel version to current latest 5.10.0-12-2 --- platform/broadcom/sonic-platform-modules-dell/debian/control | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/platform/broadcom/sonic-platform-modules-dell/debian/control b/platform/broadcom/sonic-platform-modules-dell/debian/control index 7821dbd4f21b..8e3db2f0fd7e 100644 --- a/platform/broadcom/sonic-platform-modules-dell/debian/control +++ b/platform/broadcom/sonic-platform-modules-dell/debian/control @@ -57,7 +57,7 @@ Description: kernel modules for platform devices such as fan, led, sfp Package: platform-modules-z9432f Architecture: amd64 -Depends: linux-image-5.10.0-8-2-amd64-unsigned +Depends: linux-image-5.10.0-12-2-amd64-unsigned Description: kernel modules for platform devices such as fan, led, sfp Package: platform-modules-n3248pxe From 030de9f26d8ebd09ca56d7aa5ab1ede0ec187607 Mon Sep 17 00:00:00 2001 From: Liu Shilong Date: Fri, 2 Sep 2022 14:07:48 +0800 Subject: [PATCH 070/151] [actions] Add github context env in label action. (#11926) --- .github/workflows/label.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/label.yml b/.github/workflows/label.yml index 307cbd86f871..ec04157110ae 100644 --- a/.github/workflows/label.yml +++ b/.github/workflows/label.yml @@ -23,6 +23,8 @@ jobs: runs-on: ubuntu-latest steps: - name: approve + env: + GITHUB_CONTEXT: ${{ toJson(github) }} run: | set -e echo ${{ secrets.GITHUB_TOKEN }} | gh auth login --with-token From a762b35cbca847902410de13693f0e94edcbe8ee Mon Sep 17 00:00:00 2001 From: Lawrence Lee Date: Fri, 2 Sep 2022 13:40:40 -0700 Subject: [PATCH 071/151] [arp_update]: Set failed IPv6 neighbors to incomplete (#11919) After pinging any failed IPv6 neighbor entries, set the remaining failed/incomplete entries to a permanent INCOMPLETE state. This manual setting to INCOMPLETE prevents these entries from automatically transitioning to FAILED state, and since they are now incomplete any subsequent NA messages for these neighbors is able to resolve the entry in the cache. Signed-off-by: Lawrence Lee --- files/scripts/arp_update | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/files/scripts/arp_update b/files/scripts/arp_update index df2758e187a7..5522ea46828a 100755 --- a/files/scripts/arp_update +++ b/files/scripts/arp_update @@ -78,6 +78,17 @@ while /bin/true; do eval `eval $ip6cmd` if [[ $SUBTYPE == "dualtor" ]]; then + # manually set any remaining FAILED/INCOMPLETE entries to permanently INCOMPLETE + # this prevents any remaining INCOMPLETE entries from automatically transitioning to FAILED + # once these entries are incomplete, any subsequent neighbor advertisement messages + # are able to resolve the entry + + # generates the following command for each failed or incomplete IPv6 neighbor + # ip neigh replace dev nud incomplete + neigh_replace_template="sed -e 's/^/ip neigh replace /' -e 's/,/ dev /' -e 's/$/ nud incomplete;/'" + ip_neigh_replace_cmd="ip -6 neigh show | grep -v fe80 | grep Vlan1000 | grep -E 'FAILED|INCOMPLETE' | cut -d ' ' -f 1,3 --output-delimiter=',' | $neigh_replace_template" + eval `eval $ip_neigh_replace_cmd` + # on dual ToR devices, try to resolve failed neighbor entries since # these entries will have tunnel routes installed, preventing normal # neighbor resolution (SWSS PR #2137) From a6843927d9b25ec32adf24841ff138da0d5efcbd Mon Sep 17 00:00:00 2001 From: Ying Xie Date: Fri, 2 Sep 2022 13:50:42 -0700 Subject: [PATCH 072/151] [mux] skip mux operations during warm shutdown (#11937) * [mux] skip mux operations during warm shutdown - Enhance write_standby.py script to skip actions during warm shutdown. - Expand the support to BGP service. - MuX support was added by a previous PR. - don't skip action during warm recovery Signed-off-by: Ying Xie --- .../per_namespace/bgp.service.j2 | 2 +- files/scripts/write_standby.py | 24 +++++++++++++------ 2 files changed, 18 insertions(+), 8 deletions(-) diff --git a/files/build_templates/per_namespace/bgp.service.j2 b/files/build_templates/per_namespace/bgp.service.j2 index 5ef30a164f69..0c9f01fe8b68 100644 --- a/files/build_templates/per_namespace/bgp.service.j2 +++ b/files/build_templates/per_namespace/bgp.service.j2 @@ -15,7 +15,7 @@ User={{ sonicadmin_user }} ExecStartPre=/usr/local/bin/{{docker_container_name}}.sh start{% if multi_instance == 'true' %} %i{% endif %} ExecStart=/usr/local/bin/{{docker_container_name}}.sh wait{% if multi_instance == 'true' %} %i{% endif %} ExecStop=/usr/local/bin/{{docker_container_name}}.sh stop{% if multi_instance == 'true' %} %i{% endif %} -ExecStopPost=/usr/local/bin/write_standby.py +ExecStopPost=/usr/local/bin/write_standby.py --shutdown bgp RestartSec=30 diff --git a/files/scripts/write_standby.py b/files/scripts/write_standby.py index 85b6ee8b04e8..13c5b17ea64e 100755 --- a/files/scripts/write_standby.py +++ b/files/scripts/write_standby.py @@ -20,13 +20,15 @@ class MuxStateWriter(object): Class used to write standby mux state to APP DB """ - def __init__(self, activeactive, activestandby): + def __init__(self, activeactive, activestandby, shutdown_module): self.config_db_connector = None self.appl_db_connector = None self.state_db_connector = None self.asic_db_connector = None self.default_active_active_state = activeactive self.default_active_standby_state = activestandby + self.shutdown_module = shutdown_module + self.is_shutdwon = (self.shutdown_module != None) @property def config_db(self): @@ -97,7 +99,15 @@ def is_warmrestart(self): tbl = Table(self.state_db, 'WARM_RESTART_ENABLE_TABLE') (status, value) = tbl.hget('system', 'enable') - return status and value == 'true' + if status and value == 'true': + return True + + if self.shutdown_module: + (status, value) = tbl.hget(self.shutdown_module, 'enable') + if status and value == 'true': + return True + + return False def get_all_mux_intfs_modes(self): """ @@ -153,7 +163,7 @@ def apply_mux_config(self): # If not running on a dual ToR system, take no action return - if self.is_warmrestart: + if self.is_warmrestart and self.is_shutdwon: # If in warmrestart context, take no action logger.log_warning("Skip setting mux state due to ongoing warmrestart.") return @@ -178,12 +188,12 @@ def apply_mux_config(self): parser.add_argument('-s', '--active_standby', help='state: intial state for "auto" and/or "manual" config in active-standby mode, default "standby"', type=str, required=False, default='standby') - parser.add_argument('--shutdown', help='write mux state after shutdown other services, supported: mux', - type=str, required=False, choices=['mux']) + parser.add_argument('--shutdown', help='write mux state after shutdown other services, supported: mux, bgp', + type=str, required=False, choices=['mux', 'bgp'], default=None) args = parser.parse_args() active_active_state = args.active_active active_standby_state = args.active_standby - if args.shutdown == 'mux': + if args.shutdown in ['mux', 'bgp']: active_active_state = "standby" - mux_writer = MuxStateWriter(activeactive=active_active_state, activestandby=active_standby_state) + mux_writer = MuxStateWriter(activeactive=active_active_state, activestandby=active_standby_state, shutdown_module=args.shutdown) mux_writer.apply_mux_config() From 750e1b3017f8dfafcc153c5b931b13bbf2f8e20e Mon Sep 17 00:00:00 2001 From: Ye Jianquan Date: Fri, 2 Sep 2022 15:53:54 -0700 Subject: [PATCH 073/151] Define whether a test is required by code (#11921) * Define whether a test is required by code Why I did it Define whether a test job is required before merging by code. Let the failure of multi-asic and t0-sonic don't block pr merge. The 'required' configuration can be modified by the owner in the future. How I did it Required: t1-lag, t0 Not required: multi-asic, t0-sonic How to verify it AZP itself verifies it. Signed-off-by: jianquanye@microsoft.com --- .azure-pipelines/run-test-template.yml | 3 --- azure-pipelines.yml | 15 ++++++++++----- 2 files changed, 10 insertions(+), 8 deletions(-) diff --git a/.azure-pipelines/run-test-template.yml b/.azure-pipelines/run-test-template.yml index 7ea0a982780f..2f1b3d8702d9 100644 --- a/.azure-pipelines/run-test-template.yml +++ b/.azure-pipelines/run-test-template.yml @@ -51,9 +51,6 @@ steps: rm -rf $(Build.ArtifactStagingDirectory)/* docker exec sonic-mgmt bash -c "/data/sonic-mgmt/tests/kvmtest.sh -en -T ${{ parameters.tbtype }} ${{ parameters.tbname }} ${{ parameters.dut }} ${{ parameters.section }}" displayName: "Run tests" - ${{ if eq(parameters.tbtype, 'multi-asic-t1-lag-pr') }}: - continueOnError: true - - script: | # save dut state if test fails virsh_version=$(virsh --version) diff --git a/azure-pipelines.yml b/azure-pipelines.yml index 5876080411a2..7856915f9b60 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -81,6 +81,10 @@ stages: - name: testbed_file value: vtestbed.csv +# For every test job: +# continueOnError: false means it's a required test job and will block merge if it fails +# continueOnError: true means it's an optional test job and will not block merge even though it fails(unless a required test job depends on its result) + jobs: - job: pool: sonictest @@ -133,7 +137,7 @@ stages: pool: sonictest displayName: "kvmtest-t0-part1" timeoutInMinutes: 360 - + continueOnError: true steps: - template: .azure-pipelines/run-test-template.yml parameters: @@ -147,7 +151,7 @@ stages: pool: sonictest displayName: "kvmtest-t0-part2" timeoutInMinutes: 360 - + continueOnError: true steps: - template: .azure-pipelines/run-test-template.yml parameters: @@ -165,6 +169,7 @@ stages: - t0_part1 - t0_part2 condition: always() + continueOnError: false variables: resultOfPart1: $[ dependencies.t0_part1.result ] resultOfPart2: $[ dependencies.t0_part2.result ] @@ -183,7 +188,7 @@ stages: pool: sonictest-t1-lag displayName: "kvmtest-t1-lag" timeoutInMinutes: 360 - + continueOnError: false steps: - template: .azure-pipelines/run-test-template.yml parameters: @@ -196,7 +201,7 @@ stages: pool: sonictest-sonic-t0 displayName: "kvmtest-t0-sonic" timeoutInMinutes: 360 - + continueOnError: true steps: - template: .azure-pipelines/run-test-template.yml parameters: @@ -210,7 +215,7 @@ stages: pool: sonictest-ma displayName: "kvmtest-multi-asic-t1-lag" timeoutInMinutes: 240 - + continueOnError: true steps: - template: .azure-pipelines/run-test-template.yml parameters: From e96ec5a74cf67011b17b8a65e9167d7be41b2ebb Mon Sep 17 00:00:00 2001 From: Lawrence Lee Date: Fri, 2 Sep 2022 16:06:10 -0700 Subject: [PATCH 074/151] [kernel]: Submodule update (#11947) Include following commit: - 443253f [patch]: Add accpt_untracked_na kernel param (#292) Signed-off-by: Lawrence Lee --- src/sonic-linux-kernel | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sonic-linux-kernel b/src/sonic-linux-kernel index fdd9bac78cfc..443253f637ec 160000 --- a/src/sonic-linux-kernel +++ b/src/sonic-linux-kernel @@ -1 +1 @@ -Subproject commit fdd9bac78cfc2bbe932833b38c2191b1d382ed07 +Subproject commit 443253f637ec3dccac246199977a6d65346d7878 From 71d63a7be75111539a04b4c54fdb617fbe7e0081 Mon Sep 17 00:00:00 2001 From: Renuka Manavalan <47282725+renukamanavalan@users.noreply.github.com> Date: Fri, 2 Sep 2022 21:52:24 -0700 Subject: [PATCH 075/151] New commits in swss-common: (#11954) * 651f52b (HEAD, origin/master, origin/HEAD, master) Change syslog level of Event Publish (#677) * aca253a Add routing rule table for DASH (#668) --- src/sonic-swss-common | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sonic-swss-common b/src/sonic-swss-common index 56b0f1877a02..651f52b8e511 160000 --- a/src/sonic-swss-common +++ b/src/sonic-swss-common @@ -1 +1 @@ -Subproject commit 56b0f1877a02c43b51595a2d7e6f09e1fabd3d32 +Subproject commit 651f52b8e51107112c8205d12608723357ecbe5e From 6a54bc439a980c7fc10e7a74de6472ee7731f8a5 Mon Sep 17 00:00:00 2001 From: Zain Budhwani <99770260+zbud-msft@users.noreply.github.com> Date: Sat, 3 Sep 2022 07:33:25 -0700 Subject: [PATCH 076/151] Streaming structured events implementation (#11848) With this PR in, you flap BGP and use events_tool to see the published events. With telemetry PR #111 in and corresponding submodule update done in buildimage, one could run gnmi_cli to capture BGP flap events. --- dockers/docker-eventd/Dockerfile.j2 | 36 + dockers/docker-eventd/critical_processes | 1 + dockers/docker-eventd/start.sh | 6 + dockers/docker-eventd/supervisord.conf | 52 + dockers/docker-fpm-frr/Dockerfile.j2 | 6 + dockers/docker-fpm-frr/bgp_regex.json | 8 + dockers/docker-fpm-frr/events_info.json | 10 + files/build_templates/docker_image_ctl.j2 | 1 + files/build_templates/eventd.service.j2 | 17 + files/build_templates/init_cfg.json.j2 | 3 +- files/build_templates/rsyslog_plugin.conf.j2 | 19 + .../build_templates/sonic_debian_extension.j2 | 4 + rules/docker-config-engine-bullseye.mk | 4 +- rules/docker-config-engine-buster.mk | 1 + rules/docker-eventd.dep | 11 + rules/docker-eventd.mk | 47 + rules/eventd.dep | 10 + rules/eventd.mk | 19 + rules/scripts.mk | 4 + rules/telemetry.mk | 5 +- slave.mk | 2 + src/sonic-eventd/Makefile | 84 ++ src/sonic-eventd/debian/changelog | 5 + src/sonic-eventd/debian/compat | 1 + src/sonic-eventd/debian/control | 14 + src/sonic-eventd/debian/rules | 6 + src/sonic-eventd/rsyslog_plugin/main.cpp | 57 ++ .../rsyslog_plugin/rsyslog_plugin.cpp | 135 +++ .../rsyslog_plugin/rsyslog_plugin.h | 40 + src/sonic-eventd/rsyslog_plugin/subdir.mk | 13 + .../rsyslog_plugin/syslog_parser.cpp | 65 ++ .../rsyslog_plugin/syslog_parser.h | 46 + .../rsyslog_plugin/timestamp_formatter.cpp | 74 ++ .../rsyslog_plugin/timestamp_formatter.h | 27 + .../rsyslog_plugin_ut.cpp | 274 ++++++ .../rsyslog_plugin_tests/subdir.mk | 12 + .../rsyslog_plugin_tests/test_regex_1.rc.json | 0 .../rsyslog_plugin_tests/test_regex_2.rc.json | 7 + .../rsyslog_plugin_tests/test_regex_3.rc.json | 6 + .../rsyslog_plugin_tests/test_regex_4.rc.json | 7 + .../rsyslog_plugin_tests/test_regex_5.rc.json | 7 + .../rsyslog_plugin_tests/test_syslogs.txt | 4 + .../rsyslog_plugin_tests/test_syslogs_2.txt | 3 + src/sonic-eventd/src/eventd.cpp | 798 +++++++++++++++ src/sonic-eventd/src/eventd.h | 268 +++++ src/sonic-eventd/src/main.cpp | 18 + src/sonic-eventd/src/subdir.mk | 13 + src/sonic-eventd/tests/eventd_ut.cpp | 915 ++++++++++++++++++ src/sonic-eventd/tests/main.cpp | 97 ++ .../database_config.json | 112 +++ .../database_config0.json | 92 ++ .../database_config1.json | 92 ++ .../database_global.json | 16 + src/sonic-eventd/tests/subdir.mk | 12 + src/sonic-eventd/tools/events_publish_tool.py | 97 ++ src/sonic-eventd/tools/events_tool.cpp | 328 +++++++ src/sonic-eventd/tools/events_volume_test.py | 68 ++ src/sonic-eventd/tools/sample_ip.json | 1 + src/sonic-eventd/tools/subdir.mk | 12 + 59 files changed, 4088 insertions(+), 4 deletions(-) create mode 100644 dockers/docker-eventd/Dockerfile.j2 create mode 100644 dockers/docker-eventd/critical_processes create mode 100755 dockers/docker-eventd/start.sh create mode 100644 dockers/docker-eventd/supervisord.conf create mode 100644 dockers/docker-fpm-frr/bgp_regex.json create mode 100644 dockers/docker-fpm-frr/events_info.json create mode 100644 files/build_templates/eventd.service.j2 create mode 100644 files/build_templates/rsyslog_plugin.conf.j2 create mode 100644 rules/docker-eventd.dep create mode 100644 rules/docker-eventd.mk create mode 100644 rules/eventd.dep create mode 100644 rules/eventd.mk create mode 100644 src/sonic-eventd/Makefile create mode 100644 src/sonic-eventd/debian/changelog create mode 100644 src/sonic-eventd/debian/compat create mode 100644 src/sonic-eventd/debian/control create mode 100755 src/sonic-eventd/debian/rules create mode 100644 src/sonic-eventd/rsyslog_plugin/main.cpp create mode 100644 src/sonic-eventd/rsyslog_plugin/rsyslog_plugin.cpp create mode 100644 src/sonic-eventd/rsyslog_plugin/rsyslog_plugin.h create mode 100644 src/sonic-eventd/rsyslog_plugin/subdir.mk create mode 100644 src/sonic-eventd/rsyslog_plugin/syslog_parser.cpp create mode 100644 src/sonic-eventd/rsyslog_plugin/syslog_parser.h create mode 100644 src/sonic-eventd/rsyslog_plugin/timestamp_formatter.cpp create mode 100644 src/sonic-eventd/rsyslog_plugin/timestamp_formatter.h create mode 100644 src/sonic-eventd/rsyslog_plugin_tests/rsyslog_plugin_ut.cpp create mode 100644 src/sonic-eventd/rsyslog_plugin_tests/subdir.mk create mode 100644 src/sonic-eventd/rsyslog_plugin_tests/test_regex_1.rc.json create mode 100644 src/sonic-eventd/rsyslog_plugin_tests/test_regex_2.rc.json create mode 100644 src/sonic-eventd/rsyslog_plugin_tests/test_regex_3.rc.json create mode 100644 src/sonic-eventd/rsyslog_plugin_tests/test_regex_4.rc.json create mode 100644 src/sonic-eventd/rsyslog_plugin_tests/test_regex_5.rc.json create mode 100644 src/sonic-eventd/rsyslog_plugin_tests/test_syslogs.txt create mode 100644 src/sonic-eventd/rsyslog_plugin_tests/test_syslogs_2.txt create mode 100644 src/sonic-eventd/src/eventd.cpp create mode 100644 src/sonic-eventd/src/eventd.h create mode 100644 src/sonic-eventd/src/main.cpp create mode 100644 src/sonic-eventd/src/subdir.mk create mode 100644 src/sonic-eventd/tests/eventd_ut.cpp create mode 100644 src/sonic-eventd/tests/main.cpp create mode 100644 src/sonic-eventd/tests/redis_multi_db_ut_config/database_config.json create mode 100644 src/sonic-eventd/tests/redis_multi_db_ut_config/database_config0.json create mode 100644 src/sonic-eventd/tests/redis_multi_db_ut_config/database_config1.json create mode 100644 src/sonic-eventd/tests/redis_multi_db_ut_config/database_global.json create mode 100644 src/sonic-eventd/tests/subdir.mk create mode 100644 src/sonic-eventd/tools/events_publish_tool.py create mode 100644 src/sonic-eventd/tools/events_tool.cpp create mode 100644 src/sonic-eventd/tools/events_volume_test.py create mode 100644 src/sonic-eventd/tools/sample_ip.json create mode 100644 src/sonic-eventd/tools/subdir.mk diff --git a/dockers/docker-eventd/Dockerfile.j2 b/dockers/docker-eventd/Dockerfile.j2 new file mode 100644 index 000000000000..8d935dc9f365 --- /dev/null +++ b/dockers/docker-eventd/Dockerfile.j2 @@ -0,0 +1,36 @@ +{% from "dockers/dockerfile-macros.j2" import install_debian_packages, install_python_wheels, copy_files %} +FROM docker-config-engine-bullseye-{{DOCKER_USERNAME}}:{{DOCKER_USERTAG}} + +ARG docker_container_name +ARG image_version +RUN [ -f /etc/rsyslog.conf ] && sed -ri "s/%syslogtag%/$docker_container_name#%syslogtag%/;" /etc/rsyslog.conf + +# Make apt-get non-interactive +ENV DEBIAN_FRONTEND=noninteractive + +# Pass the image_version to container +ENV IMAGE_VERSION=$image_version + +# Update apt's cache of available packages +RUN apt-get update + +{% if docker_eventd_debs.strip() -%} +# Copy built Debian packages +{{ copy_files("debs/", docker_eventd_debs.split(' '), "/debs/") }} + +# Install built Debian packages and implicitly install their dependencies +{{ install_debian_packages(docker_eventd_debs.split(' ')) }} +{%- endif %} + +# Clean up +RUN apt-get clean -y && \ + apt-get autoclean -y && \ + apt-get autoremove -y && \ + rm -rf /debs + +COPY ["start.sh", "/usr/bin/"] +COPY ["supervisord.conf", "/etc/supervisor/conf.d/"] +COPY ["files/supervisor-proc-exit-listener", "/usr/bin"] +COPY ["critical_processes", "/etc/supervisor"] + +ENTRYPOINT ["/usr/local/bin/supervisord"] diff --git a/dockers/docker-eventd/critical_processes b/dockers/docker-eventd/critical_processes new file mode 100644 index 000000000000..8ff28edbc148 --- /dev/null +++ b/dockers/docker-eventd/critical_processes @@ -0,0 +1 @@ +program:eventd diff --git a/dockers/docker-eventd/start.sh b/dockers/docker-eventd/start.sh new file mode 100755 index 000000000000..60cd6a00aecb --- /dev/null +++ b/dockers/docker-eventd/start.sh @@ -0,0 +1,6 @@ +#!/usr/bin/env bash + +if [ "${RUNTIME_OWNER}" == "" ]; then + RUNTIME_OWNER="kube" +fi + diff --git a/dockers/docker-eventd/supervisord.conf b/dockers/docker-eventd/supervisord.conf new file mode 100644 index 000000000000..5d9a50bca2ae --- /dev/null +++ b/dockers/docker-eventd/supervisord.conf @@ -0,0 +1,52 @@ +[supervisord] +logfile_maxbytes=1MB +logfile_backups=2 +nodaemon=true + +[eventlistener:dependent-startup] +command=python3 -m supervisord_dependent_startup +autostart=true +autorestart=unexpected +startretries=0 +exitcodes=0,3 +events=PROCESS_STATE +buffer_size=1024 + +[eventlistener:supervisor-proc-exit-listener] +command=/usr/bin/supervisor-proc-exit-listener --container-name eventd +events=PROCESS_STATE_EXITED,PROCESS_STATE_RUNNING +autostart=true +autorestart=unexpected +buffer_size=1024 + +[program:rsyslogd] +command=/usr/sbin/rsyslogd -n -iNONE +priority=1 +autostart=false +autorestart=unexpected +stdout_logfile=syslog +stderr_logfile=syslog +dependent_startup=true + +[program:start] +command=/usr/bin/start.sh +priority=2 +autostart=false +autorestart=false +startsecs=0 +stdout_logfile=syslog +stderr_logfile=syslog +dependent_startup=true +dependent_startup_wait_for=rsyslogd:running + + +[program:eventd] +command=/usr/sbin/eventd +priority=3 +autostart=false +autorestart=false +stdout_logfile=syslog +stderr_logfile=syslog +dependent_startup=true +dependent_startup_wait_for=start:exited + diff --git a/dockers/docker-fpm-frr/Dockerfile.j2 b/dockers/docker-fpm-frr/Dockerfile.j2 index ad665e71ceae..fd7ad0f08ed4 100644 --- a/dockers/docker-fpm-frr/Dockerfile.j2 +++ b/dockers/docker-fpm-frr/Dockerfile.j2 @@ -55,9 +55,15 @@ COPY ["TSC", "/usr/bin/TSC"] COPY ["TS", "/usr/bin/TS"] COPY ["files/supervisor-proc-exit-listener", "/usr/bin"] COPY ["zsocket.sh", "/usr/bin/"] +COPY ["*.json", "/etc/rsyslog.d/"] +COPY ["files/rsyslog_plugin.conf.j2", "/etc/rsyslog.d/"] RUN chmod a+x /usr/bin/TSA && \ chmod a+x /usr/bin/TSB && \ chmod a+x /usr/bin/TSC && \ chmod a+x /usr/bin/zsocket.sh +RUN j2 -f json /etc/rsyslog.d/rsyslog_plugin.conf.j2 /etc/rsyslog.d/events_info.json > /etc/rsyslog.d/bgp_events.conf +RUN rm -f /etc/rsyslog.d/rsyslog_plugin.conf.j2* +RUN rm -f /etc/rsyslog.d/events_info.json* + ENTRYPOINT ["/usr/bin/docker_init.sh"] diff --git a/dockers/docker-fpm-frr/bgp_regex.json b/dockers/docker-fpm-frr/bgp_regex.json new file mode 100644 index 000000000000..898b5b060ebe --- /dev/null +++ b/dockers/docker-fpm-frr/bgp_regex.json @@ -0,0 +1,8 @@ +[ + { + "tag": "bgp-state", + "regex": "Peer .default\\|([0-9a-f:.]*[0-9a-f]*). admin state is set to .(up|down).", + "params": [ "ip", "status" ] + } +] + diff --git a/dockers/docker-fpm-frr/events_info.json b/dockers/docker-fpm-frr/events_info.json new file mode 100644 index 000000000000..66fa9a727ae2 --- /dev/null +++ b/dockers/docker-fpm-frr/events_info.json @@ -0,0 +1,10 @@ +{ + "yang_module": "sonic-events-bgp", + "proclist": [ + { + "name": "bgp", + "parse_json": "bgp_regex.json" + } + ] +} + diff --git a/files/build_templates/docker_image_ctl.j2 b/files/build_templates/docker_image_ctl.j2 index 99051ee62d8c..a77706cad497 100644 --- a/files/build_templates/docker_image_ctl.j2 +++ b/files/build_templates/docker_image_ctl.j2 @@ -515,6 +515,7 @@ start() { {%- endif -%} {%- if docker_container_name == "bgp" %} -v /etc/sonic/frr/$DEV:/etc/frr:rw \ + -v /usr/share/sonic/scripts:/usr/share/sonic/scripts:ro \ {%- endif %} {%- if docker_container_name == "database" %} $DB_OPT \ diff --git a/files/build_templates/eventd.service.j2 b/files/build_templates/eventd.service.j2 new file mode 100644 index 000000000000..0ad7f52ee83d --- /dev/null +++ b/files/build_templates/eventd.service.j2 @@ -0,0 +1,17 @@ +[Unit] +Description=EVENTD container +Requires=updategraph.service +After=updategraph.service +BindsTo=sonic.target +After=sonic.target +StartLimitIntervalSec=1200 +StartLimitBurst=3 + +[Service] +ExecStartPre=/usr/bin/{{docker_container_name}}.sh start +ExecStart=/usr/bin/{{docker_container_name}}.sh wait +ExecStop=/usr/bin/{{docker_container_name}}.sh stop +RestartSec=30 + +[Install] +WantedBy=sonic.target diff --git a/files/build_templates/init_cfg.json.j2 b/files/build_templates/init_cfg.json.j2 index 7de0ad977807..8e92807f4e2c 100644 --- a/files/build_templates/init_cfg.json.j2 +++ b/files/build_templates/init_cfg.json.j2 @@ -39,6 +39,7 @@ ("pmon", "enabled", false, "enabled"), ("radv", "enabled", false, "enabled"), ("snmp", "enabled", true, "enabled"), + ("eventd", "enabled", true, "enabled"), ("swss", "enabled", false, "enabled"), ("syncd", "enabled", false, "enabled"), ("teamd", "enabled", false, "enabled")] %} @@ -69,7 +70,7 @@ "check_up_status" : "false", {%- endif %} {%- if include_kubernetes == "y" %} -{%- if feature in ["lldp", "pmon", "radv", "snmp", "telemetry"] %} +{%- if feature in ["lldp", "pmon", "radv", "eventd", "snmp", "telemetry"] %} "set_owner": "kube", {% else %} "set_owner": "local", {% endif %} {% endif %} "high_mem_alert": "disabled" diff --git a/files/build_templates/rsyslog_plugin.conf.j2 b/files/build_templates/rsyslog_plugin.conf.j2 new file mode 100644 index 000000000000..ec19c62a78f6 --- /dev/null +++ b/files/build_templates/rsyslog_plugin.conf.j2 @@ -0,0 +1,19 @@ +## rsyslog-plugin for streaming telemetry via gnmi + + + +template(name="prog_msg" type="list") { + property(name="msg") + constant(value="\n") +} + +$ModLoad omprog + +{% for proc in proclist %} +if re_match($programname, "{{ proc.name }}") then { + action(type="omprog" + binary="/usr/share/sonic/scripts/rsyslog_plugin -r /etc/rsyslog.d/{{ proc.parse_json }} -m {{ yang_module }}" + output="/var/log/rsyslog_plugin.log" + template="prog_msg") +} +{% endfor %} diff --git a/files/build_templates/sonic_debian_extension.j2 b/files/build_templates/sonic_debian_extension.j2 index 4b7a77b3151c..56b8290cc12e 100644 --- a/files/build_templates/sonic_debian_extension.j2 +++ b/files/build_templates/sonic_debian_extension.j2 @@ -799,6 +799,10 @@ sudo bash -c "echo { > $FILESYSTEM_ROOT_USR_SHARE_SONIC_TEMPLATES/ctr_image_name {% endfor %} sudo bash -c "echo } >> $FILESYSTEM_ROOT_USR_SHARE_SONIC_TEMPLATES/ctr_image_names.json" +# copy rsyslog plugin binary for use by all dockers that use plugin to publish events. +sudo mkdir -p ${FILESYSTEM_ROOT_USR_SHARE_SONIC_SCRIPTS} +sudo cp ${files_path}/rsyslog_plugin ${FILESYSTEM_ROOT_USR_SHARE_SONIC_SCRIPTS}/ + {% for script in installer_start_scripts.split(' ') -%} if [ -f $TARGET_MACHINE"_{{script}}" ]; then sudo cp $TARGET_MACHINE"_{{script}}" $FILESYSTEM_ROOT/usr/bin/{{script}} diff --git a/rules/docker-config-engine-bullseye.mk b/rules/docker-config-engine-bullseye.mk index c125aa65b209..ea0ae43b54b9 100644 --- a/rules/docker-config-engine-bullseye.mk +++ b/rules/docker-config-engine-bullseye.mk @@ -8,13 +8,15 @@ $(DOCKER_CONFIG_ENGINE_BULLSEYE)_DEPENDS += $(LIBSWSSCOMMON) \ $(LIBYANG_CPP) \ $(LIBYANG_PY3) \ $(PYTHON3_SWSSCOMMON) \ - $(SONIC_DB_CLI) + $(SONIC_DB_CLI) \ + $(SONIC_EVENTD) $(DOCKER_CONFIG_ENGINE_BULLSEYE)_PYTHON_WHEELS += $(SONIC_PY_COMMON_PY3) \ $(SONIC_YANG_MGMT_PY3) \ $(SONIC_YANG_MODELS_PY3) $(DOCKER_CONFIG_ENGINE_BULLSEYE)_PYTHON_WHEELS += $(SONIC_CONFIG_ENGINE_PY3) $(DOCKER_CONFIG_ENGINE_BULLSEYE)_LOAD_DOCKERS += $(DOCKER_BASE_BULLSEYE) $(DOCKER_CONFIG_ENGINE_BULLSEYE)_FILES += $(SWSS_VARS_TEMPLATE) +$(DOCKER_CONFIG_ENGINE_BULLSEYE)_FILES += $(RSYSLOG_PLUGIN_CONF_J2) $(DOCKER_CONFIG_ENGINE_BULLSEYE)_FILES += $($(SONIC_CTRMGRD)_CONTAINER_SCRIPT) $(DOCKER_CONFIG_ENGINE_BULLSEYE)_DBG_DEPENDS = $($(DOCKER_BASE_BULLSEYE)_DBG_DEPENDS) \ diff --git a/rules/docker-config-engine-buster.mk b/rules/docker-config-engine-buster.mk index ae5589a59595..38a94bae4c1d 100644 --- a/rules/docker-config-engine-buster.mk +++ b/rules/docker-config-engine-buster.mk @@ -15,6 +15,7 @@ $(DOCKER_CONFIG_ENGINE_BUSTER)_PYTHON_WHEELS += $(SONIC_PY_COMMON_PY3) \ $(DOCKER_CONFIG_ENGINE_BUSTER)_PYTHON_WHEELS += $(SONIC_CONFIG_ENGINE_PY3) $(DOCKER_CONFIG_ENGINE_BUSTER)_LOAD_DOCKERS += $(DOCKER_BASE_BUSTER) $(DOCKER_CONFIG_ENGINE_BUSTER)_FILES += $(SWSS_VARS_TEMPLATE) +$(DOCKER_CONFIG_ENGINE_BUSTER)_FILES += $(RSYSLOG_PLUGIN_CONF_J2) $(DOCKER_CONFIG_ENGINE_BUSTER)_FILES += $($(SONIC_CTRMGRD)_CONTAINER_SCRIPT) $(DOCKER_CONFIG_ENGINE_BUSTER)_DBG_DEPENDS = $($(DOCKER_BASE_BUSTER)_DBG_DEPENDS) \ diff --git a/rules/docker-eventd.dep b/rules/docker-eventd.dep new file mode 100644 index 000000000000..382513e5eb82 --- /dev/null +++ b/rules/docker-eventd.dep @@ -0,0 +1,11 @@ + +DPATH := $($(DOCKER_EVENTD)_PATH) +DEP_FILES := $(SONIC_COMMON_FILES_LIST) rules/docker-eventd.mk rules/docker-eventd.dep +DEP_FILES += $(SONIC_COMMON_BASE_FILES_LIST) +DEP_FILES += $(shell git ls-files $(DPATH)) + +$(DOCKER_EVENTD)_CACHE_MODE := GIT_CONTENT_SHA +$(DOCKER_EVENTD)_DEP_FLAGS := $(SONIC_COMMON_FLAGS_LIST) +$(DOCKER_EVENTD)_DEP_FILES := $(DEP_FILES) + +$(eval $(call add_dbg_docker,$(DOCKER_EVENTD),$(DOCKER_EVENTD_DBG))) diff --git a/rules/docker-eventd.mk b/rules/docker-eventd.mk new file mode 100644 index 000000000000..c69fee09e569 --- /dev/null +++ b/rules/docker-eventd.mk @@ -0,0 +1,47 @@ +# docker image for eventd + +DOCKER_EVENTD_STEM = docker-eventd +DOCKER_EVENTD = $(DOCKER_EVENTD_STEM).gz +DOCKER_EVENTD_DBG = $(DOCKER_EVENTD_STEM)-$(DBG_IMAGE_MARK).gz + +$(DOCKER_EVENTD)_DEPENDS += $(SONIC_EVENTD) + +$(DOCKER_EVENTD)_DBG_DEPENDS = $($(DOCKER_CONFIG_ENGINE_BULLSEYE)_DBG_DEPENDS) +$(DOCKER_EVENTD)_DBG_DEPENDS += $(SONIC_EVENTD_DBG) $(LIBSWSSCOMMON_DBG) + +$(DOCKER_EVENTD)_DBG_IMAGE_PACKAGES = $($(DOCKER_CONFIG_ENGINE_BULLSEYE)_DBG_IMAGE_PACKAGES) + +$(DOCKER_EVENTD)_LOAD_DOCKERS = $(DOCKER_CONFIG_ENGINE_BULLSEYE) + +$(DOCKER_EVENTD)_PATH = $(DOCKERS_PATH)/$(DOCKER_EVENTD_STEM) + +$(DOCKER_EVENTD)_INSTALL_PYTHON_WHEELS = $(SONIC_UTILITIES_PY3) +$(DOCKER_EVENTD)_INSTALL_DEBS = $(PYTHON3_SWSSCOMMON) + +$(DOCKER_EVENTD)_VERSION = 1.0.0 +$(DOCKER_EVENTD)_PACKAGE_NAME = eventd + +$(DOCKER_DHCP)_SERVICE_REQUIRES = updategraph +$(DOCKER_DHCP)_SERVICE_AFTER = database + +SONIC_DOCKER_IMAGES += $(DOCKER_EVENTD) +SONIC_INSTALL_DOCKER_IMAGES += $(DOCKER_EVENTD) + +SONIC_DOCKER_DBG_IMAGES += $(DOCKER_EVENTD_DBG) +SONIC_INSTALL_DOCKER_DBG_IMAGES += $(DOCKER_EVENTD_DBG) + +$(DOCKER_EVENTD)_CONTAINER_NAME = eventd +$(DOCKER_EVENTD)_RUN_OPT += --privileged -t +$(DOCKER_EVENTD)_RUN_OPT += -v /etc/sonic:/etc/sonic:ro + +SONIC_BULLSEYE_DOCKERS += $(DOCKER_EVENTD) +SONIC_BULLSEYE_DBG_DOCKERS += $(DOCKER_EVENTD_DBG) + +$(DOCKER_EVENTD)_FILESPATH = $($(SONIC_EVENTD)_SRC_PATH)/rsyslog_plugin + +$(DOCKER_EVENTD)_PLUGIN = rsyslog_plugin +$($(DOCKER_EVENTD)_PLUGIN)_PATH = $($(DOCKER_EVENTD)_FILESPATH) + +SONIC_COPY_FILES += $($(DOCKER_EVENTD)_PLUGIN) +$(DOCKER_EVENTD)_SHARED_FILES = $($(DOCKER_EVENTD)_PLUGIN) + diff --git a/rules/eventd.dep b/rules/eventd.dep new file mode 100644 index 000000000000..12f32a30f2c7 --- /dev/null +++ b/rules/eventd.dep @@ -0,0 +1,10 @@ + +SPATH := $($(SONIC_EVENTD)_SRC_PATH) +DEP_FILES := $(SONIC_COMMON_FILES_LIST) rules/eventd.mk rules/eventd.dep +DEP_FILES += $(SONIC_COMMON_BASE_FILES_LIST) +DEP_FILES := $(addprefix $(SPATH)/,$(shell cd $(SPATH) && git ls-files)) + +$(SONIC_EVENTD)_CACHE_MODE := GIT_CONTENT_SHA +$(SONIC_EVENTD)_DEP_FLAGS := $(SONIC_COMMON_FLAGS_LIST) +$(SONIC_EVENTD)_DEP_FILES := $(DEP_FILES) + diff --git a/rules/eventd.mk b/rules/eventd.mk new file mode 100644 index 000000000000..9eea21a4cfb5 --- /dev/null +++ b/rules/eventd.mk @@ -0,0 +1,19 @@ +# eventd package + +SONIC_EVENTD_VERSION = 1.0.0-0 +SONIC_EVENTD_PKG_NAME = eventd + +SONIC_EVENTD = sonic-$(SONIC_EVENTD_PKG_NAME)_$(SONIC_EVENTD_VERSION)_$(CONFIGURED_ARCH).deb +$(SONIC_EVENTD)_SRC_PATH = $(SRC_PATH)/sonic-eventd +$(SONIC_EVENTD)_DEPENDS += $(LIBSWSSCOMMON) $(LIBSWSSCOMMON_DEV) + +SONIC_DPKG_DEBS += $(SONIC_EVENTD) + +SONIC_EVENTD_DBG = sonic-$(SONIC_EVENTD_PKG_NAME)-dbgsym_$(SONIC_EVENTD_VERSION)_$(CONFIGURED_ARCH).deb +$(eval $(call add_derived_package,$(SONIC_EVENTD),$(SONIC_EVENTD_DBG))) + +# The .c, .cpp, .h & .hpp files under src/{$DBG_SRC_ARCHIVE list} +# are archived into debug one image to facilitate debugging. +# +DBG_SRC_ARCHIVE += sonic-eventd + diff --git a/rules/scripts.mk b/rules/scripts.mk index ce6a8eb90025..12919d520b09 100644 --- a/rules/scripts.mk +++ b/rules/scripts.mk @@ -32,6 +32,9 @@ $(SWSS_VARS_TEMPLATE)_PATH = files/build_templates COPP_CONFIG_TEMPLATE = copp_cfg.j2 $(COPP_CONFIG_TEMPLATE)_PATH = files/image_config/copp +RSYSLOG_PLUGIN_CONF_J2 = rsyslog_plugin.conf.j2 +$(RSYSLOG_PLUGIN_CONF_J2)_PATH = files/build_templates + SONIC_COPY_FILES += $(CONFIGDB_LOAD_SCRIPT) \ $(ARP_UPDATE_SCRIPT) \ $(ARP_UPDATE_VARS_TEMPLATE) \ @@ -42,4 +45,5 @@ SONIC_COPY_FILES += $(CONFIGDB_LOAD_SCRIPT) \ $(SYSCTL_NET_CONFIG) \ $(UPDATE_CHASSISDB_CONFIG_SCRIPT) \ $(SWSS_VARS_TEMPLATE) \ + $(RSYSLOG_PLUGIN_CONF_J2) \ $(COPP_CONFIG_TEMPLATE) diff --git a/rules/telemetry.mk b/rules/telemetry.mk index 24fe4ae2fe52..942e9797726a 100644 --- a/rules/telemetry.mk +++ b/rules/telemetry.mk @@ -2,6 +2,7 @@ SONIC_TELEMETRY = sonic-gnmi_0.1_$(CONFIGURED_ARCH).deb $(SONIC_TELEMETRY)_SRC_PATH = $(SRC_PATH)/sonic-gnmi -$(SONIC_TELEMETRY)_DEPENDS = $(SONIC_MGMT_COMMON) $(SONIC_MGMT_COMMON_CODEGEN) -$(SONIC_TELEMETRY)_RDEPENDS = +$(SONIC_TELEMETRY)_DEPENDS = $(SONIC_MGMT_COMMON) $(SONIC_MGMT_COMMON_CODEGEN) \ + $(LIBSWSSCOMMON_DEV) $(LIBSWSSCOMMON) +$(SONIC_TELEMETRY)_RDEPENDS = $(LIBSWSSCOMMON) $(LIBSWSSCOMMON_DEV) SONIC_DPKG_DEBS += $(SONIC_TELEMETRY) diff --git a/slave.mk b/slave.mk index 7cdee954ad73..f720061b2e52 100644 --- a/slave.mk +++ b/slave.mk @@ -1292,6 +1292,8 @@ $(addprefix $(TARGET_PATH)/, $(SONIC_INSTALLERS)) : $(TARGET_PATH)/% : \ $(if $($(docker:-dbg.gz=.gz)_MACHINE),\ mv $($(docker:-dbg.gz=.gz)_CONTAINER_NAME).sh $($(docker:-dbg.gz=.gz)_MACHINE)_$($(docker:-dbg.gz=.gz)_CONTAINER_NAME).sh ) + $(foreach file, $($(docker)_SHARED_FILES), \ + { cp $($(file)_PATH)/$(file) $(FILES_PATH)/ $(LOG) || exit 1 ; } ; ) ) # Exported variables are used by sonic_debian_extension.sh diff --git a/src/sonic-eventd/Makefile b/src/sonic-eventd/Makefile new file mode 100644 index 000000000000..00d3199a65bc --- /dev/null +++ b/src/sonic-eventd/Makefile @@ -0,0 +1,84 @@ +RM := rm -rf +EVENTD_TARGET := eventd +EVENTD_TEST := tests/tests +EVENTD_TOOL := tools/events_tool +EVENTD_PUBLISH_TOOL := tools/events_publish_tool.py +RSYSLOG-PLUGIN_TARGET := rsyslog_plugin/rsyslog_plugin +RSYSLOG-PLUGIN_TEST := rsyslog_plugin_tests/tests +CP := cp +MKDIR := mkdir +CC := g++ +LIBS := -levent -lhiredis -lswsscommon -lpthread -lboost_thread -lboost_system -lzmq -lboost_serialization -luuid -llua5.1 +TEST_LIBS := -L/usr/src/gtest -lgtest -lgtest_main -lgmock -lgmock_main + +CFLAGS += -Wall -std=c++17 -fPIE -I$(PWD)/../sonic-swss-common/common +PWD := $(shell pwd) + +ifneq ($(MAKECMDGOALS),clean) +ifneq ($(strip $(C_DEPS)),) +-include $(C_DEPS) $(OBJS) +endif +endif + +-include src/subdir.mk +-include tests/subdir.mk +-include tools/subdir.mk +-include rsyslog_plugin/subdir.mk +-include rsyslog_plugin_tests/subdir.mk + +all: sonic-eventd eventd-tests eventd-tool rsyslog-plugin rsyslog-plugin-tests + +sonic-eventd: $(OBJS) + @echo 'Building target: $@' + @echo 'Invoking: G++ Linker' + $(CC) $(LDFLAGS) -o $(EVENTD_TARGET) $(OBJS) $(LIBS) + @echo 'Finished building target: $@' + @echo ' ' + +eventd-tool: $(TOOL_OBJS) + @echo 'Building target: $@' + @echo 'Invoking: G++ Linker' + $(CC) $(LDFLAGS) -o $(EVENTD_TOOL) $(TOOL_OBJS) $(LIBS) + @echo 'Finished building target: $@' + @echo ' ' + +rsyslog-plugin: $(RSYSLOG-PLUGIN_OBJS) + @echo 'Buidling Target: $@' + @echo 'Invoking: G++ Linker' + $(CC) $(LDFLAGS) -o $(RSYSLOG-PLUGIN_TARGET) $(RSYSLOG-PLUGIN_OBJS) $(LIBS) + @echo 'Finished building target: $@' + @echo ' ' + +eventd-tests: $(TEST_OBJS) + @echo 'Building target: $@' + @echo 'Invoking: G++ Linker' + $(CC) $(LDFLAGS) -o $(EVENTD_TEST) $(TEST_OBJS) $(LIBS) $(TEST_LIBS) + @echo 'Finished building target: $@' + $(EVENTD_TEST) + @echo 'Finished running tests' + @echo ' ' + +rsyslog-plugin-tests: $(RSYSLOG-PLUGIN-TEST_OBJS) + @echo 'BUILDING target: $@' + @echo 'Invoking G++ Linker' + $(CC) $(LDFLAGS) -o $(RSYSLOG-PLUGIN_TEST) $(RSYSLOG-PLUGIN-TEST_OBJS) $(LIBS) $(TEST_LIBS) + @echo 'Finished building target: $@' + $(RSYSLOG-PLUGIN_TEST) + @echo 'Finished running tests' + @echo ' ' + +install: + $(MKDIR) -p $(DESTDIR)/usr/sbin + $(CP) $(EVENTD_TARGET) $(DESTDIR)/usr/sbin + $(CP) $(EVENTD_TOOL) $(DESTDIR)/usr/sbin + $(CP) $(EVENTD_PUBLISH_TOOL) $(DESTDIR)/usr/sbin + +deinstall: + $(RM) $(DESTDIR)/usr/sbin/$(EVENTD_TARGET) + $(RM) $(DESTDIR)/usr/sbin/$(RSYSLOG-PLUGIN_TARGET) + $(RM) -rf $(DESTDIR)/usr/sbin + +clean: + -@echo ' ' + +.PHONY: all clean dependents diff --git a/src/sonic-eventd/debian/changelog b/src/sonic-eventd/debian/changelog new file mode 100644 index 000000000000..eba3bf10ea53 --- /dev/null +++ b/src/sonic-eventd/debian/changelog @@ -0,0 +1,5 @@ +sonic-eventd (1.0.0-0) UNRELEASED; urgency=medium + + * Initial release. + +-- Renuka Manavalan diff --git a/src/sonic-eventd/debian/compat b/src/sonic-eventd/debian/compat new file mode 100644 index 000000000000..48082f72f087 --- /dev/null +++ b/src/sonic-eventd/debian/compat @@ -0,0 +1 @@ +12 diff --git a/src/sonic-eventd/debian/control b/src/sonic-eventd/debian/control new file mode 100644 index 000000000000..95ae6fd76452 --- /dev/null +++ b/src/sonic-eventd/debian/control @@ -0,0 +1,14 @@ +Source: sonic-eventd +Section: devel +Priority: optional +Maintainer: Renuka Manavalan +Build-Depends: debhelper (>= 12.0.0), libevent-dev, libboost-thread-dev, libboost-system-dev, libswsscommon-dev +Standards-Version: 3.9.3 +Homepage: https://github.com/Azure/sonic-buildimage +XS-Go-Import-Path: github.com/Azure/sonic-buildimage + +Package: sonic-eventd +Architecture: any +Built-Using: ${misc:Built-Using} +Depends: ${shlibs:Depends} +Description: SONiC event service diff --git a/src/sonic-eventd/debian/rules b/src/sonic-eventd/debian/rules new file mode 100755 index 000000000000..ac2cd63889ef --- /dev/null +++ b/src/sonic-eventd/debian/rules @@ -0,0 +1,6 @@ +#!/usr/bin/make -f + +export DEB_BUILD_MAINT_OPTIONS=hardening=+all + +%: + dh $@ --parallel diff --git a/src/sonic-eventd/rsyslog_plugin/main.cpp b/src/sonic-eventd/rsyslog_plugin/main.cpp new file mode 100644 index 000000000000..53162608c5a9 --- /dev/null +++ b/src/sonic-eventd/rsyslog_plugin/main.cpp @@ -0,0 +1,57 @@ +#include +#include +#include +#include "rsyslog_plugin.h" + +#define SUCCESS_CODE 0 +#define INVALID_REGEX_ERROR_CODE 1 +#define EVENT_INIT_PUBLISH_ERROR_CODE 2 +#define MISSING_ARGS_ERROR_CODE 3 + +void showUsage() { + cout << "Usage for rsyslog_plugin: \n" << "options\n" + << "\t-r,required,type=string\t\tPath to regex file\n" + << "\t-m,required,type=string\t\tYANG module name of source generating syslog message\n" + << "\t-h \t\tHelp" + << endl; +} + +int main(int argc, char** argv) { + string regexPath; + string moduleName; + int optionVal; + + while((optionVal = getopt(argc, argv, "r:m:h")) != -1) { + switch(optionVal) { + case 'r': + regexPath = optarg; + break; + case 'm': + moduleName = optarg; + break; + case 'h': + case '?': + default: + showUsage(); + return 1; + } + } + + if(regexPath.empty() || moduleName.empty()) { // Missing required rc path + cerr << "Error: Missing regexPath and moduleName." << endl; + return MISSING_ARGS_ERROR_CODE; + } + + unique_ptr plugin(new RsyslogPlugin(moduleName, regexPath)); + int returnCode = plugin->onInit(); + if(returnCode == INVALID_REGEX_ERROR_CODE) { + SWSS_LOG_ERROR("Rsyslog plugin was not able to be initialized due to invalid regex file provided.\n"); + return returnCode; + } else if(returnCode == EVENT_INIT_PUBLISH_ERROR_CODE) { + SWSS_LOG_ERROR("Rsyslog plugin was not able to be initialized due to event_init_publish call failing.\n"); + return returnCode; + } + + plugin->run(); + return SUCCESS_CODE; +} diff --git a/src/sonic-eventd/rsyslog_plugin/rsyslog_plugin.cpp b/src/sonic-eventd/rsyslog_plugin/rsyslog_plugin.cpp new file mode 100644 index 000000000000..3786c5f0fea9 --- /dev/null +++ b/src/sonic-eventd/rsyslog_plugin/rsyslog_plugin.cpp @@ -0,0 +1,135 @@ +#include +#include +#include +#include +#include +#include +#include "rsyslog_plugin.h" +#include "json.hpp" + +using json = nlohmann::json; + +bool RsyslogPlugin::onMessage(string msg, lua_State* luaState) { + string tag; + event_params_t paramDict; + if(!m_parser->parseMessage(msg, tag, paramDict, luaState)) { + SWSS_LOG_DEBUG("%s was not able to be parsed into a structured event\n", msg.c_str()); + return false; + } else { + int returnCode = event_publish(m_eventHandle, tag, ¶mDict); + if(returnCode != 0) { + SWSS_LOG_ERROR("rsyslog_plugin was not able to publish event for %s.\n", tag.c_str()); + return false; + } + return true; + } +} + +void parseParams(vector params, vector& eventParams) { + for(long unsigned int i = 0; i < params.size(); i++) { + if(params[i].empty()) { + SWSS_LOG_ERROR("Empty param provided in regex file\n"); + continue; + } + EventParam ep = EventParam(); + auto delimPos = params[i].find(':'); + if(delimPos == string::npos) { // no lua code + ep.paramName = params[i]; + } else { + ep.paramName = params[i].substr(0, delimPos); + ep.luaCode = params[i].substr(delimPos + 1); + if(ep.luaCode.empty()) { + SWSS_LOG_ERROR("Lua code missing after :\n"); + } + } + eventParams.push_back(ep); + } +} + +bool RsyslogPlugin::createRegexList() { + fstream regexFile; + json jsonList = json::array(); + regexFile.open(m_regexPath, ios::in); + if (!regexFile) { + SWSS_LOG_ERROR("No such path exists: %s for source %s\n", m_regexPath.c_str(), m_moduleName.c_str()); + return false; + } + try { + regexFile >> jsonList; + } catch (invalid_argument& iaException) { + SWSS_LOG_ERROR("Invalid JSON file: %s, throws exception: %s\n", m_regexPath.c_str(), iaException.what()); + return false; + } + + string regexString; + string timestampRegex = "^([a-zA-Z]{3})?\\s*([0-9]{1,2})?\\s*([0-9]{2}:[0-9]{2}:[0-9]{2}.[0-9]{0,6})?\\s*"; + regex expression; + vector regexList; + + for(long unsigned int i = 0; i < jsonList.size(); i++) { + RegexStruct rs = RegexStruct(); + vector eventParams; + try { + string eventRegex = jsonList[i]["regex"]; + regexString = timestampRegex + eventRegex; + string tag = jsonList[i]["tag"]; + vector params = jsonList[i]["params"]; + vector timestampParams = { "month", "day", "time" }; + params.insert(params.begin(), timestampParams.begin(), timestampParams.end()); + regex expr(regexString); + expression = expr; + parseParams(params, eventParams); + rs.params = eventParams; + rs.tag = tag; + rs.regexExpression = expression; + regexList.push_back(rs); + } catch (domain_error& deException) { + SWSS_LOG_ERROR("Missing required key, throws exception: %s\n", deException.what()); + return false; + } catch (regex_error& reException) { + SWSS_LOG_ERROR("Invalid regex, throws exception: %s\n", reException.what()); + return false; + } + } + + if(regexList.empty()) { + SWSS_LOG_ERROR("Empty list of regex expressions.\n"); + return false; + } + + m_parser->m_regexList = regexList; + + regexFile.close(); + return true; +} + +void RsyslogPlugin::run() { + lua_State* luaState = luaL_newstate(); + luaL_openlibs(luaState); + while(true) { + string line; + getline(cin, line); + if(line.empty()) { + continue; + } + onMessage(line, luaState); + } + lua_close(luaState); +} + +int RsyslogPlugin::onInit() { + m_eventHandle = events_init_publisher(m_moduleName); + bool success = createRegexList(); + if(!success) { + return 1; // invalid regex error code + } else if(m_eventHandle == NULL) { + return 2; // event init publish error code + } + return 0; +} + +RsyslogPlugin::RsyslogPlugin(string moduleName, string regexPath) { + m_parser = unique_ptr(new SyslogParser()); + m_moduleName = moduleName; + m_regexPath = regexPath; +} diff --git a/src/sonic-eventd/rsyslog_plugin/rsyslog_plugin.h b/src/sonic-eventd/rsyslog_plugin/rsyslog_plugin.h new file mode 100644 index 000000000000..0811b5f3032f --- /dev/null +++ b/src/sonic-eventd/rsyslog_plugin/rsyslog_plugin.h @@ -0,0 +1,40 @@ +#ifndef RSYSLOG_PLUGIN_H +#define RSYSLOG_PLUGIN_H + +extern "C" +{ + #include + #include + #include +} +#include +#include +#include "syslog_parser.h" +#include "events.h" +#include "logger.h" + +using namespace std; +using namespace swss; + +/** + * Rsyslog Plugin will utilize an instance of a syslog parser to read syslog messages from rsyslog.d and will continuously read from stdin + * A plugin instance is created for each container/host. + * + */ + +class RsyslogPlugin { +public: + int onInit(); + bool onMessage(string msg, lua_State* luaState); + void run(); + RsyslogPlugin(string moduleName, string regexPath); +private: + unique_ptr m_parser; + event_handle_t m_eventHandle; + string m_regexPath; + string m_moduleName; + bool createRegexList(); +}; + +#endif + diff --git a/src/sonic-eventd/rsyslog_plugin/subdir.mk b/src/sonic-eventd/rsyslog_plugin/subdir.mk new file mode 100644 index 000000000000..17df55c718a0 --- /dev/null +++ b/src/sonic-eventd/rsyslog_plugin/subdir.mk @@ -0,0 +1,13 @@ +CC := g++ + +RSYSLOG-PLUGIN-TEST_OBJS += ./rsyslog_plugin/rsyslog_plugin.o ./rsyslog_plugin/syslog_parser.o ./rsyslog_plugin/timestamp_formatter.o +RSYSLOG-PLUGIN_OBJS += ./rsyslog_plugin/rsyslog_plugin.o ./rsyslog_plugin/syslog_parser.o ./rsyslog_plugin/timestamp_formatter.o ./rsyslog_plugin/main.o + +C_DEPS += ./rsyslog_plugin/rsyslog_plugin.d ./rsyslog_plugin/syslog_parser.d ./rsyslog_plugin/timestamp_formatter.d ./rsyslog_plugin/main.d + +rsyslog_plugin/%.o: rsyslog_plugin/%.cpp + @echo 'Building file: $<' + @echo 'Invoking: GCC C++ Compiler' + $(CC) -D__FILENAME__="$(subst rsyslog_plugin/,,$<)" $(CFLAGS) -c -fmessage-length=0 -MMD -MP -MF"$(@:%.o=%.d)" -MT"$(@)" -o "$(@)" "$<" + @echo 'Finished building: $<' + @echo ' ' diff --git a/src/sonic-eventd/rsyslog_plugin/syslog_parser.cpp b/src/sonic-eventd/rsyslog_plugin/syslog_parser.cpp new file mode 100644 index 000000000000..ebf7c598d15a --- /dev/null +++ b/src/sonic-eventd/rsyslog_plugin/syslog_parser.cpp @@ -0,0 +1,65 @@ +#include +#include +#include "syslog_parser.h" +#include "logger.h" + +/** + * Parses syslog message and returns structured event + * + * @param nessage us syslog message being fed in by rsyslog.d + * @return return structured event json for publishing + * +*/ + +bool SyslogParser::parseMessage(string message, string& eventTag, event_params_t& paramMap, lua_State* luaState) { + for(long unsigned int i = 0; i < m_regexList.size(); i++) { + smatch matchResults; + if(!regex_search(message, matchResults, m_regexList[i].regexExpression) || m_regexList[i].params.size() != matchResults.size() - 1 || matchResults.size() < 4) { + continue; + } + string formattedTimestamp; + if(!matchResults[1].str().empty() && !matchResults[2].str().empty() && !matchResults[3].str().empty()) { // found timestamp components + formattedTimestamp = m_timestampFormatter->changeTimestampFormat({ matchResults[1].str(), matchResults[2].str(), matchResults[3].str() }); + } + if(!formattedTimestamp.empty()) { + paramMap["timestamp"] = formattedTimestamp; + } else { + SWSS_LOG_INFO("Timestamp is invalid and is not able to be formatted"); + } + + // found matching regex + eventTag = m_regexList[i].tag; + // check params for lua code + for(long unsigned int j = 3; j < m_regexList[i].params.size(); j++) { + string resultValue = matchResults[j + 1].str(); + string paramName = m_regexList[i].params[j].paramName; + const char* luaCode = m_regexList[i].params[j].luaCode.c_str(); + + if(luaCode == NULL || *luaCode == 0) { + SWSS_LOG_INFO("Invalid lua code, empty or missing"); + paramMap[paramName] = resultValue; + continue; + } + + // execute lua code + lua_pushstring(luaState, resultValue.c_str()); + lua_setglobal(luaState, "arg"); + if(luaL_dostring(luaState, luaCode) == 0) { + lua_pop(luaState, lua_gettop(luaState)); + } else { // error in lua code + SWSS_LOG_ERROR("Invalid lua code, unable to do operation.\n"); + paramMap[paramName] = resultValue; + continue; + } + lua_getglobal(luaState, "ret"); + paramMap[paramName] = lua_tostring(luaState, -1); + lua_pop(luaState, 1); + } + return true; + } + return false; +} + +SyslogParser::SyslogParser() { + m_timestampFormatter = unique_ptr(new TimestampFormatter()); +} diff --git a/src/sonic-eventd/rsyslog_plugin/syslog_parser.h b/src/sonic-eventd/rsyslog_plugin/syslog_parser.h new file mode 100644 index 000000000000..6293eb3c4a34 --- /dev/null +++ b/src/sonic-eventd/rsyslog_plugin/syslog_parser.h @@ -0,0 +1,46 @@ +#ifndef SYSLOG_PARSER_H +#define SYSLOG_PARSER_H + +extern "C" +{ + #include + #include + #include +} + +#include +#include +#include +#include "json.hpp" +#include "events.h" +#include "timestamp_formatter.h" + +using namespace std; +using json = nlohmann::json; + +struct EventParam { + string paramName; + string luaCode; +}; + +struct RegexStruct { + regex regexExpression; + vector params; + string tag; +}; + +/** + * Syslog Parser is responsible for parsing log messages fed by rsyslog.d and returns + * matched result to rsyslog_plugin to use with events publish API + * + */ + +class SyslogParser { +public: + unique_ptr m_timestampFormatter; + vector m_regexList; + bool parseMessage(string message, string& tag, event_params_t& paramDict, lua_State* luaState); + SyslogParser(); +}; + +#endif diff --git a/src/sonic-eventd/rsyslog_plugin/timestamp_formatter.cpp b/src/sonic-eventd/rsyslog_plugin/timestamp_formatter.cpp new file mode 100644 index 000000000000..cc179adbbc75 --- /dev/null +++ b/src/sonic-eventd/rsyslog_plugin/timestamp_formatter.cpp @@ -0,0 +1,74 @@ +#include +#include "timestamp_formatter.h" +#include "logger.h" +#include "events.h" + +using namespace std; + +/*** + * + * Formats given string into string needed by YANG model + * + * @param timestamp parsed from syslog message + * @return formatted timestamp that conforms to YANG model + * + */ + +static const unordered_map g_monthDict { + { "Jan", "01" }, + { "Feb", "02" }, + { "Mar", "03" }, + { "Apr", "04" }, + { "May", "05" }, + { "Jun", "06" }, + { "Jul", "07" }, + { "Aug", "08" }, + { "Sep", "09" }, + { "Oct", "10" }, + { "Nov", "11" }, + { "Dec", "12" } +}; + +string TimestampFormatter::getYear(string timestamp) { + if(!m_storedTimestamp.empty()) { + if(m_storedTimestamp.compare(timestamp) <= 0) { + m_storedTimestamp = timestamp; + return m_storedYear; + } + } + // no last timestamp or year change + time_t currentTime = time(nullptr); + tm* const localTime = localtime(¤tTime); + stringstream ss; + auto currentYear = 1900 + localTime->tm_year; + ss << currentYear; // get current year + string year = ss.str(); + m_storedTimestamp = timestamp; + m_storedYear = year; + return year; +} + +string TimestampFormatter::changeTimestampFormat(vector dateComponents) { + if(dateComponents.size() < 3) { + SWSS_LOG_ERROR("Timestamp formatter unable to format due to invalid input"); + return ""; + } + string formattedTimestamp; // need to change format of Mmm dd hh:mm:ss.SSSSSS to YYYY-mm-ddThh:mm:ss.SSSSSSZ + string month; + auto it = g_monthDict.find(dateComponents[0]); + if(it != g_monthDict.end()) { + month = it->second; + } else { + SWSS_LOG_ERROR("Timestamp month was given in wrong format.\n"); + return ""; + } + string day = dateComponents[1]; + if(day.size() == 1) { // convert 1 -> 01 + day.insert(day.begin(), '0'); + } + string time = dateComponents[2]; + string currentTimestamp = month + day + time; + string year = getYear(currentTimestamp); + formattedTimestamp = year + "-" + month + "-" + day + "T" + time + "Z"; + return formattedTimestamp; +} diff --git a/src/sonic-eventd/rsyslog_plugin/timestamp_formatter.h b/src/sonic-eventd/rsyslog_plugin/timestamp_formatter.h new file mode 100644 index 000000000000..ea99c4cfcb8c --- /dev/null +++ b/src/sonic-eventd/rsyslog_plugin/timestamp_formatter.h @@ -0,0 +1,27 @@ +#ifndef TIMESTAMP_FORMATTER_H +#define TIMESTAMP_FORMATTER_H + +#include +#include +#include +#include +#include + +using namespace std; + +/*** + * + * TimestampFormatter is responsible for formatting the timestamps received in syslog messages and to format them into the type needed by YANG model + * + */ + +class TimestampFormatter { +public: + string changeTimestampFormat(vector dateComponents); + string m_storedTimestamp; + string m_storedYear; +private: + string getYear(string timestamp); +}; + +#endif diff --git a/src/sonic-eventd/rsyslog_plugin_tests/rsyslog_plugin_ut.cpp b/src/sonic-eventd/rsyslog_plugin_tests/rsyslog_plugin_ut.cpp new file mode 100644 index 000000000000..be5a19ad5a5b --- /dev/null +++ b/src/sonic-eventd/rsyslog_plugin_tests/rsyslog_plugin_ut.cpp @@ -0,0 +1,274 @@ +extern "C" +{ + #include + #include + #include +} +#include +#include +#include +#include +#include "gtest/gtest.h" +#include "json.hpp" +#include "events.h" +#include "../rsyslog_plugin/rsyslog_plugin.h" +#include "../rsyslog_plugin/syslog_parser.h" +#include "../rsyslog_plugin/timestamp_formatter.h" + +using namespace std; +using namespace swss; +using json = nlohmann::json; + +vector createEventParams(vector params, vector luaCodes) { + vector eventParams; + for(long unsigned int i = 0; i < params.size(); i++) { + EventParam ep = EventParam(); + ep.paramName = params[i]; + ep.luaCode = luaCodes[i]; + eventParams.push_back(ep); + } + return eventParams; +} + +TEST(syslog_parser, matching_regex) { + json jList = json::array(); + vector regexList; + string regexString = "^([a-zA-Z]{3})?\\s*([0-9]{1,2})?\\s*([0-9]{2}:[0-9]{2}:[0-9]{2}.[0-9]{0,6})?\\s*message (.*) other_data (.*) even_more_data (.*)"; + vector params = { "month", "day", "time", "message", "other_data", "even_more_data" }; + vector luaCodes = { "", "", "", "", "", "" }; + regex expression(regexString); + + RegexStruct rs = RegexStruct(); + rs.tag = "test_tag"; + rs.regexExpression = expression; + rs.params = createEventParams(params, luaCodes); + regexList.push_back(rs); + + string tag; + event_params_t paramDict; + + event_params_t expectedDict; + expectedDict["message"] = "test_message"; + expectedDict["other_data"] = "test_data"; + expectedDict["even_more_data"] = "test_data"; + + unique_ptr parser(new SyslogParser()); + parser->m_regexList = regexList; + lua_State* luaState = luaL_newstate(); + luaL_openlibs(luaState); + + bool success = parser->parseMessage("message test_message other_data test_data even_more_data test_data", tag, paramDict, luaState); + EXPECT_EQ(true, success); + EXPECT_EQ("test_tag", tag); + EXPECT_EQ(expectedDict, paramDict); + + lua_close(luaState); +} + +TEST(syslog_parser, matching_regex_timestamp) { + json jList = json::array(); + vector regexList; + string regexString = "^([a-zA-Z]{3})?\\s*([0-9]{1,2})?\\s*([0-9]{2}:[0-9]{2}:[0-9]{2}.[0-9]{0,6})?\\s*message (.*) other_data (.*)"; + vector params = { "month", "day", "time", "message", "other_data" }; + vector luaCodes = { "", "", "", "", "" }; + regex expression(regexString); + + RegexStruct rs = RegexStruct(); + rs.tag = "test_tag"; + rs.regexExpression = expression; + rs.params = createEventParams(params, luaCodes); + regexList.push_back(rs); + + string tag; + event_params_t paramDict; + + event_params_t expectedDict; + expectedDict["message"] = "test_message"; + expectedDict["other_data"] = "test_data"; + expectedDict["timestamp"] = "2022-07-21T02:10:00.000000Z"; + + unique_ptr parser(new SyslogParser()); + parser->m_regexList = regexList; + lua_State* luaState = luaL_newstate(); + luaL_openlibs(luaState); + + bool success = parser->parseMessage("Jul 21 02:10:00.000000 message test_message other_data test_data", tag, paramDict, luaState); + EXPECT_EQ(true, success); + EXPECT_EQ("test_tag", tag); + EXPECT_EQ(expectedDict, paramDict); + + lua_close(luaState); +} + +TEST(syslog_parser, no_matching_regex) { + json jList = json::array(); + vector regexList; + string regexString = "^([a-zA-Z]{3})?\\s*([0-9]{1,2})?\\s*([0-9]{2}:[0-9]{2}:[0-9]{2}.[0-9]{0,6})?\\s*no match"; + vector params = { "month", "day", "time" }; + vector luaCodes = { "", "", "" }; + regex expression(regexString); + + RegexStruct rs = RegexStruct(); + rs.tag = "test_tag"; + rs.regexExpression = expression; + rs.params = createEventParams(params, luaCodes); + regexList.push_back(rs); + + string tag; + event_params_t paramDict; + + unique_ptr parser(new SyslogParser()); + parser->m_regexList = regexList; + lua_State* luaState = luaL_newstate(); + luaL_openlibs(luaState); + + bool success = parser->parseMessage("Test Message", tag, paramDict, luaState); + EXPECT_EQ(false, success); + + lua_close(luaState); +} + +TEST(syslog_parser, lua_code_valid_1) { + json jList = json::array(); + vector regexList; + string regexString = "^([a-zA-Z]{3})?\\s*([0-9]{1,2})?\\s*([0-9]{2}:[0-9]{2}:[0-9]{2}.[0-9]{0,6})?\\s*.* (sent|received) (?:to|from) .* ([0-9]{2,3}.[0-9]{2,3}.[0-9]{2,3}.[0-9]{2,3}) active ([1-9]{1,3})/([1-9]{1,3}) .*"; + vector params = { "month", "day", "time", "is-sent", "ip", "major-code", "minor-code" }; + vector luaCodes = { "", "", "", "ret=tostring(arg==\"sent\")", "", "", "" }; + regex expression(regexString); + + RegexStruct rs = RegexStruct(); + rs.tag = "test_tag"; + rs.regexExpression = expression; + rs.params = createEventParams(params, luaCodes); + regexList.push_back(rs); + + string tag; + event_params_t paramDict; + + event_params_t expectedDict; + expectedDict["is-sent"] = "true"; + expectedDict["ip"] = "100.95.147.229"; + expectedDict["major-code"] = "2"; + expectedDict["minor-code"] = "2"; + + unique_ptr parser(new SyslogParser()); + parser->m_regexList = regexList; + lua_State* luaState = luaL_newstate(); + luaL_openlibs(luaState); + + bool success = parser->parseMessage("NOTIFICATION: sent to neighbor 100.95.147.229 active 2/2 (peer in wrong AS) 2 bytes", tag, paramDict, luaState); + EXPECT_EQ(true, success); + EXPECT_EQ("test_tag", tag); + EXPECT_EQ(expectedDict, paramDict); + + lua_close(luaState); +} + +TEST(syslog_parser, lua_code_valid_2) { + json jList = json::array(); + vector regexList; + string regexString = "([a-zA-Z]{3})?\\s*([0-9]{1,2})?\\s*([0-9]{2}:[0-9]{2}:[0-9]{2}.[0-9]{0,6})?\\s*.* (sent|received) (?:to|from) .* ([0-9]{2,3}.[0-9]{2,3}.[0-9]{2,3}.[0-9]{2,3}) active ([1-9]{1,3})/([1-9]{1,3}) .*"; + vector params = { "month", "day", "time", "is-sent", "ip", "major-code", "minor-code" }; + vector luaCodes = { "", "", "", "ret=tostring(arg==\"sent\")", "", "", "" }; + regex expression(regexString); + + RegexStruct rs = RegexStruct(); + rs.tag = "test_tag"; + rs.regexExpression = expression; + rs.params = createEventParams(params, luaCodes); + regexList.push_back(rs); + + string tag; + event_params_t paramDict; + + event_params_t expectedDict; + expectedDict["is-sent"] = "false"; + expectedDict["ip"] = "10.10.24.216"; + expectedDict["major-code"] = "6"; + expectedDict["minor-code"] = "2"; + expectedDict["timestamp"] = "2022-12-03T12:36:24.503424Z"; + + unique_ptr parser(new SyslogParser()); + parser->m_regexList = regexList; + lua_State* luaState = luaL_newstate(); + luaL_openlibs(luaState); + + bool success = parser->parseMessage("Dec 3 12:36:24.503424 NOTIFICATION: received from neighbor 10.10.24.216 active 6/2 (Administrative Shutdown) 0 bytes", tag, paramDict, luaState); + EXPECT_EQ(true, success); + EXPECT_EQ("test_tag", tag); + EXPECT_EQ(expectedDict, paramDict); + + lua_close(luaState); +} + +TEST(rsyslog_plugin, onInit_emptyJSON) { + unique_ptr plugin(new RsyslogPlugin("test_mod_name", "./rsyslog_plugin_tests/test_regex_1.rc.json")); + EXPECT_NE(0, plugin->onInit()); +} + +TEST(rsyslog_plugin, onInit_missingRegex) { + unique_ptr plugin(new RsyslogPlugin("test_mod_name", "./rsyslog_plugin_tests/test_regex_3.rc.json")); + EXPECT_NE(0, plugin->onInit()); +} + +TEST(rsyslog_plugin, onInit_invalidRegex) { + unique_ptr plugin(new RsyslogPlugin("test_mod_name", "./rsyslog_plugin_tests/test_regex_4.rc.json")); + EXPECT_NE(0, plugin->onInit()); +} + +TEST(rsyslog_plugin, onMessage) { + unique_ptr plugin(new RsyslogPlugin("test_mod_name", "./rsyslog_plugin_tests/test_regex_2.rc.json")); + EXPECT_EQ(0, plugin->onInit()); + ifstream infile("./rsyslog_plugin_tests/test_syslogs.txt"); + string logMessage; + bool parseResult; + lua_State* luaState = luaL_newstate(); + luaL_openlibs(luaState); + while(infile >> logMessage >> parseResult) { + EXPECT_EQ(parseResult, plugin->onMessage(logMessage, luaState)); + } + lua_close(luaState); + infile.close(); +} + +TEST(rsyslog_plugin, onMessage_noParams) { + unique_ptr plugin(new RsyslogPlugin("test_mod_name", "./rsyslog_plugin_tests/test_regex_5.rc.json")); + EXPECT_EQ(0, plugin->onInit()); + ifstream infile("./rsyslog_plugin_tests/test_syslogs_2.txt"); + string logMessage; + bool parseResult; + lua_State* luaState = luaL_newstate(); + luaL_openlibs(luaState); + while(infile >> logMessage >> parseResult) { + EXPECT_EQ(parseResult, plugin->onMessage(logMessage, luaState)); + } + lua_close(luaState); + infile.close(); +} + +TEST(timestampFormatter, changeTimestampFormat) { + unique_ptr formatter(new TimestampFormatter()); + + vector timestampOne = { "Jul", "20", "10:09:40.230874" }; + vector timestampTwo = { "Jan", "1", "00:00:00.000000" }; + vector timestampThree = { "Dec", "31", "23:59:59.000000" }; + + string formattedTimestampOne = formatter->changeTimestampFormat(timestampOne); + EXPECT_EQ("2022-07-20T10:09:40.230874Z", formattedTimestampOne); + + EXPECT_EQ("072010:09:40.230874", formatter->m_storedTimestamp); + + string formattedTimestampTwo = formatter->changeTimestampFormat(timestampTwo); + EXPECT_EQ("2022-01-01T00:00:00.000000Z", formattedTimestampTwo); + + formatter->m_storedTimestamp = "010100:00:00.000000"; + formatter->m_storedYear = "2025"; + + string formattedTimestampThree = formatter->changeTimestampFormat(timestampThree); + EXPECT_EQ("2025-12-31T23:59:59.000000Z", formattedTimestampThree); +} + +int main(int argc, char* argv[]) { + testing::InitGoogleTest(&argc, argv); + return RUN_ALL_TESTS(); +} diff --git a/src/sonic-eventd/rsyslog_plugin_tests/subdir.mk b/src/sonic-eventd/rsyslog_plugin_tests/subdir.mk new file mode 100644 index 000000000000..6be7ef09786a --- /dev/null +++ b/src/sonic-eventd/rsyslog_plugin_tests/subdir.mk @@ -0,0 +1,12 @@ +CC := g++ + +RSYSLOG-PLUGIN-TEST_OBJS += ./rsyslog_plugin_tests/rsyslog_plugin_ut.o + +C_DEPS += ./rsyslog_plugin_tests/rsyslog_plugin_ut.d + +rsyslog_plugin_tests/%.o: rsyslog_plugin_tests/%.cpp + @echo 'Building file: $<' + @echo 'Invoking: GCC C++ Compiler' + $(CC) -D__FILENAME__="$(subst rsyslog_plugin_tests/,,$<)" $(CFLAGS) -c -fmessage-length=0 -MMD -MP -MF"$(@:%.o=%.d)" -MT"$(@)" -o "$@" "$<" + @echo 'Finished building: $<' + @echo ' ' diff --git a/src/sonic-eventd/rsyslog_plugin_tests/test_regex_1.rc.json b/src/sonic-eventd/rsyslog_plugin_tests/test_regex_1.rc.json new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/src/sonic-eventd/rsyslog_plugin_tests/test_regex_2.rc.json b/src/sonic-eventd/rsyslog_plugin_tests/test_regex_2.rc.json new file mode 100644 index 000000000000..66788d326331 --- /dev/null +++ b/src/sonic-eventd/rsyslog_plugin_tests/test_regex_2.rc.json @@ -0,0 +1,7 @@ +[ + { + "tag": "bgp-state", + "regex": ".* %ADJCHANGE: neighbor (.*) (Up|Down) .*", + "params": ["neighbor_ip", "state" ] + } +] diff --git a/src/sonic-eventd/rsyslog_plugin_tests/test_regex_3.rc.json b/src/sonic-eventd/rsyslog_plugin_tests/test_regex_3.rc.json new file mode 100644 index 000000000000..2e67e88f8448 --- /dev/null +++ b/src/sonic-eventd/rsyslog_plugin_tests/test_regex_3.rc.json @@ -0,0 +1,6 @@ +[ + { + "tag": "TEST-TAG-NO-REGEX", + "param": [] + } +] diff --git a/src/sonic-eventd/rsyslog_plugin_tests/test_regex_4.rc.json b/src/sonic-eventd/rsyslog_plugin_tests/test_regex_4.rc.json new file mode 100644 index 000000000000..c3a875aded0f --- /dev/null +++ b/src/sonic-eventd/rsyslog_plugin_tests/test_regex_4.rc.json @@ -0,0 +1,7 @@ +[ + { + "tag": "TEST-TAG-INVALID-REGEX", + "regex": "+++ ++++(", + "params": [] + } +] diff --git a/src/sonic-eventd/rsyslog_plugin_tests/test_regex_5.rc.json b/src/sonic-eventd/rsyslog_plugin_tests/test_regex_5.rc.json new file mode 100644 index 000000000000..ddaf37c931a8 --- /dev/null +++ b/src/sonic-eventd/rsyslog_plugin_tests/test_regex_5.rc.json @@ -0,0 +1,7 @@ +[ + { + "tag": "test_tag", + "regex": ".*", + "params": [] + } +] diff --git a/src/sonic-eventd/rsyslog_plugin_tests/test_syslogs.txt b/src/sonic-eventd/rsyslog_plugin_tests/test_syslogs.txt new file mode 100644 index 000000000000..78f89aec3d28 --- /dev/null +++ b/src/sonic-eventd/rsyslog_plugin_tests/test_syslogs.txt @@ -0,0 +1,4 @@ +"Aug 17 02:39:21.286611 SN6-0101-0114-02T0 INFO bgp#bgpd[62]: %ADJCHANGE: neighbor 100.126.188.90 Down Neighbor deleted" true +"Aug 17 02:46:42.615668 SN6-0101-0114-02T0 INFO bgp#bgpd[62]: %ADJCHANGE: neighbor 100.126.188.90 Up" true +"Aug 17 04:46:51.290979 SN6-0101-0114-02T0 INFO bgp#bgpd[62]: %ADJCHANGE: neighbor 100.126.188.78 Down Neighbor deleted" true +"Aug 17 04:46:51.290979 SN6-0101-0114-02T0 INFO bgp#bgpd[62]: %NOEVENT: no event" false diff --git a/src/sonic-eventd/rsyslog_plugin_tests/test_syslogs_2.txt b/src/sonic-eventd/rsyslog_plugin_tests/test_syslogs_2.txt new file mode 100644 index 000000000000..d56615f61681 --- /dev/null +++ b/src/sonic-eventd/rsyslog_plugin_tests/test_syslogs_2.txt @@ -0,0 +1,3 @@ +testMessage true +another_test_message true + true diff --git a/src/sonic-eventd/src/eventd.cpp b/src/sonic-eventd/src/eventd.cpp new file mode 100644 index 000000000000..1ff9dd8be20b --- /dev/null +++ b/src/sonic-eventd/src/eventd.cpp @@ -0,0 +1,798 @@ +#include +#include "eventd.h" +#include "dbconnector.h" + +/* + * There are 5 threads, including the main + * + * (0) main thread -- Runs eventd service that accepts commands event_req_type_t + * This can be used to control caching events and a no-op echo service. + * + * (1) capture/cache service + * Saves all the events between cache start & stop. + * Update missed cached counter in memory. + * + * (2) Main proxy service that runs XSUB/XPUB ends + * + * (3) Get stats for total published counter in memory. This thread also sends + * heartbeat message. It accomplishes by counting upon receive missed due + * to event receive timeout. + * + * (4) Thread to update counters from memory to redis periodically. + * + */ + +using namespace std; +using namespace swss; + +#define MB(N) ((N) * 1024 * 1024) +#define EVT_SIZE_AVG 150 + +#define MAX_CACHE_SIZE (MB(100) / (EVT_SIZE_AVG)) + +/* Count of elements returned in each read */ +#define READ_SET_SIZE 100 + +#define VEC_SIZE(p) ((int)p.size()) + +/* Sock read timeout in milliseconds, to enable look for control signals */ +#define CAPTURE_SOCK_TIMEOUT 800 + +#define HEARTBEAT_INTERVAL_SECS 2 /* Default: 2 seconds */ + +/* Source & tag for heartbeat events */ +#define EVENTD_PUBLISHER_SOURCE "sonic-events-eventd" +#define EVENTD_HEARTBEAT_TAG "heartbeat" + + +const char *counter_keys[COUNTERS_EVENTS_TOTAL] = { + COUNTERS_EVENTS_PUBLISHED, + COUNTERS_EVENTS_MISSED_CACHE +}; + +static bool s_unit_testing = false; + +int +eventd_proxy::init() +{ + int ret = -1, rc = 0; + SWSS_LOG_INFO("Start xpub/xsub proxy"); + + m_frontend = zmq_socket(m_ctx, ZMQ_XSUB); + RET_ON_ERR(m_frontend != NULL, "failing to get ZMQ_XSUB socket"); + + rc = zmq_bind(m_frontend, get_config(string(XSUB_END_KEY)).c_str()); + RET_ON_ERR(rc == 0, "Failing to bind XSUB to %s", get_config(string(XSUB_END_KEY)).c_str()); + + m_backend = zmq_socket(m_ctx, ZMQ_XPUB); + RET_ON_ERR(m_backend != NULL, "failing to get ZMQ_XPUB socket"); + + rc = zmq_bind(m_backend, get_config(string(XPUB_END_KEY)).c_str()); + RET_ON_ERR(rc == 0, "Failing to bind XPUB to %s", get_config(string(XPUB_END_KEY)).c_str()); + + m_capture = zmq_socket(m_ctx, ZMQ_PUB); + RET_ON_ERR(m_capture != NULL, "failing to get ZMQ_PUB socket for capture"); + + rc = zmq_bind(m_capture, get_config(string(CAPTURE_END_KEY)).c_str()); + RET_ON_ERR(rc == 0, "Failing to bind capture PUB to %s", get_config(string(CAPTURE_END_KEY)).c_str()); + + m_thr = thread(&eventd_proxy::run, this); + ret = 0; +out: + return ret; +} + +void +eventd_proxy::run() +{ + SWSS_LOG_INFO("Running xpub/xsub proxy"); + + /* runs forever until zmq context is terminated */ + zmq_proxy(m_frontend, m_backend, m_capture); + + SWSS_LOG_INFO("Stopped xpub/xsub proxy"); +} + + +stats_collector::stats_collector() : + m_shutdown(false), m_pause_heartbeat(false), m_heartbeats_published(0), + m_heartbeats_interval_cnt(0) +{ + set_heartbeat_interval(HEARTBEAT_INTERVAL_SECS); + for (int i=0; i < COUNTERS_EVENTS_TOTAL; ++i) { + m_lst_counters[i] = 0; + } + m_updated = false; +} + + +void +stats_collector::set_heartbeat_interval(int val) +{ + if (val > 0) { + /* Round to highest possible multiples of MIN */ + m_heartbeats_interval_cnt = + (((val * 1000) + STATS_HEARTBEAT_MIN - 1) / STATS_HEARTBEAT_MIN); + } + else if (val == 0) { + /* Least possible */ + m_heartbeats_interval_cnt = 1; + } + else if (val == -1) { + /* Turn off heartbeat */ + m_heartbeats_interval_cnt = 0; + SWSS_LOG_INFO("Heartbeat turned OFF"); + } + /* Any other value is ignored as invalid */ + + SWSS_LOG_INFO("Set heartbeat: val=%d secs cnt=%d min=%d ms final=%d secs", + val, m_heartbeats_interval_cnt, STATS_HEARTBEAT_MIN, + (m_heartbeats_interval_cnt * STATS_HEARTBEAT_MIN / 1000)); +} + + +int +stats_collector::get_heartbeat_interval() +{ + return m_heartbeats_interval_cnt * STATS_HEARTBEAT_MIN / 1000; +} + +int +stats_collector::start() +{ + int rc = -1; + + if (!s_unit_testing) { + try { + m_counters_db = make_shared("COUNTERS_DB", 0, true); + } + catch (exception &e) + { + SWSS_LOG_ERROR("Unable to get DB Connector, e=(%s)\n", e.what()); + } + RET_ON_ERR(m_counters_db != NULL, "Failed to get COUNTERS_DB"); + + m_stats_table = make_shared( + m_counters_db.get(), COUNTERS_EVENTS_TABLE); + RET_ON_ERR(m_stats_table != NULL, "Failed to get events table"); + + m_thr_writer = thread(&stats_collector::run_writer, this); + } + m_thr_collector = thread(&stats_collector::run_collector, this); + rc = 0; +out: + return rc; +} + +void +stats_collector::run_writer() +{ + while (true) { + if (m_updated.exchange(false)) { + /* Update if there had been any update */ + + for (int i = 0; i < COUNTERS_EVENTS_TOTAL; ++i) { + vector fv; + + fv.emplace_back(EVENTS_STATS_FIELD_NAME, to_string(m_lst_counters[i])); + + m_stats_table->set(counter_keys[i], fv); + } + } + if (m_shutdown) { + break; + } + this_thread::sleep_for(chrono::milliseconds(10)); + /* + * After sleep always do an update if needed before checking + * shutdown flag, as any counters collected during sleep + * needs to be updated. + */ + } + + m_stats_table.reset(); + m_counters_db.reset(); +} + +void +stats_collector::run_collector() +{ + int hb_cntr = 0; + string hb_key = string(EVENTD_PUBLISHER_SOURCE) + ":" + EVENTD_HEARTBEAT_TAG; + event_handle_t pub_handle = NULL; + event_handle_t subs_handle = NULL; + + /* + * A subscriber is required to set a subscription. Else all published + * events will be dropped at the point of publishing itself. + */ + pub_handle = events_init_publisher(EVENTD_PUBLISHER_SOURCE); + RET_ON_ERR(pub_handle != NULL, + "failed to create publisher handle for heartbeats"); + + subs_handle = events_init_subscriber(false, STATS_HEARTBEAT_MIN); + RET_ON_ERR(subs_handle != NULL, "failed to subscribe to all"); + + /* + * Though we can count off of capture socket, then we need to duplicate + * code in event_receive which has the logic to count all missed per + * runtime id. It also has logic to retire closed runtime IDs. + * + * So use regular subscriber API w/o cache but timeout to enable + * exit, upon shutdown. + */ + /* + * The collector service runs until shutdown. + * The only task is to update total_published & total_missed_internal. + * The write of these counters into redis is done by another thread. + */ + + while(!m_shutdown) { + event_receive_op_t op; + int rc = 0; + + try { + rc = event_receive(subs_handle, op); + } + catch (exception& e) + { + rc = -1; + stringstream ss; + ss << e.what(); + SWSS_LOG_ERROR("Receive event failed with %s", ss.str().c_str()); + } + + if ((rc == 0) && (op.key != hb_key)) { + /* TODO: Discount EVENT_STR_CTRL_DEINIT messages too */ + increment_published(1+op.missed_cnt); + + /* reset counter on receive to restart. */ + hb_cntr = 0; + } + else { + if (rc < 0) { + SWSS_LOG_ERROR( + "event_receive failed with rc=%d; stats:published(%lu)", rc, + m_lst_counters[INDEX_COUNTERS_EVENTS_PUBLISHED]); + } + if (!m_pause_heartbeat && (m_heartbeats_interval_cnt > 0) && + ++hb_cntr >= m_heartbeats_interval_cnt) { + rc = event_publish(pub_handle, EVENTD_HEARTBEAT_TAG); + if (rc != 0) { + SWSS_LOG_ERROR("Failed to publish heartbeat rc=%d", rc); + } + hb_cntr = 0; + ++m_heartbeats_published; + } + } + } + +out: + /* + * NOTE: A shutdown could lose messages in cache. + * But consider, that eventd shutdown is a critical shutdown as it would + * bring down all other features. Hence done only at system level shutdown, + * hence losing few messages in flight is acceptable. Any more complex code + * to handle is unwanted. + */ + + events_deinit_subscriber(subs_handle); + events_deinit_publisher(pub_handle); + m_shutdown = true; +} + +capture_service::~capture_service() +{ + stop_capture(); +} + +void +capture_service::stop_capture() +{ + m_ctrl = STOP_CAPTURE; + + if (m_thr.joinable()) { + m_thr.join(); + } +} + +static bool +validate_event(const internal_event_t &event, runtime_id_t &rid, sequence_t &seq) +{ + bool ret = false; + + internal_event_t::const_iterator itc_r, itc_s, itc_e; + itc_r = event.find(EVENT_RUNTIME_ID); + itc_s = event.find(EVENT_SEQUENCE); + itc_e = event.find(EVENT_STR_DATA); + + if ((itc_r != event.end()) && (itc_s != event.end()) && (itc_e != event.end())) { + ret = true; + rid = itc_r->second; + seq = str_to_seq(itc_s->second); + } + else { + SWSS_LOG_ERROR("Invalid evt: %s", map_to_str(event).c_str()); + } + + return ret; +} + + +/* + * Initialize cache with set of events provided. + * Events read by cache service will be appended + */ +void +capture_service::init_capture_cache(const event_serialized_lst_t &lst) +{ + /* Cache given events as initial stock. + * Save runtime ID with last seen seq to avoid duplicates, while reading + * from capture socket. + * No check for max cache size here, as most likely not needed. + */ + for (event_serialized_lst_t::const_iterator itc = lst.begin(); itc != lst.end(); ++itc) { + internal_event_t event; + + if (deserialize(*itc, event) == 0) { + runtime_id_t rid; + sequence_t seq; + + if (validate_event(event, rid, seq)) { + m_pre_exist_id[rid] = seq; + m_events.push_back(*itc); + } + } + } +} + + +void +capture_service::do_capture() +{ + int rc; + int block_ms=CAPTURE_SOCK_TIMEOUT; + int init_cnt; + void *cap_sub_sock = NULL; + counters_t total_overflow = 0; + + typedef enum { + /* + * In this state every event read is compared with init cache given + * Only new events are saved. + */ + CAP_STATE_INIT = 0, + + /* In this state, all events read are cached until max limit */ + CAP_STATE_ACTIVE, + + /* Cache has hit max. Hence only save last event for each runime ID */ + CAP_STATE_LAST + } cap_state_t; + + cap_state_t cap_state = CAP_STATE_INIT; + + /* + * Need subscription for publishers to publish. + * The stats collector service already has active subscriber for all. + */ + + cap_sub_sock = zmq_socket(m_ctx, ZMQ_SUB); + RET_ON_ERR(cap_sub_sock != NULL, "failing to get ZMQ_SUB socket"); + + rc = zmq_connect(cap_sub_sock, get_config(string(CAPTURE_END_KEY)).c_str()); + RET_ON_ERR(rc == 0, "Failing to bind capture SUB to %s", get_config(string(CAPTURE_END_KEY)).c_str()); + + rc = zmq_setsockopt(cap_sub_sock, ZMQ_SUBSCRIBE, "", 0); + RET_ON_ERR(rc == 0, "Failing to ZMQ_SUBSCRIBE"); + + rc = zmq_setsockopt(cap_sub_sock, ZMQ_RCVTIMEO, &block_ms, sizeof (block_ms)); + RET_ON_ERR(rc == 0, "Failed to ZMQ_RCVTIMEO to %d", block_ms); + + m_cap_run = true; + + while (m_ctrl != START_CAPTURE) { + /* Wait for capture start */ + this_thread::sleep_for(chrono::milliseconds(10)); + } + + /* + * The cache service connects but defers any reading until caller provides + * the startup cache. But all events that arrived since connect, though not read + * will be held by ZMQ in its local cache. + * + * When cache service starts reading, check against the initial stock for duplicates. + * m_pre_exist_id caches the last seq number in initial stock for each runtime id. + * So only allow sequence number greater than cached number. + * + * Theoretically all the events provided via initial stock could be duplicates. + * Hence until as many events as in initial stock or until the cached id map + * is empty, do this check. + */ + init_cnt = (int)m_events.size(); + + /* Read until STOP_CAPTURE */ + while(m_ctrl == START_CAPTURE) { + runtime_id_t rid; + sequence_t seq; + internal_event_t event; + string source, evt_str; + + if ((rc = zmq_message_read(cap_sub_sock, 0, source, event)) != 0) { + /* + * The capture socket captures SUBSCRIBE requests too. + * The messge could contain subscribe filter strings and binary code. + * Empty string with binary code will fail to deserialize. + * Else would fail event validation. + */ + RET_ON_ERR((rc == EAGAIN) || (rc == ERR_MESSAGE_INVALID), + "0:Failed to read from capture socket"); + continue; + } + if (!validate_event(event, rid, seq)) { + continue; + } + serialize(event, evt_str); + + switch(cap_state) { + case CAP_STATE_INIT: + /* + * In this state check against cache, if duplicate + * When duplicate or new one seen, remove the entry from pre-exist map + * Stay in this state, until the pre-exist cache is empty or as many + * messages as in cache are seen, as in worst case even if you see + * duplicate of each, it will end with first m_events.size() + */ + { + bool add = true; + init_cnt--; + pre_exist_id_t::iterator it = m_pre_exist_id.find(rid); + + if (it != m_pre_exist_id.end()) { + if (seq <= it->second) { + /* Duplicate; Later/same seq in cache. */ + add = false; + } + if (seq >= it->second) { + /* new one; This runtime ID need not be checked again */ + m_pre_exist_id.erase(it); + } + } + if (add) { + m_events.push_back(evt_str); + } + } + if(m_pre_exist_id.empty() || (init_cnt <= 0)) { + /* Init check is no more needed. */ + pre_exist_id_t().swap(m_pre_exist_id); + cap_state = CAP_STATE_ACTIVE; + } + break; + + case CAP_STATE_ACTIVE: + /* Save until max allowed */ + try + { + m_events.push_back(evt_str); + if (VEC_SIZE(m_events) >= m_cache_max) { + cap_state = CAP_STATE_LAST; + /* Clear the map, created to ensure memory space available */ + m_last_events.clear(); + m_last_events_init = true; + } + break; + } + catch (bad_alloc& e) + { + stringstream ss; + ss << e.what(); + SWSS_LOG_ERROR("Cache save event failed with %s events:size=%d", + ss.str().c_str(), VEC_SIZE(m_events)); + cap_state = CAP_STATE_LAST; + // fall through to save this event in last set. + } + + case CAP_STATE_LAST: + total_overflow++; + m_last_events[rid] = evt_str; + if (total_overflow > m_last_events.size()) { + m_total_missed_cache++; + m_stats_instance->increment_missed_cache(1); + } + break; + } + } + +out: + /* + * Capture stop will close the socket which fail the read + * and hence bail out. + */ + zmq_close(cap_sub_sock); + m_cap_run = false; + return; +} + + +int +capture_service::set_control(capture_control_t ctrl, event_serialized_lst_t *lst) +{ + int ret = -1; + + /* Can go in single step only. */ + RET_ON_ERR((ctrl - m_ctrl) == 1, "m_ctrl(%d)+1 < ctrl(%d)", m_ctrl, ctrl); + + switch(ctrl) { + case INIT_CAPTURE: + m_thr = thread(&capture_service::do_capture, this); + for(int i=0; !m_cap_run && (i < 100); ++i) { + /* Wait max a second for thread to init */ + this_thread::sleep_for(chrono::milliseconds(10)); + } + RET_ON_ERR(m_cap_run, "Failed to init capture"); + m_ctrl = ctrl; + ret = 0; + break; + + case START_CAPTURE: + + /* + * Reserve a MAX_PUBLISHERS_COUNT entries for last events, as we use it only + * upon m_events/vector overflow, which might block adding new entries in map + * if overall mem consumption is too high. Clearing the map just before use + * is likely to help. + */ + for (int i=0; iempty())) { + init_capture_cache(*lst); + } + m_ctrl = ctrl; + ret = 0; + break; + + + case STOP_CAPTURE: + /* + * Caller would have initiated SUBS channel. + * Read for CACHE_DRAIN_IN_MILLISECS to drain off cache + * before stopping. + */ + this_thread::sleep_for(chrono::milliseconds(CACHE_DRAIN_IN_MILLISECS)); + stop_capture(); + ret = 0; + break; + + default: + SWSS_LOG_ERROR("Unexpected code=%d", ctrl); + break; + } +out: + return ret; +} + +int +capture_service::read_cache(event_serialized_lst_t &lst_fifo, + last_events_t &lst_last, counters_t &overflow_cnt) +{ + lst_fifo.swap(m_events); + if (m_last_events_init) { + lst_last.swap(m_last_events); + } else { + last_events_t().swap(lst_last); + } + last_events_t().swap(m_last_events); + event_serialized_lst_t().swap(m_events); + overflow_cnt = m_total_missed_cache; + return 0; +} + +static int +process_options(stats_collector *stats, const event_serialized_lst_t &req_data, + event_serialized_lst_t &resp_data) +{ + int ret = -1; + if (!req_data.empty()) { + RET_ON_ERR(req_data.size() == 1, "Expect only one options string %d", + (int)req_data.size()); + const auto &data = nlohmann::json::parse(*(req_data.begin())); + RET_ON_ERR(data.size() == 1, "Only one supported option. Expect 1. size=%d", + (int)data.size()); + const auto it = data.find(GLOBAL_OPTION_HEARTBEAT); + RET_ON_ERR(it != data.end(), "Expect HEARTBEAT_INTERVAL; got %s", + data.begin().key().c_str()); + stats->set_heartbeat_interval(it.value()); + ret = 0; + } + else { + nlohmann::json msg = nlohmann::json::object(); + msg[GLOBAL_OPTION_HEARTBEAT] = stats->get_heartbeat_interval(); + resp_data.push_back(msg.dump()); + ret = 0; + } +out: + return ret; +} + + +void +run_eventd_service() +{ + int code = 0; + int cache_max; + event_service service; + stats_collector stats_instance; + eventd_proxy *proxy = NULL; + capture_service *capture = NULL; + + event_serialized_lst_t capture_fifo_events; + last_events_t capture_last_events; + + SWSS_LOG_INFO("Eventd service starting\n"); + + void *zctx = zmq_ctx_new(); + RET_ON_ERR(zctx != NULL, "Failed to get zmq ctx"); + + cache_max = get_config_data(string(CACHE_MAX_CNT), (int)MAX_CACHE_SIZE); + RET_ON_ERR(cache_max > 0, "Failed to get CACHE_MAX_CNT"); + + proxy = new eventd_proxy(zctx); + RET_ON_ERR(proxy != NULL, "Failed to create proxy"); + + RET_ON_ERR(proxy->init() == 0, "Failed to init proxy"); + + RET_ON_ERR(service.init_server(zctx) == 0, "Failed to init service"); + + RET_ON_ERR(stats_instance.start() == 0, "Failed to start stats collector"); + + /* Pause heartbeat during caching */ + stats_instance.heartbeat_ctrl(true); + + /* + * Start cache service, right upon eventd starts so as not to lose + * events until telemetry starts. + * Telemetry will send a stop & collect cache upon startup + */ + capture = new capture_service(zctx, cache_max, &stats_instance); + RET_ON_ERR(capture->set_control(INIT_CAPTURE) == 0, "Failed to init capture"); + RET_ON_ERR(capture->set_control(START_CAPTURE) == 0, "Failed to start capture"); + + this_thread::sleep_for(chrono::milliseconds(200)); + RET_ON_ERR(stats_instance.is_running(), "Failed to start stats instance"); + + while(code != EVENT_EXIT) { + int resp = -1; + event_serialized_lst_t req_data, resp_data; + + RET_ON_ERR(service.channel_read(code, req_data) == 0, + "Failed to read request"); + + switch(code) { + case EVENT_CACHE_INIT: + /* connect only*/ + if (capture != NULL) { + delete capture; + } + event_serialized_lst_t().swap(capture_fifo_events); + last_events_t().swap(capture_last_events); + + capture = new capture_service(zctx, cache_max, &stats_instance); + if (capture != NULL) { + resp = capture->set_control(INIT_CAPTURE); + } + break; + + + case EVENT_CACHE_START: + if (capture == NULL) { + SWSS_LOG_ERROR("Cache is not initialized to start"); + resp = -1; + break; + } + /* Pause heartbeat during caching */ + stats_instance.heartbeat_ctrl(true); + + resp = capture->set_control(START_CAPTURE, &req_data); + break; + + + case EVENT_CACHE_STOP: + if (capture == NULL) { + SWSS_LOG_ERROR("Cache is not initialized to stop"); + resp = -1; + break; + } + resp = capture->set_control(STOP_CAPTURE); + if (resp == 0) { + counters_t overflow; + resp = capture->read_cache(capture_fifo_events, capture_last_events, + overflow); + } + delete capture; + capture = NULL; + + /* Unpause heartbeat upon stop caching */ + stats_instance.heartbeat_ctrl(); + break; + + + case EVENT_CACHE_READ: + if (capture != NULL) { + SWSS_LOG_ERROR("Cache is not stopped yet."); + resp = -1; + break; + } + resp = 0; + + if (capture_fifo_events.empty()) { + for (last_events_t::iterator it = capture_last_events.begin(); + it != capture_last_events.end(); ++it) { + capture_fifo_events.push_back(it->second); + } + last_events_t().swap(capture_last_events); + } + + { + int sz = VEC_SIZE(capture_fifo_events) < READ_SET_SIZE ? + VEC_SIZE(capture_fifo_events) : READ_SET_SIZE; + + if (sz != 0) { + auto it = std::next(capture_fifo_events.begin(), sz); + move(capture_fifo_events.begin(), capture_fifo_events.end(), + back_inserter(resp_data)); + + if (sz == VEC_SIZE(capture_fifo_events)) { + event_serialized_lst_t().swap(capture_fifo_events); + } else { + capture_fifo_events.erase(capture_fifo_events.begin(), it); + } + } + } + break; + + + case EVENT_ECHO: + resp = 0; + resp_data.swap(req_data); + break; + + case EVENT_OPTIONS: + resp = process_options(&stats_instance, req_data, resp_data); + break; + + case EVENT_EXIT: + resp = 0; + break; + + default: + SWSS_LOG_ERROR("Unexpected request: %d", code); + assert(false); + break; + } + RET_ON_ERR(service.channel_write(resp, resp_data) == 0, + "Failed to write response back"); + } +out: + service.close_service(); + stats_instance.stop(); + + if (proxy != NULL) { + delete proxy; + } + if (capture != NULL) { + delete capture; + } + if (zctx != NULL) { + zmq_ctx_term(zctx); + } + SWSS_LOG_ERROR("Eventd service exiting\n"); +} + +void set_unit_testing(bool b) +{ + s_unit_testing = b; +} + + diff --git a/src/sonic-eventd/src/eventd.h b/src/sonic-eventd/src/eventd.h new file mode 100644 index 000000000000..8411223b35be --- /dev/null +++ b/src/sonic-eventd/src/eventd.h @@ -0,0 +1,268 @@ +/* + * Header file for eventd daemon + */ +#include "table.h" +#include "events_service.h" +#include "events.h" +#include "events_wrap.h" + +#define ARRAY_SIZE(l) (sizeof(l)/sizeof((l)[0])) + +typedef map last_events_t; + +/* stat counters */ +typedef uint64_t counters_t; + +typedef enum { + INDEX_COUNTERS_EVENTS_PUBLISHED, + INDEX_COUNTERS_EVENTS_MISSED_CACHE, + COUNTERS_EVENTS_TOTAL +} stats_counter_index_t; + +#define EVENTS_STATS_FIELD_NAME "value" +#define STATS_HEARTBEAT_MIN 300 + +/* + * Started by eventd_service. + * Creates XPUB & XSUB end points. + * Bind the same + * Create a PUB socket end point for capture and bind. + * Call run_proxy method with sockets in a dedicated thread. + * Thread runs forever until the zmq context is terminated. + */ +class eventd_proxy +{ + public: + eventd_proxy(void *ctx) : m_ctx(ctx), m_frontend(NULL), m_backend(NULL), + m_capture(NULL) {}; + + ~eventd_proxy() { + zmq_close(m_frontend); + zmq_close(m_backend); + zmq_close(m_capture); + + if (m_thr.joinable()) + m_thr.join(); + } + + int init(); + + private: + void run(); + + void *m_ctx; + void *m_frontend; + void *m_backend; + void *m_capture; + thread m_thr; +}; + + +class stats_collector +{ + public: + stats_collector(); + + ~stats_collector() { stop(); } + + int start(); + + void stop() { + + m_shutdown = true; + + if (m_thr_collector.joinable()) { + m_thr_collector.join(); + } + + if (m_thr_writer.joinable()) { + m_thr_writer.join(); + } + } + + void increment_published(counters_t val) { + _update_stats(INDEX_COUNTERS_EVENTS_PUBLISHED, val); + } + + void increment_missed_cache(counters_t val) { + _update_stats(INDEX_COUNTERS_EVENTS_MISSED_CACHE, val); + } + + counters_t read_counter(stats_counter_index_t index) { + if (index != COUNTERS_EVENTS_TOTAL) { + return m_lst_counters[index]; + } + else { + return 0; + } + } + + /* Sets heartbeat interval in milliseconds */ + void set_heartbeat_interval(int val_in_ms); + + /* + * Get heartbeat interval in milliseconds + * NOTE: Set & get value may not match as the value is rounded + * to a multiple of smallest possible interval. + */ + int get_heartbeat_interval(); + + /* A way to pause heartbeat */ + void heartbeat_ctrl(bool pause = false) { + m_pause_heartbeat = pause; + SWSS_LOG_INFO("Set heartbeat_ctrl pause=%d", pause); + } + + uint64_t heartbeats_published() const { + return m_heartbeats_published; + } + + bool is_running() + { + return !m_shutdown; + } + + private: + void _update_stats(stats_counter_index_t index, counters_t val) { + if (index != COUNTERS_EVENTS_TOTAL) { + m_lst_counters[index] += val; + m_updated = true; + } + else { + SWSS_LOG_ERROR("Internal code error. Invalid index=%d", index); + } + } + + void run_collector(); + + void run_writer(); + + atomic m_updated; + + counters_t m_lst_counters[COUNTERS_EVENTS_TOTAL]; + + bool m_shutdown; + + thread m_thr_collector; + thread m_thr_writer; + + shared_ptr m_counters_db; + shared_ptr m_stats_table; + + bool m_pause_heartbeat; + + uint64_t m_heartbeats_published; + + int m_heartbeats_interval_cnt; +}; + +/* + * Capture/Cache service + * + * The service started in a dedicted thread upon demand. + * It is controlled by the caller. + * On cache init, the thread is created. + * Upon create, it creates a SUB socket to PUB end point of capture. + * PUB end point is maintained by zproxy service. + * + * On Cache start, the thread is signalled to start reading. + * + * On cache stop, it is signalled to stop reading and exit. Caller waits + * for thread to exit, before starting to read cached data, to ensure + * that the data is not handled by two threads concurrently. + * + * This thread maintains its own copy of cache. Reader, does a swap + * after thread exits. + * This thread ensures the cache is empty at the init. + * + * Upon cache start, the thread is blocked in receive call with timeout. + * Only upon receive/timeout, it would notice stop signal. Hence stop + * is not synchronous. The caller may wait for thread to terminate + * via thread.join(). + * + * Each event is 2 parts. It drops the first part, which is + * more for filtering events. It creates string from second part + * and saves it. + * + * The string is the serialized version of internal_event_ref + * + * It keeps two sets of data + * 1) List of all events received in vector in same order as received + * 2) Map of last event from each runtime id upon list overflow max size. + * + * We add to the vector as much as allowed by vector and max limit, + * whichever comes first. + * + * The sequence number in internal event will help assess the missed count + * by the consumer of the cache data. + * + */ +typedef enum { + NEED_INIT = 0, + INIT_CAPTURE, + START_CAPTURE, + STOP_CAPTURE +} capture_control_t; + + +class capture_service +{ + public: + capture_service(void *ctx, int cache_max, stats_collector *stats) : + m_ctx(ctx), m_stats_instance(stats), m_cap_run(false), + m_ctrl(NEED_INIT), m_cache_max(cache_max), + m_last_events_init(false), m_total_missed_cache(0) + {} + + ~capture_service(); + + int set_control(capture_control_t ctrl, event_serialized_lst_t *p=NULL); + + int read_cache(event_serialized_lst_t &lst_fifo, + last_events_t &lst_last, counters_t &overflow_cnt); + + private: + void init_capture_cache(const event_serialized_lst_t &lst); + void do_capture(); + + void stop_capture(); + + void *m_ctx; + stats_collector *m_stats_instance; + + bool m_cap_run; + capture_control_t m_ctrl; + thread m_thr; + + int m_cache_max; + + event_serialized_lst_t m_events; + + last_events_t m_last_events; + bool m_last_events_init; + + typedef map pre_exist_id_t; + pre_exist_id_t m_pre_exist_id; + + counters_t m_total_missed_cache; + +}; + + +/* + * Main server, that starts the zproxy service and honor + * eventd service requests event_req_type_t + * + * For echo, it just echoes + * + * FOr cache start, create the SUB end of capture and kick off + * capture_events thread. Upon cache stop command, close the handle + * which will stop the caching thread with read failure. + * + * for cache read, returns the collected events in chunks. + * + */ +void run_eventd_service(); + +/* To help skip redis access during unit testing */ +void set_unit_testing(bool b); diff --git a/src/sonic-eventd/src/main.cpp b/src/sonic-eventd/src/main.cpp new file mode 100644 index 000000000000..7a20497f0986 --- /dev/null +++ b/src/sonic-eventd/src/main.cpp @@ -0,0 +1,18 @@ +#include "logger.h" +#include "eventd.h" + +void run_eventd_service(); + +int main() +{ + swss::Logger::setMinPrio(swss::Logger::SWSS_DEBUG); + SWSS_LOG_INFO("The eventd service started"); + SWSS_LOG_ERROR("ERR:The eventd service started"); + + run_eventd_service(); + + SWSS_LOG_INFO("The eventd service exited"); + + return 0; +} + diff --git a/src/sonic-eventd/src/subdir.mk b/src/sonic-eventd/src/subdir.mk new file mode 100644 index 000000000000..a1e2b55f8d13 --- /dev/null +++ b/src/sonic-eventd/src/subdir.mk @@ -0,0 +1,13 @@ +CC := g++ + +TEST_OBJS += ./src/eventd.o +OBJS += ./src/eventd.o ./src/main.o + +C_DEPS += ./src/eventd.d ./src/main.d + +src/%.o: src/%.cpp + @echo 'Building file: $<' + @echo 'Invoking: GCC C++ Compiler' + $(CC) -D__FILENAME__="$(subst src/,,$<)" $(CFLAGS) -c -fmessage-length=0 -MMD -MP -MF"$(@:%.o=%.d)" -MT"$(@)" -o "$@" "$<" + @echo 'Finished building: $<' + @echo ' ' diff --git a/src/sonic-eventd/tests/eventd_ut.cpp b/src/sonic-eventd/tests/eventd_ut.cpp new file mode 100644 index 000000000000..399255edb2b8 --- /dev/null +++ b/src/sonic-eventd/tests/eventd_ut.cpp @@ -0,0 +1,915 @@ +#include +#include +#include +#include +#include +#include +#include +#include "gtest/gtest.h" +#include "events_common.h" +#include "events.h" +#include "../src/eventd.h" + +using namespace std; +using namespace swss; + +extern bool g_is_redis_available; +extern const char *counter_keys[]; + +typedef struct { + int id; + string source; + string tag; + string rid; + string seq; + event_params_t params; + int missed_cnt; +} test_data_t; + +internal_event_t create_ev(const test_data_t &data) +{ + internal_event_t event_data; + + event_data[EVENT_STR_DATA] = convert_to_json( + data.source + ":" + data.tag, data.params); + event_data[EVENT_RUNTIME_ID] = data.rid; + event_data[EVENT_SEQUENCE] = data.seq; + + return event_data; +} + +/* Mock test data with event parameters and expected missed count */ +static const test_data_t ldata[] = { + { + 0, + "source0", + "tag0", + "guid-0", + "1", + {{"ip", "10.10.10.10"}, {"state", "up"}}, + 0 + }, + { + 1, + "source0", + "tag1", + "guid-1", + "100", + {{"ip", "10.10.27.10"}, {"state", "down"}}, + 0 + }, + { + 2, + "source1", + "tag2", + "guid-2", + "101", + {{"ip", "10.10.24.10"}, {"state", "down"}}, + 0 + }, + { + 3, + "source0", + "tag3", + "guid-1", + "105", + {{"ip", "10.10.10.10"}, {"state", "up"}}, + 4 + }, + { + 4, + "source0", + "tag4", + "guid-0", + "2", + {{"ip", "10.10.20.10"}, {"state", "down"}}, + 0 + }, + { + 5, + "source1", + "tag5", + "guid-2", + "110", + {{"ip", "10.10.24.10"}, {"state", "down"}}, + 8 + }, + { + 6, + "source0", + "tag0", + "guid-0", + "5", + {{"ip", "10.10.10.10"}, {"state", "up"}}, + 2 + }, + { + 7, + "source0", + "tag1", + "guid-1", + "106", + {{"ip", "10.10.27.10"}, {"state", "down"}}, + 0 + }, + { + 8, + "source1", + "tag2", + "guid-2", + "111", + {{"ip", "10.10.24.10"}, {"state", "down"}}, + 0 + }, + { + 9, + "source0", + "tag3", + "guid-1", + "109", + {{"ip", "10.10.10.10"}, {"state", "up"}}, + 2 + }, + { + 10, + "source0", + "tag4", + "guid-0", + "6", + {{"ip", "10.10.20.10"}, {"state", "down"}}, + 0 + }, + { + 11, + "source1", + "tag5", + "guid-2", + "119", + {{"ip", "10.10.24.10"}, {"state", "down"}}, + 7 + }, +}; + + +void run_cap(void *zctx, bool &term, string &read_source, + int &cnt) +{ + void *mock_cap = zmq_socket (zctx, ZMQ_SUB); + string source; + internal_event_t ev_int; + int block_ms = 200; + int i=0; + + EXPECT_TRUE(NULL != mock_cap); + EXPECT_EQ(0, zmq_connect(mock_cap, get_config(CAPTURE_END_KEY).c_str())); + EXPECT_EQ(0, zmq_setsockopt(mock_cap, ZMQ_SUBSCRIBE, "", 0)); + EXPECT_EQ(0, zmq_setsockopt(mock_cap, ZMQ_RCVTIMEO, &block_ms, sizeof (block_ms))); + + while(!term) { + string source; + internal_event_t ev_int; + + if (0 == zmq_message_read(mock_cap, 0, source, ev_int)) { + cnt = ++i; + } + } + zmq_close(mock_cap); +} + +void run_sub(void *zctx, bool &term, string &read_source, internal_events_lst_t &lst, + int &cnt) +{ + void *mock_sub = zmq_socket (zctx, ZMQ_SUB); + string source; + internal_event_t ev_int; + int block_ms = 200; + + EXPECT_TRUE(NULL != mock_sub); + EXPECT_EQ(0, zmq_connect(mock_sub, get_config(XPUB_END_KEY).c_str())); + EXPECT_EQ(0, zmq_setsockopt(mock_sub, ZMQ_SUBSCRIBE, "", 0)); + EXPECT_EQ(0, zmq_setsockopt(mock_sub, ZMQ_RCVTIMEO, &block_ms, sizeof (block_ms))); + + while(!term) { + if (0 == zmq_message_read(mock_sub, 0, source, ev_int)) { + lst.push_back(ev_int); + read_source.swap(source); + cnt = (int)lst.size(); + } + } + + zmq_close(mock_sub); +} + +void *init_pub(void *zctx) +{ + void *mock_pub = zmq_socket (zctx, ZMQ_PUB); + EXPECT_TRUE(NULL != mock_pub); + EXPECT_EQ(0, zmq_connect(mock_pub, get_config(XSUB_END_KEY).c_str())); + + /* Provide time for async connect to complete */ + this_thread::sleep_for(chrono::milliseconds(200)); + + return mock_pub; +} + +void run_pub(void *mock_pub, const string wr_source, internal_events_lst_t &lst) +{ + for(internal_events_lst_t::const_iterator itc = lst.begin(); itc != lst.end(); ++itc) { + EXPECT_EQ(0, zmq_message_send(mock_pub, wr_source, *itc)); + } +} + + +TEST(eventd, proxy) +{ + printf("Proxy TEST started\n"); + bool term_sub = false; + bool term_cap = false; + string rd_csource, rd_source, wr_source("hello"); + internal_events_lst_t rd_evts, wr_evts; + int rd_evts_sz = 0, rd_cevts_sz = 0; + int wr_sz; + + void *zctx = zmq_ctx_new(); + EXPECT_TRUE(NULL != zctx); + + eventd_proxy *pxy = new eventd_proxy(zctx); + EXPECT_TRUE(NULL != pxy); + + /* Starting proxy */ + EXPECT_EQ(0, pxy->init()); + + /* subscriber in a thread */ + thread thr(&run_sub, zctx, ref(term_sub), ref(rd_source), ref(rd_evts), ref(rd_evts_sz)); + + /* capture in a thread */ + thread thrc(&run_cap, zctx, ref(term_cap), ref(rd_csource), ref(rd_cevts_sz)); + + /* Init pub connection */ + void *mock_pub = init_pub(zctx); + + EXPECT_TRUE(5 < ARRAY_SIZE(ldata)); + + for(int i=0; i<5; ++i) { + wr_evts.push_back(create_ev(ldata[i])); + } + + EXPECT_TRUE(rd_evts.empty()); + EXPECT_TRUE(rd_source.empty()); + + /* Publish events. */ + run_pub(mock_pub, wr_source, wr_evts); + + wr_sz = (int)wr_evts.size(); + for(int i=0; (wr_sz != rd_evts_sz) && (i < 100); ++i) { + /* Loop & wait for atmost a second */ + this_thread::sleep_for(chrono::milliseconds(10)); + } + this_thread::sleep_for(chrono::milliseconds(1000)); + + delete pxy; + pxy = NULL; + + term_sub = true; + term_cap = true; + + thr.join(); + thrc.join(); + EXPECT_EQ(rd_evts.size(), wr_evts.size()); + EXPECT_EQ(rd_cevts_sz, wr_evts.size()); + + zmq_close(mock_pub); + zmq_ctx_term(zctx); + + /* Provide time for async proxy removal to complete */ + this_thread::sleep_for(chrono::milliseconds(200)); + + printf("eventd_proxy is tested GOOD\n"); +} + + +TEST(eventd, capture) +{ + printf("Capture TEST started\n"); + + bool term_sub = false; + string sub_source; + int sub_evts_sz = 0; + internal_events_lst_t sub_evts; + stats_collector stats_instance; + + /* run_pub details */ + string wr_source("hello"); + internal_events_lst_t wr_evts; + + /* capture related */ + int init_cache = 3; /* provided along with start capture */ + int cache_max = init_cache + 3; /* capture service cache max */ + + /* startup strings; expected list & read list from capture */ + event_serialized_lst_t evts_start, evts_expect, evts_read; + last_events_t last_evts_exp, last_evts_read; + counters_t overflow, overflow_exp = 0; + + void *zctx = zmq_ctx_new(); + EXPECT_TRUE(NULL != zctx); + + /* Run the proxy; Capture service reads from proxy */ + eventd_proxy *pxy = new eventd_proxy(zctx); + EXPECT_TRUE(NULL != pxy); + + /* Starting proxy */ + EXPECT_EQ(0, pxy->init()); + + /* Run subscriber; Else publisher will drop events on floor, with no subscriber. */ + thread thr_sub(&run_sub, zctx, ref(term_sub), ref(sub_source), ref(sub_evts), ref(sub_evts_sz)); + + /* Create capture service */ + capture_service *pcap = new capture_service(zctx, cache_max, &stats_instance); + + /* Expect START_CAPTURE */ + EXPECT_EQ(-1, pcap->set_control(STOP_CAPTURE)); + + /* Initialize the capture */ + EXPECT_EQ(0, pcap->set_control(INIT_CAPTURE)); + + EXPECT_TRUE(init_cache > 1); + EXPECT_TRUE((cache_max+3) < (int)ARRAY_SIZE(ldata)); + + /* Collect few serailized strings of events for startup cache */ + for(int i=0; i < init_cache; ++i) { + internal_event_t ev(create_ev(ldata[i])); + string evt_str; + serialize(ev, evt_str); + evts_start.push_back(evt_str); + evts_expect.push_back(evt_str); + } + + /* + * Collect events to publish for capture to cache + * re-publishing some events sent in cache. + * Hence i=1, when first init_cache events are already + * in crash. + */ + for(int i=1; i < (int)ARRAY_SIZE(ldata); ++i) { + internal_event_t ev(create_ev(ldata[i])); + string evt_str; + + serialize(ev, evt_str); + + wr_evts.push_back(ev); + + if (i < cache_max) { + if (i >= init_cache) { + /* for i < init_cache, evts_expect is already populated */ + evts_expect.push_back(evt_str); + } + } else { + /* collect last entries for overflow */ + last_evts_exp[ldata[i].rid] = evt_str; + overflow_exp++; + } + } + overflow_exp -= (int)last_evts_exp.size(); + + EXPECT_EQ(0, pcap->set_control(START_CAPTURE, &evts_start)); + + /* Init pub connection */ + void *mock_pub = init_pub(zctx); + + /* Publish events from 1 to all. */ + run_pub(mock_pub, wr_source, wr_evts); + + /* Provide time for async message receive. */ + this_thread::sleep_for(chrono::milliseconds(200)); + + /* Stop capture, closes socket & terminates the thread */ + EXPECT_EQ(0, pcap->set_control(STOP_CAPTURE)); + + /* terminate subs thread */ + term_sub = true; + + /* Read the cache */ + EXPECT_EQ(0, pcap->read_cache(evts_read, last_evts_read, overflow)); + +#ifdef DEBUG_TEST + if ((evts_read.size() != evts_expect.size()) || + (last_evts_read.size() != last_evts_exp.size())) { + printf("size: sub_evts_sz=%d sub_evts=%d\n", sub_evts_sz, (int)sub_evts.size()); + printf("init_cache=%d cache_max=%d\n", init_cache, cache_max); + printf("overflow=%ul overflow_exp=%ul\n", overflow, overflow_exp); + printf("evts_start=%d evts_expect=%d evts_read=%d\n", + (int)evts_start.size(), (int)evts_expect.size(), (int)evts_read.size()); + printf("last_evts_exp=%d last_evts_read=%d\n", (int)last_evts_exp.size(), + (int)last_evts_read.size()); + } +#endif + + EXPECT_EQ(evts_read.size(), evts_expect.size()); + EXPECT_EQ(evts_read, evts_expect); + EXPECT_EQ(last_evts_read.size(), last_evts_exp.size()); + EXPECT_EQ(last_evts_read, last_evts_exp); + EXPECT_EQ(overflow, overflow_exp); + + delete pxy; + pxy = NULL; + + delete pcap; + pcap = NULL; + + thr_sub.join(); + + zmq_close(mock_pub); + zmq_ctx_term(zctx); + + /* Provide time for async proxy removal to complete */ + this_thread::sleep_for(chrono::milliseconds(200)); + + printf("Capture TEST completed\n"); +} + +TEST(eventd, captureCacheMax) +{ + printf("Capture TEST with matchinhg cache-max started\n"); + + /* + * Need to run subscriber; Else publisher would skip publishing + * in the absence of any subscriber. + */ + bool term_sub = false; + string sub_source; + int sub_evts_sz = 0; + internal_events_lst_t sub_evts; + stats_collector stats_instance; + + /* run_pub details */ + string wr_source("hello"); + internal_events_lst_t wr_evts; + + /* capture related */ + int init_cache = 4; /* provided along with start capture */ + int cache_max = ARRAY_SIZE(ldata); /* capture service cache max */ + + /* startup strings; expected list & read list from capture */ + event_serialized_lst_t evts_start, evts_expect, evts_read; + last_events_t last_evts_read; + counters_t overflow; + + void *zctx = zmq_ctx_new(); + EXPECT_TRUE(NULL != zctx); + + /* Run the proxy; Capture service reads from proxy */ + eventd_proxy *pxy = new eventd_proxy(zctx); + EXPECT_TRUE(NULL != pxy); + + /* Starting proxy */ + EXPECT_EQ(0, pxy->init()); + + /* Run subscriber; Else publisher will drop events on floor, with no subscriber. */ + thread thr_sub(&run_sub, zctx, ref(term_sub), ref(sub_source), ref(sub_evts), ref(sub_evts_sz)); + + /* Create capture service */ + capture_service *pcap = new capture_service(zctx, cache_max, &stats_instance); + + /* Expect START_CAPTURE */ + EXPECT_EQ(-1, pcap->set_control(STOP_CAPTURE)); + + EXPECT_TRUE(init_cache > 1); + + /* Collect few serailized strings of events for startup cache */ + for(int i=0; i < init_cache; ++i) { + internal_event_t ev(create_ev(ldata[i])); + string evt_str; + serialize(ev, evt_str); + evts_start.push_back(evt_str); + evts_expect.push_back(evt_str); + } + + /* + * Collect events to publish for capture to cache + * re-publishing some events sent in cache. + */ + for(int i=1; i < (int)ARRAY_SIZE(ldata); ++i) { + internal_event_t ev(create_ev(ldata[i])); + string evt_str; + + serialize(ev, evt_str); + + wr_evts.push_back(ev); + + if (i >= init_cache) { + /* for i < init_cache, evts_expect is already populated */ + evts_expect.push_back(evt_str); + } + } + + EXPECT_EQ(0, pcap->set_control(INIT_CAPTURE)); + EXPECT_EQ(0, pcap->set_control(START_CAPTURE, &evts_start)); + + /* Init pub connection */ + void *mock_pub = init_pub(zctx); + + /* Publish events from 1 to all. */ + run_pub(mock_pub, wr_source, wr_evts); + + /* Provide time for async message receive. */ + this_thread::sleep_for(chrono::milliseconds(100)); + + /* Stop capture, closes socket & terminates the thread */ + EXPECT_EQ(0, pcap->set_control(STOP_CAPTURE)); + + /* terminate subs thread */ + term_sub = true; + + /* Read the cache */ + EXPECT_EQ(0, pcap->read_cache(evts_read, last_evts_read, overflow)); + +#ifdef DEBUG_TEST + if ((evts_read.size() != evts_expect.size()) || + !last_evts_read.empty()) { + printf("size: sub_evts_sz=%d sub_evts=%d\n", sub_evts_sz, (int)sub_evts.size()); + printf("init_cache=%d cache_max=%d\n", init_cache, cache_max); + printf("evts_start=%d evts_expect=%d evts_read=%d\n", + (int)evts_start.size(), (int)evts_expect.size(), (int)evts_read.size()); + printf("last_evts_read=%d\n", (int)last_evts_read.size()); + printf("overflow=%ul overflow_exp=%ul\n", overflow, overflow_exp); + } +#endif + + EXPECT_EQ(evts_read, evts_expect); + EXPECT_TRUE(last_evts_read.empty()); + EXPECT_EQ(overflow, 0); + + delete pxy; + pxy = NULL; + + delete pcap; + pcap = NULL; + + thr_sub.join(); + + zmq_close(mock_pub); + zmq_ctx_term(zctx); + + /* Provide time for async proxy removal to complete */ + this_thread::sleep_for(chrono::milliseconds(200)); + + printf("Capture TEST with matchinhg cache-max completed\n"); +} + +TEST(eventd, service) +{ + /* + * Don't PUB/SUB events as main run_eventd_service itself + * is using zmq_message_read. Any PUB/SUB will cause + * eventd's do_capture running in another thread to call + * zmq_message_read, which will crash as boost:archive is + * not thread safe. + * TEST(eventd, capture) has already tested caching. + */ + printf("Service TEST started\n"); + + /* startup strings; expected list & read list from capture */ + event_service service; + + void *zctx = zmq_ctx_new(); + EXPECT_TRUE(NULL != zctx); + + /* + * Start the eventd server side service + * It runs proxy & capture service + * It uses its own zmq context + * It starts to capture too. + */ + + if (!g_is_redis_available) { + set_unit_testing(true); + } + + thread thread_service(&run_eventd_service); + + /* Need client side service to interact with server side */ + EXPECT_EQ(0, service.init_client(zctx)); + + { + /* eventd_service starts cache too; Test this caching */ + /* Init pub connection */ + void *mock_pub = init_pub(zctx); + EXPECT_TRUE(NULL != mock_pub); + + internal_events_lst_t wr_evts; + int wr_sz = 2; + string wr_source("hello"); + + /* Test service startup caching */ + event_serialized_lst_t evts_start, evts_read; + + for(int i=0; i evts_start_int; + + EXPECT_TRUE(init_cache > 1); + + /* Collect few serailized strings of events for startup cache */ + for(int i=0; i < init_cache; ++i) { + internal_event_t ev(create_ev(ldata[i])); + string evt_str; + serialize(ev, evt_str); + evts_start.push_back(evt_str); + evts_start_int.push_back(ev); + } + + + EXPECT_EQ(0, service.cache_init()); + EXPECT_EQ(0, service.cache_start(evts_start)); + + this_thread::sleep_for(chrono::milliseconds(200)); + + /* Stop capture, closes socket & terminates the thread */ + EXPECT_EQ(0, service.cache_stop()); + + /* Read the cache */ + EXPECT_EQ(0, service.cache_read(evts_read)); + + if (evts_read != evts_start) { + vector evts_read_int; + + for (event_serialized_lst_t::const_iterator itc = evts_read.begin(); + itc != evts_read.end(); ++itc) { + internal_event_t event; + + if (deserialize(*itc, event) == 0) { + evts_read_int.push_back(event); + } + } + EXPECT_EQ(evts_read_int, evts_start_int); + } + } + + { + string set_opt_bad("{\"HEARTBEAT_INTERVAL\": 2000, \"OFFLINE_CACHE_SIZE\": 500}"); + string set_opt_good("{\"HEARTBEAT_INTERVAL\":5}"); + char buff[100]; + buff[0] = 0; + + EXPECT_EQ(-1, service.global_options_set(set_opt_bad.c_str())); + EXPECT_EQ(0, service.global_options_set(set_opt_good.c_str())); + EXPECT_LT(0, service.global_options_get(buff, sizeof(buff))); + + EXPECT_EQ(set_opt_good, string(buff)); + } + + EXPECT_EQ(0, service.send_recv(EVENT_EXIT)); + + service.close_service(); + + thread_service.join(); + + zmq_ctx_term(zctx); + printf("Service TEST completed\n"); +} + + +void +wait_for_heartbeat(stats_collector &stats_instance, long unsigned int cnt, + int wait_ms = 3000) +{ + int diff = 0; + + auto st = duration_cast(system_clock::now().time_since_epoch()).count(); + while (stats_instance.heartbeats_published() == cnt) { + auto en = duration_cast(system_clock::now().time_since_epoch()).count(); + diff = en - st; + if (diff > wait_ms) { + EXPECT_LE(diff, wait_ms); + EXPECT_EQ(cnt, stats_instance.heartbeats_published()); + break; + } + else { + stringstream ss; + ss << (en -st); + } + this_thread::sleep_for(chrono::milliseconds(300)); + } +} + +TEST(eventd, heartbeat) +{ + printf("heartbeat TEST started\n"); + + int rc; + long unsigned int cnt; + stats_collector stats_instance; + + if (!g_is_redis_available) { + set_unit_testing(true); + } + + void *zctx = zmq_ctx_new(); + EXPECT_TRUE(NULL != zctx); + + eventd_proxy *pxy = new eventd_proxy(zctx); + EXPECT_TRUE(NULL != pxy); + + /* Starting proxy */ + EXPECT_EQ(0, pxy->init()); + + rc = stats_instance.start(); + EXPECT_EQ(rc, 0); + + /* Wait for any non-zero heartbeat */ + wait_for_heartbeat(stats_instance, 0); + + /* Pause heartbeat */ + stats_instance.heartbeat_ctrl(true); + + /* Sleep to ensure the other thread noticed the pause request. */ + this_thread::sleep_for(chrono::milliseconds(200)); + + /* Get current count */ + cnt = stats_instance.heartbeats_published(); + + /* Wait for 3 seconds with no new neartbeat */ + this_thread::sleep_for(chrono::seconds(3)); + + EXPECT_EQ(stats_instance.heartbeats_published(), cnt); + + /* Set interval as 1 second */ + stats_instance.set_heartbeat_interval(1); + + /* Turn on heartbeat */ + stats_instance.heartbeat_ctrl(); + + /* Wait for heartbeat count to change from last count */ + wait_for_heartbeat(stats_instance, cnt, 2000); + + stats_instance.stop(); + + delete pxy; + + zmq_ctx_term(zctx); + + printf("heartbeat TEST completed\n"); +} + + +TEST(eventd, testDB) +{ + printf("DB TEST started\n"); + + /* consts used */ + const int pub_count = 7; + const int cache_max = 3; + + stats_collector stats_instance; + event_handle_t pub_handle; + event_serialized_lst_t evts_read; + last_events_t last_evts_read; + counters_t overflow; + string tag; + + if (!g_is_redis_available) { + printf("redis not available; Hence DB TEST skipped\n"); + return; + } + + EXPECT_LT(cache_max, pub_count); + DBConnector db("COUNTERS_DB", 0, true); + + + /* Not testing heartbeat; Hence set high val as 10 seconds */ + stats_instance.set_heartbeat_interval(10000); + + /* Start instance to capture published count & as well writes to DB */ + EXPECT_EQ(0, stats_instance.start()); + + void *zctx = zmq_ctx_new(); + EXPECT_TRUE(NULL != zctx); + + /* Run proxy to enable receive as capture test needs to receive */ + eventd_proxy *pxy = new eventd_proxy(zctx); + EXPECT_TRUE(NULL != pxy); + + /* Starting proxy */ + EXPECT_EQ(0, pxy->init()); + + /* Create capture service */ + capture_service *pcap = new capture_service(zctx, cache_max, &stats_instance); + + /* Initialize the capture */ + EXPECT_EQ(0, pcap->set_control(INIT_CAPTURE)); + + /* Kick off capture */ + EXPECT_EQ(0, pcap->set_control(START_CAPTURE)); + + pub_handle = events_init_publisher("test_db"); + + for(int i=0; i < pub_count; ++i) { + tag = string("test_db_tag_") + to_string(i); + event_publish(pub_handle, tag); + } + + /* Pause to ensure all publisghed events did reach capture service */ + this_thread::sleep_for(chrono::milliseconds(200)); + + EXPECT_EQ(0, pcap->set_control(STOP_CAPTURE)); + + /* Read the cache */ + EXPECT_EQ(0, pcap->read_cache(evts_read, last_evts_read, overflow)); + + /* + * Sent pub_count messages of different tags. + * Upon cache max, only event per sender/runtime-id is saved. Hence + * expected last_evts_read is one. + * expected overflow = pub_count - cache_max - 1 + */ + + EXPECT_EQ(cache_max, (int)evts_read.size()); + EXPECT_EQ(1, (int)last_evts_read.size()); + EXPECT_EQ((pub_count - cache_max - 1), overflow); + + EXPECT_EQ(pub_count, stats_instance.read_counter( + INDEX_COUNTERS_EVENTS_PUBLISHED)); + EXPECT_EQ((pub_count - cache_max - 1), stats_instance.read_counter( + INDEX_COUNTERS_EVENTS_MISSED_CACHE)); + + events_deinit_publisher(pub_handle); + + for (int i=0; i < COUNTERS_EVENTS_TOTAL; ++i) { + string key = string("COUNTERS_EVENTS:") + counter_keys[i]; + unordered_map m; + bool key_found = false, val_found=false, val_match=false; + + if (db.exists(key)) { + try { + m = db.hgetall(key); + unordered_map::const_iterator itc = + m.find(string(EVENTS_STATS_FIELD_NAME)); + if (itc != m.end()) { + int expect = (counter_keys[i] == string(COUNTERS_EVENTS_PUBLISHED) ? + pub_count : (pub_count - cache_max - 1)); + val_match = (expect == stoi(itc->second) ? true : false); + val_found = true; + } + } + catch (exception &e) + { + printf("Failed to get key=(%s) err=(%s)", key.c_str(), e.what()); + EXPECT_TRUE(false); + } + key_found = true; + } + + if (!val_match) { + printf("key=%s key_found=%d val_found=%d fields=%d", + key.c_str(), key_found, val_found, (int)m.size()); + + printf("hgetall BEGIN key=%s", key.c_str()); + for(unordered_map::const_iterator itc = m.begin(); + itc != m.end(); ++itc) { + printf("val[%s] = (%s)", itc->first.c_str(), itc->second.c_str()); + } + printf("hgetall END\n"); + EXPECT_TRUE(false); + } + } + + stats_instance.stop(); + + delete pxy; + delete pcap; + + zmq_ctx_term(zctx); + + printf("DB TEST completed\n"); +} + + +// TODO -- Add unit tests for stats diff --git a/src/sonic-eventd/tests/main.cpp b/src/sonic-eventd/tests/main.cpp new file mode 100644 index 000000000000..4b869e8c3004 --- /dev/null +++ b/src/sonic-eventd/tests/main.cpp @@ -0,0 +1,97 @@ +#include "gtest/gtest.h" +#include "dbconnector.h" +#include + +using namespace std; +using namespace swss; + +string existing_file = "./tests/redis_multi_db_ut_config/database_config.json"; +string nonexisting_file = "./tests/redis_multi_db_ut_config/database_config_nonexisting.json"; +string global_existing_file = "./tests/redis_multi_db_ut_config/database_global.json"; + +#define TEST_DB "APPL_DB" +#define TEST_NAMESPACE "asic0" +#define INVALID_NAMESPACE "invalid" + +bool g_is_redis_available = false; + +class SwsscommonEnvironment : public ::testing::Environment { +public: + // Override this to define how to set up the environment + void SetUp() override { + // by default , init should be false + cout<<"Default : isInit = "<:tag\n") + return sourceTag + +def getFVMFromParams(params): + param_dict = FieldValueMap() + for key, value in params.items(): + key = str(key) + value = str(value) + param_dict[key] = value + return param_dict + +def publishEvents(line, publisher_handle): + try: + json_dict = json.loads(line) + except Exception as ex: + logging.error("JSON string not able to be parsed\n") + return + if not json_dict or len(json_dict) != 1: + logging.error("JSON string not able to be parsed\n") + return + sourceTag = list(json_dict)[0] + params = list(json_dict.values())[0] + tag = getTag(sourceTag) + param_dict = getFVMFromParams(params) + if param_dict: + event_publish(publisher_handle, tag, param_dict) + +def publishEventsFromFile(publisher_handle, infile, count, pause): + try: + with open(infile, 'r') as f: + for line in f.readlines(): + line.rstrip() + publishEvents(line, publisher_handle) + time.sleep(pause) + except Exception as ex: + logging.error("Unable to open file from given path or has incorrect json format, gives exception {}\n".format(ex)) + logging.info("Switching to default bgp state publish events\n") + publishBGPEvents(publisher_handle, count, pause) + +def publishBGPEvents(publisher_handle, count, pause): + ip_addresses = [] + param_dict = FieldValueMap() + + for _ in range(count): + ip = str(ipaddress.IPv4Address(random.randint(0, 2 ** 32))) + ip_addresses.append(ip) + + # publish down events + for ip in ip_addresses: + param_dict["ip"] = ip + param_dict["status"] = "down" + event_publish(publisher_handle, "bgp-state", param_dict) + time.sleep(pause) + + # publish up events + for ip in ip_addresses: + param_dict["ip"] = ip + event_publish(publisher_handle, "bgp-state", param_dict) + time.sleep(pause) + +def main(): + parser = argparse.ArgumentParser() + parser.add_argument("-s", "--source", nargs='?', const='test-event-source', default='test-event-source', help="Source of event, default us test-event-source") + parser.add_argument("-f", "--file", nargs='?', const='', default='', help="File containing json event strings, must be in format \'{\":foo\": {\"aaa\": \"AAA\", \"bbb\": \"BBB\"}}\'") + parser.add_argument("-c", "--count", nargs='?', type=int, const=10, default=10, help="Count of default bgp events to be generated") + parser.add_argument("-p", "--pause", nargs='?', type=float, const=0.0, default=0.0, help="Pause time wanted between each event, default is 0") + args = parser.parse_args() + publisher_handle = events_init_publisher(args.source) + if args.file == '': + publishBGPEvents(publisher_handle, args.count, args.pause) + else: + publishEventsFromFile(publisher_handle, args.file, args.count, args.pause) + +if __name__ == "__main__": + main() diff --git a/src/sonic-eventd/tools/events_tool.cpp b/src/sonic-eventd/tools/events_tool.cpp new file mode 100644 index 000000000000..97b17c1d7566 --- /dev/null +++ b/src/sonic-eventd/tools/events_tool.cpp @@ -0,0 +1,328 @@ +#include +#include +#include "events.h" +#include "events_common.h" + +/* + * Sample i/p file contents for send + * + * {"src_0:key-0": {"foo": "bar", "hello": "world" }} + * {"src_0:key-1": {"foo": "barXX", "hello": "world" }} + * + * Repeat the above line to increase entries. + * Each line is parsed independently, so no "," expected at the end. + */ + +#define ASSERT(res, m, ...) \ + if (!(res)) {\ + int _e = errno; \ + printf("Failed here %s:%d errno:%d zerrno:%d ", __FUNCTION__, __LINE__, _e, zmq_errno()); \ + printf(m, ##__VA_ARGS__); \ + printf("\n"); \ + exit(-1); } + + +typedef enum { + OP_INIT=0, + OP_SEND=1, + OP_RECV=2, + OP_SEND_RECV=3 //SEND|RECV +} op_t; + + +#define PRINT_CHUNK_SZ 2 + +/* + * Usage: + */ + +const char *s_usage = "\ +-s - To Send\n\ +-r - To receive\n\ +Note:\n\ + when both -s & -r are given:\n\ + it uses main thread to publish and fork a dedicated thread to receive.\n\ + The rest of the parameters except -w is used for send\n\ +\n\ +-n - Count of messages to send/receive. When both given, it is used as count to send\n\ + Default: 1 \n\ + A value of 0 implies unlimited\n\ +\n\ +-p - Count of milliseconds to pause between sends or receives. In send-recv mode, it only affects send.\n\ + Default: 0 implying no pause\n\ +\n\ + -i - List of JSON messages to send in a file, with each event/message\n\ + declared in a single line. When n is more than size of list, the list\n\ + is rotated upon completion.\n\ + e.g. '[ \n\ + { \"sonic-bgp:bgp-state\": { \"ip\": \"10.101.01.10\", \"ts\": \"2022-10-11T01:02:30.45567\", \"state\": \"up\" }}\n\ + { \"abc-xxx:yyy-zz\": { \"foo\": \"bar\", \"hello\":\"world\", \"ts\": \"2022-10-11T01:02:30.45567\"}}\n\ + { \"some-mod:some-tag\": {}}\n\ + ]\n\ + Default: \n\ +\n\ +-c - Use offline cache in receive mode\n\ +-o - O/p file to write received events\n\ + Default: STDOUT\n"; + + +bool term_receive = false; + +template +string +t_map_to_str(const Map &m) +{ + stringstream _ss; + string sep; + + _ss << "{"; + for (const auto elem: m) { + _ss << sep << "{" << elem.first << "," << elem.second << "}"; + if (sep.empty()) { + sep = ", "; + } + } + _ss << "}"; + return _ss.str(); +} + +void +do_receive(const event_subscribe_sources_t filter, const string outfile, int cnt, int pause, bool use_cache) +{ + int index=0, total_missed = 0; + ostream* fp = &cout; + ofstream fout; + + if (!outfile.empty()) { + fout.open(outfile); + if (!fout.fail()) { + fp = &fout; + printf("outfile=%s set\n", outfile.c_str()); + } + } + event_handle_t h = events_init_subscriber(use_cache, 2000, filter.empty() ? NULL : &filter); + printf("Subscribed with use_cache=%d timeout=2000 filter %s\n", + use_cache, filter.empty() ? "empty" : "non-empty"); + ASSERT(h != NULL, "Failed to get subscriber handle"); + + while(!term_receive) { + event_receive_op_t evt; + map_str_str_t evtOp; + + int rc = event_receive(h, evt); + if (rc != 0) { + ASSERT(rc == EAGAIN, "Failed to receive rc=%d index=%d\n", + rc, index); + continue; + } + ASSERT(!evt.key.empty(), "received EMPTY key"); + ASSERT(evt.missed_cnt >= 0, "Missed count uninitialized"); + ASSERT(evt.publish_epoch_ms > 0, "publish_epoch_ms uninitialized"); + + total_missed += evt.missed_cnt; + + evtOp[evt.key] = t_map_to_str(evt.params); + (*fp) << t_map_to_str(evtOp) << "\n"; + fp->flush(); + + if ((++index % PRINT_CHUNK_SZ) == 0) { + printf("Received index %d\n", index); + } + + if (cnt > 0) { + if (--cnt <= 0) { + break; + } + } + } + + events_deinit_subscriber(h); + printf("Total received = %d missed = %dfile:%s\n", index, total_missed, + outfile.empty() ? "STDOUT" : outfile.c_str()); +} + + +int +do_send(const string infile, int cnt, int pause) +{ + typedef struct { + string tag; + event_params_t params; + } evt_t; + + typedef vector lst_t; + + lst_t lst; + string source; + event_handle_t h; + int index = 0; + + if (!infile.empty()) { + ifstream input(infile); + + /* Read infile into list of events, that are ready for send */ + for( string line; getline( input, line ); ) + { + evt_t evt; + string str_params; + + const auto &data = nlohmann::json::parse(line); + ASSERT(data.is_object(), "Parsed data is not object"); + ASSERT((int)data.size() == 1, "string parse size = %d", (int)data.size()); + + string key(data.begin().key()); + if (source.empty()) { + source = key.substr(0, key.find(":")); + } else { + ASSERT(source == key.substr(0, key.find(":")), "source:%s read=%s", + source.c_str(), key.substr(0, key.find(":")).c_str()); + } + evt.tag = key.substr(key.find(":")+1); + + const auto &val = data.begin().value(); + ASSERT(val.is_object(), "Parsed params is not object"); + ASSERT((int)val.size() >= 1, "Expect non empty params"); + + for(auto par_it = val.begin(); par_it != val.end(); par_it++) { + evt.params[string(par_it.key())] = string(par_it.value()); + } + lst.push_back(evt); + } + } + + if (lst.empty()) { + evt_t evt = { + "test-tag", + { + { "param1", "foo"}, + {"param2", "bar"} + } + }; + lst.push_back(evt); + } + + h = events_init_publisher(source); + ASSERT(h != NULL, "failed to init publisher"); + + /* cnt = 0 as i/p implies forever */ + + while(cnt >= 0) { + /* Keep resending the list until count is exhausted */ + for(lst_t::const_iterator itc = lst.begin(); (cnt >= 0) && (itc != lst.end()); ++itc) { + const evt_t &evt = *itc; + + if ((++index % PRINT_CHUNK_SZ) == 0) { + printf("Sending index %d\n", index); + } + + int rc = event_publish(h, evt.tag, evt.params.empty() ? NULL : &evt.params); + ASSERT(rc == 0, "Failed to publish index=%d rc=%d", index, rc); + + if ((cnt > 0) && (--cnt == 0)) { + /* set to termninate */ + cnt = -1; + } + else if (pause) { + /* Pause between two sends */ + this_thread::sleep_for(chrono::milliseconds(pause)); + } + } + } + + events_deinit_publisher(h); + printf("Sent %d events\n", index); + return 0; +} + +void usage() +{ + printf("%s", s_usage); + exit(-1); +} + +int main(int argc, char **argv) +{ + bool use_cache = false; + int op = OP_INIT; + int cnt=0, pause=0; + string json_str_msg, outfile("STDOUT"), infile; + event_subscribe_sources_t filter; + + for(;;) + { + switch(getopt(argc, argv, "srn:p:i:o:f:c")) // note the colon (:) to indicate that 'b' has a parameter and is not a switch + { + case 'c': + use_cache = true; + continue; + + case 's': + op |= OP_SEND; + continue; + + case 'r': + op |= OP_RECV; + continue; + + case 'n': + cnt = stoi(optarg); + continue; + + case 'p': + pause = stoi(optarg); + continue; + + case 'i': + infile = optarg; + continue; + + case 'o': + outfile = optarg; + continue; + + case 'f': + { + stringstream ss(optarg); //create string stream from the string + while(ss.good()) { + string substr; + getline(ss, substr, ','); + filter.push_back(substr); + } + } + continue; + + case -1: + break; + + case '?': + case 'h': + default : + usage(); + break; + + } + break; + } + + + printf("op=%d n=%d pause=%d i=%s o=%s\n", + op, cnt, pause, infile.c_str(), outfile.c_str()); + + if (op == OP_SEND_RECV) { + thread thr(&do_receive, filter, outfile, 0, 0, use_cache); + do_send(infile, cnt, pause); + } + else if (op == OP_SEND) { + do_send(infile, cnt, pause); + } + else if (op == OP_RECV) { + do_receive(filter, outfile, cnt, pause, use_cache); + } + else { + ASSERT(false, "Elect -s for send or -r receive or both; Bailing out with no action\n"); + } + + printf("--------- END: Good run -----------------\n"); + return 0; +} + diff --git a/src/sonic-eventd/tools/events_volume_test.py b/src/sonic-eventd/tools/events_volume_test.py new file mode 100644 index 000000000000..73143d483cd8 --- /dev/null +++ b/src/sonic-eventd/tools/events_volume_test.py @@ -0,0 +1,68 @@ +import sys +import subprocess +import time +import logging +import argparse + +logging.basicConfig( + level=logging.INFO, + format="%(asctime)s [%(levelname)s] %(message)s", + handlers = [ + logging.FileHandler("debug.log"), + logging.StreamHandler(sys.stdout) + ] +) + +def read_events_from_file(file, count): + logging.info("Reading from file generated by events_tool") + lines = 0 + with open(file, 'r') as infile: + lines = infile.readlines() + logging.info("Should receive {} events and got {} events\n".format(count, len(lines))) + assert len(lines) == count + +def start_tool(file): + logging.info("Starting events_tool\n") + proc = subprocess.Popen(["./events_tool", "-r", "-o", file]) + return proc + +def run_test(process, file, count, duplicate): + # log messages to see if events have been received + tool_proc = start_tool(file) + + time.sleep(2) # buffer for events_tool to startup + logging.info("Generating logger messages\n") + for i in range(count): + line = "" + state = "up" + if duplicate: + line = "{} test message testmessage state up".format(process) + else: + if i % 2 != 1: + state = "down" + line = "{} test message testmessage{} state {}".format(process, i, state) + command = "logger -p local0.notice -t {}".format(line) + subprocess.run(command, shell=True, stdout=subprocess.PIPE) + + time.sleep(2) # some buffer for all events to be published to file + read_events_from_file(file, count) + tool_proc.terminate() + +def main(): + parser = argparse.ArgumentParser() + parser.add_argument("-p", "--process", nargs='?', const ='', default='', help="Process that is spitting out log") + parser.add_argument("-f", "--file", nargs='?', const='', default='', help="File used by events_tool to read events from") + parser.add_argument("-c", "--count", type=int, nargs='?', const=1000, default=1000, help="Count of times log message needs to be published down/up, default is 1000") + args = parser.parse_args() + if(args.process == '' or args.file == ''): + logging.error("Invalid process or logfile\n") + return + logging.info("Starting volume test\n") + logging.info("Generating {} unique messages for rsyslog plugin\n".format(args.count)) + run_test(args.process, args.file, args.count, False) + time.sleep(2) + logging.info("Restarting volume test but for duplicate log messages\n") + run_test(args.process, args.file, args.count, True) + +if __name__ == "__main__": + main() diff --git a/src/sonic-eventd/tools/sample_ip.json b/src/sonic-eventd/tools/sample_ip.json new file mode 100644 index 000000000000..acb8726cf253 --- /dev/null +++ b/src/sonic-eventd/tools/sample_ip.json @@ -0,0 +1 @@ +{"src_0:key-0": {"foo": "bar", "hello": "world" }} diff --git a/src/sonic-eventd/tools/subdir.mk b/src/sonic-eventd/tools/subdir.mk new file mode 100644 index 000000000000..5f13043dd612 --- /dev/null +++ b/src/sonic-eventd/tools/subdir.mk @@ -0,0 +1,12 @@ +CC := g++ + +TOOL_OBJS = ./tools/events_tool.o + +C_DEPS += ./tools/events_tool.d + +tools/%.o: tools/%.cpp + @echo 'Building file: $<' + @echo 'Invoking: GCC C++ Compiler' + $(CC) -D__FILENAME__="$(subst tools/,,$<)" $(CFLAGS) -c -fmessage-length=0 -MMD -MP -MF"$(@:%.o=%.d)" -MT"$(@)" -o "$@" "$<" + @echo 'Finished building: $<' + @echo ' ' From 78eeeb76708538b431b1fd4efdd4cc37452bf70c Mon Sep 17 00:00:00 2001 From: Kebo Liu Date: Sun, 4 Sep 2022 15:53:07 +0800 Subject: [PATCH 077/151] [SN2201] remove extra empty lines in the pg_profile_lookup.ini (#11923) - Why I did it Remove extra empty lines in the SN2201 pg_profile_lookup.ini to make it aligned with other platforms. This extra empty line could confuse some test cases which need to parse this file. Signed-off-by: Kebo Liu --- .../x86_64-nvidia_sn2201-r0/ACS-SN2201/pg_profile_lookup.ini | 1 - 1 file changed, 1 deletion(-) diff --git a/device/mellanox/x86_64-nvidia_sn2201-r0/ACS-SN2201/pg_profile_lookup.ini b/device/mellanox/x86_64-nvidia_sn2201-r0/ACS-SN2201/pg_profile_lookup.ini index 53652080e967..18d2bf5ef8c5 100644 --- a/device/mellanox/x86_64-nvidia_sn2201-r0/ACS-SN2201/pg_profile_lookup.ini +++ b/device/mellanox/x86_64-nvidia_sn2201-r0/ACS-SN2201/pg_profile_lookup.ini @@ -14,7 +14,6 @@ ## See the License for the specific language governing permissions and ## limitations under the License. ## - # PG lossless profiles. # speed cable size xon xoff threshold 100 5m 49152 19456 29696 0 From 4e18510fc9f3b485628c8ce4f294fddbd9470689 Mon Sep 17 00:00:00 2001 From: Dror Prital <76714716+dprital@users.noreply.github.com> Date: Sun, 4 Sep 2022 10:54:16 +0300 Subject: [PATCH 078/151] [submodule]] Advance sonic-utilities pointer (#11897) Update sonic-utilities submodule pointer to include the following: Replace cmp in acl_loader with operator.eq (#2328) Subinterface vrf bind issue fix (#2211) [VRF]Adding CLI checks to ensure Vrf is valid in interface bind and static route commands (#2333) [doc]: Add MACsec CLI doc (#2334) [sonic-package-manager] Drop 'expires_in' (#2002) Handle non-front-panel ports in is_rj45_port (#2327) [service_mgmt]: Fix fetch MULTI_INST_DEPENDENT bug in service_mgmt.sh.j2 (#2319) correct an error by changing "show bgp summary" to "show bfd summary" (#2324) Update VRF unbind command (#2331) Fix issue: port_type is referenced before initialized (#2323) Fix issue: exception in is_rj45_port in multi ASIC env (#2313) Delete .DS_Store (#2244) Fix bug with checking VRF's routes in route_check.py (#2301) [decode-syseeprom] Fix setting use_db based on support_eeprom_db (#2270) Fix vrf UT failed issue (#2309) add lacp_rate to portchannel (#2036) --- src/sonic-utilities | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sonic-utilities b/src/sonic-utilities index 28b6ba5fc11f..3af8ba4acc2b 160000 --- a/src/sonic-utilities +++ b/src/sonic-utilities @@ -1 +1 @@ -Subproject commit 28b6ba5fc11f65abaf421c70159a605d233eda41 +Subproject commit 3af8ba4acc2bbc77d17be0d67943703021c7d1e1 From 1b5d07f665e705eb0ec9fd1af70dfa0dd9545b11 Mon Sep 17 00:00:00 2001 From: Dror Prital <76714716+dprital@users.noreply.github.com> Date: Sun, 4 Sep 2022 11:03:36 +0300 Subject: [PATCH 079/151] [submodule] Advance sonic-platform-daemons pointer (#11882) - Why I did it Update sonic-platform-daemons submodule pointer to include the following: [ycabled] enable telemetry for 'active-active'; fix gRPC portid ordering (#284) [ycabled] remove some spurious logs (#282) Correct the peer forwarding state table (#281) add psu input voltage and current (#276) [ycabled] add capability to enable/disable telemetry (#279) Signed-off-by: dprital --- src/sonic-platform-daemons | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sonic-platform-daemons b/src/sonic-platform-daemons index cc563670a5e8..7c0a326e1dcd 160000 --- a/src/sonic-platform-daemons +++ b/src/sonic-platform-daemons @@ -1 +1 @@ -Subproject commit cc563670a5e8a10a51057a4e1455a1e36b386653 +Subproject commit 7c0a326e1dcd2be74a80f6d3a2d7c4af084c2035 From a8b2a538a56d9d0a19ddcccb2cbff7f5915058f7 Mon Sep 17 00:00:00 2001 From: Stepan Blyshchak <38952541+stepanblyschak@users.noreply.github.com> Date: Tue, 6 Sep 2022 19:26:54 +0300 Subject: [PATCH 080/151] [docker-wait-any] immediately start to wait (#11595) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit It could happen that a container has already crashed but docker-wait-any will wait forever till it starts. It should, however, immediately exit to make the serivce restart. #### Why I did it It is observed in some circumstances that the auto-restart mechanism does not work. Specifically for ```swss.service```, ```orchagent``` had crashed before ```docker-wait-any``` started in ```swss.sh```. This led ```docker-wait-any``` wait forever for ```swss``` to be in ```"Running"``` state and it results in: ``` CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 1abef1ecebff bcbca2b74df6 "/usr/local/bin/supe…" 22 hours ago Up 22 hours what-just-happened 3c924d405cd5 docker-lldp:latest "/usr/bin/docker-lld…" 22 hours ago Up 22 hours lldp eb2b12a98c13 docker-router-advertiser:latest "/usr/bin/docker-ini…" 22 hours ago Up 22 hours radv d6aac4a46974 docker-sonic-mgmt-framework:latest "/usr/local/bin/supe…" 22 hours ago Up 22 hours mgmt-framework d880fd07aab9 docker-platform-monitor:latest "/usr/bin/docker_ini…" 22 hours ago Up 22 hours pmon 75f9e22d4fdd docker-snmp:latest "/usr/local/bin/supe…" 22 hours ago Up 22 hours snmp 76d570a4bd1c docker-sonic-telemetry:latest "/usr/local/bin/supe…" 22 hours ago Up 22 hours telemetry ee49f50344b3 docker-syncd-mlnx:latest "/usr/local/bin/supe…" 22 hours ago Up 22 hours syncd 1f0b0bab3687 docker-teamd:latest "/usr/local/bin/supe…" 22 hours ago Up 22 hours teamd 917aeeaf9722 docker-orchagent:latest "/usr/bin/docker-ini…" 22 hours ago Exited (0) 22 hours ago swss 81a4d3e820e8 docker-fpm-frr:latest "/usr/bin/docker_ini…" 22 hours ago Up 22 hours bgp f6eee8be282c docker-database:latest "/usr/local/bin/dock…" 22 hours ago Up 22 hours database ``` The check for ```"Running"``` state is not needed because for cold boot case we do ```start_peer_and_dependent_services``` and for warm boot case the loop will retry to wait for container if this container is doing warm boot: https://github.com/stepanblyschak/sonic-buildimage/blob/d01a91a569c9d545b30e8f81994b02d0c2513971/files/image_config/misc/docker-wait-any#L56 #### How I did it Removed the check for ```"Running"```. #### How to verify it Kill swss before ```docker-wait-any``` is reached and verify auto restart will restart swss serivce. --- files/image_config/misc/docker-wait-any | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/files/image_config/misc/docker-wait-any b/files/image_config/misc/docker-wait-any index 4200bb43c87f..3a00a2c610d1 100755 --- a/files/image_config/misc/docker-wait-any +++ b/files/image_config/misc/docker-wait-any @@ -46,10 +46,9 @@ g_dep_services = [] def wait_for_container(docker_client, container_name): - while True: - while docker_client.inspect_container(container_name)['State']['Status'] != "running": - time.sleep(1) + log.log_info("Waiting on container '{}'".format(container_name)) + while True: docker_client.wait(container_name) log.log_info("No longer waiting on container '{}'".format(container_name)) From 31e750ee0b9b67fa49f6f2e73f4c18383ce2558a Mon Sep 17 00:00:00 2001 From: Renuka Manavalan <47282725+renukamanavalan@users.noreply.github.com> Date: Tue, 6 Sep 2022 15:13:05 -0700 Subject: [PATCH 081/151] Fix PR build failure (#11973) Some PR builds fails to find this file. Remove it temporarily until we root cause it --- dockers/docker-fpm-frr/Dockerfile.j2 | 6 +++--- files/build_templates/sonic_debian_extension.j2 | 4 ++-- rules/docker-eventd.mk | 3 ++- 3 files changed, 7 insertions(+), 6 deletions(-) diff --git a/dockers/docker-fpm-frr/Dockerfile.j2 b/dockers/docker-fpm-frr/Dockerfile.j2 index fd7ad0f08ed4..25e191bc338f 100644 --- a/dockers/docker-fpm-frr/Dockerfile.j2 +++ b/dockers/docker-fpm-frr/Dockerfile.j2 @@ -56,14 +56,14 @@ COPY ["TS", "/usr/bin/TS"] COPY ["files/supervisor-proc-exit-listener", "/usr/bin"] COPY ["zsocket.sh", "/usr/bin/"] COPY ["*.json", "/etc/rsyslog.d/"] -COPY ["files/rsyslog_plugin.conf.j2", "/etc/rsyslog.d/"] +# COPY ["files/rsyslog_plugin.conf.j2", "/etc/rsyslog.d/"] RUN chmod a+x /usr/bin/TSA && \ chmod a+x /usr/bin/TSB && \ chmod a+x /usr/bin/TSC && \ chmod a+x /usr/bin/zsocket.sh -RUN j2 -f json /etc/rsyslog.d/rsyslog_plugin.conf.j2 /etc/rsyslog.d/events_info.json > /etc/rsyslog.d/bgp_events.conf -RUN rm -f /etc/rsyslog.d/rsyslog_plugin.conf.j2* +# RUN j2 -f json /etc/rsyslog.d/rsyslog_plugin.conf.j2 /etc/rsyslog.d/events_info.json > /etc/rsyslog.d/bgp_events.conf +# RUN rm -f /etc/rsyslog.d/rsyslog_plugin.conf.j2* RUN rm -f /etc/rsyslog.d/events_info.json* ENTRYPOINT ["/usr/bin/docker_init.sh"] diff --git a/files/build_templates/sonic_debian_extension.j2 b/files/build_templates/sonic_debian_extension.j2 index 56b8290cc12e..43946c10a692 100644 --- a/files/build_templates/sonic_debian_extension.j2 +++ b/files/build_templates/sonic_debian_extension.j2 @@ -800,8 +800,8 @@ sudo bash -c "echo { > $FILESYSTEM_ROOT_USR_SHARE_SONIC_TEMPLATES/ctr_image_name sudo bash -c "echo } >> $FILESYSTEM_ROOT_USR_SHARE_SONIC_TEMPLATES/ctr_image_names.json" # copy rsyslog plugin binary for use by all dockers that use plugin to publish events. -sudo mkdir -p ${FILESYSTEM_ROOT_USR_SHARE_SONIC_SCRIPTS} -sudo cp ${files_path}/rsyslog_plugin ${FILESYSTEM_ROOT_USR_SHARE_SONIC_SCRIPTS}/ +# sudo mkdir -p ${FILESYSTEM_ROOT_USR_SHARE_SONIC_SCRIPTS} +# sudo cp ${files_path}/rsyslog_plugin ${FILESYSTEM_ROOT_USR_SHARE_SONIC_SCRIPTS}/ {% for script in installer_start_scripts.split(' ') -%} if [ -f $TARGET_MACHINE"_{{script}}" ]; then diff --git a/rules/docker-eventd.mk b/rules/docker-eventd.mk index c69fee09e569..ec333bf66048 100644 --- a/rules/docker-eventd.mk +++ b/rules/docker-eventd.mk @@ -43,5 +43,6 @@ $(DOCKER_EVENTD)_PLUGIN = rsyslog_plugin $($(DOCKER_EVENTD)_PLUGIN)_PATH = $($(DOCKER_EVENTD)_FILESPATH) SONIC_COPY_FILES += $($(DOCKER_EVENTD)_PLUGIN) -$(DOCKER_EVENTD)_SHARED_FILES = $($(DOCKER_EVENTD)_PLUGIN) +# Some builds fails to find this file. Remove until we root cause it. +# $(DOCKER_EVENTD)_SHARED_FILES = $($(DOCKER_EVENTD)_PLUGIN) From 5efd6f9748d6e87c5a279bb760442cf259eecd97 Mon Sep 17 00:00:00 2001 From: Ze Gan Date: Wed, 7 Sep 2022 08:16:23 +0800 Subject: [PATCH 082/151] [macsec]: Add MACsec clear CLI support (#11731) Why I did it To support clear MACsec counters by sonic-clear macsec How I did it Add macsec sub-command in sonic-clear to cache the current macsec stats, and in the show macsec command to check the cache and return the diff with cache file. How to verify it admin@vlab-02:~$ show macsec Ethernet0 MACsec port(Ethernet0) --------------------- ----------- cipher_suite GCM-AES-128 enable true enable_encrypt true enable_protect true enable_replay_protect false replay_window 0 send_sci true --------------------- ----------- MACsec Egress SC (52540067daa70001) ----------- - encoding_an 0 ----------- - MACsec Egress SA (0) ------------------------------------- -------------------------------- auth_key 9DDD4C69220A1FA9B6763F229B75CB6F next_pn 1 sak BA86574D054FCF48B9CD7CF54F21304A salt 000000000000000000000000 ssci 0 SAI_MACSEC_SA_ATTR_CURRENT_XPN 52 SAI_MACSEC_SA_STAT_OCTETS_ENCRYPTED 0 SAI_MACSEC_SA_STAT_OCTETS_PROTECTED 0 SAI_MACSEC_SA_STAT_OUT_PKTS_ENCRYPTED 0 SAI_MACSEC_SA_STAT_OUT_PKTS_PROTECTED 0 ------------------------------------- -------------------------------- MACsec Ingress SC (525400d4fd3f0001) MACsec Ingress SA (0) --------------------------------------- -------------------------------- active true auth_key 9DDD4C69220A1FA9B6763F229B75CB6F lowest_acceptable_pn 1 sak BA86574D054FCF48B9CD7CF54F21304A salt 000000000000000000000000 ssci 0 SAI_MACSEC_SA_ATTR_CURRENT_XPN 56 SAI_MACSEC_SA_STAT_IN_PKTS_DELAYED 0 SAI_MACSEC_SA_STAT_IN_PKTS_INVALID 0 SAI_MACSEC_SA_STAT_IN_PKTS_LATE 0 SAI_MACSEC_SA_STAT_IN_PKTS_NOT_USING_SA 0 SAI_MACSEC_SA_STAT_IN_PKTS_NOT_VALID 0 SAI_MACSEC_SA_STAT_IN_PKTS_OK 0 SAI_MACSEC_SA_STAT_IN_PKTS_UNCHECKED 0 SAI_MACSEC_SA_STAT_IN_PKTS_UNUSED_SA 0 SAI_MACSEC_SA_STAT_OCTETS_ENCRYPTED 0 SAI_MACSEC_SA_STAT_OCTETS_PROTECTED 0 --------------------------------------- -------------------------------- admin@vlab-02:~$ sonic-clear macsec Clear MACsec counters admin@vlab-02:~$ show macsec Ethernet0 MACsec port(Ethernet0) --------------------- ----------- cipher_suite GCM-AES-128 enable true enable_encrypt true enable_protect true enable_replay_protect false replay_window 0 send_sci true --------------------- ----------- MACsec Egress SC (52540067daa70001) ----------- - encoding_an 0 ----------- - MACsec Egress SA (0) ------------------------------------- -------------------------------- auth_key 9DDD4C69220A1FA9B6763F229B75CB6F next_pn 1 sak BA86574D054FCF48B9CD7CF54F21304A salt 000000000000000000000000 ssci 0 SAI_MACSEC_SA_ATTR_CURRENT_XPN 52 SAI_MACSEC_SA_STAT_OCTETS_ENCRYPTED 0 SAI_MACSEC_SA_STAT_OCTETS_PROTECTED 0 SAI_MACSEC_SA_STAT_OUT_PKTS_ENCRYPTED 0 SAI_MACSEC_SA_STAT_OUT_PKTS_PROTECTED 0 ------------------------------------- -------------------------------- MACsec Ingress SC (525400d4fd3f0001) MACsec Ingress SA (0) --------------------------------------- -------------------------------- active true auth_key 9DDD4C69220A1FA9B6763F229B75CB6F lowest_acceptable_pn 1 sak BA86574D054FCF48B9CD7CF54F21304A salt 000000000000000000000000 ssci 0 SAI_MACSEC_SA_ATTR_CURRENT_XPN 0 <---this counters was cleared. SAI_MACSEC_SA_STAT_IN_PKTS_DELAYED 0 SAI_MACSEC_SA_STAT_IN_PKTS_INVALID 0 SAI_MACSEC_SA_STAT_IN_PKTS_LATE 0 SAI_MACSEC_SA_STAT_IN_PKTS_NOT_USING_SA 0 SAI_MACSEC_SA_STAT_IN_PKTS_NOT_VALID 0 SAI_MACSEC_SA_STAT_IN_PKTS_OK 0 SAI_MACSEC_SA_STAT_IN_PKTS_UNCHECKED 0 SAI_MACSEC_SA_STAT_IN_PKTS_UNUSED_SA 0 SAI_MACSEC_SA_STAT_OCTETS_ENCRYPTED 0 SAI_MACSEC_SA_STAT_OCTETS_PROTECTED 0 --------------------------------------- -------------------------------- Signed-off-by: Ze Gan Co-authored-by: Judy Joseph --- .../cli/clear/plugins/clear_macsec_counter.py | 36 ++++++++++ .../cli/show/plugins/show_macsec.py | 72 +++++++++++++++---- rules/docker-macsec.mk | 1 + 3 files changed, 94 insertions(+), 15 deletions(-) create mode 100644 dockers/docker-macsec/cli/clear/plugins/clear_macsec_counter.py diff --git a/dockers/docker-macsec/cli/clear/plugins/clear_macsec_counter.py b/dockers/docker-macsec/cli/clear/plugins/clear_macsec_counter.py new file mode 100644 index 000000000000..b47a576f9ed2 --- /dev/null +++ b/dockers/docker-macsec/cli/clear/plugins/clear_macsec_counter.py @@ -0,0 +1,36 @@ +import os +import click + +import show.plugins.macsec as show_macsec +import utilities_common.cli as clicommon +from sonic_py_common import multi_asic + +@click.group(cls=clicommon.AliasedGroup) +def macsec(): + pass + + +@macsec.command('macsec') +@click.option('--clean-cache', type=bool, required=False, default=False, help="If the option of clean cache is true, next show commands will show the raw counters which based on the service booted instead of the last clear command.") +def macsec_clear_counters(clean_cache): + """ + Clear MACsec counts. + This clear command will generated a cache for next show commands which will base on this cache as the zero baseline to show the increment of counters. + """ + + if clean_cache: + for namespace in multi_asic.get_namespace_list(): + if os.path.isfile(show_macsec.CACHE_FILE.format(namespace)): + os.remove(show_macsec.CACHE_FILE.format(namespace)) + print("Cleaned cache") + return + + clicommon.run_command("show macsec --dump-file") + print("Clear MACsec counters") + +def register(cli): + cli.add_command(macsec_clear_counters) + + +if __name__ == '__main__': + macsec_clear_counters(None) diff --git a/dockers/docker-macsec/cli/show/plugins/show_macsec.py b/dockers/docker-macsec/cli/show/plugins/show_macsec.py index 3f1058df3572..9789b32bac6b 100644 --- a/dockers/docker-macsec/cli/show/plugins/show_macsec.py +++ b/dockers/docker-macsec/cli/show/plugins/show_macsec.py @@ -1,12 +1,19 @@ import typing from natsort import natsorted +import datetime +import pickle +import os +import copy import click from tabulate import tabulate import utilities_common.multi_asic as multi_asic_util from swsscommon.swsscommon import CounterTable, MacsecCounter +from utilities_common.cli import UserCache +CACHE_MANAGER = UserCache(app_name="macsec") +CACHE_FILE = os.path.join(CACHE_MANAGER.get_directory(), "macsecstats{}") DB_CONNECTOR = None COUNTER_TABLE = None @@ -15,12 +22,12 @@ class MACsecAppMeta(object): def __init__(self, *args) -> None: SEPARATOR = DB_CONNECTOR.get_db_separator(DB_CONNECTOR.APPL_DB) - key = self.__class__.get_appl_table_name() + SEPARATOR + \ + self.key = self.__class__.get_appl_table_name() + SEPARATOR + \ SEPARATOR.join(args) self.meta = DB_CONNECTOR.get_all( - DB_CONNECTOR.APPL_DB, key) + DB_CONNECTOR.APPL_DB, self.key) if len(self.meta) == 0: - raise ValueError("No such MACsecAppMeta: {}".format(key)) + raise ValueError("No such MACsecAppMeta: {}".format(self.key)) for k, v in self.meta.items(): setattr(self, k, v) @@ -39,10 +46,15 @@ def __init__(self, port_name: str, sci: str, an: str) -> None: MACsecAppMeta.__init__(self, port_name, sci, an) MACsecCounters.__init__(self, port_name, sci, an) - def dump_str(self) -> str: + def dump_str(self, cache = None) -> str: buffer = self.get_header() meta = sorted(self.meta.items(), key=lambda x: x[0]) - counters = sorted(self.counters.items(), key=lambda x: x[0]) + counters = copy.deepcopy(self.counters) + if cache: + for k, v in counters.items(): + if k in cache.counters: + counters[k] = int(counters[k]) - int(cache.counters[k]) + counters = sorted(counters.items(), key=lambda x: x[0]) buffer += tabulate(meta + counters) buffer = "\n".join(["\t\t" + line for line in buffer.splitlines()]) return buffer @@ -87,7 +99,7 @@ def __init__(self, port_name: str, sci: str) -> None: def get_appl_table_name(cls) -> str: return "MACSEC_INGRESS_SC_TABLE" - def dump_str(self) -> str: + def dump_str(self, cache = None) -> str: buffer = self.get_header() buffer = "\n".join(["\t" + line for line in buffer.splitlines()]) return buffer @@ -104,7 +116,7 @@ def __init__(self, port_name: str, sci: str) -> None: def get_appl_table_name(cls) -> str: return "MACSEC_EGRESS_SC_TABLE" - def dump_str(self) -> str: + def dump_str(self, cache = None) -> str: buffer = self.get_header() buffer += tabulate(sorted(self.meta.items(), key=lambda x: x[0])) buffer = "\n".join(["\t" + line for line in buffer.splitlines()]) @@ -123,7 +135,7 @@ def __init__(self, port_name: str) -> None: def get_appl_table_name(cls) -> str: return "MACSEC_PORT_TABLE" - def dump_str(self) -> str: + def dump_str(self, cache = None) -> str: buffer = self.get_header() buffer += tabulate(sorted(self.meta.items(), key=lambda x: x[0])) return buffer @@ -149,6 +161,7 @@ def create_macsec_obj(key: str) -> MACsecAppMeta: except ValueError as e: return None + def create_macsec_objs(interface_name: str) -> typing.List[MACsecAppMeta]: objs = [] objs.append(create_macsec_obj(MACsecPort.get_appl_table_name() + ":" + interface_name)) @@ -179,12 +192,25 @@ def create_macsec_objs(interface_name: str) -> typing.List[MACsecAppMeta]: return objs +def cache_find(cache: dict, target: MACsecAppMeta) -> MACsecAppMeta: + if not cache or not cache["objs"]: + return None + for obj in cache["objs"]: + if type(obj) == type(target) and obj.key == target.key: + # MACsec SA may be refreshed by a cycle that use the same key + # So, use the SA as the identifier + if isinstance(obj, MACsecSA) and obj.sak != target.sak: + continue + return obj + return None + + @click.command() @click.argument('interface_name', required=False) +@click.option('--dump-file', is_flag=True, required=False, default=False) @multi_asic_util.multi_asic_click_options -def macsec(interface_name, namespace, display): - MacsecContext(namespace, display).show(interface_name) - +def macsec(interface_name, dump_file, namespace, display): + MacsecContext(namespace, display).show(interface_name, dump_file) class MacsecContext(object): @@ -194,7 +220,7 @@ def __init__(self, namespace_option, display_option): display_option, namespace_option) @multi_asic_util.run_on_multi_asic - def show(self, interface_name): + def show(self, interface_name, dump_file): global DB_CONNECTOR global COUNTER_TABLE DB_CONNECTOR = self.db @@ -205,13 +231,29 @@ def show(self, interface_name): if interface_name not in interface_names: return interface_names = [interface_name] - objs = [] + for interface_name in natsorted(interface_names): objs += create_macsec_objs(interface_name) - for obj in objs: - print(obj.dump_str()) + cache = {} + if os.path.isfile(CACHE_FILE.format(self.multi_asic.current_namespace)): + cache = pickle.load(open(CACHE_FILE.format(self.multi_asic.current_namespace), "rb")) + + if not dump_file: + if cache and cache["time"] and objs: + print("Last cached time was {}".format(cache["time"])) + for obj in objs: + cache_obj = cache_find(cache, obj) + print(obj.dump_str(cache_obj)) + else: + dump_obj = { + "time": datetime.datetime.now(), + "objs": objs + } + with open(CACHE_FILE.format(self.multi_asic.current_namespace), 'wb') as dump_file: + pickle.dump(dump_obj, dump_file) + dump_file.flush() def register(cli): cli.add_command(macsec) diff --git a/rules/docker-macsec.mk b/rules/docker-macsec.mk index 3a6e9a558577..5db5ea5a41d9 100644 --- a/rules/docker-macsec.mk +++ b/rules/docker-macsec.mk @@ -44,5 +44,6 @@ $(DOCKER_MACSEC)_RUN_OPT += -v /host/warmboot:/var/warmboot $(DOCKER_MACSEC)_CLI_CONFIG_PLUGIN = /cli/config/plugins/macsec.py $(DOCKER_MACSEC)_CLI_SHOW_PLUGIN = /cli/show/plugins/show_macsec.py +$(DOCKER_MACSEC)_CLI_CLEAR_PLUGIN = /cli/clear/plugins/clear_macsec_counter.py $(DOCKER_MACSEC)_FILES += $(SUPERVISOR_PROC_EXIT_LISTENER_SCRIPT) From 3b9bbf7d2827cbb489e20b1af28ab48a75b46572 Mon Sep 17 00:00:00 2001 From: Muhammad Danish <88161975+mdanish-kh@users.noreply.github.com> Date: Wed, 7 Sep 2022 09:25:44 +0500 Subject: [PATCH 083/151] [doc]: Update README.md (#11960) * Remove faulty pipeline URLs * Miscellaneous minor fixes --- README.md | 31 ++++++++++--------------------- 1 file changed, 10 insertions(+), 21 deletions(-) diff --git a/README.md b/README.md index 92684138845d..1f78c9f56d60 100644 --- a/README.md +++ b/README.md @@ -14,7 +14,6 @@ [![Mellanox](https://dev.azure.com/mssonic/build/_apis/build/status/mellanox/Azure.sonic-buildimage.official.mellanox?branchName=master&label=Mellanox)](https://dev.azure.com/mssonic/build/_build/latest?definitionId=139&branchName=master) [![Marvell(armhf)](https://dev.azure.com/mssonic/build/_apis/build/status/marvell/Azure.sonic-buildimage.official.marvell-armhf?branchName=master&label=Marvell-armhf)](https://dev.azure.com/mssonic/build/_build/latest?definitionId=141&branchName=master) [![Nephos](https://dev.azure.com/mssonic/build/_apis/build/status/nephos/Azure.sonic-buildimage.official.nephos?branchName=master&label=Nephos)](https://dev.azure.com/mssonic/build/_build/latest?definitionId=149&branchName=master) -[![P4](https://sonic-jenkins.westus2.cloudapp.azure.com/job/p4/job/buildimage-p4-all/badge/icon?subject=P4)](https://sonic-jenkins.westus2.cloudapp.azure.com/job/p4/job/buildimage-p4-all) [![VS](https://dev.azure.com/mssonic/build/_apis/build/status/vs/Azure.sonic-buildimage.official.vs?branchName=master&label=VS)](https://dev.azure.com/mssonic/build/_build/latest?definitionId=142&branchName=master) *202205 builds*: @@ -70,25 +69,13 @@ [![Nephos](https://dev.azure.com/mssonic/build/_apis/build/status/nephos/Azure.sonic-buildimage.official.nephos?branchName=201811&label=Nephos)](https://dev.azure.com/mssonic/build/_build/latest?definitionId=149&branchName=201811) [![VS](https://dev.azure.com/mssonic/build/_apis/build/status/vs/Azure.sonic-buildimage.official.vs?branchName=201811&label=VS)](https://dev.azure.com/mssonic/build/_build/latest?definitionId=142&branchName=201811) -*201807 builds*: - -[![Broadcom](https://sonic-jenkins.westus2.cloudapp.azure.com/job/broadcom/job/buildimage-brcm-201807/badge/icon?subject=Broadcom)](https://sonic-jenkins.westus2.cloudapp.azure.com/job/broadcom/job/buildimage-brcm-201807/) -[![Barefoot](https://sonic-jenkins.westus2.cloudapp.azure.com/job/barefoot/job/buildimage-bf-201807/badge/icon?subject=Barefoot)](https://sonic-jenkins.westus2.cloudapp.azure.com/job/barefoot/job/buildimage-bf-201807/) - -*201803 builds*: - -[![Broadcom](https://sonic-jenkins.westus2.cloudapp.azure.com/job/broadcom/job/buildimage-brcm-201803/badge/icon?subject=Broadcom)](https://sonic-jenkins.westus2.cloudapp.azure.com/job/broadcom/job/buildimage-brcm-201803/) -[![Nephos](https://sonic-jenkins.westus2.cloudapp.azure.com/job/nephos/job/buildimage-nephos-201803/badge/icon?subject=Nephos)](https://sonic-jenkins.westus2.cloudapp.azure.com/job/nephos/job/buildimage-nephos-201803/) -[![Marvell](https://sonic-jenkins.westus2.cloudapp.azure.com/job/marvell/job/buildimage-mrvl-201803/badge/icon?subject=Marvell)](https://sonic-jenkins.westus2.cloudapp.azure.com/job/marvell/job/buildimage-mrvl-201803/) -[![Mellanox](https://sonic-jenkins.westus2.cloudapp.azure.com/job/mellanox/job/buildimage-mlnx-201803/badge/icon?subject=Mellanox)](https://sonic-jenkins.westus2.cloudapp.azure.com/job/mellanox/job/buildimage-mlnx-201803/) - # sonic-buildimage ## Build SONiC Switch Images # Description -Following is the instruction on how to build an [(ONIE)](https://github.com/opencomputeproject/onie) compatible network operating system (NOS) installer image for network switches, and also how to build docker images running inside the NOS. Note that SONiC image are build per ASIC platform. Switches using the same ASIC platform share a common image. For a list of supported switches and ASIC, please refer to this [list](https://github.com/sonic-net/SONiC/wiki/Supported-Devices-and-Platforms) +Following are the instructions on how to build an [(ONIE)](https://github.com/opencomputeproject/onie) compatible network operating system (NOS) installer image for network switches, and also how to build docker images running inside the NOS. Note that SONiC images are build per ASIC platform. Switches using the same ASIC platform share a common image. For a list of supported switches and ASIC, please refer to this [list](https://github.com/sonic-net/SONiC/wiki/Supported-Devices-and-Platforms) # Hardware @@ -156,12 +143,14 @@ To build SONiC installer image and docker images, run the following commands: - PLATFORM=vs ## Usage for ARM Architecture -To build Arm32 bit for (ARMHF) platform - ARM build has dependency in docker version 18, - if docker version is 19, downgrade to 18 as below - sudo apt-get install --allow-downgrades -y docker-ce=5:18.09.0~3-0~ubuntu-xenial - sudo apt-get install --allow-downgrades -y docker-ce-cli=5:18.09.0~3-0~ubuntu-xenial +ARM build has dependency in docker version 18. If docker version is 19, downgrade to 18 with: +``` +sudo apt-get install --allow-downgrades -y docker-ce=5:18.09.0~3-0~ubuntu-xenial +sudo apt-get install --allow-downgrades -y docker-ce-cli=5:18.09.0~3-0~ubuntu-xenial +``` +To build Arm32 bit for (ARMHF) platform + # Execute make configure once to configure ASIC and ARCH make configure PLATFORM=[ASIC_VENDOR] PLATFORM_ARCH=armhf @@ -174,7 +163,7 @@ To build Arm32 bit for (ARMHF) platform make target/sonic-marvell-armhf.bin -To build Arm32 bit for (ARMHF) Marvell platform on amd64 host for debian buster using cross-compilation run the following commands: +To build Arm32 bit for (ARMHF) Marvell platform on amd64 host for debian buster using cross-compilation, run the following commands: # Execute make configure once to configure ASIC and ARCH for cross-compilation build @@ -239,7 +228,7 @@ Every target has a clean target, so in order to clean swss, execute: It is recommended to use clean targets to clean all packages that are built together, like dev packages for instance. In order to be more familiar with build process and make some changes to it, it is recommended to read this short [Documentation](README.buildsystem.md). ## Build debug dockers and debug SONiC installer image: -SONiC build system supports building dockers and ONIE-image with debug tools and debug symbols, to help with live & core debugging. For details refer to [(SONiC Buildimage Guide)](https://github.com/sonic-net/sonic-buildimage/blob/master/README.buildsystem.md). +SONiC build system supports building dockers and ONIE-image with debug tools and debug symbols, to help with live & core debugging. For details refer to [SONiC Buildimage Guide](https://github.com/sonic-net/sonic-buildimage/blob/master/README.buildsystem.md). ## SAI Version Please refer to [SONiC roadmap](https://github.com/sonic-net/SONiC/wiki/Sonic-Roadmap-Planning) on the SAI version for each SONiC release. From 38cc35f6da630b068048af02bf141e85d444dee8 Mon Sep 17 00:00:00 2001 From: UmaMaven <106967235+UmaMaven@users.noreply.github.com> Date: Wed, 7 Sep 2022 10:25:59 +0530 Subject: [PATCH 084/151] support for static-route yang model (#11932) *[Yang] support for static-route yang model #11932 --- src/sonic-yang-models/setup.py | 2 + .../tests/files/sample_config_db.json | 9 + .../yang_model_tests/tests/static_route.json | 57 + .../tests_config/static-route.json | 1028 +++++++++++++++++ .../yang-models/sonic-static-route.yang | 124 ++ 5 files changed, 1220 insertions(+) create mode 100644 src/sonic-yang-models/tests/yang_model_tests/tests/static_route.json create mode 100644 src/sonic-yang-models/tests/yang_model_tests/tests_config/static-route.json create mode 100644 src/sonic-yang-models/yang-models/sonic-static-route.yang diff --git a/src/sonic-yang-models/setup.py b/src/sonic-yang-models/setup.py index 975b84b68245..961017fc7ca0 100644 --- a/src/sonic-yang-models/setup.py +++ b/src/sonic-yang-models/setup.py @@ -158,6 +158,7 @@ def run(self): './yang-models/sonic-pfc-priority-queue-map.yang', './yang-models/sonic-pfc-priority-priority-group-map.yang', './yang-models/sonic-port-qos-map.yang', + './yang-models/sonic-static-route.yang', './yang-models/sonic-macsec.yang']), ('cvlyang-models', ['./cvlyang-models/sonic-acl.yang', './cvlyang-models/sonic-bgp-common.yang', @@ -214,6 +215,7 @@ def run(self): './cvlyang-models/sonic-pfc-priority-queue-map.yang', './cvlyang-models/sonic-pfc-priority-priority-group-map.yang', './cvlyang-models/sonic-port-qos-map.yang', + './cvlyang-models/sonic-static-route.yang', './cvlyang-models/sonic-macsec.yang']), ], zip_safe=False, diff --git a/src/sonic-yang-models/tests/files/sample_config_db.json b/src/sonic-yang-models/tests/files/sample_config_db.json index b833fab06ddd..ddf83de7f0a1 100644 --- a/src/sonic-yang-models/tests/files/sample_config_db.json +++ b/src/sonic-yang-models/tests/files/sample_config_db.json @@ -1997,6 +1997,15 @@ "console_mgmt": { "enabled": "yes" } + }, + "STATIC_ROUTE": { + "default|20.20.20.0/24": { + "blackhole": "false", + "distance": "1", + "ifname": "Ethernet14", + "nexthop": "10.184.229.212", + "nexthop-vrf": "default" + } } }, "SAMPLE_CONFIG_DB_UNKNOWN": { diff --git a/src/sonic-yang-models/tests/yang_model_tests/tests/static_route.json b/src/sonic-yang-models/tests/yang_model_tests/tests/static_route.json new file mode 100644 index 000000000000..a41a94a7fc9c --- /dev/null +++ b/src/sonic-yang-models/tests/yang_model_tests/tests/static_route.json @@ -0,0 +1,57 @@ +{ + "STATIC_ROUTE_TEST": { + "desc": "Configure basic static route with default VRFs with PREFIX" + }, + "STATIC_ROUTE_TEST_WITH_INTERFACE": { + "desc": "Configure with nexthop as interface instead of IP address" + }, + "STATIC_ROUTE_TEST_WITH_BLACKHOLE": { + "desc": "Configure with nexthop as blackhole" + }, + "STATIC_ROUTE_TEST_WITH_VRF": { + "desc": "Configure with routes in non default VRF" + }, + "STATIC_ROUTE_TEST_WITH_KEY_VRF_MGMT": { + "desc": "Configure with routes in mgmt VRF as key" + }, + "STATIC_ROUTE_TEST_WITH_VRF_MGMT": { + "desc": "Configure with routes with mgmt VRF as next hop" + }, + "STATIC_ROUTE_TEST_WITH_VRF_LEAK": { + "desc": "Configure with route leak across VRFS" + }, + "STATIC_ROUTE_TEST_ECMP": { + "desc": "Configure comma separated values for ECMP, with nexthop as PREFIX" + }, + "STATIC_ROUTE_TEST_ECMP_WITH_INTERFACE": { + "desc": "Configure comma separated values with nexthop as INTERFACE" + }, + "STATIC_ROUTE_TEST_ECMP_WITH_MGMT": { + "desc": "Configure comma separated values with one nexthop as mgmt" + }, + "STATIC_ROUTE_TEST_DISTANCE_INVALID": { + "desc": "Configure with invalid distance number", + "eStrKey": "Pattern" + }, + "STATIC_ROUTE_TEST_BLACKHOLE_INVALID": { + "desc": "Configure with invalid value for blackhole", + "eStrKey": "Pattern" + }, + "STATIC_ROUTE_TEST_NEXTHOP_VRF_INVALID": { + "desc": "Configure with invalid value for VRF", + "eStrKey": "Pattern" + }, + "STATIC_ROUTE_TEST_ECMP_DISTANCE_INVALID": { + "desc": "Configure with invalid distance for ECMP", + "eStrKey": "Pattern" + }, + "STATIC_ROUTE_TEST_ECMP_BLACKHOLE_INVALID": { + "desc": "Configure with invalid blackhop for ECMP", + "eStrKey": "Pattern" + }, + "STATIC_ROUTE_TEST_ECMP_NEXTHOP_VRF_INVALID": { + "desc": "Configure with invalid vrf for ECMP", + "eStrKey": "Pattern" + } + +} diff --git a/src/sonic-yang-models/tests/yang_model_tests/tests_config/static-route.json b/src/sonic-yang-models/tests/yang_model_tests/tests_config/static-route.json new file mode 100644 index 000000000000..3afdc2e8d25c --- /dev/null +++ b/src/sonic-yang-models/tests/yang_model_tests/tests_config/static-route.json @@ -0,0 +1,1028 @@ +{ + "STATIC_ROUTE_TEST": { + "sonic-interface:sonic-interface": { + "sonic-interface:INTERFACE": { + "INTERFACE_IPPREFIX_LIST": [ + { + "family": "IPv4", + "ip-prefix": "10.0.0.1/24", + "name": "Ethernet8", + "scope": "global" + } + ], + "INTERFACE_LIST": [ + { + "name": "Ethernet8" + } + ] + } + }, + "sonic-port:sonic-port": { + "sonic-port:PORT": { + "PORT_LIST": [ + { + "admin_status": "up", + "alias": "eth8", + "description": "Ethernet8", + "fec": "rs", + "lanes": "65", + "mtu": 9000, + "name": "Ethernet8", + "speed": 25000 + } + ] + } + }, + "sonic-static-route:sonic-static-route": { + "sonic-static-route:STATIC_ROUTE": { + "STATIC_ROUTE_LIST": [{ + "vrf_name": "default", + "prefix":"100.100.100.1/24", + "nexthop":"10.10.10.1", + "distance": "1", + "nexthop-vrf":"default", + "blackhole":"false" + }] + } + } + }, + "STATIC_ROUTE_TEST_WITH_INTERFACE": { + "sonic-interface:sonic-interface": { + "sonic-interface:INTERFACE": { + "INTERFACE_IPPREFIX_LIST": [ + { + "family": "IPv4", + "ip-prefix": "10.0.0.1/30", + "name": "Ethernet8", + "scope": "global" + } + ], + "INTERFACE_LIST": [ + { + "name": "Ethernet8" + } + ] + } + }, + "sonic-port:sonic-port": { + "sonic-port:PORT": { + "PORT_LIST": [ + { + "admin_status": "up", + "alias": "eth8", + "description": "Ethernet8", + "fec": "rs", + "lanes": "65", + "mtu": 9000, + "name": "Ethernet8", + "speed": 25000 + } + ] + } + }, + "sonic-static-route:sonic-static-route": { + "sonic-static-route:STATIC_ROUTE": { + "STATIC_ROUTE_LIST": [{ + "vrf_name": "default", + "prefix":"100.100.100.1/24", + "nexthop":"0.0.0.0", + "ifname":"Ethernet8", + "distance": "1", + "nexthop-vrf":"default", + "blackhole":"false" + }] + } + } + }, + "STATIC_ROUTE_TEST_WITH_BLACKHOLE": { + "sonic-interface:sonic-interface": { + "sonic-interface:INTERFACE": { + "INTERFACE_IPPREFIX_LIST": [ + { + "family": "IPv4", + "ip-prefix": "10.0.0.1/30", + "name": "Ethernet8", + "scope": "global" + } + ], + "INTERFACE_LIST": [ + { + "name": "Ethernet8" + } + ] + } + }, + "sonic-port:sonic-port": { + "sonic-port:PORT": { + "PORT_LIST": [ + { + "admin_status": "up", + "alias": "eth8", + "description": "Ethernet8", + "fec": "rs", + "lanes": "65", + "mtu": 9000, + "name": "Ethernet8", + "speed": 25000 + } + ] + } + }, + "sonic-static-route:sonic-static-route": { + "sonic-static-route:STATIC_ROUTE": { + "STATIC_ROUTE_LIST": [{ + "prefix": "150.150.150.0/24", + "vrf_name": "default", + "ifname": "Ethernet8", + "distance": "1", + "nexthop-vrf": "default", + "blackhole": "true" + }] + } + } + }, + "STATIC_ROUTE_TEST_WITH_VRF": { + "sonic-vrf:sonic-vrf": { + "VRF": { + "VRF_LIST": [ + { + "name": "VrfMav", + "fallback": true + } + ] + } + }, + "sonic-interface:sonic-interface": { + "sonic-interface:INTERFACE": { + "INTERFACE_IPPREFIX_LIST": [ + { + "family": "IPv4", + "ip-prefix": "1.0.0.1/30", + "name": "Ethernet8", + "scope": "global" + } + ], + "INTERFACE_LIST": [ + { + "name": "Ethernet8" + } + ] + } + }, + "sonic-port:sonic-port": { + "sonic-port:PORT": { + "PORT_LIST": [ + { + "admin_status": "up", + "alias": "eth8", + "description": "Ethernet8", + "fec": "rs", + "lanes": "65", + "mtu": 9000, + "name": "Ethernet8", + "speed": 25000 + } + ] + } + }, + "sonic-static-route:sonic-static-route": { + "sonic-static-route:STATIC_ROUTE": { + "STATIC_ROUTE_LIST": [{ + "prefix": "75.75.75.0/24", + "vrf_name": "VrfMav", + "nexthop": "1.1.1.2", + "ifname": "Ethernet8", + "distance": "1", + "nexthop-vrf": "VrfMav", + "blackhole": "false" + }] + } + } + }, + "STATIC_ROUTE_TEST_WITH_KEY_VRF_MGMT": { + "sonic-interface:sonic-interface": { + "sonic-interface:INTERFACE": { + "INTERFACE_IPPREFIX_LIST": [ + { + "family": "IPv4", + "ip-prefix": "1.0.0.1/30", + "name": "Ethernet8", + "scope": "global" + } + ], + "INTERFACE_LIST": [ + { + "name": "Ethernet8" + } + ] + } + }, + "sonic-port:sonic-port": { + "sonic-port:PORT": { + "PORT_LIST": [ + { + "admin_status": "up", + "alias": "eth8", + "description": "Ethernet8", + "fec": "rs", + "lanes": "65", + "mtu": 9000, + "name": "Ethernet8", + "speed": 25000 + } + ] + } + }, + "sonic-static-route:sonic-static-route": { + "sonic-static-route:STATIC_ROUTE": { + "STATIC_ROUTE_LIST": [{ + "prefix": "75.75.75.0/24", + "vrf_name": "mgmt", + "nexthop": "1.1.1.2", + "ifname": "Ethernet8", + "distance": "1", + "nexthop-vrf": "mgmt", + "blackhole": "false" + }] + } + } + }, + "STATIC_ROUTE_TEST_WITH_VRF_MGMT": { + "sonic-interface:sonic-interface": { + "sonic-interface:INTERFACE": { + "INTERFACE_IPPREFIX_LIST": [ + { + "family": "IPv4", + "ip-prefix": "1.0.0.1/30", + "name": "Ethernet8", + "scope": "global" + } + ], + "INTERFACE_LIST": [ + { + "name": "Ethernet8" + } + ] + } + }, + "sonic-port:sonic-port": { + "sonic-port:PORT": { + "PORT_LIST": [ + { + "admin_status": "up", + "alias": "eth8", + "description": "Ethernet8", + "fec": "rs", + "lanes": "65", + "mtu": 9000, + "name": "Ethernet8", + "speed": 25000 + } + ] + } + }, + "sonic-static-route:sonic-static-route": { + "sonic-static-route:STATIC_ROUTE": { + "STATIC_ROUTE_LIST": [{ + "prefix": "75.75.75.0/24", + "vrf_name": "VrfMav", + "nexthop": "1.1.1.2", + "ifname": "Ethernet8", + "distance": "1", + "nexthop-vrf": "mgmt", + "blackhole": "false" + }] + } + } + }, + "STATIC_ROUTE_TEST_WITH_VRF_LEAK": { + "sonic-vrf:sonic-vrf": { + "VRF": { + "VRF_LIST": [ + { + "name": "VrfAbc", + "fallback": true + } + ] + } + }, + "sonic-interface:sonic-interface": { + "sonic-interface:INTERFACE": { + "INTERFACE_IPPREFIX_LIST": [ + { + "family": "IPv4", + "ip-prefix": "1.0.0.1/30", + "name": "Ethernet8", + "scope": "global" + } + ], + "INTERFACE_LIST": [ + { + "name": "Ethernet8" + } + ] + } + }, + "sonic-port:sonic-port": { + "sonic-port:PORT": { + "PORT_LIST": [ + { + "admin_status": "up", + "alias": "eth8", + "description": "Ethernet8", + "fec": "rs", + "lanes": "65", + "mtu": 9000, + "name": "Ethernet8", + "speed": 25000 + } + ] + } + }, + "sonic-static-route:sonic-static-route": { + "sonic-static-route:STATIC_ROUTE": { + "STATIC_ROUTE_LIST": [{ + "prefix": "85.85.85.0/24", + "vrf_name": "default", + "nexthop": "1.0.0.2", + "ifname": "Ethernet8", + "distance": "1", + "nexthop-vrf": "VrfAbc", + "blackhole": "false" + }] + } + } + }, + "STATIC_ROUTE_TEST_ECMP": { + "sonic-port:sonic-port": { + "sonic-port:PORT": { + "PORT_LIST": [ + { + "admin_status": "up", + "alias": "eth0", + "description": "Ethernet0", + "fec": "rs", + "lanes": "65", + "mtu": 9000, + "name": "Ethernet0", + "speed": 25000 + } + ] + } + }, + "sonic-interface:sonic-interface": { + "sonic-interface:INTERFACE": { + "INTERFACE_IPPREFIX_LIST": [ + { + "family": "IPv4", + "ip-prefix": "1.0.0.1/30", + "name": "Ethernet0", + "scope": "global" + } + ], + "INTERFACE_LIST": [ + { + "name": "Ethernet0" + } + ] + } + }, + "sonic-port:sonic-port": { + "sonic-port:PORT": { + "PORT_LIST": [ + { + "admin_status": "up", + "alias": "eth8", + "description": "Ethernet8", + "fec": "rs", + "lanes": "65", + "mtu": 9000, + "name": "Ethernet8", + "speed": 25000 + } + ] + } + }, + "sonic-interface:sonic-interface": { + "sonic-interface:INTERFACE": { + "INTERFACE_IPPREFIX_LIST": [ + { + "family": "IPv4", + "ip-prefix": "2.0.0.1/30", + "name": "Ethernet8", + "scope": "global" + } + ], + "INTERFACE_LIST": [ + { + "name": "Ethernet8" + } + ] + } + }, + "sonic-static-route:sonic-static-route": { + "sonic-static-route:STATIC_ROUTE": { + "STATIC_ROUTE_LIST": [{ + "prefix": "15.15.15.0/24", + "vrf_name": "default", + "nexthop": "1.0.0.2,2.0.0.2", + "distance": "1,1", + "nexthop-vrf": "default,default", + "blackhole": "false,false" + }] + } + } + }, + "STATIC_ROUTE_TEST_ECMP_WITH_MGMT": { + "sonic-port:sonic-port": { + "sonic-port:PORT": { + "PORT_LIST": [ + { + "admin_status": "up", + "alias": "eth0", + "description": "Ethernet0", + "fec": "rs", + "lanes": "65", + "mtu": 9000, + "name": "Ethernet0", + "speed": 25000 + } + ] + } + }, + "sonic-interface:sonic-interface": { + "sonic-interface:INTERFACE": { + "INTERFACE_IPPREFIX_LIST": [ + { + "family": "IPv4", + "ip-prefix": "1.0.0.1/30", + "name": "Ethernet0", + "scope": "global" + } + ], + "INTERFACE_LIST": [ + { + "name": "Ethernet0" + } + ] + } + }, + "sonic-port:sonic-port": { + "sonic-port:PORT": { + "PORT_LIST": [ + { + "admin_status": "up", + "alias": "eth8", + "description": "Ethernet8", + "fec": "rs", + "lanes": "65", + "mtu": 9000, + "name": "Ethernet8", + "speed": 25000 + } + ] + } + }, + "sonic-interface:sonic-interface": { + "sonic-interface:INTERFACE": { + "INTERFACE_IPPREFIX_LIST": [ + { + "family": "IPv4", + "ip-prefix": "2.0.0.1/30", + "name": "Ethernet8", + "scope": "global" + } + ], + "INTERFACE_LIST": [ + { + "name": "Ethernet8" + } + ] + } + }, + "sonic-static-route:sonic-static-route": { + "sonic-static-route:STATIC_ROUTE": { + "STATIC_ROUTE_LIST": [{ + "prefix": "15.15.15.0/24", + "vrf_name": "default", + "nexthop": "1.0.0.2,2.0.0.2", + "distance": "1,1", + "nexthop-vrf": "default,mgmt", + "blackhole": "false,false" + }] + } + } + }, + "STATIC_ROUTE_TEST_ECMP_WITH_INTERFACE": { + "sonic-port:sonic-port": { + "sonic-port:PORT": { + "PORT_LIST": [ + { + "admin_status": "up", + "alias": "eth0", + "description": "Ethernet0", + "fec": "rs", + "lanes": "65", + "mtu": 9000, + "name": "Ethernet0", + "speed": 25000 + } + ] + } + }, + "sonic-interface:sonic-interface": { + "sonic-interface:INTERFACE": { + "INTERFACE_IPPREFIX_LIST": [ + { + "family": "IPv4", + "ip-prefix": "1.0.0.1/30", + "name": "Ethernet0", + "scope": "global" + } + ], + "INTERFACE_LIST": [ + { + "name": "Ethernet0" + } + ] + } + }, + "sonic-port:sonic-port": { + "sonic-port:PORT": { + "PORT_LIST": [ + { + "admin_status": "up", + "alias": "eth8", + "description": "Ethernet8", + "fec": "rs", + "lanes": "65", + "mtu": 9000, + "name": "Ethernet8", + "speed": 25000 + } + ] + } + }, + "sonic-interface:sonic-interface": { + "sonic-interface:INTERFACE": { + "INTERFACE_IPPREFIX_LIST": [ + { + "family": "IPv4", + "ip-prefix": "2.0.0.1/30", + "name": "Ethernet8", + "scope": "global" + } + ], + "INTERFACE_LIST": [ + { + "name": "Ethernet8" + } + ] + } + }, + "sonic-static-route:sonic-static-route": { + "sonic-static-route:STATIC_ROUTE": { + "STATIC_ROUTE_LIST": [{ + "prefix": "16.16.16.0/24", + "vrf_name": "default", + "nexthop": "0.0.0.0,0.0.0.0", + "ifname": "Ethernet0,Ethernet8", + "distance": "1,1", + "nexthop-vrf": "default,default", + "blackhole": "false,false" + }] + } + } + }, + "STATIC_ROUTE_TEST_DISTANCE_INVALID": { + "sonic-port:sonic-port": { + "sonic-port:PORT": { + "PORT_LIST": [ + { + "admin_status": "up", + "alias": "eth0", + "description": "Ethernet0", + "fec": "rs", + "lanes": "65", + "mtu": 9000, + "name": "Ethernet0", + "speed": 25000 + } + ] + } + }, + "sonic-interface:sonic-interface": { + "sonic-interface:INTERFACE": { + "INTERFACE_IPPREFIX_LIST": [ + { + "family": "IPv4", + "ip-prefix": "1.0.0.1/30", + "name": "Ethernet0", + "scope": "global" + } + ], + "INTERFACE_LIST": [ + { + "name": "Ethernet0" + } + ] + } + }, + "sonic-static-route:sonic-static-route": { + "sonic-static-route:STATIC_ROUTE": { + "STATIC_ROUTE_LIST": [{ + "prefix": "16.16.16.0/24", + "vrf_name": "default", + "nexthop": "1.0.0.4", + "distance": "300", + "nexthop-vrf": "default", + "blackhole": "false" + }] + } + } + }, + "STATIC_ROUTE_TEST_BLACKHOLE_INVALID": { + "sonic-port:sonic-port": { + "sonic-port:PORT": { + "PORT_LIST": [ + { + "admin_status": "up", + "alias": "eth0", + "description": "Ethernet0", + "fec": "rs", + "lanes": "65", + "mtu": 9000, + "name": "Ethernet0", + "speed": 25000 + } + ] + } + }, + "sonic-interface:sonic-interface": { + "sonic-interface:INTERFACE": { + "INTERFACE_IPPREFIX_LIST": [ + { + "family": "IPv4", + "ip-prefix": "1.0.0.1/30", + "name": "Ethernet0", + "scope": "global" + } + ], + "INTERFACE_LIST": [ + { + "name": "Ethernet0" + } + ] + } + }, + "sonic-static-route:sonic-static-route": { + "sonic-static-route:STATIC_ROUTE": { + "STATIC_ROUTE_LIST": [{ + "prefix": "16.16.16.0/24", + "vrf_name": "default", + "nexthop": "1.0.0.5", + "distance": "1", + "nexthop-vrf": "default", + "blackhole": "down" + }] + } + } + }, + "STATIC_ROUTE_TEST_NEXTHOP_VRF_INVALID": { + "sonic-port:sonic-port": { + "sonic-port:PORT": { + "PORT_LIST": [ + { + "admin_status": "up", + "alias": "eth0", + "description": "Ethernet0", + "fec": "rs", + "lanes": "65", + "mtu": 9000, + "name": "Ethernet0", + "speed": 25000 + } + ] + } + }, + "sonic-interface:sonic-interface": { + "sonic-interface:INTERFACE": { + "INTERFACE_IPPREFIX_LIST": [ + { + "family": "IPv4", + "ip-prefix": "1.0.0.1/30", + "name": "Ethernet0", + "scope": "global" + } + ], + "INTERFACE_LIST": [ + { + "name": "Ethernet0" + } + ] + } + }, + "sonic-static-route:sonic-static-route": { + "sonic-static-route:STATIC_ROUTE": { + "STATIC_ROUTE_LIST": [{ + "prefix": "16.16.16.0/24", + "vrf_name": "default", + "nexthop": "1.0.05", + "distance": "1", + "nexthop-vrf": "vrf123", + "blackhole": "false" + }] + } + } + }, + "STATIC_ROUTE_TEST_NEXTHOP_VRF_INVALID": { + "sonic-port:sonic-port": { + "sonic-port:PORT": { + "PORT_LIST": [ + { + "admin_status": "up", + "alias": "eth0", + "description": "Ethernet0", + "fec": "rs", + "lanes": "65", + "mtu": 9000, + "name": "Ethernet0", + "speed": 25000 + } + ] + } + }, + "sonic-interface:sonic-interface": { + "sonic-interface:INTERFACE": { + "INTERFACE_IPPREFIX_LIST": [ + { + "family": "IPv4", + "ip-prefix": "1.0.0.1/30", + "name": "Ethernet0", + "scope": "global" + } + ], + "INTERFACE_LIST": [ + { + "name": "Ethernet0" + } + ] + } + }, + "sonic-static-route:sonic-static-route": { + "sonic-static-route:STATIC_ROUTE": { + "STATIC_ROUTE_LIST": [{ + "prefix": "16.16.16.0/24", + "vrf_name": "default", + "nexthop": "1.0.05", + "distance": "1", + "nexthop-vrf": "vrf123", + "blackhole": "false" + }] + } + } + }, + "STATIC_ROUTE_TEST_ECMP_DISTANCE_INVALID": { + "sonic-port:sonic-port": { + "sonic-port:PORT": { + "PORT_LIST": [ + { + "admin_status": "up", + "alias": "eth0", + "description": "Ethernet0", + "fec": "rs", + "lanes": "65", + "mtu": 9000, + "name": "Ethernet0", + "speed": 25000 + } + ] + } + }, + "sonic-interface:sonic-interface": { + "sonic-interface:INTERFACE": { + "INTERFACE_IPPREFIX_LIST": [ + { + "family": "IPv4", + "ip-prefix": "1.0.0.1/30", + "name": "Ethernet0", + "scope": "global" + } + ], + "INTERFACE_LIST": [ + { + "name": "Ethernet0" + } + ] + } + }, + "sonic-port:sonic-port": { + "sonic-port:PORT": { + "PORT_LIST": [ + { + "admin_status": "up", + "alias": "eth8", + "description": "Ethernet8", + "fec": "rs", + "lanes": "65", + "mtu": 9000, + "name": "Ethernet8", + "speed": 25000 + } + ] + } + }, + "sonic-interface:sonic-interface": { + "sonic-interface:INTERFACE": { + "INTERFACE_IPPREFIX_LIST": [ + { + "family": "IPv4", + "ip-prefix": "2.0.0.1/30", + "name": "Ethernet8", + "scope": "global" + } + ], + "INTERFACE_LIST": [ + { + "name": "Ethernet8" + } + ] + } + }, + "sonic-static-route:sonic-static-route": { + "sonic-static-route:STATIC_ROUTE": { + "STATIC_ROUTE_LIST": [{ + "prefix": "16.16.16.0/24", + "vrf_name": "default", + "nexthop": "1.0.0.3,2.0.0.8", + "distance": "1000,1", + "nexthop-vrf": "default,default", + "blackhole": "false,false" + }] + } + } + }, + "STATIC_ROUTE_TEST_ECMP_BLACKHOLE_INVALID": { + "sonic-port:sonic-port": { + "sonic-port:PORT": { + "PORT_LIST": [ + { + "admin_status": "up", + "alias": "eth0", + "description": "Ethernet0", + "fec": "rs", + "lanes": "65", + "mtu": 9000, + "name": "Ethernet0", + "speed": 25000 + } + ] + } + }, + "sonic-interface:sonic-interface": { + "sonic-interface:INTERFACE": { + "INTERFACE_IPPREFIX_LIST": [ + { + "family": "IPv4", + "ip-prefix": "1.0.0.1/30", + "name": "Ethernet0", + "scope": "global" + } + ], + "INTERFACE_LIST": [ + { + "name": "Ethernet0" + } + ] + } + }, + "sonic-port:sonic-port": { + "sonic-port:PORT": { + "PORT_LIST": [ + { + "admin_status": "up", + "alias": "eth8", + "description": "Ethernet8", + "fec": "rs", + "lanes": "65", + "mtu": 9000, + "name": "Ethernet8", + "speed": 25000 + } + ] + } + }, + "sonic-interface:sonic-interface": { + "sonic-interface:INTERFACE": { + "INTERFACE_IPPREFIX_LIST": [ + { + "family": "IPv4", + "ip-prefix": "2.0.0.1/30", + "name": "Ethernet8", + "scope": "global" + } + ], + "INTERFACE_LIST": [ + { + "name": "Ethernet8" + } + ] + } + }, + "sonic-static-route:sonic-static-route": { + "sonic-static-route:STATIC_ROUTE": { + "STATIC_ROUTE_LIST": [{ + "prefix": "16.16.16.0/24", + "vrf_name": "default", + "nexthop": "1.0.0.4,2.0.0.3", + "distance": "1,1", + "nexthop-vrf": "default,default", + "blackhole": "no,no" + }] + } + } + }, + "STATIC_ROUTE_TEST_ECMP_NEXTHOP_VRF_INVALID": { + "sonic-port:sonic-port": { + "sonic-port:PORT": { + "PORT_LIST": [ + { + "admin_status": "up", + "alias": "eth0", + "description": "Ethernet0", + "fec": "rs", + "lanes": "65", + "mtu": 9000, + "name": "Ethernet0", + "speed": 25000 + } + ] + } + }, + "sonic-interface:sonic-interface": { + "sonic-interface:INTERFACE": { + "INTERFACE_IPPREFIX_LIST": [ + { + "family": "IPv4", + "ip-prefix": "1.0.0.1/30", + "name": "Ethernet0", + "scope": "global" + } + ], + "INTERFACE_LIST": [ + { + "name": "Ethernet0" + } + ] + } + }, + "sonic-port:sonic-port": { + "sonic-port:PORT": { + "PORT_LIST": [ + { + "admin_status": "up", + "alias": "eth8", + "description": "Ethernet8", + "fec": "rs", + "lanes": "65", + "mtu": 9000, + "name": "Ethernet8", + "speed": 25000 + } + ] + } + }, + "sonic-interface:sonic-interface": { + "sonic-interface:INTERFACE": { + "INTERFACE_IPPREFIX_LIST": [ + { + "family": "IPv4", + "ip-prefix": "2.0.0.1/30", + "name": "Ethernet8", + "scope": "global" + } + ], + "INTERFACE_LIST": [ + { + "name": "Ethernet8" + } + ] + } + }, + "sonic-static-route:sonic-static-route": { + "sonic-static-route:STATIC_ROUTE": { + "STATIC_ROUTE_LIST": [{ + "prefix": "16.16.16.0/24", + "vrf_name": "default", + "nexthop": "1.0.0.4,2.0.0.3", + "distance": "1,1", + "nexthop-vrf": "vrf123,xyz", + "blackhole": "false,false" + }] + } + } + } + +} + + diff --git a/src/sonic-yang-models/yang-models/sonic-static-route.yang b/src/sonic-yang-models/yang-models/sonic-static-route.yang new file mode 100644 index 000000000000..48a562f242d9 --- /dev/null +++ b/src/sonic-yang-models/yang-models/sonic-static-route.yang @@ -0,0 +1,124 @@ +module sonic-static-route { + yang-version 1.1; + namespace "http://github.com/Azure/sonic-static-route"; + prefix sroute; + + import sonic-vrf { + prefix vrf; + } + import ietf-inet-types { + prefix inet; + } + import sonic-types { + prefix stypes; + } + + organization + "SONiC"; + contact + "SONiC"; + description + "STATIC ROUTE yang Module for SONiC OS"; + + revision 2022-03-17 { + description + "First Revision"; + } + + container sonic-static-route { + container STATIC_ROUTE { + description + "STATIC_ROUTE part of config_db.json"; + list STATIC_ROUTE_TEMPLATE_LIST { + key "prefix"; + leaf prefix { + type inet:ip-prefix; + description + "prefix is the destination IP address, as key"; + } + leaf nexthop { + type string; + description + "The next-hop that is to be used for the + static route as IP address. When interface needs to be + specified, use 0.0.0.0 as leaf value"; + } + leaf ifname { + type string; + description + "When interface is specified, forwarding happens through it"; + } + leaf advertise { + type string { + pattern "((true|false),)*(true|false)"; + } + default "false"; + } + } + list STATIC_ROUTE_LIST { + key "vrf_name prefix"; + leaf vrf_name { + type union { + type string { + pattern 'default'; + } + type string { + pattern 'mgmt'; + } + type string { + pattern "Vrf[a-zA-Z0-9_-]+"; + } + } + description + "Virtual Routing Instance name as key"; + } + leaf prefix { + type inet:ip-prefix; + description + "prefix is the destination IP address, as key"; + } + leaf nexthop { + type string; + description + "The next-hop that is to be used for the + static route as IP address. When interface needs to be + specified, use 0.0.0.0 as leaf value"; + } + leaf ifname { + type string; + description + "When interface is specified, forwarding happens through it"; + } + leaf distance { + type string { + pattern "((25[0-5]|2[0-4][0-9]|[0-1]?[0-9][0-9]?),)*(25[0-5]|2[0-4][0-9]|[0-1]?[0-9][0-9]?)"; + } + default "0"; + description + "Administrative Distance (preference) of the entry. The + preference defines the order of selection when multiple + sources (protocols, static, etc.) contribute to the same + prefix entry. The lower the preference, the more preferable the + prefix is. When this value is not specified, the preference is + inherited from the default preference of the implementation for + static routes."; + } + leaf nexthop-vrf { + type string { + pattern "(((Vrf[a-zA-Z0-9_-]+)|(default)|(mgmt)),)*((Vrf[a-zA-Z0-9_-]+)|(default)|(mgmt))"; + } + description + "VRF name of the nexthop. This is for vrf leaking"; + } + leaf blackhole { + type string { + pattern "((true|false),)*(true|false)"; + } + default "false"; + description + "blackhole refers to a route that, if matched, discards the message silently."; + } + } /* end of list STATIC_ROUTE_LIST */ + } /* end of container STATIC_ROUTE */ + } /* end of container sonic-static_route */ +} From 98d6357ae70d903c04e1ef883887a5e15d7be348 Mon Sep 17 00:00:00 2001 From: Liu Shilong Date: Thu, 8 Sep 2022 17:23:29 +0800 Subject: [PATCH 085/151] [actions] Remove approve step in label action. (#12015) Why I did it Approve step needs special permission settings. We already added permission setting to enable bypass merging PR. So, approve step is not necessary. --- .github/workflows/label.yml | 9 --------- 1 file changed, 9 deletions(-) diff --git a/.github/workflows/label.yml b/.github/workflows/label.yml index ec04157110ae..5f8c0279b7e1 100644 --- a/.github/workflows/label.yml +++ b/.github/workflows/label.yml @@ -22,15 +22,6 @@ jobs: label: runs-on: ubuntu-latest steps: - - name: approve - env: - GITHUB_CONTEXT: ${{ toJson(github) }} - run: | - set -e - echo ${{ secrets.GITHUB_TOKEN }} | gh auth login --with-token - url=$(echo $GITHUB_CONTEXT | jq -r '.event.pull_request._links.html.href') - echo PR: $url - gh pr review $url --approve - uses: actions/labeler@main with: repo-token: "${{ secrets.GITHUB_TOKEN }}" From 016f6718572542327f941a884a87245ab5d94725 Mon Sep 17 00:00:00 2001 From: Ze Gan Date: Thu, 8 Sep 2022 23:45:06 +0800 Subject: [PATCH 086/151] [docker-macsec]: Add dependencies of MACsec (#11770) Why I did it If the SWSS services was restarted, the MACsec service should also be restarted. Otherwise the data in wpa_supplicant and orchagent will not be consistent. How I did it Add dependency in docker-macsec.mk. How to verify it Manually check by 'sudo service swss restart'. The MACsec container should be started after swss, the syslog will look like Sep 8 14:36:29.562953 sonic INFO swss.sh[9661]: Starting existing swss container with HWSKU Force10-S6000 Sep 8 14:36:30.024399 sonic DEBUG container: container_start: BEGIN ... Sep 8 14:36:33.391706 sonic INFO systemd[1]: Starting macsec container... Sep 8 14:36:33.392925 sonic INFO systemd[1]: Starting Management Framework container... Signed-off-by: Ze Gan --- files/scripts/swss.sh | 16 +++++++++++++++- rules/docker-macsec.mk | 3 +++ 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/files/scripts/swss.sh b/files/scripts/swss.sh index 3ab4242c902f..3841f77cc30b 100755 --- a/files/scripts/swss.sh +++ b/files/scripts/swss.sh @@ -30,7 +30,7 @@ function read_dependent_services() fi if [[ -f ${ETC_SONIC_PATH}/${SERVICE}_multi_inst_dependent ]]; then - MULTI_INST_DEPENDENT="${MULTI_INST_DEPENDENT} cat ${ETC_SONIC_PATH}/${SERVICE}_multi_inst_dependent" + MULTI_INST_DEPENDENT="${MULTI_INST_DEPENDENT} $(cat ${ETC_SONIC_PATH}/${SERVICE}_multi_inst_dependent)" fi } @@ -308,6 +308,19 @@ function check_peer_gbsyncd() fi } +function check_macsec() +{ + MACSEC_STATE=`show feature status | grep macsec | awk '{print $2}'` + + if [[ ${MACSEC_STATE} == 'enabled' ]]; then + if [ "$DEV" ]; then + DEPENDENT="${DEPENDENT} macsec@${DEV}" + else + DEPENDENT="${DEPENDENT} macsec" + fi + fi +} + if [ "$DEV" ]; then NET_NS="$NAMESPACE_PREFIX$DEV" #name of the network namespace SONIC_DB_CLI="sonic-db-cli -n $NET_NS" @@ -319,6 +332,7 @@ else fi check_peer_gbsyncd +check_macsec read_dependent_services case "$1" in diff --git a/rules/docker-macsec.mk b/rules/docker-macsec.mk index 5db5ea5a41d9..d4cce3ecfcb7 100644 --- a/rules/docker-macsec.mk +++ b/rules/docker-macsec.mk @@ -42,6 +42,9 @@ $(DOCKER_MACSEC)_RUN_OPT += --privileged -t $(DOCKER_MACSEC)_RUN_OPT += -v /etc/sonic:/etc/sonic:ro $(DOCKER_MACSEC)_RUN_OPT += -v /host/warmboot:/var/warmboot +$(DOCKER_MACSEC)_SERVICE_REQUIRES = updategraph +$(DOCKER_MACSEC)_SERVICE_AFTER = swss syncd + $(DOCKER_MACSEC)_CLI_CONFIG_PLUGIN = /cli/config/plugins/macsec.py $(DOCKER_MACSEC)_CLI_SHOW_PLUGIN = /cli/show/plugins/show_macsec.py $(DOCKER_MACSEC)_CLI_CLEAR_PLUGIN = /cli/clear/plugins/clear_macsec_counter.py From dc9eaa53fb1e3a10c733c4ad381379f963cd773a Mon Sep 17 00:00:00 2001 From: bingwang-ms <66248323+bingwang-ms@users.noreply.github.com> Date: Fri, 9 Sep 2022 00:18:26 +0800 Subject: [PATCH 087/151] Map TC6 to Queue 1 for regular traffic (#11904) Why I did it This PR is to update TC_TO_QUEUE_MAP|AZURE for SKU Arista-7050CX3-32S-D48C8 and Arista-7260CX3 T0. The change is only to align the TC_TO_QUEUE_MAP for regular traffic and bounced traffic. It has no impact on business because we have no traffic being mapped to TC2 or TC6. How I did it Update TC_TO_QUEUE_MAP|AZURE , and test cases as well. How to verify it Verified by running test case test_j2files.py /sonic/src/sonic-config-engine$ python3 setup.py test -s tests/test_j2files.py running test ...... ---------------------------------------------------------------------- Ran 29 tests in 25.390s OK --- .../Arista-7050CX3-32S-D48C8/qos.json.j2 | 2 +- device/common/profiles/th2/7260/BALANCED/qos.json.j2 | 2 +- device/common/profiles/th2/7260/RDMA-CENTRIC/qos.json.j2 | 2 +- .../tests/sample_output/py3/qos-arista7050cx3-dualtor.json | 2 +- .../tests/sample_output/py3/qos-arista7260-dualtor.json | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/device/arista/x86_64-arista_7050cx3_32s/Arista-7050CX3-32S-D48C8/qos.json.j2 b/device/arista/x86_64-arista_7050cx3_32s/Arista-7050CX3-32S-D48C8/qos.json.j2 index 6719911b29e5..040da33dd79f 100644 --- a/device/arista/x86_64-arista_7050cx3_32s/Arista-7050CX3-32S-D48C8/qos.json.j2 +++ b/device/arista/x86_64-arista_7050cx3_32s/Arista-7050CX3-32S-D48C8/qos.json.j2 @@ -170,7 +170,7 @@ "3": "3", "4": "4", "5": "5", - "6": "6", + "6": "1", "7": "7", "8": "1" }, diff --git a/device/common/profiles/th2/7260/BALANCED/qos.json.j2 b/device/common/profiles/th2/7260/BALANCED/qos.json.j2 index 68daa8ee92f0..750d0fb0ea77 100644 --- a/device/common/profiles/th2/7260/BALANCED/qos.json.j2 +++ b/device/common/profiles/th2/7260/BALANCED/qos.json.j2 @@ -322,7 +322,7 @@ "3": "3", "4": "4", "5": "5", - "6": "6", + "6": "1", "7": "7", "8": "1" }, diff --git a/device/common/profiles/th2/7260/RDMA-CENTRIC/qos.json.j2 b/device/common/profiles/th2/7260/RDMA-CENTRIC/qos.json.j2 index faf682d3c176..771b8305f8f0 100644 --- a/device/common/profiles/th2/7260/RDMA-CENTRIC/qos.json.j2 +++ b/device/common/profiles/th2/7260/RDMA-CENTRIC/qos.json.j2 @@ -321,7 +321,7 @@ "3": "3", "4": "4", "5": "5", - "6": "6", + "6": "1", "7": "7", "8": "1" }, diff --git a/src/sonic-config-engine/tests/sample_output/py3/qos-arista7050cx3-dualtor.json b/src/sonic-config-engine/tests/sample_output/py3/qos-arista7050cx3-dualtor.json index 8e1d376f19db..00bf9a9a438c 100644 --- a/src/sonic-config-engine/tests/sample_output/py3/qos-arista7050cx3-dualtor.json +++ b/src/sonic-config-engine/tests/sample_output/py3/qos-arista7050cx3-dualtor.json @@ -19,7 +19,7 @@ "3": "3", "4": "4", "5": "5", - "6": "6", + "6": "1", "7": "7", "8": "1" }, diff --git a/src/sonic-config-engine/tests/sample_output/py3/qos-arista7260-dualtor.json b/src/sonic-config-engine/tests/sample_output/py3/qos-arista7260-dualtor.json index cdb6e8fe842e..4d16791f9287 100644 --- a/src/sonic-config-engine/tests/sample_output/py3/qos-arista7260-dualtor.json +++ b/src/sonic-config-engine/tests/sample_output/py3/qos-arista7260-dualtor.json @@ -19,7 +19,7 @@ "3": "3", "4": "4", "5": "5", - "6": "6", + "6": "1", "7": "7", "8": "1" }, From 19155df148fbb49eecd2ce4a3b8f022a66beab76 Mon Sep 17 00:00:00 2001 From: xumia <59720581+xumia@users.noreply.github.com> Date: Fri, 9 Sep 2022 00:33:01 +0800 Subject: [PATCH 088/151] Fix dbus-run-session command not found issue when install dbus-python (#12009) --- platform/vs/docker-sonic-vs/Dockerfile.j2 | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/platform/vs/docker-sonic-vs/Dockerfile.j2 b/platform/vs/docker-sonic-vs/Dockerfile.j2 index 6594630cc20f..7585b7f6f6e3 100644 --- a/platform/vs/docker-sonic-vs/Dockerfile.j2 +++ b/platform/vs/docker-sonic-vs/Dockerfile.j2 @@ -72,7 +72,8 @@ RUN apt-get install -y net-tools \ {%- if ENABLE_ASAN == "y" %} libasan5 \ {%- endif %} - libsystemd0 + libsystemd0 \ + dbus # Install redis-server {% if CONFIGURED_ARCH == "armhf" %} From 549bb3d4833425bcc2e8f0666ec0a13a995d54be Mon Sep 17 00:00:00 2001 From: Oleksandr Ivantsiv Date: Fri, 9 Sep 2022 00:16:11 +0200 Subject: [PATCH 089/151] [services] Update "WantedBy=" section for tacacs-config.timer. (#11893) The timer execution may fail if triggered during a config reload (when the sonic.target is stopped). This might happen in a rare situation if config reload is executed after reboot in a small time slot (for 0 to 30 seconds) before the tacacs-config timer is triggered. To ensure that timer execution will be resumed after a config reload the WantedBy section of the systemd service is updated to describe relation to sonic.target. Signed-off-by: Oleksandr Ivantsiv Signed-off-by: Oleksandr Ivantsiv --- files/build_templates/tacacs-config.timer | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/files/build_templates/tacacs-config.timer b/files/build_templates/tacacs-config.timer index 28314e06f4cb..f8380cbab12d 100644 --- a/files/build_templates/tacacs-config.timer +++ b/files/build_templates/tacacs-config.timer @@ -9,4 +9,4 @@ OnBootSec=5min 30 sec Unit=tacacs-config.service [Install] -WantedBy=timers.target updategraph.service +WantedBy=timers.target sonic.target sonic-delayed.target From acc17db0c804c899dc7fb1dc4c28f14f81f320c1 Mon Sep 17 00:00:00 2001 From: ShiyanWangMS Date: Fri, 9 Sep 2022 22:18:13 +0800 Subject: [PATCH 090/151] Revert PR#11831 (#12035) "Upgrade docker-sonic-mgmt base image from Ubuntu18.04 to 20.04" --- dockers/docker-sonic-mgmt/Dockerfile.j2 | 22 ++++++++++------------ 1 file changed, 10 insertions(+), 12 deletions(-) diff --git a/dockers/docker-sonic-mgmt/Dockerfile.j2 b/dockers/docker-sonic-mgmt/Dockerfile.j2 index 1275a21c5af2..42aaa3525a64 100755 --- a/dockers/docker-sonic-mgmt/Dockerfile.j2 +++ b/dockers/docker-sonic-mgmt/Dockerfile.j2 @@ -1,5 +1,5 @@ {% set prefix = DEFAULT_CONTAINER_REGISTRY %} -FROM {{ prefix }}ubuntu:20.04 +FROM {{ prefix }}ubuntu:18.04 ENV DEBIAN_FRONTEND=noninteractive @@ -21,6 +21,8 @@ RUN apt-get update && apt-get install -y build-essential \ psmisc \ python \ python-dev \ + python-scapy \ + python-pip \ python3-pip \ python3-venv \ rsyslog \ @@ -29,16 +31,10 @@ RUN apt-get update && apt-get install -y build-essential \ sudo \ tcpdump \ telnet \ - vim \ - python-is-python2 \ - software-properties-common - -RUN add-apt-repository -y universe -RUN curl https://bootstrap.pypa.io/pip/2.7/get-pip.py --output get-pip.py \ - && python2 get-pip.py + vim RUN pip install setuptools==44.1.1 -RUN pip install cffi==1.12.0 \ +RUN pip install cffi==1.10.0 \ contextlib2==0.6.0.post1 \ cryptography==3.3.2 \ "future>=0.16.0" \ @@ -100,7 +96,7 @@ RUN pip install cffi==1.12.0 \ && rm -f 1.0.0.tar.gz \ && pip install nnpy \ && pip install dpkt \ - && pip install scapy==2.4.5 --upgrade --ignore-installed + && pip install scapy==2.4.5 --upgrade # Install docker-ce-cli RUN apt-get update \ @@ -131,7 +127,7 @@ debs/{{ deb }}{{' '}} {%- endfor -%} debs/ -RUN dpkg --force-all -i \ +RUN dpkg -i \ {% for deb in docker_sonic_mgmt_debs.split(' ') -%} debs/{{ deb }}{{' '}} {%- endfor %} @@ -197,7 +193,8 @@ ENV PATH="$VIRTUAL_ENV/bin:$PATH" ENV LANG=C.UTF-8 LC_ALL=C.UTF-8 PYTHONIOENCODING=UTF-8 -RUN python3 -m pip install --upgrade --ignore-installed pip setuptools==58.4.0 wheel==0.33.6 +RUN python3 -m pip install --upgrade --ignore-installed pip setuptools==58.4.0 + RUN python3 -m pip install setuptools-rust \ aiohttp \ defusedxml \ @@ -240,6 +237,7 @@ RUN python3 -m pip install setuptools-rust \ tabulate \ textfsm==1.1.2 \ virtualenv \ + wheel==0.33.6 \ pysubnettree \ nnpy \ dpkt \ From a2262394397e37f18d402dd6a45a645b35e70528 Mon Sep 17 00:00:00 2001 From: Ying Xie Date: Fri, 9 Sep 2022 08:41:41 -0700 Subject: [PATCH 091/151] [zebra] ignore route from default table (#12018) Signed-off-by: Ying Xie Signed-off-by: Ying Xie --- ...0009-ignore-route-from-default-table.patch | 30 +++++++++++++++++++ src/sonic-frr/patch/series | 1 + 2 files changed, 31 insertions(+) create mode 100644 src/sonic-frr/patch/0009-ignore-route-from-default-table.patch diff --git a/src/sonic-frr/patch/0009-ignore-route-from-default-table.patch b/src/sonic-frr/patch/0009-ignore-route-from-default-table.patch new file mode 100644 index 000000000000..ec41da74dad8 --- /dev/null +++ b/src/sonic-frr/patch/0009-ignore-route-from-default-table.patch @@ -0,0 +1,30 @@ +From bb3b003840959adf5b5be52e91bc798007c9857a Mon Sep 17 00:00:00 2001 +From: Ying Xie +Date: Thu, 8 Sep 2022 04:20:36 +0000 +Subject: [PATCH] From 776a29e8ab32c1364ee601a8730aabb773b0c86b Mon Sep 17 + 00:00:00 2001 Subject: [PATCH] ignore route from default table + +Signed-off-by: Ying Xie +--- + zebra/zebra_fpm_netlink.c | 5 +++++ + 1 file changed, 5 insertions(+) + +diff --git a/zebra/zebra_fpm_netlink.c b/zebra/zebra_fpm_netlink.c +index 34be9fb39..d6c875a7e 100644 +--- a/zebra/zebra_fpm_netlink.c ++++ b/zebra/zebra_fpm_netlink.c +@@ -283,6 +283,11 @@ static int netlink_route_info_fill(struct netlink_route_info *ri, int cmd, + rib_table_info(rib_dest_table(dest)); + struct zebra_vrf *zvrf = table_info->zvrf; + ++ if (table_info->table_id == RT_TABLE_DEFAULT) { ++ zfpm_debug("%s: Discard default table route", __func__); ++ return 0; ++ } ++ + memset(ri, 0, sizeof(*ri)); + + ri->prefix = rib_dest_prefix(dest); +-- +2.17.1 + diff --git a/src/sonic-frr/patch/series b/src/sonic-frr/patch/series index 3e8438bf6dd5..a474b918a8cc 100644 --- a/src/sonic-frr/patch/series +++ b/src/sonic-frr/patch/series @@ -8,3 +8,4 @@ 0008-Link-local-scope-was-not-set-while-binding-socket-for-bgp-ipv6-link-local-neighbors.patch Disable-ipv6-src-address-test-in-pceplib.patch cross-compile-changes.patch +0009-ignore-route-from-default-table.patch From 714b1807b6e528836c4af2e24d389d72518c0d7e Mon Sep 17 00:00:00 2001 From: anamehra <54692434+anamehra@users.noreply.github.com> Date: Fri, 9 Sep 2022 12:54:05 -0700 Subject: [PATCH 092/151] Fix radv.conf traceback when VLAN_INTERFACE is not defined (#12034) *Fix the if block scope to prevent traceback due to undefined vlan_list when VLAN_INTERFACE is not defined. --- dockers/docker-router-advertiser/radvd.conf.j2 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dockers/docker-router-advertiser/radvd.conf.j2 b/dockers/docker-router-advertiser/radvd.conf.j2 index 3880ef960760..ded5c7e59694 100644 --- a/dockers/docker-router-advertiser/radvd.conf.j2 +++ b/dockers/docker-router-advertiser/radvd.conf.j2 @@ -23,7 +23,6 @@ {% set _ = vlan_list.update({name: prefix_list}) %} {% endif %} {% endfor %} -{% endif %} {% for name, prefixes in vlan_list.items() %} interface {{ name }} { @@ -47,3 +46,4 @@ interface {{ name }} }; {% endfor %} +{% endif %} From 966fe0d2108e63e745d35060a50c3b9b6da83bef Mon Sep 17 00:00:00 2001 From: Zain Budhwani <99770260+zbud-msft@users.noreply.github.com> Date: Fri, 9 Sep 2022 14:23:45 -0700 Subject: [PATCH 093/151] Update gnmi submodule (#11988) * Update gnmi submodule * Update gnmi pointer again --- src/sonic-gnmi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sonic-gnmi b/src/sonic-gnmi index 92428dac99b2..14f91214fe2b 160000 --- a/src/sonic-gnmi +++ b/src/sonic-gnmi @@ -1 +1 @@ -Subproject commit 92428dac99b2d6d97b4c904cb83933cbc8f7e848 +Subproject commit 14f91214fe2b4ba7575bffff58989dbf7df71c48 From 0a8dd3f4f8357f2d470073917fa70cf491dc914b Mon Sep 17 00:00:00 2001 From: FuzailBrcm <51665572+FuzailBrcm@users.noreply.github.com> Date: Sat, 10 Sep 2022 03:03:12 +0530 Subject: [PATCH 094/151] Adding support for get/set low power mode for QSFPs in PDDF common APIs (#11786) * Adding support for get/set low pwer mode for QSFPs in PDDF common APIs * Adding support for get/set low pwer mode for QSFPs in PDDF common APIs - Review comments --- .../sonic_platform_pddf_base/pddf_sfp.py | 30 ++++++++++++++++--- 1 file changed, 26 insertions(+), 4 deletions(-) diff --git a/platform/pddf/platform-api-pddf-base/sonic_platform_pddf_base/pddf_sfp.py b/platform/pddf/platform-api-pddf-base/sonic_platform_pddf_base/pddf_sfp.py index 66fe58543f51..be286bd9eaee 100644 --- a/platform/pddf/platform-api-pddf-base/sonic_platform_pddf_base/pddf_sfp.py +++ b/platform/pddf/platform-api-pddf-base/sonic_platform_pddf_base/pddf_sfp.py @@ -10,6 +10,8 @@ except ImportError as e: raise ImportError(str(e) + "- required module not found") +QSFP_PWR_CTRL_ADDR = 93 + class PddfSfp(SfpOptoeBase): """ @@ -194,8 +196,18 @@ def get_lpmode(self): else: lpmode = False else: - # Use common SfpOptoeBase implementation for get_lpmode - lpmode = super().get_lpmode() + xcvr_id = self._xcvr_api_factory._get_id() + if xcvr_id is not None: + if xcvr_id == 0x18 or xcvr_id == 0x19 or xcvr_id == 0x1e: + # QSFP-DD or OSFP + # Use common SfpOptoeBase implementation for get_lpmode + lpmode = super().get_lpmode() + elif xcvr_id == 0x11 or xcvr_id == 0x0d or xcvr_id == 0x0c: + # QSFP28, QSFP+, QSFP + power_set = self.get_power_set() + power_override = self.get_power_override() + # By default the lpmode pin is pulled high as mentioned in the sff community + return power_set if power_override else True return lpmode @@ -321,8 +333,18 @@ def set_lpmode(self, lpmode): except IOError as e: status = False else: - # Use common SfpOptoeBase implementation for set_lpmode - status = super().set_lpmode(lpmode) + xcvr_id = self._xcvr_api_factory._get_id() + if xcvr_id is not None: + if xcvr_id == 0x18 or xcvr_id == 0x19 or xcvr_id == 0x1e: + # QSFP-DD or OSFP + # Use common SfpOptoeBase implementation for set_lpmode + status = super().set_lpmode(lpmode) + elif xcvr_id == 0x11 or xcvr_id == 0x0d or xcvr_id == 0x0c: + # QSFP28, QSFP+, QSFP + if lpmode is True: + self.set_power_override(True, True) + else: + self.set_power_override(True, False) return status From c53972b34864865a854e75df4ec6bc78ebb1c6cf Mon Sep 17 00:00:00 2001 From: Hasan Naqvi <56742004+hasan-brcm@users.noreply.github.com> Date: Fri, 9 Sep 2022 17:05:48 -0700 Subject: [PATCH 095/151] Update submodule to FRR 8.2.2 (#11502) *The sonic-frr was upgraded to FRR 8.2.2 as part of PR #10691. However, sonic-frr/frr submodule was still referring to previous 7.5 version. Update the sonic-frr/frr submodule to 8.2.2 commit id. Fixes issue #11484. --- src/sonic-frr/frr | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sonic-frr/frr b/src/sonic-frr/frr index c69608a68083..79188bf710e9 160000 --- a/src/sonic-frr/frr +++ b/src/sonic-frr/frr @@ -1 +1 @@ -Subproject commit c69608a68083d1017257977bd0260bebdb12322f +Subproject commit 79188bf710e92acf42fb5b9b0a2e9593a5ee9b05 From a8076e303bebc7907b54f8f0e612424ce67df9dc Mon Sep 17 00:00:00 2001 From: xumia <59720581+xumia@users.noreply.github.com> Date: Mon, 12 Sep 2022 20:31:29 +0800 Subject: [PATCH 096/151] Upgrade the sonic-fips packages to 0.3 (#12040) Why I did it Upgrade the sonic-fips packages to release 0.3 Fix the package timestamp not correct issue --- rules/sonic-fips.mk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rules/sonic-fips.mk b/rules/sonic-fips.mk index a63e00de3fa5..e5b6e4ad3547 100644 --- a/rules/sonic-fips.mk +++ b/rules/sonic-fips.mk @@ -1,6 +1,6 @@ # fips packages -FIPS_VERSION = 0.2 +FIPS_VERSION = 0.3 FIPS_OPENSSL_VERSION = 1.1.1n-0+deb11u3+fips FIPS_OPENSSH_VERSION = 8.4p1-5+deb11u1+fips FIPS_PYTHON_MAIN_VERSION = 3.9 From b34d94be1f22e94759775d72286769e2feae0f76 Mon Sep 17 00:00:00 2001 From: jcaiMR <111116206+jcaiMR@users.noreply.github.com> Date: Tue, 13 Sep 2022 10:07:17 +0800 Subject: [PATCH 097/151] yang model table DEVICE_NEIGHBOR_METADATA creation (#11894) * yang mode support for neighbor metadata * add description in leaf node * modify description --- src/sonic-config-engine/minigraph.py | 40 +++++-- .../tests/test_minigraph_case.py | 39 +++---- .../tests/test_multinpu_cfggen.py | 12 +- src/sonic-yang-models/setup.py | 2 + .../tests/files/sample_config_db.json | 20 ++++ .../tests/device_neighbor_metadata.json | 15 +++ .../device_neighbor_metadata.json | 107 ++++++++++++++++++ .../sonic-device_neighbor_metadata.yang | 100 ++++++++++++++++ 8 files changed, 301 insertions(+), 34 deletions(-) create mode 100644 src/sonic-yang-models/tests/yang_model_tests/tests/device_neighbor_metadata.json create mode 100644 src/sonic-yang-models/tests/yang_model_tests/tests_config/device_neighbor_metadata.json create mode 100644 src/sonic-yang-models/yang-models/sonic-device_neighbor_metadata.yang diff --git a/src/sonic-config-engine/minigraph.py b/src/sonic-config-engine/minigraph.py index 9518678bb5b7..85d9a91030ca 100644 --- a/src/sonic-config-engine/minigraph.py +++ b/src/sonic-config-engine/minigraph.py @@ -260,14 +260,24 @@ def parse_png(png, hname, dpg_ecmp_content = None): if child.tag == str(QName(ns, "Devices")): for device in child.findall(str(QName(ns, "Device"))): (lo_prefix, lo_prefix_v6, mgmt_prefix, mgmt_prefix_v6, name, hwsku, d_type, deployment_id, cluster, d_subtype) = parse_device(device) - device_data = {'lo_addr': lo_prefix, 'type': d_type, 'mgmt_addr': mgmt_prefix, 'hwsku': hwsku} - if cluster: + device_data = {} + if hwsku != None: + device_data['hwsku'] = hwsku + if cluster != None: device_data['cluster'] = cluster - if deployment_id: + if deployment_id != None: device_data['deployment_id'] = deployment_id - if lo_prefix_v6: + if lo_prefix != None: + device_data['lo_addr'] = lo_prefix + if lo_prefix_v6 != None: device_data['lo_addr_v6'] = lo_prefix_v6 - if d_subtype: + if mgmt_prefix != None: + device_data['mgmt_addr'] = mgmt_prefix + if mgmt_prefix_v6 != None: + device_data['mgmt_addr_v6'] = mgmt_prefix_v6 + if d_type != None: + device_data['type'] = d_type + if d_subtype != None: device_data['subtype'] = d_subtype devices[name] = device_data @@ -393,13 +403,23 @@ def parse_asic_png(png, asic_name, hostname): if child.tag == str(QName(ns, "Devices")): for device in child.findall(str(QName(ns, "Device"))): (lo_prefix, lo_prefix_v6, mgmt_prefix, mgmt_prefix_v6, name, hwsku, d_type, deployment_id, cluster, _) = parse_device(device) - device_data = {'lo_addr': lo_prefix, 'type': d_type, 'mgmt_addr': mgmt_prefix, 'hwsku': hwsku } - if cluster: + device_data = {} + if hwsku != None: + device_data['hwsku'] = hwsku + if cluster != None: device_data['cluster'] = cluster - if deployment_id: + if deployment_id != None: device_data['deployment_id'] = deployment_id - if lo_prefix_v6: - device_data['lo_addr_v6']= lo_prefix_v6 + if lo_prefix != None: + device_data['lo_addr'] = lo_prefix + if lo_prefix_v6 != None: + device_data['lo_addr_v6'] = lo_prefix_v6 + if mgmt_prefix != None: + device_data['mgmt_addr'] = mgmt_prefix + if mgmt_prefix_v6 != None: + device_data['mgmt_addr_v6'] = mgmt_prefix_v6 + if d_type != None: + device_data['type'] = d_type devices[name] = device_data return (neighbors, devices, port_speeds) diff --git a/src/sonic-config-engine/tests/test_minigraph_case.py b/src/sonic-config-engine/tests/test_minigraph_case.py index 2aa78944163b..9ee8a49db6ae 100644 --- a/src/sonic-config-engine/tests/test_minigraph_case.py +++ b/src/sonic-config-engine/tests/test_minigraph_case.py @@ -203,39 +203,40 @@ def test_minigraph_neighbor_metadata(self): argument = '-m "' + self.sample_graph + '" -p "' + self.port_config + '" -v "DEVICE_NEIGHBOR_METADATA"' expected_table = { - 'switch-01t1': { - 'lo_addr': '10.1.0.186/32', - 'mgmt_addr': '10.7.0.196/26', - 'hwsku': 'Force10-S6000', - 'type': 'LeafRouter', - 'deployment_id': '2' - }, 'switch2-t0': { - 'hwsku': 'Force10-S6000', 'lo_addr': '25.1.1.10/32', 'mgmt_addr': '10.7.0.196/26', + 'hwsku': 'Force10-S6000', 'type': 'ToRRouter' }, - 'server1': { + 'server2': { + 'lo_addr_v6': 'fe80::0002/128', + 'lo_addr': '10.10.10.2/32', + 'mgmt_addr': '10.0.0.2/32', 'hwsku': 'server-sku', - 'lo_addr': '10.10.10.1/32', - 'lo_addr_v6': 'fe80::0001/80', - 'mgmt_addr': '10.0.0.1/32', 'type': 'Server' }, - 'server2': { + 'server1': { + 'lo_addr_v6': 'fe80::0001/80', + 'lo_addr': '10.10.10.1/32', + 'mgmt_addr': '10.0.0.1/32', 'hwsku': 'server-sku', - 'lo_addr': '10.10.10.2/32', - 'lo_addr_v6': 'fe80::0002/128', - 'mgmt_addr': '10.0.0.2/32', 'type': 'Server' }, + 'switch-01t1': { + 'lo_addr': '10.1.0.186/32', + 'deployment_id': '2', + 'hwsku': 'Force10-S6000', + 'type': 'LeafRouter', + 'mgmt_addr': '10.7.0.196/26' + }, 'server1-SC': { - 'hwsku': 'smartcable-sku', - 'lo_addr': '0.0.0.0/0', 'lo_addr_v6': '::/0', 'mgmt_addr': '0.0.0.0/0', - 'type': 'SmartCable' + 'hwsku': 'smartcable-sku', + 'lo_addr': '0.0.0.0/0', + 'type': 'SmartCable', + 'mgmt_addr_v6': '::/0', } } output = self.run_script(argument) diff --git a/src/sonic-config-engine/tests/test_multinpu_cfggen.py b/src/sonic-config-engine/tests/test_multinpu_cfggen.py index a34b0b6cfd78..2bfb879a1ad2 100644 --- a/src/sonic-config-engine/tests/test_multinpu_cfggen.py +++ b/src/sonic-config-engine/tests/test_multinpu_cfggen.py @@ -250,10 +250,11 @@ def test_frontend_asic_device_neigh(self): def test_frontend_asic_device_neigh_metadata(self): argument = "-m {} -p {} -n asic0 --var-json \"DEVICE_NEIGHBOR_METADATA\"".format(self.sample_graph, self.port_config[0]) output = json.loads(self.run_script(argument)) + print(output) self.assertDictEqual(output, \ - {'01T2': {'lo_addr': None, 'mgmt_addr': '89.139.132.40', 'hwsku': 'VM', 'type': 'SpineRouter'}, - 'ASIC3': {'lo_addr': '0.0.0.0/0', 'lo_addr_v6': '::/0', 'mgmt_addr': '0.0.0.0/0', 'hwsku': 'multi-npu-asic', 'type': 'Asic'}, - 'ASIC2': {'lo_addr': '0.0.0.0/0', 'lo_addr_v6': '::/0', 'mgmt_addr': '0.0.0.0/0', 'hwsku': 'multi-npu-asic', 'type': 'Asic'}}) + {'01T2': {'mgmt_addr': '89.139.132.40', 'hwsku': 'VM', 'type': 'SpineRouter'}, + 'ASIC3': {'lo_addr_v6': '::/0', 'mgmt_addr': '0.0.0.0/0', 'hwsku': 'multi-npu-asic', 'lo_addr': '0.0.0.0/0', 'type': 'Asic', 'mgmt_addr_v6': '::/0'}, + 'ASIC2': {'lo_addr_v6': '::/0', 'mgmt_addr': '0.0.0.0/0', 'hwsku': 'multi-npu-asic', 'lo_addr': '0.0.0.0/0', 'type': 'Asic', 'mgmt_addr_v6': '::/0'}}) def test_backend_asic_device_neigh(self): argument = "-m {} -p {} -n asic3 --var-json \"DEVICE_NEIGHBOR\"".format(self.sample_graph, self.port_config[3]) @@ -267,9 +268,10 @@ def test_backend_asic_device_neigh(self): def test_backend_device_neigh_metadata(self): argument = "-m {} -p {} -n asic3 --var-json \"DEVICE_NEIGHBOR_METADATA\"".format(self.sample_graph, self.port_config[3]) output = json.loads(self.run_script(argument)) + print(output) self.assertDictEqual(output, \ - {'ASIC1': {'lo_addr': '0.0.0.0/0', 'lo_addr_v6': '::/0', 'mgmt_addr': '0.0.0.0/0', 'hwsku': 'multi-npu-asic', 'type': 'Asic'}, - 'ASIC0': {'lo_addr': '0.0.0.0/0', 'lo_addr_v6': '::/0', 'mgmt_addr': '0.0.0.0/0', 'hwsku': 'multi-npu-asic', 'type': 'Asic'}}) + {'ASIC1': {'lo_addr_v6': '::/0', 'mgmt_addr': '0.0.0.0/0', 'hwsku': 'multi-npu-asic', 'lo_addr': '0.0.0.0/0', 'type': 'Asic', 'mgmt_addr_v6': '::/0'}, + 'ASIC0': {'lo_addr_v6': '::/0', 'mgmt_addr': '0.0.0.0/0', 'hwsku': 'multi-npu-asic', 'lo_addr': '0.0.0.0/0', 'type': 'Asic', 'mgmt_addr_v6': '::/0'}}) def test_frontend_bgp_neighbor(self): argument = "-m {} -p {} -n asic0 --var-json \"BGP_NEIGHBOR\"".format(self.sample_graph, self.port_config[0]) diff --git a/src/sonic-yang-models/setup.py b/src/sonic-yang-models/setup.py index 961017fc7ca0..aee9d4650c7a 100644 --- a/src/sonic-yang-models/setup.py +++ b/src/sonic-yang-models/setup.py @@ -103,6 +103,7 @@ def run(self): './yang-models/sonic-default-lossless-buffer-parameter.yang', './yang-models/sonic-device_metadata.yang', './yang-models/sonic-device_neighbor.yang', + './yang-models/sonic-device_neighbor_metadata.yang', './yang-models/sonic-dhcpv6-relay.yang', './yang-models/sonic-extension.yang', './yang-models/sonic-flex_counter.yang', @@ -173,6 +174,7 @@ def run(self): './cvlyang-models/sonic-crm.yang', './cvlyang-models/sonic-device_metadata.yang', './cvlyang-models/sonic-device_neighbor.yang', + './cvlyang-models/sonic-device_neighbor_metadata.yang', './cvlyang-models/sonic-extension.yang', './cvlyang-models/sonic-flex_counter.yang', './cvlyang-models/sonic-feature.yang', diff --git a/src/sonic-yang-models/tests/files/sample_config_db.json b/src/sonic-yang-models/tests/files/sample_config_db.json index ddf83de7f0a1..6c1f47d80f51 100644 --- a/src/sonic-yang-models/tests/files/sample_config_db.json +++ b/src/sonic-yang-models/tests/files/sample_config_db.json @@ -391,6 +391,26 @@ "port": "Eth18" } }, + "DEVICE_NEIGHBOR_METADATA": { + "dccsw01.nw": { + "lo_addr": "0.0.0.0/0", + "mgmt_addr": "10.184.228.211/32", + "hwsku": "Arista", + "type": "LeafRouter", + "deployment_id": "1" + }, + "dccsw02.nw": { + "mgmt_addr_v6": "2a04:5555:40:a709::2/128", + "hwsku": "Arista", + "type": "LeafRouter", + "deployment_id": "1" + }, + "dccsw03.nw": { + "hwsku": "Arista", + "type": "LeafRouter", + "deployment_id": "1" + } + }, "MGMT_PORT": { "eth0": { "alias": "eth0", diff --git a/src/sonic-yang-models/tests/yang_model_tests/tests/device_neighbor_metadata.json b/src/sonic-yang-models/tests/yang_model_tests/tests/device_neighbor_metadata.json new file mode 100644 index 000000000000..2943a53d1b91 --- /dev/null +++ b/src/sonic-yang-models/tests/yang_model_tests/tests/device_neighbor_metadata.json @@ -0,0 +1,15 @@ +{ + "DEVICE_NEIGHBOR_METADATA_TABLE": { + "desc": "DEVICE_NEIGHBOR_METADATA_TABLE config pattern." + }, + "DEVICE_NEIGHBOR_METADATA_TYPE_INCORRECT_PATTERN": { + "desc": "DEVICE_NEIGHBOR_METADATA_TYPE_INCORRECT_PATTERN pattern failure.", + "eStrKey" : "Pattern" + }, + "DEVICE_NEIGHBOR_METADATA_TYPE_CORRECT_PATTERN": { + "desc": "DEVICE_NEIGHBOR_METADATA correct value for Type field" + }, + "DEVICE_NEIGHBOR_METADATA_TYPE_NOT_PROVISIONED_PATTERN": { + "desc": "DEVICE_NEIGHBOR_METADATA value as not-provisioned for Type field" + } +} \ No newline at end of file diff --git a/src/sonic-yang-models/tests/yang_model_tests/tests_config/device_neighbor_metadata.json b/src/sonic-yang-models/tests/yang_model_tests/tests_config/device_neighbor_metadata.json new file mode 100644 index 000000000000..ecc0c35d2208 --- /dev/null +++ b/src/sonic-yang-models/tests/yang_model_tests/tests_config/device_neighbor_metadata.json @@ -0,0 +1,107 @@ +{ + "DEVICE_NEIGHBOR_METADATA_TYPE_INCORRECT_PATTERN": { + "sonic-device_neighbor_metadata:sonic-device_neighbor_metadata": { + "sonic-device_neighbor_metadata:DEVICE_NEIGHBOR_METADATA": { + "DEVICE_NEIGHBOR_METADATA_LIST": [ + { + "name": "Ethernet116", + "hwsku": "Arista", + "type": "ToRrouter" + } + ] + } + } + }, + "DEVICE_NEIGHBOR_METADATA_TYPE_CORRECT_PATTERN": { + "sonic-device_neighbor_metadata:sonic-device_neighbor_metadata": { + "sonic-device_neighbor_metadata:DEVICE_NEIGHBOR_METADATA": { + "DEVICE_NEIGHBOR_METADATA_LIST": [ + { + "name": "Ethernet116", + "hwsku": "Arista", + "type": "BackEndToRRouter" + } + ] + } + } + }, + "DEVICE_NEIGHBOR_METADATA_TYPE_NOT_PROVISIONED_PATTERN": { + "sonic-device_neighbor_metadata:sonic-device_neighbor_metadata": { + "sonic-device_neighbor_metadata:DEVICE_NEIGHBOR_METADATA": { + "DEVICE_NEIGHBOR_METADATA_LIST": [ + { + "name": "Ethernet116", + "hwsku": "Arista", + "type": "not-provisioned" + } + ] + } + } + }, + "DEVICE_NEIGHBOR_METADATA_TABLE": { + "sonic-device_neighbor_metadata:sonic-device_neighbor_metadata": { + "sonic-device_neighbor_metadata:DEVICE_NEIGHBOR_METADATA": { + "DEVICE_NEIGHBOR_METADATA_LIST": [ + { + "lo_addr": "25.77.193.11/32", + "mgmt_addr": "0.0.0.0/0", + "name": "dccsw01.nw", + "hwsku": "Arista", + "type": "ToRRouter", + "deployment_id": "1" + }, + { + "lo_addr": "0.0.0.0/0", + "mgmt_addr": "10.11.150.46/26", + "name": "dccsw02.nw", + "hwsku": "Arista", + "type": "LeafRouter", + "deployment_id": "1" + }, + { + "lo_addr_v6": "2a04:5555:40:a709::2/126", + "mgmt_addr": "10.11.150.47/26", + "name": "dccsw03.nw", + "hwsku": "Arista", + "type": "SpineRouter", + "deployment_id": "1" + }, + { + "name": "dccsw04.nw", + "mgmt_addr_v6": "2a04:5555:40:a708::2/126", + "hwsku": "Arista", + "type": "LeafRouter", + "deployment_id": "1" + }, + { + "name": "dccsw05.nw", + "hwsku": "Arista", + "type": "LeafRouter", + "deployment_id": "1" + }, + { + "lo_addr_v6": "2a04:5555:40:a710::2/126", + "name": "dccsw06.nw", + "hwsku": "Arista", + "type": "LeafRouter", + "deployment_id": "1" + }, + { + "lo_addr": "25.77.193.11/32", + "name": "dccsw07.nw", + "hwsku": "Arista", + "type": "LeafRouter", + "deployment_id": "1" + }, + { + "mgmt_addr": "10.11.150.48/26", + "name": "dccsw08.nw", + "hwsku": "Arista", + "type": "LeafRouter", + "deployment_id": "1" + } + ] + } + } + } +} diff --git a/src/sonic-yang-models/yang-models/sonic-device_neighbor_metadata.yang b/src/sonic-yang-models/yang-models/sonic-device_neighbor_metadata.yang new file mode 100644 index 000000000000..76526f801c92 --- /dev/null +++ b/src/sonic-yang-models/yang-models/sonic-device_neighbor_metadata.yang @@ -0,0 +1,100 @@ +module sonic-device_neighbor_metadata { + + yang-version 1.1; + + namespace "http://github.com/Azure/sonic-device_neighbor_metadata"; + prefix device_neighbor_metadata; + + import ietf-yang-types { + prefix yang; + } + + import ietf-inet-types { + prefix inet; + } + + import sonic-types { + prefix stypes; + } + + description "DEVICE_NEIGHBOR_METADATA YANG Module for SONiC OS"; + + revision 2022-08-25 { + description "First Revision"; + } + + container sonic-device_neighbor_metadata { + + container DEVICE_NEIGHBOR_METADATA { + + description "DEVICE_NEIGHBOR_METADATA part of config_db.json"; + + list DEVICE_NEIGHBOR_METADATA_LIST { + + key "name"; + + leaf name { + description "Host name string, max length 255"; + type string { + length 1..255; + } + } + + leaf hwsku { + type stypes:hwsku; + } + + leaf lo_addr { + description "Device loopback ipv4 address, type of ietf-inet + ipv4-prefix or ipv4-address"; + type union { + type inet:ipv4-prefix; + type inet:ipv4-address; + } + } + + leaf lo_addr_v6 { + description "Device loopback ipv6 address, type of ietf-inet + ipv6-prefix or ipv6-address"; + type union { + type inet:ipv6-prefix; + type inet:ipv6-address; + } + } + + leaf mgmt_addr { + description "Device management ipv4 address, type of ietf-inet + ipv4-prefix or ipv4-address"; + type union { + type inet:ipv4-prefix; + type inet:ipv4-address; + } + } + + leaf mgmt_addr_v6 { + description "Device management ipv6 address, type of ietf-inet + ipv6-prefix or ipv6-address"; + type union { + type inet:ipv6-prefix; + type inet:ipv6-address; + } + } + + leaf type { + description "Network element type"; + type string { + pattern "ToRRouter|LeafRouter|SpineChassisFrontendRouter|ChassisBackendRouter|ASIC|Asic|Supervior|MgmtToRRouter|SpineRouter|BackEndToRRouter|BackEndLeafRouter|EPMS|MgmtTsToR|BmcMgmtToRRouter|Server|MiniPower|SmartCable|Ixia|not-provisioned"; + } + } + + leaf deployment_id { + type uint32; + } + } + /* end of list DEVICE_NEIGHBOR_METADATA_LIST */ + } + /* end of container DEVICE_NEIGHBOR_METADATA */ + } + /* end of container sonic-device_neighbor_metadata */ +} +/* end of module sonic-device_neighbor_metadata */ From 7d1b99a8868ed97971377cf6d30adfcf2d0252d6 Mon Sep 17 00:00:00 2001 From: Mai Bui Date: Tue, 13 Sep 2022 06:52:17 -0700 Subject: [PATCH 098/151] Replace unsafe functions in iccpd (#11694) Why I did it Replace unsafe functions in iccpd How I did it Replace memset() by zero initialization Replace strtok() by strtok_r() Signed-off-by: maipbui --- src/iccpd/src/cmd_option.c | 8 ++++---- src/iccpd/src/iccp_ifm.c | 12 ++++-------- src/iccpd/src/iccp_main.c | 3 +-- src/iccpd/src/iccp_netlink.c | 24 +++++++++--------------- src/iccpd/src/mclagdctl/mclagdctl.c | 3 +-- 5 files changed, 19 insertions(+), 31 deletions(-) diff --git a/src/iccpd/src/cmd_option.c b/src/iccpd/src/cmd_option.c index 596dafb73711..d6e7b14ef7ab 100644 --- a/src/iccpd/src/cmd_option.c +++ b/src/iccpd/src/cmd_option.c @@ -80,26 +80,26 @@ struct CmdOption* cmd_option_add(struct CmdOptionParser* parser, char* opt_name) static void cmd_option_register(struct CmdOptionParser* parser, char* syntax, char* desc) { - char buf[OPTION_MAX_LEN]; + char buf[OPTION_MAX_LEN] = {0}; struct CmdOption* opt = NULL; char* opt_name = NULL; char* param = NULL; char* desc_copy = NULL; char* token = NULL; + char* saveptr; if (parser == NULL) return; if (syntax == NULL) return; - memset(buf, 0, OPTION_MAX_LEN); snprintf(buf, OPTION_MAX_LEN - 1, "%s", syntax); - if ((token = strtok(buf, " ")) == NULL) + if ((token = strtok_r(buf, " ", &saveptr)) == NULL) return; opt_name = strdup(token); - if ((token = strtok(NULL, " ")) != NULL) + if ((token = strtok_r(NULL, " ", &saveptr)) != NULL) param = strdup(token); desc_copy = strdup(desc); if ((opt = cmd_option_find(parser, opt_name)) != NULL) diff --git a/src/iccpd/src/iccp_ifm.c b/src/iccpd/src/iccp_ifm.c index 4349599f5308..5d6d0540e32b 100644 --- a/src/iccpd/src/iccp_ifm.c +++ b/src/iccpd/src/iccp_ifm.c @@ -128,7 +128,7 @@ static void do_arp_learn_from_kernel(struct ndmsg *ndm, struct rtattr *tb[], int uint16_t vlan_id = 0; struct VLAN_ID vlan_key = { 0 }; - char buf[MAX_BUFSIZE]; + char buf[MAX_BUFSIZE] = { 0 }; size_t msg_len = 0; struct LocalInterface *lif_po = NULL, *arp_lif = NULL; @@ -144,7 +144,6 @@ static void do_arp_learn_from_kernel(struct ndmsg *ndm, struct rtattr *tb[], int return; /* create ARP msg*/ - memset(buf, 0, MAX_BUFSIZE); msg_len = sizeof(struct ARPMsg); arp_msg = (struct ARPMsg *)&buf; arp_msg->op_type = NEIGH_SYNC_LIF; @@ -388,7 +387,7 @@ static void do_ndisc_learn_from_kernel(struct ndmsg *ndm, struct rtattr *tb[], i uint16_t vlan_id = 0; struct VLAN_ID vlan_key = { 0 }; - char buf[MAX_BUFSIZE]; + char buf[MAX_BUFSIZE] = { 0 }; size_t msg_len = 0; char addr_null[16] = { 0 }; @@ -406,7 +405,6 @@ static void do_ndisc_learn_from_kernel(struct ndmsg *ndm, struct rtattr *tb[], i return; /* create NDISC msg */ - memset(buf, 0, MAX_BUFSIZE); msg_len = sizeof(struct NDISCMsg); ndisc_msg = (struct NDISCMsg *)&buf; ndisc_msg->op_type = NEIGH_SYNC_LIF; @@ -815,7 +813,7 @@ void do_arp_update_from_reply_packet(unsigned int ifindex, unsigned int addr, ui uint16_t vlan_id = 0; struct VLAN_ID vlan_key = { 0 }; - char buf[MAX_BUFSIZE]; + char buf[MAX_BUFSIZE] = { 0 }; size_t msg_len = 0; struct LocalInterface *lif_po = NULL, *arp_lif = NULL; @@ -830,7 +828,6 @@ void do_arp_update_from_reply_packet(unsigned int ifindex, unsigned int addr, ui return; /* create ARP msg*/ - memset(buf, 0, MAX_BUFSIZE); msg_len = sizeof(struct ARPMsg); arp_msg = (struct ARPMsg*)&buf; arp_msg->op_type = NEIGH_SYNC_LIF; @@ -1033,7 +1030,7 @@ void do_ndisc_update_from_reply_packet(unsigned int ifindex, char *ipv6_addr, ui struct LocalInterface *peer_link_if = NULL; int is_link_local = 0; - char buf[MAX_BUFSIZE]; + char buf[MAX_BUFSIZE] = { 0 }; size_t msg_len = 0; char addr_null[16] = { 0 }; uint16_t vlan_id = 0; @@ -1053,7 +1050,6 @@ void do_ndisc_update_from_reply_packet(unsigned int ifindex, char *ipv6_addr, ui sprintf(mac_str, "%02x:%02x:%02x:%02x:%02x:%02x", mac_addr[0], mac_addr[1], mac_addr[2], mac_addr[3], mac_addr[4], mac_addr[5]); /* create Ndisc msg */ - memset(buf, 0, MAX_BUFSIZE); msg_len = sizeof(struct NDISCMsg); ndisc_msg = (struct NDISCMsg *)&buf; ndisc_msg->op_type = NEIGH_SYNC_LIF; diff --git a/src/iccpd/src/iccp_main.c b/src/iccpd/src/iccp_main.c index fe3594583a51..5c852bade142 100644 --- a/src/iccpd/src/iccp_main.c +++ b/src/iccpd/src/iccp_main.c @@ -143,7 +143,7 @@ static int iccpd_signal_init(struct System* sys) int fds[2]; int err; sigset_t ss; - struct sigaction sa; + struct sigaction sa = { 0 }; struct epoll_event event; err = pipe(fds); @@ -171,7 +171,6 @@ static int iccpd_signal_init(struct System* sys) goto close_pipe; } - memset(&sa, 0, sizeof(sa)); sa.sa_handler = iccpd_signal_handler; sigemptyset(&sa.sa_mask); sa.sa_flags = SA_RESTART; diff --git a/src/iccpd/src/iccp_netlink.c b/src/iccpd/src/iccp_netlink.c index 1143f370ffc5..6464a209896a 100644 --- a/src/iccpd/src/iccp_netlink.c +++ b/src/iccpd/src/iccp_netlink.c @@ -461,7 +461,7 @@ void iccp_set_interface_ipadd_mac(struct LocalInterface *lif, char * mac_addr ) { struct IccpSyncdHDr * msg_hdr; mclag_sub_option_hdr_t * sub_msg; - char msg_buf[4096]; + char msg_buf[4096] = { 0 }; struct System *sys; int src_len = 0, dst_len = 0; @@ -470,8 +470,6 @@ void iccp_set_interface_ipadd_mac(struct LocalInterface *lif, char * mac_addr ) if (sys == NULL) return; - memset(msg_buf, 0, 4095); - msg_hdr = (struct IccpSyncdHDr *)msg_buf; msg_hdr->ver = 1; msg_hdr->type = MCLAG_MSG_TYPE_SET_MAC; @@ -572,9 +570,10 @@ static int iccp_netlink_set_portchannel_iff_flag( { int rv, ret_rv = 0; char* token; + char* saveptr; struct LocalInterface* member_if; char *tmp_member_buf = NULL; - + if (!lif_po) return MCLAG_ERROR; @@ -592,7 +591,7 @@ static int iccp_netlink_set_portchannel_iff_flag( lif_po->portchannel_member_buf); } /* Port-channel members are stored as comma separated strings */ - token = strtok(tmp_member_buf, ","); + token = strtok_r(tmp_member_buf, ",", &saveptr); while (token != NULL) { member_if = local_if_find_by_name(token); @@ -616,7 +615,7 @@ static int iccp_netlink_set_portchannel_iff_flag( "Can't find member %s:%s, if_up(%d), location %d", lif_po->name, token, is_iff_up, location); } - token = strtok(NULL, ","); + token = strtok_r(NULL, ",", &saveptr); } if (tmp_member_buf) free(tmp_member_buf); @@ -1942,14 +1941,12 @@ int iccp_receive_ndisc_packet_handler(struct System *sys) struct nd_msg *ndmsg = NULL; struct nd_opt_hdr *nd_opt = NULL; struct in6_addr target; - uint8_t mac_addr[ETHER_ADDR_LEN]; + uint8_t mac_addr[ETHER_ADDR_LEN] = { 0 }; int8_t *opt = NULL; int opt_len = 0, l = 0; int len; struct CSM* csm = NULL; - memset(mac_addr, 0, ETHER_ADDR_LEN); - /* Fill in message and iovec. */ msg.msg_name = (void *)(&from); msg.msg_namelen = sizeof(struct sockaddr_in6); @@ -2375,9 +2372,9 @@ void recover_vlan_if_mac_on_standby(struct LocalInterface* lif_vlan, int dir, ui struct CSM *csm = NULL; struct System* sys = NULL; uint8_t null_mac[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; - char macaddr[64]; - char remote_macaddr[64]; - uint8_t system_mac[ETHER_ADDR_LEN]; + char macaddr[64] = { 0 }; + char remote_macaddr[64] = { 0 }; + uint8_t system_mac[ETHER_ADDR_LEN] = { 0 }; int ret = 0; int vid = 0; @@ -2404,9 +2401,6 @@ void recover_vlan_if_mac_on_standby(struct LocalInterface* lif_vlan, int dir, ui sscanf (lif_vlan->name, "Vlan%d", &vid); - memset(macaddr, 0, 64); - memset(remote_macaddr, 0, 64); - memset(system_mac, 0, ETHER_ADDR_LEN); ICCPD_LOG_DEBUG(__FUNCTION__, " ifname %s, l3_proto %d, dir %d\n", lif_vlan->name, lif_vlan->is_l3_proto_enabled, dir); if (lif_vlan->is_l3_proto_enabled == true) diff --git a/src/iccpd/src/mclagdctl/mclagdctl.c b/src/iccpd/src/mclagdctl/mclagdctl.c index 2eccd944636a..eb6c8878df08 100644 --- a/src/iccpd/src/mclagdctl/mclagdctl.c +++ b/src/iccpd/src/mclagdctl/mclagdctl.c @@ -164,7 +164,7 @@ static struct command_type command_types[] = int mclagdctl_sock_connect() { - struct sockaddr_un addr; + struct sockaddr_un addr = { 0 }; int addrlen = 0; int ret = 0; @@ -181,7 +181,6 @@ int mclagdctl_sock_connect() return MCLAG_ERROR; } - memset(&addr, 0, sizeof(addr)); addr.sun_family = AF_UNIX; snprintf(addr.sun_path, sizeof(addr.sun_path) - 1, "%s", mclagdctl_sock_path); addrlen = sizeof(addr.sun_family) + strlen(mclagdctl_sock_path); From 055fbf5aaaf4b8269cd598931f2c3fc3a41987cd Mon Sep 17 00:00:00 2001 From: Samuel Angebault Date: Wed, 14 Sep 2022 04:39:49 +0200 Subject: [PATCH 099/151] [Arista] Update platform submodules (#12020) --- platform/barefoot/sonic-platform-modules-arista | 2 +- platform/broadcom/sonic-platform-modules-arista | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/platform/barefoot/sonic-platform-modules-arista b/platform/barefoot/sonic-platform-modules-arista index b65a69a9e1c2..e12a04b24c5f 160000 --- a/platform/barefoot/sonic-platform-modules-arista +++ b/platform/barefoot/sonic-platform-modules-arista @@ -1 +1 @@ -Subproject commit b65a69a9e1c2c876ba5210ce8b2a1cc9b5c8b18f +Subproject commit e12a04b24c5f752a9ca789d62bb7b94c563e1c4b diff --git a/platform/broadcom/sonic-platform-modules-arista b/platform/broadcom/sonic-platform-modules-arista index b65a69a9e1c2..e12a04b24c5f 160000 --- a/platform/broadcom/sonic-platform-modules-arista +++ b/platform/broadcom/sonic-platform-modules-arista @@ -1 +1 @@ -Subproject commit b65a69a9e1c2c876ba5210ce8b2a1cc9b5c8b18f +Subproject commit e12a04b24c5f752a9ca789d62bb7b94c563e1c4b From c674b3c63486082a0d426ae64e58f70480205ddc Mon Sep 17 00:00:00 2001 From: kannankvs Date: Wed, 14 Sep 2022 10:19:05 +0530 Subject: [PATCH 100/151] [doc]: Updated PR Template for a comment to add label/tag for the feature raised. (#12058) Signed-off-by: kannankvs --- .github/pull_request_template.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md index 1ff6883573d2..d553f7a4d0c4 100644 --- a/.github/pull_request_template.md +++ b/.github/pull_request_template.md @@ -39,6 +39,8 @@ Write a short (one line) summary that describes the changes in this pull request for inclusion in the changelog: --> +#### Ensure to add label/tag for the feature raised. example - [PR#2174](https://github.com/sonic-net/sonic-utilities/pull/2174) where, Generic Config and Update feature has been labelled as GCU. + #### Link to config_db schema for YANG module changes - [ ] 201811 - [ ] 201911 - [ ] 202006 - [ ] 202012 - [ ] 202106 - [ ] 202111 - [ ] 202205 #### Description for the changelog Improve SSHD config to use more secure settings #### Link to config_db schema for YANG module changes #### A picture of a cute animal (not mandatory but encouraged) --- build_debian.sh | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/build_debian.sh b/build_debian.sh index 8dcd8596f684..01a10d78d678 100755 --- a/build_debian.sh +++ b/build_debian.sh @@ -467,10 +467,16 @@ rm /files/etc/ssh/sshd_config/ClientAliveInterval rm /files/etc/ssh/sshd_config/ClientAliveCountMax touch /files/etc/ssh/sshd_config/EmptyLineHack rename /files/etc/ssh/sshd_config/EmptyLineHack "" -set /files/etc/ssh/sshd_config/ClientAliveInterval 900 +set /files/etc/ssh/sshd_config/ClientAliveInterval 300 set /files/etc/ssh/sshd_config/ClientAliveCountMax 1 ins #comment before /files/etc/ssh/sshd_config/ClientAliveInterval -set /files/etc/ssh/sshd_config/#comment[following-sibling::*[1][self::ClientAliveInterval]] "Close inactive client sessions after 15 minutes" +set /files/etc/ssh/sshd_config/#comment[following-sibling::*[1][self::ClientAliveInterval]] "Close inactive client sessions after 5 minutes" +rm /files/etc/ssh/sshd_config/MaxAuthTries +set /files/etc/ssh/sshd_config/MaxAuthTries 3 +rm /files/etc/ssh/sshd_config/LogLevel +set /files/etc/ssh/sshd_config/LogLevel VERBOSE +rm /files/etc/ssh/sshd_config/Banner +set /files/etc/ssh/sshd_config/Banner /etc/issue save quit EOF From 8af369a7c94d461338ee0aa63202b11252742e2c Mon Sep 17 00:00:00 2001 From: Xichen96 Date: Thu, 22 Sep 2022 13:57:52 +0800 Subject: [PATCH 118/151] Enable swap for haliburton device. (#11746) Signed-off-by: Xichen Lin Signed-off-by: Xichen Lin --- .../debian/platform-modules-haliburton.init | 22 +++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/platform/broadcom/sonic-platform-modules-cel/debian/platform-modules-haliburton.init b/platform/broadcom/sonic-platform-modules-cel/debian/platform-modules-haliburton.init index 07a6542109b5..3f6358bf4ab4 100644 --- a/platform/broadcom/sonic-platform-modules-cel/debian/platform-modules-haliburton.init +++ b/platform/broadcom/sonic-platform-modules-cel/debian/platform-modules-haliburton.init @@ -11,6 +11,26 @@ # Short-Description: Setup Haliburton board. ### END INIT INFO +setup_swap () { + SWAPFILE=/host/myswapfile + + if [ ! -f $SWAPFILE ]; then + availspace=`df -h --output=avail /host | sed '1d;s/\s//g;s/[^0-9].*//g'` + diff=$(( availspace - 2*$1 )) + if [ $diff -gt 0 ]; then + fallocate -l ${1}G $SWAPFILE + chmod 600 $SWAPFILE + echo "swap file created successfully" + else + echo "not enough disk space to turn on swap." + return + fi + fi + mkswap $SWAPFILE + swapon $SWAPFILE + echo "swap on successfully" +} + case "$1" in start) echo -n "Setting up board... " @@ -74,6 +94,8 @@ start) /bin/sh /usr/local/bin/platform_api_mgnt.sh init + setup_swap 2 + echo "done." ;; From 283efeeaccd386f99e3f9242f54d76bfd2901f44 Mon Sep 17 00:00:00 2001 From: Mai Bui Date: Thu, 22 Sep 2022 06:40:42 -0700 Subject: [PATCH 119/151] [sonic-py-common] Add getstatusoutput_noshell() functions to general module (#12065) Signed-off-by: maipbui #### Why I did it `getstatusoutput()` function from `subprocess` module has shell injection issue because it includes `shell=True` in the implementation Eliminate duplicate code #### How I did it Reimplement `getstatusoutput_noshell()` and `getstatusoutput_noshell_pipe()` functions with `shell=False` Add `check_output_pipe()` function #### How to verify it Pass UT --- .../sonic_py_common/general.py | 68 +++++++++++++++++++ src/sonic-py-common/tests/test_general.py | 31 +++++++++ 2 files changed, 99 insertions(+) create mode 100644 src/sonic-py-common/tests/test_general.py diff --git a/src/sonic-py-common/sonic_py_common/general.py b/src/sonic-py-common/sonic_py_common/general.py index 9e04f3e214ee..4fea165de9fb 100644 --- a/src/sonic-py-common/sonic_py_common/general.py +++ b/src/sonic-py-common/sonic_py_common/general.py @@ -1,4 +1,5 @@ import sys +from subprocess import Popen, STDOUT, PIPE, CalledProcessError, check_output def load_module_from_source(module_name, file_path): @@ -23,3 +24,70 @@ def load_module_from_source(module_name, file_path): sys.modules[module_name] = module return module + + +def getstatusoutput_noshell(cmd): + """ + This function implements getstatusoutput API from subprocess module + but using shell=False to prevent shell injection. + Ref: https://github.com/python/cpython/blob/3.10/Lib/subprocess.py#L602 + """ + try: + output = check_output(cmd, universal_newlines=True, stderr=STDOUT) + exitcode = 0 + except CalledProcessError as ex: + output = ex.output + exitcode = ex.returncode + if output[-1:] == '\n': + output = output[:-1] + return exitcode, output + + +def getstatusoutput_noshell_pipe(cmd0, *args): + """ + This function implements getstatusoutput API from subprocess module + but using shell=False to prevent shell injection. Input command + includes two or more commands connected by shell pipe(s). + """ + popens = [Popen(cmd0, stdout=PIPE, universal_newlines=True)] + i = 0 + while i < len(args): + popens.append(Popen(args[i], stdin=popens[i].stdout, stdout=PIPE, universal_newlines=True)) + popens[i].stdout.close() + i += 1 + output = popens[-1].communicate()[0] + if output[-1:] == '\n': + output = output[:-1] + + exitcodes = [0] * len(popens) + while popens: + last = popens.pop(-1) + exitcodes[len(popens)] = last.wait() + + return (exitcodes, output) + + +def check_output_pipe(cmd0, *args): + """ + This function implements check_output API from subprocess module. + Input command includes two or more commands connected by shell pipe(s) + """ + popens = [Popen(cmd0, stdout=PIPE, universal_newlines=True)] + i = 0 + while i < len(args): + popens.append(Popen(args[i], stdin=popens[i].stdout, stdout=PIPE, universal_newlines=True)) + popens[i].stdout.close() + i += 1 + output = popens[-1].communicate()[0] + + i = 0 + args_list = [cmd0] + list(args) + while popens: + current = popens.pop(0) + exitcode = current.wait() + if exitcode != 0: + raise CalledProcessError(returncode=exitcode, cmd=args_list[i], output=current.stdout) + i += 1 + + return output + diff --git a/src/sonic-py-common/tests/test_general.py b/src/sonic-py-common/tests/test_general.py new file mode 100644 index 000000000000..a395cf9aeb6b --- /dev/null +++ b/src/sonic-py-common/tests/test_general.py @@ -0,0 +1,31 @@ +import sys +import pytest +import subprocess +from sonic_py_common.general import getstatusoutput_noshell, getstatusoutput_noshell_pipe, check_output_pipe + + +def test_getstatusoutput_noshell(tmp_path): + exitcode, output = getstatusoutput_noshell(['echo', 'sonic']) + assert (exitcode, output) == (0, 'sonic') + + exitcode, output = getstatusoutput_noshell([sys.executable, "-c", "import sys; sys.exit(6)"]) + assert exitcode != 0 + +def test_getstatusoutput_noshell_pipe(): + exitcode, output = getstatusoutput_noshell_pipe(['echo', 'sonic'], ['awk', '{print $1}']) + assert (exitcode, output) == ([0, 0], 'sonic') + + exitcode, output = getstatusoutput_noshell_pipe([sys.executable, "-c", "import sys; sys.exit(6)"], [sys.executable, "-c", "import sys; sys.exit(8)"]) + assert exitcode == [6, 8] + +def test_check_output_pipe(): + output = check_output_pipe(['echo', 'sonic'], ['awk', '{print $1}']) + assert output == 'sonic\n' + + with pytest.raises(subprocess.CalledProcessError) as e: + check_output_pipe([sys.executable, "-c", "import sys; sys.exit(6)"], [sys.executable, "-c", "import sys; sys.exit(0)"]) + assert e.returncode == [6, 0] + + with pytest.raises(subprocess.CalledProcessError) as e: + check_output_pipe([sys.executable, "-c", "import sys; sys.exit(0)"], [sys.executable, "-c", "import sys; sys.exit(6)"]) + assert e.returncode == [0, 6] From 57ff7a230827102f2d04cfdae8c3fcf242b09b50 Mon Sep 17 00:00:00 2001 From: "Marty Y. Lok" <76118573+mlok-nokia@users.noreply.github.com> Date: Thu, 22 Sep 2022 19:39:31 -0400 Subject: [PATCH 120/151] [chassis][supervisor] show system-health summary fails on the supervisor card (#10631) Fix the command "sudo show system-health summary" shows the following error on the supervisor card. Fixes #10630 --- src/system-health/health_checker/service_checker.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/system-health/health_checker/service_checker.py b/src/system-health/health_checker/service_checker.py index 33eeb4dfb707..674ad9944280 100644 --- a/src/system-health/health_checker/service_checker.py +++ b/src/system-health/health_checker/service_checker.py @@ -127,11 +127,11 @@ def get_critical_process_list_from_file(self, container, critical_processes_file self.bad_containers.add(container) logger.log_error('Invalid syntax in critical_processes file of {}'.format(container)) continue - - identifier_key = match.group(2).strip() - identifier_value = match.group(3).strip() - if identifier_key == "program" and identifier_value: - critical_process_list.append(identifier_value) + if match.group(1) is not None: + identifier_key = match.group(2).strip() + identifier_value = match.group(3).strip() + if identifier_key == "program" and identifier_value: + critical_process_list.append(identifier_value) return critical_process_list From 27032bfb84de0db2733dd024e54f0f0f83a0c769 Mon Sep 17 00:00:00 2001 From: Samuel Angebault Date: Fri, 23 Sep 2022 02:52:40 +0200 Subject: [PATCH 121/151] Add BUILD_DATE to SWI (#11915) Add the BUILD_DATE to the SWI version info, as this is a requirement of Secure Boot. --- build_image.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/build_image.sh b/build_image.sh index ddf134e845ce..9c70713866a4 100755 --- a/build_image.sh +++ b/build_image.sh @@ -191,6 +191,7 @@ elif [ "$IMAGE_TYPE" = "aboot" ]; then zip -g $ABOOT_BOOT_IMAGE .imagehash rm .imagehash echo "SWI_VERSION=42.0.0" > version + echo "BUILD_DATE=$(date -d "${build_date}" -u +%Y%m%dT%H%M%SZ)" >> version echo "SWI_MAX_HWEPOCH=2" >> version echo "SWI_VARIANT=US" >> version zip -g $OUTPUT_ABOOT_IMAGE version From c968114a36dacd46b3dfea0e61b52a72daac4737 Mon Sep 17 00:00:00 2001 From: Liu Shilong Date: Fri, 23 Sep 2022 12:54:57 +0800 Subject: [PATCH 122/151] [ci] Use absolute template file path in docker-sonic-slave pipeline. (#12153) --- .azure-pipelines/docker-sonic-slave-template.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.azure-pipelines/docker-sonic-slave-template.yml b/.azure-pipelines/docker-sonic-slave-template.yml index 1a7b983b5c1f..142ff5fa3f6f 100644 --- a/.azure-pipelines/docker-sonic-slave-template.yml +++ b/.azure-pipelines/docker-sonic-slave-template.yml @@ -38,12 +38,12 @@ jobs: - job: Build_${{ parameters.dist }}_${{ parameters.march }}${{ parameters.arch }} timeoutInMinutes: 360 variables: - - template: .azure-pipelines/template-variables.yml@buildimage - - template: .azure-pipelines/azure-pipelines-repd-build-variables.yml@buildimage + - template: /.azure-pipelines/template-variables.yml@buildimage + - template: /.azure-pipelines/azure-pipelines-repd-build-variables.yml@buildimage pool: ${{ parameters.pool }} steps: - template: cleanup.yml - - template: .azure-pipelines/template-clean-sonic-slave.yml@buildimage + - template: /.azure-pipelines/template-clean-sonic-slave.yml@buildimage - checkout: self clean: true submodules: recursive @@ -62,7 +62,7 @@ jobs: exit 0 fi - DOCKER_DATA_ROOT_FOR_MULTIARCH=/data/march/docker make configure PLATFORM=generic PLATFORM_ARCH=${{ parameters.arch }} $args || docker image ls $image_tag + DOCKER_DATA_ROOT_FOR_MULTIARCH=/data/march/docker BLDENV=${{ parameters.dist }} make -f Makefile.work configure PLATFORM=generic PLATFORM_ARCH=${{ parameters.arch }} $args || docker image ls $image_tag if [[ "$(Build.Reason)" == "PullRequest" ]];then exit 0 fi From cc0781b40b7e442677eb4ad21d72a29f16a666b3 Mon Sep 17 00:00:00 2001 From: Hua Liu <58683130+liuh-80@users.noreply.github.com> Date: Sun, 25 Sep 2022 03:37:35 +0800 Subject: [PATCH 123/151] Build swss-common with libyang (#12087) Build swss-common with libyang #### Why I did it sonic-swss-common lib add dependency to libyang recently, so need update make file before update sonic-swss-common submodule. #### How I did it Add dependency to libyang in rules/swss-common.mk #### How to verify it Pass all E2E test case. #### Which release branch to backport (provide reason below if selected) - [ ] 201811 - [ ] 201911 - [ ] 202006 - [ ] 202012 - [ ] 202106 - [ ] 202111 - [ ] 202205 #### Description for the changelog Add new Redis database PROFILE_DB #### Link to config_db schema for YANG module changes #### A picture of a cute animal (not mandatory but encouraged) --- rules/swss-common.mk | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/rules/swss-common.mk b/rules/swss-common.mk index 9ab49b672b6c..d2c4390ef4ff 100644 --- a/rules/swss-common.mk +++ b/rules/swss-common.mk @@ -9,9 +9,9 @@ $(LIBSWSSCOMMON)_VERSION = $(LIBSWSSCOMMON_VERSION) $(LIBSWSSCOMMON)_NAME = $(LIBSWSSCOMMON_NAME) $(LIBSWSSCOMMON)_DEPENDS += $(LIBHIREDIS_DEV) $(LIBNL3_DEV) $(LIBNL_GENL3_DEV) \ $(LIBNL_ROUTE3_DEV) $(LIBNL_NF3_DEV) \ - $(LIBNL_CLI_DEV) + $(LIBNL_CLI_DEV) $(LIBYANG_DEV) $(LIBYANG) $(LIBSWSSCOMMON)_RDEPENDS += $(LIBHIREDIS) $(LIBNL3) $(LIBNL_GENL3) \ - $(LIBNL_ROUTE3) $(LIBNL_NF3) $(LIBNL_CLI) + $(LIBNL_ROUTE3) $(LIBNL_NF3) $(LIBNL_CLI) $(LIBYANG) SONIC_DPKG_DEBS += $(LIBSWSSCOMMON) LIBSWSSCOMMON_DEV = $(LIBSWSSCOMMON_NAME)-dev_$(LIBSWSSCOMMON_VERSION)_$(CONFIGURED_ARCH).deb From f50dc28789cd2fdec99131284cc4ccc5192b3806 Mon Sep 17 00:00:00 2001 From: Xin Wang Date: Mon, 26 Sep 2022 10:48:02 +0800 Subject: [PATCH 124/151] [docker-sonic-mgmt] Deprecate azure-kusto-data & azure-kusto-ingest for py2 (#12143) Why I did it The python packages azure-kusto-data and azure-kusto-ingest packages for python2 are too old and not really used. The python3 environment has newer version of these packages installed. This change is to deprecate these two packages for python2 in docker-sonic-mgmt image. How I did it Removed the lines for installing old version of packages azure-kusto-data and azure-kusto-ingest in python2 in the Dockerfile template. Signed-off-by: Xin Wang --- dockers/docker-sonic-mgmt/Dockerfile.j2 | 4 ---- 1 file changed, 4 deletions(-) diff --git a/dockers/docker-sonic-mgmt/Dockerfile.j2 b/dockers/docker-sonic-mgmt/Dockerfile.j2 index 42aaa3525a64..fec662dff0ed 100755 --- a/dockers/docker-sonic-mgmt/Dockerfile.j2 +++ b/dockers/docker-sonic-mgmt/Dockerfile.j2 @@ -114,10 +114,6 @@ RUN apt-get update \ # Install Azure CLI RUN curl -sL https://aka.ms/InstallAzureCLIDeb | bash -# Install Microsoft Azure Kusto Library for Python -RUN pip install azure-kusto-data==0.0.13 \ - azure-kusto-ingest==0.0.13 - RUN pip install wheel==0.33.6 ## Copy and install sonic-mgmt docker dependencies From 2c10ebb4fe978bded6499365d3471e8343573d8c Mon Sep 17 00:00:00 2001 From: Aryeh Feigin <101218333+arfeigin@users.noreply.github.com> Date: Mon, 26 Sep 2022 19:01:49 +0300 Subject: [PATCH 125/151] Use warm-boot infrastructure for fast-boot (#11594) This PR should be merged together with the sonic-utilities PR (sonic-net/sonic-utilities#2286) and sonic-sairedis PR (sonic-net/sonic-sairedis#1100). Use redis contents from dump file in fast-reboot. Improve fast-reboot flow by utilizing the warm-reboot infrastructure. This followes https://github.com/sonic-net/SONiC/blob/master/doc/fast-reboot/Fast-reboot_Flow_Improvements_HLD.md --- files/build_templates/docker_image_ctl.j2 | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/files/build_templates/docker_image_ctl.j2 b/files/build_templates/docker_image_ctl.j2 index b4ff4a4379c9..ace39df4e546 100644 --- a/files/build_templates/docker_image_ctl.j2 +++ b/files/build_templates/docker_image_ctl.j2 @@ -87,7 +87,7 @@ function preStartAction() {%- if docker_container_name == "database" %} WARM_DIR=/host/warmboot if [ "$DATABASE_TYPE" != "chassisdb" ]; then - if [[ ("$BOOT_TYPE" == "warm" || "$BOOT_TYPE" == "fastfast") && -f $WARM_DIR/dump.rdb ]]; then + if [[ ("$BOOT_TYPE" == "warm" || "$BOOT_TYPE" == "fastfast" || "$BOOT_TYPE" == "fast") && -f $WARM_DIR/dump.rdb ]]; then # Load redis content from /host/warmboot/dump.rdb docker cp $WARM_DIR/dump.rdb database$DEV:/var/lib/redis/dump.rdb else @@ -218,7 +218,7 @@ function postStartAction() ($(docker exec -i database$DEV sonic-db-cli PING | grep -c PONG) -gt 0) ]]; do sleep 1; done - if [[ ("$BOOT_TYPE" == "warm" || "$BOOT_TYPE" == "fastfast") && -f $WARM_DIR/dump.rdb ]]; then + if [[ ("$BOOT_TYPE" == "warm" || "$BOOT_TYPE" == "fastfast" || "$BOOT_TYPE" == "fast") && -f $WARM_DIR/dump.rdb ]]; then # retain the dump file from last boot for debugging purposes mv $WARM_DIR/dump.rdb $WARM_DIR/dump.rdb.old else From 1b50a2b72111593af51906f9bcaea89f1f763126 Mon Sep 17 00:00:00 2001 From: Tal Berlowitz <100570204+talber-nvidia@users.noreply.github.com> Date: Mon, 26 Sep 2022 19:30:38 +0300 Subject: [PATCH 126/151] Patch ifupdown2 (#9630) (#11548) --- ...alue-of-utils._execute_subprocess-me.patch | 21 +++++++++++++++++++ src/ifupdown2/patch/series | 1 + 2 files changed, 22 insertions(+) create mode 100644 src/ifupdown2/patch/0003-Fix-the-return-value-of-utils._execute_subprocess-me.patch diff --git a/src/ifupdown2/patch/0003-Fix-the-return-value-of-utils._execute_subprocess-me.patch b/src/ifupdown2/patch/0003-Fix-the-return-value-of-utils._execute_subprocess-me.patch new file mode 100644 index 000000000000..39cd481099ca --- /dev/null +++ b/src/ifupdown2/patch/0003-Fix-the-return-value-of-utils._execute_subprocess-me.patch @@ -0,0 +1,21 @@ +Fix the return value of utils._execute_subprocess method for empty strings +--- + ifupdown2/ifupdown/utils.py | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/ifupdown2/ifupdown/utils.py b/ifupdown2/ifupdown/utils.py +index d638fe9..0c5d8ce 100644 +--- a/ifupdown2/ifupdown/utils.py ++++ b/ifupdown2/ifupdown/utils.py +@@ -380,7 +380,7 @@ class utils(): + finally: + utils.disable_subprocess_signal_forwarding(signal.SIGINT) + +- cmd_output_string = cmd_output.decode() if cmd_output else cmd_output ++ cmd_output_string = cmd_output.decode() if cmd_output is not None else cmd_output + + if cmd_returncode != 0: + raise Exception(cls._format_error(cmd, +-- +2.14.1 + diff --git a/src/ifupdown2/patch/series b/src/ifupdown2/patch/series index c4e412bbe83f..7d0fa15ded61 100644 --- a/src/ifupdown2/patch/series +++ b/src/ifupdown2/patch/series @@ -1,2 +1,3 @@ 0001-fix-broadcast-addr-encoding.patch 0002-disable-checks-when-using-no-wait.patch +0003-Fix-the-return-value-of-utils._execute_subprocess-me.patch From 60c80ad26d17312b868a66ea32ccce3a1de2c8dc Mon Sep 17 00:00:00 2001 From: xumia <59720581+xumia@users.noreply.github.com> Date: Tue, 27 Sep 2022 06:55:19 +0800 Subject: [PATCH 127/151] [Build] Fix the build unstalbe issue caused by the kvm not ready (#12180) Why I did it Fix the build unstable issue caused by the kvm 9000 port is not ready to use in 2 seconds. 2022-09-02T10:57:30.8122304Z + /usr/bin/kvm -m 8192 -name onie -boot order=cd,once=d -cdrom target/files/bullseye/onie-recovery-x86_64-kvm_x86_64_4_asic-r0.iso -device e1000,netdev=onienet -netdev user,id=onienet,hostfwd=:0.0.0.0:3041-:22 -vnc 0.0.0.0:0 -vga std -drive file=target/sonic-6asic-vs.img,media=disk,if=virtio,index=0 -drive file=./sonic-installer.img,if=virtio,index=1 -serial telnet:127.0.0.1:9000,server 2022-09-02T10:57:30.8123378Z + sleep 2.0 2022-09-02T10:57:30.8123889Z + '[' -d /proc/284923 ']' 2022-09-02T10:57:30.8124528Z + echo 'to kill kvm: sudo kill 284923' 2022-09-02T10:57:30.8124994Z to kill kvm: sudo kill 284923 2022-09-02T10:57:30.8125362Z + ./install_sonic.py 2022-09-02T10:57:30.8125720Z Trying 127.0.0.1... 2022-09-02T10:57:30.8126041Z telnet: Unable to connect to remote host: Connection refused How I did it Waiting more time until the tcp port 9000 is ready, waiting for 60 seconds in maximum. --- scripts/build_kvm_image.sh | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/scripts/build_kvm_image.sh b/scripts/build_kvm_image.sh index 44009ed013f4..f3936a548299 100755 --- a/scripts/build_kvm_image.sh +++ b/scripts/build_kvm_image.sh @@ -49,6 +49,19 @@ prepare_installer_disk() umount $tmpdir } +wait_kvm_ready() +{ + local count=30 + local waiting_in_seconds=2.0 + for ((i=1; i<=$count; i++)); do + sleep $waiting_in_seconds + echo "$(date) [$i/$count] waiting for the port $KVM_PORT ready" + if netstat -l | grep -q ":$KVM_PORT"; then + break + fi + done +} + apt-get install -y net-tools create_disk prepare_installer_disk @@ -86,7 +99,7 @@ echo "Installing SONiC" kvm_pid=$! -sleep 2.0 +wait_kvm_ready [ -d "/proc/$kvm_pid" ] || { echo "ERROR: kvm died." @@ -114,7 +127,7 @@ echo "Booting up SONiC" kvm_pid=$! -sleep 2.0 +wait_kvm_ready [ -d "/proc/$kvm_pid" ] || { echo "ERROR: kvm died." From 1995540758cccbf4f3ff4c081a745db835993222 Mon Sep 17 00:00:00 2001 From: ShiyanWangMS Date: Tue, 27 Sep 2022 09:15:48 +0800 Subject: [PATCH 128/151] Upgrade docker-sonic-mgmt base image from Ubuntu18.04 to 20.04 (#12056) Upgrade docker-sonic-mgmt base image from Ubuntu18.04 to 20.04 --- dockers/docker-sonic-mgmt/Dockerfile.j2 | 27 ++++++++++++++++--------- 1 file changed, 17 insertions(+), 10 deletions(-) diff --git a/dockers/docker-sonic-mgmt/Dockerfile.j2 b/dockers/docker-sonic-mgmt/Dockerfile.j2 index fec662dff0ed..e803508e855f 100755 --- a/dockers/docker-sonic-mgmt/Dockerfile.j2 +++ b/dockers/docker-sonic-mgmt/Dockerfile.j2 @@ -1,5 +1,5 @@ {% set prefix = DEFAULT_CONTAINER_REGISTRY %} -FROM {{ prefix }}ubuntu:18.04 +FROM {{ prefix }}ubuntu:20.04 ENV DEBIAN_FRONTEND=noninteractive @@ -21,8 +21,6 @@ RUN apt-get update && apt-get install -y build-essential \ psmisc \ python \ python-dev \ - python-scapy \ - python-pip \ python3-pip \ python3-venv \ rsyslog \ @@ -31,10 +29,20 @@ RUN apt-get update && apt-get install -y build-essential \ sudo \ tcpdump \ telnet \ - vim + vim \ + python-is-python2 \ + software-properties-common + +RUN add-apt-repository -y universe +RUN curl https://bootstrap.pypa.io/pip/2.7/get-pip.py --output get-pip.py \ + && python2 get-pip.py + +RUN curl -L http://archive.ubuntu.com/ubuntu/pool/universe/s/scapy/python-scapy_2.3.3-3_all.deb \ + --output python-scapy_2.3.3-3_all.deb \ + && dpkg -i python-scapy_2.3.3-3_all.deb RUN pip install setuptools==44.1.1 -RUN pip install cffi==1.10.0 \ +RUN pip install cffi==1.12.0 \ contextlib2==0.6.0.post1 \ cryptography==3.3.2 \ "future>=0.16.0" \ @@ -96,7 +104,7 @@ RUN pip install cffi==1.10.0 \ && rm -f 1.0.0.tar.gz \ && pip install nnpy \ && pip install dpkt \ - && pip install scapy==2.4.5 --upgrade + && pip install scapy==2.4.5 --upgrade --ignore-installed # Install docker-ce-cli RUN apt-get update \ @@ -189,8 +197,7 @@ ENV PATH="$VIRTUAL_ENV/bin:$PATH" ENV LANG=C.UTF-8 LC_ALL=C.UTF-8 PYTHONIOENCODING=UTF-8 -RUN python3 -m pip install --upgrade --ignore-installed pip setuptools==58.4.0 - +RUN python3 -m pip install --upgrade --ignore-installed pip setuptools==58.4.0 wheel==0.33.6 RUN python3 -m pip install setuptools-rust \ aiohttp \ defusedxml \ @@ -206,6 +213,7 @@ RUN python3 -m pip install setuptools-rust \ ixnetwork-restpy==1.0.64 \ ixnetwork-open-traffic-generator==0.0.79 \ snappi[ixnetwork,convergence]==0.7.44 \ + markupsafe==2.0.1 \ jinja2==2.7.2 \ jsonpatch \ lxml \ @@ -233,7 +241,6 @@ RUN python3 -m pip install setuptools-rust \ tabulate \ textfsm==1.1.2 \ virtualenv \ - wheel==0.33.6 \ pysubnettree \ nnpy \ dpkt \ @@ -248,5 +255,5 @@ RUN python3 -m pip install setuptools-rust \ celery[redis]==4.4.7 \ msrest==0.6.21 -# Deactivating a virtualenv. +# Deactivating a virtualenv ENV PATH="$BACKUP_OF_PATH" From 9c602320c3df3c8e84d5819c207b939b7ea84ff3 Mon Sep 17 00:00:00 2001 From: Ye Jianquan Date: Wed, 28 Sep 2022 11:38:41 +0800 Subject: [PATCH 129/151] install missed package python-dateutil (#12197) Why I did it Fix issue of can't import dateutil.parser in show_techsupport/test_auto_techsupport.py How I did it install python-dateutil --- dockers/docker-sonic-mgmt/Dockerfile.j2 | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/dockers/docker-sonic-mgmt/Dockerfile.j2 b/dockers/docker-sonic-mgmt/Dockerfile.j2 index e803508e855f..7676341cbaed 100755 --- a/dockers/docker-sonic-mgmt/Dockerfile.j2 +++ b/dockers/docker-sonic-mgmt/Dockerfile.j2 @@ -86,6 +86,7 @@ RUN pip install cffi==1.12.0 \ allure-pytest==2.8.22 \ celery[redis]==4.4.7 \ msrest==0.6.21 \ + python-dateutil \ && git clone https://github.com/p4lang/scapy-vxlan.git \ && cd scapy-vxlan \ && python setup.py install \ @@ -253,7 +254,8 @@ RUN python3 -m pip install setuptools-rust \ ptf \ scapy==2.4.5 \ celery[redis]==4.4.7 \ - msrest==0.6.21 + msrest==0.6.21 \ + python-dateutil \ # Deactivating a virtualenv ENV PATH="$BACKUP_OF_PATH" From 7666af94030f44e48da1b4e8a8f265c32d0f2220 Mon Sep 17 00:00:00 2001 From: Ye Jianquan Date: Wed, 28 Sep 2022 14:39:33 +0800 Subject: [PATCH 130/151] Fix pip install error (#12198) Fix the error of pip install introduced in PR #12197 --- dockers/docker-sonic-mgmt/Dockerfile.j2 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dockers/docker-sonic-mgmt/Dockerfile.j2 b/dockers/docker-sonic-mgmt/Dockerfile.j2 index 7676341cbaed..c6b4d1600a8e 100755 --- a/dockers/docker-sonic-mgmt/Dockerfile.j2 +++ b/dockers/docker-sonic-mgmt/Dockerfile.j2 @@ -255,7 +255,7 @@ RUN python3 -m pip install setuptools-rust \ scapy==2.4.5 \ celery[redis]==4.4.7 \ msrest==0.6.21 \ - python-dateutil \ + python-dateutil # Deactivating a virtualenv ENV PATH="$BACKUP_OF_PATH" From f890606d8252c0e181bf16ea0c83846d9a37bbbf Mon Sep 17 00:00:00 2001 From: Junchao-Mellanox <57339448+Junchao-Mellanox@users.noreply.github.com> Date: Wed, 28 Sep 2022 15:15:26 +0800 Subject: [PATCH 131/151] Revert "[Mellanox] Redirect ethtool stderr to subprocess for better error log (#12038)" (#12183) This reverts commit 9750cb4. There is a PR to handle 202205 branch revert: #12184 - Why I did it The PR to be reverted introduced many notice logs every 1 minute if SFP is not plugged: Cannot get module EEPROM information: Input/output error Before the "bad" PR, the message format is like this: INFO pmon#supervisord: xcvrd Cannot get module EEPROM information: Input/output error It was truncated by rsyslog because every message is the same. However, the "bad" PR introduces SFP index to the message: NOTICE pmon#xcvrd: Failed to get EEPROM data for sfp 39: Cannot get module EEPROM information: Input/output error Rsyslog no longer truncate such log and many such messages are flooded to syslog. - How I did it Revert the PR - How to verify it Manual test --- platform/mellanox/mlnx-platform-api/sonic_platform/sfp.py | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/platform/mellanox/mlnx-platform-api/sonic_platform/sfp.py b/platform/mellanox/mlnx-platform-api/sonic_platform/sfp.py index d373b6a8f705..617b4f33d636 100644 --- a/platform/mellanox/mlnx-platform-api/sonic_platform/sfp.py +++ b/platform/mellanox/mlnx-platform-api/sonic_platform/sfp.py @@ -359,8 +359,7 @@ def _read_eeprom_specific_bytes(self, offset, num_bytes): try: output = subprocess.check_output(ethtool_cmd, shell=True, - universal_newlines=True, - stderr=subprocess.PIPE) + universal_newlines=True) output_lines = output.splitlines() first_line_raw = output_lines[0] if "Offset" in first_line_raw: @@ -368,7 +367,6 @@ def _read_eeprom_specific_bytes(self, offset, num_bytes): line_split = line.split() eeprom_raw = eeprom_raw + line_split[1:] except subprocess.CalledProcessError as e: - logger.log_notice("Failed to get EEPROM data for sfp {}: {}".format(self.index, e.stderr)) return None eeprom_raw = list(map(lambda h: int(h, base=16), eeprom_raw)) From 4d317aff9491a56c094f96966bb0e3ff9d009611 Mon Sep 17 00:00:00 2001 From: Stephen Sun <5379172+stephenxs@users.noreply.github.com> Date: Wed, 28 Sep 2022 16:09:18 +0800 Subject: [PATCH 132/151] [Mellanox] Fix typo in platform API (#12136) - Why I did it Fix a typo in chassis platform API which causes the following error >>> import sonic_platform as P >>> c = P.platform.Platform().get_chassis() >>> sl = c.get_all_sfps() >>> sl[0].get_lpmode() Sep 28 07:48:33 INFO LOG: Initializing SX log with STDOUT as output file. False >>> del c Exception ignored in: Traceback (most recent call last): File "/usr/local/lib/python3.9/dist-packages/sonic_platform/chassis.py", line 126, in __del__ self.sfp_module.deinitialize_sdk_handle(sfp_module.SFP.shared_sdk_handle) NameError: name 'sfp_module' is not defined - How I did it Use self while using the SDK handle - How to verify it Manual test Signed-off-by: Stephen Sun --- platform/mellanox/mlnx-platform-api/sonic_platform/chassis.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/platform/mellanox/mlnx-platform-api/sonic_platform/chassis.py b/platform/mellanox/mlnx-platform-api/sonic_platform/chassis.py index b9fa2593174c..96a7b9e2315a 100644 --- a/platform/mellanox/mlnx-platform-api/sonic_platform/chassis.py +++ b/platform/mellanox/mlnx-platform-api/sonic_platform/chassis.py @@ -123,7 +123,7 @@ def __del__(self): if self._sfp_list: if self.sfp_module.SFP.shared_sdk_handle: - self.sfp_module.deinitialize_sdk_handle(sfp_module.SFP.shared_sdk_handle) + self.sfp_module.deinitialize_sdk_handle(self.sfp_module.SFP.shared_sdk_handle) @property def RJ45_port_list(self): From 8c7e0f8e02233dc4236f8f7f048b4281ab9d31b8 Mon Sep 17 00:00:00 2001 From: vijayvyasm <112528485+vijayvyasm@users.noreply.github.com> Date: Wed, 28 Sep 2022 18:37:33 -0700 Subject: [PATCH 133/151] Support for serdes platform library debian installation for Innovium SONiC image (#11920) Signed-off-by: vijayvyasm vijayvyasm@marvell.com Signed-off-by: vijayvyasm vijayvyasm@marvell.com --- platform/innovium/invm-sai.mk | 4 +++- platform/innovium/one-image.mk | 2 +- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/platform/innovium/invm-sai.mk b/platform/innovium/invm-sai.mk index 25e490e44f83..734184e35b0c 100755 --- a/platform/innovium/invm-sai.mk +++ b/platform/innovium/invm-sai.mk @@ -5,11 +5,13 @@ INVM_SAI_ONLINE = https://github.com/Innovium/SONiC/raw/master/debian/master INVM_LIBSAI = isai.deb INVM_HSAI = saihdr.deb INVM_DRV = ipd.deb +INVM_SERDES_PLATFORM_LIBRARY = ivm_serdes_pltfm.deb $(INVM_LIBSAI)_URL = $(INVM_SAI_ONLINE)/$(INVM_LIBSAI) $(INVM_HSAI)_URL = $(INVM_SAI_ONLINE)/$(INVM_HSAI) $(INVM_DRV)_URL = $(INVM_SAI_ONLINE)/$(INVM_DRV) +$(INVM_SERDES_PLATFORM_LIBRARY)_URL = $(INVM_SAI_ONLINE)/$(INVM_SERDES_PLATFORM_LIBRARY) $(eval $(call add_conflict_package,$(INVM_HSAI),$(LIBSAIVS_DEV))) -SONIC_ONLINE_DEBS += $(INVM_LIBSAI) $(INVM_HSAI) $(INVM_DRV) +SONIC_ONLINE_DEBS += $(INVM_LIBSAI) $(INVM_HSAI) $(INVM_DRV) $(INVM_SERDES_PLATFORM_LIBRARY) diff --git a/platform/innovium/one-image.mk b/platform/innovium/one-image.mk index 2cae779d71ac..39e2e9fc8246 100755 --- a/platform/innovium/one-image.mk +++ b/platform/innovium/one-image.mk @@ -8,6 +8,6 @@ $(SONIC_ONE_IMAGE)_LAZY_INSTALLS += $(CEL_MIDSTONE_200I_PLATFORM_MODULE) $(SONIC_ONE_IMAGE)_LAZY_INSTALLS += $(DELTA_PLATFORM_MODULE) $(SONIC_ONE_IMAGE)_LAZY_INSTALLS += $(NETBERG_AURORA_715_PLATFORM_MODULE) $(SONIC_ONE_IMAGE)_LAZY_INSTALLS += $(WISTRON_PLATFORM_MODULE) -$(SONIC_ONE_IMAGE)_INSTALLS += $(INVM_DRV) +$(SONIC_ONE_IMAGE)_INSTALLS += $(INVM_DRV) $(INVM_SERDES_PLATFORM_LIBRARY) $(SONIC_ONE_IMAGE)_DOCKERS += $(SONIC_INSTALL_DOCKER_IMAGES) SONIC_INSTALLERS += $(SONIC_ONE_IMAGE) From 1f9c89a8d34ab94cd871d0dd798d991d5e4cf00e Mon Sep 17 00:00:00 2001 From: Hua Liu <58683130+liuh-80@users.noreply.github.com> Date: Thu, 29 Sep 2022 10:27:57 +0800 Subject: [PATCH 134/151] [sonic-py-common] porting sonic_db_dump_load.py from sonic-py-swsssdk to sonic-py-common (#12185) Porting sonic_db_dump_load.py from sonic-py-swsssdk to sonic-py-common. #### Why I did it sonic-py-swsssdk will be deprecate, so porting sonic_db_dump_load.py to sonic-py-common. #### How I did it Copy sonic_db_dump_load.py to sonic-py-common, and fix minor API different. #### How to verify it Pass all E2E test. The platform_tests/test_advanced_reboot.py::test_warm_reboot will cover this script. #### Which release branch to backport (provide reason below if selected) - [ ] 201811 - [ ] 201911 - [ ] 202006 - [ ] 202012 - [ ] 202106 - [ ] 202111 - [ ] 202205 #### Description for the changelog Porting sonic_db_dump_load.py from sonic-py-swsssdk to sonic-py-common. #### Ensure to add label/tag for the feature raised. example - [PR#2174](https://github.com/sonic-net/sonic-utilities/pull/2174) where, Generic Config and Update feature has been labelled as GCU. #### Link to config_db schema for YANG module changes #### A picture of a cute animal (not mandatory but encouraged) --- src/sonic-py-common/setup.py | 6 + .../sonic_py_common/sonic_db_dump_load.py | 139 ++++++++++++++++++ 2 files changed, 145 insertions(+) create mode 100755 src/sonic-py-common/sonic_py_common/sonic_db_dump_load.py diff --git a/src/sonic-py-common/setup.py b/src/sonic-py-common/setup.py index f12c0d83cb77..144cf61f52c4 100644 --- a/src/sonic-py-common/setup.py +++ b/src/sonic-py-common/setup.py @@ -27,6 +27,12 @@ 'pytest', 'mock==3.0.5' # For python 2. Version >=4.0.0 drops support for py2 ], + entry_points={ + 'console_scripts': [ + 'sonic-db-load = sonic_py_common.sonic_db_dump_load:sonic_db_dump_load', + 'sonic-db-dump = sonic_py_common.sonic_db_dump_load:sonic_db_dump_load', + ], + }, classifiers=[ 'Intended Audience :: Developers', 'Operating System :: Linux', diff --git a/src/sonic-py-common/sonic_py_common/sonic_db_dump_load.py b/src/sonic-py-common/sonic_py_common/sonic_db_dump_load.py new file mode 100755 index 000000000000..126dd2bc112e --- /dev/null +++ b/src/sonic-py-common/sonic_py_common/sonic_db_dump_load.py @@ -0,0 +1,139 @@ +## ref: https://github.com/p/redis-dump-load/blob/7bbdb1eaea0a51ed4758d3ce6ca01d497a4e7429/redisdl.py + +def sonic_db_dump_load(): + import optparse + import os.path + import re + import sys + from redisdl import dump, load + from swsscommon.swsscommon import SonicDBConfig + + DUMP = 1 + LOAD = 2 + + def options_to_kwargs(options): + args = {} + if options.password: + args['password'] = options.password + if options.encoding: + args['encoding'] = options.encoding + # dump only + if hasattr(options, 'pretty') and options.pretty: + args['pretty'] = True + if hasattr(options, 'keys') and options.keys: + args['keys'] = options.keys + # load only + if hasattr(options, 'use_expireat') and options.use_expireat: + args['use_expireat'] = True + if hasattr(options, 'empty') and options.empty: + args['empty'] = True + if hasattr(options, 'backend') and options.backend: + args['streaming_backend'] = options.backend + if hasattr(options, 'dbname') and options.dbname: + if options.conntype == 'tcp': + args['host'] = SonicDBConfig.getDbHostname(options.dbname) + args['port'] = SonicDBConfig.getDbPort(options.dbname) + args['db'] = SonicDBConfig.getDbId(options.dbname) + args['unix_socket_path'] = None + elif options.conntype == "unix_socket": + args['host'] = None + args['port'] = None + args['db'] = SonicDBConfig.getDbId(options.dbname) + args['unix_socket_path'] = SonicDBConfig.getDbSock(options.dbname) + else: + raise TypeError('redis connection type is tcp or unix_socket') + + return args + + def do_dump(options): + if options.output: + output = open(options.output, 'w') + else: + output = sys.stdout + + kwargs = options_to_kwargs(options) + dump(output, **kwargs) + + if options.output: + output.close() + + def do_load(options, args): + if len(args) > 0: + input = open(args[0], 'rb') + else: + input = sys.stdin + + kwargs = options_to_kwargs(options) + load(input, **kwargs) + + if len(args) > 0: + input.close() + + script_name = os.path.basename(sys.argv[0]) + if re.search(r'load(?:$|\.)', script_name): + action = help = LOAD + elif re.search(r'dump(?:$|\.)', script_name): + action = help = DUMP + else: + # default is dump, however if dump is specifically requested + # we don't show help text for toggling between dumping and loading + action = DUMP + help = None + + if help == LOAD: + usage = "Usage: %prog [options] [FILE]" + usage += "\n\nLoad data from FILE (which must be a JSON dump previously created" + usage += "\nby redisdl) into specified or default redis." + usage += "\n\nIf FILE is omitted standard input is read." + elif help == DUMP: + usage = "Usage: %prog [options]" + usage += "\n\nDump data from specified or default redis." + usage += "\n\nIf no output file is specified, dump to standard output." + else: + usage = "Usage: %prog [options]" + usage += "\n %prog -l [options] [FILE]" + usage += "\n\nDump data from redis or load data into redis." + usage += "\n\nIf input or output file is specified, dump to standard output and load" + usage += "\nfrom standard input." + parser = optparse.OptionParser(usage=usage) + parser.add_option('-w', '--password', help='connect with PASSWORD') + if help == DUMP: + parser.add_option('-n', '--dbname', help='dump DATABASE (APPL_DB/ASIC_DB...)') + parser.add_option('-t', '--conntype', help='indicate redis connection type (tcp[default] or unix_socket)', default='tcp') + parser.add_option('-k', '--keys', help='dump only keys matching specified glob-style pattern') + parser.add_option('-o', '--output', help='write to OUTPUT instead of stdout') + parser.add_option('-y', '--pretty', help='split output on multiple lines and indent it', action='store_true') + parser.add_option('-E', '--encoding', help='set encoding to use while decoding data from redis', default='utf-8') + elif help == LOAD: + parser.add_option('-n', '--dbname', help='dump DATABASE (APPL_DB/ASIC_DB...)') + parser.add_option('-t', '--conntype', help='indicate redis connection type (tcp[default] or unix_socket)', default='tcp') + parser.add_option('-e', '--empty', help='delete all keys in destination db prior to loading', action='store_true') + parser.add_option('-E', '--encoding', help='set encoding to use while encoding data to redis', default='utf-8') + parser.add_option('-B', '--backend', help='use specified streaming backend') + parser.add_option('-A', '--use-expireat', help='use EXPIREAT rather than TTL/EXPIRE', action='store_true') + else: + parser.add_option('-l', '--load', help='load data into redis (default is to dump data from redis)', action='store_true') + parser.add_option('-n', '--dbname', help='dump DATABASE (APPL_DB/ASIC_DB/COUNTERS_DB/LOGLEVEL_DB/CONFIG_DB...)') + parser.add_option('-t', '--conntype', help='indicate redis connection type (tcp[default] or unix_socket)', default='tcp') + parser.add_option('-k', '--keys', help='dump only keys matching specified glob-style pattern') + parser.add_option('-o', '--output', help='write to OUTPUT instead of stdout (dump mode only)') + parser.add_option('-y', '--pretty', help='split output on multiple lines and indent it (dump mode only)', action='store_true') + parser.add_option('-e', '--empty', help='delete all keys in destination db prior to loading (load mode only)', action='store_true') + parser.add_option('-E', '--encoding', help='set encoding to use while decoding data from redis', default='utf-8') + parser.add_option('-A', '--use-expireat', help='use EXPIREAT rather than TTL/EXPIRE', action='store_true') + parser.add_option('-B', '--backend', help='use specified streaming backend (load mode only)') + options, args = parser.parse_args() + + if hasattr(options, 'load') and options.load: + action = LOAD + + if action == DUMP: + if len(args) > 0: + parser.print_help() + exit(4) + do_dump(options) + else: + if len(args) > 1: + parser.print_help() + exit(4) + do_load(options, args) From d9c9c70fb543ed4e6c8bfff24e17e65613409e72 Mon Sep 17 00:00:00 2001 From: Dmytro Lytvynenko Date: Fri, 30 Sep 2022 01:12:01 +0300 Subject: [PATCH 135/151] [BFN] Move qsfp eeprom reading to new cached api (#9909) * Move qsfp eeprom reading to new cached api * provide reading multiple pages in recursive manner * workaround with flat memory on cmis * remove workaround with memory model * Remove unused imports --- .../sonic_platform/platform_thrift_client.py | 11 ++-- .../sonic_platform/pltfm_mgr_rpc/ttypes.py | 18 ------ .../sonic_platform/sfp.py | 62 +++++++++++++------ 3 files changed, 48 insertions(+), 43 deletions(-) diff --git a/platform/barefoot/sonic-platform-modules-bfn-montara/sonic_platform/platform_thrift_client.py b/platform/barefoot/sonic-platform-modules-bfn-montara/sonic_platform/platform_thrift_client.py index dff16577de74..8490d132a2df 100644 --- a/platform/barefoot/sonic-platform-modules-bfn-montara/sonic_platform/platform_thrift_client.py +++ b/platform/barefoot/sonic-platform-modules-bfn-montara/sonic_platform/platform_thrift_client.py @@ -1,12 +1,10 @@ #!/usr/bin/env python try: - import os - import sys import time - import importlib - sys.path.append(os.path.dirname(__file__)) + from sonic_platform.pltfm_mgr_rpc.pltfm_mgr_rpc import Client + from sonic_platform.pltfm_mgr_rpc.pltfm_mgr_rpc import InvalidPltfmMgrOperation from thrift.transport import TSocket from thrift.transport import TTransport @@ -25,9 +23,8 @@ def open(self): self.transport = TTransport.TBufferedTransport(self.transport) bprotocol = TBinaryProtocol.TBinaryProtocol(self.transport) - self.pltfm_mgr_module = importlib.import_module(".".join(["pltfm_mgr_rpc", "pltfm_mgr_rpc"])) pltfm_mgr_protocol = TMultiplexedProtocol.TMultiplexedProtocol(bprotocol, "pltfm_mgr_rpc") - self.pltfm_mgr = self.pltfm_mgr_module.Client(pltfm_mgr_protocol) + self.pltfm_mgr = Client(pltfm_mgr_protocol) self.transport.open() return self @@ -59,7 +56,7 @@ def pltfm_mgr_try(func, default=None, thrift_attempts=35): def pm_cb_run(client): try: return (None, func(client.pltfm_mgr)) - except client.pltfm_mgr_module.InvalidPltfmMgrOperation as ouch: + except InvalidPltfmMgrOperation as ouch: return (ouch.code, default) return thrift_try(pm_cb_run) diff --git a/platform/barefoot/sonic-platform-modules-bfn-montara/sonic_platform/pltfm_mgr_rpc/ttypes.py b/platform/barefoot/sonic-platform-modules-bfn-montara/sonic_platform/pltfm_mgr_rpc/ttypes.py index 501596941664..391d4bd5377b 100644 --- a/platform/barefoot/sonic-platform-modules-bfn-montara/sonic_platform/pltfm_mgr_rpc/ttypes.py +++ b/platform/barefoot/sonic-platform-modules-bfn-montara/sonic_platform/pltfm_mgr_rpc/ttypes.py @@ -16,24 +16,6 @@ all_structs = [] -class qsfp_eeprom_page_t(object): - PAGE0_LOWER = 0 - PAGE0_UPPER = 1 - PAGE3 = 2 - - _VALUES_TO_NAMES = { - 0: "PAGE0_LOWER", - 1: "PAGE0_UPPER", - 2: "PAGE3", - } - - _NAMES_TO_VALUES = { - "PAGE0_LOWER": 0, - "PAGE0_UPPER": 1, - "PAGE3": 2, - } - - class pltfm_mgr_sys_tmp_t(object): """ Attributes: diff --git a/platform/barefoot/sonic-platform-modules-bfn-montara/sonic_platform/sfp.py b/platform/barefoot/sonic-platform-modules-bfn-montara/sonic_platform/sfp.py index f5d800b749c9..6a5534d8ba6b 100644 --- a/platform/barefoot/sonic-platform-modules-bfn-montara/sonic_platform/sfp.py +++ b/platform/barefoot/sonic-platform-modules-bfn-montara/sonic_platform/sfp.py @@ -11,29 +11,38 @@ SFP_TYPE = "SFP" QSFP_TYPE = "QSFP" QSFP_DD_TYPE = "QSFP_DD" +EEPROM_PAGE_SIZE = 128 +try: + from thrift.Thrift import TApplicationException + + def cached_num_bytes_get(client): + return client.pltfm_mgr.pltfm_mgr_qsfp_cached_num_bytes_get(1, 0, 0, 0) + thrift_try(cached_num_bytes_get, 1) + EEPROM_CACHED_API_SUPPORT = True +except TApplicationException as e: + EEPROM_CACHED_API_SUPPORT = False class Sfp(SfpOptoeBase): """ BFN Platform-specific SFP class """ - SFP_EEPROM_PATH = "/var/run/platform/sfp/" - def __init__(self, port_num): SfpOptoeBase.__init__(self) self.index = port_num self.port_num = port_num self.sfp_type = QSFP_TYPE + self.SFP_EEPROM_PATH = "/var/run/platform/sfp/" - if not os.path.exists(self.SFP_EEPROM_PATH): - try: - os.makedirs(self.SFP_EEPROM_PATH) - except OSError as e: - if e.errno != errno.EEXIST: - raise - - self.eeprom_path = self.SFP_EEPROM_PATH + "sfp{}-eeprom-cache".format(self.index) + if not EEPROM_CACHED_API_SUPPORT: + if not os.path.exists(self.SFP_EEPROM_PATH): + try: + os.makedirs(self.SFP_EEPROM_PATH) + except OSError as e: + if e.errno != errno.EEXIST: + raise + self.eeprom_path = self.SFP_EEPROM_PATH + "sfp{}-eeprom-cache".format(self.index) def get_presence(self): """ @@ -47,7 +56,7 @@ def qsfp_presence_get(client): try: presence = thrift_try(qsfp_presence_get) except Exception as e: - print( e.__doc__) + print(e.__doc__) print(e.message) return presence @@ -75,14 +84,31 @@ def get_eeprom_path(self): def qsfp_info_get(client): return client.pltfm_mgr.pltfm_mgr_qsfp_info_get(self.index) - if self.get_presence(): - eeprom_hex = thrift_try(qsfp_info_get) - eeprom_raw = bytearray.fromhex(eeprom_hex) - with open(self.eeprom_path, 'wb') as fp: - fp.write(eeprom_raw) - return self.eeprom_path + eeprom_hex = thrift_try(qsfp_info_get) + eeprom_raw = bytearray.fromhex(eeprom_hex) + with open(self.eeprom_path, 'wb') as fp: + fp.write(eeprom_raw) + return self.eeprom_path + + def read_eeprom(self, offset, num_bytes): + if not self.get_presence(): + return None + + if not EEPROM_CACHED_API_SUPPORT: + return super().read_eeprom(offset, num_bytes) + + def cached_num_bytes_get(page, offset, num_bytes): + def qsfp_cached_num_bytes_get(client): + return client.pltfm_mgr.pltfm_mgr_qsfp_cached_num_bytes_get(self.index, page, offset, num_bytes) + return bytearray.fromhex(thrift_try(qsfp_cached_num_bytes_get)) + + page_offset = offset % EEPROM_PAGE_SIZE + if page_offset + num_bytes > EEPROM_PAGE_SIZE: + curr_page_num_bytes_left = EEPROM_PAGE_SIZE - page_offset + curr_page_bytes = cached_num_bytes_get(offset // EEPROM_PAGE_SIZE, page_offset, curr_page_num_bytes_left) + return curr_page_bytes + self.read_eeprom(offset + curr_page_num_bytes_left, num_bytes - curr_page_num_bytes_left) - return None + return cached_num_bytes_get(offset // EEPROM_PAGE_SIZE, page_offset, num_bytes) def write_eeprom(self, offset, num_bytes, write_buffer): # Not supported at the moment From d08fcc971cbd7b27c7140eaa7b1baaad433ddba8 Mon Sep 17 00:00:00 2001 From: Dmytro Lytvynenko Date: Fri, 30 Sep 2022 01:13:46 +0300 Subject: [PATCH 136/151] [BFN] Updated syseeprom platform plugin to use onie-eeprom (#10556) * Align system eeprom info with ONIE * revert linked sonic_platform implementation * refactor into one class * refactor after review --- .../sonic_platform/chassis.py | 32 ++-- .../sonic_platform/eeprom.py | 155 +++++++++------- .../pltfm_mgr_rpc/pltfm_mgr_rpc.py | 175 ++++++++++++++++++ .../sonic_platform/pltfm_mgr_rpc/ttypes.py | 62 +++++++ 4 files changed, 336 insertions(+), 88 deletions(-) diff --git a/platform/barefoot/sonic-platform-modules-bfn-montara/sonic_platform/chassis.py b/platform/barefoot/sonic-platform-modules-bfn-montara/sonic_platform/chassis.py index 6d0e8b8c120c..1041561db423 100644 --- a/platform/barefoot/sonic-platform-modules-bfn-montara/sonic_platform/chassis.py +++ b/platform/barefoot/sonic-platform-modules-bfn-montara/sonic_platform/chassis.py @@ -13,8 +13,8 @@ from sonic_platform.psu import psu_list_get from sonic_platform.fan_drawer import fan_drawer_list_get from sonic_platform.thermal import thermal_list_get - from eeprom import Eeprom - from platform_utils import file_create + from sonic_platform.platform_utils import file_create + from sonic_platform.eeprom import Eeprom from sonic_platform.platform_thrift_client import pltfm_mgr_ready from sonic_platform.platform_thrift_client import thrift_try @@ -40,7 +40,10 @@ class Chassis(ChassisBase): def __init__(self): ChassisBase.__init__(self) - self.__eeprom = None + self._eeprom = Eeprom() + self.__tlv_bin_eeprom = self._eeprom.get_raw_data() + self.__tlv_dict_eeprom = self._eeprom.get_data() + self.__fan_drawers = None self.__fan_list = None self.__thermals = None @@ -57,16 +60,6 @@ def __init__(self): file_create(config_dict['handlers']['file']['filename'], '646') logging.config.dictConfig(config_dict) - @property - def _eeprom(self): - if self.__eeprom is None: - self.__eeprom = Eeprom() - return self.__eeprom - - @_eeprom.setter - def _eeprom(self, value): - pass - @property def _fan_drawer_list(self): if self.__fan_drawers is None: @@ -152,7 +145,7 @@ def get_name(self): Returns: string: The name of the chassis """ - return self._eeprom.modelstr() + return self._eeprom.modelstr(self.__tlv_bin_eeprom) def get_presence(self): """ @@ -168,7 +161,7 @@ def get_model(self): Returns: string: Model/part number of chassis """ - return self._eeprom.part_number_str() + return self._eeprom.part_number_str(self.__tlv_bin_eeprom) def get_serial(self): """ @@ -176,7 +169,7 @@ def get_serial(self): Returns: string: Serial number of chassis """ - return self._eeprom.serial_number_str() + return self._eeprom.serial_number_str(self.__tlv_bin_eeprom) def get_revision(self): """ @@ -184,7 +177,8 @@ def get_revision(self): Returns: string: Revision number of chassis """ - return self._eeprom.revision_str() + return self.__tlv_dict_eeprom.get( + "0x{:X}".format(Eeprom._TLV_CODE_LABEL_REVISION), 'N/A') def get_sfp(self, index): """ @@ -225,7 +219,7 @@ def get_base_mac(self): A string containing the MAC address in the format 'XX:XX:XX:XX:XX:XX' """ - return self._eeprom.base_mac_addr() + return self._eeprom.base_mac_addr(self.__tlv_bin_eeprom) def get_system_eeprom_info(self): """ @@ -236,7 +230,7 @@ def get_system_eeprom_info(self): OCP ONIE TlvInfo EEPROM format and values are their corresponding values. """ - return self._eeprom.system_eeprom_info() + return self.__tlv_dict_eeprom def __get_transceiver_change_event(self, timeout=0): forever = False diff --git a/platform/barefoot/sonic-platform-modules-bfn-montara/sonic_platform/eeprom.py b/platform/barefoot/sonic-platform-modules-bfn-montara/sonic_platform/eeprom.py index 2335c02863d9..4b5c1e3051fb 100644 --- a/platform/barefoot/sonic-platform-modules-bfn-montara/sonic_platform/eeprom.py +++ b/platform/barefoot/sonic-platform-modules-bfn-montara/sonic_platform/eeprom.py @@ -2,7 +2,8 @@ import os import sys import datetime - import re + import logging + import logging.config sys.path.append(os.path.dirname(__file__)) @@ -13,13 +14,15 @@ from sonic_platform_base.sonic_eeprom import eeprom_base from sonic_platform_base.sonic_eeprom import eeprom_tlvinfo - from platform_utils import file_create - from platform_thrift_client import thrift_try + from sonic_py_common import device_info + + from sonic_platform.platform_thrift_client import thrift_try + from sonic_platform.platform_utils import file_create + except ImportError as e: raise ImportError (str(e) + "- required module not found") - _platform_eeprom_map = { "prod_name" : ("Product Name", "0x21", 12), "odm_pcba_part_num" : ("Part Number", "0x22", 13), @@ -44,25 +47,55 @@ class Eeprom(eeprom_tlvinfo.TlvInfoDecoder): def __init__(self): file_create(_EEPROM_SYMLINK, '646') file_create(_EEPROM_STATUS, '646') - with open(_EEPROM_STATUS, 'w') as f: - f.write("initializing..") + super(Eeprom, self).__init__(_EEPROM_SYMLINK, 0, _EEPROM_STATUS, True) - self.eeprom_path = _EEPROM_SYMLINK - super(Eeprom, self).__init__(self.eeprom_path, 0, _EEPROM_STATUS, True) - - def sys_eeprom_get(client): - return client.pltfm_mgr.pltfm_mgr_sys_eeprom_get() + self._eeprom_bin = bytearray() + self.report_status("initializing..") try: - platform_eeprom = thrift_try(sys_eeprom_get) - except Exception: - raise RuntimeError("eeprom.py: Initialization failed") + try: + if device_info.get_platform() in ["x86_64-accton_as9516_32d-r0", + "x86_64-accton_as9516bf_32d-r0"]: + def tlv_eeprom_get(client): + return client.pltfm_mgr.pltfm_mgr_tlv_eeprom_get() + try: + self._eeprom_bin = bytearray.fromhex( + thrift_try(tlv_eeprom_get, 1).raw_content_hex) + except TApplicationException as e: + raise RuntimeError("api is not supported") + except Exception as e: + self._eeprom_bin = bytearray.fromhex( + thrift_try(tlv_eeprom_get).raw_content_hex) + else: + raise RuntimeError("platform is not supported") + + except RuntimeError as e: + logging.warning("Tlv eeprom fetching failed: %s, using OpenBMC" % (str(e))) + + def sys_eeprom_get(client): + return client.pltfm_mgr.pltfm_mgr_sys_eeprom_get() + + eeprom_params = self.platfrom_eeprom_to_params(thrift_try(sys_eeprom_get)) + stdout_stream = sys.stdout + sys.stdout = open(os.devnull, 'w') + self._eeprom_bin = self.set_eeprom(self._eeprom_bin, [eeprom_params]) + sys.stdout.close() + sys.stdout = stdout_stream + try: + self.write_eeprom(self._eeprom_bin) + self.report_status("ok") + except IOError as e: + logging.error("Failed to write eeprom: %s" % (str(e))) - self.__eeprom_init(platform_eeprom) + except Exception as e: + logging.error("eeprom.py: Initialization failed: %s" % (str(e))) + raise RuntimeError("eeprom.py: Initialization failed: %s" % (str(e))) - def __eeprom_init(self, platform_eeprom): - with open(_EEPROM_STATUS, 'w') as f: - f.write("ok") + self._system_eeprom_info = dict() + visitor = EepromContentVisitor(self._system_eeprom_info) + self.visit_eeprom(self._eeprom_bin, visitor) + @staticmethod + def platfrom_eeprom_to_params(platform_eeprom): eeprom_params = "" for attr, val in platform_eeprom.__dict__.items(): if val is None: @@ -86,57 +119,41 @@ def __eeprom_init(self, platform_eeprom): if len(eeprom_params) > 0: eeprom_params += "," eeprom_params += "{0:s}={1:s}".format(elem[1], value) + return eeprom_params - orig_stdout = sys.stdout - sys.stdout = StringIO() - try: - eeprom_data = eeprom_tlvinfo.TlvInfoDecoder.set_eeprom(self, "", [eeprom_params]) - finally: - decode_output = sys.stdout.getvalue() - sys.stdout = orig_stdout - - eeprom_base.EepromDecoder.write_eeprom(self, eeprom_data) - self.__eeprom_tlv_dict = self.__parse_output(decode_output) + def get_data(self): + return self._system_eeprom_info - def __parse_output(self, decode_output): - EEPROM_DECODE_HEADLINES = 6 - lines = decode_output.replace('\0', '').split('\n') - lines = lines[EEPROM_DECODE_HEADLINES:] - res = dict() - - for line in lines: - try: - # match whitespace-separated tag hex, length and value (value is mathced with its whitespaces) - match = re.search('(0x[0-9a-fA-F]{2})([\s]+[\S]+[\s]+)([\S]+[\s]*[\S]*)', line) - if match is not None: - code = match.group(1) - value = match.group(3).rstrip('\0') - res[code] = value - except Exception: - pass - return res - - def __tlv_get(self, code): - return self.__eeprom_tlv_dict.get("0x{:X}".format(code), 'N/A') - - def system_eeprom_info(self): - return self.__eeprom_tlv_dict - - def serial_number_str(self): - return self.__tlv_get(self._TLV_CODE_SERIAL_NUMBER) - - def serial_str(self): - return self.serial_number_str() - - def base_mac_addr(self): - return self.__tlv_get(self._TLV_CODE_MAC_BASE) - - def part_number_str(self): - return self.__tlv_get(self._TLV_CODE_PART_NUMBER) - - def modelstr(self): - return self.__tlv_get(self._TLV_CODE_PRODUCT_NAME) - - def revision_str(self): - return self.__tlv_get(self._TLV_CODE_LABEL_REVISION) + def get_raw_data(self): + return self._eeprom_bin + def report_status(self, status): + status_file = None + try: + status_file = open(_EEPROM_STATUS, "w") + status_file.write(status) + except IOError as e: + logging.error("Failed to report state: %s" % (str(e))) + finally: + if status_file is not None: + status_file.close() + +class EepromContentVisitor(eeprom_tlvinfo.EepromDefaultVisitor): + def __init__(self, content_dict): + self.content_dict = content_dict + + def visit_tlv(self, name, code, length, value): + if code != Eeprom._TLV_CODE_VENDOR_EXT: + self.content_dict["0x{:X}".format(code)] = value.rstrip('\0') + else: + if value: + value = value.rstrip('\0') + if value: + code = "0x{:X}".format(code) + if code not in self.content_dict: + self.content_dict[code] = [value] + else: + self.content_dict[code].append(value) + + def set_error(self, error): + logging.error("EepromContentVisitor error: %s" % (str(error))) diff --git a/platform/barefoot/sonic-platform-modules-bfn-montara/sonic_platform/pltfm_mgr_rpc/pltfm_mgr_rpc.py b/platform/barefoot/sonic-platform-modules-bfn-montara/sonic_platform/pltfm_mgr_rpc/pltfm_mgr_rpc.py index 0fa03d58b31a..b671be1be313 100644 --- a/platform/barefoot/sonic-platform-modules-bfn-montara/sonic_platform/pltfm_mgr_rpc/pltfm_mgr_rpc.py +++ b/platform/barefoot/sonic-platform-modules-bfn-montara/sonic_platform/pltfm_mgr_rpc/pltfm_mgr_rpc.py @@ -33,6 +33,9 @@ def pltfm_mgr_sys_tmp_get(self): def pltfm_mgr_sys_eeprom_get(self): pass + def pltfm_mgr_tlv_eeprom_get(self): + pass + def pltfm_mgr_pwr_supply_present_get(self, ps_num): """ Parameters: @@ -403,6 +406,34 @@ def recv_pltfm_mgr_sys_eeprom_get(self): raise result.ouch raise TApplicationException(TApplicationException.MISSING_RESULT, "pltfm_mgr_sys_eeprom_get failed: unknown result") + def pltfm_mgr_tlv_eeprom_get(self): + self.send_pltfm_mgr_tlv_eeprom_get() + return self.recv_pltfm_mgr_tlv_eeprom_get() + + def send_pltfm_mgr_tlv_eeprom_get(self): + self._oprot.writeMessageBegin('pltfm_mgr_tlv_eeprom_get', TMessageType.CALL, self._seqid) + args = pltfm_mgr_tlv_eeprom_get_args() + args.write(self._oprot) + self._oprot.writeMessageEnd() + self._oprot.trans.flush() + + def recv_pltfm_mgr_tlv_eeprom_get(self): + iprot = self._iprot + (fname, mtype, rseqid) = iprot.readMessageBegin() + if mtype == TMessageType.EXCEPTION: + x = TApplicationException() + x.read(iprot) + iprot.readMessageEnd() + raise x + result = pltfm_mgr_tlv_eeprom_get_result() + result.read(iprot) + iprot.readMessageEnd() + if result.success is not None: + return result.success + if result.ouch is not None: + raise result.ouch + raise TApplicationException(TApplicationException.MISSING_RESULT, "pltfm_mgr_tlv_eeprom_get failed: unknown result") + def pltfm_mgr_pwr_supply_present_get(self, ps_num): """ Parameters: @@ -1579,6 +1610,7 @@ def __init__(self, handler): self._processMap["pltfm_mgr_dummy"] = Processor.process_pltfm_mgr_dummy self._processMap["pltfm_mgr_sys_tmp_get"] = Processor.process_pltfm_mgr_sys_tmp_get self._processMap["pltfm_mgr_sys_eeprom_get"] = Processor.process_pltfm_mgr_sys_eeprom_get + self._processMap["pltfm_mgr_tlv_eeprom_get"] = Processor.process_pltfm_mgr_tlv_eeprom_get self._processMap["pltfm_mgr_pwr_supply_present_get"] = Processor.process_pltfm_mgr_pwr_supply_present_get self._processMap["pltfm_mgr_pwr_supply_info_get"] = Processor.process_pltfm_mgr_pwr_supply_info_get self._processMap["pltfm_mgr_pwr_rail_info_get"] = Processor.process_pltfm_mgr_pwr_rail_info_get @@ -1710,6 +1742,32 @@ def process_pltfm_mgr_sys_eeprom_get(self, seqid, iprot, oprot): oprot.writeMessageEnd() oprot.trans.flush() + def process_pltfm_mgr_tlv_eeprom_get(self, seqid, iprot, oprot): + args = pltfm_mgr_tlv_eeprom_get_args() + args.read(iprot) + iprot.readMessageEnd() + result = pltfm_mgr_tlv_eeprom_get_result() + try: + result.success = self._handler.pltfm_mgr_tlv_eeprom_get() + msg_type = TMessageType.REPLY + except TTransport.TTransportException: + raise + except InvalidPltfmMgrOperation as ouch: + msg_type = TMessageType.REPLY + result.ouch = ouch + except TApplicationException as ex: + logging.exception('TApplication exception in handler') + msg_type = TMessageType.EXCEPTION + result = ex + except Exception: + logging.exception('Unexpected exception in handler') + msg_type = TMessageType.EXCEPTION + result = TApplicationException(TApplicationException.INTERNAL_ERROR, 'Internal error') + oprot.writeMessageBegin("pltfm_mgr_tlv_eeprom_get", msg_type, seqid) + result.write(oprot) + oprot.writeMessageEnd() + oprot.trans.flush() + def process_pltfm_mgr_pwr_supply_present_get(self, seqid, iprot, oprot): args = pltfm_mgr_pwr_supply_present_get_args() args.read(iprot) @@ -2954,6 +3012,123 @@ def __ne__(self, other): ) +class pltfm_mgr_tlv_eeprom_get_args(object): + + + def read(self, iprot): + if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None: + iprot._fast_decode(self, iprot, [self.__class__, self.thrift_spec]) + return + iprot.readStructBegin() + while True: + (fname, ftype, fid) = iprot.readFieldBegin() + if ftype == TType.STOP: + break + else: + iprot.skip(ftype) + iprot.readFieldEnd() + iprot.readStructEnd() + + def write(self, oprot): + if oprot._fast_encode is not None and self.thrift_spec is not None: + oprot.trans.write(oprot._fast_encode(self, [self.__class__, self.thrift_spec])) + return + oprot.writeStructBegin('pltfm_mgr_tlv_eeprom_get_args') + oprot.writeFieldStop() + oprot.writeStructEnd() + + def validate(self): + return + + def __repr__(self): + L = ['%s=%r' % (key, value) + for key, value in self.__dict__.items()] + return '%s(%s)' % (self.__class__.__name__, ', '.join(L)) + + def __eq__(self, other): + return isinstance(other, self.__class__) and self.__dict__ == other.__dict__ + + def __ne__(self, other): + return not (self == other) +all_structs.append(pltfm_mgr_tlv_eeprom_get_args) +pltfm_mgr_tlv_eeprom_get_args.thrift_spec = ( +) + + +class pltfm_mgr_tlv_eeprom_get_result(object): + """ + Attributes: + - success + - ouch + + """ + + + def __init__(self, success=None, ouch=None,): + self.success = success + self.ouch = ouch + + def read(self, iprot): + if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None: + iprot._fast_decode(self, iprot, [self.__class__, self.thrift_spec]) + return + iprot.readStructBegin() + while True: + (fname, ftype, fid) = iprot.readFieldBegin() + if ftype == TType.STOP: + break + if fid == 0: + if ftype == TType.STRUCT: + self.success = pltfm_mgr_tlv_sys_eeprom_t() + self.success.read(iprot) + else: + iprot.skip(ftype) + elif fid == 1: + if ftype == TType.STRUCT: + self.ouch = InvalidPltfmMgrOperation.read(iprot) + else: + iprot.skip(ftype) + else: + iprot.skip(ftype) + iprot.readFieldEnd() + iprot.readStructEnd() + + def write(self, oprot): + if oprot._fast_encode is not None and self.thrift_spec is not None: + oprot.trans.write(oprot._fast_encode(self, [self.__class__, self.thrift_spec])) + return + oprot.writeStructBegin('pltfm_mgr_tlv_eeprom_get_result') + if self.success is not None: + oprot.writeFieldBegin('success', TType.STRUCT, 0) + self.success.write(oprot) + oprot.writeFieldEnd() + if self.ouch is not None: + oprot.writeFieldBegin('ouch', TType.STRUCT, 1) + self.ouch.write(oprot) + oprot.writeFieldEnd() + oprot.writeFieldStop() + oprot.writeStructEnd() + + def validate(self): + return + + def __repr__(self): + L = ['%s=%r' % (key, value) + for key, value in self.__dict__.items()] + return '%s(%s)' % (self.__class__.__name__, ', '.join(L)) + + def __eq__(self, other): + return isinstance(other, self.__class__) and self.__dict__ == other.__dict__ + + def __ne__(self, other): + return not (self == other) +all_structs.append(pltfm_mgr_tlv_eeprom_get_result) +pltfm_mgr_tlv_eeprom_get_result.thrift_spec = ( + (0, TType.STRUCT, 'success', [pltfm_mgr_tlv_sys_eeprom_t, None], None, ), # 0 + (1, TType.STRUCT, 'ouch', [InvalidPltfmMgrOperation, None], None, ), # 1 +) + + class pltfm_mgr_pwr_supply_present_get_args(object): """ Attributes: diff --git a/platform/barefoot/sonic-platform-modules-bfn-montara/sonic_platform/pltfm_mgr_rpc/ttypes.py b/platform/barefoot/sonic-platform-modules-bfn-montara/sonic_platform/pltfm_mgr_rpc/ttypes.py index 391d4bd5377b..ad686b888029 100644 --- a/platform/barefoot/sonic-platform-modules-bfn-montara/sonic_platform/pltfm_mgr_rpc/ttypes.py +++ b/platform/barefoot/sonic-platform-modules-bfn-montara/sonic_platform/pltfm_mgr_rpc/ttypes.py @@ -460,6 +460,63 @@ def __ne__(self, other): return not (self == other) +class pltfm_mgr_tlv_sys_eeprom_t(object): + """ + Attributes: + - raw_content_hex + + """ + + + def __init__(self, raw_content_hex=None,): + self.raw_content_hex = raw_content_hex + + def read(self, iprot): + if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None: + iprot._fast_decode(self, iprot, [self.__class__, self.thrift_spec]) + return + iprot.readStructBegin() + while True: + (fname, ftype, fid) = iprot.readFieldBegin() + if ftype == TType.STOP: + break + if fid == 1: + if ftype == TType.STRING: + self.raw_content_hex = iprot.readString().decode('utf-8', errors='replace') if sys.version_info[0] == 2 else iprot.readString() + else: + iprot.skip(ftype) + else: + iprot.skip(ftype) + iprot.readFieldEnd() + iprot.readStructEnd() + + def write(self, oprot): + if oprot._fast_encode is not None and self.thrift_spec is not None: + oprot.trans.write(oprot._fast_encode(self, [self.__class__, self.thrift_spec])) + return + oprot.writeStructBegin('pltfm_mgr_tlv_sys_eeprom_t') + if self.raw_content_hex is not None: + oprot.writeFieldBegin('raw_content_hex', TType.STRING, 1) + oprot.writeString(self.raw_content_hex.encode('utf-8') if sys.version_info[0] == 2 else self.raw_content_hex) + oprot.writeFieldEnd() + oprot.writeFieldStop() + oprot.writeStructEnd() + + def validate(self): + return + + def __repr__(self): + L = ['%s=%r' % (key, value) + for key, value in self.__dict__.items()] + return '%s(%s)' % (self.__class__.__name__, ', '.join(L)) + + def __eq__(self, other): + return isinstance(other, self.__class__) and self.__dict__ == other.__dict__ + + def __ne__(self, other): + return not (self == other) + + class pltfm_mgr_pwr_supply_info_t(object): """ Attributes: @@ -1380,6 +1437,11 @@ def __ne__(self, other): (21, TType.STRING, 'location', 'UTF8', None, ), # 21 (22, TType.I16, 'crc8', None, None, ), # 22 ) +all_structs.append(pltfm_mgr_tlv_sys_eeprom_t) +pltfm_mgr_tlv_sys_eeprom_t.thrift_spec = ( + None, # 0 + (1, TType.STRING, 'raw_content_hex', 'UTF8', None, ), # 1 +) all_structs.append(pltfm_mgr_pwr_supply_info_t) pltfm_mgr_pwr_supply_info_t.thrift_spec = ( None, # 0 From 9bb0a7f33cd99f769063dd4bb798f0b59985e619 Mon Sep 17 00:00:00 2001 From: Andriy Kokhan Date: Fri, 30 Sep 2022 01:18:43 +0300 Subject: [PATCH 137/151] [BFN] Canceling PSU platform API calls on SIGTERM (#10720) * [BFN] Canceling PSU platform API calls on SIGTERM Signed-off-by: Andriy Kokhan * [BFN] Fixed SONiC fwutil exec time (#31) Signed-off-by: Taras Keryk Signed-off-by: Andriy Kokhan Signed-off-by: Taras Keryk Co-authored-by: Taras Keryk --- .../sonic_platform/component.py | 2 + .../sonic_platform/platform_utils.py | 60 ++++++++++++++++++- .../sonic_platform/psu.py | 30 +++++++++- 3 files changed, 89 insertions(+), 3 deletions(-) diff --git a/platform/barefoot/sonic-platform-modules-bfn-montara/sonic_platform/component.py b/platform/barefoot/sonic-platform-modules-bfn-montara/sonic_platform/component.py index 47a0993bf3e5..a7f236cb42a4 100644 --- a/platform/barefoot/sonic-platform-modules-bfn-montara/sonic_platform/component.py +++ b/platform/barefoot/sonic-platform-modules-bfn-montara/sonic_platform/component.py @@ -6,6 +6,7 @@ import json from collections import OrderedDict from sonic_py_common import device_info + from platform_utils import limit_execution_time except ImportError as e: raise ImportError(str(e) + "- required module not found") @@ -24,6 +25,7 @@ def get_bios_version(): except subprocess.CalledProcessError as e: raise RuntimeError("Failed to get BIOS version") +@limit_execution_time(1) def get_bmc_version(): """ Retrieves the firmware version of the BMC diff --git a/platform/barefoot/sonic-platform-modules-bfn-montara/sonic_platform/platform_utils.py b/platform/barefoot/sonic-platform-modules-bfn-montara/sonic_platform/platform_utils.py index 81e78ee01041..2f7b5aecb6d0 100644 --- a/platform/barefoot/sonic-platform-modules-bfn-montara/sonic_platform/platform_utils.py +++ b/platform/barefoot/sonic-platform-modules-bfn-montara/sonic_platform/platform_utils.py @@ -3,11 +3,19 @@ try: import os import subprocess + import signal + from functools import wraps except ImportError as e: raise ImportError(str(e) + "- required module not found") def file_create(path, mode=None): + """ + Ensure that file is created with the appropriate permissions + Args: + path: full path of a file + mode: file permission in octal representation + """ def run_cmd(cmd): if os.geteuid() != 0: cmd.insert(0, 'sudo') @@ -18,5 +26,55 @@ def run_cmd(cmd): run_cmd(['mkdir', '-p', file_path]) if not os.path.isfile(path): run_cmd(['touch', path]) - if (mode is not None): + if (mode is not None): run_cmd(['chmod', mode, path]) + +def cancel_on_sigterm(func): + """ + Wrapper for a function which has to be cancel on SIGTERM + """ + @wraps(func) + def wrapper(*args, **kwargs): + def handler(sig, frame): + if sigterm_handler: + sigterm_handler(sig, frame) + raise Exception("Canceling {}() execution...".format(func.__name__)) + + sigterm_handler = signal.getsignal(signal.SIGTERM) + signal.signal(signal.SIGTERM, handler) + result = None + try: + result = func(*args, **kwargs) + finally: + signal.signal(signal.SIGTERM, sigterm_handler) + return result + return wrapper + +def limit_execution_time(execution_time_secs: int): + """ + Wrapper for a function whose execution time must be limited + Args: + execution_time_secs: maximum execution time in seconds, + after which the function execution will be stopped + """ + def wrapper(func): + @wraps(func) + def execution_func(*args, **kwargs): + def handler(sig, frame): + if sigalrm_handler: + sigalrm_handler(sig, frame) + raise Exception("Canceling {}() execution...".format(func.__name__)) + + sigalrm_handler = signal.getsignal(signal.SIGALRM) + signal.signal(signal.SIGALRM, handler) + signal.alarm(execution_time_secs) + result = None + try: + result = func(*args, **kwargs) + finally: + signal.alarm(0) + + return result + return execution_func + return wrapper + diff --git a/platform/barefoot/sonic-platform-modules-bfn-montara/sonic_platform/psu.py b/platform/barefoot/sonic-platform-modules-bfn-montara/sonic_platform/psu.py index fb9bce50e071..fbd83d6496ae 100644 --- a/platform/barefoot/sonic-platform-modules-bfn-montara/sonic_platform/psu.py +++ b/platform/barefoot/sonic-platform-modules-bfn-montara/sonic_platform/psu.py @@ -4,18 +4,26 @@ import os import sys import time + import signal + import syslog sys.path.append(os.path.dirname(__file__)) from .platform_thrift_client import thrift_try from sonic_platform_base.psu_base import PsuBase + from platform_utils import cancel_on_sigterm + except ImportError as e: raise ImportError (str(e) + "- required module not found") class Psu(PsuBase): """Platform-specific PSU class""" + sigterm = False + sigterm_default_handler = None + cls_inited = False + def __init__(self, index): PsuBase.__init__(self) self.__index = index @@ -24,6 +32,21 @@ def __init__(self, index): # STUB IMPLEMENTATION self.color = "" + syslog.syslog(syslog.LOG_INFO, "Created PSU #{} instance".format(self.__index)) + if not Psu.cls_inited: + Psu.sigterm_default_handler = signal.getsignal(signal.SIGTERM) + signal.signal(signal.SIGTERM, Psu.signal_handler) + if Psu.sigterm_default_handler: + syslog.syslog(syslog.LOG_INFO, "Default SIGTERM handler overridden!!") + Psu.cls_inited = True + + @classmethod + def signal_handler(cls, sig, frame): + if cls.sigterm_default_handler: + cls.sigterm_default_handler(sig, frame) + syslog.syslog(syslog.LOG_INFO, "Canceling PSU platform API calls...") + cls.sigterm = True + ''' Units of returned info object values: vin - V @@ -33,20 +56,23 @@ def __init__(self, index): fspeed - RPM ''' def __info_get(self): + @cancel_on_sigterm def psu_info_get(client): return client.pltfm_mgr.pltfm_mgr_pwr_supply_info_get(self.__index) # Update cache once per 2 seconds - if self.__ts + 2 < time.time(): + if self.__ts + 2 < time.time() and not Psu.sigterm: self.__info = None try: self.__info = thrift_try(psu_info_get, attempts=1) + except Exception as e: + if "Canceling" in str(e): + syslog.syslog(syslog.LOG_INFO, "{}".format(e)) finally: self.__ts = time.time() return self.__info return self.__info - @staticmethod def get_num_psus(): """ From 179882398c0c035f3bf2a522c07ad5c958453d80 Mon Sep 17 00:00:00 2001 From: Prince George <45705344+prgeor@users.noreply.github.com> Date: Thu, 29 Sep 2022 17:12:20 -0700 Subject: [PATCH 138/151] Revert "Support for serdes platform library debian installation for Innovium SONiC image (#11920)" (#12227) This reverts commit 8c7e0f8e02233dc4236f8f7f048b4281ab9d31b8. --- platform/innovium/invm-sai.mk | 4 +--- platform/innovium/one-image.mk | 2 +- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/platform/innovium/invm-sai.mk b/platform/innovium/invm-sai.mk index 734184e35b0c..25e490e44f83 100755 --- a/platform/innovium/invm-sai.mk +++ b/platform/innovium/invm-sai.mk @@ -5,13 +5,11 @@ INVM_SAI_ONLINE = https://github.com/Innovium/SONiC/raw/master/debian/master INVM_LIBSAI = isai.deb INVM_HSAI = saihdr.deb INVM_DRV = ipd.deb -INVM_SERDES_PLATFORM_LIBRARY = ivm_serdes_pltfm.deb $(INVM_LIBSAI)_URL = $(INVM_SAI_ONLINE)/$(INVM_LIBSAI) $(INVM_HSAI)_URL = $(INVM_SAI_ONLINE)/$(INVM_HSAI) $(INVM_DRV)_URL = $(INVM_SAI_ONLINE)/$(INVM_DRV) -$(INVM_SERDES_PLATFORM_LIBRARY)_URL = $(INVM_SAI_ONLINE)/$(INVM_SERDES_PLATFORM_LIBRARY) $(eval $(call add_conflict_package,$(INVM_HSAI),$(LIBSAIVS_DEV))) -SONIC_ONLINE_DEBS += $(INVM_LIBSAI) $(INVM_HSAI) $(INVM_DRV) $(INVM_SERDES_PLATFORM_LIBRARY) +SONIC_ONLINE_DEBS += $(INVM_LIBSAI) $(INVM_HSAI) $(INVM_DRV) diff --git a/platform/innovium/one-image.mk b/platform/innovium/one-image.mk index 39e2e9fc8246..2cae779d71ac 100755 --- a/platform/innovium/one-image.mk +++ b/platform/innovium/one-image.mk @@ -8,6 +8,6 @@ $(SONIC_ONE_IMAGE)_LAZY_INSTALLS += $(CEL_MIDSTONE_200I_PLATFORM_MODULE) $(SONIC_ONE_IMAGE)_LAZY_INSTALLS += $(DELTA_PLATFORM_MODULE) $(SONIC_ONE_IMAGE)_LAZY_INSTALLS += $(NETBERG_AURORA_715_PLATFORM_MODULE) $(SONIC_ONE_IMAGE)_LAZY_INSTALLS += $(WISTRON_PLATFORM_MODULE) -$(SONIC_ONE_IMAGE)_INSTALLS += $(INVM_DRV) $(INVM_SERDES_PLATFORM_LIBRARY) +$(SONIC_ONE_IMAGE)_INSTALLS += $(INVM_DRV) $(SONIC_ONE_IMAGE)_DOCKERS += $(SONIC_INSTALL_DOCKER_IMAGES) SONIC_INSTALLERS += $(SONIC_ONE_IMAGE) From 5510d9c03b6f2b1b07198f3c421ab4ce7bf5a0ef Mon Sep 17 00:00:00 2001 From: Ye Jianquan Date: Fri, 30 Sep 2022 08:17:01 +0800 Subject: [PATCH 139/151] Make t0 part1 and part2 be able to be rerun if failed (#12221) Why I did it With continueOnError: true, a failed job returns the result: partiallySuccess, which cause it can't be rerun, since AZP consider it as passed. Then we can't only rerun t0 jobs when it fails. How I did it Mark t0 part1 and part2 as continueOnError: false. How to verify it The pipeline will verify it. --- azure-pipelines.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/azure-pipelines.yml b/azure-pipelines.yml index 7856915f9b60..26a86dffa01e 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -137,7 +137,7 @@ stages: pool: sonictest displayName: "kvmtest-t0-part1" timeoutInMinutes: 360 - continueOnError: true + continueOnError: false steps: - template: .azure-pipelines/run-test-template.yml parameters: @@ -151,7 +151,7 @@ stages: pool: sonictest displayName: "kvmtest-t0-part2" timeoutInMinutes: 360 - continueOnError: true + continueOnError: false steps: - template: .azure-pipelines/run-test-template.yml parameters: From 1d69f0916eccc3961cdaa2c680141f57207396a1 Mon Sep 17 00:00:00 2001 From: Junchao-Mellanox <57339448+Junchao-Mellanox@users.noreply.github.com> Date: Fri, 30 Sep 2022 14:38:05 +0800 Subject: [PATCH 140/151] [Mellanox] Provide dummy implementation for get_rx_los and get_tx_fault (#12231) - Why I did it get_rx_los and get_tx_fault is not supported via the exisitng interface used, need provide dummy implementation for them. NOTE: in later releases we will get them back via different interface. - How I did it Return False * lane_num for get_rx_los and get_tx_fault - How to verify it Added unit test --- .../mlnx-platform-api/sonic_platform/sfp.py | 32 +++++++++++++++++++ .../mlnx-platform-api/tests/test_sfp.py | 14 ++++++++ 2 files changed, 46 insertions(+) diff --git a/platform/mellanox/mlnx-platform-api/sonic_platform/sfp.py b/platform/mellanox/mlnx-platform-api/sonic_platform/sfp.py index 617b4f33d636..d35b869e9a29 100644 --- a/platform/mellanox/mlnx-platform-api/sonic_platform/sfp.py +++ b/platform/mellanox/mlnx-platform-api/sonic_platform/sfp.py @@ -755,6 +755,38 @@ def get_error_description(self): error_description = "Unknow SFP module status ({})".format(oper_status) return error_description + def get_rx_los(self): + """Accessing rx los is not supproted, return all False + + Returns: + list: [False] * channels + """ + api = self.get_xcvr_api() + return [False] * api.NUM_CHANNELS if api else None + + def get_tx_fault(self): + """Accessing tx fault is not supproted, return all False + + Returns: + list: [False] * channels + """ + api = self.get_xcvr_api() + return [False] * api.NUM_CHANNELS if api else None + + def get_xcvr_api(self): + """ + Retrieves the XcvrApi associated with this SFP + + Returns: + An object derived from XcvrApi that corresponds to the SFP + """ + if self._xcvr_api is None: + self.refresh_xcvr_api() + if self._xcvr_api is not None: + self._xcvr_api.get_rx_los = self.get_rx_los + self._xcvr_api.get_tx_fault = self.get_tx_fault + return self._xcvr_api + class RJ45Port(NvidiaSFPCommon): """class derived from SFP, representing RJ45 ports""" diff --git a/platform/mellanox/mlnx-platform-api/tests/test_sfp.py b/platform/mellanox/mlnx-platform-api/tests/test_sfp.py index f599e0241d25..b72a5f3ed4aa 100644 --- a/platform/mellanox/mlnx-platform-api/tests/test_sfp.py +++ b/platform/mellanox/mlnx-platform-api/tests/test_sfp.py @@ -119,3 +119,17 @@ def test_is_port_admin_status_up(self, mock_port_status): mock_port_status.return_value = (0, False) assert not SFP.is_port_admin_status_up(None, None) + + @mock.patch('sonic_platform.sfp.SFP.get_xcvr_api') + def test_dummy_apis(self, mock_get_xcvr_api): + mock_api = mock.MagicMock() + mock_api.NUM_CHANNELS = 4 + mock_get_xcvr_api.return_value = mock_api + + sfp = SFP(0) + assert sfp.get_rx_los() == [False] * 4 + assert sfp.get_tx_fault() == [False] * 4 + + mock_get_xcvr_api.return_value = None + assert sfp.get_rx_los() is None + assert sfp.get_tx_fault() is None From 92bd6dae281977c93bbf39e4456a62857a485dfb Mon Sep 17 00:00:00 2001 From: Volodymyr Samotiy Date: Fri, 30 Sep 2022 09:40:12 +0300 Subject: [PATCH 141/151] [Mellanox] Update SAI to v2205.22.1.19 and SDK/FW to v4.5.3168/v2010.3170 (#12205) - Why I did it To include latest fixes and new functionality SAI fixes and new features fix #3205239, incorrect object type returned for SG child list Fix VRF-VNI map entries remove issue ECC health event and logging [Port Buffers] restore default queue and pg configuration when all user pools are deleted Fix EVPN type3 error on removal of uc/bc flood group Fix EVPN type2 MAC move from local to remote results in SAI failure Fix Disable learning on VXLAN tunnel Fix error on VXLAN v6 tunnel removal Fix port cannot apply schedule group when it is a lag member Fix BFD add more detailed message on BFD packet not related to any existing session gcc10 compilation fixes Disable learning on VXLAN tunnel Support BFD remote-disc exchange in negotiation stage Tunnel Loopback packet action attribute implementation (for Dual TOR) Add KVD resources MIN/MAX functionality (pending CRM issue with MIN only) Support for CRC2 hash algorithm Bulk counter support for PGs, queues Support mirror sample rate attribute (SPC2+) [Functional] [QoS] | Unable to remove SCHEDULE profile table even if there is no object referencing it Next hop group optimized bulk API Reduce verbosity of shared database already exists print Span mirror policer (SPC2+), optimize pipeline for acl mirror action with policer on SPC2+ use same size descriptor pool for rx/tx fix bfd - notify Sonic for admin-down event 2201 - empty list for supported fec for RJ45 ports Fix don't disable used tunnel underlay interfaces SDK fixes 100GbE FCI DAC (10137628-4050LF/HPE PN: 845408-B21) was recognized by mistake as supporting "cable burning' which caused the switch firmware to read page 0x9f (which unsupported in the cable) and to report this cable as having "bad eeprom". Added remote peer UDP port information in BFD packet event. After editing an ECMP, the resilient ECMP next-hop counter may not count correctly. Fixed potential memory leaks in some APIs related to LPM If TTL_CMD_COPY is used in Encap direction for a packet with no TTL, then the value passed in the ttl data structure will be used if non-zero (default 255 if zero). In SN2201: When configuring Force mode, user should configure Speed and FEC on both sides In Flex Tunnel encapsulation flow, if the encapsulation is with an IPv6 header, the flow label field may not be updated as expected. In some cases, when changing speed to 400GbE over 8 lanes, the first few packets would be dropped. In some traffic patterns involving small packets, the PortRcvErrors counter may mistakenly count events of local physical errors due to an internal flow in the hardware that involves link packets. On Spectrum systems, sometimes during link failure, not all previous firmware indications cleared properly, potentially affecting the next link up attempt. On the NVIDIA Spectrum-2 switch, when receiving a packet with Symbol Errors on ports that are configured to cut-thought mode, a pipeline might get stuck. PCI calibration changes from a static to a dynamic mechanism. SDK debug dump shows "Unknown" Counter in RFC3635 Counter Group. SDK debug dump shows "Unknown" Counter in the PPCNT Traffic Class Counter Group. SDK Dump missing column headers in some GC tables may result in difficulty understanding the dump. SLL configuration is missing in SDK dump. Spectrum-2 systems, do no support 1GbE on supported 40GbE modules. When binding a UDP port which is already in use for BFD TX session, the error message appears incorrectly. When Flex Tunnel was used, Flex Modifier sometimes experienced a brief mis-configuration during ISSU. When many ports are active (e.g. 70 ports up), and the configuration of shared buffer is applied on the fly, occasionally, the firmware might get stuck. When running 1GbE speeds on SN4600 system, the port remained active while peer side was closed. When toggling many ports of the Spectrum devices while raising 10GbE link up and link maintenance is enabled, the switch may get stuck and may need to be rebooted. When trying to reconfigure the Flex Parser header and Flex transition parameters after ISSU, the switch will returned an error even if the configuration was identical to that done before performing the ISSU. While toggling the cable, and the low power mode is set to ON, an unexpected PMPE event error is received. - How I did it Updated SDK/SAI submodule and relevant makefiles with the required versions. - How to verify it Build an image and run tests from "sonic-mgmt". Signed-off-by: Volodymyr Samotiy --- platform/mellanox/fw.mk | 6 +++--- platform/mellanox/mlnx-sai.mk | 2 +- platform/mellanox/mlnx-sai/SAI-Implementation | 2 +- platform/mellanox/sdk-src/sx-kernel/Switch-SDK-drivers | 2 +- platform/mellanox/sdk.mk | 2 +- 5 files changed, 7 insertions(+), 7 deletions(-) diff --git a/platform/mellanox/fw.mk b/platform/mellanox/fw.mk index 962ea0ae31e1..92aed0663311 100644 --- a/platform/mellanox/fw.mk +++ b/platform/mellanox/fw.mk @@ -27,17 +27,17 @@ else FW_FROM_URL = n endif -MLNX_SPC_FW_VERSION = 13.2010.2320 +MLNX_SPC_FW_VERSION = 13.2010.3170 MLNX_SPC_FW_FILE = fw-SPC-rel-$(subst .,_,$(MLNX_SPC_FW_VERSION))-EVB.mfa $(MLNX_SPC_FW_FILE)_PATH = $(MLNX_FW_BASE_PATH) $(MLNX_SPC_FW_FILE)_URL = $(MLNX_FW_BASE_URL)/$(MLNX_SPC_FW_FILE) -MLNX_SPC2_FW_VERSION = 29.2010.2320 +MLNX_SPC2_FW_VERSION = 29.2010.3170 MLNX_SPC2_FW_FILE = fw-SPC2-rel-$(subst .,_,$(MLNX_SPC2_FW_VERSION))-EVB.mfa $(MLNX_SPC2_FW_FILE)_PATH = $(MLNX_FW_BASE_PATH) $(MLNX_SPC2_FW_FILE)_URL = $(MLNX_FW_BASE_URL)/$(MLNX_SPC2_FW_FILE) -MLNX_SPC3_FW_VERSION = 30.2010.2320 +MLNX_SPC3_FW_VERSION = 30.2010.3170 MLNX_SPC3_FW_FILE = fw-SPC3-rel-$(subst .,_,$(MLNX_SPC3_FW_VERSION))-EVB.mfa $(MLNX_SPC3_FW_FILE)_PATH = $(MLNX_FW_BASE_PATH) $(MLNX_SPC3_FW_FILE)_URL = $(MLNX_FW_BASE_URL)/$(MLNX_SPC3_FW_FILE) diff --git a/platform/mellanox/mlnx-sai.mk b/platform/mellanox/mlnx-sai.mk index 6eaa1dcf80b4..90ca7430b0ad 100644 --- a/platform/mellanox/mlnx-sai.mk +++ b/platform/mellanox/mlnx-sai.mk @@ -1,6 +1,6 @@ # Mellanox SAI -MLNX_SAI_VERSION = SAIRel1.21.2.0 +MLNX_SAI_VERSION = SAIBuild2205.22.1.19 export MLNX_SAI_VERSION diff --git a/platform/mellanox/mlnx-sai/SAI-Implementation b/platform/mellanox/mlnx-sai/SAI-Implementation index f9a21df71363..82274ffaef77 160000 --- a/platform/mellanox/mlnx-sai/SAI-Implementation +++ b/platform/mellanox/mlnx-sai/SAI-Implementation @@ -1 +1 @@ -Subproject commit f9a21df713636fe648b8bb190698e4494a0f5239 +Subproject commit 82274ffaef7748120b7657362f7875fb7d6e6f5f diff --git a/platform/mellanox/sdk-src/sx-kernel/Switch-SDK-drivers b/platform/mellanox/sdk-src/sx-kernel/Switch-SDK-drivers index 5650c3519b55..8b1f1c0f1164 160000 --- a/platform/mellanox/sdk-src/sx-kernel/Switch-SDK-drivers +++ b/platform/mellanox/sdk-src/sx-kernel/Switch-SDK-drivers @@ -1 +1 @@ -Subproject commit 5650c3519b55051124810a4625f8269694b1e592 +Subproject commit 8b1f1c0f11647749f79ebc4e823c157513067412 diff --git a/platform/mellanox/sdk.mk b/platform/mellanox/sdk.mk index b620b07ee2f8..5a6864bc1e4a 100644 --- a/platform/mellanox/sdk.mk +++ b/platform/mellanox/sdk.mk @@ -16,7 +16,7 @@ # MLNX_SDK_BASE_PATH = $(PLATFORM_PATH)/sdk-src/sx-kernel/Switch-SDK-drivers/bin/ MLNX_SDK_PKG_BASE_PATH = $(MLNX_SDK_BASE_PATH)/$(BLDENV)/$(CONFIGURED_ARCH)/ -MLNX_SDK_VERSION = 4.5.2320 +MLNX_SDK_VERSION = 4.5.3168 MLNX_SDK_ISSU_VERSION = 101 MLNX_SDK_DEB_VERSION = $(subst -,.,$(subst _,.,$(MLNX_SDK_VERSION))) From eea8ebd0a9ee977765097666d1d89961a466d891 Mon Sep 17 00:00:00 2001 From: Volodymyr Samotiy Date: Fri, 30 Sep 2022 09:48:40 +0300 Subject: [PATCH 142/151] [Mellanox] Update MFT to v4.21.0-100 (#11758) - Why I did it To update MFT package to the latest version. - How I did it Updated MFT_VERSION & MFT_REVISION in platform/mellanox/mft.mk. - How to verify it Build an image and deploy to the switch Check MFT version by dpkg -l | grep mft Verify that all the SONiC services up and running Run regression testing using tests from sonic-mgmt Signed-off-by: Volodymyr Samotiy --- platform/mellanox/mft.mk | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/platform/mellanox/mft.mk b/platform/mellanox/mft.mk index eb702a85a1d1..047e87b09086 100644 --- a/platform/mellanox/mft.mk +++ b/platform/mellanox/mft.mk @@ -16,8 +16,8 @@ # # Mellanox SAI -MFT_VERSION = 4.20.0 -MFT_REVISION = 34 +MFT_VERSION = 4.21.0 +MFT_REVISION = 100 export MFT_VERSION MFT_REVISION From 004a8b6eae203cb1496beb8b192b087cc2a32a66 Mon Sep 17 00:00:00 2001 From: Hua Liu <58683130+liuh-80@users.noreply.github.com> Date: Fri, 30 Sep 2022 15:56:46 +0800 Subject: [PATCH 143/151] [AzurePipeline] Fix vstest step failed by libyang missing. (#12240) Why I did it Fix PR merge failed because 'vstest' step does not install libyang. How I did it Install libyang in azure pipeline. How to verify it Pass vstest step. --- azure-pipelines.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/azure-pipelines.yml b/azure-pipelines.yml index 26a86dffa01e..a9004af559ef 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -113,6 +113,8 @@ stages: - script: | set -x + sudo apt-get update + sudo apt-get install libyang0.16 -y sudo dpkg -i --force-confask,confnew ../libswsscommon_1.0.0_amd64.deb sudo dpkg -i ../python3-swsscommon_1.0.0_amd64.deb sudo docker load -i ../target/docker-sonic-vs.gz From 18850e4e28bb5d536abc9c455138c57aad69811d Mon Sep 17 00:00:00 2001 From: Samuel Angebault Date: Fri, 30 Sep 2022 10:03:40 +0200 Subject: [PATCH 144/151] [Arista] Update platform submodules (#12225) Implement input power psu API Report DC power output via API Add bootloader Component in API Fix issue where naming was not unique for Component --- platform/barefoot/sonic-platform-modules-arista | 2 +- platform/broadcom/sonic-platform-modules-arista | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/platform/barefoot/sonic-platform-modules-arista b/platform/barefoot/sonic-platform-modules-arista index e12a04b24c5f..11180c37fa17 160000 --- a/platform/barefoot/sonic-platform-modules-arista +++ b/platform/barefoot/sonic-platform-modules-arista @@ -1 +1 @@ -Subproject commit e12a04b24c5f752a9ca789d62bb7b94c563e1c4b +Subproject commit 11180c37fa17421afdeef346b3896552872a2721 diff --git a/platform/broadcom/sonic-platform-modules-arista b/platform/broadcom/sonic-platform-modules-arista index e12a04b24c5f..11180c37fa17 160000 --- a/platform/broadcom/sonic-platform-modules-arista +++ b/platform/broadcom/sonic-platform-modules-arista @@ -1 +1 @@ -Subproject commit e12a04b24c5f752a9ca789d62bb7b94c563e1c4b +Subproject commit 11180c37fa17421afdeef346b3896552872a2721 From 0a2743d5e472d25209a846e49f032998ee093261 Mon Sep 17 00:00:00 2001 From: jingwenxie Date: Sat, 1 Oct 2022 11:36:55 -0700 Subject: [PATCH 145/151] [submodule] update sonic-utilities (#12138) 0a7557bd9 [minigraph] add option to specify golden path in load_minigraph (#2350) 322aefc37 [GCU]Remove GCU unique lane check for duplicate lanes platforms (#2343) 7099fffa7 [fastboot] fastboot enhancement: Use warm-boot infrastructure for fast-boot (#2286) 09026edbb [warm-reboot] fix warm-reboot when /tmp/cache is missing (#2367) a3c404c74 Fix typo in platform_sfputil_helper.is_rj45_port (#2374) 637d834ce Vnet_route_check Vxlan tunnel route update. (#2281) 29a3e5180 Added support for tunnel route status in show vnet routes all. (#2341) 1ac584bb3 Use 'default' VRF when VRF name is not provided (#2368) 4d377a620 [subinterface]Added additional checks in portchannel and subinterface commands (#2345) bbcdf2ed7 disk_check: Publish event for RO state (#2320) 3fd537b0a Support the bandit check by GitHub Action (#2358) 491d3d380 [generate dump]Added error message when saisdkdump fails (#2356) 6830e01ec [counterpoll]Fixing counterpoll show for tunnel and acl stats (#2355) 3be2ad7de [fast-reboot]Avoid stopping masked services during fast-reboot (#2335) 0e1b0cf20 [GCU] Fix missing backend in dry run (#2347) 676c31bd0 Add verification for override (#2305) 48997c266 Add Password Hardening CLI support (#2338) 414e239ea update unit tests for swap allocator a91a4922f consider swap checking memory in installer f0ce58635 [route_check]: Ignore standalone tunnel routes (#2325) --- src/sonic-utilities | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sonic-utilities b/src/sonic-utilities index 3af8ba4acc2b..0a7557bd9162 160000 --- a/src/sonic-utilities +++ b/src/sonic-utilities @@ -1 +1 @@ -Subproject commit 3af8ba4acc2bbc77d17be0d67943703021c7d1e1 +Subproject commit 0a7557bd9162eae40f5d4c4f6fbab92dbad7204b From 8c10851c2aebb44099611248f91da350b16df1dc Mon Sep 17 00:00:00 2001 From: Muhammad Danish <88161975+mdanish-kh@users.noreply.github.com> Date: Sun, 2 Oct 2022 11:02:10 +0500 Subject: [PATCH 146/151] Update azure.github.io links to sonic-net.github.io (#12209) Why I did it azure.github.io/SONiC/ no longer works and returns 404 Not Found. Updated it to the correct sonic-net.github.io/SONiC/ --- files/image_config/environment/motd | 2 +- platform/vs/sonic-gns3a.sh | 4 ++-- src/sonic-device-data/README.md | 2 +- src/sonic-host-services-data/README.md | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/files/image_config/environment/motd b/files/image_config/environment/motd index 8562e330fe2c..0d857e5c5f94 100644 --- a/files/image_config/environment/motd +++ b/files/image_config/environment/motd @@ -10,5 +10,5 @@ You are on Unauthorized access and/or use are prohibited. All access and/or use are subject to monitoring. -Help: http://azure.github.io/SONiC/ +Help: https://sonic-net.github.io/SONiC/ diff --git a/platform/vs/sonic-gns3a.sh b/platform/vs/sonic-gns3a.sh index 41e39cd8686a..2a772ce5a332 100644 --- a/platform/vs/sonic-gns3a.sh +++ b/platform/vs/sonic-gns3a.sh @@ -41,9 +41,9 @@ echo " \"category\": \"router\", \"description\": \"SONiC Virtual Switch/Router\", \"vendor_name\": \"SONiC\", - \"vendor_url\": \"https://azure.github.io/SONiC/\", + \"vendor_url\": \"https://sonic-net.github.io/SONiC/\", \"product_name\": \"SONiC\", - \"product_url\": \"https://azure.github.io/SONiC/\", + \"product_url\": \"https://sonic-net.github.io/SONiC/\", \"registry_version\": 3, \"status\": \"experimental\", \"maintainer\": \"SONiC\", diff --git a/src/sonic-device-data/README.md b/src/sonic-device-data/README.md index e8ccad58b819..d9d403758a86 100644 --- a/src/sonic-device-data/README.md +++ b/src/sonic-device-data/README.md @@ -1,4 +1,4 @@ # sonic-device-data Device-specific data for the SONiC project -See the [SONiC Website](http://azure.github.io/SONiC/) for more information about the SONiC project. +See the [SONiC Website](https://sonic-net.github.io/SONiC/) for more information about the SONiC project. diff --git a/src/sonic-host-services-data/README.md b/src/sonic-host-services-data/README.md index 93af66a83d6b..0b9e714932d2 100644 --- a/src/sonic-host-services-data/README.md +++ b/src/sonic-host-services-data/README.md @@ -16,4 +16,4 @@ dpkg-buildpackage -rfakeroot -Tclean --- -See the [SONiC Website](http://azure.github.io/SONiC/) for more information about the SONiC project. +See the [SONiC Website](https://sonic-net.github.io/SONiC/) for more information about the SONiC project. From 44356fa8d758fffd6e023ebfb7e1c8646a81ede1 Mon Sep 17 00:00:00 2001 From: Dror Prital <76714716+dprital@users.noreply.github.com> Date: Sun, 2 Oct 2022 11:34:24 +0300 Subject: [PATCH 147/151] [Mellanox] Add NVIDIA copyright header for NVIDIA added files (#12130) - Why I did it Add NVIDIA Copyright header for new "NVIDIA" files - How I did it Add the copyright header as remark at the head of the file --- .../ACS-MSN2700/buffers_defaults_objects.j2 | 17 +++++++++++++++++ .../buffers_defaults_objects.j2 | 17 +++++++++++++++++ .../Mellanox-SN4700-C128/port_config.ini | 17 +++++++++++++++++ .../Mellanox-SN4700-C128/sai_4700_128x100g.xml | 17 +++++++++++++++++ .../tests/input_platform/__init__.py | 16 ++++++++++++++++ .../tests/input_platform/output_sfp.py | 17 +++++++++++++++++ platform/mellanox/zero_profiles.j2 | 17 +++++++++++++++++ 7 files changed, 118 insertions(+) diff --git a/device/mellanox/x86_64-mlnx_msn2700-r0/ACS-MSN2700/buffers_defaults_objects.j2 b/device/mellanox/x86_64-mlnx_msn2700-r0/ACS-MSN2700/buffers_defaults_objects.j2 index 29a3c74e5233..e8edeca556d1 100644 --- a/device/mellanox/x86_64-mlnx_msn2700-r0/ACS-MSN2700/buffers_defaults_objects.j2 +++ b/device/mellanox/x86_64-mlnx_msn2700-r0/ACS-MSN2700/buffers_defaults_objects.j2 @@ -1,3 +1,20 @@ +{# + Copyright (c) 2022 NVIDIA CORPORATION & AFFILIATES. + Apache-2.0 + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +#} + {%- macro generate_buffer_pool_and_profiles_with_inactive_ports(port_names_inactive) %} "BUFFER_POOL": { {% if dynamic_mode is not defined and port_names_inactive|length > 0 -%} diff --git a/device/mellanox/x86_64-mlnx_msn2700-r0/Mellanox-SN2700-D48C8/buffers_defaults_objects.j2 b/device/mellanox/x86_64-mlnx_msn2700-r0/Mellanox-SN2700-D48C8/buffers_defaults_objects.j2 index f0b0e3993bd4..6bf657d1fb7b 100644 --- a/device/mellanox/x86_64-mlnx_msn2700-r0/Mellanox-SN2700-D48C8/buffers_defaults_objects.j2 +++ b/device/mellanox/x86_64-mlnx_msn2700-r0/Mellanox-SN2700-D48C8/buffers_defaults_objects.j2 @@ -1,3 +1,20 @@ +{# + Copyright (c) 2022 NVIDIA CORPORATION & AFFILIATES. + Apache-2.0 + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +#} + {%- macro generate_buffer_pool_and_profiles_with_inactive_ports(port_names_inactive) %} "BUFFER_POOL": { {% if dynamic_mode is not defined and port_names_inactive|length > 0 -%} diff --git a/device/mellanox/x86_64-mlnx_msn4700-r0/Mellanox-SN4700-C128/port_config.ini b/device/mellanox/x86_64-mlnx_msn4700-r0/Mellanox-SN4700-C128/port_config.ini index d64b66b0b691..0d67f9b366fc 100644 --- a/device/mellanox/x86_64-mlnx_msn4700-r0/Mellanox-SN4700-C128/port_config.ini +++ b/device/mellanox/x86_64-mlnx_msn4700-r0/Mellanox-SN4700-C128/port_config.ini @@ -1,3 +1,20 @@ +## +## Copyright (c) 2022 NVIDIA CORPORATION & AFFILIATES. +## Apache-2.0 +## +## Licensed under the Apache License, Version 2.0 (the "License"); +## you may not use this file except in compliance with the License. +## You may obtain a copy of the License at +## +## http://www.apache.org/licenses/LICENSE-2.0 +## +## Unless required by applicable law or agreed to in writing, software +## distributed under the License is distributed on an "AS IS" BASIS, +## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +## See the License for the specific language governing permissions and +## limitations under the License. +## + # name lanes alias index speed Ethernet0 0,1 etp1a 1 100000 Ethernet2 2,3 etp1b 1 100000 diff --git a/device/mellanox/x86_64-mlnx_msn4700-r0/Mellanox-SN4700-C128/sai_4700_128x100g.xml b/device/mellanox/x86_64-mlnx_msn4700-r0/Mellanox-SN4700-C128/sai_4700_128x100g.xml index f5d49f8b86ab..2575b49f3fa0 100644 --- a/device/mellanox/x86_64-mlnx_msn4700-r0/Mellanox-SN4700-C128/sai_4700_128x100g.xml +++ b/device/mellanox/x86_64-mlnx_msn4700-r0/Mellanox-SN4700-C128/sai_4700_128x100g.xml @@ -1,3 +1,20 @@ + + diff --git a/platform/mellanox/mlnx-platform-api/tests/input_platform/__init__.py b/platform/mellanox/mlnx-platform-api/tests/input_platform/__init__.py index e69de29bb2d1..07ebf17a113e 100644 --- a/platform/mellanox/mlnx-platform-api/tests/input_platform/__init__.py +++ b/platform/mellanox/mlnx-platform-api/tests/input_platform/__init__.py @@ -0,0 +1,16 @@ +# +# Copyright (c) 2017-2022 NVIDIA CORPORATION & AFFILIATES. +# Apache-2.0 +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# diff --git a/platform/mellanox/mlnx-platform-api/tests/input_platform/output_sfp.py b/platform/mellanox/mlnx-platform-api/tests/input_platform/output_sfp.py index 20a09d1b54f6..170b0246430f 100644 --- a/platform/mellanox/mlnx-platform-api/tests/input_platform/output_sfp.py +++ b/platform/mellanox/mlnx-platform-api/tests/input_platform/output_sfp.py @@ -1,3 +1,20 @@ +# +# Copyright (c) 2022 NVIDIA CORPORATION & AFFILIATES. +# Apache-2.0 +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + """ module holding the correct values for the sfp_test.py """ diff --git a/platform/mellanox/zero_profiles.j2 b/platform/mellanox/zero_profiles.j2 index a953c18409b2..007f19c83a0a 100644 --- a/platform/mellanox/zero_profiles.j2 +++ b/platform/mellanox/zero_profiles.j2 @@ -1,3 +1,20 @@ +{# + Copyright (c) 2021-2022 NVIDIA CORPORATION & AFFILIATES. + Apache-2.0 + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +#} + [ { "BUFFER_POOL_TABLE:ingress_zero_pool": { From 2f46689a059d3d7146b8ab27a0293e4b42383ec7 Mon Sep 17 00:00:00 2001 From: andywongarista <78833093+andywongarista@users.noreply.github.com> Date: Sun, 2 Oct 2022 22:53:34 -0700 Subject: [PATCH 148/151] [Arista] Add components for 720DT-48S (#12217) Why I did it Add components data for sonic-mgmt testing How I did it Update platform.json and add platform_components.json How to verify it Ran sonic-mgmt tests (test_chassis and test_component) --- device/arista/x86_64-arista_720dt_48s/platform.json | 9 ++++++++- .../x86_64-arista_720dt_48s/platform_components.json | 10 ++++++++++ 2 files changed, 18 insertions(+), 1 deletion(-) create mode 100644 device/arista/x86_64-arista_720dt_48s/platform_components.json diff --git a/device/arista/x86_64-arista_720dt_48s/platform.json b/device/arista/x86_64-arista_720dt_48s/platform.json index ce405b82f955..c560f8d739f1 100644 --- a/device/arista/x86_64-arista_720dt_48s/platform.json +++ b/device/arista/x86_64-arista_720dt_48s/platform.json @@ -1,7 +1,14 @@ { "chassis": { "name": "CCS-720DT-48S", - "components": [], + "components": [ + { + "name": "Aboot()" + }, + { + "name": "Scd(addr=0000:00:18.7)" + } + ], "fan_drawers": [ { "name": "fixed1", diff --git a/device/arista/x86_64-arista_720dt_48s/platform_components.json b/device/arista/x86_64-arista_720dt_48s/platform_components.json new file mode 100644 index 000000000000..ea8bbb5e3346 --- /dev/null +++ b/device/arista/x86_64-arista_720dt_48s/platform_components.json @@ -0,0 +1,10 @@ +{ + "chassis": { + "CCS-720DT-48S": { + "component": { + "Aboot()": {}, + "Scd(addr=0000:00:18.7)": {} + } + } + } +} From 95f4af3407d32cdec98a3d0d487ab0997ef5ff3c Mon Sep 17 00:00:00 2001 From: Mai Bui Date: Mon, 3 Oct 2022 11:38:55 -0700 Subject: [PATCH 149/151] [actions] Support Semgrep by Github Actions (#12249) Signed-off-by: maipbui #### Why I did it [Semgrep](https://github.com/returntocorp/semgrep) is a static analysis tool to find security vulnerabilities. When opening a PR or commtting to PR, Semgrep performs a diff-aware scanning, which scans changed files in PRs. When merging PR, Semgrep performs a full scan on master branch and report all findings. Ref: - [Supported Language](https://semgrep.dev/docs/supported-languages/#language-maturity) - [Semgrep Rules](https://registry.semgrep.dev/rule) #### How I did it Integrate Semgrep into this repository by committing a job configuration file #### How to verify it PR: https://github.com/maipbui/sonic-buildimage/pull/2 Master branch full scan findings: [Master branch findings results](https://github.com/maipbui/sonic-buildimage/actions/runs/3160181876/jobs/5144332404) PR https://github.com/maipbui/sonic-buildimage/pull/2 scan findings: [Pull request findings results](https://github.com/maipbui/sonic-buildimage/actions/runs/3160193505/jobs/5144357859) --- .github/workflows/semgrep.yml | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) create mode 100644 .github/workflows/semgrep.yml diff --git a/.github/workflows/semgrep.yml b/.github/workflows/semgrep.yml new file mode 100644 index 000000000000..8ebe082f50a4 --- /dev/null +++ b/.github/workflows/semgrep.yml @@ -0,0 +1,21 @@ +name: Semgrep + +on: + pull_request: {} + push: + branches: + - master + - '201[7-9][0-1][0-9]' + - '202[0-9][0-1][0-9]' + +jobs: + semgrep: + name: Semgrep + runs-on: ubuntu-latest + container: + image: returntocorp/semgrep + steps: + - uses: actions/checkout@v3 + - run: semgrep ci + env: + SEMGREP_RULES: p/default From c691b739591b9b5bcd0c1ba338d04aa64aa60549 Mon Sep 17 00:00:00 2001 From: Kalimuthu-Velappan <53821802+Kalimuthu-Velappan@users.noreply.github.com> Date: Wed, 5 Oct 2022 02:43:40 +0530 Subject: [PATCH 150/151] 01.Version-cache - restructuring of Makefile.work (#12000) - The Makefile.work becomes complex and it is very difficult to manage the changes across branches. - Restructured the Makefile.work and it becomes more readable. - Added $(QUIET) option to turn on command echo mode through command line option. - Exported the SONIC_BUILD_VARS variable, through which make options can be set dynamically. Eg: make SONIC_BUILD_VARS='INCLUDE_NAT=y' --- Makefile | 34 +++++--- Makefile.work | 213 +++++++++++++++++++++++++++++++++----------------- slave.mk | 66 ++++++++-------- 3 files changed, 196 insertions(+), 117 deletions(-) diff --git a/Makefile b/Makefile index af3d7086ec8e..ccfefc6c183c 100644 --- a/Makefile +++ b/Makefile @@ -5,6 +5,14 @@ NOSTRETCH ?= 0 NOBUSTER ?= 0 NOBULLSEYE ?= 0 +override Q := @ +ifeq ($(QUIET),n) + override Q := +endif +override SONIC_OVERRIDE_BUILD_VARS += $(SONIC_BUILD_VARS) +override SONIC_OVERRIDE_BUILD_VARS += Q=$(Q) +export Q SONIC_OVERRIDE_BUILD_VARS + ifeq ($(NOJESSIE),0) BUILD_JESSIE=1 endif @@ -29,50 +37,50 @@ PLATFORM_CHECKOUT_CMD := $(shell if [ -f $(PLATFORM_CHECKOUT_FILE) ]; then PLATF %:: @echo "+++ --- Making $@ --- +++" ifeq ($(NOJESSIE), 0) - EXTRA_DOCKER_TARGETS=$(notdir $@) make -f Makefile.work jessie + EXTRA_DOCKER_TARGETS=$(notdir $@) $(MAKE) -f Makefile.work jessie endif ifeq ($(NOSTRETCH), 0) - EXTRA_DOCKER_TARGETS=$(notdir $@) BLDENV=stretch make -f Makefile.work stretch + EXTRA_DOCKER_TARGETS=$(notdir $@) BLDENV=stretch $(MAKE) -f Makefile.work stretch endif ifeq ($(NOBUSTER), 0) - EXTRA_DOCKER_TARGETS=$(notdir $@) BLDENV=buster make -f Makefile.work buster + EXTRA_DOCKER_TARGETS=$(notdir $@) BLDENV=buster $(MAKE) -f Makefile.work buster endif ifeq ($(NOBULLSEYE), 0) - BLDENV=bullseye make -f Makefile.work $@ + BLDENV=bullseye $(MAKE) -f Makefile.work $@ endif - BLDENV=bullseye make -f Makefile.work docker-cleanup + BLDENV=bullseye $(MAKE) -f Makefile.work docker-cleanup jessie: @echo "+++ Making $@ +++" ifeq ($(NOJESSIE), 0) - make -f Makefile.work jessie + $(MAKE) -f Makefile.work jessie endif stretch: @echo "+++ Making $@ +++" ifeq ($(NOSTRETCH), 0) - make -f Makefile.work stretch + $(MAKE) -f Makefile.work stretch endif buster: @echo "+++ Making $@ +++" ifeq ($(NOBUSTER), 0) - make -f Makefile.work buster + $(MAKE) -f Makefile.work buster endif init: @echo "+++ Making $@ +++" - make -f Makefile.work $@ + $(MAKE) -f Makefile.work $@ # # Function to invoke target $@ in Makefile.work with proper BLDENV # define make_work @echo "+++ Making $@ +++" - $(if $(BUILD_JESSIE),make -f Makefile.work $@,) - $(if $(BUILD_STRETCH),BLDENV=stretch make -f Makefile.work $@,) - $(if $(BUILD_BUSTER),BLDENV=buster make -f Makefile.work $@,) - $(if $(BUILD_BULLSEYE),BLDENV=bullseye make -f Makefile.work $@,) + $(if $(BUILD_JESSIE),$(MAKE) -f Makefile.work $@,) + $(if $(BUILD_STRETCH),BLDENV=stretch $(MAKE) -f Makefile.work $@,) + $(if $(BUILD_BUSTER),BLDENV=buster $(MAKE) -f Makefile.work $@,) + $(if $(BUILD_BULLSEYE),BLDENV=bullseye $(MAKE) -f Makefile.work $@,) endef .PHONY: $(PLATFORM_PATH) diff --git a/Makefile.work b/Makefile.work index 6171a05c5192..a6cacafce834 100644 --- a/Makefile.work +++ b/Makefile.work @@ -124,7 +124,7 @@ endif # Define a do-nothing target for rules/config.user so that when # the file is missing, make won't try to rebuld everything. rules/config.user: - @echo -n "" + $(Q)echo -n "" include rules/config -include rules/config.user @@ -173,21 +173,59 @@ endif endif # Generate the version control build info -$(shell SONIC_VERSION_CONTROL_COMPONENTS=$(SONIC_VERSION_CONTROL_COMPONENTS) \ - TRUSTED_GPG_URLS=$(TRUSTED_GPG_URLS) PACKAGE_URL_PREFIX=$(PACKAGE_URL_PREFIX) \ - scripts/generate_buildinfo_config.sh) +$(shell \ + SONIC_VERSION_CONTROL_COMPONENTS=$(SONIC_VERSION_CONTROL_COMPONENTS) \ + TRUSTED_GPG_URLS=$(TRUSTED_GPG_URLS) \ + PACKAGE_URL_PREFIX=$(PACKAGE_URL_PREFIX) \ + scripts/generate_buildinfo_config.sh) # Generate the slave Dockerfile, and prepare build info for it -$(shell CONFIGURED_ARCH=$(CONFIGURED_ARCH) MULTIARCH_QEMU_ENVIRON=$(MULTIARCH_QEMU_ENVIRON) CROSS_BUILD_ENVIRON=$(CROSS_BUILD_ENVIRON) ENABLE_FIPS_FEATURE=$(ENABLE_FIPS_FEATURE) DOCKER_EXTRA_OPTS=$(DOCKER_EXTRA_OPTS) DEFAULT_CONTAINER_REGISTRY=$(DEFAULT_CONTAINER_REGISTRY) j2 $(SLAVE_DIR)/Dockerfile.j2 > $(SLAVE_DIR)/Dockerfile) -$(shell CONFIGURED_ARCH=$(CONFIGURED_ARCH) MULTIARCH_QEMU_ENVIRON=$(MULTIARCH_QEMU_ENVIRON) CROSS_BUILD_ENVIRON=$(CROSS_BUILD_ENVIRON) j2 $(SLAVE_DIR)/Dockerfile.user.j2 > $(SLAVE_DIR)/Dockerfile.user) -$(shell BUILD_SLAVE=y DEFAULT_CONTAINER_REGISTRY=$(DEFAULT_CONTAINER_REGISTRY) scripts/prepare_docker_buildinfo.sh $(SLAVE_BASE_IMAGE) $(SLAVE_DIR)/Dockerfile $(CONFIGURED_ARCH) "" $(BLDENV)) +$(shell CONFIGURED_ARCH=$(CONFIGURED_ARCH) \ + MULTIARCH_QEMU_ENVIRON=$(MULTIARCH_QEMU_ENVIRON) \ + CROSS_BUILD_ENVIRON=$(CROSS_BUILD_ENVIRON) \ + ENABLE_FIPS_FEATURE=$(ENABLE_FIPS_FEATURE) \ + DOCKER_EXTRA_OPTS=$(DOCKER_EXTRA_OPTS) \ + DEFAULT_CONTAINER_REGISTRY=$(DEFAULT_CONTAINER_REGISTRY) \ + j2 $(SLAVE_DIR)/Dockerfile.j2 > $(SLAVE_DIR)/Dockerfile) + +$(shell CONFIGURED_ARCH=$(CONFIGURED_ARCH) \ + MULTIARCH_QEMU_ENVIRON=$(MULTIARCH_QEMU_ENVIRON) \ + CROSS_BUILD_ENVIRON=$(CROSS_BUILD_ENVIRON) \ + j2 $(SLAVE_DIR)/Dockerfile.user.j2 > $(SLAVE_DIR)/Dockerfile.user) + +PREPARE_DOCKER=BUILD_SLAVE=y \ + DEFAULT_CONTAINER_REGISTRY=$(DEFAULT_CONTAINER_REGISTRY) \ + scripts/prepare_docker_buildinfo.sh \ + $(SLAVE_BASE_IMAGE) \ + $(SLAVE_DIR)/Dockerfile \ + $(CONFIGURED_ARCH) \ + "" \ + $(BLDENV) + +$(shell $(PREPARE_DOCKER) ) # Add the versions in the tag, if the version change, need to rebuild the slave -SLAVE_BASE_TAG = $(shell cat $(SLAVE_DIR)/Dockerfile $(SLAVE_DIR)/buildinfo/versions/versions-* src/sonic-build-hooks/hooks/* | sha1sum | awk '{print substr($$1,0,11);}') -# Calculate the slave TAG based on $(USER)/$(PWD)/$(CONFIGURED_PLATFORM) to get unique SHA ID -SLAVE_TAG = $(shell (cat $(SLAVE_DIR)/Dockerfile.user $(SLAVE_DIR)/Dockerfile $(SLAVE_DIR)/buildinfo/versions/versions-* .git/HEAD && echo $(USER)/$(PWD)/$(CONFIGURED_PLATFORM)) \ - | sha1sum | awk '{print substr($$1,0,11);}') +SLAVE_BASE_TAG = $(shell \ + cat $(SLAVE_DIR)/Dockerfile \ + $(SLAVE_DIR)/buildinfo/versions/versions-* \ + src/sonic-build-hooks/hooks/* 2>/dev/null \ + | sha1sum \ + | awk '{print substr($$1,0,11);}') +# Calculate the slave TAG based on $(USER)/$(PWD)/$(CONFIGURED_PLATFORM) to get unique SHA ID +SLAVE_TAG = $(shell \ + (cat $(SLAVE_DIR)/Dockerfile.user \ + $(SLAVE_DIR)/Dockerfile \ + $(SLAVE_DIR)/buildinfo/versions/versions-* \ + .git/HEAD \ + && echo $(USER)/$(PWD)/$(CONFIGURED_PLATFORM)) \ + | sha1sum \ + | awk '{print substr($$1,0,11);}') + +COLLECT_DOCKER=DEFAULT_CONTAINER_REGISTRY=$(DEFAULT_CONTAINER_REGISTRY) \ + scripts/collect_docker_version_files.sh \ + $(SLAVE_BASE_IMAGE):$(SLAVE_BASE_TAG) \ + target OVERLAY_MODULE_CHECK := \ lsmod | grep -q "^overlay " &>/dev/null || \ zgrep -q 'CONFIG_OVERLAY_FS=y' /proc/config.gz &>/dev/null || \ @@ -329,7 +367,7 @@ DOCKER_BASE_LOG = $(SLAVE_DIR)/$(SLAVE_BASE_IMAGE)_$(SLAVE_BASE_TAG).log DOCKER_LOG = $(SLAVE_DIR)/$(SLAVE_IMAGE)_$(SLAVE_TAG).log -DOCKER_BASE_BUILD = docker build --no-cache \ +DOCKER_SLAVE_BASE_BUILD = docker build --no-cache \ -t $(SLAVE_BASE_IMAGE):$(SLAVE_BASE_TAG) \ --build-arg http_proxy=$(http_proxy) \ --build-arg https_proxy=$(https_proxy) \ @@ -339,7 +377,7 @@ DOCKER_BASE_BUILD = docker build --no-cache \ DOCKER_BASE_PULL = docker pull \ $(REGISTRY_SERVER):$(REGISTRY_PORT)/$(SLAVE_BASE_IMAGE):$(SLAVE_BASE_TAG) -DOCKER_BUILD = docker build --no-cache \ +DOCKER_USER_BUILD = docker build --no-cache \ --build-arg user=$(USER) \ --build-arg uid=$(shell id -u) \ --build-arg guid=$(shell id -g) \ @@ -349,7 +387,52 @@ DOCKER_BUILD = docker build --no-cache \ -f $(SLAVE_DIR)/Dockerfile.user \ $(SLAVE_DIR) $(SPLIT_LOG) $(DOCKER_LOG) -SONIC_BUILD_INSTRUCTION := make \ + +DOCKER_SLAVE_BASE_INSPECT = \ + { \ + echo Checking sonic-slave-base image: $(SLAVE_BASE_IMAGE):$(SLAVE_BASE_TAG); \ + docker inspect --type image $(SLAVE_BASE_IMAGE):$(SLAVE_BASE_TAG) &> /dev/null; \ + } + +DOCKER_SLAVE_BASE_PULL_REGISTRY = \ + [ $(ENABLE_DOCKER_BASE_PULL) == y ] && \ + { \ + echo Image $(SLAVE_BASE_IMAGE):$(SLAVE_BASE_TAG) not found. Pulling...; \ + $(DOCKER_BASE_PULL); \ + } && \ + { \ + docker tag $(REGISTRY_SERVER):$(REGISTRY_PORT)/$(SLAVE_BASE_IMAGE):$(SLAVE_BASE_TAG) $(SLAVE_BASE_IMAGE):$(SLAVE_BASE_TAG) && \ + $(COLLECT_DOCKER); \ + }\ + +SONIC_SLAVE_BASE_BUILD = \ + { \ + $(DOCKER_SLAVE_BASE_INSPECT); \ + } || \ + { \ + $(DOCKER_SLAVE_BASE_PULL_REGISTRY); \ + } || \ + { \ + echo Image $(SLAVE_BASE_IMAGE):$(SLAVE_BASE_TAG) not found. Building... ; \ + $(PREPARE_DOCKER) ; \ + $(DOCKER_SLAVE_BASE_BUILD) ; \ + $(COLLECT_DOCKER) ; \ + } + +DOCKER_SLAVE_USER_INSPECT = \ + { \ + echo Checking sonic-slave-user image: $(SLAVE_IMAGE):$(SLAVE_TAG); \ + docker inspect --type image $(SLAVE_IMAGE):$(SLAVE_TAG) &> /dev/null; \ + } + +SONIC_SLAVE_USER_BUILD = \ + { $(DOCKER_SLAVE_USER_INSPECT) } || \ + { \ + echo Image $(SLAVE_IMAGE):$(SLAVE_TAG) not found. Building... ; \ + $(DOCKER_USER_BUILD) ; \ + } + +SONIC_BUILD_INSTRUCTION := $(MAKE) \ -f slave.mk \ PLATFORM=$(PLATFORM) \ PLATFORM_ARCH=$(PLATFORM_ARCH) \ @@ -415,87 +498,75 @@ SONIC_BUILD_INSTRUCTION := make \ .PHONY: sonic-slave-build sonic-slave-bash init reset + +ifeq ($(filter clean,$(MAKECMDGOALS)),) +COLLECT_BUILD_VERSION = { DBGOPT='$(DBGOPT)' scripts/collect_build_version_files.sh $$?; } +endif + +ifdef SOURCE_FOLDER + DOCKER_RUN += -v $(SOURCE_FOLDER):/var/$(USER)/src +endif + +ifeq "$(KEEP_SLAVE_ON)" "yes" +SLAVE_SHELL={ /bin/bash; } +endif + .DEFAULT_GOAL := all -%:: +%:: | sonic-build-hooks ifneq ($(filter y, $(MULTIARCH_QEMU_ENVIRON) $(CROSS_BUILD_ENVIRON)),) - @$(DOCKER_MULTIARCH_CHECK) + $(Q)$(DOCKER_MULTIARCH_CHECK) ifneq ($(BLDENV), ) - @$(DOCKER_SERVICE_MULTIARCH_CHECK) - @$(DOCKER_SERVICE_DOCKERFS_CHECK) -endif -endif - @$(OVERLAY_MODULE_CHECK) - - @pushd src/sonic-build-hooks; TRUSTED_GPG_URLS=$(TRUSTED_GPG_URLS) make all; popd - @cp src/sonic-build-hooks/buildinfo/sonic-build-hooks* $(SLAVE_DIR)/buildinfo - @docker inspect --type image $(SLAVE_BASE_IMAGE):$(SLAVE_BASE_TAG) &> /dev/null || \ - { [ $(ENABLE_DOCKER_BASE_PULL) == y ] && { echo Image $(SLAVE_BASE_IMAGE):$(SLAVE_BASE_TAG) not found. Pulling...; } && \ - $(DOCKER_BASE_PULL) && \ - { docker tag $(REGISTRY_SERVER):$(REGISTRY_PORT)/$(SLAVE_BASE_IMAGE):$(SLAVE_BASE_TAG) $(SLAVE_BASE_IMAGE):$(SLAVE_BASE_TAG) && \ - scripts/collect_docker_version_files.sh $(SLAVE_BASE_IMAGE):$(SLAVE_BASE_TAG) target ; } } || \ - { echo Image $(SLAVE_BASE_IMAGE):$(SLAVE_BASE_TAG) not found. Building... ; \ - $(DOCKER_BASE_BUILD) ; \ - scripts/collect_docker_version_files.sh $(SLAVE_BASE_IMAGE):$(SLAVE_BASE_TAG) target ; } - @docker inspect --type image $(SLAVE_IMAGE):$(SLAVE_TAG) &> /dev/null || \ - { echo Image $(SLAVE_IMAGE):$(SLAVE_TAG) not found. Building... ; \ - $(DOCKER_BUILD) ; } -ifeq "$(KEEP_SLAVE_ON)" "yes" - ifdef SOURCE_FOLDER - @$(DOCKER_RUN) -v $(SOURCE_FOLDER):/var/$(USER)/src $(SLAVE_IMAGE):$(SLAVE_TAG) bash -c "$(SONIC_BUILD_INSTRUCTION) $@; scripts/collect_build_version_files.sh \$$?; /bin/bash" - else - @$(DOCKER_RUN) $(SLAVE_IMAGE):$(SLAVE_TAG) bash -c "$(SONIC_BUILD_INSTRUCTION) $@; scripts/collect_build_version_files.sh \$$?; /bin/bash" - endif -else - @$(DOCKER_RUN) $(SLAVE_IMAGE):$(SLAVE_TAG) bash -c "$(SONIC_BUILD_INSTRUCTION) $@; scripts/collect_build_version_files.sh \$$?" + $(Q)$(DOCKER_SERVICE_MULTIARCH_CHECK) + $(Q)$(DOCKER_SERVICE_DOCKERFS_CHECK) +endif endif + $(Q)$(OVERLAY_MODULE_CHECK) + $(Q)$(SONIC_SLAVE_BASE_BUILD) + $(Q)$(SONIC_SLAVE_USER_BUILD) + + $(Q)$(DOCKER_RUN) \ + $(SLAVE_IMAGE):$(SLAVE_TAG) \ + bash -c "$(SONIC_BUILD_INSTRUCTION) $@;$(COLLECT_BUILD_VERSION); $(SLAVE_SHELL)" + $(Q)$(docker-image-cleanup) docker-cleanup: - $(docker-image-cleanup) + $(Q)$(docker-image-cleanup) +.PHONY: sonic-build-hooks sonic-build-hooks: - @pushd src/sonic-build-hooks; TRUSTED_GPG_URLS=$(TRUSTED_GPG_URLS) make all; popd - @cp src/sonic-build-hooks/buildinfo/sonic-build-hooks* $(SLAVE_DIR)/buildinfo + $(Q)pushd src/sonic-build-hooks; TRUSTED_GPG_URLS=$(TRUSTED_GPG_URLS) $(MAKE) all; popd + $(Q)mkdir -p $(SLAVE_DIR)/buildinfo + $(Q)cp src/sonic-build-hooks/buildinfo/sonic-build-hooks* $(SLAVE_DIR)/buildinfo -sonic-slave-base-build : sonic-build-hooks +sonic-slave-base-build : | sonic-build-hooks ifeq ($(MULTIARCH_QEMU_ENVIRON), y) - @$(DOCKER_MULTIARCH_CHECK) -endif - @$(OVERLAY_MODULE_CHECK) - @echo Checking sonic-slave-base image: $(SLAVE_BASE_IMAGE):$(SLAVE_BASE_TAG) - @docker inspect --type image $(SLAVE_BASE_IMAGE):$(SLAVE_BASE_TAG) &> /dev/null || \ - { [ $(ENABLE_DOCKER_BASE_PULL) == y ] && { echo Image $(SLAVE_BASE_IMAGE):$(SLAVE_BASE_TAG) not found. Pulling...; } && \ - $(DOCKER_BASE_PULL) && \ - { docker tag $(REGISTRY_SERVER):$(REGISTRY_PORT)/$(SLAVE_BASE_IMAGE):$(SLAVE_BASE_TAG) $(SLAVE_BASE_IMAGE):$(SLAVE_BASE_TAG) && \ - scripts/collect_docker_version_files.sh $(SLAVE_BASE_IMAGE):$(SLAVE_BASE_TAG) target ; } } || \ - { echo Image $(SLAVE_BASE_IMAGE):$(SLAVE_BASE_TAG) not found. Building... ; \ - $(DOCKER_BASE_BUILD) ; \ - scripts/collect_docker_version_files.sh $(SLAVE_BASE_IMAGE):$(SLAVE_BASE_TAG) target ; } + $(Q)$(DOCKER_MULTIARCH_CHECK) +endif + $(Q)$(OVERLAY_MODULE_CHECK) + $(Q)$(SONIC_SLAVE_BASE_BUILD) sonic-slave-build : sonic-slave-base-build - @echo Checking sonic-slave image: $(SLAVE_IMAGE):$(SLAVE_TAG) - @docker inspect --type image $(SLAVE_IMAGE):$(SLAVE_TAG) &> /dev/null || \ - { echo Image $(SLAVE_IMAGE):$(SLAVE_TAG) not found. Building... ; \ - $(DOCKER_BUILD) ; } + $(Q)$(SONIC_SLAVE_USER_BUILD) sonic-slave-bash : sonic-slave-build - @$(DOCKER_RUN) -t $(SLAVE_IMAGE):$(SLAVE_TAG) bash + $(Q)$(DOCKER_RUN) -t $(SLAVE_IMAGE):$(SLAVE_TAG) bash sonic-slave-run : sonic-slave-build - @$(DOCKER_RUN) $(SLAVE_IMAGE):$(SLAVE_TAG) bash -c "$(SONIC_RUN_CMDS)" + $(Q)$(DOCKER_RUN) $(SLAVE_IMAGE):$(SLAVE_TAG) bash -c "$(SONIC_RUN_CMDS)" showtag: - @echo $(SLAVE_IMAGE):$(SLAVE_TAG) - @echo $(SLAVE_BASE_IMAGE):$(SLAVE_BASE_TAG) + $(Q)echo $(SLAVE_IMAGE):$(SLAVE_TAG) + $(Q)echo $(SLAVE_BASE_IMAGE):$(SLAVE_BASE_TAG) init : - @git submodule update --init --recursive - @git submodule foreach --recursive '[ -f .git ] && echo "gitdir: $$(realpath --relative-to=. $$(cut -d" " -f2 .git))" > .git' + $(Q)git submodule update --init --recursive + $(Q)git submodule foreach --recursive '[ -f .git ] && echo "gitdir: $$(realpath --relative-to=. $$(cut -d" " -f2 .git))" > .git' .ONESHELL : reset reset : - @echo && echo -n "Warning! All local changes will be lost. Proceed? [y/N]: " - @read ans && ( + $(Q)echo && echo -n "Warning! All local changes will be lost. Proceed? [y/N]: " + $(Q)read ans && ( if [ $$ans == y ]; then echo "Resetting local repository. Please wait..."; sudo rm -rf fsroot*; diff --git a/slave.mk b/slave.mk index c521b3807356..28efed3dfc11 100644 --- a/slave.mk +++ b/slave.mk @@ -92,32 +92,32 @@ export BLDENV .platform : ifneq ($(CONFIGURED_PLATFORM),generic) - @echo Build system is not configured, please run make configure - @exit 1 + $(Q)echo Build system is not configured, please run make configure + $(Q)exit 1 endif configure : - @mkdir -p $(JESSIE_DEBS_PATH) - @mkdir -p $(STRETCH_DEBS_PATH) - @mkdir -p $(BUSTER_DEBS_PATH) - @mkdir -p $(BULLSEYE_DEBS_PATH) - @mkdir -p $(FILES_PATH) - @mkdir -p $(JESSIE_FILES_PATH) - @mkdir -p $(STRETCH_FILES_PATH) - @mkdir -p $(BUSTER_FILES_PATH) - @mkdir -p $(BULLSEYE_FILES_PATH) - @mkdir -p $(PYTHON_DEBS_PATH) - @mkdir -p $(PYTHON_WHEELS_PATH) - @mkdir -p $(DPKG_ADMINDIR_PATH) - @echo $(PLATFORM) > .platform - @echo $(PLATFORM_ARCH) > .arch + $(Q)mkdir -p $(JESSIE_DEBS_PATH) + $(Q)mkdir -p $(STRETCH_DEBS_PATH) + $(Q)mkdir -p $(BUSTER_DEBS_PATH) + $(Q)mkdir -p $(BULLSEYE_DEBS_PATH) + $(Q)mkdir -p $(FILES_PATH) + $(Q)mkdir -p $(JESSIE_FILES_PATH) + $(Q)mkdir -p $(STRETCH_FILES_PATH) + $(Q)mkdir -p $(BUSTER_FILES_PATH) + $(Q)mkdir -p $(BULLSEYE_FILES_PATH) + $(Q)mkdir -p $(PYTHON_DEBS_PATH) + $(Q)mkdir -p $(PYTHON_WHEELS_PATH) + $(Q)mkdir -p $(DPKG_ADMINDIR_PATH) + $(Q)echo $(PLATFORM) > .platform + $(Q)echo $(PLATFORM_ARCH) > .arch distclean : .platform clean - @rm -f .platform - @rm -f .arch + $(Q)rm -f .platform + $(Q)rm -f .arch list : - @$(foreach target,$(SONIC_TARGET_LIST),echo $(target);) + $(Q)$(foreach target,$(SONIC_TARGET_LIST),echo $(target);) ############################################################################### ## Include other rules @@ -177,7 +177,7 @@ endif # TODO(PINS): Remove when Bazel binaries are available for armhf ifeq ($(CONFIGURED_ARCH),armhf) ifeq ($(INCLUDE_P4RT),y) - @echo "Disabling P4RT due to incompatible CPU architecture: $(CONFIGURED_ARCH)" + $(Q)echo "Disabling P4RT due to incompatible CPU architecture: $(CONFIGURED_ARCH)" endif override INCLUDE_P4RT = n endif @@ -205,7 +205,7 @@ endif ifeq ($(ENABLE_ASAN),y) ifneq ($(CONFIGURED_ARCH),amd64) - @echo "Disabling SWSS address sanitizer due to incompatible CPU architecture: $(CONFIGURED_ARCH)" + $(Q)echo "Disabling SWSS address sanitizer due to incompatible CPU architecture: $(CONFIGURED_ARCH)" override ENABLE_ASAN = n endif endif @@ -870,12 +870,12 @@ endif # start docker daemon docker-start : - @sudo sed -i 's/--storage-driver=vfs/--storage-driver=$(SONIC_SLAVE_DOCKER_DRIVER)/' /etc/default/docker - @sudo sed -i -e '/http_proxy/d' -e '/https_proxy/d' /etc/default/docker - @sudo bash -c "{ echo \"export http_proxy=$$http_proxy\"; \ + $(Q)sudo sed -i 's/--storage-driver=vfs/--storage-driver=$(SONIC_SLAVE_DOCKER_DRIVER)/' /etc/default/docker + $(Q)sudo sed -i -e '/http_proxy/d' -e '/https_proxy/d' /etc/default/docker + $(Q)sudo bash -c "{ echo \"export http_proxy=$$http_proxy\"; \ echo \"export https_proxy=$$https_proxy\"; \ echo \"export no_proxy=$$no_proxy\"; } >> /etc/default/docker" - @test x$(SONIC_CONFIG_USE_NATIVE_DOCKERD_FOR_BUILD) != x"y" && sudo service docker status &> /dev/null || ( sudo service docker start &> /dev/null && ./scripts/wait_for_docker.sh 60 ) + $(Q)test x$(SONIC_CONFIG_USE_NATIVE_DOCKERD_FOR_BUILD) != x"y" && sudo service docker status &> /dev/null || ( sudo service docker start &> /dev/null && ./scripts/wait_for_docker.sh 60 ) # targets for building simple docker images that do not depend on any debian packages $(addprefix $(TARGET_PATH)/, $(SONIC_SIMPLE_DOCKER_IMAGES)) : $(TARGET_PATH)/%.gz : .platform docker-start $$(addsuffix -load,$$(addprefix $(TARGET_PATH)/,$$($$*.gz_LOAD_DOCKERS))) @@ -1414,12 +1414,12 @@ SONIC_CLEAN_FILES = $(addsuffix -clean,$(addprefix $(FILES_PATH)/, \ $(SONIC_MAKE_FILES))) $(SONIC_CLEAN_DEBS) :: $(DEBS_PATH)/%-clean : .platform $$(addsuffix -clean,$$(addprefix $(DEBS_PATH)/,$$($$*_MAIN_DEB))) - @# remove derived or extra targets if main one is removed, because we treat them - @# as part of one package - @rm -f $(addprefix $(DEBS_PATH)/, $* $($*_DERIVED_DEBS) $($*_EXTRA_DEBS)) + $(Q)# remove derived or extra targets if main one is removed, because we treat them + $(Q)# as part of one package + $(Q)rm -f $(addprefix $(DEBS_PATH)/, $* $($*_DERIVED_DEBS) $($*_EXTRA_DEBS)) $(SONIC_CLEAN_FILES) :: $(FILES_PATH)/%-clean : .platform - @rm -f $(FILES_PATH)/$* + $(Q)rm -f $(FILES_PATH)/$* SONIC_CLEAN_TARGETS += $(addsuffix -clean,$(addprefix $(TARGET_PATH)/, \ $(SONIC_DOCKER_IMAGES) \ @@ -1427,20 +1427,20 @@ SONIC_CLEAN_TARGETS += $(addsuffix -clean,$(addprefix $(TARGET_PATH)/, \ $(SONIC_SIMPLE_DOCKER_IMAGES) \ $(SONIC_INSTALLERS))) $(SONIC_CLEAN_TARGETS) :: $(TARGET_PATH)/%-clean : .platform - @rm -f $(TARGET_PATH)/$* + $(Q)rm -f $(TARGET_PATH)/$* SONIC_CLEAN_STDEB_DEBS = $(addsuffix -clean,$(addprefix $(PYTHON_DEBS_PATH)/, \ $(SONIC_PYTHON_STDEB_DEBS))) $(SONIC_CLEAN_STDEB_DEBS) :: $(PYTHON_DEBS_PATH)/%-clean : .platform - @rm -f $(PYTHON_DEBS_PATH)/$* + $(Q)rm -f $(PYTHON_DEBS_PATH)/$* SONIC_CLEAN_WHEELS = $(addsuffix -clean,$(addprefix $(PYTHON_WHEELS_PATH)/, \ $(SONIC_PYTHON_WHEELS))) $(SONIC_CLEAN_WHEELS) :: $(PYTHON_WHEELS_PATH)/%-clean : .platform - @rm -f $(PYTHON_WHEELS_PATH)/$* + $(Q)rm -f $(PYTHON_WHEELS_PATH)/$* clean-logs :: .platform - @rm -f $(TARGET_PATH)/*.log $(DEBS_PATH)/*.log $(FILES_PATH)/*.log $(PYTHON_DEBS_PATH)/*.log $(PYTHON_WHEELS_PATH)/*.log + $(Q)rm -f $(TARGET_PATH)/*.log $(DEBS_PATH)/*.log $(FILES_PATH)/*.log $(PYTHON_DEBS_PATH)/*.log $(PYTHON_WHEELS_PATH)/*.log clean :: .platform clean-logs $$(SONIC_CLEAN_DEBS) $$(SONIC_CLEAN_FILES) $$(SONIC_CLEAN_TARGETS) $$(SONIC_CLEAN_STDEB_DEBS) $$(SONIC_CLEAN_WHEELS) From 1f0699f51e51cf9ca6e36d85bc632ee0e31792e4 Mon Sep 17 00:00:00 2001 From: xumia <59720581+xumia@users.noreply.github.com> Date: Wed, 5 Oct 2022 08:10:54 +0800 Subject: [PATCH 151/151] Fix sonic-config low dpkg hit rate issue (#12244) Why I did it When sending a PR only CI change, as expected, the target target/python-wheels/buster/sonic_config_engine-1.0-py2-none-any.whl should be from the cache, because the depended files were not changed, but it rebuilt. How I did it Sort the files by name. --- rules/sonic-config.dep | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rules/sonic-config.dep b/rules/sonic-config.dep index 65aabe74d76f..2b8b98fcd42b 100644 --- a/rules/sonic-config.dep +++ b/rules/sonic-config.dep @@ -4,7 +4,7 @@ SPATH := $($(SONIC_CONFIG_ENGINE_PY3)_SRC_PATH) DEP_FILES := $(SONIC_COMMON_FILES_LIST) rules/sonic-config.mk rules/sonic-config.dep DEP_FILES += $(SONIC_COMMON_BASE_FILES_LIST) DEP_FILES += $(shell git ls-files $(SPATH)) -DEP_FILES += files/image_config/interfaces/interfaces.j2 dockers/docker-orchagent/ports.json.j2 dockers/docker-dhcp-relay/wait_for_intf.sh.j2 dockers/docker-dhcp-relay/docker-dhcp-relay.supervisord.conf.j2 dockers/docker-lldp/lldpd.conf.j2 dockers/docker-orchagent/ipinip.json.j2 $(shell find device -type f) files/build_templates/qos_config.j2 dockers/docker-orchagent/switch.json.j2 dockers/docker-orchagent/vxlan.json.j2 files/image_config/constants/constants.yml +DEP_FILES += files/image_config/interfaces/interfaces.j2 dockers/docker-orchagent/ports.json.j2 dockers/docker-dhcp-relay/wait_for_intf.sh.j2 dockers/docker-dhcp-relay/docker-dhcp-relay.supervisord.conf.j2 dockers/docker-lldp/lldpd.conf.j2 dockers/docker-orchagent/ipinip.json.j2 $(shell find device -type f | sort) files/build_templates/qos_config.j2 dockers/docker-orchagent/switch.json.j2 dockers/docker-orchagent/vxlan.json.j2 files/image_config/constants/constants.yml ifeq ($(ENABLE_PY2_MODULES), y) $(SONIC_CONFIG_ENGINE_PY2)_CACHE_MODE := GIT_CONTENT_SHA