@@ -62,10 +62,10 @@ def parse_warmfast_reboot_from_proc_cmdline():
6262 if os .path .isfile (REBOOT_TYPE_KEXEC_FILE ):
6363 with open (REBOOT_TYPE_KEXEC_FILE , "r" ) as cause_file :
6464 cause_file_kexec = cause_file .readline ()
65- m = re .match (REBOOT_TYPE_KEXEC_PATTERN_WARM , cause_file_kexec )
65+ m = re .search (REBOOT_TYPE_KEXEC_PATTERN_WARM , cause_file_kexec )
6666 if m and m .group (1 ):
6767 return 'warm-reboot'
68- m = re .match (REBOOT_TYPE_KEXEC_PATTERN_FAST , cause_file_kexec )
68+ m = re .search (REBOOT_TYPE_KEXEC_PATTERN_FAST , cause_file_kexec )
6969 if m and m .group (1 ):
7070 return 'fast-reboot'
7171 return None
@@ -77,13 +77,61 @@ def find_software_reboot_cause():
7777 if os .path .isfile (REBOOT_CAUSE_FILE ):
7878 with open (REBOOT_CAUSE_FILE , "r" ) as cause_file :
7979 software_reboot_cause = cause_file .readline ().rstrip ('\n ' )
80+ log_info ("{} indicates the reboot cause: {}" .format (REBOOT_CAUSE_FILE , software_reboot_cause ))
81+ else :
82+ log_info ("Reboot cause file {} not found" .format (REBOOT_CAUSE_FILE ))
8083
8184 if os .path .isfile (FIRST_BOOT_PLATFORM_FILE ):
8285 os .remove (FIRST_BOOT_PLATFORM_FILE )
8386
8487 return software_reboot_cause
88+
89+
90+ def find_proc_cmdline_reboot_cause ():
91+ proc_cmdline_reboot_cause = parse_warmfast_reboot_from_proc_cmdline ()
8592
93+ if proc_cmdline_reboot_cause :
94+ log_info ("/proc/cmdline indicates reboot type: {}" .format (proc_cmdline_reboot_cause ))
95+ else :
96+ log_info ("No reboot cause found from /proc/cmdline" )
8697
98+ return proc_cmdline_reboot_cause
99+
100+
101+ def find_hardware_reboot_cause ():
102+ hardware_reboot_cause = None
103+
104+ # Until all platform vendors have provided sonic_platform packages,
105+ # if there is no sonic_platform package installed, we only provide
106+ # software-related reboot causes.
107+ try :
108+ import sonic_platform
109+
110+ platform = sonic_platform .platform .Platform ()
111+
112+ chassis = platform .get_chassis ()
113+
114+ hardware_reboot_cause_major , hardware_reboot_cause_minor = chassis .get_reboot_cause ()
115+
116+ if hardware_reboot_cause_major == chassis .REBOOT_CAUSE_NON_HARDWARE :
117+ # The reboot was not caused by hardware. If there is a REBOOT_CAUSE_FILE, it will
118+ # contain any software-related reboot info. We will use it as the previous cause.
119+ pass
120+ elif hardware_reboot_cause_major == chassis .REBOOT_CAUSE_HARDWARE_OTHER :
121+ hardware_reboot_cause = "{} ({})" .format (hardware_reboot_cause_major , hardware_reboot_cause_minor )
122+ else :
123+ hardware_reboot_cause = hardware_reboot_cause_major
124+ except ImportError as err :
125+ log_warning ("sonic_platform package not installed. Unable to detect hardware reboot causes." )
126+
127+ if hardware_reboot_cause :
128+ log_info ("Platform api indicates reboot cause {}" .format (hardware_reboot_cause ))
129+ else :
130+ log_info ("No reboot cause found from platform api" )
131+
132+ return hardware_reboot_cause
133+
134+
87135def main ():
88136 log_info ("Starting up..." )
89137
@@ -99,54 +147,33 @@ def main():
99147 if os .path .exists (PREVIOUS_REBOOT_CAUSE_FILE ):
100148 os .remove (PREVIOUS_REBOOT_CAUSE_FILE )
101149
102-
103150 # Set a default previous reboot cause
104151 previous_reboot_cause = UNKNOWN_REBOOT_CAUSE
105152
106- # Until all platform vendors have provided sonic_platform packages,
107- # if there is no sonic_platform package installed, we only provide
108- # software-related reboot causes.
109- try :
110- import sonic_platform
111-
112- # 1. Check if the previous reboot was warm/fast reboot by testing whether there is "fast|fastfast|warm" in /proc/cmdline
113- # If yes, the content of /hosts/reboot-cause/reboot-cause.txt will be treated as the reboot cause
114- proc_cmdline_reboot_cause = parse_warmfast_reboot_from_proc_cmdline ()
115- if proc_cmdline_reboot_cause :
116- log_info ("/proc/cmdline indicates reboot type: {}" .format (proc_cmdline_reboot_cause ))
117- if os .path .isfile (REBOOT_CAUSE_FILE ):
118- with open (REBOOT_CAUSE_FILE , "r" ) as cause_file :
119- proc_cmdline_reboot_cause = cause_file .readline ().rstrip ('\n ' )
120- else :
121- # /proc/cmdline says it's a warm/fast reboot but /host/reboot-cause.txt doesn't exist.
122- # This could happen when upgrading from a version doesn't support reboot cause.
123- log_info ("Reboot cause file {} doesn't exist" .format (REBOOT_CAUSE_DIR ))
124-
125- if proc_cmdline_reboot_cause is not None :
126- previous_reboot_cause = proc_cmdline_reboot_cause
127- else :
128- # 2. Check if the previous reboot was caused by hardware
129- # If yes, the hardware reboot cause will be treated as the reboot cause
130- platform = sonic_platform .platform .Platform ()
131-
132- chassis = platform .get_chassis ()
133-
134- hardware_reboot_cause , optional_details = chassis .get_reboot_cause ()
135-
136- if hardware_reboot_cause == chassis .REBOOT_CAUSE_NON_HARDWARE :
137- # The reboot was not caused by hardware. If there is a REBOOT_CAUSE_FILE, it will
138- # contain any software-related reboot info. We will use it as the previous cause.
139- previous_reboot_cause = find_software_reboot_cause ()
140- elif hardware_reboot_cause == chassis .REBOOT_CAUSE_HARDWARE_OTHER :
141- previous_reboot_cause = "{} ({})" .format (hardware_reboot_cause , optional_details )
142- else :
143- previous_reboot_cause = hardware_reboot_cause
144- except ImportError as err :
145- log_warning ("sonic_platform package not installed. Unable to detect hardware reboot causes." )
146-
147- # If there is a REBOOT_CAUSE_FILE, it will contain any software-related
148- # reboot info. We will use it as the previous cause.
149- previous_reboot_cause = find_software_reboot_cause ()
153+ # 1. Check if the previous reboot was warm/fast reboot by testing whether there is "fast|fastfast|warm" in /proc/cmdline
154+ proc_cmdline_reboot_cause = find_proc_cmdline_reboot_cause ()
155+
156+ # 2. Check if the previous reboot was caused by hardware
157+ # If yes, the hardware reboot cause will be treated as the reboot cause
158+ hardware_reboot_cause = find_hardware_reboot_cause ()
159+
160+ # 3. If there is a REBOOT_CAUSE_FILE, it will contain any software-related
161+ # reboot info. We will use it as the previous cause.
162+ software_reboot_cause = find_software_reboot_cause ()
163+
164+ # The main decision logic of the reboot cause:
165+ # If there is a reboot cause indicated by /proc/cmdline, it should be warmreboot/fastreboot
166+ # the software_reboot_cause which is the content of /hosts/reboot-cause/reboot-cause.txt
167+ # will be treated as the reboot cause
168+ # Elif there is a reboot cause indicated by platform API,
169+ # the hardware_reboot_cause will be treated as the reboot cause
170+ # Else the software_reboot_cause will be treated as the reboot cause
171+ if proc_cmdline_reboot_cause is not None :
172+ previous_reboot_cause = software_reboot_cause
173+ elif hardware_reboot_cause is not None :
174+ previous_reboot_cause = hardware_reboot_cause
175+ else :
176+ previous_reboot_cause = software_reboot_cause
150177
151178 # Write the previous reboot cause to PREVIOUS_REBOOT_CAUSE_FILE
152179 with open (PREVIOUS_REBOOT_CAUSE_FILE , "w" ) as prev_cause_file :
0 commit comments