Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[DELLEMC][S6000] Platform 2.0 Reboot Reason and fixed issue in process-reboot-cause #3156

Merged
merged 4 commits into from
Jul 24, 2019
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ def main():
# if there is no sonic_platform package installed, we only provide
# software-related reboot causes.
try:
import sonic_platform
import sonic_platform.platform
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is this necessary?

Copy link
Contributor Author

@sridhar-ravindran sridhar-ravindran Jul 16, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi Joe,

sonic_platform is directory. platform is the file.

When we import directory alone We get the following error.
From File :- /usr/bin/process-reboot-cause
import sonic_platform
# Check if the previous reboot was caused by hardware
platform = sonic_platform.platform.Platform()
chassis = platform.get_chassis()
hardware_reboot_cause, optional_details = chassis.get_reboot_cause()

root@sonic:/home/admin# /usr/bin/process-reboot-cause
Traceback (most recent call last):
File "/usr/bin/process-reboot-cause", line 121, in
main()
File "/usr/bin/process-reboot-cause", line 76, in main

platform = sonic_platform.platform.Platform()
AttributeError: 'module' object has no attribute 'platform'

When we import the file "platform" the script is working
import sonic_platform.platform
# Check if the previous reboot was caused by hardware
platform = sonic_platform.platform.Platform()
chassis = platform.get_chassis()
hardware_reboot_cause, optional_details = chassis.get_reboot_cause()

root@sonic:/home/admin# /usr/bin/process-reboot-cause
root@sonic:/home/admin# <<<<<<<<<<<<< No Error

Please let me know if my understanding is fine.

Thanks
Sridhar.R

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmmm. I don't believe this should be necessary. You should be able to import the entire package by specifying the package (directory) name. Let me look into this further.

Copy link
Contributor

@jleveque jleveque Jul 16, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It appears for this to work, you need to modify the init.py file of your sonic_platform package to either import the files and/or list the module names in __all__. See: https://docs.python.org/3/tutorial/modules.html#importing-from-a-package

I should probably also do this for sonic_platform_base, as well.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi Joe,
After some literature study, i was able to successfully make it work. Updated init.py with
all = ["platform", "chassis"]
from sonic_platform import *

On adding these 2 lines, "import sonic_platform" works fine.

On adding new files like sfp.py , psu.py, device,py, we have to update the init.py file as well.

Thanks for your help and support Joe.

Thanks
Sridhar.R


# Check if the previous reboot was caused by hardware
platform = sonic_platform.platform.Platform()
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[Unit]
Description=Reboot cause determination service
After=rc-local.service
After=pmon.service
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why change this?

Copy link
Contributor Author

@sridhar-ravindran sridhar-ravindran Jul 16, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi Joe,
The hardware drivers required to provide reboot reason are installed only inside platform-modules-XXXX service.

When process-reboot-cause service starts before the pmon service, loading of drivers are not complete and it leads to race condition where the show reboot-cause CLI return incorrect answers.

If process-reboot-cause loads after pmon.service, the platform drivers would have successfully loaded by then and show reboot-cause cli will return correct value

Thanks
Sridhar.R

Copy link
Contributor

@jleveque jleveque Jul 16, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi Sridhar,

SONiC requires that hardware reboot reason and watchdog functionality need to be available in the host OS. The sonic_platform package should be installed in both the host OS and PMon container. Host OS services should not have any dependencies on the containers. We want reboot cause and watchdog to be as reliable as possible. Thanks.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi Joe,
Thanks for the input. I have removed the pmon dependency from process-restart-cause service.
Thanks
Sridhar.R


[Service]
Type=simple
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,91 +11,29 @@
# Short-Description: Setup S6000 board.
### END INIT INFO

