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

[device/alibaba] - Update firmware management function. #57

Merged
merged 4 commits into from Mar 4, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
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
191 changes: 172 additions & 19 deletions device/alibaba/x86_64-alibaba_as13-32h-cl-r0/plugins/fwmgrutil.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
import os
import pexpect
import base64
import time

try:
from sonic_fwmgr.fwgmr_base import FwMgrUtilBase
Expand All @@ -24,6 +25,7 @@ def __init__(self):
self.onie_config_file = "/host/machine.conf"
self.bmc_info_url = "http://240.1.1.1:8080/api/sys/bmc"
self.bmc_raw_command_url = "http://240.1.1.1:8080/api/sys/raw"
self.fw_upgrade_url = "http://240.1.1.1:8080/api/sys/upgrade"
self.onie_config_file = "/host/machine.conf"
self.cpldb_version_path = "/sys/devices/platform/%s.cpldb/getreg" % self.platform_name
self.fpga_version_path = "/sys/devices/platform/%s.switchboard/FPGA/getreg" % self.platform_name
Expand All @@ -43,6 +45,30 @@ def __get_register_value(self, path, register):
else:
return raw_data.strip()

def __fpga_pci_rescan(self):
"""
An sequence to trigger FPGA to load new configuration after upgrade.
"""
fpga_pci_device_remove = '/sys/devices/pci0000:00/0000:00:1c.0/0000:09:00.0/remove'
parent_pci_device_rescan = '/sys/devices/pci0000:00/0000:00:1c.0/rescan'
cmd = 'modprobe -r switchboard_fpga'
os.system(cmd)
cmd = 'echo 1 > %s' % fpga_pci_device_remove
rc = os.system(cmd)
if rc > 0:
return rc
cmd = 'echo 0xa10a 0 > /sys/devices/platform/%s.cpldb/setreg' % self.platform_name
rc = os.system(cmd)
if rc > 0:
return rc
time.sleep(10)
cmd = 'echo 1 > %s' % parent_pci_device_rescan
rc = os.system(cmd)
if rc > 0:
return rc
os.system('modprobe switchboard_fpga')
return 0

def get_bmc_pass(self):
with open(self.bmc_pwd_path) as file:
data = file.read()
Expand All @@ -65,9 +91,10 @@ def get_bmc_version(self):

bmc_version_key = "OpenBMC Version"
bmc_info_req = requests.get(self.bmc_info_url)
bmc_info_json = bmc_info_req.json()
bmc_info = bmc_info_json.get('Information')
bmc_version = bmc_info.get(bmc_version_key)
if bmc_info_req.status_code == 200:
bmc_info_json = bmc_info_req.json()
bmc_info = bmc_info_json.get('Information')
bmc_version = bmc_info.get(bmc_version_key)

return str(bmc_version)

Expand All @@ -85,6 +112,8 @@ def get_cpld_version(self):

fan_cpld_key = "FanCPLD Version"
bmc_info_req = requests.get(self.bmc_info_url)
if bmc_info_req.status_code != 200:
return {}
bmc_info_json = bmc_info_req.json()
bmc_info = bmc_info_json.get('Information')
fan_cpld = bmc_info.get(fan_cpld_key)
Expand Down Expand Up @@ -237,6 +266,7 @@ def firmware_upgrade(self, fw_type, fw_path, fw_extra=None):
reboot_dict = dict()
reboot_dict["reboot"] = "yes"
r = requests.post(self.bmc_info_url, json=reboot_dict)
print("Done")
return True
else:
print("Failed")
Expand All @@ -254,25 +284,148 @@ def firmware_upgrade(self, fw_type, fw_path, fw_extra=None):
break
if output:
print(output.strip())
rc = process.poll()
return True

if process.returncode == 0:
rc = self.__fpga_pci_rescan()
if rc == 0:
return True
else:
print("Fails to load new FPGA firmware")
return False
else:
return False