add_i2c_devices() {

echo 24c02 0x50 > /sys/class/i2c-adapter/i2c-1/new_device
echo 24c02 0x51 > /sys/class/i2c-adapter/i2c-1/new_device
echo dni_dps460 0x58 > /sys/class/i2c-adapter/i2c-1/new_device
echo dni_dps460 0x59 > /sys/class/i2c-adapter/i2c-1/new_device
echo jc42 0x18 > /sys/class/i2c-adapter/i2c-10/new_device
echo emc1403 0x4d > /sys/class/i2c-adapter/i2c-10/new_device
echo spd 0x50 > /sys/class/i2c-adapter/i2c-10/new_device
echo 24c02 0x53 > /sys/class/i2c-adapter/i2c-10/new_device
echo max6620 0x29 > /sys/class/i2c-adapter/i2c-11/new_device
echo max6620 0x2a > /sys/class/i2c-adapter/i2c-11/new_device
echo ltc4215 0x40 > /sys/class/i2c-adapter/i2c-11/new_device
echo ltc4215 0x42 > /sys/class/i2c-adapter/i2c-11/new_device
echo tmp75 0x4c > /sys/class/i2c-adapter/i2c-11/new_device
echo tmp75 0x4d > /sys/class/i2c-adapter/i2c-11/new_device
echo tmp75 0x4e > /sys/class/i2c-adapter/i2c-11/new_device
echo 24c02 0x51 > /sys/class/i2c-adapter/i2c-11/new_device
echo 24c02 0x52 > /sys/class/i2c-adapter/i2c-11/new_device
echo 24c02 0x53 > /sys/class/i2c-adapter/i2c-11/new_device
for i in `seq 0 31`; do
echo sff8436 0x50 > /sys/class/i2c-adapter/i2c-$((20+i))/new_device
done
}

remove_i2c_devices() {
echo 0x50 > /sys/class/i2c-adapter/i2c-1/delete_device
echo 0x51 > /sys/class/i2c-adapter/i2c-1/delete_device
echo 0x58 > /sys/class/i2c-adapter/i2c-1/delete_device
echo 0x59 > /sys/class/i2c-adapter/i2c-1/delete_device
echo 0x18 > /sys/class/i2c-adapter/i2c-10/delete_device
echo 0x4d > /sys/class/i2c-adapter/i2c-10/delete_device
echo 0x50 > /sys/class/i2c-adapter/i2c-10/delete_device
echo 0x53 > /sys/class/i2c-adapter/i2c-10/delete_device
echo 0x29 > /sys/class/i2c-adapter/i2c-11/delete_device
echo 0x2a > /sys/class/i2c-adapter/i2c-11/delete_device
echo 0x40 > /sys/class/i2c-adapter/i2c-11/delete_device
echo 0x42 > /sys/class/i2c-adapter/i2c-11/delete_device
echo 0x4c > /sys/class/i2c-adapter/i2c-11/delete_device
echo 0x4d > /sys/class/i2c-adapter/i2c-11/delete_device
echo 0x4e > /sys/class/i2c-adapter/i2c-11/delete_device
echo 0x51 > /sys/class/i2c-adapter/i2c-11/delete_device
echo 0x52 > /sys/class/i2c-adapter/i2c-11/delete_device
echo 0x53 > /sys/class/i2c-adapter/i2c-11/delete_device
for i in `seq 0 31`; do
echo 0x50 > /sys/class/i2c-adapter/i2c-$((20+i))/delete_device
done
}

case "$1" in
start)
echo -n "Setting up board... "

depmod -a
modprobe i2c_mux_gpio
modprobe dell_s6000_platform
modprobe nvram
echo -n "Setting up board... "

add_i2c_devices
/usr/local/bin/s6000_platform.sh init

/usr/local/bin/set-fan-speed 15000
/usr/local/bin/reset-qsfp

echo "done."
;;
echo "done."
;;

stop)
echo "done."

remove_i2c_devices
/usr/local/bin/s6000_platform.sh deinit
echo "done."

rmmod nvram
rmmod dell_s6000_platform
rmmod i2c_mux_gpio
;;
;;

force-reload|restart)
echo "Not supported"
;;
echo "Not supported"
;;

*)
echo "Usage: /etc/init.d/platform-modules-s6000.init {start|stop}"
exit 1
;;
echo "Usage: /etc/init.d/platform-modules-s6000.init {start|stop}"
exit 1
;;
esac

exit 0

Original file line number Diff line number Diff line change
@@ -1,2 +1,6 @@
s6000/scripts/s6000_platform.sh usr/local/bin
s6000/scripts/reset-qsfp usr/local/bin
s6000/scripts/set-fan-speed usr/local/bin
s6000/systemd/platform-modules-s6000.service etc/systemd/system
common/io_rd_wr.py usr/local/bin
s6000/modules/sonic_platform-1.0-py2-none-any.whl usr/share/sonic/device/x86_64-dell_s6000_s1220-r0
8 changes: 8 additions & 0 deletions platform/broadcom/sonic-platform-modules-dell/debian/rules
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,10 @@ override_dh_auto_build:
cd $(MOD_SRC_DIR)/$${mod}; \
python2.7 setup.py bdist_wheel -d $(MOD_SRC_DIR)/$${mod}/modules; \
cd $(MOD_SRC_DIR); \
elif [ $$mod = "s6000" ]; then \
cd $(MOD_SRC_DIR)/$${mod}; \
python2.7 setup.py bdist_wheel -d $(MOD_SRC_DIR)/$${mod}/modules; \
cd $(MOD_SRC_DIR); \
fi; \
echo "making man page alias $$mod -> $$mod APIs";\
make -C $(KERNEL_SRC)/build M=$(MOD_SRC_DIR)/$${mod}/modules; \
Expand Down Expand Up @@ -59,6 +63,10 @@ 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 = "s6000" ]; then \
rm -f $(MOD_SRC_DIR)/$${mod}/modules/*.whl; \
rm -rf $(MOD_SRC_DIR)/$${mod}/build; \
rm -rf $(MOD_SRC_DIR)/$${mod}/build/*.egg-info; \
fi; \
make -C $(KERNEL_SRC)/build M=$(MOD_SRC_DIR)/$${mod}/modules clean; \
done)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
#include <linux/i2c/sff-8436.h>
#include <linux/delay.h>
#include <linux/gpio.h>
#include <linux/nvram.h>

#define S6000_MUX_BASE_NR 10
#define QSFP_MODULE_BASE_NR 20
Expand All @@ -23,6 +24,8 @@

#define GPIO_I2C_MUX_PIN 10

#define RTC_NVRAM_REBOOT_REASON_OFFSET 0x49

static void device_release(struct device *dev)
{
return;
Expand Down Expand Up @@ -1094,6 +1097,24 @@ static ssize_t get_slave_cpld_ver(struct device *dev,
return sprintf(buf, "0x%x\n", data);
}

static ssize_t get_reboot_reason(struct device *dev,
struct device_attribute *devattr, char *buf)
{
uint8_t data = 0;

/* Last Reboot reason in saved in RTC NVRAM offset 0x49
* We write the reboot reason into nvram offset,
* as part of platform_reboot implementation from userspace.

* COLD_RESET = 0xE # Cold Reset (value)
* WARM_RESET = 0x6 # Warm Reset (value)
*/

/* Read it from this offset, and export it as last_reboot_reason */
data = nvram_read_byte(RTC_NVRAM_REBOOT_REASON_OFFSET);

return sprintf(buf, "0x%x\n", data);
}