elif 'cpld' in fw_type:
command = 'ispvm ' + fw_path
if fw_extra is not None:
command = 'ispvm -c ' + \
str(fw_extra) + " " + os.path.abspath(fw_path)
print("Running command : ", command)
process = subprocess.Popen(
command, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
fw_extra_str = str(fw_extra).upper()
fw_extra_str = {
"TOP_LC_CPLD": "top_lc",
"BOT_LC_CPLD": "bot_lc",
"FAN_CPLD": "fan",
"CPU_CPLD": "cpu",
"BASE_CPLD": "base",
"COMBO_CPLD": "combo",
"SW_CPLD": "switch"
}.get(fw_extra_str, None)

if fw_extra_str is None:
print("Failed: Invalid extra information string")
return False

while True:
output = process.stdout.readline()
if output == '' and process.poll() is not None:
break
if output:
print(output.strip())
rc = process.poll()
scp_command = 'sudo scp -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null -r %s root@240.1.1.1:/home/root/' % os.path.abspath(
fw_path)
child = pexpect.spawn(scp_command)
i = child.expect(["root@240.1.1.1's password:"], timeout=30)
if i == 0:
print("Uploading image to BMC...")
print("Running command : ", scp_command)
bmc_pwd = self.get_bmc_pass()
child.sendline(bmc_pwd)
data = child.read()
print(data)
child.close

filename_w_ext = os.path.basename(fw_path)
json_data = dict()
json_data["image_path"] = "root@127.0.0.1:/home/root/%s" % filename_w_ext
json_data["password"] = bmc_pwd
json_data["device"] = "cpld"
json_data["reboot"] = "no"
json_data["type"] = fw_extra_str

print("Installing CPLD type :", fw_extra_str)
r = requests.post(self.fw_upgrade_url, json=json_data)
if r.status_code != 200 or 'success' not in r.json().get('result'):
print("Failed")
return False

if fw_extra_str == "combo":
json_data["type"] = "enable"
r = requests.post(self.fw_upgrade_url, json=json_data)
if r.status_code != 200 or 'success' not in r.json().get('result'):
print("Failed")
return False

print("Done")
return True

elif 'bios' in fw_type:
fw_extra_str = str(fw_extra).lower()
flash = fw_extra_str if fw_extra_str in [
"master", "slave"] else "master"

scp_command = 'sudo scp -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null -r %s root@240.1.1.1:/home/root/' % os.path.abspath(
fw_path)
child = pexpect.spawn(scp_command)
i = child.expect(["root@240.1.1.1's password:"], timeout=30)
if i == 0:
print("Uploading image to BMC...")
print("Running command : ", scp_command)
bmc_pwd = self.get_bmc_pass()
child.sendline(bmc_pwd)
data = child.read()
print(data)
child.close

filename_w_ext = os.path.basename(fw_path)
json_data = dict()
json_data["image_path"] = "root@127.0.0.1:/home/root/%s" % filename_w_ext
json_data["password"] = bmc_pwd
json_data["device"] = "bios"
json_data["flash"] = flash
json_data["reboot"] = "no"

print("Installing BIOS ... ")
r = requests.post(self.fw_upgrade_url, json=json_data)
if r.status_code != 200 or 'success' not in r.json().get('result'):
print("Failed")
return False
print("Done")
return True

print("Failed: Invalid firmware type")
return False

def get_last_upgrade_result(self):
"""
Get last firmware upgrade information, inlcudes:
1) FwType: cpld/fpga/bios/bmc(passed by method 'firmware_upgrade'), string
2) FwPath: path and file name of firmware(passed by method 'firmware_upgrade'), string
3) FwExtra: designated string, econdings of this string is determined by vendor(passed by method 'firmware_upgrade')
4) Result: indicates whether the upgrade action is performed and success/failure status if performed. Values should be one of: "DONE"/"FAILED"/"NOT_PERFORMED".
dict object:
{
"FwType": "cpld",
"FwPath": "/tmp/fw/x86_64-alibaba-as13-48f8h/cpld_come_fan_board.vme"
"FwExtra": "specific_encoded_string"
"Result": "DONE"/"FAILED"/"NOT_PERFORMED"
}
"""
update_dict = dict()

upgrade_info_req = requests.get(self.fw_upgrade_url)
if upgrade_info_req.status_code == 200 and 'success' in upgrade_info_req.json().get('result'):
upgrade_info_json = upgrade_info_req.json()
if "CPLD upgrade log" in upgrade_info_json.keys() and upgrade_info_json["CPLD upgrade log"] != "None":
raw_data = upgrade_info_json["CPLD upgrade log"][-1]
raw_data_list = raw_data.split(",")
fw_path = raw_data_list[1].split("firmware:")[1].strip()
fw_extra_raw = raw_data_list[0].split(":")[0].strip()
fw_result_raw = raw_data_list[0].split(":")[1].strip()
fw_extra_str = {
"top_lc": "TOP_LC_CPLD",
"bot_lc": "BOT_LC_CPLD",
"fan": "FAN_CPLD",
"cpu": "CPU_CPLD",
"base": "BASE_CPLD",
"combo": "COMBO_CPLD",
"switch": "SW_CPLD"
}.get(fw_extra_raw, None)
fw_result = "DONE" if fw_result_raw == "success" else fw_result_raw.upper()
fw_result = "FAILED" if "FAILED" in fw_result else fw_result
fw_result = "NOT_PERFORMED" if fw_result != "DONE" and fw_result != "FAILED" else fw_result
update_dict["FwType"] = "cpld"
update_dict["FwPath"] = fw_path
update_dict["FwExtra"] = fw_extra_str
update_dict["Result"] = fw_result

return update_dict
Loading