static DEVICE_ATTR(qsfp_modsel, S_IRUGO, get_modsel, NULL);
static DEVICE_ATTR(qsfp_modprs, S_IRUGO, get_modprs, NULL);
Expand All @@ -1116,6 +1137,7 @@ static DEVICE_ATTR(fan2_led, S_IRUGO | S_IWUSR, get_fan2_led, set_fan2_led);
static DEVICE_ATTR(system_cpld_ver, S_IRUGO, get_system_cpld_ver, NULL);
static DEVICE_ATTR(master_cpld_ver, S_IRUGO, get_master_cpld_ver, NULL);
static DEVICE_ATTR(slave_cpld_ver, S_IRUGO, get_slave_cpld_ver, NULL);
static DEVICE_ATTR(last_reboot_reason, S_IRUGO, get_reboot_reason, NULL);

static struct attribute *s6000_cpld_attrs[] = {
&dev_attr_qsfp_modsel.attr,
Expand All @@ -1139,6 +1161,7 @@ static struct attribute *s6000_cpld_attrs[] = {
&dev_attr_system_cpld_ver.attr,
&dev_attr_master_cpld_ver.attr,
&dev_attr_slave_cpld_ver.attr,
&dev_attr_last_reboot_reason.attr,
NULL,
};

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
#!/bin/bash

### BEGIN INIT INFO
# Provides: setup-board
# Required-Start:
# Required-Stop:
# Should-Start:
# Should-Stop:
# Default-Start: S
# Default-Stop: 0 6
# Short-Description: Setup S6000 board.
### END INIT INFO

add_i2c_devices() {

echo 24c02 0x50 > /sys/class/i2c-adapter/i2c-1/new_device
echo 24c02 0x51 > /sys/class/i2c-adapter/i2c-1/new_device
echo dni_dps460 0x58 > /sys/class/i2c-adapter/i2c-1/new_device
echo dni_dps460 0x59 > /sys/class/i2c-adapter/i2c-1/new_device
echo jc42 0x18 > /sys/class/i2c-adapter/i2c-10/new_device
echo emc1403 0x4d > /sys/class/i2c-adapter/i2c-10/new_device
echo spd 0x50 > /sys/class/i2c-adapter/i2c-10/new_device
echo 24c02 0x53 > /sys/class/i2c-adapter/i2c-10/new_device
echo max6620 0x29 > /sys/class/i2c-adapter/i2c-11/new_device
echo max6620 0x2a > /sys/class/i2c-adapter/i2c-11/new_device
echo ltc4215 0x40 > /sys/class/i2c-adapter/i2c-11/new_device
echo ltc4215 0x42 > /sys/class/i2c-adapter/i2c-11/new_device
echo tmp75 0x4c > /sys/class/i2c-adapter/i2c-11/new_device
echo tmp75 0x4d > /sys/class/i2c-adapter/i2c-11/new_device
echo tmp75 0x4e > /sys/class/i2c-adapter/i2c-11/new_device
echo 24c02 0x51 > /sys/class/i2c-adapter/i2c-11/new_device
echo 24c02 0x52 > /sys/class/i2c-adapter/i2c-11/new_device
echo 24c02 0x53 > /sys/class/i2c-adapter/i2c-11/new_device
for i in `seq 0 31`; do
echo sff8436 0x50 > /sys/class/i2c-adapter/i2c-$((20+i))/new_device
done
}

remove_i2c_devices() {
echo 0x50 > /sys/class/i2c-adapter/i2c-1/delete_device
echo 0x51 > /sys/class/i2c-adapter/i2c-1/delete_device
echo 0x58 > /sys/class/i2c-adapter/i2c-1/delete_device
echo 0x59 > /sys/class/i2c-adapter/i2c-1/delete_device
echo 0x18 > /sys/class/i2c-adapter/i2c-10/delete_device
echo 0x4d > /sys/class/i2c-adapter/i2c-10/delete_device
echo 0x50 > /sys/class/i2c-adapter/i2c-10/delete_device
echo 0x53 > /sys/class/i2c-adapter/i2c-10/delete_device
echo 0x29 > /sys/class/i2c-adapter/i2c-11/delete_device
echo 0x2a > /sys/class/i2c-adapter/i2c-11/delete_device
echo 0x40 > /sys/class/i2c-adapter/i2c-11/delete_device
echo 0x42 > /sys/class/i2c-adapter/i2c-11/delete_device
echo 0x4c > /sys/class/i2c-adapter/i2c-11/delete_device
echo 0x4d > /sys/class/i2c-adapter/i2c-11/delete_device
echo 0x4e > /sys/class/i2c-adapter/i2c-11/delete_device
echo 0x51 > /sys/class/i2c-adapter/i2c-11/delete_device
echo 0x52 > /sys/class/i2c-adapter/i2c-11/delete_device
echo 0x53 > /sys/class/i2c-adapter/i2c-11/delete_device
for i in `seq 0 31`; do
echo 0x50 > /sys/class/i2c-adapter/i2c-$((20+i))/delete_device
done
}

install_python_api_package() {
device="/usr/share/sonic/device"
platform=$(/usr/local/bin/sonic-cfggen -H -v DEVICE_METADATA.localhost.platform)

if [ -e $device/$platform/sonic_platform-1.0-py2-none-any.whl ]; then
rv=$(pip install $device/$platform/sonic_platform-1.0-py2-none-any.whl)
fi
}

remove_python_api_package() {
rv=$(pip show sonic-platform > /dev/null 2>/dev/null)
if [ $? -eq 0 ]; then
rv = $(pip uninstall -y sonic-platform > /dev/null 2>/dev/null)
fi
}

if [[ "$1" == "init" ]]; then
depmod -a
modprobe nvram
modprobe i2c_mux_gpio
modprobe dell_s6000_platform
install_python_api_package

add_i2c_devices

/usr/local/bin/set-fan-speed 15000
/usr/local/bin/reset-qsfp
elif [[ "$1" == "deinit" ]]; then
remove_i2c_devices
rmmod dell_s6000_platform
rmmod nvram
rmmod i2c_mux_gpio
remove_python_api_package
else
echo "s6000_platform : Invalid option !"
fi
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
#!/usr/bin/env python

#############################################################################
#
# Module contains an implementation of SONiC Platform Base API and
# provides the platform information
#
#############################################################################

try:
import os
from sonic_platform_base.chassis_base import ChassisBase
except ImportError as e:
raise ImportError(str(e) + "- required module not found")


class Chassis(ChassisBase):
"""
DELLEMC Platform-specific Chassis class
"""

MAILBOX_DIR = "/sys/devices/platform/dell-s6000-cpld.0"

reset_reason_dict = {}
reset_reason_dict[0xe] = ChassisBase.REBOOT_CAUSE_NON_HARDWARE
reset_reason_dict[0x6] = ChassisBase.REBOOT_CAUSE_NON_HARDWARE

def __init__(self):
ChassisBase.__init__(self)

def get_register(self, reg_name):
rv = 'ERR'
mb_reg_file = self.MAILBOX_DIR+'/'+reg_name

if (not os.path.isfile(mb_reg_file)):
return rv

try:
with open(mb_reg_file, 'r') as fd:
rv = fd.read()
except Exception as error:
rv = 'ERR'

rv = rv.rstrip('\r\n')
rv = rv.lstrip(" ")
return rv

def get_reboot_cause(self):
"""
Retrieves the cause of the previous reboot
"""
reset_reason = int(self.get_register('last_reboot_reason'), base=16)

# In S6000, We track the reboot reason by writing the reason in
# NVRAM. Only Warmboot and Coldboot reason are supported here.

if (reset_reason in self.reset_reason_dict):
return (self.reset_reason_dict[reset_reason], None)

return (ChassisBase.REBOOT_CAUSE_HARDWARE_OTHER, "Invalid Reason")

Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
#!/usr/bin/env python

#############################################################################
#
# Module contains an implementation of SONiC Platform Base API and
# provides the platform information
#
#############################################################################

try:
import os
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()

Loading